diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 2839ba02b..597c69eff 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -6,6 +6,8 @@ - [ ] The pull request is done against the latest dev branch - [ ] Only relevant files were touched - [ ] Only one feature/fix was added per PR. - - [ ] The code change is tested and works on core Tasmota_core_stage - - [ ] The code change pass travis tests. **Your PR cannot be merged unless tests pass** + - [ ] The code change is tested and works on core ESP8266 V.2.7.2 + - [ ] The code change is tested and works on core ESP32 V.1.12.2 - [ ] I accept the [CLA](https://github.com/arendst/Tasmota/blob/development/CONTRIBUTING.md#contributor-license-agreement-cla). + +_NOTE: The code change must pass CI tests. **Your PR cannot be merged unless tests pass**_ diff --git a/.github/workflows/CI_github.yml b/.github/workflows/CI_github.yml new file mode 100644 index 000000000..0fe2fd9c5 --- /dev/null +++ b/.github/workflows/CI_github.yml @@ -0,0 +1,442 @@ +name: Tasmota CI + +on: + pull_request: + +jobs: + tasmota: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: platformio run -e tasmota + + tasmota-minimal: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: platformio run -e tasmota-minimal + + tasmota-lite: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: platformio run -e tasmota-lite + + tasmota-knx: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: platformio run -e tasmota-knx + + tasmota-sensors: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: platformio run -e tasmota-sensors + + + tasmota-display: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: platformio run -e tasmota-display + + tasmota-ir: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: platformio run -e tasmota-ir + + tasmota-BG: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: platformio run -e tasmota-BG + + tasmota-BR: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: platformio run -e tasmota-BR + + tasmota-CN: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: platformio run -e tasmota-CN + + tasmota-CZ: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: platformio run -e tasmota-CZ + + tasmota-DE: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: platformio run -e tasmota-DE + + tasmota-ES: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: platformio run -e tasmota-ES + + + tasmota-FR: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: platformio run -e tasmota-FR + + tasmota-GR: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: platformio run -e tasmota-GR + + tasmota-HE: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: platformio run -e tasmota-HE + + tasmota-HU: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: platformio run -e tasmota-HU + + tasmota-IT: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: platformio run -e tasmota-IT + + tasmota-KO: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: platformio run -e tasmota-KO + + tasmota-NL: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: platformio run -e tasmota-NL + + tasmota-PL: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: platformio run -e tasmota-PL + + tasmota-PT: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: platformio run -e tasmota-PT + + tasmota-RO: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: platformio run -e tasmota-RO + + tasmota-RU: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: platformio run -e tasmota-RU + + tasmota-SE: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: platformio run -e tasmota-SE + + tasmota-SK: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: platformio run -e tasmota-SK + + tasmota-TR: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: platformio run -e tasmota-TR + + tasmota-TW: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: platformio run -e tasmota-TW + + tasmota-UK: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: platformio run -e tasmota-UK diff --git a/.github/workflows/CI_github_ESP32.yml b/.github/workflows/CI_github_ESP32.yml new file mode 100644 index 000000000..5184aeb7a --- /dev/null +++ b/.github/workflows/CI_github_ESP32.yml @@ -0,0 +1,517 @@ +name: Tasmota ESP32 CI + +on: + pull_request: + +jobs: + tasmota32: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + cp platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32 + + + tasmota32-webcam: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + cp platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-webcam + + tasmota32-minimal: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + cp platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-minimal + + tasmota32-lite: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + cp platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-lite + + tasmota32-knx: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + cp platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-knx + + tasmota32-sensors: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + cp platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-sensors + + tasmota32-display: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + cp platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-display + + tasmota32-ir: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + cp platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-ir + + tasmota32-BG: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + cp platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-BG + + tasmota32-BR: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + cp platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-BR + + tasmota32-CN: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + cp platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-CN + + tasmota32-CZ: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + cp platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-CZ + + tasmota32-DE: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + cp platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-DE + + tasmota32-ES: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + cp platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-ES + + + tasmota32-FR: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + cp platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-FR + + tasmota32-GR: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + cp platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-GR + + tasmota32-HE: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + cp platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-HE + + tasmota32-HU: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + cp platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-HU + + tasmota32-IT: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + cp platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-IT + + tasmota32-KO: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + cp platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-KO + + tasmota32-NL: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + cp platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-NL + + tasmota32-PL: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + cp platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-PL + + tasmota32-PT: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + cp platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-PT + + tasmota32-RO: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + cp platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-RO + + tasmota32-RU: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + cp platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-RU + + tasmota32-SE: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + cp platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-SE + + tasmota32-SK: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + cp platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-SK + + tasmota32-TR: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + cp platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-TR + + tasmota32-TW: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + cp platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-TW + + tasmota32-UK: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + cp platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-UK diff --git a/.github/workflows/Tasmota_build.yml b/.github/workflows/Tasmota_build.yml new file mode 100644 index 000000000..819771059 --- /dev/null +++ b/.github/workflows/Tasmota_build.yml @@ -0,0 +1,1509 @@ +name: Build_firmware + +on: + push: + +jobs: + tasmota_pull: + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Use latest Tasmota development + run: | + git config --local user.name "Platformio BUILD" + git switch -c master + git remote add -f Tasmota "https://github.com/arendst/Tasmota.git" + git merge Tasmota/development --allow-unrelated-histories + - name: Push Tasmota # Push updates of latest Tasmota development to repo + uses: ad-m/github-push-action@master + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + branch: 'development' + force: true + + + tasmota: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-minimal: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-minimal + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-lite: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-lite + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-knx: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-knx + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-sensors: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-sensors + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-display: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-display + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-ir: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-ir + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-ircustom: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-ircustom + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-BG: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-BG + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-BR: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-BR + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-CN: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-CN + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-CZ: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-CZ + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-DE: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-DE + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-ES: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-ES + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-FR: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-FR + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-GR: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-GR + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-HE: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-HE + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-HU: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-HU + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-IT: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-IT + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-KO: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-KO + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-NL: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-NL + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-PL: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-PL + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-PT: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-PT + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-RO: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-RO + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-RU: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-RU + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-SE: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-SE + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-SK: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-SK + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-TR: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-TR + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-TW: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-TW + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota-UK: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + platformio run -e tasmota-UK + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + mv platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32 + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-minimal: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + mv platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-minimal + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-lite: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + mv platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-lite + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-webcam: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + mv platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-webcam + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-knx: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + mv platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-knx + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-sensors: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + mv platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-sensors + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-display: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + mv platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-display + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-ir: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + mv platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-ir + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-ircustom: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + mv platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-ircustom + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-BG: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + mv platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-BG + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-BR: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + mv platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-BR + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-CN: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + mv platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-CN + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-CZ: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + mv platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-CZ + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-DE: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + mv platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-DE + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-ES: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + mv platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-ES + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-FR: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + mv platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-FR + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-GR: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + mv platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-GR + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-HE: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + mv platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-HE + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-HU: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + mv platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-HU + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-IT: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + mv platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-IT + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-KO: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + mv platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-KO + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-NL: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + mv platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-NL + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-PL: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + mv platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-PL + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-PT: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + mv platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-PT + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-RO: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + mv platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-RO + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-RU: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + mv platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-RU + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-SE: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + mv platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-SE + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-SK: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + mv platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-SK + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-TR: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + mv platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-TR + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-TW: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + mv platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-TW + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + tasmota32-UK: + needs: tasmota_pull + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -U platformio + platformio upgrade --dev + platformio update + - name: Run PlatformIO + run: | + mv platformio_override_sample.ini platformio_override.ini + platformio run -e tasmota32-UK + - uses: actions/upload-artifact@v2 + with: + name: firmware + path: ./build_output/firmware + + + Upload: + needs: [tasmota-UK, tasmota32-ircustom, tasmota32-UK, tasmota32-TW, tasmota32-TR] + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v1 + - uses: actions/download-artifact@v2 + with: + name: firmware + path: ./mv_firmware + - name: Display structure of downloaded files + run: ls -R + working-directory: ./mv_firmware + - name: Move firmware files in sub-folders + run: | + mkdir -p ./firmware/tasmota/languages + mkdir -p ./firmware/tasmota32/languages + mkdir -p ./firmware/tasmota32/ESP32_needed_files/ + [ ! -f ./mv_firmware/tasmota.* ] || mv ./mv_firmware/tasmota.* ./firmware/tasmota/ + [ ! -f ./mv_firmware/tasmota-sensors.* ] || mv ./mv_firmware/tasmota-sensors.* ./firmware/tasmota/ + [ ! -f ./mv_firmware/tasmota-minimal.* ] || mv ./mv_firmware/tasmota-minimal.* ./firmware/tasmota/ + [ ! -f ./mv_firmware/tasmota-lite.* ] || mv ./mv_firmware/tasmota-lite.* ./firmware/tasmota/ + [ ! -f ./mv_firmware/tasmota-ir*.* ] || mv ./mv_firmware/tasmota-ir*.* ./firmware/tasmota/ + [ ! -f ./mv_firmware/tasmota-display.* ] || mv ./mv_firmware/tasmota-display.* ./firmware/tasmota/ + [ ! -f ./mv_firmware/tasmota-knx.* ] || mv ./mv_firmware/tasmota-knx.* ./firmware/tasmota/ + [ ! -f ./mv_firmware/tasmota32.* ] || mv ./mv_firmware/tasmota32.* ./firmware/tasmota32/ + [ ! -f ./mv_firmware/tasmota32-sensors.* ] || mv ./mv_firmware/tasmota32-sensors.* ./firmware/tasmota32/ + [ ! -f ./mv_firmware/tasmota32-minimal.* ] || mv ./mv_firmware/tasmota32-minimal.* ./firmware/tasmota32/ + [ ! -f ./mv_firmware/tasmota32-lite.* ] || mv ./mv_firmware/tasmota32-lite.* ./firmware/tasmota32/ + [ ! -f ./mv_firmware/tasmota32-ir*.* ] || mv ./mv_firmware/tasmota32-ir*.* ./firmware/tasmota32/ + [ ! -f ./mv_firmware/tasmota32-display.* ] || mv ./mv_firmware/tasmota32-display.* ./firmware/tasmota32/ + [ ! -f ./mv_firmware/tasmota32-web*.* ] || mv ./mv_firmware/tasmota32-web*.* ./firmware/tasmota32/ + [ ! -f ./mv_firmware/tasmota32-knx.* ] || mv ./mv_firmware/tasmota32-knx.* ./firmware/tasmota32/ + [ ! -f ./mv_firmware/tasmota32* ] || mv ./mv_firmware/tasmota32* ./firmware/tasmota32/languages/ + [ ! -f ./mv_firmware/* ] || mv ./mv_firmware/* ./firmware/tasmota/languages/ + [ ! -f ./tools/Esptool/ESP32/*.* ] || mv ./tools/Esptool/ESP32/*.* ./firmware/tasmota32/ESP32_needed_files/ + [ ! -f ./FIRMWARE.md ] || mv -f ./FIRMWARE.md ./README.md + - name: Commit files # transfer the new binaries back into the repository + run: | + git config --local user.name "Platformio BUILD" + git rm -r --cached . + git add ./README.md + git add -f ./firmware/*.* + git commit -m "Tasmota ESP Binaries http://tasmota.com" + - name: Push changes # push the firmware files to branch firmware + uses: ad-m/github-push-action@master + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + branch: 'firmware' + force: true diff --git a/.gitignore b/.gitignore index 500f720ec..75ff90814 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ ## OS specific ######## .DS_Store .fuse_hidden* +*.pyc ## Project files ###### .pioenvs @@ -17,6 +18,7 @@ tasmota*.bin tasmota*.bin.gz tasmota*.map platformio_override.ini +platformio_tasmota_cenv.ini ## Visual Studio Code specific ###### .vscode @@ -24,3 +26,4 @@ platformio_override.ini .vscode/c_cpp_properties.json .vscode/launch.json *.bak +*.code-workspace diff --git a/.travis.yml b/.travis.yml.off similarity index 100% rename from .travis.yml rename to .travis.yml.off diff --git a/BUILDS.md b/BUILDS.md index 04711b1c6..c1aa5e2e3 100644 --- a/BUILDS.md +++ b/BUILDS.md @@ -2,7 +2,7 @@ | Feature or Sensor | minimal | lite | tasmota | knx | sensors | ir | display | Remarks |-----------------------|---------|-------|--------|-----|---------|----|---------|-------- -| MY_LANGUAGE en-GB | x | x | x | x | x | x | x | +| MY_LANGUAGE en_GB | x | x | x | x | x | x | x | | USE_ARDUINO_OTA | - | - | - | - | - | - | - | | USE_DOMOTICZ | - | - | x | x | x | x | - | | USE_HOME_ASSISTANT | - | - | x | x | x | x | - | @@ -29,7 +29,7 @@ | USE_HOTPLUG | - | - | - | - | - | - | - | | | | | | | | | | | Feature or Sensor | minimal | lite | tasmota | knx | sensors | ir | display | Remarks -| ROTARY_V1 | - | - | - | - | - | - | - | +| ROTARY_V1 | - | - | x | - | x | - | - | | USE_SONOFF_RF | - | - | x | x | x | - | - | | USE_RF_FLASH | - | - | x | x | x | - | - | | USE_SONOFF_SC | - | - | x | x | x | - | - | @@ -68,13 +68,16 @@ | USE_DDSU666 | - | - | - | - | x | - | - | | USE_SOLAX_X1 | - | - | - | - | - | - | - | | USE_LE01MR | - | - | - | - | - | - | - | +| USE_TELEINFO | - | - | - | - | - | - | - | | | | | | | | | | -| USE_ADC_VCC | x | x | - | - | - | - | - | -| USE_COUNTER | - | - | x | x | x | x | x | -| USE_DS18x20 | - | - | x | x | x | x | x | -| USE_DHT | - | - | x | x | x | x | x | +| USE_ADC_VCC | x | x | - | - | - | x | - | +| USE_COUNTER | - | - | x | x | x | - | x | +| USE_DS18x20 | - | - | x | x | x | - | x | +| USE_DHT | - | - | x | x | x | - | x | | USE_MAX31855 | - | - | - | - | x | - | - | | USE_MAX31865 | - | - | - | - | - | - | - | +| USE_THERMOSTAT | - | - | - | - | - | - | - | +| USE_LMT01 | - | - | - | - | x | - | - | | | | | | | | | | | Feature or Sensor | minimal | lite | tasmota | knx | sensors | ir | display | Remarks | USE_I2C | - | - | x | x | x | - | x | @@ -117,6 +120,11 @@ | USE_AHT1x | - | - | - | - | - | - | - | | USE_HDC1080 | - | - | - | - | - | - | - | | USE_WEMOS_MOTOR_V1 | - | - | - | - | x | - | - | +| USE_IAQ | - | - | - | - | x | - | - | +| USE_AS3935 | - | - | - | - | x | - | - | +| USE_VEML6075 | - | - | - | - | - | - | - | +| USE_VEML7700 | - | - | - | - | - | - | - | +| USE_MCP9808 | - | - | - | - | - | - | - | | | | | | | | | | | Feature or Sensor | minimal | lite | tasmota | knx | sensors | ir | display | Remarks | USE_SPI | - | - | - | - | - | - | x | @@ -134,6 +142,8 @@ | USE_GPS | - | - | - | - | - | - | - | | USE_HM10 | - | - | - | - | x | - | - | | USE_HRXL | - | - | - | - | x | - | - | +| USE_TASMOTA_SLAVE | - | - | - | - | - | - | - | +| USE_OPENTHERM | - | - | - | - | - | - | - | | | | | | | | | | | USE_NRF24 | - | - | - | - | - | - | - | | USE_MIBLE | - | - | - | - | - | - | - | @@ -147,11 +157,11 @@ | USE_TM1638 | - | - | - | - | x | - | - | | USE_HX711 | - | - | - | - | x | - | - | | USE_TX2x_WIND_SENSOR | - | - | - | - | - | - | - | +| USE_WINDMETER | - | - | - | - | - | - | - | | USE_RC_SWITCH | - | - | - | - | x | - | - | | USE_RF_SENSOR | - | - | - | - | x | - | - | AlectoV2 only | USE_HRE | - | - | - | - | x | - | - | | USE_A4988_STEPPER | - | - | - | - | - | - | - | -| USE_TASMOTA_SLAVE | - | - | - | - | - | - | - | Experimental | | | | | | | | | | Feature or Sensor | minimal | lite | tasmota | knx | sensors | ir | display | Remarks | USE_DISPLAY | - | - | - | - | - | - | x | @@ -165,3 +175,11 @@ | USE_DISPLAY_ILI9488 | - | - | - | - | - | - | - | | USE_DISPLAY_SSD1351 | - | - | - | - | - | - | - | | USE_DISPLAY_RA8876 | - | - | - | - | - | - | - | + +## Additional Features and Sensors on ESP32 + +| Feature or Sensor | minimal | lite | tasmota | knx | sensors | ir | display | webcam | Remarks +|-----------------------|---------|-------|--------|-----|---------|----|---------|--------|-------- +| USE_MI_ESP32 | - | - | - | - | - | - | - | - | +| USE_WEBCAM | - | - | - | - | - | - | - | x | +| USE_ETHERNET | - | - | - | - | - | - | - | - | diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 26db830ac..34c3c2b98 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -53,7 +53,7 @@ The process is straight-forward. 2. Only relevant files should be touched (Also beware if your editor has auto-formatting feature enabled). 3. Only one feature/fix should be added per PR. 4. If adding a new functionality (new hardware, new library support) not related to an existing component move it to it's own modules (.ino file). -5. PRs that don't compile (break Travis) or cause coding errors will not be merged. Please fix the issue. Same goes for PRs that are raised against older commit in dev - you might need to rebase and resolve conflicts. +5. PRs that don't compile (fail in CI Tests) or cause coding errors will not be merged. Please fix the issue. Same goes for PRs that are raised against older commit in dev - you might need to rebase and resolve conflicts. 6. All pull requests should undergo peer review by at least one contributor other than the creator, excepts for the owner. 7. All pull requests should consider updates to the documentation. 8. Pull requests that address an outstanding issue, particularly an issue deemed to be severe, should be given priority. diff --git a/FIRMWARE.md b/FIRMWARE.md new file mode 100644 index 000000000..4feb4126d --- /dev/null +++ b/FIRMWARE.md @@ -0,0 +1,44 @@ +![Tasmota logo](https://github.com/arendst/Tasmota/blob/development/tools/logo/TASMOTA_FullLogo_Vector.svg) + +Alternative firmware for [ESP8266](https://en.wikipedia.org/wiki/ESP8266) based devices with **easy configuration using webUI, OTA updates, automation using timers or rules, expandability and entirely local control over MQTT, HTTP, Serial or KNX**. +_Written for Arduino IDE and PlatformIO._ + +[![GitHub version](https://img.shields.io/github/release/arendst/Tasmota.svg)](https://github.com/arendst/Tasmota/releases/latest) +[![GitHub download](https://img.shields.io/github/downloads/arendst/Tasmota/total.svg)](https://github.com/arendst/Tasmota/releases/latest) +[![License](https://img.shields.io/github/license/arendst/Tasmota.svg)](LICENSE.txt) +[![Chat](https://img.shields.io/discord/479389167382691863.svg)](https://discord.gg/Ks2Kzd4) + +If you like **Tasmota**, give it a star, or fork it and contribute! + +[![GitHub stars](https://img.shields.io/github/stars/arendst/Tasmota.svg?style=social&label=Star)](https://github.com/arendst/Tasmota/stargazers) +[![GitHub forks](https://img.shields.io/github/forks/arendst/Tasmota.svg?style=social&label=Fork)](https://github.com/arendst/Tasmota/network) +[![donate](https://img.shields.io/badge/donate-PayPal-blue.svg)](https://paypal.me/tasmota) + +See [CHANGELOG.md](https://github.com/arendst/Tasmota/blob/development/tasmota/CHANGELOG.md) for changes since last release. + +## Development + +[![Dev Version](https://img.shields.io/badge/development%20version-v8.3.x.x-blue.svg)](https://github.com/arendst/Tasmota) +[![Download Dev](https://img.shields.io/badge/download-development-yellow.svg)](http://thehackbox.org/tasmota/) +[![Tasmota CI](https://github.com/arendst/Tasmota/workflows/Tasmota%20CI/badge.svg)](https://github.com/arendst/Tasmota/actions?query=workflow%3A%22Tasmota+CI%22) +[![Tasmota ESP32 CI](https://github.com/arendst/Tasmota/workflows/Tasmota%20ESP32%20CI/badge.svg)](https://github.com/arendst/Tasmota/actions?query=workflow%3A%22Tasmota+ESP32+CI%22) +[![Build_firmware](https://github.com/arendst/Tasmota/workflows/Build_firmware/badge.svg)](https://github.com/arendst/Tasmota/actions?query=workflow%3ABuild_firmware) + + +Unless your Tasmota powered device exhibits a problem or you need to make use of a feature that is not available in the Tasmota version currently installed on your device, leave your device alone - it works so don't make unnecessary changes! If the release version (i.e., the master branch) exhibits unexpected behaviour for your device and configuration, you should upgrade to the latest development version instead to see if your problem is resolved as some bugs in previous releases or development builds may already have been resolved. + +If new commits have been merged and they compile successfuly, new binary files for every variant will be placed here https://github.com/arendst/Tasmota/tree/firmware/firmware (this URL address can NOT be used for OTA updates) It is important to note that these binaries are based on the current development codebase. These commits are tested as much as is possible and are typically quite stable. However, it is infeasible to test on the hundreds of different types of devices with all the available configuration options permitted. + +Note that there is a chance, as with any upgrade, that the device may not function as expected. You must always account for the possibility that you may need to flash the device via the serial programming interface if the OTA upgrade fails. Even with the master release, you should always attempt to test the device or a similar prototype before upgrading a device which is in production or is hard to reach. And, as always, make a backup of the device configuration before beginning any firmware update. + +## Disclaimer + +:warning: **DANGER OF ELECTROCUTION** :warning: + +If your device connects to mains electricity (AC power) there is danger of electrocution if not installed properly. If you don't know how to install it, please call an electrician (***Beware:*** certain countries prohibit installation without a licensed electrician present). Remember: _**SAFETY FIRST**_. It is not worth the risk to yourself, your family and your home if you don't know exactly what you are doing. Never tinker or try to flash a device using the serial programming interface while it is connected to MAINS ELECTRICITY (AC power). + +We don't take any responsibility nor liability for using this software nor for the installation or any tips, advice, videos, etc. given by any member of this site or any related site. + +## Quick Install +Download one of the binaries https://github.com/arendst/Tasmota/tree/firmware/firmware and flash it to your hardware [using our installation guide](https://tasmota.github.io/docs/Getting-Started). + diff --git a/I2CDEVICES.md b/I2CDEVICES.md index 53bbcf810..b67cc9029 100644 --- a/I2CDEVICES.md +++ b/I2CDEVICES.md @@ -69,3 +69,8 @@ Index | Define | Driver | Device | Address(es) | Description 45 | USE_HDC1080 | xsns_65 | HDC1080 | 0x40 | Temperature and Humidity sensor 46 | USE_IAQ | xsns_66 | IAQ | 0x5a | Air quality sensor 47 | USE_DISPLAY_SEVENSEG| xdsp_11 | HT16K33 | 0x70 - 0x77 | Seven segment LED + 48 | USE_AS3935 | xsns_67 | AS3935 | 0x03 | Franklin Lightning Sensor + 49 | USE_VEML6075 | xsns_70 | VEML6075 | 0x10 | UVA/UVB/UVINDEX Sensor + 50 | USE_VEML7700 | xsns_71 | VEML7700 | 0x10 | Ambient light intensity sensor + 51 | USE_MCP9808 | xsns_72 | MCP9808 | 0x18 - 0x1F | Temperature sensor + 52 | USE_HP303B | xsns_73 | HP303B | 0x76 - 0x77 | Pressure and temperature sensor \ No newline at end of file diff --git a/README.md b/README.md index 23359fe22..f5d40a631 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ _Written for Arduino IDE and PlatformIO._ [![License](https://img.shields.io/github/license/arendst/Tasmota.svg)](LICENSE.txt) [![Chat](https://img.shields.io/discord/479389167382691863.svg)](https://discord.gg/Ks2Kzd4) -If you like **Tasmota**, give it a star, or fork it and contribute! +If you like **Tasmota**, give it a star, or fork it and contribute! [![GitHub stars](https://img.shields.io/github/stars/arendst/Tasmota.svg?style=social&label=Star)](https://github.com/arendst/Tasmota/stargazers) [![GitHub forks](https://img.shields.io/github/forks/arendst/Tasmota.svg?style=social&label=Fork)](https://github.com/arendst/Tasmota/network) @@ -20,9 +20,11 @@ In addition to the [release webpage](https://github.com/arendst/Tasmota/releases ## Development -[![Dev Version](https://img.shields.io/badge/development%20version-v8.2.x.x-blue.svg)](https://github.com/arendst/Tasmota) +[![Dev Version](https://img.shields.io/badge/development%20version-v8.3.x.x-blue.svg)](https://github.com/arendst/Tasmota) [![Download Dev](https://img.shields.io/badge/download-development-yellow.svg)](http://thehackbox.org/tasmota/) -[![Build Status](https://img.shields.io/travis/arendst/Tasmota.svg)](https://travis-ci.org/arendst/Tasmota) +[![Tasmota CI](https://github.com/arendst/Tasmota/workflows/Tasmota%20CI/badge.svg)](https://github.com/arendst/Tasmota/actions?query=workflow%3A%22Tasmota+CI%22) +[![Tasmota ESP32 CI](https://github.com/arendst/Tasmota/workflows/Tasmota%20ESP32%20CI/badge.svg)](https://github.com/arendst/Tasmota/actions?query=workflow%3A%22Tasmota+ESP32+CI%22) +[![Build_firmware](https://github.com/arendst/Tasmota/workflows/Build_firmware/badge.svg)](https://github.com/arendst/Tasmota/actions?query=workflow%3ABuild_firmware) See [tasmota/CHANGELOG.md](tasmota/CHANGELOG.md) for detailed change information. @@ -144,7 +146,9 @@ People helping to keep the show on the road: - Stefan Bode for his Shutter and Deep sleep drivers - Jacek Ziółkowski for his [TDM](https://github.com/jziolkowski/tdm) management tool and [Tasmotizer](https://github.com/tasmota/tasmotizer) flashing tool - Christian Staars for NRF24L01 and HM-10 Bluetooth sensor support -- Pail Diem for UDP Group communication support +- Paul Diem for UDP Group communication support +- Jörg Schüler-Maroldt for his initial ESP32 port +- Javier Arigita for his thermostat driver - Many more providing Tips, Wips, Pocs, PRs and Donations ## License diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 325d65f23..038f20687 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -21,7 +21,7 @@ While fallback or downgrading is common practice it was never supported due to S ## Supported Core versions -This release will be supported from ESP8266/Arduino library Core version **2.6.3 + e64cb61** due to reported security and stability issues on previous Core version. This will also support gzipped binaries. +This release will be supported from ESP8266/Arduino library Core version **2.7.1** due to reported security and stability issues on previous Core version. This will also support gzipped binaries. Although it might still compile on previous Core versions all support will be removed in the near future. @@ -35,7 +35,7 @@ For initial configuration this release supports Webserver based **WifiManager** ## Provided Binary Downloads -The following binary downloads have been compiled with ESP8266/Arduino library core version **2.6.3 + e64cb61**. +The following binary downloads have been compiled with ESP8266/Arduino library core version **2.7.1**. - **tasmota.bin** = The Tasmota version with most drivers. **RECOMMENDED RELEASE BINARY** - **tasmota-BG.bin** to **tasmota-TW.bin** = The Tasmota version in different languages. @@ -52,34 +52,46 @@ The following binary downloads have been compiled with ESP8266/Arduino library c ## Changelog -### Version 8.2.0.3 +### Version 8.4.0 George -- Change HM-10 sensor type detection and add features (#7962) -- Change light scheme 2,3,4 cycle time speed from 24,48,72,... seconds to 4,6,12,24,36,48,... seconds (#8034) -- Change remove floating point libs from IRAM -- Change remove MQTT Info messages on restart for DeepSleep Wake (#8044) -- Change IRremoteESP8266 library updated to v2.7.5 -- Fix possible Relay toggle on (OTA) restart -- Fix PWM flickering during wifi connection (#8046) -- Fix Zigbee sending wrong Sat value with Hue emulation -- Fix Zigbee crash with Occupancy sensor (#8089) -- Add Zigbee command ``ZbRestore`` to restore device configuration dumped with ``ZbStatus 2`` -- Add Zigbee command ``ZbUnbind`` -- Add Zigbee command ``ZbBindState`` and ``manuf``attribute -- Add commands ``CounterDebounceLow`` and ``CounterDebounceHigh`` to control debouncing (#8021) -- Add commands ``NrfPage``, ``NrfIgnore``, ``NrfScan`` and ``NrfBeacon`` to NRF24 Bluetooth driver (#8075) -- Add command ``SetOption41 `` to force sending gratuitous ARP every seconds -- Add command ``SetOption90 1`` to disable non-json MQTT messages (#8044) -- Add command ``SetOption91 1`` to enable fading at startup / power on -- Add command ``Sensor10 0/1/2`` to control BH1750 resolution - 0 = High (default), 1 = High2, 2 = Low (#8016) -- Add command ``Sensor10 31..254`` to control BH1750 measurement time which defaults to 69 (#8016) -- Add command ``DevGroupName`` to specify up to four Device Group Names (#8087) -- Add command ``DevGroupSend`` to send an update to a Device Group (#8093) -- Add support for unreachable (unplugged) Zigbee devices in Philips Hue emulation and Alexa -- Add support for 64x48 SSD1306 OLED (#6740) -- Add support for up to four MQTT GroupTopics (#8014) -- Add support for longer template names -- Add support for an iAQ sensor (#8107) -- Add console command history (#7483, #8015) -- Add quick wifi reconnect using saved AP parameters when ``SetOption56 0`` (#3189) -- Add more accuracy to GPS NTP server (#8088) +- Change IRremoteESP8266 library updated to v2.7.7 +- Change Adafruit_SGP30 library from v1.0.3 to v1.2.0 (#8519) +- Change Energy JSON Total field from ``"Total":[33.736,11.717,16.978]`` to ``"Total":33.736,"TotalTariff":[11.717,16.978]`` +- Change Energy JSON ExportActive field from ``"ExportActive":[33.736,11.717,16.978]`` to ``"ExportActive":33.736,"ExportTariff":[11.717,16.978]`` +- Change ESP32 USER GPIO template representation decreasing template message size +- Change define USE_TASMOTA_SLAVE into USE_TASMOTA_CLIENT +- Change commands ``SlaveSend`` and ``SlaveReset`` into ``ClientSend`` and ``ClientReset`` +- Fix escape of non-JSON received serial data (#8329) +- Fix exception or watchdog on rule re-entry (#8757) +- Add command ``Rule0`` to change global rule parameters +- Add command ``Time 4`` to display timestamp using milliseconds (#8537) +- Add command ``SetOption94 0/1`` to select MAX31855 or MAX6675 thermocouple support (#8616) +- Add command ``SetOption97 0/1`` to switch between Tuya serial speeds 9600 bps (0) or 115200 bps (1) +- Add command ``SetOption98 0/1`` to provide rotary rule triggers (1) instead of controlling light (0) +- Add command ``Module2`` to configure fallback module on fast reboot (#8464) +- Add commands ``LedPwmOn 0..255``, ``LedPwmOff 0..255`` and ``LedPwmMode1 0/1`` to control led brightness by George (#8491) +- Add ESP32 ethernet commands ``EthType 0/1``, ``EthAddress 0..31`` and ``EthClockMode 0..3`` +- Add support for unique MQTTClient (and inherited fallback topic) by full Mac address using ``mqttclient DVES_%12X`` (#8300) +- Add more functionality to ``Switchmode`` 11 and 12 (#8450) +- Add wildcard pattern ``?`` for JSON matching in rules +- Add support for VEML6075 UVA/UVB/UVINDEX Sensor by device111 (#8432) +- Add support for VEML7700 Ambient light intensity Sensor by device111 (#8432) +- Add Three Phase Export Active Energy to SDM630 driver +- Add Zigbee options to ``ZbSend`` to write and report attributes +- Add Zigbee auto-responder for common attributes +- Add ``CpuFrequency`` to ``status 2`` +- Add ``FlashFrequency`` to ``status 4`` +- Add support for up to two BH1750 sensors controlled by commands ``BH1750Resolution`` and ``BH1750MTime`` (#8139) +- Add support for up to eight MCP9808 temperature sensors by device111 (#8594) +- Add support for BL0940 energy monitor as used in Blitzwolf BW-SHP10 (#8175) +- Add initial support for Telegram bot (#8619) +- Add support for HP303B Temperature and Pressure sensor by Robert Jaakke (#8638) +- Add rule trigger ``System#Init`` to allow early rule execution without wifi and mqtt initialized yet +- Add support for Energy sensor (Denky) for French Smart Metering meter provided by global Energy Providers, need a adaptater. See dedicated full [blog](http://hallard.me/category/tinfo/) about French teleinformation stuff +- Add Library to be used for decoding Teleinfo (French Metering Smart Meter) +- Add basic support for ESP32 ethernet adding commands ``Wifi 0/1`` and ``Ethernet 0/1`` both default ON +- Add support for single wire LMT01 temperature Sensor by justifiably (#8713) +- Add compile time interlock parameters (#8759) +- Add compile time user template (#8766) +- Add rotary encoder support for light dimmer and optional color temperature if button1 still pressed (#8670) +- Add support for switches/relays using an AC detection circuitry e.g. MOES MS-104B / BlitzWolf SS5 / etc. (#8606) diff --git a/TEMPLATES.md b/TEMPLATES.md index e34fb2ea5..84937c5bd 100644 --- a/TEMPLATES.md +++ b/TEMPLATES.md @@ -2,296 +2,21 @@ # Templates -Find below the available templates as of March 2020. More template information can be found in the [Tasmota Device Templates Repository](http://blakadder.github.io/templates) +Find below the available templates as of May 2020. More template information can be found in the [Tasmota Device Templates Repository](http://blakadder.github.io/templates) ## Aromatherapy Diffuser ``` Asakuki 500ml {"NAME":"Oil Diffuser","GPIO":[255,255,255,255,255,255,0,0,255,255,255,21,22],"FLAG":0,"BASE":18} +Blitzwolf BW-FUN3 400ml {"NAME":"Generic","GPIO":[255,255,255,255,255,255,255,255,255,255,255,255,255],"FLAG":0,"BASE":54} +Brilex 400ml Oil Diffuser {"NAME":"BrilexDiffuser","GPIO":[255,255,255,255,255,255,0,0,255,255,255,255,255],"FLAG":0,"BASE":54} Essential Oil 400ml {"NAME":"XD800W","GPIO":[255,255,255,255,255,255,0,0,255,255,255,255,255],"FLAG":0,"BASE":54} GD-30W 300ml {"NAME":"GD-30W","GPIO":[255,255,255,255,255,255,0,0,255,255,255,255,255],"FLAG":0,"BASE":54} +Kbaybo 300ml {"NAME":"K-H25","GPIO":[255,255,255,255,255,255,0,0,255,255,255,255,255],"FLAG":0,"BASE":54} Maxcio 400ml {"NAME":"MaxcioDiffuser","GPIO":[255,255,255,255,255,255,0,0,255,255,255,255,255],"FLAG":0,"BASE":54} Mirabella Genio Glass Aroma Diffuser 250ml {"NAME":"Genio Diffuser","GPIO":[0,0,0,0,37,38,0,0,0,160,22,39,21],"FLAG":15,"BASE":18} Wood Grain 550ML {"NAME":"MY-KCL01800FB","GPIO":[255,255,255,255,255,255,0,0,255,255,255,255,255],"FLAG":0,"BASE":54} ``` -## Bulb CCT -``` -AICase 800lm {"NAME":"AICase Smart L","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":18} -Ajax Online 380lm {"NAME":"AjaxOnline","GPIO":[17,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":38} -Ajax Online 7W Vintage {"NAME":"AjaxOnline-7W","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} -Anoopsyche 9W 800lm {"NAME":"Anoop-CW-WW","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":18} -Arlec GLD112HA 806lm {"NAME":"Arlec CCT","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":48} -BrilliantSmart 20696 9W 900lm {"NAME":"Brilliant20696","GPIO":[0,0,0,0,0,0,0,0,37,0,38,0,0],"FLAG":0,"BASE":48} -BrilliantSmart 20697 9W 900lm {"NAME":"Brilliant20699","GPIO":[0,0,0,0,0,0,0,0,37,0,38,0,0],"FLAG":0,"BASE":48} -Bulbrite Solana A19 Edison Filament {"NAME":"BulbBrite01","GPIO":[0,0,0,0,0,0,0,0,37,0,38,0,0],"FLAG":0,"BASE":18} -Calex 429036 G125 1055lm {"NAME":"Calex G125 E27","GPIO":[0,0,0,0,0,140,0,0,38,0,37,142,141],"FLAG":0,"BASE":18} -Deltaco SH-LE14W 470lm {"NAME":"SH-LE14W","GPIO":[0,0,0,0,0,140,0,0,38,0,37,142,141],"FLAG":0,"BASE":18} -Deltaco SH-LE27W 810lm {"NAME":"SH-LE27W","GPIO":[0,0,0,0,0,140,0,0,38,0,37,142,141],"FLAG":0,"BASE":18} -DGM L-WT9W1 800lm {"NAME":"DGM L-WT9W1","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":18} -DORESshop A60 720lm Filament {"NAME":"DORESshop-A60","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} -Energizer A19 10W {"NAME":"Energizer CCT ","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":18} -Geeni LUX 1050lm {"NAME":"Geeni-1050-WW","GPIO":[0,0,0,0,37,37,0,0,38,0,0,0,0],"FLAG":1,"BASE":18} -Globe 34919 ST19 Edison 500lm {"NAME":"Globe 34919","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} -Hama 176550 806lm {"NAME":"Hama Bulb xW","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":18} -Hykker SL-0392 650lm {"NAME":"Hykker 7W","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":18} -Iotton 9W 700lm {"NAME":"Iotton Light","GPIO":[0,0,0,0,37,38,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} -Kogan 10W Cool & Warm White 1050lm {"NAME":"Kogan White/Wa","GPIO":[0,0,0,0,37,40,0,0,41,38,39,0,0],"FLAG":0,"BASE":18} -LE LampUX 4.5W 410lm {"NAME":"LE LampUX","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":48} -ledscom.de 4.5W 430lm {"NAME":"GX53","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":0} -Lohas ZN070 720lm {"NAME":"Lohas ZN070","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} -Lumiman A19 7.5W 800lm {"NAME":"Lumiman LM520","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":18} -Luminea ZX-2831 {"NAME":"Luminea CCT","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} -Merkury MI-BW905-999W 700lm {"NAME":"MI-BW905-999W","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":18} -Mimoodz 1050lm {"NAME":"ID Components","GPIO":[0,0,0,0,21,22,0,0,23,24,25,26,27],"FLAG":0,"BASE":18} -Mirabella Genio 1002336 800lm {"NAME":"GenioBulbCCT","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":18} -Mirabella Genio 1002337 800lm {"NAME":"GenioBulbCCT","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":18} -Mirabella Genio 9W 800lm {"NAME":"GenioBulbCCT","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":18} -Mirabella Genio I002745 SES 470lm {"NAME":"Mirabella Candle","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} -Mirabella Genio I002746 500lm {"NAME":"GenioGU10","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} -Mirabella Genio I002747 G95 470lm {"NAME":"Genio Filament","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} -Nedis A60 800lm {"NAME":"WIFILW10WTE27","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":18} -Nedis C10 350lm {"NAME":"WIFILW10WTE14","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":18} -Nedis PAR16 330lm {"NAME":"Nedis WIFILW30","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":18} -Philips Zhirui Candle 250lm {"NAME":"Xiaomi Philips","GPIO":[0,0,0,0,0,0,0,0,38,0,0,37,0],"FLAG":0,"BASE":48} -Phillips Zhirui 450lm {"NAME":"Xiaomi Philips","GPIO":[0,0,0,0,0,0,0,0,38,0,0,37,0],"FLAG":0,"BASE":48} -Swisstone SH 330 806lm {"NAME":"SwisstoneSH330","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} -Wipro Garnet NS9100 810lm {"NAME":"WiproSmartBulb","GPIO":[0,0,0,0,38,38,0,0,37,37,0,0,0],"FLAG":0,"BASE":18} -Wyze WLPA19 A19 800lm {"NAME":"Wyze Bulb","GPIO":[0,0,0,0,0,0,0,0,0,37,47,0,0],"FLAG":0,"BASE":48} -``` - -## Bulb Cold White -``` -Feit Electric BR30/950CA/AG 650lm {"NAME":"Feit BR30 CW","GPIO":[0,0,0,0,0,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} -KMC 70113 A19 7.5W {"NAME":"Generic","GPIO":[0,0,0,0,0,0,37,38,0,0,0,0,0],"FLAG":15,"BASE":18} -Lohas LZN127 G25 800lm {"NAME":"Lohas Globe","GPIO":[0,0,0,0,0,0,0,0,0,0,37,0,0],"FLAG":0,"BASE":18} -Lohas ZN014 550lm {"NAME":"Lohas MR16","GPIO":[0,0,0,0,40,0,0,0,38,39,37,0,0],"FLAG":0,"BASE":18} -Lohas ZN124 980lm {"NAME":"Lohas LH-ZN124","GPIO":[0,0,0,0,0,0,0,0,0,0,37,0,0],"FLAG":0,"BASE":18} -Mirabella Genio 1002334 800lm {"NAME":"GenioBulbCW","GPIO":[0,0,0,0,38,37,0,0,0,40,39,0,0],"FLAG":0,"BASE":18} -Mirabella Genio A70 1400lm {"NAME":"GenioB_CW2744","GPIO":[0,0,0,0,0,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} -``` - -## Bulb Red Green Blue -``` -Deltaco SH-LE27RGB 810lm {"NAME":"SH-LE27RGB","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} -Halonix Prime Prizm 12W {"NAME":"Halonix Prizm ","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} -Jomarto 9W {"NAME":"Jomarto Wifi S","GPIO":[0,0,0,0,40,0,0,0,38,39,37,0,0],"FLAG":1,"BASE":18} -Lyasi PT-BW09 {"NAME":"Lyasi PT-BW09","GPIO":[17,0,0,0,143,144,0,0,0,0,0,0,0],"FLAG":0,"BASE":27} -MoKo YX-L01C-E27 810lm {"NAME":"MOKO","GPIO":[17,0,0,0,143,144,0,0,0,0,0,0,0],"FLAG":0,"BASE":27} -muvit IO miobulb001 600lm {"NAME":"miobulb001","GPIO":[0,0,0,0,40,0,0,0,38,39,37,0,0],"FLAG":15,"BASE":18} -Oobest ZN93028 11W {"NAME":"RGB Bulb 11W","GPIO":[0,0,0,0,40,0,0,0,38,39,37,0,0],"FLAG":1,"BASE":18} -Wipro Garnet NS7001 480lm {"NAME":"WiproSmartBulb","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} -``` - -## Bulb Red Green Blue CCT -``` -Aigital LE13 800lm {"NAME":"Aigital 9W RGB","GPIO":[0,0,0,0,41,38,0,0,39,0,40,37,0],"FLAG":0,"BASE":18} -Alfawise LE12 9W 900LM {"NAME":"Alfawise LE12 ","GPIO":[0,0,0,0,41,38,0,0,39,0,40,37,0],"FLAG":0,"BASE":18} -Aoycocr JL81 5W 400lm {"NAME":"AoycocrJLB1","GPIO":[0,0,0,0,39,0,0,0,38,41,37,40,0],"FLAG":0,"BASE":18} -Aoycocr Q0 750lm {"NAME":"AoycocrA19","GPIO":[0,0,0,0,0,39,0,0,38,0,37,40,0],"FLAG":0,"BASE":18} -Aoycocr Q10CWM 720lm {"NAME":"AoycocrBR30","GPIO":[0,0,0,0,0,39,0,0,38,0,37,40,0],"FLAG":0,"BASE":18} -Arlec GLD122HA 806lm {"NAME":"Arlec RGBWW","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} -Aunics 7W 600lm {"NAME":"Aunics RGBW","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} -Avatar ALB201W 720lm {"NAME":"AVATAR ALB201W","GPIO":[0,0,0,0,0,39,0,0,38,0,37,40,0],"FLAG":0,"BASE":18} -Avatar ALS18L A60 800lm {"NAME":"Avatar E14 7W","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":20} -B.K.Licht BKL1253 9W 806lm {"NAME":"BKL1253","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} -Bakibo TB95 9W 1000lm {"NAME":"Bakibo A19 9W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} -BlitzWolf BW-LT27 w/ remote 850lm {"NAME":"BW-LT27","GPIO":[0,0,0,0,41,38,0,0,39,51,40,37,0],"FLAG":0,"BASE":18} -BNeta IO-WIFI60-E27P 800lm {"NAME":"OM60/RGBW","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} -Bomcosy 600lm {"NAME":"Generic","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":1,"BASE":18} -Calex 429002 Reflector 350lm {"NAME":"Calex RGBW","GPIO":[0,0,0,0,0,0,0,0,181,0,180,0,0],"FLAG":0,"BASE":18} -Calex 429004 A60 806lm {"NAME":"Calex E27 RGB ","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} -Cleverio 51395 806lm {"NAME":"CleverioE27RGB","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} -CMARS 4W Reflector {"NAME":"RGBWW GU10","GPIO":[0,0,0,0,40,41,0,0,38,39,37,0,0],"FLAG":15,"BASE":18} -Dogain 320lm {"NAME":"DOGAIN","GPIO":[0,0,0,0,40,41,0,0,38,39,37,0,0],"FLAG":0,"BASE":18} -Emuni TB95 9W 850Lm {"NAME":"TB95","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} -Ener-J SHA5262 800lm {"NAME":"ENER-J RGBWWW ","GPIO":[0,0,0,0,40,41,0,0,38,39,37,0,0],"FLAG":0,"BASE":18} -Euri Lighting LIS-A1001 800lm {"NAME":"Euri Lighting ","GPIO":[0,0,0,0,37,40,0,0,38,41,39,37,0],"FLAG":0,"BASE":18} -EXUP C37 5W {"NAME":"EXUP","GPIO":[0,0,0,0,40,41,0,0,38,39,37,0,0],"FLAG":15,"BASE":18} -Feit Electric BPA800/RGBW/AG/2 800lm {"NAME":" BPA800/RGBW/AG/2","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} -Feit Electric BPA800/RGBW/AG/2(P) 800lm {"NAME":" BPA800/RGBW/AG/2P","GPIO":[0,0,0,0,37,38,0,0,141,142,140,0,0],"FLAG":0,"BASE":48} -Feit Electric OM100/RGBW/CA/AG 1600lm {"NAME":"OM100/RGBWW","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} -Feit Electric OM60/RGBW/15K/AG 800lm {"NAME":"FE-OM60-15K-AG","GPIO":[0,0,0,0,141,140,0,0,37,142,38,0,0],"FLAG":0,"BASE":18} -Feit Electric OM60/RGBW/CA/AG 800lm {"NAME":"OM60/RGBW","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} -Fulighture 9W 810lm {"NAME":"Fulighture 9W","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} -Geeni Prisma Plus 800lm {"NAME":"Geeni Prisma P","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} -Globe 34207 800lm {"NAME":"GlobeRGBWW","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} -Jeeo TF-QPZ13 800lm {"NAME":"Jeeo","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} -Julun JL-021 5W Candle {"NAME":"E14 RGBCCT","GPIO":[0,0,0,0,40,41,0,0,38,39,37,0,0],"FLAG":0,"BASE":18} -Kohree 600lm {"NAME":"Kohree VHP560","GPIO":[0,0,0,0,37,41,0,0,38,40,39,0,0],"FLAG":0,"BASE":18} -LE lampUX A19 850lm {"NAME":"LE RGBWW 60W","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":1,"BASE":18} -Ledmundo 6W 600lm {"NAME":"LEDMUNDO 6W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} -Legelite 5W Candle {"NAME":"Legelite E12","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} -Legelite A60 7W {"NAME":"Legelite A60 7","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} -Legelite A60 7W 600lm {"NAME":"Legelite E26","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} -Lohas ZN031 650lm {"NAME":"Lohas ZN031","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} -Lohas ZN033 810lm {"NAME":"Lohas RGBWW","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} -Lohas ZN036 900 lm {"NAME":"Lohas RGBCCT","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} -Lohas ZN037 450lm {"NAME":"Lohas LH-ZN037","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":20} -Lumary 9W 800lm {"NAME":"Lumary / iLint","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} -LVWIT A60 8.5W 806lm {"NAME":"LVWIT A60 8.5W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} -LVWIT A70 12W 1521lm {"NAME":"LVWIT A70 12W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} -Novostella HM-LB09 13W 1300lm {"NAME":"Novostella 13W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} -Novostella NTB10 9W 900lm {"NAME":"NTB10","GPIO":[0,0,0,0,41,38,0,0,39,0,40,37,0],"FLAG":0,"BASE":18} -Novostella UT55505 7W 600lm {"NAME":"Novostella B22","GPIO":[0,0,0,0,37,41,0,0,38,40,39,0,0],"FLAG":0,"BASE":18} -Novostella UT55508 12W 1150lm {"NAME":"Novostella","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} -Novostella UT55509 13W 1300lm {"NAME":"Novostella 13W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} -Ohlux A19 7W 600lm {"NAME":"OHLUX","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} -Ohlux BR30 10W 900lm {"NAME":"OHLUX","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} -Powertech SL225X 800lm {"NAME":"Jaycar SL225X","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} -Qualitel ALS08L 1100lm {"NAME":"Qualitel ALS08","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} -Reafoo A26 9W {"NAME":"ReaFooE26","GPIO":[0,0,0,0,41,38,0,0,39,0,40,37,0],"FLAG":0,"BASE":18} -RYE 5W 450LM Candle {"NAME":"RYE Candlebra","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} -Saudio A19 7W 700lm {"NAME":"X002BU0DOL","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} -Slitinto TB95 9W 1000lm {"NAME":"Slitinto 9W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} -Sonoff B1 (R2) {"NAME":"Sonoff B1","GPIO":[17,0,0,0,0,0,0,0,143,0,144,0,0],"FLAG":0,"BASE":26} -Sunco G25 5W 450lm {"NAME":"Sunco G25","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} -Sunco PAR20 5W 400lm {"NAME":"Sunco PAR20","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} -Teckin SB50-2 800lm {"NAME":"Teckin SB50v3","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} -Teckin SB53 1300lm {"NAME":"Teckin SB53","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} -V-Tac VT-5164 400lm {"NAME":"V-TAC VT5164","GPIO":[0,0,0,0,0,0,0,0,181,0,180,0,0],"FLAG":0,"BASE":18} -Wipro Garnet NS9001 810lm {"NAME":"WiproSmartBulb","GPIO":[0,0,0,0,37,41,0,0,38,40,39,0,0],"FLAG":0,"BASE":18} -ZZHXON 600lm {"NAME":"E27_RGB_Bulb","GPIO":[0,0,0,0,40,41,0,0,38,39,37,0,0],"FLAG":0,"BASE":18} -``` - -## Bulb Red Green Blue White -``` -3Stone EBE-QPW36 1050lm {"NAME":"3STONE","GPIO":[0,0,0,0,141,140,0,0,37,142,0,0,0],"FLAG":15,"BASE":18} -Accewit 7W 650lm {"NAME":"Accewit Bulb","GPIO":[0,0,0,0,0,38,0,0,39,0,40,37,0],"FLAG":0,"BASE":18} -Aisirer 7W 580lm {"NAME":"Aisirer RGBW","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} -Aisirer 7W 580lm {"NAME":"Aisirer RGBW","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} -AL Above Lights 810lm {"NAME":"AL 810LM","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} -Aoycocr Q3CM 230lm {"NAME":"Aoycocr_GU10","GPIO":[0,0,0,0,0,0,0,0,143,0,144,0,0],"FLAG":0,"BASE":27} -Avatar ALS08L A19 910lm {"NAME":"Avatar E27 7W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":20} -Avatar ALS09L A60 900lm {"NAME":"Avatar E14 9W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":20} -Avatar ALS11L PAR16 500lm {"NAME":"Avatar_GU10","GPIO":[0,0,0,0,0,0,0,0,0,143,0,144,0],"FLAG":0,"BASE":27} -AWOW A60 9W 800lm {"NAME":"AWOW 9W RGBW","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} -Axtee AI-003 A19 700lm {"NAME":"Axtee E26 7W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":20} -Bawoo EUWL122130 925lm {"NAME":"Bawoo","GPIO":[0,0,0,0,140,37,0,0,0,142,141,0,0],"FLAG":0,"BASE":18} -BlitzWolf BW-LT21 900lm {"NAME":"BlitzWolf LT21","GPIO":[0,0,0,0,41,39,0,0,38,0,37,40,0],"FLAG":0,"BASE":18} -BNeta IO-WIFI-GU10 380lm {"NAME":"BNeta","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} -BriHome 6,5W 500lm {"NAME":"BRI E27 6,5W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":20} -Brilliant HK17653S72 350lm {"NAME":"HK17653S72","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} -BrilliantSmart 20698 9W 800lm {"NAME":"Brilliant20698","GPIO":[0,0,0,0,141,140,0,0,37,142,0,0,0],"FLAG":0,"BASE":18} -BrilliantSmart 20699 9W 800lm {"NAME":"Brilliant20699","GPIO":[0,0,0,0,141,140,0,0,37,142,0,0,0],"FLAG":0,"BASE":18} -BrilliantSmart 20741 9W 750lm {"NAME":"Brilliant RGB+","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} -BrizLabs A19 9W 806LM {"NAME":"TCP Smart RGBW","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} -BrizLabs Candle 4,5W 350lm {"NAME":"BrizLabs RGBW","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} -Brizlabs EBE-LZW10 350Lm {"NAME":"Brizlabs E14","GPIO":[0,0,0,0,141,140,0,0,37,142,0,0,0],"FLAG":15,"BASE":18} -BrizLabs EBE-SHW03 380lm {"NAME":"BrizLabs","GPIO":[0,0,0,0,140,37,0,0,0,142,141,0,0],"FLAG":0,"BASE":18} -BTZ1 {"NAME":"WifiBulb","GPIO":[0,0,0,0,0,37,0,0,39,40,38,0,0],"FLAG":0,"BASE":18} -Calex 429008 B35 5W 470lm {"NAME":"Calex E14 RGBW","GPIO":[0,0,0,0,0,0,0,0,181,0,180,0,0],"FLAG":0,"BASE":18} -Cleverio 51398 370lm {"NAME":"CleverioGU10","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} -Cocoon DY180363-B 800lm {"NAME":"Cocoon RGBW","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} -electriQ 600lm {"NAME":"ElectricQ B22","GPIO":[0,0,0,0,37,41,0,0,38,40,39,0,0],"FLAG":0,"BASE":18} -EleLight 350lm {"NAME":"EleLight 7wA19","GPIO":[0,0,0,0,140,37,0,0,0,142,141,0,0],"FLAG":0,"BASE":18} -Esicoo 810lm {"NAME":"Esicoo Bulb","GPIO":[0,0,0,0,143,144,0,0,0,0,0,0,0],"FLAG":0,"BASE":27} -Fcmila 10W {"NAME":"FCMILA LED E27","GPIO":[0,0,0,0,40,0,0,0,38,39,37,0,0],"FLAG":0,"BASE":18} -Fcmila 7W {"NAME":"FCMILA E27 0.1","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} -Fcmila Spotlight 460lm {"NAME":"Fcmila LED 6W","GPIO":[0,0,0,0,40,0,0,0,38,39,37,0,0],"FLAG":0,"BASE":18} -Feit Electric BR30/RGBW/CA/AG 650lm {"NAME":"BR30/RGBW","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} -Fulighture A60 810lm {"NAME":"Fulighture A60","GPIO":[0,0,0,0,38,37,0,0,0,39,40,0,0],"FLAG":0,"BASE":18} -Geeni Prisma 1050lm {"NAME":"Geeni 1050 RGB","GPIO":[37,0,0,0,140,38,0,0,0,142,141,0,0],"FLAG":0,"BASE":18} -Generic 10W {"NAME":"10W E27 RGBW","GPIO":[0,0,0,0,0,39,0,0,38,0,37,40,0],"FLAG":0,"BASE":18} -Generic GU10 5W 450lm {"NAME":"RGBCW GU10","GPIO":[0,255,0,255,40,0,0,0,38,39,37,0,0],"FLAG":0,"BASE":3} -Gosund WB3 8W 800lm {"NAME":"Gosund WB3","GPIO":[0,0,0,0,40,0,0,0,37,38,39,0,0],"FLAG":0,"BASE":18} -Hama 176531 1050lm {"NAME":"Hama Bulb RGBW","GPIO":[0,0,0,0,140,37,0,0,0,142,141,0,0],"FLAG":0,"BASE":18} -Hama 176547 806lm {"NAME":"hama_rgb","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} -Hykker SL-0492 810lm {"NAME":"Hykker RBGW 9W","GPIO":[0,0,0,0,0,40,0,0,37,0,39,38,0],"FLAG":0,"BASE":18} -iDigital Smart Home Wifi Globe 9W {"NAME":"iDigitalRGB+WW","GPIO":[0,0,0,0,0,40,0,0,37,0,39,38,0],"FLAG":0,"BASE":18} -Kainsy 600lm {"NAME":"KAINSY","GPIO":[17,0,0,0,143,144,0,0,0,0,0,0,0],"FLAG":0,"BASE":27} -Koaanw 650lm {"NAME":"KOAANW Bulb","GPIO":[0,0,0,0,143,144,0,0,0,0,0,0,0],"FLAG":0,"BASE":27} -Kogan 10W Ambient 1050lm {"NAME":"Kogan RGB","GPIO":[0,0,0,0,140,37,0,0,0,0,141,0,0],"FLAG":0,"BASE":18} -Kogan Ambient Candle {"NAME":"Kogan_E14","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} -Kogan Ambient Spotlight 330lm {"NAME":"Kogan_GU10","GPIO":[0,0,0,0,39,40,0,0,37,0,38,0,0],"FLAG":0,"BASE":18} -Kuled 800lm {"NAME":"KULED 60W RGB","GPIO":[0,0,0,0,39,40,0,0,37,0,38,0,0],"FLAG":1,"BASE":18} -Laideyi 7W {"NAME":"7W-E14-RGBW-La","GPIO":[0,0,0,0,38,37,0,0,39,0,40,0,0],"FLAG":0,"BASE":18} -LeCardio 10W 980lm {"NAME":"LeCardio RGBW","GPIO":[0,0,0,0,40,0,0,0,38,39,37,0,0],"FLAG":0,"BASE":18} -Lohas ZN001 810lm {"NAME":"Lohas RGBW","GPIO":[0,0,0,0,0,0,0,0,0,143,0,144,0],"FLAG":0,"BASE":18} -Lohas ZN001-E12 810lm {"NAME":"Lohas","GPIO":[0,0,0,0,0,0,0,0,0,143,0,144,0],"FLAG":0,"BASE":26} -Lohas ZN005 420lm {"NAME":"Lohas E14 R50","GPIO":[17,0,0,0,0,0,0,0,0,143,0,144,0],"FLAG":0,"BASE":27} -Lohas ZN006 1380lm {"NAME":"Lohas100 RGBW","GPIO":[0,0,0,0,0,0,0,0,0,143,0,144,0],"FLAG":0,"BASE":18} -Lohas ZN012 450lm {"NAME":"LH-5W-ZN01204","GPIO":[0,0,0,0,0,0,0,0,0,143,0,144,0],"FLAG":0,"BASE":27} -Lonsonho 900lm {"NAME":"RGB+W+C Bulb","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} -LSC Smart Connect C45 400lm {"NAME":"LSC RGBCW E14","GPIO":[0,0,0,0,0,0,0,0,181,0,180,0,0],"FLAG":0,"BASE":18} -LSC Smart Connect MR16 380lm {"NAME":"LSC RGBCW GU10","GPIO":[0,0,0,0,0,0,0,0,181,0,180,0,0],"FLAG":0,"BASE":18} -Lumiman LM530 7.5W 800lm {"NAME":"Lumiman LM530","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":1,"BASE":18} -Lumiman LM530 7.5W 800lm {"NAME":"Lumiman LM530","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":1,"BASE":18} -Lumiman LM530 7.5W 800lm {"NAME":"LM530","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":1,"BASE":18} -Luminea ZX-2832 {"NAME":"Luminea RGBW","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":1,"BASE":18} -Luminea ZX-2986 1400lm {"NAME":"Luminea RGBW","GPIO":[0,0,0,0,37,41,0,0,0,38,39,40,0],"FLAG":0,"BASE":18} -LWE3 600lm {"NAME":"Linganzh LWE3 ","GPIO":[0,0,0,0,0,38,0,0,39,0,40,37,0],"FLAG":0,"BASE":18} -Manzoku XS-001 1050lm {"NAME":"Manzoku RGBW","GPIO":[0,0,0,0,40,0,0,0,38,39,37,0,0],"FLAG":0,"BASE":18} -Maxcio YX-L01P-E27-2P 9W {"NAME":"Maxcio YXL01P","GPIO":[17,0,0,0,143,144,0,0,0,0,0,0,0],"FLAG":0,"BASE":27} -Merkury MI-BW210-999W 1050lm {"NAME":"MI-BW210-999W","GPIO":[0,0,0,0,140,37,0,0,142,38,141,0,0],"FLAG":0,"BASE":48} -Merkury MI-BW904-999W 1050lm {"NAME":"MI-BW904-999W","GPIO":[0,0,0,0,140,37,0,0,0,142,141,0,0],"FLAG":0,"BASE":18} -Merkury MI-BW904-999W v2 1050lm {"NAME":"MI-BW210-999W","GPIO":[0,0,0,0,38,37,0,0,141,142,140,0,0],"FLAG":0,"BASE":48} -Merkury MI-BW904-999W v3 {"NAME":"MI-BW904-999W","GPIO":[0,0,0,0,37,38,0,0,141,142,140,0,0],"FLAG":0,"BASE":69} -Merkury MI-BW906-999W BR30 750lm {"NAME":"MI-BW906-999W","GPIO":[0,0,0,0,38,37,0,0,141,142,140,0,0],"FLAG":0,"BASE":18} -Mirabella Genio 1002338 800lm {"NAME":"GenioBulbRGB","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":1,"BASE":18} -Mixigoo 950lm {"NAME":"Mixigoo Bulb","GPIO":[0,0,0,0,41,38,0,0,39,0,37,40,0],"FLAG":0,"BASE":18} -MoKo JL81 5W 400lm {"NAME":"MoKo E14","GPIO":[0,0,0,0,0,0,0,0,143,0,144,0,0],"FLAG":0,"BASE":27} -Nedis A60 800lm {"NAME":"Nedis RGBW","GPIO":[0,0,0,0,140,37,0,0,0,142,141,0,0],"FLAG":1,"BASE":18} -Nedis C10 350lm {"NAME":"Nedis WIFILC10","GPIO":[0,0,0,0,39,37,0,0,40,38,41,0,0],"FLAG":1,"BASE":18} -Nedis PAR16 330lm {"NAME":"Nedis GU10","GPIO":[0,0,0,0,39,37,0,0,40,38,41,0,0],"FLAG":0,"BASE":18} -NiteBird TT-WB4 800lm {"NAME":"NiteBird TT-WB","GPIO":[0,0,0,0,40,0,0,0,37,38,39,0,0],"FLAG":0,"BASE":18} -Orbecco 5W 400lm {"NAME":"Orbecco Bulb","GPIO":[0,0,0,0,0,0,0,0,143,0,144,0,0],"FLAG":0,"BASE":27} -Premier A19 10W {"NAME":"Premier Light","GPIO":[0,0,0,0,0,39,0,0,38,0,37,40,0],"FLAG":1,"BASE":18} -Riversong Juno 10W {"NAME":"Juno10","GPIO":[0,0,0,0,140,37,0,0,0,142,141,0,0],"FLAG":0,"BASE":18} -Rogoei EBE-QPZ04 6.5W 450lm {"NAME":"EBE-QPZ04","GPIO":[0,0,0,0,180,0,0,0,0,0,181,0,0],"FLAG":0,"BASE":18} -Smart 810lm {"NAME":"OOOLED 60W RGB","GPIO":[0,0,0,0,39,40,0,0,37,0,38,0,0],"FLAG":1,"BASE":18} -Smartyfi 600lm {"NAME":"SMARTYFI 9W","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} -Solimo 12W {"NAME":"Solimo RGBWW12","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} -Solimo 810lm {"NAME":"Solimo RGBWW 9","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} -Swisstone SH 340 806lm {"NAME":"SH 340","GPIO":[0,0,0,0,140,37,0,0,0,142,141,0,0],"FLAG":15,"BASE":18} -Syska 720lm {"NAME":"SyskaSmartBulb","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} -TCP Smart 806lm {"NAME":"TCP Smart RGBW","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} -Teckin SB50 800lm {"NAME":"Teckin SB50","GPIO":[0,0,0,0,40,0,0,0,38,39,37,0,0],"FLAG":0,"BASE":18} -Teckin SB50 v2 800lm {"NAME":"Teckin SB50","GPIO":[0,0,0,0,37,0,0,0,38,40,39,0,0],"FLAG":0,"BASE":18} -Teckin SB51 800lm {"NAME":"Teckin SB51","GPIO":[0,0,0,0,40,0,0,0,38,39,37,0,0],"FLAG":0,"BASE":18} -TikLOk TL530 A19 7.5W 800lm {"NAME":"TikLOk WW-CW-L","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":18} -Utorch LE7 600lm {"NAME":"Utorch LE7","GPIO":[0,0,0,0,0,38,0,0,39,0,40,37,0],"FLAG":0,"BASE":18} -V-Tac VT-5113 1055lm {"NAME":"V-TAC LED A60 ","GPIO":[0,0,0,0,180,0,0,0,0,0,181,0,0],"FLAG":0,"BASE":18} -Wallfire WF-05 {"NAME":"Wallfire E27","GPIO":[17,0,0,0,0,0,0,0,0,143,0,144,0],"FLAG":0,"BASE":27} -Woopower 460lm {"NAME":"Woopower E14","GPIO":[0,0,0,0,0,0,0,0,0,143,0,144,0],"FLAG":0,"BASE":27} -WOOX R4553 650lm {"NAME":"WOOX R4553","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} -WOOX R5076 4W 350lm {"NAME":"WOOX R4553","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} -Woox R5077 {"NAME":"WOOX R5077","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} -Zemismart 5W {"NAME":"Zemismart_GU10","GPIO":[0,0,0,0,0,0,0,0,0,143,0,144,0],"FLAG":0,"BASE":27} -Zilotek A19 800lm {"NAME":"Zilotek RGBW","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} -``` - -## Bulb Warm White -``` -Aisirer 9W 806lm {"NAME":"Aisirer 9W","GPIO":[0,0,0,0,0,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} -Aisirer 9W 806lm {"NAME":"AISIRER E26","GPIO":[0,0,0,0,0,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} -Aisirer 9W 806lm {"NAME":"Aisirer 9W","GPIO":[0,0,0,0,0,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} -Avatar ALS15L Candle {"NAME":"AVATAR","GPIO":[0,0,0,0,0,0,0,0,0,143,0,144,0],"FLAG":0,"BASE":27} -Cleverio 51396 800lm {"NAME":"Cleverio E27","GPIO":[0,0,0,0,0,0,0,0,0,0,46,0,0],"FLAG":0,"BASE":18} -Connect Smart 10W {"NAME":"CSH-B22WW10W","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":18} -DORESshop B11 600lm Filament {"NAME":"Doresshop-cand","GPIO":[0,0,0,0,0,0,0,0,0,0,37,0,0],"FLAG":0,"BASE":18} -DORESshop ST64 720lm Filament {"NAME":"DORESshop-ST64","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} -Feit Electric BR30/927CA/AG 650lm {"NAME":"Feit BR30 WW","GPIO":[0,0,0,0,0,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} -Feit Electric OM60/927CA/AG 800lm {"NAME":" Feit P_A800_2","GPIO":[0,0,0,0,0,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} -Geeni LUX Edison {"NAME":"Geeni-Edison","GPIO":[0,0,0,0,0,0,0,0,0,0,37,0,0],"FLAG":0,"BASE":18} -Globe 34209 800lm {"NAME":"Globe WW 800lm","GPIO":[0,0,0,0,0,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} -Kogan ST-20 Filament {"NAME":"Kogan Filament","GPIO":[0,0,0,0,0,0,0,0,0,0,37,0,0],"FLAG":15,"BASE":18} -LeDesign 8W ST21 Filament {"NAME":"Edison Bulb","GPIO":[0,0,0,0,0,0,0,0,0,37,0,0,0],"FLAG":0,"BASE":18} -LSC Smart Connect Filament A60 {"NAME":"LSC Filam E27","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} -LSC Smart Connect Filament C35 {"NAME":"LSC Filam E14","GPIO":[0,255,0,255,0,0,0,0,38,0,37,0,0],"FLAG":15,"BASE":18} -LSC Smart Connect Filament G125 {"NAME":"LSC Filam Huge","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} -LSC Smart Connect Filament ST64 {"NAME":"LSC Filam Big","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} -Lumary 6W 700lm Edison {"NAME":"Lumary TS3Y","GPIO":[0,0,0,0,0,0,0,0,0,37,0,0,0],"FLAG":0,"BASE":18} -Luminea ZX-2982 ST64 Filament {"NAME":"Luminea ZX2982","GPIO":[0,0,0,0,0,0,0,0,0,0,37,0,0],"FLAG":0,"BASE":18} -Merkury MI-BW902-999W 800lm {"NAME":"MI-BW902-999W","GPIO":[0,0,0,0,0,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} -Merkury MI-BW942-999W 800lm {"NAME":"MI-BW942-999W","GPIO":[0,0,0,0,37,0,0,0,0,52,0,0,0],"FLAG":0,"BASE":18} -Merkury MIC-BW902-999W {"NAME":"MI-BW902-999W","GPIO":[0,0,0,0,0,0,0,0,0,0,37,0,0],"FLAG":0,"BASE":18} -Merkury Vintage Edison A19 {"NAME":"Merkury A19 Ed","GPIO":[0,0,0,0,0,0,0,0,0,0,37,0,0],"FLAG":0,"BASE":18} -Nedis A60 Filament {"NAME":"WIFILF10WTA60","GPIO":[0,0,0,0,0,0,0,0,0,0,37,0,0],"FLAG":0,"BASE":18} -Nedis G125 Filament {"NAME":"WIFILF10GDG125","GPIO":[0,0,0,0,0,0,0,0,0,0,37,0,0],"FLAG":0,"BASE":18} -Nedis PAR16 330lm {"NAME":"Nedis WIFILW31","GPIO":[0,0,0,0,0,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} -Sealight Vintage Edison A19 {"NAME":"SealightEdison","GPIO":[0,0,0,0,0,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} -``` - ## Bulb Socket ``` Elegant Choice E27/E26 {"NAME":"name","GPIO":[0,0,0,0,0,0,0,0,0,0,0,21,0],"FLAG":0,"BASE":18} @@ -299,6 +24,60 @@ Slampher {"NAME":"Slampher","GPIO":[17,255,0,255,0,0,0,0,21,56,0 SmartBase E0260 {"NAME":"SmartBaseE0260","GPIO":[0,0,0,0,56,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} ``` +## CCT +``` +AICase 800lm {"NAME":"AICase Smart L","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":18} +Ajax Online 380lm {"NAME":"AjaxOnline","GPIO":[17,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":38} +Ajax Online 7W Vintage {"NAME":"AjaxOnline-7W","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} +Anoopsyche 9W 800lm {"NAME":"Anoop-CW-WW","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":18} +Arlec Smart 1350lm PAR38 {"NAME":"Arlec GLD302HA","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} +Arlec Smart 9.5W 806lm {"NAME":"Arlec GLD110HA","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":48} +Arlec Smart 9.5W 806lm {"NAME":"Arlec CCT","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":48} +BrilliantSmart 20696 9W 900lm {"NAME":"Brilliant20696","GPIO":[0,0,0,0,0,0,0,0,37,0,38,0,0],"FLAG":0,"BASE":48} +BrilliantSmart 20697 9W 900lm {"NAME":"Brilliant20699","GPIO":[0,0,0,0,0,0,0,0,37,0,38,0,0],"FLAG":0,"BASE":48} +Bulbrite Solana A19 Edison Filament {"NAME":"BulbBrite01","GPIO":[0,0,0,0,0,0,0,0,37,0,38,0,0],"FLAG":0,"BASE":18} +Calex G125 7,5W 1055lm {"NAME":"Calex G125 E27","GPIO":[0,0,0,0,0,140,0,0,38,0,37,142,141],"FLAG":0,"BASE":18} +Calex G125 7.5W 1055lm Globe {"NAME":"Calex G125 E27","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} +Deltaco SH-LE14W 470lm {"NAME":"SH-LE14W","GPIO":[0,0,0,0,0,140,0,0,38,0,37,142,141],"FLAG":0,"BASE":18} +Deltaco SH-LE27W 810lm {"NAME":"SH-LE27W","GPIO":[0,0,0,0,0,140,0,0,38,0,37,142,141],"FLAG":0,"BASE":18} +DORESshop A60 720lm Filament {"NAME":"DORESshop-A60","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} +Energizer A19 10W {"NAME":"Energizer CCT ","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":18} +Euri Lighting A19 10W 800lm {"NAME":"Euri Lighting ","GPIO":[0,0,0,0,37,38,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} +Geeni LUX 1050lm {"NAME":"Geeni-1050-WW","GPIO":[0,0,0,0,37,37,0,0,38,0,0,0,0],"FLAG":1,"BASE":18} +Globe 34208 A19 800lm {"NAME":"GlobeCCT","GPIO":[0,0,0,0,38,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} +Globe 34919 ST19 Edison 500lm {"NAME":"Globe 34919","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} +Hama 806lm {"NAME":"Hama 00176550","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":18} +Hykker SL-0392 650lm {"NAME":"Hykker 7W","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":18} +Iotton 9W 700lm {"NAME":"Iotton Light","GPIO":[0,0,0,0,37,38,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} +Kogan 10W Cool & Warm White 1050lm {"NAME":"Kogan White/Wa","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":18} +LE lampUX 380lm Candle {"NAME":"LE Bulb","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} +LE LampUX 4.5W 410lm {"NAME":"LE LampUX","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":48} +ledscom.de 4.5W 430lm {"NAME":"GX53","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":0} +Lohas ZN070 720lm {"NAME":"Lohas ZN070","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} +Lumiman A19 7.5W 800lm {"NAME":"Lumiman LM520","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":18} +Luminea ZX-2831 {"NAME":"Luminea CCT","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} +LVWIT A60 6.5W 806lm Filament {"NAME":"LVWIT-E27-WiFi-6.5","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} +Merkury MI-BW905-999W 700lm {"NAME":"MI-BW905-999W","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":18} +Mimoodz 1050lm {"NAME":"ID Components","GPIO":[0,0,0,0,21,22,0,0,23,24,25,26,27],"FLAG":0,"BASE":18} +Mirabella Genio 9W 800lm {"NAME":"GenioBulbCCT","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":18} +Mirabella Genio 9W 800lm {"NAME":"GenioBulbCCT","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":18} +Mirabella Genio 9W 800lm {"NAME":"GenioBulbCCT","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":18} +Mirabella Genio I002745 SES 470lm {"NAME":"Mirabella Candle","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} +Mirabella Genio I002746 500lm {"NAME":"GenioGU10","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} +Mirabella Genio I002747 G95 470lm {"NAME":"Genio Filament","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} +Nedis A60 800lm {"NAME":"WIFILW10WTE27","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":18} +Nedis C10 350lm {"NAME":"WIFILW10WTE14","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":18} +Nedis PAR16 330lm {"NAME":"Nedis WIFILW30","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":18} +Nedis PAR16 4.5W 330lm 110 {"NAME":"WIFILW30","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":18} +Philips Zhirui Candle 250lm {"NAME":"Xiaomi Philips","GPIO":[0,0,0,0,0,0,0,0,38,0,0,37,0],"FLAG":0,"BASE":48} +Phillips Zhirui 450lm {"NAME":"Xiaomi Philips","GPIO":[0,0,0,0,0,0,0,0,38,0,0,37,0],"FLAG":0,"BASE":48} +SmartDGM L-WT9W1 9W 800lm {"NAME":"L-WT9W1","GPIO":[0,0,0,0,0,37,0,0,9,38,0,0,0],"FLAG":0,"BASE":18} +Swisstone SH 330 806lm {"NAME":"SwisstoneSH330","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} +Vestaiot BR30 800lm {"NAME":"Vesta BR30 CCT","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":18} +Wipro Garnet NS9100 810lm {"NAME":"WiproSmartBulb","GPIO":[0,0,0,0,38,38,0,0,37,37,0,0,0],"FLAG":0,"BASE":18} +Wyze WLPA19 A19 800lm {"NAME":"Wyze Bulb","GPIO":[0,0,0,0,0,0,0,0,0,37,38,0,0],"FLAG":0,"BASE":48} +``` + ## Curtain Motor ``` Zemismart BCM300D-TY {"NAME":"Zemistart_Curt","GPIO":[0,0,0,0,0,0,0,0,0,108,0,107,0],"FLAG":0,"BASE":54} @@ -307,8 +86,11 @@ Zemismart BCM300D-TY {"NAME":"Zemistart_Curt","GPIO":[0,0,0,0,0,0,0,0,0,108, ## Curtain Switch ``` Anccy Relax {"NAME":"Tuya Shutter","GPIO":[157,0,54,10,22,19,0,0,17,21,53,23,52],"FLAG":0,"BASE":18} +Etersky WF-CS01 {"NAME":"Etersky","GPIO":[157,0,53,19,23,18,0,0,17,21,54,22,52],"FLAG":0,"BASE":18} Homecube Blinds and Curtains {"NAME":"Jinvoo Curtain","GPIO":[52,0,0,18,22,19,0,0,17,21,0,23,0],"FLAG":1,"BASE":18} -Jinvoo SM-SW101-C Curtain {"NAME":"Jinvoo Curtain","GPIO":[52,0,0,18,22,19,0,0,17,21,0,23,0],"FLAG":1,"BASE":18} +Jinvoo SM-SW101-C {"NAME":"Jinvoo Curtain","GPIO":[52,0,0,18,22,19,0,0,17,21,0,23,0],"FLAG":1,"BASE":18} +LoraTap SC400W-EU {"NAME":"Loratap SC400W","GPIO":[0,0,0,19,0,17,0,0,18,22,0,21,0],"FLAG":0,"BASE":18} +LoraTap SC411WSC-EU RF Remote {"NAME":"Loratap","GPIO":[0,0,0,19,23,17,0,0,18,22,0,21,0],"FLAG":0,"BASE":18} LoraTap SC511WSC Roller Shutter {"NAME":"SC511WSC","GPIO":[0,255,0,56,17,18,0,0,21,19,22,0,0],"FLAG":0,"BASE":18} Teekar SYS-CS 01 {"NAME":"Teekar-Tag","GPIO":[56,0,157,18,22,11,0,0,0,21,57,31,17],"FLAG":0,"BASE":18} Teepao {"NAME":"Taopao","GPIO":[255,255,255,18,22,19,0,0,255,21,255,255,17],"FLAG":1,"BASE":18} @@ -319,33 +101,88 @@ WF-CS02 {"NAME":"WF-CS02 Tuya","GPIO":[157,0,53,11,23,18,0,0,17 ## DIY ``` Adafruit HUZZAH {"NAME":"Huzzah","GPIO":[17,0,56,0,255,255,0,0,255,255,255,255,255],"FLAG":0,"BASE":18} +ESP-01(S) {"NAME":"ESP01","GPIO":[255,255,255,255,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} +ESP-M3 {"NAME":"ESP-M3","GPIO":[255,255,255,255,255,0,0,0,0,255,255,0,255],"FLAG":0,"BASE":18} Heltec WiFi Kit 8 {"NAME":"HTIT-W8266","GPIO":[255,255,255,255,6,5,0,0,255,255,255,255,162],"FLAG":15,"BASE":18} LC Tech relay and PZEM-004T {"NAME":"HW-655 PZEM","GPIO":[0,63,0,62,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} Luani HVIO {"NAME":"Luani HVIO","GPIO":[0,255,255,255,21,22,0,0,9,10,255,52,0],"FLAG":1,"BASE":35} +OLED Display Module 0.66" for Wemos D1 Mini {"NAME":"OLED 64x48","GPIO":[255,255,255,255,6,5,0,0,255,255,255,255,162],"FLAG":15,"BASE":18} Splatura USB Device Power Switch {"NAME":"Splatura USB","GPIO":[0,0,52,0,0,0,0,0,0,21,0,122,0],"FLAG":0,"BASE":18} SUPLA inCan by Espablo {"NAME":"Supla Espablo","GPIO":[0,255,4,255,17,21,0,0,255,22,255,0,52],"FLAG":1,"BASE":31} Witty Cloud {"NAME":"Witty Cloud","GPIO":[255,255,56,255,17,255,0,0,38,39,255,37,255],"FLAG":1,"BASE":32} ``` +## Dimmable +``` +Aisirer 9W 806lm {"NAME":"Aisirer 9W","GPIO":[0,0,0,0,0,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} +Aisirer 9W 806lm {"NAME":"AISIRER E26","GPIO":[0,0,0,0,0,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} +Aisirer 9W 806lm {"NAME":"Aisirer 9W","GPIO":[0,0,0,0,0,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} +Arlec Smart 4W 380lm Candle {"NAME":"Arlec Bulb 4W","GPIO":[0,0,0,0,0,0,0,0,0,0,37,0,0],"FLAG":0,"BASE":18} +Arlec Smart 9W 950lm 4000K {"NAME":"Arlec-GLD124HA","GPIO":[0,0,0,0,0,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} +Avatar ALS15L Candle {"NAME":"AVATAR","GPIO":[0,0,0,0,0,0,0,0,0,143,0,144,0],"FLAG":0,"BASE":27} +Cleverio 51396 800lm {"NAME":"Cleverio E27","GPIO":[0,0,0,0,0,0,0,0,0,0,46,0,0],"FLAG":0,"BASE":18} +Connect Smart 10W {"NAME":"CSH-B22WW10W","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":18} +DORESshop B11 600lm Filament {"NAME":"Doresshop-cand","GPIO":[0,0,0,0,0,0,0,0,0,0,37,0,0],"FLAG":0,"BASE":18} +DORESshop ST64 720lm Filament {"NAME":"DORESshop-ST64","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} +Feit Electric 800lm {"NAME":" Feit P_A800_2","GPIO":[0,0,0,0,0,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} +Feit Electric BR30 650lm {"NAME":"Feit BR30 WW","GPIO":[0,0,0,0,0,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} +Feit Electric BR30 650lm {"NAME":"Feit BR30 CW","GPIO":[0,0,0,0,0,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} +Geeni LUX Edison {"NAME":"Geeni-Edison","GPIO":[0,0,0,0,0,0,0,0,0,0,37,0,0],"FLAG":0,"BASE":18} +Globe 34209 800lm {"NAME":"Globe WW 800lm","GPIO":[0,0,0,0,0,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} +Hama 7W 900lm Filament {"NAME":"Hama Filament","GPIO":[255,255,255,255,255,255,255,255,255,255,46,255,255],"FLAG":15,"BASE":18} +KMC 70113 A19 7.5W {"NAME":"Generic","GPIO":[0,0,0,0,0,0,37,38,0,0,0,0,0],"FLAG":15,"BASE":18} +Kogan ST-20 Filament {"NAME":"Kogan Filament","GPIO":[0,0,0,0,0,0,0,0,0,0,37,0,0],"FLAG":15,"BASE":18} +Krisbow Bohlam 14W {"NAME":"Krisbow SmartL","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":48} +LeDesign 8W ST21 Filament {"NAME":"Edison Bulb","GPIO":[0,0,0,0,0,0,0,0,0,37,0,0,0],"FLAG":0,"BASE":18} +Lohas LZN127 G25 800lm {"NAME":"Lohas Globe","GPIO":[0,0,0,0,0,0,0,0,0,0,37,0,0],"FLAG":0,"BASE":18} +Lohas ZN014 550lm {"NAME":"Lohas MR16","GPIO":[0,0,0,0,40,0,0,0,38,39,37,0,0],"FLAG":0,"BASE":18} +Lohas ZN124 980lm {"NAME":"Lohas LH-ZN124","GPIO":[0,0,0,0,0,0,0,0,0,0,37,0,0],"FLAG":0,"BASE":18} +LSC Smart Connect Filament A60 {"NAME":"LSC Filam E27","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} +LSC Smart Connect Filament C35 {"NAME":"LSC Filam E14","GPIO":[0,255,0,255,0,0,0,0,38,0,37,0,0],"FLAG":15,"BASE":18} +LSC Smart Connect Filament G125 {"NAME":"LSC Filam Huge","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} +LSC Smart Connect Filament ST64 {"NAME":"LSC Filam Big","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":18} +Lumary 6W 700lm Edison {"NAME":"Lumary TS3Y","GPIO":[0,0,0,0,0,0,0,0,0,37,0,0,0],"FLAG":0,"BASE":18} +Luminea ZX-2880 A60 800lm {"NAME":"LAV-110.w","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Luminea ZX-2982 ST64 Filament {"NAME":"Luminea ZX2982","GPIO":[0,0,0,0,0,0,0,0,0,0,37,0,0],"FLAG":0,"BASE":18} +Merkury 9W 800lm {"NAME":"MI-BW320-999W","GPIO":[0,0,0,0,0,0,0,0,0,0,21,0,0],"FLAG":0,"BASE":18} +Merkury MI-BW902-999W 800lm {"NAME":"MI-BW902-999W","GPIO":[0,0,0,0,0,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} +Merkury MI-BW942-999W 800lm {"NAME":"MI-BW942-999W","GPIO":[0,0,0,0,37,0,0,0,0,52,0,0,0],"FLAG":0,"BASE":18} +Merkury MIC-BW902-999W {"NAME":"MI-BW902-999W","GPIO":[0,0,0,0,0,0,0,0,0,0,37,0,0],"FLAG":0,"BASE":18} +Merkury Vintage Edison A19 {"NAME":"Merkury A19 Ed","GPIO":[0,0,0,0,0,0,0,0,0,0,37,0,0],"FLAG":0,"BASE":18} +Mirabella Genio 800lm {"NAME":"GenioBulbCW","GPIO":[0,0,0,0,38,37,0,0,0,40,39,0,0],"FLAG":0,"BASE":18} +Mirabella Genio 9W 800lm {"NAME":"GenioB22","GPIO":[0,0,0,0,0,0,0,0,0,37,0,0,0],"FLAG":0,"BASE":18} +Mirabella Genio A70 1400lm {"NAME":"GenioB_CW2744","GPIO":[0,0,0,0,0,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} +Nedis A60 Filament {"NAME":"WIFILF10WTA60","GPIO":[0,0,0,0,0,0,0,0,0,0,37,0,0],"FLAG":0,"BASE":18} +Nedis G125 Filament {"NAME":"WIFILF10GDG125","GPIO":[0,0,0,0,0,0,0,0,0,0,37,0,0],"FLAG":0,"BASE":18} +Nedis PAR16 330lm {"NAME":"Nedis WIFILW31","GPIO":[0,0,0,0,0,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} +Sealight Vintage Edison A19 {"NAME":"SealightEdison","GPIO":[0,0,0,0,0,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} +TCP Smart 810lm Filament {"NAME":"TCP Filament","GPIO":[0,0,0,0,0,0,0,0,0,0,46,0,0],"FLAG":0,"BASE":18} +Xiaomi Philips MUE4088RT {"NAME":"Xiaomi Philips","GPIO":[0,0,0,0,0,0,0,0,0,0,0,37,0],"FLAG":0,"BASE":18} +``` + ## Dimmer ``` +3A Smart Home HGZB-04D {"NAME":"HGZB-4D","GPIO":[255,255,255,255,255,255,0,0,255,255,54,255,255],"FLAG":0,"BASE":54} +Acenx SD03 {"NAME":"SD03","GPIO":[19,18,0,59,158,58,0,0,57,37,56,122,29],"FLAG":0,"BASE":73} Armtronix AC Dimmer One Triac Board {"NAME":"ARMTR Dimmer","GPIO":[0,148,0,149,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":56} Armtronix AC Dimmer Two Triac Board {"NAME":"ARMTR Dimmer","GPIO":[0,148,0,149,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":56} BrilliantSmart D350W {"NAME":"Generic","GPIO":[255,107,255,108,255,255,0,0,255,0,255,0,255],"FLAG":0,"BASE":54} CE Smart Home CFW500D-3W 3 Way {"NAME":"CE-WF500D-3W","GPIO":[0,0,0,0,0,0,0,0,0,108,0,107,0],"FLAG":0,"BASE":54} -CE Smart Home CWF500D-3W {"NAME":"CE-WF500D-3W","GPIO":[0,0,0,0,0,0,0,0,0,108,0,107,0],"FLAG":0,"BASE":54} CE Smart Home WF500D {"NAME":"CE-WF500D","GPIO":[0,0,0,0,0,0,0,0,0,108,0,107,0],"FLAG":0,"BASE":54} Eva Logik WF31 {"NAME":"WF31 Dimmer","GPIO":[255,107,255,108,255,255,0,0,255,255,255,255,255],"FLAG":0,"BASE":54} EX-Store 2 Kanal RS232 V4 {"NAME":"EXS Dimmer","GPIO":[0,148,0,149,0,0,0,0,0,183,0,0,0],"FLAG":0,"BASE":72} +Feit Electric DIM/WIFI {"NAME":"Generic","GPIO":[255,107,255,108,255,255,0,0,255,0,255,0,255],"FLAG":0,"BASE":54} Gosund SW2 {"NAME":"Gosund Dimmer","GPIO":[255,148,255,149,17,0,255,255,56,158,37,255,255],"FLAG":0,"BASE":18} -Martin Jerry MJ-SD02 {"NAME":"MJ-SD02","GPIO":[19,17,0,33,34,32,255,255,31,37,30,127,29],"FLAG":15,"BASE":18} +iSwitch Touch Switch {"NAME":"iSwitchOZ Dimmer","GPIO":[0,0,0,0,0,0,0,0,0,0,54,0,0],"FLAG":0,"BASE":54} +Martin Jerry MJ-SD01 {"NAME":"MJ-SD02","GPIO":[19,18,0,59,158,58,0,0,57,37,56,122,29],"FLAG":0,"BASE":73} Moes DS01-1 {"NAME":"MOES DS01","GPIO":[255,255,255,255,255,255,0,0,255,108,255,107,255],"FLAG":0,"BASE":54} Moes MS-105-1 v2 {"NAME":"MS-105","GPIO":[0,107,0,108,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} PS-16-DZ {"NAME":"PS-16-DZ","GPIO":[255,148,255,149,255,255,0,0,255,52,255,255,255],"FLAG":0,"BASE":58} -QS-WiFi-D01 150W {"NAME":"WiFi-Dimmer","GPIO":[0,148,0,149,0,0,0,0,0,42,37,0,0],"FLAG":0,"BASE":18} +QS-WiFi-D01-TRIAC 150W {"NAME":"WiFi-Dimmer","GPIO":[0,148,0,149,0,0,0,0,0,42,37,0,0],"FLAG":0,"BASE":18} RJWF-02A {"NAME":"RJWF-02A","GPIO":[17,107,0,108,0,0,0,0,0,0,52,0,0],"FLAG":0,"BASE":54} Sonoff D1 {"NAME":"Sonoff D1","GPIO":[255,148,0,149,0,0,0,0,0,56,0,0,0],"FLAG":0,"BASE":74} Teekar UIW001-1 {"NAME":"Teekar UIW001-","GPIO":[0,149,37,148,6,5,0,0,9,0,0,0,0],"FLAG":0,"BASE":18} +Tessan MJ-SD02 {"NAME":"MJ-SD02","GPIO":[19,18,0,59,158,58,0,0,57,37,56,122,29],"FLAG":0,"BASE":73} TreatLife DS01 {"NAME":"DS02S Dimmer","GPIO":[0,107,0,108,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} TreatLife DS02S {"NAME":"DS02S Dimmer","GPIO":[0,107,0,108,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} WF-DS01 {"NAME":"Dimmer WF-DS01","GPIO":[255,255,255,255,255,255,0,0,255,255,54,255,255],"FLAG":0,"BASE":54} @@ -356,21 +193,12 @@ Zemismart KS-7011 {"NAME":"KS-7011 Dimmer","GPIO":[255,107,255,108,255,25 ## Fan ``` Anko HEGSM40 {"NAME":"Anko HEGSM40","GPIO":[0,0,0,0,0,0,0,0,0,108,0,107,0],"FLAG":0,"BASE":54} -Arlec 45cm Smart DC Wall {"NAME":"Arlec 45cm Fan","GPIO":[0,0,0,0,0,0,0,0,0,108,0,107,0],"FLAG":0,"BASE":54} -Goldair SleepSmart GCPF315 {"NAME":"Goldair Fan","GPIO":[0,0,0,0,0,0,0,0,0,108,0,107,0],"FLAG":0,"BASE":54} -``` - -## Fan Controller -``` +Arlec Smart 45cm Smart DC Wall {"NAME":"Arlec 45cm Fan","GPIO":[0,0,0,0,0,0,0,0,0,108,0,107,0],"FLAG":0,"BASE":54} BrilliantSmart 99111 {"NAME":"Brilliant Fan","GPIO":[0,107,0,108,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} +Goldair SleepSmart GCPF315 {"NAME":"Goldair Fan","GPIO":[0,0,0,0,0,0,0,0,0,108,0,107,0],"FLAG":0,"BASE":54} Lucci Connect Remote Control {"NAME":"Lucci Fan","GPIO":[0,0,0,0,0,0,0,0,0,108,0,107,0],"FLAG":0,"BASE":54} -Sonoff iFan02 {"NAME":"Sonoff iFan02","GPIO":[17,255,0,255,23,22,18,19,21,56,20,24,0],"FLAG":0,"BASE":44} -Sonoff iFan03 {"NAME":"SonoffiFan03","GPIO":[17,148,0,149,0,0,29,161,23,56,22,24,0],"FLAG":0,"BASE":71} -``` - -## Humidifier -``` -Proscenic 807C {"NAME":"Generic","GPIO":[255,255,255,255,255,255,0,0,255,255,255,255,255],"FLAG":15,"BASE":54} +Sonoff IFan02 {"NAME":"Sonoff iFan02","GPIO":[17,255,0,255,23,22,18,19,21,56,20,24,0],"FLAG":0,"BASE":44} +Sonoff IFan03 {"NAME":"SonoffiFan03","GPIO":[17,148,0,149,0,0,29,161,23,56,22,24,0],"FLAG":0,"BASE":71} ``` ## IR Bridge @@ -383,16 +211,20 @@ Connect SmartHome Universal Smart IR Remote {"NAME":"CSH IR Bridge","GPIO":[255 Cusam CS-IRC-1 {"NAME":"YTF IR Bridge","GPIO":[255,255,255,255,56,51,0,0,0,17,8,0,0],"FLAG":0,"BASE":62} Eachen IR DC6 {"NAME":"Eachen IR","GPIO":[0,0,0,0,56,51,0,0,255,17,8,0,0],"FLAG":0,"BASE":18} Geeklink GK01 {"NAME":"GL IR Blaster","GPIO":[255,255,255,255,56,51,0,0,0,17,8,0,0],"FLAG":0,"BASE":62} +Jinvoo AC/TV Box Controller {"NAME":"Jinvoo IR Bridge","GPIO":[255,255,255,255,56,51,0,0,0,17,8,0,0],"FLAG":0,"BASE":62} Mirabella Genio I002577 {"NAME":"Genio IR TxRx","GPIO":[255,255,255,255,56,51,0,0,0,17,8,0,0],"FLAG":0,"BASE":62} +Nedis Universal Remote Control {"NAME":"Nedis IR Bridge","GPIO":[255,255,255,255,56,51,0,0,0,17,8,0,0],"FLAG":0,"BASE":62} NEO Coolcam NAS-IR03W0 {"NAME":"Neo Coolcam IR","GPIO":[0,0,0,0,56,51,0,0,0,17,8,0,0],"FLAG":0,"BASE":62} +RM mini {"NAME":"RM mini","GPIO":[255,255,255,255,56,51,0,0,0,17,8,0,0],"FLAG":0,"BASE":62} STITCH by Monoprice 35753 {"NAME":"Stitch 35753","GPIO":[0,0,0,0,52,51,0,0,0,90,8,0,0],"FLAG":0,"BASE":18} +SZMDLX IR Remote Controller {"NAME":"SZMDLX WiFi IR","GPIO":[0,0,0,0,56,51,0,0,0,17,8,0,0],"FLAG":0,"BASE":62} YTF Universal Remote {"NAME":"YTF IR Bridge","GPIO":[255,255,255,255,56,51,0,0,0,17,8,0,0],"FLAG":0,"BASE":62} ``` ## Kettle ``` Kogan 1.7L Smart Glass {"NAME":"Kogan Kettle","GPIO":[255,107,255,108,255,255,0,0,255,255,255,255,255],"FLAG":0,"BASE":54} -ProfiCook PC-WKS 1167 G 1.5 L {"NAME":"PC-WKS Kettle","GPIO":[0,107,0,108,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} +ProfiCook PC-WKS 1167G 1.5L {"NAME":"PC-WKS 1167G","GPIO":[0,107,0,108,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} ``` ## LED Controller @@ -401,19 +233,23 @@ Anncoe C350 RGB {"NAME":"TUYA LED","GPIO":[0,0,0,0,0,38,0,0,39,17,37,0, Arilux AL-LC01 {"NAME":"Arilux LC01","GPIO":[17,0,59,0,147,37,0,0,38,39,0,0,0],"FLAG":0,"BASE":37} Arilux AL-LC06 {"NAME":"Arilux LC06","GPIO":[17,0,0,0,0,0,0,0,38,39,37,41,40],"FLAG":0,"BASE":18} Arilux AL-LC11 {"NAME":"Arilux LC11","GPIO":[17,0,59,0,38,37,0,0,41,40,39,147,0],"FLAG":0,"BASE":38} +Arilux SL-LC 03 {"NAME":"Arilux LC03","GPIO":[0,0,0,0,51,38,0,0,37,39,0,40,0],"FLAG":0,"BASE":34} Arilux SL-LC 09 {"NAME":"Arilux LC09","GPIO":[0,0,0,0,106,37,0,0,39,0,38,0,0],"FLAG":0,"BASE":18} DD001-MINI(G)-IR-V08 {"NAME":"WIFI-RGB","GPIO":[0,0,0,0,37,0,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} Electrodragon ESP LED Strip Board, Mosfet Drive {"NAME":"LEDBoard RGBW","GPIO":[0,0,0,0,0,0,0,0,39,38,40,37,52],"FLAG":0,"BASE":18} H801 {"NAME":"H801","GPIO":[0,52,0,0,41,57,0,0,39,38,40,37,0],"FLAG":0,"BASE":20} +Jinvoo SM-WA104 RGB {"NAME":"Jinvoo LED Controller","GPIO":[0,0,0,0,29,39,0,0,37,17,38,0,30],"FLAG":0,"BASE":18} LEDEnet {"NAME":"LEDEnet","GPIO":[0,255,56,255,147,41,0,0,38,39,37,40,0],"FLAG":0,"BASE":34} Luminea ZX-2844 {"NAME":"Luminea ZX-284","GPIO":[40,0,0,0,0,39,0,0,38,17,37,0,0],"FLAG":0,"BASE":18} Luminea ZX-2844-675 {"NAME":"ZX-2844-675","GPIO":[17,0,0,0,38,40,0,0,37,0,39,0,0],"FLAG":0,"BASE":18} +Lustreon {"NAME":"Lustreon WiFi ","GPIO":[17,0,55,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":38} Magic UFO RGBW {"NAME":"Magic UFO","GPIO":[17,0,157,0,0,37,0,0,39,40,38,56,0],"FLAG":0,"BASE":18} MagicHome RGB ZJ-WFMN-A V1.1 {"NAME":"MagicHome RGB","GPIO":[0,0,0,0,0,37,0,0,38,39,0,0,0],"FLAG":0,"BASE":34} MagicHome RGBW ESP-IR-B-v2.3 {"NAME":"ESP-IR-B-v2.3","GPIO":[0,0,51,0,0,38,0,0,37,39,0,40,0],"FLAG":0,"BASE":18} MagicHome RGBW ZJ-WFMN-A V1.1 {"NAME":"MagicHome RGBW","GPIO":[0,0,0,0,51,38,0,0,37,39,0,40,0],"FLAG":0,"BASE":34} MagicHome RGBWW w/ RF {"NAME":"MagicHome RF","GPIO":[0,0,159,0,37,38,0,0,41,40,39,147,0],"FLAG":0,"BASE":38} MagicHome RGBWW w/ RF {"NAME":"MagicHome RF","GPIO":[0,0,0,0,147,40,0,0,38,39,37,41,159],"FLAG":0,"BASE":18} +MagicHome Single Color 5-28V {"NAME":"MagicHome","GPIO":[0,0,0,0,0,0,0,0,37,0,0,0,0],"FLAG":0,"BASE":18} MagicHome ZJ-ESP-IR-F V1 {"NAME":"ZJ-ESP-IR-F V1","GPIO":[0,0,0,0,51,38,0,0,37,39,0,40,0],"FLAG":0,"BASE":18} Maxonar Lightstrip Pro XS-SLD001 {"NAME":"Maxonar LED","GPIO":[0,0,0,0,0,37,0,0,39,17,38,0,0],"FLAG":0,"BASE":18} Nexlux {"NAME":"MagicHome V1.1","GPIO":[0,0,0,0,51,37,0,0,38,39,0,0,0],"FLAG":0,"BASE":34} @@ -423,15 +259,21 @@ ZJ-WF-ESP-A v1.1 {"NAME":"RGB2","GPIO":[0,0,0,0,0,0,0,0,38,37,39,0,0],"F ## LED Strip ``` -Arlec 2m LED Colour Changing Strip Light {"NAME":"Arlec ALD233AH","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} +Arlec Smart 2m LED Colour Changing Strip Light {"NAME":"Arlec ALD233AH","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} B.K. Licht BKL1268 2m RGB {"NAME":"RGBW-Strip","GPIO":[0,0,0,0,37,17,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} BlitzWolf BW-LT11 {"NAME":"BW-LT11 Strip","GPIO":[17,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} BrilliantSmart 20743 RGB+W {"NAME":"BrilliantStrip","GPIO":[17,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} Briloner 2256-150 RGB {"NAME":"Briloner2256-1","GPIO":[51,0,0,0,37,0,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} Cocoon Smart {"NAME":"Cocoon Smart","GPIO":[17,0,0,0,37,0,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} +HitLights L1012V-MC1 {"NAME":"HitLights RBG","GPIO":[17,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} +Hykker 3m RGB {"NAME":"HYKKER Strip","GPIO":[0,0,0,0,0,37,0,0,39,17,38,0,0],"FLAG":0,"BASE":18} +INDARUN RGB String Lights {"NAME":"STAR301","GPIO":[0,0,0,0,51,37,0,0,38,39,0,0,0],"FLAG":0,"BASE":34} +LE LampUX 16.4ft RGB {"NAME":"LampUX","GPIO":[0,18,17,0,0,38,0,0,39,51,0,37,0],"FLAG":0,"BASE":18} LE LampUX 2m RGB TV Backlight {"NAME":"LE 904102","GPIO":[0,17,18,0,0,38,0,0,39,19,0,37,0],"FLAG":0,"BASE":18} -LE LampUX 5m RGB LED Strip {"NAME":"LampUX","GPIO":[17,0,0,0,0,38,0,0,39,0,0,37,0],"FLAG":0,"BASE":18} -LE lampUX 5m RGBW {"NAME":"LampUX","GPIO":[17,0,0,0,37,40,255,255,38,41,39,0,0],"FLAG":0,"BASE":18} +LE LampUX 5m RGB {"NAME":"LampUX","GPIO":[17,0,0,0,0,38,0,0,39,0,0,37,0],"FLAG":0,"BASE":18} +LE LampUX 5m RGB {"NAME":"LE LampUx","GPIO":[0,0,0,0,0,38,0,0,39,0,0,37,0],"FLAG":0,"BASE":34} +LE lampUX 5m RGBW {"NAME":"LampUX","GPIO":[0,0,17,0,0,38,0,0,39,0,40,37,0],"FLAG":0,"BASE":18} +Lohas ZN022 5m RGBW {"NAME":"LOHAS M5-022","GPIO":[0,0,0,0,38,37,0,0,17,39,0,0,0],"FLAG":0,"BASE":18} LSC Smart Connect RGBW {"NAME":"LSC RGBW Strip","GPIO":[51,0,0,0,37,0,0,0,38,40,39,0,0],"FLAG":0,"BASE":18} Lumary RGBCCT {"NAME":"Lumary LED","GPIO":[17,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} Lumary RGBCCT {"NAME":"Lumary LED","GPIO":[17,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} @@ -446,9 +288,11 @@ Zemismart RGBW {"NAME":"Zemismart LED","GPIO":[0,0,0,0,38,37,0,0,0,39, ## Light ``` -Arlec 15W Security Floodlight {"NAME":"ArlecFlood","GPIO":[0,0,0,0,0,0,0,0,0,0,37,0,0],"FLAG":15,"BASE":18} -Arlec 40W 4000lm LED Batten Light {"NAME":"Arlec Batten","GPIO":[0,0,0,0,0,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} +Arlec Smart 15W Security Floodlight {"NAME":"ArlecFlood","GPIO":[0,0,0,0,0,0,0,0,0,0,37,0,0],"FLAG":15,"BASE":18} +Arlec Smart 40W 4000lm LED Batten {"NAME":"Arlec Batten","GPIO":[0,0,0,0,0,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} +Arlec Smart Portable Floodlight 10.5W {"NAME":"Arlec GLD301HA","GPIO":[0,0,0,0,0,37,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} BlitzWolf BW-LT20 {"NAME":"BW-LT20","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":15,"BASE":18} +Brilex Nightstand Lamp {"NAME":"Smart Table La","GPIO":[0,0,18,0,37,157,0,0,38,17,39,0,40],"FLAG":0,"BASE":18} Brilliant CORDIA Colour Temperature Changing LED Flush Ceiling Light {"NAME":"Brilliant Oyst","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":18} BrilliantSmart 20695 Downlight CCT {"NAME":"SmartCCTDwnLgt","GPIO":[0,0,0,0,0,37,0,0,0,38,0,0,0],"FLAG":0,"BASE":48} BrilliantSmart Prism LED RGBCCT Downlight {"NAME":"Prism","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} @@ -456,25 +300,34 @@ BrilliantSmart RGB Garden Kit {"NAME":"Brilliant Gard","GPIO":[0,0,0,0,37,0,0,0 Calex 429250 Ceiling {"NAME":"Calex_LED","GPIO":[0,0,0,0,0,0,0,0,52,37,38,54,0],"FLAG":0,"BASE":18} Connect SmartHome CSH-240RGB10W {"NAME":"Connect1","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} Connect SmartHome CSH-FSTN12 {"NAME":"CSH-FSTN12","GPIO":[0,0,0,0,37,0,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} +Deta 18W 1900lm T8 Tube {"NAME":"DETA Smart LED","GPIO":[0,0,0,0,0,0,0,0,0,0,37,0,0],"FLAG":0,"BASE":18} Deta DET902HA 10W 940lm RGB+CCT {"NAME":"Deta DownLight","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} -Fcmila XDD-48W {"NAME":"XDD-48W","GPIO":[0,0,0,0,37,40,0,0,38,25,39,0,0],"FLAG":0,"BASE":18} -Hama 10W RGB+WW {"NAME":"Hama Smart WiF","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +electriQ MOODL Ambiance Lamp {"NAME":"ElectriQ MOODL","GPIO":[0,201,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} +Fcmila 48W RGBCCT Ceiling Lamp {"NAME":"XDD-48W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Feit Electric 6in. RGBW Recessed Downlight {"NAME":"Feit LEDR6/RGB","GPIO":[0,0,0,0,37,40,0,0,38,50,39,0,0],"FLAG":0,"BASE":48} +Globe 5W 4" Recessed RGBCCT {"NAME":"GlobeRGBWW","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} Hyperikon 14W 1000lm 6" Downlight {"NAME":"HyperikonDL6","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} +iHomma 6W RGBCCT Downlight {"NAME":"iHomma RGBWW","GPIO":[0,0,0,0,41,40,0,0,37,38,39,0,0],"FLAG":0,"BASE":18} iHomma Downlight {"NAME":"iHommaLEDDownl","GPIO":[0,0,0,0,0,40,0,0,37,38,39,0,0],"FLAG":0,"BASE":18} -Infray 9W 900LM {"NAME":"InfrayRGBCCT","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Kogan 9W Downlight RGBCCT {"NAME":"Kogan_SMARTLED","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} LE lampUX 15W RGBCCT Ceiling {"NAME":"LE lampUX 15W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} Lohas ZN026CL10 RGBCCT {"NAME":"Lohas LED Lamp","GPIO":[0,0,0,0,38,37,0,0,40,39,41,0,0],"FLAG":0,"BASE":18} +Lumary 18W RGBCCT Recessed Panel {"NAME":"LumaryDLghtRGB","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} Mi LED Desk Lamp MJTD01YL {"NAME":"Mi Desk Lamp","GPIO":[0,0,17,0,37,38,0,0,150,151,0,0,0],"FLAG":0,"BASE":66} +MiraBella Genio 6 Pack 30mm Stainless Steel Deck Kit {"NAME":"Genio RGB Deck Lights","GPIO":[0,0,0,0,37,0,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} Mirabella Genio I002741 {"NAME":"GenioDLightRGB","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} Mirabella Genio I002742 {"NAME":"GenioDLightCCT","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":48} Mirabella Genio I002798 Warm White Filament Festoon {"NAME":"GenioFestoon","GPIO":[0,0,0,0,0,0,0,0,0,0,37,0,0],"FLAG":0,"BASE":18} +Moes 7W RGBCCT Downlight {"NAME":"Moes Downlight","GPIO":[0,0,0,0,40,41,0,0,37,38,39,0,0],"FLAG":0,"BASE":18} Novostella UT88835 20W Floodlight {"NAME":"Novo 20W Flood","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +SMRTLite LED Panel {"NAME":"SMRTLite","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} Sonoff BN-SZ01 {"NAME":"Sonoff BN-SZ","GPIO":[0,0,0,0,0,0,0,0,37,56,0,0,0],"FLAG":0,"BASE":22} Spotlight 9cm RGB+W 7W {"NAME":"Spotlight RGBW","GPIO":[0,0,0,0,0,0,0,0,0,143,0,144,0],"FLAG":0,"BASE":27} Teckin FL41 {"NAME":"Teckin FL41","GPIO":[0,0,0,0,0,17,0,0,0,0,21,0,0],"FLAG":0,"BASE":18} Utorch PZE-911 {"NAME":"Utorch PZE-911","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":1} Utorch UT40 {"NAME":"Utorch UT40","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":1} Verve Design Angie 18W Ceiling Light With RGB Ring {"NAME":"ACL12HA Light","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} +Verve Design Charlie 22W CCT Ceiling {"NAME":"Verve ACL01HA","GPIO":[0,0,0,0,0,37,0,0,0,47,0,0,0],"FLAG":0,"BASE":48} Verve Design Hana 24W CCT Ceiling {"NAME":"Verve ACL03HA","GPIO":[0,0,0,0,0,0,0,0,38,0,37,0,0],"FLAG":0,"BASE":48} Wipro Next 20W Smart LED Batten {"NAME":"WIPROBatten","GPIO":[0,0,0,0,0,37,0,0,0,47,0,0,0],"FLAG":1,"BASE":18} Zemismart 4" 10W RGBCCT {"NAME":"ZemiDownLight4","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} @@ -482,6 +335,14 @@ Zemismart 4" 10W RGBW {"NAME":"ZemiDownLight","GPIO":[0,0,0,0,0,0,0,0,0,143,0 Zemismart 6" 14W RGBCCT {"NAME":"ZemiDownLight6","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} ``` +## Miscellaneous +``` +iLONDA Fish feeder {"NAME":"Feeder","GPIO":[0,0,0,0,17,56,0,0,42,0,21,0,0],"FLAG":0,"BASE":18} +Mosquito Killer Lamp {"NAME":"MosquitoKiller","GPIO":[17,0,0,0,0,0,0,0,37,56,0,0,0],"FLAG":0,"BASE":18} +Proscenic 807C Humidifier {"NAME":"Generic","GPIO":[255,255,255,255,255,255,0,0,255,255,255,255,255],"FLAG":0,"BASE":54} +Sonoff RM433 RF Remote Controller {"NAME":"REQUIRES RF DEVICE"} +``` + ## Outdoor Plug ``` Acenx SOP04-US Dual {"NAME":"SOP04-US Dual","GPIO":[255,255,255,255,56,57,0,0,21,17,22,255,255],"FLAG":0,"BASE":18} @@ -495,22 +356,24 @@ C168 IP64 {"NAME":"C188","GPIO":[56,0,57,0,18,0,0,0,21,17,157,22, ECF-SOP03 {"NAME":"Outdoor3Outlet","GPIO":[0,0,0,23,56,0,0,0,21,17,22,0,0],"FLAG":0,"BASE":18} Ecoolbuy 4 socket {"NAME":"ECCOLBUY 4","GPIO":[0,0,0,0,22,23,0,0,21,57,17,0,24],"FLAG":0,"BASE":18} Feit Electric PLUG/WIFI/WP {"NAME":"Prime Smart ou","GPIO":[0,255,0,255,157,56,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} +Forrinx SH-18EU-A {"NAME":"SH-18EU-A","GPIO":[0,0,0,0,22,52,21,57,17,0,0,0,0],"FLAG":0,"BASE":18} Geeni Outdoor {"NAME":"Geeni Outdoor","GPIO":[17,0,0,0,0,57,0,0,0,52,21,0,0],"FLAG":0,"BASE":18} Geeni Outdoor DUO Dual Outlet {"NAME":"Geeni Dual Out","GPIO":[17,0,0,0,0,57,0,0,0,56,21,0,22],"FLAG":0,"BASE":18} HA109US {"NAME":"HA109US","GPIO":[17,0,0,0,52,53,0,0,21,0,22,0,0],"FLAG":0,"BASE":18} iClever IC-BS06 {"NAME":"iClever Switch","GPIO":[0,0,0,0,157,56,0,0,21,17,22,0,0],"FLAG":0,"BASE":18} King-Link C128 {"NAME":"King-Link C128","GPIO":[0,0,58,0,22,56,0,0,23,157,17,21,57],"FLAG":0,"BASE":18} +Kogan Energy Meter IP44 {"NAME":"Kogan Smart Sw IP44","GPIO":[17,0,0,0,133,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":18} LEPOWER {"NAME":"LEPOWER Outdoo","GPIO":[255,255,255,255,56,57,0,0,21,17,22,255,255],"FLAG":0,"BASE":18} Luminea NX-4458 {"NAME":"Luminea NX4458","GPIO":[17,0,0,0,133,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":65} Maxcio EOP03-EU {"NAME":"Maxcio EOP03-EU","GPIO":[0,0,0,0,22,57,0,0,21,52,17,0,58],"FLAG":0,"BASE":18} Maxcio SOP02-US {"NAME":"Maxcio SOP02US","GPIO":[0,0,0,0,0,157,0,0,21,17,22,0,0],"FLAG":15,"BASE":18} Merkury MI-OW101-101W {"NAME":"Merkury Switch","GPIO":[17,255,255,255,0,56,0,0,0,54,21,255,255],"FLAG":1,"BASE":18} Minoston MP22W {"NAME":"Minoston MP22W","GPIO":[0,0,0,0,56,0,0,0,21,90,0,0,0],"FLAG":0,"BASE":18} -Nedis IP44 PO120 {"NAME":"WIFIPO120FWT","GPIO":[17,0,0,0,134,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":49} +Nedis PO120 IP44 {"NAME":"WIFIPO120FWT","GPIO":[17,0,0,0,134,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":49} Obi Stecker IP44 {"NAME":"OBI Socket 2","GPIO":[0,0,0,0,21,17,0,0,56,53,0,0,0],"FLAG":0,"BASE":61} Oittm Outdoor {"NAME":"Oittm Outdoor","GPIO":[17,0,0,0,0,0,0,0,0,0,56,21,255],"FLAG":0,"BASE":18} Peteme PS-1602 {"NAME":"Peteme Outdoor","GPIO":[17,0,0,0,0,22,18,0,21,56,0,0,0],"FLAG":0,"BASE":18} -Prime CCRCWFIO2PK {"NAME":"Prime Outdoor","GPIO":[0,0,0,0,56,57,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} +Prime RCWFIO 2-Outlet {"NAME":"Prime Outdoor","GPIO":[0,0,0,0,56,57,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} Signstek EOP03-EU {"NAME":"Signstek EOP03","GPIO":[0,0,0,0,56,57,0,0,21,17,22,0,0],"FLAG":15,"BASE":18} SK03 {"NAME":"SK03 Outdoor","GPIO":[17,0,0,0,133,132,0,0,131,57,56,21,0],"FLAG":0,"BASE":57} STITCH by Monoprice 35556 {"NAME":"STITCH 35556","GPIO":[255,255,255,255,22,57,0,0,21,56,17,255,255],"FLAG":0,"BASE":18} @@ -525,20 +388,23 @@ Ucomen PA-GEBA-01SWP {"NAME":"PA-GEBA-01SWP","GPIO":[0,0,0,0,52,57,0,0,21,17 ## Plug ``` 2nice SP111 {"NAME":"2NICE SP111","GPIO":[56,0,57,0,0,0,0,0,0,17,0,21,0],"FLAG":2,"BASE":18} -2nice UP111 {"NAME":"2NICE UP111","GPIO":[0,52,0,17,134,132,0,0,131,157,21,0,0],"FLAG":0,"BASE":18} +2nice UP111 {"NAME":"2NICE UP111","GPIO":[0,158,0,17,134,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":18} 3Stone Mini {"NAME":"3Stone Smart P","GPIO":[0,17,0,0,0,0,0,0,0,57,21,0,0],"FLAG":0,"BASE":18} +7hSevenOn Home 10020 {"NAME":"7hSevenOn","GPIO":[0,0,0,0,52,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} +7hSevenOn Home 10022 USB {"NAME":"7hSevenOn","GPIO":[17,0,0,0,0,0,0,0,21,56,0,0,0],"FLAG":0,"BASE":18} Ablue WP1 {"NAME":"Ablue","GPIO":[57,0,56,0,0,0,0,0,0,17,0,21,0],"FLAG":1,"BASE":18} Aigoss 16A Mini {"NAME":"Aigoss Plug","GPIO":[255,255,0,255,52,21,0,0,54,255,17,0,255],"FLAG":15,"BASE":51} Aisirer AWP07L {"NAME":"AISIRER AWP07L","GPIO":[56,0,57,0,0,133,0,0,131,17,132,21,0],"FLAG":0,"BASE":18} Aisirer AWP07L v2 {"NAME":"AWP07L v2","GPIO":[0,17,57,0,134,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":18} +Aisirer AWP07L v3 {"NAME":"AWP07L v3","GPIO":[0,17,52,0,134,132,0,0,130,53,21,0,0],"FLAG":0,"BASE":18} Aisirer AWP08L {"NAME":"AISIRER AWP08L","GPIO":[0,0,56,0,0,0,0,0,0,0,0,21,0],"FLAG":0,"BASE":18} Aisirer AWP08L v2 {"NAME":"AISIRER AWP08L","GPIO":[0,0,0,0,17,57,0,0,21,0,0,0,0],"FLAG":0,"BASE":18} -Aisirer JH-G018 v2 {"NAME":"AISIRER JH-G01","GPIO":[0,0,0,0,56,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} -Aisirer JH-G01B {"NAME":"AISIRER","GPIO":[0,0,0,0,21,0,0,0,56,17,0,0,0],"FLAG":1,"BASE":18} +Aisirer JH-G018 {"NAME":"AISIRER JH-G01","GPIO":[0,0,0,0,56,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} Aisirer SWA11 {"NAME":"SWA11","GPIO":[0,0,0,0,52,21,0,0,0,17,0,0,0],"FLAG":0,"BASE":18} Aisirer UK-1 {"NAME":"AISIRER","GPIO":[0,17,0,0,0,0,0,0,0,52,21,0,0],"FLAG":1,"BASE":18} Alexfirst TV-ASP801EU {"NAME":"Alexfirst","GPIO":[17,0,0,0,54,56,0,0,21,0,0,0,0],"FLAG":0,"BASE":18} Alfawise PE1004T {"NAME":"PE1004T","GPIO":[0,0,0,0,56,57,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} +Alfawise PF1006 {"NAME":"PF1006","GPIO":[0,0,17,0,0,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":18} Alfawise PME1606 {"NAME":"PME1606","GPIO":[0,0,0,17,133,132,0,0,131,52,21,0,0],"FLAG":0,"BASE":18} Amysen JSM-WF02 {"NAME":"Amysen JSMWF02","GPIO":[0,17,0,0,0,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":18} Amysen YX-WS01 {"NAME":"Amysen YX-WS01","GPIO":[0,17,0,0,0,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":18} @@ -555,29 +421,39 @@ Aoycocr U3S {"NAME":"Aoycocr U3S","GPIO":[56,255,57,255,0,134,0,0,1 Aoycocr X10S {"NAME":"Aoycocr X10S","GPIO":[56,0,57,0,21,134,0,0,131,17,132,0,0],"FLAG":0,"BASE":45} Aoycocr X5P {"NAME":"Aoycocr X5P","GPIO":[56,0,57,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":18} Aoycocr X6 {"NAME":"Aoycocr X6","GPIO":[0,0,56,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":18} -Arlec PC189HA {"NAME":"Arlec Single","GPIO":[0,0,0,0,57,0,0,0,21,0,90,0,0],"FLAG":0,"BASE":18} -Arlec PC190HA {"NAME":"Arlec-PC190HA","GPIO":[0,0,0,0,0,0,0,0,21,56,17,0,0],"FLAG":0,"BASE":18} +Aquiv S1 {"NAME":"Aquiv S1","GPIO":[0,0,157,0,56,0,0,0,21,17,0,0,0],"FLAG":15,"BASE":18} +Arlec 10m Smart Extension Lead {"NAME":"Arlec Ext Cord","GPIO":[0,17,0,0,0,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":18} +Arlec Smart 2.1A USB Charger {"NAME":"Arlec Single","GPIO":[0,0,0,0,57,0,0,0,21,0,90,0,0],"FLAG":0,"BASE":18} +Arlec Smart PC189HA {"NAME":"Arlec Single","GPIO":[0,0,0,0,57,0,0,0,21,0,90,0,0],"FLAG":0,"BASE":18} +Arlec Smart PC190HA {"NAME":"Arlec-PC190HA","GPIO":[0,0,0,0,0,0,0,0,21,56,17,0,0],"FLAG":0,"BASE":18} +Arlec Smart PC399HA Plug {"NAME":"PC399HA","GPIO":[0,0,0,17,134,132,0,0,131,158,21,0,0],"FLAG":0,"BASE":52} Arlec Twin PC288HA {"NAME":"Arlec Twin","GPIO":[0,17,0,22,0,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":18} Atomi AT1217 {"NAME":"AT1217","GPIO":[0,0,0,0,56,57,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} -Aukey SH-PA1 {"NAME":"AUKEY SH-PA1","GPIO":[0,0,57,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":18} +Aukey SH-PA1 {"NAME":"AUKEY SH-PA1","GPIO":[56,0,57,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":18} +Aukey SH-PA3 {"NAME":"Aukey SH-PA3","GPIO":[0,0,158,0,57,17,0,0,22,0,0,21,0],"FLAG":0,"BASE":18} Aunics Smart EU {"NAME":"AUNICS","GPIO":[0,0,0,17,134,132,0,0,131,157,21,0,0],"FLAG":0,"BASE":18} Aunics Smart IT {"NAME":"AUNICS","GPIO":[0,0,0,17,134,132,0,0,131,157,21,0,0],"FLAG":0,"BASE":18} Avatar AWP01L {"NAME":"AWP01L","GPIO":[0,0,0,0,0,56,0,0,0,17,21,0,0],"FLAG":0,"BASE":18} Avatar AWP02L-N {"NAME":"AWP02L-N","GPIO":[158,0,0,0,56,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":18} +Avatar AWP03L {"NAME":"AWP03L","GPIO":[0,0,0,0,0,0,0,0,21,17,56,57,0],"FLAG":0,"BASE":18} Avatar AWP04L {"NAME":"AWP04L","GPIO":[57,255,255,131,255,134,0,0,21,17,132,56,255],"FLAG":0,"BASE":18} -Avatar AWP07L {"NAME":"AWP07L","GPIO":[56,255,255,255,255,134,0,0,130,17,132,21,255],"FLAG":1,"BASE":18} -Avatar AWP07L v2 {"NAME":"AWP07L","GPIO":[56,255,255,255,255,134,255,255,131,17,132,21,255],"FLAG":0,"BASE":18} +Avatar AWP07L {"NAME":"AWP07L","GPIO":[56,255,255,255,255,134,255,255,131,17,132,21,255],"FLAG":0,"BASE":18} Avatar AWP08L {"NAME":"AWP08L","GPIO":[0,0,56,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":18} -Avatar AWP12L Capsule 2-in-1 {"NAME":"Dual Plug","GPIO":[0,0,0,0,0,0,0,0,21,17,0,22,0],"FLAG":0,"BASE":18} +Avatar AWP12L Capsule 2-in-1 {"NAME":"AWP12L","GPIO":[56,0,0,131,18,134,0,0,21,17,132,22,0],"FLAG":0,"BASE":18} Avatar AWP14H {"NAME":"Avatar UK 10A","GPIO":[0,0,56,0,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":45} Avatto JH-G01E {"NAME":"AVATTO JH-G01E","GPIO":[0,145,0,146,0,0,0,0,17,56,21,0,0],"FLAG":0,"BASE":41} Avatto NAS-WR01W 10A {"NAME":"AvattoNAS-WR01W","GPIO":[0,0,0,0,52,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} Avatto OT06 16A {"NAME":"Avatto OT06","GPIO":[17,0,0,0,134,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":49} -AWP02L-N {"NAME":"AWP02L-N","GPIO":[57,0,56,0,0,0,0,0,0,17,0,21,0],"FLAG":1,"BASE":18} +Avatto OT08 {"NAME":"Avatto OT08","GPIO":[37,0,39,0,38,134,0,0,130,132,21,0,0],"FLAG":0,"BASE":18} +Awow X5P {"NAME":"Awow","GPIO":[0,0,56,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":18} +AWP02L-N {"NAME":"AWP02L-N","GPIO":[0,0,56,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":18} AzpenHome Smart {"NAME":"Socket2Me","GPIO":[52,255,255,255,22,255,0,0,21,255,17,255,255],"FLAG":0,"BASE":18} Bakibo TP22Y {"NAME":"Bakibo TP22Y","GPIO":[0,0,0,17,134,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":52} +Bardi 16A {"NAME":"BARDI","GPIO":[56,0,0,0,0,134,0,0,21,17,132,57,131],"FLAG":0,"BASE":18} Bauhn ASPU-1019 {"NAME":"Buahn Smart Pl","GPIO":[0,0,0,0,21,22,0,0,0,56,17,0,0],"FLAG":0,"BASE":18} +Bearware 303492 3AC+2USB {"NAME":"Bearware 30349","GPIO":[0,56,0,17,22,23,0,0,24,21,157,0,0],"FLAG":0,"BASE":18} Bestek MRJ1011 {"NAME":"BestekMRJ1011","GPIO":[0,0,0,0,56,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":1} +BlitzWolf BW-SHP10 {"NAME":"BW-SHP10","GPIO":[0,0,0,0,157,21,0,0,0,17,0,0,0],"FLAG":0,"BASE":18} BlitzWolf BW-SHP2 {"NAME":"BlitzWolf SHP","GPIO":[57,255,56,255,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":45} BlitzWolf BW-SHP3 {"NAME":"BlitzWolf SHP3","GPIO":[56,0,57,0,22,134,0,0,131,18,132,21,17],"FLAG":0,"BASE":45} BlitzWolf BW-SHP3 alt {"NAME":"BlitzWolf SHP3","GPIO":[18,56,0,131,134,132,0,0,17,0,22,21,0],"FLAG":0,"BASE":18} @@ -587,7 +463,9 @@ BlitzWolf BW-SHP6 10A {"NAME":"BW-SHP6 10A","GPIO":[158,255,56,255,0,134,0,0, Blitzwolf BW-SHP6 15A {"NAME":"Blitzwolf SHP6","GPIO":[56,255,158,255,132,134,0,0,131,17,0,21,0],"FLAG":0,"BASE":45} BlitzWolf BW-SHP7 {"NAME":"SHP7","GPIO":[17,158,57,131,134,132,0,0,18,56,21,0,22],"FLAG":0,"BASE":45} BN-LINK BNC-60/U133TJ-2P {"NAME":"BNC-60/U133TJ","GPIO":[0,56,0,17,134,132,0,0,131,57,21,0,0],"FLAG":0,"BASE":18} +BNETA IoT {"NAME":"BNETA WifiPlug","GPIO":[17,0,0,0,133,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":18} Brennenstuhl WA 3000 XS01 {"NAME":"WA 3000 XS01","GPIO":[0,0,0,0,21,17,0,0,158,52,0,0,0],"FLAG":0,"BASE":61} +Bright {"NAME":"Bright Wi-Fi Smart Plug","GPIO":[0,0,0,0,56,0,0,0,21,0,17,0,0],"FLAG":0,"BASE":18} Brilliant HK17654S05 {"NAME":"HK17654S05","GPIO":[17,255,255,255,133,132,255,255,131,56,21,255,255],"FLAG":0,"BASE":18} Brilliant Lighting BL20925 {"NAME":"BL20925","GPIO":[0,0,0,17,133,132,0,0,131,158,21,0,0],"FLAG":0,"BASE":52} BrilliantSmart 20676 USB Charger {"NAME":"Brilliant","GPIO":[0,0,0,0,0,21,0,0,0,52,90,0,0],"FLAG":0,"BASE":18} @@ -598,6 +476,7 @@ BSD29 {"NAME":"BSD29","GPIO":[0,0,0,131,134,132,0,0,21,17,56, BSD33 10A {"NAME":"BSD33 type 2","GPIO":[0,0,56,0,0,0,0,0,255,17,255,21,255],"FLAG":0,"BASE":18} BSD33 16A {"NAME":"Generic","GPIO":[0,255,0,131,134,132,0,0,21,17,56,0,0],"FLAG":0,"BASE":18} BSD34 {"NAME":"BSD34 Plug","GPIO":[0,0,0,0,0,0,0,0,21,17,56,0,0],"FLAG":0,"BASE":18} +BSD34-1-16A {"NAME":"BSD34-1 16A","GPIO":[0,53,0,131,134,132,0,0,21,17,52,0,0],"FLAG":0,"BASE":18} BSD48 16A {"NAME":"BSD48 Plug","GPIO":[0,52,0,0,0,0,0,0,21,17,57,0,0],"FLAG":0,"BASE":18} CE Smart Home LA-WF3 {"NAME":"CE LA-WF3","GPIO":[0,0,0,0,56,57,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} CE Smart Home LA-WF7 {"NAME":"LITESUN LA-WF7","GPIO":[0,56,0,17,134,132,0,0,131,57,21,0,0],"FLAG":0,"BASE":18} @@ -612,6 +491,7 @@ DeLock 11826 {"NAME":"DeLock 11826","GPIO":[17,0,0,0,0,0,0,0,21,158, Deltaco SH-P01 {"NAME":"DELTACO SH-P01","GPIO":[0,0,0,0,0,56,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} Deltaco SH-P01E {"NAME":"DELTACO SH-P01E","GPIO":[0,56,0,17,134,132,0,0,131,57,21,0,0],"FLAG":0,"BASE":55} Deltaco SH-P02 {"NAME":"Deltaco SH-P02","GPIO":[18,0,0,0,134,132,0,0,131,56,21,22,17],"FLAG":0,"BASE":18} +DETA 62120HA Smart Plug Base {"NAME":"DetaPlugBase","GPIO":[0,17,0,0,0,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":18} Deta 6930HA {"NAME":"DetaSmartPlug","GPIO":[0,17,0,0,0,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":18} Digoo DG-SP01 {"NAME":"DG-SP01","GPIO":[255,17,255,21,56,37,0,0,38,39,40,255,255],"FLAG":0,"BASE":18} Digoo NX-SP202 {"NAME":"Generic_SP202","GPIO":[52,0,0,131,91,134,0,0,22,17,132,21,0],"FLAG":0,"BASE":63} @@ -620,7 +500,7 @@ DILISENS SP201 {"NAME":"Dilisens SP201","GPIO":[0,0,131,0,133,132,52,2 Dunnes Stores {"NAME":"SmartLifePlug","GPIO":[0,0,0,17,0,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":18} DWFeng AWP02L-N {"NAME":"AWP02L-N","GPIO":[255,255,56,255,255,255,0,0,255,17,255,21,255],"FLAG":0,"BASE":18} DWFeng BSD01 {"NAME":"DWFeng BSD01","GPIO":[255,255,255,255,255,255,255,255,21,17,56,255,255],"FLAG":15,"BASE":18} -ECO Plugs CT-065W {"NAME":"ECO/CT-065W","GPIO":[255,255,255,255,255,255,0,0,255,17,255,21,255],"FLAG":0,"BASE":18} +ECO Plugs CT-065W {"NAME":"ECO/CT-065W","GPIO":[0,0,0,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":18} eco4life DPS1101S {"NAME":"Eco4Life Plug","GPIO":[0,0,0,0,52,57,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} ednet 84334 {"NAME":"84334","GPIO":[0,0,0,0,56,57,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} eFamilyCloud ASDFEE174 {"NAME":"eFamily Plug","GPIO":[0,0,0,0,52,21,0,0,0,17,0,0,0],"FLAG":0,"BASE":18} @@ -632,15 +512,18 @@ Esicoo JSM-WF02 {"NAME":"Esicoo Plug","GPIO":[0,17,0,0,0,0,0,0,0,56,21, Esicoo YX-WS01 {"NAME":"Esicoo Plug","GPIO":[255,17,255,255,255,255,0,0,255,56,21,255,255],"FLAG":0,"BASE":18} Estink C178 {"NAME":"Estink C178","GPIO":[0,0,0,0,52,57,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} Etekcity ESW01-USA {"NAME":"ESW01-USA","GPIO":[0,0,0,0,21,157,0,0,132,133,17,130,52],"FLAG":0,"BASE":55} +Etekcity ESW15-USA {"NAME":"ESW15-US","GPIO":[0,0,0,0,0,21,0,0,132,133,17,130,52],"FLAG":0,"BASE":18} Eva Logik NWF001 {"NAME":"EVA LOGIK Plug","GPIO":[255,17,255,255,255,255,0,0,255,52,21,255,255],"FLAG":0,"BASE":18} EVO-Smart JH-G01U {"NAME":"EVO JH-G01U","GPIO":[0,0,0,0,21,17,0,0,56,0,0,0,0],"FLAG":0,"BASE":18} Feit Electric PLUG/WIFI {"NAME":"Feit Wifi Plug","GPIO":[0,0,0,56,0,0,0,0,21,0,17,0,0],"FLAG":0,"BASE":18} FK-PW901U {"NAME":"FK-PW901U","GPIO":[56,255,255,255,255,23,0,0,21,17,24,22,255],"FLAG":0,"BASE":18} FLHS-ZN04 {"NAME":"FLHS-ZN04","GPIO":[57,0,56,0,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":45} Fontastic SH01 {"NAME":"Fontastic","GPIO":[255,0,255,0,56,0,0,0,21,17,0,0,0],"FLAG":1,"BASE":18} +Foval SM-PW701E {"NAME":"SM-PW701E","GPIO":[0,0,0,0,56,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} FrankEver FLHS-ZN04 {"NAME":"Israel plug","GPIO":[57,0,56,131,0,134,0,0,0,17,132,21,0],"FLAG":0,"BASE":45} GDTech W-US001 {"NAME":"GDTech W-US001","GPIO":[255,17,255,255,255,255,0,0,255,56,21,255,255],"FLAG":1,"BASE":18} GDTech W-US003 {"NAME":"W-US003","GPIO":[0,17,255,255,255,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":18} +Geekbes YM-WS-1 {"NAME":"Office Test Pl","GPIO":[255,255,255,255,255,255,255,255,158,17,12,21,255],"FLAG":15,"BASE":18} Geeni Spot {"NAME":"Geeni Spot","GPIO":[0,0,0,0,52,57,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} Geeni Spot Glo {"NAME":"Geeni Glo","GPIO":[0,0,0,0,56,0,0,0,21,17,22,0,0],"FLAG":0,"BASE":18} Geeni Switch {"NAME":"Geeni Switch","GPIO":[0,0,0,0,52,57,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} @@ -648,6 +531,7 @@ Geeni Switch Duo {"NAME":"Geeni Duo","GPIO":[0,0,0,0,18,22,0,0,17,52,21, Globe 50020 2 Outlet {"NAME":"Globe 50020","GPIO":[0,158,0,57,18,17,0,0,21,56,22,0,0],"FLAG":0,"BASE":18} Globe Smart {"NAME":"GlobeSmartPlug","GPIO":[0,0,0,0,56,0,0,0,21,0,17,0,0],"FLAG":0,"BASE":18} GoldenDot Mini {"NAME":"GoldenDot Mini","GPIO":[0,17,0,0,0,0,0,0,0,57,21,0,0],"FLAG":0,"BASE":52} +GoldenDot with ADC {"NAME":"W-US003-Power","GPIO":[56,0,0,0,0,0,0,0,0,17,0,21,0],"FLAG":7,"BASE":18} Gosund SP1 {"NAME":"Gosund SP1 v23","GPIO":[0,56,0,17,134,132,0,0,131,57,21,0,0],"FLAG":0,"BASE":55} Gosund SP111 {"NAME":"Gosund SP111","GPIO":[56,0,57,0,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":18} Gosund SP111 v1.1 {"NAME":"SP111 v1.1","GPIO":[56,0,158,0,132,134,0,0,131,17,0,21,0],"FLAG":0,"BASE":45} @@ -663,7 +547,7 @@ Gosund WP5 {"NAME":"Gosund-WP5","GPIO":[255,255,255,255,17,255,0,0 Gosund WP6 {"NAME":"Gosund WP6","GPIO":[0,0,0,17,0,0,0,0,56,57,21,0,0],"FLAG":0,"BASE":18} Grefic TE101 {"NAME":"Grefic TE101","GPIO":[0,0,0,0,56,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":1} Gyman SM-PW701U {"NAME":"Gyman","GPIO":[255,255,157,255,56,255,0,0,21,17,255,255,255],"FLAG":0,"BASE":18} -Hama 176565 {"NAME":"hama","GPIO":[0,0,0,17,134,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":52} +Hama 16A 3680W {"NAME":"Hama Plug","GPIO":[0,0,0,17,134,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":52} Hauppauge 01647 {"NAME":"SL-1642","GPIO":[0,0,0,0,52,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} HiHome WPP-10S1 {"NAME":"HIhome WPP-10S","GPIO":[56,0,158,255,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":49} HiHome WPP-10S2 {"NAME":"HiHome WPP-10S","GPIO":[17,0,0,0,134,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":49} @@ -671,7 +555,7 @@ HiHome WPP-16S {"NAME":"HIhome WPP-16S","GPIO":[17,0,0,0,134,132,0,0,1 HiHome WPP-16T {"NAME":"HiHome WPP-16T","GPIO":[17,56,255,255,134,132,0,0,18,255,22,130,21],"FLAG":1,"BASE":18} HIPER IoT P01 {"NAME":"HIPER IoT P01","GPIO":[0,0,0,0,0,56,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} hiwild W-US002 {"NAME":"W-US002","GPIO":[0,17,0,0,0,0,0,0,0,52,21,0,158],"FLAG":0,"BASE":18} -Houzetek AWP07L {"NAME":"AWP07L","GPIO":[56,255,255,130,255,134,0,0,0,17,132,21,255],"FLAG":0,"BASE":18} +Houzetek AWP07L {"NAME":"AWP07L","GPIO":[56,0,0,130,0,134,0,0,0,17,132,21,0],"FLAG":0,"BASE":18} HS108 {"NAME":"HS108","GPIO":[0,17,0,0,0,0,0,0,0,56,21,0,0],"FLAG":1,"BASE":18} HS108A {"NAME":"HS108A","GPIO":[0,0,0,0,52,0,0,0,21,17,0,0,0],"FLAG":1,"BASE":18} HuaFan QinLu {"NAME":"Huafan SS","GPIO":[56,0,0,57,17,29,0,0,132,130,133,0,0],"FLAG":0,"BASE":24} @@ -681,10 +565,12 @@ Hyleton 313 {"NAME":"Hyleton 313","GPIO":[57,0,56,0,0,0,0,0,0,17,0, Hyleton 314 {"NAME":"hyleton-314","GPIO":[57,0,56,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":18} Hyleton 315 {"NAME":"hyleton-315","GPIO":[0,0,0,0,57,56,0,0,21,90,0,0,0],"FLAG":0,"BASE":18} Hyleton 317 {"NAME":"hyleton-317","GPIO":[56,0,57,0,58,0,0,0,0,90,0,21,0],"FLAG":0,"BASE":18} +iClever IC-BS08 {"NAME":"iClever BS08","GPIO":[0,0,0,0,157,56,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} Ihommate ZCH-02 {"NAME":"ZCH-02","GPIO":[0,0,0,17,133,132,0,0,130,56,21,0,0],"FLAG":1,"BASE":18} iSwitch {"NAME":"Smart Plug XSA","GPIO":[255,17,255,255,255,255,0,0,255,56,21,255,255],"FLAG":0,"BASE":18} Jeeo TF-SH330 {"NAME":"Jeeo TF-SH330","GPIO":[56,0,0,0,0,0,0,0,0,17,0,21,0],"FLAG":1,"BASE":18} Jeeo TF-SH331W {"NAME":"Jeeo SH331W","GPIO":[56,0,158,0,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":18} +Jinli XS-SSA01 {"NAME":"JINLI","GPIO":[0,0,0,0,0,0,0,0,56,17,0,21,0],"FLAG":0,"BASE":18} Jinvoo SM-PW701U {"NAME":"SM-PW702","GPIO":[0,0,0,0,57,56,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} Jinvoo SM-PW712UA 10A {"NAME":"SM-PW712UA","GPIO":[0,0,0,158,56,57,0,0,22,17,21,0,0],"FLAG":15,"BASE":18} Jinvoo SM-PW762U {"NAME":"SM-PW762U","GPIO":[0,0,0,0,158,56,0,0,21,17,22,0,0],"FLAG":0,"BASE":18} @@ -705,17 +591,18 @@ Koogeek KLSP1 {"NAME":"Koogeek-KLSP1","GPIO":[0,56,0,17,134,132,0,0,1 Koogeek KLSP2 {"NAME":"KOOGEEK KLSP2","GPIO":[57,145,56,146,0,22,0,0,0,0,21,0,17],"FLAG":0,"BASE":45} Koogeek KLUP1 {"NAME":"Koogeek-KLUP1","GPIO":[0,0,0,17,134,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":18} Koogeek W-DEXI {"NAME":"W-DEXI","GPIO":[0,90,0,0,134,132,0,0,130,52,21,0,0],"FLAG":0,"BASE":18} +KULED K63 {"NAME":"KULED K63","GPIO":[0,0,0,0,21,17,0,0,56,0,0,0,0],"FLAG":0,"BASE":18} Laduo YX-DE01 {"NAME":"YX-DE01","GPIO":[255,17,255,255,255,255,0,0,255,56,21,255,255],"FLAG":0,"BASE":18} +Lenovo SE-341A {"NAME":"Lenovo SE-341A","GPIO":[0,0,0,0,17,21,0,0,158,0,56,0,0],"FLAG":0,"BASE":18} LESHP KS-501 {"NAME":"LESHP KS-501","GPIO":[17,0,0,0,0,0,0,0,21,56,0,0,0],"FLAG":0,"BASE":1} Loetad EU3S 16A {"NAME":"Loetad EU3S 16","GPIO":[0,255,56,0,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":18} Lonsonho 10A Type E {"NAME":"Lonsonho10ALed","GPIO":[0,0,0,0,56,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} LoraTap SP400W-IT {"NAME":"LoraTap SP400W","GPIO":[0,0,0,0,157,56,0,0,21,17,0,0,0],"FLAG":15,"BASE":18} -LSC Smart Connect Power {"NAME":"LSC Smart Plug","GPIO":[255,255,255,255,56,255,0,0,21,255,17,255,255],"FLAG":0,"BASE":18} -LSC Smart Connect Power Plug v2 {"NAME":"LSC Smart Plug","GPIO":[0,0,0,0,56,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} +LSC Smart Connect Power Plug {"NAME":"LSC Smart Plug","GPIO":[0,0,0,0,56,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} Lumiman LM650 {"NAME":"Lumiman LM650","GPIO":[0,0,0,0,56,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} Luminea NX-4491 {"NAME":"Luminea NX-449","GPIO":[56,0,158,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":18} -Luminea ZX-2820 {"NAME":"ZX2820-675","GPIO":[0,0,56,0,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":45} -Luminea ZX-2820 v2 {"NAME":"ZX2820-675","GPIO":[0,0,0,17,133,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":65} +Luminea NX-4541 {"NAME":"NX-4451","GPIO":[0,0,0,17,0,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":55} +Luminea ZX-2820 {"NAME":"ZX2820-675","GPIO":[0,0,0,17,133,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":65} Luminea ZX-2858 {"NAME":"Luminea SF-200","GPIO":[0,0,0,17,0,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":18} Martin Jerry XS-SSA01 {"NAME":"MJ_XS-SSA01","GPIO":[0,17,0,0,0,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":18} Maxcio W-DE004 {"NAME":"Maxcio W-DE004","GPIO":[0,17,0,0,0,0,0,0,0,56,21,0,0],"FLAG":1,"BASE":18} @@ -732,20 +619,25 @@ Merkury MI-WW102-199L {"NAME":"MIC-WW102","GPIO":[17,0,0,0,0,0,0,0,0,56,21,0, Merkury MI-WW105-199W {"NAME":"Merkury Switch","GPIO":[255,255,255,255,53,56,0,0,21,17,255,255,255],"FLAG":1,"BASE":18} Minleaf W-DEXI {"NAME":"W-DEXI","GPIO":[0,17,0,0,134,132,0,0,131,52,21,0,0],"FLAG":0,"BASE":18} Mirabella Genio 1002341 {"NAME":"Genio 1","GPIO":[0,0,56,0,0,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":1} +Mistral {"NAME":"Mistral Smart ","GPIO":[56,0,0,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":18} Moes NX-SP203 {"NAME":"Moes NX-SP203","GPIO":[52,0,0,0,17,134,0,0,21,18,0,22,0],"FLAG":0,"BASE":18} Moes WS-UEU {"NAME":"MoesHouse","GPIO":[0,0,0,21,17,0,0,0,57,0,0,0,0],"FLAG":0,"BASE":18} +MoKo YX-WS01A {"NAME":"MoKo Plug","GPIO":[0,17,0,0,0,0,0,0,0,57,21,0,0],"FLAG":0,"BASE":18} Nanxin NX-SM400 {"NAME":"NX-SM400","GPIO":[0,0,0,17,134,132,0,0,130,52,21,0,0],"FLAG":0,"BASE":18} +Naxa NSH-1000 {"NAME":"Naxa NSH-1000","GPIO":[0,0,0,0,17,0,0,0,57,56,21,0,0],"FLAG":0,"BASE":18} Nedis P110 {"NAME":"Nedis WIFIP110","GPIO":[17,0,0,0,134,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":49} Nedis P130 {"NAME":"WIFIP130FWT","GPIO":[0,0,0,0,56,57,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} -NEO Coolcam 16A {"NAME":"Neo Coolcam 16","GPIO":[17,0,0,0,133,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":49} -NEO Coolcam 16A v2 {"NAME":"Neo Coolcam 16","GPIO":[17,0,0,0,134,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":49} NEO Coolcam NAS-WR01W {"NAME":"NAS-WR01W","GPIO":[0,0,0,0,52,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} +NEO Coolcam NAS-WR01W 16A {"NAME":"Neo Coolcam 16","GPIO":[17,0,0,0,134,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":49} Nishica SM-PW701I {"NAME":"SM-PW701I","GPIO":[255,255,255,255,255,255,255,255,21,52,17,255,255],"FLAG":15,"BASE":18} NX-SM112 {"NAME":"NX-SM112v3","GPIO":[0,0,0,0,134,132,0,0,158,17,130,21,0],"FLAG":0,"BASE":45} NX-SM200 {"NAME":"NX-SM200","GPIO":[56,0,0,0,0,134,0,0,21,17,132,57,131],"FLAG":0,"BASE":18} Obi Stecker {"NAME":"OBI Socket","GPIO":[255,255,0,255,52,21,0,0,54,255,17,0,255],"FLAG":1,"BASE":51} Obi Stecker 2 {"NAME":"OBI Socket 2","GPIO":[0,0,0,0,21,17,0,0,56,53,0,0,0],"FLAG":0,"BASE":61} Oittm Smart {"NAME":"Oittm","GPIO":[0,0,0,0,21,56,0,0,17,0,0,0,0],"FLAG":0,"BASE":1} +Olliwon {"NAME":"Olliwon","GPIO":[0,0,56,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":18} +Orbecco W-US009 {"NAME":"Orbecco Plug","GPIO":[0,17,0,0,0,0,0,0,0,52,21,0,0],"FLAG":0,"BASE":18} +Orvibo B25 {"NAME":"Orvibo B25","GPIO":[0,0,0,0,53,21,0,0,52,0,17,0,0],"FLAG":0,"BASE":18} Oukitel P1 {"NAME":"Oukitel P1Dual","GPIO":[52,255,0,255,0,0,0,0,22,17,0,21,0],"FLAG":0,"BASE":18} Oukitel P2 {"NAME":"Oukitel P2","GPIO":[0,0,57,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":18} Oukitel X6P {"NAME":"OUKITEL X6P","GPIO":[0,0,57,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":18} @@ -756,13 +648,17 @@ OxaOxe NX-SP202 v2 {"NAME":"oxaoxe-dold","GPIO":[56,0,0,131,17,134,0,0,21, Panamalar NX-SM200 {"NAME":"NX-SM200","GPIO":[0,0,0,0,56,134,0,0,131,17,132,21,0],"FLAG":1,"BASE":18} Positivo PPW1000 {"NAME":"PPW1000","GPIO":[0,0,56,0,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":45} Powertech {"NAME":"Jaycar","GPIO":[56,0,0,0,0,0,0,0,0,9,0,21,0],"FLAG":0,"BASE":6} +Powertech MS6104 {"NAME":"Jaycar MS6104","GPIO":[0,0,0,17,134,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":52} +Powrui 3-Outlet with 4 USB {"NAME":"POWRUI AHR-077","GPIO":[0,0,0,20,19,18,0,0,22,23,17,21,157],"FLAG":0,"BASE":18} Powrui AW-08 {"NAME":"POWRUI AW-08","GPIO":[0,0,0,0,9,21,0,0,0,52,57,0,0],"FLAG":1,"BASE":18} -Powrui Surge Protector 4USB+3AC {"NAME":"POWRUI AHR-077","GPIO":[0,0,0,0,19,18,0,0,22,23,17,21,157],"FLAG":0,"BASE":18} Premier PWIFPLG {"NAME":"Premier Plug","GPIO":[0,0,0,17,0,0,0,0,0,56,21,0,0],"FLAG":1,"BASE":18} Prime CCRCWFII113PK {"NAME":"Prime","GPIO":[0,0,0,0,57,56,0,0,21,122,0,0,0],"FLAG":0,"BASE":18} +Prime RCWFII11 {"NAME":"Prime Plug","GPIO":[0,0,0,0,56,0,0,0,21,0,17,0,0],"FLAG":0,"BASE":18} +PrimeCables Cab-LA-WF4 {"NAME":"Mini Smart Outlet Wifi Socket with Timer Function","GPIO":[0,0,0,56,57,0,0,0,0,0,0,21,17],"FLAG":0,"BASE":18} RenPho RF-SM004 {"NAME":"RenPho RFSM004","GPIO":[0,0,0,0,157,56,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} RSH-WS007-EU {"NAME":"RSH-WS007","GPIO":[0,0,56,0,0,134,0,0,131,17,132,21,0],"FLAG":1,"BASE":18} Shelly Plug S {"NAME":"Shelly Plug S","GPIO":[57,255,56,255,0,134,0,0,131,17,132,21,0],"FLAG":2,"BASE":45} +Silvergear Slimme Stekker {"NAME":"Silvergear SmartHomePlug","GPIO":[0,0,0,122,0,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":18} Slitinto NX-SM110 {"NAME":"Slitinto SM110","GPIO":[0,0,56,0,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":45} Slitinto NX-SM112 {"NAME":"NX-SM112","GPIO":[158,0,0,131,0,134,0,0,0,17,132,21,0],"FLAG":0,"BASE":45} Slitinto NX-SM112 v2 {"NAME":"Slitinto NX SM","GPIO":[56,255,158,255,0,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":45} @@ -770,8 +666,10 @@ Slitinto NX-SM200 {"NAME":"NX-SM200","GPIO":[0,0,0,17,134,132,0,0,0,52,21 Slitinto NX-SM2001 {"NAME":"NX-SM2001","GPIO":[0,0,0,17,134,132,0,0,131,52,21,0,0],"FLAG":0,"BASE":45} Slitinto NX-SP201 Mini 2 in 1 {"NAME":"Slitinto Dual ","GPIO":[158,0,0,131,90,134,0,0,21,91,132,22,0],"FLAG":0,"BASE":18} Slitinto NX-SP202 {"NAME":"Slitinto SP202","GPIO":[17,0,0,0,134,132,0,0,131,52,22,21,91],"FLAG":0,"BASE":64} +SM-PW701K {"NAME":"SM-PW701K","GPIO":[0,0,0,0,52,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} Smaho {"NAME":"SMAHO WiFi P.","GPIO":[17,0,0,0,134,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":18} SmartDGM PP-W162 {"NAME":"SmartDGM Plug","GPIO":[0,0,0,17,134,132,0,0,131,52,21,0,0],"FLAG":0,"BASE":18} +SmartGrade AC 5008 {"NAME":"SmartGrade AC","GPIO":[17,0,0,0,133,132,0,0,131,56,21,0,0],"FLAG":0,"BASE":49} Sonoff S20 {"NAME":"Sonoff S20","GPIO":[17,255,255,255,0,0,0,0,21,56,0,0,0],"FLAG":0,"BASE":8} Sonoff S22 TH {"NAME":"Sonoff S22","GPIO":[17,255,0,255,255,0,0,0,21,56,255,0,0],"FLAG":0,"BASE":4} Sonoff S26 {"NAME":"Sonoff S26","GPIO":[17,255,255,255,0,0,0,0,21,56,0,0,0],"FLAG":0,"BASE":8} @@ -782,6 +680,7 @@ SP201 Dual {"NAME":"SP-201","GPIO":[31,0,0,131,17,134,0,0,21,18,13 SPARKE JH-G01E 10A {"NAME":"SPARKE JH-G01E","GPIO":[0,0,0,0,52,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} SPC Clever 6201B {"NAME":"SPC Clever Plu","GPIO":[17,0,0,0,0,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":18} SS01 {"NAME":"Smart Plug SS0","GPIO":[255,255,255,255,255,255,0,0,21,17,255,255,255],"FLAG":1,"BASE":18} +Steren SHOME-100 {"NAME":"SHOME-100 V1.0","GPIO":[0,0,0,0,0,56,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} STITCH by Monoprice 27937 {"NAME":"Stitch 27937","GPIO":[17,0,56,0,133,132,0,0,131,0,21,0,57],"FLAG":0,"BASE":18} STITCH by Monoprice 35511 {"NAME":"Stitch 35511","GPIO":[56,0,57,0,0,133,0,0,0,17,132,21,131],"FLAG":0,"BASE":18} SuperNight Dual {"NAME":"SuperNight Dua","GPIO":[255,17,255,21,132,133,0,0,22,130,58,255,255],"FLAG":1,"BASE":18} @@ -793,8 +692,9 @@ SWA5 {"NAME":"Lingan SWA5","GPIO":[56,0,0,0,0,0,0,0,0,17,0,2 SWA9 {"NAME":"SWA9","GPIO":[0,0,0,0,52,21,0,0,0,17,0,0,0],"FLAG":0,"BASE":18} SwissTone SH 100 {"NAME":"SwissTone","GPIO":[0,0,0,0,56,57,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} Sygonix SY-4276902 {"NAME":"SYGONIX","GPIO":[0,0,0,17,133,132,0,0,131,52,21,0,0],"FLAG":0,"BASE":18} -TanTan WP3 {"NAME":"TanTan WP3","GPIO":[57,0,56,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":18} -TCP WISSINWUK {"NAME":"TCP_Plug","GPIO":[0,0,0,0,52,21,0,0,0,17,0,0,0],"FLAG":0,"BASE":45} +TanTan WP2 {"NAME":"TanTan WP2","GPIO":[57,56,158,255,21,134,255,255,131,17,132,22,18],"FLAG":15,"BASE":18} +TanTan WP3 {"NAME":"TanTan WP3","GPIO":[0,0,56,0,17,0,0,0,57,0,21,0,0],"FLAG":0,"BASE":18} +TCP Smart WISSINWUK {"NAME":"TCP_Plug","GPIO":[0,0,0,0,52,21,0,0,0,17,0,0,0],"FLAG":0,"BASE":45} Teckin SP10 {"NAME":"Teckin SP10","GPIO":[255,255,56,255,255,255,0,0,255,17,255,21,255],"FLAG":0,"BASE":18} Teckin SP20 {"NAME":"TECKIN SP20","GPIO":[56,255,57,255,21,134,0,0,131,17,132,0,0],"FLAG":0,"BASE":45} Teckin SP21 {"NAME":"Teckin SP21","GPIO":[0,0,56,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":45} @@ -804,6 +704,7 @@ Teckin SP25 {"NAME":"Teckin SP25","GPIO":[56,255,255,255,255,255,0, Teckin SP27 {"NAME":"Teckin SP27","GPIO":[56,255,255,255,255,255,0,0,255,17,255,21,255],"FLAG":0,"BASE":18} Tflag NX-SM100 {"NAME":"NX-SM100","GPIO":[56,0,0,0,0,134,0,0,21,17,132,57,131],"FLAG":0,"BASE":18} TikLok TL650 {"NAME":"TikLok Mini","GPIO":[0,0,0,0,57,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} +Timethinker C338 {"NAME":"C338","GPIO":[17,0,255,0,0,0,0,0,21,52,255,0,0],"FLAG":0,"BASE":1} Timethinker TK04 {"NAME":"TimethinkerEU","GPIO":[255,255,255,255,17,255,0,0,255,52,21,255,0],"FLAG":0,"BASE":18} TimeThinker WS2 {"NAME":"TimeThinkerWS2","GPIO":[0,0,0,0,17,0,0,0,0,52,21,0,0],"FLAG":0,"BASE":18} TomaxUSA HKWL-SO07W {"NAME":"HKWL-SO07W","GPIO":[17,255,255,255,255,255,0,0,255,255,21,255,56],"FLAG":0,"BASE":18} @@ -818,6 +719,7 @@ Varna Crafts 16A {"NAME":"VC Plug","GPIO":[157,0,0,0,0,134,0,0,131,17,13 Vaupan X6P {"NAME":"Vaupan 10a X6P","GPIO":[0,0,56,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":18} Vingo {"NAME":"Karpal-01","GPIO":[0,0,0,0,0,56,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} Vivanco 39625 Smart Home Power Adapter {"NAME":"Vivianco","GPIO":[0,0,0,17,133,132,0,0,131,52,21,0,0],"FLAG":0,"BASE":18} +Vivitar HA-1003 {"NAME":"Vivitar HA1003","GPIO":[158,0,56,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":18} Vivitar HA-1006 {"NAME":"HA-1006","GPIO":[0,0,0,0,56,0,0,0,21,90,0,0,0],"FLAG":0,"BASE":18} Vivitar HA-1006-AU {"NAME":"HA-1006-AU","GPIO":[0,0,0,0,56,0,0,0,21,90,0,0,0],"FLAG":0,"BASE":18} WAGA life CHCZ02MB {"NAME":"WAGA CHCZ02MB","GPIO":[57,0,0,131,0,134,0,0,21,17,132,56,0],"FLAG":0,"BASE":68} @@ -836,11 +738,12 @@ Wsiiroon {"NAME":"WSIIROON","GPIO":[0,0,0,0,17,56,0,0,21,0,0,0,0 Wsiiroon {"NAME":"Wsiiroon/Wsky","GPIO":[0,0,0,0,17,56,0,0,21,0,0,0,0],"FLAG":0,"BASE":18} Wyze WLPP1 {"NAME":"WyzePlugWLPP1","GPIO":[0,0,0,0,0,56,0,0,21,0,17,0,0],"FLAG":0,"BASE":18} Xenon SM-PW702-U {"NAME":"SM-PW702","GPIO":[0,0,0,0,57,56,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} +Xiaomi IMILAB ZNCZ05CM {"NAME":"Mi Smart Plug","GPIO":[17,0,0,0,56,21,0,0,0,158,0,0,0],"FLAG":0,"BASE":18} XS-A11 {"NAME":"THRUMM XS-A11","GPIO":[0,17,0,0,0,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":18} XS-A12 {"NAME":"XS-A12","GPIO":[37,0,39,0,38,134,0,0,131,17,132,21,0],"FLAG":0,"BASE":45} XS-A14 {"NAME":"NETVIP XS-A14","GPIO":[37,0,38,0,0,17,0,0,39,21,0,0,0],"FLAG":0,"BASE":18} XS-A17 {"NAME":"XS-A18","GPIO":[37,0,38,0,0,39,0,0,0,17,0,21,0],"FLAG":0,"BASE":45} -XS-A18 {"NAME":"XS-A18","GPIO":[37,0,38,0,0,39,0,0,0,17,0,21,0],"FLAG":0,"BASE":45} +XS-A18 {"NAME":"XS-A18","GPIO":[56,0,53,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":45} XS-A23 {"NAME":"XS-A23","GPIO":[56,255,0,131,17,134,0,0,0,18,132,21,22],"FLAG":0,"BASE":45} XS-SSA01 {"NAME":"XS-SSA01","GPIO":[255,17,255,255,255,255,0,0,255,56,21,255,255],"FLAG":0,"BASE":18} XS-SSA01 v2 {"NAME":"XS-SSA01","GPIO":[255,17,255,255,255,255,0,0,56,255,255,21,255],"FLAG":0,"BASE":18} @@ -849,7 +752,10 @@ XS-SSA06 {"NAME":"XS-SSA06","GPIO":[37,0,38,0,0,39,0,0,0,90,0,21 Yagala SWA9 {"NAME":"SWA9","GPIO":[0,0,0,0,52,21,0,0,0,17,0,0,0],"FLAG":0,"BASE":18} Yelomin JH-G01E {"NAME":"Yelomin","GPIO":[0,145,0,146,0,0,0,0,17,56,21,0,0],"FLAG":0,"BASE":18} YERON US101 {"NAME":"YERON_US101","GPIO":[255,255,255,17,133,132,0,0,131,56,21,255,255],"FLAG":0,"BASE":18} +YM-WS-1 Mini {"NAME":"YM-WS1","GPIO":[0,0,0,0,0,0,0,0,56,17,0,21,0],"FLAG":0,"BASE":18} YT-E003 {"NAME":"YT-E003-SP202","GPIO":[17,0,0,0,134,132,0,0,131,52,22,21,91],"FLAG":0,"BASE":64} +Yuanguo KS-501 {"NAME":"Yuanguo_KS-501","GPIO":[17,0,0,0,0,0,0,0,21,56,0,0,0],"FLAG":0,"BASE":18} +YX-DE01 {"NAME":"YX-DE01","GPIO":[0,17,0,0,0,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":18} YX-WS02 {"NAME":"Amysen YX-WS02","GPIO":[255,17,255,255,255,255,0,0,255,56,21,255,255],"FLAG":1,"BASE":18} ZBR-001 {"NAME":"ZBR-001","GPIO":[17,255,255,255,133,132,0,0,130,56,21,255,57],"FLAG":1,"BASE":18} ZooZee SA101 {"NAME":"ZooZee","GPIO":[57,255,56,255,255,255,0,0,255,17,255,21,255],"FLAG":0,"BASE":18} @@ -860,15 +766,16 @@ ZSP-001 {"NAME":"ZSP-001","GPIO":[17,255,255,255,133,132,0,0,13 ## Power Strip ``` -A0F0 ZLD-44EU-W {"NAME":"AOFO-4AC-4USB","GPIO":[0,56,0,17,22,21,0,0,23,24,25,0,0],"FLAG":1,"BASE":18} -ACENX 3AC+3USB {"NAME":"ACENX 3-Outlet","GPIO":[56,55,54,53,0,21,0,0,23,24,22,0,17],"FLAG":0,"BASE":18} +A0F0 ZLD-44EU-W {"NAME":"AOFO-4AC-4USB","GPIO":[0,56,0,17,22,21,0,0,23,24,33,0,0],"FLAG":1,"BASE":18} +Acenx 3AC+3USB {"NAME":"ACENX 3-Outlet","GPIO":[56,55,54,53,0,21,0,0,23,24,22,0,17],"FLAG":0,"BASE":18} Annhome 3AC + 2USB {"NAME":"1200W WiFi SPS","GPIO":[32,0,0,0,57,52,0,0,21,17,22,23,33],"FLAG":0,"BASE":18} AOFO 3AC+4USB {"NAME":"AOFO","GPIO":[0,56,0,17,22,21,0,0,0,23,24,0,0],"FLAG":1,"BASE":18} AOFO 4AC+4USB {"NAME":"AOFO4AC4USB","GPIO":[0,56,0,17,22,21,0,0,23,24,25,0,0],"FLAG":0,"BASE":18} AOFO 4AC+4USB Tuya {"NAME":"AOFO-4AC-4USB","GPIO":[255,255,255,255,255,255,0,0,255,255,255,255,255],"FLAG":1,"BASE":54} AOFO 4AC+4USB UK {"NAME":"AOFO4AC4USB-UK","GPIO":[0,56,0,17,23,24,0,0,22,21,33,0,0],"FLAG":0,"BASE":18} -Arlec PB88UHA {"NAME":"ArlecPowerStri","GPIO":[0,0,0,255,22,21,0,0,24,23,0,0,0],"FLAG":0,"BASE":18} -Arlec PB89HA {"NAME":"Arlec PB89HA","GPIO":[255,255,255,255,22,21,0,0,24,23,255,255,255],"FLAG":15,"BASE":18} +Arlec Smart 3 Outlet Power Cube {"NAME":"Arlec Cube","GPIO":[0,17,0,0,0,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":18} +Arlec Smart PB88UHA {"NAME":"Arlec PB88UHA","GPIO":[0,56,0,17,22,21,0,0,24,23,0,0,0],"FLAG":15,"BASE":18} +Arlec Smart PB89HA {"NAME":"Arlec PB89HA","GPIO":[0,56,0,17,22,21,0,0,24,23,0,0,0],"FLAG":0,"BASE":18} Bauhn ASPBU-1019 {"NAME":"Bauhn 3AC+3USB","GPIO":[0,157,0,0,22,21,0,0,0,23,17,0,0],"FLAG":0,"BASE":18} BlitzWolf BW-SHP9 {"NAME":"BlitzWolf SHP9","GPIO":[158,255,0,255,0,23,0,0,21,17,22,24,0],"FLAG":0,"BASE":45} BrilliantSmart 20691 Powerboard with USB Chargers {"NAME":"B_WiFi-4","GPIO":[56,0,0,57,29,17,0,0,31,30,32,0,25],"FLAG":1,"BASE":18} @@ -877,10 +784,12 @@ CE Smart Home Garden Stake LH-7-1 {"NAME":"CE Power Stake","GPIO":[0,0,0,0,56,5 CRST LTS-4G-W {"NAME":"CRST LTS-4G-W","GPIO":[0,0,0,0,24,0,0,0,22,23,21,0,0],"FLAG":0,"BASE":18} Deltaco SH-P03USB {"NAME":"Deltaco SH-P03","GPIO":[0,56,0,0,0,21,0,0,23,17,22,24,0],"FLAG":1,"BASE":18} Digoo DG-PS01 {"NAME":"Digoo DG-PS01","GPIO":[0,56,0,17,23,22,0,0,0,24,21,0,0],"FLAG":1,"BASE":18} -Geekbes 4AC+4USB {"NAME":"Geekbes 4xStri","GPIO":[0,56,0,17,22,21,0,0,23,24,25,0,0],"FLAG":1,"BASE":18} +Geekbes 4AC+4USB {"NAME":"Geekbes 4xStri","GPIO":[0,56,0,17,22,21,0,0,23,24,25,0,0],"FLAG":1,"BASE":18} Geeni Surge {"NAME":"Geeni GNCSW003","GPIO":[52,0,0,0,22,21,0,0,24,25,23,26,17],"FLAG":0,"BASE":18} Geeni Surge Mini {"NAME":"Geeni-GN-SW004","GPIO":[56,0,0,17,0,0,0,0,22,21,23,0,0],"FLAG":15,"BASE":18} +Gosund P1 {"NAME":"Gosund_P1","GPIO":[0,145,157,146,0,32,0,0,22,23,21,0,17],"FLAG":1,"BASE":18} Gousund WP9 {"NAME":"Gosund WP9","GPIO":[56,55,54,53,0,21,0,0,23,24,22,0,17],"FLAG":0,"BASE":18} +HIPER IoT PS44 {"NAME":"HIPER IoT PS44","GPIO":[0,56,0,17,22,21,0,0,23,24,25,0,0],"FLAG":0,"BASE":18} Hyleton 330 {"NAME":"Hyleton-330","GPIO":[57,0,0,56,29,17,0,0,31,30,32,0,25],"FLAG":0,"BASE":18} Hyleton 331 {"NAME":"HLT-331","GPIO":[52,255,255,57,29,17,0,0,31,30,32,255,58],"FLAG":0,"BASE":18} Hyleton 333 {"NAME":"HLT-333","GPIO":[52,0,0,57,29,17,0,0,31,30,0,0,24],"FLAG":0,"BASE":18} @@ -889,8 +798,10 @@ KMC 5 {"NAME":"KMC 5-Outlet","GPIO":[56,0,0,0,25,9,0,0,22,21, Kogan Power Strip USB Ports & Energy Meter {"NAME":"Generic","GPIO":[90,56,0,24,134,132,0,0,131,22,23,21,0],"FLAG":0,"BASE":18} Koogeek KLOE4 {"NAME":"Koogeek KLOE4","GPIO":[0,56,0,17,22,21,0,0,23,24,25,0,0],"FLAG":1,"BASE":18} LeFun SK2 {"NAME":"LeFun SK2","GPIO":[0,0,0,17,22,21,0,0,23,24,25,0,0],"FLAG":0,"BASE":18} +Luminea 3AC+4USB 16A {"NAME":"Luminea-NX4473","GPIO":[0,56,0,17,22,21,0,0,0,23,24,0,0],"FLAG":0,"BASE":18} Maxcio ZLD-34EU-W {"NAME":"MAXCIO","GPIO":[0,56,0,17,22,21,0,0,0,23,24,0,0],"FLAG":1,"BASE":18} Meross MSS425 {"NAME":"Meross MSS425","GPIO":[33,0,0,0,56,0,0,0,21,17,22,23,32],"FLAG":0,"BASE":18} +Mirabella Genio 4 Outlet Power Board with 2 USB {"NAME":"Genio i002340","GPIO":[56,0,0,0,21,22,0,0,23,17,24,25,0],"FLAG":0,"BASE":18} Mirabella Genio Powerboard I002578 {"NAME":"Genio Powerboa","GPIO":[21,52,0,0,23,22,0,0,25,17,26,24,0],"FLAG":0,"BASE":18} Nedis P310 {"NAME":"Nedis WIFIP310","GPIO":[0,56,0,17,22,21,0,0,0,23,24,0,0],"FLAG":1,"BASE":18} Powrui AHR-079 {"NAME":"Powrui Power S","GPIO":[56,0,0,17,19,21,0,0,23,20,22,24,18],"FLAG":0,"BASE":18} @@ -899,10 +810,12 @@ S2199EU {"NAME":"S2199EU","GPIO":[0,17,0,52,23,25,0,0,21,24,22, SA-P402A {"NAME":"SA-P402A","GPIO":[0,17,0,56,23,25,21,24,22,0,0,1,0],"FLAG":1,"BASE":18} STITCH by Monoprice 34082 {"NAME":"Stitch 34082","GPIO":[255,255,255,255,21,20,0,0,23,22,24,255,255],"FLAG":0,"BASE":18} SWB1 {"NAME":"SWB1","GPIO":[52,0,0,0,0,24,0,0,21,17,22,23,0],"FLAG":0,"BASE":18} +TCP Smart 4AC+USB {"NAME":"TCP WPS4WUK","GPIO":[255,56,0,17,23,24,0,0,22,21,25,0,0],"FLAG":15,"BASE":18} Teckin SS30 {"NAME":"Teckin SS30","GPIO":[52,255,255,57,29,17,0,0,31,30,32,255,25],"FLAG":0,"BASE":18} Tellur TLL331031 {"NAME":"Tellur","GPIO":[0,56,0,17,22,21,0,0,0,23,24,0,0],"FLAG":1,"BASE":18} -TESSAN A4L-BK {"NAME":"TESSAN A4L-BK","GPIO":[0,0,0,24,23,0,0,0,21,0,22,0,0],"FLAG":0,"BASE":18} +Tessan A4L-BK {"NAME":"TESSAN A4L-BK","GPIO":[0,0,0,24,23,0,0,0,21,0,22,0,0],"FLAG":0,"BASE":18} Tonbux SM-SO301-U {"NAME":"Tonbux SM-SO30","GPIO":[56,0,0,0,29,0,0,0,31,30,32,0,25],"FLAG":0,"BASE":18} +Useelink SM-SO301AU {"NAME":"Useelink","GPIO":[56,0,0,0,29,0,0,0,31,30,32,0,25],"FLAG":0,"BASE":18} Vivitar HA-1007 {"NAME":"Vivitar HA1007","GPIO":[56,0,0,0,30,17,0,0,32,31,33,0,21],"FLAG":15,"BASE":18} Vivitar HA-1007-AU {"NAME":"HA-1007-AU","GPIO":[56,17,0,58,29,57,0,0,31,30,32,0,25],"FLAG":0,"BASE":18} wesmartify essentials 4AC+4USB {"NAME":"essential_4_po","GPIO":[56,0,0,0,24,25,0,0,22,21,23,0,17],"FLAG":0,"BASE":18} @@ -914,14 +827,14 @@ XS-A25 {"NAME":"XS-A25","GPIO":[52,0,53,0,25,22,0,0,24,17,23,2 XS-A26 {"NAME":"XS-A26","GPIO":[52,0,53,0,25,22,0,0,24,17,23,21,0],"FLAG":0,"BASE":18} XS-A34 {"NAME":"XS-A24","GPIO":[52,0,53,0,25,22,0,0,24,17,23,21,0],"FLAG":0,"BASE":18} Yagala {"NAME":"Yagala","GPIO":[0,0,0,17,22,24,0,0,23,25,21,0,0],"FLAG":0,"BASE":18} -Yagala SWB3 {"NAME":"YAGALA SWB3","GPIO":[0,0,53,0,0,23,0,0,21,0,22,24,0],"FLAG":1,"BASE":18} -Yagala SWB3 v2 {"NAME":"YAGALA SWB3","GPIO":[157,0,53,0,0,23,0,0,21,17,22,24,0],"FLAG":0,"BASE":18} +Yagala SWB3 {"NAME":"YAGALA SWB3","GPIO":[157,0,53,0,0,23,0,0,21,17,22,24,0],"FLAG":0,"BASE":18} +Yagala Z1 {"NAME":"YAGALA Z1","GPIO":[0,157,0,17,22,24,0,0,23,25,21,0,0],"FLAG":0,"BASE":18} Yuanguo 4AC + 2 USB {"NAME":"YUANGUO","GPIO":[0,20,0,24,19,18,0,0,17,22,21,23,0],"FLAG":0,"BASE":1} Yuanguo 4AC+2USB {"NAME":"YUANGUO","GPIO":[13,20,0,24,19,18,0,0,17,22,21,23,157],"FLAG":0,"BASE":1} Zeoota PS022 {"NAME":"ZEOOTA 3x plus","GPIO":[0,57,0,56,22,21,0,0,17,23,24,0,0],"FLAG":1,"BASE":18} Zeoota ZLD-44EU-W {"NAME":"ZEOOTA-ZLD-44E","GPIO":[0,56,0,17,22,21,0,0,23,24,25,0,0],"FLAG":1,"BASE":18} ZLD-44EU-W {"NAME":"ZLD-44EU-W","GPIO":[17,255,255,255,22,21,18,19,23,24,25,0,0],"FLAG":0,"BASE":23} -ZLD-44USA-W {"NAME":"ZLD-44USA-W","GPIO":[0,56,0,17,22,21,0,0,23,24,25,0,0],"FLAG":1,"BASE":18} +ZLD-44USA-W {"NAME":"ZLD-44USA-W","GPIO":[0,56,0,17,22,21,0,0,23,24,33,0,0],"FLAG":0,"BASE":18} ZLD64-EU-W {"NAME":"ZLD64-EU-W","GPIO":[0,56,0,17,22,21,0,0,0,0,23,0,0],"FLAG":0,"BASE":18} ``` @@ -930,13 +843,249 @@ ZLD64-EU-W {"NAME":"ZLD64-EU-W","GPIO":[0,56,0,17,22,21,0,0,0,0,23 Sonoff RF Bridge 433 {"NAME":"Sonoff Bridge","GPIO":[17,148,255,149,255,255,0,0,255,56,255,0,0],"FLAG":0,"BASE":25} ``` +## RGB +``` +Deltaco SH-LE27RGB 810lm {"NAME":"SH-LE27RGB","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} +Halonix Prime Prizm 12W {"NAME":"Halonix Prizm ","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Jomarto 9W {"NAME":"Jomarto Wifi S","GPIO":[0,0,0,0,40,0,0,0,38,39,37,0,0],"FLAG":1,"BASE":18} +Lyasi PT-BW09 {"NAME":"Lyasi PT-BW09","GPIO":[17,0,0,0,143,144,0,0,0,0,0,0,0],"FLAG":0,"BASE":27} +MoKo YX-L01C-E27 810lm {"NAME":"MOKO","GPIO":[17,0,0,0,143,144,0,0,0,0,0,0,0],"FLAG":0,"BASE":27} +muvit IO miobulb001 600lm {"NAME":"miobulb001","GPIO":[0,0,0,0,40,0,0,0,38,39,37,0,0],"FLAG":15,"BASE":18} +Oobest ZN93028 11W {"NAME":"RGB Bulb 11W","GPIO":[0,0,0,0,40,0,0,0,38,39,37,0,0],"FLAG":1,"BASE":18} +Wipro Garnet NS7001 480lm {"NAME":"WiproSmartBulb","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +``` + +## RGBCCT +``` +Aigital LE13 800lm {"NAME":"Aigital 9W RGB","GPIO":[0,0,0,0,41,38,0,0,39,0,40,37,0],"FLAG":0,"BASE":18} +Alfawise LE12 9W 900LM {"NAME":"Alfawise LE12 ","GPIO":[0,0,0,0,41,38,0,0,39,0,40,37,0],"FLAG":0,"BASE":18} +Aoycocr JL81 5W 400lm {"NAME":"AoycocrJLB1","GPIO":[0,0,0,0,39,0,0,0,38,41,37,40,0],"FLAG":0,"BASE":18} +Aoycocr Q0 750lm {"NAME":"AoycocrA19","GPIO":[0,0,0,0,0,39,0,0,38,0,37,40,0],"FLAG":0,"BASE":18} +Aoycocr Q10CWM BR30 9W 720lm {"NAME":"AoycocrBR30","GPIO":[0,0,0,0,0,39,0,0,38,0,37,40,0],"FLAG":0,"BASE":18} +Arlec Smart 9.5W 806lm {"NAME":"Arlec RGBWW","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Arlec Smart 9.5W 806lm {"NAME":"Arlec RGBWW","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Aunics 7W 600lm {"NAME":"Aunics RGBW","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Avatar ALB201W 720lm {"NAME":"AVATAR ALB201W","GPIO":[0,0,0,0,0,39,0,0,38,0,37,40,0],"FLAG":0,"BASE":18} +Avatar ALS18L A60 800lm {"NAME":"Avatar E14 7W","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":20} +B.K.Licht BKL1253 9W 806lm {"NAME":"BKL1253","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} +Bakibo TB95 9W 1000lm {"NAME":"Bakibo A19 9W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +BAZZ BR30 650lm {"NAME":"BAZZrgb","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":1,"BASE":18} +BlitzWolf BW-LT27 w/ remote 850lm {"NAME":"BW-LT27","GPIO":[0,0,0,0,41,38,0,0,39,51,40,37,0],"FLAG":0,"BASE":18} +BNeta IO-WIFI60-E27P 800lm {"NAME":"OM60/RGBW","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} +Bomcosy 600lm {"NAME":"Generic","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":1,"BASE":18} +Calex 429002 Reflector 350lm {"NAME":"Calex RGBW","GPIO":[0,0,0,0,0,0,0,0,181,0,180,0,0],"FLAG":0,"BASE":18} +Calex 429004 A60 806lm {"NAME":"Calex E27 RGB ","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Calex 429008 B35 5W 470lm {"NAME":"Calex E14 RGBW","GPIO":[0,0,0,0,0,0,0,0,181,0,180,0,0],"FLAG":0,"BASE":18} +Cleverio 51395 806lm {"NAME":"CleverioE27RGB","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} +CMARS 4W Reflector {"NAME":"RGBWW GU10","GPIO":[0,0,0,0,40,41,0,0,38,39,37,0,0],"FLAG":15,"BASE":18} +Dogain 320lm {"NAME":"DOGAIN","GPIO":[0,0,0,0,40,41,0,0,38,39,37,0,0],"FLAG":0,"BASE":18} +Emuni TB95 9W 850Lm {"NAME":"TB95","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Ener-J SHA5262 800lm {"NAME":"ENER-J RGBWWW ","GPIO":[0,0,0,0,40,41,0,0,38,39,37,0,0],"FLAG":0,"BASE":18} +Euri Lighting 10W 800lm {"NAME":"Euri Lighting ","GPIO":[0,0,0,0,37,40,0,0,38,41,39,37,0],"FLAG":0,"BASE":18} +EXUP C37 5W {"NAME":"EXUP","GPIO":[0,0,0,0,40,41,0,0,38,39,37,0,0],"FLAG":15,"BASE":18} +Feit Electric A19 1600lm {"NAME":"OM100/RGBWW","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Feit Electric A19 800lm {"NAME":" BPA800/RGBW/AG/2","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} +Feit Electric A19 800lm {"NAME":" BPA800/RGBW/AG/2P","GPIO":[0,0,0,0,37,38,0,0,141,142,140,0,0],"FLAG":0,"BASE":48} +Feit Electric A19 800lm {"NAME":"FE-OM60-15K-AG","GPIO":[0,0,0,0,141,140,0,0,37,142,38,0,0],"FLAG":0,"BASE":18} +Feit Electric A19 800lm {"NAME":"OM60/RGBW","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} +Fitop 9W {"NAME":"E27RGBCCT9w","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":15,"BASE":18} +Fulighture 9W 810lm {"NAME":"Fulighture 9W","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} +Geeni Prisma Plus 800lm {"NAME":"Geeni Prisma P","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} +Globe 34207 800lm {"NAME":"GlobeRGBWW","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +HIPER IoT A61 {"NAME":"HIPER IoT A61","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Infray 9W 900LM {"NAME":"InfrayRGBCCT","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Jeeo TF-QPZ13 800lm {"NAME":"Jeeo","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} +Julun JL-021 5W Candle {"NAME":"E14 RGBCCT","GPIO":[0,0,0,0,40,41,0,0,38,39,37,0,0],"FLAG":0,"BASE":18} +Kogan 10W 1050lm {"NAME":"Kogan RGB+CCT","GPIO":[255,255,255,0,37,40,255,255,38,50,39,255,255],"FLAG":15,"BASE":18} +Kohree 600lm {"NAME":"Kohree VHP560","GPIO":[0,0,0,0,37,41,0,0,38,40,39,0,0],"FLAG":0,"BASE":18} +LE lampUX 8.5W 806lm {"NAME":"lampUX","GPIO":[0,0,0,0,141,140,0,0,38,142,37,0,0],"FLAG":15,"BASE":18} +LE lampUX A19 850lm {"NAME":"LE RGBWW 60W","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":1,"BASE":18} +LE lampUX A19 9W 806lm {"NAME":"lampUX","GPIO":[0,0,0,0,141,140,0,0,38,142,37,0,0],"FLAG":15,"BASE":18} +Ledmundo 6W 600lm {"NAME":"LEDMUNDO 6W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Legelite 5W Candle {"NAME":"Legelite E12","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Legelite A60 7W {"NAME":"Legelite A60 7","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Legelite A60 7W 600lm {"NAME":"Legelite E26","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Lohas ZN011 5W 420lm {"NAME":"LohasZN011","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} +Lohas ZN014-2 5W 380lm {"NAME":"Lohas ZN014-2","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} +Lohas ZN031 650lm {"NAME":"Lohas ZN031","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} +Lohas ZN033 810lm {"NAME":"Lohas RGBWW","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} +Lohas ZN036 900 lm {"NAME":"Lohas RGBCCT","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} +Lohas ZN037 450lm {"NAME":"Lohas LH-ZN037","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":20} +Lohas ZN039 BR40 1450lm {"NAME":"Lohas ZN039","GPIO":[0,0,0,0,39,37,0,0,41,38,40,0,0],"FLAG":0,"BASE":18} +Lumary 9W 800lm {"NAME":"Lumary / iLint","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} +LVWIT A60 8.5W 806lm {"NAME":"LVWIT A60 8.5W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +LVWIT A70 12W 1521lm {"NAME":"LVWIT A70 12W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Novostella HM-LB09 13W 1300lm {"NAME":"Novostella 13W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Novostella NTB10 9W 900lm {"NAME":"NTB10","GPIO":[0,0,0,0,41,38,0,0,39,0,40,37,0],"FLAG":0,"BASE":18} +Novostella UT55505 7W 600lm {"NAME":"Novostella B22","GPIO":[0,0,0,0,37,41,0,0,38,40,39,0,0],"FLAG":0,"BASE":18} +Novostella UT55508 12W 1150lm {"NAME":"Novostella","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Novostella UT55509 13W 1300lm {"NAME":"Novostella 13W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Ohlux A19 7W 600lm {"NAME":"OHLUX","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Ohlux BR30 10W 900lm {"NAME":"OHLUX","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +oobest 7W {"NAME":"E27_RGBCW_Bulb","GPIO":[0,0,0,0,38,37,0,0,40,41,39,0,0],"FLAG":0,"BASE":18} +Positivo 10W 806lm {"NAME":"Positivo Bulb","GPIO":[0,0,0,0,37,40,0,0,38,50,39,0,0],"FLAG":0,"BASE":18} +Powertech SL225X 800lm {"NAME":"Jaycar SL225X","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Qualitel ALS08L 1100lm {"NAME":"Qualitel ALS08","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Reafoo A26 9W {"NAME":"ReaFooE26","GPIO":[0,0,0,0,41,38,0,0,39,0,40,37,0],"FLAG":0,"BASE":18} +RYE 5W 450LM Candle {"NAME":"RYE Candlebra","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Saudio A19 7W 700lm {"NAME":"X002BU0DOL","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Sealight A19 9W 810lm {"NAME":"DGO/SEASTAR","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} +Slitinto TB95 9W 1000lm {"NAME":"Slitinto 9W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +SmartLED 9W 400lm {"NAME":"SmartLED","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Sonoff B1 (R2) {"NAME":"Sonoff B1","GPIO":[17,0,0,0,0,0,0,0,143,0,144,0,0],"FLAG":0,"BASE":26} +Spectrum Smart GLS 9W 850lm {"NAME":"SPECTR. RGBCCT","GPIO":[0,0,0,0,0,0,0,0,181,0,180,0,0],"FLAG":0,"BASE":18} +Sunco G25 5W 450lm {"NAME":"Sunco G25","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} +Sunco PAR20 5W 400lm {"NAME":"Sunco PAR20","GPIO":[0,0,0,0,38,37,0,0,41,39,40,0,0],"FLAG":0,"BASE":18} +Teckin SB50 v3 A19 800lm {"NAME":"Teckin SB50v3","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Teckin SB53 1300lm {"NAME":"Teckin SB53","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +V-Tac PAR16 4.5W 400lm 100 {"NAME":"V-TAC VT5164","GPIO":[0,0,0,0,0,0,0,0,181,0,180,0,0],"FLAG":0,"BASE":18} +Vizia 5W GU10 {"NAME":"Vizia RGBWW","GPIO":[0,0,0,0,40,41,0,0,38,39,37,0,0],"FLAG":15,"BASE":18} +Wipro Garnet 9W 810lm {"NAME":"Wipro","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Zemismart 5W 480lm {"NAME":"Zemismart 5W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +ZZHXON 600lm {"NAME":"E27_RGB_Bulb","GPIO":[0,0,0,0,40,41,0,0,38,39,37,0,0],"FLAG":0,"BASE":18} +``` + +## RGBW +``` +3Stone EBE-QPW36 1050lm {"NAME":"3STONE","GPIO":[0,0,0,0,141,140,0,0,37,142,0,0,0],"FLAG":15,"BASE":18} +Accewit 7W 650lm {"NAME":"Accewit Bulb","GPIO":[0,0,0,0,0,38,0,0,39,0,40,37,0],"FLAG":0,"BASE":18} +Aisirer 7W 580lm {"NAME":"Aisirer RGBW","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} +Aisirer 7W 580lm {"NAME":"Aisirer RGBW","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} +AL Above Lights 810lm {"NAME":"AL 810LM","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} +Aoycocr Q3CM 230lm {"NAME":"Aoycocr_GU10","GPIO":[0,0,0,0,0,0,0,0,143,0,144,0,0],"FLAG":0,"BASE":27} +Aoycocr Q9WM A21 10W 900lm {"NAME":"Aoycocr Q9WM","GPIO":[0,0,0,0,0,39,0,0,38,40,37,41,0],"FLAG":0,"BASE":18} +Avatar ALS08L A19 910lm {"NAME":"Avatar E27 7W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":20} +Avatar ALS09L A60 900lm {"NAME":"Avatar E14 9W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":20} +Avatar ALS11L PAR16 500lm {"NAME":"Avatar_GU10","GPIO":[0,0,0,0,0,0,0,0,0,143,0,144,0],"FLAG":0,"BASE":27} +AWOW A60 9W 800lm {"NAME":"AWOW 9W RGBW","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} +Axtee AI-003 A19 700lm {"NAME":"Axtee E26 7W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":20} +Bawoo EUWL122130 925lm {"NAME":"Bawoo","GPIO":[0,0,0,0,140,37,0,0,0,142,141,0,0],"FLAG":0,"BASE":18} +BlitzWolf BW-LT21 900lm {"NAME":"BlitzWolf LT21","GPIO":[0,0,0,0,41,39,0,0,38,0,37,40,0],"FLAG":0,"BASE":18} +BNeta IO-WIFI-GU10 380lm {"NAME":"BNeta","GPIO":[0,0,0,0,141,140,0,0,37,142,0,0,0],"FLAG":0,"BASE":18} +BriHome 6,5W 500lm {"NAME":"BRI E27 6,5W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":20} +Brilliant HK17653S72 350lm {"NAME":"HK17653S72","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} +BrilliantSmart 20698 9W 800lm {"NAME":"Brilliant20698","GPIO":[0,0,0,0,141,140,0,0,37,142,0,0,0],"FLAG":0,"BASE":18} +BrilliantSmart 20699 9W 800lm {"NAME":"Brilliant20699","GPIO":[0,0,0,0,141,140,0,0,37,142,0,0,0],"FLAG":0,"BASE":18} +BrilliantSmart 20741 9W 750lm {"NAME":"Brilliant RGB+","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} +BrilliantSmart 20888 {"NAME":"BS-GU10-20888","GPIO":[0,0,0,0,140,38,0,0,37,142,141,0,0],"FLAG":0,"BASE":18} +BrizLabs A19 9W 806LM {"NAME":"TCP Smart RGBW","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} +BrizLabs Candle 4,5W 350lm {"NAME":"BrizLabs RGBW","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} +Brizlabs EBE-LZW10 350Lm {"NAME":"Brizlabs E14","GPIO":[0,0,0,0,141,140,0,0,37,142,0,0,0],"FLAG":15,"BASE":18} +BrizLabs EBE-SHW03 380lm {"NAME":"BrizLabs","GPIO":[0,0,0,0,140,37,0,0,0,142,141,0,0],"FLAG":0,"BASE":18} +BTZ1 {"NAME":"WifiBulb","GPIO":[0,0,0,0,0,37,0,0,39,40,38,0,0],"FLAG":0,"BASE":18} +Cleverio 51398 370lm {"NAME":"CleverioGU10","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} +Cocoon DY180363-B 800lm {"NAME":"Cocoon RGBW","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} +Connex Connect A60 6W 470lm {"NAME":"Connex RGBW Bu","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} +electriQ 600lm {"NAME":"ElectricQ B22","GPIO":[0,0,0,0,37,41,0,0,38,40,39,0,0],"FLAG":0,"BASE":18} +EleLight 350lm {"NAME":"EleLight 7wA19","GPIO":[0,0,0,0,140,37,0,0,0,142,141,0,0],"FLAG":0,"BASE":18} +Esicoo 810lm {"NAME":"Esicoo Bulb","GPIO":[0,0,0,0,143,144,0,0,0,0,0,0,0],"FLAG":0,"BASE":27} +Eurolux A70 10W {"NAME":"Eurolux A70 RG","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":1,"BASE":18} +Fcmila 10W {"NAME":"FCMILA LED E27","GPIO":[0,0,0,0,40,0,0,0,38,39,37,0,0],"FLAG":0,"BASE":18} +Fcmila 7W {"NAME":"FCMILA E27 0.1","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} +Fcmila Spotlight 460lm {"NAME":"Fcmila LED 6W","GPIO":[0,0,0,0,40,0,0,0,38,39,37,0,0],"FLAG":0,"BASE":18} +Feit Electric BR30 650lm {"NAME":"BR30/RGBW","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} +Feit Electric BR30 700lm {"NAME":"Feit BR30/RGBW","GPIO":[0,0,0,38,141,140,0,0,0,142,37,0,0],"FLAG":0,"BASE":18} +Fulighture A60 810lm {"NAME":"Fulighture A60","GPIO":[0,0,0,0,38,37,0,0,0,39,40,0,0],"FLAG":0,"BASE":18} +Geeni Prisma 1050lm {"NAME":"Geeni 1050 RGB","GPIO":[37,0,0,0,140,38,0,0,0,142,141,0,0],"FLAG":0,"BASE":18} +Generic 10W {"NAME":"10W E27 RGBW","GPIO":[0,0,0,0,0,39,0,0,38,0,37,40,0],"FLAG":0,"BASE":18} +Generic GU10 5W 450lm {"NAME":"RGBCW GU10","GPIO":[0,255,0,255,40,0,0,0,38,39,37,0,0],"FLAG":0,"BASE":3} +Gosund WB3 8W 800lm {"NAME":"Gosund WB3","GPIO":[0,0,0,0,40,0,0,0,37,38,39,0,0],"FLAG":0,"BASE":18} +Hama 10W 1050lm {"NAME":"Hama Bulb RGBW","GPIO":[0,0,0,0,140,37,0,0,0,142,141,0,0],"FLAG":0,"BASE":18} +Hama 10W 806lm {"NAME":"Hama Smart WiF","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} +Hama 4.5W {"NAME":"hama E14 RGB","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} +Hiiten A19 7W 650lm {"NAME":"Hiiten Bulb","GPIO":[37,0,0,0,140,38,0,0,0,142,141,0,0],"FLAG":0,"BASE":18} +Hykker SL-0492 810lm {"NAME":"Hykker RBGW 9W","GPIO":[0,0,0,0,0,40,0,0,37,0,39,38,0],"FLAG":0,"BASE":18} +Kainsy 600lm {"NAME":"KAINSY","GPIO":[17,0,0,0,143,144,0,0,0,0,0,0,0],"FLAG":0,"BASE":27} +Koaanw 650lm {"NAME":"KOAANW Bulb","GPIO":[0,0,0,0,143,144,0,0,0,0,0,0,0],"FLAG":0,"BASE":27} +Kogan 10W Ambient 1050lm {"NAME":"Kogan RGB","GPIO":[0,0,0,0,140,37,0,0,0,0,141,0,0],"FLAG":0,"BASE":18} +Kogan Ambient Candle {"NAME":"Kogan_E14","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} +Kogan Ambient Spotlight 330lm {"NAME":"Kogan_GU10","GPIO":[0,0,0,0,39,40,0,0,37,0,38,0,0],"FLAG":0,"BASE":18} +Kuled 800lm {"NAME":"KULED 60W RGB","GPIO":[0,0,0,0,39,40,0,0,37,0,38,0,0],"FLAG":1,"BASE":18} +Laideyi 7W {"NAME":"7W-E14-RGBW-La","GPIO":[0,0,0,0,38,37,0,0,39,0,40,0,0],"FLAG":0,"BASE":18} +LE lampUX A19 9.5W 806lm {"NAME":"LE lampUX 9W Bulb","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +LeCardio 10W 980lm {"NAME":"LeCardio RGBW","GPIO":[0,0,0,0,40,0,0,0,38,39,37,0,0],"FLAG":0,"BASE":18} +Linganzh LWE3 7W 800lm {"NAME":"LINGANZH Smart ","GPIO":[0,0,0,0,41,38,0,0,39,0,40,37,0],"FLAG":0,"BASE":18} +LiteMate A90 810lm {"NAME":"LiteMate 9W","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} +LOFTer 7W 450lm {"NAME":"Lofter","GPIO":[0,255,255,255,0,0,0,0,0,143,0,144,0],"FLAG":0,"BASE":27} +Lohas ZN001 810lm {"NAME":"Lohas RGBW","GPIO":[0,0,0,0,0,0,0,0,0,143,0,144,0],"FLAG":0,"BASE":18} +Lohas ZN001-E12 810lm {"NAME":"Lohas","GPIO":[0,0,0,0,0,0,0,0,0,143,0,144,0],"FLAG":0,"BASE":26} +Lohas ZN005 420lm {"NAME":"Lohas E14 R50","GPIO":[17,0,0,0,0,0,0,0,0,143,0,144,0],"FLAG":0,"BASE":27} +Lohas ZN006 1380lm {"NAME":"Lohas100 RGBW","GPIO":[0,0,0,0,0,0,0,0,0,143,0,144,0],"FLAG":0,"BASE":18} +Lohas ZN012 450lm {"NAME":"LH-5W-ZN01204","GPIO":[0,0,0,0,0,0,0,0,0,143,0,144,0],"FLAG":0,"BASE":27} +Lonsonho 900lm {"NAME":"RGB+W+C Bulb","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +LSC Smart Connect C45 400lm {"NAME":"LSC RGBCW E14","GPIO":[0,0,0,0,0,0,0,0,181,0,180,0,0],"FLAG":0,"BASE":18} +LSC Smart Connect MR16 380lm {"NAME":"LSC RGBCW GU10","GPIO":[0,0,0,0,0,0,0,0,181,0,180,0,0],"FLAG":0,"BASE":18} +Lumiman LM530 7.5W 800lm {"NAME":"Lumiman LM530","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":1,"BASE":18} +Lumiman LM530 7.5W 800lm {"NAME":"Lumiman LM530","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":1,"BASE":18} +Lumiman LM530 7.5W 800lm {"NAME":"LM530","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":1,"BASE":18} +Luminea ZX-2832 {"NAME":"Luminea RGBW","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":1,"BASE":18} +Luminea ZX-2986 1400lm {"NAME":"Luminea RGBW","GPIO":[0,0,0,0,37,41,0,0,0,38,39,40,0],"FLAG":0,"BASE":18} +LWE3 600lm {"NAME":"Linganzh LWE3 ","GPIO":[0,0,0,0,0,38,0,0,39,0,40,37,0],"FLAG":0,"BASE":18} +MagicLight 4.5W 350lm {"NAME":"4.5W RGBW Bulb","GPIO":[0,0,0,0,0,37,0,0,39,40,38,0,0],"FLAG":0,"BASE":18} +Manzoku XS-001 1050lm {"NAME":"Manzoku RGBW","GPIO":[0,0,0,0,40,0,0,0,38,39,37,0,0],"FLAG":0,"BASE":18} +Maxcio YX-L01P-E27-2P 9W {"NAME":"Maxcio YXL01P","GPIO":[17,0,0,0,143,144,0,0,0,0,0,0,0],"FLAG":0,"BASE":27} +Merkury 75W 1050lm {"NAME":"MIC-BW904-999W","GPIO":[38,0,0,0,141,140,0,0,37,142,0,0,0],"FLAG":0,"BASE":18} +Merkury A21 10W 1050lm {"NAME":"MI-BW210-999W","GPIO":[0,0,0,0,140,37,0,0,142,38,141,0,0],"FLAG":0,"BASE":48} +Merkury A21 10W 1050lm {"NAME":"MI-BW210-999W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Merkury MI-BW904-999W 1050lm {"NAME":"MI-BW904-999W","GPIO":[0,0,0,0,140,37,0,0,0,142,141,0,0],"FLAG":0,"BASE":18} +Merkury MI-BW904-999W v2 1050lm {"NAME":"MI-BW210-999W","GPIO":[0,0,0,0,38,37,0,0,141,142,140,0,0],"FLAG":0,"BASE":48} +Merkury MI-BW904-999W v3 {"NAME":"MI-BW904-999W","GPIO":[0,0,0,0,37,38,0,0,141,142,140,0,0],"FLAG":0,"BASE":69} +Merkury MI-BW906-999W BR30 750lm {"NAME":"MI-BW906-999W","GPIO":[0,0,0,0,38,37,0,0,141,142,140,0,0],"FLAG":0,"BASE":18} +Mirabella Genio 9W 800lm {"NAME":"GenioBulbRGB","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":1,"BASE":18} +Mirabella Genio 9W 800lm {"NAME":"GenioBulbRGB","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":1,"BASE":18} +Mirabella Genio 9W 800lm {"NAME":"MiraBellaGenio","GPIO":[0,0,0,0,0,0,0,0,181,0,180,0,0],"FLAG":0,"BASE":18} +Mixigoo 950lm {"NAME":"Mixigoo Bulb","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} +MoKo GU10 {"NAME":"MoKo GU10","GPIO":[255,255,255,255,39,255,255,255,38,41,37,40,255],"FLAG":15,"BASE":18} +MoKo JL81 5W 400lm {"NAME":"MoKo E14","GPIO":[0,0,0,0,0,0,0,0,143,0,144,0,0],"FLAG":0,"BASE":27} +MOKO YX-L01C-E14 A60 810lm {"NAME":"MOKO","GPIO":[17,0,0,0,143,144,0,0,0,0,0,0,0],"FLAG":0,"BASE":27} +Nedis 4.5W 380lm {"NAME":"Nedis RGBW","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} +Nedis A60 800lm {"NAME":"Nedis RGBW","GPIO":[0,0,0,0,140,37,0,0,0,142,141,0,0],"FLAG":1,"BASE":18} +Nedis C10 350lm {"NAME":"Nedis WIFILC10","GPIO":[0,0,0,0,39,37,0,0,40,38,41,0,0],"FLAG":1,"BASE":18} +Nedis PAR16 330lm {"NAME":"Nedis GU10","GPIO":[0,0,0,0,39,37,0,0,40,38,41,0,0],"FLAG":0,"BASE":18} +NiteBird TT-WB4 800lm {"NAME":"NiteBird TT-WB","GPIO":[0,0,0,0,40,0,0,0,37,38,39,0,0],"FLAG":0,"BASE":18} +Novostella UT55506 10W 1050lm {"NAME":"Novostella 10W","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Onforu 7W 700lm {"NAME":"Onforu RGBW","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Orbecco 5W 400lm {"NAME":"Orbecco Bulb","GPIO":[0,0,0,0,0,0,0,0,143,0,144,0,0],"FLAG":0,"BASE":27} +Premier A19 10W {"NAME":"Premier Light","GPIO":[0,0,0,0,0,39,0,0,38,0,37,40,0],"FLAG":1,"BASE":18} +Riversong Juno 10W {"NAME":"Juno10","GPIO":[0,0,0,0,140,37,0,0,0,142,141,0,0],"FLAG":0,"BASE":18} +Rogoei EBE-QPZ04 6.5W 450lm {"NAME":"EBE-QPZ04","GPIO":[0,0,0,0,180,0,0,0,0,0,181,0,0],"FLAG":0,"BASE":18} +Smart 810lm {"NAME":"OOOLED 60W RGB","GPIO":[0,0,0,0,39,40,0,0,37,0,38,0,0],"FLAG":1,"BASE":18} +SmartLED 9W 400lm {"NAME":"SmartLED RGBWW","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Smartyfi 600lm {"NAME":"SMARTYFI 9W","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} +Solimo 12W {"NAME":"Solimo RGBWW12","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Solimo 810lm {"NAME":"Solimo RGBWW 9","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Swisstone SH 320 350lm {"NAME":"SH 320","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} +Swisstone SH 340 806lm {"NAME":"SH 340","GPIO":[0,0,0,0,140,37,0,0,0,142,141,0,0],"FLAG":15,"BASE":18} +Syska 720lm {"NAME":"SyskaSmartBulb","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} +TCP Smart 806lm {"NAME":"TCP Smart RGBW","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} +Teckin SB50 800lm {"NAME":"Teckin SB50","GPIO":[0,0,0,0,40,0,0,0,38,39,37,0,0],"FLAG":0,"BASE":18} +Teckin SB50 v2 800lm {"NAME":"Teckin SB50","GPIO":[0,0,0,0,37,0,0,0,38,40,39,0,0],"FLAG":0,"BASE":18} +Teckin SB51 800lm {"NAME":"Teckin SB51","GPIO":[0,0,0,0,40,0,0,0,38,39,37,0,0],"FLAG":0,"BASE":18} +TikLOk TL530 A19 7.5W 800lm {"NAME":"TikLOk WW-CW-L","GPIO":[0,0,0,0,0,37,0,0,38,0,0,0,0],"FLAG":0,"BASE":18} +TVLive 7.5W 800lm {"NAME":"TVLIVE RGBCW","GPIO":[0,0,0,0,37,40,0,0,38,41,39,0,0],"FLAG":0,"BASE":18} +Utorch LE7 600lm {"NAME":"Utorch LE7","GPIO":[0,0,0,0,0,38,0,0,39,0,40,37,0],"FLAG":0,"BASE":18} +V-Tac A60 11W 1055lm {"NAME":"V-TAC LED A60 ","GPIO":[0,0,0,0,180,0,0,0,0,0,181,0,0],"FLAG":0,"BASE":18} +V-TAC A95 18W 1350lm {"NAME":"V-TAC VT-5021","GPIO":[0,0,0,0,37,41,0,0,38,40,39,0,0],"FLAG":0,"BASE":18} +Wallfire WF-05 {"NAME":"Wallfire E27","GPIO":[17,0,0,0,0,0,0,0,0,143,0,144,0],"FLAG":0,"BASE":27} +Woopower 460lm {"NAME":"Woopower E14","GPIO":[0,0,0,0,0,0,0,0,0,143,0,144,0],"FLAG":0,"BASE":27} +WOOX R4553 650lm {"NAME":"WOOX R4553","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} +WOOX R5076 4W 350lm {"NAME":"WOOX R4553","GPIO":[0,0,0,0,37,40,0,0,38,0,39,0,0],"FLAG":0,"BASE":18} +Woox R5077 {"NAME":"WOOX R5077","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} +Zemismart 5W {"NAME":"Zemismart_GU10","GPIO":[0,0,0,0,0,0,0,0,0,143,0,144,0],"FLAG":0,"BASE":27} +Zemismart A19 10W {"NAME":"Zemism_E27_A19","GPIO":[0,0,0,0,0,0,0,0,0,143,0,144,0],"FLAG":0,"BASE":27} +Zilotek A19 800lm {"NAME":"Zilotek RGBW","GPIO":[0,0,0,0,140,37,0,0,38,142,141,0,0],"FLAG":0,"BASE":18} +``` + ## Relay ``` 1 Channel Inching/Self-Locking {"NAME":"1 Channel","GPIO":[17,0,0,0,0,0,0,0,21,56,0,0,0],"FLAG":0,"BASE":12} BlitzWolf BW-SS1 {"NAME":"BW-SS1","GPIO":[255,255,255,255,157,21,0,0,255,17,255,255,0],"FLAG":0,"BASE":18} +BlitzWolf BW-SS5 2 Gang {"NAME":"BlitzWolf SS5 2 Gang","GPIO":[0,0,0,0,160,0,0,0,43,42,21,22,0],"FLAG":0,"BASE":18} +BlitzWolf SS4 Two Gang {"NAME":"BlitzWolf SS4","GPIO":[0,0,0,0,56,21,0,0,22,17,0,0,0],"FLAG":0,"BASE":18} Canwing CW-001 {"NAME":"Canwing CW-001","GPIO":[17,255,0,255,0,0,0,0,21,56,0,0,0],"FLAG":0,"BASE":1} Century Aoke Smart Switch {"NAME":"CenturyAoke","GPIO":[0,255,0,255,21,0,0,0,17,56,255,0,0],"FLAG":0,"BASE":18} Deta 6000HA Smart Inline Switch {"NAME":"DETA-6000HA","GPIO":[0,17,0,0,0,0,0,0,0,56,21,0,0],"FLAG":0,"BASE":18} +dewenwils Outdoor Timer Box {"NAME":"Dewenwils50054","GPIO":[0,0,54,0,0,0,0,0,0,17,0,21,0],"FLAG":0,"BASE":18} DoHome HomeKit DIY Switch {"NAME":"DoHome DIY","GPIO":[255,255,0,255,255,157,0,0,21,0,0,0,0],"FLAG":0,"BASE":1} Eachen ST-DC2 {"NAME":"Garage Control","GPIO":[11,0,0,0,23,22,18,0,21,52,12,24,0],"FLAG":1,"BASE":18} Eachen ST-UDC1 {"NAME":"ST-UDC1","GPIO":[9,0,0,0,0,0,0,0,21,56,0,0,0],"FLAG":1,"BASE":18} @@ -951,26 +1100,30 @@ EX Store 2 Kanal V5 {"NAME":"EXS Relay V5","GPIO":[255,255,255,255,255,255, Garage Door Controller {"NAME":"Garage Opener","GPIO":[0,107,0,108,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} Geekcreit 2 Channel AC 85V-250V {"NAME":"Geekcreit 2ch","GPIO":[17,0,0,0,0,22,18,0,21,52,0,0,0],"FLAG":1,"BASE":18} Geekcreit 5V DIY 4 Channel Jog Inching Self-Locking {"NAME":"Geekcreit-4ch","GPIO":[9,0,0,0,23,22,10,11,21,52,12,24,0],"FLAG":0,"BASE":18} -Geekcreit Module 220V 10A {"NAME":"WeMos Relay","GPIO":[17,255,52,255,21,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} +Geekcreit Module 220V 10A {"NAME":"DIY ESP8266 Re","GPIO":[0,0,157,0,21,17,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} Gocomma Wi-Fi Smart Switch {"NAME":"GoCommaSmartSw","GPIO":[17,255,255,255,21,0,0,0,255,56,0,0,0],"FLAG":0,"BASE":18} Hoch Circuit Breaker 1P {"NAME":"HOCH ZJSB9","GPIO":[17,255,255,255,255,255,0,0,21,56,0,0,0],"FLAG":0,"BASE":18} +HW-622 ESP8266 {"NAME":"HW-622","GPIO":[0,0,157,0,21,17,0,0,0,0,0,0,0],"FLAG":0,"BASE":18} L-5A01 {"NAME":"L-5A01","GPIO":[17,255,0,255,0,0,0,0,21,56,0,0,0],"FLAG":0,"BASE":1} LC Technology 5V 2 Channel {"NAME":"LC-ESP01-2R-5V","GPIO":[0,148,0,149,0,0,0,0,21,22,0,0,0],"FLAG":0,"BASE":18} LC Technology 5V 4 Channel {"NAME":"LC-Tech_4CH ","GPIO":[52,255,17,255,0,0,0,0,21,22,23,24,0],"FLAG":0,"BASE":18} LC Technology AC/DC 1 Channel ESP-12F Dev Board {"NAME":"LC-ESP12-1R-MV","GPIO":[255,255,157,255,255,21,255,255,255,255,255,255,57],"FLAG":15,"BASE":18} +LC Technology ESP8266 5V {"NAME":"ESP8266-01S","GPIO":[21,148,0,149,0,0,0,0,0,0,0,0,0],"FLAG":1,"BASE":18} LinkNode R4 {"NAME":"LinkNode R4","GPIO":[0,0,0,0,0,0,0,0,21,22,23,0,24],"FLAG":0,"BASE":18} LinkNode R8 {"NAME":"LinkNode R8","GPIO":[0,0,0,0,25,26,0,28,23,24,22,27,21],"FLAG":0,"BASE":18} +LoraTap 10A {"NAME":"LoraTap RR400W","GPIO":[0,0,0,0,157,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} LoraTap RR500W {"NAME":"LoraTap RR500W","GPIO":[157,255,255,255,9,255,255,255,255,21,255,255,56],"FLAG":15,"BASE":18} LoraTap SC500W Roller Shutter {"NAME":"SC500W","GPIO":[0,0,0,158,9,10,0,0,21,17,22,0,0],"FLAG":0,"BASE":18} Mhcozy 5V {"NAME":"Portail","GPIO":[9,0,0,0,0,0,0,0,21,56,0,0,0],"FLAG":1,"BASE":18} Moes MS-104B-1 {"NAME":"Moes MS-104B","GPIO":[0,0,17,0,160,0,0,0,43,42,21,22,0],"FLAG":0,"BASE":18} Nova Digital Basic 1 MS101 {"NAME":"NovaDigBasic1","GPIO":[0,255,0,255,56,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} +OpenEnergyMonitor WiFi MQTT Thermostat {"NAME":"MQTT-RELAY","GPIO":[17,0,255,0,0,21,0,0,0,0,0,0,56],"FLAG":0,"BASE":18} Protium PS-1604 {"NAME":"Protium16A","GPIO":[17,255,255,255,255,0,0,0,21,56,255,0,0],"FLAG":0,"BASE":1} -QS-WIFI-S03 {"NAME":"QS-WIFI-S03","GPIO":[17,255,255,255,255,0,0,0,82,21,0,0,0],"FLAG":0,"BASE":1} +QS-WIFI-S03 Module Switch {"NAME":"QS-WIFI-S03","GPIO":[17,255,255,255,255,0,0,0,82,21,0,0,0],"FLAG":0,"BASE":1} Shelly 1 {"NAME":"Shelly 1","GPIO":[0,0,0,0,21,82,0,0,0,0,0,0,0],"FLAG":0,"BASE":46} Shelly 1PM {"NAME":"Shelly 1PM","GPIO":[56,0,0,0,82,134,0,0,0,0,0,21,0],"FLAG":2,"BASE":18} Shelly 2 {"NAME":"Shelly 2","GPIO":[0,135,0,136,21,22,0,0,9,0,10,137,0],"FLAG":0,"BASE":47} -Shelly 2.5 {"NAME":"Shelly 2.5","GPIO":[56,255,17,255,21,83,0,0,6,82,5,22,156],"FLAG":2,"BASE":18} +Shelly 2.5 {"NAME":"Shelly 2.5","GPIO":[56,0,17,0,21,83,0,0,6,82,5,22,156],"FLAG":2,"BASE":18} Sinilink XY-WF36V DC6V-36V Switch Module {"NAME":"Sinilink XY-WF5V","GPIO":[0,0,0,0,21,255,0,0,17,52,0,0,255],"FLAG":0,"BASE":18} Sinilink XY-WFMS MOS Switch Module {"NAME":"Sinilink MOS","GPIO":[0,0,0,0,21,255,0,0,17,52,0,0,255],"FLAG":0,"BASE":18} Sinilink XY-WFUSB USB Switch {"NAME":"XY-WFUSB","GPIO":[255,255,0,255,17,21,0,0,0,0,56,0,157],"FLAG":0,"BASE":18} @@ -993,15 +1146,19 @@ SS311KWS RF Kinetic Switch and WiFi {"NAME":"SS311KWS","GPIO":[0,0,0,0,52,0,0,0 SW-R03 {"NAME":"SW-R03","GPIO":[0,0,0,0,0,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} WL-SW01_10 {"NAME":"WL-SW01_10","GPIO":[17,149,0,148,0,0,0,0,21,56,0,0,0],"FLAG":0,"BASE":1} Zemismart ERC309 Kinetic Switch {"NAME":"Kinetic Switch","GPIO":[255,255,255,255,255,255,0,0,255,108,255,107,255],"FLAG":0,"BASE":54} +ZMAi-90 Digital Energy Meter {"NAME":"ZMAi-90","GPIO":[0,148,0,149,0,0,0,0,21,90,0,0,0],"FLAG":0,"BASE":18} ``` ## Sensor ``` +Digoo DG-ZXD21 Door Detector {"NAME":"Digoo ZXD21","GPIO":[0,107,0,108,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} DP-WP001 PIR {"NAME":"TUYA PIR","GPIO":[255,107,255,108,255,255,0,0,255,255,255,255,255],"FLAG":0,"BASE":54} DS18B20 ESP01 Module Temperature {"NAME":"ESP01S ds18b20","GPIO":[255,255,4,255,255,255,0,0,255,255,255,255,255],"FLAG":15,"BASE":18} Earykong TYMC-1 Door Window {"NAME":"TYMC-1","GPIO":[0,107,0,108,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} IOT4SH01DS Temperature {"NAME":"IOT4SH01DS","GPIO":[255,255,255,255,255,255,0,0,255,4,255,255,255],"FLAG":15,"BASE":18} Mirabella Genio I002576 Motion {"NAME":"GenioPir","GPIO":[17,107,0,108,0,0,0,0,0,56,0,0,0],"FLAG":0,"BASE":54} +Nedis Smoke Detector {"NAME":"Nedis Smoke","GPIO":[0,107,0,108,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} +Shelly Temperature Sensor Add-on {"NAME":"Shelly 1 Temp ","GPIO":[192,0,0,4,21,82,0,0,0,0,0,0,0],"FLAG":0,"BASE":46} Sonoff SC {"NAME":"Sonoff SC","GPIO":[17,148,255,149,0,0,0,0,0,56,0,0,0],"FLAG":0,"BASE":21} Zemismart Door Window {"NAME":"Zemismart","GPIO":[255,107,255,108,255,255,0,0,255,255,255,255,255],"FLAG":0,"BASE":54} ``` @@ -1010,11 +1167,17 @@ Zemismart Door Window {"NAME":"Zemismart","GPIO":[255,107,255,108,255,255,0,0 ``` 3A Smart Home HGZB-043 {"NAME":"3A Smart Home ","GPIO":[52,0,55,18,22,19,0,0,17,21,54,23,53],"FLAG":0,"BASE":18} Aoycocr SW1 {"NAME":"Aoycocr SW1","GPIO":[158,255,57,255,255,255,255,255,56,17,255,21,255],"FLAG":15,"BASE":18} +Avatto 2 Gang {"NAME":"Avatto Wifi - ","GPIO":[0,0,52,0,0,17,0,0,21,22,0,0,18],"FLAG":0,"BASE":18} Bardi Smart Wallswitch 2 {"NAME":"BARDI 2 Gang","GPIO":[56,0,157,18,22,0,0,0,52,21,57,0,17],"FLAG":0,"BASE":18} Bardi Smart Wallswitch 3 {"NAME":"BARDI 3 Gang","GPIO":[56,57,157,19,23,18,0,0,52,21,58,22,17],"FLAG":0,"BASE":18} +BAZZ SWTCHWFW1 {"NAME":"BAZZ KS-602S","GPIO":[17,0,0,0,0,0,21,52,29,56,0,0,0],"FLAG":0,"BASE":18} +Blitzwolf BW-SS3 1 Gang {"NAME":"BW-SS3-1G-EU","GPIO":[52,0,0,17,0,0,0,0,0,21,0,0,0],"FLAG":0,"BASE":18} BlitzWolf BW-SS3 2 Gang {"NAME":"BW-SS3-2G-EU","GPIO":[157,255,255,255,22,18,255,255,17,21,255,255,255],"FLAG":15,"BASE":18} BlitzWolf BW-SS3 3 Gang {"NAME":"BlitzWolf SS3","GPIO":[158,0,0,10,22,11,0,0,9,21,0,23,0],"FLAG":0,"BASE":18} CD303 3 Gang Touch {"NAME":"Touch Switch 3","GPIO":[54,57,255,19,23,18,255,255,17,21,255,22,52],"FLAG":15,"BASE":18} +Connect Smart 2 Gang Wall {"NAME":"CSH-SWTCH2","GPIO":[0,0,52,0,0,18,0,0,22,21,0,0,17],"FLAG":0,"BASE":18} +Deta 3 Gang {"NAME":"DETA 3G Switch","GPIO":[157,0,0,92,91,21,0,0,23,0,22,0,90],"FLAG":0,"BASE":18} +Deta 4 Gang {"NAME":"Deta 4G Switch","GPIO":[157,0,0,17,18,24,0,0,21,19,22,23,20],"FLAG":0,"BASE":18} Deta 6911HA {"NAME":"Deta 1G Switch","GPIO":[0,0,0,0,157,0,0,0,0,21,0,0,90],"FLAG":0,"BASE":18} Deta 6912HA {"NAME":"DETA 2G Switch","GPIO":[0,0,0,0,157,0,0,0,91,21,22,0,90],"FLAG":0,"BASE":18} Digoo DG-S811 3 Gang {"NAME":"DIGOO Switch","GPIO":[0,0,0,0,19,18,0,0,22,21,23,0,17],"FLAG":0,"BASE":18} @@ -1027,15 +1190,21 @@ Enjowi WF-SK301 {"NAME":"Tuya 3 Channel","GPIO":[0,0,0,0,23,18,0,0,17,2 Etekcity ESWL01 {"NAME":"EtekCityESWL01","GPIO":[0,255,0,255,52,53,0,0,0,21,122,0,0],"FLAG":1,"BASE":18} Etekcity ESWL03 3-way {"NAME":"Etekcity 3Way","GPIO":[0,0,0,0,23,29,0,0,82,22,10,0,0],"FLAG":0,"BASE":18} Eva Logik WF30 3-Way {"NAME":"WF30 Switch","GPIO":[0,0,0,0,18,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} +Freecube AWS01F {"NAME":"Freecube","GPIO":[0,0,0,17,21,0,0,0,0,0,22,0,0],"FLAG":0,"BASE":18} Geeni TAP 3-Way {"NAME":"Geeni 3-Way","GPIO":[157,0,0,0,0,0,0,0,17,21,0,0,0],"FLAG":0,"BASE":18} +Girier EK01 RF433Mhz 1 Gang {"NAME":"Girier EK01","GPIO":[157,0,0,0,21,0,0,0,0,0,0,0,17],"FLAG":0,"BASE":18} +Girier EK02 RF433Mhz 2 Gang {"NAME":"Girier EK02","GPIO":[157,0,0,0,0,17,0,0,18,21,22,0,0],"FLAG":0,"BASE":18} +Girier EK03 RF433Mhz 3 Gang {"NAME":"EK03","GPIO":[157,0,0,0,22,17,0,0,19,21,23,0,18],"FLAG":0,"BASE":18} Girier JRSWR-SEU01 1 Gang {"NAME":"W601","GPIO":[0,0,0,0,0,17,0,0,0,0,0,21,157],"FLAG":15,"BASE":18} Girier JRSWR-SEU01 2 Gang {"NAME":"W602","GPIO":[0,0,0,0,22,0,0,0,17,21,18,0,157],"FLAG":15,"BASE":18} -Girier JRSWR-US01 No Neutral {"NAME":"Tuya 1 Channel","GPIO":[0,0,0,0,0,17,0,0,0,0,0,21,157],"FLAG":0,"BASE":18} +Girier JRSWR-SEU01 3 Gang {"NAME":"W603","GPIO":[0,0,0,0,23,18,0,0,17,21,19,22,157],"FLAG":15,"BASE":18} +Girier JRSWR-US01 No Neutral 1 Gang {"NAME":"Tuya 1 Channel","GPIO":[0,0,0,0,0,17,0,0,0,0,0,21,157],"FLAG":0,"BASE":18} +Girier JRSWR-US01 No Neutral 3 Gang {"NAME":"Girier JRSWR-U","GPIO":[0,0,0,0,21,18,0,0,19,23,17,22,157],"FLAG":0,"BASE":18} GoKlug Glass Touch 1 Gang {"NAME":"GoKlug 1x","GPIO":[56,57,0,0,0,9,0,0,0,0,0,21,0],"FLAG":0,"BASE":18} -Gosund KS-602S {"NAME":"Gosund KS-602S","GPIO":[17,56,0,0,0,0,0,0,0,0,21,0,158],"FLAG":0,"BASE":18} -Gosund SW1 {"NAME":"Gosund SW1","GPIO":[17,56,0,0,0,0,0,0,0,0,21,0,158],"FLAG":0,"BASE":18} -Gosund SW1 v2 {"NAME":"Gosund SW1","GPIO":[17,0,56,0,0,0,0,0,0,0,21,0,57],"FLAG":0,"BASE":18} -HBN Wall-Mounted Timer {"NAME":"HBN Time Switc","GPIO":[0,0,0,0,54,57,0,0,21,0,0,0,0],"FLAG":0,"BASE":18} +Gosund KS-602S {"NAME":"Gosund KS-602S","GPIO":[17,0,56,0,0,0,0,0,0,0,21,0,158],"FLAG":0,"BASE":18} +Gosund SW1 {"NAME":"Gosund SW1","GPIO":[17,0,56,0,0,0,0,0,0,0,21,0,57],"FLAG":0,"BASE":18} +Hama Flush-mounted {"NAME":"Hama WiFiTouch","GPIO":[157,0,0,0,0,18,0,0,17,22,0,21,0],"FLAG":0,"BASE":45} +HBN Wall-Mounted Timer {"NAME":"HBN Timer Switch","GPIO":[0,0,0,0,54,57,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} Jinvoo SM-SW101-1 {"NAME":"SM-SW101-1","GPIO":[52,0,0,18,0,0,0,0,17,21,0,0,0],"FLAG":1,"BASE":18} Jinvoo SM-SW101-2 {"NAME":"SM-SW101-2","GPIO":[52,0,0,18,22,0,0,0,17,21,0,0,0],"FLAG":1,"BASE":18} Jinvoo SM-SW101-3 {"NAME":"Jinvoo Wall Sw","GPIO":[52,0,0,18,22,19,0,0,17,21,0,23,0],"FLAG":1,"BASE":18} @@ -1044,6 +1213,7 @@ Koaanw CD302-EU-1 {"NAME":"CD302-EU-1","GPIO":[0,0,0,0,157,56,0,0,21,17,0 Koaanw CD302-EU-2 {"NAME":"CD302-EU-2","GPIO":[157,0,0,0,0,18,0,0,17,21,57,22,56],"FLAG":0,"BASE":18} Koaanw CD302-EU-3 {"NAME":"CD302-EU-3","GPIO":[158,53,0,19,23,18,0,0,17,21,54,22,52],"FLAG":0,"BASE":18} KS-601 2-way {"NAME":"2way Switch","GPIO":[255,255,158,255,255,83,0,0,22,21,255,82,255],"FLAG":0,"BASE":18} +KS-602 {"NAME":"Gosund KS-602","GPIO":[17,0,0,0,0,0,0,0,21,157,0,0,0],"FLAG":0,"BASE":18} KS-605 {"NAME":"KS-605","GPIO":[17,0,0,0,0,0,0,0,21,158,0,0,0],"FLAG":0,"BASE":18} Kuled K36 {"NAME":"KULED-B","GPIO":[9,255,255,255,255,255,21,52,29,56,255,255,255],"FLAG":0,"BASE":18} Kuled KS602S {"NAME":"KULED","GPIO":[17,255,255,255,255,255,0,0,21,56,255,255,255],"FLAG":0,"BASE":18} @@ -1053,9 +1223,10 @@ LerLink X801A-L No Neutral {"NAME":"LerLink X801-L","GPIO":[0,0,0,0,17,0,0,0,21 Lerlink X802A 2 Gang {"NAME":"Lerlink X802A","GPIO":[0,0,0,18,17,0,0,0,21,23,22,0,0],"FLAG":15,"BASE":18} LerLink X802A-L No Neutral {"NAME":"LerLink X802-L","GPIO":[0,0,0,18,17,0,0,0,21,158,22,0,0],"FLAG":15,"BASE":18} Lightstory WT02S {"NAME":"WT02S","GPIO":[0,0,0,0,57,56,0,0,21,17,0,0,0],"FLAG":0,"BASE":50} +Lonsonho 3 Gang {"NAME":"Lonsonho X803A","GPIO":[0,0,0,18,17,19,0,0,21,29,22,23,0],"FLAG":0,"BASE":18} Lonsonho SK3-01 {"NAME":"Tuya 1 Channel","GPIO":[0,0,0,0,0,17,0,0,0,0,0,21,52],"FLAG":0,"BASE":18} Lonsonho SK3-02 {"NAME":"Tuya 2 Channel","GPIO":[0,0,0,0,22,0,0,0,17,21,18,0,52],"FLAG":0,"BASE":18} -Lonsonho SK3-03 {"NAME":"ID Components","GPIO":[0,0,0,0,21,18,0,0,19,23,17,22,157],"FLAG":0,"BASE":18} +Lonsonho SK3-03 {"NAME":"Tuya 3-ch v2","GPIO":[157,58,0,18,22,19,0,0,17,21,57,23,56],"FLAG":0,"BASE":18} LoraTap WH100W-US 20A {"NAME":"LoraTap Boiler","GPIO":[0,0,0,0,0,0,0,0,17,21,0,0,56],"FLAG":0,"BASE":18} Luminea LHC-101.on {"NAME":"LHC-101.on","GPIO":[157,0,0,17,21,0,0,0,0,0,52,0,0],"FLAG":0,"BASE":18} Luminea LHC-102.on {"NAME":"LHC-102.on","GPIO":[157,0,53,0,0,18,0,0,17,21,0,22,52],"FLAG":0,"BASE":18} @@ -1069,23 +1240,30 @@ Minitiger 1 Gang {"NAME":"minitiger 1 Gang","GPIO":[17,255,255,255,0,0,0 Minitiger 1 Gang v2 {"NAME":"MiniTiger1Band","GPIO":[0,56,0,0,0,17,0,0,21,0,0,0,0],"FLAG":0,"BASE":18} Minitiger 2 Gang {"NAME":"minitiger 2 Gang","GPIO":[17,255,255,255,0,22,18,0,21,56,0,0,0],"FLAG":0,"BASE":28} Minitiger 2 Gang v2 {"NAME":"Minitiger2Band","GPIO":[0,0,0,17,18,0,0,0,0,21,22,0,0],"FLAG":0,"BASE":18} +Minitiger 3 Gang {"NAME":"Minitiger3gang","GPIO":[0,0,0,9,11,10,255,255,22,21,23,0,0],"FLAG":0,"BASE":18} Moes BS-US-W Boiler {"NAME":"BS-US-W","GPIO":[54,0,0,17,21,0,0,0,0,0,52,0,55],"FLAG":0,"BASE":18} Moes SS01-1 3-Way {"NAME":"Moes 3-Way","GPIO":[255,255,255,255,21,57,0,0,30,10,9,255,255],"FLAG":0,"BASE":18} Moes SS01S-1 {"NAME":"Moes Switch","GPIO":[255,255,255,255,56,0,0,0,21,17,255,255,255],"FLAG":0,"BASE":18} -Moes SS86-01 AI {"NAME":"SS86-AI 1 Gang","GPIO":[157,0,0,17,21,0,0,0,0,0,52,0,0],"FLAG":0,"BASE":18} +Moes WF-FL01 Light and Fan {"NAME":"Moes WF-FL01","GPIO":[0,107,0,108,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} Moes WS-EU1-LB 1 Gang No Neutral {"NAME":"Moes WS-EU1-LB","GPIO":[0,0,0,0,0,17,0,0,0,0,0,21,157],"FLAG":0,"BASE":18} Moes WS-EU2-LW 2 Gang No Neutral {"NAME":"Tuya 2 Channel","GPIO":[0,0,0,0,22,0,0,0,17,21,18,0,157],"FLAG":0,"BASE":18} Moes WS-EU3-LW 3 Gang No Neutral {"NAME":"Tuya 3 Channel","GPIO":[0,0,0,0,21,19,0,0,18,22,17,23,157],"FLAG":0,"BASE":18} -Moes WS-EUY3-W {"NAME":"WS-EUY3-W","GPIO":[157,0,58,18,22,19,0,0,17,21,57,23,56],"FLAG":0,"BASE":18} +Moes WS-EUY1 1 Gang {"NAME":"WS-EUY1-W","GPIO":[157,0,0,17,21,0,0,0,0,0,52,0,0],"FLAG":0,"BASE":18} +Moes WS-EUY2 2 Gang {"NAME":"WS-EUY2-W","GPIO":[157,0,53,0,0,18,0,0,17,21,0,22,52],"FLAG":0,"BASE":18} +Moes WS-EUY3 3 Gang {"NAME":"WS-EUY3-W","GPIO":[157,0,58,18,22,19,0,0,17,21,57,23,56],"FLAG":0,"BASE":18} Moes WS-US1-W 1 Gang {"NAME":"WS-US1-W","GPIO":[54,0,0,17,21,0,0,0,0,0,52,0,55],"FLAG":0,"BASE":18} Moes WS-US2-W 2 Gang {"NAME":"WS-US2-W ","GPIO":[52,0,53,0,0,18,0,0,17,21,0,22,54],"FLAG":0,"BASE":18} -Moes WS-US3-W 3 Gang {"NAME":"Tuya Moes 3 Ch","GPIO":[27,255,26,18,22,19,0,0,17,21,25,23,24],"FLAG":0,"BASE":18} +Moes WS-US3-W 3 Gang {"NAME":"Tuya Moes 3 Ch","GPIO":[157,0,54,18,22,19,0,0,17,21,53,23,52],"FLAG":0,"BASE":18} Moes WT02S {"NAME":"Moes WT02S","GPIO":[0,0,0,0,56,158,0,0,21,9,0,0,0],"FLAG":15,"BASE":18} +MoesHouse RF433 3 Gang {"NAME":"WS-EUB3-WR","GPIO":[0,107,0,108,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54} +MoKo Scene Life {"NAME":"Moko Smart Swi","GPIO":[158,0,0,0,39,38,0,0,56,0,37,21,0],"FLAG":0,"BASE":18} MoKo Smart Life {"NAME":"Moko Switch","GPIO":[0,0,0,17,21,134,0,0,0,0,0,0,0],"FLAG":0,"BASE":59} NaamaSmart KS602 {"NAME":"KS-602","GPIO":[17,0,0,0,0,0,0,0,21,158,0,0,0],"FLAG":0,"BASE":18} +Nedis Dual {"NAME":"SM-SW102U-2","GPIO":[158,0,0,18,22,0,0,0,17,21,0,0,0],"FLAG":1,"BASE":18} Nexete DS-123 {"NAME":"DS-123","GPIO":[157,57,255,17,21,18,0,0,255,22,56,255,255],"FLAG":0,"BASE":18} Nexete DS-123 Single {"NAME":"DS-123","GPIO":[157,0,255,18,0,17,0,0,255,21,56,255,255],"FLAG":0,"BASE":18} Sainko 1-Way {"NAME":"SAINKO 1CH","GPIO":[17,255,255,255,0,0,0,0,21,56,0,0,0],"FLAG":0,"BASE":28} +Sainko 2 Way {"NAME":"Sainko 2-Way","GPIO":[0,255,56,0,0,17,0,0,21,22,0,0,18],"FLAG":0,"BASE":18} SANA SASW-03 {"NAME":"SANA SASW-03","GPIO":[54,0,0,19,23,18,0,0,17,21,0,22,0],"FLAG":0,"BASE":18} SANA SW02-02 {"NAME":"SW02-02","GPIO":[31,255,255,18,22,0,0,0,17,21,255,0,255],"FLAG":0,"BASE":18} SANA SW02-03 {"NAME":"SW02-03","GPIO":[56,255,255,19,23,18,0,0,17,21,255,22,255],"FLAG":0,"BASE":18} @@ -1096,6 +1274,7 @@ Sesoo WIFI-EU-SK3-02 {"NAME":"Sesoo SK3-02","GPIO":[0,0,57,0,22,0,0,0,17,21, Sesoo WIFI-US-SK3-04 {"NAME":"Tuya 4 Channel","GPIO":[52,255,255,19,23,17,0,0,20,24,22,21,18],"FLAG":0,"BASE":18} Smartlife Opard CD302 {"NAME":"CD302","GPIO":[0,0,0,0,52,57,0,0,29,17,0,0,0],"FLAG":0,"BASE":18} SmartPlex 3 Gang {"NAME":"Tuya 3 Channel","GPIO":[255,255,255,255,21,18,0,0,19,23,17,22,255],"FLAG":0,"BASE":18} +Sonoff IW101 {"NAME":"Sonoff IW100","GPIO":[17,145,0,146,0,0,0,0,21,157,0,0,0],"FLAG":0,"BASE":41} Sonoff T1 EU 1 Gang {"NAME":"Sonoff T1 1CH","GPIO":[17,255,255,255,0,0,0,0,21,56,0,0,0],"FLAG":0,"BASE":28} Sonoff T1 EU 2 Gang {"NAME":"Sonoff T1 2CH","GPIO":[17,255,255,255,0,22,18,0,21,56,0,0,0],"FLAG":0,"BASE":29} Sonoff T1 UK 1 Gang {"NAME":"Sonoff T1 1CH","GPIO":[17,255,255,255,0,0,0,0,21,56,0,0,0],"FLAG":0,"BASE":28} @@ -1104,30 +1283,37 @@ Sonoff T1 UK 3 Gang {"NAME":"Sonoff T1 3CH","GPIO":[17,255,255,255,23,22,18 Sonoff T1 US 1 Gang {"NAME":"Sonoff T1 1CH","GPIO":[17,255,255,255,0,0,0,0,21,56,0,0,0],"FLAG":0,"BASE":28} Sonoff T1 US 2 Gang {"NAME":"Sonoff T1 2CH","GPIO":[17,255,255,255,0,22,18,0,21,56,0,0,0],"FLAG":0,"BASE":29} Sonoff T1 US 3 Gang {"NAME":"Sonoff T1 3CH","GPIO":[17,255,255,255,23,22,18,19,21,56,0,0,0],"FLAG":0,"BASE":30} -Sonoff Touch EU {"NAME":"Sonoff Touch","GPIO":[17,255,0,255,0,0,0,0,21,56,0,0,0],"FLAG":0,"BASE":10} -Sonoff Touch US {"NAME":"Sonoff Touch","GPIO":[17,255,0,255,0,0,0,0,21,56,0,0,0],"FLAG":0,"BASE":10} +Sonoff Touch {"NAME":"Sonoff Touch","GPIO":[17,255,0,255,0,0,0,0,21,56,0,0,0],"FLAG":0,"BASE":10} +Sonoff Touch {"NAME":"Sonoff Touch","GPIO":[17,255,0,255,0,0,0,0,21,56,0,0,0],"FLAG":0,"BASE":10} Sonoff TX T3 3 Gang {"NAME":"TX T3EU3C","GPIO":[17,255,0,255,23,22,18,19,21,158,0,0,0],"FLAG":0,"BASE":30} +SPC Hera {"NAME":"SPC HERA","GPIO":[157,0,0,17,21,0,0,0,0,0,52,0,0],"FLAG":0,"BASE":18} +SRL 3-4WW 4 Gang {"NAME":"SRL 4WW Switch","GPIO":[0,0,0,19,23,18,0,0,17,21,24,22,20],"FLAG":0,"BASE":18} SS118-01K1 {"NAME":"SS118-01K1","GPIO":[255,255,255,17,21,255,0,0,255,255,56,255,255],"FLAG":0,"BASE":18} SS86-AI 3-Gang {"NAME":"SS86-AI 3 Gang","GPIO":[157,0,58,18,22,19,0,0,17,21,57,23,56],"FLAG":0,"BASE":18} SSMS118-01A1 Scene Light Smart {"NAME":"RGB Switch","GPIO":[30,0,32,10,39,38,0,0,31,9,37,21,0],"FLAG":0,"BASE":18} STITCH by Monoprice 35557 {"NAME":"Tuya WF15S ","GPIO":[255,255,0,0,255,255,0,0,255,108,255,107,0],"FLAG":0,"BASE":54} +Teckin SR43 {"NAME":"Teckin SR43","GPIO":[0,0,52,0,0,17,0,0,21,22,0,0,18],"FLAG":0,"BASE":18} Teekar 10 Way 1 Gang {"NAME":"Teekar 10way","GPIO":[9,10,11,20,13,14,0,0,15,16,0,0,0],"FLAG":0,"BASE":18} Teekar Wi-Fi Light 1 Gang {"NAME":"TeeKar Touch","GPIO":[0,0,255,0,255,21,0,0,0,255,17,0,255],"FLAG":0,"BASE":18} Teepao Smart-Rollladen-Schalter {"NAME":"Teepao","GPIO":[158,58,23,18,22,19,0,0,56,21,57,0,17],"FLAG":0,"BASE":18} Tonbux AMZ180648-2 {"NAME":"Tonbux","GPIO":[17,255,255,255,255,0,0,0,21,56,255,0,0],"FLAG":0,"BASE":1} Touch 2 Gang {"NAME":"tuya_2_gang","GPIO":[52,0,0,0,18,0,0,0,17,21,255,22,29],"FLAG":0,"BASE":18} +Touch 3 Gang {"NAME":"Switch 3-Gang","GPIO":[0,0,0,0,23,18,0,0,17,21,19,22,157],"FLAG":0,"BASE":18} TreatLife SS01S {"NAME":"TL SS01S Swtch","GPIO":[0,0,0,0,52,158,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} TreatLife SS02 3-Way {"NAME":"TreatLife 3Way","GPIO":[0,0,0,0,53,29,0,0,30,18,9,0,0],"FLAG":0,"BASE":18} TreatLife SS02S {"NAME":"Treatlife SS02","GPIO":[0,0,0,0,53,0,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} +TY-US-L1-W {"NAME":"TY-US-L1-W","GPIO":[0,0,0,0,0,17,0,0,0,21,0,0,158],"FLAG":0,"BASE":18} +TY-US-L3-W {"NAME":"TY-US-L3-W","GPIO":[0,0,0,0,21,18,0,0,19,23,17,22,158],"FLAG":15,"BASE":18} Vaticas 1 {"NAME":"Vaticas","GPIO":[0,0,0,17,21,0,0,0,0,0,52,0,0],"FLAG":0,"BASE":18} +vhome RF433 3 Gang {"NAME":"VH-TB-US-003","GPIO":[0,0,0,0,21,18,0,0,19,23,17,22,158],"FLAG":15,"BASE":18} WiFi Smart Switch 2 Gang {"NAME":"Kingart N2","GPIO":[17,255,0,255,0,22,18,0,21,0,0,0,0],"FLAG":15,"BASE":18} WiFi Smart Switch 3 Gang {"NAME":"KingArt-3CH","GPIO":[17,255,0,255,23,22,18,19,21,52,0,0,0],"FLAG":15,"BASE":18} WS-US-03 {"NAME":"WS-US-03","GPIO":[17,255,255,255,23,22,18,19,21,56,0,0,0],"FLAG":0,"BASE":30} Xenon SM-SW102U 2 Gang {"NAME":"SM-SW102U-2","GPIO":[52,0,0,18,22,0,0,0,17,21,0,0,0],"FLAG":1,"BASE":18} Xenon SM-SW202 {"NAME":"SM-SW202","GPIO":[0,0,0,17,21,0,0,0,0,0,52,0,0],"FLAG":0,"BASE":18} Yapmor 1-gang {"NAME":"YAPMOR 1CH","GPIO":[17,255,255,255,0,0,0,0,21,56,0,0,0],"FLAG":0,"BASE":28} -Youngzuth 3in1 {"NAME":"SW02 3W","GPIO":[52,0,255,19,23,18,0,0,17,21,255,22,255],"FLAG":0,"BASE":18} -Youngzuth SW02 2-way {"NAME":"SW02 2W","GPIO":[52,255,255,9,21,255,0,0,10,22,255,255,255],"FLAG":0,"BASE":18} +Youngzuth 2in1 {"NAME":"SW02 2W","GPIO":[52,0,0,9,21,0,0,0,10,22,0,0,0],"FLAG":0,"BASE":18} +Youngzuth 3in1 {"NAME":"SW02 3W","GPIO":[56,0,0,19,23,18,0,0,17,21,0,22,0],"FLAG":0,"BASE":18} Zemismart KS-611 3 Gang {"NAME":"Zemismart 3 Ga","GPIO":[0,0,56,0,19,18,0,0,22,21,23,0,17],"FLAG":0,"BASE":18} Zemismart KS-811 1 Gang {"NAME":"KS-811 Single","GPIO":[17,0,0,0,0,0,0,0,21,56,0,0,0],"FLAG":0,"BASE":18} Zemismart KS-811 2 Gang {"NAME":"KS-811 Dual","GPIO":[0,0,52,0,0,18,0,0,22,21,0,0,17],"FLAG":0,"BASE":18} @@ -1137,6 +1323,8 @@ Zemismart WF-BS01 {"NAME":"WF-BS01","GPIO":[53,0,0,17,21,0,0,0,0,0,52,0,0 Zemismart ZM-L01E {"NAME":"ZSmart ZM-L01E","GPIO":[255,255,255,255,255,255,0,0,255,21,255,255,17],"FLAG":0,"BASE":18} Zemismart ZM-L02E {"NAME":"ZSmart ZM-L02E","GPIO":[255,255,255,255,255,17,0,0,18,21,22,255,255],"FLAG":0,"BASE":18} Zemismart ZM-L03E {"NAME":"ZSmart ZM-L03E","GPIO":[52,53,0,0,23,17,0,0,19,21,22,0,18],"FLAG":0,"BASE":18} +ZUCZUG 2 Gang {"NAME":"2ph105626a x2","GPIO":[0,52,0,17,18,0,0,0,0,21,22,0,0],"FLAG":0,"BASE":1} +ZUCZUG 3 Gang {"NAME":"2ph105626a x3","GPIO":[0,52,0,17,19,18,0,0,22,21,23,0,0],"FLAG":0,"BASE":1} ``` ## Valve @@ -1146,12 +1334,13 @@ Hoenyzy DN20 3/4 {"NAME":"DN20 Valve","GPIO":[0,0,0,0,0,0,0,0,17,21,0,0, Jinvoo SM-AW713 {"NAME":"Jinvoo Valve","GPIO":[0,0,0,0,0,52,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} Jinvoo SM-AW713 v2 {"NAME":"Jinvoo Valve v2","GPIO":[0,0,0,0,52,53,0,0,21,17,0,0,0],"FLAG":0,"BASE":1} Jinvoo SM-PW713 {"NAME":"Jinvoo Valve","GPIO":[0,0,0,0,21,52,0,0,17,53,0,0,0],"FLAG":1,"BASE":18} +Owfeel EN71 {"NAME":"SmartValve","GPIO":[21,0,0,0,0,0,0,0,17,52,0,0,0],"FLAG":0,"BASE":18} ``` ## Wall Outlet ``` -Bestten LO-2-W v2 {"NAME":"BESTTEN LO-2-W","GPIO":[0,0,0,0,158,17,0,0,21,0,0,0,0],"FLAG":0,"BASE":18} -Bestten LO-2-W2 {"NAME":"BESTTEN LO-2-W","GPIO":[17,0,0,0,57,0,0,0,21,56,0,0,0],"FLAG":0,"BASE":1} +Aseer THWFS01 {"NAME":"ASEER-THWFS01","GPIO":[56,18,157,59,134,132,0,0,131,22,57,21,17],"FLAG":0,"BASE":18} +Bestten LO-2-W {"NAME":"BESTTEN LO-2-W","GPIO":[0,0,0,0,158,17,0,0,21,0,0,0,0],"FLAG":0,"BASE":18} BlitzWolf BW-SHP8 {"NAME":"SHP8","GPIO":[0,56,0,17,134,132,0,0,131,53,21,0,0],"FLAG":0,"BASE":64} BSEED Smart Socket / WIFI {"NAME":"BSEED Socket","GPIO":[0,0,0,0,157,52,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} CE Smart Home LA-2-W3 {"NAME":"CE Smart Wall","GPIO":[255,255,255,255,157,17,0,0,21,255,255,255,255],"FLAG":15,"BASE":18} @@ -1172,7 +1361,7 @@ PS-1607 {"NAME":"PS-1607","GPIO":[17,0,0,0,0,22,18,0,21,0,0,0,0 Smanergy KA10 {"NAME":"KA10","GPIO":[0,56,0,17,134,132,0,0,131,53,21,0,0],"FLAG":0,"BASE":64} Sonoff IW100 {"NAME":"Sonoff IW100","GPIO":[17,145,0,146,0,0,0,0,21,157,0,0,0],"FLAG":0,"BASE":41} Sonoff S55 {"NAME":"Sonoff S55","GPIO":[17,255,0,255,255,0,0,0,21,56,0,0,0],"FLAG":0,"BASE":1} -Teckin RF-SR40-US {"NAME":"RF-SR40-US","GPIO":[0,0,0,0,57,56,0,0,21,17,0,0,0],"FLAG":0,"BASE":18} +Teckin SR40 {"NAME":"RF-SR40-US","GPIO":[158,0,0,17,56,18,0,0,22,21,57,23,0],"FLAG":0,"BASE":18} TopGreener TGWF15RM {"NAME":"TGWF15RM","GPIO":[0,56,0,17,134,132,0,0,131,57,21,0,0],"FLAG":0,"BASE":55} Vigica VGSPK00815 {"NAME":"VIGICA outlet","GPIO":[17,255,255,255,255,22,18,255,21,255,255,255,255],"FLAG":1,"BASE":18} -``` \ No newline at end of file +``` diff --git a/arduino/version 2.6.3/boards.txt b/arduino/version 2.7.1/boards.txt similarity index 96% rename from arduino/version 2.6.3/boards.txt rename to arduino/version 2.7.1/boards.txt index 3fbb48f33..0f2dc2559 100644 --- a/arduino/version 2.6.3/boards.txt +++ b/arduino/version 2.7.1/boards.txt @@ -6,10 +6,10 @@ menu.BoardModel=Model menu.ESPModule=Module +menu.led=Builtin Led menu.UploadTool=Upload Using -menu.led=Builtin Led menu.baud=Upload Speed menu.xtal=CPU Frequency menu.CrystalFreq=Crystal Frequency @@ -635,6 +635,63 @@ esp8285.menu.eesz.1M.build.flash_ld=eagle.flash.1m.ld esp8285.menu.eesz.1M.build.spiffs_pagesize=256 esp8285.menu.eesz.1M.upload.maximum_size=1023984 esp8285.menu.eesz.1M.build.rfcal_addr=0xFC000 +esp8285.menu.eesz.2M64=2MB (FS:64KB OTA:~992KB) +esp8285.menu.eesz.2M64.build.flash_size=2M +esp8285.menu.eesz.2M64.build.flash_size_bytes=0x200000 +esp8285.menu.eesz.2M64.build.flash_ld=eagle.flash.2m64.ld +esp8285.menu.eesz.2M64.build.spiffs_pagesize=256 +esp8285.menu.eesz.2M64.upload.maximum_size=1044464 +esp8285.menu.eesz.2M64.build.rfcal_addr=0x1FC000 +esp8285.menu.eesz.2M64.build.spiffs_start=0x1F0000 +esp8285.menu.eesz.2M64.build.spiffs_end=0x1FB000 +esp8285.menu.eesz.2M64.build.spiffs_blocksize=4096 +esp8285.menu.eesz.2M128=2MB (FS:128KB OTA:~960KB) +esp8285.menu.eesz.2M128.build.flash_size=2M +esp8285.menu.eesz.2M128.build.flash_size_bytes=0x200000 +esp8285.menu.eesz.2M128.build.flash_ld=eagle.flash.2m128.ld +esp8285.menu.eesz.2M128.build.spiffs_pagesize=256 +esp8285.menu.eesz.2M128.upload.maximum_size=1044464 +esp8285.menu.eesz.2M128.build.rfcal_addr=0x1FC000 +esp8285.menu.eesz.2M128.build.spiffs_start=0x1E0000 +esp8285.menu.eesz.2M128.build.spiffs_end=0x1FB000 +esp8285.menu.eesz.2M128.build.spiffs_blocksize=4096 +esp8285.menu.eesz.2M256=2MB (FS:256KB OTA:~896KB) +esp8285.menu.eesz.2M256.build.flash_size=2M +esp8285.menu.eesz.2M256.build.flash_size_bytes=0x200000 +esp8285.menu.eesz.2M256.build.flash_ld=eagle.flash.2m256.ld +esp8285.menu.eesz.2M256.build.spiffs_pagesize=256 +esp8285.menu.eesz.2M256.upload.maximum_size=1044464 +esp8285.menu.eesz.2M256.build.rfcal_addr=0x1FC000 +esp8285.menu.eesz.2M256.build.spiffs_start=0x1C0000 +esp8285.menu.eesz.2M256.build.spiffs_end=0x1FB000 +esp8285.menu.eesz.2M256.build.spiffs_blocksize=4096 +esp8285.menu.eesz.2M512=2MB (FS:512KB OTA:~768KB) +esp8285.menu.eesz.2M512.build.flash_size=2M +esp8285.menu.eesz.2M512.build.flash_size_bytes=0x200000 +esp8285.menu.eesz.2M512.build.flash_ld=eagle.flash.2m512.ld +esp8285.menu.eesz.2M512.build.spiffs_pagesize=256 +esp8285.menu.eesz.2M512.upload.maximum_size=1044464 +esp8285.menu.eesz.2M512.build.rfcal_addr=0x1FC000 +esp8285.menu.eesz.2M512.build.spiffs_start=0x180000 +esp8285.menu.eesz.2M512.build.spiffs_end=0x1FA000 +esp8285.menu.eesz.2M512.build.spiffs_blocksize=8192 +esp8285.menu.eesz.2M1M=2MB (FS:1MB OTA:~512KB) +esp8285.menu.eesz.2M1M.build.flash_size=2M +esp8285.menu.eesz.2M1M.build.flash_size_bytes=0x200000 +esp8285.menu.eesz.2M1M.build.flash_ld=eagle.flash.2m1m.ld +esp8285.menu.eesz.2M1M.build.spiffs_pagesize=256 +esp8285.menu.eesz.2M1M.upload.maximum_size=1044464 +esp8285.menu.eesz.2M1M.build.rfcal_addr=0x1FC000 +esp8285.menu.eesz.2M1M.build.spiffs_start=0x100000 +esp8285.menu.eesz.2M1M.build.spiffs_end=0x1FA000 +esp8285.menu.eesz.2M1M.build.spiffs_blocksize=8192 +esp8285.menu.eesz.2M=2MB (FS:none OTA:~1019KB) +esp8285.menu.eesz.2M.build.flash_size=2M +esp8285.menu.eesz.2M.build.flash_size_bytes=0x200000 +esp8285.menu.eesz.2M.build.flash_ld=eagle.flash.2m.ld +esp8285.menu.eesz.2M.build.spiffs_pagesize=256 +esp8285.menu.eesz.2M.upload.maximum_size=1044464 +esp8285.menu.eesz.2M.build.rfcal_addr=0x1FC000 esp8285.menu.led.2=2 esp8285.menu.led.2.build.led=-DLED_BUILTIN=2 esp8285.menu.led.0=0 @@ -4913,7 +4970,7 @@ espinotee.menu.baud.3000000.upload.speed=3000000 wifinfo.name=WifInfo wifinfo.build.board=WIFINFO wifinfo.build.variant=wifinfo -wifinfo.menu.ESPModule.ESP07192=ESP07 (1M/192K SPIFFS) +wifinfo.menu.ESPModule.ESP07192=ESP07 (1M/192K FS) wifinfo.menu.ESPModule.ESP07192.build.board=ESP8266_ESP07 wifinfo.menu.ESPModule.ESP07192.build.flash_ld=eagle.flash.1m192.ld wifinfo.menu.ESPModule.ESP07192.build.flash_size=1M @@ -4921,7 +4978,7 @@ wifinfo.menu.ESPModule.ESP07192.build.spiffs_blocksize=4096 wifinfo.menu.ESPModule.ESP07192.build.spiffs_end=0xFB000 wifinfo.menu.ESPModule.ESP07192.build.spiffs_start=0xCB000 wifinfo.menu.ESPModule.ESP07192.upload.maximum_size=827376 -wifinfo.menu.ESPModule.ESP12=ESP12 (4M/1M SPIFFS) +wifinfo.menu.ESPModule.ESP12=ESP12 (4M/1M FS) wifinfo.menu.ESPModule.ESP12.build.board=ESP8266_ESP12 wifinfo.menu.ESPModule.ESP12.build.flash_ld=eagle.flash.4m1m.ld wifinfo.menu.ESPModule.ESP12.build.flash_size=4M @@ -6645,20 +6702,213 @@ espectro.menu.baud.921600.upload.speed=921600 espectro.menu.baud.3000000=3000000 espectro.menu.baud.3000000.upload.speed=3000000 +############################################################## +eduinowifi.name=Schirmilabs Eduino WiFi +eduinowifi.build.board=ESP8266_SCHIRMILABS_EDUINO_WIFI +eduinowifi.build.variant=eduinowifi +eduinowifi.upload.tool=esptool +eduinowifi.upload.maximum_data_size=81920 +eduinowifi.upload.wait_for_upload_port=true +eduinowifi.upload.erase_cmd= +eduinowifi.serial.disableDTR=true +eduinowifi.serial.disableRTS=true +eduinowifi.build.mcu=esp8266 +eduinowifi.build.core=esp8266 +eduinowifi.build.spiffs_pagesize=256 +eduinowifi.build.debug_port= +eduinowifi.build.debug_level= +eduinowifi.menu.xtal.80=80 MHz +eduinowifi.menu.xtal.80.build.f_cpu=80000000L +eduinowifi.menu.xtal.160=160 MHz +eduinowifi.menu.xtal.160.build.f_cpu=160000000L +eduinowifi.menu.vt.flash=Flash +eduinowifi.menu.vt.flash.build.vtable_flags=-DVTABLES_IN_FLASH +eduinowifi.menu.vt.heap=Heap +eduinowifi.menu.vt.heap.build.vtable_flags=-DVTABLES_IN_DRAM +eduinowifi.menu.vt.iram=IRAM +eduinowifi.menu.vt.iram.build.vtable_flags=-DVTABLES_IN_IRAM +eduinowifi.menu.exception.legacy=Legacy (new can return nullptr) +eduinowifi.menu.exception.legacy.build.exception_flags=-fno-exceptions +eduinowifi.menu.exception.legacy.build.stdcpp_lib=-lstdc++ +eduinowifi.menu.exception.disabled=Disabled (new can abort) +eduinowifi.menu.exception.disabled.build.exception_flags=-fno-exceptions -DNEW_OOM_ABORT +eduinowifi.menu.exception.disabled.build.stdcpp_lib=-lstdc++ +eduinowifi.menu.exception.enabled=Enabled +eduinowifi.menu.exception.enabled.build.exception_flags=-fexceptions +eduinowifi.menu.exception.enabled.build.stdcpp_lib=-lstdc++-exc +eduinowifi.menu.ssl.all=All SSL ciphers (most compatible) +eduinowifi.menu.ssl.all.build.sslflags= +eduinowifi.menu.ssl.basic=Basic SSL ciphers (lower ROM use) +eduinowifi.menu.ssl.basic.build.sslflags=-DBEARSSL_SSL_BASIC +eduinowifi.upload.resetmethod=--before default_reset --after hard_reset +eduinowifi.build.flash_mode=dio +eduinowifi.build.flash_flags=-DFLASHMODE_DIO +eduinowifi.build.flash_freq=40 +eduinowifi.menu.eesz.4M2M=4MB (FS:2MB OTA:~1019KB) +eduinowifi.menu.eesz.4M2M.build.flash_size=4M +eduinowifi.menu.eesz.4M2M.build.flash_size_bytes=0x400000 +eduinowifi.menu.eesz.4M2M.build.flash_ld=eagle.flash.4m2m.ld +eduinowifi.menu.eesz.4M2M.build.spiffs_pagesize=256 +eduinowifi.menu.eesz.4M2M.upload.maximum_size=1044464 +eduinowifi.menu.eesz.4M2M.build.rfcal_addr=0x3FC000 +eduinowifi.menu.eesz.4M2M.build.spiffs_start=0x200000 +eduinowifi.menu.eesz.4M2M.build.spiffs_end=0x3FA000 +eduinowifi.menu.eesz.4M2M.build.spiffs_blocksize=8192 +eduinowifi.menu.eesz.4M3M=4MB (FS:3MB OTA:~512KB) +eduinowifi.menu.eesz.4M3M.build.flash_size=4M +eduinowifi.menu.eesz.4M3M.build.flash_size_bytes=0x400000 +eduinowifi.menu.eesz.4M3M.build.flash_ld=eagle.flash.4m3m.ld +eduinowifi.menu.eesz.4M3M.build.spiffs_pagesize=256 +eduinowifi.menu.eesz.4M3M.upload.maximum_size=1044464 +eduinowifi.menu.eesz.4M3M.build.rfcal_addr=0x3FC000 +eduinowifi.menu.eesz.4M3M.build.spiffs_start=0x100000 +eduinowifi.menu.eesz.4M3M.build.spiffs_end=0x3FA000 +eduinowifi.menu.eesz.4M3M.build.spiffs_blocksize=8192 +eduinowifi.menu.eesz.4M1M=4MB (FS:1MB OTA:~1019KB) +eduinowifi.menu.eesz.4M1M.build.flash_size=4M +eduinowifi.menu.eesz.4M1M.build.flash_size_bytes=0x400000 +eduinowifi.menu.eesz.4M1M.build.flash_ld=eagle.flash.4m1m.ld +eduinowifi.menu.eesz.4M1M.build.spiffs_pagesize=256 +eduinowifi.menu.eesz.4M1M.upload.maximum_size=1044464 +eduinowifi.menu.eesz.4M1M.build.rfcal_addr=0x3FC000 +eduinowifi.menu.eesz.4M1M.build.spiffs_start=0x300000 +eduinowifi.menu.eesz.4M1M.build.spiffs_end=0x3FA000 +eduinowifi.menu.eesz.4M1M.build.spiffs_blocksize=8192 +eduinowifi.menu.eesz.4M=4MB (FS:none OTA:~1019KB) +eduinowifi.menu.eesz.4M.build.flash_size=4M +eduinowifi.menu.eesz.4M.build.flash_size_bytes=0x400000 +eduinowifi.menu.eesz.4M.build.flash_ld=eagle.flash.4m.ld +eduinowifi.menu.eesz.4M.build.spiffs_pagesize=256 +eduinowifi.menu.eesz.4M.upload.maximum_size=1044464 +eduinowifi.menu.eesz.4M.build.rfcal_addr=0x3FC000 +eduinowifi.menu.ip.lm2f=v2 Lower Memory +eduinowifi.menu.ip.lm2f.build.lwip_include=lwip2/include +eduinowifi.menu.ip.lm2f.build.lwip_lib=-llwip2-536-feat +eduinowifi.menu.ip.lm2f.build.lwip_flags=-DLWIP_OPEN_SRC -DTCP_MSS=536 -DLWIP_FEATURES=1 -DLWIP_IPV6=0 +eduinowifi.menu.ip.hb2f=v2 Higher Bandwidth +eduinowifi.menu.ip.hb2f.build.lwip_include=lwip2/include +eduinowifi.menu.ip.hb2f.build.lwip_lib=-llwip2-1460-feat +eduinowifi.menu.ip.hb2f.build.lwip_flags=-DLWIP_OPEN_SRC -DTCP_MSS=1460 -DLWIP_FEATURES=1 -DLWIP_IPV6=0 +eduinowifi.menu.ip.lm2n=v2 Lower Memory (no features) +eduinowifi.menu.ip.lm2n.build.lwip_include=lwip2/include +eduinowifi.menu.ip.lm2n.build.lwip_lib=-llwip2-536 +eduinowifi.menu.ip.lm2n.build.lwip_flags=-DLWIP_OPEN_SRC -DTCP_MSS=536 -DLWIP_FEATURES=0 -DLWIP_IPV6=0 +eduinowifi.menu.ip.hb2n=v2 Higher Bandwidth (no features) +eduinowifi.menu.ip.hb2n.build.lwip_include=lwip2/include +eduinowifi.menu.ip.hb2n.build.lwip_lib=-llwip2-1460 +eduinowifi.menu.ip.hb2n.build.lwip_flags=-DLWIP_OPEN_SRC -DTCP_MSS=1460 -DLWIP_FEATURES=0 -DLWIP_IPV6=0 +eduinowifi.menu.ip.lm6f=v2 IPv6 Lower Memory +eduinowifi.menu.ip.lm6f.build.lwip_include=lwip2/include +eduinowifi.menu.ip.lm6f.build.lwip_lib=-llwip6-536-feat +eduinowifi.menu.ip.lm6f.build.lwip_flags=-DLWIP_OPEN_SRC -DTCP_MSS=536 -DLWIP_FEATURES=1 -DLWIP_IPV6=1 +eduinowifi.menu.ip.hb6f=v2 IPv6 Higher Bandwidth +eduinowifi.menu.ip.hb6f.build.lwip_include=lwip2/include +eduinowifi.menu.ip.hb6f.build.lwip_lib=-llwip6-1460-feat +eduinowifi.menu.ip.hb6f.build.lwip_flags=-DLWIP_OPEN_SRC -DTCP_MSS=1460 -DLWIP_FEATURES=1 -DLWIP_IPV6=1 +eduinowifi.menu.ip.hb1=v1.4 Higher Bandwidth +eduinowifi.menu.ip.hb1.build.lwip_lib=-llwip_gcc +eduinowifi.menu.ip.hb1.build.lwip_flags=-DLWIP_OPEN_SRC +eduinowifi.menu.ip.src=v1.4 Compile from source +eduinowifi.menu.ip.src.build.lwip_lib=-llwip_src +eduinowifi.menu.ip.src.build.lwip_flags=-DLWIP_OPEN_SRC +eduinowifi.menu.ip.src.recipe.hooks.sketch.prebuild.1.pattern=make -C "{runtime.platform.path}/tools/sdk/lwip/src" install TOOLS_PATH="{runtime.tools.xtensa-lx106-elf-gcc.path}/bin/xtensa-lx106-elf-" +eduinowifi.menu.dbg.Disabled=Disabled +eduinowifi.menu.dbg.Disabled.build.debug_port= +eduinowifi.menu.dbg.Serial=Serial +eduinowifi.menu.dbg.Serial.build.debug_port=-DDEBUG_ESP_PORT=Serial +eduinowifi.menu.dbg.Serial1=Serial1 +eduinowifi.menu.dbg.Serial1.build.debug_port=-DDEBUG_ESP_PORT=Serial1 +eduinowifi.menu.lvl.None____=None +eduinowifi.menu.lvl.None____.build.debug_level= +eduinowifi.menu.lvl.SSL=SSL +eduinowifi.menu.lvl.SSL.build.debug_level= -DDEBUG_ESP_SSL +eduinowifi.menu.lvl.TLS_MEM=TLS_MEM +eduinowifi.menu.lvl.TLS_MEM.build.debug_level= -DDEBUG_ESP_TLS_MEM +eduinowifi.menu.lvl.HTTP_CLIENT=HTTP_CLIENT +eduinowifi.menu.lvl.HTTP_CLIENT.build.debug_level= -DDEBUG_ESP_HTTP_CLIENT +eduinowifi.menu.lvl.HTTP_SERVER=HTTP_SERVER +eduinowifi.menu.lvl.HTTP_SERVER.build.debug_level= -DDEBUG_ESP_HTTP_SERVER +eduinowifi.menu.lvl.SSLTLS_MEM=SSL+TLS_MEM +eduinowifi.menu.lvl.SSLTLS_MEM.build.debug_level= -DDEBUG_ESP_SSL -DDEBUG_ESP_TLS_MEM +eduinowifi.menu.lvl.SSLHTTP_CLIENT=SSL+HTTP_CLIENT +eduinowifi.menu.lvl.SSLHTTP_CLIENT.build.debug_level= -DDEBUG_ESP_SSL -DDEBUG_ESP_HTTP_CLIENT +eduinowifi.menu.lvl.SSLHTTP_SERVER=SSL+HTTP_SERVER +eduinowifi.menu.lvl.SSLHTTP_SERVER.build.debug_level= -DDEBUG_ESP_SSL -DDEBUG_ESP_HTTP_SERVER +eduinowifi.menu.lvl.TLS_MEMHTTP_CLIENT=TLS_MEM+HTTP_CLIENT +eduinowifi.menu.lvl.TLS_MEMHTTP_CLIENT.build.debug_level= -DDEBUG_ESP_TLS_MEM -DDEBUG_ESP_HTTP_CLIENT +eduinowifi.menu.lvl.TLS_MEMHTTP_SERVER=TLS_MEM+HTTP_SERVER +eduinowifi.menu.lvl.TLS_MEMHTTP_SERVER.build.debug_level= -DDEBUG_ESP_TLS_MEM -DDEBUG_ESP_HTTP_SERVER +eduinowifi.menu.lvl.HTTP_CLIENTHTTP_SERVER=HTTP_CLIENT+HTTP_SERVER +eduinowifi.menu.lvl.HTTP_CLIENTHTTP_SERVER.build.debug_level= -DDEBUG_ESP_HTTP_CLIENT -DDEBUG_ESP_HTTP_SERVER +eduinowifi.menu.lvl.SSLTLS_MEMHTTP_CLIENT=SSL+TLS_MEM+HTTP_CLIENT +eduinowifi.menu.lvl.SSLTLS_MEMHTTP_CLIENT.build.debug_level= -DDEBUG_ESP_SSL -DDEBUG_ESP_TLS_MEM -DDEBUG_ESP_HTTP_CLIENT +eduinowifi.menu.lvl.SSLTLS_MEMHTTP_SERVER=SSL+TLS_MEM+HTTP_SERVER +eduinowifi.menu.lvl.SSLTLS_MEMHTTP_SERVER.build.debug_level= -DDEBUG_ESP_SSL -DDEBUG_ESP_TLS_MEM -DDEBUG_ESP_HTTP_SERVER +eduinowifi.menu.lvl.SSLHTTP_CLIENTHTTP_SERVER=SSL+HTTP_CLIENT+HTTP_SERVER +eduinowifi.menu.lvl.SSLHTTP_CLIENTHTTP_SERVER.build.debug_level= -DDEBUG_ESP_SSL -DDEBUG_ESP_HTTP_CLIENT -DDEBUG_ESP_HTTP_SERVER +eduinowifi.menu.lvl.TLS_MEMHTTP_CLIENTHTTP_SERVER=TLS_MEM+HTTP_CLIENT+HTTP_SERVER +eduinowifi.menu.lvl.TLS_MEMHTTP_CLIENTHTTP_SERVER.build.debug_level= -DDEBUG_ESP_TLS_MEM -DDEBUG_ESP_HTTP_CLIENT -DDEBUG_ESP_HTTP_SERVER +eduinowifi.menu.lvl.SSLTLS_MEMHTTP_CLIENTHTTP_SERVER=SSL+TLS_MEM+HTTP_CLIENT+HTTP_SERVER +eduinowifi.menu.lvl.SSLTLS_MEMHTTP_CLIENTHTTP_SERVER.build.debug_level= -DDEBUG_ESP_SSL -DDEBUG_ESP_TLS_MEM -DDEBUG_ESP_HTTP_CLIENT -DDEBUG_ESP_HTTP_SERVER +eduinowifi.menu.lvl.CORE=CORE +eduinowifi.menu.lvl.CORE.build.debug_level= -DDEBUG_ESP_CORE +eduinowifi.menu.lvl.WIFI=WIFI +eduinowifi.menu.lvl.WIFI.build.debug_level= -DDEBUG_ESP_WIFI +eduinowifi.menu.lvl.HTTP_UPDATE=HTTP_UPDATE +eduinowifi.menu.lvl.HTTP_UPDATE.build.debug_level= -DDEBUG_ESP_HTTP_UPDATE +eduinowifi.menu.lvl.UPDATER=UPDATER +eduinowifi.menu.lvl.UPDATER.build.debug_level= -DDEBUG_ESP_UPDATER +eduinowifi.menu.lvl.OTA=OTA +eduinowifi.menu.lvl.OTA.build.debug_level= -DDEBUG_ESP_OTA +eduinowifi.menu.lvl.OOM=OOM +eduinowifi.menu.lvl.OOM.build.debug_level= -DDEBUG_ESP_OOM +eduinowifi.menu.lvl.MDNS=MDNS +eduinowifi.menu.lvl.MDNS.build.debug_level= -DDEBUG_ESP_MDNS +eduinowifi.menu.lvl.COREWIFIHTTP_UPDATEUPDATEROTAOOMMDNS=CORE+WIFI+HTTP_UPDATE+UPDATER+OTA+OOM+MDNS +eduinowifi.menu.lvl.COREWIFIHTTP_UPDATEUPDATEROTAOOMMDNS.build.debug_level= -DDEBUG_ESP_CORE -DDEBUG_ESP_WIFI -DDEBUG_ESP_HTTP_UPDATE -DDEBUG_ESP_UPDATER -DDEBUG_ESP_OTA -DDEBUG_ESP_OOM -DDEBUG_ESP_MDNS +eduinowifi.menu.lvl.SSLTLS_MEMHTTP_CLIENTHTTP_SERVERCOREWIFIHTTP_UPDATEUPDATEROTAOOMMDNS=SSL+TLS_MEM+HTTP_CLIENT+HTTP_SERVER+CORE+WIFI+HTTP_UPDATE+UPDATER+OTA+OOM+MDNS +eduinowifi.menu.lvl.SSLTLS_MEMHTTP_CLIENTHTTP_SERVERCOREWIFIHTTP_UPDATEUPDATEROTAOOMMDNS.build.debug_level= -DDEBUG_ESP_SSL -DDEBUG_ESP_TLS_MEM -DDEBUG_ESP_HTTP_CLIENT -DDEBUG_ESP_HTTP_SERVER -DDEBUG_ESP_CORE -DDEBUG_ESP_WIFI -DDEBUG_ESP_HTTP_UPDATE -DDEBUG_ESP_UPDATER -DDEBUG_ESP_OTA -DDEBUG_ESP_OOM -DDEBUG_ESP_MDNS +eduinowifi.menu.lvl.NoAssert-NDEBUG=NoAssert-NDEBUG +eduinowifi.menu.lvl.NoAssert-NDEBUG.build.debug_level= -DNDEBUG +eduinowifi.menu.wipe.none=Only Sketch +eduinowifi.menu.wipe.none.upload.erase_cmd= +eduinowifi.menu.wipe.sdk=Sketch + WiFi Settings +eduinowifi.menu.wipe.sdk.upload.erase_cmd=erase_region "{build.rfcal_addr}" 0x4000 +eduinowifi.menu.wipe.all=All Flash Contents +eduinowifi.menu.wipe.all.upload.erase_cmd=erase_flash +eduinowifi.menu.baud.512000.windows=512000 +eduinowifi.menu.baud.512000.upload.speed=512000 +eduinowifi.menu.baud.57600=57600 +eduinowifi.menu.baud.57600.upload.speed=57600 +eduinowifi.menu.baud.115200=115200 +eduinowifi.menu.baud.115200.upload.speed=115200 +eduinowifi.menu.baud.230400.linux=230400 +eduinowifi.menu.baud.230400.macosx=230400 +eduinowifi.menu.baud.230400.upload.speed=230400 +eduinowifi.menu.baud.256000.windows=256000 +eduinowifi.menu.baud.256000.upload.speed=256000 +eduinowifi.menu.baud.460800.linux=460800 +eduinowifi.menu.baud.460800.macosx=460800 +eduinowifi.menu.baud.460800.upload.speed=460800 +eduinowifi.menu.baud.921600=921600 +eduinowifi.menu.baud.921600.upload.speed=921600 +eduinowifi.menu.baud.3000000=3000000 +eduinowifi.menu.baud.3000000.upload.speed=3000000 + ############################################################## sonoff.name=ITEAD Sonoff -sonoff.build.board=SONOFF_SV +sonoff.build.board=ESP8266_SONOFF_SV sonoff.build.extra_flags=-DESP8266 sonoff.build.flash_size=1M sonoff.build.variant=itead sonoff.menu.BoardModel.sonoffBasic=ITEAD Sonoff Basic -sonoff.menu.BoardModel.sonoffBasic.build.board=SONOFF_BASIC +sonoff.menu.BoardModel.sonoffBasic.build.board=ESP8266_SONOFF_BASIC sonoff.menu.BoardModel.sonoffS20=ITEAD Sonoff S20 -sonoff.menu.BoardModel.sonoffS20.build.board=SONOFF_S20 +sonoff.menu.BoardModel.sonoffS20.build.board=ESP8266_SONOFF_S20 sonoff.menu.BoardModel.sonoffSV=ITEAD Sonoff SV -sonoff.menu.BoardModel.sonoffSV.build.board=SONOFF_SV +sonoff.menu.BoardModel.sonoffSV.build.board=ESP8266_SONOFF_SV sonoff.menu.BoardModel.sonoffTH=ITEAD Sonoff TH -sonoff.menu.BoardModel.sonoffTH.build.board=SONOFF_TH +sonoff.menu.BoardModel.sonoffTH.build.board=ESP8266_SONOFF_TH sonoff.upload.tool=esptool sonoff.upload.maximum_data_size=81920 sonoff.upload.wait_for_upload_port=true diff --git a/arduino/version 2.6.3/platform.txt b/arduino/version 2.7.1/platform.txt similarity index 99% rename from arduino/version 2.6.3/platform.txt rename to arduino/version 2.7.1/platform.txt index 204b5793b..41bfd4a78 100644 --- a/arduino/version 2.6.3/platform.txt +++ b/arduino/version 2.7.1/platform.txt @@ -5,8 +5,8 @@ # For more info: # https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5-3rd-party-Hardware-specification -name=ESP8266 Boards (2.6.3) -version=2.6.3 +name=ESP8266 Boards (2.7.1) +version=2.7.1 # These will be removed by the packager script when doing a JSON release @@ -37,7 +37,7 @@ build.exception_flags=-fno-exceptions build.stdcpp_lib=-lstdc++ build.stdcpp_level=-std=gnu++11 -#build.float=-u _printf_float -u _scanf_float +# build.float=-u _printf_float -u _scanf_float build.float= build.led= diff --git a/esp32_partition_app1984k_spiffs60k.csv b/esp32_partition_app1984k_spiffs60k.csv new file mode 100644 index 000000000..9c5f895a0 --- /dev/null +++ b/esp32_partition_app1984k_spiffs60k.csv @@ -0,0 +1,8 @@ +# ESP-IDF Partition Table +# Name, Type, SubType, Offset, Size, Flags +nvs,data,nvs,0x9000,20K, +otadata,data,ota,0xe000,8K, +app0,app,ota_0,0x10000,1984K, +app1,app,ota_1,0x200000,1984K, +spiffs,data,spiffs,0x3f0000,60K, +eeprom,data,nvs,0x3ff000,4K, diff --git a/esp32_partition_app1984k_spiffs64k.csv b/esp32_partition_app1984k_spiffs64k.csv new file mode 100644 index 000000000..3b428f9a9 --- /dev/null +++ b/esp32_partition_app1984k_spiffs64k.csv @@ -0,0 +1,6 @@ +# Name, Type, SubType, Offset, Size, Flags +nvs, data, nvs, 0x9000, 0x5000, +otadata, data, ota, 0xe000, 0x2000, +app0, app, ota_0, 0x10000, 0x1F0000, +app1, app, ota_1, 0x200000, 0x1F0000, +spiffs, data, spiffs, 0x3F0000,0x10000, diff --git a/lib/A4988_Stepper/README.adoc b/lib/A4988_Stepper/README.adoc old mode 100755 new mode 100644 diff --git a/lib/A4988_Stepper/library.properties b/lib/A4988_Stepper/library.properties old mode 100755 new mode 100644 diff --git a/lib/AT24C256/Eeprom24C128_256.cpp b/lib/AT24C256/Eeprom24C128_256.cpp old mode 100755 new mode 100644 diff --git a/lib/AT24C256/Eeprom24C128_256.h b/lib/AT24C256/Eeprom24C128_256.h old mode 100755 new mode 100644 diff --git a/lib/Adafruit_BusIO/.travis.yml b/lib/Adafruit_BusIO/.travis.yml new file mode 100644 index 000000000..40754054e --- /dev/null +++ b/lib/Adafruit_BusIO/.travis.yml @@ -0,0 +1,23 @@ +language: c +sudo: false +cache: + directories: + - ~/arduino_ide + - ~/.arduino15/packages/ +git: + depth: false + quiet: true +env: + global: + - PRETTYNAME="Adafruit BusIO Library" + +before_install: + - source <(curl -SLs https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/install.sh) + +script: + - build_main_platforms + +# Generate and deploy documentation +after_success: + - source <(curl -SLs https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/library_check.sh) + - source <(curl -SLs https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/doxy_gen_and_deploy.sh) \ No newline at end of file diff --git a/lib/Adafruit_BusIO/Adafruit_BusIO_Register.cpp b/lib/Adafruit_BusIO/Adafruit_BusIO_Register.cpp new file mode 100644 index 000000000..2c2b22e00 --- /dev/null +++ b/lib/Adafruit_BusIO/Adafruit_BusIO_Register.cpp @@ -0,0 +1,258 @@ +#include + +/*! + * @brief Create a register we access over an I2C Device (which defines the bus and address) + * @param i2cdevice The I2CDevice to use for underlying I2C access + * @param reg_addr The address pointer value for the I2C/SMBus register, can be 8 or 16 bits + * @param width The width of the register data itself, defaults to 1 byte + * @param bitorder The bit order of the register (used when width is > 1), defaults to LSBFIRST + * @param address_width The width of the register address itself, defaults to 1 byte + */ +Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice *i2cdevice, uint16_t reg_addr, + uint8_t width, uint8_t bitorder, uint8_t address_width) { + _i2cdevice = i2cdevice; + _spidevice = NULL; + _addrwidth = address_width; + _address = reg_addr; + _bitorder = bitorder; + _width = width; +} + +/*! + * @brief Create a register we access over an SPI Device (which defines the bus and CS pin) + * @param spidevice The SPIDevice to use for underlying I2C access + * @param reg_addr The address pointer value for the I2C/SMBus register, can be 8 or 16 bits + * @param type The method we use to read/write data to SPI (which is not as well defined as I2C) + * @param width The width of the register data itself, defaults to 1 byte + * @param bitorder The bit order of the register (used when width is > 1), defaults to LSBFIRST + * @param address_width The width of the register address itself, defaults to 1 byte + */ +Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_SPIDevice *spidevice, uint16_t reg_addr, + Adafruit_BusIO_SPIRegType type, + uint8_t width, uint8_t bitorder, uint8_t address_width) { + _spidevice = spidevice; + _spiregtype = type; + _i2cdevice = NULL; + _addrwidth = address_width; + _address = reg_addr; + _bitorder = bitorder; + _width = width; +} + +/*! + * @brief Create a register we access over an I2C or SPI Device. This is a handy function because we + * can pass in NULL for the unused interface, allowing libraries to mass-define all the registers + * @param i2cdevice The I2CDevice to use for underlying I2C access, if NULL we use SPI + * @param spidevice The SPIDevice to use for underlying I2C access, if NULL we use I2C + * @param reg_addr The address pointer value for the I2C/SMBus register, can be 8 or 16 bits + * @param type The method we use to read/write data to SPI (which is not as well defined as I2C) + * @param width The width of the register data itself, defaults to 1 byte + * @param bitorder The bit order of the register (used when width is > 1), defaults to LSBFIRST + * @param address_width The width of the register address itself, defaults to 1 byte + */ +Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice *i2cdevice, Adafruit_SPIDevice *spidevice, + Adafruit_BusIO_SPIRegType type, uint16_t reg_addr, + uint8_t width, uint8_t bitorder, uint8_t address_width) { + _spidevice = spidevice; + _i2cdevice = i2cdevice; + _spiregtype = type; + _addrwidth = address_width; + _address = reg_addr; + _bitorder = bitorder; + _width = width; +} + + +/*! + * @brief Write a buffer of data to the register location + * @param buffer Pointer to data to write + * @param len Number of bytes to write + * @return True on successful write (only really useful for I2C as SPI is uncheckable) + */ +bool Adafruit_BusIO_Register::write(uint8_t *buffer, uint8_t len) { + + uint8_t addrbuffer[2] = {(uint8_t)(_address & 0xFF), (uint8_t)(_address>>8)}; + + if (_i2cdevice) { + return _i2cdevice->write(buffer, len, true, addrbuffer, _addrwidth); + } + if (_spidevice) { + if (_spiregtype == ADDRBIT8_HIGH_TOREAD) { + addrbuffer[0] &= ~0x80; + } + return _spidevice->write( buffer, len, addrbuffer, _addrwidth); + } + return false; +} + +/*! + * @brief Write up to 4 bytes of data to the register location + * @param value Data to write + * @param numbytes How many bytes from 'value' to write + * @return True on successful write (only really useful for I2C as SPI is uncheckable) + */ +bool Adafruit_BusIO_Register::write(uint32_t value, uint8_t numbytes) { + if (numbytes == 0) { + numbytes = _width; + } + if (numbytes > 4) { + return false; + } + + for (int i=0; i>= 8; + } + return write(_buffer, numbytes); +} + +/*! + * @brief Read data from the register location. This does not do any error checking! + * @return Returns 0xFFFFFFFF on failure, value otherwise + */ +uint32_t Adafruit_BusIO_Register::read(void) { + if (! read(_buffer, _width)) { + return -1; + } + + uint32_t value = 0; + + for (int i=0; i < _width; i++) { + value <<= 8; + if (_bitorder == LSBFIRST) { + value |= _buffer[_width-i-1]; + } else { + value |= _buffer[i]; + } + } + + return value; +} + + +/*! + * @brief Read a buffer of data from the register location + * @param buffer Pointer to data to read into + * @param len Number of bytes to read + * @return True on successful write (only really useful for I2C as SPI is uncheckable) + */ +bool Adafruit_BusIO_Register::read(uint8_t *buffer, uint8_t len) { + uint8_t addrbuffer[2] = {(uint8_t)(_address & 0xFF), (uint8_t)(_address>>8)}; + + if (_i2cdevice) { + return _i2cdevice->write_then_read(addrbuffer, _addrwidth, buffer, len); + } + if (_spidevice) { + if (_spiregtype == ADDRBIT8_HIGH_TOREAD) { + addrbuffer[0] |= 0x80; + } + return _spidevice->write_then_read(addrbuffer, _addrwidth, buffer, len); + } + return false; +} + +/*! + * @brief Read 2 bytes of data from the register location + * @param value Pointer to uint16_t variable to read into + * @return True on successful write (only really useful for I2C as SPI is uncheckable) + */ +bool Adafruit_BusIO_Register::read(uint16_t *value) { + if (! read(_buffer, 2)) { + return false; + } + + if (_bitorder == LSBFIRST) { + *value = _buffer[1]; + *value <<= 8; + *value |= _buffer[0]; + } else { + *value = _buffer[0]; + *value <<= 8; + *value |= _buffer[1]; + } + return true; +} + +/*! + * @brief Read 1 byte of data from the register location + * @param value Pointer to uint8_t variable to read into + * @return True on successful write (only really useful for I2C as SPI is uncheckable) + */ +bool Adafruit_BusIO_Register::read(uint8_t *value) { + if (! read(_buffer, 1)) { + return false; + } + + *value = _buffer[0]; + return true; +} + +/*! + * @brief Pretty printer for this register + * @param s The Stream to print to, defaults to &Serial + */ +void Adafruit_BusIO_Register::print(Stream *s) { + uint32_t val = read(); + s->print("0x"); s->print(val, HEX); +} + +/*! + * @brief Pretty printer for this register + * @param s The Stream to print to, defaults to &Serial + */ +void Adafruit_BusIO_Register::println(Stream *s) { + print(s); + s->println(); +} + + +/*! + * @brief Create a slice of the register that we can address without touching other bits + * @param reg The Adafruit_BusIO_Register which defines the bus/register + * @param bits The number of bits wide we are slicing + * @param shift The number of bits that our bit-slice is shifted from LSB + */ +Adafruit_BusIO_RegisterBits::Adafruit_BusIO_RegisterBits(Adafruit_BusIO_Register *reg, uint8_t bits, uint8_t shift) { + _register = reg; + _bits = bits; + _shift = shift; +} + +/*! + * @brief Read 4 bytes of data from the register + * @return data The 4 bytes to read + */ +uint32_t Adafruit_BusIO_RegisterBits::read(void) { + uint32_t val = _register->read(); + val >>= _shift; + return val & ((1 << (_bits)) - 1); +} + + +/*! + * @brief Write 4 bytes of data to the register + * @param data The 4 bytes to write + */ +void Adafruit_BusIO_RegisterBits::write(uint32_t data) { + uint32_t val = _register->read(); + + // mask off the data before writing + uint32_t mask = (1 << (_bits)) - 1; + data &= mask; + + mask <<= _shift; + val &= ~mask; // remove the current data at that spot + val |= data << _shift; // and add in the new data + + _register->write(val, _register->width()); +} + +/*! + * @brief The width of the register data, helpful for doing calculations + * @returns The data width used when initializing the register + */ +uint8_t Adafruit_BusIO_Register::width(void) { return _width; } diff --git a/lib/Adafruit_BusIO/Adafruit_BusIO_Register.h b/lib/Adafruit_BusIO/Adafruit_BusIO_Register.h new file mode 100644 index 000000000..45ae1e146 --- /dev/null +++ b/lib/Adafruit_BusIO/Adafruit_BusIO_Register.h @@ -0,0 +1,69 @@ +#include +#include +#include + + +#ifndef Adafruit_BusIO_Register_h +#define Adafruit_BusIO_Register_h + +typedef enum _Adafruit_BusIO_SPIRegType { + ADDRBIT8_HIGH_TOREAD = 0, +} Adafruit_BusIO_SPIRegType; + +/*! + * @brief The class which defines a device register (a location to read/write data from) + */ +class Adafruit_BusIO_Register { + public: + Adafruit_BusIO_Register(Adafruit_I2CDevice *i2cdevice, uint16_t reg_addr, + uint8_t width=1, uint8_t bitorder=LSBFIRST, + uint8_t address_width=1); + Adafruit_BusIO_Register(Adafruit_SPIDevice *spidevice, uint16_t reg_addr, + Adafruit_BusIO_SPIRegType type, + uint8_t width=1, uint8_t bitorder=LSBFIRST, + uint8_t address_width=1); + + Adafruit_BusIO_Register(Adafruit_I2CDevice *i2cdevice, + Adafruit_SPIDevice *spidevice, + Adafruit_BusIO_SPIRegType type, + uint16_t reg_addr, + uint8_t width=1, uint8_t bitorder=LSBFIRST, + uint8_t address_width=1); + + bool read(uint8_t *buffer, uint8_t len); + bool read(uint8_t *value); + bool read(uint16_t *value); + uint32_t read(void); + bool write(uint8_t *buffer, uint8_t len); + bool write(uint32_t value, uint8_t numbytes=0); + + uint8_t width(void); + + void print(Stream *s=&Serial); + void println(Stream *s=&Serial); + + private: + Adafruit_I2CDevice *_i2cdevice; + Adafruit_SPIDevice *_spidevice; + Adafruit_BusIO_SPIRegType _spiregtype; + uint16_t _address; + uint8_t _width, _addrwidth, _bitorder; + uint8_t _buffer[4]; // we wont support anything larger than uint32 for non-buffered read +}; + + +/*! + * @brief The class which defines a slice of bits from within a device register (a location to read/write data from) + */ +class Adafruit_BusIO_RegisterBits { + public: + Adafruit_BusIO_RegisterBits(Adafruit_BusIO_Register *reg, uint8_t bits, uint8_t shift); + void write(uint32_t value); + uint32_t read(void); + private: + Adafruit_BusIO_Register *_register; + uint8_t _bits, _shift; +}; + + +#endif //BusIO_Register_h diff --git a/lib/Adafruit_BusIO/Adafruit_I2CDevice.cpp b/lib/Adafruit_BusIO/Adafruit_I2CDevice.cpp new file mode 100644 index 000000000..7813a6df7 --- /dev/null +++ b/lib/Adafruit_BusIO/Adafruit_I2CDevice.cpp @@ -0,0 +1,213 @@ +#include +#include + +//#define DEBUG_SERIAL Serial + +/*! + * @brief Create an I2C device at a given address + * @param addr The 7-bit I2C address for the device + * @param theWire The I2C bus to use, defaults to &Wire + */ +Adafruit_I2CDevice::Adafruit_I2CDevice(uint8_t addr, TwoWire *theWire) { + _addr = addr; + _wire = theWire; + _begun = false; +#ifdef ARDUINO_ARCH_SAMD + _maxBufferSize = 250; // as defined in Wire.h's RingBuffer +#else + _maxBufferSize = 32; +#endif +} + +/*! + * @brief Initializes and does basic address detection + * @param addr_detect Whether we should attempt to detect the I2C address with a scan. + * 99% of sensors/devices don't mind but once in a while, they spaz on a scan! + * @return True if I2C initialized and a device with the addr found + */ +bool Adafruit_I2CDevice::begin(bool addr_detect) { + _wire->begin(); + _begun = true; + + if (addr_detect) { + return detected(); + } + return true; +} + + +/*! + * @brief Scans I2C for the address - note will give a false-positive + * if there's no pullups on I2C + * @return True if I2C initialized and a device with the addr found + */ +bool Adafruit_I2CDevice::detected(void) { + // Init I2C if not done yet + if (!_begun && !begin()) { + return false; + } + + // A basic scanner, see if it ACK's + _wire->beginTransmission(_addr); + if (_wire->endTransmission () == 0) { + return true; + } + return false; +} + +/*! + * @brief Write a buffer or two to the I2C device. Cannot be more than maxBufferSize() bytes. + * @param buffer Pointer to buffer of data to write + * @param len Number of bytes from buffer to write + * @param prefix_buffer Pointer to optional array of data to write before buffer. + * Cannot be more than maxBufferSize() bytes. + * @param prefix_len Number of bytes from prefix buffer to write + * @param stop Whether to send an I2C STOP signal on write + * @return True if write was successful, otherwise false. + */ +bool Adafruit_I2CDevice::write(uint8_t *buffer, size_t len, bool stop, uint8_t *prefix_buffer, size_t prefix_len) { + if ((len+prefix_len) > maxBufferSize()) { + // currently not guaranteed to work if more than 32 bytes! + // we will need to find out if some platforms have larger + // I2C buffer sizes :/ +#ifdef DEBUG_SERIAL + DEBUG_SERIAL.println(F("\tI2CDevice could not write such a large buffer")); +#endif + return false; + } + + _wire->beginTransmission(_addr); + + // Write the prefix data (usually an address) + if ((prefix_len != 0) && (prefix_buffer != NULL)) { + if (_wire->write(prefix_buffer, prefix_len) != prefix_len) { +#ifdef DEBUG_SERIAL + DEBUG_SERIAL.println(F("\tI2CDevice failed to write")); +#endif + return false; + } + } + + // Write the data itself + if (_wire->write(buffer, len) != len) { +#ifdef DEBUG_SERIAL + DEBUG_SERIAL.println(F("\tI2CDevice failed to write")); +#endif + return false; + } + +#ifdef DEBUG_SERIAL + DEBUG_SERIAL.print(F("\tI2CDevice Wrote: ")); + if ((prefix_len != 0) && (prefix_buffer != NULL)) { + for (uint16_t i=0; iendTransmission(stop) == 0) { +#ifdef DEBUG_SERIAL + DEBUG_SERIAL.println("Sent!"); +#endif + return true; + } else { +#ifdef DEBUG_SERIAL + DEBUG_SERIAL.println("Failed to send!"); +#endif + return false; + } +} + + +/*! + * @brief Read from I2C into a buffer from the I2C device. + * Cannot be more than maxBufferSize() bytes. + * @param buffer Pointer to buffer of data to read into + * @param len Number of bytes from buffer to read. + * @param stop Whether to send an I2C STOP signal on read + * @return True if read was successful, otherwise false. + */ +bool Adafruit_I2CDevice::read(uint8_t *buffer, size_t len, bool stop) { + if (len > maxBufferSize()) { + // currently not guaranteed to work if more than 32 bytes! + // we will need to find out if some platforms have larger + // I2C buffer sizes :/ +#ifdef DEBUG_SERIAL + DEBUG_SERIAL.println(F("\tI2CDevice could not read such a large buffer")); +#endif + return false; + } + + size_t recv = _wire->requestFrom((uint8_t)_addr, (uint8_t)len, (uint8_t)stop); + if (recv != len) { + // Not enough data available to fulfill our obligation! +#ifdef DEBUG_SERIAL + DEBUG_SERIAL.print(F("\tI2CDevice did not receive enough data: ")); + DEBUG_SERIAL.println(recv); +#endif + return false; + } + + for (uint16_t i=0; iread(); + } + +#ifdef DEBUG_SERIAL + DEBUG_SERIAL.print(F("\tI2CDevice Read: ")); + for (uint16_t i=0; i + +#ifndef Adafruit_I2CDevice_h +#define Adafruit_I2CDevice_h + +///< The class which defines how we will talk to this device over I2C +class Adafruit_I2CDevice { + public: + Adafruit_I2CDevice(uint8_t addr, TwoWire *theWire=&Wire); + uint8_t address(void); + bool begin(bool addr_detect=true); + bool detected(void); + + bool read(uint8_t *buffer, size_t len, bool stop=true); + bool write(uint8_t *buffer, size_t len, bool stop=true, uint8_t *prefix_buffer=NULL, size_t prefix_len=0); + bool write_then_read(uint8_t *write_buffer, size_t write_len, uint8_t *read_buffer, size_t read_len, bool stop=false); + + /*! @brief How many bytes we can read in a transaction + * @return The size of the Wire receive/transmit buffer */ + uint16_t maxBufferSize() { return _maxBufferSize; } + + private: + uint8_t _addr; + TwoWire *_wire; + bool _begun; + uint16_t _maxBufferSize; +}; + +#endif // Adafruit_I2CDevice_h diff --git a/lib/Adafruit_BusIO/Adafruit_I2CRegister.h b/lib/Adafruit_BusIO/Adafruit_I2CRegister.h new file mode 100644 index 000000000..703e93b76 --- /dev/null +++ b/lib/Adafruit_BusIO/Adafruit_I2CRegister.h @@ -0,0 +1,8 @@ +#include "Adafruit_BusIO_Register.h" +#ifndef _ADAFRUIT_I2C_REGISTER_H_ +#define _ADAFRUIT_I2C_REGISTER_H_ + +typedef Adafruit_BusIO_Register Adafruit_I2CRegister; +typedef Adafruit_BusIO_RegisterBits Adafruit_I2CRegisterBits; + +#endif diff --git a/lib/Adafruit_BusIO/Adafruit_SPIDevice.cpp b/lib/Adafruit_BusIO/Adafruit_SPIDevice.cpp new file mode 100644 index 000000000..1d599bb11 --- /dev/null +++ b/lib/Adafruit_BusIO/Adafruit_SPIDevice.cpp @@ -0,0 +1,301 @@ +#include +#include + +//#define DEBUG_SERIAL Serial + +/*! + * @brief Create an SPI device with the given CS pin and settins + * @param cspin The arduino pin number to use for chip select + * @param freq The SPI clock frequency to use, defaults to 1MHz + * @param dataOrder The SPI data order to use for bits within each byte, defaults to SPI_BITORDER_MSBFIRST + * @param dataMode The SPI mode to use, defaults to SPI_MODE0 + * @param theSPI The SPI bus to use, defaults to &theSPI + */ +Adafruit_SPIDevice::Adafruit_SPIDevice(int8_t cspin, uint32_t freq, BitOrder dataOrder, uint8_t dataMode, SPIClass *theSPI) { + _cs = cspin; + _sck = _mosi = _miso = -1; + _spi = theSPI; + _begun = false; + _spiSetting = new SPISettings(freq, dataOrder, dataMode); + _freq = freq; + _dataOrder = dataOrder; + _dataMode = dataMode; +} + +/*! + * @brief Create an SPI device with the given CS pin and settins + * @param cspin The arduino pin number to use for chip select + * @param sckpin The arduino pin number to use for SCK + * @param misopin The arduino pin number to use for MISO, set to -1 if not used + * @param mosipin The arduino pin number to use for MOSI, set to -1 if not used + * @param freq The SPI clock frequency to use, defaults to 1MHz + * @param dataOrder The SPI data order to use for bits within each byte, defaults to SPI_BITORDER_MSBFIRST + * @param dataMode The SPI mode to use, defaults to SPI_MODE0 + */ +Adafruit_SPIDevice::Adafruit_SPIDevice(int8_t cspin, int8_t sckpin, int8_t misopin, int8_t mosipin, + uint32_t freq, BitOrder dataOrder, uint8_t dataMode) { + _cs = cspin; + _sck = sckpin; + _miso = misopin; + _mosi = mosipin; + _freq = freq; + _dataOrder = dataOrder; + _dataMode = dataMode; + _begun = false; + _spiSetting = new SPISettings(freq, dataOrder, dataMode); + _spi = NULL; +} + + +/*! + * @brief Initializes SPI bus and sets CS pin high + * @return Always returns true because there's no way to test success of SPI init + */ +bool Adafruit_SPIDevice::begin(void) { + pinMode(_cs, OUTPUT); + digitalWrite(_cs, HIGH); + + if (_spi) { // hardware SPI + _spi->begin(); + } else { + pinMode(_sck, OUTPUT); + + if (_dataMode==SPI_MODE0) { + digitalWrite(_sck, HIGH); + } else { + digitalWrite(_sck, LOW); + } + if (_mosi != -1) { + pinMode(_mosi, OUTPUT); + digitalWrite(_mosi, HIGH); + } + if (_miso != -1) { + pinMode(_miso, INPUT); + } + } + + _begun = true; + return true; +} + + +/*! + * @brief Transfer (send/receive) one byte over hard/soft SPI + * @param buffer The buffer to send and receive at the same time + * @param len The number of bytes to transfer + */ +void Adafruit_SPIDevice::transfer(uint8_t *buffer, size_t len) { + if (_spi) { + // hardware SPI is easy + _spi->transfer(buffer, len); + return; + } + + // for softSPI we'll do it by hand + for (size_t i=0; i> b) & 0x1) << (7-b); + } + send = temp; + } + for (int b=7; b>=0; b--) { + reply <<= 1; + if (_dataMode == SPI_MODE0) { + digitalWrite(_sck, LOW); + digitalWrite(_mosi, send & (1<> b) & 0x1) << (7-b); + } + reply = temp; + } + + buffer[i] = reply; + } + return; +} + + + +/*! + * @brief Transfer (send/receive) one byte over hard/soft SPI + * @param send The byte to send + * @return The byte received while transmitting + */ +uint8_t Adafruit_SPIDevice::transfer(uint8_t send) { + uint8_t data = send; + transfer(&data, 1); + return data; +} + + +/*! + * @brief Write a buffer or two to the SPI device. + * @param buffer Pointer to buffer of data to write + * @param len Number of bytes from buffer to write + * @param prefix_buffer Pointer to optional array of data to write before buffer. + * @param prefix_len Number of bytes from prefix buffer to write + * @return Always returns true because there's no way to test success of SPI writes + */ +bool Adafruit_SPIDevice::write(uint8_t *buffer, size_t len, uint8_t *prefix_buffer, size_t prefix_len) { + if (_spi) { + _spi->beginTransaction(*_spiSetting); + } + + digitalWrite(_cs, LOW); + // do the writing + for (size_t i=0; iendTransaction(); + } + +#ifdef DEBUG_SERIAL + DEBUG_SERIAL.print(F("\tSPIDevice Wrote: ")); + if ((prefix_len != 0) && (prefix_buffer != NULL)) { + for (uint16_t i=0; ibeginTransaction(*_spiSetting); + } + digitalWrite(_cs, LOW); + transfer(buffer, len); + digitalWrite(_cs, HIGH); + + if (_spi) { + _spi->endTransaction(); + } + +#ifdef DEBUG_SERIAL + DEBUG_SERIAL.print(F("\tSPIDevice Read: ")); + for (uint16_t i=0; ibeginTransaction(*_spiSetting); + } + + digitalWrite(_cs, LOW); + // do the writing + for (size_t i=0; iendTransaction(); + } + + return true; +} diff --git a/lib/Adafruit_BusIO/Adafruit_SPIDevice.h b/lib/Adafruit_BusIO/Adafruit_SPIDevice.h new file mode 100644 index 000000000..987cb3f62 --- /dev/null +++ b/lib/Adafruit_BusIO/Adafruit_SPIDevice.h @@ -0,0 +1,62 @@ +#include + +#ifndef Adafruit_SPIDevice_h +#define Adafruit_SPIDevice_h + +// some modern SPI definitions don't have BitOrder enum +#if (defined(__AVR__) && !defined(ARDUINO_ARCH_MEGAAVR)) || defined(ESP8266) || defined(TEENSYDUINO) +typedef enum _BitOrder { + SPI_BITORDER_MSBFIRST = MSBFIRST, + SPI_BITORDER_LSBFIRST = LSBFIRST, +} BitOrder; +#endif + +// some modern SPI definitions don't have BitOrder enum and have different SPI mode defines +#if defined(ESP32) +typedef enum _BitOrder { + SPI_BITORDER_MSBFIRST = SPI_MSBFIRST, + SPI_BITORDER_LSBFIRST = SPI_LSBFIRST, +} BitOrder; +#endif + +// Some platforms have a BitOrder enum but its named MSBFIRST/LSBFIRST +#if defined(ARDUINO_ARCH_SAMD) || defined(__SAM3X8E__) || defined(NRF52_SERIES) || defined(ARDUINO_ARCH_ARDUINO_CORE_STM32) || defined(ARDUINO_ARCH_MEGAAVR) || defined(_STM32_DEF_) + #define SPI_BITORDER_MSBFIRST MSBFIRST + #define SPI_BITORDER_LSBFIRST LSBFIRST +#endif + +///< The class which defines how we will talk to this device over SPI +class Adafruit_SPIDevice { + public: + Adafruit_SPIDevice(int8_t cspin, + uint32_t freq=1000000, + BitOrder dataOrder=SPI_BITORDER_MSBFIRST, + uint8_t dataMode=SPI_MODE0, + SPIClass *theSPI=&SPI); + + Adafruit_SPIDevice(int8_t cspin, int8_t sck, int8_t miso, int8_t mosi, + uint32_t freq=1000000, + BitOrder dataOrder=SPI_BITORDER_MSBFIRST, + uint8_t dataMode=SPI_MODE0); + + bool begin(void); + bool read(uint8_t *buffer, size_t len, uint8_t sendvalue=0xFF); + bool write(uint8_t *buffer, size_t len, uint8_t *prefix_buffer=NULL, size_t prefix_len=0); + bool write_then_read(uint8_t *write_buffer, size_t write_len, uint8_t *read_buffer, size_t read_len, uint8_t sendvalue=0xFF); + + uint8_t transfer(uint8_t send); + void transfer(uint8_t *buffer, size_t len); + + private: + + SPIClass *_spi; + SPISettings *_spiSetting; + uint32_t _freq; + BitOrder _dataOrder; + uint8_t _dataMode; + + int8_t _cs, _sck, _mosi, _miso; + bool _begun; +}; + +#endif // Adafruit_SPIDevice_h diff --git a/lib/Adafruit_BusIO/LICENSE b/lib/Adafruit_BusIO/LICENSE new file mode 100644 index 000000000..860e3e285 --- /dev/null +++ b/lib/Adafruit_BusIO/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2017 Adafruit Industries + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/lib/Adafruit_BusIO/README.md b/lib/Adafruit_BusIO/README.md new file mode 100644 index 000000000..a1830809c --- /dev/null +++ b/lib/Adafruit_BusIO/README.md @@ -0,0 +1,7 @@ +# Adafruit Bus IO Library [![Build Status](https://travis-ci.com/adafruit/Adafruit_BusIO.svg?branch=master)](https://travis-ci.com/adafruit/Adafruit_BusIO) + +This is a helper libary to abstract away I2C & SPI transactions and registers + +Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit! + +MIT license, all text above must be included in any redistribution diff --git a/lib/Adafruit_BusIO/examples/i2c_address_detect/i2c_address_detect.ino b/lib/Adafruit_BusIO/examples/i2c_address_detect/i2c_address_detect.ino new file mode 100644 index 000000000..b1505254e --- /dev/null +++ b/lib/Adafruit_BusIO/examples/i2c_address_detect/i2c_address_detect.ino @@ -0,0 +1,21 @@ +#include + +Adafruit_I2CDevice i2c_dev = Adafruit_I2CDevice(0x10); + +void setup() { + while (!Serial) { delay(10); } + Serial.begin(115200); + Serial.println("I2C address detection test"); + + if (!i2c_dev.begin()) { + Serial.print("Did not find device at 0x"); + Serial.println(i2c_dev.address(), HEX); + while (1); + } + Serial.print("Device found on address 0x"); + Serial.println(i2c_dev.address(), HEX); +} + +void loop() { + +} diff --git a/lib/Adafruit_BusIO/examples/i2c_readwrite/i2c_readwrite.ino b/lib/Adafruit_BusIO/examples/i2c_readwrite/i2c_readwrite.ino new file mode 100644 index 000000000..909cf3118 --- /dev/null +++ b/lib/Adafruit_BusIO/examples/i2c_readwrite/i2c_readwrite.ino @@ -0,0 +1,41 @@ +#include + +#define I2C_ADDRESS 0x60 +Adafruit_I2CDevice i2c_dev = Adafruit_I2CDevice(I2C_ADDRESS); + + +void setup() { + while (!Serial) { delay(10); } + Serial.begin(115200); + Serial.println("I2C device read and write test"); + + if (!i2c_dev.begin()) { + Serial.print("Did not find device at 0x"); + Serial.println(i2c_dev.address(), HEX); + while (1); + } + Serial.print("Device found on address 0x"); + Serial.println(i2c_dev.address(), HEX); + + uint8_t buffer[32]; + // Try to read 32 bytes + i2c_dev.read(buffer, 32); + Serial.print("Read: "); + for (uint8_t i=0; i<32; i++) { + Serial.print("0x"); Serial.print(buffer[i], HEX); Serial.print(", "); + } + Serial.println(); + + // read a register by writing first, then reading + buffer[0] = 0x0C; // we'll reuse the same buffer + i2c_dev.write_then_read(buffer, 1, buffer, 2, false); + Serial.print("Write then Read: "); + for (uint8_t i=0; i<2; i++) { + Serial.print("0x"); Serial.print(buffer[i], HEX); Serial.print(", "); + } + Serial.println(); +} + +void loop() { + +} diff --git a/lib/Adafruit_BusIO/examples/i2c_registers/i2c_registers.ino b/lib/Adafruit_BusIO/examples/i2c_registers/i2c_registers.ino new file mode 100644 index 000000000..41a30436e --- /dev/null +++ b/lib/Adafruit_BusIO/examples/i2c_registers/i2c_registers.ino @@ -0,0 +1,38 @@ +#include +#include + +#define I2C_ADDRESS 0x60 +Adafruit_I2CDevice i2c_dev = Adafruit_I2CDevice(I2C_ADDRESS); + + +void setup() { + while (!Serial) { delay(10); } + Serial.begin(115200); + Serial.println("I2C device register test"); + + if (!i2c_dev.begin()) { + Serial.print("Did not find device at 0x"); + Serial.println(i2c_dev.address(), HEX); + while (1); + } + Serial.print("Device found on address 0x"); + Serial.println(i2c_dev.address(), HEX); + + Adafruit_BusIO_Register id_reg = Adafruit_BusIO_Register(&i2c_dev, 0x0C, 2, LSBFIRST); + uint16_t id; + id_reg.read(&id); + Serial.print("ID register = 0x"); Serial.println(id, HEX); + + Adafruit_BusIO_Register thresh_reg = Adafruit_BusIO_Register(&i2c_dev, 0x01, 2, LSBFIRST); + uint16_t thresh; + thresh_reg.read(&thresh); + Serial.print("Initial threshold register = 0x"); Serial.println(thresh, HEX); + + thresh_reg.write(~thresh); + + Serial.print("Post threshold register = 0x"); Serial.println(thresh_reg.read(), HEX); +} + +void loop() { + +} \ No newline at end of file diff --git a/lib/Adafruit_BusIO/examples/i2corspi_register/i2corspi_register.ino b/lib/Adafruit_BusIO/examples/i2corspi_register/i2corspi_register.ino new file mode 100644 index 000000000..555cf3b0d --- /dev/null +++ b/lib/Adafruit_BusIO/examples/i2corspi_register/i2corspi_register.ino @@ -0,0 +1,38 @@ +#include + +// Define which interface to use by setting the unused interface to NULL! + +#define SPIDEVICE_CS 10 +Adafruit_SPIDevice *spi_dev = NULL; // new Adafruit_SPIDevice(SPIDEVICE_CS); + +#define I2C_ADDRESS 0x5D +Adafruit_I2CDevice *i2c_dev = new Adafruit_I2CDevice(I2C_ADDRESS); + +void setup() { + while (!Serial) { delay(10); } + Serial.begin(115200); + Serial.println("I2C or SPI device register test"); + + if (spi_dev && !spi_dev->begin()) { + Serial.println("Could not initialize SPI device"); + } + + if (i2c_dev) { + if (i2c_dev->begin()) { + Serial.print("Device found on I2C address 0x"); + Serial.println(i2c_dev->address(), HEX); + } else { + Serial.print("Did not find I2C device at 0x"); + Serial.println(i2c_dev->address(), HEX); + } + } + + Adafruit_BusIO_Register id_reg = Adafruit_BusIO_Register(i2c_dev, spi_dev, ADDRBIT8_HIGH_TOREAD, 0x0F); + uint8_t id; + id_reg.read(&id); + Serial.print("ID register = 0x"); Serial.println(id, HEX); +} + +void loop() { + +} \ No newline at end of file diff --git a/lib/Adafruit_BusIO/examples/spi_modetest/spi_modetest.ino b/lib/Adafruit_BusIO/examples/spi_modetest/spi_modetest.ino new file mode 100644 index 000000000..10168c5ff --- /dev/null +++ b/lib/Adafruit_BusIO/examples/spi_modetest/spi_modetest.ino @@ -0,0 +1,29 @@ +#include + +#define SPIDEVICE_CS 10 +Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice(SPIDEVICE_CS, 100000, SPI_BITORDER_MSBFIRST, SPI_MODE1); +//Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice(SPIDEVICE_CS, 13, 12, 11, 100000, SPI_BITORDER_MSBFIRST, SPI_MODE1); + + +void setup() { + while (!Serial) { delay(10); } + Serial.begin(115200); + Serial.println("SPI device mode test"); + + if (!spi_dev.begin()) { + Serial.println("Could not initialize SPI device"); + while (1); + } +} + +void loop() { + Serial.println("\n\nTransfer test"); + for (uint16_t x=0; x<=0xFF; x++) { + uint8_t i = x; + Serial.print("0x"); Serial.print(i, HEX); + spi_dev.read(&i, 1, i); + Serial.print("/"); Serial.print(i, HEX); + Serial.print(", "); + delay(25); + } +} \ No newline at end of file diff --git a/lib/Adafruit_BusIO/examples/spi_readwrite/spi_readwrite.ino b/lib/Adafruit_BusIO/examples/spi_readwrite/spi_readwrite.ino new file mode 100644 index 000000000..6f2c063f0 --- /dev/null +++ b/lib/Adafruit_BusIO/examples/spi_readwrite/spi_readwrite.ino @@ -0,0 +1,39 @@ +#include + +#define SPIDEVICE_CS 10 +Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice(SPIDEVICE_CS); + + +void setup() { + while (!Serial) { delay(10); } + Serial.begin(115200); + Serial.println("SPI device read and write test"); + + if (!spi_dev.begin()) { + Serial.println("Could not initialize SPI device"); + while (1); + } + + uint8_t buffer[32]; + + // Try to read 32 bytes + spi_dev.read(buffer, 32); + Serial.print("Read: "); + for (uint8_t i=0; i<32; i++) { + Serial.print("0x"); Serial.print(buffer[i], HEX); Serial.print(", "); + } + Serial.println(); + + // read a register by writing first, then reading + buffer[0] = 0x8F; // we'll reuse the same buffer + spi_dev.write_then_read(buffer, 1, buffer, 2, false); + Serial.print("Write then Read: "); + for (uint8_t i=0; i<2; i++) { + Serial.print("0x"); Serial.print(buffer[i], HEX); Serial.print(", "); + } + Serial.println(); +} + +void loop() { + +} diff --git a/lib/Adafruit_BusIO/examples/spi_registers/spi_registers.ino b/lib/Adafruit_BusIO/examples/spi_registers/spi_registers.ino new file mode 100644 index 000000000..e24f1aa9a --- /dev/null +++ b/lib/Adafruit_BusIO/examples/spi_registers/spi_registers.ino @@ -0,0 +1,34 @@ +#include +#include + +#define SPIDEVICE_CS 10 +Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice(SPIDEVICE_CS); + +void setup() { + while (!Serial) { delay(10); } + Serial.begin(115200); + Serial.println("SPI device register test"); + + if (!spi_dev.begin()) { + Serial.println("Could not initialize SPI device"); + while (1); + } + + Adafruit_BusIO_Register id_reg = Adafruit_BusIO_Register(&spi_dev, 0x0F, ADDRBIT8_HIGH_TOREAD); + uint8_t id; + id_reg.read(&id); + Serial.print("ID register = 0x"); Serial.println(id, HEX); + + Adafruit_BusIO_Register thresh_reg = Adafruit_BusIO_Register(&spi_dev, 0x0C, ADDRBIT8_HIGH_TOREAD, 2, LSBFIRST); + uint16_t thresh; + thresh_reg.read(&thresh); + Serial.print("Initial threshold register = 0x"); Serial.println(thresh, HEX); + + thresh_reg.write(~thresh); + + Serial.print("Post threshold register = 0x"); Serial.println(thresh_reg.read(), HEX); +} + +void loop() { + +} \ No newline at end of file diff --git a/lib/Adafruit_BusIO/library.properties b/lib/Adafruit_BusIO/library.properties new file mode 100644 index 000000000..f63425a7d --- /dev/null +++ b/lib/Adafruit_BusIO/library.properties @@ -0,0 +1,9 @@ +name=Adafruit BusIO +version=1.0.10 +author=Adafruit +maintainer=Adafruit +sentence=This is a library for abstracting away UART, I2C and SPI interfacing +paragraph=This is a library for abstracting away UART, I2C and SPI interfacing +category=Signal Input/Output +url=https://github.com/adafruit/Adafruit_BusIO +architectures=* diff --git a/lib/Adafruit_SGP30-1.0.3/.github/ISSUE_TEMPLATE.md b/lib/Adafruit_MCP9808_Tasmota/.github/ISSUE_TEMPLATE.md old mode 100755 new mode 100644 similarity index 100% rename from lib/Adafruit_SGP30-1.0.3/.github/ISSUE_TEMPLATE.md rename to lib/Adafruit_MCP9808_Tasmota/.github/ISSUE_TEMPLATE.md diff --git a/lib/Adafruit_SGP30-1.0.3/.github/PULL_REQUEST_TEMPLATE.md b/lib/Adafruit_MCP9808_Tasmota/.github/PULL_REQUEST_TEMPLATE.md old mode 100755 new mode 100644 similarity index 100% rename from lib/Adafruit_SGP30-1.0.3/.github/PULL_REQUEST_TEMPLATE.md rename to lib/Adafruit_MCP9808_Tasmota/.github/PULL_REQUEST_TEMPLATE.md diff --git a/lib/Adafruit_MCP9808_Tasmota/.github/workflows/githubci.yml b/lib/Adafruit_MCP9808_Tasmota/.github/workflows/githubci.yml new file mode 100644 index 000000000..cb226da94 --- /dev/null +++ b/lib/Adafruit_MCP9808_Tasmota/.github/workflows/githubci.yml @@ -0,0 +1,32 @@ +name: Arduino Library CI + +on: [pull_request, push, repository_dispatch] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/setup-python@v1 + with: + python-version: '3.x' + - uses: actions/checkout@v2 + - uses: actions/checkout@v2 + with: + repository: adafruit/ci-arduino + path: ci + + - name: pre-install + run: bash ci/actions_install.sh + + - name: test platforms + run: python3 ci/build_platform.py main_platforms + + - name: clang + run: python3 ci/run-clang-format.py -e "ci/*" -e "bin/*" -r . + + - name: doxygen + env: + GH_REPO_TOKEN: ${{ secrets.GH_REPO_TOKEN }} + PRETTYNAME : "Adafruit MCP9808 Arduino Library" + run: bash ci/doxy_gen_and_deploy.sh diff --git a/lib/Adafruit_MCP9808_Tasmota/.gitignore b/lib/Adafruit_MCP9808_Tasmota/.gitignore new file mode 100644 index 000000000..542d266a9 --- /dev/null +++ b/lib/Adafruit_MCP9808_Tasmota/.gitignore @@ -0,0 +1,8 @@ +# osx +.DS_Store + +# doxygen +Doxyfile* +doxygen_sqlite3.db +html +*.tmp diff --git a/lib/Adafruit_MCP9808_Tasmota/Adafruit_MCP9808.cpp b/lib/Adafruit_MCP9808_Tasmota/Adafruit_MCP9808.cpp new file mode 100644 index 000000000..db3fa9f86 --- /dev/null +++ b/lib/Adafruit_MCP9808_Tasmota/Adafruit_MCP9808.cpp @@ -0,0 +1,273 @@ +/*! + * @file Adafruit_MCP9808.cpp + * + * @mainpage Adafruit MCP9808 I2C Temp Sensor + * + * @section intro_sec Introduction + * + * I2C Driver for Microchip's MCP9808 I2C Temp sensor + * + * This is a library for the Adafruit MCP9808 breakout: + * http://www.adafruit.com/products/1782 + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing products from + * Adafruit! + * + * @section author Author + * + * K.Townsend (Adafruit Industries) + * + * @section license License + * + * BSD (see license.txt) + * + * @section HISTORY + * + * v1.0 - First release + * + * changes by Martin Wagner for tasmota project: + * + * - the libary supports variabel I2C address + * + */ + +#if ARDUINO >= 100 +#include "Arduino.h" +#else +#include "WProgram.h" +#endif + +#ifdef __AVR_ATtiny85__ +#include "TinyWireM.h" +#define Wire TinyWireM +#else +#include +#endif + +#include "Adafruit_MCP9808.h" + +/*! + * @brief Instantiates a new MCP9808 class + */ +Adafruit_MCP9808::Adafruit_MCP9808() {} + +/*! + * @brief Setups the HW + * @param *theWire + * @return True if initialization was successful, otherwise false. + */ +bool Adafruit_MCP9808::begin(TwoWire *theWire) { + _wire = theWire; + _i2caddr = MCP9808_I2CADDR_DEFAULT; + return init(); +} + +/*! + * @brief Setups the HW + * @param addr + * @return True if initialization was successful, otherwise false. + */ +bool Adafruit_MCP9808::begin(uint8_t addr) { + _i2caddr = addr; + _wire = &Wire; + return init(); +} + +/*! + * @brief Setups the HW + * @param addr + * @param *theWire + * @return True if initialization was successful, otherwise false. + */ +bool Adafruit_MCP9808::begin(uint8_t addr, TwoWire *theWire) { + _i2caddr = addr; + _wire = theWire; + return init(); +} + +/*! + * @brief Setups the HW with default address + * @return True if initialization was successful, otherwise false. + */ +bool Adafruit_MCP9808::begin() { + _i2caddr = MCP9808_I2CADDR_DEFAULT; + _wire = &Wire; + return init(); +} + +/*! + * @brief init function + * @return True if initialization was successful, otherwise false. + */ +bool Adafruit_MCP9808::init() { + _wire->begin(); + + if (read16(MCP9808_REG_MANUF_ID) != 0x0054) + return false; + if (read16(MCP9808_REG_DEVICE_ID) != 0x0400) + return false; + + write16(MCP9808_REG_CONFIG, 0x0); + return true; +} + +/*! + * @brief Reads the 16-bit temperature register and returns the Centigrade + * temperature as a float. + * @return Temperature in Centigrade. + */ +float Adafruit_MCP9808::readTempC(uint8_t addr) { + _i2caddr = addr; + float temp = NAN; + uint16_t t = read16(MCP9808_REG_AMBIENT_TEMP); + + if (t != 0xFFFF) { + temp = t & 0x0FFF; + temp /= 16.0; + if (t & 0x1000) + temp -= 256; + } + + return temp; +} + +/*! + * @brief Reads the 16-bit temperature register and returns the Fahrenheit + * temperature as a float. + * @return Temperature in Fahrenheit. + */ +float Adafruit_MCP9808::readTempF(uint8_t addr) { + _i2caddr = addr; + float temp = NAN; + uint16_t t = read16(MCP9808_REG_AMBIENT_TEMP); + + if (t != 0xFFFF) { + temp = t & 0x0FFF; + temp /= 16.0; + if (t & 0x1000) + temp -= 256; + + temp = temp * 9.0 / 5.0 + 32; + } + + return temp; +} + +/*! + * @brief Set Sensor to Shutdown-State or wake up (Conf_Register BIT8) + * @param sw true = shutdown / false = wakeup + */ +void Adafruit_MCP9808::shutdown_wake(uint8_t addr, boolean sw) { + _i2caddr = addr; + uint16_t conf_shutdown; + uint16_t conf_register = read16(MCP9808_REG_CONFIG); + if (sw == true) { + conf_shutdown = conf_register | MCP9808_REG_CONFIG_SHUTDOWN; + write16(MCP9808_REG_CONFIG, conf_shutdown); + } + if (sw == false) { + conf_shutdown = conf_register & ~MCP9808_REG_CONFIG_SHUTDOWN; + write16(MCP9808_REG_CONFIG, conf_shutdown); + } +} + +/*! + * @brief Shutdown MCP9808 + */ +void Adafruit_MCP9808::shutdown(uint8_t addr) { shutdown_wake(addr, true); } + +/*! + * @brief Wake up MCP9808 + */ +void Adafruit_MCP9808::wake(uint8_t addr) { + shutdown_wake(addr, false); + delay(250); +} + +/*! + * @brief Get Resolution Value + * @return Resolution value + */ +uint8_t Adafruit_MCP9808::getResolution(uint8_t addr) { + _i2caddr = addr; + return read8(MCP9808_REG_RESOLUTION); +} + +/*! + * @brief Set Resolution Value + * @param value + */ +void Adafruit_MCP9808::setResolution(uint8_t addr, uint8_t value) { + _i2caddr = addr; + write8(MCP9808_REG_RESOLUTION, value & 0x03); +} + +/*! + * @brief Low level 16 bit write procedures + * @param reg + * @param value + */ +void Adafruit_MCP9808::write16(uint8_t reg, uint16_t value) { + _wire->beginTransmission(_i2caddr); + _wire->write((uint8_t)reg); + _wire->write(value >> 8); + _wire->write(value & 0xFF); + _wire->endTransmission(); +} + +/*! + * @brief Low level 16 bit read procedure + * @param reg + * @return value + */ +uint16_t Adafruit_MCP9808::read16(uint8_t reg) { + uint16_t val = 0xFFFF; + uint8_t state; + + _wire->beginTransmission(_i2caddr); + _wire->write((uint8_t)reg); + state = _wire->endTransmission(); + + if (state == 0) { + _wire->requestFrom((uint8_t)_i2caddr, (uint8_t)2); + val = _wire->read(); + val <<= 8; + val |= _wire->read(); + } + + return val; +} + +/*! + * @brief Low level 8 bit write procedure + * @param reg + * @param value + */ +void Adafruit_MCP9808::write8(uint8_t reg, uint8_t value) { + _wire->beginTransmission(_i2caddr); + _wire->write((uint8_t)reg); + _wire->write(value); + _wire->endTransmission(); +} + +/*! + * @brief Low level 8 bit read procedure + * @param reg + * @return value + */ +uint8_t Adafruit_MCP9808::read8(uint8_t reg) { + uint8_t val = 0xFF; + uint8_t state; + + _wire->beginTransmission(_i2caddr); + _wire->write((uint8_t)reg); + state = _wire->endTransmission(); + + if (state == 0) { + _wire->requestFrom((uint8_t)_i2caddr, (uint8_t)1); + val = _wire->read(); + } + + return val; +} diff --git a/lib/Adafruit_MCP9808_Tasmota/Adafruit_MCP9808.h b/lib/Adafruit_MCP9808_Tasmota/Adafruit_MCP9808.h new file mode 100644 index 000000000..c93351ca1 --- /dev/null +++ b/lib/Adafruit_MCP9808_Tasmota/Adafruit_MCP9808.h @@ -0,0 +1,87 @@ +/*! + * @file Adafruit_MCP9808.h + * + * I2C Driver for Microchip's MCP9808 I2C Temp sensor + * + * This is a library for the Adafruit MCP9808 breakout: + * http://www.adafruit.com/products/1782 + * + * Adafruit invests time and resources providing this open source code, + *please support Adafruit and open-source hardware by purchasing products from + * Adafruit! + * + * + * BSD license (see license.txt) + * + * changes by Martin Wagner for tasmota project: + * + * - the libary supports variabel I2C address + * + */ + +#ifndef _ADAFRUIT_MCP9808_H +#define _ADAFRUIT_MCP9808_H + +#if ARDUINO >= 100 +#include "Arduino.h" +#else +#include "WProgram.h" +#endif + +#include + +#define MCP9808_I2CADDR_DEFAULT 0x18 ///< I2C address +#define MCP9808_REG_CONFIG 0x01 ///< MCP9808 config register + +#define MCP9808_REG_CONFIG_SHUTDOWN 0x0100 ///< shutdown config +#define MCP9808_REG_CONFIG_CRITLOCKED 0x0080 ///< critical trip lock +#define MCP9808_REG_CONFIG_WINLOCKED 0x0040 ///< alarm window lock +#define MCP9808_REG_CONFIG_INTCLR 0x0020 ///< interrupt clear +#define MCP9808_REG_CONFIG_ALERTSTAT 0x0010 ///< alert output status +#define MCP9808_REG_CONFIG_ALERTCTRL 0x0008 ///< alert output control +#define MCP9808_REG_CONFIG_ALERTSEL 0x0004 ///< alert output select +#define MCP9808_REG_CONFIG_ALERTPOL 0x0002 ///< alert output polarity +#define MCP9808_REG_CONFIG_ALERTMODE 0x0001 ///< alert output mode + +#define MCP9808_REG_UPPER_TEMP 0x02 ///< upper alert boundary +#define MCP9808_REG_LOWER_TEMP 0x03 ///< lower alert boundery +#define MCP9808_REG_CRIT_TEMP 0x04 ///< critical temperature +#define MCP9808_REG_AMBIENT_TEMP 0x05 ///< ambient temperature +#define MCP9808_REG_MANUF_ID 0x06 ///< manufacture ID +#define MCP9808_REG_DEVICE_ID 0x07 ///< device ID +#define MCP9808_REG_RESOLUTION 0x08 ///< resolutin + +/*! + * @brief Class that stores state and functions for interacting with + * MCP9808 Temp Sensor + */ +class Adafruit_MCP9808 { +public: + Adafruit_MCP9808(); + bool begin(); + bool begin(TwoWire *theWire); + bool begin(uint8_t addr); + bool begin(uint8_t addr, TwoWire *theWire); + + bool init(); + float readTempC(uint8_t addr); + float readTempF(uint8_t addr); + uint8_t getResolution(uint8_t addr); + void setResolution(uint8_t addr, uint8_t value); + + void shutdown_wake(uint8_t addr, boolean sw); + void shutdown(uint8_t addr); + void wake(uint8_t addr); + + void write16(uint8_t reg, uint16_t val); + uint16_t read16(uint8_t reg); + + void write8(uint8_t reg, uint8_t val); + uint8_t read8(uint8_t reg); + +private: + TwoWire *_wire; + uint8_t _i2caddr; +}; + +#endif diff --git a/lib/Adafruit_MCP9808_Tasmota/README.md b/lib/Adafruit_MCP9808_Tasmota/README.md new file mode 100644 index 000000000..0623f214f --- /dev/null +++ b/lib/Adafruit_MCP9808_Tasmota/README.md @@ -0,0 +1,18 @@ +# Adafruit MCP9808 Library [![Build Status](https://github.com/adafruit/Adafruit_MCP9808_Library/workflows/Arduino%20Library%20CI/badge.svg)](https://github.com/adafruit/Adafruit_MCP9808_Library/actions)[![Documentation](https://github.com/adafruit/ci-arduino/blob/master/assets/doxygen_badge.svg)](http://adafruit.github.io/Adafruit_MCP9808_Library/html/index.html) + + + +This is the Adafruit MCP9808 Precision I2C Temperature sensor library + +Tested and works great with the Adafruit MCP9808 Breakout Board +* http://www.adafruit.com/products/1782 + +This chip uses I2C to communicate, 2 pins are required to interface + +Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit! + +Written by Kevin Townsend/Limor Fried for Adafruit Industries. +BSD license, check license.txt for more information +All text above must be included in any redistribution + +To install, use the Arduino Library Manager and search for "Adafruit MCP9808" and install the library. diff --git a/lib/Adafruit_MCP9808_Tasmota/assets/board.jpg b/lib/Adafruit_MCP9808_Tasmota/assets/board.jpg new file mode 100644 index 000000000..69644e1c5 Binary files /dev/null and b/lib/Adafruit_MCP9808_Tasmota/assets/board.jpg differ diff --git a/lib/Adafruit_MCP9808_Tasmota/code-of-conduct.md b/lib/Adafruit_MCP9808_Tasmota/code-of-conduct.md new file mode 100644 index 000000000..8ee6e4498 --- /dev/null +++ b/lib/Adafruit_MCP9808_Tasmota/code-of-conduct.md @@ -0,0 +1,127 @@ +# Adafruit Community Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and leaders pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, gender identity and expression, level or type of +experience, education, socio-economic status, nationality, personal appearance, +race, religion, or sexual identity and orientation. + +## Our Standards + +We are committed to providing a friendly, safe and welcoming environment for +all. + +Examples of behavior that contributes to creating a positive environment +include: + +* Be kind and courteous to others +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Collaborating with other community members +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and sexual attention or advances +* The use of inappropriate images, including in a community member's avatar +* The use of inappropriate language, including in a community member's nickname +* Any spamming, flaming, baiting or other attention-stealing behavior +* Excessive or unwelcome helping; answering outside the scope of the question + asked +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate + +The goal of the standards and moderation guidelines outlined here is to build +and maintain a respectful community. We ask that you don’t just aim to be +"technically unimpeachable", but rather try to be your best self. + +We value many things beyond technical expertise, including collaboration and +supporting others within our community. Providing a positive experience for +other community members can have a much more significant impact than simply +providing the correct answer. + +## Our Responsibilities + +Project leaders are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project leaders have the right and responsibility to remove, edit, or +reject messages, comments, commits, code, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any community member for other behaviors that they deem +inappropriate, threatening, offensive, or harmful. + +## Moderation + +Instances of behaviors that violate the Adafruit Community Code of Conduct +may be reported by any member of the community. Community members are +encouraged to report these situations, including situations they witness +involving other community members. + +You may report in the following ways: + +In any situation, you may send an email to . + +On the Adafruit Discord, you may send an open message from any channel +to all Community Helpers by tagging @community helpers. You may also send an +open message from any channel, or a direct message to @kattni#1507, +@tannewt#4653, @Dan Halbert#1614, @cater#2442, @sommersoft#0222, or +@Andon#8175. + +Email and direct message reports will be kept confidential. + +In situations on Discord where the issue is particularly egregious, possibly +illegal, requires immediate action, or violates the Discord terms of service, +you should also report the message directly to Discord. + +These are the steps for upholding our community’s standards of conduct. + +1. Any member of the community may report any situation that violates the +Adafruit Community Code of Conduct. All reports will be reviewed and +investigated. +2. If the behavior is an egregious violation, the community member who +committed the violation may be banned immediately, without warning. +3. Otherwise, moderators will first respond to such behavior with a warning. +4. Moderators follow a soft "three strikes" policy - the community member may +be given another chance, if they are receptive to the warning and change their +behavior. +5. If the community member is unreceptive or unreasonable when warned by a +moderator, or the warning goes unheeded, they may be banned for a first or +second offense. Repeated offenses will result in the community member being +banned. + +## Scope + +This Code of Conduct and the enforcement policies listed above apply to all +Adafruit Community venues. This includes but is not limited to any community +spaces (both public and private), the entire Adafruit Discord server, and +Adafruit GitHub repositories. Examples of Adafruit Community spaces include +but are not limited to meet-ups, audio chats on the Adafruit Discord, or +interaction at a conference. + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. As a community +member, you are representing our community, and are expected to behave +accordingly. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 1.4, available at +, +and the [Rust Code of Conduct](https://www.rust-lang.org/en-US/conduct.html). + +For other projects adopting the Adafruit Community Code of +Conduct, please contact the maintainers of those projects for enforcement. +If you wish to use this code of conduct for your own project, consider +explicitly mentioning your moderation policy or making a copy with your +own moderation policy so as to avoid confusion. diff --git a/lib/Adafruit_MCP9808_Tasmota/examples/mcp9808test/mcp9808test.ino b/lib/Adafruit_MCP9808_Tasmota/examples/mcp9808test/mcp9808test.ino new file mode 100644 index 000000000..6002487e9 --- /dev/null +++ b/lib/Adafruit_MCP9808_Tasmota/examples/mcp9808test/mcp9808test.ino @@ -0,0 +1,69 @@ + +/**************************************************************************/ +/*! +This is a demo for the Adafruit MCP9808 breakout +----> http://www.adafruit.com/products/1782 +Adafruit invests time and resources providing this open source code, +please support Adafruit and open-source hardware by purchasing +products from Adafruit! +*/ +/**************************************************************************/ + +#include +#include "Adafruit_MCP9808.h" + +// Create the MCP9808 temperature sensor object +Adafruit_MCP9808 tempsensor = Adafruit_MCP9808(); + +void setup() { + Serial.begin(9600); + while (!Serial); //waits for serial terminal to be open, necessary in newer arduino boards. + Serial.println("MCP9808 demo"); + + // Make sure the sensor is found, you can also pass in a different i2c + // address with tempsensor.begin(0x19) for example, also can be left in blank for default address use + // Also there is a table with all addres possible for this sensor, you can connect multiple sensors + // to the same i2c bus, just configure each sensor with a different address and define multiple objects for that + // A2 A1 A0 address + // 0 0 0 0x18 this is the default address + // 0 0 1 0x19 + // 0 1 0 0x1A + // 0 1 1 0x1B + // 1 0 0 0x1C + // 1 0 1 0x1D + // 1 1 0 0x1E + // 1 1 1 0x1F + if (!tempsensor.begin(0x18)) { + Serial.println("Couldn't find MCP9808! Check your connections and verify the address is correct."); + while (1); + } + + Serial.println("Found MCP9808!"); + + tempsensor.setResolution(3); // sets the resolution mode of reading, the modes are defined in the table bellow: + // Mode Resolution SampleTime + // 0 0.5°C 30 ms + // 1 0.25°C 65 ms + // 2 0.125°C 130 ms + // 3 0.0625°C 250 ms +} + +void loop() { + Serial.println("wake up MCP9808.... "); // wake up MCP9808 - power consumption ~200 mikro Ampere + tempsensor.wake(); // wake up, ready to read! + + // Read and print out the temperature, also shows the resolution mode used for reading. + Serial.print("Resolution in mode: "); + Serial.println (tempsensor.getResolution()); + float c = tempsensor.readTempC(); + float f = tempsensor.readTempF(); + Serial.print("Temp: "); + Serial.print(c, 4); Serial.print("*C\t and "); + Serial.print(f, 4); Serial.println("*F."); + + delay(2000); + Serial.println("Shutdown MCP9808.... "); + tempsensor.shutdown_wake(1); // shutdown MSP9808 - power consumption ~0.1 mikro Ampere, stops temperature sampling + Serial.println(""); + delay(200); +} diff --git a/lib/Adafruit_MCP9808_Tasmota/library.properties b/lib/Adafruit_MCP9808_Tasmota/library.properties new file mode 100644 index 000000000..3c4ee86ce --- /dev/null +++ b/lib/Adafruit_MCP9808_Tasmota/library.properties @@ -0,0 +1,10 @@ +name=Adafruit MCP9808 Library +version=1.1.2 +author=Adafruit +maintainer=Adafruit +sentence=Arduino library for the MCP9808 sensors in the Adafruit shop +paragraph=Arduino library for the MCP9808 sensors in the Adafruit shop +category=Sensors +url=https://github.com/adafruit/Adafruit_MCP9808_Library +architectures=* +depends=Adafruit Unified Sensor diff --git a/lib/Adafruit_SGP30-1.0.3/license.txt b/lib/Adafruit_MCP9808_Tasmota/license.txt old mode 100755 new mode 100644 similarity index 100% rename from lib/Adafruit_SGP30-1.0.3/license.txt rename to lib/Adafruit_MCP9808_Tasmota/license.txt diff --git a/lib/Adafruit_SGP30-1.0.3/.gitignore b/lib/Adafruit_SGP30-1.0.3/.gitignore deleted file mode 100755 index 7f189125f..000000000 --- a/lib/Adafruit_SGP30-1.0.3/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -*~ -Doxyfile* -doxygen_sqlite3.db -html \ No newline at end of file diff --git a/lib/Adafruit_SGP30-1.0.3/Adafruit_SGP30.cpp b/lib/Adafruit_SGP30-1.0.3/Adafruit_SGP30.cpp deleted file mode 100755 index ce6116863..000000000 --- a/lib/Adafruit_SGP30-1.0.3/Adafruit_SGP30.cpp +++ /dev/null @@ -1,267 +0,0 @@ -/*! - * @file Adafruit_SGP30.cpp - * - * @mainpage Adafruit SGP30 gas sensor driver - * - * @section intro_sec Introduction - * - * This is the documentation for Adafruit's SGP30 driver for the - * Arduino platform. It is designed specifically to work with the - * Adafruit SGP30 breakout: http://www.adafruit.com/products/3709 - * - * These sensors use I2C to communicate, 2 pins (SCL+SDA) are required - * to interface with the breakout. - * - * Adafruit invests time and resources providing this open source code, - * please support Adafruit and open-source hardware by purchasing - * products from Adafruit! - * - * - * @section author Author - * Written by Ladyada for Adafruit Industries. - * - * @section license License - * BSD license, all text here must be included in any redistribution. - * - */ - - -#if ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif - -#include "Adafruit_SGP30.h" - -//#define I2C_DEBUG - -/**************************************************************************/ -/*! - @brief Instantiates a new SGP30 class -*/ -/**************************************************************************/ -Adafruit_SGP30::Adafruit_SGP30() { -} - -/**************************************************************************/ -/*! - @brief Setups the hardware and detects a valid SGP30. Initializes I2C - then reads the serialnumber and checks that we are talking to an SGP30 - @param theWire Optional pointer to I2C interface, otherwise use Wire - @returns True if SGP30 found on I2C, False if something went wrong! -*/ -/**************************************************************************/ -boolean Adafruit_SGP30::begin(TwoWire *theWire) { - _i2caddr = SGP30_I2CADDR_DEFAULT; - if (theWire == NULL) { - _i2c = &Wire; - } else { - _i2c = theWire; - } - -// assume i2c initialized already to avoid resetting clock stretching -// _i2c->begin(); - - - uint8_t command[2]; - command[0] = 0x36; - command[1] = 0x82; - if (! readWordFromCommand(command, 2, 10, serialnumber, 3)) - return false; - - uint16_t featureset; - command[0] = 0x20; - command[1] = 0x2F; - if (! readWordFromCommand(command, 2, 10, &featureset, 1)) - return false; - //Serial.print("Featureset 0x"); Serial.println(featureset, HEX); - if (featureset != SGP30_FEATURESET) - return false; - if (! IAQinit()) - return false; - - return true; -} - -/**************************************************************************/ -/*! - @brief Commands the sensor to begin the IAQ algorithm. Must be called after startup. - @returns True if command completed successfully, false if something went wrong! -*/ -/**************************************************************************/ -boolean Adafruit_SGP30::IAQinit(void) { - uint8_t command[2]; - command[0] = 0x20; - command[1] = 0x03; - return readWordFromCommand(command, 2, 10); -} - -/**************************************************************************/ -/*! - @brief Commands the sensor to take a single eCO2/VOC measurement. Places results in {@link TVOC} and {@link eCO2} - @returns True if command completed successfully, false if something went wrong! -*/ -/**************************************************************************/ -boolean Adafruit_SGP30::IAQmeasure(void) { - uint8_t command[2]; - command[0] = 0x20; - command[1] = 0x08; - uint16_t reply[2]; - if (! readWordFromCommand(command, 2, 12, reply, 2)) - return false; - TVOC = reply[1]; - eCO2 = reply[0]; - return true; -} - -/**************************************************************************/ -/*! - @brief Request baseline calibration values for both CO2 and TVOC IAQ calculations. Places results in parameter memory locaitons. - @param eco2_base A pointer to a uint16_t which we will save the calibration value to - @param tvoc_base A pointer to a uint16_t which we will save the calibration value to - @returns True if command completed successfully, false if something went wrong! -*/ -/**************************************************************************/ -boolean Adafruit_SGP30::getIAQBaseline(uint16_t *eco2_base, uint16_t *tvoc_base) { - uint8_t command[2]; - command[0] = 0x20; - command[1] = 0x15; - uint16_t reply[2]; - if (! readWordFromCommand(command, 2, 10, reply, 2)) - return false; - *eco2_base = reply[0]; - *tvoc_base = reply[1]; - return true; -} - -/**************************************************************************/ -/*! - @brief Assign baseline calibration values for both CO2 and TVOC IAQ calculations. - @param eco2_base A uint16_t which we will save the calibration value from - @param tvoc_base A uint16_t which we will save the calibration value from - @returns True if command completed successfully, false if something went wrong! -*/ -/**************************************************************************/ -boolean Adafruit_SGP30::setIAQBaseline(uint16_t eco2_base, uint16_t tvoc_base) { - uint8_t command[8]; - command[0] = 0x20; - command[1] = 0x1e; - command[2] = tvoc_base >> 8; - command[3] = tvoc_base & 0xFF; - command[4] = generateCRC(command+2, 2); - command[5] = eco2_base >> 8; - command[6] = eco2_base & 0xFF; - command[7] = generateCRC(command+5, 2); - - return readWordFromCommand(command, 8, 10); -} - -/**************************************************************************/ -/*! - @brief Set the absolute humidity value [mg/m^3] for compensation to increase precision of TVOC and eCO2. - @param absolute_humidity A uint32_t [mg/m^3] which we will be used for compensation. If the absolute humidity is set to zero, humidity compensation will be disabled. - @returns True if command completed successfully, false if something went wrong! -*/ -/**************************************************************************/ -boolean Adafruit_SGP30::setHumidity(uint32_t absolute_humidity) { - if (absolute_humidity > 256000) { - return false; - } - - uint16_t ah_scaled = (uint16_t)(((uint64_t)absolute_humidity * 256 * 16777) >> 24); - uint8_t command[5]; - command[0] = 0x20; - command[1] = 0x61; - command[2] = ah_scaled >> 8; - command[3] = ah_scaled & 0xFF; - command[4] = generateCRC(command+2, 2); - - return readWordFromCommand(command, 5, 10); -} - -/**************************************************************************/ -/*! - @brief I2C low level interfacing -*/ -/**************************************************************************/ - - -boolean Adafruit_SGP30::readWordFromCommand(uint8_t command[], uint8_t commandLength, uint16_t delayms, uint16_t *readdata, uint8_t readlen) -{ - uint8_t data; - - _i2c->beginTransmission(_i2caddr); - -#ifdef I2C_DEBUG - Serial.print("\t\t-> "); -#endif - - for (uint8_t i=0; iwrite(command[i]); -#ifdef I2C_DEBUG - Serial.print("0x"); Serial.print(command[i], HEX); Serial.print(", "); -#endif - } -#ifdef I2C_DEBUG - Serial.println(); -#endif - _i2c->endTransmission(); - - delay(delayms); - - if (readlen == 0) - return true; - - uint8_t replylen = readlen * (SGP30_WORD_LEN +1); - if (_i2c->requestFrom(_i2caddr, replylen) != replylen) - return false; - uint8_t replybuffer[replylen]; -#ifdef I2C_DEBUG - Serial.print("\t\t<- "); -#endif - for (uint8_t i=0; iread(); -#ifdef I2C_DEBUG - Serial.print("0x"); Serial.print(replybuffer[i], HEX); Serial.print(", "); -#endif - } - -#ifdef I2C_DEBUG - Serial.println(); -#endif - - for (uint8_t i=0; i - -// the i2c address -#define SGP30_I2CADDR_DEFAULT 0x58 ///< SGP30 has only one I2C address - -// commands and constants -#define SGP30_FEATURESET 0x0020 ///< The required set for this library -#define SGP30_CRC8_POLYNOMIAL 0x31 ///< Seed for SGP30's CRC polynomial -#define SGP30_CRC8_INIT 0xFF ///< Init value for CRC -#define SGP30_WORD_LEN 2 ///< 2 bytes per word - -/**************************************************************************/ -/*! Class that stores state and functions for interacting with SGP30 Gas Sensor */ -/**************************************************************************/ -class Adafruit_SGP30 { - public: - Adafruit_SGP30(); - boolean begin(TwoWire *theWire = NULL); - boolean IAQinit(void); - boolean IAQmeasure(void); - - boolean getIAQBaseline(uint16_t *eco2_base, uint16_t *tvoc_base); - boolean setIAQBaseline(uint16_t eco2_base, uint16_t tvoc_base); - boolean setHumidity(uint32_t absolute_humidity); - - /** - * The last measurement of the IAQ-calculated Total Volatile Organic Compounds in ppb. This value is set when you call {@link IAQmeasure()} - */ - uint16_t TVOC; - - /** - * The last measurement of the IAQ-calculated equivalent CO2 in ppm. This value is set when you call {@link IAQmeasure()} - */ - uint16_t eCO2; - - /** - * The 48-bit serial number, this value is set when you call {@link begin()} - */ - uint16_t serialnumber[3]; - private: - TwoWire *_i2c; - uint8_t _i2caddr; - - void write(uint8_t address, uint8_t *data, uint8_t n); - void read(uint8_t address, uint8_t *data, uint8_t n); - boolean readWordFromCommand(uint8_t command[], uint8_t commandLength, uint16_t delay, uint16_t *readdata = NULL, uint8_t readlen = 0); - uint8_t generateCRC(uint8_t data[], uint8_t datalen); -}; diff --git a/lib/Adafruit_SGP30-1.0.3/README.md b/lib/Adafruit_SGP30-1.0.3/README.md deleted file mode 100755 index 44056b5c8..000000000 --- a/lib/Adafruit_SGP30-1.0.3/README.md +++ /dev/null @@ -1,18 +0,0 @@ -Adafruit_SGP30 -================ - -This is the Adafruit SGP30 Gas / Air Quality I2C sensor library - -Tested and works great with the Aadafruit SGP30 Breakout Board - * http://www.adafruit.com/products/3709 - -This chip uses I2C to communicate, 2 pins are required to interface - -Adafruit invests time and resources providing this open source code, -please support Adafruit and open-source hardware by purchasing -products from Adafruit! - -Written by Limor Fried for Adafruit Industries. -BSD license, check license.txt for more information -All text above must be included in any redistribution - diff --git a/lib/Adafruit_SGP30-1.2.0/Adafruit_SGP30.cpp b/lib/Adafruit_SGP30-1.2.0/Adafruit_SGP30.cpp new file mode 100644 index 000000000..936561ede --- /dev/null +++ b/lib/Adafruit_SGP30-1.2.0/Adafruit_SGP30.cpp @@ -0,0 +1,306 @@ +/*! + * @file Adafruit_SGP30.cpp + * + * @mainpage Adafruit SGP30 gas sensor driver + * + * @section intro_sec Introduction + * + * This is the documentation for Adafruit's SGP30 driver for the + * Arduino platform. It is designed specifically to work with the + * Adafruit SGP30 breakout: http://www.adafruit.com/products/3709 + * + * These sensors use I2C to communicate, 2 pins (SCL+SDA) are required + * to interface with the breakout. + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * + * @section author Author + * Written by Ladyada for Adafruit Industries. + * + * @section license License + * BSD license, all text here must be included in any redistribution. + * + */ + +#include "Arduino.h" + +#include "Adafruit_SGP30.h" +//#define I2C_DEBUG + +/*! + * @brief Instantiates a new SGP30 class + */ +Adafruit_SGP30::Adafruit_SGP30() {} + +/*! + * @brief Setups the hardware and detects a valid SGP30. Initializes I2C + * then reads the serialnumber and checks that we are talking to an + * SGP30 + * @param theWire + * Optional pointer to I2C interface, otherwise use Wire + * @param initSensor + * Optional pointer to prevent IAQinit to be called. Used for Deep + * Sleep. + * @return True if SGP30 found on I2C, False if something went wrong! + */ +boolean Adafruit_SGP30::begin(TwoWire *theWire, boolean initSensor) { + _i2caddr = SGP30_I2CADDR_DEFAULT; + _i2c = theWire; + + _i2c->begin(); + + uint8_t command[2]; + command[0] = 0x36; + command[1] = 0x82; + if (!readWordFromCommand(command, 2, 10, serialnumber, 3)) + return false; + + uint16_t featureset; + command[0] = 0x20; + command[1] = 0x2F; + if (!readWordFromCommand(command, 2, 10, &featureset, 1)) + return false; + // Serial.print("Featureset 0x"); Serial.println(featureset, HEX); + if ((featureset & 0xF0) != SGP30_FEATURESET) + return false; + if (initSensor) { + if (!IAQinit()) + return false; + } + + return true; +} + +/*! + * @brief Commands the sensor to perform a soft reset using the "General + * Call" mode. Take note that this is not sensor specific and all devices that + * support the General Call mode on the on the same I2C bus will perform this. + * + * @return True if command completed successfully, false if something went + * wrong! + */ +boolean Adafruit_SGP30::softReset(void) { + uint8_t command[2]; + command[0] = 0x00; + command[1] = 0x06; + return readWordFromCommand(command, 2, 10); +} + +/*! + * @brief Commands the sensor to begin the IAQ algorithm. Must be called + * after startup. + * @returns True if command completed successfully, false if something went + * wrong! + */ +boolean Adafruit_SGP30::IAQinit(void) { + uint8_t command[2]; + command[0] = 0x20; + command[1] = 0x03; + return readWordFromCommand(command, 2, 10); +} + +/*! + * @brief Commands the sensor to take a single eCO2/VOC measurement. Places + * results in {@link TVOC} and {@link eCO2} + * @return True if command completed successfully, false if something went + * wrong! + */ +boolean Adafruit_SGP30::IAQmeasure(void) { + uint8_t command[2]; + command[0] = 0x20; + command[1] = 0x08; + uint16_t reply[2]; + if (!readWordFromCommand(command, 2, 12, reply, 2)) + return false; + TVOC = reply[1]; + eCO2 = reply[0]; + return true; +} + +/*! + * @brief Commands the sensor to take a single H2/ethanol raw measurement. + * Places results in {@link rawH2} and {@link rawEthanol} + * @returns True if command completed successfully, false if something went + * wrong! + */ +boolean Adafruit_SGP30::IAQmeasureRaw(void) { + uint8_t command[2]; + command[0] = 0x20; + command[1] = 0x50; + uint16_t reply[2]; + if (!readWordFromCommand(command, 2, 25, reply, 2)) + return false; + rawEthanol = reply[1]; + rawH2 = reply[0]; + return true; +} + +/*! + * @brief Request baseline calibration values for both CO2 and TVOC IAQ + * calculations. Places results in parameter memory locaitons. + * @param eco2_base + * A pointer to a uint16_t which we will save the calibration + * value to + * @param tvoc_base + * A pointer to a uint16_t which we will save the calibration value to + * @return True if command completed successfully, false if something went + * wrong! + */ +boolean Adafruit_SGP30::getIAQBaseline(uint16_t *eco2_base, + uint16_t *tvoc_base) { + uint8_t command[2]; + command[0] = 0x20; + command[1] = 0x15; + uint16_t reply[2]; + if (!readWordFromCommand(command, 2, 10, reply, 2)) + return false; + *eco2_base = reply[0]; + *tvoc_base = reply[1]; + return true; +} + +/*! + * @brief Assign baseline calibration values for both CO2 and TVOC IAQ + * calculations. + * @param eco2_base + * A uint16_t which we will save the calibration value from + * @param tvoc_base + * A uint16_t which we will save the calibration value from + * @return True if command completed successfully, false if something went + * wrong! + */ +boolean Adafruit_SGP30::setIAQBaseline(uint16_t eco2_base, uint16_t tvoc_base) { + uint8_t command[8]; + command[0] = 0x20; + command[1] = 0x1e; + command[2] = tvoc_base >> 8; + command[3] = tvoc_base & 0xFF; + command[4] = generateCRC(command + 2, 2); + command[5] = eco2_base >> 8; + command[6] = eco2_base & 0xFF; + command[7] = generateCRC(command + 5, 2); + + return readWordFromCommand(command, 8, 10); +} + +/*! + * @brief Set the absolute humidity value [mg/m^3] for compensation to + * increase precision of TVOC and eCO2. + * @param absolute_humidity + * A uint32_t [mg/m^3] which we will be used for compensation. + * If the absolute humidity is set to zero, humidity compensation + * will be disabled. + * @return True if command completed successfully, false if something went + * wrong! + */ +boolean Adafruit_SGP30::setHumidity(uint32_t absolute_humidity) { + if (absolute_humidity > 256000) { + return false; + } + + uint16_t ah_scaled = + (uint16_t)(((uint64_t)absolute_humidity * 256 * 16777) >> 24); + uint8_t command[5]; + command[0] = 0x20; + command[1] = 0x61; + command[2] = ah_scaled >> 8; + command[3] = ah_scaled & 0xFF; + command[4] = generateCRC(command + 2, 2); + + return readWordFromCommand(command, 5, 10); +} + +/*! + * @brief I2C low level interfacing + */ + +boolean Adafruit_SGP30::readWordFromCommand(uint8_t command[], + uint8_t commandLength, + uint16_t delayms, + uint16_t *readdata, + uint8_t readlen) { + + _i2c->beginTransmission(_i2caddr); + +#ifdef I2C_DEBUG + Serial.print("\t\t-> "); +#endif + + for (uint8_t i = 0; i < commandLength; i++) { + _i2c->write(command[i]); +#ifdef I2C_DEBUG + Serial.print("0x"); + Serial.print(command[i], HEX); + Serial.print(", "); +#endif + } +#ifdef I2C_DEBUG + Serial.println(); +#endif + _i2c->endTransmission(); + + delay(delayms); + + if (readlen == 0) + return true; + + uint8_t replylen = readlen * (SGP30_WORD_LEN + 1); + if (_i2c->requestFrom(_i2caddr, replylen) != replylen) + return false; + uint8_t replybuffer[replylen]; +#ifdef I2C_DEBUG + Serial.print("\t\t<- "); +#endif + for (uint8_t i = 0; i < replylen; i++) { + replybuffer[i] = _i2c->read(); +#ifdef I2C_DEBUG + Serial.print("0x"); + Serial.print(replybuffer[i], HEX); + Serial.print(", "); +#endif + } + +#ifdef I2C_DEBUG + Serial.println(); +#endif + + for (uint8_t i = 0; i < readlen; i++) { + uint8_t crc = generateCRC(replybuffer + i * 3, 2); +#ifdef I2C_DEBUG + Serial.print("\t\tCRC calced: 0x"); + Serial.print(crc, HEX); + Serial.print(" vs. 0x"); + Serial.println(replybuffer[i * 3 + 2], HEX); +#endif + if (crc != replybuffer[i * 3 + 2]) + return false; + // success! store it + readdata[i] = replybuffer[i * 3]; + readdata[i] <<= 8; + readdata[i] |= replybuffer[i * 3 + 1]; +#ifdef I2C_DEBUG + Serial.print("\t\tRead: 0x"); + Serial.println(readdata[i], HEX); +#endif + } + return true; +} + +uint8_t Adafruit_SGP30::generateCRC(uint8_t *data, uint8_t datalen) { + // calculates 8-Bit checksum with given polynomial + uint8_t crc = SGP30_CRC8_INIT; + + for (uint8_t i = 0; i < datalen; i++) { + crc ^= data[i]; + for (uint8_t b = 0; b < 8; b++) { + if (crc & 0x80) + crc = (crc << 1) ^ SGP30_CRC8_POLYNOMIAL; + else + crc <<= 1; + } + } + return crc; +} diff --git a/lib/Adafruit_SGP30-1.2.0/Adafruit_SGP30.h b/lib/Adafruit_SGP30-1.2.0/Adafruit_SGP30.h new file mode 100644 index 000000000..d50099e9d --- /dev/null +++ b/lib/Adafruit_SGP30-1.2.0/Adafruit_SGP30.h @@ -0,0 +1,80 @@ +/*! + * @file Adafruit_SGP30.h + * + * This is the documentation for Adafruit's SGP30 driver for the + * Arduino platform. It is designed specifically to work with the + * Adafruit SGP30 breakout: http://www.adafruit.com/products/3709 + * + * These sensors use I2C to communicate, 2 pins (SCL+SDA) are required + * to interface with the breakout. + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Written by Ladyada for Adafruit Industries. + * + * BSD license, all text here must be included in any redistribution. + * + */ + +#include "Arduino.h" +#include + +// the i2c address +#define SGP30_I2CADDR_DEFAULT 0x58 ///< SGP30 has only one I2C address + +// commands and constants +#define SGP30_FEATURESET 0x0020 ///< The required set for this library +#define SGP30_CRC8_POLYNOMIAL 0x31 ///< Seed for SGP30's CRC polynomial +#define SGP30_CRC8_INIT 0xFF ///< Init value for CRC +#define SGP30_WORD_LEN 2 ///< 2 bytes per word + +/*! + * @brief Class that stores state and functions for interacting with + * SGP30 Gas Sensor + */ +class Adafruit_SGP30 { +public: + Adafruit_SGP30(); + boolean begin(TwoWire *theWire = &Wire, boolean initSensor = true); + boolean softReset(); + boolean IAQinit(); + boolean IAQmeasure(); + boolean IAQmeasureRaw(); + + boolean getIAQBaseline(uint16_t *eco2_base, uint16_t *tvoc_base); + boolean setIAQBaseline(uint16_t eco2_base, uint16_t tvoc_base); + boolean setHumidity(uint32_t absolute_humidity); + + /** The last measurement of the IAQ-calculated Total Volatile Organic + * Compounds in ppb. This value is set when you call {@link IAQmeasure()} **/ + uint16_t TVOC; + + /** The last measurement of the IAQ-calculated equivalent CO2 in ppm. This + * value is set when you call {@link IAQmeasure()} **/ + uint16_t eCO2; + + /** The last measurement of the IAQ-calculated equivalent CO2 in ppm. This + * value is set when you call {@link IAQmeasureRaw()} **/ + uint16_t rawH2; + + /** The last measurement of the IAQ-calculated equivalent CO2 in ppm. This + * value is set when you call {@link IAQmeasureRaw()} **/ + uint16_t rawEthanol; + + /** The 48-bit serial number, this value is set when you call {@link begin()} + * **/ + uint16_t serialnumber[3]; + +private: + TwoWire *_i2c; + uint8_t _i2caddr; + + void write(uint8_t address, uint8_t *data, uint8_t n); + void read(uint8_t address, uint8_t *data, uint8_t n); + boolean readWordFromCommand(uint8_t command[], uint8_t commandLength, + uint16_t delay, uint16_t *readdata = NULL, + uint8_t readlen = 0); + uint8_t generateCRC(uint8_t data[], uint8_t datalen); +}; diff --git a/lib/Adafruit_SGP30-1.2.0/README.md b/lib/Adafruit_SGP30-1.2.0/README.md new file mode 100644 index 000000000..f4d35eeaa --- /dev/null +++ b/lib/Adafruit_SGP30-1.2.0/README.md @@ -0,0 +1,54 @@ +# Adafruit SGP30 Gas / Air Quality I2C sensor [[![Build Status](https://github.com/adafruit/Adafruit_SGP30/workflows/Arduino%20Library%20CI/badge.svg)](https://github.com/adafruit/Adafruit_SGP30/actions)[![Documentation](https://github.com/adafruit/ci-arduino/blob/master/assets/doxygen_badge.svg)](http://adafruit.github.io/Adafruit_SGP30/html/index.html) + + + +This is the Adafruit SGP30 Gas / Air Quality I2C sensor library + +Tested and works great with the Aadafruit SGP30 Breakout Board + * http://www.adafruit.com/products/3709 + +This chip uses I2C to communicate, 2 pins are required to interface + +Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit! + +# Installation +To install, use the Arduino Library Manager and search for "Adafruit SGP30" and install the library. + +## Dependencies + * [Adafruit ILI9341](https://github.com/adafruit/Adafruit_ILI9341) + * [Adafruit GFX Library](https://github.com/adafruit/Adafruit-GFX-Library) + +# Contributing + +Contributions are welcome! Please read our [Code of Conduct](https://github.com/adafruit/Adafruit_SGP30/blob/master/CODE_OF_CONDUCT.md>) +before contributing to help this project stay welcoming. + +## Documentation and doxygen +Documentation is produced by doxygen. Contributions should include documentation for any new code added. + +Some examples of how to use doxygen can be found in these guide pages: + +https://learn.adafruit.com/the-well-automated-arduino-library/doxygen + +https://learn.adafruit.com/the-well-automated-arduino-library/doxygen-tips + +## Formatting and clang-format +This library uses [`clang-format`](https://releases.llvm.org/download.html) to standardize the formatting of `.cpp` and `.h` files. +Contributions should be formatted using `clang-format`: + +The `-i` flag will make the changes to the file. +```bash +clang-format -i *.cpp *.h +``` +If you prefer to make the changes yourself, running `clang-format` without the `-i` flag will print out a formatted version of the file. You can save this to a file and diff it against the original to see the changes. + +Note that the formatting output by `clang-format` is what the automated formatting checker will expect. Any diffs from this formatting will result in a failed build until they are addressed. Using the `-i` flag is highly recommended. + +### clang-format resources + * [Binary builds and source available on the LLVM downloads page](https://releases.llvm.org/download.html) + * [Documentation and IDE integration](https://clang.llvm.org/docs/ClangFormat.html) + +## About this Driver +Written by Limor Fried for Adafruit Industries. +BSD license, check license.txt for more information +All text above must be included in any redistribution diff --git a/lib/Adafruit_SGP30-1.0.3/examples/sgp30test/sgp30test.ino b/lib/Adafruit_SGP30-1.2.0/examples/sgp30test/sgp30test.ino old mode 100755 new mode 100644 similarity index 89% rename from lib/Adafruit_SGP30-1.0.3/examples/sgp30test/sgp30test.ino rename to lib/Adafruit_SGP30-1.2.0/examples/sgp30test/sgp30test.ino index b7ff8a70c..fbfbf49d5 --- a/lib/Adafruit_SGP30-1.0.3/examples/sgp30test/sgp30test.ino +++ b/lib/Adafruit_SGP30-1.2.0/examples/sgp30test/sgp30test.ino @@ -44,6 +44,14 @@ void loop() { } Serial.print("TVOC "); Serial.print(sgp.TVOC); Serial.print(" ppb\t"); Serial.print("eCO2 "); Serial.print(sgp.eCO2); Serial.println(" ppm"); + + if (! sgp.IAQmeasureRaw()) { + Serial.println("Raw Measurement failed"); + return; + } + Serial.print("Raw H2 "); Serial.print(sgp.rawH2); Serial.print(" \t"); + Serial.print("Raw Ethanol "); Serial.print(sgp.rawEthanol); Serial.println(""); + delay(1000); counter++; @@ -58,4 +66,4 @@ void loop() { Serial.print("****Baseline values: eCO2: 0x"); Serial.print(eCO2_base, HEX); Serial.print(" & TVOC: 0x"); Serial.println(TVOC_base, HEX); } -} \ No newline at end of file +} diff --git a/lib/Adafruit_SGP30-1.0.3/library.properties b/lib/Adafruit_SGP30-1.2.0/library.properties old mode 100755 new mode 100644 similarity index 84% rename from lib/Adafruit_SGP30-1.0.3/library.properties rename to lib/Adafruit_SGP30-1.2.0/library.properties index 6c86464d1..5242ef25b --- a/lib/Adafruit_SGP30-1.0.3/library.properties +++ b/lib/Adafruit_SGP30-1.2.0/library.properties @@ -1,5 +1,5 @@ name=Adafruit SGP30 Sensor -version=1.0.3 +version=1.2.0 author=Adafruit maintainer=Adafruit sentence=This is an Arduino library for the Adafruit SGP30 Gas / Air Quality Sensor @@ -7,3 +7,4 @@ paragraph=This is an Arduino library for the Adafruit SGP30 Gas / Air Quality Se category=Sensors url=https://github.com/adafruit/Adafruit_SGP30 architectures=* +depends=Adafruit ILI9341, Adafruit GFX Library diff --git a/lib/Adafruit_SGP30-1.2.0/license.txt b/lib/Adafruit_SGP30-1.2.0/license.txt new file mode 100644 index 000000000..f6a0f22b8 --- /dev/null +++ b/lib/Adafruit_SGP30-1.2.0/license.txt @@ -0,0 +1,26 @@ +Software License Agreement (BSD License) + +Copyright (c) 2012, Adafruit Industries +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +1. Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +3. Neither the name of the copyright holders nor the +names of its contributors may be used to endorse or promote products +derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/lib/Adafruit_SGP30-1.0.3/.travis.yml b/lib/Adafruit_SGP30-1.2.0/travis.yml old mode 100755 new mode 100644 similarity index 100% rename from lib/Adafruit_SGP30-1.0.3/.travis.yml rename to lib/Adafruit_SGP30-1.2.0/travis.yml diff --git a/lib/Adafruit_SSD1351-gemu-1.0/SSD1351.cpp b/lib/Adafruit_SSD1351-gemu-1.0/SSD1351.cpp index 3e1ccb2c7..c822fe565 100644 --- a/lib/Adafruit_SSD1351-gemu-1.0/SSD1351.cpp +++ b/lib/Adafruit_SSD1351-gemu-1.0/SSD1351.cpp @@ -29,6 +29,8 @@ SSD1351::SSD1351(int8_t cs,int8_t mosi,int8_t sclk) : Renderer(SSD1351_WIDTH, SS _hwspi = 0; } +#ifndef ESP32 + #include "spi_register.h" /* CPU Clock = 80 Mhz @@ -189,84 +191,81 @@ void SSD1351::writedata(uint8_t d) { } -uint16_t SSD1351::GetColorFromIndex(uint8_t index) { - if (index>=sizeof(ssd1351_colors)/2) index=0; - return ssd1351_colors[index]; -} +void ICACHE_RAM_ATTR SSD1351::fastSPIwrite(uint8_t d,uint8_t dc) { -void SSD1351::DisplayInit(int8_t p,int8_t size,int8_t rot,int8_t font) { - setRotation(rot); - invertDisplay(false); - setTextWrap(false); // Allow text to run off edges - cp437(true); - setTextFont(font&3); - setTextSize(size&7); - setTextColor(SSD1351_WHITE,SSD1351_BLACK); - setCursor(0,0); - fillScreen(SSD1351_BLACK); - stop(); -} + WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<_cs); + WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<_sclk); + if(dc) WRITE_PERI_REG( PIN_OUT_SET, 1<<_mosi); + else WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<_mosi); + WRITE_PERI_REG( PIN_OUT_SET, 1<<_sclk); -void SSD1351::DisplayOnff(int8_t on) { - if (on) { - writecommand(SSD1351_CMD_DISPLAYON); //Display on - } else { - writecommand(SSD1351_CMD_DISPLAYOFF); + for(uint8_t bit = 0x80; bit; bit >>= 1) { + WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<_sclk); + if(d&bit) WRITE_PERI_REG( PIN_OUT_SET, 1<<_mosi); + else WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<_mosi); + WRITE_PERI_REG( PIN_OUT_SET, 1<<_sclk); } - stop(); + WRITE_PERI_REG( PIN_OUT_SET, 1<<_cs); } -// dimmer 0-100 -void SSD1351::dim(uint8_t contrast) { - writecommand(SSD1351_CMD_CONTRASTMASTER); - if (contrast>15) contrast=15; - writedata(contrast); - stop(); + +#else +// ESP32 section +uint8_t ssd131_start; + +void SSD1351::writedata(uint8_t d) { + fastSPIwrite(d,1); } -/* -if (SSD_COMSPLIT == 1){ - _remapReg |= ((1 << 5)); - } else { - _remapReg |= ((0 << 5)); - } - setRegister_cont(CMD_CMDLOCK,SSD_COMMANDLOCK1); - setRegister_cont(CMD_CMDLOCK,SSD_COMMANDLOCK2); - writecommand_cont(CMD_DISPLAYOFF); - setRegister_cont(CMD_CLOCKDIV,SSD_CLOCKDIV); - setRegister_cont(CMD_MUXRATIO,SSD_MUXRATIO); - setRegister_cont(CMD_STARTLINE,SSD_STARTLINE); >>> - setRegister_cont(CMD_DISPLAYOFFSET,SSD_DISPLAYOFFSET); - setRegister_cont(CMD_SETGPIO,SSD_SETGPIO); - setRegister_cont(CMD_FUNCTIONSELECT,SSD_FUNCTIONSELECT); - writecommand_cont(CMD_SETVSL); - writedata8_cont(SSD_SETVSL_A);writedata8_cont(SSD_SETVSL_B);writedata8_cont(SSD_SETVSL_C); - writecommand_cont(CMD_CONTRASTABC); - writedata8_cont(SSD_CONTRAST_A);writedata8_cont(SSD_CONTRAST_B);writedata8_cont(SSD_CONTRAST_C); - setRegister_cont(CMD_MASTERCURRENT,SSD_MASTERCURRENT); >>> - writecommand_cont(CMD_DISPLAYENHANCE); >> - if (SSD_ENHANCE){ - writedata8_cont(0xA4); - } else { - writedata8_cont(0x00); - } - writedata8_cont(0x00); - writedata8_cont(0x00); - #if defined(SSD_GAMMASET) - //writecommand_cont(CMD_GRAYSCALE); for (uint8_t i =0;i<32;i++){writedata8_cont(SSD_GRAYTABLE[i]);} - #else - writecommand_cont(CMD_USELUT); - #endif - // phase here - setRegister_cont(CMD_PRECHARGE,SSD_PRECHARGE); >> - setRegister_cont(CMD_PRECHARGE2,SSD_PRECHARGE2); - setRegister_cont(CMD_VCOMH,SSD_VCOMH); - #endif - //setAddrWindow_cont(0,0,SSD_WIDTH-1,SSD_HEIGHT-1,false);// ??? - //_pushColors_cont(_defaultBgColor, SSD_CGRAM);//??? - //Normal Display and turn ON - writecommand_cont(CMD_NORMALDISPLAY); -*/ +void SSD1351::writecommand(uint8_t c) { + fastSPIwrite(c,0); +} + +#include "soc/spi_reg.h" +#include "soc/spi_struct.h" +#include "esp32-hal-spi.h" +#include "esp32-hal.h" +#include "soc/spi_struct.h" + +SPISettings oled_spiSettings; + +// diconnect from spi +void SSD1351::start(void) { + if (ssd131_start) return; + SPI.beginTransaction(oled_spiSettings); + ssd131_start = 1; +} + +// reconnect to spi +void SSD1351::stop(void) { + if (!ssd131_start) return; + SPI.endTransaction(); + ssd131_start = 0; +} + +// since ardunio transferBits ia completely disfunctional +// we use our own hardware driver for 9 bit spi +void SSD1351::fastSPIwrite(uint8_t d,uint8_t dc) { + digitalWrite( _cs, LOW); + + uint32_t regvalue=d>>1; + if (dc) regvalue|=0x80; + else regvalue&=0x7f; + if (d&1) regvalue|=0x8000; + + REG_SET_BIT(SPI_USER_REG(3), SPI_USR_MOSI); + REG_WRITE(SPI_MOSI_DLEN_REG(3), 9 - 1); + uint32_t *dp=(uint32_t*)SPI_W0_REG(3); + *dp=regvalue; + REG_SET_BIT(SPI_CMD_REG(3), SPI_USR); + while (REG_GET_FIELD(SPI_CMD_REG(3), SPI_USR)); + + digitalWrite( _cs, HIGH); +} + +#endif + + static const uint8_t PROGMEM initList[] = { SSD1351_CMD_COMMANDLOCK, 1, // Set command lock, 1 arg 0x12, @@ -305,34 +304,30 @@ static const uint8_t PROGMEM initList[] = { 0 }; // END OF COMMAND LIST - void SSD1351::sendcommand(uint8_t commandByte, const uint8_t *dataBytes, uint8_t numDataBytes) { - writecommand(commandByte); - for (int i=0; i=sizeof(ssd1351_colors)/2) index=0; + return ssd1351_colors[index]; +} + +void SSD1351::DisplayInit(int8_t p,int8_t size,int8_t rot,int8_t font) { + setRotation(rot); + invertDisplay(false); + setTextWrap(false); // Allow text to run off edges + cp437(true); + setTextFont(font&3); + setTextSize(size&7); + setTextColor(SSD1351_WHITE,SSD1351_BLACK); + setCursor(0,0); + fillScreen(SSD1351_BLACK); + stop(); +} + +void SSD1351::DisplayOnff(int8_t on) { + if (on) { + writecommand(SSD1351_CMD_DISPLAYON); //Display on + } else { + writecommand(SSD1351_CMD_DISPLAYOFF); + } + stop(); +} + +// dimmer 0-100 +void SSD1351::dim(uint8_t contrast) { + writecommand(SSD1351_CMD_CONTRASTMASTER); + if (contrast>15) contrast=15; + writedata(contrast); + stop(); +} + +#define ssd1351_swap(a, b) (((a) ^= (b)), ((b) ^= (a)), ((a) ^= (b))) ///< No-temp-var swap operation void SSD1351::setAddrWindow_i(uint16_t x1, uint16_t y1, uint16_t w, uint16_t h) { @@ -501,20 +544,3 @@ void SSD1351::drawFastHLine(int16_t x,int16_t y,int16_t w,uint16_t color) { } stop(); } - -void ICACHE_RAM_ATTR SSD1351::fastSPIwrite(uint8_t d,uint8_t dc) { - - WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<_cs); - WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<_sclk); - if(dc) WRITE_PERI_REG( PIN_OUT_SET, 1<<_mosi); - else WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<_mosi); - WRITE_PERI_REG( PIN_OUT_SET, 1<<_sclk); - - for(uint8_t bit = 0x80; bit; bit >>= 1) { - WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<_sclk); - if(d&bit) WRITE_PERI_REG( PIN_OUT_SET, 1<<_mosi); - else WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<_mosi); - WRITE_PERI_REG( PIN_OUT_SET, 1<<_sclk); - } - WRITE_PERI_REG( PIN_OUT_SET, 1<<_cs); -} diff --git a/lib/Adafruit_VEML7700/.github/ISSUE_TEMPLATE.md b/lib/Adafruit_VEML7700/.github/ISSUE_TEMPLATE.md new file mode 100644 index 000000000..f0e26146f --- /dev/null +++ b/lib/Adafruit_VEML7700/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,46 @@ +Thank you for opening an issue on an Adafruit Arduino library repository. To +improve the speed of resolution please review the following guidelines and +common troubleshooting steps below before creating the issue: + +- **Do not use GitHub issues for troubleshooting projects and issues.** Instead use + the forums at http://forums.adafruit.com to ask questions and troubleshoot why + something isn't working as expected. In many cases the problem is a common issue + that you will more quickly receive help from the forum community. GitHub issues + are meant for known defects in the code. If you don't know if there is a defect + in the code then start with troubleshooting on the forum first. + +- **If following a tutorial or guide be sure you didn't miss a step.** Carefully + check all of the steps and commands to run have been followed. Consult the + forum if you're unsure or have questions about steps in a guide/tutorial. + +- **For Arduino projects check these very common issues to ensure they don't apply**: + + - For uploading sketches or communicating with the board make sure you're using + a **USB data cable** and **not** a **USB charge-only cable**. It is sometimes + very hard to tell the difference between a data and charge cable! Try using the + cable with other devices or swapping to another cable to confirm it is not + the problem. + + - **Be sure you are supplying adequate power to the board.** Check the specs of + your board and plug in an external power supply. In many cases just + plugging a board into your computer is not enough to power it and other + peripherals. + + - **Double check all soldering joints and connections.** Flakey connections + cause many mysterious problems. See the [guide to excellent soldering](https://learn.adafruit.com/adafruit-guide-excellent-soldering/tools) for examples of good solder joints. + + - **Ensure you are using an official Arduino or Adafruit board.** We can't + guarantee a clone board will have the same functionality and work as expected + with this code and don't support them. + +If you're sure this issue is a defect in the code and checked the steps above +please fill in the following fields to provide enough troubleshooting information. +You may delete the guideline and text above to just leave the following details: + +- Arduino board: **INSERT ARDUINO BOARD NAME/TYPE HERE** + +- Arduino IDE version (found in Arduino -> About Arduino menu): **INSERT ARDUINO + VERSION HERE** + +- List the steps to reproduce the problem below (if possible attach a sketch or + copy the sketch code in too): **LIST REPRO STEPS BELOW** diff --git a/lib/Adafruit_VEML7700/.github/PULL_REQUEST_TEMPLATE.md b/lib/Adafruit_VEML7700/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000..7b641eb86 --- /dev/null +++ b/lib/Adafruit_VEML7700/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,26 @@ +Thank you for creating a pull request to contribute to Adafruit's GitHub code! +Before you open the request please review the following guidelines and tips to +help it be more easily integrated: + +- **Describe the scope of your change--i.e. what the change does and what parts + of the code were modified.** This will help us understand any risks of integrating + the code. + +- **Describe any known limitations with your change.** For example if the change + doesn't apply to a supported platform of the library please mention it. + +- **Please run any tests or examples that can exercise your modified code.** We + strive to not break users of the code and running tests/examples helps with this + process. + +Thank you again for contributing! We will try to test and integrate the change +as soon as we can, but be aware we have many GitHub repositories to manage and +can't immediately respond to every request. There is no need to bump or check in +on a pull request (it will clutter the discussion of the request). + +Also don't be worried if the request is closed or not integrated--sometimes the +priorities of Adafruit's GitHub code (education, ease of use) might not match the +priorities of the pull request. Don't fret, the open source community thrives on +forks and GitHub makes it easy to keep your changes in a forked repo. + +After reviewing the guidelines above you can delete this text from the pull request. diff --git a/lib/Adafruit_VEML7700/.gitignore b/lib/Adafruit_VEML7700/.gitignore new file mode 100644 index 000000000..542d266a9 --- /dev/null +++ b/lib/Adafruit_VEML7700/.gitignore @@ -0,0 +1,8 @@ +# osx +.DS_Store + +# doxygen +Doxyfile* +doxygen_sqlite3.db +html +*.tmp diff --git a/lib/Adafruit_VEML7700/.travis.yml b/lib/Adafruit_VEML7700/.travis.yml new file mode 100644 index 000000000..b967e9a08 --- /dev/null +++ b/lib/Adafruit_VEML7700/.travis.yml @@ -0,0 +1,26 @@ +language: c +sudo: false +cache: + directories: + - ~/arduino_ide + - ~/.arduino15/packages/ +git: + depth: false + quiet: true +env: + global: + - PRETTYNAME="Adafruit VEML7700 Arduino Library" + +before_install: + - source <(curl -SLs https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/install.sh) + +install: + - arduino --install-library "Adafruit BusIO" + +script: + - build_main_platforms + +# Generate and deploy documentation +after_success: + - source <(curl -SLs https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/library_check.sh) + - source <(curl -SLs https://raw.githubusercontent.com/adafruit/travis-ci-arduino/master/doxy_gen_and_deploy.sh) \ No newline at end of file diff --git a/lib/Adafruit_VEML7700/Adafruit_VEML7700.cpp b/lib/Adafruit_VEML7700/Adafruit_VEML7700.cpp new file mode 100644 index 000000000..254d74788 --- /dev/null +++ b/lib/Adafruit_VEML7700/Adafruit_VEML7700.cpp @@ -0,0 +1,321 @@ +/*! + * @file Adafruit_VEML7700.cpp + * + * @mainpage Adafruit VEML7700 I2C Lux Sensor + * + * @section intro_sec Introduction + * + * I2C Driver for the VEML7700 I2C Lux sensor + * + * This is a library for the Adafruit VEML7700 breakout: + * http://www.adafruit.com/ + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing products from + * Adafruit! + * + * @section author Author + * + * Limor Fried (Adafruit Industries) + * + * @section license License + * + * BSD (see license.txt) + * + * @section HISTORY + * + * v1.0 - First release + */ + +#include "Arduino.h" +#include + +#include "Adafruit_VEML7700.h" + +/*! + * @brief Instantiates a new VEML7700 class + */ +Adafruit_VEML7700::Adafruit_VEML7700(void) {} + +/*! + * @brief Setups the hardware for talking to the VEML7700 + * @param theWire An optional pointer to an I2C interface + * @return True if initialization was successful, otherwise false. + */ +boolean Adafruit_VEML7700::begin(TwoWire *theWire) { + i2c_dev = new Adafruit_I2CDevice(VEML7700_I2CADDR_DEFAULT, theWire); + + if (!i2c_dev->begin()) { + return false; + } + + ALS_Config = new Adafruit_I2CRegister(i2c_dev, VEML7700_ALS_CONFIG, 2, LSBFIRST); + ALS_HighThreshold = new Adafruit_I2CRegister(i2c_dev, VEML7700_ALS_THREHOLD_HIGH, 2, LSBFIRST); + ALS_LowThreshold = new Adafruit_I2CRegister(i2c_dev, VEML7700_ALS_THREHOLD_LOW, 2, LSBFIRST); + Power_Saving = new Adafruit_I2CRegister(i2c_dev, VEML7700_ALS_POWER_SAVE, 2, LSBFIRST); + ALS_Data = new Adafruit_I2CRegister(i2c_dev, VEML7700_ALS_DATA, 2, LSBFIRST); + White_Data = new Adafruit_I2CRegister(i2c_dev, VEML7700_WHITE_DATA, 2, LSBFIRST); + Interrupt_Status = new Adafruit_I2CRegister(i2c_dev, VEML7700_INTERRUPTSTATUS, 2, LSBFIRST); + + ALS_Shutdown = new Adafruit_I2CRegisterBits(ALS_Config, 1, 0); // # bits, bit_shift + ALS_Interrupt_Enable = new Adafruit_I2CRegisterBits(ALS_Config, 1, 1); + ALS_Persistence = new Adafruit_I2CRegisterBits(ALS_Config, 2, 4); + ALS_Integration_Time = new Adafruit_I2CRegisterBits(ALS_Config, 4, 6); + ALS_Gain = new Adafruit_I2CRegisterBits(ALS_Config, 2, 11); + PowerSave_Enable = new Adafruit_I2CRegisterBits(Power_Saving, 1, 0); + PowerSave_Mode = new Adafruit_I2CRegisterBits(Power_Saving, 2, 1); + + enable(false); + interruptEnable(false); + setPersistence(VEML7700_PERS_1); + setGain(VEML7700_GAIN_1); + setIntegrationTime(VEML7700_IT_100MS); + powerSaveEnable(false); + enable(true); + + return true; +} + +float Adafruit_VEML7700::normalize_resolution(float value) { + // adjust for gain (1x is normalized) + switch (getGain()) { + case VEML7700_GAIN_2: + value /= 2.0; break; + case VEML7700_GAIN_1_4: + value *= 4; break; + case VEML7700_GAIN_1_8: + value *= 8; break; + } + + // adjust for integrationtime (100ms is normalized) + switch (getIntegrationTime()) { + case VEML7700_IT_25MS: + value *= 4; break; + case VEML7700_IT_50MS: + value *= 2; break; + case VEML7700_IT_200MS: + value /= 2.0; break; + case VEML7700_IT_400MS: + value /= 4.0; break; + case VEML7700_IT_800MS: + value /= 8.0; break; + } + + return value; +} + +/*! + * @brief Read the calibrated lux value. See app note lux table on page 5 + * @returns Floating point Lux data (ALS multiplied by 0.0576) + */ +float Adafruit_VEML7700::readLux() { + return ( normalize_resolution(ALS_Data->read()) * 0.0576f); // see app note lux table on page 5 +} + +/*! + * @brief Read the lux value with correction for non-linearity at high-lux settings + * @returns Floating point Lux data (ALS multiplied by 0.0576 and corrected for high-lux settings) + */ +float Adafruit_VEML7700::readLuxNormalized() { + float lux = readLux(); + + // user-provided correction for non-linearities at high lux/white values: + // https://forums.adafruit.com/viewtopic.php?f=19&t=152997&p=758582#p759346 + if ((getGain() == VEML7700_GAIN_1_8) && (getIntegrationTime() == VEML7700_IT_25MS)){ + lux = 6.0135e-13f * pow(lux,4) - 9.3924e-9f * pow(lux,3) + 8.1488e-5f * pow(lux,2) + 1.0023f * lux; + } + + return lux; +} + +/*! + * @brief Read the raw ALS data + * @returns 16-bit data value from the ALS register + */ +uint16_t Adafruit_VEML7700::readALS() { + return ALS_Data->read(); +} + +/*! + * @brief Read the white light data + * @returns Floating point 'white light' data multiplied by 0.0576 + */ +float Adafruit_VEML7700::readWhite() { + // white_corrected= 2E-15*pow(VEML_white,4) + 4E-12*pow(VEML_white,3) + 9E-06*pow(VEML_white,)2 + 1.0179*VEML_white - 11.052; + return normalize_resolution(White_Data->read()) * 0.0576f; // Unclear if this is the right multiplier +} + +/*! + * @brief Read the 'white light' value with correction for non-linearity at high-lux settings + * @returns Floating point 'white light' data multiplied by 0.0576 and corrected for high-lux settings + */ +float Adafruit_VEML7700::readWhiteNormalized() { + float white = readWhite(); + + // user-provided correction for non-linearities at high lux values: + // https://forums.adafruit.com/viewtopic.php?f=19&t=152997&p=758582#p759346 + if ((getGain() == VEML7700_GAIN_1_8) && (getIntegrationTime() == VEML7700_IT_25MS)){ + white = 2E-15f * pow(white,4) + 4E-12f * pow(white,3) + 9E-06f * pow(white,2) + 1.0179f * white - 11.052f; + } + + return white; +} + +/*! + * @brief Enable or disable the sensor + * @param enable The flag to enable/disable + */ +void Adafruit_VEML7700::enable(bool enable) { + ALS_Shutdown->write(!enable); +} + +/*! + * @brief Ask if the interrupt is enabled + * @returns True if enabled, false otherwise + */ +bool Adafruit_VEML7700::enabled(void) { + return !ALS_Shutdown->read(); +} + +/*! + * @brief Enable or disable the interrupt + * @param enable The flag to enable/disable + */ +void Adafruit_VEML7700::interruptEnable(bool enable) { + ALS_Interrupt_Enable->write(enable); +} + + +/*! + * @brief Ask if the interrupt is enabled + * @returns True if enabled, false otherwise + */ +bool Adafruit_VEML7700::interruptEnabled(void) { + return ALS_Interrupt_Enable->read(); +} + + +/*! + * @brief Set the ALS IRQ persistance setting + * @param pers Persistance constant, can be VEML7700_PERS_1, VEML7700_PERS_2, + * VEML7700_PERS_4 or VEML7700_PERS_8 + */ +void Adafruit_VEML7700::setPersistence(uint8_t pers) { + ALS_Persistence->write(pers); +} + +/*! + * @brief Get the ALS IRQ persistance setting + * @returns Persistance constant, can be VEML7700_PERS_1, VEML7700_PERS_2, + * VEML7700_PERS_4 or VEML7700_PERS_8 + */ +uint8_t Adafruit_VEML7700::getPersistence(void) { + return ALS_Persistence->read(); +} + +/*! + * @brief Set ALS integration time + * @param it Can be VEML7700_IT_100MS, VEML7700_IT_200MS, VEML7700_IT_400MS, + * VEML7700_IT_800MS, VEML7700_IT_50MS or VEML7700_IT_25MS + */ +void Adafruit_VEML7700::setIntegrationTime(uint8_t it) { + ALS_Integration_Time->write(it); +} + +/*! + * @brief Get ALS integration time + * @returns IT index, can be VEML7700_IT_100MS, VEML7700_IT_200MS, VEML7700_IT_400MS, + * VEML7700_IT_800MS, VEML7700_IT_50MS or VEML7700_IT_25MS + */ +uint8_t Adafruit_VEML7700::getIntegrationTime(void) { + return ALS_Integration_Time->read(); +} + +/*! + * @brief Set ALS gain + * @param gain Can be VEML7700_GAIN_1, VEML7700_GAIN_2, VEML7700_GAIN_1_8 or VEML7700_GAIN_1_4 + */ +void Adafruit_VEML7700::setGain(uint8_t gain) { + ALS_Gain->write(gain); +} + +/*! + * @brief Get ALS gain + * @returns Gain index, can be VEML7700_GAIN_1, VEML7700_GAIN_2, VEML7700_GAIN_1_8 or VEML7700_GAIN_1_4 + */ +uint8_t Adafruit_VEML7700::getGain(void) { + return ALS_Gain->read(); +} + + +/*! + * @brief Enable power save mode + * @param enable True if power save should be enabled + */ +void Adafruit_VEML7700::powerSaveEnable(bool enable) { + PowerSave_Enable->write(enable); +} + +/*! + * @brief Check if power save mode is enabled + * @returns True if power save is enabled + */ +bool Adafruit_VEML7700::powerSaveEnabled(void) { + return PowerSave_Enable->read(); +} + +/*! + * @brief Assign the power save register data + * @param mode The 16-bit data to write to VEML7700_ALS_POWER_SAVE + */ +void Adafruit_VEML7700::setPowerSaveMode(uint8_t mode) { + PowerSave_Mode->write(mode); +} + +/*! + * @brief Retrieve the power save register data + * @return 16-bit data from VEML7700_ALS_POWER_SAVE + */ +uint8_t Adafruit_VEML7700::getPowerSaveMode(void) { + return PowerSave_Mode->read(); +} + +/*! + * @brief Assign the low threshold register data + * @param value The 16-bit data to write to VEML7700_ALS_THREHOLD_LOW + */ +void Adafruit_VEML7700::setLowThreshold(uint16_t value) { + ALS_LowThreshold->write(value); +} + +/*! + * @brief Retrieve the low threshold register data + * @return 16-bit data from VEML7700_ALS_THREHOLD_LOW + */ +uint16_t Adafruit_VEML7700::getLowThreshold(void) { + return ALS_LowThreshold->read(); +} + +/*! + * @brief Assign the high threshold register data + * @param value The 16-bit data to write to VEML7700_ALS_THREHOLD_HIGH + */ +void Adafruit_VEML7700::setHighThreshold(uint16_t value) { + ALS_HighThreshold->write(value); +} + +/*! + * @brief Retrieve the high threshold register data + * @return 16-bit data from VEML7700_ALS_THREHOLD_HIGH + */ +uint16_t Adafruit_VEML7700::getHighThreshold(void) { + return ALS_HighThreshold->read(); +} + +/*! + * @brief Retrieve the interrupt status register data + * @return 16-bit data from VEML7700_INTERRUPTSTATUS + */ +uint16_t Adafruit_VEML7700::interruptStatus(void) { + return Interrupt_Status->read(); +} diff --git a/lib/Adafruit_VEML7700/Adafruit_VEML7700.h b/lib/Adafruit_VEML7700/Adafruit_VEML7700.h new file mode 100644 index 000000000..5ae23f3b6 --- /dev/null +++ b/lib/Adafruit_VEML7700/Adafruit_VEML7700.h @@ -0,0 +1,121 @@ +/*! + * @file Adafruit_VEML7700.h + * + * I2C Driver for VEML7700 Lux sensor + * + * This is a library for the Adafruit VEML7700 breakout: + * http://www.adafruit.com/ + * + * Adafruit invests time and resources providing this open source code, + *please support Adafruit and open-source hardware by purchasing products from + * Adafruit! + * + * + * BSD license (see license.txt) + */ + +/* + * change from device111 for Tasmota + * Add alternativ Pow function for readLuxNormalized() and readWhiteNormalized() + */ + +#ifndef _ADAFRUIT_VEML7700_H +#define _ADAFRUIT_VEML7700_H + +#include "Arduino.h" +#include +#include +#include + +#define VEML7700_I2CADDR_DEFAULT 0x10 ///< I2C address + +#define VEML7700_ALS_CONFIG 0x00 ///< Light configuration register +#define VEML7700_ALS_THREHOLD_HIGH 0x01 ///< Light high threshold for irq +#define VEML7700_ALS_THREHOLD_LOW 0x02 ///< Light low threshold for irq +#define VEML7700_ALS_POWER_SAVE 0x03 ///< Power save regiester +#define VEML7700_ALS_DATA 0x04 ///< The light data output +#define VEML7700_WHITE_DATA 0x05 ///< The white light data output +#define VEML7700_INTERRUPTSTATUS 0x06 ///< What IRQ (if any) + +#define VEML7700_INTERRUPT_HIGH 0x4000 ///< Interrupt status for high threshold +#define VEML7700_INTERRUPT_LOW 0x8000 ///< Interrupt status for low threshold + +#define VEML7700_GAIN_1 0x00 ///< ALS gain 1x +#define VEML7700_GAIN_2 0x01 ///< ALS gain 2x +#define VEML7700_GAIN_1_8 0x02 ///< ALS gain 1/8x +#define VEML7700_GAIN_1_4 0x03 ///< ALS gain 1/4x + +#define VEML7700_IT_100MS 0x00 ///< ALS intetgration time 100ms +#define VEML7700_IT_200MS 0x01 ///< ALS intetgration time 200ms +#define VEML7700_IT_400MS 0x02 ///< ALS intetgration time 400ms +#define VEML7700_IT_800MS 0x03 ///< ALS intetgration time 800ms +#define VEML7700_IT_50MS 0x08 ///< ALS intetgration time 50ms +#define VEML7700_IT_25MS 0x0C ///< ALS intetgration time 25ms + +#define VEML7700_PERS_1 0x00 ///< ALS irq persisance 1 sample +#define VEML7700_PERS_2 0x01 ///< ALS irq persisance 2 samples +#define VEML7700_PERS_4 0x02 ///< ALS irq persisance 4 samples +#define VEML7700_PERS_8 0x03 ///< ALS irq persisance 8 samples + +#define VEML7700_POWERSAVE_MODE1 0x00 ///< Power saving mode 1 +#define VEML7700_POWERSAVE_MODE2 0x01 ///< Power saving mode 2 +#define VEML7700_POWERSAVE_MODE3 0x02 ///< Power saving mode 3 +#define VEML7700_POWERSAVE_MODE4 0x03 ///< Power saving mode 4 + +// FastPrecisePowf from tasmota/support_float.ino +extern float FastPrecisePowf(const float x, const float y); + +/*! + * @brief Class that stores state and functions for interacting with + * VEML7700 Temp Sensor + */ +class Adafruit_VEML7700 { +public: + Adafruit_VEML7700(); + boolean begin(TwoWire *theWire = &Wire); + + void enable(bool enable); + bool enabled(void); + + void interruptEnable(bool enable); + bool interruptEnabled(void); + void setPersistence(uint8_t pers); + uint8_t getPersistence(void); + void setIntegrationTime(uint8_t it); + uint8_t getIntegrationTime(void); + void setGain(uint8_t gain); + uint8_t getGain(void); + void powerSaveEnable(bool enable); + bool powerSaveEnabled(void); + void setPowerSaveMode(uint8_t mode); + uint8_t getPowerSaveMode(void); + + void setLowThreshold(uint16_t value); + uint16_t getLowThreshold(void); + void setHighThreshold(uint16_t value); + uint16_t getHighThreshold(void); + uint16_t interruptStatus(void); + + + float readLux(); + float readLuxNormalized(); + + uint16_t readALS(); + float readWhite(); + float readWhiteNormalized(); + +private: + Adafruit_I2CRegister *ALS_Config, *ALS_Data, *White_Data, + *ALS_HighThreshold, *ALS_LowThreshold, *Power_Saving, *Interrupt_Status; + Adafruit_I2CRegisterBits *ALS_Shutdown, *ALS_Interrupt_Enable, + *ALS_Persistence, *ALS_Integration_Time, *ALS_Gain, + *PowerSave_Enable, *PowerSave_Mode; + + float normalize_resolution(float value); + static inline float pow(float a, float b) { return FastPrecisePowf(a, b); } + + Adafruit_I2CDevice *i2c_dev; + +}; + +#endif diff --git a/lib/Adafruit_VEML7700/README.md b/lib/Adafruit_VEML7700/README.md new file mode 100644 index 000000000..fe3f3c898 --- /dev/null +++ b/lib/Adafruit_VEML7700/README.md @@ -0,0 +1,16 @@ +Adafruit_VEML7700 [![Build Status](https://travis-ci.com/adafruit/Adafruit_VEML7700.svg?branch=master)](https://travis-ci.com/adafruit/Adafruit_VEML7700) +================ + +This is the Adafruit VEML7700 Lux sensor library + +Tested and works great with the [Adafruit VEML7700 Breakout Board](http://www.adafruit.com/) + +This chip uses I2C to communicate, 2 pins are required to interface + +Adafruit invests time and resources providing this open source code, +please support Adafruit and open-source hardware by purchasing +products from Adafruit! + +Written by Kevin Townsend/Limor Fried for Adafruit Industries. +BSD license, check license.txt for more information +All text above must be included in any redistribution diff --git a/lib/Adafruit_VEML7700/examples/veml7700_test/veml7700_test.ino b/lib/Adafruit_VEML7700/examples/veml7700_test/veml7700_test.ino new file mode 100644 index 000000000..64718112d --- /dev/null +++ b/lib/Adafruit_VEML7700/examples/veml7700_test/veml7700_test.ino @@ -0,0 +1,58 @@ +#include "Adafruit_VEML7700.h" + +Adafruit_VEML7700 veml = Adafruit_VEML7700(); + +void setup() { + while (!Serial) { delay(10); } + Serial.begin(115200); + Serial.println("Adafruit VEML7700 Test"); + + if (!veml.begin()) { + Serial.println("Sensor not found"); + while (1); + } + Serial.println("Sensor found"); + + veml.setGain(VEML7700_GAIN_1); + veml.setIntegrationTime(VEML7700_IT_800MS); + + Serial.print(F("Gain: ")); + switch (veml.getGain()) { + case VEML7700_GAIN_1: Serial.println("1"); break; + case VEML7700_GAIN_2: Serial.println("2"); break; + case VEML7700_GAIN_1_4: Serial.println("1/4"); break; + case VEML7700_GAIN_1_8: Serial.println("1/8"); break; + } + + Serial.print(F("Integration Time (ms): ")); + switch (veml.getIntegrationTime()) { + case VEML7700_IT_25MS: Serial.println("25"); break; + case VEML7700_IT_50MS: Serial.println("50"); break; + case VEML7700_IT_100MS: Serial.println("100"); break; + case VEML7700_IT_200MS: Serial.println("200"); break; + case VEML7700_IT_400MS: Serial.println("400"); break; + case VEML7700_IT_800MS: Serial.println("800"); break; + } + + //veml.powerSaveEnable(true); + //veml.setPowerSaveMode(VEML7700_POWERSAVE_MODE4); + + veml.setLowThreshold(10000); + veml.setHighThreshold(20000); + veml.interruptEnable(true); +} + +void loop() { + Serial.print("Lux: "); Serial.println(veml.readLux()); + Serial.print("White: "); Serial.println(veml.readWhite()); + Serial.print("Raw ALS: "); Serial.println(veml.readALS()); + + uint16_t irq = veml.interruptStatus(); + if (irq & VEML7700_INTERRUPT_LOW) { + Serial.println("** Low threshold"); + } + if (irq & VEML7700_INTERRUPT_HIGH) { + Serial.println("** High threshold"); + } + delay(500); +} diff --git a/lib/Adafruit_VEML7700/library.properties b/lib/Adafruit_VEML7700/library.properties new file mode 100644 index 000000000..754bd2fd7 --- /dev/null +++ b/lib/Adafruit_VEML7700/library.properties @@ -0,0 +1,9 @@ +name=Adafruit VEML7700 Library +version=1.0.0 +author=Adafruit +maintainer=Adafruit +sentence=Arduino library for the VEML7700 sensors in the Adafruit shop +paragraph=Arduino library for the VEML7700 sensors in the Adafruit shop +category=Sensors +url=https://github.com/adafruit/Adafruit_VEML7700 +architectures=* diff --git a/lib/Adafruit_VEML7700/license.txt b/lib/Adafruit_VEML7700/license.txt new file mode 100644 index 000000000..f6a0f22b8 --- /dev/null +++ b/lib/Adafruit_VEML7700/license.txt @@ -0,0 +1,26 @@ +Software License Agreement (BSD License) + +Copyright (c) 2012, Adafruit Industries +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +1. Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +3. Neither the name of the copyright holders nor the +names of its contributors may be used to endorse or promote products +derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/lib/ArduinoNTPd/NTPServer.cpp b/lib/ArduinoNTPd/NTPServer.cpp index a5d0515d0..860ccc79d 100644 --- a/lib/ArduinoNTPd/NTPServer.cpp +++ b/lib/ArduinoNTPd/NTPServer.cpp @@ -87,7 +87,7 @@ bool NtpServer::processOneRequest(uint32_t utc, uint32_t millisecs) packet.swapEndian(); timeServerPort_.beginPacket(timeServerPort_.remoteIP(), timeServerPort_.remotePort()); - timeServerPort_.write(packet.packet(), NtpPacket::PACKET_SIZE); + timeServerPort_.write((const uint8_t *)packet.packet(), NtpPacket::PACKET_SIZE); timeServerPort_.endPacket(); processed = true; diff --git a/lib/FrogmoreScd30/FrogmoreScd30.cpp b/lib/FrogmoreScd30/FrogmoreScd30.cpp index 32bbee5ba..e610bfb92 100644 --- a/lib/FrogmoreScd30/FrogmoreScd30.cpp +++ b/lib/FrogmoreScd30/FrogmoreScd30.cpp @@ -58,7 +58,9 @@ void FrogmoreScd30::begin(TwoWire *pWire, uint8_t i2cAddress) } co2NewDataLocation = -1; // indicates there is no data, so the 1st data point needs to fill up the median filter +#ifdef ESP8266 this->pWire->setClockStretchLimit(200000); +#endif this->ambientPressure = 0; } @@ -106,7 +108,11 @@ int FrogmoreScd30::clearI2CBus(void) snprintf_P(scd30log_data, sizeof(scd30log_data), "clearI2CBus"); AddLog(LOG_LEVEL_DEBUG_MORE); #endif +#ifdef ESP8266 return (twi_status()); +#else + return 0; +#endif } #ifdef SCD30_DEBUG @@ -253,7 +259,7 @@ int FrogmoreScd30::get16BitRegCheckCRC(void* pInput, uint16_t *pData) } // gets 32 bits, (2) 16-bit chunks, and validates the CRCs -// +// int FrogmoreScd30::get32BitRegCheckCRC(void *pInput, float *pData) { uint16_t tempU16High; @@ -458,7 +464,7 @@ int FrogmoreScd30::setTemperatureOffset(float offset_degC) { return (ERROR_SCD30_INVALID_VALUE); } - + } int FrogmoreScd30::setTemperatureOffset(uint16_t offset_centiDegC) @@ -568,7 +574,7 @@ int FrogmoreScd30::readMeasurement( return (error); } - error = get32BitRegCheckCRC(&bytes[12], &tempHumidity); + error = get32BitRegCheckCRC(&bytes[12], &tempHumidity); if (error) { #ifdef SCD30_DEBUG @@ -650,4 +656,3 @@ int FrogmoreScd30::stopMeasuring(void) { return (sendCommand(COMMAND_SCD30_STOP_MEASUREMENT)); } - diff --git a/lib/IRremoteESP8266-2.7.5/examples/IRGCTCPServer/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/IRGCTCPServer/platformio.ini deleted file mode 100644 index e6f6320da..000000000 --- a/lib/IRremoteESP8266-2.7.5/examples/IRGCTCPServer/platformio.ini +++ /dev/null @@ -1,17 +0,0 @@ -[platformio] -src_dir = . - -[env] -lib_extra_dirs = ../../ -lib_ldf_mode = deep+ -lib_ignore = examples -framework = arduino -build_flags = ; -D_IR_LOCALE_=en-AU - -[env:nodemcuv2] -platform = espressif8266 -board = nodemcuv2 - -[env:esp32dev] -platform = espressif32 -board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.5/examples/IRServer/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/IRServer/platformio.ini deleted file mode 100644 index e6f6320da..000000000 --- a/lib/IRremoteESP8266-2.7.5/examples/IRServer/platformio.ini +++ /dev/null @@ -1,17 +0,0 @@ -[platformio] -src_dir = . - -[env] -lib_extra_dirs = ../../ -lib_ldf_mode = deep+ -lib_ignore = examples -framework = arduino -build_flags = ; -D_IR_LOCALE_=en-AU - -[env:nodemcuv2] -platform = espressif8266 -board = nodemcuv2 - -[env:esp32dev] -platform = espressif32 -board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.5/examples/IRrecvDemo/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/IRrecvDemo/platformio.ini deleted file mode 100644 index e6f6320da..000000000 --- a/lib/IRremoteESP8266-2.7.5/examples/IRrecvDemo/platformio.ini +++ /dev/null @@ -1,17 +0,0 @@ -[platformio] -src_dir = . - -[env] -lib_extra_dirs = ../../ -lib_ldf_mode = deep+ -lib_ignore = examples -framework = arduino -build_flags = ; -D_IR_LOCALE_=en-AU - -[env:nodemcuv2] -platform = espressif8266 -board = nodemcuv2 - -[env:esp32dev] -platform = espressif32 -board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.5/examples/IRrecvDump/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/IRrecvDump/platformio.ini deleted file mode 100644 index e6f6320da..000000000 --- a/lib/IRremoteESP8266-2.7.5/examples/IRrecvDump/platformio.ini +++ /dev/null @@ -1,17 +0,0 @@ -[platformio] -src_dir = . - -[env] -lib_extra_dirs = ../../ -lib_ldf_mode = deep+ -lib_ignore = examples -framework = arduino -build_flags = ; -D_IR_LOCALE_=en-AU - -[env:nodemcuv2] -platform = espressif8266 -board = nodemcuv2 - -[env:esp32dev] -platform = espressif32 -board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.5/examples/IRrecvDumpV2/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/IRrecvDumpV2/platformio.ini deleted file mode 100644 index d3c660df9..000000000 --- a/lib/IRremoteESP8266-2.7.5/examples/IRrecvDumpV2/platformio.ini +++ /dev/null @@ -1,46 +0,0 @@ -[platformio] -src_dir = . - -[env] -; Default platform -platform = espressif8266 -; Default board -board = nodemcuv2 -framework = arduino -lib_extra_dirs = ../../ -lib_ldf_mode = deep+ -lib_ignore = examples -build_flags = ; -D_IR_LOCALE_=en-AU - -[env:nodemcuv2] -board = nodemcuv2 -; build_flags = -D_IR_LOCALE_=en-AU - -[env:esp32dev] -platform = espressif32 -board = esp32dev -; build_flags = -D_IR_LOCALE_=en-AU - -[env:de-CH] -build_flags = -D_IR_LOCALE_=de-CH - -[env:de-DE] -build_flags = -D_IR_LOCALE_=de-DE - -[env:en-AU] -build_flags = -D_IR_LOCALE_=en-AU - -[env:en-IE] -build_flags = -D_IR_LOCALE_=en-IE - -[env:en-UK] -build_flags = -D_IR_LOCALE_=en-UK - -[env:en-US] -build_flags = -D_IR_LOCALE_=en-US - -[env:es-ES] -build_flags = -D_IR_LOCALE_=es-ES - -[env:fr-FR] -build_flags = -D_IR_LOCALE_=fr-FR diff --git a/lib/IRremoteESP8266-2.7.5/examples/IRsendDemo/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/IRsendDemo/platformio.ini deleted file mode 100644 index e6f6320da..000000000 --- a/lib/IRremoteESP8266-2.7.5/examples/IRsendDemo/platformio.ini +++ /dev/null @@ -1,17 +0,0 @@ -[platformio] -src_dir = . - -[env] -lib_extra_dirs = ../../ -lib_ldf_mode = deep+ -lib_ignore = examples -framework = arduino -build_flags = ; -D_IR_LOCALE_=en-AU - -[env:nodemcuv2] -platform = espressif8266 -board = nodemcuv2 - -[env:esp32dev] -platform = espressif32 -board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.5/examples/IRsendProntoDemo/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/IRsendProntoDemo/platformio.ini deleted file mode 100644 index e6f6320da..000000000 --- a/lib/IRremoteESP8266-2.7.5/examples/IRsendProntoDemo/platformio.ini +++ /dev/null @@ -1,17 +0,0 @@ -[platformio] -src_dir = . - -[env] -lib_extra_dirs = ../../ -lib_ldf_mode = deep+ -lib_ignore = examples -framework = arduino -build_flags = ; -D_IR_LOCALE_=en-AU - -[env:nodemcuv2] -platform = espressif8266 -board = nodemcuv2 - -[env:esp32dev] -platform = espressif32 -board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.5/examples/JVCPanasonicSendDemo/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/JVCPanasonicSendDemo/platformio.ini deleted file mode 100644 index e6f6320da..000000000 --- a/lib/IRremoteESP8266-2.7.5/examples/JVCPanasonicSendDemo/platformio.ini +++ /dev/null @@ -1,17 +0,0 @@ -[platformio] -src_dir = . - -[env] -lib_extra_dirs = ../../ -lib_ldf_mode = deep+ -lib_ignore = examples -framework = arduino -build_flags = ; -D_IR_LOCALE_=en-AU - -[env:nodemcuv2] -platform = espressif8266 -board = nodemcuv2 - -[env:esp32dev] -platform = espressif32 -board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.5/examples/LGACSend/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/LGACSend/platformio.ini deleted file mode 100644 index e6f6320da..000000000 --- a/lib/IRremoteESP8266-2.7.5/examples/LGACSend/platformio.ini +++ /dev/null @@ -1,17 +0,0 @@ -[platformio] -src_dir = . - -[env] -lib_extra_dirs = ../../ -lib_ldf_mode = deep+ -lib_ignore = examples -framework = arduino -build_flags = ; -D_IR_LOCALE_=en-AU - -[env:nodemcuv2] -platform = espressif8266 -board = nodemcuv2 - -[env:esp32dev] -platform = espressif32 -board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.5/examples/SmartIRRepeater/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/SmartIRRepeater/platformio.ini deleted file mode 100644 index e6f6320da..000000000 --- a/lib/IRremoteESP8266-2.7.5/examples/SmartIRRepeater/platformio.ini +++ /dev/null @@ -1,17 +0,0 @@ -[platformio] -src_dir = . - -[env] -lib_extra_dirs = ../../ -lib_ldf_mode = deep+ -lib_ignore = examples -framework = arduino -build_flags = ; -D_IR_LOCALE_=en-AU - -[env:nodemcuv2] -platform = espressif8266 -board = nodemcuv2 - -[env:esp32dev] -platform = espressif32 -board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.5/examples/TurnOnArgoAC/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/TurnOnArgoAC/platformio.ini deleted file mode 100644 index e6f6320da..000000000 --- a/lib/IRremoteESP8266-2.7.5/examples/TurnOnArgoAC/platformio.ini +++ /dev/null @@ -1,17 +0,0 @@ -[platformio] -src_dir = . - -[env] -lib_extra_dirs = ../../ -lib_ldf_mode = deep+ -lib_ignore = examples -framework = arduino -build_flags = ; -D_IR_LOCALE_=en-AU - -[env:nodemcuv2] -platform = espressif8266 -board = nodemcuv2 - -[env:esp32dev] -platform = espressif32 -board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.5/examples/TurnOnDaikinAC/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/TurnOnDaikinAC/platformio.ini deleted file mode 100644 index e6f6320da..000000000 --- a/lib/IRremoteESP8266-2.7.5/examples/TurnOnDaikinAC/platformio.ini +++ /dev/null @@ -1,17 +0,0 @@ -[platformio] -src_dir = . - -[env] -lib_extra_dirs = ../../ -lib_ldf_mode = deep+ -lib_ignore = examples -framework = arduino -build_flags = ; -D_IR_LOCALE_=en-AU - -[env:nodemcuv2] -platform = espressif8266 -board = nodemcuv2 - -[env:esp32dev] -platform = espressif32 -board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.5/examples/TurnOnFujitsuAC/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/TurnOnFujitsuAC/platformio.ini deleted file mode 100644 index e6f6320da..000000000 --- a/lib/IRremoteESP8266-2.7.5/examples/TurnOnFujitsuAC/platformio.ini +++ /dev/null @@ -1,17 +0,0 @@ -[platformio] -src_dir = . - -[env] -lib_extra_dirs = ../../ -lib_ldf_mode = deep+ -lib_ignore = examples -framework = arduino -build_flags = ; -D_IR_LOCALE_=en-AU - -[env:nodemcuv2] -platform = espressif8266 -board = nodemcuv2 - -[env:esp32dev] -platform = espressif32 -board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.5/examples/TurnOnGreeAC/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/TurnOnGreeAC/platformio.ini deleted file mode 100644 index e6f6320da..000000000 --- a/lib/IRremoteESP8266-2.7.5/examples/TurnOnGreeAC/platformio.ini +++ /dev/null @@ -1,17 +0,0 @@ -[platformio] -src_dir = . - -[env] -lib_extra_dirs = ../../ -lib_ldf_mode = deep+ -lib_ignore = examples -framework = arduino -build_flags = ; -D_IR_LOCALE_=en-AU - -[env:nodemcuv2] -platform = espressif8266 -board = nodemcuv2 - -[env:esp32dev] -platform = espressif32 -board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.5/examples/TurnOnKelvinatorAC/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/TurnOnKelvinatorAC/platformio.ini deleted file mode 100644 index e6f6320da..000000000 --- a/lib/IRremoteESP8266-2.7.5/examples/TurnOnKelvinatorAC/platformio.ini +++ /dev/null @@ -1,17 +0,0 @@ -[platformio] -src_dir = . - -[env] -lib_extra_dirs = ../../ -lib_ldf_mode = deep+ -lib_ignore = examples -framework = arduino -build_flags = ; -D_IR_LOCALE_=en-AU - -[env:nodemcuv2] -platform = espressif8266 -board = nodemcuv2 - -[env:esp32dev] -platform = espressif32 -board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.5/examples/TurnOnMitsubishiAC/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/TurnOnMitsubishiAC/platformio.ini deleted file mode 100644 index e6f6320da..000000000 --- a/lib/IRremoteESP8266-2.7.5/examples/TurnOnMitsubishiAC/platformio.ini +++ /dev/null @@ -1,17 +0,0 @@ -[platformio] -src_dir = . - -[env] -lib_extra_dirs = ../../ -lib_ldf_mode = deep+ -lib_ignore = examples -framework = arduino -build_flags = ; -D_IR_LOCALE_=en-AU - -[env:nodemcuv2] -platform = espressif8266 -board = nodemcuv2 - -[env:esp32dev] -platform = espressif32 -board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.5/examples/TurnOnMitsubishiHeavyAc/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/TurnOnMitsubishiHeavyAc/platformio.ini deleted file mode 100644 index e6f6320da..000000000 --- a/lib/IRremoteESP8266-2.7.5/examples/TurnOnMitsubishiHeavyAc/platformio.ini +++ /dev/null @@ -1,17 +0,0 @@ -[platformio] -src_dir = . - -[env] -lib_extra_dirs = ../../ -lib_ldf_mode = deep+ -lib_ignore = examples -framework = arduino -build_flags = ; -D_IR_LOCALE_=en-AU - -[env:nodemcuv2] -platform = espressif8266 -board = nodemcuv2 - -[env:esp32dev] -platform = espressif32 -board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.5/examples/TurnOnPanasonicAC/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/TurnOnPanasonicAC/platformio.ini deleted file mode 100644 index e6f6320da..000000000 --- a/lib/IRremoteESP8266-2.7.5/examples/TurnOnPanasonicAC/platformio.ini +++ /dev/null @@ -1,17 +0,0 @@ -[platformio] -src_dir = . - -[env] -lib_extra_dirs = ../../ -lib_ldf_mode = deep+ -lib_ignore = examples -framework = arduino -build_flags = ; -D_IR_LOCALE_=en-AU - -[env:nodemcuv2] -platform = espressif8266 -board = nodemcuv2 - -[env:esp32dev] -platform = espressif32 -board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.5/examples/TurnOnToshibaAC/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/TurnOnToshibaAC/platformio.ini deleted file mode 100644 index e6f6320da..000000000 --- a/lib/IRremoteESP8266-2.7.5/examples/TurnOnToshibaAC/platformio.ini +++ /dev/null @@ -1,17 +0,0 @@ -[platformio] -src_dir = . - -[env] -lib_extra_dirs = ../../ -lib_ldf_mode = deep+ -lib_ignore = examples -framework = arduino -build_flags = ; -D_IR_LOCALE_=en-AU - -[env:nodemcuv2] -platform = espressif8266 -board = nodemcuv2 - -[env:esp32dev] -platform = espressif32 -board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.5/examples/TurnOnTrotecAC/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/TurnOnTrotecAC/platformio.ini deleted file mode 100644 index e6f6320da..000000000 --- a/lib/IRremoteESP8266-2.7.5/examples/TurnOnTrotecAC/platformio.ini +++ /dev/null @@ -1,17 +0,0 @@ -[platformio] -src_dir = . - -[env] -lib_extra_dirs = ../../ -lib_ldf_mode = deep+ -lib_ignore = examples -framework = arduino -build_flags = ; -D_IR_LOCALE_=en-AU - -[env:nodemcuv2] -platform = espressif8266 -board = nodemcuv2 - -[env:esp32dev] -platform = espressif32 -board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.5/src/IRtext.cpp b/lib/IRremoteESP8266-2.7.5/src/IRtext.cpp deleted file mode 100644 index 72ddd45b7..000000000 --- a/lib/IRremoteESP8266-2.7.5/src/IRtext.cpp +++ /dev/null @@ -1,165 +0,0 @@ -// Copyright 2019 - David Conran (@crankyoldgit) - -#ifndef UNIT_TEST -#include -#endif // UNIT_TEST -#include "IRremoteESP8266.h" -#include "i18n.h" - -#ifndef PROGMEM -#define PROGMEM // Pretend we have the PROGMEM macro even if we really don't. -#endif - -// Common - -const PROGMEM char* kUnknownStr = D_STR_UNKNOWN; -const PROGMEM char* kProtocolStr = D_STR_PROTOCOL; -const PROGMEM char* kPowerStr = D_STR_POWER; -const PROGMEM char* kOnStr = D_STR_ON; -const PROGMEM char* kOffStr = D_STR_OFF; -const PROGMEM char* kModeStr = D_STR_MODE; -const PROGMEM char* kToggleStr = D_STR_TOGGLE; -const PROGMEM char* kTurboStr = D_STR_TURBO; -const PROGMEM char* kSuperStr = D_STR_SUPER; -const PROGMEM char* kSleepStr = D_STR_SLEEP; -const PROGMEM char* kLightStr = D_STR_LIGHT; -const PROGMEM char* kPowerfulStr = D_STR_POWERFUL; -const PROGMEM char* kQuietStr = D_STR_QUIET; -const PROGMEM char* kEconoStr = D_STR_ECONO; -const PROGMEM char* kSwingStr = D_STR_SWING; -const PROGMEM char* kSwingHStr = D_STR_SWINGH; -const PROGMEM char* kSwingVStr = D_STR_SWINGV; -const PROGMEM char* kBeepStr = D_STR_BEEP; -const PROGMEM char* kZoneFollowStr = D_STR_ZONEFOLLOW; -const PROGMEM char* kFixedStr = D_STR_FIXED; -const PROGMEM char* kMouldStr = D_STR_MOULD; -const PROGMEM char* kCleanStr = D_STR_CLEAN; -const PROGMEM char* kPurifyStr = D_STR_PURIFY; -const PROGMEM char* kTimerStr = D_STR_TIMER; -const PROGMEM char* kOnTimerStr = D_STR_ONTIMER; -const PROGMEM char* kOffTimerStr = D_STR_OFFTIMER; -const PROGMEM char* kClockStr = D_STR_CLOCK; -const PROGMEM char* kCommandStr = D_STR_COMMAND; -const PROGMEM char* kXFanStr = D_STR_XFAN; -const PROGMEM char* kHealthStr = D_STR_HEALTH; -const PROGMEM char* kModelStr = D_STR_MODEL; -const PROGMEM char* kTempStr = D_STR_TEMP; -const PROGMEM char* kIFeelStr = D_STR_IFEEL; -const PROGMEM char* kHumidStr = D_STR_HUMID; -const PROGMEM char* kSaveStr = D_STR_SAVE; -const PROGMEM char* kEyeStr = D_STR_EYE; -const PROGMEM char* kFollowStr = D_STR_FOLLOW; -const PROGMEM char* kIonStr = D_STR_ION; -const PROGMEM char* kFreshStr = D_STR_FRESH; -const PROGMEM char* kHoldStr = D_STR_HOLD; -const PROGMEM char* kButtonStr = D_STR_BUTTON; -const PROGMEM char* k8CHeatStr = D_STR_8C_HEAT; -const PROGMEM char* kNightStr = D_STR_NIGHT; -const PROGMEM char* kSilentStr = D_STR_SILENT; -const PROGMEM char* kFilterStr = D_STR_FILTER; -const PROGMEM char* k3DStr = D_STR_3D; -const PROGMEM char* kCelsiusStr = D_STR_CELSIUS; -const PROGMEM char* kTempUpStr = D_STR_TEMPUP; -const PROGMEM char* kTempDownStr = D_STR_TEMPDOWN; -const PROGMEM char* kStartStr = D_STR_START; -const PROGMEM char* kStopStr = D_STR_STOP; -const PROGMEM char* kMoveStr = D_STR_MOVE; -const PROGMEM char* kSetStr = D_STR_SET; -const PROGMEM char* kCancelStr = D_STR_CANCEL; -const PROGMEM char* kUpStr = D_STR_UP; -const PROGMEM char* kDownStr = D_STR_DOWN; -const PROGMEM char* kChangeStr = D_STR_CHANGE; -const PROGMEM char* kComfortStr = D_STR_COMFORT; -const PROGMEM char* kSensorStr = D_STR_SENSOR; -const PROGMEM char* kWeeklyTimerStr = D_STR_WEEKLYTIMER; -const PROGMEM char* kWifiStr = D_STR_WIFI; -const PROGMEM char* kLastStr = D_STR_LAST; -const PROGMEM char* kFastStr = D_STR_FAST; -const PROGMEM char* kSlowStr = D_STR_SLOW; -const PROGMEM char* kAirFlowStr = D_STR_AIRFLOW; -const PROGMEM char* kStepStr = D_STR_STEP; -const PROGMEM char* kNAStr = D_STR_NA; -const PROGMEM char* kOutsideStr = D_STR_OUTSIDE; -const PROGMEM char* kLoudStr = D_STR_LOUD; -const PROGMEM char* kLowerStr = D_STR_LOWER; -const PROGMEM char* kUpperStr = D_STR_UPPER; -const PROGMEM char* kBreezeStr = D_STR_BREEZE; -const PROGMEM char* kCirculateStr = D_STR_CIRCULATE; -const PROGMEM char* kCeilingStr = D_STR_CEILING; -const PROGMEM char* kWallStr = D_STR_WALL; -const PROGMEM char* kRoomStr = D_STR_ROOM; -const PROGMEM char* k6thSenseStr = D_STR_6THSENSE; - -const PROGMEM char* kAutoStr = D_STR_AUTO; -const PROGMEM char* kAutomaticStr = D_STR_AUTOMATIC; -const PROGMEM char* kManualStr = D_STR_MANUAL; -const PROGMEM char* kCoolStr = D_STR_COOL; -const PROGMEM char* kHeatStr = D_STR_HEAT; -const PROGMEM char* kFanStr = D_STR_FAN; -const PROGMEM char* kDryStr = D_STR_DRY; -const PROGMEM char* kFanOnlyStr = D_STR_FANONLY; - -const PROGMEM char* kMaxStr = D_STR_MAX; -const PROGMEM char* kMaximumStr = D_STR_MAXIMUM; -const PROGMEM char* kMinStr = D_STR_MIN; -const PROGMEM char* kMinimumStr = D_STR_MINIMUM; -const PROGMEM char* kMedStr = D_STR_MED; -const PROGMEM char* kMediumStr = D_STR_MEDIUM; - -const PROGMEM char* kHighestStr = D_STR_HIGHEST; -const PROGMEM char* kHighStr = D_STR_HIGH; -const PROGMEM char* kHiStr = D_STR_HI; -const PROGMEM char* kMidStr = D_STR_MID; -const PROGMEM char* kMiddleStr = D_STR_MIDDLE; -const PROGMEM char* kLowStr = D_STR_LOW; -const PROGMEM char* kLoStr = D_STR_LO; -const PROGMEM char* kLowestStr = D_STR_LOWEST; -const PROGMEM char* kMaxRightStr = D_STR_MAXRIGHT; -const PROGMEM char* kRightMaxStr = D_STR_RIGHTMAX_NOSPACE; -const PROGMEM char* kRightStr = D_STR_RIGHT; -const PROGMEM char* kLeftStr = D_STR_LEFT; -const PROGMEM char* kMaxLeftStr = D_STR_MAXLEFT; -const PROGMEM char* kLeftMaxStr = D_STR_LEFTMAX_NOSPACE; -const PROGMEM char* kWideStr = D_STR_WIDE; -const PROGMEM char* kCentreStr = D_STR_CENTRE; -const PROGMEM char* kTopStr = D_STR_TOP; -const PROGMEM char* kBottomStr = D_STR_BOTTOM; - -// Compound words/phrases/descriptions from pre-defined words. -const PROGMEM char* kEyeAutoStr = D_STR_EYEAUTO; -const PROGMEM char* kLightToggleStr = D_STR_LIGHTTOGGLE; -const PROGMEM char* kOutsideQuietStr = D_STR_OUTSIDEQUIET; -const PROGMEM char* kPowerToggleStr = D_STR_POWERTOGGLE; -const PROGMEM char* kPreviousPowerStr = D_STR_PREVIOUSPOWER; -const PROGMEM char* kSensorTempStr = D_STR_SENSORTEMP; -const PROGMEM char* kSleepTimerStr = D_STR_SLEEP_TIMER; -const PROGMEM char* kSwingVModeStr = D_STR_SWINGVMODE; -const PROGMEM char* kSwingVToggleStr = D_STR_SWINGVTOGGLE; - -// Separators -char kTimeSep = D_CHR_TIME_SEP; -const PROGMEM char* kSpaceLBraceStr = D_STR_SPACELBRACE; -const PROGMEM char* kCommaSpaceStr = D_STR_COMMASPACE; -const PROGMEM char* kColonSpaceStr = D_STR_COLONSPACE; - -// IRutils -// - Time -const PROGMEM char* kDayStr = D_STR_DAY; -const PROGMEM char* kDaysStr = D_STR_DAYS; -const PROGMEM char* kHourStr = D_STR_HOUR; -const PROGMEM char* kHoursStr = D_STR_HOURS; -const PROGMEM char* kMinuteStr = D_STR_MINUTE; -const PROGMEM char* kMinutesStr = D_STR_MINUTES; -const PROGMEM char* kSecondStr = D_STR_SECOND; -const PROGMEM char* kSecondsStr = D_STR_SECONDS; -const PROGMEM char* kNowStr = D_STR_NOW; -const PROGMEM char* kThreeLetterDayOfWeekStr = D_STR_THREELETTERDAYS; - -const PROGMEM char* kYesStr = D_STR_YES; -const PROGMEM char* kNoStr = D_STR_NO; -const PROGMEM char* kTrueStr = D_STR_TRUE; -const PROGMEM char* kFalseStr = D_STR_FALSE; - -const PROGMEM char* kRepeatStr = D_STR_REPEAT; -const PROGMEM char* kCodeStr = D_STR_CODE; -const PROGMEM char* kBitsStr = D_STR_BITS; diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Carrier.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Carrier.cpp deleted file mode 100644 index 293711a03..000000000 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Carrier.cpp +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright 2018 David Conran - -// Supports: -// Brand: Carrier/Surrey, Model: 42QG5A55970 remote -// Brand: Carrier/Surrey, Model: 619EGX0090E0 A/C -// Brand: Carrier/Surrey, Model: 619EGX0120E0 A/C -// Brand: Carrier/Surrey, Model: 619EGX0180E0 A/C -// Brand: Carrier/Surrey, Model: 619EGX0220E0 A/C -// Brand: Carrier/Surrey, Model: 53NGK009/012 Inverter - -#include "IRrecv.h" -#include "IRsend.h" -#include "IRutils.h" - -// Constants -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/385 -const uint16_t kCarrierAcHdrMark = 8532; -const uint16_t kCarrierAcHdrSpace = 4228; -const uint16_t kCarrierAcBitMark = 628; -const uint16_t kCarrierAcOneSpace = 1320; -const uint16_t kCarrierAcZeroSpace = 532; -const uint16_t kCarrierAcGap = 20000; - -#if SEND_CARRIER_AC -// Send a Carrier HVAC formatted message. -// -// Args: -// data: The message to be sent. -// nbits: The bit size of the message being sent. typically kCarrierAcBits. -// repeat: The number of times the message is to be repeated. -// -// Status: STABLE / Work on real devices. -// -void IRsend::sendCarrierAC(uint64_t data, uint16_t nbits, uint16_t repeat) { - for (uint16_t r = 0; r <= repeat; r++) { - uint64_t temp_data = data; - // Carrier sends the data block three times. normal + inverted + normal. - for (uint16_t i = 0; i < 3; i++) { - sendGeneric(kCarrierAcHdrMark, kCarrierAcHdrSpace, kCarrierAcBitMark, - kCarrierAcOneSpace, kCarrierAcBitMark, kCarrierAcZeroSpace, - kCarrierAcBitMark, kCarrierAcGap, temp_data, nbits, 38, true, - 0, kDutyDefault); - temp_data = invertBits(temp_data, nbits); - } - } -} -#endif - -#if DECODE_CARRIER_AC -// Decode the supplied Carrier HVAC message. -// Carrier HVAC messages contain only 32 bits, but it is sent three(3) times. -// i.e. normal + inverted + normal -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits to expect in the data portion. -// Typically kCarrierAcBits. -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: BETA / Probably works. -// -bool IRrecv::decodeCarrierAC(decode_results *results, uint16_t offset, - const uint16_t nbits, const bool strict) { - if (results->rawlen < ((2 * nbits + kHeader + kFooter) * 3) - 1 + offset) - return false; // Can't possibly be a valid Carrier message. - if (strict && nbits != kCarrierAcBits) - return false; // We expect Carrier to be 32 bits of message. - - uint64_t data = 0; - uint64_t prev_data = 0; - - for (uint8_t i = 0; i < 3; i++) { - prev_data = data; - // Match Header + Data + Footer - uint16_t used; - used = matchGeneric(results->rawbuf + offset, &data, - results->rawlen - offset, nbits, - kCarrierAcHdrMark, kCarrierAcHdrSpace, - kCarrierAcBitMark, kCarrierAcOneSpace, - kCarrierAcBitMark, kCarrierAcZeroSpace, - kCarrierAcBitMark, kCarrierAcGap, true); - if (!used) return false; - offset += used; - // Compliance. - if (strict) { - // Check if the data is an inverted copy of the previous data. - if (i > 0 && prev_data != invertBits(data, nbits)) return false; - } - } - - // Success - results->bits = nbits; - results->value = data; - results->decode_type = CARRIER_AC; - results->address = data >> 16; - results->command = data & 0xFFFF; - return true; -} -#endif diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Pronto.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Pronto.cpp deleted file mode 100644 index 6b7a779de..000000000 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Pronto.cpp +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright 2017 David Conran - -// Pronto code message generation - -#include -#include "IRsend.h" - -// Constants -const float kProntoFreqFactor = 0.241246; -const uint16_t kProntoTypeOffset = 0; -const uint16_t kProntoFreqOffset = 1; -const uint16_t kProntoSeq1LenOffset = 2; -const uint16_t kProntoSeq2LenOffset = 3; -const uint16_t kProntoDataOffset = 4; - -#if SEND_PRONTO -// Send a Pronto Code formatted message. -// -// Args: -// data: An array of uint16_t containing the pronto codes. -// len: Nr. of entries in the data[] array. -// repeat: Nr. of times to repeat the message. -// -// Status: STABLE / Known working. -// -// Note: -// Pronto codes are typically represented in hexadecimal. -// You will need to convert the code to an array of integers, and calculate -// it's length. -// e.g. -// A Sony 20 bit DVD remote command. -// "0000 0067 0000 0015 0060 0018 0018 0018 0030 0018 0030 0018 0030 0018 -// 0018 0018 0030 0018 0018 0018 0018 0018 0030 0018 0018 0018 0030 0018 -// 0030 0018 0030 0018 0018 0018 0018 0018 0030 0018 0018 0018 0018 0018 -// 0030 0018 0018 03f6" -// -// converts to: -// -// uint16_t prontoCode[46] = { -// 0x0000, 0x0067, 0x0000, 0x0015, -// 0x0060, 0x0018, 0x0018, 0x0018, 0x0030, 0x0018, 0x0030, 0x0018, -// 0x0030, 0x0018, 0x0018, 0x0018, 0x0030, 0x0018, 0x0018, 0x0018, -// 0x0018, 0x0018, 0x0030, 0x0018, 0x0018, 0x0018, 0x0030, 0x0018, -// 0x0030, 0x0018, 0x0030, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, -// 0x0030, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0030, 0x0018, -// 0x0018, 0x03f6}; -// // Send the Pronto(Sony) code. Repeat twice as Sony's require that. -// sendPronto(prontoCode, 46, kSonyMinRepeat); -// -// Ref: -// http://www.etcwiki.org/wiki/Pronto_Infrared_Format -// http://www.remotecentral.com/features/irdisp2.htm -void IRsend::sendPronto(uint16_t data[], uint16_t len, uint16_t repeat) { - // Check we have enough data to work out what to send. - if (len < kProntoMinLength) return; - - // We only know how to deal with 'raw' pronto codes types. Reject all others. - if (data[kProntoTypeOffset] != 0) return; - - // Pronto frequency is in Hz. - uint16_t hz = - (uint16_t)(1000000U / (data[kProntoFreqOffset] * kProntoFreqFactor)); - enableIROut(hz); - - // Grab the length of the two sequences. - uint16_t seq_1_len = data[kProntoSeq1LenOffset] * 2; - uint16_t seq_2_len = data[kProntoSeq2LenOffset] * 2; - // Calculate where each sequence starts in the buffer. - uint16_t seq_1_start = kProntoDataOffset; - uint16_t seq_2_start = kProntoDataOffset + seq_1_len; - - uint32_t periodic_time = calcUSecPeriod(hz, false); - - // Normal (1st sequence) case. - // Is there a first (normal) sequence to send? - if (seq_1_len > 0) { - // Check we have enough data to send the complete first sequence. - if (seq_1_len + seq_1_start > len) return; - // Send the contents of the 1st sequence. - for (uint16_t i = seq_1_start; i < seq_1_start + seq_1_len; i += 2) { - mark(data[i] * periodic_time); - space(data[i + 1] * periodic_time); - } - } else { - // There was no first sequence to send, it is implied that we have to send - // the 2nd/repeat sequence an additional time. i.e. At least once. - repeat++; - } - - // Repeat (2nd sequence) case. - // Is there a second (repeat) sequence to be sent? - if (seq_2_len > 0) { - // Check we have enough data to send the complete second sequence. - if (seq_2_len + seq_2_start > len) return; - - // Send the contents of the 2nd sequence. - for (uint16_t r = 0; r < repeat; r++) - for (uint16_t i = seq_2_start; i < seq_2_start + seq_2_len; i += 2) { - mark(data[i] * periodic_time); - space(data[i + 1] * periodic_time); - } - } -} -#endif diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Sharp.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Sharp.cpp deleted file mode 100644 index 363271012..000000000 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Sharp.cpp +++ /dev/null @@ -1,576 +0,0 @@ -// Copyright 2009 Ken Shirriff -// Copyright 2017, 2019 David Conran - -// Sharp remote emulation - -#include "ir_Sharp.h" -#include -#include -#ifndef ARDUINO -#include -#endif -#include "IRrecv.h" -#include "IRsend.h" -#include "IRtext.h" -#include "IRutils.h" - -// Equipment it seems compatible with: -// * Sharp LC-52D62U -// * Sharp AH-AxSAY A/C (Remote CRMC-A907 JBEZ) -// * -// - -// Constants -// period time = 1/38000Hz = 26.316 microseconds. -// Ref: -// GlobalCache's IR Control Tower data. -// http://www.sbprojects.com/knowledge/ir/sharp.php -const uint16_t kSharpTick = 26; -const uint16_t kSharpBitMarkTicks = 10; -const uint16_t kSharpBitMark = kSharpBitMarkTicks * kSharpTick; -const uint16_t kSharpOneSpaceTicks = 70; -const uint16_t kSharpOneSpace = kSharpOneSpaceTicks * kSharpTick; -const uint16_t kSharpZeroSpaceTicks = 30; -const uint16_t kSharpZeroSpace = kSharpZeroSpaceTicks * kSharpTick; -const uint16_t kSharpGapTicks = 1677; -const uint16_t kSharpGap = kSharpGapTicks * kSharpTick; -// Address(5) + Command(8) + Expansion(1) + Check(1) -const uint64_t kSharpToggleMask = - ((uint64_t)1 << (kSharpBits - kSharpAddressBits)) - 1; -const uint64_t kSharpAddressMask = ((uint64_t)1 << kSharpAddressBits) - 1; -const uint64_t kSharpCommandMask = ((uint64_t)1 << kSharpCommandBits) - 1; - -using irutils::addBoolToString; -using irutils::addFanToString; -using irutils::addIntToString; -using irutils::addLabeledString; -using irutils::addModeToString; -using irutils::addTempToString; -using irutils::setBit; -using irutils::setBits; - -#if (SEND_SHARP || SEND_DENON) -// Send a (raw) Sharp message -// -// Args: -// data: Contents of the message to be sent. -// nbits: Nr. of bits of data to be sent. Typically kSharpBits. -// repeat: Nr. of additional times the message is to be sent. -// -// Status: STABLE / Working fine. -// -// Notes: -// This procedure handles the inversion of bits required per protocol. -// The protocol spec says to send the LSB first, but legacy code & usage -// has us sending the MSB first. Grrrr. Normal invocation of encodeSharp() -// handles this for you, assuming you are using the correct/standard values. -// e.g. sendSharpRaw(encodeSharp(address, command)); -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/sharp.htm -// http://lirc.sourceforge.net/remotes/sharp/GA538WJSA -// http://www.mwftr.com/ucF08/LEC14%20PIC%20IR.pdf -// http://www.hifi-remote.com/johnsfine/DecodeIR.html#Sharp -void IRsend::sendSharpRaw(const uint64_t data, const uint16_t nbits, - const uint16_t repeat) { - uint64_t tempdata = data; - for (uint16_t i = 0; i <= repeat; i++) { - // Protocol demands that the data be sent twice; once normally, - // then with all but the address bits inverted. - // Note: Previously this used to be performed 3 times (normal, inverted, - // normal), however all data points to that being incorrect. - for (uint8_t n = 0; n < 2; n++) { - sendGeneric(0, 0, // No Header - kSharpBitMark, kSharpOneSpace, kSharpBitMark, kSharpZeroSpace, - kSharpBitMark, kSharpGap, tempdata, nbits, 38, true, - 0, // Repeats are handled already. - 33); - // Invert the data per protocol. This is always called twice, so it's - // retured to original upon exiting the inner loop. - tempdata ^= kSharpToggleMask; - } - } -} - -// Encode a (raw) Sharp message from it's components. -// -// Args: -// address: The value of the address to be sent. -// command: The value of the address to be sent. (8 bits) -// expansion: The value of the expansion bit to use. (0 or 1, typically 1) -// check: The value of the check bit to use. (0 or 1, typically 0) -// MSBfirst: Flag indicating MSB first or LSB first order. (Default: false) -// Returns: -// An uint32_t containing the raw Sharp message for sendSharpRaw(). -// -// Status: STABLE / Works okay. -// -// Notes: -// Assumes the standard Sharp bit sizes. -// Historically sendSharp() sends address & command in -// MSB first order. This is actually incorrect. It should be sent in LSB -// order. The behaviour of sendSharp() hasn't been changed to maintain -// backward compatibility. -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/sharp.htm -// http://lirc.sourceforge.net/remotes/sharp/GA538WJSA -// http://www.mwftr.com/ucF08/LEC14%20PIC%20IR.pdf -uint32_t IRsend::encodeSharp(const uint16_t address, const uint16_t command, - const uint16_t expansion, const uint16_t check, - const bool MSBfirst) { - // Mask any unexpected bits. - uint16_t tempaddress = GETBITS16(address, 0, kSharpAddressBits); - uint16_t tempcommand = GETBITS16(command, 0, kSharpCommandBits); - uint16_t tempexpansion = GETBITS16(expansion, 0, 1); - uint16_t tempcheck = GETBITS16(check, 0, 1); - - if (!MSBfirst) { // Correct bit order if needed. - tempaddress = reverseBits(tempaddress, kSharpAddressBits); - tempcommand = reverseBits(tempcommand, kSharpCommandBits); - } - // Concatinate all the bits. - return (tempaddress << (kSharpCommandBits + 2)) | (tempcommand << 2) | - (tempexpansion << 1) | tempcheck; -} - -// Send a Sharp message -// -// Args: -// address: Address value to be sent. -// command: Command value to be sent. -// nbits: Nr. of bits of data to be sent. Typically kSharpBits. -// repeat: Nr. of additional times the message is to be sent. -// -// Status: DEPRICATED / Previously working fine. -// -// Notes: -// This procedure has a non-standard invocation style compared to similar -// sendProtocol() routines. This is due to legacy, compatibility, & historic -// reasons. Normally the calling syntax version is like sendSharpRaw(). -// This procedure transmits the address & command in MSB first order, which is -// incorrect. This behaviour is left as-is to maintain backward -// compatibility with legacy code. -// In short, you should use sendSharpRaw(), encodeSharp(), and the correct -// values of address & command instead of using this, & the wrong values. -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/sharp.htm -// http://lirc.sourceforge.net/remotes/sharp/GA538WJSA -// http://www.mwftr.com/ucF08/LEC14%20PIC%20IR.pdf -void IRsend::sendSharp(const uint16_t address, uint16_t const command, - const uint16_t nbits, const uint16_t repeat) { - sendSharpRaw(encodeSharp(address, command, 1, 0, true), nbits, repeat); -} -#endif // (SEND_SHARP || SEND_DENON) - -#if (DECODE_SHARP || DECODE_DENON) -// Decode the supplied Sharp message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data -// Typically/Defaults to kStartOffset. -// nbits: Nr. of data bits to expect. Typically kSharpBits. -// strict: Flag indicating if we should perform strict matching. -// expansion: Should we expect the expansion bit to be set. Default is true. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Working fine. -// -// Note: -// This procedure returns a value suitable for use in sendSharpRaw(). -// TODO(crankyoldgit): Need to ensure capture of the inverted message as it can -// be missed due to the interrupt timeout used to detect an end of message. -// Several compliance checks are disabled until that is resolved. -// Ref: -// http://www.sbprojects.com/knowledge/ir/sharp.php -// http://www.mwftr.com/ucF08/LEC14%20PIC%20IR.pdf -// http://www.hifi-remote.com/johnsfine/DecodeIR.html#Sharp -bool IRrecv::decodeSharp(decode_results *results, uint16_t offset, - const uint16_t nbits, const bool strict, - const bool expansion) { - if (results->rawlen <= 2 * nbits + kFooter - 1 + offset) - return false; // Not enough entries to be a Sharp message. - // Compliance - if (strict) { - if (nbits != kSharpBits) return false; // Request is out of spec. - // DISABLED - See TODO -#ifdef UNIT_TEST - // An in spec message has the data sent normally, then inverted. So we - // expect twice as many entries than to just get the results. - if (results->rawlen <= (2 * (2 * nbits + kFooter)) - 1 + offset) - return false; -#endif - } - - uint64_t data = 0; - - // Match Data + Footer - uint16_t used; - used = matchGeneric(results->rawbuf + offset, &data, - results->rawlen - offset, nbits, - 0, 0, // No Header - kSharpBitMark, kSharpOneSpace, - kSharpBitMark, kSharpZeroSpace, - kSharpBitMark, kSharpGap, true, 35); - if (!used) return false; - offset += used; - // Compliance - if (strict) { - // Check the state of the expansion bit is what we expect. - if ((data & 0b10) >> 1 != expansion) return false; - // The check bit should be cleared in a normal message. - if (data & 0b1) return false; - // DISABLED - See TODO -#ifdef UNIT_TEST - // Grab the second copy of the data (i.e. inverted) - uint64_t second_data = 0; - // Match Data + Footer - if (!matchGeneric(results->rawbuf + offset, &second_data, - results->rawlen - offset, nbits, - 0, 0, - kSharpBitMark, kSharpOneSpace, - kSharpBitMark, kSharpZeroSpace, - kSharpBitMark, kSharpGap, true, 35)) return false; - // Check that second_data has been inverted correctly. - if (data != (second_data ^ kSharpToggleMask)) return false; -#endif // UNIT_TEST - } - - // Success - results->decode_type = SHARP; - results->bits = nbits; - results->value = data; - // Address & command are actually transmitted in LSB first order. - results->address = reverseBits(data, nbits) & kSharpAddressMask; - results->command = - reverseBits((data >> 2) & kSharpCommandMask, kSharpCommandBits); - return true; -} -#endif // (DECODE_SHARP || DECODE_DENON) - -#if SEND_SHARP_AC -// Send a Sharp A/C message. -// -// Args: -// data: An array of kSharpAcStateLength bytes containing the IR command. -// nbytes: Nr. of bytes of data to send. i.e. length of `data`. -// repeat: Nr. of times the message should be repeated. -// -// Status: Alpha / Untested. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/638 -// https://github.com/ToniA/arduino-heatpumpir/blob/master/SharpHeatpumpIR.cpp -void IRsend::sendSharpAc(const unsigned char data[], const uint16_t nbytes, - const uint16_t repeat) { - if (nbytes < kSharpAcStateLength) - return; // Not enough bytes to send a proper message. - - sendGeneric(kSharpAcHdrMark, kSharpAcHdrSpace, - kSharpAcBitMark, kSharpAcOneSpace, - kSharpAcBitMark, kSharpAcZeroSpace, - kSharpAcBitMark, kSharpAcGap, - data, nbytes, 38000, false, repeat, 50); -} -#endif // SEND_SHARP_AC - -IRSharpAc::IRSharpAc(const uint16_t pin, const bool inverted, - const bool use_modulation) - : _irsend(pin, inverted, use_modulation) { this->stateReset(); } - -void IRSharpAc::begin(void) { _irsend.begin(); } - -#if SEND_SHARP_AC -void IRSharpAc::send(const uint16_t repeat) { - _irsend.sendSharpAc(getRaw(), kSharpAcStateLength, repeat); -} -#endif // SEND_SHARP_AC - -// Calculate the checksum for a given state. -// Args: -// state: The array to verify the checksums of. -// length: The size of the state. -// Returns: -// The 4 bit checksum. -uint8_t IRSharpAc::calcChecksum(uint8_t state[], const uint16_t length) { - uint8_t xorsum = xorBytes(state, length - 1); - xorsum ^= GETBITS8(state[length - 1], kLowNibble, kNibbleSize); - xorsum ^= GETBITS8(xorsum, kHighNibble, kNibbleSize); - return GETBITS8(xorsum, kLowNibble, kNibbleSize); -} - -// Verify the checksums are valid for a given state. -// Args: -// state: The array to verify the checksums of. -// length: The size of the state. -// Returns: -// A boolean. -bool IRSharpAc::validChecksum(uint8_t state[], const uint16_t length) { - return GETBITS8(state[length - 1], kHighNibble, kNibbleSize) == - IRSharpAc::calcChecksum(state, length); -} - -// Calculate and set the checksum values for the internal state. -void IRSharpAc::checksum(void) { - setBits(&remote[kSharpAcStateLength - 1], kHighNibble, kNibbleSize, - this->calcChecksum(remote)); -} - -void IRSharpAc::stateReset(void) { - static const uint8_t reset[kSharpAcStateLength] = { - 0xAA, 0x5A, 0xCF, 0x10, 0x00, 0x01, 0x00, 0x00, 0x08, 0x80, 0x00, 0xE0, - 0x01}; - memcpy(remote, reset, kSharpAcStateLength); -} - -uint8_t *IRSharpAc::getRaw(void) { - this->checksum(); // Ensure correct settings before sending. - return remote; -} - -void IRSharpAc::setRaw(const uint8_t new_code[], const uint16_t length) { - memcpy(remote, new_code, std::min(length, kSharpAcStateLength)); -} - -void IRSharpAc::setPreviousPower(const bool on) { - setBit(&remote[kSharpAcBytePower], kSharpAcBitPreviousPowerOffset, on); -} - -bool IRSharpAc::getPreviousPower(void) { - return GETBIT8(remote[kSharpAcBytePower], kSharpAcBitPreviousPowerOffset); -} - -void IRSharpAc::on(void) { setPower(true); } - -void IRSharpAc::off(void) { setPower(false); } - -void IRSharpAc::setPower(const bool on) { - setPreviousPower(getPower()); - setBit(&remote[kSharpAcBytePower], kSharpAcBitPowerOffset, on); - setButton(kSharpAcButtonPowerMode); -} - -void IRSharpAc::setPower(const bool on, const bool prev) { - setPower(on); - setPreviousPower(prev); -} - -bool IRSharpAc::getPower(void) { - return GETBIT8(remote[kSharpAcBytePower], kSharpAcBitPowerOffset); -} - -void IRSharpAc::setButton(const uint8_t button) { - switch (button) { - case kSharpAcButtonPowerMode: - case kSharpAcButtonTemp: - case kSharpAcButtonFan: - setBits(&remote[kSharpAcByteButton], kSharpAcButtonOffset, - kSharpAcButtonSize, button); - break; - default: - setButton(kSharpAcButtonPowerMode); - } -} - -uint8_t IRSharpAc::getButton(void) { - return GETBITS8(remote[kSharpAcByteButton], kSharpAcButtonOffset, - kSharpAcButtonSize); -} - -// Set the temp in deg C -void IRSharpAc::setTemp(const uint8_t temp) { - switch (this->getMode()) { - // Auto & Dry don't allow temp changes and have a special temp. - case kSharpAcAuto: - case kSharpAcDry: - remote[kSharpAcByteTemp] = 0; - return; - default: - remote[kSharpAcByteTemp] = 0xC0; - } - uint8_t degrees = std::max(temp, kSharpAcMinTemp); - degrees = std::min(degrees, kSharpAcMaxTemp); - setBits(&remote[kSharpAcByteTemp], kLowNibble, kNibbleSize, - degrees - kSharpAcMinTemp); - setButton(kSharpAcButtonTemp); -} - -uint8_t IRSharpAc::getTemp(void) { - return GETBITS8(remote[kSharpAcByteTemp], kLowNibble, kNibbleSize) + - kSharpAcMinTemp; -} - -uint8_t IRSharpAc::getMode(void) { - return GETBITS8(remote[kSharpAcByteMode], kLowNibble, kSharpAcModeSize); -} - -void IRSharpAc::setMode(const uint8_t mode) { - switch (mode) { - case kSharpAcAuto: - case kSharpAcDry: - this->setFan(2); // When Dry or Auto, Fan always 2(Auto) - this->setTemp(0); // Dry/Auto have no temp setting. - // FALLTHRU - case kSharpAcCool: - case kSharpAcHeat: - setBits(&remote[kSharpAcByteMode], kLowNibble, kSharpAcModeSize, mode); - break; - default: - this->setMode(kSharpAcAuto); - } - setButton(kSharpAcButtonPowerMode); -} - -// Set the speed of the fan -void IRSharpAc::setFan(const uint8_t speed) { - switch (speed) { - case kSharpAcFanAuto: - case kSharpAcFanMin: - case kSharpAcFanMed: - case kSharpAcFanHigh: - case kSharpAcFanMax: - setBits(&remote[kSharpAcByteFan], kSharpAcFanOffset, kSharpAcFanSize, - speed); - break; - default: - this->setFan(kSharpAcFanAuto); - } - setButton(kSharpAcButtonFan); -} - -uint8_t IRSharpAc::getFan(void) { - return GETBITS8(remote[kSharpAcByteFan], kSharpAcFanOffset, kSharpAcFanSize); -} - -// Convert a standard A/C mode into its native mode. -uint8_t IRSharpAc::convertMode(const stdAc::opmode_t mode) { - switch (mode) { - case stdAc::opmode_t::kCool: return kSharpAcCool; - case stdAc::opmode_t::kHeat: return kSharpAcHeat; - case stdAc::opmode_t::kDry: return kSharpAcDry; - // No Fan mode. - default: return kSharpAcAuto; - } -} - -// Convert a standard A/C Fan speed into its native fan speed. -uint8_t IRSharpAc::convertFan(const stdAc::fanspeed_t speed) { - switch (speed) { - case stdAc::fanspeed_t::kMin: - case stdAc::fanspeed_t::kLow: return kSharpAcFanMin; - case stdAc::fanspeed_t::kMedium: return kSharpAcFanMed; - case stdAc::fanspeed_t::kHigh: return kSharpAcFanHigh; - case stdAc::fanspeed_t::kMax: return kSharpAcFanMax; - default: return kSharpAcFanAuto; - } -} - -// Convert a native mode to it's common equivalent. -stdAc::opmode_t IRSharpAc::toCommonMode(const uint8_t mode) { - switch (mode) { - case kSharpAcCool: return stdAc::opmode_t::kCool; - case kSharpAcHeat: return stdAc::opmode_t::kHeat; - case kSharpAcDry: return stdAc::opmode_t::kDry; - default: return stdAc::opmode_t::kAuto; - } -} - -// Convert a native fan speed to it's common equivalent. -stdAc::fanspeed_t IRSharpAc::toCommonFanSpeed(const uint8_t speed) { - switch (speed) { - case kSharpAcFanMax: return stdAc::fanspeed_t::kMax; - case kSharpAcFanHigh: return stdAc::fanspeed_t::kHigh; - case kSharpAcFanMed: return stdAc::fanspeed_t::kMedium; - case kSharpAcFanMin: return stdAc::fanspeed_t::kMin; - default: return stdAc::fanspeed_t::kAuto; - } -} - -// Convert the A/C state to it's common equivalent. -stdAc::state_t IRSharpAc::toCommon(void) { - stdAc::state_t result; - result.protocol = decode_type_t::SHARP_AC; - result.model = -1; // Not supported. - result.power = this->getPower(); - result.mode = this->toCommonMode(this->getMode()); - result.celsius = true; - result.degrees = this->getTemp(); - result.fanspeed = this->toCommonFanSpeed(this->getFan()); - // Not supported. - result.swingv = stdAc::swingv_t::kOff; - result.swingh = stdAc::swingh_t::kOff; - result.quiet = false; - result.turbo = false; - result.clean = false; - result.beep = false; - result.econo = false; - result.filter = false; - result.light = false; - result.sleep = -1; - result.clock = -1; - return result; -} - -// Convert the internal state into a human readable string. -String IRSharpAc::toString(void) { - String result = ""; - result.reserve(80); // Reserve some heap for the string to reduce fragging. - result += addBoolToString(getPower(), kPowerStr, false); - result += addBoolToString(getPreviousPower(), kPreviousPowerStr); - result += addModeToString(getMode(), kSharpAcAuto, kSharpAcCool, kSharpAcHeat, - kSharpAcDry, kSharpAcAuto); - result += addTempToString(getTemp()); - result += addFanToString(getFan(), kSharpAcFanMax, kSharpAcFanMin, - kSharpAcFanAuto, kSharpAcFanAuto, kSharpAcFanMed); - return result; -} - -#if DECODE_SHARP_AC -// Decode the supplied Sharp A/C message. -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits to expect in the data portion. (kSharpAcBits) -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Known working. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/638 -// https://github.com/ToniA/arduino-heatpumpir/blob/master/SharpHeatpumpIR.cpp -bool IRrecv::decodeSharpAc(decode_results *results, uint16_t offset, - const uint16_t nbits, const bool strict) { - // Compliance - if (strict && nbits != kSharpAcBits) return false; - - // Match Header + Data + Footer - uint16_t used; - used = matchGeneric(results->rawbuf + offset, results->state, - results->rawlen - offset, nbits, - kSharpAcHdrMark, kSharpAcHdrSpace, - kSharpAcBitMark, kSharpAcOneSpace, - kSharpAcBitMark, kSharpAcZeroSpace, - kSharpAcBitMark, kSharpAcGap, true, - _tolerance, kMarkExcess, false); - if (used == 0) return false; - offset += used; - // Compliance - if (strict) { - if (!IRSharpAc::validChecksum(results->state)) return false; - } - - // Success - results->decode_type = SHARP_AC; - results->bits = nbits; - // No need to record the state as we stored it as we decoded it. - // As we use result->state, we don't record value, address, or command as it - // is a union data type. - return true; -} -#endif // DECODE_SHARP_AC diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Sharp.h b/lib/IRremoteESP8266-2.7.5/src/ir_Sharp.h deleted file mode 100644 index 03d27d44f..000000000 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Sharp.h +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright 2019 crankyoldgit - -// Supports: -// Brand: Sharp, Model: LC-52D62U TV -// Brand: Sharp, Model: AY-ZP40KR A/C -// Brand: Sharp, Model: AH-AxSAY A/C - -#ifndef IR_SHARP_H_ -#define IR_SHARP_H_ - -#ifndef UNIT_TEST -#include -#endif -#include "IRrecv.h" -#include "IRremoteESP8266.h" -#include "IRsend.h" -#ifdef UNIT_TEST -#include "IRsend_test.h" -#endif - -// Constants -const uint16_t kSharpAcHdrMark = 3800; -const uint16_t kSharpAcHdrSpace = 1900; -const uint16_t kSharpAcBitMark = 470; -const uint16_t kSharpAcZeroSpace = 500; -const uint16_t kSharpAcOneSpace = 1400; -const uint32_t kSharpAcGap = kDefaultMessageGap; - -const uint8_t kSharpAcAuto = 0b000; -const uint8_t kSharpAcDry = 0b011; -const uint8_t kSharpAcCool = 0b010; -const uint8_t kSharpAcHeat = 0b001; -const uint8_t kSharpAcMinTemp = 15; // Celsius -const uint8_t kSharpAcMaxTemp = 30; // Celsius -const uint8_t kSharpAcFanAuto = 0b010; // 2 -const uint8_t kSharpAcFanMin = 0b100; // 4 (FAN1) -const uint8_t kSharpAcFanMed = 0b011; // 3 (FAN2) -const uint8_t kSharpAcFanHigh = 0b101; // 5 (FAN3) -const uint8_t kSharpAcFanMax = 0b111; // 7 (FAN4) -const uint8_t kSharpAcByteTemp = 4; -const uint8_t kSharpAcBytePower = 5; -const uint8_t kSharpAcBitPowerOffset = 4; // 0b000x0000 -const uint8_t kSharpAcBitPreviousPowerOffset = 5; // 0b00x00000 -const uint8_t kSharpAcByteMode = 6; -const uint8_t kSharpAcModeSize = 2; // Mask 0b00000011; -const uint8_t kSharpAcByteFan = kSharpAcByteMode; -const uint8_t kSharpAcFanOffset = 4; // Mask 0b01110000 -const uint8_t kSharpAcFanSize = 3; // Nr. of Bits -const uint8_t kSharpAcByteButton = 10; -const uint8_t kSharpAcButtonOffset = 0; -const uint8_t kSharpAcButtonSize = 3; // Mask 0b00000xxx -const uint8_t kSharpAcButtonPowerMode = 0b000; // 0 -const uint8_t kSharpAcButtonTemp = 0b100; // 4 -const uint8_t kSharpAcButtonFan = 0b101; // 5 - -class IRSharpAc { - public: - explicit IRSharpAc(const uint16_t pin, const bool inverted = false, - const bool use_modulation = true); - -#if SEND_SHARP_AC - void send(const uint16_t repeat = kSharpAcDefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } -#endif // SEND_SHARP_AC - void begin(void); - void on(void); - void off(void); - void setPower(const bool on); - void setPower(const bool on, const bool prev); - bool getPower(void); - void setPreviousPower(const bool on); - bool getPreviousPower(void); - void setTemp(const uint8_t temp); - uint8_t getTemp(void); - void setFan(const uint8_t fan); - uint8_t getFan(void); - void setMode(const uint8_t mode); - uint8_t getMode(void); - void setButton(const uint8_t button); - uint8_t getButton(void); - uint8_t* getRaw(void); - void setRaw(const uint8_t new_code[], - const uint16_t length = kSharpAcStateLength); - static bool validChecksum(uint8_t state[], - const uint16_t length = kSharpAcStateLength); - static uint8_t convertMode(const stdAc::opmode_t mode); - static uint8_t convertFan(const stdAc::fanspeed_t speed); - static stdAc::opmode_t toCommonMode(const uint8_t mode); - static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed); - stdAc::state_t toCommon(void); - String toString(void); -#ifndef UNIT_TEST - - private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - // # of bytes per command - uint8_t remote[kSharpAcStateLength]; - void stateReset(void); - void checksum(void); - static uint8_t calcChecksum(uint8_t state[], - const uint16_t length = kSharpAcStateLength); -}; - -#endif // IR_SHARP_H_ diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Sherwood.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Sherwood.cpp deleted file mode 100644 index 47c6790de..000000000 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Sherwood.cpp +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2017 David Conran - -// Sherwood IR remote emulation - -// Supports: -// Brand: Sherwood, Model: RC-138 remote -// Brand: Sherwood, Model: RD6505(B) Receiver - -#include -#include "IRsend.h" - -#if SEND_SHERWOOD -// Send an IR command to a Sherwood device. -// -// Args: -// data: The contents of the command you want to send. -// nbits: The bit size of the command being sent. (kSherwoodBits) -// repeat: The nr. of times you want the command to be repeated. (Default: 1) -// -// Status: STABLE / Known working. -// -// Note: -// Sherwood remote codes appear to be NEC codes with a manditory repeat code. -// i.e. repeat should be >= kSherwoodMinRepeat (1). -void IRsend::sendSherwood(uint64_t data, uint16_t nbits, uint16_t repeat) { - sendNEC(data, nbits, std::max((uint16_t)kSherwoodMinRepeat, repeat)); -} -#endif diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Symphony.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Symphony.cpp deleted file mode 100644 index f0194fdb8..000000000 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Symphony.cpp +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright 2020 David Conran - -// Send & decode support for Symphony added by David Conran - -// Supports: -// Brand: Symphony, Model: Air Cooler 3Di - -#include -#include "IRrecv.h" -#include "IRsend.h" -#include "IRtimer.h" -#include "IRutils.h" - -// Constants -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/1057 -const uint16_t kSymphonyZeroMark = 1250; -const uint16_t kSymphonyZeroSpace = 400; -const uint16_t kSymphonyOneMark = kSymphonyZeroSpace; -const uint16_t kSymphonyOneSpace = kSymphonyZeroMark; -const uint16_t kSymphonyFooterMark = kSymphonyOneMark; -const uint32_t kSymphonyFooterGap = 8000; - -#if SEND_SYMPHONY -// Send a Symphony packet. -// -// Args: -// data: The data we want to send. MSB first. -// nbits: The number of bits of data to send. (Typically 12, 24, or 32[Nokia]) -// repeat: The nr. of times the message should be sent. -// -// Status: STABLE / Should be working. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/1057 -void IRsend::sendSymphony(uint64_t data, uint16_t nbits, uint16_t repeat) { - sendGeneric(0, 0, - kSymphonyOneMark, kSymphonyOneSpace, - kSymphonyZeroMark, kSymphonyZeroSpace, - kSymphonyFooterMark, kSymphonyFooterGap, - data, nbits, 38000, true, repeat, kDutyDefault); -} -#endif // SEND_SYMPHONY - -#if DECODE_SYMPHONY -// Decode a Symphony packet if possible. -// Places successful decode information in the results pointer. -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits to expect in the data portion. Typically kSymphonyBits -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Should be working. -// -// Ref: -// -bool IRrecv::decodeSymphony(decode_results *results, uint16_t offset, - const uint16_t nbits, const bool strict) { - uint64_t data = 0; - - if (results->rawlen < 2 * nbits + kFooter + offset - 1) - return false; // Not enough entries to ever be SYMPHONY. - // Compliance - if (strict && nbits != kSymphonyBits) return false; - - if (!matchGeneric(results->rawbuf + offset, &data, results->rawlen - offset, - nbits, - 0, 0, // No Header - kSymphonyOneMark, kSymphonyOneSpace, - kSymphonyZeroMark, kSymphonyZeroSpace, - kSymphonyFooterMark, kSymphonyFooterGap, true, - _tolerance, 0)) - return false; - - // Success - results->value = data; - results->decode_type = decode_type_t::SYMPHONY; - results->bits = nbits; - results->address = 0; - results->command = 0; - return true; -} -#endif // DECODE_SYMPHONY diff --git a/lib/IRremoteESP8266-2.7.5/test/Makefile b/lib/IRremoteESP8266-2.7.5/test/Makefile deleted file mode 100644 index dc0574a1d..000000000 --- a/lib/IRremoteESP8266-2.7.5/test/Makefile +++ /dev/null @@ -1,653 +0,0 @@ -# SYNOPSIS: -# -# make [all] - makes everything. -# make TARGET - makes the given target. -# make run - makes everything and runs all the tests. -# make clean - removes all files generated by make. -# make install-googletest - install the googletest code suite - -# Please tweak the following variable definitions as needed by your -# project, except GTEST_HEADERS, which you can use in your own targets -# but shouldn't modify. - -# 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 - -# Where to find user code. -USER_DIR = ../src -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 - -# Flags passed to the C++ compiler. -CXXFLAGS += -g -Wall -Wextra -pthread -std=gnu++11 - -# All tests produced by this Makefile. Remember to add new tests you -# created to the list. -TESTS = IRutils_test IRsend_test ir_NEC_test ir_GlobalCache_test \ - ir_Sherwood_test ir_Sony_test ir_Samsung_test ir_Kelvinator_test \ - ir_JVC_test ir_RCMM_test ir_LG_test ir_Mitsubishi_test ir_Sharp_test \ - ir_RC5_RC6_test ir_Panasonic_test ir_Dish_test ir_Whynter_test \ - ir_Aiwa_test ir_Denon_test ir_Sanyo_test ir_Daikin_test ir_Coolix_test \ - ir_Gree_test IRrecv_test ir_Pronto_test ir_Fujitsu_test ir_Nikai_test \ - ir_Toshiba_test ir_Midea_test ir_Magiquest_test ir_Lasertag_test \ - ir_Carrier_test ir_Haier_test ir_Hitachi_test ir_GICable_test \ - ir_Whirlpool_test ir_Lutron_test ir_Electra_test ir_Pioneer_test \ - ir_MWM_test ir_Vestel_test ir_Teco_test ir_Tcl_test ir_Lego_test IRac_test \ - ir_MitsubishiHeavy_test ir_Trotec_test ir_Argo_test ir_Goodweather_test \ - ir_Inax_test ir_Neoclima_test ir_Amcor_test ir_Epson_test ir_Symphony_test \ - ir_Airwell_test - -# All Google Test headers. Usually you shouldn't change this -# definition. -GTEST_HEADERS = $(GTEST_DIR)/include/gtest/*.h \ - $(GTEST_DIR)/include/gtest/internal/*.h - -# House-keeping build targets. - -all : $(TESTS) - -clean : - rm -f $(TESTS) gtest.a gtest_main.a *.o - -# Build and run all the tests. -run : all - failed=""; \ - for unittest in $(TESTS); do \ - ./$${unittest} || failed="$${failed} $${unittest}"; \ - done; \ - if [ -n "$${failed}" ]; then \ - echo "FAIL: :-( :-( Unit test(s)$${failed} failed! :-( :-("; exit 1; \ - else \ - echo "PASS: \o/ \o/ All unit tests passed. \o/ \o/"; \ - fi - -run_tests : run - -install-googletest : - git clone -b v1.8.x https://github.com/google/googletest.git ../lib/googletest - -# Builds gtest.a and gtest_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) - -# All the IR protocol object files. -PROTOCOLS = ir_NEC.o ir_Sony.o ir_Samsung.o ir_JVC.o ir_RCMM.o ir_RC5_RC6.o \ - ir_LG.o ir_Mitsubishi.o ir_Fujitsu.o ir_Sharp.o ir_Sanyo.o ir_Denon.o ir_Dish.o \ - ir_Panasonic.o ir_Whynter.o ir_Coolix.o ir_Aiwa.o ir_Sherwood.o \ - ir_Kelvinator.o ir_Daikin.o ir_Gree.o ir_Pronto.o ir_Nikai.o ir_Toshiba.o \ - ir_Midea.o ir_Magiquest.o ir_Lasertag.o ir_Carrier.o ir_Haier.o \ - ir_Hitachi.o ir_GICable.o ir_Whirlpool.o ir_Lutron.o ir_Electra.o \ - ir_Pioneer.o ir_MWM.o ir_Vestel.o ir_Teco.o ir_Tcl.o ir_Lego.o ir_Argo.o \ - ir_Trotec.o ir_MitsubishiHeavy.o ir_Goodweather.o ir_Inax.o ir_Neoclima.o \ - ir_Amcor.o ir_Epson.o ir_Symphony.o ir_Airwell.o - -# All the IR Protocol header files. -PROTOCOLS_H = $(USER_DIR)/ir_Amcor.h \ - $(USER_DIR)/ir_Argo.h \ - $(USER_DIR)/ir_Gree.h \ - $(USER_DIR)/ir_Magiquest.h \ - $(USER_DIR)/ir_Coolix.h \ - $(USER_DIR)/ir_Electra.h \ - $(USER_DIR)/ir_Haier.h \ - $(USER_DIR)/ir_Hitachi.h \ - $(USER_DIR)/ir_Midea.h \ - $(USER_DIR)/ir_Toshiba.h \ - $(USER_DIR)/ir_Daikin.h \ - $(USER_DIR)/ir_Goodweather.h \ - $(USER_DIR)/ir_Kelvinator.h \ - $(USER_DIR)/ir_Mitsubishi.h \ - $(USER_DIR)/ir_MitsubishiHeavy.h \ - $(USER_DIR)/ir_NEC.h \ - $(USER_DIR)/ir_Neoclima.h \ - $(USER_DIR)/ir_Sharp.h \ - $(USER_DIR)/ir_Samsung.h \ - $(USER_DIR)/ir_Trotec.h \ - $(USER_DIR)/ir_Fujitsu.h \ - $(USER_DIR)/ir_LG.h \ - $(USER_DIR)/ir_Panasonic.h \ - $(USER_DIR)/ir_Whirlpool.h \ - $(USER_DIR)/ir_Vestel.h \ - $(USER_DIR)/ir_Tcl.h \ - $(USER_DIR)/ir_Teco.h \ - $(USER_DIR)/ir_Trotec.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 -# Common dependencies -COMMON_DEPS = $(USER_DIR)/IRrecv.h $(USER_DIR)/IRsend.h $(USER_DIR)/IRtimer.h \ - $(USER_DIR)/IRutils.h $(USER_DIR)/IRremoteESP8266.h \ - $(USER_DIR)/IRac.h $(USER_DIR)/i18n.h $(USER_DIR)/IRtext.h \ - $(PROTOCOLS_H) - -# Common test dependencies -COMMON_TEST_DEPS = $(COMMON_DEPS) IRrecv_test.h IRsend_test.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. -gtest-all.o : $(GTEST_SRCS_) - $(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c \ - $(GTEST_DIR)/src/gtest-all.cc - -gtest_main.o : $(GTEST_SRCS_) - $(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c \ - $(GTEST_DIR)/src/gtest_main.cc - -gtest.a : gtest-all.o - $(AR) $(ARFLAGS) $@ $^ - -gtest_main.a : gtest-all.o gtest_main.o - $(AR) $(ARFLAGS) $@ $^ - -# Builds our test. A test should link with either gtest.a or -# gtest_main.a, depending on whether it defines its own main() -# function. - -IRtext.o : $(USER_DIR)/IRtext.cpp $(USER_DIR)/IRtext.h $(USER_DIR)/IRremoteESP8266.h $(USER_DIR)/i18n.h $(USER_DIR)/locale/*.h - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/IRtext.cpp - -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) - $(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 - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -IRtimer.o : $(USER_DIR)/IRtimer.cpp $(USER_DIR)/IRtimer.h - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/IRtimer.cpp - -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) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c IRsend_test.cpp - -IRsend_test : IRsend_test.o $(COMMON_OBJ) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -IRrecv.o : $(USER_DIR)/IRrecv.cpp $(USER_DIR)/IRrecv.h $(USER_DIR)/IRremoteESP8266.h $(GTEST_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) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c IRrecv_test.cpp - -IRrecv_test : IRrecv_test.o $(COMMON_OBJ) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -IRac.o : $(USER_DIR)/IRac.cpp $(USER_DIR)/IRac.h $(COMMON_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/IRac.cpp - -IRac_test.o : IRac_test.cpp $(USER_DIR)/IRac.h $(COMMON_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c IRac_test.cpp - -IRac_test : IRac_test.o $(COMMON_OBJ) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_NEC.o : $(USER_DIR)/ir_NEC.cpp $(USER_DIR)/ir_NEC.h $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_NEC.cpp - -ir_NEC_test.o : ir_NEC_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_NEC_test.cpp - -ir_NEC_test : $(COMMON_OBJ) ir_NEC_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_GlobalCache.o : $(USER_DIR)/ir_GlobalCache.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_GlobalCache.cpp - -ir_GlobalCache_test.o : ir_GlobalCache_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_GlobalCache_test.cpp - -ir_GlobalCache_test : $(COMMON_OBJ) ir_GlobalCache_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Sherwood.o : $(USER_DIR)/ir_Sherwood.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Sherwood.cpp - -ir_Sherwood_test.o : ir_Sherwood_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Sherwood_test.cpp - -ir_Sherwood_test : $(COMMON_OBJ) ir_Sherwood_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Sony.o : $(USER_DIR)/ir_Sony.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Sony.cpp - -ir_Sony_test.o : ir_Sony_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Sony_test.cpp - -ir_Sony_test : $(COMMON_OBJ) ir_Sony_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Samsung.o : $(USER_DIR)/ir_Samsung.cpp $(USER_DIR)/ir_Samsung.h $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Samsung.cpp - -ir_Samsung_test.o : ir_Samsung_test.cpp $(USER_DIR)/ir_Samsung.h $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Samsung_test.cpp - -ir_Samsung_test : $(COMMON_OBJ) ir_Samsung_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Kelvinator.o : $(USER_DIR)/ir_Kelvinator.cpp $(USER_DIR)/ir_Kelvinator.h $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Kelvinator.cpp - -ir_Kelvinator_test.o : ir_Kelvinator_test.cpp $(USER_DIR)/ir_Kelvinator.h $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Kelvinator_test.cpp - -ir_Kelvinator_test : $(COMMON_OBJ) ir_Kelvinator_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_JVC.o : $(USER_DIR)/ir_JVC.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_JVC.cpp - -ir_JVC_test.o : ir_JVC_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_JVC_test.cpp - -ir_JVC_test : $(COMMON_OBJ) ir_JVC_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_RCMM.o : $(USER_DIR)/ir_RCMM.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_RCMM.cpp - -ir_RCMM_test.o : ir_RCMM_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_RCMM_test.cpp - -ir_RCMM_test : $(COMMON_OBJ) ir_RCMM_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_LG.o : $(USER_DIR)/ir_LG.h $(USER_DIR)/ir_LG.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_LG.cpp - -ir_LG_test.o : ir_LG_test.cpp $(USER_DIR)/ir_LG.h $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_LG_test.cpp - -ir_LG_test : $(COMMON_OBJ) ir_LG_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Mitsubishi.o : $(USER_DIR)/ir_Mitsubishi.h $(USER_DIR)/ir_Mitsubishi.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Mitsubishi.cpp - -ir_Mitsubishi_test.o : ir_Mitsubishi_test.cpp $(USER_DIR)/ir_Mitsubishi.h $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Mitsubishi_test.cpp - -ir_Mitsubishi_test : $(COMMON_OBJ) ir_Mitsubishi_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_MitsubishiHeavy.o : $(USER_DIR)/ir_MitsubishiHeavy.h $(USER_DIR)/ir_MitsubishiHeavy.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_MitsubishiHeavy.cpp - -ir_MitsubishiHeavy_test.o : ir_MitsubishiHeavy_test.cpp $(USER_DIR)/ir_MitsubishiHeavy.h $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_MitsubishiHeavy_test.cpp - -ir_MitsubishiHeavy_test : $(COMMON_OBJ) ir_MitsubishiHeavy_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Fujitsu.o : $(USER_DIR)/ir_Fujitsu.h $(USER_DIR)/ir_Fujitsu.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Fujitsu.cpp - -ir_Fujitsu_test.o : ir_Fujitsu_test.cpp $(USER_DIR)/ir_Fujitsu.h $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Fujitsu_test.cpp - -ir_Fujitsu_test : $(COMMON_OBJ) ir_Fujitsu_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Sharp.o : $(USER_DIR)/ir_Sharp.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Sharp.cpp - -ir_Sharp_test.o : ir_Sharp_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Sharp_test.cpp - -ir_Sharp_test : $(COMMON_OBJ) ir_Sharp_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_RC5_RC6.o : $(USER_DIR)/ir_RC5_RC6.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_RC5_RC6.cpp - -ir_RC5_RC6_test.o : ir_RC5_RC6_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_RC5_RC6_test.cpp - -ir_RC5_RC6_test : $(COMMON_OBJ) ir_RC5_RC6_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Panasonic.o : $(USER_DIR)/ir_Panasonic.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Panasonic.cpp - -ir_Panasonic_test.o : ir_Panasonic_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Panasonic_test.cpp - -ir_Panasonic_test : $(COMMON_OBJ) ir_Panasonic_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Dish.o : $(USER_DIR)/ir_Dish.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Dish.cpp - -ir_Dish_test.o : ir_Dish_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Dish_test.cpp - -ir_Dish_test : $(COMMON_OBJ) ir_Dish_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Whynter.o : $(USER_DIR)/ir_Whynter.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Whynter.cpp - -ir_Whynter_test.o : ir_Whynter_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Whynter_test.cpp - -ir_Whynter_test : $(COMMON_OBJ) ir_Whynter_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Coolix.o : $(USER_DIR)/ir_Coolix.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Coolix.cpp - -ir_Coolix_test.o : ir_Coolix_test.cpp $(USER_DIR)/ir_Coolix.h $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Coolix_test.cpp - -ir_Coolix_test : $(COMMON_OBJ) ir_Coolix_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Aiwa.o : $(USER_DIR)/ir_Aiwa.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Aiwa.cpp - -ir_Aiwa_test.o : ir_Aiwa_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Aiwa_test.cpp - -ir_Aiwa_test : $(COMMON_OBJ) ir_Aiwa_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Denon.o : $(USER_DIR)/ir_Denon.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Denon.cpp - -ir_Denon_test.o : ir_Denon_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Denon_test.cpp - -ir_Denon_test : $(COMMON_OBJ) ir_Denon_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Sanyo.o : $(USER_DIR)/ir_Sanyo.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Sanyo.cpp - -ir_Sanyo_test.o : ir_Sanyo_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Sanyo_test.cpp - -ir_Sanyo_test : $(COMMON_OBJ) ir_Sanyo_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Daikin.o : $(USER_DIR)/ir_Daikin.cpp $(USER_DIR)/ir_Daikin.h $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Daikin.cpp - -ir_Daikin_test.o : ir_Daikin_test.cpp $(USER_DIR)/ir_Daikin.h $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Daikin_test.cpp - -ir_Daikin_test : $(COMMON_OBJ) ir_Daikin_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Gree.o : $(USER_DIR)/ir_Gree.cpp $(GTEST_HEADERS) $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Gree.cpp - -ir_Gree_test.o : ir_Gree_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Gree_test.cpp - -ir_Gree_test : $(COMMON_OBJ) ir_Gree_test.o ir_Kelvinator.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Pronto.o : $(USER_DIR)/ir_Pronto.cpp $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Pronto.cpp - -ir_Pronto_test.o : ir_Pronto_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Pronto_test.cpp - -ir_Pronto_test : $(COMMON_OBJ) ir_Pronto_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Nikai.o : $(USER_DIR)/ir_Nikai.cpp $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Nikai.cpp - -ir_Nikai_test.o : ir_Nikai_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Nikai_test.cpp - -ir_Nikai_test : $(COMMON_OBJ) ir_Nikai_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Toshiba.o : $(USER_DIR)/ir_Toshiba.cpp $(USER_DIR)/ir_Toshiba.h $(COMMON_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Toshiba.cpp - -ir_Toshiba_test.o : ir_Toshiba_test.cpp $(USER_DIR)/ir_Toshiba.h $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Toshiba_test.cpp - -ir_Toshiba_test : $(COMMON_OBJ) ir_Toshiba_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Midea.o : $(USER_DIR)/ir_Midea.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Midea.cpp - -ir_Midea_test.o : ir_Midea_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Midea_test.cpp - -ir_Midea_test : $(COMMON_OBJ) ir_Midea_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Magiquest.o : $(USER_DIR)/ir_Magiquest.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Magiquest.cpp - -ir_Magiquest_test.o : ir_Magiquest_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Magiquest_test.cpp - -ir_Magiquest_test : $(COMMON_OBJ) ir_Magiquest_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Lasertag.o : $(USER_DIR)/ir_Lasertag.cpp $(USER_DIR)/ir_RC5_RC6.cpp $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Lasertag.cpp - -ir_Lasertag_test.o : ir_Lasertag_test.cpp $(USER_DIR)/ir_RC5_RC6.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Lasertag_test.cpp - -ir_Lasertag_test : $(COMMON_OBJ) ir_Lasertag_test.o ir_RC5_RC6.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Carrier.o : $(USER_DIR)/ir_Carrier.cpp $(COMMON_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Carrier.cpp - -ir_Carrier_test.o : ir_Carrier_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Carrier_test.cpp - -ir_Carrier_test : $(COMMON_OBJ) ir_Carrier_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Haier.o : $(USER_DIR)/ir_Haier.cpp $(USER_DIR)/ir_Haier.h $(COMMON_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Haier.cpp - -ir_Haier_test.o : ir_Haier_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Haier_test.cpp - -ir_Haier_test : $(COMMON_OBJ) ir_Haier_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Hitachi.o : $(USER_DIR)/ir_Hitachi.cpp $(USER_DIR)/ir_Hitachi.h $(COMMON_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Hitachi.cpp - -ir_Hitachi_test.o : ir_Hitachi_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Hitachi_test.cpp - -ir_Hitachi_test : $(COMMON_OBJ) ir_Hitachi_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_GICable.o : $(USER_DIR)/ir_GICable.cpp $(COMMON_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_GICable.cpp - -ir_GICable_test.o : ir_GICable_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_GICable_test.cpp - -ir_GICable_test : $(COMMON_OBJ) ir_GICable_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Whirlpool.o : $(USER_DIR)/ir_Whirlpool.cpp $(COMMON_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Whirlpool.cpp - -ir_Whirlpool_test.o : ir_Whirlpool_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Whirlpool_test.cpp - -ir_Whirlpool_test : $(COMMON_OBJ) ir_Whirlpool_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Lutron.o : $(USER_DIR)/ir_Lutron.cpp $(COMMON_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Lutron.cpp - -ir_Lutron_test.o : ir_Lutron_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Lutron_test.cpp - -ir_Lutron_test : $(COMMON_OBJ) ir_Lutron_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Electra.o : $(USER_DIR)/ir_Electra.h $(USER_DIR)/ir_Electra.cpp $(COMMON_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Electra.cpp - -ir_Electra_test.o : ir_Electra_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Electra_test.cpp - -ir_Electra_test : $(COMMON_OBJ) ir_Electra_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Pioneer.o : $(USER_DIR)/ir_Pioneer.cpp $(COMMON_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Pioneer.cpp - -ir_Pioneer_test.o : ir_Pioneer_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Pioneer_test.cpp - -ir_Pioneer_test : $(COMMON_OBJ) ir_Pioneer_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_MWM.o : $(USER_DIR)/ir_MWM.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_MWM.cpp - -ir_MWM_test.o : ir_MWM_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_MWM_test.cpp - -ir_MWM_test : $(COMMON_OBJ) ir_MWM_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Vestel.o : $(USER_DIR)/ir_Vestel.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Vestel.cpp - -ir_Vestel_test.o : ir_Vestel_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Vestel_test.cpp - -ir_Vestel_test : $(COMMON_OBJ) ir_Vestel_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Teco.o : $(USER_DIR)/ir_Teco.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Teco.cpp - -ir_Teco_test.o : ir_Teco_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Teco_test.cpp - -ir_Teco_test : $(COMMON_OBJ) ir_Teco_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Tcl.o : $(USER_DIR)/ir_Tcl.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Tcl.cpp - -ir_Tcl_test.o : ir_Tcl_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Tcl_test.cpp - -ir_Tcl_test : $(COMMON_OBJ) ir_Tcl_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Lego.o : $(USER_DIR)/ir_Lego.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Lego.cpp - -ir_Lego_test.o : ir_Lego_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Lego_test.cpp - -ir_Lego_test : $(COMMON_OBJ) ir_Lego_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Argo.o : $(USER_DIR)/ir_Argo.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Argo.cpp - -ir_Argo_test.o : ir_Argo_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Argo_test.cpp - -ir_Argo_test : $(COMMON_OBJ) ir_Argo_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Trotec.o : $(USER_DIR)/ir_Trotec.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Trotec.cpp - -ir_Trotec_test.o : ir_Trotec_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Trotec_test.cpp - -ir_Trotec_test : $(COMMON_OBJ) ir_Trotec_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Goodweather.o : $(USER_DIR)/ir_Goodweather.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Goodweather.cpp - -ir_Goodweather_test.o : ir_Goodweather_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Goodweather_test.cpp - -ir_Goodweather_test : $(COMMON_OBJ) ir_Goodweather_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Inax.o : $(USER_DIR)/ir_Inax.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Inax.cpp - -ir_Inax_test.o : ir_Inax_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Inax_test.cpp - -ir_Inax_test : $(COMMON_OBJ) ir_Inax_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Neoclima.o : $(USER_DIR)/ir_Neoclima.h $(USER_DIR)/ir_Neoclima.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Neoclima.cpp - -ir_Neoclima_test.o : ir_Neoclima_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Neoclima_test.cpp - -ir_Neoclima_test : $(COMMON_OBJ) ir_Neoclima_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Amcor.o : $(USER_DIR)/ir_Amcor.h $(USER_DIR)/ir_Amcor.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Amcor.cpp - -ir_Amcor_test.o : ir_Amcor_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Amcor_test.cpp - -ir_Amcor_test : $(COMMON_OBJ) ir_Amcor_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Epson.o : $(USER_DIR)/ir_Epson.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Epson.cpp - -ir_Epson_test.o : ir_Epson_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Epson_test.cpp - -ir_Epson_test : $(COMMON_OBJ) ir_Epson_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Symphony.o : $(USER_DIR)/ir_Symphony.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Symphony.cpp - -ir_Symphony_test.o : ir_Symphony_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Symphony_test.cpp - -ir_Symphony_test : $(COMMON_OBJ) ir_Symphony_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -ir_Airwell.o : $(USER_DIR)/ir_Airwell.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Airwell.cpp - -ir_Airwell_test.o : ir_Airwell_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Airwell_test.cpp - -ir_Airwell_test : $(COMMON_OBJ) ir_Airwell_test.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Carrier_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Carrier_test.cpp deleted file mode 100644 index f62a9d0f5..000000000 --- a/lib/IRremoteESP8266-2.7.5/test/ir_Carrier_test.cpp +++ /dev/null @@ -1,231 +0,0 @@ -// Copyright 2018 David Conran - -#include "IRrecv.h" -#include "IRsend.h" -#include "IRsend_test.h" -#include "gtest/gtest.h" - -// Tests for sendCarrierAC() - -// Test sending typical data only. -TEST(TestSendCarrierAC, SendDataOnly) { - IRsendTest irsend(0); - irsend.begin(); - - irsend.reset(); - irsend.sendCarrierAC(0x0); - EXPECT_EQ( - "f38000d50" - "m8532s4228" - "m628s532m628s532m628s532m628s532m628s532m628s532m628s532m628s532" - "m628s532m628s532m628s532m628s532m628s532m628s532m628s532m628s532" - "m628s532m628s532m628s532m628s532m628s532m628s532m628s532m628s532" - "m628s532m628s532m628s532m628s532m628s532m628s532m628s532m628s532" - "m628s20000" - "m8532s4228" - "m628s1320m628s1320m628s1320m628s1320m628s1320m628s1320m628s1320m628s1320" - "m628s1320m628s1320m628s1320m628s1320m628s1320m628s1320m628s1320m628s1320" - "m628s1320m628s1320m628s1320m628s1320m628s1320m628s1320m628s1320m628s1320" - "m628s1320m628s1320m628s1320m628s1320m628s1320m628s1320m628s1320m628s1320" - "m628s20000" - "m8532s4228" - "m628s532m628s532m628s532m628s532m628s532m628s532m628s532m628s532" - "m628s532m628s532m628s532m628s532m628s532m628s532m628s532m628s532" - "m628s532m628s532m628s532m628s532m628s532m628s532m628s532m628s532" - "m628s532m628s532m628s532m628s532m628s532m628s532m628s532m628s532" - "m628s20000", - irsend.outputStr()); - irsend.reset(); - irsend.sendCarrierAC(0x12345678); - EXPECT_EQ( - "f38000d50" - "m8532s4228" - "m628s532m628s532m628s532m628s1320m628s532m628s532m628s1320m628s532" - "m628s532m628s532m628s1320m628s1320m628s532m628s1320m628s532m628s532" - "m628s532m628s1320m628s532m628s1320m628s532m628s1320m628s1320m628s532" - "m628s532m628s1320m628s1320m628s1320m628s1320m628s532m628s532m628s532" - "m628s20000" - "m8532s4228" - "m628s1320m628s1320m628s1320m628s532m628s1320m628s1320m628s532m628s1320" - "m628s1320m628s1320m628s532m628s532m628s1320m628s532m628s1320m628s1320" - "m628s1320m628s532m628s1320m628s532m628s1320m628s532m628s532m628s1320" - "m628s1320m628s532m628s532m628s532m628s532m628s1320m628s1320m628s1320" - "m628s20000" - "m8532s4228" - "m628s532m628s532m628s532m628s1320m628s532m628s532m628s1320m628s532" - "m628s532m628s532m628s1320m628s1320m628s532m628s1320m628s532m628s532" - "m628s532m628s1320m628s532m628s1320m628s532m628s1320m628s1320m628s532" - "m628s532m628s1320m628s1320m628s1320m628s1320m628s532m628s532m628s532" - "m628s20000", - irsend.outputStr()); - - irsend.reset(); - irsend.sendCarrierAC(0x4CCA541D); - EXPECT_EQ( - "f38000d50" - "m8532s4228" - "m628s532m628s1320m628s532m628s532m628s1320m628s1320m628s532m628s532" - "m628s1320m628s1320m628s532m628s532m628s1320m628s532m628s1320m628s532" - "m628s532m628s1320m628s532m628s1320m628s532m628s1320m628s532m628s532" - "m628s532m628s532m628s532m628s1320m628s1320m628s1320m628s532m628s1320" - "m628s20000" - "m8532s4228" - "m628s1320m628s532m628s1320m628s1320m628s532m628s532m628s1320m628s1320" - "m628s532m628s532m628s1320m628s1320m628s532m628s1320m628s532m628s1320" - "m628s1320m628s532m628s1320m628s532m628s1320m628s532m628s1320m628s1320" - "m628s1320m628s1320m628s1320m628s532m628s532m628s532m628s1320m628s532" - "m628s20000" - "m8532s4228" - "m628s532m628s1320m628s532m628s532m628s1320m628s1320m628s532m628s532" - "m628s1320m628s1320m628s532m628s532m628s1320m628s532m628s1320m628s532" - "m628s532m628s1320m628s532m628s1320m628s532m628s1320m628s532m628s532" - "m628s532m628s532m628s532m628s1320m628s1320m628s1320m628s532m628s1320" - "m628s20000", - irsend.outputStr()); -} - -// Test sending typical data only. -TEST(TestSendCarrierAC, SendWithRepeats) { - IRsendTest irsend(0); - irsend.begin(); - - irsend.reset(); - irsend.sendCarrierAC(0x12345678, kCarrierAcBits, 2); // two repeats. - EXPECT_EQ( - "f38000d50" - "m8532s4228" - "m628s532m628s532m628s532m628s1320m628s532m628s532m628s1320m628s532" - "m628s532m628s532m628s1320m628s1320m628s532m628s1320m628s532m628s532" - "m628s532m628s1320m628s532m628s1320m628s532m628s1320m628s1320m628s532" - "m628s532m628s1320m628s1320m628s1320m628s1320m628s532m628s532m628s532" - "m628s20000" - "m8532s4228" - "m628s1320m628s1320m628s1320m628s532m628s1320m628s1320m628s532m628s1320" - "m628s1320m628s1320m628s532m628s532m628s1320m628s532m628s1320m628s1320" - "m628s1320m628s532m628s1320m628s532m628s1320m628s532m628s532m628s1320" - "m628s1320m628s532m628s532m628s532m628s532m628s1320m628s1320m628s1320" - "m628s20000" - "m8532s4228" - "m628s532m628s532m628s532m628s1320m628s532m628s532m628s1320m628s532" - "m628s532m628s532m628s1320m628s1320m628s532m628s1320m628s532m628s532" - "m628s532m628s1320m628s532m628s1320m628s532m628s1320m628s1320m628s532" - "m628s532m628s1320m628s1320m628s1320m628s1320m628s532m628s532m628s532" - "m628s20000" - "m8532s4228" - "m628s532m628s532m628s532m628s1320m628s532m628s532m628s1320m628s532" - "m628s532m628s532m628s1320m628s1320m628s532m628s1320m628s532m628s532" - "m628s532m628s1320m628s532m628s1320m628s532m628s1320m628s1320m628s532" - "m628s532m628s1320m628s1320m628s1320m628s1320m628s532m628s532m628s532" - "m628s20000" - "m8532s4228" - "m628s1320m628s1320m628s1320m628s532m628s1320m628s1320m628s532m628s1320" - "m628s1320m628s1320m628s532m628s532m628s1320m628s532m628s1320m628s1320" - "m628s1320m628s532m628s1320m628s532m628s1320m628s532m628s532m628s1320" - "m628s1320m628s532m628s532m628s532m628s532m628s1320m628s1320m628s1320" - "m628s20000" - "m8532s4228" - "m628s532m628s532m628s532m628s1320m628s532m628s532m628s1320m628s532" - "m628s532m628s532m628s1320m628s1320m628s532m628s1320m628s532m628s532" - "m628s532m628s1320m628s532m628s1320m628s532m628s1320m628s1320m628s532" - "m628s532m628s1320m628s1320m628s1320m628s1320m628s532m628s532m628s532" - "m628s20000" - "m8532s4228" - "m628s532m628s532m628s532m628s1320m628s532m628s532m628s1320m628s532" - "m628s532m628s532m628s1320m628s1320m628s532m628s1320m628s532m628s532" - "m628s532m628s1320m628s532m628s1320m628s532m628s1320m628s1320m628s532" - "m628s532m628s1320m628s1320m628s1320m628s1320m628s532m628s532m628s532" - "m628s20000" - "m8532s4228" - "m628s1320m628s1320m628s1320m628s532m628s1320m628s1320m628s532m628s1320" - "m628s1320m628s1320m628s532m628s532m628s1320m628s532m628s1320m628s1320" - "m628s1320m628s532m628s1320m628s532m628s1320m628s532m628s532m628s1320" - "m628s1320m628s532m628s532m628s532m628s532m628s1320m628s1320m628s1320" - "m628s20000" - "m8532s4228" - "m628s532m628s532m628s532m628s1320m628s532m628s532m628s1320m628s532" - "m628s532m628s532m628s1320m628s1320m628s532m628s1320m628s532m628s532" - "m628s532m628s1320m628s532m628s1320m628s532m628s1320m628s1320m628s532" - "m628s532m628s1320m628s1320m628s1320m628s1320m628s532m628s532m628s532" - "m628s20000", - irsend.outputStr()); -} - -// Tests for decodeCarrierAC(). - -// Decode normal "synthetic" messages. -TEST(TestDecodeCarrierAC, NormalDecodeWithStrict) { - IRsendTest irsend(0); - IRrecv irrecv(0); - irsend.begin(); - - irsend.reset(); - irsend.sendCarrierAC(0x0); - irsend.makeDecodeResult(); - ASSERT_TRUE(irrecv.decodeCarrierAC(&irsend.capture, kStartOffset, - kCarrierAcBits, true)); - EXPECT_EQ(CARRIER_AC, irsend.capture.decode_type); - EXPECT_EQ(kCarrierAcBits, irsend.capture.bits); - EXPECT_EQ(0x0, irsend.capture.value); - EXPECT_EQ(0x0, irsend.capture.address); - EXPECT_EQ(0x0, irsend.capture.command); - EXPECT_FALSE(irsend.capture.repeat); - - irsend.reset(); - irsend.sendCarrierAC(0xB335ABE2); - irsend.makeDecodeResult(); - ASSERT_TRUE(irrecv.decodeCarrierAC(&irsend.capture, kStartOffset, - kCarrierAcBits, true)); - EXPECT_EQ(CARRIER_AC, irsend.capture.decode_type); - EXPECT_EQ(kCarrierAcBits, irsend.capture.bits); - EXPECT_EQ(0xB335ABE2, irsend.capture.value); - EXPECT_EQ(0xB335, irsend.capture.address); - EXPECT_EQ(0xABE2, irsend.capture.command); - EXPECT_FALSE(irsend.capture.repeat); - - // Do the last one again, & use the full decoder, not just protocol specific. - irsend.reset(); - irsend.sendCarrierAC(0xB335ABE2); - irsend.makeDecodeResult(); - ASSERT_TRUE(irrecv.decode(&irsend.capture)); - EXPECT_EQ(CARRIER_AC, irsend.capture.decode_type); - EXPECT_EQ(kCarrierAcBits, irsend.capture.bits); - EXPECT_EQ(0xB335ABE2, irsend.capture.value); -} - -// Decode a "real" example message. -TEST(TestDecodeCarrierAC, RealExamples) { - IRsendTest irsend(0); - IRrecv irrecv(0); - irsend.begin(); - - irsend.reset(); - // Data from Issue #385 captured by gnkarn - uint16_t rawData[203] = { - 8532, 4216, 628, 1312, 628, 528, 628, 1312, 628, 1312, 628, 528, - 628, 524, 628, 1316, 624, 1316, 628, 524, 628, 528, 628, 1312, - 628, 1316, 624, 528, 628, 1312, 628, 528, 628, 1312, 628, 1312, - 628, 528, 628, 1316, 624, 528, 628, 1312, 628, 528, 628, 1312, - 628, 1316, 624, 1316, 628, 1312, 628, 1316, 628, 524, 628, 528, - 628, 528, 624, 1316, 628, 528, 628, 20064, 8504, 4228, 628, 528, - 628, 1312, 628, 528, 628, 528, 628, 1312, 628, 1316, 624, 532, - 624, 528, 628, 1316, 628, 1312, 628, 528, 628, 528, 628, 1312, - 628, 528, 628, 1316, 628, 528, 624, 528, 628, 1316, 628, 528, - 628, 1316, 624, 528, 628, 1316, 628, 528, 624, 532, 624, 528, - 628, 528, 628, 528, 628, 1316, 624, 1316, 628, 1316, 628, 528, - 624, 1316, 628, 20076, 8528, 4212, 624, 1316, 628, 528, 628, 1316, - 628, 1316, 624, 528, 628, 528, 628, 1316, 628, 1316, 628, 528, - 624, 532, 624, 1316, 628, 1316, 628, 528, 628, 1316, 624, 528, - 628, 1316, 628, 1316, 628, 528, 628, 1316, 624, 532, 624, 1316, - 628, 532, 624, 1316, 628, 1316, 624, 1320, 624, 1316, 628, 1316, - 628, 528, 628, 528, 628, 528, 628, 1316, 624, 532, 624}; - - irsend.sendRaw(rawData, 203, 38000); - irsend.makeDecodeResult(); - ASSERT_TRUE(irrecv.decode(&irsend.capture)); - EXPECT_EQ(CARRIER_AC, irsend.capture.decode_type); - EXPECT_EQ(kCarrierAcBits, irsend.capture.bits); - EXPECT_EQ(0xB335ABE2, irsend.capture.value); - EXPECT_EQ(0xB335, irsend.capture.address); - EXPECT_EQ(0xABE2, irsend.capture.command); - EXPECT_FALSE(irsend.capture.repeat); -} diff --git a/lib/IRremoteESP8266-2.7.5/tools/Makefile b/lib/IRremoteESP8266-2.7.5/tools/Makefile deleted file mode 100644 index cfbf2e33c..000000000 --- a/lib/IRremoteESP8266-2.7.5/tools/Makefile +++ /dev/null @@ -1,248 +0,0 @@ -# SYNOPSIS: -# -# make [all] - makes everything. -# make clean - removes all files generated by make. - -# Please tweak the following variable definitions as needed by your -# project, except GTEST_HEADERS, which you can use in your own targets -# but shouldn't modify. - - -# Where to find user code. -USER_DIR = ../src - -# Where to find test code. -TEST_DIR = ../test - -INCLUDES = -I$(USER_DIR) -I$(TEST_DIR) -# 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 += -DUNIT_TEST -D_IR_LOCALE_=en-AU - -# Flags passed to the C++ compiler. -CXXFLAGS += -g -Wall -Wextra -pthread -std=gnu++11 - -all : gc_decode mode2_decode - -run_tests : all - failed=""; \ - for py_unittest in *_test.py; do \ - echo "RUNNING: $${py_unittest}"; \ - python3 ./$${py_unittest} || failed="$${failed} $${py_unittest}"; \ - done; \ - if [ -n "$${failed}" ]; then \ - echo "FAIL: :-( :-( Unit test(s)$${failed} failed! :-( :-("; exit 1; \ - else \ - echo "PASS: \o/ \o/ All unit tests passed. \o/ \o/"; \ - fi - -clean : - rm -f *.o *.pyc gc_decode mode2_decode - - -# All the IR protocol object files. -PROTOCOLS = ir_NEC.o ir_Sony.o ir_Samsung.o ir_JVC.o ir_RCMM.o ir_RC5_RC6.o \ - ir_LG.o ir_Mitsubishi.o ir_Fujitsu.o ir_Sharp.o ir_Sanyo.o \ - ir_Denon.o ir_Dish.o ir_Panasonic.o ir_Whynter.o ir_Coolix.o \ - ir_Aiwa.o ir_Sherwood.o ir_Kelvinator.o ir_Daikin.o ir_Gree.o \ - ir_Pronto.o ir_GlobalCache.o ir_Nikai.o ir_Toshiba.o ir_Midea.o \ - ir_Magiquest.o ir_Lasertag.o ir_Carrier.o ir_Haier.o ir_Hitachi.o \ - ir_GICable.o ir_Whirlpool.o ir_Lutron.o ir_Electra.o ir_Pioneer.o \ - ir_MWM.o ir_Vestel.o ir_Teco.o ir_Tcl.o ir_Lego.o \ - ir_MitsubishiHeavy.o ir_Goodweather.o ir_Inax.o ir_Argo.o \ - ir_Trotec.o ir_Neoclima.o ir_Amcor.o ir_Epson.o ir_Symphony.o \ - ir_Airwell.o - -# Common object files -COMMON_OBJ = IRutils.o IRtimer.o IRsend.o IRrecv.o IRtext.o IRac.o $(PROTOCOLS) - -# Common dependencies -COMMON_DEPS = $(USER_DIR)/IRrecv.h $(USER_DIR)/IRsend.h $(USER_DIR)/IRtimer.h \ - $(USER_DIR)/IRutils.h $(USER_DIR)/IRremoteESP8266.h \ - $(TEST_DIR)/IRsend_test.h $(USER_DIR)/IRtext.h $(USER_DIR)/i18n.h -# Common test dependencies -COMMON_TEST_DEPS = $(COMMON_DEPS) $(TEST_DIR)/IRsend_test.h - -gc_decode.o : gc_decode.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c gc_decode.cpp - -gc_decode : $(COMMON_OBJ) gc_decode.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -mode2_decode.o : mode2_decode.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c mode2_decode.cpp - -mode2_decode : $(COMMON_OBJ) mode2_decode.o - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ - -IRtext.o : $(USER_DIR)/IRtext.cpp $(USER_DIR)/IRtext.h $(USER_DIR)/IRremoteESP8266.h $(USER_DIR)/i18n.h $(USER_DIR)/locale/*.h - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/IRtext.cpp - -IRutils.o : $(USER_DIR)/IRutils.cpp $(USER_DIR)/IRutils.h $(USER_DIR)/IRremoteESP8266.h - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/IRutils.cpp - -IRtimer.o : $(USER_DIR)/IRtimer.cpp $(USER_DIR)/IRtimer.h - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/IRtimer.cpp - -IRsend.o : $(USER_DIR)/IRsend.cpp $(USER_DIR)/IRsend.h $(USER_DIR)/IRremoteESP8266.h - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/IRsend.cpp - -IRrecv.o : $(USER_DIR)/IRrecv.cpp $(USER_DIR)/IRrecv.h $(USER_DIR)/IRremoteESP8266.h $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/IRrecv.cpp - -ir_NEC.o : $(USER_DIR)/ir_NEC.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_NEC.cpp - -ir_GlobalCache.o : $(USER_DIR)/ir_GlobalCache.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_GlobalCache.cpp - -ir_Sherwood.o : $(USER_DIR)/ir_Sherwood.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Sherwood.cpp - -ir_Sony.o : $(USER_DIR)/ir_Sony.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Sony.cpp - -ir_Samsung.o : $(USER_DIR)/ir_Samsung.cpp $(USER_DIR)/ir_Samsung.h $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Samsung.cpp - -ir_Kelvinator.o : $(USER_DIR)/ir_Kelvinator.cpp $(USER_DIR)/ir_Kelvinator.h $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Kelvinator.cpp - -ir_Inax.o : $(USER_DIR)/ir_Inax.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Inax.cpp - -ir_JVC.o : $(USER_DIR)/ir_JVC.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_JVC.cpp - -ir_RCMM.o : $(USER_DIR)/ir_RCMM.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_RCMM.cpp - -ir_LG.o : $(USER_DIR)/ir_LG.h $(USER_DIR)/ir_LG.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_LG.cpp - -ir_Mitsubishi.o : $(USER_DIR)/ir_Mitsubishi.h $(USER_DIR)/ir_Mitsubishi.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Mitsubishi.cpp - -ir_MitsubishiHeavy.o : $(USER_DIR)/ir_MitsubishiHeavy.h $(USER_DIR)/ir_MitsubishiHeavy.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_MitsubishiHeavy.cpp - -ir_Fujitsu.o : $(USER_DIR)/ir_Fujitsu.h $(USER_DIR)/ir_Fujitsu.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Fujitsu.cpp - -ir_Sharp.o : $(USER_DIR)/ir_Sharp.h $(USER_DIR)/ir_Sharp.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Sharp.cpp - -ir_RC5_RC6.o : $(USER_DIR)/ir_RC5_RC6.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_RC5_RC6.cpp - -ir_Panasonic.o : $(USER_DIR)/ir_Panasonic.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Panasonic.cpp - -ir_Dish.o : $(USER_DIR)/ir_Dish.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Dish.cpp - -ir_Whynter.o : $(USER_DIR)/ir_Whynter.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Whynter.cpp - -ir_Coolix.o : $(USER_DIR)/ir_Coolix.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Coolix.cpp - -ir_Aiwa.o : $(USER_DIR)/ir_Aiwa.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Aiwa.cpp - -ir_Denon.o : $(USER_DIR)/ir_Denon.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Denon.cpp - -ir_Sanyo.o : $(USER_DIR)/ir_Sanyo.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Sanyo.cpp - -ir_Daikin.o : $(USER_DIR)/ir_Daikin.cpp $(USER_DIR)/ir_Daikin.h $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Daikin.cpp - -ir_Gree.o : $(USER_DIR)/ir_Gree.cpp $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Gree.cpp - -ir_Pronto.o : $(USER_DIR)/ir_Pronto.cpp $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Pronto.cpp - -ir_Nikai.o : $(USER_DIR)/ir_Nikai.cpp $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Nikai.cpp - -ir_Toshiba.o : $(USER_DIR)/ir_Toshiba.h $(USER_DIR)/ir_Toshiba.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Toshiba.cpp - -ir_Midea.o : $(USER_DIR)/ir_Midea.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Midea.cpp - -ir_Magiquest.o : $(USER_DIR)/ir_Magiquest.cpp $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Magiquest.cpp - -ir_Lasertag.o : $(USER_DIR)/ir_Lasertag.cpp $(USER_DIR)/ir_RC5_RC6.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Lasertag.cpp - -ir_Carrier.o : $(USER_DIR)/ir_Carrier.cpp $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Carrier.cpp - -ir_Haier.o : $(USER_DIR)/ir_Haier.cpp $(USER_DIR)/ir_Haier.h $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Haier.cpp - -ir_Hitachi.o : $(USER_DIR)/ir_Hitachi.cpp $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Hitachi.cpp - -ir_GICable.o : $(USER_DIR)/ir_GICable.cpp $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_GICable.cpp - -ir_Whirlpool.o : $(USER_DIR)/ir_Whirlpool.cpp $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Whirlpool.cpp - -ir_Lutron.o : $(USER_DIR)/ir_Lutron.cpp $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Lutron.cpp - -ir_Electra.o : $(USER_DIR)/ir_Electra.cpp $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Electra.cpp - -ir_Pioneer.o : $(USER_DIR)/ir_Pioneer.cpp $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Pioneer.cpp - -ir_MWM.o : $(USER_DIR)/ir_MWM.cpp $(USER_DIR)/ir_RC5_RC6.cpp $(COMMON_DEPS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_MWM.cpp - -ir_Vestel.o : $(USER_DIR)/ir_Vestel.cpp $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Vestel.cpp - -ir_Teco.o : $(USER_DIR)/ir_Teco.cpp $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Teco.cpp - -ir_Tcl.o : $(USER_DIR)/ir_Tcl.cpp $(USER_DIR)/ir_Tcl.h $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Tcl.cpp - -ir_Trotec.o : $(USER_DIR)/ir_Trotec.cpp $(USER_DIR)/ir_Trotec.h $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Trotec.cpp - -ir_Lego.o : $(USER_DIR)/ir_Lego.cpp $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Lego.cpp - -ir_Argo.o : $(USER_DIR)/ir_Argo.cpp $(USER_DIR)/ir_Argo.h $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Argo.cpp - -ir_Goodweather.o : $(USER_DIR)/ir_Goodweather.cpp $(USER_DIR)/ir_Goodweather.h $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Goodweather.cpp - -ir_Neoclima.o : $(USER_DIR)/ir_Neoclima.cpp $(USER_DIR)/ir_Neoclima.h $(COMMON_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Neoclima.cpp - -ir_Amcor.o : $(USER_DIR)/ir_Amcor.cpp $(USER_DIR)/ir_Amcor.h $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Amcor.cpp - -ir_Epson.o : $(USER_DIR)/ir_Epson.cpp $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Epson.cpp - -ir_Symphony.o : $(USER_DIR)/ir_Symphony.cpp $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Symphony.cpp - -ir_Airwell.o : $(USER_DIR)/ir_Airwell.cpp $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Airwell.cpp - -IRac.o : $(USER_DIR)/IRac.cpp $(USER_DIR)/IRac.h $(COMMON_DEPS) $(GTEST_HEADERS) - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/IRac.cpp diff --git a/lib/IRremoteESP8266-2.7.5/CPPLINT.cfg b/lib/IRremoteESP8266-2.7.8/CPPLINT.cfg similarity index 100% rename from lib/IRremoteESP8266-2.7.5/CPPLINT.cfg rename to lib/IRremoteESP8266-2.7.8/CPPLINT.cfg diff --git a/lib/IRremoteESP8266-2.7.8/Doxyfile b/lib/IRremoteESP8266-2.7.8/Doxyfile new file mode 100644 index 000000000..224c07315 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/Doxyfile @@ -0,0 +1,15 @@ +PROJECT_NAME = "IRremoteESP8266" +OUTPUT_DIRECTORY = docs/doxygen +INPUT = src +INPUT += docs/doxygen_index.md +RECURSIVE = YES +EXCLUDE = examples +MULTILINE_CPP_IS_BRIEF = YES +TAB_SIZE = 2 +EXTRACT_ALL = YES +EXTRACT_PRIVATE = YES +EXTRACT_LOCAL_CLASSES = NO +GENERATE_LATEX = NO +ENABLE_PREPROCESSING = NO +QUIET = YES +WARN_NO_PARAMDOC = YES diff --git a/lib/IRremoteESP8266-2.7.5/LICENSE.txt b/lib/IRremoteESP8266-2.7.8/LICENSE.txt similarity index 100% rename from lib/IRremoteESP8266-2.7.5/LICENSE.txt rename to lib/IRremoteESP8266-2.7.8/LICENSE.txt diff --git a/lib/IRremoteESP8266-2.7.5/README.md b/lib/IRremoteESP8266-2.7.8/README.md similarity index 90% rename from lib/IRremoteESP8266-2.7.5/README.md rename to lib/IRremoteESP8266-2.7.8/README.md index 9ce40166f..c8ad07ee3 100644 --- a/lib/IRremoteESP8266-2.7.5/README.md +++ b/lib/IRremoteESP8266-2.7.8/README.md @@ -1,4 +1,4 @@ -# IRremote ESP8266 Library +# IRremoteESP8266 Library [![Build Status](https://travis-ci.org/crankyoldgit/IRremoteESP8266.svg?branch=master)](https://travis-ci.org/crankyoldgit/IRremoteESP8266) [![arduino-library-badge](https://www.ardu-badge.com/badge/IRremoteESP8266.svg?)](https://www.ardu-badge.com/IRremoteESP8266) @@ -9,8 +9,8 @@ This library enables you to **send _and_ receive** infra-red signals on an [ESP8266](https://github.com/esp8266/Arduino) or an [ESP32](https://github.com/espressif/arduino-esp32) using the [Arduino framework](https://www.arduino.cc/) using common 940nm IR LEDs and common IR receiver modules. e.g. TSOP{17,22,24,36,38,44,48}* demodulators etc. -## v2.7.5 Now Available -Version 2.7.5 of the library is now [available](https://github.com/crankyoldgit/IRremoteESP8266/releases/latest). You can view the [Release Notes](ReleaseNotes.md) for all the significant changes. +## v2.7.8 Now Available +Version 2.7.8 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. @@ -40,6 +40,10 @@ Before reporting an issue or asking for help, please try to follow our [Troubles ## Frequently Asked Questions Some common answers to common questions and problems are on our [F.A.Q. wiki page](https://github.com/crankyoldgit/IRremoteESP8266/wiki/Frequently-Asked-Questions). +## Library API Documentation +This library uses [Doxygen](https://www.doxygen.nl/index.html) to [automatically document](https://crankyoldgit.github.io/IRremoteESP8266/doxygen/html/) the [library's](https://crankyoldgit.github.io/IRremoteESP8266/doxygen/html/) [API](https://en.wikipedia.org/wiki/Application_programming_interface). +You can find it [here](https://crankyoldgit.github.io/IRremoteESP8266/doxygen/html/). + ## Installation ##### Official releases via the Arduino IDE v1.8+ (Windows & Linux) 1. Click the _"Sketch"_ -> _"Include Library"_ -> _"Manage Libraries..."_ Menu items. diff --git a/lib/IRremoteESP8266-2.7.5/README_fr.md b/lib/IRremoteESP8266-2.7.8/README_fr.md similarity index 84% rename from lib/IRremoteESP8266-2.7.5/README_fr.md rename to lib/IRremoteESP8266-2.7.8/README_fr.md index 49fc3188c..1e983ba35 100644 --- a/lib/IRremoteESP8266-2.7.5/README_fr.md +++ b/lib/IRremoteESP8266-2.7.8/README_fr.md @@ -1,4 +1,4 @@ -# IRremote ESP8266 Library +# IRremoteESP8266 Library [![Build Status](https://travis-ci.org/crankyoldgit/IRremoteESP8266.svg?branch=master)](https://travis-ci.org/crankyoldgit/IRremoteESP8266) [![arduino-library-badge](https://www.ardu-badge.com/badge/IRremoteESP8266.svg?)](https://www.ardu-badge.com/IRremoteESP8266) @@ -9,8 +9,8 @@ Cette librairie vous permetra de **recevoir et d'envoyer des signaux** infrarouge sur le protocole [ESP8266](https://github.com/esp8266/Arduino) ou sur le protocole [ESP32](https://github.com/espressif/arduino-esp32) en utilisant le [Arduino framework](https://www.arduino.cc/) qui utilise la norme 940nm IR LEDs et le module basique de reception d'onde IR. Exemple : TSOP{17,22,24,36,38,44,48}* modules etc. -## v2.7.5 disponible -Version 2.7.5 de la libraire est maintenant [disponible](https://github.com/crankyoldgit/IRremoteESP8266/releases/latest). Vous pouvez voir le [Release Notes](ReleaseNotes.md) pour tous les changements importants. +## v2.7.8 disponible +Version 2.7.8 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. @@ -39,6 +39,9 @@ Avant de reporter un probème ou de demander de l'aide, essayez de suivre notre ## Questions fréquentes Les questions les plus fréquentes sont ici, avec des réponses [F.A.Q. wiki page](https://github.com/crankyoldgit/IRremoteESP8266/wiki/Frequently-Asked-Questions). +## Documentation API de la bibliothèque +Cette bibliothèque utilise [Doxygen](https://www.doxygen.nl/index.html) pour [documenter automatiquement](https://crankyoldgit.github.io/IRremoteESP8266/doxygen/html/) [l'API](https://en.wikipedia.org/wiki/Application_programming_interface) de la [bibliothèque](https://crankyoldgit.github.io/IRremoteESP8266/doxygen/html/). Vous pouvez le trouver [ici](https://crankyoldgit.github.io/IRremoteESP8266/doxygen/html/). + ## Installation ##### Officiel releases avec l'Arduino IDE v1.8+ (Windows & Linux) 1. Cliquez sur _"Sketch"_ -> _"Include Library"_ -> _"Manage Libraries..."_ Menu items. @@ -46,6 +49,10 @@ Les questions les plus fréquentes sont ici, avec des réponses [F.A.Q. wiki pag 1. Cliquez sur le IRremoteESP8266 pour avoir les résultats de la recherche. 1. Selectionnez la version que vous voulez installer et cliquez sur _"Install"_. +## Library API Documentation +This library uses [Doxygen](https://www.doxygen.nl/index.html) to [automatically document](https://crankyoldgit.github.io/IRremoteESP8266/doxygen/html/) the [library's](https://crankyoldgit.github.io/IRremoteESP8266/doxygen/html/) [API](https://en.wikipedia.org/wiki/Application_programming_interface). +You can find it [here](https://crankyoldgit.github.io/IRremoteESP8266/doxygen/html/). + ##### Installation manuelle pour Windows 1. cliquez le boutton sur _"Clone or Download"_ , et _"[Download ZIP](https://github.com/crankyoldgit/IRremoteESP8266/archive->master.zip)"_ on the page. 1. Extraire l'archive. diff --git a/lib/IRremoteESP8266-2.7.5/ReleaseNotes.md b/lib/IRremoteESP8266-2.7.8/ReleaseNotes.md similarity index 87% rename from lib/IRremoteESP8266-2.7.5/ReleaseNotes.md rename to lib/IRremoteESP8266-2.7.8/ReleaseNotes.md index 51df6df27..4b757f710 100644 --- a/lib/IRremoteESP8266-2.7.5/ReleaseNotes.md +++ b/lib/IRremoteESP8266-2.7.8/ReleaseNotes.md @@ -1,5 +1,92 @@ # Release Notes +## _v2.7.8 (20200622)_ + +**[BREAKING CHANGES]** +- Fix Manchester code handling; Increase Airwell to `34` bits. (#1200) + +**[Bug Fixes]** +- Carrier40: Use correct gap value. (#1193) + +**[Features]** +- CarrierAc64: Add detailed support. (#1133) +- Add experimental support for Hitachi A/C 344 bit protocol (#1139) +- Automatic & full library code/API documentation via Doxygen (#1150 #1154 #1155 #1156 #1158 #1165 #1167 #1169 #1180 #1184 #1189 #1191 #1194 #1195 #1197 #1198) +- Hitachi344: Add detailed support and change bit ordering. (#1147) +- Add Corona AC Protocol (#1152) +- Hitachi344: Add Swing(H) and improve Swing(V) (#1148) +- Update auto_analyse_raw_data.py with better code comment sections (#1164) +- Add support for Midea24 protocol. (#1171) +- Add basic Zepeal protocol support (#1178) + +**[Misc]** +- scrape_supported_devices.py: avoid changes to SupportedProtocols.md (#1140) +- auto_analyze nice exit on empty rawdata input (#1141) +- Comments update + cleanup (#1143) +- Update D_STR_IRRECVDUMP_STARTUP text and comments. (#1144) +- Minor code cleanups (#1149) +- Update `README.md`'s to point to new API docs. (#1151) +- Update "Supports" sections (#1160) +- Add a `doxygen` check to CI/Travis. (#1161) +- scrape_supported_devices: warn about misplaced or legacy supports sections (#1159) +- Add Supports sections to some files (#1163 #1166) +- Fix compile error when `DEBUG` is enabled. +- Add no-output option and return code on error to scrape_supported_devices +- Travis: Add scrape_supported_devices error check +- Update auto_analyse_raw_data.py to have a default Supports: section +- Treat compiler warnings as errors. (#1174) +- Remove `calcLGChecksum()` and use new generic `sumNibbles()` (#1175) +- Suppress more potential compiler warnings. (#1179) +- Load balance travis tasks to reduce wall clock time. (#1183) +- Set PlatformIO's default baudrate to 115200 (#1188) +- Some fixes to Doshisha protocol handler +- Minor cleanups of Corona and Zepeal +- Enable Doxygen warning when the parameters for a function/method/procedure are wrong/missing. (#1196) + + +## _v2.7.7 (20200519)_ + +**[BREAKING CHANGES]** +- Fix Symphony protocol. (#1107, #1105) + * Now 12 bits and bits are inverted. All previous codes will no longer work. +- IRMQTTServer: Better handle power & mode operations for Home Assistant. (#1099, #1092) + * When `MQTT_CLIMATE_HA_MODE` is enabled (default) this will break previous operation mode resumption when power is changed. + +**[Bug Fixes]** +- Set correct return type for `.calibrate()` (#1095, #1093) + +**[Features]** +- Add basic support for Carrier 40 & 64 bit protocols. (#1125, #1112, #1127) +- Gree: Enable native support for Fahrenheit (#1124, #1121) +- Gree: Add option to control display temp source. (#1120, #1118) +- Add support for Multibrackets protocol. (#1106, #1103) +- Add RawToPronto.py tool & improve `sendPronto()` precision (#1104, #1103) +- Add support for `Doshisha` LED light protocol (#1115) +- Introduce IRrecvDumpV3 with basic OTA update support (#1111) +- Add detailed support for Delonghi A/C (#1098, #1096) +- Improved support for SharpAc. (#1094, #1091) +- Update auto_analyse to use new decode call structure. (#1102, #1097) +- Added Blynk app example (#1090) + +**[Misc]** +- update auto_analyse script to use new param documentation (#1126) +- Improve `raw_to_pronto_code.py` (#1122, #1103) +- Use pattern rules in Makefiles to reduce specific rule (#1110) +- Update list of supported Daikin models. (#1101) + + +## _v2.7.6 (20200425)_ + +**[Features]** +- IRMQTTServer: Use more i18n text. (#1086) +- Convert Protocol names to shared text. Saves ~3k of flash. (#1078) +- Add Chinese translation (zh-CN) & add utf-8 support. (#1080, #1085) + +**[Misc]** +- IRMQTTServer: Ensure MQTT_MAX_PACKET_SIZE is correctly set. (#1084) +- Add Italian locale to IRrecvDumpV2 platformio file. + + ## _v2.7.5 (20200409)_ **[Features]** diff --git a/lib/IRremoteESP8266-2.7.5/SupportedProtocols.md b/lib/IRremoteESP8266-2.7.8/SupportedProtocols.md similarity index 59% rename from lib/IRremoteESP8266-2.7.5/SupportedProtocols.md rename to lib/IRremoteESP8266-2.7.8/SupportedProtocols.md index ed4699de2..7dab7ccb7 100644 --- a/lib/IRremoteESP8266-2.7.5/SupportedProtocols.md +++ b/lib/IRremoteESP8266-2.7.8/SupportedProtocols.md @@ -1,76 +1,90 @@ + Last generated: Mon 22 Jun 2020 09:51:06 +0000 ---> # IR Protocols supported by this library | Protocol | Brand | Model | A/C Model | Detailed A/C Support | | --- | --- | --- | --- | --- | -| [Airwell](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Airwell.cpp) | **Airwell** | RC08W remote | | - | +| [Airwell](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Airwell.cpp) | **Airwell** | DLS 21 DCI R410 AW A/C
RC04 remote
RC08W remote | | - | | [Aiwa](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Aiwa.cpp) | **Aiwa** | RC-T501 RCU | | - | -| [Amcor](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Amcor.cpp) | **[Amcor](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Amcor.h)** | ADR-853H A/C
ADR-853H A/C
TAC-444 remote
TAC-444 remote
TAC-495 remote
TAC-495 remote | | Yes | +| [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
TAC-444 remote
TAC-495 remote | | Yes | | [Argo](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Argo.cpp) | **[Argo](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Argo.h)** | Ulisse 13 DCI Mobile Split A/C | | Yes | -| [Carrier](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Carrier.cpp) | **Carrier/Surrey** | 42QG5A55970 remote
53NGK009/012 Inverter
619EGX0090E0 A/C
619EGX0120E0 A/C
619EGX0180E0 A/C
619EGX0220E0 A/C | | - | +| [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
53NGK009/012 Inverter
619EGX0090E0 A/C
619EGX0120E0 A/C
619EGX0180E0 A/C
619EGX0220E0 A/C | | Yes | | [Coolix](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.cpp) | **[Airwell](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.h)** | RC08B remote | | Yes | -| [Coolix](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.cpp) | **[Beko](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.h)** | BINR 070/071 split-type A/C
BINR 070/071 split-type A/C
RG57K7(B)/BGEF Remote
RG57K7(B)/BGEF Remote | | Yes | -| [Coolix](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.cpp) | **[Midea](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.h)** | MS12FU-10HRDN1-QRD0GW(B) A/C
MS12FU-10HRDN1-QRD0GW(B) A/C
MSABAU-07HRFN1-QRD0GW A/C (circa 2016)
MSABAU-07HRFN1-QRD0GW A/C (circa 2016)
RG52D/BGE Remote
RG52D/BGE Remote | | Yes | -| [Coolix](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.cpp) | **[Tokio](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.h)** | AATOEMF17-12CHR1SW split-type RG51\|50/BGE Remote
AATOEMF17-12CHR1SW split-type RG51\|50/BGE Remote | | Yes | -| [Daikin](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Daikin.cpp) | **[Daikin](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Daikin.h)** | 17 Series A/C (DAIKIN128)
ARC423A5 remote
ARC433** remote
ARC433B69 remote
ARC477A1 remote
ARC480A5 remote (DAIKIN152)
BRC4C153 remote
BRC52B63 remote (DAIKIN128)
DGS01 remote (DAIKIN64)
FFN-C/FCN-F Series A/C (DAIKIN64)
FTE12HV2S A/C
FTXB09AXVJU A/C (DAIKIN128)
FTXB12AXVJU A/C (DAIKIN128)
FTXZ25NV1B A/C
FTXZ35NV1B A/C
FTXZ50NV1B A/C | | Yes | -| [Denon](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Denon.cpp) | **Unknown** | | | - | +| [Coolix](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.cpp) | **[Beko](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.h)** | BINR 070/071 split-type A/C
RG57K7(B)/BGEF Remote | | Yes | +| [Coolix](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.cpp) | **[Midea](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.h)** | MS12FU-10HRDN1-QRD0GW(B) A/C
MSABAU-07HRFN1-QRD0GW A/C (circa 2016)
RG52D/BGE Remote | | Yes | +| [Coolix](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.cpp) | **[Tokio](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.h)** | AATOEMF17-12CHR1SW split-type RG51\|50/BGE Remote | | Yes | +| [Corona](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Corona.cpp) | **[Corona](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Corona.h)** | AR-01 remote
CSH-N2211 A/C
CSH-N2511 A/C
CSH-N2811 A/C
CSH-N4011 A/C | | Yes | +| [Daikin](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Daikin.cpp) | **[Daikin](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Daikin.h)** | 17 Series A/C (DAIKIN128)
ARC423A5 remote (DAIKIN160)
ARC433** remote (DAIKIN)
ARC433B69 remote (DAIKIN216)
ARC466A33 remote (DAIKIN)
ARC477A1 remote (DAIKIN2)
ARC480A5 remote (DAIKIN152)
BRC4C153 remote (DAIKIN176)
BRC52B63 remote (DAIKIN128)
DGS01 remote (DAIKIN64)
FFN-C/FCN-F Series A/C (DAIKIN64)
FTE12HV2S A/C
FTXB09AXVJU A/C (DAIKIN128)
FTXB12AXVJU A/C (DAIKIN128)
FTXM-M A/C (DAIKIN)
FTXZ25NV1B A/C (DAIKIN2)
FTXZ35NV1B A/C (DAIKIN2)
FTXZ50NV1B A/C (DAIKIN2)
M Series A/C (DAIKIN) | | Yes | +| [Delonghi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Delonghi.cpp) | **[Delonghi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Delonghi.h)** | PAC A95 | | Yes | +| [Denon](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Denon.cpp) | **Denon** | AVR-3801 A/V Receiver (probably) | | - | | [Dish](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Dish.cpp) | **DISH NETWORK** | echostar 301 | | - | +| [Doshisha](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Doshisha.cpp) | **Doshisha** | CZ-S32D LED Light
CZ-S38D LED Light
CZ-S50D LED Light
RCZ01 remote | | - | | [Electra](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Electra.cpp) | **[AUX](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Electra.h)** | KFR-35GW/BpNFW=3 A/C
YKR-T/011 remote | | Yes | | [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
YKR-M/003E remote | | Yes | -| [Epson](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Epson.cpp) | **Unknown** | | | - | -| [Fujitsu](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Fujitsu.cpp) | **[Fujitsu](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Fujitsu.h)** | AGTV14LAC A/C
AR-DB1 remote
AR-DL10 remote
AR-RAC1E remote
AR-RAE1E remote
AR-RAH2E remote
AR-REB1E remote
AR-RY4 remote
AST9RSGCW A/C
ASTB09LBC A/C
ASU30C1 A/C
ASYG30LFCA A/C
ASYG7LMCA A/C | ARDB1
ARJW2
ARRAH2E
ARREB1E
ARRY4 | Yes | +| [Epson](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Epson.cpp) | **Epson** | EN-TW9100W Projector | | - | +| [Fujitsu](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Fujitsu.cpp) | **[Fujitsu](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Fujitsu.h)** | AGTV14LAC A/C
AR-DB1 remote
AR-DL10 remote
AR-RAC1E remote
AR-RAE1E remote
AR-RAH2E remote
AR-REB1E remote
AR-RY4 remote
AST9RSGCW A/C (ARDB1)
ASTB09LBC A/C
ASU30C1 A/C
ASYG30LFCA A/C (ARRAH2E)
ASYG7LMCA A/C (ARREB1E) | ARDB1
ARJW2
ARRAH2E
ARREB1E
ARRY4 | Yes | | [Fujitsu](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Fujitsu.cpp) | **[Fujitsu General](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Fujitsu.h)** | AR-JW2 remote | ARDB1
ARJW2
ARRAH2E
ARREB1E
ARRY4 | Yes | -| [GICable](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_GICable.cpp) | **Unknown** | | | - | -| [GlobalCache](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_GlobalCache.cpp) | **Unknown** | | | - | +| [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 | | [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
YBOFB | Yes | +| [Gree](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.cpp) | **[Gree](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.h)** | YAA1FBF remote
YB1F2F remote | YAW1F
YBOFB | Yes | | [Gree](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.cpp) | **[Green](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.h)** | YBOFB remote
YBOFB2 remote | YAW1F
YBOFB | Yes | | [Gree](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.cpp) | **[RusClimate](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.h)** | EACS/I-09HAR_X/N3 A/C
YAW1F remote | YAW1F
YBOFB | Yes | | [Gree](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.cpp) | **[Ultimate](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.h)** | Heat Pump | YAW1F
YBOFB | Yes | -| [Haier](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Haier.cpp) | **[Haier](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Haier.h)** | HSU-09HMC203 A/C
HSU07-HEA03 remote
YR-W02 remote | | Yes | -| [Hitachi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Hitachi.cpp) | **[Hitachi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Hitachi.h)** | KAZE-312KSDP A/C (HITACHI_AC1)
LT0541-HTA remote
PC-LH3B (HITACHI_AC3)
R-LT0541-HTA/Y.K.1.1-1 V2.3 remote (HITACHI_AC1)
RAR-8P2 remote
RAS-35THA6 remote
RAS-AJ25H A/C
Series VI A/C (Circa 2007) | | Yes | +| [Haier](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Haier.cpp) | **[Haier](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Haier.h)** | HSU-09HMC203 A/C (HAIER_AC_YRW02)
HSU07-HEA03 remote (HAIER_AC)
YR-W02 remote (HAIER_AC_YRW02) | | Yes | +| [Hitachi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Hitachi.cpp) | **[Hitachi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Hitachi.h)** | KAZE-312KSDP A/C (HITACHI_AC1)
LT0541-HTA remote (HITACHI_AC1)
PC-LH3B (HITACHI_AC3)
R-LT0541-HTA/Y.K.1.1-1 V2.3 remote (HITACHI_AC1)
RAR-8P2 remote (HITACHI_AC424)
RAS-22NK A/C (HITACHI_AC344)
RAS-35THA6 remote
RAS-AJ25H A/C (HITACHI_AC424)
RF11T1 remote (HITACHI_AC344)
Series VI A/C (Circa 2007) (HITACHI_AC1) | | Yes | | [Inax](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Inax.cpp) | **Lixil** | Inax DT-BA283 Toilet | | - | -| [JVC](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_JVC.cpp) | **Unknown** | | | - | +| [JVC](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_JVC.cpp) | **JVC** | PTU94023B remote | | - | | [Kelvinator](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Kelvinator.cpp) | **[Green](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Kelvinator.h)** | YAPOF3 remote | | Yes | | [Kelvinator](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Kelvinator.cpp) | **[Kelvinator](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Kelvinator.h)** | KSV26CRC A/C
KSV26HRC A/C
KSV35CRC A/C
KSV35HRC A/C
KSV53HRC A/C
KSV62HRC A/C
KSV70CRC A/C
KSV70HRC A/C
KSV80HRC A/C
YALIF Remote | | Yes | | [LG](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_LG.cpp) | **[General Electric](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_LG.h)** | 6711AR2853M A/C Remote
AG1BH09AW101 Split A/C | | Yes | -| [LG](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_LG.cpp) | **[LG](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_LG.h)** | 6711A20083V remote
6711A20083V remote
AKB74395308 remote
AKB74395308 remote
AKB75215403 remote (LG2)
S4-W12JA3AA A/C (LG2) | | Yes | -| [Lasertag](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Lasertag.cpp) | **Unknown** | | | - | +| [LG](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_LG.cpp) | **[LG](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_LG.h)** | 6711A20083V remote (LG)
AKB74395308 remote (LG2)
AKB75215403 remote (LG2)
S4-W12JA3AA A/C (LG2) | | Yes | +| [Lasertag](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Lasertag.cpp) | **Lasertag** | Phaser emitters | | - | | [Lego](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Lego.cpp) | **LEGO Power Functions** | IR Receiver | | - | -| [Lutron](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Lutron.cpp) | **Unknown** | | | - | -| [MWM](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_MWM.cpp) | **Unknown** | | | - | -| [Magiquest](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Magiquest.cpp) | **[Unknown](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Magiquest.h)** | | | - | -| [Midea](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.cpp) | **[Comfee](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.h)** | MPD1-12CRN7 A/C | | Yes | -| [Midea](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.cpp) | **[Keystone](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.h)** | RG57H4(B)BGEF remote | | Yes | -| [Midea](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.cpp) | **[Pioneer System](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.h)** | RUBO18GMFILCAD A/C (18K BTU)
RYBO12GMFILCAD A/C (12K BTU) | | Yes | -| [Mitsubishi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Mitsubishi.cpp) | **[Mitsubishi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Mitsubishi.h)** | HC3000 Projector
KM14A 0179213 remote
MS-GK24VA A/C
TV | | 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
KPOA remote
MSH-A24WV / MUH-A24WV A/C
PEAD-RP71JAA Ducted A/C | | Yes | -| [MitsubishiHeavy](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_MitsubishiHeavy.cpp) | **[Mitsubishi Heavy Industries](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_MitsubishiHeavy.h)** | RKX502A001C remote
RLA502A700B remote
SRKxxZJ-S A/C
SRKxxZM-S A/C
SRKxxZMXA-S A/C | | Yes | +| [Lutron](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Lutron.cpp) | **Lutron** | MIR-ITFS remote
MIR-ITFS-F remote
MIR-ITFS-LF remote
SP-HT remote | | - | +| [MWM](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_MWM.cpp) | **Disney** | Made With Magic (Glow With The Show) wand | | - | +| [Magiquest](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Magiquest.cpp) | **[MagiQuest](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Magiquest.h)** | Wand | | - | +| [Midea](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.cpp) | **[Comfee](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.h)** | MPD1-12CRN7 A/C (MIDEA) | | Yes | +| [Midea](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.cpp) | **[Keystone](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.h)** | RG57H4(B)BGEF remote (MIDEA) | | Yes | +| [Midea](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.cpp) | **[Midea](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.h)** | FS40-7AR Stand Fan (MIDEA24) | | Yes | +| [Midea](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.cpp) | **[Pioneer System](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.h)** | RUBO18GMFILCAD A/C (18K BTU) (MIDEA)
RYBO12GMFILCAD A/C (12K BTU) (MIDEA) | | 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)
KM14A 0179213 remote
MS-GK24VA A/C
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)
KPOA remote (MITSUBISHI112)
MSH-A24WV A/C (MITSUBISHI112)
MUH-A24WV A/C (MITSUBISHI112)
PEAD-RP71JAA Ducted A/C (MITSUBISHI136) | | 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)
RLA502A700B remote (152 bit)
SRKxxZJ-S A/C (88 bit)
SRKxxZM-S A/C (152 bit)
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 | | - | +| [NEC](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_NEC.cpp) | **[Duux](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_NEC.h)** | Blizzard Smart 10K / DXMA04 A/C
YJ-A081 TR Remote | | - | +| [NEC](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_NEC.cpp) | **[Silan Microelectronics](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_NEC.h)** | SC6121-001 IC | | - | | [NEC](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_NEC.cpp) | **[Toshiba](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_NEC.h)** | 42TL838 LCD TV | | - | | [NEC](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_NEC.cpp) | **[Yamaha](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_NEC.h)** | RAV561 remote
RXV585B A/V Receiver | | - | -| [Neoclima](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Neoclima.cpp) | **[Neoclima](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Neoclima.h)** | NS-09AHTI A/C
NS-09AHTI A/C
ZH/TY-01 remote
ZH/TY-01 remote | | Yes | -| [Nikai](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Nikai.cpp) | **Unknown** | | | - | -| [Panasonic](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Panasonic.cpp) | **[Panasonic](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Panasonic.h)** | A75C2311 remote (CKP)
A75C2616-1 remote (DKE)
A75C3704 remote
A75C3747 remote
CKP series A/C
CS-E7PKR A/C (DKE)
CS-ME10CKPG A/C
CS-ME12CKPG A/C
CS-ME14CKPG A/C
CS-YW9MKD A/C
CS-Z9RKR A/C
DKE series A/C
DKW series A/C (DKE)
JKE series A/C
NKE series A/C
PKR series A/C (DKE)
RKR series A/C
TV | CKP
DKE
JKE
LKE
NKE
RKR | Yes | -| [Pioneer](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Pioneer.cpp) | **Unknown** | | | - | -| [Pronto](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Pronto.cpp) | **Unknown** | | | - | -| [RC5_RC6](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_RC5_RC6.cpp) | **Unknown** | | | - | +| [Neoclima](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Neoclima.cpp) | **[Neoclima](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Neoclima.h)** | NS-09AHTI A/C
ZH/TY-01 remote | | Yes | +| [Nikai](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Nikai.cpp) | **Nikai** | Unknown LCD TV | | - | +| [Panasonic](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Panasonic.cpp) | **[Panasonic](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Panasonic.h)** | A75C2311 remote (PANASONIC_AC CKP/5)
A75C2616-1 remote (PANASONIC_AC DKE/3)
A75C3704 remote (PANASONIC_AC DKE/3)
A75C3747 remote (PANASONIC_AC JKE/4)
CKP series A/C (PANASONIC_AC CKP/5)
CS-E7PKR A/C (PANASONIC_AC DKE/2)
CS-ME10CKPG A/C (PANASONIC_AC CKP/5)
CS-ME12CKPG A/C (PANASONIC_AC CKP/5)
CS-ME14CKPG A/C (PANASONIC_AC CKP/5)
CS-YW9MKD A/C (PANASONIC_AC JKE/4)
CS-Z9RKR A/C (PANASONIC_AC RKR/6)
DKE series A/C (PANASONIC_AC DKE/3)
DKW series A/C (PANASONIC_AC DKE/3)
JKE series A/C (PANASONIC_AC JKE/4)
NKE series A/C (PANASONIC_AC NKE/2)
PKR series A/C (PANASONIC_AC DKE/3)
RKR series A/C (PANASONIC_AC RKR/6)
TV (PANASONIC) | CKP
DKE
JKE
LKE
NKE
RKR | Yes | +| [Pioneer](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Pioneer.cpp) | **Pioneer** | AV Receivers | | - | +| [Pronto](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Pronto.cpp) | **Pronto** | Pronto Hex | | - | +| [RC5_RC6](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_RC5_RC6.cpp) | **Philips** | RC-5X (RC5X)
Standard RC-5 (RC5)
Standard RC-6 (RC6) | | - | | [RCMM](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_RCMM.cpp) | **Microsoft** | XBOX 360 | | - | -| [Samsung](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Samsung.cpp) | **[Samsung](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Samsung.h)** | AR09FSSDAWKNFA A/C
AR12HSSDBWKNEU A/C
AR12KSFPEWQNET A/C
AR12NXCXAWKXEU A/C
DB63-03556X003 remote
DB93-16761C remote
IEC-R03 remote
UA55H6300 TV | | Yes | -| [Sanyo](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Sanyo.cpp) | **Unknown** | | | - | -| [Sharp](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Sharp.cpp) | **[Sharp](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Sharp.h)** | AH-AxSAY A/C
AY-ZP40KR A/C
LC-52D62U TV | | Yes | +| [Samsung](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Samsung.cpp) | **[Samsung](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Samsung.h)** | AK59-00167A Bluray remote (SAMSUNG36)
AR09FSSDAWKNFA A/C (SAMSUNG_AC)
AR12HSSDBWKNEU A/C (SAMSUNG_AC)
AR12KSFPEWQNET A/C (SAMSUNG_AC)
AR12NXCXAWKXEU A/C (SAMSUNG_AC)
BN59-01178B TV remote (SAMSUNG)
DB63-03556X003 remote
DB93-16761C remote
IEC-R03 remote
UA55H6300 TV (SAMSUNG) | | Yes | +| [Sanyo](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Sanyo.cpp) | **Sanyo** | LC7461 transmitter IC (SANYO_LC7461)
SA 8650B - disabled | | - | +| [Sharp](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Sharp.cpp) | **[Sharp](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Sharp.h)** | AH-AxSAY A/C
AH-XP10NRY A/C
AY-ZP40KR A/C
CRMC-820JBEZ remote
CRMC-A907 JBEZ remote
LC-52D62U TV | | Yes | | [Sherwood](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Sherwood.cpp) | **Sherwood** | RC-138 remote
RD6505(B) Receiver | | - | | [Sony](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Sony.cpp) | **Sony** | HT-CT380 Soundbar (Uses 38kHz & 3 repeats) | | - | +| [Symphony](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Symphony.cpp) | **Blyss** | Owen-SW-5 3 Fan
WP-YK8 090218 remote | | - | +| [Symphony](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Symphony.cpp) | **SamHop** | SM3015 Fan Remote Control
SM5021 Encoder chip
SM5032 Decoder chip | | - | +| [Symphony](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Symphony.cpp) | **Satellite Electronic** | ID6 Remote
JY199I Fan driver
JY199I-L Fan driver | | - | | [Symphony](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Symphony.cpp) | **Symphony** | Air Cooler 3Di | | - | +| [Symphony](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Symphony.cpp) | **Westinghouse** | 78095 Remote
Ceiling fan | | - | | [Tcl](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Tcl.cpp) | **[Leberg](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Tcl.h)** | LBS-TOR07 A/C | | Yes | | [Teco](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Teco.cpp) | **[Alaska](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Teco.h)** | SAC9010QC A/C
SAC9010QC remote | | Yes | | [Toshiba](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Toshiba.cpp) | **[Toshiba](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Toshiba.h)** | Akita EVO II
RAS 18SKP-ES
RAS-B13N3KV2
RAS-B13N3KVP-E
WC-L03SE
WH-TA04NE | | Yes | -| [Trotec](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Trotec.cpp) | **[Unknown](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Trotec.h)** | | | Yes | +| [Trotec](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Trotec.cpp) | **[Duux](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Trotec.h)** | Blizzard Smart 10K / DXMA04 A/C | | Yes | +| [Trotec](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Trotec.cpp) | **[Trotec](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Trotec.h)** | PAC 3200 A/C | | Yes | | [Vestel](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Vestel.cpp) | **[Vestel](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Vestel.h)** | BIOX CXP-9 A/C (9K BTU) | | 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
DG11J1-3A remote
DG11J1-91 remote
SPIS409L A/C
SPIS412L A/C
SPIW409L A/C
SPIW412L A/C
SPIW418L A/C | DG11J13A
DG11J191 | Yes | | [Whynter](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Whynter.cpp) | **Whynter** | ARC-110WD A/C | | - | +| [Zepeal](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Zepeal.cpp) | **Zepeal** | DRT-A3311(BG) 5 button remote
DRT-A3311(BG) floor fan | | - | ## Send only protocols: @@ -89,7 +103,10 @@ - AMCOR - ARGO - CARRIER_AC +- CARRIER_AC40 +- CARRIER_AC64 - COOLIX +- CORONA_AC - DAIKIN - DAIKIN128 - DAIKIN152 @@ -98,8 +115,10 @@ - DAIKIN2 - DAIKIN216 - DAIKIN64 +- DELONGHI_AC - DENON - DISH +- DOSHISHA - ELECTRA_AC - EPSON - FUJITSU_AC @@ -112,6 +131,7 @@ - HITACHI_AC1 - HITACHI_AC2 - HITACHI_AC3 +- HITACHI_AC344 - HITACHI_AC424 - INAX - JVC @@ -123,6 +143,7 @@ - LUTRON - MAGIQUEST - MIDEA +- MIDEA24 - MITSUBISHI - MITSUBISHI112 - MITSUBISHI136 @@ -130,6 +151,7 @@ - MITSUBISHI_AC - MITSUBISHI_HEAVY_152 - MITSUBISHI_HEAVY_88 +- MULTIBRACKETS - MWM - NEC - NEC_LIKE @@ -158,3 +180,4 @@ - VESTEL_AC - WHIRLPOOL_AC - WHYNTER +- ZEPEAL diff --git a/lib/IRremoteESP8266-2.7.8/docs/README.md b/lib/IRremoteESP8266-2.7.8/docs/README.md new file mode 100644 index 000000000..262e82b62 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/README.md @@ -0,0 +1,61 @@ +# IRremoteESP8266 Library + +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. + +## Supported Protocols +You can find the details of which protocols & devices are supported +[here](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/SupportedProtocols.md). + +## Troubleshooting +Before reporting an issue or asking for help, please try to follow our [Troubleshooting Guide](https://github.com/crankyoldgit/IRremoteESP8266/wiki/Troubleshooting-Guide) first. + +## Frequently Asked Questions +Some common answers to common questions and problems are on our [F.A.Q. wiki page](https://github.com/crankyoldgit/IRremoteESP8266/wiki/Frequently-Asked-Questions). + +## Library API Documentation +This library uses [Doxygen](https://www.doxygen.nl/index.html) to [automatically document](https://crankyoldgit.github.io/IRremoteESP8266/doxygen/html/) the [library's](https://crankyoldgit.github.io/IRremoteESP8266/doxygen/html/) [API](https://en.wikipedia.org/wiki/Application_programming_interface). +You can find it [here](https://crankyoldgit.github.io/IRremoteESP8266/doxygen/html/). + +## Installation +##### Official releases via the Arduino IDE v1.8+ (Windows & Linux) +1. Click the _"Sketch"_ -> _"Include Library"_ -> _"Manage Libraries..."_ Menu items. +1. Enter `IRremoteESP8266` into the _"Filter your search..."_ top right search box. +1. Click on the IRremoteESP8266 result of the search. +1. Select the version you wish to install and click _"Install"_. + +##### Manual Installation for Windows +1. Click on _"Clone or Download"_ button, then _"[Download ZIP](https://github.com/crankyoldgit/IRremoteESP8266/archive->master.zip)"_ on the page. +1. Extract the contents of the downloaded zip file. +1. Rename the extracted folder to _"IRremoteESP8266"_. +1. Move this folder to your libraries directory. (under windows: `C:\Users\YOURNAME\Documents\Arduino\libraries\`) +1. Restart your Arduino IDE. +1. Check out the examples. + +##### Using Git to install the library ( Linux ) +``` +cd ~/Arduino/libraries +git clone https://github.com/crankyoldgit/IRremoteESP8266.git +``` +###### To update to the latest version of the library +``` +cd ~/Arduino/libraries/IRremoteESP8266 && git pull +``` + +## Contributing +If you want to [contribute](.github/CONTRIBUTING.md#how-can-i-contribute) to this project, consider: +- [Reporting](.github/CONTRIBUTING.md#reporting-bugs) bugs and errors +- Ask for enhancements +- Improve our documentation +- [Creating issues](.github/CONTRIBUTING.md#reporting-bugs) and [pull requests](.github/CONTRIBUTING.md#pull-requests) +- Tell other people about this library + +## Contributors +Available [here](.github/Contributors.md) + +## Library History +This library was originally based on Ken Shirriff's work (https://github.com/shirriff/Arduino-IRremote/) + +[Mark Szabo](https://github.com/crankyoldgit/IRremoteESP8266) has updated the IRsend class to work on ESP8266 and [Sebastien Warin](https://github.com/sebastienwarin/IRremoteESP8266) the receiving & decoding part (IRrecv class). + +As of v2.0, the library was almost entirely re-written with the ESP8266's resources in mind. diff --git a/lib/IRremoteESP8266-2.7.8/docs/README_fr.md b/lib/IRremoteESP8266-2.7.8/docs/README_fr.md new file mode 100644 index 000000000..3ff81c5d8 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/README_fr.md @@ -0,0 +1,64 @@ +# IRremoteESP8266 Library + +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. + +## Protocoles supportés +Vous pouvez trouver le détails des protocoles et machines supportés +[here](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/SupportedProtocols.md). + +## Dépannage +Avant de reporter un probème ou de demander de l'aide, essayez de suivre notre [guide de dépannage](https://github.com/crankyoldgit/IRremoteESP8266/wiki/Troubleshooting-Guide) first. + +## Questions fréquentes +Les questions les plus fréquentes sont ici, avec des réponses [F.A.Q. wiki page](https://github.com/crankyoldgit/IRremoteESP8266/wiki/Frequently-Asked-Questions). + +## Documentation API de la bibliothèque +Cette bibliothèque utilise [Doxygen](https://www.doxygen.nl/index.html) pour [documenter automatiquement](https://crankyoldgit.github.io/IRremoteESP8266/doxygen/html/) [l'API](https://en.wikipedia.org/wiki/Application_programming_interface) de la [bibliothèque](https://crankyoldgit.github.io/IRremoteESP8266/doxygen/html/). Vous pouvez le trouver [ici](https://crankyoldgit.github.io/IRremoteESP8266/doxygen/html/). + +## Installation +##### Officiel releases avec l'Arduino IDE v1.8+ (Windows & Linux) +1. Cliquez sur _"Sketch"_ -> _"Include Library"_ -> _"Manage Libraries..."_ Menu items. +1. Entrez `IRremoteESP8266` dans le _"Filter your search..."_ barre de recherche en haut à droite. +1. Cliquez sur le IRremoteESP8266 pour avoir les résultats de la recherche. +1. Selectionnez la version que vous voulez installer et cliquez sur _"Install"_. + +## Library API Documentation +This library uses [Doxygen](https://www.doxygen.nl/index.html) to [automatically document](https://crankyoldgit.github.io/IRremoteESP8266/doxygen/html/) the [library's](https://crankyoldgit.github.io/IRremoteESP8266/doxygen/html/) [API](https://en.wikipedia.org/wiki/Application_programming_interface). +You can find it [here](https://crankyoldgit.github.io/IRremoteESP8266/doxygen/html/). + +##### Installation manuelle pour Windows +1. cliquez le boutton sur _"Clone or Download"_ , et _"[Download ZIP](https://github.com/crankyoldgit/IRremoteESP8266/archive->master.zip)"_ on the page. +1. Extraire l'archive. +1. renommez le fichier par _"IRremoteESP8266"_. +1. déplacer le fichier dans votre fichier de bibliothèques. (Pour windows : `C:\Users\VOTRE_NOM\Documents\Arduino\libraries\`) +1. Redemarrez arduino IDE. +1. Regardez les exemples. + +##### En utilisant GIT ( Linux ) +``` +cd ~/Arduino/libraries +git clone https://github.com/crankyoldgit/IRremoteESP8266.git +``` +###### Pour se mettre à jour +``` +cd ~/Arduino/libraries/IRremoteESP8266 && git pull +``` + +## Contribution +Si vous voulez [contribuer](.github/CONTRIBUTING.md#how-can-i-contribute) au projet, pour les erreurs: +- [Reporting](.github/CONTRIBUTING.md#reporting-bugs) bug et erreurs +- Demander des améliorations +- Améliorer notre documentation +- [Création d'issues](.github/CONTRIBUTING.md#reporting-bugs) et [pull requests](.github/CONTRIBUTING.md#pull-requests) +- Parlez de cettre librairie à d'autres personnes + +## Contributeurs +disponible [ici](.github/Contributors.md) + +## Historique de la bibliothèque +Elle est basée sur le travail de Shirriff (https://github.com/shirriff/Arduino-IRremote/) + +[Mark Szabo](https://github.com/crankyoldgit/IRremoteESP8266) à mis a jour la IRsend class pour qu'elle soit fonctionnelle sur ESP8266 et [Sebastien Warin](https://github.com/sebastienwarin/IRremoteESP8266) s'est occupé de la partie réception et décodage (IRrecv class). + +Comme pour la version 2.0, la bibliothèque à été completement réécrite avec les ressources sur ESP8266. diff --git a/lib/IRremoteESP8266-2.7.8/docs/_config.yml b/lib/IRremoteESP8266-2.7.8/docs/_config.yml new file mode 100644 index 000000000..c74188174 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-slate \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRac_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRac_8cpp.html new file mode 100644 index 000000000..2cd303da8 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRac_8cpp.html @@ -0,0 +1,98 @@ + + + + + + + +IRremoteESP8266: src/IRac.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
IRac.cpp File Reference
+
+
+ + + + +

+Namespaces

 IRAcUtils
 
+ + + + + + + +

+Functions

String IRAcUtils::resultAcToString (const decode_results *const result)
 Display the human readable state of an A/C message if we can. More...
 
bool IRAcUtils::decodeToState (const decode_results *decode, stdAc::state_t *result, const stdAc::state_t *prev)
 Convert a valid IR A/C remote message that we understand enough into a Common A/C state. More...
 
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRac_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRac_8h.html new file mode 100644 index 000000000..8a58a1eee --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRac_8h.html @@ -0,0 +1,127 @@ + + + + + + + +IRremoteESP8266: src/IRac.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
IRac.h File Reference
+
+
+ +

Go to the source code of this file.

+ + + + +

+Classes

class  IRac
 
+ + + +

+Namespaces

 IRAcUtils
 
+ + + + + + + +

+Functions

String IRAcUtils::resultAcToString (const decode_results *const result)
 Display the human readable state of an A/C message if we can. More...
 
bool IRAcUtils::decodeToState (const decode_results *decode, stdAc::state_t *result, const stdAc::state_t *prev)
 Convert a valid IR A/C remote message that we understand enough into a Common A/C state. More...
 
+ + + +

+Variables

const int8_t kGpioUnused = -1
 
+

Variable Documentation

+ +

◆ kGpioUnused

+ +
+
+ + + + +
const int8_t kGpioUnused = -1
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRac_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRac_8h_source.html new file mode 100644 index 000000000..00c94ee20 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRac_8h_source.html @@ -0,0 +1,652 @@ + + + + + + + +IRremoteESP8266: src/IRac.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
IRac.h
+
+
+Go to the documentation of this file.
1 #ifndef IRAC_H_
+
2 #define IRAC_H_
+
3 
+
4 // Copyright 2019 David Conran
+
5 
+
6 #ifndef UNIT_TEST
+
7 #include <Arduino.h>
+
8 #endif
+
9 #include "IRremoteESP8266.h"
+
10 #include "ir_Amcor.h"
+
11 #include "ir_Argo.h"
+
12 #include "ir_Carrier.h"
+
13 #include "ir_Coolix.h"
+
14 #include "ir_Corona.h"
+
15 #include "ir_Daikin.h"
+
16 #include "ir_Delonghi.h"
+
17 #include "ir_Fujitsu.h"
+
18 #include "ir_Electra.h"
+
19 #include "ir_Goodweather.h"
+
20 #include "ir_Gree.h"
+
21 #include "ir_Haier.h"
+
22 #include "ir_Hitachi.h"
+
23 #include "ir_Kelvinator.h"
+
24 #include "ir_LG.h"
+
25 #include "ir_Midea.h"
+
26 #include "ir_Mitsubishi.h"
+
27 #include "ir_MitsubishiHeavy.h"
+
28 #include "ir_Neoclima.h"
+
29 #include "ir_Panasonic.h"
+
30 #include "ir_Samsung.h"
+
31 #include "ir_Sharp.h"
+
32 #include "ir_Tcl.h"
+
33 #include "ir_Teco.h"
+
34 #include "ir_Toshiba.h"
+
35 #include "ir_Trotec.h"
+
36 #include "ir_Vestel.h"
+
37 #include "ir_Whirlpool.h"
+
38 
+
39 // Constants
+
40 const int8_t kGpioUnused = -1;
+
41 
+
42 // Class
+
43 class IRac {
+
44  public:
+
45  explicit IRac(const uint16_t pin, const bool inverted = false,
+
46  const bool use_modulation = true);
+
47  static bool isProtocolSupported(const decode_type_t protocol);
+
48  static void initState(stdAc::state_t *state,
+
49  const decode_type_t vendor, const int16_t model,
+
50  const bool power, const stdAc::opmode_t mode,
+
51  const float degrees, const bool celsius,
+
52  const stdAc::fanspeed_t fan,
+
53  const stdAc::swingv_t swingv,
+
54  const stdAc::swingh_t swingh,
+
55  const bool quiet, const bool turbo, const bool econo,
+
56  const bool light, const bool filter, const bool clean,
+
57  const bool beep, const int16_t sleep,
+
58  const int16_t clock);
+
59  static void initState(stdAc::state_t *state);
+
60  void markAsSent(void);
+
61  bool sendAc(void);
+
62  bool sendAc(const stdAc::state_t desired, const stdAc::state_t *prev = NULL);
+
63  bool sendAc(const decode_type_t vendor, const int16_t model,
+
64  const bool power, const stdAc::opmode_t mode, const float degrees,
+
65  const bool celsius, const stdAc::fanspeed_t fan,
+
66  const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
+
67  const bool quiet, const bool turbo, const bool econo,
+
68  const bool light, const bool filter, const bool clean,
+
69  const bool beep, const int16_t sleep = -1,
+
70  const int16_t clock = -1);
+
71  static bool cmpStates(const stdAc::state_t a, const stdAc::state_t b);
+
72  static bool strToBool(const char *str, const bool def = false);
+
73  static int16_t strToModel(const char *str, const int16_t def = -1);
+ +
75  const char *str, const stdAc::opmode_t def = stdAc::opmode_t::kAuto);
+ +
77  const char *str,
+ + +
80  const char *str, const stdAc::swingv_t def = stdAc::swingv_t::kOff);
+ +
82  const char *str, const stdAc::swingh_t def = stdAc::swingh_t::kOff);
+
83  static String boolToString(const bool value);
+
84  static String opmodeToString(const stdAc::opmode_t mode);
+
85  static String fanspeedToString(const stdAc::fanspeed_t speed);
+
86  static String swingvToString(const stdAc::swingv_t swingv);
+
87  static String swinghToString(const stdAc::swingh_t swingh);
+ + +
90  bool hasStateChanged(void);
+ +
92 #ifndef UNIT_TEST
+
93 
+
94  private:
+
95 #endif
+
96  uint16_t _pin;
+
97  bool _inverted;
+ +
99  stdAc::state_t _prev; // The state we expect the device to currently be in.
+
100 #if SEND_AMCOR
+
101  void amcor(IRAmcorAc *ac,
+
102  const bool on, const stdAc::opmode_t mode, const float degrees,
+
103  const stdAc::fanspeed_t fan);
+
104 #endif // SEND_AMCOR
+
105 #if SEND_ARGO
+
106  void argo(IRArgoAC *ac,
+
107  const bool on, const stdAc::opmode_t mode, const float degrees,
+
108  const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv,
+
109  const bool turbo, const int16_t sleep = -1);
+
110 #endif // SEND_ARGO
+
111 #if SEND_CARRIER_AC64
+
112 void carrier64(IRCarrierAc64 *ac,
+
113  const bool on, const stdAc::opmode_t mode,
+
114  const float degrees, const stdAc::fanspeed_t fan,
+
115  const stdAc::swingv_t swingv, const int16_t sleep = -1);
+
116 #endif // SEND_CARRIER_AC64
+
117 #if SEND_COOLIX
+
118  void coolix(IRCoolixAC *ac,
+
119  const bool on, const stdAc::opmode_t mode, const float degrees,
+
120  const stdAc::fanspeed_t fan,
+
121  const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
+
122  const bool turbo, const bool light, const bool clean,
+
123  const int16_t sleep = -1);
+
124 #endif // SEND_COOLIX
+
125 #if SEND_CORONA_AC
+
126  void corona(IRCoronaAc *ac,
+
127  const bool on, const stdAc::opmode_t mode,
+
128  const float degrees, const stdAc::fanspeed_t fan,
+
129  const stdAc::swingv_t swingv, const bool econo);
+
130 #endif // SEND_CORONA_AC
+
131 #if SEND_DAIKIN
+
132  void daikin(IRDaikinESP *ac,
+
133  const bool on, const stdAc::opmode_t mode, const float degrees,
+
134  const stdAc::fanspeed_t fan,
+
135  const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
+
136  const bool quiet, const bool turbo, const bool econo,
+
137  const bool clean);
+
138 #endif // SEND_DAIKIN
+
139 #if SEND_DAIKIN128
+
140  void daikin128(IRDaikin128 *ac,
+
141  const bool on, const stdAc::opmode_t mode,
+
142  const float degrees, const stdAc::fanspeed_t fan,
+
143  const stdAc::swingv_t swingv,
+
144  const bool quiet, const bool turbo, const bool light,
+
145  const bool econo, const int16_t sleep = -1,
+
146  const int16_t clock = -1);
+
147 #endif // SEND_DAIKIN128
+
148 #if SEND_DAIKIN152
+
149  void daikin152(IRDaikin152 *ac,
+
150  const bool on, const stdAc::opmode_t mode,
+
151  const float degrees, const stdAc::fanspeed_t fan,
+
152  const stdAc::swingv_t swingv,
+
153  const bool quiet, const bool turbo, const bool econo);
+
154 #endif // SEND_DAIKIN152
+
155 #if SEND_DAIKIN160
+
156  void daikin160(IRDaikin160 *ac,
+
157  const bool on, const stdAc::opmode_t mode,
+
158  const float degrees, const stdAc::fanspeed_t fan,
+
159  const stdAc::swingv_t swingv);
+
160 #endif // SEND_DAIKIN160
+
161 #if SEND_DAIKIN176
+
162  void daikin176(IRDaikin176 *ac,
+
163  const bool on, const stdAc::opmode_t mode,
+
164  const float degrees, const stdAc::fanspeed_t fan,
+
165  const stdAc::swingh_t swingh);
+
166 #endif // SEND_DAIKIN176
+
167 #if SEND_DAIKIN2
+
168  void daikin2(IRDaikin2 *ac,
+
169  const bool on, const stdAc::opmode_t mode,
+
170  const float degrees, const stdAc::fanspeed_t fan,
+
171  const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
+
172  const bool quiet, const bool turbo, const bool light,
+
173  const bool econo, const bool filter, const bool clean,
+
174  const bool beep, const int16_t sleep = -1,
+
175  const int16_t clock = -1);
+
176 #endif // SEND_DAIKIN2
+
177 #if SEND_DAIKIN216
+
178 void daikin216(IRDaikin216 *ac,
+
179  const bool on, const stdAc::opmode_t mode,
+
180  const float degrees, const stdAc::fanspeed_t fan,
+
181  const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
+
182  const bool quiet, const bool turbo);
+
183 #endif // SEND_DAIKIN216
+
184 #if SEND_DAIKIN64
+
185  void daikin64(IRDaikin64 *ac,
+
186  const bool on, const stdAc::opmode_t mode,
+
187  const float degrees, const stdAc::fanspeed_t fan,
+
188  const stdAc::swingv_t swingv,
+
189  const bool quiet, const bool turbo,
+
190  const int16_t sleep = -1, const int16_t clock = -1);
+
191 #endif // SEND_DAIKIN64
+
192 #if SEND_DELONGHI_AC
+
193  void delonghiac(IRDelonghiAc *ac,
+
194  const bool on, const stdAc::opmode_t mode, const bool celsius,
+
195  const float degrees, const stdAc::fanspeed_t fan,
+
196  const bool turbo, const int16_t sleep = -1);
+
197 #endif // SEND_DELONGHI_AC
+
198 #if SEND_ELECTRA_AC
+
199 void electra(IRElectraAc *ac,
+
200  const bool on, const stdAc::opmode_t mode,
+
201  const float degrees, const stdAc::fanspeed_t fan,
+
202  const stdAc::swingv_t swingv,
+
203  const stdAc::swingh_t swingh, const bool turbo,
+
204  const bool lighttoggle, const bool clean);
+
205 #endif // SEND_ELECTRA_AC
+
206 #if SEND_FUJITSU_AC
+
207  void fujitsu(IRFujitsuAC *ac, const fujitsu_ac_remote_model_t model,
+
208  const bool on, const stdAc::opmode_t mode, const float degrees,
+
209  const stdAc::fanspeed_t fan,
+
210  const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
+
211  const bool quiet, const bool turbo, const bool econo,
+
212  const bool filter, const bool clean);
+
213 #endif // SEND_FUJITSU_AC
+
214 #if SEND_GOODWEATHER
+
215  void goodweather(IRGoodweatherAc *ac,
+
216  const bool on, const stdAc::opmode_t mode,
+
217  const float degrees,
+
218  const stdAc::fanspeed_t fan,
+
219  const stdAc::swingv_t swingv,
+
220  const bool turbo, const bool light,
+
221  const int16_t sleep = -1);
+
222 #endif // SEND_GOODWEATHER
+
223 #if SEND_GREE
+
224  void gree(IRGreeAC *ac, const gree_ac_remote_model_t model,
+
225  const bool on, const stdAc::opmode_t mode, const bool celsius,
+
226  const float degrees, const stdAc::fanspeed_t fan,
+
227  const stdAc::swingv_t swingv, const bool turbo, const bool light,
+
228  const bool clean, const int16_t sleep = -1);
+
229 #endif // SEND_GREE
+
230 #if SEND_HAIER_AC
+
231  void haier(IRHaierAC *ac,
+
232  const bool on, const stdAc::opmode_t mode, const float degrees,
+
233  const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv,
+
234  const bool filter, const int16_t sleep = -1,
+
235  const int16_t clock = -1);
+
236 #endif // SEND_HAIER_AC
+
237 #if SEND_HAIER_AC_YRW02
+
238  void haierYrwo2(IRHaierACYRW02 *ac,
+
239  const bool on, const stdAc::opmode_t mode,
+
240  const float degrees, const stdAc::fanspeed_t fan,
+
241  const stdAc::swingv_t swingv,
+
242  const bool turbo, const bool filter,
+
243  const int16_t sleep = -1);
+
244 #endif // SEND_HAIER_AC_YRW02
+
245 #if SEND_HITACHI_AC
+
246  void hitachi(IRHitachiAc *ac,
+
247  const bool on, const stdAc::opmode_t mode,
+
248  const float degrees, const stdAc::fanspeed_t fan,
+
249  const stdAc::swingv_t swingv, const stdAc::swingh_t swingh);
+
250 #endif // SEND_HITACHI_AC
+
251 #if SEND_HITACHI_AC1
+
252  void hitachi1(IRHitachiAc1 *ac, const hitachi_ac1_remote_model_t model,
+
253  const bool on, const bool power_toggle,
+
254  const stdAc::opmode_t mode,
+
255  const float degrees, const stdAc::fanspeed_t fan,
+
256  const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
+
257  const bool swing_toggle, const int16_t sleep = -1);
+
258 #endif // SEND_HITACHI_AC1
+
259 #if SEND_HITACHI_AC344
+
260  void hitachi344(IRHitachiAc344 *ac,
+
261  const bool on, const stdAc::opmode_t mode,
+
262  const float degrees, const stdAc::fanspeed_t fan,
+
263  const stdAc::swingv_t swingv,
+
264  const stdAc::swingh_t swingh);
+
265 #endif // SEND_HITACHI_AC344
+
266 #if SEND_HITACHI_AC424
+
267  void hitachi424(IRHitachiAc424 *ac,
+
268  const bool on, const stdAc::opmode_t mode,
+
269  const float degrees, const stdAc::fanspeed_t fan,
+
270  const stdAc::swingv_t swingv);
+
271 #endif // SEND_HITACHI_AC424
+
272 #if SEND_KELVINATOR
+
273  void kelvinator(IRKelvinatorAC *ac,
+
274  const bool on, const stdAc::opmode_t mode,
+
275  const float degrees, const stdAc::fanspeed_t fan,
+
276  const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
+
277  const bool quiet, const bool turbo, const bool light,
+
278  const bool filter, const bool clean);
+
279 #endif // SEND_KELVINATOR
+
280 #if SEND_LG
+
281  void lg(IRLgAc *ac, const lg_ac_remote_model_t model,
+
282  const bool on, const stdAc::opmode_t mode,
+
283  const float degrees, const stdAc::fanspeed_t fan);
+
284 #endif // SEND_LG
+
285 #if SEND_MIDEA
+
286  void midea(IRMideaAC *ac,
+
287  const bool on, const stdAc::opmode_t mode, const bool celsius,
+
288  const float degrees, const stdAc::fanspeed_t fan,
+
289  const stdAc::swingv_t swingv, const int16_t sleep = -1);
+
290 #endif // SEND_MIDEA
+
291 #if SEND_MITSUBISHI_AC
+
292  void mitsubishi(IRMitsubishiAC *ac,
+
293  const bool on, const stdAc::opmode_t mode,
+
294  const float degrees,
+
295  const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv,
+
296  const stdAc::swingh_t swingh,
+
297  const bool quiet, const int16_t clock = -1);
+
298 #endif // SEND_MITSUBISHI_AC
+
299 #if SEND_MITSUBISHI112
+ +
301  const bool on, const stdAc::opmode_t mode,
+
302  const float degrees, const stdAc::fanspeed_t fan,
+
303  const stdAc::swingv_t swingv,
+
304  const stdAc::swingh_t swingh,
+
305  const bool quiet);
+
306 #endif // SEND_MITSUBISHI112
+
307 #if SEND_MITSUBISHI136
+ +
309  const bool on, const stdAc::opmode_t mode,
+
310  const float degrees, const stdAc::fanspeed_t fan,
+
311  const stdAc::swingv_t swingv, const bool quiet);
+
312 #endif // SEND_MITSUBISHI136
+
313 #if SEND_MITSUBISHIHEAVY
+ +
315  const bool on, const stdAc::opmode_t mode,
+
316  const float degrees, const stdAc::fanspeed_t fan,
+
317  const stdAc::swingv_t swingv,
+
318  const stdAc::swingh_t swingh,
+
319  const bool turbo, const bool econo, const bool clean);
+ +
321  const bool on, const stdAc::opmode_t mode,
+
322  const float degrees, const stdAc::fanspeed_t fan,
+
323  const stdAc::swingv_t swingv,
+
324  const stdAc::swingh_t swingh,
+
325  const bool quiet, const bool turbo, const bool econo,
+
326  const bool filter, const bool clean,
+
327  const int16_t sleep = -1);
+
328 #endif // SEND_MITSUBISHIHEAVY
+
329 #if SEND_NEOCLIMA
+
330  void neoclima(IRNeoclimaAc *ac, const bool on, const stdAc::opmode_t mode,
+
331  const float degrees, const stdAc::fanspeed_t fan,
+
332  const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
+
333  const bool turbo, const bool light, const bool filter,
+
334  const int16_t sleep = -1);
+
335 #endif // SEND_NEOCLIMA
+
336 #if SEND_PANASONIC_AC
+ +
338  const bool on, const stdAc::opmode_t mode, const float degrees,
+
339  const stdAc::fanspeed_t fan,
+
340  const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
+
341  const bool quiet, const bool turbo, const bool filter,
+
342  const int16_t clock = -1);
+
343 #endif // SEND_PANASONIC_AC
+
344 #if SEND_SAMSUNG_AC
+
345  void samsung(IRSamsungAc *ac,
+
346  const bool on, const stdAc::opmode_t mode, const float degrees,
+
347  const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv,
+
348  const bool quiet, const bool turbo, const bool light,
+
349  const bool filter, const bool clean,
+
350  const bool beep, const bool prevpower = true,
+
351  const bool forcepower = true);
+
352 #endif // SEND_SAMSUNG_AC
+
353 #if SEND_SHARP_AC
+
354  void sharp(IRSharpAc *ac,
+
355  const bool on, const bool prev_power, const stdAc::opmode_t mode,
+
356  const float degrees, const stdAc::fanspeed_t fan,
+
357  const stdAc::swingv_t swingv, const bool turbo, const bool filter,
+
358  const bool clean);
+
359 #endif // SEND_SHARP_AC
+
360 #if SEND_TCL112AC
+
361  void tcl112(IRTcl112Ac *ac,
+
362  const bool on, const stdAc::opmode_t mode, const float degrees,
+
363  const stdAc::fanspeed_t fan,
+
364  const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
+
365  const bool turbo, const bool light, const bool econo,
+
366  const bool filter);
+
367 #endif // SEND_TCL112AC
+
368 #if SEND_TECO
+
369  void teco(IRTecoAc *ac,
+
370  const bool on, const stdAc::opmode_t mode, const float degrees,
+
371  const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv,
+
372  const bool light, const int16_t sleep = -1);
+
373 #endif // SEND_TECO
+
374 #if SEND_TOSHIBA_AC
+
375  void toshiba(IRToshibaAC *ac,
+
376  const bool on, const stdAc::opmode_t mode, const float degrees,
+
377  const stdAc::fanspeed_t fan);
+
378 #endif // SEND_TOSHIBA_AC
+
379 #if SEND_TROTEC
+
380  void trotec(IRTrotecESP *ac,
+
381  const bool on, const stdAc::opmode_t mode, const float degrees,
+
382  const stdAc::fanspeed_t fan, const int16_t sleep = -1);
+
383 #endif // SEND_TROTEC
+
384 #if SEND_VESTEL_AC
+
385  void vestel(IRVestelAc *ac,
+
386  const bool on, const stdAc::opmode_t mode, const float degrees,
+
387  const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv,
+
388  const bool turbo, const bool filter,
+
389  const int16_t sleep = -1, const int16_t clock = -1,
+
390  const bool sendNormal = true);
+
391 #endif // SEND_VESTEL_AC
+
392 #if SEND_WHIRLPOOL_AC
+ +
394  const bool on, const stdAc::opmode_t mode, const float degrees,
+
395  const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv,
+
396  const bool turbo, const bool light,
+
397  const int16_t sleep = -1, const int16_t clock = -1);
+
398 #endif // SEND_WHIRLPOOL_AC
+
399 static stdAc::state_t cleanState(const stdAc::state_t state);
+
400 static stdAc::state_t handleToggles(const stdAc::state_t desired,
+
401  const stdAc::state_t *prev = NULL);
+
402 }; // IRac class
+
403 
+
404 namespace IRAcUtils {
+
405  String resultAcToString(const decode_results * const results);
+
406  bool decodeToState(const decode_results *decode, stdAc::state_t *result,
+
407  const stdAc::state_t *prev = NULL);
+
408 } // namespace IRAcUtils
+
409 #endif // IRAC_H_
+
+
Class for handling detailed Panasonic A/C messages.
Definition: ir_Panasonic.h:98
+
Support for Kelvinator A/C protocols.
+
Class for handling detailed Samsung A/C messages.
Definition: ir_Samsung.h:95
+
void hitachi(IRHitachiAc *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)
Send a Hitachi A/C message with the supplied settings.
Definition: IRac.cpp:1020
+
Class for handling detailed Toshiba A/C messages.
Definition: ir_Toshiba.h:62
+
decode_type_t
Enumerator for defining and numbering of supported IR protocol.
Definition: IRremoteESP8266.h:714
+
stdAc::state_t getStatePrev(void)
Get the previous internal A/C climate state that should have already been sent to the device....
Definition: IRac.cpp:128
+
stdAc::state_t getState(void)
Get the current internal A/C climate state.
Definition: IRac.cpp:123
+
Class for handling detailed Mitsubishi Heavy 152-bit A/C messages.
Definition: ir_MitsubishiHeavy.h:133
+
static stdAc::swingh_t strToSwingH(const char *str, const stdAc::swingh_t def=stdAc::swingh_t::kOff)
Convert the supplied str into the appropriate enum.
Definition: IRac.cpp:2499
+
void hitachi344(IRHitachiAc344 *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)
Send a Hitachi 344-bit A/C message with the supplied settings.
Definition: IRac.cpp:1096
+ +
Support for Electra A/C protocols.
+
void markAsSent(void)
Update the previous state to the current one.
Definition: IRac.cpp:2362
+
swingv_t
Common A/C settings for Vertical Swing.
Definition: IRsend.h:70
+
void daikin2(IRDaikin2 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool light, const bool econo, const bool filter, const bool clean, const bool beep, const int16_t sleep=-1, const int16_t clock=-1)
Send a Daikin2 A/C message with the supplied settings.
Definition: IRac.cpp:640
+
Support for Trotec protocols.
+
Class for handling detailed Daikin 280-bit A/C messages.
Definition: ir_Daikin.h:520
+
void lg(IRLgAc *ac, const lg_ac_remote_model_t model, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan)
Send a LG A/C message with the supplied settings.
Definition: IRac.cpp:1202
+
Class for handling detailed Delonghi A/C messages.
Definition: ir_Delonghi.h:102
+
Class for handling detailed Corona A/C messages.
Definition: ir_Corona.h:93
+
void kelvinator(IRKelvinatorAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool light, const bool filter, const bool clean)
Send a Kelvinator A/C message with the supplied settings.
Definition: IRac.cpp:1168
+
Class for handling detailed Daikin 312-bit A/C messages. Code by crankyoldgit, Reverse engineering an...
Definition: ir_Daikin.h:602
+
Support for Neoclima protocols. Analysis by crankyoldgit & AndreyShpilevoy.
+
Class for handling detailed Daikin 128-bit A/C messages. Code by crankyoldgit. Analysis by Daniel Ven...
Definition: ir_Daikin.h:864
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
Support for Sharp protocols.
+
static String fanspeedToString(const stdAc::fanspeed_t speed)
Convert the supplied fan speed enum into the appropriate String.
Definition: IRac.cpp:2641
+
whirlpool_ac_remote_model_t
Whirlpool A/C model numbers.
Definition: IRsend.h:152
+
Carrier A/C.
+
void whirlpool(IRWhirlpoolAc *ac, const whirlpool_ac_remote_model_t model, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool turbo, const bool light, const int16_t sleep=-1, const int16_t clock=-1)
Send a Whirlpool A/C message with the supplied settings.
Definition: IRac.cpp:1814
+
Results returned from the decoder.
Definition: IRrecv.h:92
+
void daikin64(IRDaikin64 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool quiet, const bool turbo, const int16_t sleep=-1, const int16_t clock=-1)
Send a Daikin 64-bit A/C message with the supplied settings.
Definition: IRac.cpp:709
+
void tcl112(IRTcl112Ac *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 light, const bool econo, const bool filter)
Send a TCL 112-bit A/C message with the supplied settings.
Definition: IRac.cpp:1640
+
bool sendAc(void)
Send an A/C message based soley on our internal state.
Definition: IRac.cpp:2368
+
static bool cmpStates(const stdAc::state_t a, const stdAc::state_t b)
Compare two AirCon states.
Definition: IRac.cpp:2379
+
Support for Midea protocols. Midea added by crankyoldgit & bwze.
+
Support for Daikin A/C protocols.
+
gree_ac_remote_model_t
Gree A/C model numbers.
Definition: IRsend.h:129
+
Class for handling detailed Daikin 64-bit A/C messages.
Definition: ir_Daikin.h:998
+ +
void vestel(IRVestelAc *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 bool filter, const int16_t sleep=-1, const int16_t clock=-1, const bool sendNormal=true)
Send a Vestel A/C message with the supplied settings.
Definition: IRac.cpp:1773
+
Class for handling detailed Hitachi 53-byte/424-bit A/C messages.
Definition: ir_Hitachi.h:313
+
void daikin(IRDaikinESP *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool econo, const bool clean)
Send a Daikin A/C message with the supplied settings.
Definition: IRac.cpp:476
+
IRac(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: IRac.cpp:49
+
Class for handling detailed Daikin 216-bit A/C messages.
Definition: ir_Daikin.h:698
+
hitachi_ac1_remote_model_t
HITACHI_AC1 A/C model numbers.
Definition: IRsend.h:135
+
void samsung(IRSamsungAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool quiet, const bool turbo, const bool light, const bool filter, const bool clean, const bool beep, const bool prevpower=true, const bool forcepower=true)
Send a Samsung A/C message with the supplied settings.
Definition: IRac.cpp:1544
+
void daikin128(IRDaikin128 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool quiet, const bool turbo, const bool light, const bool econo, const int16_t sleep=-1, const int16_t clock=-1)
Send a Daikin 128-bit A/C message with the supplied settings.
Definition: IRac.cpp:516
+
Class for handling detailed Hitachi 224-bit A/C messages.
Definition: ir_Hitachi.h:188
+
const int8_t kGpioUnused
Definition: IRac.h:40
+
Definition: IRac.cpp:2710
+
void haier(IRHaierAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool filter, const int16_t sleep=-1, const int16_t clock=-1)
Send a Haier A/C message with the supplied settings.
Definition: IRac.cpp:951
+
Class for handling detailed Whirlpool A/C messages.
Definition: ir_Whirlpool.h:91
+
Class for handling detailed Hitachi 344-bit A/C messages.
Definition: ir_Hitachi.h:401
+
static String boolToString(const bool value)
Convert the supplied boolean into the appropriate String.
Definition: IRac.cpp:2612
+
stdAc::state_t next
The state we want the device to be in after we send.
Definition: IRac.h:91
+
std::string String
Definition: IRremoteESP8266.h:1093
+
Class for handling detailed Mitsubishi 144-bit A/C messages. Inspired and derived from the work done ...
Definition: ir_Mitsubishi.h:168
+
void trotec(IRTrotecESP *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const int16_t sleep=-1)
Send a Trotec A/C message with the supplied settings.
Definition: IRac.cpp:1736
+
static int16_t strToModel(const char *str, const int16_t def=-1)
Convert the supplied str into the appropriate enum.
Definition: IRac.cpp:2539
+
Class for handling detailed Amcor A/C messages.
Definition: ir_Amcor.h:81
+
Definition: ir_Mitsubishi.h:286
+
Class for handling detailed TCL A/C messages.
Definition: ir_Tcl.h:63
+
void daikin176(IRDaikin176 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingh_t swingh)
Send a Daikin 176-bit A/C message with the supplied settings.
Definition: IRac.cpp:608
+
Class for handling detailed Electra A/C messages.
Definition: ir_Electra.h:80
+
Support for TCL protocols.
+
bool hasStateChanged(void)
Check if the internal state has changed from what was previously sent.
Definition: IRac.cpp:2391
+
void haierYrwo2(IRHaierACYRW02 *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 bool filter, const int16_t sleep=-1)
Send a Haier YRWO2 A/C message with the supplied settings.
Definition: IRac.cpp:988
+
void daikin216(IRDaikin216 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo)
Send a Daikin 216-bit A/C message with the supplied settings.
Definition: IRac.cpp:679
+
Support for Hitachi A/C protocols.
+
Support for Panasonic protocols.
+
static stdAc::state_t handleToggles(const stdAc::state_t desired, const stdAc::state_t *prev=NULL)
Create a new state base on desired & previous states but handle any state changes for options that ne...
Definition: IRac.cpp:1858
+
Class for handling detailed Mitsubishi 136-bit A/C messages.
Definition: ir_Mitsubishi.h:232
+
panasonic_ac_remote_model_t
Panasonic A/C model numbers.
Definition: IRsend.h:141
+ +
swingh_t
Common A/C settings for Horizontal Swing.
Definition: IRsend.h:83
+
void mitsubishi112(IRMitsubishi112 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet)
Send a Mitsubishi 112-bit A/C message with the supplied settings.
Definition: IRac.cpp:1306
+
bool decodeToState(const decode_results *decode, stdAc::state_t *result, const stdAc::state_t *prev)
Convert a valid IR A/C remote message that we understand enough into a Common A/C state.
Definition: IRac.cpp:3033
+
Class for handling detailed Hitachi 104-bit A/C messages.
Definition: ir_Hitachi.h:245
+
void hitachi424(IRHitachiAc424 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv)
Send a Hitachi 424-bit A/C message with the supplied settings.
Definition: IRac.cpp:1130
+
Support for Samsung protocols. Samsung originally added from https://github.com/shirriff/Arduino-IRre...
+
String resultAcToString(const decode_results *const result)
Display the human readable state of an A/C message if we can.
Definition: IRac.cpp:2716
+
void daikin152(IRDaikin152 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool quiet, const bool turbo, const bool econo)
Send a Daikin 152-bit A/C message with the supplied settings.
Definition: IRac.cpp:553
+
fujitsu_ac_remote_model_t
Fujitsu A/C model numbers.
Definition: IRsend.h:120
+
Support for Gree A/C protocols.
+
Class for handling detailed Carrier 64 bit A/C messages.
Definition: ir_Carrier.h:74
+
Class for handling detailed Midea A/C messages.
Definition: ir_Midea.h:73
+
Class for handling detailed Kelvinator A/C messages.
Definition: ir_Kelvinator.h:137
+
bool _inverted
Definition: IRac.h:97
+
Class for handling detailed Fujitsu A/C messages.
Definition: ir_Fujitsu.h:101
+
Support for Mitsubishi Heavy Industry protocols. Code to emulate Mitsubishi Heavy Industries A/C IR r...
+
Class for handling detailed Coolix A/C messages.
Definition: ir_Coolix.h:105
+
void panasonic(IRPanasonicAc *ac, const panasonic_ac_remote_model_t model, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool filter, const int16_t clock=-1)
Send a Panasonic A/C message with the supplied settings.
Definition: IRac.cpp:1500
+
static String swingvToString(const stdAc::swingv_t swingv)
Convert the supplied enum into the appropriate String.
Definition: IRac.cpp:2663
+
Support for Mitsubishi protocols. Mitsubishi (TV) decoding added from https://github....
+
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 int16_t sleep=-1)
Send a Midea A/C message with the supplied settings.
Definition: IRac.cpp:1235
+
Definition: IRac.h:43
+
Support for Teco protocols.
+
void 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 bool turbo, const bool light, const bool clean, const int16_t sleep=-1)
Send a Gree A/C message with the supplied settings.
Definition: IRac.cpp:913
+
Delonghi A/C.
+
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 bool lighttoggle, const bool clean)
Send an Electra A/C message with the supplied settings.
Definition: IRac.cpp:766
+
static stdAc::state_t cleanState(const stdAc::state_t state)
Create a new state base on the provided state that has been suitably fixed.
Definition: IRac.cpp:1845
+
Support for Argo Ulisse 13 DCI Mobile Split ACs.
+
void mitsubishi(IRMitsubishiAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const int16_t clock=-1)
Send a Mitsubishi A/C message with the supplied settings.
Definition: IRac.cpp:1271
+
void amcor(IRAmcorAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan)
Send an Amcor A/C message with the supplied settings.
Definition: IRac.cpp:279
+
Class for handling detailed Daikin 152-bit A/C messages.
Definition: ir_Daikin.h:938
+
Class for handling detailed LG A/C messages.
Definition: ir_LG.h:63
+
Support for Fujitsu A/C protocols. Fujitsu A/C support added by Jonny Graham.
+
Class for handling detailed Haier A/C messages.
Definition: ir_Haier.h:217
+
Class for handling detailed Daikin 160-bit A/C messages.
Definition: ir_Daikin.h:754
+
static String opmodeToString(const stdAc::opmode_t mode)
Convert the supplied operation mode into the appropriate String.
Definition: IRac.cpp:2619
+
Class for handling detailed Sharp A/C messages.
Definition: ir_Sharp.h:108
+
Support for Goodweather compatible HVAC protocols.
+
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)
Send an Argo A/C message with the supplied settings.
Definition: IRac.cpp:311
+
lg_ac_remote_model_t
LG A/C model numbers.
Definition: IRsend.h:158
+
void mitsubishi136(IRMitsubishi136 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool quiet)
Send a Mitsubishi 136-bit A/C message with the supplied settings.
Definition: IRac.cpp:1342
+ +
bool _modulation
Definition: IRac.h:98
+
void teco(IRTecoAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool light, const int16_t sleep=-1)
Send a Teco A/C message with the supplied settings.
Definition: IRac.cpp:1676
+
static stdAc::opmode_t strToOpmode(const char *str, const stdAc::opmode_t def=stdAc::opmode_t::kAuto)
Convert the supplied str into the appropriate enum.
Definition: IRac.cpp:2397
+
void hitachi1(IRHitachiAc1 *ac, const hitachi_ac1_remote_model_t model, const bool on, const bool power_toggle, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool swing_toggle, const int16_t sleep=-1)
Send a Hitachi1 A/C message with the supplied settings.
Definition: IRac.cpp:1057
+ +
Support for Whirlpool protocols. Decoding help from: @redmusicxd, @josh929800, @raducostea.
+
static bool strToBool(const char *str, const bool def=false)
Convert the supplied str into the appropriate boolean value.
Definition: IRac.cpp:2594
+
void toshiba(IRToshibaAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan)
Send a Toshiba A/C message with the supplied settings.
Definition: IRac.cpp:1706
+
void mitsubishiHeavy88(IRMitsubishiHeavy88Ac *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 econo, const bool clean)
Send a Mitsubishi Heavy 88-bit A/C message with the supplied settings.
Definition: IRac.cpp:1377
+
static stdAc::swingv_t strToSwingV(const char *str, const stdAc::swingv_t def=stdAc::swingv_t::kOff)
Convert the supplied str into the appropriate enum.
Definition: IRac.cpp:2458
+
Class for handling detailed Vestel A/C messages.
Definition: ir_Vestel.h:116
+
void neoclima(IRNeoclimaAc *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 light, const bool filter, const int16_t sleep=-1)
Send a Neoclima A/C message with the supplied settings.
Definition: IRac.cpp:1460
+
Class for handling detailed Trotec A/C messages.
Definition: ir_Trotec.h:76
+
Class for handling detailed Teco A/C messages.
Definition: ir_Teco.h:107
+
static String swinghToString(const stdAc::swingh_t swingh)
Convert the supplied enum into the appropriate String.
Definition: IRac.cpp:2687
+
void delonghiac(IRDelonghiAc *ac, const bool on, const stdAc::opmode_t mode, const bool celsius, const float degrees, const stdAc::fanspeed_t fan, const bool turbo, const int16_t sleep=-1)
Send a Delonghi A/C message with the supplied settings.
Definition: IRac.cpp:739
+
stdAc::state_t _prev
Definition: IRac.h:99
+
Class for handling detailed Haier ACYRW02 A/C messages.
Definition: ir_Haier.h:289
+
void daikin160(IRDaikin160 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv)
Send a Daikin 160-bit A/C message with the supplied settings.
Definition: IRac.cpp:586
+
void corona(IRCoronaAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool econo)
Send a Corona A/C message with the supplied settings.
Definition: IRac.cpp:441
+
static void initState(stdAc::state_t *state, const decode_type_t vendor, const int16_t model, const bool power, const stdAc::opmode_t mode, const float degrees, const bool celsius, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool econo, const bool light, const bool filter, const bool clean, const bool beep, const int16_t sleep, const int16_t clock)
Initialse the given state with the supplied settings.
Definition: IRac.cpp:80
+
void mitsubishiHeavy152(IRMitsubishiHeavy152Ac *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool econo, const bool filter, const bool clean, const int16_t sleep=-1)
Send a Mitsubishi Heavy 152-bit A/C message with the supplied settings.
Definition: IRac.cpp:1418
+ +
Support for Haier A/C protocols. The specifics of reverse engineering the protocols details:
+
Class for handling detailed Mitsubishi Heavy 88-bit A/C messages.
Definition: ir_MitsubishiHeavy.h:220
+
Class for handling detailed Gree A/C messages.
Definition: ir_Gree.h:117
+
void coolix(IRCoolixAC *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 light, const bool clean, const int16_t sleep=-1)
Send a Coolix A/C message with the supplied settings.
Definition: IRac.cpp:380
+
static stdAc::fanspeed_t strToFanspeed(const char *str, const stdAc::fanspeed_t def=stdAc::fanspeed_t::kAuto)
Convert the supplied str into the appropriate enum.
Definition: IRac.cpp:2427
+
Support for Toshiba protocols.
+
void sharp(IRSharpAc *ac, const bool on, const bool prev_power, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool turbo, const bool filter, const bool clean)
Send a Sharp A/C message with the supplied settings.
Definition: IRac.cpp:1588
+
void goodweather(IRGoodweatherAc *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 bool light, const int16_t sleep=-1)
Send a Goodweather A/C message with the supplied settings.
Definition: IRac.cpp:871
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
Class for handling detailed Goodweather A/C messages.
Definition: ir_Goodweather.h:90
+
Support for Vestel protocols. Vestel added by Erdem U. Altinyurt.
+ +
Class for handling detailed Argo A/C messages.
Definition: ir_Argo.h:129
+
void fujitsu(IRFujitsuAC *ac, const fujitsu_ac_remote_model_t model, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool econo, const bool filter, const bool clean)
Send a Fujitsu A/C message with the supplied settings.
Definition: IRac.cpp:808
+
Class for handling detailed Neoclima A/C messages.
Definition: ir_Neoclima.h:86
+
static bool isProtocolSupported(const decode_type_t protocol)
Is the given protocol supported by the IRac class?
Definition: IRac.cpp:133
+
Class for handling detailed Daikin 176-bit A/C messages.
Definition: ir_Daikin.h:806
+
Amcor A/C protocol.
+
uint16_t _pin
Definition: IRac.h:96
+
Support for LG protocols.
+
void carrier64(IRCarrierAc64 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const int16_t sleep=-1)
Send a Carrier 64-bit A/C message with the supplied settings.
Definition: IRac.cpp:343
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRrecv_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRrecv_8cpp.html new file mode 100644 index 000000000..405dbd5b5 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRrecv_8cpp.html @@ -0,0 +1,135 @@ + + + + + + + +IRremoteESP8266: src/IRrecv.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
IRrecv.cpp File Reference
+
+
+ + + + + + + + +

+Variables

portMUX_TYPE irremote_mux = portMUX_INITIALIZER_UNLOCKED
 
volatile irparams_t irparams
 
irparams_tirparams_save
 
+

Variable Documentation

+ +

◆ irparams

+ +
+
+ + + + +
volatile irparams_t irparams
+
+ +
+
+ +

◆ irparams_save

+ +
+
+ + + + +
irparams_t* irparams_save
+
+ +
+
+ +

◆ irremote_mux

+ +
+
+ + + + +
portMUX_TYPE irremote_mux = portMUX_INITIALIZER_UNLOCKED
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRrecv_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRrecv_8h.html new file mode 100644 index 000000000..726b05484 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRrecv_8h.html @@ -0,0 +1,425 @@ + + + + + + + +IRremoteESP8266: src/IRrecv.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
IRrecv.h File Reference
+
+
+ +

Go to the source code of this file.

+ + + + + + + + + + + + + + +

+Classes

struct  irparams_t
 Information for the interrupt handler. More...
 
struct  match_result_t
 Results from a data match. More...
 
class  decode_results
 Results returned from the decoder. More...
 
class  IRrecv
 Class for receiving IR messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kHeader = 2
 
const uint16_t kFooter = 2
 
const uint16_t kStartOffset = 1
 
const uint16_t kMarkExcess = 50
 
const uint16_t kRawBuf = 100
 
const uint64_t kRepeat = UINT64_MAX
 
const uint16_t kUnknownThreshold = 6
 
const uint8_t kIdleState = 2
 
const uint8_t kMarkState = 3
 
const uint8_t kSpaceState = 4
 
const uint8_t kStopState = 5
 
const uint8_t kTolerance = 25
 
const uint8_t kUseDefTol = 255
 
const uint16_t kRawTick = 2
 
const uint8_t kTimeoutMs = 15
 
const uint16_t kMaxTimeoutMs = kRawTick * (UINT16_MAX / MS_TO_USEC(1))
 
const uint32_t kFnvPrime32 = 16777619UL
 
const uint32_t kFnvBasis32 = 2166136261UL
 
const uint8_t kDefaultESP32Timer = 3
 
const uint16_t kStateSizeMax = kHitachiAc2StateLength
 
+

Variable Documentation

+ +

◆ kDefaultESP32Timer

+ +
+
+ + + + +
const uint8_t kDefaultESP32Timer = 3
+
+ +
+
+ +

◆ kFnvBasis32

+ +
+
+ + + + +
const uint32_t kFnvBasis32 = 2166136261UL
+
+ +
+
+ +

◆ kFnvPrime32

+ +
+
+ + + + +
const uint32_t kFnvPrime32 = 16777619UL
+
+ +
+
+ +

◆ kFooter

+ +
+
+ + + + +
const uint16_t kFooter = 2
+
+ +
+
+ +

◆ kHeader

+ +
+
+ + + + +
const uint16_t kHeader = 2
+
+ +
+
+ +

◆ kIdleState

+ +
+
+ + + + +
const uint8_t kIdleState = 2
+
+ +
+
+ +

◆ kMarkExcess

+ +
+
+ + + + +
const uint16_t kMarkExcess = 50
+
+ +
+
+ +

◆ kMarkState

+ +
+
+ + + + +
const uint8_t kMarkState = 3
+
+ +
+
+ +

◆ kMaxTimeoutMs

+ +
+
+ + + + +
const uint16_t kMaxTimeoutMs = kRawTick * (UINT16_MAX / MS_TO_USEC(1))
+
+ +
+
+ +

◆ kRawBuf

+ +
+
+ + + + +
const uint16_t kRawBuf = 100
+
+ +
+
+ +

◆ kRawTick

+ +
+
+ + + + +
const uint16_t kRawTick = 2
+
+ +
+
+ +

◆ kRepeat

+ +
+
+ + + + +
const uint64_t kRepeat = UINT64_MAX
+
+ +
+
+ +

◆ kSpaceState

+ +
+
+ + + + +
const uint8_t kSpaceState = 4
+
+ +
+
+ +

◆ kStartOffset

+ +
+
+ + + + +
const uint16_t kStartOffset = 1
+
+ +
+
+ +

◆ kStateSizeMax

+ +
+
+ + + + +
const uint16_t kStateSizeMax = kHitachiAc2StateLength
+
+ +
+
+ +

◆ kStopState

+ +
+
+ + + + +
const uint8_t kStopState = 5
+
+ +
+
+ +

◆ kTimeoutMs

+ +
+
+ + + + +
const uint8_t kTimeoutMs = 15
+
+ +
+
+ +

◆ kTolerance

+ +
+
+ + + + +
const uint8_t kTolerance = 25
+
+ +
+
+ +

◆ kUnknownThreshold

+ +
+
+ + + + +
const uint16_t kUnknownThreshold = 6
+
+ +
+
+ +

◆ kUseDefTol

+ +
+
+ + + + +
const uint8_t kUseDefTol = 255
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRrecv_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRrecv_8h_source.html new file mode 100644 index 000000000..65256af77 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRrecv_8h_source.html @@ -0,0 +1,972 @@ + + + + + + + +IRremoteESP8266: src/IRrecv.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
IRrecv.h
+
+
+Go to the documentation of this file.
1 // Copyright 2009 Ken Shirriff
+
2 // Copyright 2015 Mark Szabo
+
3 // Copyright 2015 Sebastien Warin
+
4 // Copyright 2017 David Conran
+
5 
+
6 #ifndef IRRECV_H_
+
7 #define IRRECV_H_
+
8 
+
9 #ifndef UNIT_TEST
+
10 #include <Arduino.h>
+
11 #endif
+
12 #include <stddef.h>
+
13 #define __STDC_LIMIT_MACROS
+
14 #include <stdint.h>
+
15 #include "IRremoteESP8266.h"
+
16 
+
17 // Constants
+
18 const uint16_t kHeader = 2; // Usual nr. of header entries.
+
19 const uint16_t kFooter = 2; // Usual nr. of footer (stop bits) entries.
+
20 const uint16_t kStartOffset = 1; // Usual rawbuf entry to start from.
+
21 #define MS_TO_USEC(x) (x * 1000U) // Convert milli-Seconds to micro-Seconds.
+
22 // Marks tend to be 100us too long, and spaces 100us too short
+
23 // when received due to sensor lag.
+
24 const uint16_t kMarkExcess = 50;
+
25 const uint16_t kRawBuf = 100; // Default length of raw capture buffer
+
26 const uint64_t kRepeat = UINT64_MAX;
+
27 // Default min size of reported UNKNOWN messages.
+
28 const uint16_t kUnknownThreshold = 6;
+
29 
+
30 // receiver states
+
31 const uint8_t kIdleState = 2;
+
32 const uint8_t kMarkState = 3;
+
33 const uint8_t kSpaceState = 4;
+
34 const uint8_t kStopState = 5;
+
35 const uint8_t kTolerance = 25; // default percent tolerance in measurements.
+
36 const uint8_t kUseDefTol = 255; // Indicate to use the class default tolerance.
+
37 const uint16_t kRawTick = 2; // Capture tick to uSec factor.
+
38 #define RAWTICK kRawTick // Deprecated. For legacy user code support only.
+
39 // How long (ms) before we give up wait for more data?
+
40 // Don't exceed kMaxTimeoutMs without a good reason.
+
41 // That is the capture buffers maximum value size. (UINT16_MAX / kRawTick)
+
42 // Typically messages/protocols tend to repeat around the 100ms timeframe,
+
43 // thus we should timeout before that to give us some time to try to decode
+
44 // before we need to start capturing a possible new message.
+
45 // Typically 15ms suits most applications. However, some protocols demand a
+
46 // higher value. e.g. 90ms for XMP-1 and some aircon units.
+
47 const uint8_t kTimeoutMs = 15; // In MilliSeconds.
+
48 #define TIMEOUT_MS kTimeoutMs // For legacy documentation.
+
49 const uint16_t kMaxTimeoutMs = kRawTick * (UINT16_MAX / MS_TO_USEC(1));
+
50 
+
51 // Use FNV hash algorithm: http://isthe.com/chongo/tech/comp/fnv/#FNV-param
+
52 const uint32_t kFnvPrime32 = 16777619UL;
+
53 const uint32_t kFnvBasis32 = 2166136261UL;
+
54 
+
55 // Which of the ESP32 timers to use by default. (0-3)
+
56 const uint8_t kDefaultESP32Timer = 3;
+
57 
+
58 #if DECODE_AC
+
59 // Hitachi AC is the current largest state size.
+ +
61 #else
+
62 // Just define something
+
63 const uint16_t kStateSizeMax = 0;
+
64 #endif
+
65 
+
66 // Types
+
67 
+
69 typedef struct {
+
70  uint8_t recvpin; // pin for IR data from detector
+
71  uint8_t rcvstate; // state machine
+
72  uint16_t timer; // state timer, counts 50uS ticks.
+
73  uint16_t bufsize; // max. nr. of entries in the capture buffer.
+
74  uint16_t *rawbuf; // raw data
+
75  // uint16_t is used for rawlen as it saves 3 bytes of iram in the interrupt
+
76  // handler. Don't ask why, I don't know. It just does.
+
77  uint16_t rawlen; // counter of entries in rawbuf.
+
78  uint8_t overflow; // Buffer overflow indicator.
+
79  uint8_t timeout; // Nr. of milliSeconds before we give up.
+
80 } irparams_t;
+
81 
+
83 typedef struct {
+
84  bool success; // Was the match successful?
+
85  uint64_t data; // The data found.
+
86  uint16_t used; // How many buffer positions were used.
+ +
88 
+
89 // Classes
+
90 
+ +
93  public:
+
94  decode_type_t decode_type; // NEC, SONY, RC5, UNKNOWN
+
95  // value, address, & command are all mutually exclusive with state.
+
96  // i.e. They MUST NOT be used at the same time as state, so we can use a union
+
97  // structure to save us a handful of valuable bytes of memory.
+
98  union {
+
99  struct {
+
100  uint64_t value; // Decoded value
+
101  uint32_t address; // Decoded device address.
+
102  uint32_t command; // Decoded command.
+
103  };
+
104  uint8_t state[kStateSizeMax]; // Multi-byte results.
+
105  };
+
106  uint16_t bits; // Number of bits in decoded value
+
107  volatile uint16_t *rawbuf; // Raw intervals in .5 us ticks
+
108  uint16_t rawlen; // Number of records in rawbuf.
+
109  bool overflow;
+
110  bool repeat; // Is the result a repeat code?
+
111 };
+
112 
+
114 class IRrecv {
+
115  public:
+
116 #if defined(ESP32)
+
117  explicit IRrecv(const uint16_t recvpin, const uint16_t bufsize = kRawBuf,
+
118  const uint8_t timeout = kTimeoutMs,
+
119  const bool save_buffer = false,
+
120  const uint8_t timer_num = kDefaultESP32Timer); // Constructor
+
121 #else // ESP32
+
122  explicit IRrecv(const uint16_t recvpin, const uint16_t bufsize = kRawBuf,
+
123  const uint8_t timeout = kTimeoutMs,
+
124  const bool save_buffer = false); // Constructor
+
125 #endif // ESP32
+
126  ~IRrecv(void); // Destructor
+
127  void setTolerance(const uint8_t percent = kTolerance);
+
128  uint8_t getTolerance(void);
+
129  bool decode(decode_results *results, irparams_t *save = NULL,
+
130  uint8_t max_skip = 0, uint16_t noise_floor = 0);
+
131  void enableIRIn(const bool pullup = false);
+
132  void disableIRIn(void);
+
133  void resume(void);
+
134  uint16_t getBufSize(void);
+
135 #if DECODE_HASH
+
136  void setUnknownThreshold(const uint16_t length);
+
137 #endif
+
138  bool match(const uint32_t measured, const uint32_t desired,
+
139  const uint8_t tolerance = kUseDefTol,
+
140  const uint16_t delta = 0);
+
141  bool matchMark(const uint32_t measured, const uint32_t desired,
+
142  const uint8_t tolerance = kUseDefTol,
+
143  const int16_t excess = kMarkExcess);
+
144  bool matchSpace(const uint32_t measured, const uint32_t desired,
+
145  const uint8_t tolerance = kUseDefTol,
+
146  const int16_t excess = kMarkExcess);
+
147 #ifndef UNIT_TEST
+
148 
+
149  private:
+
150 #endif
+ +
152  uint8_t _tolerance;
+
153 #if defined(ESP32)
+
154  uint8_t _timer_num;
+
155 #endif // defined(ESP32)
+
156 #if DECODE_HASH
+ +
158 #endif
+
159  // These are called by decode
+
160  uint8_t _validTolerance(const uint8_t percentage);
+
161  void copyIrParams(volatile irparams_t *src, irparams_t *dst);
+
162  uint16_t compare(const uint16_t oldval, const uint16_t newval);
+
163  uint32_t ticksLow(const uint32_t usecs,
+
164  const uint8_t tolerance = kUseDefTol,
+
165  const uint16_t delta = 0);
+
166  uint32_t ticksHigh(const uint32_t usecs,
+
167  const uint8_t tolerance = kUseDefTol,
+
168  const uint16_t delta = 0);
+
169  bool matchAtLeast(const uint32_t measured, const uint32_t desired,
+
170  const uint8_t tolerance = kUseDefTol,
+
171  const uint16_t delta = 0);
+
172  uint16_t _matchGeneric(volatile uint16_t *data_ptr,
+
173  uint64_t *result_bits_ptr,
+
174  uint8_t *result_ptr,
+
175  const bool use_bits,
+
176  const uint16_t remaining,
+
177  const uint16_t required,
+
178  const uint16_t hdrmark,
+
179  const uint32_t hdrspace,
+
180  const uint16_t onemark,
+
181  const uint32_t onespace,
+
182  const uint16_t zeromark,
+
183  const uint32_t zerospace,
+
184  const uint16_t footermark,
+
185  const uint32_t footerspace,
+
186  const bool atleast = false,
+
187  const uint8_t tolerance = kUseDefTol,
+
188  const int16_t excess = kMarkExcess,
+
189  const bool MSBfirst = true);
+
190  match_result_t matchData(volatile uint16_t *data_ptr, const uint16_t nbits,
+
191  const uint16_t onemark, const uint32_t onespace,
+
192  const uint16_t zeromark, const uint32_t zerospace,
+
193  const uint8_t tolerance = kUseDefTol,
+
194  const int16_t excess = kMarkExcess,
+
195  const bool MSBfirst = true);
+
196  uint16_t matchBytes(volatile uint16_t *data_ptr, uint8_t *result_ptr,
+
197  const uint16_t remaining, const uint16_t nbytes,
+
198  const uint16_t onemark, const uint32_t onespace,
+
199  const uint16_t zeromark, const uint32_t zerospace,
+
200  const uint8_t tolerance = kUseDefTol,
+
201  const int16_t excess = kMarkExcess,
+
202  const bool MSBfirst = true);
+
203  uint16_t matchGeneric(volatile uint16_t *data_ptr,
+
204  uint64_t *result_ptr,
+
205  const uint16_t remaining, const uint16_t nbits,
+
206  const uint16_t hdrmark, const uint32_t hdrspace,
+
207  const uint16_t onemark, const uint32_t onespace,
+
208  const uint16_t zeromark, const uint32_t zerospace,
+
209  const uint16_t footermark, const uint32_t footerspace,
+
210  const bool atleast = false,
+
211  const uint8_t tolerance = kUseDefTol,
+
212  const int16_t excess = kMarkExcess,
+
213  const bool MSBfirst = true);
+
214  uint16_t matchGeneric(volatile uint16_t *data_ptr, uint8_t *result_ptr,
+
215  const uint16_t remaining, const uint16_t nbits,
+
216  const uint16_t hdrmark, const uint32_t hdrspace,
+
217  const uint16_t onemark, const uint32_t onespace,
+
218  const uint16_t zeromark, const uint32_t zerospace,
+
219  const uint16_t footermark,
+
220  const uint32_t footerspace,
+
221  const bool atleast = false,
+
222  const uint8_t tolerance = kUseDefTol,
+
223  const int16_t excess = kMarkExcess,
+
224  const bool MSBfirst = true);
+
225  uint16_t matchGenericConstBitTime(volatile uint16_t *data_ptr,
+
226  uint64_t *result_ptr,
+
227  const uint16_t remaining,
+
228  const uint16_t nbits,
+
229  const uint16_t hdrmark,
+
230  const uint32_t hdrspace,
+
231  const uint16_t one,
+
232  const uint32_t zero,
+
233  const uint16_t footermark,
+
234  const uint32_t footerspace,
+
235  const bool atleast = false,
+
236  const uint8_t tolerance = kUseDefTol,
+
237  const int16_t excess = kMarkExcess,
+
238  const bool MSBfirst = true);
+
239  uint16_t matchManchesterData(volatile const uint16_t *data_ptr,
+
240  uint64_t *result_ptr,
+
241  const uint16_t remaining,
+
242  const uint16_t nbits,
+
243  const uint16_t half_period,
+
244  const uint16_t starting_balance = 0,
+
245  const uint8_t tolerance = kUseDefTol,
+
246  const int16_t excess = kMarkExcess,
+
247  const bool MSBfirst = true,
+
248  const bool GEThomas = true);
+
249  uint16_t matchManchester(volatile const uint16_t *data_ptr,
+
250  uint64_t *result_ptr,
+
251  const uint16_t remaining,
+
252  const uint16_t nbits,
+
253  const uint16_t hdrmark,
+
254  const uint32_t hdrspace,
+
255  const uint16_t clock_period,
+
256  const uint16_t footermark,
+
257  const uint32_t footerspace,
+
258  const bool atleast = false,
+
259  const uint8_t tolerance = kUseDefTol,
+
260  const int16_t excess = kMarkExcess,
+
261  const bool MSBfirst = true,
+
262  const bool GEThomas = true);
+
263  void crudeNoiseFilter(decode_results *results, const uint16_t floor = 0);
+
264  bool decodeHash(decode_results *results);
+
265 #if (DECODE_NEC || DECODE_SHERWOOD || DECODE_AIWA_RC_T501 || DECODE_SANYO)
+
266  bool decodeNEC(decode_results *results, uint16_t offset = kStartOffset,
+
267  const uint16_t nbits = kNECBits, const bool strict = true);
+
268 #endif
+
269 #if DECODE_ARGO
+
270  bool decodeArgo(decode_results *results, uint16_t offset = kStartOffset,
+
271  const uint16_t nbits = kArgoBits, const bool strict = true);
+
272 #endif // DECODE_ARGO
+
273 #if DECODE_SONY
+
274  bool decodeSony(decode_results *results, uint16_t offset = kStartOffset,
+
275  const uint16_t nbits = kSonyMinBits,
+
276  const bool strict = false);
+
277 #endif
+
278 #if DECODE_SANYO
+
279  // DISABLED due to poor quality.
+
280  // bool decodeSanyo(decode_results *results, uint16_t offset = kStartOffset,
+
281  // uint16_t nbits = kSanyoSA8650BBits,
+
282  // bool strict = false);
+
283  bool decodeSanyoLC7461(decode_results *results,
+
284  uint16_t offset = kStartOffset,
+
285  const uint16_t nbits = kSanyoLC7461Bits,
+
286  bool strict = true);
+
287 #endif
+
288 #if DECODE_MITSUBISHI
+
289  bool decodeMitsubishi(decode_results *results, uint16_t offset = kStartOffset,
+
290  const uint16_t nbits = kMitsubishiBits,
+
291  const bool strict = true);
+
292 #endif
+
293 #if DECODE_MITSUBISHI2
+
294  bool decodeMitsubishi2(decode_results *results,
+
295  uint16_t offset = kStartOffset,
+
296  const uint16_t nbits = kMitsubishiBits,
+
297  const bool strict = true);
+
298 #endif
+
299 #if DECODE_MITSUBISHI_AC
+
300  bool decodeMitsubishiAC(decode_results *results,
+
301  uint16_t offset = kStartOffset,
+
302  const uint16_t nbits = kMitsubishiACBits,
+
303  const bool strict = false);
+
304 #endif
+
305 #if DECODE_MITSUBISHI136
+
306  bool decodeMitsubishi136(decode_results *results,
+
307  uint16_t offset = kStartOffset,
+
308  const uint16_t nbits = kMitsubishi136Bits,
+
309  const bool strict = true);
+
310 #endif
+
311 #if DECODE_MITSUBISHI112
+
312  bool decodeMitsubishi112(decode_results *results,
+
313  uint16_t offset = kStartOffset,
+
314  const uint16_t nbits = kMitsubishi112Bits,
+
315  const bool strict = true);
+
316 #endif
+
317 #if DECODE_MITSUBISHIHEAVY
+ +
319  uint16_t offset = kStartOffset,
+
320  const uint16_t nbits = kMitsubishiHeavy152Bits,
+
321  const bool strict = true);
+
322 #endif
+
323 #if (DECODE_RC5 || DECODE_R6 || DECODE_LASERTAG || DECODE_MWM)
+
324  int16_t getRClevel(decode_results *results, uint16_t *offset, uint16_t *used,
+
325  uint16_t bitTime, const uint8_t tolerance = kUseDefTol,
+
326  const int16_t excess = kMarkExcess,
+
327  const uint16_t delta = 0, const uint8_t maxwidth = 3);
+
328 #endif
+
329 #if DECODE_RC5
+
330  bool decodeRC5(decode_results *results, uint16_t offset = kStartOffset,
+
331  const uint16_t nbits = kRC5XBits,
+
332  const bool strict = true);
+
333 #endif
+
334 #if DECODE_RC6
+
335  bool decodeRC6(decode_results *results, uint16_t offset = kStartOffset,
+
336  const uint16_t nbits = kRC6Mode0Bits,
+
337  const bool strict = false);
+
338 #endif
+
339 #if DECODE_RCMM
+
340  bool decodeRCMM(decode_results *results, uint16_t offset = kStartOffset,
+
341  const uint16_t nbits = kRCMMBits,
+
342  const bool strict = false);
+
343 #endif
+
344 #if (DECODE_PANASONIC || DECODE_DENON)
+
345  bool decodePanasonic(decode_results *results, uint16_t offset = kStartOffset,
+
346  const uint16_t nbits = kPanasonicBits,
+
347  const bool strict = false,
+
348  const uint32_t manufacturer = kPanasonicManufacturer);
+
349 #endif
+
350 #if DECODE_LG
+
351  bool decodeLG(decode_results *results, uint16_t offset = kStartOffset,
+
352  const uint16_t nbits = kLgBits,
+
353  const bool strict = false);
+
354 #endif
+
355 #if DECODE_INAX
+
356  bool decodeInax(decode_results *results, uint16_t offset = kStartOffset,
+
357  const uint16_t nbits = kInaxBits,
+
358  const bool strict = true);
+
359 #endif // DECODE_INAX
+
360 #if DECODE_JVC
+
361  bool decodeJVC(decode_results *results, uint16_t offset = kStartOffset,
+
362  const uint16_t nbits = kJvcBits,
+
363  const bool strict = true);
+
364 #endif
+
365 #if DECODE_SAMSUNG
+
366  bool decodeSAMSUNG(decode_results *results, uint16_t offset = kStartOffset,
+
367  const uint16_t nbits = kSamsungBits,
+
368  const bool strict = true);
+
369 #endif
+
370 #if DECODE_SAMSUNG
+
371  bool decodeSamsung36(decode_results *results, uint16_t offset = kStartOffset,
+
372  const uint16_t nbits = kSamsung36Bits,
+
373  const bool strict = true);
+
374 #endif
+
375 #if DECODE_SAMSUNG_AC
+
376  bool decodeSamsungAC(decode_results *results, uint16_t offset = kStartOffset,
+
377  const uint16_t nbits = kSamsungAcBits,
+
378  const bool strict = true);
+
379 #endif
+
380 #if DECODE_WHYNTER
+
381  bool decodeWhynter(decode_results *results, uint16_t offset = kStartOffset,
+
382  const uint16_t nbits = kWhynterBits,
+
383  const bool strict = true);
+
384 #endif
+
385 #if DECODE_COOLIX
+
386  bool decodeCOOLIX(decode_results *results, uint16_t offset = kStartOffset,
+
387  const uint16_t nbits = kCoolixBits,
+
388  const bool strict = true);
+
389 #endif
+
390 #if DECODE_DENON
+
391  bool decodeDenon(decode_results *results, uint16_t offset = kStartOffset,
+
392  const uint16_t nbits = kDenonBits,
+
393  const bool strict = true);
+
394 #endif
+
395 #if DECODE_DISH
+
396  bool decodeDISH(decode_results *results, uint16_t offset = kStartOffset,
+
397  const uint16_t nbits = kDishBits,
+
398  const bool strict = true);
+
399 #endif
+
400 #if (DECODE_SHARP || DECODE_DENON)
+
401  bool decodeSharp(decode_results *results, uint16_t offset = kStartOffset,
+
402  const uint16_t nbits = kSharpBits,
+
403  const bool strict = true, const bool expansion = true);
+
404 #endif
+
405 #if DECODE_SHARP_AC
+
406  bool decodeSharpAc(decode_results *results, uint16_t offset = kStartOffset,
+
407  const uint16_t nbits = kSharpAcBits,
+
408  const bool strict = true);
+
409 #endif
+
410 #if DECODE_AIWA_RC_T501
+
411  bool decodeAiwaRCT501(decode_results *results, uint16_t offset = kStartOffset,
+
412  const uint16_t nbits = kAiwaRcT501Bits,
+
413  const bool strict = true);
+
414 #endif
+
415 #if DECODE_NIKAI
+
416  bool decodeNikai(decode_results *results, uint16_t offset = kStartOffset,
+
417  const uint16_t nbits = kNikaiBits,
+
418  const bool strict = true);
+
419 #endif
+
420 #if DECODE_MAGIQUEST
+
421  bool decodeMagiQuest(decode_results *results, uint16_t offset = kStartOffset,
+
422  const uint16_t nbits = kMagiquestBits,
+
423  const bool strict = true);
+
424 #endif
+
425 #if DECODE_KELVINATOR
+
426  bool decodeKelvinator(decode_results *results, uint16_t offset = kStartOffset,
+
427  const uint16_t nbits = kKelvinatorBits,
+
428  const bool strict = true);
+
429 #endif
+
430 #if DECODE_DAIKIN
+
431  bool decodeDaikin(decode_results *results, uint16_t offset = kStartOffset,
+
432  const uint16_t nbits = kDaikinBits,
+
433  const bool strict = true);
+
434 #endif
+
435 #if DECODE_DAIKIN64
+
436  bool decodeDaikin64(decode_results *results, uint16_t offset = kStartOffset,
+
437  const uint16_t nbits = kDaikin64Bits,
+
438  const bool strict = true);
+
439 #endif // DECODE_DAIKIN64
+
440 #if DECODE_DAIKIN128
+
441  bool decodeDaikin128(decode_results *results, uint16_t offset = kStartOffset,
+
442  const uint16_t nbits = kDaikin128Bits,
+
443  const bool strict = true);
+
444 #endif // DECODE_DAIKIN128
+
445 #if DECODE_DAIKIN152
+
446  bool decodeDaikin152(decode_results *results, uint16_t offset = kStartOffset,
+
447  const uint16_t nbits = kDaikin152Bits,
+
448  const bool strict = true);
+
449 #endif // DECODE_DAIKIN152
+
450 #if DECODE_DAIKIN160
+
451  bool decodeDaikin160(decode_results *results, uint16_t offset = kStartOffset,
+
452  const uint16_t nbits = kDaikin160Bits,
+
453  const bool strict = true);
+
454 #endif // DECODE_DAIKIN160
+
455 #if DECODE_DAIKIN176
+
456  bool decodeDaikin176(decode_results *results, uint16_t offset = kStartOffset,
+
457  const uint16_t nbits = kDaikin176Bits,
+
458  const bool strict = true);
+
459 #endif // DECODE_DAIKIN176
+
460 #if DECODE_DAIKIN2
+
461  bool decodeDaikin2(decode_results *results, uint16_t offset = kStartOffset,
+
462  const uint16_t nbits = kDaikin2Bits,
+
463  const bool strict = true);
+
464 #endif
+
465 #if DECODE_DAIKIN216
+
466  bool decodeDaikin216(decode_results *results, uint16_t offset = kStartOffset,
+
467  const uint16_t nbits = kDaikin216Bits,
+
468  const bool strict = true);
+
469 #endif
+
470 #if DECODE_TOSHIBA_AC
+
471  bool decodeToshibaAC(decode_results *results, uint16_t offset = kStartOffset,
+
472  const uint16_t nbytes = kToshibaACBits,
+
473  const bool strict = true);
+
474 #endif
+
475 #if DECODE_TROTEC
+
476  bool decodeTrotec(decode_results *results, uint16_t offset = kStartOffset,
+
477  const uint16_t nbits = kTrotecBits,
+
478  const bool strict = true);
+
479 #endif // DECODE_TROTEC
+
480 #if DECODE_MIDEA
+
481  bool decodeMidea(decode_results *results, uint16_t offset = kStartOffset,
+
482  const uint16_t nbits = kMideaBits,
+
483  const bool strict = true);
+
484 #endif // DECODE_MIDEA
+
485 #if DECODE_MIDEA24
+
486  bool decodeMidea24(decode_results *results, uint16_t offset = kStartOffset,
+
487  const uint16_t nbits = kMidea24Bits,
+
488  const bool strict = true);
+
489 #endif // DECODE_MIDEA24
+
490 #if DECODE_FUJITSU_AC
+
491  bool decodeFujitsuAC(decode_results *results, uint16_t offset = kStartOffset,
+
492  const uint16_t nbits = kFujitsuAcBits,
+
493  const bool strict = false);
+
494 #endif
+
495 #if DECODE_LASERTAG
+
496  bool decodeLasertag(decode_results *results, uint16_t offset = kStartOffset,
+
497  const uint16_t nbits = kLasertagBits,
+
498  const bool strict = true);
+
499 #endif
+
500 #if DECODE_CARRIER_AC
+
501  bool decodeCarrierAC(decode_results *results, uint16_t offset = kStartOffset,
+
502  const uint16_t nbits = kCarrierAcBits,
+
503  const bool strict = true);
+
504 #endif // DECODE_CARRIER_AC
+
505 #if DECODE_CARRIER_AC40
+
506  bool decodeCarrierAC40(decode_results *results,
+
507  uint16_t offset = kStartOffset,
+
508  const uint16_t nbits = kCarrierAc40Bits,
+
509  const bool strict = true);
+
510 #endif // DECODE_CARRIER_AC40
+
511 #if DECODE_CARRIER_AC64
+
512  bool decodeCarrierAC64(decode_results *results,
+
513  uint16_t offset = kStartOffset,
+
514  const uint16_t nbits = kCarrierAc64Bits,
+
515  const bool strict = true);
+
516 #endif // DECODE_CARRIER_AC64
+
517 #if DECODE_GOODWEATHER
+
518  bool decodeGoodweather(decode_results *results,
+
519  uint16_t offset = kStartOffset,
+
520  const uint16_t nbits = kGoodweatherBits,
+
521  const bool strict = true);
+
522 #endif // DECODE_GOODWEATHER
+
523 #if DECODE_GREE
+
524  bool decodeGree(decode_results *results, uint16_t offset = kStartOffset,
+
525  const uint16_t nbits = kGreeBits,
+
526  const bool strict = true);
+
527 #endif
+
528 #if (DECODE_HAIER_AC | DECODE_HAIER_AC_YRW02)
+
529  bool decodeHaierAC(decode_results *results, uint16_t offset = kStartOffset,
+
530  const uint16_t nbits = kHaierACBits,
+
531  const bool strict = true);
+
532 #endif
+
533 #if DECODE_HAIER_AC_YRW02
+
534  bool decodeHaierACYRW02(decode_results *results,
+
535  uint16_t offset = kStartOffset,
+
536  const uint16_t nbits = kHaierACYRW02Bits,
+
537  const bool strict = true);
+
538 #endif
+
539 #if (DECODE_HITACHI_AC || DECODE_HITACHI_AC2 || DECODE_HITACHI_AC344)
+
540  bool decodeHitachiAC(decode_results *results, uint16_t offset = kStartOffset,
+
541  const uint16_t nbits = kHitachiAcBits,
+
542  const bool strict = true, const bool MSBfirst = true);
+
543 #endif
+
544 #if DECODE_HITACHI_AC1
+
545  bool decodeHitachiAC1(decode_results *results, uint16_t offset = kStartOffset,
+
546  const uint16_t nbits = kHitachiAc1Bits,
+
547  const bool strict = true);
+
548 #endif
+
549 #if DECODE_HITACHI_AC3
+
550  bool decodeHitachiAc3(decode_results *results,
+
551  uint16_t offset = kStartOffset,
+
552  const uint16_t nbits = kHitachiAc3Bits,
+
553  const bool strict = true);
+
554 #endif // DECODE_HITACHI_AC3
+
555 #if DECODE_HITACHI_AC424
+
556  bool decodeHitachiAc424(decode_results *results,
+
557  uint16_t offset = kStartOffset,
+
558  const uint16_t nbits = kHitachiAc424Bits,
+
559  const bool strict = true);
+
560 #endif // DECODE_HITACHI_AC424
+
561 #if DECODE_GICABLE
+
562  bool decodeGICable(decode_results *results, uint16_t offset = kStartOffset,
+
563  const uint16_t nbits = kGicableBits,
+
564  const bool strict = true);
+
565 #endif
+
566 #if DECODE_WHIRLPOOL_AC
+
567  bool decodeWhirlpoolAC(decode_results *results,
+
568  uint16_t offset = kStartOffset,
+
569  const uint16_t nbits = kWhirlpoolAcBits,
+
570  const bool strict = true);
+
571 #endif
+
572 #if DECODE_LUTRON
+
573  bool decodeLutron(decode_results *results, uint16_t offset = kStartOffset,
+
574  const uint16_t nbits = kLutronBits,
+
575  const bool strict = true);
+
576 #endif
+
577 #if DECODE_ELECTRA_AC
+
578  bool decodeElectraAC(decode_results *results, uint16_t offset = kStartOffset,
+
579  const uint16_t nbits = kElectraAcBits,
+
580  const bool strict = true);
+
581 #endif
+
582 #if DECODE_PANASONIC_AC
+
583  bool decodePanasonicAC(decode_results *results,
+
584  uint16_t offset = kStartOffset,
+
585  const uint16_t nbits = kPanasonicAcBits,
+
586  const bool strict = true);
+
587 #endif
+
588 #if DECODE_PIONEER
+
589  bool decodePioneer(decode_results *results, uint16_t offset = kStartOffset,
+
590  const uint16_t nbits = kPioneerBits,
+
591  const bool strict = true);
+
592 #endif
+
593 #if DECODE_MWM
+
594  bool decodeMWM(decode_results *results, uint16_t offset = kStartOffset,
+
595  const uint16_t nbits = 24,
+
596  const bool strict = true);
+
597 #endif
+
598 #if DECODE_VESTEL_AC
+
599  bool decodeVestelAc(decode_results *results, uint16_t offset = kStartOffset,
+
600  const uint16_t nbits = kVestelAcBits,
+
601  const bool strict = true);
+
602 #endif
+
603 #if DECODE_TECO
+
604  bool decodeTeco(decode_results *results, uint16_t offset = kStartOffset,
+
605  const uint16_t nbits = kTecoBits,
+
606  const bool strict = false);
+
607 #endif
+
608 #if DECODE_LEGOPF
+
609  bool decodeLegoPf(decode_results *results, uint16_t offset = kStartOffset,
+
610  const uint16_t nbits = kLegoPfBits,
+
611  const bool strict = true);
+
612 #endif
+
613 #if DECODE_NEOCLIMA
+
614  bool decodeNeoclima(decode_results *results, uint16_t offset = kStartOffset,
+
615  const uint16_t nbits = kNeoclimaBits,
+
616  const bool strict = true);
+
617 #endif // DECODE_NEOCLIMA
+
618 #if DECODE_AMCOR
+
619  bool decodeAmcor(decode_results *results, uint16_t offset = kStartOffset,
+
620  const uint16_t nbits = kAmcorBits,
+
621  const bool strict = true);
+
622 #endif // DECODE_AMCOR
+
623 #if DECODE_EPSON
+
624  bool decodeEpson(decode_results *results, uint16_t offset = kStartOffset,
+
625  const uint16_t nbits = kEpsonBits,
+
626  const bool strict = true);
+
627 #endif // DECODE_EPSON
+
628 #if DECODE_SYMPHONY
+
629  bool decodeSymphony(decode_results *results, uint16_t offset = kStartOffset,
+
630  const uint16_t nbits = kSymphonyBits,
+
631  const bool strict = true);
+
632 #endif // DECODE_SYMPHONY
+
633 #if DECODE_AIRWELL
+
634  bool decodeAirwell(decode_results *results, uint16_t offset = kStartOffset,
+
635  const uint16_t nbits = kAirwellBits,
+
636  const bool strict = true);
+
637 #endif // DECODE_AIRWELL
+
638 #if DECODE_DELONGHI_AC
+
639  bool decodeDelonghiAc(decode_results *results, uint16_t offset = kStartOffset,
+
640  const uint16_t nbits = kDelonghiAcBits,
+
641  const bool strict = true);
+
642 #endif // DECODE_DELONGHI_AC
+
643 #if DECODE_DOSHISHA
+
644  bool decodeDoshisha(decode_results *results, uint16_t offset = kStartOffset,
+
645  const uint16_t nbits = kDoshishaBits,
+
646  const bool strict = true);
+
647 #endif // DECODE_DOSHISHA
+
648 #if DECODE_MULTIBRACKETS
+
649  bool decodeMultibrackets(decode_results *results,
+
650  uint16_t offset = kStartOffset,
+
651  const uint16_t nbits = kMultibracketsBits,
+
652  const bool strict = true);
+
653 #endif // DECODE_MULTIBRACKETS
+
654 #if DECODE_CORONA_AC
+
655  bool decodeCoronaAc(decode_results *results, uint16_t offset = kStartOffset,
+
656  const uint16_t nbits = kCoronaAcBitsShort,
+
657  const bool strict = true);
+
658 #endif // DECODE_CORONA_AC
+
659 #if DECODE_ZEPEAL
+
660 bool decodeZepeal(decode_results *results, uint16_t offset = kStartOffset,
+
661  const uint16_t nbits = kZepealBits,
+
662  const bool strict = true);
+
663 #endif // DECODE_ZEPEAL
+
664 };
+
665 
+
666 #endif // IRRECV_H_
+
+
bool decodeMultibrackets(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMultibracketsBits, const bool strict=true)
Decode the Multibrackets message. Status: BETA / Appears to be working.
Definition: ir_Multibrackets.cpp:59
+
const uint16_t kDelonghiAcBits
Definition: IRremoteESP8266.h:861
+
bool decodeMitsubishi(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMitsubishiBits, const bool strict=true)
Decode the supplied Mitsubishi 16-bit message. Status: STABLE / Working.
Definition: ir_Mitsubishi.cpp:123
+
bool decodeHaierAC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kHaierACBits, const bool strict=true)
Decode the supplied Haier HSU07-HEA03 remote message. Status: STABLE / Known to be working.
Definition: ir_Haier.cpp:993
+
bool decodeNEC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kNECBits, const bool strict=true)
Decode the supplied NEC (Renesas) message. Status: STABLE / Known good.
Definition: ir_NEC.cpp:81
+
const uint32_t kFnvPrime32
Definition: IRrecv.h:52
+
bool overflow
Definition: IRrecv.h:109
+
bool decodeDaikin128(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikin128Bits, const bool strict=true)
Decode the supplied Daikin 128-bit message. (DAIKIN128) Status: STABLE / Known Working.
Definition: ir_Daikin.cpp:3109
+
const uint16_t kGicableBits
Definition: IRremoteESP8266.h:879
+
uint16_t matchGeneric(volatile uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, const uint16_t hdrmark, const uint32_t hdrspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t footerspace, const bool atleast=false, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true)
Match & decode a generic/typical <= 64bit IR message. The data is stored at result_ptr.
Definition: IRrecv.cpp:1268
+
decode_type_t
Enumerator for defining and numbering of supported IR protocol.
Definition: IRremoteESP8266.h:714
+
const uint16_t kCarrierAcBits
Definition: IRremoteESP8266.h:826
+
int16_t getRClevel(decode_results *results, uint16_t *offset, uint16_t *used, uint16_t bitTime, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const uint16_t delta=0, const uint8_t maxwidth=3)
Gets one undecoded level at a time from the raw buffer. The RC5/6 decoding is easier if the data is b...
Definition: ir_RC5_RC6.cpp:243
+
const uint16_t kMultibracketsBits
Definition: IRremoteESP8266.h:945
+
const uint16_t kSharpAcBits
Definition: IRremoteESP8266.h:983
+
const uint16_t kWhynterBits
Definition: IRremoteESP8266.h:1008
+
uint8_t overflow
Definition: IRrecv.h:78
+
bool decodeMitsubishi2(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMitsubishiBits, const bool strict=true)
Decode the supplied second variation of a Mitsubishi 16-bit message. Status: STABLE / Working.
Definition: ir_Mitsubishi.cpp:188
+
bool decodeGree(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kGreeBits, const bool strict=true)
Decode the supplied Gree HVAC message. Status: STABLE / Working.
Definition: ir_Gree.cpp:673
+
const uint16_t kAirwellBits
Definition: IRremoteESP8266.h:813
+
irparams_t * irparams_save
Definition: IRrecv.h:151
+
const uint16_t kMitsubishiACBits
Definition: IRremoteESP8266.h:931
+
bool decodeFujitsuAC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kFujitsuAcBits, const bool strict=false)
Decode the supplied Fujitsu AC IR message if possible. Status: STABLE / Working.
Definition: ir_Fujitsu.cpp:745
+
bool decodeTrotec(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kTrotecBits, const bool strict=true)
Decode the supplied Trotec message. Status: STABLE / Works. Untested on real devices.
Definition: ir_Trotec.cpp:313
+
bool decodeNeoclima(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kNeoclimaBits, const bool strict=true)
Decode the supplied Neoclima message. Status: STABLE / Known working.
Definition: ir_Neoclima.cpp:548
+
bool decodeMitsubishi112(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMitsubishi112Bits, const bool strict=true)
Decode the supplied Mitsubishi/TCL 112-bit A/C message. (MITSUBISHI112, TCL112AC) Status: STABLE / Re...
Definition: ir_Mitsubishi.cpp:1216
+
bool decodeSamsungAC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSamsungAcBits, const bool strict=true)
Decode the supplied Samsung A/C message. Status: Stable / Known to be working.
Definition: ir_Samsung.cpp:781
+
bool decodeAirwell(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kAirwellBits, const bool strict=true)
Decode the supplied Airwell "Manchester code" message.
Definition: ir_Airwell.cpp:50
+
const uint16_t kRC5XBits
Definition: IRremoteESP8266.h:963
+
bool decodeMagiQuest(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMagiquestBits, const bool strict=true)
Decode the supplied MagiQuest message. Status: Beta / Should work.
Definition: ir_Magiquest.cpp:69
+
uint16_t rawlen
Definition: IRrecv.h:77
+
const uint8_t kUseDefTol
Definition: IRrecv.h:36
+
bool decodeDelonghiAc(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDelonghiAcBits, const bool strict=true)
Decode the supplied Delonghi A/C message. Status: STABLE / Expected to be working.
Definition: ir_Delonghi.cpp:60
+
Class for receiving IR messages.
Definition: IRrecv.h:114
+
uint16_t bufsize
Definition: IRrecv.h:73
+
Results returned from the decoder.
Definition: IRrecv.h:92
+
uint16_t matchGenericConstBitTime(volatile uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, const uint16_t hdrmark, const uint32_t hdrspace, const uint16_t one, const uint32_t zero, const uint16_t footermark, const uint32_t footerspace, const bool atleast=false, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true)
Match & decode a generic/typical constant bit time <= 64bit IR message. The data is stored at result_...
Definition: IRrecv.cpp:1362
+
bool decodeCarrierAC64(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kCarrierAc64Bits, const bool strict=true)
Decode the supplied Carrier 64-bit HVAC message. Status: STABLE / Known to be working.
Definition: ir_Carrier.cpp:197
+
const uint16_t kCoolixBits
Definition: IRremoteESP8266.h:824
+
bool decodeArgo(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kArgoBits, const bool strict=true)
Decode the supplied Argo message. Status: BETA / Probably works.
Definition: ir_Argo.cpp:459
+
const uint16_t kCoronaAcBitsShort
Definition: IRremoteESP8266.h:834
+
uint64_t data
Definition: IRrecv.h:85
+
const uint16_t kSamsung36Bits
Definition: IRremoteESP8266.h:968
+
const uint16_t kMagiquestBits
Definition: IRremoteESP8266.h:921
+
uint16_t * rawbuf
Definition: IRrecv.h:74
+
Information for the interrupt handler.
Definition: IRrecv.h:69
+
uint16_t getBufSize(void)
Obtain the maximum number of entries possible in the capture buffer. i.e. It's size.
Definition: IRrecv.cpp:319
+
const uint16_t kSanyoLC7461Bits
Definition: IRremoteESP8266.h:977
+
bool decodeToshibaAC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbytes=kToshibaACBits, const bool strict=true)
Decode the supplied Toshiba A/C message. Status: STABLE / Working.
Definition: ir_Toshiba.cpp:322
+
bool repeat
Definition: IRrecv.h:110
+
bool decodeHitachiAC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kHitachiAcBits, const bool strict=true, const bool MSBfirst=true)
Decode the supplied Hitachi A/C message. Status: STABLE / Expected to work.
Definition: ir_Hitachi.cpp:868
+
const uint16_t kTrotecBits
Definition: IRremoteESP8266.h:1003
+
bool decodeVestelAc(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kVestelAcBits, const bool strict=true)
Decode the supplied Vestel message. Status: Alpha / Needs testing against a real device.
Definition: ir_Vestel.cpp:572
+
const uint8_t kIdleState
Definition: IRrecv.h:31
+
bool decodeAmcor(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kAmcorBits, const bool strict=true)
Decode the supplied Amcor HVAC message. Status: STABLE / Reported as working.
Definition: ir_Amcor.cpp:59
+
bool decodeDaikin(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikinBits, const bool strict=true)
Decode the supplied Daikin 280-bit message. (DAIKIN) Status: STABLE / Reported as working.
Definition: ir_Daikin.cpp:619
+
uint8_t recvpin
Definition: IRrecv.h:70
+
uint16_t timer
Definition: IRrecv.h:72
+
bool decodeDaikin64(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikin64Bits, const bool strict=true)
Decode the supplied Daikin 64-bit message. (DAIKIN64) Status: Beta / Probably Working.
Definition: ir_Daikin.cpp:3591
+
bool success
Definition: IRrecv.h:84
+
bool decodeDaikin2(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikin2Bits, const bool strict=true)
Decode the supplied Daikin 312-bit message. (DAIKIN2) Status: STABLE / Works as expected.
Definition: ir_Daikin.cpp:1415
+
const uint16_t kElectraAcBits
Definition: IRremoteESP8266.h:872
+
bool matchSpace(const uint32_t measured, const uint32_t desired, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess)
Check if we match a space signal(measured) with the desired within +/-tolerance percent,...
Definition: IRrecv.cpp:1000
+
const uint16_t kSonyMinBits
Definition: IRremoteESP8266.h:990
+
const uint8_t kStopState
Definition: IRrecv.h:34
+
uint16_t rawlen
Definition: IRrecv.h:108
+
const uint16_t kMaxTimeoutMs
Definition: IRrecv.h:49
+
const uint16_t kDaikin2Bits
Definition: IRremoteESP8266.h:842
+
bool decodePanasonic(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kPanasonicBits, const bool strict=false, const uint32_t manufacturer=kPanasonicManufacturer)
Decode the supplied Panasonic message. Status: STABLE / Should be working.
Definition: ir_Panasonic.cpp:130
+
const uint16_t kHitachiAc1Bits
Definition: IRremoteESP8266.h:896
+
bool decodeElectraAC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kElectraAcBits, const bool strict=true)
Decode the supplied Electra A/C message. Status: STABLE / Known working.
Definition: ir_Electra.cpp:377
+
bool decodeDaikin216(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikin216Bits, const bool strict=true)
Decode the supplied Daikin 216-bit message. (DAIKIN216) Status: STABLE / Should be working.
Definition: ir_Daikin.cpp:1789
+
bool decodeDaikin152(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikin152Bits, const bool strict=true)
Decode the supplied Daikin 152-bit message. (DAIKIN152) Status: STABLE / Known Working.
Definition: ir_Daikin.cpp:3198
+
bool decodeDenon(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDenonBits, const bool strict=true)
Decode the supplied Delonghi A/C message. Status: STABLE / Should work fine.
Definition: ir_Denon.cpp:70
+
const uint16_t kPanasonicBits
Definition: IRremoteESP8266.h:952
+
bool decodeSanyoLC7461(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSanyoLC7461Bits, bool strict=true)
Decode the supplied SANYO LC7461 message. Status: BETA / Probably works.
Definition: ir_Sanyo.cpp:117
+
decode_type_t decode_type
Definition: IRrecv.h:94
+
const uint16_t kPanasonicAcBits
Definition: IRremoteESP8266.h:956
+
const uint64_t kRepeat
Definition: IRrecv.h:26
+
void setTolerance(const uint8_t percent=kTolerance)
Set the base tolerance percentage for matching incoming IR messages.
Definition: IRrecv.cpp:332
+
bool decodeMidea(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMideaBits, const bool strict=true)
Decode the supplied Midea message. Status: Alpha / Needs testing against a real device.
Definition: ir_Midea.cpp:415
+
const uint16_t kDaikin160Bits
Definition: IRremoteESP8266.h:847
+
void copyIrParams(volatile irparams_t *src, irparams_t *dst)
Make a copy of the interrupt state & buffer data. Needed because irparams is marked as volatile,...
Definition: IRrecv.cpp:295
+
bool decodeKelvinator(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kKelvinatorBits, const bool strict=true)
Decode the supplied Kelvinator message. Status: STABLE / Known working.
Definition: ir_Kelvinator.cpp:489
+
const uint16_t kGoodweatherBits
Definition: IRremoteESP8266.h:881
+
bool decodeMWM(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=24, const bool strict=true)
Decode the supplied MWM message. Status: Implemented.
Definition: ir_MWM.cpp:81
+
void enableIRIn(const bool pullup=false)
Set up and (re)start the IR capture mechanism.
Definition: IRrecv.cpp:228
+
const uint16_t kDaikin152Bits
Definition: IRremoteESP8266.h:853
+
bool decodePanasonicAC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kPanasonicAcBits, const bool strict=true)
Decode the supplied Panasonic AC message. Status: STABLE / Works with real device(s).
Definition: ir_Panasonic.cpp:879
+
bool decodeDoshisha(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDoshishaBits, const bool strict=true)
Decode the supplied Doshisha message. Status: STABLE / Works on real device.
Definition: ir_Doshisha.cpp:85
+
bool decodeZepeal(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kZepealBits, const bool strict=true)
Decode the supplied Zepeal message. Status: STABLE / Works on real device.
Definition: ir_Zepeal.cpp:67
+
bool decodeDaikin160(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikin160Bits, const bool strict=true)
Decode the supplied Daikin 160-bit message. (DAIKIN160) Status: STABLE / Confirmed working.
Definition: ir_Daikin.cpp:2162
+
bool decodeLasertag(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kLasertagBits, const bool strict=true)
Decode the supplied Lasertag message. Status: BETA / Appears to be working 90% of the time.
Definition: ir_Lasertag.cpp:70
+ +
const uint8_t kTimeoutMs
Definition: IRrecv.h:47
+
uint16_t _matchGeneric(volatile uint16_t *data_ptr, uint64_t *result_bits_ptr, uint8_t *result_ptr, const bool use_bits, const uint16_t remaining, const uint16_t required, const uint16_t hdrmark, const uint32_t hdrspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t footerspace, const bool atleast=false, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true)
Match & decode a generic/typical IR message. The data is stored in result_bits_ptr or result_bytes_pt...
Definition: IRrecv.cpp:1168
+
const uint8_t kMarkState
Definition: IRrecv.h:32
+
void setUnknownThreshold(const uint16_t length)
Set the minimum length we will consider for reporting UNKNOWN message types.
Definition: IRrecv.cpp:324
+
const uint16_t kSymphonyBits
Definition: IRremoteESP8266.h:992
+
const uint16_t kRC6Mode0Bits
Definition: IRremoteESP8266.h:964
+
const uint16_t kStateSizeMax
Definition: IRrecv.h:60
+
Results from a data match.
Definition: IRrecv.h:83
+
uint8_t rcvstate
Definition: IRrecv.h:71
+
bool decodeRC6(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kRC6Mode0Bits, const bool strict=false)
Decode the supplied RC6 message. Status: Stable.
Definition: ir_RC5_RC6.cpp:383
+
bool decodeRC5(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kRC5XBits, const bool strict=true)
Decode the supplied RC-5/RC5X message. Status: RC-5 (stable), RC-5X (alpha)
Definition: ir_RC5_RC6.cpp:309
+
~IRrecv(void)
Class destructor Cleans up after the object is no longer needed. e.g. Frees up all memory used by the...
Definition: IRrecv.cpp:213
+
bool decodeHitachiAc3(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kHitachiAc3Bits, const bool strict=true)
Decode the supplied Hitachi 15to27-byte/120to216-bit A/C message. Status: STABLE / Works fine.
Definition: ir_Hitachi.cpp:1456
+
bool decodeWhynter(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kWhynterBits, const bool strict=true)
Decode the supplied Whynter message. Status: STABLE / Working. Strict mode is ALPHA.
Definition: ir_Whynter.cpp:74
+
bool decodeCarrierAC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kCarrierAcBits, const bool strict=true)
Decode the supplied Carrier HVAC message.
Definition: ir_Carrier.cpp:84
+
match_result_t matchData(volatile uint16_t *data_ptr, const uint16_t nbits, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true)
Match & decode the typical data section of an IR message. The data value is stored in the least signi...
Definition: IRrecv.cpp:1076
+
const uint16_t kMitsubishiHeavy152Bits
Definition: IRremoteESP8266.h:943
+
const uint16_t kDoshishaBits
Definition: IRremoteESP8266.h:868
+
const uint16_t kCarrierAc40Bits
Definition: IRremoteESP8266.h:828
+
const uint16_t kStartOffset
Definition: IRrecv.h:20
+
const uint16_t kAmcorBits
Definition: IRremoteESP8266.h:819
+
bool decodeRCMM(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kRCMMBits, const bool strict=false)
Decode a Philips RC-MM packet (between 12 & 32 bits) if possible. Status: STABLE / Should be working.
Definition: ir_RCMM.cpp:96
+
IRrecv(const uint16_t recvpin, const uint16_t bufsize=kRawBuf, const uint8_t timeout=kTimeoutMs, const bool save_buffer=false, const uint8_t timer_num=kDefaultESP32Timer)
Class constructor Args:
Definition: IRrecv.cpp:152
+
bool decodeMitsubishi136(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMitsubishi136Bits, const bool strict=true)
Decode the supplied Mitsubishi 136-bit A/C message. (MITSUBISHI136) Status: STABLE / Reported as work...
Definition: ir_Mitsubishi.cpp:835
+
volatile uint16_t * rawbuf
Definition: IRrecv.h:107
+
const uint8_t kTolerance
Definition: IRrecv.h:35
+
bool decodeSharp(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSharpBits, const bool strict=true, const bool expansion=true)
Decode the supplied Sharp message. Status: STABLE / Working fine.
Definition: ir_Sharp.cpp:156
+
uint16_t used
Definition: IRrecv.h:86
+
const uint32_t kPanasonicManufacturer
Definition: IRremoteESP8266.h:953
+
uint32_t address
Definition: IRrecv.h:101
+
bool decodeNikai(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kNikaiBits, const bool strict=true)
Decode the supplied Nikai message. Status: STABLE / Working.
Definition: ir_Nikai.cpp:52
+
const uint16_t kMitsubishiBits
Definition: IRremoteESP8266.h:926
+
bool match(const uint32_t measured, const uint32_t desired, const uint8_t tolerance=kUseDefTol, const uint16_t delta=0)
Check if we match a pulse(measured) with the desired within +/-tolerance percent and/or +/- a fixed d...
Definition: IRrecv.cpp:908
+
bool decodeSymphony(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSymphonyBits, const bool strict=true)
Decode the supplied Symphony packet/message. Status: STABLE / Should be working.
Definition: ir_Symphony.cpp:60
+
const uint16_t kSamsungAcBits
Definition: IRremoteESP8266.h:970
+
const uint16_t kUnknownThreshold
Definition: IRrecv.h:28
+
const uint16_t kMideaBits
Definition: IRremoteESP8266.h:922
+
bool decodeAiwaRCT501(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kAiwaRcT501Bits, const bool strict=true)
Decode the supplied Aiwa RC T501 message. Status: BETA / Should work.
Definition: ir_Aiwa.cpp:61
+
const uint16_t kKelvinatorBits
Definition: IRremoteESP8266.h:911
+
bool decodeGICable(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kGicableBits, const bool strict=true)
Decode the supplied G.I. Cable message. Status: Alpha / Not tested against a real device.
Definition: ir_GICable.cpp:63
+
bool decodeTeco(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kTecoBits, const bool strict=false)
Decode the supplied Teco message. Status: STABLE / Tested.
Definition: ir_Teco.cpp:365
+
bool decodeCarrierAC40(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kCarrierAc40Bits, const bool strict=true)
Decode the supplied Carrier 40-bit HVAC message. Carrier HVAC messages contain only 40 bits,...
Definition: ir_Carrier.cpp:149
+
const uint16_t kNECBits
Definition: IRremoteESP8266.h:948
+
const uint16_t kDenonBits
Definition: IRremoteESP8266.h:863
+
const uint16_t kHaierACBits
Definition: IRremoteESP8266.h:887
+
bool matchAtLeast(const uint32_t measured, const uint32_t desired, const uint8_t tolerance=kUseDefTol, const uint16_t delta=0)
Check if we match a pulse(measured) of at least desired within tolerance percent and/or a fixed delta...
Definition: IRrecv.cpp:939
+
const uint16_t kZepealBits
Definition: IRremoteESP8266.h:1010
+
const uint16_t kMidea24Bits
Definition: IRremoteESP8266.h:924
+
bool decodeDaikin176(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikin176Bits, const bool strict=true)
Decode the supplied Daikin 176-bit message. (DAIKIN176) Status: STABLE / Expected to work.
Definition: ir_Daikin.cpp:2553
+
const uint16_t kNeoclimaBits
Definition: IRremoteESP8266.h:950
+
const uint16_t kWhirlpoolAcBits
Definition: IRremoteESP8266.h:1006
+
bool decodeSharpAc(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSharpAcBits, const bool strict=true)
Decode the supplied Sharp A/C message. Status: STABLE / Known working.
Definition: ir_Sharp.cpp:723
+
bool decodeJVC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kJvcBits, const bool strict=true)
Decode the supplied JVC message. Status: Stable / Known working.
Definition: ir_JVC.cpp:94
+
bool decodeMitsubishiAC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMitsubishiACBits, const bool strict=false)
Decode the supplied Mitsubish 144-bit A/C message. Status: BETA / Probably works.
Definition: ir_Mitsubishi.cpp:254
+
const uint16_t kCarrierAc64Bits
Definition: IRremoteESP8266.h:830
+
const uint16_t kPioneerBits
Definition: IRremoteESP8266.h:959
+
uint16_t bits
Definition: IRrecv.h:106
+
const uint16_t kGreeBits
Definition: IRremoteESP8266.h:884
+
const uint16_t kJvcBits
Definition: IRremoteESP8266.h:909
+
const uint16_t kLasertagBits
Definition: IRremoteESP8266.h:913
+
const uint16_t kDaikin128Bits
Definition: IRremoteESP8266.h:850
+
const uint16_t kAiwaRcT501Bits
Definition: IRremoteESP8266.h:815
+
uint32_t ticksLow(const uint32_t usecs, const uint8_t tolerance=kUseDefTol, const uint16_t delta=0)
Calculate the lower bound of the nr. of ticks.
Definition: IRrecv.cpp:882
+
const uint16_t kTecoBits
Definition: IRremoteESP8266.h:997
+
bool decodeEpson(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kEpsonBits, const bool strict=true)
Decode the supplied Epson message. Status: Beta / Probably works.
Definition: ir_Epson.cpp:45
+
const uint16_t kToshibaACBits
Definition: IRremoteESP8266.h:1000
+
bool decodeSony(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSonyMinBits, const bool strict=false)
Decode the supplied Sony/SIRC message. Status: STABLE / Should be working. strict mode is ALPHA / Unt...
Definition: ir_Sony.cpp:121
+
const uint16_t kDaikinBits
Definition: IRremoteESP8266.h:837
+
bool matchMark(const uint32_t measured, const uint32_t desired, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess)
Check if we match a mark signal(measured) with the desired within +/-tolerance percent,...
Definition: IRrecv.cpp:981
+
const uint16_t kHitachiAcBits
Definition: IRremoteESP8266.h:893
+
const uint16_t kHitachiAc3Bits
Definition: IRremoteESP8266.h:900
+
const uint16_t kRawBuf
Definition: IRrecv.h:25
+
bool decode(decode_results *results, irparams_t *save=NULL, uint8_t max_skip=0, uint16_t noise_floor=0)
Decodes the received IR message. If the interrupt state is saved, we will immediately resume waiting ...
Definition: IRrecv.cpp:409
+
bool decodePioneer(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kPioneerBits, const bool strict=true)
Decode the supplied Pioneer message. Status: STABLE / Should be working. (Self decodes & real example...
Definition: ir_Pioneer.cpp:96
+
uint8_t getTolerance(void)
Get the base tolerance percentage for matching incoming IR messages.
Definition: IRrecv.cpp:338
+
const uint16_t kDishBits
Definition: IRremoteESP8266.h:866
+
uint16_t compare(const uint16_t oldval, const uint16_t newval)
Compare two tick values.
Definition: IRrecv.cpp:1018
+
uint32_t command
Definition: IRrecv.h:102
+
const uint16_t kFujitsuAcBits
Definition: IRremoteESP8266.h:877
+
uint64_t value
Definition: IRrecv.h:100
+
const uint16_t kArgoBits
Definition: IRremoteESP8266.h:822
+
const uint16_t kHitachiAc2StateLength
Definition: IRremoteESP8266.h:897
+
bool decodeSamsung36(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSamsung36Bits, const bool strict=true)
Decode the supplied Samsung36 message. Status: Alpha / Experimental.
Definition: ir_Samsung.cpp:186
+
const uint16_t kFooter
Definition: IRrecv.h:19
+
const uint16_t kNikaiBits
Definition: IRremoteESP8266.h:947
+
const uint16_t kLutronBits
Definition: IRremoteESP8266.h:920
+
uint8_t timeout
Definition: IRrecv.h:79
+
bool decodeCoronaAc(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kCoronaAcBitsShort, const bool strict=true)
Decode the supplied CoronaAc message. Status: STABLE / Appears to be working.
Definition: ir_Corona.cpp:89
+
bool decodeLutron(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kLutronBits, const bool strict=true)
Decode the supplied Lutron message. Status: STABLE / Working.
Definition: ir_Lutron.cpp:65
+
bool decodeDISH(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDishBits, const bool strict=true)
Decode the supplied DISH NETWORK message. Status: ALPHA (untested and unconfirmed....
Definition: ir_Dish.cpp:77
+
const uint16_t kRawTick
Definition: IRrecv.h:37
+
uint16_t matchManchesterData(volatile const uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, const uint16_t half_period, const uint16_t starting_balance=0, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true, const bool GEThomas=true)
Match & decode a Manchester Code data (<= 64bits.
Definition: IRrecv.cpp:1556
+
void resume(void)
Resume collection of received IR data.
Definition: IRrecv.cpp:280
+
const uint16_t kHaierACYRW02Bits
Definition: IRremoteESP8266.h:890
+
const uint16_t kHitachiAc424Bits
Definition: IRremoteESP8266.h:906
+
bool decodeWhirlpoolAC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kWhirlpoolAcBits, const bool strict=true)
Decode the supplied Whirlpool A/C message. Status: STABLE / Working as intended.
Definition: ir_Whirlpool.cpp:642
+
const uint16_t kMarkExcess
Definition: IRrecv.h:24
+
bool decodeHaierACYRW02(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kHaierACYRW02Bits, const bool strict=true)
Decode the supplied Haier YR-W02 remote A/C message. Status: BETA / Appears to be working.
Definition: ir_Haier.cpp:1039
+
bool decodeLG(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kLgBits, const bool strict=false)
Decode the supplied LG message. Status: STABLE / Working.
Definition: ir_LG.cpp:154
+
bool decodeCOOLIX(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kCoolixBits, const bool strict=true)
Decode the supplied Coolix A/C message. Status: STABLE / Known Working.
Definition: ir_Coolix.cpp:650
+
const uint16_t kLegoPfBits
Definition: IRremoteESP8266.h:915
+
const uint16_t kSharpBits
Definition: IRremoteESP8266.h:981
+
bool decodeGoodweather(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kGoodweatherBits, const bool strict=true)
Decode the supplied Goodweather message. Status: BETA / Probably works.
Definition: ir_Goodweather.cpp:429
+
uint8_t _tolerance
Definition: IRrecv.h:152
+
const uint8_t kDefaultESP32Timer
Definition: IRrecv.h:56
+
uint16_t matchManchester(volatile const uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, const uint16_t hdrmark, const uint32_t hdrspace, const uint16_t clock_period, const uint16_t footermark, const uint32_t footerspace, const bool atleast=false, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true, const bool GEThomas=true)
Match & decode a Manchester Code <= 64bit IR message. The data is stored at result_ptr.
Definition: IRrecv.cpp:1449
+
bool decodeInax(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kInaxBits, const bool strict=true)
Decode the supplied Inax Toilet message. Status: Stable / Known working.
Definition: ir_Inax.cpp:51
+
void crudeNoiseFilter(decode_results *results, const uint16_t floor=0)
Remove or merge pulses in the capture buffer that are too short.
Definition: IRrecv.cpp:345
+
bool decodeHitachiAC1(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kHitachiAc1Bits, const bool strict=true)
+
bool decodeSAMSUNG(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSamsungBits, const bool strict=true)
Decode the supplied Samsung 32-bit message. Status: STABLE.
Definition: ir_Samsung.cpp:112
+
bool decodeLegoPf(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kLegoPfBits, const bool strict=true)
Decode the supplied LEGO Power Functions message. Status: STABLE / Appears to work.
Definition: ir_Lego.cpp:71
+
const uint16_t kRCMMBits
Definition: IRremoteESP8266.h:966
+
const uint8_t kVestelAcBits
Definition: IRremoteESP8266.h:1009
+
const uint16_t kInaxBits
Definition: IRremoteESP8266.h:907
+
bool decodeMitsubishiHeavy(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMitsubishiHeavy152Bits, const bool strict=true)
Decode the supplied Mitsubishi Heavy Industries A/C message. Status: BETA / Appears to be working....
Definition: ir_MitsubishiHeavy.cpp:1121
+
uint16_t _unknown_threshold
Definition: IRrecv.h:157
+
const uint16_t kDaikin176Bits
Definition: IRremoteESP8266.h:856
+
bool decodeMidea24(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMidea24Bits, const bool strict=true)
Decode the supplied Midea24 message. Status: STABLE / Confirmed working on a real device.
Definition: ir_Midea.cpp:506
+
void disableIRIn(void)
Stop collection of any received IR data. Disable any timers and interrupts.
Definition: IRrecv.cpp:264
+
bool decodeHitachiAc424(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kHitachiAc424Bits, const bool strict=true)
Decode the supplied Hitachi 53-byte/424-bit A/C message. Status: STABLE / Reported as working.
Definition: ir_Hitachi.cpp:981
+
uint32_t ticksHigh(const uint32_t usecs, const uint8_t tolerance=kUseDefTol, const uint16_t delta=0)
Calculate the upper bound of the nr. of ticks.
Definition: IRrecv.cpp:895
+
const uint16_t kSamsungBits
Definition: IRremoteESP8266.h:967
+
uint8_t _timer_num
Definition: IRrecv.h:154
+
const uint16_t kDaikin64Bits
Definition: IRremoteESP8266.h:844
+
const uint16_t kDaikin216Bits
Definition: IRremoteESP8266.h:859
+
const uint16_t kMitsubishi136Bits
Definition: IRremoteESP8266.h:934
+
uint16_t matchBytes(volatile uint16_t *data_ptr, uint8_t *result_ptr, const uint16_t remaining, const uint16_t nbytes, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true)
Match & decode the typical data section of an IR message. The bytes are stored at result_ptr....
Definition: IRrecv.cpp:1118
+
const uint16_t kMitsubishi112Bits
Definition: IRremoteESP8266.h:937
+
const uint16_t kEpsonBits
Definition: IRremoteESP8266.h:869
+
uint8_t state[kStateSizeMax]
Definition: IRrecv.h:104
+
bool decodeHash(decode_results *results)
Decode any arbitrary IR message into a 32-bit code value. Instead of decoding using a standard encodi...
Definition: IRrecv.cpp:1039
+
const uint8_t kSpaceState
Definition: IRrecv.h:33
+
const uint16_t kLgBits
Definition: IRremoteESP8266.h:917
+
uint8_t _validTolerance(const uint8_t percentage)
Convert the tolerance percentage into something valid.
Definition: IRrecv.cpp:873
+
const uint16_t kHeader
Definition: IRrecv.h:18
+
const uint32_t kFnvBasis32
Definition: IRrecv.h:53
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRremoteESP8266_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRremoteESP8266_8h.html new file mode 100644 index 000000000..a8a3d1f05 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRremoteESP8266_8h.html @@ -0,0 +1,3515 @@ + + + + + + + +IRremoteESP8266: src/IRremoteESP8266.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
IRremoteESP8266.h File Reference
+
+
+ +

Go to the source code of this file.

+ + + + +

+Typedefs

typedef std::string String
 
+ + + + +

+Enumerations

enum  decode_type_t {
+  UNKNOWN = -1, +UNUSED = 0, +RC5, +RC6, +
+  NEC, +SONY, +PANASONIC, +JVC, +
+  SAMSUNG, +WHYNTER, +AIWA_RC_T501, +LG, +
+  SANYO, +MITSUBISHI, +DISH, +SHARP, +
+  COOLIX, +DAIKIN, +DENON, +KELVINATOR, +
+  SHERWOOD, +MITSUBISHI_AC, +RCMM, +SANYO_LC7461, +
+  RC5X, +GREE, +PRONTO, +NEC_LIKE, +
+  ARGO, +TROTEC, +NIKAI, +RAW, +
+  GLOBALCACHE, +TOSHIBA_AC, +FUJITSU_AC, +MIDEA, +
+  MAGIQUEST, +LASERTAG, +CARRIER_AC, +HAIER_AC, +
+  MITSUBISHI2, +HITACHI_AC, +HITACHI_AC1, +HITACHI_AC2, +
+  GICABLE, +HAIER_AC_YRW02, +WHIRLPOOL_AC, +SAMSUNG_AC, +
+  LUTRON, +ELECTRA_AC, +PANASONIC_AC, +PIONEER, +
+  LG2, +MWM, +DAIKIN2, +VESTEL_AC, +
+  TECO, +SAMSUNG36, +TCL112AC, +LEGOPF, +
+  MITSUBISHI_HEAVY_88, +MITSUBISHI_HEAVY_152, +DAIKIN216, +SHARP_AC, +
+  GOODWEATHER, +INAX, +DAIKIN160, +NEOCLIMA, +
+  DAIKIN176, +DAIKIN128, +AMCOR, +DAIKIN152, +
+  MITSUBISHI136, +MITSUBISHI112, +HITACHI_AC424, +SONY_38K, +
+  EPSON, +SYMPHONY, +HITACHI_AC3, +DAIKIN64, +
+  AIRWELL, +DELONGHI_AC, +DOSHISHA, +MULTIBRACKETS, +
+  CARRIER_AC40, +CARRIER_AC64, +HITACHI_AC344, +CORONA_AC, +
+  MIDEA24, +ZEPEAL, +kLastDecodeType = ZEPEAL +
+ }
 Enumerator for defining and numbering of supported IR protocol. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kNoRepeat = 0
 
const uint16_t kSingleRepeat = 1
 
const uint16_t kAirwellBits = 34
 
const uint16_t kAirwellMinRepeats = 2
 
const uint16_t kAiwaRcT501Bits = 15
 
const uint16_t kAiwaRcT501MinRepeats = kSingleRepeat
 
const uint16_t kAlokaBits = 32
 
const uint16_t kAmcorStateLength = 8
 
const uint16_t kAmcorBits = kAmcorStateLength * 8
 
const uint16_t kAmcorDefaultRepeat = kSingleRepeat
 
const uint16_t kArgoStateLength = 12
 
const uint16_t kArgoBits = kArgoStateLength * 8
 
const uint16_t kArgoDefaultRepeat = kNoRepeat
 
const uint16_t kCoolixBits = 24
 
const uint16_t kCoolixDefaultRepeat = kSingleRepeat
 
const uint16_t kCarrierAcBits = 32
 
const uint16_t kCarrierAcMinRepeat = kNoRepeat
 
const uint16_t kCarrierAc40Bits = 40
 
const uint16_t kCarrierAc40MinRepeat = 2
 
const uint16_t kCarrierAc64Bits = 64
 
const uint16_t kCarrierAc64MinRepeat = kNoRepeat
 
const uint16_t kCoronaAcStateLengthShort = 7
 
const uint16_t kCoronaAcStateLength = kCoronaAcStateLengthShort * 3
 
const uint16_t kCoronaAcBitsShort = kCoronaAcStateLengthShort * 8
 
const uint16_t kCoronaAcBits = kCoronaAcStateLength * 8
 
const uint16_t kDaikinStateLength = 35
 
const uint16_t kDaikinBits = kDaikinStateLength * 8
 
const uint16_t kDaikinStateLengthShort = kDaikinStateLength - 8
 
const uint16_t kDaikinBitsShort = kDaikinStateLengthShort * 8
 
const uint16_t kDaikinDefaultRepeat = kNoRepeat
 
const uint16_t kDaikin2StateLength = 39
 
const uint16_t kDaikin2Bits = kDaikin2StateLength * 8
 
const uint16_t kDaikin2DefaultRepeat = kNoRepeat
 
const uint16_t kDaikin64Bits = 64
 
const uint16_t kDaikin64DefaultRepeat = kNoRepeat
 
const uint16_t kDaikin160StateLength = 20
 
const uint16_t kDaikin160Bits = kDaikin160StateLength * 8
 
const uint16_t kDaikin160DefaultRepeat = kNoRepeat
 
const uint16_t kDaikin128StateLength = 16
 
const uint16_t kDaikin128Bits = kDaikin128StateLength * 8
 
const uint16_t kDaikin128DefaultRepeat = kNoRepeat
 
const uint16_t kDaikin152StateLength = 19
 
const uint16_t kDaikin152Bits = kDaikin152StateLength * 8
 
const uint16_t kDaikin152DefaultRepeat = kNoRepeat
 
const uint16_t kDaikin176StateLength = 22
 
const uint16_t kDaikin176Bits = kDaikin176StateLength * 8
 
const uint16_t kDaikin176DefaultRepeat = kNoRepeat
 
const uint16_t kDaikin216StateLength = 27
 
const uint16_t kDaikin216Bits = kDaikin216StateLength * 8
 
const uint16_t kDaikin216DefaultRepeat = kNoRepeat
 
const uint16_t kDelonghiAcBits = 64
 
const uint16_t kDelonghiAcDefaultRepeat = kNoRepeat
 
const uint16_t kDenonBits = 15
 
const uint16_t kDenon48Bits = 48
 
const uint16_t kDenonLegacyBits = 14
 
const uint16_t kDishBits = 16
 
const uint16_t kDishMinRepeat = 3
 
const uint16_t kDoshishaBits = 40
 
const uint16_t kEpsonBits = 32
 
const uint16_t kEpsonMinRepeat = 2
 
const uint16_t kElectraAcStateLength = 13
 
const uint16_t kElectraAcBits = kElectraAcStateLength * 8
 
const uint16_t kElectraAcMinRepeat = kNoRepeat
 
const uint16_t kFujitsuAcMinRepeat = kNoRepeat
 
const uint16_t kFujitsuAcStateLength = 16
 
const uint16_t kFujitsuAcStateLengthShort = 7
 
const uint16_t kFujitsuAcBits = kFujitsuAcStateLength * 8
 
const uint16_t kFujitsuAcMinBits = (kFujitsuAcStateLengthShort - 1) * 8
 
const uint16_t kGicableBits = 16
 
const uint16_t kGicableMinRepeat = kSingleRepeat
 
const uint16_t kGoodweatherBits = 48
 
const uint16_t kGoodweatherMinRepeat = kNoRepeat
 
const uint16_t kGreeStateLength = 8
 
const uint16_t kGreeBits = kGreeStateLength * 8
 
const uint16_t kGreeDefaultRepeat = kNoRepeat
 
const uint16_t kHaierACStateLength = 9
 
const uint16_t kHaierACBits = kHaierACStateLength * 8
 
const uint16_t kHaierAcDefaultRepeat = kNoRepeat
 
const uint16_t kHaierACYRW02StateLength = 14
 
const uint16_t kHaierACYRW02Bits = kHaierACYRW02StateLength * 8
 
const uint16_t kHaierAcYrw02DefaultRepeat = kNoRepeat
 
const uint16_t kHitachiAcStateLength = 28
 
const uint16_t kHitachiAcBits = kHitachiAcStateLength * 8
 
const uint16_t kHitachiAcDefaultRepeat = kNoRepeat
 
const uint16_t kHitachiAc1StateLength = 13
 
const uint16_t kHitachiAc1Bits = kHitachiAc1StateLength * 8
 
const uint16_t kHitachiAc2StateLength = 53
 
const uint16_t kHitachiAc2Bits = kHitachiAc2StateLength * 8
 
const uint16_t kHitachiAc3StateLength = 27
 
const uint16_t kHitachiAc3Bits = kHitachiAc3StateLength * 8
 
const uint16_t kHitachiAc3MinStateLength = 15
 
const uint16_t kHitachiAc3MinBits = kHitachiAc3MinStateLength * 8
 
const uint16_t kHitachiAc344StateLength = 43
 
const uint16_t kHitachiAc344Bits = kHitachiAc344StateLength * 8
 
const uint16_t kHitachiAc424StateLength = 53
 
const uint16_t kHitachiAc424Bits = kHitachiAc424StateLength * 8
 
const uint16_t kInaxBits = 24
 
const uint16_t kInaxMinRepeat = kSingleRepeat
 
const uint16_t kJvcBits = 16
 
const uint16_t kKelvinatorStateLength = 16
 
const uint16_t kKelvinatorBits = kKelvinatorStateLength * 8
 
const uint16_t kKelvinatorDefaultRepeat = kNoRepeat
 
const uint16_t kLasertagBits = 13
 
const uint16_t kLasertagMinRepeat = kNoRepeat
 
const uint16_t kLegoPfBits = 16
 
const uint16_t kLegoPfMinRepeat = kNoRepeat
 
const uint16_t kLgBits = 28
 
const uint16_t kLg32Bits = 32
 
const uint16_t kLgDefaultRepeat = kNoRepeat
 
const uint16_t kLutronBits = 35
 
const uint16_t kMagiquestBits = 56
 
const uint16_t kMideaBits = 48
 
const uint16_t kMideaMinRepeat = kNoRepeat
 
const uint16_t kMidea24Bits = 24
 
const uint16_t kMidea24MinRepeat = kSingleRepeat
 
const uint16_t kMitsubishiBits = 16
 
const uint16_t kMitsubishiMinRepeat = kSingleRepeat
 
const uint16_t kMitsubishiACStateLength = 18
 
const uint16_t kMitsubishiACBits = kMitsubishiACStateLength * 8
 
const uint16_t kMitsubishiACMinRepeat = kSingleRepeat
 
const uint16_t kMitsubishi136StateLength = 17
 
const uint16_t kMitsubishi136Bits = kMitsubishi136StateLength * 8
 
const uint16_t kMitsubishi136MinRepeat = kNoRepeat
 
const uint16_t kMitsubishi112StateLength = 14
 
const uint16_t kMitsubishi112Bits = kMitsubishi112StateLength * 8
 
const uint16_t kMitsubishi112MinRepeat = kNoRepeat
 
const uint16_t kMitsubishiHeavy88StateLength = 11
 
const uint16_t kMitsubishiHeavy88Bits = kMitsubishiHeavy88StateLength * 8
 
const uint16_t kMitsubishiHeavy88MinRepeat = kNoRepeat
 
const uint16_t kMitsubishiHeavy152StateLength = 19
 
const uint16_t kMitsubishiHeavy152Bits = kMitsubishiHeavy152StateLength * 8
 
const uint16_t kMitsubishiHeavy152MinRepeat = kNoRepeat
 
const uint16_t kMultibracketsBits = 8
 
const uint16_t kMultibracketsDefaultRepeat = kSingleRepeat
 
const uint16_t kNikaiBits = 24
 
const uint16_t kNECBits = 32
 
const uint16_t kNeoclimaStateLength = 12
 
const uint16_t kNeoclimaBits = kNeoclimaStateLength * 8
 
const uint16_t kNeoclimaMinRepeat = kNoRepeat
 
const uint16_t kPanasonicBits = 48
 
const uint32_t kPanasonicManufacturer = 0x4004
 
const uint16_t kPanasonicAcStateLength = 27
 
const uint16_t kPanasonicAcStateShortLength = 16
 
const uint16_t kPanasonicAcBits = kPanasonicAcStateLength * 8
 
const uint16_t kPanasonicAcShortBits = kPanasonicAcStateShortLength * 8
 
const uint16_t kPanasonicAcDefaultRepeat = kNoRepeat
 
const uint16_t kPioneerBits = 64
 
const uint16_t kProntoMinLength = 6
 
const uint16_t kRC5RawBits = 14
 
const uint16_t kRC5Bits = kRC5RawBits - 2
 
const uint16_t kRC5XBits = kRC5RawBits - 1
 
const uint16_t kRC6Mode0Bits = 20
 
const uint16_t kRC6_36Bits = 36
 
const uint16_t kRCMMBits = 24
 
const uint16_t kSamsungBits = 32
 
const uint16_t kSamsung36Bits = 36
 
const uint16_t kSamsungAcStateLength = 14
 
const uint16_t kSamsungAcBits = kSamsungAcStateLength * 8
 
const uint16_t kSamsungAcExtendedStateLength = 21
 
const uint16_t kSamsungAcExtendedBits = kSamsungAcExtendedStateLength * 8
 
const uint16_t kSamsungAcDefaultRepeat = kNoRepeat
 
const uint16_t kSanyoSA8650BBits = 12
 
const uint16_t kSanyoLC7461AddressBits = 13
 
const uint16_t kSanyoLC7461CommandBits = 8
 
const uint16_t kSanyoLC7461Bits
 
const uint8_t kSharpAddressBits = 5
 
const uint8_t kSharpCommandBits = 8
 
const uint16_t kSharpBits = kSharpAddressBits + kSharpCommandBits + 2
 
const uint16_t kSharpAcStateLength = 13
 
const uint16_t kSharpAcBits = kSharpAcStateLength * 8
 
const uint16_t kSharpAcDefaultRepeat = kNoRepeat
 
const uint8_t kSherwoodBits = kNECBits
 
const uint16_t kSherwoodMinRepeat = kSingleRepeat
 
const uint16_t kSony12Bits = 12
 
const uint16_t kSony15Bits = 15
 
const uint16_t kSony20Bits = 20
 
const uint16_t kSonyMinBits = 12
 
const uint16_t kSonyMinRepeat = 2
 
const uint16_t kSymphonyBits = 12
 
const uint16_t kSymphonyDefaultRepeat = 3
 
const uint16_t kTcl112AcStateLength = 14
 
const uint16_t kTcl112AcBits = kTcl112AcStateLength * 8
 
const uint16_t kTcl112AcDefaultRepeat = kNoRepeat
 
const uint16_t kTecoBits = 35
 
const uint16_t kTecoDefaultRepeat = kNoRepeat
 
const uint16_t kToshibaACStateLength = 9
 
const uint16_t kToshibaACBits = kToshibaACStateLength * 8
 
const uint16_t kToshibaACMinRepeat = kSingleRepeat
 
const uint16_t kTrotecStateLength = 9
 
const uint16_t kTrotecBits = kTrotecStateLength * 8
 
const uint16_t kTrotecDefaultRepeat = kNoRepeat
 
const uint16_t kWhirlpoolAcStateLength = 21
 
const uint16_t kWhirlpoolAcBits = kWhirlpoolAcStateLength * 8
 
const uint16_t kWhirlpoolAcDefaultRepeat = kNoRepeat
 
const uint16_t kWhynterBits = 32
 
const uint8_t kVestelAcBits = 56
 
const uint16_t kZepealBits = 16
 
const uint16_t kZepealMinRepeat = 4
 
+

Typedef Documentation

+ +

◆ String

+ +
+
+ + + + +
typedef std::string String
+
+ +
+
+

Enumeration Type Documentation

+ +

◆ decode_type_t

+ +
+
+ + + + +
enum decode_type_t
+
+ +

Enumerator for defining and numbering of supported IR protocol.

+
Note
Always add to the end of the list and should never remove entries or change order. Projects may save the type number for later usage so numbering should always stay the same.
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Enumerator
UNKNOWN 
UNUSED 
RC5 
RC6 
NEC 
SONY 
PANASONIC 
JVC 
SAMSUNG 
WHYNTER 
AIWA_RC_T501 
LG 
SANYO 
MITSUBISHI 
DISH 
SHARP 
COOLIX 
DAIKIN 
DENON 
KELVINATOR 
SHERWOOD 
MITSUBISHI_AC 
RCMM 
SANYO_LC7461 
RC5X 
GREE 
PRONTO 
NEC_LIKE 
ARGO 
TROTEC 
NIKAI 
RAW 
GLOBALCACHE 
TOSHIBA_AC 
FUJITSU_AC 
MIDEA 
MAGIQUEST 
LASERTAG 
CARRIER_AC 
HAIER_AC 
MITSUBISHI2 
HITACHI_AC 
HITACHI_AC1 
HITACHI_AC2 
GICABLE 
HAIER_AC_YRW02 
WHIRLPOOL_AC 
SAMSUNG_AC 
LUTRON 
ELECTRA_AC 
PANASONIC_AC 
PIONEER 
LG2 
MWM 
DAIKIN2 
VESTEL_AC 
TECO 
SAMSUNG36 
TCL112AC 
LEGOPF 
MITSUBISHI_HEAVY_88 
MITSUBISHI_HEAVY_152 
DAIKIN216 
SHARP_AC 
GOODWEATHER 
INAX 
DAIKIN160 
NEOCLIMA 
DAIKIN176 
DAIKIN128 
AMCOR 
DAIKIN152 
MITSUBISHI136 
MITSUBISHI112 
HITACHI_AC424 
SONY_38K 
EPSON 
SYMPHONY 
HITACHI_AC3 
DAIKIN64 
AIRWELL 
DELONGHI_AC 
DOSHISHA 
MULTIBRACKETS 
CARRIER_AC40 
CARRIER_AC64 
HITACHI_AC344 
CORONA_AC 
MIDEA24 
ZEPEAL 
kLastDecodeType 
+ +
+
+

Variable Documentation

+ +

◆ kAirwellBits

+ +
+
+ + + + +
const uint16_t kAirwellBits = 34
+
+ +
+
+ +

◆ kAirwellMinRepeats

+ +
+
+ + + + +
const uint16_t kAirwellMinRepeats = 2
+
+ +
+
+ +

◆ kAiwaRcT501Bits

+ +
+
+ + + + +
const uint16_t kAiwaRcT501Bits = 15
+
+ +
+
+ +

◆ kAiwaRcT501MinRepeats

+ +
+
+ + + + +
const uint16_t kAiwaRcT501MinRepeats = kSingleRepeat
+
+ +
+
+ +

◆ kAlokaBits

+ +
+
+ + + + +
const uint16_t kAlokaBits = 32
+
+ +
+
+ +

◆ kAmcorBits

+ +
+
+ + + + +
const uint16_t kAmcorBits = kAmcorStateLength * 8
+
+ +
+
+ +

◆ kAmcorDefaultRepeat

+ +
+
+ + + + +
const uint16_t kAmcorDefaultRepeat = kSingleRepeat
+
+ +
+
+ +

◆ kAmcorStateLength

+ +
+
+ + + + +
const uint16_t kAmcorStateLength = 8
+
+ +
+
+ +

◆ kArgoBits

+ +
+
+ + + + +
const uint16_t kArgoBits = kArgoStateLength * 8
+
+ +
+
+ +

◆ kArgoDefaultRepeat

+ +
+
+ + + + +
const uint16_t kArgoDefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kArgoStateLength

+ +
+
+ + + + +
const uint16_t kArgoStateLength = 12
+
+ +
+
+ +

◆ kCarrierAc40Bits

+ +
+
+ + + + +
const uint16_t kCarrierAc40Bits = 40
+
+ +
+
+ +

◆ kCarrierAc40MinRepeat

+ +
+
+ + + + +
const uint16_t kCarrierAc40MinRepeat = 2
+
+ +
+
+ +

◆ kCarrierAc64Bits

+ +
+
+ + + + +
const uint16_t kCarrierAc64Bits = 64
+
+ +
+
+ +

◆ kCarrierAc64MinRepeat

+ +
+
+ + + + +
const uint16_t kCarrierAc64MinRepeat = kNoRepeat
+
+ +
+
+ +

◆ kCarrierAcBits

+ +
+
+ + + + +
const uint16_t kCarrierAcBits = 32
+
+ +
+
+ +

◆ kCarrierAcMinRepeat

+ +
+
+ + + + +
const uint16_t kCarrierAcMinRepeat = kNoRepeat
+
+ +
+
+ +

◆ kCoolixBits

+ +
+
+ + + + +
const uint16_t kCoolixBits = 24
+
+ +
+
+ +

◆ kCoolixDefaultRepeat

+ +
+
+ + + + +
const uint16_t kCoolixDefaultRepeat = kSingleRepeat
+
+ +
+
+ +

◆ kCoronaAcBits

+ +
+
+ + + + +
const uint16_t kCoronaAcBits = kCoronaAcStateLength * 8
+
+ +
+
+ +

◆ kCoronaAcBitsShort

+ +
+
+ + + + +
const uint16_t kCoronaAcBitsShort = kCoronaAcStateLengthShort * 8
+
+ +
+
+ +

◆ kCoronaAcStateLength

+ +
+
+ + + + +
const uint16_t kCoronaAcStateLength = kCoronaAcStateLengthShort * 3
+
+ +
+
+ +

◆ kCoronaAcStateLengthShort

+ +
+
+ + + + +
const uint16_t kCoronaAcStateLengthShort = 7
+
+ +
+
+ +

◆ kDaikin128Bits

+ +
+
+ + + + +
const uint16_t kDaikin128Bits = kDaikin128StateLength * 8
+
+ +
+
+ +

◆ kDaikin128DefaultRepeat

+ +
+
+ + + + +
const uint16_t kDaikin128DefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kDaikin128StateLength

+ +
+
+ + + + +
const uint16_t kDaikin128StateLength = 16
+
+ +
+
+ +

◆ kDaikin152Bits

+ +
+
+ + + + +
const uint16_t kDaikin152Bits = kDaikin152StateLength * 8
+
+ +
+
+ +

◆ kDaikin152DefaultRepeat

+ +
+
+ + + + +
const uint16_t kDaikin152DefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kDaikin152StateLength

+ +
+
+ + + + +
const uint16_t kDaikin152StateLength = 19
+
+ +
+
+ +

◆ kDaikin160Bits

+ +
+
+ + + + +
const uint16_t kDaikin160Bits = kDaikin160StateLength * 8
+
+ +
+
+ +

◆ kDaikin160DefaultRepeat

+ +
+
+ + + + +
const uint16_t kDaikin160DefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kDaikin160StateLength

+ +
+
+ + + + +
const uint16_t kDaikin160StateLength = 20
+
+ +
+
+ +

◆ kDaikin176Bits

+ +
+
+ + + + +
const uint16_t kDaikin176Bits = kDaikin176StateLength * 8
+
+ +
+
+ +

◆ kDaikin176DefaultRepeat

+ +
+
+ + + + +
const uint16_t kDaikin176DefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kDaikin176StateLength

+ +
+
+ + + + +
const uint16_t kDaikin176StateLength = 22
+
+ +
+
+ +

◆ kDaikin216Bits

+ +
+
+ + + + +
const uint16_t kDaikin216Bits = kDaikin216StateLength * 8
+
+ +
+
+ +

◆ kDaikin216DefaultRepeat

+ +
+
+ + + + +
const uint16_t kDaikin216DefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kDaikin216StateLength

+ +
+
+ + + + +
const uint16_t kDaikin216StateLength = 27
+
+ +
+
+ +

◆ kDaikin2Bits

+ +
+
+ + + + +
const uint16_t kDaikin2Bits = kDaikin2StateLength * 8
+
+ +
+
+ +

◆ kDaikin2DefaultRepeat

+ +
+
+ + + + +
const uint16_t kDaikin2DefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kDaikin2StateLength

+ +
+
+ + + + +
const uint16_t kDaikin2StateLength = 39
+
+ +
+
+ +

◆ kDaikin64Bits

+ +
+
+ + + + +
const uint16_t kDaikin64Bits = 64
+
+ +
+
+ +

◆ kDaikin64DefaultRepeat

+ +
+
+ + + + +
const uint16_t kDaikin64DefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kDaikinBits

+ +
+
+ + + + +
const uint16_t kDaikinBits = kDaikinStateLength * 8
+
+ +
+
+ +

◆ kDaikinBitsShort

+ +
+
+ + + + +
const uint16_t kDaikinBitsShort = kDaikinStateLengthShort * 8
+
+ +
+
+ +

◆ kDaikinDefaultRepeat

+ +
+
+ + + + +
const uint16_t kDaikinDefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kDaikinStateLength

+ +
+
+ + + + +
const uint16_t kDaikinStateLength = 35
+
+ +
+
+ +

◆ kDaikinStateLengthShort

+ +
+
+ + + + +
const uint16_t kDaikinStateLengthShort = kDaikinStateLength - 8
+
+ +
+
+ +

◆ kDelonghiAcBits

+ +
+
+ + + + +
const uint16_t kDelonghiAcBits = 64
+
+ +
+
+ +

◆ kDelonghiAcDefaultRepeat

+ +
+
+ + + + +
const uint16_t kDelonghiAcDefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kDenon48Bits

+ +
+
+ + + + +
const uint16_t kDenon48Bits = 48
+
+ +
+
+ +

◆ kDenonBits

+ +
+
+ + + + +
const uint16_t kDenonBits = 15
+
+ +
+
+ +

◆ kDenonLegacyBits

+ +
+
+ + + + +
const uint16_t kDenonLegacyBits = 14
+
+ +
+
+ +

◆ kDishBits

+ +
+
+ + + + +
const uint16_t kDishBits = 16
+
+ +
+
+ +

◆ kDishMinRepeat

+ +
+
+ + + + +
const uint16_t kDishMinRepeat = 3
+
+ +
+
+ +

◆ kDoshishaBits

+ +
+
+ + + + +
const uint16_t kDoshishaBits = 40
+
+ +
+
+ +

◆ kElectraAcBits

+ +
+
+ + + + +
const uint16_t kElectraAcBits = kElectraAcStateLength * 8
+
+ +
+
+ +

◆ kElectraAcMinRepeat

+ +
+
+ + + + +
const uint16_t kElectraAcMinRepeat = kNoRepeat
+
+ +
+
+ +

◆ kElectraAcStateLength

+ +
+
+ + + + +
const uint16_t kElectraAcStateLength = 13
+
+ +
+
+ +

◆ kEpsonBits

+ +
+
+ + + + +
const uint16_t kEpsonBits = 32
+
+ +
+
+ +

◆ kEpsonMinRepeat

+ +
+
+ + + + +
const uint16_t kEpsonMinRepeat = 2
+
+ +
+
+ +

◆ kFujitsuAcBits

+ +
+
+ + + + +
const uint16_t kFujitsuAcBits = kFujitsuAcStateLength * 8
+
+ +
+
+ +

◆ kFujitsuAcMinBits

+ +
+
+ + + + +
const uint16_t kFujitsuAcMinBits = (kFujitsuAcStateLengthShort - 1) * 8
+
+ +
+
+ +

◆ kFujitsuAcMinRepeat

+ +
+
+ + + + +
const uint16_t kFujitsuAcMinRepeat = kNoRepeat
+
+ +
+
+ +

◆ kFujitsuAcStateLength

+ +
+
+ + + + +
const uint16_t kFujitsuAcStateLength = 16
+
+ +
+
+ +

◆ kFujitsuAcStateLengthShort

+ +
+
+ + + + +
const uint16_t kFujitsuAcStateLengthShort = 7
+
+ +
+
+ +

◆ kGicableBits

+ +
+
+ + + + +
const uint16_t kGicableBits = 16
+
+ +
+
+ +

◆ kGicableMinRepeat

+ +
+
+ + + + +
const uint16_t kGicableMinRepeat = kSingleRepeat
+
+ +
+
+ +

◆ kGoodweatherBits

+ +
+
+ + + + +
const uint16_t kGoodweatherBits = 48
+
+ +
+
+ +

◆ kGoodweatherMinRepeat

+ +
+
+ + + + +
const uint16_t kGoodweatherMinRepeat = kNoRepeat
+
+ +
+
+ +

◆ kGreeBits

+ +
+
+ + + + +
const uint16_t kGreeBits = kGreeStateLength * 8
+
+ +
+
+ +

◆ kGreeDefaultRepeat

+ +
+
+ + + + +
const uint16_t kGreeDefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kGreeStateLength

+ +
+
+ + + + +
const uint16_t kGreeStateLength = 8
+
+ +
+
+ +

◆ kHaierACBits

+ +
+
+ + + + +
const uint16_t kHaierACBits = kHaierACStateLength * 8
+
+ +
+
+ +

◆ kHaierAcDefaultRepeat

+ +
+
+ + + + +
const uint16_t kHaierAcDefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kHaierACStateLength

+ +
+
+ + + + +
const uint16_t kHaierACStateLength = 9
+
+ +
+
+ +

◆ kHaierACYRW02Bits

+ +
+
+ + + + +
const uint16_t kHaierACYRW02Bits = kHaierACYRW02StateLength * 8
+
+ +
+
+ +

◆ kHaierAcYrw02DefaultRepeat

+ +
+
+ + + + +
const uint16_t kHaierAcYrw02DefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kHaierACYRW02StateLength

+ +
+
+ + + + +
const uint16_t kHaierACYRW02StateLength = 14
+
+ +
+
+ +

◆ kHitachiAc1Bits

+ +
+
+ + + + +
const uint16_t kHitachiAc1Bits = kHitachiAc1StateLength * 8
+
+ +
+
+ +

◆ kHitachiAc1StateLength

+ +
+
+ + + + +
const uint16_t kHitachiAc1StateLength = 13
+
+ +
+
+ +

◆ kHitachiAc2Bits

+ +
+
+ + + + +
const uint16_t kHitachiAc2Bits = kHitachiAc2StateLength * 8
+
+ +
+
+ +

◆ kHitachiAc2StateLength

+ +
+
+ + + + +
const uint16_t kHitachiAc2StateLength = 53
+
+ +
+
+ +

◆ kHitachiAc344Bits

+ +
+
+ + + + +
const uint16_t kHitachiAc344Bits = kHitachiAc344StateLength * 8
+
+ +
+
+ +

◆ kHitachiAc344StateLength

+ +
+
+ + + + +
const uint16_t kHitachiAc344StateLength = 43
+
+ +
+
+ +

◆ kHitachiAc3Bits

+ +
+
+ + + + +
const uint16_t kHitachiAc3Bits = kHitachiAc3StateLength * 8
+
+ +
+
+ +

◆ kHitachiAc3MinBits

+ +
+
+ + + + +
const uint16_t kHitachiAc3MinBits = kHitachiAc3MinStateLength * 8
+
+ +
+
+ +

◆ kHitachiAc3MinStateLength

+ +
+
+ + + + +
const uint16_t kHitachiAc3MinStateLength = 15
+
+ +
+
+ +

◆ kHitachiAc3StateLength

+ +
+
+ + + + +
const uint16_t kHitachiAc3StateLength = 27
+
+ +
+
+ +

◆ kHitachiAc424Bits

+ +
+
+ + + + +
const uint16_t kHitachiAc424Bits = kHitachiAc424StateLength * 8
+
+ +
+
+ +

◆ kHitachiAc424StateLength

+ +
+
+ + + + +
const uint16_t kHitachiAc424StateLength = 53
+
+ +
+
+ +

◆ kHitachiAcBits

+ +
+
+ + + + +
const uint16_t kHitachiAcBits = kHitachiAcStateLength * 8
+
+ +
+
+ +

◆ kHitachiAcDefaultRepeat

+ +
+
+ + + + +
const uint16_t kHitachiAcDefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kHitachiAcStateLength

+ +
+
+ + + + +
const uint16_t kHitachiAcStateLength = 28
+
+ +
+
+ +

◆ kInaxBits

+ +
+
+ + + + +
const uint16_t kInaxBits = 24
+
+ +
+
+ +

◆ kInaxMinRepeat

+ +
+
+ + + + +
const uint16_t kInaxMinRepeat = kSingleRepeat
+
+ +
+
+ +

◆ kJvcBits

+ +
+
+ + + + +
const uint16_t kJvcBits = 16
+
+ +
+
+ +

◆ kKelvinatorBits

+ +
+
+ + + + +
const uint16_t kKelvinatorBits = kKelvinatorStateLength * 8
+
+ +
+
+ +

◆ kKelvinatorDefaultRepeat

+ +
+
+ + + + +
const uint16_t kKelvinatorDefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kKelvinatorStateLength

+ +
+
+ + + + +
const uint16_t kKelvinatorStateLength = 16
+
+ +
+
+ +

◆ kLasertagBits

+ +
+
+ + + + +
const uint16_t kLasertagBits = 13
+
+ +
+
+ +

◆ kLasertagMinRepeat

+ +
+
+ + + + +
const uint16_t kLasertagMinRepeat = kNoRepeat
+
+ +
+
+ +

◆ kLegoPfBits

+ +
+
+ + + + +
const uint16_t kLegoPfBits = 16
+
+ +
+
+ +

◆ kLegoPfMinRepeat

+ +
+
+ + + + +
const uint16_t kLegoPfMinRepeat = kNoRepeat
+
+ +
+
+ +

◆ kLg32Bits

+ +
+
+ + + + +
const uint16_t kLg32Bits = 32
+
+ +
+
+ +

◆ kLgBits

+ +
+
+ + + + +
const uint16_t kLgBits = 28
+
+ +
+
+ +

◆ kLgDefaultRepeat

+ +
+
+ + + + +
const uint16_t kLgDefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kLutronBits

+ +
+
+ + + + +
const uint16_t kLutronBits = 35
+
+ +
+
+ +

◆ kMagiquestBits

+ +
+
+ + + + +
const uint16_t kMagiquestBits = 56
+
+ +
+
+ +

◆ kMidea24Bits

+ +
+
+ + + + +
const uint16_t kMidea24Bits = 24
+
+ +
+
+ +

◆ kMidea24MinRepeat

+ +
+
+ + + + +
const uint16_t kMidea24MinRepeat = kSingleRepeat
+
+ +
+
+ +

◆ kMideaBits

+ +
+
+ + + + +
const uint16_t kMideaBits = 48
+
+ +
+
+ +

◆ kMideaMinRepeat

+ +
+
+ + + + +
const uint16_t kMideaMinRepeat = kNoRepeat
+
+ +
+
+ +

◆ kMitsubishi112Bits

+ +
+
+ + + + +
const uint16_t kMitsubishi112Bits = kMitsubishi112StateLength * 8
+
+ +
+
+ +

◆ kMitsubishi112MinRepeat

+ +
+
+ + + + +
const uint16_t kMitsubishi112MinRepeat = kNoRepeat
+
+ +
+
+ +

◆ kMitsubishi112StateLength

+ +
+
+ + + + +
const uint16_t kMitsubishi112StateLength = 14
+
+ +
+
+ +

◆ kMitsubishi136Bits

+ +
+
+ + + + +
const uint16_t kMitsubishi136Bits = kMitsubishi136StateLength * 8
+
+ +
+
+ +

◆ kMitsubishi136MinRepeat

+ +
+
+ + + + +
const uint16_t kMitsubishi136MinRepeat = kNoRepeat
+
+ +
+
+ +

◆ kMitsubishi136StateLength

+ +
+
+ + + + +
const uint16_t kMitsubishi136StateLength = 17
+
+ +
+
+ +

◆ kMitsubishiACBits

+ +
+
+ + + + +
const uint16_t kMitsubishiACBits = kMitsubishiACStateLength * 8
+
+ +
+
+ +

◆ kMitsubishiACMinRepeat

+ +
+
+ + + + +
const uint16_t kMitsubishiACMinRepeat = kSingleRepeat
+
+ +
+
+ +

◆ kMitsubishiACStateLength

+ +
+
+ + + + +
const uint16_t kMitsubishiACStateLength = 18
+
+ +
+
+ +

◆ kMitsubishiBits

+ +
+
+ + + + +
const uint16_t kMitsubishiBits = 16
+
+ +
+
+ +

◆ kMitsubishiHeavy152Bits

+ +
+
+ + + + +
const uint16_t kMitsubishiHeavy152Bits = kMitsubishiHeavy152StateLength * 8
+
+ +
+
+ +

◆ kMitsubishiHeavy152MinRepeat

+ +
+
+ + + + +
const uint16_t kMitsubishiHeavy152MinRepeat = kNoRepeat
+
+ +
+
+ +

◆ kMitsubishiHeavy152StateLength

+ +
+
+ + + + +
const uint16_t kMitsubishiHeavy152StateLength = 19
+
+ +
+
+ +

◆ kMitsubishiHeavy88Bits

+ +
+
+ + + + +
const uint16_t kMitsubishiHeavy88Bits = kMitsubishiHeavy88StateLength * 8
+
+ +
+
+ +

◆ kMitsubishiHeavy88MinRepeat

+ +
+
+ + + + +
const uint16_t kMitsubishiHeavy88MinRepeat = kNoRepeat
+
+ +
+
+ +

◆ kMitsubishiHeavy88StateLength

+ +
+
+ + + + +
const uint16_t kMitsubishiHeavy88StateLength = 11
+
+ +
+
+ +

◆ kMitsubishiMinRepeat

+ +
+
+ + + + +
const uint16_t kMitsubishiMinRepeat = kSingleRepeat
+
+ +
+
+ +

◆ kMultibracketsBits

+ +
+
+ + + + +
const uint16_t kMultibracketsBits = 8
+
+ +
+
+ +

◆ kMultibracketsDefaultRepeat

+ +
+
+ + + + +
const uint16_t kMultibracketsDefaultRepeat = kSingleRepeat
+
+ +
+
+ +

◆ kNECBits

+ +
+
+ + + + +
const uint16_t kNECBits = 32
+
+ +
+
+ +

◆ kNeoclimaBits

+ +
+
+ + + + +
const uint16_t kNeoclimaBits = kNeoclimaStateLength * 8
+
+ +
+
+ +

◆ kNeoclimaMinRepeat

+ +
+
+ + + + +
const uint16_t kNeoclimaMinRepeat = kNoRepeat
+
+ +
+
+ +

◆ kNeoclimaStateLength

+ +
+
+ + + + +
const uint16_t kNeoclimaStateLength = 12
+
+ +
+
+ +

◆ kNikaiBits

+ +
+
+ + + + +
const uint16_t kNikaiBits = 24
+
+ +
+
+ +

◆ kNoRepeat

+ +
+
+ + + + +
const uint16_t kNoRepeat = 0
+
+ +
+
+ +

◆ kPanasonicAcBits

+ +
+
+ + + + +
const uint16_t kPanasonicAcBits = kPanasonicAcStateLength * 8
+
+ +
+
+ +

◆ kPanasonicAcDefaultRepeat

+ +
+
+ + + + +
const uint16_t kPanasonicAcDefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kPanasonicAcShortBits

+ +
+
+ + + + +
const uint16_t kPanasonicAcShortBits = kPanasonicAcStateShortLength * 8
+
+ +
+
+ +

◆ kPanasonicAcStateLength

+ +
+
+ + + + +
const uint16_t kPanasonicAcStateLength = 27
+
+ +
+
+ +

◆ kPanasonicAcStateShortLength

+ +
+
+ + + + +
const uint16_t kPanasonicAcStateShortLength = 16
+
+ +
+
+ +

◆ kPanasonicBits

+ +
+
+ + + + +
const uint16_t kPanasonicBits = 48
+
+ +
+
+ +

◆ kPanasonicManufacturer

+ +
+
+ + + + +
const uint32_t kPanasonicManufacturer = 0x4004
+
+ +
+
+ +

◆ kPioneerBits

+ +
+
+ + + + +
const uint16_t kPioneerBits = 64
+
+ +
+
+ +

◆ kProntoMinLength

+ +
+
+ + + + +
const uint16_t kProntoMinLength = 6
+
+ +
+
+ +

◆ kRC5Bits

+ +
+
+ + + + +
const uint16_t kRC5Bits = kRC5RawBits - 2
+
+ +
+
+ +

◆ kRC5RawBits

+ +
+
+ + + + +
const uint16_t kRC5RawBits = 14
+
+ +
+
+ +

◆ kRC5XBits

+ +
+
+ + + + +
const uint16_t kRC5XBits = kRC5RawBits - 1
+
+ +
+
+ +

◆ kRC6_36Bits

+ +
+
+ + + + +
const uint16_t kRC6_36Bits = 36
+
+ +
+
+ +

◆ kRC6Mode0Bits

+ +
+
+ + + + +
const uint16_t kRC6Mode0Bits = 20
+
+ +
+
+ +

◆ kRCMMBits

+ +
+
+ + + + +
const uint16_t kRCMMBits = 24
+
+ +
+
+ +

◆ kSamsung36Bits

+ +
+
+ + + + +
const uint16_t kSamsung36Bits = 36
+
+ +
+
+ +

◆ kSamsungAcBits

+ +
+
+ + + + +
const uint16_t kSamsungAcBits = kSamsungAcStateLength * 8
+
+ +
+
+ +

◆ kSamsungAcDefaultRepeat

+ +
+
+ + + + +
const uint16_t kSamsungAcDefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kSamsungAcExtendedBits

+ +
+
+ + + + +
const uint16_t kSamsungAcExtendedBits = kSamsungAcExtendedStateLength * 8
+
+ +
+
+ +

◆ kSamsungAcExtendedStateLength

+ +
+
+ + + + +
const uint16_t kSamsungAcExtendedStateLength = 21
+
+ +
+
+ +

◆ kSamsungAcStateLength

+ +
+
+ + + + +
const uint16_t kSamsungAcStateLength = 14
+
+ +
+
+ +

◆ kSamsungBits

+ +
+
+ + + + +
const uint16_t kSamsungBits = 32
+
+ +
+
+ +

◆ kSanyoLC7461AddressBits

+ +
+
+ + + + +
const uint16_t kSanyoLC7461AddressBits = 13
+
+ +
+
+ +

◆ kSanyoLC7461Bits

+ +
+
+ + + + +
const uint16_t kSanyoLC7461Bits
+
+Initial value: +
+
+ +

◆ kSanyoLC7461CommandBits

+ +
+
+ + + + +
const uint16_t kSanyoLC7461CommandBits = 8
+
+ +
+
+ +

◆ kSanyoSA8650BBits

+ +
+
+ + + + +
const uint16_t kSanyoSA8650BBits = 12
+
+ +
+
+ +

◆ kSharpAcBits

+ +
+
+ + + + +
const uint16_t kSharpAcBits = kSharpAcStateLength * 8
+
+ +
+
+ +

◆ kSharpAcDefaultRepeat

+ +
+
+ + + + +
const uint16_t kSharpAcDefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kSharpAcStateLength

+ +
+
+ + + + +
const uint16_t kSharpAcStateLength = 13
+
+ +
+
+ +

◆ kSharpAddressBits

+ +
+
+ + + + +
const uint8_t kSharpAddressBits = 5
+
+ +
+
+ +

◆ kSharpBits

+ +
+
+ + + + +
const uint16_t kSharpBits = kSharpAddressBits + kSharpCommandBits + 2
+
+ +
+
+ +

◆ kSharpCommandBits

+ +
+
+ + + + +
const uint8_t kSharpCommandBits = 8
+
+ +
+
+ +

◆ kSherwoodBits

+ +
+
+ + + + +
const uint8_t kSherwoodBits = kNECBits
+
+ +
+
+ +

◆ kSherwoodMinRepeat

+ +
+
+ + + + +
const uint16_t kSherwoodMinRepeat = kSingleRepeat
+
+ +
+
+ +

◆ kSingleRepeat

+ +
+
+ + + + +
const uint16_t kSingleRepeat = 1
+
+ +
+
+ +

◆ kSony12Bits

+ +
+
+ + + + +
const uint16_t kSony12Bits = 12
+
+ +
+
+ +

◆ kSony15Bits

+ +
+
+ + + + +
const uint16_t kSony15Bits = 15
+
+ +
+
+ +

◆ kSony20Bits

+ +
+
+ + + + +
const uint16_t kSony20Bits = 20
+
+ +
+
+ +

◆ kSonyMinBits

+ +
+
+ + + + +
const uint16_t kSonyMinBits = 12
+
+ +
+
+ +

◆ kSonyMinRepeat

+ +
+
+ + + + +
const uint16_t kSonyMinRepeat = 2
+
+ +
+
+ +

◆ kSymphonyBits

+ +
+
+ + + + +
const uint16_t kSymphonyBits = 12
+
+ +
+
+ +

◆ kSymphonyDefaultRepeat

+ +
+
+ + + + +
const uint16_t kSymphonyDefaultRepeat = 3
+
+ +
+
+ +

◆ kTcl112AcBits

+ +
+
+ + + + +
const uint16_t kTcl112AcBits = kTcl112AcStateLength * 8
+
+ +
+
+ +

◆ kTcl112AcDefaultRepeat

+ +
+
+ + + + +
const uint16_t kTcl112AcDefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kTcl112AcStateLength

+ +
+
+ + + + +
const uint16_t kTcl112AcStateLength = 14
+
+ +
+
+ +

◆ kTecoBits

+ +
+
+ + + + +
const uint16_t kTecoBits = 35
+
+ +
+
+ +

◆ kTecoDefaultRepeat

+ +
+
+ + + + +
const uint16_t kTecoDefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kToshibaACBits

+ +
+
+ + + + +
const uint16_t kToshibaACBits = kToshibaACStateLength * 8
+
+ +
+
+ +

◆ kToshibaACMinRepeat

+ +
+
+ + + + +
const uint16_t kToshibaACMinRepeat = kSingleRepeat
+
+ +
+
+ +

◆ kToshibaACStateLength

+ +
+
+ + + + +
const uint16_t kToshibaACStateLength = 9
+
+ +
+
+ +

◆ kTrotecBits

+ +
+
+ + + + +
const uint16_t kTrotecBits = kTrotecStateLength * 8
+
+ +
+
+ +

◆ kTrotecDefaultRepeat

+ +
+
+ + + + +
const uint16_t kTrotecDefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kTrotecStateLength

+ +
+
+ + + + +
const uint16_t kTrotecStateLength = 9
+
+ +
+
+ +

◆ kVestelAcBits

+ +
+
+ + + + +
const uint8_t kVestelAcBits = 56
+
+ +
+
+ +

◆ kWhirlpoolAcBits

+ +
+
+ + + + +
const uint16_t kWhirlpoolAcBits = kWhirlpoolAcStateLength * 8
+
+ +
+
+ +

◆ kWhirlpoolAcDefaultRepeat

+ +
+
+ + + + +
const uint16_t kWhirlpoolAcDefaultRepeat = kNoRepeat
+
+ +
+
+ +

◆ kWhirlpoolAcStateLength

+ +
+
+ + + + +
const uint16_t kWhirlpoolAcStateLength = 21
+
+ +
+
+ +

◆ kWhynterBits

+ +
+
+ + + + +
const uint16_t kWhynterBits = 32
+
+ +
+
+ +

◆ kZepealBits

+ +
+
+ + + + +
const uint16_t kZepealBits = 16
+
+ +
+
+ +

◆ kZepealMinRepeat

+ +
+
+ + + + +
const uint16_t kZepealMinRepeat = 4
+
+ +
+
+
+
const uint16_t kSanyoLC7461CommandBits
Definition: IRremoteESP8266.h:976
+
const uint16_t kSanyoLC7461AddressBits
Definition: IRremoteESP8266.h:975
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRremoteESP8266_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRremoteESP8266_8h_source.html new file mode 100644 index 000000000..42c1af80b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRremoteESP8266_8h_source.html @@ -0,0 +1,1463 @@ + + + + + + + +IRremoteESP8266: src/IRremoteESP8266.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
IRremoteESP8266.h
+
+
+Go to the documentation of this file.
1  /***************************************************
+
2  * IRremote for ESP8266
+
3  *
+
4  * Based on the IRremote library for Arduino by Ken Shirriff
+
5  * Version 0.11 August, 2009
+
6  * Copyright 2009 Ken Shirriff
+
7  * For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html
+
8  *
+
9  * Edited by Mitra to add new controller SANYO
+
10  *
+
11  * Interrupt code based on NECIRrcv by Joe Knapp
+
12  * http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556
+
13  * Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/
+
14  *
+
15  * JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
+
16  * LG added by Darryl Smith (based on the JVC protocol)
+
17  * Whynter A/C ARC-110WD added by Francesco Meschia
+
18  * Coolix A/C / heatpump added by (send) bakrus & (decode) crankyoldgit
+
19  * Denon: sendDenon, decodeDenon added by Massimiliano Pinto
+
20  (from https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Denon.cpp)
+
21  * Kelvinator A/C and Sherwood added by crankyoldgit
+
22  * Mitsubishi (TV) sending added by crankyoldgit
+
23  * Pronto code sending added by crankyoldgit
+
24  * Mitsubishi & Toshiba A/C added by crankyoldgit
+
25  * (derived from https://github.com/r45635/HVAC-IR-Control)
+
26  * DISH decode by marcosamarinho
+
27  * Gree Heatpump sending added by Ville Skyttä (scop)
+
28  * (derived from https://github.com/ToniA/arduino-heatpumpir/blob/master/GreeHeatpumpIR.cpp)
+
29  * Updated by markszabo (https://github.com/crankyoldgit/IRremoteESP8266) for sending IR code on ESP8266
+
30  * Updated by Sebastien Warin (http://sebastien.warin.fr) for receiving IR code on ESP8266
+
31  *
+
32  * Updated by sillyfrog for Daikin, adopted from
+
33  * (https://github.com/mharizanov/Daikin-AC-remote-control-over-the-Internet/)
+
34  * Fujitsu A/C code added by jonnygraham
+
35  * Trotec AC code by stufisher
+
36  * Carrier & Haier AC code by crankyoldgit
+
37  * Vestel AC code by Erdem U. Altınyurt
+
38  * Teco AC code by Fabien Valthier (hcoohb)
+
39  * Mitsubishi 112 AC Code by kuchel77
+
40  *
+
41  * GPL license, all text above must be included in any redistribution
+
42  ****************************************************/
+
43 
+
44 #ifndef IRREMOTEESP8266_H_
+
45 #define IRREMOTEESP8266_H_
+
46 
+
47 #define __STDC_LIMIT_MACROS
+
48 #include <stdint.h>
+
49 #ifdef UNIT_TEST
+
50 #include <iostream>
+
51 #include <string>
+
52 #endif // UNIT_TEST
+
53 
+
54 // Library Version
+
55 #define _IRREMOTEESP8266_VERSION_ "2.7.7"
+
56 
+
57 // Set the language & locale for the library. See the `locale` dir for options.
+
58 #ifndef _IR_LOCALE_
+
59 #define _IR_LOCALE_ en-AU
+
60 #endif // _IR_LOCALE_
+
61 
+
62 // Do we enable all the protocols by default (true), or disable them (false)?
+
63 // This allows users of the library to disable or enable all protocols at
+
64 // compile-time with `-D_IR_ENABLE_DEFAULT_=true` or
+
65 // `-D_IR_ENABLE_DEFAULT_=false` compiler flags respectively.
+
66 // Everything is included by default.
+
67 // e.g. If you only want to enable use of he NEC protocol to save program space,
+
68 // you would use something like:
+
69 // `-D_IR_ENABLE_DEFAULT_=false -DDECODE_NEC=true -DSEND_NEC=true`
+
70 //
+
71 // or alter your 'platform.ini' file accordingly:
+
72 // ```
+
73 // build_flags = -D_IR_ENABLE_DEFAULT_=false
+
74 // -DDECODE_NEC=true
+
75 // -DSEND_NEC=true
+
76 // ```
+
77 // If you want to enable support for every protocol *except* _decoding_ the
+
78 // Kelvinator protocol, you would use:
+
79 // `-DDECODE_KELVINATOR=false`
+
80 #ifndef _IR_ENABLE_DEFAULT_
+
81 #define _IR_ENABLE_DEFAULT_ true // Unless set externally, the default is on.
+
82 #endif // _IR_ENABLE_DEFAULT_
+
83 
+
84 // Supported IR protocols
+
85 // Each protocol you include costs memory and, during decode, costs time
+
86 // Disable (set to false) all the protocols you do not need/want!
+
87 // The Air Conditioner protocols are the most expensive memory-wise.
+
88 //
+
89 
+
90 // Semi-unique code for unknown messages
+
91 #ifndef DECODE_HASH
+
92 #define DECODE_HASH _IR_ENABLE_DEFAULT_
+
93 #endif // DECODE_HASH
+
94 
+
95 #ifndef SEND_RAW
+
96 #define SEND_RAW _IR_ENABLE_DEFAULT_
+
97 #endif // SEND_RAW
+
98 
+
99 #ifndef DECODE_NEC
+
100 #define DECODE_NEC _IR_ENABLE_DEFAULT_
+
101 #endif // DECODE_NEC
+
102 #ifndef SEND_NEC
+
103 #define SEND_NEC _IR_ENABLE_DEFAULT_
+
104 #endif // SEND_NEC
+
105 
+
106 #ifndef DECODE_SHERWOOD
+
107 #define DECODE_SHERWOOD false // Not applicable. Actually is DECODE_NEC
+
108 #endif // DECODE_SHERWOOD
+
109 #ifndef SEND_SHERWOOD
+
110 #define SEND_SHERWOOD _IR_ENABLE_DEFAULT_
+
111 #endif // SEND_SHERWOOD
+
112 
+
113 #ifndef DECODE_RC5
+
114 #define DECODE_RC5 _IR_ENABLE_DEFAULT_
+
115 #endif // DECODE_RC5
+
116 #ifndef SEND_RC5
+
117 #define SEND_RC5 _IR_ENABLE_DEFAULT_
+
118 #endif // SEND_RC5
+
119 
+
120 #ifndef DECODE_RC6
+
121 #define DECODE_RC6 _IR_ENABLE_DEFAULT_
+
122 #endif // DECODE_RC6
+
123 #ifndef SEND_RC6
+
124 #define SEND_RC6 _IR_ENABLE_DEFAULT_
+
125 #endif // SEND_RC6
+
126 
+
127 #ifndef DECODE_RCMM
+
128 #define DECODE_RCMM _IR_ENABLE_DEFAULT_
+
129 #endif // DECODE_RCMM
+
130 #ifndef SEND_RCMM
+
131 #define SEND_RCMM _IR_ENABLE_DEFAULT_
+
132 #endif // SEND_RCMM
+
133 
+
134 #ifndef DECODE_SONY
+
135 #define DECODE_SONY _IR_ENABLE_DEFAULT_
+
136 #endif // DECODE_SONY
+
137 #ifndef SEND_SONY
+
138 #define SEND_SONY _IR_ENABLE_DEFAULT_
+
139 #endif // SEND_SONY
+
140 
+
141 #ifndef DECODE_PANASONIC
+
142 #define DECODE_PANASONIC _IR_ENABLE_DEFAULT_
+
143 #endif // DECODE_PANASONIC
+
144 #ifndef SEND_PANASONIC
+
145 #define SEND_PANASONIC _IR_ENABLE_DEFAULT_
+
146 #endif // SEND_PANASONIC
+
147 
+
148 #ifndef DECODE_JVC
+
149 #define DECODE_JVC _IR_ENABLE_DEFAULT_
+
150 #endif // DECODE_JVC
+
151 #ifndef SEND_JVC
+
152 #define SEND_JVC _IR_ENABLE_DEFAULT_
+
153 #endif // SEND_JVC
+
154 
+
155 #ifndef DECODE_SAMSUNG
+
156 #define DECODE_SAMSUNG _IR_ENABLE_DEFAULT_
+
157 #endif // DECODE_SAMSUNG
+
158 #ifndef SEND_SAMSUNG
+
159 #define SEND_SAMSUNG _IR_ENABLE_DEFAULT_
+
160 #endif // SEND_SAMSUNG
+
161 
+
162 #ifndef DECODE_SAMSUNG36
+
163 #define DECODE_SAMSUNG36 _IR_ENABLE_DEFAULT_
+
164 #endif // DECODE_SAMSUNG36
+
165 #ifndef SEND_SAMSUNG36
+
166 #define SEND_SAMSUNG36 _IR_ENABLE_DEFAULT_
+
167 #endif // SEND_SAMSUNG36
+
168 
+
169 #ifndef DECODE_SAMSUNG_AC
+
170 #define DECODE_SAMSUNG_AC _IR_ENABLE_DEFAULT_
+
171 #endif // DECODE_SAMSUNG_AC
+
172 #ifndef SEND_SAMSUNG_AC
+
173 #define SEND_SAMSUNG_AC _IR_ENABLE_DEFAULT_
+
174 #endif // SEND_SAMSUNG_AC
+
175 
+
176 #ifndef DECODE_WHYNTER
+
177 #define DECODE_WHYNTER _IR_ENABLE_DEFAULT_
+
178 #endif // DECODE_WHYNTER
+
179 #ifndef SEND_WHYNTER
+
180 #define SEND_WHYNTER _IR_ENABLE_DEFAULT_
+
181 #endif // SEND_WHYNTER
+
182 
+
183 #ifndef DECODE_AIWA_RC_T501
+
184 #define DECODE_AIWA_RC_T501 _IR_ENABLE_DEFAULT_
+
185 #endif // DECODE_AIWA_RC_T501
+
186 #ifndef SEND_AIWA_RC_T501
+
187 #define SEND_AIWA_RC_T501 _IR_ENABLE_DEFAULT_
+
188 #endif // SEND_AIWA_RC_T501
+
189 
+
190 #ifndef DECODE_LG
+
191 #define DECODE_LG _IR_ENABLE_DEFAULT_
+
192 #endif // DECODE_LG
+
193 #ifndef SEND_LG
+
194 #define SEND_LG _IR_ENABLE_DEFAULT_
+
195 #endif // SEND_LG
+
196 
+
197 #ifndef DECODE_SANYO
+
198 #define DECODE_SANYO _IR_ENABLE_DEFAULT_
+
199 #endif // DECODE_SANYO
+
200 #ifndef SEND_SANYO
+
201 #define SEND_SANYO _IR_ENABLE_DEFAULT_
+
202 #endif // SEND_SANYO
+
203 
+
204 #ifndef DECODE_MITSUBISHI
+
205 #define DECODE_MITSUBISHI _IR_ENABLE_DEFAULT_
+
206 #endif // DECODE_MITSUBISHI
+
207 #ifndef SEND_MITSUBISHI
+
208 #define SEND_MITSUBISHI _IR_ENABLE_DEFAULT_
+
209 #endif // SEND_MITSUBISHI
+
210 
+
211 #ifndef DECODE_MITSUBISHI2
+
212 #define DECODE_MITSUBISHI2 _IR_ENABLE_DEFAULT_
+
213 #endif // DECODE_MITSUBISHI2
+
214 #ifndef SEND_MITSUBISHI2
+
215 #define SEND_MITSUBISHI2 _IR_ENABLE_DEFAULT_
+
216 #endif // SEND_MITSUBISHI2
+
217 
+
218 #ifndef DECODE_DISH
+
219 #define DECODE_DISH _IR_ENABLE_DEFAULT_
+
220 #endif // DECODE_DISH
+
221 #ifndef SEND_DISH
+
222 #define SEND_DISH _IR_ENABLE_DEFAULT_
+
223 #endif // SEND_DISH
+
224 
+
225 #ifndef DECODE_SHARP
+
226 #define DECODE_SHARP _IR_ENABLE_DEFAULT_
+
227 #endif // DECODE_SHARP
+
228 #ifndef SEND_SHARP
+
229 #define SEND_SHARP _IR_ENABLE_DEFAULT_
+
230 #endif // SEND_SHARP
+
231 
+
232 #ifndef DECODE_SHARP_AC
+
233 #define DECODE_SHARP_AC _IR_ENABLE_DEFAULT_
+
234 #endif // DECODE_SHARP_AC
+
235 #ifndef SEND_SHARP_AC
+
236 #define SEND_SHARP_AC _IR_ENABLE_DEFAULT_
+
237 #endif // SEND_SHARP_AC
+
238 
+
239 #ifndef DECODE_DENON
+
240 #define DECODE_DENON _IR_ENABLE_DEFAULT_
+
241 #endif // DECODE_DENON
+
242 #ifndef SEND_DENON
+
243 #define SEND_DENON _IR_ENABLE_DEFAULT_
+
244 #endif // SEND_DENON
+
245 
+
246 #ifndef DECODE_KELVINATOR
+
247 #define DECODE_KELVINATOR _IR_ENABLE_DEFAULT_
+
248 #endif // DECODE_KELVINATOR
+
249 #ifndef SEND_KELVINATOR
+
250 #define SEND_KELVINATOR _IR_ENABLE_DEFAULT_
+
251 #endif // SEND_KELVINATOR
+
252 
+
253 #ifndef DECODE_MITSUBISHI_AC
+
254 #define DECODE_MITSUBISHI_AC _IR_ENABLE_DEFAULT_
+
255 #endif // DECODE_MITSUBISHI_AC
+
256 #ifndef SEND_MITSUBISHI_AC
+
257 #define SEND_MITSUBISHI_AC _IR_ENABLE_DEFAULT_
+
258 #endif // SEND_MITSUBISHI_AC
+
259 
+
260 #ifndef DECODE_MITSUBISHI136
+
261 #define DECODE_MITSUBISHI136 _IR_ENABLE_DEFAULT_
+
262 #endif // DECODE_MITSUBISHI136
+
263 #ifndef SEND_MITSUBISHI136
+
264 #define SEND_MITSUBISHI136 _IR_ENABLE_DEFAULT_
+
265 #endif // SEND_MITSUBISHI136
+
266 
+
267 #ifndef DECODE_MITSUBISHI112
+
268 #define DECODE_MITSUBISHI112 _IR_ENABLE_DEFAULT_
+
269 #endif // DECODE_MITSUBISHI112
+
270 #ifndef SEND_MITSUBISHI112
+
271 #define SEND_MITSUBISHI112 _IR_ENABLE_DEFAULT_
+
272 #endif // SEND_MITSUBISHI112
+
273 
+
274 #ifndef DECODE_FUJITSU_AC
+
275 #define DECODE_FUJITSU_AC _IR_ENABLE_DEFAULT_
+
276 #endif // DECODE_FUJITSU_AC
+
277 #ifndef SEND_FUJITSU_AC
+
278 #define SEND_FUJITSU_AC _IR_ENABLE_DEFAULT_
+
279 #endif // SEND_FUJITSU_AC
+
280 
+
281 #ifndef DECODE_INAX
+
282 #define DECODE_INAX _IR_ENABLE_DEFAULT_
+
283 #endif // DECODE_INAX
+
284 #ifndef SEND_INAX
+
285 #define SEND_INAX _IR_ENABLE_DEFAULT_
+
286 #endif // SEND_INAX
+
287 
+
288 #ifndef DECODE_DAIKIN
+
289 #define DECODE_DAIKIN _IR_ENABLE_DEFAULT_
+
290 #endif // DECODE_DAIKIN
+
291 #ifndef SEND_DAIKIN
+
292 #define SEND_DAIKIN _IR_ENABLE_DEFAULT_
+
293 #endif // SEND_DAIKIN
+
294 
+
295 #ifndef DECODE_COOLIX
+
296 #define DECODE_COOLIX _IR_ENABLE_DEFAULT_
+
297 #endif // DECODE_COOLIX
+
298 #ifndef SEND_COOLIX
+
299 #define SEND_COOLIX _IR_ENABLE_DEFAULT_
+
300 #endif // SEND_COOLIX
+
301 
+
302 #ifndef DECODE_GLOBALCACHE
+
303 #define DECODE_GLOBALCACHE false // Not applicable.
+
304 #endif // DECODE_GLOBALCACHE
+
305 #ifndef SEND_GLOBALCACHE
+
306 #define SEND_GLOBALCACHE _IR_ENABLE_DEFAULT_
+
307 #endif // SEND_GLOBALCACHE
+
308 
+
309 #ifndef DECODE_GOODWEATHER
+
310 #define DECODE_GOODWEATHER _IR_ENABLE_DEFAULT_
+
311 #endif // DECODE_GOODWEATHER
+
312 #ifndef SEND_GOODWEATHER
+
313 #define SEND_GOODWEATHER _IR_ENABLE_DEFAULT_
+
314 #endif // SEND_GOODWEATHER
+
315 
+
316 #ifndef DECODE_GREE
+
317 #define DECODE_GREE _IR_ENABLE_DEFAULT_
+
318 #endif // DECODE_GREE
+
319 #ifndef SEND_GREE
+
320 #define SEND_GREE _IR_ENABLE_DEFAULT_
+
321 #endif // SEND_GREE
+
322 
+
323 #ifndef DECODE_PRONTO
+
324 #define DECODE_PRONTO false // Not applicable.
+
325 #endif // DECODE_PRONTO
+
326 #ifndef SEND_PRONTO
+
327 #define SEND_PRONTO _IR_ENABLE_DEFAULT_
+
328 #endif // SEND_PRONTO
+
329 
+
330 #ifndef DECODE_ARGO
+
331 #define DECODE_ARGO _IR_ENABLE_DEFAULT_
+
332 #endif // DECODE_ARGO
+
333 #ifndef SEND_ARGO
+
334 #define SEND_ARGO _IR_ENABLE_DEFAULT_
+
335 #endif // SEND_ARGO
+
336 
+
337 #ifndef DECODE_TROTEC
+
338 #define DECODE_TROTEC _IR_ENABLE_DEFAULT_
+
339 #endif // DECODE_TROTEC
+
340 #ifndef SEND_TROTEC
+
341 #define SEND_TROTEC _IR_ENABLE_DEFAULT_
+
342 #endif // SEND_TROTEC
+
343 
+
344 #ifndef DECODE_NIKAI
+
345 #define DECODE_NIKAI _IR_ENABLE_DEFAULT_
+
346 #endif // DECODE_NIKAI
+
347 #ifndef SEND_NIKAI
+
348 #define SEND_NIKAI _IR_ENABLE_DEFAULT_
+
349 #endif // SEND_NIKAI
+
350 
+
351 #ifndef DECODE_TOSHIBA_AC
+
352 #define DECODE_TOSHIBA_AC _IR_ENABLE_DEFAULT_
+
353 #endif // DECODE_TOSHIBA_AC
+
354 #ifndef SEND_TOSHIBA_AC
+
355 #define SEND_TOSHIBA_AC _IR_ENABLE_DEFAULT_
+
356 #endif // SEND_TOSHIBA_AC
+
357 
+
358 #ifndef DECODE_MAGIQUEST
+
359 #define DECODE_MAGIQUEST _IR_ENABLE_DEFAULT_
+
360 #endif // DECODE_MAGIQUEST
+
361 #ifndef SEND_MAGIQUEST
+
362 #define SEND_MAGIQUEST _IR_ENABLE_DEFAULT_
+
363 #endif // SEND_MAGIQUEST
+
364 
+
365 #ifndef DECODE_MIDEA
+
366 #define DECODE_MIDEA _IR_ENABLE_DEFAULT_
+
367 #endif // DECODE_MIDEA
+
368 #ifndef SEND_MIDEA
+
369 #define SEND_MIDEA _IR_ENABLE_DEFAULT_
+
370 #endif // SEND_MIDEA
+
371 
+
372 #ifndef DECODE_MIDEA24
+
373 #define DECODE_MIDEA24 _IR_ENABLE_DEFAULT_
+
374 #endif // DECODE_MIDEA24
+
375 #ifndef SEND_MIDEA24
+
376 #define SEND_MIDEA24 _IR_ENABLE_DEFAULT_
+
377 #endif // SEND_MIDEA24
+
378 
+
379 #ifndef DECODE_LASERTAG
+
380 #define DECODE_LASERTAG _IR_ENABLE_DEFAULT_
+
381 #endif // DECODE_LASERTAG
+
382 #ifndef SEND_LASERTAG
+
383 #define SEND_LASERTAG _IR_ENABLE_DEFAULT_
+
384 #endif // SEND_LASERTAG
+
385 
+
386 #ifndef DECODE_CARRIER_AC
+
387 #define DECODE_CARRIER_AC _IR_ENABLE_DEFAULT_
+
388 #endif // DECODE_CARRIER_AC
+
389 #ifndef SEND_CARRIER_AC
+
390 #define SEND_CARRIER_AC _IR_ENABLE_DEFAULT_
+
391 #endif // SEND_CARRIER_AC
+
392 
+
393 #ifndef DECODE_CARRIER_AC40
+
394 #define DECODE_CARRIER_AC40 _IR_ENABLE_DEFAULT_
+
395 #endif // DECODE_CARRIER_AC40
+
396 #ifndef SEND_CARRIER_AC40
+
397 #define SEND_CARRIER_AC40 _IR_ENABLE_DEFAULT_
+
398 #endif // SEND_CARRIER_AC40
+
399 
+
400 #ifndef DECODE_CARRIER_AC64
+
401 #define DECODE_CARRIER_AC64 _IR_ENABLE_DEFAULT_
+
402 #endif // DECODE_CARRIER_AC64
+
403 #ifndef SEND_CARRIER_AC64
+
404 #define SEND_CARRIER_AC64 _IR_ENABLE_DEFAULT_
+
405 #endif // SEND_CARRIER_AC64
+
406 
+
407 #ifndef DECODE_HAIER_AC
+
408 #define DECODE_HAIER_AC _IR_ENABLE_DEFAULT_
+
409 #endif // DECODE_HAIER_AC
+
410 #ifndef SEND_HAIER_AC
+
411 #define SEND_HAIER_AC _IR_ENABLE_DEFAULT_
+
412 #endif // SEND_HAIER_AC
+
413 
+
414 #ifndef DECODE_HITACHI_AC
+
415 #define DECODE_HITACHI_AC _IR_ENABLE_DEFAULT_
+
416 #endif // DECODE_HITACHI_AC
+
417 #ifndef SEND_HITACHI_AC
+
418 #define SEND_HITACHI_AC _IR_ENABLE_DEFAULT_
+
419 #endif // SEND_HITACHI_AC
+
420 
+
421 #ifndef DECODE_HITACHI_AC1
+
422 #define DECODE_HITACHI_AC1 _IR_ENABLE_DEFAULT_
+
423 #endif // DECODE_HITACHI_AC1
+
424 #ifndef SEND_HITACHI_AC1
+
425 #define SEND_HITACHI_AC1 _IR_ENABLE_DEFAULT_
+
426 #endif // SEND_HITACHI_AC1
+
427 
+
428 #ifndef DECODE_HITACHI_AC2
+
429 #define DECODE_HITACHI_AC2 _IR_ENABLE_DEFAULT_
+
430 #endif // DECODE_HITACHI_AC2
+
431 #ifndef SEND_HITACHI_AC2
+
432 #define SEND_HITACHI_AC2 _IR_ENABLE_DEFAULT_
+
433 #endif // SEND_HITACHI_AC2
+
434 
+
435 #ifndef DECODE_HITACHI_AC3
+
436 #define DECODE_HITACHI_AC3 _IR_ENABLE_DEFAULT_
+
437 #endif // DECODE_HITACHI_AC3
+
438 #ifndef SEND_HITACHI_AC3
+
439 #define SEND_HITACHI_AC3 _IR_ENABLE_DEFAULT_
+
440 #endif // SEND_HITACHI_AC3
+
441 
+
442 #ifndef DECODE_HITACHI_AC344
+
443 #define DECODE_HITACHI_AC344 _IR_ENABLE_DEFAULT_
+
444 #endif // DECODE_HITACHI_AC344
+
445 #ifndef SEND_HITACHI_AC344
+
446 #define SEND_HITACHI_AC344 _IR_ENABLE_DEFAULT_
+
447 #endif // SEND_HITACHI_AC344
+
448 
+
449 #ifndef DECODE_HITACHI_AC424
+
450 #define DECODE_HITACHI_AC424 _IR_ENABLE_DEFAULT_
+
451 #endif // DECODE_HITACHI_AC424
+
452 #ifndef SEND_HITACHI_AC424
+
453 #define SEND_HITACHI_AC424 _IR_ENABLE_DEFAULT_
+
454 #endif // SEND_HITACHI_AC424
+
455 
+
456 #ifndef DECODE_GICABLE
+
457 #define DECODE_GICABLE _IR_ENABLE_DEFAULT_
+
458 #endif // DECODE_GICABLE
+
459 #ifndef SEND_GICABLE
+
460 #define SEND_GICABLE _IR_ENABLE_DEFAULT_
+
461 #endif // SEND_GICABLE
+
462 
+
463 #ifndef DECODE_HAIER_AC_YRW02
+
464 #define DECODE_HAIER_AC_YRW02 _IR_ENABLE_DEFAULT_
+
465 #endif // DECODE_HAIER_AC_YRW02
+
466 #ifndef SEND_HAIER_AC_YRW02
+
467 #define SEND_HAIER_AC_YRW02 _IR_ENABLE_DEFAULT_
+
468 #endif // SEND_HAIER_AC_YRW02
+
469 
+
470 #ifndef DECODE_WHIRLPOOL_AC
+
471 #define DECODE_WHIRLPOOL_AC _IR_ENABLE_DEFAULT_
+
472 #endif // DECODE_WHIRLPOOL_AC
+
473 #ifndef SEND_WHIRLPOOL_AC
+
474 #define SEND_WHIRLPOOL_AC _IR_ENABLE_DEFAULT_
+
475 #endif // SEND_WHIRLPOOL_AC
+
476 
+
477 #ifndef DECODE_LUTRON
+
478 #define DECODE_LUTRON _IR_ENABLE_DEFAULT_
+
479 #endif // DECODE_LUTRON
+
480 #ifndef SEND_LUTRON
+
481 #define SEND_LUTRON _IR_ENABLE_DEFAULT_
+
482 #endif // SEND_LUTRON
+
483 
+
484 #ifndef DECODE_ELECTRA_AC
+
485 #define DECODE_ELECTRA_AC _IR_ENABLE_DEFAULT_
+
486 #endif // DECODE_ELECTRA_AC
+
487 #ifndef SEND_ELECTRA_AC
+
488 #define SEND_ELECTRA_AC _IR_ENABLE_DEFAULT_
+
489 #endif // SEND_ELECTRA_AC
+
490 
+
491 #ifndef DECODE_PANASONIC_AC
+
492 #define DECODE_PANASONIC_AC _IR_ENABLE_DEFAULT_
+
493 #endif // DECODE_PANASONIC_AC
+
494 #ifndef SEND_PANASONIC_AC
+
495 #define SEND_PANASONIC_AC _IR_ENABLE_DEFAULT_
+
496 #endif // SEND_PANASONIC_AC
+
497 
+
498 #ifndef DECODE_MWM
+
499 #define DECODE_MWM _IR_ENABLE_DEFAULT_
+
500 #endif // DECODE_MWM
+
501 #ifndef SEND_MWM
+
502 #define SEND_MWM _IR_ENABLE_DEFAULT_
+
503 #endif // SEND_MWM
+
504 
+
505 #ifndef DECODE_PIONEER
+
506 #define DECODE_PIONEER _IR_ENABLE_DEFAULT_
+
507 #endif // DECODE_PIONEER
+
508 #ifndef SEND_PIONEER
+
509 #define SEND_PIONEER _IR_ENABLE_DEFAULT_
+
510 #endif // SEND_PIONEER
+
511 
+
512 #ifndef DECODE_DAIKIN2
+
513 #define DECODE_DAIKIN2 _IR_ENABLE_DEFAULT_
+
514 #endif // DECODE_DAIKIN2
+
515 #ifndef SEND_DAIKIN2
+
516 #define SEND_DAIKIN2 _IR_ENABLE_DEFAULT_
+
517 #endif // SEND_DAIKIN2
+
518 
+
519 #ifndef DECODE_VESTEL_AC
+
520 #define DECODE_VESTEL_AC _IR_ENABLE_DEFAULT_
+
521 #endif // DECODE_VESTEL_AC
+
522 #ifndef SEND_VESTEL_AC
+
523 #define SEND_VESTEL_AC _IR_ENABLE_DEFAULT_
+
524 #endif // SEND_VESTEL_AC
+
525 
+
526 #ifndef DECODE_TECO
+
527 #define DECODE_TECO _IR_ENABLE_DEFAULT_
+
528 #endif // DECODE_TECO
+
529 #ifndef SEND_TECO
+
530 #define SEND_TECO _IR_ENABLE_DEFAULT_
+
531 #endif // SEND_TECO
+
532 
+
533 #ifndef DECODE_TCL112AC
+
534 #define DECODE_TCL112AC _IR_ENABLE_DEFAULT_
+
535 #endif // DECODE_TCL112AC
+
536 #ifndef SEND_TCL112AC
+
537 #define SEND_TCL112AC _IR_ENABLE_DEFAULT_
+
538 #endif // SEND_TCL112AC
+
539 
+
540 #ifndef DECODE_LEGOPF
+
541 #define DECODE_LEGOPF _IR_ENABLE_DEFAULT_
+
542 #endif // DECODE_LEGOPF
+
543 #ifndef SEND_LEGOPF
+
544 #define SEND_LEGOPF _IR_ENABLE_DEFAULT_
+
545 #endif // SEND_LEGOPF
+
546 
+
547 #ifndef DECODE_MITSUBISHIHEAVY
+
548 #define DECODE_MITSUBISHIHEAVY _IR_ENABLE_DEFAULT_
+
549 #endif // DECODE_MITSUBISHIHEAVY
+
550 #ifndef SEND_MITSUBISHIHEAVY
+
551 #define SEND_MITSUBISHIHEAVY _IR_ENABLE_DEFAULT_
+
552 #endif // SEND_MITSUBISHIHEAVY
+
553 
+
554 #ifndef DECODE_DAIKIN216
+
555 #define DECODE_DAIKIN216 _IR_ENABLE_DEFAULT_
+
556 #endif // DECODE_DAIKIN216
+
557 #ifndef SEND_DAIKIN216
+
558 #define SEND_DAIKIN216 _IR_ENABLE_DEFAULT_
+
559 #endif // SEND_DAIKIN216
+
560 
+
561 #ifndef DECODE_DAIKIN160
+
562 #define DECODE_DAIKIN160 _IR_ENABLE_DEFAULT_
+
563 #endif // DECODE_DAIKIN160
+
564 #ifndef SEND_DAIKIN160
+
565 #define SEND_DAIKIN160 _IR_ENABLE_DEFAULT_
+
566 #endif // SEND_DAIKIN160
+
567 
+
568 #ifndef DECODE_NEOCLIMA
+
569 #define DECODE_NEOCLIMA _IR_ENABLE_DEFAULT_
+
570 #endif // DECODE_NEOCLIMA
+
571 #ifndef SEND_NEOCLIMA
+
572 #define SEND_NEOCLIMA _IR_ENABLE_DEFAULT_
+
573 #endif // SEND_NEOCLIMA
+
574 
+
575 #ifndef DECODE_DAIKIN176
+
576 #define DECODE_DAIKIN176 _IR_ENABLE_DEFAULT_
+
577 #endif // DECODE_DAIKIN176
+
578 #ifndef SEND_DAIKIN176
+
579 #define SEND_DAIKIN176 _IR_ENABLE_DEFAULT_
+
580 #endif // SEND_DAIKIN176
+
581 
+
582 #ifndef DECODE_DAIKIN128
+
583 #define DECODE_DAIKIN128 _IR_ENABLE_DEFAULT_
+
584 #endif // DECODE_DAIKIN128
+
585 #ifndef SEND_DAIKIN128
+
586 #define SEND_DAIKIN128 _IR_ENABLE_DEFAULT_
+
587 #endif // SEND_DAIKIN128
+
588 
+
589 #ifndef DECODE_AMCOR
+
590 #define DECODE_AMCOR _IR_ENABLE_DEFAULT_
+
591 #endif // DECODE_AMCOR
+
592 #ifndef SEND_AMCOR
+
593 #define SEND_AMCOR _IR_ENABLE_DEFAULT_
+
594 #endif // SEND_AMCOR
+
595 
+
596 #ifndef DECODE_DAIKIN152
+
597 #define DECODE_DAIKIN152 _IR_ENABLE_DEFAULT_
+
598 #endif // DECODE_DAIKIN152
+
599 #ifndef SEND_DAIKIN152
+
600 #define SEND_DAIKIN152 _IR_ENABLE_DEFAULT_
+
601 #endif // SEND_DAIKIN152
+
602 
+
603 #ifndef DECODE_EPSON
+
604 #define DECODE_EPSON _IR_ENABLE_DEFAULT_
+
605 #endif // DECODE_EPSON
+
606 #ifndef SEND_EPSON
+
607 #define SEND_EPSON _IR_ENABLE_DEFAULT_
+
608 #endif // SEND_EPSON
+
609 
+
610 #ifndef DECODE_SYMPHONY
+
611 #define DECODE_SYMPHONY _IR_ENABLE_DEFAULT_
+
612 #endif // DECODE_SYMPHONY
+
613 #ifndef SEND_SYMPHONY
+
614 #define SEND_SYMPHONY _IR_ENABLE_DEFAULT_
+
615 #endif // SEND_SYMPHONY
+
616 
+
617 #ifndef DECODE_DAIKIN64
+
618 #define DECODE_DAIKIN64 _IR_ENABLE_DEFAULT_
+
619 #endif // DECODE_DAIKIN64
+
620 #ifndef SEND_DAIKIN64
+
621 #define SEND_DAIKIN64 _IR_ENABLE_DEFAULT_
+
622 #endif // SEND_DAIKIN64
+
623 
+
624 #ifndef DECODE_AIRWELL
+
625 #define DECODE_AIRWELL _IR_ENABLE_DEFAULT_
+
626 #endif // DECODE_AIRWELL
+
627 #ifndef SEND_AIRWELL
+
628 #define SEND_AIRWELL _IR_ENABLE_DEFAULT_
+
629 #endif // SEND_AIRWELL
+
630 
+
631 #ifndef DECODE_DELONGHI_AC
+
632 #define DECODE_DELONGHI_AC _IR_ENABLE_DEFAULT_
+
633 #endif // DECODE_DELONGHI_AC
+
634 #ifndef SEND_DELONGHI_AC
+
635 #define SEND_DELONGHI_AC _IR_ENABLE_DEFAULT_
+
636 #endif // SEND_DELONGHI_AC
+
637 
+
638 #ifndef DECODE_DOSHISHA
+
639 #define DECODE_DOSHISHA _IR_ENABLE_DEFAULT_
+
640 #endif // DECODE_DOSHISHA
+
641 #ifndef SEND_DOSHISHA
+
642 #define SEND_DOSHISHA _IR_ENABLE_DEFAULT_
+
643 #endif // SEND_DOSHISHA
+
644 
+
645 #ifndef DECODE_MULTIBRACKETS
+
646 #define DECODE_MULTIBRACKETS _IR_ENABLE_DEFAULT_
+
647 #endif // DECODE_MULTIBRACKETS
+
648 #ifndef SEND_MULTIBRACKETS
+
649 #define SEND_MULTIBRACKETS _IR_ENABLE_DEFAULT_
+
650 #endif // SEND_MULTIBRACKETS
+
651 
+
652 #ifndef DECODE_CORONA_AC
+
653 #define DECODE_CORONA_AC _IR_ENABLE_DEFAULT_
+
654 #endif // DECODE_CORONA_AC
+
655 #ifndef SEND_CORONA_AC
+
656 #define SEND_CORONA_AC _IR_ENABLE_DEFAULT_
+
657 #endif // SEND_CORONA_AC
+
658 
+
659 #ifndef DECODE_ZEPEAL
+
660 #define DECODE_ZEPEAL _IR_ENABLE_DEFAULT_
+
661 #endif // DECODE_ZEPEAL
+
662 #ifndef SEND_ZEPEAL
+
663 #define SEND_ZEPEAL _IR_ENABLE_DEFAULT_
+
664 #endif // SEND_ZEPEAL
+
665 
+
666 #if (DECODE_ARGO || DECODE_DAIKIN || DECODE_FUJITSU_AC || DECODE_GREE || \
+
667  DECODE_KELVINATOR || DECODE_MITSUBISHI_AC || DECODE_TOSHIBA_AC || \
+
668  DECODE_TROTEC || DECODE_HAIER_AC || DECODE_HITACHI_AC || \
+
669  DECODE_HITACHI_AC1 || DECODE_HITACHI_AC2 || DECODE_HAIER_AC_YRW02 || \
+
670  DECODE_WHIRLPOOL_AC || DECODE_SAMSUNG_AC || DECODE_ELECTRA_AC || \
+
671  DECODE_PANASONIC_AC || DECODE_MWM || DECODE_DAIKIN2 || \
+
672  DECODE_VESTEL_AC || DECODE_TCL112AC || DECODE_MITSUBISHIHEAVY || \
+
673  DECODE_DAIKIN216 || DECODE_SHARP_AC || DECODE_DAIKIN160 || \
+
674  DECODE_NEOCLIMA || DECODE_DAIKIN176 || DECODE_DAIKIN128 || \
+
675  DECODE_AMCOR || DECODE_DAIKIN152 || DECODE_MITSUBISHI136 || \
+
676  DECODE_MITSUBISHI112 || DECODE_HITACHI_AC424 || DECODE_HITACHI_AC3 || \
+
677  DECODE_HITACHI_AC344 || DECODE_CORONA_AC)
+
678  // Add any DECODE to the above if it uses result->state (see kStateSizeMax)
+
679  // you might also want to add the protocol to hasACState function
+
680 #define DECODE_AC true // We need some common infrastructure for decoding A/Cs.
+
681 #else
+
682 #define DECODE_AC false // We don't need that infrastructure.
+
683 #endif
+
684 
+
685 // Use millisecond 'delay()' calls where we can to avoid tripping the WDT.
+
686 // Note: If you plan to send IR messages in the callbacks of the AsyncWebserver
+
687 // library, you need to set ALLOW_DELAY_CALLS to false.
+
688 // Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/430
+
689 #ifndef ALLOW_DELAY_CALLS
+
690 #define ALLOW_DELAY_CALLS true
+
691 #endif // ALLOW_DELAY_CALLS
+
692 
+
693 // Enable a run-time settable high-pass filter on captured data **before**
+
694 // trying any protocol decoding.
+
695 // i.e. Try to remove/merge any really short pulses detected in the raw data.
+
696 // Note: Even when this option is enabled, it is _off_ by default, and requires
+
697 // a user who knows what they are doing to enable it.
+
698 // The option to disable this feature is here if your project is _really_
+
699 // tight on resources. i.e. Saves a small handful of bytes and cpu time.
+
700 // WARNING: If you use this feature at runtime, you can no longer trust the
+
701 // **raw** data captured. It will now have been slightly **cooked**!
+
702 // DANGER: If you set the `noise_floor` value too high, it **WILL** break
+
703 // decoding of some protocols. You have been warned. Here Be Dragons!
+
704 //
+
705 // See: `irrecv::decode()` in IRrecv.cpp for more info.
+
706 #ifndef ENABLE_NOISE_FILTER_OPTION
+
707 #define ENABLE_NOISE_FILTER_OPTION true
+
708 #endif // ENABLE_NOISE_FILTER_OPTION
+
709 
+ +
715  UNKNOWN = -1,
+
716  UNUSED = 0,
+ + + + +
721  PANASONIC, // (5)
+ + + + +
726  LG, // (10)
+ + + + +
731  COOLIX, // (15)
+ + + + +
736  MITSUBISHI_AC, // (20)
+ + + + +
741  PRONTO, // Technically not a protocol, but an encoding. (25)
+ + + + +
746  RAW, // Technically not a protocol, but an encoding. (30)
+
747  GLOBALCACHE, // Technically not a protocol, but an encoding.
+ + + +
751  MAGIQUEST, // (35)
+ + + + +
756  HITACHI_AC, // (40)
+ + + + +
761  WHIRLPOOL_AC, // (45)
+ + + + +
766  PIONEER, // (50)
+ + + + +
771  TECO, // (55)
+ + + + + + + + + +
781  DAIKIN160, // 65
+ + + + +
786  DAIKIN152, // 70
+ + + + +
791  EPSON, // 75
+ + + + +
796  DELONGHI_AC, // 80
+ + + + + + + + +
805  // Add new entries before this one, and update it to point to the last entry.
+ +
807 };
+
808 
+
809 // Message lengths & required repeat values
+
810 const uint16_t kNoRepeat = 0;
+
811 const uint16_t kSingleRepeat = 1;
+
812 
+
813 const uint16_t kAirwellBits = 34;
+
814 const uint16_t kAirwellMinRepeats = 2;
+
815 const uint16_t kAiwaRcT501Bits = 15;
+ +
817 const uint16_t kAlokaBits = 32;
+
818 const uint16_t kAmcorStateLength = 8;
+
819 const uint16_t kAmcorBits = kAmcorStateLength * 8;
+ +
821 const uint16_t kArgoStateLength = 12;
+
822 const uint16_t kArgoBits = kArgoStateLength * 8;
+
823 const uint16_t kArgoDefaultRepeat = kNoRepeat;
+
824 const uint16_t kCoolixBits = 24;
+ +
826 const uint16_t kCarrierAcBits = 32;
+ +
828 const uint16_t kCarrierAc40Bits = 40;
+
829 const uint16_t kCarrierAc40MinRepeat = 2;
+
830 const uint16_t kCarrierAc64Bits = 64;
+ +
832 const uint16_t kCoronaAcStateLengthShort = 7;
+ + +
835 const uint16_t kCoronaAcBits = kCoronaAcStateLength * 8;
+
836 const uint16_t kDaikinStateLength = 35;
+
837 const uint16_t kDaikinBits = kDaikinStateLength * 8;
+ + + +
841 const uint16_t kDaikin2StateLength = 39;
+
842 const uint16_t kDaikin2Bits = kDaikin2StateLength * 8;
+ +
844 const uint16_t kDaikin64Bits = 64;
+ +
846 const uint16_t kDaikin160StateLength = 20;
+ + +
849 const uint16_t kDaikin128StateLength = 16;
+ + +
852 const uint16_t kDaikin152StateLength = 19;
+ + +
855 const uint16_t kDaikin176StateLength = 22;
+ + +
858 const uint16_t kDaikin216StateLength = 27;
+ + +
861 const uint16_t kDelonghiAcBits = 64;
+ +
863 const uint16_t kDenonBits = 15;
+
864 const uint16_t kDenon48Bits = 48;
+
865 const uint16_t kDenonLegacyBits = 14;
+
866 const uint16_t kDishBits = 16;
+
867 const uint16_t kDishMinRepeat = 3;
+
868 const uint16_t kDoshishaBits = 40;
+
869 const uint16_t kEpsonBits = 32;
+
870 const uint16_t kEpsonMinRepeat = 2;
+
871 const uint16_t kElectraAcStateLength = 13;
+ + + +
875 const uint16_t kFujitsuAcStateLength = 16;
+
876 const uint16_t kFujitsuAcStateLengthShort = 7;
+ + +
879 const uint16_t kGicableBits = 16;
+ +
881 const uint16_t kGoodweatherBits = 48;
+ +
883 const uint16_t kGreeStateLength = 8;
+
884 const uint16_t kGreeBits = kGreeStateLength * 8;
+
885 const uint16_t kGreeDefaultRepeat = kNoRepeat;
+
886 const uint16_t kHaierACStateLength = 9;
+
887 const uint16_t kHaierACBits = kHaierACStateLength * 8;
+ +
889 const uint16_t kHaierACYRW02StateLength = 14;
+ + +
892 const uint16_t kHitachiAcStateLength = 28;
+ + +
895 const uint16_t kHitachiAc1StateLength = 13;
+ +
897 const uint16_t kHitachiAc2StateLength = 53;
+ +
899 const uint16_t kHitachiAc3StateLength = 27;
+ +
901 const uint16_t kHitachiAc3MinStateLength = 15;
+ +
903 const uint16_t kHitachiAc344StateLength = 43;
+ +
905 const uint16_t kHitachiAc424StateLength = 53;
+ +
907 const uint16_t kInaxBits = 24;
+
908 const uint16_t kInaxMinRepeat = kSingleRepeat;
+
909 const uint16_t kJvcBits = 16;
+
910 const uint16_t kKelvinatorStateLength = 16;
+ + +
913 const uint16_t kLasertagBits = 13;
+
914 const uint16_t kLasertagMinRepeat = kNoRepeat;
+
915 const uint16_t kLegoPfBits = 16;
+
916 const uint16_t kLegoPfMinRepeat = kNoRepeat;
+
917 const uint16_t kLgBits = 28;
+
918 const uint16_t kLg32Bits = 32;
+
919 const uint16_t kLgDefaultRepeat = kNoRepeat;
+
920 const uint16_t kLutronBits = 35;
+
921 const uint16_t kMagiquestBits = 56;
+
922 const uint16_t kMideaBits = 48;
+
923 const uint16_t kMideaMinRepeat = kNoRepeat;
+
924 const uint16_t kMidea24Bits = 24;
+ +
926 const uint16_t kMitsubishiBits = 16;
+
927 // TODO(anyone): Verify that the Mitsubishi repeat is really needed.
+
928 // Based on marcosamarinho's code.
+ +
930 const uint16_t kMitsubishiACStateLength = 18;
+ + +
933 const uint16_t kMitsubishi136StateLength = 17;
+ + +
936 const uint16_t kMitsubishi112StateLength = 14;
+ + +
939 const uint16_t kMitsubishiHeavy88StateLength = 11;
+ + +
942 const uint16_t kMitsubishiHeavy152StateLength = 19;
+ + +
945 const uint16_t kMultibracketsBits = 8;
+ +
947 const uint16_t kNikaiBits = 24;
+
948 const uint16_t kNECBits = 32;
+
949 const uint16_t kNeoclimaStateLength = 12;
+
950 const uint16_t kNeoclimaBits = kNeoclimaStateLength * 8;
+
951 const uint16_t kNeoclimaMinRepeat = kNoRepeat;
+
952 const uint16_t kPanasonicBits = 48;
+
953 const uint32_t kPanasonicManufacturer = 0x4004;
+
954 const uint16_t kPanasonicAcStateLength = 27;
+
955 const uint16_t kPanasonicAcStateShortLength = 16;
+ + + +
959 const uint16_t kPioneerBits = 64;
+
960 const uint16_t kProntoMinLength = 6;
+
961 const uint16_t kRC5RawBits = 14;
+
962 const uint16_t kRC5Bits = kRC5RawBits - 2;
+
963 const uint16_t kRC5XBits = kRC5RawBits - 1;
+
964 const uint16_t kRC6Mode0Bits = 20; // Excludes the 'start' bit.
+
965 const uint16_t kRC6_36Bits = 36; // Excludes the 'start' bit.
+
966 const uint16_t kRCMMBits = 24;
+
967 const uint16_t kSamsungBits = 32;
+
968 const uint16_t kSamsung36Bits = 36;
+
969 const uint16_t kSamsungAcStateLength = 14;
+ +
971 const uint16_t kSamsungAcExtendedStateLength = 21;
+ + +
974 const uint16_t kSanyoSA8650BBits = 12;
+
975 const uint16_t kSanyoLC7461AddressBits = 13;
+
976 const uint16_t kSanyoLC7461CommandBits = 8;
+ + +
979 const uint8_t kSharpAddressBits = 5;
+
980 const uint8_t kSharpCommandBits = 8;
+
981 const uint16_t kSharpBits = kSharpAddressBits + kSharpCommandBits + 2; // 15
+
982 const uint16_t kSharpAcStateLength = 13;
+
983 const uint16_t kSharpAcBits = kSharpAcStateLength * 8; // 104
+ +
985 const uint8_t kSherwoodBits = kNECBits;
+ +
987 const uint16_t kSony12Bits = 12;
+
988 const uint16_t kSony15Bits = 15;
+
989 const uint16_t kSony20Bits = 20;
+
990 const uint16_t kSonyMinBits = 12;
+
991 const uint16_t kSonyMinRepeat = 2;
+
992 const uint16_t kSymphonyBits = 12;
+
993 const uint16_t kSymphonyDefaultRepeat = 3;
+
994 const uint16_t kTcl112AcStateLength = 14;
+
995 const uint16_t kTcl112AcBits = kTcl112AcStateLength * 8;
+ +
997 const uint16_t kTecoBits = 35;
+
998 const uint16_t kTecoDefaultRepeat = kNoRepeat;
+
999 const uint16_t kToshibaACStateLength = 9;
+ + +
1002 const uint16_t kTrotecStateLength = 9;
+
1003 const uint16_t kTrotecBits = kTrotecStateLength * 8;
+ +
1005 const uint16_t kWhirlpoolAcStateLength = 21;
+ + +
1008 const uint16_t kWhynterBits = 32;
+
1009 const uint8_t kVestelAcBits = 56;
+
1010 const uint16_t kZepealBits = 16;
+
1011 const uint16_t kZepealMinRepeat = 4;
+
1012 
+
1013 
+
1014 // Legacy defines. (Deprecated)
+
1015 #define AIWA_RC_T501_BITS kAiwaRcT501Bits
+
1016 #define ARGO_COMMAND_LENGTH kArgoStateLength
+
1017 #define COOLIX_BITS kCoolixBits
+
1018 #define CARRIER_AC_BITS kCarrierAcBits
+
1019 #define DAIKIN_COMMAND_LENGTH kDaikinStateLength
+
1020 #define DENON_BITS kDenonBits
+
1021 #define DENON_48_BITS kDenon48Bits
+
1022 #define DENON_LEGACY_BITS kDenonLegacyBits
+
1023 #define DISH_BITS kDishBits
+
1024 #define FUJITSU_AC_MIN_REPEAT kFujitsuAcMinRepeat
+
1025 #define FUJITSU_AC_STATE_LENGTH kFujitsuAcStateLength
+
1026 #define FUJITSU_AC_STATE_LENGTH_SHORT kFujitsuAcStateLengthShort
+
1027 #define FUJITSU_AC_BITS kFujitsuAcBits
+
1028 #define FUJITSU_AC_MIN_BITS kFujitsuAcMinBits
+
1029 #define GICABLE_BITS kGicableBits
+
1030 #define GREE_STATE_LENGTH kGreeStateLength
+
1031 #define HAIER_AC_STATE_LENGTH kHaierACStateLength
+
1032 #define HAIER_AC_YRW02_STATE_LENGTH kHaierACYRW02StateLength
+
1033 #define HITACHI_AC_STATE_LENGTH kHitachiAcStateLength
+
1034 #define HITACHI_AC_BITS kHitachiAcBits
+
1035 #define HITACHI_AC1_STATE_LENGTH kHitachiAc1StateLength
+
1036 #define HITACHI_AC1_BITS kHitachiAc1Bits
+
1037 #define HITACHI_AC2_STATE_LENGTH kHitachiAc2StateLength
+
1038 #define HITACHI_AC2_BITS kHitachiAc2Bits
+
1039 #define JVC_BITS kJvcBits
+
1040 #define KELVINATOR_STATE_LENGTH kKelvinatorStateLength
+
1041 #define LASERTAG_BITS kLasertagBits
+
1042 #define LG_BITS kLgBits
+
1043 #define LG32_BITS kLg32Bits
+
1044 #define MAGIQUEST_BITS kMagiquestBits
+
1045 #define MIDEA_BITS kMideaBits
+
1046 #define MITSUBISHI_BITS kMitsubishiBits
+
1047 #define MITSUBISHI_AC_STATE_LENGTH kMitsubishiACStateLength
+
1048 #define NEC_BITS kNECBits
+
1049 #define NIKAI_BITS kNikaiBits
+
1050 #define PANASONIC_BITS kPanasonicBits
+
1051 #define RC5_BITS kRC5Bits
+
1052 #define RC5X_BITS kRC5XBits
+
1053 #define RC6_MODE0_BITS kRC6Mode0Bits
+
1054 #define RC6_36_BITS kRC6_36Bits
+
1055 #define RCMM_BITS kRCMMBits
+
1056 #define SANYO_LC7461_BITS kSanyoLC7461Bits
+
1057 #define SAMSUNG_BITS kSamsungBits
+
1058 #define SANYO_SA8650B_BITS kSanyoSA8650BBits
+
1059 #define SHARP_BITS kSharpBits
+
1060 #define SHERWOOD_BITS kSherwoodBits
+
1061 #define SONY_12_BITS kSony12Bits
+
1062 #define SONY_15_BITS kSony15Bits
+
1063 #define SONY_20_BITS kSony20Bits
+
1064 #define TOSHIBA_AC_STATE_LENGTH kToshibaACStateLength
+
1065 #define TROTEC_COMMAND_LENGTH kTrotecStateLength
+
1066 #define WHYNTER_BITS kWhynterBits
+
1067 
+
1068 // Turn on Debugging information by uncommenting the following line.
+
1069 // #define DEBUG 1
+
1070 
+
1071 #ifdef DEBUG
+
1072 #ifdef UNIT_TEST
+
1073 #define DPRINT(x) do { std::cout << x; } while (0)
+
1074 #define DPRINTLN(x) do { std::cout << x << std::endl; } while (0)
+
1075 #endif // UNIT_TEST
+
1076 #ifdef ARDUINO
+
1077 #define DPRINT(x) do { Serial.print(x); } while (0)
+
1078 #define DPRINTLN(x) do { Serial.println(x); } while (0)
+
1079 #endif // ARDUINO
+
1080 #else // DEBUG
+
1081 #define DPRINT(x)
+
1082 #define DPRINTLN(x)
+
1083 #endif // DEBUG
+
1084 
+
1085 #ifdef UNIT_TEST
+
1086 #ifndef F
+
1087 // Create a no-op F() macro so the code base still compiles outside of the
+
1088 // Arduino framework. Thus we can safely use the Arduino 'F()' macro through-out
+
1089 // the code base. That macro stores constants in Flash (PROGMEM) memory.
+
1090 // See: https://github.com/crankyoldgit/IRremoteESP8266/issues/667
+
1091 #define F(x) x
+
1092 #endif // F
+
1093 typedef std::string String;
+
1094 #endif // UNIT_TEST
+
1095 
+
1096 #endif // IRREMOTEESP8266_H_
+
+
@ ARGO
Definition: IRremoteESP8266.h:743
+
const uint16_t kDaikin152DefaultRepeat
Definition: IRremoteESP8266.h:854
+
const uint16_t kSanyoSA8650BBits
Definition: IRremoteESP8266.h:974
+
const uint16_t kDelonghiAcBits
Definition: IRremoteESP8266.h:861
+
const uint16_t kHaierAcYrw02DefaultRepeat
Definition: IRremoteESP8266.h:891
+
const uint16_t kHitachiAc3MinStateLength
Definition: IRremoteESP8266.h:901
+
const uint16_t kMitsubishiACStateLength
Definition: IRremoteESP8266.h:930
+
const uint16_t kMitsubishiHeavy152StateLength
Definition: IRremoteESP8266.h:942
+
const uint16_t kAirwellMinRepeats
Definition: IRremoteESP8266.h:814
+
const uint16_t kMideaMinRepeat
Definition: IRremoteESP8266.h:923
+
const uint16_t kGicableBits
Definition: IRremoteESP8266.h:879
+
const uint16_t kGreeStateLength
Definition: IRremoteESP8266.h:883
+
@ DISH
Definition: IRremoteESP8266.h:729
+
@ UNUSED
Definition: IRremoteESP8266.h:716
+
decode_type_t
Enumerator for defining and numbering of supported IR protocol.
Definition: IRremoteESP8266.h:714
+
const uint16_t kCarrierAcBits
Definition: IRremoteESP8266.h:826
+
const uint16_t kDenonLegacyBits
Definition: IRremoteESP8266.h:865
+
@ SHERWOOD
Definition: IRremoteESP8266.h:735
+
const uint16_t kSingleRepeat
Definition: IRremoteESP8266.h:811
+
const uint16_t kDaikin2DefaultRepeat
Definition: IRremoteESP8266.h:843
+
const uint16_t kMultibracketsBits
Definition: IRremoteESP8266.h:945
+
const uint16_t kSharpAcBits
Definition: IRremoteESP8266.h:983
+
const uint16_t kWhynterBits
Definition: IRremoteESP8266.h:1008
+
@ CARRIER_AC
Definition: IRremoteESP8266.h:753
+
@ TOSHIBA_AC
Definition: IRremoteESP8266.h:748
+
@ AIRWELL
Definition: IRremoteESP8266.h:795
+
const uint16_t kAirwellBits
Definition: IRremoteESP8266.h:813
+
const uint16_t kHaierAcDefaultRepeat
Definition: IRremoteESP8266.h:888
+
@ PRONTO
Definition: IRremoteESP8266.h:741
+
const uint16_t kTrotecDefaultRepeat
Definition: IRremoteESP8266.h:1004
+
const uint16_t kFujitsuAcMinRepeat
Definition: IRremoteESP8266.h:874
+
const uint16_t kCoronaAcBits
Definition: IRremoteESP8266.h:835
+
const uint16_t kMitsubishiACBits
Definition: IRremoteESP8266.h:931
+
const uint16_t kMitsubishi136MinRepeat
Definition: IRremoteESP8266.h:935
+
@ UNKNOWN
Definition: IRremoteESP8266.h:715
+
const uint16_t kArgoDefaultRepeat
Definition: IRremoteESP8266.h:823
+
const uint16_t kHaierACStateLength
Definition: IRremoteESP8266.h:886
+
const uint16_t kHitachiAcStateLength
Definition: IRremoteESP8266.h:892
+
@ MITSUBISHI112
Definition: IRremoteESP8266.h:788
+
const uint16_t kDaikin176StateLength
Definition: IRremoteESP8266.h:855
+
const uint16_t kRC5XBits
Definition: IRremoteESP8266.h:963
+
const uint16_t kEpsonMinRepeat
Definition: IRremoteESP8266.h:870
+
const uint16_t kAmcorStateLength
Definition: IRremoteESP8266.h:818
+
@ DAIKIN128
Definition: IRremoteESP8266.h:784
+
const uint16_t kAlokaBits
Definition: IRremoteESP8266.h:817
+
@ JVC
Definition: IRremoteESP8266.h:722
+
@ SONY
Definition: IRremoteESP8266.h:720
+
@ HITACHI_AC2
Definition: IRremoteESP8266.h:758
+
const uint16_t kHitachiAc1StateLength
Definition: IRremoteESP8266.h:895
+
const uint16_t kCoolixBits
Definition: IRremoteESP8266.h:824
+
const uint16_t kMitsubishi112MinRepeat
Definition: IRremoteESP8266.h:938
+
const uint16_t kCoronaAcBitsShort
Definition: IRremoteESP8266.h:834
+
const uint16_t kSamsung36Bits
Definition: IRremoteESP8266.h:968
+
const uint16_t kMagiquestBits
Definition: IRremoteESP8266.h:921
+
@ LUTRON
Definition: IRremoteESP8266.h:763
+
const uint8_t kSharpCommandBits
Definition: IRremoteESP8266.h:980
+
const uint16_t kNeoclimaStateLength
Definition: IRremoteESP8266.h:949
+
@ RCMM
Definition: IRremoteESP8266.h:737
+
@ SANYO_LC7461
Definition: IRremoteESP8266.h:738
+
@ TROTEC
Definition: IRremoteESP8266.h:744
+
const uint16_t kFujitsuAcMinBits
Definition: IRremoteESP8266.h:878
+
const uint16_t kSamsungAcDefaultRepeat
Definition: IRremoteESP8266.h:973
+
const uint16_t kSanyoLC7461Bits
Definition: IRremoteESP8266.h:977
+
@ DAIKIN160
Definition: IRremoteESP8266.h:781
+
@ CORONA_AC
Definition: IRremoteESP8266.h:802
+
const uint16_t kSanyoLC7461CommandBits
Definition: IRremoteESP8266.h:976
+
const uint16_t kTrotecBits
Definition: IRremoteESP8266.h:1003
+
@ PANASONIC
Definition: IRremoteESP8266.h:721
+
const uint16_t kZepealMinRepeat
Definition: IRremoteESP8266.h:1011
+
const uint16_t kDenon48Bits
Definition: IRremoteESP8266.h:864
+
@ DAIKIN2
Definition: IRremoteESP8266.h:769
+
const uint16_t kHitachiAc2Bits
Definition: IRremoteESP8266.h:898
+
const uint16_t kElectraAcMinRepeat
Definition: IRremoteESP8266.h:873
+
@ MITSUBISHI_AC
Definition: IRremoteESP8266.h:736
+
@ MAGIQUEST
Definition: IRremoteESP8266.h:751
+
const uint16_t kHitachiAc3StateLength
Definition: IRremoteESP8266.h:899
+
const uint16_t kLg32Bits
Definition: IRremoteESP8266.h:918
+
@ DOSHISHA
Definition: IRremoteESP8266.h:797
+
const uint16_t kCoronaAcStateLengthShort
Definition: IRremoteESP8266.h:832
+
const uint16_t kElectraAcBits
Definition: IRremoteESP8266.h:872
+
const uint16_t kSonyMinBits
Definition: IRremoteESP8266.h:990
+
@ HAIER_AC_YRW02
Definition: IRremoteESP8266.h:760
+
const uint16_t kAiwaRcT501MinRepeats
Definition: IRremoteESP8266.h:816
+
@ HITACHI_AC424
Definition: IRremoteESP8266.h:789
+
const uint16_t kDaikin2Bits
Definition: IRremoteESP8266.h:842
+
const uint16_t kHitachiAc1Bits
Definition: IRremoteESP8266.h:896
+
@ CARRIER_AC64
Definition: IRremoteESP8266.h:800
+
@ NEC
Definition: IRremoteESP8266.h:719
+
@ FUJITSU_AC
Definition: IRremoteESP8266.h:749
+
const uint16_t kMitsubishiMinRepeat
Definition: IRremoteESP8266.h:929
+
@ GOODWEATHER
Definition: IRremoteESP8266.h:779
+
@ HITACHI_AC3
Definition: IRremoteESP8266.h:793
+
@ INAX
Definition: IRremoteESP8266.h:780
+
const uint16_t kArgoStateLength
Definition: IRremoteESP8266.h:821
+
@ SYMPHONY
Definition: IRremoteESP8266.h:792
+
const uint16_t kPanasonicBits
Definition: IRremoteESP8266.h:952
+
std::string String
Definition: IRremoteESP8266.h:1093
+
@ HAIER_AC
Definition: IRremoteESP8266.h:754
+
const uint16_t kDaikinStateLengthShort
Definition: IRremoteESP8266.h:838
+
const uint16_t kRC5Bits
Definition: IRremoteESP8266.h:962
+
const uint16_t kLgDefaultRepeat
Definition: IRremoteESP8266.h:919
+
const uint16_t kDaikin152StateLength
Definition: IRremoteESP8266.h:852
+
const uint16_t kPanasonicAcBits
Definition: IRremoteESP8266.h:956
+
const uint16_t kRC5RawBits
Definition: IRremoteESP8266.h:961
+
const uint16_t kHaierACYRW02StateLength
Definition: IRremoteESP8266.h:889
+
const uint16_t kSanyoLC7461AddressBits
Definition: IRremoteESP8266.h:975
+
const uint16_t kMultibracketsDefaultRepeat
Definition: IRremoteESP8266.h:946
+
@ LG
Definition: IRremoteESP8266.h:726
+
const uint16_t kDaikin160Bits
Definition: IRremoteESP8266.h:847
+
@ HITACHI_AC344
Definition: IRremoteESP8266.h:801
+
@ MIDEA
Definition: IRremoteESP8266.h:750
+
const uint16_t kGoodweatherBits
Definition: IRremoteESP8266.h:881
+
const uint16_t kGicableMinRepeat
Definition: IRremoteESP8266.h:880
+
@ GLOBALCACHE
Definition: IRremoteESP8266.h:747
+
const uint16_t kDaikin152Bits
Definition: IRremoteESP8266.h:853
+
const uint16_t kDaikin216StateLength
Definition: IRremoteESP8266.h:858
+
@ GICABLE
Definition: IRremoteESP8266.h:759
+
const uint16_t kSamsungAcStateLength
Definition: IRremoteESP8266.h:969
+
@ COOLIX
Definition: IRremoteESP8266.h:731
+
@ MIDEA24
Definition: IRremoteESP8266.h:803
+
const uint16_t kSymphonyBits
Definition: IRremoteESP8266.h:992
+
const uint16_t kDaikin128StateLength
Definition: IRremoteESP8266.h:849
+
const uint16_t kRC6Mode0Bits
Definition: IRremoteESP8266.h:964
+
@ NEOCLIMA
Definition: IRremoteESP8266.h:782
+
const uint16_t kDaikin176DefaultRepeat
Definition: IRremoteESP8266.h:857
+
const uint16_t kMitsubishiHeavy152MinRepeat
Definition: IRremoteESP8266.h:944
+
const uint16_t kSony12Bits
Definition: IRremoteESP8266.h:987
+
const uint16_t kNoRepeat
Definition: IRremoteESP8266.h:810
+
const uint16_t kSony20Bits
Definition: IRremoteESP8266.h:989
+
const uint16_t kMitsubishiACMinRepeat
Definition: IRremoteESP8266.h:932
+
@ MULTIBRACKETS
Definition: IRremoteESP8266.h:798
+
const uint16_t kHitachiAc3MinBits
Definition: IRremoteESP8266.h:902
+
const uint16_t kPanasonicAcDefaultRepeat
Definition: IRremoteESP8266.h:958
+
const uint16_t kSymphonyDefaultRepeat
Definition: IRremoteESP8266.h:993
+
const uint16_t kSamsungAcExtendedStateLength
Definition: IRremoteESP8266.h:971
+
const uint16_t kCoolixDefaultRepeat
Definition: IRremoteESP8266.h:825
+
@ DENON
Definition: IRremoteESP8266.h:733
+
const uint16_t kTcl112AcDefaultRepeat
Definition: IRremoteESP8266.h:996
+
const uint16_t kDelonghiAcDefaultRepeat
Definition: IRremoteESP8266.h:862
+
const uint16_t kCoronaAcStateLength
Definition: IRremoteESP8266.h:833
+
@ SANYO
Definition: IRremoteESP8266.h:727
+
const uint16_t kTecoDefaultRepeat
Definition: IRremoteESP8266.h:998
+
const uint16_t kMitsubishiHeavy152Bits
Definition: IRremoteESP8266.h:943
+
const uint16_t kDoshishaBits
Definition: IRremoteESP8266.h:868
+
const uint16_t kCarrierAc40Bits
Definition: IRremoteESP8266.h:828
+
const uint16_t kAmcorBits
Definition: IRremoteESP8266.h:819
+
const uint16_t kTrotecStateLength
Definition: IRremoteESP8266.h:1002
+
@ LG2
Definition: IRremoteESP8266.h:767
+
const uint16_t kWhirlpoolAcDefaultRepeat
Definition: IRremoteESP8266.h:1007
+
const uint16_t kHitachiAc424StateLength
Definition: IRremoteESP8266.h:905
+
const uint16_t kMitsubishiHeavy88StateLength
Definition: IRremoteESP8266.h:939
+
@ RC5X
Definition: IRremoteESP8266.h:739
+
@ LASERTAG
Definition: IRremoteESP8266.h:752
+
const uint16_t kFujitsuAcStateLengthShort
Definition: IRremoteESP8266.h:876
+
const uint32_t kPanasonicManufacturer
Definition: IRremoteESP8266.h:953
+
@ RAW
Definition: IRremoteESP8266.h:746
+
const uint16_t kMitsubishiBits
Definition: IRremoteESP8266.h:926
+
@ SONY_38K
Definition: IRremoteESP8266.h:790
+
@ RC6
Definition: IRremoteESP8266.h:718
+
@ PIONEER
Definition: IRremoteESP8266.h:766
+
const uint16_t kPanasonicAcStateLength
Definition: IRremoteESP8266.h:954
+
@ MITSUBISHI2
Definition: IRremoteESP8266.h:755
+
const uint16_t kFujitsuAcStateLength
Definition: IRremoteESP8266.h:875
+
const uint16_t kSamsungAcBits
Definition: IRremoteESP8266.h:970
+
const uint16_t kMideaBits
Definition: IRremoteESP8266.h:922
+
const uint16_t kKelvinatorStateLength
Definition: IRremoteESP8266.h:910
+
const uint16_t kKelvinatorBits
Definition: IRremoteESP8266.h:911
+
@ LEGOPF
Definition: IRremoteESP8266.h:774
+
@ WHYNTER
Definition: IRremoteESP8266.h:724
+
const uint16_t kDaikin216DefaultRepeat
Definition: IRremoteESP8266.h:860
+
@ AMCOR
Definition: IRremoteESP8266.h:785
+
const uint16_t kWhirlpoolAcStateLength
Definition: IRremoteESP8266.h:1005
+
const uint16_t kNECBits
Definition: IRremoteESP8266.h:948
+
const uint16_t kDenonBits
Definition: IRremoteESP8266.h:863
+
const uint16_t kHaierACBits
Definition: IRremoteESP8266.h:887
+
const uint16_t kZepealBits
Definition: IRremoteESP8266.h:1010
+
@ TCL112AC
Definition: IRremoteESP8266.h:773
+
const uint16_t kSony15Bits
Definition: IRremoteESP8266.h:988
+
const uint16_t kCarrierAc40MinRepeat
Definition: IRremoteESP8266.h:829
+
const uint16_t kMidea24Bits
Definition: IRremoteESP8266.h:924
+
const uint16_t kDaikin160DefaultRepeat
Definition: IRremoteESP8266.h:848
+
const uint16_t kToshibaACMinRepeat
Definition: IRremoteESP8266.h:1001
+
const uint16_t kSamsungAcExtendedBits
Definition: IRremoteESP8266.h:972
+
const uint16_t kHitachiAc344StateLength
Definition: IRremoteESP8266.h:903
+
const uint16_t kNeoclimaBits
Definition: IRremoteESP8266.h:950
+
const uint16_t kWhirlpoolAcBits
Definition: IRremoteESP8266.h:1006
+
const uint16_t kHitachiAc344Bits
Definition: IRremoteESP8266.h:904
+
const uint16_t kRC6_36Bits
Definition: IRremoteESP8266.h:965
+
@ DAIKIN176
Definition: IRremoteESP8266.h:783
+
const uint16_t kCarrierAc64Bits
Definition: IRremoteESP8266.h:830
+
const uint16_t kDaikin128DefaultRepeat
Definition: IRremoteESP8266.h:851
+
const uint16_t kPioneerBits
Definition: IRremoteESP8266.h:959
+
const uint16_t kSharpAcStateLength
Definition: IRremoteESP8266.h:982
+
@ MITSUBISHI_HEAVY_88
Definition: IRremoteESP8266.h:775
+
const uint16_t kGreeBits
Definition: IRremoteESP8266.h:884
+
const uint16_t kJvcBits
Definition: IRremoteESP8266.h:909
+
const uint16_t kDaikinStateLength
Definition: IRremoteESP8266.h:836
+
const uint16_t kLasertagBits
Definition: IRremoteESP8266.h:913
+
const uint16_t kDaikin128Bits
Definition: IRremoteESP8266.h:850
+
const uint16_t kAiwaRcT501Bits
Definition: IRremoteESP8266.h:815
+
const uint16_t kToshibaACStateLength
Definition: IRremoteESP8266.h:999
+
const uint16_t kTecoBits
Definition: IRremoteESP8266.h:997
+
const uint16_t kInaxMinRepeat
Definition: IRremoteESP8266.h:908
+
const uint16_t kPanasonicAcStateShortLength
Definition: IRremoteESP8266.h:955
+
@ CARRIER_AC40
Definition: IRremoteESP8266.h:799
+
const uint16_t kToshibaACBits
Definition: IRremoteESP8266.h:1000
+
const uint8_t kSherwoodBits
Definition: IRremoteESP8266.h:985
+
@ DAIKIN152
Definition: IRremoteESP8266.h:786
+
@ NEC_LIKE
Definition: IRremoteESP8266.h:742
+
const uint16_t kDaikinDefaultRepeat
Definition: IRremoteESP8266.h:840
+
const uint16_t kDaikin64DefaultRepeat
Definition: IRremoteESP8266.h:845
+
@ SAMSUNG
Definition: IRremoteESP8266.h:723
+
@ AIWA_RC_T501
Definition: IRremoteESP8266.h:725
+
@ MITSUBISHI_HEAVY_152
Definition: IRremoteESP8266.h:776
+
@ VESTEL_AC
Definition: IRremoteESP8266.h:770
+
const uint16_t kDaikinBits
Definition: IRremoteESP8266.h:837
+
@ GREE
Definition: IRremoteESP8266.h:740
+
const uint16_t kHitachiAcBits
Definition: IRremoteESP8266.h:893
+
const uint16_t kMitsubishiHeavy88MinRepeat
Definition: IRremoteESP8266.h:941
+
const uint16_t kHitachiAc3Bits
Definition: IRremoteESP8266.h:900
+
const uint16_t kHitachiAcDefaultRepeat
Definition: IRremoteESP8266.h:894
+
@ NIKAI
Definition: IRremoteESP8266.h:745
+
const uint16_t kMidea24MinRepeat
Definition: IRremoteESP8266.h:925
+
const uint16_t kDishBits
Definition: IRremoteESP8266.h:866
+
@ WHIRLPOOL_AC
Definition: IRremoteESP8266.h:761
+
const uint16_t kDishMinRepeat
Definition: IRremoteESP8266.h:867
+
const uint16_t kFujitsuAcBits
Definition: IRremoteESP8266.h:877
+
const uint16_t kArgoBits
Definition: IRremoteESP8266.h:822
+
@ RC5
Definition: IRremoteESP8266.h:717
+
const uint16_t kHitachiAc2StateLength
Definition: IRremoteESP8266.h:897
+
@ HITACHI_AC
Definition: IRremoteESP8266.h:756
+
@ SHARP_AC
Definition: IRremoteESP8266.h:778
+
@ HITACHI_AC1
Definition: IRremoteESP8266.h:757
+
const uint16_t kMitsubishiHeavy88Bits
Definition: IRremoteESP8266.h:940
+
const uint16_t kCarrierAcMinRepeat
Definition: IRremoteESP8266.h:827
+
@ ZEPEAL
Definition: IRremoteESP8266.h:804
+
const uint16_t kNikaiBits
Definition: IRremoteESP8266.h:947
+
const uint16_t kKelvinatorDefaultRepeat
Definition: IRremoteESP8266.h:912
+
const uint16_t kLutronBits
Definition: IRremoteESP8266.h:920
+
const uint16_t kSharpAcDefaultRepeat
Definition: IRremoteESP8266.h:984
+
@ MITSUBISHI136
Definition: IRremoteESP8266.h:787
+
const uint16_t kTcl112AcStateLength
Definition: IRremoteESP8266.h:994
+
const uint16_t kDaikin160StateLength
Definition: IRremoteESP8266.h:846
+
const uint16_t kDaikin2StateLength
Definition: IRremoteESP8266.h:841
+
const uint16_t kHaierACYRW02Bits
Definition: IRremoteESP8266.h:890
+
const uint16_t kSherwoodMinRepeat
Definition: IRremoteESP8266.h:986
+
const uint16_t kCarrierAc64MinRepeat
Definition: IRremoteESP8266.h:831
+
@ MWM
Definition: IRremoteESP8266.h:768
+
const uint16_t kHitachiAc424Bits
Definition: IRremoteESP8266.h:906
+
const uint16_t kPanasonicAcShortBits
Definition: IRremoteESP8266.h:957
+
@ DAIKIN
Definition: IRremoteESP8266.h:732
+
@ DELONGHI_AC
Definition: IRremoteESP8266.h:796
+
@ EPSON
Definition: IRremoteESP8266.h:791
+
const uint16_t kLegoPfBits
Definition: IRremoteESP8266.h:915
+
const uint16_t kSharpBits
Definition: IRremoteESP8266.h:981
+
@ kLastDecodeType
Definition: IRremoteESP8266.h:806
+
@ SAMSUNG_AC
Definition: IRremoteESP8266.h:762
+
const uint16_t kDaikinBitsShort
Definition: IRremoteESP8266.h:839
+
@ DAIKIN216
Definition: IRremoteESP8266.h:777
+
@ PANASONIC_AC
Definition: IRremoteESP8266.h:765
+
const uint16_t kProntoMinLength
Definition: IRremoteESP8266.h:960
+
const uint16_t kMitsubishi136StateLength
Definition: IRremoteESP8266.h:933
+
@ DAIKIN64
Definition: IRremoteESP8266.h:794
+
const uint16_t kRCMMBits
Definition: IRremoteESP8266.h:966
+
const uint8_t kVestelAcBits
Definition: IRremoteESP8266.h:1009
+
@ SAMSUNG36
Definition: IRremoteESP8266.h:772
+
const uint8_t kSharpAddressBits
Definition: IRremoteESP8266.h:979
+
const uint16_t kInaxBits
Definition: IRremoteESP8266.h:907
+
const uint16_t kLegoPfMinRepeat
Definition: IRremoteESP8266.h:916
+
const uint16_t kDaikin176Bits
Definition: IRremoteESP8266.h:856
+
const uint16_t kAmcorDefaultRepeat
Definition: IRremoteESP8266.h:820
+
@ KELVINATOR
Definition: IRremoteESP8266.h:734
+
const uint16_t kSamsungBits
Definition: IRremoteESP8266.h:967
+
const uint16_t kDaikin64Bits
Definition: IRremoteESP8266.h:844
+
const uint16_t kTcl112AcBits
Definition: IRremoteESP8266.h:995
+
@ TECO
Definition: IRremoteESP8266.h:771
+
const uint16_t kLasertagMinRepeat
Definition: IRremoteESP8266.h:914
+
@ SHARP
Definition: IRremoteESP8266.h:730
+
@ MITSUBISHI
Definition: IRremoteESP8266.h:728
+
@ ELECTRA_AC
Definition: IRremoteESP8266.h:764
+
const uint16_t kDaikin216Bits
Definition: IRremoteESP8266.h:859
+
const uint16_t kMitsubishi136Bits
Definition: IRremoteESP8266.h:934
+
const uint16_t kNeoclimaMinRepeat
Definition: IRremoteESP8266.h:951
+
const uint16_t kMitsubishi112StateLength
Definition: IRremoteESP8266.h:936
+
const uint16_t kMitsubishi112Bits
Definition: IRremoteESP8266.h:937
+
const uint16_t kSonyMinRepeat
Definition: IRremoteESP8266.h:991
+
const uint16_t kEpsonBits
Definition: IRremoteESP8266.h:869
+
const uint16_t kLgBits
Definition: IRremoteESP8266.h:917
+
const uint16_t kGoodweatherMinRepeat
Definition: IRremoteESP8266.h:882
+
const uint16_t kElectraAcStateLength
Definition: IRremoteESP8266.h:871
+
const uint16_t kGreeDefaultRepeat
Definition: IRremoteESP8266.h:885
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRsend_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRsend_8cpp.html new file mode 100644 index 000000000..33a3b4df7 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRsend_8cpp.html @@ -0,0 +1,80 @@ + + + + + + + +IRremoteESP8266: src/IRsend.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
IRsend.cpp File Reference
+
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRsend_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRsend_8h.html new file mode 100644 index 000000000..1d8ef27da --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRsend_8h.html @@ -0,0 +1,419 @@ + + + + + + + +IRremoteESP8266: src/IRsend.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
IRsend.h File Reference
+
+
+ +

Go to the source code of this file.

+ + + + + + + + +

+Classes

struct  stdAc::state_t
 Structure to hold a common A/C state. More...
 
class  IRsend
 Class for sending all basic IR protocols. More...
 
+ + + + +

+Namespaces

 stdAc
 Enumerators and Structures for the Common A/C API.
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Enumerations

enum  stdAc::opmode_t {
+  stdAc::opmode_t::kOff = -1, +stdAc::opmode_t::kAuto = 0, +stdAc::opmode_t::kCool = 1, +stdAc::opmode_t::kHeat = 2, +
+  stdAc::opmode_t::kDry = 3, +stdAc::opmode_t::kFan = 4, +stdAc::opmode_t::kLastOpmodeEnum = kFan +
+ }
 Common A/C settings for A/C operating modes. More...
 
enum  stdAc::fanspeed_t {
+  stdAc::fanspeed_t::kAuto = 0, +stdAc::fanspeed_t::kMin = 1, +stdAc::fanspeed_t::kLow = 2, +stdAc::fanspeed_t::kMedium = 3, +
+  stdAc::fanspeed_t::kHigh = 4, +stdAc::fanspeed_t::kMax = 5, +stdAc::fanspeed_t::kLastFanspeedEnum = kMax +
+ }
 Common A/C settings for Fan Speeds. More...
 
enum  stdAc::swingv_t {
+  stdAc::swingv_t::kOff = -1, +stdAc::swingv_t::kAuto = 0, +stdAc::swingv_t::kHighest = 1, +stdAc::swingv_t::kHigh = 2, +
+  stdAc::swingv_t::kMiddle = 3, +stdAc::swingv_t::kLow = 4, +stdAc::swingv_t::kLowest = 5, +stdAc::swingv_t::kLastSwingvEnum = kLowest +
+ }
 Common A/C settings for Vertical Swing. More...
 
enum  stdAc::swingh_t {
+  stdAc::swingh_t::kOff = -1, +stdAc::swingh_t::kAuto = 0, +stdAc::swingh_t::kLeftMax = 1, +stdAc::swingh_t::kLeft = 2, +
+  stdAc::swingh_t::kMiddle = 3, +stdAc::swingh_t::kRight = 4, +stdAc::swingh_t::kRightMax = 5, +stdAc::swingh_t::kWide = 6, +
+  stdAc::swingh_t::kLastSwinghEnum = kWide +
+ }
 Common A/C settings for Horizontal Swing. More...
 
enum  fujitsu_ac_remote_model_t {
+  ARRAH2E = 1, +ARDB1, +ARREB1E, +ARJW2, +
+  ARRY4 +
+ }
 Fujitsu A/C model numbers. More...
 
enum  gree_ac_remote_model_t { YAW1F = 1, +YBOFB + }
 Gree A/C model numbers. More...
 
enum  hitachi_ac1_remote_model_t { R_LT0541_HTA_A = 1, +R_LT0541_HTA_B + }
 HITACHI_AC1 A/C model numbers. More...
 
enum  panasonic_ac_remote_model_t {
+  kPanasonicUnknown = 0, +kPanasonicLke = 1, +kPanasonicNke = 2, +kPanasonicDke = 3, +
+  kPanasonicJke = 4, +kPanasonicCkp = 5, +kPanasonicRkr = 6 +
+ }
 Panasonic A/C model numbers. More...
 
enum  whirlpool_ac_remote_model_t { DG11J13A = 1, +DG11J191 + }
 Whirlpool A/C model numbers. More...
 
enum  lg_ac_remote_model_t { GE6711AR2853M = 1, +AKB75215403 + }
 LG A/C model numbers. More...
 
+ + + + + + + + + + + +

+Variables

const int8_t kPeriodOffset = -2
 
const uint8_t kDutyDefault = 50
 
const uint8_t kDutyMax = 100
 
const uint16_t kMaxAccurateUsecDelay = 16383
 
const uint32_t kDefaultMessageGap = 100000
 
+

Enumeration Type Documentation

+ +

◆ fujitsu_ac_remote_model_t

+ +
+
+ + + + +
enum fujitsu_ac_remote_model_t
+
+ +

Fujitsu A/C model numbers.

+ + + + + + +
Enumerator
ARRAH2E 
ARDB1 
ARREB1E 
ARJW2 
ARRY4 
+ +
+
+ +

◆ gree_ac_remote_model_t

+ +
+
+ + + + +
enum gree_ac_remote_model_t
+
+ +

Gree A/C model numbers.

+ + + +
Enumerator
YAW1F 
YBOFB 
+ +
+
+ +

◆ hitachi_ac1_remote_model_t

+ +
+
+ + + + +
enum hitachi_ac1_remote_model_t
+
+ +

HITACHI_AC1 A/C model numbers.

+ + + +
Enumerator
R_LT0541_HTA_A 
R_LT0541_HTA_B 
+ +
+
+ +

◆ lg_ac_remote_model_t

+ +
+
+ + + + +
enum lg_ac_remote_model_t
+
+ +

LG A/C model numbers.

+ + + +
Enumerator
GE6711AR2853M 
AKB75215403 
+ +
+
+ +

◆ panasonic_ac_remote_model_t

+ +
+
+ + + + +
enum panasonic_ac_remote_model_t
+
+ +

Panasonic A/C model numbers.

+ + + + + + + + +
Enumerator
kPanasonicUnknown 
kPanasonicLke 
kPanasonicNke 
kPanasonicDke 
kPanasonicJke 
kPanasonicCkp 
kPanasonicRkr 
+ +
+
+ +

◆ whirlpool_ac_remote_model_t

+ +
+
+ + + + +
enum whirlpool_ac_remote_model_t
+
+ +

Whirlpool A/C model numbers.

+ + + +
Enumerator
DG11J13A 
DG11J191 
+ +
+
+

Variable Documentation

+ +

◆ kDefaultMessageGap

+ +
+
+ + + + +
const uint32_t kDefaultMessageGap = 100000
+
+ +
+
+ +

◆ kDutyDefault

+ +
+
+ + + + +
const uint8_t kDutyDefault = 50
+
+ +
+
+ +

◆ kDutyMax

+ +
+
+ + + + +
const uint8_t kDutyMax = 100
+
+ +
+
+ +

◆ kMaxAccurateUsecDelay

+ +
+
+ + + + +
const uint16_t kMaxAccurateUsecDelay = 16383
+
+ +
+
+ +

◆ kPeriodOffset

+ +
+
+ + + + +
const int8_t kPeriodOffset = -2
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRsend_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRsend_8h_source.html new file mode 100644 index 000000000..5afbc44c9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRsend_8h_source.html @@ -0,0 +1,1078 @@ + + + + + + + +IRremoteESP8266: src/IRsend.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
IRsend.h
+
+
+Go to the documentation of this file.
1 // Copyright 2009 Ken Shirriff
+
2 // Copyright 2015 Mark Szabo
+
3 // Copyright 2017 David Conran
+
4 #ifndef IRSEND_H_
+
5 #define IRSEND_H_
+
6 
+
7 #define __STDC_LIMIT_MACROS
+
8 #include <stdint.h>
+
9 #include "IRremoteESP8266.h"
+
10 
+
11 // Originally from https://github.com/shirriff/Arduino-IRremote/
+
12 // Updated by markszabo (https://github.com/crankyoldgit/IRremoteESP8266) for
+
13 // sending IR code on ESP8266
+
14 
+
15 #if TEST || UNIT_TEST
+
16 #define VIRTUAL virtual
+
17 #else
+
18 #define VIRTUAL
+
19 #endif
+
20 
+
21 // Constants
+
22 // Offset (in microseconds) to use in Period time calculations to account for
+
23 // code excution time in producing the software PWM signal.
+
24 #if defined(ESP32)
+
25 // Calculated on a generic ESP-WROOM-32 board with v3.2-18 SDK @ 240MHz
+
26 const int8_t kPeriodOffset = -2;
+
27 #elif (defined(ESP8266) && F_CPU == 160000000L) // NOLINT(whitespace/parens)
+
28 // Calculated on an ESP8266 NodeMCU v2 board using:
+
29 // v2.6.0 with v2.5.2 ESP core @ 160MHz
+
30 const int8_t kPeriodOffset = -2;
+
31 #else // (defined(ESP8266) && F_CPU == 160000000L)
+
32 // Calculated on ESP8266 Wemos D1 mini using v2.4.1 with v2.4.0 ESP core @ 40MHz
+
33 const int8_t kPeriodOffset = -5;
+
34 #endif // (defined(ESP8266) && F_CPU == 160000000L)
+
35 const uint8_t kDutyDefault = 50; // Percentage
+
36 const uint8_t kDutyMax = 100; // Percentage
+
37 // delayMicroseconds() is only accurate to 16383us.
+
38 // Ref: https://www.arduino.cc/en/Reference/delayMicroseconds
+
39 const uint16_t kMaxAccurateUsecDelay = 16383;
+
40 // Usecs to wait between messages we don't know the proper gap time.
+
41 const uint32_t kDefaultMessageGap = 100000;
+
42 
+
44 namespace stdAc {
+
46  enum class opmode_t {
+
47  kOff = -1,
+
48  kAuto = 0,
+
49  kCool = 1,
+
50  kHeat = 2,
+
51  kDry = 3,
+
52  kFan = 4,
+
53  // Add new entries before this one, and update it to point to the last entry
+ +
55  };
+
56 
+
58  enum class fanspeed_t {
+
59  kAuto = 0,
+
60  kMin = 1,
+
61  kLow = 2,
+
62  kMedium = 3,
+
63  kHigh = 4,
+
64  kMax = 5,
+
65  // Add new entries before this one, and update it to point to the last entry
+ +
67  };
+
68 
+
70  enum class swingv_t {
+
71  kOff = -1,
+
72  kAuto = 0,
+
73  kHighest = 1,
+
74  kHigh = 2,
+
75  kMiddle = 3,
+
76  kLow = 4,
+
77  kLowest = 5,
+
78  // Add new entries before this one, and update it to point to the last entry
+ +
80  };
+
81 
+
83  enum class swingh_t {
+
84  kOff = -1,
+
85  kAuto = 0, // a.k.a. On.
+
86  kLeftMax = 1,
+
87  kLeft = 2,
+
88  kMiddle = 3,
+
89  kRight = 4,
+
90  kRightMax = 5,
+
91  kWide = 6, // a.k.a. left & right at the same time.
+
92  // Add new entries before this one, and update it to point to the last entry
+ +
94  };
+
95 
+
97  typedef struct {
+ +
99  int16_t model;
+
100  bool power;
+ +
102  float degrees;
+
103  bool celsius;
+ + + +
107  bool quiet;
+
108  bool turbo;
+
109  bool econo;
+
110  bool light;
+
111  bool filter;
+
112  bool clean;
+
113  bool beep;
+
114  int16_t sleep;
+
115  int16_t clock;
+
116  } state_t;
+
117 }; // namespace stdAc
+
118 
+ +
121  ARRAH2E = 1, // (1) AR-RAH2E, AR-RAC1E, AR-RAE1E (Default)
+
122  ARDB1, // (2) AR-DB1, AR-DL10 (AR-DL10 swing doesn't work)
+
123  ARREB1E, // (3) AR-REB1E
+
124  ARJW2, // (4) AR-JW2 (Same as ARDB1 but with horiz control)
+
125  ARRY4, // (5) AR-RY4 (Same as AR-RAH2E but with clean & filter)
+
126 };
+
127 
+ +
130  YAW1F = 1, // (1) Ultimate, EKOKAI, RusClimate (Default)
+
131  YBOFB, // (2) Green, YBOFB2, YAPOF3
+
132 };
+
133 
+ +
136  R_LT0541_HTA_A = 1, // (1) R-LT0541-HTA Remote in "A" setting. (Default)
+
137  R_LT0541_HTA_B, // (2) R-LT0541-HTA Remote in "B" setting.
+
138 };
+
139 
+ + + + +
145  kPanasonicDke = 3, // PKR too.
+ + + +
149 };
+
150 
+ +
153  DG11J13A = 1, // DG11J1-04 too
+ +
155 };
+
156 
+ +
159  GE6711AR2853M = 1, // (1) LG 28-bit Protocol (default)
+
160  AKB75215403, // (2) LG2 28-bit Protocol
+
161 };
+
162 
+
163 
+
164 // Classes
+
165 
+
170 class IRsend {
+
171  public:
+
172  explicit IRsend(uint16_t IRsendPin, bool inverted = false,
+
173  bool use_modulation = true);
+
174  void begin();
+
175  void enableIROut(uint32_t freq, uint8_t duty = kDutyDefault);
+
176  VIRTUAL void _delayMicroseconds(uint32_t usec);
+
177  VIRTUAL uint16_t mark(uint16_t usec);
+
178  VIRTUAL void space(uint32_t usec);
+
179  int8_t calibrate(uint16_t hz = 38000U);
+
180  void sendRaw(const uint16_t buf[], const uint16_t len, const uint16_t hz);
+
181  void sendData(uint16_t onemark, uint32_t onespace, uint16_t zeromark,
+
182  uint32_t zerospace, uint64_t data, uint16_t nbits,
+
183  bool MSBfirst = true);
+
184  void sendManchesterData(const uint16_t half_period, const uint64_t data,
+
185  const uint16_t nbits, const bool MSBfirst = true,
+
186  const bool GEThomas = true);
+
187  void sendManchester(const uint16_t headermark, const uint32_t headerspace,
+
188  const uint16_t half_period, const uint16_t footermark,
+
189  const uint32_t gap, const uint64_t data,
+
190  const uint16_t nbits, const uint16_t frequency = 38,
+
191  const bool MSBfirst = true,
+
192  const uint16_t repeat = kNoRepeat,
+
193  const uint8_t dutycycle = kDutyDefault,
+
194  const bool GEThomas = true);
+
195  void sendGeneric(const uint16_t headermark, const uint32_t headerspace,
+
196  const uint16_t onemark, const uint32_t onespace,
+
197  const uint16_t zeromark, const uint32_t zerospace,
+
198  const uint16_t footermark, const uint32_t gap,
+
199  const uint64_t data, const uint16_t nbits,
+
200  const uint16_t frequency, const bool MSBfirst,
+
201  const uint16_t repeat, const uint8_t dutycycle);
+
202  void sendGeneric(const uint16_t headermark, const uint32_t headerspace,
+
203  const uint16_t onemark, const uint32_t onespace,
+
204  const uint16_t zeromark, const uint32_t zerospace,
+
205  const uint16_t footermark, const uint32_t gap,
+
206  const uint32_t mesgtime, const uint64_t data,
+
207  const uint16_t nbits, const uint16_t frequency,
+
208  const bool MSBfirst, const uint16_t repeat,
+
209  const uint8_t dutycycle);
+
210  void sendGeneric(const uint16_t headermark, const uint32_t headerspace,
+
211  const uint16_t onemark, const uint32_t onespace,
+
212  const uint16_t zeromark, const uint32_t zerospace,
+
213  const uint16_t footermark, const uint32_t gap,
+
214  const uint8_t *dataptr, const uint16_t nbytes,
+
215  const uint16_t frequency, const bool MSBfirst,
+
216  const uint16_t repeat, const uint8_t dutycycle);
+
217  static uint16_t minRepeats(const decode_type_t protocol);
+
218  static uint16_t defaultBits(const decode_type_t protocol);
+
219  bool send(const decode_type_t type, const uint64_t data,
+
220  const uint16_t nbits, const uint16_t repeat = kNoRepeat);
+
221  bool send(const decode_type_t type, const uint8_t *state,
+
222  const uint16_t nbytes);
+
223 #if (SEND_NEC || SEND_SHERWOOD || SEND_AIWA_RC_T501 || SEND_SANYO || \
+
224  SEND_MIDEA24)
+
225  void sendNEC(uint64_t data, uint16_t nbits = kNECBits,
+
226  uint16_t repeat = kNoRepeat);
+
227  uint32_t encodeNEC(uint16_t address, uint16_t command);
+
228 #endif
+
229 #if SEND_SONY
+
230  // sendSony() should typically be called with repeat=2 as Sony devices
+
231  // expect the code to be sent at least 3 times. (code + 2 repeats = 3 codes)
+
232  // Legacy use of this procedure was to only send a single code so call it with
+
233  // repeat=0 for backward compatibility. As of v2.0 it defaults to sending
+
234  // a Sony command that will be accepted be a device.
+
235  void sendSony(const uint64_t data, const uint16_t nbits = kSony20Bits,
+
236  const uint16_t repeat = kSonyMinRepeat);
+
237  void sendSony38(const uint64_t data, const uint16_t nbits = kSony20Bits,
+
238  const uint16_t repeat = kSonyMinRepeat + 1);
+
239  uint32_t encodeSony(const uint16_t nbits, const uint16_t command,
+
240  const uint16_t address, const uint16_t extended = 0);
+
241 #endif // SEND_SONY
+
242 #if SEND_SHERWOOD
+
243  void sendSherwood(uint64_t data, uint16_t nbits = kSherwoodBits,
+
244  uint16_t repeat = kSherwoodMinRepeat);
+
245 #endif
+
246 #if SEND_SAMSUNG
+
247  void sendSAMSUNG(const uint64_t data, const uint16_t nbits = kSamsungBits,
+
248  const uint16_t repeat = kNoRepeat);
+
249  uint32_t encodeSAMSUNG(const uint8_t customer, const uint8_t command);
+
250 #endif
+
251 #if SEND_SAMSUNG36
+
252  void sendSamsung36(const uint64_t data, const uint16_t nbits = kSamsung36Bits,
+
253  const uint16_t repeat = kNoRepeat);
+
254 #endif
+
255 #if SEND_SAMSUNG_AC
+
256  void sendSamsungAC(const unsigned char data[],
+
257  const uint16_t nbytes = kSamsungAcStateLength,
+
258  const uint16_t repeat = kSamsungAcDefaultRepeat);
+
259 #endif
+
260 #if SEND_LG
+
261  void sendLG(uint64_t data, uint16_t nbits = kLgBits,
+
262  uint16_t repeat = kNoRepeat);
+
263  void sendLG2(uint64_t data, uint16_t nbits = kLgBits,
+
264  uint16_t repeat = kNoRepeat);
+
265  uint32_t encodeLG(uint16_t address, uint16_t command);
+
266 #endif
+
267 #if (SEND_SHARP || SEND_DENON)
+
268  uint32_t encodeSharp(const uint16_t address, const uint16_t command,
+
269  const uint16_t expansion = 1, const uint16_t check = 0,
+
270  const bool MSBfirst = false);
+
271  void sendSharp(const uint16_t address, const uint16_t command,
+
272  const uint16_t nbits = kSharpBits,
+
273  const uint16_t repeat = kNoRepeat);
+
274  void sendSharpRaw(const uint64_t data, const uint16_t nbits = kSharpBits,
+
275  const uint16_t repeat = kNoRepeat);
+
276 #endif
+
277 #if SEND_SHARP_AC
+
278  void sendSharpAc(const unsigned char data[],
+
279  const uint16_t nbytes = kSharpAcStateLength,
+
280  const uint16_t repeat = kSharpAcDefaultRepeat);
+
281 #endif // SEND_SHARP_AC
+
282 #if SEND_JVC
+
283  void sendJVC(uint64_t data, uint16_t nbits = kJvcBits,
+
284  uint16_t repeat = kNoRepeat);
+
285  uint16_t encodeJVC(uint8_t address, uint8_t command);
+
286 #endif
+
287 #if SEND_DENON
+
288  void sendDenon(uint64_t data, uint16_t nbits = kDenonBits,
+
289  uint16_t repeat = kNoRepeat);
+
290 #endif
+
291 #if SEND_SANYO
+
292  uint64_t encodeSanyoLC7461(uint16_t address, uint8_t command);
+
293  void sendSanyoLC7461(const uint64_t data,
+
294  const uint16_t nbits = kSanyoLC7461Bits,
+
295  const uint16_t repeat = kNoRepeat);
+
296 #endif
+
297 #if SEND_DISH
+
298  // sendDISH() should typically be called with repeat=3 as DISH devices
+
299  // expect the code to be sent at least 4 times. (code + 3 repeats = 4 codes)
+
300  // Legacy use of this procedure was only to send a single code
+
301  // so use repeat=0 for backward compatibility.
+
302  void sendDISH(uint64_t data, uint16_t nbits = kDishBits,
+
303  uint16_t repeat = kDishMinRepeat);
+
304 #endif
+
305 #if (SEND_PANASONIC || SEND_DENON)
+
306  void sendPanasonic64(const uint64_t data,
+
307  const uint16_t nbits = kPanasonicBits,
+
308  const uint16_t repeat = kNoRepeat);
+
309  void sendPanasonic(const uint16_t address, const uint32_t data,
+
310  const uint16_t nbits = kPanasonicBits,
+
311  const uint16_t repeat = kNoRepeat);
+
312  uint64_t encodePanasonic(const uint16_t manufacturer, const uint8_t device,
+
313  const uint8_t subdevice, const uint8_t function);
+
314 #endif
+
315 #if SEND_RC5
+
316  void sendRC5(const uint64_t data, uint16_t nbits = kRC5XBits,
+
317  const uint16_t repeat = kNoRepeat);
+
318  uint16_t encodeRC5(const uint8_t address, const uint8_t command,
+
319  const bool key_released = false);
+
320  uint16_t encodeRC5X(const uint8_t address, const uint8_t command,
+
321  const bool key_released = false);
+
322  uint64_t toggleRC5(const uint64_t data);
+
323 #endif
+
324 #if SEND_RC6
+
325  void sendRC6(const uint64_t data, const uint16_t nbits = kRC6Mode0Bits,
+
326  const uint16_t repeat = kNoRepeat);
+
327  uint64_t encodeRC6(const uint32_t address, const uint8_t command,
+
328  const uint16_t mode = kRC6Mode0Bits);
+
329  uint64_t toggleRC6(const uint64_t data, const uint16_t nbits = kRC6Mode0Bits);
+
330 #endif
+
331 #if SEND_RCMM
+
332  void sendRCMM(uint64_t data, uint16_t nbits = kRCMMBits,
+
333  uint16_t repeat = kNoRepeat);
+
334 #endif
+
335 #if SEND_COOLIX
+
336  void sendCOOLIX(uint64_t data, uint16_t nbits = kCoolixBits,
+
337  uint16_t repeat = kCoolixDefaultRepeat);
+
338 #endif
+
339 #if SEND_WHYNTER
+
340  void sendWhynter(const uint64_t data, const uint16_t nbits = kWhynterBits,
+
341  const uint16_t repeat = kNoRepeat);
+
342 #endif
+
343 #if SEND_MITSUBISHI
+
344  void sendMitsubishi(uint64_t data, uint16_t nbits = kMitsubishiBits,
+
345  uint16_t repeat = kMitsubishiMinRepeat);
+
346 #endif
+
347 #if SEND_MITSUBISHI136
+
348  void sendMitsubishi136(const unsigned char data[],
+
349  const uint16_t nbytes = kMitsubishi136StateLength,
+
350  const uint16_t repeat = kMitsubishi136MinRepeat);
+
351 #endif
+
352 #if SEND_MITSUBISHI112
+
353  void sendMitsubishi112(const unsigned char data[],
+
354  const uint16_t nbytes = kMitsubishi112StateLength,
+
355  const uint16_t repeat = kMitsubishi112MinRepeat);
+
356 #endif
+
357 #if SEND_MITSUBISHI2
+
358  void sendMitsubishi2(uint64_t data, uint16_t nbits = kMitsubishiBits,
+
359  uint16_t repeat = kMitsubishiMinRepeat);
+
360 #endif
+
361 #if SEND_MITSUBISHI_AC
+
362  void sendMitsubishiAC(const unsigned char data[],
+
363  const uint16_t nbytes = kMitsubishiACStateLength,
+
364  const uint16_t repeat = kMitsubishiACMinRepeat);
+
365 #endif
+
366 #if SEND_MITSUBISHIHEAVY
+ +
368  const unsigned char data[],
+
369  const uint16_t nbytes = kMitsubishiHeavy88StateLength,
+
370  const uint16_t repeat = kMitsubishiHeavy88MinRepeat);
+ +
372  const unsigned char data[],
+
373  const uint16_t nbytes = kMitsubishiHeavy152StateLength,
+
374  const uint16_t repeat = kMitsubishiHeavy152MinRepeat);
+
375 #endif
+
376 #if SEND_FUJITSU_AC
+
377  void sendFujitsuAC(const unsigned char data[], const uint16_t nbytes,
+
378  const uint16_t repeat = kFujitsuAcMinRepeat);
+
379 #endif
+
380 #if SEND_INAX
+
381  void sendInax(const uint64_t data, const uint16_t nbits = kInaxBits,
+
382  const uint16_t repeat = kInaxMinRepeat);
+
383 #endif // SEND_INAX
+
384 #if SEND_GLOBALCACHE
+
385  void sendGC(uint16_t buf[], uint16_t len);
+
386 #endif
+
387 #if SEND_KELVINATOR
+
388  void sendKelvinator(const unsigned char data[],
+
389  const uint16_t nbytes = kKelvinatorStateLength,
+
390  const uint16_t repeat = kKelvinatorDefaultRepeat);
+
391 #endif
+
392 #if SEND_DAIKIN
+
393  void sendDaikin(const unsigned char data[],
+
394  const uint16_t nbytes = kDaikinStateLength,
+
395  const uint16_t repeat = kDaikinDefaultRepeat);
+
396 #endif
+
397 #if SEND_DAIKIN64
+
398  void sendDaikin64(const uint64_t data, const uint16_t nbits = kDaikin64Bits,
+
399  const uint16_t repeat = kDaikin64DefaultRepeat);
+
400 #endif // SEND_DAIKIN64
+
401 #if SEND_DAIKIN128
+
402  void sendDaikin128(const unsigned char data[],
+
403  const uint16_t nbytes = kDaikin128StateLength,
+
404  const uint16_t repeat = kDaikin128DefaultRepeat);
+
405 #endif // SEND_DAIKIN128
+
406 #if SEND_DAIKIN152
+
407  void sendDaikin152(const unsigned char data[],
+
408  const uint16_t nbytes = kDaikin152StateLength,
+
409  const uint16_t repeat = kDaikin152DefaultRepeat);
+
410 #endif // SEND_DAIKIN152
+
411 #if SEND_DAIKIN160
+
412  void sendDaikin160(const unsigned char data[],
+
413  const uint16_t nbytes = kDaikin160StateLength,
+
414  const uint16_t repeat = kDaikin160DefaultRepeat);
+
415 #endif // SEND_DAIKIN160
+
416 #if SEND_DAIKIN176
+
417  void sendDaikin176(const unsigned char data[],
+
418  const uint16_t nbytes = kDaikin176StateLength,
+
419  const uint16_t repeat = kDaikin176DefaultRepeat);
+
420 #endif // SEND_DAIKIN176
+
421 #if SEND_DAIKIN2
+
422  void sendDaikin2(const unsigned char data[],
+
423  const uint16_t nbytes = kDaikin2StateLength,
+
424  const uint16_t repeat = kDaikin2DefaultRepeat);
+
425 #endif
+
426 #if SEND_DAIKIN216
+
427  void sendDaikin216(const unsigned char data[],
+
428  const uint16_t nbytes = kDaikin216StateLength,
+
429  const uint16_t repeat = kDaikin216DefaultRepeat);
+
430 #endif
+
431 #if SEND_AIWA_RC_T501
+
432  void sendAiwaRCT501(uint64_t data, uint16_t nbits = kAiwaRcT501Bits,
+
433  uint16_t repeat = kAiwaRcT501MinRepeats);
+
434 #endif
+
435 #if SEND_GREE
+
436  void sendGree(const uint64_t data, const uint16_t nbits = kGreeBits,
+
437  const uint16_t repeat = kGreeDefaultRepeat);
+
438  void sendGree(const uint8_t data[], const uint16_t nbytes = kGreeStateLength,
+
439  const uint16_t repeat = kGreeDefaultRepeat);
+
440 #endif
+
441 #if SEND_GOODWEATHER
+
442  void sendGoodweather(const uint64_t data,
+
443  const uint16_t nbits = kGoodweatherBits,
+
444  const uint16_t repeat = kGoodweatherMinRepeat);
+
445 #endif // SEND_GOODWEATHER
+
446 #if SEND_PRONTO
+
447  void sendPronto(uint16_t data[], uint16_t len, uint16_t repeat = kNoRepeat);
+
448 #endif
+
449 #if SEND_ARGO
+
450  void sendArgo(const unsigned char data[],
+
451  const uint16_t nbytes = kArgoStateLength,
+
452  const uint16_t repeat = kArgoDefaultRepeat);
+
453 #endif
+
454 #if SEND_TROTEC
+
455  void sendTrotec(const unsigned char data[],
+
456  const uint16_t nbytes = kTrotecStateLength,
+
457  const uint16_t repeat = kTrotecDefaultRepeat);
+
458 #endif
+
459 #if SEND_NIKAI
+
460  void sendNikai(uint64_t data, uint16_t nbits = kNikaiBits,
+
461  uint16_t repeat = kNoRepeat);
+
462 #endif
+
463 #if SEND_TOSHIBA_AC
+
464  void sendToshibaAC(const unsigned char data[],
+
465  const uint16_t nbytes = kToshibaACStateLength,
+
466  const uint16_t repeat = kToshibaACMinRepeat);
+
467 #endif
+
468 #if SEND_MIDEA
+
469  void sendMidea(uint64_t data, uint16_t nbits = kMideaBits,
+
470  uint16_t repeat = kMideaMinRepeat);
+
471 #endif // SEND_MIDEA
+
472 #if SEND_MIDEA24
+
473  void sendMidea24(const uint64_t data, const uint16_t nbits = kMidea24Bits,
+
474  const uint16_t repeat = kMidea24MinRepeat);
+
475 #endif // SEND_MIDEA24
+
476 #if SEND_MAGIQUEST
+
477  void sendMagiQuest(const uint64_t data, const uint16_t nbits = kMagiquestBits,
+
478  const uint16_t repeat = kNoRepeat);
+
479  uint64_t encodeMagiQuest(const uint32_t wand_id, const uint16_t magnitude);
+
480 #endif
+
481 #if SEND_LASERTAG
+
482  void sendLasertag(uint64_t data, uint16_t nbits = kLasertagBits,
+
483  uint16_t repeat = kLasertagMinRepeat);
+
484 #endif
+
485 #if SEND_CARRIER_AC
+
486  void sendCarrierAC(uint64_t data, uint16_t nbits = kCarrierAcBits,
+
487  uint16_t repeat = kCarrierAcMinRepeat);
+
488 #endif
+
489 #if SEND_CARRIER_AC40
+
490  void sendCarrierAC40(uint64_t data, uint16_t nbits = kCarrierAc40Bits,
+
491  uint16_t repeat = kCarrierAc40MinRepeat);
+
492 #endif
+
493 #if SEND_CARRIER_AC64
+
494  void sendCarrierAC64(uint64_t data, uint16_t nbits = kCarrierAc64Bits,
+
495  uint16_t repeat = kCarrierAc64MinRepeat);
+
496 #endif
+
497 #if (SEND_HAIER_AC || SEND_HAIER_AC_YRW02)
+
498  void sendHaierAC(const unsigned char data[],
+
499  const uint16_t nbytes = kHaierACStateLength,
+
500  const uint16_t repeat = kHaierAcDefaultRepeat);
+
501 #endif
+
502 #if SEND_HAIER_AC_YRW02
+
503  void sendHaierACYRW02(const unsigned char data[],
+
504  const uint16_t nbytes = kHaierACYRW02StateLength,
+
505  const uint16_t repeat = kHaierAcYrw02DefaultRepeat);
+
506 #endif
+
507 #if SEND_HITACHI_AC
+
508  void sendHitachiAC(const unsigned char data[],
+
509  const uint16_t nbytes = kHitachiAcStateLength,
+
510  const uint16_t repeat = kHitachiAcDefaultRepeat);
+
511 #endif
+
512 #if SEND_HITACHI_AC1
+
513  void sendHitachiAC1(const unsigned char data[],
+
514  const uint16_t nbytes = kHitachiAc1StateLength,
+
515  const uint16_t repeat = kHitachiAcDefaultRepeat);
+
516 #endif
+
517 #if SEND_HITACHI_AC2
+
518  void sendHitachiAC2(const unsigned char data[],
+
519  const uint16_t nbytes = kHitachiAc2StateLength,
+
520  const uint16_t repeat = kHitachiAcDefaultRepeat);
+
521 #endif
+
522 #if SEND_HITACHI_AC3
+
523  void sendHitachiAc3(const unsigned char data[],
+
524  const uint16_t nbytes, // No default as there as so many
+
525  // different sizes
+
526  const uint16_t repeat = kHitachiAcDefaultRepeat);
+
527 #endif // SEND_HITACHI_AC3
+
528 #if SEND_HITACHI_AC344
+
529  void sendHitachiAc344(const unsigned char data[],
+
530  const uint16_t nbytes = kHitachiAc344StateLength,
+
531  const uint16_t repeat = kHitachiAcDefaultRepeat);
+
532 #endif // SEND_HITACHI_AC344
+
533 #if SEND_HITACHI_AC424
+
534  void sendHitachiAc424(const unsigned char data[],
+
535  const uint16_t nbytes = kHitachiAc424StateLength,
+
536  const uint16_t repeat = kHitachiAcDefaultRepeat);
+
537 #endif // SEND_HITACHI_AC424
+
538 #if SEND_GICABLE
+
539  void sendGICable(uint64_t data, uint16_t nbits = kGicableBits,
+
540  uint16_t repeat = kGicableMinRepeat);
+
541 #endif
+
542 #if SEND_WHIRLPOOL_AC
+
543  void sendWhirlpoolAC(const unsigned char data[],
+
544  const uint16_t nbytes = kWhirlpoolAcStateLength,
+
545  const uint16_t repeat = kWhirlpoolAcDefaultRepeat);
+
546 #endif
+
547 #if SEND_LUTRON
+
548  void sendLutron(uint64_t data, uint16_t nbits = kLutronBits,
+
549  uint16_t repeat = kNoRepeat);
+
550 #endif
+
551 #if SEND_ELECTRA_AC
+
552  void sendElectraAC(const unsigned char data[],
+
553  const uint16_t nbytes = kElectraAcStateLength,
+
554  const uint16_t repeat = kNoRepeat);
+
555 #endif
+
556 #if SEND_PANASONIC_AC
+
557  void sendPanasonicAC(const unsigned char data[],
+
558  const uint16_t nbytes = kPanasonicAcStateLength,
+
559  const uint16_t repeat = kPanasonicAcDefaultRepeat);
+
560 #endif
+
561 #if SEND_PIONEER
+
562  void sendPioneer(const uint64_t data, const uint16_t nbits = kPioneerBits,
+
563  const uint16_t repeat = kNoRepeat);
+
564  uint64_t encodePioneer(uint16_t address, uint16_t command);
+
565 #endif
+
566 #if SEND_MWM
+
567  void sendMWM(const unsigned char data[], const uint16_t nbytes,
+
568  const uint16_t repeat = kNoRepeat);
+
569 #endif
+
570 #if SEND_VESTEL_AC
+
571  void sendVestelAc(const uint64_t data, const uint16_t nbits = kVestelAcBits,
+
572  const uint16_t repeat = kNoRepeat);
+
573 #endif
+
574 #if SEND_TCL112AC
+
575  void sendTcl112Ac(const unsigned char data[],
+
576  const uint16_t nbytes = kTcl112AcStateLength,
+
577  const uint16_t repeat = kTcl112AcDefaultRepeat);
+
578 #endif
+
579 #if SEND_TECO
+
580  void sendTeco(const uint64_t data, const uint16_t nbits = kTecoBits,
+
581  const uint16_t repeat = kNoRepeat);
+
582 #endif
+
583 #if SEND_LEGOPF
+
584  void sendLegoPf(const uint64_t data, const uint16_t nbits = kLegoPfBits,
+
585  const uint16_t repeat = kLegoPfMinRepeat);
+
586 #endif
+
587 #if SEND_NEOCLIMA
+
588  void sendNeoclima(const unsigned char data[],
+
589  const uint16_t nbytes = kNeoclimaStateLength,
+
590  const uint16_t repeat = kNeoclimaMinRepeat);
+
591 #endif // SEND_NEOCLIMA
+
592 #if SEND_AMCOR
+
593  void sendAmcor(const unsigned char data[],
+
594  const uint16_t nbytes = kAmcorStateLength,
+
595  const uint16_t repeat = kAmcorDefaultRepeat);
+
596 #endif // SEND_AMCOR
+
597 #if SEND_EPSON
+
598  void sendEpson(uint64_t data, uint16_t nbits = kEpsonBits,
+
599  uint16_t repeat = kEpsonMinRepeat);
+
600 #endif
+
601 #if SEND_SYMPHONY
+
602  void sendSymphony(uint64_t data, uint16_t nbits = kSymphonyBits,
+
603  uint16_t repeat = kSymphonyDefaultRepeat);
+
604 #endif
+
605 #if SEND_AIRWELL
+
606  void sendAirwell(uint64_t data, uint16_t nbits = kAirwellBits,
+
607  uint16_t repeat = kAirwellMinRepeats);
+
608 #endif
+
609 #if SEND_DELONGHI_AC
+
610  void sendDelonghiAc(uint64_t data, uint16_t nbits = kDelonghiAcBits,
+
611  uint16_t repeat = kDelonghiAcDefaultRepeat);
+
612 #endif
+
613 #if SEND_DOSHISHA
+
614  void sendDoshisha(const uint64_t data, uint16_t nbits = kDoshishaBits,
+
615  const uint16_t repeat = kNoRepeat);
+
616  uint64_t encodeDoshisha(const uint8_t command, const uint8_t channel = 0);
+
617 #endif // SEND_DOSHISHA
+
618 #if SEND_MULTIBRACKETS
+
619  void sendMultibrackets(const uint64_t data,
+
620  const uint16_t nbits = kMultibracketsBits,
+
621  const uint16_t repeat = kMultibracketsDefaultRepeat);
+
622 #endif
+
623 #if SEND_CORONA_AC
+
624  void sendCoronaAc(const uint8_t data[],
+
625  const uint16_t nbytes = kCoronaAcStateLength,
+
626  const uint16_t repeat = kNoRepeat);
+
627 #endif // SEND_CORONA_AC
+
628 #if SEND_ZEPEAL
+
629  void sendZepeal(const uint64_t data,
+
630  const uint16_t nbits = kZepealBits,
+
631  const uint16_t repeat = kZepealMinRepeat);
+
632 #endif
+
633 
+
634  protected:
+
635 #ifdef UNIT_TEST
+
636 #ifndef HIGH
+
637 #define HIGH 0x1
+
638 #endif
+
639 #ifndef LOW
+
640 #define LOW 0x0
+
641 #endif
+
642 #endif // UNIT_TEST
+
643  uint8_t outputOn;
+
644  uint8_t outputOff;
+
645  VIRTUAL void ledOff();
+
646  VIRTUAL void ledOn();
+
647 #ifndef UNIT_TEST
+
648 
+
649  private:
+
650 #else
+
651  uint32_t _freq_unittest;
+
652 #endif // UNIT_TEST
+
653  uint16_t onTimePeriod;
+
654  uint16_t offTimePeriod;
+
655  uint16_t IRpin;
+
656  int8_t periodOffset;
+
657  uint8_t _dutycycle;
+ +
659  uint32_t calcUSecPeriod(uint32_t hz, bool use_offset = true);
+
660 #if SEND_SONY
+
661  void _sendSony(const uint64_t data, const uint16_t nbits,
+
662  const uint16_t repeat, const uint16_t freq);
+
663 #endif // SEND_SONY
+
664 };
+
665 
+
666 #endif // IRSEND_H_
+
+
uint32_t calcUSecPeriod(uint32_t hz, bool use_offset=true)
Calculate the period for a given frequency.
Definition: IRsend.cpp:71
+
const uint16_t kDaikin152DefaultRepeat
Definition: IRremoteESP8266.h:854
+
void sendZepeal(const uint64_t data, const uint16_t nbits=kZepealBits, const uint16_t repeat=kZepealMinRepeat)
Send a Zepeal formatted message. Status: STABLE / Works on real device.
Definition: ir_Zepeal.cpp:47
+
const uint16_t kDelonghiAcBits
Definition: IRremoteESP8266.h:861
+
void sendHaierACYRW02(const unsigned char data[], const uint16_t nbytes=kHaierACYRW02StateLength, const uint16_t repeat=kHaierAcYrw02DefaultRepeat)
Send a Haier YR-W02 remote A/C formatted message. Status: Alpha / Untested on a real device.
Definition: ir_Haier.cpp:68
+
const uint16_t kHaierAcYrw02DefaultRepeat
Definition: IRremoteESP8266.h:891
+
void sendPronto(uint16_t data[], uint16_t len, uint16_t repeat=kNoRepeat)
Send a Pronto Code formatted message. Status: STABLE / Known working.
Definition: ir_Pronto.cpp:56
+
uint8_t outputOff
Definition: IRsend.h:644
+
int8_t periodOffset
Definition: IRsend.h:656
+
const uint16_t kMitsubishiACStateLength
Definition: IRremoteESP8266.h:930
+
const uint16_t kMitsubishiHeavy152StateLength
Definition: IRremoteESP8266.h:942
+
const uint16_t kAirwellMinRepeats
Definition: IRremoteESP8266.h:814
+
const uint16_t kMideaMinRepeat
Definition: IRremoteESP8266.h:923
+
int16_t clock
Definition: IRsend.h:115
+
const uint16_t kGicableBits
Definition: IRremoteESP8266.h:879
+
const uint16_t kGreeStateLength
Definition: IRremoteESP8266.h:883
+
uint32_t encodeNEC(uint16_t address, uint16_t command)
Calculate the raw NEC data based on address and command. Status: STABLE / Expected to work.
Definition: ir_NEC.cpp:48
+
decode_type_t
Enumerator for defining and numbering of supported IR protocol.
Definition: IRremoteESP8266.h:714
+
uint64_t encodeDoshisha(const uint8_t command, const uint8_t channel=0)
Encode Doshisha combining constant values with command and channel. Status: STABLE / Working.
Definition: ir_Doshisha.cpp:67
+
const uint16_t kCarrierAcBits
Definition: IRremoteESP8266.h:826
+ +
void sendHitachiAc344(const unsigned char data[], const uint16_t nbytes=kHitachiAc344StateLength, const uint16_t repeat=kHitachiAcDefaultRepeat)
Send a Hitachi A/C 43-byte/344-bit message. (HITACHI_AC344) Basically the same as sendHitatchiAC() ex...
Definition: ir_Hitachi.cpp:121
+
const uint16_t kDaikin2DefaultRepeat
Definition: IRremoteESP8266.h:843
+
const uint16_t kMultibracketsBits
Definition: IRremoteESP8266.h:945
+
const uint16_t kWhynterBits
Definition: IRremoteESP8266.h:1008
+ +
const uint16_t kAirwellBits
Definition: IRremoteESP8266.h:813
+
const uint16_t kHaierAcDefaultRepeat
Definition: IRremoteESP8266.h:888
+
void sendMidea(uint64_t data, uint16_t nbits=kMideaBits, uint16_t repeat=kMideaMinRepeat)
Send a Midea message Status: Alpha / Needs testing against a real device.
Definition: ir_Midea.cpp:52
+
const uint16_t kTrotecDefaultRepeat
Definition: IRremoteESP8266.h:1004
+
const uint16_t kFujitsuAcMinRepeat
Definition: IRremoteESP8266.h:874
+
void sendLG(uint64_t data, uint16_t nbits=kLgBits, uint16_t repeat=kNoRepeat)
Send an LG formatted message. (LG) Status: Beta / Should be working.
Definition: ir_LG.cpp:69
+
@ kPanasonicRkr
Definition: IRsend.h:148
+
const uint16_t kMitsubishi136MinRepeat
Definition: IRremoteESP8266.h:935
+
swingv_t
Common A/C settings for Vertical Swing.
Definition: IRsend.h:70
+
VIRTUAL void _delayMicroseconds(uint32_t usec)
An ESP8266 RTOS watch-dog timer friendly version of delayMicroseconds().
Definition: IRsend.cpp:114
+
bool clean
Definition: IRsend.h:112
+
void sendLegoPf(const uint64_t data, const uint16_t nbits=kLegoPfBits, const uint16_t repeat=kLegoPfMinRepeat)
Send a LEGO Power Functions message. Status: Beta / Should work.
Definition: ir_Lego.cpp:33
+
const uint16_t kArgoDefaultRepeat
Definition: IRremoteESP8266.h:823
+
uint8_t outputOn
Definition: IRsend.h:643
+
const uint16_t kHaierACStateLength
Definition: IRremoteESP8266.h:886
+
const uint16_t kHitachiAcStateLength
Definition: IRremoteESP8266.h:892
+ +
const uint16_t kDaikin176StateLength
Definition: IRremoteESP8266.h:855
+
const uint16_t kRC5XBits
Definition: IRremoteESP8266.h:963
+
const uint16_t kEpsonMinRepeat
Definition: IRremoteESP8266.h:870
+
const uint16_t kAmcorStateLength
Definition: IRremoteESP8266.h:818
+
bool send(const decode_type_t type, const uint64_t data, const uint16_t nbits, const uint16_t repeat=kNoRepeat)
Send a simple (up to 64 bits) IR message of a given type. An unknown/unsupported type will send nothi...
Definition: IRsend.cpp:749
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
@ R_LT0541_HTA_B
Definition: IRsend.h:137
+
void sendWhynter(const uint64_t data, const uint16_t nbits=kWhynterBits, const uint16_t repeat=kNoRepeat)
Send a Whynter message. Status: STABLE.
Definition: ir_Whynter.cpp:45
+
whirlpool_ac_remote_model_t
Whirlpool A/C model numbers.
Definition: IRsend.h:152
+
void sendMitsubishiAC(const unsigned char data[], const uint16_t nbytes=kMitsubishiACStateLength, const uint16_t repeat=kMitsubishiACMinRepeat)
Send a Mitsubishi 144-bit A/C formatted message. (MITSUBISHI_AC) Status: STABLE / Working.
Definition: ir_Mitsubishi.cpp:233
+
void sendNikai(uint64_t data, uint16_t nbits=kNikaiBits, uint16_t repeat=kNoRepeat)
Send a Nikai formatted message. Status: STABLE / Working.
Definition: ir_Nikai.cpp:37
+
const uint32_t kDefaultMessageGap
Definition: IRsend.h:41
+
const uint16_t kMaxAccurateUsecDelay
Definition: IRsend.h:39
+
uint16_t encodeJVC(uint8_t address, uint8_t command)
Calculate the raw JVC data based on address and command. Status: STABLE / Works fine.
Definition: ir_JVC.cpp:78
+
uint16_t onTimePeriod
Definition: IRsend.h:653
+
void sendAiwaRCT501(uint64_t data, uint16_t nbits=kAiwaRcT501Bits, uint16_t repeat=kAiwaRcT501MinRepeats)
Send an Aiwa RC T501 formatted message. Status: BETA / Should work.
Definition: ir_Aiwa.cpp:30
+
uint16_t IRpin
Definition: IRsend.h:655
+
const uint16_t kHitachiAc1StateLength
Definition: IRremoteESP8266.h:895
+
const uint16_t kCoolixBits
Definition: IRremoteESP8266.h:824
+
const uint16_t kMitsubishi112MinRepeat
Definition: IRremoteESP8266.h:938
+
void sendSymphony(uint64_t data, uint16_t nbits=kSymphonyBits, uint16_t repeat=kSymphonyDefaultRepeat)
Send a Symphony packet. Status: STABLE / Should be working.
Definition: ir_Symphony.cpp:42
+
void sendGeneric(const uint16_t headermark, const uint32_t headerspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t gap, const uint64_t data, const uint16_t nbits, const uint16_t frequency, const bool MSBfirst, const uint16_t repeat, const uint8_t dutycycle)
Generic method for sending simple protocol messages. Will send leading or trailing 0's if the nbits i...
Definition: IRsend.cpp:307
+ +
const uint16_t kSamsung36Bits
Definition: IRremoteESP8266.h:968
+
const uint16_t kMagiquestBits
Definition: IRremoteESP8266.h:921
+
static uint16_t minRepeats(const decode_type_t protocol)
Get the minimum number of repeats for a given protocol.
Definition: IRsend.cpp:557
+
const uint16_t kNeoclimaStateLength
Definition: IRremoteESP8266.h:949
+
gree_ac_remote_model_t
Gree A/C model numbers.
Definition: IRsend.h:129
+
const uint16_t kSamsungAcDefaultRepeat
Definition: IRremoteESP8266.h:973
+
const uint16_t kSanyoLC7461Bits
Definition: IRremoteESP8266.h:977
+
float degrees
Definition: IRsend.h:102
+
uint8_t _dutycycle
Definition: IRsend.h:657
+
bool celsius
Definition: IRsend.h:103
+
void sendLG2(uint64_t data, uint16_t nbits=kLgBits, uint16_t repeat=kNoRepeat)
Send an LG Variant-2 formatted message. (LG2) Status: Beta / Should be working.
Definition: ir_LG.cpp:103
+
const uint16_t kZepealMinRepeat
Definition: IRremoteESP8266.h:1011
+
VIRTUAL uint16_t mark(uint16_t usec)
Modulate the IR LED for the given period (usec) and at the duty cycle set.
Definition: IRsend.cpp:157
+
@ ARRY4
Definition: IRsend.h:125
+
@ ARDB1
Definition: IRsend.h:122
+ +
void sendDaikin152(const unsigned char data[], const uint16_t nbytes=kDaikin152StateLength, const uint16_t repeat=kDaikin152DefaultRepeat)
Send a Daikin152 (152-bit) A/C formatted message. Status: STABLE / Known Working.
Definition: ir_Daikin.cpp:3169
+
void sendAmcor(const unsigned char data[], const uint16_t nbytes=kAmcorStateLength, const uint16_t repeat=kAmcorDefaultRepeat)
Send a Amcor HVAC formatted message. Status: STABLE / Reported as working.
Definition: ir_Amcor.cpp:39
+
stdAc::swingv_t swingv
Definition: IRsend.h:105
+
void sendLasertag(uint64_t data, uint16_t nbits=kLasertagBits, uint16_t repeat=kLasertagMinRepeat)
Send a Lasertag packet/message. Status: STABLE / Working.
Definition: ir_Lasertag.cpp:33
+
hitachi_ac1_remote_model_t
HITACHI_AC1 A/C model numbers.
Definition: IRsend.h:135
+
void sendEpson(uint64_t data, uint16_t nbits=kEpsonBits, uint16_t repeat=kEpsonMinRepeat)
Send an Epson formatted message. Status: Beta / Probably works.
Definition: ir_Epson.cpp:24
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
void sendManchesterData(const uint16_t half_period, const uint64_t data, const uint16_t nbits, const bool MSBfirst=true, const bool GEThomas=true)
Generic method for sending Manchester code data. Will send leading or trailing 0's if the nbits is la...
Definition: IRsend.cpp:445
+
const uint16_t kAiwaRcT501MinRepeats
Definition: IRremoteESP8266.h:816
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+ +
const uint16_t kMitsubishiMinRepeat
Definition: IRremoteESP8266.h:929
+
uint64_t encodeSanyoLC7461(uint16_t address, uint8_t command)
Construct a Sanyo LC7461 message.
Definition: ir_Sanyo.cpp:61
+
@ ARJW2
Definition: IRsend.h:124
+
const uint16_t kArgoStateLength
Definition: IRremoteESP8266.h:821
+ +
uint32_t encodeSAMSUNG(const uint8_t customer, const uint8_t command)
Construct a raw Samsung message from the supplied customer(address) & command. Status: STABLE / Shoul...
Definition: ir_Samsung.cpp:89
+
const uint16_t kPanasonicBits
Definition: IRremoteESP8266.h:952
+
int16_t model
Definition: IRsend.h:99
+
uint64_t toggleRC6(const uint64_t data, const uint16_t nbits=kRC6Mode0Bits)
Flip the toggle bit of a Philips RC-6 data message. Used to indicate a change of remote button's stat...
Definition: ir_RC5_RC6.cpp:157
+
void sendSony(const uint64_t data, const uint16_t nbits=kSony20Bits, const uint16_t repeat=kSonyMinRepeat)
Send a standard Sony/SIRC(Serial Infra-Red Control) message. (40kHz) Status: STABLE / Known working.
Definition: ir_Sony.cpp:46
+
const uint8_t kDutyMax
Definition: IRsend.h:36
+
uint32_t _freq_unittest
Definition: IRsend.h:651
+
const uint16_t kDaikin152StateLength
Definition: IRremoteESP8266.h:852
+
uint32_t encodeLG(uint16_t address, uint16_t command)
Construct a raw 28-bit LG message code from the supplied address & command. Status: STABLE / Works.
Definition: ir_LG.cpp:131
+
void sendRaw(const uint16_t buf[], const uint16_t len, const uint16_t hz)
Send a raw IRremote message.
Definition: IRsend.cpp:539
+
void sendMultibrackets(const uint64_t data, const uint16_t nbits=kMultibracketsBits, const uint16_t repeat=kMultibracketsDefaultRepeat)
Send a Multibrackets formatted message. Status: BETA / Appears to be working.
Definition: ir_Multibrackets.cpp:26
+ +
const uint16_t kHaierACYRW02StateLength
Definition: IRremoteESP8266.h:889
+
uint64_t encodeRC6(const uint32_t address, const uint8_t command, const uint16_t mode=kRC6Mode0Bits)
Encode a Philips RC-6 data message. Status: Beta / Should be working.
Definition: ir_RC5_RC6.cpp:171
+
const uint16_t kMultibracketsDefaultRepeat
Definition: IRremoteESP8266.h:946
+
void sendMitsubishi112(const unsigned char data[], const uint16_t nbytes=kMitsubishi112StateLength, const uint16_t repeat=kMitsubishi112MinRepeat)
Send a Mitsubishi 112-bit A/C formatted message. (MITSUBISHI112) Status: Stable / Reported as working...
Definition: ir_Mitsubishi.cpp:1184
+
@ kPanasonicCkp
Definition: IRsend.h:147
+
void sendWhirlpoolAC(const unsigned char data[], const uint16_t nbytes=kWhirlpoolAcStateLength, const uint16_t repeat=kWhirlpoolAcDefaultRepeat)
Send a Whirlpool A/C message. Status: BETA / Probably works.
Definition: ir_Whirlpool.cpp:50
+ +
void sendData(uint16_t onemark, uint32_t onespace, uint16_t zeromark, uint32_t zerospace, uint64_t data, uint16_t nbits, bool MSBfirst=true)
Generic method for sending data that is common to most protocols. Will send leading or trailing 0's i...
Definition: IRsend.cpp:246
+
const uint16_t kGoodweatherBits
Definition: IRremoteESP8266.h:881
+
void sendKelvinator(const unsigned char data[], const uint16_t nbytes=kKelvinatorStateLength, const uint16_t repeat=kKelvinatorDefaultRepeat)
Send a Kelvinator A/C message. Status: STABLE / Known working.
Definition: ir_Kelvinator.cpp:78
+
VIRTUAL void ledOn()
Turn on the IR LED.
Definition: IRsend.cpp:60
+
const uint16_t kGicableMinRepeat
Definition: IRremoteESP8266.h:880
+
void sendHitachiAC1(const unsigned char data[], const uint16_t nbytes=kHitachiAc1StateLength, const uint16_t repeat=kHitachiAcDefaultRepeat)
Send a Hitachi 13 byte/224-bit A/C formatted message. (HITACHI_AC1) Status: STABLE / Confirmed Workin...
Definition: ir_Hitachi.cpp:87
+
const uint16_t kDaikin216StateLength
Definition: IRremoteESP8266.h:858
+
void sendGICable(uint64_t data, uint16_t nbits=kGicableBits, uint16_t repeat=kGicableMinRepeat)
Send a raw G.I. Cable formatted message. Status: Alpha / Untested.
Definition: ir_GICable.cpp:37
+
const uint16_t kSamsungAcStateLength
Definition: IRremoteESP8266.h:969
+
@ DG11J13A
Definition: IRsend.h:153
+
void sendSharp(const uint16_t address, const uint16_t command, const uint16_t nbits=kSharpBits, const uint16_t repeat=kNoRepeat)
Send a Sharp message Status: DEPRECATED / Previously working fine.
Definition: ir_Sharp.cpp:134
+
panasonic_ac_remote_model_t
Panasonic A/C model numbers.
Definition: IRsend.h:141
+ +
swingh_t
Common A/C settings for Horizontal Swing.
Definition: IRsend.h:83
+ +
@ AKB75215403
Definition: IRsend.h:160
+
void sendDenon(uint64_t data, uint16_t nbits=kDenonBits, uint16_t repeat=kNoRepeat)
Send a Denon formatted message. Status: STABLE / Should be working.
Definition: ir_Denon.cpp:48
+
void sendCarrierAC64(uint64_t data, uint16_t nbits=kCarrierAc64Bits, uint16_t repeat=kCarrierAc64MinRepeat)
Send a Carrier 64bit HVAC formatted message. Status: STABLE / Known to be working.
Definition: ir_Carrier.cpp:178
+
void sendPioneer(const uint64_t data, const uint16_t nbits=kPioneerBits, const uint16_t repeat=kNoRepeat)
Send a raw Pioneer formatted message. Status: STABLE / Expected to be working.
Definition: ir_Pioneer.cpp:46
+
@ YAW1F
Definition: IRsend.h:130
+
const uint16_t kSymphonyBits
Definition: IRremoteESP8266.h:992
+ +
const uint16_t kDaikin128StateLength
Definition: IRremoteESP8266.h:849
+
const uint16_t kRC6Mode0Bits
Definition: IRremoteESP8266.h:964
+
const uint16_t kDaikin176DefaultRepeat
Definition: IRremoteESP8266.h:857
+
void sendPanasonic64(const uint64_t data, const uint16_t nbits=kPanasonicBits, const uint16_t repeat=kNoRepeat)
Send a Panasonic formatted message. Status: STABLE / Should be working.
Definition: ir_Panasonic.cpp:74
+
const uint16_t kMitsubishiHeavy152MinRepeat
Definition: IRremoteESP8266.h:944
+
void sendHaierAC(const unsigned char data[], const uint16_t nbytes=kHaierACStateLength, const uint16_t repeat=kHaierAcDefaultRepeat)
Send a Haier A/C formatted message. (HSU07-HEA03 remote) Status: STABLE / Known to be working.
Definition: ir_Haier.cpp:45
+
void sendSamsung36(const uint64_t data, const uint16_t nbits=kSamsung36Bits, const uint16_t repeat=kNoRepeat)
Send a Samsung 36-bit formatted message. Status: Alpha / Experimental.
Definition: ir_Samsung.cpp:154
+
const uint16_t kNoRepeat
Definition: IRremoteESP8266.h:810
+
uint16_t offTimePeriod
Definition: IRsend.h:654
+
const uint16_t kSony20Bits
Definition: IRremoteESP8266.h:989
+
const uint16_t kMitsubishiACMinRepeat
Definition: IRremoteESP8266.h:932
+
void sendSony38(const uint64_t data, const uint16_t nbits=kSony20Bits, const uint16_t repeat=kSonyMinRepeat+1)
Send an alternative 38kHz Sony/SIRC(Serial Infra-Red Control) message. Status: STABLE / Known working...
Definition: ir_Sony.cpp:62
+
uint32_t encodeSony(const uint16_t nbits, const uint16_t command, const uint16_t address, const uint16_t extended=0)
Convert Sony/SIRC command, address, & extended bits into sendSony format. Status: STABLE / Should be ...
Definition: ir_Sony.cpp:88
+ +
@ kPanasonicUnknown
Definition: IRsend.h:142
+
fujitsu_ac_remote_model_t
Fujitsu A/C model numbers.
Definition: IRsend.h:120
+
const uint16_t kPanasonicAcDefaultRepeat
Definition: IRremoteESP8266.h:958
+
const uint16_t kSymphonyDefaultRepeat
Definition: IRremoteESP8266.h:993
+
@ ARREB1E
Definition: IRsend.h:123
+
void sendPanasonicAC(const unsigned char data[], const uint16_t nbytes=kPanasonicAcStateLength, const uint16_t repeat=kPanasonicAcDefaultRepeat)
Send a Panasonic A/C message. Status: STABLE / Work with real device(s).
Definition: ir_Panasonic.cpp:173
+
stdAc::swingh_t swingh
Definition: IRsend.h:106
+
const uint16_t kCoolixDefaultRepeat
Definition: IRremoteESP8266.h:825
+
@ kPanasonicNke
Definition: IRsend.h:144
+
@ GE6711AR2853M
Definition: IRsend.h:159
+
void sendHitachiAc3(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat=kHitachiAcDefaultRepeat)
Send a Hitachi(3) A/C formatted message. (HITACHI_AC3) Status: STABLE / Working fine.
Definition: ir_Hitachi.cpp:1361
+
const uint16_t kTcl112AcDefaultRepeat
Definition: IRremoteESP8266.h:996
+
const uint16_t kDelonghiAcDefaultRepeat
Definition: IRremoteESP8266.h:862
+
void sendToshibaAC(const unsigned char data[], const uint16_t nbytes=kToshibaACStateLength, const uint16_t repeat=kToshibaACMinRepeat)
Send a Toshiba A/C message. Status: STABLE / Working.
Definition: ir_Toshiba.cpp:44
+
const uint16_t kCoronaAcStateLength
Definition: IRremoteESP8266.h:833
+
void sendRC5(const uint64_t data, uint16_t nbits=kRC5XBits, const uint16_t repeat=kNoRepeat)
Send a Philips RC-5/RC-5X packet. Status: RC-5 (stable), RC-5X (alpha)
Definition: ir_RC5_RC6.cpp:61
+
void sendMitsubishi(uint64_t data, uint16_t nbits=kMitsubishiBits, uint16_t repeat=kMitsubishiMinRepeat)
Send the supplied Mitsubishi 16-bit message. Status: STABLE / Working.
Definition: ir_Mitsubishi.cpp:104
+
void sendAirwell(uint64_t data, uint16_t nbits=kAirwellBits, uint16_t repeat=kAirwellMinRepeats)
Send an Airwell Manchester Code formatted message. Status: BETA / Appears to be working.
Definition: ir_Airwell.cpp:28
+
const uint16_t kDoshishaBits
Definition: IRremoteESP8266.h:868
+
const uint16_t kCarrierAc40Bits
Definition: IRremoteESP8266.h:828
+ +
const uint16_t kTrotecStateLength
Definition: IRremoteESP8266.h:1002
+
const uint16_t kWhirlpoolAcDefaultRepeat
Definition: IRremoteESP8266.h:1007
+
void sendSAMSUNG(const uint64_t data, const uint16_t nbits=kSamsungBits, const uint16_t repeat=kNoRepeat)
Send a 32-bit Samsung formatted message. Status: STABLE / Should be working.
Definition: ir_Samsung.cpp:75
+
const uint16_t kHitachiAc424StateLength
Definition: IRremoteESP8266.h:905
+
const uint16_t kMitsubishiHeavy88StateLength
Definition: IRremoteESP8266.h:939
+
void sendNeoclima(const unsigned char data[], const uint16_t nbytes=kNeoclimaStateLength, const uint16_t repeat=kNeoclimaMinRepeat)
Send a Neoclima message. Status: STABLE / Known to be working.
Definition: ir_Neoclima.cpp:41
+
void sendSharpRaw(const uint64_t data, const uint16_t nbits=kSharpBits, const uint16_t repeat=kNoRepeat)
Send a (raw) Sharp message.
Definition: ir_Sharp.cpp:64
+ +
void sendGree(const uint64_t data, const uint16_t nbits=kGreeBits, const uint16_t repeat=kGreeDefaultRepeat)
Send a Gree Heat Pump formatted message. Status: STABLE / Working.
Definition: ir_Gree.cpp:76
+ +
const uint16_t kMitsubishiBits
Definition: IRremoteESP8266.h:926
+
void sendMitsubishi136(const unsigned char data[], const uint16_t nbytes=kMitsubishi136StateLength, const uint16_t repeat=kMitsubishi136MinRepeat)
Send a Mitsubishi 136-bit A/C message. (MITSUBISHI136) Status: BETA / Probably working....
Definition: ir_Mitsubishi.cpp:812
+
Enumerators and Structures for the Common A/C API.
Definition: IRsend.h:44
+
@ R_LT0541_HTA_A
Definition: IRsend.h:136
+
const uint16_t kPanasonicAcStateLength
Definition: IRremoteESP8266.h:954
+
void sendMitsubishiHeavy88(const unsigned char data[], const uint16_t nbytes=kMitsubishiHeavy88StateLength, const uint16_t repeat=kMitsubishiHeavy88MinRepeat)
Send a MitsubishiHeavy 88-bit A/C message. Status: BETA / Appears to be working. Needs testing agains...
Definition: ir_MitsubishiHeavy.cpp:45
+
void sendVestelAc(const uint64_t data, const uint16_t nbits=kVestelAcBits, const uint16_t repeat=kNoRepeat)
Send a Vestel message Status: STABLE / Working.
Definition: ir_Vestel.cpp:38
+
const uint16_t kMideaBits
Definition: IRremoteESP8266.h:922
+
const uint16_t kKelvinatorStateLength
Definition: IRremoteESP8266.h:910
+
void sendMidea24(const uint64_t data, const uint16_t nbits=kMidea24Bits, const uint16_t repeat=kMidea24MinRepeat)
Send a Midea24 formatted message. Status: STABLE / Confirmed working on a real device.
Definition: ir_Midea.cpp:479
+
static uint16_t defaultBits(const decode_type_t protocol)
Get the default number of bits for a given protocol.
Definition: IRsend.cpp:598
+
decode_type_t protocol
Definition: IRsend.h:98
+ +
const uint16_t kDaikin216DefaultRepeat
Definition: IRremoteESP8266.h:860
+ +
bool beep
Definition: IRsend.h:113
+
const uint16_t kWhirlpoolAcStateLength
Definition: IRremoteESP8266.h:1005
+
const uint16_t kNECBits
Definition: IRremoteESP8266.h:948
+
const uint16_t kDenonBits
Definition: IRremoteESP8266.h:863
+
const uint16_t kZepealBits
Definition: IRremoteESP8266.h:1010
+
bool filter
Definition: IRsend.h:111
+
const uint16_t kCarrierAc40MinRepeat
Definition: IRremoteESP8266.h:829
+
const uint16_t kMidea24Bits
Definition: IRremoteESP8266.h:924
+
void sendDelonghiAc(uint64_t data, uint16_t nbits=kDelonghiAcBits, uint16_t repeat=kDelonghiAcDefaultRepeat)
Send a Delonghi A/C formatted message. Status: STABLE / Reported as working on a real device.
Definition: ir_Delonghi.cpp:38
+
const uint16_t kDaikin160DefaultRepeat
Definition: IRremoteESP8266.h:848
+
void _sendSony(const uint64_t data, const uint16_t nbits, const uint16_t repeat, const uint16_t freq)
Internal procedure to generate a Sony/SIRC(Serial Infra-Red Control) message Status: STABLE / Known w...
Definition: ir_Sony.cpp:73
+
const uint16_t kToshibaACMinRepeat
Definition: IRremoteESP8266.h:1001
+
void enableIROut(uint32_t freq, uint8_t duty=kDutyDefault)
Set the output frequency modulation and duty cycle.
Definition: IRsend.cpp:92
+ +
const uint16_t kHitachiAc344StateLength
Definition: IRremoteESP8266.h:903
+
@ kPanasonicDke
Definition: IRsend.h:145
+
const uint16_t kCarrierAc64Bits
Definition: IRremoteESP8266.h:830
+
const uint16_t kDaikin128DefaultRepeat
Definition: IRremoteESP8266.h:851
+
const uint16_t kPioneerBits
Definition: IRremoteESP8266.h:959
+
const uint16_t kSharpAcStateLength
Definition: IRremoteESP8266.h:982
+
void sendSharpAc(const unsigned char data[], const uint16_t nbytes=kSharpAcStateLength, const uint16_t repeat=kSharpAcDefaultRepeat)
Send a Sharp A/C message. Status: Alpha / Untested.
Definition: ir_Sharp.cpp:227
+
@ kPanasonicLke
Definition: IRsend.h:143
+
const uint16_t kGreeBits
Definition: IRremoteESP8266.h:884
+
void sendCarrierAC(uint64_t data, uint16_t nbits=kCarrierAcBits, uint16_t repeat=kCarrierAcMinRepeat)
Send a Carrier HVAC formatted message. Status: STABLE / Works on real devices.
Definition: ir_Carrier.cpp:57
+
const uint16_t kJvcBits
Definition: IRremoteESP8266.h:909
+
const uint16_t kDaikinStateLength
Definition: IRremoteESP8266.h:836
+
const uint16_t kLasertagBits
Definition: IRremoteESP8266.h:913
+
void sendDaikin160(const unsigned char data[], const uint16_t nbytes=kDaikin160StateLength, const uint16_t repeat=kDaikin160DefaultRepeat)
Send a Daikin160 (160-bit) A/C formatted message. Status: STABLE / Confirmed working.
Definition: ir_Daikin.cpp:1840
+
const uint16_t kAiwaRcT501Bits
Definition: IRremoteESP8266.h:815
+
void sendDaikin2(const unsigned char data[], const uint16_t nbytes=kDaikin2StateLength, const uint16_t repeat=kDaikin2DefaultRepeat)
Send a Daikin2 (312-bit) A/C formatted message. Status: STABLE / Expected to work.
Definition: ir_Daikin.cpp:689
+
@ ARRAH2E
Definition: IRsend.h:121
+
const uint16_t kToshibaACStateLength
Definition: IRremoteESP8266.h:999
+
const uint16_t kTecoBits
Definition: IRremoteESP8266.h:997
+
void sendMitsubishi2(uint64_t data, uint16_t nbits=kMitsubishiBits, uint16_t repeat=kMitsubishiMinRepeat)
Send a supplied second variant Mitsubishi 16-bit message. Status: BETA / Probably works.
Definition: ir_Mitsubishi.cpp:161
+
const uint16_t kInaxMinRepeat
Definition: IRremoteESP8266.h:908
+
VIRTUAL void ledOff()
Turn off the IR LED.
Definition: IRsend.cpp:53
+ +
const uint8_t kSherwoodBits
Definition: IRremoteESP8266.h:985
+
stdAc::opmode_t mode
Definition: IRsend.h:101
+
const uint16_t kDaikinDefaultRepeat
Definition: IRremoteESP8266.h:840
+
const uint16_t kDaikin64DefaultRepeat
Definition: IRremoteESP8266.h:845
+
void sendInax(const uint64_t data, const uint16_t nbits=kInaxBits, const uint16_t repeat=kInaxMinRepeat)
Send a Inax Toilet formatted message. Status: STABLE / Working.
Definition: ir_Inax.cpp:31
+
lg_ac_remote_model_t
LG A/C model numbers.
Definition: IRsend.h:158
+
const uint16_t kMitsubishiHeavy88MinRepeat
Definition: IRremoteESP8266.h:941
+ +
const uint16_t kHitachiAcDefaultRepeat
Definition: IRremoteESP8266.h:894
+
bool econo
Definition: IRsend.h:109
+
void sendSherwood(uint64_t data, uint16_t nbits=kSherwoodBits, uint16_t repeat=kSherwoodMinRepeat)
Send an IR command to a Sherwood device. Status: STABLE / Known working.
Definition: ir_Sherwood.cpp:21
+
const uint16_t kMidea24MinRepeat
Definition: IRremoteESP8266.h:925
+
void sendMitsubishiHeavy152(const unsigned char data[], const uint16_t nbytes=kMitsubishiHeavy152StateLength, const uint16_t repeat=kMitsubishiHeavy152MinRepeat)
Send a MitsubishiHeavy 152-bit A/C message. Status: BETA / Appears to be working. Needs testing again...
Definition: ir_MitsubishiHeavy.cpp:62
+
const uint16_t kDishBits
Definition: IRremoteESP8266.h:866
+
const uint16_t kDishMinRepeat
Definition: IRremoteESP8266.h:867
+ +
void sendPanasonic(const uint16_t address, const uint32_t data, const uint16_t nbits=kPanasonicBits, const uint16_t repeat=kNoRepeat)
Send a Panasonic formatted message. Status: STABLE, but DEPRECATED.
Definition: ir_Panasonic.cpp:91
+
VIRTUAL void space(uint32_t usec)
Turn the pin (LED) off for a given time. Sends an IR space for the specified number of microseconds....
Definition: IRsend.cpp:194
+
const uint16_t kHitachiAc2StateLength
Definition: IRremoteESP8266.h:897
+
void sendGC(uint16_t buf[], uint16_t len)
Send a shortened GlobalCache (GC) IRdb/control tower formatted message. Status: STABLE / Known workin...
Definition: ir_GlobalCache.cpp:35
+
uint16_t encodeRC5(const uint8_t address, const uint8_t command, const bool key_released=false)
Encode a Philips RC-5 data message. Status: Beta / Should be working.
Definition: ir_RC5_RC6.cpp:115
+
void sendJVC(uint64_t data, uint16_t nbits=kJvcBits, uint16_t repeat=kNoRepeat)
Send a JVC formatted message. Status: STABLE / Working.
Definition: ir_JVC.cpp:46
+
void sendDoshisha(const uint64_t data, uint16_t nbits=kDoshishaBits, const uint16_t repeat=kNoRepeat)
Send a Doshisha formatted message. Status: STABLE / Works on real device.
Definition: ir_Doshisha.cpp:53
+ +
uint64_t toggleRC5(const uint64_t data)
Flip the toggle bit of a Philips RC-5/RC-5X data message. Used to indicate a change of remote button'...
Definition: ir_RC5_RC6.cpp:142
+
void sendDaikin(const unsigned char data[], const uint16_t nbytes=kDaikinStateLength, const uint16_t repeat=kDaikinDefaultRepeat)
Send a Daikin 280-bit A/C formatted message. Status: STABLE.
Definition: ir_Daikin.cpp:61
+
const uint16_t kCarrierAcMinRepeat
Definition: IRremoteESP8266.h:827
+
const uint16_t kNikaiBits
Definition: IRremoteESP8266.h:947
+
uint64_t encodeMagiQuest(const uint32_t wand_id, const uint16_t magnitude)
Encode a MagiQuest wand_id, and a magnitude into a single 64bit value. (Only 48 bits of real data + 8...
Definition: ir_Magiquest.cpp:42
+ +
const uint16_t kKelvinatorDefaultRepeat
Definition: IRremoteESP8266.h:912
+
void sendHitachiAC2(const unsigned char data[], const uint16_t nbytes=kHitachiAc2StateLength, const uint16_t repeat=kHitachiAcDefaultRepeat)
Send a Hitachi 53 byte/424-bit A/C formatted message. (HITACHI_AC2) Basically the same as sendHitatch...
Definition: ir_Hitachi.cpp:105
+
const uint16_t kLutronBits
Definition: IRremoteESP8266.h:920
+
void sendDaikin128(const unsigned char data[], const uint16_t nbytes=kDaikin128StateLength, const uint16_t repeat=kDaikin128DefaultRepeat)
Send a Daikin128 (128-bit) A/C formatted message. Status: STABLE / Known Working.
Definition: ir_Daikin.cpp:2605
+
void sendCarrierAC40(uint64_t data, uint16_t nbits=kCarrierAc40Bits, uint16_t repeat=kCarrierAc40MinRepeat)
Send a Carrier 40bit HVAC formatted message. Status: STABLE / Tested against a real device.
Definition: ir_Carrier.cpp:129
+
const uint16_t kSharpAcDefaultRepeat
Definition: IRremoteESP8266.h:984
+ +
void sendTrotec(const unsigned char data[], const uint16_t nbytes=kTrotecStateLength, const uint16_t repeat=kTrotecDefaultRepeat)
Send a Trotec message. Status: Beta / Probably Working.
Definition: ir_Trotec.cpp:43
+
void sendCoronaAc(const uint8_t data[], const uint16_t nbytes=kCoronaAcStateLength, const uint16_t repeat=kNoRepeat)
Send a CoronaAc formatted message. Status: STABLE / Working on real device.
Definition: ir_Corona.cpp:51
+
bool light
Definition: IRsend.h:110
+
stdAc::fanspeed_t fanspeed
Definition: IRsend.h:104
+
const uint16_t kTcl112AcStateLength
Definition: IRremoteESP8266.h:994
+
void sendRCMM(uint64_t data, uint16_t nbits=kRCMMBits, uint16_t repeat=kNoRepeat)
Send a Philips RC-MM packet. Status: STABLE / Should be working.
Definition: ir_RCMM.cpp:46
+
void sendManchester(const uint16_t headermark, const uint32_t headerspace, const uint16_t half_period, const uint16_t footermark, const uint32_t gap, const uint64_t data, const uint16_t nbits, const uint16_t frequency=38, const bool MSBfirst=true, const uint16_t repeat=kNoRepeat, const uint8_t dutycycle=kDutyDefault, const bool GEThomas=true)
Generic method for sending Manchester code messages. Will send leading or trailing 0's if the nbits i...
Definition: IRsend.cpp:506
+
const uint16_t kDaikin160StateLength
Definition: IRremoteESP8266.h:846
+
void sendHitachiAC(const unsigned char data[], const uint16_t nbytes=kHitachiAcStateLength, const uint16_t repeat=kHitachiAcDefaultRepeat)
Send a Hitachi 28-byte/224-bit A/C formatted message. (HITACHI_AC) Status: STABLE / Working.
Definition: ir_Hitachi.cpp:66
+
const uint16_t kDaikin2StateLength
Definition: IRremoteESP8266.h:841
+
void sendElectraAC(const unsigned char data[], const uint16_t nbytes=kElectraAcStateLength, const uint16_t repeat=kNoRepeat)
Send a Electra A/C formatted message. Status: Alpha / Needs testing against a real device.
Definition: ir_Electra.cpp:41
+ +
const uint16_t kSherwoodMinRepeat
Definition: IRremoteESP8266.h:986
+
const uint16_t kCarrierAc64MinRepeat
Definition: IRremoteESP8266.h:831
+
@ DG11J191
Definition: IRsend.h:154
+
void begin()
Enable the pin for output.
Definition: IRsend.cpp:45
+
void sendFujitsuAC(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat=kFujitsuAcMinRepeat)
Send a Fujitsu A/C formatted message. Status: STABLE / Known Good.
Definition: ir_Fujitsu.cpp:47
+ +
uint32_t encodeSharp(const uint16_t address, const uint16_t command, const uint16_t expansion=1, const uint16_t check=0, const bool MSBfirst=false)
Encode a (raw) Sharp message from it's components. Status: STABLE / Works okay.
Definition: ir_Sharp.cpp:99
+ +
const uint16_t kLegoPfBits
Definition: IRremoteESP8266.h:915
+
const uint16_t kSharpBits
Definition: IRremoteESP8266.h:981
+
int16_t sleep
Definition: IRsend.h:114
+
bool power
Definition: IRsend.h:100
+ +
void sendHitachiAc424(const unsigned char data[], const uint16_t nbytes=kHitachiAc424StateLength, const uint16_t repeat=kHitachiAcDefaultRepeat)
Send a Hitachi 53-byte/424-bit A/C formatted message. (HITACHI_AC424) Status: STABLE / Reported as wo...
Definition: ir_Hitachi.cpp:949
+
void sendTeco(const uint64_t data, const uint16_t nbits=kTecoBits, const uint16_t repeat=kNoRepeat)
Send a Teco A/C message. Status: Beta / Probably working.
Definition: ir_Teco.cpp:39
+ +
const uint16_t kMitsubishi136StateLength
Definition: IRremoteESP8266.h:933
+
void sendLutron(uint64_t data, uint16_t nbits=kLutronBits, uint16_t repeat=kNoRepeat)
Send a Lutron formatted message. Status: Stable / Appears to be working for real devices.
Definition: ir_Lutron.cpp:41
+
void sendSamsungAC(const unsigned char data[], const uint16_t nbytes=kSamsungAcStateLength, const uint16_t repeat=kSamsungAcDefaultRepeat)
Send a Samsung A/C message. Status: Stable / Known working.
Definition: ir_Samsung.cpp:235
+
uint64_t encodePanasonic(const uint16_t manufacturer, const uint8_t device, const uint8_t subdevice, const uint8_t function)
Calculate the raw Panasonic data based on device, subdevice, & function. Status: STABLE / Should be w...
Definition: ir_Panasonic.cpp:105
+
void sendSanyoLC7461(const uint64_t data, const uint16_t nbits=kSanyoLC7461Bits, const uint16_t repeat=kNoRepeat)
Send a Sanyo LC7461 message. Status: BETA / Probably works.
Definition: ir_Sanyo.cpp:93
+
IRsend(uint16_t IRsendPin, bool inverted=false, bool use_modulation=true)
Constructor for an IRsend object.
Definition: IRsend.cpp:28
+
void sendDISH(uint64_t data, uint16_t nbits=kDishBits, uint16_t repeat=kDishMinRepeat)
Send a DISH NETWORK formatted message. Status: STABLE / Working.
Definition: ir_Dish.cpp:48
+
const uint16_t kRCMMBits
Definition: IRremoteESP8266.h:966
+
const uint8_t kVestelAcBits
Definition: IRremoteESP8266.h:1009
+
const uint16_t kInaxBits
Definition: IRremoteESP8266.h:907
+
@ YBOFB
Definition: IRsend.h:131
+
const uint16_t kLegoPfMinRepeat
Definition: IRremoteESP8266.h:916
+
const uint16_t kAmcorDefaultRepeat
Definition: IRremoteESP8266.h:820
+
void sendDaikin216(const unsigned char data[], const uint16_t nbytes=kDaikin216StateLength, const uint16_t repeat=kDaikin216DefaultRepeat)
Send a Daikin216 (216-bit) A/C formatted message. Status: Alpha / Untested on a real device.
Definition: ir_Daikin.cpp:1476
+
const uint16_t kSamsungBits
Definition: IRremoteESP8266.h:967
+
uint64_t encodePioneer(uint16_t address, uint16_t command)
Calculate the raw Pioneer data code based on two NEC sub-codes Status: STABLE / Expected to work.
Definition: ir_Pioneer.cpp:81
+
const uint16_t kDaikin64Bits
Definition: IRremoteESP8266.h:844
+
bool quiet
Definition: IRsend.h:107
+
uint16_t encodeRC5X(const uint8_t address, const uint8_t command, const bool key_released=false)
Encode a Philips RC-5X data message. Status: Beta / Should be working.
Definition: ir_RC5_RC6.cpp:127
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
const uint16_t kLasertagMinRepeat
Definition: IRremoteESP8266.h:914
+
const uint8_t kDutyDefault
Definition: IRsend.h:35
+
bool turbo
Definition: IRsend.h:108
+
void sendMagiQuest(const uint64_t data, const uint16_t nbits=kMagiquestBits, const uint16_t repeat=kNoRepeat)
Send a MagiQuest formatted message. Status: Beta / Should be working.
Definition: ir_Magiquest.cpp:25
+
bool modulation
Definition: IRsend.h:658
+
const uint16_t kNeoclimaMinRepeat
Definition: IRremoteESP8266.h:951
+
const uint16_t kMitsubishi112StateLength
Definition: IRremoteESP8266.h:936
+ +
void sendArgo(const unsigned char data[], const uint16_t nbytes=kArgoStateLength, const uint16_t repeat=kArgoDefaultRepeat)
Send a Argo A/C formatted message. Status: BETA / Probably works.
Definition: ir_Argo.cpp:40
+
void sendTcl112Ac(const unsigned char data[], const uint16_t nbytes=kTcl112AcStateLength, const uint16_t repeat=kTcl112AcDefaultRepeat)
Send a TCL 112-bit A/C message. Status: Beta / Probably working.
Definition: ir_Tcl.cpp:33
+
@ kPanasonicJke
Definition: IRsend.h:146
+ +
const uint16_t kSonyMinRepeat
Definition: IRremoteESP8266.h:991
+
void sendCOOLIX(uint64_t data, uint16_t nbits=kCoolixBits, uint16_t repeat=kCoolixDefaultRepeat)
Send a Coolix message Status: STABLE / Confirmed Working.
Definition: ir_Coolix.cpp:51
+
const uint16_t kEpsonBits
Definition: IRremoteESP8266.h:869
+
void sendNEC(uint64_t data, uint16_t nbits=kNECBits, uint16_t repeat=kNoRepeat)
Send a raw NEC(Renesas) formatted message. Status: STABLE / Known working.
Definition: ir_NEC.cpp:28
+
void sendMWM(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat=kNoRepeat)
Send a MWM packet/message. Status: Implemented.
Definition: ir_MWM.cpp:37
+
void sendDaikin64(const uint64_t data, const uint16_t nbits=kDaikin64Bits, const uint16_t repeat=kDaikin64DefaultRepeat)
Send a Daikin64 (64-bit) A/C formatted message. Status: Beta / Probably Working.
Definition: ir_Daikin.cpp:3558
+
void sendRC6(const uint64_t data, const uint16_t nbits=kRC6Mode0Bits, const uint16_t repeat=kNoRepeat)
Send a Philips RC-6 packet. Status: Stable.
Definition: ir_RC5_RC6.cpp:190
+
const int8_t kPeriodOffset
Definition: IRsend.h:26
+
const uint16_t kLgBits
Definition: IRremoteESP8266.h:917
+
void sendDaikin176(const unsigned char data[], const uint16_t nbytes=kDaikin176StateLength, const uint16_t repeat=kDaikin176DefaultRepeat)
Send a Daikin176 (176-bit) A/C formatted message. Status: Alpha / Untested on a real device.
Definition: ir_Daikin.cpp:2212
+
const uint16_t kGoodweatherMinRepeat
Definition: IRremoteESP8266.h:882
+
const uint16_t kElectraAcStateLength
Definition: IRremoteESP8266.h:871
+
const uint16_t kGreeDefaultRepeat
Definition: IRremoteESP8266.h:885
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+
void sendGoodweather(const uint64_t data, const uint16_t nbits=kGoodweatherBits, const uint16_t repeat=kGoodweatherMinRepeat)
Send a Goodweather HVAC formatted message. Status: BETA / Needs testing on real device.
Definition: ir_Goodweather.cpp:33
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtext_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtext_8cpp.html new file mode 100644 index 000000000..cbef4a002 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtext_8cpp.html @@ -0,0 +1,2807 @@ + + + + + + + +IRremoteESP8266: src/IRtext.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
IRtext.cpp File Reference
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const PROGMEM char * kUnknownStr = D_STR_UNKNOWN
 "Unknown" More...
 
const PROGMEM char * kProtocolStr = D_STR_PROTOCOL
 "Protocol" More...
 
const PROGMEM char * kPowerStr = D_STR_POWER
 "Power" More...
 
const PROGMEM char * kOnStr = D_STR_ON
 "On" More...
 
const PROGMEM char * kOffStr = D_STR_OFF
 "Off" More...
 
const PROGMEM char * kModeStr = D_STR_MODE
 "Mode" More...
 
const PROGMEM char * kToggleStr = D_STR_TOGGLE
 "Toggle" More...
 
const PROGMEM char * kTurboStr = D_STR_TURBO
 "Turbo" More...
 
const PROGMEM char * kSuperStr = D_STR_SUPER
 "Super" More...
 
const PROGMEM char * kSleepStr = D_STR_SLEEP
 "Sleep" More...
 
const PROGMEM char * kLightStr = D_STR_LIGHT
 "Light" More...
 
const PROGMEM char * kPowerfulStr = D_STR_POWERFUL
 "Powerful" More...
 
const PROGMEM char * kQuietStr = D_STR_QUIET
 "Quiet" More...
 
const PROGMEM char * kEconoStr = D_STR_ECONO
 "Econo" More...
 
const PROGMEM char * kSwingStr = D_STR_SWING
 "Swing" More...
 
const PROGMEM char * kSwingHStr = D_STR_SWINGH
 "SwingH" More...
 
const PROGMEM char * kSwingVStr = D_STR_SWINGV
 "SwingV" More...
 
const PROGMEM char * kBeepStr = D_STR_BEEP
 "Beep" More...
 
const PROGMEM char * kZoneFollowStr = D_STR_ZONEFOLLOW
 "Zone Follow" More...
 
const PROGMEM char * kFixedStr = D_STR_FIXED
 "Fixed" More...
 
const PROGMEM char * kMouldStr = D_STR_MOULD
 "Mould" More...
 
const PROGMEM char * kCleanStr = D_STR_CLEAN
 "Clean" More...
 
const PROGMEM char * kPurifyStr = D_STR_PURIFY
 "Purify" More...
 
const PROGMEM char * kTimerStr = D_STR_TIMER
 "Timer" More...
 
const PROGMEM char * kOnTimerStr = D_STR_ONTIMER
 "OnTimer" More...
 
const PROGMEM char * kOffTimerStr = D_STR_OFFTIMER
 "OffTimer" More...
 
const PROGMEM char * kClockStr = D_STR_CLOCK
 "Clock" More...
 
const PROGMEM char * kCommandStr = D_STR_COMMAND
 "Command" More...
 
const PROGMEM char * kXFanStr = D_STR_XFAN
 "XFan" More...
 
const PROGMEM char * kHealthStr = D_STR_HEALTH
 "Health" More...
 
const PROGMEM char * kModelStr = D_STR_MODEL
 "Model" More...
 
const PROGMEM char * kTempStr = D_STR_TEMP
 "Temp" More...
 
const PROGMEM char * kIFeelStr = D_STR_IFEEL
 "IFeel" More...
 
const PROGMEM char * kHumidStr = D_STR_HUMID
 "Humid" More...
 
const PROGMEM char * kSaveStr = D_STR_SAVE
 "Save" More...
 
const PROGMEM char * kEyeStr = D_STR_EYE
 "Eye" More...
 
const PROGMEM char * kFollowStr = D_STR_FOLLOW
 "Follow" More...
 
const PROGMEM char * kIonStr = D_STR_ION
 "Ion" More...
 
const PROGMEM char * kFreshStr = D_STR_FRESH
 "Fresh" More...
 
const PROGMEM char * kHoldStr = D_STR_HOLD
 "Hold" More...
 
const PROGMEM char * kButtonStr = D_STR_BUTTON
 "Button" More...
 
const PROGMEM char * k8CHeatStr = D_STR_8C_HEAT
 "8CHeat" More...
 
const PROGMEM char * kNightStr = D_STR_NIGHT
 "Night" More...
 
const PROGMEM char * kSilentStr = D_STR_SILENT
 "Silent" More...
 
const PROGMEM char * kFilterStr = D_STR_FILTER
 "Filter" More...
 
const PROGMEM char * k3DStr = D_STR_3D
 "3D" More...
 
const PROGMEM char * kCelsiusStr = D_STR_CELSIUS
 "Celsius" More...
 
const PROGMEM char * kTempUpStr = D_STR_TEMPUP
 "Temp Up" More...
 
const PROGMEM char * kTempDownStr = D_STR_TEMPDOWN
 "Temp Down" More...
 
const PROGMEM char * kStartStr = D_STR_START
 "Start" More...
 
const PROGMEM char * kStopStr = D_STR_STOP
 "Stop" More...
 
const PROGMEM char * kMoveStr = D_STR_MOVE
 "Move" More...
 
const PROGMEM char * kSetStr = D_STR_SET
 "Set" More...
 
const PROGMEM char * kCancelStr = D_STR_CANCEL
 "Cancel" More...
 
const PROGMEM char * kUpStr = D_STR_UP
 "Up" More...
 
const PROGMEM char * kDownStr = D_STR_DOWN
 "Down" More...
 
const PROGMEM char * kChangeStr = D_STR_CHANGE
 "Change" More...
 
const PROGMEM char * kComfortStr = D_STR_COMFORT
 "Comfort" More...
 
const PROGMEM char * kSensorStr = D_STR_SENSOR
 "Sensor" More...
 
const PROGMEM char * kWeeklyTimerStr = D_STR_WEEKLYTIMER
 "WeeklyTimer" More...
 
const PROGMEM char * kWifiStr = D_STR_WIFI
 "Wifi" More...
 
const PROGMEM char * kLastStr = D_STR_LAST
 "Last" More...
 
const PROGMEM char * kFastStr = D_STR_FAST
 "Fast" More...
 
const PROGMEM char * kSlowStr = D_STR_SLOW
 "Slow" More...
 
const PROGMEM char * kAirFlowStr = D_STR_AIRFLOW
 "Air Flow" More...
 
const PROGMEM char * kStepStr = D_STR_STEP
 "Step" More...
 
const PROGMEM char * kNAStr = D_STR_NA
 "N/A" More...
 
const PROGMEM char * kInsideStr = D_STR_INSIDE
 "Inside" More...
 
const PROGMEM char * kOutsideStr = D_STR_OUTSIDE
 "Outside" More...
 
const PROGMEM char * kLoudStr = D_STR_LOUD
 "Loud" More...
 
const PROGMEM char * kLowerStr = D_STR_LOWER
 "Lower" More...
 
const PROGMEM char * kUpperStr = D_STR_UPPER
 "Upper" More...
 
const PROGMEM char * kBreezeStr = D_STR_BREEZE
 "Breeze" More...
 
const PROGMEM char * kCirculateStr = D_STR_CIRCULATE
 "Circulate" More...
 
const PROGMEM char * kCeilingStr = D_STR_CEILING
 "Ceiling" More...
 
const PROGMEM char * kWallStr = D_STR_WALL
 "Wall" More...
 
const PROGMEM char * kRoomStr = D_STR_ROOM
 "Room" More...
 
const PROGMEM char * k6thSenseStr = D_STR_6THSENSE
 "6th Sense" More...
 
const PROGMEM char * kAutoStr = D_STR_AUTO
 "Auto" More...
 
const PROGMEM char * kAutomaticStr = D_STR_AUTOMATIC
 "Automatic" More...
 
const PROGMEM char * kManualStr = D_STR_MANUAL
 "Manual" More...
 
const PROGMEM char * kCoolStr = D_STR_COOL
 "Cool" More...
 
const PROGMEM char * kHeatStr = D_STR_HEAT
 "Heat" More...
 
const PROGMEM char * kFanStr = D_STR_FAN
 "Fan" More...
 
const PROGMEM char * kDryStr = D_STR_DRY
 "Dry" More...
 
const PROGMEM char * kFanOnlyStr = D_STR_FANONLY
 "fan_only" More...
 
const PROGMEM char * kMaxStr = D_STR_MAX
 "Max" More...
 
const PROGMEM char * kMaximumStr = D_STR_MAXIMUM
 "Maximum" More...
 
const PROGMEM char * kMinStr = D_STR_MIN
 "Min" More...
 
const PROGMEM char * kMinimumStr = D_STR_MINIMUM
 "Minimum" More...
 
const PROGMEM char * kMedStr = D_STR_MED
 "Med" More...
 
const PROGMEM char * kMediumStr = D_STR_MEDIUM
 "Medium" More...
 
const PROGMEM char * kHighestStr = D_STR_HIGHEST
 "Highest" More...
 
const PROGMEM char * kHighStr = D_STR_HIGH
 "High" More...
 
const PROGMEM char * kHiStr = D_STR_HI
 "Hi" More...
 
const PROGMEM char * kMidStr = D_STR_MID
 "Mid" More...
 
const PROGMEM char * kMiddleStr = D_STR_MIDDLE
 "Middle" More...
 
const PROGMEM char * kLowStr = D_STR_LOW
 "Low" More...
 
const PROGMEM char * kLoStr = D_STR_LO
 "Lo" More...
 
const PROGMEM char * kLowestStr = D_STR_LOWEST
 "Lowest" More...
 
const PROGMEM char * kMaxRightStr = D_STR_MAXRIGHT
 "Max Right" More...
 
const PROGMEM char * kRightMaxStr = D_STR_RIGHTMAX_NOSPACE
 "RightMax" More...
 
const PROGMEM char * kRightStr = D_STR_RIGHT
 "Right" More...
 
const PROGMEM char * kLeftStr = D_STR_LEFT
 "Left" More...
 
const PROGMEM char * kMaxLeftStr = D_STR_MAXLEFT
 "Max Left" More...
 
const PROGMEM char * kLeftMaxStr = D_STR_LEFTMAX_NOSPACE
 "LeftMax" More...
 
const PROGMEM char * kWideStr = D_STR_WIDE
 "Wide" More...
 
const PROGMEM char * kCentreStr = D_STR_CENTRE
 "Centre" More...
 
const PROGMEM char * kTopStr = D_STR_TOP
 "Top" More...
 
const PROGMEM char * kBottomStr = D_STR_BOTTOM
 "Bottom" More...
 
const PROGMEM char * kEyeAutoStr = D_STR_EYEAUTO
 "Eye Auto" More...
 
const PROGMEM char * kLightToggleStr = D_STR_LIGHTTOGGLE
 "Light Toggle" More...
 
const PROGMEM char * kOutsideQuietStr = D_STR_OUTSIDEQUIET
 "Outside Quiet" More...
 
const PROGMEM char * kPowerToggleStr = D_STR_POWERTOGGLE
 "Power Toggle" More...
 
const PROGMEM char * kPowerButtonStr = D_STR_POWERBUTTON
 "Power Button" More...
 
const PROGMEM char * kPreviousPowerStr = D_STR_PREVIOUSPOWER
 "Previous Power" More...
 
const PROGMEM char * kDisplayTempStr = D_STR_DISPLAYTEMP
 "Display Temp" More...
 
const PROGMEM char * kSensorTempStr = D_STR_SENSORTEMP
 "Sensor Temp" More...
 
const PROGMEM char * kSleepTimerStr = D_STR_SLEEP_TIMER
 "Sleep Timer" More...
 
const PROGMEM char * kSwingVModeStr = D_STR_SWINGVMODE
 "Swing(V) Mode" More...
 
const PROGMEM char * kSwingVToggleStr = D_STR_SWINGVTOGGLE
 "Swing(V) Toggle" More...
 
char kTimeSep = D_CHR_TIME_SEP
 ':' More...
 
const PROGMEM char * kSpaceLBraceStr = D_STR_SPACELBRACE
 " (" More...
 
const PROGMEM char * kCommaSpaceStr = D_STR_COMMASPACE
 ", " More...
 
const PROGMEM char * kColonSpaceStr = D_STR_COLONSPACE
 ": " More...
 
const PROGMEM char * kDayStr = D_STR_DAY
 "Day" More...
 
const PROGMEM char * kDaysStr = D_STR_DAYS
 "Days" More...
 
const PROGMEM char * kHourStr = D_STR_HOUR
 "Hour" More...
 
const PROGMEM char * kHoursStr = D_STR_HOURS
 "Hours" More...
 
const PROGMEM char * kMinuteStr = D_STR_MINUTE
 "Minute" More...
 
const PROGMEM char * kMinutesStr = D_STR_MINUTES
 "Minutes" More...
 
const PROGMEM char * kSecondStr = D_STR_SECOND
 "Second" More...
 
const PROGMEM char * kSecondsStr = D_STR_SECONDS
 "Seconds" More...
 
const PROGMEM char * kNowStr = D_STR_NOW
 "Now" More...
 
const PROGMEM char * kThreeLetterDayOfWeekStr = D_STR_THREELETTERDAYS
 "SunMonTueWedThuFriSat" More...
 
const PROGMEM char * kYesStr = D_STR_YES
 "Yes" More...
 
const PROGMEM char * kNoStr = D_STR_NO
 "No" More...
 
const PROGMEM char * kTrueStr = D_STR_TRUE
 "True" More...
 
const PROGMEM char * kFalseStr = D_STR_FALSE
 "False" More...
 
const PROGMEM char * kRepeatStr = D_STR_REPEAT
 "Repeat" More...
 
const PROGMEM char * kCodeStr = D_STR_CODE
 "Code" More...
 
const PROGMEM char * kBitsStr = D_STR_BITS
 "Bits" More...
 
const PROGMEM char * kAllProtocolNamesStr
 New protocol strings should be added just above this line. More...
 
+

Detailed Description

+
Warning
If you add or remove an entry in this file, you should run: '../tools/generate_irtext_h.sh' to rebuild the IRtext.h file.
+

Variable Documentation

+ +

◆ k3DStr

+ +
+
+ + + + +
const PROGMEM char* k3DStr = D_STR_3D
+
+ +

"3D"

+ +
+
+ +

◆ k6thSenseStr

+ +
+
+ + + + +
const PROGMEM char* k6thSenseStr = D_STR_6THSENSE
+
+ +

"6th Sense"

+ +
+
+ +

◆ k8CHeatStr

+ +
+
+ + + + +
const PROGMEM char* k8CHeatStr = D_STR_8C_HEAT
+
+ +

"8CHeat"

+ +
+
+ +

◆ kAirFlowStr

+ +
+
+ + + + +
const PROGMEM char* kAirFlowStr = D_STR_AIRFLOW
+
+ +

"Air Flow"

+ +
+
+ +

◆ kAllProtocolNamesStr

+ +
+
+ + + + +
const PROGMEM char* kAllProtocolNamesStr
+
+ +

New protocol strings should be added just above this line.

+

This string requires double null termination.

+ +
+
+ +

◆ kAutomaticStr

+ +
+
+ + + + +
const PROGMEM char* kAutomaticStr = D_STR_AUTOMATIC
+
+ +

"Automatic"

+ +
+
+ +

◆ kAutoStr

+ +
+
+ + + + +
const PROGMEM char* kAutoStr = D_STR_AUTO
+
+ +

"Auto"

+ +
+
+ +

◆ kBeepStr

+ +
+
+ + + + +
const PROGMEM char* kBeepStr = D_STR_BEEP
+
+ +

"Beep"

+ +
+
+ +

◆ kBitsStr

+ +
+
+ + + + +
const PROGMEM char* kBitsStr = D_STR_BITS
+
+ +

"Bits"

+ +
+
+ +

◆ kBottomStr

+ +
+
+ + + + +
const PROGMEM char* kBottomStr = D_STR_BOTTOM
+
+ +

"Bottom"

+ +
+
+ +

◆ kBreezeStr

+ +
+
+ + + + +
const PROGMEM char* kBreezeStr = D_STR_BREEZE
+
+ +

"Breeze"

+ +
+
+ +

◆ kButtonStr

+ +
+
+ + + + +
const PROGMEM char* kButtonStr = D_STR_BUTTON
+
+ +

"Button"

+ +
+
+ +

◆ kCancelStr

+ +
+
+ + + + +
const PROGMEM char* kCancelStr = D_STR_CANCEL
+
+ +

"Cancel"

+ +
+
+ +

◆ kCeilingStr

+ +
+
+ + + + +
const PROGMEM char* kCeilingStr = D_STR_CEILING
+
+ +

"Ceiling"

+ +
+
+ +

◆ kCelsiusStr

+ +
+
+ + + + +
const PROGMEM char* kCelsiusStr = D_STR_CELSIUS
+
+ +

"Celsius"

+ +
+
+ +

◆ kCentreStr

+ +
+
+ + + + +
const PROGMEM char* kCentreStr = D_STR_CENTRE
+
+ +

"Centre"

+ +
+
+ +

◆ kChangeStr

+ +
+
+ + + + +
const PROGMEM char* kChangeStr = D_STR_CHANGE
+
+ +

"Change"

+ +
+
+ +

◆ kCirculateStr

+ +
+
+ + + + +
const PROGMEM char* kCirculateStr = D_STR_CIRCULATE
+
+ +

"Circulate"

+ +
+
+ +

◆ kCleanStr

+ +
+
+ + + + +
const PROGMEM char* kCleanStr = D_STR_CLEAN
+
+ +

"Clean"

+ +
+
+ +

◆ kClockStr

+ +
+
+ + + + +
const PROGMEM char* kClockStr = D_STR_CLOCK
+
+ +

"Clock"

+ +
+
+ +

◆ kCodeStr

+ +
+
+ + + + +
const PROGMEM char* kCodeStr = D_STR_CODE
+
+ +

"Code"

+ +
+
+ +

◆ kColonSpaceStr

+ +
+
+ + + + +
const PROGMEM char* kColonSpaceStr = D_STR_COLONSPACE
+
+ +

": "

+ +
+
+ +

◆ kComfortStr

+ +
+
+ + + + +
const PROGMEM char* kComfortStr = D_STR_COMFORT
+
+ +

"Comfort"

+ +
+
+ +

◆ kCommandStr

+ +
+
+ + + + +
const PROGMEM char* kCommandStr = D_STR_COMMAND
+
+ +

"Command"

+ +
+
+ +

◆ kCommaSpaceStr

+ +
+
+ + + + +
const PROGMEM char* kCommaSpaceStr = D_STR_COMMASPACE
+
+ +

", "

+ +
+
+ +

◆ kCoolStr

+ +
+
+ + + + +
const PROGMEM char* kCoolStr = D_STR_COOL
+
+ +

"Cool"

+ +
+
+ +

◆ kDaysStr

+ +
+
+ + + + +
const PROGMEM char* kDaysStr = D_STR_DAYS
+
+ +

"Days"

+ +
+
+ +

◆ kDayStr

+ +
+
+ + + + +
const PROGMEM char* kDayStr = D_STR_DAY
+
+ +

"Day"

+ +
+
+ +

◆ kDisplayTempStr

+ +
+
+ + + + +
const PROGMEM char* kDisplayTempStr = D_STR_DISPLAYTEMP
+
+ +

"Display Temp"

+ +
+
+ +

◆ kDownStr

+ +
+
+ + + + +
const PROGMEM char* kDownStr = D_STR_DOWN
+
+ +

"Down"

+ +
+
+ +

◆ kDryStr

+ +
+
+ + + + +
const PROGMEM char* kDryStr = D_STR_DRY
+
+ +

"Dry"

+ +
+
+ +

◆ kEconoStr

+ +
+
+ + + + +
const PROGMEM char* kEconoStr = D_STR_ECONO
+
+ +

"Econo"

+ +
+
+ +

◆ kEyeAutoStr

+ +
+
+ + + + +
const PROGMEM char* kEyeAutoStr = D_STR_EYEAUTO
+
+ +

"Eye Auto"

+ +
+
+ +

◆ kEyeStr

+ +
+
+ + + + +
const PROGMEM char* kEyeStr = D_STR_EYE
+
+ +

"Eye"

+ +
+
+ +

◆ kFalseStr

+ +
+
+ + + + +
const PROGMEM char* kFalseStr = D_STR_FALSE
+
+ +

"False"

+ +
+
+ +

◆ kFanOnlyStr

+ +
+
+ + + + +
const PROGMEM char* kFanOnlyStr = D_STR_FANONLY
+
+ +

"fan_only"

+ +
+
+ +

◆ kFanStr

+ +
+
+ + + + +
const PROGMEM char* kFanStr = D_STR_FAN
+
+ +

"Fan"

+ +
+
+ +

◆ kFastStr

+ +
+
+ + + + +
const PROGMEM char* kFastStr = D_STR_FAST
+
+ +

"Fast"

+ +
+
+ +

◆ kFilterStr

+ +
+
+ + + + +
const PROGMEM char* kFilterStr = D_STR_FILTER
+
+ +

"Filter"

+ +
+
+ +

◆ kFixedStr

+ +
+
+ + + + +
const PROGMEM char* kFixedStr = D_STR_FIXED
+
+ +

"Fixed"

+ +
+
+ +

◆ kFollowStr

+ +
+
+ + + + +
const PROGMEM char* kFollowStr = D_STR_FOLLOW
+
+ +

"Follow"

+ +
+
+ +

◆ kFreshStr

+ +
+
+ + + + +
const PROGMEM char* kFreshStr = D_STR_FRESH
+
+ +

"Fresh"

+ +
+
+ +

◆ kHealthStr

+ +
+
+ + + + +
const PROGMEM char* kHealthStr = D_STR_HEALTH
+
+ +

"Health"

+ +
+
+ +

◆ kHeatStr

+ +
+
+ + + + +
const PROGMEM char* kHeatStr = D_STR_HEAT
+
+ +

"Heat"

+ +
+
+ +

◆ kHighestStr

+ +
+
+ + + + +
const PROGMEM char* kHighestStr = D_STR_HIGHEST
+
+ +

"Highest"

+ +
+
+ +

◆ kHighStr

+ +
+
+ + + + +
const PROGMEM char* kHighStr = D_STR_HIGH
+
+ +

"High"

+ +
+
+ +

◆ kHiStr

+ +
+
+ + + + +
const PROGMEM char* kHiStr = D_STR_HI
+
+ +

"Hi"

+ +
+
+ +

◆ kHoldStr

+ +
+
+ + + + +
const PROGMEM char* kHoldStr = D_STR_HOLD
+
+ +

"Hold"

+ +
+
+ +

◆ kHoursStr

+ +
+
+ + + + +
const PROGMEM char* kHoursStr = D_STR_HOURS
+
+ +

"Hours"

+ +
+
+ +

◆ kHourStr

+ +
+
+ + + + +
const PROGMEM char* kHourStr = D_STR_HOUR
+
+ +

"Hour"

+ +
+
+ +

◆ kHumidStr

+ +
+
+ + + + +
const PROGMEM char* kHumidStr = D_STR_HUMID
+
+ +

"Humid"

+ +
+
+ +

◆ kIFeelStr

+ +
+
+ + + + +
const PROGMEM char* kIFeelStr = D_STR_IFEEL
+
+ +

"IFeel"

+ +
+
+ +

◆ kInsideStr

+ +
+
+ + + + +
const PROGMEM char* kInsideStr = D_STR_INSIDE
+
+ +

"Inside"

+ +
+
+ +

◆ kIonStr

+ +
+
+ + + + +
const PROGMEM char* kIonStr = D_STR_ION
+
+ +

"Ion"

+ +
+
+ +

◆ kLastStr

+ +
+
+ + + + +
const PROGMEM char* kLastStr = D_STR_LAST
+
+ +

"Last"

+ +
+
+ +

◆ kLeftMaxStr

+ +
+
+ + + + +
const PROGMEM char* kLeftMaxStr = D_STR_LEFTMAX_NOSPACE
+
+ +

"LeftMax"

+ +
+
+ +

◆ kLeftStr

+ +
+
+ + + + +
const PROGMEM char* kLeftStr = D_STR_LEFT
+
+ +

"Left"

+ +
+
+ +

◆ kLightStr

+ +
+
+ + + + +
const PROGMEM char* kLightStr = D_STR_LIGHT
+
+ +

"Light"

+ +
+
+ +

◆ kLightToggleStr

+ +
+
+ + + + +
const PROGMEM char* kLightToggleStr = D_STR_LIGHTTOGGLE
+
+ +

"Light Toggle"

+ +
+
+ +

◆ kLoStr

+ +
+
+ + + + +
const PROGMEM char* kLoStr = D_STR_LO
+
+ +

"Lo"

+ +
+
+ +

◆ kLoudStr

+ +
+
+ + + + +
const PROGMEM char* kLoudStr = D_STR_LOUD
+
+ +

"Loud"

+ +
+
+ +

◆ kLowerStr

+ +
+
+ + + + +
const PROGMEM char* kLowerStr = D_STR_LOWER
+
+ +

"Lower"

+ +
+
+ +

◆ kLowestStr

+ +
+
+ + + + +
const PROGMEM char* kLowestStr = D_STR_LOWEST
+
+ +

"Lowest"

+ +
+
+ +

◆ kLowStr

+ +
+
+ + + + +
const PROGMEM char* kLowStr = D_STR_LOW
+
+ +

"Low"

+ +
+
+ +

◆ kManualStr

+ +
+
+ + + + +
const PROGMEM char* kManualStr = D_STR_MANUAL
+
+ +

"Manual"

+ +
+
+ +

◆ kMaximumStr

+ +
+
+ + + + +
const PROGMEM char* kMaximumStr = D_STR_MAXIMUM
+
+ +

"Maximum"

+ +
+
+ +

◆ kMaxLeftStr

+ +
+
+ + + + +
const PROGMEM char* kMaxLeftStr = D_STR_MAXLEFT
+
+ +

"Max Left"

+ +
+
+ +

◆ kMaxRightStr

+ +
+
+ + + + +
const PROGMEM char* kMaxRightStr = D_STR_MAXRIGHT
+
+ +

"Max Right"

+ +
+
+ +

◆ kMaxStr

+ +
+
+ + + + +
const PROGMEM char* kMaxStr = D_STR_MAX
+
+ +

"Max"

+ +
+
+ +

◆ kMediumStr

+ +
+
+ + + + +
const PROGMEM char* kMediumStr = D_STR_MEDIUM
+
+ +

"Medium"

+ +
+
+ +

◆ kMedStr

+ +
+
+ + + + +
const PROGMEM char* kMedStr = D_STR_MED
+
+ +

"Med"

+ +
+
+ +

◆ kMiddleStr

+ +
+
+ + + + +
const PROGMEM char* kMiddleStr = D_STR_MIDDLE
+
+ +

"Middle"

+ +
+
+ +

◆ kMidStr

+ +
+
+ + + + +
const PROGMEM char* kMidStr = D_STR_MID
+
+ +

"Mid"

+ +
+
+ +

◆ kMinimumStr

+ +
+
+ + + + +
const PROGMEM char* kMinimumStr = D_STR_MINIMUM
+
+ +

"Minimum"

+ +
+
+ +

◆ kMinStr

+ +
+
+ + + + +
const PROGMEM char* kMinStr = D_STR_MIN
+
+ +

"Min"

+ +
+
+ +

◆ kMinutesStr

+ +
+
+ + + + +
const PROGMEM char* kMinutesStr = D_STR_MINUTES
+
+ +

"Minutes"

+ +
+
+ +

◆ kMinuteStr

+ +
+
+ + + + +
const PROGMEM char* kMinuteStr = D_STR_MINUTE
+
+ +

"Minute"

+ +
+
+ +

◆ kModelStr

+ +
+
+ + + + +
const PROGMEM char* kModelStr = D_STR_MODEL
+
+ +

"Model"

+ +
+
+ +

◆ kModeStr

+ +
+
+ + + + +
const PROGMEM char* kModeStr = D_STR_MODE
+
+ +

"Mode"

+ +
+
+ +

◆ kMouldStr

+ +
+
+ + + + +
const PROGMEM char* kMouldStr = D_STR_MOULD
+
+ +

"Mould"

+ +
+
+ +

◆ kMoveStr

+ +
+
+ + + + +
const PROGMEM char* kMoveStr = D_STR_MOVE
+
+ +

"Move"

+ +
+
+ +

◆ kNAStr

+ +
+
+ + + + +
const PROGMEM char* kNAStr = D_STR_NA
+
+ +

"N/A"

+ +
+
+ +

◆ kNightStr

+ +
+
+ + + + +
const PROGMEM char* kNightStr = D_STR_NIGHT
+
+ +

"Night"

+ +
+
+ +

◆ kNoStr

+ +
+
+ + + + +
const PROGMEM char* kNoStr = D_STR_NO
+
+ +

"No"

+ +
+
+ +

◆ kNowStr

+ +
+
+ + + + +
const PROGMEM char* kNowStr = D_STR_NOW
+
+ +

"Now"

+ +
+
+ +

◆ kOffStr

+ +
+
+ + + + +
const PROGMEM char* kOffStr = D_STR_OFF
+
+ +

"Off"

+ +
+
+ +

◆ kOffTimerStr

+ +
+
+ + + + +
const PROGMEM char* kOffTimerStr = D_STR_OFFTIMER
+
+ +

"OffTimer"

+ +
+
+ +

◆ kOnStr

+ +
+
+ + + + +
const PROGMEM char* kOnStr = D_STR_ON
+
+ +

"On"

+ +
+
+ +

◆ kOnTimerStr

+ +
+
+ + + + +
const PROGMEM char* kOnTimerStr = D_STR_ONTIMER
+
+ +

"OnTimer"

+ +
+
+ +

◆ kOutsideQuietStr

+ +
+
+ + + + +
const PROGMEM char* kOutsideQuietStr = D_STR_OUTSIDEQUIET
+
+ +

"Outside Quiet"

+ +
+
+ +

◆ kOutsideStr

+ +
+
+ + + + +
const PROGMEM char* kOutsideStr = D_STR_OUTSIDE
+
+ +

"Outside"

+ +
+
+ +

◆ kPowerButtonStr

+ +
+
+ + + + +
const PROGMEM char* kPowerButtonStr = D_STR_POWERBUTTON
+
+ +

"Power Button"

+ +
+
+ +

◆ kPowerfulStr

+ +
+
+ + + + +
const PROGMEM char* kPowerfulStr = D_STR_POWERFUL
+
+ +

"Powerful"

+ +
+
+ +

◆ kPowerStr

+ +
+
+ + + + +
const PROGMEM char* kPowerStr = D_STR_POWER
+
+ +

"Power"

+ +
+
+ +

◆ kPowerToggleStr

+ +
+
+ + + + +
const PROGMEM char* kPowerToggleStr = D_STR_POWERTOGGLE
+
+ +

"Power Toggle"

+ +
+
+ +

◆ kPreviousPowerStr

+ +
+
+ + + + +
const PROGMEM char* kPreviousPowerStr = D_STR_PREVIOUSPOWER
+
+ +

"Previous Power"

+ +
+
+ +

◆ kProtocolStr

+ +
+
+ + + + +
const PROGMEM char* kProtocolStr = D_STR_PROTOCOL
+
+ +

"Protocol"

+ +
+
+ +

◆ kPurifyStr

+ +
+
+ + + + +
const PROGMEM char* kPurifyStr = D_STR_PURIFY
+
+ +

"Purify"

+ +
+
+ +

◆ kQuietStr

+ +
+
+ + + + +
const PROGMEM char* kQuietStr = D_STR_QUIET
+
+ +

"Quiet"

+ +
+
+ +

◆ kRepeatStr

+ +
+
+ + + + +
const PROGMEM char* kRepeatStr = D_STR_REPEAT
+
+ +

"Repeat"

+ +
+
+ +

◆ kRightMaxStr

+ +
+
+ + + + +
const PROGMEM char* kRightMaxStr = D_STR_RIGHTMAX_NOSPACE
+
+ +

"RightMax"

+ +
+
+ +

◆ kRightStr

+ +
+
+ + + + +
const PROGMEM char* kRightStr = D_STR_RIGHT
+
+ +

"Right"

+ +
+
+ +

◆ kRoomStr

+ +
+
+ + + + +
const PROGMEM char* kRoomStr = D_STR_ROOM
+
+ +

"Room"

+ +
+
+ +

◆ kSaveStr

+ +
+
+ + + + +
const PROGMEM char* kSaveStr = D_STR_SAVE
+
+ +

"Save"

+ +
+
+ +

◆ kSecondsStr

+ +
+
+ + + + +
const PROGMEM char* kSecondsStr = D_STR_SECONDS
+
+ +

"Seconds"

+ +
+
+ +

◆ kSecondStr

+ +
+
+ + + + +
const PROGMEM char* kSecondStr = D_STR_SECOND
+
+ +

"Second"

+ +
+
+ +

◆ kSensorStr

+ +
+
+ + + + +
const PROGMEM char* kSensorStr = D_STR_SENSOR
+
+ +

"Sensor"

+ +
+
+ +

◆ kSensorTempStr

+ +
+
+ + + + +
const PROGMEM char* kSensorTempStr = D_STR_SENSORTEMP
+
+ +

"Sensor Temp"

+ +
+
+ +

◆ kSetStr

+ +
+
+ + + + +
const PROGMEM char* kSetStr = D_STR_SET
+
+ +

"Set"

+ +
+
+ +

◆ kSilentStr

+ +
+
+ + + + +
const PROGMEM char* kSilentStr = D_STR_SILENT
+
+ +

"Silent"

+ +
+
+ +

◆ kSleepStr

+ +
+
+ + + + +
const PROGMEM char* kSleepStr = D_STR_SLEEP
+
+ +

"Sleep"

+ +
+
+ +

◆ kSleepTimerStr

+ +
+
+ + + + +
const PROGMEM char* kSleepTimerStr = D_STR_SLEEP_TIMER
+
+ +

"Sleep Timer"

+ +
+
+ +

◆ kSlowStr

+ +
+
+ + + + +
const PROGMEM char* kSlowStr = D_STR_SLOW
+
+ +

"Slow"

+ +
+
+ +

◆ kSpaceLBraceStr

+ +
+
+ + + + +
const PROGMEM char* kSpaceLBraceStr = D_STR_SPACELBRACE
+
+ +

" ("

+ +
+
+ +

◆ kStartStr

+ +
+
+ + + + +
const PROGMEM char* kStartStr = D_STR_START
+
+ +

"Start"

+ +
+
+ +

◆ kStepStr

+ +
+
+ + + + +
const PROGMEM char* kStepStr = D_STR_STEP
+
+ +

"Step"

+ +
+
+ +

◆ kStopStr

+ +
+
+ + + + +
const PROGMEM char* kStopStr = D_STR_STOP
+
+ +

"Stop"

+ +
+
+ +

◆ kSuperStr

+ +
+
+ + + + +
const PROGMEM char* kSuperStr = D_STR_SUPER
+
+ +

"Super"

+ +
+
+ +

◆ kSwingHStr

+ +
+
+ + + + +
const PROGMEM char* kSwingHStr = D_STR_SWINGH
+
+ +

"SwingH"

+ +
+
+ +

◆ kSwingStr

+ +
+
+ + + + +
const PROGMEM char* kSwingStr = D_STR_SWING
+
+ +

"Swing"

+ +
+
+ +

◆ kSwingVModeStr

+ +
+
+ + + + +
const PROGMEM char* kSwingVModeStr = D_STR_SWINGVMODE
+
+ +

"Swing(V) Mode"

+ +
+
+ +

◆ kSwingVStr

+ +
+
+ + + + +
const PROGMEM char* kSwingVStr = D_STR_SWINGV
+
+ +

"SwingV"

+ +
+
+ +

◆ kSwingVToggleStr

+ +
+
+ + + + +
const PROGMEM char* kSwingVToggleStr = D_STR_SWINGVTOGGLE
+
+ +

"Swing(V) Toggle"

+ +
+
+ +

◆ kTempDownStr

+ +
+
+ + + + +
const PROGMEM char* kTempDownStr = D_STR_TEMPDOWN
+
+ +

"Temp Down"

+ +
+
+ +

◆ kTempStr

+ +
+
+ + + + +
const PROGMEM char* kTempStr = D_STR_TEMP
+
+ +

"Temp"

+ +
+
+ +

◆ kTempUpStr

+ +
+
+ + + + +
const PROGMEM char* kTempUpStr = D_STR_TEMPUP
+
+ +

"Temp Up"

+ +
+
+ +

◆ kThreeLetterDayOfWeekStr

+ +
+
+ + + + +
const PROGMEM char* kThreeLetterDayOfWeekStr = D_STR_THREELETTERDAYS
+
+ +

"SunMonTueWedThuFriSat"

+ +
+
+ +

◆ kTimerStr

+ +
+
+ + + + +
const PROGMEM char* kTimerStr = D_STR_TIMER
+
+ +

"Timer"

+ +
+
+ +

◆ kTimeSep

+ +
+
+ + + + +
char kTimeSep = D_CHR_TIME_SEP
+
+ +

':'

+ +
+
+ +

◆ kToggleStr

+ +
+
+ + + + +
const PROGMEM char* kToggleStr = D_STR_TOGGLE
+
+ +

"Toggle"

+ +
+
+ +

◆ kTopStr

+ +
+
+ + + + +
const PROGMEM char* kTopStr = D_STR_TOP
+
+ +

"Top"

+ +
+
+ +

◆ kTrueStr

+ +
+
+ + + + +
const PROGMEM char* kTrueStr = D_STR_TRUE
+
+ +

"True"

+ +
+
+ +

◆ kTurboStr

+ +
+
+ + + + +
const PROGMEM char* kTurboStr = D_STR_TURBO
+
+ +

"Turbo"

+ +
+
+ +

◆ kUnknownStr

+ +
+
+ + + + +
const PROGMEM char* kUnknownStr = D_STR_UNKNOWN
+
+ +

"Unknown"

+ +
+
+ +

◆ kUpperStr

+ +
+
+ + + + +
const PROGMEM char* kUpperStr = D_STR_UPPER
+
+ +

"Upper"

+ +
+
+ +

◆ kUpStr

+ +
+
+ + + + +
const PROGMEM char* kUpStr = D_STR_UP
+
+ +

"Up"

+ +
+
+ +

◆ kWallStr

+ +
+
+ + + + +
const PROGMEM char* kWallStr = D_STR_WALL
+
+ +

"Wall"

+ +
+
+ +

◆ kWeeklyTimerStr

+ +
+
+ + + + +
const PROGMEM char* kWeeklyTimerStr = D_STR_WEEKLYTIMER
+
+ +

"WeeklyTimer"

+ +
+
+ +

◆ kWideStr

+ +
+
+ + + + +
const PROGMEM char* kWideStr = D_STR_WIDE
+
+ +

"Wide"

+ +
+
+ +

◆ kWifiStr

+ +
+
+ + + + +
const PROGMEM char* kWifiStr = D_STR_WIFI
+
+ +

"Wifi"

+ +
+
+ +

◆ kXFanStr

+ +
+
+ + + + +
const PROGMEM char* kXFanStr = D_STR_XFAN
+
+ +

"XFan"

+ +
+
+ +

◆ kYesStr

+ +
+
+ + + + +
const PROGMEM char* kYesStr = D_STR_YES
+
+ +

"Yes"

+ +
+
+ +

◆ kZoneFollowStr

+ +
+
+ + + + +
const PROGMEM char* kZoneFollowStr = D_STR_ZONEFOLLOW
+
+ +

"Zone Follow"

+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtext_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtext_8h.html new file mode 100644 index 000000000..e3c285532 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtext_8h.html @@ -0,0 +1,2807 @@ + + + + + + + +IRremoteESP8266: src/IRtext.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
IRtext.h File Reference
+
+
+ +

Go to the source code of this file.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

char kTimeSep
 ':' More...
 
const char * k3DStr
 "3D" More...
 
const char * k6thSenseStr
 "6th Sense" More...
 
const char * k8CHeatStr
 "8CHeat" More...
 
const char * kAirFlowStr
 "Air Flow" More...
 
const char * kAllProtocolNamesStr
 New protocol strings should be added just above this line. More...
 
const char * kAutomaticStr
 "Automatic" More...
 
const char * kAutoStr
 "Auto" More...
 
const char * kBeepStr
 "Beep" More...
 
const char * kBitsStr
 "Bits" More...
 
const char * kBottomStr
 "Bottom" More...
 
const char * kBreezeStr
 "Breeze" More...
 
const char * kButtonStr
 "Button" More...
 
const char * kCancelStr
 "Cancel" More...
 
const char * kCeilingStr
 "Ceiling" More...
 
const char * kCelsiusStr
 "Celsius" More...
 
const char * kCentreStr
 "Centre" More...
 
const char * kChangeStr
 "Change" More...
 
const char * kCirculateStr
 "Circulate" More...
 
const char * kCleanStr
 "Clean" More...
 
const char * kClockStr
 "Clock" More...
 
const char * kCodeStr
 "Code" More...
 
const char * kColonSpaceStr
 ": " More...
 
const char * kComfortStr
 "Comfort" More...
 
const char * kCommandStr
 "Command" More...
 
const char * kCommaSpaceStr
 ", " More...
 
const char * kCoolStr
 "Cool" More...
 
const char * kDaysStr
 "Days" More...
 
const char * kDayStr
 "Day" More...
 
const char * kDisplayTempStr
 "Display Temp" More...
 
const char * kDownStr
 "Down" More...
 
const char * kDryStr
 "Dry" More...
 
const char * kEconoStr
 "Econo" More...
 
const char * kEyeAutoStr
 "Eye Auto" More...
 
const char * kEyeStr
 "Eye" More...
 
const char * kFalseStr
 "False" More...
 
const char * kFanOnlyStr
 "fan_only" More...
 
const char * kFanStr
 "Fan" More...
 
const char * kFastStr
 "Fast" More...
 
const char * kFilterStr
 "Filter" More...
 
const char * kFixedStr
 "Fixed" More...
 
const char * kFollowStr
 "Follow" More...
 
const char * kFreshStr
 "Fresh" More...
 
const char * kHealthStr
 "Health" More...
 
const char * kHeatStr
 "Heat" More...
 
const char * kHighestStr
 "Highest" More...
 
const char * kHighStr
 "High" More...
 
const char * kHiStr
 "Hi" More...
 
const char * kHoldStr
 "Hold" More...
 
const char * kHoursStr
 "Hours" More...
 
const char * kHourStr
 "Hour" More...
 
const char * kHumidStr
 "Humid" More...
 
const char * kIFeelStr
 "IFeel" More...
 
const char * kInsideStr
 "Inside" More...
 
const char * kIonStr
 "Ion" More...
 
const char * kLastStr
 "Last" More...
 
const char * kLeftMaxStr
 "LeftMax" More...
 
const char * kLeftStr
 "Left" More...
 
const char * kLightStr
 "Light" More...
 
const char * kLightToggleStr
 "Light Toggle" More...
 
const char * kLoStr
 "Lo" More...
 
const char * kLoudStr
 "Loud" More...
 
const char * kLowerStr
 "Lower" More...
 
const char * kLowestStr
 "Lowest" More...
 
const char * kLowStr
 "Low" More...
 
const char * kManualStr
 "Manual" More...
 
const char * kMaximumStr
 "Maximum" More...
 
const char * kMaxLeftStr
 "Max Left" More...
 
const char * kMaxRightStr
 "Max Right" More...
 
const char * kMaxStr
 "Max" More...
 
const char * kMediumStr
 "Medium" More...
 
const char * kMedStr
 "Med" More...
 
const char * kMiddleStr
 "Middle" More...
 
const char * kMidStr
 "Mid" More...
 
const char * kMinimumStr
 "Minimum" More...
 
const char * kMinStr
 "Min" More...
 
const char * kMinutesStr
 "Minutes" More...
 
const char * kMinuteStr
 "Minute" More...
 
const char * kModelStr
 "Model" More...
 
const char * kModeStr
 "Mode" More...
 
const char * kMouldStr
 "Mould" More...
 
const char * kMoveStr
 "Move" More...
 
const char * kNAStr
 "N/A" More...
 
const char * kNightStr
 "Night" More...
 
const char * kNoStr
 "No" More...
 
const char * kNowStr
 "Now" More...
 
const char * kOffStr
 "Off" More...
 
const char * kOffTimerStr
 "OffTimer" More...
 
const char * kOnStr
 "On" More...
 
const char * kOnTimerStr
 "OnTimer" More...
 
const char * kOutsideQuietStr
 "Outside Quiet" More...
 
const char * kOutsideStr
 "Outside" More...
 
const char * kPowerfulStr
 "Powerful" More...
 
const char * kPowerStr
 "Power" More...
 
const char * kPowerToggleStr
 "Power Toggle" More...
 
const char * kPowerButtonStr
 "Power Button" More...
 
const char * kPreviousPowerStr
 "Previous Power" More...
 
const char * kProtocolStr
 "Protocol" More...
 
const char * kPurifyStr
 "Purify" More...
 
const char * kQuietStr
 "Quiet" More...
 
const char * kRepeatStr
 "Repeat" More...
 
const char * kRightMaxStr
 "RightMax" More...
 
const char * kRightStr
 "Right" More...
 
const char * kRoomStr
 "Room" More...
 
const char * kSaveStr
 "Save" More...
 
const char * kSecondsStr
 "Seconds" More...
 
const char * kSecondStr
 "Second" More...
 
const char * kSensorStr
 "Sensor" More...
 
const char * kSensorTempStr
 "Sensor Temp" More...
 
const char * kSetStr
 "Set" More...
 
const char * kSilentStr
 "Silent" More...
 
const char * kSleepStr
 "Sleep" More...
 
const char * kSleepTimerStr
 "Sleep Timer" More...
 
const char * kSlowStr
 "Slow" More...
 
const char * kSpaceLBraceStr
 " (" More...
 
const char * kStartStr
 "Start" More...
 
const char * kStepStr
 "Step" More...
 
const char * kStopStr
 "Stop" More...
 
const char * kSuperStr
 "Super" More...
 
const char * kSwingHStr
 "SwingH" More...
 
const char * kSwingStr
 "Swing" More...
 
const char * kSwingVModeStr
 "Swing(V) Mode" More...
 
const char * kSwingVStr
 "SwingV" More...
 
const char * kSwingVToggleStr
 "Swing(V) Toggle" More...
 
const char * kTempDownStr
 "Temp Down" More...
 
const char * kTempStr
 "Temp" More...
 
const char * kTempUpStr
 "Temp Up" More...
 
const char * kThreeLetterDayOfWeekStr
 "SunMonTueWedThuFriSat" More...
 
const char * kTimerStr
 "Timer" More...
 
const char * kToggleStr
 "Toggle" More...
 
const char * kTopStr
 "Top" More...
 
const char * kTrueStr
 "True" More...
 
const char * kTurboStr
 "Turbo" More...
 
const char * kUnknownStr
 "Unknown" More...
 
const char * kUpperStr
 "Upper" More...
 
const char * kUpStr
 "Up" More...
 
const char * kWallStr
 "Wall" More...
 
const char * kWeeklyTimerStr
 "WeeklyTimer" More...
 
const char * kWideStr
 "Wide" More...
 
const char * kWifiStr
 "Wifi" More...
 
const char * kXFanStr
 "XFan" More...
 
const char * kYesStr
 "Yes" More...
 
const char * kZoneFollowStr
 "Zone Follow" More...
 
+

Variable Documentation

+ +

◆ k3DStr

+ +
+
+ + + + +
const char* k3DStr
+
+ +

"3D"

+ +
+
+ +

◆ k6thSenseStr

+ +
+
+ + + + +
const char* k6thSenseStr
+
+ +

"6th Sense"

+ +
+
+ +

◆ k8CHeatStr

+ +
+
+ + + + +
const char* k8CHeatStr
+
+ +

"8CHeat"

+ +
+
+ +

◆ kAirFlowStr

+ +
+
+ + + + +
const char* kAirFlowStr
+
+ +

"Air Flow"

+ +
+
+ +

◆ kAllProtocolNamesStr

+ +
+
+ + + + +
const char* kAllProtocolNamesStr
+
+ +

New protocol strings should be added just above this line.

+

This string requires double null termination.

+ +
+
+ +

◆ kAutomaticStr

+ +
+
+ + + + +
const char* kAutomaticStr
+
+ +

"Automatic"

+ +
+
+ +

◆ kAutoStr

+ +
+
+ + + + +
const char* kAutoStr
+
+ +

"Auto"

+ +
+
+ +

◆ kBeepStr

+ +
+
+ + + + +
const char* kBeepStr
+
+ +

"Beep"

+ +
+
+ +

◆ kBitsStr

+ +
+
+ + + + +
const char* kBitsStr
+
+ +

"Bits"

+ +
+
+ +

◆ kBottomStr

+ +
+
+ + + + +
const char* kBottomStr
+
+ +

"Bottom"

+ +
+
+ +

◆ kBreezeStr

+ +
+
+ + + + +
const char* kBreezeStr
+
+ +

"Breeze"

+ +
+
+ +

◆ kButtonStr

+ +
+
+ + + + +
const char* kButtonStr
+
+ +

"Button"

+ +
+
+ +

◆ kCancelStr

+ +
+
+ + + + +
const char* kCancelStr
+
+ +

"Cancel"

+ +
+
+ +

◆ kCeilingStr

+ +
+
+ + + + +
const char* kCeilingStr
+
+ +

"Ceiling"

+ +
+
+ +

◆ kCelsiusStr

+ +
+
+ + + + +
const char* kCelsiusStr
+
+ +

"Celsius"

+ +
+
+ +

◆ kCentreStr

+ +
+
+ + + + +
const char* kCentreStr
+
+ +

"Centre"

+ +
+
+ +

◆ kChangeStr

+ +
+
+ + + + +
const char* kChangeStr
+
+ +

"Change"

+ +
+
+ +

◆ kCirculateStr

+ +
+
+ + + + +
const char* kCirculateStr
+
+ +

"Circulate"

+ +
+
+ +

◆ kCleanStr

+ +
+
+ + + + +
const char* kCleanStr
+
+ +

"Clean"

+ +
+
+ +

◆ kClockStr

+ +
+
+ + + + +
const char* kClockStr
+
+ +

"Clock"

+ +
+
+ +

◆ kCodeStr

+ +
+
+ + + + +
const char* kCodeStr
+
+ +

"Code"

+ +
+
+ +

◆ kColonSpaceStr

+ +
+
+ + + + +
const char* kColonSpaceStr
+
+ +

": "

+ +
+
+ +

◆ kComfortStr

+ +
+
+ + + + +
const char* kComfortStr
+
+ +

"Comfort"

+ +
+
+ +

◆ kCommandStr

+ +
+
+ + + + +
const char* kCommandStr
+
+ +

"Command"

+ +
+
+ +

◆ kCommaSpaceStr

+ +
+
+ + + + +
const char* kCommaSpaceStr
+
+ +

", "

+ +
+
+ +

◆ kCoolStr

+ +
+
+ + + + +
const char* kCoolStr
+
+ +

"Cool"

+ +
+
+ +

◆ kDaysStr

+ +
+
+ + + + +
const char* kDaysStr
+
+ +

"Days"

+ +
+
+ +

◆ kDayStr

+ +
+
+ + + + +
const char* kDayStr
+
+ +

"Day"

+ +
+
+ +

◆ kDisplayTempStr

+ +
+
+ + + + +
const char* kDisplayTempStr
+
+ +

"Display Temp"

+ +
+
+ +

◆ kDownStr

+ +
+
+ + + + +
const char* kDownStr
+
+ +

"Down"

+ +
+
+ +

◆ kDryStr

+ +
+
+ + + + +
const char* kDryStr
+
+ +

"Dry"

+ +
+
+ +

◆ kEconoStr

+ +
+
+ + + + +
const char* kEconoStr
+
+ +

"Econo"

+ +
+
+ +

◆ kEyeAutoStr

+ +
+
+ + + + +
const char* kEyeAutoStr
+
+ +

"Eye Auto"

+ +
+
+ +

◆ kEyeStr

+ +
+
+ + + + +
const char* kEyeStr
+
+ +

"Eye"

+ +
+
+ +

◆ kFalseStr

+ +
+
+ + + + +
const char* kFalseStr
+
+ +

"False"

+ +
+
+ +

◆ kFanOnlyStr

+ +
+
+ + + + +
const char* kFanOnlyStr
+
+ +

"fan_only"

+ +
+
+ +

◆ kFanStr

+ +
+
+ + + + +
const char* kFanStr
+
+ +

"Fan"

+ +
+
+ +

◆ kFastStr

+ +
+
+ + + + +
const char* kFastStr
+
+ +

"Fast"

+ +
+
+ +

◆ kFilterStr

+ +
+
+ + + + +
const char* kFilterStr
+
+ +

"Filter"

+ +
+
+ +

◆ kFixedStr

+ +
+
+ + + + +
const char* kFixedStr
+
+ +

"Fixed"

+ +
+
+ +

◆ kFollowStr

+ +
+
+ + + + +
const char* kFollowStr
+
+ +

"Follow"

+ +
+
+ +

◆ kFreshStr

+ +
+
+ + + + +
const char* kFreshStr
+
+ +

"Fresh"

+ +
+
+ +

◆ kHealthStr

+ +
+
+ + + + +
const char* kHealthStr
+
+ +

"Health"

+ +
+
+ +

◆ kHeatStr

+ +
+
+ + + + +
const char* kHeatStr
+
+ +

"Heat"

+ +
+
+ +

◆ kHighestStr

+ +
+
+ + + + +
const char* kHighestStr
+
+ +

"Highest"

+ +
+
+ +

◆ kHighStr

+ +
+
+ + + + +
const char* kHighStr
+
+ +

"High"

+ +
+
+ +

◆ kHiStr

+ +
+
+ + + + +
const char* kHiStr
+
+ +

"Hi"

+ +
+
+ +

◆ kHoldStr

+ +
+
+ + + + +
const char* kHoldStr
+
+ +

"Hold"

+ +
+
+ +

◆ kHoursStr

+ +
+
+ + + + +
const char* kHoursStr
+
+ +

"Hours"

+ +
+
+ +

◆ kHourStr

+ +
+
+ + + + +
const char* kHourStr
+
+ +

"Hour"

+ +
+
+ +

◆ kHumidStr

+ +
+
+ + + + +
const char* kHumidStr
+
+ +

"Humid"

+ +
+
+ +

◆ kIFeelStr

+ +
+
+ + + + +
const char* kIFeelStr
+
+ +

"IFeel"

+ +
+
+ +

◆ kInsideStr

+ +
+
+ + + + +
const char* kInsideStr
+
+ +

"Inside"

+ +
+
+ +

◆ kIonStr

+ +
+
+ + + + +
const char* kIonStr
+
+ +

"Ion"

+ +
+
+ +

◆ kLastStr

+ +
+
+ + + + +
const char* kLastStr
+
+ +

"Last"

+ +
+
+ +

◆ kLeftMaxStr

+ +
+
+ + + + +
const char* kLeftMaxStr
+
+ +

"LeftMax"

+ +
+
+ +

◆ kLeftStr

+ +
+
+ + + + +
const char* kLeftStr
+
+ +

"Left"

+ +
+
+ +

◆ kLightStr

+ +
+
+ + + + +
const char* kLightStr
+
+ +

"Light"

+ +
+
+ +

◆ kLightToggleStr

+ +
+
+ + + + +
const char* kLightToggleStr
+
+ +

"Light Toggle"

+ +
+
+ +

◆ kLoStr

+ +
+
+ + + + +
const char* kLoStr
+
+ +

"Lo"

+ +
+
+ +

◆ kLoudStr

+ +
+
+ + + + +
const char* kLoudStr
+
+ +

"Loud"

+ +
+
+ +

◆ kLowerStr

+ +
+
+ + + + +
const char* kLowerStr
+
+ +

"Lower"

+ +
+
+ +

◆ kLowestStr

+ +
+
+ + + + +
const char* kLowestStr
+
+ +

"Lowest"

+ +
+
+ +

◆ kLowStr

+ +
+
+ + + + +
const char* kLowStr
+
+ +

"Low"

+ +
+
+ +

◆ kManualStr

+ +
+
+ + + + +
const char* kManualStr
+
+ +

"Manual"

+ +
+
+ +

◆ kMaximumStr

+ +
+
+ + + + +
const char* kMaximumStr
+
+ +

"Maximum"

+ +
+
+ +

◆ kMaxLeftStr

+ +
+
+ + + + +
const char* kMaxLeftStr
+
+ +

"Max Left"

+ +
+
+ +

◆ kMaxRightStr

+ +
+
+ + + + +
const char* kMaxRightStr
+
+ +

"Max Right"

+ +
+
+ +

◆ kMaxStr

+ +
+
+ + + + +
const char* kMaxStr
+
+ +

"Max"

+ +
+
+ +

◆ kMediumStr

+ +
+
+ + + + +
const char* kMediumStr
+
+ +

"Medium"

+ +
+
+ +

◆ kMedStr

+ +
+
+ + + + +
const char* kMedStr
+
+ +

"Med"

+ +
+
+ +

◆ kMiddleStr

+ +
+
+ + + + +
const char* kMiddleStr
+
+ +

"Middle"

+ +
+
+ +

◆ kMidStr

+ +
+
+ + + + +
const char* kMidStr
+
+ +

"Mid"

+ +
+
+ +

◆ kMinimumStr

+ +
+
+ + + + +
const char* kMinimumStr
+
+ +

"Minimum"

+ +
+
+ +

◆ kMinStr

+ +
+
+ + + + +
const char* kMinStr
+
+ +

"Min"

+ +
+
+ +

◆ kMinutesStr

+ +
+
+ + + + +
const char* kMinutesStr
+
+ +

"Minutes"

+ +
+
+ +

◆ kMinuteStr

+ +
+
+ + + + +
const char* kMinuteStr
+
+ +

"Minute"

+ +
+
+ +

◆ kModelStr

+ +
+
+ + + + +
const char* kModelStr
+
+ +

"Model"

+ +
+
+ +

◆ kModeStr

+ +
+
+ + + + +
const char* kModeStr
+
+ +

"Mode"

+ +
+
+ +

◆ kMouldStr

+ +
+
+ + + + +
const char* kMouldStr
+
+ +

"Mould"

+ +
+
+ +

◆ kMoveStr

+ +
+
+ + + + +
const char* kMoveStr
+
+ +

"Move"

+ +
+
+ +

◆ kNAStr

+ +
+
+ + + + +
const char* kNAStr
+
+ +

"N/A"

+ +
+
+ +

◆ kNightStr

+ +
+
+ + + + +
const char* kNightStr
+
+ +

"Night"

+ +
+
+ +

◆ kNoStr

+ +
+
+ + + + +
const char* kNoStr
+
+ +

"No"

+ +
+
+ +

◆ kNowStr

+ +
+
+ + + + +
const char* kNowStr
+
+ +

"Now"

+ +
+
+ +

◆ kOffStr

+ +
+
+ + + + +
const char* kOffStr
+
+ +

"Off"

+ +
+
+ +

◆ kOffTimerStr

+ +
+
+ + + + +
const char* kOffTimerStr
+
+ +

"OffTimer"

+ +
+
+ +

◆ kOnStr

+ +
+
+ + + + +
const char* kOnStr
+
+ +

"On"

+ +
+
+ +

◆ kOnTimerStr

+ +
+
+ + + + +
const char* kOnTimerStr
+
+ +

"OnTimer"

+ +
+
+ +

◆ kOutsideQuietStr

+ +
+
+ + + + +
const char* kOutsideQuietStr
+
+ +

"Outside Quiet"

+ +
+
+ +

◆ kOutsideStr

+ +
+
+ + + + +
const char* kOutsideStr
+
+ +

"Outside"

+ +
+
+ +

◆ kPowerButtonStr

+ +
+
+ + + + +
const char* kPowerButtonStr
+
+ +

"Power Button"

+ +
+
+ +

◆ kPowerfulStr

+ +
+
+ + + + +
const char* kPowerfulStr
+
+ +

"Powerful"

+ +
+
+ +

◆ kPowerStr

+ +
+
+ + + + +
const char* kPowerStr
+
+ +

"Power"

+ +
+
+ +

◆ kPowerToggleStr

+ +
+
+ + + + +
const char* kPowerToggleStr
+
+ +

"Power Toggle"

+ +
+
+ +

◆ kPreviousPowerStr

+ +
+
+ + + + +
const char* kPreviousPowerStr
+
+ +

"Previous Power"

+ +
+
+ +

◆ kProtocolStr

+ +
+
+ + + + +
const char* kProtocolStr
+
+ +

"Protocol"

+ +
+
+ +

◆ kPurifyStr

+ +
+
+ + + + +
const char* kPurifyStr
+
+ +

"Purify"

+ +
+
+ +

◆ kQuietStr

+ +
+
+ + + + +
const char* kQuietStr
+
+ +

"Quiet"

+ +
+
+ +

◆ kRepeatStr

+ +
+
+ + + + +
const char* kRepeatStr
+
+ +

"Repeat"

+ +
+
+ +

◆ kRightMaxStr

+ +
+
+ + + + +
const char* kRightMaxStr
+
+ +

"RightMax"

+ +
+
+ +

◆ kRightStr

+ +
+
+ + + + +
const char* kRightStr
+
+ +

"Right"

+ +
+
+ +

◆ kRoomStr

+ +
+
+ + + + +
const char* kRoomStr
+
+ +

"Room"

+ +
+
+ +

◆ kSaveStr

+ +
+
+ + + + +
const char* kSaveStr
+
+ +

"Save"

+ +
+
+ +

◆ kSecondsStr

+ +
+
+ + + + +
const char* kSecondsStr
+
+ +

"Seconds"

+ +
+
+ +

◆ kSecondStr

+ +
+
+ + + + +
const char* kSecondStr
+
+ +

"Second"

+ +
+
+ +

◆ kSensorStr

+ +
+
+ + + + +
const char* kSensorStr
+
+ +

"Sensor"

+ +
+
+ +

◆ kSensorTempStr

+ +
+
+ + + + +
const char* kSensorTempStr
+
+ +

"Sensor Temp"

+ +
+
+ +

◆ kSetStr

+ +
+
+ + + + +
const char* kSetStr
+
+ +

"Set"

+ +
+
+ +

◆ kSilentStr

+ +
+
+ + + + +
const char* kSilentStr
+
+ +

"Silent"

+ +
+
+ +

◆ kSleepStr

+ +
+
+ + + + +
const char* kSleepStr
+
+ +

"Sleep"

+ +
+
+ +

◆ kSleepTimerStr

+ +
+
+ + + + +
const char* kSleepTimerStr
+
+ +

"Sleep Timer"

+ +
+
+ +

◆ kSlowStr

+ +
+
+ + + + +
const char* kSlowStr
+
+ +

"Slow"

+ +
+
+ +

◆ kSpaceLBraceStr

+ +
+
+ + + + +
const char* kSpaceLBraceStr
+
+ +

" ("

+ +
+
+ +

◆ kStartStr

+ +
+
+ + + + +
const char* kStartStr
+
+ +

"Start"

+ +
+
+ +

◆ kStepStr

+ +
+
+ + + + +
const char* kStepStr
+
+ +

"Step"

+ +
+
+ +

◆ kStopStr

+ +
+
+ + + + +
const char* kStopStr
+
+ +

"Stop"

+ +
+
+ +

◆ kSuperStr

+ +
+
+ + + + +
const char* kSuperStr
+
+ +

"Super"

+ +
+
+ +

◆ kSwingHStr

+ +
+
+ + + + +
const char* kSwingHStr
+
+ +

"SwingH"

+ +
+
+ +

◆ kSwingStr

+ +
+
+ + + + +
const char* kSwingStr
+
+ +

"Swing"

+ +
+
+ +

◆ kSwingVModeStr

+ +
+
+ + + + +
const char* kSwingVModeStr
+
+ +

"Swing(V) Mode"

+ +
+
+ +

◆ kSwingVStr

+ +
+
+ + + + +
const char* kSwingVStr
+
+ +

"SwingV"

+ +
+
+ +

◆ kSwingVToggleStr

+ +
+
+ + + + +
const char* kSwingVToggleStr
+
+ +

"Swing(V) Toggle"

+ +
+
+ +

◆ kTempDownStr

+ +
+
+ + + + +
const char* kTempDownStr
+
+ +

"Temp Down"

+ +
+
+ +

◆ kTempStr

+ +
+
+ + + + +
const char* kTempStr
+
+ +

"Temp"

+ +
+
+ +

◆ kTempUpStr

+ +
+
+ + + + +
const char* kTempUpStr
+
+ +

"Temp Up"

+ +
+
+ +

◆ kThreeLetterDayOfWeekStr

+ +
+
+ + + + +
const char* kThreeLetterDayOfWeekStr
+
+ +

"SunMonTueWedThuFriSat"

+ +
+
+ +

◆ kTimerStr

+ +
+
+ + + + +
const char* kTimerStr
+
+ +

"Timer"

+ +
+
+ +

◆ kTimeSep

+ +
+
+ + + + +
char kTimeSep
+
+ +

':'

+ +
+
+ +

◆ kToggleStr

+ +
+
+ + + + +
const char* kToggleStr
+
+ +

"Toggle"

+ +
+
+ +

◆ kTopStr

+ +
+
+ + + + +
const char* kTopStr
+
+ +

"Top"

+ +
+
+ +

◆ kTrueStr

+ +
+
+ + + + +
const char* kTrueStr
+
+ +

"True"

+ +
+
+ +

◆ kTurboStr

+ +
+
+ + + + +
const char* kTurboStr
+
+ +

"Turbo"

+ +
+
+ +

◆ kUnknownStr

+ +
+
+ + + + +
const char* kUnknownStr
+
+ +

"Unknown"

+ +
+
+ +

◆ kUpperStr

+ +
+
+ + + + +
const char* kUpperStr
+
+ +

"Upper"

+ +
+
+ +

◆ kUpStr

+ +
+
+ + + + +
const char* kUpStr
+
+ +

"Up"

+ +
+
+ +

◆ kWallStr

+ +
+
+ + + + +
const char* kWallStr
+
+ +

"Wall"

+ +
+
+ +

◆ kWeeklyTimerStr

+ +
+
+ + + + +
const char* kWeeklyTimerStr
+
+ +

"WeeklyTimer"

+ +
+
+ +

◆ kWideStr

+ +
+
+ + + + +
const char* kWideStr
+
+ +

"Wide"

+ +
+
+ +

◆ kWifiStr

+ +
+
+ + + + +
const char* kWifiStr
+
+ +

"Wifi"

+ +
+
+ +

◆ kXFanStr

+ +
+
+ + + + +
const char* kXFanStr
+
+ +

"XFan"

+ +
+
+ +

◆ kYesStr

+ +
+
+ + + + +
const char* kYesStr
+
+ +

"Yes"

+ +
+
+ +

◆ kZoneFollowStr

+ +
+
+ + + + +
const char* kZoneFollowStr
+
+ +

"Zone Follow"

+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtext_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtext_8h_source.html new file mode 100644 index 000000000..a4b704249 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtext_8h_source.html @@ -0,0 +1,383 @@ + + + + + + + +IRremoteESP8266: src/IRtext.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
IRtext.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 - David Conran (@crankyoldgit)
+
2 // This header file is to be included in files **other than** 'IRtext.cpp'.
+
3 //
+
4 // WARNING: Do not edit this file! This file is automatically generated by
+
5 // 'tools/generate_irtext_h.sh'.
+
6 
+
7 #ifndef IRTEXT_H_
+
8 #define IRTEXT_H_
+
9 
+
10 #include "i18n.h"
+
11 
+
12 // Constant text to be shared across all object files.
+
13 // This means there is only one copy of the character/string/text etc.
+
14 
+
15 extern char kTimeSep;
+
16 extern const char* k3DStr;
+
17 extern const char* k6thSenseStr;
+
18 extern const char* k8CHeatStr;
+
19 extern const char* kAirFlowStr;
+
20 extern const char *kAllProtocolNamesStr;
+
21 extern const char* kAutomaticStr;
+
22 extern const char* kAutoStr;
+
23 extern const char* kBeepStr;
+
24 extern const char* kBitsStr;
+
25 extern const char* kBottomStr;
+
26 extern const char* kBreezeStr;
+
27 extern const char* kButtonStr;
+
28 extern const char* kCancelStr;
+
29 extern const char* kCeilingStr;
+
30 extern const char* kCelsiusStr;
+
31 extern const char* kCentreStr;
+
32 extern const char* kChangeStr;
+
33 extern const char* kCirculateStr;
+
34 extern const char* kCleanStr;
+
35 extern const char* kClockStr;
+
36 extern const char* kCodeStr;
+
37 extern const char* kColonSpaceStr;
+
38 extern const char* kComfortStr;
+
39 extern const char* kCommandStr;
+
40 extern const char* kCommaSpaceStr;
+
41 extern const char* kCoolStr;
+
42 extern const char* kDaysStr;
+
43 extern const char* kDayStr;
+
44 extern const char* kDisplayTempStr;
+
45 extern const char* kDownStr;
+
46 extern const char* kDryStr;
+
47 extern const char* kEconoStr;
+
48 extern const char* kEyeAutoStr;
+
49 extern const char* kEyeStr;
+
50 extern const char* kFalseStr;
+
51 extern const char* kFanOnlyStr;
+
52 extern const char* kFanStr;
+
53 extern const char* kFastStr;
+
54 extern const char* kFilterStr;
+
55 extern const char* kFixedStr;
+
56 extern const char* kFollowStr;
+
57 extern const char* kFreshStr;
+
58 extern const char* kHealthStr;
+
59 extern const char* kHeatStr;
+
60 extern const char* kHighestStr;
+
61 extern const char* kHighStr;
+
62 extern const char* kHiStr;
+
63 extern const char* kHoldStr;
+
64 extern const char* kHoursStr;
+
65 extern const char* kHourStr;
+
66 extern const char* kHumidStr;
+
67 extern const char* kIFeelStr;
+
68 extern const char* kInsideStr;
+
69 extern const char* kIonStr;
+
70 extern const char* kLastStr;
+
71 extern const char* kLeftMaxStr;
+
72 extern const char* kLeftStr;
+
73 extern const char* kLightStr;
+
74 extern const char* kLightToggleStr;
+
75 extern const char* kLoStr;
+
76 extern const char* kLoudStr;
+
77 extern const char* kLowerStr;
+
78 extern const char* kLowestStr;
+
79 extern const char* kLowStr;
+
80 extern const char* kManualStr;
+
81 extern const char* kMaximumStr;
+
82 extern const char* kMaxLeftStr;
+
83 extern const char* kMaxRightStr;
+
84 extern const char* kMaxStr;
+
85 extern const char* kMediumStr;
+
86 extern const char* kMedStr;
+
87 extern const char* kMiddleStr;
+
88 extern const char* kMidStr;
+
89 extern const char* kMinimumStr;
+
90 extern const char* kMinStr;
+
91 extern const char* kMinutesStr;
+
92 extern const char* kMinuteStr;
+
93 extern const char* kModelStr;
+
94 extern const char* kModeStr;
+
95 extern const char* kMouldStr;
+
96 extern const char* kMoveStr;
+
97 extern const char* kNAStr;
+
98 extern const char* kNightStr;
+
99 extern const char* kNoStr;
+
100 extern const char* kNowStr;
+
101 extern const char* kOffStr;
+
102 extern const char* kOffTimerStr;
+
103 extern const char* kOnStr;
+
104 extern const char* kOnTimerStr;
+
105 extern const char* kOutsideQuietStr;
+
106 extern const char* kOutsideStr;
+
107 extern const char* kPowerfulStr;
+
108 extern const char* kPowerStr;
+
109 extern const char* kPowerToggleStr;
+
110 extern const char* kPowerButtonStr;
+
111 extern const char* kPreviousPowerStr;
+
112 extern const char* kProtocolStr;
+
113 extern const char* kPurifyStr;
+
114 extern const char* kQuietStr;
+
115 extern const char* kRepeatStr;
+
116 extern const char* kRightMaxStr;
+
117 extern const char* kRightStr;
+
118 extern const char* kRoomStr;
+
119 extern const char* kSaveStr;
+
120 extern const char* kSecondsStr;
+
121 extern const char* kSecondStr;
+
122 extern const char* kSensorStr;
+
123 extern const char* kSensorTempStr;
+
124 extern const char* kSetStr;
+
125 extern const char* kSilentStr;
+
126 extern const char* kSleepStr;
+
127 extern const char* kSleepTimerStr;
+
128 extern const char* kSlowStr;
+
129 extern const char* kSpaceLBraceStr;
+
130 extern const char* kStartStr;
+
131 extern const char* kStepStr;
+
132 extern const char* kStopStr;
+
133 extern const char* kSuperStr;
+
134 extern const char* kSwingHStr;
+
135 extern const char* kSwingStr;
+
136 extern const char* kSwingVModeStr;
+
137 extern const char* kSwingVStr;
+
138 extern const char* kSwingVToggleStr;
+
139 extern const char* kTempDownStr;
+
140 extern const char* kTempStr;
+
141 extern const char* kTempUpStr;
+
142 extern const char* kThreeLetterDayOfWeekStr;
+
143 extern const char* kTimerStr;
+
144 extern const char* kToggleStr;
+
145 extern const char* kTopStr;
+
146 extern const char* kTrueStr;
+
147 extern const char* kTurboStr;
+
148 extern const char* kUnknownStr;
+
149 extern const char* kUpperStr;
+
150 extern const char* kUpStr;
+
151 extern const char* kWallStr;
+
152 extern const char* kWeeklyTimerStr;
+
153 extern const char* kWideStr;
+
154 extern const char* kWifiStr;
+
155 extern const char* kXFanStr;
+
156 extern const char* kYesStr;
+
157 extern const char* kZoneFollowStr;
+
158 
+
159 #endif // IRTEXT_H_
+
+
const char * kTrueStr
"True"
Definition: IRtext.cpp:168
+
const char * kHoldStr
"Hold"
Definition: IRtext.cpp:57
+
const char * kStopStr
"Stop"
Definition: IRtext.cpp:68
+
const char * kQuietStr
"Quiet"
Definition: IRtext.cpp:30
+
const char * kBitsStr
"Bits"
Definition: IRtext.cpp:173
+
const char * kPowerButtonStr
"Power Button"
Definition: IRtext.cpp:137
+
const char * kMediumStr
"Medium"
Definition: IRtext.cpp:111
+
const char * kStepStr
"Step"
Definition: IRtext.cpp:83
+
const char * kSilentStr
"Silent"
Definition: IRtext.cpp:61
+
const char * kOnTimerStr
"OnTimer"
Definition: IRtext.cpp:42
+
const char * kLoStr
"Lo"
Definition: IRtext.cpp:119
+
const char * kSwingStr
"Swing"
Definition: IRtext.cpp:32
+
const char * kCodeStr
"Code"
Definition: IRtext.cpp:172
+
const char * kSecondsStr
"Seconds"
Definition: IRtext.cpp:162
+
const char * kSetStr
"Set"
Definition: IRtext.cpp:70
+
const char * kHiStr
"Hi"
Definition: IRtext.cpp:115
+
const char * kRepeatStr
"Repeat"
Definition: IRtext.cpp:171
+
const char * kCeilingStr
"Ceiling"
Definition: IRtext.cpp:92
+
const char * kPowerToggleStr
"Power Toggle"
Definition: IRtext.cpp:136
+
const char * kInsideStr
"Inside"
Definition: IRtext.cpp:85
+
const char * kTempDownStr
"Temp Down"
Definition: IRtext.cpp:66
+
const char * kMoveStr
"Move"
Definition: IRtext.cpp:69
+
const char * kColonSpaceStr
": "
Definition: IRtext.cpp:151
+
const char * kWideStr
"Wide"
Definition: IRtext.cpp:127
+
const char * kRightMaxStr
"RightMax"
Definition: IRtext.cpp:122
+
const char * kDownStr
"Down"
Definition: IRtext.cpp:73
+
const char * kLightStr
"Light"
Definition: IRtext.cpp:28
+
const char * kCoolStr
"Cool"
Definition: IRtext.cpp:100
+
const char * kRightStr
"Right"
Definition: IRtext.cpp:123
+
const char * kMinuteStr
"Minute"
Definition: IRtext.cpp:159
+
const char * kMinutesStr
"Minutes"
Definition: IRtext.cpp:160
+
const char * kSleepStr
"Sleep"
Definition: IRtext.cpp:27
+
const char * kMinimumStr
"Minimum"
Definition: IRtext.cpp:109
+
const char * k3DStr
"3D"
Definition: IRtext.cpp:63
+
const char * kTempStr
"Temp"
Definition: IRtext.cpp:49
+
const char * kAutomaticStr
"Automatic"
Definition: IRtext.cpp:98
+
const char * kSecondStr
"Second"
Definition: IRtext.cpp:161
+
const char * kSwingVToggleStr
"Swing(V) Toggle"
Definition: IRtext.cpp:144
+
const char * k6thSenseStr
"6th Sense"
Definition: IRtext.cpp:95
+
const char * kFilterStr
"Filter"
Definition: IRtext.cpp:62
+
const char * kNightStr
"Night"
Definition: IRtext.cpp:60
+
const char * kSpaceLBraceStr
" ("
Definition: IRtext.cpp:149
+
const char * kSleepTimerStr
"Sleep Timer"
Definition: IRtext.cpp:142
+
const char * kSwingVModeStr
"Swing(V) Mode"
Definition: IRtext.cpp:143
+
const char * kTimerStr
"Timer"
Definition: IRtext.cpp:41
+
const char * kChangeStr
"Change"
Definition: IRtext.cpp:74
+
const char * kAllProtocolNamesStr
New protocol strings should be added just above this line.
Definition: IRtext.cpp:177
+
const char * kIFeelStr
"IFeel"
Definition: IRtext.cpp:50
+
const char * kFalseStr
"False"
Definition: IRtext.cpp:169
+
const char * kMaxLeftStr
"Max Left"
Definition: IRtext.cpp:125
+
const char * kHealthStr
"Health"
Definition: IRtext.cpp:47
+
const char * kCommandStr
"Command"
Definition: IRtext.cpp:45
+
const char * kXFanStr
"XFan"
Definition: IRtext.cpp:46
+
const char * kPurifyStr
"Purify"
Definition: IRtext.cpp:40
+
const char * kHighStr
"High"
Definition: IRtext.cpp:114
+
const char * kCommaSpaceStr
", "
Definition: IRtext.cpp:150
+
const char * kFanStr
"Fan"
Definition: IRtext.cpp:102
+
const char * kTopStr
"Top"
Definition: IRtext.cpp:129
+
const char * kNowStr
"Now"
Definition: IRtext.cpp:163
+
const char * kOffStr
"Off"
Definition: IRtext.cpp:22
+
const char * kMaximumStr
"Maximum"
Definition: IRtext.cpp:107
+
const char * kButtonStr
"Button"
Definition: IRtext.cpp:58
+ +
const char * kTempUpStr
"Temp Up"
Definition: IRtext.cpp:65
+
const char * kCleanStr
"Clean"
Definition: IRtext.cpp:39
+
const char * kIonStr
"Ion"
Definition: IRtext.cpp:55
+
const char * kProtocolStr
"Protocol"
Definition: IRtext.cpp:19
+
const char * kEyeStr
"Eye"
Definition: IRtext.cpp:53
+
const char * kMedStr
"Med"
Definition: IRtext.cpp:110
+
const char * kThreeLetterDayOfWeekStr
"SunMonTueWedThuFriSat"
Definition: IRtext.cpp:164
+
const char * kCancelStr
"Cancel"
Definition: IRtext.cpp:71
+
const char * kWallStr
"Wall"
Definition: IRtext.cpp:93
+
const char * kToggleStr
"Toggle"
Definition: IRtext.cpp:24
+
const char * kMouldStr
"Mould"
Definition: IRtext.cpp:38
+
const char * kBottomStr
"Bottom"
Definition: IRtext.cpp:130
+
const char * kBeepStr
"Beep"
Definition: IRtext.cpp:35
+
const char * kRoomStr
"Room"
Definition: IRtext.cpp:94
+
const char * kFastStr
"Fast"
Definition: IRtext.cpp:80
+
const char * kDryStr
"Dry"
Definition: IRtext.cpp:103
+
const char * kUpperStr
"Upper"
Definition: IRtext.cpp:89
+
const char * kMiddleStr
"Middle"
Definition: IRtext.cpp:117
+
const char * kAirFlowStr
"Air Flow"
Definition: IRtext.cpp:82
+
const char * kLoudStr
"Loud"
Definition: IRtext.cpp:87
+
const char * kUnknownStr
"Unknown"
Definition: IRtext.cpp:18
+
const char * kSuperStr
"Super"
Definition: IRtext.cpp:26
+
const char * kAutoStr
"Auto"
Definition: IRtext.cpp:97
+
const char * kMidStr
"Mid"
Definition: IRtext.cpp:116
+
const char * kYesStr
"Yes"
Definition: IRtext.cpp:166
+
const char * kSlowStr
"Slow"
Definition: IRtext.cpp:81
+
const char * k8CHeatStr
"8CHeat"
Definition: IRtext.cpp:59
+
const char * kClockStr
"Clock"
Definition: IRtext.cpp:44
+
const char * kLeftMaxStr
"LeftMax"
Definition: IRtext.cpp:126
+
const char * kMaxStr
"Max"
Definition: IRtext.cpp:106
+
const char * kSaveStr
"Save"
Definition: IRtext.cpp:52
+
const char * kLightToggleStr
"Light Toggle"
Definition: IRtext.cpp:134
+
const char * kDayStr
"Day"
Definition: IRtext.cpp:155
+
const char * kFreshStr
"Fresh"
Definition: IRtext.cpp:56
+
const char * kCentreStr
"Centre"
Definition: IRtext.cpp:128
+
const char * kManualStr
"Manual"
Definition: IRtext.cpp:99
+
const char * kHeatStr
"Heat"
Definition: IRtext.cpp:101
+
const char * kMaxRightStr
"Max Right"
Definition: IRtext.cpp:121
+
const char * kUpStr
"Up"
Definition: IRtext.cpp:72
+
const char * kCelsiusStr
"Celsius"
Definition: IRtext.cpp:64
+
const char * kOnStr
"On"
Definition: IRtext.cpp:21
+
const char * kHoursStr
"Hours"
Definition: IRtext.cpp:158
+
const char * kBreezeStr
"Breeze"
Definition: IRtext.cpp:90
+
const char * kPowerfulStr
"Powerful"
Definition: IRtext.cpp:29
+
const char * kEyeAutoStr
"Eye Auto"
Definition: IRtext.cpp:133
+
const char * kComfortStr
"Comfort"
Definition: IRtext.cpp:75
+
const char * kHighestStr
"Highest"
Definition: IRtext.cpp:113
+
const char * kFanOnlyStr
"fan_only"
Definition: IRtext.cpp:104
+
const char * kMinStr
"Min"
Definition: IRtext.cpp:108
+
const char * kFollowStr
"Follow"
Definition: IRtext.cpp:54
+
const char * kWeeklyTimerStr
"WeeklyTimer"
Definition: IRtext.cpp:77
+
const char * kOutsideQuietStr
"Outside Quiet"
Definition: IRtext.cpp:135
+
const char * kLowStr
"Low"
Definition: IRtext.cpp:118
+
const char * kFixedStr
"Fixed"
Definition: IRtext.cpp:37
+
const char * kStartStr
"Start"
Definition: IRtext.cpp:67
+
const char * kDaysStr
"Days"
Definition: IRtext.cpp:156
+
const char * kWifiStr
"Wifi"
Definition: IRtext.cpp:78
+
const char * kSwingHStr
"SwingH"
Definition: IRtext.cpp:33
+
const char * kLastStr
"Last"
Definition: IRtext.cpp:79
+
const char * kEconoStr
"Econo"
Definition: IRtext.cpp:31
+
const char * kNAStr
"N/A"
Definition: IRtext.cpp:84
+
char kTimeSep
':'
Definition: IRtext.cpp:148
+
const char * kModelStr
"Model"
Definition: IRtext.cpp:48
+
const char * kOutsideStr
"Outside"
Definition: IRtext.cpp:86
+
const char * kPowerStr
"Power"
Definition: IRtext.cpp:20
+
const char * kCirculateStr
"Circulate"
Definition: IRtext.cpp:91
+
const char * kLeftStr
"Left"
Definition: IRtext.cpp:124
+
const char * kSensorStr
"Sensor"
Definition: IRtext.cpp:76
+
const char * kPreviousPowerStr
"Previous Power"
Definition: IRtext.cpp:138
+
const char * kHumidStr
"Humid"
Definition: IRtext.cpp:51
+
const char * kZoneFollowStr
"Zone Follow"
Definition: IRtext.cpp:36
+
const char * kNoStr
"No"
Definition: IRtext.cpp:167
+
const char * kOffTimerStr
"OffTimer"
Definition: IRtext.cpp:43
+
const char * kLowerStr
"Lower"
Definition: IRtext.cpp:88
+
const char * kDisplayTempStr
"Display Temp"
Definition: IRtext.cpp:140
+
const char * kSwingVStr
"SwingV"
Definition: IRtext.cpp:34
+
const char * kLowestStr
"Lowest"
Definition: IRtext.cpp:120
+
const char * kTurboStr
"Turbo"
Definition: IRtext.cpp:25
+
const char * kHourStr
"Hour"
Definition: IRtext.cpp:157
+
const char * kModeStr
"Mode"
Definition: IRtext.cpp:23
+
const char * kSensorTempStr
"Sensor Temp"
Definition: IRtext.cpp:141
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtimer_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtimer_8cpp.html new file mode 100644 index 000000000..8c3da0949 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtimer_8cpp.html @@ -0,0 +1,119 @@ + + + + + + + +IRremoteESP8266: src/IRtimer.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
IRtimer.cpp File Reference
+
+
+ + + + + + +

+Variables

uint32_t _IRtimer_unittest_now = 0
 
uint32_t _TimerMs_unittest_now = 0
 
+

Variable Documentation

+ +

◆ _IRtimer_unittest_now

+ +
+
+ + + + +
uint32_t _IRtimer_unittest_now = 0
+
+ +
+
+ +

◆ _TimerMs_unittest_now

+ +
+
+ + + + +
uint32_t _TimerMs_unittest_now = 0
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtimer_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtimer_8h.html new file mode 100644 index 000000000..333d009b4 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtimer_8h.html @@ -0,0 +1,94 @@ + + + + + + + +IRremoteESP8266: src/IRtimer.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
IRtimer.h File Reference
+
+
+ +

Go to the source code of this file.

+ + + + + + + + +

+Classes

class  IRtimer
 This class performs a simple timer in useconds since instantiated. More...
 
class  TimerMs
 This class performs a simple timer in milli-seoncds since instantiated. More...
 
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtimer_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtimer_8h_source.html new file mode 100644 index 000000000..eaef1f0bc --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRtimer_8h_source.html @@ -0,0 +1,128 @@ + + + + + + + +IRremoteESP8266: src/IRtimer.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
IRtimer.h
+
+
+Go to the documentation of this file.
1 // Copyright 2017 David Conran
+
2 
+
3 #ifndef IRTIMER_H_
+
4 #define IRTIMER_H_
+
5 
+
6 #define __STDC_LIMIT_MACROS
+
7 #include <stdint.h>
+
8 
+
9 // Classes
+
10 
+
13 class IRtimer {
+
14  public:
+
15  IRtimer();
+
16  void reset();
+
17  uint32_t elapsed();
+
18 #ifdef UNIT_TEST
+
19  static void add(uint32_t usecs);
+
20 #endif // UNIT_TEST
+
21 
+
22  private:
+
23  uint32_t start;
+
24 };
+
25 
+
28 class TimerMs {
+
29  public:
+
30  TimerMs();
+
31  void reset();
+
32  uint32_t elapsed();
+
33 #ifdef UNIT_TEST
+
34  static void add(uint32_t msecs);
+
35 #endif // UNIT_TEST
+
36 
+
37  private:
+
38  uint32_t start;
+
39 };
+
40 #endif // IRTIMER_H_
+
+
uint32_t start
Definition: IRtimer.h:38
+
This class performs a simple timer in useconds since instantiated.
Definition: IRtimer.h:13
+
static void add(uint32_t usecs)
Add time to the timer to simulate elapsed time.
Definition: IRtimer.cpp:44
+
void reset()
Resets the IRtimer object.
Definition: IRtimer.cpp:18
+
IRtimer()
Class constructor.
Definition: IRtimer.cpp:15
+
uint32_t elapsed()
Calculate how many microseconds have elapsed since the timer was started.
Definition: IRtimer.cpp:28
+
uint32_t elapsed()
Calculate how many milliseconds have elapsed since the timer was started.
Definition: IRtimer.cpp:61
+
void reset()
Resets the TimerMs object.
Definition: IRtimer.cpp:51
+
TimerMs()
Class constructor.
Definition: IRtimer.cpp:48
+
uint32_t start
Definition: IRtimer.h:23
+
static void add(uint32_t msecs)
Add time to the timer to simulate elapsed time.
Definition: IRtimer.cpp:77
+
This class performs a simple timer in milli-seoncds since instantiated.
Definition: IRtimer.h:28
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRutils_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRutils_8cpp.html new file mode 100644 index 000000000..b0d65d3dc --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRutils_8cpp.html @@ -0,0 +1,871 @@ + + + + + + + +IRremoteESP8266: src/IRutils.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
IRutils.cpp File Reference
+
+
+ + + + + +

+Namespaces

 irutils
 Namespace for covering common functions & procedures for advancd protocol handlers.
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Functions

uint64_t reverseBits (uint64_t input, uint16_t nbits)
 Reverse the order of the requested least significant nr. of bits. More...
 
String uint64ToString (uint64_t input, uint8_t base)
 Convert a uint64_t (unsigned long long) to a string. Arduino String/toInt/Serial.print() can't handle printing 64 bit values. More...
 
void serialPrintUint64 (uint64_t input, uint8_t base)
 Print a uint64_t/unsigned long long to the Serial port Serial.print() can't handle printing long longs. (uint64_t) More...
 
decode_type_t strToDecodeType (const char *const str)
 Convert a C-style string to a decode_type_t. More...
 
String typeToString (const decode_type_t protocol, const bool isRepeat)
 Convert a protocol type (enum etc) to a human readable string. More...
 
bool hasACState (const decode_type_t protocol)
 Does the given protocol use a complex state as part of the decode? More...
 
uint16_t getCorrectedRawLength (const decode_results *const results)
 Return the corrected length of a 'raw' format array structure after over-large values are converted into multiple entries. More...
 
String resultToSourceCode (const decode_results *const results)
 Return a String containing the key values of a decode_results structure in a C/C++ code style format. More...
 
String resultToTimingInfo (const decode_results *const results)
 Dump out the decode_results structure. More...
 
String resultToHexidecimal (const decode_results *const result)
 Convert the decode_results structure's value/state to simple hexadecimal. More...
 
String resultToHumanReadableBasic (const decode_results *const results)
 Dump out the decode_results structure into a human readable format. More...
 
uint16_t * resultToRawArray (const decode_results *const decode)
 Convert a decode_results into an array suitable for sendRaw(). More...
 
uint8_t sumBytes (const uint8_t *const start, const uint16_t length, const uint8_t init)
 Sum all the bytes of an array and return the least significant 8-bits of the result. More...
 
uint8_t xorBytes (const uint8_t *const start, const uint16_t length, const uint8_t init)
 Calculate a rolling XOR of all the bytes of an array. More...
 
uint16_t countBits (const uint8_t *const start, const uint16_t length, const bool ones, const uint16_t init)
 Count the number of bits of a certain type in an array. More...
 
uint16_t countBits (const uint64_t data, const uint8_t length, const bool ones, const uint16_t init)
 Count the number of bits of a certain type in an Integer. More...
 
uint64_t invertBits (const uint64_t data, const uint16_t nbits)
 Invert/Flip the bits in an Integer. More...
 
float celsiusToFahrenheit (const float deg)
 Convert degrees Celsius to degrees Fahrenheit. More...
 
float fahrenheitToCelsius (const float deg)
 Convert degrees Fahrenheit to degrees Celsius. More...
 
String irutils::addLabeledString (const String value, const String label, const bool precomma)
 Create a String with a colon separated "label: value" pair suitable for Humans. More...
 
String irutils::addBoolToString (const bool value, const String label, const bool precomma)
 Create a String with a colon separated flag suitable for Humans. e.g. "Power: On". More...
 
String irutils::addIntToString (const uint16_t value, const String label, const bool precomma)
 Create a String with a colon separated labeled Integer suitable for Humans. e.g. "Foo: 23". More...
 
String irutils::modelToStr (const decode_type_t protocol, const int16_t model)
 Generate the model string for a given Protocol/Model pair. More...
 
String irutils::addModelToString (const decode_type_t protocol, const int16_t model, const bool precomma)
 Create a String of human output for a given protocol model number. e.g. "Model: JKE". More...
 
String irutils::addTempToString (const uint16_t degrees, const bool celsius, const bool precomma)
 Create a String of human output for a given temperature. e.g. "Temp: 25C". More...
 
String irutils::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)
 Create a String of human output for the given operating mode. e.g. "Mode: 1 (Cool)". More...
 
String irutils::addDayToString (const uint8_t day_of_week, const int8_t offset, const bool precomma)
 Create a String of the 3-letter day of the week from a numerical day of the week. e.g. "Day: 1 (Mon)". More...
 
String irutils::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)
 Create a String of human output for the given fan speed. e.g. "Fan: 0 (Auto)". More...
 
String irutils::htmlEscape (const String unescaped)
 Escape any special HTML (unsafe) characters in a string. e.g. anti-XSS. More...
 
String irutils::msToString (uint32_t const msecs)
 Convert a nr. of milliSeconds into a Human-readable string. e.g. "1 Day 6 Hours 34 Minutes 17 Seconds". More...
 
String irutils::minsToString (const uint16_t mins)
 Convert a nr. of minutes into a 24h clock format Human-readable string. e.g. "23:59". More...
 
uint8_t irutils::sumNibbles (const uint8_t *const start, const uint16_t length, const uint8_t init)
 Sum all the nibbles together in a series of bytes. More...
 
uint8_t irutils::sumNibbles (const uint64_t data, const uint8_t count, const uint8_t init, const bool nibbleonly)
 Sum all the nibbles together in an integer. More...
 
uint8_t irutils::bcdToUint8 (const uint8_t bcd)
 Convert a byte of Binary Coded Decimal(BCD) into an Integer. More...
 
uint8_t irutils::uint8ToBcd (const uint8_t integer)
 Convert an Integer into a byte of Binary Coded Decimal(BCD). More...
 
bool irutils::getBit (const uint64_t data, const uint8_t position, const uint8_t size)
 Return the value of positionth bit of an Integer. More...
 
bool irutils::getBit (const uint8_t data, const uint8_t position)
 Return the value of positionth bit of an Integer. More...
 
uint64_t irutils::setBit (const uint64_t data, const uint8_t position, const bool on, const uint8_t size)
 Return the value of an Integer with the positionth bit changed. More...
 
uint8_t irutils::setBit (const uint8_t data, const uint8_t position, const bool on)
 Return the value of an Integer with the positionth bit changed. More...
 
void irutils::setBit (uint8_t *const data, const uint8_t position, const bool on)
 Alter the value of an Integer with the positionth bit changed. More...
 
void irutils::setBit (uint32_t *const data, const uint8_t position, const bool on)
 Alter the value of an Integer with the positionth bit changed. More...
 
void irutils::setBit (uint64_t *const data, const uint8_t position, const bool on)
 Alter the value of an Integer with the positionth bit changed. More...
 
void irutils::setBits (uint8_t *const dst, const uint8_t offset, const uint8_t nbits, const uint8_t data)
 Alter an uint8_t value by overwriting an arbitary given number of bits. More...
 
void irutils::setBits (uint32_t *const dst, const uint8_t offset, const uint8_t nbits, const uint32_t data)
 Alter an uint32_t value by overwriting an arbitary given number of bits. More...
 
void irutils::setBits (uint64_t *const dst, const uint8_t offset, const uint8_t nbits, const uint64_t data)
 Alter an uint64_t value by overwriting an arbitary given number of bits. More...
 
+

Function Documentation

+ +

◆ celsiusToFahrenheit()

+ +
+
+ + + + + + + + +
float celsiusToFahrenheit (const float deg)
+
+ +

Convert degrees Celsius to degrees Fahrenheit.

+ +
+
+ +

◆ countBits() [1/2]

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
uint16_t countBits (const uint64_t data,
const uint8_t length,
const bool ones,
const uint16_t init 
)
+
+ +

Count the number of bits of a certain type in an Integer.

+
Parameters
+ + + + + +
[in]dataThe value you want bits counted for. Starting from the LSB.
[in]lengthHow many bits to use in the calculation? Starts at the LSB
[in]onesCount the binary nr of 1 bits. False is count the 0s.
[in]initStarting value of the calculation to use. (Default is 0)
+
+
+
Returns
The nr. of bits found of the given type found in the Integer.
+ +
+
+ +

◆ countBits() [2/2]

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
uint16_t countBits (const uint8_t *const start,
const uint16_t length,
const bool ones,
const uint16_t init 
)
+
+ +

Count the number of bits of a certain type in an array.

+
Parameters
+ + + + + +
[in]startA ptr to the start of the byte array to calculate over.
[in]lengthHow many bytes to use in the calculation.
[in]onesCount the binary nr of 1 bits. False is count the 0s.
[in]initStarting value of the calculation to use. (Default is 0)
+
+
+
Returns
The nr. of bits found of the given type found in the array.
+ +
+
+ +

◆ fahrenheitToCelsius()

+ +
+
+ + + + + + + + +
float fahrenheitToCelsius (const float deg)
+
+ +

Convert degrees Fahrenheit to degrees Celsius.

+ +
+
+ +

◆ getCorrectedRawLength()

+ +
+
+ + + + + + + + +
uint16_t getCorrectedRawLength (const decode_results *const results)
+
+ +

Return the corrected length of a 'raw' format array structure after over-large values are converted into multiple entries.

+
Parameters
+ + +
[in]resultsA ptr to a decode_results structure.
+
+
+
Returns
The corrected length.
+ +
+
+ +

◆ hasACState()

+ +
+
+ + + + + + + + +
bool hasACState (const decode_type_t protocol)
+
+ +

Does the given protocol use a complex state as part of the decode?

+
Parameters
+ + +
[in]protocolThe decode_type_t protocol we are enquiring about.
+
+
+
Returns
True if the protocol uses a state array. False if just an integer.
+ +
+
+ +

◆ invertBits()

+ +
+
+ + + + + + + + + + + + + + + + + + +
uint64_t invertBits (const uint64_t data,
const uint16_t nbits 
)
+
+ +

Invert/Flip the bits in an Integer.

+
Parameters
+ + + +
[in]dataThe Integer that will be inverted.
[in]nbitsHow many bits are to be inverted. Starting from the LSB.
+
+
+
Returns
An Integer with the appropriate bits inverted/flipped.
+ +
+
+ +

◆ resultToHexidecimal()

+ +
+
+ + + + + + + + +
String resultToHexidecimal (const decode_results *const result)
+
+ +

Convert the decode_results structure's value/state to simple hexadecimal.

+
Parameters
+ + +
[in]resultA ptr to a decode_results structure.
+
+
+
Returns
A String containing the output.
+ +
+
+ +

◆ resultToHumanReadableBasic()

+ +
+
+ + + + + + + + +
String resultToHumanReadableBasic (const decode_results *const results)
+
+ +

Dump out the decode_results structure into a human readable format.

+
Parameters
+ + +
[in]resultsA ptr to a decode_results structure.
+
+
+
Returns
A String containing the output.
+ +
+
+ +

◆ resultToRawArray()

+ +
+
+ + + + + + + + +
uint16_t* resultToRawArray (const decode_results *const decode)
+
+ +

Convert a decode_results into an array suitable for sendRaw().

+
Parameters
+ + +
[in]decodeA ptr to a decode_results structure that contains a mesg.
+
+
+
Returns
A PTR to a dynamically allocated uint16_t sendRaw compatible array.
+
Note
The returned array needs to be delete[]'ed/free()'ed (deallocated) after use by caller.
+ +
+
+ +

◆ resultToSourceCode()

+ +
+
+ + + + + + + + +
String resultToSourceCode (const decode_results *const results)
+
+ +

Return a String containing the key values of a decode_results structure in a C/C++ code style format.

+
Parameters
+ + +
[in]resultsA ptr to a decode_results structure.
+
+
+
Returns
A String containing the code-ified result.
+ +
+
+ +

◆ resultToTimingInfo()

+ +
+
+ + + + + + + + +
String resultToTimingInfo (const decode_results *const results)
+
+ +

Dump out the decode_results structure.

+
Parameters
+ + +
[in]resultsA ptr to a decode_results structure.
+
+
+
Returns
A String containing the legacy information format.
+
Deprecated:
This is only for those that want this legacy format.
+ +
+
+ +

◆ reverseBits()

+ +
+
+ + + + + + + + + + + + + + + + + + +
uint64_t reverseBits (uint64_t input,
uint16_t nbits 
)
+
+ +

Reverse the order of the requested least significant nr. of bits.

+
Parameters
+ + + +
[in]inputBit pattern/integer to reverse.
[in]nbitsNr. of bits to reverse. (LSB -> MSB)
+
+
+
Returns
The reversed bit pattern.
+ +
+
+ +

◆ serialPrintUint64()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void serialPrintUint64 (uint64_t input,
uint8_t base 
)
+
+ +

Print a uint64_t/unsigned long long to the Serial port Serial.print() can't handle printing long longs. (uint64_t)

+
Parameters
+ + + +
[in]inputThe value to print
[in]baseThe output base.
+
+
+ +
+
+ +

◆ strToDecodeType()

+ +
+
+ + + + + + + + +
decode_type_t strToDecodeType (const char *const str)
+
+ +

Convert a C-style string to a decode_type_t.

+
Parameters
+ + +
[in]strA C-style string containing a protocol name or number.
+
+
+
Returns
A decode_type_t enum. (decode_type_t::UNKNOWN if no match.)
+ +
+
+ +

◆ sumBytes()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
uint8_t sumBytes (const uint8_t *const start,
const uint16_t length,
const uint8_t init 
)
+
+ +

Sum all the bytes of an array and return the least significant 8-bits of the result.

+
Parameters
+ + + + +
[in]startA ptr to the start of the byte array to calculate over.
[in]lengthHow many bytes to use in the calculation.
[in]initStarting value of the calculation to use. (Default is 0)
+
+
+
Returns
The 8-bit calculated result of all the bytes and init value.
+ +
+
+ +

◆ typeToString()

+ +
+
+ + + + + + + + + + + + + + + + + + +
String typeToString (const decode_type_t protocol,
const bool isRepeat 
)
+
+ +

Convert a protocol type (enum etc) to a human readable string.

+
Parameters
+ + + +
[in]protocolNr. (enum) of the protocol.
[in]isRepeatA flag indicating if it is a repeat message.
+
+
+
Returns
A String containing the protocol name. kUnknownStr if no match.
+ +
+
+ +

◆ uint64ToString()

+ +
+
+ + + + + + + + + + + + + + + + + + +
String uint64ToString (uint64_t input,
uint8_t base 
)
+
+ +

Convert a uint64_t (unsigned long long) to a string. Arduino String/toInt/Serial.print() can't handle printing 64 bit values.

+
Parameters
+ + + +
[in]inputThe value to print
[in]baseThe output base.
+
+
+
Returns
A String representation of the integer.
+
Note
Based on Arduino's Print::printNumber()
+ +
+
+ +

◆ xorBytes()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
uint8_t xorBytes (const uint8_t *const start,
const uint16_t length,
const uint8_t init 
)
+
+ +

Calculate a rolling XOR of all the bytes of an array.

+
Parameters
+ + + + +
[in]startA ptr to the start of the byte array to calculate over.
[in]lengthHow many bytes to use in the calculation.
[in]initStarting value of the calculation to use. (Default is 0)
+
+
+
Returns
The 8-bit calculated result of all the bytes and init value.
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRutils_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRutils_8h.html new file mode 100644 index 000000000..9c9c4cd28 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRutils_8h.html @@ -0,0 +1,942 @@ + + + + + + + +IRremoteESP8266: src/IRutils.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
IRutils.h File Reference
+
+
+ +

Go to the source code of this file.

+ + + + + +

+Namespaces

 irutils
 Namespace for covering common functions & procedures for advancd protocol handlers.
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Functions

uint64_t reverseBits (uint64_t input, uint16_t nbits)
 Reverse the order of the requested least significant nr. of bits. More...
 
String uint64ToString (uint64_t input, uint8_t base=10)
 Convert a uint64_t (unsigned long long) to a string. Arduino String/toInt/Serial.print() can't handle printing 64 bit values. More...
 
String typeToString (const decode_type_t protocol, const bool isRepeat=false)
 Convert a protocol type (enum etc) to a human readable string. More...
 
void serialPrintUint64 (uint64_t input, uint8_t base=10)
 Print a uint64_t/unsigned long long to the Serial port Serial.print() can't handle printing long longs. (uint64_t) More...
 
String resultToSourceCode (const decode_results *const results)
 Return a String containing the key values of a decode_results structure in a C/C++ code style format. More...
 
String resultToTimingInfo (const decode_results *const results)
 Dump out the decode_results structure. More...
 
String resultToHumanReadableBasic (const decode_results *const results)
 Dump out the decode_results structure into a human readable format. More...
 
String resultToHexidecimal (const decode_results *const result)
 Convert the decode_results structure's value/state to simple hexadecimal. More...
 
bool hasACState (const decode_type_t protocol)
 Does the given protocol use a complex state as part of the decode? More...
 
uint16_t getCorrectedRawLength (const decode_results *const results)
 Return the corrected length of a 'raw' format array structure after over-large values are converted into multiple entries. More...
 
uint16_t * resultToRawArray (const decode_results *const decode)
 Convert a decode_results into an array suitable for sendRaw(). More...
 
uint8_t sumBytes (const uint8_t *const start, const uint16_t length, const uint8_t init=0)
 Sum all the bytes of an array and return the least significant 8-bits of the result. More...
 
uint8_t xorBytes (const uint8_t *const start, const uint16_t length, const uint8_t init=0)
 Calculate a rolling XOR of all the bytes of an array. More...
 
uint16_t countBits (const uint8_t *const start, const uint16_t length, const bool ones=true, const uint16_t init=0)
 Count the number of bits of a certain type in an array. More...
 
uint16_t countBits (const uint64_t data, const uint8_t length, const bool ones=true, const uint16_t init=0)
 Count the number of bits of a certain type in an Integer. More...
 
uint64_t invertBits (const uint64_t data, const uint16_t nbits)
 Invert/Flip the bits in an Integer. More...
 
decode_type_t strToDecodeType (const char *str)
 Convert a C-style string to a decode_type_t. More...
 
float celsiusToFahrenheit (const float deg)
 Convert degrees Celsius to degrees Fahrenheit. More...
 
float fahrenheitToCelsius (const float deg)
 Convert degrees Fahrenheit to degrees Celsius. More...
 
String irutils::addBoolToString (const bool value, const String label, const bool precomma)
 Create a String with a colon separated flag suitable for Humans. e.g. "Power: On". More...
 
String irutils::addIntToString (const uint16_t value, const String label, const bool precomma)
 Create a String with a colon separated labeled Integer suitable for Humans. e.g. "Foo: 23". More...
 
String irutils::modelToStr (const decode_type_t protocol, const int16_t model)
 Generate the model string for a given Protocol/Model pair. More...
 
String irutils::addModelToString (const decode_type_t protocol, const int16_t model, const bool precomma)
 Create a String of human output for a given protocol model number. e.g. "Model: JKE". More...
 
String irutils::addLabeledString (const String value, const String label, const bool precomma)
 Create a String with a colon separated "label: value" pair suitable for Humans. More...
 
String irutils::addTempToString (const uint16_t degrees, const bool celsius, const bool precomma)
 Create a String of human output for a given temperature. e.g. "Temp: 25C". More...
 
String irutils::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)
 Create a String of human output for the given operating mode. e.g. "Mode: 1 (Cool)". More...
 
String irutils::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)
 Create a String of human output for the given fan speed. e.g. "Fan: 0 (Auto)". More...
 
String irutils::addDayToString (const uint8_t day_of_week, const int8_t offset, const bool precomma)
 Create a String of the 3-letter day of the week from a numerical day of the week. e.g. "Day: 1 (Mon)". More...
 
String irutils::htmlEscape (const String unescaped)
 Escape any special HTML (unsafe) characters in a string. e.g. anti-XSS. More...
 
String irutils::msToString (uint32_t const msecs)
 Convert a nr. of milliSeconds into a Human-readable string. e.g. "1 Day 6 Hours 34 Minutes 17 Seconds". More...
 
String irutils::minsToString (const uint16_t mins)
 Convert a nr. of minutes into a 24h clock format Human-readable string. e.g. "23:59". More...
 
uint8_t irutils::sumNibbles (const uint8_t *const start, const uint16_t length, const uint8_t init)
 Sum all the nibbles together in a series of bytes. More...
 
uint8_t irutils::sumNibbles (const uint64_t data, const uint8_t count, const uint8_t init, const bool nibbleonly)
 Sum all the nibbles together in an integer. More...
 
uint8_t irutils::bcdToUint8 (const uint8_t bcd)
 Convert a byte of Binary Coded Decimal(BCD) into an Integer. More...
 
uint8_t irutils::uint8ToBcd (const uint8_t integer)
 Convert an Integer into a byte of Binary Coded Decimal(BCD). More...
 
bool irutils::getBit (const uint64_t data, const uint8_t position, const uint8_t size)
 Return the value of positionth bit of an Integer. More...
 
bool irutils::getBit (const uint8_t data, const uint8_t position)
 Return the value of positionth bit of an Integer. More...
 
uint64_t irutils::setBit (const uint64_t data, const uint8_t position, const bool on, const uint8_t size)
 Return the value of an Integer with the positionth bit changed. More...
 
uint8_t irutils::setBit (const uint8_t data, const uint8_t position, const bool on)
 Return the value of an Integer with the positionth bit changed. More...
 
void irutils::setBit (uint8_t *const data, const uint8_t position, const bool on)
 Alter the value of an Integer with the positionth bit changed. More...
 
void irutils::setBit (uint32_t *const data, const uint8_t position, const bool on)
 Alter the value of an Integer with the positionth bit changed. More...
 
void irutils::setBit (uint64_t *const data, const uint8_t position, const bool on)
 Alter the value of an Integer with the positionth bit changed. More...
 
void irutils::setBits (uint8_t *const dst, const uint8_t offset, const uint8_t nbits, const uint8_t data)
 Alter an uint8_t value by overwriting an arbitary given number of bits. More...
 
void irutils::setBits (uint32_t *const dst, const uint8_t offset, const uint8_t nbits, const uint32_t data)
 Alter an uint32_t value by overwriting an arbitary given number of bits. More...
 
void irutils::setBits (uint64_t *const dst, const uint8_t offset, const uint8_t nbits, const uint64_t data)
 Alter an uint64_t value by overwriting an arbitary given number of bits. More...
 
+ + + + + + + + + +

+Variables

const uint8_t kNibbleSize = 4
 
const uint8_t kLowNibble = 0
 
const uint8_t kHighNibble = 4
 
const uint8_t kModeBitsSize = 3
 
+

Function Documentation

+ +

◆ celsiusToFahrenheit()

+ +
+
+ + + + + + + + +
float celsiusToFahrenheit (const float deg)
+
+ +

Convert degrees Celsius to degrees Fahrenheit.

+ +
+
+ +

◆ countBits() [1/2]

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
uint16_t countBits (const uint64_t data,
const uint8_t length,
const bool ones,
const uint16_t init 
)
+
+ +

Count the number of bits of a certain type in an Integer.

+
Parameters
+ + + + + +
[in]dataThe value you want bits counted for. Starting from the LSB.
[in]lengthHow many bits to use in the calculation? Starts at the LSB
[in]onesCount the binary nr of 1 bits. False is count the 0s.
[in]initStarting value of the calculation to use. (Default is 0)
+
+
+
Returns
The nr. of bits found of the given type found in the Integer.
+ +
+
+ +

◆ countBits() [2/2]

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
uint16_t countBits (const uint8_t *const start,
const uint16_t length,
const bool ones,
const uint16_t init 
)
+
+ +

Count the number of bits of a certain type in an array.

+
Parameters
+ + + + + +
[in]startA ptr to the start of the byte array to calculate over.
[in]lengthHow many bytes to use in the calculation.
[in]onesCount the binary nr of 1 bits. False is count the 0s.
[in]initStarting value of the calculation to use. (Default is 0)
+
+
+
Returns
The nr. of bits found of the given type found in the array.
+ +
+
+ +

◆ fahrenheitToCelsius()

+ +
+
+ + + + + + + + +
float fahrenheitToCelsius (const float deg)
+
+ +

Convert degrees Fahrenheit to degrees Celsius.

+ +
+
+ +

◆ getCorrectedRawLength()

+ +
+
+ + + + + + + + +
uint16_t getCorrectedRawLength (const decode_results *const results)
+
+ +

Return the corrected length of a 'raw' format array structure after over-large values are converted into multiple entries.

+
Parameters
+ + +
[in]resultsA ptr to a decode_results structure.
+
+
+
Returns
The corrected length.
+ +
+
+ +

◆ hasACState()

+ +
+
+ + + + + + + + +
bool hasACState (const decode_type_t protocol)
+
+ +

Does the given protocol use a complex state as part of the decode?

+
Parameters
+ + +
[in]protocolThe decode_type_t protocol we are enquiring about.
+
+
+
Returns
True if the protocol uses a state array. False if just an integer.
+ +
+
+ +

◆ invertBits()

+ +
+
+ + + + + + + + + + + + + + + + + + +
uint64_t invertBits (const uint64_t data,
const uint16_t nbits 
)
+
+ +

Invert/Flip the bits in an Integer.

+
Parameters
+ + + +
[in]dataThe Integer that will be inverted.
[in]nbitsHow many bits are to be inverted. Starting from the LSB.
+
+
+
Returns
An Integer with the appropriate bits inverted/flipped.
+ +
+
+ +

◆ resultToHexidecimal()

+ +
+
+ + + + + + + + +
String resultToHexidecimal (const decode_results *const result)
+
+ +

Convert the decode_results structure's value/state to simple hexadecimal.

+
Parameters
+ + +
[in]resultA ptr to a decode_results structure.
+
+
+
Returns
A String containing the output.
+ +
+
+ +

◆ resultToHumanReadableBasic()

+ +
+
+ + + + + + + + +
String resultToHumanReadableBasic (const decode_results *const results)
+
+ +

Dump out the decode_results structure into a human readable format.

+
Parameters
+ + +
[in]resultsA ptr to a decode_results structure.
+
+
+
Returns
A String containing the output.
+ +
+
+ +

◆ resultToRawArray()

+ +
+
+ + + + + + + + +
uint16_t* resultToRawArray (const decode_results *const decode)
+
+ +

Convert a decode_results into an array suitable for sendRaw().

+
Parameters
+ + +
[in]decodeA ptr to a decode_results structure that contains a mesg.
+
+
+
Returns
A PTR to a dynamically allocated uint16_t sendRaw compatible array.
+
Note
The returned array needs to be delete[]'ed/free()'ed (deallocated) after use by caller.
+ +
+
+ +

◆ resultToSourceCode()

+ +
+
+ + + + + + + + +
String resultToSourceCode (const decode_results *const results)
+
+ +

Return a String containing the key values of a decode_results structure in a C/C++ code style format.

+
Parameters
+ + +
[in]resultsA ptr to a decode_results structure.
+
+
+
Returns
A String containing the code-ified result.
+ +
+
+ +

◆ resultToTimingInfo()

+ +
+
+ + + + + + + + +
String resultToTimingInfo (const decode_results *const results)
+
+ +

Dump out the decode_results structure.

+
Parameters
+ + +
[in]resultsA ptr to a decode_results structure.
+
+
+
Returns
A String containing the legacy information format.
+
Deprecated:
This is only for those that want this legacy format.
+ +
+
+ +

◆ reverseBits()

+ +
+
+ + + + + + + + + + + + + + + + + + +
uint64_t reverseBits (uint64_t input,
uint16_t nbits 
)
+
+ +

Reverse the order of the requested least significant nr. of bits.

+
Parameters
+ + + +
[in]inputBit pattern/integer to reverse.
[in]nbitsNr. of bits to reverse. (LSB -> MSB)
+
+
+
Returns
The reversed bit pattern.
+ +
+
+ +

◆ serialPrintUint64()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void serialPrintUint64 (uint64_t input,
uint8_t base 
)
+
+ +

Print a uint64_t/unsigned long long to the Serial port Serial.print() can't handle printing long longs. (uint64_t)

+
Parameters
+ + + +
[in]inputThe value to print
[in]baseThe output base.
+
+
+ +
+
+ +

◆ strToDecodeType()

+ +
+
+ + + + + + + + +
decode_type_t strToDecodeType (const char *const str)
+
+ +

Convert a C-style string to a decode_type_t.

+
Parameters
+ + +
[in]strA C-style string containing a protocol name or number.
+
+
+
Returns
A decode_type_t enum. (decode_type_t::UNKNOWN if no match.)
+ +
+
+ +

◆ sumBytes()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
uint8_t sumBytes (const uint8_t *const start,
const uint16_t length,
const uint8_t init 
)
+
+ +

Sum all the bytes of an array and return the least significant 8-bits of the result.

+
Parameters
+ + + + +
[in]startA ptr to the start of the byte array to calculate over.
[in]lengthHow many bytes to use in the calculation.
[in]initStarting value of the calculation to use. (Default is 0)
+
+
+
Returns
The 8-bit calculated result of all the bytes and init value.
+ +
+
+ +

◆ typeToString()

+ +
+
+ + + + + + + + + + + + + + + + + + +
String typeToString (const decode_type_t protocol,
const bool isRepeat 
)
+
+ +

Convert a protocol type (enum etc) to a human readable string.

+
Parameters
+ + + +
[in]protocolNr. (enum) of the protocol.
[in]isRepeatA flag indicating if it is a repeat message.
+
+
+
Returns
A String containing the protocol name. kUnknownStr if no match.
+ +
+
+ +

◆ uint64ToString()

+ +
+
+ + + + + + + + + + + + + + + + + + +
String uint64ToString (uint64_t input,
uint8_t base 
)
+
+ +

Convert a uint64_t (unsigned long long) to a string. Arduino String/toInt/Serial.print() can't handle printing 64 bit values.

+
Parameters
+ + + +
[in]inputThe value to print
[in]baseThe output base.
+
+
+
Returns
A String representation of the integer.
+
Note
Based on Arduino's Print::printNumber()
+ +
+
+ +

◆ xorBytes()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
uint8_t xorBytes (const uint8_t *const start,
const uint16_t length,
const uint8_t init 
)
+
+ +

Calculate a rolling XOR of all the bytes of an array.

+
Parameters
+ + + + +
[in]startA ptr to the start of the byte array to calculate over.
[in]lengthHow many bytes to use in the calculation.
[in]initStarting value of the calculation to use. (Default is 0)
+
+
+
Returns
The 8-bit calculated result of all the bytes and init value.
+ +
+
+

Variable Documentation

+ +

◆ kHighNibble

+ +
+
+ + + + +
const uint8_t kHighNibble = 4
+
+ +
+
+ +

◆ kLowNibble

+ +
+
+ + + + +
const uint8_t kLowNibble = 0
+
+ +
+
+ +

◆ kModeBitsSize

+ +
+
+ + + + +
const uint8_t kModeBitsSize = 3
+
+ +
+
+ +

◆ kNibbleSize

+ +
+
+ + + + +
const uint8_t kNibbleSize = 4
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRutils_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRutils_8h_source.html new file mode 100644 index 000000000..74305e92d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/IRutils_8h_source.html @@ -0,0 +1,235 @@ + + + + + + + +IRremoteESP8266: src/IRutils.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
IRutils.h
+
+
+Go to the documentation of this file.
1 #ifndef IRUTILS_H_
+
2 #define IRUTILS_H_
+
3 
+
4 // Copyright 2017 David Conran
+
5 
+
6 #ifndef UNIT_TEST
+
7 #include <Arduino.h>
+
8 #endif
+
9 #define __STDC_LIMIT_MACROS
+
10 #include <stdint.h>
+
11 #ifndef ARDUINO
+
12 #include <string>
+
13 #endif
+
14 #include "IRremoteESP8266.h"
+
15 #include "IRrecv.h"
+
16 
+
17 const uint8_t kNibbleSize = 4;
+
18 const uint8_t kLowNibble = 0;
+
19 const uint8_t kHighNibble = 4;
+
20 const uint8_t kModeBitsSize = 3;
+
21 uint64_t reverseBits(uint64_t input, uint16_t nbits);
+
22 String uint64ToString(uint64_t input, uint8_t base = 10);
+
23 String typeToString(const decode_type_t protocol,
+
24  const bool isRepeat = false);
+
25 void serialPrintUint64(uint64_t input, uint8_t base = 10);
+
26 String resultToSourceCode(const decode_results * const results);
+
27 String resultToTimingInfo(const decode_results * const results);
+
28 String resultToHumanReadableBasic(const decode_results * const results);
+
29 String resultToHexidecimal(const decode_results * const result);
+
30 bool hasACState(const decode_type_t protocol);
+
31 uint16_t getCorrectedRawLength(const decode_results * const results);
+
32 uint16_t *resultToRawArray(const decode_results * const decode);
+
33 uint8_t sumBytes(const uint8_t * const start, const uint16_t length,
+
34  const uint8_t init = 0);
+
35 uint8_t xorBytes(const uint8_t * const start, const uint16_t length,
+
36  const uint8_t init = 0);
+
37 uint16_t countBits(const uint8_t * const start, const uint16_t length,
+
38  const bool ones = true, const uint16_t init = 0);
+
39 uint16_t countBits(const uint64_t data, const uint8_t length,
+
40  const bool ones = true, const uint16_t init = 0);
+
41 uint64_t invertBits(const uint64_t data, const uint16_t nbits);
+
42 decode_type_t strToDecodeType(const char *str);
+
43 float celsiusToFahrenheit(const float deg);
+
44 float fahrenheitToCelsius(const float deg);
+
47 namespace irutils {
+
48  String addBoolToString(const bool value, const String label,
+
49  const bool precomma = true);
+
50  String addIntToString(const uint16_t value, const String label,
+
51  const bool precomma = true);
+
52  String modelToStr(const decode_type_t protocol, const int16_t model);
+
53  String addModelToString(const decode_type_t protocol, const int16_t model,
+
54  const bool precomma = true);
+
55  String addLabeledString(const String value, const String label,
+
56  const bool precomma = true);
+
57  String addTempToString(const uint16_t degrees, const bool celsius = true,
+
58  const bool precomma = true);
+
59  String addModeToString(const uint8_t mode, const uint8_t automatic,
+
60  const uint8_t cool, const uint8_t heat,
+
61  const uint8_t dry, const uint8_t fan);
+
62  String addFanToString(const uint8_t speed, const uint8_t high,
+
63  const uint8_t low, const uint8_t automatic,
+
64  const uint8_t quiet, const uint8_t medium);
+
65  String addDayToString(const uint8_t day_of_week, const int8_t offset = 0,
+
66  const bool precomma = true);
+
67  String htmlEscape(const String unescaped);
+
68  String msToString(uint32_t const msecs);
+
69  String minsToString(const uint16_t mins);
+
70  uint8_t sumNibbles(const uint8_t * const start, const uint16_t length,
+
71  const uint8_t init = 0);
+
72  uint8_t sumNibbles(const uint64_t data, const uint8_t count = 16,
+
73  const uint8_t init = 0, const bool nibbleonly = true);
+
74  uint8_t bcdToUint8(const uint8_t bcd);
+
75  uint8_t uint8ToBcd(const uint8_t integer);
+
76  bool getBit(const uint64_t data, const uint8_t position,
+
77  const uint8_t size = 64);
+
78  bool getBit(const uint8_t data, const uint8_t position);
+
79 #define GETBIT8(a, b) (a & ((uint8_t)1 << b))
+
80 #define GETBIT16(a, b) (a & ((uint16_t)1 << b))
+
81 #define GETBIT32(a, b) (a & ((uint32_t)1 << b))
+
82 #define GETBIT64(a, b) (a & ((uint64_t)1 << b))
+
83 #define GETBITS8(data, offset, size) \
+
84  (((data) & (((uint8_t)UINT8_MAX >> (8 - (size))) << (offset))) >> (offset))
+
85 #define GETBITS16(data, offset, size) \
+
86  (((data) & (((uint16_t)UINT16_MAX >> (16 - (size))) << (offset))) >> \
+
87  (offset))
+
88 #define GETBITS32(data, offset, size) \
+
89  (((data) & (((uint32_t)UINT32_MAX >> (32 - (size))) << (offset))) >> \
+
90  (offset))
+
91 #define GETBITS64(data, offset, size) \
+
92  (((data) & (((uint64_t)UINT64_MAX >> (64 - (size))) << (offset))) >> \
+
93  (offset))
+
94  uint64_t setBit(const uint64_t data, const uint8_t position,
+
95  const bool on = true, const uint8_t size = 64);
+
96  uint8_t setBit(const uint8_t data, const uint8_t position,
+
97  const bool on = true);
+
98  void setBit(uint8_t * const data, const uint8_t position,
+
99  const bool on = true);
+
100  void setBit(uint32_t * const data, const uint8_t position,
+
101  const bool on = true);
+
102  void setBit(uint64_t * const data, const uint8_t position,
+
103  const bool on = true);
+
104  void setBits(uint8_t * const dst, const uint8_t offset, const uint8_t nbits,
+
105  const uint8_t data);
+
106  void setBits(uint32_t * const dst, const uint8_t offset, const uint8_t nbits,
+
107  const uint32_t data);
+
108  void setBits(uint64_t * const dst, const uint8_t offset, const uint8_t nbits,
+
109  const uint64_t data);
+
110 } // namespace irutils
+
111 #endif // IRUTILS_H_
+
+
String addTempToString(const uint16_t degrees, const bool celsius, const bool precomma)
Create a String of human output for a given temperature. e.g. "Temp: 25C".
Definition: IRutils.cpp:577
+
decode_type_t
Enumerator for defining and numbering of supported IR protocol.
Definition: IRremoteESP8266.h:714
+
String addDayToString(const uint8_t day_of_week, const int8_t offset, const bool precomma)
Create a String of the 3-letter day of the week from a numerical day of the week. e....
Definition: IRutils.cpp:616
+
uint16_t * resultToRawArray(const decode_results *const decode)
Convert a decode_results into an array suitable for sendRaw().
Definition: IRutils.cpp:351
+
void setBits(uint8_t *const dst, const uint8_t offset, const uint8_t nbits, const uint8_t data)
Alter an uint8_t value by overwriting an arbitary given number of bits.
Definition: IRutils.cpp:873
+
String resultToSourceCode(const decode_results *const results)
Return a String containing the key values of a decode_results structure in a C/C++ code style format.
Definition: IRutils.cpp:193
+
Results returned from the decoder.
Definition: IRrecv.h:92
+
uint16_t getCorrectedRawLength(const decode_results *const results)
Return the corrected length of a 'raw' format array structure after over-large values are converted i...
Definition: IRutils.cpp:179
+
String addModelToString(const decode_type_t protocol, const int16_t model, const bool precomma)
Create a String of human output for a given protocol model number. e.g. "Model: JKE".
Definition: IRutils.cpp:562
+
uint16_t countBits(const uint8_t *const start, const uint16_t length, const bool ones=true, const uint16_t init=0)
Count the number of bits of a certain type in an array.
Definition: IRutils.cpp:402
+
String msToString(uint32_t const msecs)
Convert a nr. of milliSeconds into a Human-readable string. e.g. "1 Day 6 Hours 34 Minutes 17 Seconds...
Definition: IRutils.cpp:692
+
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)
Create a String of human output for the given operating mode. e.g. "Mode: 1 (Cool)".
Definition: IRutils.cpp:593
+
String resultToHumanReadableBasic(const decode_results *const results)
Dump out the decode_results structure into a human readable format.
Definition: IRutils.cpp:324
+
String resultToTimingInfo(const decode_results *const results)
Dump out the decode_results structure.
Definition: IRutils.cpp:274
+
std::string String
Definition: IRremoteESP8266.h:1093
+
const uint8_t kNibbleSize
Definition: IRutils.h:17
+
String modelToStr(const decode_type_t protocol, const int16_t model)
Generate the model string for a given Protocol/Model pair.
Definition: IRutils.cpp:498
+
const uint8_t kLowNibble
Definition: IRutils.h:18
+ +
uint8_t uint8ToBcd(const uint8_t integer)
Convert an Integer into a byte of Binary Coded Decimal(BCD).
Definition: IRutils.cpp:778
+
decode_type_t strToDecodeType(const char *str)
Convert a C-style string to a decode_type_t.
Definition: IRutils.cpp:83
+
const uint8_t kHighNibble
Definition: IRutils.h:19
+
uint8_t sumNibbles(const uint8_t *const start, const uint16_t length, const uint8_t init)
Sum all the nibbles together in a series of bytes.
Definition: IRutils.cpp:743
+
String uint64ToString(uint64_t input, uint8_t base=10)
Convert a uint64_t (unsigned long long) to a string. Arduino String/toInt/Serial.print() can't handle...
Definition: IRutils.cpp:44
+
float celsiusToFahrenheit(const float deg)
Convert degrees Celsius to degrees Fahrenheit.
Definition: IRutils.cpp:450
+
String addIntToString(const uint16_t value, const String label, const bool precomma)
Create a String with a colon separated labeled Integer suitable for Humans. e.g. "Foo: 23".
Definition: IRutils.cpp:489
+
uint8_t xorBytes(const uint8_t *const start, const uint16_t length, const uint8_t init=0)
Calculate a rolling XOR of all the bytes of an array.
Definition: IRutils.cpp:388
+
const uint8_t kModeBitsSize
Definition: IRutils.h:20
+
bool getBit(const uint64_t data, const uint8_t position, const uint8_t size)
Return the value of positionth bit of an Integer.
Definition: IRutils.cpp:788
+
float fahrenheitToCelsius(const float deg)
Convert degrees Fahrenheit to degrees Celsius.
Definition: IRutils.cpp:453
+ +
uint8_t sumBytes(const uint8_t *const start, const uint16_t length, const uint8_t init=0)
Sum all the bytes of an array and return the least significant 8-bits of the result.
Definition: IRutils.cpp:375
+
String typeToString(const decode_type_t protocol, const bool isRepeat=false)
Convert a protocol type (enum etc) to a human readable string.
Definition: IRutils.cpp:105
+
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)
Create a String of human output for the given fan speed. e.g. "Fan: 0 (Auto)".
Definition: IRutils.cpp:642
+
String resultToHexidecimal(const decode_results *const result)
Convert the decode_results structure's value/state to simple hexadecimal.
Definition: IRutils.cpp:304
+
String addBoolToString(const bool value, const String label, const bool precomma)
Create a String with a colon separated flag suitable for Humans. e.g. "Power: On".
Definition: IRutils.cpp:477
+
String minsToString(const uint16_t mins)
Convert a nr. of minutes into a 24h clock format Human-readable string. e.g. "23:59".
Definition: IRutils.cpp:728
+
uint8_t bcdToUint8(const uint8_t bcd)
Convert a byte of Binary Coded Decimal(BCD) into an Integer.
Definition: IRutils.cpp:770
+
Namespace for covering common functions & procedures for advancd protocol handlers.
Definition: IRutils.cpp:455
+
uint64_t reverseBits(uint64_t input, uint16_t nbits)
Reverse the order of the requested least significant nr. of bits.
Definition: IRutils.cpp:24
+
String htmlEscape(const String unescaped)
Escape any special HTML (unsafe) characters in a string. e.g. anti-XSS.
Definition: IRutils.cpp:660
+
bool hasACState(const decode_type_t protocol)
Does the given protocol use a complex state as part of the decode?
Definition: IRutils.cpp:130
+
uint64_t setBit(const uint64_t data, const uint8_t position, const bool on, const uint8_t size)
Return the value of an Integer with the positionth bit changed.
Definition: IRutils.cpp:808
+
void serialPrintUint64(uint64_t input, uint8_t base=10)
Print a uint64_t/unsigned long long to the Serial port Serial.print() can't handle printing long long...
Definition: IRutils.cpp:75
+
String addLabeledString(const String value, const String label, const bool precomma)
Create a String with a colon separated "label: value" pair suitable for Humans.
Definition: IRutils.cpp:462
+
uint64_t invertBits(const uint64_t data, const uint16_t nbits)
Invert/Flip the bits in an Integer.
Definition: IRutils.cpp:439
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/README_8md.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/README_8md.html new file mode 100644 index 000000000..cf3677096 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/README_8md.html @@ -0,0 +1,76 @@ + + + + + + + +IRremoteESP8266: src/locale/README.md File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
src/locale/README.md File Reference
+
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/annotated.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/annotated.html new file mode 100644 index 000000000..b4f7fbce8 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/annotated.html @@ -0,0 +1,134 @@ + + + + + + + +IRremoteESP8266: Class List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+
Class List
+
+
+
Here are the classes, structs, unions and interfaces with brief descriptions:
+
[detail level 12]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 NstdAcEnumerators and Structures for the Common A/C API
 Cstate_tStructure to hold a common A/C state
 Cdecode_resultsResults returned from the decoder
 CIRac
 CIRAmcorAcClass for handling detailed Amcor A/C messages
 CIRArgoACClass for handling detailed Argo A/C messages
 CIRCarrierAc64Class for handling detailed Carrier 64 bit A/C messages
 CIRCoolixACClass for handling detailed Coolix A/C messages
 CIRCoronaAcClass for handling detailed Corona A/C messages
 CIRDaikin128Class for handling detailed Daikin 128-bit A/C messages. Code by crankyoldgit. Analysis by Daniel Vena
 CIRDaikin152Class for handling detailed Daikin 152-bit A/C messages
 CIRDaikin160Class for handling detailed Daikin 160-bit A/C messages
 CIRDaikin176Class for handling detailed Daikin 176-bit A/C messages
 CIRDaikin2Class for handling detailed Daikin 312-bit A/C messages. Code by crankyoldgit, Reverse engineering analysis by sheppy99
 CIRDaikin216Class for handling detailed Daikin 216-bit A/C messages
 CIRDaikin64Class for handling detailed Daikin 64-bit A/C messages
 CIRDaikinESPClass for handling detailed Daikin 280-bit A/C messages
 CIRDelonghiAcClass for handling detailed Delonghi A/C messages
 CIRElectraAcClass for handling detailed Electra A/C messages
 CIRFujitsuACClass for handling detailed Fujitsu A/C messages
 CIRGoodweatherAcClass for handling detailed Goodweather A/C messages
 CIRGreeACClass for handling detailed Gree A/C messages
 CIRHaierACClass for handling detailed Haier A/C messages
 CIRHaierACYRW02Class for handling detailed Haier ACYRW02 A/C messages
 CIRHitachiAcClass for handling detailed Hitachi 224-bit A/C messages
 CIRHitachiAc1Class for handling detailed Hitachi 104-bit A/C messages
 CIRHitachiAc3Class for handling detailed Hitachi 15to27-byte/120to216-bit A/C messages
 CIRHitachiAc344Class for handling detailed Hitachi 344-bit A/C messages
 CIRHitachiAc424Class for handling detailed Hitachi 53-byte/424-bit A/C messages
 CIRKelvinatorACClass for handling detailed Kelvinator A/C messages
 CIRLgAcClass for handling detailed LG A/C messages
 CIRMideaACClass for handling detailed Midea A/C messages
 CIRMitsubishi112
 CIRMitsubishi136Class for handling detailed Mitsubishi 136-bit A/C messages
 CIRMitsubishiACClass for handling detailed Mitsubishi 144-bit A/C messages. Inspired and derived from the work done at: https://github.com/r45635/HVAC-IR-Control
 CIRMitsubishiHeavy152AcClass for handling detailed Mitsubishi Heavy 152-bit A/C messages
 CIRMitsubishiHeavy88AcClass for handling detailed Mitsubishi Heavy 88-bit A/C messages
 CIRNeoclimaAcClass for handling detailed Neoclima A/C messages
 CIRPanasonicAcClass for handling detailed Panasonic A/C messages
 Cirparams_tInformation for the interrupt handler
 CIRrecvClass for receiving IR messages
 CIRSamsungAcClass for handling detailed Samsung A/C messages
 CIRsendClass for sending all basic IR protocols
 CIRSharpAcClass for handling detailed Sharp A/C messages
 CIRTcl112AcClass for handling detailed TCL A/C messages
 CIRTecoAcClass for handling detailed Teco A/C messages
 CIRtimerThis class performs a simple timer in useconds since instantiated
 CIRToshibaACClass for handling detailed Toshiba A/C messages
 CIRTrotecESPClass for handling detailed Trotec A/C messages
 CIRVestelAcClass for handling detailed Vestel A/C messages
 CIRWhirlpoolAcClass for handling detailed Whirlpool A/C messages
 CmagiquestMagiQuest packet is both Wand ID and magnitude of swish and flick
 Cmatch_result_tResults from a data match
 CTimerMsThis class performs a simple timer in milli-seoncds since instantiated
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/bc_s.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/bc_s.png new file mode 100644 index 000000000..224b29aa9 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/bc_s.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/bdwn.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/bdwn.png new file mode 100644 index 000000000..940a0b950 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/bdwn.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRAmcorAc-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRAmcorAc-members.html new file mode 100644 index 000000000..fbda716c3 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRAmcorAc-members.html @@ -0,0 +1,109 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRAmcorAc Member List
+
+
+ +

This is the complete list of members for IRAmcorAc, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRAmcorAcprivate
begin()IRAmcorAc
calcChecksum(const uint8_t state[], const uint16_t length=kAmcorStateLength)IRAmcorAcstatic
calibrate(void)IRAmcorAcinline
checksum(void)IRAmcorAcprivate
convertFan(const stdAc::fanspeed_t speed)IRAmcorAc
convertMode(const stdAc::opmode_t mode)IRAmcorAc
getFan()IRAmcorAc
getMax(void)IRAmcorAc
getMode()IRAmcorAc
getPower()IRAmcorAc
getRaw()IRAmcorAc
getTemp()IRAmcorAc
IRAmcorAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRAmcorAcexplicit
off()IRAmcorAc
on()IRAmcorAc
remote_stateIRAmcorAcprivate
send(const uint16_t repeat=kAmcorDefaultRepeat)IRAmcorAc
setFan(const uint8_t speed)IRAmcorAc
setMax(const bool on)IRAmcorAc
setMode(const uint8_t mode)IRAmcorAc
setPower(const bool state)IRAmcorAc
setRaw(const uint8_t state[])IRAmcorAc
setTemp(const uint8_t temp)IRAmcorAc
stateReset()IRAmcorAc
toCommon(void)IRAmcorAc
toCommonFanSpeed(const uint8_t speed)IRAmcorAcstatic
toCommonMode(const uint8_t mode)IRAmcorAcstatic
toString()IRAmcorAc
validChecksum(const uint8_t state[], const uint16_t length=kAmcorStateLength)IRAmcorAcstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRAmcorAc.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRAmcorAc.html new file mode 100644 index 000000000..8d4caf51c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRAmcorAc.html @@ -0,0 +1,997 @@ + + + + + + + +IRremoteESP8266: IRAmcorAc Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Amcor A/C messages. + More...

+ +

#include <ir_Amcor.h>

+
+Collaboration diagram for IRAmcorAc:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRAmcorAc (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset ()
 Reset the internals of the object to a known good state. More...
 
void send (const uint16_t repeat=kAmcorDefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin ()
 Set up hardware to be able to send a message. More...
 
void setPower (const bool state)
 Set the internal state to have the desired power. More...
 
bool getPower ()
 Get the power setting from the internal state. More...
 
void on ()
 Set the internal state to have the power on. More...
 
void off ()
 Set the internal state to have the power off. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp ()
 Get the current temperature setting. More...
 
void setMax (const bool on)
 Control the current Maximum Cooling or Heating setting. (i.e. Turbo) More...
 
bool getMax (void)
 Is the Maximum Cooling or Heating setting (i.e. Turbo) setting on? More...
 
void setFan (const uint8_t speed)
 Set the speed of the fan. More...
 
uint8_t getFan ()
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the desired operation mode. More...
 
uint8_t getMode ()
 Get the current operation mode setting. More...
 
uint8_t * getRaw ()
 Get the raw state of the object, suitable to be sent with the appropriate IRsend object method. More...
 
void setRaw (const uint8_t state[])
 Set the raw state of the object. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString ()
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + + + + +

+Static Public Member Functions

static uint8_t calcChecksum (const uint8_t state[], const uint16_t length=kAmcorStateLength)
 Calculate the checksum for the supplied state. More...
 
static bool validChecksum (const uint8_t state[], const uint16_t length=kAmcorStateLength)
 Verify the checksum is valid for a given state. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + +

+Private Member Functions

void checksum (void)
 Update the checksum value for the internal state. More...
 
+ + + + + +

+Private Attributes

IRsend _irsend
 
uint8_t remote_state [kAmcorStateLength]
 
+

Detailed Description

+

Class for handling detailed Amcor A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRAmcorAc()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRAmcorAc::IRAmcorAc (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + +
void IRAmcorAc::begin ()
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calcChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
uint8_t IRAmcorAc::calcChecksum (const uint8_t state[],
const uint16_t length = kAmcorStateLength 
)
+
+static
+
+ +

Calculate the checksum for the supplied state.

+
Parameters
+ + + +
[in]stateThe source state to generate the checksum from.
[in]lengthLength of the supplied state to checksum.
+
+
+
Returns
The checksum value.
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRAmcorAc::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
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.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRAmcorAc::checksum (void )
+
+private
+
+ +

Update the checksum value for the internal state.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRAmcorAc::convertFan (const stdAc::fanspeed_t speed)
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRAmcorAc::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + +
uint8_t IRAmcorAc::getFan ()
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getMax()

+ +
+
+ + + + + + + + +
bool IRAmcorAc::getMax (void )
+
+ +

Is the Maximum Cooling or Heating setting (i.e. Turbo) setting on?

+
Returns
The current value.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + +
uint8_t IRAmcorAc::getMode ()
+
+ +

Get the current operation mode setting.

+
Returns
The current operation mode.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + +
bool IRAmcorAc::getPower ()
+
+ +

Get the power setting from the internal state.

+
Returns
A boolean indicating the power setting.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + +
uint8_t * IRAmcorAc::getRaw ()
+
+ +

Get the raw state of the object, suitable to be sent with the appropriate IRsend object method.

+
Returns
A PTR to the internal state.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + +
uint8_t IRAmcorAc::getTemp ()
+
+ +

Get the current temperature setting.

+
Returns
Get current setting for temp. in degrees celsius.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + +
void IRAmcorAc::off ()
+
+ +

Set the internal state to have the power off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + +
void IRAmcorAc::on ()
+
+ +

Set the internal state to have the power on.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRAmcorAc::send (const uint16_t repeat = kAmcorDefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRAmcorAc::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting.
+
+
+ +
+
+ +

◆ setMax()

+ +
+
+ + + + + + + + +
void IRAmcorAc::setMax (const bool on)
+
+ +

Control the current Maximum Cooling or Heating setting. (i.e. Turbo)

+
Note
Only allowed in Cool or Heat mode.
+
Parameters
+ + +
[in]onThe desired setting.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRAmcorAc::setMode (const uint8_t mode)
+
+ +

Set the desired operation mode.

+
Parameters
+ + +
[in]modeThe desired operation mode.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRAmcorAc::setPower (const bool on)
+
+ +

Set the internal state to have the desired power.

+
Parameters
+ + +
[in]onThe desired power state.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRAmcorAc::setRaw (const uint8_t state[])
+
+ +

Set the raw state of the object.

+
Parameters
+ + +
[in]stateThe raw state from the native IR message.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRAmcorAc::setTemp (const uint8_t degrees)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]degreesThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + +
void IRAmcorAc::stateReset ()
+
+ +

Reset the internals of the object to a known good state.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRAmcorAc::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRAmcorAc::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRAmcorAc::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + +
String IRAmcorAc::toString ()
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRAmcorAc::validChecksum (const uint8_t state[],
const uint16_t length = kAmcorStateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe size of the state.
+
+
+
Returns
A boolean indicating if it's checksum is valid.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRAmcorAc::_irsend
+
+private
+
+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRAmcorAc::remote_state[kAmcorStateLength]
+
+private
+
+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRAmcorAc__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRAmcorAc__coll__graph.map new file mode 100644 index 000000000..4cebbf9a2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRAmcorAc__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRAmcorAc__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRAmcorAc__coll__graph.md5 new file mode 100644 index 000000000..7fde870f1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRAmcorAc__coll__graph.md5 @@ -0,0 +1 @@ +163192504ac8319807adb950a6186ac0 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRAmcorAc__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRAmcorAc__coll__graph.png new file mode 100644 index 000000000..484d0b252 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRAmcorAc__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRArgoAC-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRArgoAC-members.html new file mode 100644 index 000000000..7c61d68ec --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRArgoAC-members.html @@ -0,0 +1,122 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRArgoAC Member List
+
+
+ +

This is the complete list of members for IRArgoAC, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRArgoACprivate
argoIRArgoACprivate
begin(void)IRArgoAC
calcChecksum(const uint8_t state[], const uint16_t length=kArgoStateLength)IRArgoACstatic
calibrate(void)IRArgoACinline
checksum(void)IRArgoACprivate
convertFan(const stdAc::fanspeed_t speed)IRArgoACstatic
convertMode(const stdAc::opmode_t mode)IRArgoACstatic
convertSwingV(const stdAc::swingv_t position)IRArgoACstatic
cool_modeIRArgoACprivate
flap_modeIRArgoACprivate
getFan(void)IRArgoAC
getFlap(void)IRArgoAC
getiFeel(void)IRArgoAC
getMax(void)IRArgoAC
getMode(void)IRArgoAC
getNight(void)IRArgoAC
getPower(void)IRArgoAC
getRaw(void)IRArgoAC
getRoomTemp(void)IRArgoAC
getTemp(void)IRArgoAC
heat_modeIRArgoACprivate
IRArgoAC(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRArgoACexplicit
off(void)IRArgoAC
on(void)IRArgoAC
send(const uint16_t repeat=kArgoDefaultRepeat)IRArgoAC
setFan(const uint8_t fan)IRArgoAC
setFlap(const uint8_t flap)IRArgoAC
setiFeel(const bool on)IRArgoAC
setMax(const bool on)IRArgoAC
setMode(const uint8_t mode)IRArgoAC
setNight(const bool on)IRArgoAC
setPower(const bool on)IRArgoAC
setRaw(const uint8_t state[])IRArgoAC
setRoomTemp(const uint8_t degrees)IRArgoAC
setTemp(const uint8_t degrees)IRArgoAC
setTime(void)IRArgoAC
stateReset(void)IRArgoACprivate
toCommon(void)IRArgoAC
toCommonFanSpeed(const uint8_t speed)IRArgoACstatic
toCommonMode(const uint8_t mode)IRArgoACstatic
toString()IRArgoAC
validChecksum(const uint8_t state[], const uint16_t length=kArgoStateLength)IRArgoACstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRArgoAC.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRArgoAC.html new file mode 100644 index 000000000..72244b98b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRArgoAC.html @@ -0,0 +1,1381 @@ + + + + + + + +IRremoteESP8266: IRArgoAC Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Argo A/C messages. + More...

+ +

#include <ir_Argo.h>

+
+Collaboration diagram for IRArgoAC:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRArgoAC (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void send (const uint16_t repeat=kArgoDefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Set the internal state to have the power on. More...
 
void off (void)
 Set the internal state to have the power off. More...
 
void setPower (const bool on)
 Set the internal state to have the desired power. More...
 
bool getPower (void)
 Get the power setting from the internal state. More...
 
void setTemp (const uint8_t degrees)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t fan)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setFlap (const uint8_t flap)
 Set the flap position. i.e. Swing. More...
 
uint8_t getFlap (void)
 Get the flap position. i.e. Swing. More...
 
void setMode (const uint8_t mode)
 Set the desired operation mode. More...
 
uint8_t getMode (void)
 Get the current operation mode setting. More...
 
void setMax (const bool on)
 Control the current Max setting. (i.e. Turbo) More...
 
bool getMax (void)
 Is the Max (i.e. Turbo) setting on? More...
 
void setNight (const bool on)
 Turn on/off the Night mode. i.e. Sleep. More...
 
bool getNight (void)
 Get the status of Night mode. i.e. Sleep. More...
 
void setiFeel (const bool on)
 Turn on/off the iFeel mode. More...
 
bool getiFeel (void)
 Get the status of iFeel mode. More...
 
void setTime (void)
 Set the time for the A/C. More...
 
void setRoomTemp (const uint8_t degrees)
 Set the value for the current room temperature. More...
 
uint8_t getRoomTemp (void)
 Get the currently stored value for the room temperature setting. More...
 
uint8_t * getRaw (void)
 Get the raw state of the object, suitable to be sent with the appropriate IRsend object method. More...
 
void setRaw (const uint8_t state[])
 Set the raw state of the object. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString ()
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + + + + + + + + + + + + + +

+Static Public Member Functions

static uint8_t calcChecksum (const uint8_t state[], const uint16_t length=kArgoStateLength)
 Verify the checksum is valid for a given state. More...
 
static bool validChecksum (const uint8_t state[], const uint16_t length=kArgoStateLength)
 Verify the checksum is valid for a given state. More...
 
static uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
static uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
static uint8_t convertSwingV (const stdAc::swingv_t position)
 Convert a stdAc::swingv_t enum into it's native setting. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + + + + +

+Private Member Functions

void stateReset (void)
 Reset the internals of the object to a known good state. More...
 
void checksum (void)
 Update the checksum for the internal state. More...
 
+ + + + + + + + + + + + +

+Private Attributes

IRsend _irsend
 instance of the IR send class More...
 
uint8_t argo [kArgoStateLength]
 
uint8_t flap_mode
 
uint8_t heat_mode
 
uint8_t cool_mode
 
+

Detailed Description

+

Class for handling detailed Argo A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRArgoAC()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRArgoAC::IRArgoAC (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRArgoAC::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calcChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
uint8_t IRArgoAC::calcChecksum (const uint8_t state[],
const uint16_t length = kArgoStateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe size of the state.
+
+
+
Returns
A boolean indicating if it's checksum is valid.
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRArgoAC::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
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.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRArgoAC::checksum (void )
+
+private
+
+ +

Update the checksum for the internal state.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRArgoAC::convertFan (const stdAc::fanspeed_t speed)
+
+static
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRArgoAC::convertMode (const stdAc::opmode_t mode)
+
+static
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertSwingV()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRArgoAC::convertSwingV (const stdAc::swingv_t position)
+
+static
+
+ +

Convert a stdAc::swingv_t enum into it's native setting.

+
Parameters
+ + +
[in]positionThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRArgoAC::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getFlap()

+ +
+
+ + + + + + + + +
uint8_t IRArgoAC::getFlap (void )
+
+ +

Get the flap position. i.e. Swing.

+
Warning
Not yet working!
+
Returns
The current flap setting.
+ +
+
+ +

◆ getiFeel()

+ +
+
+ + + + + + + + +
bool IRArgoAC::getiFeel (void )
+
+ +

Get the status of iFeel mode.

+
Returns
true if on, false if off.
+ +
+
+ +

◆ getMax()

+ +
+
+ + + + + + + + +
bool IRArgoAC::getMax (void )
+
+ +

Is the Max (i.e. Turbo) setting on?

+
Returns
The current value.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRArgoAC::getMode (void )
+
+ +

Get the current operation mode setting.

+
Returns
The current operation mode.
+ +
+
+ +

◆ getNight()

+ +
+
+ + + + + + + + +
bool IRArgoAC::getNight (void )
+
+ +

Get the status of Night mode. i.e. Sleep.

+
Returns
true if on, false if off.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRArgoAC::getPower (void )
+
+ +

Get the power setting from the internal state.

+
Returns
A boolean indicating the power setting.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRArgoAC::getRaw (void )
+
+ +

Get the raw state of the object, suitable to be sent with the appropriate IRsend object method.

+
Returns
A PTR to the internal state.
+ +
+
+ +

◆ getRoomTemp()

+ +
+
+ + + + + + + + +
uint8_t IRArgoAC::getRoomTemp (void )
+
+ +

Get the currently stored value for the room temperature setting.

+
Returns
The current setting for the room temp. in degrees celsius.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRArgoAC::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRArgoAC::off (void )
+
+ +

Set the internal state to have the power off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRArgoAC::on (void )
+
+ +

Set the internal state to have the power on.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRArgoAC::send (const uint16_t repeat = kArgoDefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRArgoAC::setFan (const uint8_t fan)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]fanThe desired setting.
+
+
+ +
+
+ +

◆ setFlap()

+ +
+
+ + + + + + + + +
void IRArgoAC::setFlap (const uint8_t flap)
+
+ +

Set the flap position. i.e. Swing.

+
Warning
Not yet working!
+
Parameters
+ + +
[in]flapThe desired setting.
+
+
+ +
+
+ +

◆ setiFeel()

+ +
+
+ + + + + + + + +
void IRArgoAC::setiFeel (const bool on)
+
+ +

Turn on/off the iFeel mode.

+
Parameters
+ + +
[in]onThe desired setting.
+
+
+ +
+
+ +

◆ setMax()

+ +
+
+ + + + + + + + +
void IRArgoAC::setMax (const bool on)
+
+ +

Control the current Max setting. (i.e. Turbo)

+
Parameters
+ + +
[in]onThe desired setting.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRArgoAC::setMode (const uint8_t mode)
+
+ +

Set the desired operation mode.

+
Parameters
+ + +
[in]modeThe desired operation mode.
+
+
+ +
+
+ +

◆ setNight()

+ +
+
+ + + + + + + + +
void IRArgoAC::setNight (const bool on)
+
+ +

Turn on/off the Night mode. i.e. Sleep.

+
Parameters
+ + +
[in]onThe desired setting.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRArgoAC::setPower (const bool on)
+
+ +

Set the internal state to have the desired power.

+
Parameters
+ + +
[in]onThe desired power state.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRArgoAC::setRaw (const uint8_t state[])
+
+ +

Set the raw state of the object.

+
Parameters
+ + +
[in]stateThe raw state from the native IR message.
+
+
+ +
+
+ +

◆ setRoomTemp()

+ +
+
+ + + + + + + + +
void IRArgoAC::setRoomTemp (const uint8_t degrees)
+
+ +

Set the value for the current room temperature.

+
Parameters
+ + +
[in]degreesThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRArgoAC::setTemp (const uint8_t degrees)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]degreesThe temperature in degrees celsius.
+
+
+
Note
Sending 0 equals +4
+ +
+
+ +

◆ setTime()

+ +
+
+ + + + + + + + +
void IRArgoAC::setTime (void )
+
+ +

Set the time for the A/C.

+
Warning
Not yet working!
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRArgoAC::stateReset (void )
+
+private
+
+ +

Reset the internals of the object to a known good state.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRArgoAC::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRArgoAC::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRArgoAC::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + +
String IRArgoAC::toString ()
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRArgoAC::validChecksum (const uint8_t state[],
const uint16_t length = kArgoStateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe size of the state.
+
+
+
Returns
A boolean indicating if it's checksum is valid.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRArgoAC::_irsend
+
+private
+
+ +

instance of the IR send class

+ +
+
+ +

◆ argo

+ +
+
+ + + + + +
+ + + + +
uint8_t IRArgoAC::argo[kArgoStateLength]
+
+private
+
+ +
+
+ +

◆ cool_mode

+ +
+
+ + + + + +
+ + + + +
uint8_t IRArgoAC::cool_mode
+
+private
+
+ +
+
+ +

◆ flap_mode

+ +
+
+ + + + + +
+ + + + +
uint8_t IRArgoAC::flap_mode
+
+private
+
+ +
+
+ +

◆ heat_mode

+ +
+
+ + + + + +
+ + + + +
uint8_t IRArgoAC::heat_mode
+
+private
+
+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRArgoAC__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRArgoAC__coll__graph.map new file mode 100644 index 000000000..d2a486ba8 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRArgoAC__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRArgoAC__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRArgoAC__coll__graph.md5 new file mode 100644 index 000000000..e84f3b330 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRArgoAC__coll__graph.md5 @@ -0,0 +1 @@ +7d040225d2db5b4715532b7d4ba5268b \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRArgoAC__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRArgoAC__coll__graph.png new file mode 100644 index 000000000..a7838e03d Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRArgoAC__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64-members.html new file mode 100644 index 000000000..a681c9218 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64-members.html @@ -0,0 +1,117 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRCarrierAc64 Member List
+
+
+ +

This is the complete list of members for IRCarrierAc64, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_cancelOffTimer(void)IRCarrierAc64private
_cancelOnTimer(void)IRCarrierAc64private
_irsendIRCarrierAc64private
begin()IRCarrierAc64
calcChecksum(const uint64_t state)IRCarrierAc64static
calibrate(void)IRCarrierAc64inline
checksum(void)IRCarrierAc64private
convertFan(const stdAc::fanspeed_t speed)IRCarrierAc64
convertMode(const stdAc::opmode_t mode)IRCarrierAc64
getFan()IRCarrierAc64
getMode()IRCarrierAc64
getOffTimer(void)IRCarrierAc64
getOnTimer(void)IRCarrierAc64
getPower()IRCarrierAc64
getRaw()IRCarrierAc64
getSleep(void)IRCarrierAc64
getSwingV(void)IRCarrierAc64
getTemp()IRCarrierAc64
IRCarrierAc64(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRCarrierAc64explicit
off()IRCarrierAc64
on()IRCarrierAc64
remote_stateIRCarrierAc64private
send(const uint16_t repeat=kCarrierAc64MinRepeat)IRCarrierAc64
setFan(const uint8_t speed)IRCarrierAc64
setMode(const uint8_t mode)IRCarrierAc64
setOffTimer(const uint16_t nr_of_mins)IRCarrierAc64
setOnTimer(const uint16_t nr_of_mins)IRCarrierAc64
setPower(const bool on)IRCarrierAc64
setRaw(const uint64_t state)IRCarrierAc64
setSleep(const bool on)IRCarrierAc64
setSwingV(const bool on)IRCarrierAc64
setTemp(const uint8_t temp)IRCarrierAc64
stateReset()IRCarrierAc64
toCommon(void)IRCarrierAc64
toCommonFanSpeed(const uint8_t speed)IRCarrierAc64static
toCommonMode(const uint8_t mode)IRCarrierAc64static
toString()IRCarrierAc64
validChecksum(const uint64_t state)IRCarrierAc64static
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64.html new file mode 100644 index 000000000..111037a52 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64.html @@ -0,0 +1,1206 @@ + + + + + + + +IRremoteESP8266: IRCarrierAc64 Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Carrier 64 bit A/C messages. + More...

+ +

#include <ir_Carrier.h>

+
+Collaboration diagram for IRCarrierAc64:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRCarrierAc64 (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset ()
 Reset the internal state to a fixed known good state. More...
 
void send (const uint16_t repeat=kCarrierAc64MinRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin ()
 Set up hardware to be able to send a message. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower ()
 Get the value of the current power setting. More...
 
void on ()
 Change the power setting to On. More...
 
void off ()
 Change the power setting to Off. More...
 
void setTemp (const uint8_t temp)
 Set the temp in deg C. More...
 
uint8_t getTemp ()
 Get the current temperature from the internal state. More...
 
void setSwingV (const bool on)
 Set the Vertical Swing mode of the A/C. More...
 
bool getSwingV (void)
 Get the Vertical Swing mode of the A/C. More...
 
void setSleep (const bool on)
 Set the Sleep mode of the A/C. More...
 
bool getSleep (void)
 Get the Sleep mode of the A/C. More...
 
void setFan (const uint8_t speed)
 Set the speed of the fan. More...
 
uint8_t getFan ()
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode ()
 Get the operating mode setting of the A/C. More...
 
void setOnTimer (const uint16_t nr_of_mins)
 Set the On Timer time. More...
 
uint16_t getOnTimer (void)
 Get the current On Timer time. More...
 
void setOffTimer (const uint16_t nr_of_mins)
 Set the Off Timer time. More...
 
uint16_t getOffTimer (void)
 Get the current Off Timer time. More...
 
uint64_t getRaw ()
 Get a copy of the internal state as a valid code for this protocol. More...
 
void setRaw (const uint64_t state)
 Set the internal state from a valid code for this protocol. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a standard A/C mode into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
stdAc::state_t toCommon (void)
 Convert the A/C state to it's common stdAc::state_t equivalent. More...
 
String toString ()
 Convert the internal state into a human readable string. More...
 
+ + + + + + + + + + + + + +

+Static Public Member Functions

static uint8_t calcChecksum (const uint64_t state)
 Calculate the checksum for a given state. More...
 
static bool validChecksum (const uint64_t state)
 Verify the checksum is valid for a given state. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode to it's common stdAc::opmode_t equivalent. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + + + + + + + +

+Private Member Functions

void checksum (void)
 Calculate and set the checksum values for the internal state. More...
 
void _cancelOnTimer (void)
 Clear the On Timer enable bit. More...
 
void _cancelOffTimer (void)
 Clear the Off Timer enable bit. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint64_t remote_state
 The state of the IR remote. More...
 
+

Detailed Description

+

Class for handling detailed Carrier 64 bit A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRCarrierAc64()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRCarrierAc64::IRCarrierAc64 (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ _cancelOffTimer()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRCarrierAc64::_cancelOffTimer (void )
+
+private
+
+ +

Clear the Off Timer enable bit.

+ +
+
+ +

◆ _cancelOnTimer()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRCarrierAc64::_cancelOnTimer (void )
+
+private
+
+ +

Clear the On Timer enable bit.

+ +
+
+ +

◆ begin()

+ +
+
+ + + + + + + +
void IRCarrierAc64::begin ()
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calcChecksum()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRCarrierAc64::calcChecksum (const uint64_t state)
+
+static
+
+ +

Calculate the checksum for a given state.

+
Parameters
+ + +
[in]stateThe value to calc the checksum of.
+
+
+
Returns
The 4-bit checksum stored in a uint_8.
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRCarrierAc64::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
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.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRCarrierAc64::checksum (void )
+
+private
+
+ +

Calculate and set the checksum values for the internal state.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRCarrierAc64::convertFan (const stdAc::fanspeed_t speed)
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRCarrierAc64::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a standard A/C mode into its native mode.

+
Parameters
+ + +
[in]modeA stdAc::opmode_t to be converted to it's native equivalent.
+
+
+
Returns
The corresponding native mode.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + +
uint8_t IRCarrierAc64::getFan ()
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + +
uint8_t IRCarrierAc64::getMode ()
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getOffTimer()

+ +
+
+ + + + + + + + +
uint16_t IRCarrierAc64::getOffTimer (void )
+
+ +

Get the current Off Timer time.

+
Returns
The number of minutes it is set for. 0 means it's off.
+
Note
The A/C protocol only supports one hour increments.
+ +
+
+ +

◆ getOnTimer()

+ +
+
+ + + + + + + + +
uint16_t IRCarrierAc64::getOnTimer (void )
+
+ +

Get the current On Timer time.

+
Returns
The number of minutes it is set for. 0 means it's off.
+
Note
The A/C protocol only supports one hour increments.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + +
bool IRCarrierAc64::getPower ()
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + +
uint64_t IRCarrierAc64::getRaw ()
+
+ +

Get a copy of the internal state as a valid code for this protocol.

+
Returns
A valid code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSleep()

+ +
+
+ + + + + + + + +
bool IRCarrierAc64::getSleep (void )
+
+ +

Get the Sleep mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwingV()

+ +
+
+ + + + + + + + +
bool IRCarrierAc64::getSwingV (void )
+
+ +

Get the Vertical Swing mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + +
uint8_t IRCarrierAc64::getTemp ()
+
+ +

Get the current temperature from the internal state.

+
Returns
The current temperature in Celsius.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + +
void IRCarrierAc64::off ()
+
+ +

Change the power setting to Off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + +
void IRCarrierAc64::on ()
+
+ +

Change the power setting to On.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRCarrierAc64::send (const uint16_t repeat = kCarrierAc64MinRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRCarrierAc64::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRCarrierAc64::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setOffTimer()

+ +
+
+ + + + + + + + +
void IRCarrierAc64::setOffTimer (const uint16_t nr_of_mins)
+
+ +

Set the Off Timer time.

+
Parameters
+ + +
[in]nr_of_minsNumber of minutes to set the timer to. (< 60 is disable).
+
+
+
Note
The A/C protocol only supports one hour increments.
+ +
+
+ +

◆ setOnTimer()

+ +
+
+ + + + + + + + +
void IRCarrierAc64::setOnTimer (const uint16_t nr_of_mins)
+
+ +

Set the On Timer time.

+
Parameters
+ + +
[in]nr_of_minsNumber of minutes to set the timer to. (< 60 is disable).
+
+
+
Note
The A/C protocol only supports one hour increments.
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRCarrierAc64::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRCarrierAc64::setRaw (const uint64_t state)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]stateA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSleep()

+ +
+
+ + + + + + + + +
void IRCarrierAc64::setSleep (const bool on)
+
+ +

Set the Sleep mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwingV()

+ +
+
+ + + + + + + + +
void IRCarrierAc64::setSwingV (const bool on)
+
+ +

Set the Vertical Swing mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRCarrierAc64::setTemp (const uint8_t temp)
+
+ +

Set the temp in deg C.

+
Parameters
+ + +
[in]tempThe desired temperature in Celsius.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + +
void IRCarrierAc64::stateReset ()
+
+ +

Reset the internal state to a fixed known good state.

+
Note
The state is powered off.
+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRCarrierAc64::toCommon (void )
+
+ +

Convert the A/C state to it's common stdAc::state_t equivalent.

+
Returns
A stdAc::state_t state.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRCarrierAc64::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRCarrierAc64::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode to it's common stdAc::opmode_t equivalent.

+
Parameters
+ + +
[in]modeA native operation mode to be converted.
+
+
+
Returns
The corresponding common stdAc::opmode_t mode.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + +
String IRCarrierAc64::toString ()
+
+ +

Convert the internal state into a human readable string.

+
Returns
The current internal state expressed as a human readable String.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + +
bool IRCarrierAc64::validChecksum (const uint64_t state)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + +
[in]stateThe array to verify the checksum of.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRCarrierAc64::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint64_t IRCarrierAc64::remote_state
+
+private
+
+ +

The state of the IR remote.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64__coll__graph.map new file mode 100644 index 000000000..d0c818960 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64__coll__graph.md5 new file mode 100644 index 000000000..fd7409742 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64__coll__graph.md5 @@ -0,0 +1 @@ +c88965083519dee20186a15bc2f69a8c \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64__coll__graph.png new file mode 100644 index 000000000..72adeb220 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCarrierAc64__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC-members.html new file mode 100644 index 000000000..88e247857 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC-members.html @@ -0,0 +1,137 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRCoolixAC Member List
+
+
+ +

This is the complete list of members for IRCoolixAC, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRCoolixACprivate
begin()IRCoolixAC
calibrate(void)IRCoolixACinline
cleanFlagIRCoolixACprivate
clearSensorTemp()IRCoolixAC
convertFan(const stdAc::fanspeed_t speed)IRCoolixAC
convertMode(const stdAc::opmode_t mode)IRCoolixAC
getClean()IRCoolixAC
getFan()IRCoolixAC
getLed()IRCoolixAC
getMode()IRCoolixAC
getNormalState(void)IRCoolixACprivate
getPower()IRCoolixAC
getRaw()IRCoolixAC
getSensorTemp()IRCoolixAC
getSleep()IRCoolixAC
getSwing()IRCoolixAC
getTemp()IRCoolixAC
getTempRaw()IRCoolixACprivate
getTurbo()IRCoolixAC
getZoneFollow()IRCoolixAC
handleSpecialState(const uint32_t data)IRCoolixACprivate
IRCoolixAC(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRCoolixACexplicit
isSpecialState(void)IRCoolixACprivate
ledFlagIRCoolixACprivate
off()IRCoolixAC
on()IRCoolixAC
powerFlagIRCoolixACprivate
recoverSavedState(void)IRCoolixACprivate
remote_stateIRCoolixACprivate
saved_stateIRCoolixACprivate
send(const uint16_t repeat=kCoolixDefaultRepeat)IRCoolixAC
setClean()IRCoolixAC
setFan(const uint8_t speed, const bool modecheck=true)IRCoolixAC
setLed()IRCoolixAC
setMode(const uint8_t mode)IRCoolixAC
setPower(const bool state)IRCoolixAC
setRaw(const uint32_t new_code)IRCoolixAC
setSensorTemp(const uint8_t desired)IRCoolixAC
setSensorTempRaw(const uint8_t code)IRCoolixACprivate
setSleep()IRCoolixAC
setSwing()IRCoolixAC
setTemp(const uint8_t temp)IRCoolixAC
setTempRaw(const uint8_t code)IRCoolixACprivate
setTurbo()IRCoolixAC
setZoneFollow(const bool on)IRCoolixACprivate
sleepFlagIRCoolixACprivate
stateReset()IRCoolixAC
swingFlagIRCoolixACprivate
swingHFlagIRCoolixACprivate
swingVFlagIRCoolixACprivate
toCommon(const stdAc::state_t *prev=NULL)IRCoolixAC
toCommonFanSpeed(const uint8_t speed)IRCoolixACstatic
toCommonMode(const uint8_t mode)IRCoolixACstatic
toString()IRCoolixAC
turboFlagIRCoolixACprivate
updateSavedState(void)IRCoolixACprivate
zoneFollowFlagIRCoolixACprivate
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC.html new file mode 100644 index 000000000..75343d576 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC.html @@ -0,0 +1,1710 @@ + + + + + + + +IRremoteESP8266: IRCoolixAC Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Coolix A/C messages. + More...

+ +

#include <ir_Coolix.h>

+
+Collaboration diagram for IRCoolixAC:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRCoolixAC (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset ()
 Reset the internal state to a fixed known good state. More...
 
void send (const uint16_t repeat=kCoolixDefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin ()
 Set up hardware to be able to send a message. More...
 
void on ()
 Change the power setting to On. More...
 
void off ()
 Change the power setting to Off. More...
 
void setPower (const bool state)
 Change the power setting. More...
 
bool getPower ()
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp ()
 Get the current temperature setting. More...
 
void setSensorTemp (const uint8_t desired)
 Set the sensor temperature. More...
 
uint8_t getSensorTemp ()
 Get the sensor temperature setting. More...
 
void clearSensorTemp ()
 Clear the Sensor Temperature setting.. More...
 
void setFan (const uint8_t speed, const bool modecheck=true)
 Set the speed of the fan. More...
 
uint8_t getFan ()
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode ()
 Get the operating mode setting of the A/C. More...
 
void setSwing ()
 Toggle the Swing mode of the A/C. More...
 
bool getSwing ()
 Get the Swing setting of the A/C. More...
 
void setSleep ()
 Toggle the Sleep mode of the A/C. More...
 
bool getSleep ()
 Get the Sleep setting of the A/C. More...
 
void setTurbo ()
 Toggle the Turbo mode of the A/C. More...
 
bool getTurbo ()
 Get the Turbo setting of the A/C. More...
 
void setLed ()
 Toggle the Led (light) mode of the A/C. More...
 
bool getLed ()
 Get the Led (light) setting of the A/C. More...
 
void setClean ()
 Toggle the Clean mode of the A/C. More...
 
bool getClean ()
 Get the Clean setting of the A/C. More...
 
bool getZoneFollow ()
 Get the Zone Follow setting of the A/C. More...
 
uint32_t getRaw ()
 Get a copy of the internal state as a valid code for this protocol. More...
 
void setRaw (const uint32_t new_code)
 Set the internal state from a valid code for this protocol. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a standard A/C mode into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
stdAc::state_t toCommon (const stdAc::state_t *prev=NULL)
 Convert the A/C state to it's common stdAc::state_t equivalent. More...
 
String toString ()
 Convert the internal state into a human readable string. More...
 
+ + + + + + + +

+Static Public Member Functions

static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode to it's common stdAc::opmode_t equivalent. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Private Member Functions

void setTempRaw (const uint8_t code)
 Set the raw (native) temperature value. More...
 
uint8_t getTempRaw ()
 Get the raw (native) temperature value. More...
 
void setSensorTempRaw (const uint8_t code)
 Set the raw (native) sensor temperature value. More...
 
void setZoneFollow (const bool on)
 Change the Zone Follow setting. More...
 
bool isSpecialState (void)
 Is the current state is a special state? More...
 
bool handleSpecialState (const uint32_t data)
 Adjust any internal settings based on the type of special state we are supplied. Does nothing if it isn't a special state. More...
 
void updateSavedState (void)
 Backup the current internal state as long as it isn't a special state. More...
 
void recoverSavedState (void)
 Restore the current internal state from backup as long as it isn't a special state. More...
 
uint32_t getNormalState (void)
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
bool powerFlag
 
bool turboFlag
 
bool ledFlag
 
bool cleanFlag
 
bool sleepFlag
 
bool zoneFollowFlag
 
bool swingFlag
 
bool swingHFlag
 
bool swingVFlag
 
uint32_t remote_state
 The state of the IR remote in IR code form. More...
 
uint32_t saved_state
 Copy of the state if we required a special mode. More...
 
+

Detailed Description

+

Class for handling detailed Coolix A/C messages.

+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/484
+

Constructor & Destructor Documentation

+ +

◆ IRCoolixAC()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRCoolixAC::IRCoolixAC (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + +
void IRCoolixAC::begin ()
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRCoolixAC::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
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.
+ +
+
+ +

◆ clearSensorTemp()

+ +
+
+ + + + + + + +
void IRCoolixAC::clearSensorTemp ()
+
+ +

Clear the Sensor Temperature setting..

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRCoolixAC::convertFan (const stdAc::fanspeed_t speed)
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRCoolixAC::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a standard A/C mode into its native mode.

+
Parameters
+ + +
[in]modeA stdAc::opmode_t to be converted to it's native equivalent.
+
+
+
Returns
The corresponding native mode.
+ +
+
+ +

◆ getClean()

+ +
+
+ + + + + + + +
bool IRCoolixAC::getClean ()
+
+ +

Get the Clean setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + +
uint8_t IRCoolixAC::getFan ()
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getLed()

+ +
+
+ + + + + + + +
bool IRCoolixAC::getLed ()
+
+ +

Get the Led (light) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + +
uint8_t IRCoolixAC::getMode ()
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getNormalState()

+ +
+
+ + + + + +
+ + + + + + + + +
uint32_t IRCoolixAC::getNormalState (void )
+
+private
+
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + +
bool IRCoolixAC::getPower ()
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + +
uint32_t IRCoolixAC::getRaw ()
+
+ +

Get a copy of the internal state as a valid code for this protocol.

+
Returns
A valid code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSensorTemp()

+ +
+
+ + + + + + + +
uint8_t IRCoolixAC::getSensorTemp ()
+
+ +

Get the sensor temperature setting.

+
Returns
The current setting for sensor temp. in degrees celsius.
+ +
+
+ +

◆ getSleep()

+ +
+
+ + + + + + + +
bool IRCoolixAC::getSleep ()
+
+ +

Get the Sleep setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwing()

+ +
+
+ + + + + + + +
bool IRCoolixAC::getSwing ()
+
+ +

Get the Swing setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + +
uint8_t IRCoolixAC::getTemp ()
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ getTempRaw()

+ +
+
+ + + + + +
+ + + + + + + +
uint8_t IRCoolixAC::getTempRaw ()
+
+private
+
+ +

Get the raw (native) temperature value.

+
Returns
The native temperature value.
+ +
+
+ +

◆ getTurbo()

+ +
+
+ + + + + + + +
bool IRCoolixAC::getTurbo ()
+
+ +

Get the Turbo setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getZoneFollow()

+ +
+
+ + + + + + + +
bool IRCoolixAC::getZoneFollow ()
+
+ +

Get the Zone Follow setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ handleSpecialState()

+ +
+
+ + + + + +
+ + + + + + + + +
bool IRCoolixAC::handleSpecialState (const uint32_t data)
+
+private
+
+ +

Adjust any internal settings based on the type of special state we are supplied. Does nothing if it isn't a special state.

+
Parameters
+ + +
[in]dataThe state we need to act upon.
+
+
+
Note
Special state means commands that are not affecting Temperature/Mode/Fan
+
Returns
true, if it is a special state. false if it isn't.
+ +
+
+ +

◆ isSpecialState()

+ +
+
+ + + + + +
+ + + + + + + + +
bool IRCoolixAC::isSpecialState (void )
+
+private
+
+ +

Is the current state is a special state?

+
Returns
true, if it is. false if it isn't.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + +
void IRCoolixAC::off ()
+
+ +

Change the power setting to Off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + +
void IRCoolixAC::on ()
+
+ +

Change the power setting to On.

+ +
+
+ +

◆ recoverSavedState()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRCoolixAC::recoverSavedState (void )
+
+private
+
+ +

Restore the current internal state from backup as long as it isn't a special state.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRCoolixAC::send (const uint16_t repeat = kCoolixDefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setClean()

+ +
+
+ + + + + + + +
void IRCoolixAC::setClean ()
+
+ +

Toggle the Clean mode of the A/C.

+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRCoolixAC::setFan (const uint8_t speed,
const bool modecheck = true 
)
+
+ +

Set the speed of the fan.

+
Parameters
+ + + +
[in]speedThe desired setting.
[in]modecheckDo we enforce any mode limitations before setting?
+
+
+ +
+
+ +

◆ setLed()

+ +
+
+ + + + + + + +
void IRCoolixAC::setLed ()
+
+ +

Toggle the Led (light) mode of the A/C.

+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRCoolixAC::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRCoolixAC::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRCoolixAC::setRaw (const uint32_t new_code)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]new_codeA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSensorTemp()

+ +
+
+ + + + + + + + +
void IRCoolixAC::setSensorTemp (const uint8_t desired)
+
+ +

Set the sensor temperature.

+
Parameters
+ + +
[in]desiredThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ setSensorTempRaw()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRCoolixAC::setSensorTempRaw (const uint8_t code)
+
+private
+
+ +

Set the raw (native) sensor temperature value.

+
Note
Bypasses any checks or additional actions.
+
Parameters
+ + +
[in]codeThe desired native sensor temperature.
+
+
+ +
+
+ +

◆ setSleep()

+ +
+
+ + + + + + + +
void IRCoolixAC::setSleep ()
+
+ +

Toggle the Sleep mode of the A/C.

+ +
+
+ +

◆ setSwing()

+ +
+
+ + + + + + + +
void IRCoolixAC::setSwing ()
+
+ +

Toggle the Swing mode of the A/C.

+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRCoolixAC::setTemp (const uint8_t desired)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]desiredThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ setTempRaw()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRCoolixAC::setTempRaw (const uint8_t code)
+
+private
+
+ +

Set the raw (native) temperature value.

+
Note
Bypasses any checks.
+
Parameters
+ + +
[in]codeThe desired native temperature.
+
+
+ +
+
+ +

◆ setTurbo()

+ +
+
+ + + + + + + +
void IRCoolixAC::setTurbo ()
+
+ +

Toggle the Turbo mode of the A/C.

+ +
+
+ +

◆ setZoneFollow()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRCoolixAC::setZoneFollow (const bool on)
+
+private
+
+ +

Change the Zone Follow setting.

+
Note
Internal use only.
+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + +
void IRCoolixAC::stateReset ()
+
+ +

Reset the internal state to a fixed known good state.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRCoolixAC::toCommon (const stdAc::state_tprev = NULL)
+
+ +

Convert the A/C state to it's common stdAc::state_t equivalent.

+
Parameters
+ + +
[in]prevPtr to the previous state if required.
+
+
+
Returns
A stdAc::state_t state.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRCoolixAC::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRCoolixAC::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode to it's common stdAc::opmode_t equivalent.

+
Parameters
+ + +
[in]modeA native operation mode to be converted.
+
+
+
Returns
The corresponding common stdAc::opmode_t mode.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + +
String IRCoolixAC::toString ()
+
+ +

Convert the internal state into a human readable string.

+
Returns
The current internal state expressed as a human readable String.
+ +
+
+ +

◆ updateSavedState()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRCoolixAC::updateSavedState (void )
+
+private
+
+ +

Backup the current internal state as long as it isn't a special state.

+
Note
: Must be called before every special state to make sure the remote_state is safe
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRCoolixAC::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ cleanFlag

+ +
+
+ + + + + +
+ + + + +
bool IRCoolixAC::cleanFlag
+
+private
+
+ +
+
+ +

◆ ledFlag

+ +
+
+ + + + + +
+ + + + +
bool IRCoolixAC::ledFlag
+
+private
+
+ +
+
+ +

◆ powerFlag

+ +
+
+ + + + + +
+ + + + +
bool IRCoolixAC::powerFlag
+
+private
+
+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint32_t IRCoolixAC::remote_state
+
+private
+
+ +

The state of the IR remote in IR code form.

+ +
+
+ +

◆ saved_state

+ +
+
+ + + + + +
+ + + + +
uint32_t IRCoolixAC::saved_state
+
+private
+
+ +

Copy of the state if we required a special mode.

+ +
+
+ +

◆ sleepFlag

+ +
+
+ + + + + +
+ + + + +
bool IRCoolixAC::sleepFlag
+
+private
+
+ +
+
+ +

◆ swingFlag

+ +
+
+ + + + + +
+ + + + +
bool IRCoolixAC::swingFlag
+
+private
+
+ +
+
+ +

◆ swingHFlag

+ +
+
+ + + + + +
+ + + + +
bool IRCoolixAC::swingHFlag
+
+private
+
+ +
+
+ +

◆ swingVFlag

+ +
+
+ + + + + +
+ + + + +
bool IRCoolixAC::swingVFlag
+
+private
+
+ +
+
+ +

◆ turboFlag

+ +
+
+ + + + + +
+ + + + +
bool IRCoolixAC::turboFlag
+
+private
+
+ +
+
+ +

◆ zoneFollowFlag

+ +
+
+ + + + + +
+ + + + +
bool IRCoolixAC::zoneFollowFlag
+
+private
+
+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC__coll__graph.map new file mode 100644 index 000000000..74e59be41 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC__coll__graph.md5 new file mode 100644 index 000000000..eb300fb90 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC__coll__graph.md5 @@ -0,0 +1 @@ +4ccbb54c1327fe4f53812f4cc284a8f1 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC__coll__graph.png new file mode 100644 index 000000000..76fd97acc Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoolixAC__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc-members.html new file mode 100644 index 000000000..d6f9bac48 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc-members.html @@ -0,0 +1,120 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRCoronaAc Member List
+
+
+ +

This is the complete list of members for IRCoronaAc, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_getTimer(const uint8_t section)IRCoronaAcprivate
_irsendIRCoronaAcprivate
_setPower(const bool on)IRCoronaAcprivate
_setTimer(const uint8_t section, const uint16_t nr_of_mins)IRCoronaAcprivate
begin()IRCoronaAc
calibrate(void)IRCoronaAcinline
checksum(uint8_t *data)IRCoronaAcprivatestatic
convertFan(const stdAc::fanspeed_t speed)IRCoronaAc
convertMode(const stdAc::opmode_t mode)IRCoronaAc
getEcono(void)IRCoronaAc
getFan()IRCoronaAc
getMode()IRCoronaAc
getOffTimer(void)IRCoronaAc
getOnTimer(void)IRCoronaAc
getPower()IRCoronaAc
getPowerButton()IRCoronaAc
getRaw()IRCoronaAc
getSectionByte(const uint8_t section)IRCoronaAcprivatestatic
getSwingVToggle(void)IRCoronaAc
getTemp()IRCoronaAc
IRCoronaAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRCoronaAcexplicit
off()IRCoronaAc
on()IRCoronaAc
remote_stateIRCoronaAcprivate
send(const uint16_t repeat=kNoRepeat)IRCoronaAc
setEcono(const bool on)IRCoronaAc
setFan(const uint8_t speed)IRCoronaAc
setMode(const uint8_t mode)IRCoronaAc
setOffTimer(const uint16_t nr_of_mins)IRCoronaAc
setOnTimer(const uint16_t nr_of_mins)IRCoronaAc
setPower(const bool on)IRCoronaAc
setPowerButton(const bool on)IRCoronaAcprivate
setRaw(const uint8_t new_code[], const uint16_t length=kCoronaAcStateLength)IRCoronaAc
setSwingVToggle(const bool on)IRCoronaAc
setTemp(const uint8_t temp)IRCoronaAc
stateReset()IRCoronaAc
toCommon()IRCoronaAc
toCommonFanSpeed(const uint8_t speed)IRCoronaAcstatic
toCommonMode(const uint8_t mode)IRCoronaAcstatic
toString()IRCoronaAc
validSection(const uint8_t state[], const uint16_t pos, const uint8_t section)IRCoronaAcstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc.html new file mode 100644 index 000000000..7a9e4513c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc.html @@ -0,0 +1,1360 @@ + + + + + + + +IRremoteESP8266: IRCoronaAc Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Corona A/C messages. + More...

+ +

#include <ir_Corona.h>

+
+Collaboration diagram for IRCoronaAc:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRCoronaAc (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor for handling detailed Corona A/C messages. More...
 
void stateReset ()
 Reset the internal state to a fixed known good state. More...
 
void send (const uint16_t repeat=kNoRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin ()
 Set up hardware to be able to send a message. More...
 
void setPower (const bool on)
 Change the power setting. (in practice Standby, remote power) More...
 
bool getPower ()
 Get the current power setting. (in practice Standby, remote power) More...
 
bool getPowerButton ()
 Get the value of the current power button setting. More...
 
void on ()
 Change the power setting to On. More...
 
void off ()
 Change the power setting to Off. More...
 
void setTemp (const uint8_t temp)
 Set the temp in deg C. More...
 
uint8_t getTemp ()
 Get the current temperature from the internal state. More...
 
void setSwingVToggle (const bool on)
 Set the Vertical Swing toggle setting. More...
 
bool getSwingVToggle (void)
 Get the Vertical Swing toggle setting. More...
 
void setFan (const uint8_t speed)
 Set the operating speed of the A/C Fan. More...
 
uint8_t getFan ()
 Get the operating speed of the A/C Fan. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode ()
 Get the operating mode setting of the A/C. More...
 
void setEcono (const bool on)
 Change the powersave setting. More...
 
bool getEcono (void)
 Get the value of the current powersave setting. More...
 
void setOnTimer (const uint16_t nr_of_mins)
 Set the On Timer time. More...
 
uint16_t getOnTimer (void)
 Get the current On Timer time. More...
 
void setOffTimer (const uint16_t nr_of_mins)
 Set the Off Timer time. More...
 
uint16_t getOffTimer (void)
 Get the current Off Timer time. More...
 
uint8_t * getRaw ()
 Get a copy of the internal state as a valid code for this protocol. More...
 
void setRaw (const uint8_t new_code[], const uint16_t length=kCoronaAcStateLength)
 Set the internal state from a valid code for this protocol. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a standard A/C mode into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a standard A/C Fan speed into its native fan speed. More...
 
stdAc::state_t toCommon ()
 Convert the A/C state to it's common stdAc::state_t equivalent. More...
 
String toString ()
 Convert the internal state into a human readable string. More...
 
+ + + + + + + + + + +

+Static Public Member Functions

static bool validSection (const uint8_t state[], const uint16_t pos, const uint8_t section)
 Check that a CoronaAc Section part is valid with section byte and inverted. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode to it's common stdAc::opmode_t equivalent. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed to it's common equivalent. More...
 
+ + + + + + + + + + + + + +

+Private Member Functions

void setPowerButton (const bool on)
 Change the power button setting. More...
 
void _setPower (const bool on)
 Change the power setting. (in practice Standby, remote power) More...
 
void _setTimer (const uint8_t section, const uint16_t nr_of_mins)
 Set the Timer time. More...
 
uint16_t _getTimer (const uint8_t section)
 Get the current Timer time. More...
 
+ + + + + + + +

+Static Private Member Functions

static uint8_t getSectionByte (const uint8_t section)
 Get the byte that identifies the section. More...
 
static void checksum (uint8_t *data)
 Calculate and set the check values for the internal state. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kCoronaAcStateLength]
 The state of the IR remote. More...
 
+

Detailed Description

+

Class for handling detailed Corona A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRCoronaAc()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRCoronaAc::IRCoronaAc (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor for handling detailed Corona A/C messages.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ _getTimer()

+ +
+
+ + + + + +
+ + + + + + + + +
uint16_t IRCoronaAc::_getTimer (const uint8_t section)
+
+private
+
+ +

Get the current Timer time.

+
Returns
The number of minutes it is set for. 0 means it's off.
+
Note
The A/C protocol supports 2 second increments
+ +
+
+ +

◆ _setPower()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRCoronaAc::_setPower (const bool on)
+
+private
+
+ +

Change the power setting. (in practice Standby, remote power)

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ _setTimer()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void IRCoronaAc::_setTimer (const uint8_t section,
const uint16_t nr_of_mins 
)
+
+private
+
+ +

Set the Timer time.

+
Parameters
+ + + +
[in]sectionindex of section, used for offset.
[in]nr_of_minsNumber of minutes to set the timer to. (non in range value is disable). Valid is from 1 minute to 12 hours
+
+
+ +
+
+ +

◆ begin()

+ +
+
+ + + + + + + +
void IRCoronaAc::begin ()
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRCoronaAc::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
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.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRCoronaAc::checksum (uint8_t * data)
+
+staticprivate
+
+ +

Calculate and set the check values for the internal state.

+
Parameters
+ + +
[in,out]dataThe array to be modified
+
+
+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRCoronaAc::convertFan (const stdAc::fanspeed_t speed)
+
+ +

Convert a standard A/C Fan speed into its native fan speed.

+
Parameters
+ + +
[in]speedThe desired stdAc::fanspeed_t fan speed
+
+
+
Returns
The given fan speed in native format
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRCoronaAc::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a standard A/C mode into its native mode.

+
Parameters
+ + +
[in]modeA stdAc::opmode_t mode to be converted to it's native equivalent
+
+
+
Returns
The corresponding native mode.
+ +
+
+ +

◆ getEcono()

+ +
+
+ + + + + + + + +
bool IRCoronaAc::getEcono (void )
+
+ +

Get the value of the current powersave setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + +
uint8_t IRCoronaAc::getFan ()
+
+ +

Get the operating speed of the A/C Fan.

+
Returns
The current operating fan speed setting
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + +
uint8_t IRCoronaAc::getMode ()
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getOffTimer()

+ +
+
+ + + + + + + + +
uint16_t IRCoronaAc::getOffTimer (void )
+
+ +

Get the current Off Timer time.

+
Returns
The number of minutes it is set for. 0 means it's off.
+ +
+
+ +

◆ getOnTimer()

+ +
+
+ + + + + + + + +
uint16_t IRCoronaAc::getOnTimer (void )
+
+ +

Get the current On Timer time.

+
Returns
The number of minutes it is set for. 0 means it's off.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + +
bool IRCoronaAc::getPower ()
+
+ +

Get the current power setting. (in practice Standby, remote power)

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getPowerButton()

+ +
+
+ + + + + + + +
bool IRCoronaAc::getPowerButton ()
+
+ +

Get the value of the current power button setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + +
uint8_t * IRCoronaAc::getRaw ()
+
+ +

Get a copy of the internal state as a valid code for this protocol.

+
Returns
A Ptr to a valid code for this protocol based on the current internal state.
+
Note
To get stable AC state, if no timers, send once without PowerButton set, and once with
+ +
+
+ +

◆ getSectionByte()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRCoronaAc::getSectionByte (const uint8_t section)
+
+staticprivate
+
+ +

Get the byte that identifies the section.

+
Parameters
+ + +
[in]sectionIndex of the section 0-2, 3 and above is used as the special case for short message
+
+
+
Returns
The byte used for the section
+ +
+
+ +

◆ getSwingVToggle()

+ +
+
+ + + + + + + + +
bool IRCoronaAc::getSwingVToggle (void )
+
+ +

Get the Vertical Swing toggle setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + +
uint8_t IRCoronaAc::getTemp ()
+
+ +

Get the current temperature from the internal state.

+
Returns
The current temperature in Celsius.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + +
void IRCoronaAc::off ()
+
+ +

Change the power setting to Off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + +
void IRCoronaAc::on ()
+
+ +

Change the power setting to On.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRCoronaAc::send (const uint16_t repeat = kNoRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setEcono()

+ +
+
+ + + + + + + + +
void IRCoronaAc::setEcono (const bool on)
+
+ +

Change the powersave setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRCoronaAc::setFan (const uint8_t speed)
+
+ +

Set the operating speed of the A/C Fan.

+
Parameters
+ + +
[in]speedThe desired fan speed
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRCoronaAc::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setOffTimer()

+ +
+
+ + + + + + + + +
void IRCoronaAc::setOffTimer (const uint16_t nr_of_mins)
+
+ +

Set the Off Timer time.

+
Parameters
+ + +
[in]nr_of_minsNumber of minutes to set the timer to. (0 or kCoronaAcTimerOff is disable).
+
+
+ +
+
+ +

◆ setOnTimer()

+ +
+
+ + + + + + + + +
void IRCoronaAc::setOnTimer (const uint16_t nr_of_mins)
+
+ +

Set the On Timer time.

+
Parameters
+ + +
[in]nr_of_minsNumber of minutes to set the timer to. (0 or kCoronaAcTimerOff is disable).
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRCoronaAc::setPower (const bool on)
+
+ +

Change the power setting. (in practice Standby, remote power)

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+
Note
If changed, setPowerButton is also needed, unless timer is or was active
+ +
+
+ +

◆ setPowerButton()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRCoronaAc::setPowerButton (const bool on)
+
+private
+
+ +

Change the power button setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+
Note
this sets that the AC should set power, use setPower to define if the AC should end up as on or off When no timer is active, the below is a truth table With AC On, a command with setPower and setPowerButton gives nothing With AC On, a command with setPower but not setPowerButton is ok With AC Off, a command with setPower but not setPowerButton gives nothing With AC Off, a command with setPower and setPowerButton is ok
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRCoronaAc::setRaw (const uint8_t new_code[],
const uint16_t length = kCoronaAcStateLength 
)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + + +
[in]new_codeA valid state for this protocol.
[in]lengthof the new_code array.
+
+
+ +
+
+ +

◆ setSwingVToggle()

+ +
+
+ + + + + + + + +
void IRCoronaAc::setSwingVToggle (const bool on)
+
+ +

Set the Vertical Swing toggle setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+
Note
This is a button press, and not a state after sending it once you should turn it off
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRCoronaAc::setTemp (const uint8_t temp)
+
+ +

Set the temp in deg C.

+
Parameters
+ + +
[in]tempThe desired temperature in Celsius.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + +
void IRCoronaAc::stateReset ()
+
+ +

Reset the internal state to a fixed known good state.

+
Note
The state is powered off.
+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + +
stdAc::state_t IRCoronaAc::toCommon ()
+
+ +

Convert the A/C state to it's common stdAc::state_t equivalent.

+
Returns
A stdAc::state_t state.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRCoronaAc::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed to it's common equivalent.

+
Parameters
+ + +
[in]speedThe desired native fan speed
+
+
+
Returns
The given fan speed in stdAc::fanspeed_t format
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRCoronaAc::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode to it's common stdAc::opmode_t equivalent.

+
Parameters
+ + +
[in]modeA native operation mode to be converted.
+
+
+
Returns
The corresponding common stdAc::opmode_t mode.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + +
String IRCoronaAc::toString ()
+
+ +

Convert the internal state into a human readable string.

+
Returns
The current internal state expressed as a human readable String.
+ +
+
+ +

◆ validSection()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool IRCoronaAc::validSection (const uint8_t state[],
const uint16_t pos,
const uint8_t section 
)
+
+static
+
+ +

Check that a CoronaAc Section part is valid with section byte and inverted.

+
Parameters
+ + + + +
[in]stateAn array of bytes containing the section
[in]posWhere to start in the state array
[in]sectionWhich section to work with Used to get the section byte, and is validated against pos
+
+
+
Returns
true if section is valid, otherwise false
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRCoronaAc::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRCoronaAc::remote_state[kCoronaAcStateLength]
+
+private
+
+ +

The state of the IR remote.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc__coll__graph.map new file mode 100644 index 000000000..7b9921ac4 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc__coll__graph.md5 new file mode 100644 index 000000000..fe237b80f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc__coll__graph.md5 @@ -0,0 +1 @@ +2a8dc27b8683799250ee74acb6173d8f \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc__coll__graph.png new file mode 100644 index 000000000..b8c35c470 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRCoronaAc__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128-members.html new file mode 100644 index 000000000..a77e405ef --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128-members.html @@ -0,0 +1,132 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRDaikin128 Member List
+
+
+ +

This is the complete list of members for IRDaikin128, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRDaikin128private
begin()IRDaikin128
calcFirstChecksum(const uint8_t state[])IRDaikin128privatestatic
calcSecondChecksum(const uint8_t state[])IRDaikin128privatestatic
calibrate(void)IRDaikin128inline
checksum(void)IRDaikin128private
clearOnTimerFlag(void)IRDaikin128private
clearSleepTimerFlag(void)IRDaikin128private
convertFan(const stdAc::fanspeed_t speed)IRDaikin128static
convertMode(const stdAc::opmode_t mode)IRDaikin128static
getClock(void)IRDaikin128
getEcono(void)IRDaikin128
getFan(void)IRDaikin128
getLightToggle(void)IRDaikin128
getMode(void)IRDaikin128
getOffTimer(void)IRDaikin128
getOffTimerEnabled(void)IRDaikin128
getOnTimer(void)IRDaikin128
getOnTimerEnabled(void)IRDaikin128
getPowerful(void)IRDaikin128
getPowerToggle(void)IRDaikin128
getQuiet(void)IRDaikin128
getRaw(void)IRDaikin128
getSleep(void)IRDaikin128
getSwingVertical()IRDaikin128
getTemp(void)IRDaikin128
getTimer(const uint8_t *ptr)IRDaikin128privatestatic
IRDaikin128(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRDaikin128explicit
remote_stateIRDaikin128private
send(const uint16_t repeat=kDaikin128DefaultRepeat)IRDaikin128
setClock(const uint16_t mins_since_midnight)IRDaikin128
setEcono(const bool on)IRDaikin128
setFan(const uint8_t fan)IRDaikin128
setLightToggle(const uint8_t unit_type)IRDaikin128
setMode(const uint8_t mode)IRDaikin128
setOffTimer(const uint16_t mins_since_midnight)IRDaikin128
setOffTimerEnabled(const bool on)IRDaikin128
setOnTimer(const uint16_t mins_since_midnight)IRDaikin128
setOnTimerEnabled(const bool on)IRDaikin128
setPowerful(const bool on)IRDaikin128
setPowerToggle(const bool toggle)IRDaikin128
setQuiet(const bool on)IRDaikin128
setRaw(const uint8_t new_code[])IRDaikin128
setSleep(const bool on)IRDaikin128
setSwingVertical(const bool on)IRDaikin128
setTemp(const uint8_t temp)IRDaikin128
setTimer(uint8_t *ptr, const uint16_t mins_since_midnight)IRDaikin128privatestatic
stateReset(void)IRDaikin128private
toCommon(const stdAc::state_t *prev=NULL)IRDaikin128
toCommonFanSpeed(const uint8_t speed)IRDaikin128static
toCommonMode(const uint8_t mode)IRDaikin128static
toString(void)IRDaikin128
validChecksum(uint8_t state[])IRDaikin128static
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128.html new file mode 100644 index 000000000..e2522aa48 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128.html @@ -0,0 +1,1669 @@ + + + + + + + +IRremoteESP8266: IRDaikin128 Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Daikin 128-bit A/C messages. Code by crankyoldgit. Analysis by Daniel Vena. + More...

+ +

#include <ir_Daikin.h>

+
+Collaboration diagram for IRDaikin128:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRDaikin128 (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void send (const uint16_t repeat=kDaikin128DefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin ()
 Set up hardware to be able to send a message. More...
 
void setPowerToggle (const bool toggle)
 Set the Power toggle setting of the A/C. More...
 
bool getPowerToggle (void)
 Get the Power toggle setting of the A/C. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t fan)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
void setSwingVertical (const bool on)
 Set the Vertical Swing mode of the A/C. More...
 
bool getSwingVertical ()
 Get the Vertical Swing mode of the A/C. More...
 
bool getSleep (void)
 Get the Sleep mode of the A/C. More...
 
void setSleep (const bool on)
 Set the Sleep mode of the A/C. More...
 
bool getQuiet (void)
 Get the Quiet mode status of the A/C. More...
 
void setQuiet (const bool on)
 Set the Quiet mode of the A/C. More...
 
bool getPowerful (void)
 Get the Powerful (Turbo) mode of the A/C. More...
 
void setPowerful (const bool on)
 Set the Powerful (Turbo) mode of the A/C. More...
 
void setEcono (const bool on)
 Set the Economy mode of the A/C. More...
 
bool getEcono (void)
 Get the Economical mode of the A/C. More...
 
void setOnTimer (const uint16_t mins_since_midnight)
 Set the On Timer time for the A/C unit. More...
 
uint16_t getOnTimer (void)
 Get the On Timer time to be sent to the A/C unit. More...
 
bool getOnTimerEnabled (void)
 Get the enable status of the On Timer. More...
 
void setOnTimerEnabled (const bool on)
 Set the enable status of the On Timer. More...
 
void setOffTimer (const uint16_t mins_since_midnight)
 Set the Off Timer time for the A/C unit. More...
 
uint16_t getOffTimer (void)
 Get the Off Timer time to be sent to the A/C unit. More...
 
bool getOffTimerEnabled (void)
 Get the enable status of the Off Timer. More...
 
void setOffTimerEnabled (const bool on)
 Set the enable status of the Off Timer. More...
 
void setClock (const uint16_t mins_since_midnight)
 Set the clock on the A/C unit. More...
 
uint16_t getClock (void)
 Get the clock time to be sent to the A/C unit. More...
 
void setLightToggle (const uint8_t unit_type)
 Set the Light toggle setting of the A/C. More...
 
uint8_t getLightToggle (void)
 Get the Light toggle setting of the A/C. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t new_code[])
 Set the internal state from a valid code for this protocol. More...
 
stdAc::state_t toCommon (const stdAc::state_t *prev=NULL)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (uint8_t state[])
 Verify the checksum is valid for a given state. More...
 
static uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
static uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + + + + + + + + +

+Private Member Functions

void stateReset (void)
 Reset the internal state to a fixed known good state. More...
 
void checksum (void)
 Calculate and set the checksum values for the internal state. More...
 
void clearOnTimerFlag (void)
 
void clearSleepTimerFlag (void)
 
+ + + + + + + + + + + +

+Static Private Member Functions

static uint8_t calcFirstChecksum (const uint8_t state[])
 
static uint8_t calcSecondChecksum (const uint8_t state[])
 
static void setTimer (uint8_t *ptr, const uint16_t mins_since_midnight)
 Set the time for a timer at the given location. More...
 
static uint16_t getTimer (const uint8_t *ptr)
 Get the time for a timer at the given location. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 instance of the IR send class More...
 
uint8_t remote_state [kDaikin128StateLength]
 The state of the IR remote. More...
 
+

Detailed Description

+

Class for handling detailed Daikin 128-bit A/C messages. Code by crankyoldgit. Analysis by Daniel Vena.

+

Constructor & Destructor Documentation

+ +

◆ IRDaikin128()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRDaikin128::IRDaikin128 (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + +
void IRDaikin128::begin ()
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calcFirstChecksum()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikin128::calcFirstChecksum (const uint8_t state[])
+
+staticprivate
+
+ +
+
+ +

◆ calcSecondChecksum()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikin128::calcSecondChecksum (const uint8_t state[])
+
+staticprivate
+
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRDaikin128::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
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.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRDaikin128::checksum (void )
+
+private
+
+ +

Calculate and set the checksum values for the internal state.

+ +
+
+ +

◆ clearOnTimerFlag()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRDaikin128::clearOnTimerFlag (void )
+
+private
+
+ +
+
+ +

◆ clearSleepTimerFlag()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRDaikin128::clearSleepTimerFlag (void )
+
+private
+
+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikin128::convertFan (const stdAc::fanspeed_t speed)
+
+static
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikin128::convertMode (const stdAc::opmode_t mode)
+
+static
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getClock()

+ +
+
+ + + + + + + + +
uint16_t IRDaikin128::getClock (void )
+
+ +

Get the clock time to be sent to the A/C unit.

+
Returns
The number of minutes past midnight.
+ +
+
+ +

◆ getEcono()

+ +
+
+ + + + + + + + +
bool IRDaikin128::getEcono (void )
+
+ +

Get the Economical mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRDaikin128::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getLightToggle()

+ +
+
+ + + + + + + + +
uint8_t IRDaikin128::getLightToggle (void )
+
+ +

Get the Light toggle setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRDaikin128::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getOffTimer()

+ +
+
+ + + + + + + + +
uint16_t IRDaikin128::getOffTimer (void )
+
+ +

Get the Off Timer time to be sent to the A/C unit.

+
Returns
The number of minutes past midnight.
+ +
+
+ +

◆ getOffTimerEnabled()

+ +
+
+ + + + + + + + +
bool IRDaikin128::getOffTimerEnabled (void )
+
+ +

Get the enable status of the Off Timer.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getOnTimer()

+ +
+
+ + + + + + + + +
uint16_t IRDaikin128::getOnTimer (void )
+
+ +

Get the On Timer time to be sent to the A/C unit.

+
Returns
The number of minutes past midnight.
+ +
+
+ +

◆ getOnTimerEnabled()

+ +
+
+ + + + + + + + +
bool IRDaikin128::getOnTimerEnabled (void )
+
+ +

Get the enable status of the On Timer.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getPowerful()

+ +
+
+ + + + + + + + +
bool IRDaikin128::getPowerful (void )
+
+ +

Get the Powerful (Turbo) mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getPowerToggle()

+ +
+
+ + + + + + + + +
bool IRDaikin128::getPowerToggle (void )
+
+ +

Get the Power toggle setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getQuiet()

+ +
+
+ + + + + + + + +
bool IRDaikin128::getQuiet (void )
+
+ +

Get the Quiet mode status of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRDaikin128::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSleep()

+ +
+
+ + + + + + + + +
bool IRDaikin128::getSleep (void )
+
+ +

Get the Sleep mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwingVertical()

+ +
+
+ + + + + + + +
bool IRDaikin128::getSwingVertical ()
+
+ +

Get the Vertical Swing mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRDaikin128::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ getTimer()

+ +
+
+ + + + + +
+ + + + + + + + +
uint16_t IRDaikin128::getTimer (const uint8_t * ptr)
+
+staticprivate
+
+ +

Get the time for a timer at the given location.

+
Parameters
+ + +
[in]ptrA Ptr to the byte containing the Timer value.
+
+
+
Returns
The number of minutes since midnight that the timer is set to.
+
Note
Timer is stored in nr. of half hours internally.
+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRDaikin128::send (const uint16_t repeat = kDaikin128DefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setClock()

+ +
+
+ + + + + + + + +
void IRDaikin128::setClock (const uint16_t mins_since_midnight)
+
+ +

Set the clock on the A/C unit.

+
Parameters
+ + +
[in]mins_since_midnightNr. of minutes past midnight.
+
+
+ +
+
+ +

◆ setEcono()

+ +
+
+ + + + + + + + +
void IRDaikin128::setEcono (const bool on)
+
+ +

Set the Economy mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRDaikin128::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting.
+
+
+ +
+
+ +

◆ setLightToggle()

+ +
+
+ + + + + + + + +
void IRDaikin128::setLightToggle (const uint8_t unit)
+
+ +

Set the Light toggle setting of the A/C.

+
Parameters
+ + +
[in]unitDevice to show the LED (Light) Display info about.
+
+
+
Note
0 is off.
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRDaikin128::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setOffTimer()

+ +
+
+ + + + + + + + +
void IRDaikin128::setOffTimer (const uint16_t mins_since_midnight)
+
+ +

Set the Off Timer time for the A/C unit.

+
Parameters
+ + +
[in]mins_since_midnightNr. of minutes past midnight.
+
+
+ +
+
+ +

◆ setOffTimerEnabled()

+ +
+
+ + + + + + + + +
void IRDaikin128::setOffTimerEnabled (const bool on)
+
+ +

Set the enable status of the Off Timer.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setOnTimer()

+ +
+
+ + + + + + + + +
void IRDaikin128::setOnTimer (const uint16_t mins_since_midnight)
+
+ +

Set the On Timer time for the A/C unit.

+
Parameters
+ + +
[in]mins_since_midnightNr. of minutes past midnight.
+
+
+ +
+
+ +

◆ setOnTimerEnabled()

+ +
+
+ + + + + + + + +
void IRDaikin128::setOnTimerEnabled (const bool on)
+
+ +

Set the enable status of the On Timer.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setPowerful()

+ +
+
+ + + + + + + + +
void IRDaikin128::setPowerful (const bool on)
+
+ +

Set the Powerful (Turbo) mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setPowerToggle()

+ +
+
+ + + + + + + + +
void IRDaikin128::setPowerToggle (const bool toggle)
+
+ +

Set the Power toggle setting of the A/C.

+
Parameters
+ + +
[in]toggletrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setQuiet()

+ +
+
+ + + + + + + + +
void IRDaikin128::setQuiet (const bool on)
+
+ +

Set the Quiet mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRDaikin128::setRaw (const uint8_t new_code[])
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]new_codeA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSleep()

+ +
+
+ + + + + + + + +
void IRDaikin128::setSleep (const bool on)
+
+ +

Set the Sleep mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwingVertical()

+ +
+
+ + + + + + + + +
void IRDaikin128::setSwingVertical (const bool on)
+
+ +

Set the Vertical Swing mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRDaikin128::setTemp (const uint8_t temp)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]tempThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ setTimer()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void IRDaikin128::setTimer (uint8_t * ptr,
const uint16_t mins_since_midnight 
)
+
+staticprivate
+
+ +

Set the time for a timer at the given location.

+
Parameters
+ + + +
[in,out]ptrPtr to the byte containing the Timer value to be updated.
[in]mins_since_midnightThe number of minutes the new timer should be set to.
+
+
+
Note
Timer is rounds down to the nearest half hour.
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRDaikin128::stateReset (void )
+
+private
+
+ +

Reset the internal state to a fixed known good state.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRDaikin128::toCommon (const stdAc::state_tprev = NULL)
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Parameters
+ + +
[in]prevPtr to a previous state.
+
+
+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRDaikin128::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRDaikin128::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRDaikin128::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + +
bool IRDaikin128::validChecksum (uint8_t state[])
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + +
[in]stateThe array to verify the checksum of.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRDaikin128::_irsend
+
+private
+
+ +

instance of the IR send class

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRDaikin128::remote_state[kDaikin128StateLength]
+
+private
+
+ +

The state of the IR remote.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128__coll__graph.map new file mode 100644 index 000000000..409771223 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128__coll__graph.md5 new file mode 100644 index 000000000..2f277b744 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128__coll__graph.md5 @@ -0,0 +1 @@ +de983d342633022717e3dd59d86c22b1 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128__coll__graph.png new file mode 100644 index 000000000..aeb1a1b31 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin128__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152-members.html new file mode 100644 index 000000000..7b47665d8 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152-members.html @@ -0,0 +1,116 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRDaikin152 Member List
+
+
+ +

This is the complete list of members for IRDaikin152, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRDaikin152private
begin()IRDaikin152
calibrate(void)IRDaikin152inline
checksum()IRDaikin152private
convertFan(const stdAc::fanspeed_t speed)IRDaikin152static
convertMode(const stdAc::opmode_t mode)IRDaikin152static
getComfort(void)IRDaikin152
getEcono(void)IRDaikin152
getFan(void)IRDaikin152
getMode(void)IRDaikin152
getPower(void)IRDaikin152
getPowerful(void)IRDaikin152
getQuiet(void)IRDaikin152
getRaw()IRDaikin152
getSensor(void)IRDaikin152
getSwingV(void)IRDaikin152
getTemp()IRDaikin152
IRDaikin152(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRDaikin152explicit
off(void)IRDaikin152
on(void)IRDaikin152
remote_stateIRDaikin152private
send(const uint16_t repeat=kDaikin152DefaultRepeat)IRDaikin152
setComfort(const bool on)IRDaikin152
setEcono(const bool on)IRDaikin152
setFan(const uint8_t fan)IRDaikin152
setMode(const uint8_t mode)IRDaikin152
setPower(const bool on)IRDaikin152
setPowerful(const bool on)IRDaikin152
setQuiet(const bool on)IRDaikin152
setRaw(const uint8_t new_code[])IRDaikin152
setSensor(const bool on)IRDaikin152
setSwingV(const bool on)IRDaikin152
setTemp(const uint8_t temp)IRDaikin152
stateReset()IRDaikin152private
toCommon(void)IRDaikin152
toString(void)IRDaikin152
validChecksum(uint8_t state[], const uint16_t length=kDaikin152StateLength)IRDaikin152static
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152.html new file mode 100644 index 000000000..a9d798e0b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152.html @@ -0,0 +1,1172 @@ + + + + + + + +IRremoteESP8266: IRDaikin152 Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Daikin 152-bit A/C messages. + More...

+ +

#include <ir_Daikin.h>

+
+Collaboration diagram for IRDaikin152:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRDaikin152 (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void send (const uint16_t repeat=kDaikin152DefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin ()
 Set up hardware to be able to send a message. More...
 
uint8_t * getRaw ()
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t new_code[])
 Set the internal state from a valid code for this protocol. More...
 
void on (void)
 Change the power setting to On. More...
 
void off (void)
 Change the power setting to Off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp ()
 Get the current temperature setting. More...
 
void setFan (const uint8_t fan)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setSwingV (const bool on)
 Set the Vertical Swing mode of the A/C. More...
 
bool getSwingV (void)
 Get the Vertical Swing mode of the A/C. More...
 
bool getQuiet (void)
 Get the Quiet mode status of the A/C. More...
 
void setQuiet (const bool on)
 Set the Quiet mode of the A/C. More...
 
bool getPowerful (void)
 Get the Powerful (Turbo) mode of the A/C. More...
 
void setPowerful (const bool on)
 Set the Powerful (Turbo) mode of the A/C. More...
 
void setSensor (const bool on)
 Set the Sensor mode of the A/C. More...
 
bool getSensor (void)
 Get the Sensor mode of the A/C. More...
 
void setEcono (const bool on)
 Set the Economy mode of the A/C. More...
 
bool getEcono (void)
 Get the Economical mode of the A/C. More...
 
void setComfort (const bool on)
 Set the Comfort mode of the A/C. More...
 
bool getComfort (void)
 Get the Comfort mode of the A/C. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (uint8_t state[], const uint16_t length=kDaikin152StateLength)
 Verify the checksum is valid for a given state. More...
 
static uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
static uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
+ + + + + + + +

+Private Member Functions

void stateReset ()
 Reset the internal state to a fixed known good state. More...
 
void checksum ()
 Calculate and set the checksum values for the internal state. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 instance of the IR send class More...
 
uint8_t remote_state [kDaikin152StateLength]
 The state of the IR remote. More...
 
+

Detailed Description

+

Class for handling detailed Daikin 152-bit A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRDaikin152()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRDaikin152::IRDaikin152 (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + +
void IRDaikin152::begin ()
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRDaikin152::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
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.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + +
void IRDaikin152::checksum ()
+
+private
+
+ +

Calculate and set the checksum values for the internal state.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikin152::convertFan (const stdAc::fanspeed_t speed)
+
+static
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikin152::convertMode (const stdAc::opmode_t mode)
+
+static
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getComfort()

+ +
+
+ + + + + + + + +
bool IRDaikin152::getComfort (void )
+
+ +

Get the Comfort mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getEcono()

+ +
+
+ + + + + + + + +
bool IRDaikin152::getEcono (void )
+
+ +

Get the Economical mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRDaikin152::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRDaikin152::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRDaikin152::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getPowerful()

+ +
+
+ + + + + + + + +
bool IRDaikin152::getPowerful (void )
+
+ +

Get the Powerful (Turbo) mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getQuiet()

+ +
+
+ + + + + + + + +
bool IRDaikin152::getQuiet (void )
+
+ +

Get the Quiet mode status of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + +
uint8_t * IRDaikin152::getRaw ()
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSensor()

+ +
+
+ + + + + + + + +
bool IRDaikin152::getSensor (void )
+
+ +

Get the Sensor mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwingV()

+ +
+
+ + + + + + + + +
bool IRDaikin152::getSwingV (void )
+
+ +

Get the Vertical Swing mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + +
uint8_t IRDaikin152::getTemp ()
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRDaikin152::off (void )
+
+ +

Change the power setting to Off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRDaikin152::on (void )
+
+ +

Change the power setting to On.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRDaikin152::send (const uint16_t repeat = kDaikin152DefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setComfort()

+ +
+
+ + + + + + + + +
void IRDaikin152::setComfort (const bool on)
+
+ +

Set the Comfort mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setEcono()

+ +
+
+ + + + + + + + +
void IRDaikin152::setEcono (const bool on)
+
+ +

Set the Economy mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRDaikin152::setFan (const uint8_t fan)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]fanThe desired setting.
+
+
+
Note
1-5 or kDaikinFanAuto or kDaikinFanQuiet
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRDaikin152::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRDaikin152::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setPowerful()

+ +
+
+ + + + + + + + +
void IRDaikin152::setPowerful (const bool on)
+
+ +

Set the Powerful (Turbo) mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setQuiet()

+ +
+
+ + + + + + + + +
void IRDaikin152::setQuiet (const bool on)
+
+ +

Set the Quiet mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRDaikin152::setRaw (const uint8_t new_code[])
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]new_codeA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSensor()

+ +
+
+ + + + + + + + +
void IRDaikin152::setSensor (const bool on)
+
+ +

Set the Sensor mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwingV()

+ +
+
+ + + + + + + + +
void IRDaikin152::setSwingV (const bool on)
+
+ +

Set the Vertical Swing mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRDaikin152::setTemp (const uint8_t temp)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]tempThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + +
+ + + + + + + +
void IRDaikin152::stateReset ()
+
+private
+
+ +

Reset the internal state to a fixed known good state.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRDaikin152::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRDaikin152::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRDaikin152::validChecksum (uint8_t state[],
const uint16_t length = kDaikin152StateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length of the state array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRDaikin152::_irsend
+
+private
+
+ +

instance of the IR send class

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRDaikin152::remote_state[kDaikin152StateLength]
+
+private
+
+ +

The state of the IR remote.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152__coll__graph.map new file mode 100644 index 000000000..e246fb533 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152__coll__graph.md5 new file mode 100644 index 000000000..193be7839 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152__coll__graph.md5 @@ -0,0 +1 @@ +3bbfb60d234bb57df5106a32f8aecca3 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152__coll__graph.png new file mode 100644 index 000000000..cf4e791ca Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin152__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160-members.html new file mode 100644 index 000000000..70a4643d6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160-members.html @@ -0,0 +1,108 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRDaikin160 Member List
+
+
+ +

This is the complete list of members for IRDaikin160, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRDaikin160private
begin()IRDaikin160
calibrate(void)IRDaikin160inline
checksum()IRDaikin160private
convertFan(const stdAc::fanspeed_t speed)IRDaikin160static
convertMode(const stdAc::opmode_t mode)IRDaikin160static
convertSwingV(const stdAc::swingv_t position)IRDaikin160static
getFan(void)IRDaikin160
getMode(void)IRDaikin160
getPower(void)IRDaikin160
getRaw()IRDaikin160
getSwingVertical(void)IRDaikin160
getTemp()IRDaikin160
IRDaikin160(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRDaikin160explicit
off(void)IRDaikin160
on(void)IRDaikin160
remote_stateIRDaikin160private
send(const uint16_t repeat=kDaikin160DefaultRepeat)IRDaikin160
setFan(const uint8_t fan)IRDaikin160
setMode(const uint8_t mode)IRDaikin160
setPower(const bool on)IRDaikin160
setRaw(const uint8_t new_code[])IRDaikin160
setSwingVertical(const uint8_t position)IRDaikin160
setTemp(const uint8_t temp)IRDaikin160
stateReset()IRDaikin160private
toCommon(void)IRDaikin160
toCommonSwingV(const uint8_t setting)IRDaikin160static
toString(void)IRDaikin160
validChecksum(uint8_t state[], const uint16_t length=kDaikin160StateLength)IRDaikin160static
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160.html new file mode 100644 index 000000000..b69401604 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160.html @@ -0,0 +1,983 @@ + + + + + + + +IRremoteESP8266: IRDaikin160 Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Daikin 160-bit A/C messages. + More...

+ +

#include <ir_Daikin.h>

+
+Collaboration diagram for IRDaikin160:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRDaikin160 (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void send (const uint16_t repeat=kDaikin160DefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin ()
 Set up hardware to be able to send a message. More...
 
uint8_t * getRaw ()
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t new_code[])
 Set the internal state from a valid code for this protocol. More...
 
void on (void)
 Change the power setting to On. More...
 
void off (void)
 Change the power setting to Off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp ()
 Get the current temperature setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setFan (const uint8_t fan)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setSwingVertical (const uint8_t position)
 Set the Vertical Swing mode of the A/C. More...
 
uint8_t getSwingVertical (void)
 Get the Vertical Swing mode of the A/C. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (uint8_t state[], const uint16_t length=kDaikin160StateLength)
 Verify the checksum is valid for a given state. More...
 
static uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
static uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
static uint8_t convertSwingV (const stdAc::swingv_t position)
 Convert a stdAc::swingv_t enum into it's native setting. More...
 
static stdAc::swingv_t toCommonSwingV (const uint8_t setting)
 Convert a native vertical swing postion to it's common equivalent. More...
 
+ + + + + + + +

+Private Member Functions

void stateReset ()
 Reset the internal state to a fixed known good state. More...
 
void checksum ()
 Calculate and set the checksum values for the internal state. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 instance of the IR send class More...
 
uint8_t remote_state [kDaikin160StateLength]
 The state of the IR remote. More...
 
+

Detailed Description

+

Class for handling detailed Daikin 160-bit A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRDaikin160()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRDaikin160::IRDaikin160 (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + +
void IRDaikin160::begin ()
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRDaikin160::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
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.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + +
void IRDaikin160::checksum ()
+
+private
+
+ +

Calculate and set the checksum values for the internal state.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikin160::convertFan (const stdAc::fanspeed_t speed)
+
+static
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikin160::convertMode (const stdAc::opmode_t mode)
+
+static
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertSwingV()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikin160::convertSwingV (const stdAc::swingv_t position)
+
+static
+
+ +

Convert a stdAc::swingv_t enum into it's native setting.

+
Parameters
+ + +
[in]positionThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRDaikin160::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRDaikin160::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRDaikin160::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + +
uint8_t * IRDaikin160::getRaw ()
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSwingVertical()

+ +
+
+ + + + + + + + +
uint8_t IRDaikin160::getSwingVertical (void )
+
+ +

Get the Vertical Swing mode of the A/C.

+
Returns
The native position/mode setting.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + +
uint8_t IRDaikin160::getTemp ()
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRDaikin160::off (void )
+
+ +

Change the power setting to Off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRDaikin160::on (void )
+
+ +

Change the power setting to On.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRDaikin160::send (const uint16_t repeat = kDaikin160DefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRDaikin160::setFan (const uint8_t fan)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]fanThe desired setting.
+
+
+
Note
1-5 or kDaikinFanAuto or kDaikinFanQuiet
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRDaikin160::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRDaikin160::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRDaikin160::setRaw (const uint8_t new_code[])
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]new_codeA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSwingVertical()

+ +
+
+ + + + + + + + +
void IRDaikin160::setSwingVertical (const uint8_t position)
+
+ +

Set the Vertical Swing mode of the A/C.

+
Parameters
+ + +
[in]positionThe position/mode to set the swing to.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRDaikin160::setTemp (const uint8_t temp)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]tempThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + +
+ + + + + + + +
void IRDaikin160::stateReset ()
+
+private
+
+ +

Reset the internal state to a fixed known good state.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRDaikin160::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonSwingV()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::swingv_t IRDaikin160::toCommonSwingV (const uint8_t setting)
+
+static
+
+ +

Convert a native vertical swing postion to it's common equivalent.

+
Parameters
+ + +
[in]settingA native position to convert.
+
+
+
Returns
The common vertical swing position.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRDaikin160::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRDaikin160::validChecksum (uint8_t state[],
const uint16_t length = kDaikin160StateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length of the state array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRDaikin160::_irsend
+
+private
+
+ +

instance of the IR send class

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRDaikin160::remote_state[kDaikin160StateLength]
+
+private
+
+ +

The state of the IR remote.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160__coll__graph.map new file mode 100644 index 000000000..0a46ed86a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160__coll__graph.md5 new file mode 100644 index 000000000..dadb00bba --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160__coll__graph.md5 @@ -0,0 +1 @@ +fbc66f5a6991bf58f0872d9bbb55a5da \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160__coll__graph.png new file mode 100644 index 000000000..4646db8e9 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin160__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin176-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin176-members.html new file mode 100644 index 000000000..788d1c8b6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin176-members.html @@ -0,0 +1,111 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRDaikin176 Member List
+
+
+ +

This is the complete list of members for IRDaikin176, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRDaikin176private
_saved_tempIRDaikin176private
begin()IRDaikin176
calibrate(void)IRDaikin176inline
checksum()IRDaikin176private
convertFan(const stdAc::fanspeed_t speed)IRDaikin176static
convertMode(const stdAc::opmode_t mode)IRDaikin176static
convertSwingH(const stdAc::swingh_t position)IRDaikin176static
getFan(void)IRDaikin176
getMode(void)IRDaikin176
getPower(void)IRDaikin176
getRaw()IRDaikin176
getSwingHorizontal(void)IRDaikin176
getTemp()IRDaikin176
IRDaikin176(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRDaikin176explicit
off(void)IRDaikin176
on(void)IRDaikin176
remote_stateIRDaikin176private
send(const uint16_t repeat=kDaikin176DefaultRepeat)IRDaikin176
setFan(const uint8_t fan)IRDaikin176
setMode(const uint8_t mode)IRDaikin176
setPower(const bool on)IRDaikin176
setRaw(const uint8_t new_code[])IRDaikin176
setSwingHorizontal(const uint8_t position)IRDaikin176
setTemp(const uint8_t temp)IRDaikin176
stateReset()IRDaikin176private
toCommon(void)IRDaikin176
toCommonFanSpeed(const uint8_t speed)IRDaikin176static
toCommonMode(const uint8_t mode)IRDaikin176static
toCommonSwingH(const uint8_t setting)IRDaikin176static
toString(void)IRDaikin176
validChecksum(uint8_t state[], const uint16_t length=kDaikin176StateLength)IRDaikin176static
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin176.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin176.html new file mode 100644 index 000000000..739f5c3a3 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin176.html @@ -0,0 +1,1083 @@ + + + + + + + +IRremoteESP8266: IRDaikin176 Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Daikin 176-bit A/C messages. + More...

+ +

#include <ir_Daikin.h>

+
+Collaboration diagram for IRDaikin176:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRDaikin176 (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void send (const uint16_t repeat=kDaikin176DefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin ()
 Set up hardware to be able to send a message. More...
 
uint8_t * getRaw ()
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t new_code[])
 Set the internal state from a valid code for this protocol. More...
 
void on (void)
 Change the power setting to On. More...
 
void off (void)
 Change the power setting to Off.. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp ()
 Get the current temperature setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setFan (const uint8_t fan)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setSwingHorizontal (const uint8_t position)
 Set the Horizontal Swing mode of the A/C. More...
 
uint8_t getSwingHorizontal (void)
 Get the Horizontal Swing mode of the A/C. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + + + + + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (uint8_t state[], const uint16_t length=kDaikin176StateLength)
 Verify the checksum is valid for a given state. More...
 
static uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
static uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
static uint8_t convertSwingH (const stdAc::swingh_t position)
 Convert a stdAc::swingh_t enum into it's native setting. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::swingh_t toCommonSwingH (const uint8_t setting)
 Convert a native horizontal swing postion to it's common equivalent. More...
 
+ + + + + + + +

+Private Member Functions

void stateReset ()
 Reset the internal state to a fixed known good state. More...
 
void checksum ()
 Calculate and set the checksum values for the internal state. More...
 
+ + + + + + + + + +

+Private Attributes

IRsend _irsend
 instance of the IR send class More...
 
uint8_t remote_state [kDaikin176StateLength]
 The state of the IR remote. More...
 
uint8_t _saved_temp
 
+

Detailed Description

+

Class for handling detailed Daikin 176-bit A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRDaikin176()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRDaikin176::IRDaikin176 (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + +
void IRDaikin176::begin ()
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRDaikin176::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
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.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + +
void IRDaikin176::checksum ()
+
+private
+
+ +

Calculate and set the checksum values for the internal state.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikin176::convertFan (const stdAc::fanspeed_t speed)
+
+static
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikin176::convertMode (const stdAc::opmode_t mode)
+
+static
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertSwingH()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikin176::convertSwingH (const stdAc::swingh_t position)
+
+static
+
+ +

Convert a stdAc::swingh_t enum into it's native setting.

+
Parameters
+ + +
[in]positionThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRDaikin176::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRDaikin176::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRDaikin176::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + +
uint8_t * IRDaikin176::getRaw ()
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSwingHorizontal()

+ +
+
+ + + + + + + + +
uint8_t IRDaikin176::getSwingHorizontal (void )
+
+ +

Get the Horizontal Swing mode of the A/C.

+
Returns
The native position/mode setting.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + +
uint8_t IRDaikin176::getTemp ()
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRDaikin176::off (void )
+
+ +

Change the power setting to Off..

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRDaikin176::on (void )
+
+ +

Change the power setting to On.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRDaikin176::send (const uint16_t repeat = kDaikin176DefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRDaikin176::setFan (const uint8_t fan)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]fanThe desired setting.
+
+
+
Note
1 for Min or 3 for Max
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRDaikin176::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRDaikin176::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRDaikin176::setRaw (const uint8_t new_code[])
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]new_codeA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSwingHorizontal()

+ +
+
+ + + + + + + + +
void IRDaikin176::setSwingHorizontal (const uint8_t position)
+
+ +

Set the Horizontal Swing mode of the A/C.

+
Parameters
+ + +
[in]positionThe position/mode to set the swing to.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRDaikin176::setTemp (const uint8_t temp)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]tempThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + +
+ + + + + + + +
void IRDaikin176::stateReset ()
+
+private
+
+ +

Reset the internal state to a fixed known good state.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRDaikin176::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRDaikin176::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRDaikin176::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonSwingH()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::swingh_t IRDaikin176::toCommonSwingH (const uint8_t setting)
+
+static
+
+ +

Convert a native horizontal swing postion to it's common equivalent.

+
Parameters
+ + +
[in]settingA native position to convert.
+
+
+
Returns
The common horizontal swing position.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRDaikin176::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRDaikin176::validChecksum (uint8_t state[],
const uint16_t length = kDaikin176StateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length of the state array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRDaikin176::_irsend
+
+private
+
+ +

instance of the IR send class

+ +
+
+ +

◆ _saved_temp

+ +
+
+ + + + + +
+ + + + +
uint8_t IRDaikin176::_saved_temp
+
+private
+
+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRDaikin176::remote_state[kDaikin176StateLength]
+
+private
+
+ +

The state of the IR remote.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin176__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin176__coll__graph.map new file mode 100644 index 000000000..f61dca56f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin176__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin176__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin176__coll__graph.md5 new file mode 100644 index 000000000..46c8fe910 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin176__coll__graph.md5 @@ -0,0 +1 @@ +e1b4fd7ddfe8c5ab5d5bb1cf9d344bc4 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin176__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin176__coll__graph.png new file mode 100644 index 000000000..44469aece Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin176__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2-members.html new file mode 100644 index 000000000..2dd3582dc --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2-members.html @@ -0,0 +1,152 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRDaikin2 Member List
+
+
+ +

This is the complete list of members for IRDaikin2, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRDaikin2private
begin()IRDaikin2
calibrate(void)IRDaikin2inline
checksum()IRDaikin2private
clearOnTimerFlag()IRDaikin2private
clearSleepTimerFlag()IRDaikin2private
convertFan(const stdAc::fanspeed_t speed)IRDaikin2static
convertMode(const stdAc::opmode_t mode)IRDaikin2static
convertSwingH(const stdAc::swingh_t position)IRDaikin2static
convertSwingV(const stdAc::swingv_t position)IRDaikin2static
disableOffTimer()IRDaikin2
disableOnTimer()IRDaikin2
disableSleepTimer()IRDaikin2
enableOffTimer(const uint16_t endtime)IRDaikin2
enableOnTimer(const uint16_t starttime)IRDaikin2
enableSleepTimer(const uint16_t sleeptime)IRDaikin2
getBeep()IRDaikin2
getClean()IRDaikin2
getCurrentTime()IRDaikin2
getEcono()IRDaikin2
getEye()IRDaikin2
getEyeAuto()IRDaikin2
getFan()IRDaikin2
getFreshAir()IRDaikin2
getFreshAirHigh()IRDaikin2
getLight()IRDaikin2
getMode()IRDaikin2
getMold()IRDaikin2
getOffTime()IRDaikin2
getOffTimerEnabled()IRDaikin2
getOnTime()IRDaikin2
getOnTimerEnabled()IRDaikin2
getPower()IRDaikin2
getPowerful()IRDaikin2
getPurify()IRDaikin2
getQuiet()IRDaikin2
getRaw()IRDaikin2
getSleepTime()IRDaikin2
getSleepTimerEnabled()IRDaikin2
getSwingHorizontal()IRDaikin2
getSwingVertical()IRDaikin2
getTemp()IRDaikin2
IRDaikin2(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRDaikin2explicit
off()IRDaikin2
on()IRDaikin2
remote_stateIRDaikin2private
send(const uint16_t repeat=kDaikin2DefaultRepeat)IRDaikin2
setBeep(const uint8_t beep)IRDaikin2
setClean(const bool on)IRDaikin2
setCurrentTime(const uint16_t time)IRDaikin2
setEcono(const bool on)IRDaikin2
setEye(const bool on)IRDaikin2
setEyeAuto(const bool on)IRDaikin2
setFan(const uint8_t fan)IRDaikin2
setFreshAir(const bool on)IRDaikin2
setFreshAirHigh(const bool on)IRDaikin2
setLight(const uint8_t light)IRDaikin2
setMode(const uint8_t mode)IRDaikin2
setMold(const bool on)IRDaikin2
setPower(const bool state)IRDaikin2
setPowerful(const bool on)IRDaikin2
setPurify(const bool on)IRDaikin2
setQuiet(const bool on)IRDaikin2
setRaw(const uint8_t new_code[])IRDaikin2
setSwingHorizontal(const uint8_t position)IRDaikin2
setSwingVertical(const uint8_t position)IRDaikin2
setTemp(const uint8_t temp)IRDaikin2
stateReset()IRDaikin2private
toCommon(void)IRDaikin2
toCommonSwingH(const uint8_t setting)IRDaikin2static
toCommonSwingV(const uint8_t setting)IRDaikin2static
toString()IRDaikin2
validChecksum(uint8_t state[], const uint16_t length=kDaikin2StateLength)IRDaikin2static
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2.html new file mode 100644 index 000000000..788948d02 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2.html @@ -0,0 +1,2133 @@ + + + + + + + +IRremoteESP8266: IRDaikin2 Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Daikin 312-bit A/C messages. Code by crankyoldgit, Reverse engineering analysis by sheppy99. + More...

+ +

#include <ir_Daikin.h>

+
+Collaboration diagram for IRDaikin2:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRDaikin2 (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void send (const uint16_t repeat=kDaikin2DefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin ()
 Set up hardware to be able to send a message. More...
 
void on ()
 Change the power setting to On. More...
 
void off ()
 Change the power setting to Off. More...
 
void setPower (const bool state)
 Change the power setting. More...
 
bool getPower ()
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp ()
 Get the current temperature setting. More...
 
void setFan (const uint8_t fan)
 Set the speed of the fan. More...
 
uint8_t getFan ()
 Get the current fan speed setting. More...
 
uint8_t getMode ()
 Get the operating mode setting of the A/C. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
void setSwingVertical (const uint8_t position)
 Set the Vertical Swing mode of the A/C. More...
 
uint8_t getSwingVertical ()
 Get the Vertical Swing mode of the A/C. More...
 
void setSwingHorizontal (const uint8_t position)
 Set the Horizontal Swing mode of the A/C. More...
 
uint8_t getSwingHorizontal ()
 Get the Horizontal Swing mode of the A/C. More...
 
bool getQuiet ()
 Get the Quiet mode status of the A/C. More...
 
void setQuiet (const bool on)
 Set the Quiet mode of the A/C. More...
 
bool getPowerful ()
 Get the Powerful (Turbo) mode of the A/C. More...
 
void setPowerful (const bool on)
 Set the Powerful (Turbo) mode of the A/C. More...
 
void setEcono (const bool on)
 Set the Economy mode of the A/C. More...
 
bool getEcono ()
 Get the Economical mode of the A/C. More...
 
void setEye (const bool on)
 Set the Eye (Sensor) mode of the A/C. More...
 
bool getEye ()
 Get the Eye (Sensor) mode status of the A/C. More...
 
void setEyeAuto (const bool on)
 Set the Automatic Eye (Sensor) mode of the A/C. More...
 
bool getEyeAuto ()
 Get the Automaitc Eye (Sensor) mode status of the A/C. More...
 
void setPurify (const bool on)
 Set the Purify (Filter) mode of the A/C. More...
 
bool getPurify ()
 Get the Purify (Filter) mode status of the A/C. More...
 
void setMold (const bool on)
 Set the Mould (filter) mode of the A/C. More...
 
bool getMold ()
 Get the Mould (filter) mode status of the A/C. More...
 
void enableOnTimer (const uint16_t starttime)
 Set the enable status & time of the On Timer. More...
 
void disableOnTimer ()
 Disable the On timer. More...
 
uint16_t getOnTime ()
 Get the On Timer time to be sent to the A/C unit. More...
 
bool getOnTimerEnabled ()
 Get the enable status of the On Timer. More...
 
void enableSleepTimer (const uint16_t sleeptime)
 Set the enable status & time of the Sleep Timer. More...
 
void disableSleepTimer ()
 Disable the sleep timer. More...
 
uint16_t getSleepTime ()
 Get the Sleep Timer time to be sent to the A/C unit. More...
 
bool getSleepTimerEnabled ()
 Get the Sleep timer enabled status of the A/C. More...
 
void enableOffTimer (const uint16_t endtime)
 Set the enable status & time of the Off Timer. More...
 
void disableOffTimer ()
 Disable the Off timer. More...
 
uint16_t getOffTime ()
 Get the Off Timer time to be sent to the A/C unit. More...
 
bool getOffTimerEnabled ()
 Get the enable status of the Off Timer. More...
 
void setCurrentTime (const uint16_t time)
 Set the clock on the A/C unit. More...
 
uint16_t getCurrentTime ()
 Get the clock time to be sent to the A/C unit. More...
 
void setBeep (const uint8_t beep)
 Set the Beep mode of the A/C. More...
 
uint8_t getBeep ()
 Get the Beep status of the A/C. More...
 
void setLight (const uint8_t light)
 Set the Light (LED) mode of the A/C. More...
 
uint8_t getLight ()
 Get the Light status of the A/C. More...
 
void setClean (const bool on)
 Set the Auto clean mode of the A/C. More...
 
bool getClean ()
 Get the Auto Clean mode status of the A/C. More...
 
void setFreshAir (const bool on)
 Set the Fresh Air mode of the A/C. More...
 
bool getFreshAir ()
 Get the Fresh Air mode status of the A/C. More...
 
void setFreshAirHigh (const bool on)
 Set the (High) Fresh Air mode of the A/C. More...
 
bool getFreshAirHigh ()
 Get the (High) Fresh Air mode status of the A/C. More...
 
uint8_t * getRaw ()
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t new_code[])
 Set the internal state from a valid code for this protocol. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString ()
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + + + + + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (uint8_t state[], const uint16_t length=kDaikin2StateLength)
 Verify the checksum is valid for a given state. More...
 
static uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
static uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
static uint8_t convertSwingV (const stdAc::swingv_t position)
 Convert a stdAc::swingv_t enum into it's native setting. More...
 
static uint8_t convertSwingH (const stdAc::swingh_t position)
 Convert a stdAc::swingh_t enum into it's native setting. More...
 
static stdAc::swingv_t toCommonSwingV (const uint8_t setting)
 Convert a native vertical swing postion to it's common equivalent. More...
 
static stdAc::swingh_t toCommonSwingH (const uint8_t setting)
 Convert a native horizontal swing postion to it's common equivalent. More...
 
+ + + + + + + + + + + + + +

+Private Member Functions

void stateReset ()
 Reset the internal state to a fixed known good state. More...
 
void checksum ()
 Calculate and set the checksum values for the internal state. More...
 
void clearOnTimerFlag ()
 Clear the On Timer flag. More...
 
void clearSleepTimerFlag ()
 Clear the sleep timer flag. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 instance of the IR send class More...
 
uint8_t remote_state [kDaikin2StateLength]
 The state of the IR remote. More...
 
+

Detailed Description

+

Class for handling detailed Daikin 312-bit A/C messages. Code by crankyoldgit, Reverse engineering analysis by sheppy99.

+

Constructor & Destructor Documentation

+ +

◆ IRDaikin2()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRDaikin2::IRDaikin2 (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + +
void IRDaikin2::begin ()
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRDaikin2::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
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.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + +
void IRDaikin2::checksum ()
+
+private
+
+ +

Calculate and set the checksum values for the internal state.

+ +
+
+ +

◆ clearOnTimerFlag()

+ +
+
+ + + + + +
+ + + + + + + +
void IRDaikin2::clearOnTimerFlag ()
+
+private
+
+ +

Clear the On Timer flag.

+ +
+
+ +

◆ clearSleepTimerFlag()

+ +
+
+ + + + + +
+ + + + + + + +
void IRDaikin2::clearSleepTimerFlag ()
+
+private
+
+ +

Clear the sleep timer flag.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikin2::convertFan (const stdAc::fanspeed_t speed)
+
+static
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikin2::convertMode (const stdAc::opmode_t mode)
+
+static
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertSwingH()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikin2::convertSwingH (const stdAc::swingh_t position)
+
+static
+
+ +

Convert a stdAc::swingh_t enum into it's native setting.

+
Parameters
+ + +
[in]positionThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertSwingV()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikin2::convertSwingV (const stdAc::swingv_t position)
+
+static
+
+ +

Convert a stdAc::swingv_t enum into it's native setting.

+
Parameters
+ + +
[in]positionThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ disableOffTimer()

+ +
+
+ + + + + + + +
void IRDaikin2::disableOffTimer ()
+
+ +

Disable the Off timer.

+ +
+
+ +

◆ disableOnTimer()

+ +
+
+ + + + + + + +
void IRDaikin2::disableOnTimer ()
+
+ +

Disable the On timer.

+ +
+
+ +

◆ disableSleepTimer()

+ +
+
+ + + + + + + +
void IRDaikin2::disableSleepTimer ()
+
+ +

Disable the sleep timer.

+ +
+
+ +

◆ enableOffTimer()

+ +
+
+ + + + + + + + +
void IRDaikin2::enableOffTimer (const uint16_t endtime)
+
+ +

Set the enable status & time of the Off Timer.

+
Parameters
+ + +
[in]endtimeThe number of minutes past midnight.
+
+
+ +
+
+ +

◆ enableOnTimer()

+ +
+
+ + + + + + + + +
void IRDaikin2::enableOnTimer (const uint16_t starttime)
+
+ +

Set the enable status & time of the On Timer.

+
Parameters
+ + +
[in]starttimeThe number of minutes past midnight.
+
+
+
Note
Timer location is shared with sleep timer.
+ +
+
+ +

◆ enableSleepTimer()

+ +
+
+ + + + + + + + +
void IRDaikin2::enableSleepTimer (const uint16_t sleeptime)
+
+ +

Set the enable status & time of the Sleep Timer.

+
Parameters
+ + +
[in]sleeptimeThe number of minutes past midnight.
+
+
+
Note
The Timer location is shared with On Timer.
+ +
+
+ +

◆ getBeep()

+ +
+
+ + + + + + + +
uint8_t IRDaikin2::getBeep ()
+
+ +

Get the Beep status of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getClean()

+ +
+
+ + + + + + + +
bool IRDaikin2::getClean ()
+
+ +

Get the Auto Clean mode status of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getCurrentTime()

+ +
+
+ + + + + + + +
uint16_t IRDaikin2::getCurrentTime ()
+
+ +

Get the clock time to be sent to the A/C unit.

+
Returns
The number of minutes past midnight.
+ +
+
+ +

◆ getEcono()

+ +
+
+ + + + + + + +
bool IRDaikin2::getEcono ()
+
+ +

Get the Economical mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getEye()

+ +
+
+ + + + + + + +
bool IRDaikin2::getEye ()
+
+ +

Get the Eye (Sensor) mode status of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getEyeAuto()

+ +
+
+ + + + + + + +
bool IRDaikin2::getEyeAuto ()
+
+ +

Get the Automaitc Eye (Sensor) mode status of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + +
uint8_t IRDaikin2::getFan ()
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getFreshAir()

+ +
+
+ + + + + + + +
bool IRDaikin2::getFreshAir ()
+
+ +

Get the Fresh Air mode status of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getFreshAirHigh()

+ +
+
+ + + + + + + +
bool IRDaikin2::getFreshAirHigh ()
+
+ +

Get the (High) Fresh Air mode status of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getLight()

+ +
+
+ + + + + + + +
uint8_t IRDaikin2::getLight ()
+
+ +

Get the Light status of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + +
uint8_t IRDaikin2::getMode ()
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getMold()

+ +
+
+ + + + + + + +
bool IRDaikin2::getMold ()
+
+ +

Get the Mould (filter) mode status of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getOffTime()

+ +
+
+ + + + + + + +
uint16_t IRDaikin2::getOffTime ()
+
+ +

Get the Off Timer time to be sent to the A/C unit.

+
Returns
The number of minutes past midnight.
+ +
+
+ +

◆ getOffTimerEnabled()

+ +
+
+ + + + + + + +
bool IRDaikin2::getOffTimerEnabled ()
+
+ +

Get the enable status of the Off Timer.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getOnTime()

+ +
+
+ + + + + + + +
uint16_t IRDaikin2::getOnTime ()
+
+ +

Get the On Timer time to be sent to the A/C unit.

+
Returns
The number of minutes past midnight.
+ +
+
+ +

◆ getOnTimerEnabled()

+ +
+
+ + + + + + + +
bool IRDaikin2::getOnTimerEnabled ()
+
+ +

Get the enable status of the On Timer.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + +
bool IRDaikin2::getPower ()
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getPowerful()

+ +
+
+ + + + + + + +
bool IRDaikin2::getPowerful ()
+
+ +

Get the Powerful (Turbo) mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getPurify()

+ +
+
+ + + + + + + +
bool IRDaikin2::getPurify ()
+
+ +

Get the Purify (Filter) mode status of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getQuiet()

+ +
+
+ + + + + + + +
bool IRDaikin2::getQuiet ()
+
+ +

Get the Quiet mode status of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + +
uint8_t * IRDaikin2::getRaw ()
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSleepTime()

+ +
+
+ + + + + + + +
uint16_t IRDaikin2::getSleepTime ()
+
+ +

Get the Sleep Timer time to be sent to the A/C unit.

+
Returns
The number of minutes past midnight.
+ +
+
+ +

◆ getSleepTimerEnabled()

+ +
+
+ + + + + + + +
bool IRDaikin2::getSleepTimerEnabled ()
+
+ +

Get the Sleep timer enabled status of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwingHorizontal()

+ +
+
+ + + + + + + +
uint8_t IRDaikin2::getSwingHorizontal ()
+
+ +

Get the Horizontal Swing mode of the A/C.

+
Returns
The native position/mode setting.
+ +
+
+ +

◆ getSwingVertical()

+ +
+
+ + + + + + + +
uint8_t IRDaikin2::getSwingVertical ()
+
+ +

Get the Vertical Swing mode of the A/C.

+
Returns
The native position/mode setting.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + +
uint8_t IRDaikin2::getTemp ()
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + +
void IRDaikin2::off ()
+
+ +

Change the power setting to Off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + +
void IRDaikin2::on ()
+
+ +

Change the power setting to On.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRDaikin2::send (const uint16_t repeat = kDaikin2DefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setBeep()

+ +
+
+ + + + + + + + +
void IRDaikin2::setBeep (const uint8_t beep)
+
+ +

Set the Beep mode of the A/C.

+
Parameters
+ + +
[in]beeptrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setClean()

+ +
+
+ + + + + + + + +
void IRDaikin2::setClean (const bool on)
+
+ +

Set the Auto clean mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setCurrentTime()

+ +
+
+ + + + + + + + +
void IRDaikin2::setCurrentTime (const uint16_t numMins)
+
+ +

Set the clock on the A/C unit.

+
Parameters
+ + +
[in]numMinsNr. of minutes past midnight.
+
+
+ +
+
+ +

◆ setEcono()

+ +
+
+ + + + + + + + +
void IRDaikin2::setEcono (const bool on)
+
+ +

Set the Economy mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setEye()

+ +
+
+ + + + + + + + +
void IRDaikin2::setEye (const bool on)
+
+ +

Set the Eye (Sensor) mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setEyeAuto()

+ +
+
+ + + + + + + + +
void IRDaikin2::setEyeAuto (const bool on)
+
+ +

Set the Automatic Eye (Sensor) mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRDaikin2::setFan (const uint8_t fan)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]fanThe desired setting.
+
+
+
Note
1-5 or kDaikinFanAuto or kDaikinFanQuiet
+ +
+
+ +

◆ setFreshAir()

+ +
+
+ + + + + + + + +
void IRDaikin2::setFreshAir (const bool on)
+
+ +

Set the Fresh Air mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setFreshAirHigh()

+ +
+
+ + + + + + + + +
void IRDaikin2::setFreshAirHigh (const bool on)
+
+ +

Set the (High) Fresh Air mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setLight()

+ +
+
+ + + + + + + + +
void IRDaikin2::setLight (const uint8_t light)
+
+ +

Set the Light (LED) mode of the A/C.

+
Parameters
+ + +
[in]lighttrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRDaikin2::setMode (const uint8_t desired_mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]desired_modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setMold()

+ +
+
+ + + + + + + + +
void IRDaikin2::setMold (const bool on)
+
+ +

Set the Mould (filter) mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRDaikin2::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setPowerful()

+ +
+
+ + + + + + + + +
void IRDaikin2::setPowerful (const bool on)
+
+ +

Set the Powerful (Turbo) mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setPurify()

+ +
+
+ + + + + + + + +
void IRDaikin2::setPurify (const bool on)
+
+ +

Set the Purify (Filter) mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setQuiet()

+ +
+
+ + + + + + + + +
void IRDaikin2::setQuiet (const bool on)
+
+ +

Set the Quiet mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRDaikin2::setRaw (const uint8_t new_code[])
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]new_codeA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSwingHorizontal()

+ +
+
+ + + + + + + + +
void IRDaikin2::setSwingHorizontal (const uint8_t position)
+
+ +

Set the Horizontal Swing mode of the A/C.

+
Parameters
+ + +
[in]positionThe position/mode to set the swing to.
+
+
+ +
+
+ +

◆ setSwingVertical()

+ +
+
+ + + + + + + + +
void IRDaikin2::setSwingVertical (const uint8_t position)
+
+ +

Set the Vertical Swing mode of the A/C.

+
Parameters
+ + +
[in]positionThe position/mode to set the swing to.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRDaikin2::setTemp (const uint8_t desired)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]desiredThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + +
+ + + + + + + +
void IRDaikin2::stateReset ()
+
+private
+
+ +

Reset the internal state to a fixed known good state.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRDaikin2::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonSwingH()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::swingh_t IRDaikin2::toCommonSwingH (const uint8_t setting)
+
+static
+
+ +

Convert a native horizontal swing postion to it's common equivalent.

+
Parameters
+ + +
[in]settingA native position to convert.
+
+
+
Returns
The common horizontal swing position.
+ +
+
+ +

◆ toCommonSwingV()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::swingv_t IRDaikin2::toCommonSwingV (const uint8_t setting)
+
+static
+
+ +

Convert a native vertical swing postion to it's common equivalent.

+
Parameters
+ + +
[in]settingA native position to convert.
+
+
+
Returns
The common vertical swing position.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + +
String IRDaikin2::toString ()
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRDaikin2::validChecksum (uint8_t state[],
const uint16_t length = kDaikin2StateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length of the state array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRDaikin2::_irsend
+
+private
+
+ +

instance of the IR send class

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRDaikin2::remote_state[kDaikin2StateLength]
+
+private
+
+ +

The state of the IR remote.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216-members.html new file mode 100644 index 000000000..5ee15e07e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216-members.html @@ -0,0 +1,112 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRDaikin216 Member List
+
+
+ +

This is the complete list of members for IRDaikin216, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRDaikin216private
begin()IRDaikin216
calibrate(void)IRDaikin216inline
checksum()IRDaikin216private
convertFan(const stdAc::fanspeed_t speed)IRDaikin216static
convertMode(const stdAc::opmode_t mode)IRDaikin216static
getFan(void)IRDaikin216
getMode(void)IRDaikin216
getPower(void)IRDaikin216
getPowerful(void)IRDaikin216
getQuiet(void)IRDaikin216
getRaw()IRDaikin216
getSwingHorizontal(void)IRDaikin216
getSwingVertical(void)IRDaikin216
getTemp()IRDaikin216
IRDaikin216(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRDaikin216explicit
off(void)IRDaikin216
on(void)IRDaikin216
remote_stateIRDaikin216private
send(const uint16_t repeat=kDaikin216DefaultRepeat)IRDaikin216
setFan(const uint8_t fan)IRDaikin216
setMode(const uint8_t mode)IRDaikin216
setPower(const bool on)IRDaikin216
setPowerful(const bool on)IRDaikin216
setQuiet(const bool on)IRDaikin216
setRaw(const uint8_t new_code[])IRDaikin216
setSwingHorizontal(const bool on)IRDaikin216
setSwingVertical(const bool on)IRDaikin216
setTemp(const uint8_t temp)IRDaikin216
stateReset()IRDaikin216private
toCommon(void)IRDaikin216
toString(void)IRDaikin216
validChecksum(uint8_t state[], const uint16_t length=kDaikin216StateLength)IRDaikin216static
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216.html new file mode 100644 index 000000000..d4e05e872 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216.html @@ -0,0 +1,1068 @@ + + + + + + + +IRremoteESP8266: IRDaikin216 Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Daikin 216-bit A/C messages. + More...

+ +

#include <ir_Daikin.h>

+
+Collaboration diagram for IRDaikin216:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRDaikin216 (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class Constructor. More...
 
void send (const uint16_t repeat=kDaikin216DefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin ()
 Set up hardware to be able to send a message. More...
 
uint8_t * getRaw ()
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t new_code[])
 Set the internal state from a valid code for this protocol. More...
 
void on (void)
 Change the power setting to On. More...
 
void off (void)
 Change the power setting to Off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp ()
 Get the current temperature setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setFan (const uint8_t fan)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setSwingVertical (const bool on)
 Set the Vertical Swing mode of the A/C. More...
 
bool getSwingVertical (void)
 Get the Vertical Swing mode of the A/C. More...
 
void setSwingHorizontal (const bool on)
 Set the Horizontal Swing mode of the A/C. More...
 
bool getSwingHorizontal (void)
 Get the Horizontal Swing mode of the A/C. More...
 
void setQuiet (const bool on)
 Set the Quiet mode of the A/C. More...
 
bool getQuiet (void)
 Get the Quiet mode status of the A/C. More...
 
void setPowerful (const bool on)
 Set the Powerful (Turbo) mode of the A/C. More...
 
bool getPowerful (void)
 Get the Powerful (Turbo) mode of the A/C. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (uint8_t state[], const uint16_t length=kDaikin216StateLength)
 Verify the checksum is valid for a given state. More...
 
static uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
static uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
+ + + + + + + +

+Private Member Functions

void stateReset ()
 Reset the internal state to a fixed known good state. More...
 
void checksum ()
 Calculate and set the checksum values for the internal state. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 instance of the IR send class More...
 
uint8_t remote_state [kDaikin216StateLength]
 The state of the IR remote. More...
 
+

Detailed Description

+

Class for handling detailed Daikin 216-bit A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRDaikin216()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRDaikin216::IRDaikin216 (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class Constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + +
void IRDaikin216::begin ()
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRDaikin216::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
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.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + +
void IRDaikin216::checksum ()
+
+private
+
+ +

Calculate and set the checksum values for the internal state.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikin216::convertFan (const stdAc::fanspeed_t speed)
+
+static
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikin216::convertMode (const stdAc::opmode_t mode)
+
+static
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRDaikin216::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRDaikin216::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRDaikin216::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getPowerful()

+ +
+
+ + + + + + + + +
bool IRDaikin216::getPowerful (void )
+
+ +

Get the Powerful (Turbo) mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getQuiet()

+ +
+
+ + + + + + + + +
bool IRDaikin216::getQuiet (void )
+
+ +

Get the Quiet mode status of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+
Note
This is a horrible hack till someone works out the quiet mode bit.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + +
uint8_t * IRDaikin216::getRaw ()
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSwingHorizontal()

+ +
+
+ + + + + + + + +
bool IRDaikin216::getSwingHorizontal (void )
+
+ +

Get the Horizontal Swing mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwingVertical()

+ +
+
+ + + + + + + + +
bool IRDaikin216::getSwingVertical (void )
+
+ +

Get the Vertical Swing mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + +
uint8_t IRDaikin216::getTemp ()
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRDaikin216::off (void )
+
+ +

Change the power setting to Off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRDaikin216::on (void )
+
+ +

Change the power setting to On.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRDaikin216::send (const uint16_t repeat = kDaikin216DefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRDaikin216::setFan (const uint8_t fan)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]fanThe desired setting.
+
+
+
Note
1-5 or kDaikinFanAuto or kDaikinFanQuiet
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRDaikin216::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRDaikin216::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setPowerful()

+ +
+
+ + + + + + + + +
void IRDaikin216::setPowerful (const bool on)
+
+ +

Set the Powerful (Turbo) mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setQuiet()

+ +
+
+ + + + + + + + +
void IRDaikin216::setQuiet (const bool on)
+
+ +

Set the Quiet mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+
Note
This is a horrible hack till someone works out the quiet mode bit.
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRDaikin216::setRaw (const uint8_t new_code[])
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]new_codeA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSwingHorizontal()

+ +
+
+ + + + + + + + +
void IRDaikin216::setSwingHorizontal (const bool on)
+
+ +

Set the Horizontal Swing mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwingVertical()

+ +
+
+ + + + + + + + +
void IRDaikin216::setSwingVertical (const bool on)
+
+ +

Set the Vertical Swing mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRDaikin216::setTemp (const uint8_t temp)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]tempThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + +
+ + + + + + + +
void IRDaikin216::stateReset ()
+
+private
+
+ +

Reset the internal state to a fixed known good state.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRDaikin216::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRDaikin216::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRDaikin216::validChecksum (uint8_t state[],
const uint16_t length = kDaikin216StateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length of the state array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRDaikin216::_irsend
+
+private
+
+ +

instance of the IR send class

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRDaikin216::remote_state[kDaikin216StateLength]
+
+private
+
+ +

The state of the IR remote.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216__coll__graph.map new file mode 100644 index 000000000..a2be3b0a2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216__coll__graph.md5 new file mode 100644 index 000000000..8b015e855 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216__coll__graph.md5 @@ -0,0 +1 @@ +376e63c140c9b990fbd05013138184b0 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216__coll__graph.png new file mode 100644 index 000000000..40e2871ef Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin216__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2__coll__graph.map new file mode 100644 index 000000000..b57955f2c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2__coll__graph.md5 new file mode 100644 index 000000000..73f0805f7 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2__coll__graph.md5 @@ -0,0 +1 @@ +3ef4da6c50362fb01d8d40a3983c3439 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2__coll__graph.png new file mode 100644 index 000000000..a8a2b148e Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin2__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin64-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin64-members.html new file mode 100644 index 000000000..dc600b3b2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin64-members.html @@ -0,0 +1,123 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRDaikin64 Member List
+
+
+ +

This is the complete list of members for IRDaikin64, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRDaikin64private
begin()IRDaikin64
calcChecksum(const uint64_t state)IRDaikin64static
calibrate(void)IRDaikin64inline
checksum()IRDaikin64private
convertFan(const stdAc::fanspeed_t speed)IRDaikin64static
convertMode(const stdAc::opmode_t mode)IRDaikin64static
getClock(void)IRDaikin64
getFan(void)IRDaikin64
getMode(void)IRDaikin64
getOffTime(void)IRDaikin64
getOffTimeEnabled(void)IRDaikin64
getOnTime(void)IRDaikin64
getOnTimeEnabled(void)IRDaikin64
getPowerToggle(void)IRDaikin64
getQuiet(void)IRDaikin64
getRaw()IRDaikin64
getSleep(void)IRDaikin64
getSwingVertical(void)IRDaikin64
getTemp()IRDaikin64
getTurbo(void)IRDaikin64
IRDaikin64(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRDaikin64explicit
remote_stateIRDaikin64private
send(const uint16_t repeat=kDaikin64DefaultRepeat)IRDaikin64
setClock(const uint16_t mins_since_midnight)IRDaikin64
setFan(const uint8_t fan)IRDaikin64
setMode(const uint8_t mode)IRDaikin64
setOffTime(const uint16_t mins_since_midnight)IRDaikin64
setOffTimeEnabled(const bool on)IRDaikin64
setOnTime(const uint16_t mins_since_midnight)IRDaikin64
setOnTimeEnabled(const bool on)IRDaikin64
setPowerToggle(const bool on)IRDaikin64
setQuiet(const bool on)IRDaikin64
setRaw(const uint64_t new_state)IRDaikin64
setSleep(const bool on)IRDaikin64
setSwingVertical(const bool on)IRDaikin64
setTemp(const uint8_t temp)IRDaikin64
setTurbo(const bool on)IRDaikin64
stateReset()IRDaikin64private
toCommon(const stdAc::state_t *prev=NULL)IRDaikin64
toCommonFanSpeed(const uint8_t speed)IRDaikin64static
toCommonMode(const uint8_t mode)IRDaikin64static
toString(void)IRDaikin64
validChecksum(const uint64_t state)IRDaikin64static
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin64.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin64.html new file mode 100644 index 000000000..b3a860c52 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin64.html @@ -0,0 +1,1393 @@ + + + + + + + +IRremoteESP8266: IRDaikin64 Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Daikin 64-bit A/C messages. + More...

+ +

#include <ir_Daikin.h>

+
+Collaboration diagram for IRDaikin64:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRDaikin64 (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void send (const uint16_t repeat=kDaikin64DefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin ()
 Set up hardware to be able to send a message. More...
 
uint64_t getRaw ()
 Get a copy of the internal state as a valid code for this protocol. More...
 
void setRaw (const uint64_t new_state)
 Set the internal state from a valid code for this protocol. More...
 
void setPowerToggle (const bool on)
 Set the Power toggle setting of the A/C. More...
 
bool getPowerToggle (void)
 Get the Power toggle setting of the A/C. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp ()
 Get the current temperature setting. More...
 
void setFan (const uint8_t fan)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setSwingVertical (const bool on)
 Set the Vertical Swing mode of the A/C. More...
 
bool getSwingVertical (void)
 Get the Vertical Swing mode of the A/C. More...
 
void setSleep (const bool on)
 Set the Sleep mode of the A/C. More...
 
bool getSleep (void)
 Get the Sleep mode of the A/C. More...
 
bool getQuiet (void)
 Get the Quiet mode status of the A/C. More...
 
void setQuiet (const bool on)
 Set the Quiet mode of the A/C. More...
 
bool getTurbo (void)
 Get the Turbo (Powerful) mode status of the A/C. More...
 
void setTurbo (const bool on)
 Set the Turbo (Powerful) mode of the A/C. More...
 
void setClock (const uint16_t mins_since_midnight)
 Set the clock on the A/C unit. More...
 
uint16_t getClock (void)
 Get the clock time to be sent to the A/C unit. More...
 
void setOnTimeEnabled (const bool on)
 Set the enable status of the On Timer. More...
 
bool getOnTimeEnabled (void)
 Get the enable status of the On Timer. More...
 
void setOnTime (const uint16_t mins_since_midnight)
 Set the On Timer time for the A/C unit. More...
 
uint16_t getOnTime (void)
 Get the On Timer time to be sent to the A/C unit. More...
 
void setOffTimeEnabled (const bool on)
 Set the enable status of the Off Timer. More...
 
bool getOffTimeEnabled (void)
 Get the enable status of the Off Timer. More...
 
void setOffTime (const uint16_t mins_since_midnight)
 Set the Off Timer time for the A/C unit. More...
 
uint16_t getOffTime (void)
 Get the Off Timer time to be sent to the A/C unit. More...
 
stdAc::state_t toCommon (const stdAc::state_t *prev=NULL)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + + + + + + + + + + +

+Static Public Member Functions

static uint8_t calcChecksum (const uint64_t state)
 Calculate the checksum for a given state. More...
 
static bool validChecksum (const uint64_t state)
 Verify the checksum is valid for a given state. More...
 
static uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
static uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + + + + +

+Private Member Functions

void stateReset ()
 Reset the internal state to a fixed known good state. More...
 
void checksum ()
 Calculate and set the checksum values for the internal state. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 instance of the IR send class More...
 
uint64_t remote_state
 The state of the IR remote. More...
 
+

Detailed Description

+

Class for handling detailed Daikin 64-bit A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRDaikin64()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRDaikin64::IRDaikin64 (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + +
void IRDaikin64::begin ()
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calcChecksum()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikin64::calcChecksum (const uint64_t state)
+
+static
+
+ +

Calculate the checksum for a given state.

+
Parameters
+ + +
[in]stateThe value to calc the checksum of.
+
+
+
Returns
The 4-bit checksum stored in a uint_8.
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRDaikin64::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
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.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + +
void IRDaikin64::checksum ()
+
+private
+
+ +

Calculate and set the checksum values for the internal state.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikin64::convertFan (const stdAc::fanspeed_t speed)
+
+static
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikin64::convertMode (const stdAc::opmode_t mode)
+
+static
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getClock()

+ +
+
+ + + + + + + + +
uint16_t IRDaikin64::getClock (void )
+
+ +

Get the clock time to be sent to the A/C unit.

+
Returns
The number of minutes past midnight.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRDaikin64::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRDaikin64::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getOffTime()

+ +
+
+ + + + + + + + +
uint16_t IRDaikin64::getOffTime (void )
+
+ +

Get the Off Timer time to be sent to the A/C unit.

+
Returns
The number of minutes past midnight.
+ +
+
+ +

◆ getOffTimeEnabled()

+ +
+
+ + + + + + + + +
bool IRDaikin64::getOffTimeEnabled (void )
+
+ +

Get the enable status of the Off Timer.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getOnTime()

+ +
+
+ + + + + + + + +
uint16_t IRDaikin64::getOnTime (void )
+
+ +

Get the On Timer time to be sent to the A/C unit.

+
Returns
The number of minutes past midnight.
+ +
+
+ +

◆ getOnTimeEnabled()

+ +
+
+ + + + + + + + +
bool IRDaikin64::getOnTimeEnabled (void )
+
+ +

Get the enable status of the On Timer.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getPowerToggle()

+ +
+
+ + + + + + + + +
bool IRDaikin64::getPowerToggle (void )
+
+ +

Get the Power toggle setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getQuiet()

+ +
+
+ + + + + + + + +
bool IRDaikin64::getQuiet (void )
+
+ +

Get the Quiet mode status of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + +
uint64_t IRDaikin64::getRaw ()
+
+ +

Get a copy of the internal state as a valid code for this protocol.

+
Returns
A valid code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSleep()

+ +
+
+ + + + + + + + +
bool IRDaikin64::getSleep (void )
+
+ +

Get the Sleep mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwingVertical()

+ +
+
+ + + + + + + + +
bool IRDaikin64::getSwingVertical (void )
+
+ +

Get the Vertical Swing mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + +
uint8_t IRDaikin64::getTemp ()
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ getTurbo()

+ +
+
+ + + + + + + + +
bool IRDaikin64::getTurbo (void )
+
+ +

Get the Turbo (Powerful) mode status of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRDaikin64::send (const uint16_t repeat = kDaikin64DefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setClock()

+ +
+
+ + + + + + + + +
void IRDaikin64::setClock (const uint16_t mins_since_midnight)
+
+ +

Set the clock on the A/C unit.

+
Parameters
+ + +
[in]mins_since_midnightNr. of minutes past midnight.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRDaikin64::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRDaikin64::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setOffTime()

+ +
+
+ + + + + + + + +
void IRDaikin64::setOffTime (const uint16_t mins_since_midnight)
+
+ +

Set the Off Timer time for the A/C unit.

+
Parameters
+ + +
[in]mins_since_midnightNr. of minutes past midnight.
+
+
+ +
+
+ +

◆ setOffTimeEnabled()

+ +
+
+ + + + + + + + +
void IRDaikin64::setOffTimeEnabled (const bool on)
+
+ +

Set the enable status of the Off Timer.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setOnTime()

+ +
+
+ + + + + + + + +
void IRDaikin64::setOnTime (const uint16_t mins_since_midnight)
+
+ +

Set the On Timer time for the A/C unit.

+
Parameters
+ + +
[in]mins_since_midnightNr. of minutes past midnight.
+
+
+ +
+
+ +

◆ setOnTimeEnabled()

+ +
+
+ + + + + + + + +
void IRDaikin64::setOnTimeEnabled (const bool on)
+
+ +

Set the enable status of the On Timer.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setPowerToggle()

+ +
+
+ + + + + + + + +
void IRDaikin64::setPowerToggle (const bool on)
+
+ +

Set the Power toggle setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setQuiet()

+ +
+
+ + + + + + + + +
void IRDaikin64::setQuiet (const bool on)
+
+ +

Set the Quiet mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRDaikin64::setRaw (const uint64_t new_state)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]new_stateA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSleep()

+ +
+
+ + + + + + + + +
void IRDaikin64::setSleep (const bool on)
+
+ +

Set the Sleep mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwingVertical()

+ +
+
+ + + + + + + + +
void IRDaikin64::setSwingVertical (const bool on)
+
+ +

Set the Vertical Swing mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRDaikin64::setTemp (const uint8_t temp)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]tempThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ setTurbo()

+ +
+
+ + + + + + + + +
void IRDaikin64::setTurbo (const bool on)
+
+ +

Set the Turbo (Powerful) mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + +
+ + + + + + + +
void IRDaikin64::stateReset ()
+
+private
+
+ +

Reset the internal state to a fixed known good state.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRDaikin64::toCommon (const stdAc::state_tprev = NULL)
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Parameters
+ + +
[in]prevPtr to a previous state.
+
+
+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRDaikin64::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRDaikin64::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRDaikin64::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + +
bool IRDaikin64::validChecksum (const uint64_t state)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + +
[in]stateThe state to verify the checksum of.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRDaikin64::_irsend
+
+private
+
+ +

instance of the IR send class

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint64_t IRDaikin64::remote_state
+
+private
+
+ +

The state of the IR remote.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin64__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin64__coll__graph.map new file mode 100644 index 000000000..ed3f71001 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin64__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin64__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin64__coll__graph.md5 new file mode 100644 index 000000000..40836ffaa --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin64__coll__graph.md5 @@ -0,0 +1 @@ +b2bb54fe62558d21dee90dc29baf242d \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin64__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin64__coll__graph.png new file mode 100644 index 000000000..b66057e11 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikin64__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikinESP-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikinESP-members.html new file mode 100644 index 000000000..8ef4d6ee9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikinESP-members.html @@ -0,0 +1,136 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRDaikinESP Member List
+
+
+ +

This is the complete list of members for IRDaikinESP, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRDaikinESPprivate
begin(void)IRDaikinESP
calibrate(void)IRDaikinESPinline
checksum(void)IRDaikinESPprivate
convertFan(const stdAc::fanspeed_t speed)IRDaikinESPstatic
convertMode(const stdAc::opmode_t mode)IRDaikinESPstatic
disableOffTimer(void)IRDaikinESP
disableOnTimer(void)IRDaikinESP
enableOffTimer(const uint16_t endtime)IRDaikinESP
enableOnTimer(const uint16_t starttime)IRDaikinESP
getComfort(void)IRDaikinESP
getCurrentDay(void)IRDaikinESP
getCurrentTime(void)IRDaikinESP
getEcono(void)IRDaikinESP
getFan(void)IRDaikinESP
getMode(void)IRDaikinESP
getMold(void)IRDaikinESP
getOffTime(void)IRDaikinESP
getOffTimerEnabled(void)IRDaikinESP
getOnTime(void)IRDaikinESP
getOnTimerEnabled()IRDaikinESP
getPower(void)IRDaikinESP
getPowerful(void)IRDaikinESP
getQuiet(void)IRDaikinESP
getRaw(void)IRDaikinESP
getSensor(void)IRDaikinESP
getSwingHorizontal(void)IRDaikinESP
getSwingVertical(void)IRDaikinESP
getTemp()IRDaikinESP
getWeeklyTimerEnable(void)IRDaikinESP
IRDaikinESP(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRDaikinESPexplicit
off(void)IRDaikinESP
on(void)IRDaikinESP
remoteIRDaikinESPprivate
send(const uint16_t repeat=kDaikinDefaultRepeat)IRDaikinESP
setComfort(const bool on)IRDaikinESP
setCurrentDay(const uint8_t day_of_week)IRDaikinESP
setCurrentTime(const uint16_t mins_since_midnight)IRDaikinESP
setEcono(const bool on)IRDaikinESP
setFan(const uint8_t fan)IRDaikinESP
setMode(const uint8_t mode)IRDaikinESP
setMold(const bool on)IRDaikinESP
setPower(const bool on)IRDaikinESP
setPowerful(const bool on)IRDaikinESP
setQuiet(const bool on)IRDaikinESP
setRaw(const uint8_t new_code[], const uint16_t length=kDaikinStateLength)IRDaikinESP
setSensor(const bool on)IRDaikinESP
setSwingHorizontal(const bool on)IRDaikinESP
setSwingVertical(const bool on)IRDaikinESP
setTemp(const uint8_t temp)IRDaikinESP
setWeeklyTimerEnable(const bool on)IRDaikinESP
stateReset(void)IRDaikinESPprivate
toCommon(void)IRDaikinESP
toCommonFanSpeed(const uint8_t speed)IRDaikinESPstatic
toCommonMode(const uint8_t mode)IRDaikinESPstatic
toString(void)IRDaikinESP
validChecksum(uint8_t state[], const uint16_t length=kDaikinStateLength)IRDaikinESPstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikinESP.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikinESP.html new file mode 100644 index 000000000..a8aab02cd --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikinESP.html @@ -0,0 +1,1729 @@ + + + + + + + +IRremoteESP8266: IRDaikinESP Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Daikin 280-bit A/C messages. + More...

+ +

#include <ir_Daikin.h>

+
+Collaboration diagram for IRDaikinESP:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRDaikinESP (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void send (const uint16_t repeat=kDaikinDefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Change the power setting to On. More...
 
void off (void)
 Change the power setting to Off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp ()
 Get the current temperature setting. More...
 
void setFan (const uint8_t fan)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setSwingVertical (const bool on)
 Set the Vertical Swing mode of the A/C. More...
 
bool getSwingVertical (void)
 Get the Vertical Swing mode of the A/C. More...
 
void setSwingHorizontal (const bool on)
 Set the Horizontal Swing mode of the A/C. More...
 
bool getSwingHorizontal (void)
 Get the Horizontal Swing mode of the A/C. More...
 
bool getQuiet (void)
 Get the Quiet mode status of the A/C. More...
 
void setQuiet (const bool on)
 Set the Quiet mode of the A/C. More...
 
bool getPowerful (void)
 Get the Powerful (Turbo) mode of the A/C. More...
 
void setPowerful (const bool on)
 Set the Powerful (Turbo) mode of the A/C. More...
 
void setSensor (const bool on)
 Set the Sensor mode of the A/C. More...
 
bool getSensor (void)
 Get the Sensor mode of the A/C. More...
 
void setEcono (const bool on)
 Set the Economy mode of the A/C. More...
 
bool getEcono (void)
 Get the Economical mode of the A/C. More...
 
void setMold (const bool on)
 Set the Mould mode of the A/C. More...
 
bool getMold (void)
 Get the Mould mode status of the A/C. More...
 
void setComfort (const bool on)
 Set the Comfort mode of the A/C. More...
 
bool getComfort (void)
 Get the Comfort mode of the A/C. More...
 
void enableOnTimer (const uint16_t starttime)
 Set the enable status & time of the On Timer. More...
 
void disableOnTimer (void)
 Clear and disable the On timer. More...
 
uint16_t getOnTime (void)
 Get the On Timer time to be sent to the A/C unit. More...
 
bool getOnTimerEnabled ()
 Get the enable status of the On Timer. More...
 
void enableOffTimer (const uint16_t endtime)
 Set the enable status & time of the Off Timer. More...
 
void disableOffTimer (void)
 Clear and disable the Off timer. More...
 
uint16_t getOffTime (void)
 Get the Off Timer time to be sent to the A/C unit. More...
 
bool getOffTimerEnabled (void)
 Get the enable status of the Off Timer. More...
 
void setCurrentTime (const uint16_t mins_since_midnight)
 Set the clock on the A/C unit. More...
 
uint16_t getCurrentTime (void)
 Get the clock time to be sent to the A/C unit. More...
 
void setCurrentDay (const uint8_t day_of_week)
 Set the current day of the week to be sent to the A/C unit. More...
 
uint8_t getCurrentDay (void)
 Get the current day of the week to be sent to the A/C unit. More...
 
void setWeeklyTimerEnable (const bool on)
 Set the enable status of the Weekly Timer. More...
 
bool getWeeklyTimerEnable (void)
 Get the enable status of the Weekly Timer. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t new_code[], const uint16_t length=kDaikinStateLength)
 Set the internal state from a valid code for this protocol. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (uint8_t state[], const uint16_t length=kDaikinStateLength)
 Verify the checksum is valid for a given state. More...
 
static uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
static uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + + + + +

+Private Member Functions

void stateReset (void)
 Reset the internal state to a fixed known good state. More...
 
void checksum (void)
 Calculate and set the checksum values for the internal state. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 instance of the IR send class More...
 
uint8_t remote [kDaikinStateLength]
 The state of the IR remote. More...
 
+

Detailed Description

+

Class for handling detailed Daikin 280-bit A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRDaikinESP()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRDaikinESP::IRDaikinESP (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRDaikinESP::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRDaikinESP::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
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.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRDaikinESP::checksum (void )
+
+private
+
+ +

Calculate and set the checksum values for the internal state.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikinESP::convertFan (const stdAc::fanspeed_t speed)
+
+static
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDaikinESP::convertMode (const stdAc::opmode_t mode)
+
+static
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ disableOffTimer()

+ +
+
+ + + + + + + + +
void IRDaikinESP::disableOffTimer (void )
+
+ +

Clear and disable the Off timer.

+ +
+
+ +

◆ disableOnTimer()

+ +
+
+ + + + + + + + +
void IRDaikinESP::disableOnTimer (void )
+
+ +

Clear and disable the On timer.

+ +
+
+ +

◆ enableOffTimer()

+ +
+
+ + + + + + + + +
void IRDaikinESP::enableOffTimer (const uint16_t endtime)
+
+ +

Set the enable status & time of the Off Timer.

+
Parameters
+ + +
[in]endtimeThe number of minutes past midnight.
+
+
+ +
+
+ +

◆ enableOnTimer()

+ +
+
+ + + + + + + + +
void IRDaikinESP::enableOnTimer (const uint16_t starttime)
+
+ +

Set the enable status & time of the On Timer.

+
Parameters
+ + +
[in]starttimeThe number of minutes past midnight.
+
+
+ +
+
+ +

◆ getComfort()

+ +
+
+ + + + + + + + +
bool IRDaikinESP::getComfort (void )
+
+ +

Get the Comfort mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getCurrentDay()

+ +
+
+ + + + + + + + +
uint8_t IRDaikinESP::getCurrentDay (void )
+
+ +

Get the current day of the week to be sent to the A/C unit.

+
Returns
The numerical representation of the day of the week.
+
Note
1 is SUN, 2 is MON, ..., 7 is SAT
+ +
+
+ +

◆ getCurrentTime()

+ +
+
+ + + + + + + + +
uint16_t IRDaikinESP::getCurrentTime (void )
+
+ +

Get the clock time to be sent to the A/C unit.

+
Returns
The number of minutes past midnight.
+ +
+
+ +

◆ getEcono()

+ +
+
+ + + + + + + + +
bool IRDaikinESP::getEcono (void )
+
+ +

Get the Economical mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRDaikinESP::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRDaikinESP::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getMold()

+ +
+
+ + + + + + + + +
bool IRDaikinESP::getMold (void )
+
+ +

Get the Mould mode status of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getOffTime()

+ +
+
+ + + + + + + + +
uint16_t IRDaikinESP::getOffTime (void )
+
+ +

Get the Off Timer time to be sent to the A/C unit.

+
Returns
The number of minutes past midnight.
+ +
+
+ +

◆ getOffTimerEnabled()

+ +
+
+ + + + + + + + +
bool IRDaikinESP::getOffTimerEnabled (void )
+
+ +

Get the enable status of the Off Timer.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getOnTime()

+ +
+
+ + + + + + + + +
uint16_t IRDaikinESP::getOnTime (void )
+
+ +

Get the On Timer time to be sent to the A/C unit.

+
Returns
The number of minutes past midnight.
+ +
+
+ +

◆ getOnTimerEnabled()

+ +
+
+ + + + + + + +
bool IRDaikinESP::getOnTimerEnabled ()
+
+ +

Get the enable status of the On Timer.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRDaikinESP::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getPowerful()

+ +
+
+ + + + + + + + +
bool IRDaikinESP::getPowerful (void )
+
+ +

Get the Powerful (Turbo) mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getQuiet()

+ +
+
+ + + + + + + + +
bool IRDaikinESP::getQuiet (void )
+
+ +

Get the Quiet mode status of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRDaikinESP::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSensor()

+ +
+
+ + + + + + + + +
bool IRDaikinESP::getSensor (void )
+
+ +

Get the Sensor mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwingHorizontal()

+ +
+
+ + + + + + + + +
bool IRDaikinESP::getSwingHorizontal (void )
+
+ +

Get the Horizontal Swing mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwingVertical()

+ +
+
+ + + + + + + + +
bool IRDaikinESP::getSwingVertical (void )
+
+ +

Get the Vertical Swing mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + +
uint8_t IRDaikinESP::getTemp ()
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ getWeeklyTimerEnable()

+ +
+
+ + + + + + + + +
bool IRDaikinESP::getWeeklyTimerEnable (void )
+
+ +

Get the enable status of the Weekly Timer.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRDaikinESP::off (void )
+
+ +

Change the power setting to Off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRDaikinESP::on (void )
+
+ +

Change the power setting to On.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRDaikinESP::send (const uint16_t repeat = kDaikinDefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setComfort()

+ +
+
+ + + + + + + + +
void IRDaikinESP::setComfort (const bool on)
+
+ +

Set the Comfort mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setCurrentDay()

+ +
+
+ + + + + + + + +
void IRDaikinESP::setCurrentDay (const uint8_t day_of_week)
+
+ +

Set the current day of the week to be sent to the A/C unit.

+
Parameters
+ + +
[in]day_of_weekThe numerical representation of the day of the week.
+
+
+
Note
1 is SUN, 2 is MON, ..., 7 is SAT
+ +
+
+ +

◆ setCurrentTime()

+ +
+
+ + + + + + + + +
void IRDaikinESP::setCurrentTime (const uint16_t mins_since_midnight)
+
+ +

Set the clock on the A/C unit.

+
Parameters
+ + +
[in]mins_since_midnightNr. of minutes past midnight.
+
+
+ +
+
+ +

◆ setEcono()

+ +
+
+ + + + + + + + +
void IRDaikinESP::setEcono (const bool on)
+
+ +

Set the Economy mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRDaikinESP::setFan (const uint8_t fan)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]fanThe desired setting.
+
+
+
Note
1-5 or kDaikinFanAuto or kDaikinFanQuiet
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRDaikinESP::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setMold()

+ +
+
+ + + + + + + + +
void IRDaikinESP::setMold (const bool on)
+
+ +

Set the Mould mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRDaikinESP::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setPowerful()

+ +
+
+ + + + + + + + +
void IRDaikinESP::setPowerful (const bool on)
+
+ +

Set the Powerful (Turbo) mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setQuiet()

+ +
+
+ + + + + + + + +
void IRDaikinESP::setQuiet (const bool on)
+
+ +

Set the Quiet mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRDaikinESP::setRaw (const uint8_t new_code[],
const uint16_t length = kDaikinStateLength 
)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + + +
[in]new_codeA valid code for this protocol.
[in]lengthLength of the code in bytes.
+
+
+ +
+
+ +

◆ setSensor()

+ +
+
+ + + + + + + + +
void IRDaikinESP::setSensor (const bool on)
+
+ +

Set the Sensor mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwingHorizontal()

+ +
+
+ + + + + + + + +
void IRDaikinESP::setSwingHorizontal (const bool on)
+
+ +

Set the Horizontal Swing mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwingVertical()

+ +
+
+ + + + + + + + +
void IRDaikinESP::setSwingVertical (const bool on)
+
+ +

Set the Vertical Swing mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRDaikinESP::setTemp (const uint8_t temp)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]tempThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ setWeeklyTimerEnable()

+ +
+
+ + + + + + + + +
void IRDaikinESP::setWeeklyTimerEnable (const bool on)
+
+ +

Set the enable status of the Weekly Timer.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRDaikinESP::stateReset (void )
+
+private
+
+ +

Reset the internal state to a fixed known good state.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRDaikinESP::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRDaikinESP::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRDaikinESP::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRDaikinESP::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRDaikinESP::validChecksum (uint8_t state[],
const uint16_t length = kDaikinStateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length of the state array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRDaikinESP::_irsend
+
+private
+
+ +

instance of the IR send class

+ +
+
+ +

◆ remote

+ +
+
+ + + + + +
+ + + + +
uint8_t IRDaikinESP::remote[kDaikinStateLength]
+
+private
+
+ +

The state of the IR remote.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikinESP__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikinESP__coll__graph.map new file mode 100644 index 000000000..6ae75bb13 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikinESP__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikinESP__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikinESP__coll__graph.md5 new file mode 100644 index 000000000..108e7de33 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikinESP__coll__graph.md5 @@ -0,0 +1 @@ +68cef74e6daf013f3d7f49c1a7c4d7f5 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikinESP__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikinESP__coll__graph.png new file mode 100644 index 000000000..b2c21d84a Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDaikinESP__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc-members.html new file mode 100644 index 000000000..3ad6d4a3a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc-members.html @@ -0,0 +1,123 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRDelonghiAc Member List
+
+
+ +

This is the complete list of members for IRDelonghiAc, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRDelonghiAcprivate
_saved_tempIRDelonghiAcprivate
_saved_temp_unitsIRDelonghiAcprivate
begin()IRDelonghiAc
calcChecksum(const uint64_t state)IRDelonghiAcstatic
calibrate(void)IRDelonghiAcinline
checksum(void)IRDelonghiAcprivate
convertFan(const stdAc::fanspeed_t speed)IRDelonghiAc
convertMode(const stdAc::opmode_t mode)IRDelonghiAc
getBoost()IRDelonghiAc
getFan()IRDelonghiAc
getMode()IRDelonghiAc
getOffTimer(void)IRDelonghiAc
getOffTimerEnabled(void)IRDelonghiAc
getOnTimer(void)IRDelonghiAc
getOnTimerEnabled(void)IRDelonghiAc
getPower()IRDelonghiAc
getRaw()IRDelonghiAc
getSleep()IRDelonghiAc
getTemp()IRDelonghiAc
getTempUnit(void)IRDelonghiAc
IRDelonghiAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRDelonghiAcexplicit
off()IRDelonghiAc
on()IRDelonghiAc
remote_stateIRDelonghiAcprivate
send(const uint16_t repeat=kDelonghiAcDefaultRepeat)IRDelonghiAc
setBoost(const bool on)IRDelonghiAc
setFan(const uint8_t speed)IRDelonghiAc
setMode(const uint8_t mode)IRDelonghiAc
setOffTimer(const uint16_t nr_of_mins)IRDelonghiAc
setOffTimerEnabled(const bool on)IRDelonghiAc
setOnTimer(const uint16_t nr_of_mins)IRDelonghiAc
setOnTimerEnabled(const bool on)IRDelonghiAc
setPower(const bool on)IRDelonghiAc
setRaw(const uint64_t state)IRDelonghiAc
setSleep(const bool on)IRDelonghiAc
setTemp(const uint8_t temp, const bool fahrenheit=false, const bool force=false)IRDelonghiAc
setTempUnit(const bool celsius)IRDelonghiAc
stateReset()IRDelonghiAc
toCommon(void)IRDelonghiAc
toCommonFanSpeed(const uint8_t speed)IRDelonghiAcstatic
toCommonMode(const uint8_t mode)IRDelonghiAcstatic
toString()IRDelonghiAc
validChecksum(const uint64_t state)IRDelonghiAcstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc.html new file mode 100644 index 000000000..2657047f5 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc.html @@ -0,0 +1,1370 @@ + + + + + + + +IRremoteESP8266: IRDelonghiAc Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Delonghi A/C messages. + More...

+ +

#include <ir_Delonghi.h>

+
+Collaboration diagram for IRDelonghiAc:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRDelonghiAc (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset ()
 Reset the internal state to a fixed known good state. More...
 
void send (const uint16_t repeat=kDelonghiAcDefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin ()
 Set up hardware to be able to send a message. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower ()
 Get the value of the current power setting. More...
 
void on ()
 Change the power setting to On. More...
 
void off ()
 Change the power setting to Off. More...
 
void setTempUnit (const bool celsius)
 Change the temperature scale units. More...
 
bool getTempUnit (void)
 Get the temperature scale unit of measure currently in use. More...
 
void setTemp (const uint8_t temp, const bool fahrenheit=false, const bool force=false)
 Set the temperature. More...
 
uint8_t getTemp ()
 Get the current temperature setting. More...
 
void setFan (const uint8_t speed)
 Set the speed of the fan. More...
 
uint8_t getFan ()
 Get the current native fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode ()
 Get the operating mode setting of the A/C. More...
 
void setBoost (const bool on)
 Set the Boost (Turbo) mode of the A/C. More...
 
bool getBoost ()
 Get the Boost (Turbo) mode of the A/C. More...
 
void setSleep (const bool on)
 Set the Sleep mode of the A/C. More...
 
bool getSleep ()
 Get the Sleep mode status of the A/C. More...
 
void setOnTimerEnabled (const bool on)
 Set the enable status of the On Timer. More...
 
bool getOnTimerEnabled (void)
 Get the enable status of the On Timer. More...
 
void setOnTimer (const uint16_t nr_of_mins)
 Set the On timer to activate in nr of minutes. More...
 
uint16_t getOnTimer (void)
 Get the On timer time. More...
 
void setOffTimerEnabled (const bool on)
 Set the enable status of the Off Timer. More...
 
bool getOffTimerEnabled (void)
 Get the enable status of the Off Timer. More...
 
void setOffTimer (const uint16_t nr_of_mins)
 Set the Off timer to activate in nr of minutes. More...
 
uint16_t getOffTimer (void)
 Get the Off timer time. More...
 
uint64_t getRaw ()
 Get a copy of the internal state as a valid code for this protocol. More...
 
void setRaw (const uint64_t state)
 Set the internal state from a valid code for this protocol. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString ()
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + + + + +

+Static Public Member Functions

static uint8_t calcChecksum (const uint64_t state)
 Calculate the checksum for a given state. More...
 
static bool validChecksum (const uint64_t state)
 Verify the checksum is valid for a given state. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + +

+Private Member Functions

void checksum (void)
 Calculate and set the checksum values for the internal state. More...
 
+ + + + + + + + + + + + + +

+Private Attributes

IRsend _irsend
 instance of the IR send class More...
 
uint64_t remote_state
 The state of the IR remote. More...
 
uint8_t _saved_temp
 The previously user requested temp value. More...
 
uint8_t _saved_temp_units
 The previously user requested temp units. More...
 
+

Detailed Description

+

Class for handling detailed Delonghi A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRDelonghiAc()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRDelonghiAc::IRDelonghiAc (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + +
void IRDelonghiAc::begin ()
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calcChecksum()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRDelonghiAc::calcChecksum (const uint64_t state)
+
+static
+
+ +

Calculate the checksum for a given state.

+
Parameters
+ + +
[in]stateThe value to calc the checksum of.
+
+
+
Returns
A valid checksum value.
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRDelonghiAc::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
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.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRDelonghiAc::checksum (void )
+
+private
+
+ +

Calculate and set the checksum values for the internal state.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRDelonghiAc::convertFan (const stdAc::fanspeed_t speed)
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRDelonghiAc::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getBoost()

+ +
+
+ + + + + + + +
bool IRDelonghiAc::getBoost ()
+
+ +

Get the Boost (Turbo) mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + +
uint8_t IRDelonghiAc::getFan ()
+
+ +

Get the current native fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + +
uint8_t IRDelonghiAc::getMode ()
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getOffTimer()

+ +
+
+ + + + + + + + +
uint16_t IRDelonghiAc::getOffTimer (void )
+
+ +

Get the Off timer time.

+
Returns
Total nr of mins before the device turns off.
+ +
+
+ +

◆ getOffTimerEnabled()

+ +
+
+ + + + + + + + +
bool IRDelonghiAc::getOffTimerEnabled (void )
+
+ +

Get the enable status of the Off Timer.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getOnTimer()

+ +
+
+ + + + + + + + +
uint16_t IRDelonghiAc::getOnTimer (void )
+
+ +

Get the On timer time.

+
Returns
Total nr of mins before the device turns on.
+ +
+
+ +

◆ getOnTimerEnabled()

+ +
+
+ + + + + + + + +
bool IRDelonghiAc::getOnTimerEnabled (void )
+
+ +

Get the enable status of the On Timer.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + +
bool IRDelonghiAc::getPower ()
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + +
uint64_t IRDelonghiAc::getRaw ()
+
+ +

Get a copy of the internal state as a valid code for this protocol.

+
Returns
A valid code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSleep()

+ +
+
+ + + + + + + +
bool IRDelonghiAc::getSleep ()
+
+ +

Get the Sleep mode status of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + +
uint8_t IRDelonghiAc::getTemp ()
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in currently configured units/scale.
+ +
+
+ +

◆ getTempUnit()

+ +
+
+ + + + + + + + +
bool IRDelonghiAc::getTempUnit (void )
+
+ +

Get the temperature scale unit of measure currently in use.

+
Returns
true, is Fahrenheit. false, is Celsius.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + +
void IRDelonghiAc::off ()
+
+ +

Change the power setting to Off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + +
void IRDelonghiAc::on ()
+
+ +

Change the power setting to On.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRDelonghiAc::send (const uint16_t repeat = kDelonghiAcDefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setBoost()

+ +
+
+ + + + + + + + +
void IRDelonghiAc::setBoost (const bool on)
+
+ +

Set the Boost (Turbo) mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRDelonghiAc::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired native setting.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRDelonghiAc::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired native operating mode.
+
+
+ +
+
+ +

◆ setOffTimer()

+ +
+
+ + + + + + + + +
void IRDelonghiAc::setOffTimer (const uint16_t nr_of_mins)
+
+ +

Set the Off timer to activate in nr of minutes.

+
Parameters
+ + +
[in]nr_of_minsTotal nr of mins to wait before turning off the device
+
+
+
Note
Max 23 hrs and 59 minutes. i.e. 1439 mins.
+ +
+
+ +

◆ setOffTimerEnabled()

+ +
+
+ + + + + + + + +
void IRDelonghiAc::setOffTimerEnabled (const bool on)
+
+ +

Set the enable status of the Off Timer.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setOnTimer()

+ +
+
+ + + + + + + + +
void IRDelonghiAc::setOnTimer (const uint16_t nr_of_mins)
+
+ +

Set the On timer to activate in nr of minutes.

+
Parameters
+ + +
[in]nr_of_minsTotal nr of mins to wait before waking the device.
+
+
+
Note
Max 23 hrs and 59 minutes. i.e. 1439 mins.
+ +
+
+ +

◆ setOnTimerEnabled()

+ +
+
+ + + + + + + + +
void IRDelonghiAc::setOnTimerEnabled (const bool on)
+
+ +

Set the enable status of the On Timer.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRDelonghiAc::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRDelonghiAc::setRaw (const uint64_t state)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]stateA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSleep()

+ +
+
+ + + + + + + + +
void IRDelonghiAc::setSleep (const bool on)
+
+ +

Set the Sleep mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRDelonghiAc::setTemp (const uint8_t degrees,
const bool fahrenheit = false,
const bool force = false 
)
+
+ +

Set the temperature.

+
Parameters
+ + + + +
[in]degreesThe temperature in degrees.
[in]fahrenheitUse Fahrenheit as the temperature scale.
[in]forceDo we ignore any sanity checks?
+
+
+ +
+
+ +

◆ setTempUnit()

+ +
+
+ + + + + + + + +
void IRDelonghiAc::setTempUnit (const bool fahrenheit)
+
+ +

Change the temperature scale units.

+
Parameters
+ + +
[in]fahrenheittrue, use Fahrenheit. false, use Celsius.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + +
void IRDelonghiAc::stateReset ()
+
+ +

Reset the internal state to a fixed known good state.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRDelonghiAc::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRDelonghiAc::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRDelonghiAc::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + +
String IRDelonghiAc::toString ()
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + +
bool IRDelonghiAc::validChecksum (const uint64_t state)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + +
[in]stateThe state to verify the checksum of.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRDelonghiAc::_irsend
+
+private
+
+ +

instance of the IR send class

+ +
+
+ +

◆ _saved_temp

+ +
+
+ + + + + +
+ + + + +
uint8_t IRDelonghiAc::_saved_temp
+
+private
+
+ +

The previously user requested temp value.

+ +
+
+ +

◆ _saved_temp_units

+ +
+
+ + + + + +
+ + + + +
uint8_t IRDelonghiAc::_saved_temp_units
+
+private
+
+ +

The previously user requested temp units.

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint64_t IRDelonghiAc::remote_state
+
+private
+
+ +

The state of the IR remote.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc__coll__graph.map new file mode 100644 index 000000000..069782ed6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc__coll__graph.md5 new file mode 100644 index 000000000..58e961103 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc__coll__graph.md5 @@ -0,0 +1 @@ +e2babeacb4dc45c7ae998d66cca5b36e \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc__coll__graph.png new file mode 100644 index 000000000..1a0cb0d9f Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRDelonghiAc__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc-members.html new file mode 100644 index 000000000..b71c6923c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc-members.html @@ -0,0 +1,117 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRElectraAc Member List
+
+
+ +

This is the complete list of members for IRElectraAc, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRElectraAcprivate
begin(void)IRElectraAc
calcChecksum(const uint8_t state[], const uint16_t length=kElectraAcStateLength)IRElectraAcstatic
calibrate(void)IRElectraAcinline
checksum(const uint16_t length=kElectraAcStateLength)IRElectraAcprivate
convertFan(const stdAc::fanspeed_t speed)IRElectraAc
convertMode(const stdAc::opmode_t mode)IRElectraAc
getClean(void)IRElectraAc
getFan(void)IRElectraAc
getLightToggle(void)IRElectraAc
getMode(void)IRElectraAc
getPower(void)IRElectraAc
getRaw(void)IRElectraAc
getSwingH(void)IRElectraAc
getSwingV(void)IRElectraAc
getTemp(void)IRElectraAc
getTurbo(void)IRElectraAc
IRElectraAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRElectraAcexplicit
off(void)IRElectraAc
on(void)IRElectraAc
remote_stateIRElectraAcprivate
send(const uint16_t repeat=kElectraAcMinRepeat)IRElectraAc
setClean(const bool on)IRElectraAc
setFan(const uint8_t speed)IRElectraAc
setLightToggle(const bool on)IRElectraAc
setMode(const uint8_t mode)IRElectraAc
setPower(const bool on)IRElectraAc
setRaw(const uint8_t new_code[], const uint16_t length=kElectraAcStateLength)IRElectraAc
setSwingH(const bool on)IRElectraAc
setSwingV(const bool on)IRElectraAc
setTemp(const uint8_t temp)IRElectraAc
setTurbo(const bool on)IRElectraAc
stateReset(void)IRElectraAc
toCommon(void)IRElectraAc
toCommonFanSpeed(const uint8_t speed)IRElectraAcstatic
toCommonMode(const uint8_t mode)IRElectraAcstatic
toString(void)IRElectraAc
validChecksum(const uint8_t state[], const uint16_t length=kElectraAcStateLength)IRElectraAcstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc.html new file mode 100644 index 000000000..60c60c249 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc.html @@ -0,0 +1,1242 @@ + + + + + + + +IRremoteESP8266: IRElectraAc Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Electra A/C messages. + More...

+ +

#include <ir_Electra.h>

+
+Collaboration diagram for IRElectraAc:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRElectraAc (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset (void)
 Reset the internal state to a fixed known good state. More...
 
void send (const uint16_t repeat=kElectraAcMinRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Change the power setting to On. More...
 
void off (void)
 Change the power setting to Off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t speed)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setSwingV (const bool on)
 Set the Vertical Swing mode of the A/C. More...
 
bool getSwingV (void)
 Get the Vertical Swing mode of the A/C. More...
 
void setSwingH (const bool on)
 Set the Horizontal Swing mode of the A/C. More...
 
bool getSwingH (void)
 Get the Horizontal Swing mode of the A/C. More...
 
void setClean (const bool on)
 Set the Clean mode of the A/C. More...
 
bool getClean (void)
 Get the Clean mode of the A/C. More...
 
void setLightToggle (const bool on)
 Set the Light (LED) Toggle mode of the A/C. More...
 
bool getLightToggle (void)
 Get the Light (LED) Toggle mode of the A/C. More...
 
void setTurbo (const bool on)
 Set the Turbo mode of the A/C. More...
 
bool getTurbo (void)
 Get the Turbo mode of the A/C. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t new_code[], const uint16_t length=kElectraAcStateLength)
 Set the internal state from a valid code for this protocol. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
+ + + + + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (const uint8_t state[], const uint16_t length=kElectraAcStateLength)
 Verify the checksum is valid for a given state. More...
 
static uint8_t calcChecksum (const uint8_t state[], const uint16_t length=kElectraAcStateLength)
 Calculate the checksum for a given state. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + +

+Private Member Functions

void checksum (const uint16_t length=kElectraAcStateLength)
 Calculate and set the checksum values for the internal state. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 instance of the IR send class More...
 
uint8_t remote_state [kElectraAcStateLength]
 The state of the IR remote. More...
 
+

Detailed Description

+

Class for handling detailed Electra A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRElectraAc()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRElectraAc::IRElectraAc (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRElectraAc::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calcChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
uint8_t IRElectraAc::calcChecksum (const uint8_t state[],
const uint16_t length = kElectraAcStateLength 
)
+
+static
+
+ +

Calculate the checksum for a given state.

+
Parameters
+ + + +
[in]stateThe value to calc the checksum of.
[in]lengthThe length of the state array.
+
+
+
Returns
The calculated checksum stored in a uint_8.
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRElectraAc::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
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.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRElectraAc::checksum (const uint16_t length = kElectraAcStateLength)
+
+private
+
+ +

Calculate and set the checksum values for the internal state.

+
Parameters
+ + +
[in]lengthThe length of the state array.
+
+
+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRElectraAc::convertFan (const stdAc::fanspeed_t speed)
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRElectraAc::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getClean()

+ +
+
+ + + + + + + + +
bool IRElectraAc::getClean (void )
+
+ +

Get the Clean mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRElectraAc::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getLightToggle()

+ +
+
+ + + + + + + + +
bool IRElectraAc::getLightToggle (void )
+
+ +

Get the Light (LED) Toggle mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRElectraAc::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRElectraAc::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRElectraAc::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSwingH()

+ +
+
+ + + + + + + + +
bool IRElectraAc::getSwingH (void )
+
+ +

Get the Horizontal Swing mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwingV()

+ +
+
+ + + + + + + + +
bool IRElectraAc::getSwingV (void )
+
+ +

Get the Vertical Swing mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRElectraAc::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ getTurbo()

+ +
+
+ + + + + + + + +
bool IRElectraAc::getTurbo (void )
+
+ +

Get the Turbo mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRElectraAc::off (void )
+
+ +

Change the power setting to Off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRElectraAc::on (void )
+
+ +

Change the power setting to On.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRElectraAc::send (const uint16_t repeat = kElectraAcMinRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setClean()

+ +
+
+ + + + + + + + +
void IRElectraAc::setClean (const bool on)
+
+ +

Set the Clean mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRElectraAc::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting.
+
+
+
Note
0 is auto, 1-3 is the speed
+ +
+
+ +

◆ setLightToggle()

+ +
+
+ + + + + + + + +
void IRElectraAc::setLightToggle (const bool on)
+
+ +

Set the Light (LED) Toggle mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRElectraAc::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRElectraAc::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRElectraAc::setRaw (const uint8_t new_code[],
const uint16_t length = kElectraAcStateLength 
)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + + +
[in]new_codeA valid code for this protocol.
[in]lengthThe length of the code array.
+
+
+ +
+
+ +

◆ setSwingH()

+ +
+
+ + + + + + + + +
void IRElectraAc::setSwingH (const bool on)
+
+ +

Set the Horizontal Swing mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwingV()

+ +
+
+ + + + + + + + +
void IRElectraAc::setSwingV (const bool on)
+
+ +

Set the Vertical Swing mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRElectraAc::setTemp (const uint8_t temp)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]tempThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ setTurbo()

+ +
+
+ + + + + + + + +
void IRElectraAc::setTurbo (const bool on)
+
+ +

Set the Turbo mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRElectraAc::stateReset (void )
+
+ +

Reset the internal state to a fixed known good state.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRElectraAc::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRElectraAc::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRElectraAc::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRElectraAc::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRElectraAc::validChecksum (const uint8_t state[],
const uint16_t length = kElectraAcStateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe state to verify the checksum of.
[in]lengthThe length of the state array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRElectraAc::_irsend
+
+private
+
+ +

instance of the IR send class

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRElectraAc::remote_state[kElectraAcStateLength]
+
+private
+
+ +

The state of the IR remote.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc__coll__graph.map new file mode 100644 index 000000000..2ca5c6051 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc__coll__graph.md5 new file mode 100644 index 000000000..ec7416486 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc__coll__graph.md5 @@ -0,0 +1 @@ +b6e5f96f14e5e22330cef83a09e5f30d \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc__coll__graph.png new file mode 100644 index 000000000..e49f5d0ec Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRElectraAc__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC-members.html new file mode 100644 index 000000000..2c328bcf2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC-members.html @@ -0,0 +1,135 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRFujitsuAC Member List
+
+
+ +

This is the complete list of members for IRFujitsuAC, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_cleanIRFujitsuACprivate
_cmdIRFujitsuACprivate
_fanSpeedIRFujitsuACprivate
_filterIRFujitsuACprivate
_irsendIRFujitsuACprivate
_modeIRFujitsuACprivate
_modelIRFujitsuACprivate
_outsideQuietIRFujitsuACprivate
_state_lengthIRFujitsuACprivate
_state_length_shortIRFujitsuACprivate
_swingModeIRFujitsuACprivate
_tempIRFujitsuACprivate
begin(void)IRFujitsuAC
buildFromState(const uint16_t length)IRFujitsuACprivate
buildState(void)IRFujitsuACprivate
calibrate(void)IRFujitsuACinline
convertFan(stdAc::fanspeed_t speed)IRFujitsuAC
convertMode(const stdAc::opmode_t mode)IRFujitsuAC
getClean(const bool raw=false)IRFujitsuAC
getCmd(const bool raw=false)IRFujitsuAC
getFanSpeed(void)IRFujitsuAC
getFilter(const bool raw=false)IRFujitsuAC
getMode(void)IRFujitsuAC
getModel(void)IRFujitsuAC
getOutsideQuiet(const bool raw=false)IRFujitsuAC
getPower(void)IRFujitsuAC
getRaw(void)IRFujitsuAC
getStateLength(void)IRFujitsuAC
getSwing(const bool raw=false)IRFujitsuAC
getTemp(void)IRFujitsuAC
IRFujitsuAC(const uint16_t pin, const fujitsu_ac_remote_model_t model=ARRAH2E, const bool inverted=false, const bool use_modulation=true)IRFujitsuACexplicit
off(void)IRFujitsuAC
on(void)IRFujitsuAC
remote_stateIRFujitsuACprivate
send(const uint16_t repeat=kFujitsuAcMinRepeat)IRFujitsuAC
setClean(const bool on)IRFujitsuAC
setCmd(const uint8_t cmd)IRFujitsuAC
setFanSpeed(const uint8_t fan)IRFujitsuAC
setFilter(const bool on)IRFujitsuAC
setMode(const uint8_t mode)IRFujitsuAC
setModel(const fujitsu_ac_remote_model_t model)IRFujitsuAC
setOutsideQuiet(const bool on)IRFujitsuAC
setPower(const bool on)IRFujitsuAC
setRaw(const uint8_t newState[], const uint16_t length)IRFujitsuAC
setSwing(const uint8_t mode)IRFujitsuAC
setTemp(const uint8_t temp)IRFujitsuAC
stateReset(void)IRFujitsuAC
stepHoriz(void)IRFujitsuAC
stepVert(void)IRFujitsuAC
toCommon(void)IRFujitsuAC
toCommonFanSpeed(const uint8_t speed)IRFujitsuACstatic
toCommonMode(const uint8_t mode)IRFujitsuACstatic
toggleSwingHoriz(const bool update=true)IRFujitsuAC
toggleSwingVert(const bool update=true)IRFujitsuAC
toString(void)IRFujitsuAC
validChecksum(uint8_t *state, const uint16_t length)IRFujitsuACstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC.html new file mode 100644 index 000000000..3259fb80e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC.html @@ -0,0 +1,1707 @@ + + + + + + + +IRremoteESP8266: IRFujitsuAC Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Fujitsu A/C messages. + More...

+ +

#include <ir_Fujitsu.h>

+
+Collaboration diagram for IRFujitsuAC:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRFujitsuAC (const uint16_t pin, const fujitsu_ac_remote_model_t model=ARRAH2E, const bool inverted=false, const bool use_modulation=true)
 Class Constructor. More...
 
void setModel (const fujitsu_ac_remote_model_t model)
 Set the currently emulated model of the A/C. More...
 
fujitsu_ac_remote_model_t getModel (void)
 Get the currently emulated/detected model of the A/C. More...
 
void stateReset (void)
 Reset the state of the remote to a known good state/sequence. More...
 
void send (const uint16_t repeat=kFujitsuAcMinRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void stepHoriz (void)
 Request the A/C to step the Horizontal Swing. More...
 
void toggleSwingHoriz (const bool update=true)
 Request the A/C to toggle the Horizontal Swing mode. More...
 
void stepVert (void)
 Request the A/C to step the Vertical Swing. More...
 
void toggleSwingVert (const bool update=true)
 Request the A/C to toggle the Vertical Swing mode. More...
 
void setCmd (const uint8_t cmd)
 Set the requested (special) command part for the A/C message. More...
 
uint8_t getCmd (const bool raw=false)
 Set the requested (special) command part for the A/C message. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFanSpeed (const uint8_t fan)
 Set the speed of the fan. More...
 
uint8_t getFanSpeed (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setSwing (const uint8_t mode)
 Set the requested swing operation mode of the A/C unit. More...
 
uint8_t getSwing (const bool raw=false)
 Get the requested swing operation mode of the A/C unit. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
bool setRaw (const uint8_t newState[], const uint16_t length)
 Set the internal state from a valid code for this protocol. More...
 
uint8_t getStateLength (void)
 Get the length (size) of the state code for the current configuration. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
void off (void)
 Set the requested power state of the A/C to off. More...
 
void on (void)
 Set the requested power state of the A/C to on. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setClean (const bool on)
 Set the Clean mode of the A/C. More...
 
bool getClean (const bool raw=false)
 Get the Clean mode status of the A/C. More...
 
void setFilter (const bool on)
 Set the Filter mode status of the A/C. More...
 
bool getFilter (const bool raw=false)
 Get the Filter mode status of the A/C. More...
 
void setOutsideQuiet (const bool on)
 Set the Outside Quiet mode of the A/C. More...
 
bool getOutsideQuiet (const bool raw=false)
 Get the Outside Quiet mode status of the A/C. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
uint8_t convertFan (stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (uint8_t *state, const uint16_t length)
 Verify the checksum is valid for a given state. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + + + + +

+Private Member Functions

void buildState (void)
 (Re)Build the state from the currently configured settings. More...
 
void buildFromState (const uint16_t length)
 Build the internal state/config from the current (raw) A/C message. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kFujitsuAcStateLength]
 The state of the IR remote. More...
 
uint8_t _temp
 
uint8_t _fanSpeed
 
uint8_t _mode
 
uint8_t _swingMode
 
uint8_t _cmd
 
fujitsu_ac_remote_model_t _model
 
uint8_t _state_length
 
uint8_t _state_length_short
 
bool _outsideQuiet
 
bool _clean
 
bool _filter
 
+

Detailed Description

+

Class for handling detailed Fujitsu A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRFujitsuAC()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IRFujitsuAC::IRFujitsuAC (const uint16_t pin,
const fujitsu_ac_remote_model_t model = ARRAH2E,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class Constructor.

+
Parameters
+ + + + + +
[in]pinGPIO to be used when sending.
[in]modelThe enum for the model of A/C to be emulated.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRFujitsuAC::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ buildFromState()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRFujitsuAC::buildFromState (const uint16_t length)
+
+private
+
+ +

Build the internal state/config from the current (raw) A/C message.

+
Parameters
+ + +
[in]lengthSize of the current/used (raw) A/C message array.
+
+
+ +
+
+ +

◆ buildState()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRFujitsuAC::buildState (void )
+
+private
+
+ +

(Re)Build the state from the currently configured settings.

+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRFujitsuAC::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
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.
+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRFujitsuAC::convertFan (stdAc::fanspeed_t speed)
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRFujitsuAC::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getClean()

+ +
+
+ + + + + + + + +
bool IRFujitsuAC::getClean (const bool raw = false)
+
+ +

Get the Clean mode status of the A/C.

+
Parameters
+ + +
[in]rawDo we get the result from base data?
+
+
+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getCmd()

+ +
+
+ + + + + + + + +
uint8_t IRFujitsuAC::getCmd (const bool raw = false)
+
+ +

Set the requested (special) command part for the A/C message.

+
Parameters
+ + +
[in]rawDo we need to get it from first principles from the raw data?
+
+
+
Returns
The special command code.
+ +
+
+ +

◆ getFanSpeed()

+ +
+
+ + + + + + + + +
uint8_t IRFujitsuAC::getFanSpeed (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getFilter()

+ +
+
+ + + + + + + + +
bool IRFujitsuAC::getFilter (const bool raw = false)
+
+ +

Get the Filter mode status of the A/C.

+
Parameters
+ + +
[in]rawDo we get the result from base data?
+
+
+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRFujitsuAC::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getModel()

+ +
+
+ + + + + + + + +
fujitsu_ac_remote_model_t IRFujitsuAC::getModel (void )
+
+ +

Get the currently emulated/detected model of the A/C.

+
Returns
The enum representing the model of A/C.
+ +
+
+ +

◆ getOutsideQuiet()

+ +
+
+ + + + + + + + +
bool IRFujitsuAC::getOutsideQuiet (const bool raw = false)
+
+ +

Get the Outside Quiet mode status of the A/C.

+
Parameters
+ + +
[in]rawDo we get the result from base data?
+
+
+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRFujitsuAC::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRFujitsuAC::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getStateLength()

+ +
+
+ + + + + + + + +
uint8_t IRFujitsuAC::getStateLength (void )
+
+ +

Get the length (size) of the state code for the current configuration.

+
Returns
The length of the state array required for this config.
+ +
+
+ +

◆ getSwing()

+ +
+
+ + + + + + + + +
uint8_t IRFujitsuAC::getSwing (const bool raw = false)
+
+ +

Get the requested swing operation mode of the A/C unit.

+
Parameters
+ + +
[in]rawDo we need to get it from first principles from the raw data?
+
+
+
Returns
The contents of the swing state/mode.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRFujitsuAC::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRFujitsuAC::off (void )
+
+ +

Set the requested power state of the A/C to off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRFujitsuAC::on (void )
+
+ +

Set the requested power state of the A/C to on.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRFujitsuAC::send (const uint16_t repeat = kFujitsuAcMinRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setClean()

+ +
+
+ + + + + + + + +
void IRFujitsuAC::setClean (const bool on)
+
+ +

Set the Clean mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setCmd()

+ +
+
+ + + + + + + + +
void IRFujitsuAC::setCmd (const uint8_t cmd)
+
+ +

Set the requested (special) command part for the A/C message.

+
Parameters
+ + +
[in]cmdThe special command code.
+
+
+ +
+
+ +

◆ setFanSpeed()

+ +
+
+ + + + + + + + +
void IRFujitsuAC::setFanSpeed (const uint8_t fanSpeed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]fanSpeedThe desired setting.
+
+
+ +
+
+ +

◆ setFilter()

+ +
+
+ + + + + + + + +
void IRFujitsuAC::setFilter (const bool on)
+
+ +

Set the Filter mode status of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRFujitsuAC::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setModel()

+ +
+
+ + + + + + + + +
void IRFujitsuAC::setModel (const fujitsu_ac_remote_model_t model)
+
+ +

Set the currently emulated model of the A/C.

+
Parameters
+ + +
[in]modelAn enum representing the model to support/emulate.
+
+
+ +
+
+ +

◆ setOutsideQuiet()

+ +
+
+ + + + + + + + +
void IRFujitsuAC::setOutsideQuiet (const bool on)
+
+ +

Set the Outside Quiet mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRFujitsuAC::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + + + + + + + + + + + +
bool IRFujitsuAC::setRaw (const uint8_t newState[],
const uint16_t length 
)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + + +
[in]newStateA valid code for this protocol.
[in]lengthSize of the newState array.
+
+
+
Returns
true, if successful; Otherwise false. (i.e. size check)
+ +
+
+ +

◆ setSwing()

+ +
+
+ + + + + + + + +
void IRFujitsuAC::setSwing (const uint8_t swingMode)
+
+ +

Set the requested swing operation mode of the A/C unit.

+
Parameters
+ + +
[in]swingModeThe swingMode code for the A/C. Vertical, Horizon, or Both. See constants for details.
+
+
+
Note
Not all models support all possible swing modes.
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRFujitsuAC::setTemp (const uint8_t temp)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]tempThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRFujitsuAC::stateReset (void )
+
+ +

Reset the state of the remote to a known good state/sequence.

+ +
+
+ +

◆ stepHoriz()

+ +
+
+ + + + + + + + +
void IRFujitsuAC::stepHoriz (void )
+
+ +

Request the A/C to step the Horizontal Swing.

+ +
+
+ +

◆ stepVert()

+ +
+
+ + + + + + + + +
void IRFujitsuAC::stepVert (void )
+
+ +

Request the A/C to step the Vertical Swing.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRFujitsuAC::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRFujitsuAC::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRFujitsuAC::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toggleSwingHoriz()

+ +
+
+ + + + + + + + +
void IRFujitsuAC::toggleSwingHoriz (const bool update = true)
+
+ +

Request the A/C to toggle the Horizontal Swing mode.

+
Parameters
+ + +
[in]updateDo we need to update the general swing config?
+
+
+ +
+
+ +

◆ toggleSwingVert()

+ +
+
+ + + + + + + + +
void IRFujitsuAC::toggleSwingVert (const bool update = true)
+
+ +

Request the A/C to toggle the Vertical Swing mode.

+
Parameters
+ + +
[in]updateDo we need to update the general swing config?
+
+
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRFujitsuAC::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRFujitsuAC::validChecksum (uint8_t * state,
const uint16_t length 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length of the state array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _clean

+ +
+
+ + + + + +
+ + + + +
bool IRFujitsuAC::_clean
+
+private
+
+ +
+
+ +

◆ _cmd

+ +
+
+ + + + + +
+ + + + +
uint8_t IRFujitsuAC::_cmd
+
+private
+
+ +
+
+ +

◆ _fanSpeed

+ +
+
+ + + + + +
+ + + + +
uint8_t IRFujitsuAC::_fanSpeed
+
+private
+
+ +
+
+ +

◆ _filter

+ +
+
+ + + + + +
+ + + + +
bool IRFujitsuAC::_filter
+
+private
+
+ +
+
+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRFujitsuAC::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ _mode

+ +
+
+ + + + + +
+ + + + +
uint8_t IRFujitsuAC::_mode
+
+private
+
+ +
+
+ +

◆ _model

+ +
+
+ + + + + +
+ + + + +
fujitsu_ac_remote_model_t IRFujitsuAC::_model
+
+private
+
+ +
+
+ +

◆ _outsideQuiet

+ +
+
+ + + + + +
+ + + + +
bool IRFujitsuAC::_outsideQuiet
+
+private
+
+ +
+
+ +

◆ _state_length

+ +
+
+ + + + + +
+ + + + +
uint8_t IRFujitsuAC::_state_length
+
+private
+
+ +
+
+ +

◆ _state_length_short

+ +
+
+ + + + + +
+ + + + +
uint8_t IRFujitsuAC::_state_length_short
+
+private
+
+ +
+
+ +

◆ _swingMode

+ +
+
+ + + + + +
+ + + + +
uint8_t IRFujitsuAC::_swingMode
+
+private
+
+ +
+
+ +

◆ _temp

+ +
+
+ + + + + +
+ + + + +
uint8_t IRFujitsuAC::_temp
+
+private
+
+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRFujitsuAC::remote_state[kFujitsuAcStateLength]
+
+private
+
+ +

The state of the IR remote.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC__coll__graph.map new file mode 100644 index 000000000..3099d5f4a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC__coll__graph.md5 new file mode 100644 index 000000000..cbcc342bb --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC__coll__graph.md5 @@ -0,0 +1 @@ +338c5a3ac726e2794d93445b33b8db6c \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC__coll__graph.png new file mode 100644 index 000000000..595272976 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRFujitsuAC__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGoodweatherAc-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGoodweatherAc-members.html new file mode 100644 index 000000000..d164b0e30 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGoodweatherAc-members.html @@ -0,0 +1,115 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRGoodweatherAc Member List
+
+
+ +

This is the complete list of members for IRGoodweatherAc, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRGoodweatherAcprivate
begin(void)IRGoodweatherAc
calibrate(void)IRGoodweatherAcinline
convertFan(const stdAc::fanspeed_t speed)IRGoodweatherAc
convertMode(const stdAc::opmode_t mode)IRGoodweatherAc
convertSwingV(const stdAc::swingv_t swingv)IRGoodweatherAc
getCommand(void)IRGoodweatherAc
getFan(void)IRGoodweatherAc
getLight(void)IRGoodweatherAc
getMode()IRGoodweatherAc
getPower(void)IRGoodweatherAc
getRaw(void)IRGoodweatherAc
getSleep(void)IRGoodweatherAc
getSwing(void)IRGoodweatherAc
getTemp(void)IRGoodweatherAc
getTurbo(void)IRGoodweatherAc
IRGoodweatherAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRGoodweatherAcexplicit
off(void)IRGoodweatherAc
on(void)IRGoodweatherAc
remoteIRGoodweatherAcprivate
send(const uint16_t repeat=kGoodweatherMinRepeat)IRGoodweatherAc
setCommand(const uint8_t cmd)IRGoodweatherAc
setFan(const uint8_t speed)IRGoodweatherAc
setLight(const bool toggle)IRGoodweatherAc
setMode(const uint8_t mode)IRGoodweatherAc
setPower(const bool on)IRGoodweatherAc
setRaw(const uint64_t state)IRGoodweatherAc
setSleep(const bool toggle)IRGoodweatherAc
setSwing(const uint8_t speed)IRGoodweatherAc
setTemp(const uint8_t temp)IRGoodweatherAc
setTurbo(const bool toggle)IRGoodweatherAc
stateReset(void)IRGoodweatherAc
toCommon(void)IRGoodweatherAc
toCommonFanSpeed(const uint8_t speed)IRGoodweatherAcstatic
toCommonMode(const uint8_t mode)IRGoodweatherAcstatic
toString()IRGoodweatherAc
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGoodweatherAc.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGoodweatherAc.html new file mode 100644 index 000000000..d1d4643d4 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGoodweatherAc.html @@ -0,0 +1,1119 @@ + + + + + + + +IRremoteESP8266: IRGoodweatherAc Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Goodweather A/C messages. + More...

+ +

#include <ir_Goodweather.h>

+
+Collaboration diagram for IRGoodweatherAc:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRGoodweatherAc (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset (void)
 Reset the internal state to a fixed known good state. More...
 
void send (const uint16_t repeat=kGoodweatherMinRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Change the power setting to On. More...
 
void off (void)
 Change the power setting to Off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t speed)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode ()
 Get the operating mode setting of the A/C. More...
 
void setSwing (const uint8_t speed)
 Set the Vertical Swing speed of the A/C. More...
 
uint8_t getSwing (void)
 Get the Vertical Swing speed of the A/C. More...
 
void setSleep (const bool toggle)
 Set the Sleep Toggle setting of the A/C. More...
 
bool getSleep (void)
 Get the Sleep Toggle setting of the A/C. More...
 
void setTurbo (const bool toggle)
 Set the Turbo Toggle setting of the A/C. More...
 
bool getTurbo (void)
 Get the Turbo Toggle setting of the A/C. More...
 
void setLight (const bool toggle)
 Set the Light (LED) Toggle setting of the A/C. More...
 
bool getLight (void)
 Get the Light (LED) Toggle setting of the A/C. More...
 
void setCommand (const uint8_t cmd)
 Set the remote Command type/button pressed. More...
 
uint8_t getCommand (void)
 Get the Command type/button pressed from the current settings. More...
 
uint64_t getRaw (void)
 Get a copy of the internal state as a valid code for this protocol. More...
 
void setRaw (const uint64_t state)
 Set the internal state from a valid code for this protocol. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
uint8_t convertSwingV (const stdAc::swingv_t swingv)
 Convert a stdAc::swingv_t enum into it's native setting. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString ()
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + +

+Static Public Member Functions

static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint64_t remote
 The state of the IR remote in IR code form. More...
 
+

Detailed Description

+

Class for handling detailed Goodweather A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRGoodweatherAc()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRGoodweatherAc::IRGoodweatherAc (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRGoodweatherAc::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRGoodweatherAc::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
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.
+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRGoodweatherAc::convertFan (const stdAc::fanspeed_t speed)
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRGoodweatherAc::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertSwingV()

+ +
+
+ + + + + + + + +
uint8_t IRGoodweatherAc::convertSwingV (const stdAc::swingv_t swingv)
+
+ +

Convert a stdAc::swingv_t enum into it's native setting.

+
Parameters
+ + +
[in]swingvThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getCommand()

+ +
+
+ + + + + + + + +
uint8_t IRGoodweatherAc::getCommand (void )
+
+ +

Get the Command type/button pressed from the current settings.

+
Returns
The command/button that was issued/pressed.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRGoodweatherAc::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getLight()

+ +
+
+ + + + + + + + +
bool IRGoodweatherAc::getLight (void )
+
+ +

Get the Light (LED) Toggle setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + +
uint8_t IRGoodweatherAc::getMode ()
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRGoodweatherAc::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint64_t IRGoodweatherAc::getRaw (void )
+
+ +

Get a copy of the internal state as a valid code for this protocol.

+
Returns
A valid code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSleep()

+ +
+
+ + + + + + + + +
bool IRGoodweatherAc::getSleep (void )
+
+ +

Get the Sleep Toggle setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwing()

+ +
+
+ + + + + + + + +
uint8_t IRGoodweatherAc::getSwing (void )
+
+ +

Get the Vertical Swing speed of the A/C.

+
Returns
The native swing speed setting.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRGoodweatherAc::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ getTurbo()

+ +
+
+ + + + + + + + +
bool IRGoodweatherAc::getTurbo (void )
+
+ +

Get the Turbo Toggle setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRGoodweatherAc::off (void )
+
+ +

Change the power setting to Off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRGoodweatherAc::on (void )
+
+ +

Change the power setting to On.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRGoodweatherAc::send (const uint16_t repeat = kGoodweatherMinRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setCommand()

+ +
+
+ + + + + + + + +
void IRGoodweatherAc::setCommand (const uint8_t cmd)
+
+ +

Set the remote Command type/button pressed.

+
Parameters
+ + +
[in]cmdThe command/button that was issued/pressed.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRGoodweatherAc::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting.
+
+
+ +
+
+ +

◆ setLight()

+ +
+
+ + + + + + + + +
void IRGoodweatherAc::setLight (const bool toggle)
+
+ +

Set the Light (LED) Toggle setting of the A/C.

+
Parameters
+ + +
[in]toggletrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRGoodweatherAc::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRGoodweatherAc::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRGoodweatherAc::setRaw (const uint64_t state)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]stateA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSleep()

+ +
+
+ + + + + + + + +
void IRGoodweatherAc::setSleep (const bool toggle)
+
+ +

Set the Sleep Toggle setting of the A/C.

+
Parameters
+ + +
[in]toggletrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwing()

+ +
+
+ + + + + + + + +
void IRGoodweatherAc::setSwing (const uint8_t speed)
+
+ +

Set the Vertical Swing speed of the A/C.

+
Parameters
+ + +
[in]speedThe speed to set the swing to.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRGoodweatherAc::setTemp (const uint8_t temp)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]tempThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ setTurbo()

+ +
+
+ + + + + + + + +
void IRGoodweatherAc::setTurbo (const bool toggle)
+
+ +

Set the Turbo Toggle setting of the A/C.

+
Parameters
+ + +
[in]toggletrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRGoodweatherAc::stateReset (void )
+
+ +

Reset the internal state to a fixed known good state.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRGoodweatherAc::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRGoodweatherAc::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRGoodweatherAc::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + +
String IRGoodweatherAc::toString ()
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRGoodweatherAc::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ remote

+ +
+
+ + + + + +
+ + + + +
uint64_t IRGoodweatherAc::remote
+
+private
+
+ +

The state of the IR remote in IR code form.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGoodweatherAc__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGoodweatherAc__coll__graph.map new file mode 100644 index 000000000..660cc0842 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGoodweatherAc__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGoodweatherAc__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGoodweatherAc__coll__graph.md5 new file mode 100644 index 000000000..960e5d2a0 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGoodweatherAc__coll__graph.md5 @@ -0,0 +1 @@ +bce379f76240220988c09046a0d5f283 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGoodweatherAc__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGoodweatherAc__coll__graph.png new file mode 100644 index 000000000..b9f6e66cb Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGoodweatherAc__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC-members.html new file mode 100644 index 000000000..7c4b5e991 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC-members.html @@ -0,0 +1,135 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRGreeAC Member List
+
+
+ +

This is the complete list of members for IRGreeAC, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRGreeACprivate
_modelIRGreeACprivate
begin(void)IRGreeAC
calibrate(void)IRGreeACinline
checksum(const uint16_t length=kGreeStateLength)IRGreeACprivate
convertFan(const stdAc::fanspeed_t speed)IRGreeAC
convertMode(const stdAc::opmode_t mode)IRGreeAC
convertSwingV(const stdAc::swingv_t swingv)IRGreeAC
fixup(void)IRGreeACprivate
getDisplayTempSource(void)IRGreeAC
getFan(void)IRGreeAC
getIFeel(void)IRGreeAC
getLight(void)IRGreeAC
getMode(void)IRGreeAC
getModel(void)IRGreeAC
getPower(void)IRGreeAC
getRaw(void)IRGreeAC
getSleep(void)IRGreeAC
getSwingVerticalAuto(void)IRGreeAC
getSwingVerticalPosition(void)IRGreeAC
getTemp(void)IRGreeAC
getTimer(void)IRGreeAC
getTimerEnabled(void)IRGreeACprivate
getTurbo(void)IRGreeAC
getUseFahrenheit(void)IRGreeAC
getWiFi(void)IRGreeAC
getXFan(void)IRGreeAC
IRGreeAC(const uint16_t pin, const gree_ac_remote_model_t model=gree_ac_remote_model_t::YAW1F, const bool inverted=false, const bool use_modulation=true)IRGreeACexplicit
off(void)IRGreeAC
on(void)IRGreeAC
remote_stateIRGreeACprivate
send(const uint16_t repeat=kGreeDefaultRepeat)IRGreeAC
setDisplayTempSource(const uint8_t mode)IRGreeAC
setFan(const uint8_t speed)IRGreeAC
setIFeel(const bool on)IRGreeAC
setLight(const bool on)IRGreeAC
setMode(const uint8_t new_mode)IRGreeAC
setModel(const gree_ac_remote_model_t model)IRGreeAC
setPower(const bool on)IRGreeAC
setRaw(const uint8_t new_code[])IRGreeAC
setSleep(const bool on)IRGreeAC
setSwingVertical(const bool automatic, const uint8_t position)IRGreeAC
setTemp(const uint8_t temp, const bool fahrenheit=false)IRGreeAC
setTimer(const uint16_t minutes)IRGreeAC
setTimerEnabled(const bool on)IRGreeACprivate
setTurbo(const bool on)IRGreeAC
setUseFahrenheit(const bool on)IRGreeAC
setWiFi(const bool on)IRGreeAC
setXFan(const bool on)IRGreeAC
stateReset(void)IRGreeAC
toCommon(void)IRGreeAC
toCommonFanSpeed(const uint8_t speed)IRGreeACstatic
toCommonMode(const uint8_t mode)IRGreeACstatic
toCommonSwingV(const uint8_t pos)IRGreeACstatic
toString(void)IRGreeAC
validChecksum(const uint8_t state[], const uint16_t length=kGreeStateLength)IRGreeACstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC.html new file mode 100644 index 000000000..caaba0c2d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC.html @@ -0,0 +1,1751 @@ + + + + + + + +IRremoteESP8266: IRGreeAC Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Gree A/C messages. + More...

+ +

#include <ir_Gree.h>

+
+Collaboration diagram for IRGreeAC:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRGreeAC (const uint16_t pin, const gree_ac_remote_model_t model=gree_ac_remote_model_t::YAW1F, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset (void)
 Reset the internal state to a fixed known good state. More...
 
void send (const uint16_t repeat=kGreeDefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Change the power setting to On. More...
 
void off (void)
 Change the power setting to Off. More...
 
void setModel (const gree_ac_remote_model_t model)
 Set the model of the A/C to emulate. More...
 
gree_ac_remote_model_t getModel (void)
 Get/Detect the model of the A/C. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t temp, const bool fahrenheit=false)
 Set the temp. in degrees. More...
 
uint8_t getTemp (void)
 Get the set temperature. More...
 
void setUseFahrenheit (const bool on)
 Set the default temperature units to use. More...
 
bool getUseFahrenheit (void)
 Get the default temperature units in use. More...
 
void setFan (const uint8_t speed)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t new_mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setLight (const bool on)
 Set the Light (LED) setting of the A/C. More...
 
bool getLight (void)
 Get the Light (LED) setting of the A/C. More...
 
void setXFan (const bool on)
 Set the XFan (Mould) setting of the A/C. More...
 
bool getXFan (void)
 Get the XFan (Mould) setting of the A/C. More...
 
void setSleep (const bool on)
 Set the Sleep setting of the A/C. More...
 
bool getSleep (void)
 Get the Sleep setting of the A/C. More...
 
void setTurbo (const bool on)
 Set the Turbo setting of the A/C. More...
 
bool getTurbo (void)
 Get the Turbo setting of the A/C. More...
 
void setIFeel (const bool on)
 Set the IFeel setting of the A/C. More...
 
bool getIFeel (void)
 Get the IFeel setting of the A/C. More...
 
void setWiFi (const bool on)
 Set the Wifi (enabled) setting of the A/C. More...
 
bool getWiFi (void)
 Get the Wifi (enabled) setting of the A/C. More...
 
void setSwingVertical (const bool automatic, const uint8_t position)
 Set the Vertical Swing mode of the A/C. More...
 
bool getSwingVerticalAuto (void)
 Get the Vertical Swing Automatic mode setting of the A/C. More...
 
uint8_t getSwingVerticalPosition (void)
 Get the Vertical Swing position setting of the A/C. More...
 
uint16_t getTimer (void)
 Get the timer time value from the A/C. More...
 
void setTimer (const uint16_t minutes)
 Set the A/C's timer to turn off in X many minutes. More...
 
void setDisplayTempSource (const uint8_t mode)
 Set temperature display mode. i.e. Internal, External temperature sensing. More...
 
uint8_t getDisplayTempSource (void)
 Get the temperature display mode. i.e. Internal, External temperature sensing. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
uint8_t convertSwingV (const stdAc::swingv_t swingv)
 Convert a stdAc::swingv_t enum into it's native setting. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t new_code[])
 Set the internal state from a valid code for this protocol. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + + + + +

+Static Public Member Functions

static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
static stdAc::swingv_t toCommonSwingV (const uint8_t pos)
 Convert a stdAc::swingv_t enum into it's native setting. More...
 
static bool validChecksum (const uint8_t state[], const uint16_t length=kGreeStateLength)
 Verify the checksum is valid for a given state. More...
 
+ + + + + + + + + + + + + +

+Private Member Functions

void checksum (const uint16_t length=kGreeStateLength)
 Calculate and set the checksum values for the internal state. More...
 
void fixup (void)
 Fix up the internal state so it is correct. More...
 
void setTimerEnabled (const bool on)
 Set the timer enable setting of the A/C. More...
 
bool getTimerEnabled (void)
 Get the timer enabled setting of the A/C. More...
 
+ + + + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kGreeStateLength]
 The state in native IR code form. More...
 
gree_ac_remote_model_t _model
 
+

Detailed Description

+

Class for handling detailed Gree A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRGreeAC()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IRGreeAC::IRGreeAC (const uint16_t pin,
const gree_ac_remote_model_t model = gree_ac_remote_model_t::YAW1F,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + + +
[in]pinGPIO to be used when sending.
[in]modelThe enum of the model to be emulated.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRGreeAC::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRGreeAC::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
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.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRGreeAC::checksum (const uint16_t length = kGreeStateLength)
+
+private
+
+ +

Calculate and set the checksum values for the internal state.

+
Parameters
+ + +
[in]lengthThe size/length of the state array to fix the checksum of.
+
+
+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRGreeAC::convertFan (const stdAc::fanspeed_t speed)
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRGreeAC::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertSwingV()

+ +
+
+ + + + + + + + +
uint8_t IRGreeAC::convertSwingV (const stdAc::swingv_t swingv)
+
+ +

Convert a stdAc::swingv_t enum into it's native setting.

+
Parameters
+ + +
[in]swingvThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ fixup()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRGreeAC::fixup (void )
+
+private
+
+ +

Fix up the internal state so it is correct.

+
Note
Internal use only.
+ +
+
+ +

◆ getDisplayTempSource()

+ +
+
+ + + + + + + + +
uint8_t IRGreeAC::getDisplayTempSource (void )
+
+ +

Get the temperature display mode. i.e. Internal, External temperature sensing.

+
Returns
The current temp source being displayed.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRGreeAC::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getIFeel()

+ +
+
+ + + + + + + + +
bool IRGreeAC::getIFeel (void )
+
+ +

Get the IFeel setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getLight()

+ +
+
+ + + + + + + + +
bool IRGreeAC::getLight (void )
+
+ +

Get the Light (LED) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRGreeAC::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getModel()

+ +
+
+ + + + + + + + +
gree_ac_remote_model_t IRGreeAC::getModel (void )
+
+ +

Get/Detect the model of the A/C.

+
Returns
The enum of the compatible model.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRGreeAC::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/814
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRGreeAC::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSleep()

+ +
+
+ + + + + + + + +
bool IRGreeAC::getSleep (void )
+
+ +

Get the Sleep setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwingVerticalAuto()

+ +
+
+ + + + + + + + +
bool IRGreeAC::getSwingVerticalAuto (void )
+
+ +

Get the Vertical Swing Automatic mode setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwingVerticalPosition()

+ +
+
+ + + + + + + + +
uint8_t IRGreeAC::getSwingVerticalPosition (void )
+
+ +

Get the Vertical Swing position setting of the A/C.

+
Returns
The native position/mode.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRGreeAC::getTemp (void )
+
+ +

Get the set temperature.

+
Returns
The temperature in degrees in the current units (C/F) set.
+ +
+
+ +

◆ getTimer()

+ +
+
+ + + + + + + + +
uint16_t IRGreeAC::getTimer (void )
+
+ +

Get the timer time value from the A/C.

+
Returns
The number of minutes the timer is set for.
+ +
+
+ +

◆ getTimerEnabled()

+ +
+
+ + + + + +
+ + + + + + + + +
bool IRGreeAC::getTimerEnabled (void )
+
+private
+
+ +

Get the timer enabled setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTurbo()

+ +
+
+ + + + + + + + +
bool IRGreeAC::getTurbo (void )
+
+ +

Get the Turbo setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getUseFahrenheit()

+ +
+
+ + + + + + + + +
bool IRGreeAC::getUseFahrenheit (void )
+
+ +

Get the default temperature units in use.

+
Returns
true is Fahrenheit, false is Celsius.
+ +
+
+ +

◆ getWiFi()

+ +
+
+ + + + + + + + +
bool IRGreeAC::getWiFi (void )
+
+ +

Get the Wifi (enabled) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getXFan()

+ +
+
+ + + + + + + + +
bool IRGreeAC::getXFan (void )
+
+ +

Get the XFan (Mould) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRGreeAC::off (void )
+
+ +

Change the power setting to Off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRGreeAC::on (void )
+
+ +

Change the power setting to On.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRGreeAC::send (const uint16_t repeat = kGreeDefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setDisplayTempSource()

+ +
+
+ + + + + + + + +
void IRGreeAC::setDisplayTempSource (const uint8_t mode)
+
+ +

Set temperature display mode. i.e. Internal, External temperature sensing.

+
Parameters
+ + +
[in]modeThe desired temp source to display.
+
+
+
Note
In order for the A/C unit properly accept these settings. You must cycle (send) in the following order: kGreeDisplayTempOff(0) -> kGreeDisplayTempSet(1) -> kGreeDisplayTempInside(2) ->kGreeDisplayTempOutside(3) -> kGreeDisplayTempOff(0). The unit will no behave correctly if the changes of this setting are sent out of order.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/1118#issuecomment-628242152
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRGreeAC::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting. 0 is auto, 1-3 is the speed.
+
+
+ +
+
+ +

◆ setIFeel()

+ +
+
+ + + + + + + + +
void IRGreeAC::setIFeel (const bool on)
+
+ +

Set the IFeel setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setLight()

+ +
+
+ + + + + + + + +
void IRGreeAC::setLight (const bool on)
+
+ +

Set the Light (LED) setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRGreeAC::setMode (const uint8_t new_mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]new_modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setModel()

+ +
+
+ + + + + + + + +
void IRGreeAC::setModel (const gree_ac_remote_model_t model)
+
+ +

Set the model of the A/C to emulate.

+
Parameters
+ + +
[in]modelThe enum of the appropriate model.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRGreeAC::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/814
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRGreeAC::setRaw (const uint8_t new_code[])
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]new_codeA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSleep()

+ +
+
+ + + + + + + + +
void IRGreeAC::setSleep (const bool on)
+
+ +

Set the Sleep setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwingVertical()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRGreeAC::setSwingVertical (const bool automatic,
const uint8_t position 
)
+
+ +

Set the Vertical Swing mode of the A/C.

+
Parameters
+ + + +
[in]automaticDo we use the automatic setting?
[in]positionThe position/mode to set the vanes to.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRGreeAC::setTemp (const uint8_t temp,
const bool fahrenheit = false 
)
+
+ +

Set the temp. in degrees.

+
Parameters
+ + + +
[in]tempDesired temperature in Degrees.
[in]fahrenheitUse units of Fahrenheit and set that as units used. false is Celsius (Default), true is Fahrenheit.
+
+
+
Note
The unit actually works in Celsius with a special optional "extra degree" when sending Fahrenheit.
+ +
+
+ +

◆ setTimer()

+ +
+
+ + + + + + + + +
void IRGreeAC::setTimer (const uint16_t minutes)
+
+ +

Set the A/C's timer to turn off in X many minutes.

+
Parameters
+ + +
[in]minutesThe number of minutes the timer should be set for.
+
+
+
Note
Stores time internally in 30 min units. e.g. 5 mins means 0 (& Off), 95 mins is 90 mins (& On). Max is 24 hours.
+ +
+
+ +

◆ setTimerEnabled()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRGreeAC::setTimerEnabled (const bool on)
+
+private
+
+ +

Set the timer enable setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setTurbo()

+ +
+
+ + + + + + + + +
void IRGreeAC::setTurbo (const bool on)
+
+ +

Set the Turbo setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setUseFahrenheit()

+ +
+
+ + + + + + + + +
void IRGreeAC::setUseFahrenheit (const bool on)
+
+ +

Set the default temperature units to use.

+
Parameters
+ + +
[in]onUse Fahrenheit as the units. true is Fahrenheit, false is Celsius.
+
+
+ +
+
+ +

◆ setWiFi()

+ +
+
+ + + + + + + + +
void IRGreeAC::setWiFi (const bool on)
+
+ +

Set the Wifi (enabled) setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setXFan()

+ +
+
+ + + + + + + + +
void IRGreeAC::setXFan (const bool on)
+
+ +

Set the XFan (Mould) setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRGreeAC::stateReset (void )
+
+ +

Reset the internal state to a fixed known good state.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRGreeAC::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRGreeAC::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRGreeAC::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonSwingV()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::swingv_t IRGreeAC::toCommonSwingV (const uint8_t pos)
+
+static
+
+ +

Convert a stdAc::swingv_t enum into it's native setting.

+
Parameters
+ + +
[in]posThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRGreeAC::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRGreeAC::validChecksum (const uint8_t state[],
const uint16_t length = kGreeStateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length of the state array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRGreeAC::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ _model

+ +
+
+ + + + + +
+ + + + +
gree_ac_remote_model_t IRGreeAC::_model
+
+private
+
+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRGreeAC::remote_state[kGreeStateLength]
+
+private
+
+ +

The state in native IR code form.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC__coll__graph.map new file mode 100644 index 000000000..71a32c740 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC__coll__graph.md5 new file mode 100644 index 000000000..4d1a33b48 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC__coll__graph.md5 @@ -0,0 +1 @@ +cef6b5570dcbcd982fca1b3f3abc0c0f \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC__coll__graph.png new file mode 100644 index 000000000..c78390eeb Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRGreeAC__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierAC-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierAC-members.html new file mode 100644 index 000000000..88624b980 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierAC-members.html @@ -0,0 +1,121 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRHaierAC Member List
+
+
+ +

This is the complete list of members for IRHaierAC, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRHaierACprivate
begin(void)IRHaierAC
calibrate(void)IRHaierACinline
cancelTimers(void)IRHaierAC
checksum(void)IRHaierACprivate
convertFan(const stdAc::fanspeed_t speed)IRHaierAC
convertMode(const stdAc::opmode_t mode)IRHaierAC
convertSwingV(const stdAc::swingv_t position)IRHaierAC
getCommand(void)IRHaierAC
getCurrTime(void)IRHaierAC
getFan(void)IRHaierAC
getHealth(void)IRHaierAC
getMode(void)IRHaierAC
getOffTimer(void)IRHaierAC
getOnTimer(void)IRHaierAC
getRaw(void)IRHaierAC
getSleep(void)IRHaierAC
getSwing(void)IRHaierAC
getTemp(void)IRHaierAC
getTime(const uint8_t ptr[])IRHaierACprivatestatic
IRHaierAC(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRHaierACexplicit
remote_stateIRHaierACprivate
send(const uint16_t repeat=kHaierAcDefaultRepeat)IRHaierAC
setCommand(const uint8_t command)IRHaierAC
setCurrTime(const uint16_t mins)IRHaierAC
setFan(const uint8_t speed)IRHaierAC
setHealth(const bool on)IRHaierAC
setMode(const uint8_t mode)IRHaierAC
setOffTimer(const uint16_t mins)IRHaierAC
setOnTimer(const uint16_t mins)IRHaierAC
setRaw(const uint8_t new_code[])IRHaierAC
setSleep(const bool on)IRHaierAC
setSwing(const uint8_t state)IRHaierAC
setTemp(const uint8_t temp)IRHaierAC
setTime(uint8_t ptr[], const uint16_t nr_mins)IRHaierACprivatestatic
stateReset(void)IRHaierACprivate
toCommon(void)IRHaierAC
toCommonFanSpeed(const uint8_t speed)IRHaierACstatic
toCommonMode(const uint8_t mode)IRHaierACstatic
toCommonSwingV(const uint8_t pos)IRHaierACstatic
toString(void)IRHaierAC
validChecksum(uint8_t state[], const uint16_t length=kHaierACStateLength)IRHaierACstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierAC.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierAC.html new file mode 100644 index 000000000..cd27c878e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierAC.html @@ -0,0 +1,1370 @@ + + + + + + + +IRremoteESP8266: IRHaierAC Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Haier A/C messages. + More...

+ +

#include <ir_Haier.h>

+
+Collaboration diagram for IRHaierAC:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRHaierAC (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void send (const uint16_t repeat=kHaierAcDefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void setCommand (const uint8_t command)
 Set the Command/Button setting of the A/C. More...
 
uint8_t getCommand (void)
 Get the Command/Button setting of the A/C. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t speed)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
bool getSleep (void)
 Get the Sleep setting of the A/C. More...
 
void setSleep (const bool on)
 Set the Sleep setting of the A/C. More...
 
bool getHealth (void)
 Get the Health (filter) setting of the A/C. More...
 
void setHealth (const bool on)
 Set the Health (filter) setting of the A/C. More...
 
int16_t getOnTimer (void)
 Get the On Timer value/setting of the A/C. More...
 
void setOnTimer (const uint16_t mins)
 Set & enable the On Timer. More...
 
int16_t getOffTimer (void)
 Get the Off Timer value/setting of the A/C. More...
 
void setOffTimer (const uint16_t mins)
 Set & enable the Off Timer. More...
 
void cancelTimers (void)
 Cancel/disable the On & Off timers. More...
 
uint16_t getCurrTime (void)
 Get the clock value of the A/C. More...
 
void setCurrTime (const uint16_t mins)
 Set the clock value for the A/C. More...
 
uint8_t getSwing (void)
 Get the Vertical Swing position setting of the A/C. More...
 
void setSwing (const uint8_t state)
 Set the Vertical Swing mode of the A/C. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t new_code[])
 Set the internal state from a valid code for this protocol. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
uint8_t convertSwingV (const stdAc::swingv_t position)
 Convert a stdAc::swingv_t enum into it's native setting. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (uint8_t state[], const uint16_t length=kHaierACStateLength)
 Verify the checksum is valid for a given state. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
static stdAc::swingv_t toCommonSwingV (const uint8_t pos)
 Convert a stdAc::swingv_t enum into it's native setting. More...
 
+ + + + + + + +

+Private Member Functions

void stateReset (void)
 Reset the internal state to a fixed known good state. More...
 
void checksum (void)
 Calculate and set the checksum values for the internal state. More...
 
+ + + + + + + +

+Static Private Member Functions

static uint16_t getTime (const uint8_t ptr[])
 Get the Time value at the given pointer. More...
 
static void setTime (uint8_t ptr[], const uint16_t nr_mins)
 Set the Time value at the given pointer. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kHaierACStateLength]
 The state in native code form. More...
 
+

Detailed Description

+

Class for handling detailed Haier A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRHaierAC()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRHaierAC::IRHaierAC (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRHaierAC::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRHaierAC::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
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.
+ +
+
+ +

◆ cancelTimers()

+ +
+
+ + + + + + + + +
void IRHaierAC::cancelTimers (void )
+
+ +

Cancel/disable the On & Off timers.

+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRHaierAC::checksum (void )
+
+private
+
+ +

Calculate and set the checksum values for the internal state.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRHaierAC::convertFan (const stdAc::fanspeed_t speed)
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRHaierAC::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertSwingV()

+ +
+
+ + + + + + + + +
uint8_t IRHaierAC::convertSwingV (const stdAc::swingv_t position)
+
+ +

Convert a stdAc::swingv_t enum into it's native setting.

+
Parameters
+ + +
[in]positionThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getCommand()

+ +
+
+ + + + + + + + +
uint8_t IRHaierAC::getCommand (void )
+
+ +

Get the Command/Button setting of the A/C.

+
Returns
The value of the command/button that was pressed.
+ +
+
+ +

◆ getCurrTime()

+ +
+
+ + + + + + + + +
uint16_t IRHaierAC::getCurrTime (void )
+
+ +

Get the clock value of the A/C.

+
Returns
The clock time, in Nr of minutes past midnight.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRHaierAC::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getHealth()

+ +
+
+ + + + + + + + +
bool IRHaierAC::getHealth (void )
+
+ +

Get the Health (filter) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRHaierAC::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getOffTimer()

+ +
+
+ + + + + + + + +
int16_t IRHaierAC::getOffTimer (void )
+
+ +

Get the Off Timer value/setting of the A/C.

+
Returns
Nr of minutes the timer is set to. -1 is Off/not set etc.
+ +
+
+ +

◆ getOnTimer()

+ +
+
+ + + + + + + + +
int16_t IRHaierAC::getOnTimer (void )
+
+ +

Get the On Timer value/setting of the A/C.

+
Returns
Nr of minutes the timer is set to. -1 is Off/not set etc.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRHaierAC::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSleep()

+ +
+
+ + + + + + + + +
bool IRHaierAC::getSleep (void )
+
+ +

Get the Sleep setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwing()

+ +
+
+ + + + + + + + +
uint8_t IRHaierAC::getSwing (void )
+
+ +

Get the Vertical Swing position setting of the A/C.

+
Returns
The native swing mode.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRHaierAC::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ getTime()

+ +
+
+ + + + + +
+ + + + + + + + +
uint16_t IRHaierAC::getTime (const uint8_t ptr[])
+
+staticprivate
+
+ +

Get the Time value at the given pointer.

+
Parameters
+ + +
[in]ptrA Ptr to a location in the internal state to get the time.
+
+
+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRHaierAC::send (const uint16_t repeat = kHaierAcDefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setCommand()

+ +
+
+ + + + + + + + +
void IRHaierAC::setCommand (const uint8_t command)
+
+ +

Set the Command/Button setting of the A/C.

+
Parameters
+ + +
[in]commandThe value of the command/button that was pressed.
+
+
+ +
+
+ +

◆ setCurrTime()

+ +
+
+ + + + + + + + +
void IRHaierAC::setCurrTime (const uint16_t nr_mins)
+
+ +

Set the clock value for the A/C.

+
Parameters
+ + +
[in]nr_minsThe clock time, in Nr of minutes past midnight.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRHaierAC::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting.
+
+
+ +
+
+ +

◆ setHealth()

+ +
+
+ + + + + + + + +
void IRHaierAC::setHealth (const bool on)
+
+ +

Set the Health (filter) setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRHaierAC::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setOffTimer()

+ +
+
+ + + + + + + + +
void IRHaierAC::setOffTimer (const uint16_t nr_mins)
+
+ +

Set & enable the Off Timer.

+
Parameters
+ + +
[in]nr_minsThe time expressed in total number of minutes.
+
+
+ +
+
+ +

◆ setOnTimer()

+ +
+
+ + + + + + + + +
void IRHaierAC::setOnTimer (const uint16_t nr_mins)
+
+ +

Set & enable the On Timer.

+
Parameters
+ + +
[in]nr_minsThe time expressed in total number of minutes.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRHaierAC::setRaw (const uint8_t new_code[])
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]new_codeA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSleep()

+ +
+
+ + + + + + + + +
void IRHaierAC::setSleep (const bool on)
+
+ +

Set the Sleep setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwing()

+ +
+
+ + + + + + + + +
void IRHaierAC::setSwing (const uint8_t cmd)
+
+ +

Set the Vertical Swing mode of the A/C.

+
Parameters
+ + +
[in]cmdThe mode to set the vanes to.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRHaierAC::setTemp (const uint8_t degrees)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]degreesThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ setTime()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void IRHaierAC::setTime (uint8_t ptr[],
const uint16_t nr_mins 
)
+
+staticprivate
+
+ +

Set the Time value at the given pointer.

+
Parameters
+ + + +
[out]ptrA Ptr to a location in the internal state to set the time.
[in]nr_minsThe time expressed in total number of minutes.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRHaierAC::stateReset (void )
+
+private
+
+ +

Reset the internal state to a fixed known good state.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRHaierAC::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRHaierAC::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRHaierAC::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonSwingV()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::swingv_t IRHaierAC::toCommonSwingV (const uint8_t pos)
+
+static
+
+ +

Convert a stdAc::swingv_t enum into it's native setting.

+
Parameters
+ + +
[in]posThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRHaierAC::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRHaierAC::validChecksum (uint8_t state[],
const uint16_t length = kHaierACStateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length of the state array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRHaierAC::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRHaierAC::remote_state[kHaierACStateLength]
+
+private
+
+ +

The state in native code form.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02-members.html new file mode 100644 index 000000000..2cd4356de --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02-members.html @@ -0,0 +1,118 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRHaierACYRW02 Member List
+
+
+ +

This is the complete list of members for IRHaierACYRW02, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRHaierACYRW02private
begin(void)IRHaierACYRW02
calibrate(void)IRHaierACYRW02inline
checksum(void)IRHaierACYRW02private
convertFan(const stdAc::fanspeed_t speed)IRHaierACYRW02
convertMode(const stdAc::opmode_t mode)IRHaierACYRW02
convertSwingV(const stdAc::swingv_t position)IRHaierACYRW02
getButton(void)IRHaierACYRW02
getFan(void)IRHaierACYRW02
getHealth(void)IRHaierACYRW02
getMode(void)IRHaierACYRW02
getPower(void)IRHaierACYRW02
getRaw(void)IRHaierACYRW02
getSleep(void)IRHaierACYRW02
getSwing(void)IRHaierACYRW02
getTemp(void)IRHaierACYRW02
getTurbo(void)IRHaierACYRW02
IRHaierACYRW02(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRHaierACYRW02explicit
off(void)IRHaierACYRW02
on(void)IRHaierACYRW02
remote_stateIRHaierACYRW02private
send(const uint16_t repeat=kHaierAcYrw02DefaultRepeat)IRHaierACYRW02
setButton(const uint8_t button)IRHaierACYRW02
setFan(const uint8_t speed)IRHaierACYRW02
setHealth(const bool on)IRHaierACYRW02
setMode(const uint8_t mode)IRHaierACYRW02
setPower(const bool on)IRHaierACYRW02
setRaw(const uint8_t new_code[])IRHaierACYRW02
setSleep(const bool on)IRHaierACYRW02
setSwing(const uint8_t pos)IRHaierACYRW02
setTemp(const uint8_t temp)IRHaierACYRW02
setTurbo(const uint8_t speed)IRHaierACYRW02
stateReset(void)IRHaierACYRW02private
toCommon(void)IRHaierACYRW02
toCommonFanSpeed(const uint8_t speed)IRHaierACYRW02static
toCommonMode(const uint8_t mode)IRHaierACYRW02static
toCommonSwingV(const uint8_t pos)IRHaierACYRW02static
toString(void)IRHaierACYRW02
validChecksum(uint8_t state[], const uint16_t length=kHaierACYRW02StateLength)IRHaierACYRW02static
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02.html new file mode 100644 index 000000000..0bde44c52 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02.html @@ -0,0 +1,1252 @@ + + + + + + + +IRremoteESP8266: IRHaierACYRW02 Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Haier ACYRW02 A/C messages. + More...

+ +

#include <ir_Haier.h>

+
+Collaboration diagram for IRHaierACYRW02:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRHaierACYRW02 (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void send (const uint16_t repeat=kHaierAcYrw02DefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void setButton (const uint8_t button)
 Set the Button/Command setting of the A/C. More...
 
uint8_t getButton (void)
 Get the Button/Command setting of the A/C. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t speed)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
void on (void)
 Change the power setting to On. More...
 
void off (void)
 Change the power setting to Off. More...
 
bool getSleep (void)
 Get the Sleep setting of the A/C. More...
 
void setSleep (const bool on)
 Set the Sleep setting of the A/C. More...
 
bool getHealth (void)
 Get the Health (filter) setting of the A/C. More...
 
void setHealth (const bool on)
 Set the Health (filter) setting of the A/C. More...
 
uint8_t getTurbo (void)
 Get the Turbo setting of the A/C. More...
 
void setTurbo (const uint8_t speed)
 Set the Turbo setting of the A/C. More...
 
uint8_t getSwing (void)
 Get the Vertical Swing position setting of the A/C. More...
 
void setSwing (const uint8_t pos)
 Set the Vertical Swing mode of the A/C. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t new_code[])
 Set the internal state from a valid code for this protocol. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
uint8_t convertSwingV (const stdAc::swingv_t position)
 Convert a stdAc::swingv_t enum into it's native setting. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (uint8_t state[], const uint16_t length=kHaierACYRW02StateLength)
 Verify the checksum is valid for a given state. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
static stdAc::swingv_t toCommonSwingV (const uint8_t pos)
 Convert a stdAc::swingv_t enum into it's native setting. More...
 
+ + + + + + + +

+Private Member Functions

void stateReset (void)
 Reset the internal state to a fixed known good state. More...
 
void checksum (void)
 Calculate and set the checksum values for the internal state. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kHaierACYRW02StateLength]
 The state in native form. More...
 
+

Detailed Description

+

Class for handling detailed Haier ACYRW02 A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRHaierACYRW02()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRHaierACYRW02::IRHaierACYRW02 (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRHaierACYRW02::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRHaierACYRW02::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
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.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRHaierACYRW02::checksum (void )
+
+private
+
+ +

Calculate and set the checksum values for the internal state.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRHaierACYRW02::convertFan (const stdAc::fanspeed_t speed)
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRHaierACYRW02::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertSwingV()

+ +
+
+ + + + + + + + +
uint8_t IRHaierACYRW02::convertSwingV (const stdAc::swingv_t position)
+
+ +

Convert a stdAc::swingv_t enum into it's native setting.

+
Parameters
+ + +
[in]positionThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getButton()

+ +
+
+ + + + + + + + +
uint8_t IRHaierACYRW02::getButton (void )
+
+ +

Get the Button/Command setting of the A/C.

+
Returns
The value of the button/command that was pressed.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRHaierACYRW02::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getHealth()

+ +
+
+ + + + + + + + +
bool IRHaierACYRW02::getHealth (void )
+
+ +

Get the Health (filter) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRHaierACYRW02::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRHaierACYRW02::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRHaierACYRW02::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSleep()

+ +
+
+ + + + + + + + +
bool IRHaierACYRW02::getSleep (void )
+
+ +

Get the Sleep setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwing()

+ +
+
+ + + + + + + + +
uint8_t IRHaierACYRW02::getSwing (void )
+
+ +

Get the Vertical Swing position setting of the A/C.

+
Returns
The native position/mode.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRHaierACYRW02::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ getTurbo()

+ +
+
+ + + + + + + + +
uint8_t IRHaierACYRW02::getTurbo (void )
+
+ +

Get the Turbo setting of the A/C.

+
Returns
The current turbo speed setting.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRHaierACYRW02::off (void )
+
+ +

Change the power setting to Off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRHaierACYRW02::on (void )
+
+ +

Change the power setting to On.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRHaierACYRW02::send (const uint16_t repeat = kHaierAcYrw02DefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setButton()

+ +
+
+ + + + + + + + +
void IRHaierACYRW02::setButton (const uint8_t button)
+
+ +

Set the Button/Command setting of the A/C.

+
Parameters
+ + +
[in]buttonThe value of the button/command that was pressed.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRHaierACYRW02::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting.
+
+
+ +
+
+ +

◆ setHealth()

+ +
+
+ + + + + + + + +
void IRHaierACYRW02::setHealth (const bool on)
+
+ +

Set the Health (filter) setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRHaierACYRW02::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRHaierACYRW02::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRHaierACYRW02::setRaw (const uint8_t new_code[])
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]new_codeA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSleep()

+ +
+
+ + + + + + + + +
void IRHaierACYRW02::setSleep (const bool on)
+
+ +

Set the Sleep setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwing()

+ +
+
+ + + + + + + + +
void IRHaierACYRW02::setSwing (const uint8_t pos)
+
+ +

Set the Vertical Swing mode of the A/C.

+
Parameters
+ + +
[in]posThe position/mode to set the vanes to.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRHaierACYRW02::setTemp (const uint8_t celsius)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]celsiusThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ setTurbo()

+ +
+
+ + + + + + + + +
void IRHaierACYRW02::setTurbo (const uint8_t speed)
+
+ +

Set the Turbo setting of the A/C.

+
Parameters
+ + +
[in]speedThe desired turbo speed setting.
+
+
+
Note
Valid speeds are kHaierAcYrw02TurboOff, kHaierAcYrw02TurboLow, & kHaierAcYrw02TurboHigh.
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRHaierACYRW02::stateReset (void )
+
+private
+
+ +

Reset the internal state to a fixed known good state.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRHaierACYRW02::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRHaierACYRW02::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRHaierACYRW02::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonSwingV()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::swingv_t IRHaierACYRW02::toCommonSwingV (const uint8_t pos)
+
+static
+
+ +

Convert a stdAc::swingv_t enum into it's native setting.

+
Parameters
+ + +
[in]posThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRHaierACYRW02::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRHaierACYRW02::validChecksum (uint8_t state[],
const uint16_t length = kHaierACYRW02StateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length of the state array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRHaierACYRW02::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRHaierACYRW02::remote_state[kHaierACYRW02StateLength]
+
+private
+
+ +

The state in native form.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02__coll__graph.map new file mode 100644 index 000000000..02f95a3ca --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02__coll__graph.md5 new file mode 100644 index 000000000..cb292bd5a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02__coll__graph.md5 @@ -0,0 +1 @@ +cb076b246ab80c7206b22b94a46f6e24 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02__coll__graph.png new file mode 100644 index 000000000..2075e7a09 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierACYRW02__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierAC__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierAC__coll__graph.map new file mode 100644 index 000000000..18c05ac08 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierAC__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierAC__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierAC__coll__graph.md5 new file mode 100644 index 000000000..55ab50d1a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierAC__coll__graph.md5 @@ -0,0 +1 @@ +92ecbd6eeb437ac717bd50570ccc4754 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierAC__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierAC__coll__graph.png new file mode 100644 index 000000000..cfd0aef1e Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHaierAC__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc-members.html new file mode 100644 index 000000000..9ef04b870 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc-members.html @@ -0,0 +1,112 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRHitachiAc Member List
+
+
+ +

This is the complete list of members for IRHitachiAc, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRHitachiAcprivate
_previoustempIRHitachiAcprivate
begin(void)IRHitachiAc
calcChecksum(const uint8_t state[], const uint16_t length=kHitachiAcStateLength)IRHitachiAcstatic
calibrate(void)IRHitachiAcinline
checksum(const uint16_t length=kHitachiAcStateLength)IRHitachiAcprivate
convertFan(const stdAc::fanspeed_t speed)IRHitachiAc
convertMode(const stdAc::opmode_t mode)IRHitachiAc
getFan(void)IRHitachiAc
getMode(void)IRHitachiAc
getPower(void)IRHitachiAc
getRaw(void)IRHitachiAc
getSwingHorizontal(void)IRHitachiAc
getSwingVertical(void)IRHitachiAc
getTemp(void)IRHitachiAc
IRHitachiAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRHitachiAcexplicit
off(void)IRHitachiAc
on(void)IRHitachiAc
remote_stateIRHitachiAcprivate
send(const uint16_t repeat=kHitachiAcDefaultRepeat)IRHitachiAc
setFan(const uint8_t speed)IRHitachiAc
setMode(const uint8_t mode)IRHitachiAc
setPower(const bool on)IRHitachiAc
setRaw(const uint8_t new_code[], const uint16_t length=kHitachiAcStateLength)IRHitachiAc
setSwingHorizontal(const bool on)IRHitachiAc
setSwingVertical(const bool on)IRHitachiAc
setTemp(const uint8_t temp)IRHitachiAc
stateReset(void)IRHitachiAc
toCommon(void)IRHitachiAc
toCommonFanSpeed(const uint8_t speed)IRHitachiAcstatic
toCommonMode(const uint8_t mode)IRHitachiAcstatic
toString(void)IRHitachiAc
validChecksum(const uint8_t state[], const uint16_t length=kHitachiAcStateLength)IRHitachiAcstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc.html new file mode 100644 index 000000000..dacce3479 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc.html @@ -0,0 +1,1107 @@ + + + + + + + +IRremoteESP8266: IRHitachiAc Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Hitachi 224-bit A/C messages. + More...

+ +

#include <ir_Hitachi.h>

+
+Collaboration diagram for IRHitachiAc:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRHitachiAc (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset (void)
 Reset the internal state to a fixed known good state. More...
 
void send (const uint16_t repeat=kHitachiAcDefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Change the power setting to On. More...
 
void off (void)
 Change the power setting to Off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t speed)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setSwingVertical (const bool on)
 Set the Vertical Swing setting of the A/C. More...
 
bool getSwingVertical (void)
 Get the Vertical Swing setting of the A/C. More...
 
void setSwingHorizontal (const bool on)
 Set the Horizontal Swing setting of the A/C. More...
 
bool getSwingHorizontal (void)
 Get the Horizontal Swing setting of the A/C. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t new_code[], const uint16_t length=kHitachiAcStateLength)
 Set the internal state from a valid code for this protocol. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (const uint8_t state[], const uint16_t length=kHitachiAcStateLength)
 Verify the checksum is valid for a given state. More...
 
static uint8_t calcChecksum (const uint8_t state[], const uint16_t length=kHitachiAcStateLength)
 Calculate the checksum for a given state. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + +

+Private Member Functions

void checksum (const uint16_t length=kHitachiAcStateLength)
 Calculate and set the checksum values for the internal state. More...
 
+ + + + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kHitachiAcStateLength]
 The state in native code. More...
 
uint8_t _previoustemp
 
+

Detailed Description

+

Class for handling detailed Hitachi 224-bit A/C messages.

+
See also
https://github.com/ToniA/arduino-heatpumpir/blob/master/HitachiHeatpumpIR.cpp
+

Constructor & Destructor Documentation

+ +

◆ IRHitachiAc()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRHitachiAc::IRHitachiAc (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRHitachiAc::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calcChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
uint8_t IRHitachiAc::calcChecksum (const uint8_t state[],
const uint16_t length = kHitachiAcStateLength 
)
+
+static
+
+ +

Calculate the checksum for a given state.

+
Parameters
+ + + +
[in]stateThe value to calc the checksum of.
[in]lengthThe size/length of the state.
+
+
+
Returns
The calculated checksum value.
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRHitachiAc::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
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.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRHitachiAc::checksum (const uint16_t length = kHitachiAcStateLength)
+
+private
+
+ +

Calculate and set the checksum values for the internal state.

+
Parameters
+ + +
[in]lengthThe size/length of the state.
+
+
+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRHitachiAc::convertFan (const stdAc::fanspeed_t speed)
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRHitachiAc::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRHitachiAc::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRHitachiAc::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRHitachiAc::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRHitachiAc::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSwingHorizontal()

+ +
+
+ + + + + + + + +
bool IRHitachiAc::getSwingHorizontal (void )
+
+ +

Get the Horizontal Swing setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwingVertical()

+ +
+
+ + + + + + + + +
bool IRHitachiAc::getSwingVertical (void )
+
+ +

Get the Vertical Swing setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRHitachiAc::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRHitachiAc::off (void )
+
+ +

Change the power setting to Off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRHitachiAc::on (void )
+
+ +

Change the power setting to On.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRHitachiAc::send (const uint16_t repeat = kHitachiAcDefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRHitachiAc::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRHitachiAc::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRHitachiAc::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRHitachiAc::setRaw (const uint8_t new_code[],
const uint16_t length = kHitachiAcStateLength 
)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + + +
[in]new_codeA valid code for this protocol.
[in]lengthThe length of the new_code array.
+
+
+ +
+
+ +

◆ setSwingHorizontal()

+ +
+
+ + + + + + + + +
void IRHitachiAc::setSwingHorizontal (const bool on)
+
+ +

Set the Horizontal Swing setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwingVertical()

+ +
+
+ + + + + + + + +
void IRHitachiAc::setSwingVertical (const bool on)
+
+ +

Set the Vertical Swing setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRHitachiAc::setTemp (const uint8_t celsius)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]celsiusThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRHitachiAc::stateReset (void )
+
+ +

Reset the internal state to a fixed known good state.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRHitachiAc::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRHitachiAc::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRHitachiAc::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRHitachiAc::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRHitachiAc::validChecksum (const uint8_t state[],
const uint16_t length = kHitachiAcStateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length of the state array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRHitachiAc::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ _previoustemp

+ +
+
+ + + + + +
+ + + + +
uint8_t IRHitachiAc::_previoustemp
+
+private
+
+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRHitachiAc::remote_state[kHitachiAcStateLength]
+
+private
+
+ +

The state in native code.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1-members.html new file mode 100644 index 000000000..dc9801cec --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1-members.html @@ -0,0 +1,123 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRHitachiAc1 Member List
+
+
+ +

This is the complete list of members for IRHitachiAc1, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRHitachiAc1private
begin(void)IRHitachiAc1
calcChecksum(const uint8_t state[], const uint16_t length=kHitachiAc1StateLength)IRHitachiAc1static
calibrate(void)IRHitachiAc1inline
checksum(const uint16_t length=kHitachiAc1StateLength)IRHitachiAc1private
convertFan(const stdAc::fanspeed_t speed)IRHitachiAc1
convertMode(const stdAc::opmode_t mode)IRHitachiAc1
getFan(void)IRHitachiAc1
getMode(void)IRHitachiAc1
getModel(void)IRHitachiAc1
getOffTimer(void)IRHitachiAc1
getOnTimer(void)IRHitachiAc1
getPower(void)IRHitachiAc1
getPowerToggle(void)IRHitachiAc1
getRaw(void)IRHitachiAc1
getSleep(void)IRHitachiAc1
getSwingH(void)IRHitachiAc1
getSwingToggle(void)IRHitachiAc1
getSwingV(void)IRHitachiAc1
getTemp(void)IRHitachiAc1
IRHitachiAc1(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRHitachiAc1explicit
off(void)IRHitachiAc1
on(void)IRHitachiAc1
remote_stateIRHitachiAc1private
send(const uint16_t repeat=kHitachiAcDefaultRepeat)IRHitachiAc1
setFan(const uint8_t speed, const bool force=false)IRHitachiAc1
setMode(const uint8_t mode)IRHitachiAc1
setModel(const hitachi_ac1_remote_model_t model)IRHitachiAc1
setOffTimer(const uint16_t mins)IRHitachiAc1
setOnTimer(const uint16_t mins)IRHitachiAc1
setPower(const bool on)IRHitachiAc1
setPowerToggle(const bool on)IRHitachiAc1
setRaw(const uint8_t new_code[], const uint16_t length=kHitachiAc1StateLength)IRHitachiAc1
setSleep(const uint8_t mode)IRHitachiAc1
setSwingH(const bool on)IRHitachiAc1
setSwingToggle(const bool toggle)IRHitachiAc1
setSwingV(const bool on)IRHitachiAc1
setTemp(const uint8_t temp)IRHitachiAc1
stateReset(void)IRHitachiAc1
toCommon(void)IRHitachiAc1
toCommonFanSpeed(const uint8_t speed)IRHitachiAc1static
toCommonMode(const uint8_t mode)IRHitachiAc1static
toString(void)IRHitachiAc1
validChecksum(const uint8_t state[], const uint16_t length=kHitachiAc1StateLength)IRHitachiAc1static
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1.html new file mode 100644 index 000000000..227b908d6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1.html @@ -0,0 +1,1414 @@ + + + + + + + +IRremoteESP8266: IRHitachiAc1 Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Hitachi 104-bit A/C messages. + More...

+ +

#include <ir_Hitachi.h>

+
+Collaboration diagram for IRHitachiAc1:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRHitachiAc1 (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset (void)
 Reset the internal state to a fixed known good state. More...
 
void send (const uint16_t repeat=kHitachiAcDefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Change the power setting to On. More...
 
void off (void)
 Change the power setting to Off. More...
 
void setModel (const hitachi_ac1_remote_model_t model)
 Set the model of the A/C to emulate. More...
 
hitachi_ac1_remote_model_t getModel (void)
 Get/Detect the model of the A/C. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setPowerToggle (const bool on)
 Change the power toggle setting. More...
 
bool getPowerToggle (void)
 Get the value of the current power toggle setting. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t speed, const bool force=false)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setSwingToggle (const bool toggle)
 Set the Swing toggle setting of the A/C. More...
 
bool getSwingToggle (void)
 Get the Swing Toggle setting of the A/C. More...
 
void setSwingV (const bool on)
 Set the Vertical Swing setting of the A/C. More...
 
bool getSwingV (void)
 Get the Vertical Swing setting of the A/C. More...
 
void setSwingH (const bool on)
 Set the Horizontal Swing setting of the A/C. More...
 
bool getSwingH (void)
 Get the Horizontal Swing setting of the A/C. More...
 
void setSleep (const uint8_t mode)
 Set the Sleep setting of the A/C. More...
 
uint8_t getSleep (void)
 Get the Sleep setting of the A/C. More...
 
void setOnTimer (const uint16_t mins)
 Set the On Timer time. More...
 
uint16_t getOnTimer (void)
 Get the On Timer vtime of the A/C. More...
 
void setOffTimer (const uint16_t mins)
 Set the Off Timer time. More...
 
uint16_t getOffTimer (void)
 Get the Off Timer vtime of the A/C. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t new_code[], const uint16_t length=kHitachiAc1StateLength)
 Set the internal state from a valid code for this protocol. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (const uint8_t state[], const uint16_t length=kHitachiAc1StateLength)
 Verify the checksum is valid for a given state. More...
 
static uint8_t calcChecksum (const uint8_t state[], const uint16_t length=kHitachiAc1StateLength)
 Calculate the checksum for a given state. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + +

+Private Member Functions

void checksum (const uint16_t length=kHitachiAc1StateLength)
 Calculate and set the checksum values for the internal state. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kHitachiAc1StateLength]
 The state in native code. More...
 
+

Detailed Description

+

Class for handling detailed Hitachi 104-bit A/C messages.

+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/1056
+

Constructor & Destructor Documentation

+ +

◆ IRHitachiAc1()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRHitachiAc1::IRHitachiAc1 (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRHitachiAc1::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calcChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
uint8_t IRHitachiAc1::calcChecksum (const uint8_t state[],
const uint16_t length = kHitachiAc1StateLength 
)
+
+static
+
+ +

Calculate the checksum for a given state.

+
Parameters
+ + + +
[in]stateThe value to calc the checksum of.
[in]lengthThe size/length of the state.
+
+
+
Returns
The calculated checksum value.
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRHitachiAc1::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
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.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRHitachiAc1::checksum (const uint16_t length = kHitachiAc1StateLength)
+
+private
+
+ +

Calculate and set the checksum values for the internal state.

+
Parameters
+ + +
[in]lengthThe size/length of the state.
+
+
+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRHitachiAc1::convertFan (const stdAc::fanspeed_t speed)
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRHitachiAc1::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRHitachiAc1::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRHitachiAc1::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getModel()

+ +
+
+ + + + + + + + +
hitachi_ac1_remote_model_t IRHitachiAc1::getModel (void )
+
+ +

Get/Detect the model of the A/C.

+
Returns
The enum of the compatible model.
+ +
+
+ +

◆ getOffTimer()

+ +
+
+ + + + + + + + +
uint16_t IRHitachiAc1::getOffTimer (void )
+
+ +

Get the Off Timer vtime of the A/C.

+
Returns
Nr of minutes the timer is set to.
+ +
+
+ +

◆ getOnTimer()

+ +
+
+ + + + + + + + +
uint16_t IRHitachiAc1::getOnTimer (void )
+
+ +

Get the On Timer vtime of the A/C.

+
Returns
Nr of minutes the timer is set to.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRHitachiAc1::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getPowerToggle()

+ +
+
+ + + + + + + + +
bool IRHitachiAc1::getPowerToggle (void )
+
+ +

Get the value of the current power toggle setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRHitachiAc1::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSleep()

+ +
+
+ + + + + + + + +
uint8_t IRHitachiAc1::getSleep (void )
+
+ +

Get the Sleep setting of the A/C.

+
Returns
The currently configured sleep mode.
+
Note
Sleep modes only available in Auto & Cool modes, otherwise it's off.
+ +
+
+ +

◆ getSwingH()

+ +
+
+ + + + + + + + +
bool IRHitachiAc1::getSwingH (void )
+
+ +

Get the Horizontal Swing setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwingToggle()

+ +
+
+ + + + + + + + +
bool IRHitachiAc1::getSwingToggle (void )
+
+ +

Get the Swing Toggle setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwingV()

+ +
+
+ + + + + + + + +
bool IRHitachiAc1::getSwingV (void )
+
+ +

Get the Vertical Swing setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRHitachiAc1::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRHitachiAc1::off (void )
+
+ +

Change the power setting to Off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRHitachiAc1::on (void )
+
+ +

Change the power setting to On.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRHitachiAc1::send (const uint16_t repeat = kHitachiAcDefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRHitachiAc1::setFan (const uint8_t speed,
const bool force = false 
)
+
+ +

Set the speed of the fan.

+
Parameters
+ + + +
[in]speedThe desired setting.
[in]forceDo we allow setting the speed regardless of restrictions?
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRHitachiAc1::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setModel()

+ +
+
+ + + + + + + + +
void IRHitachiAc1::setModel (const hitachi_ac1_remote_model_t model)
+
+ +

Set the model of the A/C to emulate.

+
Parameters
+ + +
[in]modelThe enum of the appropriate model.
+
+
+ +
+
+ +

◆ setOffTimer()

+ +
+
+ + + + + + + + +
void IRHitachiAc1::setOffTimer (const uint16_t mins)
+
+ +

Set the Off Timer time.

+
Parameters
+ + +
[in]minsThe time expressed in total number of minutes.
+
+
+ +
+
+ +

◆ setOnTimer()

+ +
+
+ + + + + + + + +
void IRHitachiAc1::setOnTimer (const uint16_t mins)
+
+ +

Set the On Timer time.

+
Parameters
+ + +
[in]minsThe time expressed in total number of minutes.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRHitachiAc1::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setPowerToggle()

+ +
+
+ + + + + + + + +
void IRHitachiAc1::setPowerToggle (const bool on)
+
+ +

Change the power toggle setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRHitachiAc1::setRaw (const uint8_t new_code[],
const uint16_t length = kHitachiAc1StateLength 
)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + + +
[in]new_codeA valid code for this protocol.
[in]lengthThe length of the new_code array.
+
+
+ +
+
+ +

◆ setSleep()

+ +
+
+ + + + + + + + +
void IRHitachiAc1::setSleep (const uint8_t mode)
+
+ +

Set the Sleep setting of the A/C.

+
Parameters
+ + +
[in]modeThe mode of sleep to set the A/C to.
+
+
+
Note
Sleep modes only available in Auto & Cool modes, otherwise it's off.
+ +
+
+ +

◆ setSwingH()

+ +
+
+ + + + + + + + +
void IRHitachiAc1::setSwingH (const bool on)
+
+ +

Set the Horizontal Swing setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwingToggle()

+ +
+
+ + + + + + + + +
void IRHitachiAc1::setSwingToggle (const bool toggle)
+
+ +

Set the Swing toggle setting of the A/C.

+
Parameters
+ + +
[in]toggletrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwingV()

+ +
+
+ + + + + + + + +
void IRHitachiAc1::setSwingV (const bool on)
+
+ +

Set the Vertical Swing setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRHitachiAc1::setTemp (const uint8_t celsius)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]celsiusThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRHitachiAc1::stateReset (void )
+
+ +

Reset the internal state to a fixed known good state.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRHitachiAc1::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRHitachiAc1::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRHitachiAc1::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRHitachiAc1::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRHitachiAc1::validChecksum (const uint8_t state[],
const uint16_t length = kHitachiAc1StateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length of the state array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRHitachiAc1::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRHitachiAc1::remote_state[kHitachiAc1StateLength]
+
+private
+
+ +

The state in native code.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1__coll__graph.map new file mode 100644 index 000000000..09fed2d72 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1__coll__graph.md5 new file mode 100644 index 000000000..74b080a45 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1__coll__graph.md5 @@ -0,0 +1 @@ +887e1bb9117f6436abfa2cfbb296e5b6 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1__coll__graph.png new file mode 100644 index 000000000..5fa4b6344 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc1__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc3-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc3-members.html new file mode 100644 index 000000000..718bcbd17 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc3-members.html @@ -0,0 +1,91 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRHitachiAc3 Member List
+
+
+ +

This is the complete list of members for IRHitachiAc3, including all inherited members.

+ + + + + + + + + + + + + +
_irsendIRHitachiAc3private
begin(void)IRHitachiAc3
calibrate(void)IRHitachiAc3inline
getMode(void)IRHitachiAc3
getRaw(void)IRHitachiAc3
hasInvertedStates(const uint8_t state[], const uint16_t length)IRHitachiAc3static
IRHitachiAc3(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRHitachiAc3explicit
remote_stateIRHitachiAc3private
send(const uint16_t repeat=kHitachiAcDefaultRepeat)IRHitachiAc3
setInvertedStates(const uint16_t length=kHitachiAc3StateLength)IRHitachiAc3private
setRaw(const uint8_t new_code[], const uint16_t length=kHitachiAc3StateLength)IRHitachiAc3
stateReset(void)IRHitachiAc3
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc3.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc3.html new file mode 100644 index 000000000..c19681754 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc3.html @@ -0,0 +1,498 @@ + + + + + + + +IRremoteESP8266: IRHitachiAc3 Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Hitachi 15to27-byte/120to216-bit A/C messages. + More...

+ +

#include <ir_Hitachi.h>

+
+Collaboration diagram for IRHitachiAc3:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRHitachiAc3 (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset (void)
 Reset the internal state to a fixed known good state. More...
 
void send (const uint16_t repeat=kHitachiAcDefaultRepeat)
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
uint8_t getMode (void)
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t new_code[], const uint16_t length=kHitachiAc3StateLength)
 Set the internal state from a valid code for this protocol. More...
 
+ + + + +

+Static Public Member Functions

static bool hasInvertedStates (const uint8_t state[], const uint16_t length)
 Check if every second byte of the state, after the fixed header is inverted to the previous byte. More...
 
+ + + + +

+Private Member Functions

void setInvertedStates (const uint16_t length=kHitachiAc3StateLength)
 Invert every second byte of the internal state, after the fixed header. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kHitachiAc3StateLength]
 The state in native code. More...
 
+

Detailed Description

+

Class for handling detailed Hitachi 15to27-byte/120to216-bit A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRHitachiAc3()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRHitachiAc3::IRHitachiAc3 (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRHitachiAc3::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRHitachiAc3::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
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.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRHitachiAc3::getMode (void )
+
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRHitachiAc3::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ hasInvertedStates()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRHitachiAc3::hasInvertedStates (const uint8_t state[],
const uint16_t length 
)
+
+static
+
+ +

Check if every second byte of the state, after the fixed header is inverted to the previous byte.

+
Parameters
+ + + +
[in]stateThe state array to be checked.
[in]lengthThe size of the state array.
+
+
+
Note
This is this protocols integrity check.
+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRHitachiAc3::send (const uint16_t repeat = kHitachiAcDefaultRepeat)
+
+ +
+
+ +

◆ setInvertedStates()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRHitachiAc3::setInvertedStates (const uint16_t length = kHitachiAc3StateLength)
+
+private
+
+ +

Invert every second byte of the internal state, after the fixed header.

+
Parameters
+ + +
[in]lengthThe size of the state array.
+
+
+
Note
This is this protocols integrity check.
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRHitachiAc3::setRaw (const uint8_t new_code[],
const uint16_t length = kHitachiAc3StateLength 
)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + + +
[in]new_codeA valid code for this protocol.
[in]lengthThe length of the new_code array.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRHitachiAc3::stateReset (void )
+
+ +

Reset the internal state to a fixed known good state.

+
Note
Reset to auto fan, cooling, 23° Celsius
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRHitachiAc3::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRHitachiAc3::remote_state[kHitachiAc3StateLength]
+
+private
+
+ +

The state in native code.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344-members.html new file mode 100644 index 000000000..29331de19 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344-members.html @@ -0,0 +1,118 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRHitachiAc344 Member List
+
+
+ +

This is the complete list of members for IRHitachiAc344, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRHitachiAc424private
_previoustempIRHitachiAc424private
_toString(void)IRHitachiAc424private
begin(void)IRHitachiAc424
calibrate(void)IRHitachiAc424inline
convertFan(const stdAc::fanspeed_t speed)IRHitachiAc424
convertMode(const stdAc::opmode_t mode)IRHitachiAc424
convertSwingH(const stdAc::swingh_t position)IRHitachiAc344static
getButton(void)IRHitachiAc424
getFan(void)IRHitachiAc424
getMode(void)IRHitachiAc424
getPower(void)IRHitachiAc424
getRaw(void)IRHitachiAc424
getSwingH(void)IRHitachiAc344
getSwingV(void)IRHitachiAc344
getSwingVToggle(void)IRHitachiAc424
getTemp(void)IRHitachiAc424
IRHitachiAc344(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRHitachiAc344explicit
IRHitachiAc424(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRHitachiAc424explicit
off(void)IRHitachiAc424
on(void)IRHitachiAc424
remote_stateIRHitachiAc424private
send(const uint16_t repeat=kHitachiAcDefaultRepeat)IRHitachiAc344virtual
setButton(const uint8_t button)IRHitachiAc424
setFan(const uint8_t speed)IRHitachiAc424
setInvertedStates(void)IRHitachiAc424private
setMode(const uint8_t mode)IRHitachiAc424
setPower(const bool on)IRHitachiAc424
setRaw(const uint8_t new_code[], const uint16_t length=kHitachiAc344StateLength)IRHitachiAc344virtual
setSwingH(const uint8_t position)IRHitachiAc344
setSwingV(const bool on)IRHitachiAc344
setSwingVToggle(const bool on)IRHitachiAc424
setTemp(const uint8_t temp, bool setPrevious=true)IRHitachiAc424
stateReset(void)IRHitachiAc344virtual
toCommon(void)IRHitachiAc344virtual
toCommonFanSpeed(const uint8_t speed)IRHitachiAc424static
toCommonMode(const uint8_t mode)IRHitachiAc424static
toCommonSwingH(const uint8_t pos)IRHitachiAc344static
toString(void)IRHitachiAc344
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344.html new file mode 100644 index 000000000..9e46d328c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344.html @@ -0,0 +1,607 @@ + + + + + + + +IRremoteESP8266: IRHitachiAc344 Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
IRHitachiAc344 Class Reference
+
+
+ +

Class for handling detailed Hitachi 344-bit A/C messages. + More...

+ +

#include <ir_Hitachi.h>

+
+Inheritance diagram for IRHitachiAc344:
+
+
Inheritance graph
+ + + + +
[legend]
+
+Collaboration diagram for IRHitachiAc344:
+
+
Collaboration graph
+ + + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRHitachiAc344 (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor for handling detailed Hitachi_AC344 43 byte A/C messages. More...
 
void stateReset (void)
 Reset the internal state to auto fan, cooling, 23° Celsius. More...
 
void setRaw (const uint8_t new_code[], const uint16_t length=kHitachiAc344StateLength)
 Set the internal state from a valid code for this protocol. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
void send (const uint16_t repeat=kHitachiAcDefaultRepeat)
 Create and send the IR message to the A/C. More...
 
void setSwingV (const bool on)
 Control the vertical swing setting. More...
 
bool getSwingV (void)
 Get the current vertical swing setting. More...
 
void setSwingH (const uint8_t position)
 Control the horizontal swing setting. More...
 
uint8_t getSwingH (void)
 Get the current horizontal swing setting. More...
 
String toString (void)
 Convert the internal state into a human readable string. More...
 
- Public Member Functions inherited from IRHitachiAc424
 IRHitachiAc424 (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Change the power setting to On. More...
 
void off (void)
 Change the power setting to Off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t temp, bool setPrevious=true)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t speed)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
uint8_t getButton (void)
 Get the Button/Command setting of the A/C. More...
 
void setButton (const uint8_t button)
 Set the Button/Command pressed setting of the A/C. More...
 
void setSwingVToggle (const bool on)
 Set the Vertical Swing toggle setting of the A/C. More...
 
bool getSwingVToggle (void)
 Get the Vertical Swing toggle setting of the A/C. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
String toString (void)
 Convert the internal state into a human readable string. More...
 
+ + + + + + + + + + + + + + +

+Static Public Member Functions

static uint8_t convertSwingH (const stdAc::swingh_t position)
 Convert a standard A/C horizontal swing into its native setting. More...
 
static stdAc::swingh_t toCommonSwingH (const uint8_t pos)
 Convert a native horizontal swing postion to it's common equivalent. More...
 
- Static Public Member Functions inherited from IRHitachiAc424
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+

Detailed Description

+

Class for handling detailed Hitachi 344-bit A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRHitachiAc344()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRHitachiAc344::IRHitachiAc344 (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor for handling detailed Hitachi_AC344 43 byte A/C messages.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ convertSwingH()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRHitachiAc344::convertSwingH (const stdAc::swingh_t position)
+
+static
+
+ +

Convert a standard A/C horizontal swing into its native setting.

+
Parameters
+ + +
[in]positionA stdAc::swingh_t position to convert.
+
+
+
Returns
The equivilent native horizontal swing position.
+ +
+
+ +

◆ getSwingH()

+ +
+
+ + + + + + + + +
uint8_t IRHitachiAc344::getSwingH (void )
+
+ +

Get the current horizontal swing setting.

+
Returns
The current position horizontal swing is set to.
+ +
+
+ +

◆ getSwingV()

+ +
+
+ + + + + + + + +
bool IRHitachiAc344::getSwingV (void )
+
+ +

Get the current vertical swing setting.

+
Returns
True, if the setting is on. False, it is off.
+ +
+
+ +

◆ send()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRHitachiAc344::send (const uint16_t repeat = kHitachiAcDefaultRepeat)
+
+virtual
+
+ +

Create and send the IR message to the A/C.

+
Parameters
+ + +
[in]repeatNr. of times to repeat the message.
+
+
+ +

Reimplemented from IRHitachiAc424.

+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void IRHitachiAc344::setRaw (const uint8_t new_code[],
const uint16_t length = kHitachiAc344StateLength 
)
+
+virtual
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + + +
[in]new_codeA valid code for this protocol.
[in]lengthSize (in bytes) of the code for this protocol.
+
+
+ +

Reimplemented from IRHitachiAc424.

+ +
+
+ +

◆ setSwingH()

+ +
+
+ + + + + + + + +
void IRHitachiAc344::setSwingH (const uint8_t position)
+
+ +

Control the horizontal swing setting.

+
Parameters
+ + +
[in]positionThe position to set the horizontal swing to.
+
+
+ +
+
+ +

◆ setSwingV()

+ +
+
+ + + + + + + + +
void IRHitachiAc344::setSwingV (const bool on)
+
+ +

Control the vertical swing setting.

+
Parameters
+ + +
[in]onTrue, turns on the feature. False, turns off the feature.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRHitachiAc344::stateReset (void )
+
+virtual
+
+ +

Reset the internal state to auto fan, cooling, 23° Celsius.

+ +

Reimplemented from IRHitachiAc424.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::state_t IRHitachiAc344::toCommon (void )
+
+virtual
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +

Reimplemented from IRHitachiAc424.

+ +
+
+ +

◆ toCommonSwingH()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::swingh_t IRHitachiAc344::toCommonSwingH (const uint8_t pos)
+
+static
+
+ +

Convert a native horizontal swing postion to it's common equivalent.

+
Parameters
+ + +
[in]posA native position to convert.
+
+
+
Returns
The common horizontal swing position.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRHitachiAc344::toString (void )
+
+ +

Convert the internal state into a human readable string.

+
Returns
A string containing the settings in human-readable form.
+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__coll__graph.map new file mode 100644 index 000000000..10cf25d5a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__coll__graph.map @@ -0,0 +1,5 @@ + + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__coll__graph.md5 new file mode 100644 index 000000000..0f6757465 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__coll__graph.md5 @@ -0,0 +1 @@ +bc686b22e4ddf734f61a87c2609dac47 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__coll__graph.png new file mode 100644 index 000000000..2ba11bc48 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__inherit__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__inherit__graph.map new file mode 100644 index 000000000..6ee5f2904 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__inherit__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__inherit__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__inherit__graph.md5 new file mode 100644 index 000000000..5ccb815dc --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__inherit__graph.md5 @@ -0,0 +1 @@ +35cefb94d2f36be1ad5c9d511cbdbb17 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__inherit__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__inherit__graph.png new file mode 100644 index 000000000..85a663aa2 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc344__inherit__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc3__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc3__coll__graph.map new file mode 100644 index 000000000..7ab16fde8 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc3__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc3__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc3__coll__graph.md5 new file mode 100644 index 000000000..49092288c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc3__coll__graph.md5 @@ -0,0 +1 @@ +83b1a000783b5409d1f40cfaae3aa3e3 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc3__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc3__coll__graph.png new file mode 100644 index 000000000..f721b1bcd Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc3__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424-members.html new file mode 100644 index 000000000..468c48f73 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424-members.html @@ -0,0 +1,112 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRHitachiAc424 Member List
+
+
+ +

This is the complete list of members for IRHitachiAc424, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRHitachiAc424private
_previoustempIRHitachiAc424private
_toString(void)IRHitachiAc424private
begin(void)IRHitachiAc424
calibrate(void)IRHitachiAc424inline
convertFan(const stdAc::fanspeed_t speed)IRHitachiAc424
convertMode(const stdAc::opmode_t mode)IRHitachiAc424
getButton(void)IRHitachiAc424
getFan(void)IRHitachiAc424
getMode(void)IRHitachiAc424
getPower(void)IRHitachiAc424
getRaw(void)IRHitachiAc424
getSwingVToggle(void)IRHitachiAc424
getTemp(void)IRHitachiAc424
IRHitachiAc344 classIRHitachiAc424friend
IRHitachiAc424(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRHitachiAc424explicit
off(void)IRHitachiAc424
on(void)IRHitachiAc424
remote_stateIRHitachiAc424private
send(const uint16_t repeat=kHitachiAcDefaultRepeat)IRHitachiAc424virtual
setButton(const uint8_t button)IRHitachiAc424
setFan(const uint8_t speed)IRHitachiAc424
setInvertedStates(void)IRHitachiAc424private
setMode(const uint8_t mode)IRHitachiAc424
setPower(const bool on)IRHitachiAc424
setRaw(const uint8_t new_code[], const uint16_t length=kHitachiAc424StateLength)IRHitachiAc424virtual
setSwingVToggle(const bool on)IRHitachiAc424
setTemp(const uint8_t temp, bool setPrevious=true)IRHitachiAc424
stateReset(void)IRHitachiAc424virtual
toCommon(void)IRHitachiAc424virtual
toCommonFanSpeed(const uint8_t speed)IRHitachiAc424static
toCommonMode(const uint8_t mode)IRHitachiAc424static
toString(void)IRHitachiAc424
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424.html new file mode 100644 index 000000000..ecdf66cef --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424.html @@ -0,0 +1,1125 @@ + + + + + + + +IRremoteESP8266: IRHitachiAc424 Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Hitachi 53-byte/424-bit A/C messages. + More...

+ +

#include <ir_Hitachi.h>

+
+Inheritance diagram for IRHitachiAc424:
+
+
Inheritance graph
+ + + + +
[legend]
+
+Collaboration diagram for IRHitachiAc424:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRHitachiAc424 (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
virtual void stateReset (void)
 Reset the internal state to a fixed known good state. More...
 
virtual void send (const uint16_t repeat=kHitachiAcDefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Change the power setting to On. More...
 
void off (void)
 Change the power setting to Off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t temp, bool setPrevious=true)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t speed)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
uint8_t getButton (void)
 Get the Button/Command setting of the A/C. More...
 
void setButton (const uint8_t button)
 Set the Button/Command pressed setting of the A/C. More...
 
void setSwingVToggle (const bool on)
 Set the Vertical Swing toggle setting of the A/C. More...
 
bool getSwingVToggle (void)
 Get the Vertical Swing toggle setting of the A/C. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
virtual void setRaw (const uint8_t new_code[], const uint16_t length=kHitachiAc424StateLength)
 Set the internal state from a valid code for this protocol. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
virtual stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the internal state into a human readable string. More...
 
+ + + + + + + +

+Static Public Member Functions

static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + + + + +

+Private Member Functions

void setInvertedStates (void)
 Update the internal consistency check for the protocol. More...
 
String _toString (void)
 Convert the internal state into a human readable string for the settings that are common to protocols of this nature. More...
 
+ + + + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kHitachiAc424StateLength]
 The state in native code. More...
 
uint8_t _previoustemp
 
+ + + +

+Friends

class IRHitachiAc344
 
+

Detailed Description

+

Class for handling detailed Hitachi 53-byte/424-bit A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRHitachiAc424()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRHitachiAc424::IRHitachiAc424 (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ _toString()

+ +
+
+ + + + + +
+ + + + + + + + +
String IRHitachiAc424::_toString (void )
+
+private
+
+ +

Convert the internal state into a human readable string for the settings that are common to protocols of this nature.

+
Returns
A string containing the common settings in human-readable form.
+ +
+
+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRHitachiAc424::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRHitachiAc424::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
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.
+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRHitachiAc424::convertFan (const stdAc::fanspeed_t speed)
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRHitachiAc424::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getButton()

+ +
+
+ + + + + + + + +
uint8_t IRHitachiAc424::getButton (void )
+
+ +

Get the Button/Command setting of the A/C.

+
Returns
The value of the button/command that was pressed.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRHitachiAc424::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRHitachiAc424::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRHitachiAc424::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRHitachiAc424::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSwingVToggle()

+ +
+
+ + + + + + + + +
bool IRHitachiAc424::getSwingVToggle (void )
+
+ +

Get the Vertical Swing toggle setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRHitachiAc424::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRHitachiAc424::off (void )
+
+ +

Change the power setting to Off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRHitachiAc424::on (void )
+
+ +

Change the power setting to On.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRHitachiAc424::send (const uint16_t repeat = kHitachiAcDefaultRepeat)
+
+virtual
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +

Reimplemented in IRHitachiAc344.

+ +
+
+ +

◆ setButton()

+ +
+
+ + + + + + + + +
void IRHitachiAc424::setButton (const uint8_t button)
+
+ +

Set the Button/Command pressed setting of the A/C.

+
Parameters
+ + +
[in]buttonThe value of the button/command that was pressed.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRHitachiAc424::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting.
+
+
+ +
+
+ +

◆ setInvertedStates()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRHitachiAc424::setInvertedStates (void )
+
+private
+
+ +

Update the internal consistency check for the protocol.

+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRHitachiAc424::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRHitachiAc424::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void IRHitachiAc424::setRaw (const uint8_t new_code[],
const uint16_t length = kHitachiAc424StateLength 
)
+
+virtual
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + + +
[in]new_codeA valid code for this protocol.
[in]lengthThe length of the new_code array.
+
+
+ +

Reimplemented in IRHitachiAc344.

+ +
+
+ +

◆ setSwingVToggle()

+ +
+
+ + + + + + + + +
void IRHitachiAc424::setSwingVToggle (const bool on)
+
+ +

Set the Vertical Swing toggle setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+
Note
The remote does not keep state of the vertical swing. A byte is sent indicating the swing button is pressed on the remote
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRHitachiAc424::setTemp (const uint8_t celsius,
bool setPrevious = true 
)
+
+ +

Set the temperature.

+
Parameters
+ + + +
[in]celsiusThe temperature in degrees celsius.
[in]setPrevioustrue, remember this if we change mode. false, don't.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRHitachiAc424::stateReset (void )
+
+virtual
+
+ +

Reset the internal state to a fixed known good state.

+
Note
Reset to auto fan, cooling, 23° Celsius
+ +

Reimplemented in IRHitachiAc344.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::state_t IRHitachiAc424::toCommon (void )
+
+virtual
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +

Reimplemented in IRHitachiAc344.

+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRHitachiAc424::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRHitachiAc424::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRHitachiAc424::toString (void )
+
+ +

Convert the internal state into a human readable string.

+
Returns
A string containing the settings in human-readable form.
+ +
+
+

Friends And Related Function Documentation

+ +

◆ IRHitachiAc344

+ +
+
+ + + + + +
+ + + + +
friend class IRHitachiAc344
+
+friend
+
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRHitachiAc424::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ _previoustemp

+ +
+
+ + + + + +
+ + + + +
uint8_t IRHitachiAc424::_previoustemp
+
+private
+
+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRHitachiAc424::remote_state[kHitachiAc424StateLength]
+
+private
+
+ +

The state in native code.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__coll__graph.map new file mode 100644 index 000000000..7cbfa51cc --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__coll__graph.md5 new file mode 100644 index 000000000..1ac39cb1f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__coll__graph.md5 @@ -0,0 +1 @@ +e27758fabb1539bba026d03c86a2d75d \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__coll__graph.png new file mode 100644 index 000000000..3bb4db79f Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__inherit__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__inherit__graph.map new file mode 100644 index 000000000..b93678e31 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__inherit__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__inherit__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__inherit__graph.md5 new file mode 100644 index 000000000..8cc016c00 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__inherit__graph.md5 @@ -0,0 +1 @@ +83321b013f1eecd9a72546893407d4cc \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__inherit__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__inherit__graph.png new file mode 100644 index 000000000..df924b19f Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc424__inherit__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc__coll__graph.map new file mode 100644 index 000000000..dcb9d35cc --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc__coll__graph.md5 new file mode 100644 index 000000000..16865578f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc__coll__graph.md5 @@ -0,0 +1 @@ +aeb4ec71968654b70565a578d510a768 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc__coll__graph.png new file mode 100644 index 000000000..3f092bb9a Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRHitachiAc__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC-members.html new file mode 100644 index 000000000..9ecc5c43f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC-members.html @@ -0,0 +1,121 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRKelvinatorAC Member List
+
+
+ +

This is the complete list of members for IRKelvinatorAC, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRKelvinatorACprivate
begin(void)IRKelvinatorAC
calcBlockChecksum(const uint8_t *block, const uint16_t length=kKelvinatorStateLength/2)IRKelvinatorACstatic
calibrate(void)IRKelvinatorACinline
checksum(const uint16_t length=kKelvinatorStateLength)IRKelvinatorACprivate
convertMode(const stdAc::opmode_t mode)IRKelvinatorAC
fixup(void)IRKelvinatorACprivate
getFan(void)IRKelvinatorAC
getIonFilter(void)IRKelvinatorAC
getLight(void)IRKelvinatorAC
getMode(void)IRKelvinatorAC
getPower(void)IRKelvinatorAC
getQuiet(void)IRKelvinatorAC
getRaw(void)IRKelvinatorAC
getSwingHorizontal(void)IRKelvinatorAC
getSwingVertical(void)IRKelvinatorAC
getTemp(void)IRKelvinatorAC
getTurbo(void)IRKelvinatorAC
getXFan(void)IRKelvinatorAC
IRKelvinatorAC(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRKelvinatorACexplicit
off(void)IRKelvinatorAC
on(void)IRKelvinatorAC
remote_stateIRKelvinatorACprivate
send(const uint16_t repeat=kKelvinatorDefaultRepeat)IRKelvinatorAC
setFan(const uint8_t speed)IRKelvinatorAC
setIonFilter(const bool on)IRKelvinatorAC
setLight(const bool on)IRKelvinatorAC
setMode(const uint8_t mode)IRKelvinatorAC
setPower(const bool on)IRKelvinatorAC
setQuiet(const bool on)IRKelvinatorAC
setRaw(const uint8_t new_code[])IRKelvinatorAC
setSwingHorizontal(const bool on)IRKelvinatorAC
setSwingVertical(const bool on)IRKelvinatorAC
setTemp(const uint8_t degrees)IRKelvinatorAC
setTurbo(const bool on)IRKelvinatorAC
setXFan(const bool on)IRKelvinatorAC
stateReset(void)IRKelvinatorAC
toCommon(void)IRKelvinatorAC
toCommonFanSpeed(const uint8_t speed)IRKelvinatorACstatic
toCommonMode(const uint8_t mode)IRKelvinatorACstatic
toString(void)IRKelvinatorAC
validChecksum(const uint8_t state[], const uint16_t length=kKelvinatorStateLength)IRKelvinatorACstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC.html new file mode 100644 index 000000000..1eb7ab15c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC.html @@ -0,0 +1,1340 @@ + + + + + + + +IRremoteESP8266: IRKelvinatorAC Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Kelvinator A/C messages. + More...

+ +

#include <ir_Kelvinator.h>

+
+Collaboration diagram for IRKelvinatorAC:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRKelvinatorAC (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset (void)
 Reset the internals of the object to a known good state. More...
 
void send (const uint16_t repeat=kKelvinatorDefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Set the internal state to have the power on. More...
 
void off (void)
 Set the internal state to have the power off. More...
 
void setPower (const bool on)
 Set the internal state to have the desired power. More...
 
bool getPower (void)
 Get the power setting from the internal state. More...
 
void setTemp (const uint8_t degrees)
 Set the temperature setting. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t speed)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the desired operation mode. More...
 
uint8_t getMode (void)
 Get the current operation mode setting. More...
 
void setSwingVertical (const bool on)
 Control the current vertical swing setting. More...
 
bool getSwingVertical (void)
 Is the vertical swing setting on? More...
 
void setSwingHorizontal (const bool on)
 Control the current horizontal swing setting. More...
 
bool getSwingHorizontal (void)
 Is the horizontal swing setting on? More...
 
void setQuiet (const bool on)
 Control the current Quiet setting. More...
 
bool getQuiet (void)
 Is the Quiet setting on? More...
 
void setIonFilter (const bool on)
 Control the current Ion Filter setting. More...
 
bool getIonFilter (void)
 Is the Ion Filter setting on? More...
 
void setLight (const bool on)
 Control the current Light setting. i.e. The LED display on the A/C unit that shows the basic settings. More...
 
bool getLight (void)
 Is the Light (Display) setting on? More...
 
void setXFan (const bool on)
 Control the current XFan setting. This setting will cause the unit blow air after power off to dry out the A/C device. More...
 
bool getXFan (void)
 Is the XFan setting on? More...
 
void setTurbo (const bool on)
 Control the current Turbo setting. More...
 
bool getTurbo (void)
 Is the Turbo setting on? More...
 
uint8_t * getRaw (void)
 Get the raw state of the object, suitable to be sent with the appropriate IRsend object method. More...
 
void setRaw (const uint8_t new_code[])
 Set the raw state of the object. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a standard A/C mode (stdAc::opmode_t) into it a native mode. More...
 
stdAc::state_t toCommon (void)
 Convert the internal A/C object state to it's stdAc::state_t equivalent. More...
 
String toString (void)
 Convert the internal settings into a human readable string. More...
 
+ + + + + + + + + + + + + +

+Static Public Member Functions

static uint8_t calcBlockChecksum (const uint8_t *block, const uint16_t length=kKelvinatorStateLength/2)
 Calculate the checksum for a given block of state. More...
 
static bool validChecksum (const uint8_t state[], const uint16_t length=kKelvinatorStateLength)
 Verify the checksum is valid for a given state. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode to it's stdAc::opmode_t equivalent. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed to it's stdAc::fanspeed_t equivalent. More...
 
+ + + + + + + +

+Private Member Functions

void checksum (const uint16_t length=kKelvinatorStateLength)
 Calculate the checksum for the internal state. More...
 
void fixup (void)
 Fix up any odd conditions for the current state. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kKelvinatorStateLength]
 The state in IR code form. More...
 
+

Detailed Description

+

Class for handling detailed Kelvinator A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRKelvinatorAC()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRKelvinatorAC::IRKelvinatorAC (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRKelvinatorAC::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calcBlockChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
uint8_t IRKelvinatorAC::calcBlockChecksum (const uint8_t * block,
const uint16_t length = kKelvinatorStateLength / 2 
)
+
+static
+
+ +

Calculate the checksum for a given block of state.

+
Parameters
+ + + +
[in]blockA pointer to a block to calc the checksum of.
[in]lengthLength of the block array to checksum.
+
+
+
Returns
The calculated checksum value.
+
Note
Many Bothans died to bring us this information.
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRKelvinatorAC::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
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.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRKelvinatorAC::checksum (const uint16_t length = kKelvinatorStateLength)
+
+private
+
+ +

Calculate the checksum for the internal state.

+
Parameters
+ + +
[in]lengthLength of the internal state to checksum.
+
+
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRKelvinatorAC::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a standard A/C mode (stdAc::opmode_t) into it a native mode.

+
Parameters
+ + +
[in]modeA stdAc::opmode_t operation mode.
+
+
+
Returns
The native mode equivilant.
+ +
+
+ +

◆ fixup()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRKelvinatorAC::fixup (void )
+
+private
+
+ +

Fix up any odd conditions for the current state.

+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRKelvinatorAC::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getIonFilter()

+ +
+
+ + + + + + + + +
bool IRKelvinatorAC::getIonFilter (void )
+
+ +

Is the Ion Filter setting on?

+
Returns
The current value.
+ +
+
+ +

◆ getLight()

+ +
+
+ + + + + + + + +
bool IRKelvinatorAC::getLight (void )
+
+ +

Is the Light (Display) setting on?

+
Returns
The current value.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRKelvinatorAC::getMode (void )
+
+ +

Get the current operation mode setting.

+
Returns
The current operation mode.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRKelvinatorAC::getPower (void )
+
+ +

Get the power setting from the internal state.

+
Returns
A boolean indicating if the power setting.
+ +
+
+ +

◆ getQuiet()

+ +
+
+ + + + + + + + +
bool IRKelvinatorAC::getQuiet (void )
+
+ +

Is the Quiet setting on?

+
Returns
The current value.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRKelvinatorAC::getRaw (void )
+
+ +

Get the raw state of the object, suitable to be sent with the appropriate IRsend object method.

+
Returns
A PTR to the internal state.
+ +
+
+ +

◆ getSwingHorizontal()

+ +
+
+ + + + + + + + +
bool IRKelvinatorAC::getSwingHorizontal (void )
+
+ +

Is the horizontal swing setting on?

+
Returns
The current value.
+ +
+
+ +

◆ getSwingVertical()

+ +
+
+ + + + + + + + +
bool IRKelvinatorAC::getSwingVertical (void )
+
+ +

Is the vertical swing setting on?

+
Returns
The current value.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRKelvinatorAC::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
Get current setting for temp. in degrees celsius.
+ +
+
+ +

◆ getTurbo()

+ +
+
+ + + + + + + + +
bool IRKelvinatorAC::getTurbo (void )
+
+ +

Is the Turbo setting on?

+
Returns
The current value.
+ +
+
+ +

◆ getXFan()

+ +
+
+ + + + + + + + +
bool IRKelvinatorAC::getXFan (void )
+
+ +

Is the XFan setting on?

+
Returns
The current value.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRKelvinatorAC::off (void )
+
+ +

Set the internal state to have the power off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRKelvinatorAC::on (void )
+
+ +

Set the internal state to have the power on.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRKelvinatorAC::send (const uint16_t repeat = kKelvinatorDefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRKelvinatorAC::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speed0 is auto, 1-5 is the speed
+
+
+ +
+
+ +

◆ setIonFilter()

+ +
+
+ + + + + + + + +
void IRKelvinatorAC::setIonFilter (const bool on)
+
+ +

Control the current Ion Filter setting.

+
Parameters
+ + +
[in]onThe desired setting.
+
+
+ +
+
+ +

◆ setLight()

+ +
+
+ + + + + + + + +
void IRKelvinatorAC::setLight (const bool on)
+
+ +

Control the current Light setting. i.e. The LED display on the A/C unit that shows the basic settings.

+
Parameters
+ + +
[in]onThe desired setting.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRKelvinatorAC::setMode (const uint8_t mode)
+
+ +

Set the desired operation mode.

+
Parameters
+ + +
[in]modeThe desired operation mode.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRKelvinatorAC::setPower (const bool on)
+
+ +

Set the internal state to have the desired power.

+
Parameters
+ + +
[in]onThe desired power state.
+
+
+ +
+
+ +

◆ setQuiet()

+ +
+
+ + + + + + + + +
void IRKelvinatorAC::setQuiet (const bool on)
+
+ +

Control the current Quiet setting.

+
Parameters
+ + +
[in]onThe desired setting.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRKelvinatorAC::setRaw (const uint8_t new_code[])
+
+ +

Set the raw state of the object.

+
Parameters
+ + +
[in]new_codeThe raw state from the native IR message.
+
+
+ +
+
+ +

◆ setSwingHorizontal()

+ +
+
+ + + + + + + + +
void IRKelvinatorAC::setSwingHorizontal (const bool on)
+
+ +

Control the current horizontal swing setting.

+
Parameters
+ + +
[in]onThe desired setting.
+
+
+ +
+
+ +

◆ setSwingVertical()

+ +
+
+ + + + + + + + +
void IRKelvinatorAC::setSwingVertical (const bool on)
+
+ +

Control the current vertical swing setting.

+
Parameters
+ + +
[in]onThe desired setting.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRKelvinatorAC::setTemp (const uint8_t degrees)
+
+ +

Set the temperature setting.

+
Parameters
+ + +
[in]degreesThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ setTurbo()

+ +
+
+ + + + + + + + +
void IRKelvinatorAC::setTurbo (const bool on)
+
+ +

Control the current Turbo setting.

+
Note
Turbo mode is turned off if the fan speed is changed.
+
Parameters
+ + +
[in]onThe desired setting.
+
+
+ +
+
+ +

◆ setXFan()

+ +
+
+ + + + + + + + +
void IRKelvinatorAC::setXFan (const bool on)
+
+ +

Control the current XFan setting. This setting will cause the unit blow air after power off to dry out the A/C device.

+
Note
XFan mode is only valid in Cool or Dry mode.
+
Parameters
+ + +
[in]onThe desired setting.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRKelvinatorAC::stateReset (void )
+
+ +

Reset the internals of the object to a known good state.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRKelvinatorAC::toCommon (void )
+
+ +

Convert the internal A/C object state to it's stdAc::state_t equivalent.

+
Returns
A stdAc::state_t containing the current settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRKelvinatorAC::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed to it's stdAc::fanspeed_t equivalent.

+
Parameters
+ + +
[in]speedA native fan speed value.
+
+
+
Returns
The stdAc::fanspeed_t equivilant.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRKelvinatorAC::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode to it's stdAc::opmode_t equivalent.

+
Parameters
+ + +
[in]modeA native operating mode value.
+
+
+
Returns
The stdAc::opmode_t equivilant.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRKelvinatorAC::toString (void )
+
+ +

Convert the internal settings into a human readable string.

+
Returns
A String.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRKelvinatorAC::validChecksum (const uint8_t state[],
const uint16_t length = kKelvinatorStateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe size of the state.
+
+
+
Returns
A boolean indicating if it is valid.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRKelvinatorAC::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRKelvinatorAC::remote_state[kKelvinatorStateLength]
+
+private
+
+ +

The state in IR code form.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC__coll__graph.map new file mode 100644 index 000000000..40f1acb8c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC__coll__graph.md5 new file mode 100644 index 000000000..5fe2723e9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC__coll__graph.md5 @@ -0,0 +1 @@ +bb0276d1879b23e51b948f404eb3a682 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC__coll__graph.png new file mode 100644 index 000000000..e06512959 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRKelvinatorAC__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc-members.html new file mode 100644 index 000000000..63a5286d7 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc-members.html @@ -0,0 +1,113 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRLgAc Member List
+
+
+ +

This is the complete list of members for IRLgAc, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRLgAcprivate
_protocolIRLgAcprivate
_setTemp(const uint8_t value)IRLgAcprivate
_tempIRLgAcprivate
begin(void)IRLgAc
calcChecksum(const uint32_t state)IRLgAcstatic
calibrate(void)IRLgAcinline
checksum(void)IRLgAcprivate
convertFan(const stdAc::fanspeed_t speed)IRLgAcstatic
convertMode(const stdAc::opmode_t mode)IRLgAc
getFan(void)IRLgAc
getMode(void)IRLgAc
getModel(void)IRLgAc
getPower(void)IRLgAc
getRaw(void)IRLgAc
getTemp(void)IRLgAc
IRLgAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRLgAcexplicit
isValidLgAc(void)IRLgAc
off(void)IRLgAc
on(void)IRLgAc
remote_stateIRLgAcprivate
send(const uint16_t repeat=kLgDefaultRepeat)IRLgAc
setFan(const uint8_t speed)IRLgAc
setMode(const uint8_t mode)IRLgAc
setModel(const lg_ac_remote_model_t model)IRLgAc
setPower(const bool on)IRLgAc
setRaw(const uint32_t new_code)IRLgAc
setTemp(const uint8_t degrees)IRLgAc
stateReset(void)IRLgAc
toCommon(void)IRLgAc
toCommonFanSpeed(const uint8_t speed)IRLgAcstatic
toCommonMode(const uint8_t mode)IRLgAcstatic
toString(void)IRLgAc
validChecksum(const uint32_t state)IRLgAcstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc.html new file mode 100644 index 000000000..a65b6eeaf --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc.html @@ -0,0 +1,1108 @@ + + + + + + + +IRremoteESP8266: IRLgAc Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed LG A/C messages. + More...

+ +

#include <ir_LG.h>

+
+Collaboration diagram for IRLgAc:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRLgAc (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset (void)
 Reset the internals of the object to a known good state. More...
 
bool isValidLgAc (void)
 Check if the internal state looks like a valud LG A/C message. More...
 
void send (const uint16_t repeat=kLgDefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Change the power setting to On. More...
 
void off (void)
 Change the power setting to Off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t degrees)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t speed)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
uint32_t getRaw (void)
 Get a copy of the internal state/code for this protocol. More...
 
void setRaw (const uint32_t new_code)
 Set the internal state from a valid code for this protocol. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
void setModel (const lg_ac_remote_model_t model)
 Set the model of the A/C to emulate. More...
 
lg_ac_remote_model_t getModel (void)
 Get the model of the A/C. More...
 
+ + + + + + + + + + + + + + + + +

+Static Public Member Functions

static uint8_t calcChecksum (const uint32_t state)
 Calculate the checksum for a given state. More...
 
static bool validChecksum (const uint32_t state)
 Verify the checksum is valid for a given state. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
static uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
+ + + + + + + +

+Private Member Functions

void checksum (void)
 Calculate and set the checksum values for the internal state. More...
 
void _setTemp (const uint8_t value)
 Set the temperature. More...
 
+ + + + + + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint32_t remote_state
 The state of the IR remote in IR code form. More...
 
uint8_t _temp
 
decode_type_t _protocol
 
+

Detailed Description

+

Class for handling detailed LG A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRLgAc()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRLgAc::IRLgAc (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ _setTemp()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRLgAc::_setTemp (const uint8_t value)
+
+private
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]valueThe native temperature.
+
+
+
Note
Internal use only.
+ +
+
+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRLgAc::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calcChecksum()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRLgAc::calcChecksum (const uint32_t state)
+
+static
+
+ +

Calculate the checksum for a given state.

+
Parameters
+ + +
[in]stateThe value to calc the checksum of.
+
+
+
Returns
The calculated checksum value.
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRLgAc::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
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.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRLgAc::checksum (void )
+
+private
+
+ +

Calculate and set the checksum values for the internal state.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRLgAc::convertFan (const stdAc::fanspeed_t speed)
+
+static
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRLgAc::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRLgAc::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRLgAc::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getModel()

+ +
+
+ + + + + + + + +
lg_ac_remote_model_t IRLgAc::getModel (void )
+
+ +

Get the model of the A/C.

+
Returns
The enum of the compatible model.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRLgAc::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint32_t IRLgAc::getRaw (void )
+
+ +

Get a copy of the internal state/code for this protocol.

+
Returns
The code for this protocol based on the current internal state.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRLgAc::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ isValidLgAc()

+ +
+
+ + + + + + + + +
bool IRLgAc::isValidLgAc (void )
+
+ +

Check if the internal state looks like a valud LG A/C message.

+
Returns
true, the internal state is a valid LG A/C mesg. Otherwise, false.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRLgAc::off (void )
+
+ +

Change the power setting to Off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRLgAc::on (void )
+
+ +

Change the power setting to On.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRLgAc::send (const uint16_t repeat = kLgDefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRLgAc::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRLgAc::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setModel()

+ +
+
+ + + + + + + + +
void IRLgAc::setModel (const lg_ac_remote_model_t model)
+
+ +

Set the model of the A/C to emulate.

+
Parameters
+ + +
[in]modelThe enum of the appropriate model.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRLgAc::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRLgAc::setRaw (const uint32_t new_code)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]new_codeA valid code for this protocol.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRLgAc::setTemp (const uint8_t degrees)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]degreesThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRLgAc::stateReset (void )
+
+ +

Reset the internals of the object to a known good state.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRLgAc::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRLgAc::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRLgAc::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRLgAc::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + +
bool IRLgAc::validChecksum (const uint32_t state)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + +
[in]stateThe value to verify the checksum of.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRLgAc::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ _protocol

+ +
+
+ + + + + +
+ + + + +
decode_type_t IRLgAc::_protocol
+
+private
+
+ +
+
+ +

◆ _temp

+ +
+
+ + + + + +
+ + + + +
uint8_t IRLgAc::_temp
+
+private
+
+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint32_t IRLgAc::remote_state
+
+private
+
+ +

The state of the IR remote in IR code form.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc__coll__graph.map new file mode 100644 index 000000000..37558d8ac --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc__coll__graph.md5 new file mode 100644 index 000000000..0626aca74 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc__coll__graph.md5 @@ -0,0 +1 @@ +56fb7c83360ef1487cea622f026510d6 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc__coll__graph.png new file mode 100644 index 000000000..3fabc3386 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRLgAc__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC-members.html new file mode 100644 index 000000000..59046578a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC-members.html @@ -0,0 +1,115 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRMideaAC Member List
+
+
+ +

This is the complete list of members for IRMideaAC, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRMideaACprivate
_SwingVToggleIRMideaACprivate
begin(void)IRMideaAC
calcChecksum(const uint64_t state)IRMideaACprivatestatic
calibrate(void)IRMideaACinline
checksum(void)IRMideaACprivate
convertFan(const stdAc::fanspeed_t speed)IRMideaAC
convertMode(const stdAc::opmode_t mode)IRMideaAC
getFan(void)IRMideaAC
getMode(void)IRMideaAC
getPower(void)IRMideaAC
getRaw(void)IRMideaAC
getSleep(void)IRMideaAC
getSwingVToggle(void)IRMideaAC
getTemp(const bool useCelsius=false)IRMideaAC
getUseCelsius(void)IRMideaAC
IRMideaAC(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRMideaACexplicit
isSwingVToggle(void)IRMideaAC
off(void)IRMideaAC
on(void)IRMideaAC
remote_stateIRMideaACprivate
send(const uint16_t repeat=kMideaMinRepeat)IRMideaAC
setFan(const uint8_t fan)IRMideaAC
setMode(const uint8_t mode)IRMideaAC
setPower(const bool on)IRMideaAC
setRaw(const uint64_t newState)IRMideaAC
setSleep(const bool on)IRMideaAC
setSwingVToggle(const bool on)IRMideaAC
setTemp(const uint8_t temp, const bool useCelsius=false)IRMideaAC
setUseCelsius(const bool celsius)IRMideaAC
stateReset(void)IRMideaAC
toCommon(const stdAc::state_t *prev=NULL)IRMideaAC
toCommonFanSpeed(const uint8_t speed)IRMideaACstatic
toCommonMode(const uint8_t mode)IRMideaACstatic
toString(void)IRMideaAC
validChecksum(const uint64_t state)IRMideaACstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC.html new file mode 100644 index 000000000..15c9dde37 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC.html @@ -0,0 +1,1169 @@ + + + + + + + +IRremoteESP8266: IRMideaAC Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Midea A/C messages. + More...

+ +

#include <ir_Midea.h>

+
+Collaboration diagram for IRMideaAC:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRMideaAC (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset (void)
 Reset the state of the remote to a known good state/sequence. More...
 
void send (const uint16_t repeat=kMideaMinRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Set the requested power state of the A/C to on. More...
 
void off (void)
 Set the requested power state of the A/C to off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
bool getUseCelsius (void)
 Is the device currently using Celsius or the Fahrenheit temp scale? More...
 
void setUseCelsius (const bool celsius)
 Set the A/C unit to use Celsius natively. More...
 
void setTemp (const uint8_t temp, const bool useCelsius=false)
 Set the temperature. More...
 
uint8_t getTemp (const bool useCelsius=false)
 Get the current temperature setting. More...
 
void setFan (const uint8_t fan)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setRaw (const uint64_t newState)
 Set the internal state from a valid code for this protocol. More...
 
uint64_t getRaw (void)
 Get a copy of the internal state/code for this protocol. More...
 
void setSleep (const bool on)
 Set the Sleep setting of the A/C. More...
 
bool getSleep (void)
 Get the Sleep setting of the A/C. More...
 
bool isSwingVToggle (void)
 Is the current state a vertical swing toggle message? More...
 
void setSwingVToggle (const bool on)
 Set the A/C to toggle the vertical swing toggle for the next send. More...
 
bool getSwingVToggle (void)
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
stdAc::state_t toCommon (const stdAc::state_t *prev=NULL)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (const uint64_t state)
 Verify the checksum is valid for a given state. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + +

+Private Member Functions

void checksum (void)
 Calculate & set the checksum for the current internal state of the remote. More...
 
+ + + + +

+Static Private Member Functions

static uint8_t calcChecksum (const uint64_t state)
 Calculate the checksum for a given state. More...
 
+ + + + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint64_t remote_state
 The state of the IR remote in IR code form. More...
 
bool _SwingVToggle
 
+

Detailed Description

+

Class for handling detailed Midea A/C messages.

+
Warning
Consider this very alpha code.
+

Constructor & Destructor Documentation

+ +

◆ IRMideaAC()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRMideaAC::IRMideaAC (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRMideaAC::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calcChecksum()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRMideaAC::calcChecksum (const uint64_t state)
+
+staticprivate
+
+ +

Calculate the checksum for a given state.

+
Parameters
+ + +
[in]stateThe value to calc the checksum of.
+
+
+
Returns
The calculated checksum value.
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRMideaAC::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
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.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRMideaAC::checksum (void )
+
+private
+
+ +

Calculate & set the checksum for the current internal state of the remote.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRMideaAC::convertFan (const stdAc::fanspeed_t speed)
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRMideaAC::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRMideaAC::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRMideaAC::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRMideaAC::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint64_t IRMideaAC::getRaw (void )
+
+ +

Get a copy of the internal state/code for this protocol.

+
Returns
The code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSleep()

+ +
+
+ + + + + + + + +
bool IRMideaAC::getSleep (void )
+
+ +

Get the Sleep setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwingVToggle()

+ +
+
+ + + + + + + + +
bool IRMideaAC::getSwingVToggle (void )
+
+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRMideaAC::getTemp (const bool celsius = false)
+
+ +

Get the current temperature setting.

+
Parameters
+ + +
[in]celsiustrue, the results are in Celsius. false, in Fahrenheit.
+
+
+
Returns
The current setting for temp. in the requested units/scale.
+ +
+
+ +

◆ getUseCelsius()

+ +
+
+ + + + + + + + +
bool IRMideaAC::getUseCelsius (void )
+
+ +

Is the device currently using Celsius or the Fahrenheit temp scale?

+
Returns
true, the A/C unit uses Celsius natively, false, is Fahrenheit.
+ +
+
+ +

◆ isSwingVToggle()

+ +
+
+ + + + + + + + +
bool IRMideaAC::isSwingVToggle (void )
+
+ +

Is the current state a vertical swing toggle message?

+
Returns
true, it is. false, it isn't.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRMideaAC::off (void )
+
+ +

Set the requested power state of the A/C to off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRMideaAC::on (void )
+
+ +

Set the requested power state of the A/C to on.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRMideaAC::send (const uint16_t repeat = kMideaMinRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRMideaAC::setFan (const uint8_t fan)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]fanThe desired setting. 1-3 set the speed, 0 for auto.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRMideaAC::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRMideaAC::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRMideaAC::setRaw (const uint64_t newState)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]newStateA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSleep()

+ +
+
+ + + + + + + + +
void IRMideaAC::setSleep (const bool on)
+
+ +

Set the Sleep setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwingVToggle()

+ +
+
+ + + + + + + + +
void IRMideaAC::setSwingVToggle (const bool on)
+
+ +

Set the A/C to toggle the vertical swing toggle for the next send.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRMideaAC::setTemp (const uint8_t temp,
const bool useCelsius = false 
)
+
+ +

Set the temperature.

+
Parameters
+ + + +
[in]tempThe temperature in degrees celsius.
[in]useCelsiustrue, use the Celsius temp scale. false, is Fahrenheit
+
+
+ +
+
+ +

◆ setUseCelsius()

+ +
+
+ + + + + + + + +
void IRMideaAC::setUseCelsius (const bool on)
+
+ +

Set the A/C unit to use Celsius natively.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRMideaAC::stateReset (void )
+
+ +

Reset the state of the remote to a known good state/sequence.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRMideaAC::toCommon (const stdAc::state_tprev = NULL)
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Parameters
+ + +
[in]prevA Ptr to the previous state.
+
+
+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRMideaAC::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRMideaAC::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRMideaAC::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + +
bool IRMideaAC::validChecksum (const uint64_t state)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + +
[in]stateThe state to verify the checksum of.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRMideaAC::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ _SwingVToggle

+ +
+
+ + + + + +
+ + + + +
bool IRMideaAC::_SwingVToggle
+
+private
+
+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint64_t IRMideaAC::remote_state
+
+private
+
+ +

The state of the IR remote in IR code form.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC__coll__graph.map new file mode 100644 index 000000000..7a5ecc57e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC__coll__graph.md5 new file mode 100644 index 000000000..c12aeb84b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC__coll__graph.md5 @@ -0,0 +1 @@ +7a6c2ec0b798d60bf8731cf20896a6a1 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC__coll__graph.png new file mode 100644 index 000000000..47fc1c6e9 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMideaAC__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi112-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi112-members.html new file mode 100644 index 000000000..c65f1fb8d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi112-members.html @@ -0,0 +1,115 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRMitsubishi112 Member List
+
+
+ +

This is the complete list of members for IRMitsubishi112, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRMitsubishi112private
begin(void)IRMitsubishi112
calibrate(void)IRMitsubishi112inline
checksum(void)IRMitsubishi112private
convertFan(const stdAc::fanspeed_t speed)IRMitsubishi112static
convertMode(const stdAc::opmode_t mode)IRMitsubishi112static
convertSwingH(const stdAc::swingh_t position)IRMitsubishi112static
convertSwingV(const stdAc::swingv_t position)IRMitsubishi112static
getFan(void)IRMitsubishi112
getMode(void)IRMitsubishi112
getPower(void)IRMitsubishi112
getQuiet(void)IRMitsubishi112
getRaw(void)IRMitsubishi112
getSwingH(void)IRMitsubishi112
getSwingV(void)IRMitsubishi112
getTemp(void)IRMitsubishi112
IRMitsubishi112(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRMitsubishi112explicit
off(void)IRMitsubishi112
on(void)IRMitsubishi112
remote_stateIRMitsubishi112private
send(const uint16_t repeat=kMitsubishi112MinRepeat)IRMitsubishi112
setFan(const uint8_t speed)IRMitsubishi112
setMode(const uint8_t mode)IRMitsubishi112
setPower(const bool on)IRMitsubishi112
setQuiet(const bool on)IRMitsubishi112
setRaw(const uint8_t *data)IRMitsubishi112
setSwingH(const uint8_t position)IRMitsubishi112
setSwingV(const uint8_t position)IRMitsubishi112
setTemp(const uint8_t degrees)IRMitsubishi112
stateReset(void)IRMitsubishi112
toCommon(void)IRMitsubishi112
toCommonFanSpeed(const uint8_t speed)IRMitsubishi112static
toCommonMode(const uint8_t mode)IRMitsubishi112static
toCommonSwingH(const uint8_t pos)IRMitsubishi112static
toCommonSwingV(const uint8_t pos)IRMitsubishi112static
toString(void)IRMitsubishi112
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi112.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi112.html new file mode 100644 index 000000000..601d1e36a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi112.html @@ -0,0 +1,1185 @@ + + + + + + + +IRremoteESP8266: IRMitsubishi112 Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

#include <ir_Mitsubishi.h>

+
+Collaboration diagram for IRMitsubishi112:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRMitsubishi112 (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset (void)
 Reset the state of the remote to a known good state/sequence. More...
 
void send (const uint16_t repeat=kMitsubishi112MinRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Set the requested power state of the A/C to off. More...
 
void off (void)
 Set the requested power state of the A/C to off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t degrees)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t speed)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setSwingV (const uint8_t position)
 Set the Vertical Swing mode of the A/C. More...
 
uint8_t getSwingV (void)
 Get the Vertical Swing mode of the A/C. More...
 
void setSwingH (const uint8_t position)
 Set the Horizontal Swing mode of the A/C. More...
 
uint8_t getSwingH (void)
 Get the Horizontal Swing mode of the A/C. More...
 
void setQuiet (const bool on)
 Set the Quiet mode of the A/C. More...
 
bool getQuiet (void)
 Get the Quiet mode of the A/C. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t *data)
 Set the internal state from a valid code for this protocol. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the internal state into a human readable string. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + +

+Static Public Member Functions

static uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
static uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
static uint8_t convertSwingV (const stdAc::swingv_t position)
 Convert a stdAc::swingv_t enum into it's native setting. More...
 
static uint8_t convertSwingH (const stdAc::swingh_t position)
 Convert a stdAc::swingh_t enum into it's native setting. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
static stdAc::swingv_t toCommonSwingV (const uint8_t pos)
 Convert a native vertical swing postion to it's common equivalent. More...
 
static stdAc::swingh_t toCommonSwingH (const uint8_t pos)
 Convert a native horizontal swing postion to it's common equivalent. More...
 
+ + + + +

+Private Member Functions

void checksum (void)
 Calculate the checksum for the current internal state of the remote. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kMitsubishi112StateLength]
 The state in code form. More...
 
+

Constructor & Destructor Documentation

+ +

◆ IRMitsubishi112()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRMitsubishi112::IRMitsubishi112 (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRMitsubishi112::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRMitsubishi112::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
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.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRMitsubishi112::checksum (void )
+
+private
+
+ +

Calculate the checksum for the current internal state of the remote.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRMitsubishi112::convertFan (const stdAc::fanspeed_t speed)
+
+static
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRMitsubishi112::convertMode (const stdAc::opmode_t mode)
+
+static
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertSwingH()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRMitsubishi112::convertSwingH (const stdAc::swingh_t position)
+
+static
+
+ +

Convert a stdAc::swingh_t enum into it's native setting.

+
Parameters
+ + +
[in]positionThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertSwingV()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRMitsubishi112::convertSwingV (const stdAc::swingv_t position)
+
+static
+
+ +

Convert a stdAc::swingv_t enum into it's native setting.

+
Parameters
+ + +
[in]positionThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishi112::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed/mode.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishi112::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRMitsubishi112::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getQuiet()

+ +
+
+ + + + + + + + +
bool IRMitsubishi112::getQuiet (void )
+
+ +

Get the Quiet mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+
Note
There is no true quiet setting on this A/C.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRMitsubishi112::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSwingH()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishi112::getSwingH (void )
+
+ +

Get the Horizontal Swing mode of the A/C.

+
Returns
The native position/mode setting.
+ +
+
+ +

◆ getSwingV()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishi112::getSwingV (void )
+
+ +

Get the Vertical Swing mode of the A/C.

+
Returns
The native position/mode setting.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishi112::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRMitsubishi112::off (void )
+
+ +

Set the requested power state of the A/C to off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRMitsubishi112::on (void )
+
+ +

Set the requested power state of the A/C to off.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRMitsubishi112::send (const uint16_t repeat = kMitsubishi112MinRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRMitsubishi112::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRMitsubishi112::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRMitsubishi112::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setQuiet()

+ +
+
+ + + + + + + + +
void IRMitsubishi112::setQuiet (const bool on)
+
+ +

Set the Quiet mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+
Note
There is no true quiet setting on this A/C.
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRMitsubishi112::setRaw (const uint8_t * data)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]dataA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSwingH()

+ +
+
+ + + + + + + + +
void IRMitsubishi112::setSwingH (const uint8_t position)
+
+ +

Set the Horizontal Swing mode of the A/C.

+
Parameters
+ + +
[in]positionThe position/mode to set the swing to.
+
+
+ +
+
+ +

◆ setSwingV()

+ +
+
+ + + + + + + + +
void IRMitsubishi112::setSwingV (const uint8_t position)
+
+ +

Set the Vertical Swing mode of the A/C.

+
Parameters
+ + +
[in]positionThe position/mode to set the swing to.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRMitsubishi112::setTemp (const uint8_t degrees)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]degreesThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRMitsubishi112::stateReset (void )
+
+ +

Reset the state of the remote to a known good state/sequence.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRMitsubishi112::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRMitsubishi112::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRMitsubishi112::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonSwingH()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::swingh_t IRMitsubishi112::toCommonSwingH (const uint8_t pos)
+
+static
+
+ +

Convert a native horizontal swing postion to it's common equivalent.

+
Parameters
+ + +
[in]posA native position to convert.
+
+
+
Returns
The common horizontal swing position.
+ +
+
+ +

◆ toCommonSwingV()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::swingv_t IRMitsubishi112::toCommonSwingV (const uint8_t pos)
+
+static
+
+ +

Convert a native vertical swing postion to it's common equivalent.

+
Parameters
+ + +
[in]posA native position to convert.
+
+
+
Returns
The common vertical swing position.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRMitsubishi112::toString (void )
+
+ +

Convert the internal state into a human readable string.

+
Returns
A string containing the settings in human-readable form.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRMitsubishi112::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRMitsubishi112::remote_state[kMitsubishi112StateLength]
+
+private
+
+ +

The state in code form.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi112__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi112__coll__graph.map new file mode 100644 index 000000000..b03481d27 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi112__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi112__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi112__coll__graph.md5 new file mode 100644 index 000000000..40fbd03d5 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi112__coll__graph.md5 @@ -0,0 +1 @@ +648b0b04c461ef09d8fa8c3efa7d7090 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi112__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi112__coll__graph.png new file mode 100644 index 000000000..a75dab94b Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi112__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi136-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi136-members.html new file mode 100644 index 000000000..cebd8098c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi136-members.html @@ -0,0 +1,112 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRMitsubishi136 Member List
+
+
+ +

This is the complete list of members for IRMitsubishi136, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRMitsubishi136private
begin(void)IRMitsubishi136
calibrate(void)IRMitsubishi136inline
checksum(void)IRMitsubishi136private
convertFan(const stdAc::fanspeed_t speed)IRMitsubishi136static
convertMode(const stdAc::opmode_t mode)IRMitsubishi136static
convertSwingV(const stdAc::swingv_t position)IRMitsubishi136static
getFan(void)IRMitsubishi136
getMode(void)IRMitsubishi136
getPower(void)IRMitsubishi136
getQuiet(void)IRMitsubishi136
getRaw(void)IRMitsubishi136
getSwingV(void)IRMitsubishi136
getTemp(void)IRMitsubishi136
IRMitsubishi136(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRMitsubishi136explicit
off(void)IRMitsubishi136
on(void)IRMitsubishi136
remote_stateIRMitsubishi136private
send(const uint16_t repeat=kMitsubishi136MinRepeat)IRMitsubishi136
setFan(const uint8_t speed)IRMitsubishi136
setMode(const uint8_t mode)IRMitsubishi136
setPower(const bool on)IRMitsubishi136
setQuiet(const bool on)IRMitsubishi136
setRaw(const uint8_t *data)IRMitsubishi136
setSwingV(const uint8_t position)IRMitsubishi136
setTemp(const uint8_t degrees)IRMitsubishi136
stateReset(void)IRMitsubishi136
toCommon(void)IRMitsubishi136
toCommonFanSpeed(const uint8_t speed)IRMitsubishi136static
toCommonMode(const uint8_t mode)IRMitsubishi136static
toCommonSwingV(const uint8_t pos)IRMitsubishi136static
toString(void)IRMitsubishi136
validChecksum(const uint8_t *data, const uint16_t len=kMitsubishi136StateLength)IRMitsubishi136static
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi136.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi136.html new file mode 100644 index 000000000..456227963 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi136.html @@ -0,0 +1,1108 @@ + + + + + + + +IRremoteESP8266: IRMitsubishi136 Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Mitsubishi 136-bit A/C messages. + More...

+ +

#include <ir_Mitsubishi.h>

+
+Collaboration diagram for IRMitsubishi136:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRMitsubishi136 (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset (void)
 Reset the state of the remote to a known good state/sequence. More...
 
void send (const uint16_t repeat=kMitsubishi136MinRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Set the requested power state of the A/C to on. More...
 
void off (void)
 Set the requested power state of the A/C to off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t degrees)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t speed)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setSwingV (const uint8_t position)
 Set the Vertical Swing mode of the A/C. More...
 
uint8_t getSwingV (void)
 Get the Vertical Swing mode of the A/C. More...
 
void setQuiet (const bool on)
 Set the Quiet mode of the A/C. More...
 
bool getQuiet (void)
 Get the Quiet mode of the A/C. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t *data)
 Set the internal state from a valid code for this protocol. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the internal state into a human readable string. More...
 
+ + + + + + + + + + + + + + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (const uint8_t *data, const uint16_t len=kMitsubishi136StateLength)
 Verify the checksum is valid for a given state. More...
 
static uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
static uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
static uint8_t convertSwingV (const stdAc::swingv_t position)
 Convert a stdAc::swingv_t enum into it's native setting. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
static stdAc::swingv_t toCommonSwingV (const uint8_t pos)
 Convert a native vertical swing postion to it's common equivalent. More...
 
+ + + + +

+Private Member Functions

void checksum (void)
 Calculate the checksum for the current internal state of the remote. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kMitsubishi136StateLength]
 The state in code form. More...
 
+

Detailed Description

+

Class for handling detailed Mitsubishi 136-bit A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRMitsubishi136()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRMitsubishi136::IRMitsubishi136 (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRMitsubishi136::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRMitsubishi136::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
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.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRMitsubishi136::checksum (void )
+
+private
+
+ +

Calculate the checksum for the current internal state of the remote.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRMitsubishi136::convertFan (const stdAc::fanspeed_t speed)
+
+static
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRMitsubishi136::convertMode (const stdAc::opmode_t mode)
+
+static
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertSwingV()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRMitsubishi136::convertSwingV (const stdAc::swingv_t position)
+
+static
+
+ +

Convert a stdAc::swingv_t enum into it's native setting.

+
Parameters
+ + +
[in]positionThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishi136::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed/mode.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishi136::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRMitsubishi136::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getQuiet()

+ +
+
+ + + + + + + + +
bool IRMitsubishi136::getQuiet (void )
+
+ +

Get the Quiet mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRMitsubishi136::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSwingV()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishi136::getSwingV (void )
+
+ +

Get the Vertical Swing mode of the A/C.

+
Returns
The native position/mode setting.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishi136::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRMitsubishi136::off (void )
+
+ +

Set the requested power state of the A/C to off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRMitsubishi136::on (void )
+
+ +

Set the requested power state of the A/C to on.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRMitsubishi136::send (const uint16_t repeat = kMitsubishi136MinRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRMitsubishi136::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRMitsubishi136::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRMitsubishi136::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setQuiet()

+ +
+
+ + + + + + + + +
void IRMitsubishi136::setQuiet (const bool on)
+
+ +

Set the Quiet mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRMitsubishi136::setRaw (const uint8_t * data)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]dataA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSwingV()

+ +
+
+ + + + + + + + +
void IRMitsubishi136::setSwingV (const uint8_t position)
+
+ +

Set the Vertical Swing mode of the A/C.

+
Parameters
+ + +
[in]positionThe position/mode to set the swing to.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRMitsubishi136::setTemp (const uint8_t degrees)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]degreesThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRMitsubishi136::stateReset (void )
+
+ +

Reset the state of the remote to a known good state/sequence.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRMitsubishi136::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRMitsubishi136::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRMitsubishi136::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonSwingV()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::swingv_t IRMitsubishi136::toCommonSwingV (const uint8_t pos)
+
+static
+
+ +

Convert a native vertical swing postion to it's common equivalent.

+
Parameters
+ + +
[in]posA native position to convert.
+
+
+
Returns
The common vertical swing position.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRMitsubishi136::toString (void )
+
+ +

Convert the internal state into a human readable string.

+
Returns
A string containing the settings in human-readable form.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRMitsubishi136::validChecksum (const uint8_t * data,
const uint16_t len = kMitsubishi136StateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]dataThe array to verify the checksum of.
[in]lenThe length of the data array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRMitsubishi136::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRMitsubishi136::remote_state[kMitsubishi136StateLength]
+
+private
+
+ +

The state in code form.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi136__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi136__coll__graph.map new file mode 100644 index 000000000..3775846f8 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi136__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi136__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi136__coll__graph.md5 new file mode 100644 index 000000000..213574ee0 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi136__coll__graph.md5 @@ -0,0 +1 @@ +de5d5156a942dd05dd10b0b63147e763 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi136__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi136__coll__graph.png new file mode 100644 index 000000000..23af714ae Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishi136__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC-members.html new file mode 100644 index 000000000..3696a31d2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC-members.html @@ -0,0 +1,123 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRMitsubishiAC Member List
+
+
+ +

This is the complete list of members for IRMitsubishiAC, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRMitsubishiACprivate
begin(void)IRMitsubishiAC
calculateChecksum(const uint8_t *data)IRMitsubishiACprivatestatic
calibrate(void)IRMitsubishiACinline
checksum(void)IRMitsubishiACprivate
convertFan(const stdAc::fanspeed_t speed)IRMitsubishiACstatic
convertMode(const stdAc::opmode_t mode)IRMitsubishiACstatic
convertSwingH(const stdAc::swingh_t position)IRMitsubishiACstatic
convertSwingV(const stdAc::swingv_t position)IRMitsubishiACstatic
getClock(void)IRMitsubishiAC
getFan(void)IRMitsubishiAC
getMode(void)IRMitsubishiAC
getPower(void)IRMitsubishiAC
getRaw(void)IRMitsubishiAC
getStartClock(void)IRMitsubishiAC
getStopClock(void)IRMitsubishiAC
getTemp(void)IRMitsubishiAC
getTimer(void)IRMitsubishiAC
getVane(void)IRMitsubishiAC
getWideVane(void)IRMitsubishiAC
IRMitsubishiAC(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRMitsubishiACexplicit
off(void)IRMitsubishiAC
on(void)IRMitsubishiAC
remote_stateIRMitsubishiACprivate
send(const uint16_t repeat=kMitsubishiACMinRepeat)IRMitsubishiAC
setClock(const uint8_t clock)IRMitsubishiAC
setFan(const uint8_t speed)IRMitsubishiAC
setMode(const uint8_t mode)IRMitsubishiAC
setPower(const bool on)IRMitsubishiAC
setRaw(const uint8_t *data)IRMitsubishiAC
setStartClock(const uint8_t clock)IRMitsubishiAC
setStopClock(const uint8_t clock)IRMitsubishiAC
setTemp(const uint8_t degrees)IRMitsubishiAC
setTimer(const uint8_t timer)IRMitsubishiAC
setVane(const uint8_t position)IRMitsubishiAC
setWideVane(const uint8_t position)IRMitsubishiAC
stateReset(void)IRMitsubishiAC
toCommon(void)IRMitsubishiAC
toCommonFanSpeed(const uint8_t speed)IRMitsubishiACstatic
toCommonMode(const uint8_t mode)IRMitsubishiACstatic
toCommonSwingH(const uint8_t pos)IRMitsubishiACstatic
toCommonSwingV(const uint8_t pos)IRMitsubishiACstatic
toString(void)IRMitsubishiAC
validChecksum(const uint8_t *data)IRMitsubishiACstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC.html new file mode 100644 index 000000000..92707fd32 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC.html @@ -0,0 +1,1437 @@ + + + + + + + +IRremoteESP8266: IRMitsubishiAC Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Mitsubishi 144-bit A/C messages. Inspired and derived from the work done at: https://github.com/r45635/HVAC-IR-Control. + More...

+ +

#include <ir_Mitsubishi.h>

+
+Collaboration diagram for IRMitsubishiAC:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRMitsubishiAC (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset (void)
 Reset the state of the remote to a known good state/sequence. More...
 
void send (const uint16_t repeat=kMitsubishiACMinRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Set the requested power state of the A/C to on. More...
 
void off (void)
 Set the requested power state of the A/C to off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t degrees)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t speed)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setVane (const uint8_t position)
 Set the requested vane (Vertical Swing) operation mode of the a/c unit. More...
 
void setWideVane (const uint8_t position)
 Set the requested wide-vane (Horizontal Swing) operation mode of the a/c. More...
 
uint8_t getVane (void)
 Get the Vane (Vertical Swing) mode of the A/C. More...
 
uint8_t getWideVane (void)
 Get the Wide Vane (Horizontal Swing) mode of the A/C. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t *data)
 Set the internal state from a valid code for this protocol. More...
 
uint8_t getClock (void)
 Get the clock time of the A/C unit. More...
 
void setClock (const uint8_t clock)
 Set the clock time on the A/C unit. More...
 
uint8_t getStartClock (void)
 Get the desired start time of the A/C unit. More...
 
void setStartClock (const uint8_t clock)
 Set the desired start time of the A/C unit. More...
 
uint8_t getStopClock (void)
 Get the desired stop time of the A/C unit. More...
 
void setStopClock (const uint8_t clock)
 Set the desired stop time of the A/C unit. More...
 
uint8_t getTimer (void)
 Get the timers active setting of the A/C. More...
 
void setTimer (const uint8_t timer)
 Set the timers active setting of the A/C. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the internal state into a human readable string. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (const uint8_t *data)
 Verify the checksum is valid for a given state. More...
 
static uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
static uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
static uint8_t convertSwingV (const stdAc::swingv_t position)
 Convert a stdAc::swingv_t enum into it's native setting. More...
 
static uint8_t convertSwingH (const stdAc::swingh_t position)
 Convert a stdAc::swingh_t enum into it's native setting. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
static stdAc::swingv_t toCommonSwingV (const uint8_t pos)
 Convert a native vertical swing postion to it's common equivalent. More...
 
static stdAc::swingh_t toCommonSwingH (const uint8_t pos)
 Convert a native horizontal swing postion to it's common equivalent. More...
 
+ + + + +

+Private Member Functions

void checksum (void)
 Calculate and set the checksum values for the internal state. More...
 
+ + + + +

+Static Private Member Functions

static uint8_t calculateChecksum (const uint8_t *data)
 Calculate the checksum for a given state. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kMitsubishiACStateLength]
 The state in code form. More...
 
+

Detailed Description

+

Class for handling detailed Mitsubishi 144-bit A/C messages. Inspired and derived from the work done at: https://github.com/r45635/HVAC-IR-Control.

+
Warning
Consider this very alpha code. Seems to work, but not validated.
+

Constructor & Destructor Documentation

+ +

◆ IRMitsubishiAC()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRMitsubishiAC::IRMitsubishiAC (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+
Warning
Consider this very alpha code. Seems to work, but not validated.
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRMitsubishiAC::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calculateChecksum()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRMitsubishiAC::calculateChecksum (const uint8_t * data)
+
+staticprivate
+
+ +

Calculate the checksum for a given state.

+
Parameters
+ + +
[in]dataThe value to calc the checksum of.
+
+
+
Returns
The calculated checksum value.
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRMitsubishiAC::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
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.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRMitsubishiAC::checksum (void )
+
+private
+
+ +

Calculate and set the checksum values for the internal state.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRMitsubishiAC::convertFan (const stdAc::fanspeed_t speed)
+
+static
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRMitsubishiAC::convertMode (const stdAc::opmode_t mode)
+
+static
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertSwingH()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRMitsubishiAC::convertSwingH (const stdAc::swingh_t position)
+
+static
+
+ +

Convert a stdAc::swingh_t enum into it's native setting.

+
Parameters
+ + +
[in]positionThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertSwingV()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRMitsubishiAC::convertSwingV (const stdAc::swingv_t position)
+
+static
+
+ +

Convert a stdAc::swingv_t enum into it's native setting.

+
Parameters
+ + +
[in]positionThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getClock()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishiAC::getClock (void )
+
+ +

Get the clock time of the A/C unit.

+
Returns
Nr. of 10 minute increments past midnight.
+
Note
1 = 1/6 hour (10 minutes). e.g. 4pm = 48.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishiAC::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed/mode.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishiAC::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRMitsubishiAC::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRMitsubishiAC::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getStartClock()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishiAC::getStartClock (void )
+
+ +

Get the desired start time of the A/C unit.

+
Returns
Nr. of 10 minute increments past midnight.
+
Note
1 = 1/6 hour (10 minutes). e.g. 4pm = 48.
+ +
+
+ +

◆ getStopClock()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishiAC::getStopClock (void )
+
+ +

Get the desired stop time of the A/C unit.

+
Returns
Nr. of 10 minute increments past midnight.
+
Note
1 = 1/6 hour (10 minutes). e.g. 10pm = 132.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishiAC::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ getTimer()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishiAC::getTimer (void )
+
+ +

Get the timers active setting of the A/C.

+
Returns
The current timers enabled.
+
Note
Possible values: kMitsubishiAcNoTimer, kMitsubishiAcStartTimer, kMitsubishiAcStopTimer, kMitsubishiAcStartStopTimer
+ +
+
+ +

◆ getVane()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishiAC::getVane (void )
+
+ +

Get the Vane (Vertical Swing) mode of the A/C.

+
Returns
The native position/mode setting.
+ +
+
+ +

◆ getWideVane()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishiAC::getWideVane (void )
+
+ +

Get the Wide Vane (Horizontal Swing) mode of the A/C.

+
Returns
The native position/mode setting.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRMitsubishiAC::off (void )
+
+ +

Set the requested power state of the A/C to off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRMitsubishiAC::on (void )
+
+ +

Set the requested power state of the A/C to on.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRMitsubishiAC::send (const uint16_t repeat = kMitsubishiACMinRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setClock()

+ +
+
+ + + + + + + + +
void IRMitsubishiAC::setClock (const uint8_t clock)
+
+ +

Set the clock time on the A/C unit.

+
Parameters
+ + +
[in]clockNr. of 10 minute increments past midnight.
+
+
+
Note
1 = 1/6 hour (10 minutes). e.g. 6am = 36.
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRMitsubishiAC::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting. 0 is auto, 1-5 is speed, 6 is silent.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRMitsubishiAC::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRMitsubishiAC::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRMitsubishiAC::setRaw (const uint8_t * data)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]dataA valid code for this protocol.
+
+
+ +
+
+ +

◆ setStartClock()

+ +
+
+ + + + + + + + +
void IRMitsubishiAC::setStartClock (const uint8_t clock)
+
+ +

Set the desired start time of the A/C unit.

+
Parameters
+ + +
[in]clockNr. of 10 minute increments past midnight.
+
+
+
Note
1 = 1/6 hour (10 minutes). e.g. 8pm = 120.
+ +
+
+ +

◆ setStopClock()

+ +
+
+ + + + + + + + +
void IRMitsubishiAC::setStopClock (const uint8_t clock)
+
+ +

Set the desired stop time of the A/C unit.

+
Parameters
+ + +
[in]clockNr. of 10 minute increments past midnight.
+
+
+
Note
1 = 1/6 hour (10 minutes). e.g. 10pm = 132.
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRMitsubishiAC::setTemp (const uint8_t degrees)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]degreesThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ setTimer()

+ +
+
+ + + + + + + + +
void IRMitsubishiAC::setTimer (const uint8_t timer)
+
+ +

Set the timers active setting of the A/C.

+
Parameters
+ + +
[in]timerThe timer code indicating which ones are active.
+
+
+
Note
Possible values: kMitsubishiAcNoTimer, kMitsubishiAcStartTimer, kMitsubishiAcStopTimer, kMitsubishiAcStartStopTimer
+ +
+
+ +

◆ setVane()

+ +
+
+ + + + + + + + +
void IRMitsubishiAC::setVane (const uint8_t position)
+
+ +

Set the requested vane (Vertical Swing) operation mode of the a/c unit.

+
Parameters
+ + +
[in]positionThe position/mode to set the vane to.
+
+
+ +
+
+ +

◆ setWideVane()

+ +
+
+ + + + + + + + +
void IRMitsubishiAC::setWideVane (const uint8_t position)
+
+ +

Set the requested wide-vane (Horizontal Swing) operation mode of the a/c.

+
Parameters
+ + +
[in]positionThe position/mode to set the wide vane to.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRMitsubishiAC::stateReset (void )
+
+ +

Reset the state of the remote to a known good state/sequence.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRMitsubishiAC::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRMitsubishiAC::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRMitsubishiAC::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonSwingH()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::swingh_t IRMitsubishiAC::toCommonSwingH (const uint8_t pos)
+
+static
+
+ +

Convert a native horizontal swing postion to it's common equivalent.

+
Parameters
+ + +
[in]posA native position to convert.
+
+
+
Returns
The common horizontal swing position.
+ +
+
+ +

◆ toCommonSwingV()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::swingv_t IRMitsubishiAC::toCommonSwingV (const uint8_t pos)
+
+static
+
+ +

Convert a native vertical swing postion to it's common equivalent.

+
Parameters
+ + +
[in]posA native position to convert.
+
+
+
Returns
The common vertical swing position.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRMitsubishiAC::toString (void )
+
+ +

Convert the internal state into a human readable string.

+
Returns
A string containing the settings in human-readable form.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + +
bool IRMitsubishiAC::validChecksum (const uint8_t * data)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + +
[in]dataThe array to verify the checksum of.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRMitsubishiAC::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRMitsubishiAC::remote_state[kMitsubishiACStateLength]
+
+private
+
+ +

The state in code form.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC__coll__graph.map new file mode 100644 index 000000000..627b45a20 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC__coll__graph.md5 new file mode 100644 index 000000000..2eda9cf87 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC__coll__graph.md5 @@ -0,0 +1 @@ +c5704e67d45afe4844036674d82d8c46 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC__coll__graph.png new file mode 100644 index 000000000..cc1362a22 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiAC__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac-members.html new file mode 100644 index 000000000..b8ea4cc00 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac-members.html @@ -0,0 +1,129 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRMitsubishiHeavy152Ac Member List
+
+
+ +

This is the complete list of members for IRMitsubishiHeavy152Ac, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRMitsubishiHeavy152Acprivate
begin(void)IRMitsubishiHeavy152Ac
calibrate(void)IRMitsubishiHeavy152Acinline
checksum(void)IRMitsubishiHeavy152Acprivate
checkZmsSig(const uint8_t *state)IRMitsubishiHeavy152Acstatic
convertFan(const stdAc::fanspeed_t speed)IRMitsubishiHeavy152Acstatic
convertMode(const stdAc::opmode_t mode)IRMitsubishiHeavy152Acstatic
convertSwingH(const stdAc::swingh_t position)IRMitsubishiHeavy152Acstatic
convertSwingV(const stdAc::swingv_t position)IRMitsubishiHeavy152Acstatic
get3D(void)IRMitsubishiHeavy152Ac
getClean(void)IRMitsubishiHeavy152Ac
getEcono(void)IRMitsubishiHeavy152Ac
getFan(void)IRMitsubishiHeavy152Ac
getFilter(void)IRMitsubishiHeavy152Ac
getMode(void)IRMitsubishiHeavy152Ac
getNight(void)IRMitsubishiHeavy152Ac
getPower(void)IRMitsubishiHeavy152Ac
getRaw(void)IRMitsubishiHeavy152Ac
getSilent(void)IRMitsubishiHeavy152Ac
getSwingHorizontal(void)IRMitsubishiHeavy152Ac
getSwingVertical(void)IRMitsubishiHeavy152Ac
getTemp(void)IRMitsubishiHeavy152Ac
getTurbo(void)IRMitsubishiHeavy152Ac
IRMitsubishiHeavy152Ac(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRMitsubishiHeavy152Acexplicit
off(void)IRMitsubishiHeavy152Ac
on(void)IRMitsubishiHeavy152Ac
remote_stateIRMitsubishiHeavy152Acprivate
send(const uint16_t repeat=kMitsubishiHeavy152MinRepeat)IRMitsubishiHeavy152Ac
set3D(const bool on)IRMitsubishiHeavy152Ac
setClean(const bool on)IRMitsubishiHeavy152Ac
setEcono(const bool on)IRMitsubishiHeavy152Ac
setFan(const uint8_t fan)IRMitsubishiHeavy152Ac
setFilter(const bool on)IRMitsubishiHeavy152Ac
setMode(const uint8_t mode)IRMitsubishiHeavy152Ac
setNight(const bool on)IRMitsubishiHeavy152Ac
setPower(const bool on)IRMitsubishiHeavy152Ac
setRaw(const uint8_t *data)IRMitsubishiHeavy152Ac
setSilent(const bool on)IRMitsubishiHeavy152Ac
setSwingHorizontal(const uint8_t pos)IRMitsubishiHeavy152Ac
setSwingVertical(const uint8_t pos)IRMitsubishiHeavy152Ac
setTemp(const uint8_t temp)IRMitsubishiHeavy152Ac
setTurbo(const bool on)IRMitsubishiHeavy152Ac
stateReset(void)IRMitsubishiHeavy152Ac
toCommon(void)IRMitsubishiHeavy152Ac
toCommonFanSpeed(const uint8_t speed)IRMitsubishiHeavy152Acstatic
toCommonMode(const uint8_t mode)IRMitsubishiHeavy152Acstatic
toCommonSwingH(const uint8_t pos)IRMitsubishiHeavy152Acstatic
toCommonSwingV(const uint8_t pos)IRMitsubishiHeavy152Acstatic
toString(void)IRMitsubishiHeavy152Ac
validChecksum(const uint8_t *state, const uint16_t length=kMitsubishiHeavy152StateLength)IRMitsubishiHeavy152Acstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac.html new file mode 100644 index 000000000..061206339 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac.html @@ -0,0 +1,1593 @@ + + + + + + + +IRremoteESP8266: IRMitsubishiHeavy152Ac Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Mitsubishi Heavy 152-bit A/C messages. + More...

+ +

#include <ir_MitsubishiHeavy.h>

+
+Collaboration diagram for IRMitsubishiHeavy152Ac:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRMitsubishiHeavy152Ac (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset (void)
 Reset the state of the remote to a known good state/sequence. More...
 
void send (const uint16_t repeat=kMitsubishiHeavy152MinRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Set the requested power state of the A/C to on. More...
 
void off (void)
 Set the requested power state of the A/C to off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t fan)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setSwingVertical (const uint8_t pos)
 Set the Vertical Swing mode of the A/C. More...
 
uint8_t getSwingVertical (void)
 Get the Vertical Swing mode of the A/C. More...
 
void setSwingHorizontal (const uint8_t pos)
 Set the Horizontal Swing mode of the A/C. More...
 
uint8_t getSwingHorizontal (void)
 Get the Horizontal Swing mode of the A/C. More...
 
void setNight (const bool on)
 Set the Night (Sleep) mode of the A/C. More...
 
bool getNight (void)
 Get the Night (Sleep) mode of the A/C. More...
 
void set3D (const bool on)
 Set the 3D mode of the A/C. More...
 
bool get3D (void)
 Get the 3D mode of the A/C. More...
 
void setSilent (const bool on)
 Set the Silent (Quiet) mode of the A/C. More...
 
bool getSilent (void)
 Get the Silent (Quiet) mode of the A/C. More...
 
void setFilter (const bool on)
 Set the Filter mode of the A/C. More...
 
bool getFilter (void)
 Get the Filter mode of the A/C. More...
 
void setClean (const bool on)
 Set the Clean mode of the A/C. More...
 
bool getClean (void)
 Get the Clean mode of the A/C. More...
 
void setTurbo (const bool on)
 Set the Turbo mode of the A/C. More...
 
bool getTurbo (void)
 Get the Turbo mode of the A/C. More...
 
void setEcono (const bool on)
 Set the Economical mode of the A/C. More...
 
bool getEcono (void)
 Get the Economical mode of the A/C. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t *data)
 Set the internal state from a valid code for this protocol. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the internal state into a human readable string. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Static Public Member Functions

static bool checkZmsSig (const uint8_t *state)
 Verify the given state has a ZM-S signature. More...
 
static bool validChecksum (const uint8_t *state, const uint16_t length=kMitsubishiHeavy152StateLength)
 Verify the checksum is valid for a given state. More...
 
static uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
static uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
static uint8_t convertSwingV (const stdAc::swingv_t position)
 Convert a stdAc::swingv_t enum into it's native setting. More...
 
static uint8_t convertSwingH (const stdAc::swingh_t position)
 Convert a stdAc::swingh_t enum into it's native setting. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
static stdAc::swingv_t toCommonSwingV (const uint8_t pos)
 Convert a native vertical swing postion to it's common equivalent. More...
 
static stdAc::swingh_t toCommonSwingH (const uint8_t pos)
 Convert a native horizontal swing postion to it's common equivalent. More...
 
+ + + + +

+Private Member Functions

void checksum (void)
 Calculate the checksum for the current internal state of the remote. Note: Technically it has no checksum, but does has inverted byte pairs. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kMitsubishiHeavy152StateLength]
 State in code form. More...
 
+

Detailed Description

+

Class for handling detailed Mitsubishi Heavy 152-bit A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRMitsubishiHeavy152Ac()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRMitsubishiHeavy152Ac::IRMitsubishiHeavy152Ac (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy152Ac::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRMitsubishiHeavy152Ac::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
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.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRMitsubishiHeavy152Ac::checksum (void )
+
+private
+
+ +

Calculate the checksum for the current internal state of the remote. Note: Technically it has no checksum, but does has inverted byte pairs.

+ +
+
+ +

◆ checkZmsSig()

+ +
+
+ + + + + +
+ + + + + + + + +
bool IRMitsubishiHeavy152Ac::checkZmsSig (const uint8_t * state)
+
+static
+
+ +

Verify the given state has a ZM-S signature.

+
Parameters
+ + +
[in]stateA ptr to a state to be checked.
+
+
+
Returns
true, the check passed. Otherwise, false.
+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRMitsubishiHeavy152Ac::convertFan (const stdAc::fanspeed_t speed)
+
+static
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRMitsubishiHeavy152Ac::convertMode (const stdAc::opmode_t mode)
+
+static
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertSwingH()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRMitsubishiHeavy152Ac::convertSwingH (const stdAc::swingh_t position)
+
+static
+
+ +

Convert a stdAc::swingh_t enum into it's native setting.

+
Parameters
+ + +
[in]positionThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertSwingV()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRMitsubishiHeavy152Ac::convertSwingV (const stdAc::swingv_t position)
+
+static
+
+ +

Convert a stdAc::swingv_t enum into it's native setting.

+
Parameters
+ + +
[in]positionThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ get3D()

+ +
+
+ + + + + + + + +
bool IRMitsubishiHeavy152Ac::get3D (void )
+
+ +

Get the 3D mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getClean()

+ +
+
+ + + + + + + + +
bool IRMitsubishiHeavy152Ac::getClean (void )
+
+ +

Get the Clean mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getEcono()

+ +
+
+ + + + + + + + +
bool IRMitsubishiHeavy152Ac::getEcono (void )
+
+ +

Get the Economical mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishiHeavy152Ac::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed/mode.
+ +
+
+ +

◆ getFilter()

+ +
+
+ + + + + + + + +
bool IRMitsubishiHeavy152Ac::getFilter (void )
+
+ +

Get the Filter mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishiHeavy152Ac::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getNight()

+ +
+
+ + + + + + + + +
bool IRMitsubishiHeavy152Ac::getNight (void )
+
+ +

Get the Night (Sleep) mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRMitsubishiHeavy152Ac::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRMitsubishiHeavy152Ac::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSilent()

+ +
+
+ + + + + + + + +
bool IRMitsubishiHeavy152Ac::getSilent (void )
+
+ +

Get the Silent (Quiet) mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwingHorizontal()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishiHeavy152Ac::getSwingHorizontal (void )
+
+ +

Get the Horizontal Swing mode of the A/C.

+
Returns
The native position/mode setting.
+ +
+
+ +

◆ getSwingVertical()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishiHeavy152Ac::getSwingVertical (void )
+
+ +

Get the Vertical Swing mode of the A/C.

+
Returns
The native position/mode setting.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishiHeavy152Ac::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ getTurbo()

+ +
+
+ + + + + + + + +
bool IRMitsubishiHeavy152Ac::getTurbo (void )
+
+ +

Get the Turbo mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy152Ac::off (void )
+
+ +

Set the requested power state of the A/C to off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy152Ac::on (void )
+
+ +

Set the requested power state of the A/C to on.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy152Ac::send (const uint16_t repeat = kMitsubishiHeavy152MinRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ set3D()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy152Ac::set3D (const bool on)
+
+ +

Set the 3D mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setClean()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy152Ac::setClean (const bool on)
+
+ +

Set the Clean mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setEcono()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy152Ac::setEcono (const bool on)
+
+ +

Set the Economical mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy152Ac::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting.
+
+
+ +
+
+ +

◆ setFilter()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy152Ac::setFilter (const bool on)
+
+ +

Set the Filter mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy152Ac::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setNight()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy152Ac::setNight (const bool on)
+
+ +

Set the Night (Sleep) mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy152Ac::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy152Ac::setRaw (const uint8_t * data)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]dataA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSilent()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy152Ac::setSilent (const bool on)
+
+ +

Set the Silent (Quiet) mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwingHorizontal()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy152Ac::setSwingHorizontal (const uint8_t pos)
+
+ +

Set the Horizontal Swing mode of the A/C.

+
Parameters
+ + +
[in]posThe position/mode to set the swing to.
+
+
+ +
+
+ +

◆ setSwingVertical()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy152Ac::setSwingVertical (const uint8_t pos)
+
+ +

Set the Vertical Swing mode of the A/C.

+
Parameters
+ + +
[in]posThe position/mode to set the swing to.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy152Ac::setTemp (const uint8_t temp)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]tempThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ setTurbo()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy152Ac::setTurbo (const bool on)
+
+ +

Set the Turbo mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy152Ac::stateReset (void )
+
+ +

Reset the state of the remote to a known good state/sequence.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRMitsubishiHeavy152Ac::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRMitsubishiHeavy152Ac::toCommonFanSpeed (const uint8_t spd)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]spdThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRMitsubishiHeavy152Ac::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonSwingH()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::swingh_t IRMitsubishiHeavy152Ac::toCommonSwingH (const uint8_t pos)
+
+static
+
+ +

Convert a native horizontal swing postion to it's common equivalent.

+
Parameters
+ + +
[in]posA native position to convert.
+
+
+
Returns
The common horizontal swing position.
+ +
+
+ +

◆ toCommonSwingV()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::swingv_t IRMitsubishiHeavy152Ac::toCommonSwingV (const uint8_t pos)
+
+static
+
+ +

Convert a native vertical swing postion to it's common equivalent.

+
Parameters
+ + +
[in]posA native position to convert.
+
+
+
Returns
The common vertical swing position.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRMitsubishiHeavy152Ac::toString (void )
+
+ +

Convert the internal state into a human readable string.

+
Returns
A string containing the settings in human-readable form.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRMitsubishiHeavy152Ac::validChecksum (const uint8_t * state,
const uint16_t length = kMitsubishiHeavy152StateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length/size of the state array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false. Note: Technically it has no checksum, but does has inverted byte pairs.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRMitsubishiHeavy152Ac::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRMitsubishiHeavy152Ac::remote_state[kMitsubishiHeavy152StateLength]
+
+private
+
+ +

State in code form.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac__coll__graph.map new file mode 100644 index 000000000..d1dc4b52e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac__coll__graph.md5 new file mode 100644 index 000000000..df1c2c463 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac__coll__graph.md5 @@ -0,0 +1 @@ +6ea04c88e8883bfc89458f5de25fdcea \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac__coll__graph.png new file mode 100644 index 000000000..2a4f52ae4 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy152Ac__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac-members.html new file mode 100644 index 000000000..e974689c6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac-members.html @@ -0,0 +1,122 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRMitsubishiHeavy88Ac Member List
+
+
+ +

This is the complete list of members for IRMitsubishiHeavy88Ac, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRMitsubishiHeavy88Acprivate
begin(void)IRMitsubishiHeavy88Ac
calibrate(void)IRMitsubishiHeavy88Acinline
checksum(void)IRMitsubishiHeavy88Acprivate
checkZjsSig(const uint8_t *state)IRMitsubishiHeavy88Acstatic
convertFan(const stdAc::fanspeed_t speed)IRMitsubishiHeavy88Acstatic
convertMode(const stdAc::opmode_t mode)IRMitsubishiHeavy88Acstatic
convertSwingH(const stdAc::swingh_t position)IRMitsubishiHeavy88Acstatic
convertSwingV(const stdAc::swingv_t position)IRMitsubishiHeavy88Acstatic
get3D(void)IRMitsubishiHeavy88Ac
getClean(void)IRMitsubishiHeavy88Ac
getEcono(void)IRMitsubishiHeavy88Ac
getFan(void)IRMitsubishiHeavy88Ac
getMode(void)IRMitsubishiHeavy88Ac
getPower(void)IRMitsubishiHeavy88Ac
getRaw(void)IRMitsubishiHeavy88Ac
getSwingHorizontal(void)IRMitsubishiHeavy88Ac
getSwingVertical(void)IRMitsubishiHeavy88Ac
getTemp(void)IRMitsubishiHeavy88Ac
getTurbo(void)IRMitsubishiHeavy88Ac
IRMitsubishiHeavy88Ac(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRMitsubishiHeavy88Acexplicit
off(void)IRMitsubishiHeavy88Ac
on(void)IRMitsubishiHeavy88Ac
remote_stateIRMitsubishiHeavy88Acprivate
send(const uint16_t repeat=kMitsubishiHeavy88MinRepeat)IRMitsubishiHeavy88Ac
set3D(const bool on)IRMitsubishiHeavy88Ac
setClean(const bool on)IRMitsubishiHeavy88Ac
setEcono(const bool on)IRMitsubishiHeavy88Ac
setFan(const uint8_t fan)IRMitsubishiHeavy88Ac
setMode(const uint8_t mode)IRMitsubishiHeavy88Ac
setPower(const bool on)IRMitsubishiHeavy88Ac
setRaw(const uint8_t *data)IRMitsubishiHeavy88Ac
setSwingHorizontal(const uint8_t pos)IRMitsubishiHeavy88Ac
setSwingVertical(const uint8_t pos)IRMitsubishiHeavy88Ac
setTemp(const uint8_t temp)IRMitsubishiHeavy88Ac
setTurbo(const bool on)IRMitsubishiHeavy88Ac
stateReset(void)IRMitsubishiHeavy88Ac
toCommon(void)IRMitsubishiHeavy88Ac
toCommonFanSpeed(const uint8_t speed)IRMitsubishiHeavy88Acstatic
toCommonSwingH(const uint8_t pos)IRMitsubishiHeavy88Acstatic
toCommonSwingV(const uint8_t pos)IRMitsubishiHeavy88Acstatic
toString(void)IRMitsubishiHeavy88Ac
validChecksum(const uint8_t *state, const uint16_t length=kMitsubishiHeavy88StateLength)IRMitsubishiHeavy88Acstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac.html new file mode 100644 index 000000000..2831dc0bd --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac.html @@ -0,0 +1,1396 @@ + + + + + + + +IRremoteESP8266: IRMitsubishiHeavy88Ac Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Mitsubishi Heavy 88-bit A/C messages. + More...

+ +

#include <ir_MitsubishiHeavy.h>

+
+Collaboration diagram for IRMitsubishiHeavy88Ac:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRMitsubishiHeavy88Ac (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset (void)
 Reset the state of the remote to a known good state/sequence. More...
 
void send (const uint16_t repeat=kMitsubishiHeavy88MinRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Set the requested power state of the A/C to on. More...
 
void off (void)
 Set the requested power state of the A/C to off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t fan)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setSwingVertical (const uint8_t pos)
 Set the Vertical Swing mode of the A/C. More...
 
uint8_t getSwingVertical (void)
 Get the Vertical Swing mode of the A/C. More...
 
void setSwingHorizontal (const uint8_t pos)
 Set the Horizontal Swing mode of the A/C. More...
 
uint8_t getSwingHorizontal (void)
 Get the Horizontal Swing mode of the A/C. More...
 
void setTurbo (const bool on)
 Set the Turbo mode of the A/C. More...
 
bool getTurbo (void)
 Get the Turbo mode of the A/C. More...
 
void setEcono (const bool on)
 Set the Economical mode of the A/C. More...
 
bool getEcono (void)
 Get the Economical mode of the A/C. More...
 
void set3D (const bool on)
 Set the 3D mode of the A/C. More...
 
bool get3D (void)
 Get the 3D mode of the A/C. More...
 
void setClean (const bool on)
 Set the Clean mode of the A/C. More...
 
bool getClean (void)
 Get the Clean mode of the A/C. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t *data)
 Set the internal state from a valid code for this protocol. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the internal state into a human readable string. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Static Public Member Functions

static bool checkZjsSig (const uint8_t *state)
 Verify the given state has a ZJ-S signature. More...
 
static bool validChecksum (const uint8_t *state, const uint16_t length=kMitsubishiHeavy88StateLength)
 Verify the checksum is valid for a given state. More...
 
static uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
static uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
static uint8_t convertSwingV (const stdAc::swingv_t position)
 Convert a stdAc::swingv_t enum into it's native setting. More...
 
static uint8_t convertSwingH (const stdAc::swingh_t position)
 Convert a stdAc::swingh_t enum into it's native setting. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
static stdAc::swingv_t toCommonSwingV (const uint8_t pos)
 Convert a native vertical swing postion to it's common equivalent. More...
 
static stdAc::swingh_t toCommonSwingH (const uint8_t pos)
 Convert a native horizontal swing postion to it's common equivalent. More...
 
+ + + + +

+Private Member Functions

void checksum (void)
 Calculate the checksum for the current internal state of the remote. Note: Technically it has no checksum, but does has inverted byte pairs. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kMitsubishiHeavy88StateLength]
 State in code form. More...
 
+

Detailed Description

+

Class for handling detailed Mitsubishi Heavy 88-bit A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRMitsubishiHeavy88Ac()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRMitsubishiHeavy88Ac::IRMitsubishiHeavy88Ac (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy88Ac::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRMitsubishiHeavy88Ac::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
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.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRMitsubishiHeavy88Ac::checksum (void )
+
+private
+
+ +

Calculate the checksum for the current internal state of the remote. Note: Technically it has no checksum, but does has inverted byte pairs.

+ +
+
+ +

◆ checkZjsSig()

+ +
+
+ + + + + +
+ + + + + + + + +
bool IRMitsubishiHeavy88Ac::checkZjsSig (const uint8_t * state)
+
+static
+
+ +

Verify the given state has a ZJ-S signature.

+
Parameters
+ + +
[in]stateA ptr to a state to be checked.
+
+
+
Returns
true, the check passed. Otherwise, false.
+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRMitsubishiHeavy88Ac::convertFan (const stdAc::fanspeed_t speed)
+
+static
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRMitsubishiHeavy88Ac::convertMode (const stdAc::opmode_t mode)
+
+static
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertSwingH()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRMitsubishiHeavy88Ac::convertSwingH (const stdAc::swingh_t position)
+
+static
+
+ +

Convert a stdAc::swingh_t enum into it's native setting.

+
Parameters
+ + +
[in]positionThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertSwingV()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRMitsubishiHeavy88Ac::convertSwingV (const stdAc::swingv_t position)
+
+static
+
+ +

Convert a stdAc::swingv_t enum into it's native setting.

+
Parameters
+ + +
[in]positionThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ get3D()

+ +
+
+ + + + + + + + +
bool IRMitsubishiHeavy88Ac::get3D (void )
+
+ +

Get the 3D mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getClean()

+ +
+
+ + + + + + + + +
bool IRMitsubishiHeavy88Ac::getClean (void )
+
+ +

Get the Clean mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getEcono()

+ +
+
+ + + + + + + + +
bool IRMitsubishiHeavy88Ac::getEcono (void )
+
+ +

Get the Economical mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishiHeavy88Ac::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed/mode.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishiHeavy88Ac::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRMitsubishiHeavy88Ac::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRMitsubishiHeavy88Ac::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSwingHorizontal()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishiHeavy88Ac::getSwingHorizontal (void )
+
+ +

Get the Horizontal Swing mode of the A/C.

+
Returns
The native position/mode setting.
+ +
+
+ +

◆ getSwingVertical()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishiHeavy88Ac::getSwingVertical (void )
+
+ +

Get the Vertical Swing mode of the A/C.

+
Returns
The native position/mode setting.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRMitsubishiHeavy88Ac::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ getTurbo()

+ +
+
+ + + + + + + + +
bool IRMitsubishiHeavy88Ac::getTurbo (void )
+
+ +

Get the Turbo mode of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy88Ac::off (void )
+
+ +

Set the requested power state of the A/C to off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy88Ac::on (void )
+
+ +

Set the requested power state of the A/C to on.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy88Ac::send (const uint16_t repeat = kMitsubishiHeavy88MinRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ set3D()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy88Ac::set3D (const bool on)
+
+ +

Set the 3D mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setClean()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy88Ac::setClean (const bool on)
+
+ +

Set the Clean mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setEcono()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy88Ac::setEcono (const bool on)
+
+ +

Set the Economical mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy88Ac::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy88Ac::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy88Ac::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy88Ac::setRaw (const uint8_t * data)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]dataA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSwingHorizontal()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy88Ac::setSwingHorizontal (const uint8_t pos)
+
+ +

Set the Horizontal Swing mode of the A/C.

+
Parameters
+ + +
[in]posThe position/mode to set the swing to.
+
+
+ +
+
+ +

◆ setSwingVertical()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy88Ac::setSwingVertical (const uint8_t pos)
+
+ +

Set the Vertical Swing mode of the A/C.

+
Parameters
+ + +
[in]posThe position/mode to set the swing to.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy88Ac::setTemp (const uint8_t temp)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]tempThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ setTurbo()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy88Ac::setTurbo (const bool on)
+
+ +

Set the Turbo mode of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRMitsubishiHeavy88Ac::stateReset (void )
+
+ +

Reset the state of the remote to a known good state/sequence.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRMitsubishiHeavy88Ac::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRMitsubishiHeavy88Ac::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonSwingH()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::swingh_t IRMitsubishiHeavy88Ac::toCommonSwingH (const uint8_t pos)
+
+static
+
+ +

Convert a native horizontal swing postion to it's common equivalent.

+
Parameters
+ + +
[in]posA native position to convert.
+
+
+
Returns
The common horizontal swing position.
+ +
+
+ +

◆ toCommonSwingV()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::swingv_t IRMitsubishiHeavy88Ac::toCommonSwingV (const uint8_t pos)
+
+static
+
+ +

Convert a native vertical swing postion to it's common equivalent.

+
Parameters
+ + +
[in]posA native position to convert.
+
+
+
Returns
The common vertical swing position.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRMitsubishiHeavy88Ac::toString (void )
+
+ +

Convert the internal state into a human readable string.

+
Returns
A string containing the settings in human-readable form.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRMitsubishiHeavy88Ac::validChecksum (const uint8_t * state,
const uint16_t length = kMitsubishiHeavy88StateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length/size of the state array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false. Note: Technically it has no checksum, but does has inverted byte pairs.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRMitsubishiHeavy88Ac::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRMitsubishiHeavy88Ac::remote_state[kMitsubishiHeavy88StateLength]
+
+private
+
+ +

State in code form.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac__coll__graph.map new file mode 100644 index 000000000..924baf61e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac__coll__graph.md5 new file mode 100644 index 000000000..c159b188d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac__coll__graph.md5 @@ -0,0 +1 @@ +efa3e5f38fe575e86f5114c55d9276b8 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac__coll__graph.png new file mode 100644 index 000000000..c50dbc0c4 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRMitsubishiHeavy88Ac__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRNeoclimaAc-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRNeoclimaAc-members.html new file mode 100644 index 000000000..1b550bc73 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRNeoclimaAc-members.html @@ -0,0 +1,130 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRNeoclimaAc Member List
+
+
+ +

This is the complete list of members for IRNeoclimaAc, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRNeoclimaAcprivate
begin(void)IRNeoclimaAc
calcChecksum(const uint8_t state[], const uint16_t length=kNeoclimaStateLength)IRNeoclimaAcstatic
calibrate(void)IRNeoclimaAcinline
checksum(const uint16_t length=kNeoclimaStateLength)IRNeoclimaAcprivate
convertFan(const stdAc::fanspeed_t speed)IRNeoclimaAc
convertMode(const stdAc::opmode_t mode)IRNeoclimaAc
get8CHeat(void)IRNeoclimaAc
getButton(void)IRNeoclimaAc
getEye(void)IRNeoclimaAc
getFan(void)IRNeoclimaAc
getFollow(void)IRNeoclimaAc
getFresh(void)IRNeoclimaAc
getHold(void)IRNeoclimaAc
getIon(void)IRNeoclimaAc
getLight(void)IRNeoclimaAc
getMode(void)IRNeoclimaAc
getPower(void)IRNeoclimaAc
getRaw(void)IRNeoclimaAc
getSleep(void)IRNeoclimaAc
getSwingH(void)IRNeoclimaAc
getSwingV(void)IRNeoclimaAc
getTemp(void)IRNeoclimaAc
getTurbo(void)IRNeoclimaAc
IRNeoclimaAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRNeoclimaAcexplicit
off(void)IRNeoclimaAc
on(void)IRNeoclimaAc
remote_stateIRNeoclimaAcprivate
send(const uint16_t repeat=kNeoclimaMinRepeat)IRNeoclimaAc
set8CHeat(const bool on)IRNeoclimaAc
setButton(const uint8_t button)IRNeoclimaAc
setEye(const bool on)IRNeoclimaAc
setFan(const uint8_t speed)IRNeoclimaAc
setFresh(const bool on)IRNeoclimaAc
setHold(const bool on)IRNeoclimaAc
setIon(const bool on)IRNeoclimaAc
setLight(const bool on)IRNeoclimaAc
setMode(const uint8_t mode)IRNeoclimaAc
setPower(const bool on)IRNeoclimaAc
setRaw(const uint8_t new_code[], const uint16_t length=kNeoclimaStateLength)IRNeoclimaAc
setSleep(const bool on)IRNeoclimaAc
setSwingH(const bool on)IRNeoclimaAc
setSwingV(const bool on)IRNeoclimaAc
setTemp(const uint8_t temp)IRNeoclimaAc
setTurbo(const bool on)IRNeoclimaAc
stateReset(void)IRNeoclimaAc
toCommon(void)IRNeoclimaAc
toCommonFanSpeed(const uint8_t speed)IRNeoclimaAcstatic
toCommonMode(const uint8_t mode)IRNeoclimaAcstatic
toString(void)IRNeoclimaAc
validChecksum(const uint8_t state[], const uint16_t length=kNeoclimaStateLength)IRNeoclimaAcstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRNeoclimaAc.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRNeoclimaAc.html new file mode 100644 index 000000000..4cec65c07 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRNeoclimaAc.html @@ -0,0 +1,1584 @@ + + + + + + + +IRremoteESP8266: IRNeoclimaAc Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Neoclima A/C messages. + More...

+ +

#include <ir_Neoclima.h>

+
+Collaboration diagram for IRNeoclimaAc:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRNeoclimaAc (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset (void)
 Reset the state of the remote to a known good state/sequence. More...
 
void send (const uint16_t repeat=kNeoclimaMinRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void setButton (const uint8_t button)
 Set the Button/Command pressed setting of the A/C. More...
 
uint8_t getButton (void)
 Get the Button/Command setting of the A/C. More...
 
void on (void)
 Set the requested power state of the A/C to on. More...
 
void off (void)
 Set the requested power state of the A/C to off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t speed)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setSwingV (const bool on)
 Set the vertical swing setting of the A/C. More...
 
bool getSwingV (void)
 Get the vertical swing setting of the A/C. More...
 
void setSwingH (const bool on)
 Set the horizontal swing setting of the A/C. More...
 
bool getSwingH (void)
 Get the horizontal swing (Air Flow) setting of the A/C. More...
 
void setSleep (const bool on)
 Set the Sleep setting of the A/C. More...
 
bool getSleep (void)
 Get the Sleep setting of the A/C. More...
 
void setTurbo (const bool on)
 Set the Turbo setting of the A/C. More...
 
bool getTurbo (void)
 Get the Turbo setting of the A/C. More...
 
void setFresh (const bool on)
 Set the Fresh (air) setting of the A/C. More...
 
bool getFresh (void)
 Get the Frsh (air) setting of the A/C. More...
 
void setHold (const bool on)
 Set the Hold setting of the A/C. More...
 
bool getHold (void)
 Get the Hold setting of the A/C. More...
 
void setIon (const bool on)
 Set the Ion (filter) setting of the A/C. More...
 
bool getIon (void)
 Get the Ion (filter) setting of the A/C. More...
 
void setLight (const bool on)
 Set the Light(LED display) setting of the A/C. More...
 
bool getLight (void)
 Get the Light (LED display) setting of the A/C. More...
 
void set8CHeat (const bool on)
 Set the 8°C Heat setting of the A/C. More...
 
bool get8CHeat (void)
 Get the 8°C Heat setting of the A/C. More...
 
void setEye (const bool on)
 Set the Eye (Sensor) setting of the A/C. More...
 
bool getEye (void)
 Get the Eye (Sensor) setting of the A/C. More...
 
bool getFollow (void)
 Get the Follow Me setting of the A/C. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t new_code[], const uint16_t length=kNeoclimaStateLength)
 Set the internal state from a valid code for this protocol. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
+ + + + + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (const uint8_t state[], const uint16_t length=kNeoclimaStateLength)
 Verify the checksum is valid for a given state. More...
 
static uint8_t calcChecksum (const uint8_t state[], const uint16_t length=kNeoclimaStateLength)
 Calculate the checksum for a given state. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + +

+Private Member Functions

void checksum (const uint16_t length=kNeoclimaStateLength)
 Calculate & update the checksum for the internal state. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kNeoclimaStateLength]
 State of the remote in code. More...
 
+

Detailed Description

+

Class for handling detailed Neoclima A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRNeoclimaAc()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRNeoclimaAc::IRNeoclimaAc (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRNeoclimaAc::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calcChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
uint8_t IRNeoclimaAc::calcChecksum (const uint8_t state[],
const uint16_t length = kNeoclimaStateLength 
)
+
+static
+
+ +

Calculate the checksum for a given state.

+
Parameters
+ + + +
[in]stateThe array to calc the checksum of.
[in]lengthThe length/size of the array.
+
+
+
Returns
The calculated checksum value.
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRNeoclimaAc::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
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.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRNeoclimaAc::checksum (const uint16_t length = kNeoclimaStateLength)
+
+private
+
+ +

Calculate & update the checksum for the internal state.

+
Parameters
+ + +
[in]lengthThe length/size of the internal state.
+
+
+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRNeoclimaAc::convertFan (const stdAc::fanspeed_t speed)
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRNeoclimaAc::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ get8CHeat()

+ +
+
+ + + + + + + + +
bool IRNeoclimaAc::get8CHeat (void )
+
+ +

Get the 8°C Heat setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getButton()

+ +
+
+ + + + + + + + +
uint8_t IRNeoclimaAc::getButton (void )
+
+ +

Get the Button/Command setting of the A/C.

+
Returns
The value of the button/command that was pressed.
+ +
+
+ +

◆ getEye()

+ +
+
+ + + + + + + + +
bool IRNeoclimaAc::getEye (void )
+
+ +

Get the Eye (Sensor) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRNeoclimaAc::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed/mode.
+ +
+
+ +

◆ getFollow()

+ +
+
+ + + + + + + + +
bool IRNeoclimaAc::getFollow (void )
+
+ +

Get the Follow Me setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getFresh()

+ +
+
+ + + + + + + + +
bool IRNeoclimaAc::getFresh (void )
+
+ +

Get the Frsh (air) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getHold()

+ +
+
+ + + + + + + + +
bool IRNeoclimaAc::getHold (void )
+
+ +

Get the Hold setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getIon()

+ +
+
+ + + + + + + + +
bool IRNeoclimaAc::getIon (void )
+
+ +

Get the Ion (filter) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getLight()

+ +
+
+ + + + + + + + +
bool IRNeoclimaAc::getLight (void )
+
+ +

Get the Light (LED display) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRNeoclimaAc::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRNeoclimaAc::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRNeoclimaAc::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSleep()

+ +
+
+ + + + + + + + +
bool IRNeoclimaAc::getSleep (void )
+
+ +

Get the Sleep setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwingH()

+ +
+
+ + + + + + + + +
bool IRNeoclimaAc::getSwingH (void )
+
+ +

Get the horizontal swing (Air Flow) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwingV()

+ +
+
+ + + + + + + + +
bool IRNeoclimaAc::getSwingV (void )
+
+ +

Get the vertical swing setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRNeoclimaAc::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ getTurbo()

+ +
+
+ + + + + + + + +
bool IRNeoclimaAc::getTurbo (void )
+
+ +

Get the Turbo setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRNeoclimaAc::off (void )
+
+ +

Set the requested power state of the A/C to off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRNeoclimaAc::on (void )
+
+ +

Set the requested power state of the A/C to on.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRNeoclimaAc::send (const uint16_t repeat = kNeoclimaMinRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ set8CHeat()

+ +
+
+ + + + + + + + +
void IRNeoclimaAc::set8CHeat (const bool on)
+
+ +

Set the 8°C Heat setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+
Note
This feature maintains the room temperature steadily at 8°C and prevents the room from freezing by activating the heating operation automatically when nobody is at home over a longer period during severe winter.
+ +
+
+ +

◆ setButton()

+ +
+
+ + + + + + + + +
void IRNeoclimaAc::setButton (const uint8_t button)
+
+ +

Set the Button/Command pressed setting of the A/C.

+
Parameters
+ + +
[in]buttonThe value of the button/command that was pressed.
+
+
+ +
+
+ +

◆ setEye()

+ +
+
+ + + + + + + + +
void IRNeoclimaAc::setEye (const bool on)
+
+ +

Set the Eye (Sensor) setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRNeoclimaAc::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting. 0-3, 0 is auto, 1-3 is the speed
+
+
+ +
+
+ +

◆ setFresh()

+ +
+
+ + + + + + + + +
void IRNeoclimaAc::setFresh (const bool on)
+
+ +

Set the Fresh (air) setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setHold()

+ +
+
+ + + + + + + + +
void IRNeoclimaAc::setHold (const bool on)
+
+ +

Set the Hold setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setIon()

+ +
+
+ + + + + + + + +
void IRNeoclimaAc::setIon (const bool on)
+
+ +

Set the Ion (filter) setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setLight()

+ +
+
+ + + + + + + + +
void IRNeoclimaAc::setLight (const bool on)
+
+ +

Set the Light(LED display) setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRNeoclimaAc::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRNeoclimaAc::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRNeoclimaAc::setRaw (const uint8_t new_code[],
const uint16_t length = kNeoclimaStateLength 
)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + + +
[in]new_codeA valid code for this protocol.
[in]lengthThe length/size of the new_code array.
+
+
+ +
+
+ +

◆ setSleep()

+ +
+
+ + + + + + + + +
void IRNeoclimaAc::setSleep (const bool on)
+
+ +

Set the Sleep setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwingH()

+ +
+
+ + + + + + + + +
void IRNeoclimaAc::setSwingH (const bool on)
+
+ +

Set the horizontal swing setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwingV()

+ +
+
+ + + + + + + + +
void IRNeoclimaAc::setSwingV (const bool on)
+
+ +

Set the vertical swing setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRNeoclimaAc::setTemp (const uint8_t temp)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]tempThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ setTurbo()

+ +
+
+ + + + + + + + +
void IRNeoclimaAc::setTurbo (const bool on)
+
+ +

Set the Turbo setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRNeoclimaAc::stateReset (void )
+
+ +

Reset the state of the remote to a known good state/sequence.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRNeoclimaAc::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRNeoclimaAc::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRNeoclimaAc::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRNeoclimaAc::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRNeoclimaAc::validChecksum (const uint8_t state[],
const uint16_t length = kNeoclimaStateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length/size of the array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRNeoclimaAc::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRNeoclimaAc::remote_state[kNeoclimaStateLength]
+
+private
+
+ +

State of the remote in code.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRNeoclimaAc__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRNeoclimaAc__coll__graph.map new file mode 100644 index 000000000..57358d833 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRNeoclimaAc__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRNeoclimaAc__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRNeoclimaAc__coll__graph.md5 new file mode 100644 index 000000000..fe697a810 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRNeoclimaAc__coll__graph.md5 @@ -0,0 +1 @@ +1e6ee18f808b645d10f6652b3a78aca2 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRNeoclimaAc__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRNeoclimaAc__coll__graph.png new file mode 100644 index 000000000..9515ee73a Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRNeoclimaAc__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc-members.html new file mode 100644 index 000000000..50e639d84 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc-members.html @@ -0,0 +1,138 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRPanasonicAc Member List
+
+
+ +

This is the complete list of members for IRPanasonicAc, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_getTime(const uint8_t ptr[])IRPanasonicAcprivatestatic
_irsendIRPanasonicAcprivate
_setTime(uint8_t *const ptr, const uint16_t mins_since_midnight, const bool round_down)IRPanasonicAcprivatestatic
_swinghIRPanasonicAcprivate
_tempIRPanasonicAcprivate
begin(void)IRPanasonicAc
calcChecksum(const uint8_t *state, const uint16_t length=kPanasonicAcStateLength)IRPanasonicAcstatic
calibrate(void)IRPanasonicAcinline
cancelOffTimer(void)IRPanasonicAc
cancelOnTimer(void)IRPanasonicAc
convertFan(const stdAc::fanspeed_t speed)IRPanasonicAcstatic
convertMode(const stdAc::opmode_t mode)IRPanasonicAcstatic
convertSwingH(const stdAc::swingh_t position)IRPanasonicAcstatic
convertSwingV(const stdAc::swingv_t position)IRPanasonicAcstatic
encodeTime(const uint8_t hours, const uint8_t mins)IRPanasonicAcstatic
fixChecksum(const uint16_t length=kPanasonicAcStateLength)IRPanasonicAcprivate
getClock(void)IRPanasonicAc
getFan(void)IRPanasonicAc
getIon(void)IRPanasonicAc
getMode(void)IRPanasonicAc
getModel(void)IRPanasonicAc
getOffTimer(void)IRPanasonicAc
getOnTimer(void)IRPanasonicAc
getPower(void)IRPanasonicAc
getPowerful(void)IRPanasonicAc
getQuiet(void)IRPanasonicAc
getRaw(void)IRPanasonicAc
getSwingHorizontal(void)IRPanasonicAc
getSwingVertical(void)IRPanasonicAc
getTemp(void)IRPanasonicAc
IRPanasonicAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRPanasonicAcexplicit
isOffTimerEnabled(void)IRPanasonicAc
isOnTimerEnabled(void)IRPanasonicAc
off(void)IRPanasonicAc
on(void)IRPanasonicAc
remote_stateIRPanasonicAcprivate
send(const uint16_t repeat=kPanasonicAcDefaultRepeat)IRPanasonicAc
setClock(const uint16_t mins_since_midnight)IRPanasonicAc
setFan(const uint8_t fan)IRPanasonicAc
setIon(const bool on)IRPanasonicAc
setMode(const uint8_t mode)IRPanasonicAc
setModel(const panasonic_ac_remote_model_t model)IRPanasonicAc
setOffTimer(const uint16_t mins_since_midnight, const bool enable=true)IRPanasonicAc
setOnTimer(const uint16_t mins_since_midnight, const bool enable=true)IRPanasonicAc
setPower(const bool on)IRPanasonicAc
setPowerful(const bool on)IRPanasonicAc
setQuiet(const bool on)IRPanasonicAc
setRaw(const uint8_t state[])IRPanasonicAc
setSwingHorizontal(const uint8_t direction)IRPanasonicAc
setSwingVertical(const uint8_t elevation)IRPanasonicAc
setTemp(const uint8_t temp, const bool remember=true)IRPanasonicAc
stateReset(void)IRPanasonicAc
toCommon(void)IRPanasonicAc
toCommonFanSpeed(const uint8_t speed)IRPanasonicAcstatic
toCommonMode(const uint8_t mode)IRPanasonicAcstatic
toCommonSwingH(const uint8_t pos)IRPanasonicAcstatic
toCommonSwingV(const uint8_t pos)IRPanasonicAcstatic
toString(void)IRPanasonicAc
validChecksum(const uint8_t *state, const uint16_t length=kPanasonicAcStateLength)IRPanasonicAcstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc.html new file mode 100644 index 000000000..208d2d289 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc.html @@ -0,0 +1,1936 @@ + + + + + + + +IRremoteESP8266: IRPanasonicAc Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Panasonic A/C messages. + More...

+ +

#include <ir_Panasonic.h>

+
+Collaboration diagram for IRPanasonicAc:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRPanasonicAc (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset (void)
 Reset the state of the remote to a known good state/sequence. More...
 
void send (const uint16_t repeat=kPanasonicAcDefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Change the power setting to On. More...
 
void off (void)
 Change the power setting to Off. More...
 
void setPower (const bool on)
 Control the power state of the A/C unit. More...
 
bool getPower (void)
 Get the A/C power state of the remote. More...
 
void setTemp (const uint8_t temp, const bool remember=true)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t fan)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setRaw (const uint8_t state[])
 Set the internal state from a valid code for this protocol. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
void setQuiet (const bool on)
 Set the Quiet setting of the A/C. More...
 
bool getQuiet (void)
 Get the Quiet setting of the A/C. More...
 
void setPowerful (const bool on)
 Set the Powerful (Turbo) setting of the A/C. More...
 
bool getPowerful (void)
 Get the Powerful (Turbo) setting of the A/C. More...
 
void setIon (const bool on)
 Set the Ion (filter) setting of the A/C. More...
 
bool getIon (void)
 Get the Ion (filter) setting of the A/C. More...
 
void setModel (const panasonic_ac_remote_model_t model)
 Set the model of the A/C to emulate. More...
 
panasonic_ac_remote_model_t getModel (void)
 Get/Detect the model of the A/C. More...
 
void setSwingVertical (const uint8_t elevation)
 Control the vertical swing setting. More...
 
uint8_t getSwingVertical (void)
 Get the current vertical swing setting. More...
 
void setSwingHorizontal (const uint8_t direction)
 Control the horizontal swing setting. More...
 
uint8_t getSwingHorizontal (void)
 Get the current horizontal swing setting. More...
 
uint16_t getClock (void)
 Get the current clock time value. More...
 
void setClock (const uint16_t mins_since_midnight)
 Set the current clock time value. More...
 
uint16_t getOnTimer (void)
 Get the On Timer time value. More...
 
void setOnTimer (const uint16_t mins_since_midnight, const bool enable=true)
 Set/Enable the On Timer. More...
 
void cancelOnTimer (void)
 Cancel the On Timer. More...
 
bool isOnTimerEnabled (void)
 Check if the On Timer is Enabled. More...
 
uint16_t getOffTimer (void)
 Get the Off Timer time value. More...
 
void setOffTimer (const uint16_t mins_since_midnight, const bool enable=true)
 Set/Enable the Off Timer. More...
 
void cancelOffTimer (void)
 Cancel the Off Timer. More...
 
bool isOffTimerEnabled (void)
 Check if the Off Timer is Enabled. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the internal state into a human readable string. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (const uint8_t *state, const uint16_t length=kPanasonicAcStateLength)
 Verify the checksum is valid for a given state. More...
 
static uint8_t calcChecksum (const uint8_t *state, const uint16_t length=kPanasonicAcStateLength)
 Calculate the checksum for a given state. More...
 
static uint16_t encodeTime (const uint8_t hours, const uint8_t mins)
 Convert standard (military/24hr) time to nr. of minutes since midnight. More...
 
static uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
static uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
static uint8_t convertSwingV (const stdAc::swingv_t position)
 Convert a standard A/C vertical swing into its native setting. More...
 
static uint8_t convertSwingH (const stdAc::swingh_t position)
 Convert a standard A/C horizontal swing into its native setting. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
static stdAc::swingv_t toCommonSwingV (const uint8_t pos)
 Convert a native vertical swing postion to it's common equivalent. More...
 
static stdAc::swingh_t toCommonSwingH (const uint8_t pos)
 Convert a native horizontal swing postion to it's common equivalent. More...
 
+ + + + +

+Private Member Functions

void fixChecksum (const uint16_t length=kPanasonicAcStateLength)
 Calculate and set the checksum values for the internal state. More...
 
+ + + + + + + +

+Static Private Member Functions

static uint16_t _getTime (const uint8_t ptr[])
 Get the time from a given pointer location. More...
 
static void _setTime (uint8_t *const ptr, const uint16_t mins_since_midnight, const bool round_down)
 Set the time at a given pointer location. More...
 
+ + + + + + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kPanasonicAcStateLength]
 The state in code form. More...
 
uint8_t _swingh
 
uint8_t _temp
 
+

Detailed Description

+

Class for handling detailed Panasonic A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRPanasonicAc()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRPanasonicAc::IRPanasonicAc (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ _getTime()

+ +
+
+ + + + + +
+ + + + + + + + +
uint16_t IRPanasonicAc::_getTime (const uint8_t ptr[])
+
+staticprivate
+
+ +

Get the time from a given pointer location.

+
Parameters
+ + +
[in]ptrA pointer to a time location in a state.
+
+
+
Returns
The time expressed as nr. of minutes past midnight.
+
Note
Internal use only.
+ +
+
+ +

◆ _setTime()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRPanasonicAc::_setTime (uint8_t *const ptr,
const uint16_t mins_since_midnight,
const bool round_down 
)
+
+staticprivate
+
+ +

Set the time at a given pointer location.

+
Parameters
+ + + + +
[in,out]ptrA pointer to a time location in a state.
[in]mins_since_midnightThe time as nr. of minutes past midnight.
[in]round_downDo we round to the nearest 10 minute mark?
+
+
+
Note
Internal use only.
+ +
+
+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRPanasonicAc::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calcChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
uint8_t IRPanasonicAc::calcChecksum (const uint8_t * state,
const uint16_t length = kPanasonicAcStateLength 
)
+
+static
+
+ +

Calculate the checksum for a given state.

+
Parameters
+ + + +
[in]stateThe value to calc the checksum of.
[in]lengthThe size/length of the state.
+
+
+
Returns
The calculated checksum value.
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRPanasonicAc::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
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.
+ +
+
+ +

◆ cancelOffTimer()

+ +
+
+ + + + + + + + +
void IRPanasonicAc::cancelOffTimer (void )
+
+ +

Cancel the Off Timer.

+ +
+
+ +

◆ cancelOnTimer()

+ +
+
+ + + + + + + + +
void IRPanasonicAc::cancelOnTimer (void )
+
+ +

Cancel the On Timer.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRPanasonicAc::convertFan (const stdAc::fanspeed_t speed)
+
+static
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRPanasonicAc::convertMode (const stdAc::opmode_t mode)
+
+static
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertSwingH()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRPanasonicAc::convertSwingH (const stdAc::swingh_t position)
+
+static
+
+ +

Convert a standard A/C horizontal swing into its native setting.

+
Parameters
+ + +
[in]positionA stdAc::swingh_t position to convert.
+
+
+
Returns
The equivilent native horizontal swing position.
+ +
+
+ +

◆ convertSwingV()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRPanasonicAc::convertSwingV (const stdAc::swingv_t position)
+
+static
+
+ +

Convert a standard A/C vertical swing into its native setting.

+
Parameters
+ + +
[in]positionA stdAc::swingv_t position to convert.
+
+
+
Returns
The equivilent native horizontal swing position.
+ +
+
+ +

◆ encodeTime()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
uint16_t IRPanasonicAc::encodeTime (const uint8_t hours,
const uint8_t mins 
)
+
+static
+
+ +

Convert standard (military/24hr) time to nr. of minutes since midnight.

+
Parameters
+ + + +
[in]hoursThe hours component of the time.
[in]minsThe minutes component of the time.
+
+
+
Returns
The nr of minutes since midnight.
+ +
+
+ +

◆ fixChecksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRPanasonicAc::fixChecksum (const uint16_t length = kPanasonicAcStateLength)
+
+private
+
+ +

Calculate and set the checksum values for the internal state.

+
Parameters
+ + +
[in]lengthThe size/length of the state.
+
+
+ +
+
+ +

◆ getClock()

+ +
+
+ + + + + + + + +
uint16_t IRPanasonicAc::getClock (void )
+
+ +

Get the current clock time value.

+
Returns
The time expressed as nr. of minutes past midnight.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRPanasonicAc::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed.
+ +
+
+ +

◆ getIon()

+ +
+
+ + + + + + + + +
bool IRPanasonicAc::getIon (void )
+
+ +

Get the Ion (filter) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRPanasonicAc::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getModel()

+ +
+
+ + + + + + + + +
panasonic_ac_remote_model_t IRPanasonicAc::getModel (void )
+
+ +

Get/Detect the model of the A/C.

+
Returns
The enum of the compatible model.
+ +
+
+ +

◆ getOffTimer()

+ +
+
+ + + + + + + + +
uint16_t IRPanasonicAc::getOffTimer (void )
+
+ +

Get the Off Timer time value.

+
Returns
The time expressed as nr. of minutes past midnight.
+ +
+
+ +

◆ getOnTimer()

+ +
+
+ + + + + + + + +
uint16_t IRPanasonicAc::getOnTimer (void )
+
+ +

Get the On Timer time value.

+
Returns
The time expressed as nr. of minutes past midnight.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRPanasonicAc::getPower (void )
+
+ +

Get the A/C power state of the remote.

+
Returns
true, the setting is on. false, the setting is off.
+
Warning
Except for CKP models, where it returns if the power state will be toggled on the A/C unit when the next message is sent.
+ +
+
+ +

◆ getPowerful()

+ +
+
+ + + + + + + + +
bool IRPanasonicAc::getPowerful (void )
+
+ +

Get the Powerful (Turbo) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getQuiet()

+ +
+
+ + + + + + + + +
bool IRPanasonicAc::getQuiet (void )
+
+ +

Get the Quiet setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRPanasonicAc::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSwingHorizontal()

+ +
+
+ + + + + + + + +
uint8_t IRPanasonicAc::getSwingHorizontal (void )
+
+ +

Get the current horizontal swing setting.

+
Returns
The current position it is set to.
+ +
+
+ +

◆ getSwingVertical()

+ +
+
+ + + + + + + + +
uint8_t IRPanasonicAc::getSwingVertical (void )
+
+ +

Get the current vertical swing setting.

+
Returns
The current position it is set to.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRPanasonicAc::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ isOffTimerEnabled()

+ +
+
+ + + + + + + + +
bool IRPanasonicAc::isOffTimerEnabled (void )
+
+ +

Check if the Off Timer is Enabled.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ isOnTimerEnabled()

+ +
+
+ + + + + + + + +
bool IRPanasonicAc::isOnTimerEnabled (void )
+
+ +

Check if the On Timer is Enabled.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRPanasonicAc::off (void )
+
+ +

Change the power setting to Off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRPanasonicAc::on (void )
+
+ +

Change the power setting to On.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRPanasonicAc::send (const uint16_t repeat = kPanasonicAcDefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setClock()

+ +
+
+ + + + + + + + +
void IRPanasonicAc::setClock (const uint16_t mins_since_midnight)
+
+ +

Set the current clock time value.

+
Parameters
+ + +
[in]mins_since_midnightThe time as nr. of minutes past midnight.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRPanasonicAc::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting.
+
+
+ +
+
+ +

◆ setIon()

+ +
+
+ + + + + + + + +
void IRPanasonicAc::setIon (const bool on)
+
+ +

Set the Ion (filter) setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRPanasonicAc::setMode (const uint8_t desired)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]desiredThe desired operating mode.
+
+
+ +
+
+ +

◆ setModel()

+ +
+
+ + + + + + + + +
void IRPanasonicAc::setModel (const panasonic_ac_remote_model_t model)
+
+ +

Set the model of the A/C to emulate.

+
Parameters
+ + +
[in]modelThe enum of the appropriate model.
+
+
+ +
+
+ +

◆ setOffTimer()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRPanasonicAc::setOffTimer (const uint16_t mins_since_midnight,
const bool enable = true 
)
+
+ +

Set/Enable the Off Timer.

+
Parameters
+ + + +
[in]mins_since_midnightThe time as nr. of minutes past midnight.
[in]enableDo we enable the timer or not?
+
+
+ +
+
+ +

◆ setOnTimer()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRPanasonicAc::setOnTimer (const uint16_t mins_since_midnight,
const bool enable = true 
)
+
+ +

Set/Enable the On Timer.

+
Parameters
+ + + +
[in]mins_since_midnightThe time as nr. of minutes past midnight.
[in]enableDo we enable the timer or not?
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRPanasonicAc::setPower (const bool on)
+
+ +

Control the power state of the A/C unit.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+
Warning
For CKP models, the remote has no memory of the power state the A/C unit should be in. For those models setting this on/true will toggle the power state of the Panasonic A/C unit with the next meessage. e.g. If the A/C unit is already on, setPower(true) will turn it off. If the A/C unit is already off, setPower(true) will turn it on. setPower(false) will leave the A/C power state as it was. For all other models, setPower(true) should set the internal state to turn it on, and setPower(false) should turn it off.
+ +
+
+ +

◆ setPowerful()

+ +
+
+ + + + + + + + +
void IRPanasonicAc::setPowerful (const bool on)
+
+ +

Set the Powerful (Turbo) setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setQuiet()

+ +
+
+ + + + + + + + +
void IRPanasonicAc::setQuiet (const bool on)
+
+ +

Set the Quiet setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRPanasonicAc::setRaw (const uint8_t state[])
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]stateA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSwingHorizontal()

+ +
+
+ + + + + + + + +
void IRPanasonicAc::setSwingHorizontal (const uint8_t desired_direction)
+
+ +

Control the horizontal swing setting.

+
Parameters
+ + +
[in]desired_directionThe position to set the horizontal swing to.
+
+
+ +
+
+ +

◆ setSwingVertical()

+ +
+
+ + + + + + + + +
void IRPanasonicAc::setSwingVertical (const uint8_t desired_elevation)
+
+ +

Control the vertical swing setting.

+
Parameters
+ + +
[in]desired_elevationThe position to set the vertical swing to.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRPanasonicAc::setTemp (const uint8_t celsius,
const bool remember = true 
)
+
+ +

Set the temperature.

+
Parameters
+ + + +
[in]celsiusThe temperature in degrees celsius.
[in]rememberA flag for the class to remember the temperature.
+
+
+
Note
Automatically safely limits the temp to the operating range supported.
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRPanasonicAc::stateReset (void )
+
+ +

Reset the state of the remote to a known good state/sequence.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRPanasonicAc::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRPanasonicAc::toCommonFanSpeed (const uint8_t spd)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]spdThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRPanasonicAc::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonSwingH()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::swingh_t IRPanasonicAc::toCommonSwingH (const uint8_t pos)
+
+static
+
+ +

Convert a native horizontal swing postion to it's common equivalent.

+
Parameters
+ + +
[in]posA native position to convert.
+
+
+
Returns
The common horizontal swing position.
+ +
+
+ +

◆ toCommonSwingV()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::swingv_t IRPanasonicAc::toCommonSwingV (const uint8_t pos)
+
+static
+
+ +

Convert a native vertical swing postion to it's common equivalent.

+
Parameters
+ + +
[in]posA native position to convert.
+
+
+
Returns
The common vertical swing position.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRPanasonicAc::toString (void )
+
+ +

Convert the internal state into a human readable string.

+
Returns
A string containing the settings in human-readable form.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRPanasonicAc::validChecksum (const uint8_t * state,
const uint16_t length = kPanasonicAcStateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length of the state array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRPanasonicAc::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ _swingh

+ +
+
+ + + + + +
+ + + + +
uint8_t IRPanasonicAc::_swingh
+
+private
+
+ +
+
+ +

◆ _temp

+ +
+
+ + + + + +
+ + + + +
uint8_t IRPanasonicAc::_temp
+
+private
+
+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRPanasonicAc::remote_state[kPanasonicAcStateLength]
+
+private
+
+ +

The state in code form.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc__coll__graph.map new file mode 100644 index 000000000..806678cd6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc__coll__graph.md5 new file mode 100644 index 000000000..ddab76af4 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc__coll__graph.md5 @@ -0,0 +1 @@ +d3db02dc98d87de4f04f73ee0ebb90c7 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc__coll__graph.png new file mode 100644 index 000000000..9b0c44699 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRPanasonicAc__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSamsungAc-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSamsungAc-members.html new file mode 100644 index 000000000..17f726a42 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSamsungAc-members.html @@ -0,0 +1,128 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRSamsungAc Member List
+
+
+ +

This is the complete list of members for IRSamsungAc, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_forcepowerIRSamsungAcprivate
_irsendIRSamsungAcprivate
_lastsentpowerstateIRSamsungAcprivate
begin(void)IRSamsungAc
calcChecksum(const uint8_t state[], const uint16_t length=kSamsungAcStateLength)IRSamsungAcstatic
calibrate(void)IRSamsungAcinline
checksum(const uint16_t length=kSamsungAcStateLength)IRSamsungAcprivate
convertFan(const stdAc::fanspeed_t speed)IRSamsungAc
convertMode(const stdAc::opmode_t mode)IRSamsungAc
getBeep(void)IRSamsungAc
getBreeze(void)IRSamsungAc
getClean(void)IRSamsungAc
getDisplay(void)IRSamsungAc
getFan(void)IRSamsungAc
getIon(void)IRSamsungAc
getMode(void)IRSamsungAc
getPower(void)IRSamsungAc
getPowerful(void)IRSamsungAc
getQuiet(void)IRSamsungAc
getRaw(void)IRSamsungAc
getSwing(void)IRSamsungAc
getTemp(void)IRSamsungAc
IRSamsungAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRSamsungAcexplicit
off(void)IRSamsungAc
on(void)IRSamsungAc
remote_stateIRSamsungAcprivate
send(const uint16_t repeat=kSamsungAcDefaultRepeat, const bool calcchecksum=true)IRSamsungAc
sendExtended(const uint16_t repeat=kSamsungAcDefaultRepeat, const bool calcchecksum=true)IRSamsungAc
sendOff(const uint16_t repeat=kSamsungAcDefaultRepeat)IRSamsungAc
sendOn(const uint16_t repeat=kSamsungAcDefaultRepeat)IRSamsungAc
setBeep(const bool on)IRSamsungAc
setBreeze(const bool on)IRSamsungAc
setClean(const bool on)IRSamsungAc
setDisplay(const bool on)IRSamsungAc
setFan(const uint8_t speed)IRSamsungAc
setIon(const bool on)IRSamsungAc
setMode(const uint8_t mode)IRSamsungAc
setPower(const bool on)IRSamsungAc
setPowerful(const bool on)IRSamsungAc
setQuiet(const bool on)IRSamsungAc
setRaw(const uint8_t new_code[], const uint16_t length=kSamsungAcStateLength)IRSamsungAc
setSwing(const bool on)IRSamsungAc
setTemp(const uint8_t temp)IRSamsungAc
stateReset(const bool forcepower=true, const bool initialPower=true)IRSamsungAc
toCommon(void)IRSamsungAc
toCommonFanSpeed(const uint8_t speed)IRSamsungAcstatic
toCommonMode(const uint8_t mode)IRSamsungAcstatic
toString(void)IRSamsungAc
validChecksum(const uint8_t state[], const uint16_t length=kSamsungAcStateLength)IRSamsungAcstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSamsungAc.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSamsungAc.html new file mode 100644 index 000000000..3b0e593c0 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSamsungAc.html @@ -0,0 +1,1585 @@ + + + + + + + +IRremoteESP8266: IRSamsungAc Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Samsung A/C messages. + More...

+ +

#include <ir_Samsung.h>

+
+Collaboration diagram for IRSamsungAc:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRSamsungAc (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset (const bool forcepower=true, const bool initialPower=true)
 Reset the internal state of the emulation. More...
 
void send (const uint16_t repeat=kSamsungAcDefaultRepeat, const bool calcchecksum=true)
 Send the current internal state as an IR message. More...
 
void sendExtended (const uint16_t repeat=kSamsungAcDefaultRepeat, const bool calcchecksum=true)
 Send the extended current internal state as an IR message. More...
 
void sendOn (const uint16_t repeat=kSamsungAcDefaultRepeat)
 Send the special extended "On" message as the library can't seem to reproduce this message automatically. More...
 
void sendOff (const uint16_t repeat=kSamsungAcDefaultRepeat)
 Send the special extended "Off" message as the library can't seem to reproduce this message automatically. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Set the requested power state of the A/C to on. More...
 
void off (void)
 Set the requested power state of the A/C to off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t speed)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setSwing (const bool on)
 Set the vertical swing setting of the A/C. More...
 
bool getSwing (void)
 Get the vertical swing setting of the A/C. More...
 
void setBeep (const bool on)
 Set the Beep setting of the A/C. More...
 
bool getBeep (void)
 Get the Beep setting of the A/C. More...
 
void setClean (const bool on)
 Set the Clean setting of the A/C. More...
 
bool getClean (void)
 Get the Clean setting of the A/C. More...
 
void setQuiet (const bool on)
 Set the Quiet setting of the A/C. More...
 
bool getQuiet (void)
 Get the Quiet setting of the A/C. More...
 
void setPowerful (const bool on)
 Set the Powerful (Turbo) setting of the A/C. More...
 
bool getPowerful (void)
 Get the Powerful (Turbo) setting of the A/C. More...
 
void setBreeze (const bool on)
 Closes the vanes over the fan outlet, to stop direct wind. Aka. WindFree. More...
 
bool getBreeze (void)
 Are the vanes closed over the fan outlet, to stop direct wind? Aka. WindFree. More...
 
void setDisplay (const bool on)
 Set the Display (Light/LED) setting of the A/C. More...
 
bool getDisplay (void)
 Get the Display (Light/LED) setting of the A/C. More...
 
void setIon (const bool on)
 Set the Ion (Filter) setting of the A/C. More...
 
bool getIon (void)
 Get the Ion (Filter) setting of the A/C. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t new_code[], const uint16_t length=kSamsungAcStateLength)
 Set the internal state from a valid code for this protocol. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (const uint8_t state[], const uint16_t length=kSamsungAcStateLength)
 Verify the checksum is valid for a given state. More...
 
static uint8_t calcChecksum (const uint8_t state[], const uint16_t length=kSamsungAcStateLength)
 Calculate the checksum for a given state. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + +

+Private Member Functions

void checksum (const uint16_t length=kSamsungAcStateLength)
 Update the checksum for the internal state. More...
 
+ + + + + + + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kSamsungAcExtendedStateLength]
 State in code form. More...
 
bool _forcepower
 Hack to know when we need to send a special power mesg. More...
 
bool _lastsentpowerstate
 
+

Detailed Description

+

Class for handling detailed Samsung A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRSamsungAc()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRSamsungAc::IRSamsungAc (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRSamsungAc::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calcChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
uint8_t IRSamsungAc::calcChecksum (const uint8_t state[],
const uint16_t length = kSamsungAcStateLength 
)
+
+static
+
+ +

Calculate the checksum for a given state.

+
Parameters
+ + + +
[in]stateThe array to calc the checksum of.
[in]lengthThe length/size of the array.
+
+
+
Returns
The calculated checksum value.
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRSamsungAc::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
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.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRSamsungAc::checksum (const uint16_t length = kSamsungAcStateLength)
+
+private
+
+ +

Update the checksum for the internal state.

+
Parameters
+ + +
[in]lengthThe length/size of the internal array to checksum.
+
+
+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRSamsungAc::convertFan (const stdAc::fanspeed_t speed)
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRSamsungAc::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getBeep()

+ +
+
+ + + + + + + + +
bool IRSamsungAc::getBeep (void )
+
+ +

Get the Beep setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getBreeze()

+ +
+
+ + + + + + + + +
bool IRSamsungAc::getBreeze (void )
+
+ +

Are the vanes closed over the fan outlet, to stop direct wind? Aka. WindFree.

+
Returns
true, the setting is on. false, the setting is off.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/1062
+ +
+
+ +

◆ getClean()

+ +
+
+ + + + + + + + +
bool IRSamsungAc::getClean (void )
+
+ +

Get the Clean setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getDisplay()

+ +
+
+ + + + + + + + +
bool IRSamsungAc::getDisplay (void )
+
+ +

Get the Display (Light/LED) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRSamsungAc::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed/mode.
+ +
+
+ +

◆ getIon()

+ +
+
+ + + + + + + + +
bool IRSamsungAc::getIon (void )
+
+ +

Get the Ion (Filter) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRSamsungAc::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRSamsungAc::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getPowerful()

+ +
+
+ + + + + + + + +
bool IRSamsungAc::getPowerful (void )
+
+ +

Get the Powerful (Turbo) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getQuiet()

+ +
+
+ + + + + + + + +
bool IRSamsungAc::getQuiet (void )
+
+ +

Get the Quiet setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRSamsungAc::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSwing()

+ +
+
+ + + + + + + + +
bool IRSamsungAc::getSwing (void )
+
+ +

Get the vertical swing setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+
Todo:
(Hollako) Explain why sometimes the LSB of remote_state[9] is a 1. e.g. 0xAE or 0XAF for swing move.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRSamsungAc::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRSamsungAc::off (void )
+
+ +

Set the requested power state of the A/C to off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRSamsungAc::on (void )
+
+ +

Set the requested power state of the A/C to on.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRSamsungAc::send (const uint16_t repeat = kSamsungAcDefaultRepeat,
const bool calcchecksum = true 
)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + + +
[in]repeatNr. of times the message will be repeated.
[in]calcchecksumDo we update the checksum before sending?
+
+
+
Note
Use for most function/mode/settings changes to the unit. i.e. When the device is already running.
+ +
+
+ +

◆ sendExtended()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRSamsungAc::sendExtended (const uint16_t repeat = kSamsungAcDefaultRepeat,
const bool calcchecksum = true 
)
+
+ +

Send the extended current internal state as an IR message.

+
Parameters
+ + + +
[in]repeatNr. of times the message will be repeated.
[in]calcchecksumDo we update the checksum before sending?
+
+
+
Note
Use this for when you need to power on/off the device. Samsung A/C requires an extended length message when you want to change the power operating mode of the A/C unit.
+ +
+
+ +

◆ sendOff()

+ +
+
+ + + + + + + + +
void IRSamsungAc::sendOff (const uint16_t repeat = kSamsungAcDefaultRepeat)
+
+ +

Send the special extended "Off" message as the library can't seem to reproduce this message automatically.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/604#issuecomment-475020036
+ +
+
+ +

◆ sendOn()

+ +
+
+ + + + + + + + +
void IRSamsungAc::sendOn (const uint16_t repeat = kSamsungAcDefaultRepeat)
+
+ +

Send the special extended "On" message as the library can't seem to reproduce this message automatically.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/604#issuecomment-475020036
+ +
+
+ +

◆ setBeep()

+ +
+
+ + + + + + + + +
void IRSamsungAc::setBeep (const bool on)
+
+ +

Set the Beep setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setBreeze()

+ +
+
+ + + + + + + + +
void IRSamsungAc::setBreeze (const bool on)
+
+ +

Closes the vanes over the fan outlet, to stop direct wind. Aka. WindFree.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/1062
+ +
+
+ +

◆ setClean()

+ +
+
+ + + + + + + + +
void IRSamsungAc::setClean (const bool on)
+
+ +

Set the Clean setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setDisplay()

+ +
+
+ + + + + + + + +
void IRSamsungAc::setDisplay (const bool on)
+
+ +

Set the Display (Light/LED) setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRSamsungAc::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting.
+
+
+ +
+
+ +

◆ setIon()

+ +
+
+ + + + + + + + +
void IRSamsungAc::setIon (const bool on)
+
+ +

Set the Ion (Filter) setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRSamsungAc::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRSamsungAc::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setPowerful()

+ +
+
+ + + + + + + + +
void IRSamsungAc::setPowerful (const bool on)
+
+ +

Set the Powerful (Turbo) setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setQuiet()

+ +
+
+ + + + + + + + +
void IRSamsungAc::setQuiet (const bool on)
+
+ +

Set the Quiet setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRSamsungAc::setRaw (const uint8_t new_code[],
const uint16_t length = kSamsungAcStateLength 
)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + + +
[in]new_codeA valid code for this protocol.
[in]lengthThe length/size of the new_code array.
+
+
+ +
+
+ +

◆ setSwing()

+ +
+
+ + + + + + + + +
void IRSamsungAc::setSwing (const bool on)
+
+ +

Set the vertical swing setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+
Todo:
(Hollako) Explain why sometimes the LSB of remote_state[9] is a 1. e.g. 0xAE or 0XAF for swing move.
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRSamsungAc::setTemp (const uint8_t temp)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]tempThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRSamsungAc::stateReset (const bool forcepower = true,
const bool initialPower = true 
)
+
+ +

Reset the internal state of the emulation.

+
Parameters
+ + + +
[in]forcepowerA flag indicating if force sending a special power message with the first send() call.
[in]initialPowerSet the initial power state. True, on. False, off.
+
+
+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRSamsungAc::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRSamsungAc::toCommonFanSpeed (const uint8_t spd)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]spdThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRSamsungAc::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRSamsungAc::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRSamsungAc::validChecksum (const uint8_t state[],
const uint16_t length = kSamsungAcStateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length/size of the array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _forcepower

+ +
+
+ + + + + +
+ + + + +
bool IRSamsungAc::_forcepower
+
+private
+
+ +

Hack to know when we need to send a special power mesg.

+ +
+
+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRSamsungAc::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ _lastsentpowerstate

+ +
+
+ + + + + +
+ + + + +
bool IRSamsungAc::_lastsentpowerstate
+
+private
+
+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRSamsungAc::remote_state[kSamsungAcExtendedStateLength]
+
+private
+
+ +

State in code form.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSamsungAc__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSamsungAc__coll__graph.map new file mode 100644 index 000000000..7b65cd5e6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSamsungAc__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSamsungAc__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSamsungAc__coll__graph.md5 new file mode 100644 index 000000000..c11ced0ba --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSamsungAc__coll__graph.md5 @@ -0,0 +1 @@ +383f10b4ef1888fea2358fde261598f6 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSamsungAc__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSamsungAc__coll__graph.png new file mode 100644 index 000000000..9ce17f8b0 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSamsungAc__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc-members.html new file mode 100644 index 000000000..904c5623f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc-members.html @@ -0,0 +1,130 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRSharpAc Member List
+
+
+ +

This is the complete list of members for IRSharpAc, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_fanIRSharpAcprivate
_irsendIRSharpAcprivate
_modeIRSharpAcprivate
_tempIRSharpAcprivate
begin(void)IRSharpAc
calcChecksum(uint8_t state[], const uint16_t length=kSharpAcStateLength)IRSharpAcprivatestatic
calibrate(void)IRSharpAcinline
checksum(void)IRSharpAcprivate
clearPowerSpecial(void)IRSharpAcprivate
convertFan(const stdAc::fanspeed_t speed)IRSharpAcstatic
convertMode(const stdAc::opmode_t mode)IRSharpAcstatic
getClean(void)IRSharpAc
getEconoToggle(void)IRSharpAc
getFan(void)IRSharpAc
getIon(void)IRSharpAc
getMode(void)IRSharpAc
getPower(void)IRSharpAc
getPowerSpecial(void)IRSharpAcprivate
getRaw(void)IRSharpAc
getSpecial(void)IRSharpAc
getSwingToggle(void)IRSharpAc
getTemp(void)IRSharpAc
getTimerEnabled(void)IRSharpAc
getTimerTime(void)IRSharpAc
getTimerType(void)IRSharpAc
getTurbo(void)IRSharpAc
IRSharpAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRSharpAcexplicit
isPowerSpecial(void)IRSharpAc
off(void)IRSharpAc
on(void)IRSharpAc
remoteIRSharpAcprivate
send(const uint16_t repeat=kSharpAcDefaultRepeat)IRSharpAc
setClean(const bool on)IRSharpAc
setEconoToggle(const bool on)IRSharpAc
setFan(const uint8_t fan, const bool save=true)IRSharpAc
setIon(const bool on)IRSharpAc
setMode(const uint8_t mode, const bool save=true)IRSharpAc
setPower(const bool on, const bool prev_on=true)IRSharpAc
setPowerSpecial(const uint8_t value)IRSharpAcprivate
setRaw(const uint8_t new_code[], const uint16_t length=kSharpAcStateLength)IRSharpAc
setSpecial(const uint8_t mode)IRSharpAc
setSwingToggle(const bool on)IRSharpAc
setTemp(const uint8_t temp, const bool save=true)IRSharpAc
setTimer(bool enable, bool timer_type, uint16_t mins)IRSharpAc
setTurbo(const bool on)IRSharpAc
stateReset(void)IRSharpAcprivate
toCommon(void)IRSharpAc
toCommonFanSpeed(const uint8_t speed)IRSharpAcstatic
toCommonMode(const uint8_t mode)IRSharpAcstatic
toString(void)IRSharpAc
validChecksum(uint8_t state[], const uint16_t length=kSharpAcStateLength)IRSharpAcstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc.html new file mode 100644 index 000000000..09a5d0a75 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc.html @@ -0,0 +1,1688 @@ + + + + + + + +IRremoteESP8266: IRSharpAc Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Sharp A/C messages. + More...

+ +

#include <ir_Sharp.h>

+
+Collaboration diagram for IRSharpAc:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRSharpAc (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void send (const uint16_t repeat=kSharpAcDefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Set the requested power state of the A/C to on. More...
 
void off (void)
 Set the requested power state of the A/C to off. More...
 
void setPower (const bool on, const bool prev_on=true)
 Change the power setting, including the previous power state. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
bool isPowerSpecial (void)
 Is one of the special power states in use? More...
 
void setTemp (const uint8_t temp, const bool save=true)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t fan, const bool save=true)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode, const bool save=true)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setSpecial (const uint8_t mode)
 Set the value of the Special (button/command?) setting. More...
 
uint8_t getSpecial (void)
 Get the value of the Special (button/command?) setting. More...
 
bool getTurbo (void)
 Get the Turbo setting of the A/C. More...
 
void setTurbo (const bool on)
 Set the Turbo setting of the A/C. More...
 
bool getSwingToggle (void)
 Get the (vertical) Swing Toggle setting of the A/C. More...
 
void setSwingToggle (const bool on)
 Set the (vertical) Swing Toggle setting of the A/C. More...
 
bool getIon (void)
 Get the Ion (Filter) setting of the A/C. More...
 
void setIon (const bool on)
 Set the Ion (Filter) setting of the A/C. More...
 
bool getEconoToggle (void)
 Get the Economical mode toggle setting of the A/C. More...
 
void setEconoToggle (const bool on)
 Set the Economical mode toggle setting of the A/C. More...
 
uint16_t getTimerTime (void)
 Get how long the timer is set for, in minutes. More...
 
bool getTimerEnabled (void)
 Is the Timer enabled? More...
 
bool getTimerType (void)
 Get the current timer type. More...
 
void setTimer (bool enable, bool timer_type, uint16_t mins)
 Set or cancel the timer function. More...
 
bool getClean (void)
 Get the Clean setting of the A/C. More...
 
void setClean (const bool on)
 Set the Economical mode toggle setting of the A/C. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t new_code[], const uint16_t length=kSharpAcStateLength)
 Set the internal state from a valid code for this protocol. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (uint8_t state[], const uint16_t length=kSharpAcStateLength)
 Verify the checksum is valid for a given state. More...
 
static uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
static uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + + + + + + + + + + + + + +

+Private Member Functions

void stateReset (void)
 Reset the state of the remote to a known good state/sequence. More...
 
void checksum (void)
 Calculate and set the checksum values for the internal state. More...
 
void setPowerSpecial (const uint8_t value)
 Set the value of the Power Special setting without any checks. More...
 
uint8_t getPowerSpecial (void)
 Get the value of the Power Special setting. More...
 
void clearPowerSpecial (void)
 Clear the "special"/non-normal bits in the power section. e.g. for normal/common command modes. More...
 
+ + + + +

+Static Private Member Functions

static uint8_t calcChecksum (uint8_t state[], const uint16_t length=kSharpAcStateLength)
 Calculate the checksum for a given state. More...
 
+ + + + + + + + + + + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote [kSharpAcStateLength]
 State of the remote in IR code form. More...
 
uint8_t _temp
 Saved copy of the desired temp. More...
 
uint8_t _mode
 Saved copy of the desired mode. More...
 
uint8_t _fan
 Saved copy of the desired fan speed. More...
 
+

Detailed Description

+

Class for handling detailed Sharp A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRSharpAc()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRSharpAc::IRSharpAc (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRSharpAc::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calcChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
uint8_t IRSharpAc::calcChecksum (uint8_t state[],
const uint16_t length = kSharpAcStateLength 
)
+
+staticprivate
+
+ +

Calculate the checksum for a given state.

+
Parameters
+ + + +
[in]stateThe array to calc the checksum of.
[in]lengthThe length/size of the array.
+
+
+
Returns
The calculated 4-bit checksum value.
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRSharpAc::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
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.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRSharpAc::checksum (void )
+
+private
+
+ +

Calculate and set the checksum values for the internal state.

+ +
+
+ +

◆ clearPowerSpecial()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRSharpAc::clearPowerSpecial (void )
+
+private
+
+ +

Clear the "special"/non-normal bits in the power section. e.g. for normal/common command modes.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRSharpAc::convertFan (const stdAc::fanspeed_t speed)
+
+static
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRSharpAc::convertMode (const stdAc::opmode_t mode)
+
+static
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getClean()

+ +
+
+ + + + + + + + +
bool IRSharpAc::getClean (void )
+
+ +

Get the Clean setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getEconoToggle()

+ +
+
+ + + + + + + + +
bool IRSharpAc::getEconoToggle (void )
+
+ +

Get the Economical mode toggle setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRSharpAc::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed/mode.
+ +
+
+ +

◆ getIon()

+ +
+
+ + + + + + + + +
bool IRSharpAc::getIon (void )
+
+ +

Get the Ion (Filter) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRSharpAc::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRSharpAc::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getPowerSpecial()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRSharpAc::getPowerSpecial (void )
+
+private
+
+ +

Get the value of the Power Special setting.

+
Returns
The setting's value.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRSharpAc::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSpecial()

+ +
+
+ + + + + + + + +
uint8_t IRSharpAc::getSpecial (void )
+
+ +

Get the value of the Special (button/command?) setting.

+
Returns
The setting's value.
+ +
+
+ +

◆ getSwingToggle()

+ +
+
+ + + + + + + + +
bool IRSharpAc::getSwingToggle (void )
+
+ +

Get the (vertical) Swing Toggle setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRSharpAc::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ getTimerEnabled()

+ +
+
+ + + + + + + + +
bool IRSharpAc::getTimerEnabled (void )
+
+ +

Is the Timer enabled?

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTimerTime()

+ +
+
+ + + + + + + + +
uint16_t IRSharpAc::getTimerTime (void )
+
+ +

Get how long the timer is set for, in minutes.

+
Returns
The time in nr of minutes.
+ +
+
+ +

◆ getTimerType()

+ +
+
+ + + + + + + + +
bool IRSharpAc::getTimerType (void )
+
+ +

Get the current timer type.

+
Returns
true, It's an "On" timer. false, It's an "Off" timer.
+ +
+
+ +

◆ getTurbo()

+ +
+
+ + + + + + + + +
bool IRSharpAc::getTurbo (void )
+
+ +

Get the Turbo setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ isPowerSpecial()

+ +
+
+ + + + + + + + +
bool IRSharpAc::isPowerSpecial (void )
+
+ +

Is one of the special power states in use?

+
Returns
true, it is. false, it isn't.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRSharpAc::off (void )
+
+ +

Set the requested power state of the A/C to off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRSharpAc::on (void )
+
+ +

Set the requested power state of the A/C to on.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRSharpAc::send (const uint16_t repeat = kSharpAcDefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setClean()

+ +
+
+ + + + + + + + +
void IRSharpAc::setClean (const bool on)
+
+ +

Set the Economical mode toggle setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+
Note
Officially A/C unit needs to be "Off" before clean mode can be entered
+ +
+
+ +

◆ setEconoToggle()

+ +
+
+ + + + + + + + +
void IRSharpAc::setEconoToggle (const bool on)
+
+ +

Set the Economical mode toggle setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+
Warning
Probably incompatible with setTurbo()
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRSharpAc::setFan (const uint8_t speed,
const bool save = true 
)
+
+ +

Set the speed of the fan.

+
Parameters
+ + + +
[in]speedThe desired setting.
[in]saveDo we save this setting as a user set one?
+
+
+ +
+
+ +

◆ setIon()

+ +
+
+ + + + + + + + +
void IRSharpAc::setIon (const bool on)
+
+ +

Set the Ion (Filter) setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRSharpAc::setMode (const uint8_t mode,
const bool save = true 
)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + + +
[in]modeThe desired operating mode.
[in]saveDo we save this setting as a user set one?
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRSharpAc::setPower (const bool on,
const bool prev_on = true 
)
+
+ +

Change the power setting, including the previous power state.

+
Parameters
+ + + +
[in]ontrue, the setting is on. false, the setting is off.
[in]prev_ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setPowerSpecial()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRSharpAc::setPowerSpecial (const uint8_t value)
+
+private
+
+ +

Set the value of the Power Special setting without any checks.

+
Parameters
+ + +
[in]valueThe value to set Power Special to.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRSharpAc::setRaw (const uint8_t new_code[],
const uint16_t length = kSharpAcStateLength 
)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + + +
[in]new_codeA valid code for this protocol.
[in]lengthThe length/size of the new_code array.
+
+
+ +
+
+ +

◆ setSpecial()

+ +
+
+ + + + + + + + +
void IRSharpAc::setSpecial (const uint8_t mode)
+
+ +

Set the value of the Special (button/command?) setting.

+
Parameters
+ + +
[in]modeThe value to set Special to.
+
+
+ +
+
+ +

◆ setSwingToggle()

+ +
+
+ + + + + + + + +
void IRSharpAc::setSwingToggle (const bool on)
+
+ +

Set the (vertical) Swing Toggle setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRSharpAc::setTemp (const uint8_t temp,
const bool save = true 
)
+
+ +

Set the temperature.

+
Parameters
+ + + +
[in]tempThe temperature in degrees celsius.
[in]saveDo we save this setting as a user set one?
+
+
+ +
+
+ +

◆ setTimer()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRSharpAc::setTimer (bool enable,
bool timer_type,
uint16_t mins 
)
+
+ +

Set or cancel the timer function.

+
Parameters
+ + + + +
[in]enableIs the timer to be enabled (true) or canceled(false)?
[in]timer_typeAn On (true) or an Off (false). Ignored if canceled.
[in]minsNr. of minutes the timer is to be set to.
+
+
+
Note
Rounds down to 30 min increments. (max: 720 mins (12h), 0 is Off)
+ +
+
+ +

◆ setTurbo()

+ +
+
+ + + + + + + + +
void IRSharpAc::setTurbo (const bool on)
+
+ +

Set the Turbo setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+
Note
If you use this method, you will need to send it before making other changes to the settings, as they may overwrite some of the bits used by this setting.
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRSharpAc::stateReset (void )
+
+private
+
+ +

Reset the state of the remote to a known good state/sequence.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRSharpAc::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRSharpAc::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRSharpAc::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRSharpAc::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRSharpAc::validChecksum (uint8_t state[],
const uint16_t length = kSharpAcStateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length/size of the array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _fan

+ +
+
+ + + + + +
+ + + + +
uint8_t IRSharpAc::_fan
+
+private
+
+ +

Saved copy of the desired fan speed.

+ +
+
+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRSharpAc::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ _mode

+ +
+
+ + + + + +
+ + + + +
uint8_t IRSharpAc::_mode
+
+private
+
+ +

Saved copy of the desired mode.

+ +
+
+ +

◆ _temp

+ +
+
+ + + + + +
+ + + + +
uint8_t IRSharpAc::_temp
+
+private
+
+ +

Saved copy of the desired temp.

+ +
+
+ +

◆ remote

+ +
+
+ + + + + +
+ + + + +
uint8_t IRSharpAc::remote[kSharpAcStateLength]
+
+private
+
+ +

State of the remote in IR code form.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc__coll__graph.map new file mode 100644 index 000000000..bd52394a1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc__coll__graph.md5 new file mode 100644 index 000000000..4e92a3fe3 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc__coll__graph.md5 @@ -0,0 +1 @@ +a87b7a535dbb4358d51525a2278a117d \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc__coll__graph.png new file mode 100644 index 000000000..397be3abb Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRSharpAc__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTcl112Ac-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTcl112Ac-members.html new file mode 100644 index 000000000..26927bc25 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTcl112Ac-members.html @@ -0,0 +1,119 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRTcl112Ac Member List
+
+
+ +

This is the complete list of members for IRTcl112Ac, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRTcl112Acprivate
begin(void)IRTcl112Ac
calcChecksum(uint8_t state[], const uint16_t length=kTcl112AcStateLength)IRTcl112Acstatic
calibrate(void)IRTcl112Acinline
checksum(const uint16_t length=kTcl112AcStateLength)IRTcl112Acprivate
convertFan(const stdAc::fanspeed_t speed)IRTcl112Ac
convertMode(const stdAc::opmode_t mode)IRTcl112Ac
getEcono(void)IRTcl112Ac
getFan(void)IRTcl112Ac
getHealth(void)IRTcl112Ac
getLight(void)IRTcl112Ac
getMode(void)IRTcl112Ac
getPower(void)IRTcl112Ac
getRaw(void)IRTcl112Ac
getSwingHorizontal(void)IRTcl112Ac
getSwingVertical(void)IRTcl112Ac
getTemp(void)IRTcl112Ac
getTurbo(void)IRTcl112Ac
IRTcl112Ac(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRTcl112Acexplicit
off(void)IRTcl112Ac
on(void)IRTcl112Ac
remote_stateIRTcl112Acprivate
send(const uint16_t repeat=kTcl112AcDefaultRepeat)IRTcl112Ac
setEcono(const bool on)IRTcl112Ac
setFan(const uint8_t speed)IRTcl112Ac
setHealth(const bool on)IRTcl112Ac
setLight(const bool on)IRTcl112Ac
setMode(const uint8_t mode)IRTcl112Ac
setPower(const bool on)IRTcl112Ac
setRaw(const uint8_t new_code[], const uint16_t length=kTcl112AcStateLength)IRTcl112Ac
setSwingHorizontal(const bool on)IRTcl112Ac
setSwingVertical(const bool on)IRTcl112Ac
setTemp(const float celsius)IRTcl112Ac
setTurbo(const bool on)IRTcl112Ac
stateReset(void)IRTcl112Ac
toCommon(void)IRTcl112Ac
toCommonFanSpeed(const uint8_t speed)IRTcl112Acstatic
toCommonMode(const uint8_t mode)IRTcl112Acstatic
toString(void)IRTcl112Ac
validChecksum(uint8_t state[], const uint16_t length=kTcl112AcStateLength)IRTcl112Acstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTcl112Ac.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTcl112Ac.html new file mode 100644 index 000000000..f814eac41 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTcl112Ac.html @@ -0,0 +1,1298 @@ + + + + + + + +IRremoteESP8266: IRTcl112Ac Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed TCL A/C messages. + More...

+ +

#include <ir_Tcl.h>

+
+Collaboration diagram for IRTcl112Ac:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRTcl112Ac (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void send (const uint16_t repeat=kTcl112AcDefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void stateReset (void)
 Reset the internal state of the emulation. (On, Cool, 24C) More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t new_code[], const uint16_t length=kTcl112AcStateLength)
 Set the internal state from a valid code for this protocol. More...
 
void on (void)
 Set the requested power state of the A/C to on. More...
 
void off (void)
 Set the requested power state of the A/C to off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setTemp (const float celsius)
 Set the temperature. More...
 
float getTemp (void)
 Get the current temperature setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setFan (const uint8_t speed)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setEcono (const bool on)
 Set the economy setting of the A/C. More...
 
bool getEcono (void)
 Get the economy setting of the A/C. More...
 
void setHealth (const bool on)
 Set the Health (Filter) setting of the A/C. More...
 
bool getHealth (void)
 Get the Health (Filter) setting of the A/C. More...
 
void setLight (const bool on)
 Set the Light (LED/Display) setting of the A/C. More...
 
bool getLight (void)
 Get the Light (LED/Display) setting of the A/C. More...
 
void setSwingHorizontal (const bool on)
 Set the horizontal swing setting of the A/C. More...
 
bool getSwingHorizontal (void)
 Get the horizontal swing setting of the A/C. More...
 
void setSwingVertical (const bool on)
 Set the vertical swing setting of the A/C. More...
 
bool getSwingVertical (void)
 Get the vertical swing setting of the A/C. More...
 
void setTurbo (const bool on)
 Set the Turbo setting of the A/C. More...
 
bool getTurbo (void)
 Get the Turbo setting of the A/C. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + + + + +

+Static Public Member Functions

static uint8_t calcChecksum (uint8_t state[], const uint16_t length=kTcl112AcStateLength)
 Calculate the checksum for a given state. More...
 
static bool validChecksum (uint8_t state[], const uint16_t length=kTcl112AcStateLength)
 Verify the checksum is valid for a given state. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + +

+Private Member Functions

void checksum (const uint16_t length=kTcl112AcStateLength)
 Calculate & set the checksum for the current internal state of the remote. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kTcl112AcStateLength]
 The State in IR code form. More...
 
+

Detailed Description

+

Class for handling detailed TCL A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRTcl112Ac()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRTcl112Ac::IRTcl112Ac (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRTcl112Ac::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calcChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
uint8_t IRTcl112Ac::calcChecksum (uint8_t state[],
const uint16_t length = kTcl112AcStateLength 
)
+
+static
+
+ +

Calculate the checksum for a given state.

+
Parameters
+ + + +
[in]stateThe array to calc the checksum of.
[in]lengthThe length/size of the array.
+
+
+
Returns
The calculated checksum value.
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRTcl112Ac::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
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.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRTcl112Ac::checksum (const uint16_t length = kTcl112AcStateLength)
+
+private
+
+ +

Calculate & set the checksum for the current internal state of the remote.

+
Parameters
+ + +
[in]lengthThe length/size of the internal array to checksum.
+
+
+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRTcl112Ac::convertFan (const stdAc::fanspeed_t speed)
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRTcl112Ac::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getEcono()

+ +
+
+ + + + + + + + +
bool IRTcl112Ac::getEcono (void )
+
+ +

Get the economy setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRTcl112Ac::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed/mode.
+ +
+
+ +

◆ getHealth()

+ +
+
+ + + + + + + + +
bool IRTcl112Ac::getHealth (void )
+
+ +

Get the Health (Filter) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getLight()

+ +
+
+ + + + + + + + +
bool IRTcl112Ac::getLight (void )
+
+ +

Get the Light (LED/Display) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRTcl112Ac::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRTcl112Ac::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRTcl112Ac::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSwingHorizontal()

+ +
+
+ + + + + + + + +
bool IRTcl112Ac::getSwingHorizontal (void )
+
+ +

Get the horizontal swing setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwingVertical()

+ +
+
+ + + + + + + + +
bool IRTcl112Ac::getSwingVertical (void )
+
+ +

Get the vertical swing setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
float IRTcl112Ac::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+
Note
The temperature resolution is 0.5 of a degree.
+ +
+
+ +

◆ getTurbo()

+ +
+
+ + + + + + + + +
bool IRTcl112Ac::getTurbo (void )
+
+ +

Get the Turbo setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRTcl112Ac::off (void )
+
+ +

Set the requested power state of the A/C to off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRTcl112Ac::on (void )
+
+ +

Set the requested power state of the A/C to on.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRTcl112Ac::send (const uint16_t repeat = kTcl112AcDefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setEcono()

+ +
+
+ + + + + + + + +
void IRTcl112Ac::setEcono (const bool on)
+
+ +

Set the economy setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRTcl112Ac::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting.
+
+
+
Note
Unknown speeds will default to Auto.
+ +
+
+ +

◆ setHealth()

+ +
+
+ + + + + + + + +
void IRTcl112Ac::setHealth (const bool on)
+
+ +

Set the Health (Filter) setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setLight()

+ +
+
+ + + + + + + + +
void IRTcl112Ac::setLight (const bool on)
+
+ +

Set the Light (LED/Display) setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRTcl112Ac::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+
Note
Fan/Ventilation mode sets the fan speed to high. Unknown values default to Auto.
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRTcl112Ac::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRTcl112Ac::setRaw (const uint8_t new_code[],
const uint16_t length = kTcl112AcStateLength 
)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + + +
[in]new_codeA valid code for this protocol.
[in]lengthThe length/size of the new_code array.
+
+
+ +
+
+ +

◆ setSwingHorizontal()

+ +
+
+ + + + + + + + +
void IRTcl112Ac::setSwingHorizontal (const bool on)
+
+ +

Set the horizontal swing setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwingVertical()

+ +
+
+ + + + + + + + +
void IRTcl112Ac::setSwingVertical (const bool on)
+
+ +

Set the vertical swing setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRTcl112Ac::setTemp (const float celsius)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]celsiusThe temperature in degrees celsius.
+
+
+
Note
The temperature resolution is 0.5 of a degree.
+ +
+
+ +

◆ setTurbo()

+ +
+
+ + + + + + + + +
void IRTcl112Ac::setTurbo (const bool on)
+
+ +

Set the Turbo setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRTcl112Ac::stateReset (void )
+
+ +

Reset the internal state of the emulation. (On, Cool, 24C)

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRTcl112Ac::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRTcl112Ac::toCommonFanSpeed (const uint8_t spd)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]spdThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRTcl112Ac::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRTcl112Ac::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRTcl112Ac::validChecksum (uint8_t state[],
const uint16_t length = kTcl112AcStateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length/size of the array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRTcl112Ac::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRTcl112Ac::remote_state[kTcl112AcStateLength]
+
+private
+
+ +

The State in IR code form.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTcl112Ac__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTcl112Ac__coll__graph.map new file mode 100644 index 000000000..206ef60dc --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTcl112Ac__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTcl112Ac__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTcl112Ac__coll__graph.md5 new file mode 100644 index 000000000..b7845c7a0 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTcl112Ac__coll__graph.md5 @@ -0,0 +1 @@ +b01bf74458107df4a91e8d68cd7bd7c2 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTcl112Ac__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTcl112Ac__coll__graph.png new file mode 100644 index 000000000..713bce3fb Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTcl112Ac__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc-members.html new file mode 100644 index 000000000..3b51979c9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc-members.html @@ -0,0 +1,117 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRTecoAc Member List
+
+
+ +

This is the complete list of members for IRTecoAc, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRTecoAcprivate
begin(void)IRTecoAc
calibrate(void)IRTecoAcinline
convertFan(const stdAc::fanspeed_t speed)IRTecoAc
convertMode(const stdAc::opmode_t mode)IRTecoAc
getFan(void)IRTecoAc
getHumid(void)IRTecoAc
getLight(void)IRTecoAc
getMode(void)IRTecoAc
getPower(void)IRTecoAc
getRaw(void)IRTecoAc
getSave(void)IRTecoAc
getSleep(void)IRTecoAc
getSwing(void)IRTecoAc
getTemp(void)IRTecoAc
getTimer(void)IRTecoAc
getTimerEnabled(void)IRTecoAcprivate
IRTecoAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRTecoAcexplicit
off(void)IRTecoAc
on(void)IRTecoAc
remote_stateIRTecoAcprivate
send(const uint16_t repeat=kTecoDefaultRepeat)IRTecoAc
setFan(const uint8_t fan)IRTecoAc
setHumid(const bool on)IRTecoAc
setLight(const bool on)IRTecoAc
setMode(const uint8_t mode)IRTecoAc
setPower(const bool on)IRTecoAc
setRaw(const uint64_t new_code)IRTecoAc
setSave(const bool on)IRTecoAc
setSleep(const bool on)IRTecoAc
setSwing(const bool on)IRTecoAc
setTemp(const uint8_t temp)IRTecoAc
setTimer(const uint16_t mins)IRTecoAc
stateReset(void)IRTecoAc
toCommon(void)IRTecoAc
toCommonFanSpeed(const uint8_t speed)IRTecoAcstatic
toCommonMode(const uint8_t mode)IRTecoAcstatic
toString(void)IRTecoAc
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc.html new file mode 100644 index 000000000..992922ec8 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc.html @@ -0,0 +1,1182 @@ + + + + + + + +IRremoteESP8266: IRTecoAc Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Teco A/C messages. + More...

+ +

#include <ir_Teco.h>

+
+Collaboration diagram for IRTecoAc:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRTecoAc (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset (void)
 Reset the internal state of the emulation. More...
 
void send (const uint16_t repeat=kTecoDefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Set the requested power state of the A/C to on. More...
 
void off (void)
 Set the requested power state of the A/C to off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t fan)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setSwing (const bool on)
 Set the (vertical) swing setting of the A/C. More...
 
bool getSwing (void)
 Get the (vertical) swing setting of the A/C. More...
 
void setSleep (const bool on)
 Set the Sleep setting of the A/C. More...
 
bool getSleep (void)
 Get the Sleep setting of the A/C. More...
 
void setLight (const bool on)
 Set the Light (LED/Display) setting of the A/C. More...
 
bool getLight (void)
 Get the Light (LED/Display) setting of the A/C. More...
 
void setHumid (const bool on)
 Set the Humid setting of the A/C. More...
 
bool getHumid (void)
 Get the Humid setting of the A/C. More...
 
void setSave (const bool on)
 Set the Save setting of the A/C. More...
 
bool getSave (void)
 Get the Save setting of the A/C. More...
 
uint16_t getTimer (void)
 Get the timer time for when the A/C unit will switch power state. More...
 
void setTimer (const uint16_t mins)
 Set the timer for when the A/C unit will switch power state. More...
 
uint64_t getRaw (void)
 Get a copy of the internal state/code for this protocol. More...
 
void setRaw (const uint64_t new_code)
 Set the internal state from a valid code for this protocol. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + +

+Static Public Member Functions

static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + +

+Private Member Functions

bool getTimerEnabled (void)
 Is the timer function enabled? More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint64_t remote_state
 The state of the IR remote in IR code form. More...
 
+

Detailed Description

+

Class for handling detailed Teco A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRTecoAc()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRTecoAc::IRTecoAc (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRTecoAc::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRTecoAc::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
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.
+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRTecoAc::convertFan (const stdAc::fanspeed_t speed)
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRTecoAc::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRTecoAc::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed/mode.
+ +
+
+ +

◆ getHumid()

+ +
+
+ + + + + + + + +
bool IRTecoAc::getHumid (void )
+
+ +

Get the Humid setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getLight()

+ +
+
+ + + + + + + + +
bool IRTecoAc::getLight (void )
+
+ +

Get the Light (LED/Display) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRTecoAc::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRTecoAc::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint64_t IRTecoAc::getRaw (void )
+
+ +

Get a copy of the internal state/code for this protocol.

+
Returns
A code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSave()

+ +
+
+ + + + + + + + +
bool IRTecoAc::getSave (void )
+
+ +

Get the Save setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSleep()

+ +
+
+ + + + + + + + +
bool IRTecoAc::getSleep (void )
+
+ +

Get the Sleep setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwing()

+ +
+
+ + + + + + + + +
bool IRTecoAc::getSwing (void )
+
+ +

Get the (vertical) swing setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRTecoAc::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ getTimer()

+ +
+
+ + + + + + + + +
uint16_t IRTecoAc::getTimer (void )
+
+ +

Get the timer time for when the A/C unit will switch power state.

+
Returns
The number of minutes left on the timer. 0 means off.
+ +
+
+ +

◆ getTimerEnabled()

+ +
+
+ + + + + +
+ + + + + + + + +
bool IRTecoAc::getTimerEnabled (void )
+
+private
+
+ +

Is the timer function enabled?

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRTecoAc::off (void )
+
+ +

Set the requested power state of the A/C to off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRTecoAc::on (void )
+
+ +

Set the requested power state of the A/C to on.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRTecoAc::send (const uint16_t repeat = kTecoDefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRTecoAc::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting.
+
+
+ +
+
+ +

◆ setHumid()

+ +
+
+ + + + + + + + +
void IRTecoAc::setHumid (const bool on)
+
+ +

Set the Humid setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setLight()

+ +
+
+ + + + + + + + +
void IRTecoAc::setLight (const bool on)
+
+ +

Set the Light (LED/Display) setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRTecoAc::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRTecoAc::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRTecoAc::setRaw (const uint64_t new_code)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]new_codeA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSave()

+ +
+
+ + + + + + + + +
void IRTecoAc::setSave (const bool on)
+
+ +

Set the Save setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSleep()

+ +
+
+ + + + + + + + +
void IRTecoAc::setSleep (const bool on)
+
+ +

Set the Sleep setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwing()

+ +
+
+ + + + + + + + +
void IRTecoAc::setSwing (const bool on)
+
+ +

Set the (vertical) swing setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRTecoAc::setTemp (const uint8_t temp)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]tempThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ setTimer()

+ +
+
+ + + + + + + + +
void IRTecoAc::setTimer (const uint16_t nr_mins)
+
+ +

Set the timer for when the A/C unit will switch power state.

+
Parameters
+ + +
[in]nr_minsNumber of minutes before power state change. 0 will clear the timer. Max is 24 hrs.
+
+
+
Note
Time is stored internaly in increments of 30 mins.
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRTecoAc::stateReset (void )
+
+ +

Reset the internal state of the emulation.

+
Note
Mode:auto, Power:Off, fan:auto, temp:16, swing:off, sleep:off
+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRTecoAc::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRTecoAc::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRTecoAc::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRTecoAc::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRTecoAc::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint64_t IRTecoAc::remote_state
+
+private
+
+ +

The state of the IR remote in IR code form.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc__coll__graph.map new file mode 100644 index 000000000..f3e5d1502 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc__coll__graph.md5 new file mode 100644 index 000000000..b08a20fd3 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc__coll__graph.md5 @@ -0,0 +1 @@ +70b332a49408f4e1d8c532bf7d103f45 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc__coll__graph.png new file mode 100644 index 000000000..60d06d083 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTecoAc__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC-members.html new file mode 100644 index 000000000..f54311112 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC-members.html @@ -0,0 +1,108 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRToshibaAC Member List
+
+
+ +

This is the complete list of members for IRToshibaAC, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRToshibaACprivate
begin(void)IRToshibaAC
calcChecksum(const uint8_t state[], const uint16_t length=kToshibaACStateLength)IRToshibaACprivatestatic
calibrate(void)IRToshibaACinline
checksum(const uint16_t length=kToshibaACStateLength)IRToshibaACprivate
convertFan(const stdAc::fanspeed_t speed)IRToshibaAC
convertMode(const stdAc::opmode_t mode)IRToshibaAC
getFan(void)IRToshibaAC
getMode(const bool useRaw=false)IRToshibaAC
getPower(void)IRToshibaAC
getRaw(void)IRToshibaAC
getTemp(void)IRToshibaAC
IRToshibaAC(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRToshibaACexplicit
mode_stateIRToshibaACprivate
off(void)IRToshibaAC
on(void)IRToshibaAC
remote_stateIRToshibaACprivate
send(const uint16_t repeat=kToshibaACMinRepeat)IRToshibaAC
setFan(const uint8_t speed)IRToshibaAC
setMode(const uint8_t mode)IRToshibaAC
setPower(const bool on)IRToshibaAC
setRaw(const uint8_t newState[])IRToshibaAC
setTemp(const uint8_t degrees)IRToshibaAC
stateReset(void)IRToshibaAC
toCommon(void)IRToshibaAC
toCommonFanSpeed(const uint8_t speed)IRToshibaACstatic
toCommonMode(const uint8_t mode)IRToshibaACstatic
toString(void)IRToshibaAC
validChecksum(const uint8_t state[], const uint16_t length=kToshibaACStateLength)IRToshibaACstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC.html new file mode 100644 index 000000000..285782974 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC.html @@ -0,0 +1,1001 @@ + + + + + + + +IRremoteESP8266: IRToshibaAC Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Toshiba A/C messages. + More...

+ +

#include <ir_Toshiba.h>

+
+Collaboration diagram for IRToshibaAC:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRToshibaAC (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset (void)
 Reset the state of the remote to a known good state/sequence. More...
 
void send (const uint16_t repeat=kToshibaACMinRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Set the requested power state of the A/C to on. More...
 
void off (void)
 Set the requested power state of the A/C to off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t degrees)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t speed)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (const bool useRaw=false)
 Get the operating mode setting of the A/C. More...
 
void setRaw (const uint8_t newState[])
 Set the internal state from a valid code for this protocol. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (const uint8_t state[], const uint16_t length=kToshibaACStateLength)
 Verify the checksum is valid for a given state. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + +

+Private Member Functions

void checksum (const uint16_t length=kToshibaACStateLength)
 Calculate & set the checksum for the current internal state of the remote. More...
 
+ + + + +

+Static Private Member Functions

static uint8_t calcChecksum (const uint8_t state[], const uint16_t length=kToshibaACStateLength)
 Calculate the checksum for a given state. More...
 
+ + + + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kToshibaACStateLength]
 The state in IR code form. More...
 
uint8_t mode_state
 
+

Detailed Description

+

Class for handling detailed Toshiba A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRToshibaAC()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRToshibaAC::IRToshibaAC (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRToshibaAC::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calcChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
uint8_t IRToshibaAC::calcChecksum (const uint8_t state[],
const uint16_t length = kToshibaACStateLength 
)
+
+staticprivate
+
+ +

Calculate the checksum for a given state.

+
Parameters
+ + + +
[in]stateThe array to calc the checksum of.
[in]lengthThe length/size of the array.
+
+
+
Returns
The calculated checksum value.
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRToshibaAC::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
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.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRToshibaAC::checksum (const uint16_t length = kToshibaACStateLength)
+
+private
+
+ +

Calculate & set the checksum for the current internal state of the remote.

+
Parameters
+ + +
[in]lengthThe length/size of the internal array to checksum.
+
+
+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRToshibaAC::convertFan (const stdAc::fanspeed_t speed)
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRToshibaAC::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRToshibaAC::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed/mode.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRToshibaAC::getMode (const bool useRaw = false)
+
+ +

Get the operating mode setting of the A/C.

+
Parameters
+ + +
[in]useRawIndicate to get the mode from the internal state array.
+
+
+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRToshibaAC::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRToshibaAC::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRToshibaAC::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRToshibaAC::off (void )
+
+ +

Set the requested power state of the A/C to off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRToshibaAC::on (void )
+
+ +

Set the requested power state of the A/C to on.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRToshibaAC::send (const uint16_t repeat = kToshibaACMinRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRToshibaAC::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting (0 is Auto, 1-5 is the speed, 5 is Max)
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRToshibaAC::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+
Note
If we get an unexpected mode, default to AUTO.
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRToshibaAC::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRToshibaAC::setRaw (const uint8_t newState[])
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]newStateA valid code for this protocol.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRToshibaAC::setTemp (const uint8_t degrees)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]degreesThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRToshibaAC::stateReset (void )
+
+ +

Reset the state of the remote to a known good state/sequence.

+
See also
https://github.com/r45635/HVAC-IR-Control/blob/master/HVAC_ESP8266/HVAC_ESP8266T.ino#L103
+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRToshibaAC::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRToshibaAC::toCommonFanSpeed (const uint8_t spd)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]spdThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRToshibaAC::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRToshibaAC::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRToshibaAC::validChecksum (const uint8_t state[],
const uint16_t length = kToshibaACStateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length/size of the array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRToshibaAC::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ mode_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRToshibaAC::mode_state
+
+private
+
+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRToshibaAC::remote_state[kToshibaACStateLength]
+
+private
+
+ +

The state in IR code form.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC__coll__graph.map new file mode 100644 index 000000000..483543b42 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC__coll__graph.md5 new file mode 100644 index 000000000..b4f1e5ba5 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC__coll__graph.md5 @@ -0,0 +1 @@ +c09eeaf5909d6c222783788bba05faaf \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC__coll__graph.png new file mode 100644 index 000000000..c1bfa564d Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRToshibaAC__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTrotecESP-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTrotecESP-members.html new file mode 100644 index 000000000..1319a8e35 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTrotecESP-members.html @@ -0,0 +1,111 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRTrotecESP Member List
+
+
+ +

This is the complete list of members for IRTrotecESP, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_irsendIRTrotecESPprivate
begin(void)IRTrotecESP
calcChecksum(const uint8_t state[], const uint16_t length=kTrotecStateLength)IRTrotecESPprivatestatic
calibrate(void)IRTrotecESPinline
checksum(void)IRTrotecESPprivate
convertFan(const stdAc::fanspeed_t speed)IRTrotecESP
convertMode(const stdAc::opmode_t mode)IRTrotecESP
getMode(void)IRTrotecESP
getPower(void)IRTrotecESP
getRaw(void)IRTrotecESP
getSleep(void)IRTrotecESP
getSpeed(void)IRTrotecESP
getTemp(void)IRTrotecESP
getTimer(void)IRTrotecESP
IRTrotecESP(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRTrotecESPexplicit
off(void)IRTrotecESP
on(void)IRTrotecESP
remote_stateIRTrotecESPprivate
send(const uint16_t repeat=kTrotecDefaultRepeat)IRTrotecESP
setMode(const uint8_t mode)IRTrotecESP
setPower(const bool state)IRTrotecESP
setRaw(const uint8_t state[])IRTrotecESP
setSleep(const bool on)IRTrotecESP
setSpeed(const uint8_t fan)IRTrotecESP
setTemp(const uint8_t celsius)IRTrotecESP
setTimer(const uint8_t timer)IRTrotecESP
stateReset(void)IRTrotecESP
toCommon(void)IRTrotecESP
toCommonFanSpeed(const uint8_t speed)IRTrotecESPstatic
toCommonMode(const uint8_t mode)IRTrotecESPstatic
toString(void)IRTrotecESP
validChecksum(const uint8_t state[], const uint16_t length=kTrotecStateLength)IRTrotecESPstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTrotecESP.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTrotecESP.html new file mode 100644 index 000000000..36bcf53a1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTrotecESP.html @@ -0,0 +1,1069 @@ + + + + + + + +IRremoteESP8266: IRTrotecESP Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Trotec A/C messages. + More...

+ +

#include <ir_Trotec.h>

+
+Collaboration diagram for IRTrotecESP:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRTrotecESP (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void send (const uint16_t repeat=kTrotecDefaultRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void stateReset (void)
 Reset the state of the remote to a known good state/sequence. More...
 
void on (void)
 Set the requested power state of the A/C to on. More...
 
void off (void)
 Set the requested power state of the A/C to off. More...
 
void setPower (const bool state)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setTemp (const uint8_t celsius)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setSpeed (const uint8_t fan)
 Set the speed of the fan. More...
 
uint8_t getSpeed (void)
 Get the current fan speed setting. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
bool getSleep (void)
 Get the Sleep setting of the A/C. More...
 
void setSleep (const bool on)
 Set the Sleep setting of the A/C. More...
 
uint8_t getTimer (void)
 Get the timer time in nr. of Hours. More...
 
void setTimer (const uint8_t timer)
 Set the timer time in nr. of Hours. More...
 
uint8_t * getRaw (void)
 Get a PTR to the internal state/code for this protocol. More...
 
void setRaw (const uint8_t state[])
 Set the internal state from a valid code for this protocol. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (const uint8_t state[], const uint16_t length=kTrotecStateLength)
 Verify the checksum is valid for a given state. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + +

+Private Member Functions

void checksum (void)
 Calculate & set the checksum for the current internal state of the remote. More...
 
+ + + + +

+Static Private Member Functions

static uint8_t calcChecksum (const uint8_t state[], const uint16_t length=kTrotecStateLength)
 Calculate the checksum for a given state. More...
 
+ + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kTrotecStateLength]
 Remote state in IR code form. More...
 
+

Detailed Description

+

Class for handling detailed Trotec A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRTrotecESP()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRTrotecESP::IRTrotecESP (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRTrotecESP::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calcChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
uint8_t IRTrotecESP::calcChecksum (const uint8_t state[],
const uint16_t length = kTrotecStateLength 
)
+
+staticprivate
+
+ +

Calculate the checksum for a given state.

+
Parameters
+ + + +
[in]stateThe array to calc the checksum of.
[in]lengthThe length/size of the array.
+
+
+
Returns
The calculated checksum value.
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRTrotecESP::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
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.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRTrotecESP::checksum (void )
+
+private
+
+ +

Calculate & set the checksum for the current internal state of the remote.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRTrotecESP::convertFan (const stdAc::fanspeed_t speed)
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRTrotecESP::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRTrotecESP::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRTrotecESP::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRTrotecESP::getRaw (void )
+
+ +

Get a PTR to the internal state/code for this protocol.

+
Returns
PTR to a code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSleep()

+ +
+
+ + + + + + + + +
bool IRTrotecESP::getSleep (void )
+
+ +

Get the Sleep setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSpeed()

+ +
+
+ + + + + + + + +
uint8_t IRTrotecESP::getSpeed (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed/mode.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRTrotecESP::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ getTimer()

+ +
+
+ + + + + + + + +
uint8_t IRTrotecESP::getTimer (void )
+
+ +

Get the timer time in nr. of Hours.

+
Returns
Nr. of Hours.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRTrotecESP::off (void )
+
+ +

Set the requested power state of the A/C to off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRTrotecESP::on (void )
+
+ +

Set the requested power state of the A/C to on.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRTrotecESP::send (const uint16_t repeat = kTrotecDefaultRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRTrotecESP::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRTrotecESP::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + +
void IRTrotecESP::setRaw (const uint8_t state[])
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]stateA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSleep()

+ +
+
+ + + + + + + + +
void IRTrotecESP::setSleep (const bool on)
+
+ +

Set the Sleep setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSpeed()

+ +
+
+ + + + + + + + +
void IRTrotecESP::setSpeed (const uint8_t fan)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]fanThe desired setting.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRTrotecESP::setTemp (const uint8_t celsius)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]celsiusThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ setTimer()

+ +
+
+ + + + + + + + +
void IRTrotecESP::setTimer (const uint8_t timer)
+
+ +

Set the timer time in nr. of Hours.

+
Parameters
+ + +
[in]timerNr. of Hours. Max is kTrotecMaxTimer
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRTrotecESP::stateReset (void )
+
+ +

Reset the state of the remote to a known good state/sequence.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRTrotecESP::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRTrotecESP::toCommonFanSpeed (const uint8_t spd)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]spdThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRTrotecESP::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRTrotecESP::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRTrotecESP::validChecksum (const uint8_t state[],
const uint16_t length = kTrotecStateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length/size of the array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRTrotecESP::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRTrotecESP::remote_state[kTrotecStateLength]
+
+private
+
+ +

Remote state in IR code form.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTrotecESP__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTrotecESP__coll__graph.map new file mode 100644 index 000000000..758a9b69c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTrotecESP__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTrotecESP__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTrotecESP__coll__graph.md5 new file mode 100644 index 000000000..eafdf26cf --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTrotecESP__coll__graph.md5 @@ -0,0 +1 @@ +247690158326910cfd854f7b6909ded9 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTrotecESP__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTrotecESP__coll__graph.png new file mode 100644 index 000000000..fc1d54d13 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRTrotecESP__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRVestelAc-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRVestelAc-members.html new file mode 100644 index 000000000..69ab11efc --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRVestelAc-members.html @@ -0,0 +1,136 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRVestelAc Member List
+
+
+ +

This is the complete list of members for IRVestelAc, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_getTimer(const uint8_t offset)IRVestelAcprivate
_irsendIRVestelAcprivate
_setTimer(const uint16_t minutes, const uint8_t offset)IRVestelAcprivate
begin(void)IRVestelAc
calcChecksum(const uint64_t state)IRVestelAcstatic
calibrate(void)IRVestelAcinline
checksum(void)IRVestelAcprivate
convertFan(const stdAc::fanspeed_t speed)IRVestelAcstatic
convertMode(const stdAc::opmode_t mode)IRVestelAcstatic
getFan(void)IRVestelAc
getIon(void)IRVestelAc
getMode(void)IRVestelAc
getOffTimer(void)IRVestelAc
getOnTimer(void)IRVestelAc
getPower(void)IRVestelAc
getRaw(void)IRVestelAc
getSleep(void)IRVestelAc
getSwing(void)IRVestelAc
getTemp(void)IRVestelAc
getTime(void)IRVestelAc
getTimer(void)IRVestelAc
getTurbo(void)IRVestelAc
IRVestelAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRVestelAcexplicit
isOffTimerActive(void)IRVestelAc
isOnTimerActive(void)IRVestelAc
isTimeCommand(void)IRVestelAc
isTimerActive(void)IRVestelAc
off(void)IRVestelAc
on(void)IRVestelAc
remote_stateIRVestelAcprivate
remote_time_stateIRVestelAcprivate
send(const uint16_t repeat=kNoRepeat)IRVestelAc
setAuto(const int8_t autoLevel)IRVestelAc
setFan(const uint8_t fan)IRVestelAc
setIon(const bool on)IRVestelAc
setMode(const uint8_t mode)IRVestelAc
setOffTimer(const uint16_t minutes)IRVestelAc
setOffTimerActive(const bool on)IRVestelAc
setOnTimer(const uint16_t minutes)IRVestelAc
setOnTimerActive(const bool on)IRVestelAc
setPower(const bool on)IRVestelAc
setRaw(const uint8_t *newState)IRVestelAc
setRaw(const uint64_t newState)IRVestelAc
setSleep(const bool on)IRVestelAc
setSwing(const bool on)IRVestelAc
setTemp(const uint8_t temp)IRVestelAc
setTime(const uint16_t minutes)IRVestelAc
setTimer(const uint16_t minutes)IRVestelAc
setTimerActive(const bool on)IRVestelAc
setTurbo(const bool on)IRVestelAc
stateReset(void)IRVestelAc
toCommon(void)IRVestelAc
toCommonFanSpeed(const uint8_t speed)IRVestelAcstatic
toCommonMode(const uint8_t mode)IRVestelAcstatic
toString(void)IRVestelAc
use_time_stateIRVestelAcprivate
validChecksum(const uint64_t state)IRVestelAcstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRVestelAc.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRVestelAc.html new file mode 100644 index 000000000..32ca0cf07 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRVestelAc.html @@ -0,0 +1,1758 @@ + + + + + + + +IRremoteESP8266: IRVestelAc Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Vestel A/C messages. + More...

+ +

#include <ir_Vestel.h>

+
+Collaboration diagram for IRVestelAc:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRVestelAc (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset (void)
 Reset the state of the remote to a known good state/sequence. More...
 
void send (const uint16_t repeat=kNoRepeat)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void on (void)
 Set the requested power state of the A/C to on. More...
 
void off (void)
 Set the requested power state of the A/C to off. More...
 
void setPower (const bool on)
 Change the power setting. More...
 
bool getPower (void)
 Get the value of the current power setting. More...
 
void setAuto (const int8_t autoLevel)
 Set Auto mode/level of the A/C. More...
 
void setTimer (const uint16_t minutes)
 Set Timer option of A/C. More...
 
uint16_t getTimer (void)
 Get the Timer time of A/C. More...
 
void setTime (const uint16_t minutes)
 Set the A/C's internal clock. More...
 
uint16_t getTime (void)
 Get the A/C's internal clock's time. More...
 
void setOnTimer (const uint16_t minutes)
 Set the On timer time on the A/C. More...
 
uint16_t getOnTimer (void)
 Get the A/C's On Timer time. More...
 
void setOffTimer (const uint16_t minutes)
 Set the Off timer time on the A/C. More...
 
uint16_t getOffTimer (void)
 Get the A/C's Off Timer time. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t fan)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setRaw (const uint8_t *newState)
 Set the internal state from a valid code for this protocol. More...
 
void setRaw (const uint64_t newState)
 Set the internal state from a valid code for this protocol. More...
 
uint64_t getRaw (void)
 Get a copy of the internal state/code for this protocol. More...
 
void setSwing (const bool on)
 Set the Swing Roaming setting of the A/C. More...
 
bool getSwing (void)
 Get the Swing Roaming setting of the A/C. More...
 
void setSleep (const bool on)
 Set the Sleep setting of the A/C. More...
 
bool getSleep (void)
 Get the Sleep setting of the A/C. More...
 
void setTurbo (const bool on)
 Set the Turbo setting of the A/C. More...
 
bool getTurbo (void)
 Get the Turbo setting of the A/C. More...
 
void setIon (const bool on)
 Set the Ion (Filter) setting of the A/C. More...
 
bool getIon (void)
 Get the Ion (Filter) setting of the A/C. More...
 
bool isTimeCommand (void)
 Is the current state a time command? More...
 
bool isOnTimerActive (void)
 Get if the On Timer is active on the A/C. More...
 
void setOnTimerActive (const bool on)
 Set the On timer to be active on the A/C. More...
 
bool isOffTimerActive (void)
 Get if the Off Timer is active on the A/C. More...
 
void setOffTimerActive (const bool on)
 Set the Off timer to be active on the A/C. More...
 
bool isTimerActive (void)
 Get if the Timer is active on the A/C. More...
 
void setTimerActive (const bool on)
 Set the timer to be active on the A/C. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (const uint64_t state)
 Verify the checksum is valid for a given state. More...
 
static uint8_t calcChecksum (const uint64_t state)
 Calculate the checksum for a given state. More...
 
static uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
static uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + + + + + + + +

+Private Member Functions

void checksum (void)
 Calculate & set the checksum for the current internal state of the remote. More...
 
void _setTimer (const uint16_t minutes, const uint8_t offset)
 Set a given timer time at a given bit offset. More...
 
uint16_t _getTimer (const uint8_t offset)
 Get the number of minutes a timer is set for. More...
 
+ + + + + + + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint64_t remote_state
 The state of the IR remote in IR code form. More...
 
uint64_t remote_time_state
 The time state of the remote in code form. More...
 
bool use_time_state
 
+

Detailed Description

+

Class for handling detailed Vestel A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRVestelAc()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRVestelAc::IRVestelAc (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ _getTimer()

+ +
+
+ + + + + +
+ + + + + + + + +
uint16_t IRVestelAc::_getTimer (const uint8_t offset)
+
+private
+
+ +

Get the number of minutes a timer is set for.

+
Parameters
+ + +
[in]offsetNr. of bits offset from the start of the state.
+
+
+
Returns
The time expressed in nr. of minutes.
+ +
+
+ +

◆ _setTimer()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void IRVestelAc::_setTimer (const uint16_t minutes,
const uint8_t offset 
)
+
+private
+
+ +

Set a given timer time at a given bit offset.

+
Parameters
+ + + +
[in]minutesTime in nr. of minutes.
[in]offsetNr. of bits offset from the start of the state.
+
+
+ +
+
+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRVestelAc::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calcChecksum()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRVestelAc::calcChecksum (const uint64_t state)
+
+static
+
+ +

Calculate the checksum for a given state.

+
Parameters
+ + +
[in]stateThe state to calc the checksum of.
+
+
+
Returns
The calculated checksum value.
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRVestelAc::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
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.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRVestelAc::checksum (void )
+
+private
+
+ +

Calculate & set the checksum for the current internal state of the remote.

+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRVestelAc::convertFan (const stdAc::fanspeed_t speed)
+
+static
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRVestelAc::convertMode (const stdAc::opmode_t mode)
+
+static
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRVestelAc::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed/mode.
+ +
+
+ +

◆ getIon()

+ +
+
+ + + + + + + + +
bool IRVestelAc::getIon (void )
+
+ +

Get the Ion (Filter) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRVestelAc::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getOffTimer()

+ +
+
+ + + + + + + + +
uint16_t IRVestelAc::getOffTimer (void )
+
+ +

Get the A/C's Off Timer time.

+
Returns
The time expressed in nr. of minutes.
+ +
+
+ +

◆ getOnTimer()

+ +
+
+ + + + + + + + +
uint16_t IRVestelAc::getOnTimer (void )
+
+ +

Get the A/C's On Timer time.

+
Returns
The time expressed in nr. of minutes.
+ +
+
+ +

◆ getPower()

+ +
+
+ + + + + + + + +
bool IRVestelAc::getPower (void )
+
+ +

Get the value of the current power setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint64_t IRVestelAc::getRaw (void )
+
+ +

Get a copy of the internal state/code for this protocol.

+
Returns
A code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSleep()

+ +
+
+ + + + + + + + +
bool IRVestelAc::getSleep (void )
+
+ +

Get the Sleep setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwing()

+ +
+
+ + + + + + + + +
bool IRVestelAc::getSwing (void )
+
+ +

Get the Swing Roaming setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRVestelAc::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ getTime()

+ +
+
+ + + + + + + + +
uint16_t IRVestelAc::getTime (void )
+
+ +

Get the A/C's internal clock's time.

+
Returns
The time expressed in nr. of minutes past midnight.
+ +
+
+ +

◆ getTimer()

+ +
+
+ + + + + + + + +
uint16_t IRVestelAc::getTimer (void )
+
+ +

Get the Timer time of A/C.

+
Returns
The number of minutes of time on the timer.
+ +
+
+ +

◆ getTurbo()

+ +
+
+ + + + + + + + +
bool IRVestelAc::getTurbo (void )
+
+ +

Get the Turbo setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ isOffTimerActive()

+ +
+
+ + + + + + + + +
bool IRVestelAc::isOffTimerActive (void )
+
+ +

Get if the Off Timer is active on the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ isOnTimerActive()

+ +
+
+ + + + + + + + +
bool IRVestelAc::isOnTimerActive (void )
+
+ +

Get if the On Timer is active on the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ isTimeCommand()

+ +
+
+ + + + + + + + +
bool IRVestelAc::isTimeCommand (void )
+
+ +

Is the current state a time command?

+
Returns
true, if the state is a time message. Otherwise, false.
+ +
+
+ +

◆ isTimerActive()

+ +
+
+ + + + + + + + +
bool IRVestelAc::isTimerActive (void )
+
+ +

Get if the Timer is active on the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ off()

+ +
+
+ + + + + + + + +
void IRVestelAc::off (void )
+
+ +

Set the requested power state of the A/C to off.

+ +
+
+ +

◆ on()

+ +
+
+ + + + + + + + +
void IRVestelAc::on (void )
+
+ +

Set the requested power state of the A/C to on.

+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + +
void IRVestelAc::send (const uint16_t repeat = kNoRepeat)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + +
[in]repeatNr. of times the message will be repeated.
+
+
+ +
+
+ +

◆ setAuto()

+ +
+
+ + + + + + + + +
void IRVestelAc::setAuto (const int8_t autoLevel)
+
+ +

Set Auto mode/level of the A/C.

+
Parameters
+ + +
[in]autoLevelThe auto mode/level setting.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRVestelAc::setFan (const uint8_t fan)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]fanThe desired setting.
+
+
+ +
+
+ +

◆ setIon()

+ +
+
+ + + + + + + + +
void IRVestelAc::setIon (const bool on)
+
+ +

Set the Ion (Filter) setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRVestelAc::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+
Note
If we get an unexpected mode, default to AUTO.
+ +
+
+ +

◆ setOffTimer()

+ +
+
+ + + + + + + + +
void IRVestelAc::setOffTimer (const uint16_t minutes)
+
+ +

Set the Off timer time on the A/C.

+
Parameters
+ + +
[in]minutesTime in nr. of minutes.
+
+
+ +
+
+ +

◆ setOffTimerActive()

+ +
+
+ + + + + + + + +
void IRVestelAc::setOffTimerActive (const bool on)
+
+ +

Set the Off timer to be active on the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setOnTimer()

+ +
+
+ + + + + + + + +
void IRVestelAc::setOnTimer (const uint16_t minutes)
+
+ +

Set the On timer time on the A/C.

+
Parameters
+ + +
[in]minutesTime in nr. of minutes.
+
+
+ +
+
+ +

◆ setOnTimerActive()

+ +
+
+ + + + + + + + +
void IRVestelAc::setOnTimerActive (const bool on)
+
+ +

Set the On timer to be active on the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setPower()

+ +
+
+ + + + + + + + +
void IRVestelAc::setPower (const bool on)
+
+ +

Change the power setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw() [1/2]

+ +
+
+ + + + + + + + +
void IRVestelAc::setRaw (const uint64_t newState)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]newStateA valid code for this protocol.
+
+
+ +
+
+ +

◆ setRaw() [2/2]

+ +
+
+ + + + + + + + +
void IRVestelAc::setRaw (const uint8_t * newState)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + +
[in]newStateA valid code for this protocol.
+
+
+ +
+
+ +

◆ setSleep()

+ +
+
+ + + + + + + + +
void IRVestelAc::setSleep (const bool on)
+
+ +

Set the Sleep setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwing()

+ +
+
+ + + + + + + + +
void IRVestelAc::setSwing (const bool on)
+
+ +

Set the Swing Roaming setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRVestelAc::setTemp (const uint8_t temp)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]tempThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ setTime()

+ +
+
+ + + + + + + + +
void IRVestelAc::setTime (const uint16_t minutes)
+
+ +

Set the A/C's internal clock.

+
Parameters
+ + +
[in]minutesThe time expressed in nr. of minutes past midnight.
+
+
+ +
+
+ +

◆ setTimer()

+ +
+
+ + + + + + + + +
void IRVestelAc::setTimer (const uint16_t minutes)
+
+ +

Set Timer option of A/C.

+
Parameters
+ + +
[in]minutesNr of minutes the timer is to be set for.
+
+
+
Note
Valid arguments are 0, 0.5, 1, 2, 3 and 5 hours (in minutes). 0 disables the timer.
+ +
+
+ +

◆ setTimerActive()

+ +
+
+ + + + + + + + +
void IRVestelAc::setTimerActive (const bool on)
+
+ +

Set the timer to be active on the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setTurbo()

+ +
+
+ + + + + + + + +
void IRVestelAc::setTurbo (const bool on)
+
+ +

Set the Turbo setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRVestelAc::stateReset (void )
+
+ +

Reset the state of the remote to a known good state/sequence.

+
Note
Power On, Mode Auto, Fan Auto, Temp = 25C/77F
+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRVestelAc::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRVestelAc::toCommonFanSpeed (const uint8_t spd)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]spdThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRVestelAc::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRVestelAc::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + +
bool IRVestelAc::validChecksum (const uint64_t state)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + +
[in]stateThe state to verify the checksum of.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRVestelAc::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint64_t IRVestelAc::remote_state
+
+private
+
+ +

The state of the IR remote in IR code form.

+ +
+
+ +

◆ remote_time_state

+ +
+
+ + + + + +
+ + + + +
uint64_t IRVestelAc::remote_time_state
+
+private
+
+ +

The time state of the remote in code form.

+ +
+
+ +

◆ use_time_state

+ +
+
+ + + + + +
+ + + + +
bool IRVestelAc::use_time_state
+
+private
+
+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRVestelAc__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRVestelAc__coll__graph.map new file mode 100644 index 000000000..0f380bbd5 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRVestelAc__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRVestelAc__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRVestelAc__coll__graph.md5 new file mode 100644 index 000000000..c193a6f83 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRVestelAc__coll__graph.md5 @@ -0,0 +1 @@ +f54c4cec990e7a1ff1e10a366cb92198 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRVestelAc__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRVestelAc__coll__graph.png new file mode 100644 index 000000000..5b0622536 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRVestelAc__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRWhirlpoolAc-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRWhirlpoolAc-members.html new file mode 100644 index 000000000..c07916f97 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRWhirlpoolAc-members.html @@ -0,0 +1,134 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRWhirlpoolAc Member List
+
+
+ +

This is the complete list of members for IRWhirlpoolAc, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_desiredtempIRWhirlpoolAcprivate
_irsendIRWhirlpoolAcprivate
_setMode(const uint8_t mode)IRWhirlpoolAcprivate
_setTemp(const uint8_t temp, const bool remember=true)IRWhirlpoolAcprivate
begin(void)IRWhirlpoolAc
calibrate(void)IRWhirlpoolAcinline
checksum(const uint16_t length=kWhirlpoolAcStateLength)IRWhirlpoolAcprivate
convertFan(const stdAc::fanspeed_t speed)IRWhirlpoolAc
convertMode(const stdAc::opmode_t mode)IRWhirlpoolAc
enableOffTimer(const bool on)IRWhirlpoolAc
enableOnTimer(const bool on)IRWhirlpoolAc
enableTimer(const uint16_t pos, const bool state)IRWhirlpoolAcprivate
getClock(void)IRWhirlpoolAc
getCommand(void)IRWhirlpoolAc
getFan(void)IRWhirlpoolAc
getLight(void)IRWhirlpoolAc
getMode(void)IRWhirlpoolAc
getModel(void)IRWhirlpoolAc
getOffTimer(void)IRWhirlpoolAc
getOnTimer(void)IRWhirlpoolAc
getPowerToggle(void)IRWhirlpoolAc
getRaw(const bool calcchecksum=true)IRWhirlpoolAc
getSleep(void)IRWhirlpoolAc
getSuper(void)IRWhirlpoolAc
getSwing(void)IRWhirlpoolAc
getTemp(void)IRWhirlpoolAc
getTempOffset(void)IRWhirlpoolAcprivate
getTime(const uint16_t pos)IRWhirlpoolAcprivate
IRWhirlpoolAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRWhirlpoolAcexplicit
isOffTimerEnabled(void)IRWhirlpoolAc
isOnTimerEnabled(void)IRWhirlpoolAc
isTimerEnabled(const uint16_t pos)IRWhirlpoolAcprivate
remote_stateIRWhirlpoolAcprivate
send(const uint16_t repeat=kWhirlpoolAcDefaultRepeat, const bool calcchecksum=true)IRWhirlpoolAc
setClock(const uint16_t minspastmidnight)IRWhirlpoolAc
setCommand(const uint8_t code)IRWhirlpoolAc
setFan(const uint8_t speed)IRWhirlpoolAc
setLight(const bool on)IRWhirlpoolAc
setMode(const uint8_t mode)IRWhirlpoolAc
setModel(const whirlpool_ac_remote_model_t model)IRWhirlpoolAc
setOffTimer(const uint16_t minspastmidnight)IRWhirlpoolAc
setOnTimer(const uint16_t minspastmidnight)IRWhirlpoolAc
setPowerToggle(const bool on)IRWhirlpoolAc
setRaw(const uint8_t new_code[], const uint16_t length=kWhirlpoolAcStateLength)IRWhirlpoolAc
setSleep(const bool on)IRWhirlpoolAc
setSuper(const bool on)IRWhirlpoolAc
setSwing(const bool on)IRWhirlpoolAc
setTemp(const uint8_t temp)IRWhirlpoolAc
setTime(const uint16_t pos, const uint16_t minspastmidnight)IRWhirlpoolAcprivate
stateReset(void)IRWhirlpoolAc
toCommon(void)IRWhirlpoolAc
toCommonFanSpeed(const uint8_t speed)IRWhirlpoolAcstatic
toCommonMode(const uint8_t mode)IRWhirlpoolAcstatic
toString(void)IRWhirlpoolAc
validChecksum(const uint8_t state[], const uint16_t length=kWhirlpoolAcStateLength)IRWhirlpoolAcstatic
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRWhirlpoolAc.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRWhirlpoolAc.html new file mode 100644 index 000000000..3ef4ae843 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRWhirlpoolAc.html @@ -0,0 +1,1799 @@ + + + + + + + +IRremoteESP8266: IRWhirlpoolAc Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for handling detailed Whirlpool A/C messages. + More...

+ +

#include <ir_Whirlpool.h>

+
+Collaboration diagram for IRWhirlpoolAc:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRWhirlpoolAc (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void stateReset (void)
 Reset the state of the remote to a known good state/sequence. More...
 
void send (const uint16_t repeat=kWhirlpoolAcDefaultRepeat, const bool calcchecksum=true)
 Send the current internal state as an IR message. More...
 
int8_t calibrate (void)
 Run the calibration to calculate uSec timing offsets for this platform. More...
 
void begin (void)
 Set up hardware to be able to send a message. More...
 
void setPowerToggle (const bool on)
 Change the power toggle setting. More...
 
bool getPowerToggle (void)
 Get the value of the current power toggle setting. More...
 
void setSleep (const bool on)
 Set the Sleep setting of the A/C. More...
 
bool getSleep (void)
 Get the Sleep setting of the A/C. More...
 
void setSuper (const bool on)
 Set the Super (Turbo/Jet) setting of the A/C. More...
 
bool getSuper (void)
 Get the Super (Turbo/Jet) setting of the A/C. More...
 
void setTemp (const uint8_t temp)
 Set the temperature. More...
 
uint8_t getTemp (void)
 Get the current temperature setting. More...
 
void setFan (const uint8_t speed)
 Set the speed of the fan. More...
 
uint8_t getFan (void)
 Get the current fan speed setting. More...
 
void setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
uint8_t getMode (void)
 Get the operating mode setting of the A/C. More...
 
void setSwing (const bool on)
 Set the (vertical) swing setting of the A/C. More...
 
bool getSwing (void)
 Get the (vertical) swing setting of the A/C. More...
 
void setLight (const bool on)
 Set the Light (Display/LED) setting of the A/C. More...
 
bool getLight (void)
 Get the Light (Display/LED) setting of the A/C. More...
 
uint16_t getClock (void)
 Get the clock time in nr. of minutes past midnight. More...
 
void setClock (const uint16_t minspastmidnight)
 Set the clock time in nr. of minutes past midnight. More...
 
uint16_t getOnTimer (void)
 Get the On Timer time.. More...
 
void setOnTimer (const uint16_t minspastmidnight)
 Set the On Timer time. More...
 
void enableOnTimer (const bool on)
 Enable the On Timer. More...
 
bool isOnTimerEnabled (void)
 Is the On timer enabled? More...
 
uint16_t getOffTimer (void)
 Get the Off Timer time.. More...
 
void setOffTimer (const uint16_t minspastmidnight)
 Set the Off Timer time. More...
 
void enableOffTimer (const bool on)
 Enable the Off Timer. More...
 
bool isOffTimerEnabled (void)
 Is the Off timer enabled? More...
 
void setCommand (const uint8_t code)
 Set the Command (Button) setting of the A/C. More...
 
uint8_t getCommand (void)
 Get the Command (Button) setting of the A/C. More...
 
whirlpool_ac_remote_model_t getModel (void)
 Get/Detect the model of the A/C. More...
 
void setModel (const whirlpool_ac_remote_model_t model)
 Set the model of the A/C to emulate. More...
 
uint8_t * getRaw (const bool calcchecksum=true)
 Get a copy of the internal state/code for this protocol. More...
 
void setRaw (const uint8_t new_code[], const uint16_t length=kWhirlpoolAcStateLength)
 Set the internal state from a valid code for this protocol. More...
 
uint8_t convertMode (const stdAc::opmode_t mode)
 Convert a stdAc::opmode_t enum into its native mode. More...
 
uint8_t convertFan (const stdAc::fanspeed_t speed)
 Convert a stdAc::fanspeed_t enum into it's native speed. More...
 
stdAc::state_t toCommon (void)
 Convert the current internal state into its stdAc::state_t equivilant. More...
 
String toString (void)
 Convert the current internal state into a human readable string. More...
 
+ + + + + + + + + + +

+Static Public Member Functions

static bool validChecksum (const uint8_t state[], const uint16_t length=kWhirlpoolAcStateLength)
 Verify the checksum is valid for a given state. More...
 
static stdAc::opmode_t toCommonMode (const uint8_t mode)
 Convert a native mode into its stdAc equivilant. More...
 
static stdAc::fanspeed_t toCommonFanSpeed (const uint8_t speed)
 Convert a native fan speed into its stdAc equivilant. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + +

+Private Member Functions

void checksum (const uint16_t length=kWhirlpoolAcStateLength)
 Calculate & set the checksum for the current internal state of the remote. More...
 
uint16_t getTime (const uint16_t pos)
 Get the time in nr. of minutes past midnight. More...
 
void setTime (const uint16_t pos, const uint16_t minspastmidnight)
 Set the time in nr. of minutes past midnight. More...
 
bool isTimerEnabled (const uint16_t pos)
 Is the timer enabled at the given byte offset? More...
 
void enableTimer (const uint16_t pos, const bool state)
 Enable the timer enabled at the given byte offset. More...
 
void _setTemp (const uint8_t temp, const bool remember=true)
 Set the temperature. More...
 
void _setMode (const uint8_t mode)
 Set the operating mode of the A/C. More...
 
int8_t getTempOffset (void)
 Calculate the temp. offset in deg C for the current model. More...
 
+ + + + + + + + + + +

+Private Attributes

IRsend _irsend
 Instance of the IR send class. More...
 
uint8_t remote_state [kWhirlpoolAcStateLength]
 The state in IR code form. More...
 
uint8_t _desiredtemp
 The last user explicitly set temperature. More...
 
+

Detailed Description

+

Class for handling detailed Whirlpool A/C messages.

+

Constructor & Destructor Documentation

+ +

◆ IRWhirlpoolAc()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRWhirlpoolAc::IRWhirlpoolAc (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGPIO to be used when sending.
[in]invertedIs the output signal to be inverted?
[in]use_modulationIs frequency modulation to be used?
+
+
+ +
+
+

Member Function Documentation

+ +

◆ _setMode()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRWhirlpoolAc::_setMode (const uint8_t mode)
+
+private
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+
Note
Internal use only.
+ +
+
+ +

◆ _setTemp()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void IRWhirlpoolAc::_setTemp (const uint8_t temp,
const bool remember = true 
)
+
+private
+
+ +

Set the temperature.

+
Parameters
+ + + +
[in]tempThe temperature in degrees celsius.
[in]rememberDo we save this temperature?
+
+
+
Note
Internal use only.
+ +
+
+ +

◆ begin()

+ +
+
+ + + + + + + + +
void IRWhirlpoolAc::begin (void )
+
+ +

Set up hardware to be able to send a message.

+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRWhirlpoolAc::calibrate (void )
+
+inline
+
+ +

Run the calibration to calculate uSec timing offsets for this platform.

+
Returns
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.
+ +
+
+ +

◆ checksum()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRWhirlpoolAc::checksum (const uint16_t length = kWhirlpoolAcStateLength)
+
+private
+
+ +

Calculate & set the checksum for the current internal state of the remote.

+
Parameters
+ + +
[in]lengthThe length/size of the internal state array.
+
+
+ +
+
+ +

◆ convertFan()

+ +
+
+ + + + + + + + +
uint8_t IRWhirlpoolAc::convertFan (const stdAc::fanspeed_t speed)
+
+ +

Convert a stdAc::fanspeed_t enum into it's native speed.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ convertMode()

+ +
+
+ + + + + + + + +
uint8_t IRWhirlpoolAc::convertMode (const stdAc::opmode_t mode)
+
+ +

Convert a stdAc::opmode_t enum into its native mode.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The native equivilant of the enum.
+ +
+
+ +

◆ enableOffTimer()

+ +
+
+ + + + + + + + +
void IRWhirlpoolAc::enableOffTimer (const bool on)
+
+ +

Enable the Off Timer.

+
Parameters
+ + +
[in]ontrue, the timer is enabled. false, the timer is disabled.
+
+
+ +
+
+ +

◆ enableOnTimer()

+ +
+
+ + + + + + + + +
void IRWhirlpoolAc::enableOnTimer (const bool on)
+
+ +

Enable the On Timer.

+
Parameters
+ + +
[in]ontrue, the timer is enabled. false, the timer is disabled.
+
+
+ +
+
+ +

◆ enableTimer()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void IRWhirlpoolAc::enableTimer (const uint16_t pos,
const bool on 
)
+
+private
+
+ +

Enable the timer enabled at the given byte offset.

+
Parameters
+ + + +
[in]posThe byte offset to write to.
[in]ontrue, the timer is enabled. false, the timer is disabled.
+
+
+ +
+
+ +

◆ getClock()

+ +
+
+ + + + + + + + +
uint16_t IRWhirlpoolAc::getClock (void )
+
+ +

Get the clock time in nr. of minutes past midnight.

+
Returns
The time expressed as the Nr. of minutes past midnight.
+ +
+
+ +

◆ getCommand()

+ +
+
+ + + + + + + + +
uint8_t IRWhirlpoolAc::getCommand (void )
+
+ +

Get the Command (Button) setting of the A/C.

+
Returns
The current Command (Button) of the A/C.
+ +
+
+ +

◆ getFan()

+ +
+
+ + + + + + + + +
uint8_t IRWhirlpoolAc::getFan (void )
+
+ +

Get the current fan speed setting.

+
Returns
The current fan speed/mode.
+ +
+
+ +

◆ getLight()

+ +
+
+ + + + + + + + +
bool IRWhirlpoolAc::getLight (void )
+
+ +

Get the Light (Display/LED) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getMode()

+ +
+
+ + + + + + + + +
uint8_t IRWhirlpoolAc::getMode (void )
+
+ +

Get the operating mode setting of the A/C.

+
Returns
The current operating mode setting.
+ +
+
+ +

◆ getModel()

+ +
+
+ + + + + + + + +
whirlpool_ac_remote_model_t IRWhirlpoolAc::getModel (void )
+
+ +

Get/Detect the model of the A/C.

+
Returns
The enum of the compatible model.
+ +
+
+ +

◆ getOffTimer()

+ +
+
+ + + + + + + + +
uint16_t IRWhirlpoolAc::getOffTimer (void )
+
+ +

Get the Off Timer time..

+
Returns
The time expressed as the Nr. of minutes past midnight.
+ +
+
+ +

◆ getOnTimer()

+ +
+
+ + + + + + + + +
uint16_t IRWhirlpoolAc::getOnTimer (void )
+
+ +

Get the On Timer time..

+
Returns
The time expressed as the Nr. of minutes past midnight.
+ +
+
+ +

◆ getPowerToggle()

+ +
+
+ + + + + + + + +
bool IRWhirlpoolAc::getPowerToggle (void )
+
+ +

Get the value of the current power toggle setting.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getRaw()

+ +
+
+ + + + + + + + +
uint8_t * IRWhirlpoolAc::getRaw (const bool calcchecksum = true)
+
+ +

Get a copy of the internal state/code for this protocol.

+
Parameters
+ + +
[in]calcchecksumDo we need to calculate the checksum?.
+
+
+
Returns
A code for this protocol based on the current internal state.
+ +
+
+ +

◆ getSleep()

+ +
+
+ + + + + + + + +
bool IRWhirlpoolAc::getSleep (void )
+
+ +

Get the Sleep setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSuper()

+ +
+
+ + + + + + + + +
bool IRWhirlpoolAc::getSuper (void )
+
+ +

Get the Super (Turbo/Jet) setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getSwing()

+ +
+
+ + + + + + + + +
bool IRWhirlpoolAc::getSwing (void )
+
+ +

Get the (vertical) swing setting of the A/C.

+
Returns
true, the setting is on. false, the setting is off.
+ +
+
+ +

◆ getTemp()

+ +
+
+ + + + + + + + +
uint8_t IRWhirlpoolAc::getTemp (void )
+
+ +

Get the current temperature setting.

+
Returns
The current setting for temp. in degrees celsius.
+ +
+
+ +

◆ getTempOffset()

+ +
+
+ + + + + +
+ + + + + + + + +
int8_t IRWhirlpoolAc::getTempOffset (void )
+
+private
+
+ +

Calculate the temp. offset in deg C for the current model.

+
Returns
The temperature offset.
+ +
+
+ +

◆ getTime()

+ +
+
+ + + + + +
+ + + + + + + + +
uint16_t IRWhirlpoolAc::getTime (const uint16_t pos)
+
+private
+
+ +

Get the time in nr. of minutes past midnight.

+
Parameters
+ + +
[in]posThe byte offset to read from.
+
+
+
Returns
The time in Nr. of minutes past midnight.
+ +
+
+ +

◆ isOffTimerEnabled()

+ +
+
+ + + + + + + + +
bool IRWhirlpoolAc::isOffTimerEnabled (void )
+
+ +

Is the Off timer enabled?

+
Returns
true, the Timer is enabled. false, the Timer is disabled.
+ +
+
+ +

◆ isOnTimerEnabled()

+ +
+
+ + + + + + + + +
bool IRWhirlpoolAc::isOnTimerEnabled (void )
+
+ +

Is the On timer enabled?

+
Returns
true, the Timer is enabled. false, the Timer is disabled.
+ +
+
+ +

◆ isTimerEnabled()

+ +
+
+ + + + + +
+ + + + + + + + +
bool IRWhirlpoolAc::isTimerEnabled (const uint16_t pos)
+
+private
+
+ +

Is the timer enabled at the given byte offset?

+
Parameters
+ + +
[in]posThe byte offset to read from.
+
+
+
Returns
true, the Timer is on. false, the Timer is off.
+ +
+
+ +

◆ send()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRWhirlpoolAc::send (const uint16_t repeat = kWhirlpoolAcDefaultRepeat,
const bool calcchecksum = true 
)
+
+ +

Send the current internal state as an IR message.

+
Parameters
+ + + +
[in]repeatNr. of times the message will be repeated.
[in]calcchecksumDo we need to calculate the checksum?.
+
+
+ +
+
+ +

◆ setClock()

+ +
+
+ + + + + + + + +
void IRWhirlpoolAc::setClock (const uint16_t minspastmidnight)
+
+ +

Set the clock time in nr. of minutes past midnight.

+
Parameters
+ + +
[in]minspastmidnightThe time expressed as minutes past midnight.
+
+
+ +
+
+ +

◆ setCommand()

+ +
+
+ + + + + + + + +
void IRWhirlpoolAc::setCommand (const uint8_t code)
+
+ +

Set the Command (Button) setting of the A/C.

+
Parameters
+ + +
[in]codeThe current Command (Button) of the A/C.
+
+
+ +
+
+ +

◆ setFan()

+ +
+
+ + + + + + + + +
void IRWhirlpoolAc::setFan (const uint8_t speed)
+
+ +

Set the speed of the fan.

+
Parameters
+ + +
[in]speedThe desired setting.
+
+
+ +
+
+ +

◆ setLight()

+ +
+
+ + + + + + + + +
void IRWhirlpoolAc::setLight (const bool on)
+
+ +

Set the Light (Display/LED) setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setMode()

+ +
+
+ + + + + + + + +
void IRWhirlpoolAc::setMode (const uint8_t mode)
+
+ +

Set the operating mode of the A/C.

+
Parameters
+ + +
[in]modeThe desired operating mode.
+
+
+ +
+
+ +

◆ setModel()

+ +
+
+ + + + + + + + +
void IRWhirlpoolAc::setModel (const whirlpool_ac_remote_model_t model)
+
+ +

Set the model of the A/C to emulate.

+
Parameters
+ + +
[in]modelThe enum of the appropriate model.
+
+
+ +
+
+ +

◆ setOffTimer()

+ +
+
+ + + + + + + + +
void IRWhirlpoolAc::setOffTimer (const uint16_t minspastmidnight)
+
+ +

Set the Off Timer time.

+
Parameters
+ + +
[in]minspastmidnightThe time expressed as minutes past midnight.
+
+
+ +
+
+ +

◆ setOnTimer()

+ +
+
+ + + + + + + + +
void IRWhirlpoolAc::setOnTimer (const uint16_t minspastmidnight)
+
+ +

Set the On Timer time.

+
Parameters
+ + +
[in]minspastmidnightThe time expressed as minutes past midnight.
+
+
+ +
+
+ +

◆ setPowerToggle()

+ +
+
+ + + + + + + + +
void IRWhirlpoolAc::setPowerToggle (const bool on)
+
+ +

Change the power toggle setting.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setRaw()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRWhirlpoolAc::setRaw (const uint8_t new_code[],
const uint16_t length = kWhirlpoolAcStateLength 
)
+
+ +

Set the internal state from a valid code for this protocol.

+
Parameters
+ + + +
[in]new_codeA valid code for this protocol.
[in]lengthThe length/size of the new_code array.
+
+
+ +
+
+ +

◆ setSleep()

+ +
+
+ + + + + + + + +
void IRWhirlpoolAc::setSleep (const bool on)
+
+ +

Set the Sleep setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSuper()

+ +
+
+ + + + + + + + +
void IRWhirlpoolAc::setSuper (const bool on)
+
+ +

Set the Super (Turbo/Jet) setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setSwing()

+ +
+
+ + + + + + + + +
void IRWhirlpoolAc::setSwing (const bool on)
+
+ +

Set the (vertical) swing setting of the A/C.

+
Parameters
+ + +
[in]ontrue, the setting is on. false, the setting is off.
+
+
+ +
+
+ +

◆ setTemp()

+ +
+
+ + + + + + + + +
void IRWhirlpoolAc::setTemp (const uint8_t temp)
+
+ +

Set the temperature.

+
Parameters
+ + +
[in]tempThe temperature in degrees celsius.
+
+
+ +
+
+ +

◆ setTime()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void IRWhirlpoolAc::setTime (const uint16_t pos,
const uint16_t minspastmidnight 
)
+
+private
+
+ +

Set the time in nr. of minutes past midnight.

+
Parameters
+ + + +
[in]posThe byte offset to write to.
[in]minspastmidnightNr. of minutes past midnight.
+
+
+ +
+
+ +

◆ stateReset()

+ +
+
+ + + + + + + + +
void IRWhirlpoolAc::stateReset (void )
+
+ +

Reset the state of the remote to a known good state/sequence.

+ +
+
+ +

◆ toCommon()

+ +
+
+ + + + + + + + +
stdAc::state_t IRWhirlpoolAc::toCommon (void )
+
+ +

Convert the current internal state into its stdAc::state_t equivilant.

+
Returns
The stdAc equivilant of the native settings.
+ +
+
+ +

◆ toCommonFanSpeed()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::fanspeed_t IRWhirlpoolAc::toCommonFanSpeed (const uint8_t speed)
+
+static
+
+ +

Convert a native fan speed into its stdAc equivilant.

+
Parameters
+ + +
[in]speedThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toCommonMode()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::opmode_t IRWhirlpoolAc::toCommonMode (const uint8_t mode)
+
+static
+
+ +

Convert a native mode into its stdAc equivilant.

+
Parameters
+ + +
[in]modeThe native setting to be converted.
+
+
+
Returns
The stdAc equivilant of the native setting.
+ +
+
+ +

◆ toString()

+ +
+
+ + + + + + + + +
String IRWhirlpoolAc::toString (void )
+
+ +

Convert the current internal state into a human readable string.

+
Returns
A human readable string.
+ +
+
+ +

◆ validChecksum()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRWhirlpoolAc::validChecksum (const uint8_t state[],
const uint16_t length = kWhirlpoolAcStateLength 
)
+
+static
+
+ +

Verify the checksum is valid for a given state.

+
Parameters
+ + + +
[in]stateThe array to verify the checksum of.
[in]lengthThe length/size of the array.
+
+
+
Returns
true, if the state has a valid checksum. Otherwise, false.
+ +
+
+

Member Data Documentation

+ +

◆ _desiredtemp

+ +
+
+ + + + + +
+ + + + +
uint8_t IRWhirlpoolAc::_desiredtemp
+
+private
+
+ +

The last user explicitly set temperature.

+ +
+
+ +

◆ _irsend

+ +
+
+ + + + + +
+ + + + +
IRsend IRWhirlpoolAc::_irsend
+
+private
+
+ +

Instance of the IR send class.

+ +
+
+ +

◆ remote_state

+ +
+
+ + + + + +
+ + + + +
uint8_t IRWhirlpoolAc::remote_state[kWhirlpoolAcStateLength]
+
+private
+
+ +

The state in IR code form.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRWhirlpoolAc__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRWhirlpoolAc__coll__graph.map new file mode 100644 index 000000000..8fbbe1e23 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRWhirlpoolAc__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRWhirlpoolAc__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRWhirlpoolAc__coll__graph.md5 new file mode 100644 index 000000000..2bd14cbec --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRWhirlpoolAc__coll__graph.md5 @@ -0,0 +1 @@ +67506f3229bc12f62882dd42ed993175 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRWhirlpoolAc__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRWhirlpoolAc__coll__graph.png new file mode 100644 index 000000000..08f433442 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRWhirlpoolAc__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac-members.html new file mode 100644 index 000000000..c9e1b88a1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac-members.html @@ -0,0 +1,151 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRac Member List
+
+
+ +

This is the complete list of members for IRac, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_invertedIRacprivate
_modulationIRacprivate
_pinIRacprivate
_prevIRacprivate
amcor(IRAmcorAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan)IRacprivate
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)IRacprivate
boolToString(const bool value)IRacstatic
carrier64(IRCarrierAc64 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const int16_t sleep=-1)IRacprivate
cleanState(const stdAc::state_t state)IRacprivatestatic
cmpStates(const stdAc::state_t a, const stdAc::state_t b)IRacstatic
coolix(IRCoolixAC *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 light, const bool clean, const int16_t sleep=-1)IRacprivate
corona(IRCoronaAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool econo)IRacprivate
daikin(IRDaikinESP *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool econo, const bool clean)IRacprivate
daikin128(IRDaikin128 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool quiet, const bool turbo, const bool light, const bool econo, const int16_t sleep=-1, const int16_t clock=-1)IRacprivate
daikin152(IRDaikin152 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool quiet, const bool turbo, const bool econo)IRacprivate
daikin160(IRDaikin160 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv)IRacprivate
daikin176(IRDaikin176 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingh_t swingh)IRacprivate
daikin2(IRDaikin2 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool light, const bool econo, const bool filter, const bool clean, const bool beep, const int16_t sleep=-1, const int16_t clock=-1)IRacprivate
daikin216(IRDaikin216 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo)IRacprivate
daikin64(IRDaikin64 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool quiet, const bool turbo, const int16_t sleep=-1, const int16_t clock=-1)IRacprivate
delonghiac(IRDelonghiAc *ac, const bool on, const stdAc::opmode_t mode, const bool celsius, const float degrees, const stdAc::fanspeed_t fan, const bool turbo, const int16_t sleep=-1)IRacprivate
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)IRacprivate
fanspeedToString(const stdAc::fanspeed_t speed)IRacstatic
fujitsu(IRFujitsuAC *ac, const fujitsu_ac_remote_model_t model, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool econo, const bool filter, const bool clean)IRacprivate
getState(void)IRac
getStatePrev(void)IRac
goodweather(IRGoodweatherAc *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 bool light, const int16_t sleep=-1)IRacprivate
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 bool turbo, const bool light, const bool clean, const int16_t sleep=-1)IRacprivate
haier(IRHaierAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool filter, const int16_t sleep=-1, const int16_t clock=-1)IRacprivate
haierYrwo2(IRHaierACYRW02 *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 bool filter, const int16_t sleep=-1)IRacprivate
handleToggles(const stdAc::state_t desired, const stdAc::state_t *prev=NULL)IRacprivatestatic
hasStateChanged(void)IRac
hitachi(IRHitachiAc *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)IRacprivate
hitachi1(IRHitachiAc1 *ac, const hitachi_ac1_remote_model_t model, const bool on, const bool power_toggle, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool swing_toggle, const int16_t sleep=-1)IRacprivate
hitachi344(IRHitachiAc344 *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)IRacprivate
hitachi424(IRHitachiAc424 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv)IRacprivate
initState(stdAc::state_t *state, const decode_type_t vendor, const int16_t model, const bool power, const stdAc::opmode_t mode, const float degrees, const bool celsius, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool econo, const bool light, const bool filter, const bool clean, const bool beep, const int16_t sleep, const int16_t clock)IRacstatic
initState(stdAc::state_t *state)IRacstatic
IRac(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)IRacexplicit
isProtocolSupported(const decode_type_t protocol)IRacstatic
kelvinator(IRKelvinatorAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool light, const bool filter, const bool clean)IRacprivate
lg(IRLgAc *ac, const lg_ac_remote_model_t model, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan)IRacprivate
markAsSent(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 int16_t sleep=-1)IRacprivate
mitsubishi(IRMitsubishiAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const int16_t clock=-1)IRacprivate
mitsubishi112(IRMitsubishi112 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet)IRacprivate
mitsubishi136(IRMitsubishi136 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool quiet)IRacprivate
mitsubishiHeavy152(IRMitsubishiHeavy152Ac *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool econo, const bool filter, const bool clean, const int16_t sleep=-1)IRacprivate
mitsubishiHeavy88(IRMitsubishiHeavy88Ac *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 econo, const bool clean)IRacprivate
neoclima(IRNeoclimaAc *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 light, const bool filter, const int16_t sleep=-1)IRacprivate
nextIRac
opmodeToString(const stdAc::opmode_t mode)IRacstatic
panasonic(IRPanasonicAc *ac, const panasonic_ac_remote_model_t model, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool filter, const int16_t clock=-1)IRacprivate
samsung(IRSamsungAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool quiet, const bool turbo, const bool light, const bool filter, const bool clean, const bool beep, const bool prevpower=true, const bool forcepower=true)IRacprivate
sendAc(void)IRac
sendAc(const stdAc::state_t desired, const stdAc::state_t *prev=NULL)IRac
sendAc(const decode_type_t vendor, const int16_t model, const bool power, const stdAc::opmode_t mode, const float degrees, const bool celsius, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool econo, const bool light, const bool filter, const bool clean, const bool beep, const int16_t sleep=-1, const int16_t clock=-1)IRac
sharp(IRSharpAc *ac, const bool on, const bool prev_power, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool turbo, const bool filter, const bool clean)IRacprivate
strToBool(const char *str, const bool def=false)IRacstatic
strToFanspeed(const char *str, const stdAc::fanspeed_t def=stdAc::fanspeed_t::kAuto)IRacstatic
strToModel(const char *str, const int16_t def=-1)IRacstatic
strToOpmode(const char *str, const stdAc::opmode_t def=stdAc::opmode_t::kAuto)IRacstatic
strToSwingH(const char *str, const stdAc::swingh_t def=stdAc::swingh_t::kOff)IRacstatic
strToSwingV(const char *str, const stdAc::swingv_t def=stdAc::swingv_t::kOff)IRacstatic
swinghToString(const stdAc::swingh_t swingh)IRacstatic
swingvToString(const stdAc::swingv_t swingv)IRacstatic
tcl112(IRTcl112Ac *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 light, const bool econo, const bool filter)IRacprivate
teco(IRTecoAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool light, const int16_t sleep=-1)IRacprivate
toshiba(IRToshibaAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan)IRacprivate
trotec(IRTrotecESP *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const int16_t sleep=-1)IRacprivate
vestel(IRVestelAc *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 bool filter, const int16_t sleep=-1, const int16_t clock=-1, const bool sendNormal=true)IRacprivate
whirlpool(IRWhirlpoolAc *ac, const whirlpool_ac_remote_model_t model, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool turbo, const bool light, const int16_t sleep=-1, const int16_t clock=-1)IRacprivate
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac.html new file mode 100644 index 000000000..8c0bb6274 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac.html @@ -0,0 +1,5644 @@ + + + + + + + +IRremoteESP8266: IRac Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

#include <IRac.h>

+
+Collaboration diagram for IRac:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRac (const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
 Class constructor. More...
 
void markAsSent (void)
 Update the previous state to the current one. More...
 
bool sendAc (void)
 Send an A/C message based soley on our internal state. More...
 
bool sendAc (const stdAc::state_t desired, const stdAc::state_t *prev=NULL)
 Send A/C message for a given device using state_t structures. More...
 
bool sendAc (const decode_type_t vendor, const int16_t model, const bool power, const stdAc::opmode_t mode, const float degrees, const bool celsius, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool econo, const bool light, const bool filter, const bool clean, const bool beep, const int16_t sleep=-1, const int16_t clock=-1)
 Send A/C message for a given device using common A/C settings. More...
 
stdAc::state_t getState (void)
 Get the current internal A/C climate state. More...
 
stdAc::state_t getStatePrev (void)
 Get the previous internal A/C climate state that should have already been sent to the device. i.e. What the A/C unit should already be set to. More...
 
bool hasStateChanged (void)
 Check if the internal state has changed from what was previously sent. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Static Public Member Functions

static bool isProtocolSupported (const decode_type_t protocol)
 Is the given protocol supported by the IRac class? More...
 
static void initState (stdAc::state_t *state, const decode_type_t vendor, const int16_t model, const bool power, const stdAc::opmode_t mode, const float degrees, const bool celsius, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool econo, const bool light, const bool filter, const bool clean, const bool beep, const int16_t sleep, const int16_t clock)
 Initialse the given state with the supplied settings. More...
 
static void initState (stdAc::state_t *state)
 Initialse the given state with the supplied settings. More...
 
static bool cmpStates (const stdAc::state_t a, const stdAc::state_t b)
 Compare two AirCon states. More...
 
static bool strToBool (const char *str, const bool def=false)
 Convert the supplied str into the appropriate boolean value. More...
 
static int16_t strToModel (const char *str, const int16_t def=-1)
 Convert the supplied str into the appropriate enum. More...
 
static stdAc::opmode_t strToOpmode (const char *str, const stdAc::opmode_t def=stdAc::opmode_t::kAuto)
 Convert the supplied str into the appropriate enum. More...
 
static stdAc::fanspeed_t strToFanspeed (const char *str, const stdAc::fanspeed_t def=stdAc::fanspeed_t::kAuto)
 Convert the supplied str into the appropriate enum. More...
 
static stdAc::swingv_t strToSwingV (const char *str, const stdAc::swingv_t def=stdAc::swingv_t::kOff)
 Convert the supplied str into the appropriate enum. More...
 
static stdAc::swingh_t strToSwingH (const char *str, const stdAc::swingh_t def=stdAc::swingh_t::kOff)
 Convert the supplied str into the appropriate enum. More...
 
static String boolToString (const bool value)
 Convert the supplied boolean into the appropriate String. More...
 
static String opmodeToString (const stdAc::opmode_t mode)
 Convert the supplied operation mode into the appropriate String. More...
 
static String fanspeedToString (const stdAc::fanspeed_t speed)
 Convert the supplied fan speed enum into the appropriate String. More...
 
static String swingvToString (const stdAc::swingv_t swingv)
 Convert the supplied enum into the appropriate String. More...
 
static String swinghToString (const stdAc::swingh_t swingh)
 Convert the supplied enum into the appropriate String. More...
 
+ + + + +

+Public Attributes

stdAc::state_t next
 The state we want the device to be in after we send. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Private Member Functions

void amcor (IRAmcorAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan)
 Send an Amcor A/C message with the supplied settings. More...
 
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)
 Send an Argo A/C message with the supplied settings. More...
 
void carrier64 (IRCarrierAc64 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const int16_t sleep=-1)
 Send a Carrier 64-bit A/C message with the supplied settings. More...
 
void coolix (IRCoolixAC *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 light, const bool clean, const int16_t sleep=-1)
 Send a Coolix A/C message with the supplied settings. More...
 
void corona (IRCoronaAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool econo)
 Send a Corona A/C message with the supplied settings. More...
 
void daikin (IRDaikinESP *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool econo, const bool clean)
 Send a Daikin A/C message with the supplied settings. More...
 
void daikin128 (IRDaikin128 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool quiet, const bool turbo, const bool light, const bool econo, const int16_t sleep=-1, const int16_t clock=-1)
 Send a Daikin 128-bit A/C message with the supplied settings. More...
 
void daikin152 (IRDaikin152 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool quiet, const bool turbo, const bool econo)
 Send a Daikin 152-bit A/C message with the supplied settings. More...
 
void daikin160 (IRDaikin160 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv)
 Send a Daikin 160-bit A/C message with the supplied settings. More...
 
void daikin176 (IRDaikin176 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingh_t swingh)
 Send a Daikin 176-bit A/C message with the supplied settings. More...
 
void daikin2 (IRDaikin2 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool light, const bool econo, const bool filter, const bool clean, const bool beep, const int16_t sleep=-1, const int16_t clock=-1)
 Send a Daikin2 A/C message with the supplied settings. More...
 
void daikin216 (IRDaikin216 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo)
 Send a Daikin 216-bit A/C message with the supplied settings. More...
 
void daikin64 (IRDaikin64 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool quiet, const bool turbo, const int16_t sleep=-1, const int16_t clock=-1)
 Send a Daikin 64-bit A/C message with the supplied settings. More...
 
void delonghiac (IRDelonghiAc *ac, const bool on, const stdAc::opmode_t mode, const bool celsius, const float degrees, const stdAc::fanspeed_t fan, const bool turbo, const int16_t sleep=-1)
 Send a Delonghi A/C message with the supplied settings. More...
 
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 bool lighttoggle, const bool clean)
 Send an Electra A/C message with the supplied settings. More...
 
void fujitsu (IRFujitsuAC *ac, const fujitsu_ac_remote_model_t model, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool econo, const bool filter, const bool clean)
 Send a Fujitsu A/C message with the supplied settings. More...
 
void goodweather (IRGoodweatherAc *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 bool light, const int16_t sleep=-1)
 Send a Goodweather A/C message with the supplied settings. More...
 
void 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 bool turbo, const bool light, const bool clean, const int16_t sleep=-1)
 Send a Gree A/C message with the supplied settings. More...
 
void haier (IRHaierAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool filter, const int16_t sleep=-1, const int16_t clock=-1)
 Send a Haier A/C message with the supplied settings. More...
 
void haierYrwo2 (IRHaierACYRW02 *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 bool filter, const int16_t sleep=-1)
 Send a Haier YRWO2 A/C message with the supplied settings. More...
 
void hitachi (IRHitachiAc *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)
 Send a Hitachi A/C message with the supplied settings. More...
 
void hitachi1 (IRHitachiAc1 *ac, const hitachi_ac1_remote_model_t model, const bool on, const bool power_toggle, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool swing_toggle, const int16_t sleep=-1)
 Send a Hitachi1 A/C message with the supplied settings. More...
 
void hitachi344 (IRHitachiAc344 *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)
 Send a Hitachi 344-bit A/C message with the supplied settings. More...
 
void hitachi424 (IRHitachiAc424 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv)
 Send a Hitachi 424-bit A/C message with the supplied settings. More...
 
void kelvinator (IRKelvinatorAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool light, const bool filter, const bool clean)
 Send a Kelvinator A/C message with the supplied settings. More...
 
void lg (IRLgAc *ac, const lg_ac_remote_model_t model, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan)
 Send a LG A/C message with the supplied settings. More...
 
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 int16_t sleep=-1)
 Send a Midea A/C message with the supplied settings. More...
 
void mitsubishi (IRMitsubishiAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const int16_t clock=-1)
 Send a Mitsubishi A/C message with the supplied settings. More...
 
void mitsubishi112 (IRMitsubishi112 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet)
 Send a Mitsubishi 112-bit A/C message with the supplied settings. More...
 
void mitsubishi136 (IRMitsubishi136 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool quiet)
 Send a Mitsubishi 136-bit A/C message with the supplied settings. More...
 
void mitsubishiHeavy88 (IRMitsubishiHeavy88Ac *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 econo, const bool clean)
 Send a Mitsubishi Heavy 88-bit A/C message with the supplied settings. More...
 
void mitsubishiHeavy152 (IRMitsubishiHeavy152Ac *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool econo, const bool filter, const bool clean, const int16_t sleep=-1)
 Send a Mitsubishi Heavy 152-bit A/C message with the supplied settings. More...
 
void neoclima (IRNeoclimaAc *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 light, const bool filter, const int16_t sleep=-1)
 Send a Neoclima A/C message with the supplied settings. More...
 
void panasonic (IRPanasonicAc *ac, const panasonic_ac_remote_model_t model, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool filter, const int16_t clock=-1)
 Send a Panasonic A/C message with the supplied settings. More...
 
void samsung (IRSamsungAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool quiet, const bool turbo, const bool light, const bool filter, const bool clean, const bool beep, const bool prevpower=true, const bool forcepower=true)
 Send a Samsung A/C message with the supplied settings. More...
 
void sharp (IRSharpAc *ac, const bool on, const bool prev_power, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool turbo, const bool filter, const bool clean)
 Send a Sharp A/C message with the supplied settings. More...
 
void tcl112 (IRTcl112Ac *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 light, const bool econo, const bool filter)
 Send a TCL 112-bit A/C message with the supplied settings. More...
 
void teco (IRTecoAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool light, const int16_t sleep=-1)
 Send a Teco A/C message with the supplied settings. More...
 
void toshiba (IRToshibaAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan)
 Send a Toshiba A/C message with the supplied settings. More...
 
void trotec (IRTrotecESP *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const int16_t sleep=-1)
 Send a Trotec A/C message with the supplied settings. More...
 
void vestel (IRVestelAc *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 bool filter, const int16_t sleep=-1, const int16_t clock=-1, const bool sendNormal=true)
 Send a Vestel A/C message with the supplied settings. More...
 
void whirlpool (IRWhirlpoolAc *ac, const whirlpool_ac_remote_model_t model, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool turbo, const bool light, const int16_t sleep=-1, const int16_t clock=-1)
 Send a Whirlpool A/C message with the supplied settings. More...
 
+ + + + + + + +

+Static Private Member Functions

static stdAc::state_t cleanState (const stdAc::state_t state)
 Create a new state base on the provided state that has been suitably fixed. More...
 
static stdAc::state_t handleToggles (const stdAc::state_t desired, const stdAc::state_t *prev=NULL)
 Create a new state base on desired & previous states but handle any state changes for options that need to be toggled. More...
 
+ + + + + + + + + +

+Private Attributes

uint16_t _pin
 
bool _inverted
 
bool _modulation
 
stdAc::state_t _prev
 
+

Constructor & Destructor Documentation

+ +

◆ IRac()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRac::IRac (const uint16_t pin,
const bool inverted = false,
const bool use_modulation = true 
)
+
+explicit
+
+ +

Class constructor.

+
Parameters
+ + + + +
[in]pinGpio pin to use when transmitting IR messages.
[in]invertedtrue, gpio output defaults to high. false, to low.
[in]use_modulationtrue means use frequency modulation. false, don't.
+
+
+ +
+
+

Member Function Documentation

+ +

◆ amcor()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::amcor (IRAmcorAcac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan 
)
+
+private
+
+ +

Send an Amcor A/C message with the supplied settings.

+
Parameters
+ + + + + + +
[in,out]acA Ptr to an IRAmcorAc object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
+
+
+ +
+
+ +

◆ argo()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::argo (IRArgoACac,
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 
)
+
+private
+
+ +

Send an Argo A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + +
[in,out]acA Ptr to an IRArgoAC object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]turboRun the device in turbo/powerful mode.
[in]sleepNr. of minutes for sleep mode.
+
+
+
Note
-1 is Off, >= 0 is on.
+ +
+
+ +

◆ boolToString()

+ +
+
+ + + + + +
+ + + + + + + + +
String IRac::boolToString (const bool value)
+
+static
+
+ +

Convert the supplied boolean into the appropriate String.

+
Parameters
+ + +
[in]valueThe boolean value to be converted.
+
+
+
Returns
The equivilent String for the locale.
+ +
+
+ +

◆ carrier64()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::carrier64 (IRCarrierAc64ac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const int16_t sleep = -1 
)
+
+private
+
+ +

Send a Carrier 64-bit A/C message with the supplied settings.

+
Parameters
+ + + + + + + + +
[in,out]acA Ptr to an IRCarrierAc64 object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]sleepNr. of minutes for sleep mode.
+
+
+
Note
-1 is Off, >= 0 is on.
+ +
+
+ +

◆ cleanState()

+ +
+
+ + + + + +
+ + + + + + + + +
stdAc::state_t IRac::cleanState (const stdAc::state_t state)
+
+staticprivate
+
+ +

Create a new state base on the provided state that has been suitably fixed.

+
Note
This is for use with Home Assistant, which requires mode to be off if the power is off.
+
Parameters
+ + +
[in]stateThe state_t structure describing the desired a/c state.
+
+
+
Returns
A stdAc::state_t with the needed settings.
+ +
+
+ +

◆ cmpStates()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRac::cmpStates (const stdAc::state_t a,
const stdAc::state_t b 
)
+
+static
+
+ +

Compare two AirCon states.

+
Note
The comparison excludes the clock.
+
Parameters
+ + + +
aA state_t to be compared.
bA state_t to be compared.
+
+
+
Returns
True if they differ, False if they don't.
+ +
+
+ +

◆ coolix()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::coolix (IRCoolixACac,
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 light,
const bool clean,
const int16_t sleep = -1 
)
+
+private
+
+ +

Send a Coolix A/C message with the supplied settings.

+
Note
May result in multiple messages being sent.
+
Parameters
+ + + + + + + + + + + + +
[in,out]acA Ptr to an IRCoolixAC object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]swinghThe horizontal swing setting.
[in]turboRun the device in turbo/powerful mode.
[in]lightTurn on the LED/Display mode.
[in]cleanTurn on the self-cleaning mode. e.g. Mould, dry filters etc
[in]sleepNr. of minutes for sleep mode.
+
+
+
Note
-1 is Off, >= 0 is on.
+ +
+
+ +

◆ corona()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::corona (IRCoronaAcac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const bool econo 
)
+
+private
+
+ +

Send a Corona A/C message with the supplied settings.

+
Note
May result in multiple messages being sent.
+
Parameters
+ + + + + + + + +
[in,out]acA Ptr to an IRCoronaAc object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]econoRun the device in economical mode.
+
+
+ +
+
+ +

◆ daikin()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::daikin (IRDaikinESPac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const stdAc::swingh_t swingh,
const bool quiet,
const bool turbo,
const bool econo,
const bool clean 
)
+
+private
+
+ +

Send a Daikin A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + + + +
[in,out]acA Ptr to an IRDaikinESP object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]swinghThe horizontal swing setting.
[in]quietRun the device in quiet/silent mode.
[in]turboRun the device in turbo/powerful mode.
[in]econoRun the device in economical mode.
[in]cleanTurn on the self-cleaning mode. e.g. Mould, dry filters etc
+
+
+ +
+
+ +

◆ daikin128()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::daikin128 (IRDaikin128ac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const bool quiet,
const bool turbo,
const bool light,
const bool econo,
const int16_t sleep = -1,
const int16_t clock = -1 
)
+
+private
+
+ +

Send a Daikin 128-bit A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + + + + +
[in,out]acA Ptr to an IRDaikin128 object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]quietRun the device in quiet/silent mode.
[in]turboRun the device in turbo/powerful mode.
[in]lightTurn on the LED/Display mode.
[in]econoRun the device in economical mode.
[in]sleepNr. of minutes for sleep mode. -1 is Off, > 0 is on.
[in]clockThe time in Nr. of mins since midnight. < 0 is ignore.
+
+
+ +
+
+ +

◆ daikin152()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::daikin152 (IRDaikin152ac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const bool quiet,
const bool turbo,
const bool econo 
)
+
+private
+
+ +

Send a Daikin 152-bit A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + +
[in,out]acA Ptr to an IRDaikin152 object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]quietRun the device in quiet/silent mode.
[in]turboRun the device in turbo/powerful mode.
[in]econoRun the device in economical mode.
+
+
+ +
+
+ +

◆ daikin160()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::daikin160 (IRDaikin160ac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv 
)
+
+private
+
+ +

Send a Daikin 160-bit A/C message with the supplied settings.

+
Parameters
+ + + + + + + +
[in,out]acA Ptr to an IRDaikin160 object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
+
+
+ +
+
+ +

◆ daikin176()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::daikin176 (IRDaikin176ac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingh_t swingh 
)
+
+private
+
+ +

Send a Daikin 176-bit A/C message with the supplied settings.

+
Parameters
+ + + + + + + +
[in,out]acA Ptr to an IRDaikin176 object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swinghThe horizontal swing setting.
+
+
+ +
+
+ +

◆ daikin2()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::daikin2 (IRDaikin2ac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const stdAc::swingh_t swingh,
const bool quiet,
const bool turbo,
const bool light,
const bool econo,
const bool filter,
const bool clean,
const bool beep,
const int16_t sleep = -1,
const int16_t clock = -1 
)
+
+private
+
+ +

Send a Daikin2 A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + + + + + + + + +
[in,out]acA Ptr to an IRDaikin2 object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]swinghThe horizontal swing setting.
[in]quietRun the device in quiet/silent mode.
[in]turboRun the device in turbo/powerful mode.
[in]lightTurn on the LED/Display mode.
[in]econoRun the device in economical mode.
[in]filterTurn on the (ion/pollen/etc) filter mode.
[in]cleanTurn on the self-cleaning mode. e.g. Mould, dry filters etc
[in]beepEnable/Disable beeps when receiving IR messages.
[in]sleepNr. of minutes for sleep mode. -1 is Off, > 0 is on.
[in]clockThe time in Nr. of mins since midnight. < 0 is ignore.
+
+
+ +
+
+ +

◆ daikin216()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::daikin216 (IRDaikin216ac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const stdAc::swingh_t swingh,
const bool quiet,
const bool turbo 
)
+
+private
+
+ +

Send a Daikin 216-bit A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + +
[in,out]acA Ptr to an IRDaikin216 object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]swinghThe horizontal swing setting.
[in]quietRun the device in quiet/silent mode.
[in]turboRun the device in turbo/powerful mode.
+
+
+ +
+
+ +

◆ daikin64()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::daikin64 (IRDaikin64ac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const bool quiet,
const bool turbo,
const int16_t sleep = -1,
const int16_t clock = -1 
)
+
+private
+
+ +

Send a Daikin 64-bit A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + + +
[in,out]acA Ptr to an IRDaikin64 object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]quietRun the device in quiet/silent mode.
[in]turboRun the device in turbo/powerful mode.
[in]sleepNr. of minutes for sleep mode. -1 is Off, > 0 is on.
[in]clockThe time in Nr. of mins since midnight. < 0 is ignore.
+
+
+ +
+
+ +

◆ delonghiac()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::delonghiac (IRDelonghiAcac,
const bool on,
const stdAc::opmode_t mode,
const bool celsius,
const float degrees,
const stdAc::fanspeed_t fan,
const bool turbo,
const int16_t sleep = -1 
)
+
+private
+
+ +

Send a Delonghi A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + +
[in,out]acA Ptr to an IRDelonghiAc object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]celsiusTemperature units. True is Celsius, False is Fahrenheit.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]turboRun the device in turbo/powerful mode.
[in]sleepNr. of minutes for sleep mode. -1 is Off, >= 0 is on.
+
+
+ +
+
+ +

◆ electra()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::electra (IRElectraAcac,
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 
)
+
+private
+
+ +

Send an Electra A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + + +
[in,out]acA Ptr to an IRElectraAc object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]swinghThe horizontal swing setting.
[in]turboRun the device in turbo/powerful mode.
[in]lighttoggleShould we toggle the LED/Display?
[in]cleanTurn on the self-cleaning mode. e.g. Mould, dry filters etc
+
+
+ +
+
+ +

◆ fanspeedToString()

+ +
+
+ + + + + +
+ + + + + + + + +
String IRac::fanspeedToString (const stdAc::fanspeed_t speed)
+
+static
+
+ +

Convert the supplied fan speed enum into the appropriate String.

+
Parameters
+ + +
[in]speedThe enum to be converted.
+
+
+
Returns
The equivilent String for the locale.
+ +
+
+ +

◆ fujitsu()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::fujitsu (IRFujitsuACac,
const fujitsu_ac_remote_model_t model,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const stdAc::swingh_t swingh,
const bool quiet,
const bool turbo,
const bool econo,
const bool filter,
const bool clean 
)
+
+private
+
+ +

Send a Fujitsu A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + + + + + +
[in,out]acA Ptr to an IRFujitsuAC object to use.
[in]modelThe A/C model to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]swinghThe horizontal swing setting.
[in]quietRun the device in quiet/silent mode.
[in]turboRun the device in turbo/powerful mode.
[in]econoRun the device in economical mode.
[in]filterTurn on the (ion/pollen/etc) filter mode.
[in]cleanTurn on the self-cleaning mode. e.g. Mould, dry filters etc
+
+
+ +
+
+ +

◆ getState()

+ +
+
+ + + + + + + + +
stdAc::state_t IRac::getState (void )
+
+ +

Get the current internal A/C climate state.

+
Returns
A Ptr to a state containing the current (to be sent) settings.
+ +
+
+ +

◆ getStatePrev()

+ +
+
+ + + + + + + + +
stdAc::state_t IRac::getStatePrev (void )
+
+ +

Get the previous internal A/C climate state that should have already been sent to the device. i.e. What the A/C unit should already be set to.

+
Returns
A Ptr to a state containing the previously sent settings.
+ +
+
+ +

◆ goodweather()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::goodweather (IRGoodweatherAcac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const bool turbo,
const bool light,
const int16_t sleep = -1 
)
+
+private
+
+ +

Send a Goodweather A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + +
[in,out]acA Ptr to an IRGoodweatherAc object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]turboRun the device in turbo/powerful mode.
[in]lightTurn on the LED/Display mode.
[in]sleepNr. of minutes for sleep mode. -1 is Off, >= 0 is on.
+
+
+ +
+
+ +

◆ gree()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::gree (IRGreeACac,
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 bool turbo,
const bool light,
const bool clean,
const int16_t sleep = -1 
)
+
+private
+
+ +

Send a Gree A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + + + + +
[in,out]acA Ptr to an IRGreeAC object to use.
[in]modelThe A/C model to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]celsiusTemperature units. True is Celsius, False is Fahrenheit.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]turboRun the device in turbo/powerful mode.
[in]lightTurn on the LED/Display mode.
[in]cleanTurn on the self-cleaning mode. e.g. Mould, dry filters etc
[in]sleepNr. of minutes for sleep mode. -1 is Off, >= 0 is on.
+
+
+ +
+
+ +

◆ haier()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::haier (IRHaierACac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const bool filter,
const int16_t sleep = -1,
const int16_t clock = -1 
)
+
+private
+
+ +

Send a Haier A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + +
[in,out]acA Ptr to an IRGreeAC object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]filterTurn on the (ion/pollen/etc) filter mode.
[in]sleepNr. of minutes for sleep mode. -1 is Off, >= 0 is on.
[in]clockThe time in Nr. of mins since midnight. < 0 is ignore.
+
+
+ +
+
+ +

◆ haierYrwo2()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::haierYrwo2 (IRHaierACYRW02ac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const bool turbo,
const bool filter,
const int16_t sleep = -1 
)
+
+private
+
+ +

Send a Haier YRWO2 A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + +
[in,out]acA Ptr to an IRHaierACYRW02 object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]turboRun the device in turbo/powerful mode.
[in]filterTurn on the (ion/pollen/etc) filter mode.
[in]sleepNr. of minutes for sleep mode. -1 is Off, >= 0 is on.
+
+
+ +
+
+ +

◆ handleToggles()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
stdAc::state_t IRac::handleToggles (const stdAc::state_t desired,
const stdAc::state_tprev = NULL 
)
+
+staticprivate
+
+ +

Create a new state base on desired & previous states but handle any state changes for options that need to be toggled.

+
Parameters
+ + + +
[in]desiredThe state_t structure describing the desired a/c state.
[in]prevA Ptr to the previous state_t structure.
+
+
+
Returns
A stdAc::state_t with the needed settings.
+ +
+
+ +

◆ hasStateChanged()

+ +
+
+ + + + + + + + +
bool IRac::hasStateChanged (void )
+
+ +

Check if the internal state has changed from what was previously sent.

+
Note
The comparison excludes the clock.
+
Returns
True if it has changed, False if not.
+ +
+
+ +

◆ hitachi()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::hitachi (IRHitachiAcac,
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 
)
+
+private
+
+ +

Send a Hitachi A/C message with the supplied settings.

+
Parameters
+ + + + + + + + +
[in,out]acA Ptr to an IRHitachiAc object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]swinghThe horizontal swing setting.
+
+
+ +
+
+ +

◆ hitachi1()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::hitachi1 (IRHitachiAc1ac,
const hitachi_ac1_remote_model_t model,
const bool on,
const bool power_toggle,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const stdAc::swingh_t swingh,
const bool swing_toggle,
const int16_t sleep = -1 
)
+
+private
+
+ +

Send a Hitachi1 A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + + + +
[in,out]acA Ptr to an IRHitachiAc1 object to use.
[in]modelThe A/C model to use.
[in]onThe power setting.
[in]power_toggleThe power toggle setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]swinghThe horizontal swing setting.
[in]swing_toggleThe swing_toggle setting.
[in]sleepNr. of minutes for sleep mode. -1 is Off, >= 0 is on.
+
+
+
Note
The sleep mode used is the "Sleep 2" setting.
+ +
+
+ +

◆ hitachi344()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::hitachi344 (IRHitachiAc344ac,
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 
)
+
+private
+
+ +

Send a Hitachi 344-bit A/C message with the supplied settings.

+
Parameters
+ + + + + + + + +
[in,out]acA Ptr to an IRHitachiAc344 object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]swinghThe horizontal swing setting.
+
+
+ +
+
+ +

◆ hitachi424()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::hitachi424 (IRHitachiAc424ac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv 
)
+
+private
+
+ +

Send a Hitachi 424-bit A/C message with the supplied settings.

+
Parameters
+ + + + + + + +
[in,out]acA Ptr to an IRHitachiAc424 object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
+
+
+ +
+
+ +

◆ initState() [1/2]

+ +
+
+ + + + + +
+ + + + + + + + +
void IRac::initState (stdAc::state_tstate)
+
+static
+
+ +

Initialse the given state with the supplied settings.

+
Parameters
+ + +
[out]stateA Ptr to where the settings will be stored.
+
+
+
Note
Sets all the parameters to reasonable base/automatic defaults.
+ +
+
+ +

◆ initState() [2/2]

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::initState (stdAc::state_tstate,
const decode_type_t vendor,
const int16_t model,
const bool power,
const stdAc::opmode_t mode,
const float degrees,
const bool celsius,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const stdAc::swingh_t swingh,
const bool quiet,
const bool turbo,
const bool econo,
const bool light,
const bool filter,
const bool clean,
const bool beep,
const int16_t sleep,
const int16_t clock 
)
+
+static
+
+ +

Initialse the given state with the supplied settings.

+
Parameters
+ + + + + + + + + + + + + + + + + + + + +
[out]stateA Ptr to where the settings will be stored.
[in]vendorThe vendor/protocol type.
[in]modelThe A/C model if applicable.
[in]powerThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]celsiusTemperature units. True is Celsius, False is Fahrenheit.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]swinghThe horizontal swing setting.
[in]quietRun the device in quiet/silent mode.
[in]turboRun the device in turbo/powerful mode.
[in]econoRun the device in economical mode.
[in]lightTurn on the LED/Display mode.
[in]filterTurn on the (ion/pollen/etc) filter mode.
[in]cleanTurn on the self-cleaning mode. e.g. Mould, dry filters etc
[in]beepEnable/Disable beeps when receiving IR messages.
[in]sleepNr. of minutes for sleep mode. -1 is Off, >= 0 is on. Some devices it is the nr. of mins to run for. Others it may be the time to enter/exit sleep mode. i.e. Time in Nr. of mins since midnight.
[in]clockThe time in Nr. of mins since midnight. < 0 is ignore.
+
+
+ +
+
+ +

◆ isProtocolSupported()

+ +
+
+ + + + + +
+ + + + + + + + +
bool IRac::isProtocolSupported (const decode_type_t protocol)
+
+static
+
+ +

Is the given protocol supported by the IRac class?

+
Parameters
+ + +
[in]protocolThe vendor/protocol type.
+
+
+
Returns
true if the protocol is supported by this class, otherwise false.
+ +
+
+ +

◆ kelvinator()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::kelvinator (IRKelvinatorACac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const stdAc::swingh_t swingh,
const bool quiet,
const bool turbo,
const bool light,
const bool filter,
const bool clean 
)
+
+private
+
+ +

Send a Kelvinator A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + + + + +
[in,out]acA Ptr to an IRKelvinatorAC object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]swinghThe horizontal swing setting.
[in]quietRun the device in quiet/silent mode.
[in]turboRun the device in turbo/powerful mode.
[in]lightTurn on the LED/Display mode.
[in]filterTurn on the (ion/pollen/etc) filter mode.
[in]cleanTurn on the self-cleaning mode. e.g. XFan, dry filters etc
+
+
+ +
+
+ +

◆ lg()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::lg (IRLgAcac,
const lg_ac_remote_model_t model,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan 
)
+
+private
+
+ +

Send a LG A/C message with the supplied settings.

+
Parameters
+ + + + + + + +
[in,out]acA Ptr to an IRLgAc object to use.
[in]modelThe A/C model to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
+
+
+ +
+
+ +

◆ markAsSent()

+ +
+
+ + + + + + + + +
void IRac::markAsSent (void )
+
+ +

Update the previous state to the current one.

+ +
+
+ +

◆ midea()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::midea (IRMideaACac,
const bool on,
const stdAc::opmode_t mode,
const bool celsius,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const int16_t sleep = -1 
)
+
+private
+
+ +

Send a Midea A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + +
[in,out]acA Ptr to an IRMideaAC object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]celsiusTemperature units. True is Celsius, False is Fahrenheit.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]sleepNr. of minutes for sleep mode. -1 is Off, >= 0 is on.
+
+
+ +
+
+ +

◆ mitsubishi()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::mitsubishi (IRMitsubishiACac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const stdAc::swingh_t swingh,
const bool quiet,
const int16_t clock = -1 
)
+
+private
+
+ +

Send a Mitsubishi A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + +
[in,out]acA Ptr to an IRMitsubishiAC object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]swinghThe horizontal swing setting.
[in]quietRun the device in quiet/silent mode.
[in]clockThe time in Nr. of mins since midnight. < 0 is ignore.
+
+
+
Note
Clock can only be set in 10 minute increments. i.e. % 10.
+ +
+
+ +

◆ mitsubishi112()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::mitsubishi112 (IRMitsubishi112ac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const stdAc::swingh_t swingh,
const bool quiet 
)
+
+private
+
+ +

Send a Mitsubishi 112-bit A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + +
[in,out]acA Ptr to an IRMitsubishi112 object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]swinghThe horizontal swing setting.
[in]quietRun the device in quiet/silent mode.
+
+
+ +
+
+ +

◆ mitsubishi136()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::mitsubishi136 (IRMitsubishi136ac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const bool quiet 
)
+
+private
+
+ +

Send a Mitsubishi 136-bit A/C message with the supplied settings.

+
Parameters
+ + + + + + + + +
[in,out]acA Ptr to an IRMitsubishi136 object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]quietRun the device in quiet/silent mode.
+
+
+ +
+
+ +

◆ mitsubishiHeavy152()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::mitsubishiHeavy152 (IRMitsubishiHeavy152Acac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const stdAc::swingh_t swingh,
const bool quiet,
const bool turbo,
const bool econo,
const bool filter,
const bool clean,
const int16_t sleep = -1 
)
+
+private
+
+ +

Send a Mitsubishi Heavy 152-bit A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + + + + + +
[in,out]acA Ptr to an IRMitsubishiHeavy152Ac object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]swinghThe horizontal swing setting.
[in]quietRun the device in quiet/silent mode.
[in]turboRun the device in turbo/powerful mode.
[in]econoRun the device in economical mode.
[in]filterTurn on the (ion/pollen/etc) filter mode.
[in]cleanTurn on the self-cleaning mode. e.g. Mould, dry filters etc
[in]sleepNr. of minutes for sleep mode. -1 is Off, > 0 is on.
+
+
+ +
+
+ +

◆ mitsubishiHeavy88()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::mitsubishiHeavy88 (IRMitsubishiHeavy88Acac,
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 econo,
const bool clean 
)
+
+private
+
+ +

Send a Mitsubishi Heavy 88-bit A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + + +
[in,out]acA Ptr to an IRMitsubishiHeavy88Ac object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]swinghThe horizontal swing setting.
[in]turboRun the device in turbo/powerful mode.
[in]econoRun the device in economical mode.
[in]cleanTurn on the self-cleaning mode. e.g. Mould, dry filters etc
+
+
+ +
+
+ +

◆ neoclima()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::neoclima (IRNeoclimaAcac,
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 light,
const bool filter,
const int16_t sleep = -1 
)
+
+private
+
+ +

Send a Neoclima A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + + + +
[in,out]acA Ptr to an IRNeoclimaAc object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]swinghThe horizontal swing setting.
[in]turboRun the device in turbo/powerful mode.
[in]lightTurn on the LED/Display mode.
[in]filterTurn on the (ion/pollen/etc) filter mode.
[in]sleepNr. of minutes for sleep mode. -1 is Off, > 0 is on.
+
+
+ +
+
+ +

◆ opmodeToString()

+ +
+
+ + + + + +
+ + + + + + + + +
String IRac::opmodeToString (const stdAc::opmode_t mode)
+
+static
+
+ +

Convert the supplied operation mode into the appropriate String.

+
Parameters
+ + +
[in]modeThe enum to be converted.
+
+
+
Returns
The equivilent String for the locale.
+ +
+
+ +

◆ panasonic()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::panasonic (IRPanasonicAcac,
const panasonic_ac_remote_model_t model,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const stdAc::swingh_t swingh,
const bool quiet,
const bool turbo,
const bool filter,
const int16_t clock = -1 
)
+
+private
+
+ +

Send a Panasonic A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + + + + +
[in,out]acA Ptr to an IRPanasonicAc object to use.
[in]modelThe A/C model to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]swinghThe horizontal swing setting.
[in]quietRun the device in quiet/silent mode.
[in]turboRun the device in turbo/powerful mode.
[in]filterTurn on the (ion/pollen/etc) filter mode.
[in]clockThe time in Nr. of mins since midnight. < 0 is ignore.
+
+
+ +
+
+ +

◆ samsung()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::samsung (IRSamsungAcac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const bool quiet,
const bool turbo,
const bool light,
const bool filter,
const bool clean,
const bool beep,
const bool prevpower = true,
const bool forcepower = true 
)
+
+private
+
+ +

Send a Samsung A/C message with the supplied settings.

+
Note
Multiple IR messages may be generated & sent.
+
Parameters
+ + + + + + + + + + + + + + + +
[in,out]acA Ptr to an IRSamsungAc object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]quietRun the device in quiet/silent mode.
[in]turboRun the device in turbo/powerful mode.
[in]lightTurn on the LED/Display mode.
[in]filterTurn on the (ion/pollen/etc) filter mode.
[in]cleanTurn on the self-cleaning mode. e.g. Mould, dry filters etc
[in]beepEnable/Disable beeps when receiving IR messages.
[in]prevpowerThe power setting from the previous A/C state.
[in]forcepowerDo we force send the special power message?
+
+
+ +
+
+ +

◆ sendAc() [1/3]

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRac::sendAc (const decode_type_t vendor,
const int16_t model,
const bool power,
const stdAc::opmode_t mode,
const float degrees,
const bool celsius,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const stdAc::swingh_t swingh,
const bool quiet,
const bool turbo,
const bool econo,
const bool light,
const bool filter,
const bool clean,
const bool beep,
const int16_t sleep = -1,
const int16_t clock = -1 
)
+
+ +

Send A/C message for a given device using common A/C settings.

+
Parameters
+ + + + + + + + +
[in]vendorThe vendor/protocol type.
[in]modelThe A/C model if applicable.
[in]powerThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]celsiusTemperature units. True is Celsius, False is Fahrenheit.
[in]fanThe speed setting for the fan.
+
+
+
Note
The following are all "if supported" by the underlying A/C classes.
+
Parameters
+ + + + + + + + + + + + +
[in]swingvThe vertical swing setting.
[in]swinghThe horizontal swing setting.
[in]quietRun the device in quiet/silent mode.
[in]turboRun the device in turbo/powerful mode.
[in]econoRun the device in economical mode.
[in]lightTurn on the LED/Display mode.
[in]filterTurn on the (ion/pollen/etc) filter mode.
[in]cleanTurn on the self-cleaning mode. e.g. Mould, dry filters etc
[in]beepEnable/Disable beeps when receiving IR messages.
[in]sleepNr. of minutes for sleep mode. -1 is Off, >= 0 is on. Some devices it is the nr. of mins to run for. Others it may be the time to enter/exit sleep mode. i.e. Time in Nr. of mins since midnight.
[in]clockThe time in Nr. of mins since midnight. < 0 is ignore.
+
+
+
Returns
True, if accepted/converted/attempted etc. False, if unsupported.
+ +
+
+ +

◆ sendAc() [2/3]

+ +
+
+ + + + + + + + + + + + + + + + + + +
bool IRac::sendAc (const stdAc::state_t desired,
const stdAc::state_tprev = NULL 
)
+
+ +

Send A/C message for a given device using state_t structures.

+
Parameters
+ + + +
[in]desiredThe state_t structure describing the desired new ac state
[in]prevA Ptr to the state_t structure containing the previous state
+
+
+
Returns
True, if accepted/converted/attempted etc. False, if unsupported.
+ +
+
+ +

◆ sendAc() [3/3]

+ +
+
+ + + + + + + + +
bool IRac::sendAc (void )
+
+ +

Send an A/C message based soley on our internal state.

+
Returns
True, if accepted/converted/attempted. False, if unsupported.
+ +
+
+ +

◆ sharp()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::sharp (IRSharpAcac,
const bool on,
const bool prev_power,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const bool turbo,
const bool filter,
const bool clean 
)
+
+private
+
+ +

Send a Sharp A/C message with the supplied settings.

+
Note
Multiple IR messages may be generated & sent.
+
Parameters
+ + + + + + + + + + + +
[in,out]acA Ptr to an IRSharpAc object to use.
[in]onThe power setting.
[in]prev_powerThe power setting from the previous A/C state.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]turboRun the device in turbo/powerful mode.
[in]filterTurn on the (ion/pollen/etc) filter mode.
[in]cleanTurn on the self-cleaning mode. e.g. Mould, dry filters etc
+
+
+ +
+
+ +

◆ strToBool()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
bool IRac::strToBool (const char * str,
const bool def = false 
)
+
+static
+
+ +

Convert the supplied str into the appropriate boolean value.

+
Parameters
+ + + +
[in]strA Ptr to a C-style string to be converted.
[in]defThe boolean value to return if no conversion was possible.
+
+
+
Returns
The equivilent boolean value.
+ +
+
+ +

◆ strToFanspeed()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
stdAc::fanspeed_t IRac::strToFanspeed (const char * str,
const stdAc::fanspeed_t def = stdAc::fanspeed_t::kAuto 
)
+
+static
+
+ +

Convert the supplied str into the appropriate enum.

+
Parameters
+ + + +
[in]strA Ptr to a C-style string to be converted.
[in]defThe enum to return if no conversion was possible.
+
+
+
Returns
The equivilent enum.
+ +
+
+ +

◆ strToModel()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
int16_t IRac::strToModel (const char * str,
const int16_t def = -1 
)
+
+static
+
+ +

Convert the supplied str into the appropriate enum.

+
Note
Assumes str is the model code or an integer >= 1.
+
Parameters
+ + + +
[in]strA Ptr to a C-style string to be converted.
[in]defThe enum to return if no conversion was possible.
+
+
+
Returns
The equivilent enum.
+ +
+
+ +

◆ strToOpmode()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
stdAc::opmode_t IRac::strToOpmode (const char * str,
const stdAc::opmode_t def = stdAc::opmode_t::kAuto 
)
+
+static
+
+ +

Convert the supplied str into the appropriate enum.

+
Parameters
+ + + +
[in]strA Ptr to a C-style string to be converted.
[in]defThe enum to return if no conversion was possible.
+
+
+
Returns
The equivilent enum.
+ +
+
+ +

◆ strToSwingH()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
stdAc::swingh_t IRac::strToSwingH (const char * str,
const stdAc::swingh_t def = stdAc::swingh_t::kOff 
)
+
+static
+
+ +

Convert the supplied str into the appropriate enum.

+
Parameters
+ + + +
[in]strA Ptr to a C-style string to be converted.
[in]defThe enum to return if no conversion was possible.
+
+
+
Returns
The equivilent enum.
+ +
+
+ +

◆ strToSwingV()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
stdAc::swingv_t IRac::strToSwingV (const char * str,
const stdAc::swingv_t def = stdAc::swingv_t::kOff 
)
+
+static
+
+ +

Convert the supplied str into the appropriate enum.

+
Parameters
+ + + +
[in]strA Ptr to a C-style string to be converted.
[in]defThe enum to return if no conversion was possible.
+
+
+
Returns
The equivilent enum.
+ +
+
+ +

◆ swinghToString()

+ +
+
+ + + + + +
+ + + + + + + + +
String IRac::swinghToString (const stdAc::swingh_t swingh)
+
+static
+
+ +

Convert the supplied enum into the appropriate String.

+
Parameters
+ + +
[in]swinghThe enum to be converted.
+
+
+
Returns
The equivilent String for the locale.
+ +
+
+ +

◆ swingvToString()

+ +
+
+ + + + + +
+ + + + + + + + +
String IRac::swingvToString (const stdAc::swingv_t swingv)
+
+static
+
+ +

Convert the supplied enum into the appropriate String.

+
Parameters
+ + +
[in]swingvThe enum to be converted.
+
+
+
Returns
The equivilent String for the locale.
+ +
+
+ +

◆ tcl112()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::tcl112 (IRTcl112Acac,
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 light,
const bool econo,
const bool filter 
)
+
+private
+
+ +

Send a TCL 112-bit A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + + + +
[in,out]acA Ptr to an IRTcl112Ac object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]swinghThe horizontal swing setting.
[in]turboRun the device in turbo/powerful mode.
[in]lightTurn on the LED/Display mode.
[in]econoRun the device in economical mode.
[in]filterTurn on the (ion/pollen/etc) filter mode.
+
+
+ +
+
+ +

◆ teco()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::teco (IRTecoAcac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const bool light,
const int16_t sleep = -1 
)
+
+private
+
+ +

Send a Teco A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + +
[in,out]acA Ptr to an IRTecoAc object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]lightTurn on the LED/Display mode.
[in]sleepNr. of minutes for sleep mode. -1 is Off, > 0 is on.
+
+
+ +
+
+ +

◆ toshiba()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::toshiba (IRToshibaACac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan 
)
+
+private
+
+ +

Send a Toshiba A/C message with the supplied settings.

+
Parameters
+ + + + + + +
[in,out]acA Ptr to an IRToshibaAC object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
+
+
+ +
+
+ +

◆ trotec()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::trotec (IRTrotecESPac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const int16_t sleep = -1 
)
+
+private
+
+ +

Send a Trotec A/C message with the supplied settings.

+
Parameters
+ + + + + + + +
[in,out]acA Ptr to an IRTrotecESP object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]sleepNr. of minutes for sleep mode. -1 is Off, > 0 is on.
+
+
+ +
+
+ +

◆ vestel()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::vestel (IRVestelAcac,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const bool turbo,
const bool filter,
const int16_t sleep = -1,
const int16_t clock = -1,
const bool sendNormal = true 
)
+
+private
+
+ +

Send a Vestel A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + + + +
[in,out]acA Ptr to an IRVestelAc object to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]turboRun the device in turbo/powerful mode.
[in]filterTurn on the (ion/pollen/etc) filter mode.
[in]sleepNr. of minutes for sleep mode. -1 is Off, > 0 is on.
[in]clockThe time in Nr. of mins since midnight. < 0 is ignore.
[in]sendNormalDo we send a Normal settings message at all? i.e In addition to the clock/time/timer message
+
+
+ +
+
+ +

◆ whirlpool()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRac::whirlpool (IRWhirlpoolAcac,
const whirlpool_ac_remote_model_t model,
const bool on,
const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv,
const bool turbo,
const bool light,
const int16_t sleep = -1,
const int16_t clock = -1 
)
+
+private
+
+ +

Send a Whirlpool A/C message with the supplied settings.

+
Parameters
+ + + + + + + + + + + + +
[in,out]acA Ptr to an IRWhirlpoolAc object to use.
[in]modelThe A/C model to use.
[in]onThe power setting.
[in]modeThe operation mode setting.
[in]degreesThe temperature setting in degrees.
[in]fanThe speed setting for the fan.
[in]swingvThe vertical swing setting.
[in]turboRun the device in turbo/powerful mode.
[in]lightTurn on the LED/Display mode.
[in]sleepNr. of minutes for sleep mode. -1 is Off, > 0 is on.
[in]clockThe time in Nr. of mins since midnight. < 0 is ignore.
+
+
+ +
+
+

Member Data Documentation

+ +

◆ _inverted

+ +
+
+ + + + + +
+ + + + +
bool IRac::_inverted
+
+private
+
+ +
+
+ +

◆ _modulation

+ +
+
+ + + + + +
+ + + + +
bool IRac::_modulation
+
+private
+
+ +
+
+ +

◆ _pin

+ +
+
+ + + + + +
+ + + + +
uint16_t IRac::_pin
+
+private
+
+ +
+
+ +

◆ _prev

+ +
+
+ + + + + +
+ + + + +
stdAc::state_t IRac::_prev
+
+private
+
+ +
+
+ +

◆ next

+ +
+
+ + + + +
stdAc::state_t IRac::next
+
+ +

The state we want the device to be in after we send.

+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac__coll__graph.map new file mode 100644 index 000000000..a8e1d6323 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac__coll__graph.md5 new file mode 100644 index 000000000..76e762f05 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac__coll__graph.md5 @@ -0,0 +1 @@ +798baf66f32a8ad80bc719cc6de8c2ba \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac__coll__graph.png new file mode 100644 index 000000000..ed8ea1ee9 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRac__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv-members.html new file mode 100644 index 000000000..8be86fdbc --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv-members.html @@ -0,0 +1,189 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRrecv Member List
+
+
+ +

This is the complete list of members for IRrecv, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_matchGeneric(volatile uint16_t *data_ptr, uint64_t *result_bits_ptr, uint8_t *result_ptr, const bool use_bits, const uint16_t remaining, const uint16_t required, const uint16_t hdrmark, const uint32_t hdrspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t footerspace, const bool atleast=false, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true)IRrecvprivate
_timer_numIRrecvprivate
_toleranceIRrecvprivate
_unknown_thresholdIRrecvprivate
_validTolerance(const uint8_t percentage)IRrecvprivate
compare(const uint16_t oldval, const uint16_t newval)IRrecvprivate
copyIrParams(volatile irparams_t *src, irparams_t *dst)IRrecvprivate
crudeNoiseFilter(decode_results *results, const uint16_t floor=0)IRrecvprivate
decode(decode_results *results, irparams_t *save=NULL, uint8_t max_skip=0, uint16_t noise_floor=0)IRrecv
decodeAirwell(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kAirwellBits, const bool strict=true)IRrecvprivate
decodeAiwaRCT501(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kAiwaRcT501Bits, const bool strict=true)IRrecvprivate
decodeAmcor(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kAmcorBits, const bool strict=true)IRrecvprivate
decodeArgo(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kArgoBits, const bool strict=true)IRrecvprivate
decodeCarrierAC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kCarrierAcBits, const bool strict=true)IRrecvprivate
decodeCarrierAC40(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kCarrierAc40Bits, const bool strict=true)IRrecvprivate
decodeCarrierAC64(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kCarrierAc64Bits, const bool strict=true)IRrecvprivate
decodeCOOLIX(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kCoolixBits, const bool strict=true)IRrecvprivate
decodeCoronaAc(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kCoronaAcBitsShort, const bool strict=true)IRrecvprivate
decodeDaikin(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikinBits, const bool strict=true)IRrecvprivate
decodeDaikin128(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikin128Bits, const bool strict=true)IRrecvprivate
decodeDaikin152(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikin152Bits, const bool strict=true)IRrecvprivate
decodeDaikin160(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikin160Bits, const bool strict=true)IRrecvprivate
decodeDaikin176(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikin176Bits, const bool strict=true)IRrecvprivate
decodeDaikin2(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikin2Bits, const bool strict=true)IRrecvprivate
decodeDaikin216(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikin216Bits, const bool strict=true)IRrecvprivate
decodeDaikin64(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikin64Bits, const bool strict=true)IRrecvprivate
decodeDelonghiAc(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDelonghiAcBits, const bool strict=true)IRrecvprivate
decodeDenon(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDenonBits, const bool strict=true)IRrecvprivate
decodeDISH(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDishBits, const bool strict=true)IRrecvprivate
decodeDoshisha(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDoshishaBits, const bool strict=true)IRrecvprivate
decodeElectraAC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kElectraAcBits, const bool strict=true)IRrecvprivate
decodeEpson(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kEpsonBits, const bool strict=true)IRrecvprivate
decodeFujitsuAC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kFujitsuAcBits, const bool strict=false)IRrecvprivate
decodeGICable(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kGicableBits, const bool strict=true)IRrecvprivate
decodeGoodweather(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kGoodweatherBits, const bool strict=true)IRrecvprivate
decodeGree(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kGreeBits, const bool strict=true)IRrecvprivate
decodeHaierAC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kHaierACBits, const bool strict=true)IRrecvprivate
decodeHaierACYRW02(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kHaierACYRW02Bits, const bool strict=true)IRrecvprivate
decodeHash(decode_results *results)IRrecvprivate
decodeHitachiAC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kHitachiAcBits, const bool strict=true, const bool MSBfirst=true)IRrecvprivate
decodeHitachiAC1(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kHitachiAc1Bits, const bool strict=true)IRrecvprivate
decodeHitachiAc3(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kHitachiAc3Bits, const bool strict=true)IRrecvprivate
decodeHitachiAc424(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kHitachiAc424Bits, const bool strict=true)IRrecvprivate
decodeInax(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kInaxBits, const bool strict=true)IRrecvprivate
decodeJVC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kJvcBits, const bool strict=true)IRrecvprivate
decodeKelvinator(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kKelvinatorBits, const bool strict=true)IRrecvprivate
decodeLasertag(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kLasertagBits, const bool strict=true)IRrecvprivate
decodeLegoPf(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kLegoPfBits, const bool strict=true)IRrecvprivate
decodeLG(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kLgBits, const bool strict=false)IRrecvprivate
decodeLutron(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kLutronBits, const bool strict=true)IRrecvprivate
decodeMagiQuest(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMagiquestBits, const bool strict=true)IRrecvprivate
decodeMidea(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMideaBits, const bool strict=true)IRrecvprivate
decodeMidea24(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMidea24Bits, const bool strict=true)IRrecvprivate
decodeMitsubishi(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMitsubishiBits, const bool strict=true)IRrecvprivate
decodeMitsubishi112(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMitsubishi112Bits, const bool strict=true)IRrecvprivate
decodeMitsubishi136(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMitsubishi136Bits, const bool strict=true)IRrecvprivate
decodeMitsubishi2(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMitsubishiBits, const bool strict=true)IRrecvprivate
decodeMitsubishiAC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMitsubishiACBits, const bool strict=false)IRrecvprivate
decodeMitsubishiHeavy(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMitsubishiHeavy152Bits, const bool strict=true)IRrecvprivate
decodeMultibrackets(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMultibracketsBits, const bool strict=true)IRrecvprivate
decodeMWM(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=24, const bool strict=true)IRrecvprivate
decodeNEC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kNECBits, const bool strict=true)IRrecvprivate
decodeNeoclima(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kNeoclimaBits, const bool strict=true)IRrecvprivate
decodeNikai(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kNikaiBits, const bool strict=true)IRrecvprivate
decodePanasonic(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kPanasonicBits, const bool strict=false, const uint32_t manufacturer=kPanasonicManufacturer)IRrecvprivate
decodePanasonicAC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kPanasonicAcBits, const bool strict=true)IRrecvprivate
decodePioneer(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kPioneerBits, const bool strict=true)IRrecvprivate
decodeRC5(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kRC5XBits, const bool strict=true)IRrecvprivate
decodeRC6(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kRC6Mode0Bits, const bool strict=false)IRrecvprivate
decodeRCMM(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kRCMMBits, const bool strict=false)IRrecvprivate
decodeSAMSUNG(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSamsungBits, const bool strict=true)IRrecvprivate
decodeSamsung36(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSamsung36Bits, const bool strict=true)IRrecvprivate
decodeSamsungAC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSamsungAcBits, const bool strict=true)IRrecvprivate
decodeSanyoLC7461(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSanyoLC7461Bits, bool strict=true)IRrecvprivate
decodeSharp(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSharpBits, const bool strict=true, const bool expansion=true)IRrecvprivate
decodeSharpAc(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSharpAcBits, const bool strict=true)IRrecvprivate
decodeSony(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSonyMinBits, const bool strict=false)IRrecvprivate
decodeSymphony(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSymphonyBits, const bool strict=true)IRrecvprivate
decodeTeco(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kTecoBits, const bool strict=false)IRrecvprivate
decodeToshibaAC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbytes=kToshibaACBits, const bool strict=true)IRrecvprivate
decodeTrotec(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kTrotecBits, const bool strict=true)IRrecvprivate
decodeVestelAc(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kVestelAcBits, const bool strict=true)IRrecvprivate
decodeWhirlpoolAC(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kWhirlpoolAcBits, const bool strict=true)IRrecvprivate
decodeWhynter(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kWhynterBits, const bool strict=true)IRrecvprivate
decodeZepeal(decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kZepealBits, const bool strict=true)IRrecvprivate
disableIRIn(void)IRrecv
enableIRIn(const bool pullup=false)IRrecv
getBufSize(void)IRrecv
getRClevel(decode_results *results, uint16_t *offset, uint16_t *used, uint16_t bitTime, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const uint16_t delta=0, const uint8_t maxwidth=3)IRrecvprivate
getTolerance(void)IRrecv
irparams_saveIRrecvprivate
IRrecv(const uint16_t recvpin, const uint16_t bufsize=kRawBuf, const uint8_t timeout=kTimeoutMs, const bool save_buffer=false, const uint8_t timer_num=kDefaultESP32Timer)IRrecvexplicit
IRrecv(const uint16_t recvpin, const uint16_t bufsize=kRawBuf, const uint8_t timeout=kTimeoutMs, const bool save_buffer=false)IRrecvexplicit
match(const uint32_t measured, const uint32_t desired, const uint8_t tolerance=kUseDefTol, const uint16_t delta=0)IRrecv
matchAtLeast(const uint32_t measured, const uint32_t desired, const uint8_t tolerance=kUseDefTol, const uint16_t delta=0)IRrecvprivate
matchBytes(volatile uint16_t *data_ptr, uint8_t *result_ptr, const uint16_t remaining, const uint16_t nbytes, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true)IRrecvprivate
matchData(volatile uint16_t *data_ptr, const uint16_t nbits, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true)IRrecvprivate
matchGeneric(volatile uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, const uint16_t hdrmark, const uint32_t hdrspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t footerspace, const bool atleast=false, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true)IRrecvprivate
matchGeneric(volatile uint16_t *data_ptr, uint8_t *result_ptr, const uint16_t remaining, const uint16_t nbits, const uint16_t hdrmark, const uint32_t hdrspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t footerspace, const bool atleast=false, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true)IRrecvprivate
matchGenericConstBitTime(volatile uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, const uint16_t hdrmark, const uint32_t hdrspace, const uint16_t one, const uint32_t zero, const uint16_t footermark, const uint32_t footerspace, const bool atleast=false, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true)IRrecvprivate
matchManchester(volatile const uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, const uint16_t hdrmark, const uint32_t hdrspace, const uint16_t clock_period, const uint16_t footermark, const uint32_t footerspace, const bool atleast=false, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true, const bool GEThomas=true)IRrecvprivate
matchManchesterData(volatile const uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, const uint16_t half_period, const uint16_t starting_balance=0, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true, const bool GEThomas=true)IRrecvprivate
matchMark(const uint32_t measured, const uint32_t desired, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess)IRrecv
matchSpace(const uint32_t measured, const uint32_t desired, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess)IRrecv
resume(void)IRrecv
setTolerance(const uint8_t percent=kTolerance)IRrecv
setUnknownThreshold(const uint16_t length)IRrecv
ticksHigh(const uint32_t usecs, const uint8_t tolerance=kUseDefTol, const uint16_t delta=0)IRrecvprivate
ticksLow(const uint32_t usecs, const uint8_t tolerance=kUseDefTol, const uint16_t delta=0)IRrecvprivate
~IRrecv(void)IRrecv
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv.html new file mode 100644 index 000000000..88e252a44 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv.html @@ -0,0 +1,7184 @@ + + + + + + + +IRremoteESP8266: IRrecv Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for receiving IR messages. + More...

+ +

#include <IRrecv.h>

+
+Collaboration diagram for IRrecv:
+
+
Collaboration graph
+ + + + +
[legend]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRrecv (const uint16_t recvpin, const uint16_t bufsize=kRawBuf, const uint8_t timeout=kTimeoutMs, const bool save_buffer=false, const uint8_t timer_num=kDefaultESP32Timer)
 Class constructor Args: More...
 
 IRrecv (const uint16_t recvpin, const uint16_t bufsize=kRawBuf, const uint8_t timeout=kTimeoutMs, const bool save_buffer=false)
 
 ~IRrecv (void)
 Class destructor Cleans up after the object is no longer needed. e.g. Frees up all memory used by the various buffers, and disables any timers or interrupts used. More...
 
void setTolerance (const uint8_t percent=kTolerance)
 Set the base tolerance percentage for matching incoming IR messages. More...
 
uint8_t getTolerance (void)
 Get the base tolerance percentage for matching incoming IR messages. More...
 
bool decode (decode_results *results, irparams_t *save=NULL, uint8_t max_skip=0, uint16_t noise_floor=0)
 Decodes the received IR message. If the interrupt state is saved, we will immediately resume waiting for the next IR message to avoid missing messages. More...
 
void enableIRIn (const bool pullup=false)
 Set up and (re)start the IR capture mechanism. More...
 
void disableIRIn (void)
 Stop collection of any received IR data. Disable any timers and interrupts. More...
 
void resume (void)
 Resume collection of received IR data. More...
 
uint16_t getBufSize (void)
 Obtain the maximum number of entries possible in the capture buffer. i.e. It's size. More...
 
void setUnknownThreshold (const uint16_t length)
 Set the minimum length we will consider for reporting UNKNOWN message types. More...
 
bool match (const uint32_t measured, const uint32_t desired, const uint8_t tolerance=kUseDefTol, const uint16_t delta=0)
 Check if we match a pulse(measured) with the desired within +/-tolerance percent and/or +/- a fixed delta range. More...
 
bool matchMark (const uint32_t measured, const uint32_t desired, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess)
 Check if we match a mark signal(measured) with the desired within +/-tolerance percent, after an expected is excess is added. More...
 
bool matchSpace (const uint32_t measured, const uint32_t desired, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess)
 Check if we match a space signal(measured) with the desired within +/-tolerance percent, after an expected is excess is removed. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Private Member Functions

uint8_t _validTolerance (const uint8_t percentage)
 Convert the tolerance percentage into something valid. More...
 
void copyIrParams (volatile irparams_t *src, irparams_t *dst)
 Make a copy of the interrupt state & buffer data. Needed because irparams is marked as volatile, thus memcpy() isn't allowed. Only call this when you know the interrupt handlers won't modify anything. i.e. In kStopState. More...
 
uint16_t compare (const uint16_t oldval, const uint16_t newval)
 Compare two tick values. More...
 
uint32_t ticksLow (const uint32_t usecs, const uint8_t tolerance=kUseDefTol, const uint16_t delta=0)
 Calculate the lower bound of the nr. of ticks. More...
 
uint32_t ticksHigh (const uint32_t usecs, const uint8_t tolerance=kUseDefTol, const uint16_t delta=0)
 Calculate the upper bound of the nr. of ticks. More...
 
bool matchAtLeast (const uint32_t measured, const uint32_t desired, const uint8_t tolerance=kUseDefTol, const uint16_t delta=0)
 Check if we match a pulse(measured) of at least desired within tolerance percent and/or a fixed delta margin. More...
 
uint16_t _matchGeneric (volatile uint16_t *data_ptr, uint64_t *result_bits_ptr, uint8_t *result_ptr, const bool use_bits, const uint16_t remaining, const uint16_t required, const uint16_t hdrmark, const uint32_t hdrspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t footerspace, const bool atleast=false, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true)
 Match & decode a generic/typical IR message. The data is stored in result_bits_ptr or result_bytes_ptr depending on flag use_bits. More...
 
match_result_t matchData (volatile uint16_t *data_ptr, const uint16_t nbits, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true)
 Match & decode the typical data section of an IR message. The data value is stored in the least significant bits reguardless of the bit ordering requested. More...
 
uint16_t matchBytes (volatile uint16_t *data_ptr, uint8_t *result_ptr, const uint16_t remaining, const uint16_t nbytes, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true)
 Match & decode the typical data section of an IR message. The bytes are stored at result_ptr. The first byte in the result equates to the first byte encountered, and so on. More...
 
uint16_t matchGeneric (volatile uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, const uint16_t hdrmark, const uint32_t hdrspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t footerspace, const bool atleast=false, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true)
 Match & decode a generic/typical <= 64bit IR message. The data is stored at result_ptr. More...
 
uint16_t matchGeneric (volatile uint16_t *data_ptr, uint8_t *result_ptr, const uint16_t remaining, const uint16_t nbits, const uint16_t hdrmark, const uint32_t hdrspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t footerspace, const bool atleast=false, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true)
 Match & decode a generic/typical > 64bit IR message. The bytes are stored at result_ptr. The first byte in the result equates to the first byte encountered, and so on. More...
 
uint16_t matchGenericConstBitTime (volatile uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, const uint16_t hdrmark, const uint32_t hdrspace, const uint16_t one, const uint32_t zero, const uint16_t footermark, const uint32_t footerspace, const bool atleast=false, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true)
 Match & decode a generic/typical constant bit time <= 64bit IR message. The data is stored at result_ptr. More...
 
uint16_t matchManchesterData (volatile const uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, const uint16_t half_period, const uint16_t starting_balance=0, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true, const bool GEThomas=true)
 Match & decode a Manchester Code data (<= 64bits. More...
 
uint16_t matchManchester (volatile const uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, const uint16_t hdrmark, const uint32_t hdrspace, const uint16_t clock_period, const uint16_t footermark, const uint32_t footerspace, const bool atleast=false, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true, const bool GEThomas=true)
 Match & decode a Manchester Code <= 64bit IR message. The data is stored at result_ptr. More...
 
void crudeNoiseFilter (decode_results *results, const uint16_t floor=0)
 Remove or merge pulses in the capture buffer that are too short. More...
 
bool decodeHash (decode_results *results)
 Decode any arbitrary IR message into a 32-bit code value. Instead of decoding using a standard encoding scheme (e.g. Sony, NEC, RC5), the code is hashed to a 32-bit value. More...
 
bool decodeNEC (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kNECBits, const bool strict=true)
 Decode the supplied NEC (Renesas) message. Status: STABLE / Known good. More...
 
bool decodeArgo (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kArgoBits, const bool strict=true)
 Decode the supplied Argo message. Status: BETA / Probably works. More...
 
bool decodeSony (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSonyMinBits, const bool strict=false)
 Decode the supplied Sony/SIRC message. Status: STABLE / Should be working. strict mode is ALPHA / Untested. More...
 
bool decodeSanyoLC7461 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSanyoLC7461Bits, bool strict=true)
 Decode the supplied SANYO LC7461 message. Status: BETA / Probably works. More...
 
bool decodeMitsubishi (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMitsubishiBits, const bool strict=true)
 Decode the supplied Mitsubishi 16-bit message. Status: STABLE / Working. More...
 
bool decodeMitsubishi2 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMitsubishiBits, const bool strict=true)
 Decode the supplied second variation of a Mitsubishi 16-bit message. Status: STABLE / Working. More...
 
bool decodeMitsubishiAC (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMitsubishiACBits, const bool strict=false)
 Decode the supplied Mitsubish 144-bit A/C message. Status: BETA / Probably works. More...
 
bool decodeMitsubishi136 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMitsubishi136Bits, const bool strict=true)
 Decode the supplied Mitsubishi 136-bit A/C message. (MITSUBISHI136) Status: STABLE / Reported as working. More...
 
bool decodeMitsubishi112 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMitsubishi112Bits, const bool strict=true)
 Decode the supplied Mitsubishi/TCL 112-bit A/C message. (MITSUBISHI112, TCL112AC) Status: STABLE / Reported as working. More...
 
bool decodeMitsubishiHeavy (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMitsubishiHeavy152Bits, const bool strict=true)
 Decode the supplied Mitsubishi Heavy Industries A/C message. Status: BETA / Appears to be working. Needs testing against a real device. More...
 
int16_t getRClevel (decode_results *results, uint16_t *offset, uint16_t *used, uint16_t bitTime, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const uint16_t delta=0, const uint8_t maxwidth=3)
 Gets one undecoded level at a time from the raw buffer. The RC5/6 decoding is easier if the data is broken into time intervals. E.g. if the buffer has MARK for 2 time intervals and SPACE for 1, successive calls to getRClevel will return MARK, MARK, SPACE. offset and used are updated to keep track of the current position. More...
 
bool decodeRC5 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kRC5XBits, const bool strict=true)
 Decode the supplied RC-5/RC5X message. Status: RC-5 (stable), RC-5X (alpha) More...
 
bool decodeRC6 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kRC6Mode0Bits, const bool strict=false)
 Decode the supplied RC6 message. Status: Stable. More...
 
bool decodeRCMM (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kRCMMBits, const bool strict=false)
 Decode a Philips RC-MM packet (between 12 & 32 bits) if possible. Status: STABLE / Should be working. More...
 
bool decodePanasonic (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kPanasonicBits, const bool strict=false, const uint32_t manufacturer=kPanasonicManufacturer)
 Decode the supplied Panasonic message. Status: STABLE / Should be working. More...
 
bool decodeLG (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kLgBits, const bool strict=false)
 Decode the supplied LG message. Status: STABLE / Working. More...
 
bool decodeInax (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kInaxBits, const bool strict=true)
 Decode the supplied Inax Toilet message. Status: Stable / Known working. More...
 
bool decodeJVC (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kJvcBits, const bool strict=true)
 Decode the supplied JVC message. Status: Stable / Known working. More...
 
bool decodeSAMSUNG (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSamsungBits, const bool strict=true)
 Decode the supplied Samsung 32-bit message. Status: STABLE. More...
 
bool decodeSamsung36 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSamsung36Bits, const bool strict=true)
 Decode the supplied Samsung36 message. Status: Alpha / Experimental. More...
 
bool decodeSamsungAC (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSamsungAcBits, const bool strict=true)
 Decode the supplied Samsung A/C message. Status: Stable / Known to be working. More...
 
bool decodeWhynter (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kWhynterBits, const bool strict=true)
 Decode the supplied Whynter message. Status: STABLE / Working. Strict mode is ALPHA. More...
 
bool decodeCOOLIX (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kCoolixBits, const bool strict=true)
 Decode the supplied Coolix A/C message. Status: STABLE / Known Working. More...
 
bool decodeDenon (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDenonBits, const bool strict=true)
 Decode the supplied Delonghi A/C message. Status: STABLE / Should work fine. More...
 
bool decodeDISH (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDishBits, const bool strict=true)
 Decode the supplied DISH NETWORK message. Status: ALPHA (untested and unconfirmed.) More...
 
bool decodeSharp (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSharpBits, const bool strict=true, const bool expansion=true)
 Decode the supplied Sharp message. Status: STABLE / Working fine. More...
 
bool decodeSharpAc (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSharpAcBits, const bool strict=true)
 Decode the supplied Sharp A/C message. Status: STABLE / Known working. More...
 
bool decodeAiwaRCT501 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kAiwaRcT501Bits, const bool strict=true)
 Decode the supplied Aiwa RC T501 message. Status: BETA / Should work. More...
 
bool decodeNikai (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kNikaiBits, const bool strict=true)
 Decode the supplied Nikai message. Status: STABLE / Working. More...
 
bool decodeMagiQuest (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMagiquestBits, const bool strict=true)
 Decode the supplied MagiQuest message. Status: Beta / Should work. More...
 
bool decodeKelvinator (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kKelvinatorBits, const bool strict=true)
 Decode the supplied Kelvinator message. Status: STABLE / Known working. More...
 
bool decodeDaikin (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikinBits, const bool strict=true)
 Decode the supplied Daikin 280-bit message. (DAIKIN) Status: STABLE / Reported as working. More...
 
bool decodeDaikin64 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikin64Bits, const bool strict=true)
 Decode the supplied Daikin 64-bit message. (DAIKIN64) Status: Beta / Probably Working. More...
 
bool decodeDaikin128 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikin128Bits, const bool strict=true)
 Decode the supplied Daikin 128-bit message. (DAIKIN128) Status: STABLE / Known Working. More...
 
bool decodeDaikin152 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikin152Bits, const bool strict=true)
 Decode the supplied Daikin 152-bit message. (DAIKIN152) Status: STABLE / Known Working. More...
 
bool decodeDaikin160 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikin160Bits, const bool strict=true)
 Decode the supplied Daikin 160-bit message. (DAIKIN160) Status: STABLE / Confirmed working. More...
 
bool decodeDaikin176 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikin176Bits, const bool strict=true)
 Decode the supplied Daikin 176-bit message. (DAIKIN176) Status: STABLE / Expected to work. More...
 
bool decodeDaikin2 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikin2Bits, const bool strict=true)
 Decode the supplied Daikin 312-bit message. (DAIKIN2) Status: STABLE / Works as expected. More...
 
bool decodeDaikin216 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDaikin216Bits, const bool strict=true)
 Decode the supplied Daikin 216-bit message. (DAIKIN216) Status: STABLE / Should be working. More...
 
bool decodeToshibaAC (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbytes=kToshibaACBits, const bool strict=true)
 Decode the supplied Toshiba A/C message. Status: STABLE / Working. More...
 
bool decodeTrotec (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kTrotecBits, const bool strict=true)
 Decode the supplied Trotec message. Status: STABLE / Works. Untested on real devices. More...
 
bool decodeMidea (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMideaBits, const bool strict=true)
 Decode the supplied Midea message. Status: Alpha / Needs testing against a real device. More...
 
bool decodeMidea24 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMidea24Bits, const bool strict=true)
 Decode the supplied Midea24 message. Status: STABLE / Confirmed working on a real device. More...
 
bool decodeFujitsuAC (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kFujitsuAcBits, const bool strict=false)
 Decode the supplied Fujitsu AC IR message if possible. Status: STABLE / Working. More...
 
bool decodeLasertag (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kLasertagBits, const bool strict=true)
 Decode the supplied Lasertag message. Status: BETA / Appears to be working 90% of the time. More...
 
bool decodeCarrierAC (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kCarrierAcBits, const bool strict=true)
 Decode the supplied Carrier HVAC message. More...
 
bool decodeCarrierAC40 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kCarrierAc40Bits, const bool strict=true)
 Decode the supplied Carrier 40-bit HVAC message. Carrier HVAC messages contain only 40 bits, but it is sent three(3) times. Status: STABLE / Tested against a real device. More...
 
bool decodeCarrierAC64 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kCarrierAc64Bits, const bool strict=true)
 Decode the supplied Carrier 64-bit HVAC message. Status: STABLE / Known to be working. More...
 
bool decodeGoodweather (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kGoodweatherBits, const bool strict=true)
 Decode the supplied Goodweather message. Status: BETA / Probably works. More...
 
bool decodeGree (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kGreeBits, const bool strict=true)
 Decode the supplied Gree HVAC message. Status: STABLE / Working. More...
 
bool decodeHaierAC (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kHaierACBits, const bool strict=true)
 Decode the supplied Haier HSU07-HEA03 remote message. Status: STABLE / Known to be working. More...
 
bool decodeHaierACYRW02 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kHaierACYRW02Bits, const bool strict=true)
 Decode the supplied Haier YR-W02 remote A/C message. Status: BETA / Appears to be working. More...
 
bool decodeHitachiAC (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kHitachiAcBits, const bool strict=true, const bool MSBfirst=true)
 Decode the supplied Hitachi A/C message. Status: STABLE / Expected to work. More...
 
bool decodeHitachiAC1 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kHitachiAc1Bits, const bool strict=true)
 
bool decodeHitachiAc3 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kHitachiAc3Bits, const bool strict=true)
 Decode the supplied Hitachi 15to27-byte/120to216-bit A/C message. Status: STABLE / Works fine. More...
 
bool decodeHitachiAc424 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kHitachiAc424Bits, const bool strict=true)
 Decode the supplied Hitachi 53-byte/424-bit A/C message. Status: STABLE / Reported as working. More...
 
bool decodeGICable (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kGicableBits, const bool strict=true)
 Decode the supplied G.I. Cable message. Status: Alpha / Not tested against a real device. More...
 
bool decodeWhirlpoolAC (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kWhirlpoolAcBits, const bool strict=true)
 Decode the supplied Whirlpool A/C message. Status: STABLE / Working as intended. More...
 
bool decodeLutron (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kLutronBits, const bool strict=true)
 Decode the supplied Lutron message. Status: STABLE / Working. More...
 
bool decodeElectraAC (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kElectraAcBits, const bool strict=true)
 Decode the supplied Electra A/C message. Status: STABLE / Known working. More...
 
bool decodePanasonicAC (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kPanasonicAcBits, const bool strict=true)
 Decode the supplied Panasonic AC message. Status: STABLE / Works with real device(s). More...
 
bool decodePioneer (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kPioneerBits, const bool strict=true)
 Decode the supplied Pioneer message. Status: STABLE / Should be working. (Self decodes & real examples) More...
 
bool decodeMWM (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=24, const bool strict=true)
 Decode the supplied MWM message. Status: Implemented. More...
 
bool decodeVestelAc (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kVestelAcBits, const bool strict=true)
 Decode the supplied Vestel message. Status: Alpha / Needs testing against a real device. More...
 
bool decodeTeco (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kTecoBits, const bool strict=false)
 Decode the supplied Teco message. Status: STABLE / Tested. More...
 
bool decodeLegoPf (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kLegoPfBits, const bool strict=true)
 Decode the supplied LEGO Power Functions message. Status: STABLE / Appears to work. More...
 
bool decodeNeoclima (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kNeoclimaBits, const bool strict=true)
 Decode the supplied Neoclima message. Status: STABLE / Known working. More...
 
bool decodeAmcor (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kAmcorBits, const bool strict=true)
 Decode the supplied Amcor HVAC message. Status: STABLE / Reported as working. More...
 
bool decodeEpson (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kEpsonBits, const bool strict=true)
 Decode the supplied Epson message. Status: Beta / Probably works. More...
 
bool decodeSymphony (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSymphonyBits, const bool strict=true)
 Decode the supplied Symphony packet/message. Status: STABLE / Should be working. More...
 
bool decodeAirwell (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kAirwellBits, const bool strict=true)
 Decode the supplied Airwell "Manchester code" message. More...
 
bool decodeDelonghiAc (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDelonghiAcBits, const bool strict=true)
 Decode the supplied Delonghi A/C message. Status: STABLE / Expected to be working. More...
 
bool decodeDoshisha (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kDoshishaBits, const bool strict=true)
 Decode the supplied Doshisha message. Status: STABLE / Works on real device. More...
 
bool decodeMultibrackets (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kMultibracketsBits, const bool strict=true)
 Decode the Multibrackets message. Status: BETA / Appears to be working. More...
 
bool decodeCoronaAc (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kCoronaAcBitsShort, const bool strict=true)
 Decode the supplied CoronaAc message. Status: STABLE / Appears to be working. More...
 
bool decodeZepeal (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kZepealBits, const bool strict=true)
 Decode the supplied Zepeal message. Status: STABLE / Works on real device. More...
 
+ + + + + + + + + +

+Private Attributes

irparams_tirparams_save
 
uint8_t _tolerance
 
uint8_t _timer_num
 
uint16_t _unknown_threshold
 
+

Detailed Description

+

Class for receiving IR messages.

+

Constructor & Destructor Documentation

+ +

◆ IRrecv() [1/2]

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IRrecv::IRrecv (const uint16_t recvpin,
const uint16_t bufsize = kRawBuf,
const uint8_t timeout = kTimeoutMs,
const bool save_buffer = false,
const uint8_t timer_num = kDefaultESP32Timer 
)
+
+explicit
+
+ +

Class constructor Args:

+
Parameters
+ + + + + + +
[in]recvpinThe GPIO pin the IR receiver module's data pin is connected to.
[in]bufsizeNr. of entries to have in the capture buffer. (Default: kRawBuf)
[in]timeoutNr. of milli-Seconds of no signal before we stop capturing data. (Default: kTimeoutMs)
[in]save_bufferUse a second (save) buffer to decode from. (Default: false)
[in]timer_numNr. of the ESP32 timer to use (0 to 3) (ESP32 Only)
+
+
+ +
+
+ +

◆ IRrecv() [2/2]

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IRrecv::IRrecv (const uint16_t recvpin,
const uint16_t bufsize = kRawBuf,
const uint8_t timeout = kTimeoutMs,
const bool save_buffer = false 
)
+
+explicit
+
+ +
+
+ +

◆ ~IRrecv()

+ +
+
+ + + + + + + + +
IRrecv::~IRrecv (void )
+
+ +

Class destructor Cleans up after the object is no longer needed. e.g. Frees up all memory used by the various buffers, and disables any timers or interrupts used.

+ +
+
+

Member Function Documentation

+ +

◆ _matchGeneric()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
uint16_t IRrecv::_matchGeneric (volatile uint16_t * data_ptr,
uint64_t * result_bits_ptr,
uint8_t * result_bytes_ptr,
const bool use_bits,
const uint16_t remaining,
const uint16_t nbits,
const uint16_t hdrmark,
const uint32_t hdrspace,
const uint16_t onemark,
const uint32_t onespace,
const uint16_t zeromark,
const uint32_t zerospace,
const uint16_t footermark,
const uint32_t footerspace,
const bool atleast = false,
const uint8_t tolerance = kUseDefTol,
const int16_t excess = kMarkExcess,
const bool MSBfirst = true 
)
+
+private
+
+ +

Match & decode a generic/typical IR message. The data is stored in result_bits_ptr or result_bytes_ptr depending on flag use_bits.

+
Note
Values of 0 for hdrmark, hdrspace, footermark, or footerspace mean skip that requirement.
+
Parameters
+ + + + + + + + + + + + + + + + + + + +
[in]data_ptrA pointer to where we are at in the capture buffer.
[out]result_bits_ptrA pointer to where to start storing the bits we decoded.
[out]result_bytes_ptrA pointer to where to start storing the bytes we decoded.
[in]use_bitsA flag indicating if we are to decode bits or bytes.
[in]remainingThe size of the capture buffer remaining.
[in]nbitsNr. of data bits we expect.
[in]hdrmarkNr. of uSeconds for the expected header mark signal.
[in]hdrspaceNr. of uSeconds for the expected header space signal.
[in]onemarkNr. of uSeconds in an expected mark signal for a '1' bit.
[in]onespaceNr. of uSecs in an expected space signal for a '1' bit.
[in]zeromarkNr. of uSecs in an expected mark signal for a '0' bit.
[in]zerospaceNr. of uSecs in an expected space signal for a '0' bit.
[in]footermarkNr. of uSeconds for the expected footer mark signal.
[in]footerspaceNr. of uSeconds for the expected footer space/gap signal.
[in]atleastIs the match on the footerspace a matchAtLeast or matchSpace?
[in]tolerancePercentage error margin to allow. (Default: kUseDefTol)
[in]excessNr. of uSeconds. (Def: kMarkExcess)
[in]MSBfirstBit order to save the data in. (Def: true) true is Most Significant Bit First Order, false is Least Significant First
+
+
+
Returns
If successful, how many buffer entries were used. Otherwise 0.
+ +
+
+ +

◆ _validTolerance()

+ +
+
+ + + + + +
+ + + + + + + + +
uint8_t IRrecv::_validTolerance (const uint8_t percentage)
+
+private
+
+ +

Convert the tolerance percentage into something valid.

+
Parameters
+ + +
[in]percentageAn integer percentage.
+
+
+ +
+
+ +

◆ compare()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
uint16_t IRrecv::compare (const uint16_t oldval,
const uint16_t newval 
)
+
+private
+
+ +

Compare two tick values.

+
Parameters
+ + + +
[in]oldvalNr. of ticks.
[in]newvalNr. of ticks.
+
+
+
Returns
0 if newval is shorter, 1 if it is equal, & 2 if it is longer.
+
Note
Use a tolerance of 20%
+ +
+
+ +

◆ copyIrParams()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void IRrecv::copyIrParams (volatile irparams_tsrc,
irparams_tdst 
)
+
+private
+
+ +

Make a copy of the interrupt state & buffer data. Needed because irparams is marked as volatile, thus memcpy() isn't allowed. Only call this when you know the interrupt handlers won't modify anything. i.e. In kStopState.

+
Parameters
+ + + +
[in]srcPointer to an irparams_t structure to copy from.
[out]dstPointer to an irparams_t structure to copy to.
+
+
+ +
+
+ +

◆ crudeNoiseFilter()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void IRrecv::crudeNoiseFilter (decode_resultsresults,
const uint16_t floor = 0 
)
+
+private
+
+ +

Remove or merge pulses in the capture buffer that are too short.

+
Parameters
+ + + +
[in,out]resultsPtr to the decode_results we are going to filter.
[in]floorOnly allow values in the buffer large than this. (in microSeconds)
+
+
+ +
+
+ +

◆ decode()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decode (decode_resultsresults,
irparams_tsave = NULL,
uint8_t max_skip = 0,
uint16_t noise_floor = 0 
)
+
+ +

Decodes the received IR message. If the interrupt state is saved, we will immediately resume waiting for the next IR message to avoid missing messages.

+
Note
There is a trade-off here. Saving the state means less time lost until we can receiving the next message vs. using more RAM. Choose appropriately.
+
Parameters
+ + + + +
[out]resultsA PTR to where the decoded IR message will be stored.
[out]saveA PTR to an irparams_t instance in which to save the interrupt's memory/state. NULL means don't save it.
[in]max_skipMaximum Nr. of pulses at the begining of a capture we can skip when attempting to find a protocol we can successfully decode. This parameter can dramatically improve detection of protocols when there is light IR interference just before an incoming IR message, however, it comes at a steep performace price. (Default is 0. No skipping.)
+
+
+
Warning
Increasing the max_skip value will dramatically (linearly) increase the cpu time & usage to decode protocols. e.g. 0 -> 1 will be a 2x increase in cpu usage/time. 0 -> 2 will be a 3x increase etc. If you are going to do this, consider disabling protocol decoding for protocols you are not expecting.
+
Parameters
+ + +
[in]noise_floorPulses below this size (in usecs) will be removed or merged prior to any decoding. This is to try to remove noise/poor readings & slighly increase the chances of a successful decode but at the cost of data fidelity & integrity. (Defaults to 0 usecs. i.e. Don't filter; which is safe!)
+
+
+
Warning
DANGER: Here Be Dragons! If you set the noise_floor value too high, it WILL break decoding of some protocols. You have been warned! Any non-zero value has the potential to cook the captured raw data i.e. The raw data is going to lie to you. It may obscure hardware, circuit, & environment issues thus making it impossible to support you accurately or confidently. Values of <= 50 usecs will probably be safe. 51 - 100 usecs might be okay. 100 - 150 usecs is "Danger, Will Robinson!". 150 - 200 usecs expect broken protocols. At 200+ usecs, you have protocols you can't decode!!
+
Returns
A boolean indicating if an IR message is ready or not.
+ +
+
+ +

◆ decodeAirwell()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeAirwell (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kAirwellBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Airwell "Manchester code" message.

+

Status: BETA / Appears to be working.

Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/1069
+ +
+
+ +

◆ decodeAiwaRCT501()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeAiwaRCT501 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kAiwaRcT501Bits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Aiwa RC T501 message. Status: BETA / Should work.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+
Note
Aiwa RC T501 appears to be a 42 bit variant of the NEC1 protocol. However, we historically (original Arduino IRremote project) treats it as a 15 bit (data) protocol. So, we expect nbits to typically be 15, and we will remove the prefix and postfix from the raw data, and use that as the result.
+
See also
http://www.sbprojects.com/knowledge/ir/nec.php
+
+https://github.com/crankyoldgit/IRremoteESP8266/issues/1069
+ +
+
+ +

◆ decodeAmcor()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeAmcor (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kAmcorBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Amcor HVAC message. Status: STABLE / Reported as working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeArgo()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeArgo (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kArgoBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Argo message. Status: BETA / Probably works.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+
Note
This decoder is based soley off sendArgo(). We have no actual captures to test this against. If you have one of these units, please let us know.
+ +
+
+ +

◆ decodeCarrierAC()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeCarrierAC (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kCarrierAcBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Carrier HVAC message.

+
Note
Carrier HVAC messages contain only 32 bits, but it is sent three(3) times. i.e. normal + inverted + normal Status: BETA / Probably works.
+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeCarrierAC40()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeCarrierAC40 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kCarrierAc40Bits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Carrier 40-bit HVAC message. Carrier HVAC messages contain only 40 bits, but it is sent three(3) times. Status: STABLE / Tested against a real device.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeCarrierAC64()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeCarrierAC64 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kCarrierAc64Bits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Carrier 64-bit HVAC message. Status: STABLE / Known to be working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeCOOLIX()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeCOOLIX (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kCoolixBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Coolix A/C message. Status: STABLE / Known Working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeCoronaAc()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeCoronaAc (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kCoronaAcBitsShort,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied CoronaAc message. Status: STABLE / Appears to be working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store it
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeDaikin()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeDaikin (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kDaikinBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Daikin 280-bit message. (DAIKIN) Status: STABLE / Reported as working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+
See also
https://github.com/mharizanov/Daikin-AC-remote-control-over-the-Internet/tree/master/IRremote
+ +
+
+ +

◆ decodeDaikin128()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeDaikin128 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kDaikin128Bits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Daikin 128-bit message. (DAIKIN128) Status: STABLE / Known Working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/827
+ +
+
+ +

◆ decodeDaikin152()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeDaikin152 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kDaikin152Bits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Daikin 152-bit message. (DAIKIN152) Status: STABLE / Known Working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/873
+ +
+
+ +

◆ decodeDaikin160()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeDaikin160 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kDaikin160Bits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Daikin 160-bit message. (DAIKIN160) Status: STABLE / Confirmed working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/731
+ +
+
+ +

◆ decodeDaikin176()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeDaikin176 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kDaikin176Bits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Daikin 176-bit message. (DAIKIN176) Status: STABLE / Expected to work.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeDaikin2()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeDaikin2 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kDaikin2Bits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Daikin 312-bit message. (DAIKIN2) Status: STABLE / Works as expected.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeDaikin216()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeDaikin216 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kDaikin216Bits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Daikin 216-bit message. (DAIKIN216) Status: STABLE / Should be working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/689
+
+https://github.com/danny-source/Arduino_DY_IRDaikin
+ +
+
+ +

◆ decodeDaikin64()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeDaikin64 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kDaikin64Bits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Daikin 64-bit message. (DAIKIN64) Status: Beta / Probably Working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/1064
+ +
+
+ +

◆ decodeDelonghiAc()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeDelonghiAc (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kDelonghiAcBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Delonghi A/C message. Status: STABLE / Expected to be working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/1096
+ +
+
+ +

◆ decodeDenon()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeDenon (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kDenonBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Delonghi A/C message. Status: STABLE / Should work fine.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+
See also
https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Denon.cpp
+ +
+
+ +

◆ decodeDISH()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeDISH (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kDishBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied DISH NETWORK message. Status: ALPHA (untested and unconfirmed.)

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+
Note
Dishplayer is a different protocol. Typically a DISH device needs to get a command a total of at least 4 times to accept it.
+
See also
http://www.hifi-remote.com/wiki/index.php?title=Dish
+
+http://lirc.sourceforge.net/remotes/echostar/301_501_3100_5100_58xx_59xx
+
+https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Dish.cpp
+ +
+
+ +

◆ decodeDoshisha()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeDoshisha (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kDoshishaBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Doshisha message. Status: STABLE / Works on real device.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeElectraAC()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeElectraAC (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kElectraAcBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Electra A/C message. Status: STABLE / Known working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeEpson()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeEpson (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kEpsonBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Epson message. Status: Beta / Probably works.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+
Note
Experimental data indicates there are at least three messages (first + 2 repeats). We only require the first + a single repeat to match. This helps us distinguish it from NEC messages which are near identical.
+ +
+
+ +

◆ decodeFujitsuAC()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeFujitsuAC (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kFujitsuAcBits,
const bool strict = false 
)
+
+private
+
+ +

Decode the supplied Fujitsu AC IR message if possible. Status: STABLE / Working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeGICable()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeGICable (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kGicableBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied G.I. Cable message. Status: Alpha / Not tested against a real device.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeGoodweather()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeGoodweather (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kGoodweatherBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Goodweather message. Status: BETA / Probably works.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeGree()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeGree (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kGreeBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Gree HVAC message. Status: STABLE / Working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeHaierAC()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeHaierAC (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kHaierACBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Haier HSU07-HEA03 remote message. Status: STABLE / Known to be working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeHaierACYRW02()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeHaierACYRW02 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kHaierACYRW02Bits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Haier YR-W02 remote A/C message. Status: BETA / Appears to be working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeHash()

+ +
+
+ + + + + +
+ + + + + + + + +
bool IRrecv::decodeHash (decode_resultsresults)
+
+private
+
+ +

Decode any arbitrary IR message into a 32-bit code value. Instead of decoding using a standard encoding scheme (e.g. Sony, NEC, RC5), the code is hashed to a 32-bit value.

+

The algorithm: look at the sequence of MARK signals, and see if each one is shorter (0), the same length (1), or longer (2) than the previous. Do the same with the SPACE signals. Hash the resulting sequence of 0's, 1's, and 2's to a 32-bit value. This will give a unique value for each different code (probably), for most code systems.

See also
http://arcfn.com/2010/01/using-arbitrary-remotes-with-arduino.html
+
Note
This isn't a "real" decoding, just an arbitrary value. Hopefully this code is unique for each button.
+ +
+
+ +

◆ decodeHitachiAC()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeHitachiAC (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kHitachiAcBits,
const bool strict = true,
const bool MSBfirst = true 
)
+
+private
+
+ +

Decode the supplied Hitachi A/C message. Status: STABLE / Expected to work.

+
Parameters
+ + + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect. Typically kHitachiAcBits, kHitachiAc1Bits, kHitachiAc2Bits, kHitachiAc344Bits
[in]strictFlag indicating if we should perform strict matching.
[in]MSBfirstIs the data per byte stored in MSB First (true) or LSB First order(false)?
+
+
+
Returns
True if it can decode it, false if it can't.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/417
+
+https://github.com/crankyoldgit/IRremoteESP8266/issues/453
+
+https://github.com/crankyoldgit/IRremoteESP8266/issues/1134
+ +
+
+ +

◆ decodeHitachiAC1()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeHitachiAC1 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kHitachiAc1Bits,
const bool strict = true 
)
+
+private
+
+ +
+
+ +

◆ decodeHitachiAc3()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeHitachiAc3 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kHitachiAc3Bits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Hitachi 15to27-byte/120to216-bit A/C message. Status: STABLE / Works fine.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+
Note
This protocol is almost exactly the same as HitachiAC424 except this variant has subtle timing differences and multiple lengths. There are five(5) typical lengths: kHitachiAc3MinStateLength (Cancel Timer), kHitachiAc3MinStateLength + 2 (Change Temp), kHitachiAc3StateLength - 6 (Change Mode), kHitachiAc3StateLength - 4 (Normal), & kHitachiAc3StateLength (Set Timer)
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/1060
+ +
+
+ +

◆ decodeHitachiAc424()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeHitachiAc424 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kHitachiAc424Bits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Hitachi 53-byte/424-bit A/C message. Status: STABLE / Reported as working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+
Note
This protocol is almost exactly the same as HitachiAC2 except this variant has a leader section as well, and subtle timing differences. It is also in LSBF order (per byte), rather than MSBF order.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/973
+
+(Japanese Manual) https://kadenfan.hitachi.co.jp/support/raj/item/docs/ras_aj22h_a_tori.pdf
+ +
+
+ +

◆ decodeInax()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeInax (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kInaxBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Inax Toilet message. Status: Stable / Known working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/706
+ +
+
+ +

◆ decodeJVC()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeJVC (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kJvcBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied JVC message. Status: Stable / Known working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+
Note
JVC repeat codes don't have a header.
+
See also
http://www.sbprojects.com/knowledge/ir/jvc.php
+ +
+
+ +

◆ decodeKelvinator()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeKelvinator (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kKelvinatorBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Kelvinator message. Status: STABLE / Known working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeLasertag()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeLasertag (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kLasertagBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Lasertag message. Status: BETA / Appears to be working 90% of the time.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+
Note
This protocol is pretty much just raw Manchester encoding.
+
See also
http://www.sbprojects.com/knowledge/ir/rc5.php
+
+https://en.wikipedia.org/wiki/RC-5
+
+https://en.wikipedia.org/wiki/Manchester_code
+
Todo:
Convert to using matchManchester() if we can.
+ +
+
+ +

◆ decodeLegoPf()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeLegoPf (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kLegoPfBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied LEGO Power Functions message. Status: STABLE / Appears to work.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeLG()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeLG (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kLgBits,
const bool strict = false 
)
+
+private
+
+ +

Decode the supplied LG message. Status: STABLE / Working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect. Typically kLgBits or kLg32Bits.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+
Note
LG protocol has a repeat code which is 4 items long. Even though the protocol has 28/32 bits of data, only 24/28 bits are distinct. In transmission order, the 28/32 bits are constructed as follows: 8/12 bits of address + 16 bits of command + 4 bits of checksum.
+
+LG 32bit protocol appears near identical to the Samsung protocol. They possibly differ on how they repeat and initial HDR mark.
+
See also
https://funembedded.wordpress.com/2014/11/08/ir-remote-control-for-lg-conditioner-using-stm32f302-mcu-on-mbed-platform/
+ +
+
+ +

◆ decodeLutron()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeLutron (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kLutronBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Lutron message. Status: STABLE / Working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeMagiQuest()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeMagiQuest (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kMagiquestBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied MagiQuest message. Status: Beta / Should work.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+
Note
MagiQuest protocol appears to be a header of 8 'zero' bits, followed by 32 bits of "wand ID" and finally 16 bits of "magnitude". Even though we describe this protocol as 56 bits, it really only has 48 bits of data that matter. In transmission order, 8 zeros + 32 wand_id + 16 magnitude.
+
See also
https://github.com/kitlaan/Arduino-IRremote/blob/master/ir_Magiquest.cpp
+ +
+
+ +

◆ decodeMidea()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeMidea (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kMideaBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Midea message. Status: Alpha / Needs testing against a real device.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect. Typically kHitachiAcBits, kHitachiAc1Bits, kHitachiAc2Bits, kHitachiAc344Bits
[in]strictFlag indicating if we should perform strict matching.
+
+
+ +
+
+ +

◆ decodeMidea24()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeMidea24 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kMidea24Bits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Midea24 message. Status: STABLE / Confirmed working on a real device.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+
Note
This protocol is basically a 48-bit version of the NEC protocol with alternate bytes inverted, thus only 24 bits of real data.
+
Warning
Can't be used beyond 32 bits.
+ +
+
+ +

◆ decodeMitsubishi()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeMitsubishi (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kMitsubishiBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Mitsubishi 16-bit message. Status: STABLE / Working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+
Note
This protocol appears to have no header.
+
See also
GlobalCache's Control Tower's Mitsubishi TV data.
+ +
+
+ +

◆ decodeMitsubishi112()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeMitsubishi112 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kMitsubishi112Bits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Mitsubishi/TCL 112-bit A/C message. (MITSUBISHI112, TCL112AC) Status: STABLE / Reported as working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Note
Note Mitsubishi112 & Tcl112Ac are basically the same protocol. The only significant difference I can see is Mitsubishi112 has a slightly longer header mark. We will use that to determine which variant it should be. The other differences require full decoding and only only with certain settings. There are some other timing differences too, but the tolerances will overlap.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/619
+
+https://github.com/crankyoldgit/IRremoteESP8266/issues/947
+ +
+
+ +

◆ decodeMitsubishi136()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeMitsubishi136 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kMitsubishi136Bits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Mitsubishi 136-bit A/C message. (MITSUBISHI136) Status: STABLE / Reported as working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/888
+ +
+
+ +

◆ decodeMitsubishi2()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeMitsubishi2 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kMitsubishiBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied second variation of a Mitsubishi 16-bit message. Status: STABLE / Working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/441
+ +
+
+ +

◆ decodeMitsubishiAC()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeMitsubishiAC (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kMitsubishiACBits,
const bool strict = false 
)
+
+private
+
+ +

Decode the supplied Mitsubish 144-bit A/C message. Status: BETA / Probably works.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
See also
https://www.analysir.com/blog/2015/01/06/reverse-engineering-mitsubishi-ac-infrared-protocol/
+ +
+
+ +

◆ decodeMitsubishiHeavy()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeMitsubishiHeavy (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kMitsubishiHeavy152Bits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Mitsubishi Heavy Industries A/C message. Status: BETA / Appears to be working. Needs testing against a real device.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect. Typically kMitsubishiHeavy88Bits or kMitsubishiHeavy152Bits (def).
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeMultibrackets()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeMultibrackets (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kMultibracketsBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the Multibrackets message. Status: BETA / Appears to be working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeMWM()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeMWM (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = 24,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied MWM message. Status: Implemented.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+
Note
This protocol is 2400 bps serial, 1 start bit (mark), 1 stop bit (space), no parity
+ +
+
+ +

◆ decodeNEC()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeNEC (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kNECBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied NEC (Renesas) message. Status: STABLE / Known good.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+
Note
NEC protocol has three variants/forms. Normal: an 8 bit address & an 8 bit command in 32 bit data form. i.e. address + inverted(address) + command + inverted(command) Extended: a 16 bit address & an 8 bit command in 32 bit data form. i.e. address + command + inverted(command) Repeat: a 0-bit code. i.e. No data bits. Just the header + footer.
+
See also
http://www.sbprojects.com/knowledge/ir/nec.php
+ +
+
+ +

◆ decodeNeoclima()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeNeoclima (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kNeoclimaBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Neoclima message. Status: STABLE / Known working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeNikai()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeNikai (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kNikaiBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Nikai message. Status: STABLE / Working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+ +
+
+ +

◆ decodePanasonic()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodePanasonic (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kPanasonicBits,
const bool strict = false,
const uint32_t manufacturer = kPanasonicManufacturer 
)
+
+private
+
+ +

Decode the supplied Panasonic message. Status: STABLE / Should be working.

+
Parameters
+ + + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]manufacturerA 16-bit manufacturer code. e.g. 0x4004 is Panasonic
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+
Warning
Results to be used with sendPanasonic64(), not sendPanasonic().
+
Note
Panasonic 48-bit protocol is a modified version of Kaseikyo.
+
See also
http://www.remotecentral.com/cgi-bin/mboard/rc-pronto/thread.cgi?2615
+
+http://www.hifi-remote.com/wiki/index.php?title=Panasonic
+ +
+
+ +

◆ decodePanasonicAC()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodePanasonicAC (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kPanasonicAcBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Panasonic AC message. Status: STABLE / Works with real device(s).

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodePioneer()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodePioneer (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kPioneerBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Pioneer message. Status: STABLE / Should be working. (Self decodes & real examples)

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeRC5()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeRC5 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kRC5XBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied RC-5/RC5X message. Status: RC-5 (stable), RC-5X (alpha)

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+
Note
The 'toggle' bit is included as the 6th (MSB) address bit, the MSB of data, & in the count of bits decoded.
+
Todo:
Serious testing of the RC-5X and strict aspects needs to be done.
+ +
+
+ +

◆ decodeRC6()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeRC6 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kRC6Mode0Bits,
const bool strict = false 
)
+
+private
+
+ +

Decode the supplied RC6 message. Status: Stable.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+
Todo:
Testing of the strict compliance aspects.
+ +
+
+ +

◆ decodeRCMM()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeRCMM (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kRCMMBits,
const bool strict = false 
)
+
+private
+
+ +

Decode a Philips RC-MM packet (between 12 & 32 bits) if possible. Status: STABLE / Should be working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeSAMSUNG()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeSAMSUNG (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kSamsungBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Samsung 32-bit message. Status: STABLE.

+
Note
Samsung messages whilst 32 bits in size, only contain 16 bits of distinct data. e.g. In transmition order: customer_byte + customer_byte(same) + address_byte + invert(address_byte)
+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+
Note
LG 32bit protocol appears near identical to the Samsung protocol. They differ on their compliance criteria and how they repeat.
+
See also
http://elektrolab.wz.cz/katalog/samsung_protocol.pdf
+ +
+
+ +

◆ decodeSamsung36()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeSamsung36 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kSamsung36Bits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Samsung36 message. Status: Alpha / Experimental.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/621
+ +
+
+ +

◆ decodeSamsungAC()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeSamsungAC (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kSamsungAcBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Samsung A/C message. Status: Stable / Known to be working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/505
+ +
+
+ +

◆ decodeSanyoLC7461()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeSanyoLC7461 (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kSanyoLC7461Bits,
bool strict = true 
)
+
+private
+
+ +

Decode the supplied SANYO LC7461 message. Status: BETA / Probably works.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+
Note
Based on @marcosamarinho's work. This protocol uses the NEC protocol. However, data is formatted as : address(13 bits), !address, command (8 bits), !command. According with LIRC, this protocol is used on Sanyo, Aiwa and Chinon Information for this protocol is available at the Sanyo LC7461 datasheet.
+
See also
http://slydiman.narod.ru/scr/kb/sanyo.htm
+
+https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Sanyo.cpp
+
+http://pdf.datasheetcatalog.com/datasheet/sanyo/LC7461.pdf
+ +
+
+ +

◆ decodeSharp()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeSharp (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kSharpBits,
const bool strict = true,
const bool expansion = true 
)
+
+private
+
+ +

Decode the supplied Sharp message. Status: STABLE / Working fine.

+
Parameters
+ + + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
[in]expansionShould we expect the expansion bit to be set. Default is true.
+
+
+
Returns
True if it can decode it, false if it can't.
+
Note
This procedure returns a value suitable for use in sendSharpRaw().
+
Todo:
Need to ensure capture of the inverted message as it can be missed due to the interrupt timeout used to detect an end of message. Several compliance checks are disabled until that is resolved.
+ +
+
+ +

◆ decodeSharpAc()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeSharpAc (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kSharpAcBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Sharp A/C message. Status: STABLE / Known working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/638
+
+https://github.com/ToniA/arduino-heatpumpir/blob/master/SharpHeatpumpIR.cpp
+ +
+
+ +

◆ decodeSony()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeSony (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kSonyMinBits,
const bool strict = false 
)
+
+private
+
+ +

Decode the supplied Sony/SIRC message. Status: STABLE / Should be working. strict mode is ALPHA / Untested.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+
Note
SONY protocol, SIRC (Serial Infra-Red Control) can be 12, 15, or 20 bits long.
+ +
+
+ +

◆ decodeSymphony()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeSymphony (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kSymphonyBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Symphony packet/message. Status: STABLE / Should be working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeTeco()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeTeco (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kTecoBits,
const bool strict = false 
)
+
+private
+
+ +

Decode the supplied Teco message. Status: STABLE / Tested.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeToshibaAC()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeToshibaAC (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kToshibaACBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Toshiba A/C message. Status: STABLE / Working.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeTrotec()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeTrotec (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kTrotecBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Trotec message. Status: STABLE / Works. Untested on real devices.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeVestelAc()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeVestelAc (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kVestelAcBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Vestel message. Status: Alpha / Needs testing against a real device.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeWhirlpoolAC()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeWhirlpoolAC (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kWhirlpoolAcBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Whirlpool A/C message. Status: STABLE / Working as intended.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+ +
+
+ +

◆ decodeWhynter()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeWhynter (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kWhynterBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Whynter message. Status: STABLE / Working. Strict mode is ALPHA.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the result
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
True if it can decode it, false if it can't.
+
See also
https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Whynter.cpp
+ +
+
+ +

◆ decodeZepeal()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::decodeZepeal (decode_resultsresults,
uint16_t offset = kStartOffset,
const uint16_t nbits = kZepealBits,
const bool strict = true 
)
+
+private
+
+ +

Decode the supplied Zepeal message. Status: STABLE / Works on real device.

+
Parameters
+ + + + + +
[in,out]resultsPtr to the data to decode & where to store the decode result.
[in]offsetThe starting index to use when attempting to decode the raw data. Typically/Defaults to kStartOffset.
[in]nbitsThe number of data bits to expect. Typically kZepealBits.
[in]strictFlag indicating if we should perform strict matching.
+
+
+
Returns
A boolean. True if it can decode it, false if it can't.
+ +
+
+ +

◆ disableIRIn()

+ +
+
+ + + + + + + + +
void IRrecv::disableIRIn (void )
+
+ +

Stop collection of any received IR data. Disable any timers and interrupts.

+ +
+
+ +

◆ enableIRIn()

+ +
+
+ + + + + + + + +
void IRrecv::enableIRIn (const bool pullup = false)
+
+ +

Set up and (re)start the IR capture mechanism.

+
Parameters
+ + +
[in]pullupA flag indicating should the GPIO use the internal pullup resistor. (Default: false. i.e. No.)
+
+
+ +
+
+ +

◆ getBufSize()

+ +
+
+ + + + + + + + +
uint16_t IRrecv::getBufSize (void )
+
+ +

Obtain the maximum number of entries possible in the capture buffer. i.e. It's size.

+
Returns
The size of the buffer that is in use by the object.
+ +
+
+ +

◆ getRClevel()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
int16_t IRrecv::getRClevel (decode_resultsresults,
uint16_t * offset,
uint16_t * used,
uint16_t bitTime,
const uint8_t tolerance = kUseDefTol,
const int16_t excess = kMarkExcess,
const uint16_t delta = 0,
const uint8_t maxwidth = 3 
)
+
+private
+
+ +

Gets one undecoded level at a time from the raw buffer. The RC5/6 decoding is easier if the data is broken into time intervals. E.g. if the buffer has MARK for 2 time intervals and SPACE for 1, successive calls to getRClevel will return MARK, MARK, SPACE. offset and used are updated to keep track of the current position.

+
Parameters
+ + + + + + + + + +
[in,out]resultsPtr to the data to decode and where to store the decode result.
[in,out]offsetPtr to the currect offset to the rawbuf.
[in,out]usedPtr to the current used counter.
[in]bitTimeTime interval of single bit in microseconds.
[in]tolerancePercent tolerance to be used in matching.
[in]excessExtra useconds to add to Marks & removed from Spaces.
[in]deltaA non-scaling (+/-) error margin (in useconds).
[in]maxwidthMaximum number of successive levels to find in a single level (default is 3)
+
+
+
Returns
MARK, SPACE, or -1 for error. (The measured time interval is not a multiple of t1.)
+
See also
https://en.wikipedia.org/wiki/Manchester_code
+ +
+
+ +

◆ getTolerance()

+ +
+
+ + + + + + + + +
uint8_t IRrecv::getTolerance (void )
+
+ +

Get the base tolerance percentage for matching incoming IR messages.

+
Returns
A integer percentage.
+ +
+
+ +

◆ match()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::match (const uint32_t measured,
const uint32_t desired,
const uint8_t tolerance = kUseDefTol,
const uint16_t delta = 0 
)
+
+ +

Check if we match a pulse(measured) with the desired within +/-tolerance percent and/or +/- a fixed delta range.

+
Parameters
+ + + + + +
[in]measuredThe recorded period of the signal pulse.
[in]desiredThe expected period (in usecs) we are matching against.
[in]toleranceA percentage expressed as an integer. e.g. 10 is 10%.
[in]deltaA non-scaling (+/-) error margin (in useconds).
+
+
+
Returns
A Boolean. true if it matches, false if it doesn't.
+ +
+
+ +

◆ matchAtLeast()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::matchAtLeast (const uint32_t measured,
const uint32_t desired,
const uint8_t tolerance = kUseDefTol,
const uint16_t delta = 0 
)
+
+private
+
+ +

Check if we match a pulse(measured) of at least desired within tolerance percent and/or a fixed delta margin.

+
Parameters
+ + + + + +
[in]measuredThe recorded period of the signal pulse.
[in]desiredThe expected period (in usecs) we are matching against.
[in]toleranceA percentage expressed as an integer. e.g. 10 is 10%.
[in]deltaA non-scaling amount to reduce usecs by.
+
+
+
Returns
A Boolean. true if it matches, false if it doesn't.
+ +
+
+ +

◆ matchBytes()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
uint16_t IRrecv::matchBytes (volatile uint16_t * data_ptr,
uint8_t * result_ptr,
const uint16_t remaining,
const uint16_t nbytes,
const uint16_t onemark,
const uint32_t onespace,
const uint16_t zeromark,
const uint32_t zerospace,
const uint8_t tolerance = kUseDefTol,
const int16_t excess = kMarkExcess,
const bool MSBfirst = true 
)
+
+private
+
+ +

Match & decode the typical data section of an IR message. The bytes are stored at result_ptr. The first byte in the result equates to the first byte encountered, and so on.

+
Parameters
+ + + + + + + + + + + + +
[in]data_ptrA pointer to where we are at in the capture buffer.
[out]result_ptrA ptr to where to start storing the bytes we decoded.
[in]remainingThe size of the capture buffer remaining.
[in]nbytesNr. of data bytes we expect.
[in]onemarkNr. of uSeconds in an expected mark signal for a '1' bit.
[in]onespaceNr. of uSecs in an expected space signal for a '1' bit.
[in]zeromarkNr. of uSecs in an expected mark signal for a '0' bit.
[in]zerospaceNr. of uSecs in an expected space signal for a '0' bit.
[in]tolerancePercentage error margin to allow. (Default: kUseDefTol)
[in]excessNr. of uSeconds. (Def: kMarkExcess)
[in]MSBfirstBit order to save the data in. (Def: true) true is Most Significant Bit First Order, false is Least Significant First
+
+
+
Returns
If successful, how many buffer entries were used. Otherwise 0.
+ +
+
+ +

◆ matchData()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
match_result_t IRrecv::matchData (volatile uint16_t * data_ptr,
const uint16_t nbits,
const uint16_t onemark,
const uint32_t onespace,
const uint16_t zeromark,
const uint32_t zerospace,
const uint8_t tolerance = kUseDefTol,
const int16_t excess = kMarkExcess,
const bool MSBfirst = true 
)
+
+private
+
+ +

Match & decode the typical data section of an IR message. The data value is stored in the least significant bits reguardless of the bit ordering requested.

+
Parameters
+ + + + + + + + + + +
[in]data_ptrA pointer to where we are at in the capture buffer.
[in]nbitsNr. of data bits we expect.
[in]onemarkNr. of uSeconds in an expected mark signal for a '1' bit.
[in]onespaceNr. of uSecs in an expected space signal for a '1' bit.
[in]zeromarkNr. of uSecs in an expected mark signal for a '0' bit.
[in]zerospaceNr. of uSecs in an expected space signal for a '0' bit.
[in]tolerancePercentage error margin to allow. (Default: kUseDefTol)
[in]excessNr. of uSeconds. (Def: kMarkExcess)
[in]MSBfirstBit order to save the data in. (Def: true) true is Most Significant Bit First Order, false is Least Significant First
+
+
+
Returns
A match_result_t structure containing the success (or not), the data value, and how many buffer entries were used.
+ +
+
+ +

◆ matchGeneric() [1/2]

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
uint16_t IRrecv::matchGeneric (volatile uint16_t * data_ptr,
uint64_t * result_ptr,
const uint16_t remaining,
const uint16_t nbits,
const uint16_t hdrmark,
const uint32_t hdrspace,
const uint16_t onemark,
const uint32_t onespace,
const uint16_t zeromark,
const uint32_t zerospace,
const uint16_t footermark,
const uint32_t footerspace,
const bool atleast = false,
const uint8_t tolerance = kUseDefTol,
const int16_t excess = kMarkExcess,
const bool MSBfirst = true 
)
+
+private
+
+ +

Match & decode a generic/typical <= 64bit IR message. The data is stored at result_ptr.

+
Note
Values of 0 for hdrmark, hdrspace, footermark, or footerspace mean skip that requirement.
+
Parameters
+ + + + + + + + + + + + + + + + + +
[in]data_ptrA pointer to where we are at in the capture buffer.
[out]result_ptrA ptr to where to start storing the bits we decoded.
[in]remainingThe size of the capture buffer remaining.
[in]nbitsNr. of data bits we expect.
[in]hdrmarkNr. of uSeconds for the expected header mark signal.
[in]hdrspaceNr. of uSeconds for the expected header space signal.
[in]onemarkNr. of uSeconds in an expected mark signal for a '1' bit.
[in]onespaceNr. of uSecs in an expected space signal for a '1' bit.
[in]zeromarkNr. of uSecs in an expected mark signal for a '0' bit.
[in]zerospaceNr. of uSecs in an expected space signal for a '0' bit.
[in]footermarkNr. of uSeconds for the expected footer mark signal.
[in]footerspaceNr. of uSeconds for the expected footer space/gap signal.
[in]atleastIs the match on the footerspace a matchAtLeast or matchSpace?
[in]tolerancePercentage error margin to allow. (Default: kUseDefTol)
[in]excessNr. of uSeconds. (Def: kMarkExcess)
[in]MSBfirstBit order to save the data in. (Def: true) true is Most Significant Bit First Order, false is Least Significant First
+
+
+
Returns
If successful, how many buffer entries were used. Otherwise 0.
+ +
+
+ +

◆ matchGeneric() [2/2]

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
uint16_t IRrecv::matchGeneric (volatile uint16_t * data_ptr,
uint8_t * result_ptr,
const uint16_t remaining,
const uint16_t nbits,
const uint16_t hdrmark,
const uint32_t hdrspace,
const uint16_t onemark,
const uint32_t onespace,
const uint16_t zeromark,
const uint32_t zerospace,
const uint16_t footermark,
const uint32_t footerspace,
const bool atleast = false,
const uint8_t tolerance = kUseDefTol,
const int16_t excess = kMarkExcess,
const bool MSBfirst = true 
)
+
+private
+
+ +

Match & decode a generic/typical > 64bit IR message. The bytes are stored at result_ptr. The first byte in the result equates to the first byte encountered, and so on.

+
Note
Values of 0 for hdrmark, hdrspace, footermark, or footerspace mean skip that requirement.
+
Parameters
+ + + + + + + + + + + + + + + + + +
[in]data_ptrA pointer to where we are at in the capture buffer.
[out]result_ptrA ptr to where to start storing the bytes we decoded.
[in]remainingThe size of the capture buffer remaining.
[in]nbitsNr. of data bits we expect.
[in]hdrmarkNr. of uSeconds for the expected header mark signal.
[in]hdrspaceNr. of uSeconds for the expected header space signal.
[in]onemarkNr. of uSeconds in an expected mark signal for a '1' bit.
[in]onespaceNr. of uSecs in an expected space signal for a '1' bit.
[in]zeromarkNr. of uSecs in an expected mark signal for a '0' bit.
[in]zerospaceNr. of uSecs in an expected space signal for a '0' bit.
[in]footermarkNr. of uSeconds for the expected footer mark signal.
[in]footerspaceNr. of uSeconds for the expected footer space/gap signal.
[in]atleastIs the match on the footerspace a matchAtLeast or matchSpace?
[in]tolerancePercentage error margin to allow. (Default: kUseDefTol)
[in]excessNr. of uSeconds. (Def: kMarkExcess)
[in]MSBfirstBit order to save the data in. (Def: true) true is Most Significant Bit First Order, false is Least Significant First
+
+
+
Returns
If successful, how many buffer entries were used. Otherwise 0.
+ +
+
+ +

◆ matchGenericConstBitTime()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
uint16_t IRrecv::matchGenericConstBitTime (volatile uint16_t * data_ptr,
uint64_t * result_ptr,
const uint16_t remaining,
const uint16_t nbits,
const uint16_t hdrmark,
const uint32_t hdrspace,
const uint16_t one,
const uint32_t zero,
const uint16_t footermark,
const uint32_t footerspace,
const bool atleast = false,
const uint8_t tolerance = kUseDefTol,
const int16_t excess = kMarkExcess,
const bool MSBfirst = true 
)
+
+private
+
+ +

Match & decode a generic/typical constant bit time <= 64bit IR message. The data is stored at result_ptr.

+
Note
Values of 0 for hdrmark, hdrspace, footermark, or footerspace mean skip that requirement.
+
Parameters
+ + +
[in]data_ptrA pointer to where we are at in the capture buffer.
+
+
+
Note
data_ptr is assumed to be pointing to a "Mark", not a "Space".
+
Parameters
+ + + + + + + + + + + + + + +
[out]result_ptrA ptr to where to start storing the bits we decoded.
[in]remainingThe size of the capture buffer remaining.
[in]nbitsNr. of data bits we expect.
[in]hdrmarkNr. of uSeconds for the expected header mark signal.
[in]hdrspaceNr. of uSeconds for the expected header space signal.
[in]oneNr. of uSeconds in an expected mark signal for a '1' bit.
[in]zeroNr. of uSeconds in an expected mark signal for a '0' bit.
[in]footermarkNr. of uSeconds for the expected footer mark signal.
[in]footerspaceNr. of uSeconds for the expected footer space/gap signal.
[in]atleastIs the match on the footerspace a matchAtLeast or matchSpace?
[in]tolerancePercentage error margin to allow. (Default: kUseDefTol)
[in]excessNr. of uSeconds. (Def: kMarkExcess)
[in]MSBfirstBit order to save the data in. (Def: true) true is Most Significant Bit First Order, false is Least Significant First
+
+
+
Returns
If successful, how many buffer entries were used. Otherwise 0.
+
Note
Parameters one + zero add up to the total time for a bit. e.g. mark(one) + space(zero) is a 1, mark(zero) + space(one) is a 0.
+ +
+
+ +

◆ matchManchester()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
uint16_t IRrecv::matchManchester (volatile const uint16_t * data_ptr,
uint64_t * result_ptr,
const uint16_t remaining,
const uint16_t nbits,
const uint16_t hdrmark,
const uint32_t hdrspace,
const uint16_t half_period,
const uint16_t footermark,
const uint32_t footerspace,
const bool atleast = false,
const uint8_t tolerance = kUseDefTol,
const int16_t excess = kMarkExcess,
const bool MSBfirst = true,
const bool GEThomas = true 
)
+
+private
+
+ +

Match & decode a Manchester Code <= 64bit IR message. The data is stored at result_ptr.

+
Note
Values of 0 for hdrmark, hdrspace, footermark, or footerspace mean skip that requirement.
+
Parameters
+ + +
[in]data_ptrA pointer to where we are at in the capture buffer.
+
+
+
Note
data_ptr is assumed to be pointing to a "Mark", not a "Space".
+
Parameters
+ + + + + + + + + + + + + + +
[out]result_ptrA ptr to where to start storing the bits we decoded.
[in]remainingThe size of the capture buffer remaining.
[in]nbitsNr. of data bits we expect.
[in]hdrmarkNr. of uSeconds for the expected header mark signal.
[in]hdrspaceNr. of uSeconds for the expected header space signal.
[in]half_periodNr. of uSeconds for half the clock's period. i.e. 1/2 wavelength
[in]footermarkNr. of uSeconds for the expected footer mark signal.
[in]footerspaceNr. of uSeconds for the expected footer space/gap signal.
[in]atleastIs the match on the footerspace a matchAtLeast or matchSpace?
[in]tolerancePercentage error margin to allow. (Default: kUseDefTol)
[in]excessNr. of uSeconds. (Def: kMarkExcess)
[in]MSBfirstBit order to save the data in. (Def: true) true is Most Significant Bit First Order, false is Least Significant First
[in]GEThomasUse G.E. Thomas (true) or IEEE 802.3 (false) convention?
+
+
+
Returns
If successful, how many buffer entries were used. Otherwise 0.
+
See also
https://en.wikipedia.org/wiki/Manchester_code
+
+http://ww1.microchip.com/downloads/en/AppNotes/Atmel-9164-Manchester-Coding-Basics_Application-Note.pdf
+ +
+
+ +

◆ matchManchesterData()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
uint16_t IRrecv::matchManchesterData (volatile const uint16_t * data_ptr,
uint64_t * result_ptr,
const uint16_t remaining,
const uint16_t nbits,
const uint16_t half_period,
const uint16_t starting_balance = 0,
const uint8_t tolerance = kUseDefTol,
const int16_t excess = kMarkExcess,
const bool MSBfirst = true,
const bool GEThomas = true 
)
+
+private
+
+ +

Match & decode a Manchester Code data (<= 64bits.

+
Parameters
+ + +
[in]data_ptrA pointer to where we are at in the capture buffer.
+
+
+
Note
data_ptr is assumed to be pointing to a "Mark", not a "Space".
+
Parameters
+ + + + + + + + + + +
[out]result_ptrA ptr to where to start storing the bits we decoded.
[in]remainingThe size of the capture buffer remaining.
[in]nbitsNr. of data bits we expect.
[in]half_periodNr. of uSeconds for half the clock's period. i.e. 1/2 wavelength
[in]tolerancePercentage error margin to allow. (Default: kUseDefTol)
[in]starting_balanceAmount of uSeconds to assume exists prior to the current value pointed too.
[in]excessNr. of uSeconds. (Def: kMarkExcess)
[in]MSBfirstBit order to save the data in. (Def: true) true is Most Significant Bit First Order, false is Least Significant First
[in]GEThomasUse G.E. Thomas (true) or IEEE 802.3 (false) convention?
+
+
+
Returns
If successful, how many buffer entries were used. Otherwise 0.
+
See also
https://en.wikipedia.org/wiki/Manchester_code
+
+http://ww1.microchip.com/downloads/en/AppNotes/Atmel-9164-Manchester-Coding-Basics_Application-Note.pdf
+
Todo:
Clean up and optimise this. It is just "get it working code" atm.
+ +
+
+ +

◆ matchMark()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::matchMark (const uint32_t measured,
const uint32_t desired,
const uint8_t tolerance = kUseDefTol,
const int16_t excess = kMarkExcess 
)
+
+ +

Check if we match a mark signal(measured) with the desired within +/-tolerance percent, after an expected is excess is added.

+
Parameters
+ + + + + +
[in]measuredThe recorded period of the signal pulse.
[in]desiredThe expected period (in usecs) we are matching against.
[in]toleranceA percentage expressed as an integer. e.g. 10 is 10%.
[in]excessA non-scaling amount to reduce usecs by.
+
+
+
Returns
A Boolean. true if it matches, false if it doesn't.
+ +
+
+ +

◆ matchSpace()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRrecv::matchSpace (const uint32_t measured,
const uint32_t desired,
const uint8_t tolerance = kUseDefTol,
const int16_t excess = kMarkExcess 
)
+
+ +

Check if we match a space signal(measured) with the desired within +/-tolerance percent, after an expected is excess is removed.

+
Parameters
+ + + + + +
[in]measuredThe recorded period of the signal pulse.
[in]desiredThe expected period (in usecs) we are matching against.
[in]toleranceA percentage expressed as an integer. e.g. 10 is 10%.
[in]excessA non-scaling amount to reduce usecs by.
+
+
+
Returns
A Boolean. true if it matches, false if it doesn't.
+ +
+
+ +

◆ resume()

+ +
+
+ + + + + + + + +
void IRrecv::resume (void )
+
+ +

Resume collection of received IR data.

+
Note
This is required if decode() is successful and save_buffer was not set when the class was instanciated.
+
See also
IRrecv class constructor
+ +
+
+ +

◆ setTolerance()

+ +
+
+ + + + + + + + +
void IRrecv::setTolerance (const uint8_t percent = kTolerance)
+
+ +

Set the base tolerance percentage for matching incoming IR messages.

+
Parameters
+ + +
[in]percentAn integer percentage. (0-100)
+
+
+ +
+
+ +

◆ setUnknownThreshold()

+ +
+
+ + + + + + + + +
void IRrecv::setUnknownThreshold (const uint16_t length)
+
+ +

Set the minimum length we will consider for reporting UNKNOWN message types.

+
Parameters
+ + +
[in]lengthMin nr. of mark/space pulses required to be considered.
+
+
+ +
+
+ +

◆ ticksHigh()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
uint32_t IRrecv::ticksHigh (const uint32_t usecs,
const uint8_t tolerance = kUseDefTol,
const uint16_t delta = 0 
)
+
+private
+
+ +

Calculate the upper bound of the nr. of ticks.

+
Parameters
+ + + + +
[in]usecsNr. of uSeconds.
[in]tolerancePercent as an integer. e.g. 10 is 10%
[in]deltaA non-scaling amount to increase usecs by.
+
+
+
Returns
Nr. of ticks.
+ +
+
+ +

◆ ticksLow()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
uint32_t IRrecv::ticksLow (const uint32_t usecs,
const uint8_t tolerance = kUseDefTol,
const uint16_t delta = 0 
)
+
+private
+
+ +

Calculate the lower bound of the nr. of ticks.

+
Parameters
+ + + + +
[in]usecsNr. of uSeconds.
[in]tolerancePercent as an integer. e.g. 10 is 10%
[in]deltaA non-scaling amount to reduce usecs by.
+
+
+
Returns
Nr. of ticks.
+ +
+
+

Member Data Documentation

+ +

◆ _timer_num

+ +
+
+ + + + + +
+ + + + +
uint8_t IRrecv::_timer_num
+
+private
+
+ +
+
+ +

◆ _tolerance

+ +
+
+ + + + + +
+ + + + +
uint8_t IRrecv::_tolerance
+
+private
+
+ +
+
+ +

◆ _unknown_threshold

+ +
+
+ + + + + +
+ + + + +
uint16_t IRrecv::_unknown_threshold
+
+private
+
+ +
+
+ +

◆ irparams_save

+ +
+
+ + + + + +
+ + + + +
irparams_t* IRrecv::irparams_save
+
+private
+
+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv__coll__graph.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv__coll__graph.map new file mode 100644 index 000000000..afb28be42 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv__coll__graph.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv__coll__graph.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv__coll__graph.md5 new file mode 100644 index 000000000..03ea8f4ee --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv__coll__graph.md5 @@ -0,0 +1 @@ +86a4a18f846668b6a3cf862d7669306a \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv__coll__graph.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv__coll__graph.png new file mode 100644 index 000000000..69ea6e16f Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRrecv__coll__graph.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRsend-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRsend-members.html new file mode 100644 index 000000000..af01c2961 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRsend-members.html @@ -0,0 +1,213 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRsend Member List
+
+
+ +

This is the complete list of members for IRsend, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
_delayMicroseconds(uint32_t usec)IRsend
_dutycycleIRsendprivate
_freq_unittestIRsendprivate
_sendSony(const uint64_t data, const uint16_t nbits, const uint16_t repeat, const uint16_t freq)IRsendprivate
begin()IRsend
calcUSecPeriod(uint32_t hz, bool use_offset=true)IRsendprivate
calibrate(uint16_t hz=38000U)IRsend
defaultBits(const decode_type_t protocol)IRsendstatic
enableIROut(uint32_t freq, uint8_t duty=kDutyDefault)IRsend
encodeDoshisha(const uint8_t command, const uint8_t channel=0)IRsend
encodeJVC(uint8_t address, uint8_t command)IRsend
encodeLG(uint16_t address, uint16_t command)IRsend
encodeMagiQuest(const uint32_t wand_id, const uint16_t magnitude)IRsend
encodeNEC(uint16_t address, uint16_t command)IRsend
encodePanasonic(const uint16_t manufacturer, const uint8_t device, const uint8_t subdevice, const uint8_t function)IRsend
encodePioneer(uint16_t address, uint16_t command)IRsend
encodeRC5(const uint8_t address, const uint8_t command, const bool key_released=false)IRsend
encodeRC5X(const uint8_t address, const uint8_t command, const bool key_released=false)IRsend
encodeRC6(const uint32_t address, const uint8_t command, const uint16_t mode=kRC6Mode0Bits)IRsend
encodeSAMSUNG(const uint8_t customer, const uint8_t command)IRsend
encodeSanyoLC7461(uint16_t address, uint8_t command)IRsend
encodeSharp(const uint16_t address, const uint16_t command, const uint16_t expansion=1, const uint16_t check=0, const bool MSBfirst=false)IRsend
encodeSony(const uint16_t nbits, const uint16_t command, const uint16_t address, const uint16_t extended=0)IRsend
IRpinIRsendprivate
IRsend(uint16_t IRsendPin, bool inverted=false, bool use_modulation=true)IRsendexplicit
ledOff()IRsendprotected
ledOn()IRsendprotected
mark(uint16_t usec)IRsend
minRepeats(const decode_type_t protocol)IRsendstatic
modulationIRsendprivate
offTimePeriodIRsendprivate
onTimePeriodIRsendprivate
outputOffIRsendprotected
outputOnIRsendprotected
periodOffsetIRsendprivate
send(const decode_type_t type, const uint64_t data, const uint16_t nbits, const uint16_t repeat=kNoRepeat)IRsend
send(const decode_type_t type, const uint8_t *state, const uint16_t nbytes)IRsend
sendAirwell(uint64_t data, uint16_t nbits=kAirwellBits, uint16_t repeat=kAirwellMinRepeats)IRsend
sendAiwaRCT501(uint64_t data, uint16_t nbits=kAiwaRcT501Bits, uint16_t repeat=kAiwaRcT501MinRepeats)IRsend
sendAmcor(const unsigned char data[], const uint16_t nbytes=kAmcorStateLength, const uint16_t repeat=kAmcorDefaultRepeat)IRsend
sendArgo(const unsigned char data[], const uint16_t nbytes=kArgoStateLength, const uint16_t repeat=kArgoDefaultRepeat)IRsend
sendCarrierAC(uint64_t data, uint16_t nbits=kCarrierAcBits, uint16_t repeat=kCarrierAcMinRepeat)IRsend
sendCarrierAC40(uint64_t data, uint16_t nbits=kCarrierAc40Bits, uint16_t repeat=kCarrierAc40MinRepeat)IRsend
sendCarrierAC64(uint64_t data, uint16_t nbits=kCarrierAc64Bits, uint16_t repeat=kCarrierAc64MinRepeat)IRsend
sendCOOLIX(uint64_t data, uint16_t nbits=kCoolixBits, uint16_t repeat=kCoolixDefaultRepeat)IRsend
sendCoronaAc(const uint8_t data[], const uint16_t nbytes=kCoronaAcStateLength, const uint16_t repeat=kNoRepeat)IRsend
sendDaikin(const unsigned char data[], const uint16_t nbytes=kDaikinStateLength, const uint16_t repeat=kDaikinDefaultRepeat)IRsend
sendDaikin128(const unsigned char data[], const uint16_t nbytes=kDaikin128StateLength, const uint16_t repeat=kDaikin128DefaultRepeat)IRsend
sendDaikin152(const unsigned char data[], const uint16_t nbytes=kDaikin152StateLength, const uint16_t repeat=kDaikin152DefaultRepeat)IRsend
sendDaikin160(const unsigned char data[], const uint16_t nbytes=kDaikin160StateLength, const uint16_t repeat=kDaikin160DefaultRepeat)IRsend
sendDaikin176(const unsigned char data[], const uint16_t nbytes=kDaikin176StateLength, const uint16_t repeat=kDaikin176DefaultRepeat)IRsend
sendDaikin2(const unsigned char data[], const uint16_t nbytes=kDaikin2StateLength, const uint16_t repeat=kDaikin2DefaultRepeat)IRsend
sendDaikin216(const unsigned char data[], const uint16_t nbytes=kDaikin216StateLength, const uint16_t repeat=kDaikin216DefaultRepeat)IRsend
sendDaikin64(const uint64_t data, const uint16_t nbits=kDaikin64Bits, const uint16_t repeat=kDaikin64DefaultRepeat)IRsend
sendData(uint16_t onemark, uint32_t onespace, uint16_t zeromark, uint32_t zerospace, uint64_t data, uint16_t nbits, bool MSBfirst=true)IRsend
sendDelonghiAc(uint64_t data, uint16_t nbits=kDelonghiAcBits, uint16_t repeat=kDelonghiAcDefaultRepeat)IRsend
sendDenon(uint64_t data, uint16_t nbits=kDenonBits, uint16_t repeat=kNoRepeat)IRsend
sendDISH(uint64_t data, uint16_t nbits=kDishBits, uint16_t repeat=kDishMinRepeat)IRsend
sendDoshisha(const uint64_t data, uint16_t nbits=kDoshishaBits, const uint16_t repeat=kNoRepeat)IRsend
sendElectraAC(const unsigned char data[], const uint16_t nbytes=kElectraAcStateLength, const uint16_t repeat=kNoRepeat)IRsend
sendEpson(uint64_t data, uint16_t nbits=kEpsonBits, uint16_t repeat=kEpsonMinRepeat)IRsend
sendFujitsuAC(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat=kFujitsuAcMinRepeat)IRsend
sendGC(uint16_t buf[], uint16_t len)IRsend
sendGeneric(const uint16_t headermark, const uint32_t headerspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t gap, const uint64_t data, const uint16_t nbits, const uint16_t frequency, const bool MSBfirst, const uint16_t repeat, const uint8_t dutycycle)IRsend
sendGeneric(const uint16_t headermark, const uint32_t headerspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t gap, const uint32_t mesgtime, const uint64_t data, const uint16_t nbits, const uint16_t frequency, const bool MSBfirst, const uint16_t repeat, const uint8_t dutycycle)IRsend
sendGeneric(const uint16_t headermark, const uint32_t headerspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t gap, const uint8_t *dataptr, const uint16_t nbytes, const uint16_t frequency, const bool MSBfirst, const uint16_t repeat, const uint8_t dutycycle)IRsend
sendGICable(uint64_t data, uint16_t nbits=kGicableBits, uint16_t repeat=kGicableMinRepeat)IRsend
sendGoodweather(const uint64_t data, const uint16_t nbits=kGoodweatherBits, const uint16_t repeat=kGoodweatherMinRepeat)IRsend
sendGree(const uint64_t data, const uint16_t nbits=kGreeBits, const uint16_t repeat=kGreeDefaultRepeat)IRsend
sendGree(const uint8_t data[], const uint16_t nbytes=kGreeStateLength, const uint16_t repeat=kGreeDefaultRepeat)IRsend
sendHaierAC(const unsigned char data[], const uint16_t nbytes=kHaierACStateLength, const uint16_t repeat=kHaierAcDefaultRepeat)IRsend
sendHaierACYRW02(const unsigned char data[], const uint16_t nbytes=kHaierACYRW02StateLength, const uint16_t repeat=kHaierAcYrw02DefaultRepeat)IRsend
sendHitachiAC(const unsigned char data[], const uint16_t nbytes=kHitachiAcStateLength, const uint16_t repeat=kHitachiAcDefaultRepeat)IRsend
sendHitachiAC1(const unsigned char data[], const uint16_t nbytes=kHitachiAc1StateLength, const uint16_t repeat=kHitachiAcDefaultRepeat)IRsend
sendHitachiAC2(const unsigned char data[], const uint16_t nbytes=kHitachiAc2StateLength, const uint16_t repeat=kHitachiAcDefaultRepeat)IRsend
sendHitachiAc3(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat=kHitachiAcDefaultRepeat)IRsend
sendHitachiAc344(const unsigned char data[], const uint16_t nbytes=kHitachiAc344StateLength, const uint16_t repeat=kHitachiAcDefaultRepeat)IRsend
sendHitachiAc424(const unsigned char data[], const uint16_t nbytes=kHitachiAc424StateLength, const uint16_t repeat=kHitachiAcDefaultRepeat)IRsend
sendInax(const uint64_t data, const uint16_t nbits=kInaxBits, const uint16_t repeat=kInaxMinRepeat)IRsend
sendJVC(uint64_t data, uint16_t nbits=kJvcBits, uint16_t repeat=kNoRepeat)IRsend
sendKelvinator(const unsigned char data[], const uint16_t nbytes=kKelvinatorStateLength, const uint16_t repeat=kKelvinatorDefaultRepeat)IRsend
sendLasertag(uint64_t data, uint16_t nbits=kLasertagBits, uint16_t repeat=kLasertagMinRepeat)IRsend
sendLegoPf(const uint64_t data, const uint16_t nbits=kLegoPfBits, const uint16_t repeat=kLegoPfMinRepeat)IRsend
sendLG(uint64_t data, uint16_t nbits=kLgBits, uint16_t repeat=kNoRepeat)IRsend
sendLG2(uint64_t data, uint16_t nbits=kLgBits, uint16_t repeat=kNoRepeat)IRsend
sendLutron(uint64_t data, uint16_t nbits=kLutronBits, uint16_t repeat=kNoRepeat)IRsend
sendMagiQuest(const uint64_t data, const uint16_t nbits=kMagiquestBits, const uint16_t repeat=kNoRepeat)IRsend
sendManchester(const uint16_t headermark, const uint32_t headerspace, const uint16_t half_period, const uint16_t footermark, const uint32_t gap, const uint64_t data, const uint16_t nbits, const uint16_t frequency=38, const bool MSBfirst=true, const uint16_t repeat=kNoRepeat, const uint8_t dutycycle=kDutyDefault, const bool GEThomas=true)IRsend
sendManchesterData(const uint16_t half_period, const uint64_t data, const uint16_t nbits, const bool MSBfirst=true, const bool GEThomas=true)IRsend
sendMidea(uint64_t data, uint16_t nbits=kMideaBits, uint16_t repeat=kMideaMinRepeat)IRsend
sendMidea24(const uint64_t data, const uint16_t nbits=kMidea24Bits, const uint16_t repeat=kMidea24MinRepeat)IRsend
sendMitsubishi(uint64_t data, uint16_t nbits=kMitsubishiBits, uint16_t repeat=kMitsubishiMinRepeat)IRsend
sendMitsubishi112(const unsigned char data[], const uint16_t nbytes=kMitsubishi112StateLength, const uint16_t repeat=kMitsubishi112MinRepeat)IRsend
sendMitsubishi136(const unsigned char data[], const uint16_t nbytes=kMitsubishi136StateLength, const uint16_t repeat=kMitsubishi136MinRepeat)IRsend
sendMitsubishi2(uint64_t data, uint16_t nbits=kMitsubishiBits, uint16_t repeat=kMitsubishiMinRepeat)IRsend
sendMitsubishiAC(const unsigned char data[], const uint16_t nbytes=kMitsubishiACStateLength, const uint16_t repeat=kMitsubishiACMinRepeat)IRsend
sendMitsubishiHeavy152(const unsigned char data[], const uint16_t nbytes=kMitsubishiHeavy152StateLength, const uint16_t repeat=kMitsubishiHeavy152MinRepeat)IRsend
sendMitsubishiHeavy88(const unsigned char data[], const uint16_t nbytes=kMitsubishiHeavy88StateLength, const uint16_t repeat=kMitsubishiHeavy88MinRepeat)IRsend
sendMultibrackets(const uint64_t data, const uint16_t nbits=kMultibracketsBits, const uint16_t repeat=kMultibracketsDefaultRepeat)IRsend
sendMWM(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat=kNoRepeat)IRsend
sendNEC(uint64_t data, uint16_t nbits=kNECBits, uint16_t repeat=kNoRepeat)IRsend
sendNeoclima(const unsigned char data[], const uint16_t nbytes=kNeoclimaStateLength, const uint16_t repeat=kNeoclimaMinRepeat)IRsend
sendNikai(uint64_t data, uint16_t nbits=kNikaiBits, uint16_t repeat=kNoRepeat)IRsend
sendPanasonic(const uint16_t address, const uint32_t data, const uint16_t nbits=kPanasonicBits, const uint16_t repeat=kNoRepeat)IRsend
sendPanasonic64(const uint64_t data, const uint16_t nbits=kPanasonicBits, const uint16_t repeat=kNoRepeat)IRsend
sendPanasonicAC(const unsigned char data[], const uint16_t nbytes=kPanasonicAcStateLength, const uint16_t repeat=kPanasonicAcDefaultRepeat)IRsend
sendPioneer(const uint64_t data, const uint16_t nbits=kPioneerBits, const uint16_t repeat=kNoRepeat)IRsend
sendPronto(uint16_t data[], uint16_t len, uint16_t repeat=kNoRepeat)IRsend
sendRaw(const uint16_t buf[], const uint16_t len, const uint16_t hz)IRsend
sendRC5(const uint64_t data, uint16_t nbits=kRC5XBits, const uint16_t repeat=kNoRepeat)IRsend
sendRC6(const uint64_t data, const uint16_t nbits=kRC6Mode0Bits, const uint16_t repeat=kNoRepeat)IRsend
sendRCMM(uint64_t data, uint16_t nbits=kRCMMBits, uint16_t repeat=kNoRepeat)IRsend
sendSAMSUNG(const uint64_t data, const uint16_t nbits=kSamsungBits, const uint16_t repeat=kNoRepeat)IRsend
sendSamsung36(const uint64_t data, const uint16_t nbits=kSamsung36Bits, const uint16_t repeat=kNoRepeat)IRsend
sendSamsungAC(const unsigned char data[], const uint16_t nbytes=kSamsungAcStateLength, const uint16_t repeat=kSamsungAcDefaultRepeat)IRsend
sendSanyoLC7461(const uint64_t data, const uint16_t nbits=kSanyoLC7461Bits, const uint16_t repeat=kNoRepeat)IRsend
sendSharp(const uint16_t address, const uint16_t command, const uint16_t nbits=kSharpBits, const uint16_t repeat=kNoRepeat)IRsend
sendSharpAc(const unsigned char data[], const uint16_t nbytes=kSharpAcStateLength, const uint16_t repeat=kSharpAcDefaultRepeat)IRsend
sendSharpRaw(const uint64_t data, const uint16_t nbits=kSharpBits, const uint16_t repeat=kNoRepeat)IRsend
sendSherwood(uint64_t data, uint16_t nbits=kSherwoodBits, uint16_t repeat=kSherwoodMinRepeat)IRsend
sendSony(const uint64_t data, const uint16_t nbits=kSony20Bits, const uint16_t repeat=kSonyMinRepeat)IRsend
sendSony38(const uint64_t data, const uint16_t nbits=kSony20Bits, const uint16_t repeat=kSonyMinRepeat+1)IRsend
sendSymphony(uint64_t data, uint16_t nbits=kSymphonyBits, uint16_t repeat=kSymphonyDefaultRepeat)IRsend
sendTcl112Ac(const unsigned char data[], const uint16_t nbytes=kTcl112AcStateLength, const uint16_t repeat=kTcl112AcDefaultRepeat)IRsend
sendTeco(const uint64_t data, const uint16_t nbits=kTecoBits, const uint16_t repeat=kNoRepeat)IRsend
sendToshibaAC(const unsigned char data[], const uint16_t nbytes=kToshibaACStateLength, const uint16_t repeat=kToshibaACMinRepeat)IRsend
sendTrotec(const unsigned char data[], const uint16_t nbytes=kTrotecStateLength, const uint16_t repeat=kTrotecDefaultRepeat)IRsend
sendVestelAc(const uint64_t data, const uint16_t nbits=kVestelAcBits, const uint16_t repeat=kNoRepeat)IRsend
sendWhirlpoolAC(const unsigned char data[], const uint16_t nbytes=kWhirlpoolAcStateLength, const uint16_t repeat=kWhirlpoolAcDefaultRepeat)IRsend
sendWhynter(const uint64_t data, const uint16_t nbits=kWhynterBits, const uint16_t repeat=kNoRepeat)IRsend
sendZepeal(const uint64_t data, const uint16_t nbits=kZepealBits, const uint16_t repeat=kZepealMinRepeat)IRsend
space(uint32_t usec)IRsend
toggleRC5(const uint64_t data)IRsend
toggleRC6(const uint64_t data, const uint16_t nbits=kRC6Mode0Bits)IRsend
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRsend.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRsend.html new file mode 100644 index 000000000..93a9b7efe --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRsend.html @@ -0,0 +1,6599 @@ + + + + + + + +IRremoteESP8266: IRsend Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

Class for sending all basic IR protocols. + More...

+ +

#include <IRsend.h>

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Member Functions

 IRsend (uint16_t IRsendPin, bool inverted=false, bool use_modulation=true)
 Constructor for an IRsend object. More...
 
void begin ()
 Enable the pin for output. More...
 
void enableIROut (uint32_t freq, uint8_t duty=kDutyDefault)
 Set the output frequency modulation and duty cycle. More...
 
VIRTUAL void _delayMicroseconds (uint32_t usec)
 An ESP8266 RTOS watch-dog timer friendly version of delayMicroseconds(). More...
 
VIRTUAL uint16_t mark (uint16_t usec)
 Modulate the IR LED for the given period (usec) and at the duty cycle set. More...
 
VIRTUAL void space (uint32_t usec)
 Turn the pin (LED) off for a given time. Sends an IR space for the specified number of microseconds. A space is no output, so the PWM output is disabled. More...
 
int8_t calibrate (uint16_t hz=38000U)
 Calculate & set any offsets to account for execution times during sending. More...
 
void sendRaw (const uint16_t buf[], const uint16_t len, const uint16_t hz)
 Send a raw IRremote message. More...
 
void sendData (uint16_t onemark, uint32_t onespace, uint16_t zeromark, uint32_t zerospace, uint64_t data, uint16_t nbits, bool MSBfirst=true)
 Generic method for sending data that is common to most protocols. Will send leading or trailing 0's if the nbits is larger than the number of bits in data. More...
 
void sendManchesterData (const uint16_t half_period, const uint64_t data, const uint16_t nbits, const bool MSBfirst=true, const bool GEThomas=true)
 Generic method for sending Manchester code data. Will send leading or trailing 0's if the nbits is larger than the number of bits in data. More...
 
void sendManchester (const uint16_t headermark, const uint32_t headerspace, const uint16_t half_period, const uint16_t footermark, const uint32_t gap, const uint64_t data, const uint16_t nbits, const uint16_t frequency=38, const bool MSBfirst=true, const uint16_t repeat=kNoRepeat, const uint8_t dutycycle=kDutyDefault, const bool GEThomas=true)
 Generic method for sending Manchester code messages. Will send leading or trailing 0's if the nbits is larger than the number. More...
 
void sendGeneric (const uint16_t headermark, const uint32_t headerspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t gap, const uint64_t data, const uint16_t nbits, const uint16_t frequency, const bool MSBfirst, const uint16_t repeat, const uint8_t dutycycle)
 Generic method for sending simple protocol messages. Will send leading or trailing 0's if the nbits is larger than the number of bits in data. More...
 
void sendGeneric (const uint16_t headermark, const uint32_t headerspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t gap, const uint32_t mesgtime, const uint64_t data, const uint16_t nbits, const uint16_t frequency, const bool MSBfirst, const uint16_t repeat, const uint8_t dutycycle)
 Generic method for sending simple protocol messages. Will send leading or trailing 0's if the nbits is larger than the number of bits in data. More...
 
void sendGeneric (const uint16_t headermark, const uint32_t headerspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t gap, const uint8_t *dataptr, const uint16_t nbytes, const uint16_t frequency, const bool MSBfirst, const uint16_t repeat, const uint8_t dutycycle)
 Generic method for sending simple protocol messages. More...
 
bool send (const decode_type_t type, const uint64_t data, const uint16_t nbits, const uint16_t repeat=kNoRepeat)
 Send a simple (up to 64 bits) IR message of a given type. An unknown/unsupported type will send nothing. More...
 
bool send (const decode_type_t type, const uint8_t *state, const uint16_t nbytes)
 Send a complex (>= 64 bits) IR message of a given type. An unknown/unsupported type will send nothing. More...
 
void sendNEC (uint64_t data, uint16_t nbits=kNECBits, uint16_t repeat=kNoRepeat)
 Send a raw NEC(Renesas) formatted message. Status: STABLE / Known working. More...
 
uint32_t encodeNEC (uint16_t address, uint16_t command)
 Calculate the raw NEC data based on address and command. Status: STABLE / Expected to work. More...
 
void sendSony (const uint64_t data, const uint16_t nbits=kSony20Bits, const uint16_t repeat=kSonyMinRepeat)
 Send a standard Sony/SIRC(Serial Infra-Red Control) message. (40kHz) Status: STABLE / Known working. More...
 
void sendSony38 (const uint64_t data, const uint16_t nbits=kSony20Bits, const uint16_t repeat=kSonyMinRepeat+1)
 Send an alternative 38kHz Sony/SIRC(Serial Infra-Red Control) message. Status: STABLE / Known working. More...
 
uint32_t encodeSony (const uint16_t nbits, const uint16_t command, const uint16_t address, const uint16_t extended=0)
 Convert Sony/SIRC command, address, & extended bits into sendSony format. Status: STABLE / Should be working. More...
 
void sendSherwood (uint64_t data, uint16_t nbits=kSherwoodBits, uint16_t repeat=kSherwoodMinRepeat)
 Send an IR command to a Sherwood device. Status: STABLE / Known working. More...
 
void sendSAMSUNG (const uint64_t data, const uint16_t nbits=kSamsungBits, const uint16_t repeat=kNoRepeat)
 Send a 32-bit Samsung formatted message. Status: STABLE / Should be working. More...
 
uint32_t encodeSAMSUNG (const uint8_t customer, const uint8_t command)
 Construct a raw Samsung message from the supplied customer(address) & command. Status: STABLE / Should be working. More...
 
void sendSamsung36 (const uint64_t data, const uint16_t nbits=kSamsung36Bits, const uint16_t repeat=kNoRepeat)
 Send a Samsung 36-bit formatted message. Status: Alpha / Experimental. More...
 
void sendSamsungAC (const unsigned char data[], const uint16_t nbytes=kSamsungAcStateLength, const uint16_t repeat=kSamsungAcDefaultRepeat)
 Send a Samsung A/C message. Status: Stable / Known working. More...
 
void sendLG (uint64_t data, uint16_t nbits=kLgBits, uint16_t repeat=kNoRepeat)
 Send an LG formatted message. (LG) Status: Beta / Should be working. More...
 
void sendLG2 (uint64_t data, uint16_t nbits=kLgBits, uint16_t repeat=kNoRepeat)
 Send an LG Variant-2 formatted message. (LG2) Status: Beta / Should be working. More...
 
uint32_t encodeLG (uint16_t address, uint16_t command)
 Construct a raw 28-bit LG message code from the supplied address & command. Status: STABLE / Works. More...
 
uint32_t encodeSharp (const uint16_t address, const uint16_t command, const uint16_t expansion=1, const uint16_t check=0, const bool MSBfirst=false)
 Encode a (raw) Sharp message from it's components. Status: STABLE / Works okay. More...
 
void sendSharp (const uint16_t address, const uint16_t command, const uint16_t nbits=kSharpBits, const uint16_t repeat=kNoRepeat)
 Send a Sharp message Status: DEPRECATED / Previously working fine. More...
 
void sendSharpRaw (const uint64_t data, const uint16_t nbits=kSharpBits, const uint16_t repeat=kNoRepeat)
 Send a (raw) Sharp message. More...
 
void sendSharpAc (const unsigned char data[], const uint16_t nbytes=kSharpAcStateLength, const uint16_t repeat=kSharpAcDefaultRepeat)
 Send a Sharp A/C message. Status: Alpha / Untested. More...
 
void sendJVC (uint64_t data, uint16_t nbits=kJvcBits, uint16_t repeat=kNoRepeat)
 Send a JVC formatted message. Status: STABLE / Working. More...
 
uint16_t encodeJVC (uint8_t address, uint8_t command)
 Calculate the raw JVC data based on address and command. Status: STABLE / Works fine. More...
 
void sendDenon (uint64_t data, uint16_t nbits=kDenonBits, uint16_t repeat=kNoRepeat)
 Send a Denon formatted message. Status: STABLE / Should be working. More...
 
uint64_t encodeSanyoLC7461 (uint16_t address, uint8_t command)
 Construct a Sanyo LC7461 message. More...
 
void sendSanyoLC7461 (const uint64_t data, const uint16_t nbits=kSanyoLC7461Bits, const uint16_t repeat=kNoRepeat)
 Send a Sanyo LC7461 message. Status: BETA / Probably works. More...
 
void sendDISH (uint64_t data, uint16_t nbits=kDishBits, uint16_t repeat=kDishMinRepeat)
 Send a DISH NETWORK formatted message. Status: STABLE / Working. More...
 
void sendPanasonic64 (const uint64_t data, const uint16_t nbits=kPanasonicBits, const uint16_t repeat=kNoRepeat)
 Send a Panasonic formatted message. Status: STABLE / Should be working. More...
 
void sendPanasonic (const uint16_t address, const uint32_t data, const uint16_t nbits=kPanasonicBits, const uint16_t repeat=kNoRepeat)
 Send a Panasonic formatted message. Status: STABLE, but DEPRECATED. More...
 
uint64_t encodePanasonic (const uint16_t manufacturer, const uint8_t device, const uint8_t subdevice, const uint8_t function)
 Calculate the raw Panasonic data based on device, subdevice, & function. Status: STABLE / Should be working. More...
 
void sendRC5 (const uint64_t data, uint16_t nbits=kRC5XBits, const uint16_t repeat=kNoRepeat)
 Send a Philips RC-5/RC-5X packet. Status: RC-5 (stable), RC-5X (alpha) More...
 
uint16_t encodeRC5 (const uint8_t address, const uint8_t command, const bool key_released=false)
 Encode a Philips RC-5 data message. Status: Beta / Should be working. More...
 
uint16_t encodeRC5X (const uint8_t address, const uint8_t command, const bool key_released=false)
 Encode a Philips RC-5X data message. Status: Beta / Should be working. More...
 
uint64_t toggleRC5 (const uint64_t data)
 Flip the toggle bit of a Philips RC-5/RC-5X data message. Used to indicate a change of remote button's state. Status: STABLE. More...
 
void sendRC6 (const uint64_t data, const uint16_t nbits=kRC6Mode0Bits, const uint16_t repeat=kNoRepeat)
 Send a Philips RC-6 packet. Status: Stable. More...
 
uint64_t encodeRC6 (const uint32_t address, const uint8_t command, const uint16_t mode=kRC6Mode0Bits)
 Encode a Philips RC-6 data message. Status: Beta / Should be working. More...
 
uint64_t toggleRC6 (const uint64_t data, const uint16_t nbits=kRC6Mode0Bits)
 Flip the toggle bit of a Philips RC-6 data message. Used to indicate a change of remote button's state. Status: STABLE / Should work fine. More...
 
void sendRCMM (uint64_t data, uint16_t nbits=kRCMMBits, uint16_t repeat=kNoRepeat)
 Send a Philips RC-MM packet. Status: STABLE / Should be working. More...
 
void sendCOOLIX (uint64_t data, uint16_t nbits=kCoolixBits, uint16_t repeat=kCoolixDefaultRepeat)
 Send a Coolix message Status: STABLE / Confirmed Working. More...
 
void sendWhynter (const uint64_t data, const uint16_t nbits=kWhynterBits, const uint16_t repeat=kNoRepeat)
 Send a Whynter message. Status: STABLE. More...
 
void sendMitsubishi (uint64_t data, uint16_t nbits=kMitsubishiBits, uint16_t repeat=kMitsubishiMinRepeat)
 Send the supplied Mitsubishi 16-bit message. Status: STABLE / Working. More...
 
void sendMitsubishi136 (const unsigned char data[], const uint16_t nbytes=kMitsubishi136StateLength, const uint16_t repeat=kMitsubishi136MinRepeat)
 Send a Mitsubishi 136-bit A/C message. (MITSUBISHI136) Status: BETA / Probably working. Needs to be tested against a real device. More...
 
void sendMitsubishi112 (const unsigned char data[], const uint16_t nbytes=kMitsubishi112StateLength, const uint16_t repeat=kMitsubishi112MinRepeat)
 Send a Mitsubishi 112-bit A/C formatted message. (MITSUBISHI112) Status: Stable / Reported as working. More...
 
void sendMitsubishi2 (uint64_t data, uint16_t nbits=kMitsubishiBits, uint16_t repeat=kMitsubishiMinRepeat)
 Send a supplied second variant Mitsubishi 16-bit message. Status: BETA / Probably works. More...
 
void sendMitsubishiAC (const unsigned char data[], const uint16_t nbytes=kMitsubishiACStateLength, const uint16_t repeat=kMitsubishiACMinRepeat)
 Send a Mitsubishi 144-bit A/C formatted message. (MITSUBISHI_AC) Status: STABLE / Working. More...
 
void sendMitsubishiHeavy88 (const unsigned char data[], const uint16_t nbytes=kMitsubishiHeavy88StateLength, const uint16_t repeat=kMitsubishiHeavy88MinRepeat)
 Send a MitsubishiHeavy 88-bit A/C message. Status: BETA / Appears to be working. Needs testing against a real device. More...
 
void sendMitsubishiHeavy152 (const unsigned char data[], const uint16_t nbytes=kMitsubishiHeavy152StateLength, const uint16_t repeat=kMitsubishiHeavy152MinRepeat)
 Send a MitsubishiHeavy 152-bit A/C message. Status: BETA / Appears to be working. Needs testing against a real device. More...
 
void sendFujitsuAC (const unsigned char data[], const uint16_t nbytes, const uint16_t repeat=kFujitsuAcMinRepeat)
 Send a Fujitsu A/C formatted message. Status: STABLE / Known Good. More...
 
void sendInax (const uint64_t data, const uint16_t nbits=kInaxBits, const uint16_t repeat=kInaxMinRepeat)
 Send a Inax Toilet formatted message. Status: STABLE / Working. More...
 
void sendGC (uint16_t buf[], uint16_t len)
 Send a shortened GlobalCache (GC) IRdb/control tower formatted message. Status: STABLE / Known working. More...
 
void sendKelvinator (const unsigned char data[], const uint16_t nbytes=kKelvinatorStateLength, const uint16_t repeat=kKelvinatorDefaultRepeat)
 Send a Kelvinator A/C message. Status: STABLE / Known working. More...
 
void sendDaikin (const unsigned char data[], const uint16_t nbytes=kDaikinStateLength, const uint16_t repeat=kDaikinDefaultRepeat)
 Send a Daikin 280-bit A/C formatted message. Status: STABLE. More...
 
void sendDaikin64 (const uint64_t data, const uint16_t nbits=kDaikin64Bits, const uint16_t repeat=kDaikin64DefaultRepeat)
 Send a Daikin64 (64-bit) A/C formatted message. Status: Beta / Probably Working. More...
 
void sendDaikin128 (const unsigned char data[], const uint16_t nbytes=kDaikin128StateLength, const uint16_t repeat=kDaikin128DefaultRepeat)
 Send a Daikin128 (128-bit) A/C formatted message. Status: STABLE / Known Working. More...
 
void sendDaikin152 (const unsigned char data[], const uint16_t nbytes=kDaikin152StateLength, const uint16_t repeat=kDaikin152DefaultRepeat)
 Send a Daikin152 (152-bit) A/C formatted message. Status: STABLE / Known Working. More...
 
void sendDaikin160 (const unsigned char data[], const uint16_t nbytes=kDaikin160StateLength, const uint16_t repeat=kDaikin160DefaultRepeat)
 Send a Daikin160 (160-bit) A/C formatted message. Status: STABLE / Confirmed working. More...
 
void sendDaikin176 (const unsigned char data[], const uint16_t nbytes=kDaikin176StateLength, const uint16_t repeat=kDaikin176DefaultRepeat)
 Send a Daikin176 (176-bit) A/C formatted message. Status: Alpha / Untested on a real device. More...
 
void sendDaikin2 (const unsigned char data[], const uint16_t nbytes=kDaikin2StateLength, const uint16_t repeat=kDaikin2DefaultRepeat)
 Send a Daikin2 (312-bit) A/C formatted message. Status: STABLE / Expected to work. More...
 
void sendDaikin216 (const unsigned char data[], const uint16_t nbytes=kDaikin216StateLength, const uint16_t repeat=kDaikin216DefaultRepeat)
 Send a Daikin216 (216-bit) A/C formatted message. Status: Alpha / Untested on a real device. More...
 
void sendAiwaRCT501 (uint64_t data, uint16_t nbits=kAiwaRcT501Bits, uint16_t repeat=kAiwaRcT501MinRepeats)
 Send an Aiwa RC T501 formatted message. Status: BETA / Should work. More...
 
void sendGree (const uint64_t data, const uint16_t nbits=kGreeBits, const uint16_t repeat=kGreeDefaultRepeat)
 Send a Gree Heat Pump formatted message. Status: STABLE / Working. More...
 
void sendGree (const uint8_t data[], const uint16_t nbytes=kGreeStateLength, const uint16_t repeat=kGreeDefaultRepeat)
 Send a Gree Heat Pump formatted message. Status: STABLE / Working. More...
 
void sendGoodweather (const uint64_t data, const uint16_t nbits=kGoodweatherBits, const uint16_t repeat=kGoodweatherMinRepeat)
 Send a Goodweather HVAC formatted message. Status: BETA / Needs testing on real device. More...
 
void sendPronto (uint16_t data[], uint16_t len, uint16_t repeat=kNoRepeat)
 Send a Pronto Code formatted message. Status: STABLE / Known working. More...
 
void sendArgo (const unsigned char data[], const uint16_t nbytes=kArgoStateLength, const uint16_t repeat=kArgoDefaultRepeat)
 Send a Argo A/C formatted message. Status: BETA / Probably works. More...
 
void sendTrotec (const unsigned char data[], const uint16_t nbytes=kTrotecStateLength, const uint16_t repeat=kTrotecDefaultRepeat)
 Send a Trotec message. Status: Beta / Probably Working. More...
 
void sendNikai (uint64_t data, uint16_t nbits=kNikaiBits, uint16_t repeat=kNoRepeat)
 Send a Nikai formatted message. Status: STABLE / Working. More...
 
void sendToshibaAC (const unsigned char data[], const uint16_t nbytes=kToshibaACStateLength, const uint16_t repeat=kToshibaACMinRepeat)
 Send a Toshiba A/C message. Status: STABLE / Working. More...
 
void sendMidea (uint64_t data, uint16_t nbits=kMideaBits, uint16_t repeat=kMideaMinRepeat)
 Send a Midea message Status: Alpha / Needs testing against a real device. More...
 
void sendMidea24 (const uint64_t data, const uint16_t nbits=kMidea24Bits, const uint16_t repeat=kMidea24MinRepeat)
 Send a Midea24 formatted message. Status: STABLE / Confirmed working on a real device. More...
 
void sendMagiQuest (const uint64_t data, const uint16_t nbits=kMagiquestBits, const uint16_t repeat=kNoRepeat)
 Send a MagiQuest formatted message. Status: Beta / Should be working. More...
 
uint64_t encodeMagiQuest (const uint32_t wand_id, const uint16_t magnitude)
 Encode a MagiQuest wand_id, and a magnitude into a single 64bit value. (Only 48 bits of real data + 8 leading zero bits) This is suitable for calling sendMagiQuest() with. e.g. sendMagiQuest(encodeMagiQuest(wand_id, magnitude)) More...
 
void sendLasertag (uint64_t data, uint16_t nbits=kLasertagBits, uint16_t repeat=kLasertagMinRepeat)
 Send a Lasertag packet/message. Status: STABLE / Working. More...
 
void sendCarrierAC (uint64_t data, uint16_t nbits=kCarrierAcBits, uint16_t repeat=kCarrierAcMinRepeat)
 Send a Carrier HVAC formatted message. Status: STABLE / Works on real devices. More...
 
void sendCarrierAC40 (uint64_t data, uint16_t nbits=kCarrierAc40Bits, uint16_t repeat=kCarrierAc40MinRepeat)
 Send a Carrier 40bit HVAC formatted message. Status: STABLE / Tested against a real device. More...
 
void sendCarrierAC64 (uint64_t data, uint16_t nbits=kCarrierAc64Bits, uint16_t repeat=kCarrierAc64MinRepeat)
 Send a Carrier 64bit HVAC formatted message. Status: STABLE / Known to be working. More...
 
void sendHaierAC (const unsigned char data[], const uint16_t nbytes=kHaierACStateLength, const uint16_t repeat=kHaierAcDefaultRepeat)
 Send a Haier A/C formatted message. (HSU07-HEA03 remote) Status: STABLE / Known to be working. More...
 
void sendHaierACYRW02 (const unsigned char data[], const uint16_t nbytes=kHaierACYRW02StateLength, const uint16_t repeat=kHaierAcYrw02DefaultRepeat)
 Send a Haier YR-W02 remote A/C formatted message. Status: Alpha / Untested on a real device. More...
 
void sendHitachiAC (const unsigned char data[], const uint16_t nbytes=kHitachiAcStateLength, const uint16_t repeat=kHitachiAcDefaultRepeat)
 Send a Hitachi 28-byte/224-bit A/C formatted message. (HITACHI_AC) Status: STABLE / Working. More...
 
void sendHitachiAC1 (const unsigned char data[], const uint16_t nbytes=kHitachiAc1StateLength, const uint16_t repeat=kHitachiAcDefaultRepeat)
 Send a Hitachi 13 byte/224-bit A/C formatted message. (HITACHI_AC1) Status: STABLE / Confirmed Working. More...
 
void sendHitachiAC2 (const unsigned char data[], const uint16_t nbytes=kHitachiAc2StateLength, const uint16_t repeat=kHitachiAcDefaultRepeat)
 Send a Hitachi 53 byte/424-bit A/C formatted message. (HITACHI_AC2) Basically the same as sendHitatchiAC() except different size. Status: STABLE / Expected to work. More...
 
void sendHitachiAc3 (const unsigned char data[], const uint16_t nbytes, const uint16_t repeat=kHitachiAcDefaultRepeat)
 Send a Hitachi(3) A/C formatted message. (HITACHI_AC3) Status: STABLE / Working fine. More...
 
void sendHitachiAc344 (const unsigned char data[], const uint16_t nbytes=kHitachiAc344StateLength, const uint16_t repeat=kHitachiAcDefaultRepeat)
 Send a Hitachi A/C 43-byte/344-bit message. (HITACHI_AC344) Basically the same as sendHitatchiAC() except different size. Status: Beta / Probably works. More...
 
void sendHitachiAc424 (const unsigned char data[], const uint16_t nbytes=kHitachiAc424StateLength, const uint16_t repeat=kHitachiAcDefaultRepeat)
 Send a Hitachi 53-byte/424-bit A/C formatted message. (HITACHI_AC424) Status: STABLE / Reported as working. More...
 
void sendGICable (uint64_t data, uint16_t nbits=kGicableBits, uint16_t repeat=kGicableMinRepeat)
 Send a raw G.I. Cable formatted message. Status: Alpha / Untested. More...
 
void sendWhirlpoolAC (const unsigned char data[], const uint16_t nbytes=kWhirlpoolAcStateLength, const uint16_t repeat=kWhirlpoolAcDefaultRepeat)
 Send a Whirlpool A/C message. Status: BETA / Probably works. More...
 
void sendLutron (uint64_t data, uint16_t nbits=kLutronBits, uint16_t repeat=kNoRepeat)
 Send a Lutron formatted message. Status: Stable / Appears to be working for real devices. More...
 
void sendElectraAC (const unsigned char data[], const uint16_t nbytes=kElectraAcStateLength, const uint16_t repeat=kNoRepeat)
 Send a Electra A/C formatted message. Status: Alpha / Needs testing against a real device. More...
 
void sendPanasonicAC (const unsigned char data[], const uint16_t nbytes=kPanasonicAcStateLength, const uint16_t repeat=kPanasonicAcDefaultRepeat)
 Send a Panasonic A/C message. Status: STABLE / Work with real device(s). More...
 
void sendPioneer (const uint64_t data, const uint16_t nbits=kPioneerBits, const uint16_t repeat=kNoRepeat)
 Send a raw Pioneer formatted message. Status: STABLE / Expected to be working. More...
 
uint64_t encodePioneer (uint16_t address, uint16_t command)
 Calculate the raw Pioneer data code based on two NEC sub-codes Status: STABLE / Expected to work. More...
 
void sendMWM (const unsigned char data[], const uint16_t nbytes, const uint16_t repeat=kNoRepeat)
 Send a MWM packet/message. Status: Implemented. More...
 
void sendVestelAc (const uint64_t data, const uint16_t nbits=kVestelAcBits, const uint16_t repeat=kNoRepeat)
 Send a Vestel message Status: STABLE / Working. More...
 
void sendTcl112Ac (const unsigned char data[], const uint16_t nbytes=kTcl112AcStateLength, const uint16_t repeat=kTcl112AcDefaultRepeat)
 Send a TCL 112-bit A/C message. Status: Beta / Probably working. More...
 
void sendTeco (const uint64_t data, const uint16_t nbits=kTecoBits, const uint16_t repeat=kNoRepeat)
 Send a Teco A/C message. Status: Beta / Probably working. More...
 
void sendLegoPf (const uint64_t data, const uint16_t nbits=kLegoPfBits, const uint16_t repeat=kLegoPfMinRepeat)
 Send a LEGO Power Functions message. Status: Beta / Should work. More...
 
void sendNeoclima (const unsigned char data[], const uint16_t nbytes=kNeoclimaStateLength, const uint16_t repeat=kNeoclimaMinRepeat)
 Send a Neoclima message. Status: STABLE / Known to be working. More...
 
void sendAmcor (const unsigned char data[], const uint16_t nbytes=kAmcorStateLength, const uint16_t repeat=kAmcorDefaultRepeat)
 Send a Amcor HVAC formatted message. Status: STABLE / Reported as working. More...
 
void sendEpson (uint64_t data, uint16_t nbits=kEpsonBits, uint16_t repeat=kEpsonMinRepeat)
 Send an Epson formatted message. Status: Beta / Probably works. More...
 
void sendSymphony (uint64_t data, uint16_t nbits=kSymphonyBits, uint16_t repeat=kSymphonyDefaultRepeat)
 Send a Symphony packet. Status: STABLE / Should be working. More...
 
void sendAirwell (uint64_t data, uint16_t nbits=kAirwellBits, uint16_t repeat=kAirwellMinRepeats)
 Send an Airwell Manchester Code formatted message. Status: BETA / Appears to be working. More...
 
void sendDelonghiAc (uint64_t data, uint16_t nbits=kDelonghiAcBits, uint16_t repeat=kDelonghiAcDefaultRepeat)
 Send a Delonghi A/C formatted message. Status: STABLE / Reported as working on a real device. More...
 
void sendDoshisha (const uint64_t data, uint16_t nbits=kDoshishaBits, const uint16_t repeat=kNoRepeat)
 Send a Doshisha formatted message. Status: STABLE / Works on real device. More...
 
uint64_t encodeDoshisha (const uint8_t command, const uint8_t channel=0)
 Encode Doshisha combining constant values with command and channel. Status: STABLE / Working. More...
 
void sendMultibrackets (const uint64_t data, const uint16_t nbits=kMultibracketsBits, const uint16_t repeat=kMultibracketsDefaultRepeat)
 Send a Multibrackets formatted message. Status: BETA / Appears to be working. More...
 
void sendCoronaAc (const uint8_t data[], const uint16_t nbytes=kCoronaAcStateLength, const uint16_t repeat=kNoRepeat)
 Send a CoronaAc formatted message. Status: STABLE / Working on real device. More...
 
void sendZepeal (const uint64_t data, const uint16_t nbits=kZepealBits, const uint16_t repeat=kZepealMinRepeat)
 Send a Zepeal formatted message. Status: STABLE / Works on real device. More...
 
+ + + + + + + +

+Static Public Member Functions

static uint16_t minRepeats (const decode_type_t protocol)
 Get the minimum number of repeats for a given protocol. More...
 
static uint16_t defaultBits (const decode_type_t protocol)
 Get the default number of bits for a given protocol. More...
 
+ + + + + + + +

+Protected Member Functions

VIRTUAL void ledOff ()
 Turn off the IR LED. More...
 
VIRTUAL void ledOn ()
 Turn on the IR LED. More...
 
+ + + + + +

+Protected Attributes

uint8_t outputOn
 
uint8_t outputOff
 
+ + + + + + + +

+Private Member Functions

uint32_t calcUSecPeriod (uint32_t hz, bool use_offset=true)
 Calculate the period for a given frequency. More...
 
void _sendSony (const uint64_t data, const uint16_t nbits, const uint16_t repeat, const uint16_t freq)
 Internal procedure to generate a Sony/SIRC(Serial Infra-Red Control) message Status: STABLE / Known working. More...
 
+ + + + + + + + + + + + + + + +

+Private Attributes

uint32_t _freq_unittest
 
uint16_t onTimePeriod
 
uint16_t offTimePeriod
 
uint16_t IRpin
 
int8_t periodOffset
 
uint8_t _dutycycle
 
bool modulation
 
+

Detailed Description

+

Class for sending all basic IR protocols.

+
Note
Originally from https://github.com/shirriff/Arduino-IRremote/ Updated by markszabo (https://github.com/crankyoldgit/IRremoteESP8266) for sending IR code on ESP8266
+

Constructor & Destructor Documentation

+ +

◆ IRsend()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
IRsend::IRsend (uint16_t IRsendPin,
bool inverted = false,
bool use_modulation = true 
)
+
+explicit
+
+ +

Constructor for an IRsend object.

+
Parameters
+ + + +
[in]IRsendPinWhich GPIO pin to use when sending an IR command.
[in]invertedOptional flag to invert the output. (default = false) e.g. LED is illuminated when GPIO is LOW rather than HIGH.
+
+
+
Warning
Setting inverted to something other than the default could easily destroy your IR LED if you are overdriving it. Unless you REALLY know what you are doing, don't change this.
+
Parameters
+ + +
[in]use_modulationDo we do frequency modulation during transmission? i.e. If not, assume a 100% duty cycle. Ignore attempts to change the duty cycle etc.
+
+
+ +
+
+

Member Function Documentation

+ +

◆ _delayMicroseconds()

+ +
+
+ + + + + + + + +
void IRsend::_delayMicroseconds (uint32_t usec)
+
+ +

An ESP8266 RTOS watch-dog timer friendly version of delayMicroseconds().

+

A version of delayMicroseconds() that handles large values and does NOT use the watch-dog friendly delay() calls where appropriate.

+
Parameters
+ + +
[in]usecNr. of uSeconds to delay for.
+
+
+
Note
Use this only if you know what you are doing as it may cause the WDT to reset the ESP8266.
+ +
+
+ +

◆ _sendSony()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::_sendSony (const uint64_t data,
const uint16_t nbits,
const uint16_t repeat,
const uint16_t freq 
)
+
+private
+
+ +

Internal procedure to generate a Sony/SIRC(Serial Infra-Red Control) message Status: STABLE / Known working.

+
Parameters
+ + + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
[in]freqFrequency of the modulation to transmit at. (Hz or kHz)
+
+
+ +
+
+ +

◆ begin()

+ +
+
+ + + + + + + +
void IRsend::begin ()
+
+ +

Enable the pin for output.

+ +
+
+ +

◆ calcUSecPeriod()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
uint32_t IRsend::calcUSecPeriod (uint32_t hz,
bool use_offset = true 
)
+
+private
+
+ +

Calculate the period for a given frequency.

+
Parameters
+ + + +
[in]hzFrequency in Hz.
[in]use_offsetShould we use the calculated offset or not?
+
+
+
Returns
nr. of uSeconds.
+
Note
(T = 1/f)
+ +
+
+ +

◆ calibrate()

+ +
+
+ + + + + + + + +
int8_t IRsend::calibrate (uint16_t hz = 38000U)
+
+ +

Calculate & set any offsets to account for execution times during sending.

+
Parameters
+ + +
[in]hzThe frequency to calibrate at >= 1000Hz. Default is 38000Hz.
+
+
+
Returns
The calculated period offset (in uSeconds) which is now in use. e.g. -5.
+
Note
This will generate an 65535us mark() IR LED signal. This only needs to be called once, if at all.
+ +
+
+ +

◆ defaultBits()

+ +
+
+ + + + + +
+ + + + + + + + +
uint16_t IRsend::defaultBits (const decode_type_t protocol)
+
+static
+
+ +

Get the default number of bits for a given protocol.

+
Parameters
+ + +
[in]protocolProtocol number/type you want the default bit size for.
+
+
+
Returns
The number of bits.
+ +
+
+ +

◆ enableIROut()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRsend::enableIROut (uint32_t freq,
uint8_t duty = kDutyDefault 
)
+
+ +

Set the output frequency modulation and duty cycle.

+
Parameters
+ + + +
[in]freqThe freq we want to modulate at. Assumes < 1000 means kHz else Hz.
[in]dutyPercentage duty cycle of the LED. e.g. 25 = 25% = 1/4 on, 3/4 off. If you are not sure, try 50 percent. This is ignored if modulation is disabled at object instantiation.
+
+
+
Note
Integer timing functions & math mean we can't do fractions of microseconds timing. Thus minor changes to the freq & duty values may have limited effect. You've been warned.
+ +
+
+ +

◆ encodeDoshisha()

+ +
+
+ + + + + + + + + + + + + + + + + + +
uint64_t IRsend::encodeDoshisha (const uint8_t command,
const uint8_t channel = 0 
)
+
+ +

Encode Doshisha combining constant values with command and channel. Status: STABLE / Working.

+
Parameters
+ + + +
[in]commandThe command code to be sent.
[in]channelThe one bit channel 0 for CH1 and 1 for CH2
+
+
+
Returns
The corresponding Doshisha code.
+ +
+
+ +

◆ encodeJVC()

+ +
+
+ + + + + + + + + + + + + + + + + + +
uint16_t IRsend::encodeJVC (uint8_t address,
uint8_t command 
)
+
+ +

Calculate the raw JVC data based on address and command. Status: STABLE / Works fine.

+
Parameters
+ + + +
[in]addressAn 8-bit address value.
[in]commandAn 8-bit command value.
+
+
+
Returns
A raw JVC message code, suitable for sendJVC()..
+
See also
http://www.sbprojects.com/knowledge/ir/jvc.php
+ +
+
+ +

◆ encodeLG()

+ +
+
+ + + + + + + + + + + + + + + + + + +
uint32_t IRsend::encodeLG (uint16_t address,
uint16_t command 
)
+
+ +

Construct a raw 28-bit LG message code from the supplied address & command. Status: STABLE / Works.

+
Parameters
+ + + +
[in]addressThe address code.
[in]commandThe command code.
+
+
+
Returns
A raw 28-bit LG message code suitable for sendLG() etc.
+
Note
Sequence of bits = address + command + checksum.
+ +
+
+ +

◆ encodeMagiQuest()

+ +
+
+ + + + + + + + + + + + + + + + + + +
uint64_t IRsend::encodeMagiQuest (const uint32_t wand_id,
const uint16_t magnitude 
)
+
+ +

Encode a MagiQuest wand_id, and a magnitude into a single 64bit value. (Only 48 bits of real data + 8 leading zero bits) This is suitable for calling sendMagiQuest() with. e.g. sendMagiQuest(encodeMagiQuest(wand_id, magnitude))

+
Parameters
+ + + +
[in]wand_idThe value for the wand ID.
[in]magnitudeThe value for the magnitude
+
+
+
Returns
A code suitable for calling sendMagiQuest() with.
+ +
+
+ +

◆ encodeNEC()

+ +
+
+ + + + + + + + + + + + + + + + + + +
uint32_t IRsend::encodeNEC (uint16_t address,
uint16_t command 
)
+
+ +

Calculate the raw NEC data based on address and command. Status: STABLE / Expected to work.

+
Parameters
+ + + +
[in]addressAn address value.
[in]commandAn 8-bit command value.
+
+
+
Returns
A raw 32-bit NEC message suitable for use with sendNEC().
+
See also
http://www.sbprojects.com/knowledge/ir/nec.php
+ +
+
+ +

◆ encodePanasonic()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
uint64_t IRsend::encodePanasonic (const uint16_t manufacturer,
const uint8_t device,
const uint8_t subdevice,
const uint8_t function 
)
+
+ +

Calculate the raw Panasonic data based on device, subdevice, & function. Status: STABLE / Should be working.

+
Parameters
+ + + + + +
[in]manufacturerA 16-bit manufacturer code. e.g. 0x4004 is Panasonic
[in]deviceAn 8-bit code.
[in]subdeviceAn 8-bit code.
[in]functionAn 8-bit code.
+
+
+
Returns
A value suitable for use with sendPanasonic64().
+
Note
Panasonic 48-bit protocol is a modified version of Kaseikyo.
+
See also
http://www.remotecentral.com/cgi-bin/mboard/rc-pronto/thread.cgi?2615
+ +
+
+ +

◆ encodePioneer()

+ +
+
+ + + + + + + + + + + + + + + + + + +
uint64_t IRsend::encodePioneer (uint16_t address,
uint16_t command 
)
+
+ +

Calculate the raw Pioneer data code based on two NEC sub-codes Status: STABLE / Expected to work.

+
Parameters
+ + + +
[in]addressA 16-bit "published" NEC value.
[in]commandA 16-bit "published" NEC value.
+
+
+
Returns
A raw 64-bit Pioneer message code for use with sendPioneer()`
+
Note
Address & Command can be take from a decode result OR from the spreadsheets located at: https://www.pioneerelectronics.com/PUSA/Support/Home-Entertainment-Custom-Install/IR+Codes/A+V+Receivers where the first part is considered the address, and the second the command. e.g. "A556+AF20" is an Address of 0xA556 & a Command of 0xAF20.
+ +
+
+ +

◆ encodeRC5()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
uint16_t IRsend::encodeRC5 (const uint8_t address,
const uint8_t command,
const bool key_released = false 
)
+
+ +

Encode a Philips RC-5 data message. Status: Beta / Should be working.

+
Parameters
+ + + + +
[in]addressThe 5-bit address value for the message.
[in]commandThe 6-bit command value for the message.
[in]key_releasedIndicate if the remote key has been released.
+
+
+
Returns
A message suitable for use in sendRC5().
+ +
+
+ +

◆ encodeRC5X()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
uint16_t IRsend::encodeRC5X (const uint8_t address,
const uint8_t command,
const bool key_released = false 
)
+
+ +

Encode a Philips RC-5X data message. Status: Beta / Should be working.

+
Parameters
+ + + + +
[in]addressThe 5-bit address value for the message.
[in]commandThe 7-bit command value for the message.
[in]key_releasedIndicate if the remote key has been released.
+
+
+
Returns
A message suitable for use in sendRC5().
+ +
+
+ +

◆ encodeRC6()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
uint64_t IRsend::encodeRC6 (const uint32_t address,
const uint8_t command,
const uint16_t mode = kRC6Mode0Bits 
)
+
+ +

Encode a Philips RC-6 data message. Status: Beta / Should be working.

+
Parameters
+ + + + +
[in]addressThe address (aka. control) value for the message. Includes the field/mode/toggle bits.
[in]commandThe 8-bit command value for the message. (aka. information)
[in]modeWhich protocol to use. Defined by nr. of bits in the protocol.
+
+
+
Returns
A data message suitable for use in sendRC6().
+ +
+
+ +

◆ encodeSAMSUNG()

+ +
+
+ + + + + + + + + + + + + + + + + + +
uint32_t IRsend::encodeSAMSUNG (const uint8_t customer,
const uint8_t command 
)
+
+ +

Construct a raw Samsung message from the supplied customer(address) & command. Status: STABLE / Should be working.

+
Parameters
+ + + +
[in]customerThe customer code. (aka. Address)
[in]commandThe command code.
+
+
+
Returns
A raw 32-bit Samsung message suitable for sendSAMSUNG().
+ +
+
+ +

◆ encodeSanyoLC7461()

+ +
+
+ + + + + + + + + + + + + + + + + + +
uint64_t IRsend::encodeSanyoLC7461 (uint16_t address,
uint8_t command 
)
+
+ +

Construct a Sanyo LC7461 message.

+
Parameters
+ + + +
[in]addressThe 13 bit value of the address(Custom) portion of the protocol.
[in]commandThe 8 bit value of the command(Key) portion of the protocol.
+
+
+
Returns
An uint64_t with the encoded raw 42 bit Sanyo LC7461 data value.
+
Note
This protocol uses the NEC protocol timings. However, data is formatted as : address(13 bits), !address, command(8 bits), !command. According with LIRC, this protocol is used on Sanyo, Aiwa and Chinon
+ +
+
+ +

◆ encodeSharp()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
uint32_t IRsend::encodeSharp (const uint16_t address,
const uint16_t command,
const uint16_t expansion = 1,
const uint16_t check = 0,
const bool MSBfirst = false 
)
+
+ +

Encode a (raw) Sharp message from it's components. Status: STABLE / Works okay.

+
Parameters
+ + + + + + +
[in]addressThe value of the address to be sent.
[in]commandThe value of the address to be sent. (8 bits)
[in]expansionThe value of the expansion bit to use. (0 or 1, typically 1)
[in]checkThe value of the check bit to use. (0 or 1, typically 0)
[in]MSBfirstFlag indicating MSB first or LSB first order.
+
+
+
Returns
A uint32_t containing the raw Sharp message for sendSharpRaw().
+
Note
Assumes the standard Sharp bit sizes. Historically sendSharp() sends address & command in MSB first order. This is actually incorrect. It should be sent in LSB order. The behaviour of sendSharp() hasn't been changed to maintain backward compatibility.
+ +
+
+ +

◆ encodeSony()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
uint32_t IRsend::encodeSony (const uint16_t nbits,
const uint16_t command,
const uint16_t address,
const uint16_t extended = 0 
)
+
+ +

Convert Sony/SIRC command, address, & extended bits into sendSony format. Status: STABLE / Should be working.

+
Parameters
+ + + + + +
[in]nbitsSony protocol bit size.
[in]commandSony command bits.
[in]addressSony address bits.
[in]extendedSony extended bits.
+
+
+
Returns
A sendSony() etc compatible data message.
+ +
+
+ +

◆ ledOff()

+ +
+
+ + + + + +
+ + + + + + + +
void IRsend::ledOff ()
+
+protected
+
+ +

Turn off the IR LED.

+ +
+
+ +

◆ ledOn()

+ +
+
+ + + + + +
+ + + + + + + +
void IRsend::ledOn ()
+
+protected
+
+ +

Turn on the IR LED.

+ +
+
+ +

◆ mark()

+ +
+
+ + + + + + + + +
uint16_t IRsend::mark (uint16_t usec)
+
+ +

Modulate the IR LED for the given period (usec) and at the duty cycle set.

+
Parameters
+ + +
[in]usecThe period of time to modulate the IR LED for, in microseconds.
+
+
+
Returns
Nr. of pulses actually sent.
+
Note
The ESP8266 has no good way to do hardware PWM, so we have to do it all in software. There is a horrible kludge/brilliant hack to use the second serial TX line to do fairly accurate hardware PWM, but it is only available on a single specific GPIO and only available on some modules. e.g. It's not available on the ESP-01 module. Hence, for greater compatibility & choice, we don't use that method. Ref: https://www.analysir.com/blog/2017/01/29/updated-esp8266-nodemcu-backdoor-upwm-hack-for-ir-signals/
+ +
+
+ +

◆ minRepeats()

+ +
+
+ + + + + +
+ + + + + + + + +
uint16_t IRsend::minRepeats (const decode_type_t protocol)
+
+static
+
+ +

Get the minimum number of repeats for a given protocol.

+
Parameters
+ + +
[in]protocolProtocol number/type of the message you want to send.
+
+
+
Returns
The number of repeats required.
+ +
+
+ +

◆ send() [1/2]

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
bool IRsend::send (const decode_type_t type,
const uint64_t data,
const uint16_t nbits,
const uint16_t repeat = kNoRepeat 
)
+
+ +

Send a simple (up to 64 bits) IR message of a given type. An unknown/unsupported type will send nothing.

+
Parameters
+ + + + + +
[in]typeProtocol number/type of the message you want to send.
[in]dataThe data you want to send (up to 64 bits).
[in]nbitsHow many bits long the message is to be.
[in]repeatHow many repeats to do?
+
+
+
Returns
True if it is a type we can attempt to send, false if not.
+ +
+
+ +

◆ send() [2/2]

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
bool IRsend::send (const decode_type_t type,
const uint8_t * state,
const uint16_t nbytes 
)
+
+ +

Send a complex (>= 64 bits) IR message of a given type. An unknown/unsupported type will send nothing.

+
Parameters
+ + + + +
[in]typeProtocol number/type of the message you want to send.
[in]stateA pointer to the array of bytes that make up the state[].
[in]nbytesHow many bytes are in the state.
+
+
+
Returns
True if it is a type we can attempt to send, false if not.
+ +
+
+ +

◆ sendAirwell()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendAirwell (uint64_t data,
uint16_t nbits = kAirwellBits,
uint16_t repeat = kAirwellMinRepeats 
)
+
+ +

Send an Airwell Manchester Code formatted message. Status: BETA / Appears to be working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of the message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/1069
+ +
+
+ +

◆ sendAiwaRCT501()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendAiwaRCT501 (uint64_t data,
uint16_t nbits = kAiwaRcT501Bits,
uint16_t repeat = kAiwaRcT501MinRepeats 
)
+
+ +

Send an Aiwa RC T501 formatted message. Status: BETA / Should work.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of the message to be sent. Typically kAiwaRcT501Bits. Max is 37 = (64 - 27)
[in]repeatThe number of times the command is to be repeated.
+
+
+
See also
http://lirc.sourceforge.net/remotes/aiwa/RC-T501
+ +
+
+ +

◆ sendAmcor()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendAmcor (const unsigned char data[],
const uint16_t nbytes = kAmcorStateLength,
const uint16_t repeat = kAmcorDefaultRepeat 
)
+
+ +

Send a Amcor HVAC formatted message. Status: STABLE / Reported as working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendArgo()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendArgo (const unsigned char data[],
const uint16_t nbytes = kArgoStateLength,
const uint16_t repeat = kArgoDefaultRepeat 
)
+
+ +

Send a Argo A/C formatted message. Status: BETA / Probably works.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendCarrierAC()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendCarrierAC (uint64_t data,
uint16_t nbits = kCarrierAcBits,
uint16_t repeat = kCarrierAcMinRepeat 
)
+
+ +

Send a Carrier HVAC formatted message. Status: STABLE / Works on real devices.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendCarrierAC40()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendCarrierAC40 (uint64_t data,
uint16_t nbits = kCarrierAc40Bits,
uint16_t repeat = kCarrierAc40MinRepeat 
)
+
+ +

Send a Carrier 40bit HVAC formatted message. Status: STABLE / Tested against a real device.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe bit size of the message being sent.
[in]repeatThe number of times the message is to be repeated.
+
+
+ +
+
+ +

◆ sendCarrierAC64()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendCarrierAC64 (uint64_t data,
uint16_t nbits = kCarrierAc64Bits,
uint16_t repeat = kCarrierAc64MinRepeat 
)
+
+ +

Send a Carrier 64bit HVAC formatted message. Status: STABLE / Known to be working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe bit size of the message being sent.
[in]repeatThe number of times the message is to be repeated.
+
+
+ +
+
+ +

◆ sendCOOLIX()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendCOOLIX (uint64_t data,
uint16_t nbits = kCoolixBits,
uint16_t repeat = kCoolixDefaultRepeat 
)
+
+ +

Send a Coolix message Status: STABLE / Confirmed Working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
See also
https://github.com/z3t0/Arduino-IRremote/blob/master/ir_COOLIX.cpp
+ +
+
+ +

◆ sendCoronaAc()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendCoronaAc (const uint8_t data[],
const uint16_t nbytes = kCoronaAcStateLength,
const uint16_t repeat = kNoRepeat 
)
+
+ +

Send a CoronaAc formatted message. Status: STABLE / Working on real device.

+
Parameters
+ + + + +
[in]dataAn array of bytes containing the IR command.
[in]nbytesNr. of bytes of data in the array. e.g.
uint8_t data[kCoronaAcStateLength] = {
+
0x28, 0x61, 0x3D, 0x19, 0xE6, 0x37, 0xC8,
+
0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00,
+
0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00};
+
[in]repeatNr. of times the message is to be repeated.
+
+
+ +
+
+ +

◆ sendDaikin()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendDaikin (const unsigned char data[],
const uint16_t nbytes = kDaikinStateLength,
const uint16_t repeat = kDaikinDefaultRepeat 
)
+
+ +

Send a Daikin 280-bit A/C formatted message. Status: STABLE.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
See also
https://github.com/mharizanov/Daikin-AC-remote-control-over-the-Internet/tree/master/IRremote
+
+https://github.com/blafois/Daikin-IR-Reverse
+ +
+
+ +

◆ sendDaikin128()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendDaikin128 (const unsigned char data[],
const uint16_t nbytes = kDaikin128StateLength,
const uint16_t repeat = kDaikin128DefaultRepeat 
)
+
+ +

Send a Daikin128 (128-bit) A/C formatted message. Status: STABLE / Known Working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/827
+ +
+
+ +

◆ sendDaikin152()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendDaikin152 (const unsigned char data[],
const uint16_t nbytes = kDaikin152StateLength,
const uint16_t repeat = kDaikin152DefaultRepeat 
)
+
+ +

Send a Daikin152 (152-bit) A/C formatted message. Status: STABLE / Known Working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/873
+ +
+
+ +

◆ sendDaikin160()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendDaikin160 (const unsigned char data[],
const uint16_t nbytes = kDaikin160StateLength,
const uint16_t repeat = kDaikin160DefaultRepeat 
)
+
+ +

Send a Daikin160 (160-bit) A/C formatted message. Status: STABLE / Confirmed working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/731
+ +
+
+ +

◆ sendDaikin176()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendDaikin176 (const unsigned char data[],
const uint16_t nbytes = kDaikin176StateLength,
const uint16_t repeat = kDaikin176DefaultRepeat 
)
+
+ +

Send a Daikin176 (176-bit) A/C formatted message. Status: Alpha / Untested on a real device.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendDaikin2()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendDaikin2 (const unsigned char data[],
const uint16_t nbytes = kDaikin2StateLength,
const uint16_t repeat = kDaikin2DefaultRepeat 
)
+
+ +

Send a Daikin2 (312-bit) A/C formatted message. Status: STABLE / Expected to work.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/582
+ +
+
+ +

◆ sendDaikin216()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendDaikin216 (const unsigned char data[],
const uint16_t nbytes = kDaikin216StateLength,
const uint16_t repeat = kDaikin216DefaultRepeat 
)
+
+ +

Send a Daikin216 (216-bit) A/C formatted message. Status: Alpha / Untested on a real device.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/689
+
+https://github.com/danny-source/Arduino_DY_IRDaikin
+ +
+
+ +

◆ sendDaikin64()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendDaikin64 (const uint64_t data,
const uint16_t nbits = kDaikin64Bits,
const uint16_t repeat = kDaikin64DefaultRepeat 
)
+
+ +

Send a Daikin64 (64-bit) A/C formatted message. Status: Beta / Probably Working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/1064
+ +
+
+ +

◆ sendData()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendData (uint16_t onemark,
uint32_t onespace,
uint16_t zeromark,
uint32_t zerospace,
uint64_t data,
uint16_t nbits,
bool MSBfirst = true 
)
+
+ +

Generic method for sending data that is common to most protocols. Will send leading or trailing 0's if the nbits is larger than the number of bits in data.

+
Parameters
+ + + + + + + + +
[in]onemarkNr. of usecs for the led to be pulsed for a '1' bit.
[in]onespaceNr. of usecs for the led to be fully off for a '1' bit.
[in]zeromarkNr. of usecs for the led to be pulsed for a '0' bit.
[in]zerospaceNr. of usecs for the led to be fully off for a '0' bit.
[in]dataThe data to be transmitted.
[in]nbitsNr. of bits of data to be sent.
[in]MSBfirstFlag for bit transmission order. Defaults to MSB->LSB order.
+
+
+ +
+
+ +

◆ sendDelonghiAc()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendDelonghiAc (uint64_t data,
uint16_t nbits = kDelonghiAcBits,
uint16_t repeat = kDelonghiAcDefaultRepeat 
)
+
+ +

Send a Delonghi A/C formatted message. Status: STABLE / Reported as working on a real device.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/1096
+ +
+
+ +

◆ sendDenon()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendDenon (uint64_t data,
uint16_t nbits = kDenonBits,
uint16_t repeat = kNoRepeat 
)
+
+ +

Send a Denon formatted message. Status: STABLE / Should be working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
Some Denon devices use a Kaseikyo/Panasonic 48-bit format Others use the Sharp protocol.
+ +
+
+ +

◆ sendDISH()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendDISH (uint64_t data,
uint16_t nbits = kDishBits,
uint16_t repeat = kDishMinRepeat 
)
+
+ +

Send a DISH NETWORK formatted message. Status: STABLE / Working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
Dishplayer is a different protocol. Typically a DISH device needs to get a command a total of at least 4 times to accept it. e.g. repeat=3
+

Here is the LIRC file I found that seems to match the remote codes from the oscilloscope: DISH NETWORK (echostar 301):

See also
http://lirc.sourceforge.net/remotes/echostar/301_501_3100_5100_58xx_59xx
+
+http://www.hifi-remote.com/wiki/index.php?title=Dish
+ +
+
+ +

◆ sendDoshisha()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendDoshisha (const uint64_t data,
uint16_t nbits = kDoshishaBits,
const uint16_t repeat = kNoRepeat 
)
+
+ +

Send a Doshisha formatted message. Status: STABLE / Works on real device.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendElectraAC()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendElectraAC (const unsigned char data[],
const uint16_t nbytes = kElectraAcStateLength,
const uint16_t repeat = kNoRepeat 
)
+
+ +

Send a Electra A/C formatted message. Status: Alpha / Needs testing against a real device.

+
Parameters
+ + +
[in]dataThe message to be sent.
+
+
+
Note
Guessing MSBF order.
+
Parameters
+ + + +
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendEpson()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendEpson (uint64_t data,
uint16_t nbits = kEpsonBits,
uint16_t repeat = kEpsonMinRepeat 
)
+
+ +

Send an Epson formatted message. Status: Beta / Probably works.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of nbits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendFujitsuAC()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendFujitsuAC (const unsigned char data[],
const uint16_t nbytes,
const uint16_t repeat = kFujitsuAcMinRepeat 
)
+
+ +

Send a Fujitsu A/C formatted message. Status: STABLE / Known Good.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent. Typically one of: kFujitsuAcStateLength, kFujitsuAcStateLength - 1, kFujitsuAcStateLengthShort, kFujitsuAcStateLengthShort - 1
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendGC()

+ +
+
+ + + + + + + + + + + + + + + + + + +
void IRsend::sendGC (uint16_t buf[],
uint16_t len 
)
+
+ +

Send a shortened GlobalCache (GC) IRdb/control tower formatted message. Status: STABLE / Known working.

+
Parameters
+ + + +
[in]bufArray of uint16_t containing the shortened GlobalCache data.
[in]lenNr. of entries in the buf[] array.
+
+
+
Note
Global Cache format without the emitter ID or request ID. Starts at the frequency (Hertz), followed by nr. of times to emit (count), then the offset for repeats (where a repeat will start from), then the rest of entries are the actual IR message as units of periodic time. e.g. sendir,1:1,1,38000,1,1,9,70,9,30,9,... -> 38000,1,1,9,70,9,30,9,...
+
See also
https://irdb.globalcache.com/Home/Database
+ +
+
+ +

◆ sendGeneric() [1/3]

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendGeneric (const uint16_t headermark,
const uint32_t headerspace,
const uint16_t onemark,
const uint32_t onespace,
const uint16_t zeromark,
const uint32_t zerospace,
const uint16_t footermark,
const uint32_t gap,
const uint32_t mesgtime,
const uint64_t data,
const uint16_t nbits,
const uint16_t frequency,
const bool MSBfirst,
const uint16_t repeat,
const uint8_t dutycycle 
)
+
+ +

Generic method for sending simple protocol messages. Will send leading or trailing 0's if the nbits is larger than the number of bits in data.

+
Parameters
+ + + + + + + + + + + + + + + + +
[in]headermarkNr. of usecs for the led to be pulsed for the header mark. A value of 0 means no header mark.
[in]headerspaceNr. of usecs for the led to be off after the header mark. A value of 0 means no header space.
[in]onemarkNr. of usecs for the led to be pulsed for a '1' bit.
[in]onespaceNr. of usecs for the led to be fully off for a '1' bit.
[in]zeromarkNr. of usecs for the led to be pulsed for a '0' bit.
[in]zerospaceNr. of usecs for the led to be fully off for a '0' bit.
[in]footermarkNr. of usecs for the led to be pulsed for the footer mark. A value of 0 means no footer mark.
[in]gapNr. of usecs for the led to be off after the footer mark. This is effectively the gap between messages. A value of 0 means no gap space.
[in]mesgtimeMin. nr. of usecs a single message needs to be. This is effectively the min. total length of a single message.
[in]dataThe data to be transmitted.
[in]nbitsNr. of bits of data to be sent.
[in]frequencyThe frequency we want to modulate at. (Hz/kHz)
[in]MSBfirstFlag for bit transmission order. Defaults to MSB->LSB order.
[in]repeatNr. of extra times the message will be sent. e.g. 0 = 1 message sent, 1 = 1 initial + 1 repeat = 2 messages
[in]dutycyclePercentage duty cycle of the LED. e.g. 25 = 25% = 1/4 on, 3/4 off. If you are not sure, try 50 percent.
+
+
+
Note
Assumes a frequency < 1000 means kHz otherwise it is in Hz. Most common value is 38000 or 38, for 38kHz.
+ +
+
+ +

◆ sendGeneric() [2/3]

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendGeneric (const uint16_t headermark,
const uint32_t headerspace,
const uint16_t onemark,
const uint32_t onespace,
const uint16_t zeromark,
const uint32_t zerospace,
const uint16_t footermark,
const uint32_t gap,
const uint64_t data,
const uint16_t nbits,
const uint16_t frequency,
const bool MSBfirst,
const uint16_t repeat,
const uint8_t dutycycle 
)
+
+ +

Generic method for sending simple protocol messages. Will send leading or trailing 0's if the nbits is larger than the number of bits in data.

+
Parameters
+ + + + + + + + + + + + + + + +
[in]headermarkNr. of usecs for the led to be pulsed for the header mark. A value of 0 means no header mark.
[in]headerspaceNr. of usecs for the led to be off after the header mark. A value of 0 means no header space.
[in]onemarkNr. of usecs for the led to be pulsed for a '1' bit.
[in]onespaceNr. of usecs for the led to be fully off for a '1' bit.
[in]zeromarkNr. of usecs for the led to be pulsed for a '0' bit.
[in]zerospaceNr. of usecs for the led to be fully off for a '0' bit.
[in]footermarkNr. of usecs for the led to be pulsed for the footer mark. A value of 0 means no footer mark.
[in]gapNr. of usecs for the led to be off after the footer mark. This is effectively the gap between messages. A value of 0 means no gap space.
[in]dataThe data to be transmitted.
[in]nbitsNr. of bits of data to be sent.
[in]frequencyThe frequency we want to modulate at. (Hz/kHz)
[in]MSBfirstFlag for bit transmission order. Defaults to MSB->LSB order.
[in]repeatNr. of extra times the message will be sent. e.g. 0 = 1 message sent, 1 = 1 initial + 1 repeat = 2 messages
[in]dutycyclePercentage duty cycle of the LED. e.g. 25 = 25% = 1/4 on, 3/4 off. If you are not sure, try 50 percent.
+
+
+
Note
Assumes a frequency < 1000 means kHz otherwise it is in Hz. Most common value is 38000 or 38, for 38kHz.
+ +
+
+ +

◆ sendGeneric() [3/3]

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendGeneric (const uint16_t headermark,
const uint32_t headerspace,
const uint16_t onemark,
const uint32_t onespace,
const uint16_t zeromark,
const uint32_t zerospace,
const uint16_t footermark,
const uint32_t gap,
const uint8_t * dataptr,
const uint16_t nbytes,
const uint16_t frequency,
const bool MSBfirst,
const uint16_t repeat,
const uint8_t dutycycle 
)
+
+ +

Generic method for sending simple protocol messages.

+
Parameters
+ + + + + + + + + + + + + + + +
[in]headermarkNr. of usecs for the led to be pulsed for the header mark. A value of 0 means no header mark.
[in]headerspaceNr. of usecs for the led to be off after the header mark. A value of 0 means no header space.
[in]onemarkNr. of usecs for the led to be pulsed for a '1' bit.
[in]onespaceNr. of usecs for the led to be fully off for a '1' bit.
[in]zeromarkNr. of usecs for the led to be pulsed for a '0' bit.
[in]zerospaceNr. of usecs for the led to be fully off for a '0' bit.
[in]footermarkNr. of usecs for the led to be pulsed for the footer mark. A value of 0 means no footer mark.
[in]gapNr. of usecs for the led to be off after the footer mark. This is effectively the gap between messages. A value of 0 means no gap space.
[in]dataptrPointer to the data to be transmitted.
[in]nbytesNr. of bytes of data to be sent.
[in]frequencyThe frequency we want to modulate at. (Hz/kHz)
[in]MSBfirstFlag for bit transmission order. Defaults to MSB->LSB order.
[in]repeatNr. of extra times the message will be sent. e.g. 0 = 1 message sent, 1 = 1 initial + 1 repeat = 2 messages
[in]dutycyclePercentage duty cycle of the LED. e.g. 25 = 25% = 1/4 on, 3/4 off. If you are not sure, try 50 percent.
+
+
+
Note
Assumes a frequency < 1000 means kHz otherwise it is in Hz. Most common value is 38000 or 38, for 38kHz.
+ +
+
+ +

◆ sendGICable()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendGICable (uint64_t data,
uint16_t nbits = kGicableBits,
uint16_t repeat = kGicableMinRepeat 
)
+
+ +

Send a raw G.I. Cable formatted message. Status: Alpha / Untested.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendGoodweather()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendGoodweather (const uint64_t data,
const uint16_t nbits = kGoodweatherBits,
const uint16_t repeat = kGoodweatherMinRepeat 
)
+
+ +

Send a Goodweather HVAC formatted message. Status: BETA / Needs testing on real device.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendGree() [1/2]

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendGree (const uint64_t data,
const uint16_t nbits = kGreeBits,
const uint16_t repeat = kGreeDefaultRepeat 
)
+
+ +

Send a Gree Heat Pump formatted message. Status: STABLE / Working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendGree() [2/2]

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendGree (const uint8_t data[],
const uint16_t nbytes = kGreeStateLength,
const uint16_t repeat = kGreeDefaultRepeat 
)
+
+ +

Send a Gree Heat Pump formatted message. Status: STABLE / Working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendHaierAC()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendHaierAC (const unsigned char data[],
const uint16_t nbytes = kHaierACStateLength,
const uint16_t repeat = kHaierAcDefaultRepeat 
)
+
+ +

Send a Haier A/C formatted message. (HSU07-HEA03 remote) Status: STABLE / Known to be working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendHaierACYRW02()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendHaierACYRW02 (const unsigned char data[],
const uint16_t nbytes = kHaierACYRW02StateLength,
const uint16_t repeat = kHaierAcYrw02DefaultRepeat 
)
+
+ +

Send a Haier YR-W02 remote A/C formatted message. Status: Alpha / Untested on a real device.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendHitachiAC()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendHitachiAC (const unsigned char data[],
const uint16_t nbytes = kHitachiAcStateLength,
const uint16_t repeat = kHitachiAcDefaultRepeat 
)
+
+ +

Send a Hitachi 28-byte/224-bit A/C formatted message. (HITACHI_AC) Status: STABLE / Working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/417
+ +
+
+ +

◆ sendHitachiAC1()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendHitachiAC1 (const unsigned char data[],
const uint16_t nbytes = kHitachiAc1StateLength,
const uint16_t repeat = kHitachiAcDefaultRepeat 
)
+
+ +

Send a Hitachi 13 byte/224-bit A/C formatted message. (HITACHI_AC1) Status: STABLE / Confirmed Working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
Basically the same as sendHitatchiAC() except different size & header.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/453
+ +
+
+ +

◆ sendHitachiAC2()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendHitachiAC2 (const unsigned char data[],
const uint16_t nbytes = kHitachiAc2StateLength,
const uint16_t repeat = kHitachiAcDefaultRepeat 
)
+
+ +

Send a Hitachi 53 byte/424-bit A/C formatted message. (HITACHI_AC2) Basically the same as sendHitatchiAC() except different size. Status: STABLE / Expected to work.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendHitachiAc3()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendHitachiAc3 (const unsigned char data[],
const uint16_t nbytes,
const uint16_t repeat = kHitachiAcDefaultRepeat 
)
+
+ +

Send a Hitachi(3) A/C formatted message. (HITACHI_AC3) Status: STABLE / Working fine.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
This protocol is almost exactly the same as HitachiAC424 except this variant has subtle timing differences. There are five(5) typical sizes: kHitachiAc3MinStateLength (Cancel Timer), kHitachiAc3MinStateLength + 2 (Change Temp), kHitachiAc3StateLength - 6 (Change Mode), kHitachiAc3StateLength - 4 (Normal), & kHitachiAc3StateLength (Set Timer)
+ +
+
+ +

◆ sendHitachiAc344()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendHitachiAc344 (const unsigned char data[],
const uint16_t nbytes = kHitachiAc344StateLength,
const uint16_t repeat = kHitachiAcDefaultRepeat 
)
+
+ +

Send a Hitachi A/C 43-byte/344-bit message. (HITACHI_AC344) Basically the same as sendHitatchiAC() except different size. Status: Beta / Probably works.

+
Parameters
+ + + + +
[in]dataAn array of bytes containing the IR command.
[in]nbytesNr. of bytes of data in the array.
[in]repeatNr. of times the message is to be repeated. (Default = 0).
+
+
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/1134
+ +
+
+ +

◆ sendHitachiAc424()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendHitachiAc424 (const unsigned char data[],
const uint16_t nbytes = kHitachiAc424StateLength,
const uint16_t repeat = kHitachiAcDefaultRepeat 
)
+
+ +

Send a Hitachi 53-byte/424-bit A/C formatted message. (HITACHI_AC424) Status: STABLE / Reported as working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
This protocol is almost exactly the same as HitachiAC2 except this variant has a leader section as well, and subtle timing differences. It is also in LSBF order (per byte), rather than MSBF order.
+ +
+
+ +

◆ sendInax()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendInax (const uint64_t data,
const uint16_t nbits = kInaxBits,
const uint16_t repeat = kInaxMinRepeat 
)
+
+ +

Send a Inax Toilet formatted message. Status: STABLE / Working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/706
+ +
+
+ +

◆ sendJVC()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendJVC (uint64_t data,
uint16_t nbits = kJvcBits,
uint16_t repeat = kNoRepeat 
)
+
+ +

Send a JVC formatted message. Status: STABLE / Working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
See also
http://www.sbprojects.com/knowledge/ir/jvc.php
+ +
+
+ +

◆ sendKelvinator()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendKelvinator (const unsigned char data[],
const uint16_t nbytes = kKelvinatorStateLength,
const uint16_t repeat = kKelvinatorDefaultRepeat 
)
+
+ +

Send a Kelvinator A/C message. Status: STABLE / Known working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendLasertag()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendLasertag (uint64_t data,
uint16_t nbits = kLasertagBits,
uint16_t repeat = kLasertagMinRepeat 
)
+
+ +

Send a Lasertag packet/message. Status: STABLE / Working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
This protocol is pretty much just raw Manchester encoding.
+
Todo:
Convert this to use sendManchester() if we can.`
+ +
+
+ +

◆ sendLegoPf()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendLegoPf (const uint64_t data,
const uint16_t nbits = kLegoPfBits,
const uint16_t repeat = kLegoPfMinRepeat 
)
+
+ +

Send a LEGO Power Functions message. Status: Beta / Should work.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
Non-zero repeats results in at least 5 messages per spec.
+ +
+
+ +

◆ sendLG()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendLG (uint64_t data,
uint16_t nbits = kLgBits,
uint16_t repeat = kNoRepeat 
)
+
+ +

Send an LG formatted message. (LG) Status: Beta / Should be working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent. Typically kLgBits or kLg32Bits.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
LG has a separate message to indicate a repeat, like NEC does.
+ +
+
+ +

◆ sendLG2()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendLG2 (uint64_t data,
uint16_t nbits = kLgBits,
uint16_t repeat = kNoRepeat 
)
+
+ +

Send an LG Variant-2 formatted message. (LG2) Status: Beta / Should be working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent. Typically kLgBits or kLg32Bits.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
LG has a separate message to indicate a repeat, like NEC does.
+ +
+
+ +

◆ sendLutron()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendLutron (uint64_t data,
uint16_t nbits = kLutronBits,
uint16_t repeat = kNoRepeat 
)
+
+ +

Send a Lutron formatted message. Status: Stable / Appears to be working for real devices.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
The protocol is really 36 bits long, but the first bit is always a 1. So, assume the 1 and only have a normal payload of 35 bits.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/515
+ +
+
+ +

◆ sendMagiQuest()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendMagiQuest (const uint64_t data,
const uint16_t nbits = kMagiquestBits,
const uint16_t repeat = kNoRepeat 
)
+
+ +

Send a MagiQuest formatted message. Status: Beta / Should be working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendManchester()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendManchester (const uint16_t headermark,
const uint32_t headerspace,
const uint16_t half_period,
const uint16_t footermark,
const uint32_t gap,
const uint64_t data,
const uint16_t nbits,
const uint16_t frequency = 38,
const bool MSBfirst = true,
const uint16_t repeat = kNoRepeat,
const uint8_t dutycycle = kDutyDefault,
const bool GEThomas = true 
)
+
+ +

Generic method for sending Manchester code messages. Will send leading or trailing 0's if the nbits is larger than the number.

+
Parameters
+ + + + + + + + + + + + + +
[in]headermarkNr. of usecs for the led to be pulsed for the header mark. A value of 0 means no header mark.
[in]headerspaceNr. of usecs for the led to be off after the header mark. A value of 0 means no header space.
[in]half_periodNr. of uSeconds for half the clock's period. (1/2 wavelength)
[in]footermarkNr. of usecs for the led to be pulsed for the footer mark. A value of 0 means no footer mark.
[in]gapMin. nr. of usecs for the led to be off after the footer mark. This is effectively the absolute minimum gap between messages.
[in]dataThe data to be transmitted.
[in]nbitsNr. of bits of data to be sent.
[in]frequencyThe frequency we want to modulate at. (Hz/kHz)
[in]MSBfirstFlag for bit transmission order. Defaults to MSB->LSB order.
[in]repeatNr. of extra times the message will be sent. e.g. 0 = 1 message sent, 1 = 1 initial + 1 repeat = 2 messages
[in]dutycyclePercentage duty cycle of the LED. e.g. 25 = 25% = 1/4 on, 3/4 off. If you are not sure, try 50 percent.
[in]GEThomasUse G.E. Thomas (true/default) or IEEE 802.3 (false).
+
+
+
Note
Assumes a frequency < 1000 means kHz otherwise it is in Hz. Most common value is 38000 or 38, for 38kHz.
+ +
+
+ +

◆ sendManchesterData()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendManchesterData (const uint16_t half_period,
const uint64_t data,
const uint16_t nbits,
const bool MSBfirst = true,
const bool GEThomas = true 
)
+
+ +

Generic method for sending Manchester code data. Will send leading or trailing 0's if the nbits is larger than the number of bits in data.

+
Parameters
+ + + + + + +
[in]half_periodNr. of uSeconds for half the clock's period. (1/2 wavelength)
[in]dataThe data to be transmitted.
[in]nbitsNr. of bits of data to be sent.
[in]MSBfirstFlag for bit transmission order. Defaults to MSB->LSB order.
[in]GEThomasUse G.E. Thomas (true/default) or IEEE 802.3 (false).
+
+
+ +
+
+ +

◆ sendMidea()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendMidea (uint64_t data,
uint16_t nbits = kMideaBits,
uint16_t repeat = kMideaMinRepeat 
)
+
+ +

Send a Midea message Status: Alpha / Needs testing against a real device.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendMidea24()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendMidea24 (const uint64_t data,
const uint16_t nbits = kMidea24Bits,
const uint16_t repeat = kMidea24MinRepeat 
)
+
+ +

Send a Midea24 formatted message. Status: STABLE / Confirmed working on a real device.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/1170
+
Note
This protocol is basically a 48-bit version of the NEC protocol with alternate bytes inverted, thus only 24 bits of real data, and with at least a single repeat.
+
Warning
Can't be used beyond 32 bits.
+ +
+
+ +

◆ sendMitsubishi()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendMitsubishi (uint64_t data,
uint16_t nbits = kMitsubishiBits,
uint16_t repeat = kMitsubishiMinRepeat 
)
+
+ +

Send the supplied Mitsubishi 16-bit message. Status: STABLE / Working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
This protocol appears to have no header.
+
See also
https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Mitsubishi.cpp
+
+GlobalCache's Control Tower's Mitsubishi TV data.
+ +
+
+ +

◆ sendMitsubishi112()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendMitsubishi112 (const unsigned char data[],
const uint16_t nbytes = kMitsubishi112StateLength,
const uint16_t repeat = kMitsubishi112MinRepeat 
)
+
+ +

Send a Mitsubishi 112-bit A/C formatted message. (MITSUBISHI112) Status: Stable / Reported as working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/947
+ +
+
+ +

◆ sendMitsubishi136()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendMitsubishi136 (const unsigned char data[],
const uint16_t nbytes = kMitsubishi136StateLength,
const uint16_t repeat = kMitsubishi136MinRepeat 
)
+
+ +

Send a Mitsubishi 136-bit A/C message. (MITSUBISHI136) Status: BETA / Probably working. Needs to be tested against a real device.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/888
+ +
+
+ +

◆ sendMitsubishi2()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendMitsubishi2 (uint64_t data,
uint16_t nbits = kMitsubishiBits,
uint16_t repeat = kMitsubishiMinRepeat 
)
+
+ +

Send a supplied second variant Mitsubishi 16-bit message. Status: BETA / Probably works.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
Based on a Mitsubishi HC3000 projector's remote. This protocol appears to have a manditory in-protocol repeat. That is in addition to the entire message needing to be sent twice for the device to accept the command. That is separate from the repeat. i.e. Allegedly, the real remote requires the "Off" button pressed twice. You will need to add a suitable gap yourself.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/441
+ +
+
+ +

◆ sendMitsubishiAC()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendMitsubishiAC (const unsigned char data[],
const uint16_t nbytes = kMitsubishiACStateLength,
const uint16_t repeat = kMitsubishiACMinRepeat 
)
+
+ +

Send a Mitsubishi 144-bit A/C formatted message. (MITSUBISHI_AC) Status: STABLE / Working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendMitsubishiHeavy152()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendMitsubishiHeavy152 (const unsigned char data[],
const uint16_t nbytes = kMitsubishiHeavy152StateLength,
const uint16_t repeat = kMitsubishiHeavy152MinRepeat 
)
+
+ +

Send a MitsubishiHeavy 152-bit A/C message. Status: BETA / Appears to be working. Needs testing against a real device.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendMitsubishiHeavy88()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendMitsubishiHeavy88 (const unsigned char data[],
const uint16_t nbytes = kMitsubishiHeavy88StateLength,
const uint16_t repeat = kMitsubishiHeavy88MinRepeat 
)
+
+ +

Send a MitsubishiHeavy 88-bit A/C message. Status: BETA / Appears to be working. Needs testing against a real device.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendMultibrackets()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendMultibrackets (const uint64_t data,
const uint16_t nbits = kMultibracketsBits,
const uint16_t repeat = kMultibracketsDefaultRepeat 
)
+
+ +

Send a Multibrackets formatted message. Status: BETA / Appears to be working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendMWM()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendMWM (const unsigned char data[],
const uint16_t nbytes,
const uint16_t repeat = kNoRepeat 
)
+
+ +

Send a MWM packet/message. Status: Implemented.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
This protocol is 2400 bps serial, 1 start bit (mark), 1 stop bit (space), no parity
+ +
+
+ +

◆ sendNEC()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendNEC (uint64_t data,
uint16_t nbits = kNECBits,
uint16_t repeat = kNoRepeat 
)
+
+ +

Send a raw NEC(Renesas) formatted message. Status: STABLE / Known working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
This protocol appears to have no header.
+
See also
http://www.sbprojects.com/knowledge/ir/nec.php
+ +
+
+ +

◆ sendNeoclima()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendNeoclima (const unsigned char data[],
const uint16_t nbytes = kNeoclimaStateLength,
const uint16_t repeat = kNeoclimaMinRepeat 
)
+
+ +

Send a Neoclima message. Status: STABLE / Known to be working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendNikai()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendNikai (uint64_t data,
uint16_t nbits = kNikaiBits,
uint16_t repeat = kNoRepeat 
)
+
+ +

Send a Nikai formatted message. Status: STABLE / Working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendPanasonic()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendPanasonic (const uint16_t address,
const uint32_t data,
const uint16_t nbits = kPanasonicBits,
const uint16_t repeat = kNoRepeat 
)
+
+ +

Send a Panasonic formatted message. Status: STABLE, but DEPRECATED.

+
Deprecated:
This is only for legacy use only, please use sendPanasonic64() instead.
+
Parameters
+ + + + + +
[in]addressThe 16-bit manufacturer code.
[in]dataThe 32-bit data portion of the message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
This protocol is a modified version of Kaseikyo.
+ +
+
+ +

◆ sendPanasonic64()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendPanasonic64 (const uint64_t data,
const uint16_t nbits = kPanasonicBits,
const uint16_t repeat = kNoRepeat 
)
+
+ +

Send a Panasonic formatted message. Status: STABLE / Should be working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
This protocol is a modified version of Kaseikyo.
+
+Use this method if you want to send the results of decodePanasonic.
+ +
+
+ +

◆ sendPanasonicAC()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendPanasonicAC (const unsigned char data[],
const uint16_t nbytes = kPanasonicAcStateLength,
const uint16_t repeat = kPanasonicAcDefaultRepeat 
)
+
+ +

Send a Panasonic A/C message. Status: STABLE / Work with real device(s).

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendPioneer()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendPioneer (const uint64_t data,
const uint16_t nbits = kPioneerBits,
const uint16_t repeat = kNoRepeat 
)
+
+ +

Send a raw Pioneer formatted message. Status: STABLE / Expected to be working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendPronto()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendPronto (uint16_t data[],
uint16_t len,
uint16_t repeat = kNoRepeat 
)
+
+ +

Send a Pronto Code formatted message. Status: STABLE / Known working.

+
Parameters
+ + + + +
[in]dataAn array of uint16_t containing the pronto codes.
[in]lenNr. of entries in the data[] array.
[in]repeatNr. of times to repeat the message.
+
+
+
Note
Pronto codes are typically represented in hexadecimal. You will need to convert the code to an array of integers, and calculate it's length. e.g.
A Sony 20 bit DVD remote command.
+
"0000 0067 0000 0015 0060 0018 0018 0018 0030 0018 0030 0018 0030 0018
+
0018 0018 0030 0018 0018 0018 0018 0018 0030 0018 0018 0018 0030 0018
+
0030 0018 0030 0018 0018 0018 0018 0018 0030 0018 0018 0018 0018 0018
+
0030 0018 0018 03f6"
+
converts to:
uint16_t prontoCode[46] = {
+
0x0000, 0x0067, 0x0000, 0x0015,
+
0x0060, 0x0018, 0x0018, 0x0018, 0x0030, 0x0018, 0x0030, 0x0018,
+
0x0030, 0x0018, 0x0018, 0x0018, 0x0030, 0x0018, 0x0018, 0x0018,
+
0x0018, 0x0018, 0x0030, 0x0018, 0x0018, 0x0018, 0x0030, 0x0018,
+
0x0030, 0x0018, 0x0030, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018,
+
0x0030, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0030, 0x0018,
+
0x0018, 0x03f6};
+
// Send the Pronto(Sony) code. Repeat twice as Sony's require that.
+
sendPronto(prontoCode, 46, kSonyMinRepeat);
+
+
See also
http://www.etcwiki.org/wiki/Pronto_Infrared_Format
+
+http://www.remotecentral.com/features/irdisp2.htm
+ +
+
+ +

◆ sendRaw()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendRaw (const uint16_t buf[],
const uint16_t len,
const uint16_t hz 
)
+
+ +

Send a raw IRremote message.

+
Parameters
+ + + + +
[in]bufAn array of uint16_t's that has microseconds elements.
[in]lenNr. of elements in the buf[] array.
[in]hzFrequency to send the message at. (kHz < 1000; Hz >= 1000)
+
+
+
Note
Even elements are Mark times (On), Odd elements are Space times (Off). Ref: examples/IRrecvDumpV2/IRrecvDumpV2.ino (or later)
+ +
+
+ +

◆ sendRC5()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendRC5 (const uint64_t data,
uint16_t nbits = kRC5XBits,
const uint16_t repeat = kNoRepeat 
)
+
+ +

Send a Philips RC-5/RC-5X packet. Status: RC-5 (stable), RC-5X (alpha)

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
Caller needs to take care of flipping the toggle bit. That bit differentiates between key press & key release. For RC-5 it is the MSB of the data. For RC-5X it is the 2nd MSB of the data.
+
Todo:
Testing of the RC-5X components.
+ +
+
+ +

◆ sendRC6()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendRC6 (const uint64_t data,
const uint16_t nbits = kRC6Mode0Bits,
const uint16_t repeat = kNoRepeat 
)
+
+ +

Send a Philips RC-6 packet. Status: Stable.

+
Note
Caller needs to take care of flipping the toggle bit (The 4th Most Significant Bit). That bit differentiates between key press & key release.
+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendRCMM()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendRCMM (uint64_t data,
uint16_t nbits = kRCMMBits,
uint16_t repeat = kNoRepeat 
)
+
+ +

Send a Philips RC-MM packet. Status: STABLE / Should be working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendSAMSUNG()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendSAMSUNG (const uint64_t data,
const uint16_t nbits = kSamsungBits,
const uint16_t repeat = kNoRepeat 
)
+
+ +

Send a 32-bit Samsung formatted message. Status: STABLE / Should be working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
See also
http://elektrolab.wz.cz/katalog/samsung_protocol.pdf
+
Note
Samsung has a separate message to indicate a repeat, like NEC does.
+
Todo:
Confirm that is actually how Samsung sends a repeat. The refdoc doesn't indicate it is true.
+ +
+
+ +

◆ sendSamsung36()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendSamsung36 (const uint64_t data,
const uint16_t nbits = kSamsung36Bits,
const uint16_t repeat = kNoRepeat 
)
+
+ +

Send a Samsung 36-bit formatted message. Status: Alpha / Experimental.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/621
+ +
+
+ +

◆ sendSamsungAC()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendSamsungAC (const unsigned char data[],
const uint16_t nbytes = kSamsungAcStateLength,
const uint16_t repeat = kSamsungAcDefaultRepeat 
)
+
+ +

Send a Samsung A/C message. Status: Stable / Known working.

+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/505
+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendSanyoLC7461()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendSanyoLC7461 (const uint64_t data,
const uint16_t nbits = kSanyoLC7461Bits,
const uint16_t repeat = kNoRepeat 
)
+
+ +

Send a Sanyo LC7461 message. Status: BETA / Probably works.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
Based on @marcosamarinho's work. This protocol uses the NEC protocol timings. However, data is formatted as : address(13 bits), !address, command (8 bits), !command. According with LIRC, this protocol is used on Sanyo, Aiwa and Chinon Information for this protocol is available at the Sanyo LC7461 datasheet. Repeats are performed similar to the NEC method of sending a special repeat message, rather than duplicating the entire message.
+
See also
https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Sanyo.cpp
+
+http://pdf.datasheetcatalog.com/datasheet/sanyo/LC7461.pdf
+ +
+
+ +

◆ sendSharp()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendSharp (const uint16_t address,
const uint16_t command,
const uint16_t nbits = kSharpBits,
const uint16_t repeat = kNoRepeat 
)
+
+ +

Send a Sharp message Status: DEPRECATED / Previously working fine.

+
Deprecated:
Only use this if you are using legacy from the original Arduino-IRremote library. 99% of the time, you will want to use sendSharpRaw() instead
+
Parameters
+ + + + + +
[in]addressAddress value to be sent.
[in]commandCommand value to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
This procedure has a non-standard invocation style compared to similar sendProtocol() routines. This is due to legacy, compatibility, & historic reasons. Normally the calling syntax version is like sendSharpRaw(). This procedure transmits the address & command in MSB first order, which is incorrect. This behaviour is left as-is to maintain backward compatibility with legacy code. In short, you should use sendSharpRaw(), encodeSharp(), and the correct values of address & command instead of using this, & the wrong values.
+ +
+
+ +

◆ sendSharpAc()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendSharpAc (const unsigned char data[],
const uint16_t nbytes = kSharpAcStateLength,
const uint16_t repeat = kSharpAcDefaultRepeat 
)
+
+ +

Send a Sharp A/C message. Status: Alpha / Untested.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/638
+
+https://github.com/ToniA/arduino-heatpumpir/blob/master/SharpHeatpumpIR.cpp
+ +
+
+ +

◆ sendSharpRaw()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendSharpRaw (const uint64_t data,
const uint16_t nbits = kSharpBits,
const uint16_t repeat = kNoRepeat 
)
+
+ +

Send a (raw) Sharp message.

+
Note
Status: STABLE / Working fine.
+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
his procedure handles the inversion of bits required per protocol. The protocol spec says to send the LSB first, but legacy code & usage has us sending the MSB first. Grrrr. Normal invocation of encodeSharp() handles this for you, assuming you are using the correct/standard values. e.g. sendSharpRaw(encodeSharp(address, command));
+ +
+
+ +

◆ sendSherwood()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendSherwood (uint64_t data,
uint16_t nbits = kSherwoodBits,
uint16_t repeat = kSherwoodMinRepeat 
)
+
+ +

Send an IR command to a Sherwood device. Status: STABLE / Known working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
Sherwood remote codes appear to be NEC codes with a manditory repeat code. i.e. repeat should be >= kSherwoodMinRepeat (1).
+ +
+
+ +

◆ sendSony()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendSony (const uint64_t data,
const uint16_t nbits = kSony20Bits,
const uint16_t repeat = kSonyMinRepeat 
)
+
+ +

Send a standard Sony/SIRC(Serial Infra-Red Control) message. (40kHz) Status: STABLE / Known working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
sendSony() should typically be called with repeat=2 as Sony devices expect the message to be sent at least 3 times.
+ +
+
+ +

◆ sendSony38()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendSony38 (const uint64_t data,
const uint16_t nbits = kSony20Bits,
const uint16_t repeat = kSonyMinRepeat + 1 
)
+
+ +

Send an alternative 38kHz Sony/SIRC(Serial Infra-Red Control) message. Status: STABLE / Known working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
Note
sendSony38() should typically be called with repeat=3 as these Sony devices expect the message to be sent at least 4 times.
+
Warning
Messages send via this method will be detected by this library as just SONY, not SONY_38K as the library has no way to determine the modulation frequency used. Hence, there is no decodeSony38().
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/1018
+ +
+
+ +

◆ sendSymphony()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendSymphony (uint64_t data,
uint16_t nbits = kSymphonyBits,
uint16_t repeat = kSymphonyDefaultRepeat 
)
+
+ +

Send a Symphony packet. Status: STABLE / Should be working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendTcl112Ac()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendTcl112Ac (const unsigned char data[],
const uint16_t nbytes = kTcl112AcStateLength,
const uint16_t repeat = kTcl112AcDefaultRepeat 
)
+
+ +

Send a TCL 112-bit A/C message. Status: Beta / Probably working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendTeco()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendTeco (const uint64_t data,
const uint16_t nbits = kTecoBits,
const uint16_t repeat = kNoRepeat 
)
+
+ +

Send a Teco A/C message. Status: Beta / Probably working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendToshibaAC()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendToshibaAC (const unsigned char data[],
const uint16_t nbytes = kToshibaACStateLength,
const uint16_t repeat = kToshibaACMinRepeat 
)
+
+ +

Send a Toshiba A/C message. Status: STABLE / Working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendTrotec()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendTrotec (const unsigned char data[],
const uint16_t nbytes = kTrotecStateLength,
const uint16_t repeat = kTrotecDefaultRepeat 
)
+
+ +

Send a Trotec message. Status: Beta / Probably Working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendVestelAc()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendVestelAc (const uint64_t data,
const uint16_t nbits = kVestelAcBits,
const uint16_t repeat = kNoRepeat 
)
+
+ +

Send a Vestel message Status: STABLE / Working.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendWhirlpoolAC()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendWhirlpoolAC (const unsigned char data[],
const uint16_t nbytes = kWhirlpoolAcStateLength,
const uint16_t repeat = kWhirlpoolAcDefaultRepeat 
)
+
+ +

Send a Whirlpool A/C message. Status: BETA / Probably works.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbytesThe number of bytes of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+ +
+
+ +

◆ sendWhynter()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendWhynter (const uint64_t data,
const uint16_t nbits = kWhynterBits,
const uint16_t repeat = kNoRepeat 
)
+
+ +

Send a Whynter message. Status: STABLE.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe number of bits of message to be sent.
[in]repeatThe number of times the command is to be repeated.
+
+
+
See also
https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Whynter.cpp
+ +
+
+ +

◆ sendZepeal()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void IRsend::sendZepeal (const uint64_t data,
const uint16_t nbits = kZepealBits,
const uint16_t repeat = kZepealMinRepeat 
)
+
+ +

Send a Zepeal formatted message. Status: STABLE / Works on real device.

+
Parameters
+ + + + +
[in]dataThe message to be sent.
[in]nbitsThe bit size of the message being sent.
[in]repeatThe number of times the message is to be repeated.
+
+
+ +
+
+ +

◆ space()

+ +
+
+ + + + + + + + +
void IRsend::space (uint32_t time)
+
+ +

Turn the pin (LED) off for a given time. Sends an IR space for the specified number of microseconds. A space is no output, so the PWM output is disabled.

+
Parameters
+ + +
[in]timeTime in microseconds (us).
+
+
+ +
+
+ +

◆ toggleRC5()

+ +
+
+ + + + + + + + +
uint64_t IRsend::toggleRC5 (const uint64_t data)
+
+ +

Flip the toggle bit of a Philips RC-5/RC-5X data message. Used to indicate a change of remote button's state. Status: STABLE.

+
Parameters
+ + +
[in]dataThe existing RC-5/RC-5X message.
+
+
+
Returns
A data message suitable for use in sendRC5() with the toggle bit flipped.
+ +
+
+ +

◆ toggleRC6()

+ +
+
+ + + + + + + + + + + + + + + + + + +
uint64_t IRsend::toggleRC6 (const uint64_t data,
const uint16_t nbits = kRC6Mode0Bits 
)
+
+ +

Flip the toggle bit of a Philips RC-6 data message. Used to indicate a change of remote button's state. Status: STABLE / Should work fine.

+
Parameters
+ + + +
[in]dataThe existing RC-6 message.
[in]nbitsNr. of bits in the RC-6 protocol.
+
+
+
Returns
A data message suitable for use in sendRC6() with the toggle bit flipped.
+
Note
For RC-6 (20-bits), it is the 17th least significant bit.
+
+For RC-6 (36-bits/Xbox-360), it is the 16th least significant bit.
+ +
+
+

Member Data Documentation

+ +

◆ _dutycycle

+ +
+
+ + + + + +
+ + + + +
uint8_t IRsend::_dutycycle
+
+private
+
+ +
+
+ +

◆ _freq_unittest

+ +
+
+ + + + + +
+ + + + +
uint32_t IRsend::_freq_unittest
+
+private
+
+ +
+
+ +

◆ IRpin

+ +
+
+ + + + + +
+ + + + +
uint16_t IRsend::IRpin
+
+private
+
+ +
+
+ +

◆ modulation

+ +
+
+ + + + + +
+ + + + +
bool IRsend::modulation
+
+private
+
+ +
+
+ +

◆ offTimePeriod

+ +
+
+ + + + + +
+ + + + +
uint16_t IRsend::offTimePeriod
+
+private
+
+ +
+
+ +

◆ onTimePeriod

+ +
+
+ + + + + +
+ + + + +
uint16_t IRsend::onTimePeriod
+
+private
+
+ +
+
+ +

◆ outputOff

+ +
+
+ + + + + +
+ + + + +
uint8_t IRsend::outputOff
+
+protected
+
+ +
+
+ +

◆ outputOn

+ +
+
+ + + + + +
+ + + + +
uint8_t IRsend::outputOn
+
+protected
+
+ +
+
+ +

◆ periodOffset

+ +
+
+ + + + + +
+ + + + +
int8_t IRsend::periodOffset
+
+private
+
+ +
+
+
The documentation for this class was generated from the following files: +
+
void sendPronto(uint16_t data[], uint16_t len, uint16_t repeat=kNoRepeat)
Send a Pronto Code formatted message. Status: STABLE / Known working.
Definition: ir_Pronto.cpp:56
+
const uint16_t kCoronaAcStateLength
Definition: IRremoteESP8266.h:833
+
const uint16_t kSonyMinRepeat
Definition: IRremoteESP8266.h:991
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRtimer-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRtimer-members.html new file mode 100644 index 000000000..b1603a411 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRtimer-members.html @@ -0,0 +1,84 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
IRtimer Member List
+
+
+ +

This is the complete list of members for IRtimer, including all inherited members.

+ + + + + + +
add(uint32_t usecs)IRtimerstatic
elapsed()IRtimer
IRtimer()IRtimer
reset()IRtimer
startIRtimerprivate
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRtimer.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRtimer.html new file mode 100644 index 000000000..b0d7fac99 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classIRtimer.html @@ -0,0 +1,235 @@ + + + + + + + +IRremoteESP8266: IRtimer Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

This class performs a simple timer in useconds since instantiated. + More...

+ +

#include <IRtimer.h>

+ + + + + + + + + + + +

+Public Member Functions

 IRtimer ()
 Class constructor. More...
 
void reset ()
 Resets the IRtimer object. More...
 
uint32_t elapsed ()
 Calculate how many microseconds have elapsed since the timer was started. More...
 
+ + + + +

+Static Public Member Functions

static void add (uint32_t usecs)
 Add time to the timer to simulate elapsed time. More...
 
+ + + +

+Private Attributes

uint32_t start
 
+

Detailed Description

+

This class performs a simple timer in useconds since instantiated.

+
Note
Handles when the system timer wraps around (once).
+

Constructor & Destructor Documentation

+ +

◆ IRtimer()

+ +
+
+ + + + + + + +
IRtimer::IRtimer ()
+
+ +

Class constructor.

+ +
+
+

Member Function Documentation

+ +

◆ add()

+ +
+
+ + + + + +
+ + + + + + + + +
void IRtimer::add (uint32_t usecs)
+
+static
+
+ +

Add time to the timer to simulate elapsed time.

+
Parameters
+ + +
[in]usecsNr. of uSeconds to be added.
+
+
+
Note
Only used in unit testing.
+ +
+
+ +

◆ elapsed()

+ +
+
+ + + + + + + +
uint32_t IRtimer::elapsed ()
+
+ +

Calculate how many microseconds have elapsed since the timer was started.

+
Returns
Nr. of microseconds.
+ +
+
+ +

◆ reset()

+ +
+
+ + + + + + + +
void IRtimer::reset ()
+
+ +

Resets the IRtimer object.

+ +
+
+

Member Data Documentation

+ +

◆ start

+ +
+
+ + + + + +
+ + + + +
uint32_t IRtimer::start
+
+private
+
+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classTimerMs-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classTimerMs-members.html new file mode 100644 index 000000000..63f0f8ba0 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classTimerMs-members.html @@ -0,0 +1,84 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
TimerMs Member List
+
+
+ +

This is the complete list of members for TimerMs, including all inherited members.

+ + + + + + +
add(uint32_t msecs)TimerMsstatic
elapsed()TimerMs
reset()TimerMs
startTimerMsprivate
TimerMs()TimerMs
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classTimerMs.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classTimerMs.html new file mode 100644 index 000000000..a67791242 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classTimerMs.html @@ -0,0 +1,235 @@ + + + + + + + +IRremoteESP8266: TimerMs Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +

This class performs a simple timer in milli-seoncds since instantiated. + More...

+ +

#include <IRtimer.h>

+ + + + + + + + + + + +

+Public Member Functions

 TimerMs ()
 Class constructor. More...
 
void reset ()
 Resets the TimerMs object. More...
 
uint32_t elapsed ()
 Calculate how many milliseconds have elapsed since the timer was started. More...
 
+ + + + +

+Static Public Member Functions

static void add (uint32_t msecs)
 Add time to the timer to simulate elapsed time. More...
 
+ + + +

+Private Attributes

uint32_t start
 
+

Detailed Description

+

This class performs a simple timer in milli-seoncds since instantiated.

+
Note
Handles when the system timer wraps around (once).
+

Constructor & Destructor Documentation

+ +

◆ TimerMs()

+ +
+
+ + + + + + + +
TimerMs::TimerMs ()
+
+ +

Class constructor.

+ +
+
+

Member Function Documentation

+ +

◆ add()

+ +
+
+ + + + + +
+ + + + + + + + +
void TimerMs::add (uint32_t msecs)
+
+static
+
+ +

Add time to the timer to simulate elapsed time.

+
Parameters
+ + +
[in]msecsNr. of mSeconds to be added.
+
+
+
Note
Only used in unit testing.
+ +
+
+ +

◆ elapsed()

+ +
+
+ + + + + + + +
uint32_t TimerMs::elapsed ()
+
+ +

Calculate how many milliseconds have elapsed since the timer was started.

+
Returns
Nr. of milliseconds.
+ +
+
+ +

◆ reset()

+ +
+
+ + + + + + + +
void TimerMs::reset ()
+
+ +

Resets the TimerMs object.

+ +
+
+

Member Data Documentation

+ +

◆ start

+ +
+
+ + + + + +
+ + + + +
uint32_t TimerMs::start
+
+private
+
+ +
+
+
The documentation for this class was generated from the following files: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classdecode__results-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classdecode__results-members.html new file mode 100644 index 000000000..5939b876d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classdecode__results-members.html @@ -0,0 +1,89 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
decode_results Member List
+
+ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classdecode__results.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classdecode__results.html new file mode 100644 index 000000000..2028cee12 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classdecode__results.html @@ -0,0 +1,274 @@ + + + + + + + +IRremoteESP8266: decode_results Class Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
decode_results Class Reference
+
+
+ +

Results returned from the decoder. + More...

+ +

#include <IRrecv.h>

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Attributes

decode_type_t decode_type
 
union {
   struct {
      uint64_t   value
 
      uint32_t   address
 
      uint32_t   command
 
   } 
 
   uint8_t   state [kStateSizeMax]
 
}; 
 
uint16_t bits
 
volatile uint16_t * rawbuf
 
uint16_t rawlen
 
bool overflow
 
bool repeat
 
+

Detailed Description

+

Results returned from the decoder.

+

Member Data Documentation

+ +

◆ @2

+ +
+
+ + + + +
union { ... }
+
+ +
+
+ +

◆ address

+ +
+
+ + + + +
uint32_t decode_results::address
+
+ +
+
+ +

◆ bits

+ +
+
+ + + + +
uint16_t decode_results::bits
+
+ +
+
+ +

◆ command

+ +
+
+ + + + +
uint32_t decode_results::command
+
+ +
+
+ +

◆ decode_type

+ +
+
+ + + + +
decode_type_t decode_results::decode_type
+
+ +
+
+ +

◆ overflow

+ +
+
+ + + + +
bool decode_results::overflow
+
+ +
+
+ +

◆ rawbuf

+ +
+
+ + + + +
volatile uint16_t* decode_results::rawbuf
+
+ +
+
+ +

◆ rawlen

+ +
+
+ + + + +
uint16_t decode_results::rawlen
+
+ +
+
+ +

◆ repeat

+ +
+
+ + + + +
bool decode_results::repeat
+
+ +
+
+ +

◆ state

+ +
+
+ + + + +
uint8_t decode_results::state[kStateSizeMax]
+
+ +
+
+ +

◆ value

+ +
+
+ + + + +
uint64_t decode_results::value
+
+ +
+
+
The documentation for this class was generated from the following file: +
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classes.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classes.html new file mode 100644 index 000000000..72eebee83 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/classes.html @@ -0,0 +1,157 @@ + + + + + + + +IRremoteESP8266: Class Index + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+
Class Index
+
+
+
d | i | m | s | t
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  d  
+
IRDaikin160   IRHitachiAc   IRNeoclimaAc   IRWhirlpoolAc   
IRDaikin176   IRHitachiAc1   IRPanasonicAc   
  m  
+
decode_results   IRDaikin2   IRHitachiAc3   irparams_t   
  i  
+
IRDaikin216   IRHitachiAc344   IRrecv   magiquest   
IRDaikin64   IRHitachiAc424   IRSamsungAc   match_result_t   
IRac   IRDaikinESP   IRKelvinatorAC   IRsend   
  s  
+
IRAmcorAc   IRDelonghiAc   IRLgAc   IRSharpAc   
IRArgoAC   IRElectraAc   IRMideaAC   IRTcl112Ac   state_t (stdAc)   
IRCarrierAc64   IRFujitsuAC   IRMitsubishi112   IRTecoAc   
  t  
+
IRCoolixAC   IRGoodweatherAc   IRMitsubishi136   IRtimer   
IRCoronaAc   IRGreeAC   IRMitsubishiAC   IRToshibaAC   TimerMs   
IRDaikin128   IRHaierAC   IRMitsubishiHeavy152Ac   IRTrotecESP   
IRDaikin152   IRHaierACYRW02   IRMitsubishiHeavy88Ac   IRVestelAc   
+
d | i | m | s | t
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/closed.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/closed.png new file mode 100644 index 000000000..98cc2c909 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/closed.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/de-CH_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/de-CH_8h.html new file mode 100644 index 000000000..d0cada931 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/de-CH_8h.html @@ -0,0 +1,82 @@ + + + + + + + +IRremoteESP8266: src/locale/de-CH.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
de-CH.h File Reference
+
+ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/de-CH_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/de-CH_8h_source.html new file mode 100644 index 000000000..8ad5119f2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/de-CH_8h_source.html @@ -0,0 +1,239 @@ + + + + + + + +IRremoteESP8266: src/locale/de-CH.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
de-CH.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 - Martin (@finfinack)
+
2 // Locale/language file for German / Switzerland.
+
3 // This file will override the default values located in `defaults.h`.
+
4 #ifndef LOCALE_DE_CH_H_
+
5 #define LOCALE_DE_CH_H_
+
6 
+
7 // Import German / Germany as default overrides.
+
8 #include "locale/de-DE.h"
+
9 
+
10 // As we have loaded another language, we need to #undef anything we need
+
11 // to update/change.
+
12 
+
13 #undef D_STR_ON
+
14 #define D_STR_ON "Ii"
+
15 #undef D_STR_OFF
+
16 #define D_STR_OFF "Us"
+
17 #undef D_STR_TOGGLE
+
18 #define D_STR_TOGGLE "Umschalte"
+
19 #undef D_STR_SLEEP
+
20 #define D_STR_SLEEP "Schlafe"
+
21 #undef D_STR_LIGHT
+
22 #define D_STR_LIGHT "Liecht"
+
23 #undef D_STR_POWERFUL
+
24 #define D_STR_POWERFUL "Starch"
+
25 #undef D_STR_QUIET
+
26 #define D_STR_QUIET "Liislig"
+
27 #undef D_STR_CLEAN
+
28 #define D_STR_CLEAN "Reinige"
+
29 #undef D_STR_PURIFY
+
30 #define D_STR_PURIFY "Frische"
+
31 #undef D_STR_HEALTH
+
32 #define D_STR_HEALTH "Gsundheit"
+
33 #undef D_STR_HUMID
+
34 #define D_STR_HUMID "Füecht"
+
35 #undef D_STR_SAVE
+
36 #define D_STR_SAVE "Speichere"
+
37 #undef D_STR_EYE
+
38 #define D_STR_EYE "Aug"
+
39 #undef D_STR_FOLLOW
+
40 #define D_STR_FOLLOW "Folge"
+
41 #undef D_STR_HOLD
+
42 #define D_STR_HOLD "Halte"
+
43 #undef D_STR_BUTTON
+
44 #define D_STR_BUTTON "Chnopf"
+
45 #undef D_STR_UP
+
46 #define D_STR_UP "Ufe"
+
47 #undef D_STR_TEMPUP
+
48 #define D_STR_TEMPUP D_STR_TEMP " " D_STR_UP
+
49 #undef D_STR_DOWN
+
50 #define D_STR_DOWN "Abe"
+
51 #undef D_STR_TEMPDOWN
+
52 #define D_STR_TEMPDOWN D_STR_TEMP " " D_STR_DOWN
+
53 #undef D_STR_CHANGE
+
54 #define D_STR_CHANGE "Wechsele"
+
55 #undef D_STR_MOVE
+
56 #define D_STR_MOVE "Verschiebe"
+
57 #undef D_STR_SET
+
58 #define D_STR_SET "Setze"
+
59 #undef D_STR_CANCEL
+
60 #define D_STR_CANCEL "Abbreche"
+
61 #undef D_STR_WEEKLY
+
62 #define D_STR_WEEKLY "Wüchentlich"
+
63 #undef D_STR_WEEKLYTIMER
+
64 #define D_STR_WEEKLYTIMER D_STR_WEEKLY " " D_STR_TIMER
+
65 #undef D_STR_OUTSIDE
+
66 #define D_STR_OUTSIDE "Dusse"
+
67 #undef D_STR_LOUD
+
68 #define D_STR_LOUD "Luut"
+
69 #undef D_STR_UPPER
+
70 #define D_STR_UPPER "Obe"
+
71 #undef D_STR_LOWER
+
72 #define D_STR_LOWER "Une"
+
73 #undef D_STR_CIRCULATE
+
74 #define D_STR_CIRCULATE "Zirkuliere"
+
75 #undef D_STR_CEILING
+
76 #define D_STR_CEILING "Decki"
+
77 #undef D_STR_6THSENSE
+
78 #define D_STR_6THSENSE "6te Sinn"
+
79 
+
80 #undef D_STR_COOL
+
81 #define D_STR_COOL "Chüehle"
+
82 #undef D_STR_HEAT
+
83 #define D_STR_HEAT "Heize"
+
84 #undef D_STR_DRY
+
85 #define D_STR_DRY "Tröchne"
+
86 
+
87 #undef D_STR_MED
+
88 #define D_STR_MED "Mit"
+
89 #undef D_STR_MEDIUM
+
90 #define D_STR_MEDIUM "Mittel"
+
91 
+
92 #undef D_STR_HIGHEST
+
93 #define D_STR_HIGHEST "Höchscht"
+
94 #undef D_STR_HIGH
+
95 #define D_STR_HIGH "Höch"
+
96 #undef D_STR_HI
+
97 #define D_STR_HI "H"
+
98 #undef D_STR_MID
+
99 #define D_STR_MID "M"
+
100 #undef D_STR_MIDDLE
+
101 #define D_STR_MIDDLE "Mittel"
+
102 #undef D_STR_LOW
+
103 #define D_STR_LOW "Tüüf"
+
104 #undef D_STR_LO
+
105 #define D_STR_LO "T"
+
106 #undef D_STR_LOWEST
+
107 #define D_STR_LOWEST "Tüfschte"
+
108 #undef D_STR_MAXRIGHT
+
109 #define D_STR_MAXRIGHT D_STR_MAX " " D_STR_RIGHT
+
110 #undef D_STR_RIGHTMAX_NOSPACE
+
111 #define D_STR_RIGHTMAX_NOSPACE D_STR_RIGHT D_STR_MAX
+
112 #undef D_STR_MAXLEFT
+
113 #define D_STR_MAXLEFT D_STR_MAX " " D_STR_LEFT
+
114 #undef D_STR_LEFTMAX_NOSPACE
+
115 #define D_STR_LEFTMAX_NOSPACE D_STR_LEFT D_STR_MAX
+
116 #undef D_STR_CENTRE
+
117 #define D_STR_CENTRE "Mitti"
+
118 #undef D_STR_TOP
+
119 #define D_STR_TOP "Obe"
+
120 #undef D_STR_BOTTOM
+
121 #define D_STR_BOTTOM "Une"
+
122 
+
123 #undef D_STR_DAY
+
124 #define D_STR_DAY "Tag"
+
125 #undef D_STR_DAYS
+
126 #define D_STR_DAYS "Täg"
+
127 #undef D_STR_HOUR
+
128 #define D_STR_HOUR "Stund"
+
129 #undef D_STR_HOURS
+
130 #define D_STR_HOURS D_STR_HOUR "e"
+
131 #undef D_STR_MINUTE
+
132 #define D_STR_MINUTE "Minute"
+
133 #undef D_STR_MINUTES
+
134 #define D_STR_MINUTES D_STR_MINUTE
+
135 #undef D_STR_SECONDS
+
136 #define D_STR_SECONDS D_STR_SECOND
+
137 #undef D_STR_NOW
+
138 #define D_STR_NOW "Jetz"
+
139 
+
140 #undef D_STR_NO
+
141 #define D_STR_NO "Nei"
+
142 
+
143 #undef D_STR_REPEAT
+
144 #define D_STR_REPEAT "Wiederhole"
+
145 
+
146 // IRrecvDumpV2+
+
147 #undef D_STR_TIMESTAMP
+
148 #define D_STR_TIMESTAMP "Ziitstämpfel"
+
149 #undef D_STR_IRRECVDUMP_STARTUP
+
150 #define D_STR_IRRECVDUMP_STARTUP \
+
151  "IRrecvDump lauft und wartet uf IR Iigab ufem Pin %d"
+
152 #undef D_WARN_BUFFERFULL
+
153 #define D_WARN_BUFFERFULL \
+
154  "WARNUNG: IR Code isch zgross für de Buffer (>= %d). " \
+
155  "Dem Resultat sött mer nöd vertraue bevor das behobe isch. " \
+
156  "Bearbeite & vergrössere `kCaptureBufferSize`."
+
157 
+
158 #endif // LOCALE_DE_CH_H_
+
+ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/de-DE_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/de-DE_8h.html new file mode 100644 index 000000000..2b94c27ea --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/de-DE_8h.html @@ -0,0 +1,82 @@ + + + + + + + +IRremoteESP8266: src/locale/de-DE.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
de-DE.h File Reference
+
+ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/de-DE_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/de-DE_8h_source.html new file mode 100644 index 000000000..f3eda60f6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/de-DE_8h_source.html @@ -0,0 +1,206 @@ + + + + + + + +IRremoteESP8266: src/locale/de-DE.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
de-DE.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 - Martin (@finfinack)
+
2 // Locale/language file for German / Germany.
+
3 // This file will override the default values located in `defaults.h`.
+
4 #ifndef LOCALE_DE_DE_H_
+
5 #define LOCALE_DE_DE_H_
+
6 
+
7 #define D_STR_UNKNOWN "UNBEKANNT"
+
8 #define D_STR_PROTOCOL "Protokoll"
+
9 #define D_STR_ON "Ein"
+
10 #define D_STR_OFF "Aus"
+
11 #define D_STR_MODE "Modus"
+
12 #define D_STR_TOGGLE "Umschalten"
+
13 #define D_STR_SLEEP "Schlafen"
+
14 #define D_STR_LIGHT "Licht"
+
15 #define D_STR_POWERFUL "Stark"
+
16 #define D_STR_QUIET "Ruhig"
+
17 #define D_STR_ECONO "Eco"
+
18 #define D_STR_BEEP "Piep"
+
19 #define D_STR_MOULD "Schimmel"
+
20 #define D_STR_CLEAN "Reinigen"
+
21 #define D_STR_PURIFY "Frischen"
+
22 #define D_STR_TIMER "Timer"
+
23 #define D_STR_ONTIMER D_STR_ON " " D_STR_TIMER
+
24 #define D_STR_OFFTIMER D_STR_OFF " " D_STR_TIMER
+
25 #define D_STR_CLOCK "Uhr"
+
26 #define D_STR_COMMAND "Befehl"
+
27 #define D_STR_HEALTH "Gesundheit"
+
28 #define D_STR_TEMP "Temp"
+
29 #define D_STR_HUMID "Feucht"
+
30 #define D_STR_SAVE "Speichern"
+
31 #define D_STR_EYE "Auge"
+
32 #define D_STR_FOLLOW "Folgen"
+
33 #define D_STR_FRESH "Frisch"
+
34 #define D_STR_HOLD "Halten"
+
35 #define D_STR_BUTTON "Knopf"
+
36 #define D_STR_NIGHT "Nacht"
+
37 #define D_STR_SILENT "Ruhig"
+
38 #define D_STR_UP "Hinauf"
+
39 #define D_STR_TEMPUP D_STR_TEMP " " D_STR_UP
+
40 #define D_STR_DOWN "Hinunter"
+
41 #define D_STR_TEMPDOWN D_STR_TEMP " " D_STR_DOWN
+
42 #define D_STR_CHANGE "Wechseln"
+
43 #define D_STR_MOVE "Verschieben"
+
44 #define D_STR_SET "Setzen"
+
45 #define D_STR_CANCEL "Abbrechen"
+
46 #define D_STR_COMFORT "Komfort"
+
47 #define D_STR_WEEKLY "Wöchentlich"
+
48 #define D_STR_WEEKLYTIMER D_STR_WEEKLY " " D_STR_TIMER
+
49 #define D_STR_FAST "Schnell"
+
50 #define D_STR_SLOW "Langsam"
+
51 #define D_STR_AIRFLOW "Luftzug"
+
52 #define D_STR_STEP "Schritt"
+
53 #define D_STR_NA "N/A"
+
54 #define D_STR_OUTSIDE "Draussen"
+
55 #define D_STR_LOUD "Laut"
+
56 #define D_STR_UPPER "Oben"
+
57 #define D_STR_LOWER "Unten"
+
58 #define D_STR_BREEZE "Brise"
+
59 #define D_STR_CIRCULATE "Zirkulieren"
+
60 #define D_STR_CEILING "Decke"
+
61 #define D_STR_WALL "Wand"
+
62 #define D_STR_ROOM "Raum"
+
63 #define D_STR_6THSENSE "6ter Sinn"
+
64 #define D_STR_FIXED "Fixiert"
+
65 
+
66 #define D_STR_AUTOMATIC "Automatisch"
+
67 #define D_STR_MANUAL "Manuell"
+
68 #define D_STR_COOL "Kühlen"
+
69 #define D_STR_HEAT "Heizen"
+
70 #define D_STR_FAN "Lüfter"
+
71 #define D_STR_FANONLY "nur_lüfter"
+
72 #define D_STR_DRY "Trocken"
+
73 
+
74 #define D_STR_MED "Mit"
+
75 #define D_STR_MEDIUM "Mittel"
+
76 
+
77 #define D_STR_HIGHEST "Höchste"
+
78 #define D_STR_HIGH "Hoch"
+
79 #define D_STR_HI "H"
+
80 #define D_STR_MID "M"
+
81 #define D_STR_MIDDLE "Mittel"
+
82 #define D_STR_LOW "Tief"
+
83 #define D_STR_LO "T"
+
84 #define D_STR_LOWEST "Tiefste"
+
85 #define D_STR_RIGHT "Rechts"
+
86 #define D_STR_MAXRIGHT D_STR_MAX " " D_STR_RIGHT
+
87 #define D_STR_RIGHTMAX_NOSPACE D_STR_RIGHT D_STR_MAX
+
88 #define D_STR_LEFT "Links"
+
89 #define D_STR_MAXLEFT D_STR_MAX " " D_STR_LEFT
+
90 #define D_STR_LEFTMAX_NOSPACE D_STR_LEFT D_STR_MAX
+
91 #define D_STR_WIDE "Breit"
+
92 #define D_STR_CENTRE "Mitte"
+
93 #define D_STR_TOP "Oben"
+
94 #define D_STR_BOTTOM "Unten"
+
95 
+
96 #define D_STR_DAY "Tag"
+
97 #define D_STR_DAYS D_STR_DAY "e"
+
98 #define D_STR_HOUR "Stunde"
+
99 #define D_STR_HOURS D_STR_HOUR "n"
+
100 #define D_STR_MINUTES D_STR_MINUTE "n"
+
101 #define D_STR_SECOND "Sekunde"
+
102 #define D_STR_SECONDS D_STR_SECOND "n"
+
103 #define D_STR_NOW "Jetzt"
+
104 // These don't translate well to German as typically only 2 letter
+
105 // abbreviations are used. Hence, this is an approximation.
+
106 #define D_STR_THREELETTERDAYS "SonMonDieMitDonFreSam"
+
107 
+
108 #define D_STR_YES "Ja"
+
109 #define D_STR_NO "Nein"
+
110 #define D_STR_TRUE "Wahr"
+
111 #define D_STR_FALSE "Falsch"
+
112 
+
113 #define D_STR_REPEAT "Wiederholen"
+
114 
+
115 // IRrecvDumpV2+
+
116 #define D_STR_TIMESTAMP "Zeitstempel"
+
117 #define D_STR_LIBRARY "Bibliothek"
+
118 #define D_STR_MESGDESC "Nachr. Beschr."
+
119 #define D_STR_IRRECVDUMP_STARTUP \
+
120  "IRrecvDump läuft und wartet auf IR Eingabe auf Pin %d"
+
121 #define D_WARN_BUFFERFULL \
+
122  "WARNUNG: IR Code ist zu gross für Buffer (>= %d). " \
+
123  "Dem Resultat sollte nicht vertraut werden bevor das behoben ist. " \
+
124  "Bearbeite & vergrössere `kCaptureBufferSize`."
+
125 
+
126 #endif // LOCALE_DE_DE_H_
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/defaults_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/defaults_8h.html new file mode 100644 index 000000000..512778196 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/defaults_8h.html @@ -0,0 +1,82 @@ + + + + + + + +IRremoteESP8266: src/locale/defaults.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
defaults.h File Reference
+
+ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/defaults_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/defaults_8h_source.html new file mode 100644 index 000000000..f2cf638b3 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/defaults_8h_source.html @@ -0,0 +1,838 @@ + + + + + + + +IRremoteESP8266: src/locale/defaults.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
defaults.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 - David Conran (@crankyoldgit)
+
2 // The default text to use throughout the library.
+
3 // The library will use this text if no locale (_IR_LOCALE_) is set or if
+
4 // the locale doesn't define particular values.
+
5 // If they are defined, this file should NOT override them.
+
6 //
+
7 // This file should contain a #define for every translateable/locale dependant
+
8 // string used by the library. Language specific files don't have to include
+
9 // everything.
+
10 //
+
11 // NOTE: ASCII/UTF-8 characters only. Unicode is NOT supported.
+
12 //
+
13 // The defaults are English (AU) / en-AU. Australia (AU) is pretty much the same
+
14 // as English (UK) for this libraries use case.
+
15 #ifndef LOCALE_DEFAULTS_H_
+
16 #define LOCALE_DEFAULTS_H_
+
17 
+
18 #ifndef D_STR_UNKNOWN
+
19 #define D_STR_UNKNOWN "UNKNOWN"
+
20 #endif // D_STR_UNKNOWN
+
21 #ifndef D_STR_PROTOCOL
+
22 #define D_STR_PROTOCOL "Protocol"
+
23 #endif // D_STR_PROTOCOL
+
24 #ifndef D_STR_POWER
+
25 #define D_STR_POWER "Power"
+
26 #endif // D_STR_POWER
+
27 #ifndef D_STR_PREVIOUS
+
28 #define D_STR_PREVIOUS "Previous"
+
29 #endif // D_STR_PREVIOUS
+
30 #ifndef D_STR_ON
+
31 #define D_STR_ON "On"
+
32 #endif // D_STR_ON
+
33 #ifndef D_STR_OFF
+
34 #define D_STR_OFF "Off"
+
35 #endif // D_STR_OFF
+
36 #ifndef D_STR_MODE
+
37 #define D_STR_MODE "Mode"
+
38 #endif // D_STR_MODE
+
39 #ifndef D_STR_TOGGLE
+
40 #define D_STR_TOGGLE "Toggle"
+
41 #endif // D_STR_TOGGLE
+
42 #ifndef D_STR_TURBO
+
43 #define D_STR_TURBO "Turbo"
+
44 #endif // D_STR_TURBO
+
45 #ifndef D_STR_SUPER
+
46 #define D_STR_SUPER "Super"
+
47 #endif // D_STR_SUPER
+
48 #ifndef D_STR_SLEEP
+
49 #define D_STR_SLEEP "Sleep"
+
50 #endif // D_STR_SLEEP
+
51 #ifndef D_STR_LIGHT
+
52 #define D_STR_LIGHT "Light"
+
53 #endif // D_STR_LIGHT
+
54 #ifndef D_STR_POWERFUL
+
55 #define D_STR_POWERFUL "Powerful"
+
56 #endif // D_STR_POWERFUL
+
57 #ifndef D_STR_QUIET
+
58 #define D_STR_QUIET "Quiet"
+
59 #endif // D_STR_QUIET
+
60 #ifndef D_STR_ECONO
+
61 #define D_STR_ECONO "Econo"
+
62 #endif // D_STR_ECONO
+
63 #ifndef D_STR_SWING
+
64 #define D_STR_SWING "Swing"
+
65 #endif // D_STR_SWING
+
66 #ifndef D_STR_SWINGH
+
67 #define D_STR_SWINGH D_STR_SWING"(H)" // Set `D_STR_SWING` first!
+
68 #endif // D_STR_SWINGH
+
69 #ifndef D_STR_SWINGV
+
70 #define D_STR_SWINGV D_STR_SWING"(V)" // Set `D_STR_SWING` first!
+
71 #endif // D_STR_SWINGV
+
72 #ifndef D_STR_BEEP
+
73 #define D_STR_BEEP "Beep"
+
74 #endif // D_STR_BEEP
+
75 #ifndef D_STR_MOULD
+
76 #define D_STR_MOULD "Mould"
+
77 #endif // D_STR_MOULD
+
78 #ifndef D_STR_CLEAN
+
79 #define D_STR_CLEAN "Clean"
+
80 #endif // D_STR_CLEAN
+
81 #ifndef D_STR_PURIFY
+
82 #define D_STR_PURIFY "Purify"
+
83 #endif // D_STR_PURIFY
+
84 #ifndef D_STR_TIMER
+
85 #define D_STR_TIMER "Timer"
+
86 #endif // D_STR_TIMER
+
87 #ifndef D_STR_ONTIMER
+
88 #define D_STR_ONTIMER D_STR_ON " " D_STR_TIMER // Set `D_STR_ON` first!
+
89 #endif // D_STR_ONTIMER
+
90 #ifndef D_STR_OFFTIMER
+
91 #define D_STR_OFFTIMER D_STR_OFF " " D_STR_TIMER // Set `D_STR_OFF` first!
+
92 #endif // D_STR_OFFTIMER
+
93 #ifndef D_STR_CLOCK
+
94 #define D_STR_CLOCK "Clock"
+
95 #endif // D_STR_CLOCK
+
96 #ifndef D_STR_COMMAND
+
97 #define D_STR_COMMAND "Command"
+
98 #endif // D_STR_COMMAND
+
99 #ifndef D_STR_XFAN
+
100 #define D_STR_XFAN "XFan"
+
101 #endif // D_STR_XFAN
+
102 #ifndef D_STR_HEALTH
+
103 #define D_STR_HEALTH "Health"
+
104 #endif // D_STR_HEALTH
+
105 #ifndef D_STR_MODEL
+
106 #define D_STR_MODEL "Model"
+
107 #endif // D_STR_MODEL
+
108 #ifndef D_STR_TEMP
+
109 #define D_STR_TEMP "Temp"
+
110 #endif // D_STR_TEMP
+
111 #ifndef D_STR_IFEEL
+
112 #define D_STR_IFEEL "IFeel"
+
113 #endif // D_STR_IFEEL
+
114 #ifndef D_STR_HUMID
+
115 #define D_STR_HUMID "Humid"
+
116 #endif // D_STR_HUMID
+
117 #ifndef D_STR_SAVE
+
118 #define D_STR_SAVE "Save"
+
119 #endif // D_STR_SAVE
+
120 #ifndef D_STR_EYE
+
121 #define D_STR_EYE "Eye"
+
122 #endif // D_STR_EYE
+
123 #ifndef D_STR_FOLLOW
+
124 #define D_STR_FOLLOW "Follow"
+
125 #endif // D_STR_FOLLOW
+
126 #ifndef D_STR_ION
+
127 #define D_STR_ION "Ion"
+
128 #endif // D_STR_ION
+
129 #ifndef D_STR_FRESH
+
130 #define D_STR_FRESH "Fresh"
+
131 #endif // D_STR_FRESH
+
132 #ifndef D_STR_HOLD
+
133 #define D_STR_HOLD "Hold"
+
134 #endif // D_STR_HOLD
+
135 #ifndef D_STR_8C_HEAT
+
136 #define D_STR_8C_HEAT "8C " D_STR_HEAT // Set `D_STR_HEAT` first!
+
137 #endif // D_STR_8C_HEAT
+
138 #ifndef D_STR_BUTTON
+
139 #define D_STR_BUTTON "Button"
+
140 #endif // D_STR_BUTTON
+
141 #ifndef D_STR_NIGHT
+
142 #define D_STR_NIGHT "Night"
+
143 #endif // D_STR_NIGHT
+
144 #ifndef D_STR_SILENT
+
145 #define D_STR_SILENT "Silent"
+
146 #endif // D_STR_SILENT
+
147 #ifndef D_STR_FILTER
+
148 #define D_STR_FILTER "Filter"
+
149 #endif // D_STR_FILTER
+
150 #ifndef D_STR_3D
+
151 #define D_STR_3D "3D"
+
152 #endif // D_STR_3D
+
153 #ifndef D_STR_CELSIUS
+
154 #define D_STR_CELSIUS "Celsius"
+
155 #endif // D_STR_CELSIUS
+
156 #ifndef D_STR_UP
+
157 #define D_STR_UP "Up"
+
158 #endif // D_STR_UP
+
159 #ifndef D_STR_TEMPUP
+
160 #define D_STR_TEMPUP D_STR_TEMP " " D_STR_UP // Set `D_STR_TEMP` first!
+
161 #endif // D_STR_TEMPUP
+
162 #ifndef D_STR_DOWN
+
163 #define D_STR_DOWN "Down"
+
164 #endif // D_STR_DOWN
+
165 #ifndef D_STR_TEMPDOWN
+
166 #define D_STR_TEMPDOWN D_STR_TEMP " " D_STR_DOWN // Set `D_STR_TEMP` first!
+
167 #endif // D_STR_TEMPDOWN
+
168 #ifndef D_STR_CHANGE
+
169 #define D_STR_CHANGE "Change"
+
170 #endif // D_STR_CHANGE
+
171 #ifndef D_STR_START
+
172 #define D_STR_START "Start"
+
173 #endif // D_STR_START
+
174 #ifndef D_STR_STOP
+
175 #define D_STR_STOP "Stop"
+
176 #endif // D_STR_STOP
+
177 #ifndef D_STR_MOVE
+
178 #define D_STR_MOVE "Move"
+
179 #endif // D_STR_MOVE
+
180 #ifndef D_STR_SET
+
181 #define D_STR_SET "Set"
+
182 #endif // D_STR_SET
+
183 #ifndef D_STR_CANCEL
+
184 #define D_STR_CANCEL "Cancel"
+
185 #endif // D_STR_CANCEL
+
186 #ifndef D_STR_COMFORT
+
187 #define D_STR_COMFORT "Comfort"
+
188 #endif // D_STR_COMFORT
+
189 #ifndef D_STR_SENSOR
+
190 #define D_STR_SENSOR "Sensor"
+
191 #endif // D_STR_SENSOR
+
192 #ifndef D_STR_DISPLAY
+
193 #define D_STR_DISPLAY "Display"
+
194 #endif // D_STR_DISPLAY
+
195 #ifndef D_STR_WEEKLY
+
196 #define D_STR_WEEKLY "Weekly"
+
197 #endif // D_STR_WEEKLY
+
198 #ifndef D_STR_WEEKLYTIMER
+
199 #define D_STR_WEEKLYTIMER D_STR_WEEKLY " " D_STR_TIMER // Needs `D_STR_WEEKLY`!
+
200 #endif // D_STR_WEEKLYTIMER
+
201 #ifndef D_STR_WIFI
+
202 #define D_STR_WIFI "WiFi"
+
203 #endif // D_STR_WIFI
+
204 #ifndef D_STR_LAST
+
205 #define D_STR_LAST "Last"
+
206 #endif // D_STR_LAST
+
207 #ifndef D_STR_FAST
+
208 #define D_STR_FAST "Fast"
+
209 #endif // D_STR_FAST
+
210 #ifndef D_STR_SLOW
+
211 #define D_STR_SLOW "Slow"
+
212 #endif // D_STR_SLOW
+
213 #ifndef D_STR_AIRFLOW
+
214 #define D_STR_AIRFLOW "Air Flow"
+
215 #endif // D_STR_AIRFLOW
+
216 #ifndef D_STR_STEP
+
217 #define D_STR_STEP "Step"
+
218 #endif // D_STR_STEP
+
219 #ifndef D_STR_NA
+
220 #define D_STR_NA "N/A"
+
221 #endif // D_STR_NA
+
222 #ifndef D_STR_INSIDE
+
223 #define D_STR_INSIDE "Inside"
+
224 #endif // D_STR_INSIDE
+
225 #ifndef D_STR_OUTSIDE
+
226 #define D_STR_OUTSIDE "Outside"
+
227 #endif // D_STR_OUTSIDE
+
228 #ifndef D_STR_LOUD
+
229 #define D_STR_LOUD "Loud"
+
230 #endif // D_STR_LOUD
+
231 #ifndef D_STR_UPPER
+
232 #define D_STR_UPPER "Upper"
+
233 #endif // D_STR_UPPER
+
234 #ifndef D_STR_LOWER
+
235 #define D_STR_LOWER "Lower"
+
236 #endif // D_STR_LOWER
+
237 #ifndef D_STR_BREEZE
+
238 #define D_STR_BREEZE "Breeze"
+
239 #endif // D_STR_BREEZE
+
240 #ifndef D_STR_CIRCULATE
+
241 #define D_STR_CIRCULATE "Circulate"
+
242 #endif // D_STR_CIRCULATE
+
243 #ifndef D_STR_CEILING
+
244 #define D_STR_CEILING "Ceiling"
+
245 #endif // D_STR_CEILING
+
246 #ifndef D_STR_WALL
+
247 #define D_STR_WALL "Wall"
+
248 #endif // D_STR_WALL
+
249 #ifndef D_STR_ROOM
+
250 #define D_STR_ROOM "Room"
+
251 #endif // D_STR_ROOM
+
252 #ifndef D_STR_6THSENSE
+
253 #define D_STR_6THSENSE "6th Sense"
+
254 #endif // D_STR_6THSENSE
+
255 #ifndef D_STR_ZONEFOLLOW
+
256 #define D_STR_ZONEFOLLOW "Zone Follow"
+
257 #endif // D_STR_ZONEFOLLOW
+
258 #ifndef D_STR_FIXED
+
259 #define D_STR_FIXED "Fixed"
+
260 #endif // D_STR_FIXED
+
261 
+
262 #ifndef D_STR_AUTO
+
263 #define D_STR_AUTO "Auto"
+
264 #endif // D_STR_AUTO
+
265 #ifndef D_STR_AUTOMATIC
+
266 #define D_STR_AUTOMATIC "Automatic"
+
267 #endif // D_STR_AUTOMATIC
+
268 #ifndef D_STR_MANUAL
+
269 #define D_STR_MANUAL "Manual"
+
270 #endif // D_STR_MANUAL
+
271 #ifndef D_STR_COOL
+
272 #define D_STR_COOL "Cool"
+
273 #endif // D_STR_COOL
+
274 #ifndef D_STR_HEAT
+
275 #define D_STR_HEAT "Heat"
+
276 #endif // D_STR_HEAT
+
277 #ifndef D_STR_FAN
+
278 #define D_STR_FAN "Fan"
+
279 #endif // D_STR_FAN
+
280 #ifndef D_STR_FANONLY
+
281 #define D_STR_FANONLY "fan_only"
+
282 #endif // D_STR_FANONLY
+
283 #ifndef D_STR_DRY
+
284 #define D_STR_DRY "Dry"
+
285 #endif // D_STR_DRY
+
286 
+
287 #ifndef D_STR_MAX
+
288 #define D_STR_MAX "Max"
+
289 #endif // D_STR_MAX
+
290 #ifndef D_STR_MAXIMUM
+
291 #define D_STR_MAXIMUM "Maximum"
+
292 #endif // D_STR_MAXIMUM
+
293 #ifndef D_STR_MIN
+
294 #define D_STR_MIN "Min"
+
295 #endif // D_STR_MIN
+
296 #ifndef D_STR_MINIMUM
+
297 #define D_STR_MINIMUM "Minimum"
+
298 #endif // D_STR_MINIMUM
+
299 #ifndef D_STR_MED
+
300 #define D_STR_MED "Med"
+
301 #endif // D_STR_MED
+
302 #ifndef D_STR_MEDIUM
+
303 #define D_STR_MEDIUM "Medium"
+
304 #endif // D_STR_MEDIUM
+
305 
+
306 #ifndef D_STR_HIGHEST
+
307 #define D_STR_HIGHEST "Highest"
+
308 #endif // D_STR_HIGHEST
+
309 #ifndef D_STR_HIGH
+
310 #define D_STR_HIGH "High"
+
311 #endif // D_STR_HIGH
+
312 #ifndef D_STR_HI
+
313 #define D_STR_HI "Hi"
+
314 #endif // D_STR_HI
+
315 #ifndef D_STR_MID
+
316 #define D_STR_MID "Mid"
+
317 #endif // D_STR_MID
+
318 #ifndef D_STR_MIDDLE
+
319 #define D_STR_MIDDLE "Middle"
+
320 #endif // D_STR_MIDDLE
+
321 #ifndef D_STR_LOW
+
322 #define D_STR_LOW "Low"
+
323 #endif // D_STR_LOW
+
324 #ifndef D_STR_LO
+
325 #define D_STR_LO "Lo"
+
326 #endif // D_STR_LO
+
327 #ifndef D_STR_LOWEST
+
328 #define D_STR_LOWEST "Lowest"
+
329 #endif // D_STR_LOWEST
+
330 #ifndef D_STR_RIGHT
+
331 #define D_STR_RIGHT "Right"
+
332 #endif // D_STR_RIGHT
+
333 #ifndef D_STR_MAXRIGHT
+
334 #define D_STR_MAXRIGHT D_STR_MAX " " D_STR_RIGHT // Set `D_STR_MAX` first!
+
335 #endif // D_STR_MAXRIGHT
+
336 #ifndef D_STR_RIGHTMAX_NOSPACE
+
337 #define D_STR_RIGHTMAX_NOSPACE D_STR_RIGHT D_STR_MAX // Set `D_STR_MAX` first!
+
338 #endif // D_STR_RIGHTMAX_NOSPACE
+
339 #ifndef D_STR_LEFT
+
340 #define D_STR_LEFT "Left"
+
341 #endif // D_STR_LEFT
+
342 #ifndef D_STR_MAXLEFT
+
343 #define D_STR_MAXLEFT D_STR_MAX " " D_STR_LEFT // Set `D_STR_MAX` first!
+
344 #endif // D_STR_MAXLEFT
+
345 #ifndef D_STR_LEFTMAX_NOSPACE
+
346 #define D_STR_LEFTMAX_NOSPACE D_STR_LEFT D_STR_MAX // Set `D_STR_MAX` first!
+
347 #endif // D_STR_LEFTMAX_NOSPACE
+
348 #ifndef D_STR_WIDE
+
349 #define D_STR_WIDE "Wide"
+
350 #endif // D_STR_WIDE
+
351 #ifndef D_STR_CENTRE
+
352 #define D_STR_CENTRE "Centre"
+
353 #endif // D_STR_CENTRE
+
354 #ifndef D_STR_TOP
+
355 #define D_STR_TOP "Top"
+
356 #endif // D_STR_TOP
+
357 #ifndef D_STR_BOTTOM
+
358 #define D_STR_BOTTOM "Bottom"
+
359 #endif // D_STR_BOTTOM
+
360 
+
361 // Compound words/phrases/descriptions from pre-defined words.
+
362 // Note: Obviously these need to be defined *after* their component words.
+
363 #ifndef D_STR_EYEAUTO
+
364 #define D_STR_EYEAUTO D_STR_EYE " " D_STR_AUTO
+
365 #endif // D_STR_EYEAUTO
+
366 #ifndef D_STR_LIGHTTOGGLE
+
367 #define D_STR_LIGHTTOGGLE D_STR_LIGHT " " D_STR_TOGGLE
+
368 #endif // D_STR_LIGHTTOGGLE
+
369 #ifndef D_STR_OUTSIDEQUIET
+
370 #define D_STR_OUTSIDEQUIET D_STR_OUTSIDE " " D_STR_QUIET
+
371 #endif // D_STR_OUTSIDEQUIET
+
372 #ifndef D_STR_POWERTOGGLE
+
373 #define D_STR_POWERTOGGLE D_STR_POWER " " D_STR_TOGGLE
+
374 #endif // D_STR_POWERTOGGLE
+
375 #ifndef D_STR_POWERBUTTON
+
376 #define D_STR_POWERBUTTON D_STR_POWER " " D_STR_BUTTON
+
377 #endif // D_STR_POWERBUTTON
+
378 #ifndef D_STR_PREVIOUSPOWER
+
379 #define D_STR_PREVIOUSPOWER D_STR_PREVIOUS " " D_STR_POWER
+
380 #endif // D_STR_PREVIOUSPOWER
+
381 #ifndef D_STR_DISPLAYTEMP
+
382 #define D_STR_DISPLAYTEMP D_STR_DISPLAY " " D_STR_TEMP
+
383 #endif // D_STR_DISPLAYTEMP
+
384 #ifndef D_STR_SENSORTEMP
+
385 #define D_STR_SENSORTEMP D_STR_SENSOR " " D_STR_TEMP
+
386 #endif // D_STR_SENSORTEMP
+
387 #ifndef D_STR_SLEEP_TIMER
+
388 #define D_STR_SLEEP_TIMER D_STR_SLEEP " " D_STR_TIMER
+
389 #endif // D_STR_SLEEP_TIMER
+
390 #ifndef D_STR_SWINGVMODE
+
391 #define D_STR_SWINGVMODE D_STR_SWINGV " " D_STR_MODE
+
392 #endif // D_STR_SWINGVMODE
+
393 #ifndef D_STR_SWINGVTOGGLE
+
394 #define D_STR_SWINGVTOGGLE D_STR_SWINGV " " D_STR_TOGGLE
+
395 #endif // D_STR_SWINGVTOGGLE
+
396 
+
397 // Separators
+
398 #ifndef D_CHR_TIME_SEP
+
399 #define D_CHR_TIME_SEP ':'
+
400 #endif // D_CHR_TIME_SEP
+
401 #ifndef D_STR_SPACELBRACE
+
402 #define D_STR_SPACELBRACE " ("
+
403 #endif // D_STR_SPACELBRACE
+
404 #ifndef D_STR_COMMASPACE
+
405 #define D_STR_COMMASPACE ", "
+
406 #endif // D_STR_COMMASPACE
+
407 #ifndef D_STR_COLONSPACE
+
408 #define D_STR_COLONSPACE ": "
+
409 #endif // D_STR_COLONSPACE
+
410 
+
411 #ifndef D_STR_DAY
+
412 #define D_STR_DAY "Day"
+
413 #endif // D_STR_DAY
+
414 #ifndef D_STR_DAYS
+
415 #define D_STR_DAYS D_STR_DAY "s"
+
416 #endif // D_STR_DAYS
+
417 #ifndef D_STR_HOUR
+
418 #define D_STR_HOUR "Hour"
+
419 #endif // D_STR_HOUR
+
420 #ifndef D_STR_HOURS
+
421 #define D_STR_HOURS D_STR_HOUR "s"
+
422 #endif // D_STR_HOURS
+
423 #ifndef D_STR_MINUTE
+
424 #define D_STR_MINUTE "Minute"
+
425 #endif // D_STR_MINUTE
+
426 #ifndef D_STR_MINUTES
+
427 #define D_STR_MINUTES D_STR_MINUTE "s"
+
428 #endif // D_STR_MINUTES
+
429 #ifndef D_STR_SECOND
+
430 #define D_STR_SECOND "Second"
+
431 #endif // D_STR_SECOND
+
432 #ifndef D_STR_SECONDS
+
433 #define D_STR_SECONDS D_STR_SECOND "s"
+
434 #endif // D_STR_SECONDS
+
435 #ifndef D_STR_NOW
+
436 #define D_STR_NOW "Now"
+
437 #endif // D_STR_NOW
+
438 #ifndef D_STR_THREELETTERDAYS
+
439 #define D_STR_THREELETTERDAYS "SunMonTueWedThuFriSat"
+
440 #endif // D_STR_THREELETTERDAYS
+
441 
+
442 #ifndef D_STR_YES
+
443 #define D_STR_YES "Yes"
+
444 #endif // D_STR_YES
+
445 #ifndef D_STR_NO
+
446 #define D_STR_NO "No"
+
447 #endif // D_STR_NO
+
448 #ifndef D_STR_TRUE
+
449 #define D_STR_TRUE "True"
+
450 #endif // D_STR_TRUE
+
451 #ifndef D_STR_FALSE
+
452 #define D_STR_FALSE "False"
+
453 #endif // D_STR_FALSE
+
454 
+
455 #ifndef D_STR_REPEAT
+
456 #define D_STR_REPEAT "Repeat"
+
457 #endif // D_STR_REPEAT
+
458 #ifndef D_STR_CODE
+
459 #define D_STR_CODE "Code"
+
460 #endif // D_STR_CODE
+
461 #ifndef D_STR_BITS
+
462 #define D_STR_BITS "Bits"
+
463 #endif // D_STR_BITS
+
464 
+
465 // Protocols Names
+
466 #ifndef D_STR_AIRWELL
+
467 #define D_STR_AIRWELL "AIRWELL"
+
468 #endif // D_STR_AIRWELL
+
469 #ifndef D_STR_AIWA_RC_T501
+
470 #define D_STR_AIWA_RC_T501 "AIWA_RC_T501"
+
471 #endif // D_STR_AIWA_RC_T501
+
472 #ifndef D_STR_AMCOR
+
473 #define D_STR_AMCOR "AMCOR"
+
474 #endif // D_STR_AMCOR
+
475 #ifndef D_STR_ARGO
+
476 #define D_STR_ARGO "ARGO"
+
477 #endif // D_STR_ARGO
+
478 #ifndef D_STR_CARRIER_AC
+
479 #define D_STR_CARRIER_AC "CARRIER_AC"
+
480 #endif // D_STR_CARRIER_AC
+
481 #ifndef D_STR_CARRIER_AC40
+
482 #define D_STR_CARRIER_AC40 D_STR_CARRIER_AC "40"
+
483 #endif // D_STR_CARRIER_AC40
+
484 #ifndef D_STR_CARRIER_AC64
+
485 #define D_STR_CARRIER_AC64 D_STR_CARRIER_AC "64"
+
486 #endif // D_STR_CARRIER_AC64
+
487 #ifndef D_STR_COOLIX
+
488 #define D_STR_COOLIX "COOLIX"
+
489 #endif // D_STR_COOLIX
+
490 #ifndef D_STR_CORONA_AC
+
491 #define D_STR_CORONA_AC "CORONA_AC"
+
492 #endif // D_STR_CORONA_AC
+
493 #ifndef D_STR_DAIKIN
+
494 #define D_STR_DAIKIN "DAIKIN"
+
495 #endif // D_STR_DAIKIN
+
496 #ifndef D_STR_DAIKIN128
+
497 #define D_STR_DAIKIN128 "DAIKIN128"
+
498 #endif // D_STR_DAIKIN128
+
499 #ifndef D_STR_DAIKIN152
+
500 #define D_STR_DAIKIN152 "DAIKIN152"
+
501 #endif // D_STR_DAIKIN152
+
502 #ifndef D_STR_DAIKIN160
+
503 #define D_STR_DAIKIN160 "DAIKIN160"
+
504 #endif // D_STR_DAIKIN160
+
505 #ifndef D_STR_DAIKIN176
+
506 #define D_STR_DAIKIN176 "DAIKIN176"
+
507 #endif // D_STR_DAIKIN176
+
508 #ifndef D_STR_DAIKIN2
+
509 #define D_STR_DAIKIN2 "DAIKIN2"
+
510 #endif // D_STR_DAIKIN2
+
511 #ifndef D_STR_DAIKIN216
+
512 #define D_STR_DAIKIN216 "DAIKIN216"
+
513 #endif // D_STR_DAIKIN216
+
514 #ifndef D_STR_DAIKIN64
+
515 #define D_STR_DAIKIN64 "DAIKIN64"
+
516 #endif // D_STR_DAIKIN64
+
517 #ifndef D_STR_DELONGHI_AC
+
518 #define D_STR_DELONGHI_AC "DELONGHI_AC"
+
519 #endif // D_STR_DELONGHI_AC
+
520 #ifndef D_STR_DENON
+
521 #define D_STR_DENON "DENON"
+
522 #endif // D_STR_DENON
+
523 #ifndef D_STR_DISH
+
524 #define D_STR_DISH "DISH"
+
525 #endif // D_STR_DISH
+
526 #ifndef D_STR_DOSHISHA
+
527 #define D_STR_DOSHISHA "DOSHISHA"
+
528 #endif // D_STR_DOSHISHA
+
529 #ifndef D_STR_ELECTRA_AC
+
530 #define D_STR_ELECTRA_AC "ELECTRA_AC"
+
531 #endif // D_STR_ELECTRA_AC
+
532 #ifndef D_STR_EPSON
+
533 #define D_STR_EPSON "EPSON"
+
534 #endif // D_STR_EPSON
+
535 #ifndef D_STR_FUJITSU_AC
+
536 #define D_STR_FUJITSU_AC "FUJITSU_AC"
+
537 #endif // D_STR_FUJITSU_AC
+
538 #ifndef D_STR_GICABLE
+
539 #define D_STR_GICABLE "GICABLE"
+
540 #endif // D_STR_GICABLE
+
541 #ifndef D_STR_GLOBALCACHE
+
542 #define D_STR_GLOBALCACHE "GLOBALCACHE"
+
543 #endif // D_STR_GLOBALCACHE
+
544 #ifndef D_STR_GOODWEATHER
+
545 #define D_STR_GOODWEATHER "GOODWEATHER"
+
546 #endif // D_STR_GOODWEATHER
+
547 #ifndef D_STR_GREE
+
548 #define D_STR_GREE "GREE"
+
549 #endif // D_STR_GREE
+
550 #ifndef D_STR_HAIER_AC
+
551 #define D_STR_HAIER_AC "HAIER_AC"
+
552 #endif // D_STR_HAIER_AC
+
553 #ifndef D_STR_HAIER_AC_YRW02
+
554 #define D_STR_HAIER_AC_YRW02 "HAIER_AC_YRW02"
+
555 #endif // D_STR_HAIER_AC_YRW02
+
556 #ifndef D_STR_HITACHI_AC
+
557 #define D_STR_HITACHI_AC "HITACHI_AC"
+
558 #endif // D_STR_HITACHI_AC
+
559 #ifndef D_STR_HITACHI_AC1
+
560 #define D_STR_HITACHI_AC1 "HITACHI_AC1"
+
561 #endif // D_STR_HITACHI_AC1
+
562 #ifndef D_STR_HITACHI_AC2
+
563 #define D_STR_HITACHI_AC2 "HITACHI_AC2"
+
564 #endif // D_STR_HITACHI_AC2
+
565 #ifndef D_STR_HITACHI_AC3
+
566 #define D_STR_HITACHI_AC3 "HITACHI_AC3"
+
567 #endif // D_STR_HITACHI_AC3
+
568 #ifndef D_STR_HITACHI_AC344
+
569 #define D_STR_HITACHI_AC344 "HITACHI_AC344"
+
570 #endif // D_STR_HITACHI_AC344
+
571 #ifndef D_STR_HITACHI_AC424
+
572 #define D_STR_HITACHI_AC424 "HITACHI_AC424"
+
573 #endif // D_STR_HITACHI_AC424
+
574 #ifndef D_STR_INAX
+
575 #define D_STR_INAX "INAX"
+
576 #endif // D_STR_INAX
+
577 #ifndef D_STR_JVC
+
578 #define D_STR_JVC "JVC"
+
579 #endif // D_STR_JVC
+
580 #ifndef D_STR_KELVINATOR
+
581 #define D_STR_KELVINATOR "KELVINATOR"
+
582 #endif // D_STR_KELVINATOR
+
583 #ifndef D_STR_LASERTAG
+
584 #define D_STR_LASERTAG "LASERTAG"
+
585 #endif // D_STR_LASERTAG
+
586 #ifndef D_STR_LEGOPF
+
587 #define D_STR_LEGOPF "LEGOPF"
+
588 #endif // D_STR_LEGOPF
+
589 #ifndef D_STR_LG
+
590 #define D_STR_LG "LG"
+
591 #endif // D_STR_LG
+
592 #ifndef D_STR_LG2
+
593 #define D_STR_LG2 "LG2"
+
594 #endif // D_STR_LG2
+
595 #ifndef D_STR_LUTRON
+
596 #define D_STR_LUTRON "LUTRON"
+
597 #endif // D_STR_LUTRON
+
598 #ifndef D_STR_MAGIQUEST
+
599 #define D_STR_MAGIQUEST "MAGIQUEST"
+
600 #endif // D_STR_MAGIQUEST
+
601 #ifndef D_STR_MIDEA
+
602 #define D_STR_MIDEA "MIDEA"
+
603 #endif // D_STR_MIDEA
+
604 #ifndef D_STR_MIDEA24
+
605 #define D_STR_MIDEA24 "MIDEA24"
+
606 #endif // D_STR_MIDEA24
+
607 #ifndef D_STR_MITSUBISHI
+
608 #define D_STR_MITSUBISHI "MITSUBISHI"
+
609 #endif // D_STR_MITSUBISHI
+
610 #ifndef D_STR_MITSUBISHI112
+
611 #define D_STR_MITSUBISHI112 "MITSUBISHI112"
+
612 #endif // D_STR_MITSUBISHI112
+
613 #ifndef D_STR_MITSUBISHI136
+
614 #define D_STR_MITSUBISHI136 "MITSUBISHI136"
+
615 #endif // D_STR_MITSUBISHI136
+
616 #ifndef D_STR_MITSUBISHI2
+
617 #define D_STR_MITSUBISHI2 "MITSUBISHI2"
+
618 #endif // D_STR_MITSUBISHI2
+
619 #ifndef D_STR_MITSUBISHI_AC
+
620 #define D_STR_MITSUBISHI_AC "MITSUBISHI_AC"
+
621 #endif // D_STR_MITSUBISHI_AC
+
622 #ifndef D_STR_MITSUBISHI_HEAVY_152
+
623 #define D_STR_MITSUBISHI_HEAVY_152 "MITSUBISHI_HEAVY_152"
+
624 #endif // D_STR_MITSUBISHI_HEAVY_152
+
625 #ifndef D_STR_MITSUBISHI_HEAVY_88
+
626 #define D_STR_MITSUBISHI_HEAVY_88 "MITSUBISHI_HEAVY_88"
+
627 #endif // D_STR_MITSUBISHI_HEAVY_88
+
628 #ifndef D_STR_MULTIBRACKETS
+
629 #define D_STR_MULTIBRACKETS "MULTIBRACKETS"
+
630 #endif // D_STR_MULTIBRACKETS
+
631 #ifndef D_STR_MWM
+
632 #define D_STR_MWM "MWM"
+
633 #endif // D_STR_MWM
+
634 #ifndef D_STR_NEC
+
635 #define D_STR_NEC "NEC"
+
636 #endif // D_STR_NEC
+
637 #ifndef D_STR_NEC_LIKE
+
638 #define D_STR_NEC_LIKE D_STR_NEC "_LIKE"
+
639 #endif // D_STR_NEC_LIKE
+
640 #ifndef D_STR_NEC_NON_STRICT
+
641 #define D_STR_NEC_NON_STRICT D_STR_NEC " (NON-STRICT)"
+
642 #endif // D_STR_NEC_NON_STRICT
+
643 #ifndef D_STR_NEOCLIMA
+
644 #define D_STR_NEOCLIMA "NEOCLIMA"
+
645 #endif // D_STR_NEOCLIMA
+
646 #ifndef D_STR_NIKAI
+
647 #define D_STR_NIKAI "NIKAI"
+
648 #endif // D_STR_NIKAI
+
649 #ifndef D_STR_PANASONIC
+
650 #define D_STR_PANASONIC "PANASONIC"
+
651 #endif // D_STR_PANASONIC
+
652 #ifndef D_STR_PANASONIC_AC
+
653 #define D_STR_PANASONIC_AC "PANASONIC_AC"
+
654 #endif // D_STR_PANASONIC_AC
+
655 #ifndef D_STR_PIONEER
+
656 #define D_STR_PIONEER "PIONEER"
+
657 #endif // D_STR_PIONEER
+
658 #ifndef D_STR_PRONTO
+
659 #define D_STR_PRONTO "PRONTO"
+
660 #endif // D_STR_PRONTO
+
661 #ifndef D_STR_RAW
+
662 #define D_STR_RAW "RAW"
+
663 #endif // D_STR_RAW
+
664 #ifndef D_STR_RC5
+
665 #define D_STR_RC5 "RC5"
+
666 #endif // D_STR_RC5
+
667 #ifndef D_STR_RC5X
+
668 #define D_STR_RC5X "RC5X"
+
669 #endif // D_STR_RC5X
+
670 #ifndef D_STR_RC6
+
671 #define D_STR_RC6 "RC6"
+
672 #endif // D_STR_RC6
+
673 #ifndef D_STR_RCMM
+
674 #define D_STR_RCMM "RCMM"
+
675 #endif // D_STR_RCMM
+
676 #ifndef D_STR_SAMSUNG
+
677 #define D_STR_SAMSUNG "SAMSUNG"
+
678 #endif // D_STR_SAMSUNG
+
679 #ifndef D_STR_SAMSUNG36
+
680 #define D_STR_SAMSUNG36 "SAMSUNG36"
+
681 #endif // D_STR_SAMSUNG36
+
682 #ifndef D_STR_SAMSUNG_AC
+
683 #define D_STR_SAMSUNG_AC "SAMSUNG_AC"
+
684 #endif // D_STR_SAMSUNG_AC
+
685 #ifndef D_STR_SANYO
+
686 #define D_STR_SANYO "SANYO"
+
687 #endif // D_STR_SANYO
+
688 #ifndef D_STR_SANYO_LC7461
+
689 #define D_STR_SANYO_LC7461 "SANYO_LC7461"
+
690 #endif // D_STR_SANYO_LC7461
+
691 #ifndef D_STR_SHARP
+
692 #define D_STR_SHARP "SHARP"
+
693 #endif // D_STR_SHARP
+
694 #ifndef D_STR_SHARP_AC
+
695 #define D_STR_SHARP_AC "SHARP_AC"
+
696 #endif // D_STR_SHARP_AC
+
697 #ifndef D_STR_SHERWOOD
+
698 #define D_STR_SHERWOOD "SHERWOOD"
+
699 #endif // D_STR_SHERWOOD
+
700 #ifndef D_STR_SONY
+
701 #define D_STR_SONY "SONY"
+
702 #endif // D_STR_SONY
+
703 #ifndef D_STR_SONY_38K
+
704 #define D_STR_SONY_38K "SONY_38K"
+
705 #endif // D_STR_SONY_38K
+
706 #ifndef D_STR_SYMPHONY
+
707 #define D_STR_SYMPHONY "SYMPHONY"
+
708 #endif // D_STR_SYMPHONY
+
709 #ifndef D_STR_TCL112AC
+
710 #define D_STR_TCL112AC "TCL112AC"
+
711 #endif // D_STR_TCL112AC
+
712 #ifndef D_STR_TECO
+
713 #define D_STR_TECO "TECO"
+
714 #endif // D_STR_TECO
+
715 #ifndef D_STR_TOSHIBA_AC
+
716 #define D_STR_TOSHIBA_AC "TOSHIBA_AC"
+
717 #endif // D_STR_TOSHIBA_AC
+
718 #ifndef D_STR_TROTEC
+
719 #define D_STR_TROTEC "TROTEC"
+
720 #endif // D_STR_TROTEC
+
721 #ifndef D_STR_UNUSED
+
722 #define D_STR_UNUSED "UNUSED"
+
723 #endif // D_STR_UNUSED
+
724 #ifndef D_STR_VESTEL_AC
+
725 #define D_STR_VESTEL_AC "VESTEL_AC"
+
726 #endif // D_STR_VESTEL_AC
+
727 #ifndef D_STR_WHIRLPOOL_AC
+
728 #define D_STR_WHIRLPOOL_AC "WHIRLPOOL_AC"
+
729 #endif // D_STR_WHIRLPOOL_AC
+
730 #ifndef D_STR_WHYNTER
+
731 #define D_STR_WHYNTER "WHYNTER"
+
732 #endif // D_STR_WHYNTER
+
733 #ifndef D_STR_ZEPEAL
+
734 #define D_STR_ZEPEAL "ZEPEAL"
+
735 #endif // D_STR_ZEPEAL
+
736 
+
737 // IRrecvDumpV2+
+
738 #ifndef D_STR_TIMESTAMP
+
739 #define D_STR_TIMESTAMP "Timestamp"
+
740 #endif // D_STR_TIMESTAMP
+
741 #ifndef D_STR_LIBRARY
+
742 #define D_STR_LIBRARY "Library"
+
743 #endif // D_STR_LIBRARY
+
744 #ifndef D_STR_MESGDESC
+
745 #define D_STR_MESGDESC "Mesg Desc."
+
746 #endif // D_STR_MESGDESC
+
747 #ifndef D_STR_IRRECVDUMP_STARTUP
+
748 #define D_STR_IRRECVDUMP_STARTUP \
+
749  "IRrecvDump is now running and waiting for IR input on Pin %d"
+
750 #endif // D_STR_IRRECVDUMP_STARTUP
+
751 #ifndef D_WARN_BUFFERFULL
+
752 #define D_WARN_BUFFERFULL \
+
753  "WARNING: IR code is too big for buffer (>= %d). " \
+
754  "This result shouldn't be trusted until this is resolved. " \
+
755  "Edit & increase `kCaptureBufferSize`."
+
756 #endif // D_WARN_BUFFERFULL
+
757 
+
758 #endif // LOCALE_DEFAULTS_H_
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/deprecated.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/deprecated.html new file mode 100644 index 000000000..58f8129ca --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/deprecated.html @@ -0,0 +1,85 @@ + + + + + + + +IRremoteESP8266: Deprecated List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
Deprecated List
+
+
+
+
Member IRsend::sendPanasonic (const uint16_t address, const uint32_t data, const uint16_t nbits=kPanasonicBits, const uint16_t repeat=kNoRepeat)
+
This is only for legacy use only, please use sendPanasonic64() instead.
+
Member IRsend::sendSharp (const uint16_t address, const uint16_t command, const uint16_t nbits=kSharpBits, const uint16_t repeat=kNoRepeat)
+
Only use this if you are using legacy from the original Arduino-IRremote library. 99% of the time, you will want to use sendSharpRaw() instead
+
Member resultToTimingInfo (const decode_results *const results)
+
This is only for those that want this legacy format.
+
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/dir_49e56c817e5e54854c35e136979f97ca.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/dir_49e56c817e5e54854c35e136979f97ca.html new file mode 100644 index 000000000..6b30372c6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/dir_49e56c817e5e54854c35e136979f97ca.html @@ -0,0 +1,80 @@ + + + + + + + +IRremoteESP8266: docs Directory Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
docs Directory Reference
+
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/dir_68267d1309a1af8e8297ef4c3efbcdba.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/dir_68267d1309a1af8e8297ef4c3efbcdba.html new file mode 100644 index 000000000..9d915e190 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/dir_68267d1309a1af8e8297ef4c3efbcdba.html @@ -0,0 +1,373 @@ + + + + + + + +IRremoteESP8266: src Directory Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
src Directory Reference
+
+
+ + + + +

+Directories

directory  locale
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Files

file  i18n.h [code]
 
file  ir_Airwell.cpp
 Airwell "Manchester code" based protocol. Some other Airwell products use the COOLIX protocol.
 
file  ir_Aiwa.cpp
 Aiwa based protocol. Based off the RC-T501 RCU Inspired by IRremoteESP8266's implementation.
 
file  ir_Amcor.cpp
 Amcor A/C protocol.
 
file  ir_Amcor.h [code]
 Amcor A/C protocol.
 
file  ir_Argo.cpp
 Argo A/C protocol. Controls an Argo Ulisse 13 DCI A/C.
 
file  ir_Argo.h [code]
 Support for Argo Ulisse 13 DCI Mobile Split ACs.
 
file  ir_Carrier.cpp
 Carrier protocols.
 
file  ir_Carrier.h [code]
 Carrier A/C.
 
file  ir_Coolix.cpp
 Coolix A/C / heatpump.
 
file  ir_Coolix.h [code]
 
file  ir_Corona.cpp
 Corona A/C protocol.
 
file  ir_Corona.h [code]
 
file  ir_Daikin.cpp
 Support for Daikin A/C protocols.
 
file  ir_Daikin.h [code]
 Support for Daikin A/C protocols.
 
file  ir_Delonghi.cpp
 Delonghi based protocol.
 
file  ir_Delonghi.h [code]
 Delonghi A/C.
 
file  ir_Denon.cpp
 Denon support Original Denon support added by https://github.com/csBlueChip Ported over by Massimiliano Pinto.
 
file  ir_Dish.cpp
 DISH Network protocol support DISH support originally by Todd Treece.
 
file  ir_Doshisha.cpp
 Doshisha protocol support.
 
file  ir_Electra.cpp
 Support for Electra A/C protocols.
 
file  ir_Electra.h [code]
 Support for Electra A/C protocols.
 
file  ir_Epson.cpp
 Support for Epson protocols. Epson is an NEC-like protocol, except it doesn't use the NEC style repeat.
 
file  ir_Fujitsu.cpp
 Support for Fujitsu A/C protocols. Fujitsu A/C support added by Jonny Graham & David Conran.
 
file  ir_Fujitsu.h [code]
 Support for Fujitsu A/C protocols. Fujitsu A/C support added by Jonny Graham.
 
file  ir_GICable.cpp
 G.I. Cable.
 
file  ir_GlobalCache.cpp
 Global Cache IR format sender Originally added by Hisham Khalifa (http://www.hishamkhalifa.com)
 
file  ir_Goodweather.cpp
 Support for Goodweather compatible HVAC protocols.
 
file  ir_Goodweather.h [code]
 Support for Goodweather compatible HVAC protocols.
 
file  ir_Gree.cpp
 Support for Gree A/C protocols.
 
file  ir_Gree.h [code]
 Support for Gree A/C protocols.
 
file  ir_Haier.cpp
 Support for Haier A/C protocols. The specifics of reverse engineering the protocols details:
 
file  ir_Haier.h [code]
 Support for Haier A/C protocols. The specifics of reverse engineering the protocols details:
 
file  ir_Hitachi.cpp
 Support for Hitachi A/C protocols.
 
file  ir_Hitachi.h [code]
 Support for Hitachi A/C protocols.
 
file  ir_Inax.cpp
 Support for the Inax Robot Toilet IR protocols.
 
file  ir_JVC.cpp
 Support for JVC protocols. Originally added by Kristian Lauszus Thanks to zenwheel and other people at the original blog post.
 
file  ir_Kelvinator.cpp
 Support for Kelvinator A/C protocols. Code to emulate IR Kelvinator YALIF remote control unit, which should control at least the following Kelvinator A/C units: KSV26CRC, KSV26HRC, KSV35CRC, KSV35HRC, KSV53HRC, KSV62HRC, KSV70CRC, KSV70HRC, KSV80HRC.
 
file  ir_Kelvinator.h [code]
 Support for Kelvinator A/C protocols.
 
file  ir_Lasertag.cpp
 Support for Lasertag protocols.
 
file  ir_Lego.cpp
 Support for LEGO protocols.
 
file  ir_LG.cpp
 Support for LG protocols. LG decode originally added by Darryl Smith (based on the JVC protocol) LG send originally added by https://github.com/chaeplin.
 
file  ir_LG.h [code]
 Support for LG protocols.
 
file  ir_Lutron.cpp
 Support for Lutron protocols.
 
file  ir_Magiquest.cpp
 Support for MagiQuest protocols.
 
file  ir_Magiquest.h [code]
 Support for MagiQuest protocols.
 
file  ir_Midea.cpp
 Support for Midea protocols. Midea added by crankyoldgit & bwze. send: bwze/crankyoldgit, decode: crankyoldgit.
 
file  ir_Midea.h [code]
 Support for Midea protocols. Midea added by crankyoldgit & bwze.
 
file  ir_Mitsubishi.cpp
 Support for Mitsubishi protocols. Mitsubishi (TV) decoding added from https://github.com/z3t0/Arduino-IRremote Mitsubishi (TV) sending & Mitsubishi A/C support added by David Conran.
 
file  ir_Mitsubishi.h [code]
 Support for Mitsubishi protocols. Mitsubishi (TV) decoding added from https://github.com/z3t0/Arduino-IRremote Mitsubishi (TV) sending & Mitsubishi A/C support added by David Conran.
 
file  ir_MitsubishiHeavy.cpp
 Support for Mitsubishi Heavy Industry protocols. Code to emulate Mitsubishi Heavy Industries A/C IR remote control units.
 
file  ir_MitsubishiHeavy.h [code]
 Support for Mitsubishi Heavy Industry protocols. Code to emulate Mitsubishi Heavy Industries A/C IR remote control units.
 
file  ir_Multibrackets.cpp
 Support for Multibrackets protocols.
 
file  ir_MWM.cpp
 Disney Made With Magic (MWM) Support derived from ir_Lasertag.cpp.
 
file  ir_NEC.cpp
 Support for NEC (Renesas) protocols. NEC originally added from https://github.com/shirriff/Arduino-IRremote/.
 
file  ir_NEC.h [code]
 Support for NEC (Renesas) protocols. NEC originally added from https://github.com/shirriff/Arduino-IRremote/.
 
file  ir_Neoclima.cpp
 Support for Neoclima protocols. Analysis by crankyoldgit & AndreyShpilevoy Code by crankyoldgit.
 
file  ir_Neoclima.h [code]
 Support for Neoclima protocols. Analysis by crankyoldgit & AndreyShpilevoy.
 
file  ir_Nikai.cpp
 Nikai.
 
file  ir_Panasonic.cpp
 Support for Panasonic protocols. Panasonic protocol originally added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
 
file  ir_Panasonic.h [code]
 Support for Panasonic protocols.
 
file  ir_Pioneer.cpp
 Pioneer remote emulation.
 
file  ir_Pronto.cpp
 Pronto code message generation.
 
file  ir_RC5_RC6.cpp
 RC-5 & RC-6 support RC-5 & RC-6 support added from https://github.com/z3t0/Arduino-IRremote RC-5X support added by David Conran.
 
file  ir_RCMM.cpp
 Support for the Phillips RC-MM protocol.
 
file  ir_Samsung.cpp
 Support for Samsung protocols. Samsung originally added from https://github.com/shirriff/Arduino-IRremote/.
 
file  ir_Samsung.h [code]
 Support for Samsung protocols. Samsung originally added from https://github.com/shirriff/Arduino-IRremote/.
 
file  ir_Sanyo.cpp
 Support for Sanyo protocols. Sanyo LC7461 support originally by marcosamarinho Sanyo SA 8650B originally added from https://github.com/shirriff/Arduino-IRremote/.
 
file  ir_Sharp.cpp
 Support for Sharp protocols.
 
file  ir_Sharp.h [code]
 Support for Sharp protocols.
 
file  ir_Sherwood.cpp
 Support for Sherwood protocols.
 
file  ir_Sony.cpp
 Support for Sony SIRC(Serial Infra-Red Control) protocols. Sony originally added from https://github.com/shirriff/Arduino-IRremote/ Updates from marcosamarinho.
 
file  ir_Symphony.cpp
 Support for Symphony protocols.
 
file  ir_Tcl.cpp
 Support for TCL protocols.
 
file  ir_Tcl.h [code]
 Support for TCL protocols.
 
file  ir_Teco.cpp
 Support for Teco protocols.
 
file  ir_Teco.h [code]
 Support for Teco protocols.
 
file  ir_Toshiba.cpp
 Support for Toshiba protocols.
 
file  ir_Toshiba.h [code]
 Support for Toshiba protocols.
 
file  ir_Trotec.cpp
 Support for Trotec protocols.
 
file  ir_Trotec.h [code]
 Support for Trotec protocols.
 
file  ir_Vestel.cpp
 Support for Vestel protocols. Vestel added by Erdem U. Altinyurt.
 
file  ir_Vestel.h [code]
 Support for Vestel protocols. Vestel added by Erdem U. Altinyurt.
 
file  ir_Whirlpool.cpp
 Support for Whirlpool protocols. Decoding help from: @redmusicxd, @josh929800, @raducostea.
 
file  ir_Whirlpool.h [code]
 Support for Whirlpool protocols. Decoding help from: @redmusicxd, @josh929800, @raducostea.
 
file  ir_Whynter.cpp
 Support for Whynter protocols. Whynter A/C ARC-110WD added by Francesco Meschia Whynter originally added from https://github.com/shirriff/Arduino-IRremote/.
 
file  ir_Zepeal.cpp
 Support for Zepeal protocol. This protocol uses fixed length bit encoding. Most official information about Zepeal seems to be from Denkyosha.
 
file  IRac.cpp
 
file  IRac.h [code]
 
file  IRrecv.cpp
 
file  IRrecv.h [code]
 
file  IRremoteESP8266.h [code]
 
file  IRsend.cpp
 
file  IRsend.h [code]
 
file  IRtext.cpp
 
file  IRtext.h [code]
 
file  IRtimer.cpp
 
file  IRtimer.h [code]
 
file  IRutils.cpp
 
file  IRutils.h [code]
 
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/dir_84fe998d1eb06414cc389ad334e77e63.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/dir_84fe998d1eb06414cc389ad334e77e63.html new file mode 100644 index 000000000..fc5e7c1db --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/dir_84fe998d1eb06414cc389ad334e77e63.html @@ -0,0 +1,106 @@ + + + + + + + +IRremoteESP8266: src/locale Directory Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
locale Directory Reference
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + +

+Files

file  de-CH.h [code]
 
file  de-DE.h [code]
 
file  defaults.h [code]
 
file  en-AU.h [code]
 
file  en-IE.h [code]
 
file  en-UK.h [code]
 
file  en-US.h [code]
 
file  es-ES.h [code]
 
file  fr-FR.h [code]
 
file  it-IT.h [code]
 
file  zh-CN.h [code]
 
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/doc.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/doc.png new file mode 100644 index 000000000..17edabff9 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/doc.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/doxygen.css b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/doxygen.css new file mode 100644 index 000000000..73ecbb2cb --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/doxygen.css @@ -0,0 +1,1771 @@ +/* The standard CSS for doxygen 1.8.17 */ + +body, table, div, p, dl { + font: 400 14px/22px Roboto,sans-serif; +} + +p.reference, p.definition { + font: 400 14px/22px Roboto,sans-serif; +} + +/* @group Heading Levels */ + +h1.groupheader { + font-size: 150%; +} + +.title { + font: 400 14px/28px Roboto,sans-serif; + font-size: 150%; + font-weight: bold; + margin: 10px 2px; +} + +h2.groupheader { + border-bottom: 1px solid #879ECB; + color: #354C7B; + font-size: 150%; + font-weight: normal; + margin-top: 1.75em; + padding-top: 8px; + padding-bottom: 4px; + width: 100%; +} + +h3.groupheader { + font-size: 100%; +} + +h1, h2, h3, h4, h5, h6 { + -webkit-transition: text-shadow 0.5s linear; + -moz-transition: text-shadow 0.5s linear; + -ms-transition: text-shadow 0.5s linear; + -o-transition: text-shadow 0.5s linear; + transition: text-shadow 0.5s linear; + margin-right: 15px; +} + +h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow { + text-shadow: 0 0 15px cyan; +} + +dt { + font-weight: bold; +} + +ul.multicol { + -moz-column-gap: 1em; + -webkit-column-gap: 1em; + column-gap: 1em; + -moz-column-count: 3; + -webkit-column-count: 3; + column-count: 3; +} + +p.startli, p.startdd { + margin-top: 2px; +} + +th p.starttd, p.intertd, p.endtd { + font-size: 100%; + font-weight: 700; +} + +p.starttd { + margin-top: 0px; +} + +p.endli { + margin-bottom: 0px; +} + +p.enddd { + margin-bottom: 4px; +} + +p.endtd { + margin-bottom: 2px; +} + +p.interli { +} + +p.interdd { +} + +p.intertd { +} + +/* @end */ + +caption { + font-weight: bold; +} + +span.legend { + font-size: 70%; + text-align: center; +} + +h3.version { + font-size: 90%; + text-align: center; +} + +div.qindex, div.navtab{ + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; +} + +div.qindex, div.navpath { + width: 100%; + line-height: 140%; +} + +div.navtab { + margin-right: 15px; +} + +/* @group Link Styling */ + +a { + color: #3D578C; + font-weight: normal; + text-decoration: none; +} + +.contents a:visited { + color: #4665A2; +} + +a:hover { + text-decoration: underline; +} + +a.qindex { + font-weight: bold; +} + +a.qindexHL { + font-weight: bold; + background-color: #9CAFD4; + color: #FFFFFF; + border: 1px double #869DCA; +} + +.contents a.qindexHL:visited { + color: #FFFFFF; +} + +a.el { + font-weight: bold; +} + +a.elRef { +} + +a.code, a.code:visited, a.line, a.line:visited { + color: #4665A2; +} + +a.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited { + color: #4665A2; +} + +/* @end */ + +dl.el { + margin-left: -1cm; +} + +ul { + overflow: hidden; /*Fixed: list item bullets overlap floating elements*/ +} + +#side-nav ul { + overflow: visible; /* reset ul rule for scroll bar in GENERATE_TREEVIEW window */ +} + +#main-nav ul { + overflow: visible; /* reset ul rule for the navigation bar drop down lists */ +} + +.fragment { + text-align: left; + direction: ltr; + overflow-x: auto; /*Fixed: fragment lines overlap floating elements*/ + overflow-y: hidden; +} + +pre.fragment { + border: 1px solid #C4CFE5; + background-color: #FBFCFD; + padding: 4px 6px; + margin: 4px 8px 4px 2px; + overflow: auto; + word-wrap: break-word; + font-size: 9pt; + line-height: 125%; + font-family: monospace, fixed; + font-size: 105%; +} + +div.fragment { + padding: 0 0 1px 0; /*Fixed: last line underline overlap border*/ + margin: 4px 8px 4px 2px; + background-color: #FBFCFD; + border: 1px solid #C4CFE5; +} + +div.line { + font-family: monospace, fixed; + font-size: 13px; + min-height: 13px; + line-height: 1.0; + text-wrap: unrestricted; + white-space: -moz-pre-wrap; /* Moz */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + white-space: pre-wrap; /* CSS3 */ + word-wrap: break-word; /* IE 5.5+ */ + text-indent: -53px; + padding-left: 53px; + padding-bottom: 0px; + margin: 0px; + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +div.line:after { + content:"\000A"; + white-space: pre; +} + +div.line.glow { + background-color: cyan; + box-shadow: 0 0 10px cyan; +} + + +span.lineno { + padding-right: 4px; + text-align: right; + border-right: 2px solid #0F0; + background-color: #E8E8E8; + white-space: pre; +} +span.lineno a { + background-color: #D8D8D8; +} + +span.lineno a:hover { + background-color: #C8C8C8; +} + +.lineno { + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +div.ah, span.ah { + background-color: black; + font-weight: bold; + color: #FFFFFF; + margin-bottom: 3px; + margin-top: 3px; + padding: 0.2em; + border: solid thin #333; + border-radius: 0.5em; + -webkit-border-radius: .5em; + -moz-border-radius: .5em; + box-shadow: 2px 2px 3px #999; + -webkit-box-shadow: 2px 2px 3px #999; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444)); + background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000 110%); +} + +div.classindex ul { + list-style: none; + padding-left: 0; +} + +div.classindex span.ai { + display: inline-block; +} + +div.groupHeader { + margin-left: 16px; + margin-top: 12px; + font-weight: bold; +} + +div.groupText { + margin-left: 16px; + font-style: italic; +} + +body { + background-color: white; + color: black; + margin: 0; +} + +div.contents { + margin-top: 10px; + margin-left: 12px; + margin-right: 8px; +} + +td.indexkey { + background-color: #EBEFF6; + font-weight: bold; + border: 1px solid #C4CFE5; + margin: 2px 0px 2px 0; + padding: 2px 10px; + white-space: nowrap; + vertical-align: top; +} + +td.indexvalue { + background-color: #EBEFF6; + border: 1px solid #C4CFE5; + padding: 2px 10px; + margin: 2px 0px; +} + +tr.memlist { + background-color: #EEF1F7; +} + +p.formulaDsp { + text-align: center; +} + +img.formulaDsp { + +} + +img.formulaInl, img.inline { + vertical-align: middle; +} + +div.center { + text-align: center; + margin-top: 0px; + margin-bottom: 0px; + padding: 0px; +} + +div.center img { + border: 0px; +} + +address.footer { + text-align: right; + padding-right: 12px; +} + +img.footer { + border: 0px; + vertical-align: middle; +} + +/* @group Code Colorization */ + +span.keyword { + color: #008000 +} + +span.keywordtype { + color: #604020 +} + +span.keywordflow { + color: #e08000 +} + +span.comment { + color: #800000 +} + +span.preprocessor { + color: #806020 +} + +span.stringliteral { + color: #002080 +} + +span.charliteral { + color: #008080 +} + +span.vhdldigit { + color: #ff00ff +} + +span.vhdlchar { + color: #000000 +} + +span.vhdlkeyword { + color: #700070 +} + +span.vhdllogic { + color: #ff0000 +} + +blockquote { + background-color: #F7F8FB; + border-left: 2px solid #9CAFD4; + margin: 0 24px 0 4px; + padding: 0 12px 0 16px; +} + +blockquote.DocNodeRTL { + border-left: 0; + border-right: 2px solid #9CAFD4; + margin: 0 4px 0 24px; + padding: 0 16px 0 12px; +} + +/* @end */ + +/* +.search { + color: #003399; + font-weight: bold; +} + +form.search { + margin-bottom: 0px; + margin-top: 0px; +} + +input.search { + font-size: 75%; + color: #000080; + font-weight: normal; + background-color: #e8eef2; +} +*/ + +td.tiny { + font-size: 75%; +} + +.dirtab { + padding: 4px; + border-collapse: collapse; + border: 1px solid #A3B4D7; +} + +th.dirtab { + background: #EBEFF6; + font-weight: bold; +} + +hr { + height: 0px; + border: none; + border-top: 1px solid #4A6AAA; +} + +hr.footer { + height: 1px; +} + +/* @group Member Descriptions */ + +table.memberdecls { + border-spacing: 0px; + padding: 0px; +} + +.memberdecls td, .fieldtable tr { + -webkit-transition-property: background-color, box-shadow; + -webkit-transition-duration: 0.5s; + -moz-transition-property: background-color, box-shadow; + -moz-transition-duration: 0.5s; + -ms-transition-property: background-color, box-shadow; + -ms-transition-duration: 0.5s; + -o-transition-property: background-color, box-shadow; + -o-transition-duration: 0.5s; + transition-property: background-color, box-shadow; + transition-duration: 0.5s; +} + +.memberdecls td.glow, .fieldtable tr.glow { + background-color: cyan; + box-shadow: 0 0 15px cyan; +} + +.mdescLeft, .mdescRight, +.memItemLeft, .memItemRight, +.memTemplItemLeft, .memTemplItemRight, .memTemplParams { + background-color: #F9FAFC; + border: none; + margin: 4px; + padding: 1px 0 0 8px; +} + +.mdescLeft, .mdescRight { + padding: 0px 8px 4px 8px; + color: #555; +} + +.memSeparator { + border-bottom: 1px solid #DEE4F0; + line-height: 1px; + margin: 0px; + padding: 0px; +} + +.memItemLeft, .memTemplItemLeft { + white-space: nowrap; +} + +.memItemRight, .memTemplItemRight { + width: 100%; +} + +.memTemplParams { + color: #4665A2; + white-space: nowrap; + font-size: 80%; +} + +/* @end */ + +/* @group Member Details */ + +/* Styles for detailed member documentation */ + +.memtitle { + padding: 8px; + border-top: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + border-top-right-radius: 4px; + border-top-left-radius: 4px; + margin-bottom: -1px; + background-image: url('nav_f.png'); + background-repeat: repeat-x; + background-color: #E2E8F2; + line-height: 1.25; + font-weight: 300; + float:left; +} + +.permalink +{ + font-size: 65%; + display: inline-block; + vertical-align: middle; +} + +.memtemplate { + font-size: 80%; + color: #4665A2; + font-weight: normal; + margin-left: 9px; +} + +.memnav { + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} + +.mempage { + width: 100%; +} + +.memitem { + padding: 0; + margin-bottom: 10px; + margin-right: 5px; + -webkit-transition: box-shadow 0.5s linear; + -moz-transition: box-shadow 0.5s linear; + -ms-transition: box-shadow 0.5s linear; + -o-transition: box-shadow 0.5s linear; + transition: box-shadow 0.5s linear; + display: table !important; + width: 100%; +} + +.memitem.glow { + box-shadow: 0 0 15px cyan; +} + +.memname { + font-weight: 400; + margin-left: 6px; +} + +.memname td { + vertical-align: bottom; +} + +.memproto, dl.reflist dt { + border-top: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 0px 6px 0px; + color: #253555; + font-weight: bold; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + background-color: #DFE5F1; + /* opera specific markup */ + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + border-top-right-radius: 4px; + /* firefox specific markup */ + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + -moz-border-radius-topright: 4px; + /* webkit specific markup */ + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + -webkit-border-top-right-radius: 4px; + +} + +.overload { + font-family: "courier new",courier,monospace; + font-size: 65%; +} + +.memdoc, dl.reflist dd { + border-bottom: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 10px 2px 10px; + background-color: #FBFCFD; + border-top-width: 0; + background-image:url('nav_g.png'); + background-repeat:repeat-x; + background-color: #FFFFFF; + /* opera specific markup */ + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + /* firefox specific markup */ + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-bottomright: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + /* webkit specific markup */ + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +dl.reflist dt { + padding: 5px; +} + +dl.reflist dd { + margin: 0px 0px 10px 0px; + padding: 5px; +} + +.paramkey { + text-align: right; +} + +.paramtype { + white-space: nowrap; +} + +.paramname { + color: #602020; + white-space: nowrap; +} +.paramname em { + font-style: normal; +} +.paramname code { + line-height: 14px; +} + +.params, .retval, .exception, .tparams { + margin-left: 0px; + padding-left: 0px; +} + +.params .paramname, .retval .paramname, .tparams .paramname, .exception .paramname { + font-weight: bold; + vertical-align: top; +} + +.params .paramtype, .tparams .paramtype { + font-style: italic; + vertical-align: top; +} + +.params .paramdir, .tparams .paramdir { + font-family: "courier new",courier,monospace; + vertical-align: top; +} + +table.mlabels { + border-spacing: 0px; +} + +td.mlabels-left { + width: 100%; + padding: 0px; +} + +td.mlabels-right { + vertical-align: bottom; + padding: 0px; + white-space: nowrap; +} + +span.mlabels { + margin-left: 8px; +} + +span.mlabel { + background-color: #728DC1; + border-top:1px solid #5373B4; + border-left:1px solid #5373B4; + border-right:1px solid #C4CFE5; + border-bottom:1px solid #C4CFE5; + text-shadow: none; + color: white; + margin-right: 4px; + padding: 2px 3px; + border-radius: 3px; + font-size: 7pt; + white-space: nowrap; + vertical-align: middle; +} + + + +/* @end */ + +/* these are for tree view inside a (index) page */ + +div.directory { + margin: 10px 0px; + border-top: 1px solid #9CAFD4; + border-bottom: 1px solid #9CAFD4; + width: 100%; +} + +.directory table { + border-collapse:collapse; +} + +.directory td { + margin: 0px; + padding: 0px; + vertical-align: top; +} + +.directory td.entry { + white-space: nowrap; + padding-right: 6px; + padding-top: 3px; +} + +.directory td.entry a { + outline:none; +} + +.directory td.entry a img { + border: none; +} + +.directory td.desc { + width: 100%; + padding-left: 6px; + padding-right: 6px; + padding-top: 3px; + border-left: 1px solid rgba(0,0,0,0.05); +} + +.directory tr.even { + padding-left: 6px; + background-color: #F7F8FB; +} + +.directory img { + vertical-align: -30%; +} + +.directory .levels { + white-space: nowrap; + width: 100%; + text-align: right; + font-size: 9pt; +} + +.directory .levels span { + cursor: pointer; + padding-left: 2px; + padding-right: 2px; + color: #3D578C; +} + +.arrow { + color: #9CAFD4; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + cursor: pointer; + font-size: 80%; + display: inline-block; + width: 16px; + height: 22px; +} + +.icon { + font-family: Arial, Helvetica; + font-weight: bold; + font-size: 12px; + height: 14px; + width: 16px; + display: inline-block; + background-color: #728DC1; + color: white; + text-align: center; + border-radius: 4px; + margin-left: 2px; + margin-right: 2px; +} + +.icona { + width: 24px; + height: 22px; + display: inline-block; +} + +.iconfopen { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('folderopen.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +.iconfclosed { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('folderclosed.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +.icondoc { + width: 24px; + height: 18px; + margin-bottom: 4px; + background-image:url('doc.png'); + background-position: 0px -4px; + background-repeat: repeat-y; + vertical-align:top; + display: inline-block; +} + +table.directory { + font: 400 14px Roboto,sans-serif; +} + +/* @end */ + +div.dynheader { + margin-top: 8px; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +address { + font-style: normal; + color: #2A3D61; +} + +table.doxtable caption { + caption-side: top; +} + +table.doxtable { + border-collapse:collapse; + margin-top: 4px; + margin-bottom: 4px; +} + +table.doxtable td, table.doxtable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +table.doxtable th { + background-color: #374F7F; + color: #FFFFFF; + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; +} + +table.fieldtable { + /*width: 100%;*/ + margin-bottom: 10px; + border: 1px solid #A8B8D9; + border-spacing: 0px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); + box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); +} + +.fieldtable td, .fieldtable th { + padding: 3px 7px 2px; +} + +.fieldtable td.fieldtype, .fieldtable td.fieldname { + white-space: nowrap; + border-right: 1px solid #A8B8D9; + border-bottom: 1px solid #A8B8D9; + vertical-align: top; +} + +.fieldtable td.fieldname { + padding-top: 3px; +} + +.fieldtable td.fielddoc { + border-bottom: 1px solid #A8B8D9; + /*width: 100%;*/ +} + +.fieldtable td.fielddoc p:first-child { + margin-top: 0px; +} + +.fieldtable td.fielddoc p:last-child { + margin-bottom: 2px; +} + +.fieldtable tr:last-child td { + border-bottom: none; +} + +.fieldtable th { + background-image:url('nav_f.png'); + background-repeat:repeat-x; + background-color: #E2E8F2; + font-size: 90%; + color: #253555; + padding-bottom: 4px; + padding-top: 5px; + text-align:left; + font-weight: 400; + -moz-border-radius-topleft: 4px; + -moz-border-radius-topright: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom: 1px solid #A8B8D9; +} + + +.tabsearch { + top: 0px; + left: 10px; + height: 36px; + background-image: url('tab_b.png'); + z-index: 101; + overflow: hidden; + font-size: 13px; +} + +.navpath ul +{ + font-size: 11px; + background-image:url('tab_b.png'); + background-repeat:repeat-x; + background-position: 0 -5px; + height:30px; + line-height:30px; + color:#8AA0CC; + border:solid 1px #C2CDE4; + overflow:hidden; + margin:0px; + padding:0px; +} + +.navpath li +{ + list-style-type:none; + float:left; + padding-left:10px; + padding-right:15px; + background-image:url('bc_s.png'); + background-repeat:no-repeat; + background-position:right; + color:#364D7C; +} + +.navpath li.navelem a +{ + height:32px; + display:block; + text-decoration: none; + outline: none; + color: #283A5D; + font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + text-decoration: none; +} + +.navpath li.navelem a:hover +{ + color:#6884BD; +} + +.navpath li.footer +{ + list-style-type:none; + float:right; + padding-left:10px; + padding-right:15px; + background-image:none; + background-repeat:no-repeat; + background-position:right; + color:#364D7C; + font-size: 8pt; +} + + +div.summary +{ + float: right; + font-size: 8pt; + padding-right: 5px; + width: 50%; + text-align: right; +} + +div.summary a +{ + white-space: nowrap; +} + +table.classindex +{ + margin: 10px; + white-space: nowrap; + margin-left: 3%; + margin-right: 3%; + width: 94%; + border: 0; + border-spacing: 0; + padding: 0; +} + +div.ingroups +{ + font-size: 8pt; + width: 50%; + text-align: left; +} + +div.ingroups a +{ + white-space: nowrap; +} + +div.header +{ + background-image:url('nav_h.png'); + background-repeat:repeat-x; + background-color: #F9FAFC; + margin: 0px; + border-bottom: 1px solid #C4CFE5; +} + +div.headertitle +{ + padding: 5px 5px 5px 10px; +} + +.PageDocRTL-title div.headertitle { + text-align: right; + direction: rtl; +} + +dl { + padding: 0 0 0 0; +} + +/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug, dl.examples */ +dl.section { + margin-left: 0px; + padding-left: 0px; +} + +dl.section.DocNodeRTL { + margin-right: 0px; + padding-right: 0px; +} + +dl.note { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #D0C000; +} + +dl.note.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #D0C000; +} + +dl.warning, dl.attention { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #FF0000; +} + +dl.warning.DocNodeRTL, dl.attention.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #FF0000; +} + +dl.pre, dl.post, dl.invariant { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #00D000; +} + +dl.pre.DocNodeRTL, dl.post.DocNodeRTL, dl.invariant.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #00D000; +} + +dl.deprecated { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #505050; +} + +dl.deprecated.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #505050; +} + +dl.todo { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #00C0E0; +} + +dl.todo.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #00C0E0; +} + +dl.test { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #3030E0; +} + +dl.test.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #3030E0; +} + +dl.bug { + margin-left: -7px; + padding-left: 3px; + border-left: 4px solid; + border-color: #C08050; +} + +dl.bug.DocNodeRTL { + margin-left: 0; + padding-left: 0; + border-left: 0; + margin-right: -7px; + padding-right: 3px; + border-right: 4px solid; + border-color: #C08050; +} + +dl.section dd { + margin-bottom: 6px; +} + + +#projectlogo +{ + text-align: center; + vertical-align: bottom; + border-collapse: separate; +} + +#projectlogo img +{ + border: 0px none; +} + +#projectalign +{ + vertical-align: middle; +} + +#projectname +{ + font: 300% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 2px 0px; +} + +#projectbrief +{ + font: 120% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#projectnumber +{ + font: 50% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#titlearea +{ + padding: 0px; + margin: 0px; + width: 100%; + border-bottom: 1px solid #5373B4; +} + +.image +{ + text-align: center; +} + +.dotgraph +{ + text-align: center; +} + +.mscgraph +{ + text-align: center; +} + +.plantumlgraph +{ + text-align: center; +} + +.diagraph +{ + text-align: center; +} + +.caption +{ + font-weight: bold; +} + +div.zoom +{ + border: 1px solid #90A5CE; +} + +dl.citelist { + margin-bottom:50px; +} + +dl.citelist dt { + color:#334975; + float:left; + font-weight:bold; + margin-right:10px; + padding:5px; +} + +dl.citelist dd { + margin:2px 0; + padding:5px 0; +} + +div.toc { + padding: 14px 25px; + background-color: #F4F6FA; + border: 1px solid #D8DFEE; + border-radius: 7px 7px 7px 7px; + float: right; + height: auto; + margin: 0 8px 10px 10px; + width: 200px; +} + +.PageDocRTL-title div.toc { + float: left !important; + text-align: right; +} + +div.toc li { + background: url("bdwn.png") no-repeat scroll 0 5px transparent; + font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif; + margin-top: 5px; + padding-left: 10px; + padding-top: 2px; +} + +.PageDocRTL-title div.toc li { + background-position-x: right !important; + padding-left: 0 !important; + padding-right: 10px; +} + +div.toc h3 { + font: bold 12px/1.2 Arial,FreeSans,sans-serif; + color: #4665A2; + border-bottom: 0 none; + margin: 0; +} + +div.toc ul { + list-style: none outside none; + border: medium none; + padding: 0px; +} + +div.toc li.level1 { + margin-left: 0px; +} + +div.toc li.level2 { + margin-left: 15px; +} + +div.toc li.level3 { + margin-left: 30px; +} + +div.toc li.level4 { + margin-left: 45px; +} + +.PageDocRTL-title div.toc li.level1 { + margin-left: 0 !important; + margin-right: 0; +} + +.PageDocRTL-title div.toc li.level2 { + margin-left: 0 !important; + margin-right: 15px; +} + +.PageDocRTL-title div.toc li.level3 { + margin-left: 0 !important; + margin-right: 30px; +} + +.PageDocRTL-title div.toc li.level4 { + margin-left: 0 !important; + margin-right: 45px; +} + +.inherit_header { + font-weight: bold; + color: gray; + cursor: pointer; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.inherit_header td { + padding: 6px 0px 2px 5px; +} + +.inherit { + display: none; +} + +tr.heading h2 { + margin-top: 12px; + margin-bottom: 4px; +} + +/* tooltip related style info */ + +.ttc { + position: absolute; + display: none; +} + +#powerTip { + cursor: default; + white-space: nowrap; + background-color: white; + border: 1px solid gray; + border-radius: 4px 4px 4px 4px; + box-shadow: 1px 1px 7px gray; + display: none; + font-size: smaller; + max-width: 80%; + opacity: 0.9; + padding: 1ex 1em 1em; + position: absolute; + z-index: 2147483647; +} + +#powerTip div.ttdoc { + color: grey; + font-style: italic; +} + +#powerTip div.ttname a { + font-weight: bold; +} + +#powerTip div.ttname { + font-weight: bold; +} + +#powerTip div.ttdeci { + color: #006318; +} + +#powerTip div { + margin: 0px; + padding: 0px; + font: 12px/16px Roboto,sans-serif; +} + +#powerTip:before, #powerTip:after { + content: ""; + position: absolute; + margin: 0px; +} + +#powerTip.n:after, #powerTip.n:before, +#powerTip.s:after, #powerTip.s:before, +#powerTip.w:after, #powerTip.w:before, +#powerTip.e:after, #powerTip.e:before, +#powerTip.ne:after, #powerTip.ne:before, +#powerTip.se:after, #powerTip.se:before, +#powerTip.nw:after, #powerTip.nw:before, +#powerTip.sw:after, #powerTip.sw:before { + border: solid transparent; + content: " "; + height: 0; + width: 0; + position: absolute; +} + +#powerTip.n:after, #powerTip.s:after, +#powerTip.w:after, #powerTip.e:after, +#powerTip.nw:after, #powerTip.ne:after, +#powerTip.sw:after, #powerTip.se:after { + border-color: rgba(255, 255, 255, 0); +} + +#powerTip.n:before, #powerTip.s:before, +#powerTip.w:before, #powerTip.e:before, +#powerTip.nw:before, #powerTip.ne:before, +#powerTip.sw:before, #powerTip.se:before { + border-color: rgba(128, 128, 128, 0); +} + +#powerTip.n:after, #powerTip.n:before, +#powerTip.ne:after, #powerTip.ne:before, +#powerTip.nw:after, #powerTip.nw:before { + top: 100%; +} + +#powerTip.n:after, #powerTip.ne:after, #powerTip.nw:after { + border-top-color: #FFFFFF; + border-width: 10px; + margin: 0px -10px; +} +#powerTip.n:before { + border-top-color: #808080; + border-width: 11px; + margin: 0px -11px; +} +#powerTip.n:after, #powerTip.n:before { + left: 50%; +} + +#powerTip.nw:after, #powerTip.nw:before { + right: 14px; +} + +#powerTip.ne:after, #powerTip.ne:before { + left: 14px; +} + +#powerTip.s:after, #powerTip.s:before, +#powerTip.se:after, #powerTip.se:before, +#powerTip.sw:after, #powerTip.sw:before { + bottom: 100%; +} + +#powerTip.s:after, #powerTip.se:after, #powerTip.sw:after { + border-bottom-color: #FFFFFF; + border-width: 10px; + margin: 0px -10px; +} + +#powerTip.s:before, #powerTip.se:before, #powerTip.sw:before { + border-bottom-color: #808080; + border-width: 11px; + margin: 0px -11px; +} + +#powerTip.s:after, #powerTip.s:before { + left: 50%; +} + +#powerTip.sw:after, #powerTip.sw:before { + right: 14px; +} + +#powerTip.se:after, #powerTip.se:before { + left: 14px; +} + +#powerTip.e:after, #powerTip.e:before { + left: 100%; +} +#powerTip.e:after { + border-left-color: #FFFFFF; + border-width: 10px; + top: 50%; + margin-top: -10px; +} +#powerTip.e:before { + border-left-color: #808080; + border-width: 11px; + top: 50%; + margin-top: -11px; +} + +#powerTip.w:after, #powerTip.w:before { + right: 100%; +} +#powerTip.w:after { + border-right-color: #FFFFFF; + border-width: 10px; + top: 50%; + margin-top: -10px; +} +#powerTip.w:before { + border-right-color: #808080; + border-width: 11px; + top: 50%; + margin-top: -11px; +} + +@media print +{ + #top { display: none; } + #side-nav { display: none; } + #nav-path { display: none; } + body { overflow:visible; } + h1, h2, h3, h4, h5, h6 { page-break-after: avoid; } + .summary { display: none; } + .memitem { page-break-inside: avoid; } + #doc-content + { + margin-left:0 !important; + height:auto !important; + width:auto !important; + overflow:inherit; + display:inline; + } +} + +/* @group Markdown */ + +/* +table.markdownTable { + border-collapse:collapse; + margin-top: 4px; + margin-bottom: 4px; +} + +table.markdownTable td, table.markdownTable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +table.markdownTableHead tr { +} + +table.markdownTableBodyLeft td, table.markdownTable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +th.markdownTableHeadLeft th.markdownTableHeadRight th.markdownTableHeadCenter th.markdownTableHeadNone { + background-color: #374F7F; + color: #FFFFFF; + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; +} + +th.markdownTableHeadLeft { + text-align: left +} + +th.markdownTableHeadRight { + text-align: right +} + +th.markdownTableHeadCenter { + text-align: center +} +*/ + +table.markdownTable { + border-collapse:collapse; + margin-top: 4px; + margin-bottom: 4px; +} + +table.markdownTable td, table.markdownTable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +table.markdownTable tr { +} + +th.markdownTableHeadLeft, th.markdownTableHeadRight, th.markdownTableHeadCenter, th.markdownTableHeadNone { + background-color: #374F7F; + color: #FFFFFF; + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; +} + +th.markdownTableHeadLeft, td.markdownTableBodyLeft { + text-align: left +} + +th.markdownTableHeadRight, td.markdownTableBodyRight { + text-align: right +} + +th.markdownTableHeadCenter, td.markdownTableBodyCenter { + text-align: center +} + +.DocNodeRTL { + text-align: right; + direction: rtl; +} + +.DocNodeLTR { + text-align: left; + direction: ltr; +} + +table.DocNodeRTL { + width: auto; + margin-right: 0; + margin-left: auto; +} + +table.DocNodeLTR { + width: auto; + margin-right: auto; + margin-left: 0; +} + +tt, code, kbd, samp +{ + display: inline-block; + direction:ltr; +} +/* @end */ + +u { + text-decoration: underline; +} + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/doxygen.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/doxygen.png new file mode 100644 index 000000000..3ff17d807 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/doxygen.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/doxygen__index_8md.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/doxygen__index_8md.html new file mode 100644 index 000000000..ad1a690b3 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/doxygen__index_8md.html @@ -0,0 +1,76 @@ + + + + + + + +IRremoteESP8266: docs/doxygen_index.md File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
docs/doxygen_index.md File Reference
+
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/dynsections.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/dynsections.js new file mode 100644 index 000000000..ea0a7b39a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/dynsections.js @@ -0,0 +1,120 @@ +/* + @licstart The following is the entire license notice for the + JavaScript code in this file. + + Copyright (C) 1997-2017 by Dimitri van Heesch + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + @licend The above is the entire license notice + for the JavaScript code in this file + */ +function toggleVisibility(linkObj) +{ + var base = $(linkObj).attr('id'); + var summary = $('#'+base+'-summary'); + var content = $('#'+base+'-content'); + var trigger = $('#'+base+'-trigger'); + var src=$(trigger).attr('src'); + if (content.is(':visible')===true) { + content.hide(); + summary.show(); + $(linkObj).addClass('closed').removeClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png'); + } else { + content.show(); + summary.hide(); + $(linkObj).removeClass('closed').addClass('opened'); + $(trigger).attr('src',src.substring(0,src.length-10)+'open.png'); + } + return false; +} + +function updateStripes() +{ + $('table.directory tr'). + removeClass('even').filter(':visible:even').addClass('even'); +} + +function toggleLevel(level) +{ + $('table.directory tr').each(function() { + var l = this.id.split('_').length-1; + var i = $('#img'+this.id.substring(3)); + var a = $('#arr'+this.id.substring(3)); + if (l + + + + + + +IRremoteESP8266: src/locale/en-AU.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
en-AU.h File Reference
+
+ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-AU_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-AU_8h_source.html new file mode 100644 index 000000000..0484fcd20 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-AU_8h_source.html @@ -0,0 +1,88 @@ + + + + + + + +IRremoteESP8266: src/locale/en-AU.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
en-AU.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 - David Conran (@crankyoldgit)
+
2 // Locale/language file for English / Australia.
+
3 // This file will override the default values located in `defaults.h`.
+
4 #ifndef LOCALE_EN_AU_H_
+
5 #define LOCALE_EN_AU_H_
+
6 // Nothing should really need to be set here, as en-AU is the default
+
7 // locale/language.
+
8 #endif // LOCALE_EN_AU_H__
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-IE_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-IE_8h.html new file mode 100644 index 000000000..fe4574abc --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-IE_8h.html @@ -0,0 +1,82 @@ + + + + + + + +IRremoteESP8266: src/locale/en-IE.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
en-IE.h File Reference
+
+ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-IE_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-IE_8h_source.html new file mode 100644 index 000000000..27678a585 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-IE_8h_source.html @@ -0,0 +1,88 @@ + + + + + + + +IRremoteESP8266: src/locale/en-IE.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
en-IE.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 - David Conran (@crankyoldgit)
+
2 // Locale/language file for English / Ireland.
+
3 // This file will override the default values located in `defaults.h`.
+
4 #ifndef LOCALE_EN_IE_H_
+
5 #define LOCALE_EN_IE_H_
+
6 // Nothing should really need to be set here, as en-IE is the same as en-AU,
+
7 // which is the default locale/language.
+
8 #endif // LOCALE_EN_IE_H__
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-UK_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-UK_8h.html new file mode 100644 index 000000000..a18db62c2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-UK_8h.html @@ -0,0 +1,82 @@ + + + + + + + +IRremoteESP8266: src/locale/en-UK.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
en-UK.h File Reference
+
+ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-UK_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-UK_8h_source.html new file mode 100644 index 000000000..e46cdbc56 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-UK_8h_source.html @@ -0,0 +1,88 @@ + + + + + + + +IRremoteESP8266: src/locale/en-UK.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
en-UK.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 - David Conran (@crankyoldgit)
+
2 // Locale/language file for English / United Kingdom.
+
3 // This file will override the default values located in `defaults.h`.
+
4 #ifndef LOCALE_EN_UK_H_
+
5 #define LOCALE_EN_UK_H_
+
6 // Nothing should really need to be set here, as en-UK is the same as en-AU,
+
7 // which is the default locale/language.
+
8 #endif // LOCALE_EN_UK_H__
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-US_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-US_8h.html new file mode 100644 index 000000000..ac8bce965 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-US_8h.html @@ -0,0 +1,82 @@ + + + + + + + +IRremoteESP8266: src/locale/en-US.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
en-US.h File Reference
+
+ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-US_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-US_8h_source.html new file mode 100644 index 000000000..fd8ed5161 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/en-US_8h_source.html @@ -0,0 +1,93 @@ + + + + + + + +IRremoteESP8266: src/locale/en-US.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
en-US.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 - David Conran (@crankyoldgit)
+
2 // Locale/language file for English / United States of America.
+
3 // This file will override the default values located in `defaults.h`.
+
4 #ifndef LOCALE_EN_US_H_
+
5 #define LOCALE_EN_US_H_
+
6 // Not much should really need to be set here, as English is the default
+
7 // locale/language.
+
8 
+
9 // Overrides to the default.
+
10 #define D_STR_CENTRE "Center"
+
11 #define D_STR_MOULD "Mold"
+
12 
+
13 #endif // LOCALE_EN_US_H__
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/es-ES_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/es-ES_8h.html new file mode 100644 index 000000000..4d9de7fab --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/es-ES_8h.html @@ -0,0 +1,82 @@ + + + + + + + +IRremoteESP8266: src/locale/es-ES.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
es-ES.h File Reference
+
+ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/es-ES_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/es-ES_8h_source.html new file mode 100644 index 000000000..fe7a1d618 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/es-ES_8h_source.html @@ -0,0 +1,216 @@ + + + + + + + +IRremoteESP8266: src/locale/es-ES.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
es-ES.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 - Carlos (@charlieyv)
+
2 // Locale/language file for Spanish / Spain.
+
3 // This file will override the default values located in `defaults.h`.
+
4 #ifndef LOCALE_ES_ES_H_
+
5 #define LOCALE_ES_ES_H_
+
6 
+
7 #define D_STR_UNKNOWN "DESCONOCIDO"
+
8 #define D_STR_PROTOCOL "Protocolo"
+
9 #define D_STR_POWER "Poder"
+
10 #define D_STR_PREVIOUS "Anterior"
+
11 #define D_STR_PREVIOUSPOWER D_STR_POWER " " D_STR_PREVIOUS
+
12 #define D_STR_ON "Encendido"
+
13 #define D_STR_OFF "Apagado"
+
14 #define D_STR_MODE "Modo"
+
15 #define D_STR_TOGGLE "Palanca"
+
16 #define D_STR_SLEEP "Dormir"
+
17 #define D_STR_LIGHT "Luz"
+
18 #define D_STR_POWERFUL "Poderoso"
+
19 #define D_STR_QUIET "Silencio"
+
20 #define D_STR_ECONO "Econo"
+
21 #define D_STR_SWING "Oscilar"
+
22 #define D_STR_SWINGH D_STR_SWING"(H)"
+
23 #define D_STR_SWINGV D_STR_SWING"(V)"
+
24 #define D_STR_BEEP "Bip"
+
25 #define D_STR_MOULD "Molde"
+
26 #define D_STR_CLEAN "Limpiar"
+
27 #define D_STR_PURIFY "Purificar"
+
28 #define D_STR_TIMER "Temporizador"
+
29 #define D_STR_ONTIMER D_STR_ON " " D_STR_TIMER
+
30 #define D_STR_OFFTIMER D_STR_OFF " " D_STR_TIMER
+
31 #define D_STR_CLOCK "Reloj"
+
32 #define D_STR_COMMAND "Comando"
+
33 #define D_STR_HEALTH "Salud"
+
34 #define D_STR_MODEL "Modelo"
+
35 #define D_STR_TEMP "Temperatura"
+
36 #define D_STR_HUMID "Humedo"
+
37 #define D_STR_SAVE "Guardar"
+
38 #define D_STR_EYE "Ojo"
+
39 #define D_STR_FOLLOW "Seguir"
+
40 #define D_STR_FRESH "Fresco"
+
41 #define D_STR_HOLD "Mantener"
+
42 #define D_STR_8C_HEAT "8C " D_STR_HEAT
+
43 #define D_STR_BUTTON "Boton"
+
44 #define D_STR_NIGHT "Noche"
+
45 #define D_STR_SILENT "Silencio"
+
46 #define D_STR_FILTER "Filtro"
+
47 #define D_STR_UP "Arriba"
+
48 #define D_STR_TEMPUP D_STR_TEMP " " D_STR_UP
+
49 #define D_STR_DOWN "Abajo"
+
50 #define D_STR_TEMPDOWN D_STR_TEMP " " D_STR_DOWN
+
51 #define D_STR_CHANGE "Cambiar"
+
52 #define D_STR_START "Comenzar"
+
53 #define D_STR_STOP "Parar"
+
54 #define D_STR_MOVE "Mover"
+
55 #define D_STR_SET "Fijar"
+
56 #define D_STR_CANCEL "Cancelar"
+
57 #define D_STR_COMFORT "Comodo"
+
58 #define D_STR_WEEKLY "Semanal"
+
59 #define D_STR_WEEKLYTIMER D_STR_WEEKLY " " D_STR_TIMER
+
60 #define D_STR_LAST "Ultimo"
+
61 #define D_STR_FAST "Rapido"
+
62 #define D_STR_SLOW "Lento"
+
63 #define D_STR_AIRFLOW "Flujo de Aire"
+
64 #define D_STR_STEP "Paso"
+
65 #define D_STR_OUTSIDE "Afuera"
+
66 #define D_STR_LOUD "Ruidoso"
+
67 #define D_STR_UPPER "Superior"
+
68 #define D_STR_LOWER "Inferior"
+
69 #define D_STR_BREEZE "Brisa"
+
70 #define D_STR_CIRCULATE "Circular"
+
71 #define D_STR_CEILING "Techo"
+
72 #define D_STR_WALL "Pared"
+
73 #define D_STR_ROOM "Cuarto"
+
74 #define D_STR_6THSENSE "6to. Sentido"
+
75 #define D_STR_ZONEFOLLOW "Zona Seguir"
+
76 #define D_STR_FIXED "Fijo"
+
77 #define D_STR_AUTOMATIC "Automatico"
+
78 #define D_STR_COOL "Frio"
+
79 #define D_STR_HEAT "Calor"
+
80 #define D_STR_FAN "Ventilador"
+
81 #define D_STR_FANONLY "ventilador_solamente"
+
82 #define D_STR_DRY "Seco"
+
83 #define D_STR_MAX "Max"
+
84 #define D_STR_MAXIMUM "Maximo"
+
85 #define D_STR_MIN "Min"
+
86 #define D_STR_MINIMUM "Minimo"
+
87 #define D_STR_MED "Med"
+
88 #define D_STR_MEDIUM "Medio"
+
89 #define D_STR_HIGHEST "Mas Alto"
+
90 #define D_STR_HIGH "Alto"
+
91 #define D_STR_HI D_STR_HIGH
+
92 #define D_STR_MIDDLE "Medio"
+
93 #define D_STR_MID D_STR_MIDDLE
+
94 #define D_STR_LOW "Bajo"
+
95 #define D_STR_LO D_STR_LOW
+
96 #define D_STR_LOWEST "Mas Bajo"
+
97 #define D_STR_RIGHT "Derecha"
+
98 #define D_STR_MAXRIGHT D_STR_MAX " " D_STR_RIGHT
+
99 #define D_STR_RIGHTMAX_NOSPACE D_STR_RIGHT D_STR_MAX
+
100 #define D_STR_LEFT "Izquierda"
+
101 #define D_STR_MAXLEFT D_STR_MAX " " D_STR_LEFT
+
102 #define D_STR_LEFTMAX_NOSPACE D_STR_LEFT D_STR_MAX
+
103 #define D_STR_WIDE "Ancho"
+
104 #define D_STR_CENTRE "Centro"
+
105 #define D_STR_TOP "Tope"
+
106 #define D_STR_BOTTOM "Fondo"
+
107 #define D_STR_DAY "Dia"
+
108 #define D_STR_DAYS D_STR_DAY "s"
+
109 #define D_STR_HOUR "Hora"
+
110 #define D_STR_HOURS D_STR_HOUR "s"
+
111 #define D_STR_MINUTE "Minuto"
+
112 #define D_STR_MINUTES D_STR_MINUTE "s"
+
113 #define D_STR_SECOND "Segundo"
+
114 #define D_STR_SECONDS D_STR_SECOND "s"
+
115 #define D_STR_NOW "Ahora"
+
116 #define D_STR_THREELETTERDAYS "DomLunMarMieJueVieSab"
+
117 #define D_STR_YES "Si"
+
118 #define D_STR_NO "No"
+
119 #define D_STR_TRUE "Cierto"
+
120 #define D_STR_FALSE "Falso"
+
121 #define D_STR_REPEAT "Repetir"
+
122 #define D_STR_CODE "Codigo"
+
123 
+
124 // IRrecvDumpV2+
+
125 #define D_STR_TIMESTAMP "marca de tiempo"
+
126 #define D_STR_LIBRARY "Libreria"
+
127 #define D_STR_IRRECVDUMP_STARTUP \
+
128  "IRrecvDump esta ahora corriendo y esperando por comando IR en Pin %d"
+
129 #ifndef D_WARN_BUFFERFULL
+
130 #define D_WARN_BUFFERFULL \
+
131  "WARNING: Codigo IR es muy grande para el buffer (>= %d). "\
+
132  "Este resultando no debe ser reconocido hasta que esto sea resuelto." \
+
133  "Edite & incremente `kCaptureBufferSize`."
+
134 #endif // D_WARN_BUFFERFULL
+
135 
+
136 #endif // LOCALE_ES_ES_H_
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/files.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/files.html new file mode 100644 index 000000000..b77a4f9f9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/files.html @@ -0,0 +1,194 @@ + + + + + + + +IRremoteESP8266: File List + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+
File List
+
+
+
Here is a list of all files with brief descriptions:
+
[detail level 123]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 docs
  src
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/folderclosed.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/folderclosed.png new file mode 100644 index 000000000..bb8ab35ed Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/folderclosed.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/folderopen.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/folderopen.png new file mode 100644 index 000000000..d6c7f676a Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/folderopen.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/fr-FR_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/fr-FR_8h.html new file mode 100644 index 000000000..14793daa2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/fr-FR_8h.html @@ -0,0 +1,82 @@ + + + + + + + +IRremoteESP8266: src/locale/fr-FR.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
fr-FR.h File Reference
+
+ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/fr-FR_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/fr-FR_8h_source.html new file mode 100644 index 000000000..5913604c0 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/fr-FR_8h_source.html @@ -0,0 +1,197 @@ + + + + + + + +IRremoteESP8266: src/locale/fr-FR.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
fr-FR.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 - Mathieu D(@Knackie)
+
2 // Locale/language file for French / Quebec.
+
3 // This file will override the default values located in `defaults.h`.
+
4 #ifndef LOCALE_FR_FR_H_
+
5 #define LOCALE_FR_FR_H_
+
6 
+
7 #define D_STR_UNKNOWN "INCONNU"
+
8 #define D_STR_PROTOCOL "Protocole"
+
9 #define D_STR_TOGGLE "Bascule"
+
10 #define D_STR_SLEEP "Pause"
+
11 #define D_STR_LIGHT "Lumière"
+
12 #define D_STR_POWERFUL "Puissance"
+
13 #define D_STR_PREVIOUS "Precedente"
+
14 #define D_STR_PREVIOUSPOWER D_STR_POWER " " D_STR_PREVIOUS
+
15 #define D_STR_QUIET "Silence"
+
16 #define D_STR_ECONO "Economie"
+
17 #define D_STR_BEEP "Bip"
+
18 #define D_STR_MOULD "Moule"
+
19 #define D_STR_CLEAN "Nettoyer"
+
20 #define D_STR_PURIFY "Purifier"
+
21 #define D_STR_ON "On"
+
22 #define D_STR_OFF "Off"
+
23 #define D_STR_ONTIMER D_STR_ON " " D_STR_TIMER
+
24 #define D_STR_OFFTIMER D_STR_OFF " " D_STR_TIMER
+
25 #define D_STR_CLOCK "Heure"
+
26 #define D_STR_COMMAND "Commandement"
+
27 #define D_STR_HEALTH "Santé"
+
28 #define D_STR_TEMP "Temporaire"
+
29 #define D_STR_HUMID "Humidité"
+
30 #define D_STR_SAVE "Sauvegarder"
+
31 #define D_STR_EYE "Oeil"
+
32 #define D_STR_FOLLOW "Suivre"
+
33 #define D_STR_FRESH "Frais"
+
34 #define D_STR_HOLD "Maintenir"
+
35 #define D_STR_BUTTON "Bouton"
+
36 #define D_STR_NIGHT "Nuit"
+
37 #define D_STR_SILENT "Silence"
+
38 #define D_STR_UP "En haut"
+
39 #define D_STR_TEMPUP D_STR_TEMP " " D_STR_UP
+
40 #define D_STR_DOWN "En bas"
+
41 #define D_STR_TEMPDOWN D_STR_TEMP " " D_STR_DOWN
+
42 #define D_STR_CHANGE "Changement"
+
43 #define D_STR_SET "Mettre"
+
44 #define D_STR_CANCEL "Annuler"
+
45 #define D_STR_COMFORT "Confort"
+
46 #define D_STR_WEEKLY "Chaque semaine"
+
47 #define D_STR_WEEKLYTIMER D_STR_WEEKLY " " D_STR_TIMER
+
48 #define D_STR_FAST "Rapide"
+
49 #define D_STR_SLOW "Lent"
+
50 #define D_STR_AIRFLOW "Ebauche"
+
51 #define D_STR_STEP "Etape"
+
52 #define D_STR_OUTSIDE "Plein air"
+
53 #define D_STR_LOUD "Fort"
+
54 #define D_STR_UPPER "Au dessus"
+
55 #define D_STR_LOWER "En dessous"
+
56 #define D_STR_BREEZE "Brise"
+
57 #define D_STR_CIRCULATE "Faire circuler"
+
58 #define D_STR_CEILING "Plafond"
+
59 #define D_STR_WALL "Mur"
+
60 #define D_STR_ROOM "Pièce"
+
61 #define D_STR_6THSENSE "6ter Sens"
+
62 #define D_STR_FIXED "Fixer"
+
63 
+
64 #define D_STR_AUTOMATIC "Automatique"
+
65 #define D_STR_MANUAL "Manuel"
+
66 #define D_STR_COOL "Frais"
+
67 #define D_STR_HEAT "Chaleur"
+
68 #define D_STR_FAN "Ventillateur"
+
69 #define D_STR_FANONLY "Seul_fan"
+
70 #define D_STR_DRY "Sec"
+
71 
+
72 #define D_STR_MEDIUM "Moyen"
+
73 
+
74 #define D_STR_HIGHEST "Le plus haut"
+
75 #define D_STR_HIGH "Haut"
+
76 #define D_STR_HI "H"
+
77 #define D_STR_MID "M"
+
78 #define D_STR_MIDDLE "Moitié"
+
79 #define D_STR_LOW "Bas"
+
80 #define D_STR_LO "B"
+
81 #define D_STR_LOWEST "Le plus bas"
+
82 #define D_STR_RIGHT "Droite"
+
83 #define D_STR_MAX "Max"
+
84 #define D_STR_MAXRIGHT D_STR_MAX " " D_STR_RIGHT
+
85 #define D_STR_RIGHTMAX_NOSPACE D_STR_RIGHT D_STR_MAX
+
86 #define D_STR_LEFT "Gauche"
+
87 #define D_STR_MAXLEFT D_STR_MAX " " D_STR_LEFT
+
88 #define D_STR_LEFTMAX_NOSPACE D_STR_LEFT D_STR_MAX
+
89 #define D_STR_WIDE "Large"
+
90 #define D_STR_TOP "Au-dessus"
+
91 #define D_STR_BOTTOM "En-dessous"
+
92 
+
93 #define D_STR_DAY "Jour"
+
94 #define D_STR_HOUR "Heure"
+
95 #define D_STR_SECOND "Seconde"
+
96 #define D_STR_NOW "Maintenant"
+
97 #define D_STR_THREELETTERDAYS "LunMarMerJeuVenSamDim"
+
98 
+
99 #define D_STR_YES "Oui"
+
100 #define D_STR_NO "Non"
+
101 #define D_STR_TRUE "Vrai"
+
102 #define D_STR_FALSE "Faux"
+
103 
+
104 #define D_STR_REPEAT "Répetition"
+
105 
+
106 // IRrecvDumpV2+
+
107 #define D_STR_TIMESTAMP "Horodatage"
+
108 #define D_STR_LIBRARY "Bibliothèque"
+
109 #define D_STR_MESGDESC "Rèférence"
+
110 #define D_STR_IRRECVDUMP_STARTUP \
+
111  "IRrecvDump fonctionne et attend l’entrée IR sur la broche %d"
+
112 #define D_WARN_BUFFERFULL \
+
113  "ATTENTION: IR Code est trop gros pour le buffer (>= %d). " \
+
114  "Le résultat ne doit pas être approuvé avant que cela soit résolu. " \
+
115  "Modifier et agrandir `kCaptureBufferSize`."
+
116 
+
117 #endif // LOCALE_FR_FR_H_
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions.html new file mode 100644 index 000000000..8c1ce9777 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions.html @@ -0,0 +1,262 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- _ -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_a.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_a.html new file mode 100644 index 000000000..6b205ec13 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_a.html @@ -0,0 +1,90 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- a -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_b.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_b.html new file mode 100644 index 000000000..f6295fb16 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_b.html @@ -0,0 +1,142 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- b -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_c.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_c.html new file mode 100644 index 000000000..399846159 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_c.html @@ -0,0 +1,377 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- c -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_d.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_d.html new file mode 100644 index 000000000..d430dbd7d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_d.html @@ -0,0 +1,360 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- d -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_e.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_e.html new file mode 100644 index 000000000..111809dc6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_e.html @@ -0,0 +1,153 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- e -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_f.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_f.html new file mode 100644 index 000000000..2987a747c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_f.html @@ -0,0 +1,98 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- f -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func.html new file mode 100644 index 000000000..03a682390 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func.html @@ -0,0 +1,121 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- _ -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_a.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_a.html new file mode 100644 index 000000000..f9827ebb4 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_a.html @@ -0,0 +1,86 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- a -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_b.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_b.html new file mode 100644 index 000000000..7d6b5234b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_b.html @@ -0,0 +1,130 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ + + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_c.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_c.html new file mode 100644 index 000000000..7f83216f8 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_c.html @@ -0,0 +1,356 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- c -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_d.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_d.html new file mode 100644 index 000000000..9795c7095 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_d.html @@ -0,0 +1,351 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- d -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_e.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_e.html new file mode 100644 index 000000000..bd4c8e138 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_e.html @@ -0,0 +1,150 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- e -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_f.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_f.html new file mode 100644 index 000000000..5a3c52eb6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_f.html @@ -0,0 +1,89 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- f -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_g.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_g.html new file mode 100644 index 000000000..96cde27c8 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_g.html @@ -0,0 +1,777 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- g -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_h.html new file mode 100644 index 000000000..eac317665 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_h.html @@ -0,0 +1,106 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- h -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_i.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_i.html new file mode 100644 index 000000000..67add7234 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_i.html @@ -0,0 +1,258 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- i -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_k.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_k.html new file mode 100644 index 000000000..4d4c3a736 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_k.html @@ -0,0 +1,79 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- k -

    +
  • kelvinator() +: IRac +
  • +
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_l.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_l.html new file mode 100644 index 000000000..c29455324 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_l.html @@ -0,0 +1,85 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- l -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_m.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_m.html new file mode 100644 index 000000000..fb1e3e368 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_m.html @@ -0,0 +1,133 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- m -

    +
  • mark() +: IRsend +
  • +
  • markAsSent() +: IRac +
  • +
  • match() +: IRrecv +
  • +
  • matchAtLeast() +: IRrecv +
  • +
  • matchBytes() +: IRrecv +
  • +
  • matchData() +: IRrecv +
  • +
  • matchGeneric() +: IRrecv +
  • +
  • matchGenericConstBitTime() +: IRrecv +
  • +
  • matchManchester() +: IRrecv +
  • +
  • matchManchesterData() +: IRrecv +
  • +
  • matchMark() +: IRrecv +
  • +
  • matchSpace() +: IRrecv +
  • +
  • midea() +: IRac +
  • +
  • minRepeats() +: IRsend +
  • +
  • mitsubishi() +: IRac +
  • +
  • mitsubishi112() +: IRac +
  • +
  • mitsubishi136() +: IRac +
  • +
  • mitsubishiHeavy152() +: IRac +
  • +
  • mitsubishiHeavy88() +: IRac +
  • +
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_n.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_n.html new file mode 100644 index 000000000..1ed8fdb21 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_n.html @@ -0,0 +1,79 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- n -

    +
  • neoclima() +: IRac +
  • +
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_o.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_o.html new file mode 100644 index 000000000..98b0c7c35 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_o.html @@ -0,0 +1,157 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ + + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_p.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_p.html new file mode 100644 index 000000000..fb659551b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_p.html @@ -0,0 +1,79 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- p -

    +
  • panasonic() +: IRac +
  • +
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_r.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_r.html new file mode 100644 index 000000000..ba2940aba --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_r.html @@ -0,0 +1,86 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- r -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_s.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_s.html new file mode 100644 index 000000000..b94617c0c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_s.html @@ -0,0 +1,1156 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- s -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_t.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_t.html new file mode 100644 index 000000000..19764a1f2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_t.html @@ -0,0 +1,297 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- t -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_u.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_u.html new file mode 100644 index 000000000..eb9d2cbfa --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_u.html @@ -0,0 +1,79 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- u -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_v.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_v.html new file mode 100644 index 000000000..5c3693e4f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_v.html @@ -0,0 +1,119 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ + + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_w.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_w.html new file mode 100644 index 000000000..863296b9e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_w.html @@ -0,0 +1,79 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- w -

    +
  • whirlpool() +: IRac +
  • +
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_~.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_~.html new file mode 100644 index 000000000..be24e6f9f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_func_~.html @@ -0,0 +1,79 @@ + + + + + + + +IRremoteESP8266: Class Members - Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- ~ -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_g.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_g.html new file mode 100644 index 000000000..d62a98dee --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_g.html @@ -0,0 +1,777 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- g -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_h.html new file mode 100644 index 000000000..327b474a4 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_h.html @@ -0,0 +1,109 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- h -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_i.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_i.html new file mode 100644 index 000000000..fa40ebe60 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_i.html @@ -0,0 +1,265 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- i -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_k.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_k.html new file mode 100644 index 000000000..d234e9b83 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_k.html @@ -0,0 +1,79 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- k -

    +
  • kelvinator() +: IRac +
  • +
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_l.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_l.html new file mode 100644 index 000000000..e97cda96f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_l.html @@ -0,0 +1,97 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- l -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_m.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_m.html new file mode 100644 index 000000000..7a5beaee5 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_m.html @@ -0,0 +1,148 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- m -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_n.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_n.html new file mode 100644 index 000000000..76f6bd78a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_n.html @@ -0,0 +1,82 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- n -

    +
  • neoclima() +: IRac +
  • +
  • next +: IRac +
  • +
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_o.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_o.html new file mode 100644 index 000000000..59c01849d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_o.html @@ -0,0 +1,173 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ + + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_p.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_p.html new file mode 100644 index 000000000..d52453d58 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_p.html @@ -0,0 +1,94 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- p -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_q.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_q.html new file mode 100644 index 000000000..82dc51deb --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_q.html @@ -0,0 +1,79 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- q -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_r.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_r.html new file mode 100644 index 000000000..ede8716ba --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_r.html @@ -0,0 +1,151 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- r -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_rela.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_rela.html new file mode 100644 index 000000000..568f1564c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_rela.html @@ -0,0 +1,77 @@ + + + + + + + +IRremoteESP8266: Class Members - Related Functions + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_s.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_s.html new file mode 100644 index 000000000..91e9f3159 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_s.html @@ -0,0 +1,1193 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- s -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_t.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_t.html new file mode 100644 index 000000000..64393dccc --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_t.html @@ -0,0 +1,309 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- t -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_u.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_u.html new file mode 100644 index 000000000..aeda54c2d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_u.html @@ -0,0 +1,85 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- u -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_v.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_v.html new file mode 100644 index 000000000..3ef7c39c6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_v.html @@ -0,0 +1,122 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- v -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars.html new file mode 100644 index 000000000..1eb24f7c7 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars.html @@ -0,0 +1,563 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- _ -

+ + +

- a -

+ + +

- b -

+ + +

- c -

+ + +

- d -

+ + +

- e -

+ + +

- f -

+ + +

- h -

+ + +

- i -

+ + +

- l -

+ + +

- m -

+ + +

- n -

+ + +

- o -

+ + +

- p -

+ + +

- q -

+ + +

- r -

+ + +

- s -

+ + +

- t -

+ + +

- u -

+ + +

- v -

+ + +

- w -

+ + +

- z -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_a.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_a.html new file mode 100644 index 000000000..420e56269 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_a.html @@ -0,0 +1,82 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- a -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_b.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_b.html new file mode 100644 index 000000000..0a3196ab1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_b.html @@ -0,0 +1,88 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- b -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_c.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_c.html new file mode 100644 index 000000000..2def7a087 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_c.html @@ -0,0 +1,97 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- c -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_d.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_d.html new file mode 100644 index 000000000..9a9ddc836 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_d.html @@ -0,0 +1,85 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- d -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_e.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_e.html new file mode 100644 index 000000000..0cab373d2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_e.html @@ -0,0 +1,79 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- e -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_f.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_f.html new file mode 100644 index 000000000..a53f124b0 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_f.html @@ -0,0 +1,85 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- f -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_h.html new file mode 100644 index 000000000..d365bf7e4 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_h.html @@ -0,0 +1,79 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- h -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_i.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_i.html new file mode 100644 index 000000000..000576cfe --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_i.html @@ -0,0 +1,82 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- i -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_l.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_l.html new file mode 100644 index 000000000..a8027a466 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_l.html @@ -0,0 +1,88 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- l -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_m.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_m.html new file mode 100644 index 000000000..2959960d3 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_m.html @@ -0,0 +1,91 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- m -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_n.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_n.html new file mode 100644 index 000000000..598b08dd6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_n.html @@ -0,0 +1,79 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- n -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_o.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_o.html new file mode 100644 index 000000000..82097786b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_o.html @@ -0,0 +1,92 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- o -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_p.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_p.html new file mode 100644 index 000000000..997a6d00c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_p.html @@ -0,0 +1,91 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- p -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_q.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_q.html new file mode 100644 index 000000000..21d49182e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_q.html @@ -0,0 +1,79 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- q -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_r.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_r.html new file mode 100644 index 000000000..8a7baf613 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_r.html @@ -0,0 +1,140 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ + + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_s.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_s.html new file mode 100644 index 000000000..0518f87fc --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_s.html @@ -0,0 +1,113 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- s -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_t.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_t.html new file mode 100644 index 000000000..2ed112f2c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_t.html @@ -0,0 +1,88 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- t -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_u.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_u.html new file mode 100644 index 000000000..a52e0c8a4 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_u.html @@ -0,0 +1,82 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- u -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_v.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_v.html new file mode 100644 index 000000000..094dd4c27 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_v.html @@ -0,0 +1,79 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- v -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_w.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_w.html new file mode 100644 index 000000000..9da5476dd --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_w.html @@ -0,0 +1,79 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- w -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_z.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_z.html new file mode 100644 index 000000000..a3501487e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_vars_z.html @@ -0,0 +1,79 @@ + + + + + + + +IRremoteESP8266: Class Members - Variables + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- z -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_w.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_w.html new file mode 100644 index 000000000..efd7bd622 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_w.html @@ -0,0 +1,82 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- w -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_z.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_z.html new file mode 100644 index 000000000..2b16d459f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_z.html @@ -0,0 +1,79 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- z -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_~.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_~.html new file mode 100644 index 000000000..dc46b16b7 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/functions_~.html @@ -0,0 +1,79 @@ + + + + + + + +IRremoteESP8266: Class Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all class members with links to the classes they belong to:
+ +

- ~ -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals.html new file mode 100644 index 000000000..7ea1c71d3 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals.html @@ -0,0 +1,82 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- _ -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_a.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_a.html new file mode 100644 index 000000000..ae8115d60 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_a.html @@ -0,0 +1,106 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- a -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_c.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_c.html new file mode 100644 index 000000000..121baa0db --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_c.html @@ -0,0 +1,100 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- c -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_d.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_d.html new file mode 100644 index 000000000..34d34bc20 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_d.html @@ -0,0 +1,121 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- d -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_e.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_e.html new file mode 100644 index 000000000..d7bb8acf2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_e.html @@ -0,0 +1,82 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- e -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_enum.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_enum.html new file mode 100644 index 000000000..2b3c7b53b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_enum.html @@ -0,0 +1,95 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_eval.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_eval.html new file mode 100644 index 000000000..41fffa21e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_eval.html @@ -0,0 +1,493 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- a -

+ + +

- c -

+ + +

- d -

+ + +

- e -

+ + +

- f -

+ + +

- g -

+ + +

- h -

+ + +

- i -

+ + +

- j -

+ + +

- k -

+ + +

- l -

+ + +

- m -

+ + +

- n -

+ + +

- p -

+ + +

- r -

+ + +

- s -

+ + +

- t -

+ + +

- u -

+ + +

- v -

+ + +

- w -

+ + +

- y -

+ + +

- z -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_f.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_f.html new file mode 100644 index 000000000..d57b47a26 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_f.html @@ -0,0 +1,86 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- f -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_func.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_func.html new file mode 100644 index 000000000..1d31640cb --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_func.html @@ -0,0 +1,184 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- c -

+ + +

- f -

+ + +

- g -

+ + +

- h -

+ + +

- i -

+ + +

- r -

+ + +

- s -

+ + +

- t -

+ + +

- u -

+ + +

- x -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_g.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_g.html new file mode 100644 index 000000000..27ae53537 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_g.html @@ -0,0 +1,98 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- g -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_h.html new file mode 100644 index 000000000..fb077717b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_h.html @@ -0,0 +1,107 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- h -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_i.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_i.html new file mode 100644 index 000000000..4a0b8d8b6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_i.html @@ -0,0 +1,92 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- i -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_j.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_j.html new file mode 100644 index 000000000..7c90ed62d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_j.html @@ -0,0 +1,79 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- j -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_k.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_k.html new file mode 100644 index 000000000..a84fe0e7f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_k.html @@ -0,0 +1,7825 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- k -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_l.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_l.html new file mode 100644 index 000000000..7e56f59c1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_l.html @@ -0,0 +1,94 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- l -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_m.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_m.html new file mode 100644 index 000000000..57d34e5a0 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_m.html @@ -0,0 +1,112 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- m -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_n.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_n.html new file mode 100644 index 000000000..715ffa0f0 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_n.html @@ -0,0 +1,88 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- n -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_p.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_p.html new file mode 100644 index 000000000..e3df36e7f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_p.html @@ -0,0 +1,91 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- p -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_r.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_r.html new file mode 100644 index 000000000..7d4e405db --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_r.html @@ -0,0 +1,121 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- r -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_s.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_s.html new file mode 100644 index 000000000..78989d651 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_s.html @@ -0,0 +1,124 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- s -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_t.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_t.html new file mode 100644 index 000000000..8c16fa974 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_t.html @@ -0,0 +1,92 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- t -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_type.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_type.html new file mode 100644 index 000000000..5f3e05a75 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_type.html @@ -0,0 +1,77 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_u.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_u.html new file mode 100644 index 000000000..860d132a7 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_u.html @@ -0,0 +1,86 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- u -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_v.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_v.html new file mode 100644 index 000000000..5adfbfdf9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_v.html @@ -0,0 +1,79 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- v -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_vars.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_vars.html new file mode 100644 index 000000000..4db0b55aa --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_vars.html @@ -0,0 +1,82 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- _ -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_vars_i.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_vars_i.html new file mode 100644 index 000000000..47c235016 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_vars_i.html @@ -0,0 +1,85 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- i -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_vars_k.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_vars_k.html new file mode 100644 index 000000000..48f17baeb --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_vars_k.html @@ -0,0 +1,7798 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+  + +

- k -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_w.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_w.html new file mode 100644 index 000000000..5a333bf99 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_w.html @@ -0,0 +1,85 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- w -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_x.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_x.html new file mode 100644 index 000000000..714a73193 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_x.html @@ -0,0 +1,80 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- x -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_y.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_y.html new file mode 100644 index 000000000..f28dd18c0 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_y.html @@ -0,0 +1,82 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- y -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_z.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_z.html new file mode 100644 index 000000000..3a092ec10 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/globals_z.html @@ -0,0 +1,79 @@ + + + + + + + +IRremoteESP8266: File Members + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
Here is a list of all file members with links to the files they belong to:
+ +

- z -

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/graph_legend.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/graph_legend.html new file mode 100644 index 000000000..8a04ec5bb --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/graph_legend.html @@ -0,0 +1,136 @@ + + + + + + + +IRremoteESP8266: Graph Legend + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+
Graph Legend
+
+
+

This page explains how to interpret the graphs that are generated by doxygen.

+

Consider the following example:

/*! Invisible class because of truncation */
+
class Invisible { };
+
+
/*! Truncated class, inheritance relation is hidden */
+
class Truncated : public Invisible { };
+
+
/* Class not documented with doxygen comments */
+
class Undocumented { };
+
+
/*! Class that is inherited using public inheritance */
+
class PublicBase : public Truncated { };
+
+
/*! A template class */
+
template<class T> class Templ { };
+
+
/*! Class that is inherited using protected inheritance */
+
class ProtectedBase { };
+
+
/*! Class that is inherited using private inheritance */
+
class PrivateBase { };
+
+
/*! Class that is used by the Inherited class */
+
class Used { };
+
+
/*! Super class that inherits a number of other classes */
+
class Inherited : public PublicBase,
+
protected ProtectedBase,
+
private PrivateBase,
+
public Undocumented,
+
public Templ<int>
+
{
+
private:
+
Used *m_usedClass;
+
};
+

This will result in the following graph:

+

The boxes in the above graph have the following meaning:

+
    +
  • +A filled gray box represents the struct or class for which the graph is generated.
  • +
  • +A box with a black border denotes a documented struct or class.
  • +
  • +A box with a gray border denotes an undocumented struct or class.
  • +
  • +A box with a red border denotes a documented struct or class forwhich not all inheritance/containment relations are shown. A graph is truncated if it does not fit within the specified boundaries.
  • +
+

The arrows have the following meaning:

+
    +
  • +A dark blue arrow is used to visualize a public inheritance relation between two classes.
  • +
  • +A dark green arrow is used for protected inheritance.
  • +
  • +A dark red arrow is used for private inheritance.
  • +
  • +A purple dashed arrow is used if a class is contained or used by another class. The arrow is labelled with the variable(s) through which the pointed class or struct is accessible.
  • +
  • +A yellow dashed arrow denotes a relation between a template instance and the template class it was instantiated from. The arrow is labelled with the template parameters of the instance.
  • +
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/graph_legend.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/graph_legend.md5 new file mode 100644 index 000000000..8fcdccd1b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/graph_legend.md5 @@ -0,0 +1 @@ +f51bf6e9a10430aafef59831b08dcbfe \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/graph_legend.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/graph_legend.png new file mode 100644 index 000000000..7e2cbcfb2 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/graph_legend.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/hierarchy.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/hierarchy.html new file mode 100644 index 000000000..225996d27 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/hierarchy.html @@ -0,0 +1,135 @@ + + + + + + + +IRremoteESP8266: Class Hierarchy + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+
Class Hierarchy
+
+
+
+

Go to the graphical class hierarchy

+This inheritance list is sorted roughly, but not completely, alphabetically:
+
[detail level 12]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 Cdecode_resultsResults returned from the decoder
 CIRac
 CIRAmcorAcClass for handling detailed Amcor A/C messages
 CIRArgoACClass for handling detailed Argo A/C messages
 CIRCarrierAc64Class for handling detailed Carrier 64 bit A/C messages
 CIRCoolixACClass for handling detailed Coolix A/C messages
 CIRCoronaAcClass for handling detailed Corona A/C messages
 CIRDaikin128Class for handling detailed Daikin 128-bit A/C messages. Code by crankyoldgit. Analysis by Daniel Vena
 CIRDaikin152Class for handling detailed Daikin 152-bit A/C messages
 CIRDaikin160Class for handling detailed Daikin 160-bit A/C messages
 CIRDaikin176Class for handling detailed Daikin 176-bit A/C messages
 CIRDaikin2Class for handling detailed Daikin 312-bit A/C messages. Code by crankyoldgit, Reverse engineering analysis by sheppy99
 CIRDaikin216Class for handling detailed Daikin 216-bit A/C messages
 CIRDaikin64Class for handling detailed Daikin 64-bit A/C messages
 CIRDaikinESPClass for handling detailed Daikin 280-bit A/C messages
 CIRDelonghiAcClass for handling detailed Delonghi A/C messages
 CIRElectraAcClass for handling detailed Electra A/C messages
 CIRFujitsuACClass for handling detailed Fujitsu A/C messages
 CIRGoodweatherAcClass for handling detailed Goodweather A/C messages
 CIRGreeACClass for handling detailed Gree A/C messages
 CIRHaierACClass for handling detailed Haier A/C messages
 CIRHaierACYRW02Class for handling detailed Haier ACYRW02 A/C messages
 CIRHitachiAcClass for handling detailed Hitachi 224-bit A/C messages
 CIRHitachiAc1Class for handling detailed Hitachi 104-bit A/C messages
 CIRHitachiAc3Class for handling detailed Hitachi 15to27-byte/120to216-bit A/C messages
 CIRHitachiAc424Class for handling detailed Hitachi 53-byte/424-bit A/C messages
 CIRHitachiAc344Class for handling detailed Hitachi 344-bit A/C messages
 CIRKelvinatorACClass for handling detailed Kelvinator A/C messages
 CIRLgAcClass for handling detailed LG A/C messages
 CIRMideaACClass for handling detailed Midea A/C messages
 CIRMitsubishi112
 CIRMitsubishi136Class for handling detailed Mitsubishi 136-bit A/C messages
 CIRMitsubishiACClass for handling detailed Mitsubishi 144-bit A/C messages. Inspired and derived from the work done at: https://github.com/r45635/HVAC-IR-Control
 CIRMitsubishiHeavy152AcClass for handling detailed Mitsubishi Heavy 152-bit A/C messages
 CIRMitsubishiHeavy88AcClass for handling detailed Mitsubishi Heavy 88-bit A/C messages
 CIRNeoclimaAcClass for handling detailed Neoclima A/C messages
 CIRPanasonicAcClass for handling detailed Panasonic A/C messages
 Cirparams_tInformation for the interrupt handler
 CIRrecvClass for receiving IR messages
 CIRSamsungAcClass for handling detailed Samsung A/C messages
 CIRsendClass for sending all basic IR protocols
 CIRSharpAcClass for handling detailed Sharp A/C messages
 CIRTcl112AcClass for handling detailed TCL A/C messages
 CIRTecoAcClass for handling detailed Teco A/C messages
 CIRtimerThis class performs a simple timer in useconds since instantiated
 CIRToshibaACClass for handling detailed Toshiba A/C messages
 CIRTrotecESPClass for handling detailed Trotec A/C messages
 CIRVestelAcClass for handling detailed Vestel A/C messages
 CIRWhirlpoolAcClass for handling detailed Whirlpool A/C messages
 CmagiquestMagiQuest packet is both Wand ID and magnitude of swish and flick
 Cmatch_result_tResults from a data match
 CstdAc::state_tStructure to hold a common A/C state
 CTimerMsThis class performs a simple timer in milli-seoncds since instantiated
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/i18n_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/i18n_8h.html new file mode 100644 index 000000000..74c2dc9e0 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/i18n_8h.html @@ -0,0 +1,82 @@ + + + + + + + +IRremoteESP8266: src/i18n.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
i18n.h File Reference
+
+ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/i18n_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/i18n_8h_source.html new file mode 100644 index 000000000..d0ee17951 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/i18n_8h_source.html @@ -0,0 +1,107 @@ + + + + + + + +IRremoteESP8266: src/i18n.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
i18n.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 - David Conran (@crankyoldgit)
+
2 
+
3 #ifndef I18N_H_
+
4 #define I18N_H_
+
5 
+
6 #include "IRremoteESP8266.h"
+
7 
+
8 // Load the appropriate locale header file.
+
9 #ifndef _IR_LOCALE_
+
10 #define _IR_LOCALE_ en-AU
+
11 #endif // _IR_LOCALE_
+
12 
+
13 #define ENQUOTE_(x) #x
+
14 #define ENQUOTE(x) ENQUOTE_(x)
+
15 
+
16 // Load the desired/requested locale.
+
17 #ifdef _IR_LOCALE_
+
18 #include ENQUOTE(locale/_IR_LOCALE_.h)
+
19 #endif // _IR_LOCALE_
+
20 
+
21 // Now that any specific locale has been loaded, we can safely load the defaults
+
22 // as the defaults should not override anything that has now set.
+
23 #include "locale/defaults.h"
+
24 
+
25 #endif // I18N_H_
+
+ + + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/index.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/index.html new file mode 100644 index 000000000..42934a359 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/index.html @@ -0,0 +1,104 @@ + + + + + + + +IRremoteESP8266: IRremoteESP8266 Library API Documentation + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+
IRremoteESP8266 Library API Documentation
+
+
+

+Getting Started

+

+The basics

+

For sending messages, look at the IRsend class.

+

For receiving messages, look at the IRrecv & decode_results classes.

+

+Air Conditioners

+

For generic Air Conditioner control, look at the IRac class & the stdAc::state_t structure.

+

For detailed Air Conditioner control, you need to determine what protocol the library detects your remote/Air Conditioner to be, look into the appropriate src/ir_Protocol.[h|cpp] files and use the appropriate class object. e.g. if IRrecvDumpV2 (or better) detects the protocol as KELVINATOR, open the src/ir_Kelvinator.* files, and examine the IRKelvinatorAC class the methods available to create/decode/send KELVINATOR messages with all the abilities the library offers. You can also select it from the Classes menu above.

+

Various native constants & options for a given Protocol's class object can be found in the associated header file for that protocol.

+

+Examples

+

Most of the common uses of this library's APIs have demonstration code available under the examples directory. It ranges from trivial examples to complex real-world project code.

+

+Tuning

+

The most commonly used & needed knobs for controlling aspects of this library are available via run-time class methods or at class-object instantiation. Again, you are referred to the IRsend & IRrecv classes.

+

+Advanced

+

Certain addition constants and options are available as compile-time tweaks. You should inspect IRremoteESP8266.h, IRsend.h, & IRrecv.h for General, Sending, & Receiving tweaks respectively.

+

+Protocol timings

+

Generally you should never need to adjust the timing parameters for a given protocol or device. However, occasionally some individual devices just want to be special. If you are having problems decoding/receiving a message, look into the tolerance, kTolerance, or IRrecv::setTolerance constants/methods etc first. However, if your problems is sending, or adjusting the tolerance doesn't work you may need to tweak per-protocol timing values. These are stored as constants in the ir_ProtocolName.cpp file for the given protocol. This is typically a step of last resort.

+

+Reducing code size & flash usage.

+

You can disable most protocols by either modifying the appropriate #‍defines in IRremoteESP8266.h or passing the appropriate compile-time flags, as documented in the same file.

+

Avoid using the A/C classes, especially the IRac class as they will force the compiler to include large amounts of code you may not need.

+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_0.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_0.map new file mode 100644 index 000000000..a8b60bc08 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_0.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_0.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_0.md5 new file mode 100644 index 000000000..47dabebf8 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_0.md5 @@ -0,0 +1 @@ +a846ea81466572d0dcd38c89e164f553 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_0.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_0.png new file mode 100644 index 000000000..9b6798ac0 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_0.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_1.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_1.map new file mode 100644 index 000000000..e05cbf4b5 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_1.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_1.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_1.md5 new file mode 100644 index 000000000..bd11ebe19 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_1.md5 @@ -0,0 +1 @@ +327933a92eeebe9fdbbc6b40d5ab778a \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_1.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_1.png new file mode 100644 index 000000000..559fc0217 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_1.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_10.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_10.map new file mode 100644 index 000000000..3c6cfb9c1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_10.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_10.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_10.md5 new file mode 100644 index 000000000..18f33803c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_10.md5 @@ -0,0 +1 @@ +ef00148bc0f51868126f49db7c64045c \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_10.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_10.png new file mode 100644 index 000000000..1321a6dfd Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_10.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_11.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_11.map new file mode 100644 index 000000000..82841d494 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_11.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_11.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_11.md5 new file mode 100644 index 000000000..42c49f978 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_11.md5 @@ -0,0 +1 @@ +be983b2a61d65504f4b34c48e356ed36 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_11.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_11.png new file mode 100644 index 000000000..6fe436b03 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_11.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_12.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_12.map new file mode 100644 index 000000000..279bf8c7d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_12.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_12.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_12.md5 new file mode 100644 index 000000000..965dce765 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_12.md5 @@ -0,0 +1 @@ +4d7d1c5757d6d8c2ba1dee85111694e8 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_12.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_12.png new file mode 100644 index 000000000..e8860a43a Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_12.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_13.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_13.map new file mode 100644 index 000000000..89e9d4dd4 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_13.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_13.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_13.md5 new file mode 100644 index 000000000..ece2dd31c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_13.md5 @@ -0,0 +1 @@ +bac1b057abc6acdf006c520a2648695e \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_13.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_13.png new file mode 100644 index 000000000..29dd07a68 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_13.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_14.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_14.map new file mode 100644 index 000000000..72e272f5c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_14.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_14.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_14.md5 new file mode 100644 index 000000000..3857a757f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_14.md5 @@ -0,0 +1 @@ +beb2e4a39c2932d475766be916f606b6 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_14.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_14.png new file mode 100644 index 000000000..28f2cbc5c Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_14.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_15.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_15.map new file mode 100644 index 000000000..8cf71992a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_15.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_15.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_15.md5 new file mode 100644 index 000000000..02c096729 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_15.md5 @@ -0,0 +1 @@ +82db646c1e50878e4bc1d2d8e42f9084 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_15.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_15.png new file mode 100644 index 000000000..d952333e9 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_15.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_16.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_16.map new file mode 100644 index 000000000..79bd99c23 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_16.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_16.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_16.md5 new file mode 100644 index 000000000..c95f62f61 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_16.md5 @@ -0,0 +1 @@ +8f9d660abbc70be4c1cf621adf15df03 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_16.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_16.png new file mode 100644 index 000000000..e55a8da53 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_16.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_17.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_17.map new file mode 100644 index 000000000..a68b62f6b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_17.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_17.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_17.md5 new file mode 100644 index 000000000..e94efc85c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_17.md5 @@ -0,0 +1 @@ +8463fec8e273d2b003400f5fc52905d2 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_17.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_17.png new file mode 100644 index 000000000..24448b28b Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_17.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_18.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_18.map new file mode 100644 index 000000000..e933c51b4 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_18.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_18.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_18.md5 new file mode 100644 index 000000000..e976aad9e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_18.md5 @@ -0,0 +1 @@ +494470899dc7bc1f09771a91824eb25c \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_18.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_18.png new file mode 100644 index 000000000..aee74feca Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_18.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_19.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_19.map new file mode 100644 index 000000000..eabd6a84c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_19.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_19.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_19.md5 new file mode 100644 index 000000000..62bb81d6a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_19.md5 @@ -0,0 +1 @@ +ef1756185927c9dc031ac38fa0bd7314 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_19.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_19.png new file mode 100644 index 000000000..d0bd0654f Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_19.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_2.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_2.map new file mode 100644 index 000000000..59f2bf9e0 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_2.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_2.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_2.md5 new file mode 100644 index 000000000..7f14e3836 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_2.md5 @@ -0,0 +1 @@ +fd77e92eb539b07b298ba28c872ed33a \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_2.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_2.png new file mode 100644 index 000000000..f6da0e6ff Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_2.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_20.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_20.map new file mode 100644 index 000000000..4c3c9cad8 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_20.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_20.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_20.md5 new file mode 100644 index 000000000..43f0e4cbd --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_20.md5 @@ -0,0 +1 @@ +b7a5f99a38a961494782496866818bd7 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_20.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_20.png new file mode 100644 index 000000000..fa378ff65 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_20.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_21.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_21.map new file mode 100644 index 000000000..4a6d7147d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_21.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_21.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_21.md5 new file mode 100644 index 000000000..1e63f137d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_21.md5 @@ -0,0 +1 @@ +1a4371fa075bf61e18fb4a59f6c1ee8b \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_21.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_21.png new file mode 100644 index 000000000..797a53002 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_21.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_22.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_22.map new file mode 100644 index 000000000..7ea07790c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_22.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_22.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_22.md5 new file mode 100644 index 000000000..865f0a8cc --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_22.md5 @@ -0,0 +1 @@ +8fe022190fb8b4af703989db74b3df09 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_22.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_22.png new file mode 100644 index 000000000..6d3377afe Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_22.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_23.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_23.map new file mode 100644 index 000000000..5c7828789 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_23.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_23.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_23.md5 new file mode 100644 index 000000000..84388b9e5 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_23.md5 @@ -0,0 +1 @@ +1cc4c4dcff122c327c69c3c13dedc3fa \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_23.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_23.png new file mode 100644 index 000000000..9dd34695a Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_23.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_24.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_24.map new file mode 100644 index 000000000..efdf67e75 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_24.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_24.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_24.md5 new file mode 100644 index 000000000..705c5ba93 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_24.md5 @@ -0,0 +1 @@ +8cd321ec10c446c399675698b2c22573 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_24.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_24.png new file mode 100644 index 000000000..407da8542 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_24.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_25.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_25.map new file mode 100644 index 000000000..d41d30f1c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_25.map @@ -0,0 +1,4 @@ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_25.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_25.md5 new file mode 100644 index 000000000..880e7c145 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_25.md5 @@ -0,0 +1 @@ +a08686bcc5f729a82c296a6cc288080f \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_25.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_25.png new file mode 100644 index 000000000..bc365a65d Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_25.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_26.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_26.map new file mode 100644 index 000000000..ae7dc8f2e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_26.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_26.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_26.md5 new file mode 100644 index 000000000..3ee74b3a2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_26.md5 @@ -0,0 +1 @@ +f936b6c8bdc58c028bb8933191b34c6c \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_26.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_26.png new file mode 100644 index 000000000..5db982d56 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_26.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_27.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_27.map new file mode 100644 index 000000000..975bb02bf --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_27.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_27.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_27.md5 new file mode 100644 index 000000000..04d962ad6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_27.md5 @@ -0,0 +1 @@ +87662e5ac3f382c4e9890e2f0c246809 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_27.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_27.png new file mode 100644 index 000000000..1ff0ee123 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_27.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_28.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_28.map new file mode 100644 index 000000000..e760517d6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_28.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_28.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_28.md5 new file mode 100644 index 000000000..1c90a6e8a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_28.md5 @@ -0,0 +1 @@ +ba89299cb349c224517905a60a70be44 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_28.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_28.png new file mode 100644 index 000000000..d6dfbd599 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_28.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_29.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_29.map new file mode 100644 index 000000000..15f5c0a89 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_29.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_29.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_29.md5 new file mode 100644 index 000000000..854d22bae --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_29.md5 @@ -0,0 +1 @@ +ad82d3480a6e94b8a6c77c6da65217a4 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_29.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_29.png new file mode 100644 index 000000000..e0006ac9d Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_29.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_3.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_3.map new file mode 100644 index 000000000..769988ee6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_3.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_3.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_3.md5 new file mode 100644 index 000000000..a26a3b99a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_3.md5 @@ -0,0 +1 @@ +c57cc0030c7d3a9e44b4f20708a8d83f \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_3.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_3.png new file mode 100644 index 000000000..e44e05dd8 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_3.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_30.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_30.map new file mode 100644 index 000000000..8756dabf2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_30.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_30.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_30.md5 new file mode 100644 index 000000000..cc64f617c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_30.md5 @@ -0,0 +1 @@ +388b2bb7b074fbc6b23cb65b17a2d52c \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_30.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_30.png new file mode 100644 index 000000000..00d80fd2a Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_30.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_31.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_31.map new file mode 100644 index 000000000..eb655359d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_31.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_31.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_31.md5 new file mode 100644 index 000000000..994f3c528 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_31.md5 @@ -0,0 +1 @@ +5a2b620ebe4a488c39b0491478c216ee \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_31.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_31.png new file mode 100644 index 000000000..9d2c7f009 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_31.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_32.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_32.map new file mode 100644 index 000000000..5e69d0b66 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_32.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_32.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_32.md5 new file mode 100644 index 000000000..f6848c29b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_32.md5 @@ -0,0 +1 @@ +a45b337701fd72c704017f44bd397e8d \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_32.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_32.png new file mode 100644 index 000000000..ef8c7f7b0 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_32.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_33.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_33.map new file mode 100644 index 000000000..55c3c5c8a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_33.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_33.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_33.md5 new file mode 100644 index 000000000..851893b9d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_33.md5 @@ -0,0 +1 @@ +189c2435c324f1057aaf97e832f8d5e8 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_33.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_33.png new file mode 100644 index 000000000..d094da528 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_33.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_34.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_34.map new file mode 100644 index 000000000..2668a5553 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_34.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_34.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_34.md5 new file mode 100644 index 000000000..4eda18e00 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_34.md5 @@ -0,0 +1 @@ +db104ffd0bed1c2b2b66be9a2d94884c \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_34.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_34.png new file mode 100644 index 000000000..842798e42 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_34.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_35.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_35.map new file mode 100644 index 000000000..acbf5c9c5 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_35.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_35.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_35.md5 new file mode 100644 index 000000000..5af67464a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_35.md5 @@ -0,0 +1 @@ +47e03bef0106d920f6df1a4650c42161 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_35.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_35.png new file mode 100644 index 000000000..356ddb54b Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_35.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_36.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_36.map new file mode 100644 index 000000000..e7394ad03 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_36.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_36.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_36.md5 new file mode 100644 index 000000000..629a81748 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_36.md5 @@ -0,0 +1 @@ +f161f3f640d27ec87610fe7e0258daa2 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_36.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_36.png new file mode 100644 index 000000000..14d655e7b Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_36.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_37.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_37.map new file mode 100644 index 000000000..d72919bc5 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_37.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_37.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_37.md5 new file mode 100644 index 000000000..6aec8ecfb --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_37.md5 @@ -0,0 +1 @@ +2ba122d741860d8a73f208c9d30316bb \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_37.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_37.png new file mode 100644 index 000000000..5c3154f57 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_37.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_38.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_38.map new file mode 100644 index 000000000..0bef81fa9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_38.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_38.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_38.md5 new file mode 100644 index 000000000..dbc1c97ac --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_38.md5 @@ -0,0 +1 @@ +094d47bf89b4692d513b3c18447ea38c \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_38.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_38.png new file mode 100644 index 000000000..58a4979bb Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_38.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_39.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_39.map new file mode 100644 index 000000000..2416b8ea9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_39.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_39.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_39.md5 new file mode 100644 index 000000000..569a1d5be --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_39.md5 @@ -0,0 +1 @@ +091acded027244d4f3129e0f10946f38 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_39.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_39.png new file mode 100644 index 000000000..c39529cd3 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_39.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_4.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_4.map new file mode 100644 index 000000000..26c2153e2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_4.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_4.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_4.md5 new file mode 100644 index 000000000..07028de7e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_4.md5 @@ -0,0 +1 @@ +d0bba657e71229bb0975d1d5e96b55e1 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_4.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_4.png new file mode 100644 index 000000000..ed97ecbf8 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_4.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_40.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_40.map new file mode 100644 index 000000000..548a598d9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_40.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_40.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_40.md5 new file mode 100644 index 000000000..655ca8cf2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_40.md5 @@ -0,0 +1 @@ +6be102575488e73fd84b8d956f0802b7 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_40.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_40.png new file mode 100644 index 000000000..8021f0771 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_40.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_41.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_41.map new file mode 100644 index 000000000..567ca90a3 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_41.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_41.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_41.md5 new file mode 100644 index 000000000..a60a6f7ec --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_41.md5 @@ -0,0 +1 @@ +513e53cdbd67e1c3be296e616b5088fe \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_41.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_41.png new file mode 100644 index 000000000..0b8afa3a5 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_41.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_42.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_42.map new file mode 100644 index 000000000..f53df572a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_42.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_42.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_42.md5 new file mode 100644 index 000000000..8d243e0ac --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_42.md5 @@ -0,0 +1 @@ +8496a1131f5933bedde7a327a5d4457d \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_42.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_42.png new file mode 100644 index 000000000..437f5dcc4 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_42.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_43.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_43.map new file mode 100644 index 000000000..7cf417931 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_43.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_43.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_43.md5 new file mode 100644 index 000000000..df2bca32a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_43.md5 @@ -0,0 +1 @@ +fbbd125722f48899a4de6646741795f2 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_43.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_43.png new file mode 100644 index 000000000..c3582874c Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_43.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_44.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_44.map new file mode 100644 index 000000000..543dea86a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_44.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_44.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_44.md5 new file mode 100644 index 000000000..280ca8256 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_44.md5 @@ -0,0 +1 @@ +0bd47951338d799baa7faad737d93c2f \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_44.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_44.png new file mode 100644 index 000000000..aa25f7705 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_44.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_45.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_45.map new file mode 100644 index 000000000..73d6c2f9d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_45.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_45.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_45.md5 new file mode 100644 index 000000000..bf09ae4c3 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_45.md5 @@ -0,0 +1 @@ +e2cd65da5815253bc9bf312036b6aaa3 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_45.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_45.png new file mode 100644 index 000000000..e34bb58b3 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_45.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_46.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_46.map new file mode 100644 index 000000000..93c7e61e4 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_46.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_46.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_46.md5 new file mode 100644 index 000000000..efe4879d6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_46.md5 @@ -0,0 +1 @@ +40c25360d6e911f460499817a1f66d2f \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_46.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_46.png new file mode 100644 index 000000000..ff087624b Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_46.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_47.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_47.map new file mode 100644 index 000000000..acdbbcaac --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_47.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_47.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_47.md5 new file mode 100644 index 000000000..a3fc301c1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_47.md5 @@ -0,0 +1 @@ +8e6e75ba5587c932001eae5a688a6d27 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_47.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_47.png new file mode 100644 index 000000000..7b3fc9762 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_47.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_48.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_48.map new file mode 100644 index 000000000..6206c6e84 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_48.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_48.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_48.md5 new file mode 100644 index 000000000..527fc865e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_48.md5 @@ -0,0 +1 @@ +912bf27b3c1ff508088dbbabcad26cef \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_48.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_48.png new file mode 100644 index 000000000..6d77adeec Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_48.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_49.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_49.map new file mode 100644 index 000000000..28a530cd0 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_49.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_49.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_49.md5 new file mode 100644 index 000000000..1371e210d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_49.md5 @@ -0,0 +1 @@ +8d39cd46dd30d6c731fd7374f101062f \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_49.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_49.png new file mode 100644 index 000000000..97cbab8ac Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_49.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_5.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_5.map new file mode 100644 index 000000000..09cc591e5 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_5.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_5.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_5.md5 new file mode 100644 index 000000000..6010a609d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_5.md5 @@ -0,0 +1 @@ +bc950b2a380edb2222e6039af29b1619 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_5.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_5.png new file mode 100644 index 000000000..716877088 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_5.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_50.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_50.map new file mode 100644 index 000000000..f49a88956 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_50.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_50.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_50.md5 new file mode 100644 index 000000000..30529d258 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_50.md5 @@ -0,0 +1 @@ +f1bcb75b933276ee5fde30f34c416529 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_50.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_50.png new file mode 100644 index 000000000..6d81796fb Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_50.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_51.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_51.map new file mode 100644 index 000000000..082401084 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_51.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_51.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_51.md5 new file mode 100644 index 000000000..5e164cba6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_51.md5 @@ -0,0 +1 @@ +636d74cd7d8543185699996922cb3512 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_51.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_51.png new file mode 100644 index 000000000..c156a9810 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_51.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_6.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_6.map new file mode 100644 index 000000000..078ab7b14 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_6.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_6.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_6.md5 new file mode 100644 index 000000000..06179feb6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_6.md5 @@ -0,0 +1 @@ +b8916d3b51e3fb200c11a55d0ce781f3 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_6.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_6.png new file mode 100644 index 000000000..ac6ff436a Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_6.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_7.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_7.map new file mode 100644 index 000000000..402f748ac --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_7.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_7.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_7.md5 new file mode 100644 index 000000000..3c6e51c78 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_7.md5 @@ -0,0 +1 @@ +8a2ff2afbd606f6ff99bf4a81ad27232 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_7.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_7.png new file mode 100644 index 000000000..cbf8e53c5 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_7.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_8.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_8.map new file mode 100644 index 000000000..62ae05dc9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_8.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_8.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_8.md5 new file mode 100644 index 000000000..d2ddcd27c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_8.md5 @@ -0,0 +1 @@ +e31d247ca830d0fbc9b398310b889137 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_8.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_8.png new file mode 100644 index 000000000..f2784a51c Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_8.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_9.map b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_9.map new file mode 100644 index 000000000..8eb29e24b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_9.map @@ -0,0 +1,3 @@ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_9.md5 b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_9.md5 new file mode 100644 index 000000000..cb1829bbb --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_9.md5 @@ -0,0 +1 @@ +e8d46fafad2734ff1ba6435e75760054 \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_9.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_9.png new file mode 100644 index 000000000..686145aac Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherit_graph_9.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherits.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherits.html new file mode 100644 index 000000000..e4a63a9ee --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/inherits.html @@ -0,0 +1,341 @@ + + + + + + + +IRremoteESP8266: Class Hierarchy + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + +
+ +
+
+ + +
+ +
+ +
+
+
Class Hierarchy
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Airwell_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Airwell_8cpp.html new file mode 100644 index 000000000..baf4b7576 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Airwell_8cpp.html @@ -0,0 +1,172 @@ + + + + + + + +IRremoteESP8266: src/ir_Airwell.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Airwell.cpp File Reference
+
+
+ +

Airwell "Manchester code" based protocol. Some other Airwell products use the COOLIX protocol. +More...

+ + + + + + + + + + + + +

+Variables

const uint8_t kAirwellOverhead = 4
 
const uint16_t kAirwellHalfClockPeriod = 950
 
const uint16_t kAirwellHdrMark = 3 * kAirwellHalfClockPeriod
 
const uint16_t kAirwellHdrSpace = 3 * kAirwellHalfClockPeriod
 
const uint16_t kAirwellFooterMark = 5 * kAirwellHalfClockPeriod
 
+

Detailed Description

+

Airwell "Manchester code" based protocol. Some other Airwell products use the COOLIX protocol.

+

Variable Documentation

+ +

◆ kAirwellFooterMark

+ +
+
+ + + + +
const uint16_t kAirwellFooterMark = 5 * kAirwellHalfClockPeriod
+
+ +
+
+ +

◆ kAirwellHalfClockPeriod

+ +
+
+ + + + +
const uint16_t kAirwellHalfClockPeriod = 950
+
+ +
+
+ +

◆ kAirwellHdrMark

+ +
+
+ + + + +
const uint16_t kAirwellHdrMark = 3 * kAirwellHalfClockPeriod
+
+ +
+
+ +

◆ kAirwellHdrSpace

+ +
+
+ + + + +
const uint16_t kAirwellHdrSpace = 3 * kAirwellHalfClockPeriod
+
+ +
+
+ +

◆ kAirwellOverhead

+ +
+
+ + + + +
const uint8_t kAirwellOverhead = 4
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Aiwa_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Aiwa_8cpp.html new file mode 100644 index 000000000..f5fd8eaba --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Aiwa_8cpp.html @@ -0,0 +1,157 @@ + + + + + + + +IRremoteESP8266: src/ir_Aiwa.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Aiwa.cpp File Reference
+
+
+ +

Aiwa based protocol. Based off the RC-T501 RCU Inspired by IRremoteESP8266's implementation. +More...

+ + + + + + + + + + +

+Variables

const uint16_t kAiwaRcT501PreBits = 26
 
const uint16_t kAiwaRcT501PostBits = 1
 
const uint64_t kAiwaRcT501PreData = 0x1D8113FULL
 
const uint64_t kAiwaRcT501PostData = 1ULL
 
+

Detailed Description

+

Aiwa based protocol. Based off the RC-T501 RCU Inspired by IRremoteESP8266's implementation.

+
See also
https://github.com/z3t0/Arduino-IRremote
+

Variable Documentation

+ +

◆ kAiwaRcT501PostBits

+ +
+
+ + + + +
const uint16_t kAiwaRcT501PostBits = 1
+
+ +
+
+ +

◆ kAiwaRcT501PostData

+ +
+
+ + + + +
const uint64_t kAiwaRcT501PostData = 1ULL
+
+ +
+
+ +

◆ kAiwaRcT501PreBits

+ +
+
+ + + + +
const uint16_t kAiwaRcT501PreBits = 26
+
+ +
+
+ +

◆ kAiwaRcT501PreData

+ +
+
+ + + + +
const uint64_t kAiwaRcT501PreData = 0x1D8113FULL
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Amcor_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Amcor_8cpp.html new file mode 100644 index 000000000..cf51c2624 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Amcor_8cpp.html @@ -0,0 +1,239 @@ + + + + + + + +IRremoteESP8266: src/ir_Amcor.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Amcor.cpp File Reference
+
+
+ +

Amcor A/C protocol. +More...

+ + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kAmcorHdrMark = 8200
 
const uint16_t kAmcorHdrSpace = 4200
 
const uint16_t kAmcorOneMark = 1500
 
const uint16_t kAmcorZeroMark = 600
 
const uint16_t kAmcorOneSpace = kAmcorZeroMark
 
const uint16_t kAmcorZeroSpace = kAmcorOneMark
 
const uint16_t kAmcorFooterMark = 1900
 
const uint16_t kAmcorGap = 34300
 
const uint8_t kAmcorTolerance = 40
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kAmcorFooterMark

+ +
+
+ + + + +
const uint16_t kAmcorFooterMark = 1900
+
+ +
+
+ +

◆ kAmcorGap

+ +
+
+ + + + +
const uint16_t kAmcorGap = 34300
+
+ +
+
+ +

◆ kAmcorHdrMark

+ +
+
+ + + + +
const uint16_t kAmcorHdrMark = 8200
+
+ +
+
+ +

◆ kAmcorHdrSpace

+ +
+
+ + + + +
const uint16_t kAmcorHdrSpace = 4200
+
+ +
+
+ +

◆ kAmcorOneMark

+ +
+
+ + + + +
const uint16_t kAmcorOneMark = 1500
+
+ +
+
+ +

◆ kAmcorOneSpace

+ +
+
+ + + + +
const uint16_t kAmcorOneSpace = kAmcorZeroMark
+
+ +
+
+ +

◆ kAmcorTolerance

+ +
+
+ + + + +
const uint8_t kAmcorTolerance = 40
+
+ +
+
+ +

◆ kAmcorZeroMark

+ +
+
+ + + + +
const uint16_t kAmcorZeroMark = 600
+
+ +
+
+ +

◆ kAmcorZeroSpace

+ +
+
+ + + + +
const uint16_t kAmcorZeroSpace = kAmcorOneMark
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Amcor_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Amcor_8h.html new file mode 100644 index 000000000..6ec44115a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Amcor_8h.html @@ -0,0 +1,615 @@ + + + + + + + +IRremoteESP8266: src/ir_Amcor.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Amcor.h File Reference
+
+
+ +

Amcor A/C protocol. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRAmcorAc
 Class for handling detailed Amcor A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kAmcorModeFanByte = 1
 
const uint8_t kAmcorFanMin = 0b001
 
const uint8_t kAmcorFanMed = 0b010
 
const uint8_t kAmcorFanMax = 0b011
 
const uint8_t kAmcorFanAuto = 0b100
 
const uint8_t kAmcorFanOffset = 4
 
const uint8_t kAmcorFanSize = 3
 
const uint8_t kAmcorCool = 0b001
 
const uint8_t kAmcorHeat = 0b010
 
const uint8_t kAmcorFan = 0b011
 
const uint8_t kAmcorDry = 0b100
 
const uint8_t kAmcorAuto = 0b101
 
const uint8_t kAmcorModeOffset = 0
 
const uint8_t kAmcorModeSize = 3
 
const uint8_t kAmcorTempByte = 2
 
const uint8_t kAmcorMinTemp = 12
 
const uint8_t kAmcorMaxTemp = 32
 
const uint8_t kAmcorTempOffset = 1
 
const uint8_t kAmcorTempSize = 6
 
const uint8_t kAmcorPowerByte = 5
 
const uint8_t kAmcorPowerOffset = 4
 
const uint8_t kAmcorPowerSize = 4
 
const uint8_t kAmcorPowerOn = 0b0011
 
const uint8_t kAmcorPowerOff = 0b1100
 
const uint8_t kAmcorSpecialByte = 6
 
const uint8_t kAmcorMax = 0b11
 
const uint8_t kAmcorMaxOffset = 0
 
const uint8_t kAmcorMaxSize = 2
 
const uint8_t kAmcorVentOn = 0b11
 
const uint8_t kAmcorVentOffset = 6
 
const uint8_t kAmcorVentSize = 2
 
const uint8_t kAmcorChecksumByte = kAmcorStateLength - 1
 
+

Detailed Description

+

Amcor A/C protocol.

+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/834
+
Remarks
Kudos to ldellus; For the breakdown and mapping of the bit values.
+

Variable Documentation

+ +

◆ kAmcorAuto

+ +
+
+ + + + +
const uint8_t kAmcorAuto = 0b101
+
+ +
+
+ +

◆ kAmcorChecksumByte

+ +
+
+ + + + +
const uint8_t kAmcorChecksumByte = kAmcorStateLength - 1
+
+ +
+
+ +

◆ kAmcorCool

+ +
+
+ + + + +
const uint8_t kAmcorCool = 0b001
+
+ +
+
+ +

◆ kAmcorDry

+ +
+
+ + + + +
const uint8_t kAmcorDry = 0b100
+
+ +
+
+ +

◆ kAmcorFan

+ +
+
+ + + + +
const uint8_t kAmcorFan = 0b011
+
+ +
+
+ +

◆ kAmcorFanAuto

+ +
+
+ + + + +
const uint8_t kAmcorFanAuto = 0b100
+
+ +
+
+ +

◆ kAmcorFanMax

+ +
+
+ + + + +
const uint8_t kAmcorFanMax = 0b011
+
+ +
+
+ +

◆ kAmcorFanMed

+ +
+
+ + + + +
const uint8_t kAmcorFanMed = 0b010
+
+ +
+
+ +

◆ kAmcorFanMin

+ +
+
+ + + + +
const uint8_t kAmcorFanMin = 0b001
+
+ +
+
+ +

◆ kAmcorFanOffset

+ +
+
+ + + + +
const uint8_t kAmcorFanOffset = 4
+
+ +
+
+ +

◆ kAmcorFanSize

+ +
+
+ + + + +
const uint8_t kAmcorFanSize = 3
+
+ +
+
+ +

◆ kAmcorHeat

+ +
+
+ + + + +
const uint8_t kAmcorHeat = 0b010
+
+ +
+
+ +

◆ kAmcorMax

+ +
+
+ + + + +
const uint8_t kAmcorMax = 0b11
+
+ +
+
+ +

◆ kAmcorMaxOffset

+ +
+
+ + + + +
const uint8_t kAmcorMaxOffset = 0
+
+ +
+
+ +

◆ kAmcorMaxSize

+ +
+
+ + + + +
const uint8_t kAmcorMaxSize = 2
+
+ +
+
+ +

◆ kAmcorMaxTemp

+ +
+
+ + + + +
const uint8_t kAmcorMaxTemp = 32
+
+ +
+
+ +

◆ kAmcorMinTemp

+ +
+
+ + + + +
const uint8_t kAmcorMinTemp = 12
+
+ +
+
+ +

◆ kAmcorModeFanByte

+ +
+
+ + + + +
const uint8_t kAmcorModeFanByte = 1
+
+ +
+
+ +

◆ kAmcorModeOffset

+ +
+
+ + + + +
const uint8_t kAmcorModeOffset = 0
+
+ +
+
+ +

◆ kAmcorModeSize

+ +
+
+ + + + +
const uint8_t kAmcorModeSize = 3
+
+ +
+
+ +

◆ kAmcorPowerByte

+ +
+
+ + + + +
const uint8_t kAmcorPowerByte = 5
+
+ +
+
+ +

◆ kAmcorPowerOff

+ +
+
+ + + + +
const uint8_t kAmcorPowerOff = 0b1100
+
+ +
+
+ +

◆ kAmcorPowerOffset

+ +
+
+ + + + +
const uint8_t kAmcorPowerOffset = 4
+
+ +
+
+ +

◆ kAmcorPowerOn

+ +
+
+ + + + +
const uint8_t kAmcorPowerOn = 0b0011
+
+ +
+
+ +

◆ kAmcorPowerSize

+ +
+
+ + + + +
const uint8_t kAmcorPowerSize = 4
+
+ +
+
+ +

◆ kAmcorSpecialByte

+ +
+
+ + + + +
const uint8_t kAmcorSpecialByte = 6
+
+ +
+
+ +

◆ kAmcorTempByte

+ +
+
+ + + + +
const uint8_t kAmcorTempByte = 2
+
+ +
+
+ +

◆ kAmcorTempOffset

+ +
+
+ + + + +
const uint8_t kAmcorTempOffset = 1
+
+ +
+
+ +

◆ kAmcorTempSize

+ +
+
+ + + + +
const uint8_t kAmcorTempSize = 6
+
+ +
+
+ +

◆ kAmcorVentOffset

+ +
+
+ + + + +
const uint8_t kAmcorVentOffset = 6
+
+ +
+
+ +

◆ kAmcorVentOn

+ +
+
+ + + + +
const uint8_t kAmcorVentOn = 0b11
+
+ +
+
+ +

◆ kAmcorVentSize

+ +
+
+ + + + +
const uint8_t kAmcorVentSize = 2
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Amcor_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Amcor_8h_source.html new file mode 100644 index 000000000..6bf1b93e7 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Amcor_8h_source.html @@ -0,0 +1,274 @@ + + + + + + + +IRremoteESP8266: src/ir_Amcor.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Amcor.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 David Conran
+
2 
+
7 // Supports:
+
8 // Brand: Amcor, Model: ADR-853H A/C
+
9 // Brand: Amcor, Model: TAC-495 remote
+
10 // Brand: Amcor, Model: TAC-444 remote
+
11 
+
12 #ifndef IR_AMCOR_H_
+
13 #define IR_AMCOR_H_
+
14 
+
15 #define __STDC_LIMIT_MACROS
+
16 #include <stdint.h>
+
17 #ifndef UNIT_TEST
+
18 #include <Arduino.h>
+
19 #endif
+
20 #include "IRremoteESP8266.h"
+
21 #include "IRsend.h"
+
22 #ifdef UNIT_TEST
+
23 #include "IRsend_test.h"
+
24 #endif
+
25 
+
26 
+
27 // Constants
+
28 
+
29 // state[1]
+
30 const uint8_t kAmcorModeFanByte = 1;
+
31 // Fan Control
+
32 const uint8_t kAmcorFanMin = 0b001;
+
33 const uint8_t kAmcorFanMed = 0b010;
+
34 const uint8_t kAmcorFanMax = 0b011;
+
35 const uint8_t kAmcorFanAuto = 0b100;
+
36 const uint8_t kAmcorFanOffset = 4;
+
37 const uint8_t kAmcorFanSize = 3;
+
38 // Modes
+
39 const uint8_t kAmcorCool = 0b001;
+
40 const uint8_t kAmcorHeat = 0b010;
+
41 const uint8_t kAmcorFan = 0b011; // Aka "Vent"
+
42 const uint8_t kAmcorDry = 0b100;
+
43 const uint8_t kAmcorAuto = 0b101;
+
44 const uint8_t kAmcorModeOffset = 0;
+
45 const uint8_t kAmcorModeSize = 3;
+
46 
+
47 // state[2]
+
48 const uint8_t kAmcorTempByte = 2;
+
49 // Temperature
+
50 const uint8_t kAmcorMinTemp = 12; // Celsius
+
51 const uint8_t kAmcorMaxTemp = 32; // Celsius
+
52 const uint8_t kAmcorTempOffset = 1;
+
53 const uint8_t kAmcorTempSize = 6; // Bits
+
54 
+
55 // state[5]
+
56 // Power
+
57 const uint8_t kAmcorPowerByte = 5;
+
58 const uint8_t kAmcorPowerOffset = 4;
+
59 const uint8_t kAmcorPowerSize = 4;
+
60 const uint8_t kAmcorPowerOn = 0b0011; // 0x3
+
61 const uint8_t kAmcorPowerOff = 0b1100; // 0xC
+
62 
+
63 // state[6]
+
64 const uint8_t kAmcorSpecialByte = 6;
+
65 // Max Mode (aka "Lo" in Cool and "Hi" in Heat)
+
66 const uint8_t kAmcorMax = 0b11;
+
67 const uint8_t kAmcorMaxOffset = 0;
+
68 const uint8_t kAmcorMaxSize = 2;
+
69 
+
70 // "Vent" Mode
+
71 const uint8_t kAmcorVentOn = 0b11;
+
72 const uint8_t kAmcorVentOffset = 6;
+
73 const uint8_t kAmcorVentSize = 2;
+
74 // state[7]
+
75 // Checksum byte.
+ +
77 
+
78 // Classes
+
79 
+
81 class IRAmcorAc {
+
82  public:
+
83  explicit IRAmcorAc(const uint16_t pin, const bool inverted = false,
+
84  const bool use_modulation = true);
+
85 
+
86  void stateReset();
+
87 #if SEND_AMCOR
+
88  void send(const uint16_t repeat = kAmcorDefaultRepeat);
+
93  int8_t calibrate(void) { return _irsend.calibrate(); }
+
94 #endif // SEND_AMCOR
+
95  void begin();
+
96  static uint8_t calcChecksum(const uint8_t state[],
+
97  const uint16_t length = kAmcorStateLength);
+
98  static bool validChecksum(const uint8_t state[],
+
99  const uint16_t length = kAmcorStateLength);
+
100  void setPower(const bool state);
+
101  bool getPower();
+
102  void on();
+
103  void off();
+
104  void setTemp(const uint8_t temp);
+
105  uint8_t getTemp();
+
106  void setMax(const bool on);
+
107  bool getMax(void);
+
108  void setFan(const uint8_t speed);
+
109  uint8_t getFan();
+
110  void setMode(const uint8_t mode);
+
111  uint8_t getMode();
+
112  uint8_t* getRaw();
+
113  void setRaw(const uint8_t state[]);
+
114  uint8_t convertMode(const stdAc::opmode_t mode);
+
115  uint8_t convertFan(const stdAc::fanspeed_t speed);
+
116  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
117  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
118  stdAc::state_t toCommon(void);
+
119  String toString();
+
120 #ifndef UNIT_TEST
+
121 
+
122  private:
+ +
124 #else
+
125  IRsendTest _irsend;
+
128 #endif
+
129  uint8_t remote_state[kAmcorStateLength]; // The state of the IR remote.
+
130  void checksum(void);
+
131 };
+
132 #endif // IR_AMCOR_H_
+
+
IRAmcorAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Amcor.cpp:96
+
const uint8_t kAmcorSpecialByte
Definition: ir_Amcor.h:64
+
void setMode(const uint8_t mode)
Set the desired operation mode.
Definition: ir_Amcor.cpp:247
+
void send(const uint16_t repeat=kAmcorDefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Amcor.cpp:106
+
const uint8_t kAmcorCool
Definition: ir_Amcor.h:39
+
const uint16_t kAmcorStateLength
Definition: IRremoteESP8266.h:818
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Amcor.cpp:303
+
const uint8_t kAmcorPowerOn
Definition: ir_Amcor.h:60
+
static uint8_t calcChecksum(const uint8_t state[], const uint16_t length=kAmcorStateLength)
Calculate the checksum for the supplied state.
Definition: ir_Amcor.cpp:115
+
const uint8_t kAmcorMax
Definition: ir_Amcor.h:66
+
IRsend _irsend
Definition: ir_Amcor.h:123
+
uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Amcor.cpp:285
+
const uint8_t kAmcorHeat
Definition: ir_Amcor.h:40
+
void begin()
Set up hardware to be able to send a message.
Definition: ir_Amcor.cpp:101
+
uint8_t getFan()
Get the current fan speed setting.
Definition: ir_Amcor.cpp:233
+ +
const uint8_t kAmcorMaxOffset
Definition: ir_Amcor.h:67
+
const uint8_t kAmcorFanAuto
Definition: ir_Amcor.h:35
+
uint8_t * getRaw()
Get the raw state of the object, suitable to be sent with the appropriate IRsend object method.
Definition: ir_Amcor.cpp:145
+
const uint8_t kAmcorVentSize
Definition: ir_Amcor.h:73
+
uint8_t getMode()
Get the current operation mode setting.
Definition: ir_Amcor.cpp:240
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
void setFan(const uint8_t speed)
Set the speed of the fan.
Definition: ir_Amcor.cpp:217
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
const uint8_t kAmcorTempByte
Definition: ir_Amcor.h:48
+
void on()
Set the internal state to have the power on.
Definition: ir_Amcor.cpp:157
+
std::string String
Definition: IRremoteESP8266.h:1093
+
const uint8_t kAmcorPowerSize
Definition: ir_Amcor.h:59
+
Class for handling detailed Amcor A/C messages.
Definition: ir_Amcor.h:81
+
const uint8_t kAmcorMinTemp
Definition: ir_Amcor.h:50
+
void setMax(const bool on)
Control the current Maximum Cooling or Heating setting. (i.e. Turbo)
Definition: ir_Amcor.cpp:195
+
const uint8_t kAmcorMaxSize
Definition: ir_Amcor.h:68
+
const uint8_t kAmcorChecksumByte
Definition: ir_Amcor.h:76
+
void stateReset()
Reset the internals of the object to a known good state.
Definition: ir_Amcor.cpp:134
+
const uint8_t kAmcorFan
Definition: ir_Amcor.h:41
+
void setRaw(const uint8_t state[])
Set the raw state of the object.
Definition: ir_Amcor.cpp:152
+
const uint8_t kAmcorVentOn
Definition: ir_Amcor.h:71
+
const uint8_t kAmcorFanMin
Definition: ir_Amcor.h:32
+ +
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Amcor.cpp:267
+
const uint8_t kAmcorVentOffset
Definition: ir_Amcor.h:72
+
const uint8_t kAmcorDry
Definition: ir_Amcor.h:42
+
const uint8_t kAmcorFanMed
Definition: ir_Amcor.h:33
+
uint8_t remote_state[kAmcorStateLength]
Definition: ir_Amcor.h:129
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Amcor.cpp:178
+
const uint8_t kAmcorPowerByte
Definition: ir_Amcor.h:57
+
const uint8_t kAmcorTempSize
Definition: ir_Amcor.h:53
+
void off()
Set the internal state to have the power off.
Definition: ir_Amcor.cpp:160
+
void setPower(const bool state)
Set the internal state to have the desired power.
Definition: ir_Amcor.cpp:164
+
uint8_t getTemp()
Get the current temperature setting.
Definition: ir_Amcor.cpp:187
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Amcor.h:93
+
bool getPower()
Get the power setting from the internal state.
Definition: ir_Amcor.cpp:171
+
const uint8_t kAmcorPowerOff
Definition: ir_Amcor.h:61
+
const uint8_t kAmcorModeSize
Definition: ir_Amcor.h:45
+
void checksum(void)
Update the checksum value for the internal state.
Definition: ir_Amcor.cpp:128
+
const uint8_t kAmcorFanSize
Definition: ir_Amcor.h:37
+
const uint8_t kAmcorModeOffset
Definition: ir_Amcor.h:44
+
static bool validChecksum(const uint8_t state[], const uint16_t length=kAmcorStateLength)
Verify the checksum is valid for a given state.
Definition: ir_Amcor.cpp:123
+
const uint8_t kAmcorPowerOffset
Definition: ir_Amcor.h:58
+
const uint8_t kAmcorAuto
Definition: ir_Amcor.h:43
+
const uint8_t kAmcorModeFanByte
Definition: ir_Amcor.h:30
+
const uint8_t kAmcorMaxTemp
Definition: ir_Amcor.h:51
+
const uint16_t kAmcorDefaultRepeat
Definition: IRremoteESP8266.h:820
+
const uint8_t kAmcorFanOffset
Definition: ir_Amcor.h:36
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Amcor.cpp:327
+
const uint8_t kAmcorFanMax
Definition: ir_Amcor.h:34
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
String toString()
Convert the current internal state into a human readable string.
Definition: ir_Amcor.cpp:353
+
bool getMax(void)
Is the Maximum Cooling or Heating setting (i.e. Turbo) setting on?
Definition: ir_Amcor.cpp:210
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Amcor.cpp:316
+
const uint8_t kAmcorTempOffset
Definition: ir_Amcor.h:52
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Argo_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Argo_8cpp.html new file mode 100644 index 000000000..7acafb331 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Argo_8cpp.html @@ -0,0 +1,188 @@ + + + + + + + +IRremoteESP8266: src/ir_Argo.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Argo.cpp File Reference
+
+
+ +

Argo A/C protocol. Controls an Argo Ulisse 13 DCI A/C. +More...

+ + + + + + + + + + + + + + +

+Variables

const uint16_t kArgoHdrMark = 6400
 
const uint16_t kArgoHdrSpace = 3300
 
const uint16_t kArgoBitMark = 400
 
const uint16_t kArgoOneSpace = 2200
 
const uint16_t kArgoZeroSpace = 900
 
const uint32_t kArgoGap = kDefaultMessageGap
 
+

Detailed Description

+

Argo A/C protocol. Controls an Argo Ulisse 13 DCI A/C.

+

Variable Documentation

+ +

◆ kArgoBitMark

+ +
+
+ + + + +
const uint16_t kArgoBitMark = 400
+
+ +
+
+ +

◆ kArgoGap

+ +
+
+ + + + +
const uint32_t kArgoGap = kDefaultMessageGap
+
+ +
+
+ +

◆ kArgoHdrMark

+ +
+
+ + + + +
const uint16_t kArgoHdrMark = 6400
+
+ +
+
+ +

◆ kArgoHdrSpace

+ +
+
+ + + + +
const uint16_t kArgoHdrSpace = 3300
+
+ +
+
+ +

◆ kArgoOneSpace

+ +
+
+ + + + +
const uint16_t kArgoOneSpace = 2200
+
+ +
+
+ +

◆ kArgoZeroSpace

+ +
+
+ + + + +
const uint16_t kArgoZeroSpace = 900
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Argo_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Argo_8h.html new file mode 100644 index 000000000..4e754d73f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Argo_8h.html @@ -0,0 +1,747 @@ + + + + + + + +IRremoteESP8266: src/ir_Argo.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Argo.h File Reference
+
+
+ +

Support for Argo Ulisse 13 DCI Mobile Split ACs. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRArgoAC
 Class for handling detailed Argo A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kArgoHeatBit = 0b00100000
 
const uint8_t kArgoTempLowOffset = 5
 
const uint8_t kArgoTempLowSize = 2
 
const uint8_t kArgoModeOffset = 3
 
const uint8_t kArgoModeSize = 3
 
const uint8_t kArgoCool = 0b000
 
const uint8_t kArgoDry = 0b001
 
const uint8_t kArgoAuto = 0b010
 
const uint8_t kArgoOff = 0b011
 
const uint8_t kArgoHeat = 0b100
 
const uint8_t kArgoHeatAuto = 0b101
 
const uint8_t kArgoHeatBlink = 0b110
 
const uint8_t kArgoTempHighOffset = 0
 
const uint8_t kArgoTempHighSize = 3
 
const uint8_t kArgoFanOffset = 3
 
const uint8_t kArgoFanSize = 2
 
const uint8_t kArgoFanAuto = 0
 
const uint8_t kArgoFan1 = 1
 
const uint8_t kArgoFan2 = 2
 
const uint8_t kArgoFan3 = 3
 
const uint8_t kArgoRoomTempLowOffset = 5
 
const uint8_t kArgoRoomTempLowSize = 3
 
const uint8_t kArgoRoomTempHighOffset = 0
 
const uint8_t kArgoRoomTempHighSize = 2
 
const uint8_t kArgoTempDelta = 4
 
const uint8_t kArgoMaxRoomTemp
 
const uint8_t kArgoNightBitOffset = 2
 
const uint8_t kArgoMaxBitOffset = 3
 
const uint8_t kArgoPowerBitOffset = 5
 
const uint8_t kArgoIFeelBitOffset = 7
 
const uint8_t kArgoMinTemp = 10
 
const uint8_t kArgoMaxTemp = 32
 
const uint8_t kArgoFlapAuto = 0
 
const uint8_t kArgoFlap1 = 1
 
const uint8_t kArgoFlap2 = 2
 
const uint8_t kArgoFlap3 = 3
 
const uint8_t kArgoFlap4 = 4
 
const uint8_t kArgoFlap5 = 5
 
const uint8_t kArgoFlap6 = 6
 
const uint8_t kArgoFlapFull = 7
 
+

Detailed Description

+

Support for Argo Ulisse 13 DCI Mobile Split ACs.

+

Variable Documentation

+ +

◆ kArgoAuto

+ +
+
+ + + + +
const uint8_t kArgoAuto = 0b010
+
+ +
+
+ +

◆ kArgoCool

+ +
+
+ + + + +
const uint8_t kArgoCool = 0b000
+
+ +
+
+ +

◆ kArgoDry

+ +
+
+ + + + +
const uint8_t kArgoDry = 0b001
+
+ +
+
+ +

◆ kArgoFan1

+ +
+
+ + + + +
const uint8_t kArgoFan1 = 1
+
+ +
+
+ +

◆ kArgoFan2

+ +
+
+ + + + +
const uint8_t kArgoFan2 = 2
+
+ +
+
+ +

◆ kArgoFan3

+ +
+
+ + + + +
const uint8_t kArgoFan3 = 3
+
+ +
+
+ +

◆ kArgoFanAuto

+ +
+
+ + + + +
const uint8_t kArgoFanAuto = 0
+
+ +
+
+ +

◆ kArgoFanOffset

+ +
+
+ + + + +
const uint8_t kArgoFanOffset = 3
+
+ +
+
+ +

◆ kArgoFanSize

+ +
+
+ + + + +
const uint8_t kArgoFanSize = 2
+
+ +
+
+ +

◆ kArgoFlap1

+ +
+
+ + + + +
const uint8_t kArgoFlap1 = 1
+
+ +
+
+ +

◆ kArgoFlap2

+ +
+
+ + + + +
const uint8_t kArgoFlap2 = 2
+
+ +
+
+ +

◆ kArgoFlap3

+ +
+
+ + + + +
const uint8_t kArgoFlap3 = 3
+
+ +
+
+ +

◆ kArgoFlap4

+ +
+
+ + + + +
const uint8_t kArgoFlap4 = 4
+
+ +
+
+ +

◆ kArgoFlap5

+ +
+
+ + + + +
const uint8_t kArgoFlap5 = 5
+
+ +
+
+ +

◆ kArgoFlap6

+ +
+
+ + + + +
const uint8_t kArgoFlap6 = 6
+
+ +
+
+ +

◆ kArgoFlapAuto

+ +
+
+ + + + +
const uint8_t kArgoFlapAuto = 0
+
+ +
+
+ +

◆ kArgoFlapFull

+ +
+
+ + + + +
const uint8_t kArgoFlapFull = 7
+
+ +
+
+ +

◆ kArgoHeat

+ +
+
+ + + + +
const uint8_t kArgoHeat = 0b100
+
+ +
+
+ +

◆ kArgoHeatAuto

+ +
+
+ + + + +
const uint8_t kArgoHeatAuto = 0b101
+
+ +
+
+ +

◆ kArgoHeatBit

+ +
+
+ + + + +
const uint8_t kArgoHeatBit = 0b00100000
+
+ +
+
+ +

◆ kArgoHeatBlink

+ +
+
+ + + + +
const uint8_t kArgoHeatBlink = 0b110
+
+ +
+
+ +

◆ kArgoIFeelBitOffset

+ +
+
+ + + + +
const uint8_t kArgoIFeelBitOffset = 7
+
+ +
+
+ +

◆ kArgoMaxBitOffset

+ +
+
+ + + + +
const uint8_t kArgoMaxBitOffset = 3
+
+ +
+
+ +

◆ kArgoMaxRoomTemp

+ +
+
+ + + + +
const uint8_t kArgoMaxRoomTemp
+
+Initial value: +
+
+ +

◆ kArgoMaxTemp

+ +
+
+ + + + +
const uint8_t kArgoMaxTemp = 32
+
+ +
+
+ +

◆ kArgoMinTemp

+ +
+
+ + + + +
const uint8_t kArgoMinTemp = 10
+
+ +
+
+ +

◆ kArgoModeOffset

+ +
+
+ + + + +
const uint8_t kArgoModeOffset = 3
+
+ +
+
+ +

◆ kArgoModeSize

+ +
+
+ + + + +
const uint8_t kArgoModeSize = 3
+
+ +
+
+ +

◆ kArgoNightBitOffset

+ +
+
+ + + + +
const uint8_t kArgoNightBitOffset = 2
+
+ +
+
+ +

◆ kArgoOff

+ +
+
+ + + + +
const uint8_t kArgoOff = 0b011
+
+ +
+
+ +

◆ kArgoPowerBitOffset

+ +
+
+ + + + +
const uint8_t kArgoPowerBitOffset = 5
+
+ +
+
+ +

◆ kArgoRoomTempHighOffset

+ +
+
+ + + + +
const uint8_t kArgoRoomTempHighOffset = 0
+
+ +
+
+ +

◆ kArgoRoomTempHighSize

+ +
+
+ + + + +
const uint8_t kArgoRoomTempHighSize = 2
+
+ +
+
+ +

◆ kArgoRoomTempLowOffset

+ +
+
+ + + + +
const uint8_t kArgoRoomTempLowOffset = 5
+
+ +
+
+ +

◆ kArgoRoomTempLowSize

+ +
+
+ + + + +
const uint8_t kArgoRoomTempLowSize = 3
+
+ +
+
+ +

◆ kArgoTempDelta

+ +
+
+ + + + +
const uint8_t kArgoTempDelta = 4
+
+ +
+
+ +

◆ kArgoTempHighOffset

+ +
+
+ + + + +
const uint8_t kArgoTempHighOffset = 0
+
+ +
+
+ +

◆ kArgoTempHighSize

+ +
+
+ + + + +
const uint8_t kArgoTempHighSize = 3
+
+ +
+
+ +

◆ kArgoTempLowOffset

+ +
+
+ + + + +
const uint8_t kArgoTempLowOffset = 5
+
+ +
+
+ +

◆ kArgoTempLowSize

+ +
+
+ + + + +
const uint8_t kArgoTempLowSize = 2
+
+ +
+
+
+
const uint8_t kArgoRoomTempHighSize
Definition: ir_Argo.h:79
+
const uint8_t kArgoRoomTempLowSize
Definition: ir_Argo.h:74
+
const uint8_t kArgoTempDelta
Definition: ir_Argo.h:81
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Argo_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Argo_8h_source.html new file mode 100644 index 000000000..c042059f9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Argo_8h_source.html @@ -0,0 +1,373 @@ + + + + + + + +IRremoteESP8266: src/ir_Argo.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Argo.h
+
+
+Go to the documentation of this file.
1 // Copyright 2017 Schmolders
+
4 
+
5 // Supports:
+
6 // Brand: Argo, Model: Ulisse 13 DCI Mobile Split A/C
+
7 
+
8 #ifndef IR_ARGO_H_
+
9 #define IR_ARGO_H_
+
10 
+
11 #ifndef UNIT_TEST
+
12 #include <Arduino.h>
+
13 #endif
+
14 #include "IRremoteESP8266.h"
+
15 #include "IRsend.h"
+
16 #ifdef UNIT_TEST
+
17 #include "IRsend_test.h"
+
18 #endif
+
19 
+
20 
+
21 // ARGO Ulisse DCI
+
22 
+
23 /*
+
24  Protocol Description:
+
25  All in LSB first as it is sent. argo message array will be stored MSB first!
+
26  do LSB-MSB conversion in sendData
+
27  Byte 0: const 0 0 1 1 0 1 0 1
+
28  Byte 1: const 1 0 1 0 1 1 1 1
+
29  Byte 2: 0 0 0, 3bit Cool/Heat Mode, 2bit start SetTemp LSB first
+
30  Byte 3: 3bit End SetTemp, 2bit Fan Mode, 3bit RoomTemp LSB first
+
31  Byte 4: 2bit RoomTemp, 3bit Flap Mode, 3bit OnTimer
+
32  Byte 5: 8bit OnTimer
+
33  Byte 6: 8Bit OffTimer
+
34  Byte 7: 3bit OffTimer, 5bit Time
+
35  Byte 8: 6bit Time, 1bit Timer On/Off, 1bit Timer Program
+
36  Byte 9: 1bit Timer Program, 1bit Timer 1h, 1 bit Night Mode, 1bit Max Mode, 1bit Filter, 1bit on/off, 1bit const 0, 1bit iFeel
+
37  Byte 10: 2bit const 0 1, 6bit Checksum
+
38  Byte 11: 2bit Checksum
+
39 */
+
40 
+
41 // Constants. Store MSB left.
+
42 
+
43 // byte[2]
+
44 const uint8_t kArgoHeatBit = 0b00100000;
+
45 // kArgoTempLowMask = 0b11000000;
+
46 const uint8_t kArgoTempLowOffset = 5;
+
47 const uint8_t kArgoTempLowSize = 2;
+
48 
+
49 // Mode 0b00111000
+
50 const uint8_t kArgoModeOffset = 3;
+
51 const uint8_t kArgoModeSize = 3;
+
52 const uint8_t kArgoCool = 0b000;
+
53 const uint8_t kArgoDry = 0b001;
+
54 const uint8_t kArgoAuto = 0b010;
+
55 const uint8_t kArgoOff = 0b011;
+
56 const uint8_t kArgoHeat = 0b100;
+
57 const uint8_t kArgoHeatAuto = 0b101;
+
58 // ?no idea what mode that is
+
59 const uint8_t kArgoHeatBlink = 0b110;
+
60 
+
61 // byte[3]
+
62 // kArgoTempHighMask = 0b00000111;
+
63 const uint8_t kArgoTempHighOffset = 0;
+
64 const uint8_t kArgoTempHighSize = 3;
+
65 // Fan 0b00011000
+
66 const uint8_t kArgoFanOffset = 3;
+
67 const uint8_t kArgoFanSize = 2;
+
68 const uint8_t kArgoFanAuto = 0; // 0b00
+
69 const uint8_t kArgoFan1 = 1; // 0b01
+
70 const uint8_t kArgoFan2 = 2; // 0b10
+
71 const uint8_t kArgoFan3 = 3; // 0b11
+
72 // kArgoRoomTempLowMask = 0b11100000;
+
73 const uint8_t kArgoRoomTempLowOffset = 5;
+
74 const uint8_t kArgoRoomTempLowSize = 3;
+
75 
+
76 // byte[4]
+
77 // kArgoRoomTempHighMask = 0b00000011;
+
78 const uint8_t kArgoRoomTempHighOffset = 0;
+
79 const uint8_t kArgoRoomTempHighSize = 2;
+
80 
+
81 const uint8_t kArgoTempDelta = 4;
+
82 const uint8_t kArgoMaxRoomTemp =
+ +
84  kArgoTempDelta; // 35C
+
85 
+
86 // byte[9]
+
87 const uint8_t kArgoNightBitOffset = 2;
+
88 const uint8_t kArgoMaxBitOffset = 3;
+
89 const uint8_t kArgoPowerBitOffset = 5;
+
90 const uint8_t kArgoIFeelBitOffset = 7;
+
91 
+
92 const uint8_t kArgoMinTemp = 10; // Celsius delta +4
+
93 const uint8_t kArgoMaxTemp = 32; // Celsius
+
94 
+
95 const uint8_t kArgoFlapAuto = 0;
+
96 const uint8_t kArgoFlap1 = 1;
+
97 const uint8_t kArgoFlap2 = 2;
+
98 const uint8_t kArgoFlap3 = 3;
+
99 const uint8_t kArgoFlap4 = 4;
+
100 const uint8_t kArgoFlap5 = 5;
+
101 const uint8_t kArgoFlap6 = 6;
+
102 const uint8_t kArgoFlapFull = 7;
+
103 
+
104 // Legacy defines. (Deperecated)
+
105 #define ARGO_COOL_ON kArgoCoolOn
+
106 #define ARGO_COOL_OFF kArgoCoolOff
+
107 #define ARGO_COOL_AUTO kArgoCoolAuto
+
108 #define ARGO_COOL_HUM kArgoCoolHum
+
109 #define ARGO_HEAT_ON kArgoHeatOn
+
110 #define ARGO_HEAT_AUTO kArgoHeatAuto
+
111 #define ARGO_HEAT_BLINK kArgoHeatBlink
+
112 #define ARGO_MIN_TEMP kArgoMinTemp
+
113 #define ARGO_MAX_TEMP kArgoMaxTemp
+
114 #define ARGO_FAN_AUTO kArgoFanAuto
+
115 #define ARGO_FAN_3 kArgoFan3
+
116 #define ARGO_FAN_2 kArgoFan2
+
117 #define ARGO_FAN_1 kArgoFan1
+
118 #define ARGO_FLAP_AUTO kArgoFlapAuto
+
119 #define ARGO_FLAP_1 kArgoFlap1
+
120 #define ARGO_FLAP_2 kArgoFlap2
+
121 #define ARGO_FLAP_3 kArgoFlap3
+
122 #define ARGO_FLAP_4 kArgoFlap4
+
123 #define ARGO_FLAP_5 kArgoFlap5
+
124 #define ARGO_FLAP_6 kArgoFlap6
+
125 #define ARGO_FLAP_FULL kArgoFlapFull
+
126 
+
127 
+
129 class IRArgoAC {
+
130  public:
+
131  explicit IRArgoAC(const uint16_t pin, const bool inverted = false,
+
132  const bool use_modulation = true);
+
133 
+
134 #if SEND_ARGO
+
135  void send(const uint16_t repeat = kArgoDefaultRepeat);
+
140  int8_t calibrate(void) { return _irsend.calibrate(); }
+
141 #endif // SEND_ARGO
+
142  void begin(void);
+
143  void on(void);
+
144  void off(void);
+
145 
+
146  void setPower(const bool on);
+
147  bool getPower(void);
+
148 
+
149  void setTemp(const uint8_t degrees);
+
150  uint8_t getTemp(void);
+
151 
+
152  void setFan(const uint8_t fan);
+
153  uint8_t getFan(void);
+
154 
+
155  void setFlap(const uint8_t flap);
+
156  uint8_t getFlap(void);
+
157 
+
158  void setMode(const uint8_t mode);
+
159  uint8_t getMode(void);
+
160 
+
161  void setMax(const bool on);
+
162  bool getMax(void);
+
163 
+
164  void setNight(const bool on);
+
165  bool getNight(void);
+
166 
+
167  void setiFeel(const bool on);
+
168  bool getiFeel(void);
+
169 
+
170  void setTime(void);
+
171  void setRoomTemp(const uint8_t degrees);
+
172  uint8_t getRoomTemp(void);
+
173 
+
174  uint8_t* getRaw(void);
+
175  void setRaw(const uint8_t state[]);
+
176  static uint8_t calcChecksum(const uint8_t state[],
+
177  const uint16_t length = kArgoStateLength);
+
178  static bool validChecksum(const uint8_t state[],
+
179  const uint16_t length = kArgoStateLength);
+
180  static uint8_t convertMode(const stdAc::opmode_t mode);
+
181  static uint8_t convertFan(const stdAc::fanspeed_t speed);
+
182  static uint8_t convertSwingV(const stdAc::swingv_t position);
+
183  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
184  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
185  stdAc::state_t toCommon(void);
+
186  String toString();
+
187 #ifndef UNIT_TEST
+
188 
+
189  private:
+ +
191 #else
+
192  IRsendTest _irsend;
+
194 #endif
+
196  // # of bytes per command
+
197  uint8_t argo[kArgoStateLength]; // Defined in IRremoteESP8266.h
+
198  void stateReset(void);
+
199  void checksum(void);
+
200 
+
201  // Attributes
+
202  uint8_t flap_mode;
+
203  uint8_t heat_mode;
+
204  uint8_t cool_mode;
+
205 };
+
206 
+
207 #endif // IR_ARGO_H_
+
+
const uint8_t kArgoFanOffset
Definition: ir_Argo.h:66
+
void setTime(void)
Set the time for the A/C.
Definition: ir_Argo.cpp:253
+
static uint8_t calcChecksum(const uint8_t state[], const uint16_t length=kArgoStateLength)
Verify the checksum is valid for a given state.
Definition: ir_Argo.cpp:74
+
uint8_t flap_mode
Definition: ir_Argo.h:202
+
void setFan(const uint8_t fan)
Set the speed of the fan.
Definition: ir_Argo.cpp:185
+
IRsend _irsend
instance of the IR send class
Definition: ir_Argo.h:190
+
const uint8_t kArgoHeatBlink
Definition: ir_Argo.h:59
+
swingv_t
Common A/C settings for Vertical Swing.
Definition: IRsend.h:70
+
const uint8_t kArgoMaxTemp
Definition: ir_Argo.h:93
+
const uint16_t kArgoDefaultRepeat
Definition: IRremoteESP8266.h:823
+
void setTemp(const uint8_t degrees)
Set the temperature.
Definition: ir_Argo.cpp:162
+
void setFlap(const uint8_t flap)
Set the flap position. i.e. Swing.
Definition: ir_Argo.cpp:198
+
uint8_t getMode(void)
Get the current operation mode setting.
Definition: ir_Argo.cpp:210
+
static uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Argo.cpp:279
+
const uint8_t kArgoPowerBitOffset
Definition: ir_Argo.h:89
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
const uint8_t kArgoTempHighOffset
Definition: ir_Argo.h:63
+
const uint8_t kArgoFlap2
Definition: ir_Argo.h:97
+
void stateReset(void)
Reset the internals of the object to a known good state.
Definition: ir_Argo.cpp:101
+
const uint8_t kArgoFlap4
Definition: ir_Argo.h:99
+
const uint8_t kArgoTempHighSize
Definition: ir_Argo.h:64
+
const uint8_t kArgoHeatBit
Definition: ir_Argo.h:44
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Argo.h:140
+
uint8_t argo[kArgoStateLength]
Definition: ir_Argo.h:197
+ +
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Argo.cpp:360
+
const uint8_t kArgoFlap3
Definition: ir_Argo.h:98
+
const uint8_t kArgoMaxBitOffset
Definition: ir_Argo.h:88
+
bool getiFeel(void)
Get the status of iFeel mode.
Definition: ir_Argo.cpp:249
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
static bool validChecksum(const uint8_t state[], const uint16_t length=kArgoStateLength)
Verify the checksum is valid for a given state.
Definition: ir_Argo.cpp:85
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
uint8_t getFlap(void)
Get the flap position. i.e. Swing.
Definition: ir_Argo.cpp:206
+
bool getMax(void)
Is the Max (i.e. Turbo) setting on?
Definition: ir_Argo.cpp:157
+
const uint16_t kArgoStateLength
Definition: IRremoteESP8266.h:821
+
std::string String
Definition: IRremoteESP8266.h:1093
+
const uint8_t kArgoFan1
Definition: ir_Argo.h:69
+
uint8_t getRoomTemp(void)
Get the currently stored value for the room temperature setting.
Definition: ir_Argo.cpp:269
+
bool getPower(void)
Get the power setting from the internal state.
Definition: ir_Argo.cpp:147
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Argo.cpp:336
+
const uint8_t kArgoOff
Definition: ir_Argo.h:55
+
static uint8_t convertSwingV(const stdAc::swingv_t position)
Convert a stdAc::swingv_t enum into it's native setting.
Definition: ir_Argo.cpp:316
+
const uint8_t kArgoFlapFull
Definition: ir_Argo.h:102
+
const uint8_t kArgoRoomTempHighSize
Definition: ir_Argo.h:79
+ +
const uint8_t kArgoDry
Definition: ir_Argo.h:53
+
const uint8_t kArgoAuto
Definition: ir_Argo.h:54
+
void setRoomTemp(const uint8_t degrees)
Set the value for the current room temperature.
Definition: ir_Argo.cpp:259
+
static uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Argo.cpp:298
+
const uint8_t kArgoTempLowOffset
Definition: ir_Argo.h:46
+
void off(void)
Set the internal state to have the power off.
Definition: ir_Argo.cpp:137
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Argo.cpp:191
+
void setPower(const bool on)
Set the internal state to have the desired power.
Definition: ir_Argo.cpp:141
+
const uint8_t kArgoRoomTempLowOffset
Definition: ir_Argo.h:73
+
const uint8_t kArgoFlap1
Definition: ir_Argo.h:96
+
const uint8_t kArgoModeOffset
Definition: ir_Argo.h:50
+
uint8_t * getRaw(void)
Get the raw state of the object, suitable to be sent with the appropriate IRsend object method.
Definition: ir_Argo.cpp:122
+
const uint8_t kArgoTempLowSize
Definition: ir_Argo.h:47
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Argo.cpp:176
+
const uint8_t kArgoRoomTempLowSize
Definition: ir_Argo.h:74
+
uint8_t heat_mode
Definition: ir_Argo.h:203
+
const uint8_t kArgoMinTemp
Definition: ir_Argo.h:92
+
void on(void)
Set the internal state to have the power on.
Definition: ir_Argo.cpp:134
+
void setNight(const bool on)
Turn on/off the Night mode. i.e. Sleep.
Definition: ir_Argo.cpp:233
+
bool getNight(void)
Get the status of Night mode. i.e. Sleep.
Definition: ir_Argo.cpp:239
+
const uint8_t kArgoFan2
Definition: ir_Argo.h:70
+
const uint8_t kArgoIFeelBitOffset
Definition: ir_Argo.h:90
+
const uint8_t kArgoCool
Definition: ir_Argo.h:52
+
void send(const uint16_t repeat=kArgoDefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Argo.cpp:65
+
const uint8_t kArgoHeatAuto
Definition: ir_Argo.h:57
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Argo.cpp:349
+
const uint8_t kArgoHeat
Definition: ir_Argo.h:56
+
void setRaw(const uint8_t state[])
Set the raw state of the object.
Definition: ir_Argo.cpp:129
+
const uint8_t kArgoFlap5
Definition: ir_Argo.h:100
+
IRArgoAC(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Argo.cpp:55
+
const uint8_t kArgoTempDelta
Definition: ir_Argo.h:81
+
const uint8_t kArgoRoomTempHighOffset
Definition: ir_Argo.h:78
+
void checksum(void)
Update the checksum for the internal state.
Definition: ir_Argo.cpp:91
+
const uint8_t kArgoFlap6
Definition: ir_Argo.h:101
+
const uint8_t kArgoModeSize
Definition: ir_Argo.h:51
+
uint8_t cool_mode
Definition: ir_Argo.h:204
+
void setiFeel(const bool on)
Turn on/off the iFeel mode.
Definition: ir_Argo.cpp:243
+
void setMax(const bool on)
Control the current Max setting. (i.e. Turbo)
Definition: ir_Argo.cpp:151
+
String toString()
Convert the current internal state into a human readable string.
Definition: ir_Argo.cpp:386
+
const uint8_t kArgoFlapAuto
Definition: ir_Argo.h:95
+
const uint8_t kArgoFanSize
Definition: ir_Argo.h:67
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
const uint8_t kArgoFan3
Definition: ir_Argo.h:71
+
Class for handling detailed Argo A/C messages.
Definition: ir_Argo.h:129
+
const uint8_t kArgoNightBitOffset
Definition: ir_Argo.h:87
+
const uint8_t kArgoFanAuto
Definition: ir_Argo.h:68
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Argo.cpp:60
+
void setMode(const uint8_t mode)
Set the desired operation mode.
Definition: ir_Argo.cpp:216
+
const uint8_t kArgoMaxRoomTemp
Definition: ir_Argo.h:82
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Carrier_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Carrier_8cpp.html new file mode 100644 index 000000000..23c897e70 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Carrier_8cpp.html @@ -0,0 +1,400 @@ + + + + + + + +IRremoteESP8266: src/ir_Carrier.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Carrier.cpp File Reference
+
+
+ +

Carrier protocols. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kCarrierAcHdrMark = 8532
 
const uint16_t kCarrierAcHdrSpace = 4228
 
const uint16_t kCarrierAcBitMark = 628
 
const uint16_t kCarrierAcOneSpace = 1320
 
const uint16_t kCarrierAcZeroSpace = 532
 
const uint16_t kCarrierAcGap = 20000
 
const uint16_t kCarrierAcFreq = 38
 
const uint16_t kCarrierAc40HdrMark = 8402
 
const uint16_t kCarrierAc40HdrSpace = 4166
 
const uint16_t kCarrierAc40BitMark = 547
 
const uint16_t kCarrierAc40OneSpace = 1540
 
const uint16_t kCarrierAc40ZeroSpace = 497
 
const uint32_t kCarrierAc40Gap = 150000
 
const uint16_t kCarrierAc64HdrMark = 8940
 
const uint16_t kCarrierAc64HdrSpace = 4556
 
const uint16_t kCarrierAc64BitMark = 503
 
const uint16_t kCarrierAc64OneSpace = 1736
 
const uint16_t kCarrierAc64ZeroSpace = 615
 
const uint32_t kCarrierAc64Gap = kDefaultMessageGap
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kCarrierAc40BitMark

+ +
+
+ + + + +
const uint16_t kCarrierAc40BitMark = 547
+
+ +
+
+ +

◆ kCarrierAc40Gap

+ +
+
+ + + + +
const uint32_t kCarrierAc40Gap = 150000
+
+
+ +

◆ kCarrierAc40HdrMark

+ +
+
+ + + + +
const uint16_t kCarrierAc40HdrMark = 8402
+
+ +
+
+ +

◆ kCarrierAc40HdrSpace

+ +
+
+ + + + +
const uint16_t kCarrierAc40HdrSpace = 4166
+
+ +
+
+ +

◆ kCarrierAc40OneSpace

+ +
+
+ + + + +
const uint16_t kCarrierAc40OneSpace = 1540
+
+ +
+
+ +

◆ kCarrierAc40ZeroSpace

+ +
+
+ + + + +
const uint16_t kCarrierAc40ZeroSpace = 497
+
+ +
+
+ +

◆ kCarrierAc64BitMark

+ +
+
+ + + + +
const uint16_t kCarrierAc64BitMark = 503
+
+ +
+
+ +

◆ kCarrierAc64Gap

+ +
+
+ + + + +
const uint32_t kCarrierAc64Gap = kDefaultMessageGap
+
+ +
+
+ +

◆ kCarrierAc64HdrMark

+ +
+
+ + + + +
const uint16_t kCarrierAc64HdrMark = 8940
+
+ +
+
+ +

◆ kCarrierAc64HdrSpace

+ +
+
+ + + + +
const uint16_t kCarrierAc64HdrSpace = 4556
+
+ +
+
+ +

◆ kCarrierAc64OneSpace

+ +
+
+ + + + +
const uint16_t kCarrierAc64OneSpace = 1736
+
+ +
+
+ +

◆ kCarrierAc64ZeroSpace

+ +
+
+ + + + +
const uint16_t kCarrierAc64ZeroSpace = 615
+
+ +
+
+ +

◆ kCarrierAcBitMark

+ +
+
+ + + + +
const uint16_t kCarrierAcBitMark = 628
+
+ +
+
+ +

◆ kCarrierAcFreq

+ +
+
+ + + + +
const uint16_t kCarrierAcFreq = 38
+
+ +
+
+ +

◆ kCarrierAcGap

+ +
+
+ + + + +
const uint16_t kCarrierAcGap = 20000
+
+ +
+
+ +

◆ kCarrierAcHdrMark

+ +
+
+ + + + +
const uint16_t kCarrierAcHdrMark = 8532
+
+ +
+
+ +

◆ kCarrierAcHdrSpace

+ +
+
+ + + + +
const uint16_t kCarrierAcHdrSpace = 4228
+
+ +
+
+ +

◆ kCarrierAcOneSpace

+ +
+
+ + + + +
const uint16_t kCarrierAcOneSpace = 1320
+
+ +
+
+ +

◆ kCarrierAcZeroSpace

+ +
+
+ + + + +
const uint16_t kCarrierAcZeroSpace = 532
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Carrier_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Carrier_8h.html new file mode 100644 index 000000000..a8953bf3e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Carrier_8h.html @@ -0,0 +1,568 @@ + + + + + + + +IRremoteESP8266: src/ir_Carrier.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Carrier.h File Reference
+
+
+ +

Carrier A/C. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRCarrierAc64
 Class for handling detailed Carrier 64 bit A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kCarrierAc64ChecksumOffset = 16
 
const uint8_t kCarrierAc64ChecksumSize = 4
 
const uint8_t kCarrierAc64ModeOffset
 
const uint8_t kCarrierAc64ModeSize = 2
 
const uint8_t kCarrierAc64Heat = 0b01
 
const uint8_t kCarrierAc64Cool = 0b10
 
const uint8_t kCarrierAc64Fan = 0b11
 
const uint8_t kCarrierAc64FanOffset
 
const uint8_t kCarrierAc64FanSize = 2
 
const uint8_t kCarrierAc64FanAuto = 0b00
 
const uint8_t kCarrierAc64FanLow = 0b01
 
const uint8_t kCarrierAc64FanMedium = 0b10
 
const uint8_t kCarrierAc64FanHigh = 0b11
 
const uint8_t kCarrierAc64TempOffset
 
const uint8_t kCarrierAc64TempSize = 4
 
const uint8_t kCarrierAc64MinTemp = 16
 
const uint8_t kCarrierAc64MaxTemp = 30
 
const uint8_t kCarrierAc64SwingVOffset
 
const uint8_t kCarrierAc64PowerOffset = kCarrierAc64SwingVOffset + 6 + 1
 
const uint8_t kCarrierAc64OffTimerEnableOffset
 
const uint8_t kCarrierAc64OnTimerEnableOffset
 
const uint8_t kCarrierAc64SleepOffset
 
const uint8_t kCarrierAc64TimerSize = 4
 
const uint8_t kCarrierAc64TimerMax = 9
 
const uint8_t kCarrierAc64TimerMin = 1
 
const uint8_t kCarrierAc64OnTimerOffset
 
const uint8_t kCarrierAc64OffTimerOffset
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kCarrierAc64ChecksumOffset

+ +
+
+ + + + +
const uint8_t kCarrierAc64ChecksumOffset = 16
+
+ +
+
+ +

◆ kCarrierAc64ChecksumSize

+ +
+
+ + + + +
const uint8_t kCarrierAc64ChecksumSize = 4
+
+ +
+
+ +

◆ kCarrierAc64Cool

+ +
+
+ + + + +
const uint8_t kCarrierAc64Cool = 0b10
+
+ +
+
+ +

◆ kCarrierAc64Fan

+ +
+
+ + + + +
const uint8_t kCarrierAc64Fan = 0b11
+
+ +
+
+ +

◆ kCarrierAc64FanAuto

+ +
+
+ + + + +
const uint8_t kCarrierAc64FanAuto = 0b00
+
+ +
+
+ +

◆ kCarrierAc64FanHigh

+ +
+
+ + + + +
const uint8_t kCarrierAc64FanHigh = 0b11
+
+ +
+
+ +

◆ kCarrierAc64FanLow

+ +
+
+ + + + +
const uint8_t kCarrierAc64FanLow = 0b01
+
+ +
+
+ +

◆ kCarrierAc64FanMedium

+ +
+
+ + + + +
const uint8_t kCarrierAc64FanMedium = 0b10
+
+ +
+
+ +

◆ kCarrierAc64FanOffset

+ +
+
+ + + + +
const uint8_t kCarrierAc64FanOffset
+
+
+ +

◆ kCarrierAc64FanSize

+ +
+
+ + + + +
const uint8_t kCarrierAc64FanSize = 2
+
+ +
+
+ +

◆ kCarrierAc64Heat

+ +
+
+ + + + +
const uint8_t kCarrierAc64Heat = 0b01
+
+ +
+
+ +

◆ kCarrierAc64MaxTemp

+ +
+
+ + + + +
const uint8_t kCarrierAc64MaxTemp = 30
+
+ +
+
+ +

◆ kCarrierAc64MinTemp

+ +
+
+ + + + +
const uint8_t kCarrierAc64MinTemp = 16
+
+ +
+
+ +

◆ kCarrierAc64ModeOffset

+ +
+
+ + + + +
const uint8_t kCarrierAc64ModeOffset
+
+
+ +

◆ kCarrierAc64ModeSize

+ +
+
+ + + + +
const uint8_t kCarrierAc64ModeSize = 2
+
+ +
+
+ +

◆ kCarrierAc64OffTimerEnableOffset

+ +
+
+ + + + +
const uint8_t kCarrierAc64OffTimerEnableOffset
+
+Initial value: +
+
+ +

◆ kCarrierAc64OffTimerOffset

+ +
+
+ + + + +
const uint8_t kCarrierAc64OffTimerOffset
+
+Initial value: +
+
+ +

◆ kCarrierAc64OnTimerEnableOffset

+ +
+
+ + + + +
const uint8_t kCarrierAc64OnTimerEnableOffset
+
+Initial value: +
+
+ +

◆ kCarrierAc64OnTimerOffset

+ +
+
+ + + + +
const uint8_t kCarrierAc64OnTimerOffset
+
+Initial value: +
+
+ +

◆ kCarrierAc64PowerOffset

+ +
+
+ + + + +
const uint8_t kCarrierAc64PowerOffset = kCarrierAc64SwingVOffset + 6 + 1
+
+ +
+
+ +

◆ kCarrierAc64SleepOffset

+ +
+
+ + + + +
const uint8_t kCarrierAc64SleepOffset
+
+Initial value: +
+
+ +

◆ kCarrierAc64SwingVOffset

+ +
+
+ + + + +
const uint8_t kCarrierAc64SwingVOffset
+
+Initial value: +
+
+ +

◆ kCarrierAc64TempOffset

+ +
+
+ + + + +
const uint8_t kCarrierAc64TempOffset
+
+Initial value: +
+
+ +

◆ kCarrierAc64TempSize

+ +
+
+ + + + +
const uint8_t kCarrierAc64TempSize = 4
+
+ +
+
+ +

◆ kCarrierAc64TimerMax

+ +
+
+ + + + +
const uint8_t kCarrierAc64TimerMax = 9
+
+ +
+
+ +

◆ kCarrierAc64TimerMin

+ +
+
+ + + + +
const uint8_t kCarrierAc64TimerMin = 1
+
+ +
+
+ +

◆ kCarrierAc64TimerSize

+ +
+
+ + + + +
const uint8_t kCarrierAc64TimerSize = 4
+
+ +
+
+
+
const uint8_t kCarrierAc64SleepOffset
Definition: ir_Carrier.h:60
+
const uint8_t kCarrierAc64FanSize
Definition: ir_Carrier.h:43
+
const uint8_t kCarrierAc64OnTimerEnableOffset
Definition: ir_Carrier.h:58
+
const uint8_t kCarrierAc64OnTimerOffset
Definition: ir_Carrier.h:65
+
const uint8_t kCarrierAc64OffTimerEnableOffset
Definition: ir_Carrier.h:56
+
const uint8_t kCarrierAc64TimerSize
Definition: ir_Carrier.h:62
+
const uint8_t kCarrierAc64ChecksumSize
Definition: ir_Carrier.h:34
+
const uint8_t kCarrierAc64ModeOffset
Definition: ir_Carrier.h:35
+
const uint8_t kCarrierAc64PowerOffset
Definition: ir_Carrier.h:55
+
const uint8_t kCarrierAc64ModeSize
Definition: ir_Carrier.h:37
+
const uint8_t kCarrierAc64TempOffset
Definition: ir_Carrier.h:48
+
const uint8_t kCarrierAc64TempSize
Definition: ir_Carrier.h:50
+
const uint8_t kCarrierAc64ChecksumOffset
Definition: ir_Carrier.h:33
+
const uint8_t kCarrierAc64FanOffset
Definition: ir_Carrier.h:41
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Carrier_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Carrier_8h_source.html new file mode 100644 index 000000000..aa44f135b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Carrier_8h_source.html @@ -0,0 +1,275 @@ + + + + + + + +IRremoteESP8266: src/ir_Carrier.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Carrier.h
+
+
+Go to the documentation of this file.
1 // Copyright 2020 David Conran
+
6 
+
7 // Supports:
+
8 // Brand: Carrier/Surrey, Model: 42QG5A55970 remote
+
9 // Brand: Carrier/Surrey, Model: 619EGX0090E0 A/C
+
10 // Brand: Carrier/Surrey, Model: 619EGX0120E0 A/C
+
11 // Brand: Carrier/Surrey, Model: 619EGX0180E0 A/C
+
12 // Brand: Carrier/Surrey, Model: 619EGX0220E0 A/C
+
13 // Brand: Carrier/Surrey, Model: 53NGK009/012 Inverter
+
14 
+
15 #ifndef IR_CARRIER_H_
+
16 #define IR_CARRIER_H_
+
17 
+
18 #define __STDC_LIMIT_MACROS
+
19 #include <stdint.h>
+
20 #ifndef UNIT_TEST
+
21 #include <Arduino.h>
+
22 #endif
+
23 #include "IRremoteESP8266.h"
+
24 #include "IRsend.h"
+
25 #ifdef UNIT_TEST
+
26 #include "IRsend_test.h"
+
27 #endif
+
28 
+
29 
+
30 // Constants
+
31 
+
32 // CARRIER_AC64
+
33 const uint8_t kCarrierAc64ChecksumOffset = 16;
+
34 const uint8_t kCarrierAc64ChecksumSize = 4;
+ + +
37 const uint8_t kCarrierAc64ModeSize = 2;
+
38 const uint8_t kCarrierAc64Heat = 0b01; // 1
+
39 const uint8_t kCarrierAc64Cool = 0b10; // 2
+
40 const uint8_t kCarrierAc64Fan = 0b11; // 3
+ + +
43 const uint8_t kCarrierAc64FanSize = 2;
+
44 const uint8_t kCarrierAc64FanAuto = 0b00; // 0
+
45 const uint8_t kCarrierAc64FanLow = 0b01; // 1
+
46 const uint8_t kCarrierAc64FanMedium = 0b10; // 2
+
47 const uint8_t kCarrierAc64FanHigh = 0b11; // 3
+ +
49  kCarrierAc64FanSize; // 24
+
50 const uint8_t kCarrierAc64TempSize = 4;
+
51 const uint8_t kCarrierAc64MinTemp = 16; // Celsius
+
52 const uint8_t kCarrierAc64MaxTemp = 30; // Celsius
+ +
54  kCarrierAc64TempSize + 1; // 29
+
55 const uint8_t kCarrierAc64PowerOffset = kCarrierAc64SwingVOffset + 6 + 1; // 36
+ +
57  kCarrierAc64PowerOffset + 1; // 37
+ + +
60 const uint8_t kCarrierAc64SleepOffset =
+ +
62 const uint8_t kCarrierAc64TimerSize = 4;
+
63 const uint8_t kCarrierAc64TimerMax = 9; // Hours.
+
64 const uint8_t kCarrierAc64TimerMin = 1; // Hours.
+ +
66  kCarrierAc64SleepOffset + 12 + 1; // 52
+ +
68  kCarrierAc64TimerSize + 4; // 60
+
69 
+
70 
+
71 // Classes
+
72 
+ +
75  public:
+
76  explicit IRCarrierAc64(const uint16_t pin, const bool inverted = false,
+
77  const bool use_modulation = true);
+
78 
+
79  void stateReset();
+
80 #if SEND_CARRIER_AC64
+
81  void send(const uint16_t repeat = kCarrierAc64MinRepeat);
+
86  int8_t calibrate(void) { return _irsend.calibrate(); }
+
87 #endif // SEND_CARRIER_AC64
+
88  void begin();
+
89  static uint8_t calcChecksum(const uint64_t state);
+
90  static bool validChecksum(const uint64_t state);
+
91  void setPower(const bool on);
+
92  bool getPower();
+
93  void on();
+
94  void off();
+
95  void setTemp(const uint8_t temp);
+
96  uint8_t getTemp();
+
97  void setSwingV(const bool on);
+
98  bool getSwingV(void);
+
99  void setSleep(const bool on);
+
100  bool getSleep(void);
+
101  void setFan(const uint8_t speed);
+
102  uint8_t getFan();
+
103  void setMode(const uint8_t mode);
+
104  uint8_t getMode();
+
105  void setOnTimer(const uint16_t nr_of_mins);
+
106  uint16_t getOnTimer(void);
+
107  void setOffTimer(const uint16_t nr_of_mins);
+
108  uint16_t getOffTimer(void);
+
109  uint64_t getRaw();
+
110  void setRaw(const uint64_t state);
+
111  uint8_t convertMode(const stdAc::opmode_t mode);
+
112  uint8_t convertFan(const stdAc::fanspeed_t speed);
+
113  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
114  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
115  stdAc::state_t toCommon(void);
+
116  String toString();
+
117 #ifndef UNIT_TEST
+
118 
+
119  private:
+ +
121 #else
+
122  IRsendTest _irsend;
+
124 #endif
+
126  uint64_t remote_state;
+
127  void checksum(void);
+
128  void _cancelOnTimer(void);
+
129  void _cancelOffTimer(void);
+
130 };
+
131 #endif // IR_CARRIER_H_
+
+
const uint8_t kCarrierAc64MinTemp
Definition: ir_Carrier.h:51
+
const uint8_t kCarrierAc64TimerMin
Definition: ir_Carrier.h:64
+
void off()
Change the power setting to Off.
Definition: ir_Carrier.cpp:318
+
uint16_t getOffTimer(void)
Get the current Off Timer time.
Definition: ir_Carrier.cpp:474
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Carrier.cpp:304
+
void checksum(void)
Calculate and set the checksum values for the internal state.
Definition: ir_Carrier.cpp:259
+
bool getSwingV(void)
Get the Vertical Swing mode of the A/C.
Definition: ir_Carrier.cpp:412
+
IRCarrierAc64(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Carrier.cpp:228
+
void on()
Change the power setting to On.
Definition: ir_Carrier.cpp:315
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
const uint8_t kCarrierAc64SleepOffset
Definition: ir_Carrier.h:60
+
stdAc::state_t toCommon(void)
Convert the A/C state to it's common stdAc::state_t equivalent.
Definition: ir_Carrier.cpp:523
+
uint64_t remote_state
The state of the IR remote.
Definition: ir_Carrier.h:126
+
const uint8_t kCarrierAc64Heat
Definition: ir_Carrier.h:38
+ +
const uint8_t kCarrierAc64FanSize
Definition: ir_Carrier.h:43
+
uint64_t getRaw()
Get a copy of the internal state as a valid code for this protocol.
Definition: ir_Carrier.cpp:277
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
void _cancelOnTimer(void)
Clear the On Timer enable bit.
Definition: ir_Carrier.cpp:436
+
void begin()
Set up hardware to be able to send a message.
Definition: ir_Carrier.cpp:265
+
const uint8_t kCarrierAc64Cool
Definition: ir_Carrier.h:39
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode to it's common stdAc::opmode_t equivalent.
Definition: ir_Carrier.cpp:355
+
uint8_t getMode()
Get the operating mode setting of the A/C.
Definition: ir_Carrier.cpp:322
+
uint8_t getFan()
Get the current fan speed setting.
Definition: ir_Carrier.cpp:365
+
const uint8_t kCarrierAc64OffTimerOffset
Definition: ir_Carrier.h:67
+
std::string String
Definition: IRremoteESP8266.h:1093
+
const uint8_t kCarrierAc64OnTimerEnableOffset
Definition: ir_Carrier.h:58
+
void setTemp(const uint8_t temp)
Set the temp in deg C.
Definition: ir_Carrier.cpp:288
+
const uint8_t kCarrierAc64OnTimerOffset
Definition: ir_Carrier.h:65
+
uint16_t getOnTimer(void)
Get the current On Timer time.
Definition: ir_Carrier.cpp:443
+
void send(const uint16_t repeat=kCarrierAc64MinRepeat)
Send the current internal state as an IR message.
Definition: ir_Carrier.cpp:270
+
uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Carrier.cpp:381
+
void setOffTimer(const uint16_t nr_of_mins)
Set the Off Timer time.
Definition: ir_Carrier.cpp:486
+
const uint8_t kCarrierAc64TimerMax
Definition: ir_Carrier.h:63
+
const uint8_t kCarrierAc64FanHigh
Definition: ir_Carrier.h:47
+ +
static bool validChecksum(const uint64_t state)
Verify the checksum is valid for a given state.
Definition: ir_Carrier.cpp:252
+
bool getPower()
Get the value of the current power setting.
Definition: ir_Carrier.cpp:310
+
const uint8_t kCarrierAc64FanMedium
Definition: ir_Carrier.h:46
+
const uint8_t kCarrierAc64MaxTemp
Definition: ir_Carrier.h:52
+
Class for handling detailed Carrier 64 bit A/C messages.
Definition: ir_Carrier.h:74
+
uint8_t getTemp()
Get the current temperature from the internal state.
Definition: ir_Carrier.cpp:297
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Carrier.h:120
+
void stateReset()
Reset the internal state to a fixed known good state.
Definition: ir_Carrier.cpp:234
+
const uint8_t kCarrierAc64OffTimerEnableOffset
Definition: ir_Carrier.h:56
+
const uint8_t kCarrierAc64SwingVOffset
Definition: ir_Carrier.h:53
+
static uint8_t calcChecksum(const uint64_t state)
Calculate the checksum for a given state.
Definition: ir_Carrier.cpp:239
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Carrier.h:86
+
void setRaw(const uint64_t state)
Set the internal state from a valid code for this protocol.
Definition: ir_Carrier.cpp:284
+
const uint8_t kCarrierAc64TimerSize
Definition: ir_Carrier.h:62
+
const uint8_t kCarrierAc64Fan
Definition: ir_Carrier.h:40
+
const uint8_t kCarrierAc64ChecksumSize
Definition: ir_Carrier.h:34
+
const uint8_t kCarrierAc64ModeOffset
Definition: ir_Carrier.h:35
+
bool getSleep(void)
Get the Sleep mode of the A/C.
Definition: ir_Carrier.cpp:431
+
void setOnTimer(const uint16_t nr_of_mins)
Set the On Timer time.
Definition: ir_Carrier.cpp:455
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a standard A/C mode into its native mode.
Definition: ir_Carrier.cpp:344
+
const uint16_t kCarrierAc64MinRepeat
Definition: IRremoteESP8266.h:831
+
const uint8_t kCarrierAc64FanLow
Definition: ir_Carrier.h:45
+
const uint8_t kCarrierAc64FanAuto
Definition: ir_Carrier.h:44
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Carrier.cpp:395
+
void setFan(const uint8_t speed)
Set the speed of the fan.
Definition: ir_Carrier.cpp:371
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Carrier.cpp:328
+
void setSwingV(const bool on)
Set the Vertical Swing mode of the A/C.
Definition: ir_Carrier.cpp:406
+
void setSleep(const bool on)
Set the Sleep mode of the A/C.
Definition: ir_Carrier.cpp:418
+
void _cancelOffTimer(void)
Clear the Off Timer enable bit.
Definition: ir_Carrier.cpp:467
+
String toString()
Convert the internal state into a human readable string.
Definition: ir_Carrier.cpp:500
+
const uint8_t kCarrierAc64PowerOffset
Definition: ir_Carrier.h:55
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
const uint8_t kCarrierAc64ModeSize
Definition: ir_Carrier.h:37
+
const uint8_t kCarrierAc64TempOffset
Definition: ir_Carrier.h:48
+
const uint8_t kCarrierAc64TempSize
Definition: ir_Carrier.h:50
+
const uint8_t kCarrierAc64ChecksumOffset
Definition: ir_Carrier.h:33
+
const uint8_t kCarrierAc64FanOffset
Definition: ir_Carrier.h:41
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Coolix_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Coolix_8cpp.html new file mode 100644 index 000000000..d09e7f0cf --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Coolix_8cpp.html @@ -0,0 +1,301 @@ + + + + + + + +IRremoteESP8266: src/ir_Coolix.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Coolix.cpp File Reference
+
+
+ +

Coolix A/C / heatpump. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kCoolixTick = 276
 
const uint16_t kCoolixBitMarkTicks = 2
 
const uint16_t kCoolixBitMark = kCoolixBitMarkTicks * kCoolixTick
 
const uint16_t kCoolixOneSpaceTicks = 6
 
const uint16_t kCoolixOneSpace = kCoolixOneSpaceTicks * kCoolixTick
 
const uint16_t kCoolixZeroSpaceTicks = 2
 
const uint16_t kCoolixZeroSpace = kCoolixZeroSpaceTicks * kCoolixTick
 
const uint16_t kCoolixHdrMarkTicks = 17
 
const uint16_t kCoolixHdrMark = kCoolixHdrMarkTicks * kCoolixTick
 
const uint16_t kCoolixHdrSpaceTicks = 16
 
const uint16_t kCoolixHdrSpace = kCoolixHdrSpaceTicks * kCoolixTick
 
const uint16_t kCoolixMinGapTicks = kCoolixHdrMarkTicks + kCoolixZeroSpaceTicks
 
const uint16_t kCoolixMinGap = kCoolixMinGapTicks * kCoolixTick
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kCoolixBitMark

+ +
+
+ + + + +
const uint16_t kCoolixBitMark = kCoolixBitMarkTicks * kCoolixTick
+
+ +
+
+ +

◆ kCoolixBitMarkTicks

+ +
+
+ + + + +
const uint16_t kCoolixBitMarkTicks = 2
+
+ +
+
+ +

◆ kCoolixHdrMark

+ +
+
+ + + + +
const uint16_t kCoolixHdrMark = kCoolixHdrMarkTicks * kCoolixTick
+
+ +
+
+ +

◆ kCoolixHdrMarkTicks

+ +
+
+ + + + +
const uint16_t kCoolixHdrMarkTicks = 17
+
+ +
+
+ +

◆ kCoolixHdrSpace

+ +
+
+ + + + +
const uint16_t kCoolixHdrSpace = kCoolixHdrSpaceTicks * kCoolixTick
+
+ +
+
+ +

◆ kCoolixHdrSpaceTicks

+ +
+
+ + + + +
const uint16_t kCoolixHdrSpaceTicks = 16
+
+ +
+
+ +

◆ kCoolixMinGap

+ +
+
+ + + + +
const uint16_t kCoolixMinGap = kCoolixMinGapTicks * kCoolixTick
+
+ +
+
+ +

◆ kCoolixMinGapTicks

+ +
+
+ + + + +
const uint16_t kCoolixMinGapTicks = kCoolixHdrMarkTicks + kCoolixZeroSpaceTicks
+
+ +
+
+ +

◆ kCoolixOneSpace

+ +
+
+ + + + +
const uint16_t kCoolixOneSpace = kCoolixOneSpaceTicks * kCoolixTick
+
+ +
+
+ +

◆ kCoolixOneSpaceTicks

+ +
+
+ + + + +
const uint16_t kCoolixOneSpaceTicks = 6
+
+ +
+
+ +

◆ kCoolixTick

+ +
+
+ + + + +
const uint16_t kCoolixTick = 276
+
+ +
+
+ +

◆ kCoolixZeroSpace

+ +
+
+ + + + +
const uint16_t kCoolixZeroSpace = kCoolixZeroSpaceTicks * kCoolixTick
+
+ +
+
+ +

◆ kCoolixZeroSpaceTicks

+ +
+
+ + + + +
const uint16_t kCoolixZeroSpaceTicks = 2
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Coolix_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Coolix_8h.html new file mode 100644 index 000000000..47a8b96fa --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Coolix_8h.html @@ -0,0 +1,768 @@ + + + + + + + +IRremoteESP8266: src/ir_Coolix.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Coolix.h File Reference
+
+
+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRCoolixAC
 Class for handling detailed Coolix A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kCoolixCool = 0b000
 
const uint8_t kCoolixDry = 0b001
 
const uint8_t kCoolixAuto = 0b010
 
const uint8_t kCoolixHeat = 0b011
 
const uint8_t kCoolixFan = 0b100
 
const uint8_t kCoolixModeOffset = 2
 
const uint8_t kCoolixModeSize = 2
 
const uint8_t kCoolixZoneFollowMaskOffset = 19
 
const uint8_t kCoolixFanOffset = 13
 
const uint8_t kCoolixFanSize = 3
 
const uint8_t kCoolixFanMin = 0b100
 
const uint8_t kCoolixFanMed = 0b010
 
const uint8_t kCoolixFanMax = 0b001
 
const uint8_t kCoolixFanAuto = 0b101
 
const uint8_t kCoolixFanAuto0 = 0b000
 
const uint8_t kCoolixFanZoneFollow = 0b110
 
const uint8_t kCoolixFanFixed = 0b111
 
const uint8_t kCoolixTempMin = 17
 
const uint8_t kCoolixTempMax = 30
 
const uint8_t kCoolixTempRange = kCoolixTempMax - kCoolixTempMin + 1
 
const uint8_t kCoolixFanTempCode = 0b1110
 
const uint8_t kCoolixTempOffset = 4
 
const uint8_t kCoolixTempSize = 4
 
const uint8_t kCoolixTempMap [kCoolixTempRange]
 
const uint8_t kCoolixSensorTempMin = 16
 
const uint8_t kCoolixSensorTempMax = 30
 
const uint8_t kCoolixSensorTempIgnoreCode = 0b1111
 
const uint8_t kCoolixSensorTempOffset = 8
 
const uint8_t kCoolixSensorTempSize = 4
 
const uint8_t kCoolixPrefix = 0b1011
 
const uint8_t kCoolixUnknown = 0xFF
 
const uint32_t kCoolixOff = 0b101100100111101111100000
 
const uint32_t kCoolixSwing = 0b101100100110101111100000
 
const uint32_t kCoolixSwingH = 0b101100101111010110100010
 
const uint32_t kCoolixSwingV = 0b101100100000111111100000
 
const uint32_t kCoolixSleep = 0b101100101110000000000011
 
const uint32_t kCoolixTurbo = 0b101101011111010110100010
 
const uint32_t kCoolixLed = 0b101101011111010110100101
 
const uint32_t kCoolixClean = 0b101101011111010110101010
 
const uint32_t kCoolixCmdFan = 0b101100101011111111100100
 
const uint32_t kCoolixDefaultState = 0b101100100001111111001000
 
+

Variable Documentation

+ +

◆ kCoolixAuto

+ +
+
+ + + + +
const uint8_t kCoolixAuto = 0b010
+
+ +
+
+ +

◆ kCoolixClean

+ +
+
+ + + + +
const uint32_t kCoolixClean = 0b101101011111010110101010
+
+ +
+
+ +

◆ kCoolixCmdFan

+ +
+
+ + + + +
const uint32_t kCoolixCmdFan = 0b101100101011111111100100
+
+ +
+
+ +

◆ kCoolixCool

+ +
+
+ + + + +
const uint8_t kCoolixCool = 0b000
+
+ +
+
+ +

◆ kCoolixDefaultState

+ +
+
+ + + + +
const uint32_t kCoolixDefaultState = 0b101100100001111111001000
+
+ +
+
+ +

◆ kCoolixDry

+ +
+
+ + + + +
const uint8_t kCoolixDry = 0b001
+
+ +
+
+ +

◆ kCoolixFan

+ +
+
+ + + + +
const uint8_t kCoolixFan = 0b100
+
+ +
+
+ +

◆ kCoolixFanAuto

+ +
+
+ + + + +
const uint8_t kCoolixFanAuto = 0b101
+
+ +
+
+ +

◆ kCoolixFanAuto0

+ +
+
+ + + + +
const uint8_t kCoolixFanAuto0 = 0b000
+
+ +
+
+ +

◆ kCoolixFanFixed

+ +
+
+ + + + +
const uint8_t kCoolixFanFixed = 0b111
+
+ +
+
+ +

◆ kCoolixFanMax

+ +
+
+ + + + +
const uint8_t kCoolixFanMax = 0b001
+
+ +
+
+ +

◆ kCoolixFanMed

+ +
+
+ + + + +
const uint8_t kCoolixFanMed = 0b010
+
+ +
+
+ +

◆ kCoolixFanMin

+ +
+
+ + + + +
const uint8_t kCoolixFanMin = 0b100
+
+ +
+
+ +

◆ kCoolixFanOffset

+ +
+
+ + + + +
const uint8_t kCoolixFanOffset = 13
+
+ +
+
+ +

◆ kCoolixFanSize

+ +
+
+ + + + +
const uint8_t kCoolixFanSize = 3
+
+ +
+
+ +

◆ kCoolixFanTempCode

+ +
+
+ + + + +
const uint8_t kCoolixFanTempCode = 0b1110
+
+ +
+
+ +

◆ kCoolixFanZoneFollow

+ +
+
+ + + + +
const uint8_t kCoolixFanZoneFollow = 0b110
+
+ +
+
+ +

◆ kCoolixHeat

+ +
+
+ + + + +
const uint8_t kCoolixHeat = 0b011
+
+ +
+
+ +

◆ kCoolixLed

+ +
+
+ + + + +
const uint32_t kCoolixLed = 0b101101011111010110100101
+
+ +
+
+ +

◆ kCoolixModeOffset

+ +
+
+ + + + +
const uint8_t kCoolixModeOffset = 2
+
+ +
+
+ +

◆ kCoolixModeSize

+ +
+
+ + + + +
const uint8_t kCoolixModeSize = 2
+
+ +
+
+ +

◆ kCoolixOff

+ +
+
+ + + + +
const uint32_t kCoolixOff = 0b101100100111101111100000
+
+ +
+
+ +

◆ kCoolixPrefix

+ +
+
+ + + + +
const uint8_t kCoolixPrefix = 0b1011
+
+ +
+
+ +

◆ kCoolixSensorTempIgnoreCode

+ +
+
+ + + + +
const uint8_t kCoolixSensorTempIgnoreCode = 0b1111
+
+ +
+
+ +

◆ kCoolixSensorTempMax

+ +
+
+ + + + +
const uint8_t kCoolixSensorTempMax = 30
+
+ +
+
+ +

◆ kCoolixSensorTempMin

+ +
+
+ + + + +
const uint8_t kCoolixSensorTempMin = 16
+
+ +
+
+ +

◆ kCoolixSensorTempOffset

+ +
+
+ + + + +
const uint8_t kCoolixSensorTempOffset = 8
+
+ +
+
+ +

◆ kCoolixSensorTempSize

+ +
+
+ + + + +
const uint8_t kCoolixSensorTempSize = 4
+
+ +
+
+ +

◆ kCoolixSleep

+ +
+
+ + + + +
const uint32_t kCoolixSleep = 0b101100101110000000000011
+
+ +
+
+ +

◆ kCoolixSwing

+ +
+
+ + + + +
const uint32_t kCoolixSwing = 0b101100100110101111100000
+
+ +
+
+ +

◆ kCoolixSwingH

+ +
+
+ + + + +
const uint32_t kCoolixSwingH = 0b101100101111010110100010
+
+ +
+
+ +

◆ kCoolixSwingV

+ +
+
+ + + + +
const uint32_t kCoolixSwingV = 0b101100100000111111100000
+
+ +
+
+ +

◆ kCoolixTempMap

+ +
+
+ + + + +
const uint8_t kCoolixTempMap[kCoolixTempRange]
+
+Initial value:
= {
+
0b0000,
+
0b0001,
+
0b0011,
+
0b0010,
+
0b0110,
+
0b0111,
+
0b0101,
+
0b0100,
+
0b1100,
+
0b1101,
+
0b1001,
+
0b1000,
+
0b1010,
+
0b1011
+
}
+
+
+
+ +

◆ kCoolixTempMax

+ +
+
+ + + + +
const uint8_t kCoolixTempMax = 30
+
+ +
+
+ +

◆ kCoolixTempMin

+ +
+
+ + + + +
const uint8_t kCoolixTempMin = 17
+
+ +
+
+ +

◆ kCoolixTempOffset

+ +
+
+ + + + +
const uint8_t kCoolixTempOffset = 4
+
+ +
+
+ +

◆ kCoolixTempRange

+ +
+
+ + + + +
const uint8_t kCoolixTempRange = kCoolixTempMax - kCoolixTempMin + 1
+
+ +
+
+ +

◆ kCoolixTempSize

+ +
+
+ + + + +
const uint8_t kCoolixTempSize = 4
+
+ +
+
+ +

◆ kCoolixTurbo

+ +
+
+ + + + +
const uint32_t kCoolixTurbo = 0b101101011111010110100010
+
+ +
+
+ +

◆ kCoolixUnknown

+ +
+
+ + + + +
const uint8_t kCoolixUnknown = 0xFF
+
+ +
+
+ +

◆ kCoolixZoneFollowMaskOffset

+ +
+
+ + + + +
const uint8_t kCoolixZoneFollowMaskOffset = 19
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Coolix_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Coolix_8h_source.html new file mode 100644 index 000000000..570f91033 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Coolix_8h_source.html @@ -0,0 +1,365 @@ + + + + + + + +IRremoteESP8266: src/ir_Coolix.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Coolix.h
+
+
+Go to the documentation of this file.
1 // Coolix A/C
+
2 //
+
3 // Copyright 2018 David Conran
+
4 
+
5 // Supports:
+
6 // Brand: Beko, Model: RG57K7(B)/BGEF Remote
+
7 // Brand: Beko, Model: BINR 070/071 split-type A/C
+
8 // Brand: Midea, Model: RG52D/BGE Remote
+
9 // Brand: Midea, Model: MS12FU-10HRDN1-QRD0GW(B) A/C
+
10 // Brand: Midea, Model: MSABAU-07HRFN1-QRD0GW A/C (circa 2016)
+
11 // Brand: Tokio, Model: AATOEMF17-12CHR1SW split-type RG51|50/BGE Remote
+
12 // Brand: Airwell, Model: RC08B remote
+
13 
+
14 #ifndef IR_COOLIX_H_
+
15 #define IR_COOLIX_H_
+
16 
+
17 #define __STDC_LIMIT_MACROS
+
18 #include <stdint.h>
+
19 #ifndef UNIT_TEST
+
20 #include <Arduino.h>
+
21 #endif
+
22 #include "IRremoteESP8266.h"
+
23 #include "IRsend.h"
+
24 #ifdef UNIT_TEST
+
25 #include "IRsend_test.h"
+
26 #endif
+
27 
+
28 // Ref:
+
29 // https://github.com/crankyoldgit/IRremoteESP8266/issues/484
+
30 // Kudos:
+
31 // Hamper: For the breakdown and mapping of the bit values.
+
32 
+
33 // Constants
+
34 // Modes
+
35 const uint8_t kCoolixCool = 0b000;
+
36 const uint8_t kCoolixDry = 0b001;
+
37 const uint8_t kCoolixAuto = 0b010;
+
38 const uint8_t kCoolixHeat = 0b011;
+
39 const uint8_t kCoolixFan = 0b100; // Synthetic.
+
40 // const uint32_t kCoolixModeMask = 0b000000000000000000001100; // 0xC
+
41 const uint8_t kCoolixModeOffset = 2;
+
42 const uint8_t kCoolixModeSize = 2;
+
43 // const uint32_t kCoolixZoneFollowMask = 0b000010000000000000000000 0x80000
+
44 const uint8_t kCoolixZoneFollowMaskOffset = 19;
+
45 // Fan Control
+
46 // const uint32_t kCoolixFanMask = 0b000000001110000000000000; // 0x00E000
+
47 const uint8_t kCoolixFanOffset = 13;
+
48 const uint8_t kCoolixFanSize = 3;
+
49 const uint8_t kCoolixFanMin = 0b100;
+
50 const uint8_t kCoolixFanMed = 0b010;
+
51 const uint8_t kCoolixFanMax = 0b001;
+
52 const uint8_t kCoolixFanAuto = 0b101;
+
53 const uint8_t kCoolixFanAuto0 = 0b000;
+
54 const uint8_t kCoolixFanZoneFollow = 0b110;
+
55 const uint8_t kCoolixFanFixed = 0b111;
+
56 // Temperature
+
57 const uint8_t kCoolixTempMin = 17; // Celsius
+
58 const uint8_t kCoolixTempMax = 30; // Celsius
+ +
60 const uint8_t kCoolixFanTempCode = 0b1110; // Part of Fan Mode.
+
61 // const uint32_t kCoolixTempMask = 0b11110000;
+
62 const uint8_t kCoolixTempOffset = 4;
+
63 const uint8_t kCoolixTempSize = 4;
+
64 const uint8_t kCoolixTempMap[kCoolixTempRange] = {
+
65  0b0000, // 17C
+
66  0b0001, // 18c
+
67  0b0011, // 19C
+
68  0b0010, // 20C
+
69  0b0110, // 21C
+
70  0b0111, // 22C
+
71  0b0101, // 23C
+
72  0b0100, // 24C
+
73  0b1100, // 25C
+
74  0b1101, // 26C
+
75  0b1001, // 27C
+
76  0b1000, // 28C
+
77  0b1010, // 29C
+
78  0b1011 // 30C
+
79 };
+
80 const uint8_t kCoolixSensorTempMin = 16; // Celsius
+
81 const uint8_t kCoolixSensorTempMax = 30; // Celsius
+
82 const uint8_t kCoolixSensorTempIgnoreCode = 0b1111;
+
83 // kCoolixSensorTempMask = 0b000000000000111100000000; // 0xF00
+
84 const uint8_t kCoolixSensorTempOffset = 8;
+
85 const uint8_t kCoolixSensorTempSize = 4;
+
86 // Fixed states/messages.
+
87 const uint8_t kCoolixPrefix = 0b1011; // 0xB
+
88 const uint8_t kCoolixUnknown = 0xFF;
+
89 const uint32_t kCoolixOff = 0b101100100111101111100000; // 0xB27BE0
+
90 const uint32_t kCoolixSwing = 0b101100100110101111100000; // 0xB26BE0
+
91 const uint32_t kCoolixSwingH = 0b101100101111010110100010; // 0xB5F5A2
+
92 const uint32_t kCoolixSwingV = 0b101100100000111111100000; // 0xB20FE0
+
93 const uint32_t kCoolixSleep = 0b101100101110000000000011; // 0xB2E003
+
94 const uint32_t kCoolixTurbo = 0b101101011111010110100010; // 0xB5F5A2
+
95 const uint32_t kCoolixLed = 0b101101011111010110100101; // 0xB5F5A5
+
96 const uint32_t kCoolixClean = 0b101101011111010110101010; // 0xB5F5AA
+
97 const uint32_t kCoolixCmdFan = 0b101100101011111111100100; // 0xB2BFE4
+
98 // On, 25C, Mode: Auto, Fan: Auto, Zone Follow: Off, Sensor Temp: Ignore.
+
99 const uint32_t kCoolixDefaultState = 0b101100100001111111001000; // 0xB21FC8
+
100 
+
101 // Classes
+
102 
+
105 class IRCoolixAC {
+
106  public:
+
107  explicit IRCoolixAC(const uint16_t pin, const bool inverted = false,
+
108  const bool use_modulation = true);
+
109  void stateReset();
+
110 #if SEND_COOLIX
+
111  void send(const uint16_t repeat = kCoolixDefaultRepeat);
+
116  int8_t calibrate(void) { return _irsend.calibrate(); }
+
117 #endif // SEND_COOLIX
+
118  void begin();
+
119  void on();
+
120  void off();
+
121  void setPower(const bool state);
+
122  bool getPower();
+
123  void setTemp(const uint8_t temp);
+
124  uint8_t getTemp();
+
125  void setSensorTemp(const uint8_t desired);
+
126  uint8_t getSensorTemp();
+
127  void clearSensorTemp();
+
128  void setFan(const uint8_t speed, const bool modecheck = true);
+
129  uint8_t getFan();
+
130  void setMode(const uint8_t mode);
+
131  uint8_t getMode();
+
132  void setSwing();
+
133  bool getSwing();
+
134  void setSleep();
+
135  bool getSleep();
+
136  void setTurbo();
+
137  bool getTurbo();
+
138  void setLed();
+
139  bool getLed();
+
140  void setClean();
+
141  bool getClean();
+
142  bool getZoneFollow();
+
143  uint32_t getRaw();
+
144  void setRaw(const uint32_t new_code);
+
145  uint8_t convertMode(const stdAc::opmode_t mode);
+
146  uint8_t convertFan(const stdAc::fanspeed_t speed);
+
147  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
148  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
149  stdAc::state_t toCommon(const stdAc::state_t *prev = NULL);
+
150  String toString();
+
151 #ifndef UNIT_TEST
+
152 
+
153  private:
+ +
155 #else
+
156  IRsendTest _irsend;
+
158 #endif
+
160  // internal state
+
161  bool powerFlag;
+
162  bool turboFlag;
+
163  bool ledFlag;
+
164  bool cleanFlag;
+
165  bool sleepFlag;
+ +
167  bool swingFlag;
+ + +
170 
+
171  uint32_t remote_state;
+
172  uint32_t saved_state;
+
173  void setTempRaw(const uint8_t code);
+
174  uint8_t getTempRaw();
+
175  void setSensorTempRaw(const uint8_t code);
+
176  void setZoneFollow(const bool on);
+
177  bool isSpecialState(void);
+
178  bool handleSpecialState(const uint32_t data);
+
179  void updateSavedState(void);
+
180  void recoverSavedState(void);
+
181  uint32_t getNormalState(void);
+
182 };
+
183 
+
184 #endif // IR_COOLIX_H_
+
+
void setLed()
Toggle the Led (light) mode of the A/C.
Definition: ir_Coolix.cpp:325
+
const uint8_t kCoolixFanSize
Definition: ir_Coolix.h:48
+
const uint8_t kCoolixZoneFollowMaskOffset
Definition: ir_Coolix.h:44
+
bool zoneFollowFlag
Definition: ir_Coolix.h:166
+
const uint8_t kCoolixFanZoneFollow
Definition: ir_Coolix.h:54
+
uint32_t getNormalState(void)
+
void setTempRaw(const uint8_t code)
Set the raw (native) temperature value.
Definition: ir_Coolix.cpp:206
+
void setSensorTempRaw(const uint8_t code)
Set the raw (native) sensor temperature value.
Definition: ir_Coolix.cpp:237
+
bool getTurbo()
Get the Turbo setting of the A/C.
Definition: ir_Coolix.cpp:310
+
const uint8_t kCoolixFanMin
Definition: ir_Coolix.h:49
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Coolix.h:116
+
void setZoneFollow(const bool on)
Change the Zone Follow setting.
Definition: ir_Coolix.cpp:352
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Coolix.cpp:365
+
const uint32_t kCoolixSwingH
Definition: ir_Coolix.h:91
+
uint32_t remote_state
The state of the IR remote in IR code form.
Definition: ir_Coolix.h:171
+
void send(const uint16_t repeat=kCoolixDefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Coolix.cpp:112
+
bool getZoneFollow()
Get the Zone Follow setting of the A/C.
Definition: ir_Coolix.cpp:345
+
const uint8_t kCoolixFanAuto0
Definition: ir_Coolix.h:53
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
const uint8_t kCoolixDry
Definition: ir_Coolix.h:36
+
void setClean()
Toggle the Clean mode of the A/C.
Definition: ir_Coolix.cpp:337
+
uint8_t getTemp()
Get the current temperature setting.
Definition: ir_Coolix.cpp:227
+
const uint8_t kCoolixFanMed
Definition: ir_Coolix.h:50
+
bool getSwing()
Get the Swing setting of the A/C.
Definition: ir_Coolix.cpp:287
+
const uint8_t kCoolixTempSize
Definition: ir_Coolix.h:63
+
uint8_t getSensorTemp()
Get the sensor temperature setting.
Definition: ir_Coolix.cpp:253
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Coolix.h:154
+
bool turboFlag
Definition: ir_Coolix.h:162
+
const uint8_t kCoolixSensorTempMin
Definition: ir_Coolix.h:80
+ +
bool ledFlag
Definition: ir_Coolix.h:163
+
const uint32_t kCoolixSwing
Definition: ir_Coolix.h:90
+
const uint8_t kCoolixCool
Definition: ir_Coolix.h:35
+
const uint8_t kCoolixAuto
Definition: ir_Coolix.h:37
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
bool cleanFlag
Definition: ir_Coolix.h:164
+
uint32_t getRaw()
Get a copy of the internal state as a valid code for this protocol.
Definition: ir_Coolix.cpp:122
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Coolix.cpp:488
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
void updateSavedState(void)
Backup the current internal state as long as it isn't a special state.
Definition: ir_Coolix.cpp:189
+
const uint8_t kCoolixHeat
Definition: ir_Coolix.h:38
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a standard A/C mode into its native mode.
Definition: ir_Coolix.cpp:448
+
const uint32_t kCoolixOff
Definition: ir_Coolix.h:89
+
stdAc::state_t toCommon(const stdAc::state_t *prev=NULL)
Convert the A/C state to it's common stdAc::state_t equivalent.
Definition: ir_Coolix.cpp:500
+
std::string String
Definition: IRremoteESP8266.h:1093
+
void recoverSavedState(void)
Restore the current internal state from backup as long as it isn't a special state.
Definition: ir_Coolix.cpp:195
+
void setTurbo()
Toggle the Turbo mode of the A/C.
Definition: ir_Coolix.cpp:313
+
const uint8_t kCoolixSensorTempSize
Definition: ir_Coolix.h:85
+
const uint8_t kCoolixFanTempCode
Definition: ir_Coolix.h:60
+
bool swingVFlag
Definition: ir_Coolix.h:169
+
bool getClean()
Get the Clean setting of the A/C.
Definition: ir_Coolix.cpp:334
+
void on()
Change the power setting to On.
Definition: ir_Coolix.cpp:280
+ +
const uint8_t kCoolixTempMap[kCoolixTempRange]
Definition: ir_Coolix.h:64
+
void clearSensorTemp()
Clear the Sensor Temperature setting..
Definition: ir_Coolix.cpp:358
+
const uint32_t kCoolixClean
Definition: ir_Coolix.h:96
+
const uint8_t kCoolixFanFixed
Definition: ir_Coolix.h:55
+
const uint8_t kCoolixModeSize
Definition: ir_Coolix.h:42
+
void stateReset()
Reset the internal state to a fixed known good state.
Definition: ir_Coolix.cpp:93
+
const uint32_t kCoolixDefaultState
Definition: ir_Coolix.h:99
+
const uint16_t kCoolixDefaultRepeat
Definition: IRremoteESP8266.h:825
+
uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Coolix.cpp:461
+
void setSleep()
Toggle the Sleep mode of the A/C.
Definition: ir_Coolix.cpp:302
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode to it's common stdAc::opmode_t equivalent.
Definition: ir_Coolix.cpp:475
+
uint32_t saved_state
Copy of the state if we required a special mode.
Definition: ir_Coolix.h:172
+
bool isSpecialState(void)
Is the current state is a special state?
Definition: ir_Coolix.cpp:142
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Coolix.cpp:218
+
const uint8_t kCoolixTempOffset
Definition: ir_Coolix.h:62
+
Class for handling detailed Coolix A/C messages.
Definition: ir_Coolix.h:105
+
uint8_t getMode()
Get the operating mode setting of the A/C.
Definition: ir_Coolix.cpp:393
+
uint8_t getFan()
Get the current fan speed setting.
Definition: ir_Coolix.cpp:403
+
const uint32_t kCoolixLed
Definition: ir_Coolix.h:95
+
const uint8_t kCoolixUnknown
Definition: ir_Coolix.h:88
+
void begin()
Set up hardware to be able to send a message.
Definition: ir_Coolix.cpp:107
+
void setRaw(const uint32_t new_code)
Set the internal state from a valid code for this protocol.
Definition: ir_Coolix.cpp:126
+
uint8_t getTempRaw()
Get the raw (native) temperature value.
Definition: ir_Coolix.cpp:212
+
const uint8_t kCoolixFanOffset
Definition: ir_Coolix.h:47
+
const uint32_t kCoolixCmdFan
Definition: ir_Coolix.h:97
+
const uint8_t kCoolixTempMax
Definition: ir_Coolix.h:58
+
bool swingFlag
Definition: ir_Coolix.h:167
+
const uint8_t kCoolixFan
Definition: ir_Coolix.h:39
+
const uint32_t kCoolixSwingV
Definition: ir_Coolix.h:92
+
bool swingHFlag
Definition: ir_Coolix.h:168
+
void off()
Change the power setting to Off.
Definition: ir_Coolix.cpp:283
+
bool sleepFlag
Definition: ir_Coolix.h:165
+
const uint32_t kCoolixSleep
Definition: ir_Coolix.h:93
+
void setSensorTemp(const uint8_t desired)
Set the sensor temperature.
Definition: ir_Coolix.cpp:243
+
IRCoolixAC(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Coolix.cpp:88
+
const uint8_t kCoolixPrefix
Definition: ir_Coolix.h:87
+
const uint8_t kCoolixTempRange
Definition: ir_Coolix.h:59
+
const uint8_t kCoolixTempMin
Definition: ir_Coolix.h:57
+
const uint8_t kCoolixSensorTempMax
Definition: ir_Coolix.h:81
+
const uint8_t kCoolixModeOffset
Definition: ir_Coolix.h:41
+
const uint8_t kCoolixFanMax
Definition: ir_Coolix.h:51
+
const uint8_t kCoolixSensorTempOffset
Definition: ir_Coolix.h:84
+
const uint8_t kCoolixFanAuto
Definition: ir_Coolix.h:52
+
bool powerFlag
Definition: ir_Coolix.h:161
+
String toString()
Convert the internal state into a human readable string.
Definition: ir_Coolix.cpp:559
+
bool getPower()
Get the value of the current power setting.
Definition: ir_Coolix.cpp:260
+
void setFan(const uint8_t speed, const bool modecheck=true)
Set the speed of the fan.
Definition: ir_Coolix.cpp:410
+
bool handleSpecialState(const uint32_t data)
Adjust any internal settings based on the type of special state we are supplied. Does nothing if it i...
Definition: ir_Coolix.cpp:160
+
bool getSleep()
Get the Sleep setting of the A/C.
Definition: ir_Coolix.cpp:299
+
void setPower(const bool state)
Change the power setting.
Definition: ir_Coolix.cpp:267
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
void setSwing()
Toggle the Swing mode of the A/C.
Definition: ir_Coolix.cpp:290
+
const uint8_t kCoolixSensorTempIgnoreCode
Definition: ir_Coolix.h:82
+
const uint32_t kCoolixTurbo
Definition: ir_Coolix.h:94
+
bool getLed()
Get the Led (light) setting of the A/C.
Definition: ir_Coolix.cpp:322
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Corona_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Corona_8cpp.html new file mode 100644 index 000000000..ba795e56d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Corona_8cpp.html @@ -0,0 +1,256 @@ + + + + + + + +IRremoteESP8266: src/ir_Corona.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Corona.cpp File Reference
+
+
+ +

Corona A/C protocol. +More...

+ + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kCoronaAcHdrMark = 3500
 
const uint16_t kCoronaAcHdrSpace = 1680
 
const uint16_t kCoronaAcBitMark = 450
 
const uint16_t kCoronaAcOneSpace = 1270
 
const uint16_t kCoronaAcZeroSpace = 420
 
const uint16_t kCoronaAcSpaceGap = 10800
 
const uint16_t kCoronaAcFreq = 38000
 
const uint16_t kCoronaAcOverheadShort = 3
 
const uint16_t kCoronaAcOverhead = 11
 
const uint8_t kCoronaTolerance = 5
 
+

Detailed Description

+

Corona A/C protocol.

+
Note
Unsupported:
    +
  • Auto/Max button press (special format)
  • +
+
+

Variable Documentation

+ +

◆ kCoronaAcBitMark

+ +
+
+ + + + +
const uint16_t kCoronaAcBitMark = 450
+
+ +
+
+ +

◆ kCoronaAcFreq

+ +
+
+ + + + +
const uint16_t kCoronaAcFreq = 38000
+
+ +
+
+ +

◆ kCoronaAcHdrMark

+ +
+
+ + + + +
const uint16_t kCoronaAcHdrMark = 3500
+
+ +
+
+ +

◆ kCoronaAcHdrSpace

+ +
+
+ + + + +
const uint16_t kCoronaAcHdrSpace = 1680
+
+ +
+
+ +

◆ kCoronaAcOneSpace

+ +
+
+ + + + +
const uint16_t kCoronaAcOneSpace = 1270
+
+ +
+
+ +

◆ kCoronaAcOverhead

+ +
+
+ + + + +
const uint16_t kCoronaAcOverhead = 11
+
+ +
+
+ +

◆ kCoronaAcOverheadShort

+ +
+
+ + + + +
const uint16_t kCoronaAcOverheadShort = 3
+
+ +
+
+ +

◆ kCoronaAcSpaceGap

+ +
+
+ + + + +
const uint16_t kCoronaAcSpaceGap = 10800
+
+ +
+
+ +

◆ kCoronaAcZeroSpace

+ +
+
+ + + + +
const uint16_t kCoronaAcZeroSpace = 420
+
+ +
+
+ +

◆ kCoronaTolerance

+ +
+
+ + + + +
const uint8_t kCoronaTolerance = 5
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Corona_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Corona_8h.html new file mode 100644 index 000000000..62a551867 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Corona_8h.html @@ -0,0 +1,730 @@ + + + + + + + +IRremoteESP8266: src/ir_Corona.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Corona.h File Reference
+
+
+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRCoronaAc
 Class for handling detailed Corona A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kCoronaAcSectionBytes = 7
 
const uint8_t kCoronaAcSections = 3
 
const uint8_t kCoronaAcSectionHeader0Pos = 0
 
const uint8_t kCoronaAcSectionHeader0 = 0x28
 
const uint8_t kCoronaAcSectionHeader1Pos = 1
 
const uint8_t kCoronaAcSectionHeader1 = 0x61
 
const uint8_t kCoronaAcSectionLabelPos = 2
 
const uint8_t kCoronaAcSectionLabelBase = 0x0D
 
const uint8_t kCoronaAcSectionData0Pos = 3
 
const uint8_t kCoronaAcSectionData0InvPos = 4
 
const uint8_t kCoronaAcSectionData1Pos = 5
 
const uint8_t kCoronaAcSectionData1InvPos = 6
 
const uint8_t kCoronaAcSectionData0Base = 0x10
 
const uint8_t kCoronaAcSettingsSection = 0
 
const uint8_t kCoronaAcFanOffset = 0
 
const uint8_t kCoronaAcFanSize = 2
 
const uint8_t kCoronaAcFanAuto = 0b00
 
const uint8_t kCoronaAcFanLow = 0b01
 
const uint8_t kCoronaAcFanMedium = 0b10
 
const uint8_t kCoronaAcFanHigh = 0b11
 
const uint8_t kCoronaAcPowerSaveOffset = 3
 
const uint8_t kCoronaAcSwingVToggleOffset = 6
 
const uint8_t kCoronaAcTempOffset = 0
 
const uint8_t kCoronaAcTempSize = 4
 
const uint8_t kCoronaAcMinTemp = 17
 
const uint8_t kCoronaAcMaxTemp = 30
 
const uint8_t kCoronaAcPowerOffset
 
const uint8_t kCoronaAcPowerButtonOffset
 
const uint8_t kCoronaAcModeOffset
 
const uint8_t kCoronaAcModeSize = 2
 
const uint8_t kCoronaAcModeHeat = 0b00
 
const uint8_t kCoronaAcModeDry = 0b01
 
const uint8_t kCoronaAcModeCool = 0b10
 
const uint8_t kCoronaAcModeFan = 0b11
 
const uint8_t kCoronaAcOnTimerSection = 1
 
const uint8_t kCoronaAcOffTimerSection = 2
 
const uint16_t kCoronaAcTimerMax = 12 * 60
 
const uint16_t kCoronaAcTimerOff = 0xffff
 
const uint16_t kCoronaAcTimerUnitsPerMin = 30
 
+

Variable Documentation

+ +

◆ kCoronaAcFanAuto

+ +
+
+ + + + +
const uint8_t kCoronaAcFanAuto = 0b00
+
+ +
+
+ +

◆ kCoronaAcFanHigh

+ +
+
+ + + + +
const uint8_t kCoronaAcFanHigh = 0b11
+
+ +
+
+ +

◆ kCoronaAcFanLow

+ +
+
+ + + + +
const uint8_t kCoronaAcFanLow = 0b01
+
+ +
+
+ +

◆ kCoronaAcFanMedium

+ +
+
+ + + + +
const uint8_t kCoronaAcFanMedium = 0b10
+
+ +
+
+ +

◆ kCoronaAcFanOffset

+ +
+
+ + + + +
const uint8_t kCoronaAcFanOffset = 0
+
+ +
+
+ +

◆ kCoronaAcFanSize

+ +
+
+ + + + +
const uint8_t kCoronaAcFanSize = 2
+
+ +
+
+ +

◆ kCoronaAcMaxTemp

+ +
+
+ + + + +
const uint8_t kCoronaAcMaxTemp = 30
+
+ +
+
+ +

◆ kCoronaAcMinTemp

+ +
+
+ + + + +
const uint8_t kCoronaAcMinTemp = 17
+
+ +
+
+ +

◆ kCoronaAcModeCool

+ +
+
+ + + + +
const uint8_t kCoronaAcModeCool = 0b10
+
+ +
+
+ +

◆ kCoronaAcModeDry

+ +
+
+ + + + +
const uint8_t kCoronaAcModeDry = 0b01
+
+ +
+
+ +

◆ kCoronaAcModeFan

+ +
+
+ + + + +
const uint8_t kCoronaAcModeFan = 0b11
+
+ +
+
+ +

◆ kCoronaAcModeHeat

+ +
+
+ + + + +
const uint8_t kCoronaAcModeHeat = 0b00
+
+ +
+
+ +

◆ kCoronaAcModeOffset

+ +
+
+ + + + +
const uint8_t kCoronaAcModeOffset
+
+Initial value: +
+
+ +

◆ kCoronaAcModeSize

+ +
+
+ + + + +
const uint8_t kCoronaAcModeSize = 2
+
+ +
+
+ +

◆ kCoronaAcOffTimerSection

+ +
+
+ + + + +
const uint8_t kCoronaAcOffTimerSection = 2
+
+ +
+
+ +

◆ kCoronaAcOnTimerSection

+ +
+
+ + + + +
const uint8_t kCoronaAcOnTimerSection = 1
+
+ +
+
+ +

◆ kCoronaAcPowerButtonOffset

+ +
+
+ + + + +
const uint8_t kCoronaAcPowerButtonOffset
+
+Initial value: +
+
+ +

◆ kCoronaAcPowerOffset

+ +
+
+ + + + +
const uint8_t kCoronaAcPowerOffset
+
+Initial value: +
+
+ +

◆ kCoronaAcPowerSaveOffset

+ +
+
+ + + + +
const uint8_t kCoronaAcPowerSaveOffset = 3
+
+ +
+
+ +

◆ kCoronaAcSectionBytes

+ +
+
+ + + + +
const uint8_t kCoronaAcSectionBytes = 7
+
+ +
+
+ +

◆ kCoronaAcSectionData0Base

+ +
+
+ + + + +
const uint8_t kCoronaAcSectionData0Base = 0x10
+
+ +
+
+ +

◆ kCoronaAcSectionData0InvPos

+ +
+
+ + + + +
const uint8_t kCoronaAcSectionData0InvPos = 4
+
+ +
+
+ +

◆ kCoronaAcSectionData0Pos

+ +
+
+ + + + +
const uint8_t kCoronaAcSectionData0Pos = 3
+
+ +
+
+ +

◆ kCoronaAcSectionData1InvPos

+ +
+
+ + + + +
const uint8_t kCoronaAcSectionData1InvPos = 6
+
+ +
+
+ +

◆ kCoronaAcSectionData1Pos

+ +
+
+ + + + +
const uint8_t kCoronaAcSectionData1Pos = 5
+
+ +
+
+ +

◆ kCoronaAcSectionHeader0

+ +
+
+ + + + +
const uint8_t kCoronaAcSectionHeader0 = 0x28
+
+ +
+
+ +

◆ kCoronaAcSectionHeader0Pos

+ +
+
+ + + + +
const uint8_t kCoronaAcSectionHeader0Pos = 0
+
+ +
+
+ +

◆ kCoronaAcSectionHeader1

+ +
+
+ + + + +
const uint8_t kCoronaAcSectionHeader1 = 0x61
+
+ +
+
+ +

◆ kCoronaAcSectionHeader1Pos

+ +
+
+ + + + +
const uint8_t kCoronaAcSectionHeader1Pos = 1
+
+ +
+
+ +

◆ kCoronaAcSectionLabelBase

+ +
+
+ + + + +
const uint8_t kCoronaAcSectionLabelBase = 0x0D
+
+ +
+
+ +

◆ kCoronaAcSectionLabelPos

+ +
+
+ + + + +
const uint8_t kCoronaAcSectionLabelPos = 2
+
+ +
+
+ +

◆ kCoronaAcSections

+ +
+
+ + + + +
const uint8_t kCoronaAcSections = 3
+
+ +
+
+ +

◆ kCoronaAcSettingsSection

+ +
+
+ + + + +
const uint8_t kCoronaAcSettingsSection = 0
+
+ +
+
+ +

◆ kCoronaAcSwingVToggleOffset

+ +
+
+ + + + +
const uint8_t kCoronaAcSwingVToggleOffset = 6
+
+ +
+
+ +

◆ kCoronaAcTempOffset

+ +
+
+ + + + +
const uint8_t kCoronaAcTempOffset = 0
+
+ +
+
+ +

◆ kCoronaAcTempSize

+ +
+
+ + + + +
const uint8_t kCoronaAcTempSize = 4
+
+ +
+
+ +

◆ kCoronaAcTimerMax

+ +
+
+ + + + +
const uint16_t kCoronaAcTimerMax = 12 * 60
+
+ +
+
+ +

◆ kCoronaAcTimerOff

+ +
+
+ + + + +
const uint16_t kCoronaAcTimerOff = 0xffff
+
+ +
+
+ +

◆ kCoronaAcTimerUnitsPerMin

+ +
+
+ + + + +
const uint16_t kCoronaAcTimerUnitsPerMin = 30
+
+ +
+
+
+
const uint8_t kCoronaAcTempOffset
Definition: ir_Corona.h:67
+
const uint8_t kCoronaAcTempSize
Definition: ir_Corona.h:68
+
const uint8_t kCoronaAcPowerOffset
Definition: ir_Corona.h:71
+
const uint8_t kCoronaAcPowerButtonOffset
Definition: ir_Corona.h:73
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Corona_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Corona_8h_source.html new file mode 100644 index 000000000..61f778b49 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Corona_8h_source.html @@ -0,0 +1,319 @@ + + + + + + + +IRremoteESP8266: src/ir_Corona.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Corona.h
+
+
+Go to the documentation of this file.
1 // Corona A/C
+
2 //
+
3 // Copyright 2020 Christian Nilsson
+
4 
+
5 // Supports:
+
6 // Brand: Corona, Model: CSH-N2211 A/C
+
7 // Brand: Corona, Model: CSH-N2511 A/C
+
8 // Brand: Corona, Model: CSH-N2811 A/C
+
9 // Brand: Corona, Model: CSH-N4011 A/C
+
10 // Brand: Corona, Model: AR-01 remote
+
11 //
+
12 // Ref: https://docs.google.com/spreadsheets/d/1zzDEUQ52y7MZ7_xCU3pdjdqbRXOwZLsbTGvKWcicqCI/
+
13 // Ref: https://www.corona.co.jp/box/download.php?id=145060636229
+
14 
+
15 #ifndef IR_CORONA_H_
+
16 #define IR_CORONA_H_
+
17 
+
18 #define __STDC_LIMIT_MACROS
+
19 #include <stdint.h>
+
20 #ifndef UNIT_TEST
+
21 #include <Arduino.h>
+
22 #endif
+
23 #include "IRremoteESP8266.h"
+
24 #include "IRsend.h"
+
25 #ifdef UNIT_TEST
+
26 #include "IRsend_test.h"
+
27 #endif
+
28 
+
29 // Constants
+
30 
+
31 // CORONA_AC
+
32 const uint8_t kCoronaAcSectionBytes = 7; // kCoronaAcStateLengthShort
+
33 const uint8_t kCoronaAcSections = 3;
+
34 const uint8_t kCoronaAcSectionHeader0Pos = 0;
+
35 const uint8_t kCoronaAcSectionHeader0 = 0x28;
+
36 const uint8_t kCoronaAcSectionHeader1Pos = 1;
+
37 const uint8_t kCoronaAcSectionHeader1 = 0x61;
+
38 const uint8_t kCoronaAcSectionLabelPos = 2;
+
39 const uint8_t kCoronaAcSectionLabelBase = 0x0D; // 0b1101
+
40 const uint8_t kCoronaAcSectionData0Pos = 3;
+
41 const uint8_t kCoronaAcSectionData0InvPos = 4;
+
42 const uint8_t kCoronaAcSectionData1Pos = 5;
+
43 const uint8_t kCoronaAcSectionData1InvPos = 6;
+
44 const uint8_t kCoronaAcSectionData0Base = 0x10; // D0 Pos 4 always on
+
45 
+
46 const uint8_t kCoronaAcSettingsSection = 0;
+
47 // D0
+
48 const uint8_t kCoronaAcFanOffset = 0; // D0 LSB Pos 0-1
+
49 const uint8_t kCoronaAcFanSize = 2;
+
50 const uint8_t kCoronaAcFanAuto = 0b00; // 0
+
51 const uint8_t kCoronaAcFanLow = 0b01; // 1
+
52 const uint8_t kCoronaAcFanMedium = 0b10; // 2
+
53 const uint8_t kCoronaAcFanHigh = 0b11; // 3
+
54 
+
55 // One bit unknown // D0 Pos 2
+
56 const uint8_t kCoronaAcPowerSaveOffset = 3; // D0 Pos 3
+
57 // One bit unknown always on // D0 Pos 4
+
58 // One bit unknown // D0 Pos 5
+
59 const uint8_t kCoronaAcSwingVToggleOffset = 6; // D0 Pos 6
+
60 // One bit unknown // D0 MSB Pos 7
+
61 
+
62 // D1
+
63 /* full auto mode not supported by this code yet
+
64 const uint8_t kCoronaAcAutoD0 = 0b00010100; // only combined with power save
+
65 const uint8_t kCoronaAcAutoD1 = 0b10000011; // only combined with power
+
66 */
+
67 const uint8_t kCoronaAcTempOffset = 0; // D1 LSB Pos 0
+
68 const uint8_t kCoronaAcTempSize = 4;
+
69 const uint8_t kCoronaAcMinTemp = 17; // Celsius = 0b0001
+
70 const uint8_t kCoronaAcMaxTemp = 30; // Celsius = 0b1110
+
71 const uint8_t kCoronaAcPowerOffset =
+ + +
74  kCoronaAcPowerOffset + 1; // D1 Pos 5
+
75 const uint8_t kCoronaAcModeOffset =
+
76  kCoronaAcPowerButtonOffset + 1; // D1 MSB Pos 6-7
+
77 const uint8_t kCoronaAcModeSize = 2;
+
78 const uint8_t kCoronaAcModeHeat = 0b00; // 0
+
79 const uint8_t kCoronaAcModeDry = 0b01; // 1
+
80 const uint8_t kCoronaAcModeCool = 0b10; // 2
+
81 const uint8_t kCoronaAcModeFan = 0b11; // 3
+
82 
+
83 const uint8_t kCoronaAcOnTimerSection = 1;
+
84 const uint8_t kCoronaAcOffTimerSection = 2;
+
85 const uint16_t kCoronaAcTimerMax = 12 * 60; // 12H in Minutes
+
86 // Min value on remote is 1 hour, actual sent value can be 2 secs
+
87 const uint16_t kCoronaAcTimerOff = 0xffff;
+
88 const uint16_t kCoronaAcTimerUnitsPerMin = 30; // 30 units = 1 minute
+
89 
+
90 // Classes
+
91 
+
93 class IRCoronaAc {
+
94  public:
+
95  explicit IRCoronaAc(const uint16_t pin, const bool inverted = false,
+
96  const bool use_modulation = true);
+
97 
+
98  void stateReset();
+
99 #if SEND_CORONA_AC
+
100  void send(const uint16_t repeat = kNoRepeat);
+
105  int8_t calibrate(void) { return _irsend.calibrate(); }
+
106 #endif // SEND_CORONA_AC
+
107  void begin();
+
108  static bool validSection(const uint8_t state[], const uint16_t pos,
+
109  const uint8_t section);
+
110  void setPower(const bool on);
+
111  bool getPower();
+
112  bool getPowerButton();
+
113  void on();
+
114  void off();
+
115  void setTemp(const uint8_t temp);
+
116  uint8_t getTemp();
+
117  void setSwingVToggle(const bool on);
+
118  bool getSwingVToggle(void);
+
119  void setFan(const uint8_t speed);
+
120  uint8_t getFan();
+
121  void setMode(const uint8_t mode);
+
122  uint8_t getMode();
+
123  void setEcono(const bool on);
+
124  bool getEcono(void);
+
125  void setOnTimer(const uint16_t nr_of_mins);
+
126  uint16_t getOnTimer(void);
+
127  void setOffTimer(const uint16_t nr_of_mins);
+
128  uint16_t getOffTimer(void);
+
129  uint8_t* getRaw();
+
130  void setRaw(const uint8_t new_code[],
+
131  const uint16_t length = kCoronaAcStateLength);
+
132  uint8_t convertMode(const stdAc::opmode_t mode);
+
133  uint8_t convertFan(const stdAc::fanspeed_t speed);
+
134  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
135  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+ +
137  String toString();
+
138 #ifndef UNIT_TEST
+
139 
+
140  private:
+ +
142 #else
+
143  IRsendTest _irsend;
+
145 #endif
+ +
148  static uint8_t getSectionByte(const uint8_t section);
+
149  static void checksum(uint8_t* data);
+
150  void setPowerButton(const bool on);
+
151  void _setPower(const bool on);
+
152  void _setTimer(const uint8_t section, const uint16_t nr_of_mins);
+
153  uint16_t _getTimer(const uint8_t section);
+
154 };
+
155 #endif // IR_CORONA_H_
+
+
bool getPowerButton()
Get the value of the current power button setting.
Definition: ir_Corona.cpp:346
+
uint16_t getOnTimer(void)
Get the current On Timer time.
Definition: ir_Corona.cpp:518
+
const uint8_t kCoronaAcSectionBytes
Definition: ir_Corona.h:32
+
const uint8_t kCoronaAcTempOffset
Definition: ir_Corona.h:67
+
void setFan(const uint8_t speed)
Set the operating speed of the A/C Fan.
Definition: ir_Corona.cpp:415
+
void setEcono(const bool on)
Change the powersave setting.
Definition: ir_Corona.cpp:425
+
const uint8_t kCoronaAcSectionHeader0Pos
Definition: ir_Corona.h:34
+
void setRaw(const uint8_t new_code[], const uint16_t length=kCoronaAcStateLength)
Set the internal state from a valid code for this protocol.
Definition: ir_Corona.cpp:285
+
const uint8_t kCoronaAcSectionLabelBase
Definition: ir_Corona.h:39
+
const uint8_t kCoronaAcModeFan
Definition: ir_Corona.h:81
+
void setPowerButton(const bool on)
Change the power button setting.
Definition: ir_Corona.cpp:339
+
Class for handling detailed Corona A/C messages.
Definition: ir_Corona.h:93
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
const uint8_t kCoronaAcModeDry
Definition: ir_Corona.h:79
+
const uint8_t kCoronaAcSectionData0Base
Definition: ir_Corona.h:44
+
const uint8_t kCoronaAcPowerSaveOffset
Definition: ir_Corona.h:56
+
void setPower(const bool on)
Change the power setting. (in practice Standby, remote power)
Definition: ir_Corona.cpp:315
+
void stateReset()
Reset the internal state to a fixed known good state.
Definition: ir_Corona.cpp:155
+
const uint8_t kCoronaAcTempSize
Definition: ir_Corona.h:68
+
void begin()
Set up hardware to be able to send a message.
Definition: ir_Corona.cpp:255
+
const uint8_t kCoronaAcFanMedium
Definition: ir_Corona.h:52
+
const uint16_t kCoronaAcTimerUnitsPerMin
Definition: ir_Corona.h:88
+
void setOffTimer(const uint16_t nr_of_mins)
Set the Off Timer time.
Definition: ir_Corona.cpp:541
+
const uint8_t kCoronaAcFanLow
Definition: ir_Corona.h:51
+
stdAc::state_t toCommon()
Convert the A/C state to it's common stdAc::state_t equivalent.
Definition: ir_Corona.cpp:575
+ +
void setTemp(const uint8_t temp)
Set the temp in deg C.
Definition: ir_Corona.cpp:291
+
const uint8_t kCoronaAcSectionHeader0
Definition: ir_Corona.h:35
+
void setOnTimer(const uint16_t nr_of_mins)
Set the On Timer time.
Definition: ir_Corona.cpp:525
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
uint8_t remote_state[kCoronaAcStateLength]
The state of the IR remote.
Definition: ir_Corona.h:147
+
uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a standard A/C Fan speed into its native fan speed.
Definition: ir_Corona.cpp:439
+
const uint8_t kCoronaAcSwingVToggleOffset
Definition: ir_Corona.h:59
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
std::string String
Definition: IRremoteESP8266.h:1093
+
const uint8_t kCoronaAcOffTimerSection
Definition: ir_Corona.h:84
+
void on()
Change the power setting to On.
Definition: ir_Corona.cpp:352
+
const uint16_t kCoronaAcTimerMax
Definition: ir_Corona.h:85
+
static bool validSection(const uint8_t state[], const uint16_t pos, const uint8_t section)
Check that a CoronaAc Section part is valid with section byte and inverted.
Definition: ir_Corona.cpp:188
+
bool getPower()
Get the current power setting. (in practice Standby, remote power)
Definition: ir_Corona.cpp:326
+
const uint8_t kCoronaAcSectionHeader1
Definition: ir_Corona.h:37
+
uint8_t getTemp()
Get the current temperature from the internal state.
Definition: ir_Corona.cpp:300
+
bool getEcono(void)
Get the value of the current powersave setting.
Definition: ir_Corona.cpp:431
+
bool getSwingVToggle(void)
Get the Vertical Swing toggle setting.
Definition: ir_Corona.cpp:473
+ +
uint8_t getMode()
Get the operating mode setting of the A/C.
Definition: ir_Corona.cpp:359
+
void send(const uint16_t repeat=kNoRepeat)
Send the current internal state as an IR message.
Definition: ir_Corona.cpp:260
+
const uint8_t kCoronaAcSectionData1InvPos
Definition: ir_Corona.h:43
+
const uint8_t kCoronaAcPowerOffset
Definition: ir_Corona.h:71
+
const uint8_t kCoronaAcPowerButtonOffset
Definition: ir_Corona.h:73
+
const uint8_t kCoronaAcSections
Definition: ir_Corona.h:33
+
const uint8_t kCoronaAcSectionData0InvPos
Definition: ir_Corona.h:41
+
const uint16_t kNoRepeat
Definition: IRremoteESP8266.h:810
+
const uint8_t kCoronaAcFanHigh
Definition: ir_Corona.h:53
+
const uint8_t kCoronaAcSectionData1Pos
Definition: ir_Corona.h:42
+
const uint16_t kCoronaAcStateLength
Definition: IRremoteESP8266.h:833
+
static void checksum(uint8_t *data)
Calculate and set the check values for the internal state.
Definition: ir_Corona.cpp:240
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a standard A/C mode into its native mode.
Definition: ir_Corona.cpp:385
+
uint16_t _getTimer(const uint8_t section)
Get the current Timer time.
Definition: ir_Corona.cpp:504
+
uint8_t getFan()
Get the operating speed of the A/C Fan.
Definition: ir_Corona.cpp:408
+
const uint8_t kCoronaAcFanSize
Definition: ir_Corona.h:49
+
void _setTimer(const uint8_t section, const uint16_t nr_of_mins)
Set the Timer time.
Definition: ir_Corona.cpp:483
+
const uint8_t kCoronaAcModeCool
Definition: ir_Corona.h:80
+
const uint8_t kCoronaAcMinTemp
Definition: ir_Corona.h:69
+
const uint8_t kCoronaAcSectionData0Pos
Definition: ir_Corona.h:40
+
const uint8_t kCoronaAcSectionLabelPos
Definition: ir_Corona.h:38
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode to it's common stdAc::opmode_t equivalent.
Definition: ir_Corona.cpp:397
+
uint16_t getOffTimer(void)
Get the current Off Timer time.
Definition: ir_Corona.cpp:534
+
const uint8_t kCoronaAcSectionHeader1Pos
Definition: ir_Corona.h:36
+
IRCoronaAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor for handling detailed Corona A/C messages.
Definition: ir_Corona.cpp:149
+
uint8_t * getRaw()
Get a copy of the internal state as a valid code for this protocol.
Definition: ir_Corona.cpp:277
+
const uint8_t kCoronaAcSettingsSection
Definition: ir_Corona.h:46
+
const uint8_t kCoronaAcFanOffset
Definition: ir_Corona.h:48
+
const uint8_t kCoronaAcModeHeat
Definition: ir_Corona.h:78
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Corona.h:141
+
void setSwingVToggle(const bool on)
Set the Vertical Swing toggle setting.
Definition: ir_Corona.cpp:466
+
const uint8_t kCoronaAcModeOffset
Definition: ir_Corona.h:75
+
static uint8_t getSectionByte(const uint8_t section)
Get the byte that identifies the section.
Definition: ir_Corona.cpp:172
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Corona.cpp:366
+
void off()
Change the power setting to Off.
Definition: ir_Corona.cpp:355
+
void _setPower(const bool on)
Change the power setting. (in practice Standby, remote power)
Definition: ir_Corona.cpp:307
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed to it's common equivalent.
Definition: ir_Corona.cpp:453
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Corona.h:105
+
const uint16_t kCoronaAcTimerOff
Definition: ir_Corona.h:87
+
const uint8_t kCoronaAcOnTimerSection
Definition: ir_Corona.h:83
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
String toString()
Convert the internal state into a human readable string.
Definition: ir_Corona.cpp:550
+
const uint8_t kCoronaAcMaxTemp
Definition: ir_Corona.h:70
+
const uint8_t kCoronaAcFanAuto
Definition: ir_Corona.h:50
+
const uint8_t kCoronaAcModeSize
Definition: ir_Corona.h:77
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Daikin_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Daikin_8cpp.html new file mode 100644 index 000000000..3f6d4561f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Daikin_8cpp.html @@ -0,0 +1,114 @@ + + + + + + + +IRremoteESP8266: src/ir_Daikin.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Daikin.cpp File Reference
+
+ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Daikin_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Daikin_8h.html new file mode 100644 index 000000000..5732dacd5 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Daikin_8h.html @@ -0,0 +1,5674 @@ + + + + + + + +IRremoteESP8266: src/ir_Daikin.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Daikin.h File Reference
+
+
+ +

Support for Daikin A/C protocols. +More...

+ +

Go to the source code of this file.

+ + + + + + + + + + + + + + + + + + + + + + + + + + +

+Classes

class  IRDaikinESP
 Class for handling detailed Daikin 280-bit A/C messages. More...
 
class  IRDaikin2
 Class for handling detailed Daikin 312-bit A/C messages. Code by crankyoldgit, Reverse engineering analysis by sheppy99. More...
 
class  IRDaikin216
 Class for handling detailed Daikin 216-bit A/C messages. More...
 
class  IRDaikin160
 Class for handling detailed Daikin 160-bit A/C messages. More...
 
class  IRDaikin176
 Class for handling detailed Daikin 176-bit A/C messages. More...
 
class  IRDaikin128
 Class for handling detailed Daikin 128-bit A/C messages. Code by crankyoldgit. Analysis by Daniel Vena. More...
 
class  IRDaikin152
 Class for handling detailed Daikin 152-bit A/C messages. More...
 
class  IRDaikin64
 Class for handling detailed Daikin 64-bit A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kDaikinAuto = 0b000
 
const uint8_t kDaikinDry = 0b010
 
const uint8_t kDaikinCool = 0b011
 
const uint8_t kDaikinHeat = 0b100
 
const uint8_t kDaikinFan = 0b110
 
const uint8_t kDaikinModeOffset = 4
 
const uint8_t kDaikinModeSize = 3
 
const uint8_t kDaikinMinTemp = 10
 
const uint8_t kDaikinMaxTemp = 32
 
const uint8_t kDaikinFanMin = 1
 
const uint8_t kDaikinFanMed = 3
 
const uint8_t kDaikinFanMax = 5
 
const uint8_t kDaikinFanAuto = 0b1010
 
const uint8_t kDaikinFanQuiet = 0b1011
 
const uint8_t kDaikinFanOffset = 4
 
const uint8_t kDaikinFanSize = 4
 
const uint8_t kDaikinSwingOffset = 0
 
const uint8_t kDaikinSwingSize = 4
 
const uint8_t kDaikinSwingOn = 0b1111
 
const uint8_t kDaikinSwingOff = 0b0000
 
const uint16_t kDaikinHeaderLength = 5
 
const uint8_t kDaikinSections = 3
 
const uint8_t kDaikinSection1Length = 8
 
const uint8_t kDaikinSection2Length = 8
 
const uint8_t kDaikinSection3Length
 
const uint8_t kDaikinByteComfort = 6
 
const uint8_t kDaikinByteChecksum1 = 7
 
const uint8_t kDaikinBitComfortOffset = 4
 
const uint8_t kDaikinBitComfort = 1 << kDaikinBitComfortOffset
 
const uint8_t kDaikinByteClockMinsLow = 13
 
const uint8_t kDaikinByteClockMinsHigh = 14
 
const uint8_t kDaikinClockMinsHighOffset = 0
 
const uint8_t kDaikinClockMinsHighSize = 3
 
const uint8_t kDaikinDoWOffset = 3
 
const uint8_t kDaikinDoWSize = 3
 
const uint8_t kDaikinByteChecksum2 = 15
 
const uint8_t kDaikinBytePower = 21
 
const uint8_t kDaikinBitPowerOffset = 0
 
const uint8_t kDaikinBitPower = 1 << kDaikinBitPowerOffset
 
const uint8_t kDaikinTempOffset = 1
 
const uint8_t kDaikinTempSize = 6
 
const uint8_t kDaikinByteTemp = 22
 
const uint8_t kDaikinByteFan = 24
 
const uint8_t kDaikinByteSwingH = 25
 
const uint8_t kDaikinByteOnTimerMinsLow = 26
 
const uint8_t kDaikinByteOnTimerMinsHigh = 27
 
const uint8_t kDaikinOnTimerMinsHighOffset = 0
 
const uint8_t kDaikinOnTimerMinsHighSize = 4
 
const uint8_t kDaikinByteOffTimerMinsLow = kDaikinByteOnTimerMinsHigh
 
const uint8_t kDaikinByteOffTimerMinsHigh = 28
 
const uint8_t kDaikinBytePowerful = 29
 
const uint8_t kDaikinBitPowerfulOffset = 0
 
const uint8_t kDaikinBitPowerful = 1 << kDaikinBitPowerfulOffset
 
const uint8_t kDaikinByteSilent = kDaikinBytePowerful
 
const uint8_t kDaikinBitSilentOffset = 5
 
const uint8_t kDaikinBitSilent = 1 << kDaikinBitSilentOffset
 
const uint8_t kDaikinByteSensor = 32
 
const uint8_t kDaikinBitSensorOffset = 1
 
const uint8_t kDaikinBitSensor = 1 << kDaikinBitSensorOffset
 
const uint8_t kDaikinByteEcono = kDaikinByteSensor
 
const uint8_t kDaikinBitEconoOffset = 2
 
const uint8_t kDaikinBitEcono = 1 << kDaikinBitEconoOffset
 
const uint8_t kDaikinByteEye = kDaikinByteSensor
 
const uint8_t kDaikinBitEye = 0b10000000
 
const uint8_t kDaikinByteWeeklyTimer = kDaikinByteSensor
 
const uint8_t kDaikinBitWeeklyTimerOffset = 7
 
const uint8_t kDaikinBitWeeklyTimer = 1 << kDaikinBitWeeklyTimerOffset
 
const uint8_t kDaikinByteMold = 33
 
const uint8_t kDaikinBitMoldOffset = 1
 
const uint8_t kDaikinBitMold = 1 << kDaikinBitMoldOffset
 
const uint8_t kDaikinByteOffTimer = kDaikinBytePower
 
const uint8_t kDaikinBitOffTimerOffset = 2
 
const uint8_t kDaikinBitOffTimer = 1 << kDaikinBitOffTimerOffset
 
const uint8_t kDaikinByteOnTimer = kDaikinByteOffTimer
 
const uint8_t kDaikinBitOnTimerOffset = 1
 
const uint8_t kDaikinBitOnTimer = 1 << kDaikinBitOnTimerOffset
 
const uint8_t kDaikinByteChecksum3 = kDaikinStateLength - 1
 
const uint16_t kDaikinUnusedTime = 0x600
 
const uint8_t kDaikinBeepQuiet = 1
 
const uint8_t kDaikinBeepLoud = 2
 
const uint8_t kDaikinBeepOff = 3
 
const uint8_t kDaikinLightBright = 1
 
const uint8_t kDaikinLightDim = 2
 
const uint8_t kDaikinLightOff = 3
 
const uint8_t kDaikinCurBit = kDaikinStateLength
 
const uint8_t kDaikinCurIndex = kDaikinStateLength + 1
 
const uint8_t kDaikinTolerance = 35
 
const uint16_t kDaikinMarkExcess = kMarkExcess
 
const uint16_t kDaikinHdrMark = 3650
 
const uint16_t kDaikinHdrSpace = 1623
 
const uint16_t kDaikinBitMark = 428
 
const uint16_t kDaikinZeroSpace = 428
 
const uint16_t kDaikinOneSpace = 1280
 
const uint16_t kDaikinGap = 29000
 
const uint64_t kDaikinFirstHeader64
 
const uint16_t kDaikin2Freq = 36700
 
const uint16_t kDaikin2LeaderMark = 10024
 
const uint16_t kDaikin2LeaderSpace = 25180
 
const uint16_t kDaikin2Gap = kDaikin2LeaderMark + kDaikin2LeaderSpace
 
const uint16_t kDaikin2HdrMark = 3500
 
const uint16_t kDaikin2HdrSpace = 1728
 
const uint16_t kDaikin2BitMark = 460
 
const uint16_t kDaikin2OneSpace = 1270
 
const uint16_t kDaikin2ZeroSpace = 420
 
const uint16_t kDaikin2Sections = 2
 
const uint16_t kDaikin2Section1Length = 20
 
const uint16_t kDaikin2Section2Length = 19
 
const uint8_t kDaikin2Tolerance = 5
 
const uint8_t kDaikin2BitSleepTimerOffset = 5
 
const uint8_t kDaikin2BitSleepTimer = 1 << kDaikin2BitSleepTimerOffset
 
const uint8_t kDaikin2BitPurifyOffset = 4
 
const uint8_t kDaikin2BitPurify = 1 << kDaikin2BitPurifyOffset
 
const uint8_t kDaikin2BitEyeOffset = 1
 
const uint8_t kDaikin2BitEye = 1 << kDaikin2BitEyeOffset
 
const uint8_t kDaikin2BitEyeAutoOffset = 7
 
const uint8_t kDaikin2BitEyeAuto = 1 << kDaikin2BitEyeAutoOffset
 
const uint8_t kDaikin2BitMoldOffset = 3
 
const uint8_t kDaikin2BitMold = 1 << kDaikin2BitMoldOffset
 
const uint8_t kDaikin2BitCleanOffset = 5
 
const uint8_t kDaikin2BitClean = 1 << kDaikin2BitCleanOffset
 
const uint8_t kDaikin2BitFreshAirOffset = 0
 
const uint8_t kDaikin2BitFreshAir = 1 << kDaikin2BitFreshAirOffset
 
const uint8_t kDaikin2BitFreshAirHighOffset = 7
 
const uint8_t kDaikin2BitFreshAirHigh = 1 << kDaikin2BitFreshAirHighOffset
 
const uint8_t kDaikin2BitPowerOffset = 7
 
const uint8_t kDaikin2BitPower = 1 << kDaikin2BitPowerOffset
 
const uint8_t kDaikin2LightOffset = 4
 
const uint8_t kDaikin2LightSize = 2
 
const uint8_t kDaikin2BeepOffset = 6
 
const uint8_t kDaikin2BeepSize = 2
 
const uint8_t kDaikin2SwingVHigh = 0x1
 
const uint8_t kDaikin2SwingVLow = 0x6
 
const uint8_t kDaikin2SwingVSwing = 0xF
 
const uint8_t kDaikin2SwingVAuto = 0xE
 
const uint8_t kDaikin2SwingVBreeze = 0xC
 
const uint8_t kDaikin2SwingVCirculate = 0xD
 
const uint8_t kDaikin2FanByte = 28
 
const uint8_t kDaikin2SwingHWide = 0xA3
 
const uint8_t kDaikin2SwingHLeftMax = 0xA8
 
const uint8_t kDaikin2SwingHLeft = 0xA9
 
const uint8_t kDaikin2SwingHMiddle = 0xAA
 
const uint8_t kDaikin2SwingHRight = 0xAB
 
const uint8_t kDaikin2SwingHRightMax = 0xAC
 
const uint8_t kDaikin2SwingHAuto = 0xBE
 
const uint8_t kDaikin2SwingHSwing = 0xBF
 
const uint8_t kDaikin2MinCoolTemp = 18
 
const uint16_t kDaikin216Freq = 38000
 
const uint16_t kDaikin216HdrMark = 3440
 
const uint16_t kDaikin216HdrSpace = 1750
 
const uint16_t kDaikin216BitMark = 420
 
const uint16_t kDaikin216OneSpace = 1300
 
const uint16_t kDaikin216ZeroSpace = 450
 
const uint16_t kDaikin216Gap = 29650
 
const uint16_t kDaikin216Sections = 2
 
const uint16_t kDaikin216Section1Length = 8
 
const uint16_t kDaikin216Section2Length
 
const uint8_t kDaikin216BytePower = 13
 
const uint8_t kDaikin216ByteMode = kDaikin216BytePower
 
const uint8_t kDaikin216ByteTemp = 14
 
const uint8_t kDaikin216TempOffset = 1
 
const uint8_t kDaikin216TempSize = 6
 
const uint8_t kDaikin216ByteFan = 16
 
const uint8_t kDaikin216MaskFan = 0b11110000
 
const uint8_t kDaikin216ByteSwingV = 16
 
const uint8_t kDaikin216SwingSize = 4
 
const uint8_t kDaikin216SwingOn = 0b1111
 
const uint8_t kDaikin216SwingOff = 0b0000
 
const uint8_t kDaikin216ByteSwingH = 17
 
const uint8_t kDaikin216BytePowerful = 21
 
const uint16_t kDaikin160Freq = 38000
 
const uint16_t kDaikin160HdrMark = 5000
 
const uint16_t kDaikin160HdrSpace = 2145
 
const uint16_t kDaikin160BitMark = 342
 
const uint16_t kDaikin160OneSpace = 1786
 
const uint16_t kDaikin160ZeroSpace = 700
 
const uint16_t kDaikin160Gap = 29650
 
const uint16_t kDaikin160Sections = 2
 
const uint16_t kDaikin160Section1Length = 7
 
const uint16_t kDaikin160Section2Length
 
const uint8_t kDaikin160BytePower = 12
 
const uint8_t kDaikin160ByteMode = kDaikin160BytePower
 
const uint8_t kDaikin160ByteTemp = 16
 
const uint8_t kDaikin160TempOffset = 1
 
const uint8_t kDaikin160TempSize = 6
 
const uint8_t kDaikin160ByteFan = 17
 
const uint8_t kDaikin160MaskFan = 0b00001111
 
const uint8_t kDaikin160ByteSwingV = 13
 
const uint8_t kDaikin160MaskSwingV = 0b11110000
 
const uint8_t kDaikin160SwingVLowest = 0x1
 
const uint8_t kDaikin160SwingVLow = 0x2
 
const uint8_t kDaikin160SwingVMiddle = 0x3
 
const uint8_t kDaikin160SwingVHigh = 0x4
 
const uint8_t kDaikin160SwingVHighest = 0x5
 
const uint8_t kDaikin160SwingVAuto = 0xF
 
const uint16_t kDaikin176Freq = 38000
 
const uint16_t kDaikin176HdrMark = 5070
 
const uint16_t kDaikin176HdrSpace = 2140
 
const uint16_t kDaikin176BitMark = 370
 
const uint16_t kDaikin176OneSpace = 1780
 
const uint16_t kDaikin176ZeroSpace = 710
 
const uint16_t kDaikin176Gap = 29410
 
const uint16_t kDaikin176Sections = 2
 
const uint16_t kDaikin176Section1Length = 7
 
const uint16_t kDaikin176Section2Length
 
const uint8_t kDaikin176Cool = 0b111
 
const uint8_t kDaikin176BytePower = 14
 
const uint8_t kDaikin176ByteMode = 12
 
const uint8_t kDaikin176MaskMode = 0b01110000
 
const uint8_t kDaikin176ByteModeButton = 13
 
const uint8_t kDaikin176ModeButton = 0b00000100
 
const uint8_t kDaikin176ByteTemp = 17
 
const uint8_t kDaikin176TempOffset = 1
 
const uint8_t kDaikin176TempSize = 6
 
const uint8_t kDaikin176DryFanTemp = 17
 
const uint8_t kDaikin176ByteFan = 18
 
const uint8_t kDaikin176MaskFan = 0b11110000
 
const uint8_t kDaikin176FanMax = 3
 
const uint8_t kDaikin176ByteSwingH = 18
 
const uint8_t kDaikin176SwingHAuto = 0x5
 
const uint8_t kDaikin176SwingHOff = 0x6
 
const uint16_t kDaikin128Freq = 38000
 
const uint16_t kDaikin128LeaderMark = 9800
 
const uint16_t kDaikin128LeaderSpace = 9800
 
const uint16_t kDaikin128HdrMark = 4600
 
const uint16_t kDaikin128HdrSpace = 2500
 
const uint16_t kDaikin128BitMark = 350
 
const uint16_t kDaikin128OneSpace = 954
 
const uint16_t kDaikin128ZeroSpace = 382
 
const uint16_t kDaikin128Gap = 20300
 
const uint16_t kDaikin128FooterMark = kDaikin128HdrMark
 
const uint16_t kDaikin128Sections = 2
 
const uint16_t kDaikin128SectionLength = 8
 
const uint8_t kDaikin128ByteModeFan = 1
 
const uint8_t kDaikin128ModeSize = 4
 
const uint8_t kDaikin128Dry = 0b00000001
 
const uint8_t kDaikin128Cool = 0b00000010
 
const uint8_t kDaikin128Fan = 0b00000100
 
const uint8_t kDaikin128Heat = 0b00001000
 
const uint8_t kDaikin128Auto = 0b00001010
 
const uint8_t kDaikin128MaskFan = 0b11110000
 
const uint8_t kDaikin128FanAuto = 0b0001
 
const uint8_t kDaikin128FanHigh = 0b0010
 
const uint8_t kDaikin128FanMed = 0b0100
 
const uint8_t kDaikin128FanLow = 0b1000
 
const uint8_t kDaikin128FanPowerful = 0b0011
 
const uint8_t kDaikin128FanQuiet = 0b1001
 
const uint8_t kDaikin128ByteClockMins = 2
 
const uint8_t kDaikin128ByteClockHours = 3
 
const uint8_t kDaikin128ByteOnTimer = 4
 
const uint8_t kDaikin128ByteOffTimer = 5
 
const uint8_t kDaikin128BitTimerEnabledOffset = 7
 
const uint8_t kDaikin128BitTimerEnabled = 1 << kDaikin128BitTimerEnabledOffset
 
const uint8_t kDaikin128TimerOffset = 0
 
const uint8_t kDaikin128TimerSize = 7
 
const uint8_t kDaikin128HalfHourOffset = 6
 
const uint8_t kDaikin128BitHalfHour = 1 << kDaikin128HalfHourOffset
 
const uint8_t kDaikin128HoursOffset = 0
 
const uint8_t kDaikin128HoursSize = 6
 
const uint8_t kDaikin128ByteTemp = 6
 
const uint8_t kDaikin128MinTemp = 16
 
const uint8_t kDaikin128MaxTemp = 30
 
const uint8_t kDaikin128BytePowerSwingSleep = 7
 
const uint8_t kDaikin128BitSwingOffset = 0
 
const uint8_t kDaikin128BitSwing = 1 << kDaikin128BitSwingOffset
 
const uint8_t kDaikin128BitSleepOffset = 1
 
const uint8_t kDaikin128BitSleep = 1 << kDaikin128BitSleepOffset
 
const uint8_t kDaikin128BitPowerToggleOffset = 3
 
const uint8_t kDaikin128BitPowerToggle = 1 << kDaikin128BitPowerToggleOffset
 
const uint8_t kDaikin128ByteEconoLight = 9
 
const uint8_t kDaikin128BitEconoOffset = 2
 
const uint8_t kDaikin128BitEcono = 1 << kDaikin128BitEconoOffset
 
const uint8_t kDaikin128BitWall = 0b00001000
 
const uint8_t kDaikin128BitCeiling = 0b00000001
 
const uint8_t kDaikin128MaskLight = kDaikin128BitWall | kDaikin128BitCeiling
 
const uint16_t kDaikin152Freq = 38000
 
const uint8_t kDaikin152LeaderBits = 5
 
const uint16_t kDaikin152HdrMark = 3492
 
const uint16_t kDaikin152HdrSpace = 1718
 
const uint16_t kDaikin152BitMark = 433
 
const uint16_t kDaikin152OneSpace = 1529
 
const uint16_t kDaikin152ZeroSpace = kDaikin152BitMark
 
const uint16_t kDaikin152Gap = 25182
 
const uint8_t kDaikin152ModeByte = 5
 
const uint8_t kDaikin152PowerByte = kDaikin152ModeByte
 
const uint8_t kDaikin152TempByte = 6
 
const uint8_t kDaikin152TempSize = 7
 
const uint8_t kDaikin152DryTemp = kDaikin2MinCoolTemp
 
const uint8_t kDaikin152FanTemp = 0x60
 
const uint8_t kDaikin152FanByte = 8
 
const uint8_t kDaikin152SwingVByte = kDaikin152FanByte
 
const uint8_t kDaikin152QuietByte = 13
 
const uint8_t kDaikin152PowerfulByte = kDaikin152QuietByte
 
const uint8_t kDaikin152EconoByte = 16
 
const uint8_t kDaikin152ComfortByte = kDaikin152EconoByte
 
const uint8_t kDaikin152ComfortOffset = 1
 
const uint8_t kDaikin152SensorByte = kDaikin152EconoByte
 
const uint8_t kDaikin152SensorOffset = 3
 
const uint16_t kDaikin64HdrMark = kDaikin128HdrMark
 
const uint16_t kDaikin64BitMark = kDaikin128BitMark
 
const uint16_t kDaikin64HdrSpace = kDaikin128HdrSpace
 
const uint16_t kDaikin64OneSpace = kDaikin128OneSpace
 
const uint16_t kDaikin64ZeroSpace = kDaikin128ZeroSpace
 
const uint16_t kDaikin64LdrMark = kDaikin128LeaderMark
 
const uint16_t kDaikin64Gap = kDaikin128Gap
 
const uint16_t kDaikin64LdrSpace = kDaikin128LeaderSpace
 
const uint16_t kDaikin64Freq = kDaikin128Freq
 
const uint8_t kDaikin64Overhead = 9
 
const int8_t kDaikin64ToleranceDelta = 5
 
const uint64_t kDaikin64KnownGoodState = 0x7C16161607204216
 
const uint8_t kDaikin64ModeOffset = 8
 
const uint8_t kDaikin64ModeSize = 4
 
const uint8_t kDaikin64Dry = 0b001
 
const uint8_t kDaikin64Cool = 0b010
 
const uint8_t kDaikin64Fan = 0b100
 
const uint8_t kDaikin64FanOffset = kDaikin64ModeOffset + kDaikin64ModeSize
 
const uint8_t kDaikin64FanSize = 4
 
const uint8_t kDaikin64FanAuto = 0b0001
 
const uint8_t kDaikin64FanLow = 0b1000
 
const uint8_t kDaikin64FanMed = 0b0100
 
const uint8_t kDaikin64FanHigh = 0b0010
 
const uint8_t kDaikin64FanQuiet = 0b1001
 
const uint8_t kDaikin64FanTurbo = 0b0011
 
const uint8_t kDaikin64ClockOffset = kDaikin64FanOffset + kDaikin64FanSize
 
const uint8_t kDaikin64ClockMinsSize = 8
 
const uint8_t kDaikin64ClockHoursSize = 8
 
const uint8_t kDaikin64ClockSize
 
const uint8_t kDaikin64OnTimeOffset
 
const uint8_t kDaikin64OnTimeSize = 6
 
const uint8_t kDaikin64OnTimeHalfHourBit
 
const uint8_t kDaikin64OnTimeEnableBit = kDaikin64OnTimeHalfHourBit + 1
 
const uint8_t kDaikin64OffTimeOffset = kDaikin64OnTimeEnableBit + 1
 
const uint8_t kDaikin64OffTimeSize = 6
 
const uint8_t kDaikin64OffTimeHalfHourBit
 
const uint8_t kDaikin64OffTimeEnableBit = kDaikin64OffTimeHalfHourBit + 1
 
const uint8_t kDaikin64TempOffset = 48
 
const uint8_t kDaikin64TempSize = 8
 
const uint8_t kDaikin64MinTemp = 16
 
const uint8_t kDaikin64MaxTemp = 30
 
const uint8_t kDaikin64SwingVBit = 56
 
const uint8_t kDaikin64SleepBit = kDaikin64SwingVBit + 1
 
const uint8_t kDaikin64PowerToggleBit = 59
 
const uint8_t kDaikin64ChecksumOffset = 60
 
const uint8_t kDaikin64ChecksumSize = 4
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kDaikin128Auto

+ +
+
+ + + + +
const uint8_t kDaikin128Auto = 0b00001010
+
+ +
+
+ +

◆ kDaikin128BitCeiling

+ +
+
+ + + + +
const uint8_t kDaikin128BitCeiling = 0b00000001
+
+ +
+
+ +

◆ kDaikin128BitEcono

+ +
+
+ + + + +
const uint8_t kDaikin128BitEcono = 1 << kDaikin128BitEconoOffset
+
+ +
+
+ +

◆ kDaikin128BitEconoOffset

+ +
+
+ + + + +
const uint8_t kDaikin128BitEconoOffset = 2
+
+ +
+
+ +

◆ kDaikin128BitHalfHour

+ +
+
+ + + + +
const uint8_t kDaikin128BitHalfHour = 1 << kDaikin128HalfHourOffset
+
+ +
+
+ +

◆ kDaikin128BitMark

+ +
+
+ + + + +
const uint16_t kDaikin128BitMark = 350
+
+ +
+
+ +

◆ kDaikin128BitPowerToggle

+ +
+
+ + + + +
const uint8_t kDaikin128BitPowerToggle = 1 << kDaikin128BitPowerToggleOffset
+
+ +
+
+ +

◆ kDaikin128BitPowerToggleOffset

+ +
+
+ + + + +
const uint8_t kDaikin128BitPowerToggleOffset = 3
+
+ +
+
+ +

◆ kDaikin128BitSleep

+ +
+
+ + + + +
const uint8_t kDaikin128BitSleep = 1 << kDaikin128BitSleepOffset
+
+ +
+
+ +

◆ kDaikin128BitSleepOffset

+ +
+
+ + + + +
const uint8_t kDaikin128BitSleepOffset = 1
+
+ +
+
+ +

◆ kDaikin128BitSwing

+ +
+
+ + + + +
const uint8_t kDaikin128BitSwing = 1 << kDaikin128BitSwingOffset
+
+ +
+
+ +

◆ kDaikin128BitSwingOffset

+ +
+
+ + + + +
const uint8_t kDaikin128BitSwingOffset = 0
+
+ +
+
+ +

◆ kDaikin128BitTimerEnabled

+ +
+
+ + + + +
const uint8_t kDaikin128BitTimerEnabled = 1 << kDaikin128BitTimerEnabledOffset
+
+ +
+
+ +

◆ kDaikin128BitTimerEnabledOffset

+ +
+
+ + + + +
const uint8_t kDaikin128BitTimerEnabledOffset = 7
+
+ +
+
+ +

◆ kDaikin128BitWall

+ +
+
+ + + + +
const uint8_t kDaikin128BitWall = 0b00001000
+
+ +
+
+ +

◆ kDaikin128ByteClockHours

+ +
+
+ + + + +
const uint8_t kDaikin128ByteClockHours = 3
+
+ +
+
+ +

◆ kDaikin128ByteClockMins

+ +
+
+ + + + +
const uint8_t kDaikin128ByteClockMins = 2
+
+ +
+
+ +

◆ kDaikin128ByteEconoLight

+ +
+
+ + + + +
const uint8_t kDaikin128ByteEconoLight = 9
+
+ +
+
+ +

◆ kDaikin128ByteModeFan

+ +
+
+ + + + +
const uint8_t kDaikin128ByteModeFan = 1
+
+ +
+
+ +

◆ kDaikin128ByteOffTimer

+ +
+
+ + + + +
const uint8_t kDaikin128ByteOffTimer = 5
+
+ +
+
+ +

◆ kDaikin128ByteOnTimer

+ +
+
+ + + + +
const uint8_t kDaikin128ByteOnTimer = 4
+
+ +
+
+ +

◆ kDaikin128BytePowerSwingSleep

+ +
+
+ + + + +
const uint8_t kDaikin128BytePowerSwingSleep = 7
+
+ +
+
+ +

◆ kDaikin128ByteTemp

+ +
+
+ + + + +
const uint8_t kDaikin128ByteTemp = 6
+
+ +
+
+ +

◆ kDaikin128Cool

+ +
+
+ + + + +
const uint8_t kDaikin128Cool = 0b00000010
+
+ +
+
+ +

◆ kDaikin128Dry

+ +
+
+ + + + +
const uint8_t kDaikin128Dry = 0b00000001
+
+ +
+
+ +

◆ kDaikin128Fan

+ +
+
+ + + + +
const uint8_t kDaikin128Fan = 0b00000100
+
+ +
+
+ +

◆ kDaikin128FanAuto

+ +
+
+ + + + +
const uint8_t kDaikin128FanAuto = 0b0001
+
+ +
+
+ +

◆ kDaikin128FanHigh

+ +
+
+ + + + +
const uint8_t kDaikin128FanHigh = 0b0010
+
+ +
+
+ +

◆ kDaikin128FanLow

+ +
+
+ + + + +
const uint8_t kDaikin128FanLow = 0b1000
+
+ +
+
+ +

◆ kDaikin128FanMed

+ +
+
+ + + + +
const uint8_t kDaikin128FanMed = 0b0100
+
+ +
+
+ +

◆ kDaikin128FanPowerful

+ +
+
+ + + + +
const uint8_t kDaikin128FanPowerful = 0b0011
+
+ +
+
+ +

◆ kDaikin128FanQuiet

+ +
+
+ + + + +
const uint8_t kDaikin128FanQuiet = 0b1001
+
+ +
+
+ +

◆ kDaikin128FooterMark

+ +
+
+ + + + +
const uint16_t kDaikin128FooterMark = kDaikin128HdrMark
+
+ +
+
+ +

◆ kDaikin128Freq

+ +
+
+ + + + +
const uint16_t kDaikin128Freq = 38000
+
+ +
+
+ +

◆ kDaikin128Gap

+ +
+
+ + + + +
const uint16_t kDaikin128Gap = 20300
+
+ +
+
+ +

◆ kDaikin128HalfHourOffset

+ +
+
+ + + + +
const uint8_t kDaikin128HalfHourOffset = 6
+
+ +
+
+ +

◆ kDaikin128HdrMark

+ +
+
+ + + + +
const uint16_t kDaikin128HdrMark = 4600
+
+ +
+
+ +

◆ kDaikin128HdrSpace

+ +
+
+ + + + +
const uint16_t kDaikin128HdrSpace = 2500
+
+ +
+
+ +

◆ kDaikin128Heat

+ +
+
+ + + + +
const uint8_t kDaikin128Heat = 0b00001000
+
+ +
+
+ +

◆ kDaikin128HoursOffset

+ +
+
+ + + + +
const uint8_t kDaikin128HoursOffset = 0
+
+ +
+
+ +

◆ kDaikin128HoursSize

+ +
+
+ + + + +
const uint8_t kDaikin128HoursSize = 6
+
+ +
+
+ +

◆ kDaikin128LeaderMark

+ +
+
+ + + + +
const uint16_t kDaikin128LeaderMark = 9800
+
+ +
+
+ +

◆ kDaikin128LeaderSpace

+ +
+
+ + + + +
const uint16_t kDaikin128LeaderSpace = 9800
+
+ +
+
+ +

◆ kDaikin128MaskFan

+ +
+
+ + + + +
const uint8_t kDaikin128MaskFan = 0b11110000
+
+ +
+
+ +

◆ kDaikin128MaskLight

+ +
+
+ + + + +
const uint8_t kDaikin128MaskLight = kDaikin128BitWall | kDaikin128BitCeiling
+
+ +
+
+ +

◆ kDaikin128MaxTemp

+ +
+
+ + + + +
const uint8_t kDaikin128MaxTemp = 30
+
+ +
+
+ +

◆ kDaikin128MinTemp

+ +
+
+ + + + +
const uint8_t kDaikin128MinTemp = 16
+
+ +
+
+ +

◆ kDaikin128ModeSize

+ +
+
+ + + + +
const uint8_t kDaikin128ModeSize = 4
+
+ +
+
+ +

◆ kDaikin128OneSpace

+ +
+
+ + + + +
const uint16_t kDaikin128OneSpace = 954
+
+ +
+
+ +

◆ kDaikin128SectionLength

+ +
+
+ + + + +
const uint16_t kDaikin128SectionLength = 8
+
+ +
+
+ +

◆ kDaikin128Sections

+ +
+
+ + + + +
const uint16_t kDaikin128Sections = 2
+
+ +
+
+ +

◆ kDaikin128TimerOffset

+ +
+
+ + + + +
const uint8_t kDaikin128TimerOffset = 0
+
+ +
+
+ +

◆ kDaikin128TimerSize

+ +
+
+ + + + +
const uint8_t kDaikin128TimerSize = 7
+
+ +
+
+ +

◆ kDaikin128ZeroSpace

+ +
+
+ + + + +
const uint16_t kDaikin128ZeroSpace = 382
+
+ +
+
+ +

◆ kDaikin152BitMark

+ +
+
+ + + + +
const uint16_t kDaikin152BitMark = 433
+
+ +
+
+ +

◆ kDaikin152ComfortByte

+ +
+
+ + + + +
const uint8_t kDaikin152ComfortByte = kDaikin152EconoByte
+
+ +
+
+ +

◆ kDaikin152ComfortOffset

+ +
+
+ + + + +
const uint8_t kDaikin152ComfortOffset = 1
+
+ +
+
+ +

◆ kDaikin152DryTemp

+ +
+
+ + + + +
const uint8_t kDaikin152DryTemp = kDaikin2MinCoolTemp
+
+ +
+
+ +

◆ kDaikin152EconoByte

+ +
+
+ + + + +
const uint8_t kDaikin152EconoByte = 16
+
+ +
+
+ +

◆ kDaikin152FanByte

+ +
+
+ + + + +
const uint8_t kDaikin152FanByte = 8
+
+ +
+
+ +

◆ kDaikin152FanTemp

+ +
+
+ + + + +
const uint8_t kDaikin152FanTemp = 0x60
+
+ +
+
+ +

◆ kDaikin152Freq

+ +
+
+ + + + +
const uint16_t kDaikin152Freq = 38000
+
+ +
+
+ +

◆ kDaikin152Gap

+ +
+
+ + + + +
const uint16_t kDaikin152Gap = 25182
+
+ +
+
+ +

◆ kDaikin152HdrMark

+ +
+
+ + + + +
const uint16_t kDaikin152HdrMark = 3492
+
+ +
+
+ +

◆ kDaikin152HdrSpace

+ +
+
+ + + + +
const uint16_t kDaikin152HdrSpace = 1718
+
+ +
+
+ +

◆ kDaikin152LeaderBits

+ +
+
+ + + + +
const uint8_t kDaikin152LeaderBits = 5
+
+ +
+
+ +

◆ kDaikin152ModeByte

+ +
+
+ + + + +
const uint8_t kDaikin152ModeByte = 5
+
+ +
+
+ +

◆ kDaikin152OneSpace

+ +
+
+ + + + +
const uint16_t kDaikin152OneSpace = 1529
+
+ +
+
+ +

◆ kDaikin152PowerByte

+ +
+
+ + + + +
const uint8_t kDaikin152PowerByte = kDaikin152ModeByte
+
+ +
+
+ +

◆ kDaikin152PowerfulByte

+ +
+
+ + + + +
const uint8_t kDaikin152PowerfulByte = kDaikin152QuietByte
+
+ +
+
+ +

◆ kDaikin152QuietByte

+ +
+
+ + + + +
const uint8_t kDaikin152QuietByte = 13
+
+ +
+
+ +

◆ kDaikin152SensorByte

+ +
+
+ + + + +
const uint8_t kDaikin152SensorByte = kDaikin152EconoByte
+
+ +
+
+ +

◆ kDaikin152SensorOffset

+ +
+
+ + + + +
const uint8_t kDaikin152SensorOffset = 3
+
+ +
+
+ +

◆ kDaikin152SwingVByte

+ +
+
+ + + + +
const uint8_t kDaikin152SwingVByte = kDaikin152FanByte
+
+ +
+
+ +

◆ kDaikin152TempByte

+ +
+
+ + + + +
const uint8_t kDaikin152TempByte = 6
+
+ +
+
+ +

◆ kDaikin152TempSize

+ +
+
+ + + + +
const uint8_t kDaikin152TempSize = 7
+
+ +
+
+ +

◆ kDaikin152ZeroSpace

+ +
+
+ + + + +
const uint16_t kDaikin152ZeroSpace = kDaikin152BitMark
+
+ +
+
+ +

◆ kDaikin160BitMark

+ +
+
+ + + + +
const uint16_t kDaikin160BitMark = 342
+
+ +
+
+ +

◆ kDaikin160ByteFan

+ +
+
+ + + + +
const uint8_t kDaikin160ByteFan = 17
+
+ +
+
+ +

◆ kDaikin160ByteMode

+ +
+
+ + + + +
const uint8_t kDaikin160ByteMode = kDaikin160BytePower
+
+ +
+
+ +

◆ kDaikin160BytePower

+ +
+
+ + + + +
const uint8_t kDaikin160BytePower = 12
+
+ +
+
+ +

◆ kDaikin160ByteSwingV

+ +
+
+ + + + +
const uint8_t kDaikin160ByteSwingV = 13
+
+ +
+
+ +

◆ kDaikin160ByteTemp

+ +
+
+ + + + +
const uint8_t kDaikin160ByteTemp = 16
+
+ +
+
+ +

◆ kDaikin160Freq

+ +
+
+ + + + +
const uint16_t kDaikin160Freq = 38000
+
+ +
+
+ +

◆ kDaikin160Gap

+ +
+
+ + + + +
const uint16_t kDaikin160Gap = 29650
+
+ +
+
+ +

◆ kDaikin160HdrMark

+ +
+
+ + + + +
const uint16_t kDaikin160HdrMark = 5000
+
+ +
+
+ +

◆ kDaikin160HdrSpace

+ +
+
+ + + + +
const uint16_t kDaikin160HdrSpace = 2145
+
+ +
+
+ +

◆ kDaikin160MaskFan

+ +
+
+ + + + +
const uint8_t kDaikin160MaskFan = 0b00001111
+
+ +
+
+ +

◆ kDaikin160MaskSwingV

+ +
+
+ + + + +
const uint8_t kDaikin160MaskSwingV = 0b11110000
+
+ +
+
+ +

◆ kDaikin160OneSpace

+ +
+
+ + + + +
const uint16_t kDaikin160OneSpace = 1786
+
+ +
+
+ +

◆ kDaikin160Section1Length

+ +
+
+ + + + +
const uint16_t kDaikin160Section1Length = 7
+
+ +
+
+ +

◆ kDaikin160Section2Length

+ +
+
+ + + + +
const uint16_t kDaikin160Section2Length
+
+
+ +

◆ kDaikin160Sections

+ +
+
+ + + + +
const uint16_t kDaikin160Sections = 2
+
+ +
+
+ +

◆ kDaikin160SwingVAuto

+ +
+
+ + + + +
const uint8_t kDaikin160SwingVAuto = 0xF
+
+ +
+
+ +

◆ kDaikin160SwingVHigh

+ +
+
+ + + + +
const uint8_t kDaikin160SwingVHigh = 0x4
+
+ +
+
+ +

◆ kDaikin160SwingVHighest

+ +
+
+ + + + +
const uint8_t kDaikin160SwingVHighest = 0x5
+
+ +
+
+ +

◆ kDaikin160SwingVLow

+ +
+
+ + + + +
const uint8_t kDaikin160SwingVLow = 0x2
+
+ +
+
+ +

◆ kDaikin160SwingVLowest

+ +
+
+ + + + +
const uint8_t kDaikin160SwingVLowest = 0x1
+
+ +
+
+ +

◆ kDaikin160SwingVMiddle

+ +
+
+ + + + +
const uint8_t kDaikin160SwingVMiddle = 0x3
+
+ +
+
+ +

◆ kDaikin160TempOffset

+ +
+
+ + + + +
const uint8_t kDaikin160TempOffset = 1
+
+ +
+
+ +

◆ kDaikin160TempSize

+ +
+
+ + + + +
const uint8_t kDaikin160TempSize = 6
+
+ +
+
+ +

◆ kDaikin160ZeroSpace

+ +
+
+ + + + +
const uint16_t kDaikin160ZeroSpace = 700
+
+ +
+
+ +

◆ kDaikin176BitMark

+ +
+
+ + + + +
const uint16_t kDaikin176BitMark = 370
+
+ +
+
+ +

◆ kDaikin176ByteFan

+ +
+
+ + + + +
const uint8_t kDaikin176ByteFan = 18
+
+ +
+
+ +

◆ kDaikin176ByteMode

+ +
+
+ + + + +
const uint8_t kDaikin176ByteMode = 12
+
+ +
+
+ +

◆ kDaikin176ByteModeButton

+ +
+
+ + + + +
const uint8_t kDaikin176ByteModeButton = 13
+
+ +
+
+ +

◆ kDaikin176BytePower

+ +
+
+ + + + +
const uint8_t kDaikin176BytePower = 14
+
+ +
+
+ +

◆ kDaikin176ByteSwingH

+ +
+
+ + + + +
const uint8_t kDaikin176ByteSwingH = 18
+
+ +
+
+ +

◆ kDaikin176ByteTemp

+ +
+
+ + + + +
const uint8_t kDaikin176ByteTemp = 17
+
+ +
+
+ +

◆ kDaikin176Cool

+ +
+
+ + + + +
const uint8_t kDaikin176Cool = 0b111
+
+ +
+
+ +

◆ kDaikin176DryFanTemp

+ +
+
+ + + + +
const uint8_t kDaikin176DryFanTemp = 17
+
+ +
+
+ +

◆ kDaikin176FanMax

+ +
+
+ + + + +
const uint8_t kDaikin176FanMax = 3
+
+ +
+
+ +

◆ kDaikin176Freq

+ +
+
+ + + + +
const uint16_t kDaikin176Freq = 38000
+
+ +
+
+ +

◆ kDaikin176Gap

+ +
+
+ + + + +
const uint16_t kDaikin176Gap = 29410
+
+ +
+
+ +

◆ kDaikin176HdrMark

+ +
+
+ + + + +
const uint16_t kDaikin176HdrMark = 5070
+
+ +
+
+ +

◆ kDaikin176HdrSpace

+ +
+
+ + + + +
const uint16_t kDaikin176HdrSpace = 2140
+
+ +
+
+ +

◆ kDaikin176MaskFan

+ +
+
+ + + + +
const uint8_t kDaikin176MaskFan = 0b11110000
+
+ +
+
+ +

◆ kDaikin176MaskMode

+ +
+
+ + + + +
const uint8_t kDaikin176MaskMode = 0b01110000
+
+ +
+
+ +

◆ kDaikin176ModeButton

+ +
+
+ + + + +
const uint8_t kDaikin176ModeButton = 0b00000100
+
+ +
+
+ +

◆ kDaikin176OneSpace

+ +
+
+ + + + +
const uint16_t kDaikin176OneSpace = 1780
+
+ +
+
+ +

◆ kDaikin176Section1Length

+ +
+
+ + + + +
const uint16_t kDaikin176Section1Length = 7
+
+ +
+
+ +

◆ kDaikin176Section2Length

+ +
+
+ + + + +
const uint16_t kDaikin176Section2Length
+
+
+ +

◆ kDaikin176Sections

+ +
+
+ + + + +
const uint16_t kDaikin176Sections = 2
+
+ +
+
+ +

◆ kDaikin176SwingHAuto

+ +
+
+ + + + +
const uint8_t kDaikin176SwingHAuto = 0x5
+
+ +
+
+ +

◆ kDaikin176SwingHOff

+ +
+
+ + + + +
const uint8_t kDaikin176SwingHOff = 0x6
+
+ +
+
+ +

◆ kDaikin176TempOffset

+ +
+
+ + + + +
const uint8_t kDaikin176TempOffset = 1
+
+ +
+
+ +

◆ kDaikin176TempSize

+ +
+
+ + + + +
const uint8_t kDaikin176TempSize = 6
+
+ +
+
+ +

◆ kDaikin176ZeroSpace

+ +
+
+ + + + +
const uint16_t kDaikin176ZeroSpace = 710
+
+ +
+
+ +

◆ kDaikin216BitMark

+ +
+
+ + + + +
const uint16_t kDaikin216BitMark = 420
+
+ +
+
+ +

◆ kDaikin216ByteFan

+ +
+
+ + + + +
const uint8_t kDaikin216ByteFan = 16
+
+ +
+
+ +

◆ kDaikin216ByteMode

+ +
+
+ + + + +
const uint8_t kDaikin216ByteMode = kDaikin216BytePower
+
+ +
+
+ +

◆ kDaikin216BytePower

+ +
+
+ + + + +
const uint8_t kDaikin216BytePower = 13
+
+ +
+
+ +

◆ kDaikin216BytePowerful

+ +
+
+ + + + +
const uint8_t kDaikin216BytePowerful = 21
+
+ +
+
+ +

◆ kDaikin216ByteSwingH

+ +
+
+ + + + +
const uint8_t kDaikin216ByteSwingH = 17
+
+ +
+
+ +

◆ kDaikin216ByteSwingV

+ +
+
+ + + + +
const uint8_t kDaikin216ByteSwingV = 16
+
+ +
+
+ +

◆ kDaikin216ByteTemp

+ +
+
+ + + + +
const uint8_t kDaikin216ByteTemp = 14
+
+ +
+
+ +

◆ kDaikin216Freq

+ +
+
+ + + + +
const uint16_t kDaikin216Freq = 38000
+
+ +
+
+ +

◆ kDaikin216Gap

+ +
+
+ + + + +
const uint16_t kDaikin216Gap = 29650
+
+ +
+
+ +

◆ kDaikin216HdrMark

+ +
+
+ + + + +
const uint16_t kDaikin216HdrMark = 3440
+
+ +
+
+ +

◆ kDaikin216HdrSpace

+ +
+
+ + + + +
const uint16_t kDaikin216HdrSpace = 1750
+
+ +
+
+ +

◆ kDaikin216MaskFan

+ +
+
+ + + + +
const uint8_t kDaikin216MaskFan = 0b11110000
+
+ +
+
+ +

◆ kDaikin216OneSpace

+ +
+
+ + + + +
const uint16_t kDaikin216OneSpace = 1300
+
+ +
+
+ +

◆ kDaikin216Section1Length

+ +
+
+ + + + +
const uint16_t kDaikin216Section1Length = 8
+
+ +
+
+ +

◆ kDaikin216Section2Length

+ +
+
+ + + + +
const uint16_t kDaikin216Section2Length
+
+
+ +

◆ kDaikin216Sections

+ +
+
+ + + + +
const uint16_t kDaikin216Sections = 2
+
+ +
+
+ +

◆ kDaikin216SwingOff

+ +
+
+ + + + +
const uint8_t kDaikin216SwingOff = 0b0000
+
+ +
+
+ +

◆ kDaikin216SwingOn

+ +
+
+ + + + +
const uint8_t kDaikin216SwingOn = 0b1111
+
+ +
+
+ +

◆ kDaikin216SwingSize

+ +
+
+ + + + +
const uint8_t kDaikin216SwingSize = 4
+
+ +
+
+ +

◆ kDaikin216TempOffset

+ +
+
+ + + + +
const uint8_t kDaikin216TempOffset = 1
+
+ +
+
+ +

◆ kDaikin216TempSize

+ +
+
+ + + + +
const uint8_t kDaikin216TempSize = 6
+
+ +
+
+ +

◆ kDaikin216ZeroSpace

+ +
+
+ + + + +
const uint16_t kDaikin216ZeroSpace = 450
+
+ +
+
+ +

◆ kDaikin2BeepOffset

+ +
+
+ + + + +
const uint8_t kDaikin2BeepOffset = 6
+
+ +
+
+ +

◆ kDaikin2BeepSize

+ +
+
+ + + + +
const uint8_t kDaikin2BeepSize = 2
+
+ +
+
+ +

◆ kDaikin2BitClean

+ +
+
+ + + + +
const uint8_t kDaikin2BitClean = 1 << kDaikin2BitCleanOffset
+
+ +
+
+ +

◆ kDaikin2BitCleanOffset

+ +
+
+ + + + +
const uint8_t kDaikin2BitCleanOffset = 5
+
+ +
+
+ +

◆ kDaikin2BitEye

+ +
+
+ + + + +
const uint8_t kDaikin2BitEye = 1 << kDaikin2BitEyeOffset
+
+ +
+
+ +

◆ kDaikin2BitEyeAuto

+ +
+
+ + + + +
const uint8_t kDaikin2BitEyeAuto = 1 << kDaikin2BitEyeAutoOffset
+
+ +
+
+ +

◆ kDaikin2BitEyeAutoOffset

+ +
+
+ + + + +
const uint8_t kDaikin2BitEyeAutoOffset = 7
+
+ +
+
+ +

◆ kDaikin2BitEyeOffset

+ +
+
+ + + + +
const uint8_t kDaikin2BitEyeOffset = 1
+
+ +
+
+ +

◆ kDaikin2BitFreshAir

+ +
+
+ + + + +
const uint8_t kDaikin2BitFreshAir = 1 << kDaikin2BitFreshAirOffset
+
+ +
+
+ +

◆ kDaikin2BitFreshAirHigh

+ +
+
+ + + + +
const uint8_t kDaikin2BitFreshAirHigh = 1 << kDaikin2BitFreshAirHighOffset
+
+ +
+
+ +

◆ kDaikin2BitFreshAirHighOffset

+ +
+
+ + + + +
const uint8_t kDaikin2BitFreshAirHighOffset = 7
+
+ +
+
+ +

◆ kDaikin2BitFreshAirOffset

+ +
+
+ + + + +
const uint8_t kDaikin2BitFreshAirOffset = 0
+
+ +
+
+ +

◆ kDaikin2BitMark

+ +
+
+ + + + +
const uint16_t kDaikin2BitMark = 460
+
+ +
+
+ +

◆ kDaikin2BitMold

+ +
+
+ + + + +
const uint8_t kDaikin2BitMold = 1 << kDaikin2BitMoldOffset
+
+ +
+
+ +

◆ kDaikin2BitMoldOffset

+ +
+
+ + + + +
const uint8_t kDaikin2BitMoldOffset = 3
+
+ +
+
+ +

◆ kDaikin2BitPower

+ +
+
+ + + + +
const uint8_t kDaikin2BitPower = 1 << kDaikin2BitPowerOffset
+
+ +
+
+ +

◆ kDaikin2BitPowerOffset

+ +
+
+ + + + +
const uint8_t kDaikin2BitPowerOffset = 7
+
+ +
+
+ +

◆ kDaikin2BitPurify

+ +
+
+ + + + +
const uint8_t kDaikin2BitPurify = 1 << kDaikin2BitPurifyOffset
+
+ +
+
+ +

◆ kDaikin2BitPurifyOffset

+ +
+
+ + + + +
const uint8_t kDaikin2BitPurifyOffset = 4
+
+ +
+
+ +

◆ kDaikin2BitSleepTimer

+ +
+
+ + + + +
const uint8_t kDaikin2BitSleepTimer = 1 << kDaikin2BitSleepTimerOffset
+
+ +
+
+ +

◆ kDaikin2BitSleepTimerOffset

+ +
+
+ + + + +
const uint8_t kDaikin2BitSleepTimerOffset = 5
+
+ +
+
+ +

◆ kDaikin2FanByte

+ +
+
+ + + + +
const uint8_t kDaikin2FanByte = 28
+
+ +
+
+ +

◆ kDaikin2Freq

+ +
+
+ + + + +
const uint16_t kDaikin2Freq = 36700
+
+ +
+
+ +

◆ kDaikin2Gap

+ +
+
+ + + + +
const uint16_t kDaikin2Gap = kDaikin2LeaderMark + kDaikin2LeaderSpace
+
+ +
+
+ +

◆ kDaikin2HdrMark

+ +
+
+ + + + +
const uint16_t kDaikin2HdrMark = 3500
+
+ +
+
+ +

◆ kDaikin2HdrSpace

+ +
+
+ + + + +
const uint16_t kDaikin2HdrSpace = 1728
+
+ +
+
+ +

◆ kDaikin2LeaderMark

+ +
+
+ + + + +
const uint16_t kDaikin2LeaderMark = 10024
+
+ +
+
+ +

◆ kDaikin2LeaderSpace

+ +
+
+ + + + +
const uint16_t kDaikin2LeaderSpace = 25180
+
+ +
+
+ +

◆ kDaikin2LightOffset

+ +
+
+ + + + +
const uint8_t kDaikin2LightOffset = 4
+
+ +
+
+ +

◆ kDaikin2LightSize

+ +
+
+ + + + +
const uint8_t kDaikin2LightSize = 2
+
+ +
+
+ +

◆ kDaikin2MinCoolTemp

+ +
+
+ + + + +
const uint8_t kDaikin2MinCoolTemp = 18
+
+ +
+
+ +

◆ kDaikin2OneSpace

+ +
+
+ + + + +
const uint16_t kDaikin2OneSpace = 1270
+
+ +
+
+ +

◆ kDaikin2Section1Length

+ +
+
+ + + + +
const uint16_t kDaikin2Section1Length = 20
+
+ +
+
+ +

◆ kDaikin2Section2Length

+ +
+
+ + + + +
const uint16_t kDaikin2Section2Length = 19
+
+ +
+
+ +

◆ kDaikin2Sections

+ +
+
+ + + + +
const uint16_t kDaikin2Sections = 2
+
+ +
+
+ +

◆ kDaikin2SwingHAuto

+ +
+
+ + + + +
const uint8_t kDaikin2SwingHAuto = 0xBE
+
+ +
+
+ +

◆ kDaikin2SwingHLeft

+ +
+
+ + + + +
const uint8_t kDaikin2SwingHLeft = 0xA9
+
+ +
+
+ +

◆ kDaikin2SwingHLeftMax

+ +
+
+ + + + +
const uint8_t kDaikin2SwingHLeftMax = 0xA8
+
+ +
+
+ +

◆ kDaikin2SwingHMiddle

+ +
+
+ + + + +
const uint8_t kDaikin2SwingHMiddle = 0xAA
+
+ +
+
+ +

◆ kDaikin2SwingHRight

+ +
+
+ + + + +
const uint8_t kDaikin2SwingHRight = 0xAB
+
+ +
+
+ +

◆ kDaikin2SwingHRightMax

+ +
+
+ + + + +
const uint8_t kDaikin2SwingHRightMax = 0xAC
+
+ +
+
+ +

◆ kDaikin2SwingHSwing

+ +
+
+ + + + +
const uint8_t kDaikin2SwingHSwing = 0xBF
+
+ +
+
+ +

◆ kDaikin2SwingHWide

+ +
+
+ + + + +
const uint8_t kDaikin2SwingHWide = 0xA3
+
+ +
+
+ +

◆ kDaikin2SwingVAuto

+ +
+
+ + + + +
const uint8_t kDaikin2SwingVAuto = 0xE
+
+ +
+
+ +

◆ kDaikin2SwingVBreeze

+ +
+
+ + + + +
const uint8_t kDaikin2SwingVBreeze = 0xC
+
+ +
+
+ +

◆ kDaikin2SwingVCirculate

+ +
+
+ + + + +
const uint8_t kDaikin2SwingVCirculate = 0xD
+
+ +
+
+ +

◆ kDaikin2SwingVHigh

+ +
+
+ + + + +
const uint8_t kDaikin2SwingVHigh = 0x1
+
+ +
+
+ +

◆ kDaikin2SwingVLow

+ +
+
+ + + + +
const uint8_t kDaikin2SwingVLow = 0x6
+
+ +
+
+ +

◆ kDaikin2SwingVSwing

+ +
+
+ + + + +
const uint8_t kDaikin2SwingVSwing = 0xF
+
+ +
+
+ +

◆ kDaikin2Tolerance

+ +
+
+ + + + +
const uint8_t kDaikin2Tolerance = 5
+
+ +
+
+ +

◆ kDaikin2ZeroSpace

+ +
+
+ + + + +
const uint16_t kDaikin2ZeroSpace = 420
+
+ +
+
+ +

◆ kDaikin64BitMark

+ +
+
+ + + + +
const uint16_t kDaikin64BitMark = kDaikin128BitMark
+
+ +
+
+ +

◆ kDaikin64ChecksumOffset

+ +
+
+ + + + +
const uint8_t kDaikin64ChecksumOffset = 60
+
+ +
+
+ +

◆ kDaikin64ChecksumSize

+ +
+
+ + + + +
const uint8_t kDaikin64ChecksumSize = 4
+
+ +
+
+ +

◆ kDaikin64ClockHoursSize

+ +
+
+ + + + +
const uint8_t kDaikin64ClockHoursSize = 8
+
+ +
+
+ +

◆ kDaikin64ClockMinsSize

+ +
+
+ + + + +
const uint8_t kDaikin64ClockMinsSize = 8
+
+ +
+
+ +

◆ kDaikin64ClockOffset

+ +
+
+ + + + +
const uint8_t kDaikin64ClockOffset = kDaikin64FanOffset + kDaikin64FanSize
+
+ +
+
+ +

◆ kDaikin64ClockSize

+ +
+
+ + + + +
const uint8_t kDaikin64ClockSize
+
+
+ +

◆ kDaikin64Cool

+ +
+
+ + + + +
const uint8_t kDaikin64Cool = 0b010
+
+ +
+
+ +

◆ kDaikin64Dry

+ +
+
+ + + + +
const uint8_t kDaikin64Dry = 0b001
+
+ +
+
+ +

◆ kDaikin64Fan

+ +
+
+ + + + +
const uint8_t kDaikin64Fan = 0b100
+
+ +
+
+ +

◆ kDaikin64FanAuto

+ +
+
+ + + + +
const uint8_t kDaikin64FanAuto = 0b0001
+
+ +
+
+ +

◆ kDaikin64FanHigh

+ +
+
+ + + + +
const uint8_t kDaikin64FanHigh = 0b0010
+
+ +
+
+ +

◆ kDaikin64FanLow

+ +
+
+ + + + +
const uint8_t kDaikin64FanLow = 0b1000
+
+ +
+
+ +

◆ kDaikin64FanMed

+ +
+
+ + + + +
const uint8_t kDaikin64FanMed = 0b0100
+
+ +
+
+ +

◆ kDaikin64FanOffset

+ +
+
+ + + + +
const uint8_t kDaikin64FanOffset = kDaikin64ModeOffset + kDaikin64ModeSize
+
+ +
+
+ +

◆ kDaikin64FanQuiet

+ +
+
+ + + + +
const uint8_t kDaikin64FanQuiet = 0b1001
+
+ +
+
+ +

◆ kDaikin64FanSize

+ +
+
+ + + + +
const uint8_t kDaikin64FanSize = 4
+
+ +
+
+ +

◆ kDaikin64FanTurbo

+ +
+
+ + + + +
const uint8_t kDaikin64FanTurbo = 0b0011
+
+ +
+
+ +

◆ kDaikin64Freq

+ +
+
+ + + + +
const uint16_t kDaikin64Freq = kDaikin128Freq
+
+ +
+
+ +

◆ kDaikin64Gap

+ +
+
+ + + + +
const uint16_t kDaikin64Gap = kDaikin128Gap
+
+ +
+
+ +

◆ kDaikin64HdrMark

+ +
+
+ + + + +
const uint16_t kDaikin64HdrMark = kDaikin128HdrMark
+
+ +
+
+ +

◆ kDaikin64HdrSpace

+ +
+
+ + + + +
const uint16_t kDaikin64HdrSpace = kDaikin128HdrSpace
+
+ +
+
+ +

◆ kDaikin64KnownGoodState

+ +
+
+ + + + +
const uint64_t kDaikin64KnownGoodState = 0x7C16161607204216
+
+ +
+
+ +

◆ kDaikin64LdrMark

+ +
+
+ + + + +
const uint16_t kDaikin64LdrMark = kDaikin128LeaderMark
+
+ +
+
+ +

◆ kDaikin64LdrSpace

+ +
+
+ + + + +
const uint16_t kDaikin64LdrSpace = kDaikin128LeaderSpace
+
+ +
+
+ +

◆ kDaikin64MaxTemp

+ +
+
+ + + + +
const uint8_t kDaikin64MaxTemp = 30
+
+ +
+
+ +

◆ kDaikin64MinTemp

+ +
+
+ + + + +
const uint8_t kDaikin64MinTemp = 16
+
+ +
+
+ +

◆ kDaikin64ModeOffset

+ +
+
+ + + + +
const uint8_t kDaikin64ModeOffset = 8
+
+ +
+
+ +

◆ kDaikin64ModeSize

+ +
+
+ + + + +
const uint8_t kDaikin64ModeSize = 4
+
+ +
+
+ +

◆ kDaikin64OffTimeEnableBit

+ +
+
+ + + + +
const uint8_t kDaikin64OffTimeEnableBit = kDaikin64OffTimeHalfHourBit + 1
+
+ +
+
+ +

◆ kDaikin64OffTimeHalfHourBit

+ +
+
+ + + + +
const uint8_t kDaikin64OffTimeHalfHourBit
+
+
+ +

◆ kDaikin64OffTimeOffset

+ +
+
+ + + + +
const uint8_t kDaikin64OffTimeOffset = kDaikin64OnTimeEnableBit + 1
+
+ +
+
+ +

◆ kDaikin64OffTimeSize

+ +
+
+ + + + +
const uint8_t kDaikin64OffTimeSize = 6
+
+ +
+
+ +

◆ kDaikin64OneSpace

+ +
+
+ + + + +
const uint16_t kDaikin64OneSpace = kDaikin128OneSpace
+
+ +
+
+ +

◆ kDaikin64OnTimeEnableBit

+ +
+
+ + + + +
const uint8_t kDaikin64OnTimeEnableBit = kDaikin64OnTimeHalfHourBit + 1
+
+ +
+
+ +

◆ kDaikin64OnTimeHalfHourBit

+ +
+
+ + + + +
const uint8_t kDaikin64OnTimeHalfHourBit
+
+Initial value: +
+
+ +

◆ kDaikin64OnTimeOffset

+ +
+
+ + + + +
const uint8_t kDaikin64OnTimeOffset
+
+Initial value: +
+
+ +

◆ kDaikin64OnTimeSize

+ +
+
+ + + + +
const uint8_t kDaikin64OnTimeSize = 6
+
+ +
+
+ +

◆ kDaikin64Overhead

+ +
+
+ + + + +
const uint8_t kDaikin64Overhead = 9
+
+ +
+
+ +

◆ kDaikin64PowerToggleBit

+ +
+
+ + + + +
const uint8_t kDaikin64PowerToggleBit = 59
+
+ +
+
+ +

◆ kDaikin64SleepBit

+ +
+
+ + + + +
const uint8_t kDaikin64SleepBit = kDaikin64SwingVBit + 1
+
+ +
+
+ +

◆ kDaikin64SwingVBit

+ +
+
+ + + + +
const uint8_t kDaikin64SwingVBit = 56
+
+ +
+
+ +

◆ kDaikin64TempOffset

+ +
+
+ + + + +
const uint8_t kDaikin64TempOffset = 48
+
+ +
+
+ +

◆ kDaikin64TempSize

+ +
+
+ + + + +
const uint8_t kDaikin64TempSize = 8
+
+ +
+
+ +

◆ kDaikin64ToleranceDelta

+ +
+
+ + + + +
const int8_t kDaikin64ToleranceDelta = 5
+
+ +
+
+ +

◆ kDaikin64ZeroSpace

+ +
+
+ + + + +
const uint16_t kDaikin64ZeroSpace = kDaikin128ZeroSpace
+
+ +
+
+ +

◆ kDaikinAuto

+ +
+
+ + + + +
const uint8_t kDaikinAuto = 0b000
+
+ +
+
+ +

◆ kDaikinBeepLoud

+ +
+
+ + + + +
const uint8_t kDaikinBeepLoud = 2
+
+ +
+
+ +

◆ kDaikinBeepOff

+ +
+
+ + + + +
const uint8_t kDaikinBeepOff = 3
+
+ +
+
+ +

◆ kDaikinBeepQuiet

+ +
+
+ + + + +
const uint8_t kDaikinBeepQuiet = 1
+
+ +
+
+ +

◆ kDaikinBitComfort

+ +
+
+ + + + +
const uint8_t kDaikinBitComfort = 1 << kDaikinBitComfortOffset
+
+ +
+
+ +

◆ kDaikinBitComfortOffset

+ +
+
+ + + + +
const uint8_t kDaikinBitComfortOffset = 4
+
+ +
+
+ +

◆ kDaikinBitEcono

+ +
+
+ + + + +
const uint8_t kDaikinBitEcono = 1 << kDaikinBitEconoOffset
+
+ +
+
+ +

◆ kDaikinBitEconoOffset

+ +
+
+ + + + +
const uint8_t kDaikinBitEconoOffset = 2
+
+ +
+
+ +

◆ kDaikinBitEye

+ +
+
+ + + + +
const uint8_t kDaikinBitEye = 0b10000000
+
+ +
+
+ +

◆ kDaikinBitMark

+ +
+
+ + + + +
const uint16_t kDaikinBitMark = 428
+
+ +
+
+ +

◆ kDaikinBitMold

+ +
+
+ + + + +
const uint8_t kDaikinBitMold = 1 << kDaikinBitMoldOffset
+
+ +
+
+ +

◆ kDaikinBitMoldOffset

+ +
+
+ + + + +
const uint8_t kDaikinBitMoldOffset = 1
+
+ +
+
+ +

◆ kDaikinBitOffTimer

+ +
+
+ + + + +
const uint8_t kDaikinBitOffTimer = 1 << kDaikinBitOffTimerOffset
+
+ +
+
+ +

◆ kDaikinBitOffTimerOffset

+ +
+
+ + + + +
const uint8_t kDaikinBitOffTimerOffset = 2
+
+ +
+
+ +

◆ kDaikinBitOnTimer

+ +
+
+ + + + +
const uint8_t kDaikinBitOnTimer = 1 << kDaikinBitOnTimerOffset
+
+ +
+
+ +

◆ kDaikinBitOnTimerOffset

+ +
+
+ + + + +
const uint8_t kDaikinBitOnTimerOffset = 1
+
+ +
+
+ +

◆ kDaikinBitPower

+ +
+
+ + + + +
const uint8_t kDaikinBitPower = 1 << kDaikinBitPowerOffset
+
+ +
+
+ +

◆ kDaikinBitPowerful

+ +
+
+ + + + +
const uint8_t kDaikinBitPowerful = 1 << kDaikinBitPowerfulOffset
+
+ +
+
+ +

◆ kDaikinBitPowerfulOffset

+ +
+
+ + + + +
const uint8_t kDaikinBitPowerfulOffset = 0
+
+ +
+
+ +

◆ kDaikinBitPowerOffset

+ +
+
+ + + + +
const uint8_t kDaikinBitPowerOffset = 0
+
+ +
+
+ +

◆ kDaikinBitSensor

+ +
+
+ + + + +
const uint8_t kDaikinBitSensor = 1 << kDaikinBitSensorOffset
+
+ +
+
+ +

◆ kDaikinBitSensorOffset

+ +
+
+ + + + +
const uint8_t kDaikinBitSensorOffset = 1
+
+ +
+
+ +

◆ kDaikinBitSilent

+ +
+
+ + + + +
const uint8_t kDaikinBitSilent = 1 << kDaikinBitSilentOffset
+
+ +
+
+ +

◆ kDaikinBitSilentOffset

+ +
+
+ + + + +
const uint8_t kDaikinBitSilentOffset = 5
+
+ +
+
+ +

◆ kDaikinBitWeeklyTimer

+ +
+
+ + + + +
const uint8_t kDaikinBitWeeklyTimer = 1 << kDaikinBitWeeklyTimerOffset
+
+ +
+
+ +

◆ kDaikinBitWeeklyTimerOffset

+ +
+
+ + + + +
const uint8_t kDaikinBitWeeklyTimerOffset = 7
+
+ +
+
+ +

◆ kDaikinByteChecksum1

+ +
+
+ + + + +
const uint8_t kDaikinByteChecksum1 = 7
+
+ +
+
+ +

◆ kDaikinByteChecksum2

+ +
+
+ + + + +
const uint8_t kDaikinByteChecksum2 = 15
+
+ +
+
+ +

◆ kDaikinByteChecksum3

+ +
+
+ + + + +
const uint8_t kDaikinByteChecksum3 = kDaikinStateLength - 1
+
+ +
+
+ +

◆ kDaikinByteClockMinsHigh

+ +
+
+ + + + +
const uint8_t kDaikinByteClockMinsHigh = 14
+
+ +
+
+ +

◆ kDaikinByteClockMinsLow

+ +
+
+ + + + +
const uint8_t kDaikinByteClockMinsLow = 13
+
+ +
+
+ +

◆ kDaikinByteComfort

+ +
+
+ + + + +
const uint8_t kDaikinByteComfort = 6
+
+ +
+
+ +

◆ kDaikinByteEcono

+ +
+
+ + + + +
const uint8_t kDaikinByteEcono = kDaikinByteSensor
+
+ +
+
+ +

◆ kDaikinByteEye

+ +
+
+ + + + +
const uint8_t kDaikinByteEye = kDaikinByteSensor
+
+ +
+
+ +

◆ kDaikinByteFan

+ +
+
+ + + + +
const uint8_t kDaikinByteFan = 24
+
+ +
+
+ +

◆ kDaikinByteMold

+ +
+
+ + + + +
const uint8_t kDaikinByteMold = 33
+
+ +
+
+ +

◆ kDaikinByteOffTimer

+ +
+
+ + + + +
const uint8_t kDaikinByteOffTimer = kDaikinBytePower
+
+ +
+
+ +

◆ kDaikinByteOffTimerMinsHigh

+ +
+
+ + + + +
const uint8_t kDaikinByteOffTimerMinsHigh = 28
+
+ +
+
+ +

◆ kDaikinByteOffTimerMinsLow

+ +
+
+ + + + +
const uint8_t kDaikinByteOffTimerMinsLow = kDaikinByteOnTimerMinsHigh
+
+ +
+
+ +

◆ kDaikinByteOnTimer

+ +
+
+ + + + +
const uint8_t kDaikinByteOnTimer = kDaikinByteOffTimer
+
+ +
+
+ +

◆ kDaikinByteOnTimerMinsHigh

+ +
+
+ + + + +
const uint8_t kDaikinByteOnTimerMinsHigh = 27
+
+ +
+
+ +

◆ kDaikinByteOnTimerMinsLow

+ +
+
+ + + + +
const uint8_t kDaikinByteOnTimerMinsLow = 26
+
+ +
+
+ +

◆ kDaikinBytePower

+ +
+
+ + + + +
const uint8_t kDaikinBytePower = 21
+
+ +
+
+ +

◆ kDaikinBytePowerful

+ +
+
+ + + + +
const uint8_t kDaikinBytePowerful = 29
+
+ +
+
+ +

◆ kDaikinByteSensor

+ +
+
+ + + + +
const uint8_t kDaikinByteSensor = 32
+
+ +
+
+ +

◆ kDaikinByteSilent

+ +
+
+ + + + +
const uint8_t kDaikinByteSilent = kDaikinBytePowerful
+
+ +
+
+ +

◆ kDaikinByteSwingH

+ +
+
+ + + + +
const uint8_t kDaikinByteSwingH = 25
+
+ +
+
+ +

◆ kDaikinByteTemp

+ +
+
+ + + + +
const uint8_t kDaikinByteTemp = 22
+
+ +
+
+ +

◆ kDaikinByteWeeklyTimer

+ +
+
+ + + + +
const uint8_t kDaikinByteWeeklyTimer = kDaikinByteSensor
+
+ +
+
+ +

◆ kDaikinClockMinsHighOffset

+ +
+
+ + + + +
const uint8_t kDaikinClockMinsHighOffset = 0
+
+ +
+
+ +

◆ kDaikinClockMinsHighSize

+ +
+
+ + + + +
const uint8_t kDaikinClockMinsHighSize = 3
+
+ +
+
+ +

◆ kDaikinCool

+ +
+
+ + + + +
const uint8_t kDaikinCool = 0b011
+
+ +
+
+ +

◆ kDaikinCurBit

+ +
+
+ + + + +
const uint8_t kDaikinCurBit = kDaikinStateLength
+
+ +
+
+ +

◆ kDaikinCurIndex

+ +
+
+ + + + +
const uint8_t kDaikinCurIndex = kDaikinStateLength + 1
+
+ +
+
+ +

◆ kDaikinDoWOffset

+ +
+
+ + + + +
const uint8_t kDaikinDoWOffset = 3
+
+ +
+
+ +

◆ kDaikinDoWSize

+ +
+
+ + + + +
const uint8_t kDaikinDoWSize = 3
+
+ +
+
+ +

◆ kDaikinDry

+ +
+
+ + + + +
const uint8_t kDaikinDry = 0b010
+
+ +
+
+ +

◆ kDaikinFan

+ +
+
+ + + + +
const uint8_t kDaikinFan = 0b110
+
+ +
+
+ +

◆ kDaikinFanAuto

+ +
+
+ + + + +
const uint8_t kDaikinFanAuto = 0b1010
+
+ +
+
+ +

◆ kDaikinFanMax

+ +
+
+ + + + +
const uint8_t kDaikinFanMax = 5
+
+ +
+
+ +

◆ kDaikinFanMed

+ +
+
+ + + + +
const uint8_t kDaikinFanMed = 3
+
+ +
+
+ +

◆ kDaikinFanMin

+ +
+
+ + + + +
const uint8_t kDaikinFanMin = 1
+
+ +
+
+ +

◆ kDaikinFanOffset

+ +
+
+ + + + +
const uint8_t kDaikinFanOffset = 4
+
+ +
+
+ +

◆ kDaikinFanQuiet

+ +
+
+ + + + +
const uint8_t kDaikinFanQuiet = 0b1011
+
+ +
+
+ +

◆ kDaikinFanSize

+ +
+
+ + + + +
const uint8_t kDaikinFanSize = 4
+
+ +
+
+ +

◆ kDaikinFirstHeader64

+ +
+
+ + + + +
const uint64_t kDaikinFirstHeader64
+
+Initial value:
=
+
0b1101011100000000000000001100010100000000001001111101101000010001
+
+
+
+ +

◆ kDaikinGap

+ +
+
+ + + + +
const uint16_t kDaikinGap = 29000
+
+ +
+
+ +

◆ kDaikinHdrMark

+ +
+
+ + + + +
const uint16_t kDaikinHdrMark = 3650
+
+ +
+
+ +

◆ kDaikinHdrSpace

+ +
+
+ + + + +
const uint16_t kDaikinHdrSpace = 1623
+
+ +
+
+ +

◆ kDaikinHeaderLength

+ +
+
+ + + + +
const uint16_t kDaikinHeaderLength = 5
+
+ +
+
+ +

◆ kDaikinHeat

+ +
+
+ + + + +
const uint8_t kDaikinHeat = 0b100
+
+ +
+
+ +

◆ kDaikinLightBright

+ +
+
+ + + + +
const uint8_t kDaikinLightBright = 1
+
+ +
+
+ +

◆ kDaikinLightDim

+ +
+
+ + + + +
const uint8_t kDaikinLightDim = 2
+
+ +
+
+ +

◆ kDaikinLightOff

+ +
+
+ + + + +
const uint8_t kDaikinLightOff = 3
+
+ +
+
+ +

◆ kDaikinMarkExcess

+ +
+
+ + + + +
const uint16_t kDaikinMarkExcess = kMarkExcess
+
+ +
+
+ +

◆ kDaikinMaxTemp

+ +
+
+ + + + +
const uint8_t kDaikinMaxTemp = 32
+
+ +
+
+ +

◆ kDaikinMinTemp

+ +
+
+ + + + +
const uint8_t kDaikinMinTemp = 10
+
+ +
+
+ +

◆ kDaikinModeOffset

+ +
+
+ + + + +
const uint8_t kDaikinModeOffset = 4
+
+ +
+
+ +

◆ kDaikinModeSize

+ +
+
+ + + + +
const uint8_t kDaikinModeSize = 3
+
+ +
+
+ +

◆ kDaikinOneSpace

+ +
+
+ + + + +
const uint16_t kDaikinOneSpace = 1280
+
+ +
+
+ +

◆ kDaikinOnTimerMinsHighOffset

+ +
+
+ + + + +
const uint8_t kDaikinOnTimerMinsHighOffset = 0
+
+ +
+
+ +

◆ kDaikinOnTimerMinsHighSize

+ +
+
+ + + + +
const uint8_t kDaikinOnTimerMinsHighSize = 4
+
+ +
+
+ +

◆ kDaikinSection1Length

+ +
+
+ + + + +
const uint8_t kDaikinSection1Length = 8
+
+ +
+
+ +

◆ kDaikinSection2Length

+ +
+
+ + + + +
const uint8_t kDaikinSection2Length = 8
+
+ +
+
+ +

◆ kDaikinSection3Length

+ +
+
+ + + + +
const uint8_t kDaikinSection3Length
+
+
+ +

◆ kDaikinSections

+ +
+
+ + + + +
const uint8_t kDaikinSections = 3
+
+ +
+
+ +

◆ kDaikinSwingOff

+ +
+
+ + + + +
const uint8_t kDaikinSwingOff = 0b0000
+
+ +
+
+ +

◆ kDaikinSwingOffset

+ +
+
+ + + + +
const uint8_t kDaikinSwingOffset = 0
+
+ +
+
+ +

◆ kDaikinSwingOn

+ +
+
+ + + + +
const uint8_t kDaikinSwingOn = 0b1111
+
+ +
+
+ +

◆ kDaikinSwingSize

+ +
+
+ + + + +
const uint8_t kDaikinSwingSize = 4
+
+ +
+
+ +

◆ kDaikinTempOffset

+ +
+
+ + + + +
const uint8_t kDaikinTempOffset = 1
+
+ +
+
+ +

◆ kDaikinTempSize

+ +
+
+ + + + +
const uint8_t kDaikinTempSize = 6
+
+ +
+
+ +

◆ kDaikinTolerance

+ +
+
+ + + + +
const uint8_t kDaikinTolerance = 35
+
+ +
+
+ +

◆ kDaikinUnusedTime

+ +
+
+ + + + +
const uint16_t kDaikinUnusedTime = 0x600
+
+ +
+
+ +

◆ kDaikinZeroSpace

+ +
+
+ + + + +
const uint16_t kDaikinZeroSpace = 428
+
+ +
+
+
+
const uint8_t kDaikin64OnTimeOffset
Definition: ir_Daikin.h:485
+
const uint16_t kDaikin176StateLength
Definition: IRremoteESP8266.h:855
+
const uint8_t kDaikin64ClockOffset
Definition: ir_Daikin.h:480
+
const uint8_t kDaikinSection1Length
Definition: ir_Daikin.h:139
+
const uint8_t kDaikin64OffTimeOffset
Definition: ir_Daikin.h:491
+
const uint8_t kDaikin64ClockSize
Definition: ir_Daikin.h:483
+
const uint16_t kDaikin216StateLength
Definition: IRremoteESP8266.h:858
+
const uint16_t kDaikin216Section1Length
Definition: ir_Daikin.h:282
+
const uint16_t kDaikin160Section1Length
Definition: ir_Daikin.h:312
+
const uint8_t kDaikin64OnTimeSize
Definition: ir_Daikin.h:487
+
const uint16_t kDaikinStateLength
Definition: IRremoteESP8266.h:836
+
const uint16_t kDaikin160StateLength
Definition: IRremoteESP8266.h:846
+
const uint8_t kDaikinSection2Length
Definition: ir_Daikin.h:140
+
const uint8_t kDaikin64ClockHoursSize
Definition: ir_Daikin.h:482
+
const uint16_t kDaikin176Section1Length
Definition: ir_Daikin.h:342
+
const uint8_t kDaikin64ClockMinsSize
Definition: ir_Daikin.h:481
+
const uint8_t kDaikin64OffTimeSize
Definition: ir_Daikin.h:492
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Daikin_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Daikin_8h_source.html new file mode 100644 index 000000000..f557d4dd2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Daikin_8h_source.html @@ -0,0 +1,1801 @@ + + + + + + + +IRremoteESP8266: src/ir_Daikin.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Daikin.h
+
+
+Go to the documentation of this file.
1 // Copyright 2016 sillyfrog
+
2 // Copyright 2017 sillyfrog, crankyoldgit
+
3 // Copyright 2018-2020 crankyoldgit
+
4 // Copyright 2019 pasna (IRDaikin160 class / Daikin176 class)
+
5 
+
23 
+
24 // Supports:
+
25 // Brand: Daikin, Model: ARC433** remote (DAIKIN)
+
26 // Brand: Daikin, Model: ARC477A1 remote (DAIKIN2)
+
27 // Brand: Daikin, Model: FTXZ25NV1B A/C (DAIKIN2)
+
28 // Brand: Daikin, Model: FTXZ35NV1B A/C (DAIKIN2)
+
29 // Brand: Daikin, Model: FTXZ50NV1B A/C (DAIKIN2)
+
30 // Brand: Daikin, Model: ARC433B69 remote (DAIKIN216)
+
31 // Brand: Daikin, Model: ARC423A5 remote (DAIKIN160)
+
32 // Brand: Daikin, Model: FTE12HV2S A/C
+
33 // Brand: Daikin, Model: BRC4C153 remote (DAIKIN176)
+
34 // Brand: Daikin, Model: 17 Series A/C (DAIKIN128)
+
35 // Brand: Daikin, Model: FTXB12AXVJU A/C (DAIKIN128)
+
36 // Brand: Daikin, Model: FTXB09AXVJU A/C (DAIKIN128)
+
37 // Brand: Daikin, Model: BRC52B63 remote (DAIKIN128)
+
38 // Brand: Daikin, Model: ARC480A5 remote (DAIKIN152)
+
39 // Brand: Daikin, Model: FFN-C/FCN-F Series A/C (DAIKIN64)
+
40 // Brand: Daikin, Model: DGS01 remote (DAIKIN64)
+
41 // Brand: Daikin, Model: M Series A/C (DAIKIN)
+
42 // Brand: Daikin, Model: FTXM-M A/C (DAIKIN)
+
43 // Brand: Daikin, Model: ARC466A33 remote (DAIKIN)
+
44 
+
45 #ifndef IR_DAIKIN_H_
+
46 #define IR_DAIKIN_H_
+
47 
+
48 #ifndef UNIT_TEST
+
49 #include <Arduino.h>
+
50 #endif
+
51 #include "IRrecv.h"
+
52 #include "IRremoteESP8266.h"
+
53 #include "IRsend.h"
+
54 #ifdef UNIT_TEST
+
55 #include "IRsend_test.h"
+
56 #endif
+
57 
+
58 /*
+
59  Daikin AC map (i.e. DAIKIN, not the other variants)
+
60  byte 6=
+
61  b4:Comfort
+
62  byte 7= checksum of the first part (and last byte before a 29ms pause)
+
63  byte 13=Current time, mins past midnight, low bits
+
64  byte 14
+
65  b5-b3=Day of the week (SUN=1, MON=2, ..., SAT=7)
+
66  b2-b0=Current time, mins past midnight, high bits
+
67  byte 15= checksum of the second part (and last byte before a 29ms pause)
+
68  byte 21=mode
+
69  b7 = 0
+
70  b6+b5+b4 = Mode
+
71  Modes: b6+b5+b4
+
72  011 = Cool
+
73  100 = Heat (temp 23)
+
74  110 = FAN (temp not shown, but 25)
+
75  000 = Fully Automatic (temp 25)
+
76  010 = DRY (temp 0xc0 = 96 degrees c)
+
77  b3 = 1
+
78  b2 = OFF timer set
+
79  b1 = ON timer set
+
80  b0 = Air Conditioner ON
+
81  byte 22=temp*2 (Temp should be between 10 - 32)
+
82  byte 24=Fan
+
83  FAN control
+
84  b7+b6+b5+b4 = Fan speed
+
85  Fan: b7+b6+b5+b4
+
86  0×3 = 1 bar
+
87  0×4 = 2 bar
+
88  0×5 = 3 bar
+
89  0×6 = 4 bar
+
90  0×7 = 5 bar
+
91  0xa = Auto
+
92  0xb = Quite
+
93  b3+b2+b1+b0 = Swing control up/down
+
94  Swing control up/down:
+
95  0000 = Swing up/down off
+
96  1111 = Swing up/down on
+
97  byte 25
+
98  Swing control left/right:
+
99  0000 = Swing left/right off
+
100  1111 = Swing left/right on
+
101  byte 26=On timer mins past midnight, low bits
+
102  byte 27
+
103  b0-b3=On timer mins past midnight, high bits
+
104  b4-b7=Off timer mins past midnight, low bits
+
105  byte 28=Off timer mins past midnight, high bits
+
106  byte 29=Aux -> Powerful (bit 1), Silent (bit 5)
+
107  byte 32=Aux2
+
108  b1: Sensor
+
109  b2: Econo mode
+
110  b7: Intelligent eye on
+
111  byte 33=Aux3
+
112  b1: Mold Proof
+
113  byte 34= checksum of the third part
+
114 */
+
115 
+
116 // Constants
+
117 const uint8_t kDaikinAuto = 0b000;
+
118 const uint8_t kDaikinDry = 0b010;
+
119 const uint8_t kDaikinCool = 0b011;
+
120 const uint8_t kDaikinHeat = 0b100;
+
121 const uint8_t kDaikinFan = 0b110;
+
122 const uint8_t kDaikinModeOffset = 4;
+
123 const uint8_t kDaikinModeSize = 3;
+
124 const uint8_t kDaikinMinTemp = 10; // Celsius
+
125 const uint8_t kDaikinMaxTemp = 32; // Celsius
+
126 const uint8_t kDaikinFanMin = 1;
+
127 const uint8_t kDaikinFanMed = 3;
+
128 const uint8_t kDaikinFanMax = 5;
+
129 const uint8_t kDaikinFanAuto = 0b1010; // 10 / 0xA
+
130 const uint8_t kDaikinFanQuiet = 0b1011; // 11 / 0xB
+
131 const uint8_t kDaikinFanOffset = 4;
+
132 const uint8_t kDaikinFanSize = 4;
+
133 const uint8_t kDaikinSwingOffset = 0;
+
134 const uint8_t kDaikinSwingSize = 4;
+
135 const uint8_t kDaikinSwingOn = 0b1111;
+
136 const uint8_t kDaikinSwingOff = 0b0000;
+
137 const uint16_t kDaikinHeaderLength = 5;
+
138 const uint8_t kDaikinSections = 3;
+
139 const uint8_t kDaikinSection1Length = 8;
+
140 const uint8_t kDaikinSection2Length = 8;
+
141 const uint8_t kDaikinSection3Length =
+ +
143 const uint8_t kDaikinByteComfort = 6;
+
144 const uint8_t kDaikinByteChecksum1 = 7;
+
145 const uint8_t kDaikinBitComfortOffset = 4;
+ +
147 const uint8_t kDaikinByteClockMinsLow = 13;
+
148 const uint8_t kDaikinByteClockMinsHigh = 14;
+
149 const uint8_t kDaikinClockMinsHighOffset = 0;
+
150 const uint8_t kDaikinClockMinsHighSize = 3;
+
151 const uint8_t kDaikinDoWOffset = 3;
+
152 const uint8_t kDaikinDoWSize = 3;
+
153 const uint8_t kDaikinByteChecksum2 = 15;
+
154 const uint8_t kDaikinBytePower = 21;
+
155 const uint8_t kDaikinBitPowerOffset = 0;
+ +
157 const uint8_t kDaikinTempOffset = 1;
+
158 const uint8_t kDaikinTempSize = 6;
+
159 const uint8_t kDaikinByteTemp = 22;
+
160 const uint8_t kDaikinByteFan = 24;
+
161 const uint8_t kDaikinByteSwingH = 25;
+
162 const uint8_t kDaikinByteOnTimerMinsLow = 26;
+
163 const uint8_t kDaikinByteOnTimerMinsHigh = 27;
+ +
165 const uint8_t kDaikinOnTimerMinsHighSize = 4;
+ +
167 const uint8_t kDaikinByteOffTimerMinsHigh = 28;
+
168 const uint8_t kDaikinBytePowerful = 29;
+
169 const uint8_t kDaikinBitPowerfulOffset = 0;
+ + +
172 const uint8_t kDaikinBitSilentOffset = 5;
+ +
174 const uint8_t kDaikinByteSensor = 32;
+
175 const uint8_t kDaikinBitSensorOffset = 1;
+ + +
178 const uint8_t kDaikinBitEconoOffset = 2;
+ + +
181 const uint8_t kDaikinBitEye = 0b10000000;
+ +
183 const uint8_t kDaikinBitWeeklyTimerOffset = 7;
+ +
185 const uint8_t kDaikinByteMold = 33;
+
186 const uint8_t kDaikinBitMoldOffset = 1;
+ + +
189 const uint8_t kDaikinBitOffTimerOffset = 2;
+ + +
192 const uint8_t kDaikinBitOnTimerOffset = 1;
+ + +
195 const uint16_t kDaikinUnusedTime = 0x600;
+
196 const uint8_t kDaikinBeepQuiet = 1;
+
197 const uint8_t kDaikinBeepLoud = 2;
+
198 const uint8_t kDaikinBeepOff = 3;
+
199 const uint8_t kDaikinLightBright = 1;
+
200 const uint8_t kDaikinLightDim = 2;
+
201 const uint8_t kDaikinLightOff = 3;
+ + +
204 const uint8_t kDaikinTolerance = 35;
+ +
206 const uint16_t kDaikinHdrMark = 3650; // kDaikinBitMark * 8
+
207 const uint16_t kDaikinHdrSpace = 1623; // kDaikinBitMark * 4
+
208 const uint16_t kDaikinBitMark = 428;
+
209 const uint16_t kDaikinZeroSpace = 428;
+
210 const uint16_t kDaikinOneSpace = 1280;
+
211 const uint16_t kDaikinGap = 29000;
+
212 // Note bits in each octet swapped so can be sent as a single value
+
213 const uint64_t kDaikinFirstHeader64 =
+
214  0b1101011100000000000000001100010100000000001001111101101000010001;
+
215 
+
216 
+
217 const uint16_t kDaikin2Freq = 36700; // Modulation Frequency in Hz.
+
218 const uint16_t kDaikin2LeaderMark = 10024;
+
219 const uint16_t kDaikin2LeaderSpace = 25180;
+ +
221 const uint16_t kDaikin2HdrMark = 3500;
+
222 const uint16_t kDaikin2HdrSpace = 1728;
+
223 const uint16_t kDaikin2BitMark = 460;
+
224 const uint16_t kDaikin2OneSpace = 1270;
+
225 const uint16_t kDaikin2ZeroSpace = 420;
+
226 const uint16_t kDaikin2Sections = 2;
+
227 const uint16_t kDaikin2Section1Length = 20;
+
228 const uint16_t kDaikin2Section2Length = 19;
+
229 const uint8_t kDaikin2Tolerance = 5; // Extra percentage tolerance
+
230 const uint8_t kDaikin2BitSleepTimerOffset = 5;
+ +
232 const uint8_t kDaikin2BitPurifyOffset = 4;
+
233 const uint8_t kDaikin2BitPurify = 1 << kDaikin2BitPurifyOffset; // 0b00010000
+
234 const uint8_t kDaikin2BitEyeOffset = 1;
+
235 const uint8_t kDaikin2BitEye = 1 << kDaikin2BitEyeOffset; // 0b00000010
+
236 const uint8_t kDaikin2BitEyeAutoOffset = 7;
+
237 const uint8_t kDaikin2BitEyeAuto = 1 << kDaikin2BitEyeAutoOffset; // 0b10000000
+
238 const uint8_t kDaikin2BitMoldOffset = 3;
+
239 const uint8_t kDaikin2BitMold = 1 << kDaikin2BitMoldOffset; // 0b00001000
+
240 const uint8_t kDaikin2BitCleanOffset = 5; // Byte[8]
+
241 const uint8_t kDaikin2BitClean = 1 << kDaikin2BitCleanOffset; // 0b00100000
+
242 const uint8_t kDaikin2BitFreshAirOffset = 0;
+ + + +
246 const uint8_t kDaikin2BitPowerOffset = 7;
+
247 const uint8_t kDaikin2BitPower = 1 << kDaikin2BitPowerOffset; // 0b10000000
+
248 // const uint8_t kDaikin2LightMask = 0b00110000; // Byte[7]
+
249 const uint8_t kDaikin2LightOffset = 4; // Byte[7]
+
250 const uint8_t kDaikin2LightSize = 2;
+
251 // const uint8_t kDaikin2BeepMask = 0b11000000; // Byte[7]
+
252 const uint8_t kDaikin2BeepOffset = 6; // Byte[7]
+
253 const uint8_t kDaikin2BeepSize = 2;
+
254 const uint8_t kDaikin2SwingVHigh = 0x1;
+
255 const uint8_t kDaikin2SwingVLow = 0x6;
+
256 const uint8_t kDaikin2SwingVSwing = 0xF;
+
257 const uint8_t kDaikin2SwingVAuto = 0xE;
+
258 const uint8_t kDaikin2SwingVBreeze = 0xC;
+
259 const uint8_t kDaikin2SwingVCirculate = 0xD;
+
260 const uint8_t kDaikin2FanByte = 28;
+
261 
+
262 const uint8_t kDaikin2SwingHWide = 0xA3;
+
263 const uint8_t kDaikin2SwingHLeftMax = 0xA8;
+
264 const uint8_t kDaikin2SwingHLeft = 0xA9;
+
265 const uint8_t kDaikin2SwingHMiddle = 0xAA;
+
266 const uint8_t kDaikin2SwingHRight = 0xAB;
+
267 const uint8_t kDaikin2SwingHRightMax = 0xAC;
+
268 const uint8_t kDaikin2SwingHAuto = 0xBE;
+
269 const uint8_t kDaikin2SwingHSwing = 0xBF;
+
270 
+
271 const uint8_t kDaikin2MinCoolTemp = 18; // Min temp (in C) when in Cool mode.
+
272 
+
273 
+
274 const uint16_t kDaikin216Freq = 38000; // Modulation Frequency in Hz.
+
275 const uint16_t kDaikin216HdrMark = 3440;
+
276 const uint16_t kDaikin216HdrSpace = 1750;
+
277 const uint16_t kDaikin216BitMark = 420;
+
278 const uint16_t kDaikin216OneSpace = 1300;
+
279 const uint16_t kDaikin216ZeroSpace = 450;
+
280 const uint16_t kDaikin216Gap = 29650;
+
281 const uint16_t kDaikin216Sections = 2;
+
282 const uint16_t kDaikin216Section1Length = 8;
+ + +
285 const uint8_t kDaikin216BytePower = 13;
+ +
287 // const uint8_t kDaikin216MaskMode = 0b01110000;
+
288 const uint8_t kDaikin216ByteTemp = 14;
+
289 // const uint8_t kDaikin216MaskTemp = 0b01111110;
+
290 const uint8_t kDaikin216TempOffset = 1;
+
291 const uint8_t kDaikin216TempSize = 6;
+
292 
+
293 const uint8_t kDaikin216ByteFan = 16;
+
294 const uint8_t kDaikin216MaskFan = 0b11110000;
+
295 const uint8_t kDaikin216ByteSwingV = 16;
+
296 // const uint8_t kDaikin216MaskSwingV = 0b00001111;
+
297 const uint8_t kDaikin216SwingSize = 4;
+
298 const uint8_t kDaikin216SwingOn = 0b1111;
+
299 const uint8_t kDaikin216SwingOff = 0b0000;
+
300 const uint8_t kDaikin216ByteSwingH = 17;
+
301 const uint8_t kDaikin216BytePowerful = 21;
+
302 
+
303 
+
304 const uint16_t kDaikin160Freq = 38000; // Modulation Frequency in Hz.
+
305 const uint16_t kDaikin160HdrMark = 5000;
+
306 const uint16_t kDaikin160HdrSpace = 2145;
+
307 const uint16_t kDaikin160BitMark = 342;
+
308 const uint16_t kDaikin160OneSpace = 1786;
+
309 const uint16_t kDaikin160ZeroSpace = 700;
+
310 const uint16_t kDaikin160Gap = 29650;
+
311 const uint16_t kDaikin160Sections = 2;
+
312 const uint16_t kDaikin160Section1Length = 7;
+ + +
315 const uint8_t kDaikin160BytePower = 12;
+ +
317 // const uint8_t kDaikin160MaskMode = 0b01110000;
+
318 const uint8_t kDaikin160ByteTemp = 16;
+
319 // const uint8_t kDaikin160MaskTemp = 0b01111110;
+
320 const uint8_t kDaikin160TempOffset = 1;
+
321 const uint8_t kDaikin160TempSize = 6;
+
322 const uint8_t kDaikin160ByteFan = 17;
+
323 const uint8_t kDaikin160MaskFan = 0b00001111;
+
324 const uint8_t kDaikin160ByteSwingV = 13;
+
325 const uint8_t kDaikin160MaskSwingV = 0b11110000;
+
326 const uint8_t kDaikin160SwingVLowest = 0x1;
+
327 const uint8_t kDaikin160SwingVLow = 0x2;
+
328 const uint8_t kDaikin160SwingVMiddle = 0x3;
+
329 const uint8_t kDaikin160SwingVHigh = 0x4;
+
330 const uint8_t kDaikin160SwingVHighest = 0x5;
+
331 const uint8_t kDaikin160SwingVAuto = 0xF;
+
332 
+
333 
+
334 const uint16_t kDaikin176Freq = 38000; // Modulation Frequency in Hz.
+
335 const uint16_t kDaikin176HdrMark = 5070;
+
336 const uint16_t kDaikin176HdrSpace = 2140;
+
337 const uint16_t kDaikin176BitMark = 370;
+
338 const uint16_t kDaikin176OneSpace = 1780;
+
339 const uint16_t kDaikin176ZeroSpace = 710;
+
340 const uint16_t kDaikin176Gap = 29410;
+
341 const uint16_t kDaikin176Sections = 2;
+
342 const uint16_t kDaikin176Section1Length = 7;
+ + +
345 const uint8_t kDaikin176Cool = 0b111; // 7
+
346 const uint8_t kDaikin176BytePower = 14;
+
347 const uint8_t kDaikin176ByteMode = 12;
+
348 const uint8_t kDaikin176MaskMode = 0b01110000;
+
349 const uint8_t kDaikin176ByteModeButton = 13;
+
350 const uint8_t kDaikin176ModeButton = 0b00000100;
+
351 const uint8_t kDaikin176ByteTemp = 17;
+
352 // const uint8_t kDaikin176MaskTemp = 0b01111110;
+
353 const uint8_t kDaikin176TempOffset = 1;
+
354 const uint8_t kDaikin176TempSize = 6;
+
355 const uint8_t kDaikin176DryFanTemp = 17; // Dry/Fan mode is always 17 Celsius.
+
356 const uint8_t kDaikin176ByteFan = 18;
+
357 const uint8_t kDaikin176MaskFan = 0b11110000;
+
358 const uint8_t kDaikin176FanMax = 3;
+
359 const uint8_t kDaikin176ByteSwingH = 18;
+
360 // const uint8_t kDaikin176MaskSwingH = 0b00001111;
+
361 const uint8_t kDaikin176SwingHAuto = 0x5;
+
362 const uint8_t kDaikin176SwingHOff = 0x6;
+
363 
+
364 
+
365 const uint16_t kDaikin128Freq = 38000; // Modulation Frequency in Hz.
+
366 const uint16_t kDaikin128LeaderMark = 9800;
+
367 const uint16_t kDaikin128LeaderSpace = 9800;
+
368 const uint16_t kDaikin128HdrMark = 4600;
+
369 const uint16_t kDaikin128HdrSpace = 2500;
+
370 const uint16_t kDaikin128BitMark = 350;
+
371 const uint16_t kDaikin128OneSpace = 954;
+
372 const uint16_t kDaikin128ZeroSpace = 382;
+
373 const uint16_t kDaikin128Gap = 20300;
+ +
375 const uint16_t kDaikin128Sections = 2;
+
376 const uint16_t kDaikin128SectionLength = 8;
+
377 const uint8_t kDaikin128ByteModeFan = 1;
+
378 // const uint8_t kDaikin128MaskMode = 0b00001111;
+
379 const uint8_t kDaikin128ModeSize = 4;
+
380 const uint8_t kDaikin128Dry = 0b00000001;
+
381 const uint8_t kDaikin128Cool = 0b00000010;
+
382 const uint8_t kDaikin128Fan = 0b00000100;
+
383 const uint8_t kDaikin128Heat = 0b00001000;
+
384 const uint8_t kDaikin128Auto = 0b00001010;
+
385 const uint8_t kDaikin128MaskFan = 0b11110000;
+
386 const uint8_t kDaikin128FanAuto = 0b0001;
+
387 const uint8_t kDaikin128FanHigh = 0b0010;
+
388 const uint8_t kDaikin128FanMed = 0b0100;
+
389 const uint8_t kDaikin128FanLow = 0b1000;
+
390 const uint8_t kDaikin128FanPowerful = 0b0011;
+
391 const uint8_t kDaikin128FanQuiet = 0b1001;
+
392 const uint8_t kDaikin128ByteClockMins = 2;
+
393 const uint8_t kDaikin128ByteClockHours = 3;
+
394 const uint8_t kDaikin128ByteOnTimer = 4;
+
395 const uint8_t kDaikin128ByteOffTimer = 5;
+ + +
398 const uint8_t kDaikin128TimerOffset = 0;
+
399 const uint8_t kDaikin128TimerSize = 7;
+
400 const uint8_t kDaikin128HalfHourOffset = 6;
+ +
402 // const uint8_t kDaikin128MaskHours = 0b00111111;
+
403 const uint8_t kDaikin128HoursOffset = 0;
+
404 const uint8_t kDaikin128HoursSize = 6;
+
405 const uint8_t kDaikin128ByteTemp = 6;
+
406 const uint8_t kDaikin128MinTemp = 16; // C
+
407 const uint8_t kDaikin128MaxTemp = 30; // C
+ +
409 const uint8_t kDaikin128BitSwingOffset = 0;
+
410 const uint8_t kDaikin128BitSwing = 1 << kDaikin128BitSwingOffset; // 0b00000001
+
411 const uint8_t kDaikin128BitSleepOffset = 1;
+
412 const uint8_t kDaikin128BitSleep = 1 << kDaikin128BitSleepOffset; // 0b00000010
+ + +
415 const uint8_t kDaikin128ByteEconoLight = 9;
+
416 const uint8_t kDaikin128BitEconoOffset = 2;
+
417 const uint8_t kDaikin128BitEcono = 1 << kDaikin128BitEconoOffset; // 0b00000100
+
418 const uint8_t kDaikin128BitWall = 0b00001000;
+
419 const uint8_t kDaikin128BitCeiling = 0b00000001;
+ +
421 
+
422 
+
423 const uint16_t kDaikin152Freq = 38000; // Modulation Frequency in Hz.
+
424 const uint8_t kDaikin152LeaderBits = 5;
+
425 const uint16_t kDaikin152HdrMark = 3492;
+
426 const uint16_t kDaikin152HdrSpace = 1718;
+
427 const uint16_t kDaikin152BitMark = 433;
+
428 const uint16_t kDaikin152OneSpace = 1529;
+ +
430 const uint16_t kDaikin152Gap = 25182;
+
431 
+
432 // Byte[5]
+
433 const uint8_t kDaikin152ModeByte = 5; // Mask 0b01110000
+
434 const uint8_t kDaikin152PowerByte = kDaikin152ModeByte; // Mask 0b00000001
+
435 // Byte[6]
+
436 const uint8_t kDaikin152TempByte = 6; // Mask 0b11111110
+
437 const uint8_t kDaikin152TempSize = 7;
+
438 const uint8_t kDaikin152DryTemp = kDaikin2MinCoolTemp; // Celsius
+
439 const uint8_t kDaikin152FanTemp = 0x60; // 96 Celsius
+
440 // Byte[8]
+
441 const uint8_t kDaikin152FanByte = 8;
+ +
443 // Byte[13]
+
444 const uint8_t kDaikin152QuietByte = 13; // Mask 0b00100000
+
445 const uint8_t kDaikin152PowerfulByte = kDaikin152QuietByte; // Mask 0b00000001
+
446 // Byte[16]
+
447 const uint8_t kDaikin152EconoByte = 16; // Mask 0b00000100
+
448 const uint8_t kDaikin152ComfortByte = kDaikin152EconoByte; // Mask 0b00000010
+
449 const uint8_t kDaikin152ComfortOffset = 1; // Mask 0b00000010
+
450 const uint8_t kDaikin152SensorByte = kDaikin152EconoByte; // Mask 0b00001000
+
451 const uint8_t kDaikin152SensorOffset = 3; // Mask 0b00001000
+
452 
+
453 
+ + + + + + +
460 const uint16_t kDaikin64Gap = kDaikin128Gap;
+ +
462 const uint16_t kDaikin64Freq = kDaikin128Freq; // Hz.
+
463 const uint8_t kDaikin64Overhead = 9;
+
464 const int8_t kDaikin64ToleranceDelta = 5; // +5%
+
465 
+
466 const uint64_t kDaikin64KnownGoodState = 0x7C16161607204216;
+
467 const uint8_t kDaikin64ModeOffset = 8;
+
468 const uint8_t kDaikin64ModeSize = 4; // Mask 0b111100000000
+
469 const uint8_t kDaikin64Dry = 0b001;
+
470 const uint8_t kDaikin64Cool = 0b010;
+
471 const uint8_t kDaikin64Fan = 0b100;
+ +
473 const uint8_t kDaikin64FanSize = 4; // Mask 0b1111000000000000
+
474 const uint8_t kDaikin64FanAuto = 0b0001;
+
475 const uint8_t kDaikin64FanLow = 0b1000;
+
476 const uint8_t kDaikin64FanMed = 0b0100;
+
477 const uint8_t kDaikin64FanHigh = 0b0010;
+
478 const uint8_t kDaikin64FanQuiet = 0b1001;
+
479 const uint8_t kDaikin64FanTurbo = 0b0011;
+ +
481 const uint8_t kDaikin64ClockMinsSize = 8;
+
482 const uint8_t kDaikin64ClockHoursSize = 8;
+ +
484  kDaikin64ClockHoursSize; // Mask 0b1111111111111111 << 15
+ + +
487 const uint8_t kDaikin64OnTimeSize = 6;
+ + + + +
492 const uint8_t kDaikin64OffTimeSize = 6;
+ + + +
496 const uint8_t kDaikin64TempOffset = 48;
+
497 const uint8_t kDaikin64TempSize = 8; // Mask 0b11111111 << 47
+
498 const uint8_t kDaikin64MinTemp = 16; // Celsius
+
499 const uint8_t kDaikin64MaxTemp = 30; // Celsius
+
500 const uint8_t kDaikin64SwingVBit = 56;
+ +
502 const uint8_t kDaikin64PowerToggleBit = 59;
+
503 const uint8_t kDaikin64ChecksumOffset = 60;
+
504 const uint8_t kDaikin64ChecksumSize = 4; // Mask 0b1111 << 59
+
505 
+
506 // Legacy defines.
+
507 #define DAIKIN_COOL kDaikinCool
+
508 #define DAIKIN_HEAT kDaikinHeat
+
509 #define DAIKIN_FAN kDaikinFan
+
510 #define DAIKIN_AUTO kDaikinAuto
+
511 #define DAIKIN_DRY kDaikinDry
+
512 #define DAIKIN_MIN_TEMP kDaikinMinTemp
+
513 #define DAIKIN_MAX_TEMP kDaikinMaxTemp
+
514 #define DAIKIN_FAN_MIN kDaikinFanMin
+
515 #define DAIKIN_FAN_MAX kDaikinFanMax
+
516 #define DAIKIN_FAN_AUTO kDaikinFanAuto
+
517 #define DAIKIN_FAN_QUIET kDaikinFanQuiet
+
518 
+
520 class IRDaikinESP {
+
521  public:
+
522  explicit IRDaikinESP(const uint16_t pin, const bool inverted = false,
+
523  const bool use_modulation = true);
+
524 
+
525 #if SEND_DAIKIN
+
526  void send(const uint16_t repeat = kDaikinDefaultRepeat);
+
531  int8_t calibrate(void) { return _irsend.calibrate(); }
+
532 #endif
+
533  void begin(void);
+
534  void on(void);
+
535  void off(void);
+
536  void setPower(const bool on);
+
537  bool getPower(void);
+
538  void setTemp(const uint8_t temp);
+
539  uint8_t getTemp();
+
540  void setFan(const uint8_t fan);
+
541  uint8_t getFan(void);
+
542  void setMode(const uint8_t mode);
+
543  uint8_t getMode(void);
+
544  void setSwingVertical(const bool on);
+
545  bool getSwingVertical(void);
+
546  void setSwingHorizontal(const bool on);
+
547  bool getSwingHorizontal(void);
+
548  bool getQuiet(void);
+
549  void setQuiet(const bool on);
+
550  bool getPowerful(void);
+
551  void setPowerful(const bool on);
+
552  void setSensor(const bool on);
+
553  bool getSensor(void);
+
554  void setEcono(const bool on);
+
555  bool getEcono(void);
+
556  void setMold(const bool on);
+
557  bool getMold(void);
+
558  void setComfort(const bool on);
+
559  bool getComfort(void);
+
560  void enableOnTimer(const uint16_t starttime);
+
561  void disableOnTimer(void);
+
562  uint16_t getOnTime(void);
+
563  bool getOnTimerEnabled();
+
564  void enableOffTimer(const uint16_t endtime);
+
565  void disableOffTimer(void);
+
566  uint16_t getOffTime(void);
+
567  bool getOffTimerEnabled(void);
+
568  void setCurrentTime(const uint16_t mins_since_midnight);
+
569  uint16_t getCurrentTime(void);
+
570  void setCurrentDay(const uint8_t day_of_week);
+
571  uint8_t getCurrentDay(void);
+
572  void setWeeklyTimerEnable(const bool on);
+
573  bool getWeeklyTimerEnable(void);
+
574  uint8_t* getRaw(void);
+
575  void setRaw(const uint8_t new_code[],
+
576  const uint16_t length = kDaikinStateLength);
+
577  static bool validChecksum(uint8_t state[],
+
578  const uint16_t length = kDaikinStateLength);
+
579  static uint8_t convertMode(const stdAc::opmode_t mode);
+
580  static uint8_t convertFan(const stdAc::fanspeed_t speed);
+
581  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
582  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
583  stdAc::state_t toCommon(void);
+
584  String toString(void);
+
585 #ifndef UNIT_TEST
+
586 
+
587  private:
+ +
589 #else
+
590  IRsendTest _irsend;
+
592 #endif
+
594  // # of bytes per command
+ +
596  void stateReset(void);
+
597  void checksum(void);
+
598 };
+
599 
+
602 class IRDaikin2 {
+
603  public:
+
604  explicit IRDaikin2(const uint16_t pin, const bool inverted = false,
+
605  const bool use_modulation = true);
+
606 
+
607 #if SEND_DAIKIN2
+
608  void send(const uint16_t repeat = kDaikin2DefaultRepeat);
+
613  int8_t calibrate(void) { return _irsend.calibrate(); }
+
614 #endif
+
615  void begin();
+
616  void on();
+
617  void off();
+
618  void setPower(const bool state);
+
619  bool getPower();
+
620  void setTemp(const uint8_t temp);
+
621  uint8_t getTemp();
+
622  void setFan(const uint8_t fan);
+
623  uint8_t getFan();
+
624  uint8_t getMode();
+
625  void setMode(const uint8_t mode);
+
626  void setSwingVertical(const uint8_t position);
+
627  uint8_t getSwingVertical();
+
628  void setSwingHorizontal(const uint8_t position);
+
629  uint8_t getSwingHorizontal();
+
630  bool getQuiet();
+
631  void setQuiet(const bool on);
+
632  bool getPowerful();
+
633  void setPowerful(const bool on);
+
634  void setEcono(const bool on);
+
635  bool getEcono();
+
636  void setEye(const bool on);
+
637  bool getEye();
+
638  void setEyeAuto(const bool on);
+
639  bool getEyeAuto();
+
640  void setPurify(const bool on);
+
641  bool getPurify();
+
642  void setMold(const bool on);
+
643  bool getMold();
+
644  void enableOnTimer(const uint16_t starttime);
+
645  void disableOnTimer();
+
646  uint16_t getOnTime();
+
647  bool getOnTimerEnabled();
+
648  void enableSleepTimer(const uint16_t sleeptime);
+
649  void disableSleepTimer();
+
650  uint16_t getSleepTime();
+
651  bool getSleepTimerEnabled();
+
652  void enableOffTimer(const uint16_t endtime);
+
653  void disableOffTimer();
+
654  uint16_t getOffTime();
+
655  bool getOffTimerEnabled();
+
656  void setCurrentTime(const uint16_t time);
+
657  uint16_t getCurrentTime();
+
658  void setBeep(const uint8_t beep);
+
659  uint8_t getBeep();
+
660  void setLight(const uint8_t light);
+
661  uint8_t getLight();
+
662  void setClean(const bool on);
+
663  bool getClean();
+
664  void setFreshAir(const bool on);
+
665  bool getFreshAir();
+
666  void setFreshAirHigh(const bool on);
+
667  bool getFreshAirHigh();
+
668  uint8_t* getRaw();
+
669  void setRaw(const uint8_t new_code[]);
+
670  static bool validChecksum(uint8_t state[],
+
671  const uint16_t length = kDaikin2StateLength);
+
672  static uint8_t convertMode(const stdAc::opmode_t mode);
+
673  static uint8_t convertFan(const stdAc::fanspeed_t speed);
+
674  static uint8_t convertSwingV(const stdAc::swingv_t position);
+
675  static uint8_t convertSwingH(const stdAc::swingh_t position);
+
676  static stdAc::swingv_t toCommonSwingV(const uint8_t setting);
+
677  static stdAc::swingh_t toCommonSwingH(const uint8_t setting);
+
678  stdAc::state_t toCommon(void);
+
679  String toString();
+
680 #ifndef UNIT_TEST
+
681 
+
682  private:
+ +
684 #else
+
685  IRsendTest _irsend;
+
687 #endif
+
689  // # of bytes per command
+ +
691  void stateReset();
+
692  void checksum();
+
693  void clearOnTimerFlag();
+
694  void clearSleepTimerFlag();
+
695 };
+
696 
+
698 class IRDaikin216 {
+
699  public:
+
700  explicit IRDaikin216(const uint16_t pin, const bool inverted = false,
+
701  const bool use_modulation = true);
+
702 
+
703 #if SEND_DAIKIN216
+
704  void send(const uint16_t repeat = kDaikin216DefaultRepeat);
+
709  int8_t calibrate(void) { return _irsend.calibrate(); }
+
710 #endif
+
711  void begin();
+
712  uint8_t* getRaw();
+
713  void setRaw(const uint8_t new_code[]);
+
714  static bool validChecksum(uint8_t state[],
+
715  const uint16_t length = kDaikin216StateLength);
+
716  void on(void);
+
717  void off(void);
+
718  void setPower(const bool on);
+
719  bool getPower(void);
+
720  void setTemp(const uint8_t temp);
+
721  uint8_t getTemp();
+
722  void setMode(const uint8_t mode);
+
723  uint8_t getMode(void);
+
724  static uint8_t convertMode(const stdAc::opmode_t mode);
+
725  void setFan(const uint8_t fan);
+
726  uint8_t getFan(void);
+
727  static uint8_t convertFan(const stdAc::fanspeed_t speed);
+
728  void setSwingVertical(const bool on);
+
729  bool getSwingVertical(void);
+
730  void setSwingHorizontal(const bool on);
+
731  bool getSwingHorizontal(void);
+
732  void setQuiet(const bool on);
+
733  bool getQuiet(void);
+
734  void setPowerful(const bool on);
+
735  bool getPowerful(void);
+
736  stdAc::state_t toCommon(void);
+
737  String toString(void);
+
738 #ifndef UNIT_TEST
+
739 
+
740  private:
+ +
742 #else
+
743  IRsendTest _irsend;
+
745 #endif
+
747  // # of bytes per command
+ +
749  void stateReset();
+
750  void checksum();
+
751 };
+
752 
+
754 class IRDaikin160 {
+
755  public:
+
756  explicit IRDaikin160(const uint16_t pin, const bool inverted = false,
+
757  const bool use_modulation = true);
+
758 
+
759 #if SEND_DAIKIN160
+
760  void send(const uint16_t repeat = kDaikin160DefaultRepeat);
+
765  int8_t calibrate(void) { return _irsend.calibrate(); }
+
766 #endif
+
767  void begin();
+
768  uint8_t* getRaw();
+
769  void setRaw(const uint8_t new_code[]);
+
770  static bool validChecksum(uint8_t state[],
+
771  const uint16_t length = kDaikin160StateLength);
+
772  void on(void);
+
773  void off(void);
+
774  void setPower(const bool on);
+
775  bool getPower(void);
+
776  void setTemp(const uint8_t temp);
+
777  uint8_t getTemp();
+
778  void setMode(const uint8_t mode);
+
779  uint8_t getMode(void);
+
780  static uint8_t convertMode(const stdAc::opmode_t mode);
+
781  void setFan(const uint8_t fan);
+
782  uint8_t getFan(void);
+
783  static uint8_t convertFan(const stdAc::fanspeed_t speed);
+
784  void setSwingVertical(const uint8_t position);
+
785  uint8_t getSwingVertical(void);
+
786  static uint8_t convertSwingV(const stdAc::swingv_t position);
+
787  static stdAc::swingv_t toCommonSwingV(const uint8_t setting);
+
788  stdAc::state_t toCommon(void);
+
789  String toString(void);
+
790 #ifndef UNIT_TEST
+
791 
+
792  private:
+ +
794 #else
+
795  IRsendTest _irsend;
+
797 #endif
+
799  // # of bytes per command
+ +
801  void stateReset();
+
802  void checksum();
+
803 };
+
804 
+
806 class IRDaikin176 {
+
807  public:
+
808  explicit IRDaikin176(const uint16_t pin, const bool inverted = false,
+
809  const bool use_modulation = true);
+
810 
+
811 #if SEND_DAIKIN176
+
812  void send(const uint16_t repeat = kDaikin176DefaultRepeat);
+
817  int8_t calibrate(void) { return _irsend.calibrate(); }
+
818 #endif
+
819  void begin();
+
820  uint8_t* getRaw();
+
821  void setRaw(const uint8_t new_code[]);
+
822  static bool validChecksum(uint8_t state[],
+
823  const uint16_t length = kDaikin176StateLength);
+
824  void on(void);
+
825  void off(void);
+
826  void setPower(const bool on);
+
827  bool getPower(void);
+
828  void setTemp(const uint8_t temp);
+
829  uint8_t getTemp();
+
830  void setMode(const uint8_t mode);
+
831  uint8_t getMode(void);
+
832  static uint8_t convertMode(const stdAc::opmode_t mode);
+
833  void setFan(const uint8_t fan);
+
834  uint8_t getFan(void);
+
835  static uint8_t convertFan(const stdAc::fanspeed_t speed);
+
836  void setSwingHorizontal(const uint8_t position);
+
837  uint8_t getSwingHorizontal(void);
+
838  static uint8_t convertSwingH(const stdAc::swingh_t position);
+
839  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
840  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
841  static stdAc::swingh_t toCommonSwingH(const uint8_t setting);
+
842  stdAc::state_t toCommon(void);
+
843  String toString(void);
+
844 
+
845 #ifndef UNIT_TEST
+
846 
+
847  private:
+ +
849 #else
+
850  IRsendTest _irsend;
+
852 #endif
+
854  // # of bytes per command
+ +
856  uint8_t _saved_temp;
+
857  void stateReset();
+
858  void checksum();
+
859 };
+
860 
+
864 class IRDaikin128 {
+
865  public:
+
866  explicit IRDaikin128(const uint16_t pin, const bool inverted = false,
+
867  const bool use_modulation = true);
+
868 #if SEND_DAIKIN128
+
869  void send(const uint16_t repeat = kDaikin128DefaultRepeat);
+
874  int8_t calibrate(void) { return _irsend.calibrate(); }
+
875 #endif // SEND_DAIKIN128
+
876  void begin();
+
877  void setPowerToggle(const bool toggle);
+
878  bool getPowerToggle(void);
+
879  void setTemp(const uint8_t temp);
+
880  uint8_t getTemp(void);
+
881  void setFan(const uint8_t fan);
+
882  uint8_t getFan(void);
+
883  uint8_t getMode(void);
+
884  void setMode(const uint8_t mode);
+
885  void setSwingVertical(const bool on);
+
886  bool getSwingVertical();
+
887  bool getSleep(void);
+
888  void setSleep(const bool on);
+
889  bool getQuiet(void);
+
890  void setQuiet(const bool on);
+
891  bool getPowerful(void);
+
892  void setPowerful(const bool on);
+
893  void setEcono(const bool on);
+
894  bool getEcono(void);
+
895  void setOnTimer(const uint16_t mins_since_midnight);
+
896  uint16_t getOnTimer(void);
+
897  bool getOnTimerEnabled(void);
+
898  void setOnTimerEnabled(const bool on);
+
899  void setOffTimer(const uint16_t mins_since_midnight);
+
900  uint16_t getOffTimer(void);
+
901  bool getOffTimerEnabled(void);
+
902  void setOffTimerEnabled(const bool on);
+
903  void setClock(const uint16_t mins_since_midnight);
+
904  uint16_t getClock(void);
+
905  void setLightToggle(const uint8_t unit_type);
+
906  uint8_t getLightToggle(void);
+
907  uint8_t* getRaw(void);
+
908  void setRaw(const uint8_t new_code[]);
+
909  static bool validChecksum(uint8_t state[]);
+
910  static uint8_t convertMode(const stdAc::opmode_t mode);
+
911  static uint8_t convertFan(const stdAc::fanspeed_t speed);
+
912  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
913  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
914  stdAc::state_t toCommon(const stdAc::state_t *prev = NULL);
+
915  String toString(void);
+
916 #ifndef UNIT_TEST
+
917 
+
918  private:
+ +
920 #else
+
921  IRsendTest _irsend;
+
923 #endif
+
925  // # of bytes per command
+ +
927  void stateReset(void);
+
928  static uint8_t calcFirstChecksum(const uint8_t state[]);
+
929  static uint8_t calcSecondChecksum(const uint8_t state[]);
+
930  static void setTimer(uint8_t *ptr, const uint16_t mins_since_midnight);
+
931  static uint16_t getTimer(const uint8_t *ptr);
+
932  void checksum(void);
+
933  void clearOnTimerFlag(void);
+
934  void clearSleepTimerFlag(void);
+
935 };
+
936 
+
938 class IRDaikin152 {
+
939  public:
+
940  explicit IRDaikin152(const uint16_t pin, const bool inverted = false,
+
941  const bool use_modulation = true);
+
942 
+
943 #if SEND_DAIKIN152
+
944  void send(const uint16_t repeat = kDaikin152DefaultRepeat);
+
949  int8_t calibrate(void) { return _irsend.calibrate(); }
+
950 #endif
+
951  void begin();
+
952  uint8_t* getRaw();
+
953  void setRaw(const uint8_t new_code[]);
+
954  static bool validChecksum(uint8_t state[],
+
955  const uint16_t length = kDaikin152StateLength);
+
956  void on(void);
+
957  void off(void);
+
958  void setPower(const bool on);
+
959  bool getPower(void);
+
960  void setTemp(const uint8_t temp);
+
961  uint8_t getTemp();
+
962  void setFan(const uint8_t fan);
+
963  uint8_t getFan(void);
+
964  void setMode(const uint8_t mode);
+
965  uint8_t getMode(void);
+
966  void setSwingV(const bool on);
+
967  bool getSwingV(void);
+
968  bool getQuiet(void);
+
969  void setQuiet(const bool on);
+
970  bool getPowerful(void);
+
971  void setPowerful(const bool on);
+
972  void setSensor(const bool on);
+
973  bool getSensor(void);
+
974  void setEcono(const bool on);
+
975  bool getEcono(void);
+
976  void setComfort(const bool on);
+
977  bool getComfort(void);
+
978  static uint8_t convertMode(const stdAc::opmode_t mode);
+
979  static uint8_t convertFan(const stdAc::fanspeed_t speed);
+
980  stdAc::state_t toCommon(void);
+
981  String toString(void);
+
982 #ifndef UNIT_TEST
+
983 
+
984  private:
+ +
986 #else
+
987  IRsendTest _irsend;
+
989 #endif
+
991  // # of bytes per command
+ +
993  void stateReset();
+
994  void checksum();
+
995 };
+
996 
+
998 class IRDaikin64 {
+
999  public:
+
1000  explicit IRDaikin64(const uint16_t pin, const bool inverted = false,
+
1001  const bool use_modulation = true);
+
1002 
+
1003 #if SEND_DAIKIN64
+
1004  void send(const uint16_t repeat = kDaikin64DefaultRepeat);
+
1009  int8_t calibrate(void) { return _irsend.calibrate(); }
+
1010 #endif // SEND_DAIKIN64
+
1011  void begin();
+
1012  uint64_t getRaw();
+
1013  void setRaw(const uint64_t new_state);
+
1014  static uint8_t calcChecksum(const uint64_t state);
+
1015  static bool validChecksum(const uint64_t state);
+
1016  void setPowerToggle(const bool on);
+
1017  bool getPowerToggle(void);
+
1018  void setTemp(const uint8_t temp);
+
1019  uint8_t getTemp();
+
1020  void setFan(const uint8_t fan);
+
1021  uint8_t getFan(void);
+
1022  void setMode(const uint8_t mode);
+
1023  uint8_t getMode(void);
+
1024  void setSwingVertical(const bool on);
+
1025  bool getSwingVertical(void);
+
1026  void setSleep(const bool on);
+
1027  bool getSleep(void);
+
1028  bool getQuiet(void);
+
1029  void setQuiet(const bool on);
+
1030  bool getTurbo(void);
+
1031  void setTurbo(const bool on);
+
1032  void setClock(const uint16_t mins_since_midnight);
+
1033  uint16_t getClock(void);
+
1034  void setOnTimeEnabled(const bool on);
+
1035  bool getOnTimeEnabled(void);
+
1036  void setOnTime(const uint16_t mins_since_midnight);
+
1037  uint16_t getOnTime(void);
+
1038  void setOffTimeEnabled(const bool on);
+
1039  bool getOffTimeEnabled(void);
+
1040  void setOffTime(const uint16_t mins_since_midnight);
+
1041  uint16_t getOffTime(void);
+
1042  static uint8_t convertMode(const stdAc::opmode_t mode);
+
1043  static uint8_t convertFan(const stdAc::fanspeed_t speed);
+
1044  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
1045  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
1046  stdAc::state_t toCommon(const stdAc::state_t *prev = NULL);
+
1047  String toString(void);
+
1048 #ifndef UNIT_TEST
+
1049 
+
1050  private:
+ +
1052 #else
+
1053  IRsendTest _irsend;
+
1055 #endif
+
1057  uint64_t remote_state;
+
1058  void stateReset();
+
1059  void checksum();
+
1060 };
+
1061 #endif // IR_DAIKIN_H_
+
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Daikin.cpp:3957
+
const uint8_t kDaikin2SwingHRightMax
Definition: ir_Daikin.h:267
+
const uint8_t kDaikin64ChecksumOffset
Definition: ir_Daikin.h:503
+
const uint8_t kDaikin64TempOffset
Definition: ir_Daikin.h:496
+
void setCurrentTime(const uint16_t time)
Set the clock on the A/C unit.
Definition: ir_Daikin.cpp:958
+
const uint8_t kDaikinByteTemp
Definition: ir_Daikin.h:159
+
static uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Daikin.cpp:511
+
const uint16_t kDaikin152DefaultRepeat
Definition: IRremoteESP8266.h:854
+
const uint8_t kDaikinModeSize
Definition: ir_Daikin.h:123
+
const uint8_t kDaikin216ByteTemp
Definition: ir_Daikin.h:288
+
static uint8_t convertSwingH(const stdAc::swingh_t position)
Convert a stdAc::swingh_t enum into it's native setting.
Definition: ir_Daikin.cpp:1233
+
static bool validChecksum(uint8_t state[], const uint16_t length=kDaikinStateLength)
Verify the checksum is valid for a given state.
Definition: ir_Daikin.cpp:125
+
const uint16_t kDaikin152OneSpace
Definition: ir_Daikin.h:428
+
const uint8_t kDaikin152PowerByte
Definition: ir_Daikin.h:434
+
const uint8_t kDaikinBitEconoOffset
Definition: ir_Daikin.h:178
+
void setOffTimeEnabled(const bool on)
Set the enable status of the Off Timer.
Definition: ir_Daikin.cpp:3926
+
void on()
Change the power setting to On.
Definition: ir_Daikin.cpp:808
+
bool getPurify()
Get the Purify (Filter) mode status of the A/C.
Definition: ir_Daikin.cpp:1212
+
const uint8_t kDaikin176ByteTemp
Definition: ir_Daikin.h:351
+
void send(const uint16_t repeat=kDaikinDefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Daikin.cpp:116
+
const uint8_t kDaikin152EconoByte
Definition: ir_Daikin.h:447
+
void begin()
Set up hardware to be able to send a message.
Definition: ir_Daikin.cpp:723
+
const uint8_t kDaikinDry
Definition: ir_Daikin.h:118
+
stdAc::state_t toCommon(const stdAc::state_t *prev=NULL)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Daikin.cpp:3072
+
void setPowerful(const bool on)
Set the Powerful (Turbo) mode of the A/C.
Definition: ir_Daikin.cpp:1192
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Daikin.cpp:1598
+
void checksum(void)
Calculate and set the checksum values for the internal state.
Definition: ir_Daikin.cpp:146
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Daikin.cpp:2783
+
const uint8_t kDaikin128BitPowerToggleOffset
Definition: ir_Daikin.h:413
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Daikin.h:531
+
bool getPowerful(void)
Get the Powerful (Turbo) mode of the A/C.
Definition: ir_Daikin.cpp:334
+
const uint8_t kDaikin2BitSleepTimerOffset
Definition: ir_Daikin.h:230
+
const uint8_t kDaikin64OffTimeEnableBit
Definition: ir_Daikin.h:495
+
const uint8_t kDaikinBitOnTimerOffset
Definition: ir_Daikin.h:192
+
const uint8_t kDaikin2BitClean
Definition: ir_Daikin.h:241
+
const uint16_t kDaikin152ZeroSpace
Definition: ir_Daikin.h:429
+
const uint16_t kDaikin64OneSpace
Definition: ir_Daikin.h:457
+
const uint16_t kDaikin2DefaultRepeat
Definition: IRremoteESP8266.h:843
+
const uint8_t kDaikin128BitEconoOffset
Definition: ir_Daikin.h:416
+
const uint8_t kDaikin64Fan
Definition: ir_Daikin.h:471
+
const uint16_t kDaikin64Freq
Definition: ir_Daikin.h:462
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Daikin.cpp:3362
+
const uint8_t kDaikinByteFan
Definition: ir_Daikin.h:160
+
bool getOffTimerEnabled()
Get the enable status of the Off Timer.
Definition: ir_Daikin.cpp:1032
+
const uint8_t kDaikin128BitSwingOffset
Definition: ir_Daikin.h:409
+
const uint8_t kDaikin128MaskLight
Definition: ir_Daikin.h:420
+
void send(const uint16_t repeat=kDaikin2DefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Daikin.cpp:728
+
const uint8_t kDaikin128BitSwing
Definition: ir_Daikin.h:410
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Daikin.cpp:2776
+
void setEyeAuto(const bool on)
Set the Automatic Eye (Sensor) mode of the A/C.
Definition: ir_Daikin.cpp:1110
+
static uint8_t convertSwingH(const stdAc::swingh_t position)
Convert a stdAc::swingh_t enum into it's native setting.
Definition: ir_Daikin.cpp:2461
+
bool getComfort(void)
Get the Comfort mode of the A/C.
Definition: ir_Daikin.cpp:384
+
const uint8_t kDaikin176SwingHAuto
Definition: ir_Daikin.h:361
+
const uint8_t kDaikin64OnTimeHalfHourBit
Definition: ir_Daikin.h:488
+
IRDaikin2(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Daikin.cpp:718
+
const uint8_t kDaikin216TempOffset
Definition: ir_Daikin.h:290
+
bool getWeeklyTimerEnable(void)
Get the enable status of the Weekly Timer.
Definition: ir_Daikin.cpp:491
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Daikin.cpp:111
+
const uint16_t kDaikin176Section2Length
Definition: ir_Daikin.h:343
+
swingv_t
Common A/C settings for Vertical Swing.
Definition: IRsend.h:70
+
void setSwingVertical(const uint8_t position)
Set the Vertical Swing mode of the A/C.
Definition: ir_Daikin.cpp:892
+
static uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Daikin.cpp:1226
+
const uint8_t kDaikinBitSilent
Definition: ir_Daikin.h:173
+
bool getMold()
Get the Mould (filter) mode status of the A/C.
Definition: ir_Daikin.cpp:1068
+
const uint8_t kDaikin128MaskFan
Definition: ir_Daikin.h:385
+
static bool validChecksum(uint8_t state[], const uint16_t length=kDaikin2StateLength)
Verify the checksum is valid for a given state.
Definition: ir_Daikin.cpp:737
+
bool getSwingVertical(void)
Get the Vertical Swing mode of the A/C.
Definition: ir_Daikin.cpp:1677
+
const uint8_t kDaikin128TimerOffset
Definition: ir_Daikin.h:398
+
const uint8_t kDaikin64Overhead
Definition: ir_Daikin.h:463
+
const uint16_t kDaikinOneSpace
Definition: ir_Daikin.h:210
+
const uint8_t kDaikin216ByteSwingH
Definition: ir_Daikin.h:300
+
const uint8_t kDaikin128ByteTemp
Definition: ir_Daikin.h:405
+
const uint8_t kDaikinBitPower
Definition: ir_Daikin.h:156
+
const uint16_t kDaikin2ZeroSpace
Definition: ir_Daikin.h:225
+
Class for handling detailed Daikin 280-bit A/C messages.
Definition: ir_Daikin.h:520
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Daikin.cpp:2385
+
bool getOnTimerEnabled()
Get the enable status of the On Timer.
Definition: ir_Daikin.cpp:415
+
const uint16_t kDaikin2HdrMark
Definition: ir_Daikin.h:221
+
const uint8_t kDaikinBitPowerful
Definition: ir_Daikin.h:170
+
static bool validChecksum(uint8_t state[], const uint16_t length=kDaikin216StateLength)
Verify the checksum is valid for a given state.
Definition: ir_Daikin.cpp:1522
+
void setOffTime(const uint16_t mins_since_midnight)
Set the Off Timer time for the A/C unit.
Definition: ir_Daikin.cpp:3946
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Daikin.cpp:2484
+
const uint8_t kDaikin64OnTimeOffset
Definition: ir_Daikin.h:485
+
const uint8_t kDaikin160ByteFan
Definition: ir_Daikin.h:322
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Daikin.cpp:2022
+
void off(void)
Change the power setting to Off.
Definition: ir_Daikin.cpp:1946
+
Class for handling detailed Daikin 312-bit A/C messages. Code by crankyoldgit, Reverse engineering an...
Definition: ir_Daikin.h:602
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Daikin.h:709
+
const uint16_t kDaikin176StateLength
Definition: IRremoteESP8266.h:855
+
void setSwingHorizontal(const uint8_t position)
Set the Horizontal Swing mode of the A/C.
Definition: ir_Daikin.cpp:2440
+
Class for handling detailed Daikin 128-bit A/C messages. Code by crankyoldgit. Analysis by Daniel Ven...
Definition: ir_Daikin.h:864
+
void setMold(const bool on)
Set the Mould (filter) mode of the A/C.
Definition: ir_Daikin.cpp:1062
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
static stdAc::swingh_t toCommonSwingH(const uint8_t setting)
Convert a native horizontal swing postion to it's common equivalent.
Definition: ir_Daikin.cpp:1249
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Daikin.cpp:1950
+
const uint8_t kDaikin176TempSize
Definition: ir_Daikin.h:354
+
const uint8_t kDaikin64TempSize
Definition: ir_Daikin.h:497
+
uint8_t getSwingVertical(void)
Get the Vertical Swing mode of the A/C.
Definition: ir_Daikin.cpp:2063
+
const uint8_t kDaikin2BitFreshAirHigh
Definition: ir_Daikin.h:245
+
const uint8_t kDaikinBitEcono
Definition: ir_Daikin.h:179
+
void setSwingHorizontal(const bool on)
Set the Horizontal Swing mode of the A/C.
Definition: ir_Daikin.cpp:295
+
void setPowerful(const bool on)
Set the Powerful (Turbo) mode of the A/C.
Definition: ir_Daikin.cpp:1718
+
const uint8_t kDaikin152TempByte
Definition: ir_Daikin.h:436
+
const uint8_t kDaikin64ModeOffset
Definition: ir_Daikin.h:467
+
bool getTurbo(void)
Get the Turbo (Powerful) mode status of the A/C.
Definition: ir_Daikin.cpp:3818
+
static uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Daikin.cpp:2751
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Daikin.cpp:1592
+
bool getFreshAirHigh()
Get the (High) Fresh Air mode status of the A/C.
Definition: ir_Daikin.cpp:1104
+
const uint8_t kDaikinByteSwingH
Definition: ir_Daikin.h:161
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Daikin.cpp:1580
+
bool getPowerToggle(void)
Get the Power toggle setting of the A/C.
Definition: ir_Daikin.cpp:2715
+
const uint16_t kDaikin64HdrMark
Definition: ir_Daikin.h:454
+
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_Daikin.cpp:2687
+
const uint16_t kDaikin176HdrMark
Definition: ir_Daikin.h:335
+
const uint8_t kDaikinBitOnTimer
Definition: ir_Daikin.h:193
+
void setOffTimer(const uint16_t mins_since_midnight)
Set the Off Timer time for the A/C unit.
Definition: ir_Daikin.cpp:3004
+
void disableOnTimer()
Disable the On timer.
Definition: ir_Daikin.cpp:988
+
const uint8_t kDaikinByteEye
Definition: ir_Daikin.h:180
+
bool getEcono(void)
Get the Economical mode of the A/C.
Definition: ir_Daikin.cpp:3469
+
void setClock(const uint16_t mins_since_midnight)
Set the clock on the A/C unit.
Definition: ir_Daikin.cpp:3874
+
const uint8_t kDaikin128FanPowerful
Definition: ir_Daikin.h:390
+
const uint16_t kDaikin128Freq
Definition: ir_Daikin.h:365
+
const uint16_t kDaikinGap
Definition: ir_Daikin.h:211
+
void disableSleepTimer()
Disable the sleep timer.
Definition: ir_Daikin.cpp:1160
+
IRsend _irsend
instance of the IR send class
Definition: ir_Daikin.h:919
+
const uint8_t kDaikinByteOnTimerMinsHigh
Definition: ir_Daikin.h:163
+
const uint8_t kDaikin128MinTemp
Definition: ir_Daikin.h:406
+
void on(void)
Change the power setting to On.
Definition: ir_Daikin.cpp:1943
+
const uint8_t kDaikin2SwingVSwing
Definition: ir_Daikin.h:256
+
const uint8_t kDaikin2BitSleepTimer
Definition: ir_Daikin.h:231
+
void off(void)
Change the power setting to Off.
Definition: ir_Daikin.cpp:1576
+
uint16_t getOnTime(void)
Get the On Timer time to be sent to the A/C unit.
Definition: ir_Daikin.cpp:406
+
bool getPowerful(void)
Get the Powerful (Turbo) mode of the A/C.
Definition: ir_Daikin.cpp:2915
+
const uint8_t kDaikin2BeepSize
Definition: ir_Daikin.h:253
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Daikin.cpp:3707
+
uint8_t * getRaw()
Get a PTR to the internal state/code for this protocol.
Definition: ir_Daikin.cpp:1561
+
bool getPower()
Get the value of the current power setting.
Definition: ir_Daikin.cpp:822
+
void setRaw(const uint8_t new_code[])
Set the internal state from a valid code for this protocol.
Definition: ir_Daikin.cpp:2302
+
const uint8_t kDaikin216ByteSwingV
Definition: ir_Daikin.h:295
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Daikin.cpp:3320
+
const uint8_t kDaikin160ByteSwingV
Definition: ir_Daikin.h:324
+
uint16_t getOnTime()
Get the On Timer time to be sent to the A/C unit.
Definition: ir_Daikin.cpp:996
+
const uint16_t kDaikin160Gap
Definition: ir_Daikin.h:310
+
Class for handling detailed Daikin 64-bit A/C messages.
Definition: ir_Daikin.h:998
+
const uint16_t kDaikinBitMark
Definition: ir_Daikin.h:208
+
bool getEcono()
Get the Economical mode of the A/C.
Definition: ir_Daikin.cpp:1140
+
void enableOffTimer(const uint16_t endtime)
Set the enable status & time of the Off Timer.
Definition: ir_Daikin.cpp:1009
+
static uint8_t calcChecksum(const uint64_t state)
Calculate the checksum for a given state.
Definition: ir_Daikin.cpp:3654
+
const uint8_t kDaikin64ClockOffset
Definition: ir_Daikin.h:480
+
const uint16_t kDaikin152BitMark
Definition: ir_Daikin.h:427
+
uint8_t remote[kDaikinStateLength]
The state of the IR remote.
Definition: ir_Daikin.h:595
+
const uint8_t kDaikin176FanMax
Definition: ir_Daikin.h:358
+
void setCurrentTime(const uint16_t mins_since_midnight)
Set the clock on the A/C unit.
Definition: ir_Daikin.cpp:449
+
void checksum()
Calculate and set the checksum values for the internal state.
Definition: ir_Daikin.cpp:1537
+
const uint16_t kDaikin152HdrSpace
Definition: ir_Daikin.h:426
+
const uint16_t kDaikin160BitMark
Definition: ir_Daikin.h:307
+
void setRaw(const uint8_t new_code[])
Set the internal state from a valid code for this protocol.
Definition: ir_Daikin.cpp:803
+
const uint8_t kDaikinBitOffTimerOffset
Definition: ir_Daikin.h:189
+
bool getPowerful()
Get the Powerful (Turbo) mode of the A/C.
Definition: ir_Daikin.cpp:1200
+
void setEcono(const bool on)
Set the Economy mode of the A/C.
Definition: ir_Daikin.cpp:3461
+
const uint8_t kDaikinByteOffTimerMinsHigh
Definition: ir_Daikin.h:167
+
const uint8_t kDaikin152ComfortOffset
Definition: ir_Daikin.h:449
+
void clearSleepTimerFlag()
Clear the sleep timer flag.
Definition: ir_Daikin.cpp:1155
+
static uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Daikin.cpp:3408
+
const uint8_t kDaikinBitMold
Definition: ir_Daikin.h:187
+
const uint8_t kDaikinModeOffset
Definition: ir_Daikin.h:122
+
const uint8_t kDaikin2MinCoolTemp
Definition: ir_Daikin.h:271
+
const uint8_t kDaikinBitOffTimer
Definition: ir_Daikin.h:190
+
const uint8_t kDaikin216ByteFan
Definition: ir_Daikin.h:293
+
bool getSwingVertical()
Get the Vertical Swing mode of the A/C.
Definition: ir_Daikin.cpp:2853
+
const uint8_t kDaikin128BitSleepOffset
Definition: ir_Daikin.h:411
+
const uint8_t kDaikinDoWOffset
Definition: ir_Daikin.h:151
+ +
const uint8_t kDaikin176ByteModeButton
Definition: ir_Daikin.h:349
+
const uint8_t kDaikin64FanQuiet
Definition: ir_Daikin.h:478
+
bool getEcono(void)
Get the Economical mode of the A/C.
Definition: ir_Daikin.cpp:2882
+
void setPowerToggle(const bool toggle)
Set the Power toggle setting of the A/C.
Definition: ir_Daikin.cpp:2708
+
const uint8_t kDaikin152FanTemp
Definition: ir_Daikin.h:439
+
Class for handling detailed Daikin 216-bit A/C messages.
Definition: ir_Daikin.h:698
+
const uint8_t kDaikinBitMoldOffset
Definition: ir_Daikin.h:186
+
const uint8_t kDaikin64Cool
Definition: ir_Daikin.h:470
+
void setMold(const bool on)
Set the Mould mode of the A/C.
Definition: ir_Daikin.cpp:366
+
const uint8_t kDaikin64FanTurbo
Definition: ir_Daikin.h:479
+
const uint8_t kDaikinFan
Definition: ir_Daikin.h:121
+
bool getPowerful(void)
Get the Powerful (Turbo) mode of the A/C.
Definition: ir_Daikin.cpp:3454
+
IRsend _irsend
instance of the IR send class
Definition: ir_Daikin.h:1051
+
void setFreshAirHigh(const bool on)
Set the (High) Fresh Air mode of the A/C.
Definition: ir_Daikin.cpp:1098
+
void disableOffTimer()
Disable the Off timer.
Definition: ir_Daikin.cpp:1017
+
const uint16_t kDaikinZeroSpace
Definition: ir_Daikin.h:209
+
bool getOffTimeEnabled(void)
Get the enable status of the Off Timer.
Definition: ir_Daikin.cpp:3932
+
const uint8_t kDaikin2LightOffset
Definition: ir_Daikin.h:249
+
const uint8_t kDaikinSection1Length
Definition: ir_Daikin.h:139
+
const uint8_t kDaikinByteChecksum2
Definition: ir_Daikin.h:153
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Daikin.h:949
+
const uint8_t kDaikin64OffTimeOffset
Definition: ir_Daikin.h:491
+
const uint8_t kDaikin2BitEye
Definition: ir_Daikin.h:235
+
const uint8_t kDaikin128BitTimerEnabled
Definition: ir_Daikin.h:397
+
static uint16_t getTimer(const uint8_t *ptr)
Get the time for a timer at the given location.
Definition: ir_Daikin.cpp:2970
+
const uint8_t kDaikin160TempSize
Definition: ir_Daikin.h:321
+
const uint8_t kDaikinClockMinsHighSize
Definition: ir_Daikin.h:150
+
const uint8_t kDaikinBitComfortOffset
Definition: ir_Daikin.h:145
+
uint8_t getTemp()
Get the current temperature setting.
Definition: ir_Daikin.cpp:231
+
const uint8_t kDaikin2BitEyeAutoOffset
Definition: ir_Daikin.h:236
+
const uint8_t kDaikinByteWeeklyTimer
Definition: ir_Daikin.h:182
+
void setSensor(const bool on)
Set the Sensor mode of the A/C.
Definition: ir_Daikin.cpp:340
+
static uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Daikin.cpp:1985
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Daikin.cpp:3533
+
const uint8_t kDaikin64ClockSize
Definition: ir_Daikin.h:483
+
const uint8_t kDaikin176MaskMode
Definition: ir_Daikin.h:348
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
const uint16_t kDaikinUnusedTime
Definition: ir_Daikin.h:195
+
const uint8_t kDaikin216SwingSize
Definition: ir_Daikin.h:297
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Daikin.h:817
+
void setPowerful(const bool on)
Set the Powerful (Turbo) mode of the A/C.
Definition: ir_Daikin.cpp:3442
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Daikin.cpp:1654
+
uint16_t getOffTime()
Get the Off Timer time to be sent to the A/C unit.
Definition: ir_Daikin.cpp:1025
+
bool getFreshAir()
Get the Fresh Air mode status of the A/C.
Definition: ir_Daikin.cpp:1092
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
const uint16_t kDaikin216ZeroSpace
Definition: ir_Daikin.h:279
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Daikin.cpp:2342
+
void off(void)
Change the power setting to Off.
Definition: ir_Daikin.cpp:3310
+
bool getQuiet(void)
Get the Quiet mode status of the A/C.
Definition: ir_Daikin.cpp:2899
+
bool getSwingVertical(void)
Get the Vertical Swing mode of the A/C.
Definition: ir_Daikin.cpp:3856
+
const uint8_t kDaikin2BitPurifyOffset
Definition: ir_Daikin.h:232
+
const uint8_t kDaikin2SwingHLeft
Definition: ir_Daikin.h:264
+
uint8_t * getRaw()
Get a PTR to the internal state/code for this protocol.
Definition: ir_Daikin.cpp:796
+
uint16_t getOffTime(void)
Get the Off Timer time to be sent to the A/C unit.
Definition: ir_Daikin.cpp:3938
+
static stdAc::swingh_t toCommonSwingH(const uint8_t setting)
Convert a native horizontal swing postion to it's common equivalent.
Definition: ir_Daikin.cpp:2472
+
uint8_t getFan()
Get the current fan speed setting.
Definition: ir_Daikin.cpp:876
+
void setQuiet(const bool on)
Set the Quiet mode of the A/C.
Definition: ir_Daikin.cpp:3840
+
uint8_t * getRaw()
Get a PTR to the internal state/code for this protocol.
Definition: ir_Daikin.cpp:1923
+
stdAc::state_t toCommon(const stdAc::state_t *prev=NULL)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Daikin.cpp:3991
+
void setPowerful(const bool on)
Set the Powerful (Turbo) mode of the A/C.
Definition: ir_Daikin.cpp:323
+
static void setTimer(uint8_t *ptr, const uint16_t mins_since_midnight)
Set the time for a timer at the given location.
Definition: ir_Daikin.cpp:2956
+
const uint8_t kDaikin128HoursOffset
Definition: ir_Daikin.h:403
+
const uint8_t kDaikinBitPowerOffset
Definition: ir_Daikin.h:155
+
const uint16_t kDaikinHdrSpace
Definition: ir_Daikin.h:207
+
const uint16_t kDaikin160HdrSpace
Definition: ir_Daikin.h:306
+
std::string String
Definition: IRremoteESP8266.h:1093
+
void setOnTimeEnabled(const bool on)
Set the enable status of the On Timer.
Definition: ir_Daikin.cpp:3895
+
IRDaikinESP(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Daikin.cpp:106
+
void setPower(const bool state)
Change the power setting.
Definition: ir_Daikin.cpp:815
+
const uint8_t kDaikinCurIndex
Definition: ir_Daikin.h:203
+
const uint8_t kDaikin2BitPurify
Definition: ir_Daikin.h:233
+
const uint8_t kDaikin160SwingVHighest
Definition: ir_Daikin.h:330
+
void setSwingVertical(const uint8_t position)
Set the Vertical Swing mode of the A/C.
Definition: ir_Daikin.cpp:2046
+
static uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Daikin.cpp:2819
+
static uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Daikin.cpp:2032
+
const uint16_t kDaikin2Section2Length
Definition: ir_Daikin.h:228
+
uint8_t remote_state[kDaikin176StateLength]
The state of the IR remote.
Definition: ir_Daikin.h:855
+
const uint8_t kDaikin216BytePower
Definition: ir_Daikin.h:285
+
const uint8_t kDaikin64SwingVBit
Definition: ir_Daikin.h:500
+
const uint16_t kDaikin152StateLength
Definition: IRremoteESP8266.h:852
+
const uint8_t kDaikin176ByteSwingH
Definition: ir_Daikin.h:359
+
const uint8_t kDaikin128BitCeiling
Definition: ir_Daikin.h:419
+
void off(void)
Change the power setting to Off.
Definition: ir_Daikin.cpp:207
+
const uint8_t kDaikin64ModeSize
Definition: ir_Daikin.h:468
+
const uint16_t kDaikin160OneSpace
Definition: ir_Daikin.h:308
+
const uint8_t kDaikinOnTimerMinsHighSize
Definition: ir_Daikin.h:165
+
void setFreshAir(const bool on)
Set the Fresh Air mode of the A/C.
Definition: ir_Daikin.cpp:1086
+
void setLight(const uint8_t light)
Set the Light (LED) mode of the A/C.
Definition: ir_Daikin.cpp:1056
+
const uint8_t kDaikin128BitPowerToggle
Definition: ir_Daikin.h:414
+
bool getComfort(void)
Get the Comfort mode of the A/C.
Definition: ir_Daikin.cpp:3500
+
bool getSwingV(void)
Get the Vertical Swing mode of the A/C.
Definition: ir_Daikin.cpp:3421
+
const uint16_t kDaikin128ZeroSpace
Definition: ir_Daikin.h:372
+
String toString()
Convert the current internal state into a human readable string.
Definition: ir_Daikin.cpp:1290
+
bool getSleepTimerEnabled()
Get the Sleep timer enabled status of the A/C.
Definition: ir_Daikin.cpp:1172
+
const uint8_t kDaikinFanMax
Definition: ir_Daikin.h:128
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Daikin.cpp:2729
+
const uint16_t kDaikin176Gap
Definition: ir_Daikin.h:340
+
uint16_t getOffTimer(void)
Get the Off Timer time to be sent to the A/C unit.
Definition: ir_Daikin.cpp:3010
+
const uint8_t kDaikinBytePowerful
Definition: ir_Daikin.h:168
+
const uint8_t kDaikin2BitFreshAirHighOffset
Definition: ir_Daikin.h:244
+
bool getSleep(void)
Get the Sleep mode of the A/C.
Definition: ir_Daikin.cpp:3868
+
void enableOnTimer(const uint16_t starttime)
Set the enable status & time of the On Timer.
Definition: ir_Daikin.cpp:975
+
void setOffTimerEnabled(const bool on)
Set the enable status of the Off Timer.
Definition: ir_Daikin.cpp:2990
+
const uint8_t kDaikin160ByteTemp
Definition: ir_Daikin.h:318
+
const uint8_t kDaikinBitSensor
Definition: ir_Daikin.h:176
+
const uint8_t kDaikin128FanMed
Definition: ir_Daikin.h:388
+
void setFan(const uint8_t fan)
Set the speed of the fan.
Definition: ir_Daikin.cpp:2408
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Daikin.cpp:2127
+
void off(void)
Change the power setting to Off..
Definition: ir_Daikin.cpp:2319
+
void setRaw(const uint8_t new_code[])
Set the internal state from a valid code for this protocol.
Definition: ir_Daikin.cpp:1568
+
const uint8_t kDaikin64PowerToggleBit
Definition: ir_Daikin.h:502
+
const uint8_t kDaikinOnTimerMinsHighOffset
Definition: ir_Daikin.h:164
+
const uint8_t kDaikinSwingOn
Definition: ir_Daikin.h:135
+
const uint16_t kDaikin216Freq
Definition: ir_Daikin.h:274
+
const uint8_t kDaikinSwingOffset
Definition: ir_Daikin.h:133
+
void clearOnTimerFlag()
Clear the On Timer flag.
Definition: ir_Daikin.cpp:983
+
void setSwingVertical(const bool on)
Set the Vertical Swing mode of the A/C.
Definition: ir_Daikin.cpp:282
+
const uint16_t kDaikin216StateLength
Definition: IRremoteESP8266.h:858
+
const uint16_t kDaikin176Freq
Definition: ir_Daikin.h:334
+
uint16_t getCurrentTime(void)
Get the clock time to be sent to the A/C unit.
Definition: ir_Daikin.cpp:460
+
void setQuiet(const bool on)
Set the Quiet mode of the A/C.
Definition: ir_Daikin.cpp:2889
+
const uint8_t kDaikinBitComfort
Definition: ir_Daikin.h:146
+
const uint8_t kDaikin152TempSize
Definition: ir_Daikin.h:437
+
uint8_t getTemp()
Get the current temperature setting.
Definition: ir_Daikin.cpp:1631
+
const uint16_t kDaikin2Section1Length
Definition: ir_Daikin.h:227
+
void setLightToggle(const uint8_t unit_type)
Set the Light toggle setting of the A/C.
Definition: ir_Daikin.cpp:3017
+
const uint8_t kDaikin2SwingHMiddle
Definition: ir_Daikin.h:265
+ +
swingh_t
Common A/C settings for Horizontal Swing.
Definition: IRsend.h:83
+
IRsend _irsend
instance of the IR send class
Definition: ir_Daikin.h:683
+
void checksum()
Calculate and set the checksum values for the internal state.
Definition: ir_Daikin.cpp:3672
+
const uint8_t kDaikin64OnTimeEnableBit
Definition: ir_Daikin.h:490
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Daikin.cpp:580
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Daikin.cpp:2336
+
const uint8_t kDaikin2BitFreshAir
Definition: ir_Daikin.h:243
+
const uint16_t kDaikin152Freq
Definition: ir_Daikin.h:423
+
uint8_t * getRaw()
Get a PTR to the internal state/code for this protocol.
Definition: ir_Daikin.cpp:2295
+
void send(const uint16_t repeat=kDaikin128DefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Daikin.cpp:2701
+
void setQuiet(const bool on)
Set the Quiet mode of the A/C.
Definition: ir_Daikin.cpp:3428
+
const uint16_t kDaikin128HdrSpace
Definition: ir_Daikin.h:369
+
bool getSensor(void)
Get the Sensor mode of the A/C.
Definition: ir_Daikin.cpp:346
+
const uint8_t kDaikinByteSensor
Definition: ir_Daikin.h:174
+
const uint8_t kDaikin128HoursSize
Definition: ir_Daikin.h:404
+
const uint8_t kDaikinBeepOff
Definition: ir_Daikin.h:198
+
const uint8_t kDaikin2BitCleanOffset
Definition: ir_Daikin.h:240
+
void setSensor(const bool on)
Set the Sensor mode of the A/C.
Definition: ir_Daikin.cpp:3475
+
const uint16_t kDaikin176HdrSpace
Definition: ir_Daikin.h:336
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Daikin.cpp:2374
+
static uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Daikin.cpp:3745
+
const uint16_t kDaikin2Sections
Definition: ir_Daikin.h:226
+
const uint8_t kDaikin160SwingVHigh
Definition: ir_Daikin.h:329
+
static uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Daikin.cpp:1616
+
static uint8_t calcSecondChecksum(const uint8_t state[])
Definition: ir_Daikin.cpp:2650
+
void setComfort(const bool on)
Set the Comfort mode of the A/C.
Definition: ir_Daikin.cpp:378
+
const uint16_t kDaikin128StateLength
Definition: IRremoteESP8266.h:849
+
const uint16_t kDaikin176DefaultRepeat
Definition: IRremoteESP8266.h:857
+
const uint8_t kDaikin2BeepOffset
Definition: ir_Daikin.h:252
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Daikin.cpp:259
+
void checksum(void)
Calculate and set the checksum values for the internal state.
Definition: ir_Daikin.cpp:2669
+
const uint8_t kDaikin128BitWall
Definition: ir_Daikin.h:418
+
void setFan(const uint8_t fan)
Set the speed of the fan.
Definition: ir_Daikin.cpp:3773
+
const uint16_t kDaikin2BitMark
Definition: ir_Daikin.h:223
+
static bool validChecksum(uint8_t state[], const uint16_t length=kDaikin152StateLength)
Verify the checksum is valid for a given state.
Definition: ir_Daikin.cpp:3269
+
const uint8_t kDaikinByteClockMinsLow
Definition: ir_Daikin.h:147
+
const uint16_t kDaikin2LeaderSpace
Definition: ir_Daikin.h:219
+
void setComfort(const bool on)
Set the Comfort mode of the A/C.
Definition: ir_Daikin.cpp:3487
+
bool getSwingHorizontal(void)
Get the Horizontal Swing mode of the A/C.
Definition: ir_Daikin.cpp:1691
+
static stdAc::swingv_t toCommonSwingV(const uint8_t setting)
Convert a native vertical swing postion to it's common equivalent.
Definition: ir_Daikin.cpp:933
+
void clearOnTimerFlag(void)
+
const uint16_t kDaikin160Sections
Definition: ir_Daikin.h:311
+
void setSwingV(const bool on)
Set the Vertical Swing mode of the A/C.
Definition: ir_Daikin.cpp:3414
+
const uint8_t kDaikin64OffTimeHalfHourBit
Definition: ir_Daikin.h:493
+
const uint8_t kDaikin64FanAuto
Definition: ir_Daikin.h:474
+
void setSwingHorizontal(const uint8_t position)
Set the Horizontal Swing mode of the A/C.
Definition: ir_Daikin.cpp:948
+
void setQuiet(const bool on)
Set the Quiet mode of the A/C.
Definition: ir_Daikin.cpp:1699
+
const uint16_t kDaikin160Freq
Definition: ir_Daikin.h:304
+
uint8_t remote_state[kDaikin2StateLength]
The state of the IR remote.
Definition: ir_Daikin.h:690
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Daikin.cpp:1264
+
uint8_t remote_state[kDaikin128StateLength]
The state of the IR remote.
Definition: ir_Daikin.h:926
+
bool getPowerful(void)
Get the Powerful (Turbo) mode of the A/C.
Definition: ir_Daikin.cpp:1726
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Daikin.cpp:835
+
const uint8_t kDaikin64Dry
Definition: ir_Daikin.h:469
+
bool getMold(void)
Get the Mould mode status of the A/C.
Definition: ir_Daikin.cpp:372
+
const uint8_t kDaikin2SwingVBreeze
Definition: ir_Daikin.h:258
+
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_Daikin.cpp:185
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Daikin.cpp:2789
+
IRDaikin176(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Daikin.cpp:2239
+
static bool validChecksum(uint8_t state[], const uint16_t length=kDaikin160StateLength)
Verify the checksum is valid for a given state.
Definition: ir_Daikin.cpp:1878
+
const uint8_t kDaikin64FanLow
Definition: ir_Daikin.h:475
+
bool getPowerToggle(void)
Get the Power toggle setting of the A/C.
Definition: ir_Daikin.cpp:3701
+
uint8_t remote_state[kDaikin152StateLength]
The state of the IR remote.
Definition: ir_Daikin.h:992
+
void on(void)
Change the power setting to On.
Definition: ir_Daikin.cpp:3307
+
IRDaikin160(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Daikin.cpp:1867
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Daikin.cpp:3326
+
const uint8_t kDaikinBeepLoud
Definition: ir_Daikin.h:197
+
const uint8_t kDaikinFanAuto
Definition: ir_Daikin.h:129
+
const uint8_t kDaikin152QuietByte
Definition: ir_Daikin.h:444
+
const uint8_t kDaikin128HalfHourOffset
Definition: ir_Daikin.h:400
+
const uint8_t kDaikin128Dry
Definition: ir_Daikin.h:380
+
void setSwingHorizontal(const bool on)
Set the Horizontal Swing mode of the A/C.
Definition: ir_Daikin.cpp:1684
+
const uint64_t kDaikin64KnownGoodState
Definition: ir_Daikin.h:466
+
static bool validChecksum(uint8_t state[], const uint16_t length=kDaikin176StateLength)
Verify the checksum is valid for a given state.
Definition: ir_Daikin.cpp:2250
+
const uint16_t kDaikin216Sections
Definition: ir_Daikin.h:281
+
static uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Daikin.cpp:1664
+
IRDaikin128(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Daikin.cpp:2638
+
uint16_t getOnTimer(void)
Get the On Timer time to be sent to the A/C unit.
Definition: ir_Daikin.cpp:2984
+
const uint8_t kDaikin152DryTemp
Definition: ir_Daikin.h:438
+
void setCurrentDay(const uint8_t day_of_week)
Set the current day of the week to be sent to the A/C unit.
Definition: ir_Daikin.cpp:469
+
IRDaikin64(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Daikin.cpp:3636
+
const uint8_t kDaikin128ByteClockHours
Definition: ir_Daikin.h:393
+
const uint8_t kDaikinTempSize
Definition: ir_Daikin.h:158
+
void checksum()
Calculate and set the checksum values for the internal state.
Definition: ir_Daikin.cpp:2265
+
IRDaikin152(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Daikin.cpp:3250
+
uint16_t getSleepTime()
Get the Sleep Timer time to be sent to the A/C unit.
Definition: ir_Daikin.cpp:1166
+
const uint16_t kDaikin160HdrMark
Definition: ir_Daikin.h:305
+
const uint16_t kDaikin64ZeroSpace
Definition: ir_Daikin.h:458
+
uint8_t getLightToggle(void)
Get the Light toggle setting of the A/C.
Definition: ir_Daikin.cpp:3031
+
const uint8_t kDaikin176MaskFan
Definition: ir_Daikin.h:357
+
static bool validChecksum(uint8_t state[])
Verify the checksum is valid for a given state.
Definition: ir_Daikin.cpp:2658
+
const uint16_t kDaikin128SectionLength
Definition: ir_Daikin.h:376
+
const uint8_t kDaikin176Cool
Definition: ir_Daikin.h:345
+
void setTurbo(const bool on)
Set the Turbo (Powerful) mode of the A/C.
Definition: ir_Daikin.cpp:3824
+
const uint16_t kDaikin128LeaderSpace
Definition: ir_Daikin.h:367
+
uint16_t getClock(void)
Get the clock time to be sent to the A/C unit.
Definition: ir_Daikin.cpp:3885
+
void setFan(const uint8_t fan)
Set the speed of the fan.
Definition: ir_Daikin.cpp:862
+
const uint8_t kDaikinByteOnTimer
Definition: ir_Daikin.h:191
+
void setWeeklyTimerEnable(const bool on)
Set the enable status of the Weekly Timer.
Definition: ir_Daikin.cpp:484
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Daikin.h:1009
+
const uint16_t kDaikin2LeaderMark
Definition: ir_Daikin.h:218
+
const uint8_t kDaikinBeepQuiet
Definition: ir_Daikin.h:196
+
const uint8_t kDaikin2SwingVAuto
Definition: ir_Daikin.h:257
+
const uint8_t kDaikin2BitEyeOffset
Definition: ir_Daikin.h:234
+
static uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Daikin.cpp:498
+
const uint8_t kDaikin160TempOffset
Definition: ir_Daikin.h:320
+
const uint16_t kDaikin216Section1Length
Definition: ir_Daikin.h:282
+
const uint8_t kDaikinLightBright
Definition: ir_Daikin.h:199
+
void checksum()
Calculate and set the checksum values for the internal state.
Definition: ir_Daikin.cpp:3278
+
const uint16_t kDaikin152Gap
Definition: ir_Daikin.h:430
+
void send(const uint16_t repeat=kDaikin176DefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Daikin.cpp:2310
+
static uint8_t convertSwingV(const stdAc::swingv_t position)
Convert a stdAc::swingv_t enum into it's native setting.
Definition: ir_Daikin.cpp:917
+
const uint8_t kDaikin176BytePower
Definition: ir_Daikin.h:346
+
const uint8_t kDaikin128Auto
Definition: ir_Daikin.h:384
+
const uint8_t kDaikin160SwingVMiddle
Definition: ir_Daikin.h:328
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Daikin.cpp:3767
+
void setFan(const uint8_t fan)
Set the speed of the fan.
Definition: ir_Daikin.cpp:2008
+
void setEcono(const bool on)
Set the Economy mode of the A/C.
Definition: ir_Daikin.cpp:2874
+
const uint8_t kDaikinByteEcono
Definition: ir_Daikin.h:177
+
const uint16_t kDaikin128Gap
Definition: ir_Daikin.h:373
+
const uint8_t kDaikin64MaxTemp
Definition: ir_Daikin.h:499
+
const uint8_t kDaikinHeat
Definition: ir_Daikin.h:120
+
const uint16_t kDaikin216OneSpace
Definition: ir_Daikin.h:278
+
const uint8_t kDaikinBitSensorOffset
Definition: ir_Daikin.h:175
+
void checksum()
Calculate and set the checksum values for the internal state.
Definition: ir_Daikin.cpp:1893
+
const uint8_t kDaikin176SwingHOff
Definition: ir_Daikin.h:362
+
void setQuiet(const bool on)
Set the Quiet mode of the A/C.
Definition: ir_Daikin.cpp:309
+
const uint8_t kDaikin216TempSize
Definition: ir_Daikin.h:291
+
const uint16_t kDaikin64BitMark
Definition: ir_Daikin.h:455
+
const uint8_t kDaikin160SwingVLowest
Definition: ir_Daikin.h:326
+
const uint16_t kDaikin216DefaultRepeat
Definition: IRremoteESP8266.h:860
+
uint16_t getOffTime(void)
Get the Off Timer time to be sent to the A/C unit.
Definition: ir_Daikin.cpp:436
+
const uint8_t kDaikinTempOffset
Definition: ir_Daikin.h:157
+
const uint8_t kDaikin2SwingHLeftMax
Definition: ir_Daikin.h:263
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Daikin.cpp:3314
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Daikin.cpp:1761
+
const uint8_t kDaikinCurBit
Definition: ir_Daikin.h:202
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Daikin.h:765
+
bool getQuiet(void)
Get the Quiet mode status of the A/C.
Definition: ir_Daikin.cpp:3834
+
const uint16_t kDaikin176BitMark
Definition: ir_Daikin.h:337
+
const uint16_t kDaikin160DefaultRepeat
Definition: IRremoteESP8266.h:848
+
void setPowerToggle(const bool on)
Set the Power toggle setting of the A/C.
Definition: ir_Daikin.cpp:3695
+
static uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Daikin.cpp:2362
+
void setEcono(const bool on)
Set the Economy mode of the A/C.
Definition: ir_Daikin.cpp:352
+
void off()
Change the power setting to Off.
Definition: ir_Daikin.cpp:811
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Daikin.cpp:2323
+
const int8_t kDaikin64ToleranceDelta
Definition: ir_Daikin.h:464
+
bool getEye()
Get the Eye (Sensor) mode status of the A/C.
Definition: ir_Daikin.cpp:1128
+
const uint8_t kDaikinFanOffset
Definition: ir_Daikin.h:131
+
const uint8_t kDaikin152SensorOffset
Definition: ir_Daikin.h:451
+
const uint8_t kDaikin160SwingVAuto
Definition: ir_Daikin.h:331
+
void begin()
Set up hardware to be able to send a message.
Definition: ir_Daikin.cpp:3255
+
const uint16_t kDaikinHeaderLength
Definition: ir_Daikin.h:137
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Daikin.cpp:211
+
const uint16_t kDaikin64LdrMark
Definition: ir_Daikin.h:459
+
const uint8_t kDaikin176ByteMode
Definition: ir_Daikin.h:347
+
void setFan(const uint8_t fan)
Set the speed of the fan.
Definition: ir_Daikin.cpp:3381
+
uint64_t remote_state
The state of the IR remote.
Definition: ir_Daikin.h:1057
+ +
const uint8_t kDaikinFanSize
Definition: ir_Daikin.h:132
+
void stateReset()
Reset the internal state to a fixed known good state.
Definition: ir_Daikin.cpp:1901
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Daikin.cpp:2518
+
uint8_t getSwingHorizontal()
Get the Horizontal Swing mode of the A/C.
Definition: ir_Daikin.cpp:954
+
const uint8_t kDaikin128Cool
Definition: ir_Daikin.h:381
+
const uint8_t kDaikin128BytePowerSwingSleep
Definition: ir_Daikin.h:408
+
const uint16_t kDaikin176ZeroSpace
Definition: ir_Daikin.h:339
+
const uint8_t kDaikin128Heat
Definition: ir_Daikin.h:383
+
const uint8_t kDaikinSection3Length
Definition: ir_Daikin.h:141
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Daikin.cpp:3333
+
const uint8_t kDaikin160MaskSwingV
Definition: ir_Daikin.h:325
+
const uint16_t kDaikin160Section1Length
Definition: ir_Daikin.h:312
+
void on(void)
Change the power setting to On.
Definition: ir_Daikin.cpp:1573
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Daikin.cpp:2330
+
void begin()
Set up hardware to be able to send a message.
Definition: ir_Daikin.cpp:2244
+
const uint16_t kDaikin128Sections
Definition: ir_Daikin.h:375
+
const uint16_t kDaikin176Sections
Definition: ir_Daikin.h:341
+
bool getQuiet()
Get the Quiet mode status of the A/C.
Definition: ir_Daikin.cpp:1186
+
const uint8_t kDaikinByteChecksum3
Definition: ir_Daikin.h:194
+
const uint16_t kDaikin128DefaultRepeat
Definition: IRremoteESP8266.h:851
+
static uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Daikin.cpp:3356
+
Class for handling detailed Daikin 152-bit A/C messages.
Definition: ir_Daikin.h:938
+
const uint8_t kDaikin216ByteMode
Definition: ir_Daikin.h:286
+
const uint8_t kDaikin64OnTimeSize
Definition: ir_Daikin.h:487
+
const uint8_t kDaikin128ByteOffTimer
Definition: ir_Daikin.h:395
+
void setPowerful(const bool on)
Set the Powerful (Turbo) mode of the A/C.
Definition: ir_Daikin.cpp:2905
+
const uint8_t kDaikin160ByteMode
Definition: ir_Daikin.h:316
+
const uint8_t kDaikin64FanOffset
Definition: ir_Daikin.h:472
+
const uint8_t kDaikin128FanLow
Definition: ir_Daikin.h:389
+
const uint16_t kDaikinStateLength
Definition: IRremoteESP8266.h:836
+
void setOnTime(const uint16_t mins_since_midnight)
Set the On Timer time for the A/C unit.
Definition: ir_Daikin.cpp:3915
+
Class for handling detailed Daikin 160-bit A/C messages.
Definition: ir_Daikin.h:754
+
void stateReset()
Reset the internal state to a fixed known good state.
Definition: ir_Daikin.cpp:3284
+
IRsend _irsend
instance of the IR send class
Definition: ir_Daikin.h:588
+
const uint16_t kDaikin216Section2Length
Definition: ir_Daikin.h:283
+
const uint8_t kDaikin128BitSleep
Definition: ir_Daikin.h:412
+
void begin()
Set up hardware to be able to send a message.
Definition: ir_Daikin.cpp:3641
+
const uint8_t kDaikin64FanMed
Definition: ir_Daikin.h:476
+
void setFan(const uint8_t fan)
Set the speed of the fan.
Definition: ir_Daikin.cpp:236
+
const uint8_t kDaikin152SwingVByte
Definition: ir_Daikin.h:442
+
void stateReset()
Reset the internal state to a fixed known good state.
Definition: ir_Daikin.cpp:760
+
const uint16_t kDaikin128FooterMark
Definition: ir_Daikin.h:374
+
bool getOnTimerEnabled(void)
Get the enable status of the On Timer.
Definition: ir_Daikin.cpp:2946
+
uint8_t getTemp()
Get the current temperature setting.
Definition: ir_Daikin.cpp:888
+
void disableOffTimer(void)
Clear and disable the Off timer.
Definition: ir_Daikin.cpp:429
+
const uint8_t kDaikinByteSilent
Definition: ir_Daikin.h:171
+
void setPurify(const bool on)
Set the Purify (Filter) mode of the A/C.
Definition: ir_Daikin.cpp:1206
+
const uint16_t kDaikin2Gap
Definition: ir_Daikin.h:220
+
const uint8_t kDaikin176TempOffset
Definition: ir_Daikin.h:353
+
const uint8_t kDaikin176ByteFan
Definition: ir_Daikin.h:356
+
void setSleep(const bool on)
Set the Sleep mode of the A/C.
Definition: ir_Daikin.cpp:3862
+
const uint8_t kDaikin152LeaderBits
Definition: ir_Daikin.h:424
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Daikin.cpp:3723
+
void setOnTimer(const uint16_t mins_since_midnight)
Set the On Timer time for the A/C unit.
Definition: ir_Daikin.cpp:2978
+
const uint16_t kDaikinDefaultRepeat
Definition: IRremoteESP8266.h:840
+
const uint16_t kDaikin64DefaultRepeat
Definition: IRremoteESP8266.h:845
+
const uint8_t kDaikin152SensorByte
Definition: ir_Daikin.h:450
+
const uint8_t kDaikin2BitEyeAuto
Definition: ir_Daikin.h:237
+
const uint8_t kDaikin152ModeByte
Definition: ir_Daikin.h:433
+
const uint8_t kDaikinByteOffTimer
Definition: ir_Daikin.h:188
+
const uint16_t kDaikin64LdrSpace
Definition: ir_Daikin.h:461
+
const uint8_t kDaikin128Fan
Definition: ir_Daikin.h:382
+
bool getSwingVertical(void)
Get the Vertical Swing mode of the A/C.
Definition: ir_Daikin.cpp:289
+
const uint8_t kDaikinBitPowerfulOffset
Definition: ir_Daikin.h:169
+
const uint8_t kDaikinBitEye
Definition: ir_Daikin.h:181
+
const uint8_t kDaikinByteOnTimerMinsLow
Definition: ir_Daikin.h:162
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Daikin.h:613
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Daikin.cpp:3805
+
static stdAc::swingv_t toCommonSwingV(const uint8_t setting)
Convert a native vertical swing postion to it's common equivalent.
Definition: ir_Daikin.cpp:2087
+
const uint8_t kDaikinBitWeeklyTimer
Definition: ir_Daikin.h:184
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Daikin.cpp:2491
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Daikin.cpp:3395
+
void setOnTimerEnabled(const bool on)
Set the enable status of the On Timer.
Definition: ir_Daikin.cpp:2939
+
const uint8_t kDaikin128ByteEconoLight
Definition: ir_Daikin.h:415
+
const uint8_t kDaikin216BytePowerful
Definition: ir_Daikin.h:301
+
void setRaw(const uint64_t new_state)
Set the internal state from a valid code for this protocol.
Definition: ir_Daikin.cpp:3691
+
void on(void)
Change the power setting to On.
Definition: ir_Daikin.cpp:2316
+
void enableSleepTimer(const uint16_t sleeptime)
Set the enable status & time of the Sleep Timer.
Definition: ir_Daikin.cpp:1147
+
static bool validChecksum(const uint64_t state)
Verify the checksum is valid for a given state.
Definition: ir_Daikin.cpp:3665
+
bool getOnTimerEnabled()
Get the enable status of the On Timer.
Definition: ir_Daikin.cpp:1003
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Daikin.cpp:1586
+
const uint8_t kDaikin2SwingVHigh
Definition: ir_Daikin.h:254
+
const uint8_t kDaikinClockMinsHighOffset
Definition: ir_Daikin.h:149
+
const uint16_t kDaikin160Section2Length
Definition: ir_Daikin.h:313
+
const uint8_t kDaikin128FanQuiet
Definition: ir_Daikin.h:391
+
const uint8_t kDaikin216SwingOn
Definition: ir_Daikin.h:298
+
const uint8_t kDaikinDoWSize
Definition: ir_Daikin.h:152
+
void enableOnTimer(const uint16_t starttime)
Set the enable status & time of the On Timer.
Definition: ir_Daikin.cpp:390
+
IRsend _irsend
instance of the IR send class
Definition: ir_Daikin.h:985
+
const uint8_t kDaikin128TimerSize
Definition: ir_Daikin.h:399
+
uint8_t getTemp()
Get the current temperature setting.
Definition: ir_Daikin.cpp:2000
+
void on(void)
Change the power setting to On.
Definition: ir_Daikin.cpp:204
+
uint8_t getTemp()
Get the current temperature setting.
Definition: ir_Daikin.cpp:3373
+
void setQuiet(const bool on)
Set the Quiet mode of the A/C.
Definition: ir_Daikin.cpp:1178
+
void setSwingVertical(const bool on)
Set the Vertical Swing mode of the A/C.
Definition: ir_Daikin.cpp:3850
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Daikin.cpp:538
+
const uint8_t kDaikin2FanByte
Definition: ir_Daikin.h:260
+
void checksum()
Calculate and set the checksum values for the internal state.
Definition: ir_Daikin.cpp:752
+
const uint8_t kDaikinByteMold
Definition: ir_Daikin.h:185
+
const uint8_t kDaikin64FanSize
Definition: ir_Daikin.h:473
+
const uint8_t kDaikin160MaskFan
Definition: ir_Daikin.h:323
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Daikin.cpp:217
+
static uint8_t calcFirstChecksum(const uint8_t state[])
Definition: ir_Daikin.cpp:2645
+
const uint8_t kDaikin64MinTemp
Definition: ir_Daikin.h:498
+
const uint8_t kDaikin2SwingHRight
Definition: ir_Daikin.h:266
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Daikin.cpp:1991
+
bool getSleep(void)
Get the Sleep mode of the A/C.
Definition: ir_Daikin.cpp:2867
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Daikin.cpp:3037
+
uint8_t getSwingHorizontal(void)
Get the Horizontal Swing mode of the A/C.
Definition: ir_Daikin.cpp:2453
+
bool getQuiet(void)
Get the Quiet mode status of the A/C.
Definition: ir_Daikin.cpp:3436
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Daikin.cpp:2423
+
void setClock(const uint16_t mins_since_midnight)
Set the clock on the A/C unit.
Definition: ir_Daikin.cpp:2921
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Daikin.cpp:1968
+
uint16_t getOnTime(void)
Get the On Timer time to be sent to the A/C unit.
Definition: ir_Daikin.cpp:3907
+
bool getOffTimerEnabled(void)
Get the enable status of the Off Timer.
Definition: ir_Daikin.cpp:2997
+
const uint16_t kDaikin64Gap
Definition: ir_Daikin.h:460
+
const uint16_t kDaikin128OneSpace
Definition: ir_Daikin.h:371
+
bool getEcono(void)
Get the Economical mode of the A/C.
Definition: ir_Daikin.cpp:360
+
const uint16_t kDaikin152HdrMark
Definition: ir_Daikin.h:425
+
const uint8_t kDaikin2BitMoldOffset
Definition: ir_Daikin.h:238
+
const uint8_t kDaikin2BitPowerOffset
Definition: ir_Daikin.h:246
+
static uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Daikin.cpp:2430
+
const uint8_t kDaikinByteOffTimerMinsLow
Definition: ir_Daikin.h:166
+
const uint8_t kDaikin64SleepBit
Definition: ir_Daikin.h:501
+
const uint8_t kDaikin2SwingHSwing
Definition: ir_Daikin.h:269
+
void setSwingVertical(const bool on)
Set the Vertical Swing mode of the A/C.
Definition: ir_Daikin.cpp:2846
+
bool getSensor(void)
Get the Sensor mode of the A/C.
Definition: ir_Daikin.cpp:3481
+
void enableOffTimer(const uint16_t endtime)
Set the enable status & time of the Off Timer.
Definition: ir_Daikin.cpp:421
+
const uint16_t kDaikin160StateLength
Definition: IRremoteESP8266.h:846
+
const uint16_t kDaikin216HdrMark
Definition: ir_Daikin.h:275
+
const uint8_t kDaikinByteClockMinsHigh
Definition: ir_Daikin.h:148
+
const uint16_t kDaikin2HdrSpace
Definition: ir_Daikin.h:222
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Daikin.cpp:250
+
const uint8_t kDaikin176ModeButton
Definition: ir_Daikin.h:350
+
const uint8_t kDaikinSections
Definition: ir_Daikin.h:138
+
const uint16_t kDaikin2StateLength
Definition: IRremoteESP8266.h:841
+
uint8_t _saved_temp
Definition: ir_Daikin.h:856
+
const uint8_t kDaikinByteComfort
Definition: ir_Daikin.h:143
+
const uint8_t kDaikinByteChecksum1
Definition: ir_Daikin.h:144
+
void stateReset()
Reset the internal state to a fixed known good state.
Definition: ir_Daikin.cpp:2273
+
void setEye(const bool on)
Set the Eye (Sensor) mode of the A/C.
Definition: ir_Daikin.cpp:1122
+
void setRaw(const uint8_t new_code[])
Set the internal state from a valid code for this protocol.
Definition: ir_Daikin.cpp:3302
+
const uint8_t kDaikin64FanHigh
Definition: ir_Daikin.h:477
+
IRsend _irsend
instance of the IR send class
Definition: ir_Daikin.h:793
+
void stateReset()
Reset the internal state to a fixed known good state.
Definition: ir_Daikin.cpp:3678
+
void send(const uint16_t repeat=kDaikin152DefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Daikin.cpp:3260
+
const uint8_t kDaikin64ChecksumSize
Definition: ir_Daikin.h:504
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Daikin.cpp:223
+
const uint8_t kDaikinFanMed
Definition: ir_Daikin.h:127
+
bool getOnTimeEnabled(void)
Get the enable status of the On Timer.
Definition: ir_Daikin.cpp:3901
+
const uint8_t kDaikin152ComfortByte
Definition: ir_Daikin.h:448
+
const uint16_t kDaikin64HdrSpace
Definition: ir_Daikin.h:456
+
void stateReset(void)
Reset the internal state to a fixed known good state.
Definition: ir_Daikin.cpp:2677
+
void send(const uint16_t repeat=kDaikin216DefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Daikin.cpp:1513
+
void setRaw(const uint8_t new_code[], const uint16_t length=kDaikinStateLength)
Set the internal state from a valid code for this protocol.
Definition: ir_Daikin.cpp:193
+
const uint8_t kDaikin128BitTimerEnabledOffset
Definition: ir_Daikin.h:396
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Daikin.cpp:3506
+
bool getQuiet(void)
Get the Quiet mode status of the A/C.
Definition: ir_Daikin.cpp:317
+
void setSwingVertical(const bool on)
Set the Vertical Swing mode of the A/C.
Definition: ir_Daikin.cpp:1670
+
const uint8_t kDaikin2LightSize
Definition: ir_Daikin.h:250
+
const uint8_t kDaikinSwingOff
Definition: ir_Daikin.h:136
+
uint8_t getTemp()
Get the current temperature setting.
Definition: ir_Daikin.cpp:2400
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Daikin.cpp:3729
+
const uint16_t kMarkExcess
Definition: IRrecv.h:24
+
const uint8_t kDaikin216SwingOff
Definition: ir_Daikin.h:299
+
void stateReset()
Reset the internal state to a fixed known good state.
Definition: ir_Daikin.cpp:1545
+
const uint8_t kDaikinSwingSize
Definition: ir_Daikin.h:134
+
const uint8_t kDaikinAuto
Definition: ir_Daikin.h:117
+
static uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Daikin.cpp:3791
+
const uint16_t kDaikin216BitMark
Definition: ir_Daikin.h:277
+
const uint8_t kDaikinCool
Definition: ir_Daikin.h:119
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Daikin.h:874
+
void begin()
Set up hardware to be able to send a message.
Definition: ir_Daikin.cpp:2643
+
const uint16_t kDaikin160ZeroSpace
Definition: ir_Daikin.h:309
+
const uint64_t kDaikinFirstHeader64
Definition: ir_Daikin.h:213
+
const uint8_t kDaikin128ByteModeFan
Definition: ir_Daikin.h:377
+
const uint16_t kDaikin216Gap
Definition: ir_Daikin.h:280
+
const uint8_t kDaikin2BitPower
Definition: ir_Daikin.h:247
+
void setBeep(const uint8_t beep)
Set the Beep mode of the A/C.
Definition: ir_Daikin.cpp:1044
+
void begin()
Set up hardware to be able to send a message.
Definition: ir_Daikin.cpp:1508
+
const uint8_t kDaikinFanQuiet
Definition: ir_Daikin.h:130
+
const uint16_t kDaikinMarkExcess
Definition: ir_Daikin.h:205
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Daikin.cpp:2764
+
uint8_t getBeep()
Get the Beep status of the A/C.
Definition: ir_Daikin.cpp:1038
+
const uint8_t kDaikinTolerance
Definition: ir_Daikin.h:204
+
bool getOffTimerEnabled(void)
Get the enable status of the Off Timer.
Definition: ir_Daikin.cpp:443
+
const uint8_t kDaikin216MaskFan
Definition: ir_Daikin.h:294
+
bool getSwingHorizontal(void)
Get the Horizontal Swing mode of the A/C.
Definition: ir_Daikin.cpp:302
+
const uint8_t kDaikin2SwingVLow
Definition: ir_Daikin.h:255
+
const uint8_t kDaikin160BytePower
Definition: ir_Daikin.h:315
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Daikin.cpp:525
+
void setClean(const bool on)
Set the Auto clean mode of the A/C.
Definition: ir_Daikin.cpp:1074
+
const uint16_t kDaikin216HdrSpace
Definition: ir_Daikin.h:276
+
const uint8_t kDaikinSection2Length
Definition: ir_Daikin.h:140
+
const uint8_t kDaikin128ModeSize
Definition: ir_Daikin.h:379
+
const uint16_t kDaikin176OneSpace
Definition: ir_Daikin.h:338
+
bool getEyeAuto()
Get the Automaitc Eye (Sensor) mode status of the A/C.
Definition: ir_Daikin.cpp:1116
+
IRsend _irsend
instance of the IR send class
Definition: ir_Daikin.h:848
+
uint8_t * getRaw()
Get a PTR to the internal state/code for this protocol.
Definition: ir_Daikin.cpp:3295
+
const uint16_t kDaikinHdrMark
Definition: ir_Daikin.h:206
+
const uint8_t kDaikin128ByteClockMins
Definition: ir_Daikin.h:392
+
const uint8_t kDaikinLightOff
Definition: ir_Daikin.h:201
+
void setEcono(const bool on)
Set the Economy mode of the A/C.
Definition: ir_Daikin.cpp:1134
+
static uint8_t convertSwingV(const stdAc::swingv_t position)
Convert a stdAc::swingv_t enum into it's native setting.
Definition: ir_Daikin.cpp:2071
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Daikin.cpp:552
+
const uint8_t kDaikin2Tolerance
Definition: ir_Daikin.h:229
+
const uint8_t kDaikin160SwingVLow
Definition: ir_Daikin.h:327
+
const uint8_t kDaikin128BitHalfHour
Definition: ir_Daikin.h:401
+
const uint8_t kDaikin128BitEcono
Definition: ir_Daikin.h:417
+
uint8_t getTemp()
Get the current temperature setting.
Definition: ir_Daikin.cpp:3716
+
const uint8_t kDaikin176DryFanTemp
Definition: ir_Daikin.h:355
+
uint8_t getMode()
Get the operating mode setting of the A/C.
Definition: ir_Daikin.cpp:829
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Daikin.cpp:1962
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Daikin.cpp:265
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Daikin.cpp:2833
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Daikin.cpp:2722
+
const uint16_t kDaikin2OneSpace
Definition: ir_Daikin.h:224
+
const uint8_t kDaikin2SwingHWide
Definition: ir_Daikin.h:262
+
const uint8_t kDaikin152FanByte
Definition: ir_Daikin.h:441
+
uint8_t remote_state[kDaikin216StateLength]
The state of the IR remote.
Definition: ir_Daikin.h:748
+
const uint8_t kDaikin64ClockHoursSize
Definition: ir_Daikin.h:482
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Daikin.cpp:3756
+
uint64_t getRaw()
Get a copy of the internal state as a valid code for this protocol.
Definition: ir_Daikin.cpp:3684
+
const uint16_t kDaikin128HdrMark
Definition: ir_Daikin.h:368
+
uint8_t getLight()
Get the Light status of the A/C.
Definition: ir_Daikin.cpp:1050
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
void setRaw(const uint8_t new_code[])
Set the internal state from a valid code for this protocol.
Definition: ir_Daikin.cpp:2694
+
void send(const uint16_t repeat=kDaikin64DefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Daikin.cpp:3646
+
void setFan(const uint8_t fan)
Set the speed of the fan.
Definition: ir_Daikin.cpp:1639
+
uint8_t getCurrentDay(void)
Get the current day of the week to be sent to the A/C unit.
Definition: ir_Daikin.cpp:477
+
bool getClean()
Get the Auto Clean mode status of the A/C.
Definition: ir_Daikin.cpp:1080
+
const uint8_t kDaikin2BitMold
Definition: ir_Daikin.h:239
+
const uint8_t kDaikinBitSilentOffset
Definition: ir_Daikin.h:172
+
void begin()
Set up hardware to be able to send a message.
Definition: ir_Daikin.cpp:1872
+
void setRaw(const uint8_t new_code[])
Set the internal state from a valid code for this protocol.
Definition: ir_Daikin.cpp:1930
+
void setFan(const uint8_t fan)
Set the speed of the fan.
Definition: ir_Daikin.cpp:2796
+
void stateReset(void)
Reset the internal state to a fixed known good state.
Definition: ir_Daikin.cpp:156
+
void clearSleepTimerFlag(void)
+
const uint8_t kDaikin128MaxTemp
Definition: ir_Daikin.h:407
+
void send(const uint16_t repeat=kDaikin160DefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Daikin.cpp:1937
+
const uint8_t kDaikinMaxTemp
Definition: ir_Daikin.h:125
+
Class for handling detailed Daikin 176-bit A/C messages.
Definition: ir_Daikin.h:806
+
const uint8_t kDaikin128FanHigh
Definition: ir_Daikin.h:387
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Daikin.cpp:2101
+
const uint8_t kDaikin128FanAuto
Definition: ir_Daikin.h:386
+
uint8_t getSwingVertical()
Get the Vertical Swing mode of the A/C.
Definition: ir_Daikin.cpp:910
+
IRsend _irsend
instance of the IR send class
Definition: ir_Daikin.h:741
+
static uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Daikin.cpp:1219
+
const uint8_t kDaikinBitWeeklyTimerOffset
Definition: ir_Daikin.h:183
+
uint8_t remote_state[kDaikin160StateLength]
The state of the IR remote.
Definition: ir_Daikin.h:800
+
const uint16_t kDaikin176Section1Length
Definition: ir_Daikin.h:342
+
const uint16_t kDaikin2Freq
Definition: ir_Daikin.h:217
+
const uint16_t kDaikin128BitMark
Definition: ir_Daikin.h:370
+
const uint8_t kDaikinMinTemp
Definition: ir_Daikin.h:124
+
uint16_t getClock(void)
Get the clock time to be sent to the A/C unit.
Definition: ir_Daikin.cpp:2932
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Daikin.cpp:1622
+
const uint8_t kDaikin2BitFreshAirOffset
Definition: ir_Daikin.h:242
+
bool getQuiet(void)
Get the Quiet mode status of the A/C.
Definition: ir_Daikin.cpp:1712
+
const uint8_t kDaikin152PowerfulByte
Definition: ir_Daikin.h:445
+
void disableOnTimer(void)
Clear and disable the On timer.
Definition: ir_Daikin.cpp:399
+
IRDaikin216(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class Constructor.
Definition: ir_Daikin.cpp:1503
+
const uint8_t kDaikin64ClockMinsSize
Definition: ir_Daikin.h:481
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Daikin.cpp:851
+
const uint8_t kDaikinFanMin
Definition: ir_Daikin.h:126
+
const uint8_t kDaikinBytePower
Definition: ir_Daikin.h:154
+
const uint16_t kDaikin128LeaderMark
Definition: ir_Daikin.h:366
+
void setSleep(const bool on)
Set the Sleep mode of the A/C.
Definition: ir_Daikin.cpp:2860
+
const uint8_t kDaikin2SwingVCirculate
Definition: ir_Daikin.h:259
+
const uint8_t kDaikin2SwingHAuto
Definition: ir_Daikin.h:268
+
const uint8_t kDaikinLightDim
Definition: ir_Daikin.h:200
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Daikin.cpp:1956
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Daikin.cpp:1733
+
const uint8_t kDaikin64OffTimeSize
Definition: ir_Daikin.h:492
+
uint16_t getCurrentTime()
Get the clock time to be sent to the A/C unit.
Definition: ir_Daikin.cpp:967
+
const uint8_t kDaikin128ByteOnTimer
Definition: ir_Daikin.h:394
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Delonghi_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Delonghi_8cpp.html new file mode 100644 index 000000000..e71f63ef8 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Delonghi_8cpp.html @@ -0,0 +1,220 @@ + + + + + + + +IRremoteESP8266: src/ir_Delonghi.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Delonghi.cpp File Reference
+
+
+ +

Delonghi based protocol. +More...

+ + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kDelonghiAcHdrMark = 8984
 
const uint16_t kDelonghiAcBitMark = 572
 
const uint16_t kDelonghiAcHdrSpace = 4200
 
const uint16_t kDelonghiAcOneSpace = 1558
 
const uint16_t kDelonghiAcZeroSpace = 510
 
const uint32_t kDelonghiAcGap = kDefaultMessageGap
 
const uint16_t kDelonghiAcFreq = 38000
 
const uint16_t kDelonghiAcOverhead = 3
 
+

Detailed Description

+

Delonghi based protocol.

+

Variable Documentation

+ +

◆ kDelonghiAcBitMark

+ +
+
+ + + + +
const uint16_t kDelonghiAcBitMark = 572
+
+ +
+
+ +

◆ kDelonghiAcFreq

+ +
+
+ + + + +
const uint16_t kDelonghiAcFreq = 38000
+
+ +
+
+ +

◆ kDelonghiAcGap

+ +
+
+ + + + +
const uint32_t kDelonghiAcGap = kDefaultMessageGap
+
+ +
+
+ +

◆ kDelonghiAcHdrMark

+ +
+
+ + + + +
const uint16_t kDelonghiAcHdrMark = 8984
+
+ +
+
+ +

◆ kDelonghiAcHdrSpace

+ +
+
+ + + + +
const uint16_t kDelonghiAcHdrSpace = 4200
+
+ +
+
+ +

◆ kDelonghiAcOneSpace

+ +
+
+ + + + +
const uint16_t kDelonghiAcOneSpace = 1558
+
+ +
+
+ +

◆ kDelonghiAcOverhead

+ +
+
+ + + + +
const uint16_t kDelonghiAcOverhead = 3
+
+ +
+
+ +

◆ kDelonghiAcZeroSpace

+ +
+
+ + + + +
const uint16_t kDelonghiAcZeroSpace = 510
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Delonghi_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Delonghi_8h.html new file mode 100644 index 000000000..4a6219b46 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Delonghi_8h.html @@ -0,0 +1,695 @@ + + + + + + + +IRremoteESP8266: src/ir_Delonghi.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Delonghi.h File Reference
+
+
+ +

Delonghi A/C. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRDelonghiAc
 Class for handling detailed Delonghi A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kDelonghiAcTempOffset = 8
 
const uint8_t kDelonghiAcTempSize = 5
 
const uint8_t kDelonghiAcTempMinC = 18
 
const uint8_t kDelonghiAcTempMaxC = 32
 
const uint8_t kDelonghiAcTempMinF = 64
 
const uint8_t kDelonghiAcTempMaxF = 90
 
const uint8_t kDelonghiAcTempAutoDryMode = 0
 
const uint8_t kDelonghiAcTempFanMode = 0b00110
 
const uint8_t kDelonghiAcFanOffset
 
const uint8_t kDelonghiAcFanSize = 2
 
const uint8_t kDelonghiAcFanAuto = 0b00
 
const uint8_t kDelonghiAcFanHigh = 0b01
 
const uint8_t kDelonghiAcFanMedium = 0b10
 
const uint8_t kDelonghiAcFanLow = 0b11
 
const uint8_t kDelonghiAcTempUnitBit
 
const uint8_t kDelonghiAcPowerBit = kDelonghiAcTempUnitBit + 1
 
const uint8_t kDelonghiAcModeOffset = kDelonghiAcPowerBit + 1
 
const uint8_t kDelonghiAcModeSize = 3
 
const uint8_t kDelonghiAcCool = 0b000
 
const uint8_t kDelonghiAcDry = 0b001
 
const uint8_t kDelonghiAcFan = 0b010
 
const uint8_t kDelonghiAcAuto = 0b100
 
const uint8_t kDelonghiAcBoostBit
 
const uint8_t kDelonghiAcSleepBit = kDelonghiAcBoostBit + 1
 
const uint8_t kDelonghiAcOnTimerEnableBit = kDelonghiAcSleepBit + 3
 
const uint8_t kDelonghiAcHoursSize = 5
 
const uint8_t kDelonghiAcMinsSize = 6
 
const uint16_t kDelonghiAcTimerMax = 23 * 60 + 59
 
const uint8_t kDelonghiAcOnTimerHoursOffset
 
const uint8_t kDelonghiAcOnTimerMinsOffset
 
const uint8_t kDelonghiAcOffTimerEnableBit
 
const uint8_t kDelonghiAcOffTimerHoursOffset
 
const uint8_t kDelonghiAcOffTimerMinsOffset
 
const uint8_t kDelonghiAcChecksumOffset
 
const uint8_t kDelonghiAcChecksumSize = 8
 
+

Detailed Description

+

Delonghi A/C.

+
Note
Kudos to TheMaxxz For the breakdown and mapping of the bit values.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/1096
+

Variable Documentation

+ +

◆ kDelonghiAcAuto

+ +
+
+ + + + +
const uint8_t kDelonghiAcAuto = 0b100
+
+ +
+
+ +

◆ kDelonghiAcBoostBit

+ +
+
+ + + + +
const uint8_t kDelonghiAcBoostBit
+
+Initial value: +
+
+ +

◆ kDelonghiAcChecksumOffset

+ +
+
+ + + + +
const uint8_t kDelonghiAcChecksumOffset
+
+
+ +

◆ kDelonghiAcChecksumSize

+ +
+
+ + + + +
const uint8_t kDelonghiAcChecksumSize = 8
+
+ +
+
+ +

◆ kDelonghiAcCool

+ +
+
+ + + + +
const uint8_t kDelonghiAcCool = 0b000
+
+ +
+
+ +

◆ kDelonghiAcDry

+ +
+
+ + + + +
const uint8_t kDelonghiAcDry = 0b001
+
+ +
+
+ +

◆ kDelonghiAcFan

+ +
+
+ + + + +
const uint8_t kDelonghiAcFan = 0b010
+
+ +
+
+ +

◆ kDelonghiAcFanAuto

+ +
+
+ + + + +
const uint8_t kDelonghiAcFanAuto = 0b00
+
+ +
+
+ +

◆ kDelonghiAcFanHigh

+ +
+
+ + + + +
const uint8_t kDelonghiAcFanHigh = 0b01
+
+ +
+
+ +

◆ kDelonghiAcFanLow

+ +
+
+ + + + +
const uint8_t kDelonghiAcFanLow = 0b11
+
+ +
+
+ +

◆ kDelonghiAcFanMedium

+ +
+
+ + + + +
const uint8_t kDelonghiAcFanMedium = 0b10
+
+ +
+
+ +

◆ kDelonghiAcFanOffset

+ +
+
+ + + + +
const uint8_t kDelonghiAcFanOffset
+
+Initial value: +
+
+ +

◆ kDelonghiAcFanSize

+ +
+
+ + + + +
const uint8_t kDelonghiAcFanSize = 2
+
+ +
+
+ +

◆ kDelonghiAcHoursSize

+ +
+
+ + + + +
const uint8_t kDelonghiAcHoursSize = 5
+
+ +
+
+ +

◆ kDelonghiAcMinsSize

+ +
+
+ + + + +
const uint8_t kDelonghiAcMinsSize = 6
+
+ +
+
+ +

◆ kDelonghiAcModeOffset

+ +
+
+ + + + +
const uint8_t kDelonghiAcModeOffset = kDelonghiAcPowerBit + 1
+
+ +
+
+ +

◆ kDelonghiAcModeSize

+ +
+
+ + + + +
const uint8_t kDelonghiAcModeSize = 3
+
+ +
+
+ +

◆ kDelonghiAcOffTimerEnableBit

+ +
+
+ + + + +
const uint8_t kDelonghiAcOffTimerEnableBit
+
+
+ +

◆ kDelonghiAcOffTimerHoursOffset

+ +
+
+ + + + +
const uint8_t kDelonghiAcOffTimerHoursOffset
+
+Initial value: +
+
+ +

◆ kDelonghiAcOffTimerMinsOffset

+ +
+
+ + + + +
const uint8_t kDelonghiAcOffTimerMinsOffset
+
+
+ +

◆ kDelonghiAcOnTimerEnableBit

+ +
+
+ + + + +
const uint8_t kDelonghiAcOnTimerEnableBit = kDelonghiAcSleepBit + 3
+
+ +
+
+ +

◆ kDelonghiAcOnTimerHoursOffset

+ +
+
+ + + + +
const uint8_t kDelonghiAcOnTimerHoursOffset
+
+Initial value: +
+
+ +

◆ kDelonghiAcOnTimerMinsOffset

+ +
+
+ + + + +
const uint8_t kDelonghiAcOnTimerMinsOffset
+
+
+ +

◆ kDelonghiAcPowerBit

+ +
+
+ + + + +
const uint8_t kDelonghiAcPowerBit = kDelonghiAcTempUnitBit + 1
+
+ +
+
+ +

◆ kDelonghiAcSleepBit

+ +
+
+ + + + +
const uint8_t kDelonghiAcSleepBit = kDelonghiAcBoostBit + 1
+
+ +
+
+ +

◆ kDelonghiAcTempAutoDryMode

+ +
+
+ + + + +
const uint8_t kDelonghiAcTempAutoDryMode = 0
+
+ +
+
+ +

◆ kDelonghiAcTempFanMode

+ +
+
+ + + + +
const uint8_t kDelonghiAcTempFanMode = 0b00110
+
+ +
+
+ +

◆ kDelonghiAcTempMaxC

+ +
+
+ + + + +
const uint8_t kDelonghiAcTempMaxC = 32
+
+ +
+
+ +

◆ kDelonghiAcTempMaxF

+ +
+
+ + + + +
const uint8_t kDelonghiAcTempMaxF = 90
+
+ +
+
+ +

◆ kDelonghiAcTempMinC

+ +
+
+ + + + +
const uint8_t kDelonghiAcTempMinC = 18
+
+ +
+
+ +

◆ kDelonghiAcTempMinF

+ +
+
+ + + + +
const uint8_t kDelonghiAcTempMinF = 64
+
+ +
+
+ +

◆ kDelonghiAcTempOffset

+ +
+
+ + + + +
const uint8_t kDelonghiAcTempOffset = 8
+
+ +
+
+ +

◆ kDelonghiAcTempSize

+ +
+
+ + + + +
const uint8_t kDelonghiAcTempSize = 5
+
+ +
+
+ +

◆ kDelonghiAcTempUnitBit

+ +
+
+ + + + +
const uint8_t kDelonghiAcTempUnitBit
+
+Initial value: +
+
+ +

◆ kDelonghiAcTimerMax

+ +
+
+ + + + +
const uint16_t kDelonghiAcTimerMax = 23 * 60 + 59
+
+ +
+
+
+
const uint8_t kDelonghiAcTempOffset
Definition: ir_Delonghi.h:50
+
const uint8_t kDelonghiAcOnTimerHoursOffset
Definition: ir_Delonghi.h:82
+
const uint8_t kDelonghiAcModeOffset
Definition: ir_Delonghi.h:68
+
const uint8_t kDelonghiAcOnTimerMinsOffset
Definition: ir_Delonghi.h:84
+
const uint8_t kDelonghiAcModeSize
Definition: ir_Delonghi.h:69
+
const uint8_t kDelonghiAcTempSize
Definition: ir_Delonghi.h:51
+
const uint8_t kDelonghiAcOffTimerMinsOffset
Definition: ir_Delonghi.h:91
+
const uint8_t kDelonghiAcFanSize
Definition: ir_Delonghi.h:60
+
const uint8_t kDelonghiAcOnTimerEnableBit
Definition: ir_Delonghi.h:78
+
const uint8_t kDelonghiAcMinsSize
Definition: ir_Delonghi.h:80
+
const uint8_t kDelonghiAcOffTimerEnableBit
Definition: ir_Delonghi.h:87
+
const uint8_t kDelonghiAcHoursSize
Definition: ir_Delonghi.h:79
+
const uint8_t kDelonghiAcFanOffset
Definition: ir_Delonghi.h:58
+
const uint8_t kDelonghiAcOffTimerHoursOffset
Definition: ir_Delonghi.h:89
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Delonghi_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Delonghi_8h_source.html new file mode 100644 index 000000000..c14c0dbe1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Delonghi_8h_source.html @@ -0,0 +1,323 @@ + + + + + + + +IRremoteESP8266: src/ir_Delonghi.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Delonghi.h
+
+
+Go to the documentation of this file.
1 // Copyright 2020 David Conran
+
2 
+
7 
+
8 // Supports:
+
9 // Brand: Delonghi, Model: PAC A95
+
10 
+
11 #ifndef IR_DELONGHI_H_
+
12 #define IR_DELONGHI_H_
+
13 
+
14 #define __STDC_LIMIT_MACROS
+
15 #include <stdint.h>
+
16 #ifndef UNIT_TEST
+
17 #include <Arduino.h>
+
18 #endif
+
19 #include "IRremoteESP8266.h"
+
20 #include "IRsend.h"
+
21 #ifdef UNIT_TEST
+
22 #include "IRsend_test.h"
+
23 #endif
+
24 
+
25 /* State bit map:
+
26 
+
27 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+------+
+
28 | FIXED HEADER | TEMPERATURE | FAN |F or C|
+
29 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+------+
+
30  0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+
31 
+
32 +--+--+--+--+-----+-----+
+
33 |ON| MODE |Boost|Sleep|
+
34 +--+--+--+--+-----+-----+
+
35 16 17 18 19 20 21
+
36 
+
37 +--+--+------------+--+--+--+--+--+--+--+--+--+--+--+--+--+
+
38 | 0| 0|Timer Enable| ON TIME HOUR | 0 0| ON TIME MIN |
+
39 +--+--+------------+--+--+--+--+--+--+--+--+--+--+--+--+--+
+
40  22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
+
41 
+
42 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+
43 | 0 0| OFF TIMER | CHECKSUM |
+
44 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+
45  38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
+
46 
+
47 */
+
48 
+
49 // Constants
+
50 const uint8_t kDelonghiAcTempOffset = 8;
+
51 const uint8_t kDelonghiAcTempSize = 5;
+
52 const uint8_t kDelonghiAcTempMinC = 18; // Deg C
+
53 const uint8_t kDelonghiAcTempMaxC = 32; // Deg C
+
54 const uint8_t kDelonghiAcTempMinF = 64; // Deg F
+
55 const uint8_t kDelonghiAcTempMaxF = 90; // Deg F
+
56 const uint8_t kDelonghiAcTempAutoDryMode = 0;
+
57 const uint8_t kDelonghiAcTempFanMode = 0b00110;
+ +
59  kDelonghiAcTempSize; // 13
+
60 const uint8_t kDelonghiAcFanSize = 2;
+
61 const uint8_t kDelonghiAcFanAuto = 0b00;
+
62 const uint8_t kDelonghiAcFanHigh = 0b01;
+
63 const uint8_t kDelonghiAcFanMedium = 0b10;
+
64 const uint8_t kDelonghiAcFanLow = 0b11;
+ +
66  kDelonghiAcFanSize; // 15 (1 = Celsius, 0 = Fahrenheit)
+
67 const uint8_t kDelonghiAcPowerBit = kDelonghiAcTempUnitBit + 1; // 16
+
68 const uint8_t kDelonghiAcModeOffset = kDelonghiAcPowerBit + 1; // 17
+
69 const uint8_t kDelonghiAcModeSize = 3;
+
70 const uint8_t kDelonghiAcCool = 0b000;
+
71 const uint8_t kDelonghiAcDry = 0b001;
+
72 const uint8_t kDelonghiAcFan = 0b010;
+
73 const uint8_t kDelonghiAcAuto = 0b100;
+ +
75  kDelonghiAcModeSize; // 20 (Aka Turbo)
+
76 const uint8_t kDelonghiAcSleepBit = kDelonghiAcBoostBit + 1; // 21
+
77 // Two zero bits
+ +
79 const uint8_t kDelonghiAcHoursSize = 5; // Max 23 hrs
+
80 const uint8_t kDelonghiAcMinsSize = 6; // Max 59 mins
+
81 const uint16_t kDelonghiAcTimerMax = 23 * 60 + 59;
+ +
83  1; // 25
+ +
85  kDelonghiAcHoursSize + 2; // 32 (inc another two zero bits)
+
86 // Two zero bits
+ +
88  kDelonghiAcMinsSize + 2; // 40
+ +
90  1; // 41
+ +
92  kDelonghiAcHoursSize + 2; // 48 (inc another two zero bits)
+
93 // Two zero bits
+ +
95  kDelonghiAcMinsSize + 2; // 56
+
96 const uint8_t kDelonghiAcChecksumSize = 8;
+
97 
+
98 
+
99 // Classes
+
100 
+ +
103  public:
+
104  explicit IRDelonghiAc(const uint16_t pin, const bool inverted = false,
+
105  const bool use_modulation = true);
+
106  void stateReset();
+
107 #if SEND_DELONGHI_AC
+
108  void send(const uint16_t repeat = kDelonghiAcDefaultRepeat);
+
113  int8_t calibrate(void) { return _irsend.calibrate(); }
+
114 #endif // SEND_DELONGHI_AC
+
115  void begin();
+
116  static uint8_t calcChecksum(const uint64_t state);
+
117  static bool validChecksum(const uint64_t state);
+
118  void setPower(const bool on);
+
119  bool getPower();
+
120  void on();
+
121  void off();
+
122  void setTempUnit(const bool celsius);
+
123  bool getTempUnit(void);
+
124  void setTemp(const uint8_t temp, const bool fahrenheit = false,
+
125  const bool force = false);
+
126  uint8_t getTemp();
+
127  void setFan(const uint8_t speed);
+
128  uint8_t getFan();
+
129  void setMode(const uint8_t mode);
+
130  uint8_t getMode();
+
131  void setBoost(const bool on); // Aka Turbo
+
132  bool getBoost(); // Aka Turbo
+
133  void setSleep(const bool on);
+
134  bool getSleep();
+
135  void setOnTimerEnabled(const bool on);
+
136  bool getOnTimerEnabled(void);
+
137  void setOnTimer(const uint16_t nr_of_mins);
+
138  uint16_t getOnTimer(void);
+
139  void setOffTimerEnabled(const bool on);
+
140  bool getOffTimerEnabled(void);
+
141  void setOffTimer(const uint16_t nr_of_mins);
+
142  uint16_t getOffTimer(void);
+
143  uint64_t getRaw();
+
144  void setRaw(const uint64_t state);
+
145  uint8_t convertMode(const stdAc::opmode_t mode);
+
146  uint8_t convertFan(const stdAc::fanspeed_t speed);
+
147  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
148  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
149  stdAc::state_t toCommon(void);
+
150  String toString();
+
151 #ifndef UNIT_TEST
+
152 
+
153  private:
+ +
155 #else
+
156  IRsendTest _irsend;
+
158 #endif
+
160  uint64_t remote_state;
+
161  uint8_t _saved_temp;
+ +
163  void checksum(void);
+
164 };
+
165 #endif // IR_DELONGHI_H_
+
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Delonghi.cpp:274
+
const uint8_t kDelonghiAcCool
Definition: ir_Delonghi.h:70
+
uint16_t getOnTimer(void)
Get the On timer time.
Definition: ir_Delonghi.cpp:393
+
const uint8_t kDelonghiAcTempOffset
Definition: ir_Delonghi.h:50
+
void begin()
Set up hardware to be able to send a message.
Definition: ir_Delonghi.cpp:100
+
void setFan(const uint8_t speed)
Set the speed of the fan.
Definition: ir_Delonghi.cpp:221
+
void send(const uint16_t repeat=kDelonghiAcDefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Delonghi.cpp:105
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Delonghi.cpp:333
+
uint8_t getTemp()
Get the current temperature setting.
Definition: ir_Delonghi.cpp:214
+
void setRaw(const uint64_t state)
Set the internal state from a valid code for this protocol.
Definition: ir_Delonghi.cpp:153
+
const uint8_t kDelonghiAcTempFanMode
Definition: ir_Delonghi.h:57
+
const uint8_t kDelonghiAcOnTimerHoursOffset
Definition: ir_Delonghi.h:82
+
Class for handling detailed Delonghi A/C messages.
Definition: ir_Delonghi.h:102
+
IRDelonghiAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Delonghi.cpp:95
+
const uint8_t kDelonghiAcModeOffset
Definition: ir_Delonghi.h:68
+
const uint8_t kDelonghiAcTempMinC
Definition: ir_Delonghi.h:52
+
const uint8_t kDelonghiAcFanHigh
Definition: ir_Delonghi.h:62
+
void setOnTimer(const uint16_t nr_of_mins)
Set the On timer to activate in nr of minutes.
Definition: ir_Delonghi.cpp:381
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Delonghi.cpp:163
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
uint8_t _saved_temp
The previously user requested temp value.
Definition: ir_Delonghi.h:161
+
const uint8_t kDelonghiAcOnTimerMinsOffset
Definition: ir_Delonghi.h:84
+
void setOffTimerEnabled(const bool on)
Set the enable status of the Off Timer.
Definition: ir_Delonghi.cpp:402
+
const uint8_t kDelonghiAcFanMedium
Definition: ir_Delonghi.h:63
+
const uint8_t kDelonghiAcTempAutoDryMode
Definition: ir_Delonghi.h:56
+
const uint8_t kDelonghiAcFanLow
Definition: ir_Delonghi.h:64
+
static bool validChecksum(const uint64_t state)
Verify the checksum is valid for a given state.
Definition: ir_Delonghi.cpp:125
+
void on()
Change the power setting to On.
Definition: ir_Delonghi.cpp:156
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Delonghi.cpp:317
+ +
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Delonghi.h:113
+
void stateReset()
Reset the internal state to a fixed known good state.
Definition: ir_Delonghi.cpp:138
+
bool getPower()
Get the value of the current power setting.
Definition: ir_Delonghi.cpp:169
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
bool getOnTimerEnabled(void)
Get the enable status of the On Timer.
Definition: ir_Delonghi.cpp:374
+
uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Delonghi.cpp:256
+
std::string String
Definition: IRremoteESP8266.h:1093
+
const uint8_t kDelonghiAcModeSize
Definition: ir_Delonghi.h:69
+
const uint8_t kDelonghiAcFanAuto
Definition: ir_Delonghi.h:61
+
const uint8_t kDelonghiAcChecksumOffset
Definition: ir_Delonghi.h:94
+
void setOnTimerEnabled(const bool on)
Set the enable status of the On Timer.
Definition: ir_Delonghi.cpp:368
+
const uint8_t kDelonghiAcTempSize
Definition: ir_Delonghi.h:51
+
const uint8_t kDelonghiAcTempMaxF
Definition: ir_Delonghi.h:55
+
uint16_t getOffTimer(void)
Get the Off timer time.
Definition: ir_Delonghi.cpp:427
+
bool getBoost()
Get the Boost (Turbo) mode of the A/C.
Definition: ir_Delonghi.cpp:350
+ +
const uint8_t kDelonghiAcAuto
Definition: ir_Delonghi.h:73
+
const uint8_t kDelonghiAcOffTimerMinsOffset
Definition: ir_Delonghi.h:91
+
const uint8_t kDelonghiAcBoostBit
Definition: ir_Delonghi.h:74
+
const uint8_t kDelonghiAcSleepBit
Definition: ir_Delonghi.h:76
+
const uint8_t kDelonghiAcPowerBit
Definition: ir_Delonghi.h:67
+
const uint8_t kDelonghiAcFanSize
Definition: ir_Delonghi.h:60
+
bool getTempUnit(void)
Get the temperature scale unit of measure currently in use.
Definition: ir_Delonghi.cpp:181
+
const uint8_t kDelonghiAcOnTimerEnableBit
Definition: ir_Delonghi.h:78
+
void checksum(void)
Calculate and set the checksum values for the internal state.
Definition: ir_Delonghi.cpp:132
+
void setSleep(const bool on)
Set the Sleep mode of the A/C.
Definition: ir_Delonghi.cpp:356
+
const uint16_t kDelonghiAcDefaultRepeat
Definition: IRremoteESP8266.h:862
+
uint8_t _saved_temp_units
The previously user requested temp units.
Definition: ir_Delonghi.h:162
+
const uint16_t kDelonghiAcTimerMax
Definition: ir_Delonghi.h:81
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Delonghi.cpp:291
+
void setTemp(const uint8_t temp, const bool fahrenheit=false, const bool force=false)
Set the temperature.
Definition: ir_Delonghi.cpp:189
+
void setOffTimer(const uint16_t nr_of_mins)
Set the Off timer to activate in nr of minutes.
Definition: ir_Delonghi.cpp:415
+
bool getOffTimerEnabled(void)
Get the enable status of the Off Timer.
Definition: ir_Delonghi.cpp:408
+
const uint8_t kDelonghiAcMinsSize
Definition: ir_Delonghi.h:80
+
static uint8_t calcChecksum(const uint64_t state)
Calculate the checksum for a given state.
Definition: ir_Delonghi.cpp:113
+
IRsend _irsend
instance of the IR send class
Definition: ir_Delonghi.h:154
+
const uint8_t kDelonghiAcTempUnitBit
Definition: ir_Delonghi.h:65
+
void setTempUnit(const bool celsius)
Change the temperature scale units.
Definition: ir_Delonghi.cpp:175
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Delonghi.cpp:436
+
bool getSleep()
Get the Sleep mode status of the A/C.
Definition: ir_Delonghi.cpp:362
+
uint64_t remote_state
The state of the IR remote.
Definition: ir_Delonghi.h:160
+
uint8_t getFan()
Get the current native fan speed setting.
Definition: ir_Delonghi.cpp:249
+
const uint8_t kDelonghiAcOffTimerEnableBit
Definition: ir_Delonghi.h:87
+
const uint8_t kDelonghiAcDry
Definition: ir_Delonghi.h:71
+
const uint8_t kDelonghiAcFan
Definition: ir_Delonghi.h:72
+
uint64_t getRaw()
Get a copy of the internal state as a valid code for this protocol.
Definition: ir_Delonghi.cpp:146
+
const uint8_t kDelonghiAcChecksumSize
Definition: ir_Delonghi.h:96
+
const uint8_t kDelonghiAcHoursSize
Definition: ir_Delonghi.h:79
+
uint8_t getMode()
Get the operating mode setting of the A/C.
Definition: ir_Delonghi.cpp:285
+
String toString()
Convert the current internal state into a human readable string.
Definition: ir_Delonghi.cpp:462
+
const uint8_t kDelonghiAcFanOffset
Definition: ir_Delonghi.h:58
+
void setBoost(const bool on)
Set the Boost (Turbo) mode of the A/C.
Definition: ir_Delonghi.cpp:344
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
void off()
Change the power setting to Off.
Definition: ir_Delonghi.cpp:159
+
const uint8_t kDelonghiAcTempMinF
Definition: ir_Delonghi.h:54
+
const uint8_t kDelonghiAcOffTimerHoursOffset
Definition: ir_Delonghi.h:89
+
const uint8_t kDelonghiAcTempMaxC
Definition: ir_Delonghi.h:53
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Denon_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Denon_8cpp.html new file mode 100644 index 000000000..4e9d4d77e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Denon_8cpp.html @@ -0,0 +1,346 @@ + + + + + + + +IRremoteESP8266: src/ir_Denon.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Denon.cpp File Reference
+
+
+ +

Denon support Original Denon support added by https://github.com/csBlueChip Ported over by Massimiliano Pinto. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kDenonTick = 263
 
const uint16_t kDenonHdrMarkTicks = 1
 
const uint16_t kDenonHdrMark = kDenonHdrMarkTicks * kDenonTick
 
const uint16_t kDenonHdrSpaceTicks = 3
 
const uint16_t kDenonHdrSpace = kDenonHdrSpaceTicks * kDenonTick
 
const uint16_t kDenonBitMarkTicks = 1
 
const uint16_t kDenonBitMark = kDenonBitMarkTicks * kDenonTick
 
const uint16_t kDenonOneSpaceTicks = 7
 
const uint16_t kDenonOneSpace = kDenonOneSpaceTicks * kDenonTick
 
const uint16_t kDenonZeroSpaceTicks = 3
 
const uint16_t kDenonZeroSpace = kDenonZeroSpaceTicks * kDenonTick
 
const uint16_t kDenonMinCommandLengthTicks = 510
 
const uint16_t kDenonMinGapTicks
 
const uint32_t kDenonMinGap = kDenonMinGapTicks * kDenonTick
 
const uint64_t kDenonManufacturer = 0x2A4CULL
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kDenonBitMark

+ +
+
+ + + + +
const uint16_t kDenonBitMark = kDenonBitMarkTicks * kDenonTick
+
+ +
+
+ +

◆ kDenonBitMarkTicks

+ +
+
+ + + + +
const uint16_t kDenonBitMarkTicks = 1
+
+ +
+
+ +

◆ kDenonHdrMark

+ +
+
+ + + + +
const uint16_t kDenonHdrMark = kDenonHdrMarkTicks * kDenonTick
+
+ +
+
+ +

◆ kDenonHdrMarkTicks

+ +
+
+ + + + +
const uint16_t kDenonHdrMarkTicks = 1
+
+ +
+
+ +

◆ kDenonHdrSpace

+ +
+
+ + + + +
const uint16_t kDenonHdrSpace = kDenonHdrSpaceTicks * kDenonTick
+
+ +
+
+ +

◆ kDenonHdrSpaceTicks

+ +
+
+ + + + +
const uint16_t kDenonHdrSpaceTicks = 3
+
+ +
+
+ +

◆ kDenonManufacturer

+ +
+
+ + + + +
const uint64_t kDenonManufacturer = 0x2A4CULL
+
+ +
+
+ +

◆ kDenonMinCommandLengthTicks

+ +
+
+ + + + +
const uint16_t kDenonMinCommandLengthTicks = 510
+
+ +
+
+ +

◆ kDenonMinGap

+ +
+
+ + + + +
const uint32_t kDenonMinGap = kDenonMinGapTicks * kDenonTick
+
+ +
+
+ +

◆ kDenonMinGapTicks

+ +
+
+ + + + +
const uint16_t kDenonMinGapTicks
+
+
+ +

◆ kDenonOneSpace

+ +
+
+ + + + +
const uint16_t kDenonOneSpace = kDenonOneSpaceTicks * kDenonTick
+
+ +
+
+ +

◆ kDenonOneSpaceTicks

+ +
+
+ + + + +
const uint16_t kDenonOneSpaceTicks = 7
+
+ +
+
+ +

◆ kDenonTick

+ +
+
+ + + + +
const uint16_t kDenonTick = 263
+
+ +
+
+ +

◆ kDenonZeroSpace

+ +
+
+ + + + +
const uint16_t kDenonZeroSpace = kDenonZeroSpaceTicks * kDenonTick
+
+ +
+
+ +

◆ kDenonZeroSpaceTicks

+ +
+
+ + + + +
const uint16_t kDenonZeroSpaceTicks = 3
+
+ +
+
+
+
const uint16_t kDenonMinCommandLengthTicks
Definition: ir_Denon.cpp:31
+
const uint16_t kDenonHdrSpaceTicks
Definition: ir_Denon.cpp:23
+
const uint16_t kDenonBitMarkTicks
Definition: ir_Denon.cpp:25
+
const uint16_t kDenonHdrMarkTicks
Definition: ir_Denon.cpp:21
+
const uint16_t kDenonBits
Definition: IRremoteESP8266.h:863
+
const uint16_t kDenonOneSpaceTicks
Definition: ir_Denon.cpp:27
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Dish_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Dish_8cpp.html new file mode 100644 index 000000000..abc86c6b3 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Dish_8cpp.html @@ -0,0 +1,305 @@ + + + + + + + +IRremoteESP8266: src/ir_Dish.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Dish.cpp File Reference
+
+
+ +

DISH Network protocol support DISH support originally by Todd Treece. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kDishTick = 100
 
const uint16_t kDishHdrMarkTicks = 4
 
const uint16_t kDishHdrMark = kDishHdrMarkTicks * kDishTick
 
const uint16_t kDishHdrSpaceTicks = 61
 
const uint16_t kDishHdrSpace = kDishHdrSpaceTicks * kDishTick
 
const uint16_t kDishBitMarkTicks = 4
 
const uint16_t kDishBitMark = kDishBitMarkTicks * kDishTick
 
const uint16_t kDishOneSpaceTicks = 17
 
const uint16_t kDishOneSpace = kDishOneSpaceTicks * kDishTick
 
const uint16_t kDishZeroSpaceTicks = 28
 
const uint16_t kDishZeroSpace = kDishZeroSpaceTicks * kDishTick
 
const uint16_t kDishRptSpaceTicks = kDishHdrSpaceTicks
 
const uint16_t kDishRptSpace = kDishRptSpaceTicks * kDishTick
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kDishBitMark

+ +
+
+ + + + +
const uint16_t kDishBitMark = kDishBitMarkTicks * kDishTick
+
+ +
+
+ +

◆ kDishBitMarkTicks

+ +
+
+ + + + +
const uint16_t kDishBitMarkTicks = 4
+
+ +
+
+ +

◆ kDishHdrMark

+ +
+
+ + + + +
const uint16_t kDishHdrMark = kDishHdrMarkTicks * kDishTick
+
+ +
+
+ +

◆ kDishHdrMarkTicks

+ +
+
+ + + + +
const uint16_t kDishHdrMarkTicks = 4
+
+ +
+
+ +

◆ kDishHdrSpace

+ +
+
+ + + + +
const uint16_t kDishHdrSpace = kDishHdrSpaceTicks * kDishTick
+
+ +
+
+ +

◆ kDishHdrSpaceTicks

+ +
+
+ + + + +
const uint16_t kDishHdrSpaceTicks = 61
+
+ +
+
+ +

◆ kDishOneSpace

+ +
+
+ + + + +
const uint16_t kDishOneSpace = kDishOneSpaceTicks * kDishTick
+
+ +
+
+ +

◆ kDishOneSpaceTicks

+ +
+
+ + + + +
const uint16_t kDishOneSpaceTicks = 17
+
+ +
+
+ +

◆ kDishRptSpace

+ +
+
+ + + + +
const uint16_t kDishRptSpace = kDishRptSpaceTicks * kDishTick
+
+ +
+
+ +

◆ kDishRptSpaceTicks

+ +
+
+ + + + +
const uint16_t kDishRptSpaceTicks = kDishHdrSpaceTicks
+
+ +
+
+ +

◆ kDishTick

+ +
+
+ + + + +
const uint16_t kDishTick = 100
+
+ +
+
+ +

◆ kDishZeroSpace

+ +
+
+ + + + +
const uint16_t kDishZeroSpace = kDishZeroSpaceTicks * kDishTick
+
+ +
+
+ +

◆ kDishZeroSpaceTicks

+ +
+
+ + + + +
const uint16_t kDishZeroSpaceTicks = 28
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Doshisha_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Doshisha_8cpp.html new file mode 100644 index 000000000..7e19c1cdc --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Doshisha_8cpp.html @@ -0,0 +1,429 @@ + + + + + + + +IRremoteESP8266: src/ir_Doshisha.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Doshisha.cpp File Reference
+
+
+ +

Doshisha protocol support. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kDoshishaHdrMark = 3412
 
const uint16_t kDoshishaHdrSpace = 1722
 
const uint16_t kDoshishaBitMark = 420
 
const uint16_t kDoshishaOneSpace = 1310
 
const uint16_t kDoshishaZeroSpace = 452
 
const uint64_t kRcz01SignatureMask = 0xffffffff00
 
const uint64_t kRcz01Signature = 0x800B304800
 
const uint8_t kRcz01CommandMask = 0xFE
 
const uint8_t kRcz01ChannelMask = 0x01
 
const uint8_t kRcz01CommandSwitchChannel = 0xD2
 
const uint8_t kRcz01CommandTimmer60 = 0x52
 
const uint8_t kRcz01CommandTimmer30 = 0x92
 
const uint8_t kRcz01CommandOff = 0xA0
 
const uint8_t kRcz01CommandLevelDown = 0x2C
 
const uint8_t kRcz01CommandLevelUp = 0xCC
 
const uint8_t kRcz01CommandLevel1 = 0xA4
 
const uint8_t kRcz01CommandLevel2 = 0x24
 
const uint8_t kRcz01CommandLevel3 = 0xC4
 
const uint8_t kRcz01CommandLevel4 = 0xD0
 
const uint8_t kRcz01CommandOn = 0xC0
 
const uint8_t kRcz01CommandNightLight = 0xC8
 
+

Detailed Description

+

Doshisha protocol support.

+
See also
https://www.doshisha-led.com/
+

Variable Documentation

+ +

◆ kDoshishaBitMark

+ +
+
+ + + + +
const uint16_t kDoshishaBitMark = 420
+
+ +
+
+ +

◆ kDoshishaHdrMark

+ +
+
+ + + + +
const uint16_t kDoshishaHdrMark = 3412
+
+ +
+
+ +

◆ kDoshishaHdrSpace

+ +
+
+ + + + +
const uint16_t kDoshishaHdrSpace = 1722
+
+ +
+
+ +

◆ kDoshishaOneSpace

+ +
+
+ + + + +
const uint16_t kDoshishaOneSpace = 1310
+
+ +
+
+ +

◆ kDoshishaZeroSpace

+ +
+
+ + + + +
const uint16_t kDoshishaZeroSpace = 452
+
+ +
+
+ +

◆ kRcz01ChannelMask

+ +
+
+ + + + +
const uint8_t kRcz01ChannelMask = 0x01
+
+ +
+
+ +

◆ kRcz01CommandLevel1

+ +
+
+ + + + +
const uint8_t kRcz01CommandLevel1 = 0xA4
+
+ +
+
+ +

◆ kRcz01CommandLevel2

+ +
+
+ + + + +
const uint8_t kRcz01CommandLevel2 = 0x24
+
+ +
+
+ +

◆ kRcz01CommandLevel3

+ +
+
+ + + + +
const uint8_t kRcz01CommandLevel3 = 0xC4
+
+ +
+
+ +

◆ kRcz01CommandLevel4

+ +
+
+ + + + +
const uint8_t kRcz01CommandLevel4 = 0xD0
+
+ +
+
+ +

◆ kRcz01CommandLevelDown

+ +
+
+ + + + +
const uint8_t kRcz01CommandLevelDown = 0x2C
+
+ +
+
+ +

◆ kRcz01CommandLevelUp

+ +
+
+ + + + +
const uint8_t kRcz01CommandLevelUp = 0xCC
+
+ +
+
+ +

◆ kRcz01CommandMask

+ +
+
+ + + + +
const uint8_t kRcz01CommandMask = 0xFE
+
+ +
+
+ +

◆ kRcz01CommandNightLight

+ +
+
+ + + + +
const uint8_t kRcz01CommandNightLight = 0xC8
+
+ +
+
+ +

◆ kRcz01CommandOff

+ +
+
+ + + + +
const uint8_t kRcz01CommandOff = 0xA0
+
+ +
+
+ +

◆ kRcz01CommandOn

+ +
+
+ + + + +
const uint8_t kRcz01CommandOn = 0xC0
+
+ +
+
+ +

◆ kRcz01CommandSwitchChannel

+ +
+
+ + + + +
const uint8_t kRcz01CommandSwitchChannel = 0xD2
+
+ +
+
+ +

◆ kRcz01CommandTimmer30

+ +
+
+ + + + +
const uint8_t kRcz01CommandTimmer30 = 0x92
+
+ +
+
+ +

◆ kRcz01CommandTimmer60

+ +
+
+ + + + +
const uint8_t kRcz01CommandTimmer60 = 0x52
+
+ +
+
+ +

◆ kRcz01Signature

+ +
+
+ + + + +
const uint64_t kRcz01Signature = 0x800B304800
+
+ +
+
+ +

◆ kRcz01SignatureMask

+ +
+
+ + + + +
const uint64_t kRcz01SignatureMask = 0xffffffff00
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Electra_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Electra_8cpp.html new file mode 100644 index 000000000..30e634456 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Electra_8cpp.html @@ -0,0 +1,195 @@ + + + + + + + +IRremoteESP8266: src/ir_Electra.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Electra.cpp File Reference
+
+
+ +

Support for Electra A/C protocols. +More...

+ + + + + + + + + + + + + + +

+Variables

const uint16_t kElectraAcHdrMark = 9166
 
const uint16_t kElectraAcBitMark = 646
 
const uint16_t kElectraAcHdrSpace = 4470
 
const uint16_t kElectraAcOneSpace = 1647
 
const uint16_t kElectraAcZeroSpace = 547
 
const uint32_t kElectraAcMessageGap = kDefaultMessageGap
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kElectraAcBitMark

+ +
+
+ + + + +
const uint16_t kElectraAcBitMark = 646
+
+ +
+
+ +

◆ kElectraAcHdrMark

+ +
+
+ + + + +
const uint16_t kElectraAcHdrMark = 9166
+
+ +
+
+ +

◆ kElectraAcHdrSpace

+ +
+
+ + + + +
const uint16_t kElectraAcHdrSpace = 4470
+
+ +
+
+ +

◆ kElectraAcMessageGap

+ +
+
+ + + + +
const uint32_t kElectraAcMessageGap = kDefaultMessageGap
+
+ +
+
+ +

◆ kElectraAcOneSpace

+ +
+
+ + + + +
const uint16_t kElectraAcOneSpace = 1647
+
+ +
+
+ +

◆ kElectraAcZeroSpace

+ +
+
+ + + + +
const uint16_t kElectraAcZeroSpace = 547
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Electra_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Electra_8h.html new file mode 100644 index 000000000..e66afd648 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Electra_8h.html @@ -0,0 +1,550 @@ + + + + + + + +IRremoteESP8266: src/ir_Electra.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Electra.h File Reference
+
+
+ +

Support for Electra A/C protocols. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRElectraAc
 Class for handling detailed Electra A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kElectraAcTempOffset = 3
 
const uint8_t kElectraAcTempSize = 5
 
const uint8_t kElectraAcMinTemp = 16
 
const uint8_t kElectraAcMaxTemp = 32
 
const uint8_t kElectraAcTempDelta = 8
 
const uint8_t kElectraAcSwingSize = 3
 
const uint8_t kElectraAcSwingOn = 0b000
 
const uint8_t kElectraAcSwingOff = 0b111
 
const uint8_t kElectraAcSwingVOffset = 0
 
const uint8_t kElectraAcSwingHOffset = 5
 
const uint8_t kElectraAcFanOffset = 5
 
const uint8_t kElectraAcFanSize = 3
 
const uint8_t kElectraAcFanAuto = 0b101
 
const uint8_t kElectraAcFanLow = 0b011
 
const uint8_t kElectraAcFanMed = 0b010
 
const uint8_t kElectraAcFanHigh = 0b001
 
const uint8_t kElectraAcTurboOffset = 6
 
const uint8_t kElectraAcModeOffset = 5
 
const uint8_t kElectraAcAuto = 0b000
 
const uint8_t kElectraAcCool = 0b001
 
const uint8_t kElectraAcDry = 0b010
 
const uint8_t kElectraAcHeat = 0b100
 
const uint8_t kElectraAcFan = 0b110
 
const uint8_t kElectraAcCleanOffset = 2
 
const uint8_t kElectraAcPowerOffset = 5
 
const uint8_t kElectraAcLightToggleOn = 0x15
 
const uint8_t kElectraAcLightToggleMask = 0x11
 
const uint8_t kElectraAcLightToggleOff = 0x08
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kElectraAcAuto

+ +
+
+ + + + +
const uint8_t kElectraAcAuto = 0b000
+
+ +
+
+ +

◆ kElectraAcCleanOffset

+ +
+
+ + + + +
const uint8_t kElectraAcCleanOffset = 2
+
+ +
+
+ +

◆ kElectraAcCool

+ +
+
+ + + + +
const uint8_t kElectraAcCool = 0b001
+
+ +
+
+ +

◆ kElectraAcDry

+ +
+
+ + + + +
const uint8_t kElectraAcDry = 0b010
+
+ +
+
+ +

◆ kElectraAcFan

+ +
+
+ + + + +
const uint8_t kElectraAcFan = 0b110
+
+ +
+
+ +

◆ kElectraAcFanAuto

+ +
+
+ + + + +
const uint8_t kElectraAcFanAuto = 0b101
+
+ +
+
+ +

◆ kElectraAcFanHigh

+ +
+
+ + + + +
const uint8_t kElectraAcFanHigh = 0b001
+
+ +
+
+ +

◆ kElectraAcFanLow

+ +
+
+ + + + +
const uint8_t kElectraAcFanLow = 0b011
+
+ +
+
+ +

◆ kElectraAcFanMed

+ +
+
+ + + + +
const uint8_t kElectraAcFanMed = 0b010
+
+ +
+
+ +

◆ kElectraAcFanOffset

+ +
+
+ + + + +
const uint8_t kElectraAcFanOffset = 5
+
+ +
+
+ +

◆ kElectraAcFanSize

+ +
+
+ + + + +
const uint8_t kElectraAcFanSize = 3
+
+ +
+
+ +

◆ kElectraAcHeat

+ +
+
+ + + + +
const uint8_t kElectraAcHeat = 0b100
+
+ +
+
+ +

◆ kElectraAcLightToggleMask

+ +
+
+ + + + +
const uint8_t kElectraAcLightToggleMask = 0x11
+
+ +
+
+ +

◆ kElectraAcLightToggleOff

+ +
+
+ + + + +
const uint8_t kElectraAcLightToggleOff = 0x08
+
+ +
+
+ +

◆ kElectraAcLightToggleOn

+ +
+
+ + + + +
const uint8_t kElectraAcLightToggleOn = 0x15
+
+ +
+
+ +

◆ kElectraAcMaxTemp

+ +
+
+ + + + +
const uint8_t kElectraAcMaxTemp = 32
+
+ +
+
+ +

◆ kElectraAcMinTemp

+ +
+
+ + + + +
const uint8_t kElectraAcMinTemp = 16
+
+ +
+
+ +

◆ kElectraAcModeOffset

+ +
+
+ + + + +
const uint8_t kElectraAcModeOffset = 5
+
+ +
+
+ +

◆ kElectraAcPowerOffset

+ +
+
+ + + + +
const uint8_t kElectraAcPowerOffset = 5
+
+ +
+
+ +

◆ kElectraAcSwingHOffset

+ +
+
+ + + + +
const uint8_t kElectraAcSwingHOffset = 5
+
+ +
+
+ +

◆ kElectraAcSwingOff

+ +
+
+ + + + +
const uint8_t kElectraAcSwingOff = 0b111
+
+ +
+
+ +

◆ kElectraAcSwingOn

+ +
+
+ + + + +
const uint8_t kElectraAcSwingOn = 0b000
+
+ +
+
+ +

◆ kElectraAcSwingSize

+ +
+
+ + + + +
const uint8_t kElectraAcSwingSize = 3
+
+ +
+
+ +

◆ kElectraAcSwingVOffset

+ +
+
+ + + + +
const uint8_t kElectraAcSwingVOffset = 0
+
+ +
+
+ +

◆ kElectraAcTempDelta

+ +
+
+ + + + +
const uint8_t kElectraAcTempDelta = 8
+
+ +
+
+ +

◆ kElectraAcTempOffset

+ +
+
+ + + + +
const uint8_t kElectraAcTempOffset = 3
+
+ +
+
+ +

◆ kElectraAcTempSize

+ +
+
+ + + + +
const uint8_t kElectraAcTempSize = 5
+
+ +
+
+ +

◆ kElectraAcTurboOffset

+ +
+
+ + + + +
const uint8_t kElectraAcTurboOffset = 6
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Electra_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Electra_8h_source.html new file mode 100644 index 000000000..a5a25cb15 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Electra_8h_source.html @@ -0,0 +1,286 @@ + + + + + + + +IRremoteESP8266: src/ir_Electra.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Electra.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 David Conran
+
5 
+
6 // Supports:
+
7 // Brand: AUX, Model: KFR-35GW/BpNFW=3 A/C
+
8 // Brand: AUX, Model: YKR-T/011 remote
+
9 // Brand: Electra, Model: Classic INV 17 / AXW12DCS A/C
+
10 // Brand: Electra, Model: YKR-M/003E remote
+
11 
+
12 #ifndef IR_ELECTRA_H_
+
13 #define IR_ELECTRA_H_
+
14 
+
15 #define __STDC_LIMIT_MACROS
+
16 #include <stdint.h>
+
17 #ifndef UNIT_TEST
+
18 #include <Arduino.h>
+
19 #endif
+
20 #include "IRremoteESP8266.h"
+
21 #include "IRsend.h"
+
22 #ifdef UNIT_TEST
+
23 #include "IRsend_test.h"
+
24 #endif
+
25 
+
26 // Constants
+
27 // state[1]
+
28 // Temp 0b11111000
+
29 const uint8_t kElectraAcTempOffset = 3;
+
30 const uint8_t kElectraAcTempSize = 5; // Bits
+
31 const uint8_t kElectraAcMinTemp = 16; // 16C
+
32 const uint8_t kElectraAcMaxTemp = 32; // 32C
+
33 const uint8_t kElectraAcTempDelta = 8;
+
34 const uint8_t kElectraAcSwingSize = 3; // Bits
+
35 const uint8_t kElectraAcSwingOn = 0b000;
+
36 const uint8_t kElectraAcSwingOff = 0b111;
+
37 // SwingVMask = 0b00000111;
+
38 const uint8_t kElectraAcSwingVOffset = 0;
+
39 // state[2]
+
40 // SwingHMask = 0b11100000;
+
41 const uint8_t kElectraAcSwingHOffset = 5;
+
42 // state[4]
+
43 // FanMask = 0b11100000;
+
44 const uint8_t kElectraAcFanOffset = 5;
+
45 const uint8_t kElectraAcFanSize = 3; // Bits
+
46 
+
47 const uint8_t kElectraAcFanAuto = 0b101;
+
48 const uint8_t kElectraAcFanLow = 0b011;
+
49 const uint8_t kElectraAcFanMed = 0b010;
+
50 const uint8_t kElectraAcFanHigh = 0b001;
+
51 // state[5]
+
52 // TurboMask = 0b01000000;
+
53 const uint8_t kElectraAcTurboOffset = 6;
+
54 
+
55 // state[6]
+
56 // Mode 0b11100000
+
57 const uint8_t kElectraAcModeOffset = 5;
+
58 const uint8_t kElectraAcAuto = 0b000;
+
59 const uint8_t kElectraAcCool = 0b001;
+
60 const uint8_t kElectraAcDry = 0b010;
+
61 const uint8_t kElectraAcHeat = 0b100;
+
62 const uint8_t kElectraAcFan = 0b110;
+
63 // state[9]
+
64 //
+
65 const uint8_t kElectraAcCleanOffset = 2; // Bit 0b00000100
+
66 const uint8_t kElectraAcPowerOffset = 5; // Bit 0b00100000
+
67 // state[11]
+
68 //
+
69 const uint8_t kElectraAcLightToggleOn = 0x15;
+
70 // Light has known ON values of 0x15 (0b00010101) or 0x19 (0b00011001)
+
71 // Thus common bits ON are: 0b00010001 (0x11)
+
72 // We will use this for the getLightToggle() test.
+
73 const uint8_t kElectraAcLightToggleMask = 0x11;
+
74 // and known OFF values of 0x08 (0b00001000) & 0x05 (0x00000101)
+
75 const uint8_t kElectraAcLightToggleOff = 0x08;
+
76 
+
77 
+
78 // Classes
+
80 class IRElectraAc {
+
81  public:
+
82  explicit IRElectraAc(const uint16_t pin, const bool inverted = false,
+
83  const bool use_modulation = true);
+
84  void stateReset(void);
+
85 #if SEND_ELECTRA_AC
+
86  void send(const uint16_t repeat = kElectraAcMinRepeat);
+
91  int8_t calibrate(void) { return _irsend.calibrate(); }
+
92 #endif // SEND_ELECTRA_AC
+
93  void begin(void);
+
94  void on(void);
+
95  void off(void);
+
96  void setPower(const bool on);
+
97  bool getPower(void);
+
98  void setMode(const uint8_t mode);
+
99  uint8_t getMode(void);
+
100  void setTemp(const uint8_t temp);
+
101  uint8_t getTemp(void);
+
102  void setFan(const uint8_t speed);
+
103  uint8_t getFan(void);
+
104  void setSwingV(const bool on);
+
105  bool getSwingV(void);
+
106  void setSwingH(const bool on);
+
107  bool getSwingH(void);
+
108  void setClean(const bool on);
+
109  bool getClean(void);
+
110  void setLightToggle(const bool on);
+
111  bool getLightToggle(void);
+
112  void setTurbo(const bool on);
+
113  bool getTurbo(void);
+
114  uint8_t* getRaw(void);
+
115  void setRaw(const uint8_t new_code[],
+
116  const uint16_t length = kElectraAcStateLength);
+
117  static bool validChecksum(const uint8_t state[],
+
118  const uint16_t length = kElectraAcStateLength);
+
119  static uint8_t calcChecksum(const uint8_t state[],
+
120  const uint16_t length = kElectraAcStateLength);
+
121  String toString(void);
+
122  uint8_t convertMode(const stdAc::opmode_t mode);
+
123  uint8_t convertFan(const stdAc::fanspeed_t speed);
+
124  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
125  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
126  stdAc::state_t toCommon(void);
+
127 #ifndef UNIT_TEST
+
128 
+
129  private:
+ +
131 #else
+
132  IRsendTest _irsend;
+
134 #endif
+ +
137  void checksum(const uint16_t length = kElectraAcStateLength);
+
138 };
+
139 #endif // IR_ELECTRA_H_
+
+
bool getSwingV(void)
Get the Vertical Swing mode of the A/C.
Definition: ir_Electra.cpp:263
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Electra.cpp:167
+
void checksum(const uint16_t length=kElectraAcStateLength)
Calculate and set the checksum values for the internal state.
Definition: ir_Electra.cpp:96
+
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_Electra.cpp:111
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Electra.cpp:224
+
const uint8_t kElectraAcMinTemp
Definition: ir_Electra.h:31
+
bool getLightToggle(void)
Get the Light (LED) Toggle mode of the A/C.
Definition: ir_Electra.cpp:290
+
bool getTurbo(void)
Get the Turbo mode of the A/C.
Definition: ir_Electra.cpp:315
+
const uint8_t kElectraAcMaxTemp
Definition: ir_Electra.h:32
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
static bool validChecksum(const uint8_t state[], const uint16_t length=kElectraAcStateLength)
Verify the checksum is valid for a given state.
Definition: ir_Electra.cpp:88
+
const uint8_t kElectraAcFanAuto
Definition: ir_Electra.h:47
+
bool getSwingH(void)
Get the Horizontal Swing mode of the A/C.
Definition: ir_Electra.cpp:277
+
const uint8_t kElectraAcPowerOffset
Definition: ir_Electra.h:66
+
void on(void)
Change the power setting to On.
Definition: ir_Electra.cpp:124
+
const uint8_t kElectraAcTurboOffset
Definition: ir_Electra.h:53
+
void setClean(const bool on)
Set the Clean mode of the A/C.
Definition: ir_Electra.cpp:297
+ +
const uint16_t kElectraAcMinRepeat
Definition: IRremoteESP8266.h:873
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
IRElectraAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Electra.cpp:57
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Electra.cpp:321
+
const uint8_t kElectraAcHeat
Definition: ir_Electra.h:61
+
std::string String
Definition: IRremoteESP8266.h:1093
+
const uint8_t kElectraAcCool
Definition: ir_Electra.h:59
+
void setFan(const uint8_t speed)
Set the speed of the fan.
Definition: ir_Electra.cpp:208
+
Class for handling detailed Electra A/C messages.
Definition: ir_Electra.h:80
+
const uint8_t kElectraAcTempSize
Definition: ir_Electra.h:30
+
const uint8_t kElectraAcAuto
Definition: ir_Electra.h:58
+ +
const uint8_t kElectraAcTempOffset
Definition: ir_Electra.h:29
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Electra.cpp:180
+
const uint8_t kElectraAcDry
Definition: ir_Electra.h:60
+
bool getClean(void)
Get the Clean mode of the A/C.
Definition: ir_Electra.cpp:303
+
void setRaw(const uint8_t new_code[], const uint16_t length=kElectraAcStateLength)
Set the internal state from a valid code for this protocol.
Definition: ir_Electra.cpp:119
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Electra.cpp:131
+
const uint8_t kElectraAcTempDelta
Definition: ir_Electra.h:33
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Electra.h:91
+
const uint8_t kElectraAcLightToggleOff
Definition: ir_Electra.h:75
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Electra.cpp:245
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Electra.cpp:137
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Electra.cpp:349
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Electra.cpp:192
+
const uint8_t kElectraAcLightToggleOn
Definition: ir_Electra.h:69
+
void setLightToggle(const bool on)
Set the Light (LED) Toggle mode of the A/C.
Definition: ir_Electra.cpp:284
+
const uint8_t kElectraAcFanLow
Definition: ir_Electra.h:48
+
void setSwingH(const bool on)
Set the Horizontal Swing mode of the A/C.
Definition: ir_Electra.cpp:270
+
const uint8_t kElectraAcFanOffset
Definition: ir_Electra.h:44
+
const uint8_t kElectraAcModeOffset
Definition: ir_Electra.h:57
+
static uint8_t calcChecksum(const uint8_t state[], const uint16_t length=kElectraAcStateLength)
Calculate the checksum for a given state.
Definition: ir_Electra.cpp:78
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Electra.cpp:160
+
const uint8_t kElectraAcSwingSize
Definition: ir_Electra.h:34
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Electra.cpp:200
+
const uint8_t kElectraAcSwingHOffset
Definition: ir_Electra.h:41
+
void off(void)
Change the power setting to Off.
Definition: ir_Electra.cpp:127
+
void send(const uint16_t repeat=kElectraAcMinRepeat)
Send the current internal state as an IR message.
Definition: ir_Electra.cpp:104
+
IRsend _irsend
instance of the IR send class
Definition: ir_Electra.h:130
+
const uint8_t kElectraAcSwingOn
Definition: ir_Electra.h:35
+
const uint8_t kElectraAcFanMed
Definition: ir_Electra.h:49
+
const uint8_t kElectraAcFanHigh
Definition: ir_Electra.h:50
+
uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Electra.cpp:231
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Electra.cpp:72
+
void setTurbo(const bool on)
Set the Turbo mode of the A/C.
Definition: ir_Electra.cpp:309
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Electra.cpp:143
+
const uint8_t kElectraAcSwingVOffset
Definition: ir_Electra.h:38
+
const uint8_t kElectraAcFan
Definition: ir_Electra.h:62
+
uint8_t remote_state[kElectraAcStateLength]
The state of the IR remote.
Definition: ir_Electra.h:136
+
const uint8_t kElectraAcLightToggleMask
Definition: ir_Electra.h:73
+
const uint8_t kElectraAcSwingOff
Definition: ir_Electra.h:36
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
const uint8_t kElectraAcFanSize
Definition: ir_Electra.h:45
+
void stateReset(void)
Reset the internal state to a fixed known good state.
Definition: ir_Electra.cpp:64
+
void setSwingV(const bool on)
Set the Vertical Swing mode of the A/C.
Definition: ir_Electra.cpp:256
+
const uint16_t kElectraAcStateLength
Definition: IRremoteESP8266.h:871
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+
const uint8_t kElectraAcCleanOffset
Definition: ir_Electra.h:65
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Epson_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Epson_8cpp.html new file mode 100644 index 000000000..3b1fa2a04 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Epson_8cpp.html @@ -0,0 +1,86 @@ + + + + + + + +IRremoteESP8266: src/ir_Epson.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Epson.cpp File Reference
+
+
+ +

Support for Epson protocols. Epson is an NEC-like protocol, except it doesn't use the NEC style repeat. +More...

+

Detailed Description

+

Support for Epson protocols. Epson is an NEC-like protocol, except it doesn't use the NEC style repeat.

+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/1034
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Fujitsu_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Fujitsu_8cpp.html new file mode 100644 index 000000000..20fa1a48d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Fujitsu_8cpp.html @@ -0,0 +1,188 @@ + + + + + + + +IRremoteESP8266: src/ir_Fujitsu.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Fujitsu.cpp File Reference
+
+
+ +

Support for Fujitsu A/C protocols. Fujitsu A/C support added by Jonny Graham & David Conran. +More...

+ + + + + + + + + + + + + + +

+Variables

const uint16_t kFujitsuAcHdrMark = 3324
 
const uint16_t kFujitsuAcHdrSpace = 1574
 
const uint16_t kFujitsuAcBitMark = 448
 
const uint16_t kFujitsuAcOneSpace = 1182
 
const uint16_t kFujitsuAcZeroSpace = 390
 
const uint16_t kFujitsuAcMinGap = 8100
 
+

Detailed Description

+

Support for Fujitsu A/C protocols. Fujitsu A/C support added by Jonny Graham & David Conran.

+

Variable Documentation

+ +

◆ kFujitsuAcBitMark

+ +
+
+ + + + +
const uint16_t kFujitsuAcBitMark = 448
+
+ +
+
+ +

◆ kFujitsuAcHdrMark

+ +
+
+ + + + +
const uint16_t kFujitsuAcHdrMark = 3324
+
+ +
+
+ +

◆ kFujitsuAcHdrSpace

+ +
+
+ + + + +
const uint16_t kFujitsuAcHdrSpace = 1574
+
+ +
+
+ +

◆ kFujitsuAcMinGap

+ +
+
+ + + + +
const uint16_t kFujitsuAcMinGap = 8100
+
+ +
+
+ +

◆ kFujitsuAcOneSpace

+ +
+
+ + + + +
const uint16_t kFujitsuAcOneSpace = 1182
+
+ +
+
+ +

◆ kFujitsuAcZeroSpace

+ +
+
+ + + + +
const uint16_t kFujitsuAcZeroSpace = 390
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Fujitsu_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Fujitsu_8h.html new file mode 100644 index 000000000..ed36c7104 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Fujitsu_8h.html @@ -0,0 +1,581 @@ + + + + + + + +IRremoteESP8266: src/ir_Fujitsu.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Fujitsu.h File Reference
+
+
+ +

Support for Fujitsu A/C protocols. Fujitsu A/C support added by Jonny Graham. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRFujitsuAC
 Class for handling detailed Fujitsu A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kFujitsuAcModeAuto = 0x00
 
const uint8_t kFujitsuAcModeCool = 0x01
 
const uint8_t kFujitsuAcModeDry = 0x02
 
const uint8_t kFujitsuAcModeFan = 0x03
 
const uint8_t kFujitsuAcModeHeat = 0x04
 
const uint8_t kFujitsuAcCmdStayOn = 0x00
 
const uint8_t kFujitsuAcCmdTurnOn = 0x01
 
const uint8_t kFujitsuAcCmdTurnOff = 0x02
 
const uint8_t kFujitsuAcCmdEcono = 0x09
 
const uint8_t kFujitsuAcCmdPowerful = 0x39
 
const uint8_t kFujitsuAcCmdStepVert = 0x6C
 
const uint8_t kFujitsuAcCmdToggleSwingVert = 0x6D
 
const uint8_t kFujitsuAcCmdStepHoriz = 0x79
 
const uint8_t kFujitsuAcCmdToggleSwingHoriz = 0x7A
 
const uint8_t kFujitsuAcFanAuto = 0x00
 
const uint8_t kFujitsuAcFanHigh = 0x01
 
const uint8_t kFujitsuAcFanMed = 0x02
 
const uint8_t kFujitsuAcFanLow = 0x03
 
const uint8_t kFujitsuAcFanQuiet = 0x04
 
const uint8_t kFujitsuAcFanSize = 3
 
const uint8_t kFujitsuAcMinTemp = 16
 
const uint8_t kFujitsuAcMaxTemp = 30
 
const uint8_t kFujitsuAcSwingSize = 2
 
const uint8_t kFujitsuAcSwingOff = 0x00
 
const uint8_t kFujitsuAcSwingVert = 0x01
 
const uint8_t kFujitsuAcSwingHoriz = 0x02
 
const uint8_t kFujitsuAcSwingBoth = 0x03
 
const uint8_t kFujitsuAcOutsideQuietOffset = 7
 
const uint8_t kFujitsuAcCleanOffset = 3
 
const uint8_t kFujitsuAcFilterOffset = 3
 
+

Detailed Description

+

Support for Fujitsu A/C protocols. Fujitsu A/C support added by Jonny Graham.

+

Variable Documentation

+ +

◆ kFujitsuAcCleanOffset

+ +
+
+ + + + +
const uint8_t kFujitsuAcCleanOffset = 3
+
+ +
+
+ +

◆ kFujitsuAcCmdEcono

+ +
+
+ + + + +
const uint8_t kFujitsuAcCmdEcono = 0x09
+
+ +
+
+ +

◆ kFujitsuAcCmdPowerful

+ +
+
+ + + + +
const uint8_t kFujitsuAcCmdPowerful = 0x39
+
+ +
+
+ +

◆ kFujitsuAcCmdStayOn

+ +
+
+ + + + +
const uint8_t kFujitsuAcCmdStayOn = 0x00
+
+ +
+
+ +

◆ kFujitsuAcCmdStepHoriz

+ +
+
+ + + + +
const uint8_t kFujitsuAcCmdStepHoriz = 0x79
+
+ +
+
+ +

◆ kFujitsuAcCmdStepVert

+ +
+
+ + + + +
const uint8_t kFujitsuAcCmdStepVert = 0x6C
+
+ +
+
+ +

◆ kFujitsuAcCmdToggleSwingHoriz

+ +
+
+ + + + +
const uint8_t kFujitsuAcCmdToggleSwingHoriz = 0x7A
+
+ +
+
+ +

◆ kFujitsuAcCmdToggleSwingVert

+ +
+
+ + + + +
const uint8_t kFujitsuAcCmdToggleSwingVert = 0x6D
+
+ +
+
+ +

◆ kFujitsuAcCmdTurnOff

+ +
+
+ + + + +
const uint8_t kFujitsuAcCmdTurnOff = 0x02
+
+ +
+
+ +

◆ kFujitsuAcCmdTurnOn

+ +
+
+ + + + +
const uint8_t kFujitsuAcCmdTurnOn = 0x01
+
+ +
+
+ +

◆ kFujitsuAcFanAuto

+ +
+
+ + + + +
const uint8_t kFujitsuAcFanAuto = 0x00
+
+ +
+
+ +

◆ kFujitsuAcFanHigh

+ +
+
+ + + + +
const uint8_t kFujitsuAcFanHigh = 0x01
+
+ +
+
+ +

◆ kFujitsuAcFanLow

+ +
+
+ + + + +
const uint8_t kFujitsuAcFanLow = 0x03
+
+ +
+
+ +

◆ kFujitsuAcFanMed

+ +
+
+ + + + +
const uint8_t kFujitsuAcFanMed = 0x02
+
+ +
+
+ +

◆ kFujitsuAcFanQuiet

+ +
+
+ + + + +
const uint8_t kFujitsuAcFanQuiet = 0x04
+
+ +
+
+ +

◆ kFujitsuAcFanSize

+ +
+
+ + + + +
const uint8_t kFujitsuAcFanSize = 3
+
+ +
+
+ +

◆ kFujitsuAcFilterOffset

+ +
+
+ + + + +
const uint8_t kFujitsuAcFilterOffset = 3
+
+ +
+
+ +

◆ kFujitsuAcMaxTemp

+ +
+
+ + + + +
const uint8_t kFujitsuAcMaxTemp = 30
+
+ +
+
+ +

◆ kFujitsuAcMinTemp

+ +
+
+ + + + +
const uint8_t kFujitsuAcMinTemp = 16
+
+ +
+
+ +

◆ kFujitsuAcModeAuto

+ +
+
+ + + + +
const uint8_t kFujitsuAcModeAuto = 0x00
+
+ +
+
+ +

◆ kFujitsuAcModeCool

+ +
+
+ + + + +
const uint8_t kFujitsuAcModeCool = 0x01
+
+ +
+
+ +

◆ kFujitsuAcModeDry

+ +
+
+ + + + +
const uint8_t kFujitsuAcModeDry = 0x02
+
+ +
+
+ +

◆ kFujitsuAcModeFan

+ +
+
+ + + + +
const uint8_t kFujitsuAcModeFan = 0x03
+
+ +
+
+ +

◆ kFujitsuAcModeHeat

+ +
+
+ + + + +
const uint8_t kFujitsuAcModeHeat = 0x04
+
+ +
+
+ +

◆ kFujitsuAcOutsideQuietOffset

+ +
+
+ + + + +
const uint8_t kFujitsuAcOutsideQuietOffset = 7
+
+ +
+
+ +

◆ kFujitsuAcSwingBoth

+ +
+
+ + + + +
const uint8_t kFujitsuAcSwingBoth = 0x03
+
+ +
+
+ +

◆ kFujitsuAcSwingHoriz

+ +
+
+ + + + +
const uint8_t kFujitsuAcSwingHoriz = 0x02
+
+ +
+
+ +

◆ kFujitsuAcSwingOff

+ +
+
+ + + + +
const uint8_t kFujitsuAcSwingOff = 0x00
+
+ +
+
+ +

◆ kFujitsuAcSwingSize

+ +
+
+ + + + +
const uint8_t kFujitsuAcSwingSize = 2
+
+ +
+
+ +

◆ kFujitsuAcSwingVert

+ +
+
+ + + + +
const uint8_t kFujitsuAcSwingVert = 0x01
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Fujitsu_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Fujitsu_8h_source.html new file mode 100644 index 000000000..ccc167f12 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Fujitsu_8h_source.html @@ -0,0 +1,350 @@ + + + + + + + +IRremoteESP8266: src/ir_Fujitsu.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Fujitsu.h
+
+
+Go to the documentation of this file.
1 // Copyright 2017 Jonny Graham
+
2 // Copyright 2018-2019 David Conran
+
3 
+
7 
+
8 // Supports:
+
9 // Brand: Fujitsu, Model: AR-RAH2E remote
+
10 // Brand: Fujitsu, Model: ASYG30LFCA A/C (ARRAH2E)
+
11 // Brand: Fujitsu, Model: AR-DB1 remote
+
12 // Brand: Fujitsu, Model: AST9RSGCW A/C (ARDB1)
+
13 // Brand: Fujitsu, Model: AR-REB1E remote
+
14 // Brand: Fujitsu, Model: ASYG7LMCA A/C (ARREB1E)
+
15 // Brand: Fujitsu, Model: AR-RAE1E remote
+
16 // Brand: Fujitsu, Model: AGTV14LAC A/C
+
17 // Brand: Fujitsu, Model: AR-RAC1E remote
+
18 // Brand: Fujitsu, Model: ASTB09LBC A/C
+
19 // Brand: Fujitsu, Model: AR-RY4 remote
+
20 // Brand: Fujitsu General, Model: AR-JW2 remote
+
21 // Brand: Fujitsu, Model: AR-DL10 remote
+
22 // Brand: Fujitsu, Model: ASU30C1 A/C
+
23 
+
24 #ifndef IR_FUJITSU_H_
+
25 #define IR_FUJITSU_H_
+
26 
+
27 #define __STDC_LIMIT_MACROS
+
28 #include <stdint.h>
+
29 #ifdef ARDUINO
+
30 #include <Arduino.h>
+
31 #endif
+
32 #include "IRrecv.h"
+
33 #include "IRremoteESP8266.h"
+
34 #include "IRsend.h"
+
35 #ifdef UNIT_TEST
+
36 #include "IRsend_test.h"
+
37 #endif
+
38 
+
39 
+
40 // Constants
+
41 const uint8_t kFujitsuAcModeAuto = 0x00;
+
42 const uint8_t kFujitsuAcModeCool = 0x01;
+
43 const uint8_t kFujitsuAcModeDry = 0x02;
+
44 const uint8_t kFujitsuAcModeFan = 0x03;
+
45 const uint8_t kFujitsuAcModeHeat = 0x04;
+
46 
+
47 const uint8_t kFujitsuAcCmdStayOn = 0x00; // b00000000
+
48 const uint8_t kFujitsuAcCmdTurnOn = 0x01; // b00000001
+
49 const uint8_t kFujitsuAcCmdTurnOff = 0x02; // b00000010
+
50 const uint8_t kFujitsuAcCmdEcono = 0x09; // b00001001
+
51 const uint8_t kFujitsuAcCmdPowerful = 0x39; // b00111001
+
52 const uint8_t kFujitsuAcCmdStepVert = 0x6C; // b01101100
+
53 const uint8_t kFujitsuAcCmdToggleSwingVert = 0x6D; // b01101101
+
54 const uint8_t kFujitsuAcCmdStepHoriz = 0x79; // b01111001
+
55 const uint8_t kFujitsuAcCmdToggleSwingHoriz = 0x7A; // b01111010
+
56 
+
57 const uint8_t kFujitsuAcFanAuto = 0x00;
+
58 const uint8_t kFujitsuAcFanHigh = 0x01;
+
59 const uint8_t kFujitsuAcFanMed = 0x02;
+
60 const uint8_t kFujitsuAcFanLow = 0x03;
+
61 const uint8_t kFujitsuAcFanQuiet = 0x04;
+
62 const uint8_t kFujitsuAcFanSize = 3; // Bits
+
63 
+
64 const uint8_t kFujitsuAcMinTemp = 16; // 16C
+
65 const uint8_t kFujitsuAcMaxTemp = 30; // 30C
+
66 
+
67 const uint8_t kFujitsuAcSwingSize = 2;
+
68 const uint8_t kFujitsuAcSwingOff = 0x00;
+
69 const uint8_t kFujitsuAcSwingVert = 0x01;
+
70 const uint8_t kFujitsuAcSwingHoriz = 0x02;
+
71 const uint8_t kFujitsuAcSwingBoth = 0x03;
+
72 
+
73 const uint8_t kFujitsuAcOutsideQuietOffset = 7;
+
74 const uint8_t kFujitsuAcCleanOffset = 3;
+
75 const uint8_t kFujitsuAcFilterOffset = 3;
+
76 
+
77 // Legacy defines.
+
78 #define FUJITSU_AC_MODE_AUTO kFujitsuAcModeAuto
+
79 #define FUJITSU_AC_MODE_COOL kFujitsuAcModeCool
+
80 #define FUJITSU_AC_MODE_DRY kFujitsuAcModeDry
+
81 #define FUJITSU_AC_MODE_FAN kFujitsuAcModeFan
+
82 #define FUJITSU_AC_MODE_HEAT kFujitsuAcModeHeat
+
83 #define FUJITSU_AC_CMD_STAY_ON kFujitsuAcCmdStayOn
+
84 #define FUJITSU_AC_CMD_TURN_ON kFujitsuAcCmdTurnOn
+
85 #define FUJITSU_AC_CMD_TURN_OFF kFujitsuAcCmdTurnOff
+
86 #define FUJITSU_AC_CMD_STEP_HORIZ kFujitsuAcCmdStepHoriz
+
87 #define FUJITSU_AC_CMD_STEP_VERT kFujitsuAcCmdStepVert
+
88 #define FUJITSU_AC_FAN_AUTO kFujitsuAcFanAuto
+
89 #define FUJITSU_AC_FAN_HIGH kFujitsuAcFanHigh
+
90 #define FUJITSU_AC_FAN_MED kFujitsuAcFanMed
+
91 #define FUJITSU_AC_FAN_LOW kFujitsuAcFanLow
+
92 #define FUJITSU_AC_FAN_QUIET kFujitsuAcFanQuiet
+
93 #define FUJITSU_AC_MIN_TEMP kFujitsuAcMinTemp
+
94 #define FUJITSU_AC_MAX_TEMP kFujitsuAcMaxTemp
+
95 #define FUJITSU_AC_SWING_OFF kFujitsuAcSwingOff
+
96 #define FUJITSU_AC_SWING_VERT kFujitsuAcSwingVert
+
97 #define FUJITSU_AC_SWING_HORIZ kFujitsuAcSwingHoriz
+
98 #define FUJITSU_AC_SWING_BOTH kFujitsuAcSwingBoth
+
99 
+
101 class IRFujitsuAC {
+
102  public:
+
103  explicit IRFujitsuAC(const uint16_t pin,
+
104  const fujitsu_ac_remote_model_t model = ARRAH2E,
+
105  const bool inverted = false,
+
106  const bool use_modulation = true);
+
107  void setModel(const fujitsu_ac_remote_model_t model);
+ +
109  void stateReset(void);
+
110 #if SEND_FUJITSU_AC
+
111  void send(const uint16_t repeat = kFujitsuAcMinRepeat);
+
116  int8_t calibrate(void) { return _irsend.calibrate(); }
+
117 #endif // SEND_FUJITSU_AC
+
118  void begin(void);
+
119  void stepHoriz(void);
+
120  void toggleSwingHoriz(const bool update = true);
+
121  void stepVert(void);
+
122  void toggleSwingVert(const bool update = true);
+
123  void setCmd(const uint8_t cmd);
+
124  uint8_t getCmd(const bool raw = false);
+
125  void setTemp(const uint8_t temp);
+
126  uint8_t getTemp(void);
+
127  void setFanSpeed(const uint8_t fan);
+
128  uint8_t getFanSpeed(void);
+
129  void setMode(const uint8_t mode);
+
130  uint8_t getMode(void);
+
131  void setSwing(const uint8_t mode);
+
132  uint8_t getSwing(const bool raw = false);
+
133  uint8_t* getRaw(void);
+
134  bool setRaw(const uint8_t newState[], const uint16_t length);
+
135  uint8_t getStateLength(void);
+
136  static bool validChecksum(uint8_t* state, const uint16_t length);
+
137  void setPower(const bool on);
+
138  void off(void);
+
139  void on(void);
+
140  bool getPower(void);
+
141  void setClean(const bool on);
+
142  bool getClean(const bool raw = false);
+
143  void setFilter(const bool on);
+
144  bool getFilter(const bool raw = false);
+
145  void setOutsideQuiet(const bool on);
+
146 
+
147  bool getOutsideQuiet(const bool raw = false);
+
148 
+
149  uint8_t convertMode(const stdAc::opmode_t mode);
+
150  uint8_t convertFan(stdAc::fanspeed_t speed);
+
151  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
152  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
153  stdAc::state_t toCommon(void);
+
154  String toString(void);
+
155 #ifndef UNIT_TEST
+
156 
+
157  private:
+ +
159 #else
+
160  IRsendTest _irsend;
+
162 #endif
+ +
165  uint8_t _temp;
+
166  uint8_t _fanSpeed;
+
167  uint8_t _mode;
+
168  uint8_t _swingMode;
+
169  uint8_t _cmd;
+ +
171  uint8_t _state_length;
+ + +
174  bool _clean;
+
175  bool _filter;
+
176  void buildState(void);
+
177  void buildFromState(const uint16_t length);
+
178 };
+
179 
+
180 #endif // IR_FUJITSU_H_
+
+
bool _clean
Definition: ir_Fujitsu.h:174
+
const uint8_t kFujitsuAcCmdTurnOff
Definition: ir_Fujitsu.h:49
+
const uint16_t kFujitsuAcMinRepeat
Definition: IRremoteESP8266.h:874
+
uint8_t _cmd
Definition: ir_Fujitsu.h:169
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
const uint8_t kFujitsuAcFilterOffset
Definition: ir_Fujitsu.h:75
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Fujitsu.h:116
+
void setClean(const bool on)
Set the Clean mode of the A/C.
Definition: ir_Fujitsu.cpp:491
+
const uint8_t kFujitsuAcCmdToggleSwingVert
Definition: ir_Fujitsu.h:53
+
uint8_t _fanSpeed
Definition: ir_Fujitsu.h:166
+
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_Fujitsu.cpp:229
+
bool _filter
Definition: ir_Fujitsu.h:175
+ +
void stepVert(void)
Request the A/C to step the Vertical Swing.
Definition: ir_Fujitsu.cpp:323
+
bool _outsideQuiet
Definition: ir_Fujitsu.h:173
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Fujitsu.cpp:418
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Fujitsu.cpp:559
+
void stateReset(void)
Reset the state of the remote to a known good state/sequence.
Definition: ir_Fujitsu.cpp:95
+
const uint8_t kFujitsuAcCleanOffset
Definition: ir_Fujitsu.h:74
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
const uint8_t kFujitsuAcFanAuto
Definition: ir_Fujitsu.h:57
+
bool setRaw(const uint8_t newState[], const uint16_t length)
Set the internal state from a valid code for this protocol.
Definition: ir_Fujitsu.cpp:298
+
std::string String
Definition: IRremoteESP8266.h:1093
+
const uint8_t kFujitsuAcOutsideQuietOffset
Definition: ir_Fujitsu.h:73
+
const uint8_t kFujitsuAcCmdTurnOn
Definition: ir_Fujitsu.h:48
+
uint8_t _state_length_short
Definition: ir_Fujitsu.h:172
+
const uint8_t kFujitsuAcMinTemp
Definition: ir_Fujitsu.h:64
+
const uint8_t kFujitsuAcFanHigh
Definition: ir_Fujitsu.h:58
+
const uint8_t kFujitsuAcModeHeat
Definition: ir_Fujitsu.h:45
+
void setFilter(const bool on)
Set the Filter mode status of the A/C.
Definition: ir_Fujitsu.cpp:512
+
uint8_t convertFan(stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Fujitsu.cpp:572
+ +
void stepHoriz(void)
Request the A/C to step the Horizontal Swing.
Definition: ir_Fujitsu.cpp:311
+
fujitsu_ac_remote_model_t getModel(void)
Get the currently emulated/detected model of the A/C.
Definition: ir_Fujitsu.cpp:92
+
const uint8_t kFujitsuAcCmdToggleSwingHoriz
Definition: ir_Fujitsu.h:55
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Fujitsu.h:158
+
fujitsu_ac_remote_model_t
Fujitsu A/C model numbers.
Definition: IRsend.h:120
+
void setCmd(const uint8_t cmd)
Set the requested (special) command part for the A/C message.
Definition: ir_Fujitsu.cpp:336
+
void buildFromState(const uint16_t length)
Build the internal state/config from the current (raw) A/C message.
Definition: ir_Fujitsu.cpp:236
+
uint8_t _temp
Definition: ir_Fujitsu.h:165
+
uint8_t _swingMode
Definition: ir_Fujitsu.h:168
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Fujitsu.cpp:107
+
Class for handling detailed Fujitsu A/C messages.
Definition: ir_Fujitsu.h:101
+
const uint8_t kFujitsuAcCmdStepVert
Definition: ir_Fujitsu.h:52
+
void setSwing(const uint8_t mode)
Set the requested swing operation mode of the A/C unit.
Definition: ir_Fujitsu.cpp:460
+
const uint16_t kFujitsuAcStateLength
Definition: IRremoteESP8266.h:875
+
const uint8_t kFujitsuAcCmdPowerful
Definition: ir_Fujitsu.h:51
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Fujitsu.cpp:586
+
const uint8_t kFujitsuAcSwingSize
Definition: ir_Fujitsu.h:67
+
uint8_t _mode
Definition: ir_Fujitsu.h:167
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Fujitsu.cpp:611
+
const uint8_t kFujitsuAcCmdStepHoriz
Definition: ir_Fujitsu.h:54
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Fujitsu.cpp:444
+
const uint8_t kFujitsuAcSwingHoriz
Definition: ir_Fujitsu.h:70
+
const uint8_t kFujitsuAcSwingVert
Definition: ir_Fujitsu.h:69
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Fujitsu.cpp:599
+
void toggleSwingVert(const bool update=true)
Request the A/C to toggle the Vertical Swing mode.
Definition: ir_Fujitsu.cpp:327
+ +
const uint8_t kFujitsuAcModeAuto
Definition: ir_Fujitsu.h:41
+
void setOutsideQuiet(const bool on)
Set the Outside Quiet mode of the A/C.
Definition: ir_Fujitsu.cpp:399
+
const uint8_t kFujitsuAcSwingOff
Definition: ir_Fujitsu.h:68
+
void setModel(const fujitsu_ac_remote_model_t model)
Set the currently emulated model of the A/C.
Definition: ir_Fujitsu.cpp:73
+
const uint8_t kFujitsuAcModeDry
Definition: ir_Fujitsu.h:43
+
@ ARRAH2E
Definition: IRsend.h:121
+
bool getFilter(const bool raw=false)
Get the Filter mode status of the A/C.
Definition: ir_Fujitsu.cpp:520
+
uint8_t getStateLength(void)
Get the length (size) of the state code for the current configuration.
Definition: ir_Fujitsu.cpp:214
+
const uint8_t kFujitsuAcFanSize
Definition: ir_Fujitsu.h:62
+
const uint8_t kFujitsuAcFanMed
Definition: ir_Fujitsu.h:59
+
IRFujitsuAC(const uint16_t pin, const fujitsu_ac_remote_model_t model=ARRAH2E, const bool inverted=false, const bool use_modulation=true)
Class Constructor.
Definition: ir_Fujitsu.cpp:63
+
const uint8_t kFujitsuAcSwingBoth
Definition: ir_Fujitsu.h:71
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Fujitsu.cpp:454
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Fujitsu.cpp:426
+
void buildState(void)
(Re)Build the state from the currently configured settings.
Definition: ir_Fujitsu.cpp:119
+
fujitsu_ac_remote_model_t _model
Definition: ir_Fujitsu.h:170
+
const uint8_t kFujitsuAcMaxTemp
Definition: ir_Fujitsu.h:65
+
const uint8_t kFujitsuAcCmdStayOn
Definition: ir_Fujitsu.h:47
+
bool getOutsideQuiet(const bool raw=false)
Get the Outside Quiet mode status of the A/C.
Definition: ir_Fujitsu.cpp:407
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Fujitsu.cpp:654
+
uint8_t getFanSpeed(void)
Get the current fan speed setting.
Definition: ir_Fujitsu.cpp:440
+
uint8_t getCmd(const bool raw=false)
Set the requested (special) command part for the A/C message.
Definition: ir_Fujitsu.cpp:376
+
void setFanSpeed(const uint8_t fan)
Set the speed of the fan.
Definition: ir_Fujitsu.cpp:430
+
uint8_t getSwing(const bool raw=false)
Get the requested swing operation mode of the A/C unit.
Definition: ir_Fujitsu.cpp:483
+
void off(void)
Set the requested power state of the A/C to off.
Definition: ir_Fujitsu.cpp:388
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Fujitsu.cpp:383
+
void on(void)
Set the requested power state of the A/C to on.
Definition: ir_Fujitsu.cpp:391
+
void send(const uint16_t repeat=kFujitsuAcMinRepeat)
Send the current internal state as an IR message.
Definition: ir_Fujitsu.cpp:112
+
bool getClean(const bool raw=false)
Get the Clean mode status of the A/C.
Definition: ir_Fujitsu.cpp:499
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Fujitsu.cpp:395
+
static bool validChecksum(uint8_t *state, const uint16_t length)
Verify the checksum is valid for a given state.
Definition: ir_Fujitsu.cpp:535
+
uint8_t _state_length
Definition: ir_Fujitsu.h:171
+
void toggleSwingHoriz(const bool update=true)
Request the A/C to toggle the Horizontal Swing mode.
Definition: ir_Fujitsu.cpp:315
+
const uint8_t kFujitsuAcModeFan
Definition: ir_Fujitsu.h:44
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
const uint8_t kFujitsuAcCmdEcono
Definition: ir_Fujitsu.h:50
+
uint8_t remote_state[kFujitsuAcStateLength]
The state of the IR remote.
Definition: ir_Fujitsu.h:164
+
const uint8_t kFujitsuAcFanQuiet
Definition: ir_Fujitsu.h:61
+
const uint8_t kFujitsuAcFanLow
Definition: ir_Fujitsu.h:60
+
const uint8_t kFujitsuAcModeCool
Definition: ir_Fujitsu.h:42
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__GICable_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__GICable_8cpp.html new file mode 100644 index 000000000..635f3333b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__GICable_8cpp.html @@ -0,0 +1,233 @@ + + + + + + + +IRremoteESP8266: src/ir_GICable.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_GICable.cpp File Reference
+
+
+ +

G.I. Cable. +More...

+ + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kGicableHdrMark = 9000
 
const uint16_t kGicableHdrSpace = 4400
 
const uint16_t kGicableBitMark = 550
 
const uint16_t kGicableOneSpace = 4400
 
const uint16_t kGicableZeroSpace = 2200
 
const uint16_t kGicableRptSpace = 2200
 
const uint32_t kGicableMinCommandLength = 99600
 
const uint32_t kGicableMinGap
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kGicableBitMark

+ +
+
+ + + + +
const uint16_t kGicableBitMark = 550
+
+ +
+
+ +

◆ kGicableHdrMark

+ +
+
+ + + + +
const uint16_t kGicableHdrMark = 9000
+
+ +
+
+ +

◆ kGicableHdrSpace

+ +
+
+ + + + +
const uint16_t kGicableHdrSpace = 4400
+
+ +
+
+ +

◆ kGicableMinCommandLength

+ +
+
+ + + + +
const uint32_t kGicableMinCommandLength = 99600
+
+ +
+
+ +

◆ kGicableMinGap

+ +
+
+ + + + +
const uint32_t kGicableMinGap
+
+
+ +

◆ kGicableOneSpace

+ +
+
+ + + + +
const uint16_t kGicableOneSpace = 4400
+
+ +
+
+ +

◆ kGicableRptSpace

+ +
+
+ + + + +
const uint16_t kGicableRptSpace = 2200
+
+ +
+
+ +

◆ kGicableZeroSpace

+ +
+
+ + + + +
const uint16_t kGicableZeroSpace = 2200
+
+ +
+
+
+
const uint16_t kGicableHdrSpace
Definition: ir_GICable.cpp:20
+
const uint16_t kGicableBits
Definition: IRremoteESP8266.h:879
+
const uint16_t kGicableOneSpace
Definition: ir_GICable.cpp:22
+
const uint32_t kGicableMinCommandLength
Definition: ir_GICable.cpp:25
+
const uint16_t kGicableBitMark
Definition: ir_GICable.cpp:21
+
const uint16_t kGicableHdrMark
Definition: ir_GICable.cpp:19
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__GlobalCache_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__GlobalCache_8cpp.html new file mode 100644 index 000000000..7ff602faf --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__GlobalCache_8cpp.html @@ -0,0 +1,189 @@ + + + + + + + +IRremoteESP8266: src/ir_GlobalCache.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_GlobalCache.cpp File Reference
+
+
+ +

Global Cache IR format sender Originally added by Hisham Khalifa (http://www.hishamkhalifa.com) +More...

+ + + + + + + + + + + + + + +

+Variables

const uint16_t kGlobalCacheMaxRepeat = 50
 
const uint32_t kGlobalCacheMinUsec = 80
 
const uint8_t kGlobalCacheFreqIndex = 0
 
const uint8_t kGlobalCacheRptIndex = kGlobalCacheFreqIndex + 1
 
const uint8_t kGlobalCacheRptStartIndex = kGlobalCacheRptIndex + 1
 
const uint8_t kGlobalCacheStartIndex = kGlobalCacheRptStartIndex + 1
 
+

Detailed Description

+

Global Cache IR format sender Originally added by Hisham Khalifa (http://www.hishamkhalifa.com)

+
See also
https://irdb.globalcache.com/Home/Database
+

Variable Documentation

+ +

◆ kGlobalCacheFreqIndex

+ +
+
+ + + + +
const uint8_t kGlobalCacheFreqIndex = 0
+
+ +
+
+ +

◆ kGlobalCacheMaxRepeat

+ +
+
+ + + + +
const uint16_t kGlobalCacheMaxRepeat = 50
+
+ +
+
+ +

◆ kGlobalCacheMinUsec

+ +
+
+ + + + +
const uint32_t kGlobalCacheMinUsec = 80
+
+ +
+
+ +

◆ kGlobalCacheRptIndex

+ +
+
+ + + + +
const uint8_t kGlobalCacheRptIndex = kGlobalCacheFreqIndex + 1
+
+ +
+
+ +

◆ kGlobalCacheRptStartIndex

+ +
+
+ + + + +
const uint8_t kGlobalCacheRptStartIndex = kGlobalCacheRptIndex + 1
+
+ +
+
+ +

◆ kGlobalCacheStartIndex

+ +
+
+ + + + +
const uint8_t kGlobalCacheStartIndex = kGlobalCacheRptStartIndex + 1
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Goodweather_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Goodweather_8cpp.html new file mode 100644 index 000000000..62188cc57 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Goodweather_8cpp.html @@ -0,0 +1,86 @@ + + + + + + + +IRremoteESP8266: src/ir_Goodweather.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Goodweather.cpp File Reference
+
+
+ +

Support for Goodweather compatible HVAC protocols. +More...

+

Detailed Description

+

Support for Goodweather compatible HVAC protocols.

+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/697
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Goodweather_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Goodweather_8h.html new file mode 100644 index 000000000..a7910ef35 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Goodweather_8h.html @@ -0,0 +1,886 @@ + + + + + + + +IRremoteESP8266: src/ir_Goodweather.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Goodweather.h File Reference
+
+
+ +

Support for Goodweather compatible HVAC protocols. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRGoodweatherAc
 Class for handling detailed Goodweather A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kGoodweatherBitMark = 580
 
const uint16_t kGoodweatherOneSpace = 580
 
const uint16_t kGoodweatherZeroSpace = 1860
 
const uint16_t kGoodweatherHdrMark = 6820
 
const uint16_t kGoodweatherHdrSpace = 6820
 
const uint8_t kGoodweatherExtraTolerance = 12
 
const uint8_t kGoodweatherBitLight = 8
 
const uint8_t kGoodweatherBitTurbo = kGoodweatherBitLight + 3
 
const uint8_t kGoodweatherBitCommand = kGoodweatherBitTurbo + 5
 
const uint8_t kGoodweatherCommandSize = 4
 
const uint8_t kGoodweatherBitSleep = kGoodweatherBitCommand + 8
 
const uint8_t kGoodweatherBitPower = kGoodweatherBitSleep + 1
 
const uint8_t kGoodweatherBitSwing = kGoodweatherBitPower + 1
 
const uint8_t kGoodweatherSwingSize = 2
 
const uint8_t kGoodweatherBitAirFlow = kGoodweatherBitSwing + 2
 
const uint8_t kGoodweatherBitFan = kGoodweatherBitAirFlow + 1
 
const uint8_t kGoodweatherFanSize = 2
 
const uint8_t kGoodweatherBitTemp = kGoodweatherBitFan + 3
 
const uint8_t kGoodweatherTempSize = 4
 
const uint8_t kGoodweatherBitMode = kGoodweatherBitTemp + 5
 
const uint8_t kGoodweatherBitEOF = kGoodweatherBitMode + 3
 
const uint64_t kGoodweatherEOFMask = 0xFFULL << kGoodweatherBitEOF
 
const uint8_t kGoodweatherAuto = 0b000
 
const uint8_t kGoodweatherCool = 0b001
 
const uint8_t kGoodweatherDry = 0b010
 
const uint8_t kGoodweatherFan = 0b011
 
const uint8_t kGoodweatherHeat = 0b100
 
const uint8_t kGoodweatherSwingFast = 0b00
 
const uint8_t kGoodweatherSwingSlow = 0b01
 
const uint8_t kGoodweatherSwingOff = 0b10
 
const uint8_t kGoodweatherFanAuto = 0b00
 
const uint8_t kGoodweatherFanHigh = 0b01
 
const uint8_t kGoodweatherFanMed = 0b10
 
const uint8_t kGoodweatherFanLow = 0b11
 
const uint8_t kGoodweatherTempMin = 16
 
const uint8_t kGoodweatherTempMax = 31
 
const uint8_t kGoodweatherCmdPower = 0x00
 
const uint8_t kGoodweatherCmdMode = 0x01
 
const uint8_t kGoodweatherCmdUpTemp = 0x02
 
const uint8_t kGoodweatherCmdDownTemp = 0x03
 
const uint8_t kGoodweatherCmdSwing = 0x04
 
const uint8_t kGoodweatherCmdFan = 0x05
 
const uint8_t kGoodweatherCmdTimer = 0x06
 
const uint8_t kGoodweatherCmdAirFlow = 0x07
 
const uint8_t kGoodweatherCmdHold = 0x08
 
const uint8_t kGoodweatherCmdSleep = 0x09
 
const uint8_t kGoodweatherCmdTurbo = 0x0A
 
const uint8_t kGoodweatherCmdLight = 0x0B
 
const uint64_t kGoodweatherStateInit = 0xD50000000000
 
+

Detailed Description

+

Support for Goodweather compatible HVAC protocols.

+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/697
+

Variable Documentation

+ +

◆ kGoodweatherAuto

+ +
+
+ + + + +
const uint8_t kGoodweatherAuto = 0b000
+
+ +
+
+ +

◆ kGoodweatherBitAirFlow

+ +
+
+ + + + +
const uint8_t kGoodweatherBitAirFlow = kGoodweatherBitSwing + 2
+
+ +
+
+ +

◆ kGoodweatherBitCommand

+ +
+
+ + + + +
const uint8_t kGoodweatherBitCommand = kGoodweatherBitTurbo + 5
+
+ +
+
+ +

◆ kGoodweatherBitEOF

+ +
+
+ + + + +
const uint8_t kGoodweatherBitEOF = kGoodweatherBitMode + 3
+
+ +
+
+ +

◆ kGoodweatherBitFan

+ +
+
+ + + + +
const uint8_t kGoodweatherBitFan = kGoodweatherBitAirFlow + 1
+
+ +
+
+ +

◆ kGoodweatherBitLight

+ +
+
+ + + + +
const uint8_t kGoodweatherBitLight = 8
+
+ +
+
+ +

◆ kGoodweatherBitMark

+ +
+
+ + + + +
const uint16_t kGoodweatherBitMark = 580
+
+ +
+
+ +

◆ kGoodweatherBitMode

+ +
+
+ + + + +
const uint8_t kGoodweatherBitMode = kGoodweatherBitTemp + 5
+
+ +
+
+ +

◆ kGoodweatherBitPower

+ +
+
+ + + + +
const uint8_t kGoodweatherBitPower = kGoodweatherBitSleep + 1
+
+ +
+
+ +

◆ kGoodweatherBitSleep

+ +
+
+ + + + +
const uint8_t kGoodweatherBitSleep = kGoodweatherBitCommand + 8
+
+ +
+
+ +

◆ kGoodweatherBitSwing

+ +
+
+ + + + +
const uint8_t kGoodweatherBitSwing = kGoodweatherBitPower + 1
+
+ +
+
+ +

◆ kGoodweatherBitTemp

+ +
+
+ + + + +
const uint8_t kGoodweatherBitTemp = kGoodweatherBitFan + 3
+
+ +
+
+ +

◆ kGoodweatherBitTurbo

+ +
+
+ + + + +
const uint8_t kGoodweatherBitTurbo = kGoodweatherBitLight + 3
+
+ +
+
+ +

◆ kGoodweatherCmdAirFlow

+ +
+
+ + + + +
const uint8_t kGoodweatherCmdAirFlow = 0x07
+
+ +
+
+ +

◆ kGoodweatherCmdDownTemp

+ +
+
+ + + + +
const uint8_t kGoodweatherCmdDownTemp = 0x03
+
+ +
+
+ +

◆ kGoodweatherCmdFan

+ +
+
+ + + + +
const uint8_t kGoodweatherCmdFan = 0x05
+
+ +
+
+ +

◆ kGoodweatherCmdHold

+ +
+
+ + + + +
const uint8_t kGoodweatherCmdHold = 0x08
+
+ +
+
+ +

◆ kGoodweatherCmdLight

+ +
+
+ + + + +
const uint8_t kGoodweatherCmdLight = 0x0B
+
+ +
+
+ +

◆ kGoodweatherCmdMode

+ +
+
+ + + + +
const uint8_t kGoodweatherCmdMode = 0x01
+
+ +
+
+ +

◆ kGoodweatherCmdPower

+ +
+
+ + + + +
const uint8_t kGoodweatherCmdPower = 0x00
+
+ +
+
+ +

◆ kGoodweatherCmdSleep

+ +
+
+ + + + +
const uint8_t kGoodweatherCmdSleep = 0x09
+
+ +
+
+ +

◆ kGoodweatherCmdSwing

+ +
+
+ + + + +
const uint8_t kGoodweatherCmdSwing = 0x04
+
+ +
+
+ +

◆ kGoodweatherCmdTimer

+ +
+
+ + + + +
const uint8_t kGoodweatherCmdTimer = 0x06
+
+ +
+
+ +

◆ kGoodweatherCmdTurbo

+ +
+
+ + + + +
const uint8_t kGoodweatherCmdTurbo = 0x0A
+
+ +
+
+ +

◆ kGoodweatherCmdUpTemp

+ +
+
+ + + + +
const uint8_t kGoodweatherCmdUpTemp = 0x02
+
+ +
+
+ +

◆ kGoodweatherCommandSize

+ +
+
+ + + + +
const uint8_t kGoodweatherCommandSize = 4
+
+ +
+
+ +

◆ kGoodweatherCool

+ +
+
+ + + + +
const uint8_t kGoodweatherCool = 0b001
+
+ +
+
+ +

◆ kGoodweatherDry

+ +
+
+ + + + +
const uint8_t kGoodweatherDry = 0b010
+
+ +
+
+ +

◆ kGoodweatherEOFMask

+ +
+
+ + + + +
const uint64_t kGoodweatherEOFMask = 0xFFULL << kGoodweatherBitEOF
+
+ +
+
+ +

◆ kGoodweatherExtraTolerance

+ +
+
+ + + + +
const uint8_t kGoodweatherExtraTolerance = 12
+
+ +
+
+ +

◆ kGoodweatherFan

+ +
+
+ + + + +
const uint8_t kGoodweatherFan = 0b011
+
+ +
+
+ +

◆ kGoodweatherFanAuto

+ +
+
+ + + + +
const uint8_t kGoodweatherFanAuto = 0b00
+
+ +
+
+ +

◆ kGoodweatherFanHigh

+ +
+
+ + + + +
const uint8_t kGoodweatherFanHigh = 0b01
+
+ +
+
+ +

◆ kGoodweatherFanLow

+ +
+
+ + + + +
const uint8_t kGoodweatherFanLow = 0b11
+
+ +
+
+ +

◆ kGoodweatherFanMed

+ +
+
+ + + + +
const uint8_t kGoodweatherFanMed = 0b10
+
+ +
+
+ +

◆ kGoodweatherFanSize

+ +
+
+ + + + +
const uint8_t kGoodweatherFanSize = 2
+
+ +
+
+ +

◆ kGoodweatherHdrMark

+ +
+
+ + + + +
const uint16_t kGoodweatherHdrMark = 6820
+
+ +
+
+ +

◆ kGoodweatherHdrSpace

+ +
+
+ + + + +
const uint16_t kGoodweatherHdrSpace = 6820
+
+ +
+
+ +

◆ kGoodweatherHeat

+ +
+
+ + + + +
const uint8_t kGoodweatherHeat = 0b100
+
+ +
+
+ +

◆ kGoodweatherOneSpace

+ +
+
+ + + + +
const uint16_t kGoodweatherOneSpace = 580
+
+ +
+
+ +

◆ kGoodweatherStateInit

+ +
+
+ + + + +
const uint64_t kGoodweatherStateInit = 0xD50000000000
+
+ +
+
+ +

◆ kGoodweatherSwingFast

+ +
+
+ + + + +
const uint8_t kGoodweatherSwingFast = 0b00
+
+ +
+
+ +

◆ kGoodweatherSwingOff

+ +
+
+ + + + +
const uint8_t kGoodweatherSwingOff = 0b10
+
+ +
+
+ +

◆ kGoodweatherSwingSize

+ +
+
+ + + + +
const uint8_t kGoodweatherSwingSize = 2
+
+ +
+
+ +

◆ kGoodweatherSwingSlow

+ +
+
+ + + + +
const uint8_t kGoodweatherSwingSlow = 0b01
+
+ +
+
+ +

◆ kGoodweatherTempMax

+ +
+
+ + + + +
const uint8_t kGoodweatherTempMax = 31
+
+ +
+
+ +

◆ kGoodweatherTempMin

+ +
+
+ + + + +
const uint8_t kGoodweatherTempMin = 16
+
+ +
+
+ +

◆ kGoodweatherTempSize

+ +
+
+ + + + +
const uint8_t kGoodweatherTempSize = 4
+
+ +
+
+ +

◆ kGoodweatherZeroSpace

+ +
+
+ + + + +
const uint16_t kGoodweatherZeroSpace = 1860
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Goodweather_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Goodweather_8h_source.html new file mode 100644 index 000000000..3a72c4a94 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Goodweather_8h_source.html @@ -0,0 +1,310 @@ + + + + + + + +IRremoteESP8266: src/ir_Goodweather.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Goodweather.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 ribeirodanielf
+
2 // Copyright 2019 David Conran
+
3 
+
7 
+
8 // Supports:
+
9 // Brand: Goodweather, Model: ZH/JT-03 remote
+
10 
+
11 #ifndef IR_GOODWEATHER_H_
+
12 #define IR_GOODWEATHER_H_
+
13 
+
14 #define __STDC_LIMIT_MACROS
+
15 #include <stdint.h>
+
16 #ifndef UNIT_TEST
+
17 #include <Arduino.h>
+
18 #endif
+
19 #include "IRremoteESP8266.h"
+
20 #include "IRsend.h"
+
21 #ifdef UNIT_TEST
+
22 #include "IRsend_test.h"
+
23 #endif
+
24 
+
25 
+
26 // Constants
+
27 // Timing
+
28 const uint16_t kGoodweatherBitMark = 580;
+
29 const uint16_t kGoodweatherOneSpace = 580;
+
30 const uint16_t kGoodweatherZeroSpace = 1860;
+
31 const uint16_t kGoodweatherHdrMark = 6820;
+
32 const uint16_t kGoodweatherHdrSpace = 6820;
+
33 const uint8_t kGoodweatherExtraTolerance = 12; // +12% extra
+
34 
+
35 // Masks
+
36 const uint8_t kGoodweatherBitLight = 8;
+
37 const uint8_t kGoodweatherBitTurbo = kGoodweatherBitLight + 3; // 11
+
38 const uint8_t kGoodweatherBitCommand = kGoodweatherBitTurbo + 5; // 16
+
39 const uint8_t kGoodweatherCommandSize = 4; // Bits
+
40 const uint8_t kGoodweatherBitSleep = kGoodweatherBitCommand + 8; // 24
+
41 const uint8_t kGoodweatherBitPower = kGoodweatherBitSleep + 1; // 25
+
42 const uint8_t kGoodweatherBitSwing = kGoodweatherBitPower + 1; // 26
+
43 const uint8_t kGoodweatherSwingSize = 2; // Bits
+
44 const uint8_t kGoodweatherBitAirFlow = kGoodweatherBitSwing + 2; // 28
+
45 const uint8_t kGoodweatherBitFan = kGoodweatherBitAirFlow + 1; // 29
+
46 const uint8_t kGoodweatherFanSize = 2; // Bits
+
47 const uint8_t kGoodweatherBitTemp = kGoodweatherBitFan + 3; // 32
+
48 const uint8_t kGoodweatherTempSize = 4; // Bits
+
49 const uint8_t kGoodweatherBitMode = kGoodweatherBitTemp + 5; // 37
+
50 const uint8_t kGoodweatherBitEOF = kGoodweatherBitMode + 3; // 40
+
51 const uint64_t kGoodweatherEOFMask = 0xFFULL << kGoodweatherBitEOF;
+
52 
+
53 // Modes
+
54 const uint8_t kGoodweatherAuto = 0b000;
+
55 const uint8_t kGoodweatherCool = 0b001;
+
56 const uint8_t kGoodweatherDry = 0b010;
+
57 const uint8_t kGoodweatherFan = 0b011;
+
58 const uint8_t kGoodweatherHeat = 0b100;
+
59 // Swing
+
60 const uint8_t kGoodweatherSwingFast = 0b00;
+
61 const uint8_t kGoodweatherSwingSlow = 0b01;
+
62 const uint8_t kGoodweatherSwingOff = 0b10;
+
63 // Fan Control
+
64 const uint8_t kGoodweatherFanAuto = 0b00;
+
65 const uint8_t kGoodweatherFanHigh = 0b01;
+
66 const uint8_t kGoodweatherFanMed = 0b10;
+
67 const uint8_t kGoodweatherFanLow = 0b11;
+
68 // Temperature
+
69 const uint8_t kGoodweatherTempMin = 16; // Celsius
+
70 const uint8_t kGoodweatherTempMax = 31; // Celsius
+
71 // Commands
+
72 const uint8_t kGoodweatherCmdPower = 0x00;
+
73 const uint8_t kGoodweatherCmdMode = 0x01;
+
74 const uint8_t kGoodweatherCmdUpTemp = 0x02;
+
75 const uint8_t kGoodweatherCmdDownTemp = 0x03;
+
76 const uint8_t kGoodweatherCmdSwing = 0x04;
+
77 const uint8_t kGoodweatherCmdFan = 0x05;
+
78 const uint8_t kGoodweatherCmdTimer = 0x06;
+
79 const uint8_t kGoodweatherCmdAirFlow = 0x07;
+
80 const uint8_t kGoodweatherCmdHold = 0x08;
+
81 const uint8_t kGoodweatherCmdSleep = 0x09;
+
82 const uint8_t kGoodweatherCmdTurbo = 0x0A;
+
83 const uint8_t kGoodweatherCmdLight = 0x0B;
+
84 // PAD EOF
+
85 const uint64_t kGoodweatherStateInit = 0xD50000000000;
+
86 
+
87 
+
88 // Classes
+ +
91  public:
+
92  explicit IRGoodweatherAc(const uint16_t pin, const bool inverted = false,
+
93  const bool use_modulation = true);
+
94  void stateReset(void);
+
95 #if SEND_GOODWEATHER
+
96  void send(const uint16_t repeat = kGoodweatherMinRepeat);
+
101  int8_t calibrate(void) { return _irsend.calibrate(); }
+
102 #endif // SEND_GOODWEATHER
+
103  void begin(void);
+
104  void on(void);
+
105  void off(void);
+
106  void setPower(const bool on);
+
107  bool getPower(void);
+
108  void setTemp(const uint8_t temp);
+
109  uint8_t getTemp(void);
+
110  void setFan(const uint8_t speed);
+
111  uint8_t getFan(void);
+
112  void setMode(const uint8_t mode);
+
113  uint8_t getMode();
+
114  void setSwing(const uint8_t speed);
+
115  uint8_t getSwing(void);
+
116  void setSleep(const bool toggle);
+
117  bool getSleep(void);
+
118  void setTurbo(const bool toggle);
+
119  bool getTurbo(void);
+
120  void setLight(const bool toggle);
+
121  bool getLight(void);
+
122  void setCommand(const uint8_t cmd);
+
123  uint8_t getCommand(void);
+
124  uint64_t getRaw(void);
+
125  void setRaw(const uint64_t state);
+
126  uint8_t convertMode(const stdAc::opmode_t mode);
+
127  uint8_t convertFan(const stdAc::fanspeed_t speed);
+
128  uint8_t convertSwingV(const stdAc::swingv_t swingv);
+
129  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
130  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
131  stdAc::state_t toCommon(void);
+
132  String toString();
+
133 #ifndef UNIT_TEST
+
134 
+
135  private:
+ +
137 #else // UNIT_TEST
+
138  IRsendTest _irsend;
+
140 #endif // UNIT_TEST
+
142  uint64_t remote;
+
143 };
+
144 #endif // IR_GOODWEATHER_H_
+
+
const uint8_t kGoodweatherBitTurbo
Definition: ir_Goodweather.h:37
+
const uint8_t kGoodweatherCmdLight
Definition: ir_Goodweather.h:83
+
const uint8_t kGoodweatherCmdDownTemp
Definition: ir_Goodweather.h:75
+
void off(void)
Change the power setting to Off.
Definition: ir_Goodweather.cpp:96
+
void on(void)
Change the power setting to On.
Definition: ir_Goodweather.cpp:93
+
const uint16_t kGoodweatherOneSpace
Definition: ir_Goodweather.h:29
+
const uint8_t kGoodweatherCommandSize
Definition: ir_Goodweather.h:39
+
void stateReset(void)
Reset the internal state to a fixed known good state.
Definition: ir_Goodweather.cpp:71
+
const uint8_t kGoodweatherTempMin
Definition: ir_Goodweather.h:69
+
bool getLight(void)
Get the Light (LED) Toggle setting of the A/C.
Definition: ir_Goodweather.cpp:184
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Goodweather.h:136
+
const uint8_t kGoodweatherCmdPower
Definition: ir_Goodweather.h:72
+
swingv_t
Common A/C settings for Vertical Swing.
Definition: IRsend.h:70
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Goodweather.cpp:317
+
const uint8_t kGoodweatherCmdAirFlow
Definition: ir_Goodweather.h:79
+
bool getTurbo(void)
Get the Turbo Toggle setting of the A/C.
Definition: ir_Goodweather.cpp:210
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
const uint8_t kGoodweatherFanSize
Definition: ir_Goodweather.h:46
+
void setTurbo(const bool toggle)
Set the Turbo Toggle setting of the A/C.
Definition: ir_Goodweather.cpp:203
+
bool getSleep(void)
Get the Sleep Toggle setting of the A/C.
Definition: ir_Goodweather.cpp:197
+
void setLight(const bool toggle)
Set the Light (LED) Toggle setting of the A/C.
Definition: ir_Goodweather.cpp:177
+
const uint8_t kGoodweatherBitMode
Definition: ir_Goodweather.h:49
+ +
const uint8_t kGoodweatherCmdSwing
Definition: ir_Goodweather.h:76
+
const uint8_t kGoodweatherFanMed
Definition: ir_Goodweather.h:66
+
uint8_t convertSwingV(const stdAc::swingv_t swingv)
Convert a stdAc::swingv_t enum into it's native setting.
Definition: ir_Goodweather.cpp:278
+
const uint8_t kGoodweatherCmdUpTemp
Definition: ir_Goodweather.h:74
+
const uint16_t kGoodweatherHdrSpace
Definition: ir_Goodweather.h:32
+
const uint64_t kGoodweatherEOFMask
Definition: ir_Goodweather.h:51
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Goodweather.h:101
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
const uint8_t kGoodweatherFanAuto
Definition: ir_Goodweather.h:64
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
IRGoodweatherAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Goodweather.cpp:66
+
const uint16_t kGoodweatherZeroSpace
Definition: ir_Goodweather.h:30
+
void setRaw(const uint64_t state)
Set the internal state from a valid code for this protocol.
Definition: ir_Goodweather.cpp:90
+
const uint8_t kGoodweatherAuto
Definition: ir_Goodweather.h:54
+
std::string String
Definition: IRremoteESP8266.h:1093
+
void send(const uint16_t repeat=kGoodweatherMinRepeat)
Send the current internal state as an IR message.
Definition: ir_Goodweather.cpp:79
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Goodweather.cpp:293
+
const uint8_t kGoodweatherExtraTolerance
Definition: ir_Goodweather.h:33
+
const uint8_t kGoodweatherSwingSlow
Definition: ir_Goodweather.h:61
+
const uint8_t kGoodweatherTempSize
Definition: ir_Goodweather.h:48
+ +
const uint8_t kGoodweatherSwingOff
Definition: ir_Goodweather.h:62
+
const uint8_t kGoodweatherDry
Definition: ir_Goodweather.h:56
+
const uint8_t kGoodweatherSwingFast
Definition: ir_Goodweather.h:60
+
const uint8_t kGoodweatherBitFan
Definition: ir_Goodweather.h:45
+
const uint8_t kGoodweatherCmdSleep
Definition: ir_Goodweather.h:81
+
const uint8_t kGoodweatherCool
Definition: ir_Goodweather.h:55
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Goodweather.cpp:113
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Goodweather.cpp:74
+
const uint8_t kGoodweatherBitEOF
Definition: ir_Goodweather.h:50
+
const uint8_t kGoodweatherCmdFan
Definition: ir_Goodweather.h:77
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Goodweather.cpp:107
+
const uint8_t kGoodweatherCmdHold
Definition: ir_Goodweather.h:80
+
void setSwing(const uint8_t speed)
Set the Vertical Swing speed of the A/C.
Definition: ir_Goodweather.cpp:216
+
const uint8_t kGoodweatherFan
Definition: ir_Goodweather.h:57
+
const uint8_t kGoodweatherCmdTurbo
Definition: ir_Goodweather.h:82
+
void setCommand(const uint8_t cmd)
Set the remote Command type/button pressed.
Definition: ir_Goodweather.cpp:237
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Goodweather.cpp:147
+
const uint8_t kGoodweatherBitSwing
Definition: ir_Goodweather.h:42
+
const uint64_t kGoodweatherStateInit
Definition: ir_Goodweather.h:85
+
const uint8_t kGoodweatherCmdTimer
Definition: ir_Goodweather.h:78
+
const uint8_t kGoodweatherBitSleep
Definition: ir_Goodweather.h:40
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Goodweather.cpp:153
+
const uint8_t kGoodweatherBitLight
Definition: ir_Goodweather.h:36
+
const uint8_t kGoodweatherTempMax
Definition: ir_Goodweather.h:70
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Goodweather.cpp:306
+
uint8_t getCommand(void)
Get the Command type/button pressed from the current settings.
Definition: ir_Goodweather.cpp:244
+
const uint8_t kGoodweatherFanLow
Definition: ir_Goodweather.h:67
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Goodweather.cpp:124
+
String toString()
Convert the current internal state into a human readable string.
Definition: ir_Goodweather.cpp:344
+
void setFan(const uint8_t speed)
Set the speed of the fan.
Definition: ir_Goodweather.cpp:131
+
const uint8_t kGoodweatherHeat
Definition: ir_Goodweather.h:58
+
const uint16_t kGoodweatherBitMark
Definition: ir_Goodweather.h:28
+
uint64_t remote
The state of the IR remote in IR code form.
Definition: ir_Goodweather.h:142
+
const uint8_t kGoodweatherFanHigh
Definition: ir_Goodweather.h:65
+
uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Goodweather.cpp:264
+
uint8_t getMode()
Get the operating mode setting of the A/C.
Definition: ir_Goodweather.cpp:171
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Goodweather.cpp:251
+
const uint16_t kGoodweatherHdrMark
Definition: ir_Goodweather.h:31
+
const uint8_t kGoodweatherSwingSize
Definition: ir_Goodweather.h:43
+
const uint8_t kGoodweatherBitAirFlow
Definition: ir_Goodweather.h:44
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Goodweather.cpp:100
+
void setSleep(const bool toggle)
Set the Sleep Toggle setting of the A/C.
Definition: ir_Goodweather.cpp:190
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
Class for handling detailed Goodweather A/C messages.
Definition: ir_Goodweather.h:90
+
const uint8_t kGoodweatherBitCommand
Definition: ir_Goodweather.h:38
+
const uint8_t kGoodweatherBitPower
Definition: ir_Goodweather.h:41
+
const uint8_t kGoodweatherBitTemp
Definition: ir_Goodweather.h:47
+
uint64_t getRaw(void)
Get a copy of the internal state as a valid code for this protocol.
Definition: ir_Goodweather.cpp:86
+
const uint16_t kGoodweatherMinRepeat
Definition: IRremoteESP8266.h:882
+
const uint8_t kGoodweatherCmdMode
Definition: ir_Goodweather.h:73
+
uint8_t getSwing(void)
Get the Vertical Swing speed of the A/C.
Definition: ir_Goodweather.cpp:231
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Gree_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Gree_8cpp.html new file mode 100644 index 000000000..182deded3 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Gree_8cpp.html @@ -0,0 +1,224 @@ + + + + + + + +IRremoteESP8266: src/ir_Gree.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Gree.cpp File Reference
+
+
+ +

Support for Gree A/C protocols. +More...

+ + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kGreeHdrMark = 9000
 
const uint16_t kGreeHdrSpace = 4500
 See #684 & real example in unit tests. More...
 
const uint16_t kGreeBitMark = 620
 
const uint16_t kGreeOneSpace = 1600
 
const uint16_t kGreeZeroSpace = 540
 
const uint16_t kGreeMsgSpace = 19000
 
const uint8_t kGreeBlockFooter = 0b010
 
const uint8_t kGreeBlockFooterBits = 3
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kGreeBitMark

+ +
+
+ + + + +
const uint16_t kGreeBitMark = 620
+
+ +
+
+ +

◆ kGreeBlockFooter

+ +
+
+ + + + +
const uint8_t kGreeBlockFooter = 0b010
+
+ +
+
+ +

◆ kGreeBlockFooterBits

+ +
+
+ + + + +
const uint8_t kGreeBlockFooterBits = 3
+
+ +
+
+ +

◆ kGreeHdrMark

+ +
+
+ + + + +
const uint16_t kGreeHdrMark = 9000
+
+ +
+
+ +

◆ kGreeHdrSpace

+ +
+
+ + + + +
const uint16_t kGreeHdrSpace = 4500
+
+ +

See #684 & real example in unit tests.

+ +
+
+ +

◆ kGreeMsgSpace

+ +
+
+ + + + +
const uint16_t kGreeMsgSpace = 19000
+
+ +
+
+ +

◆ kGreeOneSpace

+ +
+
+ + + + +
const uint16_t kGreeOneSpace = 1600
+
+ +
+
+ +

◆ kGreeZeroSpace

+ +
+
+ + + + +
const uint16_t kGreeZeroSpace = 540
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Gree_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Gree_8h.html new file mode 100644 index 000000000..1e9e1788e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Gree_8h.html @@ -0,0 +1,934 @@ + + + + + + + +IRremoteESP8266: src/ir_Gree.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Gree.h File Reference
+
+
+ +

Support for Gree A/C protocols. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRGreeAC
 Class for handling detailed Gree A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kGreeAuto = 0
 
const uint8_t kGreeCool = 1
 
const uint8_t kGreeDry = 2
 
const uint8_t kGreeFan = 3
 
const uint8_t kGreeHeat = 4
 
const uint8_t kGreePower1Offset = 3
 
const uint8_t kGreeFanOffset = 4
 
const uint8_t kGreeFanSize = 2
 
const uint8_t kGreeFanAuto = 0
 
const uint8_t kGreeFanMin = 1
 
const uint8_t kGreeFanMed = 2
 
const uint8_t kGreeFanMax = 3
 
const uint8_t kGreeSwingAutoOffset = 6
 
const uint8_t kGreeSleepOffset = 7
 
const uint8_t kGreeTempOffset = 0
 
const uint8_t kGreeTempSize = 4
 
const uint8_t kGreeMinTempC = 16
 
const uint8_t kGreeMaxTempC = 30
 
const uint8_t kGreeMinTempF = 61
 
const uint8_t kGreeMaxTempF = 86
 
const uint8_t kGreeTimerHalfHrOffset = 4
 
const uint8_t kGreeTimerTensHrOffset = 5
 
const uint8_t kGreeTimerTensHrSize = 2
 
const uint16_t kGreeTimerMax = 24 * 60
 
const uint8_t kGreeTimerEnabledOffset = 7
 
const uint8_t kGreeTimerHoursOffset = 0
 
const uint8_t kGreeTimerHoursSize = 4
 
const uint8_t kGreeTurboOffset = 4
 
const uint8_t kGreeLightOffset = 5
 
const uint8_t kGreePower2Offset = 6
 
const uint8_t kGreeXfanOffset = 7
 
const uint8_t kGreeTempExtraDegreeFOffset = 2
 
const uint8_t kGreeUseFahrenheitOffset = 3
 
const uint8_t kGreeSwingSize = 4
 
const uint8_t kGreeSwingLastPos = 0b0000
 
const uint8_t kGreeSwingAuto = 0b0001
 
const uint8_t kGreeSwingUp = 0b0010
 
const uint8_t kGreeSwingMiddleUp = 0b0011
 
const uint8_t kGreeSwingMiddle = 0b0100
 
const uint8_t kGreeSwingMiddleDown = 0b0101
 
const uint8_t kGreeSwingDown = 0b0110
 
const uint8_t kGreeSwingDownAuto = 0b0111
 
const uint8_t kGreeSwingMiddleAuto = 0b1001
 
const uint8_t kGreeSwingUpAuto = 0b1011
 
const uint8_t kGreeWiFiOffset = 6
 
const uint8_t kGreeIFeelOffset = 2
 
const uint8_t kGreeDisplayTempOffset = 0
 
const uint8_t kGreeDisplayTempSize = 2
 
const uint8_t kGreeDisplayTempOff = 0b00
 
const uint8_t kGreeDisplayTempSet = 0b01
 
const uint8_t kGreeDisplayTempInside = 0b10
 
const uint8_t kGreeDisplayTempOutside = 0b11
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kGreeAuto

+ +
+
+ + + + +
const uint8_t kGreeAuto = 0
+
+ +
+
+ +

◆ kGreeCool

+ +
+
+ + + + +
const uint8_t kGreeCool = 1
+
+ +
+
+ +

◆ kGreeDisplayTempInside

+ +
+
+ + + + +
const uint8_t kGreeDisplayTempInside = 0b10
+
+ +
+
+ +

◆ kGreeDisplayTempOff

+ +
+
+ + + + +
const uint8_t kGreeDisplayTempOff = 0b00
+
+ +
+
+ +

◆ kGreeDisplayTempOffset

+ +
+
+ + + + +
const uint8_t kGreeDisplayTempOffset = 0
+
+ +
+
+ +

◆ kGreeDisplayTempOutside

+ +
+
+ + + + +
const uint8_t kGreeDisplayTempOutside = 0b11
+
+ +
+
+ +

◆ kGreeDisplayTempSet

+ +
+
+ + + + +
const uint8_t kGreeDisplayTempSet = 0b01
+
+ +
+
+ +

◆ kGreeDisplayTempSize

+ +
+
+ + + + +
const uint8_t kGreeDisplayTempSize = 2
+
+ +
+
+ +

◆ kGreeDry

+ +
+
+ + + + +
const uint8_t kGreeDry = 2
+
+ +
+
+ +

◆ kGreeFan

+ +
+
+ + + + +
const uint8_t kGreeFan = 3
+
+ +
+
+ +

◆ kGreeFanAuto

+ +
+
+ + + + +
const uint8_t kGreeFanAuto = 0
+
+ +
+
+ +

◆ kGreeFanMax

+ +
+
+ + + + +
const uint8_t kGreeFanMax = 3
+
+ +
+
+ +

◆ kGreeFanMed

+ +
+
+ + + + +
const uint8_t kGreeFanMed = 2
+
+ +
+
+ +

◆ kGreeFanMin

+ +
+
+ + + + +
const uint8_t kGreeFanMin = 1
+
+ +
+
+ +

◆ kGreeFanOffset

+ +
+
+ + + + +
const uint8_t kGreeFanOffset = 4
+
+ +
+
+ +

◆ kGreeFanSize

+ +
+
+ + + + +
const uint8_t kGreeFanSize = 2
+
+ +
+
+ +

◆ kGreeHeat

+ +
+
+ + + + +
const uint8_t kGreeHeat = 4
+
+ +
+
+ +

◆ kGreeIFeelOffset

+ +
+
+ + + + +
const uint8_t kGreeIFeelOffset = 2
+
+ +
+
+ +

◆ kGreeLightOffset

+ +
+
+ + + + +
const uint8_t kGreeLightOffset = 5
+
+ +
+
+ +

◆ kGreeMaxTempC

+ +
+
+ + + + +
const uint8_t kGreeMaxTempC = 30
+
+ +
+
+ +

◆ kGreeMaxTempF

+ +
+
+ + + + +
const uint8_t kGreeMaxTempF = 86
+
+ +
+
+ +

◆ kGreeMinTempC

+ +
+
+ + + + +
const uint8_t kGreeMinTempC = 16
+
+ +
+
+ +

◆ kGreeMinTempF

+ +
+
+ + + + +
const uint8_t kGreeMinTempF = 61
+
+ +
+
+ +

◆ kGreePower1Offset

+ +
+
+ + + + +
const uint8_t kGreePower1Offset = 3
+
+ +
+
+ +

◆ kGreePower2Offset

+ +
+
+ + + + +
const uint8_t kGreePower2Offset = 6
+
+ +
+
+ +

◆ kGreeSleepOffset

+ +
+
+ + + + +
const uint8_t kGreeSleepOffset = 7
+
+ +
+
+ +

◆ kGreeSwingAuto

+ +
+
+ + + + +
const uint8_t kGreeSwingAuto = 0b0001
+
+ +
+
+ +

◆ kGreeSwingAutoOffset

+ +
+
+ + + + +
const uint8_t kGreeSwingAutoOffset = 6
+
+ +
+
+ +

◆ kGreeSwingDown

+ +
+
+ + + + +
const uint8_t kGreeSwingDown = 0b0110
+
+ +
+
+ +

◆ kGreeSwingDownAuto

+ +
+
+ + + + +
const uint8_t kGreeSwingDownAuto = 0b0111
+
+ +
+
+ +

◆ kGreeSwingLastPos

+ +
+
+ + + + +
const uint8_t kGreeSwingLastPos = 0b0000
+
+ +
+
+ +

◆ kGreeSwingMiddle

+ +
+
+ + + + +
const uint8_t kGreeSwingMiddle = 0b0100
+
+ +
+
+ +

◆ kGreeSwingMiddleAuto

+ +
+
+ + + + +
const uint8_t kGreeSwingMiddleAuto = 0b1001
+
+ +
+
+ +

◆ kGreeSwingMiddleDown

+ +
+
+ + + + +
const uint8_t kGreeSwingMiddleDown = 0b0101
+
+ +
+
+ +

◆ kGreeSwingMiddleUp

+ +
+
+ + + + +
const uint8_t kGreeSwingMiddleUp = 0b0011
+
+ +
+
+ +

◆ kGreeSwingSize

+ +
+
+ + + + +
const uint8_t kGreeSwingSize = 4
+
+ +
+
+ +

◆ kGreeSwingUp

+ +
+
+ + + + +
const uint8_t kGreeSwingUp = 0b0010
+
+ +
+
+ +

◆ kGreeSwingUpAuto

+ +
+
+ + + + +
const uint8_t kGreeSwingUpAuto = 0b1011
+
+ +
+
+ +

◆ kGreeTempExtraDegreeFOffset

+ +
+
+ + + + +
const uint8_t kGreeTempExtraDegreeFOffset = 2
+
+ +
+
+ +

◆ kGreeTempOffset

+ +
+
+ + + + +
const uint8_t kGreeTempOffset = 0
+
+ +
+
+ +

◆ kGreeTempSize

+ +
+
+ + + + +
const uint8_t kGreeTempSize = 4
+
+ +
+
+ +

◆ kGreeTimerEnabledOffset

+ +
+
+ + + + +
const uint8_t kGreeTimerEnabledOffset = 7
+
+ +
+
+ +

◆ kGreeTimerHalfHrOffset

+ +
+
+ + + + +
const uint8_t kGreeTimerHalfHrOffset = 4
+
+ +
+
+ +

◆ kGreeTimerHoursOffset

+ +
+
+ + + + +
const uint8_t kGreeTimerHoursOffset = 0
+
+ +
+
+ +

◆ kGreeTimerHoursSize

+ +
+
+ + + + +
const uint8_t kGreeTimerHoursSize = 4
+
+ +
+
+ +

◆ kGreeTimerMax

+ +
+
+ + + + +
const uint16_t kGreeTimerMax = 24 * 60
+
+ +
+
+ +

◆ kGreeTimerTensHrOffset

+ +
+
+ + + + +
const uint8_t kGreeTimerTensHrOffset = 5
+
+ +
+
+ +

◆ kGreeTimerTensHrSize

+ +
+
+ + + + +
const uint8_t kGreeTimerTensHrSize = 2
+
+ +
+
+ +

◆ kGreeTurboOffset

+ +
+
+ + + + +
const uint8_t kGreeTurboOffset = 4
+
+ +
+
+ +

◆ kGreeUseFahrenheitOffset

+ +
+
+ + + + +
const uint8_t kGreeUseFahrenheitOffset = 3
+
+ +
+
+ +

◆ kGreeWiFiOffset

+ +
+
+ + + + +
const uint8_t kGreeWiFiOffset = 6
+
+ +
+
+ +

◆ kGreeXfanOffset

+ +
+
+ + + + +
const uint8_t kGreeXfanOffset = 7
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Gree_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Gree_8h_source.html new file mode 100644 index 000000000..4abec57b7 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Gree_8h_source.html @@ -0,0 +1,387 @@ + + + + + + + +IRremoteESP8266: src/ir_Gree.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Gree.h
+
+
+Go to the documentation of this file.
1 // Copyright 2016 David Conran
+
2 
+
6 
+
7 // Supports:
+
8 // Brand: Ultimate, Model: Heat Pump
+
9 // Brand: EKOKAI, Model: A/C
+
10 // Brand: RusClimate, Model: EACS/I-09HAR_X/N3 A/C
+
11 // Brand: RusClimate, Model: YAW1F remote
+
12 // Brand: Green, Model: YBOFB remote
+
13 // Brand: Green, Model: YBOFB2 remote
+
14 // Brand: Gree, Model: YAA1FBF remote
+
15 // Brand: Gree, Model: YB1F2F remote
+
16 
+
17 #ifndef IR_GREE_H_
+
18 #define IR_GREE_H_
+
19 
+
20 #define __STDC_LIMIT_MACROS
+
21 #include <stdint.h>
+
22 #ifndef UNIT_TEST
+
23 #include <Arduino.h>
+
24 #endif
+
25 #include "IRremoteESP8266.h"
+
26 #include "IRsend.h"
+
27 #ifdef UNIT_TEST
+
28 #include "IRsend_test.h"
+
29 #endif
+
30 
+
31 // Constants
+
32 
+
33 const uint8_t kGreeAuto = 0;
+
34 const uint8_t kGreeCool = 1;
+
35 const uint8_t kGreeDry = 2;
+
36 const uint8_t kGreeFan = 3;
+
37 const uint8_t kGreeHeat = 4;
+
38 
+
39 // Byte[0]
+
40 const uint8_t kGreePower1Offset = 3;
+
41 const uint8_t kGreeFanOffset = 4;
+
42 const uint8_t kGreeFanSize = 2; // Bits
+
43 const uint8_t kGreeFanAuto = 0;
+
44 const uint8_t kGreeFanMin = 1;
+
45 const uint8_t kGreeFanMed = 2;
+
46 const uint8_t kGreeFanMax = 3;
+
47 const uint8_t kGreeSwingAutoOffset = 6;
+
48 const uint8_t kGreeSleepOffset = 7;
+
49 // Byte[1]
+
50 const uint8_t kGreeTempOffset = 0;
+
51 const uint8_t kGreeTempSize = 4; // Mask 0b0000xxxx
+
52 const uint8_t kGreeMinTempC = 16; // Celsius
+
53 const uint8_t kGreeMaxTempC = 30; // Celsius
+
54 const uint8_t kGreeMinTempF = 61; // Fahrenheit
+
55 const uint8_t kGreeMaxTempF = 86; // Fahrenheit
+
56 const uint8_t kGreeTimerHalfHrOffset = 4; // Mask 0b000x0000
+
57 const uint8_t kGreeTimerTensHrOffset = 5;
+
58 const uint8_t kGreeTimerTensHrSize = 2; // Mask 0b0xx00000
+
59 const uint16_t kGreeTimerMax = 24 * 60;
+
60 const uint8_t kGreeTimerEnabledOffset = 7; // Mask 0bx0000000
+
61 // Byte[2]
+
62 const uint8_t kGreeTimerHoursOffset = 0;
+
63 const uint8_t kGreeTimerHoursSize = 4; // Bits
+
64 const uint8_t kGreeTurboOffset = 4;
+
65 const uint8_t kGreeLightOffset = 5;
+
66 // This might not be used. See #814
+
67 const uint8_t kGreePower2Offset = 6;
+
68 const uint8_t kGreeXfanOffset = 7;
+
69 // Byte[3]
+
70 const uint8_t kGreeTempExtraDegreeFOffset = 2; // Mask 0b00000x00
+
71 const uint8_t kGreeUseFahrenheitOffset = 3; // Mask 0b0000x000
+
72 // Byte[4]
+
73 const uint8_t kGreeSwingSize = 4; // Bits
+
74 const uint8_t kGreeSwingLastPos = 0b0000;
+
75 const uint8_t kGreeSwingAuto = 0b0001;
+
76 const uint8_t kGreeSwingUp = 0b0010;
+
77 const uint8_t kGreeSwingMiddleUp = 0b0011;
+
78 const uint8_t kGreeSwingMiddle = 0b0100;
+
79 const uint8_t kGreeSwingMiddleDown = 0b0101;
+
80 const uint8_t kGreeSwingDown = 0b0110;
+
81 const uint8_t kGreeSwingDownAuto = 0b0111;
+
82 const uint8_t kGreeSwingMiddleAuto = 0b1001;
+
83 const uint8_t kGreeSwingUpAuto = 0b1011;
+
84 // Byte[5]
+
85 const uint8_t kGreeWiFiOffset = 6; // Mask 0b0x000000
+
86 const uint8_t kGreeIFeelOffset = 2; // Mask 0b00000x00
+
87 const uint8_t kGreeDisplayTempOffset = 0;
+
88 const uint8_t kGreeDisplayTempSize = 2; // Mask 0b000000xx
+
89 const uint8_t kGreeDisplayTempOff = 0b00; // 0
+
90 const uint8_t kGreeDisplayTempSet = 0b01; // 1
+
91 const uint8_t kGreeDisplayTempInside = 0b10; // 2
+
92 const uint8_t kGreeDisplayTempOutside = 0b11; // 3
+
93 
+
94 
+
95 // Legacy defines.
+
96 #define GREE_AUTO kGreeAuto
+
97 #define GREE_COOL kGreeCool
+
98 #define GREE_DRY kGreeDry
+
99 #define GREE_FAN kGreeFan
+
100 #define GREE_HEAT kGreeHeat
+
101 #define GREE_MIN_TEMP kGreeMinTempC
+
102 #define GREE_MAX_TEMP kGreeMaxTempC
+
103 #define GREE_FAN_MAX kGreeFanMax
+
104 #define GREE_SWING_LAST_POS kGreeSwingLastPos
+
105 #define GREE_SWING_AUTO kGreeSwingAuto
+
106 #define GREE_SWING_UP kGreeSwingUp
+
107 #define GREE_SWING_MIDDLE_UP kGreeSwingMiddleUp
+
108 #define GREE_SWING_MIDDLE kGreeSwingMiddle
+
109 #define GREE_SWING_MIDDLE_DOWN kGreeSwingMiddleDown
+
110 #define GREE_SWING_DOWN kGreeSwingDown
+
111 #define GREE_SWING_DOWN_AUTO kGreeSwingDownAuto
+
112 #define GREE_SWING_MIDDLE_AUTO kGreeSwingMiddleAuto
+
113 #define GREE_SWING_UP_AUTO kGreeSwingUpAuto
+
114 
+
115 // Classes
+
117 class IRGreeAC {
+
118  public:
+
119  explicit IRGreeAC(
+
120  const uint16_t pin,
+ +
122  const bool inverted = false, const bool use_modulation = true);
+
123  void stateReset(void);
+
124 #if SEND_GREE
+
125  void send(const uint16_t repeat = kGreeDefaultRepeat);
+
130  int8_t calibrate(void) { return _irsend.calibrate(); }
+
131 #endif // SEND_GREE
+
132  void begin(void);
+
133  void on(void);
+
134  void off(void);
+
135  void setModel(const gree_ac_remote_model_t model);
+ +
137  void setPower(const bool on);
+
138  bool getPower(void);
+
139  void setTemp(const uint8_t temp, const bool fahrenheit = false);
+
140  uint8_t getTemp(void);
+
141  void setUseFahrenheit(const bool on);
+
142  bool getUseFahrenheit(void);
+
143  void setFan(const uint8_t speed);
+
144  uint8_t getFan(void);
+
145  void setMode(const uint8_t new_mode);
+
146  uint8_t getMode(void);
+
147  void setLight(const bool on);
+
148  bool getLight(void);
+
149  void setXFan(const bool on);
+
150  bool getXFan(void);
+
151  void setSleep(const bool on);
+
152  bool getSleep(void);
+
153  void setTurbo(const bool on);
+
154  bool getTurbo(void);
+
155  void setIFeel(const bool on);
+
156  bool getIFeel(void);
+
157  void setWiFi(const bool on);
+
158  bool getWiFi(void);
+
159  void setSwingVertical(const bool automatic, const uint8_t position);
+
160  bool getSwingVerticalAuto(void);
+
161  uint8_t getSwingVerticalPosition(void);
+
162  uint16_t getTimer(void);
+
163  void setTimer(const uint16_t minutes);
+
164  void setDisplayTempSource(const uint8_t mode);
+
165  uint8_t getDisplayTempSource(void);
+
166  uint8_t convertMode(const stdAc::opmode_t mode);
+
167  uint8_t convertFan(const stdAc::fanspeed_t speed);
+
168  uint8_t convertSwingV(const stdAc::swingv_t swingv);
+
169  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
170  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
171  static stdAc::swingv_t toCommonSwingV(const uint8_t pos);
+
172  stdAc::state_t toCommon(void);
+
173  uint8_t* getRaw(void);
+
174  void setRaw(const uint8_t new_code[]);
+
175  static bool validChecksum(const uint8_t state[],
+
176  const uint16_t length = kGreeStateLength);
+
177  String toString(void);
+
178 #ifndef UNIT_TEST
+
179 
+
180  private:
+ +
182 #else // UNIT_TEST
+
183  IRsendTest _irsend;
+
185 #endif // UNIT_TEST
+ + +
189  void checksum(const uint16_t length = kGreeStateLength);
+
190  void fixup(void);
+
191  void setTimerEnabled(const bool on);
+
192  bool getTimerEnabled(void);
+
193 };
+
194 
+
195 #endif // IR_GREE_H_
+
+
void setSwingVertical(const bool automatic, const uint8_t position)
Set the Vertical Swing mode of the A/C.
Definition: ir_Gree.cpp:395
+
const uint8_t kGreeTimerTensHrSize
Definition: ir_Gree.h:58
+
const uint16_t kGreeStateLength
Definition: IRremoteESP8266.h:883
+
uint8_t getTemp(void)
Get the set temperature.
Definition: ir_Gree.cpp:269
+
const uint8_t kGreeIFeelOffset
Definition: ir_Gree.h:86
+
const uint8_t kGreeXfanOffset
Definition: ir_Gree.h:68
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Gree.cpp:220
+
const uint8_t kGreeSwingUp
Definition: ir_Gree.h:76
+
swingv_t
Common A/C settings for Vertical Swing.
Definition: IRsend.h:70
+
static bool validChecksum(const uint8_t state[], const uint16_t length=kGreeStateLength)
Verify the checksum is valid for a given state.
Definition: ir_Gree.cpp:181
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Gree.cpp:609
+
const uint8_t kGreeFanSize
Definition: ir_Gree.h:42
+
void off(void)
Change the power setting to Off.
Definition: ir_Gree.cpp:205
+
uint16_t getTimer(void)
Get the timer time value from the A/C.
Definition: ir_Gree.cpp:449
+
const uint8_t kGreeFan
Definition: ir_Gree.h:36
+
void setXFan(const bool on)
Set the XFan (Mould) setting of the A/C.
Definition: ir_Gree.cpp:358
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Gree.cpp:542
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Gree.cpp:501
+
const uint8_t kGreeDry
Definition: ir_Gree.h:35
+
const uint8_t kGreeFanMax
Definition: ir_Gree.h:46
+
const uint8_t kGreeSleepOffset
Definition: ir_Gree.h:48
+
const uint8_t kGreeMaxTempF
Definition: ir_Gree.h:55
+
void setMode(const uint8_t new_mode)
Set the operating mode of the A/C.
Definition: ir_Gree.cpp:298
+
gree_ac_remote_model_t getModel(void)
Get/Detect the model of the A/C.
Definition: ir_Gree.cpp:199
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Gree.cpp:580
+
gree_ac_remote_model_t
Gree A/C model numbers.
Definition: IRsend.h:129
+
void send(const uint16_t repeat=kGreeDefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Gree.cpp:143
+
const uint8_t kGreeSwingUpAuto
Definition: ir_Gree.h:83
+
const uint8_t kGreeDisplayTempOutside
Definition: ir_Gree.h:92
+
void fixup(void)
Fix up the internal state so it is correct.
Definition: ir_Gree.cpp:132
+
const uint8_t kGreeSwingDownAuto
Definition: ir_Gree.h:81
+
const uint8_t kGreeSwingSize
Definition: ir_Gree.h:73
+ +
void setPower(const bool on)
Change the power setting.
Definition: ir_Gree.cpp:210
+
bool getUseFahrenheit(void)
Get the default temperature units in use.
Definition: ir_Gree.cpp:234
+
const uint8_t kGreeTimerTensHrOffset
Definition: ir_Gree.h:57
+
void setTimerEnabled(const bool on)
Set the timer enable setting of the A/C.
Definition: ir_Gree.cpp:437
+
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_Gree.cpp:151
+
bool getSwingVerticalAuto(void)
Get the Vertical Swing Automatic mode setting of the A/C.
Definition: ir_Gree.cpp:425
+
bool getLight(void)
Get the Light (LED) setting of the A/C.
Definition: ir_Gree.cpp:328
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
const uint8_t kGreeSwingAutoOffset
Definition: ir_Gree.h:47
+
std::string String
Definition: IRremoteESP8266.h:1093
+
const uint8_t kGreeDisplayTempSet
Definition: ir_Gree.h:90
+
const uint8_t kGreeTempOffset
Definition: ir_Gree.h:50
+
const uint8_t kGreeSwingMiddleDown
Definition: ir_Gree.h:79
+
IRGreeAC(const uint16_t pin, const gree_ac_remote_model_t model=gree_ac_remote_model_t::YAW1F, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Gree.cpp:112
+
const uint8_t kGreeFanMed
Definition: ir_Gree.h:45
+
bool getSleep(void)
Get the Sleep setting of the A/C.
Definition: ir_Gree.cpp:376
+ +
const uint8_t kGreeSwingMiddleAuto
Definition: ir_Gree.h:82
+
uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Gree.cpp:514
+
const uint8_t kGreeHeat
Definition: ir_Gree.h:37
+
void setSleep(const bool on)
Set the Sleep setting of the A/C.
Definition: ir_Gree.cpp:370
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Gree.cpp:138
+
const uint16_t kGreeTimerMax
Definition: ir_Gree.h:59
+
@ YAW1F
Definition: IRsend.h:130
+
const uint8_t kGreeMaxTempC
Definition: ir_Gree.h:53
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Gree.h:130
+
uint8_t getSwingVerticalPosition(void)
Get the Vertical Swing position setting of the A/C.
Definition: ir_Gree.cpp:431
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Gree.cpp:292
+
const uint8_t kGreeMinTempF
Definition: ir_Gree.h:54
+
const uint8_t kGreeTurboOffset
Definition: ir_Gree.h:64
+
const uint8_t kGreeDisplayTempOff
Definition: ir_Gree.h:89
+
void setFan(const uint8_t speed)
Set the speed of the fan.
Definition: ir_Gree.cpp:283
+
void setUseFahrenheit(const bool on)
Set the default temperature units to use.
Definition: ir_Gree.cpp:228
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Gree.cpp:555
+
const uint8_t kGreeTimerHoursOffset
Definition: ir_Gree.h:62
+
const uint8_t kGreePower1Offset
Definition: ir_Gree.h:40
+
const uint8_t kGreeTimerHalfHrOffset
Definition: ir_Gree.h:56
+
bool getIFeel(void)
Get the IFeel setting of the A/C.
Definition: ir_Gree.cpp:340
+
const uint8_t kGreeTimerHoursSize
Definition: ir_Gree.h:63
+
void checksum(const uint16_t length=kGreeStateLength)
Calculate and set the checksum values for the internal state.
Definition: ir_Gree.cpp:171
+
bool getTimerEnabled(void)
Get the timer enabled setting of the A/C.
Definition: ir_Gree.cpp:443
+
const uint8_t kGreeDisplayTempSize
Definition: ir_Gree.h:88
+
void setTimer(const uint16_t minutes)
Set the A/C's timer to turn off in X many minutes.
Definition: ir_Gree.cpp:461
+
void setModel(const gree_ac_remote_model_t model)
Set the model of the A/C to emulate.
Definition: ir_Gree.cpp:189
+
bool getTurbo(void)
Get the Turbo setting of the A/C.
Definition: ir_Gree.cpp:388
+
const uint8_t kGreeFanOffset
Definition: ir_Gree.h:41
+
const uint8_t kGreeAuto
Definition: ir_Gree.h:33
+
void setWiFi(const bool on)
Set the Wifi (enabled) setting of the A/C.
Definition: ir_Gree.cpp:346
+
uint8_t convertSwingV(const stdAc::swingv_t swingv)
Convert a stdAc::swingv_t enum into it's native setting.
Definition: ir_Gree.cpp:528
+
void setIFeel(const bool on)
Set the IFeel setting of the A/C.
Definition: ir_Gree.cpp:334
+
const uint8_t kGreeSwingMiddleUp
Definition: ir_Gree.h:77
+
uint8_t remote_state[kGreeStateLength]
The state in native IR code form.
Definition: ir_Gree.h:187
+
uint8_t getDisplayTempSource(void)
Get the temperature display mode. i.e. Internal, External temperature sensing.
Definition: ir_Gree.cpp:493
+
const uint8_t kGreeFanMin
Definition: ir_Gree.h:44
+
const uint8_t kGreeCool
Definition: ir_Gree.h:34
+
const uint8_t kGreeSwingMiddle
Definition: ir_Gree.h:78
+
bool getXFan(void)
Get the XFan (Mould) setting of the A/C.
Definition: ir_Gree.cpp:364
+
const uint8_t kGreeSwingLastPos
Definition: ir_Gree.h:74
+
void setTemp(const uint8_t temp, const bool fahrenheit=false)
Set the temp. in degrees.
Definition: ir_Gree.cpp:244
+
gree_ac_remote_model_t _model
Definition: ir_Gree.h:188
+
const uint8_t kGreeWiFiOffset
Definition: ir_Gree.h:85
+
const uint8_t kGreeTimerEnabledOffset
Definition: ir_Gree.h:60
+
void setTurbo(const bool on)
Set the Turbo setting of the A/C.
Definition: ir_Gree.cpp:382
+
const uint8_t kGreeSwingDown
Definition: ir_Gree.h:80
+
static stdAc::swingv_t toCommonSwingV(const uint8_t pos)
Convert a stdAc::swingv_t enum into it's native setting.
Definition: ir_Gree.cpp:567
+
const uint8_t kGreeFanAuto
Definition: ir_Gree.h:43
+
const uint8_t kGreeUseFahrenheitOffset
Definition: ir_Gree.h:71
+
const uint8_t kGreeMinTempC
Definition: ir_Gree.h:52
+
const uint8_t kGreeTempSize
Definition: ir_Gree.h:51
+
void setDisplayTempSource(const uint8_t mode)
Set temperature display mode. i.e. Internal, External temperature sensing.
Definition: ir_Gree.cpp:486
+
const uint8_t kGreeSwingAuto
Definition: ir_Gree.h:75
+
Class for handling detailed Gree A/C messages.
Definition: ir_Gree.h:117
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Gree.cpp:316
+
const uint8_t kGreeTempExtraDegreeFOffset
Definition: ir_Gree.h:70
+
const uint8_t kGreeDisplayTempInside
Definition: ir_Gree.h:91
+
void stateReset(void)
Reset the internal state to a fixed known good state.
Definition: ir_Gree.cpp:120
+
const uint8_t kGreePower2Offset
Definition: ir_Gree.h:67
+
const uint8_t kGreeLightOffset
Definition: ir_Gree.h:65
+
bool getWiFi(void)
Get the Wifi (enabled) setting of the A/C.
Definition: ir_Gree.cpp:352
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
void setRaw(const uint8_t new_code[])
Set the internal state from a valid code for this protocol.
Definition: ir_Gree.cpp:158
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Gree.h:181
+
const uint8_t kGreeDisplayTempOffset
Definition: ir_Gree.h:87
+
void on(void)
Change the power setting to On.
Definition: ir_Gree.cpp:202
+
void setLight(const bool on)
Set the Light (LED) setting of the A/C.
Definition: ir_Gree.cpp:322
+
const uint16_t kGreeDefaultRepeat
Definition: IRremoteESP8266.h:885
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Haier_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Haier_8cpp.html new file mode 100644 index 000000000..dd738e178 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Haier_8cpp.html @@ -0,0 +1,199 @@ + + + + + + + +IRremoteESP8266: src/ir_Haier.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Haier.cpp File Reference
+
+
+ +

Support for Haier A/C protocols. The specifics of reverse engineering the protocols details: +More...

+ + + + + + + + + + + + + + +

+Variables

const uint16_t kHaierAcHdr = 3000
 
const uint16_t kHaierAcHdrGap = 4300
 
const uint16_t kHaierAcBitMark = 520
 
const uint16_t kHaierAcOneSpace = 1650
 
const uint16_t kHaierAcZeroSpace = 650
 
const uint32_t kHaierAcMinGap = 150000
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kHaierAcBitMark

+ +
+
+ + + + +
const uint16_t kHaierAcBitMark = 520
+
+ +
+
+ +

◆ kHaierAcHdr

+ +
+
+ + + + +
const uint16_t kHaierAcHdr = 3000
+
+ +
+
+ +

◆ kHaierAcHdrGap

+ +
+
+ + + + +
const uint16_t kHaierAcHdrGap = 4300
+
+ +
+
+ +

◆ kHaierAcMinGap

+ +
+
+ + + + +
const uint32_t kHaierAcMinGap = 150000
+
+ +
+
+ +

◆ kHaierAcOneSpace

+ +
+
+ + + + +
const uint16_t kHaierAcOneSpace = 1650
+
+ +
+
+ +

◆ kHaierAcZeroSpace

+ +
+
+ + + + +
const uint16_t kHaierAcZeroSpace = 650
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Haier_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Haier_8h.html new file mode 100644 index 000000000..c13ae8eee --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Haier_8h.html @@ -0,0 +1,1363 @@ + + + + + + + +IRremoteESP8266: src/ir_Haier.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Haier.h File Reference
+
+
+ +

Support for Haier A/C protocols. The specifics of reverse engineering the protocols details: +More...

+ +

Go to the source code of this file.

+ + + + + + + + +

+Classes

class  IRHaierAC
 Class for handling detailed Haier A/C messages. More...
 
class  IRHaierACYRW02
 Class for handling detailed Haier ACYRW02 A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kHaierAcPrefix = 0b10100101
 
const uint8_t kHaierAcMinTemp = 16
 
const uint8_t kHaierAcDefTemp = 25
 
const uint8_t kHaierAcMaxTemp = 30
 
const uint8_t kHaierAcCmdOff = 0b0000
 
const uint8_t kHaierAcCmdOn = 0b0001
 
const uint8_t kHaierAcCmdMode = 0b0010
 
const uint8_t kHaierAcCmdFan = 0b0011
 
const uint8_t kHaierAcCmdTempUp = 0b0110
 
const uint8_t kHaierAcCmdTempDown = 0b0111
 
const uint8_t kHaierAcCmdSleep = 0b1000
 
const uint8_t kHaierAcCmdTimerSet = 0b1001
 
const uint8_t kHaierAcCmdTimerCancel = 0b1010
 
const uint8_t kHaierAcCmdHealth = 0b1100
 
const uint8_t kHaierAcCmdSwing = 0b1101
 
const uint8_t kHaierAcOffTimerOffset = 6
 
const uint8_t kHaierAcOnTimerOffset = 7
 
const uint8_t kHaierAcHealthBitOffset = 5
 
const uint8_t kHaierAcSwingOffset = 6
 
const uint8_t kHaierAcSwingSize = 2
 
const uint8_t kHaierAcSwingOff = 0b00
 
const uint8_t kHaierAcSwingUp = 0b01
 
const uint8_t kHaierAcSwingDown = 0b10
 
const uint8_t kHaierAcSwingChg = 0b11
 
const uint8_t kHaierAcModeOffset = 5
 
const uint8_t kHaierAcAuto = 0
 
const uint8_t kHaierAcCool = 1
 
const uint8_t kHaierAcDry = 2
 
const uint8_t kHaierAcHeat = 3
 
const uint8_t kHaierAcFan = 4
 
const uint8_t kHaierAcFanAuto = 0
 
const uint8_t kHaierAcFanLow = 1
 
const uint8_t kHaierAcFanMed = 2
 
const uint8_t kHaierAcFanHigh = 3
 
const uint8_t kHaierAcTimeOffset = 0
 
const uint8_t kHaierAcHoursSize = 5
 
const uint8_t kHaierAcMinsSize = 6
 
const uint16_t kHaierAcMaxTime = (23 * 60) + 59
 
const uint8_t kHaierAcSleepBitOffset = 6
 
const uint8_t kHaierAcSleepBit = 0b01000000
 
const uint8_t kHaierAcYrw02Prefix = 0xA6
 
const uint8_t kHaierAcYrw02SwingOff = 0x0
 
const uint8_t kHaierAcYrw02SwingTop = 0x1
 
const uint8_t kHaierAcYrw02SwingMiddle = 0x2
 
const uint8_t kHaierAcYrw02SwingBottom = 0x3
 
const uint8_t kHaierAcYrw02SwingDown = 0xA
 
const uint8_t kHaierAcYrw02SwingAuto = 0xC
 
const uint8_t kHaierAcYrw02HealthOffset = 1
 
const uint8_t kHaierAcYrw02PowerOffset = 6
 
const uint8_t kHaierAcYrw02Power = 0b01000000
 
const uint8_t kHaierAcYrw02FanOffset = 5
 
const uint8_t kHaierAcYrw02FanSize = 3
 
const uint8_t kHaierAcYrw02FanHigh = 0b001
 
const uint8_t kHaierAcYrw02FanMed = 0b010
 
const uint8_t kHaierAcYrw02FanLow = 0b011
 
const uint8_t kHaierAcYrw02FanAuto = 0b101
 
const uint8_t kHaierAcYrw02TurboOffset = 6
 
const uint8_t kHaierAcYrw02TurboSize = 2
 
const uint8_t kHaierAcYrw02TurboOff = 0x0
 
const uint8_t kHaierAcYrw02TurboHigh = 0x1
 
const uint8_t kHaierAcYrw02TurboLow = 0x2
 
const uint8_t kHaierAcYrw02ModeOffset = 5
 
const uint8_t kHaierAcYrw02Auto = 0b000
 
const uint8_t kHaierAcYrw02Cool = 0b001
 
const uint8_t kHaierAcYrw02Dry = 0b010
 
const uint8_t kHaierAcYrw02Heat = 0b100
 
const uint8_t kHaierAcYrw02Fan = 0b110
 
const uint8_t kHaierAcYrw02SleepOffset = 7
 
const uint8_t kHaierAcYrw02Sleep = 0b10000000
 
const uint8_t kHaierAcYrw02ButtonTempUp = 0x0
 
const uint8_t kHaierAcYrw02ButtonTempDown = 0x1
 
const uint8_t kHaierAcYrw02ButtonSwing = 0x2
 
const uint8_t kHaierAcYrw02ButtonFan = 0x4
 
const uint8_t kHaierAcYrw02ButtonPower = 0x5
 
const uint8_t kHaierAcYrw02ButtonMode = 0x6
 
const uint8_t kHaierAcYrw02ButtonHealth = 0x7
 
const uint8_t kHaierAcYrw02ButtonTurbo = 0x8
 
const uint8_t kHaierAcYrw02ButtonSleep = 0xB
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kHaierAcAuto

+ +
+
+ + + + +
const uint8_t kHaierAcAuto = 0
+
+ +
+
+ +

◆ kHaierAcCmdFan

+ +
+
+ + + + +
const uint8_t kHaierAcCmdFan = 0b0011
+
+ +
+
+ +

◆ kHaierAcCmdHealth

+ +
+
+ + + + +
const uint8_t kHaierAcCmdHealth = 0b1100
+
+ +
+
+ +

◆ kHaierAcCmdMode

+ +
+
+ + + + +
const uint8_t kHaierAcCmdMode = 0b0010
+
+ +
+
+ +

◆ kHaierAcCmdOff

+ +
+
+ + + + +
const uint8_t kHaierAcCmdOff = 0b0000
+
+ +
+
+ +

◆ kHaierAcCmdOn

+ +
+
+ + + + +
const uint8_t kHaierAcCmdOn = 0b0001
+
+ +
+
+ +

◆ kHaierAcCmdSleep

+ +
+
+ + + + +
const uint8_t kHaierAcCmdSleep = 0b1000
+
+ +
+
+ +

◆ kHaierAcCmdSwing

+ +
+
+ + + + +
const uint8_t kHaierAcCmdSwing = 0b1101
+
+ +
+
+ +

◆ kHaierAcCmdTempDown

+ +
+
+ + + + +
const uint8_t kHaierAcCmdTempDown = 0b0111
+
+ +
+
+ +

◆ kHaierAcCmdTempUp

+ +
+
+ + + + +
const uint8_t kHaierAcCmdTempUp = 0b0110
+
+ +
+
+ +

◆ kHaierAcCmdTimerCancel

+ +
+
+ + + + +
const uint8_t kHaierAcCmdTimerCancel = 0b1010
+
+ +
+
+ +

◆ kHaierAcCmdTimerSet

+ +
+
+ + + + +
const uint8_t kHaierAcCmdTimerSet = 0b1001
+
+ +
+
+ +

◆ kHaierAcCool

+ +
+
+ + + + +
const uint8_t kHaierAcCool = 1
+
+ +
+
+ +

◆ kHaierAcDefTemp

+ +
+
+ + + + +
const uint8_t kHaierAcDefTemp = 25
+
+ +
+
+ +

◆ kHaierAcDry

+ +
+
+ + + + +
const uint8_t kHaierAcDry = 2
+
+ +
+
+ +

◆ kHaierAcFan

+ +
+
+ + + + +
const uint8_t kHaierAcFan = 4
+
+ +
+
+ +

◆ kHaierAcFanAuto

+ +
+
+ + + + +
const uint8_t kHaierAcFanAuto = 0
+
+ +
+
+ +

◆ kHaierAcFanHigh

+ +
+
+ + + + +
const uint8_t kHaierAcFanHigh = 3
+
+ +
+
+ +

◆ kHaierAcFanLow

+ +
+
+ + + + +
const uint8_t kHaierAcFanLow = 1
+
+ +
+
+ +

◆ kHaierAcFanMed

+ +
+
+ + + + +
const uint8_t kHaierAcFanMed = 2
+
+ +
+
+ +

◆ kHaierAcHealthBitOffset

+ +
+
+ + + + +
const uint8_t kHaierAcHealthBitOffset = 5
+
+ +
+
+ +

◆ kHaierAcHeat

+ +
+
+ + + + +
const uint8_t kHaierAcHeat = 3
+
+ +
+
+ +

◆ kHaierAcHoursSize

+ +
+
+ + + + +
const uint8_t kHaierAcHoursSize = 5
+
+ +
+
+ +

◆ kHaierAcMaxTemp

+ +
+
+ + + + +
const uint8_t kHaierAcMaxTemp = 30
+
+ +
+
+ +

◆ kHaierAcMaxTime

+ +
+
+ + + + +
const uint16_t kHaierAcMaxTime = (23 * 60) + 59
+
+ +
+
+ +

◆ kHaierAcMinsSize

+ +
+
+ + + + +
const uint8_t kHaierAcMinsSize = 6
+
+ +
+
+ +

◆ kHaierAcMinTemp

+ +
+
+ + + + +
const uint8_t kHaierAcMinTemp = 16
+
+ +
+
+ +

◆ kHaierAcModeOffset

+ +
+
+ + + + +
const uint8_t kHaierAcModeOffset = 5
+
+ +
+
+ +

◆ kHaierAcOffTimerOffset

+ +
+
+ + + + +
const uint8_t kHaierAcOffTimerOffset = 6
+
+ +
+
+ +

◆ kHaierAcOnTimerOffset

+ +
+
+ + + + +
const uint8_t kHaierAcOnTimerOffset = 7
+
+ +
+
+ +

◆ kHaierAcPrefix

+ +
+
+ + + + +
const uint8_t kHaierAcPrefix = 0b10100101
+
+ +
+
+ +

◆ kHaierAcSleepBit

+ +
+
+ + + + +
const uint8_t kHaierAcSleepBit = 0b01000000
+
+ +
+
+ +

◆ kHaierAcSleepBitOffset

+ +
+
+ + + + +
const uint8_t kHaierAcSleepBitOffset = 6
+
+ +
+
+ +

◆ kHaierAcSwingChg

+ +
+
+ + + + +
const uint8_t kHaierAcSwingChg = 0b11
+
+ +
+
+ +

◆ kHaierAcSwingDown

+ +
+
+ + + + +
const uint8_t kHaierAcSwingDown = 0b10
+
+ +
+
+ +

◆ kHaierAcSwingOff

+ +
+
+ + + + +
const uint8_t kHaierAcSwingOff = 0b00
+
+ +
+
+ +

◆ kHaierAcSwingOffset

+ +
+
+ + + + +
const uint8_t kHaierAcSwingOffset = 6
+
+ +
+
+ +

◆ kHaierAcSwingSize

+ +
+
+ + + + +
const uint8_t kHaierAcSwingSize = 2
+
+ +
+
+ +

◆ kHaierAcSwingUp

+ +
+
+ + + + +
const uint8_t kHaierAcSwingUp = 0b01
+
+ +
+
+ +

◆ kHaierAcTimeOffset

+ +
+
+ + + + +
const uint8_t kHaierAcTimeOffset = 0
+
+ +
+
+ +

◆ kHaierAcYrw02Auto

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02Auto = 0b000
+
+ +
+
+ +

◆ kHaierAcYrw02ButtonFan

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02ButtonFan = 0x4
+
+ +
+
+ +

◆ kHaierAcYrw02ButtonHealth

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02ButtonHealth = 0x7
+
+ +
+
+ +

◆ kHaierAcYrw02ButtonMode

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02ButtonMode = 0x6
+
+ +
+
+ +

◆ kHaierAcYrw02ButtonPower

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02ButtonPower = 0x5
+
+ +
+
+ +

◆ kHaierAcYrw02ButtonSleep

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02ButtonSleep = 0xB
+
+ +
+
+ +

◆ kHaierAcYrw02ButtonSwing

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02ButtonSwing = 0x2
+
+ +
+
+ +

◆ kHaierAcYrw02ButtonTempDown

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02ButtonTempDown = 0x1
+
+ +
+
+ +

◆ kHaierAcYrw02ButtonTempUp

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02ButtonTempUp = 0x0
+
+ +
+
+ +

◆ kHaierAcYrw02ButtonTurbo

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02ButtonTurbo = 0x8
+
+ +
+
+ +

◆ kHaierAcYrw02Cool

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02Cool = 0b001
+
+ +
+
+ +

◆ kHaierAcYrw02Dry

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02Dry = 0b010
+
+ +
+
+ +

◆ kHaierAcYrw02Fan

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02Fan = 0b110
+
+ +
+
+ +

◆ kHaierAcYrw02FanAuto

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02FanAuto = 0b101
+
+ +
+
+ +

◆ kHaierAcYrw02FanHigh

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02FanHigh = 0b001
+
+ +
+
+ +

◆ kHaierAcYrw02FanLow

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02FanLow = 0b011
+
+ +
+
+ +

◆ kHaierAcYrw02FanMed

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02FanMed = 0b010
+
+ +
+
+ +

◆ kHaierAcYrw02FanOffset

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02FanOffset = 5
+
+ +
+
+ +

◆ kHaierAcYrw02FanSize

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02FanSize = 3
+
+ +
+
+ +

◆ kHaierAcYrw02HealthOffset

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02HealthOffset = 1
+
+ +
+
+ +

◆ kHaierAcYrw02Heat

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02Heat = 0b100
+
+ +
+
+ +

◆ kHaierAcYrw02ModeOffset

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02ModeOffset = 5
+
+ +
+
+ +

◆ kHaierAcYrw02Power

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02Power = 0b01000000
+
+ +
+
+ +

◆ kHaierAcYrw02PowerOffset

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02PowerOffset = 6
+
+ +
+
+ +

◆ kHaierAcYrw02Prefix

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02Prefix = 0xA6
+
+ +
+
+ +

◆ kHaierAcYrw02Sleep

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02Sleep = 0b10000000
+
+ +
+
+ +

◆ kHaierAcYrw02SleepOffset

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02SleepOffset = 7
+
+ +
+
+ +

◆ kHaierAcYrw02SwingAuto

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02SwingAuto = 0xC
+
+ +
+
+ +

◆ kHaierAcYrw02SwingBottom

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02SwingBottom = 0x3
+
+ +
+
+ +

◆ kHaierAcYrw02SwingDown

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02SwingDown = 0xA
+
+ +
+
+ +

◆ kHaierAcYrw02SwingMiddle

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02SwingMiddle = 0x2
+
+ +
+
+ +

◆ kHaierAcYrw02SwingOff

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02SwingOff = 0x0
+
+ +
+
+ +

◆ kHaierAcYrw02SwingTop

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02SwingTop = 0x1
+
+ +
+
+ +

◆ kHaierAcYrw02TurboHigh

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02TurboHigh = 0x1
+
+ +
+
+ +

◆ kHaierAcYrw02TurboLow

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02TurboLow = 0x2
+
+ +
+
+ +

◆ kHaierAcYrw02TurboOff

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02TurboOff = 0x0
+
+ +
+
+ +

◆ kHaierAcYrw02TurboOffset

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02TurboOffset = 6
+
+ +
+
+ +

◆ kHaierAcYrw02TurboSize

+ +
+
+ + + + +
const uint8_t kHaierAcYrw02TurboSize = 2
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Haier_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Haier_8h_source.html new file mode 100644 index 000000000..2869def4a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Haier_8h_source.html @@ -0,0 +1,587 @@ + + + + + + + +IRremoteESP8266: src/ir_Haier.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Haier.h
+
+
+Go to the documentation of this file.
1 // Copyright 2018 crankyoldgit
+
11 
+
12 // Supports:
+
13 // Brand: Haier, Model: HSU07-HEA03 remote (HAIER_AC)
+
14 // Brand: Haier, Model: YR-W02 remote (HAIER_AC_YRW02)
+
15 // Brand: Haier, Model: HSU-09HMC203 A/C (HAIER_AC_YRW02)
+
16 
+
17 #ifndef IR_HAIER_H_
+
18 #define IR_HAIER_H_
+
19 
+
20 #ifndef UNIT_TEST
+
21 #include <Arduino.h>
+
22 #endif
+
23 #include "IRremoteESP8266.h"
+
24 #include "IRsend.h"
+
25 #ifdef UNIT_TEST
+
26 #include "IRsend_test.h"
+
27 #endif
+
28 
+
29 // Constants
+
30 
+
31 // Haier HSU07-HEA03 remote
+
32 // Byte 0
+
33 const uint8_t kHaierAcPrefix = 0b10100101;
+
34 
+
35 // Byte 1
+
36 const uint8_t kHaierAcMinTemp = 16;
+
37 const uint8_t kHaierAcDefTemp = 25;
+
38 const uint8_t kHaierAcMaxTemp = 30;
+
39 const uint8_t kHaierAcCmdOff = 0b0000;
+
40 const uint8_t kHaierAcCmdOn = 0b0001;
+
41 const uint8_t kHaierAcCmdMode = 0b0010;
+
42 const uint8_t kHaierAcCmdFan = 0b0011;
+
43 const uint8_t kHaierAcCmdTempUp = 0b0110;
+
44 const uint8_t kHaierAcCmdTempDown = 0b0111;
+
45 const uint8_t kHaierAcCmdSleep = 0b1000;
+
46 const uint8_t kHaierAcCmdTimerSet = 0b1001;
+
47 const uint8_t kHaierAcCmdTimerCancel = 0b1010;
+
48 const uint8_t kHaierAcCmdHealth = 0b1100;
+
49 const uint8_t kHaierAcCmdSwing = 0b1101;
+
50 
+
51 // Byte 2 (Clock Hours)
+
52 
+
53 // Byte 3 (Timer Flags & Clock Minutes)
+
54 const uint8_t kHaierAcOffTimerOffset = 6;
+
55 const uint8_t kHaierAcOnTimerOffset = 7;
+
56 
+
57 // Byte 4 (Health & Off Time Hours)
+
58 const uint8_t kHaierAcHealthBitOffset = 5;
+
59 
+
60 // Byte 5 (Swing & Off Time Mins)
+
61 const uint8_t kHaierAcSwingOffset = 6;
+
62 const uint8_t kHaierAcSwingSize = 2; // Bits
+
63 const uint8_t kHaierAcSwingOff = 0b00;
+
64 const uint8_t kHaierAcSwingUp = 0b01;
+
65 const uint8_t kHaierAcSwingDown = 0b10;
+
66 const uint8_t kHaierAcSwingChg = 0b11;
+
67 
+
68 // Byte 6 (Mode & On Time Hours)
+
69 const uint8_t kHaierAcModeOffset = 5;
+
70 const uint8_t kHaierAcAuto = 0;
+
71 const uint8_t kHaierAcCool = 1;
+
72 const uint8_t kHaierAcDry = 2;
+
73 const uint8_t kHaierAcHeat = 3;
+
74 const uint8_t kHaierAcFan = 4;
+
75 
+
76 const uint8_t kHaierAcFanAuto = 0;
+
77 const uint8_t kHaierAcFanLow = 1;
+
78 const uint8_t kHaierAcFanMed = 2;
+
79 const uint8_t kHaierAcFanHigh = 3;
+
80 
+
81 // Byte 7 (On Time Minutes)
+
82 
+
83 // Time
+
84 const uint8_t kHaierAcTimeOffset = 0; // Bits
+
85 const uint8_t kHaierAcHoursSize = 5; // Bits
+
86 const uint8_t kHaierAcMinsSize = 6; // Bits
+
87 
+
88 const uint16_t kHaierAcMaxTime = (23 * 60) + 59;
+
89 
+
90 // Byte 7
+
91 const uint8_t kHaierAcSleepBitOffset = 6;
+
92 const uint8_t kHaierAcSleepBit = 0b01000000;
+
93 
+
94 // Legacy Haier AC defines.
+
95 #define HAIER_AC_MIN_TEMP kHaierAcMinTemp
+
96 #define HAIER_AC_DEF_TEMP kHaierAcDefTemp
+
97 #define HAIER_AC_MAX_TEMP kHaierAcMaxTemp
+
98 #define HAIER_AC_CMD_OFF kHaierAcCmdOff
+
99 #define HAIER_AC_CMD_ON kHaierAcCmdOn
+
100 #define HAIER_AC_CMD_MODE kHaierAcCmdMode
+
101 #define HAIER_AC_CMD_FAN kHaierAcCmdFan
+
102 #define HAIER_AC_CMD_TEMP_UP kHaierAcCmdTempUp
+
103 #define HAIER_AC_CMD_TEMP_DOWN kHaierAcCmdTempDown
+
104 #define HAIER_AC_CMD_SLEEP kHaierAcCmdSleep
+
105 #define HAIER_AC_CMD_TIMER_SET kHaierAcCmdTimerSet
+
106 #define HAIER_AC_CMD_TIMER_CANCEL kHaierAcCmdTimerCancel
+
107 #define HAIER_AC_CMD_HEALTH kHaierAcCmdHealth
+
108 #define HAIER_AC_CMD_SWING kHaierAcCmdSwing
+
109 #define HAIER_AC_SWING_OFF kHaierAcSwingOff
+
110 #define HAIER_AC_SWING_UP kHaierAcSwingUp
+
111 #define HAIER_AC_SWING_DOWN kHaierAcSwingDown
+
112 #define HAIER_AC_SWING_CHG kHaierAcSwingChg
+
113 #define HAIER_AC_AUTO kHaierAcAuto
+
114 #define HAIER_AC_COOL kHaierAcCool
+
115 #define HAIER_AC_DRY kHaierAcDry
+
116 #define HAIER_AC_HEAT kHaierAcHeat
+
117 #define HAIER_AC_FAN kHaierAcFan
+
118 #define HAIER_AC_FAN_AUTO kHaierAcFanAuto
+
119 #define HAIER_AC_FAN_LOW kHaierAcFanLow
+
120 #define HAIER_AC_FAN_MED kHaierAcFanMed
+
121 #define HAIER_AC_FAN_HIGH kHaierAcFanHigh
+
122 
+
123 // Haier YRW02 remote
+
124 // Byte 0
+
125 const uint8_t kHaierAcYrw02Prefix = 0xA6;
+
126 
+
127 // Byte 1
+
128 // High Nibble - Temperature
+
129 // 0x0 = 16DegC, ... 0xE = 30DegC
+
130 // Low Nibble - Swing
+
131 const uint8_t kHaierAcYrw02SwingOff = 0x0;
+
132 const uint8_t kHaierAcYrw02SwingTop = 0x1;
+
133 const uint8_t kHaierAcYrw02SwingMiddle = 0x2; // Not available in heat mode.
+
134 const uint8_t kHaierAcYrw02SwingBottom = 0x3; // Only available in heat mode.
+
135 const uint8_t kHaierAcYrw02SwingDown = 0xA;
+
136 const uint8_t kHaierAcYrw02SwingAuto = 0xC; // Airflow
+
137 
+
138 // Byte 3
+
139 const uint8_t kHaierAcYrw02HealthOffset = 1;
+
140 
+
141 // Byte 4
+
142 const uint8_t kHaierAcYrw02PowerOffset = 6;
+
143 const uint8_t kHaierAcYrw02Power = 0b01000000;
+
144 
+
145 // Byte 5
+
146 // Bits 0-3
+
147 const uint8_t kHaierAcYrw02FanOffset = 5;
+
148 const uint8_t kHaierAcYrw02FanSize = 3;
+
149 const uint8_t kHaierAcYrw02FanHigh = 0b001;
+
150 const uint8_t kHaierAcYrw02FanMed = 0b010;
+
151 const uint8_t kHaierAcYrw02FanLow = 0b011;
+
152 const uint8_t kHaierAcYrw02FanAuto = 0b101;
+
153 
+
154 // Byte 6
+
155 const uint8_t kHaierAcYrw02TurboOffset = 6;
+
156 const uint8_t kHaierAcYrw02TurboSize = 2;
+
157 const uint8_t kHaierAcYrw02TurboOff = 0x0;
+
158 const uint8_t kHaierAcYrw02TurboHigh = 0x1;
+
159 const uint8_t kHaierAcYrw02TurboLow = 0x2;
+
160 
+
161 // Byte 7
+
162 // Mode mask 0b11100000
+
163 const uint8_t kHaierAcYrw02ModeOffset = 5;
+
164 const uint8_t kHaierAcYrw02Auto = 0b000; // 0
+
165 const uint8_t kHaierAcYrw02Cool = 0b001; // 1
+
166 const uint8_t kHaierAcYrw02Dry = 0b010; // 2
+
167 const uint8_t kHaierAcYrw02Heat = 0b100; // 4
+
168 const uint8_t kHaierAcYrw02Fan = 0b110; // 5
+
169 
+
170 // Byte 8
+
171 const uint8_t kHaierAcYrw02SleepOffset = 7;
+
172 const uint8_t kHaierAcYrw02Sleep = 0b10000000;
+
173 
+
174 // Byte 12
+
175 // Bits 4-7
+
176 const uint8_t kHaierAcYrw02ButtonTempUp = 0x0;
+
177 const uint8_t kHaierAcYrw02ButtonTempDown = 0x1;
+
178 const uint8_t kHaierAcYrw02ButtonSwing = 0x2;
+
179 const uint8_t kHaierAcYrw02ButtonFan = 0x4;
+
180 const uint8_t kHaierAcYrw02ButtonPower = 0x5;
+
181 const uint8_t kHaierAcYrw02ButtonMode = 0x6;
+
182 const uint8_t kHaierAcYrw02ButtonHealth = 0x7;
+
183 const uint8_t kHaierAcYrw02ButtonTurbo = 0x8;
+
184 const uint8_t kHaierAcYrw02ButtonSleep = 0xB;
+
185 
+
186 // Legacy Haier YRW02 remote defines.
+
187 #define HAIER_AC_YRW02_SWING_OFF kHaierAcYrw02SwingOff
+
188 #define HAIER_AC_YRW02_SWING_TOP kHaierAcYrw02SwingTop
+
189 #define HAIER_AC_YRW02_SWING_MIDDLE kHaierAcYrw02SwingMiddle
+
190 #define HAIER_AC_YRW02_SWING_BOTTOM kHaierAcYrw02SwingBottom
+
191 #define HAIER_AC_YRW02_SWING_DOWN kHaierAcYrw02SwingDown
+
192 #define HAIER_AC_YRW02_SWING_AUTO kHaierAcYrw02SwingAuto
+
193 #define HAIER_AC_YRW02_FAN_HIGH kHaierAcYrw02FanHigh
+
194 #define HAIER_AC_YRW02_FAN_MED kHaierAcYrw02FanMed
+
195 #define HAIER_AC_YRW02_FAN_LOW kHaierAcYrw02FanLow
+
196 #define HAIER_AC_YRW02_FAN_AUTO kHaierAcYrw02FanAuto
+
197 #define HAIER_AC_YRW02_TURBO_OFF kHaierAcYrw02TurboOff
+
198 #define HAIER_AC_YRW02_TURBO_HIGH kHaierAcYrw02TurboHigh
+
199 #define HAIER_AC_YRW02_TURBO_LOW kHaierAcYrw02TurboLow
+
200 #define HAIER_AC_YRW02_AUTO kHaierAcYrw02Auto
+
201 #define HAIER_AC_YRW02_COOL kHaierAcYrw02Cool
+
202 #define HAIER_AC_YRW02_DRY kHaierAcYrw02Dry
+
203 #define HAIER_AC_YRW02_HEAT kHaierAcYrw02Heat
+
204 #define HAIER_AC_YRW02_FAN kHaierAcYrw02Fan
+
205 #define HAIER_AC_YRW02_BUTTON_TEMP_UP kHaierAcYrw02ButtonTempUp
+
206 #define HAIER_AC_YRW02_BUTTON_TEMP_DOWN kHaierAcYrw02ButtonTempDown
+
207 #define HAIER_AC_YRW02_BUTTON_SWING kHaierAcYrw02ButtonSwing
+
208 #define HAIER_AC_YRW02_BUTTON_FAN kHaierAcYrw02ButtonFan
+
209 #define HAIER_AC_YRW02_BUTTON_POWER kHaierAcYrw02ButtonPower
+
210 #define HAIER_AC_YRW02_BUTTON_MODE kHaierAcYrw02ButtonMode
+
211 #define HAIER_AC_YRW02_BUTTON_HEALTH kHaierAcYrw02ButtonHealth
+
212 #define HAIER_AC_YRW02_BUTTON_TURBO kHaierAcYrw02ButtonTurbo
+
213 #define HAIER_AC_YRW02_BUTTON_SLEEP kHaierAcYrw02ButtonSleep
+
214 
+
215 // Classes
+
217 class IRHaierAC {
+
218  public:
+
219  explicit IRHaierAC(const uint16_t pin, const bool inverted = false,
+
220  const bool use_modulation = true);
+
221 #if SEND_HAIER_AC
+
222  void send(const uint16_t repeat = kHaierAcDefaultRepeat);
+
227  int8_t calibrate(void) { return _irsend.calibrate(); }
+
228 #endif // SEND_HAIER_AC
+
229  void begin(void);
+
230 
+
231  void setCommand(const uint8_t command);
+
232  uint8_t getCommand(void);
+
233 
+
234  void setTemp(const uint8_t temp);
+
235  uint8_t getTemp(void);
+
236 
+
237  void setFan(const uint8_t speed);
+
238  uint8_t getFan(void);
+
239 
+
240  uint8_t getMode(void);
+
241  void setMode(const uint8_t mode);
+
242 
+
243  bool getSleep(void);
+
244  void setSleep(const bool on);
+
245  bool getHealth(void);
+
246  void setHealth(const bool on);
+
247 
+
248  int16_t getOnTimer(void);
+
249  void setOnTimer(const uint16_t mins);
+
250  int16_t getOffTimer(void);
+
251  void setOffTimer(const uint16_t mins);
+
252  void cancelTimers(void);
+
253 
+
254  uint16_t getCurrTime(void);
+
255  void setCurrTime(const uint16_t mins);
+
256 
+
257  uint8_t getSwing(void);
+
258  void setSwing(const uint8_t state);
+
259 
+
260  uint8_t* getRaw(void);
+
261  void setRaw(const uint8_t new_code[]);
+
262  static bool validChecksum(uint8_t state[],
+
263  const uint16_t length = kHaierACStateLength);
+
264  uint8_t convertMode(const stdAc::opmode_t mode);
+
265  uint8_t convertFan(const stdAc::fanspeed_t speed);
+
266  uint8_t convertSwingV(const stdAc::swingv_t position);
+
267  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
268  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
269  static stdAc::swingv_t toCommonSwingV(const uint8_t pos);
+
270  stdAc::state_t toCommon(void);
+
271  String toString(void);
+
272 #ifndef UNIT_TEST
+
273 
+
274  private:
+ +
276 #else // UNIT_TEST
+
277  IRsendTest _irsend;
+
279 #endif
+ +
282  void stateReset(void);
+
283  void checksum(void);
+
284  static uint16_t getTime(const uint8_t ptr[]);
+
285  static void setTime(uint8_t ptr[], const uint16_t nr_mins);
+
286 };
+
287 
+ +
290  public:
+
291  explicit IRHaierACYRW02(const uint16_t pin, const bool inverted = false,
+
292  const bool use_modulation = true);
+
293 #if SEND_HAIER_AC_YRW02
+
294  void send(const uint16_t repeat = kHaierAcYrw02DefaultRepeat);
+
299  int8_t calibrate(void) { return _irsend.calibrate(); }
+
300 #endif // SEND_HAIER_AC_YRW02
+
301  void begin(void);
+
302 
+
303  void setButton(const uint8_t button);
+
304  uint8_t getButton(void);
+
305 
+
306  void setTemp(const uint8_t temp);
+
307  uint8_t getTemp(void);
+
308 
+
309  void setFan(const uint8_t speed);
+
310  uint8_t getFan(void);
+
311 
+
312  uint8_t getMode(void);
+
313  void setMode(const uint8_t mode);
+
314 
+
315  bool getPower(void);
+
316  void setPower(const bool on);
+
317  void on(void);
+
318  void off(void);
+
319 
+
320  bool getSleep(void);
+
321  void setSleep(const bool on);
+
322  bool getHealth(void);
+
323  void setHealth(const bool on);
+
324 
+
325  uint8_t getTurbo(void);
+
326  void setTurbo(const uint8_t speed);
+
327 
+
328  uint8_t getSwing(void);
+
329  void setSwing(const uint8_t pos);
+
330 
+
331  uint8_t* getRaw(void);
+
332  void setRaw(const uint8_t new_code[]);
+
333  static bool validChecksum(uint8_t state[],
+
334  const uint16_t length = kHaierACYRW02StateLength);
+
335  uint8_t convertMode(const stdAc::opmode_t mode);
+
336  uint8_t convertFan(const stdAc::fanspeed_t speed);
+
337  uint8_t convertSwingV(const stdAc::swingv_t position);
+
338  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
339  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
340  static stdAc::swingv_t toCommonSwingV(const uint8_t pos);
+
341  stdAc::state_t toCommon(void);
+
342  String toString(void);
+
343 #ifndef UNIT_TEST
+
344 
+
345  private:
+ +
347 #else // UNIT_TEST
+
348  IRsendTest _irsend;
+
350 #endif // UNIT_TEST
+ +
353  void stateReset(void);
+
354  void checksum(void);
+
355 };
+
356 #endif // IR_HAIER_H_
+
+
const uint8_t kHaierAcCmdFan
Definition: ir_Haier.h:42
+
const uint8_t kHaierAcFanHigh
Definition: ir_Haier.h:79
+
bool getHealth(void)
Get the Health (filter) setting of the A/C.
Definition: ir_Haier.cpp:674
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Haier.cpp:543
+
static void setTime(uint8_t ptr[], const uint16_t nr_mins)
Set the Time value at the given pointer.
Definition: ir_Haier.cpp:286
+
const uint16_t kHaierAcYrw02DefaultRepeat
Definition: IRremoteESP8266.h:891
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Haier.cpp:686
+
const uint8_t kHaierAcMinsSize
Definition: ir_Haier.h:86
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Haier.cpp:839
+
const uint8_t kHaierAcHealthBitOffset
Definition: ir_Haier.h:58
+
const uint8_t kHaierAcTimeOffset
Definition: ir_Haier.h:84
+
static uint16_t getTime(const uint8_t ptr[])
Get the Time value at the given pointer.
Definition: ir_Haier.cpp:254
+
const uint8_t kHaierAcYrw02ModeOffset
Definition: ir_Haier.h:163
+
const uint8_t kHaierAcYrw02Fan
Definition: ir_Haier.h:168
+
const uint16_t kHaierAcDefaultRepeat
Definition: IRremoteESP8266.h:888
+
const uint8_t kHaierAcYrw02FanMed
Definition: ir_Haier.h:150
+
const uint8_t kHaierAcSwingChg
Definition: ir_Haier.h:66
+
void setSwing(const uint8_t state)
Set the Vertical Swing mode of the A/C.
Definition: ir_Haier.cpp:329
+
const uint8_t kHaierAcAuto
Definition: ir_Haier.h:70
+
const uint8_t kHaierAcYrw02ButtonTurbo
Definition: ir_Haier.h:183
+
bool getHealth(void)
Get the Health (filter) setting of the A/C.
Definition: ir_Haier.cpp:235
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Haier.h:299
+
swingv_t
Common A/C settings for Vertical Swing.
Definition: IRsend.h:70
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Haier.h:346
+
const uint16_t kHaierACStateLength
Definition: IRremoteESP8266.h:886
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Haier.cpp:680
+
const uint8_t kHaierAcCmdTempDown
Definition: ir_Haier.h:44
+
void setRaw(const uint8_t new_code[])
Set the internal state from a valid code for this protocol.
Definition: ir_Haier.cpp:130
+
void stateReset(void)
Reset the internal state to a fixed known good state.
Definition: ir_Haier.cpp:108
+
const uint8_t kHaierAcCmdMode
Definition: ir_Haier.h:41
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
const uint8_t kHaierAcYrw02ButtonHealth
Definition: ir_Haier.h:182
+
void setFan(const uint8_t speed)
Set the speed of the fan.
Definition: ir_Haier.cpp:161
+
void on(void)
Change the power setting to On.
Definition: ir_Haier.cpp:692
+
const uint8_t kHaierAcCmdSleep
Definition: ir_Haier.h:45
+
uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Haier.cpp:358
+
const uint8_t kHaierAcYrw02PowerOffset
Definition: ir_Haier.h:142
+
const uint8_t kHaierAcYrw02TurboOffset
Definition: ir_Haier.h:155
+
int16_t getOffTimer(void)
Get the Off Timer value/setting of the A/C.
Definition: ir_Haier.cpp:271
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Haier.cpp:826
+
uint8_t remote_state[kHaierACYRW02StateLength]
The state in native form.
Definition: ir_Haier.h:352
+
const uint8_t kHaierAcYrw02Auto
Definition: ir_Haier.h:164
+
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_Haier.cpp:123
+
const uint8_t kHaierAcCmdSwing
Definition: ir_Haier.h:49
+
const uint8_t kHaierAcYrw02Prefix
Definition: ir_Haier.h:125
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Haier.cpp:450
+
const uint8_t kHaierAcYrw02TurboSize
Definition: ir_Haier.h:156
+
void setSleep(const bool on)
Set the Sleep setting of the A/C.
Definition: ir_Haier.cpp:241
+
const uint8_t kHaierAcYrw02SwingTop
Definition: ir_Haier.h:132
+ +
const uint8_t kHaierAcCmdTimerSet
Definition: ir_Haier.h:46
+
bool getSleep(void)
Get the Sleep setting of the A/C.
Definition: ir_Haier.cpp:699
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Haier.cpp:188
+
const uint8_t kHaierAcCmdTempUp
Definition: ir_Haier.h:43
+
void cancelTimers(void)
Cancel/disable the On & Off timers.
Definition: ir_Haier.cpp:310
+
void stateReset(void)
Reset the internal state to a fixed known good state.
Definition: ir_Haier.cpp:569
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
uint8_t getTurbo(void)
Get the Turbo setting of the A/C.
Definition: ir_Haier.cpp:712
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Haier.h:275
+
void setSwing(const uint8_t pos)
Set the Vertical Swing mode of the A/C.
Definition: ir_Haier.cpp:761
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Haier.cpp:345
+
uint8_t getSwing(void)
Get the Vertical Swing position setting of the A/C.
Definition: ir_Haier.cpp:755
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
const uint8_t kHaierAcFanLow
Definition: ir_Haier.h:77
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Haier.cpp:734
+
std::string String
Definition: IRremoteESP8266.h:1093
+
const uint8_t kHaierAcYrw02Sleep
Definition: ir_Haier.h:172
+
const uint8_t kHaierAcYrw02ButtonSleep
Definition: ir_Haier.h:184
+
const uint8_t kHaierAcPrefix
Definition: ir_Haier.h:33
+
const uint16_t kHaierACYRW02StateLength
Definition: IRremoteESP8266.h:889
+
void setOnTimer(const uint16_t mins)
Set & enable the On Timer.
Definition: ir_Haier.cpp:295
+
const uint8_t kHaierAcSwingOff
Definition: ir_Haier.h:63
+
const uint8_t kHaierAcSwingDown
Definition: ir_Haier.h:65
+ +
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Haier.cpp:637
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Haier.cpp:864
+
const uint8_t kHaierAcYrw02FanHigh
Definition: ir_Haier.h:149
+
const uint8_t kHaierAcFan
Definition: ir_Haier.h:74
+
const uint8_t kHaierAcYrw02FanLow
Definition: ir_Haier.h:151
+
const uint8_t kHaierAcYrw02SwingAuto
Definition: ir_Haier.h:136
+
const uint8_t kHaierAcCool
Definition: ir_Haier.h:71
+
const uint8_t kHaierAcDefTemp
Definition: ir_Haier.h:37
+
uint8_t remote_state[kHaierACStateLength]
The state in native code form.
Definition: ir_Haier.h:281
+
const uint8_t kHaierAcYrw02SwingOff
Definition: ir_Haier.h:131
+
uint8_t convertSwingV(const stdAc::swingv_t position)
Convert a stdAc::swingv_t enum into it's native setting.
Definition: ir_Haier.cpp:372
+
void setFan(const uint8_t speed)
Set the speed of the fan.
Definition: ir_Haier.cpp:741
+
const uint8_t kHaierAcOffTimerOffset
Definition: ir_Haier.h:54
+
void setHealth(const bool on)
Set the Health (filter) setting of the A/C.
Definition: ir_Haier.cpp:228
+
const uint8_t kHaierAcYrw02ButtonTempUp
Definition: ir_Haier.h:176
+
const uint8_t kHaierAcYrw02SleepOffset
Definition: ir_Haier.h:171
+
void off(void)
Change the power setting to Off.
Definition: ir_Haier.cpp:695
+
void setHealth(const bool on)
Set the Health (filter) setting of the A/C.
Definition: ir_Haier.cpp:667
+
const uint8_t kHaierAcMinTemp
Definition: ir_Haier.h:36
+
const uint8_t kHaierAcYrw02SwingDown
Definition: ir_Haier.h:135
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Haier.cpp:222
+
static bool validChecksum(uint8_t state[], const uint16_t length=kHaierACStateLength)
Verify the checksum is valid for a given state.
Definition: ir_Haier.cpp:102
+
void checksum(void)
Calculate and set the checksum values for the internal state.
Definition: ir_Haier.cpp:554
+
bool getSleep(void)
Get the Sleep setting of the A/C.
Definition: ir_Haier.cpp:248
+
const uint8_t kHaierAcCmdHealth
Definition: ir_Haier.h:48
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Haier.cpp:661
+
const uint8_t kHaierAcCmdOn
Definition: ir_Haier.h:40
+
const uint8_t kHaierAcYrw02SwingMiddle
Definition: ir_Haier.h:133
+
const uint8_t kHaierAcYrw02ButtonSwing
Definition: ir_Haier.h:178
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Haier.cpp:890
+
const uint8_t kHaierAcYrw02TurboLow
Definition: ir_Haier.h:159
+
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_Haier.cpp:585
+
const uint8_t kHaierAcFanMed
Definition: ir_Haier.h:78
+
void setSleep(const bool on)
Set the Sleep setting of the A/C.
Definition: ir_Haier.cpp:705
+
const uint8_t kHaierAcYrw02TurboOff
Definition: ir_Haier.h:157
+
uint8_t getButton(void)
Get the Button/Command setting of the A/C.
Definition: ir_Haier.cpp:615
+
const uint8_t kHaierAcYrw02ButtonTempDown
Definition: ir_Haier.h:177
+
Class for handling detailed Haier A/C messages.
Definition: ir_Haier.h:217
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Haier.cpp:643
+
const uint8_t kHaierAcYrw02FanOffset
Definition: ir_Haier.h:147
+
uint16_t getCurrTime(void)
Get the clock value of the A/C.
Definition: ir_Haier.cpp:281
+
const uint8_t kHaierAcSleepBitOffset
Definition: ir_Haier.h:91
+
void setOffTimer(const uint16_t mins)
Set & enable the Off Timer.
Definition: ir_Haier.cpp:303
+
const uint8_t kHaierAcYrw02FanAuto
Definition: ir_Haier.h:152
+
const uint8_t kHaierAcYrw02TurboHigh
Definition: ir_Haier.h:158
+
const uint8_t kHaierAcMaxTemp
Definition: ir_Haier.h:38
+
void send(const uint16_t repeat=kHaierAcYrw02DefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Haier.cpp:548
+
void setButton(const uint8_t button)
Set the Button/Command setting of the A/C.
Definition: ir_Haier.cpp:598
+
const uint8_t kHaierAcYrw02ButtonFan
Definition: ir_Haier.h:179
+
const uint8_t kHaierAcYrw02Cool
Definition: ir_Haier.h:165
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Haier.cpp:387
+
void setRaw(const uint8_t new_code[])
Set the internal state from a valid code for this protocol.
Definition: ir_Haier.cpp:592
+
const uint8_t kHaierAcYrw02HealthOffset
Definition: ir_Haier.h:139
+
const uint8_t kHaierAcYrw02SwingBottom
Definition: ir_Haier.h:134
+
const uint8_t kHaierAcFanAuto
Definition: ir_Haier.h:76
+
uint8_t convertSwingV(const stdAc::swingv_t position)
Convert a stdAc::swingv_t enum into it's native setting.
Definition: ir_Haier.cpp:811
+
uint8_t getCommand(void)
Get the Command/Button setting of the A/C.
Definition: ir_Haier.cpp:155
+
const uint8_t kHaierAcYrw02Power
Definition: ir_Haier.h:143
+
const uint8_t kHaierAcCmdOff
Definition: ir_Haier.h:39
+
IRHaierACYRW02(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Haier.cpp:538
+
const uint8_t kHaierAcYrw02Heat
Definition: ir_Haier.h:167
+
void checksum(void)
Calculate and set the checksum values for the internal state.
Definition: ir_Haier.cpp:94
+
void setCommand(const uint8_t command)
Set the Command/Button setting of the A/C.
Definition: ir_Haier.cpp:136
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Haier.h:227
+
const uint8_t kHaierAcSleepBit
Definition: ir_Haier.h:92
+
const uint8_t kHaierAcDry
Definition: ir_Haier.h:72
+
const uint8_t kHaierAcOnTimerOffset
Definition: ir_Haier.h:55
+
static bool validChecksum(uint8_t state[], const uint16_t length=kHaierACYRW02StateLength)
Verify the checksum is valid for a given state.
Definition: ir_Haier.cpp:563
+
const uint8_t kHaierAcSwingUp
Definition: ir_Haier.h:64
+
static stdAc::swingv_t toCommonSwingV(const uint8_t pos)
Convert a stdAc::swingv_t enum into it's native setting.
Definition: ir_Haier.cpp:412
+
const uint8_t kHaierAcYrw02ButtonMode
Definition: ir_Haier.h:181
+
const uint8_t kHaierAcHeat
Definition: ir_Haier.h:73
+
const uint8_t kHaierAcYrw02FanSize
Definition: ir_Haier.h:148
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Haier.cpp:198
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Haier.cpp:83
+
uint8_t getSwing(void)
Get the Vertical Swing position setting of the A/C.
Definition: ir_Haier.cpp:323
+
const uint16_t kHaierAcMaxTime
Definition: ir_Haier.h:88
+
void setCurrTime(const uint16_t mins)
Set the clock value for the A/C.
Definition: ir_Haier.cpp:317
+
static stdAc::swingv_t toCommonSwingV(const uint8_t pos)
Convert a stdAc::swingv_t enum into it's native setting.
Definition: ir_Haier.cpp:851
+
Class for handling detailed Haier ACYRW02 A/C messages.
Definition: ir_Haier.h:289
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Haier.cpp:177
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Haier.cpp:423
+
IRHaierAC(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Haier.cpp:78
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Haier.cpp:204
+
const uint8_t kHaierAcSwingOffset
Definition: ir_Haier.h:61
+
void setTurbo(const uint8_t speed)
Set the Turbo setting of the A/C.
Definition: ir_Haier.cpp:721
+
const uint8_t kHaierAcYrw02Dry
Definition: ir_Haier.h:166
+
const uint8_t kHaierAcModeOffset
Definition: ir_Haier.h:69
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Haier.cpp:784
+
const uint8_t kHaierAcHoursSize
Definition: ir_Haier.h:85
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Haier.cpp:400
+
const uint8_t kHaierAcYrw02ButtonPower
Definition: ir_Haier.h:180
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Haier.cpp:621
+
int16_t getOnTimer(void)
Get the On Timer value/setting of the A/C.
Definition: ir_Haier.cpp:261
+
const uint8_t kHaierAcSwingSize
Definition: ir_Haier.h:62
+
const uint8_t kHaierAcCmdTimerCancel
Definition: ir_Haier.h:47
+
uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Haier.cpp:797
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+
void send(const uint16_t repeat=kHaierAcDefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Haier.cpp:88
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Hitachi_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Hitachi_8cpp.html new file mode 100644 index 000000000..705884418 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Hitachi_8cpp.html @@ -0,0 +1,423 @@ + + + + + + + +IRremoteESP8266: src/ir_Hitachi.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Hitachi.cpp File Reference
+
+
+ +

Support for Hitachi A/C protocols. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kHitachiAcHdrMark = 3300
 
const uint16_t kHitachiAcHdrSpace = 1700
 
const uint16_t kHitachiAc1HdrMark = 3400
 
const uint16_t kHitachiAc1HdrSpace = 3400
 
const uint16_t kHitachiAcBitMark = 400
 
const uint16_t kHitachiAcOneSpace = 1250
 
const uint16_t kHitachiAcZeroSpace = 500
 
const uint32_t kHitachiAcMinGap = kDefaultMessageGap
 
const uint16_t kHitachiAc424LdrMark = 29784
 
const uint16_t kHitachiAc424LdrSpace = 49290
 
const uint16_t kHitachiAc424HdrMark = 3416
 
const uint16_t kHitachiAc424HdrSpace = 1604
 
const uint16_t kHitachiAc424BitMark = 463
 
const uint16_t kHitachiAc424OneSpace = 1208
 
const uint16_t kHitachiAc424ZeroSpace = 372
 
const uint16_t kHitachiAc3HdrMark = 3400
 
const uint16_t kHitachiAc3HdrSpace = 1660
 
const uint16_t kHitachiAc3BitMark = 460
 
const uint16_t kHitachiAc3OneSpace = 1250
 
const uint16_t kHitachiAc3ZeroSpace = 410
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kHitachiAc1HdrMark

+ +
+
+ + + + +
const uint16_t kHitachiAc1HdrMark = 3400
+
+ +
+
+ +

◆ kHitachiAc1HdrSpace

+ +
+
+ + + + +
const uint16_t kHitachiAc1HdrSpace = 3400
+
+ +
+
+ +

◆ kHitachiAc3BitMark

+ +
+
+ + + + +
const uint16_t kHitachiAc3BitMark = 460
+
+ +
+
+ +

◆ kHitachiAc3HdrMark

+ +
+
+ + + + +
const uint16_t kHitachiAc3HdrMark = 3400
+
+ +
+
+ +

◆ kHitachiAc3HdrSpace

+ +
+
+ + + + +
const uint16_t kHitachiAc3HdrSpace = 1660
+
+ +
+
+ +

◆ kHitachiAc3OneSpace

+ +
+
+ + + + +
const uint16_t kHitachiAc3OneSpace = 1250
+
+ +
+
+ +

◆ kHitachiAc3ZeroSpace

+ +
+
+ + + + +
const uint16_t kHitachiAc3ZeroSpace = 410
+
+ +
+
+ +

◆ kHitachiAc424BitMark

+ +
+
+ + + + +
const uint16_t kHitachiAc424BitMark = 463
+
+ +
+
+ +

◆ kHitachiAc424HdrMark

+ +
+
+ + + + +
const uint16_t kHitachiAc424HdrMark = 3416
+
+ +
+
+ +

◆ kHitachiAc424HdrSpace

+ +
+
+ + + + +
const uint16_t kHitachiAc424HdrSpace = 1604
+
+ +
+
+ +

◆ kHitachiAc424LdrMark

+ +
+
+ + + + +
const uint16_t kHitachiAc424LdrMark = 29784
+
+ +
+
+ +

◆ kHitachiAc424LdrSpace

+ +
+
+ + + + +
const uint16_t kHitachiAc424LdrSpace = 49290
+
+ +
+
+ +

◆ kHitachiAc424OneSpace

+ +
+
+ + + + +
const uint16_t kHitachiAc424OneSpace = 1208
+
+ +
+
+ +

◆ kHitachiAc424ZeroSpace

+ +
+
+ + + + +
const uint16_t kHitachiAc424ZeroSpace = 372
+
+ +
+
+ +

◆ kHitachiAcBitMark

+ +
+
+ + + + +
const uint16_t kHitachiAcBitMark = 400
+
+ +
+
+ +

◆ kHitachiAcHdrMark

+ +
+
+ + + + +
const uint16_t kHitachiAcHdrMark = 3300
+
+ +
+
+ +

◆ kHitachiAcHdrSpace

+ +
+
+ + + + +
const uint16_t kHitachiAcHdrSpace = 1700
+
+ +
+
+ +

◆ kHitachiAcMinGap

+ +
+
+ + + + +
const uint32_t kHitachiAcMinGap = kDefaultMessageGap
+
+ +
+
+ +

◆ kHitachiAcOneSpace

+ +
+
+ + + + +
const uint16_t kHitachiAcOneSpace = 1250
+
+ +
+
+ +

◆ kHitachiAcZeroSpace

+ +
+
+ + + + +
const uint16_t kHitachiAcZeroSpace = 500
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Hitachi_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Hitachi_8h.html new file mode 100644 index 000000000..062ecdd3d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Hitachi_8h.html @@ -0,0 +1,2028 @@ + + + + + + + +IRremoteESP8266: src/ir_Hitachi.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Hitachi.h File Reference
+
+
+ +

Support for Hitachi A/C protocols. +More...

+ +

Go to the source code of this file.

+ + + + + + + + + + + + + + + + + +

+Classes

class  IRHitachiAc
 Class for handling detailed Hitachi 224-bit A/C messages. More...
 
class  IRHitachiAc1
 Class for handling detailed Hitachi 104-bit A/C messages. More...
 
class  IRHitachiAc424
 Class for handling detailed Hitachi 53-byte/424-bit A/C messages. More...
 
class  IRHitachiAc3
 Class for handling detailed Hitachi 15to27-byte/120to216-bit A/C messages. More...
 
class  IRHitachiAc344
 Class for handling detailed Hitachi 344-bit A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kHitachiAcFreq = 38000
 
const uint8_t kHitachiAcAuto = 2
 
const uint8_t kHitachiAcHeat = 3
 
const uint8_t kHitachiAcCool = 4
 
const uint8_t kHitachiAcDry = 5
 
const uint8_t kHitachiAcFan = 0xC
 
const uint8_t kHitachiAcFanAuto = 1
 
const uint8_t kHitachiAcFanLow = 2
 
const uint8_t kHitachiAcFanMed = 3
 
const uint8_t kHitachiAcFanHigh = 5
 
const uint8_t kHitachiAcMinTemp = 16
 
const uint8_t kHitachiAcMaxTemp = 32
 
const uint8_t kHitachiAcAutoTemp = 23
 
const uint8_t kHitachiAcPowerOffset = 0
 
const uint8_t kHitachiAcSwingOffset = 7
 
const uint8_t kHitachiAc424ButtonByte = 11
 
const uint8_t kHitachiAc424ButtonPowerMode = 0x13
 
const uint8_t kHitachiAc424ButtonFan = 0x42
 
const uint8_t kHitachiAc424ButtonTempDown = 0x43
 
const uint8_t kHitachiAc424ButtonTempUp = 0x44
 
const uint8_t kHitachiAc424ButtonSwingV = 0x81
 
const uint8_t kHitachiAc424ButtonSwingH = 0x8C
 
const uint8_t kHitachiAc344ButtonPowerMode = kHitachiAc424ButtonPowerMode
 
const uint8_t kHitachiAc344ButtonFan = kHitachiAc424ButtonFan
 
const uint8_t kHitachiAc344ButtonTempDown = kHitachiAc424ButtonTempDown
 
const uint8_t kHitachiAc344ButtonTempUp = kHitachiAc424ButtonTempUp
 
const uint8_t kHitachiAc344ButtonSwingV = kHitachiAc424ButtonSwingV
 
const uint8_t kHitachiAc344ButtonSwingH = kHitachiAc424ButtonSwingH
 
const uint8_t kHitachiAc424TempByte = 13
 
const uint8_t kHitachiAc424TempOffset = 2
 
const uint8_t kHitachiAc424TempSize = 6
 
const uint8_t kHitachiAc424MinTemp = 16
 
const uint8_t kHitachiAc424MaxTemp = 32
 
const uint8_t kHitachiAc344MinTemp = kHitachiAc424MinTemp
 
const uint8_t kHitachiAc344MaxTemp = kHitachiAc424MaxTemp
 
const uint8_t kHitachiAc424FanTemp = 27
 
const uint8_t kHitachiAc424ModeByte = 25
 
const uint8_t kHitachiAc424Fan = 1
 
const uint8_t kHitachiAc424Cool = 3
 
const uint8_t kHitachiAc424Dry = 5
 
const uint8_t kHitachiAc424Heat = 6
 
const uint8_t kHitachiAc344Fan = kHitachiAc424Fan
 
const uint8_t kHitachiAc344Cool = kHitachiAc424Cool
 
const uint8_t kHitachiAc344Dry = kHitachiAc424Dry
 
const uint8_t kHitachiAc344Heat = kHitachiAc424Heat
 
const uint8_t kHitachiAc424FanByte = kHitachiAc424ModeByte
 
const uint8_t kHitachiAc424FanMin = 1
 
const uint8_t kHitachiAc424FanLow = 2
 
const uint8_t kHitachiAc424FanMedium = 3
 
const uint8_t kHitachiAc424FanHigh = 4
 
const uint8_t kHitachiAc424FanAuto = 5
 
const uint8_t kHitachiAc424FanMax = 6
 
const uint8_t kHitachiAc424FanMaxDry = 2
 
const uint8_t kHitachiAc344FanMin = kHitachiAc424FanMin
 
const uint8_t kHitachiAc344FanLow = kHitachiAc424FanLow
 
const uint8_t kHitachiAc344FanMedium = kHitachiAc424FanMedium
 
const uint8_t kHitachiAc344FanHigh = kHitachiAc424FanHigh
 
const uint8_t kHitachiAc344FanAuto = kHitachiAc424FanAuto
 
const uint8_t kHitachiAc344FanMax = kHitachiAc424FanMax
 
const uint8_t kHitachiAc424PowerByte = 27
 
const uint8_t kHitachiAc424PowerOn = 0xF1
 
const uint8_t kHitachiAc424PowerOff = 0xE1
 
const uint8_t kHitachiAc344SwingHByte = 35
 
const uint8_t kHitachiAc344SwingHOffset = 0
 
const uint8_t kHitachiAc344SwingHSize = 3
 
const uint8_t kHitachiAc344SwingHAuto = 0
 
const uint8_t kHitachiAc344SwingHRightMax = 1
 
const uint8_t kHitachiAc344SwingHRight = 2
 
const uint8_t kHitachiAc344SwingHMiddle = 3
 
const uint8_t kHitachiAc344SwingHLeft = 4
 
const uint8_t kHitachiAc344SwingHLeftMax = 5
 
const uint8_t kHitachiAc344SwingVByte = 37
 
const uint8_t kHitachiAc344SwingVOffset = 5
 
const uint8_t kHitachiAc1ModelByte = 3
 
const uint8_t kHitachiAc1ModelOffset = 6
 
const uint8_t kHitachiAc1Model_A = 0b10
 
const uint8_t kHitachiAc1Model_B = 0b01
 
const uint8_t kHitachiAc1ModelSize = 2
 
const uint8_t kHitachiAc1ModeByte = 5
 
const uint8_t kHitachiAc1ModeOffset = 4
 
const uint8_t kHitachiAc1ModeSize = 4
 
const uint8_t kHitachiAc1Dry = 0b0010
 
const uint8_t kHitachiAc1Fan = 0b0100
 
const uint8_t kHitachiAc1Cool = 0b0110
 
const uint8_t kHitachiAc1Heat = 0b1001
 
const uint8_t kHitachiAc1Auto = 0b1110
 
const uint8_t kHitachiAc1FanByte = kHitachiAc1ModeByte
 
const uint8_t kHitachiAc1FanOffset = 0
 
const uint8_t kHitachiAc1FanSize = 4
 
const uint8_t kHitachiAc1FanAuto = 1
 
const uint8_t kHitachiAc1FanHigh = 2
 
const uint8_t kHitachiAc1FanMed = 4
 
const uint8_t kHitachiAc1FanLow = 8
 
const uint8_t kHitachiAc1TempByte = 6
 
const uint8_t kHitachiAc1TempOffset = 2
 
const uint8_t kHitachiAc1TempSize = 5
 
const uint8_t kHitachiAc1TempDelta = 7
 
const uint8_t kHitachiAc1TempAuto = 25
 
const uint8_t kHitachiAc1TimerSize = 16
 
const uint8_t kHitachiAc1OffTimerLowByte = 7
 
const uint8_t kHitachiAc1OffTimerHighByte = 8
 
const uint8_t kHitachiAc1OnTimerLowByte = 9
 
const uint8_t kHitachiAc1OnTimerHighByte = 10
 
const uint8_t kHitachiAc1PowerByte = 11
 
const uint8_t kHitachiAc1PowerOffset = 5
 
const uint8_t kHitachiAc1PowerToggleOffset = 4
 
const uint8_t kHitachiAc1SwingByte = kHitachiAc1PowerByte
 
const uint8_t kHitachiAc1SwingHOffset = 7
 
const uint8_t kHitachiAc1SwingVOffset = 6
 
const uint8_t kHitachiAc1SwingToggleOffset = 0
 
const uint8_t kHitachiAc1SleepByte = kHitachiAc1PowerByte
 
const uint8_t kHitachiAc1SleepOffset = 1
 
const uint8_t kHitachiAc1SleepSize = 3
 
const uint8_t kHitachiAc1SleepOff = 0b000
 
const uint8_t kHitachiAc1Sleep1 = 0b001
 
const uint8_t kHitachiAc1Sleep2 = 0b010
 
const uint8_t kHitachiAc1Sleep3 = 0b011
 
const uint8_t kHitachiAc1Sleep4 = 0b100
 
const uint8_t kHitachiAc1ChecksumStartByte = 5
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kHitachiAc1Auto

+ +
+
+ + + + +
const uint8_t kHitachiAc1Auto = 0b1110
+
+ +
+
+ +

◆ kHitachiAc1ChecksumStartByte

+ +
+
+ + + + +
const uint8_t kHitachiAc1ChecksumStartByte = 5
+
+ +
+
+ +

◆ kHitachiAc1Cool

+ +
+
+ + + + +
const uint8_t kHitachiAc1Cool = 0b0110
+
+ +
+
+ +

◆ kHitachiAc1Dry

+ +
+
+ + + + +
const uint8_t kHitachiAc1Dry = 0b0010
+
+ +
+
+ +

◆ kHitachiAc1Fan

+ +
+
+ + + + +
const uint8_t kHitachiAc1Fan = 0b0100
+
+ +
+
+ +

◆ kHitachiAc1FanAuto

+ +
+
+ + + + +
const uint8_t kHitachiAc1FanAuto = 1
+
+ +
+
+ +

◆ kHitachiAc1FanByte

+ +
+
+ + + + +
const uint8_t kHitachiAc1FanByte = kHitachiAc1ModeByte
+
+ +
+
+ +

◆ kHitachiAc1FanHigh

+ +
+
+ + + + +
const uint8_t kHitachiAc1FanHigh = 2
+
+ +
+
+ +

◆ kHitachiAc1FanLow

+ +
+
+ + + + +
const uint8_t kHitachiAc1FanLow = 8
+
+ +
+
+ +

◆ kHitachiAc1FanMed

+ +
+
+ + + + +
const uint8_t kHitachiAc1FanMed = 4
+
+ +
+
+ +

◆ kHitachiAc1FanOffset

+ +
+
+ + + + +
const uint8_t kHitachiAc1FanOffset = 0
+
+ +
+
+ +

◆ kHitachiAc1FanSize

+ +
+
+ + + + +
const uint8_t kHitachiAc1FanSize = 4
+
+ +
+
+ +

◆ kHitachiAc1Heat

+ +
+
+ + + + +
const uint8_t kHitachiAc1Heat = 0b1001
+
+ +
+
+ +

◆ kHitachiAc1ModeByte

+ +
+
+ + + + +
const uint8_t kHitachiAc1ModeByte = 5
+
+ +
+
+ +

◆ kHitachiAc1Model_A

+ +
+
+ + + + +
const uint8_t kHitachiAc1Model_A = 0b10
+
+ +
+
+ +

◆ kHitachiAc1Model_B

+ +
+
+ + + + +
const uint8_t kHitachiAc1Model_B = 0b01
+
+ +
+
+ +

◆ kHitachiAc1ModelByte

+ +
+
+ + + + +
const uint8_t kHitachiAc1ModelByte = 3
+
+ +
+
+ +

◆ kHitachiAc1ModelOffset

+ +
+
+ + + + +
const uint8_t kHitachiAc1ModelOffset = 6
+
+ +
+
+ +

◆ kHitachiAc1ModelSize

+ +
+
+ + + + +
const uint8_t kHitachiAc1ModelSize = 2
+
+ +
+
+ +

◆ kHitachiAc1ModeOffset

+ +
+
+ + + + +
const uint8_t kHitachiAc1ModeOffset = 4
+
+ +
+
+ +

◆ kHitachiAc1ModeSize

+ +
+
+ + + + +
const uint8_t kHitachiAc1ModeSize = 4
+
+ +
+
+ +

◆ kHitachiAc1OffTimerHighByte

+ +
+
+ + + + +
const uint8_t kHitachiAc1OffTimerHighByte = 8
+
+ +
+
+ +

◆ kHitachiAc1OffTimerLowByte

+ +
+
+ + + + +
const uint8_t kHitachiAc1OffTimerLowByte = 7
+
+ +
+
+ +

◆ kHitachiAc1OnTimerHighByte

+ +
+
+ + + + +
const uint8_t kHitachiAc1OnTimerHighByte = 10
+
+ +
+
+ +

◆ kHitachiAc1OnTimerLowByte

+ +
+
+ + + + +
const uint8_t kHitachiAc1OnTimerLowByte = 9
+
+ +
+
+ +

◆ kHitachiAc1PowerByte

+ +
+
+ + + + +
const uint8_t kHitachiAc1PowerByte = 11
+
+ +
+
+ +

◆ kHitachiAc1PowerOffset

+ +
+
+ + + + +
const uint8_t kHitachiAc1PowerOffset = 5
+
+ +
+
+ +

◆ kHitachiAc1PowerToggleOffset

+ +
+
+ + + + +
const uint8_t kHitachiAc1PowerToggleOffset = 4
+
+ +
+
+ +

◆ kHitachiAc1Sleep1

+ +
+
+ + + + +
const uint8_t kHitachiAc1Sleep1 = 0b001
+
+ +
+
+ +

◆ kHitachiAc1Sleep2

+ +
+
+ + + + +
const uint8_t kHitachiAc1Sleep2 = 0b010
+
+ +
+
+ +

◆ kHitachiAc1Sleep3

+ +
+
+ + + + +
const uint8_t kHitachiAc1Sleep3 = 0b011
+
+ +
+
+ +

◆ kHitachiAc1Sleep4

+ +
+
+ + + + +
const uint8_t kHitachiAc1Sleep4 = 0b100
+
+ +
+
+ +

◆ kHitachiAc1SleepByte

+ +
+
+ + + + +
const uint8_t kHitachiAc1SleepByte = kHitachiAc1PowerByte
+
+ +
+
+ +

◆ kHitachiAc1SleepOff

+ +
+
+ + + + +
const uint8_t kHitachiAc1SleepOff = 0b000
+
+ +
+
+ +

◆ kHitachiAc1SleepOffset

+ +
+
+ + + + +
const uint8_t kHitachiAc1SleepOffset = 1
+
+ +
+
+ +

◆ kHitachiAc1SleepSize

+ +
+
+ + + + +
const uint8_t kHitachiAc1SleepSize = 3
+
+ +
+
+ +

◆ kHitachiAc1SwingByte

+ +
+
+ + + + +
const uint8_t kHitachiAc1SwingByte = kHitachiAc1PowerByte
+
+ +
+
+ +

◆ kHitachiAc1SwingHOffset

+ +
+
+ + + + +
const uint8_t kHitachiAc1SwingHOffset = 7
+
+ +
+
+ +

◆ kHitachiAc1SwingToggleOffset

+ +
+
+ + + + +
const uint8_t kHitachiAc1SwingToggleOffset = 0
+
+ +
+
+ +

◆ kHitachiAc1SwingVOffset

+ +
+
+ + + + +
const uint8_t kHitachiAc1SwingVOffset = 6
+
+ +
+
+ +

◆ kHitachiAc1TempAuto

+ +
+
+ + + + +
const uint8_t kHitachiAc1TempAuto = 25
+
+ +
+
+ +

◆ kHitachiAc1TempByte

+ +
+
+ + + + +
const uint8_t kHitachiAc1TempByte = 6
+
+ +
+
+ +

◆ kHitachiAc1TempDelta

+ +
+
+ + + + +
const uint8_t kHitachiAc1TempDelta = 7
+
+ +
+
+ +

◆ kHitachiAc1TempOffset

+ +
+
+ + + + +
const uint8_t kHitachiAc1TempOffset = 2
+
+ +
+
+ +

◆ kHitachiAc1TempSize

+ +
+
+ + + + +
const uint8_t kHitachiAc1TempSize = 5
+
+ +
+
+ +

◆ kHitachiAc1TimerSize

+ +
+
+ + + + +
const uint8_t kHitachiAc1TimerSize = 16
+
+ +
+
+ +

◆ kHitachiAc344ButtonFan

+ +
+
+ + + + +
const uint8_t kHitachiAc344ButtonFan = kHitachiAc424ButtonFan
+
+ +
+
+ +

◆ kHitachiAc344ButtonPowerMode

+ +
+
+ + + + +
const uint8_t kHitachiAc344ButtonPowerMode = kHitachiAc424ButtonPowerMode
+
+ +
+
+ +

◆ kHitachiAc344ButtonSwingH

+ +
+
+ + + + +
const uint8_t kHitachiAc344ButtonSwingH = kHitachiAc424ButtonSwingH
+
+ +
+
+ +

◆ kHitachiAc344ButtonSwingV

+ +
+
+ + + + +
const uint8_t kHitachiAc344ButtonSwingV = kHitachiAc424ButtonSwingV
+
+ +
+
+ +

◆ kHitachiAc344ButtonTempDown

+ +
+
+ + + + +
const uint8_t kHitachiAc344ButtonTempDown = kHitachiAc424ButtonTempDown
+
+ +
+
+ +

◆ kHitachiAc344ButtonTempUp

+ +
+
+ + + + +
const uint8_t kHitachiAc344ButtonTempUp = kHitachiAc424ButtonTempUp
+
+ +
+
+ +

◆ kHitachiAc344Cool

+ +
+
+ + + + +
const uint8_t kHitachiAc344Cool = kHitachiAc424Cool
+
+ +
+
+ +

◆ kHitachiAc344Dry

+ +
+
+ + + + +
const uint8_t kHitachiAc344Dry = kHitachiAc424Dry
+
+ +
+
+ +

◆ kHitachiAc344Fan

+ +
+
+ + + + +
const uint8_t kHitachiAc344Fan = kHitachiAc424Fan
+
+ +
+
+ +

◆ kHitachiAc344FanAuto

+ +
+
+ + + + +
const uint8_t kHitachiAc344FanAuto = kHitachiAc424FanAuto
+
+ +
+
+ +

◆ kHitachiAc344FanHigh

+ +
+
+ + + + +
const uint8_t kHitachiAc344FanHigh = kHitachiAc424FanHigh
+
+ +
+
+ +

◆ kHitachiAc344FanLow

+ +
+
+ + + + +
const uint8_t kHitachiAc344FanLow = kHitachiAc424FanLow
+
+ +
+
+ +

◆ kHitachiAc344FanMax

+ +
+
+ + + + +
const uint8_t kHitachiAc344FanMax = kHitachiAc424FanMax
+
+ +
+
+ +

◆ kHitachiAc344FanMedium

+ +
+
+ + + + +
const uint8_t kHitachiAc344FanMedium = kHitachiAc424FanMedium
+
+ +
+
+ +

◆ kHitachiAc344FanMin

+ +
+
+ + + + +
const uint8_t kHitachiAc344FanMin = kHitachiAc424FanMin
+
+ +
+
+ +

◆ kHitachiAc344Heat

+ +
+
+ + + + +
const uint8_t kHitachiAc344Heat = kHitachiAc424Heat
+
+ +
+
+ +

◆ kHitachiAc344MaxTemp

+ +
+
+ + + + +
const uint8_t kHitachiAc344MaxTemp = kHitachiAc424MaxTemp
+
+ +
+
+ +

◆ kHitachiAc344MinTemp

+ +
+
+ + + + +
const uint8_t kHitachiAc344MinTemp = kHitachiAc424MinTemp
+
+ +
+
+ +

◆ kHitachiAc344SwingHAuto

+ +
+
+ + + + +
const uint8_t kHitachiAc344SwingHAuto = 0
+
+ +
+
+ +

◆ kHitachiAc344SwingHByte

+ +
+
+ + + + +
const uint8_t kHitachiAc344SwingHByte = 35
+
+ +
+
+ +

◆ kHitachiAc344SwingHLeft

+ +
+
+ + + + +
const uint8_t kHitachiAc344SwingHLeft = 4
+
+ +
+
+ +

◆ kHitachiAc344SwingHLeftMax

+ +
+
+ + + + +
const uint8_t kHitachiAc344SwingHLeftMax = 5
+
+ +
+
+ +

◆ kHitachiAc344SwingHMiddle

+ +
+
+ + + + +
const uint8_t kHitachiAc344SwingHMiddle = 3
+
+ +
+
+ +

◆ kHitachiAc344SwingHOffset

+ +
+
+ + + + +
const uint8_t kHitachiAc344SwingHOffset = 0
+
+ +
+
+ +

◆ kHitachiAc344SwingHRight

+ +
+
+ + + + +
const uint8_t kHitachiAc344SwingHRight = 2
+
+ +
+
+ +

◆ kHitachiAc344SwingHRightMax

+ +
+
+ + + + +
const uint8_t kHitachiAc344SwingHRightMax = 1
+
+ +
+
+ +

◆ kHitachiAc344SwingHSize

+ +
+
+ + + + +
const uint8_t kHitachiAc344SwingHSize = 3
+
+ +
+
+ +

◆ kHitachiAc344SwingVByte

+ +
+
+ + + + +
const uint8_t kHitachiAc344SwingVByte = 37
+
+ +
+
+ +

◆ kHitachiAc344SwingVOffset

+ +
+
+ + + + +
const uint8_t kHitachiAc344SwingVOffset = 5
+
+ +
+
+ +

◆ kHitachiAc424ButtonByte

+ +
+
+ + + + +
const uint8_t kHitachiAc424ButtonByte = 11
+
+ +
+
+ +

◆ kHitachiAc424ButtonFan

+ +
+
+ + + + +
const uint8_t kHitachiAc424ButtonFan = 0x42
+
+ +
+
+ +

◆ kHitachiAc424ButtonPowerMode

+ +
+
+ + + + +
const uint8_t kHitachiAc424ButtonPowerMode = 0x13
+
+ +
+
+ +

◆ kHitachiAc424ButtonSwingH

+ +
+
+ + + + +
const uint8_t kHitachiAc424ButtonSwingH = 0x8C
+
+ +
+
+ +

◆ kHitachiAc424ButtonSwingV

+ +
+
+ + + + +
const uint8_t kHitachiAc424ButtonSwingV = 0x81
+
+ +
+
+ +

◆ kHitachiAc424ButtonTempDown

+ +
+
+ + + + +
const uint8_t kHitachiAc424ButtonTempDown = 0x43
+
+ +
+
+ +

◆ kHitachiAc424ButtonTempUp

+ +
+
+ + + + +
const uint8_t kHitachiAc424ButtonTempUp = 0x44
+
+ +
+
+ +

◆ kHitachiAc424Cool

+ +
+
+ + + + +
const uint8_t kHitachiAc424Cool = 3
+
+ +
+
+ +

◆ kHitachiAc424Dry

+ +
+
+ + + + +
const uint8_t kHitachiAc424Dry = 5
+
+ +
+
+ +

◆ kHitachiAc424Fan

+ +
+
+ + + + +
const uint8_t kHitachiAc424Fan = 1
+
+ +
+
+ +

◆ kHitachiAc424FanAuto

+ +
+
+ + + + +
const uint8_t kHitachiAc424FanAuto = 5
+
+ +
+
+ +

◆ kHitachiAc424FanByte

+ +
+
+ + + + +
const uint8_t kHitachiAc424FanByte = kHitachiAc424ModeByte
+
+ +
+
+ +

◆ kHitachiAc424FanHigh

+ +
+
+ + + + +
const uint8_t kHitachiAc424FanHigh = 4
+
+ +
+
+ +

◆ kHitachiAc424FanLow

+ +
+
+ + + + +
const uint8_t kHitachiAc424FanLow = 2
+
+ +
+
+ +

◆ kHitachiAc424FanMax

+ +
+
+ + + + +
const uint8_t kHitachiAc424FanMax = 6
+
+ +
+
+ +

◆ kHitachiAc424FanMaxDry

+ +
+
+ + + + +
const uint8_t kHitachiAc424FanMaxDry = 2
+
+ +
+
+ +

◆ kHitachiAc424FanMedium

+ +
+
+ + + + +
const uint8_t kHitachiAc424FanMedium = 3
+
+ +
+
+ +

◆ kHitachiAc424FanMin

+ +
+
+ + + + +
const uint8_t kHitachiAc424FanMin = 1
+
+ +
+
+ +

◆ kHitachiAc424FanTemp

+ +
+
+ + + + +
const uint8_t kHitachiAc424FanTemp = 27
+
+ +
+
+ +

◆ kHitachiAc424Heat

+ +
+
+ + + + +
const uint8_t kHitachiAc424Heat = 6
+
+ +
+
+ +

◆ kHitachiAc424MaxTemp

+ +
+
+ + + + +
const uint8_t kHitachiAc424MaxTemp = 32
+
+ +
+
+ +

◆ kHitachiAc424MinTemp

+ +
+
+ + + + +
const uint8_t kHitachiAc424MinTemp = 16
+
+ +
+
+ +

◆ kHitachiAc424ModeByte

+ +
+
+ + + + +
const uint8_t kHitachiAc424ModeByte = 25
+
+ +
+
+ +

◆ kHitachiAc424PowerByte

+ +
+
+ + + + +
const uint8_t kHitachiAc424PowerByte = 27
+
+ +
+
+ +

◆ kHitachiAc424PowerOff

+ +
+
+ + + + +
const uint8_t kHitachiAc424PowerOff = 0xE1
+
+ +
+
+ +

◆ kHitachiAc424PowerOn

+ +
+
+ + + + +
const uint8_t kHitachiAc424PowerOn = 0xF1
+
+ +
+
+ +

◆ kHitachiAc424TempByte

+ +
+
+ + + + +
const uint8_t kHitachiAc424TempByte = 13
+
+ +
+
+ +

◆ kHitachiAc424TempOffset

+ +
+
+ + + + +
const uint8_t kHitachiAc424TempOffset = 2
+
+ +
+
+ +

◆ kHitachiAc424TempSize

+ +
+
+ + + + +
const uint8_t kHitachiAc424TempSize = 6
+
+ +
+
+ +

◆ kHitachiAcAuto

+ +
+
+ + + + +
const uint8_t kHitachiAcAuto = 2
+
+ +
+
+ +

◆ kHitachiAcAutoTemp

+ +
+
+ + + + +
const uint8_t kHitachiAcAutoTemp = 23
+
+ +
+
+ +

◆ kHitachiAcCool

+ +
+
+ + + + +
const uint8_t kHitachiAcCool = 4
+
+ +
+
+ +

◆ kHitachiAcDry

+ +
+
+ + + + +
const uint8_t kHitachiAcDry = 5
+
+ +
+
+ +

◆ kHitachiAcFan

+ +
+
+ + + + +
const uint8_t kHitachiAcFan = 0xC
+
+ +
+
+ +

◆ kHitachiAcFanAuto

+ +
+
+ + + + +
const uint8_t kHitachiAcFanAuto = 1
+
+ +
+
+ +

◆ kHitachiAcFanHigh

+ +
+
+ + + + +
const uint8_t kHitachiAcFanHigh = 5
+
+ +
+
+ +

◆ kHitachiAcFanLow

+ +
+
+ + + + +
const uint8_t kHitachiAcFanLow = 2
+
+ +
+
+ +

◆ kHitachiAcFanMed

+ +
+
+ + + + +
const uint8_t kHitachiAcFanMed = 3
+
+ +
+
+ +

◆ kHitachiAcFreq

+ +
+
+ + + + +
const uint16_t kHitachiAcFreq = 38000
+
+ +
+
+ +

◆ kHitachiAcHeat

+ +
+
+ + + + +
const uint8_t kHitachiAcHeat = 3
+
+ +
+
+ +

◆ kHitachiAcMaxTemp

+ +
+
+ + + + +
const uint8_t kHitachiAcMaxTemp = 32
+
+ +
+
+ +

◆ kHitachiAcMinTemp

+ +
+
+ + + + +
const uint8_t kHitachiAcMinTemp = 16
+
+ +
+
+ +

◆ kHitachiAcPowerOffset

+ +
+
+ + + + +
const uint8_t kHitachiAcPowerOffset = 0
+
+ +
+
+ +

◆ kHitachiAcSwingOffset

+ +
+
+ + + + +
const uint8_t kHitachiAcSwingOffset = 7
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Hitachi_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Hitachi_8h_source.html new file mode 100644 index 000000000..66b330dd1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Hitachi_8h_source.html @@ -0,0 +1,734 @@ + + + + + + + +IRremoteESP8266: src/ir_Hitachi.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Hitachi.h
+
+
+Go to the documentation of this file.
1 // Copyright 2018-2020 David Conran
+
10 
+
11 // Supports:
+
12 // Brand: Hitachi, Model: RAS-35THA6 remote
+
13 // Brand: Hitachi, Model: LT0541-HTA remote (HITACHI_AC1)
+
14 // Brand: Hitachi, Model: Series VI A/C (Circa 2007) (HITACHI_AC1)
+
15 // Brand: Hitachi, Model: RAR-8P2 remote (HITACHI_AC424)
+
16 // Brand: Hitachi, Model: RAS-AJ25H A/C (HITACHI_AC424)
+
17 // Brand: Hitachi, Model: PC-LH3B (HITACHI_AC3)
+
18 // Brand: Hitachi, Model: KAZE-312KSDP A/C (HITACHI_AC1)
+
19 // Brand: Hitachi, Model: R-LT0541-HTA/Y.K.1.1-1 V2.3 remote (HITACHI_AC1)
+
20 // Brand: Hitachi, Model: RAS-22NK A/C (HITACHI_AC344)
+
21 // Brand: Hitachi, Model: RF11T1 remote (HITACHI_AC344)
+
22 
+
23 #ifndef IR_HITACHI_H_
+
24 #define IR_HITACHI_H_
+
25 
+
26 #define __STDC_LIMIT_MACROS
+
27 #include <stdint.h>
+
28 #ifndef UNIT_TEST
+
29 #include <Arduino.h>
+
30 #endif
+
31 #include "IRremoteESP8266.h"
+
32 #include "IRsend.h"
+
33 #ifdef UNIT_TEST
+
34 #include "IRsend_test.h"
+
35 #endif
+
36 
+
37 // Constants
+
38 const uint16_t kHitachiAcFreq = 38000; // Hz.
+
39 const uint8_t kHitachiAcAuto = 2;
+
40 const uint8_t kHitachiAcHeat = 3;
+
41 const uint8_t kHitachiAcCool = 4;
+
42 const uint8_t kHitachiAcDry = 5;
+
43 const uint8_t kHitachiAcFan = 0xC;
+
44 const uint8_t kHitachiAcFanAuto = 1;
+
45 const uint8_t kHitachiAcFanLow = 2;
+
46 const uint8_t kHitachiAcFanMed = 3;
+
47 const uint8_t kHitachiAcFanHigh = 5;
+
48 const uint8_t kHitachiAcMinTemp = 16; // 16C
+
49 const uint8_t kHitachiAcMaxTemp = 32; // 32C
+
50 const uint8_t kHitachiAcAutoTemp = 23; // 23C
+
51 const uint8_t kHitachiAcPowerOffset = 0;
+
52 const uint8_t kHitachiAcSwingOffset = 7;
+
53 
+
54 // HitachiAc424 & HitachiAc344
+
55 // Byte[11]
+
56 const uint8_t kHitachiAc424ButtonByte = 11;
+
57 const uint8_t kHitachiAc424ButtonPowerMode = 0x13;
+
58 const uint8_t kHitachiAc424ButtonFan = 0x42;
+
59 const uint8_t kHitachiAc424ButtonTempDown = 0x43;
+
60 const uint8_t kHitachiAc424ButtonTempUp = 0x44;
+
61 const uint8_t kHitachiAc424ButtonSwingV = 0x81;
+
62 const uint8_t kHitachiAc424ButtonSwingH = 0x8C;
+ + + + + + +
69 
+
70 // Byte[13]
+
71 const uint8_t kHitachiAc424TempByte = 13;
+
72 const uint8_t kHitachiAc424TempOffset = 2;
+
73 const uint8_t kHitachiAc424TempSize = 6;
+
74 const uint8_t kHitachiAc424MinTemp = 16; // 16C
+
75 const uint8_t kHitachiAc424MaxTemp = 32; // 32C
+ + +
78 const uint8_t kHitachiAc424FanTemp = 27; // 27C
+
79 
+
80 // Byte[25]
+
81 const uint8_t kHitachiAc424ModeByte = 25;
+
82 const uint8_t kHitachiAc424Fan = 1;
+
83 const uint8_t kHitachiAc424Cool = 3;
+
84 const uint8_t kHitachiAc424Dry = 5;
+
85 const uint8_t kHitachiAc424Heat = 6;
+ + + + +
90 
+ +
92 const uint8_t kHitachiAc424FanMin = 1;
+
93 const uint8_t kHitachiAc424FanLow = 2;
+
94 const uint8_t kHitachiAc424FanMedium = 3;
+
95 const uint8_t kHitachiAc424FanHigh = 4;
+
96 const uint8_t kHitachiAc424FanAuto = 5;
+
97 const uint8_t kHitachiAc424FanMax = 6;
+
98 const uint8_t kHitachiAc424FanMaxDry = 2;
+ + + + + + +
105 
+
106 // Byte[27]
+
107 const uint8_t kHitachiAc424PowerByte = 27;
+
108 const uint8_t kHitachiAc424PowerOn = 0xF1;
+
109 const uint8_t kHitachiAc424PowerOff = 0xE1;
+
110 
+
111 // Byte[35]
+
112 const uint8_t kHitachiAc344SwingHByte = 35;
+
113 const uint8_t kHitachiAc344SwingHOffset = 0; // Mask 0b00000xxx
+
114 const uint8_t kHitachiAc344SwingHSize = 3; // Mask 0b00000xxx
+
115 const uint8_t kHitachiAc344SwingHAuto = 0; // 0b000
+
116 const uint8_t kHitachiAc344SwingHRightMax = 1; // 0b001
+
117 const uint8_t kHitachiAc344SwingHRight = 2; // 0b010
+
118 const uint8_t kHitachiAc344SwingHMiddle = 3; // 0b011
+
119 const uint8_t kHitachiAc344SwingHLeft = 4; // 0b100
+
120 const uint8_t kHitachiAc344SwingHLeftMax = 5; // 0b101
+
121 
+
122 // Byte[37]
+
123 const uint8_t kHitachiAc344SwingVByte = 37;
+
124 const uint8_t kHitachiAc344SwingVOffset = 5; // Mask 0b00x00000
+
125 
+
126 // HitachiAc1
+
127 // Byte[3] (Model)
+
128 const uint8_t kHitachiAc1ModelByte = 3;
+
129 const uint8_t kHitachiAc1ModelOffset = 6; // Mask 0b11000000
+
130 const uint8_t kHitachiAc1Model_A = 0b10;
+
131 const uint8_t kHitachiAc1Model_B = 0b01;
+
132 const uint8_t kHitachiAc1ModelSize = 2;
+
133 
+
134 // Byte[5] (Mode & Fan)
+
135 const uint8_t kHitachiAc1ModeByte = 5;
+
136 const uint8_t kHitachiAc1ModeOffset = 4;
+
137 const uint8_t kHitachiAc1ModeSize = 4; // Mask 0b11110000
+
138 const uint8_t kHitachiAc1Dry = 0b0010; // 2
+
139 const uint8_t kHitachiAc1Fan = 0b0100; // 4
+
140 const uint8_t kHitachiAc1Cool = 0b0110; // 6
+
141 const uint8_t kHitachiAc1Heat = 0b1001; // 9
+
142 const uint8_t kHitachiAc1Auto = 0b1110; // 14
+ +
144 const uint8_t kHitachiAc1FanOffset = 0;
+
145 const uint8_t kHitachiAc1FanSize = 4; // Mask 0b0001111
+
146 const uint8_t kHitachiAc1FanAuto = 1; // 0b0001
+
147 const uint8_t kHitachiAc1FanHigh = 2; // 0b0010
+
148 const uint8_t kHitachiAc1FanMed = 4; // 0b0100
+
149 const uint8_t kHitachiAc1FanLow = 8; // 0b1000
+
150 // Byte[6] (Temperature)
+
151 // Note: Temp is stored in LSB order.
+
152 const uint8_t kHitachiAc1TempByte = 6;
+
153 const uint8_t kHitachiAc1TempOffset = 2;
+
154 const uint8_t kHitachiAc1TempSize = 5; // Mask 0b01111100
+
155 const uint8_t kHitachiAc1TempDelta = 7;
+
156 const uint8_t kHitachiAc1TempAuto = 25; // Celsius
+
157 // Note: Timers are nr. of minutes & stored in LSB order.
+
158 // Byte[7-8] (Off Timer)
+
159 const uint8_t kHitachiAc1TimerSize = 16; // Mask 0b1111111111111111
+
160 const uint8_t kHitachiAc1OffTimerLowByte = 7;
+
161 const uint8_t kHitachiAc1OffTimerHighByte = 8;
+
162 // Byte[9-10] (On Timer)
+
163 const uint8_t kHitachiAc1OnTimerLowByte = 9;
+
164 const uint8_t kHitachiAc1OnTimerHighByte = 10;
+
165 // Byte[11] (Power/Swing/Sleep)
+
166 const uint8_t kHitachiAc1PowerByte = 11;
+
167 const uint8_t kHitachiAc1PowerOffset = 5; // Mask 0b00100000
+
168 const uint8_t kHitachiAc1PowerToggleOffset = 4; // Mask 0b00010000
+ +
170 const uint8_t kHitachiAc1SwingHOffset = 7; // Mask 0b10000000
+
171 const uint8_t kHitachiAc1SwingVOffset = 6; // Mask 0b01000000
+
172 const uint8_t kHitachiAc1SwingToggleOffset = 0; // Mask 0b00000001
+ +
174 const uint8_t kHitachiAc1SleepOffset = 1; // Mask 0b00001110
+
175 const uint8_t kHitachiAc1SleepSize = 3; // Mask 0b00001110
+
176 const uint8_t kHitachiAc1SleepOff = 0b000;
+
177 const uint8_t kHitachiAc1Sleep1 = 0b001;
+
178 const uint8_t kHitachiAc1Sleep2 = 0b010;
+
179 const uint8_t kHitachiAc1Sleep3 = 0b011;
+
180 const uint8_t kHitachiAc1Sleep4 = 0b100;
+
181 // Byte[12] (Checksum)
+ +
183 
+
184 
+
185 // Classes
+
188 class IRHitachiAc {
+
189  public:
+
190  explicit IRHitachiAc(const uint16_t pin, const bool inverted = false,
+
191  const bool use_modulation = true);
+
192  void stateReset(void);
+
193 #if SEND_HITACHI_AC
+
194  void send(const uint16_t repeat = kHitachiAcDefaultRepeat);
+
199  int8_t calibrate(void) { return _irsend.calibrate(); }
+
200 #endif // SEND_HITACHI_AC
+
201  void begin(void);
+
202  void on(void);
+
203  void off(void);
+
204  void setPower(const bool on);
+
205  bool getPower(void);
+
206  void setTemp(const uint8_t temp);
+
207  uint8_t getTemp(void);
+
208  void setFan(const uint8_t speed);
+
209  uint8_t getFan(void);
+
210  void setMode(const uint8_t mode);
+
211  uint8_t getMode(void);
+
212  void setSwingVertical(const bool on);
+
213  bool getSwingVertical(void);
+
214  void setSwingHorizontal(const bool on);
+
215  bool getSwingHorizontal(void);
+
216  uint8_t* getRaw(void);
+
217  void setRaw(const uint8_t new_code[],
+
218  const uint16_t length = kHitachiAcStateLength);
+
219  static bool validChecksum(const uint8_t state[],
+
220  const uint16_t length = kHitachiAcStateLength);
+
221  static uint8_t calcChecksum(const uint8_t state[],
+
222  const uint16_t length = kHitachiAcStateLength);
+
223  uint8_t convertMode(const stdAc::opmode_t mode);
+
224  uint8_t convertFan(const stdAc::fanspeed_t speed);
+
225  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
226  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
227  stdAc::state_t toCommon(void);
+
228  String toString(void);
+
229 #ifndef UNIT_TEST
+
230 
+
231  private:
+ +
233 #else // UNIT_TEST
+
234  IRsendTest _irsend;
+
236 #endif // UNIT_TEST
+ +
239  void checksum(const uint16_t length = kHitachiAcStateLength);
+
240  uint8_t _previoustemp;
+
241 };
+
242 
+ +
246  public:
+
247  explicit IRHitachiAc1(const uint16_t pin, const bool inverted = false,
+
248  const bool use_modulation = true);
+
249 
+
250  void stateReset(void);
+
251 #if SEND_HITACHI_AC1
+
252  void send(const uint16_t repeat = kHitachiAcDefaultRepeat);
+
257  int8_t calibrate(void) { return _irsend.calibrate(); }
+
258 #endif // SEND_HITACHI_AC1
+
259  void begin(void);
+
260  void on(void);
+
261  void off(void);
+
262  void setModel(const hitachi_ac1_remote_model_t model);
+ +
264  void setPower(const bool on);
+
265  bool getPower(void);
+
266  void setPowerToggle(const bool on);
+
267  bool getPowerToggle(void);
+
268  void setTemp(const uint8_t temp);
+
269  uint8_t getTemp(void);
+
270  void setFan(const uint8_t speed, const bool force = false);
+
271  uint8_t getFan(void);
+
272  void setMode(const uint8_t mode);
+
273  uint8_t getMode(void);
+
274  void setSwingToggle(const bool toggle);
+
275  bool getSwingToggle(void);
+
276  void setSwingV(const bool on);
+
277  bool getSwingV(void);
+
278  void setSwingH(const bool on);
+
279  bool getSwingH(void);
+
280  void setSleep(const uint8_t mode);
+
281  uint8_t getSleep(void);
+
282  void setOnTimer(const uint16_t mins);
+
283  uint16_t getOnTimer(void);
+
284  void setOffTimer(const uint16_t mins);
+
285  uint16_t getOffTimer(void);
+
286  uint8_t* getRaw(void);
+
287  void setRaw(const uint8_t new_code[],
+
288  const uint16_t length = kHitachiAc1StateLength);
+
289  static bool validChecksum(const uint8_t state[],
+
290  const uint16_t length = kHitachiAc1StateLength);
+
291  static uint8_t calcChecksum(const uint8_t state[],
+
292  const uint16_t length = kHitachiAc1StateLength);
+
293  uint8_t convertMode(const stdAc::opmode_t mode);
+
294  uint8_t convertFan(const stdAc::fanspeed_t speed);
+
295  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
296  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
297  stdAc::state_t toCommon(void);
+
298  String toString(void);
+
299 #ifndef UNIT_TEST
+
300 
+
301  private:
+ +
303 #else // UNIT_TEST
+
304  IRsendTest _irsend;
+
306 #endif // UNIT_TEST
+ +
309  void checksum(const uint16_t length = kHitachiAc1StateLength);
+
310 };
+
311 
+ +
314  friend class IRHitachiAc344;
+
315  public:
+
316  explicit IRHitachiAc424(const uint16_t pin, const bool inverted = false,
+
317  const bool use_modulation = true);
+
318  virtual void stateReset(void);
+
319 #if SEND_HITACHI_AC424
+
320  virtual void send(const uint16_t repeat = kHitachiAcDefaultRepeat);
+
325  int8_t calibrate(void) { return _irsend.calibrate(); }
+
326 #endif // SEND_HITACHI_AC424
+
327  void begin(void);
+
328  void on(void);
+
329  void off(void);
+
330  void setPower(const bool on);
+
331  bool getPower(void);
+
332  void setTemp(const uint8_t temp, bool setPrevious = true);
+
333  uint8_t getTemp(void);
+
334  void setFan(const uint8_t speed);
+
335  uint8_t getFan(void);
+
336  uint8_t getButton(void);
+
337  void setButton(const uint8_t button);
+
338  void setSwingVToggle(const bool on);
+
339  bool getSwingVToggle(void);
+
340  void setMode(const uint8_t mode);
+
341  uint8_t getMode(void);
+
342  uint8_t* getRaw(void);
+
343  virtual void setRaw(const uint8_t new_code[],
+
344  const uint16_t length = kHitachiAc424StateLength);
+
345  uint8_t convertMode(const stdAc::opmode_t mode);
+
346  uint8_t convertFan(const stdAc::fanspeed_t speed);
+
347  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
348  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
349  virtual stdAc::state_t toCommon(void);
+
350  String toString(void);
+
351 #ifndef UNIT_TEST
+
352 
+
353  private:
+ +
355 #else // UNIT_TEST
+
356  IRsendTest _irsend;
+
358 #endif // UNIT_TEST
+ +
361  void setInvertedStates(void);
+
362  String _toString(void);
+
363  uint8_t _previoustemp;
+
364 };
+
365 
+ +
368  public:
+
369  explicit IRHitachiAc3(const uint16_t pin, const bool inverted = false,
+
370  const bool use_modulation = true);
+
371 
+
372  void stateReset(void);
+
373 #if SEND_HITACHI_AC3
+
374  void send(const uint16_t repeat = kHitachiAcDefaultRepeat);
+
379  int8_t calibrate(void) { return _irsend.calibrate(); }
+
380 #endif // SEND_HITACHI_AC3
+
381  void begin(void);
+
382  uint8_t getMode(void);
+
383  uint8_t* getRaw(void);
+
384  void setRaw(const uint8_t new_code[],
+
385  const uint16_t length = kHitachiAc3StateLength);
+
386  static bool hasInvertedStates(const uint8_t state[], const uint16_t length);
+
387 #ifndef UNIT_TEST
+
388 
+
389  private:
+ +
391 #else // UNIT_TEST
+
392  IRsendTest _irsend;
+
394 #endif // UNIT_TEST
+ +
397  void setInvertedStates(const uint16_t length = kHitachiAc3StateLength);
+
398 };
+
399 
+ +
402  public:
+
403  explicit IRHitachiAc344(const uint16_t pin, const bool inverted = false,
+
404  const bool use_modulation = true);
+
405  void stateReset(void);
+
406  void setRaw(const uint8_t new_code[],
+
407  const uint16_t length = kHitachiAc344StateLength);
+
408  stdAc::state_t toCommon(void);
+
409 #if SEND_HITACHI_AC344
+
410  void send(const uint16_t repeat = kHitachiAcDefaultRepeat);
+
411 #endif // SEND_HITACHI_AC344
+
412  void setSwingV(const bool on);
+
413  bool getSwingV(void);
+
414  void setSwingH(const uint8_t position);
+
415  uint8_t getSwingH(void);
+
416  static uint8_t convertSwingH(const stdAc::swingh_t position);
+
417  static stdAc::swingh_t toCommonSwingH(const uint8_t pos);
+
418  String toString(void);
+
419 };
+
420 #endif // IR_HITACHI_H_
+
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Hitachi.cpp:1585
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Hitachi.cpp:1087
+
uint8_t _previoustemp
Definition: ir_Hitachi.h:363
+
const uint8_t kHitachiAc424Fan
Definition: ir_Hitachi.h:82
+
static uint8_t calcChecksum(const uint8_t state[], const uint16_t length=kHitachiAc1StateLength)
Calculate the checksum for a given state.
Definition: ir_Hitachi.cpp:448
+
const uint8_t kHitachiAc1TempOffset
Definition: ir_Hitachi.h:153
+
const uint8_t kHitachiAc424ButtonByte
Definition: ir_Hitachi.h:56
+
const uint8_t kHitachiAc1Fan
Definition: ir_Hitachi.h:139
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Hitachi.cpp:1149
+
const uint8_t kHitachiAc344SwingHRightMax
Definition: ir_Hitachi.h:116
+
IRHitachiAc3(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Hitachi.cpp:1378
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Hitachi.cpp:1107
+
const uint8_t kHitachiAcMinTemp
Definition: ir_Hitachi.h:48
+
bool getSwingVertical(void)
Get the Vertical Swing setting of the A/C.
Definition: ir_Hitachi.cpp:298
+
const uint8_t kHitachiAc344SwingVOffset
Definition: ir_Hitachi.h:124
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Hitachi.cpp:363
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Hitachi.cpp:593
+
uint8_t getSleep(void)
Get the Sleep setting of the A/C.
Definition: ir_Hitachi.cpp:690
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Hitachi.h:354
+
void setTemp(const uint8_t temp, bool setPrevious=true)
Set the temperature.
Definition: ir_Hitachi.cpp:1134
+
const uint8_t kHitachiAcMaxTemp
Definition: ir_Hitachi.h:49
+
void setSleep(const uint8_t mode)
Set the Sleep setting of the A/C.
Definition: ir_Hitachi.cpp:698
+
void stateReset(void)
Reset the internal state to a fixed known good state.
Definition: ir_Hitachi.cpp:138
+
const uint8_t kHitachiAc1PowerOffset
Definition: ir_Hitachi.h:167
+
void off(void)
Change the power setting to Off.
Definition: ir_Hitachi.cpp:1097
+
const uint8_t kHitachiAcAuto
Definition: ir_Hitachi.h:39
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Hitachi.h:390
+
bool getSwingToggle(void)
Get the Swing Toggle setting of the A/C.
Definition: ir_Hitachi.cpp:651
+
const uint8_t kHitachiAc344ButtonFan
Definition: ir_Hitachi.h:64
+
const uint8_t kHitachiAc1Model_A
Definition: ir_Hitachi.h:130
+
const uint8_t kHitachiAc344ButtonPowerMode
Definition: ir_Hitachi.h:63
+
void setFan(const uint8_t speed)
Set the speed of the fan.
Definition: ir_Hitachi.cpp:279
+
void setPowerToggle(const bool on)
Change the power toggle setting.
Definition: ir_Hitachi.cpp:548
+
static uint8_t convertSwingH(const stdAc::swingh_t position)
Convert a standard A/C horizontal swing into its native setting.
Definition: ir_Hitachi.cpp:1558
+
void checksum(const uint16_t length=kHitachiAc1StateLength)
Calculate and set the checksum values for the internal state.
Definition: ir_Hitachi.cpp:462
+
const uint16_t kHitachiAcStateLength
Definition: IRremoteESP8266.h:892
+
const uint8_t kHitachiAcPowerOffset
Definition: ir_Hitachi.h:51
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
const uint8_t kHitachiAc344SwingHRight
Definition: ir_Hitachi.h:117
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Hitachi.cpp:1422
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Hitachi.h:379
+
void setSwingVertical(const bool on)
Set the Vertical Swing setting of the A/C.
Definition: ir_Hitachi.cpp:304
+
void stateReset(void)
Reset the internal state to a fixed known good state.
Definition: ir_Hitachi.cpp:427
+
void send(const uint16_t repeat=kHitachiAcDefaultRepeat)
+
void setSwingHorizontal(const bool on)
Set the Horizontal Swing setting of the A/C.
Definition: ir_Hitachi.cpp:316
+
void setFan(const uint8_t speed)
Set the speed of the fan.
Definition: ir_Hitachi.cpp:1155
+
const uint8_t kHitachiAc1ModeOffset
Definition: ir_Hitachi.h:136
+
const uint16_t kHitachiAc1StateLength
Definition: IRremoteESP8266.h:895
+
void setSwingVToggle(const bool on)
Set the Vertical Swing toggle setting of the A/C.
Definition: ir_Hitachi.cpp:1202
+
const uint8_t kHitachiAc1ChecksumStartByte
Definition: ir_Hitachi.h:182
+
const uint8_t kHitachiAc344SwingHSize
Definition: ir_Hitachi.h:114
+
const uint8_t kHitachiAc344FanHigh
Definition: ir_Hitachi.h:102
+
void setOnTimer(const uint16_t mins)
Set the On Timer time.
Definition: ir_Hitachi.cpp:713
+
const uint8_t kHitachiAcFanHigh
Definition: ir_Hitachi.h:47
+
const uint8_t kHitachiAc1Sleep3
Definition: ir_Hitachi.h:179
+
const uint8_t kHitachiAc1TimerSize
Definition: ir_Hitachi.h:159
+
const uint8_t kHitachiAc1ModeSize
Definition: ir_Hitachi.h:137
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Hitachi.cpp:560
+
void stateReset(void)
Reset the internal state to auto fan, cooling, 23° Celsius.
Definition: ir_Hitachi.cpp:1503
+
const uint8_t kHitachiAc344Fan
Definition: ir_Hitachi.h:86
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Hitachi.cpp:227
+
Class for handling detailed Hitachi 53-byte/424-bit A/C messages.
Definition: ir_Hitachi.h:313
+
void setInvertedStates(void)
Update the internal consistency check for the protocol.
Definition: ir_Hitachi.cpp:1049
+
IRHitachiAc1(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Hitachi.cpp:422
+
void send(const uint16_t repeat=kHitachiAcDefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Hitachi.cpp:492
+
const uint8_t kHitachiAc1Sleep1
Definition: ir_Hitachi.h:177
+
IRHitachiAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Hitachi.cpp:133
+
const uint8_t kHitachiAc344SwingHOffset
Definition: ir_Hitachi.h:113
+ +
const uint8_t kHitachiAc1Auto
Definition: ir_Hitachi.h:142
+
void setSwingV(const bool on)
Control the vertical swing setting.
Definition: ir_Hitachi.cpp:1526
+
const uint8_t kHitachiAc344MaxTemp
Definition: ir_Hitachi.h:77
+
const uint16_t kHitachiAc3StateLength
Definition: IRremoteESP8266.h:899
+
bool getSwingV(void)
Get the Vertical Swing setting of the A/C.
Definition: ir_Hitachi.cpp:665
+
hitachi_ac1_remote_model_t
HITACHI_AC1 A/C model numbers.
Definition: IRsend.h:135
+
uint8_t getButton(void)
Get the Button/Command setting of the A/C.
Definition: ir_Hitachi.cpp:1188
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Hitachi.h:257
+
const uint8_t kHitachiAc424ButtonSwingH
Definition: ir_Hitachi.h:62
+
const uint8_t kHitachiAc424PowerByte
Definition: ir_Hitachi.h:107
+
const uint8_t kHitachiAc424ButtonTempDown
Definition: ir_Hitachi.h:59
+
void send(const uint16_t repeat=kHitachiAcDefaultRepeat)
Create and send the IR message to the A/C.
Definition: ir_Hitachi.cpp:1512
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
const uint8_t kHitachiAc344SwingHAuto
Definition: ir_Hitachi.h:115
+
void setSwingH(const bool on)
Set the Horizontal Swing setting of the A/C.
Definition: ir_Hitachi.cpp:683
+
const uint8_t kHitachiAc344Heat
Definition: ir_Hitachi.h:89
+
Class for handling detailed Hitachi 224-bit A/C messages.
Definition: ir_Hitachi.h:188
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
const uint8_t kHitachiAc344SwingHLeftMax
Definition: ir_Hitachi.h:120
+
const uint8_t kHitachiAc424TempSize
Definition: ir_Hitachi.h:73
+
static bool validChecksum(const uint8_t state[], const uint16_t length=kHitachiAc1StateLength)
Verify the checksum is valid for a given state.
Definition: ir_Hitachi.cpp:470
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Hitachi.cpp:746
+
const uint8_t kHitachiAc1FanLow
Definition: ir_Hitachi.h:149
+
Class for handling detailed Hitachi 344-bit A/C messages.
Definition: ir_Hitachi.h:401
+
const uint8_t kHitachiAc424MinTemp
Definition: ir_Hitachi.h:74
+
const uint8_t kHitachiAc344FanAuto
Definition: ir_Hitachi.h:103
+
std::string String
Definition: IRremoteESP8266.h:1093
+
const uint8_t kHitachiAc1Model_B
Definition: ir_Hitachi.h:131
+
uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Hitachi.cpp:336
+
static uint8_t calcChecksum(const uint8_t state[], const uint16_t length=kHitachiAcStateLength)
Calculate the checksum for a given state.
Definition: ir_Hitachi.cpp:163
+
const uint8_t kHitachiAc1FanHigh
Definition: ir_Hitachi.h:147
+
const uint8_t kHitachiAc1SleepSize
Definition: ir_Hitachi.h:175
+
const uint8_t kHitachiAc424ButtonSwingV
Definition: ir_Hitachi.h:61
+
const uint8_t kHitachiAcDry
Definition: ir_Hitachi.h:42
+
void setButton(const uint8_t button)
Set the Button/Command pressed setting of the A/C.
Definition: ir_Hitachi.cpp:1194
+
const uint8_t kHitachiAc1Sleep2
Definition: ir_Hitachi.h:178
+
String toString(void)
Convert the internal state into a human readable string.
Definition: ir_Hitachi.cpp:1595
+
const uint8_t kHitachiAc424ButtonTempUp
Definition: ir_Hitachi.h:60
+
void stateReset(void)
Reset the internal state to a fixed known good state.
Definition: ir_Hitachi.cpp:1384
+
const uint8_t kHitachiAc1PowerByte
Definition: ir_Hitachi.h:166
+
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_Hitachi.cpp:1059
+
bool getSwingV(void)
Get the current vertical swing setting.
Definition: ir_Hitachi.cpp:1533
+
const uint8_t kHitachiAc1SwingVOffset
Definition: ir_Hitachi.h:171
+
const uint8_t kHitachiAc424ButtonFan
Definition: ir_Hitachi.h:58
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Hitachi.cpp:275
+
const uint8_t kHitachiAcFanAuto
Definition: ir_Hitachi.h:44
+
const uint8_t kHitachiAc1OffTimerHighByte
Definition: ir_Hitachi.h:161
+
const uint8_t kHitachiAc344Dry
Definition: ir_Hitachi.h:88
+
hitachi_ac1_remote_model_t getModel(void)
Get/Detect the model of the A/C.
Definition: ir_Hitachi.cpp:502
+
Class for handling detailed Hitachi 15to27-byte/120to216-bit A/C messages.
Definition: ir_Hitachi.h:367
+ +
swingh_t
Common A/C settings for Horizontal Swing.
Definition: IRsend.h:83
+
void setModel(const hitachi_ac1_remote_model_t model)
Set the model of the A/C to emulate.
Definition: ir_Hitachi.cpp:512
+
const uint8_t kHitachiAc344FanLow
Definition: ir_Hitachi.h:100
+
const uint8_t kHitachiAc424FanMaxDry
Definition: ir_Hitachi.h:98
+
const uint8_t kHitachiAc424FanHigh
Definition: ir_Hitachi.h:95
+
void setSwingToggle(const bool toggle)
Set the Swing toggle setting of the A/C.
Definition: ir_Hitachi.cpp:658
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Hitachi.cpp:527
+
Class for handling detailed Hitachi 104-bit A/C messages.
Definition: ir_Hitachi.h:245
+
const uint8_t kHitachiAc344SwingHLeft
Definition: ir_Hitachi.h:119
+
bool getPowerToggle(void)
Get the value of the current power toggle setting.
Definition: ir_Hitachi.cpp:541
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Hitachi.cpp:1248
+
void on(void)
Change the power setting to On.
Definition: ir_Hitachi.cpp:553
+
const uint8_t kHitachiAc1TempSize
Definition: ir_Hitachi.h:154
+
const uint8_t kHitachiAc1SleepByte
Definition: ir_Hitachi.h:173
+
uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Hitachi.cpp:1234
+
const uint8_t kHitachiAc1FanSize
Definition: ir_Hitachi.h:145
+
const uint8_t kHitachiAcFanMed
Definition: ir_Hitachi.h:46
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Hitachi.cpp:601
+
void on(void)
Change the power setting to On.
Definition: ir_Hitachi.cpp:220
+
const uint8_t kHitachiAc424ModeByte
Definition: ir_Hitachi.h:81
+
uint8_t getMode(void)
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Hitachi.cpp:323
+
const uint8_t kHitachiAc1OnTimerLowByte
Definition: ir_Hitachi.h:163
+
const uint8_t kHitachiAc344SwingHByte
Definition: ir_Hitachi.h:112
+
static bool hasInvertedStates(const uint8_t state[], const uint16_t length)
Check if every second byte of the state, after the fixed header is inverted to the previous byte.
Definition: ir_Hitachi.cpp:1414
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Hitachi.cpp:403
+
const uint16_t kHitachiAc424StateLength
Definition: IRremoteESP8266.h:905
+
uint8_t remote_state[kHitachiAc3StateLength]
The state in native code.
Definition: ir_Hitachi.h:396
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Hitachi.cpp:773
+
void off(void)
Change the power setting to Off.
Definition: ir_Hitachi.cpp:223
+
const uint8_t kHitachiAc1Heat
Definition: ir_Hitachi.h:141
+
const uint8_t kHitachiAc1TempByte
Definition: ir_Hitachi.h:152
+
const uint16_t kHitachiAcFreq
Definition: ir_Hitachi.h:38
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Hitachi.h:325
+
const uint8_t kHitachiAc1SleepOffset
Definition: ir_Hitachi.h:174
+
uint16_t getOffTimer(void)
Get the Off Timer vtime of the A/C.
Definition: ir_Hitachi.cpp:737
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Hitachi.cpp:1126
+
const uint8_t kHitachiAc424TempByte
Definition: ir_Hitachi.h:71
+
uint8_t remote_state[kHitachiAcStateLength]
The state in native code.
Definition: ir_Hitachi.h:238
+
const uint8_t kHitachiAcFanLow
Definition: ir_Hitachi.h:45
+
const uint8_t kHitachiAc344FanMin
Definition: ir_Hitachi.h:99
+
const uint8_t kHitachiAc424FanAuto
Definition: ir_Hitachi.h:96
+
void setRaw(const uint8_t new_code[], const uint16_t length=kHitachiAcStateLength)
Set the internal state from a valid code for this protocol.
Definition: ir_Hitachi.cpp:195
+
const uint8_t kHitachiAc1FanMed
Definition: ir_Hitachi.h:148
+
const uint8_t kHitachiAc424FanByte
Definition: ir_Hitachi.h:91
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Hitachi.cpp:533
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Hitachi.cpp:209
+
IRHitachiAc424(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Hitachi.cpp:1018
+
const uint8_t kHitachiAcCool
Definition: ir_Hitachi.h:41
+
const uint8_t kHitachiAc1Sleep4
Definition: ir_Hitachi.h:180
+
static stdAc::swingh_t toCommonSwingH(const uint8_t pos)
Convert a native horizontal swing postion to it's common equivalent.
Definition: ir_Hitachi.cpp:1572
+
const uint8_t kHitachiAc1FanOffset
Definition: ir_Hitachi.h:144
+
const uint8_t kHitachiAc1SwingToggleOffset
Definition: ir_Hitachi.h:172
+
void setRaw(const uint8_t new_code[], const uint16_t length=kHitachiAc1StateLength)
Set the internal state from a valid code for this protocol.
Definition: ir_Hitachi.cpp:485
+
const uint8_t kHitachiAcHeat
Definition: ir_Hitachi.h:40
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Hitachi.cpp:1055
+
friend class IRHitachiAc344
Definition: ir_Hitachi.h:314
+
const uint8_t kHitachiAc1FanByte
Definition: ir_Hitachi.h:143
+
const uint8_t kHitachiAc424MaxTemp
Definition: ir_Hitachi.h:75
+
uint8_t remote_state[kHitachiAc1StateLength]
The state in native code.
Definition: ir_Hitachi.h:308
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Hitachi.cpp:375
+
void setInvertedStates(const uint16_t length=kHitachiAc3StateLength)
Invert every second byte of the internal state, after the fixed header.
Definition: ir_Hitachi.cpp:1404
+
const uint16_t kHitachiAc344StateLength
Definition: IRremoteESP8266.h:903
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Hitachi.h:232
+
const uint8_t kHitachiAc1SwingHOffset
Definition: ir_Hitachi.h:170
+
void send(const uint16_t repeat=kHitachiAcDefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Hitachi.cpp:202
+
const uint8_t kHitachiAc424FanTemp
Definition: ir_Hitachi.h:78
+
const uint8_t kHitachiAc1Cool
Definition: ir_Hitachi.h:140
+
uint8_t remote_state[kHitachiAc424StateLength]
The state in native code.
Definition: ir_Hitachi.h:360
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Hitachi.cpp:613
+
uint8_t _previoustemp
Definition: ir_Hitachi.h:240
+
const uint8_t kHitachiAc1FanAuto
Definition: ir_Hitachi.h:146
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Hitachi.cpp:157
+
const uint8_t kHitachiAc424TempOffset
Definition: ir_Hitachi.h:72
+
const uint8_t kHitachiAc1ModelByte
Definition: ir_Hitachi.h:128
+
const uint8_t kHitachiAc424PowerOff
Definition: ir_Hitachi.h:109
+
const uint8_t kHitachiAc1PowerToggleOffset
Definition: ir_Hitachi.h:168
+
const uint8_t kHitachiAc424FanMin
Definition: ir_Hitachi.h:92
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Hitachi.cpp:1101
+
virtual void stateReset(void)
Reset the internal state to a fixed known good state.
Definition: ir_Hitachi.cpp:1024
+
const uint8_t kHitachiAc344FanMax
Definition: ir_Hitachi.h:104
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Hitachi.h:302
+
const uint8_t kHitachiAc1ModelOffset
Definition: ir_Hitachi.h:129
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Hitachi.cpp:249
+
const uint8_t kHitachiAc424Dry
Definition: ir_Hitachi.h:84
+
void setSwingH(const uint8_t position)
Control the horizontal swing setting.
Definition: ir_Hitachi.cpp:1540
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Hitachi.cpp:567
+
const uint16_t kHitachiAcDefaultRepeat
Definition: IRremoteESP8266.h:894
+
const uint8_t kHitachiAc424PowerOn
Definition: ir_Hitachi.h:108
+
const uint8_t kHitachiAc344SwingVByte
Definition: ir_Hitachi.h:123
+
String toString(void)
Convert the internal state into a human readable string.
Definition: ir_Hitachi.cpp:1343
+
const uint8_t kHitachiAc344SwingHMiddle
Definition: ir_Hitachi.h:118
+
void checksum(const uint16_t length=kHitachiAcStateLength)
Calculate and set the checksum values for the internal state.
Definition: ir_Hitachi.cpp:172
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Hitachi.cpp:1221
+
uint16_t getOnTimer(void)
Get the On Timer vtime of the A/C.
Definition: ir_Hitachi.cpp:721
+
void setFan(const uint8_t speed, const bool force=false)
Set the speed of the fan.
Definition: ir_Hitachi.cpp:621
+
uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Hitachi.cpp:759
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Hitachi.cpp:825
+
void setSwingV(const bool on)
Set the Vertical Swing setting of the A/C.
Definition: ir_Hitachi.cpp:671
+
const uint8_t kHitachiAc1SwingByte
Definition: ir_Hitachi.h:169
+
const uint8_t kHitachiAc1ModeByte
Definition: ir_Hitachi.h:135
+
static bool validChecksum(const uint8_t state[], const uint16_t length=kHitachiAcStateLength)
Verify the checksum is valid for a given state.
Definition: ir_Hitachi.cpp:180
+
const uint8_t kHitachiAc424FanMedium
Definition: ir_Hitachi.h:94
+
const uint8_t kHitachiAc344ButtonTempUp
Definition: ir_Hitachi.h:66
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Hitachi.cpp:350
+
const uint8_t kHitachiAc424Cool
Definition: ir_Hitachi.h:83
+
void setRaw(const uint8_t new_code[], const uint16_t length=kHitachiAc3StateLength)
Set the internal state from a valid code for this protocol.
Definition: ir_Hitachi.cpp:1434
+
const uint8_t kHitachiAcFan
Definition: ir_Hitachi.h:43
+
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_Hitachi.cpp:1426
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Hitachi.cpp:797
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Hitachi.cpp:442
+
const uint8_t kHitachiAc1OnTimerHighByte
Definition: ir_Hitachi.h:164
+
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_Hitachi.cpp:187
+
void setOffTimer(const uint16_t mins)
Set the Off Timer time.
Definition: ir_Hitachi.cpp:729
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Hitachi.cpp:786
+
virtual void send(const uint16_t repeat=kHitachiAcDefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Hitachi.cpp:1074
+
const uint8_t kHitachiAc344ButtonSwingH
Definition: ir_Hitachi.h:68
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Hitachi.cpp:215
+
virtual void setRaw(const uint8_t new_code[], const uint16_t length=kHitachiAc424StateLength)
Set the internal state from a valid code for this protocol.
Definition: ir_Hitachi.cpp:1067
+
const uint8_t kHitachiAc424FanLow
Definition: ir_Hitachi.h:93
+
const uint8_t kHitachiAcAutoTemp
Definition: ir_Hitachi.h:50
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Hitachi.h:199
+
void setRaw(const uint8_t new_code[], const uint16_t length=kHitachiAc344StateLength)
Set the internal state from a valid code for this protocol.
Definition: ir_Hitachi.cpp:1520
+
const uint8_t kHitachiAc344FanMedium
Definition: ir_Hitachi.h:101
+
const uint8_t kHitachiAc1Dry
Definition: ir_Hitachi.h:138
+
bool getSwingH(void)
Get the Horizontal Swing setting of the A/C.
Definition: ir_Hitachi.cpp:677
+
bool getSwingHorizontal(void)
Get the Horizontal Swing setting of the A/C.
Definition: ir_Hitachi.cpp:310
+
const uint8_t kHitachiAc344Cool
Definition: ir_Hitachi.h:87
+
const uint8_t kHitachiAc424FanMax
Definition: ir_Hitachi.h:97
+
const uint8_t kHitachiAc424Heat
Definition: ir_Hitachi.h:85
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Hitachi.cpp:1261
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Hitachi.cpp:231
+
const uint8_t kHitachiAc1ModelSize
Definition: ir_Hitachi.h:132
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
const uint8_t kHitachiAc344ButtonTempDown
Definition: ir_Hitachi.h:65
+
const uint8_t kHitachiAc424ButtonPowerMode
Definition: ir_Hitachi.h:57
+
const uint8_t kHitachiAc1TempAuto
Definition: ir_Hitachi.h:156
+
const uint8_t kHitachiAc1OffTimerLowByte
Definition: ir_Hitachi.h:160
+
const uint8_t kHitachiAc344MinTemp
Definition: ir_Hitachi.h:76
+
const uint8_t kHitachiAc1TempDelta
Definition: ir_Hitachi.h:155
+
void on(void)
Change the power setting to On.
Definition: ir_Hitachi.cpp:1094
+
const uint8_t kHitachiAcSwingOffset
Definition: ir_Hitachi.h:52
+
void off(void)
Change the power setting to Off.
Definition: ir_Hitachi.cpp:556
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Hitachi.cpp:1081
+
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_Hitachi.cpp:477
+
const uint8_t kHitachiAc344ButtonSwingV
Definition: ir_Hitachi.h:67
+
const uint8_t kHitachiAc1SleepOff
Definition: ir_Hitachi.h:176
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Hitachi.cpp:255
+
virtual stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Hitachi.cpp:1274
+
uint8_t getSwingH(void)
Get the current horizontal swing setting.
Definition: ir_Hitachi.cpp:1550
+
String _toString(void)
Convert the internal state into a human readable string for the settings that are common to protocols...
Definition: ir_Hitachi.cpp:1302
+
bool getSwingVToggle(void)
Get the Vertical Swing toggle setting of the A/C.
Definition: ir_Hitachi.cpp:1214
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Inax_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Inax_8cpp.html new file mode 100644 index 000000000..5e5f3eaf4 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Inax_8cpp.html @@ -0,0 +1,207 @@ + + + + + + + +IRremoteESP8266: src/ir_Inax.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Inax.cpp File Reference
+
+
+ +

Support for the Inax Robot Toilet IR protocols. +More...

+ + + + + + + + + + + + + + + + +

+Variables

const uint16_t kInaxTick = 500
 
const uint16_t kInaxHdrMark = 9000
 
const uint16_t kInaxHdrSpace = 4500
 
const uint16_t kInaxBitMark = 560
 
const uint16_t kInaxOneSpace = 1675
 
const uint16_t kInaxZeroSpace = kInaxBitMark
 
const uint16_t kInaxMinGap = 40000
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kInaxBitMark

+ +
+
+ + + + +
const uint16_t kInaxBitMark = 560
+
+ +
+
+ +

◆ kInaxHdrMark

+ +
+
+ + + + +
const uint16_t kInaxHdrMark = 9000
+
+ +
+
+ +

◆ kInaxHdrSpace

+ +
+
+ + + + +
const uint16_t kInaxHdrSpace = 4500
+
+ +
+
+ +

◆ kInaxMinGap

+ +
+
+ + + + +
const uint16_t kInaxMinGap = 40000
+
+ +
+
+ +

◆ kInaxOneSpace

+ +
+
+ + + + +
const uint16_t kInaxOneSpace = 1675
+
+ +
+
+ +

◆ kInaxTick

+ +
+
+ + + + +
const uint16_t kInaxTick = 500
+
+ +
+
+ +

◆ kInaxZeroSpace

+ +
+
+ + + + +
const uint16_t kInaxZeroSpace = kInaxBitMark
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__JVC_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__JVC_8cpp.html new file mode 100644 index 000000000..0392fa940 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__JVC_8cpp.html @@ -0,0 +1,343 @@ + + + + + + + +IRremoteESP8266: src/ir_JVC.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_JVC.cpp File Reference
+
+
+ +

Support for JVC protocols. Originally added by Kristian Lauszus Thanks to zenwheel and other people at the original blog post. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kJvcTick = 75
 
const uint16_t kJvcHdrMarkTicks = 112
 
const uint16_t kJvcHdrMark = kJvcHdrMarkTicks * kJvcTick
 
const uint16_t kJvcHdrSpaceTicks = 56
 
const uint16_t kJvcHdrSpace = kJvcHdrSpaceTicks * kJvcTick
 
const uint16_t kJvcBitMarkTicks = 7
 
const uint16_t kJvcBitMark = kJvcBitMarkTicks * kJvcTick
 
const uint16_t kJvcOneSpaceTicks = 23
 
const uint16_t kJvcOneSpace = kJvcOneSpaceTicks * kJvcTick
 
const uint16_t kJvcZeroSpaceTicks = 7
 
const uint16_t kJvcZeroSpace = kJvcZeroSpaceTicks * kJvcTick
 
const uint16_t kJvcRptLengthTicks = 800
 
const uint16_t kJvcRptLength = kJvcRptLengthTicks * kJvcTick
 
const uint16_t kJvcMinGapTicks
 
const uint16_t kJvcMinGap = kJvcMinGapTicks * kJvcTick
 
+

Detailed Description

+

Support for JVC protocols. Originally added by Kristian Lauszus Thanks to zenwheel and other people at the original blog post.

+
See also
http://www.sbprojects.com/knowledge/ir/jvc.php
+

Variable Documentation

+ +

◆ kJvcBitMark

+ +
+
+ + + + +
const uint16_t kJvcBitMark = kJvcBitMarkTicks * kJvcTick
+
+ +
+
+ +

◆ kJvcBitMarkTicks

+ +
+
+ + + + +
const uint16_t kJvcBitMarkTicks = 7
+
+ +
+
+ +

◆ kJvcHdrMark

+ +
+
+ + + + +
const uint16_t kJvcHdrMark = kJvcHdrMarkTicks * kJvcTick
+
+ +
+
+ +

◆ kJvcHdrMarkTicks

+ +
+
+ + + + +
const uint16_t kJvcHdrMarkTicks = 112
+
+ +
+
+ +

◆ kJvcHdrSpace

+ +
+
+ + + + +
const uint16_t kJvcHdrSpace = kJvcHdrSpaceTicks * kJvcTick
+
+ +
+
+ +

◆ kJvcHdrSpaceTicks

+ +
+
+ + + + +
const uint16_t kJvcHdrSpaceTicks = 56
+
+ +
+
+ +

◆ kJvcMinGap

+ +
+
+ + + + +
const uint16_t kJvcMinGap = kJvcMinGapTicks * kJvcTick
+
+ +
+
+ +

◆ kJvcMinGapTicks

+ +
+
+ + + + +
const uint16_t kJvcMinGapTicks
+
+
+ +

◆ kJvcOneSpace

+ +
+
+ + + + +
const uint16_t kJvcOneSpace = kJvcOneSpaceTicks * kJvcTick
+
+ +
+
+ +

◆ kJvcOneSpaceTicks

+ +
+
+ + + + +
const uint16_t kJvcOneSpaceTicks = 23
+
+ +
+
+ +

◆ kJvcRptLength

+ +
+
+ + + + +
const uint16_t kJvcRptLength = kJvcRptLengthTicks * kJvcTick
+
+ +
+
+ +

◆ kJvcRptLengthTicks

+ +
+
+ + + + +
const uint16_t kJvcRptLengthTicks = 800
+
+ +
+
+ +

◆ kJvcTick

+ +
+
+ + + + +
const uint16_t kJvcTick = 75
+
+ +
+
+ +

◆ kJvcZeroSpace

+ +
+
+ + + + +
const uint16_t kJvcZeroSpace = kJvcZeroSpaceTicks * kJvcTick
+
+ +
+
+ +

◆ kJvcZeroSpaceTicks

+ +
+
+ + + + +
const uint16_t kJvcZeroSpaceTicks = 7
+
+ +
+
+
+
const uint16_t kJvcHdrSpaceTicks
Definition: ir_JVC.cpp:23
+
const uint16_t kJvcBitMarkTicks
Definition: ir_JVC.cpp:25
+
const uint16_t kJvcBits
Definition: IRremoteESP8266.h:909
+
const uint16_t kJvcOneSpaceTicks
Definition: ir_JVC.cpp:27
+
const uint16_t kJvcHdrMarkTicks
Definition: ir_JVC.cpp:21
+
const uint16_t kJvcRptLengthTicks
Definition: ir_JVC.cpp:31
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Kelvinator_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Kelvinator_8cpp.html new file mode 100644 index 000000000..2fabc1753 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Kelvinator_8cpp.html @@ -0,0 +1,569 @@ + + + + + + + +IRremoteESP8266: src/ir_Kelvinator.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Kelvinator.cpp File Reference
+
+
+ +

Support for Kelvinator A/C protocols. Code to emulate IR Kelvinator YALIF remote control unit, which should control at least the following Kelvinator A/C units: KSV26CRC, KSV26HRC, KSV35CRC, KSV35HRC, KSV53HRC, KSV62HRC, KSV70CRC, KSV70HRC, KSV80HRC. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kKelvinatorTick = 85
 
const uint16_t kKelvinatorHdrMarkTicks = 106
 
const uint16_t kKelvinatorHdrMark = kKelvinatorHdrMarkTicks * kKelvinatorTick
 
const uint16_t kKelvinatorHdrSpaceTicks = 53
 
const uint16_t kKelvinatorHdrSpace = kKelvinatorHdrSpaceTicks * kKelvinatorTick
 
const uint16_t kKelvinatorBitMarkTicks = 8
 
const uint16_t kKelvinatorBitMark = kKelvinatorBitMarkTicks * kKelvinatorTick
 
const uint16_t kKelvinatorOneSpaceTicks = 18
 
const uint16_t kKelvinatorOneSpace = kKelvinatorOneSpaceTicks * kKelvinatorTick
 
const uint16_t kKelvinatorZeroSpaceTicks = 6
 
const uint16_t kKelvinatorZeroSpace
 
const uint16_t kKelvinatorGapSpaceTicks = 235
 
const uint16_t kKelvinatorGapSpace = kKelvinatorGapSpaceTicks * kKelvinatorTick
 
const uint8_t kKelvinatorCmdFooter = 2
 
const uint8_t kKelvinatorCmdFooterBits = 3
 
const uint8_t kKelvinatorModeOffset = 0
 
const uint8_t kKelvinatorPowerOffset = 3
 
const uint8_t kKelvinatorFanOffset = 4
 
const uint8_t kKelvinatorFanSize = 3
 
const uint8_t kKelvinatorBasicFanSize = 2
 
const uint8_t kKelvinatorChecksumStart = 10
 
const uint8_t kKelvinatorVentSwingOffset = 6
 
const uint8_t kKelvinatorVentSwingVOffset = 0
 
const uint8_t kKelvinatorVentSwingHOffset = 4
 
const uint8_t kKelvinatorQuietOffset = 7
 
const uint8_t kKelvinatorIonFilterOffset = 6
 
const uint8_t kKelvinatorLightOffset = 5
 
const uint8_t kKelvinatorXfanOffset = 7
 
const uint8_t kKelvinatorTurboOffset = 4
 
+

Detailed Description

+

Support for Kelvinator A/C protocols. Code to emulate IR Kelvinator YALIF remote control unit, which should control at least the following Kelvinator A/C units: KSV26CRC, KSV26HRC, KSV35CRC, KSV35HRC, KSV53HRC, KSV62HRC, KSV70CRC, KSV70HRC, KSV80HRC.

+
Note
Unsupported:
    +
  • All Sleep modes.
  • +
  • All Timer modes.
  • +
  • "I Feel" button & mode.
  • +
  • Energy Saving mode.
  • +
  • Low Heat mode.
  • +
  • Fahrenheit.
  • +
+
+

Variable Documentation

+ +

◆ kKelvinatorBasicFanSize

+ +
+
+ + + + +
const uint8_t kKelvinatorBasicFanSize = 2
+
+ +
+
+ +

◆ kKelvinatorBitMark

+ +
+
+ + + + +
const uint16_t kKelvinatorBitMark = kKelvinatorBitMarkTicks * kKelvinatorTick
+
+ +
+
+ +

◆ kKelvinatorBitMarkTicks

+ +
+
+ + + + +
const uint16_t kKelvinatorBitMarkTicks = 8
+
+ +
+
+ +

◆ kKelvinatorChecksumStart

+ +
+
+ + + + +
const uint8_t kKelvinatorChecksumStart = 10
+
+ +
+
+ +

◆ kKelvinatorCmdFooter

+ +
+
+ + + + +
const uint8_t kKelvinatorCmdFooter = 2
+
+ +
+
+ +

◆ kKelvinatorCmdFooterBits

+ +
+
+ + + + +
const uint8_t kKelvinatorCmdFooterBits = 3
+
+ +
+
+ +

◆ kKelvinatorFanOffset

+ +
+
+ + + + +
const uint8_t kKelvinatorFanOffset = 4
+
+ +
+
+ +

◆ kKelvinatorFanSize

+ +
+
+ + + + +
const uint8_t kKelvinatorFanSize = 3
+
+ +
+
+ +

◆ kKelvinatorGapSpace

+ +
+
+ + + + +
const uint16_t kKelvinatorGapSpace = kKelvinatorGapSpaceTicks * kKelvinatorTick
+
+ +
+
+ +

◆ kKelvinatorGapSpaceTicks

+ +
+
+ + + + +
const uint16_t kKelvinatorGapSpaceTicks = 235
+
+ +
+
+ +

◆ kKelvinatorHdrMark

+ +
+
+ + + + +
const uint16_t kKelvinatorHdrMark = kKelvinatorHdrMarkTicks * kKelvinatorTick
+
+ +
+
+ +

◆ kKelvinatorHdrMarkTicks

+ +
+
+ + + + +
const uint16_t kKelvinatorHdrMarkTicks = 106
+
+ +
+
+ +

◆ kKelvinatorHdrSpace

+ +
+
+ + + + +
const uint16_t kKelvinatorHdrSpace = kKelvinatorHdrSpaceTicks * kKelvinatorTick
+
+ +
+
+ +

◆ kKelvinatorHdrSpaceTicks

+ +
+
+ + + + +
const uint16_t kKelvinatorHdrSpaceTicks = 53
+
+ +
+
+ +

◆ kKelvinatorIonFilterOffset

+ +
+
+ + + + +
const uint8_t kKelvinatorIonFilterOffset = 6
+
+ +
+
+ +

◆ kKelvinatorLightOffset

+ +
+
+ + + + +
const uint8_t kKelvinatorLightOffset = 5
+
+ +
+
+ +

◆ kKelvinatorModeOffset

+ +
+
+ + + + +
const uint8_t kKelvinatorModeOffset = 0
+
+ +
+
+ +

◆ kKelvinatorOneSpace

+ +
+
+ + + + +
const uint16_t kKelvinatorOneSpace = kKelvinatorOneSpaceTicks * kKelvinatorTick
+
+ +
+
+ +

◆ kKelvinatorOneSpaceTicks

+ +
+
+ + + + +
const uint16_t kKelvinatorOneSpaceTicks = 18
+
+ +
+
+ +

◆ kKelvinatorPowerOffset

+ +
+
+ + + + +
const uint8_t kKelvinatorPowerOffset = 3
+
+ +
+
+ +

◆ kKelvinatorQuietOffset

+ +
+
+ + + + +
const uint8_t kKelvinatorQuietOffset = 7
+
+ +
+
+ +

◆ kKelvinatorTick

+ +
+
+ + + + +
const uint16_t kKelvinatorTick = 85
+
+ +
+
+ +

◆ kKelvinatorTurboOffset

+ +
+
+ + + + +
const uint8_t kKelvinatorTurboOffset = 4
+
+ +
+
+ +

◆ kKelvinatorVentSwingHOffset

+ +
+
+ + + + +
const uint8_t kKelvinatorVentSwingHOffset = 4
+
+ +
+
+ +

◆ kKelvinatorVentSwingOffset

+ +
+
+ + + + +
const uint8_t kKelvinatorVentSwingOffset = 6
+
+ +
+
+ +

◆ kKelvinatorVentSwingVOffset

+ +
+
+ + + + +
const uint8_t kKelvinatorVentSwingVOffset = 0
+
+ +
+
+ +

◆ kKelvinatorXfanOffset

+ +
+
+ + + + +
const uint8_t kKelvinatorXfanOffset = 7
+
+ +
+
+ +

◆ kKelvinatorZeroSpace

+ +
+
+ + + + +
const uint16_t kKelvinatorZeroSpace
+
+Initial value: +
+
+ +

◆ kKelvinatorZeroSpaceTicks

+ +
+
+ + + + +
const uint16_t kKelvinatorZeroSpaceTicks = 6
+
+ +
+
+
+
const uint16_t kKelvinatorZeroSpaceTicks
Definition: ir_Kelvinator.cpp:39
+
const uint16_t kKelvinatorTick
Definition: ir_Kelvinator.cpp:30
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Kelvinator_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Kelvinator_8h.html new file mode 100644 index 000000000..3feaa32f7 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Kelvinator_8h.html @@ -0,0 +1,293 @@ + + + + + + + +IRremoteESP8266: src/ir_Kelvinator.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Kelvinator.h File Reference
+
+
+ +

Support for Kelvinator A/C protocols. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRKelvinatorAC
 Class for handling detailed Kelvinator A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kKelvinatorAuto = 0
 
const uint8_t kKelvinatorCool = 1
 
const uint8_t kKelvinatorDry = 2
 
const uint8_t kKelvinatorFan = 3
 
const uint8_t kKelvinatorHeat = 4
 
const uint8_t kKelvinatorBasicFanMax = 3
 
const uint8_t kKelvinatorFanAuto = 0
 
const uint8_t kKelvinatorFanMin = 1
 
const uint8_t kKelvinatorFanMax = 5
 
const uint8_t kKelvinatorMinTemp = 16
 
const uint8_t kKelvinatorMaxTemp = 30
 
const uint8_t kKelvinatorAutoTemp = 25
 
+

Detailed Description

+

Support for Kelvinator A/C protocols.

+

Variable Documentation

+ +

◆ kKelvinatorAuto

+ +
+
+ + + + +
const uint8_t kKelvinatorAuto = 0
+
+ +
+
+ +

◆ kKelvinatorAutoTemp

+ +
+
+ + + + +
const uint8_t kKelvinatorAutoTemp = 25
+
+ +
+
+ +

◆ kKelvinatorBasicFanMax

+ +
+
+ + + + +
const uint8_t kKelvinatorBasicFanMax = 3
+
+ +
+
+ +

◆ kKelvinatorCool

+ +
+
+ + + + +
const uint8_t kKelvinatorCool = 1
+
+ +
+
+ +

◆ kKelvinatorDry

+ +
+
+ + + + +
const uint8_t kKelvinatorDry = 2
+
+ +
+
+ +

◆ kKelvinatorFan

+ +
+
+ + + + +
const uint8_t kKelvinatorFan = 3
+
+ +
+
+ +

◆ kKelvinatorFanAuto

+ +
+
+ + + + +
const uint8_t kKelvinatorFanAuto = 0
+
+ +
+
+ +

◆ kKelvinatorFanMax

+ +
+
+ + + + +
const uint8_t kKelvinatorFanMax = 5
+
+ +
+
+ +

◆ kKelvinatorFanMin

+ +
+
+ + + + +
const uint8_t kKelvinatorFanMin = 1
+
+ +
+
+ +

◆ kKelvinatorHeat

+ +
+
+ + + + +
const uint8_t kKelvinatorHeat = 4
+
+ +
+
+ +

◆ kKelvinatorMaxTemp

+ +
+
+ + + + +
const uint8_t kKelvinatorMaxTemp = 30
+
+ +
+
+ +

◆ kKelvinatorMinTemp

+ +
+
+ + + + +
const uint8_t kKelvinatorMinTemp = 16
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Kelvinator_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Kelvinator_8h_source.html new file mode 100644 index 000000000..16ffcfeef --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Kelvinator_8h_source.html @@ -0,0 +1,336 @@ + + + + + + + +IRremoteESP8266: src/ir_Kelvinator.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Kelvinator.h
+
+
+Go to the documentation of this file.
1 // Copyright 2016 David Conran
+
4 
+
5 // Supports:
+
6 // Brand: Kelvinator, Model: YALIF Remote
+
7 // Brand: Kelvinator, Model: KSV26CRC A/C
+
8 // Brand: Kelvinator, Model: KSV26HRC A/C
+
9 // Brand: Kelvinator, Model: KSV35CRC A/C
+
10 // Brand: Kelvinator, Model: KSV35HRC A/C
+
11 // Brand: Kelvinator, Model: KSV53HRC A/C
+
12 // Brand: Kelvinator, Model: KSV62HRC A/C
+
13 // Brand: Kelvinator, Model: KSV70CRC A/C
+
14 // Brand: Kelvinator, Model: KSV70HRC A/C
+
15 // Brand: Kelvinator, Model: KSV80HRC A/C
+
16 // Brand: Green, Model: YAPOF3 remote
+
17 
+
18 #ifndef IR_KELVINATOR_H_
+
19 #define IR_KELVINATOR_H_
+
20 
+
21 #define __STDC_LIMIT_MACROS
+
22 #include <stdint.h>
+
23 #ifndef UNIT_TEST
+
24 #include <Arduino.h>
+
25 #endif
+
26 #include "IRremoteESP8266.h"
+
27 #include "IRsend.h"
+
28 #ifdef UNIT_TEST
+
29 #include "IRsend_test.h"
+
30 #endif
+
31 
+
32 // Constants
+
33 const uint8_t kKelvinatorAuto = 0;
+
34 const uint8_t kKelvinatorCool = 1;
+
35 const uint8_t kKelvinatorDry = 2;
+
36 const uint8_t kKelvinatorFan = 3;
+
37 const uint8_t kKelvinatorHeat = 4;
+
38 const uint8_t kKelvinatorBasicFanMax = 3;
+
39 const uint8_t kKelvinatorFanAuto = 0;
+
40 const uint8_t kKelvinatorFanMin = 1;
+
41 const uint8_t kKelvinatorFanMax = 5;
+
42 const uint8_t kKelvinatorMinTemp = 16; // 16C
+
43 const uint8_t kKelvinatorMaxTemp = 30; // 30C
+
44 const uint8_t kKelvinatorAutoTemp = 25; // 25C
+
45 
+
46 // Legacy defines (Deprecated)
+
47 #define KELVINATOR_MIN_TEMP kKelvinatorMinTemp
+
48 #define KELVINATOR_MAX_TEMP kKelvinatorMaxTemp
+
49 #define KELVINATOR_HEAT kKelvinatorHeat
+
50 #define KELVINATOR_FAN_MAX kKelvinatorFanMax
+
51 #define KELVINATOR_FAN_AUTO kKelvinatorFanAuto
+
52 #define KELVINATOR_FAN kKelvinatorFan
+
53 #define KELVINATOR_DRY kKelvinatorDry
+
54 #define KELVINATOR_COOL kKelvinatorCool
+
55 #define KELVINATOR_BASIC_FAN_MAX kKelvinatorBasicFanMax
+
56 #define KELVINATOR_AUTO_TEMP kKelvinatorAutoTemp
+
57 #define KELVINATOR_AUTO kKelvinatorAuto
+
58 
+
59 /*
+
60  Kelvinator AC map
+
61 
+
62  (header mark and space)
+
63  byte 0 = Basic Modes
+
64  b2-0 = Modes
+
65  Modes:
+
66  000 = Auto (temp = 25C)
+
67  001 = Cool
+
68  010 = Dry (temp = 25C, but not shown)
+
69  011 = Fan
+
70  100 = Heat
+
71  b3 = Power Status (1 = On, 0 = Off)
+
72  b5-4 = Fan (Basic modes)
+
73  Fan:
+
74  00 = Auto
+
75  01 = Fan 1
+
76  10 = Fan 2
+
77  11 = Fan 3 or higher (See byte 14)
+
78  b6 = Vent swing (1 = On, 0 = Off) (See byte 4)
+
79  b7 = Sleep Modes 1 & 3 (1 = On, 0 = Off)
+
80  byte 1 = Temperature
+
81  b3-0: Degrees C.
+
82  0000 (0) = 16C
+
83  0001 (1) = 17C
+
84  0010 (2) = 18C
+
85  ...
+
86  1101 (13) = 29C
+
87  1110 (14) = 30C
+
88  byte 2 = Extras
+
89  b3-0 = UNKNOWN, typically 0.
+
90  b4 = Turbo Fan (1 = On, 0 = Off)
+
91  b5 = Light (Display) (1 = On, 0 = Off)
+
92  b6 = Ion Filter (1 = On, 0 = Off)
+
93  b7 = X-Fan (Fan runs for a while after power off) (1 = On, 0 = Off)
+
94  byte 3 = Section Indicator
+
95  b3-0 = Unused (Typically 0)
+
96  b5-4 = Unknown (possibly timer related) (Typically 0b01)
+
97  b7-6 = End of command block (B01)
+
98  (B010 marker and a gap of 20ms)
+
99  byte 4 = Extended options
+
100  b0 = Swing Vent Vertical (1 = On, 0 = Off)
+
101  b4 = Swing Vent Horizontal (1 = On, 0 = Off)
+
102  byte 5-6 = Timer related. Typically 0 except when timer in use.
+
103  byte 7 = checksum
+
104  b3-0 = Unknown (Used in Timer mode)
+
105  b7-4 = checksum of the previous bytes (0-6)
+
106  (gap of 40ms)
+
107  (header mark and space)
+
108  byte 8 = Repeat of byte 0
+
109  byte 9 = Repeat of byte 1
+
110  byte 10 = Repeat of byte 2
+
111  byte 11 = Section Indicator
+
112  b3-0 = Unused (Typically 0)
+
113  b5-4 = Unknown (possibly timer related) (Typically 0b11)
+
114  b7-6 = End of command block (B01)
+
115  (B010 marker and a gap of 20ms)
+
116  byte 12 = Extended options
+
117  b0 = Sleep mode 2 (1 = On, 0=Off)
+
118  b6-1 = Unknown (Used in Sleep Mode 3, Typically 0b000000)
+
119  b7 = Quiet Mode (1 = On, 0=Off)
+
120  byte 13 = Unknown (Sleep Mode 3 related, Typically 0x00)
+
121  byte 14 = Fan control
+
122  b3-0 = Unknown (Sleep Mode 3 related, Typically 0b0000)
+
123  b6-4 = Fan speed
+
124  0b000 (0) = Automatic
+
125  0b001 (1) = Fan 1
+
126  0b010 (2) = Fan 2
+
127  0b011 (3) = Fan 3
+
128  0b100 (4) = Fan 4
+
129  0b101 (5) = Fan 5
+
130  byte 15 = checksum
+
131  b3-0 = Unknown (Typically 0b0000)
+
132  b7-4 = checksum of the previous bytes (8-14)
+
133 */
+
134 
+
135 // Classes
+ +
138  public:
+
139  explicit IRKelvinatorAC(const uint16_t pin, const bool inverted = false,
+
140  const bool use_modulation = true);
+
141  void stateReset(void);
+
142 #if SEND_KELVINATOR
+
143  void send(const uint16_t repeat = kKelvinatorDefaultRepeat);
+
148  int8_t calibrate(void) { return _irsend.calibrate(); }
+
149 #endif // SEND_KELVINATOR
+
150  void begin(void);
+
151  void on(void);
+
152  void off(void);
+
153  void setPower(const bool on);
+
154  bool getPower(void);
+
155  void setTemp(const uint8_t degrees);
+
156  uint8_t getTemp(void);
+
157  void setFan(const uint8_t speed);
+
158  uint8_t getFan(void);
+
159  void setMode(const uint8_t mode);
+
160  uint8_t getMode(void);
+
161  void setSwingVertical(const bool on);
+
162  bool getSwingVertical(void);
+
163  void setSwingHorizontal(const bool on);
+
164  bool getSwingHorizontal(void);
+
165  void setQuiet(const bool on);
+
166  bool getQuiet(void);
+
167  void setIonFilter(const bool on);
+
168  bool getIonFilter(void);
+
169  void setLight(const bool on);
+
170  bool getLight(void);
+
171  void setXFan(const bool on);
+
172  bool getXFan(void);
+
173  void setTurbo(const bool on);
+
174  bool getTurbo(void);
+
175  uint8_t* getRaw(void);
+
176  void setRaw(const uint8_t new_code[]);
+
177  static uint8_t calcBlockChecksum(
+
178  const uint8_t* block, const uint16_t length = kKelvinatorStateLength / 2);
+
179  static bool validChecksum(const uint8_t state[],
+
180  const uint16_t length = kKelvinatorStateLength);
+
181  uint8_t convertMode(const stdAc::opmode_t mode);
+
182  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
183  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
184  stdAc::state_t toCommon(void);
+
185  String toString(void);
+
186 #ifndef UNIT_TEST
+
187 
+
188  private:
+ +
190 #else // UNIT_TEST
+
191  IRsendTest _irsend;
+
193 #endif // UNIT_TEST
+ +
196  void checksum(const uint16_t length = kKelvinatorStateLength);
+
197  void fixup(void);
+
198 };
+
199 
+
200 #endif // IR_KELVINATOR_H_
+
+
void setSwingHorizontal(const bool on)
Control the current horizontal swing setting.
Definition: ir_Kelvinator.cpp:314
+
void stateReset(void)
Reset the internals of the object to a known good state.
Definition: ir_Kelvinator.cpp:129
+
void checksum(const uint16_t length=kKelvinatorStateLength)
Calculate the checksum for the internal state.
Definition: ir_Kelvinator.cpp:188
+
bool getTurbo(void)
Is the Turbo setting on?
Definition: ir_Kelvinator.cpp:392
+
void setTurbo(const bool on)
Control the current Turbo setting.
Definition: ir_Kelvinator.cpp:385
+
bool getSwingVertical(void)
Is the vertical swing setting on?
Definition: ir_Kelvinator.cpp:308
+
const uint8_t kKelvinatorFanAuto
Definition: ir_Kelvinator.h:39
+
void on(void)
Set the internal state to have the power on.
Definition: ir_Kelvinator.cpp:212
+
const uint8_t kKelvinatorFanMax
Definition: ir_Kelvinator.h:41
+
const uint8_t kKelvinatorCool
Definition: ir_Kelvinator.h:34
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
void setLight(const bool on)
Control the current Light setting. i.e. The LED display on the A/C unit that shows the basic settings...
Definition: ir_Kelvinator.cpp:355
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed to it's stdAc::fanspeed_t equivalent.
Definition: ir_Kelvinator.cpp:425
+
const uint8_t kKelvinatorAutoTemp
Definition: ir_Kelvinator.h:44
+
uint8_t * getRaw(void)
Get the raw state of the object, suitable to be sent with the appropriate IRsend object method.
Definition: ir_Kelvinator.cpp:158
+ +
void setIonFilter(const bool on)
Control the current Ion Filter setting.
Definition: ir_Kelvinator.cpp:341
+
void setFan(const uint8_t speed)
Set the speed of the fan.
Definition: ir_Kelvinator.cpp:248
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
const uint8_t kKelvinatorMinTemp
Definition: ir_Kelvinator.h:42
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Kelvinator.h:148
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
std::string String
Definition: IRremoteESP8266.h:1093
+
void setPower(const bool on)
Set the internal state to have the desired power.
Definition: ir_Kelvinator.cpp:219
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Kelvinator.cpp:266
+
void setMode(const uint8_t mode)
Set the desired operation mode.
Definition: ir_Kelvinator.cpp:278
+
void send(const uint16_t repeat=kKelvinatorDefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Kelvinator.cpp:149
+
void setRaw(const uint8_t new_code[])
Set the raw state of the object.
Definition: ir_Kelvinator.cpp:165
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Kelvinator.cpp:136
+
uint8_t getMode(void)
Get the current operation mode setting.
Definition: ir_Kelvinator.cpp:272
+
static uint8_t calcBlockChecksum(const uint8_t *block, const uint16_t length=kKelvinatorStateLength/2)
Calculate the checksum for a given block of state.
Definition: ir_Kelvinator.cpp:174
+ +
IRsend _irsend
Instance of the IR send class.
Definition: ir_Kelvinator.h:189
+
bool getPower(void)
Get the power setting from the internal state.
Definition: ir_Kelvinator.cpp:226
+
static bool validChecksum(const uint8_t state[], const uint16_t length=kKelvinatorStateLength)
Verify the checksum is valid for a given state.
Definition: ir_Kelvinator.cpp:200
+
Class for handling detailed Kelvinator A/C messages.
Definition: ir_Kelvinator.h:137
+
const uint8_t kKelvinatorMaxTemp
Definition: ir_Kelvinator.h:43
+
void fixup(void)
Fix up any odd conditions for the current state.
Definition: ir_Kelvinator.cpp:139
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Kelvinator.cpp:241
+
const uint16_t kKelvinatorStateLength
Definition: IRremoteESP8266.h:910
+
stdAc::state_t toCommon(void)
Convert the internal A/C object state to it's stdAc::state_t equivalent.
Definition: ir_Kelvinator.cpp:431
+
void setQuiet(const bool on)
Control the current Quiet setting.
Definition: ir_Kelvinator.cpp:329
+
void setXFan(const bool on)
Control the current XFan setting. This setting will cause the unit blow air after power off to dry ou...
Definition: ir_Kelvinator.cpp:371
+
const uint8_t kKelvinatorFan
Definition: ir_Kelvinator.h:36
+
void setTemp(const uint8_t degrees)
Set the temperature setting.
Definition: ir_Kelvinator.cpp:232
+
const uint8_t kKelvinatorBasicFanMax
Definition: ir_Kelvinator.h:38
+
const uint8_t kKelvinatorFanMin
Definition: ir_Kelvinator.h:40
+
bool getLight(void)
Is the Light (Display) setting on?
Definition: ir_Kelvinator.cpp:362
+
const uint8_t kKelvinatorHeat
Definition: ir_Kelvinator.h:37
+
IRKelvinatorAC(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Kelvinator.cpp:124
+
void off(void)
Set the internal state to have the power off.
Definition: ir_Kelvinator.cpp:215
+
const uint16_t kKelvinatorDefaultRepeat
Definition: IRremoteESP8266.h:912
+
uint8_t remote_state[kKelvinatorStateLength]
The state in IR code form.
Definition: ir_Kelvinator.h:195
+
void setSwingVertical(const bool on)
Control the current vertical swing setting.
Definition: ir_Kelvinator.cpp:299
+
const uint8_t kKelvinatorDry
Definition: ir_Kelvinator.h:35
+
bool getIonFilter(void)
Is the Ion Filter setting on?
Definition: ir_Kelvinator.cpp:348
+
String toString(void)
Convert the internal settings into a human readable string.
Definition: ir_Kelvinator.cpp:459
+
bool getXFan(void)
Is the XFan setting on?
Definition: ir_Kelvinator.cpp:378
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode to it's stdAc::opmode_t equivalent.
Definition: ir_Kelvinator.cpp:412
+
bool getQuiet(void)
Is the Quiet setting on?
Definition: ir_Kelvinator.cpp:335
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
bool getSwingHorizontal(void)
Is the horizontal swing setting on?
Definition: ir_Kelvinator.cpp:323
+
const uint8_t kKelvinatorAuto
Definition: ir_Kelvinator.h:33
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a standard A/C mode (stdAc::opmode_t) into it a native mode.
Definition: ir_Kelvinator.cpp:399
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__LG_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__LG_8cpp.html new file mode 100644 index 000000000..3613112d7 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__LG_8cpp.html @@ -0,0 +1,557 @@ + + + + + + + +IRremoteESP8266: src/ir_LG.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_LG.cpp File Reference
+
+
+ +

Support for LG protocols. LG decode originally added by Darryl Smith (based on the JVC protocol) LG send originally added by https://github.com/chaeplin. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kLgTick = 50
 
const uint16_t kLgHdrMarkTicks = 170
 
const uint16_t kLgHdrMark = kLgHdrMarkTicks * kLgTick
 
const uint16_t kLgHdrSpaceTicks = 85
 
const uint16_t kLgHdrSpace = kLgHdrSpaceTicks * kLgTick
 
const uint16_t kLgBitMarkTicks = 11
 
const uint16_t kLgBitMark = kLgBitMarkTicks * kLgTick
 
const uint16_t kLgOneSpaceTicks = 32
 
const uint16_t kLgOneSpace = kLgOneSpaceTicks * kLgTick
 
const uint16_t kLgZeroSpaceTicks = 11
 
const uint16_t kLgZeroSpace = kLgZeroSpaceTicks * kLgTick
 
const uint16_t kLgRptSpaceTicks = 45
 
const uint16_t kLgRptSpace = kLgRptSpaceTicks * kLgTick
 
const uint16_t kLgMinGapTicks = 795
 
const uint16_t kLgMinGap = kLgMinGapTicks * kLgTick
 
const uint16_t kLgMinMessageLengthTicks = 2161
 
const uint32_t kLgMinMessageLength = kLgMinMessageLengthTicks * kLgTick
 
const uint16_t kLg32HdrMarkTicks = 90
 
const uint16_t kLg32HdrMark = kLg32HdrMarkTicks * kLgTick
 
const uint16_t kLg32HdrSpaceTicks = 89
 
const uint16_t kLg32HdrSpace = kLg32HdrSpaceTicks * kLgTick
 
const uint16_t kLg32RptHdrMarkTicks = 179
 
const uint16_t kLg32RptHdrMark = kLg32RptHdrMarkTicks * kLgTick
 
const uint16_t kLg2HdrMarkTicks = 64
 
const uint16_t kLg2HdrMark = kLg2HdrMarkTicks * kLgTick
 
const uint16_t kLg2HdrSpaceTicks = 197
 
const uint16_t kLg2HdrSpace = kLg2HdrSpaceTicks * kLgTick
 
const uint16_t kLg2BitMarkTicks = 10
 
const uint16_t kLg2BitMark = kLg2BitMarkTicks * kLgTick
 
+

Detailed Description

+

Support for LG protocols. LG decode originally added by Darryl Smith (based on the JVC protocol) LG send originally added by https://github.com/chaeplin.

+
See also
https://github.com/arendst/Tasmota/blob/54c2eb283a02e4287640a4595e506bc6eadbd7f2/sonoff/xdrv_05_irremote.ino#L327-438
+

Variable Documentation

+ +

◆ kLg2BitMark

+ +
+
+ + + + +
const uint16_t kLg2BitMark = kLg2BitMarkTicks * kLgTick
+
+ +
+
+ +

◆ kLg2BitMarkTicks

+ +
+
+ + + + +
const uint16_t kLg2BitMarkTicks = 10
+
+ +
+
+ +

◆ kLg2HdrMark

+ +
+
+ + + + +
const uint16_t kLg2HdrMark = kLg2HdrMarkTicks * kLgTick
+
+ +
+
+ +

◆ kLg2HdrMarkTicks

+ +
+
+ + + + +
const uint16_t kLg2HdrMarkTicks = 64
+
+ +
+
+ +

◆ kLg2HdrSpace

+ +
+
+ + + + +
const uint16_t kLg2HdrSpace = kLg2HdrSpaceTicks * kLgTick
+
+ +
+
+ +

◆ kLg2HdrSpaceTicks

+ +
+
+ + + + +
const uint16_t kLg2HdrSpaceTicks = 197
+
+ +
+
+ +

◆ kLg32HdrMark

+ +
+
+ + + + +
const uint16_t kLg32HdrMark = kLg32HdrMarkTicks * kLgTick
+
+ +
+
+ +

◆ kLg32HdrMarkTicks

+ +
+
+ + + + +
const uint16_t kLg32HdrMarkTicks = 90
+
+ +
+
+ +

◆ kLg32HdrSpace

+ +
+
+ + + + +
const uint16_t kLg32HdrSpace = kLg32HdrSpaceTicks * kLgTick
+
+ +
+
+ +

◆ kLg32HdrSpaceTicks

+ +
+
+ + + + +
const uint16_t kLg32HdrSpaceTicks = 89
+
+ +
+
+ +

◆ kLg32RptHdrMark

+ +
+
+ + + + +
const uint16_t kLg32RptHdrMark = kLg32RptHdrMarkTicks * kLgTick
+
+ +
+
+ +

◆ kLg32RptHdrMarkTicks

+ +
+
+ + + + +
const uint16_t kLg32RptHdrMarkTicks = 179
+
+ +
+
+ +

◆ kLgBitMark

+ +
+
+ + + + +
const uint16_t kLgBitMark = kLgBitMarkTicks * kLgTick
+
+ +
+
+ +

◆ kLgBitMarkTicks

+ +
+
+ + + + +
const uint16_t kLgBitMarkTicks = 11
+
+ +
+
+ +

◆ kLgHdrMark

+ +
+
+ + + + +
const uint16_t kLgHdrMark = kLgHdrMarkTicks * kLgTick
+
+ +
+
+ +

◆ kLgHdrMarkTicks

+ +
+
+ + + + +
const uint16_t kLgHdrMarkTicks = 170
+
+ +
+
+ +

◆ kLgHdrSpace

+ +
+
+ + + + +
const uint16_t kLgHdrSpace = kLgHdrSpaceTicks * kLgTick
+
+ +
+
+ +

◆ kLgHdrSpaceTicks

+ +
+
+ + + + +
const uint16_t kLgHdrSpaceTicks = 85
+
+ +
+
+ +

◆ kLgMinGap

+ +
+
+ + + + +
const uint16_t kLgMinGap = kLgMinGapTicks * kLgTick
+
+ +
+
+ +

◆ kLgMinGapTicks

+ +
+
+ + + + +
const uint16_t kLgMinGapTicks = 795
+
+ +
+
+ +

◆ kLgMinMessageLength

+ +
+
+ + + + +
const uint32_t kLgMinMessageLength = kLgMinMessageLengthTicks * kLgTick
+
+ +
+
+ +

◆ kLgMinMessageLengthTicks

+ +
+
+ + + + +
const uint16_t kLgMinMessageLengthTicks = 2161
+
+ +
+
+ +

◆ kLgOneSpace

+ +
+
+ + + + +
const uint16_t kLgOneSpace = kLgOneSpaceTicks * kLgTick
+
+ +
+
+ +

◆ kLgOneSpaceTicks

+ +
+
+ + + + +
const uint16_t kLgOneSpaceTicks = 32
+
+ +
+
+ +

◆ kLgRptSpace

+ +
+
+ + + + +
const uint16_t kLgRptSpace = kLgRptSpaceTicks * kLgTick
+
+ +
+
+ +

◆ kLgRptSpaceTicks

+ +
+
+ + + + +
const uint16_t kLgRptSpaceTicks = 45
+
+ +
+
+ +

◆ kLgTick

+ +
+
+ + + + +
const uint16_t kLgTick = 50
+
+ +
+
+ +

◆ kLgZeroSpace

+ +
+
+ + + + +
const uint16_t kLgZeroSpace = kLgZeroSpaceTicks * kLgTick
+
+ +
+
+ +

◆ kLgZeroSpaceTicks

+ +
+
+ + + + +
const uint16_t kLgZeroSpaceTicks = 11
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__LG_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__LG_8h.html new file mode 100644 index 000000000..76c02aabf --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__LG_8h.html @@ -0,0 +1,550 @@ + + + + + + + +IRremoteESP8266: src/ir_LG.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_LG.h File Reference
+
+
+ +

Support for LG protocols. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRLgAc
 Class for handling detailed LG A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kLgAcChecksumOffset = 0
 
const uint8_t kLgAcChecksumSize = kNibbleSize
 
const uint8_t kLgAcFanOffset = 4
 
const uint8_t kLgAcFanSize = 3
 
const uint8_t kLgAcFanLow = 0
 
const uint8_t kLgAcFanMedium = 2
 
const uint8_t kLgAcFanHigh = 4
 
const uint8_t kLgAcFanAuto = 5
 
const uint8_t kLgAcTempOffset = 8
 
const uint8_t kLgAcTempSize = 4
 
const uint8_t kLgAcTempAdjust = 15
 
const uint8_t kLgAcMinTemp = 16
 
const uint8_t kLgAcMaxTemp = 30
 
const uint8_t kLgAcModeOffset = 12
 
const uint8_t kLgAcModeSize = 3
 
const uint8_t kLgAcCool = 0
 
const uint8_t kLgAcDry = 1
 
const uint8_t kLgAcFan = 2
 
const uint8_t kLgAcAuto = 3
 
const uint8_t kLgAcHeat = 4
 
const uint8_t kLgAcPowerOffset = 18
 
const uint8_t kLgAcPowerSize = 2
 
const uint8_t kLgAcPowerOff = 3
 
const uint8_t kLgAcPowerOn = 0
 
const uint8_t kLgAcSignatureOffset = 20
 
const uint8_t kLgAcSignatureSize = 8
 
const uint8_t kLgAcSignature = 0x88
 
const uint32_t kLgAcOffCommand = 0x88C0051
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kLgAcAuto

+ +
+
+ + + + +
const uint8_t kLgAcAuto = 3
+
+ +
+
+ +

◆ kLgAcChecksumOffset

+ +
+
+ + + + +
const uint8_t kLgAcChecksumOffset = 0
+
+ +
+
+ +

◆ kLgAcChecksumSize

+ +
+
+ + + + +
const uint8_t kLgAcChecksumSize = kNibbleSize
+
+ +
+
+ +

◆ kLgAcCool

+ +
+
+ + + + +
const uint8_t kLgAcCool = 0
+
+ +
+
+ +

◆ kLgAcDry

+ +
+
+ + + + +
const uint8_t kLgAcDry = 1
+
+ +
+
+ +

◆ kLgAcFan

+ +
+
+ + + + +
const uint8_t kLgAcFan = 2
+
+ +
+
+ +

◆ kLgAcFanAuto

+ +
+
+ + + + +
const uint8_t kLgAcFanAuto = 5
+
+ +
+
+ +

◆ kLgAcFanHigh

+ +
+
+ + + + +
const uint8_t kLgAcFanHigh = 4
+
+ +
+
+ +

◆ kLgAcFanLow

+ +
+
+ + + + +
const uint8_t kLgAcFanLow = 0
+
+ +
+
+ +

◆ kLgAcFanMedium

+ +
+
+ + + + +
const uint8_t kLgAcFanMedium = 2
+
+ +
+
+ +

◆ kLgAcFanOffset

+ +
+
+ + + + +
const uint8_t kLgAcFanOffset = 4
+
+ +
+
+ +

◆ kLgAcFanSize

+ +
+
+ + + + +
const uint8_t kLgAcFanSize = 3
+
+ +
+
+ +

◆ kLgAcHeat

+ +
+
+ + + + +
const uint8_t kLgAcHeat = 4
+
+ +
+
+ +

◆ kLgAcMaxTemp

+ +
+
+ + + + +
const uint8_t kLgAcMaxTemp = 30
+
+ +
+
+ +

◆ kLgAcMinTemp

+ +
+
+ + + + +
const uint8_t kLgAcMinTemp = 16
+
+ +
+
+ +

◆ kLgAcModeOffset

+ +
+
+ + + + +
const uint8_t kLgAcModeOffset = 12
+
+ +
+
+ +

◆ kLgAcModeSize

+ +
+
+ + + + +
const uint8_t kLgAcModeSize = 3
+
+ +
+
+ +

◆ kLgAcOffCommand

+ +
+
+ + + + +
const uint32_t kLgAcOffCommand = 0x88C0051
+
+ +
+
+ +

◆ kLgAcPowerOff

+ +
+
+ + + + +
const uint8_t kLgAcPowerOff = 3
+
+ +
+
+ +

◆ kLgAcPowerOffset

+ +
+
+ + + + +
const uint8_t kLgAcPowerOffset = 18
+
+ +
+
+ +

◆ kLgAcPowerOn

+ +
+
+ + + + +
const uint8_t kLgAcPowerOn = 0
+
+ +
+
+ +

◆ kLgAcPowerSize

+ +
+
+ + + + +
const uint8_t kLgAcPowerSize = 2
+
+ +
+
+ +

◆ kLgAcSignature

+ +
+
+ + + + +
const uint8_t kLgAcSignature = 0x88
+
+ +
+
+ +

◆ kLgAcSignatureOffset

+ +
+
+ + + + +
const uint8_t kLgAcSignatureOffset = 20
+
+ +
+
+ +

◆ kLgAcSignatureSize

+ +
+
+ + + + +
const uint8_t kLgAcSignatureSize = 8
+
+ +
+
+ +

◆ kLgAcTempAdjust

+ +
+
+ + + + +
const uint8_t kLgAcTempAdjust = 15
+
+ +
+
+ +

◆ kLgAcTempOffset

+ +
+
+ + + + +
const uint8_t kLgAcTempOffset = 8
+
+ +
+
+ +

◆ kLgAcTempSize

+ +
+
+ + + + +
const uint8_t kLgAcTempSize = 4
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__LG_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__LG_8h_source.html new file mode 100644 index 000000000..05bcb6a1b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__LG_8h_source.html @@ -0,0 +1,262 @@ + + + + + + + +IRremoteESP8266: src/ir_LG.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_LG.h
+
+
+Go to the documentation of this file.
1 // Copyright 2017, 2019 David Conran
+
2 
+
6 
+
7 
+
8 // Supports:
+
9 // Brand: LG, Model: 6711A20083V remote (LG)
+
10 // Brand: LG, Model: AKB74395308 remote (LG2)
+
11 // Brand: LG, Model: S4-W12JA3AA A/C (LG2)
+
12 // Brand: LG, Model: AKB75215403 remote (LG2)
+
13 // Brand: General Electric, Model: AG1BH09AW101 Split A/C
+
14 // Brand: General Electric, Model: 6711AR2853M A/C Remote
+
15 
+
16 #ifndef IR_LG_H_
+
17 #define IR_LG_H_
+
18 
+
19 #define __STDC_LIMIT_MACROS
+
20 #include <stdint.h>
+
21 #ifndef UNIT_TEST
+
22 #include <Arduino.h>
+
23 #endif
+
24 #include "IRremoteESP8266.h"
+
25 #include "IRsend.h"
+
26 #include "IRutils.h"
+
27 #ifdef UNIT_TEST
+
28 #include "IRsend_test.h"
+
29 #endif
+
30 
+
31 const uint8_t kLgAcChecksumOffset = 0; // Nr. of bits
+
32 const uint8_t kLgAcChecksumSize = kNibbleSize; // Nr. of bits
+
33 const uint8_t kLgAcFanOffset = 4; // Nr. of bits
+
34 const uint8_t kLgAcFanSize = 3; // Nr. of bits
+
35 const uint8_t kLgAcFanLow = 0; // 0b000
+
36 const uint8_t kLgAcFanMedium = 2; // 0b010
+
37 const uint8_t kLgAcFanHigh = 4; // 0b100
+
38 const uint8_t kLgAcFanAuto = 5; // 0b101
+
39 const uint8_t kLgAcTempOffset = 8; // Nr. of bits
+
40 const uint8_t kLgAcTempSize = 4; // Nr. of bits
+
41 const uint8_t kLgAcTempAdjust = 15;
+
42 const uint8_t kLgAcMinTemp = 16; // Celsius
+
43 const uint8_t kLgAcMaxTemp = 30; // Celsius
+
44 const uint8_t kLgAcModeOffset = 12; // Nr. of bits
+
45 const uint8_t kLgAcModeSize = 3; // Nr. of bits
+
46 const uint8_t kLgAcCool = 0; // 0b000
+
47 const uint8_t kLgAcDry = 1; // 0b001
+
48 const uint8_t kLgAcFan = 2; // 0b010
+
49 const uint8_t kLgAcAuto = 3; // 0b011
+
50 const uint8_t kLgAcHeat = 4; // 0b100
+
51 const uint8_t kLgAcPowerOffset = 18; // Nr. of bits
+
52 const uint8_t kLgAcPowerSize = 2; // Nr. of bits
+
53 const uint8_t kLgAcPowerOff = 3; // 0b11
+
54 const uint8_t kLgAcPowerOn = 0; // 0b00
+
55 const uint8_t kLgAcSignatureOffset = 20; // Nr. of bits
+
56 const uint8_t kLgAcSignatureSize = 8; // Nr. of bits
+
57 const uint8_t kLgAcSignature = 0x88;
+
58 
+
59 const uint32_t kLgAcOffCommand = 0x88C0051;
+
60 
+
61 // Classes
+
63 class IRLgAc {
+
64  public:
+
65  explicit IRLgAc(const uint16_t pin, const bool inverted = false,
+
66  const bool use_modulation = true);
+
67  void stateReset(void);
+
68  static uint8_t calcChecksum(const uint32_t state);
+
69  static bool validChecksum(const uint32_t state);
+
70  bool isValidLgAc(void);
+
71 #if SEND_LG
+
72  void send(const uint16_t repeat = kLgDefaultRepeat);
+
77  int8_t calibrate(void) { return _irsend.calibrate(); }
+
78 #endif // SEND_LG
+
79  void begin(void);
+
80  void on(void);
+
81  void off(void);
+
82  void setPower(const bool on);
+
83  bool getPower(void);
+
84  void setTemp(const uint8_t degrees);
+
85  uint8_t getTemp(void);
+
86  void setFan(const uint8_t speed);
+
87  uint8_t getFan(void);
+
88  void setMode(const uint8_t mode);
+
89  uint8_t getMode(void);
+
90  uint32_t getRaw(void);
+
91  void setRaw(const uint32_t new_code);
+
92  uint8_t convertMode(const stdAc::opmode_t mode);
+
93  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
94  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
95  static uint8_t convertFan(const stdAc::fanspeed_t speed);
+ +
97  String toString(void);
+
98  void setModel(const lg_ac_remote_model_t model);
+ +
100 #ifndef UNIT_TEST
+
101 
+
102  private:
+ +
104 #else // UNIT_TEST
+
105  IRsendTest _irsend;
+
107 #endif // UNIT_TEST
+
109  uint32_t remote_state;
+
110  uint8_t _temp;
+ +
112  void checksum(void);
+
113  void _setTemp(const uint8_t value);
+
114 };
+
115 
+
116 #endif // IR_LG_H_
+
+
const uint8_t kLgAcFanMedium
Definition: ir_LG.h:36
+
void _setTemp(const uint8_t value)
Set the temperature.
Definition: ir_LG.cpp:375
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_LG.cpp:457
+
decode_type_t
Enumerator for defining and numbering of supported IR protocol.
Definition: IRremoteESP8266.h:714
+
uint32_t getRaw(void)
Get a copy of the internal state/code for this protocol.
Definition: ir_LG.cpp:314
+
decode_type_t _protocol
Definition: ir_LG.h:111
+
const uint8_t kLgAcFanSize
Definition: ir_LG.h:34
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_LG.h:77
+
const uint8_t kLgAcFanAuto
Definition: ir_LG.h:38
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
const uint8_t kLgAcFanOffset
Definition: ir_LG.h:33
+
const uint8_t kLgAcPowerOff
Definition: ir_LG.h:53
+
lg_ac_remote_model_t getModel(void)
Get the model of the A/C.
Definition: ir_LG.cpp:301
+
void setFan(const uint8_t speed)
Set the speed of the fan.
Definition: ir_LG.cpp:400
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_LG.cpp:521
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_LG.cpp:421
+
const uint8_t kLgAcFanHigh
Definition: ir_LG.h:37
+ +
const uint8_t kLgAcPowerOffset
Definition: ir_LG.h:51
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
const uint8_t kLgAcDry
Definition: ir_LG.h:47
+
void setTemp(const uint8_t degrees)
Set the temperature.
Definition: ir_LG.cpp:381
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
const uint8_t kLgAcTempOffset
Definition: ir_LG.h:39
+
const uint32_t kLgAcOffCommand
Definition: ir_LG.h:59
+
std::string String
Definition: IRremoteESP8266.h:1093
+
const uint8_t kNibbleSize
Definition: IRutils.h:17
+
static uint8_t calcChecksum(const uint32_t state)
Calculate the checksum for a given state.
Definition: ir_LG.cpp:330
+
const uint8_t kLgAcFanLow
Definition: ir_LG.h:35
+
void setModel(const lg_ac_remote_model_t model)
Set the model of the A/C to emulate.
Definition: ir_LG.cpp:287
+
const uint16_t kLgDefaultRepeat
Definition: IRremoteESP8266.h:919
+
const uint8_t kLgAcMaxTemp
Definition: ir_LG.h:43
+
IRLgAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_LG.cpp:259
+
const uint8_t kLgAcSignature
Definition: ir_LG.h:57
+ +
const uint8_t kLgAcSignatureSize
Definition: ir_LG.h:56
+
static uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_LG.cpp:470
+
const uint8_t kLgAcTempSize
Definition: ir_LG.h:40
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_LG.cpp:484
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_LG.cpp:495
+
const uint8_t kLgAcCool
Definition: ir_LG.h:46
+
const uint8_t kLgAcHeat
Definition: ir_LG.h:50
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_LG.cpp:270
+
const uint8_t kLgAcChecksumSize
Definition: ir_LG.h:32
+
const uint8_t kLgAcPowerSize
Definition: ir_LG.h:52
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_LG.cpp:415
+
Class for handling detailed LG A/C messages.
Definition: ir_LG.h:63
+ +
const uint8_t kLgAcSignatureOffset
Definition: ir_LG.h:55
+
const uint8_t kLgAcModeSize
Definition: ir_LG.h:45
+
uint32_t remote_state
The state of the IR remote in IR code form.
Definition: ir_LG.h:109
+
lg_ac_remote_model_t
LG A/C model numbers.
Definition: IRsend.h:158
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_LG.cpp:427
+
uint8_t _temp
Definition: ir_LG.h:110
+
const uint8_t kLgAcModeOffset
Definition: ir_LG.h:44
+
const uint8_t kLgAcAuto
Definition: ir_LG.h:49
+
void setRaw(const uint32_t new_code)
Set the internal state from a valid code for this protocol.
Definition: ir_LG.cpp:321
+
const uint8_t kLgAcPowerOn
Definition: ir_LG.h:54
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_LG.cpp:390
+
void off(void)
Change the power setting to Off.
Definition: ir_LG.cpp:352
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_LG.cpp:367
+
void checksum(void)
Calculate and set the checksum values for the internal state.
Definition: ir_LG.cpp:343
+
void stateReset(void)
Reset the internals of the object to a known good state.
Definition: ir_LG.cpp:264
+
const uint8_t kLgAcChecksumOffset
Definition: ir_LG.h:31
+
const uint8_t kLgAcMinTemp
Definition: ir_LG.h:42
+
const uint8_t kLgAcTempAdjust
Definition: ir_LG.h:41
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_LG.cpp:444
+
void setPower(const bool on)
Change the power setting.
Definition: ir_LG.cpp:356
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
void send(const uint16_t repeat=kLgDefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_LG.cpp:275
+
static bool validChecksum(const uint32_t state)
Verify the checksum is valid for a given state.
Definition: ir_LG.cpp:337
+
const uint8_t kLgAcFan
Definition: ir_LG.h:48
+
void on(void)
Change the power setting to On.
Definition: ir_LG.cpp:349
+
bool isValidLgAc(void)
Check if the internal state looks like a valud LG A/C message.
Definition: ir_LG.cpp:538
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_LG.h:103
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Lasertag_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Lasertag_8cpp.html new file mode 100644 index 000000000..568c1faa2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Lasertag_8cpp.html @@ -0,0 +1,221 @@ + + + + + + + +IRremoteESP8266: src/ir_Lasertag.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Lasertag.cpp File Reference
+
+
+ +

Support for Lasertag protocols. +More...

+ + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kLasertagMinSamples = 13
 
const uint16_t kLasertagTick = 333
 
const uint32_t kLasertagMinGap = kDefaultMessageGap
 
const uint8_t kLasertagTolerance = 0
 
const uint16_t kLasertagExcess = 0
 
const uint16_t kLasertagDelta = 150
 
const int16_t kSpace = 1
 
const int16_t kMark = 0
 
+

Detailed Description

+

Support for Lasertag protocols.

+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/366
+

Variable Documentation

+ +

◆ kLasertagDelta

+ +
+
+ + + + +
const uint16_t kLasertagDelta = 150
+
+ +
+
+ +

◆ kLasertagExcess

+ +
+
+ + + + +
const uint16_t kLasertagExcess = 0
+
+ +
+
+ +

◆ kLasertagMinGap

+ +
+
+ + + + +
const uint32_t kLasertagMinGap = kDefaultMessageGap
+
+ +
+
+ +

◆ kLasertagMinSamples

+ +
+
+ + + + +
const uint16_t kLasertagMinSamples = 13
+
+ +
+
+ +

◆ kLasertagTick

+ +
+
+ + + + +
const uint16_t kLasertagTick = 333
+
+ +
+
+ +

◆ kLasertagTolerance

+ +
+
+ + + + +
const uint8_t kLasertagTolerance = 0
+
+ +
+
+ +

◆ kMark

+ +
+
+ + + + +
const int16_t kMark = 0
+
+ +
+
+ +

◆ kSpace

+ +
+
+ + + + +
const int16_t kSpace = 1
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Lego_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Lego_8cpp.html new file mode 100644 index 000000000..8a2d2c588 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Lego_8cpp.html @@ -0,0 +1,176 @@ + + + + + + + +IRremoteESP8266: src/ir_Lego.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Lego.cpp File Reference
+
+
+ +

Support for LEGO protocols. +More...

+ + + + + + + + + + + + +

+Variables

const uint16_t kLegoPfBitMark = 158
 
const uint16_t kLegoPfHdrSpace = 1026
 
const uint16_t kLegoPfZeroSpace = 263
 
const uint16_t kLegoPfOneSpace = 553
 
const uint32_t kLegoPfMinCommandLength = 16000
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kLegoPfBitMark

+ +
+
+ + + + +
const uint16_t kLegoPfBitMark = 158
+
+ +
+
+ +

◆ kLegoPfHdrSpace

+ +
+
+ + + + +
const uint16_t kLegoPfHdrSpace = 1026
+
+ +
+
+ +

◆ kLegoPfMinCommandLength

+ +
+
+ + + + +
const uint32_t kLegoPfMinCommandLength = 16000
+
+ +
+
+ +

◆ kLegoPfOneSpace

+ +
+
+ + + + +
const uint16_t kLegoPfOneSpace = 553
+
+ +
+
+ +

◆ kLegoPfZeroSpace

+ +
+
+ + + + +
const uint16_t kLegoPfZeroSpace = 263
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Lutron_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Lutron_8cpp.html new file mode 100644 index 000000000..b75090a1f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Lutron_8cpp.html @@ -0,0 +1,144 @@ + + + + + + + +IRremoteESP8266: src/ir_Lutron.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Lutron.cpp File Reference
+
+
+ +

Support for Lutron protocols. +More...

+ + + + + + + + +

+Variables

const uint16_t kLutronTick = 2288
 
const uint32_t kLutronGap = 150000
 
const uint16_t kLutronDelta = 400
 
+

Detailed Description

+

Support for Lutron protocols.

+
Note
The Lutron protocol uses a sort of Run Length encoding to encode its data. There is no header or footer per-se. As a mark is the first data we will notice, we always assume the First bit of the technically 36-bit protocol is '1'. So it is assumed, and thus we only care about the 35 bits of data.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/515
+
+http://www.lutron.com/TechnicalDocumentLibrary/048158.doc
+

Variable Documentation

+ +

◆ kLutronDelta

+ +
+
+ + + + +
const uint16_t kLutronDelta = 400
+
+ +
+
+ +

◆ kLutronGap

+ +
+
+ + + + +
const uint32_t kLutronGap = 150000
+
+ +
+
+ +

◆ kLutronTick

+ +
+
+ + + + +
const uint16_t kLutronTick = 2288
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__MWM_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__MWM_8cpp.html new file mode 100644 index 000000000..8a6c009c2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__MWM_8cpp.html @@ -0,0 +1,237 @@ + + + + + + + +IRremoteESP8266: src/ir_MWM.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_MWM.cpp File Reference
+
+
+ +

Disney Made With Magic (MWM) Support derived from ir_Lasertag.cpp. +More...

+ + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kMWMMinSamples = 6
 
const uint16_t kMWMTick = 417
 
const uint32_t kMWMMinGap = 30000
 
const uint8_t kMWMTolerance = 0
 
const uint16_t kMWMExcess = 0
 
const uint16_t kMWMDelta = 150
 
const uint8_t kMWMMaxWidth = 9
 
const int16_t kSpace = 1
 
const int16_t kMark = 0
 
+

Detailed Description

+

Disney Made With Magic (MWM) Support derived from ir_Lasertag.cpp.

+
See also
https://github.com/crankyoldgit/IRremoteESP8266/pull/557
+

Variable Documentation

+ +

◆ kMark

+ +
+
+ + + + +
const int16_t kMark = 0
+
+ +
+
+ +

◆ kMWMDelta

+ +
+
+ + + + +
const uint16_t kMWMDelta = 150
+
+ +
+
+ +

◆ kMWMExcess

+ +
+
+ + + + +
const uint16_t kMWMExcess = 0
+
+ +
+
+ +

◆ kMWMMaxWidth

+ +
+
+ + + + +
const uint8_t kMWMMaxWidth = 9
+
+ +
+
+ +

◆ kMWMMinGap

+ +
+
+ + + + +
const uint32_t kMWMMinGap = 30000
+
+ +
+
+ +

◆ kMWMMinSamples

+ +
+
+ + + + +
const uint16_t kMWMMinSamples = 6
+
+ +
+
+ +

◆ kMWMTick

+ +
+
+ + + + +
const uint16_t kMWMTick = 417
+
+ +
+
+ +

◆ kMWMTolerance

+ +
+
+ + + + +
const uint8_t kMWMTolerance = 0
+
+ +
+
+ +

◆ kSpace

+ +
+
+ + + + +
const int16_t kSpace = 1
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Magiquest_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Magiquest_8cpp.html new file mode 100644 index 000000000..3b0c54da6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Magiquest_8cpp.html @@ -0,0 +1,88 @@ + + + + + + + +IRremoteESP8266: src/ir_Magiquest.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Magiquest.cpp File Reference
+
+
+ +

Support for MagiQuest protocols. +More...

+

Detailed Description

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Magiquest_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Magiquest_8h.html new file mode 100644 index 000000000..628b41793 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Magiquest_8h.html @@ -0,0 +1,232 @@ + + + + + + + +IRremoteESP8266: src/ir_Magiquest.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Magiquest.h File Reference
+
+
+ +

Support for MagiQuest protocols. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

union  magiquest
 MagiQuest packet is both Wand ID and magnitude of swish and flick. More...
 
+ + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kMagiQuestTotalUsec = 1150
 
const uint8_t kMagiQuestZeroRatio = 30
 
const uint8_t kMagiQuestOneRatio = 38
 
const uint16_t kMagiQuestMarkZero = 280
 
const uint16_t kMagiQuestSpaceZero = 850
 
const uint16_t kMagiQuestMarkOne = 580
 
const uint16_t kMagiQuestSpaceOne = 600
 
const uint32_t kMagiQuestGap = kDefaultMessageGap
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kMagiQuestGap

+ +
+
+ + + + +
const uint32_t kMagiQuestGap = kDefaultMessageGap
+
+ +
+
+ +

◆ kMagiQuestMarkOne

+ +
+
+ + + + +
const uint16_t kMagiQuestMarkOne = 580
+
+ +
+
+ +

◆ kMagiQuestMarkZero

+ +
+
+ + + + +
const uint16_t kMagiQuestMarkZero = 280
+
+ +
+
+ +

◆ kMagiQuestOneRatio

+ +
+
+ + + + +
const uint8_t kMagiQuestOneRatio = 38
+
+ +
+
+ +

◆ kMagiQuestSpaceOne

+ +
+
+ + + + +
const uint16_t kMagiQuestSpaceOne = 600
+
+ +
+
+ +

◆ kMagiQuestSpaceZero

+ +
+
+ + + + +
const uint16_t kMagiQuestSpaceZero = 850
+
+ +
+
+ +

◆ kMagiQuestTotalUsec

+ +
+
+ + + + +
const uint16_t kMagiQuestTotalUsec = 1150
+
+ +
+
+ +

◆ kMagiQuestZeroRatio

+ +
+
+ + + + +
const uint8_t kMagiQuestZeroRatio = 30
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Magiquest_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Magiquest_8h_source.html new file mode 100644 index 000000000..1928697e9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Magiquest_8h_source.html @@ -0,0 +1,137 @@ + + + + + + + +IRremoteESP8266: src/ir_Magiquest.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Magiquest.h
+
+
+Go to the documentation of this file.
1 // Copyright 2013 mpflaga
+
2 // Copyright 2015 kitlaan
+
3 // Copyright 2017 Jason kendall, David Conran
+
4 
+
9 
+
10 // Supports:
+
11 // Brand: MagiQuest, Model: Wand
+
12 
+
13 #ifndef IR_MAGIQUEST_H_
+
14 #define IR_MAGIQUEST_H_
+
15 
+
16 #define __STDC_LIMIT_MACROS
+
17 #include <stdint.h>
+
18 #include "IRremoteESP8266.h"
+
19 #include "IRsend.h"
+
20 
+
22 union magiquest {
+
23  uint64_t llword;
+
24  uint8_t byte[8];
+
25  // uint16_t word[4];
+
26  uint32_t lword[2];
+
27  struct {
+
28  uint16_t magnitude;
+
29  uint32_t wand_id;
+
30  uint8_t padding;
+
31  uint8_t scrap;
+
32  } cmd;
+
33 };
+
34 
+
35 const uint16_t kMagiQuestTotalUsec = 1150;
+
36 const uint8_t kMagiQuestZeroRatio = 30; // usually <= ~25%
+
37 const uint8_t kMagiQuestOneRatio = 38; // usually >= ~50%
+
38 const uint16_t kMagiQuestMarkZero = 280;
+
39 const uint16_t kMagiQuestSpaceZero = 850;
+
40 const uint16_t kMagiQuestMarkOne = 580;
+
41 const uint16_t kMagiQuestSpaceOne = 600;
+
42 const uint32_t kMagiQuestGap = kDefaultMessageGap; // Just a guess.
+
43 #endif // IR_MAGIQUEST_H_
+
+
const uint32_t kDefaultMessageGap
Definition: IRsend.h:41
+
uint8_t scrap
Definition: ir_Magiquest.h:31
+
const uint16_t kMagiQuestMarkZero
Definition: ir_Magiquest.h:38
+ +
uint16_t magnitude
Definition: ir_Magiquest.h:28
+
struct magiquest::@0 cmd
+
uint64_t llword
Definition: ir_Magiquest.h:23
+ +
const uint16_t kMagiQuestMarkOne
Definition: ir_Magiquest.h:40
+
MagiQuest packet is both Wand ID and magnitude of swish and flick.
Definition: ir_Magiquest.h:22
+
uint32_t wand_id
Definition: ir_Magiquest.h:29
+
const uint32_t kMagiQuestGap
Definition: ir_Magiquest.h:42
+
const uint16_t kMagiQuestSpaceZero
Definition: ir_Magiquest.h:39
+
const uint16_t kMagiQuestSpaceOne
Definition: ir_Magiquest.h:41
+
uint32_t lword[2]
Definition: ir_Magiquest.h:26
+
const uint16_t kMagiQuestTotalUsec
Definition: ir_Magiquest.h:35
+
uint8_t padding
Definition: ir_Magiquest.h:30
+
const uint8_t kMagiQuestOneRatio
Definition: ir_Magiquest.h:37
+
const uint8_t kMagiQuestZeroRatio
Definition: ir_Magiquest.h:36
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Midea_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Midea_8cpp.html new file mode 100644 index 000000000..4d39bc403 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Midea_8cpp.html @@ -0,0 +1,341 @@ + + + + + + + +IRremoteESP8266: src/ir_Midea.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Midea.cpp File Reference
+
+
+ +

Support for Midea protocols. Midea added by crankyoldgit & bwze. send: bwze/crankyoldgit, decode: crankyoldgit. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kMideaTick = 80
 
const uint16_t kMideaBitMarkTicks = 7
 
const uint16_t kMideaBitMark = kMideaBitMarkTicks * kMideaTick
 
const uint16_t kMideaOneSpaceTicks = 21
 
const uint16_t kMideaOneSpace = kMideaOneSpaceTicks * kMideaTick
 
const uint16_t kMideaZeroSpaceTicks = 7
 
const uint16_t kMideaZeroSpace = kMideaZeroSpaceTicks * kMideaTick
 
const uint16_t kMideaHdrMarkTicks = 56
 
const uint16_t kMideaHdrMark = kMideaHdrMarkTicks * kMideaTick
 
const uint16_t kMideaHdrSpaceTicks = 56
 
const uint16_t kMideaHdrSpace = kMideaHdrSpaceTicks * kMideaTick
 
const uint16_t kMideaMinGapTicks
 
const uint16_t kMideaMinGap = kMideaMinGapTicks * kMideaTick
 
const uint8_t kMideaTolerance = 30
 
const uint16_t kMidea24MinGap = 13000
 uSecs More...
 
+

Detailed Description

+

Support for Midea protocols. Midea added by crankyoldgit & bwze. send: bwze/crankyoldgit, decode: crankyoldgit.

+
See also
https://docs.google.com/spreadsheets/d/1TZh4jWrx4h9zzpYUI9aYXMl1fYOiqu-xVuOOMqagxrs/edit?usp=sharing
+

Variable Documentation

+ +

◆ kMidea24MinGap

+ +
+
+ + + + +
const uint16_t kMidea24MinGap = 13000
+
+ +

uSecs

+ +
+
+ +

◆ kMideaBitMark

+ +
+
+ + + + +
const uint16_t kMideaBitMark = kMideaBitMarkTicks * kMideaTick
+
+ +
+
+ +

◆ kMideaBitMarkTicks

+ +
+
+ + + + +
const uint16_t kMideaBitMarkTicks = 7
+
+ +
+
+ +

◆ kMideaHdrMark

+ +
+
+ + + + +
const uint16_t kMideaHdrMark = kMideaHdrMarkTicks * kMideaTick
+
+ +
+
+ +

◆ kMideaHdrMarkTicks

+ +
+
+ + + + +
const uint16_t kMideaHdrMarkTicks = 56
+
+ +
+
+ +

◆ kMideaHdrSpace

+ +
+
+ + + + +
const uint16_t kMideaHdrSpace = kMideaHdrSpaceTicks * kMideaTick
+
+ +
+
+ +

◆ kMideaHdrSpaceTicks

+ +
+
+ + + + +
const uint16_t kMideaHdrSpaceTicks = 56
+
+ +
+
+ +

◆ kMideaMinGap

+ +
+
+ + + + +
const uint16_t kMideaMinGap = kMideaMinGapTicks * kMideaTick
+
+ +
+
+ +

◆ kMideaMinGapTicks

+ +
+
+ + + + +
const uint16_t kMideaMinGapTicks
+
+
+ +

◆ kMideaOneSpace

+ +
+
+ + + + +
const uint16_t kMideaOneSpace = kMideaOneSpaceTicks * kMideaTick
+
+ +
+
+ +

◆ kMideaOneSpaceTicks

+ +
+
+ + + + +
const uint16_t kMideaOneSpaceTicks = 21
+
+ +
+
+ +

◆ kMideaTick

+ +
+
+ + + + +
const uint16_t kMideaTick = 80
+
+ +
+
+ +

◆ kMideaTolerance

+ +
+
+ + + + +
const uint8_t kMideaTolerance = 30
+
+ +
+
+ +

◆ kMideaZeroSpace

+ +
+
+ + + + +
const uint16_t kMideaZeroSpace = kMideaZeroSpaceTicks * kMideaTick
+
+ +
+
+ +

◆ kMideaZeroSpaceTicks

+ +
+
+ + + + +
const uint16_t kMideaZeroSpaceTicks = 7
+
+ +
+
+
+
const uint16_t kMideaZeroSpaceTicks
Definition: ir_Midea.cpp:25
+
const uint16_t kMideaBitMarkTicks
Definition: ir_Midea.cpp:21
+
const uint16_t kMideaHdrMarkTicks
Definition: ir_Midea.cpp:27
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Midea_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Midea_8h.html new file mode 100644 index 000000000..309a3a97a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Midea_8h.html @@ -0,0 +1,454 @@ + + + + + + + +IRremoteESP8266: src/ir_Midea.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Midea.h File Reference
+
+
+ +

Support for Midea protocols. Midea added by crankyoldgit & bwze. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRMideaAC
 Class for handling detailed Midea A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kMideaACTempOffset = 24
 
const uint8_t kMideaACTempSize = 5
 
const uint8_t kMideaACMinTempF = 62
 
const uint8_t kMideaACMaxTempF = 86
 
const uint8_t kMideaACMinTempC = 17
 
const uint8_t kMideaACMaxTempC = 30
 
const uint8_t kMideaACCelsiusOffset = 29
 
const uint8_t kMideaACModeOffset = 32
 
const uint8_t kMideaACCool = 0
 
const uint8_t kMideaACDry = 1
 
const uint8_t kMideaACAuto = 2
 
const uint8_t kMideaACHeat = 3
 
const uint8_t kMideaACFan = 4
 
const uint8_t kMideaACFanOffset = 35
 
const uint8_t kMideaACFanSize = 2
 
const uint8_t kMideaACFanAuto = 0
 
const uint8_t kMideaACFanLow = 1
 
const uint8_t kMideaACFanMed = 2
 
const uint8_t kMideaACFanHigh = 3
 
const uint8_t kMideaACSleepOffset = 38
 
const uint8_t kMideaACPowerOffset = 39
 
const uint64_t kMideaACToggleSwingV = 0x0000A201FFFFFF7C
 
+

Detailed Description

+

Support for Midea protocols. Midea added by crankyoldgit & bwze.

+
See also
https://docs.google.com/spreadsheets/d/1TZh4jWrx4h9zzpYUI9aYXMl1fYOiqu-xVuOOMqagxrs/edit?usp=sharing
+

Variable Documentation

+ +

◆ kMideaACAuto

+ +
+
+ + + + +
const uint8_t kMideaACAuto = 2
+
+ +
+
+ +

◆ kMideaACCelsiusOffset

+ +
+
+ + + + +
const uint8_t kMideaACCelsiusOffset = 29
+
+ +
+
+ +

◆ kMideaACCool

+ +
+
+ + + + +
const uint8_t kMideaACCool = 0
+
+ +
+
+ +

◆ kMideaACDry

+ +
+
+ + + + +
const uint8_t kMideaACDry = 1
+
+ +
+
+ +

◆ kMideaACFan

+ +
+
+ + + + +
const uint8_t kMideaACFan = 4
+
+ +
+
+ +

◆ kMideaACFanAuto

+ +
+
+ + + + +
const uint8_t kMideaACFanAuto = 0
+
+ +
+
+ +

◆ kMideaACFanHigh

+ +
+
+ + + + +
const uint8_t kMideaACFanHigh = 3
+
+ +
+
+ +

◆ kMideaACFanLow

+ +
+
+ + + + +
const uint8_t kMideaACFanLow = 1
+
+ +
+
+ +

◆ kMideaACFanMed

+ +
+
+ + + + +
const uint8_t kMideaACFanMed = 2
+
+ +
+
+ +

◆ kMideaACFanOffset

+ +
+
+ + + + +
const uint8_t kMideaACFanOffset = 35
+
+ +
+
+ +

◆ kMideaACFanSize

+ +
+
+ + + + +
const uint8_t kMideaACFanSize = 2
+
+ +
+
+ +

◆ kMideaACHeat

+ +
+
+ + + + +
const uint8_t kMideaACHeat = 3
+
+ +
+
+ +

◆ kMideaACMaxTempC

+ +
+
+ + + + +
const uint8_t kMideaACMaxTempC = 30
+
+ +
+
+ +

◆ kMideaACMaxTempF

+ +
+
+ + + + +
const uint8_t kMideaACMaxTempF = 86
+
+ +
+
+ +

◆ kMideaACMinTempC

+ +
+
+ + + + +
const uint8_t kMideaACMinTempC = 17
+
+ +
+
+ +

◆ kMideaACMinTempF

+ +
+
+ + + + +
const uint8_t kMideaACMinTempF = 62
+
+ +
+
+ +

◆ kMideaACModeOffset

+ +
+
+ + + + +
const uint8_t kMideaACModeOffset = 32
+
+ +
+
+ +

◆ kMideaACPowerOffset

+ +
+
+ + + + +
const uint8_t kMideaACPowerOffset = 39
+
+ +
+
+ +

◆ kMideaACSleepOffset

+ +
+
+ + + + +
const uint8_t kMideaACSleepOffset = 38
+
+ +
+
+ +

◆ kMideaACTempOffset

+ +
+
+ + + + +
const uint8_t kMideaACTempOffset = 24
+
+ +
+
+ +

◆ kMideaACTempSize

+ +
+
+ + + + +
const uint8_t kMideaACTempSize = 5
+
+ +
+
+ +

◆ kMideaACToggleSwingV

+ +
+
+ + + + +
const uint64_t kMideaACToggleSwingV = 0x0000A201FFFFFF7C
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Midea_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Midea_8h_source.html new file mode 100644 index 000000000..f8649c8cd --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Midea_8h_source.html @@ -0,0 +1,264 @@ + + + + + + + +IRremoteESP8266: src/ir_Midea.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Midea.h
+
+
+Go to the documentation of this file.
1 // Copyright 2017 David Conran
+
2 
+
7 
+
8 // Supports:
+
9 // Brand: Pioneer System, Model: RYBO12GMFILCAD A/C (12K BTU) (MIDEA)
+
10 // Brand: Pioneer System, Model: RUBO18GMFILCAD A/C (18K BTU) (MIDEA)
+
11 // Brand: Comfee, Model: MPD1-12CRN7 A/C (MIDEA)
+
12 // Brand: Keystone, Model: RG57H4(B)BGEF remote (MIDEA)
+
13 // Brand: Midea, Model: FS40-7AR Stand Fan (MIDEA24)
+
14 
+
15 #ifndef IR_MIDEA_H_
+
16 #define IR_MIDEA_H_
+
17 
+
18 #define __STDC_LIMIT_MACROS
+
19 #include <stdint.h>
+
20 #ifdef ARDUINO
+
21 #include <Arduino.h>
+
22 #endif
+
23 #include "IRremoteESP8266.h"
+
24 #include "IRsend.h"
+
25 #ifdef UNIT_TEST
+
26 #include "IRsend_test.h"
+
27 #endif
+
28 
+
29 // Constants
+
30 const uint8_t kMideaACTempOffset = 24;
+
31 const uint8_t kMideaACTempSize = 5; // Bits
+
32 const uint8_t kMideaACMinTempF = 62; // Fahrenheit
+
33 const uint8_t kMideaACMaxTempF = 86; // Fahrenheit
+
34 const uint8_t kMideaACMinTempC = 17; // Celsius
+
35 const uint8_t kMideaACMaxTempC = 30; // Celsius
+
36 const uint8_t kMideaACCelsiusOffset = 29;
+
37 const uint8_t kMideaACModeOffset = 32;
+
38 const uint8_t kMideaACCool = 0; // 0b000
+
39 const uint8_t kMideaACDry = 1; // 0b001
+
40 const uint8_t kMideaACAuto = 2; // 0b010
+
41 const uint8_t kMideaACHeat = 3; // 0b011
+
42 const uint8_t kMideaACFan = 4; // 0b100
+
43 const uint8_t kMideaACFanOffset = 35;
+
44 const uint8_t kMideaACFanSize = 2; // Bits
+
45 const uint8_t kMideaACFanAuto = 0; // 0b00
+
46 const uint8_t kMideaACFanLow = 1; // 0b01
+
47 const uint8_t kMideaACFanMed = 2; // 0b10
+
48 const uint8_t kMideaACFanHigh = 3; // 0b11
+
49 const uint8_t kMideaACSleepOffset = 38;
+
50 const uint8_t kMideaACPowerOffset = 39;
+
51 const uint64_t kMideaACToggleSwingV = 0x0000A201FFFFFF7C;
+
52 
+
53 // Legacy defines. (Deprecated)
+
54 #define MIDEA_AC_COOL kMideaACCool
+
55 #define MIDEA_AC_DRY kMideaACDry
+
56 #define MIDEA_AC_AUTO kMideaACAuto
+
57 #define MIDEA_AC_HEAT kMideaACHeat
+
58 #define MIDEA_AC_FAN kMideaACFan
+
59 #define MIDEA_AC_FAN_AUTO kMideaACFanAuto
+
60 #define MIDEA_AC_FAN_LOW kMideaACFanLow
+
61 #define MIDEA_AC_FAN_MED kMideaACFanMed
+
62 #define MIDEA_AC_FAN_HI kMideaACFanHigh
+
63 #define MIDEA_AC_POWER kMideaACPower
+
64 #define MIDEA_AC_SLEEP kMideaACSleep
+
65 #define MIDEA_AC_MIN_TEMP_F kMideaACMinTempF
+
66 #define MIDEA_AC_MAX_TEMP_F kMideaACMaxTempF
+
67 #define MIDEA_AC_MIN_TEMP_C kMideaACMinTempC
+
68 #define MIDEA_AC_MAX_TEMP_C kMideaACMaxTempC
+
69 
+
70 // Classes
+
73 class IRMideaAC {
+
74  public:
+
75  explicit IRMideaAC(const uint16_t pin, const bool inverted = false,
+
76  const bool use_modulation = true);
+
77  void stateReset(void);
+
78 #if SEND_MIDEA
+
79  void send(const uint16_t repeat = kMideaMinRepeat);
+
84  int8_t calibrate(void) { return _irsend.calibrate(); }
+
85 #endif // SEND_MIDEA
+
86  void begin(void);
+
87  void on(void);
+
88  void off(void);
+
89  void setPower(const bool on);
+
90  bool getPower(void);
+
91  bool getUseCelsius(void);
+
92  void setUseCelsius(const bool celsius);
+
93  void setTemp(const uint8_t temp, const bool useCelsius = false);
+
94  uint8_t getTemp(const bool useCelsius = false);
+
95  void setFan(const uint8_t fan);
+
96  uint8_t getFan(void);
+
97  void setMode(const uint8_t mode);
+
98  uint8_t getMode(void);
+
99  void setRaw(const uint64_t newState);
+
100  uint64_t getRaw(void);
+
101  static bool validChecksum(const uint64_t state);
+
102  void setSleep(const bool on);
+
103  bool getSleep(void);
+
104  bool isSwingVToggle(void);
+
105  void setSwingVToggle(const bool on);
+
106  bool getSwingVToggle(void);
+
107  uint8_t convertMode(const stdAc::opmode_t mode);
+
108  uint8_t convertFan(const stdAc::fanspeed_t speed);
+
109  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
110  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
111  stdAc::state_t toCommon(const stdAc::state_t *prev = NULL);
+
112  String toString(void);
+
113 #ifndef UNIT_TEST
+
114 
+
115  private:
+ +
117 #else // UNIT_TEST
+
118  IRsendTest _irsend;
+
120 #endif // UNIT_TEST
+
122  uint64_t remote_state;
+ +
124  void checksum(void);
+
125  static uint8_t calcChecksum(const uint64_t state);
+
126 };
+
127 
+
128 #endif // IR_MIDEA_H_
+
+
const uint8_t kMideaACMinTempF
Definition: ir_Midea.h:32
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Midea.cpp:105
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Midea.cpp:336
+
void setSleep(const bool on)
Set the Sleep setting of the A/C.
Definition: ir_Midea.cpp:238
+
void on(void)
Set the requested power state of the A/C to on.
Definition: ir_Midea.cpp:133
+
void setUseCelsius(const bool celsius)
Set the A/C unit to use Celsius natively.
Definition: ir_Midea.cpp:158
+
const uint16_t kMideaMinRepeat
Definition: IRremoteESP8266.h:923
+
void setTemp(const uint8_t temp, const bool useCelsius=false)
Set the temperature.
Definition: ir_Midea.cpp:169
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Midea.h:84
+
const uint8_t kMideaACTempOffset
Definition: ir_Midea.h:30
+
const uint8_t kMideaACFanSize
Definition: ir_Midea.h:44
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Midea.cpp:210
+
bool _SwingVToggle
Definition: ir_Midea.h:123
+
const uint8_t kMideaACAuto
Definition: ir_Midea.h:40
+
void checksum(void)
Calculate & set the checksum for the current internal state of the remote.
Definition: ir_Midea.cpp:288
+
IRMideaAC(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Midea.cpp:93
+
const uint8_t kMideaACFan
Definition: ir_Midea.h:42
+
void send(const uint16_t repeat=kMideaMinRepeat)
Send the current internal state as an IR message.
Definition: ir_Midea.cpp:110
+
const uint8_t kMideaACModeOffset
Definition: ir_Midea.h:37
+
bool isSwingVToggle(void)
Is the current state a vertical swing toggle message?
Definition: ir_Midea.cpp:254
+
bool getSleep(void)
Get the Sleep setting of the A/C.
Definition: ir_Midea.cpp:244
+ +
const uint8_t kMideaACMaxTempF
Definition: ir_Midea.h:33
+
const uint8_t kMideaACCelsiusOffset
Definition: ir_Midea.h:36
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
void setSwingVToggle(const bool on)
Set the A/C to toggle the vertical swing toggle for the next send.
Definition: ir_Midea.cpp:250
+
std::string String
Definition: IRremoteESP8266.h:1093
+
bool getSwingVToggle(void)
Definition: ir_Midea.cpp:260
+
void off(void)
Set the requested power state of the A/C to off.
Definition: ir_Midea.cpp:136
+ +
const uint8_t kMideaACHeat
Definition: ir_Midea.h:41
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Midea.cpp:146
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Midea.cpp:216
+
bool getUseCelsius(void)
Is the device currently using Celsius or the Fahrenheit temp scale?
Definition: ir_Midea.cpp:152
+
uint8_t getTemp(const bool useCelsius=false)
Get the current temperature setting.
Definition: ir_Midea.cpp:190
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Midea.cpp:323
+
const uint8_t kMideaACFanAuto
Definition: ir_Midea.h:45
+
const uint64_t kMideaACToggleSwingV
Definition: ir_Midea.h:51
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Midea.h:116
+
Class for handling detailed Midea A/C messages.
Definition: ir_Midea.h:73
+
void setRaw(const uint64_t newState)
Set the internal state from a valid code for this protocol.
Definition: ir_Midea.cpp:130
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Midea.cpp:222
+
static uint8_t calcChecksum(const uint64_t state)
Calculate the checksum for a given state.
Definition: ir_Midea.cpp:268
+
const uint8_t kMideaACTempSize
Definition: ir_Midea.h:31
+
uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Midea.cpp:309
+
const uint8_t kMideaACSleepOffset
Definition: ir_Midea.h:49
+
const uint8_t kMideaACFanMed
Definition: ir_Midea.h:47
+
uint64_t getRaw(void)
Get a copy of the internal state/code for this protocol.
Definition: ir_Midea.cpp:123
+
const uint8_t kMideaACMinTempC
Definition: ir_Midea.h:34
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Midea.cpp:296
+
uint64_t remote_state
The state of the IR remote in IR code form.
Definition: ir_Midea.h:122
+
const uint8_t kMideaACPowerOffset
Definition: ir_Midea.h:50
+
const uint8_t kMideaACFanHigh
Definition: ir_Midea.h:48
+
const uint8_t kMideaACMaxTempC
Definition: ir_Midea.h:35
+
stdAc::state_t toCommon(const stdAc::state_t *prev=NULL)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Midea.cpp:348
+
const uint8_t kMideaACDry
Definition: ir_Midea.h:39
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Midea.cpp:384
+
static bool validChecksum(const uint64_t state)
Verify the checksum is valid for a given state.
Definition: ir_Midea.cpp:283
+
const uint8_t kMideaACFanOffset
Definition: ir_Midea.h:43
+
const uint8_t kMideaACCool
Definition: ir_Midea.h:38
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Midea.cpp:140
+
void stateReset(void)
Reset the state of the remote to a known good state/sequence.
Definition: ir_Midea.cpp:98
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
const uint8_t kMideaACFanLow
Definition: ir_Midea.h:46
+
void setFan(const uint8_t fan)
Set the speed of the fan.
Definition: ir_Midea.cpp:203
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__MitsubishiHeavy_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__MitsubishiHeavy_8cpp.html new file mode 100644 index 000000000..8c6af97fa --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__MitsubishiHeavy_8cpp.html @@ -0,0 +1,194 @@ + + + + + + + +IRremoteESP8266: src/ir_MitsubishiHeavy.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_MitsubishiHeavy.cpp File Reference
+
+
+ +

Support for Mitsubishi Heavy Industry protocols. Code to emulate Mitsubishi Heavy Industries A/C IR remote control units. +More...

+ + + + + + + + + + + + + + +

+Variables

const uint16_t kMitsubishiHeavyHdrMark = 3140
 
const uint16_t kMitsubishiHeavyHdrSpace = 1630
 
const uint16_t kMitsubishiHeavyBitMark = 370
 
const uint16_t kMitsubishiHeavyOneSpace = 420
 
const uint16_t kMitsubishiHeavyZeroSpace = 1220
 
const uint32_t kMitsubishiHeavyGap = kDefaultMessageGap
 
+

Detailed Description

+

Support for Mitsubishi Heavy Industry protocols. Code to emulate Mitsubishi Heavy Industries A/C IR remote control units.

+
Note
This code was heavily influenced by ToniA's great work & code, but it has been written from scratch. Nothing was copied other than constants and message analysis.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/660
+
+https://github.com/ToniA/Raw-IR-decoder-for-Arduino/blob/master/MitsubishiHeavy.cpp
+
+https://github.com/ToniA/arduino-heatpumpir/blob/master/MitsubishiHeavyHeatpumpIR.cpp
+

Variable Documentation

+ +

◆ kMitsubishiHeavyBitMark

+ +
+
+ + + + +
const uint16_t kMitsubishiHeavyBitMark = 370
+
+ +
+
+ +

◆ kMitsubishiHeavyGap

+ +
+
+ + + + +
const uint32_t kMitsubishiHeavyGap = kDefaultMessageGap
+
+ +
+
+ +

◆ kMitsubishiHeavyHdrMark

+ +
+
+ + + + +
const uint16_t kMitsubishiHeavyHdrMark = 3140
+
+ +
+
+ +

◆ kMitsubishiHeavyHdrSpace

+ +
+
+ + + + +
const uint16_t kMitsubishiHeavyHdrSpace = 1630
+
+ +
+
+ +

◆ kMitsubishiHeavyOneSpace

+ +
+
+ + + + +
const uint16_t kMitsubishiHeavyOneSpace = 420
+
+ +
+
+ +

◆ kMitsubishiHeavyZeroSpace

+ +
+
+ + + + +
const uint16_t kMitsubishiHeavyZeroSpace = 1220
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__MitsubishiHeavy_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__MitsubishiHeavy_8h.html new file mode 100644 index 000000000..320f3cab8 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__MitsubishiHeavy_8h.html @@ -0,0 +1,1314 @@ + + + + + + + +IRremoteESP8266: src/ir_MitsubishiHeavy.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_MitsubishiHeavy.h File Reference
+
+
+ +

Support for Mitsubishi Heavy Industry protocols. Code to emulate Mitsubishi Heavy Industries A/C IR remote control units. +More...

+ +

Go to the source code of this file.

+ + + + + + + + +

+Classes

class  IRMitsubishiHeavy152Ac
 Class for handling detailed Mitsubishi Heavy 152-bit A/C messages. More...
 
class  IRMitsubishiHeavy88Ac
 Class for handling detailed Mitsubishi Heavy 88-bit A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kMitsubishiHeavySigLength = 5
 
const uint8_t kMitsubishiHeavyZmsSig [kMitsubishiHeavySigLength]
 
const uint8_t kMitsubishiHeavyModeOffset = 0
 
const uint8_t kMitsubishiHeavyAuto = 0
 
const uint8_t kMitsubishiHeavyCool = 1
 
const uint8_t kMitsubishiHeavyDry = 2
 
const uint8_t kMitsubishiHeavyFan = 3
 
const uint8_t kMitsubishiHeavyHeat = 4
 
const uint8_t kMitsubishiHeavyPowerOffset = 3
 
const uint8_t kMitsubishiHeavyCleanOffset = 5
 
const uint8_t kMitsubishiHeavyFilterOffset = 6
 
const uint8_t kMitsubishiHeavyMinTemp = 17
 
const uint8_t kMitsubishiHeavyMaxTemp = 31
 
const uint8_t kMitsubishiHeavy152FanAuto = 0x0
 
const uint8_t kMitsubishiHeavy152FanLow = 0x1
 
const uint8_t kMitsubishiHeavy152FanMed = 0x2
 
const uint8_t kMitsubishiHeavy152FanHigh = 0x3
 
const uint8_t kMitsubishiHeavy152FanMax = 0x4
 
const uint8_t kMitsubishiHeavy152FanEcono = 0x6
 
const uint8_t kMitsubishiHeavy152FanTurbo = 0x8
 
const uint8_t kMitsubishiHeavy3DMask = 0b00010010
 
const uint8_t kMitsubishiHeavy152SwingVOffset = 5
 
const uint8_t kMitsubishiHeavy152SwingVSize = 3
 
const uint8_t kMitsubishiHeavy152SwingVAuto = 0
 
const uint8_t kMitsubishiHeavy152SwingVHighest = 1
 
const uint8_t kMitsubishiHeavy152SwingVHigh = 2
 
const uint8_t kMitsubishiHeavy152SwingVMiddle = 3
 
const uint8_t kMitsubishiHeavy152SwingVLow = 4
 
const uint8_t kMitsubishiHeavy152SwingVLowest = 5
 
const uint8_t kMitsubishiHeavy152SwingVOff = 6
 
const uint8_t kMitsubishiHeavy152SwingHAuto = 0
 
const uint8_t kMitsubishiHeavy152SwingHLeftMax = 1
 
const uint8_t kMitsubishiHeavy152SwingHLeft = 2
 
const uint8_t kMitsubishiHeavy152SwingHMiddle = 3
 
const uint8_t kMitsubishiHeavy152SwingHRight = 4
 
const uint8_t kMitsubishiHeavy152SwingHRightMax = 5
 
const uint8_t kMitsubishiHeavy152SwingHRightLeft = 6
 
const uint8_t kMitsubishiHeavy152SwingHLeftRight = 7
 
const uint8_t kMitsubishiHeavy152SwingHOff = 8
 
const uint8_t kMitsubishiHeavyNightOffset = 6
 
const uint8_t kMitsubishiHeavySilentOffset = 7
 
const uint8_t kMitsubishiHeavyZjsSig [kMitsubishiHeavySigLength]
 
const uint8_t kMitsubishiHeavy88CleanOffset = 5
 
const uint8_t kMitsubishiHeavy88SwingHOffset1 = 2
 
const uint8_t kMitsubishiHeavy88SwingHOffset2 = 6
 
const uint8_t kMitsubishiHeavy88SwingHSize = 2
 
const uint8_t kMitsubishiHeavy88SwingHOff = 0b0000
 
const uint8_t kMitsubishiHeavy88SwingHAuto = 0b1000
 
const uint8_t kMitsubishiHeavy88SwingHLeftMax = 0b0001
 
const uint8_t kMitsubishiHeavy88SwingHLeft = 0b0101
 
const uint8_t kMitsubishiHeavy88SwingHMiddle = 0b1001
 
const uint8_t kMitsubishiHeavy88SwingHRight = 0b1101
 
const uint8_t kMitsubishiHeavy88SwingHRightMax = 0b0010
 
const uint8_t kMitsubishiHeavy88SwingHRightLeft = 0b1010
 
const uint8_t kMitsubishiHeavy88SwingHLeftRight = 0b0110
 
const uint8_t kMitsubishiHeavy88SwingH3D = 0b1110
 
const uint8_t kMitsubishiHeavy88FanOffset = 5
 
const uint8_t kMitsubishiHeavy88FanSize = 3
 
const uint8_t kMitsubishiHeavy88FanAuto = 0
 
const uint8_t kMitsubishiHeavy88FanLow = 2
 
const uint8_t kMitsubishiHeavy88FanMed = 3
 
const uint8_t kMitsubishiHeavy88FanHigh = 4
 
const uint8_t kMitsubishiHeavy88FanTurbo = 6
 
const uint8_t kMitsubishiHeavy88FanEcono = 7
 
const uint8_t kMitsubishiHeavy88SwingVByte5Offset = 1
 
const uint8_t kMitsubishiHeavy88SwingVByte5Size = 1
 
const uint8_t kMitsubishiHeavy88SwingVByte7Offset = 3
 
const uint8_t kMitsubishiHeavy88SwingVByte7Size = 2
 
const uint8_t kMitsubishiHeavy88SwingVOff = 0b000
 
const uint8_t kMitsubishiHeavy88SwingVAuto = 0b100
 
const uint8_t kMitsubishiHeavy88SwingVHighest = 0b110
 
const uint8_t kMitsubishiHeavy88SwingVHigh = 0b001
 
const uint8_t kMitsubishiHeavy88SwingVMiddle = 0b011
 
const uint8_t kMitsubishiHeavy88SwingVLow = 0b101
 
const uint8_t kMitsubishiHeavy88SwingVLowest = 0b111
 
+

Detailed Description

+

Support for Mitsubishi Heavy Industry protocols. Code to emulate Mitsubishi Heavy Industries A/C IR remote control units.

+
Note
This code was heavily influenced by ToniA's great work & code, but it has been written from scratch. Nothing was copied other than constants and message analysis.
+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/660
+
+https://github.com/ToniA/Raw-IR-decoder-for-Arduino/blob/master/MitsubishiHeavy.cpp
+
+https://github.com/ToniA/arduino-heatpumpir/blob/master/MitsubishiHeavyHeatpumpIR.cpp
+

Variable Documentation

+ +

◆ kMitsubishiHeavy152FanAuto

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152FanAuto = 0x0
+
+ +
+
+ +

◆ kMitsubishiHeavy152FanEcono

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152FanEcono = 0x6
+
+ +
+
+ +

◆ kMitsubishiHeavy152FanHigh

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152FanHigh = 0x3
+
+ +
+
+ +

◆ kMitsubishiHeavy152FanLow

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152FanLow = 0x1
+
+ +
+
+ +

◆ kMitsubishiHeavy152FanMax

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152FanMax = 0x4
+
+ +
+
+ +

◆ kMitsubishiHeavy152FanMed

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152FanMed = 0x2
+
+ +
+
+ +

◆ kMitsubishiHeavy152FanTurbo

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152FanTurbo = 0x8
+
+ +
+
+ +

◆ kMitsubishiHeavy152SwingHAuto

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152SwingHAuto = 0
+
+ +
+
+ +

◆ kMitsubishiHeavy152SwingHLeft

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152SwingHLeft = 2
+
+ +
+
+ +

◆ kMitsubishiHeavy152SwingHLeftMax

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152SwingHLeftMax = 1
+
+ +
+
+ +

◆ kMitsubishiHeavy152SwingHLeftRight

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152SwingHLeftRight = 7
+
+ +
+
+ +

◆ kMitsubishiHeavy152SwingHMiddle

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152SwingHMiddle = 3
+
+ +
+
+ +

◆ kMitsubishiHeavy152SwingHOff

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152SwingHOff = 8
+
+ +
+
+ +

◆ kMitsubishiHeavy152SwingHRight

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152SwingHRight = 4
+
+ +
+
+ +

◆ kMitsubishiHeavy152SwingHRightLeft

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152SwingHRightLeft = 6
+
+ +
+
+ +

◆ kMitsubishiHeavy152SwingHRightMax

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152SwingHRightMax = 5
+
+ +
+
+ +

◆ kMitsubishiHeavy152SwingVAuto

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152SwingVAuto = 0
+
+ +
+
+ +

◆ kMitsubishiHeavy152SwingVHigh

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152SwingVHigh = 2
+
+ +
+
+ +

◆ kMitsubishiHeavy152SwingVHighest

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152SwingVHighest = 1
+
+ +
+
+ +

◆ kMitsubishiHeavy152SwingVLow

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152SwingVLow = 4
+
+ +
+
+ +

◆ kMitsubishiHeavy152SwingVLowest

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152SwingVLowest = 5
+
+ +
+
+ +

◆ kMitsubishiHeavy152SwingVMiddle

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152SwingVMiddle = 3
+
+ +
+
+ +

◆ kMitsubishiHeavy152SwingVOff

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152SwingVOff = 6
+
+ +
+
+ +

◆ kMitsubishiHeavy152SwingVOffset

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152SwingVOffset = 5
+
+ +
+
+ +

◆ kMitsubishiHeavy152SwingVSize

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy152SwingVSize = 3
+
+ +
+
+ +

◆ kMitsubishiHeavy3DMask

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy3DMask = 0b00010010
+
+ +
+
+ +

◆ kMitsubishiHeavy88CleanOffset

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88CleanOffset = 5
+
+ +
+
+ +

◆ kMitsubishiHeavy88FanAuto

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88FanAuto = 0
+
+ +
+
+ +

◆ kMitsubishiHeavy88FanEcono

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88FanEcono = 7
+
+ +
+
+ +

◆ kMitsubishiHeavy88FanHigh

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88FanHigh = 4
+
+ +
+
+ +

◆ kMitsubishiHeavy88FanLow

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88FanLow = 2
+
+ +
+
+ +

◆ kMitsubishiHeavy88FanMed

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88FanMed = 3
+
+ +
+
+ +

◆ kMitsubishiHeavy88FanOffset

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88FanOffset = 5
+
+ +
+
+ +

◆ kMitsubishiHeavy88FanSize

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88FanSize = 3
+
+ +
+
+ +

◆ kMitsubishiHeavy88FanTurbo

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88FanTurbo = 6
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingH3D

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingH3D = 0b1110
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingHAuto

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingHAuto = 0b1000
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingHLeft

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingHLeft = 0b0101
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingHLeftMax

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingHLeftMax = 0b0001
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingHLeftRight

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingHLeftRight = 0b0110
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingHMiddle

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingHMiddle = 0b1001
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingHOff

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingHOff = 0b0000
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingHOffset1

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingHOffset1 = 2
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingHOffset2

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingHOffset2 = 6
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingHRight

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingHRight = 0b1101
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingHRightLeft

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingHRightLeft = 0b1010
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingHRightMax

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingHRightMax = 0b0010
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingHSize

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingHSize = 2
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingVAuto

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingVAuto = 0b100
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingVByte5Offset

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingVByte5Offset = 1
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingVByte5Size

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingVByte5Size = 1
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingVByte7Offset

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingVByte7Offset = 3
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingVByte7Size

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingVByte7Size = 2
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingVHigh

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingVHigh = 0b001
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingVHighest

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingVHighest = 0b110
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingVLow

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingVLow = 0b101
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingVLowest

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingVLowest = 0b111
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingVMiddle

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingVMiddle = 0b011
+
+ +
+
+ +

◆ kMitsubishiHeavy88SwingVOff

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavy88SwingVOff = 0b000
+
+ +
+
+ +

◆ kMitsubishiHeavyAuto

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavyAuto = 0
+
+ +
+
+ +

◆ kMitsubishiHeavyCleanOffset

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavyCleanOffset = 5
+
+ +
+
+ +

◆ kMitsubishiHeavyCool

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavyCool = 1
+
+ +
+
+ +

◆ kMitsubishiHeavyDry

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavyDry = 2
+
+ +
+
+ +

◆ kMitsubishiHeavyFan

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavyFan = 3
+
+ +
+
+ +

◆ kMitsubishiHeavyFilterOffset

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavyFilterOffset = 6
+
+ +
+
+ +

◆ kMitsubishiHeavyHeat

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavyHeat = 4
+
+ +
+
+ +

◆ kMitsubishiHeavyMaxTemp

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavyMaxTemp = 31
+
+ +
+
+ +

◆ kMitsubishiHeavyMinTemp

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavyMinTemp = 17
+
+ +
+
+ +

◆ kMitsubishiHeavyModeOffset

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavyModeOffset = 0
+
+ +
+
+ +

◆ kMitsubishiHeavyNightOffset

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavyNightOffset = 6
+
+ +
+
+ +

◆ kMitsubishiHeavyPowerOffset

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavyPowerOffset = 3
+
+ +
+
+ +

◆ kMitsubishiHeavySigLength

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavySigLength = 5
+
+ +
+
+ +

◆ kMitsubishiHeavySilentOffset

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavySilentOffset = 7
+
+ +
+
+ +

◆ kMitsubishiHeavyZjsSig

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavyZjsSig[kMitsubishiHeavySigLength]
+
+Initial value:
= {
+
0xAD, 0x51, 0x3C, 0xD9, 0x26}
+
+
+
+ +

◆ kMitsubishiHeavyZmsSig

+ +
+
+ + + + +
const uint8_t kMitsubishiHeavyZmsSig[kMitsubishiHeavySigLength]
+
+Initial value:
= {
+
0xAD, 0x51, 0x3C, 0xE5, 0x1A}
+
+
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__MitsubishiHeavy_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__MitsubishiHeavy_8h_source.html new file mode 100644 index 000000000..eed842d5d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__MitsubishiHeavy_8h_source.html @@ -0,0 +1,536 @@ + + + + + + + +IRremoteESP8266: src/ir_MitsubishiHeavy.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_MitsubishiHeavy.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 David Conran
+
2 
+
12 
+
13 // Supports:
+
14 // Brand: Mitsubishi Heavy Industries, Model: RLA502A700B remote (152 bit)
+
15 // Brand: Mitsubishi Heavy Industries, Model: SRKxxZM-S A/C (152 bit)
+
16 // Brand: Mitsubishi Heavy Industries, Model: SRKxxZMXA-S A/C (152 bit)
+
17 // Brand: Mitsubishi Heavy Industries, Model: RKX502A001C remote (88 bit)
+
18 // Brand: Mitsubishi Heavy Industries, Model: SRKxxZJ-S A/C (88 bit)
+
19 
+
20 #ifndef IR_MITSUBISHIHEAVY_H_
+
21 #define IR_MITSUBISHIHEAVY_H_
+
22 
+
23 #ifndef UNIT_TEST
+
24 #include <Arduino.h>
+
25 #endif
+
26 #include "IRremoteESP8266.h"
+
27 #include "IRsend.h"
+
28 #ifdef UNIT_TEST
+
29 #include "IRsend_test.h"
+
30 #endif
+
31 
+
32 // Constants.
+
33 const uint8_t kMitsubishiHeavySigLength = 5;
+
34 
+
35 // ZMS (152 bit)
+ +
37  0xAD, 0x51, 0x3C, 0xE5, 0x1A};
+
38 // Byte[5]
+
39 const uint8_t kMitsubishiHeavyModeOffset = 0;
+
40 // Mode Mask = 0b00000111; // Byte 9 on ZJS
+
41 const uint8_t kMitsubishiHeavyAuto = 0; // 0b000
+
42 const uint8_t kMitsubishiHeavyCool = 1; // 0b001
+
43 const uint8_t kMitsubishiHeavyDry = 2; // 0b010
+
44 const uint8_t kMitsubishiHeavyFan = 3; // 0b011
+
45 const uint8_t kMitsubishiHeavyHeat = 4; // 0b100
+
46 const uint8_t kMitsubishiHeavyPowerOffset = 3; // Byte 9 on ZJS
+
47 const uint8_t kMitsubishiHeavyCleanOffset = 5;
+
48 const uint8_t kMitsubishiHeavyFilterOffset = 6;
+
49 // Byte[7]
+
50 const uint8_t kMitsubishiHeavyMinTemp = 17; // 17C
+
51 const uint8_t kMitsubishiHeavyMaxTemp = 31; // 31C
+
52 // Byte[9]
+
53 // FanMask = 0b00001111; // ~Byte 7 on ZJS.
+
54 const uint8_t kMitsubishiHeavy152FanAuto = 0x0; // 0b0000
+
55 const uint8_t kMitsubishiHeavy152FanLow = 0x1; // 0b0001
+
56 const uint8_t kMitsubishiHeavy152FanMed = 0x2; // 0b0010
+
57 const uint8_t kMitsubishiHeavy152FanHigh = 0x3; // 0b0011
+
58 const uint8_t kMitsubishiHeavy152FanMax = 0x4; // 0b0100
+
59 const uint8_t kMitsubishiHeavy152FanEcono = 0x6; // 0b0110
+
60 const uint8_t kMitsubishiHeavy152FanTurbo = 0x8; // 0b1000
+
61 // Byte[11]
+
62 const uint8_t kMitsubishiHeavy3DMask = 0b00010010;
+ +
64 const uint8_t kMitsubishiHeavy152SwingVSize = 3; // Bits
+
65 const uint8_t kMitsubishiHeavy152SwingVAuto = 0; // 0b000
+
66 const uint8_t kMitsubishiHeavy152SwingVHighest = 1; // 0b001
+
67 const uint8_t kMitsubishiHeavy152SwingVHigh = 2; // 0b010
+
68 const uint8_t kMitsubishiHeavy152SwingVMiddle = 3; // 0b011
+
69 const uint8_t kMitsubishiHeavy152SwingVLow = 4; // 0b100
+
70 const uint8_t kMitsubishiHeavy152SwingVLowest = 5; // 0b101
+
71 const uint8_t kMitsubishiHeavy152SwingVOff = 6; // 0b110
+
72 // Byte[13]
+
73 const uint8_t kMitsubishiHeavy152SwingHAuto = 0; // 0b0000
+
74 const uint8_t kMitsubishiHeavy152SwingHLeftMax = 1; // 0b0001
+
75 const uint8_t kMitsubishiHeavy152SwingHLeft = 2; // 0b0010
+
76 const uint8_t kMitsubishiHeavy152SwingHMiddle = 3; // 0b0011
+
77 const uint8_t kMitsubishiHeavy152SwingHRight = 4; // 0b0100
+
78 const uint8_t kMitsubishiHeavy152SwingHRightMax = 5; // 0b0101
+
79 const uint8_t kMitsubishiHeavy152SwingHRightLeft = 6; // 0b0110
+
80 const uint8_t kMitsubishiHeavy152SwingHLeftRight = 7; // 0b0111
+
81 const uint8_t kMitsubishiHeavy152SwingHOff = 8; // 0b1000
+
82 // Byte[15]
+
83 const uint8_t kMitsubishiHeavyNightOffset = 6;
+
84 const uint8_t kMitsubishiHeavySilentOffset = 7;
+
85 
+
86 
+
87 // ZJS (88 bit)
+ +
89  0xAD, 0x51, 0x3C, 0xD9, 0x26};
+
90 // Byte [5]
+ + + +
94 const uint8_t kMitsubishiHeavy88SwingHSize = 2; // Bits (per offset)
+
95 const uint8_t kMitsubishiHeavy88SwingHOff = 0b0000;
+
96 const uint8_t kMitsubishiHeavy88SwingHAuto = 0b1000;
+
97 const uint8_t kMitsubishiHeavy88SwingHLeftMax = 0b0001;
+
98 const uint8_t kMitsubishiHeavy88SwingHLeft = 0b0101;
+
99 const uint8_t kMitsubishiHeavy88SwingHMiddle = 0b1001;
+
100 const uint8_t kMitsubishiHeavy88SwingHRight = 0b1101;
+
101 const uint8_t kMitsubishiHeavy88SwingHRightMax = 0b0010;
+
102 const uint8_t kMitsubishiHeavy88SwingHRightLeft = 0b1010;
+
103 const uint8_t kMitsubishiHeavy88SwingHLeftRight = 0b0110;
+
104 const uint8_t kMitsubishiHeavy88SwingH3D = 0b1110;
+
105 // Byte[7]
+
106 const uint8_t kMitsubishiHeavy88FanOffset = 5;
+
107 const uint8_t kMitsubishiHeavy88FanSize = 3; // Bits
+
108 const uint8_t kMitsubishiHeavy88FanAuto = 0; // 0b000
+
109 const uint8_t kMitsubishiHeavy88FanLow = 2; // 0b010
+
110 const uint8_t kMitsubishiHeavy88FanMed = 3; // 0b011
+
111 const uint8_t kMitsubishiHeavy88FanHigh = 4; // 0b100
+
112 const uint8_t kMitsubishiHeavy88FanTurbo = 6; // 0b110
+
113 const uint8_t kMitsubishiHeavy88FanEcono = 7; // 0b111
+ + + + +
118 
+
119  // Mask 0b111
+
120 const uint8_t kMitsubishiHeavy88SwingVOff = 0b000; // 0
+
121 const uint8_t kMitsubishiHeavy88SwingVAuto = 0b100; // 4
+
122 const uint8_t kMitsubishiHeavy88SwingVHighest = 0b110; // 6
+
123 const uint8_t kMitsubishiHeavy88SwingVHigh = 0b001; // 1
+
124 const uint8_t kMitsubishiHeavy88SwingVMiddle = 0b011; // 3
+
125 const uint8_t kMitsubishiHeavy88SwingVLow = 0b101; // 5
+
126 const uint8_t kMitsubishiHeavy88SwingVLowest = 0b111; // 7
+
127 // Byte[9] is Power & Mode & Temp.
+
128 
+
129 
+
130 // Classes
+
131 
+ +
134  public:
+
135  explicit IRMitsubishiHeavy152Ac(const uint16_t pin,
+
136  const bool inverted = false,
+
137  const bool use_modulation = true);
+
138  void stateReset(void);
+
139 #if SEND_MITSUBISHIHEAVY
+
140  void send(const uint16_t repeat = kMitsubishiHeavy152MinRepeat);
+
145  int8_t calibrate(void) { return _irsend.calibrate(); }
+
146 #endif // SEND_MITSUBISHIHEAVY
+
147  void begin(void);
+
148  void on(void);
+
149  void off(void);
+
150 
+
151  void setPower(const bool on);
+
152  bool getPower(void);
+
153 
+
154  void setTemp(const uint8_t temp);
+
155  uint8_t getTemp(void);
+
156 
+
157  void setFan(const uint8_t fan);
+
158  uint8_t getFan(void);
+
159 
+
160  void setMode(const uint8_t mode);
+
161  uint8_t getMode(void);
+
162 
+
163  void setSwingVertical(const uint8_t pos);
+
164  uint8_t getSwingVertical(void);
+
165  void setSwingHorizontal(const uint8_t pos);
+
166  uint8_t getSwingHorizontal(void);
+
167 
+
168  void setNight(const bool on);
+
169  bool getNight(void);
+
170 
+
171  void set3D(const bool on);
+
172  bool get3D(void);
+
173 
+
174  void setSilent(const bool on);
+
175  bool getSilent(void);
+
176 
+
177  void setFilter(const bool on);
+
178  bool getFilter(void);
+
179 
+
180  void setClean(const bool on);
+
181  bool getClean(void);
+
182 
+
183  void setTurbo(const bool on);
+
184  bool getTurbo(void);
+
185 
+
186  void setEcono(const bool on);
+
187  bool getEcono(void);
+
188 
+
189  uint8_t* getRaw(void);
+
190  void setRaw(const uint8_t* data);
+
191 
+
192  static bool checkZmsSig(const uint8_t *state);
+
193  static bool validChecksum(
+
194  const uint8_t *state,
+
195  const uint16_t length = kMitsubishiHeavy152StateLength);
+
196  static uint8_t convertMode(const stdAc::opmode_t mode);
+
197  static uint8_t convertFan(const stdAc::fanspeed_t speed);
+
198  static uint8_t convertSwingV(const stdAc::swingv_t position);
+
199  static uint8_t convertSwingH(const stdAc::swingh_t position);
+
200  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
201  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
202  static stdAc::swingv_t toCommonSwingV(const uint8_t pos);
+
203  static stdAc::swingh_t toCommonSwingH(const uint8_t pos);
+
204  stdAc::state_t toCommon(void);
+
205  String toString(void);
+
206 #ifndef UNIT_TEST
+
207 
+
208  private:
+ +
210 #else // UNIT_TEST
+
211  IRsendTest _irsend;
+
213 #endif // UNIT_TEST
+ +
216  void checksum(void);
+
217 };
+
218 
+ +
221  public:
+
222  explicit IRMitsubishiHeavy88Ac(const uint16_t pin,
+
223  const bool inverted = false,
+
224  const bool use_modulation = true);
+
225  void stateReset(void);
+
226 #if SEND_MITSUBISHIHEAVY
+
227  void send(const uint16_t repeat = kMitsubishiHeavy88MinRepeat);
+
232  int8_t calibrate(void) { return _irsend.calibrate(); }
+
233 #endif // SEND_MITSUBISHIHEAVY
+
234  void begin(void);
+
235  void on(void);
+
236  void off(void);
+
237 
+
238  void setPower(const bool on);
+
239  bool getPower(void);
+
240 
+
241  void setTemp(const uint8_t temp);
+
242  uint8_t getTemp(void);
+
243 
+
244  void setFan(const uint8_t fan);
+
245  uint8_t getFan(void);
+
246 
+
247  void setMode(const uint8_t mode);
+
248  uint8_t getMode(void);
+
249 
+
250  void setSwingVertical(const uint8_t pos);
+
251  uint8_t getSwingVertical(void);
+
252  void setSwingHorizontal(const uint8_t pos);
+
253  uint8_t getSwingHorizontal(void);
+
254 
+
255  void setTurbo(const bool on);
+
256  bool getTurbo(void);
+
257 
+
258  void setEcono(const bool on);
+
259  bool getEcono(void);
+
260 
+
261  void set3D(const bool on);
+
262  bool get3D(void);
+
263 
+
264  void setClean(const bool on);
+
265  bool getClean(void);
+
266 
+
267  uint8_t* getRaw(void);
+
268  void setRaw(const uint8_t* data);
+
269 
+
270  static bool checkZjsSig(const uint8_t *state);
+
271  static bool validChecksum(
+
272  const uint8_t *state,
+
273  const uint16_t length = kMitsubishiHeavy88StateLength);
+
274  static uint8_t convertMode(const stdAc::opmode_t mode);
+
275  static uint8_t convertFan(const stdAc::fanspeed_t speed);
+
276  static uint8_t convertSwingV(const stdAc::swingv_t position);
+
277  static uint8_t convertSwingH(const stdAc::swingh_t position);
+
278  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
279  static stdAc::swingv_t toCommonSwingV(const uint8_t pos);
+
280  static stdAc::swingh_t toCommonSwingH(const uint8_t pos);
+
281  stdAc::state_t toCommon(void);
+
282  String toString(void);
+
283 #ifndef UNIT_TEST
+
284 
+
285  private:
+ +
287 #else // UNIT_TEST
+
288  IRsendTest _irsend;
+
290 #endif // UNIT_TEST
+ +
293  void checksum(void);
+
294 };
+
295 #endif // IR_MITSUBISHIHEAVY_H_
+
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_MitsubishiHeavy.cpp:976
+
void setFan(const uint8_t fan)
Set the speed of the fan.
Definition: ir_MitsubishiHeavy.cpp:688
+
void off(void)
Set the requested power state of the A/C to off.
Definition: ir_MitsubishiHeavy.cpp:655
+
const uint8_t kMitsubishiHeavy88SwingVByte5Size
Definition: ir_MitsubishiHeavy.h:115
+
const uint16_t kMitsubishiHeavy152StateLength
Definition: IRremoteESP8266.h:942
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_MitsubishiHeavy.h:145
+
Class for handling detailed Mitsubishi Heavy 152-bit A/C messages.
Definition: ir_MitsubishiHeavy.h:133
+
void stateReset(void)
Reset the state of the remote to a known good state/sequence.
Definition: ir_MitsubishiHeavy.cpp:632
+
String toString(void)
Convert the internal state into a human readable string.
Definition: ir_MitsubishiHeavy.cpp:1002
+
void checksum(void)
Calculate the checksum for the current internal state of the remote. Note: Technically it has no chec...
Definition: ir_MitsubishiHeavy.cpp:325
+
const uint8_t kMitsubishiHeavy152SwingVHigh
Definition: ir_MitsubishiHeavy.h:67
+
static uint8_t convertSwingH(const stdAc::swingh_t position)
Convert a stdAc::swingh_t enum into it's native setting.
Definition: ir_MitsubishiHeavy.cpp:398
+
const uint8_t kMitsubishiHeavy152SwingHRightLeft
Definition: ir_MitsubishiHeavy.h:79
+
static uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_MitsubishiHeavy.cpp:355
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_MitsubishiHeavy.cpp:665
+
const uint8_t kMitsubishiHeavy3DMask
Definition: ir_MitsubishiHeavy.h:62
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_MitsubishiHeavy.cpp:933
+
bool getEcono(void)
Get the Economical mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:310
+
void setPower(const bool on)
Change the power setting.
Definition: ir_MitsubishiHeavy.cpp:123
+
void set3D(const bool on)
Set the 3D mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:824
+
swingv_t
Common A/C settings for Vertical Swing.
Definition: IRsend.h:70
+
const uint8_t kMitsubishiHeavy152FanMed
Definition: ir_MitsubishiHeavy.h:56
+
const uint8_t kMitsubishiHeavyCleanOffset
Definition: ir_MitsubishiHeavy.h:47
+
void setSwingHorizontal(const uint8_t pos)
Set the Horizontal Swing mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:763
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_MitsubishiHeavy.h:209
+
const uint8_t kMitsubishiHeavy152FanAuto
Definition: ir_MitsubishiHeavy.h:54
+
IRMitsubishiHeavy152Ac(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_MitsubishiHeavy.cpp:77
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
const uint8_t kMitsubishiHeavy152SwingVAuto
Definition: ir_MitsubishiHeavy.h:65
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:711
+
const uint8_t kMitsubishiHeavy88FanTurbo
Definition: ir_MitsubishiHeavy.h:112
+
static uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_MitsubishiHeavy.cpp:888
+
const uint8_t kMitsubishiHeavy88SwingHLeftMax
Definition: ir_MitsubishiHeavy.h:97
+
const uint8_t kMitsubishiHeavy152SwingVHighest
Definition: ir_MitsubishiHeavy.h:66
+
const uint8_t kMitsubishiHeavy88SwingH3D
Definition: ir_MitsubishiHeavy.h:104
+
const uint8_t kMitsubishiHeavy88SwingHLeft
Definition: ir_MitsubishiHeavy.h:98
+
const uint8_t kMitsubishiHeavy152SwingVLow
Definition: ir_MitsubishiHeavy.h:69
+
const uint8_t kMitsubishiHeavyNightOffset
Definition: ir_MitsubishiHeavy.h:83
+
const uint8_t kMitsubishiHeavy152SwingHOff
Definition: ir_MitsubishiHeavy.h:81
+
const uint8_t kMitsubishiHeavy88SwingHOffset1
Definition: ir_MitsubishiHeavy.h:92
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_MitsubishiHeavy.cpp:129
+
void stateReset(void)
Reset the state of the remote to a known good state/sequence.
Definition: ir_MitsubishiHeavy.cpp:95
+ +
const uint8_t kMitsubishiHeavy152SwingHLeftRight
Definition: ir_MitsubishiHeavy.h:80
+
void checksum(void)
Calculate the checksum for the current internal state of the remote. Note: Technically it has no chec...
Definition: ir_MitsubishiHeavy.cpp:860
+
const uint8_t kMitsubishiHeavy88SwingHMiddle
Definition: ir_MitsubishiHeavy.h:99
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_MitsubishiHeavy.cpp:426
+
void on(void)
Set the requested power state of the A/C to on.
Definition: ir_MitsubishiHeavy.cpp:652
+
bool getTurbo(void)
Get the Turbo mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:296
+
const uint8_t kMitsubishiHeavy88SwingVAuto
Definition: ir_MitsubishiHeavy.h:121
+
String toString(void)
Convert the internal state into a human readable string.
Definition: ir_MitsubishiHeavy.cpp:495
+
void setClean(const bool on)
Set the Clean mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:839
+
void setSilent(const bool on)
Set the Silent (Quiet) mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:251
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
const uint8_t kMitsubishiHeavy88FanEcono
Definition: ir_MitsubishiHeavy.h:113
+
void setSwingVertical(const uint8_t pos)
Set the Vertical Swing mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:733
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_MitsubishiHeavy.cpp:145
+
const uint8_t kMitsubishiHeavy88SwingHSize
Definition: ir_MitsubishiHeavy.h:94
+
void setClean(const bool on)
Set the Clean mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:275
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_MitsubishiHeavy.cpp:135
+
const uint8_t kMitsubishiHeavyPowerOffset
Definition: ir_MitsubishiHeavy.h:46
+
void on(void)
Set the requested power state of the A/C to on.
Definition: ir_MitsubishiHeavy.cpp:116
+
std::string String
Definition: IRremoteESP8266.h:1093
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_MitsubishiHeavy.cpp:83
+
uint8_t getSwingVertical(void)
Get the Vertical Swing mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:753
+
const uint8_t kMitsubishiHeavyFilterOffset
Definition: ir_MitsubishiHeavy.h:48
+
static uint8_t convertSwingV(const stdAc::swingv_t position)
Convert a stdAc::swingv_t enum into it's native setting.
Definition: ir_MitsubishiHeavy.cpp:903
+
void setNight(const bool on)
Set the Night (Sleep) mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:224
+
const uint8_t kMitsubishiHeavy88SwingHOffset2
Definition: ir_MitsubishiHeavy.h:93
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_MitsubishiHeavy.h:286
+
const uint8_t kMitsubishiHeavy152SwingVSize
Definition: ir_MitsubishiHeavy.h:64
+
const uint8_t kMitsubishiHeavySigLength
Definition: ir_MitsubishiHeavy.h:33
+
uint8_t getSwingVertical(void)
Get the Vertical Swing mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:204
+
void off(void)
Set the requested power state of the A/C to off.
Definition: ir_MitsubishiHeavy.cpp:119
+
void setSwingVertical(const uint8_t pos)
Set the Vertical Swing mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:196
+
const uint8_t kMitsubishiHeavy88SwingHRightLeft
Definition: ir_MitsubishiHeavy.h:102
+
uint8_t remote_state[kMitsubishiHeavy88StateLength]
State in code form.
Definition: ir_MitsubishiHeavy.h:292
+
const uint8_t kMitsubishiHeavy152SwingHRight
Definition: ir_MitsubishiHeavy.h:77
+
uint8_t getSwingHorizontal(void)
Get the Horizontal Swing mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:786
+
const uint8_t kMitsubishiHeavyHeat
Definition: ir_MitsubishiHeavy.h:45
+
uint8_t getSwingHorizontal(void)
Get the Horizontal Swing mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:218
+
void setTurbo(const bool on)
Set the Turbo mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:796
+
bool getNight(void)
Get the Night (Sleep) mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:230
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_MitsubishiHeavy.cpp:704
+ +
swingh_t
Common A/C settings for Horizontal Swing.
Definition: IRsend.h:83
+
const uint8_t kMitsubishiHeavy152SwingHLeftMax
Definition: ir_MitsubishiHeavy.h:74
+
bool getClean(void)
Get the Clean mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:282
+
const uint8_t kMitsubishiHeavyZmsSig[kMitsubishiHeavySigLength]
Definition: ir_MitsubishiHeavy.h:36
+
bool getEcono(void)
Get the Economical mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:818
+
const uint16_t kMitsubishiHeavy152MinRepeat
Definition: IRremoteESP8266.h:944
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_MitsubishiHeavy.h:232
+
const uint8_t kMitsubishiHeavy88SwingVByte5Offset
Definition: ir_MitsubishiHeavy.h:114
+
static bool checkZjsSig(const uint8_t *state)
Verify the given state has a ZJ-S signature.
Definition: ir_MitsubishiHeavy.cpp:852
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_MitsubishiHeavy.cpp:671
+
IRMitsubishiHeavy88Ac(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_MitsubishiHeavy.cpp:614
+
const uint8_t kMitsubishiHeavy88FanOffset
Definition: ir_MitsubishiHeavy.h:106
+
const uint8_t kMitsubishiHeavyMaxTemp
Definition: ir_MitsubishiHeavy.h:51
+
void setRaw(const uint8_t *data)
Set the internal state from a valid code for this protocol.
Definition: ir_MitsubishiHeavy.cpp:647
+
const uint16_t kMitsubishiHeavy88StateLength
Definition: IRremoteESP8266.h:939
+
const uint8_t kMitsubishiHeavy88SwingVMiddle
Definition: ir_MitsubishiHeavy.h:124
+
static uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_MitsubishiHeavy.cpp:368
+
const uint8_t kMitsubishiHeavyZjsSig[kMitsubishiHeavySigLength]
Definition: ir_MitsubishiHeavy.h:88
+
const uint8_t kMitsubishiHeavy152FanLow
Definition: ir_MitsubishiHeavy.h:55
+
const uint8_t kMitsubishiHeavy88FanHigh
Definition: ir_MitsubishiHeavy.h:111
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_MitsubishiHeavy.cpp:413
+
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_MitsubishiHeavy.cpp:104
+
const uint8_t kMitsubishiHeavyMinTemp
Definition: ir_MitsubishiHeavy.h:50
+
const uint8_t kMitsubishiHeavyCool
Definition: ir_MitsubishiHeavy.h:42
+
void setEcono(const bool on)
Set the Economical mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:302
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_MitsubishiHeavy.cpp:681
+
bool getSilent(void)
Get the Silent (Quiet) mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:257
+
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_MitsubishiHeavy.cpp:640
+
const uint8_t kMitsubishiHeavy88FanLow
Definition: ir_MitsubishiHeavy.h:109
+
const uint8_t kMitsubishiHeavy88SwingVLow
Definition: ir_MitsubishiHeavy.h:125
+
static bool checkZmsSig(const uint8_t *state)
Verify the given state has a ZM-S signature.
Definition: ir_MitsubishiHeavy.cpp:317
+
const uint8_t kMitsubishiHeavy152SwingVMiddle
Definition: ir_MitsubishiHeavy.h:68
+
const uint8_t kMitsubishiHeavy88SwingHRight
Definition: ir_MitsubishiHeavy.h:100
+
const uint8_t kMitsubishiHeavy88SwingVHighest
Definition: ir_MitsubishiHeavy.h:122
+
const uint8_t kMitsubishiHeavyModeOffset
Definition: ir_MitsubishiHeavy.h:39
+
const uint8_t kMitsubishiHeavy88SwingVOff
Definition: ir_MitsubishiHeavy.h:120
+
bool getTurbo(void)
Get the Turbo mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:804
+
void setEcono(const bool on)
Set the Economical mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:810
+
const uint8_t kMitsubishiHeavy88SwingVLowest
Definition: ir_MitsubishiHeavy.h:126
+
const uint8_t kMitsubishiHeavy152SwingHAuto
Definition: ir_MitsubishiHeavy.h:73
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_MitsubishiHeavy.cpp:190
+
const uint8_t kMitsubishiHeavy152SwingHLeft
Definition: ir_MitsubishiHeavy.h:75
+
void setFan(const uint8_t fan)
Set the speed of the fan.
Definition: ir_MitsubishiHeavy.cpp:152
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_MitsubishiHeavy.cpp:469
+
const uint8_t kMitsubishiHeavySilentOffset
Definition: ir_MitsubishiHeavy.h:84
+
bool getClean(void)
Get the Clean mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:845
+
static uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_MitsubishiHeavy.cpp:881
+
const uint8_t kMitsubishiHeavy88SwingHAuto
Definition: ir_MitsubishiHeavy.h:96
+
const uint8_t kMitsubishiHeavyFan
Definition: ir_MitsubishiHeavy.h:44
+
const uint16_t kMitsubishiHeavy88MinRepeat
Definition: IRremoteESP8266.h:941
+
const uint8_t kMitsubishiHeavy88SwingHOff
Definition: ir_MitsubishiHeavy.h:95
+
void setSwingHorizontal(const uint8_t pos)
Set the Horizontal Swing mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:211
+
static bool validChecksum(const uint8_t *state, const uint16_t length=kMitsubishiHeavy152StateLength)
Verify the checksum is valid for a given state.
Definition: ir_MitsubishiHeavy.cpp:338
+
const uint8_t kMitsubishiHeavy152SwingVOff
Definition: ir_MitsubishiHeavy.h:71
+
const uint8_t kMitsubishiHeavy152SwingVLowest
Definition: ir_MitsubishiHeavy.h:70
+
void setRaw(const uint8_t *data)
Set the internal state from a valid code for this protocol.
Definition: ir_MitsubishiHeavy.cpp:111
+
const uint8_t kMitsubishiHeavy88SwingHLeftRight
Definition: ir_MitsubishiHeavy.h:103
+
const uint8_t kMitsubishiHeavy88FanAuto
Definition: ir_MitsubishiHeavy.h:108
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:174
+
static stdAc::swingh_t toCommonSwingH(const uint8_t pos)
Convert a native horizontal swing postion to it's common equivalent.
Definition: ir_MitsubishiHeavy.cpp:440
+
const uint8_t kMitsubishiHeavy88FanMed
Definition: ir_MitsubishiHeavy.h:110
+
void setTurbo(const bool on)
Set the Turbo mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:288
+
uint8_t remote_state[kMitsubishiHeavy152StateLength]
State in code form.
Definition: ir_MitsubishiHeavy.h:215
+
bool getFilter(void)
Get the Filter mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:269
+
bool get3D(void)
Get the 3D mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:833
+
const uint8_t kMitsubishiHeavy88SwingHRightMax
Definition: ir_MitsubishiHeavy.h:101
+
const uint8_t kMitsubishiHeavy152SwingVOffset
Definition: ir_MitsubishiHeavy.h:63
+
void setPower(const bool on)
Change the power setting.
Definition: ir_MitsubishiHeavy.cpp:659
+
const uint8_t kMitsubishiHeavy88SwingVByte7Size
Definition: ir_MitsubishiHeavy.h:117
+
const uint8_t kMitsubishiHeavy152FanHigh
Definition: ir_MitsubishiHeavy.h:57
+
void setFilter(const bool on)
Set the Filter mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:263
+
static bool validChecksum(const uint8_t *state, const uint16_t length=kMitsubishiHeavy88StateLength)
Verify the checksum is valid for a given state.
Definition: ir_MitsubishiHeavy.cpp:873
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_MitsubishiHeavy.cpp:620
+
const uint8_t kMitsubishiHeavy152SwingHRightMax
Definition: ir_MitsubishiHeavy.h:78
+
void set3D(const bool on)
Set the 3D mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:236
+
const uint8_t kMitsubishiHeavy152SwingHMiddle
Definition: ir_MitsubishiHeavy.h:76
+
static uint8_t convertSwingV(const stdAc::swingv_t position)
Convert a stdAc::swingv_t enum into it's native setting.
Definition: ir_MitsubishiHeavy.cpp:383
+
Class for handling detailed Mitsubishi Heavy 88-bit A/C messages.
Definition: ir_MitsubishiHeavy.h:220
+
const uint8_t kMitsubishiHeavy152FanTurbo
Definition: ir_MitsubishiHeavy.h:60
+
static stdAc::swingv_t toCommonSwingV(const uint8_t pos)
Convert a native vertical swing postion to it's common equivalent.
Definition: ir_MitsubishiHeavy.cpp:455
+
static uint8_t convertSwingH(const stdAc::swingh_t position)
Convert a stdAc::swingh_t enum into it's native setting.
Definition: ir_MitsubishiHeavy.cpp:918
+
const uint8_t kMitsubishiHeavyDry
Definition: ir_MitsubishiHeavy.h:43
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_MitsubishiHeavy.cpp:168
+
static stdAc::swingh_t toCommonSwingH(const uint8_t pos)
Convert a native horizontal swing postion to it's common equivalent.
Definition: ir_MitsubishiHeavy.cpp:947
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
const uint8_t kMitsubishiHeavy88FanSize
Definition: ir_MitsubishiHeavy.h:107
+
const uint8_t kMitsubishiHeavy88SwingVByte7Offset
Definition: ir_MitsubishiHeavy.h:116
+
const uint8_t kMitsubishiHeavy88SwingVHigh
Definition: ir_MitsubishiHeavy.h:123
+
static stdAc::swingv_t toCommonSwingV(const uint8_t pos)
Convert a native vertical swing postion to it's common equivalent.
Definition: ir_MitsubishiHeavy.cpp:962
+
void send(const uint16_t repeat=kMitsubishiHeavy88MinRepeat)
Send the current internal state as an IR message.
Definition: ir_MitsubishiHeavy.cpp:625
+
void send(const uint16_t repeat=kMitsubishiHeavy152MinRepeat)
Send the current internal state as an IR message.
Definition: ir_MitsubishiHeavy.cpp:88
+
const uint8_t kMitsubishiHeavy88CleanOffset
Definition: ir_MitsubishiHeavy.h:91
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_MitsubishiHeavy.cpp:727
+
const uint8_t kMitsubishiHeavyAuto
Definition: ir_MitsubishiHeavy.h:41
+
const uint8_t kMitsubishiHeavy152FanEcono
Definition: ir_MitsubishiHeavy.h:59
+
bool get3D(void)
Get the 3D mode of the A/C.
Definition: ir_MitsubishiHeavy.cpp:245
+
const uint8_t kMitsubishiHeavy152FanMax
Definition: ir_MitsubishiHeavy.h:58
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Mitsubishi_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Mitsubishi_8cpp.html new file mode 100644 index 000000000..ae23abaec --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Mitsubishi_8cpp.html @@ -0,0 +1,722 @@ + + + + + + + +IRremoteESP8266: src/ir_Mitsubishi.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Mitsubishi.cpp File Reference
+
+
+ +

Support for Mitsubishi protocols. Mitsubishi (TV) decoding added from https://github.com/z3t0/Arduino-IRremote Mitsubishi (TV) sending & Mitsubishi A/C support added by David Conran. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kMitsubishiTick = 30
 
const uint16_t kMitsubishiBitMarkTicks = 10
 
const uint16_t kMitsubishiBitMark = kMitsubishiBitMarkTicks * kMitsubishiTick
 
const uint16_t kMitsubishiOneSpaceTicks = 70
 
const uint16_t kMitsubishiOneSpace = kMitsubishiOneSpaceTicks * kMitsubishiTick
 
const uint16_t kMitsubishiZeroSpaceTicks = 30
 
const uint16_t kMitsubishiZeroSpace
 
const uint16_t kMitsubishiMinCommandLengthTicks = 1786
 
const uint16_t kMitsubishiMinCommandLength
 
const uint16_t kMitsubishiMinGapTicks = 936
 
const uint16_t kMitsubishiMinGap = kMitsubishiMinGapTicks * kMitsubishiTick
 
const uint16_t kMitsubishi2HdrMark = 8400
 
const uint16_t kMitsubishi2HdrSpace = kMitsubishi2HdrMark / 2
 
const uint16_t kMitsubishi2BitMark = 560
 
const uint16_t kMitsubishi2ZeroSpace = 520
 
const uint16_t kMitsubishi2OneSpace = kMitsubishi2ZeroSpace * 3
 
const uint16_t kMitsubishi2MinGap = 28500
 
const uint16_t kMitsubishiAcHdrMark = 3400
 
const uint16_t kMitsubishiAcHdrSpace = 1750
 
const uint16_t kMitsubishiAcBitMark = 450
 
const uint16_t kMitsubishiAcOneSpace = 1300
 
const uint16_t kMitsubishiAcZeroSpace = 420
 
const uint16_t kMitsubishiAcRptMark = 440
 
const uint16_t kMitsubishiAcRptSpace = 17100
 
const uint8_t kMitsubishiAcExtraTolerance = 5
 
const uint16_t kMitsubishi136HdrMark = 3324
 
const uint16_t kMitsubishi136HdrSpace = 1474
 
const uint16_t kMitsubishi136BitMark = 467
 
const uint16_t kMitsubishi136OneSpace = 1137
 
const uint16_t kMitsubishi136ZeroSpace = 351
 
const uint32_t kMitsubishi136Gap = kDefaultMessageGap
 
const uint16_t kMitsubishi112HdrMark = 3450
 
const uint16_t kMitsubishi112HdrSpace = 1696
 
const uint16_t kMitsubishi112BitMark = 450
 
const uint16_t kMitsubishi112OneSpace = 1250
 
const uint16_t kMitsubishi112ZeroSpace = 385
 
const uint32_t kMitsubishi112Gap = kDefaultMessageGap
 
const uint8_t kMitsubishi112HdrMarkTolerance = 5
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kMitsubishi112BitMark

+ +
+
+ + + + +
const uint16_t kMitsubishi112BitMark = 450
+
+ +
+
+ +

◆ kMitsubishi112Gap

+ +
+
+ + + + +
const uint32_t kMitsubishi112Gap = kDefaultMessageGap
+
+ +
+
+ +

◆ kMitsubishi112HdrMark

+ +
+
+ + + + +
const uint16_t kMitsubishi112HdrMark = 3450
+
+ +
+
+ +

◆ kMitsubishi112HdrMarkTolerance

+ +
+
+ + + + +
const uint8_t kMitsubishi112HdrMarkTolerance = 5
+
+ +
+
+ +

◆ kMitsubishi112HdrSpace

+ +
+
+ + + + +
const uint16_t kMitsubishi112HdrSpace = 1696
+
+ +
+
+ +

◆ kMitsubishi112OneSpace

+ +
+
+ + + + +
const uint16_t kMitsubishi112OneSpace = 1250
+
+ +
+
+ +

◆ kMitsubishi112ZeroSpace

+ +
+
+ + + + +
const uint16_t kMitsubishi112ZeroSpace = 385
+
+ +
+
+ +

◆ kMitsubishi136BitMark

+ +
+
+ + + + +
const uint16_t kMitsubishi136BitMark = 467
+
+ +
+
+ +

◆ kMitsubishi136Gap

+ +
+
+ + + + +
const uint32_t kMitsubishi136Gap = kDefaultMessageGap
+
+ +
+
+ +

◆ kMitsubishi136HdrMark

+ +
+
+ + + + +
const uint16_t kMitsubishi136HdrMark = 3324
+
+ +
+
+ +

◆ kMitsubishi136HdrSpace

+ +
+
+ + + + +
const uint16_t kMitsubishi136HdrSpace = 1474
+
+ +
+
+ +

◆ kMitsubishi136OneSpace

+ +
+
+ + + + +
const uint16_t kMitsubishi136OneSpace = 1137
+
+ +
+
+ +

◆ kMitsubishi136ZeroSpace

+ +
+
+ + + + +
const uint16_t kMitsubishi136ZeroSpace = 351
+
+ +
+
+ +

◆ kMitsubishi2BitMark

+ +
+
+ + + + +
const uint16_t kMitsubishi2BitMark = 560
+
+ +
+
+ +

◆ kMitsubishi2HdrMark

+ +
+
+ + + + +
const uint16_t kMitsubishi2HdrMark = 8400
+
+ +
+
+ +

◆ kMitsubishi2HdrSpace

+ +
+
+ + + + +
const uint16_t kMitsubishi2HdrSpace = kMitsubishi2HdrMark / 2
+
+ +
+
+ +

◆ kMitsubishi2MinGap

+ +
+
+ + + + +
const uint16_t kMitsubishi2MinGap = 28500
+
+ +
+
+ +

◆ kMitsubishi2OneSpace

+ +
+
+ + + + +
const uint16_t kMitsubishi2OneSpace = kMitsubishi2ZeroSpace * 3
+
+ +
+
+ +

◆ kMitsubishi2ZeroSpace

+ +
+
+ + + + +
const uint16_t kMitsubishi2ZeroSpace = 520
+
+ +
+
+ +

◆ kMitsubishiAcBitMark

+ +
+
+ + + + +
const uint16_t kMitsubishiAcBitMark = 450
+
+ +
+
+ +

◆ kMitsubishiAcExtraTolerance

+ +
+
+ + + + +
const uint8_t kMitsubishiAcExtraTolerance = 5
+
+ +
+
+ +

◆ kMitsubishiAcHdrMark

+ +
+
+ + + + +
const uint16_t kMitsubishiAcHdrMark = 3400
+
+ +
+
+ +

◆ kMitsubishiAcHdrSpace

+ +
+
+ + + + +
const uint16_t kMitsubishiAcHdrSpace = 1750
+
+ +
+
+ +

◆ kMitsubishiAcOneSpace

+ +
+
+ + + + +
const uint16_t kMitsubishiAcOneSpace = 1300
+
+ +
+
+ +

◆ kMitsubishiAcRptMark

+ +
+
+ + + + +
const uint16_t kMitsubishiAcRptMark = 440
+
+ +
+
+ +

◆ kMitsubishiAcRptSpace

+ +
+
+ + + + +
const uint16_t kMitsubishiAcRptSpace = 17100
+
+ +
+
+ +

◆ kMitsubishiAcZeroSpace

+ +
+
+ + + + +
const uint16_t kMitsubishiAcZeroSpace = 420
+
+ +
+
+ +

◆ kMitsubishiBitMark

+ +
+
+ + + + +
const uint16_t kMitsubishiBitMark = kMitsubishiBitMarkTicks * kMitsubishiTick
+
+ +
+
+ +

◆ kMitsubishiBitMarkTicks

+ +
+
+ + + + +
const uint16_t kMitsubishiBitMarkTicks = 10
+
+ +
+
+ +

◆ kMitsubishiMinCommandLength

+ +
+
+ + + + +
const uint16_t kMitsubishiMinCommandLength
+
+
+ +

◆ kMitsubishiMinCommandLengthTicks

+ +
+
+ + + + +
const uint16_t kMitsubishiMinCommandLengthTicks = 1786
+
+ +
+
+ +

◆ kMitsubishiMinGap

+ +
+
+ + + + +
const uint16_t kMitsubishiMinGap = kMitsubishiMinGapTicks * kMitsubishiTick
+
+ +
+
+ +

◆ kMitsubishiMinGapTicks

+ +
+
+ + + + +
const uint16_t kMitsubishiMinGapTicks = 936
+
+ +
+
+ +

◆ kMitsubishiOneSpace

+ +
+
+ + + + +
const uint16_t kMitsubishiOneSpace = kMitsubishiOneSpaceTicks * kMitsubishiTick
+
+ +
+
+ +

◆ kMitsubishiOneSpaceTicks

+ +
+
+ + + + +
const uint16_t kMitsubishiOneSpaceTicks = 70
+
+ +
+
+ +

◆ kMitsubishiTick

+ +
+
+ + + + +
const uint16_t kMitsubishiTick = 30
+
+ +
+
+ +

◆ kMitsubishiZeroSpace

+ +
+
+ + + + +
const uint16_t kMitsubishiZeroSpace
+
+Initial value: +
+
+ +

◆ kMitsubishiZeroSpaceTicks

+ +
+
+ + + + +
const uint16_t kMitsubishiZeroSpaceTicks = 30
+
+ +
+
+
+
const uint16_t kMitsubishiTick
Definition: ir_Mitsubishi.cpp:34
+
const uint16_t kMitsubishiMinCommandLengthTicks
Definition: ir_Mitsubishi.cpp:42
+
const uint16_t kMitsubishiZeroSpaceTicks
Definition: ir_Mitsubishi.cpp:39
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Mitsubishi_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Mitsubishi_8h.html new file mode 100644 index 000000000..968bfbb6c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Mitsubishi_8h.html @@ -0,0 +1,1609 @@ + + + + + + + +IRremoteESP8266: src/ir_Mitsubishi.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Mitsubishi.h File Reference
+
+
+ +

Support for Mitsubishi protocols. Mitsubishi (TV) decoding added from https://github.com/z3t0/Arduino-IRremote Mitsubishi (TV) sending & Mitsubishi A/C support added by David Conran. +More...

+ +

Go to the source code of this file.

+ + + + + + + + + + +

+Classes

class  IRMitsubishiAC
 Class for handling detailed Mitsubishi 144-bit A/C messages. Inspired and derived from the work done at: https://github.com/r45635/HVAC-IR-Control. More...
 
class  IRMitsubishi136
 Class for handling detailed Mitsubishi 136-bit A/C messages. More...
 
class  IRMitsubishi112
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kMitsubishiAcModeOffset = 3
 
const uint8_t kMitsubishiAcAuto = 0b100
 
const uint8_t kMitsubishiAcCool = 0b011
 
const uint8_t kMitsubishiAcDry = 0b010
 
const uint8_t kMitsubishiAcHeat = 0b001
 
const uint8_t kMitsubishiAcPowerOffset = 5
 
const uint8_t kMitsubishiAcPower = 1 << kMitsubishiAcPowerOffset
 
const uint8_t kMitsubishiAcFanOffset = 0
 
const uint8_t kMitsubishiAcFanSize = 3
 
const uint8_t kMitsubishiAcFanAuto = 0
 
const uint8_t kMitsubishiAcFanAutoOffset = 7
 
const uint8_t kMitsubishiAcFanMax = 5
 
const uint8_t kMitsubishiAcFanRealMax = 4
 
const uint8_t kMitsubishiAcFanSilent = 6
 
const uint8_t kMitsubishiAcFanQuiet = kMitsubishiAcFanSilent
 
const uint8_t kMitsubishiAcMinTemp = 16
 
const uint8_t kMitsubishiAcMaxTemp = 31
 
const uint8_t kMitsubishiAcVaneBitOffset = 6
 
const uint8_t kMitsubishiAcVaneOffset = 3
 
const uint8_t kMitsubishiAcVaneSize = 3
 
const uint8_t kMitsubishiAcVaneAuto = 0
 
const uint8_t kMitsubishiAcVaneAutoMove = 7
 
const uint8_t kMitsubishiAcNoTimer = 0
 
const uint8_t kMitsubishiAcStartTimer = 5
 
const uint8_t kMitsubishiAcStopTimer = 3
 
const uint8_t kMitsubishiAcStartStopTimer = 7
 
const uint8_t kMitsubishiAcWideVaneAuto = 8
 
const uint8_t kMitsubishi136PowerByte = 5
 
const uint8_t kMitsubishi136PowerOffset = 6
 
const uint8_t kMitsubishi136PowerBit = 1 << kMitsubishi136PowerOffset
 
const uint8_t kMitsubishi136TempByte = 6
 
const uint8_t kMitsubishi136MinTemp = 17
 
const uint8_t kMitsubishi136MaxTemp = 30
 
const uint8_t kMitsubishi136ModeByte = kMitsubishi136TempByte
 
const uint8_t kMitsubishi136ModeOffset = 0
 
const uint8_t kMitsubishi136Fan = 0b000
 
const uint8_t kMitsubishi136Cool = 0b001
 
const uint8_t kMitsubishi136Heat = 0b010
 
const uint8_t kMitsubishi136Auto = 0b011
 
const uint8_t kMitsubishi136Dry = 0b101
 
const uint8_t kMitsubishi136SwingVByte = 7
 
const uint8_t kMitsubishi136SwingVLowest = 0b0000
 
const uint8_t kMitsubishi136SwingVLow = 0b0001
 
const uint8_t kMitsubishi136SwingVHigh = 0b0010
 
const uint8_t kMitsubishi136SwingVHighest = 0b0011
 
const uint8_t kMitsubishi136SwingVAuto = 0b1100
 
const uint8_t kMitsubishi136FanByte = kMitsubishi136SwingVByte
 
const uint8_t kMitsubishi136FanOffset = 1
 
const uint8_t kMitsubishi136FanSize = 2
 
const uint8_t kMitsubishi136FanMin = 0b00
 
const uint8_t kMitsubishi136FanLow = 0b01
 
const uint8_t kMitsubishi136FanMed = 0b10
 
const uint8_t kMitsubishi136FanMax = 0b11
 
const uint8_t kMitsubishi136FanQuiet = kMitsubishi136FanMin
 
const uint8_t kMitsubishi112PowerByte = 5
 
const uint8_t kMitsubishi112PowerOffset = 2
 
const uint8_t kMitsubishi112ModeByte = 6
 
const uint8_t kMitsubishi112ModeOffset = 0
 
const uint8_t kMitsubishi112Cool = 0b011
 
const uint8_t kMitsubishi112Heat = 0b001
 
const uint8_t kMitsubishi112Auto = 0b111
 
const uint8_t kMitsubishi112Dry = 0b010
 
const uint8_t kMitsubishi112TempByte = 7
 
const uint8_t kMitsubishi112TempSize = 4
 
const uint8_t kMitsubishi112MinTemp = 16
 
const uint8_t kMitsubishi112MaxTemp = 31
 
const uint8_t kMitsubishi112FanByte = 8
 
const uint8_t kMitsubishi112FanOffset = 0
 
const uint8_t kMitsubishi112FanSize = 3
 
const uint8_t kMitsubishi112FanMin = 0b010
 
const uint8_t kMitsubishi112FanLow = 0b011
 
const uint8_t kMitsubishi112FanMed = 0b101
 
const uint8_t kMitsubishi112FanMax = 0b000
 
const uint8_t kMitsubishi112FanQuiet = kMitsubishi112FanMin
 
const uint8_t kMitsubishi112SwingVByte = kMitsubishi112FanByte
 
const uint8_t kMitsubishi112SwingVOffset = 3
 
const uint8_t kMitsubishi112SwingVSize = 3
 
const uint8_t kMitsubishi112SwingVLowest = 0b101
 
const uint8_t kMitsubishi112SwingVLow = 0b100
 
const uint8_t kMitsubishi112SwingVMiddle = 0b011
 
const uint8_t kMitsubishi112SwingVHigh = 0b010
 
const uint8_t kMitsubishi112SwingVHighest = 0b001
 
const uint8_t kMitsubishi112SwingVAuto = 0b111
 
const uint8_t kMitsubishi112SwingHByte = 12
 
const uint8_t kMitsubishi112SwingHSize = 4
 
const uint8_t kMitsubishi112SwingHOffset = 2
 
const uint8_t kMitsubishi112SwingHLeftMax = 0b0001
 
const uint8_t kMitsubishi112SwingHLeft = 0b0010
 
const uint8_t kMitsubishi112SwingHMiddle = 0b0011
 
const uint8_t kMitsubishi112SwingHRight = 0b0100
 
const uint8_t kMitsubishi112SwingHRightMax = 0b0101
 
const uint8_t kMitsubishi112SwingHWide = 0b1000
 
const uint8_t kMitsubishi112SwingHAuto = 0b1100
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kMitsubishi112Auto

+ +
+
+ + + + +
const uint8_t kMitsubishi112Auto = 0b111
+
+ +
+
+ +

◆ kMitsubishi112Cool

+ +
+
+ + + + +
const uint8_t kMitsubishi112Cool = 0b011
+
+ +
+
+ +

◆ kMitsubishi112Dry

+ +
+
+ + + + +
const uint8_t kMitsubishi112Dry = 0b010
+
+ +
+
+ +

◆ kMitsubishi112FanByte

+ +
+
+ + + + +
const uint8_t kMitsubishi112FanByte = 8
+
+ +
+
+ +

◆ kMitsubishi112FanLow

+ +
+
+ + + + +
const uint8_t kMitsubishi112FanLow = 0b011
+
+ +
+
+ +

◆ kMitsubishi112FanMax

+ +
+
+ + + + +
const uint8_t kMitsubishi112FanMax = 0b000
+
+ +
+
+ +

◆ kMitsubishi112FanMed

+ +
+
+ + + + +
const uint8_t kMitsubishi112FanMed = 0b101
+
+ +
+
+ +

◆ kMitsubishi112FanMin

+ +
+
+ + + + +
const uint8_t kMitsubishi112FanMin = 0b010
+
+ +
+
+ +

◆ kMitsubishi112FanOffset

+ +
+
+ + + + +
const uint8_t kMitsubishi112FanOffset = 0
+
+ +
+
+ +

◆ kMitsubishi112FanQuiet

+ +
+
+ + + + +
const uint8_t kMitsubishi112FanQuiet = kMitsubishi112FanMin
+
+ +
+
+ +

◆ kMitsubishi112FanSize

+ +
+
+ + + + +
const uint8_t kMitsubishi112FanSize = 3
+
+ +
+
+ +

◆ kMitsubishi112Heat

+ +
+
+ + + + +
const uint8_t kMitsubishi112Heat = 0b001
+
+ +
+
+ +

◆ kMitsubishi112MaxTemp

+ +
+
+ + + + +
const uint8_t kMitsubishi112MaxTemp = 31
+
+ +
+
+ +

◆ kMitsubishi112MinTemp

+ +
+
+ + + + +
const uint8_t kMitsubishi112MinTemp = 16
+
+ +
+
+ +

◆ kMitsubishi112ModeByte

+ +
+
+ + + + +
const uint8_t kMitsubishi112ModeByte = 6
+
+ +
+
+ +

◆ kMitsubishi112ModeOffset

+ +
+
+ + + + +
const uint8_t kMitsubishi112ModeOffset = 0
+
+ +
+
+ +

◆ kMitsubishi112PowerByte

+ +
+
+ + + + +
const uint8_t kMitsubishi112PowerByte = 5
+
+ +
+
+ +

◆ kMitsubishi112PowerOffset

+ +
+
+ + + + +
const uint8_t kMitsubishi112PowerOffset = 2
+
+ +
+
+ +

◆ kMitsubishi112SwingHAuto

+ +
+
+ + + + +
const uint8_t kMitsubishi112SwingHAuto = 0b1100
+
+ +
+
+ +

◆ kMitsubishi112SwingHByte

+ +
+
+ + + + +
const uint8_t kMitsubishi112SwingHByte = 12
+
+ +
+
+ +

◆ kMitsubishi112SwingHLeft

+ +
+
+ + + + +
const uint8_t kMitsubishi112SwingHLeft = 0b0010
+
+ +
+
+ +

◆ kMitsubishi112SwingHLeftMax

+ +
+
+ + + + +
const uint8_t kMitsubishi112SwingHLeftMax = 0b0001
+
+ +
+
+ +

◆ kMitsubishi112SwingHMiddle

+ +
+
+ + + + +
const uint8_t kMitsubishi112SwingHMiddle = 0b0011
+
+ +
+
+ +

◆ kMitsubishi112SwingHOffset

+ +
+
+ + + + +
const uint8_t kMitsubishi112SwingHOffset = 2
+
+ +
+
+ +

◆ kMitsubishi112SwingHRight

+ +
+
+ + + + +
const uint8_t kMitsubishi112SwingHRight = 0b0100
+
+ +
+
+ +

◆ kMitsubishi112SwingHRightMax

+ +
+
+ + + + +
const uint8_t kMitsubishi112SwingHRightMax = 0b0101
+
+ +
+
+ +

◆ kMitsubishi112SwingHSize

+ +
+
+ + + + +
const uint8_t kMitsubishi112SwingHSize = 4
+
+ +
+
+ +

◆ kMitsubishi112SwingHWide

+ +
+
+ + + + +
const uint8_t kMitsubishi112SwingHWide = 0b1000
+
+ +
+
+ +

◆ kMitsubishi112SwingVAuto

+ +
+
+ + + + +
const uint8_t kMitsubishi112SwingVAuto = 0b111
+
+ +
+
+ +

◆ kMitsubishi112SwingVByte

+ +
+
+ + + + +
const uint8_t kMitsubishi112SwingVByte = kMitsubishi112FanByte
+
+ +
+
+ +

◆ kMitsubishi112SwingVHigh

+ +
+
+ + + + +
const uint8_t kMitsubishi112SwingVHigh = 0b010
+
+ +
+
+ +

◆ kMitsubishi112SwingVHighest

+ +
+
+ + + + +
const uint8_t kMitsubishi112SwingVHighest = 0b001
+
+ +
+
+ +

◆ kMitsubishi112SwingVLow

+ +
+
+ + + + +
const uint8_t kMitsubishi112SwingVLow = 0b100
+
+ +
+
+ +

◆ kMitsubishi112SwingVLowest

+ +
+
+ + + + +
const uint8_t kMitsubishi112SwingVLowest = 0b101
+
+ +
+
+ +

◆ kMitsubishi112SwingVMiddle

+ +
+
+ + + + +
const uint8_t kMitsubishi112SwingVMiddle = 0b011
+
+ +
+
+ +

◆ kMitsubishi112SwingVOffset

+ +
+
+ + + + +
const uint8_t kMitsubishi112SwingVOffset = 3
+
+ +
+
+ +

◆ kMitsubishi112SwingVSize

+ +
+
+ + + + +
const uint8_t kMitsubishi112SwingVSize = 3
+
+ +
+
+ +

◆ kMitsubishi112TempByte

+ +
+
+ + + + +
const uint8_t kMitsubishi112TempByte = 7
+
+ +
+
+ +

◆ kMitsubishi112TempSize

+ +
+
+ + + + +
const uint8_t kMitsubishi112TempSize = 4
+
+ +
+
+ +

◆ kMitsubishi136Auto

+ +
+
+ + + + +
const uint8_t kMitsubishi136Auto = 0b011
+
+ +
+
+ +

◆ kMitsubishi136Cool

+ +
+
+ + + + +
const uint8_t kMitsubishi136Cool = 0b001
+
+ +
+
+ +

◆ kMitsubishi136Dry

+ +
+
+ + + + +
const uint8_t kMitsubishi136Dry = 0b101
+
+ +
+
+ +

◆ kMitsubishi136Fan

+ +
+
+ + + + +
const uint8_t kMitsubishi136Fan = 0b000
+
+ +
+
+ +

◆ kMitsubishi136FanByte

+ +
+
+ + + + +
const uint8_t kMitsubishi136FanByte = kMitsubishi136SwingVByte
+
+ +
+
+ +

◆ kMitsubishi136FanLow

+ +
+
+ + + + +
const uint8_t kMitsubishi136FanLow = 0b01
+
+ +
+
+ +

◆ kMitsubishi136FanMax

+ +
+
+ + + + +
const uint8_t kMitsubishi136FanMax = 0b11
+
+ +
+
+ +

◆ kMitsubishi136FanMed

+ +
+
+ + + + +
const uint8_t kMitsubishi136FanMed = 0b10
+
+ +
+
+ +

◆ kMitsubishi136FanMin

+ +
+
+ + + + +
const uint8_t kMitsubishi136FanMin = 0b00
+
+ +
+
+ +

◆ kMitsubishi136FanOffset

+ +
+
+ + + + +
const uint8_t kMitsubishi136FanOffset = 1
+
+ +
+
+ +

◆ kMitsubishi136FanQuiet

+ +
+
+ + + + +
const uint8_t kMitsubishi136FanQuiet = kMitsubishi136FanMin
+
+ +
+
+ +

◆ kMitsubishi136FanSize

+ +
+
+ + + + +
const uint8_t kMitsubishi136FanSize = 2
+
+ +
+
+ +

◆ kMitsubishi136Heat

+ +
+
+ + + + +
const uint8_t kMitsubishi136Heat = 0b010
+
+ +
+
+ +

◆ kMitsubishi136MaxTemp

+ +
+
+ + + + +
const uint8_t kMitsubishi136MaxTemp = 30
+
+ +
+
+ +

◆ kMitsubishi136MinTemp

+ +
+
+ + + + +
const uint8_t kMitsubishi136MinTemp = 17
+
+ +
+
+ +

◆ kMitsubishi136ModeByte

+ +
+
+ + + + +
const uint8_t kMitsubishi136ModeByte = kMitsubishi136TempByte
+
+ +
+
+ +

◆ kMitsubishi136ModeOffset

+ +
+
+ + + + +
const uint8_t kMitsubishi136ModeOffset = 0
+
+ +
+
+ +

◆ kMitsubishi136PowerBit

+ +
+
+ + + + +
const uint8_t kMitsubishi136PowerBit = 1 << kMitsubishi136PowerOffset
+
+ +
+
+ +

◆ kMitsubishi136PowerByte

+ +
+
+ + + + +
const uint8_t kMitsubishi136PowerByte = 5
+
+ +
+
+ +

◆ kMitsubishi136PowerOffset

+ +
+
+ + + + +
const uint8_t kMitsubishi136PowerOffset = 6
+
+ +
+
+ +

◆ kMitsubishi136SwingVAuto

+ +
+
+ + + + +
const uint8_t kMitsubishi136SwingVAuto = 0b1100
+
+ +
+
+ +

◆ kMitsubishi136SwingVByte

+ +
+
+ + + + +
const uint8_t kMitsubishi136SwingVByte = 7
+
+ +
+
+ +

◆ kMitsubishi136SwingVHigh

+ +
+
+ + + + +
const uint8_t kMitsubishi136SwingVHigh = 0b0010
+
+ +
+
+ +

◆ kMitsubishi136SwingVHighest

+ +
+
+ + + + +
const uint8_t kMitsubishi136SwingVHighest = 0b0011
+
+ +
+
+ +

◆ kMitsubishi136SwingVLow

+ +
+
+ + + + +
const uint8_t kMitsubishi136SwingVLow = 0b0001
+
+ +
+
+ +

◆ kMitsubishi136SwingVLowest

+ +
+
+ + + + +
const uint8_t kMitsubishi136SwingVLowest = 0b0000
+
+ +
+
+ +

◆ kMitsubishi136TempByte

+ +
+
+ + + + +
const uint8_t kMitsubishi136TempByte = 6
+
+ +
+
+ +

◆ kMitsubishiAcAuto

+ +
+
+ + + + +
const uint8_t kMitsubishiAcAuto = 0b100
+
+ +
+
+ +

◆ kMitsubishiAcCool

+ +
+
+ + + + +
const uint8_t kMitsubishiAcCool = 0b011
+
+ +
+
+ +

◆ kMitsubishiAcDry

+ +
+
+ + + + +
const uint8_t kMitsubishiAcDry = 0b010
+
+ +
+
+ +

◆ kMitsubishiAcFanAuto

+ +
+
+ + + + +
const uint8_t kMitsubishiAcFanAuto = 0
+
+ +
+
+ +

◆ kMitsubishiAcFanAutoOffset

+ +
+
+ + + + +
const uint8_t kMitsubishiAcFanAutoOffset = 7
+
+ +
+
+ +

◆ kMitsubishiAcFanMax

+ +
+
+ + + + +
const uint8_t kMitsubishiAcFanMax = 5
+
+ +
+
+ +

◆ kMitsubishiAcFanOffset

+ +
+
+ + + + +
const uint8_t kMitsubishiAcFanOffset = 0
+
+ +
+
+ +

◆ kMitsubishiAcFanQuiet

+ +
+
+ + + + +
const uint8_t kMitsubishiAcFanQuiet = kMitsubishiAcFanSilent
+
+ +
+
+ +

◆ kMitsubishiAcFanRealMax

+ +
+
+ + + + +
const uint8_t kMitsubishiAcFanRealMax = 4
+
+ +
+
+ +

◆ kMitsubishiAcFanSilent

+ +
+
+ + + + +
const uint8_t kMitsubishiAcFanSilent = 6
+
+ +
+
+ +

◆ kMitsubishiAcFanSize

+ +
+
+ + + + +
const uint8_t kMitsubishiAcFanSize = 3
+
+ +
+
+ +

◆ kMitsubishiAcHeat

+ +
+
+ + + + +
const uint8_t kMitsubishiAcHeat = 0b001
+
+ +
+
+ +

◆ kMitsubishiAcMaxTemp

+ +
+
+ + + + +
const uint8_t kMitsubishiAcMaxTemp = 31
+
+ +
+
+ +

◆ kMitsubishiAcMinTemp

+ +
+
+ + + + +
const uint8_t kMitsubishiAcMinTemp = 16
+
+ +
+
+ +

◆ kMitsubishiAcModeOffset

+ +
+
+ + + + +
const uint8_t kMitsubishiAcModeOffset = 3
+
+ +
+
+ +

◆ kMitsubishiAcNoTimer

+ +
+
+ + + + +
const uint8_t kMitsubishiAcNoTimer = 0
+
+ +
+
+ +

◆ kMitsubishiAcPower

+ +
+
+ + + + +
const uint8_t kMitsubishiAcPower = 1 << kMitsubishiAcPowerOffset
+
+ +
+
+ +

◆ kMitsubishiAcPowerOffset

+ +
+
+ + + + +
const uint8_t kMitsubishiAcPowerOffset = 5
+
+ +
+
+ +

◆ kMitsubishiAcStartStopTimer

+ +
+
+ + + + +
const uint8_t kMitsubishiAcStartStopTimer = 7
+
+ +
+
+ +

◆ kMitsubishiAcStartTimer

+ +
+
+ + + + +
const uint8_t kMitsubishiAcStartTimer = 5
+
+ +
+
+ +

◆ kMitsubishiAcStopTimer

+ +
+
+ + + + +
const uint8_t kMitsubishiAcStopTimer = 3
+
+ +
+
+ +

◆ kMitsubishiAcVaneAuto

+ +
+
+ + + + +
const uint8_t kMitsubishiAcVaneAuto = 0
+
+ +
+
+ +

◆ kMitsubishiAcVaneAutoMove

+ +
+
+ + + + +
const uint8_t kMitsubishiAcVaneAutoMove = 7
+
+ +
+
+ +

◆ kMitsubishiAcVaneBitOffset

+ +
+
+ + + + +
const uint8_t kMitsubishiAcVaneBitOffset = 6
+
+ +
+
+ +

◆ kMitsubishiAcVaneOffset

+ +
+
+ + + + +
const uint8_t kMitsubishiAcVaneOffset = 3
+
+ +
+
+ +

◆ kMitsubishiAcVaneSize

+ +
+
+ + + + +
const uint8_t kMitsubishiAcVaneSize = 3
+
+ +
+
+ +

◆ kMitsubishiAcWideVaneAuto

+ +
+
+ + + + +
const uint8_t kMitsubishiAcWideVaneAuto = 8
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Mitsubishi_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Mitsubishi_8h_source.html new file mode 100644 index 000000000..7c5ef139b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Mitsubishi_8h_source.html @@ -0,0 +1,612 @@ + + + + + + + +IRremoteESP8266: src/ir_Mitsubishi.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Mitsubishi.h
+
+
+Go to the documentation of this file.
1 // Copyright 2009 Ken Shirriff
+
2 // Copyright 2017-2019 David Conran
+
3 // Copyright 2019 Mark Kuchel
+
4 
+
17 
+
18 // Supports:
+
19 // Brand: Mitsubishi, Model: TV (MITSUBISHI)
+
20 // Brand: Mitsubishi, Model: HC3000 Projector (MITSUBISHI2)
+
21 // Brand: Mitsubishi, Model: MS-GK24VA A/C
+
22 // Brand: Mitsubishi, Model: KM14A 0179213 remote
+
23 // Brand: Mitsubishi Electric, Model: PEAD-RP71JAA Ducted A/C (MITSUBISHI136)
+
24 // Brand: Mitsubishi Electric, Model: 001CP T7WE10714 remote (MITSUBISHI136)
+
25 // Brand: Mitsubishi Electric, Model: MSH-A24WV A/C (MITSUBISHI112)
+
26 // Brand: Mitsubishi Electric, Model: MUH-A24WV A/C (MITSUBISHI112)
+
27 // Brand: Mitsubishi Electric, Model: KPOA remote (MITSUBISHI112)
+
28 
+
29 #ifndef IR_MITSUBISHI_H_
+
30 #define IR_MITSUBISHI_H_
+
31 
+
32 #define __STDC_LIMIT_MACROS
+
33 #include <stdint.h>
+
34 #ifndef UNIT_TEST
+
35 #include <Arduino.h>
+
36 #endif
+
37 #include "IRremoteESP8266.h"
+
38 #include "IRsend.h"
+
39 #ifdef UNIT_TEST
+
40 #include "IRsend_test.h"
+
41 #endif
+
42 
+
43 
+
44 // Constants
+
45 const uint8_t kMitsubishiAcModeOffset = 3;
+
46 const uint8_t kMitsubishiAcAuto = 0b100;
+
47 const uint8_t kMitsubishiAcCool = 0b011;
+
48 const uint8_t kMitsubishiAcDry = 0b010;
+
49 const uint8_t kMitsubishiAcHeat = 0b001;
+
50 const uint8_t kMitsubishiAcPowerOffset = 5;
+
51 const uint8_t kMitsubishiAcPower = 1 << kMitsubishiAcPowerOffset; // 0x20
+
52 const uint8_t kMitsubishiAcFanOffset = 0;
+
53 const uint8_t kMitsubishiAcFanSize = 3; // Mask 0b111
+
54 const uint8_t kMitsubishiAcFanAuto = 0;
+
55 const uint8_t kMitsubishiAcFanAutoOffset = 7;
+
56 const uint8_t kMitsubishiAcFanMax = 5;
+
57 const uint8_t kMitsubishiAcFanRealMax = 4;
+
58 const uint8_t kMitsubishiAcFanSilent = 6;
+ +
60 const uint8_t kMitsubishiAcMinTemp = 16; // 16C
+
61 const uint8_t kMitsubishiAcMaxTemp = 31; // 31C
+
62 const uint8_t kMitsubishiAcVaneBitOffset = 6;
+
63 const uint8_t kMitsubishiAcVaneOffset = 3;
+
64 const uint8_t kMitsubishiAcVaneSize = 3;
+
65 const uint8_t kMitsubishiAcVaneAuto = 0;
+
66 const uint8_t kMitsubishiAcVaneAutoMove = 7;
+
67 const uint8_t kMitsubishiAcNoTimer = 0;
+
68 const uint8_t kMitsubishiAcStartTimer = 5;
+
69 const uint8_t kMitsubishiAcStopTimer = 3;
+
70 const uint8_t kMitsubishiAcStartStopTimer = 7;
+
71 const uint8_t kMitsubishiAcWideVaneAuto = 8;
+
72 
+
73 const uint8_t kMitsubishi136PowerByte = 5;
+
74 const uint8_t kMitsubishi136PowerOffset = 6;
+ +
76 const uint8_t kMitsubishi136TempByte = 6;
+
77 const uint8_t kMitsubishi136MinTemp = 17; // 17C
+
78 const uint8_t kMitsubishi136MaxTemp = 30; // 30C
+ +
80 const uint8_t kMitsubishi136ModeOffset = 0;
+
81 const uint8_t kMitsubishi136Fan = 0b000;
+
82 const uint8_t kMitsubishi136Cool = 0b001;
+
83 const uint8_t kMitsubishi136Heat = 0b010;
+
84 const uint8_t kMitsubishi136Auto = 0b011;
+
85 const uint8_t kMitsubishi136Dry = 0b101;
+
86 const uint8_t kMitsubishi136SwingVByte = 7;
+
87 const uint8_t kMitsubishi136SwingVLowest = 0b0000;
+
88 const uint8_t kMitsubishi136SwingVLow = 0b0001;
+
89 const uint8_t kMitsubishi136SwingVHigh = 0b0010;
+
90 const uint8_t kMitsubishi136SwingVHighest = 0b0011;
+
91 const uint8_t kMitsubishi136SwingVAuto = 0b1100;
+ +
93 // FanMask = 0b00000110;
+
94 const uint8_t kMitsubishi136FanOffset = 1;
+
95 const uint8_t kMitsubishi136FanSize = 2; // Bits
+
96 const uint8_t kMitsubishi136FanMin = 0b00;
+
97 const uint8_t kMitsubishi136FanLow = 0b01;
+
98 const uint8_t kMitsubishi136FanMed = 0b10;
+
99 const uint8_t kMitsubishi136FanMax = 0b11;
+ +
101 
+
102 // Mitsubishi112
+
103 
+
104 // remote_state[5]
+
105 const uint8_t kMitsubishi112PowerByte = 5;
+
106 const uint8_t kMitsubishi112PowerOffset = 2; // 0b00000100
+
107 // remote_state[6]
+
108 const uint8_t kMitsubishi112ModeByte = 6;
+
109 const uint8_t kMitsubishi112ModeOffset = 0; // Mask 0b00000111
+
110 const uint8_t kMitsubishi112Cool = 0b011;
+
111 const uint8_t kMitsubishi112Heat = 0b001;
+
112 const uint8_t kMitsubishi112Auto = 0b111;
+
113 const uint8_t kMitsubishi112Dry = 0b010;
+
114 // remote_state[7]
+
115 const uint8_t kMitsubishi112TempByte = 7;
+
116 const uint8_t kMitsubishi112TempSize = 4; // Mask 0b00001111
+
117 const uint8_t kMitsubishi112MinTemp = 16; // 16C
+
118 const uint8_t kMitsubishi112MaxTemp = 31; // 31C
+
119 // remote_state[8]
+
120 const uint8_t kMitsubishi112FanByte = 8;
+
121 const uint8_t kMitsubishi112FanOffset = 0; // Mask 0b00000111;
+
122 const uint8_t kMitsubishi112FanSize = 3;
+
123 const uint8_t kMitsubishi112FanMin = 0b010;
+
124 const uint8_t kMitsubishi112FanLow = 0b011;
+
125 const uint8_t kMitsubishi112FanMed = 0b101;
+
126 const uint8_t kMitsubishi112FanMax = 0b000;
+ + +
129 const uint8_t kMitsubishi112SwingVOffset = 3; // Mask 0b00111000
+
130 const uint8_t kMitsubishi112SwingVSize = 3; // Mask 0b00111000
+
131 const uint8_t kMitsubishi112SwingVLowest = 0b101;
+
132 const uint8_t kMitsubishi112SwingVLow = 0b100;
+
133 const uint8_t kMitsubishi112SwingVMiddle = 0b011;
+
134 const uint8_t kMitsubishi112SwingVHigh = 0b010;
+
135 const uint8_t kMitsubishi112SwingVHighest = 0b001;
+
136 const uint8_t kMitsubishi112SwingVAuto = 0b111;
+
137 // remote_state[12]
+
138 const uint8_t kMitsubishi112SwingHByte = 12;
+
139 const uint8_t kMitsubishi112SwingHSize = 4;
+
140 const uint8_t kMitsubishi112SwingHOffset = 2; // Mask 0b00111100
+
141 const uint8_t kMitsubishi112SwingHLeftMax = 0b0001;
+
142 const uint8_t kMitsubishi112SwingHLeft = 0b0010;
+
143 const uint8_t kMitsubishi112SwingHMiddle = 0b0011;
+
144 const uint8_t kMitsubishi112SwingHRight = 0b0100;
+
145 const uint8_t kMitsubishi112SwingHRightMax = 0b0101;
+
146 const uint8_t kMitsubishi112SwingHWide = 0b1000;
+
147 const uint8_t kMitsubishi112SwingHAuto = 0b1100;
+
148 
+
149 // Legacy defines (Deprecated)
+
150 #define MITSUBISHI_AC_VANE_AUTO_MOVE kMitsubishiAcVaneAutoMove
+
151 #define MITSUBISHI_AC_VANE_AUTO kMitsubishiAcVaneAuto
+
152 #define MITSUBISHI_AC_POWER kMitsubishiAcPower
+
153 #define MITSUBISHI_AC_MIN_TEMP kMitsubishiAcMinTemp
+
154 #define MITSUBISHI_AC_MAX_TEMP kMitsubishiAcMaxTemp
+
155 #define MITSUBISHI_AC_HEAT kMitsubishiAcHeat
+
156 #define MITSUBISHI_AC_FAN_SILENT kMitsubishiAcFanSilent
+
157 #define MITSUBISHI_AC_FAN_REAL_MAX kMitsubishiAcFanRealMax
+
158 #define MITSUBISHI_AC_FAN_MAX kMitsubishiAcFanMax
+
159 #define MITSUBISHI_AC_FAN_AUTO kMitsubishiAcFanAuto
+
160 #define MITSUBISHI_AC_DRY kMitsubishiAcDry
+
161 #define MITSUBISHI_AC_COOL kMitsubishiAcCool
+
162 #define MITSUBISHI_AC_AUTO kMitsubishiAcAuto
+
163 
+
164 
+ +
169  public:
+
170  explicit IRMitsubishiAC(const uint16_t pin, const bool inverted = false,
+
171  const bool use_modulation = true);
+
172  void stateReset(void);
+
173  static bool validChecksum(const uint8_t* data);
+
174 #if SEND_MITSUBISHI_AC
+
175  void send(const uint16_t repeat = kMitsubishiACMinRepeat);
+
180  int8_t calibrate(void) { return _irsend.calibrate(); }
+
181 #endif // SEND_MITSUBISHI_AC
+
182  void begin(void);
+
183  void on(void);
+
184  void off(void);
+
185  void setPower(const bool on);
+
186  bool getPower(void);
+
187  void setTemp(const uint8_t degrees);
+
188  uint8_t getTemp(void);
+
189  void setFan(const uint8_t speed);
+
190  uint8_t getFan(void);
+
191  void setMode(const uint8_t mode);
+
192  uint8_t getMode(void);
+
193  void setVane(const uint8_t position);
+
194  void setWideVane(const uint8_t position);
+
195  uint8_t getVane(void);
+
196  uint8_t getWideVane(void);
+
197  uint8_t* getRaw(void);
+
198  void setRaw(const uint8_t* data);
+
199  uint8_t getClock(void);
+
200  void setClock(const uint8_t clock);
+
201  uint8_t getStartClock(void);
+
202  void setStartClock(const uint8_t clock);
+
203  uint8_t getStopClock(void);
+
204  void setStopClock(const uint8_t clock);
+
205  uint8_t getTimer(void);
+
206  void setTimer(const uint8_t timer);
+
207  static uint8_t convertMode(const stdAc::opmode_t mode);
+
208  static uint8_t convertFan(const stdAc::fanspeed_t speed);
+
209  static uint8_t convertSwingV(const stdAc::swingv_t position);
+
210  static uint8_t convertSwingH(const stdAc::swingh_t position);
+
211  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
212  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
213  static stdAc::swingv_t toCommonSwingV(const uint8_t pos);
+
214  static stdAc::swingh_t toCommonSwingH(const uint8_t pos);
+
215  stdAc::state_t toCommon(void);
+
216  String toString(void);
+
217 #ifndef UNIT_TEST
+
218 
+
219  private:
+ +
221 #else // UNIT_TEST
+
222  IRsendTest _irsend;
+
224 #endif // UNIT_TEST
+ +
227  void checksum(void);
+
228  static uint8_t calculateChecksum(const uint8_t* data);
+
229 };
+
230 
+ +
233  public:
+
234  explicit IRMitsubishi136(const uint16_t pin, const bool inverted = false,
+
235  const bool use_modulation = true);
+
236  void stateReset(void);
+
237 #if SEND_MITSUBISHI136
+
238  void send(const uint16_t repeat = kMitsubishi136MinRepeat);
+
243  int8_t calibrate(void) { return _irsend.calibrate(); }
+
244 #endif // SEND_MITSUBISHI136
+
245  void begin(void);
+
246  static bool validChecksum(const uint8_t* data,
+
247  const uint16_t len = kMitsubishi136StateLength);
+
248  void on(void);
+
249  void off(void);
+
250  void setPower(const bool on);
+
251  bool getPower(void);
+
252  void setTemp(const uint8_t degrees);
+
253  uint8_t getTemp(void);
+
254  void setFan(const uint8_t speed);
+
255  uint8_t getFan(void);
+
256  void setMode(const uint8_t mode);
+
257  uint8_t getMode(void);
+
258  void setSwingV(const uint8_t position);
+
259  uint8_t getSwingV(void);
+
260  void setQuiet(const bool on);
+
261  bool getQuiet(void);
+
262  uint8_t* getRaw(void);
+
263  void setRaw(const uint8_t* data);
+
264  static uint8_t convertMode(const stdAc::opmode_t mode);
+
265  static uint8_t convertFan(const stdAc::fanspeed_t speed);
+
266  static uint8_t convertSwingV(const stdAc::swingv_t position);
+
267  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
268  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
269  static stdAc::swingv_t toCommonSwingV(const uint8_t pos);
+
270  stdAc::state_t toCommon(void);
+
271  String toString(void);
+
272 #ifndef UNIT_TEST
+
273 
+
274  private:
+ +
276 #else // UNIT_TEST
+
277  IRsendTest _irsend;
+
279 #endif // UNIT_TEST
+ +
282  void checksum(void);
+
283 };
+
284 
+
285 
+ +
287  public:
+
288  explicit IRMitsubishi112(const uint16_t pin, const bool inverted = false,
+
289  const bool use_modulation = true);
+
290  void stateReset(void);
+
291 #if SEND_MITSUBISHI112
+
292  void send(const uint16_t repeat = kMitsubishi112MinRepeat);
+
297  int8_t calibrate(void) { return _irsend.calibrate(); }
+
298 #endif // SEND_MITSUBISHI112
+
299  void begin(void);
+
300  void on(void);
+
301  void off(void);
+
302  void setPower(const bool on);
+
303  bool getPower(void);
+
304  void setTemp(const uint8_t degrees);
+
305  uint8_t getTemp(void);
+
306  void setFan(const uint8_t speed);
+
307  uint8_t getFan(void);
+
308  void setMode(const uint8_t mode);
+
309  uint8_t getMode(void);
+
310  void setSwingV(const uint8_t position);
+
311  uint8_t getSwingV(void);
+
312  void setSwingH(const uint8_t position);
+
313  uint8_t getSwingH(void);
+
314  void setQuiet(const bool on);
+
315  bool getQuiet(void);
+
316  uint8_t* getRaw(void);
+
317  void setRaw(const uint8_t* data);
+
318  static uint8_t convertMode(const stdAc::opmode_t mode);
+
319  static uint8_t convertFan(const stdAc::fanspeed_t speed);
+
320  static uint8_t convertSwingV(const stdAc::swingv_t position);
+
321  static uint8_t convertSwingH(const stdAc::swingh_t position);
+
322  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
323  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
324  static stdAc::swingv_t toCommonSwingV(const uint8_t pos);
+
325  static stdAc::swingh_t toCommonSwingH(const uint8_t pos);
+
326  stdAc::state_t toCommon(void);
+
327  String toString(void);
+
328 #ifndef UNIT_TEST
+
329 
+
330  private:
+ +
332 #else // UNIT_TEST
+
333  IRsendTest _irsend;
+
335 #endif // UNIT_TEST
+ +
338  void checksum(void);
+
339 };
+
340 
+
341 #endif // IR_MITSUBISHI_H_
+
+
const uint8_t kMitsubishi112SwingVMiddle
Definition: ir_Mitsubishi.h:133
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Mitsubishi.cpp:1399
+
const uint8_t kMitsubishi112SwingVLowest
Definition: ir_Mitsubishi.h:131
+
const uint8_t kMitsubishi112ModeOffset
Definition: ir_Mitsubishi.h:109
+
const uint8_t kMitsubishi112SwingVAuto
Definition: ir_Mitsubishi.h:136
+
const uint8_t kMitsubishi112FanQuiet
Definition: ir_Mitsubishi.h:127
+
void stateReset(void)
Reset the state of the remote to a known good state/sequence.
Definition: ir_Mitsubishi.cpp:1295
+
const uint8_t kMitsubishi112SwingHLeft
Definition: ir_Mitsubishi.h:142
+
const uint8_t kMitsubishi136ModeByte
Definition: ir_Mitsubishi.h:79
+
const uint8_t kMitsubishi112FanMed
Definition: ir_Mitsubishi.h:125
+
const uint16_t kMitsubishiACStateLength
Definition: IRremoteESP8266.h:930
+
const uint8_t kMitsubishiAcHeat
Definition: ir_Mitsubishi.h:49
+
const uint8_t kMitsubishiAcAuto
Definition: ir_Mitsubishi.h:46
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Mitsubishi.cpp:1309
+
const uint8_t kMitsubishi112ModeByte
Definition: ir_Mitsubishi.h:108
+
const uint8_t kMitsubishi112SwingHRight
Definition: ir_Mitsubishi.h:144
+
const uint8_t kMitsubishiAcFanSilent
Definition: ir_Mitsubishi.h:58
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Mitsubishi.h:297
+
const uint8_t kMitsubishiAcVaneAuto
Definition: ir_Mitsubishi.h:65
+
const uint8_t kMitsubishi112SwingHRightMax
Definition: ir_Mitsubishi.h:145
+
void stateReset(void)
Reset the state of the remote to a known good state/sequence.
Definition: ir_Mitsubishi.cpp:874
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Mitsubishi.cpp:454
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Mitsubishi.cpp:907
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Mitsubishi.cpp:498
+
uint8_t getStopClock(void)
Get the desired stop time of the A/C unit.
Definition: ir_Mitsubishi.cpp:574
+
bool getQuiet(void)
Get the Quiet mode of the A/C.
Definition: ir_Mitsubishi.cpp:1482
+
const uint16_t kMitsubishi136MinRepeat
Definition: IRremoteESP8266.h:935
+
swingv_t
Common A/C settings for Vertical Swing.
Definition: IRsend.h:70
+
const uint8_t kMitsubishiAcFanOffset
Definition: ir_Mitsubishi.h:52
+
void stateReset(void)
Reset the state of the remote to a known good state/sequence.
Definition: ir_Mitsubishi.cpp:388
+
void setVane(const uint8_t position)
Set the requested vane (Vertical Swing) operation mode of the a/c unit.
Definition: ir_Mitsubishi.cpp:520
+
const uint8_t kMitsubishi136FanMed
Definition: ir_Mitsubishi.h:98
+
const uint8_t kMitsubishi136PowerByte
Definition: ir_Mitsubishi.h:73
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
const uint8_t kMitsubishi136PowerBit
Definition: ir_Mitsubishi.h:75
+
void setStopClock(const uint8_t clock)
Set the desired stop time of the A/C unit.
Definition: ir_Mitsubishi.cpp:579
+
const uint8_t kMitsubishi136MaxTemp
Definition: ir_Mitsubishi.h:78
+
static uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Mitsubishi.cpp:1046
+
void setRaw(const uint8_t *data)
Set the internal state from a valid code for this protocol.
Definition: ir_Mitsubishi.cpp:417
+
void setFan(const uint8_t speed)
Set the speed of the fan.
Definition: ir_Mitsubishi.cpp:967
+
const uint16_t kMitsubishi112MinRepeat
Definition: IRremoteESP8266.h:938
+
void setRaw(const uint8_t *data)
Set the internal state from a valid code for this protocol.
Definition: ir_Mitsubishi.cpp:1328
+
void setStartClock(const uint8_t clock)
Set the desired start time of the A/C unit.
Definition: ir_Mitsubishi.cpp:567
+
const uint8_t kMitsubishi112FanLow
Definition: ir_Mitsubishi.h:124
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Mitsubishi.cpp:1558
+
const uint8_t kMitsubishi136FanSize
Definition: ir_Mitsubishi.h:95
+
void checksum(void)
Calculate and set the checksum values for the internal state.
Definition: ir_Mitsubishi.cpp:422
+
const uint8_t kMitsubishi136SwingVByte
Definition: ir_Mitsubishi.h:86
+
const uint8_t kMitsubishi112Heat
Definition: ir_Mitsubishi.h:111
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Mitsubishi.cpp:981
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Mitsubishi.cpp:960
+
const uint8_t kMitsubishi112SwingHLeftMax
Definition: ir_Mitsubishi.h:141
+
bool getQuiet(void)
Get the Quiet mode of the A/C.
Definition: ir_Mitsubishi.cpp:1039
+
static bool validChecksum(const uint8_t *data)
Verify the checksum is valid for a given state.
Definition: ir_Mitsubishi.cpp:429
+
uint8_t getClock(void)
Get the clock time of the A/C unit.
Definition: ir_Mitsubishi.cpp:550
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Mitsubishi.h:243
+
const uint8_t kMitsubishi112Cool
Definition: ir_Mitsubishi.h:110
+
const uint8_t kMitsubishi112PowerByte
Definition: ir_Mitsubishi.h:105
+
void setQuiet(const bool on)
Set the Quiet mode of the A/C.
Definition: ir_Mitsubishi.cpp:1031
+ +
const uint8_t kMitsubishiAcNoTimer
Definition: ir_Mitsubishi.h:67
+
void send(const uint16_t repeat=kMitsubishi112MinRepeat)
Send the current internal state as an IR message.
Definition: ir_Mitsubishi.cpp:1314
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Mitsubishi.cpp:489
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Mitsubishi.cpp:448
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Mitsubishi.cpp:1546
+
static uint8_t calculateChecksum(const uint8_t *data)
Calculate the checksum for a given state.
Definition: ir_Mitsubishi.cpp:436
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
uint8_t getWideVane(void)
Get the Wide Vane (Horizontal Swing) mode of the A/C.
Definition: ir_Mitsubishi.cpp:543
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
const uint8_t kMitsubishi136Cool
Definition: ir_Mitsubishi.h:82
+
const uint8_t kMitsubishi136Dry
Definition: ir_Mitsubishi.h:85
+
IRMitsubishi112(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Mitsubishi.cpp:1290
+
void setClock(const uint8_t clock)
Set the clock time on the A/C unit.
Definition: ir_Mitsubishi.cpp:555
+
const uint8_t kMitsubishiAcPowerOffset
Definition: ir_Mitsubishi.h:50
+
uint8_t getStartClock(void)
Get the desired start time of the A/C unit.
Definition: ir_Mitsubishi.cpp:562
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Mitsubishi.cpp:1362
+
std::string String
Definition: IRremoteESP8266.h:1093
+
Class for handling detailed Mitsubishi 144-bit A/C messages. Inspired and derived from the work done ...
Definition: ir_Mitsubishi.h:168
+
static uint8_t convertSwingV(const stdAc::swingv_t position)
Convert a stdAc::swingv_t enum into it's native setting.
Definition: ir_Mitsubishi.cpp:631
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Mitsubishi.cpp:674
+
Definition: ir_Mitsubishi.h:286
+
void setFan(const uint8_t speed)
Set the speed of the fan.
Definition: ir_Mitsubishi.cpp:474
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Mitsubishi.cpp:1385
+
const uint8_t kMitsubishi112SwingVLow
Definition: ir_Mitsubishi.h:132
+
const uint8_t kMitsubishiAcFanSize
Definition: ir_Mitsubishi.h:53
+
static uint8_t convertSwingH(const stdAc::swingh_t position)
Convert a stdAc::swingh_t enum into it's native setting.
Definition: ir_Mitsubishi.cpp:646
+
void setTemp(const uint8_t degrees)
Set the temperature.
Definition: ir_Mitsubishi.cpp:1353
+
uint8_t getVane(void)
Get the Vane (Vertical Swing) mode of the A/C.
Definition: ir_Mitsubishi.cpp:536
+
const uint8_t kMitsubishi112SwingHAuto
Definition: ir_Mitsubishi.h:147
+
const uint8_t kMitsubishi112MinTemp
Definition: ir_Mitsubishi.h:117
+
Class for handling detailed Mitsubishi 136-bit A/C messages.
Definition: ir_Mitsubishi.h:232
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Mitsubishi.cpp:1340
+
void checksum(void)
Calculate the checksum for the current internal state of the remote.
Definition: ir_Mitsubishi.cpp:1303
+ +
swingh_t
Common A/C settings for Horizontal Swing.
Definition: IRsend.h:83
+
static uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Mitsubishi.cpp:604
+
String toString(void)
Convert the internal state into a human readable string.
Definition: ir_Mitsubishi.cpp:1150
+
const uint8_t kMitsubishi112TempByte
Definition: ir_Mitsubishi.h:115
+
const uint8_t kMitsubishiAcStopTimer
Definition: ir_Mitsubishi.h:69
+
String toString(void)
Convert the internal state into a human readable string.
Definition: ir_Mitsubishi.cpp:1627
+
const uint8_t kMitsubishiAcVaneSize
Definition: ir_Mitsubishi.h:64
+
const uint8_t kMitsubishiAcFanMax
Definition: ir_Mitsubishi.h:56
+
const uint8_t kMitsubishi112SwingVHighest
Definition: ir_Mitsubishi.h:135
+
static stdAc::swingh_t toCommonSwingH(const uint8_t pos)
Convert a native horizontal swing postion to it's common equivalent.
Definition: ir_Mitsubishi.cpp:702
+
const uint8_t kMitsubishi136FanLow
Definition: ir_Mitsubishi.h:97
+
const uint16_t kMitsubishiACMinRepeat
Definition: IRremoteESP8266.h:932
+
const uint8_t kMitsubishi136MinTemp
Definition: ir_Mitsubishi.h:77
+
const uint8_t kMitsubishi112SwingVOffset
Definition: ir_Mitsubishi.h:129
+
const uint8_t kMitsubishi112SwingVSize
Definition: ir_Mitsubishi.h:130
+
static stdAc::swingv_t toCommonSwingV(const uint8_t pos)
Convert a native vertical swing postion to it's common equivalent.
Definition: ir_Mitsubishi.cpp:1112
+
IRMitsubishi136(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Mitsubishi.cpp:869
+
uint8_t remote_state[kMitsubishi112StateLength]
The state in code form.
Definition: ir_Mitsubishi.h:337
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Mitsubishi.h:220
+
const uint8_t kMitsubishi136Auto
Definition: ir_Mitsubishi.h:84
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Mitsubishi.cpp:1599
+
const uint8_t kMitsubishi112TempSize
Definition: ir_Mitsubishi.h:116
+
const uint8_t kMitsubishi136FanMax
Definition: ir_Mitsubishi.h:99
+
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_Mitsubishi.cpp:410
+
const uint8_t kMitsubishiAcFanAuto
Definition: ir_Mitsubishi.h:54
+
void on(void)
Set the requested power state of the A/C to on.
Definition: ir_Mitsubishi.cpp:441
+
String toString(void)
Convert the internal state into a human readable string.
Definition: ir_Mitsubishi.cpp:742
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Mitsubishi.cpp:1124
+
const uint8_t kMitsubishiAcVaneOffset
Definition: ir_Mitsubishi.h:63
+
const uint8_t kMitsubishiAcFanQuiet
Definition: ir_Mitsubishi.h:59
+
static uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Mitsubishi.cpp:1502
+
static uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Mitsubishi.cpp:1489
+
const uint8_t kMitsubishiAcWideVaneAuto
Definition: ir_Mitsubishi.h:71
+
const uint8_t kMitsubishi112PowerOffset
Definition: ir_Mitsubishi.h:106
+
void send(const uint16_t repeat=kMitsubishi136MinRepeat)
Send the current internal state as an IR message.
Definition: ir_Mitsubishi.cpp:912
+
const uint8_t kMitsubishi136Fan
Definition: ir_Mitsubishi.h:81
+
void setFan(const uint8_t speed)
Set the speed of the fan.
Definition: ir_Mitsubishi.cpp:1369
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Mitsubishi.h:180
+
void off(void)
Set the requested power state of the A/C to off.
Definition: ir_Mitsubishi.cpp:1336
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Mitsubishi.cpp:504
+
const uint8_t kMitsubishi136FanOffset
Definition: ir_Mitsubishi.h:94
+
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_Mitsubishi.cpp:1321
+
static uint8_t convertSwingH(const stdAc::swingh_t position)
Convert a stdAc::swingh_t enum into it's native setting.
Definition: ir_Mitsubishi.cpp:1530
+
void setSwingH(const uint8_t position)
Set the Horizontal Swing mode of the A/C.
Definition: ir_Mitsubishi.cpp:1443
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Mitsubishi.cpp:1086
+
const uint8_t kMitsubishi112SwingVByte
Definition: ir_Mitsubishi.h:128
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Mitsubishi.cpp:398
+
uint8_t remote_state[kMitsubishi136StateLength]
The state in code form.
Definition: ir_Mitsubishi.h:281
+
IRMitsubishiAC(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Mitsubishi.cpp:383
+
const uint8_t kMitsubishi112SwingHSize
Definition: ir_Mitsubishi.h:139
+
const uint8_t kMitsubishi136FanMin
Definition: ir_Mitsubishi.h:96
+
const uint8_t kMitsubishi136SwingVAuto
Definition: ir_Mitsubishi.h:91
+
const uint8_t kMitsubishiAcVaneBitOffset
Definition: ir_Mitsubishi.h:62
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Mitsubishi.h:331
+
const uint8_t kMitsubishi136Heat
Definition: ir_Mitsubishi.h:83
+
void setTemp(const uint8_t degrees)
Set the temperature.
Definition: ir_Mitsubishi.cpp:951
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Mitsubishi.cpp:662
+
void checksum(void)
Calculate the checksum for the current internal state of the remote.
Definition: ir_Mitsubishi.cpp:884
+
const uint8_t kMitsubishi112FanMin
Definition: ir_Mitsubishi.h:123
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Mitsubishi.cpp:974
+
const uint8_t kMitsubishiAcModeOffset
Definition: ir_Mitsubishi.h:45
+
const uint8_t kMitsubishiAcFanRealMax
Definition: ir_Mitsubishi.h:57
+
const uint8_t kMitsubishiAcStartStopTimer
Definition: ir_Mitsubishi.h:70
+
static uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Mitsubishi.cpp:616
+
uint8_t getTimer(void)
Get the timers active setting of the A/C.
Definition: ir_Mitsubishi.cpp:588
+
const uint8_t kMitsubishi112FanByte
Definition: ir_Mitsubishi.h:120
+
const uint8_t kMitsubishi112SwingVHigh
Definition: ir_Mitsubishi.h:134
+
const uint8_t kMitsubishi112SwingHMiddle
Definition: ir_Mitsubishi.h:143
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Mitsubishi.cpp:1346
+
const uint8_t kMitsubishi136SwingVLow
Definition: ir_Mitsubishi.h:88
+
const uint8_t kMitsubishi112FanSize
Definition: ir_Mitsubishi.h:122
+
static uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Mitsubishi.cpp:1059
+
const uint8_t kMitsubishiAcVaneAutoMove
Definition: ir_Mitsubishi.h:66
+
void send(const uint16_t repeat=kMitsubishiACMinRepeat)
Send the current internal state as an IR message.
Definition: ir_Mitsubishi.cpp:403
+
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_Mitsubishi.cpp:919
+
void setWideVane(const uint8_t position)
Set the requested wide-vane (Horizontal Swing) operation mode of the a/c.
Definition: ir_Mitsubishi.cpp:529
+
uint8_t getSwingV(void)
Get the Vertical Swing mode of the A/C.
Definition: ir_Mitsubishi.cpp:1024
+
const uint8_t kMitsubishi112SwingHByte
Definition: ir_Mitsubishi.h:138
+
uint8_t getSwingV(void)
Get the Vertical Swing mode of the A/C.
Definition: ir_Mitsubishi.cpp:1436
+
const uint8_t kMitsubishi112Auto
Definition: ir_Mitsubishi.h:112
+
const uint8_t kMitsubishiAcMinTemp
Definition: ir_Mitsubishi.h:60
+
const uint8_t kMitsubishi136SwingVLowest
Definition: ir_Mitsubishi.h:87
+
const uint8_t kMitsubishiAcStartTimer
Definition: ir_Mitsubishi.h:68
+
void setRaw(const uint8_t *data)
Set the internal state from a valid code for this protocol.
Definition: ir_Mitsubishi.cpp:926
+
const uint8_t kMitsubishi136FanByte
Definition: ir_Mitsubishi.h:92
+
static uint8_t convertSwingV(const stdAc::swingv_t position)
Convert a stdAc::swingv_t enum into it's native setting.
Definition: ir_Mitsubishi.cpp:1072
+
static stdAc::swingv_t toCommonSwingV(const uint8_t pos)
Convert a native vertical swing postion to it's common equivalent.
Definition: ir_Mitsubishi.cpp:1571
+
const uint8_t kMitsubishi136PowerOffset
Definition: ir_Mitsubishi.h:74
+
const uint8_t kMitsubishi112FanMax
Definition: ir_Mitsubishi.h:126
+
void on(void)
Set the requested power state of the A/C to off.
Definition: ir_Mitsubishi.cpp:1333
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Mitsubishi.h:275
+
void setSwingV(const uint8_t position)
Set the Vertical Swing mode of the A/C.
Definition: ir_Mitsubishi.cpp:1006
+
const uint8_t kMitsubishi136TempByte
Definition: ir_Mitsubishi.h:76
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Mitsubishi.cpp:468
+
const uint8_t kMitsubishi112FanOffset
Definition: ir_Mitsubishi.h:121
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Mitsubishi.cpp:716
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Mitsubishi.cpp:944
+
const uint8_t kMitsubishi136FanQuiet
Definition: ir_Mitsubishi.h:100
+
void setQuiet(const bool on)
Set the Quiet mode of the A/C.
Definition: ir_Mitsubishi.cpp:1472
+
const uint8_t kMitsubishiAcFanAutoOffset
Definition: ir_Mitsubishi.h:55
+
void setSwingV(const uint8_t position)
Set the Vertical Swing mode of the A/C.
Definition: ir_Mitsubishi.cpp:1417
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Mitsubishi.cpp:1099
+
const uint8_t kMitsubishi112SwingHOffset
Definition: ir_Mitsubishi.h:140
+
static stdAc::swingh_t toCommonSwingH(const uint8_t pos)
Convert a native horizontal swing postion to it's common equivalent.
Definition: ir_Mitsubishi.cpp:1585
+
uint8_t getSwingH(void)
Get the Horizontal Swing mode of the A/C.
Definition: ir_Mitsubishi.cpp:1464
+
void off(void)
Set the requested power state of the A/C to off.
Definition: ir_Mitsubishi.cpp:934
+
void setTemp(const uint8_t degrees)
Set the temperature.
Definition: ir_Mitsubishi.cpp:460
+
const uint8_t kMitsubishiAcMaxTemp
Definition: ir_Mitsubishi.h:61
+
const uint16_t kMitsubishi136StateLength
Definition: IRremoteESP8266.h:933
+
const uint8_t kMitsubishi136SwingVHigh
Definition: ir_Mitsubishi.h:89
+
const uint8_t kMitsubishiAcCool
Definition: ir_Mitsubishi.h:47
+
static stdAc::swingv_t toCommonSwingV(const uint8_t pos)
Convert a native vertical swing postion to it's common equivalent.
Definition: ir_Mitsubishi.cpp:688
+
const uint8_t kMitsubishi112SwingHWide
Definition: ir_Mitsubishi.h:146
+
void on(void)
Set the requested power state of the A/C to on.
Definition: ir_Mitsubishi.cpp:931
+
static uint8_t convertSwingV(const stdAc::swingv_t position)
Convert a stdAc::swingv_t enum into it's native setting.
Definition: ir_Mitsubishi.cpp:1516
+
const uint8_t kMitsubishi112Dry
Definition: ir_Mitsubishi.h:113
+
const uint8_t kMitsubishi136SwingVHighest
Definition: ir_Mitsubishi.h:90
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Mitsubishi.cpp:1392
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Mitsubishi.cpp:938
+
const uint8_t kMitsubishiAcPower
Definition: ir_Mitsubishi.h:51
+
void setTimer(const uint8_t timer)
Set the timers active setting of the A/C.
Definition: ir_Mitsubishi.cpp:597
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
void off(void)
Set the requested power state of the A/C to off.
Definition: ir_Mitsubishi.cpp:444
+
uint8_t remote_state[kMitsubishiACStateLength]
The state in code form.
Definition: ir_Mitsubishi.h:226
+
const uint16_t kMitsubishi112StateLength
Definition: IRremoteESP8266.h:936
+
const uint8_t kMitsubishi136ModeOffset
Definition: ir_Mitsubishi.h:80
+
const uint8_t kMitsubishi112MaxTemp
Definition: ir_Mitsubishi.h:118
+
static bool validChecksum(const uint8_t *data, const uint16_t len=kMitsubishi136StateLength)
Verify the checksum is valid for a given state.
Definition: ir_Mitsubishi.cpp:894
+
const uint8_t kMitsubishiAcDry
Definition: ir_Mitsubishi.h:48
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Mitsubishi.cpp:988
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Multibrackets_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Multibrackets_8cpp.html new file mode 100644 index 000000000..ce9f031d1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Multibrackets_8cpp.html @@ -0,0 +1,175 @@ + + + + + + + +IRremoteESP8266: src/ir_Multibrackets.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Multibrackets.cpp File Reference
+
+
+ +

Support for Multibrackets protocols. +More...

+ + + + + + + + + + + + +

+Variables

const uint16_t kMultibracketsTick = 5000
 
const uint16_t kMultibracketsHdrMark = 3 * kMultibracketsTick
 
const uint16_t kMultibracketsFooterSpace = 6 * kMultibracketsTick
 
const uint8_t kMultibracketsTolerance = 5
 
const uint16_t kMultibracketsFreq = 38000
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kMultibracketsFooterSpace

+ +
+
+ + + + +
const uint16_t kMultibracketsFooterSpace = 6 * kMultibracketsTick
+
+ +
+
+ +

◆ kMultibracketsFreq

+ +
+
+ + + + +
const uint16_t kMultibracketsFreq = 38000
+
+ +
+
+ +

◆ kMultibracketsHdrMark

+ +
+
+ + + + +
const uint16_t kMultibracketsHdrMark = 3 * kMultibracketsTick
+
+ +
+
+ +

◆ kMultibracketsTick

+ +
+
+ + + + +
const uint16_t kMultibracketsTick = 5000
+
+ +
+
+ +

◆ kMultibracketsTolerance

+ +
+
+ + + + +
const uint8_t kMultibracketsTolerance = 5
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__NEC_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__NEC_8cpp.html new file mode 100644 index 000000000..bcfee8232 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__NEC_8cpp.html @@ -0,0 +1,86 @@ + + + + + + + +IRremoteESP8266: src/ir_NEC.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_NEC.cpp File Reference
+
+
+ +

Support for NEC (Renesas) protocols. NEC originally added from https://github.com/shirriff/Arduino-IRremote/. +More...

+

Detailed Description

+

Support for NEC (Renesas) protocols. NEC originally added from https://github.com/shirriff/Arduino-IRremote/.

+
See also
http://www.sbprojects.com/knowledge/ir/nec.php
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__NEC_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__NEC_8h.html new file mode 100644 index 000000000..945f7a962 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__NEC_8h.html @@ -0,0 +1,642 @@ + + + + + + + +IRremoteESP8266: src/ir_NEC.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_NEC.h File Reference
+
+
+ +

Support for NEC (Renesas) protocols. NEC originally added from https://github.com/shirriff/Arduino-IRremote/. +More...

+ +

Go to the source code of this file.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kNecTick = 560
 
const uint16_t kNecHdrMarkTicks = 16
 
const uint16_t kNecHdrMark = kNecHdrMarkTicks * kNecTick
 
const uint16_t kNecHdrSpaceTicks = 8
 
const uint16_t kNecHdrSpace = kNecHdrSpaceTicks * kNecTick
 
const uint16_t kNecBitMarkTicks = 1
 
const uint16_t kNecBitMark = kNecBitMarkTicks * kNecTick
 
const uint16_t kNecOneSpaceTicks = 3
 
const uint16_t kNecOneSpace = kNecOneSpaceTicks * kNecTick
 
const uint16_t kNecZeroSpaceTicks = 1
 
const uint16_t kNecZeroSpace = kNecZeroSpaceTicks * kNecTick
 
const uint16_t kNecRptSpaceTicks = 4
 
const uint16_t kNecRptSpace = kNecRptSpaceTicks * kNecTick
 
const uint16_t kNecRptLength = 4
 
const uint16_t kNecMinCommandLengthTicks = 193
 
const uint32_t kNecMinCommandLength = kNecMinCommandLengthTicks * kNecTick
 
const uint32_t kNecMinGap
 
const uint16_t kNecMinGapTicks
 
const uint32_t kAlokaPower = 0xFF609F
 
const uint32_t kAlokaLedWhite = 0xFF906F
 
const uint32_t kAlokaLedGreen = 0xFF9867
 
const uint32_t kAlokaLedBlue = 0xFFD827
 
const uint32_t kAlokaLedPinkRed = 0xFF8877
 
const uint32_t kAlokaLedRed = 0xFFA857
 
const uint32_t kAlokaLedLightGreen = 0xFFE817
 
const uint32_t kAlokaLedMidBlue = 0xFF48B7
 
const uint32_t kAlokaLedPink = 0xFF6897
 
const uint32_t kAlokaLedOrange = 0xFFB24D
 
const uint32_t kAlokaLedYellow = 0xFF00FF
 
const uint32_t kAlokaNightFade = 0xFF50AF
 
const uint32_t kAlokaNightTimer = 0xFF7887
 
const uint32_t kAlokaLedRainbow = 0xFF708F
 
const uint32_t kAlokaLedTreeGrow = 0xFF58A7
 
+

Detailed Description

+

Support for NEC (Renesas) protocols. NEC originally added from https://github.com/shirriff/Arduino-IRremote/.

+
See also
http://www.sbprojects.com/knowledge/ir/nec.php
+

Variable Documentation

+ +

◆ kAlokaLedBlue

+ +
+
+ + + + +
const uint32_t kAlokaLedBlue = 0xFFD827
+
+ +
+
+ +

◆ kAlokaLedGreen

+ +
+
+ + + + +
const uint32_t kAlokaLedGreen = 0xFF9867
+
+ +
+
+ +

◆ kAlokaLedLightGreen

+ +
+
+ + + + +
const uint32_t kAlokaLedLightGreen = 0xFFE817
+
+ +
+
+ +

◆ kAlokaLedMidBlue

+ +
+
+ + + + +
const uint32_t kAlokaLedMidBlue = 0xFF48B7
+
+ +
+
+ +

◆ kAlokaLedOrange

+ +
+
+ + + + +
const uint32_t kAlokaLedOrange = 0xFFB24D
+
+ +
+
+ +

◆ kAlokaLedPink

+ +
+
+ + + + +
const uint32_t kAlokaLedPink = 0xFF6897
+
+ +
+
+ +

◆ kAlokaLedPinkRed

+ +
+
+ + + + +
const uint32_t kAlokaLedPinkRed = 0xFF8877
+
+ +
+
+ +

◆ kAlokaLedRainbow

+ +
+
+ + + + +
const uint32_t kAlokaLedRainbow = 0xFF708F
+
+ +
+
+ +

◆ kAlokaLedRed

+ +
+
+ + + + +
const uint32_t kAlokaLedRed = 0xFFA857
+
+ +
+
+ +

◆ kAlokaLedTreeGrow

+ +
+
+ + + + +
const uint32_t kAlokaLedTreeGrow = 0xFF58A7
+
+ +
+
+ +

◆ kAlokaLedWhite

+ +
+
+ + + + +
const uint32_t kAlokaLedWhite = 0xFF906F
+
+ +
+
+ +

◆ kAlokaLedYellow

+ +
+
+ + + + +
const uint32_t kAlokaLedYellow = 0xFF00FF
+
+ +
+
+ +

◆ kAlokaNightFade

+ +
+
+ + + + +
const uint32_t kAlokaNightFade = 0xFF50AF
+
+ +
+
+ +

◆ kAlokaNightTimer

+ +
+
+ + + + +
const uint32_t kAlokaNightTimer = 0xFF7887
+
+ +
+
+ +

◆ kAlokaPower

+ +
+
+ + + + +
const uint32_t kAlokaPower = 0xFF609F
+
+ +
+
+ +

◆ kNecBitMark

+ +
+
+ + + + +
const uint16_t kNecBitMark = kNecBitMarkTicks * kNecTick
+
+ +
+
+ +

◆ kNecBitMarkTicks

+ +
+
+ + + + +
const uint16_t kNecBitMarkTicks = 1
+
+ +
+
+ +

◆ kNecHdrMark

+ +
+
+ + + + +
const uint16_t kNecHdrMark = kNecHdrMarkTicks * kNecTick
+
+ +
+
+ +

◆ kNecHdrMarkTicks

+ +
+
+ + + + +
const uint16_t kNecHdrMarkTicks = 16
+
+ +
+
+ +

◆ kNecHdrSpace

+ +
+
+ + + + +
const uint16_t kNecHdrSpace = kNecHdrSpaceTicks * kNecTick
+
+ +
+
+ +

◆ kNecHdrSpaceTicks

+ +
+
+ + + + +
const uint16_t kNecHdrSpaceTicks = 8
+
+ +
+
+ +

◆ kNecMinCommandLength

+ +
+
+ + + + +
const uint32_t kNecMinCommandLength = kNecMinCommandLengthTicks * kNecTick
+
+ +
+
+ +

◆ kNecMinCommandLengthTicks

+ +
+
+ + + + +
const uint16_t kNecMinCommandLengthTicks = 193
+
+ +
+
+ +

◆ kNecMinGap

+ +
+
+ + + + +
const uint32_t kNecMinGap
+
+
+ +

◆ kNecMinGapTicks

+ +
+
+ + + + +
const uint16_t kNecMinGapTicks
+
+
+ +

◆ kNecOneSpace

+ +
+
+ + + + +
const uint16_t kNecOneSpace = kNecOneSpaceTicks * kNecTick
+
+ +
+
+ +

◆ kNecOneSpaceTicks

+ +
+
+ + + + +
const uint16_t kNecOneSpaceTicks = 3
+
+ +
+
+ +

◆ kNecRptLength

+ +
+
+ + + + +
const uint16_t kNecRptLength = 4
+
+ +
+
+ +

◆ kNecRptSpace

+ +
+
+ + + + +
const uint16_t kNecRptSpace = kNecRptSpaceTicks * kNecTick
+
+ +
+
+ +

◆ kNecRptSpaceTicks

+ +
+
+ + + + +
const uint16_t kNecRptSpaceTicks = 4
+
+ +
+
+ +

◆ kNecTick

+ +
+
+ + + + +
const uint16_t kNecTick = 560
+
+ +
+
+ +

◆ kNecZeroSpace

+ +
+
+ + + + +
const uint16_t kNecZeroSpace = kNecZeroSpaceTicks * kNecTick
+
+ +
+
+ +

◆ kNecZeroSpaceTicks

+ +
+
+ + + + +
const uint16_t kNecZeroSpaceTicks = 1
+
+ +
+
+
+
const uint16_t kNecBitMarkTicks
Definition: ir_NEC.h:30
+
const uint16_t kNecHdrSpace
Definition: ir_NEC.h:29
+
const uint16_t kNecBitMark
Definition: ir_NEC.h:31
+
const uint32_t kNecMinCommandLength
Definition: ir_NEC.h:40
+
const uint16_t kNecOneSpace
Definition: ir_NEC.h:33
+
const uint16_t kNecMinCommandLengthTicks
Definition: ir_NEC.h:39
+
const uint16_t kNecOneSpaceTicks
Definition: ir_NEC.h:32
+
const uint16_t kNecHdrMarkTicks
Definition: ir_NEC.h:26
+
const uint16_t kNECBits
Definition: IRremoteESP8266.h:948
+
const uint16_t kNecHdrMark
Definition: ir_NEC.h:27
+
const uint16_t kNecHdrSpaceTicks
Definition: ir_NEC.h:28
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__NEC_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__NEC_8h_source.html new file mode 100644 index 000000000..6e315d527 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__NEC_8h_source.html @@ -0,0 +1,189 @@ + + + + + + + +IRremoteESP8266: src/ir_NEC.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_NEC.h
+
+
+Go to the documentation of this file.
1 // Copyright 2009 Ken Shirriff
+
2 // Copyright 2017, 2018 David Conran
+
3 
+
8 
+
9 // Supports:
+
10 // Brand: Yamaha, Model: RAV561 remote
+
11 // Brand: Yamaha, Model: RXV585B A/V Receiver
+
12 // Brand: Aloka, Model: SleepyLights LED Lamp
+
13 // Brand: Toshiba, Model: 42TL838 LCD TV
+
14 // Brand: Duux, Model: Blizzard Smart 10K / DXMA04 A/C
+
15 // Brand: Duux, Model: YJ-A081 TR Remote
+
16 // Brand: Silan Microelectronics, Model: SC6121-001 IC
+
17 
+
18 #ifndef IR_NEC_H_
+
19 #define IR_NEC_H_
+
20 
+
21 #include <stdint.h>
+
22 #include "IRremoteESP8266.h"
+
23 
+
24 // Constants
+
25 const uint16_t kNecTick = 560;
+
26 const uint16_t kNecHdrMarkTicks = 16;
+ +
28 const uint16_t kNecHdrSpaceTicks = 8;
+ +
30 const uint16_t kNecBitMarkTicks = 1;
+ +
32 const uint16_t kNecOneSpaceTicks = 3;
+ +
34 const uint16_t kNecZeroSpaceTicks = 1;
+ +
36 const uint16_t kNecRptSpaceTicks = 4;
+ +
38 const uint16_t kNecRptLength = 4;
+
39 const uint16_t kNecMinCommandLengthTicks = 193;
+ +
41 const uint32_t kNecMinGap =
+ + +
44  kNecBitMark);
+
45 const uint16_t kNecMinGapTicks =
+ + + +
49 
+
50 // IR codes and structure for kids ALOKA SleepyLights LED Lamp.
+
51 // https://aloka-designs.com/
+
52 // Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1004
+
53 //
+
54 // May be useful for someone wanting to control the lamp.
+
55 //
+
56 // The lamp is toggled On and Off with the same power button.
+
57 // The colour, when selected, is the brightest and there are 4 levels of
+
58 // brightness that decrease on each send of the colour. A fifth send of the
+
59 // colour resets to brightest again.
+
60 //
+
61 // Remote buttons defined left to right, top line to bottom line on the remote.
+
62 const uint32_t kAlokaPower = 0xFF609F;
+
63 const uint32_t kAlokaLedWhite = 0xFF906F;
+
64 const uint32_t kAlokaLedGreen = 0xFF9867;
+
65 const uint32_t kAlokaLedBlue = 0xFFD827;
+
66 const uint32_t kAlokaLedPinkRed = 0xFF8877;
+
67 const uint32_t kAlokaLedRed = 0xFFA857;
+
68 const uint32_t kAlokaLedLightGreen = 0xFFE817;
+
69 const uint32_t kAlokaLedMidBlue = 0xFF48B7;
+
70 const uint32_t kAlokaLedPink = 0xFF6897;
+
71 const uint32_t kAlokaLedOrange = 0xFFB24D;
+
72 const uint32_t kAlokaLedYellow = 0xFF00FF;
+
73 const uint32_t kAlokaNightFade = 0xFF50AF;
+
74 const uint32_t kAlokaNightTimer = 0xFF7887;
+
75 const uint32_t kAlokaLedRainbow = 0xFF708F;
+
76 // Didn't have a better description for it...
+
77 const uint32_t kAlokaLedTreeGrow = 0xFF58A7;
+
78 #endif // IR_NEC_H_
+
+
const uint32_t kAlokaLedWhite
Definition: ir_NEC.h:63
+
const uint16_t kNecBitMarkTicks
Definition: ir_NEC.h:30
+
const uint16_t kNecHdrSpace
Definition: ir_NEC.h:29
+
const uint16_t kNecBitMark
Definition: ir_NEC.h:31
+
const uint32_t kNecMinCommandLength
Definition: ir_NEC.h:40
+
const uint16_t kNecZeroSpaceTicks
Definition: ir_NEC.h:34
+
const uint32_t kAlokaLedBlue
Definition: ir_NEC.h:65
+
const uint32_t kAlokaLedLightGreen
Definition: ir_NEC.h:68
+
const uint16_t kNecOneSpace
Definition: ir_NEC.h:33
+
const uint32_t kAlokaNightTimer
Definition: ir_NEC.h:74
+
const uint16_t kNecMinCommandLengthTicks
Definition: ir_NEC.h:39
+
const uint16_t kNecZeroSpace
Definition: ir_NEC.h:35
+
const uint16_t kNecOneSpaceTicks
Definition: ir_NEC.h:32
+
const uint16_t kNecRptSpace
Definition: ir_NEC.h:37
+
const uint16_t kNecHdrMarkTicks
Definition: ir_NEC.h:26
+
const uint32_t kAlokaNightFade
Definition: ir_NEC.h:73
+ +
const uint16_t kNecRptLength
Definition: ir_NEC.h:38
+
const uint32_t kAlokaLedPink
Definition: ir_NEC.h:70
+
const uint16_t kNecMinGapTicks
Definition: ir_NEC.h:45
+
const uint32_t kAlokaLedPinkRed
Definition: ir_NEC.h:66
+
const uint16_t kNECBits
Definition: IRremoteESP8266.h:948
+
const uint32_t kAlokaLedRed
Definition: ir_NEC.h:67
+
const uint32_t kAlokaLedTreeGrow
Definition: ir_NEC.h:77
+
const uint16_t kNecHdrMark
Definition: ir_NEC.h:27
+
const uint16_t kNecRptSpaceTicks
Definition: ir_NEC.h:36
+
const uint32_t kAlokaLedOrange
Definition: ir_NEC.h:71
+
const uint32_t kNecMinGap
Definition: ir_NEC.h:41
+
const uint32_t kAlokaPower
Definition: ir_NEC.h:62
+
const uint32_t kAlokaLedMidBlue
Definition: ir_NEC.h:69
+
const uint32_t kAlokaLedRainbow
Definition: ir_NEC.h:75
+
const uint32_t kAlokaLedYellow
Definition: ir_NEC.h:72
+
const uint16_t kNecHdrSpaceTicks
Definition: ir_NEC.h:28
+
const uint16_t kNecTick
Definition: ir_NEC.h:25
+
const uint32_t kAlokaLedGreen
Definition: ir_NEC.h:64
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Neoclima_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Neoclima_8cpp.html new file mode 100644 index 000000000..3de0b6df2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Neoclima_8cpp.html @@ -0,0 +1,191 @@ + + + + + + + +IRremoteESP8266: src/ir_Neoclima.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Neoclima.cpp File Reference
+
+
+ +

Support for Neoclima protocols. Analysis by crankyoldgit & AndreyShpilevoy Code by crankyoldgit. +More...

+ + + + + + + + + + + + + + +

+Variables

const uint16_t kNeoclimaHdrMark = 6112
 
const uint16_t kNeoclimaHdrSpace = 7391
 
const uint16_t kNeoclimaBitMark = 537
 
const uint16_t kNeoclimaOneSpace = 1651
 
const uint16_t kNeoclimaZeroSpace = 571
 
const uint32_t kNeoclimaMinGap = kDefaultMessageGap
 
+

Detailed Description

+

Support for Neoclima protocols. Analysis by crankyoldgit & AndreyShpilevoy Code by crankyoldgit.

+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/764
+
+https://drive.google.com/file/d/1kjYk4zS9NQcMQhFkak-L4mp4UuaAIesW/view
+

Variable Documentation

+ +

◆ kNeoclimaBitMark

+ +
+
+ + + + +
const uint16_t kNeoclimaBitMark = 537
+
+ +
+
+ +

◆ kNeoclimaHdrMark

+ +
+
+ + + + +
const uint16_t kNeoclimaHdrMark = 6112
+
+ +
+
+ +

◆ kNeoclimaHdrSpace

+ +
+
+ + + + +
const uint16_t kNeoclimaHdrSpace = 7391
+
+ +
+
+ +

◆ kNeoclimaMinGap

+ +
+
+ + + + +
const uint32_t kNeoclimaMinGap = kDefaultMessageGap
+
+ +
+
+ +

◆ kNeoclimaOneSpace

+ +
+
+ + + + +
const uint16_t kNeoclimaOneSpace = 1651
+
+ +
+
+ +

◆ kNeoclimaZeroSpace

+ +
+
+ + + + +
const uint16_t kNeoclimaZeroSpace = 571
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Neoclima_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Neoclima_8h.html new file mode 100644 index 000000000..6ca564a14 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Neoclima_8h.html @@ -0,0 +1,888 @@ + + + + + + + +IRremoteESP8266: src/ir_Neoclima.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Neoclima.h File Reference
+
+
+ +

Support for Neoclima protocols. Analysis by crankyoldgit & AndreyShpilevoy. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRNeoclimaAc
 Class for handling detailed Neoclima A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kNeoclima8CHeatOffset = 1
 
const uint8_t kNeoclimaIonOffset = 2
 
const uint8_t kNeoclimaLightOffset = 0
 
const uint8_t kNeoclimaHoldOffset = 2
 
const uint8_t kNeoclimaTurboOffset = 3
 
const uint8_t kNeoclimaEyeOffset = 6
 
const uint8_t kNeoclimaFreshOffset = 7
 
const uint8_t kNeoclimaButtonOffset = 0
 
const uint8_t kNeoclimaButtonSize = 5
 
const uint8_t kNeoclimaButtonPower = 0x00
 
const uint8_t kNeoclimaButtonMode = 0x01
 
const uint8_t kNeoclimaButtonTempUp = 0x02
 
const uint8_t kNeoclimaButtonTempDown = 0x03
 
const uint8_t kNeoclimaButtonSwing = 0x04
 
const uint8_t kNeoclimaButtonFanSpeed = 0x05
 
const uint8_t kNeoclimaButtonAirFlow = 0x07
 
const uint8_t kNeoclimaButtonHold = 0x08
 
const uint8_t kNeoclimaButtonSleep = 0x09
 
const uint8_t kNeoclimaButtonTurbo = 0x0A
 
const uint8_t kNeoclimaButtonLight = 0x0B
 
const uint8_t kNeoclimaButtonEye = 0x0E
 
const uint8_t kNeoclimaButtonFollow = 0x13
 
const uint8_t kNeoclimaButtonIon = 0x14
 
const uint8_t kNeoclimaButtonFresh = 0x15
 
const uint8_t kNeoclimaButton8CHeat = 0x1D
 
const uint8_t kNeoclimaSleepOffset = 0
 
const uint8_t kNeoclimaPowerOffset = 1
 
const uint8_t kNeoclimaSwingVOffset = 2
 
const uint8_t kNeoclimaSwingVSize = 2
 
const uint8_t kNeoclimaSwingVOn = 0b01
 
const uint8_t kNeoclimaSwingVOff = 0b10
 
const uint8_t kNeoclimaSwingHOffset = 4
 
const uint8_t kNeoclimaFanOffest = 5
 
const uint8_t kNeoclimaFanSize = 2
 
const uint8_t kNeoclimaFanAuto = 0b00
 
const uint8_t kNeoclimaFanHigh = 0b01
 
const uint8_t kNeoclimaFanMed = 0b10
 
const uint8_t kNeoclimaFanLow = 0b11
 
const uint8_t kNeoclimaFollowMe = 0x5D
 
const uint8_t kNeoclimaTempOffset = 0
 
const uint8_t kNeoclimaTempSize = 5
 
const uint8_t kNeoclimaMinTemp = 16
 
const uint8_t kNeoclimaMaxTemp = 32
 
const uint8_t kNeoclimaModeOffset = 5
 
const uint8_t kNeoclimaAuto = 0b000
 
const uint8_t kNeoclimaCool = 0b001
 
const uint8_t kNeoclimaDry = 0b010
 
const uint8_t kNeoclimaFan = 0b011
 
const uint8_t kNeoclimaHeat = 0b100
 
+

Detailed Description

+

Support for Neoclima protocols. Analysis by crankyoldgit & AndreyShpilevoy.

+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/764
+
+https://drive.google.com/file/d/1kjYk4zS9NQcMQhFkak-L4mp4UuaAIesW/view
+

Variable Documentation

+ +

◆ kNeoclima8CHeatOffset

+ +
+
+ + + + +
const uint8_t kNeoclima8CHeatOffset = 1
+
+ +
+
+ +

◆ kNeoclimaAuto

+ +
+
+ + + + +
const uint8_t kNeoclimaAuto = 0b000
+
+ +
+
+ +

◆ kNeoclimaButton8CHeat

+ +
+
+ + + + +
const uint8_t kNeoclimaButton8CHeat = 0x1D
+
+ +
+
+ +

◆ kNeoclimaButtonAirFlow

+ +
+
+ + + + +
const uint8_t kNeoclimaButtonAirFlow = 0x07
+
+ +
+
+ +

◆ kNeoclimaButtonEye

+ +
+
+ + + + +
const uint8_t kNeoclimaButtonEye = 0x0E
+
+ +
+
+ +

◆ kNeoclimaButtonFanSpeed

+ +
+
+ + + + +
const uint8_t kNeoclimaButtonFanSpeed = 0x05
+
+ +
+
+ +

◆ kNeoclimaButtonFollow

+ +
+
+ + + + +
const uint8_t kNeoclimaButtonFollow = 0x13
+
+ +
+
+ +

◆ kNeoclimaButtonFresh

+ +
+
+ + + + +
const uint8_t kNeoclimaButtonFresh = 0x15
+
+ +
+
+ +

◆ kNeoclimaButtonHold

+ +
+
+ + + + +
const uint8_t kNeoclimaButtonHold = 0x08
+
+ +
+
+ +

◆ kNeoclimaButtonIon

+ +
+
+ + + + +
const uint8_t kNeoclimaButtonIon = 0x14
+
+ +
+
+ +

◆ kNeoclimaButtonLight

+ +
+
+ + + + +
const uint8_t kNeoclimaButtonLight = 0x0B
+
+ +
+
+ +

◆ kNeoclimaButtonMode

+ +
+
+ + + + +
const uint8_t kNeoclimaButtonMode = 0x01
+
+ +
+
+ +

◆ kNeoclimaButtonOffset

+ +
+
+ + + + +
const uint8_t kNeoclimaButtonOffset = 0
+
+ +
+
+ +

◆ kNeoclimaButtonPower

+ +
+
+ + + + +
const uint8_t kNeoclimaButtonPower = 0x00
+
+ +
+
+ +

◆ kNeoclimaButtonSize

+ +
+
+ + + + +
const uint8_t kNeoclimaButtonSize = 5
+
+ +
+
+ +

◆ kNeoclimaButtonSleep

+ +
+
+ + + + +
const uint8_t kNeoclimaButtonSleep = 0x09
+
+ +
+
+ +

◆ kNeoclimaButtonSwing

+ +
+
+ + + + +
const uint8_t kNeoclimaButtonSwing = 0x04
+
+ +
+
+ +

◆ kNeoclimaButtonTempDown

+ +
+
+ + + + +
const uint8_t kNeoclimaButtonTempDown = 0x03
+
+ +
+
+ +

◆ kNeoclimaButtonTempUp

+ +
+
+ + + + +
const uint8_t kNeoclimaButtonTempUp = 0x02
+
+ +
+
+ +

◆ kNeoclimaButtonTurbo

+ +
+
+ + + + +
const uint8_t kNeoclimaButtonTurbo = 0x0A
+
+ +
+
+ +

◆ kNeoclimaCool

+ +
+
+ + + + +
const uint8_t kNeoclimaCool = 0b001
+
+ +
+
+ +

◆ kNeoclimaDry

+ +
+
+ + + + +
const uint8_t kNeoclimaDry = 0b010
+
+ +
+
+ +

◆ kNeoclimaEyeOffset

+ +
+
+ + + + +
const uint8_t kNeoclimaEyeOffset = 6
+
+ +
+
+ +

◆ kNeoclimaFan

+ +
+
+ + + + +
const uint8_t kNeoclimaFan = 0b011
+
+ +
+
+ +

◆ kNeoclimaFanAuto

+ +
+
+ + + + +
const uint8_t kNeoclimaFanAuto = 0b00
+
+ +
+
+ +

◆ kNeoclimaFanHigh

+ +
+
+ + + + +
const uint8_t kNeoclimaFanHigh = 0b01
+
+ +
+
+ +

◆ kNeoclimaFanLow

+ +
+
+ + + + +
const uint8_t kNeoclimaFanLow = 0b11
+
+ +
+
+ +

◆ kNeoclimaFanMed

+ +
+
+ + + + +
const uint8_t kNeoclimaFanMed = 0b10
+
+ +
+
+ +

◆ kNeoclimaFanOffest

+ +
+
+ + + + +
const uint8_t kNeoclimaFanOffest = 5
+
+ +
+
+ +

◆ kNeoclimaFanSize

+ +
+
+ + + + +
const uint8_t kNeoclimaFanSize = 2
+
+ +
+
+ +

◆ kNeoclimaFollowMe

+ +
+
+ + + + +
const uint8_t kNeoclimaFollowMe = 0x5D
+
+ +
+
+ +

◆ kNeoclimaFreshOffset

+ +
+
+ + + + +
const uint8_t kNeoclimaFreshOffset = 7
+
+ +
+
+ +

◆ kNeoclimaHeat

+ +
+
+ + + + +
const uint8_t kNeoclimaHeat = 0b100
+
+ +
+
+ +

◆ kNeoclimaHoldOffset

+ +
+
+ + + + +
const uint8_t kNeoclimaHoldOffset = 2
+
+ +
+
+ +

◆ kNeoclimaIonOffset

+ +
+
+ + + + +
const uint8_t kNeoclimaIonOffset = 2
+
+ +
+
+ +

◆ kNeoclimaLightOffset

+ +
+
+ + + + +
const uint8_t kNeoclimaLightOffset = 0
+
+ +
+
+ +

◆ kNeoclimaMaxTemp

+ +
+
+ + + + +
const uint8_t kNeoclimaMaxTemp = 32
+
+ +
+
+ +

◆ kNeoclimaMinTemp

+ +
+
+ + + + +
const uint8_t kNeoclimaMinTemp = 16
+
+ +
+
+ +

◆ kNeoclimaModeOffset

+ +
+
+ + + + +
const uint8_t kNeoclimaModeOffset = 5
+
+ +
+
+ +

◆ kNeoclimaPowerOffset

+ +
+
+ + + + +
const uint8_t kNeoclimaPowerOffset = 1
+
+ +
+
+ +

◆ kNeoclimaSleepOffset

+ +
+
+ + + + +
const uint8_t kNeoclimaSleepOffset = 0
+
+ +
+
+ +

◆ kNeoclimaSwingHOffset

+ +
+
+ + + + +
const uint8_t kNeoclimaSwingHOffset = 4
+
+ +
+
+ +

◆ kNeoclimaSwingVOff

+ +
+
+ + + + +
const uint8_t kNeoclimaSwingVOff = 0b10
+
+ +
+
+ +

◆ kNeoclimaSwingVOffset

+ +
+
+ + + + +
const uint8_t kNeoclimaSwingVOffset = 2
+
+ +
+
+ +

◆ kNeoclimaSwingVOn

+ +
+
+ + + + +
const uint8_t kNeoclimaSwingVOn = 0b01
+
+ +
+
+ +

◆ kNeoclimaSwingVSize

+ +
+
+ + + + +
const uint8_t kNeoclimaSwingVSize = 2
+
+ +
+
+ +

◆ kNeoclimaTempOffset

+ +
+
+ + + + +
const uint8_t kNeoclimaTempOffset = 0
+
+ +
+
+ +

◆ kNeoclimaTempSize

+ +
+
+ + + + +
const uint8_t kNeoclimaTempSize = 5
+
+ +
+
+ +

◆ kNeoclimaTurboOffset

+ +
+
+ + + + +
const uint8_t kNeoclimaTurboOffset = 3
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Neoclima_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Neoclima_8h_source.html new file mode 100644 index 000000000..ccfa9da53 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Neoclima_8h_source.html @@ -0,0 +1,340 @@ + + + + + + + +IRremoteESP8266: src/ir_Neoclima.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Neoclima.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 David Conran
+
2 
+
8 
+
9 // Supports:
+
10 // Brand: Neoclima, Model: NS-09AHTI A/C
+
11 // Brand: Neoclima, Model: ZH/TY-01 remote
+
12 
+
13 #ifndef IR_NEOCLIMA_H_
+
14 #define IR_NEOCLIMA_H_
+
15 
+
16 #define __STDC_LIMIT_MACROS
+
17 #include <stdint.h>
+
18 #ifndef UNIT_TEST
+
19 #include <Arduino.h>
+
20 #endif
+
21 #include "IRremoteESP8266.h"
+
22 #include "IRsend.h"
+
23 #ifdef UNIT_TEST
+
24 #include "IRsend_test.h"
+
25 #endif
+
26 
+
27 // Constants
+
28 // state[1]
+
29 const uint8_t kNeoclima8CHeatOffset = 1;
+
30 const uint8_t kNeoclimaIonOffset = 2;
+
31 // state[3]
+
32 const uint8_t kNeoclimaLightOffset = 0;
+
33 const uint8_t kNeoclimaHoldOffset = 2;
+
34 const uint8_t kNeoclimaTurboOffset = 3;
+
35 const uint8_t kNeoclimaEyeOffset = 6;
+
36 // state[5]
+
37 const uint8_t kNeoclimaFreshOffset = 7;
+
38 const uint8_t kNeoclimaButtonOffset = 0;
+
39 const uint8_t kNeoclimaButtonSize = 5;
+
40 const uint8_t kNeoclimaButtonPower = 0x00;
+
41 const uint8_t kNeoclimaButtonMode = 0x01;
+
42 const uint8_t kNeoclimaButtonTempUp = 0x02;
+
43 const uint8_t kNeoclimaButtonTempDown = 0x03;
+
44 const uint8_t kNeoclimaButtonSwing = 0x04;
+
45 const uint8_t kNeoclimaButtonFanSpeed = 0x05;
+
46 const uint8_t kNeoclimaButtonAirFlow = 0x07;
+
47 const uint8_t kNeoclimaButtonHold = 0x08;
+
48 const uint8_t kNeoclimaButtonSleep = 0x09;
+
49 const uint8_t kNeoclimaButtonTurbo = 0x0A;
+
50 const uint8_t kNeoclimaButtonLight = 0x0B;
+
51 const uint8_t kNeoclimaButtonEye = 0x0E;
+
52 const uint8_t kNeoclimaButtonFollow = 0x13;
+
53 const uint8_t kNeoclimaButtonIon = 0x14;
+
54 const uint8_t kNeoclimaButtonFresh = 0x15;
+
55 const uint8_t kNeoclimaButton8CHeat = 0x1D;
+
56 // state[7]
+
57 const uint8_t kNeoclimaSleepOffset = 0;
+
58 const uint8_t kNeoclimaPowerOffset = 1;
+
59 const uint8_t kNeoclimaSwingVOffset = 2;
+
60 const uint8_t kNeoclimaSwingVSize = 2; // Bits
+
61 const uint8_t kNeoclimaSwingVOn = 0b01;
+
62 const uint8_t kNeoclimaSwingVOff = 0b10;
+
63 const uint8_t kNeoclimaSwingHOffset = 4;
+
64 const uint8_t kNeoclimaFanOffest = 5;
+
65 const uint8_t kNeoclimaFanSize = 2;
+
66 const uint8_t kNeoclimaFanAuto = 0b00;
+
67 const uint8_t kNeoclimaFanHigh = 0b01;
+
68 const uint8_t kNeoclimaFanMed = 0b10;
+
69 const uint8_t kNeoclimaFanLow = 0b11;
+
70 // state[8]
+
71 const uint8_t kNeoclimaFollowMe = 0x5D; // Also 0x5F
+
72 // state[9]
+
73 const uint8_t kNeoclimaTempOffset = 0;
+
74 const uint8_t kNeoclimaTempSize = 5; // Bits
+
75 const uint8_t kNeoclimaMinTemp = 16; // 16C
+
76 const uint8_t kNeoclimaMaxTemp = 32; // 32C
+
77 const uint8_t kNeoclimaModeOffset = 5;
+
78 const uint8_t kNeoclimaAuto = 0b000;
+
79 const uint8_t kNeoclimaCool = 0b001;
+
80 const uint8_t kNeoclimaDry = 0b010;
+
81 const uint8_t kNeoclimaFan = 0b011;
+
82 const uint8_t kNeoclimaHeat = 0b100;
+
83 
+
84 // Classes
+
86 class IRNeoclimaAc {
+
87  public:
+
88  explicit IRNeoclimaAc(const uint16_t pin, const bool inverted = false,
+
89  const bool use_modulation = true);
+
90  void stateReset(void);
+
91 #if SEND_NEOCLIMA
+
92  void send(const uint16_t repeat = kNeoclimaMinRepeat);
+
97  int8_t calibrate(void) { return _irsend.calibrate(); }
+
98 #endif // SEND_NEOCLIMA
+
99  void begin(void);
+
100  void setButton(const uint8_t button);
+
101  uint8_t getButton(void);
+
102  void on(void);
+
103  void off(void);
+
104  void setPower(const bool on);
+
105  bool getPower(void);
+
106  void setMode(const uint8_t mode);
+
107  uint8_t getMode(void);
+
108  void setTemp(const uint8_t temp);
+
109  uint8_t getTemp(void);
+
110  void setFan(const uint8_t speed);
+
111  uint8_t getFan(void);
+
112  void setSwingV(const bool on);
+
113  bool getSwingV(void);
+
114  void setSwingH(const bool on);
+
115  bool getSwingH(void);
+
116  void setSleep(const bool on);
+
117  bool getSleep(void);
+
118  void setTurbo(const bool on);
+
119  bool getTurbo(void);
+
120  void setFresh(const bool on);
+
121  bool getFresh(void);
+
122  void setHold(const bool on);
+
123  bool getHold(void);
+
124  void setIon(const bool on);
+
125  bool getIon(void);
+
126  void setLight(const bool on);
+
127  bool getLight(void);
+
128  void set8CHeat(const bool on);
+
129  bool get8CHeat(void);
+
130  void setEye(const bool on);
+
131  bool getEye(void);
+
132  // DISABLED: See TODO in ir_Neoclima.cpp
+
133  // void setFollow(const bool on);
+
134  bool getFollow(void);
+
135  uint8_t* getRaw(void);
+
136  void setRaw(const uint8_t new_code[],
+
137  const uint16_t length = kNeoclimaStateLength);
+
138  static bool validChecksum(const uint8_t state[],
+
139  const uint16_t length = kNeoclimaStateLength);
+
140  static uint8_t calcChecksum(const uint8_t state[],
+
141  const uint16_t length = kNeoclimaStateLength);
+
142  String toString(void);
+
143  uint8_t convertMode(const stdAc::opmode_t mode);
+
144  uint8_t convertFan(const stdAc::fanspeed_t speed);
+
145  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
146  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
147  stdAc::state_t toCommon(void);
+
148 #ifndef UNIT_TEST
+
149 
+
150  private:
+ +
152 #else // UNIT_TEST
+
153  IRsendTest _irsend;
+
155 #endif // UNIT_TEST
+ +
158  void checksum(const uint16_t length = kNeoclimaStateLength);
+
159 };
+
160 
+
161 #endif // IR_NEOCLIMA_H_
+
+
const uint8_t kNeoclimaFanHigh
Definition: ir_Neoclima.h:67
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Neoclima.cpp:237
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Neoclima.cpp:301
+
const uint8_t kNeoclimaButtonFanSpeed
Definition: ir_Neoclima.h:45
+
const uint8_t kNeoclimaButtonTurbo
Definition: ir_Neoclima.h:49
+
const uint8_t kNeoclimaFollowMe
Definition: ir_Neoclima.h:71
+
bool getSleep(void)
Get the Sleep setting of the A/C.
Definition: ir_Neoclima.cpp:319
+
const uint8_t kNeoclimaEyeOffset
Definition: ir_Neoclima.h:35
+
const uint8_t kNeoclimaTempOffset
Definition: ir_Neoclima.h:73
+
bool getEye(void)
Get the Eye (Sensor) setting of the A/C.
Definition: ir_Neoclima.cpp:442
+
bool getFollow(void)
Get the Follow Me setting of the A/C.
Definition: ir_Neoclima.cpp:459
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
const uint8_t kNeoclimaIonOffset
Definition: ir_Neoclima.h:30
+
const uint8_t kNeoclimaDry
Definition: ir_Neoclima.h:80
+
static uint8_t calcChecksum(const uint8_t state[], const uint16_t length=kNeoclimaStateLength)
Calculate the checksum for a given state.
Definition: ir_Neoclima.cpp:84
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Neoclima.h:97
+
const uint8_t kNeoclimaMaxTemp
Definition: ir_Neoclima.h:76
+
void set8CHeat(const bool on)
Set the 8°C Heat setting of the A/C.
Definition: ir_Neoclima.cpp:422
+
const uint8_t kNeoclimaButtonEye
Definition: ir_Neoclima.h:51
+
const uint8_t kNeoclimaMinTemp
Definition: ir_Neoclima.h:75
+
const uint8_t kNeoclimaButtonPower
Definition: ir_Neoclima.h:40
+
void setFan(const uint8_t speed)
Set the speed of the fan.
Definition: ir_Neoclima.cpp:258
+
const uint8_t kNeoclimaSwingVOn
Definition: ir_Neoclima.h:61
+
const uint8_t kNeoclimaButtonMode
Definition: ir_Neoclima.h:41
+
const uint16_t kNeoclimaStateLength
Definition: IRremoteESP8266.h:949
+
void setHold(const bool on)
Set the Hold setting of the A/C.
Definition: ir_Neoclima.cpp:379
+
const uint8_t kNeoclimaSleepOffset
Definition: ir_Neoclima.h:57
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Neoclima.cpp:205
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Neoclima.cpp:178
+
void setRaw(const uint8_t new_code[], const uint16_t length=kNeoclimaStateLength)
Set the internal state from a valid code for this protocol.
Definition: ir_Neoclima.cpp:125
+
const uint8_t kNeoclimaButtonHold
Definition: ir_Neoclima.h:47
+ +
const uint8_t kNeoclimaSwingVSize
Definition: ir_Neoclima.h:60
+
const uint8_t kNeoclimaAuto
Definition: ir_Neoclima.h:78
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Neoclima.cpp:280
+
void setLight(const bool on)
Set the Light(LED display) setting of the A/C.
Definition: ir_Neoclima.cpp:405
+
const uint8_t kNeoclimaFan
Definition: ir_Neoclima.h:81
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_Neoclima.cpp:117
+
const uint8_t kNeoclimaFanAuto
Definition: ir_Neoclima.h:66
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
const uint8_t kNeoclimaFreshOffset
Definition: ir_Neoclima.h:37
+
bool getFresh(void)
Get the Frsh (air) setting of the A/C.
Definition: ir_Neoclima.cpp:373
+
uint8_t getButton(void)
Get the Button/Command setting of the A/C.
Definition: ir_Neoclima.cpp:159
+
std::string String
Definition: IRremoteESP8266.h:1093
+
bool getSwingH(void)
Get the horizontal swing (Air Flow) setting of the A/C.
Definition: ir_Neoclima.cpp:347
+
const uint8_t kNeoclimaButtonFresh
Definition: ir_Neoclima.h:54
+
bool getTurbo(void)
Get the Turbo setting of the A/C.
Definition: ir_Neoclima.cpp:360
+
const uint8_t kNeoclimaButtonAirFlow
Definition: ir_Neoclima.h:46
+ +
void stateReset(void)
Reset the state of the remote to a known good state/sequence.
Definition: ir_Neoclima.cpp:71
+
uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Neoclima.cpp:287
+
const uint8_t kNeoclimaButtonOffset
Definition: ir_Neoclima.h:38
+
const uint8_t kNeoclimaButtonTempDown
Definition: ir_Neoclima.h:43
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Neoclima.cpp:78
+
const uint8_t kNeoclima8CHeatOffset
Definition: ir_Neoclima.h:29
+
const uint8_t kNeoclimaSwingHOffset
Definition: ir_Neoclima.h:63
+
const uint8_t kNeoclimaPowerOffset
Definition: ir_Neoclima.h:58
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Neoclima.cpp:251
+
const uint8_t kNeoclimaFanSize
Definition: ir_Neoclima.h:65
+
bool getSwingV(void)
Get the vertical swing setting of the A/C.
Definition: ir_Neoclima.cpp:333
+
const uint8_t kNeoclimaButtonSize
Definition: ir_Neoclima.h:39
+
const uint8_t kNeoclimaLightOffset
Definition: ir_Neoclima.h:32
+
uint8_t remote_state[kNeoclimaStateLength]
State of the remote in code.
Definition: ir_Neoclima.h:157
+
const uint8_t kNeoclimaTempSize
Definition: ir_Neoclima.h:74
+
const uint8_t kNeoclimaButtonLight
Definition: ir_Neoclima.h:50
+
void setIon(const bool on)
Set the Ion (filter) setting of the A/C.
Definition: ir_Neoclima.cpp:392
+
const uint8_t kNeoclimaButtonSwing
Definition: ir_Neoclima.h:44
+
const uint8_t kNeoclimaButtonFollow
Definition: ir_Neoclima.h:52
+
bool getHold(void)
Get the Hold setting of the A/C.
Definition: ir_Neoclima.cpp:386
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Neoclima.h:151
+
const uint8_t kNeoclimaSwingVOff
Definition: ir_Neoclima.h:62
+
void setSwingV(const bool on)
Set the vertical swing setting of the A/C.
Definition: ir_Neoclima.cpp:325
+
void setEye(const bool on)
Set the Eye (Sensor) setting of the A/C.
Definition: ir_Neoclima.cpp:435
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Neoclima.cpp:225
+
const uint8_t kNeoclimaButtonSleep
Definition: ir_Neoclima.h:48
+
const uint8_t kNeoclimaTurboOffset
Definition: ir_Neoclima.h:34
+
void on(void)
Set the requested power state of the A/C to on.
Definition: ir_Neoclima.cpp:164
+
const uint8_t kNeoclimaFanMed
Definition: ir_Neoclima.h:68
+
void setFresh(const bool on)
Set the Fresh (air) setting of the A/C.
Definition: ir_Neoclima.cpp:366
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Neoclima.cpp:465
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Neoclima.cpp:171
+
const uint8_t kNeoclimaCool
Definition: ir_Neoclima.h:79
+
const uint8_t kNeoclimaHoldOffset
Definition: ir_Neoclima.h:33
+
const uint8_t kNeoclimaButton8CHeat
Definition: ir_Neoclima.h:55
+
bool getIon(void)
Get the Ion (filter) setting of the A/C.
Definition: ir_Neoclima.cpp:399
+
const uint8_t kNeoclimaSwingVOffset
Definition: ir_Neoclima.h:59
+
bool get8CHeat(void)
Get the 8°C Heat setting of the A/C.
Definition: ir_Neoclima.cpp:429
+
const uint8_t kNeoclimaFanOffest
Definition: ir_Neoclima.h:64
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Neoclima.cpp:212
+
const uint8_t kNeoclimaHeat
Definition: ir_Neoclima.h:82
+
void setButton(const uint8_t button)
Set the Button/Command pressed setting of the A/C.
Definition: ir_Neoclima.cpp:131
+
const uint8_t kNeoclimaButtonIon
Definition: ir_Neoclima.h:53
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Neoclima.cpp:493
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Neoclima.cpp:184
+
const uint8_t kNeoclimaFanLow
Definition: ir_Neoclima.h:69
+
void setTurbo(const bool on)
Set the Turbo setting of the A/C.
Definition: ir_Neoclima.cpp:353
+
void checksum(const uint16_t length=kNeoclimaStateLength)
Calculate & update the checksum for the internal state.
Definition: ir_Neoclima.cpp:102
+
const uint8_t kNeoclimaModeOffset
Definition: ir_Neoclima.h:77
+
void setSwingH(const bool on)
Set the horizontal swing setting of the A/C.
Definition: ir_Neoclima.cpp:340
+
void send(const uint16_t repeat=kNeoclimaMinRepeat)
Send the current internal state as an IR message.
Definition: ir_Neoclima.cpp:110
+
void off(void)
Set the requested power state of the A/C to off.
Definition: ir_Neoclima.cpp:167
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
const uint16_t kNeoclimaMinRepeat
Definition: IRremoteESP8266.h:951
+
IRNeoclimaAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Neoclima.cpp:64
+
Class for handling detailed Neoclima A/C messages.
Definition: ir_Neoclima.h:86
+
bool getLight(void)
Get the Light (LED display) setting of the A/C.
Definition: ir_Neoclima.cpp:412
+
void setSleep(const bool on)
Set the Sleep setting of the A/C.
Definition: ir_Neoclima.cpp:312
+
static bool validChecksum(const uint8_t state[], const uint16_t length=kNeoclimaStateLength)
Verify the checksum is valid for a given state.
Definition: ir_Neoclima.cpp:94
+
const uint8_t kNeoclimaButtonTempUp
Definition: ir_Neoclima.h:42
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Nikai_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Nikai_8cpp.html new file mode 100644 index 000000000..95c82cd74 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Nikai_8cpp.html @@ -0,0 +1,301 @@ + + + + + + + +IRremoteESP8266: src/ir_Nikai.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Nikai.cpp File Reference
+
+
+ +

Nikai. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kNikaiTick = 500
 
const uint16_t kNikaiHdrMarkTicks = 8
 
const uint16_t kNikaiHdrMark = kNikaiHdrMarkTicks * kNikaiTick
 
const uint16_t kNikaiHdrSpaceTicks = 8
 
const uint16_t kNikaiHdrSpace = kNikaiHdrSpaceTicks * kNikaiTick
 
const uint16_t kNikaiBitMarkTicks = 1
 
const uint16_t kNikaiBitMark = kNikaiBitMarkTicks * kNikaiTick
 
const uint16_t kNikaiOneSpaceTicks = 2
 
const uint16_t kNikaiOneSpace = kNikaiOneSpaceTicks * kNikaiTick
 
const uint16_t kNikaiZeroSpaceTicks = 4
 
const uint16_t kNikaiZeroSpace = kNikaiZeroSpaceTicks * kNikaiTick
 
const uint16_t kNikaiMinGapTicks = 17
 
const uint16_t kNikaiMinGap = kNikaiMinGapTicks * kNikaiTick
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kNikaiBitMark

+ +
+
+ + + + +
const uint16_t kNikaiBitMark = kNikaiBitMarkTicks * kNikaiTick
+
+ +
+
+ +

◆ kNikaiBitMarkTicks

+ +
+
+ + + + +
const uint16_t kNikaiBitMarkTicks = 1
+
+ +
+
+ +

◆ kNikaiHdrMark

+ +
+
+ + + + +
const uint16_t kNikaiHdrMark = kNikaiHdrMarkTicks * kNikaiTick
+
+ +
+
+ +

◆ kNikaiHdrMarkTicks

+ +
+
+ + + + +
const uint16_t kNikaiHdrMarkTicks = 8
+
+ +
+
+ +

◆ kNikaiHdrSpace

+ +
+
+ + + + +
const uint16_t kNikaiHdrSpace = kNikaiHdrSpaceTicks * kNikaiTick
+
+ +
+
+ +

◆ kNikaiHdrSpaceTicks

+ +
+
+ + + + +
const uint16_t kNikaiHdrSpaceTicks = 8
+
+ +
+
+ +

◆ kNikaiMinGap

+ +
+
+ + + + +
const uint16_t kNikaiMinGap = kNikaiMinGapTicks * kNikaiTick
+
+ +
+
+ +

◆ kNikaiMinGapTicks

+ +
+
+ + + + +
const uint16_t kNikaiMinGapTicks = 17
+
+ +
+
+ +

◆ kNikaiOneSpace

+ +
+
+ + + + +
const uint16_t kNikaiOneSpace = kNikaiOneSpaceTicks * kNikaiTick
+
+ +
+
+ +

◆ kNikaiOneSpaceTicks

+ +
+
+ + + + +
const uint16_t kNikaiOneSpaceTicks = 2
+
+ +
+
+ +

◆ kNikaiTick

+ +
+
+ + + + +
const uint16_t kNikaiTick = 500
+
+ +
+
+ +

◆ kNikaiZeroSpace

+ +
+
+ + + + +
const uint16_t kNikaiZeroSpace = kNikaiZeroSpaceTicks * kNikaiTick
+
+ +
+
+ +

◆ kNikaiZeroSpaceTicks

+ +
+
+ + + + +
const uint16_t kNikaiZeroSpaceTicks = 4
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Panasonic_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Panasonic_8cpp.html new file mode 100644 index 000000000..8e777f8ec --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Panasonic_8cpp.html @@ -0,0 +1,416 @@ + + + + + + + +IRremoteESP8266: src/ir_Panasonic.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Panasonic.cpp File Reference
+
+
+ +

Support for Panasonic protocols. Panasonic protocol originally added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post) +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kPanasonicTick = 432
 
const uint16_t kPanasonicHdrMarkTicks = 8
 
const uint16_t kPanasonicHdrMark = kPanasonicHdrMarkTicks * kPanasonicTick
 
const uint16_t kPanasonicHdrSpaceTicks = 4
 
const uint16_t kPanasonicHdrSpace = kPanasonicHdrSpaceTicks * kPanasonicTick
 
const uint16_t kPanasonicBitMarkTicks = 1
 
const uint16_t kPanasonicBitMark = kPanasonicBitMarkTicks * kPanasonicTick
 
const uint16_t kPanasonicOneSpaceTicks = 3
 
const uint16_t kPanasonicOneSpace = kPanasonicOneSpaceTicks * kPanasonicTick
 
const uint16_t kPanasonicZeroSpaceTicks = 1
 
const uint16_t kPanasonicZeroSpace = kPanasonicZeroSpaceTicks * kPanasonicTick
 
const uint16_t kPanasonicMinCommandLengthTicks = 378
 
const uint32_t kPanasonicMinCommandLength
 
const uint16_t kPanasonicEndGap = 5000
 
const uint16_t kPanasonicMinGapTicks
 
const uint32_t kPanasonicMinGap = kPanasonicMinGapTicks * kPanasonicTick
 
const uint16_t kPanasonicAcSectionGap = 10000
 
const uint16_t kPanasonicAcSection1Length = 8
 
const uint32_t kPanasonicAcMessageGap = kDefaultMessageGap
 
+

Detailed Description

+

Support for Panasonic protocols. Panasonic protocol originally added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)

+
See also
Panasonic https://github.com/z3t0/Arduino-IRremote
+
+http://www.remotecentral.com/cgi-bin/mboard/rc-pronto/thread.cgi?2615
+
+Panasonic A/C support heavily influenced by https://github.com/ToniA/ESPEasy/blob/HeatpumpIR/lib/HeatpumpIR/PanasonicHeatpumpIR.cpp Panasonic A/C Clock & Timer support: Reverse Engineering by MikkelTb Code by crankyoldgit
+

Variable Documentation

+ +

◆ kPanasonicAcMessageGap

+ +
+
+ + + + +
const uint32_t kPanasonicAcMessageGap = kDefaultMessageGap
+
+ +
+
+ +

◆ kPanasonicAcSection1Length

+ +
+
+ + + + +
const uint16_t kPanasonicAcSection1Length = 8
+
+ +
+
+ +

◆ kPanasonicAcSectionGap

+ +
+
+ + + + +
const uint16_t kPanasonicAcSectionGap = 10000
+
+ +
+
+ +

◆ kPanasonicBitMark

+ +
+
+ + + + +
const uint16_t kPanasonicBitMark = kPanasonicBitMarkTicks * kPanasonicTick
+
+ +
+
+ +

◆ kPanasonicBitMarkTicks

+ +
+
+ + + + +
const uint16_t kPanasonicBitMarkTicks = 1
+
+ +
+
+ +

◆ kPanasonicEndGap

+ +
+
+ + + + +
const uint16_t kPanasonicEndGap = 5000
+
+ +
+
+ +

◆ kPanasonicHdrMark

+ +
+
+ + + + +
const uint16_t kPanasonicHdrMark = kPanasonicHdrMarkTicks * kPanasonicTick
+
+ +
+
+ +

◆ kPanasonicHdrMarkTicks

+ +
+
+ + + + +
const uint16_t kPanasonicHdrMarkTicks = 8
+
+ +
+
+ +

◆ kPanasonicHdrSpace

+ +
+
+ + + + +
const uint16_t kPanasonicHdrSpace = kPanasonicHdrSpaceTicks * kPanasonicTick
+
+ +
+
+ +

◆ kPanasonicHdrSpaceTicks

+ +
+
+ + + + +
const uint16_t kPanasonicHdrSpaceTicks = 4
+
+ +
+
+ +

◆ kPanasonicMinCommandLength

+ +
+
+ + + + +
const uint32_t kPanasonicMinCommandLength
+
+
+ +

◆ kPanasonicMinCommandLengthTicks

+ +
+
+ + + + +
const uint16_t kPanasonicMinCommandLengthTicks = 378
+
+ +
+
+ +

◆ kPanasonicMinGap

+ +
+
+ + + + +
const uint32_t kPanasonicMinGap = kPanasonicMinGapTicks * kPanasonicTick
+
+ +
+
+ +

◆ kPanasonicMinGapTicks

+ +
+
+ + + + +
const uint16_t kPanasonicMinGapTicks
+
+
+ +

◆ kPanasonicOneSpace

+ +
+
+ + + + +
const uint16_t kPanasonicOneSpace = kPanasonicOneSpaceTicks * kPanasonicTick
+
+ +
+
+ +

◆ kPanasonicOneSpaceTicks

+ +
+
+ + + + +
const uint16_t kPanasonicOneSpaceTicks = 3
+
+ +
+
+ +

◆ kPanasonicTick

+ +
+
+ + + + +
const uint16_t kPanasonicTick = 432
+
+
+ +

◆ kPanasonicZeroSpace

+ +
+
+ + + + +
const uint16_t kPanasonicZeroSpace = kPanasonicZeroSpaceTicks * kPanasonicTick
+
+ +
+
+ +

◆ kPanasonicZeroSpaceTicks

+ +
+
+ + + + +
const uint16_t kPanasonicZeroSpaceTicks = 1
+
+ +
+
+
+
const uint16_t kPanasonicHdrMarkTicks
Definition: ir_Panasonic.cpp:29
+
const uint16_t kPanasonicBits
Definition: IRremoteESP8266.h:952
+
const uint16_t kPanasonicTick
Definition: ir_Panasonic.cpp:28
+
const uint16_t kPanasonicBitMarkTicks
Definition: ir_Panasonic.cpp:33
+
const uint16_t kPanasonicOneSpaceTicks
Definition: ir_Panasonic.cpp:35
+
const uint16_t kPanasonicHdrSpaceTicks
Definition: ir_Panasonic.cpp:31
+
const uint16_t kPanasonicMinCommandLengthTicks
Definition: ir_Panasonic.cpp:39
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Panasonic_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Panasonic_8h.html new file mode 100644 index 000000000..1eab81246 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Panasonic_8h.html @@ -0,0 +1,826 @@ + + + + + + + +IRremoteESP8266: src/ir_Panasonic.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Panasonic.h File Reference
+
+
+ +

Support for Panasonic protocols. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRPanasonicAc
 Class for handling detailed Panasonic A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kPanasonicFreq = 36700
 
const uint16_t kPanasonicAcExcess = 0
 
const uint16_t kPanasonicAcTolerance = 40
 
const uint8_t kPanasonicAcAuto = 0
 
const uint8_t kPanasonicAcDry = 2
 
const uint8_t kPanasonicAcCool = 3
 
const uint8_t kPanasonicAcHeat = 4
 
const uint8_t kPanasonicAcFan = 6
 
const uint8_t kPanasonicAcFanMin = 0
 
const uint8_t kPanasonicAcFanMed = 2
 
const uint8_t kPanasonicAcFanMax = 4
 
const uint8_t kPanasonicAcFanAuto = 7
 
const uint8_t kPanasonicAcFanDelta = 3
 
const uint8_t kPanasonicAcPowerOffset = 0
 
const uint8_t kPanasonicAcTempOffset = 1
 
const uint8_t kPanasonicAcTempSize = 5
 
const uint8_t kPanasonicAcMinTemp = 16
 
const uint8_t kPanasonicAcMaxTemp = 30
 
const uint8_t kPanasonicAcFanModeTemp = 27
 
const uint8_t kPanasonicAcQuietOffset = 0
 
const uint8_t kPanasonicAcPowerfulOffset = 5
 
const uint8_t kPanasonicAcQuietCkpOffset = kPanasonicAcPowerfulOffset
 
const uint8_t kPanasonicAcPowerfulCkpOffset = kPanasonicAcQuietOffset
 
const uint8_t kPanasonicAcSwingVHighest = 0x1
 
const uint8_t kPanasonicAcSwingVHigh = 0x2
 
const uint8_t kPanasonicAcSwingVMiddle = 0x3
 
const uint8_t kPanasonicAcSwingVLow = 0x4
 
const uint8_t kPanasonicAcSwingVLowest = 0x5
 
const uint8_t kPanasonicAcSwingVAuto = 0xF
 
const uint8_t kPanasonicAcSwingHMiddle = 0x6
 
const uint8_t kPanasonicAcSwingHFullLeft = 0x9
 
const uint8_t kPanasonicAcSwingHLeft = 0xA
 
const uint8_t kPanasonicAcSwingHRight = 0xB
 
const uint8_t kPanasonicAcSwingHFullRight = 0xC
 
const uint8_t kPanasonicAcSwingHAuto = 0xD
 
const uint8_t kPanasonicAcChecksumInit = 0xF4
 
const uint8_t kPanasonicAcOnTimerOffset = 1
 
const uint8_t kPanasonicAcOffTimerOffset = 2
 
const uint8_t kPanasonicAcTimeSize = 11
 
const uint8_t kPanasonicAcTimeOverflowSize = 3
 
const uint16_t kPanasonicAcTimeMax = 23 * 60 + 59
 
const uint16_t kPanasonicAcTimeSpecial = 0x600
 
const uint8_t kPanasonicAcIonFilterByte = 22
 
const uint8_t kPanasonicAcIonFilterOffset = 0
 
const uint8_t kPanasonicKnownGoodState [kPanasonicAcStateLength]
 
+

Detailed Description

+

Support for Panasonic protocols.

+
See also
Panasonic A/C support heavily influenced by https://github.com/ToniA/ESPEasy/blob/HeatpumpIR/lib/HeatpumpIR/PanasonicHeatpumpIR.cpp
+

Variable Documentation

+ +

◆ kPanasonicAcAuto

+ +
+
+ + + + +
const uint8_t kPanasonicAcAuto = 0
+
+ +
+
+ +

◆ kPanasonicAcChecksumInit

+ +
+
+ + + + +
const uint8_t kPanasonicAcChecksumInit = 0xF4
+
+ +
+
+ +

◆ kPanasonicAcCool

+ +
+
+ + + + +
const uint8_t kPanasonicAcCool = 3
+
+ +
+
+ +

◆ kPanasonicAcDry

+ +
+
+ + + + +
const uint8_t kPanasonicAcDry = 2
+
+ +
+
+ +

◆ kPanasonicAcExcess

+ +
+
+ + + + +
const uint16_t kPanasonicAcExcess = 0
+
+ +
+
+ +

◆ kPanasonicAcFan

+ +
+
+ + + + +
const uint8_t kPanasonicAcFan = 6
+
+ +
+
+ +

◆ kPanasonicAcFanAuto

+ +
+
+ + + + +
const uint8_t kPanasonicAcFanAuto = 7
+
+ +
+
+ +

◆ kPanasonicAcFanDelta

+ +
+
+ + + + +
const uint8_t kPanasonicAcFanDelta = 3
+
+ +
+
+ +

◆ kPanasonicAcFanMax

+ +
+
+ + + + +
const uint8_t kPanasonicAcFanMax = 4
+
+ +
+
+ +

◆ kPanasonicAcFanMed

+ +
+
+ + + + +
const uint8_t kPanasonicAcFanMed = 2
+
+ +
+
+ +

◆ kPanasonicAcFanMin

+ +
+
+ + + + +
const uint8_t kPanasonicAcFanMin = 0
+
+ +
+
+ +

◆ kPanasonicAcFanModeTemp

+ +
+
+ + + + +
const uint8_t kPanasonicAcFanModeTemp = 27
+
+ +
+
+ +

◆ kPanasonicAcHeat

+ +
+
+ + + + +
const uint8_t kPanasonicAcHeat = 4
+
+ +
+
+ +

◆ kPanasonicAcIonFilterByte

+ +
+
+ + + + +
const uint8_t kPanasonicAcIonFilterByte = 22
+
+ +
+
+ +

◆ kPanasonicAcIonFilterOffset

+ +
+
+ + + + +
const uint8_t kPanasonicAcIonFilterOffset = 0
+
+ +
+
+ +

◆ kPanasonicAcMaxTemp

+ +
+
+ + + + +
const uint8_t kPanasonicAcMaxTemp = 30
+
+ +
+
+ +

◆ kPanasonicAcMinTemp

+ +
+
+ + + + +
const uint8_t kPanasonicAcMinTemp = 16
+
+ +
+
+ +

◆ kPanasonicAcOffTimerOffset

+ +
+
+ + + + +
const uint8_t kPanasonicAcOffTimerOffset = 2
+
+ +
+
+ +

◆ kPanasonicAcOnTimerOffset

+ +
+
+ + + + +
const uint8_t kPanasonicAcOnTimerOffset = 1
+
+ +
+
+ +

◆ kPanasonicAcPowerfulCkpOffset

+ +
+
+ + + + +
const uint8_t kPanasonicAcPowerfulCkpOffset = kPanasonicAcQuietOffset
+
+ +
+
+ +

◆ kPanasonicAcPowerfulOffset

+ +
+
+ + + + +
const uint8_t kPanasonicAcPowerfulOffset = 5
+
+ +
+
+ +

◆ kPanasonicAcPowerOffset

+ +
+
+ + + + +
const uint8_t kPanasonicAcPowerOffset = 0
+
+ +
+
+ +

◆ kPanasonicAcQuietCkpOffset

+ +
+
+ + + + +
const uint8_t kPanasonicAcQuietCkpOffset = kPanasonicAcPowerfulOffset
+
+ +
+
+ +

◆ kPanasonicAcQuietOffset

+ +
+
+ + + + +
const uint8_t kPanasonicAcQuietOffset = 0
+
+ +
+
+ +

◆ kPanasonicAcSwingHAuto

+ +
+
+ + + + +
const uint8_t kPanasonicAcSwingHAuto = 0xD
+
+ +
+
+ +

◆ kPanasonicAcSwingHFullLeft

+ +
+
+ + + + +
const uint8_t kPanasonicAcSwingHFullLeft = 0x9
+
+ +
+
+ +

◆ kPanasonicAcSwingHFullRight

+ +
+
+ + + + +
const uint8_t kPanasonicAcSwingHFullRight = 0xC
+
+ +
+
+ +

◆ kPanasonicAcSwingHLeft

+ +
+
+ + + + +
const uint8_t kPanasonicAcSwingHLeft = 0xA
+
+ +
+
+ +

◆ kPanasonicAcSwingHMiddle

+ +
+
+ + + + +
const uint8_t kPanasonicAcSwingHMiddle = 0x6
+
+ +
+
+ +

◆ kPanasonicAcSwingHRight

+ +
+
+ + + + +
const uint8_t kPanasonicAcSwingHRight = 0xB
+
+ +
+
+ +

◆ kPanasonicAcSwingVAuto

+ +
+
+ + + + +
const uint8_t kPanasonicAcSwingVAuto = 0xF
+
+ +
+
+ +

◆ kPanasonicAcSwingVHigh

+ +
+
+ + + + +
const uint8_t kPanasonicAcSwingVHigh = 0x2
+
+ +
+
+ +

◆ kPanasonicAcSwingVHighest

+ +
+
+ + + + +
const uint8_t kPanasonicAcSwingVHighest = 0x1
+
+ +
+
+ +

◆ kPanasonicAcSwingVLow

+ +
+
+ + + + +
const uint8_t kPanasonicAcSwingVLow = 0x4
+
+ +
+
+ +

◆ kPanasonicAcSwingVLowest

+ +
+
+ + + + +
const uint8_t kPanasonicAcSwingVLowest = 0x5
+
+ +
+
+ +

◆ kPanasonicAcSwingVMiddle

+ +
+
+ + + + +
const uint8_t kPanasonicAcSwingVMiddle = 0x3
+
+ +
+
+ +

◆ kPanasonicAcTempOffset

+ +
+
+ + + + +
const uint8_t kPanasonicAcTempOffset = 1
+
+ +
+
+ +

◆ kPanasonicAcTempSize

+ +
+
+ + + + +
const uint8_t kPanasonicAcTempSize = 5
+
+ +
+
+ +

◆ kPanasonicAcTimeMax

+ +
+
+ + + + +
const uint16_t kPanasonicAcTimeMax = 23 * 60 + 59
+
+ +
+
+ +

◆ kPanasonicAcTimeOverflowSize

+ +
+
+ + + + +
const uint8_t kPanasonicAcTimeOverflowSize = 3
+
+ +
+
+ +

◆ kPanasonicAcTimeSize

+ +
+
+ + + + +
const uint8_t kPanasonicAcTimeSize = 11
+
+ +
+
+ +

◆ kPanasonicAcTimeSpecial

+ +
+
+ + + + +
const uint16_t kPanasonicAcTimeSpecial = 0x600
+
+ +
+
+ +

◆ kPanasonicAcTolerance

+ +
+
+ + + + +
const uint16_t kPanasonicAcTolerance = 40
+
+ +
+
+ +

◆ kPanasonicFreq

+ +
+
+ + + + +
const uint16_t kPanasonicFreq = 36700
+
+ +
+
+ +

◆ kPanasonicKnownGoodState

+ +
+
+ + + + +
const uint8_t kPanasonicKnownGoodState[kPanasonicAcStateLength]
+
+Initial value:
= {
+
0x02, 0x20, 0xE0, 0x04, 0x00, 0x00, 0x00, 0x06, 0x02,
+
0x20, 0xE0, 0x04, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+
0x00, 0x0E, 0xE0, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00}
+
+
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Panasonic_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Panasonic_8h_source.html new file mode 100644 index 000000000..5e233c8dc --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Panasonic_8h_source.html @@ -0,0 +1,368 @@ + + + + + + + +IRremoteESP8266: src/ir_Panasonic.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Panasonic.h
+
+
+Go to the documentation of this file.
1 // Copyright 2018 David Conran
+
2 
+
6 
+
7 // Supports:
+
8 // Brand: Panasonic, Model: TV (PANASONIC)
+
9 // Brand: Panasonic, Model: NKE series A/C (PANASONIC_AC NKE/2)
+
10 // Brand: Panasonic, Model: DKE series A/C (PANASONIC_AC DKE/3)
+
11 // Brand: Panasonic, Model: DKW series A/C (PANASONIC_AC DKE/3)
+
12 // Brand: Panasonic, Model: PKR series A/C (PANASONIC_AC DKE/3)
+
13 // Brand: Panasonic, Model: JKE series A/C (PANASONIC_AC JKE/4)
+
14 // Brand: Panasonic, Model: CKP series A/C (PANASONIC_AC CKP/5)
+
15 // Brand: Panasonic, Model: RKR series A/C (PANASONIC_AC RKR/6)
+
16 // Brand: Panasonic, Model: CS-ME10CKPG A/C (PANASONIC_AC CKP/5)
+
17 // Brand: Panasonic, Model: CS-ME12CKPG A/C (PANASONIC_AC CKP/5)
+
18 // Brand: Panasonic, Model: CS-ME14CKPG A/C (PANASONIC_AC CKP/5)
+
19 // Brand: Panasonic, Model: CS-E7PKR A/C (PANASONIC_AC DKE/2)
+
20 // Brand: Panasonic, Model: CS-Z9RKR A/C (PANASONIC_AC RKR/6)
+
21 // Brand: Panasonic, Model: CS-YW9MKD A/C (PANASONIC_AC JKE/4)
+
22 // Brand: Panasonic, Model: A75C2311 remote (PANASONIC_AC CKP/5)
+
23 // Brand: Panasonic, Model: A75C2616-1 remote (PANASONIC_AC DKE/3)
+
24 // Brand: Panasonic, Model: A75C3704 remote (PANASONIC_AC DKE/3)
+
25 // Brand: Panasonic, Model: A75C3747 remote (PANASONIC_AC JKE/4)
+
26 
+
27 #ifndef IR_PANASONIC_H_
+
28 #define IR_PANASONIC_H_
+
29 
+
30 #define __STDC_LIMIT_MACROS
+
31 #include <stdint.h>
+
32 #ifdef ARDUINO
+
33 #include <Arduino.h>
+
34 #endif
+
35 #include "IRremoteESP8266.h"
+
36 #include "IRsend.h"
+
37 #ifdef UNIT_TEST
+
38 #include "IRsend_test.h"
+
39 #endif
+
40 
+
41 // Constants
+
42 const uint16_t kPanasonicFreq = 36700;
+
43 const uint16_t kPanasonicAcExcess = 0;
+
44 // Much higher than usual. See issue #540.
+
45 const uint16_t kPanasonicAcTolerance = 40;
+
46 
+
47 const uint8_t kPanasonicAcAuto = 0; // 0b000
+
48 const uint8_t kPanasonicAcDry = 2; // 0b010
+
49 const uint8_t kPanasonicAcCool = 3; // 0b011
+
50 const uint8_t kPanasonicAcHeat = 4; // 0b010
+
51 const uint8_t kPanasonicAcFan = 6; // 0b110
+
52 const uint8_t kPanasonicAcFanMin = 0;
+
53 const uint8_t kPanasonicAcFanMed = 2;
+
54 const uint8_t kPanasonicAcFanMax = 4;
+
55 const uint8_t kPanasonicAcFanAuto = 7;
+
56 const uint8_t kPanasonicAcFanDelta = 3;
+
57 const uint8_t kPanasonicAcPowerOffset = 0;
+
58 const uint8_t kPanasonicAcTempOffset = 1; // Bits
+
59 const uint8_t kPanasonicAcTempSize = 5; // Bits
+
60 const uint8_t kPanasonicAcMinTemp = 16; // Celsius
+
61 const uint8_t kPanasonicAcMaxTemp = 30; // Celsius
+
62 const uint8_t kPanasonicAcFanModeTemp = 27; // Celsius
+
63 const uint8_t kPanasonicAcQuietOffset = 0;
+
64 const uint8_t kPanasonicAcPowerfulOffset = 5; // 0b100000
+
65 // CKP & RKR models have Powerful and Quiet bits swapped.
+ + +
68 const uint8_t kPanasonicAcSwingVHighest = 0x1; // 0b0001
+
69 const uint8_t kPanasonicAcSwingVHigh = 0x2; // 0b0010
+
70 const uint8_t kPanasonicAcSwingVMiddle = 0x3; // 0b0011
+
71 const uint8_t kPanasonicAcSwingVLow = 0x4; // 0b0100
+
72 const uint8_t kPanasonicAcSwingVLowest = 0x5; // 0b0101
+
73 const uint8_t kPanasonicAcSwingVAuto = 0xF; // 0b1111
+
74 
+
75 const uint8_t kPanasonicAcSwingHMiddle = 0x6; // 0b0110
+
76 const uint8_t kPanasonicAcSwingHFullLeft = 0x9; // 0b1001
+
77 const uint8_t kPanasonicAcSwingHLeft = 0xA; // 0b1010
+
78 const uint8_t kPanasonicAcSwingHRight = 0xB; // 0b1011
+
79 const uint8_t kPanasonicAcSwingHFullRight = 0xC; // 0b1100
+
80 const uint8_t kPanasonicAcSwingHAuto = 0xD; // 0b1101
+
81 const uint8_t kPanasonicAcChecksumInit = 0xF4;
+
82 const uint8_t kPanasonicAcOnTimerOffset = 1;
+
83 const uint8_t kPanasonicAcOffTimerOffset = 2;
+
84 const uint8_t kPanasonicAcTimeSize = 11; // Bits
+
85 const uint8_t kPanasonicAcTimeOverflowSize = 3; // Bits
+
86 const uint16_t kPanasonicAcTimeMax = 23 * 60 + 59; // Mins since midnight.
+
87 const uint16_t kPanasonicAcTimeSpecial = 0x600;
+
88 
+
89 const uint8_t kPanasonicAcIonFilterByte = 22; // Byte
+
90 const uint8_t kPanasonicAcIonFilterOffset = 0; // Bit
+
91 
+ +
93  0x02, 0x20, 0xE0, 0x04, 0x00, 0x00, 0x00, 0x06, 0x02,
+
94  0x20, 0xE0, 0x04, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+
95  0x00, 0x0E, 0xE0, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00};
+
96 
+ +
99  public:
+
100  explicit IRPanasonicAc(const uint16_t pin, const bool inverted = false,
+
101  const bool use_modulation = true);
+
102  void stateReset(void);
+
103 #if SEND_PANASONIC
+
104  void send(const uint16_t repeat = kPanasonicAcDefaultRepeat);
+
109  int8_t calibrate(void) { return _irsend.calibrate(); }
+
110 #endif // SEND_PANASONIC
+
111  void begin(void);
+
112  void on(void);
+
113  void off(void);
+
114  void setPower(const bool on);
+
115  bool getPower(void);
+
116  void setTemp(const uint8_t temp, const bool remember = true);
+
117  uint8_t getTemp(void);
+
118  void setFan(const uint8_t fan);
+
119  uint8_t getFan(void);
+
120  void setMode(const uint8_t mode);
+
121  uint8_t getMode(void);
+
122  void setRaw(const uint8_t state[]);
+
123  uint8_t *getRaw(void);
+
124  static bool validChecksum(const uint8_t *state,
+
125  const uint16_t length = kPanasonicAcStateLength);
+
126  static uint8_t calcChecksum(const uint8_t *state,
+
127  const uint16_t length = kPanasonicAcStateLength);
+
128  void setQuiet(const bool on);
+
129  bool getQuiet(void);
+
130  void setPowerful(const bool on);
+
131  bool getPowerful(void);
+
132  void setIon(const bool on);
+
133  bool getIon(void);
+
134  void setModel(const panasonic_ac_remote_model_t model);
+ +
136  void setSwingVertical(const uint8_t elevation);
+
137  uint8_t getSwingVertical(void);
+
138  void setSwingHorizontal(const uint8_t direction);
+
139  uint8_t getSwingHorizontal(void);
+
140  static uint16_t encodeTime(const uint8_t hours, const uint8_t mins);
+
141  uint16_t getClock(void);
+
142  void setClock(const uint16_t mins_since_midnight);
+
143  uint16_t getOnTimer(void);
+
144  void setOnTimer(const uint16_t mins_since_midnight, const bool enable = true);
+
145  void cancelOnTimer(void);
+
146  bool isOnTimerEnabled(void);
+
147  uint16_t getOffTimer(void);
+
148  void setOffTimer(const uint16_t mins_since_midnight,
+
149  const bool enable = true);
+
150  void cancelOffTimer(void);
+
151  bool isOffTimerEnabled(void);
+
152  static uint8_t convertMode(const stdAc::opmode_t mode);
+
153  static uint8_t convertFan(const stdAc::fanspeed_t speed);
+
154  static uint8_t convertSwingV(const stdAc::swingv_t position);
+
155  static uint8_t convertSwingH(const stdAc::swingh_t position);
+
156  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
157  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
158  static stdAc::swingv_t toCommonSwingV(const uint8_t pos);
+
159  static stdAc::swingh_t toCommonSwingH(const uint8_t pos);
+
160  stdAc::state_t toCommon(void);
+
161  String toString(void);
+
162 #ifndef UNIT_TEST
+
163 
+
164  private:
+ +
166 #else // UNIT_TEST
+
167  IRsendTest _irsend;
+
169 #endif // UNIT_TEST
+ +
172  uint8_t _swingh;
+
173  uint8_t _temp;
+
174  void fixChecksum(const uint16_t length = kPanasonicAcStateLength);
+
175  static uint16_t _getTime(const uint8_t ptr[]);
+
176  static void _setTime(uint8_t * const ptr, const uint16_t mins_since_midnight,
+
177  const bool round_down);
+
178 };
+
179 
+
180 #endif // IR_PANASONIC_H_
+
+
const uint8_t kPanasonicAcFanAuto
Definition: ir_Panasonic.h:55
+
static uint16_t _getTime(const uint8_t ptr[])
Get the time from a given pointer location.
Definition: ir_Panasonic.cpp:540
+
Class for handling detailed Panasonic A/C messages.
Definition: ir_Panasonic.h:98
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Panasonic.cpp:385
+
const uint8_t kPanasonicAcIonFilterOffset
Definition: ir_Panasonic.h:90
+
const uint8_t kPanasonicAcAuto
Definition: ir_Panasonic.h:47
+
const uint8_t kPanasonicAcTimeSize
Definition: ir_Panasonic.h:84
+
void setRaw(const uint8_t state[])
Set the internal state from a valid code for this protocol.
Definition: ir_Panasonic.cpp:322
+
const uint8_t kPanasonicAcSwingHRight
Definition: ir_Panasonic.h:78
+
swingv_t
Common A/C settings for Vertical Swing.
Definition: IRsend.h:70
+
const uint8_t kPanasonicAcFanMin
Definition: ir_Panasonic.h:52
+
uint16_t getOffTimer(void)
Get the Off Timer time value.
Definition: ir_Panasonic.cpp:601
+
const uint8_t kPanasonicAcQuietOffset
Definition: ir_Panasonic.h:63
+
const uint8_t kPanasonicAcOffTimerOffset
Definition: ir_Panasonic.h:83
+
const uint16_t kPanasonicAcTolerance
Definition: ir_Panasonic.h:45
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
const uint16_t kPanasonicAcExcess
Definition: ir_Panasonic.h:43
+
uint8_t _swingh
Definition: ir_Panasonic.h:172
+
static uint8_t convertSwingV(const stdAc::swingv_t position)
Convert a standard A/C vertical swing into its native setting.
Definition: ir_Panasonic.cpp:684
+
const uint8_t kPanasonicAcPowerfulOffset
Definition: ir_Panasonic.h:64
+
static uint16_t encodeTime(const uint8_t hours, const uint8_t mins)
Convert standard (military/24hr) time to nr. of minutes since midnight.
Definition: ir_Panasonic.cpp:532
+
const uint8_t kPanasonicAcTimeOverflowSize
Definition: ir_Panasonic.h:85
+
const uint8_t kPanasonicAcFanMed
Definition: ir_Panasonic.h:53
+ +
void setFan(const uint8_t fan)
Set the speed of the fan.
Definition: ir_Panasonic.cpp:457
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Panasonic.cpp:472
+
void setQuiet(const bool on)
Set the Quiet setting of the A/C.
Definition: ir_Panasonic.cpp:491
+
uint8_t _temp
Definition: ir_Panasonic.h:173
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
void setSwingVertical(const uint8_t elevation)
Control the vertical swing setting.
Definition: ir_Panasonic.cpp:411
+
std::string String
Definition: IRremoteESP8266.h:1093
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Panasonic.cpp:725
+
void setIon(const bool on)
Set the Ion (filter) setting of the A/C.
Definition: ir_Panasonic.cpp:648
+
const uint8_t kPanasonicAcPowerfulCkpOffset
Definition: ir_Panasonic.h:67
+
const uint8_t kPanasonicAcSwingHAuto
Definition: ir_Panasonic.h:80
+
const uint8_t kPanasonicAcMinTemp
Definition: ir_Panasonic.h:60
+
const uint8_t kPanasonicAcPowerOffset
Definition: ir_Panasonic.h:57
+
const uint8_t kPanasonicAcHeat
Definition: ir_Panasonic.h:50
+
void send(const uint16_t repeat=kPanasonicAcDefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Panasonic.cpp:239
+
uint16_t getClock(void)
Get the current clock time value.
Definition: ir_Panasonic.cpp:550
+
bool getPower(void)
Get the A/C power state of the remote.
Definition: ir_Panasonic.cpp:344
+
bool getQuiet(void)
Get the Quiet setting of the A/C.
Definition: ir_Panasonic.cpp:479
+
panasonic_ac_remote_model_t
Panasonic A/C model numbers.
Definition: IRsend.h:141
+ +
swingh_t
Common A/C settings for Horizontal Swing.
Definition: IRsend.h:83
+
void setOffTimer(const uint16_t mins_since_midnight, const bool enable=true)
Set/Enable the Off Timer.
Definition: ir_Panasonic.cpp:611
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Panasonic.cpp:762
+
static uint8_t calcChecksum(const uint8_t *state, const uint16_t length=kPanasonicAcStateLength)
Calculate the checksum for a given state.
Definition: ir_Panasonic.cpp:225
+
static uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Panasonic.cpp:657
+
const uint8_t kPanasonicAcChecksumInit
Definition: ir_Panasonic.h:81
+
static void _setTime(uint8_t *const ptr, const uint16_t mins_since_midnight, const bool round_down)
Set the time at a given pointer location.
Definition: ir_Panasonic.cpp:557
+
uint8_t getSwingVertical(void)
Get the current vertical swing setting.
Definition: ir_Panasonic.cpp:405
+
const uint16_t kPanasonicAcDefaultRepeat
Definition: IRremoteESP8266.h:958
+
const uint8_t kPanasonicAcSwingHFullRight
Definition: ir_Panasonic.h:79
+
const uint8_t kPanasonicAcSwingHLeft
Definition: ir_Panasonic.h:77
+
bool getPowerful(void)
Get the Powerful (Turbo) setting of the A/C.
Definition: ir_Panasonic.cpp:504
+
void setSwingHorizontal(const uint8_t direction)
Control the horizontal swing setting.
Definition: ir_Panasonic.cpp:428
+
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_Panasonic.cpp:315
+
const uint16_t kPanasonicAcStateLength
Definition: IRremoteESP8266.h:954
+
const uint8_t kPanasonicAcSwingHMiddle
Definition: ir_Panasonic.h:75
+
const uint8_t kPanasonicAcCool
Definition: ir_Panasonic.h:49
+
const uint16_t kPanasonicFreq
Definition: ir_Panasonic.h:42
+
static stdAc::swingh_t toCommonSwingH(const uint8_t pos)
Convert a native horizontal swing postion to it's common equivalent.
Definition: ir_Panasonic.cpp:739
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Panasonic.h:165
+
void setOnTimer(const uint16_t mins_since_midnight, const bool enable=true)
Set/Enable the On Timer.
Definition: ir_Panasonic.cpp:582
+
void on(void)
Change the power setting to On.
Definition: ir_Panasonic.cpp:349
+
IRPanasonicAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Panasonic.cpp:197
+
String toString(void)
Convert the internal state into a human readable string.
Definition: ir_Panasonic.cpp:788
+
const uint8_t kPanasonicAcQuietCkpOffset
Definition: ir_Panasonic.h:66
+
const uint8_t kPanasonicKnownGoodState[kPanasonicAcStateLength]
Definition: ir_Panasonic.h:92
+
const uint8_t kPanasonicAcSwingVAuto
Definition: ir_Panasonic.h:73
+
const uint8_t kPanasonicAcSwingVHigh
Definition: ir_Panasonic.h:69
+
bool isOnTimerEnabled(void)
Check if the On Timer is Enabled.
Definition: ir_Panasonic.cpp:595
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Panasonic.cpp:209
+
void fixChecksum(const uint16_t length=kPanasonicAcStateLength)
Calculate and set the checksum values for the internal state.
Definition: ir_Panasonic.cpp:232
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Panasonic.h:109
+
void setPower(const bool on)
Control the power state of the A/C unit.
Definition: ir_Panasonic.cpp:336
+
const uint8_t kPanasonicAcTempOffset
Definition: ir_Panasonic.h:58
+
void setClock(const uint16_t mins_since_midnight)
Set the current clock time value.
Definition: ir_Panasonic.cpp:571
+
const uint16_t kPanasonicAcTimeSpecial
Definition: ir_Panasonic.h:87
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Panasonic.cpp:362
+
const uint8_t kPanasonicAcSwingVLow
Definition: ir_Panasonic.h:71
+
void cancelOnTimer(void)
Cancel the On Timer.
Definition: ir_Panasonic.cpp:591
+
uint8_t getSwingHorizontal(void)
Get the current horizontal swing setting.
Definition: ir_Panasonic.cpp:422
+
const uint8_t kPanasonicAcFan
Definition: ir_Panasonic.h:51
+
void off(void)
Change the power setting to Off.
Definition: ir_Panasonic.cpp:352
+
const uint8_t kPanasonicAcDry
Definition: ir_Panasonic.h:48
+
uint8_t remote_state[kPanasonicAcStateLength]
The state in code form.
Definition: ir_Panasonic.h:171
+
void cancelOffTimer(void)
Cancel the Off Timer.
Definition: ir_Panasonic.cpp:626
+
const uint8_t kPanasonicAcIonFilterByte
Definition: ir_Panasonic.h:89
+
static uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Panasonic.cpp:670
+
const uint8_t kPanasonicAcSwingVMiddle
Definition: ir_Panasonic.h:70
+
static bool validChecksum(const uint8_t *state, const uint16_t length=kPanasonicAcStateLength)
Verify the checksum is valid for a given state.
Definition: ir_Panasonic.cpp:215
+
const uint8_t kPanasonicAcFanDelta
Definition: ir_Panasonic.h:56
+
const uint8_t kPanasonicAcSwingVHighest
Definition: ir_Panasonic.h:68
+
void stateReset(void)
Reset the state of the remote to a known good state/sequence.
Definition: ir_Panasonic.cpp:202
+
const uint8_t kPanasonicAcTempSize
Definition: ir_Panasonic.h:59
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Panasonic.cpp:356
+
void setPowerful(const bool on)
Set the Powerful (Turbo) setting of the A/C.
Definition: ir_Panasonic.cpp:516
+
const uint8_t kPanasonicAcFanModeTemp
Definition: ir_Panasonic.h:62
+
const uint8_t kPanasonicAcFanMax
Definition: ir_Panasonic.h:54
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Panasonic.cpp:712
+
bool isOffTimerEnabled(void)
Check if the Off Timer is Enabled.
Definition: ir_Panasonic.cpp:630
+
const uint16_t kPanasonicAcTimeMax
Definition: ir_Panasonic.h:86
+
const uint8_t kPanasonicAcSwingHFullLeft
Definition: ir_Panasonic.h:76
+
panasonic_ac_remote_model_t getModel(void)
Get/Detect the model of the A/C.
Definition: ir_Panasonic.cpp:296
+
bool getIon(void)
Get the Ion (filter) setting of the A/C.
Definition: ir_Panasonic.cpp:636
+
uint16_t getOnTimer(void)
Get the On Timer time value.
Definition: ir_Panasonic.cpp:577
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
void setModel(const panasonic_ac_remote_model_t model)
Set the model of the A/C to emulate.
Definition: ir_Panasonic.cpp:246
+
const uint8_t kPanasonicAcMaxTemp
Definition: ir_Panasonic.h:61
+
static uint8_t convertSwingH(const stdAc::swingh_t position)
Convert a standard A/C horizontal swing into its native setting.
Definition: ir_Panasonic.cpp:698
+
void setTemp(const uint8_t temp, const bool remember=true)
Set the temperature.
Definition: ir_Panasonic.cpp:394
+
const uint8_t kPanasonicAcSwingVLowest
Definition: ir_Panasonic.h:72
+
const uint8_t kPanasonicAcOnTimerOffset
Definition: ir_Panasonic.h:82
+
static stdAc::swingv_t toCommonSwingV(const uint8_t pos)
Convert a native vertical swing postion to it's common equivalent.
Definition: ir_Panasonic.cpp:753
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Pioneer_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Pioneer_8cpp.html new file mode 100644 index 000000000..bd39de11e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Pioneer_8cpp.html @@ -0,0 +1,341 @@ + + + + + + + +IRremoteESP8266: src/ir_Pioneer.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Pioneer.cpp File Reference
+
+
+ +

Pioneer remote emulation. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kPioneerTick = 534
 
const uint16_t kPioneerHdrMarkTicks = 16
 
const uint16_t kPioneerHdrMark = kPioneerHdrMarkTicks * kPioneerTick
 
const uint16_t kPioneerHdrSpaceTicks = 8
 
const uint16_t kPioneerHdrSpace = kPioneerHdrSpaceTicks * kPioneerTick
 
const uint16_t kPioneerBitMarkTicks = 1
 
const uint16_t kPioneerBitMark = kPioneerBitMarkTicks * kPioneerTick
 
const uint16_t kPioneerOneSpaceTicks = 3
 
const uint16_t kPioneerOneSpace = kPioneerOneSpaceTicks * kPioneerTick
 
const uint16_t kPioneerZeroSpaceTicks = 1
 
const uint16_t kPioneerZeroSpace = kPioneerZeroSpaceTicks * kPioneerTick
 
const uint16_t kPioneerMinCommandLengthTicks = 159
 
const uint32_t kPioneerMinCommandLength
 
const uint16_t kPioneerMinGapTicks = 47
 
const uint32_t kPioneerMinGap = kPioneerMinGapTicks * kPioneerTick
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kPioneerBitMark

+ +
+
+ + + + +
const uint16_t kPioneerBitMark = kPioneerBitMarkTicks * kPioneerTick
+
+ +
+
+ +

◆ kPioneerBitMarkTicks

+ +
+
+ + + + +
const uint16_t kPioneerBitMarkTicks = 1
+
+ +
+
+ +

◆ kPioneerHdrMark

+ +
+
+ + + + +
const uint16_t kPioneerHdrMark = kPioneerHdrMarkTicks * kPioneerTick
+
+ +
+
+ +

◆ kPioneerHdrMarkTicks

+ +
+
+ + + + +
const uint16_t kPioneerHdrMarkTicks = 16
+
+ +
+
+ +

◆ kPioneerHdrSpace

+ +
+
+ + + + +
const uint16_t kPioneerHdrSpace = kPioneerHdrSpaceTicks * kPioneerTick
+
+ +
+
+ +

◆ kPioneerHdrSpaceTicks

+ +
+
+ + + + +
const uint16_t kPioneerHdrSpaceTicks = 8
+
+ +
+
+ +

◆ kPioneerMinCommandLength

+ +
+
+ + + + +
const uint32_t kPioneerMinCommandLength
+
+
+ +

◆ kPioneerMinCommandLengthTicks

+ +
+
+ + + + +
const uint16_t kPioneerMinCommandLengthTicks = 159
+
+ +
+
+ +

◆ kPioneerMinGap

+ +
+
+ + + + +
const uint32_t kPioneerMinGap = kPioneerMinGapTicks * kPioneerTick
+
+ +
+
+ +

◆ kPioneerMinGapTicks

+ +
+
+ + + + +
const uint16_t kPioneerMinGapTicks = 47
+
+ +
+
+ +

◆ kPioneerOneSpace

+ +
+
+ + + + +
const uint16_t kPioneerOneSpace = kPioneerOneSpaceTicks * kPioneerTick
+
+ +
+
+ +

◆ kPioneerOneSpaceTicks

+ +
+
+ + + + +
const uint16_t kPioneerOneSpaceTicks = 3
+
+ +
+
+ +

◆ kPioneerTick

+ +
+
+ + + + +
const uint16_t kPioneerTick = 534
+
+ +
+
+ +

◆ kPioneerZeroSpace

+ +
+
+ + + + +
const uint16_t kPioneerZeroSpace = kPioneerZeroSpaceTicks * kPioneerTick
+
+ +
+
+ +

◆ kPioneerZeroSpaceTicks

+ +
+
+ + + + +
const uint16_t kPioneerZeroSpaceTicks = 1
+
+ +
+
+
+
const uint16_t kPioneerMinCommandLengthTicks
Definition: ir_Pioneer.cpp:34
+
const uint16_t kPioneerTick
Definition: ir_Pioneer.cpp:23
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Pronto_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Pronto_8cpp.html new file mode 100644 index 000000000..e962543bf --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Pronto_8cpp.html @@ -0,0 +1,195 @@ + + + + + + + +IRremoteESP8266: src/ir_Pronto.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Pronto.cpp File Reference
+
+
+ +

Pronto code message generation. +More...

+ + + + + + + + + + + + + + +

+Variables

const float kProntoFreqFactor = 0.241246
 
const uint16_t kProntoTypeOffset = 0
 
const uint16_t kProntoFreqOffset = 1
 
const uint16_t kProntoSeq1LenOffset = 2
 
const uint16_t kProntoSeq2LenOffset = 3
 
const uint16_t kProntoDataOffset = 4
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kProntoDataOffset

+ +
+
+ + + + +
const uint16_t kProntoDataOffset = 4
+
+ +
+
+ +

◆ kProntoFreqFactor

+ +
+
+ + + + +
const float kProntoFreqFactor = 0.241246
+
+ +
+
+ +

◆ kProntoFreqOffset

+ +
+
+ + + + +
const uint16_t kProntoFreqOffset = 1
+
+ +
+
+ +

◆ kProntoSeq1LenOffset

+ +
+
+ + + + +
const uint16_t kProntoSeq1LenOffset = 2
+
+ +
+
+ +

◆ kProntoSeq2LenOffset

+ +
+
+ + + + +
const uint16_t kProntoSeq2LenOffset = 3
+
+ +
+
+ +

◆ kProntoTypeOffset

+ +
+
+ + + + +
const uint16_t kProntoTypeOffset = 0
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__RC5__RC6_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__RC5__RC6_8cpp.html new file mode 100644 index 000000000..0a479e434 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__RC5__RC6_8cpp.html @@ -0,0 +1,361 @@ + + + + + + + +IRremoteESP8266: src/ir_RC5_RC6.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_RC5_RC6.cpp File Reference
+
+
+ +

RC-5 & RC-6 support RC-5 & RC-6 support added from https://github.com/z3t0/Arduino-IRremote RC-5X support added by David Conran. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kRc5T1 = 889
 
const uint32_t kRc5MinCommandLength = 113778
 
const uint32_t kRc5MinGap = kRc5MinCommandLength - kRC5RawBits * (2 * kRc5T1)
 
const uint16_t kRc5ToggleMask = 0x800
 
const uint16_t kRc5SamplesMin = 11
 
const uint16_t kRc6Tick = 444
 
const uint16_t kRc6HdrMarkTicks = 6
 
const uint16_t kRc6HdrMark = kRc6HdrMarkTicks * kRc6Tick
 
const uint16_t kRc6HdrSpaceTicks = 2
 
const uint16_t kRc6HdrSpace = kRc6HdrSpaceTicks * kRc6Tick
 
const uint16_t kRc6RptLengthTicks = 187
 
const uint32_t kRc6RptLength = kRc6RptLengthTicks * kRc6Tick
 
const uint32_t kRc6ToggleMask = 0x10000UL
 
const uint16_t kRc6_36ToggleMask = 0x8000
 
const int16_t kMark = 0
 
const int16_t kSpace = 1
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kMark

+ +
+
+ + + + +
const int16_t kMark = 0
+
+ +
+
+ +

◆ kRc5MinCommandLength

+ +
+
+ + + + +
const uint32_t kRc5MinCommandLength = 113778
+
+ +
+
+ +

◆ kRc5MinGap

+ +
+
+ + + + +
const uint32_t kRc5MinGap = kRc5MinCommandLength - kRC5RawBits * (2 * kRc5T1)
+
+ +
+
+ +

◆ kRc5SamplesMin

+ +
+
+ + + + +
const uint16_t kRc5SamplesMin = 11
+
+ +
+
+ +

◆ kRc5T1

+ +
+
+ + + + +
const uint16_t kRc5T1 = 889
+
+ +
+
+ +

◆ kRc5ToggleMask

+ +
+
+ + + + +
const uint16_t kRc5ToggleMask = 0x800
+
+ +
+
+ +

◆ kRc6_36ToggleMask

+ +
+
+ + + + +
const uint16_t kRc6_36ToggleMask = 0x8000
+
+ +
+
+ +

◆ kRc6HdrMark

+ +
+
+ + + + +
const uint16_t kRc6HdrMark = kRc6HdrMarkTicks * kRc6Tick
+
+ +
+
+ +

◆ kRc6HdrMarkTicks

+ +
+
+ + + + +
const uint16_t kRc6HdrMarkTicks = 6
+
+ +
+
+ +

◆ kRc6HdrSpace

+ +
+
+ + + + +
const uint16_t kRc6HdrSpace = kRc6HdrSpaceTicks * kRc6Tick
+
+ +
+
+ +

◆ kRc6HdrSpaceTicks

+ +
+
+ + + + +
const uint16_t kRc6HdrSpaceTicks = 2
+
+ +
+
+ +

◆ kRc6RptLength

+ +
+
+ + + + +
const uint32_t kRc6RptLength = kRc6RptLengthTicks * kRc6Tick
+
+ +
+
+ +

◆ kRc6RptLengthTicks

+ +
+
+ + + + +
const uint16_t kRc6RptLengthTicks = 187
+
+ +
+
+ +

◆ kRc6Tick

+ +
+
+ + + + +
const uint16_t kRc6Tick = 444
+
+ +
+
+ +

◆ kRc6ToggleMask

+ +
+
+ + + + +
const uint32_t kRc6ToggleMask = 0x10000UL
+
+ +
+
+ +

◆ kSpace

+ +
+
+ + + + +
const int16_t kSpace = 1
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__RCMM_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__RCMM_8cpp.html new file mode 100644 index 000000000..fcffe316b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__RCMM_8cpp.html @@ -0,0 +1,429 @@ + + + + + + + +IRremoteESP8266: src/ir_RCMM.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_RCMM.cpp File Reference
+
+
+ +

Support for the Phillips RC-MM protocol. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kRcmmTick = 28
 
const uint16_t kRcmmHdrMarkTicks = 15
 
const uint16_t kRcmmHdrMark = 416
 
const uint16_t kRcmmHdrSpaceTicks = 10
 
const uint16_t kRcmmHdrSpace = 277
 
const uint16_t kRcmmBitMarkTicks = 6
 
const uint16_t kRcmmBitMark = 166
 
const uint16_t kRcmmBitSpace0Ticks = 10
 
const uint16_t kRcmmBitSpace0 = 277
 
const uint16_t kRcmmBitSpace1Ticks = 16
 
const uint16_t kRcmmBitSpace1 = 444
 
const uint16_t kRcmmBitSpace2Ticks = 22
 
const uint16_t kRcmmBitSpace2 = 611
 
const uint16_t kRcmmBitSpace3Ticks = 28
 
const uint16_t kRcmmBitSpace3 = 777
 
const uint16_t kRcmmRptLengthTicks = 992
 
const uint32_t kRcmmRptLength = 27778
 
const uint16_t kRcmmMinGapTicks = 120
 
const uint32_t kRcmmMinGap = 3360
 
const uint8_t kRcmmTolerance = 10
 
const uint16_t kRcmmExcess = 50
 
+

Detailed Description

+

Support for the Phillips RC-MM protocol.

+
See also
http://www.sbprojects.com/knowledge/ir/rcmm.php
+

Variable Documentation

+ +

◆ kRcmmBitMark

+ +
+
+ + + + +
const uint16_t kRcmmBitMark = 166
+
+ +
+
+ +

◆ kRcmmBitMarkTicks

+ +
+
+ + + + +
const uint16_t kRcmmBitMarkTicks = 6
+
+ +
+
+ +

◆ kRcmmBitSpace0

+ +
+
+ + + + +
const uint16_t kRcmmBitSpace0 = 277
+
+ +
+
+ +

◆ kRcmmBitSpace0Ticks

+ +
+
+ + + + +
const uint16_t kRcmmBitSpace0Ticks = 10
+
+ +
+
+ +

◆ kRcmmBitSpace1

+ +
+
+ + + + +
const uint16_t kRcmmBitSpace1 = 444
+
+ +
+
+ +

◆ kRcmmBitSpace1Ticks

+ +
+
+ + + + +
const uint16_t kRcmmBitSpace1Ticks = 16
+
+ +
+
+ +

◆ kRcmmBitSpace2

+ +
+
+ + + + +
const uint16_t kRcmmBitSpace2 = 611
+
+ +
+
+ +

◆ kRcmmBitSpace2Ticks

+ +
+
+ + + + +
const uint16_t kRcmmBitSpace2Ticks = 22
+
+ +
+
+ +

◆ kRcmmBitSpace3

+ +
+
+ + + + +
const uint16_t kRcmmBitSpace3 = 777
+
+ +
+
+ +

◆ kRcmmBitSpace3Ticks

+ +
+
+ + + + +
const uint16_t kRcmmBitSpace3Ticks = 28
+
+ +
+
+ +

◆ kRcmmExcess

+ +
+
+ + + + +
const uint16_t kRcmmExcess = 50
+
+ +
+
+ +

◆ kRcmmHdrMark

+ +
+
+ + + + +
const uint16_t kRcmmHdrMark = 416
+
+ +
+
+ +

◆ kRcmmHdrMarkTicks

+ +
+
+ + + + +
const uint16_t kRcmmHdrMarkTicks = 15
+
+ +
+
+ +

◆ kRcmmHdrSpace

+ +
+
+ + + + +
const uint16_t kRcmmHdrSpace = 277
+
+ +
+
+ +

◆ kRcmmHdrSpaceTicks

+ +
+
+ + + + +
const uint16_t kRcmmHdrSpaceTicks = 10
+
+ +
+
+ +

◆ kRcmmMinGap

+ +
+
+ + + + +
const uint32_t kRcmmMinGap = 3360
+
+ +
+
+ +

◆ kRcmmMinGapTicks

+ +
+
+ + + + +
const uint16_t kRcmmMinGapTicks = 120
+
+ +
+
+ +

◆ kRcmmRptLength

+ +
+
+ + + + +
const uint32_t kRcmmRptLength = 27778
+
+ +
+
+ +

◆ kRcmmRptLengthTicks

+ +
+
+ + + + +
const uint16_t kRcmmRptLengthTicks = 992
+
+ +
+
+ +

◆ kRcmmTick

+ +
+
+ + + + +
const uint16_t kRcmmTick = 28
+
+ +
+
+ +

◆ kRcmmTolerance

+ +
+
+ + + + +
const uint8_t kRcmmTolerance = 10
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Samsung_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Samsung_8cpp.html new file mode 100644 index 000000000..c0203d881 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Samsung_8cpp.html @@ -0,0 +1,529 @@ + + + + + + + +IRremoteESP8266: src/ir_Samsung.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Samsung.cpp File Reference
+
+
+ +

Support for Samsung protocols. Samsung originally added from https://github.com/shirriff/Arduino-IRremote/. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kSamsungTick = 560
 
const uint16_t kSamsungHdrMarkTicks = 8
 
const uint16_t kSamsungHdrMark = kSamsungHdrMarkTicks * kSamsungTick
 
const uint16_t kSamsungHdrSpaceTicks = 8
 
const uint16_t kSamsungHdrSpace = kSamsungHdrSpaceTicks * kSamsungTick
 
const uint16_t kSamsungBitMarkTicks = 1
 
const uint16_t kSamsungBitMark = kSamsungBitMarkTicks * kSamsungTick
 
const uint16_t kSamsungOneSpaceTicks = 3
 
const uint16_t kSamsungOneSpace = kSamsungOneSpaceTicks * kSamsungTick
 
const uint16_t kSamsungZeroSpaceTicks = 1
 
const uint16_t kSamsungZeroSpace = kSamsungZeroSpaceTicks * kSamsungTick
 
const uint16_t kSamsungRptSpaceTicks = 4
 
const uint16_t kSamsungRptSpace = kSamsungRptSpaceTicks * kSamsungTick
 
const uint16_t kSamsungMinMessageLengthTicks = 193
 
const uint32_t kSamsungMinMessageLength
 
const uint16_t kSamsungMinGapTicks
 
const uint32_t kSamsungMinGap = kSamsungMinGapTicks * kSamsungTick
 
const uint16_t kSamsungAcHdrMark = 690
 
const uint16_t kSamsungAcHdrSpace = 17844
 
const uint8_t kSamsungAcSections = 2
 
const uint16_t kSamsungAcSectionMark = 3086
 
const uint16_t kSamsungAcSectionSpace = 8864
 
const uint16_t kSamsungAcSectionGap = 2886
 
const uint16_t kSamsungAcBitMark = 586
 
const uint16_t kSamsungAcOneSpace = 1432
 
const uint16_t kSamsungAcZeroSpace = 436
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kSamsungAcBitMark

+ +
+
+ + + + +
const uint16_t kSamsungAcBitMark = 586
+
+ +
+
+ +

◆ kSamsungAcHdrMark

+ +
+
+ + + + +
const uint16_t kSamsungAcHdrMark = 690
+
+ +
+
+ +

◆ kSamsungAcHdrSpace

+ +
+
+ + + + +
const uint16_t kSamsungAcHdrSpace = 17844
+
+ +
+
+ +

◆ kSamsungAcOneSpace

+ +
+
+ + + + +
const uint16_t kSamsungAcOneSpace = 1432
+
+ +
+
+ +

◆ kSamsungAcSectionGap

+ +
+
+ + + + +
const uint16_t kSamsungAcSectionGap = 2886
+
+ +
+
+ +

◆ kSamsungAcSectionMark

+ +
+
+ + + + +
const uint16_t kSamsungAcSectionMark = 3086
+
+ +
+
+ +

◆ kSamsungAcSections

+ +
+
+ + + + +
const uint8_t kSamsungAcSections = 2
+
+ +
+
+ +

◆ kSamsungAcSectionSpace

+ +
+
+ + + + +
const uint16_t kSamsungAcSectionSpace = 8864
+
+ +
+
+ +

◆ kSamsungAcZeroSpace

+ +
+
+ + + + +
const uint16_t kSamsungAcZeroSpace = 436
+
+ +
+
+ +

◆ kSamsungBitMark

+ +
+
+ + + + +
const uint16_t kSamsungBitMark = kSamsungBitMarkTicks * kSamsungTick
+
+ +
+
+ +

◆ kSamsungBitMarkTicks

+ +
+
+ + + + +
const uint16_t kSamsungBitMarkTicks = 1
+
+ +
+
+ +

◆ kSamsungHdrMark

+ +
+
+ + + + +
const uint16_t kSamsungHdrMark = kSamsungHdrMarkTicks * kSamsungTick
+
+ +
+
+ +

◆ kSamsungHdrMarkTicks

+ +
+
+ + + + +
const uint16_t kSamsungHdrMarkTicks = 8
+
+ +
+
+ +

◆ kSamsungHdrSpace

+ +
+
+ + + + +
const uint16_t kSamsungHdrSpace = kSamsungHdrSpaceTicks * kSamsungTick
+
+ +
+
+ +

◆ kSamsungHdrSpaceTicks

+ +
+
+ + + + +
const uint16_t kSamsungHdrSpaceTicks = 8
+
+ +
+
+ +

◆ kSamsungMinGap

+ +
+
+ + + + +
const uint32_t kSamsungMinGap = kSamsungMinGapTicks * kSamsungTick
+
+ +
+
+ +

◆ kSamsungMinGapTicks

+ +
+
+ + + + +
const uint16_t kSamsungMinGapTicks
+
+
+ +

◆ kSamsungMinMessageLength

+ +
+
+ + + + +
const uint32_t kSamsungMinMessageLength
+
+
+ +

◆ kSamsungMinMessageLengthTicks

+ +
+
+ + + + +
const uint16_t kSamsungMinMessageLengthTicks = 193
+
+ +
+
+ +

◆ kSamsungOneSpace

+ +
+
+ + + + +
const uint16_t kSamsungOneSpace = kSamsungOneSpaceTicks * kSamsungTick
+
+ +
+
+ +

◆ kSamsungOneSpaceTicks

+ +
+
+ + + + +
const uint16_t kSamsungOneSpaceTicks = 3
+
+ +
+
+ +

◆ kSamsungRptSpace

+ +
+
+ + + + +
const uint16_t kSamsungRptSpace = kSamsungRptSpaceTicks * kSamsungTick
+
+ +
+
+ +

◆ kSamsungRptSpaceTicks

+ +
+
+ + + + +
const uint16_t kSamsungRptSpaceTicks = 4
+
+ +
+
+ +

◆ kSamsungTick

+ +
+
+ + + + +
const uint16_t kSamsungTick = 560
+
+ +
+
+ +

◆ kSamsungZeroSpace

+ +
+
+ + + + +
const uint16_t kSamsungZeroSpace = kSamsungZeroSpaceTicks * kSamsungTick
+
+ +
+
+ +

◆ kSamsungZeroSpaceTicks

+ +
+
+ + + + +
const uint16_t kSamsungZeroSpaceTicks = 1
+
+ +
+
+
+
const uint16_t kSamsungMinMessageLengthTicks
Definition: ir_Samsung.cpp:36
+
const uint16_t kSamsungTick
Definition: ir_Samsung.cpp:23
+
const uint16_t kSamsungBitMarkTicks
Definition: ir_Samsung.cpp:28
+
const uint16_t kSamsungHdrMarkTicks
Definition: ir_Samsung.cpp:24
+
const uint16_t kSamsungOneSpaceTicks
Definition: ir_Samsung.cpp:30
+
const uint16_t kSamsungBits
Definition: IRremoteESP8266.h:967
+
const uint16_t kSamsungHdrSpaceTicks
Definition: ir_Samsung.cpp:26
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Samsung_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Samsung_8h.html new file mode 100644 index 000000000..09282ae84 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Samsung_8h.html @@ -0,0 +1,748 @@ + + + + + + + +IRremoteESP8266: src/ir_Samsung.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Samsung.h File Reference
+
+
+ +

Support for Samsung protocols. Samsung originally added from https://github.com/shirriff/Arduino-IRremote/. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRSamsungAc
 Class for handling detailed Samsung A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kSamsungAcPower1Offset = 5
 
const uint8_t kSamsungAcQuiet1Offset = 4
 
const uint8_t kSamsungAcQuiet5Offset = 5
 
const uint8_t kSamsungAcPower6Offset = 4
 
const uint8_t kSamsungAcPower6Size = 2
 
const uint8_t kSamsungAcPowerfulMask8 = 0b01010000
 
const uint8_t kSamsungAcSwingOffset = 4
 
const uint8_t kSamsungAcSwingSize = 3
 
const uint8_t kSamsungAcSwingMove = 0b010
 
const uint8_t kSamsungAcSwingStop = 0b111
 
const uint8_t kSamsungAcPowerful10Offset = 1
 
const uint8_t kSamsungAcPowerful10Size = 3
 
const uint8_t kSamsungAcPowerful10On = 0b011
 
const uint8_t kSamsungAcBreezeOffset = kSamsungAcPowerful10Offset
 
const uint8_t kSamsungAcBreezeSize = kSamsungAcPowerful10Size
 
const uint8_t kSamsungAcBreezeOn = 0b101
 
const uint8_t kSamsungAcDisplayOffset = 4
 
const uint8_t kSamsungAcClean10Offset = 7
 
const uint8_t kSamsungAcIonOffset = 0
 
const uint8_t kSamsungAcClean11Offset = 1
 
const uint8_t kSamsungAcMinTemp = 16
 
const uint8_t kSamsungAcMaxTemp = 30
 
const uint8_t kSamsungAcAutoTemp = 25
 
const uint8_t kSamsungAcModeOffset = 4
 
const uint8_t kSamsungAcAuto = 0
 
const uint8_t kSamsungAcCool = 1
 
const uint8_t kSamsungAcDry = 2
 
const uint8_t kSamsungAcFan = 3
 
const uint8_t kSamsungAcHeat = 4
 
const uint8_t kSamsungAcFanOffest = 1
 
const uint8_t kSamsungAcFanSize = 3
 
const uint8_t kSamsungAcFanAuto = 0
 
const uint8_t kSamsungAcFanLow = 2
 
const uint8_t kSamsungAcFanMed = 4
 
const uint8_t kSamsungAcFanHigh = 5
 
const uint8_t kSamsungAcFanAuto2 = 6
 
const uint8_t kSamsungAcFanTurbo = 7
 
const uint8_t kSamsungAcBeepOffset = 1
 
const uint16_t kSamsungAcSectionLength = 7
 
const uint64_t kSamsungAcPowerSection = 0x1D20F00000000
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kSamsungAcAuto

+ +
+
+ + + + +
const uint8_t kSamsungAcAuto = 0
+
+ +
+
+ +

◆ kSamsungAcAutoTemp

+ +
+
+ + + + +
const uint8_t kSamsungAcAutoTemp = 25
+
+ +
+
+ +

◆ kSamsungAcBeepOffset

+ +
+
+ + + + +
const uint8_t kSamsungAcBeepOffset = 1
+
+ +
+
+ +

◆ kSamsungAcBreezeOffset

+ +
+
+ + + + +
const uint8_t kSamsungAcBreezeOffset = kSamsungAcPowerful10Offset
+
+ +
+
+ +

◆ kSamsungAcBreezeOn

+ +
+
+ + + + +
const uint8_t kSamsungAcBreezeOn = 0b101
+
+ +
+
+ +

◆ kSamsungAcBreezeSize

+ +
+
+ + + + +
const uint8_t kSamsungAcBreezeSize = kSamsungAcPowerful10Size
+
+ +
+
+ +

◆ kSamsungAcClean10Offset

+ +
+
+ + + + +
const uint8_t kSamsungAcClean10Offset = 7
+
+ +
+
+ +

◆ kSamsungAcClean11Offset

+ +
+
+ + + + +
const uint8_t kSamsungAcClean11Offset = 1
+
+ +
+
+ +

◆ kSamsungAcCool

+ +
+
+ + + + +
const uint8_t kSamsungAcCool = 1
+
+ +
+
+ +

◆ kSamsungAcDisplayOffset

+ +
+
+ + + + +
const uint8_t kSamsungAcDisplayOffset = 4
+
+ +
+
+ +

◆ kSamsungAcDry

+ +
+
+ + + + +
const uint8_t kSamsungAcDry = 2
+
+ +
+
+ +

◆ kSamsungAcFan

+ +
+
+ + + + +
const uint8_t kSamsungAcFan = 3
+
+ +
+
+ +

◆ kSamsungAcFanAuto

+ +
+
+ + + + +
const uint8_t kSamsungAcFanAuto = 0
+
+ +
+
+ +

◆ kSamsungAcFanAuto2

+ +
+
+ + + + +
const uint8_t kSamsungAcFanAuto2 = 6
+
+ +
+
+ +

◆ kSamsungAcFanHigh

+ +
+
+ + + + +
const uint8_t kSamsungAcFanHigh = 5
+
+ +
+
+ +

◆ kSamsungAcFanLow

+ +
+
+ + + + +
const uint8_t kSamsungAcFanLow = 2
+
+ +
+
+ +

◆ kSamsungAcFanMed

+ +
+
+ + + + +
const uint8_t kSamsungAcFanMed = 4
+
+ +
+
+ +

◆ kSamsungAcFanOffest

+ +
+
+ + + + +
const uint8_t kSamsungAcFanOffest = 1
+
+ +
+
+ +

◆ kSamsungAcFanSize

+ +
+
+ + + + +
const uint8_t kSamsungAcFanSize = 3
+
+ +
+
+ +

◆ kSamsungAcFanTurbo

+ +
+
+ + + + +
const uint8_t kSamsungAcFanTurbo = 7
+
+ +
+
+ +

◆ kSamsungAcHeat

+ +
+
+ + + + +
const uint8_t kSamsungAcHeat = 4
+
+ +
+
+ +

◆ kSamsungAcIonOffset

+ +
+
+ + + + +
const uint8_t kSamsungAcIonOffset = 0
+
+ +
+
+ +

◆ kSamsungAcMaxTemp

+ +
+
+ + + + +
const uint8_t kSamsungAcMaxTemp = 30
+
+ +
+
+ +

◆ kSamsungAcMinTemp

+ +
+
+ + + + +
const uint8_t kSamsungAcMinTemp = 16
+
+ +
+
+ +

◆ kSamsungAcModeOffset

+ +
+
+ + + + +
const uint8_t kSamsungAcModeOffset = 4
+
+ +
+
+ +

◆ kSamsungAcPower1Offset

+ +
+
+ + + + +
const uint8_t kSamsungAcPower1Offset = 5
+
+ +
+
+ +

◆ kSamsungAcPower6Offset

+ +
+
+ + + + +
const uint8_t kSamsungAcPower6Offset = 4
+
+ +
+
+ +

◆ kSamsungAcPower6Size

+ +
+
+ + + + +
const uint8_t kSamsungAcPower6Size = 2
+
+ +
+
+ +

◆ kSamsungAcPowerful10Offset

+ +
+
+ + + + +
const uint8_t kSamsungAcPowerful10Offset = 1
+
+ +
+
+ +

◆ kSamsungAcPowerful10On

+ +
+
+ + + + +
const uint8_t kSamsungAcPowerful10On = 0b011
+
+ +
+
+ +

◆ kSamsungAcPowerful10Size

+ +
+
+ + + + +
const uint8_t kSamsungAcPowerful10Size = 3
+
+ +
+
+ +

◆ kSamsungAcPowerfulMask8

+ +
+
+ + + + +
const uint8_t kSamsungAcPowerfulMask8 = 0b01010000
+
+ +
+
+ +

◆ kSamsungAcPowerSection

+ +
+
+ + + + +
const uint64_t kSamsungAcPowerSection = 0x1D20F00000000
+
+ +
+
+ +

◆ kSamsungAcQuiet1Offset

+ +
+
+ + + + +
const uint8_t kSamsungAcQuiet1Offset = 4
+
+ +
+
+ +

◆ kSamsungAcQuiet5Offset

+ +
+
+ + + + +
const uint8_t kSamsungAcQuiet5Offset = 5
+
+ +
+
+ +

◆ kSamsungAcSectionLength

+ +
+
+ + + + +
const uint16_t kSamsungAcSectionLength = 7
+
+ +
+
+ +

◆ kSamsungAcSwingMove

+ +
+
+ + + + +
const uint8_t kSamsungAcSwingMove = 0b010
+
+ +
+
+ +

◆ kSamsungAcSwingOffset

+ +
+
+ + + + +
const uint8_t kSamsungAcSwingOffset = 4
+
+ +
+
+ +

◆ kSamsungAcSwingSize

+ +
+
+ + + + +
const uint8_t kSamsungAcSwingSize = 3
+
+ +
+
+ +

◆ kSamsungAcSwingStop

+ +
+
+ + + + +
const uint8_t kSamsungAcSwingStop = 0b111
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Samsung_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Samsung_8h_source.html new file mode 100644 index 000000000..a6c27ffcd --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Samsung_8h_source.html @@ -0,0 +1,335 @@ + + + + + + + +IRremoteESP8266: src/ir_Samsung.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Samsung.h
+
+
+Go to the documentation of this file.
1 // Copyright 2018 David Conran
+
9 
+
10 // Supports:
+
11 // Brand: Samsung, Model: UA55H6300 TV (SAMSUNG)
+
12 // Brand: Samsung, Model: BN59-01178B TV remote (SAMSUNG)
+
13 // Brand: Samsung, Model: DB63-03556X003 remote
+
14 // Brand: Samsung, Model: DB93-16761C remote
+
15 // Brand: Samsung, Model: IEC-R03 remote
+
16 // Brand: Samsung, Model: AK59-00167A Bluray remote (SAMSUNG36)
+
17 // Brand: Samsung, Model: AR09FSSDAWKNFA A/C (SAMSUNG_AC)
+
18 // Brand: Samsung, Model: AR12KSFPEWQNET A/C (SAMSUNG_AC)
+
19 // Brand: Samsung, Model: AR12HSSDBWKNEU A/C (SAMSUNG_AC)
+
20 // Brand: Samsung, Model: AR12NXCXAWKXEU A/C (SAMSUNG_AC)
+
21 
+
22 #ifndef IR_SAMSUNG_H_
+
23 #define IR_SAMSUNG_H_
+
24 
+
25 #define __STDC_LIMIT_MACROS
+
26 #include <stdint.h>
+
27 #ifndef UNIT_TEST
+
28 #include <Arduino.h>
+
29 #endif
+
30 #include "IRremoteESP8266.h"
+
31 #include "IRsend.h"
+
32 #ifdef UNIT_TEST
+
33 #include "IRsend_test.h"
+
34 #endif
+
35 
+
36 // Constants
+
37 
+
38 // SamsungAc
+
39 // Byte[1]
+
40 // Checksum 0b11110000 ???
+
41 const uint8_t kSamsungAcPower1Offset = 5; // Mask 0b00100000
+
42 const uint8_t kSamsungAcQuiet1Offset = 4; // Mask 0b00010000
+
43 // Byte[5]
+
44 const uint8_t kSamsungAcQuiet5Offset = 5;
+
45 // Byte[6]
+
46 const uint8_t kSamsungAcPower6Offset = 4; // Mask 0b00110000
+
47 const uint8_t kSamsungAcPower6Size = 2; // Bits
+
48 // Byte[8]
+
49 // Checksum 0b11110000 ???
+
50 const uint8_t kSamsungAcPowerfulMask8 = 0b01010000;
+
51 // Byte[9]
+
52 const uint8_t kSamsungAcSwingOffset = 4; // Mask 0b01110000
+
53 const uint8_t kSamsungAcSwingSize = 3; // Bits
+
54 const uint8_t kSamsungAcSwingMove = 0b010;
+
55 const uint8_t kSamsungAcSwingStop = 0b111;
+
56 // Byte[10]
+
57 const uint8_t kSamsungAcPowerful10Offset = 1; // Mask 0b00001110
+
58 const uint8_t kSamsungAcPowerful10Size = 3; // Mask 0b00001110
+
59 const uint8_t kSamsungAcPowerful10On = 0b011;
+
60 // Breeze (aka. WindFree)
+ + +
63 const uint8_t kSamsungAcBreezeOn = 0b101;
+
64 const uint8_t kSamsungAcDisplayOffset = 4; // Mask 0b00010000
+
65 const uint8_t kSamsungAcClean10Offset = 7; // Mask 0b10000000
+
66 // Byte[11]
+
67 const uint8_t kSamsungAcIonOffset = 0; // Mask 0b00000001
+
68 const uint8_t kSamsungAcClean11Offset = 1; // Mask 0b00000010
+
69 const uint8_t kSamsungAcMinTemp = 16; // C Mask 0b11110000
+
70 const uint8_t kSamsungAcMaxTemp = 30; // C Mask 0b11110000
+
71 const uint8_t kSamsungAcAutoTemp = 25; // C Mask 0b11110000
+
72 // Byte[12]
+
73 const uint8_t kSamsungAcModeOffset = 4; // Mask 0b01110000
+
74 const uint8_t kSamsungAcAuto = 0;
+
75 const uint8_t kSamsungAcCool = 1;
+
76 const uint8_t kSamsungAcDry = 2;
+
77 const uint8_t kSamsungAcFan = 3;
+
78 const uint8_t kSamsungAcHeat = 4;
+
79 const uint8_t kSamsungAcFanOffest = 1; // Mask 0b00001110
+
80 const uint8_t kSamsungAcFanSize = 3; // Bits
+
81 const uint8_t kSamsungAcFanAuto = 0;
+
82 const uint8_t kSamsungAcFanLow = 2;
+
83 const uint8_t kSamsungAcFanMed = 4;
+
84 const uint8_t kSamsungAcFanHigh = 5;
+
85 const uint8_t kSamsungAcFanAuto2 = 6;
+
86 const uint8_t kSamsungAcFanTurbo = 7;
+
87 // Byte[13]
+
88 const uint8_t kSamsungAcBeepOffset = 1; // Mask 0b00000010
+
89 
+
90 const uint16_t kSamsungAcSectionLength = 7;
+
91 const uint64_t kSamsungAcPowerSection = 0x1D20F00000000;
+
92 
+
93 // Classes
+
95 class IRSamsungAc {
+
96  public:
+
97  explicit IRSamsungAc(const uint16_t pin, const bool inverted = false,
+
98  const bool use_modulation = true);
+
99  void stateReset(const bool forcepower = true, const bool initialPower = true);
+
100 #if SEND_SAMSUNG_AC
+
101  void send(const uint16_t repeat = kSamsungAcDefaultRepeat,
+
102  const bool calcchecksum = true);
+
103  void sendExtended(const uint16_t repeat = kSamsungAcDefaultRepeat,
+
104  const bool calcchecksum = true);
+
105  void sendOn(const uint16_t repeat = kSamsungAcDefaultRepeat);
+
106  void sendOff(const uint16_t repeat = kSamsungAcDefaultRepeat);
+
111  int8_t calibrate(void) { return _irsend.calibrate(); }
+
112 #endif // SEND_SAMSUNG_AC
+
113  void begin(void);
+
114  void on(void);
+
115  void off(void);
+
116  void setPower(const bool on);
+
117  bool getPower(void);
+
118  void setTemp(const uint8_t temp);
+
119  uint8_t getTemp(void);
+
120  void setFan(const uint8_t speed);
+
121  uint8_t getFan(void);
+
122  void setMode(const uint8_t mode);
+
123  uint8_t getMode(void);
+
124  void setSwing(const bool on);
+
125  bool getSwing(void);
+
126  void setBeep(const bool on);
+
127  bool getBeep(void);
+
128  void setClean(const bool on);
+
129  bool getClean(void);
+
130  void setQuiet(const bool on);
+
131  bool getQuiet(void);
+
132  void setPowerful(const bool on);
+
133  bool getPowerful(void);
+
134  void setBreeze(const bool on);
+
135  bool getBreeze(void);
+
136  void setDisplay(const bool on);
+
137  bool getDisplay(void);
+
138  void setIon(const bool on);
+
139  bool getIon(void);
+
140  uint8_t* getRaw(void);
+
141  void setRaw(const uint8_t new_code[],
+
142  const uint16_t length = kSamsungAcStateLength);
+
143  static bool validChecksum(const uint8_t state[],
+
144  const uint16_t length = kSamsungAcStateLength);
+
145  static uint8_t calcChecksum(const uint8_t state[],
+
146  const uint16_t length = kSamsungAcStateLength);
+
147  uint8_t convertMode(const stdAc::opmode_t mode);
+
148  uint8_t convertFan(const stdAc::fanspeed_t speed);
+
149  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
150  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
151  stdAc::state_t toCommon(void);
+
152  String toString(void);
+
153 #ifndef UNIT_TEST
+
154 
+
155  private:
+ +
157 #else // UNIT_TEST
+
158  IRsendTest _irsend;
+
160 #endif // UNIT_TEST
+ +
163  bool _forcepower;
+ +
165  void checksum(const uint16_t length = kSamsungAcStateLength);
+
166 };
+
167 
+
168 #endif // IR_SAMSUNG_H_
+
+
bool getIon(void)
Get the Ion (Filter) setting of the A/C.
Definition: ir_Samsung.cpp:636
+
const uint8_t kSamsungAcDry
Definition: ir_Samsung.h:76
+
Class for handling detailed Samsung A/C messages.
Definition: ir_Samsung.h:95
+
bool _forcepower
Hack to know when we need to send a special power mesg.
Definition: ir_Samsung.h:163
+
const uint8_t kSamsungAcCool
Definition: ir_Samsung.h:75
+
void setQuiet(const bool on)
Set the Quiet setting of the A/C.
Definition: ir_Samsung.cpp:563
+
const uint8_t kSamsungAcFanMed
Definition: ir_Samsung.h:83
+
void send(const uint16_t repeat=kSamsungAcDefaultRepeat, const bool calcchecksum=true)
Send the current internal state as an IR message.
Definition: ir_Samsung.cpp:337
+
const uint8_t kSamsungAcFanAuto2
Definition: ir_Samsung.h:85
+
const uint8_t kSamsungAcAuto
Definition: ir_Samsung.h:74
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Samsung.h:156
+
IRSamsungAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Samsung.cpp:264
+
const uint8_t kSamsungAcFanHigh
Definition: ir_Samsung.h:84
+
const uint8_t kSamsungAcBreezeSize
Definition: ir_Samsung.h:62
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
const uint8_t kSamsungAcFan
Definition: ir_Samsung.h:77
+
bool getBreeze(void)
Are the vanes closed over the fan outlet, to stop direct wind? Aka. WindFree.
Definition: ir_Samsung.cpp:603
+
void setBreeze(const bool on)
Closes the vanes over the fan outlet, to stop direct wind. Aka. WindFree.
Definition: ir_Samsung.cpp:612
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Samsung.cpp:701
+
const uint8_t kSamsungAcSwingStop
Definition: ir_Samsung.h:55
+
const uint8_t kSamsungAcPower1Offset
Definition: ir_Samsung.h:41
+
bool getDisplay(void)
Get the Display (Light/LED) setting of the A/C.
Definition: ir_Samsung.cpp:624
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Samsung.cpp:480
+
const uint16_t kSamsungAcDefaultRepeat
Definition: IRremoteESP8266.h:973
+
const uint8_t kSamsungAcPowerful10On
Definition: ir_Samsung.h:59
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Samsung.cpp:438
+ +
void setSwing(const bool on)
Set the vertical swing setting of the A/C.
Definition: ir_Samsung.cpp:523
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Samsung.cpp:728
+
const uint16_t kSamsungAcSectionLength
Definition: ir_Samsung.h:90
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Samsung.cpp:285
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
void setIon(const bool on)
Set the Ion (Filter) setting of the A/C.
Definition: ir_Samsung.cpp:642
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
void setRaw(const uint8_t new_code[], const uint16_t length=kSamsungAcStateLength)
Set the internal state from a valid code for this protocol.
Definition: ir_Samsung.cpp:412
+
std::string String
Definition: IRremoteESP8266.h:1093
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Samsung.cpp:455
+
void sendOff(const uint16_t repeat=kSamsungAcDefaultRepeat)
Send the special extended "Off" message as the library can't seem to reproduce this message automatic...
Definition: ir_Samsung.cpp:392
+
const uint8_t kSamsungAcQuiet1Offset
Definition: ir_Samsung.h:42
+
bool getPowerful(void)
Get the Powerful (Turbo) setting of the A/C.
Definition: ir_Samsung.cpp:575
+
void on(void)
Set the requested power state of the A/C to on.
Definition: ir_Samsung.cpp:423
+
bool getBeep(void)
Get the Beep setting of the A/C.
Definition: ir_Samsung.cpp:530
+
const uint8_t kSamsungAcFanSize
Definition: ir_Samsung.h:80
+
uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Samsung.cpp:662
+
uint8_t remote_state[kSamsungAcExtendedStateLength]
State in code form.
Definition: ir_Samsung.h:162
+
const uint8_t kSamsungAcPowerfulMask8
Definition: ir_Samsung.h:50
+
const uint16_t kSamsungAcStateLength
Definition: IRremoteESP8266.h:969
+
static bool validChecksum(const uint8_t state[], const uint16_t length=kSamsungAcStateLength)
Verify the checksum is valid for a given state.
Definition: ir_Samsung.cpp:310
+ +
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Samsung.cpp:446
+
const uint8_t kSamsungAcSwingOffset
Definition: ir_Samsung.h:52
+
const uint64_t kSamsungAcPowerSection
Definition: ir_Samsung.h:91
+
void setPowerful(const bool on)
Set the Powerful (Turbo) setting of the A/C.
Definition: ir_Samsung.cpp:584
+
const uint8_t kSamsungAcModeOffset
Definition: ir_Samsung.h:73
+
const uint16_t kSamsungAcExtendedStateLength
Definition: IRremoteESP8266.h:971
+
bool getQuiet(void)
Get the Quiet setting of the A/C.
Definition: ir_Samsung.cpp:556
+
const uint8_t kSamsungAcDisplayOffset
Definition: ir_Samsung.h:64
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Samsung.cpp:430
+
void setDisplay(const bool on)
Set the Display (Light/LED) setting of the A/C.
Definition: ir_Samsung.cpp:630
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Samsung.cpp:506
+
const uint8_t kSamsungAcBreezeOn
Definition: ir_Samsung.h:63
+
const uint8_t kSamsungAcPowerful10Offset
Definition: ir_Samsung.h:57
+
void stateReset(const bool forcepower=true, const bool initialPower=true)
Reset the internal state of the emulation.
Definition: ir_Samsung.cpp:274
+
static uint8_t calcChecksum(const uint8_t state[], const uint16_t length=kSamsungAcStateLength)
Calculate the checksum for a given state.
Definition: ir_Samsung.cpp:291
+
bool _lastsentpowerstate
Definition: ir_Samsung.h:164
+
const uint8_t kSamsungAcAutoTemp
Definition: ir_Samsung.h:71
+
const uint8_t kSamsungAcSwingMove
Definition: ir_Samsung.h:54
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Samsung.cpp:462
+
const uint8_t kSamsungAcBreezeOffset
Definition: ir_Samsung.h:61
+
const uint8_t kSamsungAcSwingSize
Definition: ir_Samsung.h:53
+
const uint8_t kSamsungAcFanLow
Definition: ir_Samsung.h:82
+
void setClean(const bool on)
Set the Clean setting of the A/C.
Definition: ir_Samsung.cpp:549
+
const uint8_t kSamsungAcHeat
Definition: ir_Samsung.h:78
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Samsung.cpp:676
+
void sendOn(const uint16_t repeat=kSamsungAcDefaultRepeat)
Send the special extended "On" message as the library can't seem to reproduce this message automatica...
Definition: ir_Samsung.cpp:379
+
const uint8_t kSamsungAcFanAuto
Definition: ir_Samsung.h:81
+
const uint8_t kSamsungAcClean11Offset
Definition: ir_Samsung.h:68
+
void checksum(const uint16_t length=kSamsungAcStateLength)
Update the checksum for the internal state.
Definition: ir_Samsung.cpp:323
+
void setBeep(const bool on)
Set the Beep setting of the A/C.
Definition: ir_Samsung.cpp:536
+
bool getClean(void)
Get the Clean setting of the A/C.
Definition: ir_Samsung.cpp:542
+
const uint8_t kSamsungAcFanOffest
Definition: ir_Samsung.h:79
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Samsung.cpp:649
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Samsung.h:111
+
void sendExtended(const uint16_t repeat=kSamsungAcDefaultRepeat, const bool calcchecksum=true)
Send the extended current internal state as an IR message.
Definition: ir_Samsung.cpp:358
+
void setFan(const uint8_t speed)
Set the speed of the fan.
Definition: ir_Samsung.cpp:486
+
const uint8_t kSamsungAcMaxTemp
Definition: ir_Samsung.h:70
+
const uint8_t kSamsungAcIonOffset
Definition: ir_Samsung.h:67
+
const uint8_t kSamsungAcPower6Offset
Definition: ir_Samsung.h:46
+
const uint8_t kSamsungAcPowerful10Size
Definition: ir_Samsung.h:58
+
const uint8_t kSamsungAcClean10Offset
Definition: ir_Samsung.h:65
+
bool getSwing(void)
Get the vertical swing setting of the A/C.
Definition: ir_Samsung.cpp:514
+
void off(void)
Set the requested power state of the A/C to off.
Definition: ir_Samsung.cpp:426
+
const uint8_t kSamsungAcPower6Size
Definition: ir_Samsung.h:47
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Samsung.cpp:689
+
const uint8_t kSamsungAcBeepOffset
Definition: ir_Samsung.h:88
+
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_Samsung.cpp:404
+
const uint8_t kSamsungAcQuiet5Offset
Definition: ir_Samsung.h:44
+
const uint8_t kSamsungAcFanTurbo
Definition: ir_Samsung.h:86
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
const uint8_t kSamsungAcMinTemp
Definition: ir_Samsung.h:69
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sanyo_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sanyo_8cpp.html new file mode 100644 index 000000000..51a096705 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sanyo_8cpp.html @@ -0,0 +1,352 @@ + + + + + + + +IRremoteESP8266: src/ir_Sanyo.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Sanyo.cpp File Reference
+
+
+ +

Support for Sanyo protocols. Sanyo LC7461 support originally by marcosamarinho Sanyo SA 8650B originally added from https://github.com/shirriff/Arduino-IRremote/. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kSanyoSa8650bHdrMark = 3500
 
const uint16_t kSanyoSa8650bHdrSpace = 950
 
const uint16_t kSanyoSa8650bOneMark = 2400
 
const uint16_t kSanyoSa8650bZeroMark = 700
 
const uint16_t kSanyoSa8650bDoubleSpaceUsecs = 800
 
const uint16_t kSanyoSa8650bRptLength = 45000
 
const uint16_t kSanyoLc7461AddressMask = (1 << kSanyoLC7461AddressBits) - 1
 
const uint16_t kSanyoLc7461CommandMask = (1 << kSanyoLC7461CommandBits) - 1
 
const uint16_t kSanyoLc7461HdrMark = 9000
 
const uint16_t kSanyoLc7461HdrSpace = 4500
 
const uint16_t kSanyoLc7461BitMark = 560
 
const uint16_t kSanyoLc7461OneSpace = 1690
 
const uint16_t kSanyoLc7461ZeroSpace = 560
 
const uint32_t kSanyoLc7461MinCommandLength = 108000
 
const uint16_t kSanyoLc7461MinGap
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kSanyoLc7461AddressMask

+ +
+
+ + + + +
const uint16_t kSanyoLc7461AddressMask = (1 << kSanyoLC7461AddressBits) - 1
+
+ +
+
+ +

◆ kSanyoLc7461BitMark

+ +
+
+ + + + +
const uint16_t kSanyoLc7461BitMark = 560
+
+ +
+
+ +

◆ kSanyoLc7461CommandMask

+ +
+
+ + + + +
const uint16_t kSanyoLc7461CommandMask = (1 << kSanyoLC7461CommandBits) - 1
+
+ +
+
+ +

◆ kSanyoLc7461HdrMark

+ +
+
+ + + + +
const uint16_t kSanyoLc7461HdrMark = 9000
+
+ +
+
+ +

◆ kSanyoLc7461HdrSpace

+ +
+
+ + + + +
const uint16_t kSanyoLc7461HdrSpace = 4500
+
+ +
+
+ +

◆ kSanyoLc7461MinCommandLength

+ +
+
+ + + + +
const uint32_t kSanyoLc7461MinCommandLength = 108000
+
+ +
+
+ +

◆ kSanyoLc7461MinGap

+ +
+
+ + + + +
const uint16_t kSanyoLc7461MinGap
+
+
+ +

◆ kSanyoLc7461OneSpace

+ +
+
+ + + + +
const uint16_t kSanyoLc7461OneSpace = 1690
+
+ +
+
+ +

◆ kSanyoLc7461ZeroSpace

+ +
+
+ + + + +
const uint16_t kSanyoLc7461ZeroSpace = 560
+
+ +
+
+ +

◆ kSanyoSa8650bDoubleSpaceUsecs

+ +
+
+ + + + +
const uint16_t kSanyoSa8650bDoubleSpaceUsecs = 800
+
+ +
+
+ +

◆ kSanyoSa8650bHdrMark

+ +
+
+ + + + +
const uint16_t kSanyoSa8650bHdrMark = 3500
+
+ +
+
+ +

◆ kSanyoSa8650bHdrSpace

+ +
+
+ + + + +
const uint16_t kSanyoSa8650bHdrSpace = 950
+
+ +
+
+ +

◆ kSanyoSa8650bOneMark

+ +
+
+ + + + +
const uint16_t kSanyoSa8650bOneMark = 2400
+
+ +
+
+ +

◆ kSanyoSa8650bRptLength

+ +
+
+ + + + +
const uint16_t kSanyoSa8650bRptLength = 45000
+
+ +
+
+ +

◆ kSanyoSa8650bZeroMark

+ +
+
+ + + + +
const uint16_t kSanyoSa8650bZeroMark = 700
+
+ +
+
+
+
const uint16_t kSanyoLc7461HdrMark
Definition: ir_Sanyo.cpp:37
+
const uint32_t kSanyoLc7461MinCommandLength
Definition: ir_Sanyo.cpp:42
+
const uint16_t kSanyoLC7461Bits
Definition: IRremoteESP8266.h:977
+
const uint16_t kSanyoLc7461HdrSpace
Definition: ir_Sanyo.cpp:38
+
const uint16_t kSanyoLc7461BitMark
Definition: ir_Sanyo.cpp:39
+
const uint16_t kSanyoLc7461ZeroSpace
Definition: ir_Sanyo.cpp:41
+
const uint16_t kSanyoLc7461OneSpace
Definition: ir_Sanyo.cpp:40
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sharp_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sharp_8cpp.html new file mode 100644 index 000000000..27e3c360b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sharp_8cpp.html @@ -0,0 +1,301 @@ + + + + + + + +IRremoteESP8266: src/ir_Sharp.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Sharp.cpp File Reference
+
+
+ +

Support for Sharp protocols. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kSharpTick = 26
 
const uint16_t kSharpBitMarkTicks = 10
 
const uint16_t kSharpBitMark = kSharpBitMarkTicks * kSharpTick
 
const uint16_t kSharpOneSpaceTicks = 70
 
const uint16_t kSharpOneSpace = kSharpOneSpaceTicks * kSharpTick
 
const uint16_t kSharpZeroSpaceTicks = 30
 
const uint16_t kSharpZeroSpace = kSharpZeroSpaceTicks * kSharpTick
 
const uint16_t kSharpGapTicks = 1677
 
const uint16_t kSharpGap = kSharpGapTicks * kSharpTick
 
const uint64_t kSharpToggleMask
 
const uint64_t kSharpAddressMask = ((uint64_t)1 << kSharpAddressBits) - 1
 
const uint64_t kSharpCommandMask = ((uint64_t)1 << kSharpCommandBits) - 1
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kSharpAddressMask

+ +
+
+ + + + +
const uint64_t kSharpAddressMask = ((uint64_t)1 << kSharpAddressBits) - 1
+
+ +
+
+ +

◆ kSharpBitMark

+ +
+
+ + + + +
const uint16_t kSharpBitMark = kSharpBitMarkTicks * kSharpTick
+
+ +
+
+ +

◆ kSharpBitMarkTicks

+ +
+
+ + + + +
const uint16_t kSharpBitMarkTicks = 10
+
+ +
+
+ +

◆ kSharpCommandMask

+ +
+
+ + + + +
const uint64_t kSharpCommandMask = ((uint64_t)1 << kSharpCommandBits) - 1
+
+ +
+
+ +

◆ kSharpGap

+ +
+
+ + + + +
const uint16_t kSharpGap = kSharpGapTicks * kSharpTick
+
+ +
+
+ +

◆ kSharpGapTicks

+ +
+
+ + + + +
const uint16_t kSharpGapTicks = 1677
+
+ +
+
+ +

◆ kSharpOneSpace

+ +
+
+ + + + +
const uint16_t kSharpOneSpace = kSharpOneSpaceTicks * kSharpTick
+
+ +
+
+ +

◆ kSharpOneSpaceTicks

+ +
+
+ + + + +
const uint16_t kSharpOneSpaceTicks = 70
+
+ +
+
+ +

◆ kSharpTick

+ +
+
+ + + + +
const uint16_t kSharpTick = 26
+
+ +
+
+ +

◆ kSharpToggleMask

+ +
+
+ + + + +
const uint64_t kSharpToggleMask
+
+Initial value:
=
+
((uint64_t)1 << (kSharpBits - kSharpAddressBits)) - 1
+
+
+
+ +

◆ kSharpZeroSpace

+ +
+
+ + + + +
const uint16_t kSharpZeroSpace = kSharpZeroSpaceTicks * kSharpTick
+
+ +
+
+ +

◆ kSharpZeroSpaceTicks

+ +
+
+ + + + +
const uint16_t kSharpZeroSpaceTicks = 30
+
+ +
+
+
+
const uint16_t kSharpBits
Definition: IRremoteESP8266.h:981
+
const uint8_t kSharpAddressBits
Definition: IRremoteESP8266.h:979
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sharp_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sharp_8h.html new file mode 100644 index 000000000..a5f909c81 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sharp_8h.html @@ -0,0 +1,1074 @@ + + + + + + + +IRremoteESP8266: src/ir_Sharp.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Sharp.h File Reference
+
+
+ +

Support for Sharp protocols. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRSharpAc
 Class for handling detailed Sharp A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kSharpAcHdrMark = 3800
 
const uint16_t kSharpAcHdrSpace = 1900
 
const uint16_t kSharpAcBitMark = 470
 
const uint16_t kSharpAcZeroSpace = 500
 
const uint16_t kSharpAcOneSpace = 1400
 
const uint32_t kSharpAcGap = kDefaultMessageGap
 
const uint8_t kSharpAcByteTemp = 4
 
const uint8_t kSharpAcMinTemp = 15
 
const uint8_t kSharpAcMaxTemp = 30
 
const uint8_t kSharpAcBytePowerSpecial = 5
 
const uint8_t kSharpAcPowerSetSpecialOffset = kHighNibble
 
const uint8_t kSharpAcPowerSpecialSize = kNibbleSize
 
const uint8_t kSharpAcPowerUnknown = 0
 
const uint8_t kSharpAcPowerOnFromOff = 1
 
const uint8_t kSharpAcPowerOff = 2
 
const uint8_t kSharpAcPowerOn = 3
 
const uint8_t kSharpAcPowerSetSpecialOn = 6
 
const uint8_t kSharpAcPowerSetSpecialOff = 7
 
const uint8_t kSharpAcPowerTimerSetting = 8
 
const uint8_t kSharpAcByteMode = 6
 
const uint8_t kSharpAcModeSize = 2
 
const uint8_t kSharpAcAuto = 0b00
 
const uint8_t kSharpAcDry = 0b11
 
const uint8_t kSharpAcCool = 0b10
 
const uint8_t kSharpAcHeat = 0b01
 
const uint8_t kSharpAcByteClean = kSharpAcByteMode
 
const uint8_t kSharpAcBitCleanOffset = 3
 
const uint8_t kSharpAcByteFan = kSharpAcByteMode
 
const uint8_t kSharpAcFanOffset = 4
 
const uint8_t kSharpAcFanSize = 3
 
const uint8_t kSharpAcFanAuto = 0b010
 
const uint8_t kSharpAcFanMin = 0b100
 
const uint8_t kSharpAcFanMed = 0b011
 
const uint8_t kSharpAcFanHigh = 0b101
 
const uint8_t kSharpAcFanMax = 0b111
 
const uint8_t kSharpAcByteTimer = 7
 
const uint8_t kSharpAcTimerIncrement = 30
 
const uint8_t kSharpAcTimerHoursOffset = kLowNibble
 
const uint8_t kSharpAcTimerHoursSize = kNibbleSize
 
const uint8_t kSharpAcTimerHoursOff = 0b0000
 
const uint8_t kSharpAcTimerHoursMax = 0b1100
 
const uint8_t kSharpAcBitTimerType = 6
 
const uint8_t kSharpAcOffTimerType = 0b0
 
const uint8_t kSharpAcOnTimerType = 0b1
 
const uint8_t kSharpAcBitTimerEnabled = 7
 
const uint8_t kSharpAcByteSwing = 8
 
const uint8_t kSharpAcSwingOffset = 0
 
const uint8_t kSharpAcSwingSize = 3
 
const uint8_t kSharpAcSwingToggle = 0b111
 
const uint8_t kSharpAcSwingNoToggle = 0b000
 
const uint8_t kSharpAcByteSpecial = 10
 
const uint8_t kSharpAcSpecialPower = 0x00
 
const uint8_t kSharpAcSpecialTurbo = 0x01
 
const uint8_t kSharpAcSpecialTempEcono = 0x04
 
const uint8_t kSharpAcSpecialFan = 0x05
 
const uint8_t kSharpAcSpecialSwing = 0x06
 
const uint8_t kSharpAcSpecialTimer = 0xC0
 
const uint8_t kSharpAcSpecialTimerHalfHour = 0xDE
 
const uint8_t kSharpAcByteIon = 11
 
const uint8_t kSharpAcBitIonOffset = 2
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kSharpAcAuto

+ +
+
+ + + + +
const uint8_t kSharpAcAuto = 0b00
+
+ +
+
+ +

◆ kSharpAcBitCleanOffset

+ +
+
+ + + + +
const uint8_t kSharpAcBitCleanOffset = 3
+
+ +
+
+ +

◆ kSharpAcBitIonOffset

+ +
+
+ + + + +
const uint8_t kSharpAcBitIonOffset = 2
+
+ +
+
+ +

◆ kSharpAcBitMark

+ +
+
+ + + + +
const uint16_t kSharpAcBitMark = 470
+
+ +
+
+ +

◆ kSharpAcBitTimerEnabled

+ +
+
+ + + + +
const uint8_t kSharpAcBitTimerEnabled = 7
+
+ +
+
+ +

◆ kSharpAcBitTimerType

+ +
+
+ + + + +
const uint8_t kSharpAcBitTimerType = 6
+
+ +
+
+ +

◆ kSharpAcByteClean

+ +
+
+ + + + +
const uint8_t kSharpAcByteClean = kSharpAcByteMode
+
+ +
+
+ +

◆ kSharpAcByteFan

+ +
+
+ + + + +
const uint8_t kSharpAcByteFan = kSharpAcByteMode
+
+ +
+
+ +

◆ kSharpAcByteIon

+ +
+
+ + + + +
const uint8_t kSharpAcByteIon = 11
+
+ +
+
+ +

◆ kSharpAcByteMode

+ +
+
+ + + + +
const uint8_t kSharpAcByteMode = 6
+
+ +
+
+ +

◆ kSharpAcBytePowerSpecial

+ +
+
+ + + + +
const uint8_t kSharpAcBytePowerSpecial = 5
+
+ +
+
+ +

◆ kSharpAcByteSpecial

+ +
+
+ + + + +
const uint8_t kSharpAcByteSpecial = 10
+
+ +
+
+ +

◆ kSharpAcByteSwing

+ +
+
+ + + + +
const uint8_t kSharpAcByteSwing = 8
+
+ +
+
+ +

◆ kSharpAcByteTemp

+ +
+
+ + + + +
const uint8_t kSharpAcByteTemp = 4
+
+ +
+
+ +

◆ kSharpAcByteTimer

+ +
+
+ + + + +
const uint8_t kSharpAcByteTimer = 7
+
+ +
+
+ +

◆ kSharpAcCool

+ +
+
+ + + + +
const uint8_t kSharpAcCool = 0b10
+
+ +
+
+ +

◆ kSharpAcDry

+ +
+
+ + + + +
const uint8_t kSharpAcDry = 0b11
+
+ +
+
+ +

◆ kSharpAcFanAuto

+ +
+
+ + + + +
const uint8_t kSharpAcFanAuto = 0b010
+
+ +
+
+ +

◆ kSharpAcFanHigh

+ +
+
+ + + + +
const uint8_t kSharpAcFanHigh = 0b101
+
+ +
+
+ +

◆ kSharpAcFanMax

+ +
+
+ + + + +
const uint8_t kSharpAcFanMax = 0b111
+
+ +
+
+ +

◆ kSharpAcFanMed

+ +
+
+ + + + +
const uint8_t kSharpAcFanMed = 0b011
+
+ +
+
+ +

◆ kSharpAcFanMin

+ +
+
+ + + + +
const uint8_t kSharpAcFanMin = 0b100
+
+ +
+
+ +

◆ kSharpAcFanOffset

+ +
+
+ + + + +
const uint8_t kSharpAcFanOffset = 4
+
+ +
+
+ +

◆ kSharpAcFanSize

+ +
+
+ + + + +
const uint8_t kSharpAcFanSize = 3
+
+ +
+
+ +

◆ kSharpAcGap

+ +
+
+ + + + +
const uint32_t kSharpAcGap = kDefaultMessageGap
+
+ +
+
+ +

◆ kSharpAcHdrMark

+ +
+
+ + + + +
const uint16_t kSharpAcHdrMark = 3800
+
+ +
+
+ +

◆ kSharpAcHdrSpace

+ +
+
+ + + + +
const uint16_t kSharpAcHdrSpace = 1900
+
+ +
+
+ +

◆ kSharpAcHeat

+ +
+
+ + + + +
const uint8_t kSharpAcHeat = 0b01
+
+ +
+
+ +

◆ kSharpAcMaxTemp

+ +
+
+ + + + +
const uint8_t kSharpAcMaxTemp = 30
+
+ +
+
+ +

◆ kSharpAcMinTemp

+ +
+
+ + + + +
const uint8_t kSharpAcMinTemp = 15
+
+ +
+
+ +

◆ kSharpAcModeSize

+ +
+
+ + + + +
const uint8_t kSharpAcModeSize = 2
+
+ +
+
+ +

◆ kSharpAcOffTimerType

+ +
+
+ + + + +
const uint8_t kSharpAcOffTimerType = 0b0
+
+ +
+
+ +

◆ kSharpAcOneSpace

+ +
+
+ + + + +
const uint16_t kSharpAcOneSpace = 1400
+
+ +
+
+ +

◆ kSharpAcOnTimerType

+ +
+
+ + + + +
const uint8_t kSharpAcOnTimerType = 0b1
+
+ +
+
+ +

◆ kSharpAcPowerOff

+ +
+
+ + + + +
const uint8_t kSharpAcPowerOff = 2
+
+ +
+
+ +

◆ kSharpAcPowerOn

+ +
+
+ + + + +
const uint8_t kSharpAcPowerOn = 3
+
+ +
+
+ +

◆ kSharpAcPowerOnFromOff

+ +
+
+ + + + +
const uint8_t kSharpAcPowerOnFromOff = 1
+
+ +
+
+ +

◆ kSharpAcPowerSetSpecialOff

+ +
+
+ + + + +
const uint8_t kSharpAcPowerSetSpecialOff = 7
+
+ +
+
+ +

◆ kSharpAcPowerSetSpecialOffset

+ +
+
+ + + + +
const uint8_t kSharpAcPowerSetSpecialOffset = kHighNibble
+
+ +
+
+ +

◆ kSharpAcPowerSetSpecialOn

+ +
+
+ + + + +
const uint8_t kSharpAcPowerSetSpecialOn = 6
+
+ +
+
+ +

◆ kSharpAcPowerSpecialSize

+ +
+
+ + + + +
const uint8_t kSharpAcPowerSpecialSize = kNibbleSize
+
+ +
+
+ +

◆ kSharpAcPowerTimerSetting

+ +
+
+ + + + +
const uint8_t kSharpAcPowerTimerSetting = 8
+
+ +
+
+ +

◆ kSharpAcPowerUnknown

+ +
+
+ + + + +
const uint8_t kSharpAcPowerUnknown = 0
+
+ +
+
+ +

◆ kSharpAcSpecialFan

+ +
+
+ + + + +
const uint8_t kSharpAcSpecialFan = 0x05
+
+ +
+
+ +

◆ kSharpAcSpecialPower

+ +
+
+ + + + +
const uint8_t kSharpAcSpecialPower = 0x00
+
+ +
+
+ +

◆ kSharpAcSpecialSwing

+ +
+
+ + + + +
const uint8_t kSharpAcSpecialSwing = 0x06
+
+ +
+
+ +

◆ kSharpAcSpecialTempEcono

+ +
+
+ + + + +
const uint8_t kSharpAcSpecialTempEcono = 0x04
+
+ +
+
+ +

◆ kSharpAcSpecialTimer

+ +
+
+ + + + +
const uint8_t kSharpAcSpecialTimer = 0xC0
+
+ +
+
+ +

◆ kSharpAcSpecialTimerHalfHour

+ +
+
+ + + + +
const uint8_t kSharpAcSpecialTimerHalfHour = 0xDE
+
+ +
+
+ +

◆ kSharpAcSpecialTurbo

+ +
+
+ + + + +
const uint8_t kSharpAcSpecialTurbo = 0x01
+
+ +
+
+ +

◆ kSharpAcSwingNoToggle

+ +
+
+ + + + +
const uint8_t kSharpAcSwingNoToggle = 0b000
+
+ +
+
+ +

◆ kSharpAcSwingOffset

+ +
+
+ + + + +
const uint8_t kSharpAcSwingOffset = 0
+
+ +
+
+ +

◆ kSharpAcSwingSize

+ +
+
+ + + + +
const uint8_t kSharpAcSwingSize = 3
+
+ +
+
+ +

◆ kSharpAcSwingToggle

+ +
+
+ + + + +
const uint8_t kSharpAcSwingToggle = 0b111
+
+ +
+
+ +

◆ kSharpAcTimerHoursMax

+ +
+
+ + + + +
const uint8_t kSharpAcTimerHoursMax = 0b1100
+
+ +
+
+ +

◆ kSharpAcTimerHoursOff

+ +
+
+ + + + +
const uint8_t kSharpAcTimerHoursOff = 0b0000
+
+ +
+
+ +

◆ kSharpAcTimerHoursOffset

+ +
+
+ + + + +
const uint8_t kSharpAcTimerHoursOffset = kLowNibble
+
+ +
+
+ +

◆ kSharpAcTimerHoursSize

+ +
+
+ + + + +
const uint8_t kSharpAcTimerHoursSize = kNibbleSize
+
+ +
+
+ +

◆ kSharpAcTimerIncrement

+ +
+
+ + + + +
const uint8_t kSharpAcTimerIncrement = 30
+
+ +
+
+ +

◆ kSharpAcZeroSpace

+ +
+
+ + + + +
const uint16_t kSharpAcZeroSpace = 500
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sharp_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sharp_8h_source.html new file mode 100644 index 000000000..9091598a9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sharp_8h_source.html @@ -0,0 +1,373 @@ + + + + + + + +IRremoteESP8266: src/ir_Sharp.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Sharp.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 crankyoldgit
+
2 
+
12 
+
13 // Supports:
+
14 // Brand: Sharp, Model: LC-52D62U TV
+
15 // Brand: Sharp, Model: AY-ZP40KR A/C
+
16 // Brand: Sharp, Model: AH-AxSAY A/C
+
17 // Brand: Sharp, Model: CRMC-A907 JBEZ remote
+
18 // Brand: Sharp, Model: AH-XP10NRY A/C
+
19 // Brand: Sharp, Model: CRMC-820JBEZ remote
+
20 
+
21 #ifndef IR_SHARP_H_
+
22 #define IR_SHARP_H_
+
23 
+
24 #ifndef UNIT_TEST
+
25 #include <Arduino.h>
+
26 #endif
+
27 #include "IRrecv.h"
+
28 #include "IRremoteESP8266.h"
+
29 #include "IRsend.h"
+
30 #ifdef UNIT_TEST
+
31 #include "IRsend_test.h"
+
32 #endif
+
33 #include "IRutils.h"
+
34 
+
35 // Constants
+
36 const uint16_t kSharpAcHdrMark = 3800;
+
37 const uint16_t kSharpAcHdrSpace = 1900;
+
38 const uint16_t kSharpAcBitMark = 470;
+
39 const uint16_t kSharpAcZeroSpace = 500;
+
40 const uint16_t kSharpAcOneSpace = 1400;
+ +
42 
+
43 // Byte[4]
+
44 const uint8_t kSharpAcByteTemp = 4;
+
45 const uint8_t kSharpAcMinTemp = 15; // Celsius
+
46 const uint8_t kSharpAcMaxTemp = 30; // Celsius
+
47 // Byte[5]
+
48 const uint8_t kSharpAcBytePowerSpecial = 5;
+
49 const uint8_t kSharpAcPowerSetSpecialOffset = kHighNibble; // 0bxxxx0000
+
50 const uint8_t kSharpAcPowerSpecialSize = kNibbleSize; // 0bxxxx0000
+
51 const uint8_t kSharpAcPowerUnknown = 0; // 0b0000
+
52 const uint8_t kSharpAcPowerOnFromOff = 1; // 0b0001
+
53 const uint8_t kSharpAcPowerOff = 2; // 0b0010
+
54 const uint8_t kSharpAcPowerOn = 3; // 0b0011 (Normal)
+
55 const uint8_t kSharpAcPowerSetSpecialOn = 6; // 0b0110
+
56 const uint8_t kSharpAcPowerSetSpecialOff = 7; // 0b0111
+
57 const uint8_t kSharpAcPowerTimerSetting = 8; // 0b1000
+
58 // Byte[6]
+
59 const uint8_t kSharpAcByteMode = 6;
+
60 const uint8_t kSharpAcModeSize = 2; // Mask 0b000000xx;
+
61 const uint8_t kSharpAcAuto = 0b00;
+
62 const uint8_t kSharpAcDry = 0b11;
+
63 const uint8_t kSharpAcCool = 0b10;
+
64 const uint8_t kSharpAcHeat = 0b01;
+ +
66 const uint8_t kSharpAcBitCleanOffset = 3; // Mask 0b0000x000
+ +
68 const uint8_t kSharpAcFanOffset = 4; // Mask 0b0xxx0000
+
69 const uint8_t kSharpAcFanSize = 3; // Nr. of Bits
+
70 const uint8_t kSharpAcFanAuto = 0b010; // 2
+
71 const uint8_t kSharpAcFanMin = 0b100; // 4 (FAN1)
+
72 const uint8_t kSharpAcFanMed = 0b011; // 3 (FAN2)
+
73 const uint8_t kSharpAcFanHigh = 0b101; // 5 (FAN3)
+
74 const uint8_t kSharpAcFanMax = 0b111; // 7 (FAN4)
+
75 // Byte[7]
+
76 const uint8_t kSharpAcByteTimer = 7;
+
77 const uint8_t kSharpAcTimerIncrement = 30; // Mins
+ +
79 const uint8_t kSharpAcTimerHoursSize = kNibbleSize; // Mask 0b0000xxxx
+
80 const uint8_t kSharpAcTimerHoursOff = 0b0000;
+
81 const uint8_t kSharpAcTimerHoursMax = 0b1100; // 12
+
82 const uint8_t kSharpAcBitTimerType = 6; // Mask 0b0x000000
+
83 const uint8_t kSharpAcOffTimerType = 0b0;
+
84 const uint8_t kSharpAcOnTimerType = 0b1;
+
85 const uint8_t kSharpAcBitTimerEnabled = 7; // Mask 0bx0000000
+
86 // Byte[8]
+
87 const uint8_t kSharpAcByteSwing = 8;
+
88 const uint8_t kSharpAcSwingOffset = 0;
+
89 const uint8_t kSharpAcSwingSize = 3; // Mask 0b00000xxx
+
90 const uint8_t kSharpAcSwingToggle = 0b111;
+
91 const uint8_t kSharpAcSwingNoToggle = 0b000;
+
92 // Byte[10]
+
93 const uint8_t kSharpAcByteSpecial = 10; // Mask 0bxxxxxxxx
+
94 const uint8_t kSharpAcSpecialPower = 0x00;
+
95 const uint8_t kSharpAcSpecialTurbo = 0x01;
+
96 const uint8_t kSharpAcSpecialTempEcono = 0x04;
+
97 const uint8_t kSharpAcSpecialFan = 0x05;
+
98 const uint8_t kSharpAcSpecialSwing = 0x06;
+
99 const uint8_t kSharpAcSpecialTimer = 0xC0;
+
100 const uint8_t kSharpAcSpecialTimerHalfHour = 0xDE;
+
101 // Byte[11]
+
102 const uint8_t kSharpAcByteIon = 11;
+
103 const uint8_t kSharpAcBitIonOffset = 2; // Mask 0b00000x00
+
104 // Byte[12] (Checksum)
+
105 
+
106 // Classes
+
108 class IRSharpAc {
+
109  public:
+
110  explicit IRSharpAc(const uint16_t pin, const bool inverted = false,
+
111  const bool use_modulation = true);
+
112 #if SEND_SHARP_AC
+
113  void send(const uint16_t repeat = kSharpAcDefaultRepeat);
+
118  int8_t calibrate(void) { return _irsend.calibrate(); }
+
119 #endif // SEND_SHARP_AC
+
120  void begin(void);
+
121  void on(void);
+
122  void off(void);
+
123  void setPower(const bool on, const bool prev_on = true);
+
124  bool getPower(void);
+
125  bool isPowerSpecial(void);
+
126  void setTemp(const uint8_t temp, const bool save = true);
+
127  uint8_t getTemp(void);
+
128  void setFan(const uint8_t fan, const bool save = true);
+
129  uint8_t getFan(void);
+
130  void setMode(const uint8_t mode, const bool save = true);
+
131  uint8_t getMode(void);
+
132  void setSpecial(const uint8_t mode);
+
133  uint8_t getSpecial(void);
+
134  bool getTurbo(void);
+
135  void setTurbo(const bool on);
+
136  bool getSwingToggle(void);
+
137  void setSwingToggle(const bool on);
+
138  bool getIon(void);
+
139  void setIon(const bool on);
+
140  bool getEconoToggle(void);
+
141  void setEconoToggle(const bool on);
+
142  uint16_t getTimerTime(void);
+
143  bool getTimerEnabled(void);
+
144  bool getTimerType(void);
+
145  void setTimer(bool enable, bool timer_type, uint16_t mins);
+
146  bool getClean(void);
+
147  void setClean(const bool on);
+
148  uint8_t* getRaw(void);
+
149  void setRaw(const uint8_t new_code[],
+
150  const uint16_t length = kSharpAcStateLength);
+
151  static bool validChecksum(uint8_t state[],
+
152  const uint16_t length = kSharpAcStateLength);
+
153  static uint8_t convertMode(const stdAc::opmode_t mode);
+
154  static uint8_t convertFan(const stdAc::fanspeed_t speed);
+
155  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
156  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
157  stdAc::state_t toCommon(void);
+
158  String toString(void);
+
159 #ifndef UNIT_TEST
+
160 
+
161  private:
+ +
163 #else // UNIT_TEST
+
164  IRsendTest _irsend;
+
166 #endif // UNIT_TEST
+ +
169  uint8_t _temp;
+
170  uint8_t _mode;
+
171  uint8_t _fan;
+
172  void stateReset(void);
+
173  void checksum(void);
+
174  static uint8_t calcChecksum(uint8_t state[],
+
175  const uint16_t length = kSharpAcStateLength);
+
176  void setPowerSpecial(const uint8_t value);
+
177  uint8_t getPowerSpecial(void);
+
178  void clearPowerSpecial(void);
+
179 };
+
180 
+
181 #endif // IR_SHARP_H_
+
+
uint8_t getPowerSpecial(void)
Get the value of the Power Special setting.
Definition: ir_Sharp.cpp:319
+
const uint8_t kSharpAcTimerHoursSize
Definition: ir_Sharp.h:79
+
const uint8_t kSharpAcByteFan
Definition: ir_Sharp.h:67
+
const uint8_t kSharpAcFanSize
Definition: ir_Sharp.h:69
+
const uint8_t kSharpAcHeat
Definition: ir_Sharp.h:64
+
const uint8_t kSharpAcSpecialTempEcono
Definition: ir_Sharp.h:96
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Sharp.cpp:421
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Sharp.h:118
+
void setTimer(bool enable, bool timer_type, uint16_t mins)
Set or cancel the timer function.
Definition: ir_Sharp.cpp:568
+
bool isPowerSpecial(void)
Is one of the special power states in use?
Definition: ir_Sharp.cpp:332
+
void setTemp(const uint8_t temp, const bool save=true)
Set the temperature.
Definition: ir_Sharp.cpp:393
+
const uint8_t kSharpAcPowerOnFromOff
Definition: ir_Sharp.h:52
+
const uint8_t kSharpAcPowerSpecialSize
Definition: ir_Sharp.h:50
+
void off(void)
Set the requested power state of the A/C to off.
Definition: ir_Sharp.cpp:345
+
const uint16_t kSharpAcOneSpace
Definition: ir_Sharp.h:40
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
uint8_t _temp
Saved copy of the desired temp.
Definition: ir_Sharp.h:169
+
const uint32_t kDefaultMessageGap
Definition: IRsend.h:41
+
static uint8_t calcChecksum(uint8_t state[], const uint16_t length=kSharpAcStateLength)
Calculate the checksum for a given state.
Definition: ir_Sharp.cpp:263
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Sharp.cpp:663
+
bool getIon(void)
Get the Ion (Filter) setting of the A/C.
Definition: ir_Sharp.cpp:515
+
const uint8_t kSharpAcSpecialTimer
Definition: ir_Sharp.h:99
+
const uint8_t kSharpAcOnTimerType
Definition: ir_Sharp.h:84
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Sharp.cpp:476
+
const uint8_t kSharpAcCool
Definition: ir_Sharp.h:63
+ +
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Sharp.cpp:360
+
const uint8_t kSharpAcSpecialFan
Definition: ir_Sharp.h:97
+
const uint8_t kSharpAcSpecialSwing
Definition: ir_Sharp.h:98
+
const uint8_t kSharpAcOffTimerType
Definition: ir_Sharp.h:83
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
const uint8_t kSharpAcMaxTemp
Definition: ir_Sharp.h:46
+
void setFan(const uint8_t fan, const bool save=true)
Set the speed of the fan.
Definition: ir_Sharp.cpp:455
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
IRSharpAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Sharp.cpp:244
+
const uint8_t kSharpAcSwingOffset
Definition: ir_Sharp.h:88
+
const uint16_t kSharpAcZeroSpace
Definition: ir_Sharp.h:39
+
void setPower(const bool on, const bool prev_on=true)
Change the power setting, including the previous power state.
Definition: ir_Sharp.cpp:350
+
const uint8_t kSharpAcDry
Definition: ir_Sharp.h:62
+
std::string String
Definition: IRremoteESP8266.h:1093
+
const uint8_t kNibbleSize
Definition: IRutils.h:17
+
const uint8_t kSharpAcTimerHoursMax
Definition: ir_Sharp.h:81
+
const uint8_t kSharpAcPowerOff
Definition: ir_Sharp.h:53
+
uint16_t getTimerTime(void)
Get how long the timer is set for, in minutes.
Definition: ir_Sharp.cpp:544
+
const uint8_t kLowNibble
Definition: IRutils.h:18
+
const uint8_t kSharpAcSwingNoToggle
Definition: ir_Sharp.h:91
+
const uint8_t kSharpAcTimerIncrement
Definition: ir_Sharp.h:77
+ +
const uint8_t kSharpAcPowerSetSpecialOn
Definition: ir_Sharp.h:55
+
static uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Sharp.cpp:612
+
void setTurbo(const bool on)
Set the Turbo setting of the A/C.
Definition: ir_Sharp.cpp:492
+
static bool validChecksum(uint8_t state[], const uint16_t length=kSharpAcStateLength)
Verify the checksum is valid for a given state.
Definition: ir_Sharp.cpp:274
+
uint8_t getSpecial(void)
Get the value of the Special (button/command?) setting.
Definition: ir_Sharp.cpp:388
+
const uint8_t kSharpAcSpecialTimerHalfHour
Definition: ir_Sharp.h:100
+
const uint8_t kSharpAcTimerHoursOff
Definition: ir_Sharp.h:80
+
const uint8_t kSharpAcBitTimerEnabled
Definition: ir_Sharp.h:85
+
const uint8_t kSharpAcByteTimer
Definition: ir_Sharp.h:76
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Sharp.cpp:414
+
const uint8_t kHighNibble
Definition: IRutils.h:19
+
const uint8_t kSharpAcByteSpecial
Definition: ir_Sharp.h:93
+
const uint8_t kSharpAcSwingToggle
Definition: ir_Sharp.h:90
+
void setPowerSpecial(const uint8_t value)
Set the value of the Power Special setting without any checks.
Definition: ir_Sharp.cpp:312
+
const uint8_t kSharpAcFanAuto
Definition: ir_Sharp.h:70
+
void send(const uint16_t repeat=kSharpAcDefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Sharp.cpp:254
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Sharp.h:162
+
void checksum(void)
Calculate and set the checksum values for the internal state.
Definition: ir_Sharp.cpp:280
+
const uint32_t kSharpAcGap
Definition: ir_Sharp.h:41
+
const uint8_t kSharpAcBitTimerType
Definition: ir_Sharp.h:82
+
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_Sharp.cpp:298
+
const uint8_t kSharpAcSwingSize
Definition: ir_Sharp.h:89
+
const uint8_t kSharpAcByteMode
Definition: ir_Sharp.h:59
+
bool getTimerType(void)
Get the current timer type.
Definition: ir_Sharp.cpp:559
+
const uint8_t kSharpAcPowerUnknown
Definition: ir_Sharp.h:51
+ +
const uint8_t kSharpAcPowerOn
Definition: ir_Sharp.h:54
+
void setSpecial(const uint8_t mode)
Set the value of the Special (button/command?) setting.
Definition: ir_Sharp.cpp:370
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Sharp.cpp:249
+
const uint8_t kSharpAcByteClean
Definition: ir_Sharp.h:65
+
const uint16_t kSharpAcStateLength
Definition: IRremoteESP8266.h:982
+
const uint8_t kSharpAcModeSize
Definition: ir_Sharp.h:60
+
const uint8_t kSharpAcFanMax
Definition: ir_Sharp.h:74
+ +
uint8_t _mode
Saved copy of the desired mode.
Definition: ir_Sharp.h:170
+
const uint8_t kSharpAcBytePowerSpecial
Definition: ir_Sharp.h:48
+
Class for handling detailed Sharp A/C messages.
Definition: ir_Sharp.h:108
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Sharp.cpp:639
+
bool getEconoToggle(void)
Get the Economical mode toggle setting of the A/C.
Definition: ir_Sharp.cpp:529
+
const uint8_t kSharpAcPowerTimerSetting
Definition: ir_Sharp.h:57
+
const uint8_t kSharpAcBitIonOffset
Definition: ir_Sharp.h:103
+
const uint8_t kSharpAcFanHigh
Definition: ir_Sharp.h:73
+
bool getSwingToggle(void)
Get the (vertical) Swing Toggle setting of the A/C.
Definition: ir_Sharp.cpp:500
+
const uint8_t kSharpAcFanMin
Definition: ir_Sharp.h:71
+
const uint8_t kSharpAcByteSwing
Definition: ir_Sharp.h:87
+
void setClean(const bool on)
Set the Economical mode toggle setting of the A/C.
Definition: ir_Sharp.cpp:595
+
uint8_t remote[kSharpAcStateLength]
State of the remote in IR code form.
Definition: ir_Sharp.h:168
+
const uint8_t kSharpAcFanMed
Definition: ir_Sharp.h:72
+
const uint16_t kSharpAcDefaultRepeat
Definition: IRremoteESP8266.h:984
+
const uint8_t kSharpAcTimerHoursOffset
Definition: ir_Sharp.h:78
+
uint8_t _fan
Saved copy of the desired fan speed.
Definition: ir_Sharp.h:171
+
const uint8_t kSharpAcByteIon
Definition: ir_Sharp.h:102
+
void setEconoToggle(const bool on)
Set the Economical mode toggle setting of the A/C.
Definition: ir_Sharp.cpp:537
+
const uint8_t kSharpAcFanOffset
Definition: ir_Sharp.h:68
+
bool getClean(void)
Get the Clean setting of the A/C.
Definition: ir_Sharp.cpp:588
+
const uint16_t kSharpAcHdrSpace
Definition: ir_Sharp.h:37
+
bool getTurbo(void)
Get the Turbo setting of the A/C.
Definition: ir_Sharp.cpp:482
+
const uint8_t kSharpAcAuto
Definition: ir_Sharp.h:61
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Sharp.cpp:651
+
void setSwingToggle(const bool on)
Set the (vertical) Swing Toggle setting of the A/C.
Definition: ir_Sharp.cpp:507
+
bool getTimerEnabled(void)
Is the Timer enabled?
Definition: ir_Sharp.cpp:553
+
const uint8_t kSharpAcPowerSetSpecialOffset
Definition: ir_Sharp.h:49
+
const uint8_t kSharpAcPowerSetSpecialOff
Definition: ir_Sharp.h:56
+
void on(void)
Set the requested power state of the A/C to on.
Definition: ir_Sharp.cpp:342
+
void setMode(const uint8_t mode, const bool save=true)
Set the operating mode of the A/C.
Definition: ir_Sharp.cpp:428
+
const uint16_t kSharpAcBitMark
Definition: ir_Sharp.h:38
+
const uint8_t kSharpAcMinTemp
Definition: ir_Sharp.h:45
+
const uint8_t kSharpAcSpecialTurbo
Definition: ir_Sharp.h:95
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Sharp.cpp:690
+
void stateReset(void)
Reset the state of the remote to a known good state/sequence.
Definition: ir_Sharp.cpp:286
+
const uint8_t kSharpAcByteTemp
Definition: ir_Sharp.h:44
+
void setIon(const bool on)
Set the Ion (Filter) setting of the A/C.
Definition: ir_Sharp.cpp:521
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
void clearPowerSpecial(void)
Clear the "special"/non-normal bits in the power section. e.g. for normal/common command modes.
Definition: ir_Sharp.cpp:326
+
const uint16_t kSharpAcHdrMark
Definition: ir_Sharp.h:36
+
void setRaw(const uint8_t new_code[], const uint16_t length=kSharpAcStateLength)
Set the internal state from a valid code for this protocol.
Definition: ir_Sharp.cpp:306
+
const uint8_t kSharpAcSpecialPower
Definition: ir_Sharp.h:94
+
const uint8_t kSharpAcBitCleanOffset
Definition: ir_Sharp.h:66
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+
static uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Sharp.cpp:625
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sherwood_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sherwood_8cpp.html new file mode 100644 index 000000000..a6b133aa1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sherwood_8cpp.html @@ -0,0 +1,85 @@ + + + + + + + +IRremoteESP8266: src/ir_Sherwood.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Sherwood.cpp File Reference
+
+
+ +

Support for Sherwood protocols. +More...

+

Detailed Description

+

Support for Sherwood protocols.

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sony_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sony_8cpp.html new file mode 100644 index 000000000..fa1d5b055 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Sony_8cpp.html @@ -0,0 +1,335 @@ + + + + + + + +IRremoteESP8266: src/ir_Sony.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Sony.cpp File Reference
+
+
+ +

Support for Sony SIRC(Serial Infra-Red Control) protocols. Sony originally added from https://github.com/shirriff/Arduino-IRremote/ Updates from marcosamarinho. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kSonyTick = 200
 
const uint16_t kSonyHdrMarkTicks = 12
 
const uint16_t kSonyHdrMark = kSonyHdrMarkTicks * kSonyTick
 
const uint16_t kSonySpaceTicks = 3
 
const uint16_t kSonySpace = kSonySpaceTicks * kSonyTick
 
const uint16_t kSonyOneMarkTicks = 6
 
const uint16_t kSonyOneMark = kSonyOneMarkTicks * kSonyTick
 
const uint16_t kSonyZeroMarkTicks = 3
 
const uint16_t kSonyZeroMark = kSonyZeroMarkTicks * kSonyTick
 
const uint16_t kSonyRptLengthTicks = 225
 
const uint16_t kSonyRptLength = kSonyRptLengthTicks * kSonyTick
 
const uint16_t kSonyMinGapTicks = 50
 
const uint16_t kSonyMinGap = kSonyMinGapTicks * kSonyTick
 
const uint16_t kSonyStdFreq = 40000
 
const uint16_t kSonyAltFreq = 38000
 
+

Detailed Description

+

Support for Sony SIRC(Serial Infra-Red Control) protocols. Sony originally added from https://github.com/shirriff/Arduino-IRremote/ Updates from marcosamarinho.

+
See also
http://www.sbprojects.com/knowledge/ir/sirc.php
+
+https://github.com/crankyoldgit/IRremoteESP8266/issues/1018
+

Variable Documentation

+ +

◆ kSonyAltFreq

+ +
+
+ + + + +
const uint16_t kSonyAltFreq = 38000
+
+ +
+
+ +

◆ kSonyHdrMark

+ +
+
+ + + + +
const uint16_t kSonyHdrMark = kSonyHdrMarkTicks * kSonyTick
+
+ +
+
+ +

◆ kSonyHdrMarkTicks

+ +
+
+ + + + +
const uint16_t kSonyHdrMarkTicks = 12
+
+ +
+
+ +

◆ kSonyMinGap

+ +
+
+ + + + +
const uint16_t kSonyMinGap = kSonyMinGapTicks * kSonyTick
+
+ +
+
+ +

◆ kSonyMinGapTicks

+ +
+
+ + + + +
const uint16_t kSonyMinGapTicks = 50
+
+ +
+
+ +

◆ kSonyOneMark

+ +
+
+ + + + +
const uint16_t kSonyOneMark = kSonyOneMarkTicks * kSonyTick
+
+ +
+
+ +

◆ kSonyOneMarkTicks

+ +
+
+ + + + +
const uint16_t kSonyOneMarkTicks = 6
+
+ +
+
+ +

◆ kSonyRptLength

+ +
+
+ + + + +
const uint16_t kSonyRptLength = kSonyRptLengthTicks * kSonyTick
+
+ +
+
+ +

◆ kSonyRptLengthTicks

+ +
+
+ + + + +
const uint16_t kSonyRptLengthTicks = 225
+
+ +
+
+ +

◆ kSonySpace

+ +
+
+ + + + +
const uint16_t kSonySpace = kSonySpaceTicks * kSonyTick
+
+ +
+
+ +

◆ kSonySpaceTicks

+ +
+
+ + + + +
const uint16_t kSonySpaceTicks = 3
+
+ +
+
+ +

◆ kSonyStdFreq

+ +
+
+ + + + +
const uint16_t kSonyStdFreq = 40000
+
+ +
+
+ +

◆ kSonyTick

+ +
+
+ + + + +
const uint16_t kSonyTick = 200
+
+ +
+
+ +

◆ kSonyZeroMark

+ +
+
+ + + + +
const uint16_t kSonyZeroMark = kSonyZeroMarkTicks * kSonyTick
+
+ +
+
+ +

◆ kSonyZeroMarkTicks

+ +
+
+ + + + +
const uint16_t kSonyZeroMarkTicks = 3
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Symphony_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Symphony_8cpp.html new file mode 100644 index 000000000..9ad124022 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Symphony_8cpp.html @@ -0,0 +1,181 @@ + + + + + + + +IRremoteESP8266: src/ir_Symphony.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Symphony.cpp File Reference
+
+
+ +

Support for Symphony protocols. +More...

+ + + + + + + + + + + + +

+Variables

const uint16_t kSymphonyZeroMark = 400
 
const uint16_t kSymphonyZeroSpace = 1250
 
const uint16_t kSymphonyOneMark = kSymphonyZeroSpace
 
const uint16_t kSymphonyOneSpace = kSymphonyZeroMark
 
const uint32_t kSymphonyFooterGap
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kSymphonyFooterGap

+ +
+
+ + + + +
const uint32_t kSymphonyFooterGap
+
+Initial value: +
+
+ +

◆ kSymphonyOneMark

+ +
+
+ + + + +
const uint16_t kSymphonyOneMark = kSymphonyZeroSpace
+
+ +
+
+ +

◆ kSymphonyOneSpace

+ +
+
+ + + + +
const uint16_t kSymphonyOneSpace = kSymphonyZeroMark
+
+ +
+
+ +

◆ kSymphonyZeroMark

+ +
+
+ + + + +
const uint16_t kSymphonyZeroMark = 400
+
+ +
+
+ +

◆ kSymphonyZeroSpace

+ +
+
+ + + + +
const uint16_t kSymphonyZeroSpace = 1250
+
+ +
+
+
+
const uint16_t kSymphonyZeroMark
Definition: ir_Symphony.cpp:29
+
const uint16_t kSymphonyZeroSpace
Definition: ir_Symphony.cpp:30
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Tcl_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Tcl_8cpp.html new file mode 100644 index 000000000..722bb446c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Tcl_8cpp.html @@ -0,0 +1,86 @@ + + + + + + + +IRremoteESP8266: src/ir_Tcl.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Tcl.cpp File Reference
+
+
+ +

Support for TCL protocols. +More...

+

Detailed Description

+

Support for TCL protocols.

+
Note
There is no decodedecodeTcl112Ac(). It's the same as decodeMitsubishi112(). A shared routine is used. You can find it in: ir_Mitsubishi.cpp
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Tcl_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Tcl_8h.html new file mode 100644 index 000000000..9a6621ade --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Tcl_8h.html @@ -0,0 +1,613 @@ + + + + + + + +IRremoteESP8266: src/ir_Tcl.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Tcl.h File Reference
+
+
+ +

Support for TCL protocols. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRTcl112Ac
 Class for handling detailed TCL A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kTcl112AcHdrMark = 3000
 
const uint16_t kTcl112AcHdrSpace = 1650
 
const uint16_t kTcl112AcBitMark = 500
 
const uint16_t kTcl112AcOneSpace = 1050
 
const uint16_t kTcl112AcZeroSpace = 325
 
const uint32_t kTcl112AcGap = kDefaultMessageGap
 
const uint8_t kTcl112AcHdrMarkTolerance = 6
 
const uint8_t kTcl112AcTolerance = 5
 
const uint8_t kTcl112AcHeat = 1
 
const uint8_t kTcl112AcDry = 2
 
const uint8_t kTcl112AcCool = 3
 
const uint8_t kTcl112AcFan = 7
 
const uint8_t kTcl112AcAuto = 8
 
const uint8_t kTcl112AcModeSize = 4
 
const uint8_t kTcl112AcFanSize = 3
 
const uint8_t kTcl112AcFanAuto = 0b000
 
const uint8_t kTcl112AcFanLow = 0b010
 
const uint8_t kTcl112AcFanMed = 0b011
 
const uint8_t kTcl112AcFanHigh = 0b101
 
const uint8_t kTcl112AcHalfDegreeOffset = 5
 
const float kTcl112AcTempMax = 31.0
 
const float kTcl112AcTempMin = 16.0
 
const uint8_t kTcl112AcPowerOffset = 2
 
const uint8_t kTcl112AcBitEconoOffset = 7
 
const uint8_t kTcl112AcBitLightOffset = 6
 
const uint8_t kTcl112AcBitHealthOffset = 4
 
const uint8_t kTcl112AcBitSwingHOffset = 3
 
const uint8_t kTcl112AcSwingVOffset = 3
 
const uint8_t kTcl112AcSwingVSize = 3
 
const uint8_t kTcl112AcSwingVOn = 0b111
 
const uint8_t kTcl112AcSwingVOff = 0b000
 
const uint8_t kTcl112AcBitTurboOffset = 6
 
+

Detailed Description

+

Support for TCL protocols.

+

Variable Documentation

+ +

◆ kTcl112AcAuto

+ +
+
+ + + + +
const uint8_t kTcl112AcAuto = 8
+
+ +
+
+ +

◆ kTcl112AcBitEconoOffset

+ +
+
+ + + + +
const uint8_t kTcl112AcBitEconoOffset = 7
+
+ +
+
+ +

◆ kTcl112AcBitHealthOffset

+ +
+
+ + + + +
const uint8_t kTcl112AcBitHealthOffset = 4
+
+ +
+
+ +

◆ kTcl112AcBitLightOffset

+ +
+
+ + + + +
const uint8_t kTcl112AcBitLightOffset = 6
+
+ +
+
+ +

◆ kTcl112AcBitMark

+ +
+
+ + + + +
const uint16_t kTcl112AcBitMark = 500
+
+ +
+
+ +

◆ kTcl112AcBitSwingHOffset

+ +
+
+ + + + +
const uint8_t kTcl112AcBitSwingHOffset = 3
+
+ +
+
+ +

◆ kTcl112AcBitTurboOffset

+ +
+
+ + + + +
const uint8_t kTcl112AcBitTurboOffset = 6
+
+ +
+
+ +

◆ kTcl112AcCool

+ +
+
+ + + + +
const uint8_t kTcl112AcCool = 3
+
+ +
+
+ +

◆ kTcl112AcDry

+ +
+
+ + + + +
const uint8_t kTcl112AcDry = 2
+
+ +
+
+ +

◆ kTcl112AcFan

+ +
+
+ + + + +
const uint8_t kTcl112AcFan = 7
+
+ +
+
+ +

◆ kTcl112AcFanAuto

+ +
+
+ + + + +
const uint8_t kTcl112AcFanAuto = 0b000
+
+ +
+
+ +

◆ kTcl112AcFanHigh

+ +
+
+ + + + +
const uint8_t kTcl112AcFanHigh = 0b101
+
+ +
+
+ +

◆ kTcl112AcFanLow

+ +
+
+ + + + +
const uint8_t kTcl112AcFanLow = 0b010
+
+ +
+
+ +

◆ kTcl112AcFanMed

+ +
+
+ + + + +
const uint8_t kTcl112AcFanMed = 0b011
+
+ +
+
+ +

◆ kTcl112AcFanSize

+ +
+
+ + + + +
const uint8_t kTcl112AcFanSize = 3
+
+ +
+
+ +

◆ kTcl112AcGap

+ +
+
+ + + + +
const uint32_t kTcl112AcGap = kDefaultMessageGap
+
+ +
+
+ +

◆ kTcl112AcHalfDegreeOffset

+ +
+
+ + + + +
const uint8_t kTcl112AcHalfDegreeOffset = 5
+
+ +
+
+ +

◆ kTcl112AcHdrMark

+ +
+
+ + + + +
const uint16_t kTcl112AcHdrMark = 3000
+
+ +
+
+ +

◆ kTcl112AcHdrMarkTolerance

+ +
+
+ + + + +
const uint8_t kTcl112AcHdrMarkTolerance = 6
+
+ +
+
+ +

◆ kTcl112AcHdrSpace

+ +
+
+ + + + +
const uint16_t kTcl112AcHdrSpace = 1650
+
+ +
+
+ +

◆ kTcl112AcHeat

+ +
+
+ + + + +
const uint8_t kTcl112AcHeat = 1
+
+ +
+
+ +

◆ kTcl112AcModeSize

+ +
+
+ + + + +
const uint8_t kTcl112AcModeSize = 4
+
+ +
+
+ +

◆ kTcl112AcOneSpace

+ +
+
+ + + + +
const uint16_t kTcl112AcOneSpace = 1050
+
+ +
+
+ +

◆ kTcl112AcPowerOffset

+ +
+
+ + + + +
const uint8_t kTcl112AcPowerOffset = 2
+
+ +
+
+ +

◆ kTcl112AcSwingVOff

+ +
+
+ + + + +
const uint8_t kTcl112AcSwingVOff = 0b000
+
+ +
+
+ +

◆ kTcl112AcSwingVOffset

+ +
+
+ + + + +
const uint8_t kTcl112AcSwingVOffset = 3
+
+ +
+
+ +

◆ kTcl112AcSwingVOn

+ +
+
+ + + + +
const uint8_t kTcl112AcSwingVOn = 0b111
+
+ +
+
+ +

◆ kTcl112AcSwingVSize

+ +
+
+ + + + +
const uint8_t kTcl112AcSwingVSize = 3
+
+ +
+
+ +

◆ kTcl112AcTempMax

+ +
+
+ + + + +
const float kTcl112AcTempMax = 31.0
+
+ +
+
+ +

◆ kTcl112AcTempMin

+ +
+
+ + + + +
const float kTcl112AcTempMin = 16.0
+
+ +
+
+ +

◆ kTcl112AcTolerance

+ +
+
+ + + + +
const uint8_t kTcl112AcTolerance = 5
+
+ +
+
+ +

◆ kTcl112AcZeroSpace

+ +
+
+ + + + +
const uint16_t kTcl112AcZeroSpace = 325
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Tcl_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Tcl_8h_source.html new file mode 100644 index 000000000..3c6dbbbcf --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Tcl_8h_source.html @@ -0,0 +1,281 @@ + + + + + + + +IRremoteESP8266: src/ir_Tcl.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Tcl.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 David Conran
+
2 
+
5 
+
6 // Supports:
+
7 // Brand: Leberg, Model: LBS-TOR07 A/C
+
8 
+
9 #ifndef IR_TCL_H_
+
10 #define IR_TCL_H_
+
11 
+
12 #ifndef UNIT_TEST
+
13 #include <Arduino.h>
+
14 #endif
+
15 #include "IRremoteESP8266.h"
+
16 #include "IRsend.h"
+
17 #include "IRrecv.h"
+
18 #ifdef UNIT_TEST
+
19 #include "IRsend_test.h"
+
20 #endif
+
21 
+
22 // Constants
+
23 const uint16_t kTcl112AcHdrMark = 3000;
+
24 const uint16_t kTcl112AcHdrSpace = 1650;
+
25 const uint16_t kTcl112AcBitMark = 500;
+
26 const uint16_t kTcl112AcOneSpace = 1050;
+
27 const uint16_t kTcl112AcZeroSpace = 325;
+
28 const uint32_t kTcl112AcGap = kDefaultMessageGap; // Just a guess.
+
29 // Total tolerance percentage to use for matching the header mark.
+
30 const uint8_t kTcl112AcHdrMarkTolerance = 6;
+
31 const uint8_t kTcl112AcTolerance = 5; // Extra Percentage for the rest.
+
32 
+
33 const uint8_t kTcl112AcHeat = 1;
+
34 const uint8_t kTcl112AcDry = 2;
+
35 const uint8_t kTcl112AcCool = 3;
+
36 const uint8_t kTcl112AcFan = 7;
+
37 const uint8_t kTcl112AcAuto = 8;
+
38 const uint8_t kTcl112AcModeSize = 4; // Nr. of Bits
+
39 
+
40 const uint8_t kTcl112AcFanSize = 3; // Nr. of Bits. Mask = 0b00000111
+
41 const uint8_t kTcl112AcFanAuto = 0b000;
+
42 const uint8_t kTcl112AcFanLow = 0b010;
+
43 const uint8_t kTcl112AcFanMed = 0b011;
+
44 const uint8_t kTcl112AcFanHigh = 0b101;
+
45 
+
46 const uint8_t kTcl112AcHalfDegreeOffset = 5;
+
47 const float kTcl112AcTempMax = 31.0;
+
48 const float kTcl112AcTempMin = 16.0;
+
49 
+
50 const uint8_t kTcl112AcPowerOffset = 2;
+
51 const uint8_t kTcl112AcBitEconoOffset = 7;
+
52 const uint8_t kTcl112AcBitLightOffset = 6;
+
53 const uint8_t kTcl112AcBitHealthOffset = 4;
+
54 const uint8_t kTcl112AcBitSwingHOffset = 3;
+
55 const uint8_t kTcl112AcSwingVOffset = 3; // Mask 0b00111000
+
56 const uint8_t kTcl112AcSwingVSize = 3; // Nr. of bits.
+
57 const uint8_t kTcl112AcSwingVOn = 0b111;
+
58 const uint8_t kTcl112AcSwingVOff = 0b000;
+
59 const uint8_t kTcl112AcBitTurboOffset = 6;
+
60 
+
61 // Classes
+
63 class IRTcl112Ac {
+
64  public:
+
65  explicit IRTcl112Ac(const uint16_t pin, const bool inverted = false,
+
66  const bool use_modulation = true);
+
67 #if SEND_TCL112AC
+
68  void send(const uint16_t repeat = kTcl112AcDefaultRepeat);
+
73  int8_t calibrate(void) { return _irsend.calibrate(); }
+
74 #endif // SEND_TCL
+
75  void begin(void);
+
76  void stateReset(void);
+
77  uint8_t* getRaw(void);
+
78  void setRaw(const uint8_t new_code[],
+
79  const uint16_t length = kTcl112AcStateLength);
+
80  void on(void);
+
81  void off(void);
+
82  void setPower(const bool on);
+
83  bool getPower(void);
+
84  void setTemp(const float celsius); // Celsius in 0.5 increments
+
85  float getTemp(void);
+
86  void setMode(const uint8_t mode);
+
87  uint8_t getMode(void);
+
88  static uint8_t calcChecksum(uint8_t state[],
+
89  const uint16_t length = kTcl112AcStateLength);
+
90  static bool validChecksum(uint8_t state[],
+
91  const uint16_t length = kTcl112AcStateLength);
+
92  void setFan(const uint8_t speed);
+
93  uint8_t getFan(void);
+
94  void setEcono(const bool on);
+
95  bool getEcono(void);
+
96  void setHealth(const bool on);
+
97  bool getHealth(void);
+
98  void setLight(const bool on);
+
99  bool getLight(void);
+
100  void setSwingHorizontal(const bool on);
+
101  bool getSwingHorizontal(void);
+
102  void setSwingVertical(const bool on);
+
103  bool getSwingVertical(void);
+
104  void setTurbo(const bool on);
+
105  bool getTurbo(void);
+
106  uint8_t convertMode(const stdAc::opmode_t mode);
+
107  uint8_t convertFan(const stdAc::fanspeed_t speed);
+
108  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
109  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
110  stdAc::state_t toCommon(void);
+
111  String toString(void);
+
112 #ifndef UNIT_TEST
+
113 
+
114  private:
+ +
116 #else // UNIT_TEST
+
117  IRsendTest _irsend;
+
119 #endif // UNIT_TEST
+ +
122  void checksum(const uint16_t length = kTcl112AcStateLength);
+
123 };
+
124 
+
125 #endif // IR_TCL_H_
+
+
bool getSwingHorizontal(void)
Get the horizontal swing setting of the A/C.
Definition: ir_Tcl.cpp:248
+
void setSwingHorizontal(const bool on)
Set the horizontal swing setting of the A/C.
Definition: ir_Tcl.cpp:242
+
const uint8_t kTcl112AcBitSwingHOffset
Definition: ir_Tcl.h:54
+
uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Tcl.cpp:297
+
static uint8_t calcChecksum(uint8_t state[], const uint16_t length=kTcl112AcStateLength)
Calculate the checksum for a given state.
Definition: ir_Tcl.cpp:66
+
const float kTcl112AcTempMin
Definition: ir_Tcl.h:48
+
void setSwingVertical(const bool on)
Set the vertical swing setting of the A/C.
Definition: ir_Tcl.cpp:254
+
bool getEcono(void)
Get the economy setting of the A/C.
Definition: ir_Tcl.cpp:212
+
const uint16_t kTcl112AcHdrSpace
Definition: ir_Tcl.h:24
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Tcl.cpp:284
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
const uint32_t kDefaultMessageGap
Definition: IRsend.h:41
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Tcl.cpp:363
+
const uint8_t kTcl112AcFanLow
Definition: ir_Tcl.h:42
+
void send(const uint16_t repeat=kTcl112AcDefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Tcl.cpp:57
+
const uint16_t kTcl112AcBitMark
Definition: ir_Tcl.h:25
+
const uint8_t kTcl112AcSwingVOffset
Definition: ir_Tcl.h:55
+
const uint8_t kTcl112AcFanMed
Definition: ir_Tcl.h:43
+
bool getLight(void)
Get the Light (LED/Display) setting of the A/C.
Definition: ir_Tcl.cpp:236
+
bool getHealth(void)
Get the Health (Filter) setting of the A/C.
Definition: ir_Tcl.cpp:224
+ +
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
void setEcono(const bool on)
Set the economy setting of the A/C.
Definition: ir_Tcl.cpp:206
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Tcl.cpp:200
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
const uint8_t kTcl112AcBitLightOffset
Definition: ir_Tcl.h:52
+
const uint16_t kTcl112AcOneSpace
Definition: ir_Tcl.h:26
+
std::string String
Definition: IRremoteESP8266.h:1093
+
void stateReset(void)
Reset the internal state of the emulation. (On, Cool, 24C)
Definition: ir_Tcl.cpp:90
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Tcl.cpp:132
+
Class for handling detailed TCL A/C messages.
Definition: ir_Tcl.h:63
+
void checksum(const uint16_t length=kTcl112AcStateLength)
Calculate & set the checksum for the current internal state of the remote.
Definition: ir_Tcl.cpp:75
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Tcl.cpp:335
+ +
IRsend _irsend
Instance of the IR send class.
Definition: ir_Tcl.h:115
+
void setTemp(const float celsius)
Set the temperature.
Definition: ir_Tcl.cpp:160
+
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_Tcl.cpp:100
+
void setLight(const bool on)
Set the Light (LED/Display) setting of the A/C.
Definition: ir_Tcl.cpp:230
+
const uint8_t kTcl112AcHalfDegreeOffset
Definition: ir_Tcl.h:46
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Tcl.cpp:120
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Tcl.h:73
+
const uint32_t kTcl112AcGap
Definition: ir_Tcl.h:28
+
static bool validChecksum(uint8_t state[], const uint16_t length=kTcl112AcStateLength)
Verify the checksum is valid for a given state.
Definition: ir_Tcl.cpp:85
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Tcl.cpp:52
+
const uint8_t kTcl112AcSwingVOn
Definition: ir_Tcl.h:57
+
const uint8_t kTcl112AcAuto
Definition: ir_Tcl.h:37
+
const uint16_t kTcl112AcDefaultRepeat
Definition: IRremoteESP8266.h:996
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Tcl.cpp:324
+
const float kTcl112AcTempMax
Definition: ir_Tcl.h:47
+
const uint16_t kTcl112AcHdrMark
Definition: ir_Tcl.h:23
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Tcl.cpp:140
+
const uint8_t kTcl112AcBitHealthOffset
Definition: ir_Tcl.h:53
+
const uint8_t kTcl112AcFanAuto
Definition: ir_Tcl.h:41
+
const uint8_t kTcl112AcModeSize
Definition: ir_Tcl.h:38
+
const uint8_t kTcl112AcSwingVSize
Definition: ir_Tcl.h:56
+
const uint8_t kTcl112AcCool
Definition: ir_Tcl.h:35
+
float getTemp(void)
Get the current temperature setting.
Definition: ir_Tcl.cpp:175
+
void on(void)
Set the requested power state of the A/C to on.
Definition: ir_Tcl.cpp:113
+
const uint8_t kTcl112AcFanSize
Definition: ir_Tcl.h:40
+ +
const uint8_t kTcl112AcPowerOffset
Definition: ir_Tcl.h:50
+
void setHealth(const bool on)
Set the Health (Filter) setting of the A/C.
Definition: ir_Tcl.cpp:218
+
void off(void)
Set the requested power state of the A/C to off.
Definition: ir_Tcl.cpp:116
+
void setRaw(const uint8_t new_code[], const uint16_t length=kTcl112AcStateLength)
Set the internal state from a valid code for this protocol.
Definition: ir_Tcl.cpp:108
+
const uint8_t kTcl112AcSwingVOff
Definition: ir_Tcl.h:58
+
void setFan(const uint8_t speed)
Set the speed of the fan.
Definition: ir_Tcl.cpp:185
+
const uint8_t kTcl112AcHdrMarkTolerance
Definition: ir_Tcl.h:30
+
uint8_t remote_state[kTcl112AcStateLength]
The State in IR code form.
Definition: ir_Tcl.h:121
+
const uint8_t kTcl112AcDry
Definition: ir_Tcl.h:34
+
const uint8_t kTcl112AcFanHigh
Definition: ir_Tcl.h:44
+
const uint16_t kTcl112AcStateLength
Definition: IRremoteESP8266.h:994
+
const uint8_t kTcl112AcFan
Definition: ir_Tcl.h:36
+
const uint8_t kTcl112AcBitTurboOffset
Definition: ir_Tcl.h:59
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Tcl.cpp:126
+
const uint8_t kTcl112AcBitEconoOffset
Definition: ir_Tcl.h:51
+
const uint16_t kTcl112AcZeroSpace
Definition: ir_Tcl.h:27
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Tcl.cpp:311
+
void setTurbo(const bool on)
Set the Turbo setting of the A/C.
Definition: ir_Tcl.cpp:267
+
IRTcl112Ac(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Tcl.cpp:47
+
bool getTurbo(void)
Get the Turbo setting of the A/C.
Definition: ir_Tcl.cpp:277
+
const uint8_t kTcl112AcTolerance
Definition: ir_Tcl.h:31
+
const uint8_t kTcl112AcHeat
Definition: ir_Tcl.h:33
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
bool getSwingVertical(void)
Get the vertical swing setting of the A/C.
Definition: ir_Tcl.cpp:261
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Teco_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Teco_8cpp.html new file mode 100644 index 000000000..56e288060 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Teco_8cpp.html @@ -0,0 +1,188 @@ + + + + + + + +IRremoteESP8266: src/ir_Teco.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Teco.cpp File Reference
+
+
+ +

Support for Teco protocols. +More...

+ + + + + + + + + + + + + + +

+Variables

const uint16_t kTecoHdrMark = 9000
 
const uint16_t kTecoHdrSpace = 4440
 
const uint16_t kTecoBitMark = 620
 
const uint16_t kTecoOneSpace = 1650
 
const uint16_t kTecoZeroSpace = 580
 
const uint32_t kTecoGap = kDefaultMessageGap
 
+

Detailed Description

+

Support for Teco protocols.

+

Variable Documentation

+ +

◆ kTecoBitMark

+ +
+
+ + + + +
const uint16_t kTecoBitMark = 620
+
+ +
+
+ +

◆ kTecoGap

+ +
+
+ + + + +
const uint32_t kTecoGap = kDefaultMessageGap
+
+ +
+
+ +

◆ kTecoHdrMark

+ +
+
+ + + + +
const uint16_t kTecoHdrMark = 9000
+
+ +
+
+ +

◆ kTecoHdrSpace

+ +
+
+ + + + +
const uint16_t kTecoHdrSpace = 4440
+
+ +
+
+ +

◆ kTecoOneSpace

+ +
+
+ + + + +
const uint16_t kTecoOneSpace = 1650
+
+ +
+
+ +

◆ kTecoZeroSpace

+ +
+
+ + + + +
const uint16_t kTecoZeroSpace = 580
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Teco_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Teco_8h.html new file mode 100644 index 000000000..a387292b9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Teco_8h.html @@ -0,0 +1,565 @@ + + + + + + + +IRremoteESP8266: src/ir_Teco.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Teco.h File Reference
+
+
+ +

Support for Teco protocols. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRTecoAc
 Class for handling detailed Teco A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kTecoAuto = 0
 
const uint8_t kTecoCool = 1
 
const uint8_t kTecoDry = 2
 
const uint8_t kTecoFan = 3
 
const uint8_t kTecoHeat = 4
 
const uint8_t kTecoFanAuto = 0
 
const uint8_t kTecoFanLow = 1
 
const uint8_t kTecoFanMed = 2
 
const uint8_t kTecoFanHigh = 3
 
const uint8_t kTecoMinTemp = 16
 
const uint8_t kTecoMaxTemp = 30
 
const uint8_t kTecoModeOffset = 0
 
const uint8_t kTecoPowerOffset = 3
 
const uint8_t kTecoFanOffset = 4
 
const uint8_t kTecoFanSize = 2
 
const uint8_t kTecoSwingOffset = 6
 
const uint8_t kTecoSleepOffset = 7
 
const uint8_t kTecoTempOffset = 8
 
const uint8_t kTecoTempSize = 4
 
const uint8_t kTecoTimerHalfHourOffset = 12
 
const uint8_t kTecoTimerTensHoursOffset = 13
 
const uint8_t kTecoTimerTensHoursSize = 2
 
const uint8_t kTecoTimerOnOffset = 15
 
const uint8_t kTecoTimerUnitHoursOffset = 16
 
const uint8_t kTecoTimerUnitHoursSize = 4
 
const uint8_t kTecoHumidOffset = 20
 
const uint8_t kTecoLightOffset = 21
 
const uint8_t kTecoSaveOffset = 23
 
const uint64_t kTecoReset = 0b01001010000000000000010000000000000
 
+

Detailed Description

+

Support for Teco protocols.

+

Variable Documentation

+ +

◆ kTecoAuto

+ +
+
+ + + + +
const uint8_t kTecoAuto = 0
+
+ +
+
+ +

◆ kTecoCool

+ +
+
+ + + + +
const uint8_t kTecoCool = 1
+
+ +
+
+ +

◆ kTecoDry

+ +
+
+ + + + +
const uint8_t kTecoDry = 2
+
+ +
+
+ +

◆ kTecoFan

+ +
+
+ + + + +
const uint8_t kTecoFan = 3
+
+ +
+
+ +

◆ kTecoFanAuto

+ +
+
+ + + + +
const uint8_t kTecoFanAuto = 0
+
+ +
+
+ +

◆ kTecoFanHigh

+ +
+
+ + + + +
const uint8_t kTecoFanHigh = 3
+
+ +
+
+ +

◆ kTecoFanLow

+ +
+
+ + + + +
const uint8_t kTecoFanLow = 1
+
+ +
+
+ +

◆ kTecoFanMed

+ +
+
+ + + + +
const uint8_t kTecoFanMed = 2
+
+ +
+
+ +

◆ kTecoFanOffset

+ +
+
+ + + + +
const uint8_t kTecoFanOffset = 4
+
+ +
+
+ +

◆ kTecoFanSize

+ +
+
+ + + + +
const uint8_t kTecoFanSize = 2
+
+ +
+
+ +

◆ kTecoHeat

+ +
+
+ + + + +
const uint8_t kTecoHeat = 4
+
+ +
+
+ +

◆ kTecoHumidOffset

+ +
+
+ + + + +
const uint8_t kTecoHumidOffset = 20
+
+ +
+
+ +

◆ kTecoLightOffset

+ +
+
+ + + + +
const uint8_t kTecoLightOffset = 21
+
+ +
+
+ +

◆ kTecoMaxTemp

+ +
+
+ + + + +
const uint8_t kTecoMaxTemp = 30
+
+ +
+
+ +

◆ kTecoMinTemp

+ +
+
+ + + + +
const uint8_t kTecoMinTemp = 16
+
+ +
+
+ +

◆ kTecoModeOffset

+ +
+
+ + + + +
const uint8_t kTecoModeOffset = 0
+
+ +
+
+ +

◆ kTecoPowerOffset

+ +
+
+ + + + +
const uint8_t kTecoPowerOffset = 3
+
+ +
+
+ +

◆ kTecoReset

+ +
+
+ + + + +
const uint64_t kTecoReset = 0b01001010000000000000010000000000000
+
+ +
+
+ +

◆ kTecoSaveOffset

+ +
+
+ + + + +
const uint8_t kTecoSaveOffset = 23
+
+ +
+
+ +

◆ kTecoSleepOffset

+ +
+
+ + + + +
const uint8_t kTecoSleepOffset = 7
+
+ +
+
+ +

◆ kTecoSwingOffset

+ +
+
+ + + + +
const uint8_t kTecoSwingOffset = 6
+
+ +
+
+ +

◆ kTecoTempOffset

+ +
+
+ + + + +
const uint8_t kTecoTempOffset = 8
+
+ +
+
+ +

◆ kTecoTempSize

+ +
+
+ + + + +
const uint8_t kTecoTempSize = 4
+
+ +
+
+ +

◆ kTecoTimerHalfHourOffset

+ +
+
+ + + + +
const uint8_t kTecoTimerHalfHourOffset = 12
+
+ +
+
+ +

◆ kTecoTimerOnOffset

+ +
+
+ + + + +
const uint8_t kTecoTimerOnOffset = 15
+
+ +
+
+ +

◆ kTecoTimerTensHoursOffset

+ +
+
+ + + + +
const uint8_t kTecoTimerTensHoursOffset = 13
+
+ +
+
+ +

◆ kTecoTimerTensHoursSize

+ +
+
+ + + + +
const uint8_t kTecoTimerTensHoursSize = 2
+
+ +
+
+ +

◆ kTecoTimerUnitHoursOffset

+ +
+
+ + + + +
const uint8_t kTecoTimerUnitHoursOffset = 16
+
+ +
+
+ +

◆ kTecoTimerUnitHoursSize

+ +
+
+ + + + +
const uint8_t kTecoTimerUnitHoursSize = 4
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Teco_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Teco_8h_source.html new file mode 100644 index 000000000..ea0e37a5f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Teco_8h_source.html @@ -0,0 +1,324 @@ + + + + + + + +IRremoteESP8266: src/ir_Teco.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Teco.h
+
+
+Go to the documentation of this file.
1 // Copyright 2019 Fabien Valthier
+
2 
+
5 
+
6 // Supports:
+
7 // Brand: Alaska, Model: SAC9010QC A/C
+
8 // Brand: Alaska, Model: SAC9010QC remote
+
9 
+
10 #ifndef IR_TECO_H_
+
11 #define IR_TECO_H_
+
12 
+
13 #ifndef UNIT_TEST
+
14 #include <Arduino.h>
+
15 #endif
+
16 #include "IRremoteESP8266.h"
+
17 #include "IRsend.h"
+
18 #ifdef UNIT_TEST
+
19 #include "IRsend_test.h"
+
20 #endif
+
21 
+
22 // Constants.
+
23 const uint8_t kTecoAuto = 0;
+
24 const uint8_t kTecoCool = 1;
+
25 const uint8_t kTecoDry = 2;
+
26 const uint8_t kTecoFan = 3;
+
27 const uint8_t kTecoHeat = 4;
+
28 const uint8_t kTecoFanAuto = 0; // 0b00
+
29 const uint8_t kTecoFanLow = 1; // 0b01
+
30 const uint8_t kTecoFanMed = 2; // 0b10
+
31 const uint8_t kTecoFanHigh = 3; // 0b11
+
32 const uint8_t kTecoMinTemp = 16; // 16C
+
33 const uint8_t kTecoMaxTemp = 30; // 30C
+
34 
+
35 const uint8_t kTecoModeOffset = 0;
+
36 const uint8_t kTecoPowerOffset = 3;
+
37 const uint8_t kTecoFanOffset = 4;
+
38 const uint8_t kTecoFanSize = 2; // Nr. of bits
+
39 const uint8_t kTecoSwingOffset = 6;
+
40 const uint8_t kTecoSleepOffset = 7;
+
41 const uint8_t kTecoTempOffset = 8;
+
42 const uint8_t kTecoTempSize = 4; // Nr. of bits
+
43 const uint8_t kTecoTimerHalfHourOffset = 12;
+
44 const uint8_t kTecoTimerTensHoursOffset = 13;
+
45 const uint8_t kTecoTimerTensHoursSize = 2; // Nr. of bits
+
46 const uint8_t kTecoTimerOnOffset = 15;
+
47 const uint8_t kTecoTimerUnitHoursOffset = 16;
+
48 const uint8_t kTecoTimerUnitHoursSize = 4; // Nr. of bits
+
49 const uint8_t kTecoHumidOffset = 20;
+
50 const uint8_t kTecoLightOffset = 21;
+
51 const uint8_t kTecoSaveOffset = 23;
+
52 const uint64_t kTecoReset = 0b01001010000000000000010000000000000;
+
53 /*
+
54  (header mark and space)
+
55  Teco AC map read and to be sent in LSB with number of bits
+
56 
+
57  byte 0 = Cst 0x02
+
58  byte 1 = Cst 0x50
+
59  b6-7 = "AIR" 0, 1, 2 (Not Implemented)
+
60  byte 2:
+
61  b0 = Save
+
62  b1 = "Tree with bubbles" / Filter?? (Not Implemented)
+
63  b2 = Light/LED.
+
64  b3 = Humid
+
65  b4-7 = Timer hours (unit, not thenth)
+
66  hours:
+
67  0000 (0) = +0 hour
+
68  0001 (1) = +1 hour
+
69  ...
+
70  1001 (9) = +9 hours
+
71  byte 3: = timer and Temperature
+
72  b0 = Timer (1 = On, 0 = Off)
+
73  b1-2 = Timer - number of 10hours
+
74  10Hours:
+
75  00 = 0 * 10hours of timer
+
76  01 = 1 * 10 hours of timer
+
77  10 = 2 * 10hours of timer
+
78  b3 = Timer - half hour (1=half hour on, 0 = round hour)
+
79  b4-7: Degrees C.
+
80  0000 (0) = 16C
+
81  0001 (1) = 17C
+
82  0010 (2) = 18C
+
83  ...
+
84  1101 (13) = 29C
+
85  1110 (14) = 30C
+
86  byte 4: Basics
+
87  b0 = Sleep Mode (1 = On, 0 = Off)
+
88  b1 = Vent swing (1 = On, 0 = Off)
+
89  b2-3 = Fan
+
90  Fan:
+
91  00 = Auto
+
92  01 = Fan 1
+
93  10 = Fan 2
+
94  11 = Fan 3 or higher
+
95  b4 = Power Status (1 = On, 0 = Off)
+
96  b5-7 = Modes LSB first
+
97  Modes:
+
98  000 = Auto (temp = 25C)
+
99  001 = Cool
+
100  010 = Dry (temp = 25C, but not shown)
+
101  011 = Fan
+
102  100 = Heat
+
103 */
+
104 
+
105 // Classes
+
107 class IRTecoAc {
+
108  public:
+
109  explicit IRTecoAc(const uint16_t pin, const bool inverted = false,
+
110  const bool use_modulation = true);
+
111  void stateReset(void);
+
112 #if SEND_TECO
+
113  void send(const uint16_t repeat = kTecoDefaultRepeat);
+
118  int8_t calibrate(void) { return _irsend.calibrate(); }
+
119 #endif // SEND_TECO
+
120  void begin(void);
+
121  void on(void);
+
122  void off(void);
+
123 
+
124  void setPower(const bool on);
+
125  bool getPower(void);
+
126 
+
127  void setTemp(const uint8_t temp);
+
128  uint8_t getTemp(void);
+
129 
+
130  void setFan(const uint8_t fan);
+
131  uint8_t getFan(void);
+
132 
+
133  void setMode(const uint8_t mode);
+
134  uint8_t getMode(void);
+
135 
+
136  void setSwing(const bool on);
+
137  bool getSwing(void);
+
138 
+
139  void setSleep(const bool on);
+
140  bool getSleep(void);
+
141 
+
142  void setLight(const bool on);
+
143  bool getLight(void);
+
144 
+
145  void setHumid(const bool on);
+
146  bool getHumid(void);
+
147 
+
148  void setSave(const bool on);
+
149  bool getSave(void);
+
150 
+
151  uint16_t getTimer(void);
+
152  void setTimer(const uint16_t mins);
+
153 
+
154  uint64_t getRaw(void);
+
155  void setRaw(const uint64_t new_code);
+
156 
+
157  uint8_t convertMode(const stdAc::opmode_t mode);
+
158  uint8_t convertFan(const stdAc::fanspeed_t speed);
+
159  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
160  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
161  stdAc::state_t toCommon(void);
+
162  String toString(void);
+
163 #ifndef UNIT_TEST
+
164 
+
165  private:
+ +
167 #else // UNIT_TEST
+
168  IRsendTest _irsend;
+
170 #endif // UNIT_TEST
+
172  uint64_t remote_state;
+
173  bool getTimerEnabled(void);
+
174 };
+
175 
+
176 #endif // IR_TECO_H_
+
+
bool getSwing(void)
Get the (vertical) swing setting of the A/C.
Definition: ir_Teco.cpp:163
+
const uint8_t kTecoFanMed
Definition: ir_Teco.h:30
+
bool getHumid(void)
Get the Humid setting of the A/C.
Definition: ir_Teco.cpp:199
+
const uint8_t kTecoTempOffset
Definition: ir_Teco.h:41
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Teco.cpp:94
+
const uint8_t kTecoPowerOffset
Definition: ir_Teco.h:36
+
const uint64_t kTecoReset
Definition: ir_Teco.h:52
+
bool getTimerEnabled(void)
Is the timer function enabled?
Definition: ir_Teco.cpp:217
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Teco.cpp:283
+
void off(void)
Set the requested power state of the A/C to off.
Definition: ir_Teco.cpp:84
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
bool getSleep(void)
Get the Sleep setting of the A/C.
Definition: ir_Teco.cpp:175
+
const uint8_t kTecoModeOffset
Definition: ir_Teco.h:35
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Teco.cpp:256
+
uint16_t getTimer(void)
Get the timer time for when the A/C unit will switch power state.
Definition: ir_Teco.cpp:223
+
const uint8_t kTecoTempSize
Definition: ir_Teco.h:42
+
const uint8_t kTecoSleepOffset
Definition: ir_Teco.h:40
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Teco.h:118
+ +
const uint8_t kTecoMinTemp
Definition: ir_Teco.h:32
+
void setRaw(const uint64_t new_code)
Set the internal state from a valid code for this protocol.
Definition: ir_Teco.cpp:78
+
IRTecoAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Teco.cpp:51
+
const uint8_t kTecoMaxTemp
Definition: ir_Teco.h:33
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
void on(void)
Set the requested power state of the A/C to on.
Definition: ir_Teco.cpp:81
+
const uint8_t kTecoDry
Definition: ir_Teco.h:25
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
const uint8_t kTecoHeat
Definition: ir_Teco.h:27
+
const uint8_t kTecoTimerTensHoursOffset
Definition: ir_Teco.h:44
+
const uint8_t kTecoFanOffset
Definition: ir_Teco.h:37
+
std::string String
Definition: IRremoteESP8266.h:1093
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Teco.cpp:88
+
void setSwing(const bool on)
Set the (vertical) swing setting of the A/C.
Definition: ir_Teco.cpp:157
+
const uint8_t kTecoSaveOffset
Definition: ir_Teco.h:51
+
const uint8_t kTecoTimerUnitHoursOffset
Definition: ir_Teco.h:47
+ +
void setHumid(const bool on)
Set the Humid setting of the A/C.
Definition: ir_Teco.cpp:193
+
void setTimer(const uint16_t mins)
Set the timer for when the A/C unit will switch power state.
Definition: ir_Teco.cpp:239
+
const uint8_t kTecoFanLow
Definition: ir_Teco.h:29
+
void setSleep(const bool on)
Set the Sleep setting of the A/C.
Definition: ir_Teco.cpp:169
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Teco.cpp:56
+
const uint16_t kTecoDefaultRepeat
Definition: IRremoteESP8266.h:998
+
const uint8_t kTecoFanSize
Definition: ir_Teco.h:38
+
const uint8_t kTecoFanAuto
Definition: ir_Teco.h:28
+
bool getLight(void)
Get the Light (LED/Display) setting of the A/C.
Definition: ir_Teco.cpp:187
+
const uint8_t kTecoCool
Definition: ir_Teco.h:24
+
const uint8_t kTecoTimerTensHoursSize
Definition: ir_Teco.h:45
+
bool getSave(void)
Get the Save setting of the A/C.
Definition: ir_Teco.cpp:211
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Teco.cpp:334
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Teco.cpp:110
+
const uint8_t kTecoTimerUnitHoursSize
Definition: ir_Teco.h:48
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Teco.cpp:100
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Teco.cpp:136
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Teco.cpp:296
+
void setSave(const bool on)
Set the Save setting of the A/C.
Definition: ir_Teco.cpp:205
+
const uint8_t kTecoHumidOffset
Definition: ir_Teco.h:49
+
const uint8_t kTecoSwingOffset
Definition: ir_Teco.h:39
+
void stateReset(void)
Reset the internal state of the emulation.
Definition: ir_Teco.cpp:68
+
uint64_t getRaw(void)
Get a copy of the internal state/code for this protocol.
Definition: ir_Teco.cpp:74
+
const uint8_t kTecoLightOffset
Definition: ir_Teco.h:50
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Teco.cpp:130
+
const uint8_t kTecoFan
Definition: ir_Teco.h:26
+
const uint8_t kTecoTimerOnOffset
Definition: ir_Teco.h:46
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Teco.cpp:151
+
Class for handling detailed Teco A/C messages.
Definition: ir_Teco.h:107
+
uint64_t remote_state
The state of the IR remote in IR code form.
Definition: ir_Teco.h:172
+
uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Teco.cpp:269
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Teco.cpp:307
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Teco.h:166
+
void setLight(const bool on)
Set the Light (LED/Display) setting of the A/C.
Definition: ir_Teco.cpp:181
+
void send(const uint16_t repeat=kTecoDefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Teco.cpp:61
+
const uint8_t kTecoFanHigh
Definition: ir_Teco.h:31
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
const uint8_t kTecoAuto
Definition: ir_Teco.h:23
+
void setFan(const uint8_t fan)
Set the speed of the fan.
Definition: ir_Teco.cpp:116
+
const uint8_t kTecoTimerHalfHourOffset
Definition: ir_Teco.h:43
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Toshiba_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Toshiba_8cpp.html new file mode 100644 index 000000000..29efab1fc --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Toshiba_8cpp.html @@ -0,0 +1,191 @@ + + + + + + + +IRremoteESP8266: src/ir_Toshiba.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Toshiba.cpp File Reference
+
+
+ +

Support for Toshiba protocols. +More...

+ + + + + + + + + + + + + + +

+Variables

const uint16_t kToshibaAcHdrMark = 4400
 
const uint16_t kToshibaAcHdrSpace = 4300
 
const uint16_t kToshibaAcBitMark = 543
 
const uint16_t kToshibaAcOneSpace = 1623
 
const uint16_t kToshibaAcZeroSpace = 472
 
const uint16_t kToshibaAcMinGap = 7048
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kToshibaAcBitMark

+ +
+
+ + + + +
const uint16_t kToshibaAcBitMark = 543
+
+ +
+
+ +

◆ kToshibaAcHdrMark

+ +
+
+ + + + +
const uint16_t kToshibaAcHdrMark = 4400
+
+ +
+
+ +

◆ kToshibaAcHdrSpace

+ +
+
+ + + + +
const uint16_t kToshibaAcHdrSpace = 4300
+
+ +
+
+ +

◆ kToshibaAcMinGap

+ +
+
+ + + + +
const uint16_t kToshibaAcMinGap = 7048
+
+ +
+
+ +

◆ kToshibaAcOneSpace

+ +
+
+ + + + +
const uint16_t kToshibaAcOneSpace = 1623
+
+ +
+
+ +

◆ kToshibaAcZeroSpace

+ +
+
+ + + + +
const uint16_t kToshibaAcZeroSpace = 472
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Toshiba_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Toshiba_8h.html new file mode 100644 index 000000000..a48d5a462 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Toshiba_8h.html @@ -0,0 +1,376 @@ + + + + + + + +IRremoteESP8266: src/ir_Toshiba.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Toshiba.h File Reference
+
+
+ +

Support for Toshiba protocols. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRToshibaAC
 Class for handling detailed Toshiba A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kToshibaAcModeOffset = 0
 
const uint8_t kToshibaAcModeSize = 2
 
const uint8_t kToshibaAcAuto = 0
 
const uint8_t kToshibaAcCool = 1
 
const uint8_t kToshibaAcDry = 2
 
const uint8_t kToshibaAcHeat = 3
 
const uint8_t kToshibaAcPowerOffset = 2
 
const uint8_t kToshibaAcFanOffset = 5
 
const uint8_t kToshibaAcFanSize = 3
 
const uint8_t kToshibaAcFanAuto = 0b000
 
const uint8_t kToshibaAcFanMin = 0b001
 
const uint8_t kToshibaAcFanMed = 0b011
 
const uint8_t kToshibaAcFanMax = 0b101
 
const uint8_t kToshibaAcTempOffset = 4
 
const uint8_t kToshibaAcTempSize = 4
 
const uint8_t kToshibaAcMinTemp = 17
 
const uint8_t kToshibaAcMaxTemp = 30
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kToshibaAcAuto

+ +
+
+ + + + +
const uint8_t kToshibaAcAuto = 0
+
+ +
+
+ +

◆ kToshibaAcCool

+ +
+
+ + + + +
const uint8_t kToshibaAcCool = 1
+
+ +
+
+ +

◆ kToshibaAcDry

+ +
+
+ + + + +
const uint8_t kToshibaAcDry = 2
+
+ +
+
+ +

◆ kToshibaAcFanAuto

+ +
+
+ + + + +
const uint8_t kToshibaAcFanAuto = 0b000
+
+ +
+
+ +

◆ kToshibaAcFanMax

+ +
+
+ + + + +
const uint8_t kToshibaAcFanMax = 0b101
+
+ +
+
+ +

◆ kToshibaAcFanMed

+ +
+
+ + + + +
const uint8_t kToshibaAcFanMed = 0b011
+
+ +
+
+ +

◆ kToshibaAcFanMin

+ +
+
+ + + + +
const uint8_t kToshibaAcFanMin = 0b001
+
+ +
+
+ +

◆ kToshibaAcFanOffset

+ +
+
+ + + + +
const uint8_t kToshibaAcFanOffset = 5
+
+ +
+
+ +

◆ kToshibaAcFanSize

+ +
+
+ + + + +
const uint8_t kToshibaAcFanSize = 3
+
+ +
+
+ +

◆ kToshibaAcHeat

+ +
+
+ + + + +
const uint8_t kToshibaAcHeat = 3
+
+ +
+
+ +

◆ kToshibaAcMaxTemp

+ +
+
+ + + + +
const uint8_t kToshibaAcMaxTemp = 30
+
+ +
+
+ +

◆ kToshibaAcMinTemp

+ +
+
+ + + + +
const uint8_t kToshibaAcMinTemp = 17
+
+ +
+
+ +

◆ kToshibaAcModeOffset

+ +
+
+ + + + +
const uint8_t kToshibaAcModeOffset = 0
+
+ +
+
+ +

◆ kToshibaAcModeSize

+ +
+
+ + + + +
const uint8_t kToshibaAcModeSize = 2
+
+ +
+
+ +

◆ kToshibaAcPowerOffset

+ +
+
+ + + + +
const uint8_t kToshibaAcPowerOffset = 2
+
+ +
+
+ +

◆ kToshibaAcTempOffset

+ +
+
+ + + + +
const uint8_t kToshibaAcTempOffset = 4
+
+ +
+
+ +

◆ kToshibaAcTempSize

+ +
+
+ + + + +
const uint8_t kToshibaAcTempSize = 4
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Toshiba_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Toshiba_8h_source.html new file mode 100644 index 000000000..5eac89ce6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Toshiba_8h_source.html @@ -0,0 +1,238 @@ + + + + + + + +IRremoteESP8266: src/ir_Toshiba.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Toshiba.h
+
+
+Go to the documentation of this file.
1 // Copyright 2017 David Conran
+
2 
+
7 
+
8 // Supports:
+
9 // Brand: Toshiba, Model: RAS-B13N3KV2
+
10 // Brand: Toshiba, Model: Akita EVO II
+
11 // Brand: Toshiba, Model: RAS-B13N3KVP-E
+
12 // Brand: Toshiba, Model: RAS 18SKP-ES
+
13 // Brand: Toshiba, Model: WH-TA04NE
+
14 // Brand: Toshiba, Model: WC-L03SE
+
15 
+
16 #ifndef IR_TOSHIBA_H_
+
17 #define IR_TOSHIBA_H_
+
18 
+
19 #define __STDC_LIMIT_MACROS
+
20 #include <stdint.h>
+
21 #ifdef ARDUINO
+
22 #include <Arduino.h>
+
23 #endif
+
24 #include "IRremoteESP8266.h"
+
25 #include "IRsend.h"
+
26 #ifdef UNIT_TEST
+
27 #include "IRsend_test.h"
+
28 #endif
+
29 
+
30 // Constants
+
31 const uint8_t kToshibaAcModeOffset = 0;
+
32 const uint8_t kToshibaAcModeSize = 2; // Nr. of bits
+
33 const uint8_t kToshibaAcAuto = 0;
+
34 const uint8_t kToshibaAcCool = 1;
+
35 const uint8_t kToshibaAcDry = 2;
+
36 const uint8_t kToshibaAcHeat = 3;
+
37 const uint8_t kToshibaAcPowerOffset = 2;
+
38 const uint8_t kToshibaAcFanOffset = 5;
+
39 const uint8_t kToshibaAcFanSize = 3; // Nr. of bits
+
40 const uint8_t kToshibaAcFanAuto = 0b000;
+
41 const uint8_t kToshibaAcFanMin = 0b001;
+
42 const uint8_t kToshibaAcFanMed = 0b011;
+
43 const uint8_t kToshibaAcFanMax = 0b101;
+
44 const uint8_t kToshibaAcTempOffset = 4;
+
45 const uint8_t kToshibaAcTempSize = 4; // Nr. of bits
+
46 const uint8_t kToshibaAcMinTemp = 17; // 17C
+
47 const uint8_t kToshibaAcMaxTemp = 30; // 30C
+
48 
+
49 // Legacy defines. (Deperecated)
+
50 #define TOSHIBA_AC_AUTO kToshibaAcAuto
+
51 #define TOSHIBA_AC_COOL kToshibaAcCool
+
52 #define TOSHIBA_AC_DRY kToshibaAcDry
+
53 #define TOSHIBA_AC_HEAT kToshibaAcHeat
+
54 #define TOSHIBA_AC_POWER kToshibaAcPower
+
55 #define TOSHIBA_AC_FAN_AUTO kToshibaAcFanAuto
+
56 #define TOSHIBA_AC_FAN_MAX kToshibaAcFanMax
+
57 #define TOSHIBA_AC_MIN_TEMP kToshibaAcMinTemp
+
58 #define TOSHIBA_AC_MAX_TEMP kToshibaAcMaxTemp
+
59 
+
60 // Classes
+
62 class IRToshibaAC {
+
63  public:
+
64  explicit IRToshibaAC(const uint16_t pin, const bool inverted = false,
+
65  const bool use_modulation = true);
+
66  void stateReset(void);
+
67 #if SEND_TOSHIBA_AC
+
68  void send(const uint16_t repeat = kToshibaACMinRepeat);
+
73  int8_t calibrate(void) { return _irsend.calibrate(); }
+
74 #endif // SEND_TOSHIBA_AC
+
75  void begin(void);
+
76  void on(void);
+
77  void off(void);
+
78  void setPower(const bool on);
+
79  bool getPower(void);
+
80  void setTemp(const uint8_t degrees);
+
81  uint8_t getTemp(void);
+
82  void setFan(const uint8_t speed);
+
83  uint8_t getFan(void);
+
84  void setMode(const uint8_t mode);
+
85  uint8_t getMode(const bool useRaw = false);
+
86  void setRaw(const uint8_t newState[]);
+
87  uint8_t* getRaw(void);
+
88  static bool validChecksum(const uint8_t state[],
+
89  const uint16_t length = kToshibaACStateLength);
+
90  uint8_t convertMode(const stdAc::opmode_t mode);
+
91  uint8_t convertFan(const stdAc::fanspeed_t speed);
+
92  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
93  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+ +
95  String toString(void);
+
96 #ifndef UNIT_TEST
+
97 
+
98  private:
+ +
100 #else // UNIT_TEST
+
101  IRsendTest _irsend;
+
103 #endif // UNIT_TEST
+ +
106  void checksum(const uint16_t length = kToshibaACStateLength);
+
107  static uint8_t calcChecksum(const uint8_t state[],
+
108  const uint16_t length = kToshibaACStateLength);
+
109  uint8_t mode_state;
+
110 };
+
111 
+
112 #endif // IR_TOSHIBA_H_
+
+
void off(void)
Set the requested power state of the A/C to off.
Definition: ir_Toshiba.cpp:134
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Toshiba.cpp:249
+
Class for handling detailed Toshiba A/C messages.
Definition: ir_Toshiba.h:62
+
const uint8_t kToshibaAcCool
Definition: ir_Toshiba.h:34
+
static uint8_t calcChecksum(const uint8_t state[], const uint16_t length=kToshibaACStateLength)
Calculate the checksum for a given state.
Definition: ir_Toshiba.cpp:101
+
void on(void)
Set the requested power state of the A/C to on.
Definition: ir_Toshiba.cpp:131
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Toshiba.cpp:222
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
const uint8_t kToshibaAcFanAuto
Definition: ir_Toshiba.h:40
+
void send(const uint16_t repeat=kToshibaACMinRepeat)
Send the current internal state as an IR message.
Definition: ir_Toshiba.cpp:78
+
const uint8_t kToshibaAcModeOffset
Definition: ir_Toshiba.h:31
+
void setFan(const uint8_t speed)
Set the speed of the fan.
Definition: ir_Toshiba.cpp:172
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Toshiba.cpp:274
+
const uint8_t kToshibaAcMinTemp
Definition: ir_Toshiba.h:46
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Toshiba.h:99
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Toshiba.h:73
+ +
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_Toshiba.cpp:85
+
void checksum(const uint16_t length=kToshibaACStateLength)
Calculate & set the checksum for the current internal state of the remote.
Definition: ir_Toshiba.cpp:124
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Toshiba.cpp:150
+
const uint8_t kToshibaAcPowerOffset
Definition: ir_Toshiba.h:37
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Toshiba.cpp:300
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Toshiba.cpp:138
+
std::string String
Definition: IRremoteESP8266.h:1093
+
IRToshibaAC(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Toshiba.cpp:59
+
const uint8_t kToshibaAcFanMed
Definition: ir_Toshiba.h:42
+ +
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Toshiba.cpp:73
+
void stateReset(void)
Reset the state of the remote to a known good state/sequence.
Definition: ir_Toshiba.cpp:65
+
const uint8_t kToshibaAcTempSize
Definition: ir_Toshiba.h:45
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Toshiba.cpp:165
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Toshiba.cpp:261
+
const uint8_t kToshibaAcHeat
Definition: ir_Toshiba.h:36
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Toshiba.cpp:203
+
const uint8_t kToshibaAcModeSize
Definition: ir_Toshiba.h:32
+
void setRaw(const uint8_t newState[])
Set the internal state from a valid code for this protocol.
Definition: ir_Toshiba.cpp:92
+
const uint16_t kToshibaACMinRepeat
Definition: IRremoteESP8266.h:1001
+
uint8_t getMode(const bool useRaw=false)
Get the operating mode setting of the A/C.
Definition: ir_Toshiba.cpp:193
+
const uint16_t kToshibaACStateLength
Definition: IRremoteESP8266.h:999
+
static bool validChecksum(const uint8_t state[], const uint16_t length=kToshibaACStateLength)
Verify the checksum is valid for a given state.
Definition: ir_Toshiba.cpp:116
+
const uint8_t kToshibaAcFanSize
Definition: ir_Toshiba.h:39
+
const uint8_t kToshibaAcFanOffset
Definition: ir_Toshiba.h:38
+
uint8_t remote_state[kToshibaACStateLength]
The state in IR code form.
Definition: ir_Toshiba.h:105
+
const uint8_t kToshibaAcDry
Definition: ir_Toshiba.h:35
+
uint8_t mode_state
Definition: ir_Toshiba.h:109
+
const uint8_t kToshibaAcAuto
Definition: ir_Toshiba.h:33
+
const uint8_t kToshibaAcMaxTemp
Definition: ir_Toshiba.h:47
+
uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Toshiba.cpp:235
+
void setTemp(const uint8_t degrees)
Set the temperature.
Definition: ir_Toshiba.cpp:156
+
const uint8_t kToshibaAcTempOffset
Definition: ir_Toshiba.h:44
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Toshiba.cpp:183
+
const uint8_t kToshibaAcFanMax
Definition: ir_Toshiba.h:43
+
const uint8_t kToshibaAcFanMin
Definition: ir_Toshiba.h:41
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Trotec_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Trotec_8cpp.html new file mode 100644 index 000000000..3d4b6e325 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Trotec_8cpp.html @@ -0,0 +1,207 @@ + + + + + + + +IRremoteESP8266: src/ir_Trotec.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Trotec.cpp File Reference
+
+
+ +

Support for Trotec protocols. +More...

+ + + + + + + + + + + + + + + + +

+Variables

const uint16_t kTrotecHdrMark = 5952
 
const uint16_t kTrotecHdrSpace = 7364
 
const uint16_t kTrotecBitMark = 592
 
const uint16_t kTrotecOneSpace = 1560
 
const uint16_t kTrotecZeroSpace = 592
 
const uint16_t kTrotecGap = 6184
 
const uint16_t kTrotecGapEnd = 1500
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kTrotecBitMark

+ +
+
+ + + + +
const uint16_t kTrotecBitMark = 592
+
+ +
+
+ +

◆ kTrotecGap

+ +
+
+ + + + +
const uint16_t kTrotecGap = 6184
+
+ +
+
+ +

◆ kTrotecGapEnd

+ +
+
+ + + + +
const uint16_t kTrotecGapEnd = 1500
+
+ +
+
+ +

◆ kTrotecHdrMark

+ +
+
+ + + + +
const uint16_t kTrotecHdrMark = 5952
+
+ +
+
+ +

◆ kTrotecHdrSpace

+ +
+
+ + + + +
const uint16_t kTrotecHdrSpace = 7364
+
+ +
+
+ +

◆ kTrotecOneSpace

+ +
+
+ + + + +
const uint16_t kTrotecOneSpace = 1560
+
+ +
+
+ +

◆ kTrotecZeroSpace

+ +
+
+ + + + +
const uint16_t kTrotecZeroSpace = 592
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Trotec_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Trotec_8h.html new file mode 100644 index 000000000..943ec1243 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Trotec_8h.html @@ -0,0 +1,456 @@ + + + + + + + +IRremoteESP8266: src/ir_Trotec.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Trotec.h File Reference
+
+
+ +

Support for Trotec protocols. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRTrotecESP
 Class for handling detailed Trotec A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kTrotecIntro1 = 0x12
 
const uint8_t kTrotecIntro2 = 0x34
 
const uint8_t kTrotecModeOffset = 0
 
const uint8_t kTrotecModeSize = 2
 
const uint8_t kTrotecAuto = 0
 
const uint8_t kTrotecCool = 1
 
const uint8_t kTrotecDry = 2
 
const uint8_t kTrotecFan = 3
 
const uint8_t kTrotecPowerBitOffset = 3
 
const uint8_t kTrotecFanOffset = 4
 
const uint8_t kTrotecFanSize = 2
 
const uint8_t kTrotecFanLow = 1
 
const uint8_t kTrotecFanMed = 2
 
const uint8_t kTrotecFanHigh = 3
 
const uint8_t kTrotecTempOffset = 0
 
const uint8_t kTrotecTempSize = 4
 
const uint8_t kTrotecMinTemp = 18
 
const uint8_t kTrotecDefTemp = 25
 
const uint8_t kTrotecMaxTemp = 32
 
const uint8_t kTrotecSleepBitOffset = 7
 
const uint8_t kTrotecTimerBitOffset = 6
 
const uint8_t kTrotecMaxTimer = 23
 
+

Detailed Description

+

Variable Documentation

+ +

◆ kTrotecAuto

+ +
+
+ + + + +
const uint8_t kTrotecAuto = 0
+
+ +
+
+ +

◆ kTrotecCool

+ +
+
+ + + + +
const uint8_t kTrotecCool = 1
+
+ +
+
+ +

◆ kTrotecDefTemp

+ +
+
+ + + + +
const uint8_t kTrotecDefTemp = 25
+
+ +
+
+ +

◆ kTrotecDry

+ +
+
+ + + + +
const uint8_t kTrotecDry = 2
+
+ +
+
+ +

◆ kTrotecFan

+ +
+
+ + + + +
const uint8_t kTrotecFan = 3
+
+ +
+
+ +

◆ kTrotecFanHigh

+ +
+
+ + + + +
const uint8_t kTrotecFanHigh = 3
+
+ +
+
+ +

◆ kTrotecFanLow

+ +
+
+ + + + +
const uint8_t kTrotecFanLow = 1
+
+ +
+
+ +

◆ kTrotecFanMed

+ +
+
+ + + + +
const uint8_t kTrotecFanMed = 2
+
+ +
+
+ +

◆ kTrotecFanOffset

+ +
+
+ + + + +
const uint8_t kTrotecFanOffset = 4
+
+ +
+
+ +

◆ kTrotecFanSize

+ +
+
+ + + + +
const uint8_t kTrotecFanSize = 2
+
+ +
+
+ +

◆ kTrotecIntro1

+ +
+
+ + + + +
const uint8_t kTrotecIntro1 = 0x12
+
+ +
+
+ +

◆ kTrotecIntro2

+ +
+
+ + + + +
const uint8_t kTrotecIntro2 = 0x34
+
+ +
+
+ +

◆ kTrotecMaxTemp

+ +
+
+ + + + +
const uint8_t kTrotecMaxTemp = 32
+
+ +
+
+ +

◆ kTrotecMaxTimer

+ +
+
+ + + + +
const uint8_t kTrotecMaxTimer = 23
+
+ +
+
+ +

◆ kTrotecMinTemp

+ +
+
+ + + + +
const uint8_t kTrotecMinTemp = 18
+
+ +
+
+ +

◆ kTrotecModeOffset

+ +
+
+ + + + +
const uint8_t kTrotecModeOffset = 0
+
+ +
+
+ +

◆ kTrotecModeSize

+ +
+
+ + + + +
const uint8_t kTrotecModeSize = 2
+
+ +
+
+ +

◆ kTrotecPowerBitOffset

+ +
+
+ + + + +
const uint8_t kTrotecPowerBitOffset = 3
+
+ +
+
+ +

◆ kTrotecSleepBitOffset

+ +
+
+ + + + +
const uint8_t kTrotecSleepBitOffset = 7
+
+ +
+
+ +

◆ kTrotecTempOffset

+ +
+
+ + + + +
const uint8_t kTrotecTempOffset = 0
+
+ +
+
+ +

◆ kTrotecTempSize

+ +
+
+ + + + +
const uint8_t kTrotecTempSize = 4
+
+ +
+
+ +

◆ kTrotecTimerBitOffset

+ +
+
+ + + + +
const uint8_t kTrotecTimerBitOffset = 6
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Trotec_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Trotec_8h_source.html new file mode 100644 index 000000000..950f39edc --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Trotec_8h_source.html @@ -0,0 +1,270 @@ + + + + + + + +IRremoteESP8266: src/ir_Trotec.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Trotec.h
+
+
+Go to the documentation of this file.
1 // Copyright 2017 stufisher
+
2 // Copyright 2019 crankyoldgit
+
3 
+
8 
+
9 // Supports:
+
10 // Brand: Trotec, Model: PAC 3200 A/C
+
11 // Brand: Duux, Model: Blizzard Smart 10K / DXMA04 A/C
+
12 
+
13 #ifndef IR_TROTEC_H_
+
14 #define IR_TROTEC_H_
+
15 
+
16 #ifndef UNIT_TEST
+
17 #include <Arduino.h>
+
18 #endif
+
19 #include "IRremoteESP8266.h"
+
20 #include "IRsend.h"
+
21 #ifdef UNIT_TEST
+
22 #include "IRsend_test.h"
+
23 #endif
+
24 
+
25 // Constants
+
26 // Byte 0
+
27 const uint8_t kTrotecIntro1 = 0x12;
+
28 
+
29 // Byte 1
+
30 const uint8_t kTrotecIntro2 = 0x34;
+
31 
+
32 // Byte 2
+
33 const uint8_t kTrotecModeOffset = 0;
+
34 const uint8_t kTrotecModeSize = 2; // Nr. of bits
+
35 const uint8_t kTrotecAuto = 0;
+
36 const uint8_t kTrotecCool = 1;
+
37 const uint8_t kTrotecDry = 2;
+
38 const uint8_t kTrotecFan = 3;
+
39 
+
40 const uint8_t kTrotecPowerBitOffset = 3;
+
41 
+
42 const uint8_t kTrotecFanOffset = 4;
+
43 const uint8_t kTrotecFanSize = 2; // Nr. of bits
+
44 const uint8_t kTrotecFanLow = 1;
+
45 const uint8_t kTrotecFanMed = 2;
+
46 const uint8_t kTrotecFanHigh = 3;
+
47 
+
48 // Byte 3
+
49 const uint8_t kTrotecTempOffset = 0;
+
50 const uint8_t kTrotecTempSize = 4; // Nr. of bits
+
51 const uint8_t kTrotecMinTemp = 18;
+
52 const uint8_t kTrotecDefTemp = 25;
+
53 const uint8_t kTrotecMaxTemp = 32;
+
54 const uint8_t kTrotecSleepBitOffset = 7;
+
55 
+
56 // Byte 5
+
57 const uint8_t kTrotecTimerBitOffset = 6;
+
58 
+
59 // Byte 6
+
60 const uint8_t kTrotecMaxTimer = 23;
+
61 
+
62 // Legacy defines. (Deperecated)
+
63 #define TROTEC_AUTO kTrotecAuto
+
64 #define TROTEC_COOL kTrotecCool
+
65 #define TROTEC_DRY kTrotecDry
+
66 #define TROTEC_FAN kTrotecFan
+
67 #define TROTEC_FAN_LOW kTrotecFanLow
+
68 #define TROTEC_FAN_MED kTrotecFanMed
+
69 #define TROTEC_FAN_HIGH kTrotecFanHigh
+
70 #define TROTEC_MIN_TEMP kTrotecMinTemp
+
71 #define TROTEC_MAX_TEMP kTrotecMaxTemp
+
72 #define TROTEC_MAX_TIMER kTrotecMaxTimer
+
73 
+
74 // Class
+
76 class IRTrotecESP {
+
77  public:
+
78  explicit IRTrotecESP(const uint16_t pin, const bool inverted = false,
+
79  const bool use_modulation = true);
+
80 #if SEND_TROTEC
+
81  void send(const uint16_t repeat = kTrotecDefaultRepeat);
+
86  int8_t calibrate(void) { return _irsend.calibrate(); }
+
87 #endif // SEND_TROTEC
+
88  void begin(void);
+
89  void stateReset(void);
+
90 
+
91  void on(void);
+
92  void off(void);
+
93  void setPower(const bool state);
+
94  bool getPower(void);
+
95 
+
96  void setTemp(const uint8_t celsius);
+
97  uint8_t getTemp(void);
+
98 
+
99  void setSpeed(const uint8_t fan);
+
100  uint8_t getSpeed(void);
+
101 
+
102  uint8_t getMode(void);
+
103  void setMode(const uint8_t mode);
+
104 
+
105  bool getSleep(void);
+
106  void setSleep(const bool on);
+
107 
+
108  uint8_t getTimer(void);
+
109  void setTimer(const uint8_t timer);
+
110 
+
111  uint8_t* getRaw(void);
+
112  void setRaw(const uint8_t state[]);
+
113  static bool validChecksum(const uint8_t state[],
+
114  const uint16_t length = kTrotecStateLength);
+
115  uint8_t convertMode(const stdAc::opmode_t mode);
+
116  uint8_t convertFan(const stdAc::fanspeed_t speed);
+
117  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
118  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
119  stdAc::state_t toCommon(void);
+
120  String toString(void);
+
121 #ifndef UNIT_TEST
+
122 
+
123  private:
+ +
125 #else // UNIT_TEST
+
126  IRsendTest _irsend;
+
128 #endif // UNIT_TEST
+ +
131  static uint8_t calcChecksum(const uint8_t state[],
+
132  const uint16_t length = kTrotecStateLength);
+
133  void checksum(void);
+
134 };
+
135 
+
136 #endif // IR_TROTEC_H_
+
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Trotec.cpp:184
+
const uint8_t kTrotecFanOffset
Definition: ir_Trotec.h:42
+
void checksum(void)
Calculate & set the checksum for the current internal state of the remote.
Definition: ir_Trotec.cpp:98
+
const uint8_t kTrotecTimerBitOffset
Definition: ir_Trotec.h:57
+
bool getSleep(void)
Get the Sleep setting of the A/C.
Definition: ir_Trotec.cpp:197
+
const uint16_t kTrotecDefaultRepeat
Definition: IRremoteESP8266.h:1004
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Trotec.cpp:169
+
const uint8_t kTrotecSleepBitOffset
Definition: ir_Trotec.h:54
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Trotec.cpp:291
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Trotec.cpp:70
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Trotec.cpp:143
+
const uint8_t kTrotecFanMed
Definition: ir_Trotec.h:45
+ +
uint8_t * getRaw(void)
Get a PTR to the internal state/code for this protocol.
Definition: ir_Trotec.cpp:118
+
const uint8_t kTrotecIntro2
Definition: ir_Trotec.h:30
+
const uint8_t kTrotecFanHigh
Definition: ir_Trotec.h:46
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
std::string String
Definition: IRremoteESP8266.h:1093
+
static bool validChecksum(const uint8_t state[], const uint16_t length=kTrotecStateLength)
Verify the checksum is valid for a given state.
Definition: ir_Trotec.cpp:93
+
const uint8_t kTrotecMinTemp
Definition: ir_Trotec.h:51
+
const uint8_t kTrotecDefTemp
Definition: ir_Trotec.h:52
+
void on(void)
Set the requested power state of the A/C to on.
Definition: ir_Trotec.cpp:130
+
const uint8_t kTrotecMaxTimer
Definition: ir_Trotec.h:60
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Trotec.cpp:265
+ +
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Trotec.cpp:215
+
const uint8_t kTrotecDry
Definition: ir_Trotec.h:37
+
const uint8_t kTrotecTempOffset
Definition: ir_Trotec.h:49
+
uint8_t getTimer(void)
Get the timer time in nr. of Hours.
Definition: ir_Trotec.cpp:210
+
void setTemp(const uint8_t celsius)
Set the temperature.
Definition: ir_Trotec.cpp:175
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Trotec.cpp:162
+
const uint16_t kTrotecStateLength
Definition: IRremoteESP8266.h:1002
+
const uint8_t kTrotecMaxTemp
Definition: ir_Trotec.h:53
+
const uint8_t kTrotecFanLow
Definition: ir_Trotec.h:44
+
void stateReset(void)
Reset the state of the remote to a known good state/sequence.
Definition: ir_Trotec.cpp:104
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Trotec.h:86
+
void setTimer(const uint8_t timer)
Set the timer time in nr. of Hours.
Definition: ir_Trotec.cpp:203
+
void setPower(const bool state)
Change the power setting.
Definition: ir_Trotec.cpp:137
+
const uint8_t kTrotecFan
Definition: ir_Trotec.h:38
+
const uint8_t kTrotecModeSize
Definition: ir_Trotec.h:34
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Trotec.cpp:242
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Trotec.h:124
+
const uint8_t kTrotecCool
Definition: ir_Trotec.h:36
+
void setSleep(const bool on)
Set the Sleep setting of the A/C.
Definition: ir_Trotec.cpp:191
+
void off(void)
Set the requested power state of the A/C to off.
Definition: ir_Trotec.cpp:133
+
static uint8_t calcChecksum(const uint8_t state[], const uint16_t length=kTrotecStateLength)
Calculate the checksum for a given state.
Definition: ir_Trotec.cpp:84
+
void send(const uint16_t repeat=kTrotecDefaultRepeat)
Send the current internal state as an IR message.
Definition: ir_Trotec.cpp:75
+
uint8_t remote_state[kTrotecStateLength]
Remote state in IR code form.
Definition: ir_Trotec.h:130
+
const uint8_t kTrotecModeOffset
Definition: ir_Trotec.h:33
+
const uint8_t kTrotecAuto
Definition: ir_Trotec.h:35
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Trotec.cpp:254
+
Class for handling detailed Trotec A/C messages.
Definition: ir_Trotec.h:76
+
const uint8_t kTrotecFanSize
Definition: ir_Trotec.h:43
+
uint8_t getSpeed(void)
Get the current fan speed setting.
Definition: ir_Trotec.cpp:156
+
IRTrotecESP(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Trotec.cpp:65
+
const uint8_t kTrotecTempSize
Definition: ir_Trotec.h:50
+
uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Trotec.cpp:228
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
const uint8_t kTrotecIntro1
Definition: ir_Trotec.h:27
+
void setRaw(const uint8_t state[])
Set the internal state from a valid code for this protocol.
Definition: ir_Trotec.cpp:125
+
void setSpeed(const uint8_t fan)
Set the speed of the fan.
Definition: ir_Trotec.cpp:149
+
const uint8_t kTrotecPowerBitOffset
Definition: ir_Trotec.h:40
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Vestel_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Vestel_8cpp.html new file mode 100644 index 000000000..36b147b25 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Vestel_8cpp.html @@ -0,0 +1,85 @@ + + + + + + + +IRremoteESP8266: src/ir_Vestel.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Vestel.cpp File Reference
+
+
+ +

Support for Vestel protocols. Vestel added by Erdem U. Altinyurt. +More...

+

Detailed Description

+

Support for Vestel protocols. Vestel added by Erdem U. Altinyurt.

+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Vestel_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Vestel_8h.html new file mode 100644 index 000000000..ff591a74e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Vestel_8h.html @@ -0,0 +1,905 @@ + + + + + + + +IRremoteESP8266: src/ir_Vestel.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Vestel.h File Reference
+
+
+ +

Support for Vestel protocols. Vestel added by Erdem U. Altinyurt. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRVestelAc
 Class for handling detailed Vestel A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kVestelAcHdrMark = 3110
 
const uint16_t kVestelAcHdrSpace = 9066
 
const uint16_t kVestelAcBitMark = 520
 
const uint16_t kVestelAcOneSpace = 1535
 
const uint16_t kVestelAcZeroSpace = 480
 
const uint16_t kVestelAcTolerance = 30
 
const uint8_t kVestelAcMinTempH = 16
 
const uint8_t kVestelAcMinTempC = 18
 
const uint8_t kVestelAcMaxTemp = 30
 
const uint8_t kVestelAcAuto = 0
 
const uint8_t kVestelAcCool = 1
 
const uint8_t kVestelAcDry = 2
 
const uint8_t kVestelAcFan = 3
 
const uint8_t kVestelAcHeat = 4
 
const uint8_t kVestelAcFanAuto = 1
 
const uint8_t kVestelAcFanLow = 5
 
const uint8_t kVestelAcFanMed = 9
 
const uint8_t kVestelAcFanHigh = 0xB
 
const uint8_t kVestelAcFanAutoCool = 0xC
 
const uint8_t kVestelAcFanAutoHot = 0xD
 
const uint8_t kVestelAcNormal = 1
 
const uint8_t kVestelAcSleep = 3
 
const uint8_t kVestelAcTurbo = 7
 
const uint8_t kVestelAcIon = 4
 
const uint8_t kVestelAcSwing = 0xA
 
const uint8_t kVestelAcChecksumOffset = 12
 
const uint8_t kVestelAcChecksumSize = 8
 
const uint8_t kVestelAcSwingOffset = 20
 
const uint8_t kVestelAcTurboSleepOffset = 24
 
const uint8_t kVestelAcTempOffset = 36
 
const uint8_t kVestelAcFanOffset = 40
 
const uint8_t kVestelAcFanSize = 4
 
const uint8_t kVestelAcModeOffset = 44
 
const uint8_t kVestelAcIonOffset = 50
 
const uint8_t kVestelAcPowerOffset = 52
 
const uint8_t kVestelAcPowerSize = 2
 
const uint8_t kVestelAcOffTimeOffset = 20
 
const uint8_t kVestelAcOnTimeOffset = 28
 
const uint8_t kVestelAcTimerHourSize = 5
 
const uint8_t kVestelAcTimerMinsSize = 3
 
const uint8_t kVestelAcTimerSize
 
const uint8_t kVestelAcHourOffset = 36
 
const uint8_t kVestelAcHourSize = 5
 
const uint8_t kVestelAcOnTimerFlagOffset = kVestelAcHourOffset + 5
 
const uint8_t kVestelAcOffTimerFlagOffset = kVestelAcHourOffset + 6
 
const uint8_t kVestelAcTimerFlagOffset = kVestelAcHourOffset + 7
 
const uint8_t kVestelAcMinuteOffset = 44
 
const uint8_t kVestelAcMinuteSize = 8
 
const uint64_t kVestelAcStateDefault = 0x0F00D9001FEF201ULL
 
const uint64_t kVestelAcTimeStateDefault = 0x201ULL
 
+

Detailed Description

+

Support for Vestel protocols. Vestel added by Erdem U. Altinyurt.

+

Variable Documentation

+ +

◆ kVestelAcAuto

+ +
+
+ + + + +
const uint8_t kVestelAcAuto = 0
+
+ +
+
+ +

◆ kVestelAcBitMark

+ +
+
+ + + + +
const uint16_t kVestelAcBitMark = 520
+
+ +
+
+ +

◆ kVestelAcChecksumOffset

+ +
+
+ + + + +
const uint8_t kVestelAcChecksumOffset = 12
+
+ +
+
+ +

◆ kVestelAcChecksumSize

+ +
+
+ + + + +
const uint8_t kVestelAcChecksumSize = 8
+
+ +
+
+ +

◆ kVestelAcCool

+ +
+
+ + + + +
const uint8_t kVestelAcCool = 1
+
+ +
+
+ +

◆ kVestelAcDry

+ +
+
+ + + + +
const uint8_t kVestelAcDry = 2
+
+ +
+
+ +

◆ kVestelAcFan

+ +
+
+ + + + +
const uint8_t kVestelAcFan = 3
+
+ +
+
+ +

◆ kVestelAcFanAuto

+ +
+
+ + + + +
const uint8_t kVestelAcFanAuto = 1
+
+ +
+
+ +

◆ kVestelAcFanAutoCool

+ +
+
+ + + + +
const uint8_t kVestelAcFanAutoCool = 0xC
+
+ +
+
+ +

◆ kVestelAcFanAutoHot

+ +
+
+ + + + +
const uint8_t kVestelAcFanAutoHot = 0xD
+
+ +
+
+ +

◆ kVestelAcFanHigh

+ +
+
+ + + + +
const uint8_t kVestelAcFanHigh = 0xB
+
+ +
+
+ +

◆ kVestelAcFanLow

+ +
+
+ + + + +
const uint8_t kVestelAcFanLow = 5
+
+ +
+
+ +

◆ kVestelAcFanMed

+ +
+
+ + + + +
const uint8_t kVestelAcFanMed = 9
+
+ +
+
+ +

◆ kVestelAcFanOffset

+ +
+
+ + + + +
const uint8_t kVestelAcFanOffset = 40
+
+ +
+
+ +

◆ kVestelAcFanSize

+ +
+
+ + + + +
const uint8_t kVestelAcFanSize = 4
+
+ +
+
+ +

◆ kVestelAcHdrMark

+ +
+
+ + + + +
const uint16_t kVestelAcHdrMark = 3110
+
+ +
+
+ +

◆ kVestelAcHdrSpace

+ +
+
+ + + + +
const uint16_t kVestelAcHdrSpace = 9066
+
+ +
+
+ +

◆ kVestelAcHeat

+ +
+
+ + + + +
const uint8_t kVestelAcHeat = 4
+
+ +
+
+ +

◆ kVestelAcHourOffset

+ +
+
+ + + + +
const uint8_t kVestelAcHourOffset = 36
+
+ +
+
+ +

◆ kVestelAcHourSize

+ +
+
+ + + + +
const uint8_t kVestelAcHourSize = 5
+
+ +
+
+ +

◆ kVestelAcIon

+ +
+
+ + + + +
const uint8_t kVestelAcIon = 4
+
+ +
+
+ +

◆ kVestelAcIonOffset

+ +
+
+ + + + +
const uint8_t kVestelAcIonOffset = 50
+
+ +
+
+ +

◆ kVestelAcMaxTemp

+ +
+
+ + + + +
const uint8_t kVestelAcMaxTemp = 30
+
+ +
+
+ +

◆ kVestelAcMinTempC

+ +
+
+ + + + +
const uint8_t kVestelAcMinTempC = 18
+
+ +
+
+ +

◆ kVestelAcMinTempH

+ +
+
+ + + + +
const uint8_t kVestelAcMinTempH = 16
+
+ +
+
+ +

◆ kVestelAcMinuteOffset

+ +
+
+ + + + +
const uint8_t kVestelAcMinuteOffset = 44
+
+ +
+
+ +

◆ kVestelAcMinuteSize

+ +
+
+ + + + +
const uint8_t kVestelAcMinuteSize = 8
+
+ +
+
+ +

◆ kVestelAcModeOffset

+ +
+
+ + + + +
const uint8_t kVestelAcModeOffset = 44
+
+ +
+
+ +

◆ kVestelAcNormal

+ +
+
+ + + + +
const uint8_t kVestelAcNormal = 1
+
+ +
+
+ +

◆ kVestelAcOffTimeOffset

+ +
+
+ + + + +
const uint8_t kVestelAcOffTimeOffset = 20
+
+ +
+
+ +

◆ kVestelAcOffTimerFlagOffset

+ +
+
+ + + + +
const uint8_t kVestelAcOffTimerFlagOffset = kVestelAcHourOffset + 6
+
+ +
+
+ +

◆ kVestelAcOneSpace

+ +
+
+ + + + +
const uint16_t kVestelAcOneSpace = 1535
+
+ +
+
+ +

◆ kVestelAcOnTimeOffset

+ +
+
+ + + + +
const uint8_t kVestelAcOnTimeOffset = 28
+
+ +
+
+ +

◆ kVestelAcOnTimerFlagOffset

+ +
+
+ + + + +
const uint8_t kVestelAcOnTimerFlagOffset = kVestelAcHourOffset + 5
+
+ +
+
+ +

◆ kVestelAcPowerOffset

+ +
+
+ + + + +
const uint8_t kVestelAcPowerOffset = 52
+
+ +
+
+ +

◆ kVestelAcPowerSize

+ +
+
+ + + + +
const uint8_t kVestelAcPowerSize = 2
+
+ +
+
+ +

◆ kVestelAcSleep

+ +
+
+ + + + +
const uint8_t kVestelAcSleep = 3
+
+ +
+
+ +

◆ kVestelAcStateDefault

+ +
+
+ + + + +
const uint64_t kVestelAcStateDefault = 0x0F00D9001FEF201ULL
+
+ +
+
+ +

◆ kVestelAcSwing

+ +
+
+ + + + +
const uint8_t kVestelAcSwing = 0xA
+
+ +
+
+ +

◆ kVestelAcSwingOffset

+ +
+
+ + + + +
const uint8_t kVestelAcSwingOffset = 20
+
+ +
+
+ +

◆ kVestelAcTempOffset

+ +
+
+ + + + +
const uint8_t kVestelAcTempOffset = 36
+
+ +
+
+ +

◆ kVestelAcTimerFlagOffset

+ +
+
+ + + + +
const uint8_t kVestelAcTimerFlagOffset = kVestelAcHourOffset + 7
+
+ +
+
+ +

◆ kVestelAcTimerHourSize

+ +
+
+ + + + +
const uint8_t kVestelAcTimerHourSize = 5
+
+ +
+
+ +

◆ kVestelAcTimerMinsSize

+ +
+
+ + + + +
const uint8_t kVestelAcTimerMinsSize = 3
+
+ +
+
+ +

◆ kVestelAcTimerSize

+ +
+
+ + + + +
const uint8_t kVestelAcTimerSize
+
+
+ +

◆ kVestelAcTimeStateDefault

+ +
+
+ + + + +
const uint64_t kVestelAcTimeStateDefault = 0x201ULL
+
+ +
+
+ +

◆ kVestelAcTolerance

+ +
+
+ + + + +
const uint16_t kVestelAcTolerance = 30
+
+ +
+
+ +

◆ kVestelAcTurbo

+ +
+
+ + + + +
const uint8_t kVestelAcTurbo = 7
+
+ +
+
+ +

◆ kVestelAcTurboSleepOffset

+ +
+
+ + + + +
const uint8_t kVestelAcTurboSleepOffset = 24
+
+ +
+
+ +

◆ kVestelAcZeroSpace

+ +
+
+ + + + +
const uint16_t kVestelAcZeroSpace = 480
+
+ +
+
+
+
const uint8_t kVestelAcTimerHourSize
Definition: ir_Vestel.h:99
+
const uint8_t kVestelAcTimerMinsSize
Definition: ir_Vestel.h:100
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Vestel_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Vestel_8h_source.html new file mode 100644 index 000000000..e737cba4c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Vestel_8h_source.html @@ -0,0 +1,378 @@ + + + + + + + +IRremoteESP8266: src/ir_Vestel.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Vestel.h
+
+
+Go to the documentation of this file.
1 // Copyright 2018 Erdem U. Altinyurt
+
2 // Copyright 2019 David Conran
+
3 
+
7 
+
8 // Supports:
+
9 // Brand: Vestel, Model: BIOX CXP-9 A/C (9K BTU)
+
10 
+
11 #ifndef IR_VESTEL_H_
+
12 #define IR_VESTEL_H_
+
13 
+
14 #define __STDC_LIMIT_MACROS
+
15 #include <stdint.h>
+
16 #ifdef ARDUINO
+
17 #include <Arduino.h>
+
18 #endif
+
19 #include "IRremoteESP8266.h"
+
20 #include "IRsend.h"
+
21 #ifdef UNIT_TEST
+
22 #include "IRsend_test.h"
+
23 #endif
+
24 
+
25 
+
26 // Structure of a Command message (56 bits)
+
27 // Signature: 12 bits. e.g. 0x201
+
28 // Checksum: 8 bits
+
29 // Swing: 4 bits. (auto 0xA, stop 0xF)
+
30 // turbo_sleep_normal: 4bits. (normal 0x1, sleep 0x3, turbo 0x7)
+
31 // Unused: 8 bits. (0x00)
+
32 // Temperature: 4 bits. (Celsius, but offset by -16 degrees. e.g. 0x0 = 16C)
+
33 // Fan Speed: 4 bits (auto 0x1, low 0x5, mid 0x9, high 0xB, 0xD auto hot,
+
34 // 0xC auto cool)
+
35 // Mode: 3 bits. (auto 0x0, cold 0x1, dry 0x2, fan 0x3, hot 0x4)
+
36 // unknown/unused: 6 bits.
+
37 // Ion flag: 1 bit.
+
38 // unknown/unused: 1 bit.
+
39 // Power/message type: 4 bits. (on 0xF, off 0xC, 0x0 == Timer mesage)
+
40 //
+
41 // Structure of a Time(r) message (56 bits)
+
42 // Signature: 12 bits. e.g. 0x201
+
43 // Checksum: 8 bits
+
44 // Off Minutes: 3 bits. (Stored in 10 min increments. eg. xx:20 is 0x2)
+
45 // Off Hours: 5 bits. (0x17 == 11PM / 23:00)
+
46 // On Minutes: 3 bits. (Stored in 10 min increments. eg. xx:20 is 0x2)
+
47 // On Hours: 5 bits. (0x9 == 9AM / 09:00)
+
48 // Clock Hours: 5 bits.
+
49 // On Timer flag: 1 bit.
+
50 // Off Timer flag: 1 bit.
+
51 // Timer mode flag: 1 bit. (Off after X many hours/mins, not at clock time.)
+
52 // Clock Minutes: 8 bits. (0-59)
+
53 // Power/message type: 4 bits. (0x0 == Timer mesage, else see Comman message)
+
54 
+
55 // Constants
+
56 const uint16_t kVestelAcHdrMark = 3110;
+
57 const uint16_t kVestelAcHdrSpace = 9066;
+
58 const uint16_t kVestelAcBitMark = 520;
+
59 const uint16_t kVestelAcOneSpace = 1535;
+
60 const uint16_t kVestelAcZeroSpace = 480;
+
61 const uint16_t kVestelAcTolerance = 30;
+
62 
+
63 const uint8_t kVestelAcMinTempH = 16;
+
64 const uint8_t kVestelAcMinTempC = 18;
+
65 const uint8_t kVestelAcMaxTemp = 30;
+
66 
+
67 const uint8_t kVestelAcAuto = 0;
+
68 const uint8_t kVestelAcCool = 1;
+
69 const uint8_t kVestelAcDry = 2;
+
70 const uint8_t kVestelAcFan = 3;
+
71 const uint8_t kVestelAcHeat = 4;
+
72 
+
73 const uint8_t kVestelAcFanAuto = 1;
+
74 const uint8_t kVestelAcFanLow = 5;
+
75 const uint8_t kVestelAcFanMed = 9;
+
76 const uint8_t kVestelAcFanHigh = 0xB;
+
77 const uint8_t kVestelAcFanAutoCool = 0xC;
+
78 const uint8_t kVestelAcFanAutoHot = 0xD;
+
79 
+
80 const uint8_t kVestelAcNormal = 1;
+
81 const uint8_t kVestelAcSleep = 3;
+
82 const uint8_t kVestelAcTurbo = 7;
+
83 const uint8_t kVestelAcIon = 4;
+
84 const uint8_t kVestelAcSwing = 0xA;
+
85 
+
86 const uint8_t kVestelAcChecksumOffset = 12;
+
87 const uint8_t kVestelAcChecksumSize = 8; // Nr. of bits
+
88 const uint8_t kVestelAcSwingOffset = 20;
+
89 const uint8_t kVestelAcTurboSleepOffset = 24;
+
90 const uint8_t kVestelAcTempOffset = 36;
+
91 const uint8_t kVestelAcFanOffset = 40;
+
92 const uint8_t kVestelAcFanSize = 4; // Nr. of bits
+
93 const uint8_t kVestelAcModeOffset = 44;
+
94 const uint8_t kVestelAcIonOffset = 50;
+
95 const uint8_t kVestelAcPowerOffset = 52;
+
96 const uint8_t kVestelAcPowerSize = 2; // Nr. of bits
+
97 const uint8_t kVestelAcOffTimeOffset = 20;
+
98 const uint8_t kVestelAcOnTimeOffset = 28;
+
99 const uint8_t kVestelAcTimerHourSize = 5; // Nr. of bits
+
100 const uint8_t kVestelAcTimerMinsSize = 3; // Nr. of bits
+ +
102  kVestelAcTimerMinsSize; // Nr. of bits
+
103 const uint8_t kVestelAcHourOffset = 36; // 5 bits
+
104 const uint8_t kVestelAcHourSize = 5; // Nr. of bits
+ + + +
108 const uint8_t kVestelAcMinuteOffset = 44;
+
109 const uint8_t kVestelAcMinuteSize = 8; // Nr. of bits
+
110 // Default states
+
111 const uint64_t kVestelAcStateDefault = 0x0F00D9001FEF201ULL;
+
112 const uint64_t kVestelAcTimeStateDefault = 0x201ULL;
+
113 
+
114 // Classes
+
116 class IRVestelAc {
+
117  public:
+
118  explicit IRVestelAc(const uint16_t pin, const bool inverted = false,
+
119  const bool use_modulation = true);
+
120  void stateReset(void);
+
121 #if SEND_VESTEL_AC
+
122  void send(const uint16_t repeat = kNoRepeat);
+
127  int8_t calibrate(void) { return _irsend.calibrate(); }
+
128 #endif // SEND_VESTEL_AC
+
129  void begin(void);
+
130  void on(void);
+
131  void off(void);
+
132  void setPower(const bool on);
+
133  bool getPower(void);
+
134  void setAuto(const int8_t autoLevel);
+
135  void setTimer(const uint16_t minutes);
+
136  uint16_t getTimer(void);
+
137  void setTime(const uint16_t minutes);
+
138  uint16_t getTime(void);
+
139  void setOnTimer(const uint16_t minutes);
+
140  uint16_t getOnTimer(void);
+
141  void setOffTimer(const uint16_t minutes);
+
142  uint16_t getOffTimer(void);
+
143  void setTemp(const uint8_t temp);
+
144  uint8_t getTemp(void);
+
145  void setFan(const uint8_t fan);
+
146  uint8_t getFan(void);
+
147  void setMode(const uint8_t mode);
+
148  uint8_t getMode(void);
+
149  void setRaw(const uint8_t* newState);
+
150  void setRaw(const uint64_t newState);
+
151  uint64_t getRaw(void);
+
152  static bool validChecksum(const uint64_t state);
+
153  void setSwing(const bool on);
+
154  bool getSwing(void);
+
155  void setSleep(const bool on);
+
156  bool getSleep(void);
+
157  void setTurbo(const bool on);
+
158  bool getTurbo(void);
+
159  void setIon(const bool on);
+
160  bool getIon(void);
+
161  bool isTimeCommand(void);
+
162  bool isOnTimerActive(void);
+
163  void setOnTimerActive(const bool on);
+
164  bool isOffTimerActive(void);
+
165  void setOffTimerActive(const bool on);
+
166  bool isTimerActive(void);
+
167  void setTimerActive(const bool on);
+
168  static uint8_t calcChecksum(const uint64_t state);
+
169  static uint8_t convertMode(const stdAc::opmode_t mode);
+
170  static uint8_t convertFan(const stdAc::fanspeed_t speed);
+
171  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
172  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
173  stdAc::state_t toCommon(void);
+
174  String toString(void);
+
175 #ifndef UNIT_TEST
+
176 
+
177  private:
+ +
179 #else // UNIT_TEST
+
180  IRsendTest _irsend;
+
182 #endif // UNIT_TEST
+
184  uint64_t remote_state;
+
185  uint64_t remote_time_state;
+ +
187  void checksum(void);
+
188  void _setTimer(const uint16_t minutes, const uint8_t offset);
+
189  uint16_t _getTimer(const uint8_t offset);
+
190 };
+
191 
+
192 #endif // IR_VESTEL_H_
+
+
const uint16_t kVestelAcHdrSpace
Definition: ir_Vestel.h:57
+
const uint8_t kVestelAcOffTimeOffset
Definition: ir_Vestel.h:97
+
const uint8_t kVestelAcFanAutoHot
Definition: ir_Vestel.h:78
+
void stateReset(void)
Reset the state of the remote to a known good state/sequence.
Definition: ir_Vestel.cpp:60
+
uint16_t getOffTimer(void)
Get the A/C's Off Timer time.
Definition: ir_Vestel.cpp:330
+
const uint8_t kVestelAcTimerHourSize
Definition: ir_Vestel.h:99
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Vestel.cpp:478
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Vestel.cpp:67
+
void setFan(const uint8_t fan)
Set the speed of the fan.
Definition: ir_Vestel.cpp:147
+
const uint8_t kVestelAcHourSize
Definition: ir_Vestel.h:104
+
const uint8_t kVestelAcFanOffset
Definition: ir_Vestel.h:91
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Vestel.cpp:130
+
void setOffTimerActive(const bool on)
Set the Off timer to be active on the A/C.
Definition: ir_Vestel.cpp:310
+
void setTime(const uint16_t minutes)
Set the A/C's internal clock.
Definition: ir_Vestel.cpp:247
+
const uint8_t kVestelAcMaxTemp
Definition: ir_Vestel.h:65
+
void setPower(const bool on)
Change the power setting.
Definition: ir_Vestel.cpp:116
+
bool isTimeCommand(void)
Is the current state a time command?
Definition: ir_Vestel.cpp:419
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
const uint8_t kVestelAcSleep
Definition: ir_Vestel.h:81
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Vestel.h:127
+
const uint8_t kVestelAcDry
Definition: ir_Vestel.h:69
+
const uint16_t kVestelAcBitMark
Definition: ir_Vestel.h:58
+
const uint8_t kVestelAcAuto
Definition: ir_Vestel.h:67
+
const uint8_t kVestelAcFanMed
Definition: ir_Vestel.h:75
+
void setTurbo(const bool on)
Set the Turbo setting of the A/C.
Definition: ir_Vestel.cpp:351
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Vestel.h:178
+
void setTimer(const uint16_t minutes)
Set Timer option of A/C.
Definition: ir_Vestel.cpp:228
+
void on(void)
Set the requested power state of the A/C to on.
Definition: ir_Vestel.cpp:109
+
uint16_t _getTimer(const uint8_t offset)
Get the number of minutes a timer is set for.
Definition: ir_Vestel.cpp:289
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Vestel.cpp:178
+ +
bool isOffTimerActive(void)
Get if the Off Timer is active on the A/C.
Definition: ir_Vestel.cpp:317
+
const uint8_t kVestelAcMinuteSize
Definition: ir_Vestel.h:109
+
const uint8_t kVestelAcMinTempC
Definition: ir_Vestel.h:64
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
const uint8_t kVestelAcChecksumSize
Definition: ir_Vestel.h:87
+
uint16_t getTimer(void)
Get the Timer time of A/C.
Definition: ir_Vestel.cpp:243
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
const uint8_t kVestelAcFanSize
Definition: ir_Vestel.h:92
+
const uint8_t kVestelAcSwingOffset
Definition: ir_Vestel.h:88
+
bool isOnTimerActive(void)
Get if the On Timer is active on the A/C.
Definition: ir_Vestel.cpp:272
+
std::string String
Definition: IRremoteESP8266.h:1093
+
const uint8_t kVestelAcTimerFlagOffset
Definition: ir_Vestel.h:107
+
bool isTimerActive(void)
Get if the Timer is active on the A/C.
Definition: ir_Vestel.cpp:220
+
void setRaw(const uint8_t *newState)
Set the internal state from a valid code for this protocol.
Definition: ir_Vestel.cpp:87
+
const uint8_t kVestelAcFan
Definition: ir_Vestel.h:70
+ +
const uint8_t kVestelAcMinTempH
Definition: ir_Vestel.h:63
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Vestel.cpp:140
+
const uint16_t kVestelAcHdrMark
Definition: ir_Vestel.h:56
+
const uint16_t kNoRepeat
Definition: IRremoteESP8266.h:810
+
uint64_t remote_time_state
The time state of the remote in code form.
Definition: ir_Vestel.h:185
+
const uint8_t kVestelAcOnTimerFlagOffset
Definition: ir_Vestel.h:105
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Vestel.cpp:454
+
uint64_t remote_state
The state of the IR remote in IR code form.
Definition: ir_Vestel.h:184
+
bool getSleep(void)
Get the Sleep setting of the A/C.
Definition: ir_Vestel.cpp:344
+
const uint16_t kVestelAcOneSpace
Definition: ir_Vestel.h:59
+
void checksum(void)
Calculate & set the checksum for the current internal state of the remote.
Definition: ir_Vestel.cpp:409
+
void setSwing(const bool on)
Set the Swing Roaming setting of the A/C.
Definition: ir_Vestel.cpp:379
+
bool getTurbo(void)
Get the Turbo setting of the A/C.
Definition: ir_Vestel.cpp:359
+
const uint8_t kVestelAcTempOffset
Definition: ir_Vestel.h:90
+
void setOffTimer(const uint16_t minutes)
Set the Off timer time on the A/C.
Definition: ir_Vestel.cpp:323
+
const uint8_t kVestelAcTimerMinsSize
Definition: ir_Vestel.h:100
+
void setOnTimerActive(const bool on)
Set the On timer to be active on the A/C.
Definition: ir_Vestel.cpp:265
+
const uint8_t kVestelAcHourOffset
Definition: ir_Vestel.h:103
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Vestel.cpp:467
+
void send(const uint16_t repeat=kNoRepeat)
Send the current internal state as an IR message.
Definition: ir_Vestel.cpp:72
+
void off(void)
Set the requested power state of the A/C to off.
Definition: ir_Vestel.cpp:112
+
const uint8_t kVestelAcFanAutoCool
Definition: ir_Vestel.h:77
+
const uint64_t kVestelAcStateDefault
Definition: ir_Vestel.h:111
+
static uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Vestel.cpp:427
+
void setIon(const bool on)
Set the Ion (Filter) setting of the A/C.
Definition: ir_Vestel.cpp:366
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Vestel.cpp:505
+
const uint16_t kVestelAcTolerance
Definition: ir_Vestel.h:61
+
const uint8_t kVestelAcFanLow
Definition: ir_Vestel.h:74
+
const uint8_t kVestelAcChecksumOffset
Definition: ir_Vestel.h:86
+
const uint8_t kVestelAcPowerSize
Definition: ir_Vestel.h:96
+
const uint8_t kVestelAcSwing
Definition: ir_Vestel.h:84
+
const uint8_t kVestelAcIonOffset
Definition: ir_Vestel.h:94
+
const uint8_t kVestelAcOnTimeOffset
Definition: ir_Vestel.h:98
+
const uint16_t kVestelAcZeroSpace
Definition: ir_Vestel.h:60
+
const uint8_t kVestelAcMinuteOffset
Definition: ir_Vestel.h:108
+
const uint64_t kVestelAcTimeStateDefault
Definition: ir_Vestel.h:112
+
uint16_t getTime(void)
Get the A/C's internal clock's time.
Definition: ir_Vestel.cpp:257
+
const uint8_t kVestelAcTurboSleepOffset
Definition: ir_Vestel.h:89
+
const uint8_t kVestelAcTurbo
Definition: ir_Vestel.h:82
+
bool getPower(void)
Get the value of the current power setting.
Definition: ir_Vestel.cpp:124
+
static uint8_t calcChecksum(const uint64_t state)
Calculate the checksum for a given state.
Definition: ir_Vestel.cpp:395
+
uint64_t getRaw(void)
Get a copy of the internal state/code for this protocol.
Definition: ir_Vestel.cpp:79
+
const uint8_t kVestelAcHeat
Definition: ir_Vestel.h:71
+
const uint8_t kVestelAcNormal
Definition: ir_Vestel.h:80
+
const uint8_t kVestelAcFanHigh
Definition: ir_Vestel.h:76
+
const uint8_t kVestelAcTimerSize
Definition: ir_Vestel.h:101
+
IRVestelAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Vestel.cpp:54
+
Class for handling detailed Vestel A/C messages.
Definition: ir_Vestel.h:116
+
bool getIon(void)
Get the Ion (Filter) setting of the A/C.
Definition: ir_Vestel.cpp:373
+
const uint8_t kVestelAcCool
Definition: ir_Vestel.h:68
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Vestel.cpp:171
+
uint16_t getOnTimer(void)
Get the A/C's On Timer time.
Definition: ir_Vestel.cpp:304
+
void setTimerActive(const bool on)
Set the timer to be active on the A/C.
Definition: ir_Vestel.cpp:213
+
void setSleep(const bool on)
Set the Sleep setting of the A/C.
Definition: ir_Vestel.cpp:336
+
void _setTimer(const uint16_t minutes, const uint8_t offset)
Set a given timer time at a given bit offset.
Definition: ir_Vestel.cpp:279
+
bool use_time_state
Definition: ir_Vestel.h:186
+
const uint8_t kVestelAcOffTimerFlagOffset
Definition: ir_Vestel.h:106
+
const uint8_t kVestelAcModeOffset
Definition: ir_Vestel.h:93
+
const uint8_t kVestelAcIon
Definition: ir_Vestel.h:83
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Vestel.cpp:165
+
bool getSwing(void)
Get the Swing Roaming setting of the A/C.
Definition: ir_Vestel.cpp:387
+
const uint8_t kVestelAcPowerOffset
Definition: ir_Vestel.h:95
+
static bool validChecksum(const uint64_t state)
Verify the checksum is valid for a given state.
Definition: ir_Vestel.cpp:403
+
void setAuto(const int8_t autoLevel)
Set Auto mode/level of the A/C.
Definition: ir_Vestel.cpp:195
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
const uint8_t kVestelAcFanAuto
Definition: ir_Vestel.h:73
+
static uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Vestel.cpp:440
+
void setOnTimer(const uint16_t minutes)
Set the On timer time on the A/C.
Definition: ir_Vestel.cpp:297
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Whirlpool_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Whirlpool_8cpp.html new file mode 100644 index 000000000..95fcdadbf --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Whirlpool_8cpp.html @@ -0,0 +1,224 @@ + + + + + + + +IRremoteESP8266: src/ir_Whirlpool.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Whirlpool.cpp File Reference
+
+
+ +

Support for Whirlpool protocols. Decoding help from: @redmusicxd, @josh929800, @raducostea. +More...

+ + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kWhirlpoolAcHdrMark = 8950
 
const uint16_t kWhirlpoolAcHdrSpace = 4484
 
const uint16_t kWhirlpoolAcBitMark = 597
 
const uint16_t kWhirlpoolAcOneSpace = 1649
 
const uint16_t kWhirlpoolAcZeroSpace = 533
 
const uint16_t kWhirlpoolAcGap = 7920
 
const uint32_t kWhirlpoolAcMinGap = kDefaultMessageGap
 
const uint8_t kWhirlpoolAcSections = 3
 
+

Detailed Description

+

Support for Whirlpool protocols. Decoding help from: @redmusicxd, @josh929800, @raducostea.

+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/509
+
Note
Smart, iFeel, AroundU, PowerSave, & Silent modes are unsupported. Advanced 6thSense, Dehumidify, & Sleep modes are not supported.
+
+Dim == !Light, Jet == Super == Turbo
+

Variable Documentation

+ +

◆ kWhirlpoolAcBitMark

+ +
+
+ + + + +
const uint16_t kWhirlpoolAcBitMark = 597
+
+ +
+
+ +

◆ kWhirlpoolAcGap

+ +
+
+ + + + +
const uint16_t kWhirlpoolAcGap = 7920
+
+ +
+
+ +

◆ kWhirlpoolAcHdrMark

+ +
+
+ + + + +
const uint16_t kWhirlpoolAcHdrMark = 8950
+
+ +
+
+ +

◆ kWhirlpoolAcHdrSpace

+ +
+
+ + + + +
const uint16_t kWhirlpoolAcHdrSpace = 4484
+
+ +
+
+ +

◆ kWhirlpoolAcMinGap

+ +
+
+ + + + +
const uint32_t kWhirlpoolAcMinGap = kDefaultMessageGap
+
+ +
+
+ +

◆ kWhirlpoolAcOneSpace

+ +
+
+ + + + +
const uint16_t kWhirlpoolAcOneSpace = 1649
+
+ +
+
+ +

◆ kWhirlpoolAcSections

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcSections = 3
+
+ +
+
+ +

◆ kWhirlpoolAcZeroSpace

+ +
+
+ + + + +
const uint16_t kWhirlpoolAcZeroSpace = 533
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Whirlpool_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Whirlpool_8h.html new file mode 100644 index 000000000..555b83ade --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Whirlpool_8h.html @@ -0,0 +1,937 @@ + + + + + + + +IRremoteESP8266: src/ir_Whirlpool.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Whirlpool.h File Reference
+
+
+ +

Support for Whirlpool protocols. Decoding help from: @redmusicxd, @josh929800, @raducostea. +More...

+ +

Go to the source code of this file.

+ + + + + +

+Classes

class  IRWhirlpoolAc
 Class for handling detailed Whirlpool A/C messages. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint8_t kWhirlpoolAcChecksumByte1 = 13
 
const uint8_t kWhirlpoolAcChecksumByte2 = kWhirlpoolAcStateLength - 1
 
const uint8_t kWhirlpoolAcHeat = 0
 
const uint8_t kWhirlpoolAcAuto = 1
 
const uint8_t kWhirlpoolAcCool = 2
 
const uint8_t kWhirlpoolAcDry = 3
 
const uint8_t kWhirlpoolAcFan = 4
 
const uint8_t kWhirlpoolAcModeOffset = 0
 
const uint8_t kWhirlpoolAcModePos = 3
 
const uint8_t kWhirlpoolAcFanOffset = 0
 
const uint8_t kWhirlpoolAcFanSize = 2
 
const uint8_t kWhirlpoolAcFanAuto = 0
 
const uint8_t kWhirlpoolAcFanHigh = 1
 
const uint8_t kWhirlpoolAcFanMedium = 2
 
const uint8_t kWhirlpoolAcFanLow = 3
 
const uint8_t kWhirlpoolAcFanPos = 2
 
const uint8_t kWhirlpoolAcMinTemp = 18
 
const uint8_t kWhirlpoolAcMaxTemp = 32
 
const uint8_t kWhirlpoolAcAutoTemp = 23
 
const uint8_t kWhirlpoolAcTempPos = 3
 
const uint8_t kWhirlpoolAcSwing1Offset = 7
 
const uint8_t kWhirlpoolAcSwing2Offset = 6
 
const uint8_t kWhirlpoolAcLightOffset = 5
 
const uint8_t kWhirlpoolAcPowerToggleOffset = 2
 
const uint8_t kWhirlpoolAcPowerTogglePos = 2
 
const uint8_t kWhirlpoolAcSleepOffset = 3
 
const uint8_t kWhirlpoolAcSleepPos = 2
 
const uint8_t kWhirlpoolAcSuperMask = 0b10010000
 
const uint8_t kWhirlpoolAcSuperPos = 5
 
const uint8_t kWhirlpoolAcHourOffset = 0
 
const uint8_t kWhirlpoolAcHourSize = 5
 
const uint8_t kWhirlpoolAcMinuteOffset = 0
 
const uint8_t kWhirlpoolAcMinuteSize = 6
 
const uint8_t kWhirlpoolAcTimerEnableOffset = 7
 
const uint8_t kWhirlpoolAcClockPos = 6
 
const uint8_t kWhirlpoolAcOffTimerPos = 8
 
const uint8_t kWhirlpoolAcOnTimerPos = 10
 
const uint8_t kWhirlpoolAcCommandPos = 15
 
const uint8_t kWhirlpoolAcCommandLight = 0x00
 
const uint8_t kWhirlpoolAcCommandPower = 0x01
 
const uint8_t kWhirlpoolAcCommandTemp = 0x02
 
const uint8_t kWhirlpoolAcCommandSleep = 0x03
 
const uint8_t kWhirlpoolAcCommandSuper = 0x04
 
const uint8_t kWhirlpoolAcCommandOnTimer = 0x05
 
const uint8_t kWhirlpoolAcCommandMode = 0x06
 
const uint8_t kWhirlpoolAcCommandSwing = 0x07
 
const uint8_t kWhirlpoolAcCommandIFeel = 0x0D
 
const uint8_t kWhirlpoolAcCommandFanSpeed = 0x11
 
const uint8_t kWhirlpoolAcCommand6thSense = 0x17
 
const uint8_t kWhirlpoolAcCommandOffTimer = 0x1D
 
const uint8_t kWhirlpoolAcAltTempOffset = 3
 
const uint8_t kWhirlpoolAcAltTempPos = 18
 
+

Detailed Description

+

Support for Whirlpool protocols. Decoding help from: @redmusicxd, @josh929800, @raducostea.

+
See also
https://github.com/crankyoldgit/IRremoteESP8266/issues/509
+
Note
Smart, iFeel, AroundU, PowerSave, & Silent modes are unsupported. Advanced 6thSense, Dehumidify, & Sleep modes are not supported.
+
+Dim == !Light, Jet == Super == Turbo
+

Variable Documentation

+ +

◆ kWhirlpoolAcAltTempOffset

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcAltTempOffset = 3
+
+ +
+
+ +

◆ kWhirlpoolAcAltTempPos

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcAltTempPos = 18
+
+ +
+
+ +

◆ kWhirlpoolAcAuto

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcAuto = 1
+
+ +
+
+ +

◆ kWhirlpoolAcAutoTemp

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcAutoTemp = 23
+
+ +
+
+ +

◆ kWhirlpoolAcChecksumByte1

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcChecksumByte1 = 13
+
+ +
+
+ +

◆ kWhirlpoolAcChecksumByte2

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcChecksumByte2 = kWhirlpoolAcStateLength - 1
+
+ +
+
+ +

◆ kWhirlpoolAcClockPos

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcClockPos = 6
+
+ +
+
+ +

◆ kWhirlpoolAcCommand6thSense

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcCommand6thSense = 0x17
+
+ +
+
+ +

◆ kWhirlpoolAcCommandFanSpeed

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcCommandFanSpeed = 0x11
+
+ +
+
+ +

◆ kWhirlpoolAcCommandIFeel

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcCommandIFeel = 0x0D
+
+ +
+
+ +

◆ kWhirlpoolAcCommandLight

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcCommandLight = 0x00
+
+ +
+
+ +

◆ kWhirlpoolAcCommandMode

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcCommandMode = 0x06
+
+ +
+
+ +

◆ kWhirlpoolAcCommandOffTimer

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcCommandOffTimer = 0x1D
+
+ +
+
+ +

◆ kWhirlpoolAcCommandOnTimer

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcCommandOnTimer = 0x05
+
+ +
+
+ +

◆ kWhirlpoolAcCommandPos

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcCommandPos = 15
+
+ +
+
+ +

◆ kWhirlpoolAcCommandPower

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcCommandPower = 0x01
+
+ +
+
+ +

◆ kWhirlpoolAcCommandSleep

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcCommandSleep = 0x03
+
+ +
+
+ +

◆ kWhirlpoolAcCommandSuper

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcCommandSuper = 0x04
+
+ +
+
+ +

◆ kWhirlpoolAcCommandSwing

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcCommandSwing = 0x07
+
+ +
+
+ +

◆ kWhirlpoolAcCommandTemp

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcCommandTemp = 0x02
+
+ +
+
+ +

◆ kWhirlpoolAcCool

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcCool = 2
+
+ +
+
+ +

◆ kWhirlpoolAcDry

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcDry = 3
+
+ +
+
+ +

◆ kWhirlpoolAcFan

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcFan = 4
+
+ +
+
+ +

◆ kWhirlpoolAcFanAuto

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcFanAuto = 0
+
+ +
+
+ +

◆ kWhirlpoolAcFanHigh

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcFanHigh = 1
+
+ +
+
+ +

◆ kWhirlpoolAcFanLow

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcFanLow = 3
+
+ +
+
+ +

◆ kWhirlpoolAcFanMedium

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcFanMedium = 2
+
+ +
+
+ +

◆ kWhirlpoolAcFanOffset

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcFanOffset = 0
+
+ +
+
+ +

◆ kWhirlpoolAcFanPos

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcFanPos = 2
+
+ +
+
+ +

◆ kWhirlpoolAcFanSize

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcFanSize = 2
+
+ +
+
+ +

◆ kWhirlpoolAcHeat

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcHeat = 0
+
+ +
+
+ +

◆ kWhirlpoolAcHourOffset

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcHourOffset = 0
+
+ +
+
+ +

◆ kWhirlpoolAcHourSize

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcHourSize = 5
+
+ +
+
+ +

◆ kWhirlpoolAcLightOffset

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcLightOffset = 5
+
+ +
+
+ +

◆ kWhirlpoolAcMaxTemp

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcMaxTemp = 32
+
+ +
+
+ +

◆ kWhirlpoolAcMinTemp

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcMinTemp = 18
+
+ +
+
+ +

◆ kWhirlpoolAcMinuteOffset

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcMinuteOffset = 0
+
+ +
+
+ +

◆ kWhirlpoolAcMinuteSize

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcMinuteSize = 6
+
+ +
+
+ +

◆ kWhirlpoolAcModeOffset

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcModeOffset = 0
+
+ +
+
+ +

◆ kWhirlpoolAcModePos

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcModePos = 3
+
+ +
+
+ +

◆ kWhirlpoolAcOffTimerPos

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcOffTimerPos = 8
+
+ +
+
+ +

◆ kWhirlpoolAcOnTimerPos

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcOnTimerPos = 10
+
+ +
+
+ +

◆ kWhirlpoolAcPowerToggleOffset

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcPowerToggleOffset = 2
+
+ +
+
+ +

◆ kWhirlpoolAcPowerTogglePos

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcPowerTogglePos = 2
+
+ +
+
+ +

◆ kWhirlpoolAcSleepOffset

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcSleepOffset = 3
+
+ +
+
+ +

◆ kWhirlpoolAcSleepPos

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcSleepPos = 2
+
+ +
+
+ +

◆ kWhirlpoolAcSuperMask

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcSuperMask = 0b10010000
+
+ +
+
+ +

◆ kWhirlpoolAcSuperPos

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcSuperPos = 5
+
+ +
+
+ +

◆ kWhirlpoolAcSwing1Offset

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcSwing1Offset = 7
+
+ +
+
+ +

◆ kWhirlpoolAcSwing2Offset

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcSwing2Offset = 6
+
+ +
+
+ +

◆ kWhirlpoolAcTempPos

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcTempPos = 3
+
+ +
+
+ +

◆ kWhirlpoolAcTimerEnableOffset

+ +
+
+ + + + +
const uint8_t kWhirlpoolAcTimerEnableOffset = 7
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Whirlpool_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Whirlpool_8h_source.html new file mode 100644 index 000000000..380cd8281 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Whirlpool_8h_source.html @@ -0,0 +1,353 @@ + + + + + + + +IRremoteESP8266: src/ir_Whirlpool.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
ir_Whirlpool.h
+
+
+Go to the documentation of this file.
1 // Copyright 2018 David Conran
+
2 
+
10 
+
11 // Supports:
+
12 // Brand: Whirlpool, Model: DG11J1-3A remote
+
13 // Brand: Whirlpool, Model: DG11J1-04 remote
+
14 // Brand: Whirlpool, Model: DG11J1-91 remote
+
15 // Brand: Whirlpool, Model: SPIS409L A/C
+
16 // Brand: Whirlpool, Model: SPIS412L A/C
+
17 // Brand: Whirlpool, Model: SPIW409L A/C
+
18 // Brand: Whirlpool, Model: SPIW412L A/C
+
19 // Brand: Whirlpool, Model: SPIW418L A/C
+
20 
+
21 #ifndef IR_WHIRLPOOL_H_
+
22 #define IR_WHIRLPOOL_H_
+
23 
+
24 #define __STDC_LIMIT_MACROS
+
25 #include <stdint.h>
+
26 #ifndef UNIT_TEST
+
27 #include <Arduino.h>
+
28 #endif
+
29 #include "IRremoteESP8266.h"
+
30 #include "IRsend.h"
+
31 #ifdef UNIT_TEST
+
32 #include "IRsend_test.h"
+
33 #endif
+
34 
+
35 // Constants
+
36 const uint8_t kWhirlpoolAcChecksumByte1 = 13;
+ +
38 const uint8_t kWhirlpoolAcHeat = 0;
+
39 const uint8_t kWhirlpoolAcAuto = 1;
+
40 const uint8_t kWhirlpoolAcCool = 2;
+
41 const uint8_t kWhirlpoolAcDry = 3;
+
42 const uint8_t kWhirlpoolAcFan = 4;
+
43 const uint8_t kWhirlpoolAcModeOffset = 0;
+
44 const uint8_t kWhirlpoolAcModePos = 3;
+
45 const uint8_t kWhirlpoolAcFanOffset = 0; // Mask 0b00000011
+
46 const uint8_t kWhirlpoolAcFanSize = 2; // Nr. of bits
+
47 const uint8_t kWhirlpoolAcFanAuto = 0;
+
48 const uint8_t kWhirlpoolAcFanHigh = 1;
+
49 const uint8_t kWhirlpoolAcFanMedium = 2;
+
50 const uint8_t kWhirlpoolAcFanLow = 3;
+
51 const uint8_t kWhirlpoolAcFanPos = 2;
+
52 const uint8_t kWhirlpoolAcMinTemp = 18; // 18C (DG11J1-3A), 16C (DG11J1-91)
+
53 const uint8_t kWhirlpoolAcMaxTemp = 32; // 32C (DG11J1-3A), 30C (DG11J1-91)
+
54 const uint8_t kWhirlpoolAcAutoTemp = 23; // 23C
+
55 const uint8_t kWhirlpoolAcTempPos = 3;
+
56 const uint8_t kWhirlpoolAcSwing1Offset = 7;
+
57 const uint8_t kWhirlpoolAcSwing2Offset = 6;
+
58 const uint8_t kWhirlpoolAcLightOffset = 5;
+
59 const uint8_t kWhirlpoolAcPowerToggleOffset = 2; // 0b00000100
+
60 const uint8_t kWhirlpoolAcPowerTogglePos = 2;
+
61 const uint8_t kWhirlpoolAcSleepOffset = 3;
+
62 const uint8_t kWhirlpoolAcSleepPos = 2;
+
63 const uint8_t kWhirlpoolAcSuperMask = 0b10010000;
+
64 const uint8_t kWhirlpoolAcSuperPos = 5;
+
65 const uint8_t kWhirlpoolAcHourOffset = 0; // Mask 0b00011111
+
66 const uint8_t kWhirlpoolAcHourSize = 5; // Nr. of bits
+
67 const uint8_t kWhirlpoolAcMinuteOffset = 0; // Mask 0b00111111
+
68 const uint8_t kWhirlpoolAcMinuteSize = 6; // Nr. of bits
+
69 const uint8_t kWhirlpoolAcTimerEnableOffset = 7; // 0b10000000
+
70 const uint8_t kWhirlpoolAcClockPos = 6;
+
71 const uint8_t kWhirlpoolAcOffTimerPos = 8;
+
72 const uint8_t kWhirlpoolAcOnTimerPos = 10;
+
73 const uint8_t kWhirlpoolAcCommandPos = 15;
+
74 const uint8_t kWhirlpoolAcCommandLight = 0x00;
+
75 const uint8_t kWhirlpoolAcCommandPower = 0x01;
+
76 const uint8_t kWhirlpoolAcCommandTemp = 0x02;
+
77 const uint8_t kWhirlpoolAcCommandSleep = 0x03;
+
78 const uint8_t kWhirlpoolAcCommandSuper = 0x04;
+
79 const uint8_t kWhirlpoolAcCommandOnTimer = 0x05;
+
80 const uint8_t kWhirlpoolAcCommandMode = 0x06;
+
81 const uint8_t kWhirlpoolAcCommandSwing = 0x07;
+
82 const uint8_t kWhirlpoolAcCommandIFeel = 0x0D;
+
83 const uint8_t kWhirlpoolAcCommandFanSpeed = 0x11;
+
84 const uint8_t kWhirlpoolAcCommand6thSense = 0x17;
+
85 const uint8_t kWhirlpoolAcCommandOffTimer = 0x1D;
+
86 const uint8_t kWhirlpoolAcAltTempOffset = 3;
+
87 const uint8_t kWhirlpoolAcAltTempPos = 18;
+
88 
+
89 // Classes
+ +
92  public:
+
93  explicit IRWhirlpoolAc(const uint16_t pin, const bool inverted = false,
+
94  const bool use_modulation = true);
+
95  void stateReset(void);
+
96 #if SEND_WHIRLPOOL_AC
+
97  void send(const uint16_t repeat = kWhirlpoolAcDefaultRepeat,
+
98  const bool calcchecksum = true);
+
103  int8_t calibrate(void) { return _irsend.calibrate(); }
+
104 #endif // SEND_WHIRLPOOL_AC
+
105  void begin(void);
+
106  void setPowerToggle(const bool on);
+
107  bool getPowerToggle(void);
+
108  void setSleep(const bool on);
+
109  bool getSleep(void);
+
110  void setSuper(const bool on);
+
111  bool getSuper(void);
+
112  void setTemp(const uint8_t temp);
+
113  uint8_t getTemp(void);
+
114  void setFan(const uint8_t speed);
+
115  uint8_t getFan(void);
+
116  void setMode(const uint8_t mode);
+
117  uint8_t getMode(void);
+
118  void setSwing(const bool on);
+
119  bool getSwing(void);
+
120  void setLight(const bool on);
+
121  bool getLight(void);
+
122  uint16_t getClock(void);
+
123  void setClock(const uint16_t minspastmidnight);
+
124  uint16_t getOnTimer(void);
+
125  void setOnTimer(const uint16_t minspastmidnight);
+
126  void enableOnTimer(const bool on);
+
127  bool isOnTimerEnabled(void);
+
128  uint16_t getOffTimer(void);
+
129  void setOffTimer(const uint16_t minspastmidnight);
+
130  void enableOffTimer(const bool on);
+
131  bool isOffTimerEnabled(void);
+
132  void setCommand(const uint8_t code);
+
133  uint8_t getCommand(void);
+ +
135  void setModel(const whirlpool_ac_remote_model_t model);
+
136  uint8_t* getRaw(const bool calcchecksum = true);
+
137  void setRaw(const uint8_t new_code[],
+
138  const uint16_t length = kWhirlpoolAcStateLength);
+
139  static bool validChecksum(const uint8_t state[],
+
140  const uint16_t length = kWhirlpoolAcStateLength);
+
141  uint8_t convertMode(const stdAc::opmode_t mode);
+
142  uint8_t convertFan(const stdAc::fanspeed_t speed);
+
143  static stdAc::opmode_t toCommonMode(const uint8_t mode);
+
144  static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+
145  stdAc::state_t toCommon(void);
+
146  String toString(void);
+
147 #ifndef UNIT_TEST
+
148 
+
149  private:
+ +
151 #else // UNIT_TEST
+
152  IRsendTest _irsend;
+
154 #endif // UNIT_TEST
+ +
157  uint8_t _desiredtemp;
+
158  void checksum(const uint16_t length = kWhirlpoolAcStateLength);
+
159  uint16_t getTime(const uint16_t pos);
+
160  void setTime(const uint16_t pos, const uint16_t minspastmidnight);
+
161  bool isTimerEnabled(const uint16_t pos);
+
162  void enableTimer(const uint16_t pos, const bool state);
+
163  void _setTemp(const uint8_t temp, const bool remember = true);
+
164  void _setMode(const uint8_t mode);
+
165  int8_t getTempOffset(void);
+
166 };
+
167 
+
168 #endif // IR_WHIRLPOOL_H_
+
+
const uint8_t kWhirlpoolAcLightOffset
Definition: ir_Whirlpool.h:58
+
void send(const uint16_t repeat=kWhirlpoolAcDefaultRepeat, const bool calcchecksum=true)
Send the current internal state as an IR message.
Definition: ir_Whirlpool.cpp:139
+
const uint8_t kWhirlpoolAcOnTimerPos
Definition: ir_Whirlpool.h:72
+
void stateReset(void)
Reset the state of the remote to a known good state/sequence.
Definition: ir_Whirlpool.cpp:89
+
uint16_t getClock(void)
Get the clock time in nr. of minutes past midnight.
Definition: ir_Whirlpool.cpp:357
+
const uint8_t kWhirlpoolAcCommandSuper
Definition: ir_Whirlpool.h:78
+
int8_t calibrate(void)
Run the calibration to calculate uSec timing offsets for this platform.
Definition: ir_Whirlpool.h:103
+
const uint8_t kWhirlpoolAcFanSize
Definition: ir_Whirlpool.h:46
+
uint8_t convertMode(const stdAc::opmode_t mode)
Convert a stdAc::opmode_t enum into its native mode.
Definition: ir_Whirlpool.cpp:485
+
const uint8_t kWhirlpoolAcSuperPos
Definition: ir_Whirlpool.h:64
+
void _setTemp(const uint8_t temp, const bool remember=true)
Set the temperature.
Definition: ir_Whirlpool.cpp:198
+
fanspeed_t
Common A/C settings for Fan Speeds.
Definition: IRsend.h:58
+
whirlpool_ac_remote_model_t
Whirlpool A/C model numbers.
Definition: IRsend.h:152
+
const uint8_t kWhirlpoolAcAutoTemp
Definition: ir_Whirlpool.h:54
+
const uint8_t kWhirlpoolAcModePos
Definition: ir_Whirlpool.h:44
+
const uint8_t kWhirlpoolAcFanHigh
Definition: ir_Whirlpool.h:48
+
const uint8_t kWhirlpoolAcPowerTogglePos
Definition: ir_Whirlpool.h:60
+
const uint8_t kWhirlpoolAcMaxTemp
Definition: ir_Whirlpool.h:53
+
const uint8_t kWhirlpoolAcAltTempPos
Definition: ir_Whirlpool.h:87
+
const uint8_t kWhirlpoolAcAuto
Definition: ir_Whirlpool.h:39
+
const uint8_t kWhirlpoolAcFanPos
Definition: ir_Whirlpool.h:51
+
uint8_t convertFan(const stdAc::fanspeed_t speed)
Convert a stdAc::fanspeed_t enum into it's native speed.
Definition: ir_Whirlpool.cpp:498
+
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed)
Convert a native fan speed into its stdAc equivilant.
Definition: ir_Whirlpool.cpp:525
+
bool isOnTimerEnabled(void)
Is the On timer enabled?
Definition: ir_Whirlpool.cpp:400
+
IRWhirlpoolAc(const uint16_t pin, const bool inverted=false, const bool use_modulation=true)
Class constructor.
Definition: ir_Whirlpool.cpp:84
+
uint8_t getMode(void)
Get the operating mode setting of the A/C.
Definition: ir_Whirlpool.cpp:255
+
const uint8_t kWhirlpoolAcCommandOnTimer
Definition: ir_Whirlpool.h:79
+ +
const uint8_t kWhirlpoolAcTempPos
Definition: ir_Whirlpool.h:55
+
bool getLight(void)
Get the Light (Display/LED) setting of the A/C.
Definition: ir_Whirlpool.cpp:308
+
void setTemp(const uint8_t temp)
Set the temperature.
Definition: ir_Whirlpool.cpp:209
+
const uint8_t kWhirlpoolAcTimerEnableOffset
Definition: ir_Whirlpool.h:69
+
const uint8_t kWhirlpoolAcCommandIFeel
Definition: ir_Whirlpool.h:82
+
bool getSwing(void)
Get the (vertical) swing setting of the A/C.
Definition: ir_Whirlpool.cpp:293
+
const uint8_t kWhirlpoolAcModeOffset
Definition: ir_Whirlpool.h:43
+
void setClock(const uint16_t minspastmidnight)
Set the clock time in nr. of minutes past midnight.
Definition: ir_Whirlpool.cpp:351
+
Class for sending all basic IR protocols.
Definition: IRsend.h:170
+
const uint8_t kWhirlpoolAcSuperMask
Definition: ir_Whirlpool.h:63
+
int8_t calibrate(uint16_t hz=38000U)
Calculate & set any offsets to account for execution times during sending.
Definition: IRsend.cpp:207
+
const uint8_t kWhirlpoolAcChecksumByte1
Definition: ir_Whirlpool.h:36
+
bool getSleep(void)
Get the Sleep setting of the A/C.
Definition: ir_Whirlpool.cpp:444
+
const uint8_t kWhirlpoolAcMinuteSize
Definition: ir_Whirlpool.h:68
+
uint16_t getTime(const uint16_t pos)
Get the time in nr. of minutes past midnight.
Definition: ir_Whirlpool.cpp:328
+
void enableTimer(const uint16_t pos, const bool state)
Enable the timer enabled at the given byte offset.
Definition: ir_Whirlpool.cpp:345
+
Class for handling detailed Whirlpool A/C messages.
Definition: ir_Whirlpool.h:91
+
std::string String
Definition: IRremoteESP8266.h:1093
+
const uint8_t kWhirlpoolAcCommandPos
Definition: ir_Whirlpool.h:73
+
const uint8_t kWhirlpoolAcCommandMode
Definition: ir_Whirlpool.h:80
+
uint8_t getTemp(void)
Get the current temperature setting.
Definition: ir_Whirlpool.cpp:217
+
int8_t getTempOffset(void)
Calculate the temp. offset in deg C for the current model.
Definition: ir_Whirlpool.cpp:187
+
uint8_t getFan(void)
Get the current fan speed setting.
Definition: ir_Whirlpool.cpp:278
+
const uint8_t kWhirlpoolAcCool
Definition: ir_Whirlpool.h:40
+
const uint8_t kWhirlpoolAcSleepPos
Definition: ir_Whirlpool.h:62
+
whirlpool_ac_remote_model_t getModel(void)
Get/Detect the model of the A/C.
Definition: ir_Whirlpool.cpp:162
+
const uint8_t kWhirlpoolAcCommandOffTimer
Definition: ir_Whirlpool.h:85
+
const uint8_t kWhirlpoolAcSwing1Offset
Definition: ir_Whirlpool.h:56
+ +
const uint8_t kWhirlpoolAcCommandSwing
Definition: ir_Whirlpool.h:81
+
bool isOffTimerEnabled(void)
Is the Off timer enabled?
Definition: ir_Whirlpool.cpp:375
+
const uint8_t kWhirlpoolAcMinuteOffset
Definition: ir_Whirlpool.h:67
+
static bool validChecksum(const uint8_t state[], const uint16_t length=kWhirlpoolAcStateLength)
Verify the checksum is valid for a given state.
Definition: ir_Whirlpool.cpp:104
+
const uint8_t kWhirlpoolAcFanMedium
Definition: ir_Whirlpool.h:49
+
const uint8_t kWhirlpoolAcDry
Definition: ir_Whirlpool.h:41
+
const uint8_t kWhirlpoolAcAltTempOffset
Definition: ir_Whirlpool.h:86
+
void setPowerToggle(const bool on)
Change the power toggle setting.
Definition: ir_Whirlpool.cpp:413
+
void setOffTimer(const uint16_t minspastmidnight)
Set the Off Timer time.
Definition: ir_Whirlpool.cpp:363
+
const uint8_t kWhirlpoolAcSwing2Offset
Definition: ir_Whirlpool.h:57
+
const uint8_t kWhirlpoolAcCommandLight
Definition: ir_Whirlpool.h:74
+
uint8_t getCommand(void)
Get the Command (Button) setting of the A/C.
Definition: ir_Whirlpool.cpp:429
+
void _setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Whirlpool.cpp:225
+
const uint8_t kWhirlpoolAcFanLow
Definition: ir_Whirlpool.h:50
+
const uint16_t kWhirlpoolAcDefaultRepeat
Definition: IRremoteESP8266.h:1007
+
const uint8_t kWhirlpoolAcOffTimerPos
Definition: ir_Whirlpool.h:71
+
uint16_t getOffTimer(void)
Get the Off Timer time..
Definition: ir_Whirlpool.cpp:369
+
void setModel(const whirlpool_ac_remote_model_t model)
Set the model of the A/C to emulate.
Definition: ir_Whirlpool.cpp:171
+
void setSuper(const bool on)
Set the Super (Turbo/Jet) setting of the A/C.
Definition: ir_Whirlpool.cpp:450
+
const uint8_t kWhirlpoolAcChecksumByte2
Definition: ir_Whirlpool.h:37
+
const uint8_t kWhirlpoolAcFan
Definition: ir_Whirlpool.h:42
+
uint16_t getOnTimer(void)
Get the On Timer time..
Definition: ir_Whirlpool.cpp:394
+
const uint8_t kWhirlpoolAcCommandFanSpeed
Definition: ir_Whirlpool.h:83
+
void setCommand(const uint8_t code)
Set the Command (Button) setting of the A/C.
Definition: ir_Whirlpool.cpp:478
+
const uint16_t kWhirlpoolAcStateLength
Definition: IRremoteESP8266.h:1005
+
const uint8_t kWhirlpoolAcHourOffset
Definition: ir_Whirlpool.h:65
+
void setRaw(const uint8_t new_code[], const uint16_t length=kWhirlpoolAcStateLength)
Set the internal state from a valid code for this protocol.
Definition: ir_Whirlpool.cpp:156
+
const uint8_t kWhirlpoolAcMinTemp
Definition: ir_Whirlpool.h:52
+
bool getSuper(void)
Get the Super (Turbo/Jet) setting of the A/C.
Definition: ir_Whirlpool.cpp:472
+
void setSleep(const bool on)
Set the Sleep setting of the A/C.
Definition: ir_Whirlpool.cpp:435
+
uint8_t remote_state[kWhirlpoolAcStateLength]
The state in IR code form.
Definition: ir_Whirlpool.h:156
+
void setMode(const uint8_t mode)
Set the operating mode of the A/C.
Definition: ir_Whirlpool.cpp:248
+
String toString(void)
Convert the current internal state into a human readable string.
Definition: ir_Whirlpool.cpp:563
+
const uint8_t kWhirlpoolAcHeat
Definition: ir_Whirlpool.h:38
+
void checksum(const uint16_t length=kWhirlpoolAcStateLength)
Calculate & set the checksum for the current internal state of the remote.
Definition: ir_Whirlpool.cpp:125
+
void enableOffTimer(const bool on)
Enable the Off Timer.
Definition: ir_Whirlpool.cpp:381
+
const uint8_t kWhirlpoolAcCommandPower
Definition: ir_Whirlpool.h:75
+
void enableOnTimer(const bool on)
Enable the On Timer.
Definition: ir_Whirlpool.cpp:406
+
IRsend _irsend
Instance of the IR send class.
Definition: ir_Whirlpool.h:150
+
void setOnTimer(const uint16_t minspastmidnight)
Set the On Timer time.
Definition: ir_Whirlpool.cpp:388
+
uint8_t _desiredtemp
The last user explicitly set temperature.
Definition: ir_Whirlpool.h:157
+
bool getPowerToggle(void)
Get the value of the current power toggle setting.
Definition: ir_Whirlpool.cpp:422
+
const uint8_t kWhirlpoolAcCommandTemp
Definition: ir_Whirlpool.h:76
+
const uint8_t kWhirlpoolAcFanOffset
Definition: ir_Whirlpool.h:45
+
const uint8_t kWhirlpoolAcCommand6thSense
Definition: ir_Whirlpool.h:84
+
const uint8_t kWhirlpoolAcCommandSleep
Definition: ir_Whirlpool.h:77
+
const uint8_t kWhirlpoolAcClockPos
Definition: ir_Whirlpool.h:70
+
const uint8_t kWhirlpoolAcPowerToggleOffset
Definition: ir_Whirlpool.h:59
+
void begin(void)
Set up hardware to be able to send a message.
Definition: ir_Whirlpool.cpp:98
+
const uint8_t kWhirlpoolAcSleepOffset
Definition: ir_Whirlpool.h:61
+
stdAc::state_t toCommon(void)
Convert the current internal state into its stdAc::state_t equivilant.
Definition: ir_Whirlpool.cpp:536
+
Structure to hold a common A/C state.
Definition: IRsend.h:97
+
void setFan(const uint8_t speed)
Set the speed of the fan.
Definition: ir_Whirlpool.cpp:262
+
void setLight(const bool on)
Set the Light (Display/LED) setting of the A/C.
Definition: ir_Whirlpool.cpp:301
+
void setTime(const uint16_t pos, const uint16_t minspastmidnight)
Set the time in nr. of minutes past midnight.
Definition: ir_Whirlpool.cpp:315
+
void setSwing(const bool on)
Set the (vertical) swing setting of the A/C.
Definition: ir_Whirlpool.cpp:285
+
static stdAc::opmode_t toCommonMode(const uint8_t mode)
Convert a native mode into its stdAc equivilant.
Definition: ir_Whirlpool.cpp:512
+
const uint8_t kWhirlpoolAcHourSize
Definition: ir_Whirlpool.h:66
+
const uint8_t kWhirlpoolAcFanAuto
Definition: ir_Whirlpool.h:47
+
uint8_t * getRaw(const bool calcchecksum=true)
Get a copy of the internal state/code for this protocol.
Definition: ir_Whirlpool.cpp:148
+
bool isTimerEnabled(const uint16_t pos)
Is the timer enabled at the given byte offset?
Definition: ir_Whirlpool.cpp:338
+
opmode_t
Common A/C settings for A/C operating modes.
Definition: IRsend.h:46
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Whynter_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Whynter_8cpp.html new file mode 100644 index 000000000..11e6a0701 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Whynter_8cpp.html @@ -0,0 +1,344 @@ + + + + + + + +IRremoteESP8266: src/ir_Whynter.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Whynter.cpp File Reference
+
+
+ +

Support for Whynter protocols. Whynter A/C ARC-110WD added by Francesco Meschia Whynter originally added from https://github.com/shirriff/Arduino-IRremote/. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kWhynterTick = 50
 
const uint16_t kWhynterHdrMarkTicks = 57
 
const uint16_t kWhynterHdrMark = kWhynterHdrMarkTicks * kWhynterTick
 
const uint16_t kWhynterHdrSpaceTicks = 57
 
const uint16_t kWhynterHdrSpace = kWhynterHdrSpaceTicks * kWhynterTick
 
const uint16_t kWhynterBitMarkTicks = 15
 
const uint16_t kWhynterBitMark = kWhynterBitMarkTicks * kWhynterTick
 
const uint16_t kWhynterOneSpaceTicks = 43
 
const uint16_t kWhynterOneSpace = kWhynterOneSpaceTicks * kWhynterTick
 
const uint16_t kWhynterZeroSpaceTicks = 15
 
const uint16_t kWhynterZeroSpace = kWhynterZeroSpaceTicks * kWhynterTick
 
const uint16_t kWhynterMinCommandLengthTicks = 2160
 
const uint32_t kWhynterMinCommandLength
 
const uint16_t kWhynterMinGapTicks
 
const uint16_t kWhynterMinGap = kWhynterMinGapTicks * kWhynterTick
 
+

Detailed Description

+

Support for Whynter protocols. Whynter A/C ARC-110WD added by Francesco Meschia Whynter originally added from https://github.com/shirriff/Arduino-IRremote/.

+

Variable Documentation

+ +

◆ kWhynterBitMark

+ +
+
+ + + + +
const uint16_t kWhynterBitMark = kWhynterBitMarkTicks * kWhynterTick
+
+ +
+
+ +

◆ kWhynterBitMarkTicks

+ +
+
+ + + + +
const uint16_t kWhynterBitMarkTicks = 15
+
+ +
+
+ +

◆ kWhynterHdrMark

+ +
+
+ + + + +
const uint16_t kWhynterHdrMark = kWhynterHdrMarkTicks * kWhynterTick
+
+ +
+
+ +

◆ kWhynterHdrMarkTicks

+ +
+
+ + + + +
const uint16_t kWhynterHdrMarkTicks = 57
+
+ +
+
+ +

◆ kWhynterHdrSpace

+ +
+
+ + + + +
const uint16_t kWhynterHdrSpace = kWhynterHdrSpaceTicks * kWhynterTick
+
+ +
+
+ +

◆ kWhynterHdrSpaceTicks

+ +
+
+ + + + +
const uint16_t kWhynterHdrSpaceTicks = 57
+
+ +
+
+ +

◆ kWhynterMinCommandLength

+ +
+
+ + + + +
const uint32_t kWhynterMinCommandLength
+
+
+ +

◆ kWhynterMinCommandLengthTicks

+ +
+
+ + + + +
const uint16_t kWhynterMinCommandLengthTicks = 2160
+
+ +
+
+ +

◆ kWhynterMinGap

+ +
+
+ + + + +
const uint16_t kWhynterMinGap = kWhynterMinGapTicks * kWhynterTick
+
+ +
+
+ +

◆ kWhynterMinGapTicks

+ +
+
+ + + + +
const uint16_t kWhynterMinGapTicks
+
+
+ +

◆ kWhynterOneSpace

+ +
+
+ + + + +
const uint16_t kWhynterOneSpace = kWhynterOneSpaceTicks * kWhynterTick
+
+ +
+
+ +

◆ kWhynterOneSpaceTicks

+ +
+
+ + + + +
const uint16_t kWhynterOneSpaceTicks = 43
+
+ +
+
+ +

◆ kWhynterTick

+ +
+
+ + + + +
const uint16_t kWhynterTick = 50
+
+ +
+
+ +

◆ kWhynterZeroSpace

+ +
+
+ + + + +
const uint16_t kWhynterZeroSpace = kWhynterZeroSpaceTicks * kWhynterTick
+
+ +
+
+ +

◆ kWhynterZeroSpaceTicks

+ +
+
+ + + + +
const uint16_t kWhynterZeroSpaceTicks = 15
+
+ +
+
+
+
const uint16_t kWhynterBits
Definition: IRremoteESP8266.h:1008
+
const uint16_t kWhynterZeroSpaceTicks
Definition: ir_Whynter.cpp:27
+
const uint16_t kWhynterMinCommandLengthTicks
Definition: ir_Whynter.cpp:29
+
const uint16_t kWhynterBitMarkTicks
Definition: ir_Whynter.cpp:23
+
const uint16_t kWhynterTick
Definition: ir_Whynter.cpp:18
+
const uint16_t kWhynterOneSpaceTicks
Definition: ir_Whynter.cpp:25
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Zepeal_8cpp.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Zepeal_8cpp.html new file mode 100644 index 000000000..a28b6cdcd --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/ir__Zepeal_8cpp.html @@ -0,0 +1,333 @@ + + + + + + + +IRremoteESP8266: src/ir_Zepeal.cpp File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+ +
+
ir_Zepeal.cpp File Reference
+
+
+ +

Support for Zepeal protocol. This protocol uses fixed length bit encoding. Most official information about Zepeal seems to be from Denkyosha. +More...

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const uint16_t kZepealHdrMark = 2330
 
const uint16_t kZepealHdrSpace = 3380
 
const uint16_t kZepealOneMark = 1300
 
const uint16_t kZepealZeroMark = 420
 
const uint16_t kZepealOneSpace = kZepealZeroMark
 
const uint16_t kZepealZeroSpace = kZepealOneMark
 
const uint16_t kZepealFooterMark = 420
 
const uint16_t kZepealGap = 6750
 
const uint8_t kZepealTolerance = 40
 
const uint8_t kZepealSignature = 0x6C
 
const uint16_t kZepealCommandSpeed = 0x6C82
 
const uint16_t kZepealCommandOffOn = 0x6C81
 
const uint16_t kZepealCommandRhythm = 0x6C84
 
const uint16_t kZepealCommandOffTimer = 0x6C88
 
const uint16_t kZepealCommandOnTimer = 0x6CC3
 
+

Detailed Description

+

Support for Zepeal protocol. This protocol uses fixed length bit encoding. Most official information about Zepeal seems to be from Denkyosha.

+
See also
https://www.denkyosha.co.jp/
+

Variable Documentation

+ +

◆ kZepealCommandOffOn

+ +
+
+ + + + +
const uint16_t kZepealCommandOffOn = 0x6C81
+
+ +
+
+ +

◆ kZepealCommandOffTimer

+ +
+
+ + + + +
const uint16_t kZepealCommandOffTimer = 0x6C88
+
+ +
+
+ +

◆ kZepealCommandOnTimer

+ +
+
+ + + + +
const uint16_t kZepealCommandOnTimer = 0x6CC3
+
+ +
+
+ +

◆ kZepealCommandRhythm

+ +
+
+ + + + +
const uint16_t kZepealCommandRhythm = 0x6C84
+
+ +
+
+ +

◆ kZepealCommandSpeed

+ +
+
+ + + + +
const uint16_t kZepealCommandSpeed = 0x6C82
+
+ +
+
+ +

◆ kZepealFooterMark

+ +
+
+ + + + +
const uint16_t kZepealFooterMark = 420
+
+ +
+
+ +

◆ kZepealGap

+ +
+
+ + + + +
const uint16_t kZepealGap = 6750
+
+ +
+
+ +

◆ kZepealHdrMark

+ +
+
+ + + + +
const uint16_t kZepealHdrMark = 2330
+
+ +
+
+ +

◆ kZepealHdrSpace

+ +
+
+ + + + +
const uint16_t kZepealHdrSpace = 3380
+
+ +
+
+ +

◆ kZepealOneMark

+ +
+
+ + + + +
const uint16_t kZepealOneMark = 1300
+
+ +
+
+ +

◆ kZepealOneSpace

+ +
+
+ + + + +
const uint16_t kZepealOneSpace = kZepealZeroMark
+
+ +
+
+ +

◆ kZepealSignature

+ +
+
+ + + + +
const uint8_t kZepealSignature = 0x6C
+
+ +
+
+ +

◆ kZepealTolerance

+ +
+
+ + + + +
const uint8_t kZepealTolerance = 40
+
+ +
+
+ +

◆ kZepealZeroMark

+ +
+
+ + + + +
const uint16_t kZepealZeroMark = 420
+
+ +
+
+ +

◆ kZepealZeroSpace

+ +
+
+ + + + +
const uint16_t kZepealZeroSpace = kZepealOneMark
+
+ +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/it-IT_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/it-IT_8h.html new file mode 100644 index 000000000..8bd3af9fa --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/it-IT_8h.html @@ -0,0 +1,82 @@ + + + + + + + +IRremoteESP8266: src/locale/it-IT.h File Reference + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
it-IT.h File Reference
+
+ + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/it-IT_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/it-IT_8h_source.html new file mode 100644 index 000000000..4b554dec9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/it-IT_8h_source.html @@ -0,0 +1,239 @@ + + + + + + + +IRremoteESP8266: src/locale/it-IT.h Source File + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ + +
+
+
+
it-IT.h
+
+
+Go to the documentation of this file.
1 // Copyright 2020 - Enrico Gueli (@egueli)
+
2 // Locale/language file for Italian.
+
3 // This file will override the default values located in `defaults.h`.
+
4 
+
5 #ifndef LOCALE_IT_IT_H_
+
6 #define LOCALE_IT_IT_H_
+
7 
+
8 #define D_STR_UNKNOWN "SCONOSCIUTO"
+
9 #define D_STR_PROTOCOL "Protocollo"
+
10 #define D_STR_POWER "Accensione"
+
11 #define D_STR_PREVIOUS "Precedente"
+
12 #define D_STR_PREVIOUSPOWER D_STR_POWER " " D_STR_PREVIOUS
+
13 #define D_STR_ON "Acceso"
+
14 #define D_STR_OFF "Spento"
+
15 #define D_STR_MODE "Modalità"
+
16 #define D_STR_TOGGLE "Alterna"
+
17 #define D_STR_SLEEP "Sonno"
+
18 #define D_STR_LIGHT "Leggero"
+
19 #define D_STR_POWERFUL "Forte"
+
20 #define D_STR_QUIET "Silenzioso"
+
21 #define D_STR_ECONO "Eco"
+
22 #define D_STR_SWING "Swing"
+
23 #define D_STR_SWINGH D_STR_SWING"(O)" // Set `D_STR_SWING` first!
+
24 #define D_STR_SWINGV D_STR_SWING"(V)" // Set `D_STR_SWING` first!
+
25 #define D_STR_MOULD "Muffa"
+
26 #define D_STR_CLEAN "Pulizia"
+
27 #define D_STR_PURIFY "Purifica"
+
28 #define D_STR_TIMER "Timer"
+
29 #define D_STR_ONTIMER D_STR_ON " " D_STR_TIMER // Set `D_STR_ON` first!
+
30 #define D_STR_OFFTIMER D_STR_OFF " " D_STR_TIMER // Set `D_STR_OFF` first!
+
31 #define D_STR_CLOCK "Orologio"
+
32 #define D_STR_COMMAND "Comando"
+
33 #define D_STR_MODEL "Modello"
+
34 #define D_STR_TEMP "Temp"
+
35 #define D_STR_HUMID "Umido"
+
36 #define D_STR_SAVE "Salva"
+
37 #define D_STR_EYE "Occhio"
+
38 #define D_STR_FOLLOW "Segui"
+
39 #define D_STR_ION "Ioni"
+
40 #define D_STR_FRESH "Fresco"
+
41 #define D_STR_HOLD "Mantieni"
+
42 #define D_STR_8C_HEAT "8C " D_STR_HEAT // Set `D_STR_HEAT` first!
+
43 #define D_STR_BUTTON "Pulsante"
+
44 #define D_STR_NIGHT "Notte"
+
45 #define D_STR_SILENT "Silenzioso"
+
46 #define D_STR_FILTER "Filtro"
+
47 #define D_STR_UP "Su"
+
48 #define D_STR_TEMPUP D_STR_TEMP " " D_STR_UP // Set `D_STR_TEMP` first!
+
49 #define D_STR_DOWN "Giù"
+
50 #define D_STR_TEMPDOWN D_STR_TEMP " " D_STR_DOWN // Set `D_STR_TEMP` first!
+
51 #define D_STR_CHANGE "Cambia"
+
52 #define D_STR_START "Avvia"
+
53 #define D_STR_STOP "Ferma"
+
54 #define D_STR_MOVE "Muovi"
+
55 #define D_STR_SET "Imposta"
+
56 #define D_STR_CANCEL "Annulla"
+
57 #define D_STR_SENSOR "Sensore"
+
58 #define D_STR_WEEKLY "Settimanale"
+
59 #define D_STR_WEEKLYTIMER D_STR_WEEKLY " " D_STR_TIMER // Needs `D_STR_WEEKLY`!
+
60 #define D_STR_LAST "Ultimo"
+
61 #define D_STR_FAST "Veloce"
+
62 #define D_STR_SLOW "Lento"
+
63 #define D_STR_AIRFLOW "Flusso d'aria"
+
64 #define D_STR_STEP "Passo"
+
65 #define D_STR_NA "N/D"
+
66 #define D_STR_OUTSIDE "Esterno"
+
67 #define D_STR_LOUD "Rumoroso"
+
68 #define D_STR_UPPER "Superiore"
+
69 #define D_STR_LOWER "Inferiore"
+
70 #define D_STR_CIRCULATE "Circolare"
+
71 #define D_STR_CEILING "Soffitto"
+
72 #define D_STR_WALL "Muro"
+
73 #define D_STR_ROOM "Camera"
+
74 #define D_STR_FIXED "Fisso"
+
75 
+
76 #define D_STR_AUTO "Auto"
+
77 #define D_STR_AUTOMATIC "Automatico"
+
78 #define D_STR_MANUAL "Manuale"
+
79 #define D_STR_COOL "Fresco"
+
80 #define D_STR_HEAT "Caldo"
+
81 #define D_STR_FAN "Ventola"
+
82 #define D_STR_FANONLY "solo_ventola"
+
83 #define D_STR_DRY "Secco"
+
84 
+
85 #define D_STR_MAX "Max"
+
86 #define D_STR_MAXIMUM "Massimo"
+
87 #define D_STR_MINIMUM "Minimo"
+
88 #define D_STR_MEDIUM "Medio"
+
89 
+
90 #define D_STR_HIGHEST "Molto alto"
+
91 #define D_STR_HIGH "Alto"
+
92 #define D_STR_MID "Med"
+
93 #define D_STR_MIDDLE "Medio"
+
94 #define D_STR_LOW "Basso"
+
95 #define D_STR_LOWEST "Bassissimo"
+
96 #define D_STR_RIGHT "Destra"
+
97 #define D_STR_MAXRIGHT D_STR_MAX " " D_STR_RIGHT // Set `D_STR_MAX` first!
+
98 #define D_STR_RIGHTMAX_NOSPACE D_STR_RIGHT D_STR_MAX // Set `D_STR_MAX` first!
+
99 #define D_STR_LEFT "Sinistra"
+
100 #define D_STR_MAXLEFT D_STR_MAX " " D_STR_LEFT // Set `D_STR_MAX` first!
+
101 #define D_STR_LEFTMAX_NOSPACE D_STR_LEFT D_STR_MAX // Set `D_STR_MAX` first!
+
102 #define D_STR_WIDE "Largo"
+
103 #define D_STR_CENTRE "Centro"
+
104 #define D_STR_TOP "Superiore"
+
105 #define D_STR_BOTTOM "Inferiore"
+
106 // Compound words/phrases/descriptions from pre-defined words.
+
107 // Note: Obviously these need to be defined *after* their component words.
+
108 
+
109 #define D_STR_EYEAUTO D_STR_EYE " " D_STR_AUTO
+
110 #define D_STR_LIGHTTOGGLE D_STR_LIGHT " " D_STR_TOGGLE
+
111 #define D_STR_OUTSIDEQUIET D_STR_OUTSIDE " " D_STR_QUIET
+
112 #define D_STR_POWERTOGGLE D_STR_POWER " " D_STR_TOGGLE
+
113 #define D_STR_SENSORTEMP D_STR_SENSOR " " D_STR_TEMP
+
114 #define D_STR_SLEEP_TIMER D_STR_SLEEP " " D_STR_TIMER
+
115 #define D_STR_SWINGVMODE D_STR_SWINGV " " D_STR_MODE
+
116 #define D_STR_SWINGVTOGGLE D_STR_SWINGV " " D_STR_TOGGLE
+
117 // Separators
+
118 #ifndef D_CHR_TIME_SEP
+
119 #define D_CHR_TIME_SEP '.'
+
120 #endif // D_CHR_TIME_SEP
+
121 
+
122 #define D_STR_SPACELBRACE " ("
+
123 #define D_STR_COMMASPACE ", "
+
124 #define D_STR_COLONSPACE ": "
+
125 
+
126 #define D_STR_DAY "Giorno"
+
127 #define D_STR_DAYS D_STR_DAY "s"
+
128 #define D_STR_HOUR "Ore"
+
129 #define D_STR_HOURS D_STR_HOUR "s"
+
130 #define D_STR_MINUTE "Minuti"
+
131 #define D_STR_MINUTES D_STR_MINUTE "s"
+
132 #define D_STR_SECOND "Secondi"
+
133 #define D_STR_SECONDS D_STR_SECOND "s"
+
134 #define D_STR_NOW "Adesso"
+
135 #define D_STR_THREELETTERDAYS "DomLunMarMerGioVenSab"
+
136 
+
137 #define D_STR_YES "Sì"
+
138 #define D_STR_TRUE "Vero"
+
139 #define D_STR_FALSE "Falso"
+
140 
+
141 #define D_STR_REPEAT "Ripeti"
+
142 #define D_STR_CODE "Codice"
+
143 #define D_STR_BITS "Bit"
+
144 
+
145 // IRrecvDumpV2+
+
146 #define D_STR_LIBRARY "Libreria"
+
147 #define D_STR_MESGDESC "Desc. Mess."
+
148 #define D_STR_IRRECVDUMP_STARTUP \
+
149  "IRrecvDump è ora attivo e in attesa di segnali IR dal pin %d"
+
150 
+
151 #ifndef D_WARN_BUFFERFULL
+
152 #define D_WARN_BUFFERFULL \
+
153  "ATTENZIONE: il codice IR è troppo grande per il buffer (>= %d). " \
+
154  "Non fare affidamento a questi risultati finché questo problema " \
+
155  "non è risolto." \
+
156  "Modifica e aumenta `kCaptureBufferSize`."
+
157 #endif // D_WARN_BUFFERFULL
+
158 
+
159 #endif // LOCALE_IT_IT_H_
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/jquery.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/jquery.js new file mode 100644 index 000000000..103c32d79 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/jquery.js @@ -0,0 +1,35 @@ +/*! jQuery v3.4.1 | (c) JS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],E=C.document,r=Object.getPrototypeOf,s=t.slice,g=t.concat,u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.4.1",k=function(e,t){return new k.fn.init(e,t)},p=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function d(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp($),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+$),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),ne=function(e,t,n){var r="0x"+t-65536;return r!=r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(m.childNodes),m.childNodes),t[m.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&((e?e.ownerDocument||e:m)!==C&&T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!A[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&U.test(t)){(s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=k),o=(l=h(t)).length;while(o--)l[o]="#"+s+" "+xe(l[o]);c=l.join(","),f=ee.test(t)&&ye(e.parentNode)||e}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){A(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return g(t.replace(B,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[k]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:m;return r!==C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),m!==C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=k,!C.getElementsByName||!C.getElementsByName(k).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+k+"-]").length||v.push("~="),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+k+"+*").length||v.push(".#.+[+~]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",$)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e===C||e.ownerDocument===m&&y(m,e)?-1:t===C||t.ownerDocument===m&&y(m,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===C?-1:t===C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]===m?-1:s[r]===m?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if((e.ownerDocument||e)!==C&&T(e),d.matchesSelector&&E&&!A[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){A(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=p[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&p(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?k.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?k.grep(e,function(e){return e===n!==r}):"string"!=typeof n?k.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(k.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||q,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:L.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof k?t[0]:t,k.merge(this,k.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),D.test(r[1])&&k.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(k):k.makeArray(e,this)}).prototype=k.fn,q=k(E);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i,ge={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?k.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;nx",y.noCloneChecked=!!me.cloneNode(!0).lastChild.defaultValue;var Te=/^key/,Ce=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ee=/^([^.]*)(?:\.(.+)|)/;function ke(){return!0}function Se(){return!1}function Ne(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==("focus"===t)}function Ae(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)Ae(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Se;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return k().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=k.guid++)),e.each(function(){k.event.add(this,t,i,r,n)})}function De(e,i,o){o?(Q.set(e,i,!1),k.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Q.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(k.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Q.set(this,i,r),t=o(this,i),this[i](),r!==(n=Q.get(this,i))||t?Q.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else r.length&&(Q.set(this,i,{value:k.event.trigger(k.extend(r[0],k.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Q.get(e,i)&&k.event.add(e,i,ke)}k.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.get(t);if(v){n.handler&&(n=(o=n).handler,i=o.selector),i&&k.find.matchesSelector(ie,i),n.guid||(n.guid=k.guid++),(u=v.events)||(u=v.events={}),(a=v.handle)||(a=v.handle=function(e){return"undefined"!=typeof k&&k.event.triggered!==e.type?k.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(R)||[""]).length;while(l--)d=g=(s=Ee.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=k.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=k.event.special[d]||{},c=k.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&k.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),k.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.hasData(e)&&Q.get(e);if(v&&(u=v.events)){l=(t=(t||"").match(R)||[""]).length;while(l--)if(d=g=(s=Ee.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){f=k.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||k.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)k.event.remove(e,d+t[l],n,r,!0);k.isEmptyObject(u)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=k.event.fix(e),u=new Array(arguments.length),l=(Q.get(this,"events")||{})[s.type]||[],c=k.event.special[s.type]||{};for(u[0]=s,t=1;t\x20\t\r\n\f]*)[^>]*)\/>/gi,qe=/\s*$/g;function Oe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Re(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Me(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(Q.hasData(e)&&(o=Q.access(e),a=Q.set(t,o),l=o.events))for(i in delete a.handle,a.events={},l)for(n=0,r=l[i].length;n")},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=oe(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||k.isXMLDoc(e)))for(a=ve(c),r=0,i=(o=ve(e)).length;r").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Vt,Gt=[],Yt=/(=)\?(?=&|$)|\?\?/;k.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Gt.pop()||k.expando+"_"+kt++;return this[e]=!0,e}}),k.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Yt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Yt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Yt,"$1"+r):!1!==e.jsonp&&(e.url+=(St.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||k.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?k(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Gt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Vt=E.implementation.createHTMLDocument("").body).innerHTML="
",2===Vt.childNodes.length),k.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=D.exec(e))?[t.createElement(i[1])]:(i=we([e],t,o),o&&o.length&&k(o).remove(),k.merge([],i.childNodes)));var r,i,o},k.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(k.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},k.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){k.fn[t]=function(e){return this.on(t,e)}}),k.expr.pseudos.animated=function(t){return k.grep(k.timers,function(e){return t===e.elem}).length},k.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=k.css(e,"position"),c=k(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=k.css(e,"top"),u=k.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,k.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},k.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){k.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===k.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===k.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=k(e).offset()).top+=k.css(e,"borderTopWidth",!0),i.left+=k.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-k.css(r,"marginTop",!0),left:t.left-i.left-k.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===k.css(e,"position"))e=e.offsetParent;return e||ie})}}),k.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;k.fn[t]=function(e){return _(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),k.each(["top","left"],function(e,n){k.cssHooks[n]=ze(y.pixelPosition,function(e,t){if(t)return t=_e(e,n),$e.test(t)?k(e).position()[n]+"px":t})}),k.each({Height:"height",Width:"width"},function(a,s){k.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){k.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return _(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?k.css(e,t,i):k.style(e,t,n,i)},s,n?e:void 0,n)}})}),k.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){k.fn[n]=function(e,t){return 0a;a++)for(i in o[a])n=o[a][i],o[a].hasOwnProperty(i)&&void 0!==n&&(e[i]=t.isPlainObject(n)?t.isPlainObject(e[i])?t.widget.extend({},e[i],n):t.widget.extend({},n):n);return e},t.widget.bridge=function(e,i){var n=i.prototype.widgetFullName||e;t.fn[e]=function(o){var a="string"==typeof o,r=s.call(arguments,1),h=this;return a?this.length||"instance"!==o?this.each(function(){var i,s=t.data(this,n);return"instance"===o?(h=s,!1):s?t.isFunction(s[o])&&"_"!==o.charAt(0)?(i=s[o].apply(s,r),i!==s&&void 0!==i?(h=i&&i.jquery?h.pushStack(i.get()):i,!1):void 0):t.error("no such method '"+o+"' for "+e+" widget instance"):t.error("cannot call methods on "+e+" prior to initialization; "+"attempted to call method '"+o+"'")}):h=void 0:(r.length&&(o=t.widget.extend.apply(null,[o].concat(r))),this.each(function(){var e=t.data(this,n);e?(e.option(o||{}),e._init&&e._init()):t.data(this,n,new i(o,this))})),h}},t.Widget=function(){},t.Widget._childConstructors=[],t.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"
",options:{classes:{},disabled:!1,create:null},_createWidget:function(e,s){s=t(s||this.defaultElement||this)[0],this.element=t(s),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=t(),this.hoverable=t(),this.focusable=t(),this.classesElementLookup={},s!==this&&(t.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===s&&this.destroy()}}),this.document=t(s.style?s.ownerDocument:s.document||s),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this.options=t.widget.extend({},this.options,this._getCreateOptions(),e),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){var e=this;this._destroy(),t.each(this.classesElementLookup,function(t,i){e._removeClass(i,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:t.noop,widget:function(){return this.element},option:function(e,i){var s,n,o,a=e;if(0===arguments.length)return t.widget.extend({},this.options);if("string"==typeof e)if(a={},s=e.split("."),e=s.shift(),s.length){for(n=a[e]=t.widget.extend({},this.options[e]),o=0;s.length-1>o;o++)n[s[o]]=n[s[o]]||{},n=n[s[o]];if(e=s.pop(),1===arguments.length)return void 0===n[e]?null:n[e];n[e]=i}else{if(1===arguments.length)return void 0===this.options[e]?null:this.options[e];a[e]=i}return this._setOptions(a),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return"classes"===t&&this._setOptionClasses(e),this.options[t]=e,"disabled"===t&&this._setOptionDisabled(e),this},_setOptionClasses:function(e){var i,s,n;for(i in e)n=this.classesElementLookup[i],e[i]!==this.options.classes[i]&&n&&n.length&&(s=t(n.get()),this._removeClass(n,i),s.addClass(this._classes({element:s,keys:i,classes:e,add:!0})))},_setOptionDisabled:function(t){this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!!t),t&&(this._removeClass(this.hoverable,null,"ui-state-hover"),this._removeClass(this.focusable,null,"ui-state-focus"))},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_classes:function(e){function i(i,o){var a,r;for(r=0;i.length>r;r++)a=n.classesElementLookup[i[r]]||t(),a=e.add?t(t.unique(a.get().concat(e.element.get()))):t(a.not(e.element).get()),n.classesElementLookup[i[r]]=a,s.push(i[r]),o&&e.classes[i[r]]&&s.push(e.classes[i[r]])}var s=[],n=this;return e=t.extend({element:this.element,classes:this.options.classes||{}},e),this._on(e.element,{remove:"_untrackClassesElement"}),e.keys&&i(e.keys.match(/\S+/g)||[],!0),e.extra&&i(e.extra.match(/\S+/g)||[]),s.join(" ")},_untrackClassesElement:function(e){var i=this;t.each(i.classesElementLookup,function(s,n){-1!==t.inArray(e.target,n)&&(i.classesElementLookup[s]=t(n.not(e.target).get()))})},_removeClass:function(t,e,i){return this._toggleClass(t,e,i,!1)},_addClass:function(t,e,i){return this._toggleClass(t,e,i,!0)},_toggleClass:function(t,e,i,s){s="boolean"==typeof s?s:i;var n="string"==typeof t||null===t,o={extra:n?e:i,keys:n?t:e,element:n?this.element:t,add:s};return o.element.toggleClass(this._classes(o),s),this},_on:function(e,i,s){var n,o=this;"boolean"!=typeof e&&(s=i,i=e,e=!1),s?(i=n=t(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,n=this.widget()),t.each(s,function(s,a){function r(){return e||o.options.disabled!==!0&&!t(this).hasClass("ui-state-disabled")?("string"==typeof a?o[a]:a).apply(o,arguments):void 0}"string"!=typeof a&&(r.guid=a.guid=a.guid||r.guid||t.guid++);var h=s.match(/^([\w:-]*)\s*(.*)$/),l=h[1]+o.eventNamespace,c=h[2];c?n.on(l,c,r):i.on(l,r)})},_off:function(e,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.off(i).off(i),this.bindings=t(this.bindings.not(e).get()),this.focusable=t(this.focusable.not(e).get()),this.hoverable=t(this.hoverable.not(e).get())},_delay:function(t,e){function i(){return("string"==typeof t?s[t]:t).apply(s,arguments)}var s=this;return setTimeout(i,e||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){this._addClass(t(e.currentTarget),null,"ui-state-hover")},mouseleave:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){this._addClass(t(e.currentTarget),null,"ui-state-focus")},focusout:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-focus")}})},_trigger:function(e,i,s){var n,o,a=this.options[e];if(s=s||{},i=t.Event(i),i.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),i.target=this.element[0],o=i.originalEvent)for(n in o)n in i||(i[n]=o[n]);return this.element.trigger(i,s),!(t.isFunction(a)&&a.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},t.each({show:"fadeIn",hide:"fadeOut"},function(e,i){t.Widget.prototype["_"+e]=function(s,n,o){"string"==typeof n&&(n={effect:n});var a,r=n?n===!0||"number"==typeof n?i:n.effect||i:e;n=n||{},"number"==typeof n&&(n={duration:n}),a=!t.isEmptyObject(n),n.complete=o,n.delay&&s.delay(n.delay),a&&t.effects&&t.effects.effect[r]?s[e](n):r!==e&&s[r]?s[r](n.duration,n.easing,o):s.queue(function(i){t(this)[e](),o&&o.call(s[0]),i()})}}),t.widget,function(){function e(t,e,i){return[parseFloat(t[0])*(u.test(t[0])?e/100:1),parseFloat(t[1])*(u.test(t[1])?i/100:1)]}function i(e,i){return parseInt(t.css(e,i),10)||0}function s(e){var i=e[0];return 9===i.nodeType?{width:e.width(),height:e.height(),offset:{top:0,left:0}}:t.isWindow(i)?{width:e.width(),height:e.height(),offset:{top:e.scrollTop(),left:e.scrollLeft()}}:i.preventDefault?{width:0,height:0,offset:{top:i.pageY,left:i.pageX}}:{width:e.outerWidth(),height:e.outerHeight(),offset:e.offset()}}var n,o=Math.max,a=Math.abs,r=/left|center|right/,h=/top|center|bottom/,l=/[\+\-]\d+(\.[\d]+)?%?/,c=/^\w+/,u=/%$/,d=t.fn.position;t.position={scrollbarWidth:function(){if(void 0!==n)return n;var e,i,s=t("
"),o=s.children()[0];return t("body").append(s),e=o.offsetWidth,s.css("overflow","scroll"),i=o.offsetWidth,e===i&&(i=s[0].clientWidth),s.remove(),n=e-i},getScrollInfo:function(e){var i=e.isWindow||e.isDocument?"":e.element.css("overflow-x"),s=e.isWindow||e.isDocument?"":e.element.css("overflow-y"),n="scroll"===i||"auto"===i&&e.widthi?"left":e>0?"right":"center",vertical:0>r?"top":s>0?"bottom":"middle"};l>p&&p>a(e+i)&&(u.horizontal="center"),c>f&&f>a(s+r)&&(u.vertical="middle"),u.important=o(a(e),a(i))>o(a(s),a(r))?"horizontal":"vertical",n.using.call(this,t,u)}),h.offset(t.extend(D,{using:r}))})},t.ui.position={fit:{left:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollLeft:s.offset.left,a=s.width,r=t.left-e.collisionPosition.marginLeft,h=n-r,l=r+e.collisionWidth-a-n;e.collisionWidth>a?h>0&&0>=l?(i=t.left+h+e.collisionWidth-a-n,t.left+=h-i):t.left=l>0&&0>=h?n:h>l?n+a-e.collisionWidth:n:h>0?t.left+=h:l>0?t.left-=l:t.left=o(t.left-r,t.left)},top:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollTop:s.offset.top,a=e.within.height,r=t.top-e.collisionPosition.marginTop,h=n-r,l=r+e.collisionHeight-a-n;e.collisionHeight>a?h>0&&0>=l?(i=t.top+h+e.collisionHeight-a-n,t.top+=h-i):t.top=l>0&&0>=h?n:h>l?n+a-e.collisionHeight:n:h>0?t.top+=h:l>0?t.top-=l:t.top=o(t.top-r,t.top)}},flip:{left:function(t,e){var i,s,n=e.within,o=n.offset.left+n.scrollLeft,r=n.width,h=n.isWindow?n.scrollLeft:n.offset.left,l=t.left-e.collisionPosition.marginLeft,c=l-h,u=l+e.collisionWidth-r-h,d="left"===e.my[0]?-e.elemWidth:"right"===e.my[0]?e.elemWidth:0,p="left"===e.at[0]?e.targetWidth:"right"===e.at[0]?-e.targetWidth:0,f=-2*e.offset[0];0>c?(i=t.left+d+p+f+e.collisionWidth-r-o,(0>i||a(c)>i)&&(t.left+=d+p+f)):u>0&&(s=t.left-e.collisionPosition.marginLeft+d+p+f-h,(s>0||u>a(s))&&(t.left+=d+p+f))},top:function(t,e){var i,s,n=e.within,o=n.offset.top+n.scrollTop,r=n.height,h=n.isWindow?n.scrollTop:n.offset.top,l=t.top-e.collisionPosition.marginTop,c=l-h,u=l+e.collisionHeight-r-h,d="top"===e.my[1],p=d?-e.elemHeight:"bottom"===e.my[1]?e.elemHeight:0,f="top"===e.at[1]?e.targetHeight:"bottom"===e.at[1]?-e.targetHeight:0,m=-2*e.offset[1];0>c?(s=t.top+p+f+m+e.collisionHeight-r-o,(0>s||a(c)>s)&&(t.top+=p+f+m)):u>0&&(i=t.top-e.collisionPosition.marginTop+p+f+m-h,(i>0||u>a(i))&&(t.top+=p+f+m))}},flipfit:{left:function(){t.ui.position.flip.left.apply(this,arguments),t.ui.position.fit.left.apply(this,arguments)},top:function(){t.ui.position.flip.top.apply(this,arguments),t.ui.position.fit.top.apply(this,arguments)}}}}(),t.ui.position,t.extend(t.expr[":"],{data:t.expr.createPseudo?t.expr.createPseudo(function(e){return function(i){return!!t.data(i,e)}}):function(e,i,s){return!!t.data(e,s[3])}}),t.fn.extend({disableSelection:function(){var t="onselectstart"in document.createElement("div")?"selectstart":"mousedown";return function(){return this.on(t+".ui-disableSelection",function(t){t.preventDefault()})}}(),enableSelection:function(){return this.off(".ui-disableSelection")}}),t.ui.focusable=function(i,s){var n,o,a,r,h,l=i.nodeName.toLowerCase();return"area"===l?(n=i.parentNode,o=n.name,i.href&&o&&"map"===n.nodeName.toLowerCase()?(a=t("img[usemap='#"+o+"']"),a.length>0&&a.is(":visible")):!1):(/^(input|select|textarea|button|object)$/.test(l)?(r=!i.disabled,r&&(h=t(i).closest("fieldset")[0],h&&(r=!h.disabled))):r="a"===l?i.href||s:s,r&&t(i).is(":visible")&&e(t(i)))},t.extend(t.expr[":"],{focusable:function(e){return t.ui.focusable(e,null!=t.attr(e,"tabindex"))}}),t.ui.focusable,t.fn.form=function(){return"string"==typeof this[0].form?this.closest("form"):t(this[0].form)},t.ui.formResetMixin={_formResetHandler:function(){var e=t(this);setTimeout(function(){var i=e.data("ui-form-reset-instances");t.each(i,function(){this.refresh()})})},_bindFormResetHandler:function(){if(this.form=this.element.form(),this.form.length){var t=this.form.data("ui-form-reset-instances")||[];t.length||this.form.on("reset.ui-form-reset",this._formResetHandler),t.push(this),this.form.data("ui-form-reset-instances",t)}},_unbindFormResetHandler:function(){if(this.form.length){var e=this.form.data("ui-form-reset-instances");e.splice(t.inArray(this,e),1),e.length?this.form.data("ui-form-reset-instances",e):this.form.removeData("ui-form-reset-instances").off("reset.ui-form-reset")}}},"1.7"===t.fn.jquery.substring(0,3)&&(t.each(["Width","Height"],function(e,i){function s(e,i,s,o){return t.each(n,function(){i-=parseFloat(t.css(e,"padding"+this))||0,s&&(i-=parseFloat(t.css(e,"border"+this+"Width"))||0),o&&(i-=parseFloat(t.css(e,"margin"+this))||0)}),i}var n="Width"===i?["Left","Right"]:["Top","Bottom"],o=i.toLowerCase(),a={innerWidth:t.fn.innerWidth,innerHeight:t.fn.innerHeight,outerWidth:t.fn.outerWidth,outerHeight:t.fn.outerHeight};t.fn["inner"+i]=function(e){return void 0===e?a["inner"+i].call(this):this.each(function(){t(this).css(o,s(this,e)+"px")})},t.fn["outer"+i]=function(e,n){return"number"!=typeof e?a["outer"+i].call(this,e):this.each(function(){t(this).css(o,s(this,e,!0,n)+"px")})}}),t.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),t.ui.keyCode={BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38},t.ui.escapeSelector=function(){var t=/([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g;return function(e){return e.replace(t,"\\$1")}}(),t.fn.labels=function(){var e,i,s,n,o;return this[0].labels&&this[0].labels.length?this.pushStack(this[0].labels):(n=this.eq(0).parents("label"),s=this.attr("id"),s&&(e=this.eq(0).parents().last(),o=e.add(e.length?e.siblings():this.siblings()),i="label[for='"+t.ui.escapeSelector(s)+"']",n=n.add(o.find(i).addBack(i))),this.pushStack(n))},t.fn.scrollParent=function(e){var i=this.css("position"),s="absolute"===i,n=e?/(auto|scroll|hidden)/:/(auto|scroll)/,o=this.parents().filter(function(){var e=t(this);return s&&"static"===e.css("position")?!1:n.test(e.css("overflow")+e.css("overflow-y")+e.css("overflow-x"))}).eq(0);return"fixed"!==i&&o.length?o:t(this[0].ownerDocument||document)},t.extend(t.expr[":"],{tabbable:function(e){var i=t.attr(e,"tabindex"),s=null!=i;return(!s||i>=0)&&t.ui.focusable(e,s)}}),t.fn.extend({uniqueId:function(){var t=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++t)})}}(),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&t(this).removeAttr("id")})}}),t.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase());var n=!1;t(document).on("mouseup",function(){n=!1}),t.widget("ui.mouse",{version:"1.12.1",options:{cancel:"input, textarea, button, select, option",distance:1,delay:0},_mouseInit:function(){var e=this;this.element.on("mousedown."+this.widgetName,function(t){return e._mouseDown(t)}).on("click."+this.widgetName,function(i){return!0===t.data(i.target,e.widgetName+".preventClickEvent")?(t.removeData(i.target,e.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):void 0}),this.started=!1},_mouseDestroy:function(){this.element.off("."+this.widgetName),this._mouseMoveDelegate&&this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(e){if(!n){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(e),this._mouseDownEvent=e;var i=this,s=1===e.which,o="string"==typeof this.options.cancel&&e.target.nodeName?t(e.target).closest(this.options.cancel).length:!1;return s&&!o&&this._mouseCapture(e)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){i.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(e)!==!1,!this._mouseStarted)?(e.preventDefault(),!0):(!0===t.data(e.target,this.widgetName+".preventClickEvent")&&t.removeData(e.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(t){return i._mouseMove(t)},this._mouseUpDelegate=function(t){return i._mouseUp(t)},this.document.on("mousemove."+this.widgetName,this._mouseMoveDelegate).on("mouseup."+this.widgetName,this._mouseUpDelegate),e.preventDefault(),n=!0,!0)):!0}},_mouseMove:function(e){if(this._mouseMoved){if(t.ui.ie&&(!document.documentMode||9>document.documentMode)&&!e.button)return this._mouseUp(e);if(!e.which)if(e.originalEvent.altKey||e.originalEvent.ctrlKey||e.originalEvent.metaKey||e.originalEvent.shiftKey)this.ignoreMissingWhich=!0;else if(!this.ignoreMissingWhich)return this._mouseUp(e)}return(e.which||e.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(e),e.preventDefault()):(this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,e)!==!1,this._mouseStarted?this._mouseDrag(e):this._mouseUp(e)),!this._mouseStarted)},_mouseUp:function(e){this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,e.target===this._mouseDownEvent.target&&t.data(e.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(e)),this._mouseDelayTimer&&(clearTimeout(this._mouseDelayTimer),delete this._mouseDelayTimer),this.ignoreMissingWhich=!1,n=!1,e.preventDefault()},_mouseDistanceMet:function(t){return Math.max(Math.abs(this._mouseDownEvent.pageX-t.pageX),Math.abs(this._mouseDownEvent.pageY-t.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),t.ui.plugin={add:function(e,i,s){var n,o=t.ui[e].prototype;for(n in s)o.plugins[n]=o.plugins[n]||[],o.plugins[n].push([i,s[n]])},call:function(t,e,i,s){var n,o=t.plugins[e];if(o&&(s||t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType))for(n=0;o.length>n;n++)t.options[o[n][0]]&&o[n][1].apply(t.element,i)}},t.widget("ui.resizable",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,classes:{"ui-resizable-se":"ui-icon ui-icon-gripsmall-diagonal-se"},containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_num:function(t){return parseFloat(t)||0},_isNumber:function(t){return!isNaN(parseFloat(t))},_hasScroll:function(e,i){if("hidden"===t(e).css("overflow"))return!1;var s=i&&"left"===i?"scrollLeft":"scrollTop",n=!1;return e[s]>0?!0:(e[s]=1,n=e[s]>0,e[s]=0,n)},_create:function(){var e,i=this.options,s=this;this._addClass("ui-resizable"),t.extend(this,{_aspectRatio:!!i.aspectRatio,aspectRatio:i.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:i.helper||i.ghost||i.animate?i.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)&&(this.element.wrap(t("
").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,e={marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom"),marginLeft:this.originalElement.css("marginLeft")},this.element.css(e),this.originalElement.css("margin",0),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css(e),this._proportionallyResize()),this._setupHandles(),i.autoHide&&t(this.element).on("mouseenter",function(){i.disabled||(s._removeClass("ui-resizable-autohide"),s._handles.show())}).on("mouseleave",function(){i.disabled||s.resizing||(s._addClass("ui-resizable-autohide"),s._handles.hide())}),this._mouseInit()},_destroy:function(){this._mouseDestroy();var e,i=function(e){t(e).removeData("resizable").removeData("ui-resizable").off(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(i(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),i(this.originalElement),this},_setOption:function(t,e){switch(this._super(t,e),t){case"handles":this._removeHandles(),this._setupHandles();break;default:}},_setupHandles:function(){var e,i,s,n,o,a=this.options,r=this;if(this.handles=a.handles||(t(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this._handles=t(),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),s=this.handles.split(","),this.handles={},i=0;s.length>i;i++)e=t.trim(s[i]),n="ui-resizable-"+e,o=t("
"),this._addClass(o,"ui-resizable-handle "+n),o.css({zIndex:a.zIndex}),this.handles[e]=".ui-resizable-"+e,this.element.append(o);this._renderAxis=function(e){var i,s,n,o;e=e||this.element;for(i in this.handles)this.handles[i].constructor===String?this.handles[i]=this.element.children(this.handles[i]).first().show():(this.handles[i].jquery||this.handles[i].nodeType)&&(this.handles[i]=t(this.handles[i]),this._on(this.handles[i],{mousedown:r._mouseDown})),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)&&(s=t(this.handles[i],this.element),o=/sw|ne|nw|se|n|s/.test(i)?s.outerHeight():s.outerWidth(),n=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join(""),e.css(n,o),this._proportionallyResize()),this._handles=this._handles.add(this.handles[i])},this._renderAxis(this.element),this._handles=this._handles.add(this.element.find(".ui-resizable-handle")),this._handles.disableSelection(),this._handles.on("mouseover",function(){r.resizing||(this.className&&(o=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),r.axis=o&&o[1]?o[1]:"se")}),a.autoHide&&(this._handles.hide(),this._addClass("ui-resizable-autohide"))},_removeHandles:function(){this._handles.remove()},_mouseCapture:function(e){var i,s,n=!1;for(i in this.handles)s=t(this.handles[i])[0],(s===e.target||t.contains(s,e.target))&&(n=!0);return!this.options.disabled&&n},_mouseStart:function(e){var i,s,n,o=this.options,a=this.element;return this.resizing=!0,this._renderProxy(),i=this._num(this.helper.css("left")),s=this._num(this.helper.css("top")),o.containment&&(i+=t(o.containment).scrollLeft()||0,s+=t(o.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:i,top:s},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:a.width(),height:a.height()},this.originalSize=this._helper?{width:a.outerWidth(),height:a.outerHeight()}:{width:a.width(),height:a.height()},this.sizeDiff={width:a.outerWidth()-a.width(),height:a.outerHeight()-a.height()},this.originalPosition={left:i,top:s},this.originalMousePosition={left:e.pageX,top:e.pageY},this.aspectRatio="number"==typeof o.aspectRatio?o.aspectRatio:this.originalSize.width/this.originalSize.height||1,n=t(".ui-resizable-"+this.axis).css("cursor"),t("body").css("cursor","auto"===n?this.axis+"-resize":n),this._addClass("ui-resizable-resizing"),this._propagate("start",e),!0},_mouseDrag:function(e){var i,s,n=this.originalMousePosition,o=this.axis,a=e.pageX-n.left||0,r=e.pageY-n.top||0,h=this._change[o];return this._updatePrevProperties(),h?(i=h.apply(this,[e,a,r]),this._updateVirtualBoundaries(e.shiftKey),(this._aspectRatio||e.shiftKey)&&(i=this._updateRatio(i,e)),i=this._respectSize(i,e),this._updateCache(i),this._propagate("resize",e),s=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),t.isEmptyObject(s)||(this._updatePrevProperties(),this._trigger("resize",e,this.ui()),this._applyChanges()),!1):!1},_mouseStop:function(e){this.resizing=!1;var i,s,n,o,a,r,h,l=this.options,c=this;return this._helper&&(i=this._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),n=s&&this._hasScroll(i[0],"left")?0:c.sizeDiff.height,o=s?0:c.sizeDiff.width,a={width:c.helper.width()-o,height:c.helper.height()-n},r=parseFloat(c.element.css("left"))+(c.position.left-c.originalPosition.left)||null,h=parseFloat(c.element.css("top"))+(c.position.top-c.originalPosition.top)||null,l.animate||this.element.css(t.extend(a,{top:h,left:r})),c.helper.height(c.size.height),c.helper.width(c.size.width),this._helper&&!l.animate&&this._proportionallyResize()),t("body").css("cursor","auto"),this._removeClass("ui-resizable-resizing"),this._propagate("stop",e),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var t={};return this.position.top!==this.prevPosition.top&&(t.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(t.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(t.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(t.height=this.size.height+"px"),this.helper.css(t),t},_updateVirtualBoundaries:function(t){var e,i,s,n,o,a=this.options;o={minWidth:this._isNumber(a.minWidth)?a.minWidth:0,maxWidth:this._isNumber(a.maxWidth)?a.maxWidth:1/0,minHeight:this._isNumber(a.minHeight)?a.minHeight:0,maxHeight:this._isNumber(a.maxHeight)?a.maxHeight:1/0},(this._aspectRatio||t)&&(e=o.minHeight*this.aspectRatio,s=o.minWidth/this.aspectRatio,i=o.maxHeight*this.aspectRatio,n=o.maxWidth/this.aspectRatio,e>o.minWidth&&(o.minWidth=e),s>o.minHeight&&(o.minHeight=s),o.maxWidth>i&&(o.maxWidth=i),o.maxHeight>n&&(o.maxHeight=n)),this._vBoundaries=o},_updateCache:function(t){this.offset=this.helper.offset(),this._isNumber(t.left)&&(this.position.left=t.left),this._isNumber(t.top)&&(this.position.top=t.top),this._isNumber(t.height)&&(this.size.height=t.height),this._isNumber(t.width)&&(this.size.width=t.width)},_updateRatio:function(t){var e=this.position,i=this.size,s=this.axis;return this._isNumber(t.height)?t.width=t.height*this.aspectRatio:this._isNumber(t.width)&&(t.height=t.width/this.aspectRatio),"sw"===s&&(t.left=e.left+(i.width-t.width),t.top=null),"nw"===s&&(t.top=e.top+(i.height-t.height),t.left=e.left+(i.width-t.width)),t},_respectSize:function(t){var e=this._vBoundaries,i=this.axis,s=this._isNumber(t.width)&&e.maxWidth&&e.maxWidtht.width,a=this._isNumber(t.height)&&e.minHeight&&e.minHeight>t.height,r=this.originalPosition.left+this.originalSize.width,h=this.originalPosition.top+this.originalSize.height,l=/sw|nw|w/.test(i),c=/nw|ne|n/.test(i);return o&&(t.width=e.minWidth),a&&(t.height=e.minHeight),s&&(t.width=e.maxWidth),n&&(t.height=e.maxHeight),o&&l&&(t.left=r-e.minWidth),s&&l&&(t.left=r-e.maxWidth),a&&c&&(t.top=h-e.minHeight),n&&c&&(t.top=h-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_getPaddingPlusBorderDimensions:function(t){for(var e=0,i=[],s=[t.css("borderTopWidth"),t.css("borderRightWidth"),t.css("borderBottomWidth"),t.css("borderLeftWidth")],n=[t.css("paddingTop"),t.css("paddingRight"),t.css("paddingBottom"),t.css("paddingLeft")];4>e;e++)i[e]=parseFloat(s[e])||0,i[e]+=parseFloat(n[e])||0;return{height:i[0]+i[2],width:i[1]+i[3]}},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var t,e=0,i=this.helper||this.element;this._proportionallyResizeElements.length>e;e++)t=this._proportionallyResizeElements[e],this.outerDimensions||(this.outerDimensions=this._getPaddingPlusBorderDimensions(t)),t.css({height:i.height()-this.outerDimensions.height||0,width:i.width()-this.outerDimensions.width||0})},_renderProxy:function(){var e=this.element,i=this.options;this.elementOffset=e.offset(),this._helper?(this.helper=this.helper||t("
"),this._addClass(this.helper,this._helper),this.helper.css({width:this.element.outerWidth(),height:this.element.outerHeight(),position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++i.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element +},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize,s=this.originalPosition;return{left:s.left+e,width:i.width-e}},n:function(t,e,i){var s=this.originalSize,n=this.originalPosition;return{top:n.top+i,height:s.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},sw:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[e,i,s]))},ne:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},nw:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[e,i,s]))}},_propagate:function(e,i){t.ui.plugin.call(this,e,[i,this.ui()]),"resize"!==e&&this._trigger(e,i,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),t.ui.plugin.add("resizable","animate",{stop:function(e){var i=t(this).resizable("instance"),s=i.options,n=i._proportionallyResizeElements,o=n.length&&/textarea/i.test(n[0].nodeName),a=o&&i._hasScroll(n[0],"left")?0:i.sizeDiff.height,r=o?0:i.sizeDiff.width,h={width:i.size.width-r,height:i.size.height-a},l=parseFloat(i.element.css("left"))+(i.position.left-i.originalPosition.left)||null,c=parseFloat(i.element.css("top"))+(i.position.top-i.originalPosition.top)||null;i.element.animate(t.extend(h,c&&l?{top:c,left:l}:{}),{duration:s.animateDuration,easing:s.animateEasing,step:function(){var s={width:parseFloat(i.element.css("width")),height:parseFloat(i.element.css("height")),top:parseFloat(i.element.css("top")),left:parseFloat(i.element.css("left"))};n&&n.length&&t(n[0]).css({width:s.width,height:s.height}),i._updateCache(s),i._propagate("resize",e)}})}}),t.ui.plugin.add("resizable","containment",{start:function(){var e,i,s,n,o,a,r,h=t(this).resizable("instance"),l=h.options,c=h.element,u=l.containment,d=u instanceof t?u.get(0):/parent/.test(u)?c.parent().get(0):u;d&&(h.containerElement=t(d),/document/.test(u)||u===document?(h.containerOffset={left:0,top:0},h.containerPosition={left:0,top:0},h.parentData={element:t(document),left:0,top:0,width:t(document).width(),height:t(document).height()||document.body.parentNode.scrollHeight}):(e=t(d),i=[],t(["Top","Right","Left","Bottom"]).each(function(t,s){i[t]=h._num(e.css("padding"+s))}),h.containerOffset=e.offset(),h.containerPosition=e.position(),h.containerSize={height:e.innerHeight()-i[3],width:e.innerWidth()-i[1]},s=h.containerOffset,n=h.containerSize.height,o=h.containerSize.width,a=h._hasScroll(d,"left")?d.scrollWidth:o,r=h._hasScroll(d)?d.scrollHeight:n,h.parentData={element:d,left:s.left,top:s.top,width:a,height:r}))},resize:function(e){var i,s,n,o,a=t(this).resizable("instance"),r=a.options,h=a.containerOffset,l=a.position,c=a._aspectRatio||e.shiftKey,u={top:0,left:0},d=a.containerElement,p=!0;d[0]!==document&&/static/.test(d.css("position"))&&(u=h),l.left<(a._helper?h.left:0)&&(a.size.width=a.size.width+(a._helper?a.position.left-h.left:a.position.left-u.left),c&&(a.size.height=a.size.width/a.aspectRatio,p=!1),a.position.left=r.helper?h.left:0),l.top<(a._helper?h.top:0)&&(a.size.height=a.size.height+(a._helper?a.position.top-h.top:a.position.top),c&&(a.size.width=a.size.height*a.aspectRatio,p=!1),a.position.top=a._helper?h.top:0),n=a.containerElement.get(0)===a.element.parent().get(0),o=/relative|absolute/.test(a.containerElement.css("position")),n&&o?(a.offset.left=a.parentData.left+a.position.left,a.offset.top=a.parentData.top+a.position.top):(a.offset.left=a.element.offset().left,a.offset.top=a.element.offset().top),i=Math.abs(a.sizeDiff.width+(a._helper?a.offset.left-u.left:a.offset.left-h.left)),s=Math.abs(a.sizeDiff.height+(a._helper?a.offset.top-u.top:a.offset.top-h.top)),i+a.size.width>=a.parentData.width&&(a.size.width=a.parentData.width-i,c&&(a.size.height=a.size.width/a.aspectRatio,p=!1)),s+a.size.height>=a.parentData.height&&(a.size.height=a.parentData.height-s,c&&(a.size.width=a.size.height*a.aspectRatio,p=!1)),p||(a.position.left=a.prevPosition.left,a.position.top=a.prevPosition.top,a.size.width=a.prevSize.width,a.size.height=a.prevSize.height)},stop:function(){var e=t(this).resizable("instance"),i=e.options,s=e.containerOffset,n=e.containerPosition,o=e.containerElement,a=t(e.helper),r=a.offset(),h=a.outerWidth()-e.sizeDiff.width,l=a.outerHeight()-e.sizeDiff.height;e._helper&&!i.animate&&/relative/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l}),e._helper&&!i.animate&&/static/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l})}}),t.ui.plugin.add("resizable","alsoResize",{start:function(){var e=t(this).resizable("instance"),i=e.options;t(i.alsoResize).each(function(){var e=t(this);e.data("ui-resizable-alsoresize",{width:parseFloat(e.width()),height:parseFloat(e.height()),left:parseFloat(e.css("left")),top:parseFloat(e.css("top"))})})},resize:function(e,i){var s=t(this).resizable("instance"),n=s.options,o=s.originalSize,a=s.originalPosition,r={height:s.size.height-o.height||0,width:s.size.width-o.width||0,top:s.position.top-a.top||0,left:s.position.left-a.left||0};t(n.alsoResize).each(function(){var e=t(this),s=t(this).data("ui-resizable-alsoresize"),n={},o=e.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];t.each(o,function(t,e){var i=(s[e]||0)+(r[e]||0);i&&i>=0&&(n[e]=i||null)}),e.css(n)})},stop:function(){t(this).removeData("ui-resizable-alsoresize")}}),t.ui.plugin.add("resizable","ghost",{start:function(){var e=t(this).resizable("instance"),i=e.size;e.ghost=e.originalElement.clone(),e.ghost.css({opacity:.25,display:"block",position:"relative",height:i.height,width:i.width,margin:0,left:0,top:0}),e._addClass(e.ghost,"ui-resizable-ghost"),t.uiBackCompat!==!1&&"string"==typeof e.options.ghost&&e.ghost.addClass(this.options.ghost),e.ghost.appendTo(e.helper)},resize:function(){var e=t(this).resizable("instance");e.ghost&&e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})},stop:function(){var e=t(this).resizable("instance");e.ghost&&e.helper&&e.helper.get(0).removeChild(e.ghost.get(0))}}),t.ui.plugin.add("resizable","grid",{resize:function(){var e,i=t(this).resizable("instance"),s=i.options,n=i.size,o=i.originalSize,a=i.originalPosition,r=i.axis,h="number"==typeof s.grid?[s.grid,s.grid]:s.grid,l=h[0]||1,c=h[1]||1,u=Math.round((n.width-o.width)/l)*l,d=Math.round((n.height-o.height)/c)*c,p=o.width+u,f=o.height+d,m=s.maxWidth&&p>s.maxWidth,g=s.maxHeight&&f>s.maxHeight,_=s.minWidth&&s.minWidth>p,v=s.minHeight&&s.minHeight>f;s.grid=h,_&&(p+=l),v&&(f+=c),m&&(p-=l),g&&(f-=c),/^(se|s|e)$/.test(r)?(i.size.width=p,i.size.height=f):/^(ne)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.top=a.top-d):/^(sw)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.left=a.left-u):((0>=f-c||0>=p-l)&&(e=i._getPaddingPlusBorderDimensions(this)),f-c>0?(i.size.height=f,i.position.top=a.top-d):(f=c-e.height,i.size.height=f,i.position.top=a.top+o.height-f),p-l>0?(i.size.width=p,i.position.left=a.left-u):(p=l-e.width,i.size.width=p,i.position.left=a.left+o.width-p))}}),t.ui.resizable});/** + * Copyright (c) 2007 Ariel Flesler - aflesler ○ gmail • com | https://github.com/flesler + * Licensed under MIT + * @author Ariel Flesler + * @version 2.1.2 + */ +;(function(f){"use strict";"function"===typeof define&&define.amd?define(["jquery"],f):"undefined"!==typeof module&&module.exports?module.exports=f(require("jquery")):f(jQuery)})(function($){"use strict";function n(a){return!a.nodeName||-1!==$.inArray(a.nodeName.toLowerCase(),["iframe","#document","html","body"])}function h(a){return $.isFunction(a)||$.isPlainObject(a)?a:{top:a,left:a}}var p=$.scrollTo=function(a,d,b){return $(window).scrollTo(a,d,b)};p.defaults={axis:"xy",duration:0,limit:!0};$.fn.scrollTo=function(a,d,b){"object"=== typeof d&&(b=d,d=0);"function"===typeof b&&(b={onAfter:b});"max"===a&&(a=9E9);b=$.extend({},p.defaults,b);d=d||b.duration;var u=b.queue&&1=f[g]?0:Math.min(f[g],n));!a&&1-1){targetElements.on(evt+EVENT_NAMESPACE,function elementToggle(event){$.powerTip.toggle(this,event)})}else{targetElements.on(evt+EVENT_NAMESPACE,function elementOpen(event){$.powerTip.show(this,event)})}});$.each(options.closeEvents,function(idx,evt){if($.inArray(evt,options.openEvents)<0){targetElements.on(evt+EVENT_NAMESPACE,function elementClose(event){$.powerTip.hide(this,!isMouseEvent(event))})}});targetElements.on("keydown"+EVENT_NAMESPACE,function elementKeyDown(event){if(event.keyCode===27){$.powerTip.hide(this,true)}})}return targetElements};$.fn.powerTip.defaults={fadeInTime:200,fadeOutTime:100,followMouse:false,popupId:"powerTip",popupClass:null,intentSensitivity:7,intentPollInterval:100,closeDelay:100,placement:"n",smartPlacement:false,offset:10,mouseOnToPopup:false,manual:false,openEvents:["mouseenter","focus"],closeEvents:["mouseleave","blur"]};$.fn.powerTip.smartPlacementLists={n:["n","ne","nw","s"],e:["e","ne","se","w","nw","sw","n","s","e"],s:["s","se","sw","n"],w:["w","nw","sw","e","ne","se","n","s","w"],nw:["nw","w","sw","n","s","se","nw"],ne:["ne","e","se","n","s","sw","ne"],sw:["sw","w","nw","s","n","ne","sw"],se:["se","e","ne","s","n","nw","se"],"nw-alt":["nw-alt","n","ne-alt","sw-alt","s","se-alt","w","e"],"ne-alt":["ne-alt","n","nw-alt","se-alt","s","sw-alt","e","w"],"sw-alt":["sw-alt","s","se-alt","nw-alt","n","ne-alt","w","e"],"se-alt":["se-alt","s","sw-alt","ne-alt","n","nw-alt","e","w"]};$.powerTip={show:function apiShowTip(element,event){if(isMouseEvent(event)){trackMouse(event);session.previousX=event.pageX;session.previousY=event.pageY;$(element).data(DATA_DISPLAYCONTROLLER).show()}else{$(element).first().data(DATA_DISPLAYCONTROLLER).show(true,true)}return element},reposition:function apiResetPosition(element){$(element).first().data(DATA_DISPLAYCONTROLLER).resetPosition();return element},hide:function apiCloseTip(element,immediate){var displayController;immediate=element?immediate:true;if(element){displayController=$(element).first().data(DATA_DISPLAYCONTROLLER)}else if(session.activeHover){displayController=session.activeHover.data(DATA_DISPLAYCONTROLLER)}if(displayController){displayController.hide(immediate)}return element},toggle:function apiToggle(element,event){if(session.activeHover&&session.activeHover.is(element)){$.powerTip.hide(element,!isMouseEvent(event))}else{$.powerTip.show(element,event)}return element}};$.powerTip.showTip=$.powerTip.show;$.powerTip.closeTip=$.powerTip.hide;function CSSCoordinates(){var me=this;me.top="auto";me.left="auto";me.right="auto";me.bottom="auto";me.set=function(property,value){if($.isNumeric(value)){me[property]=Math.round(value)}}}function DisplayController(element,options,tipController){var hoverTimer=null,myCloseDelay=null;function openTooltip(immediate,forceOpen){cancelTimer();if(!element.data(DATA_HASACTIVEHOVER)){if(!immediate){session.tipOpenImminent=true;hoverTimer=setTimeout(function intentDelay(){hoverTimer=null;checkForIntent()},options.intentPollInterval)}else{if(forceOpen){element.data(DATA_FORCEDOPEN,true)}closeAnyDelayed();tipController.showTip(element)}}else{cancelClose()}}function closeTooltip(disableDelay){if(myCloseDelay){myCloseDelay=session.closeDelayTimeout=clearTimeout(myCloseDelay);session.delayInProgress=false}cancelTimer();session.tipOpenImminent=false;if(element.data(DATA_HASACTIVEHOVER)){element.data(DATA_FORCEDOPEN,false);if(!disableDelay){session.delayInProgress=true;session.closeDelayTimeout=setTimeout(function closeDelay(){session.closeDelayTimeout=null;tipController.hideTip(element);session.delayInProgress=false;myCloseDelay=null},options.closeDelay);myCloseDelay=session.closeDelayTimeout}else{tipController.hideTip(element)}}}function checkForIntent(){var xDifference=Math.abs(session.previousX-session.currentX),yDifference=Math.abs(session.previousY-session.currentY),totalDifference=xDifference+yDifference;if(totalDifference",{id:options.popupId});if($body.length===0){$body=$("body")}$body.append(tipElement);session.tooltips=session.tooltips?session.tooltips.add(tipElement):tipElement}if(options.followMouse){if(!tipElement.data(DATA_HASMOUSEMOVE)){$document.on("mousemove"+EVENT_NAMESPACE,positionTipOnCursor);$window.on("scroll"+EVENT_NAMESPACE,positionTipOnCursor);tipElement.data(DATA_HASMOUSEMOVE,true)}}function beginShowTip(element){element.data(DATA_HASACTIVEHOVER,true);tipElement.queue(function queueTipInit(next){showTip(element);next()})}function showTip(element){var tipContent;if(!element.data(DATA_HASACTIVEHOVER)){return}if(session.isTipOpen){if(!session.isClosing){hideTip(session.activeHover)}tipElement.delay(100).queue(function queueTipAgain(next){showTip(element);next()});return}element.trigger("powerTipPreRender");tipContent=getTooltipContent(element);if(tipContent){tipElement.empty().append(tipContent)}else{return}element.trigger("powerTipRender");session.activeHover=element;session.isTipOpen=true;tipElement.data(DATA_MOUSEONTOTIP,options.mouseOnToPopup);tipElement.addClass(options.popupClass);if(!options.followMouse||element.data(DATA_FORCEDOPEN)){positionTipOnElement(element);session.isFixedTipOpen=true}else{positionTipOnCursor()}if(!element.data(DATA_FORCEDOPEN)&&!options.followMouse){$document.on("click"+EVENT_NAMESPACE,function documentClick(event){var target=event.target;if(target!==element[0]){if(options.mouseOnToPopup){if(target!==tipElement[0]&&!$.contains(tipElement[0],target)){$.powerTip.hide()}}else{$.powerTip.hide()}}})}if(options.mouseOnToPopup&&!options.manual){tipElement.on("mouseenter"+EVENT_NAMESPACE,function tipMouseEnter(){if(session.activeHover){session.activeHover.data(DATA_DISPLAYCONTROLLER).cancel()}});tipElement.on("mouseleave"+EVENT_NAMESPACE,function tipMouseLeave(){if(session.activeHover){session.activeHover.data(DATA_DISPLAYCONTROLLER).hide()}})}tipElement.fadeIn(options.fadeInTime,function fadeInCallback(){if(!session.desyncTimeout){session.desyncTimeout=setInterval(closeDesyncedTip,500)}element.trigger("powerTipOpen")})}function hideTip(element){session.isClosing=true;session.isTipOpen=false;session.desyncTimeout=clearInterval(session.desyncTimeout);element.data(DATA_HASACTIVEHOVER,false);element.data(DATA_FORCEDOPEN,false);$document.off("click"+EVENT_NAMESPACE);tipElement.off(EVENT_NAMESPACE);tipElement.fadeOut(options.fadeOutTime,function fadeOutCallback(){var coords=new CSSCoordinates;session.activeHover=null;session.isClosing=false;session.isFixedTipOpen=false;tipElement.removeClass();coords.set("top",session.currentY+options.offset);coords.set("left",session.currentX+options.offset);tipElement.css(coords);element.trigger("powerTipClose")})}function positionTipOnCursor(){var tipWidth,tipHeight,coords,collisions,collisionCount;if(!session.isFixedTipOpen&&(session.isTipOpen||session.tipOpenImminent&&tipElement.data(DATA_HASMOUSEMOVE))){tipWidth=tipElement.outerWidth();tipHeight=tipElement.outerHeight();coords=new CSSCoordinates;coords.set("top",session.currentY+options.offset);coords.set("left",session.currentX+options.offset);collisions=getViewportCollisions(coords,tipWidth,tipHeight);if(collisions!==Collision.none){collisionCount=countFlags(collisions);if(collisionCount===1){if(collisions===Collision.right){coords.set("left",session.scrollLeft+session.windowWidth-tipWidth)}else if(collisions===Collision.bottom){coords.set("top",session.scrollTop+session.windowHeight-tipHeight)}}else{coords.set("left",session.currentX-tipWidth-options.offset);coords.set("top",session.currentY-tipHeight-options.offset)}}tipElement.css(coords)}}function positionTipOnElement(element){var priorityList,finalPlacement;if(options.smartPlacement||options.followMouse&&element.data(DATA_FORCEDOPEN)){priorityList=$.fn.powerTip.smartPlacementLists[options.placement];$.each(priorityList,function(idx,pos){var collisions=getViewportCollisions(placeTooltip(element,pos),tipElement.outerWidth(),tipElement.outerHeight());finalPlacement=pos;return collisions!==Collision.none})}else{placeTooltip(element,options.placement);finalPlacement=options.placement}tipElement.removeClass("w nw sw e ne se n s w se-alt sw-alt ne-alt nw-alt");tipElement.addClass(finalPlacement)}function placeTooltip(element,placement){var iterationCount=0,tipWidth,tipHeight,coords=new CSSCoordinates;coords.set("top",0);coords.set("left",0);tipElement.css(coords);do{tipWidth=tipElement.outerWidth();tipHeight=tipElement.outerHeight();coords=placementCalculator.compute(element,placement,tipWidth,tipHeight,options.offset);tipElement.css(coords)}while(++iterationCount<=5&&(tipWidth!==tipElement.outerWidth()||tipHeight!==tipElement.outerHeight()));return coords}function closeDesyncedTip(){var isDesynced=false,hasDesyncableCloseEvent=$.grep(["mouseleave","mouseout","blur","focusout"],function(eventType){return $.inArray(eventType,options.closeEvents)!==-1}).length>0;if(session.isTipOpen&&!session.isClosing&&!session.delayInProgress&&hasDesyncableCloseEvent){if(session.activeHover.data(DATA_HASACTIVEHOVER)===false||session.activeHover.is(":disabled")){isDesynced=true}else if(!isMouseOver(session.activeHover)&&!session.activeHover.is(":focus")&&!session.activeHover.data(DATA_FORCEDOPEN)){if(tipElement.data(DATA_MOUSEONTOTIP)){if(!isMouseOver(tipElement)){isDesynced=true}}else{isDesynced=true}}if(isDesynced){hideTip(session.activeHover)}}}this.showTip=beginShowTip;this.hideTip=hideTip;this.resetPosition=positionTipOnElement}function isSvgElement(element){return Boolean(window.SVGElement&&element[0]instanceof SVGElement)}function isMouseEvent(event){return Boolean(event&&$.inArray(event.type,MOUSE_EVENTS)>-1&&typeof event.pageX==="number")}function initTracking(){if(!session.mouseTrackingActive){session.mouseTrackingActive=true;getViewportDimensions();$(getViewportDimensions);$document.on("mousemove"+EVENT_NAMESPACE,trackMouse);$window.on("resize"+EVENT_NAMESPACE,trackResize);$window.on("scroll"+EVENT_NAMESPACE,trackScroll)}}function getViewportDimensions(){session.scrollLeft=$window.scrollLeft();session.scrollTop=$window.scrollTop();session.windowWidth=$window.width();session.windowHeight=$window.height()}function trackResize(){session.windowWidth=$window.width();session.windowHeight=$window.height()}function trackScroll(){var x=$window.scrollLeft(),y=$window.scrollTop();if(x!==session.scrollLeft){session.currentX+=x-session.scrollLeft;session.scrollLeft=x}if(y!==session.scrollTop){session.currentY+=y-session.scrollTop;session.scrollTop=y}}function trackMouse(event){session.currentX=event.pageX;session.currentY=event.pageY}function isMouseOver(element){var elementPosition=element.offset(),elementBox=element[0].getBoundingClientRect(),elementWidth=elementBox.right-elementBox.left,elementHeight=elementBox.bottom-elementBox.top;return session.currentX>=elementPosition.left&&session.currentX<=elementPosition.left+elementWidth&&session.currentY>=elementPosition.top&&session.currentY<=elementPosition.top+elementHeight}function getTooltipContent(element){var tipText=element.data(DATA_POWERTIP),tipObject=element.data(DATA_POWERTIPJQ),tipTarget=element.data(DATA_POWERTIPTARGET),targetElement,content;if(tipText){if($.isFunction(tipText)){tipText=tipText.call(element[0])}content=tipText}else if(tipObject){if($.isFunction(tipObject)){tipObject=tipObject.call(element[0])}if(tipObject.length>0){content=tipObject.clone(true,true)}}else if(tipTarget){targetElement=$("#"+tipTarget);if(targetElement.length>0){content=targetElement.html()}}return content}function getViewportCollisions(coords,elementWidth,elementHeight){var viewportTop=session.scrollTop,viewportLeft=session.scrollLeft,viewportBottom=viewportTop+session.windowHeight,viewportRight=viewportLeft+session.windowWidth,collisions=Collision.none;if(coords.topviewportBottom||Math.abs(coords.bottom-session.windowHeight)>viewportBottom){collisions|=Collision.bottom}if(coords.leftviewportRight){collisions|=Collision.left}if(coords.left+elementWidth>viewportRight||coords.right1)){a.preventDefault();var c=a.originalEvent.changedTouches[0],d=document.createEvent("MouseEvents");d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),a.target.dispatchEvent(d)}}if(a.support.touch="ontouchend"in document,a.support.touch){var e,b=a.ui.mouse.prototype,c=b._mouseInit,d=b._mouseDestroy;b._touchStart=function(a){var b=this;!e&&b._mouseCapture(a.originalEvent.changedTouches[0])&&(e=!0,b._touchMoved=!1,f(a,"mouseover"),f(a,"mousemove"),f(a,"mousedown"))},b._touchMove=function(a){e&&(this._touchMoved=!0,f(a,"mousemove"))},b._touchEnd=function(a){e&&(f(a,"mouseup"),f(a,"mouseout"),this._touchMoved||f(a,"click"),e=!1)},b._mouseInit=function(){var b=this;b.element.bind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),c.call(b)},b._mouseDestroy=function(){var b=this;b.element.unbind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),d.call(b)}}}(jQuery);/*! SmartMenus jQuery Plugin - v1.1.0 - September 17, 2017 + * http://www.smartmenus.org/ + * Copyright Vasil Dinkov, Vadikom Web Ltd. http://vadikom.com; Licensed MIT */(function(t){"function"==typeof define&&define.amd?define(["jquery"],t):"object"==typeof module&&"object"==typeof module.exports?module.exports=t(require("jquery")):t(jQuery)})(function($){function initMouseDetection(t){var e=".smartmenus_mouse";if(mouseDetectionEnabled||t)mouseDetectionEnabled&&t&&($(document).off(e),mouseDetectionEnabled=!1);else{var i=!0,s=null,o={mousemove:function(t){var e={x:t.pageX,y:t.pageY,timeStamp:(new Date).getTime()};if(s){var o=Math.abs(s.x-e.x),a=Math.abs(s.y-e.y);if((o>0||a>0)&&2>=o&&2>=a&&300>=e.timeStamp-s.timeStamp&&(mouse=!0,i)){var n=$(t.target).closest("a");n.is("a")&&$.each(menuTrees,function(){return $.contains(this.$root[0],n[0])?(this.itemEnter({currentTarget:n[0]}),!1):void 0}),i=!1}}s=e}};o[touchEvents?"touchstart":"pointerover pointermove pointerout MSPointerOver MSPointerMove MSPointerOut"]=function(t){isTouchEvent(t.originalEvent)&&(mouse=!1)},$(document).on(getEventsNS(o,e)),mouseDetectionEnabled=!0}}function isTouchEvent(t){return!/^(4|mouse)$/.test(t.pointerType)}function getEventsNS(t,e){e||(e="");var i={};for(var s in t)i[s.split(" ").join(e+" ")+e]=t[s];return i}var menuTrees=[],mouse=!1,touchEvents="ontouchstart"in window,mouseDetectionEnabled=!1,requestAnimationFrame=window.requestAnimationFrame||function(t){return setTimeout(t,1e3/60)},cancelAnimationFrame=window.cancelAnimationFrame||function(t){clearTimeout(t)},canAnimate=!!$.fn.animate;return $.SmartMenus=function(t,e){this.$root=$(t),this.opts=e,this.rootId="",this.accessIdPrefix="",this.$subArrow=null,this.activatedItems=[],this.visibleSubMenus=[],this.showTimeout=0,this.hideTimeout=0,this.scrollTimeout=0,this.clickActivated=!1,this.focusActivated=!1,this.zIndexInc=0,this.idInc=0,this.$firstLink=null,this.$firstSub=null,this.disabled=!1,this.$disableOverlay=null,this.$touchScrollingSub=null,this.cssTransforms3d="perspective"in t.style||"webkitPerspective"in t.style,this.wasCollapsible=!1,this.init()},$.extend($.SmartMenus,{hideAll:function(){$.each(menuTrees,function(){this.menuHideAll()})},destroy:function(){for(;menuTrees.length;)menuTrees[0].destroy();initMouseDetection(!0)},prototype:{init:function(t){var e=this;if(!t){menuTrees.push(this),this.rootId=((new Date).getTime()+Math.random()+"").replace(/\D/g,""),this.accessIdPrefix="sm-"+this.rootId+"-",this.$root.hasClass("sm-rtl")&&(this.opts.rightToLeftSubMenus=!0);var i=".smartmenus";this.$root.data("smartmenus",this).attr("data-smartmenus-id",this.rootId).dataSM("level",1).on(getEventsNS({"mouseover focusin":$.proxy(this.rootOver,this),"mouseout focusout":$.proxy(this.rootOut,this),keydown:$.proxy(this.rootKeyDown,this)},i)).on(getEventsNS({mouseenter:$.proxy(this.itemEnter,this),mouseleave:$.proxy(this.itemLeave,this),mousedown:$.proxy(this.itemDown,this),focus:$.proxy(this.itemFocus,this),blur:$.proxy(this.itemBlur,this),click:$.proxy(this.itemClick,this)},i),"a"),i+=this.rootId,this.opts.hideOnClick&&$(document).on(getEventsNS({touchstart:$.proxy(this.docTouchStart,this),touchmove:$.proxy(this.docTouchMove,this),touchend:$.proxy(this.docTouchEnd,this),click:$.proxy(this.docClick,this)},i)),$(window).on(getEventsNS({"resize orientationchange":$.proxy(this.winResize,this)},i)),this.opts.subIndicators&&(this.$subArrow=$("").addClass("sub-arrow"),this.opts.subIndicatorsText&&this.$subArrow.html(this.opts.subIndicatorsText)),initMouseDetection()}if(this.$firstSub=this.$root.find("ul").each(function(){e.menuInit($(this))}).eq(0),this.$firstLink=this.$root.find("a").eq(0),this.opts.markCurrentItem){var s=/(index|default)\.[^#\?\/]*/i,o=/#.*/,a=window.location.href.replace(s,""),n=a.replace(o,"");this.$root.find("a").each(function(){var t=this.href.replace(s,""),i=$(this);(t==a||t==n)&&(i.addClass("current"),e.opts.markCurrentTree&&i.parentsUntil("[data-smartmenus-id]","ul").each(function(){$(this).dataSM("parent-a").addClass("current")}))})}this.wasCollapsible=this.isCollapsible()},destroy:function(t){if(!t){var e=".smartmenus";this.$root.removeData("smartmenus").removeAttr("data-smartmenus-id").removeDataSM("level").off(e),e+=this.rootId,$(document).off(e),$(window).off(e),this.opts.subIndicators&&(this.$subArrow=null)}this.menuHideAll();var i=this;this.$root.find("ul").each(function(){var t=$(this);t.dataSM("scroll-arrows")&&t.dataSM("scroll-arrows").remove(),t.dataSM("shown-before")&&((i.opts.subMenusMinWidth||i.opts.subMenusMaxWidth)&&t.css({width:"",minWidth:"",maxWidth:""}).removeClass("sm-nowrap"),t.dataSM("scroll-arrows")&&t.dataSM("scroll-arrows").remove(),t.css({zIndex:"",top:"",left:"",marginLeft:"",marginTop:"",display:""})),0==(t.attr("id")||"").indexOf(i.accessIdPrefix)&&t.removeAttr("id")}).removeDataSM("in-mega").removeDataSM("shown-before").removeDataSM("scroll-arrows").removeDataSM("parent-a").removeDataSM("level").removeDataSM("beforefirstshowfired").removeAttr("role").removeAttr("aria-hidden").removeAttr("aria-labelledby").removeAttr("aria-expanded"),this.$root.find("a.has-submenu").each(function(){var t=$(this);0==t.attr("id").indexOf(i.accessIdPrefix)&&t.removeAttr("id")}).removeClass("has-submenu").removeDataSM("sub").removeAttr("aria-haspopup").removeAttr("aria-controls").removeAttr("aria-expanded").closest("li").removeDataSM("sub"),this.opts.subIndicators&&this.$root.find("span.sub-arrow").remove(),this.opts.markCurrentItem&&this.$root.find("a.current").removeClass("current"),t||(this.$root=null,this.$firstLink=null,this.$firstSub=null,this.$disableOverlay&&(this.$disableOverlay.remove(),this.$disableOverlay=null),menuTrees.splice($.inArray(this,menuTrees),1))},disable:function(t){if(!this.disabled){if(this.menuHideAll(),!t&&!this.opts.isPopup&&this.$root.is(":visible")){var e=this.$root.offset();this.$disableOverlay=$('
').css({position:"absolute",top:e.top,left:e.left,width:this.$root.outerWidth(),height:this.$root.outerHeight(),zIndex:this.getStartZIndex(!0),opacity:0}).appendTo(document.body)}this.disabled=!0}},docClick:function(t){return this.$touchScrollingSub?(this.$touchScrollingSub=null,void 0):((this.visibleSubMenus.length&&!$.contains(this.$root[0],t.target)||$(t.target).closest("a").length)&&this.menuHideAll(),void 0)},docTouchEnd:function(){if(this.lastTouch){if(!(!this.visibleSubMenus.length||void 0!==this.lastTouch.x2&&this.lastTouch.x1!=this.lastTouch.x2||void 0!==this.lastTouch.y2&&this.lastTouch.y1!=this.lastTouch.y2||this.lastTouch.target&&$.contains(this.$root[0],this.lastTouch.target))){this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0);var t=this;this.hideTimeout=setTimeout(function(){t.menuHideAll()},350)}this.lastTouch=null}},docTouchMove:function(t){if(this.lastTouch){var e=t.originalEvent.touches[0];this.lastTouch.x2=e.pageX,this.lastTouch.y2=e.pageY}},docTouchStart:function(t){var e=t.originalEvent.touches[0];this.lastTouch={x1:e.pageX,y1:e.pageY,target:e.target}},enable:function(){this.disabled&&(this.$disableOverlay&&(this.$disableOverlay.remove(),this.$disableOverlay=null),this.disabled=!1)},getClosestMenu:function(t){for(var e=$(t).closest("ul");e.dataSM("in-mega");)e=e.parent().closest("ul");return e[0]||null},getHeight:function(t){return this.getOffset(t,!0)},getOffset:function(t,e){var i;"none"==t.css("display")&&(i={position:t[0].style.position,visibility:t[0].style.visibility},t.css({position:"absolute",visibility:"hidden"}).show());var s=t[0].getBoundingClientRect&&t[0].getBoundingClientRect(),o=s&&(e?s.height||s.bottom-s.top:s.width||s.right-s.left);return o||0===o||(o=e?t[0].offsetHeight:t[0].offsetWidth),i&&t.hide().css(i),o},getStartZIndex:function(t){var e=parseInt(this[t?"$root":"$firstSub"].css("z-index"));return!t&&isNaN(e)&&(e=parseInt(this.$root.css("z-index"))),isNaN(e)?1:e},getTouchPoint:function(t){return t.touches&&t.touches[0]||t.changedTouches&&t.changedTouches[0]||t},getViewport:function(t){var e=t?"Height":"Width",i=document.documentElement["client"+e],s=window["inner"+e];return s&&(i=Math.min(i,s)),i},getViewportHeight:function(){return this.getViewport(!0)},getViewportWidth:function(){return this.getViewport()},getWidth:function(t){return this.getOffset(t)},handleEvents:function(){return!this.disabled&&this.isCSSOn()},handleItemEvents:function(t){return this.handleEvents()&&!this.isLinkInMegaMenu(t)},isCollapsible:function(){return"static"==this.$firstSub.css("position")},isCSSOn:function(){return"inline"!=this.$firstLink.css("display")},isFixed:function(){var t="fixed"==this.$root.css("position");return t||this.$root.parentsUntil("body").each(function(){return"fixed"==$(this).css("position")?(t=!0,!1):void 0}),t},isLinkInMegaMenu:function(t){return $(this.getClosestMenu(t[0])).hasClass("mega-menu")},isTouchMode:function(){return!mouse||this.opts.noMouseOver||this.isCollapsible()},itemActivate:function(t,e){var i=t.closest("ul"),s=i.dataSM("level");if(s>1&&(!this.activatedItems[s-2]||this.activatedItems[s-2][0]!=i.dataSM("parent-a")[0])){var o=this;$(i.parentsUntil("[data-smartmenus-id]","ul").get().reverse()).add(i).each(function(){o.itemActivate($(this).dataSM("parent-a"))})}if((!this.isCollapsible()||e)&&this.menuHideSubMenus(this.activatedItems[s-1]&&this.activatedItems[s-1][0]==t[0]?s:s-1),this.activatedItems[s-1]=t,this.$root.triggerHandler("activate.smapi",t[0])!==!1){var a=t.dataSM("sub");a&&(this.isTouchMode()||!this.opts.showOnClick||this.clickActivated)&&this.menuShow(a)}},itemBlur:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&this.$root.triggerHandler("blur.smapi",e[0])},itemClick:function(t){var e=$(t.currentTarget);if(this.handleItemEvents(e)){if(this.$touchScrollingSub&&this.$touchScrollingSub[0]==e.closest("ul")[0])return this.$touchScrollingSub=null,t.stopPropagation(),!1;if(this.$root.triggerHandler("click.smapi",e[0])===!1)return!1;var i=$(t.target).is(".sub-arrow"),s=e.dataSM("sub"),o=s?2==s.dataSM("level"):!1,a=this.isCollapsible(),n=/toggle$/.test(this.opts.collapsibleBehavior),r=/link$/.test(this.opts.collapsibleBehavior),h=/^accordion/.test(this.opts.collapsibleBehavior);if(s&&!s.is(":visible")){if((!r||!a||i)&&(this.opts.showOnClick&&o&&(this.clickActivated=!0),this.itemActivate(e,h),s.is(":visible")))return this.focusActivated=!0,!1}else if(a&&(n||i))return this.itemActivate(e,h),this.menuHide(s),n&&(this.focusActivated=!1),!1;return this.opts.showOnClick&&o||e.hasClass("disabled")||this.$root.triggerHandler("select.smapi",e[0])===!1?!1:void 0}},itemDown:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&e.dataSM("mousedown",!0)},itemEnter:function(t){var e=$(t.currentTarget);if(this.handleItemEvents(e)){if(!this.isTouchMode()){this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0);var i=this;this.showTimeout=setTimeout(function(){i.itemActivate(e)},this.opts.showOnClick&&1==e.closest("ul").dataSM("level")?1:this.opts.showTimeout)}this.$root.triggerHandler("mouseenter.smapi",e[0])}},itemFocus:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&(!this.focusActivated||this.isTouchMode()&&e.dataSM("mousedown")||this.activatedItems.length&&this.activatedItems[this.activatedItems.length-1][0]==e[0]||this.itemActivate(e,!0),this.$root.triggerHandler("focus.smapi",e[0]))},itemLeave:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&(this.isTouchMode()||(e[0].blur(),this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0)),e.removeDataSM("mousedown"),this.$root.triggerHandler("mouseleave.smapi",e[0]))},menuHide:function(t){if(this.$root.triggerHandler("beforehide.smapi",t[0])!==!1&&(canAnimate&&t.stop(!0,!0),"none"!=t.css("display"))){var e=function(){t.css("z-index","")};this.isCollapsible()?canAnimate&&this.opts.collapsibleHideFunction?this.opts.collapsibleHideFunction.call(this,t,e):t.hide(this.opts.collapsibleHideDuration,e):canAnimate&&this.opts.hideFunction?this.opts.hideFunction.call(this,t,e):t.hide(this.opts.hideDuration,e),t.dataSM("scroll")&&(this.menuScrollStop(t),t.css({"touch-action":"","-ms-touch-action":"","-webkit-transform":"",transform:""}).off(".smartmenus_scroll").removeDataSM("scroll").dataSM("scroll-arrows").hide()),t.dataSM("parent-a").removeClass("highlighted").attr("aria-expanded","false"),t.attr({"aria-expanded":"false","aria-hidden":"true"});var i=t.dataSM("level");this.activatedItems.splice(i-1,1),this.visibleSubMenus.splice($.inArray(t,this.visibleSubMenus),1),this.$root.triggerHandler("hide.smapi",t[0])}},menuHideAll:function(){this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0);for(var t=this.opts.isPopup?1:0,e=this.visibleSubMenus.length-1;e>=t;e--)this.menuHide(this.visibleSubMenus[e]);this.opts.isPopup&&(canAnimate&&this.$root.stop(!0,!0),this.$root.is(":visible")&&(canAnimate&&this.opts.hideFunction?this.opts.hideFunction.call(this,this.$root):this.$root.hide(this.opts.hideDuration))),this.activatedItems=[],this.visibleSubMenus=[],this.clickActivated=!1,this.focusActivated=!1,this.zIndexInc=0,this.$root.triggerHandler("hideAll.smapi")},menuHideSubMenus:function(t){for(var e=this.activatedItems.length-1;e>=t;e--){var i=this.activatedItems[e].dataSM("sub");i&&this.menuHide(i)}},menuInit:function(t){if(!t.dataSM("in-mega")){t.hasClass("mega-menu")&&t.find("ul").dataSM("in-mega",!0);for(var e=2,i=t[0];(i=i.parentNode.parentNode)!=this.$root[0];)e++;var s=t.prevAll("a").eq(-1);s.length||(s=t.prevAll().find("a").eq(-1)),s.addClass("has-submenu").dataSM("sub",t),t.dataSM("parent-a",s).dataSM("level",e).parent().dataSM("sub",t);var o=s.attr("id")||this.accessIdPrefix+ ++this.idInc,a=t.attr("id")||this.accessIdPrefix+ ++this.idInc;s.attr({id:o,"aria-haspopup":"true","aria-controls":a,"aria-expanded":"false"}),t.attr({id:a,role:"group","aria-hidden":"true","aria-labelledby":o,"aria-expanded":"false"}),this.opts.subIndicators&&s[this.opts.subIndicatorsPos](this.$subArrow.clone())}},menuPosition:function(t){var e,i,s=t.dataSM("parent-a"),o=s.closest("li"),a=o.parent(),n=t.dataSM("level"),r=this.getWidth(t),h=this.getHeight(t),u=s.offset(),l=u.left,c=u.top,d=this.getWidth(s),m=this.getHeight(s),p=$(window),f=p.scrollLeft(),v=p.scrollTop(),b=this.getViewportWidth(),S=this.getViewportHeight(),g=a.parent().is("[data-sm-horizontal-sub]")||2==n&&!a.hasClass("sm-vertical"),M=this.opts.rightToLeftSubMenus&&!o.is("[data-sm-reverse]")||!this.opts.rightToLeftSubMenus&&o.is("[data-sm-reverse]"),w=2==n?this.opts.mainMenuSubOffsetX:this.opts.subMenusSubOffsetX,T=2==n?this.opts.mainMenuSubOffsetY:this.opts.subMenusSubOffsetY;if(g?(e=M?d-r-w:w,i=this.opts.bottomToTopSubMenus?-h-T:m+T):(e=M?w-r:d-w,i=this.opts.bottomToTopSubMenus?m-T-h:T),this.opts.keepInViewport){var y=l+e,I=c+i;if(M&&f>y?e=g?f-y+e:d-w:!M&&y+r>f+b&&(e=g?f+b-r-y+e:w-r),g||(S>h&&I+h>v+S?i+=v+S-h-I:(h>=S||v>I)&&(i+=v-I)),g&&(I+h>v+S+.49||v>I)||!g&&h>S+.49){var x=this;t.dataSM("scroll-arrows")||t.dataSM("scroll-arrows",$([$('')[0],$('')[0]]).on({mouseenter:function(){t.dataSM("scroll").up=$(this).hasClass("scroll-up"),x.menuScroll(t)},mouseleave:function(e){x.menuScrollStop(t),x.menuScrollOut(t,e)},"mousewheel DOMMouseScroll":function(t){t.preventDefault()}}).insertAfter(t));var A=".smartmenus_scroll";if(t.dataSM("scroll",{y:this.cssTransforms3d?0:i-m,step:1,itemH:m,subH:h,arrowDownH:this.getHeight(t.dataSM("scroll-arrows").eq(1))}).on(getEventsNS({mouseover:function(e){x.menuScrollOver(t,e)},mouseout:function(e){x.menuScrollOut(t,e)},"mousewheel DOMMouseScroll":function(e){x.menuScrollMousewheel(t,e)}},A)).dataSM("scroll-arrows").css({top:"auto",left:"0",marginLeft:e+(parseInt(t.css("border-left-width"))||0),width:r-(parseInt(t.css("border-left-width"))||0)-(parseInt(t.css("border-right-width"))||0),zIndex:t.css("z-index")}).eq(g&&this.opts.bottomToTopSubMenus?0:1).show(),this.isFixed()){var C={};C[touchEvents?"touchstart touchmove touchend":"pointerdown pointermove pointerup MSPointerDown MSPointerMove MSPointerUp"]=function(e){x.menuScrollTouch(t,e)},t.css({"touch-action":"none","-ms-touch-action":"none"}).on(getEventsNS(C,A))}}}t.css({top:"auto",left:"0",marginLeft:e,marginTop:i-m})},menuScroll:function(t,e,i){var s,o=t.dataSM("scroll"),a=t.dataSM("scroll-arrows"),n=o.up?o.upEnd:o.downEnd;if(!e&&o.momentum){if(o.momentum*=.92,s=o.momentum,.5>s)return this.menuScrollStop(t),void 0}else s=i||(e||!this.opts.scrollAccelerate?this.opts.scrollStep:Math.floor(o.step));var r=t.dataSM("level");if(this.activatedItems[r-1]&&this.activatedItems[r-1].dataSM("sub")&&this.activatedItems[r-1].dataSM("sub").is(":visible")&&this.menuHideSubMenus(r-1),o.y=o.up&&o.y>=n||!o.up&&n>=o.y?o.y:Math.abs(n-o.y)>s?o.y+(o.up?s:-s):n,t.css(this.cssTransforms3d?{"-webkit-transform":"translate3d(0, "+o.y+"px, 0)",transform:"translate3d(0, "+o.y+"px, 0)"}:{marginTop:o.y}),mouse&&(o.up&&o.y>o.downEnd||!o.up&&o.y0;t.dataSM("scroll-arrows").eq(i?0:1).is(":visible")&&(t.dataSM("scroll").up=i,this.menuScroll(t,!0))}e.preventDefault()},menuScrollOut:function(t,e){mouse&&(/^scroll-(up|down)/.test((e.relatedTarget||"").className)||(t[0]==e.relatedTarget||$.contains(t[0],e.relatedTarget))&&this.getClosestMenu(e.relatedTarget)==t[0]||t.dataSM("scroll-arrows").css("visibility","hidden"))},menuScrollOver:function(t,e){if(mouse&&!/^scroll-(up|down)/.test(e.target.className)&&this.getClosestMenu(e.target)==t[0]){this.menuScrollRefreshData(t);var i=t.dataSM("scroll"),s=$(window).scrollTop()-t.dataSM("parent-a").offset().top-i.itemH;t.dataSM("scroll-arrows").eq(0).css("margin-top",s).end().eq(1).css("margin-top",s+this.getViewportHeight()-i.arrowDownH).end().css("visibility","visible")}},menuScrollRefreshData:function(t){var e=t.dataSM("scroll"),i=$(window).scrollTop()-t.dataSM("parent-a").offset().top-e.itemH;this.cssTransforms3d&&(i=-(parseFloat(t.css("margin-top"))-i)),$.extend(e,{upEnd:i,downEnd:i+this.getViewportHeight()-e.subH})},menuScrollStop:function(t){return this.scrollTimeout?(cancelAnimationFrame(this.scrollTimeout),this.scrollTimeout=0,t.dataSM("scroll").step=1,!0):void 0},menuScrollTouch:function(t,e){if(e=e.originalEvent,isTouchEvent(e)){var i=this.getTouchPoint(e);if(this.getClosestMenu(i.target)==t[0]){var s=t.dataSM("scroll");if(/(start|down)$/i.test(e.type))this.menuScrollStop(t)?(e.preventDefault(),this.$touchScrollingSub=t):this.$touchScrollingSub=null,this.menuScrollRefreshData(t),$.extend(s,{touchStartY:i.pageY,touchStartTime:e.timeStamp});else if(/move$/i.test(e.type)){var o=void 0!==s.touchY?s.touchY:s.touchStartY;if(void 0!==o&&o!=i.pageY){this.$touchScrollingSub=t;var a=i.pageY>o;void 0!==s.up&&s.up!=a&&$.extend(s,{touchStartY:i.pageY,touchStartTime:e.timeStamp}),$.extend(s,{up:a,touchY:i.pageY}),this.menuScroll(t,!0,Math.abs(i.pageY-o))}e.preventDefault()}else void 0!==s.touchY&&((s.momentum=15*Math.pow(Math.abs(i.pageY-s.touchStartY)/(e.timeStamp-s.touchStartTime),2))&&(this.menuScrollStop(t),this.menuScroll(t),e.preventDefault()),delete s.touchY)}}},menuShow:function(t){if((t.dataSM("beforefirstshowfired")||(t.dataSM("beforefirstshowfired",!0),this.$root.triggerHandler("beforefirstshow.smapi",t[0])!==!1))&&this.$root.triggerHandler("beforeshow.smapi",t[0])!==!1&&(t.dataSM("shown-before",!0),canAnimate&&t.stop(!0,!0),!t.is(":visible"))){var e=t.dataSM("parent-a"),i=this.isCollapsible();if((this.opts.keepHighlighted||i)&&e.addClass("highlighted"),i)t.removeClass("sm-nowrap").css({zIndex:"",width:"auto",minWidth:"",maxWidth:"",top:"",left:"",marginLeft:"",marginTop:""});else{if(t.css("z-index",this.zIndexInc=(this.zIndexInc||this.getStartZIndex())+1),(this.opts.subMenusMinWidth||this.opts.subMenusMaxWidth)&&(t.css({width:"auto",minWidth:"",maxWidth:""}).addClass("sm-nowrap"),this.opts.subMenusMinWidth&&t.css("min-width",this.opts.subMenusMinWidth),this.opts.subMenusMaxWidth)){var s=this.getWidth(t);t.css("max-width",this.opts.subMenusMaxWidth),s>this.getWidth(t)&&t.removeClass("sm-nowrap").css("width",this.opts.subMenusMaxWidth)}this.menuPosition(t)}var o=function(){t.css("overflow","")};i?canAnimate&&this.opts.collapsibleShowFunction?this.opts.collapsibleShowFunction.call(this,t,o):t.show(this.opts.collapsibleShowDuration,o):canAnimate&&this.opts.showFunction?this.opts.showFunction.call(this,t,o):t.show(this.opts.showDuration,o),e.attr("aria-expanded","true"),t.attr({"aria-expanded":"true","aria-hidden":"false"}),this.visibleSubMenus.push(t),this.$root.triggerHandler("show.smapi",t[0])}},popupHide:function(t){this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0);var e=this;this.hideTimeout=setTimeout(function(){e.menuHideAll()},t?1:this.opts.hideTimeout)},popupShow:function(t,e){if(!this.opts.isPopup)return alert('SmartMenus jQuery Error:\n\nIf you want to show this menu via the "popupShow" method, set the isPopup:true option.'),void 0;if(this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0),this.$root.dataSM("shown-before",!0),canAnimate&&this.$root.stop(!0,!0),!this.$root.is(":visible")){this.$root.css({left:t,top:e});var i=this,s=function(){i.$root.css("overflow","")};canAnimate&&this.opts.showFunction?this.opts.showFunction.call(this,this.$root,s):this.$root.show(this.opts.showDuration,s),this.visibleSubMenus[0]=this.$root}},refresh:function(){this.destroy(!0),this.init(!0)},rootKeyDown:function(t){if(this.handleEvents())switch(t.keyCode){case 27:var e=this.activatedItems[0];if(e){this.menuHideAll(),e[0].focus();var i=e.dataSM("sub");i&&this.menuHide(i)}break;case 32:var s=$(t.target);if(s.is("a")&&this.handleItemEvents(s)){var i=s.dataSM("sub");i&&!i.is(":visible")&&(this.itemClick({currentTarget:t.target}),t.preventDefault())}}},rootOut:function(t){if(this.handleEvents()&&!this.isTouchMode()&&t.target!=this.$root[0]&&(this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0),!this.opts.showOnClick||!this.opts.hideOnClick)){var e=this;this.hideTimeout=setTimeout(function(){e.menuHideAll()},this.opts.hideTimeout)}},rootOver:function(t){this.handleEvents()&&!this.isTouchMode()&&t.target!=this.$root[0]&&this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0)},winResize:function(t){if(this.handleEvents()){if(!("onorientationchange"in window)||"orientationchange"==t.type){var e=this.isCollapsible();this.wasCollapsible&&e||(this.activatedItems.length&&this.activatedItems[this.activatedItems.length-1][0].blur(),this.menuHideAll()),this.wasCollapsible=e}}else if(this.$disableOverlay){var i=this.$root.offset();this.$disableOverlay.css({top:i.top,left:i.left,width:this.$root.outerWidth(),height:this.$root.outerHeight()})}}}}),$.fn.dataSM=function(t,e){return e?this.data(t+"_smartmenus",e):this.data(t+"_smartmenus")},$.fn.removeDataSM=function(t){return this.removeData(t+"_smartmenus")},$.fn.smartmenus=function(options){if("string"==typeof options){var args=arguments,method=options;return Array.prototype.shift.call(args),this.each(function(){var t=$(this).data("smartmenus");t&&t[method]&&t[method].apply(t,args)})}return this.each(function(){var dataOpts=$(this).data("sm-options")||null;if(dataOpts)try{dataOpts=eval("("+dataOpts+")")}catch(e){dataOpts=null,alert('ERROR\n\nSmartMenus jQuery init:\nInvalid "data-sm-options" attribute value syntax.')}new $.SmartMenus(this,$.extend({},$.fn.smartmenus.defaults,options,dataOpts))})},$.fn.smartmenus.defaults={isPopup:!1,mainMenuSubOffsetX:0,mainMenuSubOffsetY:0,subMenusSubOffsetX:0,subMenusSubOffsetY:0,subMenusMinWidth:"10em",subMenusMaxWidth:"20em",subIndicators:!0,subIndicatorsPos:"append",subIndicatorsText:"",scrollStep:30,scrollAccelerate:!0,showTimeout:250,hideTimeout:500,showDuration:0,showFunction:null,hideDuration:0,hideFunction:function(t,e){t.fadeOut(200,e)},collapsibleShowDuration:0,collapsibleShowFunction:function(t,e){t.slideDown(200,e)},collapsibleHideDuration:0,collapsibleHideFunction:function(t,e){t.slideUp(200,e)},showOnClick:!1,hideOnClick:!0,noMouseOver:!1,keepInViewport:!0,keepHighlighted:!0,markCurrentItem:!1,markCurrentTree:!0,rightToLeftSubMenus:!1,bottomToTopSubMenus:!1,collapsibleBehavior:"default"},$}); \ No newline at end of file diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/md_src_locale_README.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/md_src_locale_README.html new file mode 100644 index 000000000..2289f61b3 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/md_src_locale_README.html @@ -0,0 +1,135 @@ + + + + + + + +IRremoteESP8266: Internationalisation (I18N) & Locale Files + + + + + + + + + +
+
+ + + + + + +
+
IRremoteESP8266 +
+
+
+ + + + + + + + +
+
+ + +
+ +
+ +
+
+
+
Internationalisation (I18N) & Locale Files
+
+
+

This directory contains the files used by the library to store the text it uses. If you want to add support for a language, this is the correct place. If you are adding text strings to a routine, you should use the ones here.

+

+Changing the language/locale used by the library.

+

There are several ways to change which locale file is used by the library. Use which ever one suits your needs best. To keep the space used by the library to a minimum, all methods require the change to happen at compile time. There is no runtime option to change locales.

+

+Change <tt>_IR_LOCALE_</tt> in the <tt>src/IRremoteESP8266.h</tt> file.

+

In the IRremoteESP8266.h file, find and locate the lines that look like:

{c++}
+
#ifndef _IR_LOCALE_
+
#define _IR_LOCALE_ en-AU
+
#endif // _IR_LOCALE_
+

Change en-AU to the language & country that best suits your needs. e.g. de-DE for Germany/German.

+

+Use a compile-time build flag.

+

Use the compiler flag: -D_IR_LOCALE_=en-AU when compiling the library. Especially when compiling the IRtext.cpp file. Change en-AU to a value which matches one of the file names in this directory. e.g. de-DE for Germany/German, which will use the de_DE.h file.

+

+Use the appropriate pre-prepared build environment. _(PlatformIO only)_

+

If you examine the platformio.ini file located in the same directory as the example code you may find pre-setup compile environments for the different supported locales. Choose the appropriate one for you language by asking PlatformIO to build or upload using that environment. e.g. See IRrecvDumpV2's platformio.ini

+

+Use a custom <tt>build_flags</tt>. _(PlatformIO only)_

+

Edit the platformio.ini file in the directory containing your example/source code. Either in the default PlatformIO environment ([env]), or in which ever PlatformIO environment you using, change or add the following line:

build_flags = -D_IR_LOCALE_=en-AU ; Or use which ever locale variable you want.
+

Every time you change that line, you should do a pio clean or choose the clean option from the build menu, to ensure a fresh copy of IRtext.o is created.

+

+Adding support for a new locale/language.

+

Only ASCII/UTF-8 8-bit characters are supported. Unicode is not supported. Unicode may work. It may not. It's just not supported. i.e. If Arduino's Serial.print() can handle it, it will probably work.

+

+Copy/create a new locale file in this directory.

+

Copy en-AU.h or which every is a closer fit for your language to xx-YY.h where xx is the ISO code for the language. e.g. en is English. de is German etc. and YY is the ISO country code. e.g. AU is Australia. Modify the comments and all LOCALE_EN_AU_H_s in the file to LOCALE_XX_YY_H_ for your locale.

+

+Override any <tt>#‍define</tt> values that reside in <tt>defaults.h</tt>

+

Go through the defaults.h file, and find any #‍define lines that define a macro starting with D_ that has text that needs to change for your locale. Copy or create a corresponding #‍define D_STR_HELLOWORLD "Hello World" in your xx-YY.h file, and translate the text appropriately e.g. #‍define D_STR_HELLOWORLD "Bonjour le monde" (French)

+

Any values you #‍define in xx-YY.h will override the corresponding value in the defaults.h file.

+

+Supporting a dialect/regional variant of another <em>existing</em> language/locale.

+

Similar to the previous step, if you only need to modify a small subset of the strings used in another locale file, then include the other locale file and then make sure to #‍undef any strings that need to be (re-)changed. See the Swiss-German for an example of how to do this. i.e. It #‍include "locale/de-DE.h"s the German locale, and redefines any strings that are not standard German.

+

+Adding new text strings to the library.

+

If you need to add an entirely new string to the library to support some feature etc. e.g. _"Widget"_. You should first understand how the library tries to do this such that it is easy to support different languages for it.

+
    +
  1. Use a constant named kWidgetStr in the appropriate statement in the .cpp file.
  2. +
  3. Edit IRtext.cpp, and add the appropriate line for your new constant. e.g.
    {c++}
    +
    String kWidgetStr = D_STR_WIDGET;
    +
  4. +
+

The kWidgetStr variable will house the sole copy of the string for the entire library. This limits any duplication. The D_STR_WIDGET macro will be what is targeted by the different language / locales files.

+
    +
  1. Edit locale/defaults.h, and add the appropriate stanza for your new string. e.g.
    {c++}
    +
    #ifndef D_STR_WIDGET
    +
    #define D_STR_WIDGET "Turbo"
    +
    #endif // D_STR_WIDGET
    +
  2. +
  3. _(Manual)_ Update IRtext.h, and add the appropriate line for your new constant. e.g.
    {c++}
    +
    extern const String kWidgetStr;
    +
  4. +
+

For any file that #‍include <IRtext.h>s this file, it will tell it that the string is stored elsewhere, and to look for it elsewhere at the object linking stage of the build. This is what makes the string be referenced from a central location.

+
    +
  1. _(Automatic)_ Run tools/generate_irtext_h.sh to update IRtext.h. In the src/locale directory. Run the ../../tools/generate_irtext_h.sh command. It will update the file for you automatically.
  2. +
+
+
+ + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/menu.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/menu.js new file mode 100644 index 000000000..433c15b8f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/menu.js @@ -0,0 +1,50 @@ +/* + @licstart The following is the entire license notice for the + JavaScript code in this file. + + Copyright (C) 1997-2017 by Dimitri van Heesch + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + @licend The above is the entire license notice + for the JavaScript code in this file + */ +function initMenu(relPath,searchEnabled,serverSide,searchPage,search) { + function makeTree(data,relPath) { + var result=''; + if ('children' in data) { + result+=''; + } + return result; + } + + $('#main-nav').append(makeTree(menudata,relPath)); + $('#main-nav').children(':first').addClass('sm sm-dox').attr('id','main-menu'); + if (searchEnabled) { + if (serverSide) { + $('#main-menu').append('
  • '); + } else { + $('#main-menu').append('
  • '); + } + } + $('#main-menu').smartmenus(); +} +/* @license-end */ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/menudata.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/menudata.js new file mode 100644 index 000000000..f6289d4dd --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/menudata.js @@ -0,0 +1,189 @@ +/* +@licstart The following is the entire license notice for the +JavaScript code in this file. + +Copyright (C) 1997-2019 by Dimitri van Heesch + +This program is free software; you can redistribute it and/or modify +it under the terms of version 2 of the GNU General Public License as published by +the Free Software Foundation + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +@licend The above is the entire license notice +for the JavaScript code in this file +*/ +var menudata={children:[ +{text:"Main Page",url:"index.html"}, +{text:"Related Pages",url:"pages.html"}, +{text:"Namespaces",url:"namespaces.html",children:[ +{text:"Namespace List",url:"namespaces.html"}, +{text:"Namespace Members",url:"namespacemembers.html",children:[ +{text:"All",url:"namespacemembers.html",children:[ +{text:"a",url:"namespacemembers.html#index_a"}, +{text:"b",url:"namespacemembers.html#index_b"}, +{text:"d",url:"namespacemembers.html#index_d"}, +{text:"f",url:"namespacemembers.html#index_f"}, +{text:"g",url:"namespacemembers.html#index_g"}, +{text:"h",url:"namespacemembers.html#index_h"}, +{text:"m",url:"namespacemembers.html#index_m"}, +{text:"o",url:"namespacemembers.html#index_o"}, +{text:"r",url:"namespacemembers.html#index_r"}, +{text:"s",url:"namespacemembers.html#index_s"}, +{text:"u",url:"namespacemembers.html#index_u"}]}, +{text:"Functions",url:"namespacemembers_func.html"}, +{text:"Enumerations",url:"namespacemembers_enum.html"}]}]}, +{text:"Classes",url:"annotated.html",children:[ +{text:"Class List",url:"annotated.html"}, +{text:"Class Index",url:"classes.html"}, +{text:"Class Hierarchy",url:"inherits.html"}, +{text:"Class Members",url:"functions.html",children:[ +{text:"All",url:"functions.html",children:[ +{text:"_",url:"functions.html#index__5F"}, +{text:"a",url:"functions_a.html#index_a"}, +{text:"b",url:"functions_b.html#index_b"}, +{text:"c",url:"functions_c.html#index_c"}, +{text:"d",url:"functions_d.html#index_d"}, +{text:"e",url:"functions_e.html#index_e"}, +{text:"f",url:"functions_f.html#index_f"}, +{text:"g",url:"functions_g.html#index_g"}, +{text:"h",url:"functions_h.html#index_h"}, +{text:"i",url:"functions_i.html#index_i"}, +{text:"k",url:"functions_k.html#index_k"}, +{text:"l",url:"functions_l.html#index_l"}, +{text:"m",url:"functions_m.html#index_m"}, +{text:"n",url:"functions_n.html#index_n"}, +{text:"o",url:"functions_o.html#index_o"}, +{text:"p",url:"functions_p.html#index_p"}, +{text:"q",url:"functions_q.html#index_q"}, +{text:"r",url:"functions_r.html#index_r"}, +{text:"s",url:"functions_s.html#index_s"}, +{text:"t",url:"functions_t.html#index_t"}, +{text:"u",url:"functions_u.html#index_u"}, +{text:"v",url:"functions_v.html#index_v"}, +{text:"w",url:"functions_w.html#index_w"}, +{text:"z",url:"functions_z.html#index_z"}, +{text:"~",url:"functions_~.html#index__7E"}]}, +{text:"Functions",url:"functions_func.html",children:[ +{text:"_",url:"functions_func.html#index__5F"}, +{text:"a",url:"functions_func_a.html#index_a"}, +{text:"b",url:"functions_func_b.html#index_b"}, +{text:"c",url:"functions_func_c.html#index_c"}, +{text:"d",url:"functions_func_d.html#index_d"}, +{text:"e",url:"functions_func_e.html#index_e"}, +{text:"f",url:"functions_func_f.html#index_f"}, +{text:"g",url:"functions_func_g.html#index_g"}, +{text:"h",url:"functions_func_h.html#index_h"}, +{text:"i",url:"functions_func_i.html#index_i"}, +{text:"k",url:"functions_func_k.html#index_k"}, +{text:"l",url:"functions_func_l.html#index_l"}, +{text:"m",url:"functions_func_m.html#index_m"}, +{text:"n",url:"functions_func_n.html#index_n"}, +{text:"o",url:"functions_func_o.html#index_o"}, +{text:"p",url:"functions_func_p.html#index_p"}, +{text:"r",url:"functions_func_r.html#index_r"}, +{text:"s",url:"functions_func_s.html#index_s"}, +{text:"t",url:"functions_func_t.html#index_t"}, +{text:"u",url:"functions_func_u.html#index_u"}, +{text:"v",url:"functions_func_v.html#index_v"}, +{text:"w",url:"functions_func_w.html#index_w"}, +{text:"~",url:"functions_func_~.html#index__7E"}]}, +{text:"Variables",url:"functions_vars.html",children:[ +{text:"_",url:"functions_vars.html#index__5F"}, +{text:"a",url:"functions_vars.html#index_a"}, +{text:"b",url:"functions_vars.html#index_b"}, +{text:"c",url:"functions_vars.html#index_c"}, +{text:"d",url:"functions_vars.html#index_d"}, +{text:"e",url:"functions_vars.html#index_e"}, +{text:"f",url:"functions_vars.html#index_f"}, +{text:"h",url:"functions_vars.html#index_h"}, +{text:"i",url:"functions_vars.html#index_i"}, +{text:"l",url:"functions_vars.html#index_l"}, +{text:"m",url:"functions_vars.html#index_m"}, +{text:"n",url:"functions_vars.html#index_n"}, +{text:"o",url:"functions_vars.html#index_o"}, +{text:"p",url:"functions_vars.html#index_p"}, +{text:"q",url:"functions_vars.html#index_q"}, +{text:"r",url:"functions_vars.html#index_r"}, +{text:"s",url:"functions_vars.html#index_s"}, +{text:"t",url:"functions_vars.html#index_t"}, +{text:"u",url:"functions_vars.html#index_u"}, +{text:"v",url:"functions_vars.html#index_v"}, +{text:"w",url:"functions_vars.html#index_w"}, +{text:"z",url:"functions_vars.html#index_z"}]}, +{text:"Related Functions",url:"functions_rela.html"}]}]}, +{text:"Files",url:"files.html",children:[ +{text:"File List",url:"files.html"}, +{text:"File Members",url:"globals.html",children:[ +{text:"All",url:"globals.html",children:[ +{text:"_",url:"globals.html#index__5F"}, +{text:"a",url:"globals_a.html#index_a"}, +{text:"c",url:"globals_c.html#index_c"}, +{text:"d",url:"globals_d.html#index_d"}, +{text:"e",url:"globals_e.html#index_e"}, +{text:"f",url:"globals_f.html#index_f"}, +{text:"g",url:"globals_g.html#index_g"}, +{text:"h",url:"globals_h.html#index_h"}, +{text:"i",url:"globals_i.html#index_i"}, +{text:"j",url:"globals_j.html#index_j"}, +{text:"k",url:"globals_k.html#index_k"}, +{text:"l",url:"globals_l.html#index_l"}, +{text:"m",url:"globals_m.html#index_m"}, +{text:"n",url:"globals_n.html#index_n"}, +{text:"p",url:"globals_p.html#index_p"}, +{text:"r",url:"globals_r.html#index_r"}, +{text:"s",url:"globals_s.html#index_s"}, +{text:"t",url:"globals_t.html#index_t"}, +{text:"u",url:"globals_u.html#index_u"}, +{text:"v",url:"globals_v.html#index_v"}, +{text:"w",url:"globals_w.html#index_w"}, +{text:"x",url:"globals_x.html#index_x"}, +{text:"y",url:"globals_y.html#index_y"}, +{text:"z",url:"globals_z.html#index_z"}]}, +{text:"Functions",url:"globals_func.html",children:[ +{text:"c",url:"globals_func.html#index_c"}, +{text:"f",url:"globals_func.html#index_f"}, +{text:"g",url:"globals_func.html#index_g"}, +{text:"h",url:"globals_func.html#index_h"}, +{text:"i",url:"globals_func.html#index_i"}, +{text:"r",url:"globals_func.html#index_r"}, +{text:"s",url:"globals_func.html#index_s"}, +{text:"t",url:"globals_func.html#index_t"}, +{text:"u",url:"globals_func.html#index_u"}, +{text:"x",url:"globals_func.html#index_x"}]}, +{text:"Variables",url:"globals_vars.html",children:[ +{text:"_",url:"globals_vars.html#index__5F"}, +{text:"i",url:"globals_vars_i.html#index_i"}, +{text:"k",url:"globals_vars_k.html#index_k"}]}, +{text:"Typedefs",url:"globals_type.html"}, +{text:"Enumerations",url:"globals_enum.html"}, +{text:"Enumerator",url:"globals_eval.html",children:[ +{text:"a",url:"globals_eval.html#index_a"}, +{text:"c",url:"globals_eval.html#index_c"}, +{text:"d",url:"globals_eval.html#index_d"}, +{text:"e",url:"globals_eval.html#index_e"}, +{text:"f",url:"globals_eval.html#index_f"}, +{text:"g",url:"globals_eval.html#index_g"}, +{text:"h",url:"globals_eval.html#index_h"}, +{text:"i",url:"globals_eval.html#index_i"}, +{text:"j",url:"globals_eval.html#index_j"}, +{text:"k",url:"globals_eval.html#index_k"}, +{text:"l",url:"globals_eval.html#index_l"}, +{text:"m",url:"globals_eval.html#index_m"}, +{text:"n",url:"globals_eval.html#index_n"}, +{text:"p",url:"globals_eval.html#index_p"}, +{text:"r",url:"globals_eval.html#index_r"}, +{text:"s",url:"globals_eval.html#index_s"}, +{text:"t",url:"globals_eval.html#index_t"}, +{text:"u",url:"globals_eval.html#index_u"}, +{text:"v",url:"globals_eval.html#index_v"}, +{text:"w",url:"globals_eval.html#index_w"}, +{text:"y",url:"globals_eval.html#index_y"}, +{text:"z",url:"globals_eval.html#index_z"}]}]}]}]} diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespaceIRAcUtils.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespaceIRAcUtils.html new file mode 100644 index 000000000..3813acb54 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespaceIRAcUtils.html @@ -0,0 +1,161 @@ + + + + + + + +IRremoteESP8266: IRAcUtils Namespace Reference + + + + + + + + + +
    +
    + + + + + + +
    +
    IRremoteESP8266 +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + +
    +
    + +
    +
    IRAcUtils Namespace Reference
    +
    +
    + + + + + + + + +

    +Functions

    String resultAcToString (const decode_results *const result)
     Display the human readable state of an A/C message if we can. More...
     
    bool decodeToState (const decode_results *decode, stdAc::state_t *result, const stdAc::state_t *prev)
     Convert a valid IR A/C remote message that we understand enough into a Common A/C state. More...
     
    +

    Function Documentation

    + +

    ◆ decodeToState()

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    bool IRAcUtils::decodeToState (const decode_resultsdecode,
    stdAc::state_tresult,
    const stdAc::state_tprev 
    )
    +
    + +

    Convert a valid IR A/C remote message that we understand enough into a Common A/C state.

    +
    Parameters
    + + + + +
    [in]decodeA PTR to a successful raw IR decode object.
    [in]resultA PTR to a state structure to store the result in.
    [in]prevA PTR to a state structure which has the prev. state.
    +
    +
    +
    Returns
    A boolean indicating success or failure.
    + +
    +
    + +

    ◆ resultAcToString()

    + +
    +
    + + + + + + + + +
    String IRAcUtils::resultAcToString (const decode_results *const result)
    +
    + +

    Display the human readable state of an A/C message if we can.

    +
    Parameters
    + + +
    [in]resultA Ptr to the captured decode_results that contains an A/C mesg.
    +
    +
    +
    Returns
    A string with the human description of the A/C message. An empty string if we can't.
    + +
    +
    +
    + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespaceirutils.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespaceirutils.html new file mode 100644 index 000000000..296bae1d2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespaceirutils.html @@ -0,0 +1,1303 @@ + + + + + + + +IRremoteESP8266: irutils Namespace Reference + + + + + + + + + +
    +
    + + + + + + +
    +
    IRremoteESP8266 +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + +
    +
    + +
    +
    irutils Namespace Reference
    +
    +
    + +

    Namespace for covering common functions & procedures for advancd protocol handlers. +More...

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +Functions

    String addLabeledString (const String value, const String label, const bool precomma)
     Create a String with a colon separated "label: value" pair suitable for Humans. More...
     
    String addBoolToString (const bool value, const String label, const bool precomma)
     Create a String with a colon separated flag suitable for Humans. e.g. "Power: On". More...
     
    String addIntToString (const uint16_t value, const String label, const bool precomma)
     Create a String with a colon separated labeled Integer suitable for Humans. e.g. "Foo: 23". More...
     
    String modelToStr (const decode_type_t protocol, const int16_t model)
     Generate the model string for a given Protocol/Model pair. More...
     
    String addModelToString (const decode_type_t protocol, const int16_t model, const bool precomma)
     Create a String of human output for a given protocol model number. e.g. "Model: JKE". More...
     
    String addTempToString (const uint16_t degrees, const bool celsius, const bool precomma)
     Create a String of human output for a given temperature. e.g. "Temp: 25C". More...
     
    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)
     Create a String of human output for the given operating mode. e.g. "Mode: 1 (Cool)". More...
     
    String addDayToString (const uint8_t day_of_week, const int8_t offset, const bool precomma)
     Create a String of the 3-letter day of the week from a numerical day of the week. e.g. "Day: 1 (Mon)". More...
     
    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)
     Create a String of human output for the given fan speed. e.g. "Fan: 0 (Auto)". More...
     
    String htmlEscape (const String unescaped)
     Escape any special HTML (unsafe) characters in a string. e.g. anti-XSS. More...
     
    String msToString (uint32_t const msecs)
     Convert a nr. of milliSeconds into a Human-readable string. e.g. "1 Day 6 Hours 34 Minutes 17 Seconds". More...
     
    String minsToString (const uint16_t mins)
     Convert a nr. of minutes into a 24h clock format Human-readable string. e.g. "23:59". More...
     
    uint8_t sumNibbles (const uint8_t *const start, const uint16_t length, const uint8_t init)
     Sum all the nibbles together in a series of bytes. More...
     
    uint8_t sumNibbles (const uint64_t data, const uint8_t count, const uint8_t init, const bool nibbleonly)
     Sum all the nibbles together in an integer. More...
     
    uint8_t bcdToUint8 (const uint8_t bcd)
     Convert a byte of Binary Coded Decimal(BCD) into an Integer. More...
     
    uint8_t uint8ToBcd (const uint8_t integer)
     Convert an Integer into a byte of Binary Coded Decimal(BCD). More...
     
    bool getBit (const uint64_t data, const uint8_t position, const uint8_t size)
     Return the value of positionth bit of an Integer. More...
     
    bool getBit (const uint8_t data, const uint8_t position)
     Return the value of positionth bit of an Integer. More...
     
    uint64_t setBit (const uint64_t data, const uint8_t position, const bool on, const uint8_t size)
     Return the value of an Integer with the positionth bit changed. More...
     
    uint8_t setBit (const uint8_t data, const uint8_t position, const bool on)
     Return the value of an Integer with the positionth bit changed. More...
     
    void setBit (uint8_t *const data, const uint8_t position, const bool on)
     Alter the value of an Integer with the positionth bit changed. More...
     
    void setBit (uint32_t *const data, const uint8_t position, const bool on)
     Alter the value of an Integer with the positionth bit changed. More...
     
    void setBit (uint64_t *const data, const uint8_t position, const bool on)
     Alter the value of an Integer with the positionth bit changed. More...
     
    void setBits (uint8_t *const dst, const uint8_t offset, const uint8_t nbits, const uint8_t data)
     Alter an uint8_t value by overwriting an arbitary given number of bits. More...
     
    void setBits (uint32_t *const dst, const uint8_t offset, const uint8_t nbits, const uint32_t data)
     Alter an uint32_t value by overwriting an arbitary given number of bits. More...
     
    void setBits (uint64_t *const dst, const uint8_t offset, const uint8_t nbits, const uint64_t data)
     Alter an uint64_t value by overwriting an arbitary given number of bits. More...
     
    +

    Detailed Description

    +

    Namespace for covering common functions & procedures for advancd protocol handlers.

    +

    Function Documentation

    + +

    ◆ addBoolToString()

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    String irutils::addBoolToString (const bool value,
    const String label,
    const bool precomma 
    )
    +
    + +

    Create a String with a colon separated flag suitable for Humans. e.g. "Power: On".

    +
    Parameters
    + + + + +
    [in]valueThe value to come after the label.
    [in]labelThe label to precede the value.
    [in]precommaShould the output string start with ", " or not?
    +
    +
    +
    Returns
    The resulting String.
    + +
    +
    + +

    ◆ addDayToString()

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    String irutils::addDayToString (const uint8_t day_of_week,
    const int8_t offset,
    const bool precomma 
    )
    +
    + +

    Create a String of the 3-letter day of the week from a numerical day of the week. e.g. "Day: 1 (Mon)".

    +
    Parameters
    + + + + +
    [in]day_of_weekA numerical version of the sequential day of the week. e.g. Saturday = 7 etc.
    [in]offsetDays to offset by. e.g. For different day starting the week.
    [in]precommaShould the output string start with ", " or not?
    +
    +
    +
    Returns
    The resulting String.
    + +
    +
    + +

    ◆ addFanToString()

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    String irutils::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 
    )
    +
    + +

    Create a String of human output for the given fan speed. e.g. "Fan: 0 (Auto)".

    +
    Parameters
    + + + + + + + +
    [in]speedThe numeric speed of the fan to display.
    [in]highThe numeric value for High speed.
    [in]lowThe numeric value for Low speed.
    [in]automaticThe numeric value for Auto speed.
    [in]quietThe numeric value for Quiet speed.
    [in]mediumThe numeric value for Medium speed.
    +
    +
    +
    Returns
    The resulting String.
    + +
    +
    + +

    ◆ addIntToString()

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    String irutils::addIntToString (const uint16_t value,
    const String label,
    const bool precomma 
    )
    +
    + +

    Create a String with a colon separated labeled Integer suitable for Humans. e.g. "Foo: 23".

    +
    Parameters
    + + + + +
    [in]valueThe value to come after the label.
    [in]labelThe label to precede the value.
    [in]precommaShould the output string start with ", " or not?
    +
    +
    +
    Returns
    The resulting String.
    + +
    +
    + +

    ◆ addLabeledString()

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    String irutils::addLabeledString (const String value,
    const String label,
    const bool precomma 
    )
    +
    + +

    Create a String with a colon separated "label: value" pair suitable for Humans.

    +
    Parameters
    + + + + +
    [in]valueThe value to come after the label.
    [in]labelThe label to precede the value.
    [in]precommaShould the output string start with ", " or not?
    +
    +
    +
    Returns
    The resulting String.
    + +
    +
    + +

    ◆ addModelToString()

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    String irutils::addModelToString (const decode_type_t protocol,
    const int16_t model,
    const bool precomma 
    )
    +
    + +

    Create a String of human output for a given protocol model number. e.g. "Model: JKE".

    +
    Parameters
    + + + + +
    [in]protocolThe IR protocol.
    [in]modelThe model number for that protocol.
    [in]precommaShould the output string start with ", " or not?
    +
    +
    +
    Returns
    The resulting String.
    + +
    +
    + +

    ◆ addModeToString()

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    String irutils::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 
    )
    +
    + +

    Create a String of human output for the given operating mode. e.g. "Mode: 1 (Cool)".

    +
    Parameters
    + + + + + + + +
    [in]modeThe operating mode to display.
    [in]automaticThe numeric value for Auto mode.
    [in]coolThe numeric value for Cool mode.
    [in]heatThe numeric value for Heat mode.
    [in]dryThe numeric value for Dry mode.
    [in]fanThe numeric value for Fan mode.
    +
    +
    +
    Returns
    The resulting String.
    + +
    +
    + +

    ◆ addTempToString()

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    String irutils::addTempToString (const uint16_t degrees,
    const bool celsius,
    const bool precomma 
    )
    +
    + +

    Create a String of human output for a given temperature. e.g. "Temp: 25C".

    +
    Parameters
    + + + + +
    [in]degreesThe temperature in degrees.
    [in]celsiusIs the temp Celsius or Fahrenheit. true is C, false is F
    [in]precommaShould the output string start with ", " or not?
    +
    +
    +
    Returns
    The resulting String.
    + +
    +
    + +

    ◆ bcdToUint8()

    + +
    +
    + + + + + + + + +
    uint8_t irutils::bcdToUint8 (const uint8_t bcd)
    +
    + +

    Convert a byte of Binary Coded Decimal(BCD) into an Integer.

    +
    Parameters
    + + +
    [in]bcdThe BCD value.
    +
    +
    +
    Returns
    A normal Integer value.
    + +
    +
    + +

    ◆ getBit() [1/2]

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    bool irutils::getBit (const uint64_t data,
    const uint8_t position,
    const uint8_t size 
    )
    +
    + +

    Return the value of positionth bit of an Integer.

    +
    Parameters
    + + + + +
    [in]dataValue to be examined.
    [in]positionNr. of the Nth bit to be examined. 0 is the LSB.
    [in]sizeNr. of bits in data.
    +
    +
    +
    Returns
    The bit's value.
    + +
    +
    + +

    ◆ getBit() [2/2]

    + +
    +
    + + + + + + + + + + + + + + + + + + +
    bool irutils::getBit (const uint8_t data,
    const uint8_t position 
    )
    +
    + +

    Return the value of positionth bit of an Integer.

    +
    Parameters
    + + + +
    [in]dataValue to be examined.
    [in]positionNr. of the Nth bit to be examined. 0 is the LSB.
    +
    +
    +
    Returns
    The bit's value.
    + +
    +
    + +

    ◆ htmlEscape()

    + +
    +
    + + + + + + + + +
    String irutils::htmlEscape (const String unescaped)
    +
    + +

    Escape any special HTML (unsafe) characters in a string. e.g. anti-XSS.

    +
    Parameters
    + + +
    [in]unescapedA String containing text to make HTML safe.
    +
    +
    +
    Returns
    A string that is HTML safe.
    + +
    +
    + +

    ◆ minsToString()

    + +
    +
    + + + + + + + + +
    String irutils::minsToString (const uint16_t mins)
    +
    + +

    Convert a nr. of minutes into a 24h clock format Human-readable string. e.g. "23:59".

    +
    Parameters
    + + +
    [in]minsNr. of Minutes.
    +
    +
    +
    Returns
    A human readable string.
    + +
    +
    + +

    ◆ modelToStr()

    + +
    +
    + + + + + + + + + + + + + + + + + + +
    String irutils::modelToStr (const decode_type_t protocol,
    const int16_t model 
    )
    +
    + +

    Generate the model string for a given Protocol/Model pair.

    +
    Parameters
    + + + +
    [in]protocolThe IR protocol.
    [in]modelThe model number for that protocol.
    +
    +
    +
    Returns
    The resulting String.
    + +
    +
    + +

    ◆ msToString()

    + +
    +
    + + + + + + + + +
    String irutils::msToString (uint32_t const msecs)
    +
    + +

    Convert a nr. of milliSeconds into a Human-readable string. e.g. "1 Day 6 Hours 34 Minutes 17 Seconds".

    +
    Parameters
    + + +
    [in]msecsNr. of milliSeconds (ms).
    +
    +
    +
    Returns
    A human readable string.
    + +
    +
    + +

    ◆ setBit() [1/5]

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    uint64_t irutils::setBit (const uint64_t data,
    const uint8_t position,
    const bool on,
    const uint8_t size 
    )
    +
    + +

    Return the value of an Integer with the positionth bit changed.

    +
    Parameters
    + + + + + +
    [in]dataValue to be changed.
    [in]positionNr. of the bit to be changed. 0 is the LSB.
    [in]onValue to set the position'th bit to.
    [in]sizeNr. of bits in data.
    +
    +
    +
    Returns
    A suitably modified integer.
    + +
    +
    + +

    ◆ setBit() [2/5]

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    uint8_t irutils::setBit (const uint8_t data,
    const uint8_t position,
    const bool on 
    )
    +
    + +

    Return the value of an Integer with the positionth bit changed.

    +
    Parameters
    + + + + +
    [in]dataValue to be changed.
    [in]positionNr. of the bit to be changed. 0 is the LSB.
    [in]onValue to set the position'th bit to.
    +
    +
    +
    Returns
    A suitably modified integer.
    + +
    +
    + +

    ◆ setBit() [3/5]

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    void irutils::setBit (uint32_t *const data,
    const uint8_t position,
    const bool on 
    )
    +
    + +

    Alter the value of an Integer with the positionth bit changed.

    +
    Parameters
    + + + + +
    [in,out]dataA pointer to the 32-bit integer to be changed.
    [in]positionNr. of the bit to be changed. 0 is the LSB.
    [in]onValue to set the position'th bit to.
    +
    +
    + +
    +
    + +

    ◆ setBit() [4/5]

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    void irutils::setBit (uint64_t *const data,
    const uint8_t position,
    const bool on 
    )
    +
    + +

    Alter the value of an Integer with the positionth bit changed.

    +
    Parameters
    + + + + +
    [in,out]dataA pointer to the 64-bit integer to be changed.
    [in]positionNr. of the bit to be changed. 0 is the LSB.
    [in]onValue to set the position'th bit to.
    +
    +
    + +
    +
    + +

    ◆ setBit() [5/5]

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    void irutils::setBit (uint8_t *const data,
    const uint8_t position,
    const bool on 
    )
    +
    + +

    Alter the value of an Integer with the positionth bit changed.

    +
    Parameters
    + + + + +
    [in,out]dataA pointer to the 8-bit integer to be changed.
    [in]positionNr. of the bit to be changed. 0 is the LSB.
    [in]onValue to set the position'th bit to.
    +
    +
    + +
    +
    + +

    ◆ setBits() [1/3]

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    void irutils::setBits (uint32_t *const dst,
    const uint8_t offset,
    const uint8_t nbits,
    const uint32_t data 
    )
    +
    + +

    Alter an uint32_t value by overwriting an arbitary given number of bits.

    +
    Parameters
    + + + + + +
    [in,out]dstA pointer to the value to be changed.
    [in]offsetNr. of bits from the Least Significant Bit to be ignored
    [in]nbitsNr of bits of data to be placed into the destination.
    [in]dataThe value to be placed.
    +
    +
    + +
    +
    + +

    ◆ setBits() [2/3]

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    void irutils::setBits (uint64_t *const dst,
    const uint8_t offset,
    const uint8_t nbits,
    const uint64_t data 
    )
    +
    + +

    Alter an uint64_t value by overwriting an arbitary given number of bits.

    +
    Parameters
    + + + + + +
    [in,out]dstA pointer to the value to be changed.
    [in]offsetNr. of bits from the Least Significant Bit to be ignored
    [in]nbitsNr of bits of data to be placed into the destination.
    [in]dataThe value to be placed.
    +
    +
    + +
    +
    + +

    ◆ setBits() [3/3]

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    void irutils::setBits (uint8_t *const dst,
    const uint8_t offset,
    const uint8_t nbits,
    const uint8_t data 
    )
    +
    + +

    Alter an uint8_t value by overwriting an arbitary given number of bits.

    +
    Parameters
    + + + + + +
    [in,out]dstA pointer to the value to be changed.
    [in]offsetNr. of bits from the Least Significant Bit to be ignored
    [in]nbitsNr of bits of data to be placed into the destination.
    [in]dataThe value to be placed.
    +
    +
    + +
    +
    + +

    ◆ sumNibbles() [1/2]

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    uint8_t irutils::sumNibbles (const uint64_t data,
    const uint8_t count,
    const uint8_t init,
    const bool nibbleonly 
    )
    +
    + +

    Sum all the nibbles together in an integer.

    +
    Parameters
    + + + + + +
    [in]dataThe integer to be summed.
    [in]countThe number of nibbles to sum. Starts from LSB. Max of 16.
    [in]initStarting value of the calculation to use. (Default is 0)
    [in]nibbleonlytrue, the result is 4 bits. false, it's 8 bits.
    +
    +
    +
    Returns
    The 4/8-bit calculated result of all the nibbles and init value.
    + +
    +
    + +

    ◆ sumNibbles() [2/2]

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    uint8_t irutils::sumNibbles (const uint8_t *const start,
    const uint16_t length,
    const uint8_t init 
    )
    +
    + +

    Sum all the nibbles together in a series of bytes.

    +
    Parameters
    + + + + +
    [in]startA ptr to the start of the byte array to calculate over.
    [in]lengthHow many bytes to use in the calculation.
    [in]initStarting value of the calculation to use. (Default is 0)
    +
    +
    +
    Returns
    The 8-bit calculated result of all the bytes and init value.
    + +
    +
    + +

    ◆ uint8ToBcd()

    + +
    +
    + + + + + + + + +
    uint8_t irutils::uint8ToBcd (const uint8_t integer)
    +
    + +

    Convert an Integer into a byte of Binary Coded Decimal(BCD).

    +
    Parameters
    + + +
    [in]integerThe number to convert.
    +
    +
    +
    Returns
    An 8-bit BCD value.
    + +
    +
    +
    + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespacemembers.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespacemembers.html new file mode 100644 index 000000000..894fdde87 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespacemembers.html @@ -0,0 +1,188 @@ + + + + + + + +IRremoteESP8266: Namespace Members + + + + + + + + + +
    +
    + + + + + + +
    +
    IRremoteESP8266 +
    +
    +
    + + + + + + + +
    + +
    +
    + + +
    + +
    + +
    +
    Here is a list of all namespace members with links to the namespace documentation for each member:
    + +

    - a -

    + + +

    - b -

    + + +

    - d -

    + + +

    - f -

      +
    • fanspeed_t +: stdAc +
    • +
    + + +

    - g -

    + + +

    - h -

    + + +

    - m -

    + + +

    - o -

    + + +

    - r -

    + + +

    - s -

    + + +

    - u -

    +
    + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespacemembers_enum.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespacemembers_enum.html new file mode 100644 index 000000000..20b291697 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespacemembers_enum.html @@ -0,0 +1,86 @@ + + + + + + + +IRremoteESP8266: Namespace Members + + + + + + + + + +
    +
    + + + + + + +
    +
    IRremoteESP8266 +
    +
    +
    + + + + + + + +
    + +
    +
    + + +
    + +
    + +
    +
    + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespacemembers_func.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespacemembers_func.html new file mode 100644 index 000000000..2e79392e0 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespacemembers_func.html @@ -0,0 +1,134 @@ + + + + + + + +IRremoteESP8266: Namespace Members + + + + + + + + + +
    +
    + + + + + + +
    +
    IRremoteESP8266 +
    +
    +
    + + + + + + + +
    + +
    +
    + + +
    + +
    + +
    +
    + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespaces.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespaces.html new file mode 100644 index 000000000..5112518f1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespaces.html @@ -0,0 +1,83 @@ + + + + + + + +IRremoteESP8266: Namespace List + + + + + + + + + +
    +
    + + + + + + +
    +
    IRremoteESP8266 +
    +
    +
    + + + + + + + +
    + +
    +
    + + +
    + +
    + +
    +
    +
    Namespace List
    +
    +
    +
    Here is a list of all namespaces with brief descriptions:
    + + + + +
     NIRAcUtils
     NirutilsNamespace for covering common functions & procedures for advancd protocol handlers
     NstdAcEnumerators and Structures for the Common A/C API
    +
    +
    + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespacestdAc.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespacestdAc.html new file mode 100644 index 000000000..59ba02326 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/namespacestdAc.html @@ -0,0 +1,286 @@ + + + + + + + +IRremoteESP8266: stdAc Namespace Reference + + + + + + + + + +
    +
    + + + + + + +
    +
    IRremoteESP8266 +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + +
    +
    + +
    +
    stdAc Namespace Reference
    +
    +
    + +

    Enumerators and Structures for the Common A/C API. +More...

    + + + + + +

    +Classes

    struct  state_t
     Structure to hold a common A/C state. More...
     
    + + + + + + + + + + + + + +

    +Enumerations

    enum  opmode_t {
    +  opmode_t::kOff = -1, +opmode_t::kAuto = 0, +opmode_t::kCool = 1, +opmode_t::kHeat = 2, +
    +  opmode_t::kDry = 3, +opmode_t::kFan = 4, +opmode_t::kLastOpmodeEnum = kFan +
    + }
     Common A/C settings for A/C operating modes. More...
     
    enum  fanspeed_t {
    +  fanspeed_t::kAuto = 0, +fanspeed_t::kMin = 1, +fanspeed_t::kLow = 2, +fanspeed_t::kMedium = 3, +
    +  fanspeed_t::kHigh = 4, +fanspeed_t::kMax = 5, +fanspeed_t::kLastFanspeedEnum = kMax +
    + }
     Common A/C settings for Fan Speeds. More...
     
    enum  swingv_t {
    +  swingv_t::kOff = -1, +swingv_t::kAuto = 0, +swingv_t::kHighest = 1, +swingv_t::kHigh = 2, +
    +  swingv_t::kMiddle = 3, +swingv_t::kLow = 4, +swingv_t::kLowest = 5, +swingv_t::kLastSwingvEnum = kLowest +
    + }
     Common A/C settings for Vertical Swing. More...
     
    enum  swingh_t {
    +  swingh_t::kOff = -1, +swingh_t::kAuto = 0, +swingh_t::kLeftMax = 1, +swingh_t::kLeft = 2, +
    +  swingh_t::kMiddle = 3, +swingh_t::kRight = 4, +swingh_t::kRightMax = 5, +swingh_t::kWide = 6, +
    +  swingh_t::kLastSwinghEnum = kWide +
    + }
     Common A/C settings for Horizontal Swing. More...
     
    +

    Detailed Description

    +

    Enumerators and Structures for the Common A/C API.

    +

    Enumeration Type Documentation

    + +

    ◆ fanspeed_t

    + +
    +
    + + + + + +
    + + + + +
    enum stdAc::fanspeed_t
    +
    +strong
    +
    + +

    Common A/C settings for Fan Speeds.

    + + + + + + + + +
    Enumerator
    kAuto 
    kMin 
    kLow 
    kMedium 
    kHigh 
    kMax 
    kLastFanspeedEnum 
    + +
    +
    + +

    ◆ opmode_t

    + +
    +
    + + + + + +
    + + + + +
    enum stdAc::opmode_t
    +
    +strong
    +
    + +

    Common A/C settings for A/C operating modes.

    + + + + + + + + +
    Enumerator
    kOff 
    kAuto 
    kCool 
    kHeat 
    kDry 
    kFan 
    kLastOpmodeEnum 
    + +
    +
    + +

    ◆ swingh_t

    + +
    +
    + + + + + +
    + + + + +
    enum stdAc::swingh_t
    +
    +strong
    +
    + +

    Common A/C settings for Horizontal Swing.

    + + + + + + + + + + +
    Enumerator
    kOff 
    kAuto 
    kLeftMax 
    kLeft 
    kMiddle 
    kRight 
    kRightMax 
    kWide 
    kLastSwinghEnum 
    + +
    +
    + +

    ◆ swingv_t

    + +
    +
    + + + + + +
    + + + + +
    enum stdAc::swingv_t
    +
    +strong
    +
    + +

    Common A/C settings for Vertical Swing.

    + + + + + + + + + +
    Enumerator
    kOff 
    kAuto 
    kHighest 
    kHigh 
    kMiddle 
    kLow 
    kLowest 
    kLastSwingvEnum 
    + +
    +
    +
    + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/nav_f.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/nav_f.png new file mode 100644 index 000000000..72a58a529 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/nav_f.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/nav_g.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/nav_g.png new file mode 100644 index 000000000..2093a237a Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/nav_g.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/nav_h.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/nav_h.png new file mode 100644 index 000000000..33389b101 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/nav_h.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/open.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/open.png new file mode 100644 index 000000000..30f75c7ef Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/open.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/pages.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/pages.html new file mode 100644 index 000000000..8cc753069 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/pages.html @@ -0,0 +1,83 @@ + + + + + + + +IRremoteESP8266: Related Pages + + + + + + + + + +
    +
    + + + + + + +
    +
    IRremoteESP8266 +
    +
    +
    + + + + + + + +
    + +
    +
    + + +
    + +
    + +
    +
    +
    Related Pages
    +
    +
    +
    Here is a list of all related documentation pages:
    +
    + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_0.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_0.html new file mode 100644 index 000000000..26dd244fd --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_0.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_0.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_0.js new file mode 100644 index 000000000..0be3721bd --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_0.js @@ -0,0 +1,50 @@ +var searchData= +[ + ['_5fcancelofftimer_0',['_cancelOffTimer',['../classIRCarrierAc64.html#a4a0fdf34836b1c954b27c9b242324679',1,'IRCarrierAc64']]], + ['_5fcancelontimer_1',['_cancelOnTimer',['../classIRCarrierAc64.html#a43e7be5a1a6fe2dbfe245e99d2205779',1,'IRCarrierAc64']]], + ['_5fclean_2',['_clean',['../classIRFujitsuAC.html#acf7808cfeb6e15cea1d5ee8196075e04',1,'IRFujitsuAC']]], + ['_5fcmd_3',['_cmd',['../classIRFujitsuAC.html#a5e66bc4a24b892525cfa02bb4d741cbf',1,'IRFujitsuAC']]], + ['_5fdelaymicroseconds_4',['_delayMicroseconds',['../classIRsend.html#a61ceb32aa53f538b93377b10e58b45c9',1,'IRsend']]], + ['_5fdesiredtemp_5',['_desiredtemp',['../classIRWhirlpoolAc.html#aee17cfa10f19e0df992b25cff58e9613',1,'IRWhirlpoolAc']]], + ['_5fdutycycle_6',['_dutycycle',['../classIRsend.html#a602e96e8cdbd6af41d288d905043e51f',1,'IRsend']]], + ['_5ffan_7',['_fan',['../classIRSharpAc.html#ad0f4e6025f2952c477bbd3f72a64d2fe',1,'IRSharpAc']]], + ['_5ffanspeed_8',['_fanSpeed',['../classIRFujitsuAC.html#a537f02328039c044f7152bf0a61a05c9',1,'IRFujitsuAC']]], + ['_5ffilter_9',['_filter',['../classIRFujitsuAC.html#a4a2f96f4f1cd6650d48ebc3b13fd561c',1,'IRFujitsuAC']]], + ['_5fforcepower_10',['_forcepower',['../classIRSamsungAc.html#a022c96bfab671b1d0b6b5b331be31993',1,'IRSamsungAc']]], + ['_5ffreq_5funittest_11',['_freq_unittest',['../classIRsend.html#a2caec2f35ecdb890b1e34d9eb3642363',1,'IRsend']]], + ['_5fgettime_12',['_getTime',['../classIRPanasonicAc.html#ab0a592b759daf90be548ac69ae99f40f',1,'IRPanasonicAc']]], + ['_5fgettimer_13',['_getTimer',['../classIRCoronaAc.html#a419053fbf9ef27e937db0ff7519927bd',1,'IRCoronaAc::_getTimer()'],['../classIRVestelAc.html#ad3f095d248ad3c84a777ed9f2d3b001e',1,'IRVestelAc::_getTimer()']]], + ['_5finverted_14',['_inverted',['../classIRac.html#a9cfaa0b92819f06b3aa5b3e9e48b9d51',1,'IRac']]], + ['_5firsend_15',['_irsend',['../classIRAmcorAc.html#a6245bb51fa206031c3348e3eb6cb096d',1,'IRAmcorAc::_irsend()'],['../classIRArgoAC.html#a1abd8d958c3e153c4f2aaf7a3716414e',1,'IRArgoAC::_irsend()'],['../classIRCarrierAc64.html#a17270f2b1d6cab828e2a51fc23b36437',1,'IRCarrierAc64::_irsend()'],['../classIRCoolixAC.html#a6c7033e72fb860bca600ba6ea6e7afef',1,'IRCoolixAC::_irsend()'],['../classIRCoronaAc.html#afba5a3c3cff3859303a91d136ad00b66',1,'IRCoronaAc::_irsend()'],['../classIRDaikinESP.html#a2f5a8cb170d54f06bfa3eeb9b8ff838e',1,'IRDaikinESP::_irsend()'],['../classIRDaikin2.html#aa8ba00ae2c09af098146452164c4cb3b',1,'IRDaikin2::_irsend()'],['../classIRDaikin216.html#ac0e88b92a5c75138ce5b3a31f0c09be2',1,'IRDaikin216::_irsend()'],['../classIRDaikin160.html#a3094f35b359d8774a95dd3896c0e45e4',1,'IRDaikin160::_irsend()'],['../classIRDaikin176.html#a24f7022eb1c1936f5ee95ac0d732584c',1,'IRDaikin176::_irsend()'],['../classIRDaikin128.html#a1f155cc34e6c21d206962239d0135d1b',1,'IRDaikin128::_irsend()'],['../classIRDaikin152.html#a9b203215156d48dabac0fa8fd19dc613',1,'IRDaikin152::_irsend()'],['../classIRDaikin64.html#a6eb57b0eb12dab12bd9cf2fe4fded2c7',1,'IRDaikin64::_irsend()'],['../classIRDelonghiAc.html#a8cbe8b6857b7492c108118b4eda3ecb0',1,'IRDelonghiAc::_irsend()'],['../classIRElectraAc.html#af8732b31f2a4421226220dd8a4a4f985',1,'IRElectraAc::_irsend()'],['../classIRFujitsuAC.html#a2b7fec218b3530b06ce8b49f472e9595',1,'IRFujitsuAC::_irsend()'],['../classIRGoodweatherAc.html#acf606eb9e024c99407138dbd058e98d9',1,'IRGoodweatherAc::_irsend()'],['../classIRGreeAC.html#a36390655badf0ad5b5809499a8634f70',1,'IRGreeAC::_irsend()'],['../classIRHaierAC.html#aec69643fe633a57d635754690225fdd1',1,'IRHaierAC::_irsend()'],['../classIRHaierACYRW02.html#a24dd00bfa5e062c5c7f459bcd60213b7',1,'IRHaierACYRW02::_irsend()'],['../classIRHitachiAc.html#a0e296fa54cc4c56e16c6fc58c7ad827f',1,'IRHitachiAc::_irsend()'],['../classIRHitachiAc1.html#a61ad6289fc3719a850299788e642b98b',1,'IRHitachiAc1::_irsend()'],['../classIRHitachiAc424.html#a39157a1bda46304429570be2880c6ec4',1,'IRHitachiAc424::_irsend()'],['../classIRHitachiAc3.html#a8dc3b713e29f3ea96a106868451ba728',1,'IRHitachiAc3::_irsend()'],['../classIRKelvinatorAC.html#ae3571bf6de20e47f81ad1da8f1d13118',1,'IRKelvinatorAC::_irsend()'],['../classIRLgAc.html#a779f321b65db6ad05ab3e578b38cf093',1,'IRLgAc::_irsend()'],['../classIRMideaAC.html#ae2b6068355ecdc360c4c2ca2fd8d921b',1,'IRMideaAC::_irsend()'],['../classIRMitsubishiAC.html#a6753b676690f35bc8ba73504fdc34946',1,'IRMitsubishiAC::_irsend()'],['../classIRMitsubishi136.html#acd14c7bb6b26d0603ee552a000e16d43',1,'IRMitsubishi136::_irsend()'],['../classIRMitsubishi112.html#af858d640f9b2fca053287f280c8a27c0',1,'IRMitsubishi112::_irsend()'],['../classIRMitsubishiHeavy152Ac.html#a1ebd4c8b06d64e0944358156f58d414e',1,'IRMitsubishiHeavy152Ac::_irsend()'],['../classIRMitsubishiHeavy88Ac.html#a1e999c9ee028d35c03cd6b4751bcb8be',1,'IRMitsubishiHeavy88Ac::_irsend()'],['../classIRNeoclimaAc.html#a43e42b1c7e68e5a85ed10454c6210be5',1,'IRNeoclimaAc::_irsend()'],['../classIRPanasonicAc.html#a065dcc65ef3dbb8f2384f883fb97d102',1,'IRPanasonicAc::_irsend()'],['../classIRSamsungAc.html#a5815878dbebe512c41c26924cf9f5eeb',1,'IRSamsungAc::_irsend()'],['../classIRSharpAc.html#a10ee598c31c0f8179ace953ed88e37c6',1,'IRSharpAc::_irsend()'],['../classIRTcl112Ac.html#a3f10e710a44c3a80f4f9ed5247b28058',1,'IRTcl112Ac::_irsend()'],['../classIRTecoAc.html#a283ff8b73ef2998f0668d0a03cba0938',1,'IRTecoAc::_irsend()'],['../classIRToshibaAC.html#a694609136a9cbdb9af5f8bb98411c2eb',1,'IRToshibaAC::_irsend()'],['../classIRTrotecESP.html#a1faa968fc2651dc1774160950e97a74e',1,'IRTrotecESP::_irsend()'],['../classIRVestelAc.html#a56d35fc5d39c97b4c6f2decf176e2cae',1,'IRVestelAc::_irsend()'],['../classIRWhirlpoolAc.html#af4fdac2382048e2776c787bebd482e9e',1,'IRWhirlpoolAc::_irsend()']]], + ['_5firtimer_5funittest_5fnow_16',['_IRtimer_unittest_now',['../IRtimer_8cpp.html#a4ac531aa761a28d68edbc12967038180',1,'IRtimer.cpp']]], + ['_5flastsentpowerstate_17',['_lastsentpowerstate',['../classIRSamsungAc.html#af1c6712dc05a451e815675abe972d9b4',1,'IRSamsungAc']]], + ['_5fmatchgeneric_18',['_matchGeneric',['../classIRrecv.html#af0b300fe6fdff58324525e8208be3024',1,'IRrecv']]], + ['_5fmode_19',['_mode',['../classIRFujitsuAC.html#a1b22f3bb3dc43e370aabad5b6efd7ca5',1,'IRFujitsuAC::_mode()'],['../classIRSharpAc.html#a169d5636aead556234dc301729050619',1,'IRSharpAc::_mode()']]], + ['_5fmodel_20',['_model',['../classIRFujitsuAC.html#a181c71dbd46ceabdcfe08448ee32bba7',1,'IRFujitsuAC::_model()'],['../classIRGreeAC.html#ae357bf1611f349e2686f4f46c2581c47',1,'IRGreeAC::_model()']]], + ['_5fmodulation_21',['_modulation',['../classIRac.html#acc6b7380f11c38d13fffa99ca2189a9b',1,'IRac']]], + ['_5foutsidequiet_22',['_outsideQuiet',['../classIRFujitsuAC.html#a20a794245e0bc44607faf7927a285672',1,'IRFujitsuAC']]], + ['_5fpin_23',['_pin',['../classIRac.html#aba78a2510d8cdcaf4c601e8b0574ae6c',1,'IRac']]], + ['_5fprev_24',['_prev',['../classIRac.html#a8c63dc78c49f3714887fea0feefffd44',1,'IRac']]], + ['_5fprevioustemp_25',['_previoustemp',['../classIRHitachiAc.html#a1368dcd7f4c0049822fd2b9b1e0acb5e',1,'IRHitachiAc::_previoustemp()'],['../classIRHitachiAc424.html#aba6c17936775e268744af23a4a533f92',1,'IRHitachiAc424::_previoustemp()']]], + ['_5fprotocol_26',['_protocol',['../classIRLgAc.html#a9bd32e865a7358bbf32830d888e2786a',1,'IRLgAc']]], + ['_5fsaved_5ftemp_27',['_saved_temp',['../classIRDaikin176.html#a8f1d6c765bf09c1a3dc9678c3939a5be',1,'IRDaikin176::_saved_temp()'],['../classIRDelonghiAc.html#a724aa5748e714a7f0109a2f3502cd1d1',1,'IRDelonghiAc::_saved_temp()']]], + ['_5fsaved_5ftemp_5funits_28',['_saved_temp_units',['../classIRDelonghiAc.html#a14fba6ccbc25da76744d28e7a40c385b',1,'IRDelonghiAc']]], + ['_5fsendsony_29',['_sendSony',['../classIRsend.html#a21352b4499f976872a74bae36ea10338',1,'IRsend']]], + ['_5fsetmode_30',['_setMode',['../classIRWhirlpoolAc.html#a60fd8da35d6e0137711e114a5307d664',1,'IRWhirlpoolAc']]], + ['_5fsetpower_31',['_setPower',['../classIRCoronaAc.html#a4b05b7e34e0f2e66f59ff279c6970478',1,'IRCoronaAc']]], + ['_5fsettemp_32',['_setTemp',['../classIRLgAc.html#a39aca9861608211c8e74c89a7ccc97cd',1,'IRLgAc::_setTemp()'],['../classIRWhirlpoolAc.html#abb221e09077efd96304f84e8ca130458',1,'IRWhirlpoolAc::_setTemp()']]], + ['_5fsettime_33',['_setTime',['../classIRPanasonicAc.html#a51e306dd7a3e4d580ed5396fcd166141',1,'IRPanasonicAc']]], + ['_5fsettimer_34',['_setTimer',['../classIRCoronaAc.html#a0ea9319987de7cb7f3dcb9fbefb60a2c',1,'IRCoronaAc::_setTimer()'],['../classIRVestelAc.html#a726178a16458c84d031aec07355d0dd2',1,'IRVestelAc::_setTimer()']]], + ['_5fstate_5flength_35',['_state_length',['../classIRFujitsuAC.html#aea1819d0041f305e2c990f6f3eced865',1,'IRFujitsuAC']]], + ['_5fstate_5flength_5fshort_36',['_state_length_short',['../classIRFujitsuAC.html#a7093cf32cd2e856ff692aebc732c1d50',1,'IRFujitsuAC']]], + ['_5fswingh_37',['_swingh',['../classIRPanasonicAc.html#ad0300ee66bcab38e13724520cb3226f9',1,'IRPanasonicAc']]], + ['_5fswingmode_38',['_swingMode',['../classIRFujitsuAC.html#a74a00fbba55b457b68f61481ce9ffbaa',1,'IRFujitsuAC']]], + ['_5fswingvtoggle_39',['_SwingVToggle',['../classIRMideaAC.html#adb4318940487aea09116fe6b9f061470',1,'IRMideaAC']]], + ['_5ftemp_40',['_temp',['../classIRFujitsuAC.html#afcff35df74885c63651134ba85359694',1,'IRFujitsuAC::_temp()'],['../classIRLgAc.html#a1eeb727ee96c26b784a607aabd4577c9',1,'IRLgAc::_temp()'],['../classIRPanasonicAc.html#af6511e3c9745ff6750dc6fc3fdda21b3',1,'IRPanasonicAc::_temp()'],['../classIRSharpAc.html#a1d0a6274534123133217175920c7cd95',1,'IRSharpAc::_temp()']]], + ['_5ftimer_5fnum_41',['_timer_num',['../classIRrecv.html#aff11c0c20735b16ce411088003607911',1,'IRrecv']]], + ['_5ftimerms_5funittest_5fnow_42',['_TimerMs_unittest_now',['../IRtimer_8cpp.html#aed35ce7fa92ebb856a03f81e756cb2c6',1,'IRtimer.cpp']]], + ['_5ftolerance_43',['_tolerance',['../classIRrecv.html#a0459a65dd31b215713ad66a1e4f3540e',1,'IRrecv']]], + ['_5ftostring_44',['_toString',['../classIRHitachiAc424.html#af7ab654c4eecf770a70399f6b9959db3',1,'IRHitachiAc424']]], + ['_5funknown_5fthreshold_45',['_unknown_threshold',['../classIRrecv.html#adb8cbc5c1cb739f33f5be25b3a6c79bd',1,'IRrecv']]], + ['_5fvalidtolerance_46',['_validTolerance',['../classIRrecv.html#a0b4221970de0d027b5ae99648fa1c003',1,'IRrecv']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1.html new file mode 100644 index 000000000..8eb215b90 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1.js new file mode 100644 index 000000000..02e9d8e2f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1.js @@ -0,0 +1,23 @@ +var searchData= +[ + ['add_47',['add',['../classIRtimer.html#aa8e3ff975ae5468b4727790c828fa032',1,'IRtimer::add()'],['../classTimerMs.html#a77bfc23a029a9172c3dbac03f746b0cb',1,'TimerMs::add()']]], + ['addbooltostring_48',['addBoolToString',['../namespaceirutils.html#a12ba9cf1830a886649a80c3cc5fdce2b',1,'irutils']]], + ['adddaytostring_49',['addDayToString',['../namespaceirutils.html#a6ead1d10578c64627f8a24b5d8a7444f',1,'irutils']]], + ['addfantostring_50',['addFanToString',['../namespaceirutils.html#ae023bbabc452173d348c14eac7d86ab4',1,'irutils']]], + ['addinttostring_51',['addIntToString',['../namespaceirutils.html#a772e623c4b60208200e02afbaec66651',1,'irutils']]], + ['addlabeledstring_52',['addLabeledString',['../namespaceirutils.html#ac98793392d1e65c1b8d6895eb9d9b75b',1,'irutils']]], + ['addmodeltostring_53',['addModelToString',['../namespaceirutils.html#a06e5a5c2b6f6649035dfa5eb19801367',1,'irutils']]], + ['addmodetostring_54',['addModeToString',['../namespaceirutils.html#a8b74ae0258e98aa0eaebc6f3efe1481e',1,'irutils']]], + ['address_55',['address',['../classdecode__results.html#a2858c3a5e28eccca95d44aaa87b70e9e',1,'decode_results']]], + ['addtemptostring_56',['addTempToString',['../namespaceirutils.html#a0cef0634f4db979a93b7dc19cc2b4a85',1,'irutils']]], + ['airwell_57',['AIRWELL',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada0cd75c2edaa4c674d679dbb39635990a',1,'IRremoteESP8266.h']]], + ['aiwa_5frc_5ft501_58',['AIWA_RC_T501',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada7dc14b2c4769ef9de663c2e2165d8f75',1,'IRremoteESP8266.h']]], + ['akb75215403_59',['AKB75215403',['../IRsend_8h.html#a50c54713e16502d280723334879dc83ba37d3851f43307f1e1eac46c5fbf3f08a',1,'IRsend.h']]], + ['amcor_60',['amcor',['../classIRac.html#a4bad16621b232572e14fe4a53f678131',1,'IRac::amcor()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada1325ba25674d7a99562f15a1b392086b',1,'AMCOR(): IRremoteESP8266.h']]], + ['ardb1_61',['ARDB1',['../IRsend_8h.html#a7204e78a1fe37a819c0b66f87a685dc0a6f6fcd0be917d91b71c1b80b5446ee5b',1,'IRsend.h']]], + ['argo_62',['argo',['../classIRArgoAC.html#ab607bde051712a57fe9c0a0cf9da20ac',1,'IRArgoAC::argo()'],['../classIRac.html#aa06ee1314529dbf96f4e6f3c28ea6821',1,'IRac::argo()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadac9ff1fa84905b54238b16d31197efb72',1,'ARGO(): IRremoteESP8266.h']]], + ['arjw2_63',['ARJW2',['../IRsend_8h.html#a7204e78a1fe37a819c0b66f87a685dc0acbca1f3d199103d8cb9d856b9089cdc4',1,'IRsend.h']]], + ['arrah2e_64',['ARRAH2E',['../IRsend_8h.html#a7204e78a1fe37a819c0b66f87a685dc0a6ccf47af1067e794e02e21f03389297b',1,'IRsend.h']]], + ['arreb1e_65',['ARREB1E',['../IRsend_8h.html#a7204e78a1fe37a819c0b66f87a685dc0a2443ff6f0181dbc1af275c709d67147a',1,'IRsend.h']]], + ['arry4_66',['ARRY4',['../IRsend_8h.html#a7204e78a1fe37a819c0b66f87a685dc0aee3994c5a4a8447463d67df2cdf5a946',1,'IRsend.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_10.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_10.html new file mode 100644 index 000000000..6fd3a4aa2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_10.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_10.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_10.js new file mode 100644 index 000000000..46c722884 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_10.js @@ -0,0 +1,13 @@ +var searchData= +[ + ['padding_3198',['padding',['../unionmagiquest.html#a28ca4be56c78ef762f87171506dc6e93',1,'magiquest']]], + ['panasonic_3199',['panasonic',['../classIRac.html#af873db2b9735127eb6f079861daed67a',1,'IRac::panasonic()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadaf87c99938d26a1f77d4f082c070d4660',1,'PANASONIC(): IRremoteESP8266.h']]], + ['panasonic_5fac_3200',['PANASONIC_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada02178d0c70511011d5f381291bb7e491',1,'IRremoteESP8266.h']]], + ['panasonic_5fac_5fremote_5fmodel_5ft_3201',['panasonic_ac_remote_model_t',['../IRsend_8h.html#a1b797a5e5176ac0eef49810bf7f40e6f',1,'IRsend.h']]], + ['periodoffset_3202',['periodOffset',['../classIRsend.html#a1b5180cbf4f88f19fca3f677e1e91b96',1,'IRsend']]], + ['pioneer_3203',['PIONEER',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadadf49fef8f6e9740c92af2e25384f7846',1,'IRremoteESP8266.h']]], + ['power_3204',['power',['../structstdAc_1_1state__t.html#ab85d37cc99bbbc4915331369c4ea622e',1,'stdAc::state_t']]], + ['powerflag_3205',['powerFlag',['../classIRCoolixAC.html#a5984ff64ff14df92291618a647da08f9',1,'IRCoolixAC']]], + ['pronto_3206',['PRONTO',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada5b68c32f80c4afa6e61039843b2d1f97',1,'IRremoteESP8266.h']]], + ['protocol_3207',['protocol',['../structstdAc_1_1state__t.html#af59897778be0e571f77dd11337352c27',1,'stdAc::state_t']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_11.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_11.html new file mode 100644 index 000000000..f78343b9b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_11.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_11.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_11.js new file mode 100644 index 000000000..7b22d20b7 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_11.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['quiet_3208',['quiet',['../structstdAc_1_1state__t.html#a251ad14e187a9905137e9e4e010c3e34',1,'stdAc::state_t']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_12.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_12.html new file mode 100644 index 000000000..dd9ff1d59 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_12.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_12.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_12.js new file mode 100644 index 000000000..138cb936c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_12.js @@ -0,0 +1,29 @@ +var searchData= +[ + ['r_5flt0541_5fhta_5fa_3209',['R_LT0541_HTA_A',['../IRsend_8h.html#acd0c6107b5a6cab2080b18a8de14ea49afed7c9dd67250bb1e72081e5f05b35f8',1,'IRsend.h']]], + ['r_5flt0541_5fhta_5fb_3210',['R_LT0541_HTA_B',['../IRsend_8h.html#acd0c6107b5a6cab2080b18a8de14ea49a03b6e058b4cfeb6719906bc3cd57594f',1,'IRsend.h']]], + ['raw_3211',['RAW',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadabdeded99fe7d3f2773014a9a2cfb73d7',1,'IRremoteESP8266.h']]], + ['rawbuf_3212',['rawbuf',['../structirparams__t.html#a6f8a82b51fa206a8cb195e5838aa0cb3',1,'irparams_t::rawbuf()'],['../classdecode__results.html#a19043dc161cd5e0d3dcc82b5a7470e49',1,'decode_results::rawbuf()']]], + ['rawlen_3213',['rawlen',['../structirparams__t.html#a08e83386c65a90038e0d4922f1f6aa84',1,'irparams_t::rawlen()'],['../classdecode__results.html#a913e19fc5032fa1f97cf8afe0fa450ec',1,'decode_results::rawlen()']]], + ['rc5_3214',['RC5',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadac3c0a3883a1488209bcd91730ece33b2',1,'IRremoteESP8266.h']]], + ['rc5x_3215',['RC5X',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada8a3ac4419806a34ba566bfcbbb0e4f1d',1,'IRremoteESP8266.h']]], + ['rc6_3216',['RC6',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada7f7247f15587eb3812846f424b941abe',1,'IRremoteESP8266.h']]], + ['rcmm_3217',['RCMM',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada79204b7ae26be334cebf3ea8268c34ab',1,'IRremoteESP8266.h']]], + ['rcvstate_3218',['rcvstate',['../structirparams__t.html#a63354788dab4569f4092cd05e77f0260',1,'irparams_t']]], + ['readme_2emd_3219',['README.md',['../README_8md.html',1,'']]], + ['recoversavedstate_3220',['recoverSavedState',['../classIRCoolixAC.html#a134cb36681c3fab53074b402bba0a45c',1,'IRCoolixAC']]], + ['recvpin_3221',['recvpin',['../structirparams__t.html#a50da5aa1c42a69b01d50ea688db67d14',1,'irparams_t']]], + ['remote_3222',['remote',['../classIRDaikinESP.html#ac24751c23f6b27cb26dcd51e91c63c9b',1,'IRDaikinESP::remote()'],['../classIRGoodweatherAc.html#af511a0703a4cbc77f5b8a520abf11f2f',1,'IRGoodweatherAc::remote()'],['../classIRSharpAc.html#a411a4db0579ed84b54533dcde153d5da',1,'IRSharpAc::remote()']]], + ['remote_5fstate_3223',['remote_state',['../classIRAmcorAc.html#acef1c3896f03afd5d10d5cbb7ed105ce',1,'IRAmcorAc::remote_state()'],['../classIRCarrierAc64.html#a257272c7cb54f5854e79053c8223a43e',1,'IRCarrierAc64::remote_state()'],['../classIRCoolixAC.html#a03bf575961d4d924275cb16a45edaa46',1,'IRCoolixAC::remote_state()'],['../classIRCoronaAc.html#afcf0b21ac5c438dc560612a785a29864',1,'IRCoronaAc::remote_state()'],['../classIRDaikin2.html#a0b28396956687a4009cab7c860b9ce4b',1,'IRDaikin2::remote_state()'],['../classIRDaikin216.html#abf9bab0a52f9227d54f583488b024a85',1,'IRDaikin216::remote_state()'],['../classIRDaikin160.html#a17fb5726060e8872735559654a72cb22',1,'IRDaikin160::remote_state()'],['../classIRDaikin176.html#adb6863da11f0569524f0beb31681d0b5',1,'IRDaikin176::remote_state()'],['../classIRDaikin128.html#af1b36cc2f51cd145da3bfe7ec3d9134a',1,'IRDaikin128::remote_state()'],['../classIRDaikin152.html#aa16c89c0cb6d83aef83d293466dab197',1,'IRDaikin152::remote_state()'],['../classIRDaikin64.html#aa279d6df0d130e727c3a1500b283eda0',1,'IRDaikin64::remote_state()'],['../classIRDelonghiAc.html#a3b3364143c52dc2a29d9db43612c07b1',1,'IRDelonghiAc::remote_state()'],['../classIRElectraAc.html#a3f423f5d896e4bfc2f3a0ce04b596289',1,'IRElectraAc::remote_state()'],['../classIRFujitsuAC.html#a851b9192e1f18f6a4b2f1726d49ef33b',1,'IRFujitsuAC::remote_state()'],['../classIRGreeAC.html#a9e0cb21278ac3c9a72738ab8e6e09096',1,'IRGreeAC::remote_state()'],['../classIRHaierAC.html#a609abaeab9df642fdaccd77235a84eed',1,'IRHaierAC::remote_state()'],['../classIRHaierACYRW02.html#a08069ef89f5c5e2c1ba8563cdad24578',1,'IRHaierACYRW02::remote_state()'],['../classIRHitachiAc.html#a44b3d360b2a8044782b73f7f4a533a99',1,'IRHitachiAc::remote_state()'],['../classIRHitachiAc1.html#a13340cba808d457d6093f1c9efffc419',1,'IRHitachiAc1::remote_state()'],['../classIRHitachiAc424.html#a58bac4ef7f46ef1e9f38c1a144e2ca41',1,'IRHitachiAc424::remote_state()'],['../classIRHitachiAc3.html#a5602ded229a41796c205519449f7d509',1,'IRHitachiAc3::remote_state()'],['../classIRKelvinatorAC.html#a70f75821274e53cc5ed64ac53a6e32b4',1,'IRKelvinatorAC::remote_state()'],['../classIRLgAc.html#a481133671657b13ecce1bd08f710089d',1,'IRLgAc::remote_state()'],['../classIRMideaAC.html#a8f122367cc407e7bb658fe7f3132effb',1,'IRMideaAC::remote_state()'],['../classIRMitsubishiAC.html#ac0a149b9705371e59c45ece162bc1aab',1,'IRMitsubishiAC::remote_state()'],['../classIRMitsubishi136.html#ad1e80d693d3558f0bed4c0f7995bddd5',1,'IRMitsubishi136::remote_state()'],['../classIRMitsubishi112.html#a64a40e57208d08b5cd6ef87a7c8d6671',1,'IRMitsubishi112::remote_state()'],['../classIRMitsubishiHeavy152Ac.html#a6d333f238bf1b42e39919d4897080aa8',1,'IRMitsubishiHeavy152Ac::remote_state()'],['../classIRMitsubishiHeavy88Ac.html#a46be0e755530f59fad7d3f9050ecc107',1,'IRMitsubishiHeavy88Ac::remote_state()'],['../classIRNeoclimaAc.html#a336507e0635ede3b9ebf53881ece50bb',1,'IRNeoclimaAc::remote_state()'],['../classIRPanasonicAc.html#a85d5118c0ed947cc77f2ed94b0d44e4a',1,'IRPanasonicAc::remote_state()'],['../classIRSamsungAc.html#a5966a3b665ce034de807de1955396e10',1,'IRSamsungAc::remote_state()'],['../classIRTcl112Ac.html#a6eda1148a977a3ccf0c6c30239fca4c8',1,'IRTcl112Ac::remote_state()'],['../classIRTecoAc.html#a3c2ad7587ed4f5589deb20d8dc16b1e4',1,'IRTecoAc::remote_state()'],['../classIRToshibaAC.html#aab228aa6db2255dddf98a46a25cbb0f0',1,'IRToshibaAC::remote_state()'],['../classIRTrotecESP.html#afccba55e2c3d42c716591c10bc9afa18',1,'IRTrotecESP::remote_state()'],['../classIRVestelAc.html#a74d889a0db2fa63a2e38aaa15819568c',1,'IRVestelAc::remote_state()'],['../classIRWhirlpoolAc.html#a65333985c39773896071081ebcca4821',1,'IRWhirlpoolAc::remote_state()']]], + ['remote_5ftime_5fstate_3224',['remote_time_state',['../classIRVestelAc.html#a9b10e4a0c1f71aecbeb385666d1a53bd',1,'IRVestelAc']]], + ['repeat_3225',['repeat',['../classdecode__results.html#a09da48786fe3966cd5621840fd771bfa',1,'decode_results']]], + ['reset_3226',['reset',['../classIRtimer.html#aaaf886de2c9533a8c791242dc575db1a',1,'IRtimer::reset()'],['../classTimerMs.html#a25ab025793a4d432e7d4180cbd31157b',1,'TimerMs::reset()']]], + ['resultactostring_3227',['resultAcToString',['../namespaceIRAcUtils.html#ac3d2683bc26edc2bf58916187b5349c3',1,'IRAcUtils']]], + ['resulttohexidecimal_3228',['resultToHexidecimal',['../IRutils_8cpp.html#a25a669d53f231de6152f8e60cedf39f7',1,'resultToHexidecimal(const decode_results *const result): IRutils.cpp'],['../IRutils_8h.html#a25a669d53f231de6152f8e60cedf39f7',1,'resultToHexidecimal(const decode_results *const result): IRutils.cpp']]], + ['resulttohumanreadablebasic_3229',['resultToHumanReadableBasic',['../IRutils_8cpp.html#a0cc6ae1b9649b1ea1d2bfe7e7b03b6d8',1,'resultToHumanReadableBasic(const decode_results *const results): IRutils.cpp'],['../IRutils_8h.html#a0cc6ae1b9649b1ea1d2bfe7e7b03b6d8',1,'resultToHumanReadableBasic(const decode_results *const results): IRutils.cpp']]], + ['resulttorawarray_3230',['resultToRawArray',['../IRutils_8cpp.html#a7b3bbfa1f2bf2dea2fc40a2fefe05a2a',1,'resultToRawArray(const decode_results *const decode): IRutils.cpp'],['../IRutils_8h.html#a7b3bbfa1f2bf2dea2fc40a2fefe05a2a',1,'resultToRawArray(const decode_results *const decode): IRutils.cpp']]], + ['resulttosourcecode_3231',['resultToSourceCode',['../IRutils_8cpp.html#a10fc00c8b399dddb67a228325e6e2f79',1,'resultToSourceCode(const decode_results *const results): IRutils.cpp'],['../IRutils_8h.html#a10fc00c8b399dddb67a228325e6e2f79',1,'resultToSourceCode(const decode_results *const results): IRutils.cpp']]], + ['resulttotiminginfo_3232',['resultToTimingInfo',['../IRutils_8cpp.html#afbfdef125ff077431f3abc27a1eeb800',1,'resultToTimingInfo(const decode_results *const results): IRutils.cpp'],['../IRutils_8h.html#afbfdef125ff077431f3abc27a1eeb800',1,'resultToTimingInfo(const decode_results *const results): IRutils.cpp']]], + ['resume_3233',['resume',['../classIRrecv.html#a6b5beb7348d807d8d98ae929d005510e',1,'IRrecv']]], + ['reversebits_3234',['reverseBits',['../IRutils_8cpp.html#a366219b6f1c46f41c6573b3e5e875e41',1,'reverseBits(uint64_t input, uint16_t nbits): IRutils.cpp'],['../IRutils_8h.html#a366219b6f1c46f41c6573b3e5e875e41',1,'reverseBits(uint64_t input, uint16_t nbits): IRutils.cpp']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_13.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_13.html new file mode 100644 index 000000000..2611a100d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_13.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_13.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_13.js new file mode 100644 index 000000000..745394494 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_13.js @@ -0,0 +1,244 @@ +var searchData= +[ + ['samsung_3235',['samsung',['../classIRac.html#a619c659a11c258ea9623eaa37689ba4c',1,'IRac::samsung()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada2b451b6e7bebbf070d0913ec77d5d438',1,'SAMSUNG(): IRremoteESP8266.h']]], + ['samsung36_3236',['SAMSUNG36',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadaa0d1be0c368e3594bc546c241d031fd4',1,'IRremoteESP8266.h']]], + ['samsung_5fac_3237',['SAMSUNG_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada39f991023009d760432489e7ad7ad4df',1,'IRremoteESP8266.h']]], + ['sanyo_3238',['SANYO',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadac1cf5078ebfd7ff83c70e8ec8522b288',1,'IRremoteESP8266.h']]], + ['sanyo_5flc7461_3239',['SANYO_LC7461',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada558721044a11b1d4b491343f02267e1d',1,'IRremoteESP8266.h']]], + ['saved_5fstate_3240',['saved_state',['../classIRCoolixAC.html#aec0bce8019d7d49a30915394bee56b9a',1,'IRCoolixAC']]], + ['scrap_3241',['scrap',['../unionmagiquest.html#afd0bcf9a87f0fa2db87b68b211952a73',1,'magiquest']]], + ['send_3242',['send',['../classIRAmcorAc.html#a4fa894c01a8baabfeadb39634a850fd9',1,'IRAmcorAc::send()'],['../classIRArgoAC.html#a0e4793a4f6fc537ec1450f5a42206dae',1,'IRArgoAC::send()'],['../classIRCarrierAc64.html#aace8aa2d125c6e80bcdd6d96eac722c2',1,'IRCarrierAc64::send()'],['../classIRCoolixAC.html#aaaa681d6cfcf04d110b913e8bb27a53c',1,'IRCoolixAC::send()'],['../classIRCoronaAc.html#aa0c8a1ef4473a3c7d02e1a04c7678fa6',1,'IRCoronaAc::send()'],['../classIRDaikinESP.html#a9f0d2641b54e97da943fceb0ba3f67eb',1,'IRDaikinESP::send()'],['../classIRDaikin2.html#aae2db88038d8d02617f16588e6a82b64',1,'IRDaikin2::send()'],['../classIRDaikin216.html#ab1061620f838cf7774c16c593b4ada8c',1,'IRDaikin216::send()'],['../classIRDaikin160.html#a0e1c74070c03be02e40fdd05ed56465c',1,'IRDaikin160::send()'],['../classIRDaikin176.html#affd71592fa8ed05816d94edbf94d2c0a',1,'IRDaikin176::send()'],['../classIRDaikin128.html#aae7fec91ad2265e8b0378c6b99379e89',1,'IRDaikin128::send()'],['../classIRDaikin152.html#a205de6821effc077f51d941d369791e4',1,'IRDaikin152::send()'],['../classIRDaikin64.html#a904eec38045d9ddc8a97ab33c8a2ac4d',1,'IRDaikin64::send()'],['../classIRDelonghiAc.html#afba831b6884771b84bab684732e0f4f5',1,'IRDelonghiAc::send()'],['../classIRElectraAc.html#a30170a65de1161e26daeddf694f8afdb',1,'IRElectraAc::send()'],['../classIRFujitsuAC.html#a1f1aa593cc4503d14c0fbea5cd9823a1',1,'IRFujitsuAC::send()'],['../classIRGoodweatherAc.html#abcc3c9d9b0912b09d3c0b0c1affb8cc8',1,'IRGoodweatherAc::send()'],['../classIRGreeAC.html#a9823578040c2d15e2b3e8e3a17a9e220',1,'IRGreeAC::send()'],['../classIRHaierAC.html#a9fe53d04965efca6daf234f20d20eb5a',1,'IRHaierAC::send()'],['../classIRHaierACYRW02.html#a65a5d5840dddac505b009e899a0dada7',1,'IRHaierACYRW02::send()'],['../classIRHitachiAc.html#afc53e562370bbaba8b5dda26a62de427',1,'IRHitachiAc::send()'],['../classIRHitachiAc1.html#aafad51c226066b8697cf00661ef38d99',1,'IRHitachiAc1::send()'],['../classIRHitachiAc424.html#adf15121bb329e1bb061f9e5efb848764',1,'IRHitachiAc424::send()'],['../classIRHitachiAc3.html#ab95fd527a4841c44d6e91c8b4afee8b4',1,'IRHitachiAc3::send()'],['../classIRHitachiAc344.html#ae9b33c0adfc1506b1d9ede1e3285c3e3',1,'IRHitachiAc344::send()'],['../classIRKelvinatorAC.html#aa55fbfefbaca1acf5bc9ba796bea8464',1,'IRKelvinatorAC::send()'],['../classIRLgAc.html#aea85c840161b48f2e8d31e7e6e7da532',1,'IRLgAc::send()'],['../classIRMideaAC.html#af66b9f76ad794450a0a7eace4bb59300',1,'IRMideaAC::send()'],['../classIRMitsubishiAC.html#a2467ad33d88af8f6244e7cd0620e012e',1,'IRMitsubishiAC::send()'],['../classIRMitsubishi136.html#a41295e551acf428e76b9b404af2381ad',1,'IRMitsubishi136::send()'],['../classIRMitsubishi112.html#a8f813da813b1a281654147ada2e63eba',1,'IRMitsubishi112::send()'],['../classIRMitsubishiHeavy152Ac.html#acc53c5c136c6987c420d48bddcf9b2da',1,'IRMitsubishiHeavy152Ac::send()'],['../classIRMitsubishiHeavy88Ac.html#a707cb3ec3e3c18bedeb12205580d5048',1,'IRMitsubishiHeavy88Ac::send()'],['../classIRNeoclimaAc.html#a2220bbb1d928b8f6490cd43b702ef430',1,'IRNeoclimaAc::send()'],['../classIRPanasonicAc.html#a778420ebe52aa6422ba5633ce91676df',1,'IRPanasonicAc::send()'],['../classIRSamsungAc.html#a8128429fcb1828a049784d832cafc9fe',1,'IRSamsungAc::send()'],['../classIRSharpAc.html#a829872744bf9fef51dccd89584ddffe6',1,'IRSharpAc::send()'],['../classIRTcl112Ac.html#a9aa8c67e167a3d241157306d0668ff15',1,'IRTcl112Ac::send()'],['../classIRTecoAc.html#ad5785e93e8c0c95a8618b0e371adaa79',1,'IRTecoAc::send()'],['../classIRToshibaAC.html#a14b155d3a20fb9c127eb7f3fe1fd16cd',1,'IRToshibaAC::send()'],['../classIRTrotecESP.html#add228d50195d7b9b43346a90bf959512',1,'IRTrotecESP::send()'],['../classIRVestelAc.html#a606497754b381e70d13ddef5643c9d0b',1,'IRVestelAc::send()'],['../classIRWhirlpoolAc.html#a0c043b3d7cc993940941351e6c63b5cc',1,'IRWhirlpoolAc::send()'],['../classIRsend.html#a204eedc3ad182fb2f40c42ef58f78cfc',1,'IRsend::send(const decode_type_t type, const uint64_t data, const uint16_t nbits, const uint16_t repeat=kNoRepeat)'],['../classIRsend.html#ac684c209ea8722f0a377070752df0040',1,'IRsend::send(const decode_type_t type, const uint8_t *state, const uint16_t nbytes)']]], + ['sendac_3243',['sendAc',['../classIRac.html#a0cea80b7bab92c9dc4f18c61f5762130',1,'IRac::sendAc(void)'],['../classIRac.html#aa33c42968acafc5cf479574483f94ea9',1,'IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev=NULL)'],['../classIRac.html#ad60fbe1488efe2d02307d81b090b3b72',1,'IRac::sendAc(const decode_type_t vendor, const int16_t model, const bool power, const stdAc::opmode_t mode, const float degrees, const bool celsius, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool econo, const bool light, const bool filter, const bool clean, const bool beep, const int16_t sleep=-1, const int16_t clock=-1)']]], + ['sendairwell_3244',['sendAirwell',['../classIRsend.html#a5b180d3845b45af38a19b72e6fa8e0c0',1,'IRsend']]], + ['sendaiwarct501_3245',['sendAiwaRCT501',['../classIRsend.html#ad39a4b13ad2e8500c95db49265e7c771',1,'IRsend']]], + ['sendamcor_3246',['sendAmcor',['../classIRsend.html#acd64b100eb155f90451d467188a83e92',1,'IRsend']]], + ['sendargo_3247',['sendArgo',['../classIRsend.html#a59668b767e4ad4966fe0bc259c3bd34f',1,'IRsend']]], + ['sendcarrierac_3248',['sendCarrierAC',['../classIRsend.html#a9e859a8b5eaea2e64978c8f93b78d159',1,'IRsend']]], + ['sendcarrierac40_3249',['sendCarrierAC40',['../classIRsend.html#a4342b775777d2ff9371f48aa39ad9b69',1,'IRsend']]], + ['sendcarrierac64_3250',['sendCarrierAC64',['../classIRsend.html#abf755688d87fcef5aee86c6a2c89e7c4',1,'IRsend']]], + ['sendcoolix_3251',['sendCOOLIX',['../classIRsend.html#a088af5f0d76965c61fe5716f7b8f2b61',1,'IRsend']]], + ['sendcoronaac_3252',['sendCoronaAc',['../classIRsend.html#a81f82b8248b324799a48a7685d62aaa5',1,'IRsend']]], + ['senddaikin_3253',['sendDaikin',['../classIRsend.html#a3010546144b5ca3b3c94f5881050dbd0',1,'IRsend']]], + ['senddaikin128_3254',['sendDaikin128',['../classIRsend.html#a72a41a704d48750c144c6467ae9a1430',1,'IRsend']]], + ['senddaikin152_3255',['sendDaikin152',['../classIRsend.html#a4ad420eb86e0ae38b12e983f7eaa912c',1,'IRsend']]], + ['senddaikin160_3256',['sendDaikin160',['../classIRsend.html#ab144a86def38f9f5c98701742683c004',1,'IRsend']]], + ['senddaikin176_3257',['sendDaikin176',['../classIRsend.html#ac4b5bcb95d3aff70b2f84074177e9e92',1,'IRsend']]], + ['senddaikin2_3258',['sendDaikin2',['../classIRsend.html#a34262e579cbb6634459bc09c5b15dfa0',1,'IRsend']]], + ['senddaikin216_3259',['sendDaikin216',['../classIRsend.html#aa99bfdaa71ff5bf088faaa17d304f45d',1,'IRsend']]], + ['senddaikin64_3260',['sendDaikin64',['../classIRsend.html#aa403d2192a6eb57910e6f84695475b27',1,'IRsend']]], + ['senddata_3261',['sendData',['../classIRsend.html#a4f8cd77dab7ce6c406029fe87674858f',1,'IRsend']]], + ['senddelonghiac_3262',['sendDelonghiAc',['../classIRsend.html#a35dc18f9abbffa8da40816a8a9df1093',1,'IRsend']]], + ['senddenon_3263',['sendDenon',['../classIRsend.html#a2618e000bf91cf1585329308a078653a',1,'IRsend']]], + ['senddish_3264',['sendDISH',['../classIRsend.html#ac7a72d61af219d983409911bdc1769b8',1,'IRsend']]], + ['senddoshisha_3265',['sendDoshisha',['../classIRsend.html#a3a9a8247e470975137b37f474bb97639',1,'IRsend']]], + ['sendelectraac_3266',['sendElectraAC',['../classIRsend.html#a52526c4e7bc4402e57ecf81e0047d49c',1,'IRsend']]], + ['sendepson_3267',['sendEpson',['../classIRsend.html#a063168fd82f6a88cca7253b42b9c0b28',1,'IRsend']]], + ['sendextended_3268',['sendExtended',['../classIRSamsungAc.html#a16a8dbd8f3fd34a6e681125b276acfd9',1,'IRSamsungAc']]], + ['sendfujitsuac_3269',['sendFujitsuAC',['../classIRsend.html#a1a3d3f83d0b7a59ff5510b038f658eb6',1,'IRsend']]], + ['sendgc_3270',['sendGC',['../classIRsend.html#acf987a501326d9c945cd8dbeb0806e17',1,'IRsend']]], + ['sendgeneric_3271',['sendGeneric',['../classIRsend.html#a5215fd797dfd490816f31bb99b38c273',1,'IRsend::sendGeneric(const uint16_t headermark, const uint32_t headerspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t gap, const uint64_t data, const uint16_t nbits, const uint16_t frequency, const bool MSBfirst, const uint16_t repeat, const uint8_t dutycycle)'],['../classIRsend.html#aaace48306af9c020c18848db1a05e641',1,'IRsend::sendGeneric(const uint16_t headermark, const uint32_t headerspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t gap, const uint32_t mesgtime, const uint64_t data, const uint16_t nbits, const uint16_t frequency, const bool MSBfirst, const uint16_t repeat, const uint8_t dutycycle)'],['../classIRsend.html#a4f5ad649827692b4b42d15b45c7f684b',1,'IRsend::sendGeneric(const uint16_t headermark, const uint32_t headerspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t gap, const uint8_t *dataptr, const uint16_t nbytes, const uint16_t frequency, const bool MSBfirst, const uint16_t repeat, const uint8_t dutycycle)']]], + ['sendgicable_3272',['sendGICable',['../classIRsend.html#a61dd16bc150473bbfd998dada72b205f',1,'IRsend']]], + ['sendgoodweather_3273',['sendGoodweather',['../classIRsend.html#a8e2d98ae5c39ee07a61f08facecbaa1e',1,'IRsend']]], + ['sendgree_3274',['sendGree',['../classIRsend.html#aca81ea348ceb6b0c9e62073b57bc0b17',1,'IRsend::sendGree(const uint64_t data, const uint16_t nbits=kGreeBits, const uint16_t repeat=kGreeDefaultRepeat)'],['../classIRsend.html#af788e7d9a2ad2483313434f9b5196753',1,'IRsend::sendGree(const uint8_t data[], const uint16_t nbytes=kGreeStateLength, const uint16_t repeat=kGreeDefaultRepeat)']]], + ['sendhaierac_3275',['sendHaierAC',['../classIRsend.html#a6b4b9144d56dda302f5b321f1c5017ff',1,'IRsend']]], + ['sendhaieracyrw02_3276',['sendHaierACYRW02',['../classIRsend.html#a6aa1c1a6880872c87a46e4e0ead5d9b0',1,'IRsend']]], + ['sendhitachiac_3277',['sendHitachiAC',['../classIRsend.html#a8e6079b8b1b69ad7d7f8d05c492becbe',1,'IRsend']]], + ['sendhitachiac1_3278',['sendHitachiAC1',['../classIRsend.html#a5be9a87ce052e4f056766919247e0b22',1,'IRsend']]], + ['sendhitachiac2_3279',['sendHitachiAC2',['../classIRsend.html#a451b1913608a4ba8c26d9af8c85d16f1',1,'IRsend']]], + ['sendhitachiac3_3280',['sendHitachiAc3',['../classIRsend.html#aec7e67f4292622521b5a0a8cfdd21d84',1,'IRsend']]], + ['sendhitachiac344_3281',['sendHitachiAc344',['../classIRsend.html#a5fb28d54f2832651d992450673d05c01',1,'IRsend']]], + ['sendhitachiac424_3282',['sendHitachiAc424',['../classIRsend.html#a2a9676de30bb868b313cc9c30025f790',1,'IRsend']]], + ['sendinax_3283',['sendInax',['../classIRsend.html#a5fa5ff62276d9d680fb1255cc8b99eec',1,'IRsend']]], + ['sendjvc_3284',['sendJVC',['../classIRsend.html#aaa10c899768a5b4cdb1a7913d06141ca',1,'IRsend']]], + ['sendkelvinator_3285',['sendKelvinator',['../classIRsend.html#a8cba9df982fc91f895196d61d2e65b0e',1,'IRsend']]], + ['sendlasertag_3286',['sendLasertag',['../classIRsend.html#a55a79f9727590044751f291a4df83892',1,'IRsend']]], + ['sendlegopf_3287',['sendLegoPf',['../classIRsend.html#a4e38273aeacf01873a013c02d41a44e4',1,'IRsend']]], + ['sendlg_3288',['sendLG',['../classIRsend.html#a079a84c82f360d6d55fde5c27634f51c',1,'IRsend']]], + ['sendlg2_3289',['sendLG2',['../classIRsend.html#a5b6be1ceac8a4bc4ef55dc12eb060531',1,'IRsend']]], + ['sendlutron_3290',['sendLutron',['../classIRsend.html#a85f2a98255d3af7b7407c082ea7b7c16',1,'IRsend']]], + ['sendmagiquest_3291',['sendMagiQuest',['../classIRsend.html#af1d0e9ec0f735fc5fb9011d4f4cb8327',1,'IRsend']]], + ['sendmanchester_3292',['sendManchester',['../classIRsend.html#a7862231cbb1d50f42996c25e2f05b93e',1,'IRsend']]], + ['sendmanchesterdata_3293',['sendManchesterData',['../classIRsend.html#aa76aa33785827c1278eb57d1c15236f8',1,'IRsend']]], + ['sendmidea_3294',['sendMidea',['../classIRsend.html#a37d91b3a77b36509abdc53e2fec20a67',1,'IRsend']]], + ['sendmidea24_3295',['sendMidea24',['../classIRsend.html#a103d79e8df7954e9ab6284fa9f3daf02',1,'IRsend']]], + ['sendmitsubishi_3296',['sendMitsubishi',['../classIRsend.html#a59e8941a25c5c0bbc839fba5b1a22813',1,'IRsend']]], + ['sendmitsubishi112_3297',['sendMitsubishi112',['../classIRsend.html#a0a55e688c6aad015494168f25eb337b5',1,'IRsend']]], + ['sendmitsubishi136_3298',['sendMitsubishi136',['../classIRsend.html#a988a8b7dda3563977d537d6ac448ebc8',1,'IRsend']]], + ['sendmitsubishi2_3299',['sendMitsubishi2',['../classIRsend.html#ac54e50a6819f5c39e060891f1f6ea0f2',1,'IRsend']]], + ['sendmitsubishiac_3300',['sendMitsubishiAC',['../classIRsend.html#a3600527a82f9f22387c9f16ae51fb06f',1,'IRsend']]], + ['sendmitsubishiheavy152_3301',['sendMitsubishiHeavy152',['../classIRsend.html#ae1cffc4882c63f192c231397d19a4032',1,'IRsend']]], + ['sendmitsubishiheavy88_3302',['sendMitsubishiHeavy88',['../classIRsend.html#afaf4fd0c3dabd1bd6f8fe421294c5063',1,'IRsend']]], + ['sendmultibrackets_3303',['sendMultibrackets',['../classIRsend.html#a9026d42480b85270e560e122b8be3b6c',1,'IRsend']]], + ['sendmwm_3304',['sendMWM',['../classIRsend.html#a98301801daf929ec8ce022987ae394f2',1,'IRsend']]], + ['sendnec_3305',['sendNEC',['../classIRsend.html#a324c9e455c0bae51ebe9bc07e915c043',1,'IRsend']]], + ['sendneoclima_3306',['sendNeoclima',['../classIRsend.html#a71e1b5e780851210465bbf061b9c095b',1,'IRsend']]], + ['sendnikai_3307',['sendNikai',['../classIRsend.html#a693e6616b81509cf27d1345c140acc96',1,'IRsend']]], + ['sendoff_3308',['sendOff',['../classIRSamsungAc.html#a96e2ae87f3ffcf1ad812f256f31e4898',1,'IRSamsungAc']]], + ['sendon_3309',['sendOn',['../classIRSamsungAc.html#a7e6980c829dfd143d4d19abaf5d65678',1,'IRSamsungAc']]], + ['sendpanasonic_3310',['sendPanasonic',['../classIRsend.html#a92192475f89b19cfdf7fd0416a263145',1,'IRsend']]], + ['sendpanasonic64_3311',['sendPanasonic64',['../classIRsend.html#adc4fd287f3546f7ff0b67e177a42b560',1,'IRsend']]], + ['sendpanasonicac_3312',['sendPanasonicAC',['../classIRsend.html#a10a3c387a328dbb11733a251f4db7614',1,'IRsend']]], + ['sendpioneer_3313',['sendPioneer',['../classIRsend.html#a11f099f3768a659d1f996589cea8a313',1,'IRsend']]], + ['sendpronto_3314',['sendPronto',['../classIRsend.html#a0b349351e2ba19f87e6b01cde7e67c49',1,'IRsend']]], + ['sendraw_3315',['sendRaw',['../classIRsend.html#a2b9b84f828918f933bd1764d113b53f8',1,'IRsend']]], + ['sendrc5_3316',['sendRC5',['../classIRsend.html#a2bd2ccb27ecd57e14b36f76d82af308a',1,'IRsend']]], + ['sendrc6_3317',['sendRC6',['../classIRsend.html#a2192a95e0d162f9b1775fc2a47f65c37',1,'IRsend']]], + ['sendrcmm_3318',['sendRCMM',['../classIRsend.html#a3cafe475a58234a0d3aa655a2464be75',1,'IRsend']]], + ['sendsamsung_3319',['sendSAMSUNG',['../classIRsend.html#a5252dd159aad713c099de6728ac56d81',1,'IRsend']]], + ['sendsamsung36_3320',['sendSamsung36',['../classIRsend.html#ab5dcd4ec5ddb0b0351870ddf54e5ba66',1,'IRsend']]], + ['sendsamsungac_3321',['sendSamsungAC',['../classIRsend.html#a2773d251da1d35b964810c8cc4cb438b',1,'IRsend']]], + ['sendsanyolc7461_3322',['sendSanyoLC7461',['../classIRsend.html#aa23e51a97a0ec1907d22623fed6dd223',1,'IRsend']]], + ['sendsharp_3323',['sendSharp',['../classIRsend.html#a801ae78ac5a72116c566c4ac5f99c6bd',1,'IRsend']]], + ['sendsharpac_3324',['sendSharpAc',['../classIRsend.html#a438e4c9d50e62da7d772d8d638728213',1,'IRsend']]], + ['sendsharpraw_3325',['sendSharpRaw',['../classIRsend.html#aa1f12fd537ca8c21c183ee41d17a3afc',1,'IRsend']]], + ['sendsherwood_3326',['sendSherwood',['../classIRsend.html#afb3a89acfb868c92a997a3000e70c6e8',1,'IRsend']]], + ['sendsony_3327',['sendSony',['../classIRsend.html#a02bb64503474a0841c51664cf4668d85',1,'IRsend']]], + ['sendsony38_3328',['sendSony38',['../classIRsend.html#a558442f49b32453f0fb987c29e1ec6d3',1,'IRsend']]], + ['sendsymphony_3329',['sendSymphony',['../classIRsend.html#a1f1d5a30660ab0061f64d559d4916d4e',1,'IRsend']]], + ['sendtcl112ac_3330',['sendTcl112Ac',['../classIRsend.html#a2dedce2841e4a6445a98f03393fce823',1,'IRsend']]], + ['sendteco_3331',['sendTeco',['../classIRsend.html#ac6300f977fe94119813481ba682ce33f',1,'IRsend']]], + ['sendtoshibaac_3332',['sendToshibaAC',['../classIRsend.html#a4ef8e028135536dc1f5a63be85ef7d49',1,'IRsend']]], + ['sendtrotec_3333',['sendTrotec',['../classIRsend.html#a135796327b5db127473f4d198e663c00',1,'IRsend']]], + ['sendvestelac_3334',['sendVestelAc',['../classIRsend.html#a129a40f9d344cb0fadfd4cca53ca6b44',1,'IRsend']]], + ['sendwhirlpoolac_3335',['sendWhirlpoolAC',['../classIRsend.html#aa440a50000a259072f93ad6c0e42ec22',1,'IRsend']]], + ['sendwhynter_3336',['sendWhynter',['../classIRsend.html#a07188366deed3dd902cba80a711cf220',1,'IRsend']]], + ['sendzepeal_3337',['sendZepeal',['../classIRsend.html#a9bcba8bbac41d679b5b930e67d3e1b7f',1,'IRsend']]], + ['serialprintuint64_3338',['serialPrintUint64',['../IRutils_8cpp.html#ad2b0a4b9a1a7fca3d5f5afc14b682433',1,'serialPrintUint64(uint64_t input, uint8_t base): IRutils.cpp'],['../IRutils_8h.html#a315d5f05fb572564025bc9ce9b820243',1,'serialPrintUint64(uint64_t input, uint8_t base=10): IRutils.cpp']]], + ['set3d_3339',['set3D',['../classIRMitsubishiHeavy152Ac.html#ab22654d492a4b0e82efcd0c96fc9bbe3',1,'IRMitsubishiHeavy152Ac::set3D()'],['../classIRMitsubishiHeavy88Ac.html#ae0b7eac743a8de6852722f067e010ba7',1,'IRMitsubishiHeavy88Ac::set3D()']]], + ['set8cheat_3340',['set8CHeat',['../classIRNeoclimaAc.html#a3176c5fe3251bd6a31a3a0ddc2c294be',1,'IRNeoclimaAc']]], + ['setauto_3341',['setAuto',['../classIRVestelAc.html#a2509eed2e0d7b23595bbe6dd7df17d74',1,'IRVestelAc']]], + ['setbeep_3342',['setBeep',['../classIRDaikin2.html#a4c0588887a45403a0a9f2cf95f847889',1,'IRDaikin2::setBeep()'],['../classIRSamsungAc.html#a092ccbea031dd4be747076530117649d',1,'IRSamsungAc::setBeep()']]], + ['setbit_3343',['setBit',['../namespaceirutils.html#a316301577d2ff338bfba6605df2cc46b',1,'irutils::setBit(const uint64_t data, const uint8_t position, const bool on, const uint8_t size)'],['../namespaceirutils.html#a2e9e858b490fa3328b4c5bd01adedb8c',1,'irutils::setBit(const uint8_t data, const uint8_t position, const bool on)'],['../namespaceirutils.html#ac1b3de6e733d9c4d614a8239f5bd3220',1,'irutils::setBit(uint8_t *const data, const uint8_t position, const bool on)'],['../namespaceirutils.html#a86bbcf05c1601712b1d587b87035f09b',1,'irutils::setBit(uint32_t *const data, const uint8_t position, const bool on)'],['../namespaceirutils.html#a9e7814e2274f02df0dac0106c293c487',1,'irutils::setBit(uint64_t *const data, const uint8_t position, const bool on)']]], + ['setbits_3344',['setBits',['../namespaceirutils.html#ab4f5e3eb26e111909ddc93a8b018ba78',1,'irutils::setBits(uint8_t *const dst, const uint8_t offset, const uint8_t nbits, const uint8_t data)'],['../namespaceirutils.html#a3fd8b18a76f0ae8f730b4de55fc9486e',1,'irutils::setBits(uint32_t *const dst, const uint8_t offset, const uint8_t nbits, const uint32_t data)'],['../namespaceirutils.html#a4dfb0984a9ea38602805987a7845839c',1,'irutils::setBits(uint64_t *const dst, const uint8_t offset, const uint8_t nbits, const uint64_t data)']]], + ['setboost_3345',['setBoost',['../classIRDelonghiAc.html#a827d1e43e9252657147226aa3f8e4eb8',1,'IRDelonghiAc']]], + ['setbreeze_3346',['setBreeze',['../classIRSamsungAc.html#a310a73f15a0274fbaf15b981abaae592',1,'IRSamsungAc']]], + ['setbutton_3347',['setButton',['../classIRHaierACYRW02.html#aa0f1561e2446f6231f722581f5bae34d',1,'IRHaierACYRW02::setButton()'],['../classIRHitachiAc424.html#af4ded7ea8aa94271d5135eebd3bb80a8',1,'IRHitachiAc424::setButton()'],['../classIRNeoclimaAc.html#a7e2e6e646411b4f5ea3c1ce1e944581c',1,'IRNeoclimaAc::setButton()']]], + ['setclean_3348',['setClean',['../classIRCoolixAC.html#a0087ac58749ef946632fbb5a8b41fe0d',1,'IRCoolixAC::setClean()'],['../classIRDaikin2.html#a21e09b867710a225d5cf53006f723326',1,'IRDaikin2::setClean()'],['../classIRElectraAc.html#a4aa44fc40196067469dfa8a722e33115',1,'IRElectraAc::setClean()'],['../classIRFujitsuAC.html#a7f6f18ea39bf28717cb65ff348b1b2f5',1,'IRFujitsuAC::setClean()'],['../classIRMitsubishiHeavy152Ac.html#a11678e7eb906414770938f6efce266f1',1,'IRMitsubishiHeavy152Ac::setClean()'],['../classIRMitsubishiHeavy88Ac.html#a65968304e4aaf025dfefc49d5d777cbd',1,'IRMitsubishiHeavy88Ac::setClean()'],['../classIRSamsungAc.html#a911ca57dfb0e6787cba330e8d49b2496',1,'IRSamsungAc::setClean()'],['../classIRSharpAc.html#ace6e7b98496a594031809fe8a535c429',1,'IRSharpAc::setClean()']]], + ['setclock_3349',['setClock',['../classIRDaikin128.html#aa9928ac010ec79ddab4f551eedf2f5d9',1,'IRDaikin128::setClock()'],['../classIRDaikin64.html#a655f1cec5e28f79e5718573678c535ec',1,'IRDaikin64::setClock()'],['../classIRMitsubishiAC.html#a7abe34adf36bdd1a65a17f56ee8af1f6',1,'IRMitsubishiAC::setClock()'],['../classIRPanasonicAc.html#a3f76c6aca94f52c227c2e259512fd101',1,'IRPanasonicAc::setClock()'],['../classIRWhirlpoolAc.html#aab09aae7de733414bf480c3df22b83f8',1,'IRWhirlpoolAc::setClock()']]], + ['setcmd_3350',['setCmd',['../classIRFujitsuAC.html#a7579944c11b3d31bb069303926307617',1,'IRFujitsuAC']]], + ['setcomfort_3351',['setComfort',['../classIRDaikinESP.html#aaa15c0be7ffb8e845a03d193583a58d1',1,'IRDaikinESP::setComfort()'],['../classIRDaikin152.html#a95de2dc0a90fe4212cb60973b9430486',1,'IRDaikin152::setComfort()']]], + ['setcommand_3352',['setCommand',['../classIRGoodweatherAc.html#a4e266f42b7a82c49208e2acc7813e07b',1,'IRGoodweatherAc::setCommand()'],['../classIRHaierAC.html#ade34c951e72a794c2ff7fa0d1595d68f',1,'IRHaierAC::setCommand()'],['../classIRWhirlpoolAc.html#aaea26b1388489dff70a98fde1e6185be',1,'IRWhirlpoolAc::setCommand()']]], + ['setcurrentday_3353',['setCurrentDay',['../classIRDaikinESP.html#a5465b9857fd73b82362f766368717d16',1,'IRDaikinESP']]], + ['setcurrenttime_3354',['setCurrentTime',['../classIRDaikinESP.html#ae6559268982ae0968358a885c7dbba6e',1,'IRDaikinESP::setCurrentTime()'],['../classIRDaikin2.html#a8b32b1b9a87c9b671af6aeedb709d520',1,'IRDaikin2::setCurrentTime()']]], + ['setcurrtime_3355',['setCurrTime',['../classIRHaierAC.html#a53500ebdec058d27396e5906a572fe15',1,'IRHaierAC']]], + ['setdisplay_3356',['setDisplay',['../classIRSamsungAc.html#ad20199bed3a01208ec694b9d4eb7ef98',1,'IRSamsungAc']]], + ['setdisplaytempsource_3357',['setDisplayTempSource',['../classIRGreeAC.html#a1d073c31ea169d0e5cf33c8592982035',1,'IRGreeAC']]], + ['setecono_3358',['setEcono',['../classIRCoronaAc.html#abb5624317fff60674bed410be3a3fa52',1,'IRCoronaAc::setEcono()'],['../classIRDaikinESP.html#a12129aedd6320522a9b6e811e347089c',1,'IRDaikinESP::setEcono()'],['../classIRDaikin2.html#a42a44a6cefa6bf6f45148d39c216ebc0',1,'IRDaikin2::setEcono()'],['../classIRDaikin128.html#a07fb5289ee476e0335fec4845254b7ce',1,'IRDaikin128::setEcono()'],['../classIRDaikin152.html#a8062d16f7aefb7586e3d3bdfea8755b4',1,'IRDaikin152::setEcono()'],['../classIRMitsubishiHeavy152Ac.html#ab3964219ee3c0c5112bb38c892a01784',1,'IRMitsubishiHeavy152Ac::setEcono()'],['../classIRMitsubishiHeavy88Ac.html#a7612448f1cceaa6aeee1697f51adaf43',1,'IRMitsubishiHeavy88Ac::setEcono()'],['../classIRTcl112Ac.html#a48ac7acfa8fed8e9da39907282f4f377',1,'IRTcl112Ac::setEcono()']]], + ['seteconotoggle_3359',['setEconoToggle',['../classIRSharpAc.html#ae3495676b8bffecba5c56fbf1ab9ee4d',1,'IRSharpAc']]], + ['seteye_3360',['setEye',['../classIRDaikin2.html#a5ba8e5d5dd4aba45a90de1d450a7a88b',1,'IRDaikin2::setEye()'],['../classIRNeoclimaAc.html#aaf433cab785db382c55a420e68e7d7ec',1,'IRNeoclimaAc::setEye()']]], + ['seteyeauto_3361',['setEyeAuto',['../classIRDaikin2.html#a975c2fdb261d6d2b6c8e196fbd074899',1,'IRDaikin2']]], + ['setfan_3362',['setFan',['../classIRAmcorAc.html#acf26fc65363e2734e4dc6eb562812553',1,'IRAmcorAc::setFan()'],['../classIRArgoAC.html#a8144f003628e128ec6630aef49ed5cb5',1,'IRArgoAC::setFan()'],['../classIRCarrierAc64.html#a312027468b508e9d38dd9e23ee99f9e4',1,'IRCarrierAc64::setFan()'],['../classIRCoolixAC.html#aff4189cb1000c6db7d88624fbadbe0cb',1,'IRCoolixAC::setFan()'],['../classIRCoronaAc.html#aa4da12502bf85438846bdde56391ee5c',1,'IRCoronaAc::setFan()'],['../classIRDaikinESP.html#a1f191f45e473482a86aad9a1c879e083',1,'IRDaikinESP::setFan()'],['../classIRDaikin2.html#af9f3ddbdd1f1d5d99c84846b73c5daa1',1,'IRDaikin2::setFan()'],['../classIRDaikin216.html#a8fadfb1e61deca74a2d1b9c1d5ae62e1',1,'IRDaikin216::setFan()'],['../classIRDaikin160.html#a7f507c64dc7a9fa1e9391e9e8473af1b',1,'IRDaikin160::setFan()'],['../classIRDaikin176.html#a050a9943dc7d8289472e6b9dbdcb06c1',1,'IRDaikin176::setFan()'],['../classIRDaikin128.html#a0495834250e97e7831e9906ab548fe44',1,'IRDaikin128::setFan()'],['../classIRDaikin152.html#a385a4f65dfccd0a9e94be06ae60c5343',1,'IRDaikin152::setFan()'],['../classIRDaikin64.html#af39206f90b99fd5ee340923b196368b8',1,'IRDaikin64::setFan()'],['../classIRDelonghiAc.html#a440f1e0efa18c6b1a8e18e0a97fbfb79',1,'IRDelonghiAc::setFan()'],['../classIRElectraAc.html#aa338ce18cafaf9c7b9aa3385e681bbe7',1,'IRElectraAc::setFan()'],['../classIRGoodweatherAc.html#af8cf9ba59af548677e586cd59e8a6cc2',1,'IRGoodweatherAc::setFan()'],['../classIRGreeAC.html#a9bb570e71df5002298505d49473e6bac',1,'IRGreeAC::setFan()'],['../classIRHaierAC.html#a42ee1c5889f07bf7615c8f853bca2261',1,'IRHaierAC::setFan()'],['../classIRHaierACYRW02.html#ae9c3a7bffc08d9d5204616823f709889',1,'IRHaierACYRW02::setFan()'],['../classIRHitachiAc.html#a0760b07502b976880ee8499dc6fa61ff',1,'IRHitachiAc::setFan()'],['../classIRHitachiAc1.html#a7294dc1324877d4a64f7b4373d97d745',1,'IRHitachiAc1::setFan()'],['../classIRHitachiAc424.html#afd69bcff56224f39af92fc2d334b67bb',1,'IRHitachiAc424::setFan()'],['../classIRKelvinatorAC.html#af08e94be9699983c0087c9b059aad319',1,'IRKelvinatorAC::setFan()'],['../classIRLgAc.html#a0f1901a21ffb93641d3481417d74bb4e',1,'IRLgAc::setFan()'],['../classIRMideaAC.html#a546eeca4eea015899a5ad9f5d1c6fafb',1,'IRMideaAC::setFan()'],['../classIRMitsubishiAC.html#a4e88e50b2eddd0233aade5c1bf7819f1',1,'IRMitsubishiAC::setFan()'],['../classIRMitsubishi136.html#a2aa62126614f734ec3d1b7b3cb653e9e',1,'IRMitsubishi136::setFan()'],['../classIRMitsubishi112.html#ab681e78572c869a8c57079a660fe1505',1,'IRMitsubishi112::setFan()'],['../classIRMitsubishiHeavy152Ac.html#ac8d8eceba935aa626cb229d1c41081bb',1,'IRMitsubishiHeavy152Ac::setFan()'],['../classIRMitsubishiHeavy88Ac.html#a4f8c934a82091547c36da512329e76d7',1,'IRMitsubishiHeavy88Ac::setFan()'],['../classIRNeoclimaAc.html#a8db9d2d446e8614b2fc4583a454d7cee',1,'IRNeoclimaAc::setFan()'],['../classIRPanasonicAc.html#a8d77292226f55601c30ee53252ba83cd',1,'IRPanasonicAc::setFan()'],['../classIRSamsungAc.html#a6c7571e14fe6629348273a2b49a0a824',1,'IRSamsungAc::setFan()'],['../classIRSharpAc.html#a5138068f8ba4c51939ff3bb14f0aae45',1,'IRSharpAc::setFan()'],['../classIRTcl112Ac.html#a0dab8ad6675c4ec122d0d7e28a557cba',1,'IRTcl112Ac::setFan()'],['../classIRTecoAc.html#afda9a33ca450568f968217bedc9ad7f2',1,'IRTecoAc::setFan()'],['../classIRToshibaAC.html#a020ba3e95c607f52ce091193fc5825fc',1,'IRToshibaAC::setFan()'],['../classIRVestelAc.html#af53dfd0a0372c878b6ba2ca1cfc21ccd',1,'IRVestelAc::setFan()'],['../classIRWhirlpoolAc.html#a8da28ee25fdc91d55a9f6ab5dab3af81',1,'IRWhirlpoolAc::setFan()']]], + ['setfanspeed_3363',['setFanSpeed',['../classIRFujitsuAC.html#af0fc10ec0a606434477cb41c60eb49e5',1,'IRFujitsuAC']]], + ['setfilter_3364',['setFilter',['../classIRFujitsuAC.html#aec0048efe87f60406c76ad6bc3ffbc61',1,'IRFujitsuAC::setFilter()'],['../classIRMitsubishiHeavy152Ac.html#aaf76ac48228d3a7b8490e684407e65b1',1,'IRMitsubishiHeavy152Ac::setFilter()']]], + ['setflap_3365',['setFlap',['../classIRArgoAC.html#a55a6402ffc3fe7fb59775050901416ca',1,'IRArgoAC']]], + ['setfresh_3366',['setFresh',['../classIRNeoclimaAc.html#a6354d8b902ffc1e7c044a61185504404',1,'IRNeoclimaAc']]], + ['setfreshair_3367',['setFreshAir',['../classIRDaikin2.html#a6e0596c7b9f9b43b8d241340ae08e886',1,'IRDaikin2']]], + ['setfreshairhigh_3368',['setFreshAirHigh',['../classIRDaikin2.html#a044471f2298a1942bcc2f859f9459924',1,'IRDaikin2']]], + ['sethealth_3369',['setHealth',['../classIRHaierAC.html#a48c9ae91809d63156eeb3889f2e908f4',1,'IRHaierAC::setHealth()'],['../classIRHaierACYRW02.html#a79673650a2285f029a35ab69edeb0e74',1,'IRHaierACYRW02::setHealth()'],['../classIRTcl112Ac.html#a28ed509977d8642174bc6c9aa97ae1c3',1,'IRTcl112Ac::setHealth()']]], + ['sethold_3370',['setHold',['../classIRNeoclimaAc.html#a2eb4e0a2ff39ceb1b6b571998d91b31e',1,'IRNeoclimaAc']]], + ['sethumid_3371',['setHumid',['../classIRTecoAc.html#a4ab07a7c95f34d3b292926c719aeb303',1,'IRTecoAc']]], + ['setifeel_3372',['setIFeel',['../classIRGreeAC.html#a68a670156a5e0a91a8a3cf9225263e0b',1,'IRGreeAC::setIFeel()'],['../classIRArgoAC.html#ae59f903855961441b676b7f662602554',1,'IRArgoAC::setiFeel()']]], + ['setinvertedstates_3373',['setInvertedStates',['../classIRHitachiAc424.html#ad18528cf83e863b98cb1609eec970ac5',1,'IRHitachiAc424::setInvertedStates()'],['../classIRHitachiAc3.html#af37c710449cd32df4753509749e31cad',1,'IRHitachiAc3::setInvertedStates()']]], + ['setion_3374',['setIon',['../classIRNeoclimaAc.html#a504fc5e371746fda8e7eb7cc0abf137a',1,'IRNeoclimaAc::setIon()'],['../classIRPanasonicAc.html#a5a1c4f5b9eb7a3a1a81a6acd0491c3cd',1,'IRPanasonicAc::setIon()'],['../classIRSamsungAc.html#aeee65ca6d2100635a517077f01053bed',1,'IRSamsungAc::setIon()'],['../classIRSharpAc.html#af6a390362bc5b40eecc6564b16b3379b',1,'IRSharpAc::setIon()'],['../classIRVestelAc.html#acf860da68a15d463dab437a808c9c8c6',1,'IRVestelAc::setIon()']]], + ['setionfilter_3375',['setIonFilter',['../classIRKelvinatorAC.html#a6a219c481ddc21d93028f5c799c25883',1,'IRKelvinatorAC']]], + ['setled_3376',['setLed',['../classIRCoolixAC.html#a3132f99cffa108129dff64a0b68bd614',1,'IRCoolixAC']]], + ['setlight_3377',['setLight',['../classIRDaikin2.html#a7ecadb3335e9b22729a89b4c41456242',1,'IRDaikin2::setLight()'],['../classIRGoodweatherAc.html#a3f149ff426b236ba9f90659a6daf4a9c',1,'IRGoodweatherAc::setLight()'],['../classIRGreeAC.html#a702bbba38e11bb8f3428ee707fc82311',1,'IRGreeAC::setLight()'],['../classIRKelvinatorAC.html#a870890c2bc8510f8f7351ca21db8d855',1,'IRKelvinatorAC::setLight()'],['../classIRNeoclimaAc.html#a1d7a6ec6d319544bee907a23a1d14084',1,'IRNeoclimaAc::setLight()'],['../classIRTcl112Ac.html#a7dec5b0559f996df8a4fc259ab6012e9',1,'IRTcl112Ac::setLight()'],['../classIRTecoAc.html#a25d97c1e7be31d80a4ffad0026e633d7',1,'IRTecoAc::setLight()'],['../classIRWhirlpoolAc.html#a70b4c0467a7747f9cf9e106af1025771',1,'IRWhirlpoolAc::setLight()']]], + ['setlighttoggle_3378',['setLightToggle',['../classIRDaikin128.html#a6361c789141ccecb729c104e71ddcc41',1,'IRDaikin128::setLightToggle()'],['../classIRElectraAc.html#a15373982641e36f4b68258368700be7d',1,'IRElectraAc::setLightToggle()']]], + ['setmax_3379',['setMax',['../classIRAmcorAc.html#a1250c6b106378286d9db013296c9b16f',1,'IRAmcorAc::setMax()'],['../classIRArgoAC.html#a909c1f74e9452d0e19fc3ffd28b1b81b',1,'IRArgoAC::setMax()']]], + ['setmode_3380',['setMode',['../classIRAmcorAc.html#afa9c2d080ed5c4c7bc64eb13a07eab68',1,'IRAmcorAc::setMode()'],['../classIRArgoAC.html#a8575f0ef967b09308ed6a453857e65c7',1,'IRArgoAC::setMode()'],['../classIRCarrierAc64.html#ae462eeec49ff91358f1b9921750ee36d',1,'IRCarrierAc64::setMode()'],['../classIRCoolixAC.html#a5c0094d32aca6a5323f4dc72a03f02e9',1,'IRCoolixAC::setMode()'],['../classIRCoronaAc.html#aedeeedd176c89e5b7b650a4311e712be',1,'IRCoronaAc::setMode()'],['../classIRDaikinESP.html#af0f463201c877d33fa8680053dda7551',1,'IRDaikinESP::setMode()'],['../classIRDaikin2.html#a24ef3b53f22fe3557ed2dbc98a5bc6d2',1,'IRDaikin2::setMode()'],['../classIRDaikin216.html#a1d0dfce75ac95df9125b2cfe7c955080',1,'IRDaikin216::setMode()'],['../classIRDaikin160.html#a48e6fff63fd8b894c649fb495a467faa',1,'IRDaikin160::setMode()'],['../classIRDaikin176.html#a7ce82479f5ae2721baae8119b711c112',1,'IRDaikin176::setMode()'],['../classIRDaikin128.html#a9693e9931449f39253ca9102ac5cbfe9',1,'IRDaikin128::setMode()'],['../classIRDaikin152.html#aad0a46c751b73792282d6614103f57d8',1,'IRDaikin152::setMode()'],['../classIRDaikin64.html#a04dff0d273457a7bc3f3e0e1af4f7cd9',1,'IRDaikin64::setMode()'],['../classIRDelonghiAc.html#a62392c26321f038a84d99d54039bcfae',1,'IRDelonghiAc::setMode()'],['../classIRElectraAc.html#a911b7410fd2f29464c1505e183c04c5d',1,'IRElectraAc::setMode()'],['../classIRFujitsuAC.html#ac125c320f9794aae931bc59ba332a4a8',1,'IRFujitsuAC::setMode()'],['../classIRGoodweatherAc.html#a8eed6b70b7b1c2e8a9620db7462e1fb5',1,'IRGoodweatherAc::setMode()'],['../classIRGreeAC.html#a9d9dbd416e3dc270fcfda620b3bb4fe2',1,'IRGreeAC::setMode()'],['../classIRHaierAC.html#a3ad0317f2fd4f57d8ce61353ab3e48c7',1,'IRHaierAC::setMode()'],['../classIRHaierACYRW02.html#ae762c5f5422b4af612fa00f7c26452ed',1,'IRHaierACYRW02::setMode()'],['../classIRHitachiAc.html#a208f73a42484a1555145b41849e8c51f',1,'IRHitachiAc::setMode()'],['../classIRHitachiAc1.html#a1f3ced601e1131b70f840820ecb3feaa',1,'IRHitachiAc1::setMode()'],['../classIRHitachiAc424.html#a373a51d207674e35e00762b057f73cd5',1,'IRHitachiAc424::setMode()'],['../classIRKelvinatorAC.html#af55cc77892bc960587037c337b90d1bc',1,'IRKelvinatorAC::setMode()'],['../classIRLgAc.html#a5e1b21d9121c6bf6507f615f470b5890',1,'IRLgAc::setMode()'],['../classIRMideaAC.html#a3b92f25a82741ae404e8f9af8dbca3a8',1,'IRMideaAC::setMode()'],['../classIRMitsubishiAC.html#a2b4e2f00ee5a385172b13e8d9858ac0b',1,'IRMitsubishiAC::setMode()'],['../classIRMitsubishi136.html#aaef2ed81bdeb183995e2342c2ca17a8b',1,'IRMitsubishi136::setMode()'],['../classIRMitsubishi112.html#a0c1434e1d8dd513007400042324e868e',1,'IRMitsubishi112::setMode()'],['../classIRMitsubishiHeavy152Ac.html#a5a68388f337d7ba80289359903a1d01d',1,'IRMitsubishiHeavy152Ac::setMode()'],['../classIRMitsubishiHeavy88Ac.html#a1802cc8a382d6161b83f8947137d941d',1,'IRMitsubishiHeavy88Ac::setMode()'],['../classIRNeoclimaAc.html#adabd715c4a2ec34dd88330b97a1f0ecd',1,'IRNeoclimaAc::setMode()'],['../classIRPanasonicAc.html#add025b64e736d5120abeb2564a2849a4',1,'IRPanasonicAc::setMode()'],['../classIRSamsungAc.html#a708d9c6c91d774d6eeadbc0bd7f350af',1,'IRSamsungAc::setMode()'],['../classIRSharpAc.html#ab51c207de90391cb7190e3ec95adc16e',1,'IRSharpAc::setMode()'],['../classIRTcl112Ac.html#a1a050c9b238691ba6d4764beeb788778',1,'IRTcl112Ac::setMode()'],['../classIRTecoAc.html#aba404540b723fa4687a4fda954221130',1,'IRTecoAc::setMode()'],['../classIRToshibaAC.html#aa001cddc464d6cbcc342e5e4c7af13ff',1,'IRToshibaAC::setMode()'],['../classIRTrotecESP.html#a5d34e8d1e1be765e51cbfb6874482997',1,'IRTrotecESP::setMode()'],['../classIRVestelAc.html#a470e14ab5623386c0fa2b02fd15ea1d8',1,'IRVestelAc::setMode()'],['../classIRWhirlpoolAc.html#ab09869929f5cc1fd0cc5dede93bba1c5',1,'IRWhirlpoolAc::setMode()']]], + ['setmodel_3381',['setModel',['../classIRFujitsuAC.html#a5393698000d8becf33ff332b32b97c73',1,'IRFujitsuAC::setModel()'],['../classIRGreeAC.html#a1075a08c30a2de97892e0842cb30e451',1,'IRGreeAC::setModel()'],['../classIRHitachiAc1.html#abb8c2c87e87f9d538f171e842c9d309a',1,'IRHitachiAc1::setModel()'],['../classIRLgAc.html#ae4b8758ecf10bd7e25ed401593692821',1,'IRLgAc::setModel()'],['../classIRPanasonicAc.html#a342531bfea3b05484de84e537bde390c',1,'IRPanasonicAc::setModel()'],['../classIRWhirlpoolAc.html#accfa1660ed792acc3cf48ff60d9570f0',1,'IRWhirlpoolAc::setModel()']]], + ['setmold_3382',['setMold',['../classIRDaikinESP.html#a1616d08c8fd3c628fc45a76c32743ac9',1,'IRDaikinESP::setMold()'],['../classIRDaikin2.html#ad53e046e545f3b6c5418dfbaf58653ca',1,'IRDaikin2::setMold()']]], + ['setnight_3383',['setNight',['../classIRArgoAC.html#a769dd3b538653940e41883848bc1e19c',1,'IRArgoAC::setNight()'],['../classIRMitsubishiHeavy152Ac.html#a6920a1aad327e2f347b09da12f11cf8c',1,'IRMitsubishiHeavy152Ac::setNight()']]], + ['setofftime_3384',['setOffTime',['../classIRDaikin64.html#a46a0b1e2438087ba557494b0b4fce4a5',1,'IRDaikin64']]], + ['setofftimeenabled_3385',['setOffTimeEnabled',['../classIRDaikin64.html#aea59ae39ddd0fc33a6941d0affceae9a',1,'IRDaikin64']]], + ['setofftimer_3386',['setOffTimer',['../classIRCarrierAc64.html#a92b1066e783db1bdffabfdc57699deef',1,'IRCarrierAc64::setOffTimer()'],['../classIRCoronaAc.html#a00f269b6389bf65d1816e80b835aa9b0',1,'IRCoronaAc::setOffTimer()'],['../classIRDaikin128.html#a30ca067676dfde963986e25c84616368',1,'IRDaikin128::setOffTimer()'],['../classIRDelonghiAc.html#a9602c652b10b06c6eeae0e6158c42c68',1,'IRDelonghiAc::setOffTimer()'],['../classIRHaierAC.html#aa16b36aa7ef07628343dbd2dfe5157a2',1,'IRHaierAC::setOffTimer()'],['../classIRHitachiAc1.html#a62e9c7b68e63d1791d79805f2bce99df',1,'IRHitachiAc1::setOffTimer()'],['../classIRPanasonicAc.html#a08e097f40cee6c614ec1a8de716222cf',1,'IRPanasonicAc::setOffTimer()'],['../classIRVestelAc.html#acc61cd785d2f668a86ecefb243d63549',1,'IRVestelAc::setOffTimer()'],['../classIRWhirlpoolAc.html#a69f3555c9b27f3cfd9167ed3239804b8',1,'IRWhirlpoolAc::setOffTimer()']]], + ['setofftimeractive_3387',['setOffTimerActive',['../classIRVestelAc.html#a8a023f5594b446f0c20f66c4ee584d8e',1,'IRVestelAc']]], + ['setofftimerenabled_3388',['setOffTimerEnabled',['../classIRDaikin128.html#aac8a178bdaf7de7a183991e710a9a9d8',1,'IRDaikin128::setOffTimerEnabled()'],['../classIRDelonghiAc.html#a5cf81c9864f3c3728d4dd65e4d9c49c8',1,'IRDelonghiAc::setOffTimerEnabled()']]], + ['setontime_3389',['setOnTime',['../classIRDaikin64.html#aaada482820a90492a933f368fafaebb7',1,'IRDaikin64']]], + ['setontimeenabled_3390',['setOnTimeEnabled',['../classIRDaikin64.html#a8e7a7c1f775f8ddf9d48a96915751c7a',1,'IRDaikin64']]], + ['setontimer_3391',['setOnTimer',['../classIRCarrierAc64.html#a9049a8d91200b878cc2a1b9b80a280ea',1,'IRCarrierAc64::setOnTimer()'],['../classIRCoronaAc.html#aae4142f45cc9c2b3e392b72cb404a2d8',1,'IRCoronaAc::setOnTimer()'],['../classIRDaikin128.html#a21773493eafae741b5716ac569eaf0a8',1,'IRDaikin128::setOnTimer()'],['../classIRDelonghiAc.html#a9a478f463a632893be7c4f5223c188ad',1,'IRDelonghiAc::setOnTimer()'],['../classIRHaierAC.html#aa5e95aa05749f6d35dd31b021fea2f5b',1,'IRHaierAC::setOnTimer()'],['../classIRHitachiAc1.html#a51ed6155f228628942ba08ea2ff5c547',1,'IRHitachiAc1::setOnTimer()'],['../classIRPanasonicAc.html#a51fdaa11e4e3f77189a94007a5acbec2',1,'IRPanasonicAc::setOnTimer()'],['../classIRVestelAc.html#af19bb7704326eb5688f2a2fa08e10ee2',1,'IRVestelAc::setOnTimer()'],['../classIRWhirlpoolAc.html#a1cb0e346e6f40b65b98a768df7fdace8',1,'IRWhirlpoolAc::setOnTimer()']]], + ['setontimeractive_3392',['setOnTimerActive',['../classIRVestelAc.html#a16ef4ecb7c76bef89b6e0ca36746d606',1,'IRVestelAc']]], + ['setontimerenabled_3393',['setOnTimerEnabled',['../classIRDaikin128.html#a07f693fac3de101c91c190e5e70edb57',1,'IRDaikin128::setOnTimerEnabled()'],['../classIRDelonghiAc.html#af6b956c273284e287093260039003362',1,'IRDelonghiAc::setOnTimerEnabled()']]], + ['setoutsidequiet_3394',['setOutsideQuiet',['../classIRFujitsuAC.html#a9a0533cba18739e52014307bf4b1ad07',1,'IRFujitsuAC']]], + ['setpower_3395',['setPower',['../classIRAmcorAc.html#a2ccfb2c2f0feb8a8cea9e10e30035988',1,'IRAmcorAc::setPower()'],['../classIRArgoAC.html#a991f73d84952c1d8ac86c579d1b01785',1,'IRArgoAC::setPower()'],['../classIRCarrierAc64.html#a8acf59cbf3b02381b5188324030b7727',1,'IRCarrierAc64::setPower()'],['../classIRCoolixAC.html#a41dc75b29e7a05eff5f16161cb9b3eeb',1,'IRCoolixAC::setPower()'],['../classIRCoronaAc.html#adc636402b51e0c78c4797aea5f80915d',1,'IRCoronaAc::setPower()'],['../classIRDaikinESP.html#aa0fb65d01bb203d17d923504ddd60984',1,'IRDaikinESP::setPower()'],['../classIRDaikin2.html#a3adfe1a80a702b7098ccd0e18225396e',1,'IRDaikin2::setPower()'],['../classIRDaikin216.html#a130a98bb2422a228977dea8a4e068ace',1,'IRDaikin216::setPower()'],['../classIRDaikin160.html#af1a800ef7494c49a868d01039f5c37e4',1,'IRDaikin160::setPower()'],['../classIRDaikin176.html#a58c755ba53d1f14a51b0c64ff4ef0669',1,'IRDaikin176::setPower()'],['../classIRDaikin152.html#a887f7340b9c3e7933f5d06bc5f59ee91',1,'IRDaikin152::setPower()'],['../classIRDelonghiAc.html#aa1ebbf63aa2331b87b95df9c5bdb41dc',1,'IRDelonghiAc::setPower()'],['../classIRElectraAc.html#abd04ffe9a77a97d4fafbcecd3a7949a4',1,'IRElectraAc::setPower()'],['../classIRFujitsuAC.html#a8d8211f20c8ec299e1fcb588a0846ac2',1,'IRFujitsuAC::setPower()'],['../classIRGoodweatherAc.html#ac49e30082777b10fe9edf6ec7bd76ea5',1,'IRGoodweatherAc::setPower()'],['../classIRGreeAC.html#a16b8c6af038752cd2b416cdcf9e2fb51',1,'IRGreeAC::setPower()'],['../classIRHaierACYRW02.html#a32e4a52cf31b43ad96ff3d8f0f390620',1,'IRHaierACYRW02::setPower()'],['../classIRHitachiAc.html#ad78a7176ded93735a296eefbf75cbc06',1,'IRHitachiAc::setPower()'],['../classIRHitachiAc1.html#a4dd034793018ea58d0cc32e7a47e8f35',1,'IRHitachiAc1::setPower()'],['../classIRHitachiAc424.html#a7b0b2e2c631d1bce2dd4677bb71e79b4',1,'IRHitachiAc424::setPower()'],['../classIRKelvinatorAC.html#a517a0193a9236a28a20d1760d7401efd',1,'IRKelvinatorAC::setPower()'],['../classIRLgAc.html#a175e6482fd1565d43906c527f911b59e',1,'IRLgAc::setPower()'],['../classIRMideaAC.html#ab8341f8d3d553d8b0ed9270cc15fc8ec',1,'IRMideaAC::setPower()'],['../classIRMitsubishiAC.html#a13f26de3c35b01470176b6fd9efda566',1,'IRMitsubishiAC::setPower()'],['../classIRMitsubishi136.html#a4bf52b3784faaca95ff97a09b8be322a',1,'IRMitsubishi136::setPower()'],['../classIRMitsubishi112.html#a0545da32a5048bc9d857ffb05767d3a6',1,'IRMitsubishi112::setPower()'],['../classIRMitsubishiHeavy152Ac.html#a08202752226ff3295eb8ccd637b0158b',1,'IRMitsubishiHeavy152Ac::setPower()'],['../classIRMitsubishiHeavy88Ac.html#ac2ee9dd82e84a3735e8a0c69e64cb02e',1,'IRMitsubishiHeavy88Ac::setPower()'],['../classIRNeoclimaAc.html#ac19bea3b79cdfc868bd137b0a70c0718',1,'IRNeoclimaAc::setPower()'],['../classIRPanasonicAc.html#ad60bf8a88d041f8e8ab3d728831ee8f3',1,'IRPanasonicAc::setPower()'],['../classIRSamsungAc.html#a4af21fa0dcbf5595386f67db676a443c',1,'IRSamsungAc::setPower()'],['../classIRSharpAc.html#a6b57a66878f125f86d2aed8bd7545000',1,'IRSharpAc::setPower()'],['../classIRTcl112Ac.html#ad2367d2481f94f14b9c4f7b378711b7e',1,'IRTcl112Ac::setPower()'],['../classIRTecoAc.html#a989e48a889b36ec36386a532c81872d9',1,'IRTecoAc::setPower()'],['../classIRToshibaAC.html#a100f01c014582e162f9fd287beb91dff',1,'IRToshibaAC::setPower()'],['../classIRTrotecESP.html#a0f3f5f5db367cb5a9adb936fada94fd5',1,'IRTrotecESP::setPower()'],['../classIRVestelAc.html#a01e06ff3916d4a14f9ca49f22918a47b',1,'IRVestelAc::setPower()']]], + ['setpowerbutton_3396',['setPowerButton',['../classIRCoronaAc.html#a518471d42a62863953c97334cad348be',1,'IRCoronaAc']]], + ['setpowerful_3397',['setPowerful',['../classIRDaikinESP.html#a4c0da54ee1639a3bf813cb3f3afee064',1,'IRDaikinESP::setPowerful()'],['../classIRDaikin2.html#a6538104cdcf1b55e480aaddd51116d9a',1,'IRDaikin2::setPowerful()'],['../classIRDaikin216.html#a5cb6e958f3b9789828738defe4d12c7b',1,'IRDaikin216::setPowerful()'],['../classIRDaikin128.html#aeb3aa5013b1746ed714146ca7f233119',1,'IRDaikin128::setPowerful()'],['../classIRDaikin152.html#a6477111b5662146e937c10cf02423e10',1,'IRDaikin152::setPowerful()'],['../classIRPanasonicAc.html#a6357688bc9cca92ab222343ee045f4f4',1,'IRPanasonicAc::setPowerful()'],['../classIRSamsungAc.html#ab657b79740e0f84c09611ea3b10d06f0',1,'IRSamsungAc::setPowerful()']]], + ['setpowerspecial_3398',['setPowerSpecial',['../classIRSharpAc.html#af7dd64c6d82a8502d2ee176f7b0f5abb',1,'IRSharpAc']]], + ['setpowertoggle_3399',['setPowerToggle',['../classIRDaikin128.html#a5d7edaa44f0c9ca55ef1040dd42e42e3',1,'IRDaikin128::setPowerToggle()'],['../classIRDaikin64.html#ac7f673619842d217d4eda893da2f35fd',1,'IRDaikin64::setPowerToggle()'],['../classIRHitachiAc1.html#ae30430edd92ec4b848c8a105a78e8068',1,'IRHitachiAc1::setPowerToggle()'],['../classIRWhirlpoolAc.html#a61bec25edce5bc244acb41f79df561e7',1,'IRWhirlpoolAc::setPowerToggle()']]], + ['setpurify_3400',['setPurify',['../classIRDaikin2.html#accd4430e998a8c9be80b5a708be9337e',1,'IRDaikin2']]], + ['setquiet_3401',['setQuiet',['../classIRDaikinESP.html#a4927eb8b2db2540efa90b37f4c3cc733',1,'IRDaikinESP::setQuiet()'],['../classIRDaikin2.html#a61ca7e72f850d0f9600fa9d8a336a8ef',1,'IRDaikin2::setQuiet()'],['../classIRDaikin216.html#a062528f54412cd3d2339c7bf82305ebb',1,'IRDaikin216::setQuiet()'],['../classIRDaikin128.html#a89c49332006831debbabbfcb5ec30249',1,'IRDaikin128::setQuiet()'],['../classIRDaikin152.html#a3aadf5f0ae11c5c6c53f351dd6b9c1a4',1,'IRDaikin152::setQuiet()'],['../classIRDaikin64.html#a7e3fb8debcefb76e76dda5612e28f377',1,'IRDaikin64::setQuiet()'],['../classIRKelvinatorAC.html#a2a3ca238649c55cd4f6f92f48eddf9ac',1,'IRKelvinatorAC::setQuiet()'],['../classIRMitsubishi136.html#a70c8a44f93e90ba025a8909c004c3a7b',1,'IRMitsubishi136::setQuiet()'],['../classIRMitsubishi112.html#a9fbbfb7bb1f6cccfcdcfbc4dcc335169',1,'IRMitsubishi112::setQuiet()'],['../classIRPanasonicAc.html#a51b6ae49cb490f697adeaf7f9f466518',1,'IRPanasonicAc::setQuiet()'],['../classIRSamsungAc.html#a6b3dd7d83c613a06f3499f1c8b26a67b',1,'IRSamsungAc::setQuiet()']]], + ['setraw_3402',['setRaw',['../classIRAmcorAc.html#ac0520033d7a59c817ca8ec08462fe39b',1,'IRAmcorAc::setRaw()'],['../classIRArgoAC.html#a98db56256eb71bf2e8da419007145e2b',1,'IRArgoAC::setRaw()'],['../classIRCarrierAc64.html#af49cf0b53bf8ff946a63bae94be0251d',1,'IRCarrierAc64::setRaw()'],['../classIRCoolixAC.html#aed28d08743c529a5715331255a8d5507',1,'IRCoolixAC::setRaw()'],['../classIRCoronaAc.html#a9ccf78675a3c175209c8d0ef08e2e671',1,'IRCoronaAc::setRaw()'],['../classIRDaikinESP.html#a7c69fc77ead837e5b4f1ececd9f43ca9',1,'IRDaikinESP::setRaw()'],['../classIRDaikin2.html#a132001e73eb5744a3a174c5517c9bbda',1,'IRDaikin2::setRaw()'],['../classIRDaikin216.html#a49f6a2ffc2e76ec4ff020e773bd70160',1,'IRDaikin216::setRaw()'],['../classIRDaikin160.html#a22e8a1600f612dd4326b2f9722d3a269',1,'IRDaikin160::setRaw()'],['../classIRDaikin176.html#a51e5f74b532eca958c09998727064e8d',1,'IRDaikin176::setRaw()'],['../classIRDaikin128.html#a25db29e01def45e8850ac9da68aa7ea7',1,'IRDaikin128::setRaw()'],['../classIRDaikin152.html#aab10e030ebe66e44607e9f35af1eb4cb',1,'IRDaikin152::setRaw()'],['../classIRDaikin64.html#a5f081026aca2bccc6fdeef8199e80779',1,'IRDaikin64::setRaw()'],['../classIRDelonghiAc.html#a219bafa7839f10acca33526cf585152a',1,'IRDelonghiAc::setRaw()'],['../classIRElectraAc.html#ae57c51cd3f5d1ebfb2fe7b926d149dd6',1,'IRElectraAc::setRaw()'],['../classIRFujitsuAC.html#a9b89d756948affa7029eeeed51916cbb',1,'IRFujitsuAC::setRaw()'],['../classIRGoodweatherAc.html#a2eae4bbdb14fea9e3004d656f852df59',1,'IRGoodweatherAc::setRaw()'],['../classIRGreeAC.html#a588f526f2f5500c7c2933ca91ccaf865',1,'IRGreeAC::setRaw()'],['../classIRHaierAC.html#a152961e20b5a5bed2ea03cbc65d65ce9',1,'IRHaierAC::setRaw()'],['../classIRHaierACYRW02.html#a389e711e128533c409731d2c87868c85',1,'IRHaierACYRW02::setRaw()'],['../classIRHitachiAc.html#a3b67215c162ef508c68c49b621c5199b',1,'IRHitachiAc::setRaw()'],['../classIRHitachiAc1.html#ae2d40bc477e30ee574f5c5e2ba4e09c2',1,'IRHitachiAc1::setRaw()'],['../classIRHitachiAc424.html#adc24b8b984ff20cebdf81f65843bb283',1,'IRHitachiAc424::setRaw()'],['../classIRHitachiAc3.html#acff4faf79a30df7b7e7c183dec4153a7',1,'IRHitachiAc3::setRaw()'],['../classIRHitachiAc344.html#a31c8984cfea8364734da6f32fe9a2337',1,'IRHitachiAc344::setRaw()'],['../classIRKelvinatorAC.html#a4a32bbf1a7ee8a089ea1e4e7c750433b',1,'IRKelvinatorAC::setRaw()'],['../classIRLgAc.html#a0da8ea4946826736f526386dc4d115cc',1,'IRLgAc::setRaw()'],['../classIRMideaAC.html#ab24da22531f5b2823551501642ec1b94',1,'IRMideaAC::setRaw()'],['../classIRMitsubishiAC.html#ac7bb79f91d5a9296c2b2b74aae1bfb53',1,'IRMitsubishiAC::setRaw()'],['../classIRMitsubishi136.html#abf0487a6fb163bf896e09b2cae6ee939',1,'IRMitsubishi136::setRaw()'],['../classIRMitsubishi112.html#a5c82f92d4a1ba1477ae7738ed5ade368',1,'IRMitsubishi112::setRaw()'],['../classIRMitsubishiHeavy152Ac.html#a8d42a2d87bf889ab4b233ea0c239f4c2',1,'IRMitsubishiHeavy152Ac::setRaw()'],['../classIRMitsubishiHeavy88Ac.html#abf01e448da9ec6e3b4512f58c3020299',1,'IRMitsubishiHeavy88Ac::setRaw()'],['../classIRNeoclimaAc.html#a607ea7df35572578ef86da7f505ab407',1,'IRNeoclimaAc::setRaw()'],['../classIRPanasonicAc.html#a63308883e8447aa5cdf7d29107be220f',1,'IRPanasonicAc::setRaw()'],['../classIRSamsungAc.html#a95377e8c73b51e73e78b51a2b2fa16d4',1,'IRSamsungAc::setRaw()'],['../classIRSharpAc.html#a89b18c4ee29afa56ebed5fa32e578df7',1,'IRSharpAc::setRaw()'],['../classIRTcl112Ac.html#a5b0994f37df6846137b564eeb322f21b',1,'IRTcl112Ac::setRaw()'],['../classIRTecoAc.html#a1ef3423214f55a2e2695cc1180f94bcc',1,'IRTecoAc::setRaw()'],['../classIRToshibaAC.html#ae74ff9241303eb4c7f3593f73e781c73',1,'IRToshibaAC::setRaw()'],['../classIRTrotecESP.html#a4ffe5ee2559828a61af710bb7d892b6c',1,'IRTrotecESP::setRaw()'],['../classIRVestelAc.html#a617bf1f4b5596d5ad005237e8445c12e',1,'IRVestelAc::setRaw(const uint8_t *newState)'],['../classIRVestelAc.html#a5cc86216d33f228c0648d6c66526b0eb',1,'IRVestelAc::setRaw(const uint64_t newState)'],['../classIRWhirlpoolAc.html#afa9c66ea36c970f80c88a0489448ab5b',1,'IRWhirlpoolAc::setRaw()']]], + ['setroomtemp_3403',['setRoomTemp',['../classIRArgoAC.html#aec5a2edc6f414aab201a18defaa78c5b',1,'IRArgoAC']]], + ['setsave_3404',['setSave',['../classIRTecoAc.html#a0f7d203d44d4040be3a4b28fcd5dd34c',1,'IRTecoAc']]], + ['setsensor_3405',['setSensor',['../classIRDaikinESP.html#ae1c95533934fffb29eed3e9a27e8f636',1,'IRDaikinESP::setSensor()'],['../classIRDaikin152.html#af418dbf2bb79dab0193801167dfb5b78',1,'IRDaikin152::setSensor()']]], + ['setsensortemp_3406',['setSensorTemp',['../classIRCoolixAC.html#a05e660b2b61b9a312e29688289f4bf3e',1,'IRCoolixAC']]], + ['setsensortempraw_3407',['setSensorTempRaw',['../classIRCoolixAC.html#a425c3f5fb26330266156c133fb9104eb',1,'IRCoolixAC']]], + ['setsilent_3408',['setSilent',['../classIRMitsubishiHeavy152Ac.html#ab398b9ea2965f059903137ab088791c0',1,'IRMitsubishiHeavy152Ac']]], + ['setsleep_3409',['setSleep',['../classIRCarrierAc64.html#aa729dbef39afeeed8e83f26b927d3b21',1,'IRCarrierAc64::setSleep()'],['../classIRCoolixAC.html#a4ee44167eca3fc88115fef3e845a3768',1,'IRCoolixAC::setSleep()'],['../classIRDaikin128.html#ac43854ae557ec5582f2bfd9150fd57f2',1,'IRDaikin128::setSleep()'],['../classIRDaikin64.html#a7faf8e018179fed2b091a78d0d69a9b8',1,'IRDaikin64::setSleep()'],['../classIRDelonghiAc.html#aa74806e520b2b01a5b0c87ee32ce427e',1,'IRDelonghiAc::setSleep()'],['../classIRGoodweatherAc.html#a30987629a159c5112649f0973895c9c1',1,'IRGoodweatherAc::setSleep()'],['../classIRGreeAC.html#ac9c11817d15bc5c82732a901cd95e07c',1,'IRGreeAC::setSleep()'],['../classIRHaierAC.html#acb72b89fa53b565f9d32db4d8960f988',1,'IRHaierAC::setSleep()'],['../classIRHaierACYRW02.html#ad63834eb1a91ed974af988c385570457',1,'IRHaierACYRW02::setSleep()'],['../classIRHitachiAc1.html#a2ddb6a5d446b379884828e81df0806ee',1,'IRHitachiAc1::setSleep()'],['../classIRMideaAC.html#a1e008ff673450060bf39a65f1cb926e6',1,'IRMideaAC::setSleep()'],['../classIRNeoclimaAc.html#ad01a62fb369c6894333adb2fe0f52b79',1,'IRNeoclimaAc::setSleep()'],['../classIRTecoAc.html#a1e989a4fbd21c507ba13014b1e336ce2',1,'IRTecoAc::setSleep()'],['../classIRTrotecESP.html#a41c558c6937e61e77269139f96135420',1,'IRTrotecESP::setSleep()'],['../classIRVestelAc.html#a4b93d5585b7fb9d509e7fcf84e2b4abc',1,'IRVestelAc::setSleep()'],['../classIRWhirlpoolAc.html#a6eaa24abc9eac64d9cbe79205a239474',1,'IRWhirlpoolAc::setSleep()']]], + ['setspecial_3410',['setSpecial',['../classIRSharpAc.html#ad7d2eca8b863569a1b17fdca4930d84f',1,'IRSharpAc']]], + ['setspeed_3411',['setSpeed',['../classIRTrotecESP.html#a268146141ce0358c2353c0ff59cfbad3',1,'IRTrotecESP']]], + ['setstartclock_3412',['setStartClock',['../classIRMitsubishiAC.html#a22d8c0dfd8098cb274d915476ed4caae',1,'IRMitsubishiAC']]], + ['setstopclock_3413',['setStopClock',['../classIRMitsubishiAC.html#a228dafbf1ea3e9c3487506a5ca2ea274',1,'IRMitsubishiAC']]], + ['setsuper_3414',['setSuper',['../classIRWhirlpoolAc.html#a19a14674b0bae79d3aee81b8d48aacc7',1,'IRWhirlpoolAc']]], + ['setswing_3415',['setSwing',['../classIRCoolixAC.html#a57e3641e20f072df238b305045e74246',1,'IRCoolixAC::setSwing()'],['../classIRFujitsuAC.html#a60ab8f21b5561e94a322b72a606468b9',1,'IRFujitsuAC::setSwing()'],['../classIRGoodweatherAc.html#a4d11a6885a5e7851e7c941b559159c35',1,'IRGoodweatherAc::setSwing()'],['../classIRHaierAC.html#a28c8bf6e0f45e074bf5eb13c25805627',1,'IRHaierAC::setSwing()'],['../classIRHaierACYRW02.html#ab9152dd09dec2db522dd96778f3b1556',1,'IRHaierACYRW02::setSwing()'],['../classIRSamsungAc.html#aaa7aaca1134e1565f527fcaa96a2fa6e',1,'IRSamsungAc::setSwing()'],['../classIRTecoAc.html#aaaeb10176c0b73e72fdb63b53fdcd5d0',1,'IRTecoAc::setSwing()'],['../classIRVestelAc.html#a6c98427df6e5e8081a6dcbfcd436ff0d',1,'IRVestelAc::setSwing()'],['../classIRWhirlpoolAc.html#a6fec80710ba87599840e576f37e0c944',1,'IRWhirlpoolAc::setSwing()']]], + ['setswingh_3416',['setSwingH',['../classIRElectraAc.html#afcd40681003d57b4f1b652175fc276a8',1,'IRElectraAc::setSwingH()'],['../classIRHitachiAc1.html#af6cc42d52dfed89e23d3d180e7b69af9',1,'IRHitachiAc1::setSwingH()'],['../classIRHitachiAc344.html#a5651cb90ba9b87ef841f8987bad267d4',1,'IRHitachiAc344::setSwingH()'],['../classIRMitsubishi112.html#a99f97b04ac22a7942ea371f470faaf49',1,'IRMitsubishi112::setSwingH()'],['../classIRNeoclimaAc.html#a1aeebc60d7bbd0fb801ad88f639cb6a0',1,'IRNeoclimaAc::setSwingH()']]], + ['setswinghorizontal_3417',['setSwingHorizontal',['../classIRDaikinESP.html#a5a7ec7b00811138879c636b03ae58606',1,'IRDaikinESP::setSwingHorizontal()'],['../classIRDaikin2.html#a75b6d6fb5bab0a9c951ad35e3e1d07c5',1,'IRDaikin2::setSwingHorizontal()'],['../classIRDaikin216.html#af8a1525cbe8d813c419d17ee6776a7d9',1,'IRDaikin216::setSwingHorizontal()'],['../classIRDaikin176.html#a9e63cf22410ffad45f6b308674079ee8',1,'IRDaikin176::setSwingHorizontal()'],['../classIRHitachiAc.html#ae70600f4a6f9fd7579221b11cd73062f',1,'IRHitachiAc::setSwingHorizontal()'],['../classIRKelvinatorAC.html#a2f1731f71bc74fb7ad6fec1210ecb1c7',1,'IRKelvinatorAC::setSwingHorizontal()'],['../classIRMitsubishiHeavy152Ac.html#a8713144e057424809292494a663dcd22',1,'IRMitsubishiHeavy152Ac::setSwingHorizontal()'],['../classIRMitsubishiHeavy88Ac.html#aaceffdd4e631fb2d4c404de0c8ff8cdb',1,'IRMitsubishiHeavy88Ac::setSwingHorizontal()'],['../classIRPanasonicAc.html#a32f3f07813165a39359887485dd87254',1,'IRPanasonicAc::setSwingHorizontal()'],['../classIRTcl112Ac.html#aedc63c59a924d64048bc034a752ce7ed',1,'IRTcl112Ac::setSwingHorizontal()']]], + ['setswingtoggle_3418',['setSwingToggle',['../classIRHitachiAc1.html#a24ec128b6bb27cfc4be4dda9ece003d6',1,'IRHitachiAc1::setSwingToggle()'],['../classIRSharpAc.html#a0d397009ecf213111207fcebb12b95fb',1,'IRSharpAc::setSwingToggle()']]], + ['setswingv_3419',['setSwingV',['../classIRCarrierAc64.html#a61a3f9f29cabc0634a9a74fc2227d8c5',1,'IRCarrierAc64::setSwingV()'],['../classIRDaikin152.html#ad151bb85529d46f7e3e3e65dbf446ff0',1,'IRDaikin152::setSwingV()'],['../classIRElectraAc.html#ae5b33942670e0033cbb9b9c7a1524e93',1,'IRElectraAc::setSwingV()'],['../classIRHitachiAc1.html#a1bcc61a9a33a3ddec41d44d52e7df0d3',1,'IRHitachiAc1::setSwingV()'],['../classIRHitachiAc344.html#a3982f110de8ff9881cf4070902294285',1,'IRHitachiAc344::setSwingV()'],['../classIRMitsubishi136.html#a0d54bc6dd55da18b05f723a1b61e575e',1,'IRMitsubishi136::setSwingV()'],['../classIRMitsubishi112.html#ae33b469f1b67616f101f4a3df874fb78',1,'IRMitsubishi112::setSwingV()'],['../classIRNeoclimaAc.html#aa6e5f6f092f52c5c289642c9576c8bc0',1,'IRNeoclimaAc::setSwingV()']]], + ['setswingvertical_3420',['setSwingVertical',['../classIRDaikinESP.html#a9200ef5751df5d488d7e08b138ec6356',1,'IRDaikinESP::setSwingVertical()'],['../classIRDaikin2.html#a35e72dc8e7967ee8ca8e84a6344468f3',1,'IRDaikin2::setSwingVertical()'],['../classIRDaikin216.html#a851484d5a37ceb1b0fc32e2e4bc2bcbb',1,'IRDaikin216::setSwingVertical()'],['../classIRDaikin160.html#a1683a255393f233d3e5b46d186d62881',1,'IRDaikin160::setSwingVertical()'],['../classIRDaikin128.html#a961aceb41145001003a50c5988f04c4d',1,'IRDaikin128::setSwingVertical()'],['../classIRDaikin64.html#afca186067111fa7181916a218c2800ec',1,'IRDaikin64::setSwingVertical()'],['../classIRGreeAC.html#a1b571dea8a5bf553554e45074f3a01c0',1,'IRGreeAC::setSwingVertical()'],['../classIRHitachiAc.html#a7e3ee78e4835fe402095b544c1e52f9f',1,'IRHitachiAc::setSwingVertical()'],['../classIRKelvinatorAC.html#a7334fbf8f2a67b33562ecea6b6e66f0e',1,'IRKelvinatorAC::setSwingVertical()'],['../classIRMitsubishiHeavy152Ac.html#aea3ac937feff058feef321bfe7357145',1,'IRMitsubishiHeavy152Ac::setSwingVertical()'],['../classIRMitsubishiHeavy88Ac.html#a9406e1890483703afb7b383e1363f8ec',1,'IRMitsubishiHeavy88Ac::setSwingVertical()'],['../classIRPanasonicAc.html#a48f31b1f85c92fac22f85a1aa8074c6e',1,'IRPanasonicAc::setSwingVertical()'],['../classIRTcl112Ac.html#a53f702dcc66de81f6e7e03d538a6946d',1,'IRTcl112Ac::setSwingVertical()']]], + ['setswingvtoggle_3421',['setSwingVToggle',['../classIRCoronaAc.html#a7cb31da86353ec637239cb747890bd7b',1,'IRCoronaAc::setSwingVToggle()'],['../classIRHitachiAc424.html#a220fd85bd213dd13ee9c609d4d7d20c1',1,'IRHitachiAc424::setSwingVToggle()'],['../classIRMideaAC.html#a7fce182bff4f5bc2c6679b20f344837b',1,'IRMideaAC::setSwingVToggle()']]], + ['settemp_3422',['setTemp',['../classIRAmcorAc.html#af4b2c476b76534687f14e9be963e9522',1,'IRAmcorAc::setTemp()'],['../classIRArgoAC.html#abad424a3cf1894715baa03780fa9b53b',1,'IRArgoAC::setTemp()'],['../classIRCarrierAc64.html#a79e193514ac6d07be537a78887426311',1,'IRCarrierAc64::setTemp()'],['../classIRCoolixAC.html#a1d4b4fb810b9f3835ee585b2aa66088f',1,'IRCoolixAC::setTemp()'],['../classIRCoronaAc.html#a9b1d5223cbb6ae6ba07f32871b27d9c6',1,'IRCoronaAc::setTemp()'],['../classIRDaikinESP.html#a631db8830684b745711667aed73a6433',1,'IRDaikinESP::setTemp()'],['../classIRDaikin2.html#a7f752c785fe180d5038e35bb07ff965a',1,'IRDaikin2::setTemp()'],['../classIRDaikin216.html#a8735732d3264eec119127d4353990669',1,'IRDaikin216::setTemp()'],['../classIRDaikin160.html#abedd99ed838478a7ef856537c6fabb82',1,'IRDaikin160::setTemp()'],['../classIRDaikin176.html#acb3b296f4c87a5a37258c666ef886ff3',1,'IRDaikin176::setTemp()'],['../classIRDaikin128.html#aba143a1b80e6de7d1c7b987eeda6b0db',1,'IRDaikin128::setTemp()'],['../classIRDaikin152.html#a97567ade1c0262b3f95f23f171936d8c',1,'IRDaikin152::setTemp()'],['../classIRDaikin64.html#adb1eb657998c05a143365755da0a1e81',1,'IRDaikin64::setTemp()'],['../classIRDelonghiAc.html#a08cc3e32c50277e3f986ed2c3945ce0d',1,'IRDelonghiAc::setTemp()'],['../classIRElectraAc.html#a5f986d9a376b6d5348fcb021d66d235b',1,'IRElectraAc::setTemp()'],['../classIRFujitsuAC.html#ab56c02fc0311ee7f28e780948cbc6a75',1,'IRFujitsuAC::setTemp()'],['../classIRGoodweatherAc.html#a8b1c90f69a3a2e412020d07809d180cc',1,'IRGoodweatherAc::setTemp()'],['../classIRGreeAC.html#a1890c6d134183beb89b791ec565623bb',1,'IRGreeAC::setTemp()'],['../classIRHaierAC.html#a9fb2a375cc1b8692fe4d5dcdd765cc46',1,'IRHaierAC::setTemp()'],['../classIRHaierACYRW02.html#a80170879e7bd391e360d41f18f6fa52b',1,'IRHaierACYRW02::setTemp()'],['../classIRHitachiAc.html#a9f416886ae341cdb6d449572e4d168a9',1,'IRHitachiAc::setTemp()'],['../classIRHitachiAc1.html#a10ba2dcbe447e505cbaa1a9b63f4823c',1,'IRHitachiAc1::setTemp()'],['../classIRHitachiAc424.html#a5cca8f31d07ce87b6e4a0ff0c22b1be8',1,'IRHitachiAc424::setTemp()'],['../classIRKelvinatorAC.html#ab098a376c7393d377abcc6c1f504d372',1,'IRKelvinatorAC::setTemp()'],['../classIRLgAc.html#ad9924a8bc9737ec6007d76ec47b34142',1,'IRLgAc::setTemp()'],['../classIRMideaAC.html#a42f79e73f418d5267eed7ba5b0e266f5',1,'IRMideaAC::setTemp()'],['../classIRMitsubishiAC.html#afd629013630747400e005fab8407d711',1,'IRMitsubishiAC::setTemp()'],['../classIRMitsubishi136.html#ac19c9234a5f65cae50b64d56c4bebb8f',1,'IRMitsubishi136::setTemp()'],['../classIRMitsubishi112.html#a03ba44a6d2f152b7afade423f12c8726',1,'IRMitsubishi112::setTemp()'],['../classIRMitsubishiHeavy152Ac.html#ad4f9ae94b8ab1fff8fc99b8d7818a8fe',1,'IRMitsubishiHeavy152Ac::setTemp()'],['../classIRMitsubishiHeavy88Ac.html#aa4a92e5334aebdca5d2b26b642e9b9e8',1,'IRMitsubishiHeavy88Ac::setTemp()'],['../classIRNeoclimaAc.html#a59e27fa001f9ab674b69eb2c41b6393c',1,'IRNeoclimaAc::setTemp()'],['../classIRPanasonicAc.html#a58376c311177e701333f4915515d49f1',1,'IRPanasonicAc::setTemp()'],['../classIRSamsungAc.html#a94a71e82321343220836aa614b231bd0',1,'IRSamsungAc::setTemp()'],['../classIRSharpAc.html#a151f88799cdab6fda4cfef83b30e5917',1,'IRSharpAc::setTemp()'],['../classIRTcl112Ac.html#a110bae0201b63db0409c352dd8d62786',1,'IRTcl112Ac::setTemp()'],['../classIRTecoAc.html#a405106cb572dac338d79da48fe7a7cb3',1,'IRTecoAc::setTemp()'],['../classIRToshibaAC.html#a923fad1f637e1851a77a063978994604',1,'IRToshibaAC::setTemp()'],['../classIRTrotecESP.html#ad467e7fe9ff61fec4ec10b367c0f9279',1,'IRTrotecESP::setTemp()'],['../classIRVestelAc.html#a8c4eddfba4edfa16e317e12677736756',1,'IRVestelAc::setTemp()'],['../classIRWhirlpoolAc.html#afff1ae75ffa362abb791c97c20023755',1,'IRWhirlpoolAc::setTemp()']]], + ['settempraw_3423',['setTempRaw',['../classIRCoolixAC.html#ae9371280e92daa8e1441523026f1ef0a',1,'IRCoolixAC']]], + ['settempunit_3424',['setTempUnit',['../classIRDelonghiAc.html#a4e3681e49065ba232577ca05157a5ef2',1,'IRDelonghiAc']]], + ['settime_3425',['setTime',['../classIRArgoAC.html#ae285801cde19da82e128098097624852',1,'IRArgoAC::setTime()'],['../classIRHaierAC.html#a81ca00cf5b49308c2609b717d34958ad',1,'IRHaierAC::setTime()'],['../classIRVestelAc.html#afc5dedf83855a8fea8b29494bfb07d64',1,'IRVestelAc::setTime()'],['../classIRWhirlpoolAc.html#a40289737223c14c8a1e723e7a28bad13',1,'IRWhirlpoolAc::setTime()']]], + ['settimer_3426',['setTimer',['../classIRDaikin128.html#a8498de57fc1bdb2f71a678f7877d3125',1,'IRDaikin128::setTimer()'],['../classIRGreeAC.html#a84debd45d2f2ba221f825257e0bc6294',1,'IRGreeAC::setTimer()'],['../classIRMitsubishiAC.html#acb56c91ef0db6ace7782d356af2dcd4d',1,'IRMitsubishiAC::setTimer()'],['../classIRSharpAc.html#a8782543c33e48af0a09e548276eb6413',1,'IRSharpAc::setTimer()'],['../classIRTecoAc.html#a88a84e22d53a204da754c04210fadd04',1,'IRTecoAc::setTimer()'],['../classIRTrotecESP.html#a92bfed0f247b21c77737b720151dbb88',1,'IRTrotecESP::setTimer()'],['../classIRVestelAc.html#a7c66e1ec13c827714eaa2233f50f072b',1,'IRVestelAc::setTimer()']]], + ['settimeractive_3427',['setTimerActive',['../classIRVestelAc.html#a77f78e534b19a8dca776b17aa06739aa',1,'IRVestelAc']]], + ['settimerenabled_3428',['setTimerEnabled',['../classIRGreeAC.html#a1002d6dfe409076fa7ef252589d5043c',1,'IRGreeAC']]], + ['settolerance_3429',['setTolerance',['../classIRrecv.html#aa091c449db70c65fd0221669df7438ea',1,'IRrecv']]], + ['setturbo_3430',['setTurbo',['../classIRCoolixAC.html#a65a04ec9028025155792be5ba0f81927',1,'IRCoolixAC::setTurbo()'],['../classIRDaikin64.html#a734cc23f79a4de4099a4ceb1aff14762',1,'IRDaikin64::setTurbo()'],['../classIRElectraAc.html#adb40e95465788b03e4cb845bd481f7ed',1,'IRElectraAc::setTurbo()'],['../classIRGoodweatherAc.html#a7827fc5a8f85b284c0121727dba34f11',1,'IRGoodweatherAc::setTurbo()'],['../classIRGreeAC.html#ae873023ad81f7dcb12ee5b061e160bea',1,'IRGreeAC::setTurbo()'],['../classIRHaierACYRW02.html#aba5f028ee1ebf7be2d4de5a66237f01b',1,'IRHaierACYRW02::setTurbo()'],['../classIRKelvinatorAC.html#a7d9c44970e85f23c83723f27e96260ee',1,'IRKelvinatorAC::setTurbo()'],['../classIRMitsubishiHeavy152Ac.html#a275e8ae44e2018a848b3e8f0893c8023',1,'IRMitsubishiHeavy152Ac::setTurbo()'],['../classIRMitsubishiHeavy88Ac.html#a39ac892d349180327cce92c6f82bea30',1,'IRMitsubishiHeavy88Ac::setTurbo()'],['../classIRNeoclimaAc.html#aa2a9563d9e3c5c95dfa512c0bb87e16f',1,'IRNeoclimaAc::setTurbo()'],['../classIRSharpAc.html#a8a184ae8eeb07704b9b69849421e3172',1,'IRSharpAc::setTurbo()'],['../classIRTcl112Ac.html#a99e3b3e2f0cc627b6d872d04b35d6230',1,'IRTcl112Ac::setTurbo()'],['../classIRVestelAc.html#afa762d0fa63ecc7444c1c107f8f07cdb',1,'IRVestelAc::setTurbo()']]], + ['setunknownthreshold_3431',['setUnknownThreshold',['../classIRrecv.html#a02693553aad1decd67bdae60402e48bf',1,'IRrecv']]], + ['setusecelsius_3432',['setUseCelsius',['../classIRMideaAC.html#a1eeb72ddd2b9867c2f9c392080b9c1ed',1,'IRMideaAC']]], + ['setusefahrenheit_3433',['setUseFahrenheit',['../classIRGreeAC.html#af559afaa9da5fd27cdb516355da67bd6',1,'IRGreeAC']]], + ['setvane_3434',['setVane',['../classIRMitsubishiAC.html#abb247f1dca5cf23a7b8a16852dcf32f1',1,'IRMitsubishiAC']]], + ['setweeklytimerenable_3435',['setWeeklyTimerEnable',['../classIRDaikinESP.html#a0db67d46b13acfad9b94c7e4691777b8',1,'IRDaikinESP']]], + ['setwidevane_3436',['setWideVane',['../classIRMitsubishiAC.html#a02b2b3d7456e6123c60dca70de346c25',1,'IRMitsubishiAC']]], + ['setwifi_3437',['setWiFi',['../classIRGreeAC.html#afde745ceaa97f9608195b2ba9fce6c5c',1,'IRGreeAC']]], + ['setxfan_3438',['setXFan',['../classIRGreeAC.html#af465c607222fa433f54c2ce56ced2474',1,'IRGreeAC::setXFan()'],['../classIRKelvinatorAC.html#af02da81109109cf1cb44057fd1a40164',1,'IRKelvinatorAC::setXFan()']]], + ['setzonefollow_3439',['setZoneFollow',['../classIRCoolixAC.html#a0c0f39d8e2e79d8259000695263ec3fa',1,'IRCoolixAC']]], + ['sharp_3440',['sharp',['../classIRac.html#a7b6d8b4e554a89f339f896fe4233ed15',1,'IRac::sharp()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadaad63db67a2284cd7e3ffe382b6d6ea82',1,'SHARP(): IRremoteESP8266.h']]], + ['sharp_5fac_3441',['SHARP_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada353a9d71906702ae10aa4f803a04ca68',1,'IRremoteESP8266.h']]], + ['sherwood_3442',['SHERWOOD',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada1412522651b0c8f1a35e1db3807466bb',1,'IRremoteESP8266.h']]], + ['sleep_3443',['sleep',['../structstdAc_1_1state__t.html#a94fa6098d7422292a1c6943973cd106a',1,'stdAc::state_t']]], + ['sleepflag_3444',['sleepFlag',['../classIRCoolixAC.html#a26560e04d1f77830e40e5570845b9e06',1,'IRCoolixAC']]], + ['sony_3445',['SONY',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada72d58193d4d25517202d22b7e57a65c3',1,'IRremoteESP8266.h']]], + ['sony_5f38k_3446',['SONY_38K',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada0027bcfbb78c0c2b951dfff1102a027b',1,'IRremoteESP8266.h']]], + ['space_3447',['space',['../classIRsend.html#a0417b10d4e16718a87f8b2062a7d04a1',1,'IRsend']]], + ['start_3448',['start',['../classIRtimer.html#aaa087b8688ff8150e0fc1ec6d5c4a52a',1,'IRtimer::start()'],['../classTimerMs.html#a15ad2e08a5931397391d48f040722f65',1,'TimerMs::start()']]], + ['state_3449',['state',['../classdecode__results.html#aaeb4b1b2e950bdd181582c385b2f4305',1,'decode_results']]], + ['state_5ft_3450',['state_t',['../structstdAc_1_1state__t.html',1,'stdAc']]], + ['statereset_3451',['stateReset',['../classIRAmcorAc.html#a018ab4ca4d738d848d3388ea1300b83b',1,'IRAmcorAc::stateReset()'],['../classIRArgoAC.html#af34a99bc37c4496c9fd68856aa065a13',1,'IRArgoAC::stateReset()'],['../classIRCarrierAc64.html#abe58c8f97ab4c34fd0cf198b07589694',1,'IRCarrierAc64::stateReset()'],['../classIRCoolixAC.html#a88a44b7ba5ac7d5654de4592bd41c207',1,'IRCoolixAC::stateReset()'],['../classIRCoronaAc.html#a47726d4ff93528bd8a5a6f1b47ba7141',1,'IRCoronaAc::stateReset()'],['../classIRDaikinESP.html#a49f6b90336225f7e94b8aefd066e1993',1,'IRDaikinESP::stateReset()'],['../classIRDaikin2.html#a9b49e90604bf6b1abb93581eecfc6c88',1,'IRDaikin2::stateReset()'],['../classIRDaikin216.html#adbc856e6531b38963db5680d279a4767',1,'IRDaikin216::stateReset()'],['../classIRDaikin160.html#ade56e55c8a0c81f0803dec2cda4625b0',1,'IRDaikin160::stateReset()'],['../classIRDaikin176.html#ab86a1b458a1be5d7fe5fcb7e287ef1d3',1,'IRDaikin176::stateReset()'],['../classIRDaikin128.html#ab604a7594c3b0131c5d977e3fc3b3565',1,'IRDaikin128::stateReset()'],['../classIRDaikin152.html#a278291def7d0e14552e7fbe9a56346bd',1,'IRDaikin152::stateReset()'],['../classIRDaikin64.html#af5a691404b8026cf1da45502f1c019f4',1,'IRDaikin64::stateReset()'],['../classIRDelonghiAc.html#aac444790a16678a1e88f1adef02829ba',1,'IRDelonghiAc::stateReset()'],['../classIRElectraAc.html#ab8035c14158fcf3758f46f6976b814f7',1,'IRElectraAc::stateReset()'],['../classIRFujitsuAC.html#a603a0e1870f406e4e746a7bb4c37fb70',1,'IRFujitsuAC::stateReset()'],['../classIRGoodweatherAc.html#ae7f8873ad58e553dc89307220628bebf',1,'IRGoodweatherAc::stateReset()'],['../classIRGreeAC.html#a61356a0dfb4656ac438c3629c591b165',1,'IRGreeAC::stateReset()'],['../classIRHaierAC.html#a62fbae1d2bac01ac3a2194274aa839d9',1,'IRHaierAC::stateReset()'],['../classIRHaierACYRW02.html#a106e7ffa0d69cdf976087c6e190d03ea',1,'IRHaierACYRW02::stateReset()'],['../classIRHitachiAc.html#a0564c00c60e64e57e20f3c1a4bd3d894',1,'IRHitachiAc::stateReset()'],['../classIRHitachiAc1.html#a9764b329d982d018b15098b3044f9596',1,'IRHitachiAc1::stateReset()'],['../classIRHitachiAc424.html#afd8d5b21086b34cdc07b498157240f8f',1,'IRHitachiAc424::stateReset()'],['../classIRHitachiAc3.html#a7bdcddf9c7f85b7cb43a92198e422549',1,'IRHitachiAc3::stateReset()'],['../classIRHitachiAc344.html#ab0174472d44790a5516b8f4377a89f22',1,'IRHitachiAc344::stateReset()'],['../classIRKelvinatorAC.html#ad6fefe85023c3fc318b0e45924874f9f',1,'IRKelvinatorAC::stateReset()'],['../classIRLgAc.html#a5959000c9f0b2cf64742d6a2f1c4c9b9',1,'IRLgAc::stateReset()'],['../classIRMideaAC.html#acc584e07406e1811acfb26f6cd5383cd',1,'IRMideaAC::stateReset()'],['../classIRMitsubishiAC.html#a8da4be360c8e2fd3a5a40cb4049b5d84',1,'IRMitsubishiAC::stateReset()'],['../classIRMitsubishi136.html#a67556dab7ed42c68a274f4f24ecc35bb',1,'IRMitsubishi136::stateReset()'],['../classIRMitsubishi112.html#a9c601ba34e10d5c63886c2c5b405d9ae',1,'IRMitsubishi112::stateReset()'],['../classIRMitsubishiHeavy152Ac.html#a0b239cacd3a8a96f2e3d7047f26119da',1,'IRMitsubishiHeavy152Ac::stateReset()'],['../classIRMitsubishiHeavy88Ac.html#a1cf118f435c99372c89a140a79c67f1f',1,'IRMitsubishiHeavy88Ac::stateReset()'],['../classIRNeoclimaAc.html#a5ce32a6e6195b246696cb609994f3762',1,'IRNeoclimaAc::stateReset()'],['../classIRPanasonicAc.html#a9a9fbf531f04c486edf913c382351b2b',1,'IRPanasonicAc::stateReset()'],['../classIRSamsungAc.html#a52186401655966b3103d3d73fb77e7f0',1,'IRSamsungAc::stateReset()'],['../classIRSharpAc.html#aa151c704ba4f5690a7cfadaf90c4b60d',1,'IRSharpAc::stateReset()'],['../classIRTcl112Ac.html#a049f475c1af7b62b9f3482dcf9e66d4a',1,'IRTcl112Ac::stateReset()'],['../classIRTecoAc.html#ad53e6f3d3693ee6efb419326a3d4c492',1,'IRTecoAc::stateReset()'],['../classIRToshibaAC.html#a3d3c3df261b4db7a9d831c94cc206e8a',1,'IRToshibaAC::stateReset()'],['../classIRTrotecESP.html#a86c3415d8c1880c325bc22c2c4ca44e0',1,'IRTrotecESP::stateReset()'],['../classIRVestelAc.html#a921100234f5751f8b94d9673a5d217f9',1,'IRVestelAc::stateReset()'],['../classIRWhirlpoolAc.html#a371a6f48a2f4f66e4243dacbbf4471be',1,'IRWhirlpoolAc::stateReset()']]], + ['stdac_3452',['stdAc',['../namespacestdAc.html',1,'']]], + ['stephoriz_3453',['stepHoriz',['../classIRFujitsuAC.html#a53c48bc1f32c849263a3aa86ff06b1d4',1,'IRFujitsuAC']]], + ['stepvert_3454',['stepVert',['../classIRFujitsuAC.html#a942f106c27ce04094b5b615f2e174022',1,'IRFujitsuAC']]], + ['string_3455',['String',['../IRremoteESP8266_8h.html#afbeda3fd1bdc8c37d01bdf9f5c8274ff',1,'IRremoteESP8266.h']]], + ['strtobool_3456',['strToBool',['../classIRac.html#a3dba736fe25bd3a3a47b9ec7dae51728',1,'IRac']]], + ['strtodecodetype_3457',['strToDecodeType',['../IRutils_8cpp.html#ae1614f315c1ebc44eaf1ac62055cc1ff',1,'strToDecodeType(const char *const str): IRutils.cpp'],['../IRutils_8h.html#a10b9312e4ac9c96d895af83db01ed72e',1,'strToDecodeType(const char *str): IRutils.cpp']]], + ['strtofanspeed_3458',['strToFanspeed',['../classIRac.html#a7173b12c155d04dd1db07a055f4ecb03',1,'IRac']]], + ['strtomodel_3459',['strToModel',['../classIRac.html#a7036fbbb918d644a98b5efa16374a256',1,'IRac']]], + ['strtoopmode_3460',['strToOpmode',['../classIRac.html#a251fa76ddacc84d2655bac723b7dea28',1,'IRac']]], + ['strtoswingh_3461',['strToSwingH',['../classIRac.html#a294d6040909519f465945245df56e56d',1,'IRac']]], + ['strtoswingv_3462',['strToSwingV',['../classIRac.html#a538c861d79afabb11fb8becedd3962f8',1,'IRac']]], + ['success_3463',['success',['../structmatch__result__t.html#a13fe18ae6cf89364df443a64295b2f90',1,'match_result_t']]], + ['sumbytes_3464',['sumBytes',['../IRutils_8cpp.html#abfbd3d7cc33d0aac341e6619f3390108',1,'sumBytes(const uint8_t *const start, const uint16_t length, const uint8_t init): IRutils.cpp'],['../IRutils_8h.html#a3f33bdd680bea210b212d4e9925eb8eb',1,'sumBytes(const uint8_t *const start, const uint16_t length, const uint8_t init=0): IRutils.cpp']]], + ['sumnibbles_3465',['sumNibbles',['../namespaceirutils.html#a4752ecc3eafa3ca2e13344a52519b343',1,'irutils::sumNibbles(const uint8_t *const start, const uint16_t length, const uint8_t init)'],['../namespaceirutils.html#aeb5202fa0093ee6b7e07d4290229fbd2',1,'irutils::sumNibbles(const uint64_t data, const uint8_t count, const uint8_t init, const bool nibbleonly)']]], + ['swingflag_3466',['swingFlag',['../classIRCoolixAC.html#a6d61903a90cebef56b931bebbfa5cba3',1,'IRCoolixAC']]], + ['swingh_3467',['swingh',['../structstdAc_1_1state__t.html#a761bb702891ed1fa35906929a4c8a3f8',1,'stdAc::state_t']]], + ['swingh_5ft_3468',['swingh_t',['../namespacestdAc.html#aae50ee315fa9c9ec1a4078da40d6b147',1,'stdAc']]], + ['swinghflag_3469',['swingHFlag',['../classIRCoolixAC.html#a1c5fb27fb58d4d1a1fd8c9931eba58c4',1,'IRCoolixAC']]], + ['swinghtostring_3470',['swinghToString',['../classIRac.html#a21c9d71bbf229fd8369480e50a7c3689',1,'IRac']]], + ['swingv_3471',['swingv',['../structstdAc_1_1state__t.html#a35477d368350d8981ad8b7b09505857e',1,'stdAc::state_t']]], + ['swingv_5ft_3472',['swingv_t',['../namespacestdAc.html#ac07f224c7bb47cac55dd01f24770ef43',1,'stdAc']]], + ['swingvflag_3473',['swingVFlag',['../classIRCoolixAC.html#adf18ad8494466f6301176ce10aa3a075',1,'IRCoolixAC']]], + ['swingvtostring_3474',['swingvToString',['../classIRac.html#a641b59e48183a8f6d9b739ce7210f142',1,'IRac']]], + ['symphony_3475',['SYMPHONY',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada44c4a84d776e02328ef3b169e743e5ec',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_14.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_14.html new file mode 100644 index 000000000..72d12e90e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_14.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_14.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_14.js new file mode 100644 index 000000000..ee5a479d4 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_14.js @@ -0,0 +1,28 @@ +var searchData= +[ + ['tcl112_3476',['tcl112',['../classIRac.html#a3028bd9e83956d57b592bb96638b3f59',1,'IRac']]], + ['tcl112ac_3477',['TCL112AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadac4a6ebe702365620ed65ac6f484afda6',1,'IRremoteESP8266.h']]], + ['teco_3478',['teco',['../classIRac.html#a9e612e04e270dd5710e8a63a64b56064',1,'IRac::teco()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada3a15ee4466478d484508acc3d4d7a050',1,'TECO(): IRremoteESP8266.h']]], + ['tickshigh_3479',['ticksHigh',['../classIRrecv.html#a573dbb20695f2ffc808623df8c36280c',1,'IRrecv']]], + ['tickslow_3480',['ticksLow',['../classIRrecv.html#ac08e50c5eec10c0095157f4bdd4051c8',1,'IRrecv']]], + ['timeout_3481',['timeout',['../structirparams__t.html#a132d6448ad59f03f6b35c4b04a6d1af4',1,'irparams_t']]], + ['timer_3482',['timer',['../structirparams__t.html#a6d4594a4d6bf8a2587095be7adfc018d',1,'irparams_t']]], + ['timerms_3483',['TimerMs',['../classTimerMs.html',1,'TimerMs'],['../classTimerMs.html#a7bf7f8d2fcf76b27b34ea4705810eef5',1,'TimerMs::TimerMs()']]], + ['tocommon_3484',['toCommon',['../classIRAmcorAc.html#aac4ae204cf0c393c18e5de96c4ba44ab',1,'IRAmcorAc::toCommon()'],['../classIRArgoAC.html#a4b1fda530b50c30cb863a3c146f4c81b',1,'IRArgoAC::toCommon()'],['../classIRCarrierAc64.html#a7c4a84d0d9f1e78ba611e118ddb90635',1,'IRCarrierAc64::toCommon()'],['../classIRCoolixAC.html#acadeabae7017e49c944eb22528297b3a',1,'IRCoolixAC::toCommon()'],['../classIRCoronaAc.html#a78dee47464e312d57e660b34c10bb13c',1,'IRCoronaAc::toCommon()'],['../classIRDaikinESP.html#a6bc97a753db054ce2ed59809845e23f1',1,'IRDaikinESP::toCommon()'],['../classIRDaikin2.html#a090407aff4ef81714e31ef28ac41d8e2',1,'IRDaikin2::toCommon()'],['../classIRDaikin216.html#ac477511261d7f135ee4f909eb5512f9a',1,'IRDaikin216::toCommon()'],['../classIRDaikin160.html#a0641f2e7f86412a36dcbe98b9049d322',1,'IRDaikin160::toCommon()'],['../classIRDaikin176.html#ac99fcb66d866196b51ad11384154f8ae',1,'IRDaikin176::toCommon()'],['../classIRDaikin128.html#a54de8ff37216f7a3a2cc744d97c2e1c6',1,'IRDaikin128::toCommon()'],['../classIRDaikin152.html#a96fee4c7cee70cc9249c556b277b2f74',1,'IRDaikin152::toCommon()'],['../classIRDaikin64.html#ad57748fa03e79a277508aa42b08c8f83',1,'IRDaikin64::toCommon()'],['../classIRDelonghiAc.html#a2cdcd20dffb763a5f9ff7bd264c1d3e8',1,'IRDelonghiAc::toCommon()'],['../classIRElectraAc.html#ad10aba2fa72f4b839538fc5a99c696ad',1,'IRElectraAc::toCommon()'],['../classIRFujitsuAC.html#adfd6ff9d4449eae7a5268b26058a483f',1,'IRFujitsuAC::toCommon()'],['../classIRGoodweatherAc.html#ae616e9fc03406ec88b5c5ddcde5f2f2c',1,'IRGoodweatherAc::toCommon()'],['../classIRGreeAC.html#ac28c640aa4b5dd0dbbca42b056f877f7',1,'IRGreeAC::toCommon()'],['../classIRHaierAC.html#a1e74862d6ab7e65108a7b1a3b7af7e91',1,'IRHaierAC::toCommon()'],['../classIRHaierACYRW02.html#aff86d2e3e1d357f0eecf6322964e7c16',1,'IRHaierACYRW02::toCommon()'],['../classIRHitachiAc.html#aa1ec8cc4b5025272c72dc69c6d6486a3',1,'IRHitachiAc::toCommon()'],['../classIRHitachiAc1.html#aef93034682210a6c564fbea4461ab47e',1,'IRHitachiAc1::toCommon()'],['../classIRHitachiAc424.html#a36711772ebdf385e0a95564f8a552634',1,'IRHitachiAc424::toCommon()'],['../classIRHitachiAc344.html#a146203ad02a3df4037b97c0416ba828e',1,'IRHitachiAc344::toCommon()'],['../classIRKelvinatorAC.html#a1e900aa29dad75f74de2bb797d475b20',1,'IRKelvinatorAC::toCommon()'],['../classIRLgAc.html#a75c52ef31270f25651521ae2be558faa',1,'IRLgAc::toCommon()'],['../classIRMideaAC.html#a62086b58f71908b75e28a61bd4f6bf15',1,'IRMideaAC::toCommon()'],['../classIRMitsubishiAC.html#a42338266a34940e657e5226c81f2fd06',1,'IRMitsubishiAC::toCommon()'],['../classIRMitsubishi136.html#a938360f488ec923e138744b6f80477bb',1,'IRMitsubishi136::toCommon()'],['../classIRMitsubishi112.html#aadde5055371b418fd733a2e93d12b478',1,'IRMitsubishi112::toCommon()'],['../classIRMitsubishiHeavy152Ac.html#af9cbfb13cd48d5d503756c50df8fc7b7',1,'IRMitsubishiHeavy152Ac::toCommon()'],['../classIRMitsubishiHeavy88Ac.html#a3f80427169359dc72367e6ee4e52c42f',1,'IRMitsubishiHeavy88Ac::toCommon()'],['../classIRNeoclimaAc.html#a455397211c7cb8074f6b7358dc6a5b9e',1,'IRNeoclimaAc::toCommon()'],['../classIRPanasonicAc.html#af2218f117db06424ced00ba6c0cc3234',1,'IRPanasonicAc::toCommon()'],['../classIRSamsungAc.html#a01e9279d541f64ebfa433c35a3651796',1,'IRSamsungAc::toCommon()'],['../classIRSharpAc.html#aaade155b2128ba11c2e91bba676c72d9',1,'IRSharpAc::toCommon()'],['../classIRTcl112Ac.html#af5813975bfe55a76d202f8c7f48df82d',1,'IRTcl112Ac::toCommon()'],['../classIRTecoAc.html#af3953289854dabf105c6612f14ef5da0',1,'IRTecoAc::toCommon()'],['../classIRToshibaAC.html#acda90e0171043c3a673ffac52ef9b4b5',1,'IRToshibaAC::toCommon()'],['../classIRTrotecESP.html#ac224a0a18a64ce9802c3f25fafa20a04',1,'IRTrotecESP::toCommon()'],['../classIRVestelAc.html#adb7ab58e91f13b999b62559fc7add91a',1,'IRVestelAc::toCommon()'],['../classIRWhirlpoolAc.html#a961da338e344fd975934f9f69d97f5b5',1,'IRWhirlpoolAc::toCommon()']]], + ['tocommonfanspeed_3485',['toCommonFanSpeed',['../classIRAmcorAc.html#a951aa81d98c66138f61069431e13f35a',1,'IRAmcorAc::toCommonFanSpeed()'],['../classIRArgoAC.html#a334afe3ce6536089bc2832985067f029',1,'IRArgoAC::toCommonFanSpeed()'],['../classIRCarrierAc64.html#a5a9149acc82fcc22a5be8dcbe791ab77',1,'IRCarrierAc64::toCommonFanSpeed()'],['../classIRCoolixAC.html#a6a0e7219c667eb06897b47a7c36f5fbc',1,'IRCoolixAC::toCommonFanSpeed()'],['../classIRCoronaAc.html#a6d5d0015f01acc97badff7edda964485',1,'IRCoronaAc::toCommonFanSpeed()'],['../classIRDaikinESP.html#a6855a423f10a2230953646d478400574',1,'IRDaikinESP::toCommonFanSpeed()'],['../classIRDaikin176.html#a6f9b7dddcf98c7a42495c900dddf505d',1,'IRDaikin176::toCommonFanSpeed()'],['../classIRDaikin128.html#a1c53a27678731229308e355eb94ec762',1,'IRDaikin128::toCommonFanSpeed()'],['../classIRDaikin64.html#acd24c4932e2bfd6bffbb9a90da2028a6',1,'IRDaikin64::toCommonFanSpeed()'],['../classIRDelonghiAc.html#a231e26843e3616e7455fd020dbb8807b',1,'IRDelonghiAc::toCommonFanSpeed()'],['../classIRElectraAc.html#a5d53fb85582344cfdbfa33da6acbdb7d',1,'IRElectraAc::toCommonFanSpeed()'],['../classIRFujitsuAC.html#a93a35e42d887b5ca6414b295a4a91526',1,'IRFujitsuAC::toCommonFanSpeed()'],['../classIRGoodweatherAc.html#aff899c76d5b808ee35c9f88c116b5dc4',1,'IRGoodweatherAc::toCommonFanSpeed()'],['../classIRGreeAC.html#ade6cb54e99b6dab1df708cbf25fc5967',1,'IRGreeAC::toCommonFanSpeed()'],['../classIRHaierAC.html#ad67ee0b7299d041aad77382dde893229',1,'IRHaierAC::toCommonFanSpeed()'],['../classIRHaierACYRW02.html#a15402e3ba2a9875d5b49f6dab3e85034',1,'IRHaierACYRW02::toCommonFanSpeed()'],['../classIRHitachiAc.html#afba02d48c4a023ed800abf38d5314c7e',1,'IRHitachiAc::toCommonFanSpeed()'],['../classIRHitachiAc1.html#a99f205391deb75d23d08d63e1feff0d4',1,'IRHitachiAc1::toCommonFanSpeed()'],['../classIRHitachiAc424.html#a16abdf55ea3ae4b06e2a23dad3496738',1,'IRHitachiAc424::toCommonFanSpeed()'],['../classIRKelvinatorAC.html#a0ebd262c554c5c843bc3f710570e1401',1,'IRKelvinatorAC::toCommonFanSpeed()'],['../classIRLgAc.html#af47317ba139a4b1e5961b9a45db974df',1,'IRLgAc::toCommonFanSpeed()'],['../classIRMideaAC.html#acd89d4864a46b146ac4f648c4406ded5',1,'IRMideaAC::toCommonFanSpeed()'],['../classIRMitsubishiAC.html#aa7dd30cde520b14575d7fcd992c3bbf1',1,'IRMitsubishiAC::toCommonFanSpeed()'],['../classIRMitsubishi136.html#aaf9f9f17f3ac59ef325b57b9110faa34',1,'IRMitsubishi136::toCommonFanSpeed()'],['../classIRMitsubishi112.html#aaeee082d9adbf7b0d91316c703571f1a',1,'IRMitsubishi112::toCommonFanSpeed()'],['../classIRMitsubishiHeavy152Ac.html#a5e26c3121aceb944fc688e6f641dd5b1',1,'IRMitsubishiHeavy152Ac::toCommonFanSpeed()'],['../classIRMitsubishiHeavy88Ac.html#aa5dae03951ba9a9aeac62184c27f9439',1,'IRMitsubishiHeavy88Ac::toCommonFanSpeed()'],['../classIRNeoclimaAc.html#a5d87285928bd8bfa2abad92fbdf384b5',1,'IRNeoclimaAc::toCommonFanSpeed()'],['../classIRPanasonicAc.html#a1eff8e4d670abc303a02d8baeeb58f8c',1,'IRPanasonicAc::toCommonFanSpeed()'],['../classIRSamsungAc.html#a2905b33c273d2be6cabfc3b16b51a5b4',1,'IRSamsungAc::toCommonFanSpeed()'],['../classIRSharpAc.html#a520666e591965b3b3b2421e06260976a',1,'IRSharpAc::toCommonFanSpeed()'],['../classIRTcl112Ac.html#a66843ee5b53ce9be1aef3774b8df5c84',1,'IRTcl112Ac::toCommonFanSpeed()'],['../classIRTecoAc.html#ac3ad2828770440695969d696ca6ff46d',1,'IRTecoAc::toCommonFanSpeed()'],['../classIRToshibaAC.html#a6c77121c9aba3928e676394f88e88dee',1,'IRToshibaAC::toCommonFanSpeed()'],['../classIRTrotecESP.html#a4aaf17993757533370290fffb728befc',1,'IRTrotecESP::toCommonFanSpeed()'],['../classIRVestelAc.html#a6dfd46f56f2d6b15344722cde0741500',1,'IRVestelAc::toCommonFanSpeed()'],['../classIRWhirlpoolAc.html#a61ef6661a985763540b7c2273b8b1b9c',1,'IRWhirlpoolAc::toCommonFanSpeed()']]], + ['tocommonmode_3486',['toCommonMode',['../classIRAmcorAc.html#a6da2f34f1e044f815e94ede578f4c26f',1,'IRAmcorAc::toCommonMode()'],['../classIRArgoAC.html#a8ccd3f5398f50548fda3a9e0172fb5fa',1,'IRArgoAC::toCommonMode()'],['../classIRCarrierAc64.html#ab17b24d0306b8983886d15175898909e',1,'IRCarrierAc64::toCommonMode()'],['../classIRCoolixAC.html#a789fb5d5eab2e78d392c8e0b9a194b18',1,'IRCoolixAC::toCommonMode()'],['../classIRCoronaAc.html#a04ca6532beb099893eb1dd5d01bb4d31',1,'IRCoronaAc::toCommonMode()'],['../classIRDaikinESP.html#a3a7543204520da36547c163a96e30deb',1,'IRDaikinESP::toCommonMode()'],['../classIRDaikin176.html#aa0b9c96d3bf08400a5110bcfa9f1ec9d',1,'IRDaikin176::toCommonMode()'],['../classIRDaikin128.html#a105a4fc511feba96afc956bb36d2dc50',1,'IRDaikin128::toCommonMode()'],['../classIRDaikin64.html#a80b9dd0fbf935bed5035463af2ad0102',1,'IRDaikin64::toCommonMode()'],['../classIRDelonghiAc.html#a5a3eef369009836a629369cf835741c4',1,'IRDelonghiAc::toCommonMode()'],['../classIRElectraAc.html#a01bd399c3b8908083b95f31d97ddb26f',1,'IRElectraAc::toCommonMode()'],['../classIRFujitsuAC.html#a96140e74d31631581003064f70041d02',1,'IRFujitsuAC::toCommonMode()'],['../classIRGoodweatherAc.html#ab3bcd1354b715179f67499c28fb219fb',1,'IRGoodweatherAc::toCommonMode()'],['../classIRGreeAC.html#a3f393071163fd1577c772a8515e2b5a9',1,'IRGreeAC::toCommonMode()'],['../classIRHaierAC.html#a4d73f75516afff0ef18bdbb7ed9c26ed',1,'IRHaierAC::toCommonMode()'],['../classIRHaierACYRW02.html#a24007a5be360c93ec157b95c8cc06493',1,'IRHaierACYRW02::toCommonMode()'],['../classIRHitachiAc.html#ab7edc0f5571100e1778779081e1c1114',1,'IRHitachiAc::toCommonMode()'],['../classIRHitachiAc1.html#a5cbca62775089593fe2447a77d84b3d5',1,'IRHitachiAc1::toCommonMode()'],['../classIRHitachiAc424.html#a2a725d8dc2178975c977a7496792e667',1,'IRHitachiAc424::toCommonMode()'],['../classIRKelvinatorAC.html#ae2683d38ae72b99e6843e37d36f96db2',1,'IRKelvinatorAC::toCommonMode()'],['../classIRLgAc.html#ac3436968a4445f0210403c353d766b73',1,'IRLgAc::toCommonMode()'],['../classIRMideaAC.html#ac2e0ff374678aadd7fea80194aef8bca',1,'IRMideaAC::toCommonMode()'],['../classIRMitsubishiAC.html#a7eae5da584faf41139be597d6a5e7210',1,'IRMitsubishiAC::toCommonMode()'],['../classIRMitsubishi136.html#a2771fd09b2e953b037c0c65c4e4029ee',1,'IRMitsubishi136::toCommonMode()'],['../classIRMitsubishi112.html#a6da77ebe6e03cfc09aa35e531c292ed1',1,'IRMitsubishi112::toCommonMode()'],['../classIRMitsubishiHeavy152Ac.html#a9faaff371ad3ec33de5646a1afd1992a',1,'IRMitsubishiHeavy152Ac::toCommonMode()'],['../classIRNeoclimaAc.html#a2a220b673c96e54e675d8296aa8b2303',1,'IRNeoclimaAc::toCommonMode()'],['../classIRPanasonicAc.html#a1ace0180b9ac3f4bd17357a03c64792e',1,'IRPanasonicAc::toCommonMode()'],['../classIRSamsungAc.html#a39820a05a9650e9da8a44109234a8d87',1,'IRSamsungAc::toCommonMode()'],['../classIRSharpAc.html#a5e8fca86bcf138bb7c1fd1b4e4384b5f',1,'IRSharpAc::toCommonMode()'],['../classIRTcl112Ac.html#a230a8d768089d869efdea6589b0a9e37',1,'IRTcl112Ac::toCommonMode()'],['../classIRTecoAc.html#ac6c7011b31208887de6d15edbffb211a',1,'IRTecoAc::toCommonMode()'],['../classIRToshibaAC.html#a77871a927ee67460b7bdcb8f204297bc',1,'IRToshibaAC::toCommonMode()'],['../classIRTrotecESP.html#a2b28b06bd25234427d90172b27d57092',1,'IRTrotecESP::toCommonMode()'],['../classIRVestelAc.html#add602c0f052c8ada3b3b5748dda50a58',1,'IRVestelAc::toCommonMode()'],['../classIRWhirlpoolAc.html#a748caa4e22f2f1f47e6334b1a031c4d8',1,'IRWhirlpoolAc::toCommonMode()']]], + ['tocommonswingh_3487',['toCommonSwingH',['../classIRDaikin2.html#a85bb152a4bdcc2798270ee58a3cfe2ae',1,'IRDaikin2::toCommonSwingH()'],['../classIRDaikin176.html#a6a3b66c9777992ed9fcab4e26c1d74dc',1,'IRDaikin176::toCommonSwingH()'],['../classIRHitachiAc344.html#a31562e32ccdf179032e75334b16279f0',1,'IRHitachiAc344::toCommonSwingH()'],['../classIRMitsubishiAC.html#ad7446e0a4ea8d349004c2b4224e69cd9',1,'IRMitsubishiAC::toCommonSwingH()'],['../classIRMitsubishi112.html#a17cfee6dc9ddc38465539ca46f29b263',1,'IRMitsubishi112::toCommonSwingH()'],['../classIRMitsubishiHeavy152Ac.html#afb9e039776c77e898928e9139a21a2b8',1,'IRMitsubishiHeavy152Ac::toCommonSwingH()'],['../classIRMitsubishiHeavy88Ac.html#aead69a01407729240055bd64e583b51b',1,'IRMitsubishiHeavy88Ac::toCommonSwingH()'],['../classIRPanasonicAc.html#aa4241990c350ca936c73b8391c2a11fc',1,'IRPanasonicAc::toCommonSwingH()']]], + ['tocommonswingv_3488',['toCommonSwingV',['../classIRDaikin2.html#a1f3e17757bd4beb0330d75ec3df9788b',1,'IRDaikin2::toCommonSwingV()'],['../classIRDaikin160.html#afae9b50e59c0efa46b96eef9f05a95b7',1,'IRDaikin160::toCommonSwingV()'],['../classIRGreeAC.html#a537d17801a90e22ad2baba7145b038cb',1,'IRGreeAC::toCommonSwingV()'],['../classIRHaierAC.html#aac354e2e4ad72d91667509398078b309',1,'IRHaierAC::toCommonSwingV()'],['../classIRHaierACYRW02.html#a0e426a3479fd80bb3816f016fac22f19',1,'IRHaierACYRW02::toCommonSwingV()'],['../classIRMitsubishiAC.html#a173e3c22f4173f235e7213e41925fdd9',1,'IRMitsubishiAC::toCommonSwingV()'],['../classIRMitsubishi136.html#aca5e6ac2d886083c8c56e2949f9d11e9',1,'IRMitsubishi136::toCommonSwingV()'],['../classIRMitsubishi112.html#a0e577d8554a090d7f2ac2a9ddd3bf15c',1,'IRMitsubishi112::toCommonSwingV()'],['../classIRMitsubishiHeavy152Ac.html#ae4dd9b8f0b5b4becb07618e859a09a51',1,'IRMitsubishiHeavy152Ac::toCommonSwingV()'],['../classIRMitsubishiHeavy88Ac.html#a0597303839e79c97b0fafe6c9ddbcf9a',1,'IRMitsubishiHeavy88Ac::toCommonSwingV()'],['../classIRPanasonicAc.html#adae801e0a2641c196a59d65c26404a13',1,'IRPanasonicAc::toCommonSwingV()']]], + ['todo_20list_3489',['Todo List',['../todo.html',1,'']]], + ['togglerc5_3490',['toggleRC5',['../classIRsend.html#a42a78d4a3ef0f88b54bee488320344da',1,'IRsend']]], + ['togglerc6_3491',['toggleRC6',['../classIRsend.html#a5a0e8778394021ea12a8b8c2daf0add6',1,'IRsend']]], + ['toggleswinghoriz_3492',['toggleSwingHoriz',['../classIRFujitsuAC.html#aeba829bb9a9934ad9246a5ba4f4c03fc',1,'IRFujitsuAC']]], + ['toggleswingvert_3493',['toggleSwingVert',['../classIRFujitsuAC.html#a6dc9cc4bda83215fa97896c41b01e584',1,'IRFujitsuAC']]], + ['toshiba_3494',['toshiba',['../classIRac.html#a384e62cc56ebbdd790ebcd500ce56fc5',1,'IRac']]], + ['toshiba_5fac_3495',['TOSHIBA_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada66de3fced9e8f97d1919bcf4d5726f3e',1,'IRremoteESP8266.h']]], + ['tostring_3496',['toString',['../classIRAmcorAc.html#a2435fd76c642e4a64c7e2330236dcaa6',1,'IRAmcorAc::toString()'],['../classIRArgoAC.html#ad9f52d54687754c0b8d676cb75a3b1bf',1,'IRArgoAC::toString()'],['../classIRCarrierAc64.html#acede081614a80ae46345d4ae45e39ab2',1,'IRCarrierAc64::toString()'],['../classIRCoolixAC.html#ad1282b4071f003ab35d2a97287ba6d2d',1,'IRCoolixAC::toString()'],['../classIRCoronaAc.html#a13e87d763ffd0d25a9d09010828c2124',1,'IRCoronaAc::toString()'],['../classIRDaikinESP.html#a38e705d3ed5128e400efd971e50518d5',1,'IRDaikinESP::toString()'],['../classIRDaikin2.html#a5804ef19f37ee7b8a525bc8db5146c73',1,'IRDaikin2::toString()'],['../classIRDaikin216.html#a5b9ea30424aa3abd9fdee95c78ba9e40',1,'IRDaikin216::toString()'],['../classIRDaikin160.html#a5d9ff2f09b95023c595e9c4794cb29b8',1,'IRDaikin160::toString()'],['../classIRDaikin176.html#a5ff8d589c7e97bd48b50e0ae01356783',1,'IRDaikin176::toString()'],['../classIRDaikin128.html#a48fc2a4080400f83260d2c861c831a28',1,'IRDaikin128::toString()'],['../classIRDaikin152.html#abb9253e8fe7e9bdf786246ce7ab8c54b',1,'IRDaikin152::toString()'],['../classIRDaikin64.html#aa19ba82f1dd405633f078eaf5cb915b8',1,'IRDaikin64::toString()'],['../classIRDelonghiAc.html#a386fb70137a7c2100d05f3202c224887',1,'IRDelonghiAc::toString()'],['../classIRElectraAc.html#a2b1f49b99ec17e211c6cc63d4f72f6a4',1,'IRElectraAc::toString()'],['../classIRFujitsuAC.html#ad779b8b86849ab4c6fe3cfc4afe2c7b8',1,'IRFujitsuAC::toString()'],['../classIRGoodweatherAc.html#a8c298ad0ab98789aa4eb419ed134ee03',1,'IRGoodweatherAc::toString()'],['../classIRGreeAC.html#a1f18b275e0e3d10fbc952d1da9613074',1,'IRGreeAC::toString()'],['../classIRHaierAC.html#a7effff64e7c9c20b7d9e6c2c10e0ffbc',1,'IRHaierAC::toString()'],['../classIRHaierACYRW02.html#a3858dd619f4ea4071b248bb5fb64fb08',1,'IRHaierACYRW02::toString()'],['../classIRHitachiAc.html#a9d927f191807b52fbd4f5d411e0c6519',1,'IRHitachiAc::toString()'],['../classIRHitachiAc1.html#ac70d5ed48897559d7e2ff0f843c79ddc',1,'IRHitachiAc1::toString()'],['../classIRHitachiAc424.html#abc1c122c68d62b582a7e38cdaf9febe7',1,'IRHitachiAc424::toString()'],['../classIRHitachiAc344.html#a5286ffe0ad72f82f66ad19bd6c3bdacc',1,'IRHitachiAc344::toString()'],['../classIRKelvinatorAC.html#a2cc438f41b6f4ed2f9df42acc1ffccfe',1,'IRKelvinatorAC::toString()'],['../classIRLgAc.html#a4546e2e0f63aac0bb9bd54f4f93c5f6c',1,'IRLgAc::toString()'],['../classIRMideaAC.html#a4980fbb52145e1d12a6fa5601f75018a',1,'IRMideaAC::toString()'],['../classIRMitsubishiAC.html#a28cfd4bb4d3372fb983f737c7e86b530',1,'IRMitsubishiAC::toString()'],['../classIRMitsubishi136.html#a8e49c540665a724c895674edef31d980',1,'IRMitsubishi136::toString()'],['../classIRMitsubishi112.html#ab99894eb185d13c5bd097c287fdbddeb',1,'IRMitsubishi112::toString()'],['../classIRMitsubishiHeavy152Ac.html#a9082e1498220f7b641f5f265d1131c0a',1,'IRMitsubishiHeavy152Ac::toString()'],['../classIRMitsubishiHeavy88Ac.html#a7c77e68371e70eb5fd565d8ac815950e',1,'IRMitsubishiHeavy88Ac::toString()'],['../classIRNeoclimaAc.html#a9e6a036411583bad6daf1ef2e60e013c',1,'IRNeoclimaAc::toString()'],['../classIRPanasonicAc.html#ada0b3e2bf11123d0a2f5df8692ae73ad',1,'IRPanasonicAc::toString()'],['../classIRSamsungAc.html#a82de7f9c7b4984f002ea3849b4e95ff2',1,'IRSamsungAc::toString()'],['../classIRSharpAc.html#afee9b0acec54d1683404b7af66c73046',1,'IRSharpAc::toString()'],['../classIRTcl112Ac.html#a381c019f805973000ac5ddb6c70e2773',1,'IRTcl112Ac::toString()'],['../classIRTecoAc.html#a7f085b545dac637927ae58fca13e5c5f',1,'IRTecoAc::toString()'],['../classIRToshibaAC.html#a5bbf6a725f496ac40ec2fac8f9a0dc1c',1,'IRToshibaAC::toString()'],['../classIRTrotecESP.html#a06783a7571b684be20ee5485f30ceb3c',1,'IRTrotecESP::toString()'],['../classIRVestelAc.html#a5fd0630ad7c1d5da3b1bfc5aefc443ec',1,'IRVestelAc::toString()'],['../classIRWhirlpoolAc.html#ad599025e8413f23d13a9783ff4c1fe93',1,'IRWhirlpoolAc::toString()']]], + ['trotec_3497',['trotec',['../classIRac.html#aed1a012c0546c2b1d53e86871a42ba1a',1,'IRac::trotec()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada7d0f8056d221b37f68f80bace2b794b9',1,'TROTEC(): IRremoteESP8266.h']]], + ['turbo_3498',['turbo',['../structstdAc_1_1state__t.html#aae084b686685f2b2a07ccdda649e358c',1,'stdAc::state_t']]], + ['turboflag_3499',['turboFlag',['../classIRCoolixAC.html#a60a8a848951555dba34f2a317d6611ea',1,'IRCoolixAC']]], + ['typetostring_3500',['typeToString',['../IRutils_8cpp.html#a9e98a1b929f36dfa75c2e325bf281cd1',1,'typeToString(const decode_type_t protocol, const bool isRepeat): IRutils.cpp'],['../IRutils_8h.html#a7f49135f3d160700eb12ff6b7309341c',1,'typeToString(const decode_type_t protocol, const bool isRepeat=false): IRutils.cpp']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_15.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_15.html new file mode 100644 index 000000000..767aec361 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_15.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_15.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_15.js new file mode 100644 index 000000000..485738113 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_15.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['uint64tostring_3501',['uint64ToString',['../IRutils_8cpp.html#a9f6ddef74b41ef6f8d2805fcfc396420',1,'uint64ToString(uint64_t input, uint8_t base): IRutils.cpp'],['../IRutils_8h.html#a781650451d38303e80da677539f574ee',1,'uint64ToString(uint64_t input, uint8_t base=10): IRutils.cpp']]], + ['uint8tobcd_3502',['uint8ToBcd',['../namespaceirutils.html#a534704a52b75acd46f687cc0a2b91bf1',1,'irutils']]], + ['unknown_3503',['UNKNOWN',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada6ce26a62afab55d7606ad4e92428b30c',1,'IRremoteESP8266.h']]], + ['unused_3504',['UNUSED',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadaa09b651ef326a9d8efcee5cc5b720ab4',1,'IRremoteESP8266.h']]], + ['updatesavedstate_3505',['updateSavedState',['../classIRCoolixAC.html#a1f39630b328939307bb08c18e56e9ad3',1,'IRCoolixAC']]], + ['use_5ftime_5fstate_3506',['use_time_state',['../classIRVestelAc.html#af1b622c50a4952fb3edaf483e1bf9328',1,'IRVestelAc']]], + ['used_3507',['used',['../structmatch__result__t.html#a26cea305aa83ed65b88ac0b6ed6de54a',1,'match_result_t']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_16.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_16.html new file mode 100644 index 000000000..7bd7afe63 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_16.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_16.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_16.js new file mode 100644 index 000000000..a9e6c124f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_16.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['validchecksum_3508',['validChecksum',['../classIRAmcorAc.html#a1ad297a62ac3152c9d957cef38757d28',1,'IRAmcorAc::validChecksum()'],['../classIRArgoAC.html#acfa5a9df8273123e6f4c48684ef60006',1,'IRArgoAC::validChecksum()'],['../classIRCarrierAc64.html#affa23f178e079cd3a6c933240759fe80',1,'IRCarrierAc64::validChecksum()'],['../classIRDaikinESP.html#ad766e60827f80b96a66449bddc621d87',1,'IRDaikinESP::validChecksum()'],['../classIRDaikin2.html#ade5c0dbfe38d9ac0c4bc009c897af04d',1,'IRDaikin2::validChecksum()'],['../classIRDaikin216.html#a663c11977545ba01b34715a61a26ab88',1,'IRDaikin216::validChecksum()'],['../classIRDaikin160.html#a0d9f3af404e3b6c116e8c27e938f8479',1,'IRDaikin160::validChecksum()'],['../classIRDaikin176.html#abc97abc68f535f7ad801b393e0a795d5',1,'IRDaikin176::validChecksum()'],['../classIRDaikin128.html#ad0b16e48bff00c5cdeffa1419c003946',1,'IRDaikin128::validChecksum()'],['../classIRDaikin152.html#ade1c641eecea63857115fc20f1811fe7',1,'IRDaikin152::validChecksum()'],['../classIRDaikin64.html#ab04287881112ff21d1ea541c0f21b507',1,'IRDaikin64::validChecksum()'],['../classIRDelonghiAc.html#ae39b20bcea2b7090ac2e29d8cd28e5f6',1,'IRDelonghiAc::validChecksum()'],['../classIRElectraAc.html#a60034a18e7574844fb59a03e7789f419',1,'IRElectraAc::validChecksum()'],['../classIRFujitsuAC.html#a26153c647d127356e47d35a7456c6235',1,'IRFujitsuAC::validChecksum()'],['../classIRGreeAC.html#a74e7df0634f0a60110db8c033d9d5b1d',1,'IRGreeAC::validChecksum()'],['../classIRHaierAC.html#ad7aae554b8f0a76493efc2a43ac0f780',1,'IRHaierAC::validChecksum()'],['../classIRHaierACYRW02.html#a3f6d071d215b0316cccc2e94c4786954',1,'IRHaierACYRW02::validChecksum()'],['../classIRHitachiAc.html#a2549c1fd2e8a603eb8924fbba8b26e87',1,'IRHitachiAc::validChecksum()'],['../classIRHitachiAc1.html#aa6b7ab76567ee15aa08b1594c67bd29d',1,'IRHitachiAc1::validChecksum()'],['../classIRKelvinatorAC.html#aaa915fa5eb3f7e5c7a3dc143b6fda826',1,'IRKelvinatorAC::validChecksum()'],['../classIRLgAc.html#a51748fa24de24049a2fafb4590e84176',1,'IRLgAc::validChecksum()'],['../classIRMideaAC.html#a971ab4af0267bb732834e7e1f7b8e354',1,'IRMideaAC::validChecksum()'],['../classIRMitsubishiAC.html#ad74885e17434aa9038dc19ad74de4cd0',1,'IRMitsubishiAC::validChecksum()'],['../classIRMitsubishi136.html#a666d1268a93e96b50ac9012c09320de9',1,'IRMitsubishi136::validChecksum()'],['../classIRMitsubishiHeavy152Ac.html#abef94200719da0c14e211315ffc8bede',1,'IRMitsubishiHeavy152Ac::validChecksum()'],['../classIRMitsubishiHeavy88Ac.html#aabd9d8f81108f20f1d7adff3ac6c2fd4',1,'IRMitsubishiHeavy88Ac::validChecksum()'],['../classIRNeoclimaAc.html#a32e4b4444e0a97b6da4447e977f74f94',1,'IRNeoclimaAc::validChecksum()'],['../classIRPanasonicAc.html#a6a084754596f7840dd308041d11a822d',1,'IRPanasonicAc::validChecksum()'],['../classIRSamsungAc.html#a4f7339bce78ce2b656fc597b4c88db22',1,'IRSamsungAc::validChecksum()'],['../classIRSharpAc.html#acb7fb0ac19e09da02d36cb73c808420d',1,'IRSharpAc::validChecksum()'],['../classIRTcl112Ac.html#a204bc37ffadf72ed31b305197c4803f4',1,'IRTcl112Ac::validChecksum()'],['../classIRToshibaAC.html#adc7c1eee14e4de896121ad06e88b61eb',1,'IRToshibaAC::validChecksum()'],['../classIRTrotecESP.html#ae08748e33ed12c536b18f6d0dc4da1c7',1,'IRTrotecESP::validChecksum()'],['../classIRVestelAc.html#ad3bcc08fb4242af7dcc65e534816a219',1,'IRVestelAc::validChecksum()'],['../classIRWhirlpoolAc.html#a2d891069ebdecc62b03e8c92befa15c6',1,'IRWhirlpoolAc::validChecksum()']]], + ['validsection_3509',['validSection',['../classIRCoronaAc.html#af36894d88e7fb45affc883ba0b077862',1,'IRCoronaAc']]], + ['value_3510',['value',['../classdecode__results.html#a033502b7a6b4b0412e5a2062e33c5f47',1,'decode_results']]], + ['vestel_3511',['vestel',['../classIRac.html#a9b1cd1a4d44bc56e62128b9dbc178bba',1,'IRac']]], + ['vestel_5fac_3512',['VESTEL_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada165413c6395bde985757b5b446f76569',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_17.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_17.html new file mode 100644 index 000000000..35702ecdd --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_17.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_17.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_17.js new file mode 100644 index 000000000..3b357053e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_17.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['wand_5fid_3513',['wand_id',['../unionmagiquest.html#a1b159cd47635d548e1d4198cd6d41e93',1,'magiquest']]], + ['whirlpool_3514',['whirlpool',['../classIRac.html#ae5f7a03589f614c03c5ad8629100b05a',1,'IRac']]], + ['whirlpool_5fac_3515',['WHIRLPOOL_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada9faf927323d110269541b356f079b85a',1,'IRremoteESP8266.h']]], + ['whirlpool_5fac_5fremote_5fmodel_5ft_3516',['whirlpool_ac_remote_model_t',['../IRsend_8h.html#ab4e3ebf2fdf3c6a46da89a3e6ebcd2e2',1,'IRsend.h']]], + ['whynter_3517',['WHYNTER',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada458cdd7fa2b29dc8617c694696580c0c',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_18.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_18.html new file mode 100644 index 000000000..540cdb6a5 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_18.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_18.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_18.js new file mode 100644 index 000000000..072cb0952 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_18.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['xorbytes_3518',['xorBytes',['../IRutils_8cpp.html#aaa2a3fb714375e61051a0b24623b9cc9',1,'xorBytes(const uint8_t *const start, const uint16_t length, const uint8_t init): IRutils.cpp'],['../IRutils_8h.html#ab030689a93499311ee8e6621ac8757aa',1,'xorBytes(const uint8_t *const start, const uint16_t length, const uint8_t init=0): IRutils.cpp']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_19.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_19.html new file mode 100644 index 000000000..14e13e7d2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_19.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_19.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_19.js new file mode 100644 index 000000000..8079328d1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_19.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['yaw1f_3519',['YAW1F',['../IRsend_8h.html#af65070c92b97fa00b2de3818c46039c9a6b29d752ac8bafc8fedabc1282fccfb6',1,'IRsend.h']]], + ['ybofb_3520',['YBOFB',['../IRsend_8h.html#af65070c92b97fa00b2de3818c46039c9a5d6dadebb4f337aa20ea06a87ae9b34a',1,'IRsend.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1a.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1a.html new file mode 100644 index 000000000..233281a12 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1a.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1a.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1a.js new file mode 100644 index 000000000..403d933ff --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1a.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['zepeal_3521',['ZEPEAL',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada1622e3d0835b4d47add716811c7bf797',1,'IRremoteESP8266.h']]], + ['zh_2dcn_2eh_3522',['zh-CN.h',['../zh-CN_8h.html',1,'']]], + ['zonefollowflag_3523',['zoneFollowFlag',['../classIRCoolixAC.html#a9cb37ed201fcf842c153f0414d9bfd9f',1,'IRCoolixAC']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1b.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1b.html new file mode 100644 index 000000000..470a5bffa --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1b.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1b.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1b.js new file mode 100644 index 000000000..e3b5013ee --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_1b.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['_7eirrecv_3524',['~IRrecv',['../classIRrecv.html#a87d4cca5e350177cb0922842dda1eb5b',1,'IRrecv']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_2.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_2.html new file mode 100644 index 000000000..b26d91650 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_2.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_2.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_2.js new file mode 100644 index 000000000..88a5182d9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_2.js @@ -0,0 +1,12 @@ +var searchData= +[ + ['bcdtouint8_67',['bcdToUint8',['../namespaceirutils.html#af18c4abfd0ed9f4b3a099ecec1999ee7',1,'irutils']]], + ['beep_68',['beep',['../structstdAc_1_1state__t.html#a468ce4cf8b68467964b1f1840257663d',1,'stdAc::state_t']]], + ['begin_69',['begin',['../classIRAmcorAc.html#aa723533eea981f79844f241d5bb84654',1,'IRAmcorAc::begin()'],['../classIRArgoAC.html#aca61a63c37797699540c180354809bd8',1,'IRArgoAC::begin()'],['../classIRCarrierAc64.html#a7d9800edffad8a529971535ada5c00ad',1,'IRCarrierAc64::begin()'],['../classIRCoolixAC.html#a506a5ab28865d0243d75ebb7fe62e4ea',1,'IRCoolixAC::begin()'],['../classIRCoronaAc.html#a7db1a8eb9c3c7f76091b2707458e54a9',1,'IRCoronaAc::begin()'],['../classIRDaikinESP.html#accd087c48f246a71898cc6fd7afc2cc7',1,'IRDaikinESP::begin()'],['../classIRDaikin2.html#a6a7b5c28feec523ee81e99a9c32da26e',1,'IRDaikin2::begin()'],['../classIRDaikin216.html#a95be01fb6e672ebd12f2ebca0406ba15',1,'IRDaikin216::begin()'],['../classIRDaikin160.html#a62bb5f66cd99711e388eaa1be9faf617',1,'IRDaikin160::begin()'],['../classIRDaikin176.html#aa742f7d9ae3c9e57cae0e471d7fe59d1',1,'IRDaikin176::begin()'],['../classIRDaikin128.html#af86dba9e085b771c8c3caaebb9f8ee84',1,'IRDaikin128::begin()'],['../classIRDaikin152.html#a2746854350ca7d3a71699439f9843381',1,'IRDaikin152::begin()'],['../classIRDaikin64.html#a291d5f702b4ce763507c731db08b48f2',1,'IRDaikin64::begin()'],['../classIRDelonghiAc.html#a8d5e4f95e929c2365b2be47f42c6328c',1,'IRDelonghiAc::begin()'],['../classIRElectraAc.html#afff519ff9e81ec4aa03ff337f8efef13',1,'IRElectraAc::begin()'],['../classIRFujitsuAC.html#af0dc3fffdafae5970bc367f31029464b',1,'IRFujitsuAC::begin()'],['../classIRGoodweatherAc.html#abace3c8b25d4737a83fe33f94fc741d9',1,'IRGoodweatherAc::begin()'],['../classIRGreeAC.html#a44cf8f0e09248741094af4b35321ab1c',1,'IRGreeAC::begin()'],['../classIRHaierAC.html#ab92fd48ccb5707cb6d14e9d46ce42e17',1,'IRHaierAC::begin()'],['../classIRHaierACYRW02.html#addc01e60e8c4045fab6f22c852eb620f',1,'IRHaierACYRW02::begin()'],['../classIRHitachiAc.html#a62817c840f352bb01a394c37fc95f0f0',1,'IRHitachiAc::begin()'],['../classIRHitachiAc1.html#a28d5d351003d3e0bc1506b06cac8b3d6',1,'IRHitachiAc1::begin()'],['../classIRHitachiAc424.html#a11866bba49e9b976eb22b1039787ecae',1,'IRHitachiAc424::begin()'],['../classIRHitachiAc3.html#a6d79ac7b8ce977e8059019349d6991a7',1,'IRHitachiAc3::begin()'],['../classIRKelvinatorAC.html#a4591bf4e8131aa2a228cbc611156e7f4',1,'IRKelvinatorAC::begin()'],['../classIRLgAc.html#ac08ada1c67ace5ee2ebe4d325aa8c25d',1,'IRLgAc::begin()'],['../classIRMideaAC.html#ac36b6aa76b6b98ab186cd1d5ad9246b4',1,'IRMideaAC::begin()'],['../classIRMitsubishiAC.html#aa6e58080fd811f5b6d0f90c4ef5917df',1,'IRMitsubishiAC::begin()'],['../classIRMitsubishi136.html#abbcd8307862beee2899d2b9900537520',1,'IRMitsubishi136::begin()'],['../classIRMitsubishi112.html#a1d00958556872286b1818d0dbf02e112',1,'IRMitsubishi112::begin()'],['../classIRMitsubishiHeavy152Ac.html#afd649a53d9f7d9b31b7a5732d6cd0857',1,'IRMitsubishiHeavy152Ac::begin()'],['../classIRMitsubishiHeavy88Ac.html#a9bcf18c942ad4df4856bd319215a2002',1,'IRMitsubishiHeavy88Ac::begin()'],['../classIRNeoclimaAc.html#a8f82159b94d86cc4e3d4719441bfa96e',1,'IRNeoclimaAc::begin()'],['../classIRPanasonicAc.html#af48075dc4eb84fcc7f718375d4b0e00a',1,'IRPanasonicAc::begin()'],['../classIRSamsungAc.html#a89f1f902042cd6c6ba9d0f0c6d2cc581',1,'IRSamsungAc::begin()'],['../classIRSharpAc.html#ab87e5b599b7e8fc387fff25b5e13e34f',1,'IRSharpAc::begin()'],['../classIRTcl112Ac.html#a5b9983ab4027951679f0dc31b33cbadf',1,'IRTcl112Ac::begin()'],['../classIRTecoAc.html#a3b23a8556686c83b146101fc31b0dff3',1,'IRTecoAc::begin()'],['../classIRToshibaAC.html#a41e847f399e42c91b0f4aa2ef5d36cba',1,'IRToshibaAC::begin()'],['../classIRTrotecESP.html#a093b874287adb8ef2cc60c832765ff58',1,'IRTrotecESP::begin()'],['../classIRVestelAc.html#a794808d49eb6ce1521ff800b2b15a580',1,'IRVestelAc::begin()'],['../classIRWhirlpoolAc.html#a21db8b31504d416efb2511a33bdc2209',1,'IRWhirlpoolAc::begin()'],['../classIRsend.html#a386f026bf739b0718efde4cffa6ce129',1,'IRsend::begin()']]], + ['bits_70',['bits',['../classdecode__results.html#aa5ba2fd53bdb36bdc120d8eabd9f36d7',1,'decode_results']]], + ['booltostring_71',['boolToString',['../classIRac.html#a9bbd9e6b72e82a752df56e8c489668cf',1,'IRac']]], + ['bufsize_72',['bufsize',['../structirparams__t.html#a2b34d697b85ee6a0ce08344c941e50ec',1,'irparams_t']]], + ['buildfromstate_73',['buildFromState',['../classIRFujitsuAC.html#a6fc8d7d0f649185e0858974394636a8d',1,'IRFujitsuAC']]], + ['buildstate_74',['buildState',['../classIRFujitsuAC.html#ac885c7952253fcee9bf5b4a889b54da9',1,'IRFujitsuAC']]], + ['byte_75',['byte',['../unionmagiquest.html#af1a9c9a147a1610fe5f0e77ca3e09e44',1,'magiquest']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_3.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_3.html new file mode 100644 index 000000000..b61b96f83 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_3.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_3.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_3.js new file mode 100644 index 000000000..527d634a1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_3.js @@ -0,0 +1,45 @@ +var searchData= +[ + ['calcblockchecksum_76',['calcBlockChecksum',['../classIRKelvinatorAC.html#a22f561397c526ed6cc3f69a5d527d8d6',1,'IRKelvinatorAC']]], + ['calcchecksum_77',['calcChecksum',['../classIRAmcorAc.html#aec764cf4d88bb3fcbe3f36d24780f6a9',1,'IRAmcorAc::calcChecksum()'],['../classIRArgoAC.html#acab2fe3b9f77f57f0e99da0bec0d7392',1,'IRArgoAC::calcChecksum()'],['../classIRCarrierAc64.html#a20676dcf4b0a6510cc3bce282fbf8504',1,'IRCarrierAc64::calcChecksum()'],['../classIRDaikin64.html#ac29c18fde1b0cd98991e68c0f672d0e9',1,'IRDaikin64::calcChecksum()'],['../classIRDelonghiAc.html#a14d7629bb888deb02e83886191f44c2d',1,'IRDelonghiAc::calcChecksum()'],['../classIRElectraAc.html#aa8063d07e41ca2cc0fd27093a2e67bb2',1,'IRElectraAc::calcChecksum()'],['../classIRHitachiAc.html#a6e5da77c12ad105439eb159b6a58104a',1,'IRHitachiAc::calcChecksum()'],['../classIRHitachiAc1.html#a6995513d5b59cd7b14cfff39c8843e8d',1,'IRHitachiAc1::calcChecksum()'],['../classIRLgAc.html#a96024e736cf87e65b4e2db7c4c269520',1,'IRLgAc::calcChecksum()'],['../classIRMideaAC.html#ac8733348b311ecf8eed87021cdf4ee31',1,'IRMideaAC::calcChecksum()'],['../classIRNeoclimaAc.html#ac75f316cd1813cdb4e8a6d45d10ddd57',1,'IRNeoclimaAc::calcChecksum()'],['../classIRPanasonicAc.html#a0e38b0f3c54e49cdb59f92279e19840f',1,'IRPanasonicAc::calcChecksum()'],['../classIRSamsungAc.html#a00f9b2a1480d2ed45bdea5d236c77d0f',1,'IRSamsungAc::calcChecksum()'],['../classIRSharpAc.html#af3655c9c394b1391572e8ffab70881ff',1,'IRSharpAc::calcChecksum()'],['../classIRTcl112Ac.html#a0973a1c8a53661ee7720ecb5d08e6dcc',1,'IRTcl112Ac::calcChecksum()'],['../classIRToshibaAC.html#a0d91d32d0d9d722f750eb423d88509f4',1,'IRToshibaAC::calcChecksum()'],['../classIRTrotecESP.html#ac1fdbcbbb8dd1ca50ccf2b55c7281c89',1,'IRTrotecESP::calcChecksum()'],['../classIRVestelAc.html#ac0ba3de4de70350c5325b3d5e0b39e58',1,'IRVestelAc::calcChecksum()']]], + ['calcfirstchecksum_78',['calcFirstChecksum',['../classIRDaikin128.html#a25b25f6b73bb5f1fd17a16080179d4bc',1,'IRDaikin128']]], + ['calcsecondchecksum_79',['calcSecondChecksum',['../classIRDaikin128.html#aea8da64300afe0d62ddf3082a72251f2',1,'IRDaikin128']]], + ['calculatechecksum_80',['calculateChecksum',['../classIRMitsubishiAC.html#aaadefc5880dcd48e3fb2f12b59101f71',1,'IRMitsubishiAC']]], + ['calcusecperiod_81',['calcUSecPeriod',['../classIRsend.html#ae9e68c0ed22e27c8f7ff82cec7ca3e33',1,'IRsend']]], + ['calibrate_82',['calibrate',['../classIRAmcorAc.html#a6206e866e859bc4690cb014c49c1ff80',1,'IRAmcorAc::calibrate()'],['../classIRArgoAC.html#a63cd2f350a7f249c020439543ef3c6d5',1,'IRArgoAC::calibrate()'],['../classIRCarrierAc64.html#a0718376156750e66f98ea0549c75b21b',1,'IRCarrierAc64::calibrate()'],['../classIRCoolixAC.html#a9e39ce5050888210d6ba9b79ae3763e3',1,'IRCoolixAC::calibrate()'],['../classIRCoronaAc.html#a5b10141e4a6e3d8511fb7f9f46d00a96',1,'IRCoronaAc::calibrate()'],['../classIRDaikinESP.html#a638a49f49275a2ab0affb09088794e1b',1,'IRDaikinESP::calibrate()'],['../classIRDaikin2.html#a96c62125bddf113c6524960062d05a57',1,'IRDaikin2::calibrate()'],['../classIRDaikin216.html#a49d7501966528c0a690cfb505f163e26',1,'IRDaikin216::calibrate()'],['../classIRDaikin160.html#a608b5556f316c31e3a8aa73684e4e10d',1,'IRDaikin160::calibrate()'],['../classIRDaikin176.html#a1f5989110782c18aa18e3757c50f4a31',1,'IRDaikin176::calibrate()'],['../classIRDaikin128.html#a281396f4c632899648694e3139c3acd0',1,'IRDaikin128::calibrate()'],['../classIRDaikin152.html#a82fa8bfb3384ed09473345b6e194c3ba',1,'IRDaikin152::calibrate()'],['../classIRDaikin64.html#a12a1e21ba1b06f9b3ffac56691ff2206',1,'IRDaikin64::calibrate()'],['../classIRDelonghiAc.html#aab8f78adcd7fcbea0be753a4fc7696e0',1,'IRDelonghiAc::calibrate()'],['../classIRElectraAc.html#af333e90117ab035ff92389d4eefb3649',1,'IRElectraAc::calibrate()'],['../classIRFujitsuAC.html#a8bb6d8456561dfb04ccac95e0e489558',1,'IRFujitsuAC::calibrate()'],['../classIRGoodweatherAc.html#a8a747144587cf38d64bb32a7f86432b3',1,'IRGoodweatherAc::calibrate()'],['../classIRGreeAC.html#a8069d00a16ed04fd6fa10d84b364bca7',1,'IRGreeAC::calibrate()'],['../classIRHaierAC.html#a448b1d5db05f7722db4758e968ea3171',1,'IRHaierAC::calibrate()'],['../classIRHaierACYRW02.html#a2081b29d0526e339a6b94fc41c854197',1,'IRHaierACYRW02::calibrate()'],['../classIRHitachiAc.html#aaabd743da491ef5d73c4b8c46f11241a',1,'IRHitachiAc::calibrate()'],['../classIRHitachiAc1.html#a847a26df2e19668b147cba2eef595a21',1,'IRHitachiAc1::calibrate()'],['../classIRHitachiAc424.html#aae5e5c13767f335331c5fab8d8ba55d6',1,'IRHitachiAc424::calibrate()'],['../classIRHitachiAc3.html#a02e065c08f9ec4a3d9e6f71432087595',1,'IRHitachiAc3::calibrate()'],['../classIRKelvinatorAC.html#aee8863c1678b09432618bb4ca734db95',1,'IRKelvinatorAC::calibrate()'],['../classIRLgAc.html#a4fd11e935c781319b29f606f2f4b2570',1,'IRLgAc::calibrate()'],['../classIRMideaAC.html#a4077604c2af56783f95a0a64eda7148b',1,'IRMideaAC::calibrate()'],['../classIRMitsubishiAC.html#a973c876e34942776ac98f27de96c5228',1,'IRMitsubishiAC::calibrate()'],['../classIRMitsubishi136.html#a76133542efc3763cb7edc9809ad8d93c',1,'IRMitsubishi136::calibrate()'],['../classIRMitsubishi112.html#ad148250070a3f4ac57ed6cb957ffdefb',1,'IRMitsubishi112::calibrate()'],['../classIRMitsubishiHeavy152Ac.html#a5d4c4ce0e69ed33a2f1db2af127c13c5',1,'IRMitsubishiHeavy152Ac::calibrate()'],['../classIRMitsubishiHeavy88Ac.html#a027423ffbee92ef65b02423f7cbaeca8',1,'IRMitsubishiHeavy88Ac::calibrate()'],['../classIRNeoclimaAc.html#a636dd97ca22c847f966eca8112c8eede',1,'IRNeoclimaAc::calibrate()'],['../classIRPanasonicAc.html#a3f850333f2aa7ce40856c99ef85ffd79',1,'IRPanasonicAc::calibrate()'],['../classIRSamsungAc.html#a5cc7486ae41f61cbe0bb053dd7c9e9e3',1,'IRSamsungAc::calibrate()'],['../classIRSharpAc.html#ac37b1a5679ce90e84f6f95c5df1526bb',1,'IRSharpAc::calibrate()'],['../classIRTcl112Ac.html#a435744e4c6ef31b362d15523ce0584f5',1,'IRTcl112Ac::calibrate()'],['../classIRTecoAc.html#ad700578cbae74857483372597a399ff3',1,'IRTecoAc::calibrate()'],['../classIRToshibaAC.html#a74c66bba288cb3cbb43008edb7b376bf',1,'IRToshibaAC::calibrate()'],['../classIRTrotecESP.html#a56de318a27011e0bddb40738c18dbcf2',1,'IRTrotecESP::calibrate()'],['../classIRVestelAc.html#aae91667d96d86de824a20c256c311f15',1,'IRVestelAc::calibrate()'],['../classIRWhirlpoolAc.html#a006c59c1c84c62fccd3730bec30ef5e8',1,'IRWhirlpoolAc::calibrate()'],['../classIRsend.html#ad1776aa6c699f9eeca1eef9bb4fe355b',1,'IRsend::calibrate()']]], + ['cancelofftimer_83',['cancelOffTimer',['../classIRPanasonicAc.html#a6d202284320c59205cb0d02cb613cada',1,'IRPanasonicAc']]], + ['cancelontimer_84',['cancelOnTimer',['../classIRPanasonicAc.html#a102e7c029a923e121e40326859f2e4a3',1,'IRPanasonicAc']]], + ['canceltimers_85',['cancelTimers',['../classIRHaierAC.html#a1cccc733f74232751f95c32e47795638',1,'IRHaierAC']]], + ['carrier64_86',['carrier64',['../classIRac.html#a8090f2d79a31b81a0342b2e9efb9d555',1,'IRac']]], + ['carrier_5fac_87',['CARRIER_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada4d7328071e0a48bc828fccb02f969c20',1,'IRremoteESP8266.h']]], + ['carrier_5fac40_88',['CARRIER_AC40',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada1340c578f7986b0ed126744127af3907',1,'IRremoteESP8266.h']]], + ['carrier_5fac64_89',['CARRIER_AC64',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada4122973f5d8ce282457d348857ba0af0',1,'IRremoteESP8266.h']]], + ['celsius_90',['celsius',['../structstdAc_1_1state__t.html#a235b17f3979b155b368bfdc2b14123f5',1,'stdAc::state_t']]], + ['celsiustofahrenheit_91',['celsiusToFahrenheit',['../IRutils_8cpp.html#a19b940e26a4f8ddcaf86cce1ec62d563',1,'celsiusToFahrenheit(const float deg): IRutils.cpp'],['../IRutils_8h.html#a19b940e26a4f8ddcaf86cce1ec62d563',1,'celsiusToFahrenheit(const float deg): IRutils.cpp']]], + ['checksum_92',['checksum',['../classIRAmcorAc.html#a67244a75731be6a3bd96ecc0384d0113',1,'IRAmcorAc::checksum()'],['../classIRArgoAC.html#ab0fe4e42d1c1201a92f5c4738b869763',1,'IRArgoAC::checksum()'],['../classIRCarrierAc64.html#a005fab56acf94fe97db7fa92651b2882',1,'IRCarrierAc64::checksum()'],['../classIRCoronaAc.html#ae0257fdafacf7fd2e7ac6ca3f8ae3168',1,'IRCoronaAc::checksum()'],['../classIRDaikinESP.html#ac8ac2a0674dc5cfaf514d319b51b20ab',1,'IRDaikinESP::checksum()'],['../classIRDaikin2.html#abb8e4ad1f8c3ada4211541e5a6e23e64',1,'IRDaikin2::checksum()'],['../classIRDaikin216.html#af2c951901b3b9db9f285a4e9b563ea5e',1,'IRDaikin216::checksum()'],['../classIRDaikin160.html#a34090a598e2b25ee4688c8fbac933638',1,'IRDaikin160::checksum()'],['../classIRDaikin176.html#a4cfe2c4ca95adbf66e149b322d58a843',1,'IRDaikin176::checksum()'],['../classIRDaikin128.html#a747c906808c269581de6cf9b02e5c0a7',1,'IRDaikin128::checksum()'],['../classIRDaikin152.html#a0e208d3e1938abcb320665fffd6ed0e3',1,'IRDaikin152::checksum()'],['../classIRDaikin64.html#a27e2f82b2f13f1e63e981af8f1d3912a',1,'IRDaikin64::checksum()'],['../classIRDelonghiAc.html#ae4c4e7140a763eee159991f5c8afc54f',1,'IRDelonghiAc::checksum()'],['../classIRElectraAc.html#a73dc5b9a038669cc1f00f5b64ad458d1',1,'IRElectraAc::checksum()'],['../classIRGreeAC.html#aaa6b2702d79a7a3db454b99d71064679',1,'IRGreeAC::checksum()'],['../classIRHaierAC.html#ab7faae274ff7f30bf7df3c58d6e7e210',1,'IRHaierAC::checksum()'],['../classIRHaierACYRW02.html#a18045defdd5641ae13c7c75dda0cf23a',1,'IRHaierACYRW02::checksum()'],['../classIRHitachiAc.html#a3b65ccbd6de6b5dcb5a794b471e363f5',1,'IRHitachiAc::checksum()'],['../classIRHitachiAc1.html#aa6687d6282b134d508d6534e8446b341',1,'IRHitachiAc1::checksum()'],['../classIRKelvinatorAC.html#a09acf66b92d3fde6692ec02ff8e62dab',1,'IRKelvinatorAC::checksum()'],['../classIRLgAc.html#a438cbbb77668205c3f2b59b8f28585cd',1,'IRLgAc::checksum()'],['../classIRMideaAC.html#a418b7cbb4b388dba732176d891bb499d',1,'IRMideaAC::checksum()'],['../classIRMitsubishiAC.html#a7c5b1e5c53d99f1564d8a0424f626adb',1,'IRMitsubishiAC::checksum()'],['../classIRMitsubishi136.html#aa2c6fe9b28462052cf6627960126a783',1,'IRMitsubishi136::checksum()'],['../classIRMitsubishi112.html#a65ee232bfc09d05724b8ec5ada538ccf',1,'IRMitsubishi112::checksum()'],['../classIRMitsubishiHeavy152Ac.html#a14cdcaeefef283f707d0fae5108d65f4',1,'IRMitsubishiHeavy152Ac::checksum()'],['../classIRMitsubishiHeavy88Ac.html#acb03ef0da10d3fec14c71bfa087a02b8',1,'IRMitsubishiHeavy88Ac::checksum()'],['../classIRNeoclimaAc.html#acba18ea35a59f6f1ccbcfd75e7979feb',1,'IRNeoclimaAc::checksum()'],['../classIRSamsungAc.html#a75c5886916dd3ef3aa6f96f04934048d',1,'IRSamsungAc::checksum()'],['../classIRSharpAc.html#ad87f46ad9220213d77022dc34920d802',1,'IRSharpAc::checksum()'],['../classIRTcl112Ac.html#a2486f46c7db6a3dfbe3af9c842ff37fa',1,'IRTcl112Ac::checksum()'],['../classIRToshibaAC.html#a5aa2c6fc3b07830f872f98906df7e9ec',1,'IRToshibaAC::checksum()'],['../classIRTrotecESP.html#a5e416e083653ab365f65b3f645f60e8c',1,'IRTrotecESP::checksum()'],['../classIRVestelAc.html#a7a9046e7b5ff57864862bf5f7ad23c4d',1,'IRVestelAc::checksum()'],['../classIRWhirlpoolAc.html#a7790be3df6c4609e5c08c17c5ee52047',1,'IRWhirlpoolAc::checksum()']]], + ['checkzjssig_93',['checkZjsSig',['../classIRMitsubishiHeavy88Ac.html#a6aaf8ae4c9b52d73229b20414099f309',1,'IRMitsubishiHeavy88Ac']]], + ['checkzmssig_94',['checkZmsSig',['../classIRMitsubishiHeavy152Ac.html#a3d1c9d2c98945d21eb1ce82fac1771d2',1,'IRMitsubishiHeavy152Ac']]], + ['clean_95',['clean',['../structstdAc_1_1state__t.html#a703fa57ade60d68deccbb2a59258b32a',1,'stdAc::state_t']]], + ['cleanflag_96',['cleanFlag',['../classIRCoolixAC.html#a9280bc7517713dae451a64e35674804d',1,'IRCoolixAC']]], + ['cleanstate_97',['cleanState',['../classIRac.html#aad988dc123495012758307213a933f37',1,'IRac']]], + ['clearontimerflag_98',['clearOnTimerFlag',['../classIRDaikin2.html#a3587ce954ba94e347d08d73974b50d72',1,'IRDaikin2::clearOnTimerFlag()'],['../classIRDaikin128.html#a8f0bd823535a5bf8b2642eed698b9a71',1,'IRDaikin128::clearOnTimerFlag()']]], + ['clearpowerspecial_99',['clearPowerSpecial',['../classIRSharpAc.html#a3c98c96a66dff560941e461a70efdb1a',1,'IRSharpAc']]], + ['clearsensortemp_100',['clearSensorTemp',['../classIRCoolixAC.html#a5deca09ced33931f089f5cd3c07eac4a',1,'IRCoolixAC']]], + ['clearsleeptimerflag_101',['clearSleepTimerFlag',['../classIRDaikin2.html#a0c165ff91a712e61910ef25e9728e066',1,'IRDaikin2::clearSleepTimerFlag()'],['../classIRDaikin128.html#a5517a481892dd55f4528103037a0d408',1,'IRDaikin128::clearSleepTimerFlag()']]], + ['clock_102',['clock',['../structstdAc_1_1state__t.html#ab1d76172930ebfe992fd9b700369e787',1,'stdAc::state_t']]], + ['cmd_103',['cmd',['../unionmagiquest.html#a71f7646ffd59f0478ae28fad2d724a44',1,'magiquest']]], + ['cmpstates_104',['cmpStates',['../classIRac.html#a3ba4eee08650dfcdd6d492a67c86f016',1,'IRac']]], + ['command_105',['command',['../classdecode__results.html#a9b750d09f713b0693472f815fd0fd402',1,'decode_results']]], + ['compare_106',['compare',['../classIRrecv.html#ad7347c72b14d9f2f20f65bcf235ab3dc',1,'IRrecv']]], + ['convertfan_107',['convertFan',['../classIRAmcorAc.html#ad0f8b7cdf5942c3680639d410f53d18c',1,'IRAmcorAc::convertFan()'],['../classIRArgoAC.html#acd147993fb998a0e7015173b9514d4a2',1,'IRArgoAC::convertFan()'],['../classIRCarrierAc64.html#a255e6679397434877f1c6c9ac70fff50',1,'IRCarrierAc64::convertFan()'],['../classIRCoolixAC.html#a7ffa1cfcf82bd905b0f607401200c895',1,'IRCoolixAC::convertFan()'],['../classIRCoronaAc.html#a6826036fcabbb45e7369f42912fae02f',1,'IRCoronaAc::convertFan()'],['../classIRDaikinESP.html#ab58be19636d41d60b9c62d658ca18cae',1,'IRDaikinESP::convertFan()'],['../classIRDaikin2.html#ad147ea14695c9498bb091862e172dc81',1,'IRDaikin2::convertFan()'],['../classIRDaikin216.html#a520cc65161290f15022b4108f7049a83',1,'IRDaikin216::convertFan()'],['../classIRDaikin160.html#a32658c0f24d0b0c398d54ef648d717a9',1,'IRDaikin160::convertFan()'],['../classIRDaikin176.html#ae3dda9a55f851b5253d0677835a2c3dd',1,'IRDaikin176::convertFan()'],['../classIRDaikin128.html#a983c13bc608fbfa32d7ea2c36dc84116',1,'IRDaikin128::convertFan()'],['../classIRDaikin152.html#a5e2e79252602ca3493baf00cf3fe7787',1,'IRDaikin152::convertFan()'],['../classIRDaikin64.html#a109ff0c33b0a7dfd763683538915c811',1,'IRDaikin64::convertFan()'],['../classIRDelonghiAc.html#aeff2970b20963ae59b99464ae683113f',1,'IRDelonghiAc::convertFan()'],['../classIRElectraAc.html#afcf3ef62d69e370cb88dd2036e5a1357',1,'IRElectraAc::convertFan()'],['../classIRFujitsuAC.html#a111060b7c93e77fdbd1dc96fc8a6c10f',1,'IRFujitsuAC::convertFan()'],['../classIRGoodweatherAc.html#abb443826453a65e87f6dedddf2dd74d5',1,'IRGoodweatherAc::convertFan()'],['../classIRGreeAC.html#a39aa0e4759330aef39382813d3aa96a4',1,'IRGreeAC::convertFan()'],['../classIRHaierAC.html#a58628dd19a7247fc5358c0dc8c30baba',1,'IRHaierAC::convertFan()'],['../classIRHaierACYRW02.html#a66e42d018f3d86b136624a347d333401',1,'IRHaierACYRW02::convertFan()'],['../classIRHitachiAc.html#a5c632c9efc42d9378fdefe608c9bb771',1,'IRHitachiAc::convertFan()'],['../classIRHitachiAc1.html#a96c22fddcd7dfcc5b8f205cc5c7efdef',1,'IRHitachiAc1::convertFan()'],['../classIRHitachiAc424.html#a4f502b779f9fe4aca3a2f649c4cfbda3',1,'IRHitachiAc424::convertFan()'],['../classIRLgAc.html#a71ce8d1be4222ecae26fcea3b71a1ba6',1,'IRLgAc::convertFan()'],['../classIRMideaAC.html#a08a8e49986ce808fd7edd8aee7399a64',1,'IRMideaAC::convertFan()'],['../classIRMitsubishiAC.html#a58ce95e1ae198a9855ee5e81335570cf',1,'IRMitsubishiAC::convertFan()'],['../classIRMitsubishi136.html#a81e691b386950859d1ad0a3c7faf7e49',1,'IRMitsubishi136::convertFan()'],['../classIRMitsubishi112.html#a4194e5b076687b79153bc8cd50c9bc86',1,'IRMitsubishi112::convertFan()'],['../classIRMitsubishiHeavy152Ac.html#ae11040290301b5fe66dfe79e8ea9512b',1,'IRMitsubishiHeavy152Ac::convertFan()'],['../classIRMitsubishiHeavy88Ac.html#acd69c45dbc3f5a150e17b82b5eae7b3f',1,'IRMitsubishiHeavy88Ac::convertFan()'],['../classIRNeoclimaAc.html#a8c3ac622428f118b28d53a3a82740993',1,'IRNeoclimaAc::convertFan()'],['../classIRPanasonicAc.html#aeada51b2d1ff51ff81dfc5c996b416df',1,'IRPanasonicAc::convertFan()'],['../classIRSamsungAc.html#a6be52cc6980ad0bf80261c2a48eb3c87',1,'IRSamsungAc::convertFan()'],['../classIRSharpAc.html#a9b58f12bc44639694a8422a2b9b78a88',1,'IRSharpAc::convertFan()'],['../classIRTcl112Ac.html#a3f8178f8f646ed9892eefa40bbff4fb1',1,'IRTcl112Ac::convertFan()'],['../classIRTecoAc.html#a262aead12607ff962dd97c73e6dea078',1,'IRTecoAc::convertFan()'],['../classIRToshibaAC.html#aeef5cfb840f3058629b486232b7efb22',1,'IRToshibaAC::convertFan()'],['../classIRTrotecESP.html#a905d4d5bd298db8c2e1a9b004fd541e8',1,'IRTrotecESP::convertFan()'],['../classIRVestelAc.html#aa7702b0e50b6c8073cd7740a630b19dd',1,'IRVestelAc::convertFan()'],['../classIRWhirlpoolAc.html#a3004feef0ec5fe327d6a43d68d029377',1,'IRWhirlpoolAc::convertFan()']]], + ['convertmode_108',['convertMode',['../classIRAmcorAc.html#ab57117e1072b5265ac9ab5be6d58bccc',1,'IRAmcorAc::convertMode()'],['../classIRArgoAC.html#ad242e7b18dea9768b9fad6b1e0e12f65',1,'IRArgoAC::convertMode()'],['../classIRCarrierAc64.html#a8e94b1526b26cec55f1e700c86aaf74e',1,'IRCarrierAc64::convertMode()'],['../classIRCoolixAC.html#acfb0d2c20322cb4d3cd681a3a54b30fe',1,'IRCoolixAC::convertMode()'],['../classIRCoronaAc.html#a9f9cf8e38285cb2f3caf79e14516bda1',1,'IRCoronaAc::convertMode()'],['../classIRDaikinESP.html#aa96f52596148cab1f806faf190a0aa0a',1,'IRDaikinESP::convertMode()'],['../classIRDaikin2.html#a10aae6ec9783eac9d89ff98b947767dd',1,'IRDaikin2::convertMode()'],['../classIRDaikin216.html#a4fa9eca71ee6ad66b3fffd8b779f5fb0',1,'IRDaikin216::convertMode()'],['../classIRDaikin160.html#ac69861fdbde341fc75d90a5e4918aa56',1,'IRDaikin160::convertMode()'],['../classIRDaikin176.html#ab07fd6eab0ac6132625a291dae8cfc78',1,'IRDaikin176::convertMode()'],['../classIRDaikin128.html#a0bad4830267887299b2773075a16b283',1,'IRDaikin128::convertMode()'],['../classIRDaikin152.html#a25592419c95c0271d8a0c4203a2919c3',1,'IRDaikin152::convertMode()'],['../classIRDaikin64.html#a595d91c0294c9482aa453f077eebf882',1,'IRDaikin64::convertMode()'],['../classIRDelonghiAc.html#a51a6eab431f81fa448a48c0ec071e706',1,'IRDelonghiAc::convertMode()'],['../classIRElectraAc.html#a0026a1981e713ce1f6916203717e0a00',1,'IRElectraAc::convertMode()'],['../classIRFujitsuAC.html#a242504a5b97c19ff7e369efcadd3916e',1,'IRFujitsuAC::convertMode()'],['../classIRGoodweatherAc.html#aef14e2b6c220e556300d286922da1f54',1,'IRGoodweatherAc::convertMode()'],['../classIRGreeAC.html#a609e87ad4926f150b44426caf79fd38e',1,'IRGreeAC::convertMode()'],['../classIRHaierAC.html#af6188dbed5cae022b4fd1eef358f594c',1,'IRHaierAC::convertMode()'],['../classIRHaierACYRW02.html#a9a51f3d4b4c60ed7d99f9836a57bb3e5',1,'IRHaierACYRW02::convertMode()'],['../classIRHitachiAc.html#af1bdc5e22e5e24218421bd3bbb436301',1,'IRHitachiAc::convertMode()'],['../classIRHitachiAc1.html#a6211c96f463353791e5d922d9939f23c',1,'IRHitachiAc1::convertMode()'],['../classIRHitachiAc424.html#a974bf3ada7117e463b8c23e2158902be',1,'IRHitachiAc424::convertMode()'],['../classIRKelvinatorAC.html#acc9d70a94dd3813005ca0381b80a35e4',1,'IRKelvinatorAC::convertMode()'],['../classIRLgAc.html#a114eca216b7c9c7be33d4527f848311e',1,'IRLgAc::convertMode()'],['../classIRMideaAC.html#a0ca16c8bc2232be467baba8ea69b40d4',1,'IRMideaAC::convertMode()'],['../classIRMitsubishiAC.html#a86d069e406d247bafbefbdd09b22894f',1,'IRMitsubishiAC::convertMode()'],['../classIRMitsubishi136.html#a43b8ff1083d09563a5d3a25b24e480ea',1,'IRMitsubishi136::convertMode()'],['../classIRMitsubishi112.html#aa41d6ec8bc6dc91891aaddbd996f6040',1,'IRMitsubishi112::convertMode()'],['../classIRMitsubishiHeavy152Ac.html#a067ca776edc19a577e8bcda5013e1d0f',1,'IRMitsubishiHeavy152Ac::convertMode()'],['../classIRMitsubishiHeavy88Ac.html#ad0419d176d70935fc535cdcc47ffba02',1,'IRMitsubishiHeavy88Ac::convertMode()'],['../classIRNeoclimaAc.html#a61335773816ecbbeb949e5da78d07e50',1,'IRNeoclimaAc::convertMode()'],['../classIRPanasonicAc.html#a3f3bc3e4b73338351f33f26c635075bb',1,'IRPanasonicAc::convertMode()'],['../classIRSamsungAc.html#a76f7fed436bdfcd9c9a9da8dd99cb9f7',1,'IRSamsungAc::convertMode()'],['../classIRSharpAc.html#a340d60b4b24c10479b3fed4409e0834b',1,'IRSharpAc::convertMode()'],['../classIRTcl112Ac.html#ac063653636319a9451590b08abbfecdc',1,'IRTcl112Ac::convertMode()'],['../classIRTecoAc.html#a5f95c5aacd8fc312acd0f36fd9dc33f2',1,'IRTecoAc::convertMode()'],['../classIRToshibaAC.html#a1cdcb695e128d57c721623cfdc9a8e8d',1,'IRToshibaAC::convertMode()'],['../classIRTrotecESP.html#a114a7022f0382275a55a2775d3d8e894',1,'IRTrotecESP::convertMode()'],['../classIRVestelAc.html#a5bb967d4972374254dad2c0a6fac7ed2',1,'IRVestelAc::convertMode()'],['../classIRWhirlpoolAc.html#afbf2f473c98f480d68c8bb28e1202d56',1,'IRWhirlpoolAc::convertMode()']]], + ['convertswingh_109',['convertSwingH',['../classIRDaikin2.html#a79a989ad0221157c4dd8d992cc2863dc',1,'IRDaikin2::convertSwingH()'],['../classIRDaikin176.html#a2387b8dff2a9c9cd164034977b03f192',1,'IRDaikin176::convertSwingH()'],['../classIRHitachiAc344.html#a34d0fa5b522b51dac46f33cbb0a0a389',1,'IRHitachiAc344::convertSwingH()'],['../classIRMitsubishiAC.html#a8235a527a178486bb58ce62749aaf2fb',1,'IRMitsubishiAC::convertSwingH()'],['../classIRMitsubishi112.html#ab17598ce693475ef167525b8408e2da4',1,'IRMitsubishi112::convertSwingH()'],['../classIRMitsubishiHeavy152Ac.html#a0183cf4fcefb60ac61060dde698efbd1',1,'IRMitsubishiHeavy152Ac::convertSwingH()'],['../classIRMitsubishiHeavy88Ac.html#a8b995256a6651822731da7a912c01f19',1,'IRMitsubishiHeavy88Ac::convertSwingH()'],['../classIRPanasonicAc.html#abb17db3452ae347101dc6eaa8e84433b',1,'IRPanasonicAc::convertSwingH()']]], + ['convertswingv_110',['convertSwingV',['../classIRArgoAC.html#ac23ff32b45c3fc5402e7e303ad9b5d54',1,'IRArgoAC::convertSwingV()'],['../classIRDaikin2.html#aa3de8468b869989ec52a5f9f57ff4a77',1,'IRDaikin2::convertSwingV()'],['../classIRDaikin160.html#a615f599f3bc3e8dec5e5ef92512a2301',1,'IRDaikin160::convertSwingV()'],['../classIRGoodweatherAc.html#a3b37c04fd9b60b63052d93374fc15d4f',1,'IRGoodweatherAc::convertSwingV()'],['../classIRGreeAC.html#ae3717400d1dc0336bcc5fa17c1397a9b',1,'IRGreeAC::convertSwingV()'],['../classIRHaierAC.html#a34053c32ba50ff3b81b208d068efe2a4',1,'IRHaierAC::convertSwingV()'],['../classIRHaierACYRW02.html#a1f7dffe29fbe67989b2f425d629850db',1,'IRHaierACYRW02::convertSwingV()'],['../classIRMitsubishiAC.html#ab561f6421b2f3e0d92d9fab685da639a',1,'IRMitsubishiAC::convertSwingV()'],['../classIRMitsubishi136.html#a59dee0c57d3ca2bdf4c7839142d23059',1,'IRMitsubishi136::convertSwingV()'],['../classIRMitsubishi112.html#a95c545497e0acc6f78ec229a2ada9de0',1,'IRMitsubishi112::convertSwingV()'],['../classIRMitsubishiHeavy152Ac.html#a93f2678fce3b35cfe3e31221d3355291',1,'IRMitsubishiHeavy152Ac::convertSwingV()'],['../classIRMitsubishiHeavy88Ac.html#abeba5346e1fc2223838fbc5d3ed03f23',1,'IRMitsubishiHeavy88Ac::convertSwingV()'],['../classIRPanasonicAc.html#a024e64fe32848e9b0b72e9c04db0fd98',1,'IRPanasonicAc::convertSwingV()']]], + ['cool_5fmode_111',['cool_mode',['../classIRArgoAC.html#a74e7e489d743f213664d9259f1e7a431',1,'IRArgoAC']]], + ['coolix_112',['coolix',['../classIRac.html#a4750db3b06db51f5a23c22538c41b7b3',1,'IRac::coolix()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadae561d1d82d90c1b54a1a502431749873',1,'COOLIX(): IRremoteESP8266.h']]], + ['copyirparams_113',['copyIrParams',['../classIRrecv.html#ab017a0f9256954bb7d943e3c6b7e31bf',1,'IRrecv']]], + ['corona_114',['corona',['../classIRac.html#adcf2bdb1ef6dc057532ae7d188557dac',1,'IRac']]], + ['corona_5fac_115',['CORONA_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadaf61f2c360f487309cfa466a44fcae106',1,'IRremoteESP8266.h']]], + ['countbits_116',['countBits',['../IRutils_8cpp.html#a84621a9f7fb2d57bd425f9f0d662cf7d',1,'countBits(const uint8_t *const start, const uint16_t length, const bool ones, const uint16_t init): IRutils.cpp'],['../IRutils_8cpp.html#aae8042367bb94df81672603270fa7342',1,'countBits(const uint64_t data, const uint8_t length, const bool ones, const uint16_t init): IRutils.cpp'],['../IRutils_8h.html#a27816eac50afafa9e53ba4b53675da20',1,'countBits(const uint8_t *const start, const uint16_t length, const bool ones=true, const uint16_t init=0): IRutils.cpp'],['../IRutils_8h.html#a5a719829db11f5d5560b4367c0d2d365',1,'countBits(const uint64_t data, const uint8_t length, const bool ones=true, const uint16_t init=0): IRutils.cpp']]], + ['crudenoisefilter_117',['crudeNoiseFilter',['../classIRrecv.html#ae833bdb8fccc676043fc4ccae432fab1',1,'IRrecv']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_4.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_4.html new file mode 100644 index 000000000..06de1550e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_4.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_4.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_4.js new file mode 100644 index 000000000..450e9d625 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_4.js @@ -0,0 +1,111 @@ +var searchData= +[ + ['daikin_118',['daikin',['../classIRac.html#afb6d77bbeb5b2465437cef4f58b83e0e',1,'IRac::daikin()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadad8dc0597fd237d7098246334f3b5f37e',1,'DAIKIN(): IRremoteESP8266.h']]], + ['daikin128_119',['daikin128',['../classIRac.html#a8fe7c254e1bcb32b6b6fdc1f91693a50',1,'IRac::daikin128()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada4b26fb376f6375dd6d1d4be186438f88',1,'DAIKIN128(): IRremoteESP8266.h']]], + ['daikin152_120',['daikin152',['../classIRac.html#a6dff8e608e3e9fecffe71c3fd1ebe74e',1,'IRac::daikin152()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadad3f5f7ca39aee5fdab671a1b0d647ae4',1,'DAIKIN152(): IRremoteESP8266.h']]], + ['daikin160_121',['daikin160',['../classIRac.html#a3b34f44d713efa52f30d43405cde831c',1,'IRac::daikin160()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada4db6a848df3aed4289801e1b2bbbf6aa',1,'DAIKIN160(): IRremoteESP8266.h']]], + ['daikin176_122',['daikin176',['../classIRac.html#aaae173fd58a7b53c3f4d2edbf7c4afe7',1,'IRac::daikin176()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada57f78a3b04d904f19d10bac13483deab',1,'DAIKIN176(): IRremoteESP8266.h']]], + ['daikin2_123',['daikin2',['../classIRac.html#a89eddc0e1b3c41c608208d2752dc954c',1,'IRac::daikin2()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadab37b344f84d575ec78a92ca55e153586',1,'DAIKIN2(): IRremoteESP8266.h']]], + ['daikin216_124',['daikin216',['../classIRac.html#a101ac8b9e9564e557ef1a1f61ff111d9',1,'IRac::daikin216()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadaa833fa3a20c3cbb7e6206dac4da30ffb',1,'DAIKIN216(): IRremoteESP8266.h']]], + ['daikin64_125',['daikin64',['../classIRac.html#a074db6fc0cff2878d80a397020e1b249',1,'IRac::daikin64()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada70581853ce4883b747d22fdfd74409c4',1,'DAIKIN64(): IRremoteESP8266.h']]], + ['data_126',['data',['../structmatch__result__t.html#ae88be61a6d1ffa7c3525aa958f4c0d25',1,'match_result_t']]], + ['de_2dch_2eh_127',['de-CH.h',['../de-CH_8h.html',1,'']]], + ['de_2dde_2eh_128',['de-DE.h',['../de-DE_8h.html',1,'']]], + ['decode_129',['decode',['../classIRrecv.html#aeaa5c07a8b46f8fbb982f996cc1f9f4b',1,'IRrecv']]], + ['decode_5fresults_130',['decode_results',['../classdecode__results.html',1,'']]], + ['decode_5ftype_131',['decode_type',['../classdecode__results.html#a9c0e9f161b9c90dc10b7561d4c0b50fa',1,'decode_results']]], + ['decode_5ftype_5ft_132',['decode_type_t',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fad',1,'IRremoteESP8266.h']]], + ['decodeairwell_133',['decodeAirwell',['../classIRrecv.html#acf4635d5ee146a82498cb0c269b6af41',1,'IRrecv']]], + ['decodeaiwarct501_134',['decodeAiwaRCT501',['../classIRrecv.html#aa4d678376a4c0f8ea953474a6f5ef9d2',1,'IRrecv']]], + ['decodeamcor_135',['decodeAmcor',['../classIRrecv.html#a8d81fcfb47e36925975d313027689a44',1,'IRrecv']]], + ['decodeargo_136',['decodeArgo',['../classIRrecv.html#a94f12dc000a6e7b75ea8680fd48fc487',1,'IRrecv']]], + ['decodecarrierac_137',['decodeCarrierAC',['../classIRrecv.html#acf3d1c37038120a5c0996d92577ce74a',1,'IRrecv']]], + ['decodecarrierac40_138',['decodeCarrierAC40',['../classIRrecv.html#a4bdb35ec34f49401a6b9becd15b8a3b5',1,'IRrecv']]], + ['decodecarrierac64_139',['decodeCarrierAC64',['../classIRrecv.html#a79d03c31da48a385ab47cc8f342ef9b3',1,'IRrecv']]], + ['decodecoolix_140',['decodeCOOLIX',['../classIRrecv.html#a964af7e72e2133688f0596c718cb98ca',1,'IRrecv']]], + ['decodecoronaac_141',['decodeCoronaAc',['../classIRrecv.html#a981cba14551c93af57f9c1c0e1775d12',1,'IRrecv']]], + ['decodedaikin_142',['decodeDaikin',['../classIRrecv.html#a141f0de9f4cae8daeb025aff3904ecaa',1,'IRrecv']]], + ['decodedaikin128_143',['decodeDaikin128',['../classIRrecv.html#ac7188577c874d9f8f19304a3ec775415',1,'IRrecv']]], + ['decodedaikin152_144',['decodeDaikin152',['../classIRrecv.html#ab20a6586b4e56cc428012ec96f5ccc2c',1,'IRrecv']]], + ['decodedaikin160_145',['decodeDaikin160',['../classIRrecv.html#af0b9822defe6b29099079d664d9dc413',1,'IRrecv']]], + ['decodedaikin176_146',['decodeDaikin176',['../classIRrecv.html#aa142d1340201b6fdc5b462f46fe21ee0',1,'IRrecv']]], + ['decodedaikin2_147',['decodeDaikin2',['../classIRrecv.html#a4c4799a0d45ea5562159c46939617d80',1,'IRrecv']]], + ['decodedaikin216_148',['decodeDaikin216',['../classIRrecv.html#a7f860686a5c58aa8f4d1842cfb15b2f9',1,'IRrecv']]], + ['decodedaikin64_149',['decodeDaikin64',['../classIRrecv.html#a030701f081a9c6eab0c07b75433b524c',1,'IRrecv']]], + ['decodedelonghiac_150',['decodeDelonghiAc',['../classIRrecv.html#a8c91cc83770d243e942387cc16e9ca6f',1,'IRrecv']]], + ['decodedenon_151',['decodeDenon',['../classIRrecv.html#a0b1bd1c817cb43bc3755126191b7f4a2',1,'IRrecv']]], + ['decodedish_152',['decodeDISH',['../classIRrecv.html#a851776d9178aeb706d9a1abd3f254e31',1,'IRrecv']]], + ['decodedoshisha_153',['decodeDoshisha',['../classIRrecv.html#a675c45e6b32aaeca3de734ccf2f0c819',1,'IRrecv']]], + ['decodeelectraac_154',['decodeElectraAC',['../classIRrecv.html#ad3a7be8afc36451c8e28e27f3c3e9aaa',1,'IRrecv']]], + ['decodeepson_155',['decodeEpson',['../classIRrecv.html#aaadef8415f273ba25f4086fecd681d2e',1,'IRrecv']]], + ['decodefujitsuac_156',['decodeFujitsuAC',['../classIRrecv.html#aa3778bdf994bf9c99ac48ef95434a826',1,'IRrecv']]], + ['decodegicable_157',['decodeGICable',['../classIRrecv.html#afade8dac9b1d023e5e0946e6b2c08aea',1,'IRrecv']]], + ['decodegoodweather_158',['decodeGoodweather',['../classIRrecv.html#a64650ce7dbaf5fc860a6a253d906e9de',1,'IRrecv']]], + ['decodegree_159',['decodeGree',['../classIRrecv.html#a2e756342d7524a13d53d6c656700638c',1,'IRrecv']]], + ['decodehaierac_160',['decodeHaierAC',['../classIRrecv.html#ad97403174f05197a7fa9a4a0107e3111',1,'IRrecv']]], + ['decodehaieracyrw02_161',['decodeHaierACYRW02',['../classIRrecv.html#a281fb9d972fee75db49209c42f649822',1,'IRrecv']]], + ['decodehash_162',['decodeHash',['../classIRrecv.html#a7c15fbfa7936ca474712a1953911fd06',1,'IRrecv']]], + ['decodehitachiac_163',['decodeHitachiAC',['../classIRrecv.html#aa42facfffc0e304005272b6ddd4583c8',1,'IRrecv']]], + ['decodehitachiac1_164',['decodeHitachiAC1',['../classIRrecv.html#a122e0dcbf14c90ec2d77399acce21459',1,'IRrecv']]], + ['decodehitachiac3_165',['decodeHitachiAc3',['../classIRrecv.html#a113bc834eff00f55d5545ce3fa1ab203',1,'IRrecv']]], + ['decodehitachiac424_166',['decodeHitachiAc424',['../classIRrecv.html#a01c3dda56d6d916076fa1affa2213129',1,'IRrecv']]], + ['decodeinax_167',['decodeInax',['../classIRrecv.html#a94545c6a8da027b9cb0e23ecba4c29d8',1,'IRrecv']]], + ['decodejvc_168',['decodeJVC',['../classIRrecv.html#a25ab71efc223a418e9630d8421f44bc9',1,'IRrecv']]], + ['decodekelvinator_169',['decodeKelvinator',['../classIRrecv.html#a0ac82f20b48b2d71ee07eb392578b226',1,'IRrecv']]], + ['decodelasertag_170',['decodeLasertag',['../classIRrecv.html#ae4af614a45ea65cb3304ef5bd7965122',1,'IRrecv']]], + ['decodelegopf_171',['decodeLegoPf',['../classIRrecv.html#aea75ad0ba1d8fec33de16501940f2553',1,'IRrecv']]], + ['decodelg_172',['decodeLG',['../classIRrecv.html#afe70015c36b1477a5de0c193163e13a7',1,'IRrecv']]], + ['decodelutron_173',['decodeLutron',['../classIRrecv.html#a6093c4404a9a9d415c5bfeab5ec53be5',1,'IRrecv']]], + ['decodemagiquest_174',['decodeMagiQuest',['../classIRrecv.html#a6f3bfcc6767484151dee758bcf94fb0b',1,'IRrecv']]], + ['decodemidea_175',['decodeMidea',['../classIRrecv.html#a255b15601f7439a09ab5e77ad78816fb',1,'IRrecv']]], + ['decodemidea24_176',['decodeMidea24',['../classIRrecv.html#a62a04019308b29ae2aea4b3a83ba9155',1,'IRrecv']]], + ['decodemitsubishi_177',['decodeMitsubishi',['../classIRrecv.html#a6efe3be80f0ebef3ff94ed0e56c5c52a',1,'IRrecv']]], + ['decodemitsubishi112_178',['decodeMitsubishi112',['../classIRrecv.html#ae0690ff3cb5a5cdcdb6a514bb7bf0cdd',1,'IRrecv']]], + ['decodemitsubishi136_179',['decodeMitsubishi136',['../classIRrecv.html#a87b3ee57dbdf762a0e305ddd43eec629',1,'IRrecv']]], + ['decodemitsubishi2_180',['decodeMitsubishi2',['../classIRrecv.html#a9514197850491a5b8c30ae9ffc89d895',1,'IRrecv']]], + ['decodemitsubishiac_181',['decodeMitsubishiAC',['../classIRrecv.html#a942c5f41df5cbff32a8b7703673cb621',1,'IRrecv']]], + ['decodemitsubishiheavy_182',['decodeMitsubishiHeavy',['../classIRrecv.html#aef9cedf79793806df4cc5376710781bc',1,'IRrecv']]], + ['decodemultibrackets_183',['decodeMultibrackets',['../classIRrecv.html#af61afacc9865232643164ba824e665ab',1,'IRrecv']]], + ['decodemwm_184',['decodeMWM',['../classIRrecv.html#a27518b5d792cdf3ab333b324f409f328',1,'IRrecv']]], + ['decodenec_185',['decodeNEC',['../classIRrecv.html#a52b844f80df7f64edf9ce9cc189ac5b9',1,'IRrecv']]], + ['decodeneoclima_186',['decodeNeoclima',['../classIRrecv.html#a4729ee949e533448b481ae33bbbf1adf',1,'IRrecv']]], + ['decodenikai_187',['decodeNikai',['../classIRrecv.html#abbcbf5fc07d7e37d7724acc37bb5f592',1,'IRrecv']]], + ['decodepanasonic_188',['decodePanasonic',['../classIRrecv.html#aa8dd5f24d28576c6db03cc463bd0a865',1,'IRrecv']]], + ['decodepanasonicac_189',['decodePanasonicAC',['../classIRrecv.html#a0f78e180ed731e8fb16d1c85aa721c95',1,'IRrecv']]], + ['decodepioneer_190',['decodePioneer',['../classIRrecv.html#a78a9487cbe8a562392a07a4090b3091e',1,'IRrecv']]], + ['decoderc5_191',['decodeRC5',['../classIRrecv.html#adab9dffbeceee514520fababd0e721bd',1,'IRrecv']]], + ['decoderc6_192',['decodeRC6',['../classIRrecv.html#a67316499ef37db82e3b3ecaac25c5980',1,'IRrecv']]], + ['decodercmm_193',['decodeRCMM',['../classIRrecv.html#a0e7bf769cb5bebf174e852e4b0b08cf3',1,'IRrecv']]], + ['decodesamsung_194',['decodeSAMSUNG',['../classIRrecv.html#a18b6cf177364faf11b9a076dd2025eec',1,'IRrecv']]], + ['decodesamsung36_195',['decodeSamsung36',['../classIRrecv.html#a290a9e6a0b12ef1fe02a92a456c8ad57',1,'IRrecv']]], + ['decodesamsungac_196',['decodeSamsungAC',['../classIRrecv.html#ae779c76ebd0f3cd1fc13abaa55f80d67',1,'IRrecv']]], + ['decodesanyolc7461_197',['decodeSanyoLC7461',['../classIRrecv.html#a201a5a78f43c2ac216fae4a2ba4d14ec',1,'IRrecv']]], + ['decodesharp_198',['decodeSharp',['../classIRrecv.html#a3390d63ba21a835d7c74c261532a22a7',1,'IRrecv']]], + ['decodesharpac_199',['decodeSharpAc',['../classIRrecv.html#a8a9b920079f783e236f8a938e20b9743',1,'IRrecv']]], + ['decodesony_200',['decodeSony',['../classIRrecv.html#ab03227955cf7d1d00c1620c55d7f9f18',1,'IRrecv']]], + ['decodesymphony_201',['decodeSymphony',['../classIRrecv.html#a61cdf4d891654521afbc6ca9fb415745',1,'IRrecv']]], + ['decodeteco_202',['decodeTeco',['../classIRrecv.html#a950711d7df8dfe4cda86f53650cd9f56',1,'IRrecv']]], + ['decodetoshibaac_203',['decodeToshibaAC',['../classIRrecv.html#a01228e51ede905beac689967bb14b538',1,'IRrecv']]], + ['decodetostate_204',['decodeToState',['../namespaceIRAcUtils.html#ac5eb498bf12cb6cba023c9c1e9726949',1,'IRAcUtils']]], + ['decodetrotec_205',['decodeTrotec',['../classIRrecv.html#ae2920c488173f3fa37f5325438157ced',1,'IRrecv']]], + ['decodevestelac_206',['decodeVestelAc',['../classIRrecv.html#a5d48b3c91434c18c7726cca504d75b73',1,'IRrecv']]], + ['decodewhirlpoolac_207',['decodeWhirlpoolAC',['../classIRrecv.html#a0d1eec83cf092f5621cb34b3e94777c4',1,'IRrecv']]], + ['decodewhynter_208',['decodeWhynter',['../classIRrecv.html#a66289f6a462557ad26e6c0a64f36cf02',1,'IRrecv']]], + ['decodezepeal_209',['decodeZepeal',['../classIRrecv.html#a72afd857c8b2e0192021a40afc96c2d8',1,'IRrecv']]], + ['defaultbits_210',['defaultBits',['../classIRsend.html#a70a2256bee8ad9b8ea8571dd4f26596f',1,'IRsend']]], + ['defaults_2eh_211',['defaults.h',['../defaults_8h.html',1,'']]], + ['degrees_212',['degrees',['../structstdAc_1_1state__t.html#a3d1ff0ff2e0035db4ee8ead5c53b2dbd',1,'stdAc::state_t']]], + ['delonghi_5fac_213',['DELONGHI_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada149190c9dec98e9c3f4a2bd530b154a3',1,'IRremoteESP8266.h']]], + ['delonghiac_214',['delonghiac',['../classIRac.html#af290b0b08cff5121bb88c62051ed1074',1,'IRac']]], + ['denon_215',['DENON',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada2bda37b76abb290d1675c3e027e3c2e1',1,'IRremoteESP8266.h']]], + ['deprecated_20list_216',['Deprecated List',['../deprecated.html',1,'']]], + ['dg11j13a_217',['DG11J13A',['../IRsend_8h.html#ab4e3ebf2fdf3c6a46da89a3e6ebcd2e2a868d69f0605cf9151b0163a3481e2fb9',1,'IRsend.h']]], + ['dg11j191_218',['DG11J191',['../IRsend_8h.html#ab4e3ebf2fdf3c6a46da89a3e6ebcd2e2adaecfc16f36975f231db2507a8a36c0c',1,'IRsend.h']]], + ['disableirin_219',['disableIRIn',['../classIRrecv.html#a9f4a719e756ad78c7dd47186f8bef087',1,'IRrecv']]], + ['disableofftimer_220',['disableOffTimer',['../classIRDaikinESP.html#a1e4e05ad0799002d0ab25db92dcaac06',1,'IRDaikinESP::disableOffTimer()'],['../classIRDaikin2.html#a6c8ad4c34713d61942c80b6052e6283a',1,'IRDaikin2::disableOffTimer()']]], + ['disableontimer_221',['disableOnTimer',['../classIRDaikinESP.html#a0733e4a15d76baac23493926ef1765b1',1,'IRDaikinESP::disableOnTimer()'],['../classIRDaikin2.html#ab0e77969a86af9637cb9aa4b4befd4aa',1,'IRDaikin2::disableOnTimer()']]], + ['disablesleeptimer_222',['disableSleepTimer',['../classIRDaikin2.html#a5461cf51967d3fe67489384c82daac47',1,'IRDaikin2']]], + ['dish_223',['DISH',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadac27c6ac38ba872593af8e46ac2fdc85a',1,'IRremoteESP8266.h']]], + ['doshisha_224',['DOSHISHA',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadab4566b260773b60c85450f40fa5b4341',1,'IRremoteESP8266.h']]], + ['doxygen_5findex_2emd_225',['doxygen_index.md',['../doxygen__index_8md.html',1,'']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_5.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_5.html new file mode 100644 index 000000000..2544c4e5b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_5.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_5.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_5.js new file mode 100644 index 000000000..c57085813 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_5.js @@ -0,0 +1,34 @@ +var searchData= +[ + ['econo_226',['econo',['../structstdAc_1_1state__t.html#a580c826c6d9671715adfe8445531b957',1,'stdAc::state_t']]], + ['elapsed_227',['elapsed',['../classIRtimer.html#ad655e585f053580d49d8de7d52cd62a1',1,'IRtimer::elapsed()'],['../classTimerMs.html#ad4aa759c58727393f69863b3461dfc09',1,'TimerMs::elapsed()']]], + ['electra_228',['electra',['../classIRac.html#abb847bd5e09feb293432b8a8cf0dd9de',1,'IRac']]], + ['electra_5fac_229',['ELECTRA_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada05f193ef4ead3e54624bd92dc3203fac',1,'IRremoteESP8266.h']]], + ['en_2dau_2eh_230',['en-AU.h',['../en-AU_8h.html',1,'']]], + ['en_2die_2eh_231',['en-IE.h',['../en-IE_8h.html',1,'']]], + ['en_2duk_2eh_232',['en-UK.h',['../en-UK_8h.html',1,'']]], + ['en_2dus_2eh_233',['en-US.h',['../en-US_8h.html',1,'']]], + ['enableirin_234',['enableIRIn',['../classIRrecv.html#a52c05ec6d8f3dbfb75f21f3b4fe7be3d',1,'IRrecv']]], + ['enableirout_235',['enableIROut',['../classIRsend.html#ab3b6d36c9b5d26c400526717d433ed2d',1,'IRsend']]], + ['enableofftimer_236',['enableOffTimer',['../classIRDaikinESP.html#a8a5686066bfc86f1d7cc454e793d3357',1,'IRDaikinESP::enableOffTimer()'],['../classIRDaikin2.html#afc7ba7d7de2976e010a72778091d633a',1,'IRDaikin2::enableOffTimer()'],['../classIRWhirlpoolAc.html#abb1c3685d90d81b44e72050cd0e042f6',1,'IRWhirlpoolAc::enableOffTimer()']]], + ['enableontimer_237',['enableOnTimer',['../classIRDaikinESP.html#aac4d0f5f60c9f4c41d3bb1e0f24bc4bc',1,'IRDaikinESP::enableOnTimer()'],['../classIRDaikin2.html#a91ec5f7c67cb87102a5eb030e0763b50',1,'IRDaikin2::enableOnTimer()'],['../classIRWhirlpoolAc.html#aa3edd58882cf4fc65172e490c9e0bb2e',1,'IRWhirlpoolAc::enableOnTimer()']]], + ['enablesleeptimer_238',['enableSleepTimer',['../classIRDaikin2.html#a9c86782a98a54818ae92419eec5a060b',1,'IRDaikin2']]], + ['enabletimer_239',['enableTimer',['../classIRWhirlpoolAc.html#ad07804318721bc5dd60f7322e02c9696',1,'IRWhirlpoolAc']]], + ['encodedoshisha_240',['encodeDoshisha',['../classIRsend.html#a0522a2256e8358df715065530be6317d',1,'IRsend']]], + ['encodejvc_241',['encodeJVC',['../classIRsend.html#a6303b991c0545443e7ccf63ba89dbf18',1,'IRsend']]], + ['encodelg_242',['encodeLG',['../classIRsend.html#a109b67a68e7a33900cb5c5017ed4578b',1,'IRsend']]], + ['encodemagiquest_243',['encodeMagiQuest',['../classIRsend.html#a4ee40126279dbde8bb02888115577563',1,'IRsend']]], + ['encodenec_244',['encodeNEC',['../classIRsend.html#ab2e1ce918e4e06b955c3d2a089ce189c',1,'IRsend']]], + ['encodepanasonic_245',['encodePanasonic',['../classIRsend.html#a8340497ae75f00c844e53dfc73700d9c',1,'IRsend']]], + ['encodepioneer_246',['encodePioneer',['../classIRsend.html#ae0686829eba31587b71034a1c0495971',1,'IRsend']]], + ['encoderc5_247',['encodeRC5',['../classIRsend.html#a88457fd4cc01d6e8097e04c022ede74a',1,'IRsend']]], + ['encoderc5x_248',['encodeRC5X',['../classIRsend.html#ae760ef1be11f25f7a61237f96a8871d9',1,'IRsend']]], + ['encoderc6_249',['encodeRC6',['../classIRsend.html#ac0e341462426ea146b944502a6d3fde0',1,'IRsend']]], + ['encodesamsung_250',['encodeSAMSUNG',['../classIRsend.html#a4ab0579bd854306b2667de19207e4ffb',1,'IRsend']]], + ['encodesanyolc7461_251',['encodeSanyoLC7461',['../classIRsend.html#a864bef0dc48f6af4b59057362906cf5d',1,'IRsend']]], + ['encodesharp_252',['encodeSharp',['../classIRsend.html#a8f4c7a36380ba31155eba5ff8f5f631e',1,'IRsend']]], + ['encodesony_253',['encodeSony',['../classIRsend.html#aa0aea2cb04f0a7ee9056f15fecfc08c3',1,'IRsend']]], + ['encodetime_254',['encodeTime',['../classIRPanasonicAc.html#a0eee4ad6105d35ee6c34c4666174b04b',1,'IRPanasonicAc']]], + ['epson_255',['EPSON',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadaaf677fd380c38297264a10732631927c',1,'IRremoteESP8266.h']]], + ['es_2des_2eh_256',['es-ES.h',['../es-ES_8h.html',1,'']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_6.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_6.html new file mode 100644 index 000000000..43f14eab3 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_6.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_6.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_6.js new file mode 100644 index 000000000..3952b75de --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_6.js @@ -0,0 +1,15 @@ +var searchData= +[ + ['fahrenheittocelsius_257',['fahrenheitToCelsius',['../IRutils_8cpp.html#a83538e86145850c24b1c824723089502',1,'fahrenheitToCelsius(const float deg): IRutils.cpp'],['../IRutils_8h.html#a83538e86145850c24b1c824723089502',1,'fahrenheitToCelsius(const float deg): IRutils.cpp']]], + ['fanspeed_258',['fanspeed',['../structstdAc_1_1state__t.html#a28a50c877a0eaa71689ccc3bf9c957d7',1,'stdAc::state_t']]], + ['fanspeed_5ft_259',['fanspeed_t',['../namespacestdAc.html#a8bb0dbf18fe69f639f4ac0b3ff133383',1,'stdAc']]], + ['fanspeedtostring_260',['fanspeedToString',['../classIRac.html#ab8d8a1ce5de8970c07c90fb41731e2e6',1,'IRac']]], + ['filter_261',['filter',['../structstdAc_1_1state__t.html#a41e4b957f9e011ddb32d35bfcd56c0e7',1,'stdAc::state_t']]], + ['fixchecksum_262',['fixChecksum',['../classIRPanasonicAc.html#aa40bef35000ddf6d14e286b3f2044897',1,'IRPanasonicAc']]], + ['fixup_263',['fixup',['../classIRGreeAC.html#a5bbdcc83f9d49e32379cd27cad0ba130',1,'IRGreeAC::fixup()'],['../classIRKelvinatorAC.html#a389af589003c39794ae5d4bd572fa485',1,'IRKelvinatorAC::fixup()']]], + ['flap_5fmode_264',['flap_mode',['../classIRArgoAC.html#abfc383d92ced7d47945cc5ac996e5fc4',1,'IRArgoAC']]], + ['fr_2dfr_2eh_265',['fr-FR.h',['../fr-FR_8h.html',1,'']]], + ['fujitsu_266',['fujitsu',['../classIRac.html#a23cf80270562ca28ae1f1da2bbb559e7',1,'IRac']]], + ['fujitsu_5fac_267',['FUJITSU_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadad8cf99a3a8776d644b78313306a2108c',1,'IRremoteESP8266.h']]], + ['fujitsu_5fac_5fremote_5fmodel_5ft_268',['fujitsu_ac_remote_model_t',['../IRsend_8h.html#a7204e78a1fe37a819c0b66f87a685dc0',1,'IRsend.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_7.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_7.html new file mode 100644 index 000000000..af52f82a4 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_7.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_7.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_7.js new file mode 100644 index 000000000..7437f2c8e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_7.js @@ -0,0 +1,118 @@ +var searchData= +[ + ['ge6711ar2853m_269',['GE6711AR2853M',['../IRsend_8h.html#a50c54713e16502d280723334879dc83bada534bddbb58907faa6c7eae385ec790',1,'IRsend.h']]], + ['get3d_270',['get3D',['../classIRMitsubishiHeavy152Ac.html#ab55c9e587d472baf6a6d9cb61c733b08',1,'IRMitsubishiHeavy152Ac::get3D()'],['../classIRMitsubishiHeavy88Ac.html#ad5171595fef2360f50d7991897c40632',1,'IRMitsubishiHeavy88Ac::get3D()']]], + ['get8cheat_271',['get8CHeat',['../classIRNeoclimaAc.html#aee5b855ce2decb455eaaceb6b4913368',1,'IRNeoclimaAc']]], + ['getbeep_272',['getBeep',['../classIRDaikin2.html#ab6cc9737950ac0ab476bb240897902ec',1,'IRDaikin2::getBeep()'],['../classIRSamsungAc.html#ab13b10f80e8e1169f0b01239f357b3ba',1,'IRSamsungAc::getBeep()']]], + ['getbit_273',['getBit',['../namespaceirutils.html#ac0756774b20e4f7c836abee466800ee6',1,'irutils::getBit(const uint64_t data, const uint8_t position, const uint8_t size)'],['../namespaceirutils.html#a27f90f74ed0b7af37c7bd8cd2a059dee',1,'irutils::getBit(const uint8_t data, const uint8_t position)']]], + ['getboost_274',['getBoost',['../classIRDelonghiAc.html#abf9fd996c60573eca50b5e165cbcbf63',1,'IRDelonghiAc']]], + ['getbreeze_275',['getBreeze',['../classIRSamsungAc.html#ad46fed65fb1375bf3a3940aa2cb311d5',1,'IRSamsungAc']]], + ['getbufsize_276',['getBufSize',['../classIRrecv.html#a69ab02ea6823ccf18d1f6be87ca1b92e',1,'IRrecv']]], + ['getbutton_277',['getButton',['../classIRHaierACYRW02.html#af4df303e5662aa63cba715ff49e09b75',1,'IRHaierACYRW02::getButton()'],['../classIRHitachiAc424.html#a32fa646e61cbaca805f33995344732cc',1,'IRHitachiAc424::getButton()'],['../classIRNeoclimaAc.html#a747fec9ea02220e6cf7465f5f9bb800a',1,'IRNeoclimaAc::getButton()']]], + ['getclean_278',['getClean',['../classIRCoolixAC.html#a272f94ef641041835a650dd4fbdda7bf',1,'IRCoolixAC::getClean()'],['../classIRDaikin2.html#a7930bbca261f07ef1c129cd6a2c848b4',1,'IRDaikin2::getClean()'],['../classIRElectraAc.html#aa06b1246aaa3f25b239b50e395258b7a',1,'IRElectraAc::getClean()'],['../classIRFujitsuAC.html#a4bf872038fc175d1496eae25e9fcdce3',1,'IRFujitsuAC::getClean()'],['../classIRMitsubishiHeavy152Ac.html#a8e7c2759efe24e580d5886600f513648',1,'IRMitsubishiHeavy152Ac::getClean()'],['../classIRMitsubishiHeavy88Ac.html#a54eafb2474559371393c3ec3ba560d3a',1,'IRMitsubishiHeavy88Ac::getClean()'],['../classIRSamsungAc.html#a789edd6c6b0cb291753204d1e9c78fc8',1,'IRSamsungAc::getClean()'],['../classIRSharpAc.html#a599032d1101f15b98ffa9aa3039bc7d6',1,'IRSharpAc::getClean()']]], + ['getclock_279',['getClock',['../classIRDaikin128.html#a6ef4d58f53b35619e8cc44fae6125490',1,'IRDaikin128::getClock()'],['../classIRDaikin64.html#a676ecda2ad53f78ef5cbf470f524918e',1,'IRDaikin64::getClock()'],['../classIRMitsubishiAC.html#a8918c5b8a72d58282b160c8fde9866ad',1,'IRMitsubishiAC::getClock()'],['../classIRPanasonicAc.html#a084479e8f23f7dbb8f155209b36efb3b',1,'IRPanasonicAc::getClock()'],['../classIRWhirlpoolAc.html#a329e06f4c44fa9aef42952f2d123b7a8',1,'IRWhirlpoolAc::getClock()']]], + ['getcmd_280',['getCmd',['../classIRFujitsuAC.html#a758d209fd0e07cb200b2d4a232b6b0a2',1,'IRFujitsuAC']]], + ['getcomfort_281',['getComfort',['../classIRDaikinESP.html#a4377e48a16a6ed1cb4fb2b711e672b16',1,'IRDaikinESP::getComfort()'],['../classIRDaikin152.html#a22cc2073fd7d4a609c335172ff6720cf',1,'IRDaikin152::getComfort()']]], + ['getcommand_282',['getCommand',['../classIRGoodweatherAc.html#aa2a24e8c783cb5b463a95fa05779456e',1,'IRGoodweatherAc::getCommand()'],['../classIRHaierAC.html#a3a291fccea5f4b32f83da2605d2a82e0',1,'IRHaierAC::getCommand()'],['../classIRWhirlpoolAc.html#ab1c34a9498bc2c8da8e4bdcfe4bf011a',1,'IRWhirlpoolAc::getCommand()']]], + ['getcorrectedrawlength_283',['getCorrectedRawLength',['../IRutils_8cpp.html#aad5f25cf6a2dded8b48f4a6dd16857be',1,'getCorrectedRawLength(const decode_results *const results): IRutils.cpp'],['../IRutils_8h.html#aad5f25cf6a2dded8b48f4a6dd16857be',1,'getCorrectedRawLength(const decode_results *const results): IRutils.cpp']]], + ['getcurrentday_284',['getCurrentDay',['../classIRDaikinESP.html#ad0ecc69b2ab3e7678c8e4e8d64949077',1,'IRDaikinESP']]], + ['getcurrenttime_285',['getCurrentTime',['../classIRDaikinESP.html#a724c204890e6810d150ed54794c9a505',1,'IRDaikinESP::getCurrentTime()'],['../classIRDaikin2.html#a94dc89b80dfdee2afa718314ec522b53',1,'IRDaikin2::getCurrentTime()']]], + ['getcurrtime_286',['getCurrTime',['../classIRHaierAC.html#aa0e05983088035f6d85c520843922c25',1,'IRHaierAC']]], + ['getdisplay_287',['getDisplay',['../classIRSamsungAc.html#a890aa3cab0918fda56daf0bf84ecc5c1',1,'IRSamsungAc']]], + ['getdisplaytempsource_288',['getDisplayTempSource',['../classIRGreeAC.html#adea5a2d2b3a9d699c722e7a93784809e',1,'IRGreeAC']]], + ['getecono_289',['getEcono',['../classIRCoronaAc.html#a0b8413e2a7aeecc5c0c55049c1705c38',1,'IRCoronaAc::getEcono()'],['../classIRDaikinESP.html#a84337719e737ea4dc1e1fb10f6f7df92',1,'IRDaikinESP::getEcono()'],['../classIRDaikin2.html#ad8098fa67e8808eebfad7611b6fc7881',1,'IRDaikin2::getEcono()'],['../classIRDaikin128.html#a0c05f4c6f996d56d56075e20a46f2c2c',1,'IRDaikin128::getEcono()'],['../classIRDaikin152.html#a9946c73f0c5906fbb2f39119e00531e5',1,'IRDaikin152::getEcono()'],['../classIRMitsubishiHeavy152Ac.html#aa7814232c84ff918f1d05ec105abf851',1,'IRMitsubishiHeavy152Ac::getEcono()'],['../classIRMitsubishiHeavy88Ac.html#af3accae413215cdd45a180f22bbe443e',1,'IRMitsubishiHeavy88Ac::getEcono()'],['../classIRTcl112Ac.html#afabe458a354d822f3ff929a461b6e046',1,'IRTcl112Ac::getEcono()']]], + ['geteconotoggle_290',['getEconoToggle',['../classIRSharpAc.html#a701542019d3a823ba203f0db3cfce353',1,'IRSharpAc']]], + ['geteye_291',['getEye',['../classIRDaikin2.html#a02fbd472d3c79b2391fc11da692c8998',1,'IRDaikin2::getEye()'],['../classIRNeoclimaAc.html#a15b91e2c854537d94cbabd7cd9bd30e4',1,'IRNeoclimaAc::getEye()']]], + ['geteyeauto_292',['getEyeAuto',['../classIRDaikin2.html#a0cae45648292bdee8092a30338975ed0',1,'IRDaikin2']]], + ['getfan_293',['getFan',['../classIRAmcorAc.html#a8ba84d83fc426ee5b75e0be27fd22d9c',1,'IRAmcorAc::getFan()'],['../classIRArgoAC.html#a413e60e09f1abcf231a173e1374e51e0',1,'IRArgoAC::getFan()'],['../classIRCarrierAc64.html#a93bb27688657af434d57f0dd9a159566',1,'IRCarrierAc64::getFan()'],['../classIRCoolixAC.html#a937c0084f79eaef2a160331993dfb881',1,'IRCoolixAC::getFan()'],['../classIRCoronaAc.html#aa51ccd3684009d5a56bbde73eab7ccfa',1,'IRCoronaAc::getFan()'],['../classIRDaikinESP.html#addad5838bb00885df8af258a61fa4131',1,'IRDaikinESP::getFan()'],['../classIRDaikin2.html#aafe89842b356c288dd38d256f9eb050c',1,'IRDaikin2::getFan()'],['../classIRDaikin216.html#a0905e04fc3d21249b057aa79721c1614',1,'IRDaikin216::getFan()'],['../classIRDaikin160.html#a2eb3987f87d19e1ab01dac111ae2d16b',1,'IRDaikin160::getFan()'],['../classIRDaikin176.html#a59c3d23a5e1b7c69c05690cf7984dab8',1,'IRDaikin176::getFan()'],['../classIRDaikin128.html#a68a7bdb134ea62913f51844f976beab1',1,'IRDaikin128::getFan()'],['../classIRDaikin152.html#a64eacdc63547026477b5f861e7da62ea',1,'IRDaikin152::getFan()'],['../classIRDaikin64.html#abdd4bc3d5464b5297b4f2fd0e7a831e1',1,'IRDaikin64::getFan()'],['../classIRDelonghiAc.html#afd2ed0ec70e3912335a9174bca7e7f5e',1,'IRDelonghiAc::getFan()'],['../classIRElectraAc.html#a6e8b30452671c26777ba2bc556bc8dce',1,'IRElectraAc::getFan()'],['../classIRGoodweatherAc.html#ac1ac922370ad09a80dd4e7158b279b9f',1,'IRGoodweatherAc::getFan()'],['../classIRGreeAC.html#a0bf5a552490c7500f0584affacac13d0',1,'IRGreeAC::getFan()'],['../classIRHaierAC.html#a5b15678e94acc14a0bb86bff61230e93',1,'IRHaierAC::getFan()'],['../classIRHaierACYRW02.html#a6de2fb6111049720913eb28bf6f64a00',1,'IRHaierACYRW02::getFan()'],['../classIRHitachiAc.html#a6a5f5b9544e93e842f76a2f4994c1665',1,'IRHitachiAc::getFan()'],['../classIRHitachiAc1.html#af1c6acc2ff9946af7091695b616c2cac',1,'IRHitachiAc1::getFan()'],['../classIRHitachiAc424.html#ab3ecfb8b6fb503ba3eed023609f2fe7b',1,'IRHitachiAc424::getFan()'],['../classIRKelvinatorAC.html#a64ce2ccf879217410269230218e0c76b',1,'IRKelvinatorAC::getFan()'],['../classIRLgAc.html#a10d666ca13c99696a53dca7f5773d7de',1,'IRLgAc::getFan()'],['../classIRMideaAC.html#ab793e409c666e001242623a2607786e7',1,'IRMideaAC::getFan()'],['../classIRMitsubishiAC.html#a06cb4179b92af1b1d3c167659c30db95',1,'IRMitsubishiAC::getFan()'],['../classIRMitsubishi136.html#a61b0a21a32eb1211cab201587de6f7ce',1,'IRMitsubishi136::getFan()'],['../classIRMitsubishi112.html#a00446fe1fdf27012acd41303b711e575',1,'IRMitsubishi112::getFan()'],['../classIRMitsubishiHeavy152Ac.html#a957abe79b7966da644db091ffe75d73b',1,'IRMitsubishiHeavy152Ac::getFan()'],['../classIRMitsubishiHeavy88Ac.html#ac00255061012eef8d62f44e478839d7e',1,'IRMitsubishiHeavy88Ac::getFan()'],['../classIRNeoclimaAc.html#a8690eda2de7b00029f70304131388890',1,'IRNeoclimaAc::getFan()'],['../classIRPanasonicAc.html#a302ba64400c820a5a0d822315516564a',1,'IRPanasonicAc::getFan()'],['../classIRSamsungAc.html#a6461c72b2598d1bdc14263552b5b0c98',1,'IRSamsungAc::getFan()'],['../classIRSharpAc.html#abae439959603f62b0fe5aea8ec93afb5',1,'IRSharpAc::getFan()'],['../classIRTcl112Ac.html#af59bcc28ac97869595a5ad928300908b',1,'IRTcl112Ac::getFan()'],['../classIRTecoAc.html#a420b209010276b30c9bc322b7393b3be',1,'IRTecoAc::getFan()'],['../classIRToshibaAC.html#afd2000b62b79afde107ebc8a513724ab',1,'IRToshibaAC::getFan()'],['../classIRVestelAc.html#a492abc867ad5b766715eaa301c71f3c8',1,'IRVestelAc::getFan()'],['../classIRWhirlpoolAc.html#a80fedb2ddec4a3dbb2c96b5a76a26e1a',1,'IRWhirlpoolAc::getFan()']]], + ['getfanspeed_294',['getFanSpeed',['../classIRFujitsuAC.html#aacb180bb884b80c1f8bbbed7e2dd23d5',1,'IRFujitsuAC']]], + ['getfilter_295',['getFilter',['../classIRFujitsuAC.html#a430ed6a4b946d1b4527741b42e12a25c',1,'IRFujitsuAC::getFilter()'],['../classIRMitsubishiHeavy152Ac.html#aaf2864f7187acd1b75d9daad2d504c13',1,'IRMitsubishiHeavy152Ac::getFilter()']]], + ['getflap_296',['getFlap',['../classIRArgoAC.html#a2285908626731c2feaa85635f3ce1ff1',1,'IRArgoAC']]], + ['getfollow_297',['getFollow',['../classIRNeoclimaAc.html#af4ed34fe7b151bcc5ff6922a54427da0',1,'IRNeoclimaAc']]], + ['getfresh_298',['getFresh',['../classIRNeoclimaAc.html#a2c411cf55667339ff8e3664a6d0ee843',1,'IRNeoclimaAc']]], + ['getfreshair_299',['getFreshAir',['../classIRDaikin2.html#aad50061042e14f665e5ecbd85ac48741',1,'IRDaikin2']]], + ['getfreshairhigh_300',['getFreshAirHigh',['../classIRDaikin2.html#a72c8d47c2e6664eb0e40efe6933e4ac1',1,'IRDaikin2']]], + ['gethealth_301',['getHealth',['../classIRHaierAC.html#a5c69955fe18f4ddb0286084f3fb39228',1,'IRHaierAC::getHealth()'],['../classIRHaierACYRW02.html#a97fc67cddf50a51b0db6c4e22fcaafa1',1,'IRHaierACYRW02::getHealth()'],['../classIRTcl112Ac.html#adf484b6a4097dd8834c202c81fea0ad4',1,'IRTcl112Ac::getHealth()']]], + ['gethold_302',['getHold',['../classIRNeoclimaAc.html#a63045d768858265ed1bbc4c337de79eb',1,'IRNeoclimaAc']]], + ['gethumid_303',['getHumid',['../classIRTecoAc.html#a30012508c6ba93ad07185a13795c5909',1,'IRTecoAc']]], + ['getifeel_304',['getiFeel',['../classIRArgoAC.html#abc802d8ab9dbd9f918bc2aa36d2ea414',1,'IRArgoAC::getiFeel()'],['../classIRGreeAC.html#ae1f8352fc32fa773bb33243cc32657a2',1,'IRGreeAC::getIFeel()']]], + ['getion_305',['getIon',['../classIRNeoclimaAc.html#a908a65189ba6eb8141d50da000feec0a',1,'IRNeoclimaAc::getIon()'],['../classIRPanasonicAc.html#a6d6909b7b96815c227f0009dcbd3ce8c',1,'IRPanasonicAc::getIon()'],['../classIRSamsungAc.html#aab1ebb523ca45431a0127b82cb4ce36f',1,'IRSamsungAc::getIon()'],['../classIRSharpAc.html#a1de89912129d0a1fffbd51625a1eeab7',1,'IRSharpAc::getIon()'],['../classIRVestelAc.html#a835f194f14479c25a3d651f324e6436c',1,'IRVestelAc::getIon()']]], + ['getionfilter_306',['getIonFilter',['../classIRKelvinatorAC.html#a81127edca40e504c432b2079030f84a5',1,'IRKelvinatorAC']]], + ['getled_307',['getLed',['../classIRCoolixAC.html#aa7712ebbf103c4d61dc645cb42dcf3f0',1,'IRCoolixAC']]], + ['getlight_308',['getLight',['../classIRDaikin2.html#ada92da390d8b4247a014057c3d6fa296',1,'IRDaikin2::getLight()'],['../classIRGoodweatherAc.html#a90454990d7f9cde54ab5a11170d5e97d',1,'IRGoodweatherAc::getLight()'],['../classIRGreeAC.html#ae63281a9caf850429857cc3fa99ccf05',1,'IRGreeAC::getLight()'],['../classIRKelvinatorAC.html#a85e77c7a1b763373b0732d125923f53f',1,'IRKelvinatorAC::getLight()'],['../classIRNeoclimaAc.html#ad87fc87e34c3de56c4bbe35443e92226',1,'IRNeoclimaAc::getLight()'],['../classIRTcl112Ac.html#ae711a585331ffab24f96b0bb0f3960ed',1,'IRTcl112Ac::getLight()'],['../classIRTecoAc.html#a12a2bb7a5d3c90139dba85d54a535b8f',1,'IRTecoAc::getLight()'],['../classIRWhirlpoolAc.html#a87f2274da6101e1c2e78eb4e68aadff0',1,'IRWhirlpoolAc::getLight()']]], + ['getlighttoggle_309',['getLightToggle',['../classIRDaikin128.html#a3e279e67bbafc0dc74dbd847e2e8ad75',1,'IRDaikin128::getLightToggle()'],['../classIRElectraAc.html#a63bc44235b18e11531479dc2f633f94b',1,'IRElectraAc::getLightToggle()']]], + ['getmax_310',['getMax',['../classIRAmcorAc.html#a61659b6b54d652713efdf408a09db087',1,'IRAmcorAc::getMax()'],['../classIRArgoAC.html#aff24da9d975bf1f6df0a83be2ad7a913',1,'IRArgoAC::getMax()']]], + ['getmode_311',['getMode',['../classIRAmcorAc.html#a30fd2a228e63e6b9a1544c3c1ec910f7',1,'IRAmcorAc::getMode()'],['../classIRArgoAC.html#a532a313f22c716b60cee070d9ba0839d',1,'IRArgoAC::getMode()'],['../classIRCarrierAc64.html#a4f8e0435a086ec934b10e9bd66f2ae85',1,'IRCarrierAc64::getMode()'],['../classIRCoolixAC.html#a16772a297404e2c54f951c49bfc608de',1,'IRCoolixAC::getMode()'],['../classIRCoronaAc.html#aa6ccd147a1da55d5e9596159008d40de',1,'IRCoronaAc::getMode()'],['../classIRDaikinESP.html#a164452703a7a6d46766acc85aab63898',1,'IRDaikinESP::getMode()'],['../classIRDaikin2.html#a681279a765159550ac1ec84895fff4d2',1,'IRDaikin2::getMode()'],['../classIRDaikin216.html#a21b3e93f98ac55e743efe38c20617d6a',1,'IRDaikin216::getMode()'],['../classIRDaikin160.html#a2b890fe446db67acd828fefd4afef84f',1,'IRDaikin160::getMode()'],['../classIRDaikin176.html#a1fc59660d77eb9dc3a8361d7d4698cd9',1,'IRDaikin176::getMode()'],['../classIRDaikin128.html#aa3d96e14663c498a6e0938ba04a02f87',1,'IRDaikin128::getMode()'],['../classIRDaikin152.html#af4c6c468f3075ffa83694a0da15a707b',1,'IRDaikin152::getMode()'],['../classIRDaikin64.html#a96624667a4494087074792562090b552',1,'IRDaikin64::getMode()'],['../classIRDelonghiAc.html#a89d9fa5b2c4a59b46cac111418232090',1,'IRDelonghiAc::getMode()'],['../classIRElectraAc.html#a473a794960bc07837e407830a3ea528b',1,'IRElectraAc::getMode()'],['../classIRFujitsuAC.html#a5f9630d81acffc74434ce852b9523d17',1,'IRFujitsuAC::getMode()'],['../classIRGoodweatherAc.html#a622e11c7b236fa127008f990819eca75',1,'IRGoodweatherAc::getMode()'],['../classIRGreeAC.html#abb5c4a29000c8b22b25e150e7ef5a6c3',1,'IRGreeAC::getMode()'],['../classIRHaierAC.html#aa180c60030d9972807238cceba886ff5',1,'IRHaierAC::getMode()'],['../classIRHaierACYRW02.html#aec7359fb8c796fc45577a40370f874c9',1,'IRHaierACYRW02::getMode()'],['../classIRHitachiAc.html#a414a4083e15deb1890a1eab4827d78ac',1,'IRHitachiAc::getMode()'],['../classIRHitachiAc1.html#afc4fdc94989297b73e08e9c82bd00733',1,'IRHitachiAc1::getMode()'],['../classIRHitachiAc424.html#ac1bf6df8277d50dcad8e389b21971e24',1,'IRHitachiAc424::getMode()'],['../classIRHitachiAc3.html#a511c9b731a0367fd05b32b42a69adec2',1,'IRHitachiAc3::getMode()'],['../classIRKelvinatorAC.html#a7a0f8f587fdda24db12db7aace478fd6',1,'IRKelvinatorAC::getMode()'],['../classIRLgAc.html#a19752b31eb74aad0cc9538a2f0af8b8c',1,'IRLgAc::getMode()'],['../classIRMideaAC.html#a1b5d19958e11a85d1af09b15631af124',1,'IRMideaAC::getMode()'],['../classIRMitsubishiAC.html#a069fd1d3bea102968e74b312fdf01548',1,'IRMitsubishiAC::getMode()'],['../classIRMitsubishi136.html#a3176aec8444f500bdea6e650cee2dbcc',1,'IRMitsubishi136::getMode()'],['../classIRMitsubishi112.html#ac2006f1e33f2a0cebcb6c23fcac389bb',1,'IRMitsubishi112::getMode()'],['../classIRMitsubishiHeavy152Ac.html#af0a51f8195492aac62bea483cb9a392c',1,'IRMitsubishiHeavy152Ac::getMode()'],['../classIRMitsubishiHeavy88Ac.html#ae8e1263a77b8fb04c2a4a5d6ce9805f9',1,'IRMitsubishiHeavy88Ac::getMode()'],['../classIRNeoclimaAc.html#ad2a43e0405a44787bb177bf13a324dde',1,'IRNeoclimaAc::getMode()'],['../classIRPanasonicAc.html#a5ffd59dd87b047e172ba74866267a9f3',1,'IRPanasonicAc::getMode()'],['../classIRSamsungAc.html#a740a874ee2c492027623943043a1ebf6',1,'IRSamsungAc::getMode()'],['../classIRSharpAc.html#adbccabd2ec614c8b921a02af8b529b4e',1,'IRSharpAc::getMode()'],['../classIRTcl112Ac.html#ad1b6538977bc464f1e6719b5cea89945',1,'IRTcl112Ac::getMode()'],['../classIRTecoAc.html#a4200081a4d42f2ec06935f71c4870e67',1,'IRTecoAc::getMode()'],['../classIRToshibaAC.html#aba5db1f6c8665443f26875ee9716302f',1,'IRToshibaAC::getMode()'],['../classIRTrotecESP.html#ab1b08911e9b76a06a08f4c7b8a2244c0',1,'IRTrotecESP::getMode()'],['../classIRVestelAc.html#ae5b3d9f1420f4d1951ba148399ccbd41',1,'IRVestelAc::getMode()'],['../classIRWhirlpoolAc.html#a4d2896e42e9c5ee1e8dc8f7e917618dc',1,'IRWhirlpoolAc::getMode()']]], + ['getmodel_312',['getModel',['../classIRFujitsuAC.html#a35c6bfb730014f3a24676f94e8308163',1,'IRFujitsuAC::getModel()'],['../classIRGreeAC.html#a3780fc11488a2b40f3c1a50bb94783c7',1,'IRGreeAC::getModel()'],['../classIRHitachiAc1.html#a9ad677e1a2d7acba032701051538b08a',1,'IRHitachiAc1::getModel()'],['../classIRLgAc.html#aa49cde438a42a5415e127cc95da465ac',1,'IRLgAc::getModel()'],['../classIRPanasonicAc.html#a625be846baf3ec556a59379785e642e8',1,'IRPanasonicAc::getModel()'],['../classIRWhirlpoolAc.html#ac55e17fde1ef2acf6524d936732a0469',1,'IRWhirlpoolAc::getModel()']]], + ['getmold_313',['getMold',['../classIRDaikinESP.html#ad593ac32c01752f56e9476af234cf813',1,'IRDaikinESP::getMold()'],['../classIRDaikin2.html#a330b3a8f25bd2d053dab318126b32569',1,'IRDaikin2::getMold()']]], + ['getnight_314',['getNight',['../classIRArgoAC.html#adca87781240cf9c22e6bbaad9d59537c',1,'IRArgoAC::getNight()'],['../classIRMitsubishiHeavy152Ac.html#a659036b987991f39daa13fbd23b35f35',1,'IRMitsubishiHeavy152Ac::getNight()']]], + ['getnormalstate_315',['getNormalState',['../classIRCoolixAC.html#a458618f926f8b57e4b9bdeae0d13a70d',1,'IRCoolixAC']]], + ['getofftime_316',['getOffTime',['../classIRDaikinESP.html#a5213017d706cd6bce88cbfb65150bdb5',1,'IRDaikinESP::getOffTime()'],['../classIRDaikin2.html#af3a47c7b99cec3b108b5173cf1ae7da4',1,'IRDaikin2::getOffTime()'],['../classIRDaikin64.html#a7f163901c3b5065e393e3ae0e01d599a',1,'IRDaikin64::getOffTime()']]], + ['getofftimeenabled_317',['getOffTimeEnabled',['../classIRDaikin64.html#a9ebf2deb196caece88c286d8c03bb69a',1,'IRDaikin64']]], + ['getofftimer_318',['getOffTimer',['../classIRCarrierAc64.html#a6a28f83442d695385f76f13913c76542',1,'IRCarrierAc64::getOffTimer()'],['../classIRCoronaAc.html#a4602f36769e6b135fec8802a3b087adf',1,'IRCoronaAc::getOffTimer()'],['../classIRDaikin128.html#a6a18b029d75b006de5aeac2efb8e08e2',1,'IRDaikin128::getOffTimer()'],['../classIRDelonghiAc.html#acd32fa9acbc9782df9aa00325efea2a7',1,'IRDelonghiAc::getOffTimer()'],['../classIRHaierAC.html#a8b5c970b3204aa447d86dc2941dbd7b1',1,'IRHaierAC::getOffTimer()'],['../classIRHitachiAc1.html#ab99d73871d3510a830f988628dc5e33d',1,'IRHitachiAc1::getOffTimer()'],['../classIRPanasonicAc.html#a4bce377d32504f666662f1d93645761f',1,'IRPanasonicAc::getOffTimer()'],['../classIRVestelAc.html#a575ba7c6aee1d2377975ef0ef938775a',1,'IRVestelAc::getOffTimer()'],['../classIRWhirlpoolAc.html#a05e1308970e0169d6a081baf120efd9f',1,'IRWhirlpoolAc::getOffTimer()']]], + ['getofftimerenabled_319',['getOffTimerEnabled',['../classIRDaikinESP.html#af6388cd6d2189f9067b708d46917a83a',1,'IRDaikinESP::getOffTimerEnabled()'],['../classIRDaikin2.html#a7a413002b64497a5fce7cdcdd6924e8f',1,'IRDaikin2::getOffTimerEnabled()'],['../classIRDaikin128.html#a4234e0e3ff261afa9d5ec6a8b92d8f53',1,'IRDaikin128::getOffTimerEnabled()'],['../classIRDelonghiAc.html#ac1b91f6d4bb5e41e43fc7e4b9a3187a3',1,'IRDelonghiAc::getOffTimerEnabled()']]], + ['getontime_320',['getOnTime',['../classIRDaikinESP.html#a8a6730accc69647cbc12ebc99b2cfb77',1,'IRDaikinESP::getOnTime()'],['../classIRDaikin2.html#ad62f28698595be7717f0f29a5396853d',1,'IRDaikin2::getOnTime()'],['../classIRDaikin64.html#a9b316390ffc3e81d423d3e4b326be7d4',1,'IRDaikin64::getOnTime()']]], + ['getontimeenabled_321',['getOnTimeEnabled',['../classIRDaikin64.html#a0b9795a5536566fe2f9b713aaff4b9ee',1,'IRDaikin64']]], + ['getontimer_322',['getOnTimer',['../classIRCarrierAc64.html#a071ebd204e56e2cd771281b1c42b9cb5',1,'IRCarrierAc64::getOnTimer()'],['../classIRCoronaAc.html#a7beec38ab35dbebe955c4da188de25d5',1,'IRCoronaAc::getOnTimer()'],['../classIRDaikin128.html#a3b8a36d99a7cbf87bac8480f16c3d583',1,'IRDaikin128::getOnTimer()'],['../classIRDelonghiAc.html#a03f6d037d62d3c641b45ec97a1bff715',1,'IRDelonghiAc::getOnTimer()'],['../classIRHaierAC.html#a99d3339eb5ecdbf1c86e85408507af7b',1,'IRHaierAC::getOnTimer()'],['../classIRHitachiAc1.html#a9d5846c1efcc8fae1eeb6079a61cb18b',1,'IRHitachiAc1::getOnTimer()'],['../classIRPanasonicAc.html#a51d50a59e09f0911022c59ab60bf4889',1,'IRPanasonicAc::getOnTimer()'],['../classIRVestelAc.html#aa39e3047ea694ada9cc7e992e7b03e32',1,'IRVestelAc::getOnTimer()'],['../classIRWhirlpoolAc.html#a26c00db3316585e32d64428d6732fcd0',1,'IRWhirlpoolAc::getOnTimer()']]], + ['getontimerenabled_323',['getOnTimerEnabled',['../classIRDaikinESP.html#a45e473403547c8ec95a50aeb1ed93607',1,'IRDaikinESP::getOnTimerEnabled()'],['../classIRDaikin2.html#a8921edb7885d728ee5294fa03cb13a87',1,'IRDaikin2::getOnTimerEnabled()'],['../classIRDaikin128.html#a450948bdbdc22da751c8f1abc2da642d',1,'IRDaikin128::getOnTimerEnabled()'],['../classIRDelonghiAc.html#a0911f40ee5838bfc6b7deb3193e6a62a',1,'IRDelonghiAc::getOnTimerEnabled()']]], + ['getoutsidequiet_324',['getOutsideQuiet',['../classIRFujitsuAC.html#a404a06b5022899e622e629ec099864f5',1,'IRFujitsuAC']]], + ['getpower_325',['getPower',['../classIRAmcorAc.html#a141e2af9eb4530b175a430dee31bc5ae',1,'IRAmcorAc::getPower()'],['../classIRArgoAC.html#a10812d30095c4adc24cb3eee25e2d246',1,'IRArgoAC::getPower()'],['../classIRCarrierAc64.html#ad50ebb44815e55cc0a99f4762939dc54',1,'IRCarrierAc64::getPower()'],['../classIRCoolixAC.html#a150e3b827d8002e77135955079c78704',1,'IRCoolixAC::getPower()'],['../classIRCoronaAc.html#a313c5489b53bba5747e871ec0a7af417',1,'IRCoronaAc::getPower()'],['../classIRDaikinESP.html#a1d72647db12276493d8e093a4feda44e',1,'IRDaikinESP::getPower()'],['../classIRDaikin2.html#a2f25c4ff097f82a91c062aacd5ebabfc',1,'IRDaikin2::getPower()'],['../classIRDaikin216.html#a2b1e1dd2a059466ab5e5c8ab7eb4f2b4',1,'IRDaikin216::getPower()'],['../classIRDaikin160.html#ad472f0d0680da6ab83a1b636bc00e271',1,'IRDaikin160::getPower()'],['../classIRDaikin176.html#ad564616fc1bf90c00c594c2d3cb5394d',1,'IRDaikin176::getPower()'],['../classIRDaikin152.html#a8581147072fecf6ebd0dd2da50a63f05',1,'IRDaikin152::getPower()'],['../classIRDelonghiAc.html#ae077f0e444fcf24b1e0343e93244b7e8',1,'IRDelonghiAc::getPower()'],['../classIRElectraAc.html#aed11407cd8be470baf5d4667e28e1273',1,'IRElectraAc::getPower()'],['../classIRFujitsuAC.html#a5d03a83db8bc2084ae2acea17c2c7ae2',1,'IRFujitsuAC::getPower()'],['../classIRGoodweatherAc.html#a6f7db9f499c4fea860976bb273ba15df',1,'IRGoodweatherAc::getPower()'],['../classIRGreeAC.html#ac2c97551e02c6cce1b9983cc902f5f1a',1,'IRGreeAC::getPower()'],['../classIRHaierACYRW02.html#a446ee5873e80fa474d322ca5ff598fb5',1,'IRHaierACYRW02::getPower()'],['../classIRHitachiAc.html#a3be8c7ded012c2ad5cab59ee6fe3c88e',1,'IRHitachiAc::getPower()'],['../classIRHitachiAc1.html#ab4756a44153997ff686e8a14369407c0',1,'IRHitachiAc1::getPower()'],['../classIRHitachiAc424.html#ae4d3370d89253ec0861a60b84b2d078c',1,'IRHitachiAc424::getPower()'],['../classIRKelvinatorAC.html#a3dc660afab763c9a4b0cfc5d8e14d220',1,'IRKelvinatorAC::getPower()'],['../classIRLgAc.html#ac09b8af7cc2d46881d3a710068acb5bd',1,'IRLgAc::getPower()'],['../classIRMideaAC.html#a2035653f3ac503a8d30563fded46cab2',1,'IRMideaAC::getPower()'],['../classIRMitsubishiAC.html#aa5fb3f328b6c8a553d25088ec9e858d7',1,'IRMitsubishiAC::getPower()'],['../classIRMitsubishi136.html#a371faf10c80560e1ad59c70d66147723',1,'IRMitsubishi136::getPower()'],['../classIRMitsubishi112.html#afb9ea09a7a9724410470944f6decaeed',1,'IRMitsubishi112::getPower()'],['../classIRMitsubishiHeavy152Ac.html#a1e1d742e255685d1b16935d6031b25fc',1,'IRMitsubishiHeavy152Ac::getPower()'],['../classIRMitsubishiHeavy88Ac.html#a05c50ad07ba7be443414792c7e585354',1,'IRMitsubishiHeavy88Ac::getPower()'],['../classIRNeoclimaAc.html#a635e81f673155eb123dab84a78ff86d5',1,'IRNeoclimaAc::getPower()'],['../classIRPanasonicAc.html#a2d50ed3994f6cc6e205d2c5fb6c0cc55',1,'IRPanasonicAc::getPower()'],['../classIRSamsungAc.html#a26fb214fdf3af4d39a898a1721583cf3',1,'IRSamsungAc::getPower()'],['../classIRSharpAc.html#a49c6c86c901a8d02d7a0d67bfcc397af',1,'IRSharpAc::getPower()'],['../classIRTcl112Ac.html#a36e3b74c79ec42a0922893a3ccd5d045',1,'IRTcl112Ac::getPower()'],['../classIRTecoAc.html#a66c39da54baa6d0c56418ff8027a12a6',1,'IRTecoAc::getPower()'],['../classIRToshibaAC.html#a6d69c147e786aa642906f24c9781bb0f',1,'IRToshibaAC::getPower()'],['../classIRTrotecESP.html#a2e303fe918f79281df98cffb9d2cd539',1,'IRTrotecESP::getPower()'],['../classIRVestelAc.html#a1d6cdc9ad13ebbf1e9a4a83f95244ced',1,'IRVestelAc::getPower()']]], + ['getpowerbutton_326',['getPowerButton',['../classIRCoronaAc.html#ae38a9860cc3fe73909ba20260ad9a51a',1,'IRCoronaAc']]], + ['getpowerful_327',['getPowerful',['../classIRDaikinESP.html#a827c3dc88027b043271a469bc41c4bb1',1,'IRDaikinESP::getPowerful()'],['../classIRDaikin2.html#abad28f7287f4d90d196eb0eb7f93ed43',1,'IRDaikin2::getPowerful()'],['../classIRDaikin216.html#acf94e292df8f45233e115324a95a5e83',1,'IRDaikin216::getPowerful()'],['../classIRDaikin128.html#a50f2de409b3e8966f8406b659aaaedac',1,'IRDaikin128::getPowerful()'],['../classIRDaikin152.html#a20ec24a0ef288cabb93080b4fa0f71fe',1,'IRDaikin152::getPowerful()'],['../classIRPanasonicAc.html#a736b77df0563705095d8f4241a80b1cb',1,'IRPanasonicAc::getPowerful()'],['../classIRSamsungAc.html#ac43367d5aec71e1dcb5b178427268412',1,'IRSamsungAc::getPowerful()']]], + ['getpowerspecial_328',['getPowerSpecial',['../classIRSharpAc.html#aeb5d032c42863b6c3e2665c0719b9341',1,'IRSharpAc']]], + ['getpowertoggle_329',['getPowerToggle',['../classIRDaikin128.html#a0b6b298a0287411f6fe34ec1a0032ff1',1,'IRDaikin128::getPowerToggle()'],['../classIRDaikin64.html#a7921b6a9e776a1802b98e25c0ac4d2dc',1,'IRDaikin64::getPowerToggle()'],['../classIRHitachiAc1.html#a384412f40bfde7a9934fbb7eb2813641',1,'IRHitachiAc1::getPowerToggle()'],['../classIRWhirlpoolAc.html#a08150bcdcf13f0dfb3a7608b2d354a1e',1,'IRWhirlpoolAc::getPowerToggle()']]], + ['getpurify_330',['getPurify',['../classIRDaikin2.html#a3e2785832ae78bafa655aa61853a47bf',1,'IRDaikin2']]], + ['getquiet_331',['getQuiet',['../classIRDaikinESP.html#a25dcfbeacce65f9a89d14a87f759c483',1,'IRDaikinESP::getQuiet()'],['../classIRDaikin2.html#a237eb163e3dd1bf8e45ae2324f0b7dcf',1,'IRDaikin2::getQuiet()'],['../classIRDaikin216.html#aaa0f1aa62f8afd3d489a33af1c1067bc',1,'IRDaikin216::getQuiet()'],['../classIRDaikin128.html#a685bbc2afeecdef69180229b64e1d54b',1,'IRDaikin128::getQuiet()'],['../classIRDaikin152.html#adc8878ec0f6ea2d4fc2fa756a2e9ef4e',1,'IRDaikin152::getQuiet()'],['../classIRDaikin64.html#a431e41baa2881f397b5bf8ee2b79fec9',1,'IRDaikin64::getQuiet()'],['../classIRKelvinatorAC.html#a467c0d63911a87bed8815a5b636d6d75',1,'IRKelvinatorAC::getQuiet()'],['../classIRMitsubishi136.html#afaf690f15d21fea1070b33b2720e98fa',1,'IRMitsubishi136::getQuiet()'],['../classIRMitsubishi112.html#a3b3b78ba5114d783ab7696f3e4687002',1,'IRMitsubishi112::getQuiet()'],['../classIRPanasonicAc.html#a8d7dfc9b5f7c7a4523c0bfa4e0bc415a',1,'IRPanasonicAc::getQuiet()'],['../classIRSamsungAc.html#a0baaf3d40419bb744204bdb30d4aa9b9',1,'IRSamsungAc::getQuiet()']]], + ['getraw_332',['getRaw',['../classIRAmcorAc.html#aa2b99d815e499edf3ae53aebb35cbe9b',1,'IRAmcorAc::getRaw()'],['../classIRArgoAC.html#ac9e8b45dbbef453a54e3593d7e2927fb',1,'IRArgoAC::getRaw()'],['../classIRCarrierAc64.html#ad40279db2c9bd3d1abb5a6e028ec0d80',1,'IRCarrierAc64::getRaw()'],['../classIRCoolixAC.html#aa231938dfcff03325383205edc9c88d2',1,'IRCoolixAC::getRaw()'],['../classIRCoronaAc.html#ac2ba3b4bcefb801da345c9da5daa85fc',1,'IRCoronaAc::getRaw()'],['../classIRDaikinESP.html#ab100221dacc23402f486dee038df046d',1,'IRDaikinESP::getRaw()'],['../classIRDaikin2.html#aaf2ac0fc5924829a1209bd5e0b608b5f',1,'IRDaikin2::getRaw()'],['../classIRDaikin216.html#ac41b3de39ffc6ccd097085c727329531',1,'IRDaikin216::getRaw()'],['../classIRDaikin160.html#aeb68f80476362b0581fcb273b13cdf1e',1,'IRDaikin160::getRaw()'],['../classIRDaikin176.html#a86896be45037015683299004f2eb4d22',1,'IRDaikin176::getRaw()'],['../classIRDaikin128.html#a05669c2b1a6720b95d9a5fb898179a10',1,'IRDaikin128::getRaw()'],['../classIRDaikin152.html#a4af01f8a2459493762977f8ed260c4e6',1,'IRDaikin152::getRaw()'],['../classIRDaikin64.html#a1f8df45c67771ffca620f8c2f17af2e0',1,'IRDaikin64::getRaw()'],['../classIRDelonghiAc.html#a9e6934607f162df3d259d8fb95319d67',1,'IRDelonghiAc::getRaw()'],['../classIRElectraAc.html#a7674d29474ecbbb6366d96056794314c',1,'IRElectraAc::getRaw()'],['../classIRFujitsuAC.html#ae4dce44cab1f26756d63728cb8d55e65',1,'IRFujitsuAC::getRaw()'],['../classIRGoodweatherAc.html#a82d973e562b2425e8823fbc7332c06de',1,'IRGoodweatherAc::getRaw()'],['../classIRGreeAC.html#afa1595d4f69200b0076db1b9f8f2ea73',1,'IRGreeAC::getRaw()'],['../classIRHaierAC.html#abf72eed86c2c86c4f0f5f49f6a788b82',1,'IRHaierAC::getRaw()'],['../classIRHaierACYRW02.html#abca7bbe8c723551723f24f186343b764',1,'IRHaierACYRW02::getRaw()'],['../classIRHitachiAc.html#a8dafb9436f63cfc2d7e4f558fbd6e1ab',1,'IRHitachiAc::getRaw()'],['../classIRHitachiAc1.html#ad850b6364603880ccc444381e85af564',1,'IRHitachiAc1::getRaw()'],['../classIRHitachiAc424.html#acd8388f938feeaf6808ff65779435b5d',1,'IRHitachiAc424::getRaw()'],['../classIRHitachiAc3.html#a915605ca6d0bf3ff6fc9b376ddd394ae',1,'IRHitachiAc3::getRaw()'],['../classIRKelvinatorAC.html#a09149dd7bc45ca50b0c490b9c1f1e6f4',1,'IRKelvinatorAC::getRaw()'],['../classIRLgAc.html#afcb529d2f2c9016388264b80e6a99351',1,'IRLgAc::getRaw()'],['../classIRMideaAC.html#ae0b2c3a5a0a1d84eaeb462bbbe944d97',1,'IRMideaAC::getRaw()'],['../classIRMitsubishiAC.html#a1f2d0ea70bdeb71efab4c20ccd876aa9',1,'IRMitsubishiAC::getRaw()'],['../classIRMitsubishi136.html#a61cceec2bf241a75be1389391e8f3d9a',1,'IRMitsubishi136::getRaw()'],['../classIRMitsubishi112.html#a5e47e892921b8464652b55f41f42fd9a',1,'IRMitsubishi112::getRaw()'],['../classIRMitsubishiHeavy152Ac.html#a34ae73479c76b08512eaa87ed0662c0a',1,'IRMitsubishiHeavy152Ac::getRaw()'],['../classIRMitsubishiHeavy88Ac.html#af96915ac45861327ed7d55803dadd4fd',1,'IRMitsubishiHeavy88Ac::getRaw()'],['../classIRNeoclimaAc.html#a1f67329cad92d4252b0d33effce6380e',1,'IRNeoclimaAc::getRaw()'],['../classIRPanasonicAc.html#ad65c2bcdc3984a986f5ef2f03b5574d4',1,'IRPanasonicAc::getRaw()'],['../classIRSamsungAc.html#a96c6ac410053f0f2804160040d9fcf12',1,'IRSamsungAc::getRaw()'],['../classIRSharpAc.html#a9d680b0145c376060bd2d2e4c2630162',1,'IRSharpAc::getRaw()'],['../classIRTcl112Ac.html#a517375b764d1381aa5a7d4ec962346ec',1,'IRTcl112Ac::getRaw()'],['../classIRTecoAc.html#a7726e9d638cb81c7a4010112887a0ffe',1,'IRTecoAc::getRaw()'],['../classIRToshibaAC.html#a3572a06423851d2c4da5f85133a1a8ff',1,'IRToshibaAC::getRaw()'],['../classIRTrotecESP.html#a412dd2cf9dcb711003bcbb5b579cb2b8',1,'IRTrotecESP::getRaw()'],['../classIRVestelAc.html#afffd1dbcdec22ecca4efe9a996bf27e5',1,'IRVestelAc::getRaw()'],['../classIRWhirlpoolAc.html#a788a6a5373256e10200969cc5c73da63',1,'IRWhirlpoolAc::getRaw()']]], + ['getrclevel_333',['getRClevel',['../classIRrecv.html#a8e32daaa903a8e42dad7faaf405b33dc',1,'IRrecv']]], + ['getroomtemp_334',['getRoomTemp',['../classIRArgoAC.html#a5e4d8447c8851d2fce656abce6c4d368',1,'IRArgoAC']]], + ['getsave_335',['getSave',['../classIRTecoAc.html#a0b4eea3d89f3aef649e32ee1b8bf65a3',1,'IRTecoAc']]], + ['getsectionbyte_336',['getSectionByte',['../classIRCoronaAc.html#aed9181df842370739a5b4977b20769f9',1,'IRCoronaAc']]], + ['getsensor_337',['getSensor',['../classIRDaikinESP.html#ac22369a04bb8f428a127b3625d9989fc',1,'IRDaikinESP::getSensor()'],['../classIRDaikin152.html#a88d4d0d41f33f71d4a846f6c2547f597',1,'IRDaikin152::getSensor()']]], + ['getsensortemp_338',['getSensorTemp',['../classIRCoolixAC.html#aebbed796cab76248138e124aac1d535a',1,'IRCoolixAC']]], + ['getsilent_339',['getSilent',['../classIRMitsubishiHeavy152Ac.html#a93aa735996a31d6f1928aa35d704bd24',1,'IRMitsubishiHeavy152Ac']]], + ['getsleep_340',['getSleep',['../classIRCarrierAc64.html#a24f208b955af86f6927ac97b7f7066d5',1,'IRCarrierAc64::getSleep()'],['../classIRCoolixAC.html#a0b22f5427254c3f784f468d53909882c',1,'IRCoolixAC::getSleep()'],['../classIRDaikin128.html#a0cab507cdea112168757e1ab1a5a1dbe',1,'IRDaikin128::getSleep()'],['../classIRDaikin64.html#a32f4b90d4071cdbc4f37dd401e2d771f',1,'IRDaikin64::getSleep()'],['../classIRDelonghiAc.html#ab9baadd8f41c6dc7f89e71415e0e57b5',1,'IRDelonghiAc::getSleep()'],['../classIRGoodweatherAc.html#acf84e27fedc3c30a03c7d83e4843f8e0',1,'IRGoodweatherAc::getSleep()'],['../classIRGreeAC.html#abd106daa5324a454c5ced13e2fed2a1b',1,'IRGreeAC::getSleep()'],['../classIRHaierAC.html#a0ac7155d5ba294ce50b9436a35aa166b',1,'IRHaierAC::getSleep()'],['../classIRHaierACYRW02.html#acecf20cbe6065a4096ee5a353d2161c9',1,'IRHaierACYRW02::getSleep()'],['../classIRHitachiAc1.html#ab2e82cce1d9dc6e6ce66f2382ffcf4d4',1,'IRHitachiAc1::getSleep()'],['../classIRMideaAC.html#af4b76f42fd9be5eed9b546be7b0c34db',1,'IRMideaAC::getSleep()'],['../classIRNeoclimaAc.html#a8565f8f39127ed51eec7f7883319da61',1,'IRNeoclimaAc::getSleep()'],['../classIRTecoAc.html#a3eebb19e029aa882e161eb2bd6cfe333',1,'IRTecoAc::getSleep()'],['../classIRTrotecESP.html#a28558241d4dd18e191c6fab2c21f973e',1,'IRTrotecESP::getSleep()'],['../classIRVestelAc.html#a54f97dfe120c96b8c041550ed26d46f2',1,'IRVestelAc::getSleep()'],['../classIRWhirlpoolAc.html#a83c1b70e9c3b256b9e77ff6fb7fe0bde',1,'IRWhirlpoolAc::getSleep()']]], + ['getsleeptime_341',['getSleepTime',['../classIRDaikin2.html#a31af96f9a05b3adea2e2ae84d3d242b9',1,'IRDaikin2']]], + ['getsleeptimerenabled_342',['getSleepTimerEnabled',['../classIRDaikin2.html#ae4944acaa5c9d381a1875f4d0b16590a',1,'IRDaikin2']]], + ['getspecial_343',['getSpecial',['../classIRSharpAc.html#a18fb9e6f965682e4faae3d1ecc2561cb',1,'IRSharpAc']]], + ['getspeed_344',['getSpeed',['../classIRTrotecESP.html#ae57c9ab5bc2196f5028ea1af1bdb5428',1,'IRTrotecESP']]], + ['getstartclock_345',['getStartClock',['../classIRMitsubishiAC.html#a0e0d8fa3bec35107929aaa9e9b4b5818',1,'IRMitsubishiAC']]], + ['getstate_346',['getState',['../classIRac.html#af0122722691881b04c312bb30efcc3f2',1,'IRac']]], + ['getstatelength_347',['getStateLength',['../classIRFujitsuAC.html#a02636372996211d464c7394329921ea0',1,'IRFujitsuAC']]], + ['getstateprev_348',['getStatePrev',['../classIRac.html#adf582223eae0127491c7f1db38f101d3',1,'IRac']]], + ['getstopclock_349',['getStopClock',['../classIRMitsubishiAC.html#a9b6266611d7cf75337557533a32796c2',1,'IRMitsubishiAC']]], + ['getsuper_350',['getSuper',['../classIRWhirlpoolAc.html#a8bcf542e3499d05c4028157c803a0965',1,'IRWhirlpoolAc']]], + ['getswing_351',['getSwing',['../classIRCoolixAC.html#a4846bb6a16802158dca3a8b1b7f5b6ff',1,'IRCoolixAC::getSwing()'],['../classIRFujitsuAC.html#af6f05f1375c3c4662d10026028fadbed',1,'IRFujitsuAC::getSwing()'],['../classIRGoodweatherAc.html#a96c844ec310323b62d9127ff250c3629',1,'IRGoodweatherAc::getSwing()'],['../classIRHaierAC.html#aa18839d213e4cd46405c683ec67fa23e',1,'IRHaierAC::getSwing()'],['../classIRHaierACYRW02.html#a88b15d20c007926ab5871b8e6a9fbe3f',1,'IRHaierACYRW02::getSwing()'],['../classIRSamsungAc.html#a5e6a7caccfdcb23cdb7d1341376c2343',1,'IRSamsungAc::getSwing()'],['../classIRTecoAc.html#a152fb025a2ba4410864637e8fdcef27a',1,'IRTecoAc::getSwing()'],['../classIRVestelAc.html#a991f8ca21319cb39b6c4cd358de4dbf4',1,'IRVestelAc::getSwing()'],['../classIRWhirlpoolAc.html#abac55fcea520ea4bbef3fa76223e2efc',1,'IRWhirlpoolAc::getSwing()']]], + ['getswingh_352',['getSwingH',['../classIRElectraAc.html#a40e8f0ae2e57c3adf756b12524b36e6d',1,'IRElectraAc::getSwingH()'],['../classIRHitachiAc1.html#ac5bfde2c87281d3e7f427cb7ea601e85',1,'IRHitachiAc1::getSwingH()'],['../classIRHitachiAc344.html#a33ad0fe4939b2e2456a3d8a09da5a161',1,'IRHitachiAc344::getSwingH()'],['../classIRMitsubishi112.html#a05a343020c64f0ef95c365adcb337140',1,'IRMitsubishi112::getSwingH()'],['../classIRNeoclimaAc.html#a133fb28183fc33702bd8afb7c8886cb2',1,'IRNeoclimaAc::getSwingH()']]], + ['getswinghorizontal_353',['getSwingHorizontal',['../classIRDaikinESP.html#a0a551cc1c22b5378015e8722919534aa',1,'IRDaikinESP::getSwingHorizontal()'],['../classIRDaikin2.html#a338a70b5d7f71da467a0f32b4a057f13',1,'IRDaikin2::getSwingHorizontal()'],['../classIRDaikin216.html#a4b5c648e6568bf1dd24932e108c560d9',1,'IRDaikin216::getSwingHorizontal()'],['../classIRDaikin176.html#aac0a1b9b5e618b31c651b9abc158a552',1,'IRDaikin176::getSwingHorizontal()'],['../classIRHitachiAc.html#a080f87358270eb1482d4a5d4b873f22c',1,'IRHitachiAc::getSwingHorizontal()'],['../classIRKelvinatorAC.html#abe27eb5ec7eb4c4b766a47b551422af3',1,'IRKelvinatorAC::getSwingHorizontal()'],['../classIRMitsubishiHeavy152Ac.html#a587eddf4684bdcb6c399b3f9c6cec684',1,'IRMitsubishiHeavy152Ac::getSwingHorizontal()'],['../classIRMitsubishiHeavy88Ac.html#ae538830313d02aa1ecc671188687dd35',1,'IRMitsubishiHeavy88Ac::getSwingHorizontal()'],['../classIRPanasonicAc.html#a37d9b268b3c8527be0939e0a24b02ef6',1,'IRPanasonicAc::getSwingHorizontal()'],['../classIRTcl112Ac.html#a7080def7f41498fc5af723e852c2e75c',1,'IRTcl112Ac::getSwingHorizontal()']]], + ['getswingtoggle_354',['getSwingToggle',['../classIRHitachiAc1.html#ac4a5d4d5f9b4ae000d0acb232a1e2752',1,'IRHitachiAc1::getSwingToggle()'],['../classIRSharpAc.html#ae0327e90a68638c254706a99ed40f173',1,'IRSharpAc::getSwingToggle()']]], + ['getswingv_355',['getSwingV',['../classIRCarrierAc64.html#a78aac688a4b040b2b6102fac8b028bde',1,'IRCarrierAc64::getSwingV()'],['../classIRDaikin152.html#a74ee60e666520513b33927178f15bc7e',1,'IRDaikin152::getSwingV()'],['../classIRElectraAc.html#a9cd2a7d7716f855dca6be12e3cdc3d24',1,'IRElectraAc::getSwingV()'],['../classIRHitachiAc1.html#a24216e1bc4cf9e9187e9031cee1684dc',1,'IRHitachiAc1::getSwingV()'],['../classIRHitachiAc344.html#a4e011e409f1bf97c8bd4043e2d069020',1,'IRHitachiAc344::getSwingV()'],['../classIRMitsubishi136.html#af2cacca74c4a6ade5f9689674bb707ea',1,'IRMitsubishi136::getSwingV()'],['../classIRMitsubishi112.html#a6d1e939169686978c83a2b26ebc3b8c2',1,'IRMitsubishi112::getSwingV()'],['../classIRNeoclimaAc.html#a3007ed9857bb212de05b7757ee0691e3',1,'IRNeoclimaAc::getSwingV()']]], + ['getswingvertical_356',['getSwingVertical',['../classIRDaikinESP.html#a95f87fd97248e13c6339b71702a79e3a',1,'IRDaikinESP::getSwingVertical()'],['../classIRDaikin2.html#aa1d07be72001f06b6a8dfc279ffc40f5',1,'IRDaikin2::getSwingVertical()'],['../classIRDaikin216.html#ae72a3858a0023dac48fe755fd1bb1677',1,'IRDaikin216::getSwingVertical()'],['../classIRDaikin160.html#a5ed62940052f79587c92eaf92e30cf53',1,'IRDaikin160::getSwingVertical()'],['../classIRDaikin128.html#a60c21eaff6bf860ae25b974a0fd04e11',1,'IRDaikin128::getSwingVertical()'],['../classIRDaikin64.html#a7d538ad1ae23b92c1d82ae85ddd55ef1',1,'IRDaikin64::getSwingVertical()'],['../classIRHitachiAc.html#a9f507cc12bd3a5639777af0329a6dd5c',1,'IRHitachiAc::getSwingVertical()'],['../classIRKelvinatorAC.html#a69aaabc1f34e061272a76e4dc3c98bf1',1,'IRKelvinatorAC::getSwingVertical()'],['../classIRMitsubishiHeavy152Ac.html#a73c59d829a82306edf22acbd930650e0',1,'IRMitsubishiHeavy152Ac::getSwingVertical()'],['../classIRMitsubishiHeavy88Ac.html#ae836aee7dfb729f6b978b0b4ac8e9d3c',1,'IRMitsubishiHeavy88Ac::getSwingVertical()'],['../classIRPanasonicAc.html#a7a35303cd4fb4b23c0e5a25777d5819c',1,'IRPanasonicAc::getSwingVertical()'],['../classIRTcl112Ac.html#a0b75d06b14c1b7e2d2eb3a8779160ae5',1,'IRTcl112Ac::getSwingVertical()']]], + ['getswingverticalauto_357',['getSwingVerticalAuto',['../classIRGreeAC.html#a4105bcde953896b12df050b12f1a45cc',1,'IRGreeAC']]], + ['getswingverticalposition_358',['getSwingVerticalPosition',['../classIRGreeAC.html#a7b1b840483ef92102dd61fefd52ccd8b',1,'IRGreeAC']]], + ['getswingvtoggle_359',['getSwingVToggle',['../classIRCoronaAc.html#ab10588a662031607ed4d01603a4471d6',1,'IRCoronaAc::getSwingVToggle()'],['../classIRHitachiAc424.html#ab697f595b6323288b6fd86f2a2911333',1,'IRHitachiAc424::getSwingVToggle()'],['../classIRMideaAC.html#a50b260d69bc0df8851bfccb003971dfe',1,'IRMideaAC::getSwingVToggle()']]], + ['gettemp_360',['getTemp',['../classIRAmcorAc.html#a2f3e4765a3ae65ffda197f5a58070bf3',1,'IRAmcorAc::getTemp()'],['../classIRArgoAC.html#af5c4cfd3cac33f223e2807ec831df0a9',1,'IRArgoAC::getTemp()'],['../classIRCarrierAc64.html#a799edf21e766b8ae2638a9b1e1d18ac1',1,'IRCarrierAc64::getTemp()'],['../classIRCoolixAC.html#af90462598f294a75b35e20d986251942',1,'IRCoolixAC::getTemp()'],['../classIRCoronaAc.html#ac951434588fd9fa2de630db9ae844840',1,'IRCoronaAc::getTemp()'],['../classIRDaikinESP.html#a43c6675b688cad1ca714ecd726dbb411',1,'IRDaikinESP::getTemp()'],['../classIRDaikin2.html#aa1d39acc14bff5d55e918cb123c66e83',1,'IRDaikin2::getTemp()'],['../classIRDaikin216.html#a65b37310c01075c34cedd5ca1c8a2c37',1,'IRDaikin216::getTemp()'],['../classIRDaikin160.html#ae9cee15343fce5b0f32a4f2ff13a9dbe',1,'IRDaikin160::getTemp()'],['../classIRDaikin176.html#aa9015826e70e4ef1a319db4b2a3fba5f',1,'IRDaikin176::getTemp()'],['../classIRDaikin128.html#a0b5aa11a597bded38c067a9e9a01fd45',1,'IRDaikin128::getTemp()'],['../classIRDaikin152.html#af0a1f8bf9fe412186b53977d225032b2',1,'IRDaikin152::getTemp()'],['../classIRDaikin64.html#abeff1ec38e2d3c9fa12d59e506e7b699',1,'IRDaikin64::getTemp()'],['../classIRDelonghiAc.html#a5664302ab883fc88c23c8bb2aa020cb9',1,'IRDelonghiAc::getTemp()'],['../classIRElectraAc.html#ae92bd241a14058ece0e6d27332f9a3fa',1,'IRElectraAc::getTemp()'],['../classIRFujitsuAC.html#a9209df913f46821a66a390b8cff37acf',1,'IRFujitsuAC::getTemp()'],['../classIRGoodweatherAc.html#a796089c84e265cd7f1b2b82edc6b2367',1,'IRGoodweatherAc::getTemp()'],['../classIRGreeAC.html#a3e935c044cdccfb988a97d5fb0c4068b',1,'IRGreeAC::getTemp()'],['../classIRHaierAC.html#af137371c6766ee068a0200ff1facd8b0',1,'IRHaierAC::getTemp()'],['../classIRHaierACYRW02.html#a9cb0edcb5f36054e4e024c38ec3f26b9',1,'IRHaierACYRW02::getTemp()'],['../classIRHitachiAc.html#a85e0b2dfa45e894d1a89a2f862c6aa69',1,'IRHitachiAc::getTemp()'],['../classIRHitachiAc1.html#ac5c55a06a32134bb3e30b83cce2feeaa',1,'IRHitachiAc1::getTemp()'],['../classIRHitachiAc424.html#aa405408fd31795b714486af88a86112e',1,'IRHitachiAc424::getTemp()'],['../classIRKelvinatorAC.html#aabda77a2381526f4be86f05b311248db',1,'IRKelvinatorAC::getTemp()'],['../classIRLgAc.html#a029399c5926bd4f1ff0b26175bc4af79',1,'IRLgAc::getTemp()'],['../classIRMideaAC.html#a546ab6d3e317e6219ad371fd0825520d',1,'IRMideaAC::getTemp()'],['../classIRMitsubishiAC.html#a9881be01c53dce83bd1eae8a32f150f4',1,'IRMitsubishiAC::getTemp()'],['../classIRMitsubishi136.html#a34bc0e7666264a7e567e45405a57e3e0',1,'IRMitsubishi136::getTemp()'],['../classIRMitsubishi112.html#a4bfd306fecfcaa4c20589440ecfb35db',1,'IRMitsubishi112::getTemp()'],['../classIRMitsubishiHeavy152Ac.html#a7ec864271cf232cab7b8bd778bc36cb4',1,'IRMitsubishiHeavy152Ac::getTemp()'],['../classIRMitsubishiHeavy88Ac.html#afd629c9951a390b7809bc6ac4d3aeeb1',1,'IRMitsubishiHeavy88Ac::getTemp()'],['../classIRNeoclimaAc.html#aaa1a625af6cf094823b58f1fe43deb3a',1,'IRNeoclimaAc::getTemp()'],['../classIRPanasonicAc.html#af8a5607c317e541752fada6ca79ee80f',1,'IRPanasonicAc::getTemp()'],['../classIRSamsungAc.html#a11a6c86f2e4a918e1587ef564c63dddd',1,'IRSamsungAc::getTemp()'],['../classIRSharpAc.html#a1f75c17cc396162e776f3c6cd1848f50',1,'IRSharpAc::getTemp()'],['../classIRTcl112Ac.html#a61bf139cc737b99e5d68294c353eb353',1,'IRTcl112Ac::getTemp()'],['../classIRTecoAc.html#a40e717564222c5c1e4fdce13eba5efc3',1,'IRTecoAc::getTemp()'],['../classIRToshibaAC.html#ab2a9b47d49c5608c97a7c6968c43037d',1,'IRToshibaAC::getTemp()'],['../classIRTrotecESP.html#adcfae2ee1e58cd6a78805c72d7a8a942',1,'IRTrotecESP::getTemp()'],['../classIRVestelAc.html#a835ab977fa0dbf47776e5d618d59c819',1,'IRVestelAc::getTemp()'],['../classIRWhirlpoolAc.html#a4a73ee67cb2eb4407e78add1009cdd51',1,'IRWhirlpoolAc::getTemp()']]], + ['gettempoffset_361',['getTempOffset',['../classIRWhirlpoolAc.html#a2d6111c9b97745d197f0b5d4d4610b3d',1,'IRWhirlpoolAc']]], + ['gettempraw_362',['getTempRaw',['../classIRCoolixAC.html#a559634f3c6aee54683d4b6ccbbc7a884',1,'IRCoolixAC']]], + ['gettempunit_363',['getTempUnit',['../classIRDelonghiAc.html#a8bbe27e1e87fbfc6b126c7f135886632',1,'IRDelonghiAc']]], + ['gettime_364',['getTime',['../classIRHaierAC.html#a60e891775fbc3a77ee487cde26f650c5',1,'IRHaierAC::getTime()'],['../classIRVestelAc.html#a3542ec93c30ec3bc1bb4e242edcf1def',1,'IRVestelAc::getTime()'],['../classIRWhirlpoolAc.html#a27aba1f22b55aa6f72686e0a722682b0',1,'IRWhirlpoolAc::getTime()']]], + ['gettimer_365',['getTimer',['../classIRDaikin128.html#ab35fa1fdd65db9d9cd7fbaffdd4ecd85',1,'IRDaikin128::getTimer()'],['../classIRGreeAC.html#a7a56024e2840306e071e03d1fae53ce9',1,'IRGreeAC::getTimer()'],['../classIRMitsubishiAC.html#a8bb8e92a00f8d9dfff31589d435c9ae5',1,'IRMitsubishiAC::getTimer()'],['../classIRTecoAc.html#a0bff25b2c686e397b62300ce5cad90f7',1,'IRTecoAc::getTimer()'],['../classIRTrotecESP.html#ae372b3120f0253c5a1607460817d36f6',1,'IRTrotecESP::getTimer()'],['../classIRVestelAc.html#aca4faedc9d82e357c8974fc6143b6e77',1,'IRVestelAc::getTimer()']]], + ['gettimerenabled_366',['getTimerEnabled',['../classIRGreeAC.html#aeec03eb7f506a0ba62c28469b789b0da',1,'IRGreeAC::getTimerEnabled()'],['../classIRSharpAc.html#abd7c061b343b4f096019f42ad6162940',1,'IRSharpAc::getTimerEnabled()'],['../classIRTecoAc.html#a3524f149cd3076e757a1b3228bdf12f2',1,'IRTecoAc::getTimerEnabled()']]], + ['gettimertime_367',['getTimerTime',['../classIRSharpAc.html#a72044d8afb1349a29cd8adcc8644c7ac',1,'IRSharpAc']]], + ['gettimertype_368',['getTimerType',['../classIRSharpAc.html#a9357c50c356b29cc444bf9aafb7df146',1,'IRSharpAc']]], + ['gettolerance_369',['getTolerance',['../classIRrecv.html#a144f64da3b44708394c06b0fbefb6347',1,'IRrecv']]], + ['getturbo_370',['getTurbo',['../classIRCoolixAC.html#ab5f87216fb91bbb437c0899b0742a63f',1,'IRCoolixAC::getTurbo()'],['../classIRDaikin64.html#ade80a5ea137c32bdedd794d64925a2d3',1,'IRDaikin64::getTurbo()'],['../classIRElectraAc.html#a75cae6845498eec84109374a2fefcced',1,'IRElectraAc::getTurbo()'],['../classIRGoodweatherAc.html#a983eca3c2ec1233184939702f43557eb',1,'IRGoodweatherAc::getTurbo()'],['../classIRGreeAC.html#a6e319c8584d0cb82223fd190fa4bde29',1,'IRGreeAC::getTurbo()'],['../classIRHaierACYRW02.html#a4ccd26dad24915b81ae5fb94d18fb85a',1,'IRHaierACYRW02::getTurbo()'],['../classIRKelvinatorAC.html#aff32ab0524f4afeb9b53aa65b8df8e36',1,'IRKelvinatorAC::getTurbo()'],['../classIRMitsubishiHeavy152Ac.html#acf2a73ccddb87bd66c39670bd1d3caba',1,'IRMitsubishiHeavy152Ac::getTurbo()'],['../classIRMitsubishiHeavy88Ac.html#a179ecc619e9eea4adb601309421e5fc0',1,'IRMitsubishiHeavy88Ac::getTurbo()'],['../classIRNeoclimaAc.html#a6cf241f0392744a91b703475ee88bfa1',1,'IRNeoclimaAc::getTurbo()'],['../classIRSharpAc.html#aad2ec46f8da6fd84bc0523f40d6bd57d',1,'IRSharpAc::getTurbo()'],['../classIRTcl112Ac.html#a0de33a2175eada44030d3640d940b697',1,'IRTcl112Ac::getTurbo()'],['../classIRVestelAc.html#a9ce168cc9422e54d631aed571cfe66be',1,'IRVestelAc::getTurbo()']]], + ['getusecelsius_371',['getUseCelsius',['../classIRMideaAC.html#aa88de606a914e33e8beb75a069137b52',1,'IRMideaAC']]], + ['getusefahrenheit_372',['getUseFahrenheit',['../classIRGreeAC.html#aad6acfb8a697aba851bb34b14bc94ac1',1,'IRGreeAC']]], + ['getvane_373',['getVane',['../classIRMitsubishiAC.html#acd98301535e7e161f8fdf42877f3e482',1,'IRMitsubishiAC']]], + ['getweeklytimerenable_374',['getWeeklyTimerEnable',['../classIRDaikinESP.html#a9ee2013c069496884c62b6e9a58d01db',1,'IRDaikinESP']]], + ['getwidevane_375',['getWideVane',['../classIRMitsubishiAC.html#a217dba9f9dcc6f75d466b0b7beca3aea',1,'IRMitsubishiAC']]], + ['getwifi_376',['getWiFi',['../classIRGreeAC.html#a967afbe980bae858ce0e4daea6628c37',1,'IRGreeAC']]], + ['getxfan_377',['getXFan',['../classIRGreeAC.html#acb677dde02be1a3461a7c8bc2406194f',1,'IRGreeAC::getXFan()'],['../classIRKelvinatorAC.html#a2e511ca0a8876928412c2db9214e7fe2',1,'IRKelvinatorAC::getXFan()']]], + ['getzonefollow_378',['getZoneFollow',['../classIRCoolixAC.html#a647a41d63301e3d95460323d1fe0ce4a',1,'IRCoolixAC']]], + ['gicable_379',['GICABLE',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadac8f9010b746a07a7a6329d1b336b68cf',1,'IRremoteESP8266.h']]], + ['globalcache_380',['GLOBALCACHE',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadaf8c11b983768907fdb625ff9fb3729d2',1,'IRremoteESP8266.h']]], + ['goodweather_381',['goodweather',['../classIRac.html#ac47ff5c6faf41e6fb37df258a8bafc08',1,'IRac::goodweather()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada9e8d893590b745f6b1b5ffcb556d9cba',1,'GOODWEATHER(): IRremoteESP8266.h']]], + ['gree_382',['gree',['../classIRac.html#ab66e48b039c9990bf97cd8c2512a6c70',1,'IRac::gree()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadae3a5e7c315f6f88b34a4c856f280ed83',1,'GREE(): IRremoteESP8266.h']]], + ['gree_5fac_5fremote_5fmodel_5ft_383',['gree_ac_remote_model_t',['../IRsend_8h.html#af65070c92b97fa00b2de3818c46039c9',1,'IRsend.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_8.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_8.html new file mode 100644 index 000000000..cf2b5df92 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_8.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_8.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_8.js new file mode 100644 index 000000000..e58d7a183 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_8.js @@ -0,0 +1,25 @@ +var searchData= +[ + ['haier_384',['haier',['../classIRac.html#ae0a29a4cb8c7a4707a7725c576822a58',1,'IRac']]], + ['haier_5fac_385',['HAIER_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada1f232bcdf330ec2e353196941b9f1628',1,'IRremoteESP8266.h']]], + ['haier_5fac_5fyrw02_386',['HAIER_AC_YRW02',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadaacda5821835865551f6df46c76282fa4',1,'IRremoteESP8266.h']]], + ['haieryrwo2_387',['haierYrwo2',['../classIRac.html#a7bc779a162dd9a1b4c925febec443353',1,'IRac']]], + ['handlespecialstate_388',['handleSpecialState',['../classIRCoolixAC.html#af78090c6d8b45b4202a80f1223640390',1,'IRCoolixAC']]], + ['handletoggles_389',['handleToggles',['../classIRac.html#a36833999dce4ad608a5a0f084988cfd1',1,'IRac']]], + ['hasacstate_390',['hasACState',['../IRutils_8cpp.html#a6efd4986db60709d3501606ec7ab5382',1,'hasACState(const decode_type_t protocol): IRutils.cpp'],['../IRutils_8h.html#a6efd4986db60709d3501606ec7ab5382',1,'hasACState(const decode_type_t protocol): IRutils.cpp']]], + ['hasinvertedstates_391',['hasInvertedStates',['../classIRHitachiAc3.html#ac06b36245c85480d97c1a9f49cfaa005',1,'IRHitachiAc3']]], + ['hasstatechanged_392',['hasStateChanged',['../classIRac.html#a35258c35a2d2b19886292b22b2aa053a',1,'IRac']]], + ['heat_5fmode_393',['heat_mode',['../classIRArgoAC.html#a255762f71502b9ffeb0686759991ec53',1,'IRArgoAC']]], + ['hitachi_394',['hitachi',['../classIRac.html#acd0f2fcf03aabf947a19a195000add3c',1,'IRac']]], + ['hitachi1_395',['hitachi1',['../classIRac.html#ac8807d62f6ae87af72d44b50bed3f17b',1,'IRac']]], + ['hitachi344_396',['hitachi344',['../classIRac.html#a0bc34635a1a349816344916a82585460',1,'IRac']]], + ['hitachi424_397',['hitachi424',['../classIRac.html#aec6de0752ddd3a3e7c6824cb1b692508',1,'IRac']]], + ['hitachi_5fac_398',['HITACHI_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada9020fb54ac69d8aec0185f7e80c962ca',1,'IRremoteESP8266.h']]], + ['hitachi_5fac1_399',['HITACHI_AC1',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada7d9a74161d95e62bece3c0e48900cb35',1,'IRremoteESP8266.h']]], + ['hitachi_5fac1_5fremote_5fmodel_5ft_400',['hitachi_ac1_remote_model_t',['../IRsend_8h.html#acd0c6107b5a6cab2080b18a8de14ea49',1,'IRsend.h']]], + ['hitachi_5fac2_401',['HITACHI_AC2',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadab5a44068d519506efa8a3113aa44c9c0',1,'IRremoteESP8266.h']]], + ['hitachi_5fac3_402',['HITACHI_AC3',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadac3487c47b14da6af922f5b27992b30f3',1,'IRremoteESP8266.h']]], + ['hitachi_5fac344_403',['HITACHI_AC344',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada1e147eb39adc40e4181940cc2357f070',1,'IRremoteESP8266.h']]], + ['hitachi_5fac424_404',['HITACHI_AC424',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada85af068f8964d4359512265d8cc27a31',1,'IRremoteESP8266.h']]], + ['htmlescape_405',['htmlEscape',['../namespaceirutils.html#a6e55c6fdcc82e1ef8bd5f73df83609a7',1,'irutils']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_9.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_9.html new file mode 100644 index 000000000..690785a5d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_9.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_9.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_9.js new file mode 100644 index 000000000..64280c4ef --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_9.js @@ -0,0 +1,175 @@ +var searchData= +[ + ['i18n_2eh_406',['i18n.h',['../i18n_8h.html',1,'']]], + ['inax_407',['INAX',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadafc566aab3afb8face6d8965ca4d0eab7',1,'IRremoteESP8266.h']]], + ['irremoteesp8266_20library_20api_20documentation_408',['IRremoteESP8266 Library API Documentation',['../index.html',1,'']]], + ['initstate_409',['initState',['../classIRac.html#af1c4ae70e61298c0be8d350d67e7c342',1,'IRac::initState(stdAc::state_t *state, const decode_type_t vendor, const int16_t model, const bool power, const stdAc::opmode_t mode, const float degrees, const bool celsius, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool econo, const bool light, const bool filter, const bool clean, const bool beep, const int16_t sleep, const int16_t clock)'],['../classIRac.html#a165b7fdb9b3a02b1fb5ff2c2c3747958',1,'IRac::initState(stdAc::state_t *state)']]], + ['invertbits_410',['invertBits',['../IRutils_8cpp.html#a1a85904f25c8ec77fb554d238c59cfdb',1,'invertBits(const uint64_t data, const uint16_t nbits): IRutils.cpp'],['../IRutils_8h.html#a1a85904f25c8ec77fb554d238c59cfdb',1,'invertBits(const uint64_t data, const uint16_t nbits): IRutils.cpp']]], + ['ir_5fairwell_2ecpp_411',['ir_Airwell.cpp',['../ir__Airwell_8cpp.html',1,'']]], + ['ir_5faiwa_2ecpp_412',['ir_Aiwa.cpp',['../ir__Aiwa_8cpp.html',1,'']]], + ['ir_5famcor_2ecpp_413',['ir_Amcor.cpp',['../ir__Amcor_8cpp.html',1,'']]], + ['ir_5famcor_2eh_414',['ir_Amcor.h',['../ir__Amcor_8h.html',1,'']]], + ['ir_5fargo_2ecpp_415',['ir_Argo.cpp',['../ir__Argo_8cpp.html',1,'']]], + ['ir_5fargo_2eh_416',['ir_Argo.h',['../ir__Argo_8h.html',1,'']]], + ['ir_5fcarrier_2ecpp_417',['ir_Carrier.cpp',['../ir__Carrier_8cpp.html',1,'']]], + ['ir_5fcarrier_2eh_418',['ir_Carrier.h',['../ir__Carrier_8h.html',1,'']]], + ['ir_5fcoolix_2ecpp_419',['ir_Coolix.cpp',['../ir__Coolix_8cpp.html',1,'']]], + ['ir_5fcoolix_2eh_420',['ir_Coolix.h',['../ir__Coolix_8h.html',1,'']]], + ['ir_5fcorona_2ecpp_421',['ir_Corona.cpp',['../ir__Corona_8cpp.html',1,'']]], + ['ir_5fcorona_2eh_422',['ir_Corona.h',['../ir__Corona_8h.html',1,'']]], + ['ir_5fdaikin_2ecpp_423',['ir_Daikin.cpp',['../ir__Daikin_8cpp.html',1,'']]], + ['ir_5fdaikin_2eh_424',['ir_Daikin.h',['../ir__Daikin_8h.html',1,'']]], + ['ir_5fdelonghi_2ecpp_425',['ir_Delonghi.cpp',['../ir__Delonghi_8cpp.html',1,'']]], + ['ir_5fdelonghi_2eh_426',['ir_Delonghi.h',['../ir__Delonghi_8h.html',1,'']]], + ['ir_5fdenon_2ecpp_427',['ir_Denon.cpp',['../ir__Denon_8cpp.html',1,'']]], + ['ir_5fdish_2ecpp_428',['ir_Dish.cpp',['../ir__Dish_8cpp.html',1,'']]], + ['ir_5fdoshisha_2ecpp_429',['ir_Doshisha.cpp',['../ir__Doshisha_8cpp.html',1,'']]], + ['ir_5felectra_2ecpp_430',['ir_Electra.cpp',['../ir__Electra_8cpp.html',1,'']]], + ['ir_5felectra_2eh_431',['ir_Electra.h',['../ir__Electra_8h.html',1,'']]], + ['ir_5fepson_2ecpp_432',['ir_Epson.cpp',['../ir__Epson_8cpp.html',1,'']]], + ['ir_5ffujitsu_2ecpp_433',['ir_Fujitsu.cpp',['../ir__Fujitsu_8cpp.html',1,'']]], + ['ir_5ffujitsu_2eh_434',['ir_Fujitsu.h',['../ir__Fujitsu_8h.html',1,'']]], + ['ir_5fgicable_2ecpp_435',['ir_GICable.cpp',['../ir__GICable_8cpp.html',1,'']]], + ['ir_5fglobalcache_2ecpp_436',['ir_GlobalCache.cpp',['../ir__GlobalCache_8cpp.html',1,'']]], + ['ir_5fgoodweather_2ecpp_437',['ir_Goodweather.cpp',['../ir__Goodweather_8cpp.html',1,'']]], + ['ir_5fgoodweather_2eh_438',['ir_Goodweather.h',['../ir__Goodweather_8h.html',1,'']]], + ['ir_5fgree_2ecpp_439',['ir_Gree.cpp',['../ir__Gree_8cpp.html',1,'']]], + ['ir_5fgree_2eh_440',['ir_Gree.h',['../ir__Gree_8h.html',1,'']]], + ['ir_5fhaier_2ecpp_441',['ir_Haier.cpp',['../ir__Haier_8cpp.html',1,'']]], + ['ir_5fhaier_2eh_442',['ir_Haier.h',['../ir__Haier_8h.html',1,'']]], + ['ir_5fhitachi_2ecpp_443',['ir_Hitachi.cpp',['../ir__Hitachi_8cpp.html',1,'']]], + ['ir_5fhitachi_2eh_444',['ir_Hitachi.h',['../ir__Hitachi_8h.html',1,'']]], + ['ir_5finax_2ecpp_445',['ir_Inax.cpp',['../ir__Inax_8cpp.html',1,'']]], + ['ir_5fjvc_2ecpp_446',['ir_JVC.cpp',['../ir__JVC_8cpp.html',1,'']]], + ['ir_5fkelvinator_2ecpp_447',['ir_Kelvinator.cpp',['../ir__Kelvinator_8cpp.html',1,'']]], + ['ir_5fkelvinator_2eh_448',['ir_Kelvinator.h',['../ir__Kelvinator_8h.html',1,'']]], + ['ir_5flasertag_2ecpp_449',['ir_Lasertag.cpp',['../ir__Lasertag_8cpp.html',1,'']]], + ['ir_5flego_2ecpp_450',['ir_Lego.cpp',['../ir__Lego_8cpp.html',1,'']]], + ['ir_5flg_2ecpp_451',['ir_LG.cpp',['../ir__LG_8cpp.html',1,'']]], + ['ir_5flg_2eh_452',['ir_LG.h',['../ir__LG_8h.html',1,'']]], + ['ir_5flutron_2ecpp_453',['ir_Lutron.cpp',['../ir__Lutron_8cpp.html',1,'']]], + ['ir_5fmagiquest_2ecpp_454',['ir_Magiquest.cpp',['../ir__Magiquest_8cpp.html',1,'']]], + ['ir_5fmagiquest_2eh_455',['ir_Magiquest.h',['../ir__Magiquest_8h.html',1,'']]], + ['ir_5fmidea_2ecpp_456',['ir_Midea.cpp',['../ir__Midea_8cpp.html',1,'']]], + ['ir_5fmidea_2eh_457',['ir_Midea.h',['../ir__Midea_8h.html',1,'']]], + ['ir_5fmitsubishi_2ecpp_458',['ir_Mitsubishi.cpp',['../ir__Mitsubishi_8cpp.html',1,'']]], + ['ir_5fmitsubishi_2eh_459',['ir_Mitsubishi.h',['../ir__Mitsubishi_8h.html',1,'']]], + ['ir_5fmitsubishiheavy_2ecpp_460',['ir_MitsubishiHeavy.cpp',['../ir__MitsubishiHeavy_8cpp.html',1,'']]], + ['ir_5fmitsubishiheavy_2eh_461',['ir_MitsubishiHeavy.h',['../ir__MitsubishiHeavy_8h.html',1,'']]], + ['ir_5fmultibrackets_2ecpp_462',['ir_Multibrackets.cpp',['../ir__Multibrackets_8cpp.html',1,'']]], + ['ir_5fmwm_2ecpp_463',['ir_MWM.cpp',['../ir__MWM_8cpp.html',1,'']]], + ['ir_5fnec_2ecpp_464',['ir_NEC.cpp',['../ir__NEC_8cpp.html',1,'']]], + ['ir_5fnec_2eh_465',['ir_NEC.h',['../ir__NEC_8h.html',1,'']]], + ['ir_5fneoclima_2ecpp_466',['ir_Neoclima.cpp',['../ir__Neoclima_8cpp.html',1,'']]], + ['ir_5fneoclima_2eh_467',['ir_Neoclima.h',['../ir__Neoclima_8h.html',1,'']]], + ['ir_5fnikai_2ecpp_468',['ir_Nikai.cpp',['../ir__Nikai_8cpp.html',1,'']]], + ['ir_5fpanasonic_2ecpp_469',['ir_Panasonic.cpp',['../ir__Panasonic_8cpp.html',1,'']]], + ['ir_5fpanasonic_2eh_470',['ir_Panasonic.h',['../ir__Panasonic_8h.html',1,'']]], + ['ir_5fpioneer_2ecpp_471',['ir_Pioneer.cpp',['../ir__Pioneer_8cpp.html',1,'']]], + ['ir_5fpronto_2ecpp_472',['ir_Pronto.cpp',['../ir__Pronto_8cpp.html',1,'']]], + ['ir_5frc5_5frc6_2ecpp_473',['ir_RC5_RC6.cpp',['../ir__RC5__RC6_8cpp.html',1,'']]], + ['ir_5frcmm_2ecpp_474',['ir_RCMM.cpp',['../ir__RCMM_8cpp.html',1,'']]], + ['ir_5fsamsung_2ecpp_475',['ir_Samsung.cpp',['../ir__Samsung_8cpp.html',1,'']]], + ['ir_5fsamsung_2eh_476',['ir_Samsung.h',['../ir__Samsung_8h.html',1,'']]], + ['ir_5fsanyo_2ecpp_477',['ir_Sanyo.cpp',['../ir__Sanyo_8cpp.html',1,'']]], + ['ir_5fsharp_2ecpp_478',['ir_Sharp.cpp',['../ir__Sharp_8cpp.html',1,'']]], + ['ir_5fsharp_2eh_479',['ir_Sharp.h',['../ir__Sharp_8h.html',1,'']]], + ['ir_5fsherwood_2ecpp_480',['ir_Sherwood.cpp',['../ir__Sherwood_8cpp.html',1,'']]], + ['ir_5fsony_2ecpp_481',['ir_Sony.cpp',['../ir__Sony_8cpp.html',1,'']]], + ['ir_5fsymphony_2ecpp_482',['ir_Symphony.cpp',['../ir__Symphony_8cpp.html',1,'']]], + ['ir_5ftcl_2ecpp_483',['ir_Tcl.cpp',['../ir__Tcl_8cpp.html',1,'']]], + ['ir_5ftcl_2eh_484',['ir_Tcl.h',['../ir__Tcl_8h.html',1,'']]], + ['ir_5fteco_2ecpp_485',['ir_Teco.cpp',['../ir__Teco_8cpp.html',1,'']]], + ['ir_5fteco_2eh_486',['ir_Teco.h',['../ir__Teco_8h.html',1,'']]], + ['ir_5ftoshiba_2ecpp_487',['ir_Toshiba.cpp',['../ir__Toshiba_8cpp.html',1,'']]], + ['ir_5ftoshiba_2eh_488',['ir_Toshiba.h',['../ir__Toshiba_8h.html',1,'']]], + ['ir_5ftrotec_2ecpp_489',['ir_Trotec.cpp',['../ir__Trotec_8cpp.html',1,'']]], + ['ir_5ftrotec_2eh_490',['ir_Trotec.h',['../ir__Trotec_8h.html',1,'']]], + ['ir_5fvestel_2ecpp_491',['ir_Vestel.cpp',['../ir__Vestel_8cpp.html',1,'']]], + ['ir_5fvestel_2eh_492',['ir_Vestel.h',['../ir__Vestel_8h.html',1,'']]], + ['ir_5fwhirlpool_2ecpp_493',['ir_Whirlpool.cpp',['../ir__Whirlpool_8cpp.html',1,'']]], + ['ir_5fwhirlpool_2eh_494',['ir_Whirlpool.h',['../ir__Whirlpool_8h.html',1,'']]], + ['ir_5fwhynter_2ecpp_495',['ir_Whynter.cpp',['../ir__Whynter_8cpp.html',1,'']]], + ['ir_5fzepeal_2ecpp_496',['ir_Zepeal.cpp',['../ir__Zepeal_8cpp.html',1,'']]], + ['irac_497',['IRac',['../classIRac.html',1,'IRac'],['../classIRac.html#abb0864e277d4f6c68a92c2729112a40d',1,'IRac::IRac()']]], + ['irac_2ecpp_498',['IRac.cpp',['../IRac_8cpp.html',1,'']]], + ['irac_2eh_499',['IRac.h',['../IRac_8h.html',1,'']]], + ['iracutils_500',['IRAcUtils',['../namespaceIRAcUtils.html',1,'']]], + ['iramcorac_501',['IRAmcorAc',['../classIRAmcorAc.html',1,'IRAmcorAc'],['../classIRAmcorAc.html#a92db59a33c861dcd3b2960e9711f97c4',1,'IRAmcorAc::IRAmcorAc()']]], + ['irargoac_502',['IRArgoAC',['../classIRArgoAC.html',1,'IRArgoAC'],['../classIRArgoAC.html#ad6c2250738397441b8f956d1477b7d70',1,'IRArgoAC::IRArgoAC()']]], + ['ircarrierac64_503',['IRCarrierAc64',['../classIRCarrierAc64.html',1,'IRCarrierAc64'],['../classIRCarrierAc64.html#ac225c0f24a0e385a145375ff447ab79b',1,'IRCarrierAc64::IRCarrierAc64()']]], + ['ircoolixac_504',['IRCoolixAC',['../classIRCoolixAC.html',1,'IRCoolixAC'],['../classIRCoolixAC.html#a043ad3b74e964e39b111e1fcf9e55f42',1,'IRCoolixAC::IRCoolixAC()']]], + ['ircoronaac_505',['IRCoronaAc',['../classIRCoronaAc.html',1,'IRCoronaAc'],['../classIRCoronaAc.html#aa96f1ffce21cdec5b3901ebbb1c63fbb',1,'IRCoronaAc::IRCoronaAc()']]], + ['irdaikin128_506',['IRDaikin128',['../classIRDaikin128.html',1,'IRDaikin128'],['../classIRDaikin128.html#aa669739541daf1a2b39ce1cd0424c43b',1,'IRDaikin128::IRDaikin128()']]], + ['irdaikin152_507',['IRDaikin152',['../classIRDaikin152.html',1,'IRDaikin152'],['../classIRDaikin152.html#a68dce79bab5890d9aea325a45ef8e4a3',1,'IRDaikin152::IRDaikin152()']]], + ['irdaikin160_508',['IRDaikin160',['../classIRDaikin160.html',1,'IRDaikin160'],['../classIRDaikin160.html#a76fb744b041c38abb730bce0538a497a',1,'IRDaikin160::IRDaikin160()']]], + ['irdaikin176_509',['IRDaikin176',['../classIRDaikin176.html',1,'IRDaikin176'],['../classIRDaikin176.html#accfe7c3f34351844d12059455f65f312',1,'IRDaikin176::IRDaikin176()']]], + ['irdaikin2_510',['IRDaikin2',['../classIRDaikin2.html',1,'IRDaikin2'],['../classIRDaikin2.html#a3ffe908313f162b92e92307578592fca',1,'IRDaikin2::IRDaikin2()']]], + ['irdaikin216_511',['IRDaikin216',['../classIRDaikin216.html',1,'IRDaikin216'],['../classIRDaikin216.html#ad802bde79e5ee2d16e3b09fbc8bbe8df',1,'IRDaikin216::IRDaikin216()']]], + ['irdaikin64_512',['IRDaikin64',['../classIRDaikin64.html',1,'IRDaikin64'],['../classIRDaikin64.html#a88855df33ce903884b21d2ef4771e94f',1,'IRDaikin64::IRDaikin64()']]], + ['irdaikinesp_513',['IRDaikinESP',['../classIRDaikinESP.html',1,'IRDaikinESP'],['../classIRDaikinESP.html#a2652cb45e07e8a4329c16cded9f6ad9a',1,'IRDaikinESP::IRDaikinESP()']]], + ['irdelonghiac_514',['IRDelonghiAc',['../classIRDelonghiAc.html',1,'IRDelonghiAc'],['../classIRDelonghiAc.html#aa6f8661cf6baa369a0a5b9d775c392e0',1,'IRDelonghiAc::IRDelonghiAc()']]], + ['irelectraac_515',['IRElectraAc',['../classIRElectraAc.html',1,'IRElectraAc'],['../classIRElectraAc.html#a2f56ad22943c3d261b1d2ef88d86e300',1,'IRElectraAc::IRElectraAc()']]], + ['irfujitsuac_516',['IRFujitsuAC',['../classIRFujitsuAC.html',1,'IRFujitsuAC'],['../classIRFujitsuAC.html#acdb70f239884507f540b872ba25747ce',1,'IRFujitsuAC::IRFujitsuAC()']]], + ['irgoodweatherac_517',['IRGoodweatherAc',['../classIRGoodweatherAc.html',1,'IRGoodweatherAc'],['../classIRGoodweatherAc.html#a681feff1a58125cde97b2d7ed0ba775e',1,'IRGoodweatherAc::IRGoodweatherAc()']]], + ['irgreeac_518',['IRGreeAC',['../classIRGreeAC.html',1,'IRGreeAC'],['../classIRGreeAC.html#abf7ead6ebee4bc776f83fb55f6fe6b63',1,'IRGreeAC::IRGreeAC()']]], + ['irhaierac_519',['IRHaierAC',['../classIRHaierAC.html',1,'IRHaierAC'],['../classIRHaierAC.html#a0b78060cbd150cd886a409adc2dea49c',1,'IRHaierAC::IRHaierAC()']]], + ['irhaieracyrw02_520',['IRHaierACYRW02',['../classIRHaierACYRW02.html',1,'IRHaierACYRW02'],['../classIRHaierACYRW02.html#afd9354c36df33434840bbc5f38d4e7ed',1,'IRHaierACYRW02::IRHaierACYRW02()']]], + ['irhitachiac_521',['IRHitachiAc',['../classIRHitachiAc.html',1,'IRHitachiAc'],['../classIRHitachiAc.html#a4c43e95e0cc28339e7162d7090ae16bf',1,'IRHitachiAc::IRHitachiAc()']]], + ['irhitachiac1_522',['IRHitachiAc1',['../classIRHitachiAc1.html',1,'IRHitachiAc1'],['../classIRHitachiAc1.html#ac00cfd9a60e08d34f292878de47f622f',1,'IRHitachiAc1::IRHitachiAc1()']]], + ['irhitachiac3_523',['IRHitachiAc3',['../classIRHitachiAc3.html',1,'IRHitachiAc3'],['../classIRHitachiAc3.html#adef0e7ad217f078ce418e3aa82b9cb86',1,'IRHitachiAc3::IRHitachiAc3()']]], + ['irhitachiac344_524',['IRHitachiAc344',['../classIRHitachiAc344.html',1,'IRHitachiAc344'],['../classIRHitachiAc424.html#a3c885313a79bf8c02bc5eb9f7d80088b',1,'IRHitachiAc424::IRHitachiAc344()'],['../classIRHitachiAc344.html#afbff8a1dd2777880d2d1713d07e1d419',1,'IRHitachiAc344::IRHitachiAc344()']]], + ['irhitachiac424_525',['IRHitachiAc424',['../classIRHitachiAc424.html',1,'IRHitachiAc424'],['../classIRHitachiAc424.html#add708c10a56d20621ef65a0ddcc2aac1',1,'IRHitachiAc424::IRHitachiAc424()']]], + ['irkelvinatorac_526',['IRKelvinatorAC',['../classIRKelvinatorAC.html',1,'IRKelvinatorAC'],['../classIRKelvinatorAC.html#a111dd384b1898a4fb880a19b6d1b1635',1,'IRKelvinatorAC::IRKelvinatorAC()']]], + ['irlgac_527',['IRLgAc',['../classIRLgAc.html',1,'IRLgAc'],['../classIRLgAc.html#a290636496526a9ed2057532649709375',1,'IRLgAc::IRLgAc()']]], + ['irmideaac_528',['IRMideaAC',['../classIRMideaAC.html',1,'IRMideaAC'],['../classIRMideaAC.html#a1ef2f532a1e6c6bfe89617d3fd0d9082',1,'IRMideaAC::IRMideaAC()']]], + ['irmitsubishi112_529',['IRMitsubishi112',['../classIRMitsubishi112.html',1,'IRMitsubishi112'],['../classIRMitsubishi112.html#adea6f3b7b7619b0bf6da4a94cec9d712',1,'IRMitsubishi112::IRMitsubishi112()']]], + ['irmitsubishi136_530',['IRMitsubishi136',['../classIRMitsubishi136.html',1,'IRMitsubishi136'],['../classIRMitsubishi136.html#ad92926b993869d0695f11ddb999b2090',1,'IRMitsubishi136::IRMitsubishi136()']]], + ['irmitsubishiac_531',['IRMitsubishiAC',['../classIRMitsubishiAC.html',1,'IRMitsubishiAC'],['../classIRMitsubishiAC.html#a83fabfd9ebed5cef8dd2a18a85fdf4e6',1,'IRMitsubishiAC::IRMitsubishiAC()']]], + ['irmitsubishiheavy152ac_532',['IRMitsubishiHeavy152Ac',['../classIRMitsubishiHeavy152Ac.html',1,'IRMitsubishiHeavy152Ac'],['../classIRMitsubishiHeavy152Ac.html#a704e9f96c2d0a07f9ba16a400d9c97aa',1,'IRMitsubishiHeavy152Ac::IRMitsubishiHeavy152Ac()']]], + ['irmitsubishiheavy88ac_533',['IRMitsubishiHeavy88Ac',['../classIRMitsubishiHeavy88Ac.html',1,'IRMitsubishiHeavy88Ac'],['../classIRMitsubishiHeavy88Ac.html#aceabecf4a615e807a4636ff5990d77d7',1,'IRMitsubishiHeavy88Ac::IRMitsubishiHeavy88Ac()']]], + ['irneoclimaac_534',['IRNeoclimaAc',['../classIRNeoclimaAc.html',1,'IRNeoclimaAc'],['../classIRNeoclimaAc.html#a99ed2962176e5f12f8387fab977c6395',1,'IRNeoclimaAc::IRNeoclimaAc()']]], + ['irpanasonicac_535',['IRPanasonicAc',['../classIRPanasonicAc.html',1,'IRPanasonicAc'],['../classIRPanasonicAc.html#ae8b0f4518ee1a913d47a7101b0a11185',1,'IRPanasonicAc::IRPanasonicAc()']]], + ['irparams_536',['irparams',['../IRrecv_8cpp.html#a5620be27a7445f25d43dbe3432ed6fd1',1,'IRrecv.cpp']]], + ['irparams_5fsave_537',['irparams_save',['../classIRrecv.html#a6fdac84ce51ce119972bf121ccc95aab',1,'IRrecv::irparams_save()'],['../IRrecv_8cpp.html#a96e84ae171529ee954c53e2e938dd998',1,'irparams_save(): IRrecv.cpp']]], + ['irparams_5ft_538',['irparams_t',['../structirparams__t.html',1,'']]], + ['irpin_539',['IRpin',['../classIRsend.html#ae4a6ea1e72f4861167002d6e7bf17b7c',1,'IRsend']]], + ['irrecv_540',['IRrecv',['../classIRrecv.html',1,'IRrecv'],['../classIRrecv.html#a8fe4d26ef1f863db1db9994fed5fc209',1,'IRrecv::IRrecv(const uint16_t recvpin, const uint16_t bufsize=kRawBuf, const uint8_t timeout=kTimeoutMs, const bool save_buffer=false, const uint8_t timer_num=kDefaultESP32Timer)'],['../classIRrecv.html#a3bb1bcc1c1a3184294dd35c8f6f758b1',1,'IRrecv::IRrecv(const uint16_t recvpin, const uint16_t bufsize=kRawBuf, const uint8_t timeout=kTimeoutMs, const bool save_buffer=false)']]], + ['irrecv_2ecpp_541',['IRrecv.cpp',['../IRrecv_8cpp.html',1,'']]], + ['irrecv_2eh_542',['IRrecv.h',['../IRrecv_8h.html',1,'']]], + ['irremote_5fmux_543',['irremote_mux',['../IRrecv_8cpp.html#ad2612f65707186ef7df0179d3636b4ea',1,'IRrecv.cpp']]], + ['irremoteesp8266_2eh_544',['IRremoteESP8266.h',['../IRremoteESP8266_8h.html',1,'']]], + ['irsamsungac_545',['IRSamsungAc',['../classIRSamsungAc.html',1,'IRSamsungAc'],['../classIRSamsungAc.html#a0db771b80d7d7a63b5ecb4b25efee609',1,'IRSamsungAc::IRSamsungAc()']]], + ['irsend_546',['IRsend',['../classIRsend.html',1,'IRsend'],['../classIRsend.html#a792780b7de996c90c86dd7b700eaf271',1,'IRsend::IRsend()']]], + ['irsend_2ecpp_547',['IRsend.cpp',['../IRsend_8cpp.html',1,'']]], + ['irsend_2eh_548',['IRsend.h',['../IRsend_8h.html',1,'']]], + ['irsharpac_549',['IRSharpAc',['../classIRSharpAc.html',1,'IRSharpAc'],['../classIRSharpAc.html#a30b5f8f634a41c943b4e1453d12bc980',1,'IRSharpAc::IRSharpAc()']]], + ['irtcl112ac_550',['IRTcl112Ac',['../classIRTcl112Ac.html',1,'IRTcl112Ac'],['../classIRTcl112Ac.html#a061bdfdf4444cb5e06fa90824985c1ec',1,'IRTcl112Ac::IRTcl112Ac()']]], + ['irtecoac_551',['IRTecoAc',['../classIRTecoAc.html',1,'IRTecoAc'],['../classIRTecoAc.html#a56e3f31a080bfd565570bf3b165e71d4',1,'IRTecoAc::IRTecoAc()']]], + ['irtext_2ecpp_552',['IRtext.cpp',['../IRtext_8cpp.html',1,'']]], + ['irtext_2eh_553',['IRtext.h',['../IRtext_8h.html',1,'']]], + ['irtimer_554',['IRtimer',['../classIRtimer.html',1,'IRtimer'],['../classIRtimer.html#a09d64d689137ef8ca68973bb9e550e76',1,'IRtimer::IRtimer()']]], + ['irtimer_2ecpp_555',['IRtimer.cpp',['../IRtimer_8cpp.html',1,'']]], + ['irtimer_2eh_556',['IRtimer.h',['../IRtimer_8h.html',1,'']]], + ['irtoshibaac_557',['IRToshibaAC',['../classIRToshibaAC.html',1,'IRToshibaAC'],['../classIRToshibaAC.html#abf2b3db316f7d6acb20c4f7ea2476ec2',1,'IRToshibaAC::IRToshibaAC()']]], + ['irtrotecesp_558',['IRTrotecESP',['../classIRTrotecESP.html',1,'IRTrotecESP'],['../classIRTrotecESP.html#a1b56b6e55bf133ccab6a482090408ee5',1,'IRTrotecESP::IRTrotecESP()']]], + ['irutils_559',['irutils',['../namespaceirutils.html',1,'']]], + ['irutils_2ecpp_560',['IRutils.cpp',['../IRutils_8cpp.html',1,'']]], + ['irutils_2eh_561',['IRutils.h',['../IRutils_8h.html',1,'']]], + ['irvestelac_562',['IRVestelAc',['../classIRVestelAc.html',1,'IRVestelAc'],['../classIRVestelAc.html#af1583ef81331edf112a0d04771c2cbec',1,'IRVestelAc::IRVestelAc()']]], + ['irwhirlpoolac_563',['IRWhirlpoolAc',['../classIRWhirlpoolAc.html',1,'IRWhirlpoolAc'],['../classIRWhirlpoolAc.html#a89bc9d440a5f7d04a602d7bc73904bc2',1,'IRWhirlpoolAc::IRWhirlpoolAc()']]], + ['isofftimeractive_564',['isOffTimerActive',['../classIRVestelAc.html#aa756171e82ed1b43593b81aa3a63b812',1,'IRVestelAc']]], + ['isofftimerenabled_565',['isOffTimerEnabled',['../classIRPanasonicAc.html#ac8e218b4886d66889734b01232767c8a',1,'IRPanasonicAc::isOffTimerEnabled()'],['../classIRWhirlpoolAc.html#a1bc1366524cf3c7fb426e908a166801f',1,'IRWhirlpoolAc::isOffTimerEnabled()']]], + ['isontimeractive_566',['isOnTimerActive',['../classIRVestelAc.html#a67f0e970af50fcf6e01e4cac85c5862a',1,'IRVestelAc']]], + ['isontimerenabled_567',['isOnTimerEnabled',['../classIRPanasonicAc.html#a04cbf8f5063a3892020d383c77abc57c',1,'IRPanasonicAc::isOnTimerEnabled()'],['../classIRWhirlpoolAc.html#aff1b8c2d063b376725a5a77745f6be3a',1,'IRWhirlpoolAc::isOnTimerEnabled()']]], + ['ispowerspecial_568',['isPowerSpecial',['../classIRSharpAc.html#a57072f2458897ffb9184769aca10b944',1,'IRSharpAc']]], + ['isprotocolsupported_569',['isProtocolSupported',['../classIRac.html#ad9c2fc9d07db70704f78a2d5f7be5b1c',1,'IRac']]], + ['isspecialstate_570',['isSpecialState',['../classIRCoolixAC.html#a51bde954328ca5887a8353ba5562b3db',1,'IRCoolixAC']]], + ['isswingvtoggle_571',['isSwingVToggle',['../classIRMideaAC.html#a848076f02a38a32c691a4617586862cc',1,'IRMideaAC']]], + ['istimecommand_572',['isTimeCommand',['../classIRVestelAc.html#ae811a07c1a8d82e7068c39b9ca73aaf1',1,'IRVestelAc']]], + ['istimeractive_573',['isTimerActive',['../classIRVestelAc.html#a160b73df8e1eda984f9bfbff3df7fa63',1,'IRVestelAc']]], + ['istimerenabled_574',['isTimerEnabled',['../classIRWhirlpoolAc.html#a5a713ffed99ab3450257d83e2d6e15ee',1,'IRWhirlpoolAc']]], + ['isvalidlgac_575',['isValidLgAc',['../classIRLgAc.html#a5984041eb12603ac1a277c28b355322a',1,'IRLgAc']]], + ['it_2dit_2eh_576',['it-IT.h',['../it-IT_8h.html',1,'']]], + ['internationalisation_20_28i18n_29_20_26_20locale_20files_577',['Internationalisation (I18N) & Locale Files',['../md_src_locale_README.html',1,'']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_a.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_a.html new file mode 100644 index 000000000..f2f3d3a38 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_a.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_a.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_a.js new file mode 100644 index 000000000..7ee51c41b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_a.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['jvc_578',['JVC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada5b6f507fb4bbd70ee70be4e2e0b0371d',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_b.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_b.html new file mode 100644 index 000000000..14f34036c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_b.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_b.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_b.js new file mode 100644 index 000000000..600985f6a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_b.js @@ -0,0 +1,2560 @@ +var searchData= +[ + ['k3dstr_579',['k3DStr',['../IRtext_8cpp.html#aedbfd5e861447c2cde9f7bb6aade1370',1,'k3DStr(): IRtext.cpp'],['../IRtext_8h.html#a084c940b7221cd1d85d4a3b58063051d',1,'k3DStr(): IRtext.cpp']]], + ['k6thsensestr_580',['k6thSenseStr',['../IRtext_8cpp.html#ad0bfc24932f22a599c7e7bf04fb57b10',1,'k6thSenseStr(): IRtext.cpp'],['../IRtext_8h.html#a7425119d393b134c4659db9d35691e35',1,'k6thSenseStr(): IRtext.cpp']]], + ['k8cheatstr_581',['k8CHeatStr',['../IRtext_8cpp.html#ac6ab822edcfe7768cd1a8b0426a1bd59',1,'k8CHeatStr(): IRtext.cpp'],['../IRtext_8h.html#acfcc1bc573f4520f3e37977a949b74e8',1,'k8CHeatStr(): IRtext.cpp']]], + ['kairflowstr_582',['kAirFlowStr',['../IRtext_8cpp.html#a7ecf1c6454bbf9963ca85a2bd7d4a34a',1,'kAirFlowStr(): IRtext.cpp'],['../IRtext_8h.html#a0f7e35a10e28e403da578c85b0e6b180',1,'kAirFlowStr(): IRtext.cpp']]], + ['kairwellbits_583',['kAirwellBits',['../IRremoteESP8266_8h.html#a570219a14f2d19c7a6ce0aecd37a3b1f',1,'IRremoteESP8266.h']]], + ['kairwellfootermark_584',['kAirwellFooterMark',['../ir__Airwell_8cpp.html#a2f41c6fe12eb5b3369ffb67fc6333431',1,'ir_Airwell.cpp']]], + ['kairwellhalfclockperiod_585',['kAirwellHalfClockPeriod',['../ir__Airwell_8cpp.html#a955f70631a1bc9be8453ccc9fbb3ecfc',1,'ir_Airwell.cpp']]], + ['kairwellhdrmark_586',['kAirwellHdrMark',['../ir__Airwell_8cpp.html#ad0c7b6c28df61b706eef2ec05506d8c2',1,'ir_Airwell.cpp']]], + ['kairwellhdrspace_587',['kAirwellHdrSpace',['../ir__Airwell_8cpp.html#ad7e80d679eaa5742f261619cc1115567',1,'ir_Airwell.cpp']]], + ['kairwellminrepeats_588',['kAirwellMinRepeats',['../IRremoteESP8266_8h.html#a669217ae5aa0baa159f7452f53551875',1,'IRremoteESP8266.h']]], + ['kairwelloverhead_589',['kAirwellOverhead',['../ir__Airwell_8cpp.html#a8365fb4b254f5eeb6fed59cdc627fead',1,'ir_Airwell.cpp']]], + ['kaiwarct501bits_590',['kAiwaRcT501Bits',['../IRremoteESP8266_8h.html#a9078adf040d21c9c3eb10ed69f9dced6',1,'IRremoteESP8266.h']]], + ['kaiwarct501minrepeats_591',['kAiwaRcT501MinRepeats',['../IRremoteESP8266_8h.html#ad796714d955b6cc8e207b03058eae5a3',1,'IRremoteESP8266.h']]], + ['kaiwarct501postbits_592',['kAiwaRcT501PostBits',['../ir__Aiwa_8cpp.html#a1ad2ad119febec79cb20bf2356ae4dd4',1,'ir_Aiwa.cpp']]], + ['kaiwarct501postdata_593',['kAiwaRcT501PostData',['../ir__Aiwa_8cpp.html#a5c8aa67edc9ceed9dc398f878930b1cb',1,'ir_Aiwa.cpp']]], + ['kaiwarct501prebits_594',['kAiwaRcT501PreBits',['../ir__Aiwa_8cpp.html#a614f30df204126f234ce1d256406f075',1,'ir_Aiwa.cpp']]], + ['kaiwarct501predata_595',['kAiwaRcT501PreData',['../ir__Aiwa_8cpp.html#a9aafbd2938553c9b97dac6f4e3edee6e',1,'ir_Aiwa.cpp']]], + ['kallprotocolnamesstr_596',['kAllProtocolNamesStr',['../IRtext_8cpp.html#a3ef36cf85e44181ecc4d11085b7abed6',1,'kAllProtocolNamesStr(): IRtext.cpp'],['../IRtext_8h.html#aa0dfe94cd4cba3bec642328f399dc775',1,'kAllProtocolNamesStr(): IRtext.cpp']]], + ['kalokabits_597',['kAlokaBits',['../IRremoteESP8266_8h.html#a864918ca63a5fe7345688a72d61ddf23',1,'IRremoteESP8266.h']]], + ['kalokaledblue_598',['kAlokaLedBlue',['../ir__NEC_8h.html#a49908cff59d8e7a4926638c74b796c61',1,'ir_NEC.h']]], + ['kalokaledgreen_599',['kAlokaLedGreen',['../ir__NEC_8h.html#aa6c6afc878f4b2a8d4b9349bf6766fb6',1,'ir_NEC.h']]], + ['kalokaledlightgreen_600',['kAlokaLedLightGreen',['../ir__NEC_8h.html#ab2daa6b17fd2d5e30fc47105e4c3c6b6',1,'ir_NEC.h']]], + ['kalokaledmidblue_601',['kAlokaLedMidBlue',['../ir__NEC_8h.html#a47d88027186cd96216bea935ca93d7bc',1,'ir_NEC.h']]], + ['kalokaledorange_602',['kAlokaLedOrange',['../ir__NEC_8h.html#a40f8ae5d6ec8f6aa887c73f032ce03bb',1,'ir_NEC.h']]], + ['kalokaledpink_603',['kAlokaLedPink',['../ir__NEC_8h.html#a53cf14e43062b82259e8d171a992ceff',1,'ir_NEC.h']]], + ['kalokaledpinkred_604',['kAlokaLedPinkRed',['../ir__NEC_8h.html#a20ef8a4a844577849b4b3bc7a86fe352',1,'ir_NEC.h']]], + ['kalokaledrainbow_605',['kAlokaLedRainbow',['../ir__NEC_8h.html#a724ce8d8c71c07a019ed2ddfba269151',1,'ir_NEC.h']]], + ['kalokaledred_606',['kAlokaLedRed',['../ir__NEC_8h.html#ade8f47e4607be919ca05b6dd6ed23ae9',1,'ir_NEC.h']]], + ['kalokaledtreegrow_607',['kAlokaLedTreeGrow',['../ir__NEC_8h.html#a5ecb76db25229f9f05044e54239144ee',1,'ir_NEC.h']]], + ['kalokaledwhite_608',['kAlokaLedWhite',['../ir__NEC_8h.html#a0c0b35e9d905de0b299e38e5807f363e',1,'ir_NEC.h']]], + ['kalokaledyellow_609',['kAlokaLedYellow',['../ir__NEC_8h.html#a1853a0e8856b8af97f458a180c41d6d5',1,'ir_NEC.h']]], + ['kalokanightfade_610',['kAlokaNightFade',['../ir__NEC_8h.html#adb8489faf42032a38187759b5f1037a1',1,'ir_NEC.h']]], + ['kalokanighttimer_611',['kAlokaNightTimer',['../ir__NEC_8h.html#a1b48b8bbd71fbe3728487f36123f4e4b',1,'ir_NEC.h']]], + ['kalokapower_612',['kAlokaPower',['../ir__NEC_8h.html#a147ecbccf8f11976f65b3f374b6ab2d0',1,'ir_NEC.h']]], + ['kamcorauto_613',['kAmcorAuto',['../ir__Amcor_8h.html#a9c02a27d5ed80963ff3b1ff32fc261c5',1,'ir_Amcor.h']]], + ['kamcorbits_614',['kAmcorBits',['../IRremoteESP8266_8h.html#a34bcab75a8ab94adfd46a245dd0748db',1,'IRremoteESP8266.h']]], + ['kamcorchecksumbyte_615',['kAmcorChecksumByte',['../ir__Amcor_8h.html#a6c60b38dd5b08d5787e346a55dfe0111',1,'ir_Amcor.h']]], + ['kamcorcool_616',['kAmcorCool',['../ir__Amcor_8h.html#a221c452a3323bd4d39a6084f84ecefbd',1,'ir_Amcor.h']]], + ['kamcordefaultrepeat_617',['kAmcorDefaultRepeat',['../IRremoteESP8266_8h.html#a746e1ce73c2ebd9bd1f5300494820a0c',1,'IRremoteESP8266.h']]], + ['kamcordry_618',['kAmcorDry',['../ir__Amcor_8h.html#a4d285053d14cf85d0c17e738c53538cd',1,'ir_Amcor.h']]], + ['kamcorfan_619',['kAmcorFan',['../ir__Amcor_8h.html#a5fa0c6e3a73c94fc419ff8d1aa1423c2',1,'ir_Amcor.h']]], + ['kamcorfanauto_620',['kAmcorFanAuto',['../ir__Amcor_8h.html#a3199dbace6444ed6ca7ff2e55a8a3a24',1,'ir_Amcor.h']]], + ['kamcorfanmax_621',['kAmcorFanMax',['../ir__Amcor_8h.html#a08ea054d4121220ba758a0e0cacef8ca',1,'ir_Amcor.h']]], + ['kamcorfanmed_622',['kAmcorFanMed',['../ir__Amcor_8h.html#a9ef019a27cf0724ff1f1ff39e06c0c87',1,'ir_Amcor.h']]], + ['kamcorfanmin_623',['kAmcorFanMin',['../ir__Amcor_8h.html#a0276f72dc5b39557850838c8c70fd157',1,'ir_Amcor.h']]], + ['kamcorfanoffset_624',['kAmcorFanOffset',['../ir__Amcor_8h.html#aaa3beed08599db5e155b3b54a3fc60bd',1,'ir_Amcor.h']]], + ['kamcorfansize_625',['kAmcorFanSize',['../ir__Amcor_8h.html#a4a6d1ad01cd89d8064efdd29311948b7',1,'ir_Amcor.h']]], + ['kamcorfootermark_626',['kAmcorFooterMark',['../ir__Amcor_8cpp.html#a3f877b05b07810ff43712dd4412af4f5',1,'ir_Amcor.cpp']]], + ['kamcorgap_627',['kAmcorGap',['../ir__Amcor_8cpp.html#a090f83ec3d4f3fd10baa16bf512dca23',1,'ir_Amcor.cpp']]], + ['kamcorhdrmark_628',['kAmcorHdrMark',['../ir__Amcor_8cpp.html#ab528f545e9af4ffb0f13d5674cfd1589',1,'ir_Amcor.cpp']]], + ['kamcorhdrspace_629',['kAmcorHdrSpace',['../ir__Amcor_8cpp.html#ae0e00c60c4220d27ef7051b45f2ae8b5',1,'ir_Amcor.cpp']]], + ['kamcorheat_630',['kAmcorHeat',['../ir__Amcor_8h.html#a9467539574a0030d166fac79684216f8',1,'ir_Amcor.h']]], + ['kamcormax_631',['kAmcorMax',['../ir__Amcor_8h.html#afac44479dc50e3885e474d2cf8d1f878',1,'ir_Amcor.h']]], + ['kamcormaxoffset_632',['kAmcorMaxOffset',['../ir__Amcor_8h.html#a2740428d3e431ff7b04e85ec73009660',1,'ir_Amcor.h']]], + ['kamcormaxsize_633',['kAmcorMaxSize',['../ir__Amcor_8h.html#a01d5ae3a2abe48f35971ad5373230ff8',1,'ir_Amcor.h']]], + ['kamcormaxtemp_634',['kAmcorMaxTemp',['../ir__Amcor_8h.html#a6460abc4e2b44e4ef3f680c7e195c019',1,'ir_Amcor.h']]], + ['kamcormintemp_635',['kAmcorMinTemp',['../ir__Amcor_8h.html#a2d952bf3f43cb55253a89db1bcc0b568',1,'ir_Amcor.h']]], + ['kamcormodefanbyte_636',['kAmcorModeFanByte',['../ir__Amcor_8h.html#a077021dbba23d1727caf1fe037e5bd88',1,'ir_Amcor.h']]], + ['kamcormodeoffset_637',['kAmcorModeOffset',['../ir__Amcor_8h.html#a1aebade414c6d493d5fd1ae8d9b4f626',1,'ir_Amcor.h']]], + ['kamcormodesize_638',['kAmcorModeSize',['../ir__Amcor_8h.html#aa306915bcc7fcf7209584d84dc5d1aa4',1,'ir_Amcor.h']]], + ['kamcoronemark_639',['kAmcorOneMark',['../ir__Amcor_8cpp.html#a402a3643dc6b85813eb5f28d742c4e7f',1,'ir_Amcor.cpp']]], + ['kamcoronespace_640',['kAmcorOneSpace',['../ir__Amcor_8cpp.html#a51163573fdc7b8017c7311f0e4011b1b',1,'ir_Amcor.cpp']]], + ['kamcorpowerbyte_641',['kAmcorPowerByte',['../ir__Amcor_8h.html#a47e85c75d262d9091f27c7ddca141ab7',1,'ir_Amcor.h']]], + ['kamcorpoweroff_642',['kAmcorPowerOff',['../ir__Amcor_8h.html#aeccd11f34ca0a93f682ab6c144f07fb7',1,'ir_Amcor.h']]], + ['kamcorpoweroffset_643',['kAmcorPowerOffset',['../ir__Amcor_8h.html#aeebaa4acca33937e47df058885d3167f',1,'ir_Amcor.h']]], + ['kamcorpoweron_644',['kAmcorPowerOn',['../ir__Amcor_8h.html#adf21c2364e64c818ba5379e78cae9d5c',1,'ir_Amcor.h']]], + ['kamcorpowersize_645',['kAmcorPowerSize',['../ir__Amcor_8h.html#a6a4e3568f341a7a60bdf7a4dc56fd482',1,'ir_Amcor.h']]], + ['kamcorspecialbyte_646',['kAmcorSpecialByte',['../ir__Amcor_8h.html#aa73133f5a673eebd7e8ca99155138cb7',1,'ir_Amcor.h']]], + ['kamcorstatelength_647',['kAmcorStateLength',['../IRremoteESP8266_8h.html#a62866e6918602533d590912487150bc7',1,'IRremoteESP8266.h']]], + ['kamcortempbyte_648',['kAmcorTempByte',['../ir__Amcor_8h.html#a9d352d1da6a93fc990786662fb3698de',1,'ir_Amcor.h']]], + ['kamcortempoffset_649',['kAmcorTempOffset',['../ir__Amcor_8h.html#ae7113af741d2edfebf0fc4d4cc181b2d',1,'ir_Amcor.h']]], + ['kamcortempsize_650',['kAmcorTempSize',['../ir__Amcor_8h.html#a4c5fb23ff11e99a2b860553b145e33bb',1,'ir_Amcor.h']]], + ['kamcortolerance_651',['kAmcorTolerance',['../ir__Amcor_8cpp.html#ad7a4b72f06c5e71002a44c3e4d483bef',1,'ir_Amcor.cpp']]], + ['kamcorventoffset_652',['kAmcorVentOffset',['../ir__Amcor_8h.html#aa231f74cdba0fe6813c2d6c77268d300',1,'ir_Amcor.h']]], + ['kamcorventon_653',['kAmcorVentOn',['../ir__Amcor_8h.html#a0774a9180ab233da61c77c717be02521',1,'ir_Amcor.h']]], + ['kamcorventsize_654',['kAmcorVentSize',['../ir__Amcor_8h.html#a55cd6972c20ddc0fa24ee8f42b50e46f',1,'ir_Amcor.h']]], + ['kamcorzeromark_655',['kAmcorZeroMark',['../ir__Amcor_8cpp.html#a6f16bcf81087461a4e196a2c670f29ee',1,'ir_Amcor.cpp']]], + ['kamcorzerospace_656',['kAmcorZeroSpace',['../ir__Amcor_8cpp.html#a0cbb87d1a5bb594cf428c79cd96c8733',1,'ir_Amcor.cpp']]], + ['kargoauto_657',['kArgoAuto',['../ir__Argo_8h.html#a527fa5776cb58f88013de5062c620b12',1,'ir_Argo.h']]], + ['kargobitmark_658',['kArgoBitMark',['../ir__Argo_8cpp.html#aa15902c11e3a7d3cbb25504764b163c1',1,'ir_Argo.cpp']]], + ['kargobits_659',['kArgoBits',['../IRremoteESP8266_8h.html#a351efcd1805c87bd338de81dab3f8fb2',1,'IRremoteESP8266.h']]], + ['kargocool_660',['kArgoCool',['../ir__Argo_8h.html#ab331356887b5f8f04f5ffdf9031fde71',1,'ir_Argo.h']]], + ['kargodefaultrepeat_661',['kArgoDefaultRepeat',['../IRremoteESP8266_8h.html#a9a2190c526885753c676db666e48b764',1,'IRremoteESP8266.h']]], + ['kargodry_662',['kArgoDry',['../ir__Argo_8h.html#ae119706139f65f730db477d060a7bc5d',1,'ir_Argo.h']]], + ['kargofan1_663',['kArgoFan1',['../ir__Argo_8h.html#abfbde2676afb8b027a26a49d947a1396',1,'ir_Argo.h']]], + ['kargofan2_664',['kArgoFan2',['../ir__Argo_8h.html#a7b544220198b6aa311da78bc02b0e211',1,'ir_Argo.h']]], + ['kargofan3_665',['kArgoFan3',['../ir__Argo_8h.html#aa34af62e7134bbca2028d74ba7dfed4e',1,'ir_Argo.h']]], + ['kargofanauto_666',['kArgoFanAuto',['../ir__Argo_8h.html#a3b17c0ba868b439135e6e016452f1623',1,'ir_Argo.h']]], + ['kargofanoffset_667',['kArgoFanOffset',['../ir__Argo_8h.html#ab652e466dfce6bfabab04f70e23e6bc9',1,'ir_Argo.h']]], + ['kargofansize_668',['kArgoFanSize',['../ir__Argo_8h.html#a032348f63ce0e391120161f2547ab280',1,'ir_Argo.h']]], + ['kargoflap1_669',['kArgoFlap1',['../ir__Argo_8h.html#a477dac25a687b9d875cf9e94623d5e84',1,'ir_Argo.h']]], + ['kargoflap2_670',['kArgoFlap2',['../ir__Argo_8h.html#aa72401adcdd23c12d36f98370c605ef6',1,'ir_Argo.h']]], + ['kargoflap3_671',['kArgoFlap3',['../ir__Argo_8h.html#ab18e2931823d631b533c14f417ed4adb',1,'ir_Argo.h']]], + ['kargoflap4_672',['kArgoFlap4',['../ir__Argo_8h.html#a59204076030de56e1160fc599879b142',1,'ir_Argo.h']]], + ['kargoflap5_673',['kArgoFlap5',['../ir__Argo_8h.html#a5a3f4c1b1303b177a924c61dfdcce3e6',1,'ir_Argo.h']]], + ['kargoflap6_674',['kArgoFlap6',['../ir__Argo_8h.html#ac11d6b575b4abc7ac5aec9006ac41634',1,'ir_Argo.h']]], + ['kargoflapauto_675',['kArgoFlapAuto',['../ir__Argo_8h.html#af7f4a97011f94e4bf453e7cfd01fd780',1,'ir_Argo.h']]], + ['kargoflapfull_676',['kArgoFlapFull',['../ir__Argo_8h.html#a8befe8d8b6826fc79176b66eea8352b7',1,'ir_Argo.h']]], + ['kargogap_677',['kArgoGap',['../ir__Argo_8cpp.html#a1a28fc063dea8beacbaac39cf8e9b81b',1,'ir_Argo.cpp']]], + ['kargohdrmark_678',['kArgoHdrMark',['../ir__Argo_8cpp.html#a5c25d5a07e397fe86378021e7c3f2980',1,'ir_Argo.cpp']]], + ['kargohdrspace_679',['kArgoHdrSpace',['../ir__Argo_8cpp.html#a10e8a2ac55f8b123093cd92757d1603d',1,'ir_Argo.cpp']]], + ['kargoheat_680',['kArgoHeat',['../ir__Argo_8h.html#a431536a03ef985b53a4147df5a043b21',1,'ir_Argo.h']]], + ['kargoheatauto_681',['kArgoHeatAuto',['../ir__Argo_8h.html#a154f8b3e0d600d87b2822027bf0c6619',1,'ir_Argo.h']]], + ['kargoheatbit_682',['kArgoHeatBit',['../ir__Argo_8h.html#ada4b42336f3d423e3ef1060605c7f7f1',1,'ir_Argo.h']]], + ['kargoheatblink_683',['kArgoHeatBlink',['../ir__Argo_8h.html#ad29933c939f9364399dfa0f7eaa8cce6',1,'ir_Argo.h']]], + ['kargoifeelbitoffset_684',['kArgoIFeelBitOffset',['../ir__Argo_8h.html#a0dc059f228415b3cc7a22b50fff71e9c',1,'ir_Argo.h']]], + ['kargomaxbitoffset_685',['kArgoMaxBitOffset',['../ir__Argo_8h.html#af487de7857781edbe368a2ba724fc7c7',1,'ir_Argo.h']]], + ['kargomaxroomtemp_686',['kArgoMaxRoomTemp',['../ir__Argo_8h.html#a27427d4479dc126e8782985008d4dd7d',1,'ir_Argo.h']]], + ['kargomaxtemp_687',['kArgoMaxTemp',['../ir__Argo_8h.html#a2409d2f472fb950c070fa5c0a07f69ce',1,'ir_Argo.h']]], + ['kargomintemp_688',['kArgoMinTemp',['../ir__Argo_8h.html#a4bc4e4cfe12af43730cb128f4043ad11',1,'ir_Argo.h']]], + ['kargomodeoffset_689',['kArgoModeOffset',['../ir__Argo_8h.html#a127045d26371fa051310208b0a3d0316',1,'ir_Argo.h']]], + ['kargomodesize_690',['kArgoModeSize',['../ir__Argo_8h.html#a98e4d25798fb992200ade3dd5e53a401',1,'ir_Argo.h']]], + ['kargonightbitoffset_691',['kArgoNightBitOffset',['../ir__Argo_8h.html#a4d0f78fc9017ed0ff93c77794a411738',1,'ir_Argo.h']]], + ['kargooff_692',['kArgoOff',['../ir__Argo_8h.html#af3c6e4f7b18095179ea9e20e45e1890a',1,'ir_Argo.h']]], + ['kargoonespace_693',['kArgoOneSpace',['../ir__Argo_8cpp.html#a47131b446d160fed9c7af1886d3580e4',1,'ir_Argo.cpp']]], + ['kargopowerbitoffset_694',['kArgoPowerBitOffset',['../ir__Argo_8h.html#a26c8b660b323ac8a8f1bbf30d7f40bf7',1,'ir_Argo.h']]], + ['kargoroomtemphighoffset_695',['kArgoRoomTempHighOffset',['../ir__Argo_8h.html#abe1b434b09b0c42d0d7c90496d180aeb',1,'ir_Argo.h']]], + ['kargoroomtemphighsize_696',['kArgoRoomTempHighSize',['../ir__Argo_8h.html#a6fdcdd90f37c2f4572815b279379484d',1,'ir_Argo.h']]], + ['kargoroomtemplowoffset_697',['kArgoRoomTempLowOffset',['../ir__Argo_8h.html#a1272f85bf89b7f0326352ae7a05b2244',1,'ir_Argo.h']]], + ['kargoroomtemplowsize_698',['kArgoRoomTempLowSize',['../ir__Argo_8h.html#a2cd767383014feb1c6cdea45715e49c7',1,'ir_Argo.h']]], + ['kargostatelength_699',['kArgoStateLength',['../IRremoteESP8266_8h.html#a5f38a56eacd9964a8514cb57de287a45',1,'IRremoteESP8266.h']]], + ['kargotempdelta_700',['kArgoTempDelta',['../ir__Argo_8h.html#a7256560730a73dcaaa60cdfc8140fc0b',1,'ir_Argo.h']]], + ['kargotemphighoffset_701',['kArgoTempHighOffset',['../ir__Argo_8h.html#af06b47b51a4b837ee92a2e2774d214e3',1,'ir_Argo.h']]], + ['kargotemphighsize_702',['kArgoTempHighSize',['../ir__Argo_8h.html#af2b0c18a612c097f6356ff04ce9c78d0',1,'ir_Argo.h']]], + ['kargotemplowoffset_703',['kArgoTempLowOffset',['../ir__Argo_8h.html#a17137f6bec2d629cca04a859bb48dae8',1,'ir_Argo.h']]], + ['kargotemplowsize_704',['kArgoTempLowSize',['../ir__Argo_8h.html#aa50679112dc998ff06588d9a35ff313c',1,'ir_Argo.h']]], + ['kargozerospace_705',['kArgoZeroSpace',['../ir__Argo_8cpp.html#a5e06b6d522b35f503ca1e5db27f32ff6',1,'ir_Argo.cpp']]], + ['kauto_706',['kAuto',['../namespacestdAc.html#a99ad268c783486f9b3207cb78f48444faa8c857c2f1b000c92f9794ebf53888d7',1,'stdAc::kAuto()'],['../namespacestdAc.html#a8bb0dbf18fe69f639f4ac0b3ff133383aa8c857c2f1b000c92f9794ebf53888d7',1,'stdAc::kAuto()'],['../namespacestdAc.html#ac07f224c7bb47cac55dd01f24770ef43aa8c857c2f1b000c92f9794ebf53888d7',1,'stdAc::kAuto()'],['../namespacestdAc.html#aae50ee315fa9c9ec1a4078da40d6b147aa8c857c2f1b000c92f9794ebf53888d7',1,'stdAc::kAuto()']]], + ['kautomaticstr_707',['kAutomaticStr',['../IRtext_8cpp.html#a66a32b6387a99572644e91f3299910a6',1,'kAutomaticStr(): IRtext.cpp'],['../IRtext_8h.html#a0fc9126a02b933a2af702cd6fdcb47ea',1,'kAutomaticStr(): IRtext.cpp']]], + ['kautostr_708',['kAutoStr',['../IRtext_8cpp.html#ae8ec328761b0218d0b18479a972b1121',1,'kAutoStr(): IRtext.cpp'],['../IRtext_8h.html#a15a085c4f9e89926d2c165de4b1755d9',1,'kAutoStr(): IRtext.cpp']]], + ['kbeepstr_709',['kBeepStr',['../IRtext_8cpp.html#a429f5c2f5aea162bd1568e8489aecb28',1,'kBeepStr(): IRtext.cpp'],['../IRtext_8h.html#a2e98c29968ade682d94f35e28364c878',1,'kBeepStr(): IRtext.cpp']]], + ['kbitsstr_710',['kBitsStr',['../IRtext_8cpp.html#aaabaca413c37bb6b18dc13daf5b335c1',1,'kBitsStr(): IRtext.cpp'],['../IRtext_8h.html#aaf3e1b0041b00b261dfd949b41569d94',1,'kBitsStr(): IRtext.cpp']]], + ['kbottomstr_711',['kBottomStr',['../IRtext_8cpp.html#ab0bd355efc13bd278a0e33765a783cd0',1,'kBottomStr(): IRtext.cpp'],['../IRtext_8h.html#accfb2322a40cfaf6707394e43f39e2a3',1,'kBottomStr(): IRtext.cpp']]], + ['kbreezestr_712',['kBreezeStr',['../IRtext_8cpp.html#ab0317e8cf720936fb02816e7827bea9e',1,'kBreezeStr(): IRtext.cpp'],['../IRtext_8h.html#af4f31b53c295a877507e3ef5a5fbbc9d',1,'kBreezeStr(): IRtext.cpp']]], + ['kbuttonstr_713',['kButtonStr',['../IRtext_8cpp.html#a6ee11e0a45632c54e34bed14c3a971ce',1,'kButtonStr(): IRtext.cpp'],['../IRtext_8h.html#a58bf62453a96d4e84bd1da3449b8799e',1,'kButtonStr(): IRtext.cpp']]], + ['kcancelstr_714',['kCancelStr',['../IRtext_8cpp.html#af79c3879bac5ca97947f16c3a6a03321',1,'kCancelStr(): IRtext.cpp'],['../IRtext_8h.html#ab64c4cdebbc72cbb62ae6cd9a449876b',1,'kCancelStr(): IRtext.cpp']]], + ['kcarrierac40bitmark_715',['kCarrierAc40BitMark',['../ir__Carrier_8cpp.html#a3f8996aa3a7b9b871bc6556f98efb345',1,'ir_Carrier.cpp']]], + ['kcarrierac40bits_716',['kCarrierAc40Bits',['../IRremoteESP8266_8h.html#a56d1176a7b3fe59aeb3f4f39926c617d',1,'IRremoteESP8266.h']]], + ['kcarrierac40gap_717',['kCarrierAc40Gap',['../ir__Carrier_8cpp.html#aa5f0d39a4e12645a6fb477efb3191384',1,'ir_Carrier.cpp']]], + ['kcarrierac40hdrmark_718',['kCarrierAc40HdrMark',['../ir__Carrier_8cpp.html#a4b77665ded6dab393779d2763bc367f0',1,'ir_Carrier.cpp']]], + ['kcarrierac40hdrspace_719',['kCarrierAc40HdrSpace',['../ir__Carrier_8cpp.html#a5ea98bc575a7ac8d7f5da937feeaeed4',1,'ir_Carrier.cpp']]], + ['kcarrierac40minrepeat_720',['kCarrierAc40MinRepeat',['../IRremoteESP8266_8h.html#a222aa743f398883a4910fbbb6d408bdc',1,'IRremoteESP8266.h']]], + ['kcarrierac40onespace_721',['kCarrierAc40OneSpace',['../ir__Carrier_8cpp.html#a79073c06820817e077c5bd8d9b8acfbd',1,'ir_Carrier.cpp']]], + ['kcarrierac40zerospace_722',['kCarrierAc40ZeroSpace',['../ir__Carrier_8cpp.html#a2ee9b60c12887983a6f4f123db6fd5e9',1,'ir_Carrier.cpp']]], + ['kcarrierac64bitmark_723',['kCarrierAc64BitMark',['../ir__Carrier_8cpp.html#ae32b2dab6a654fa293f54684da45c5c0',1,'ir_Carrier.cpp']]], + ['kcarrierac64bits_724',['kCarrierAc64Bits',['../IRremoteESP8266_8h.html#a41bc7ab7289e499ad33901da3eab661a',1,'IRremoteESP8266.h']]], + ['kcarrierac64checksumoffset_725',['kCarrierAc64ChecksumOffset',['../ir__Carrier_8h.html#a3aa65474b5be8c77d498b7e83d8b8f31',1,'ir_Carrier.h']]], + ['kcarrierac64checksumsize_726',['kCarrierAc64ChecksumSize',['../ir__Carrier_8h.html#a0b446c17c4965508f335e68c786f0596',1,'ir_Carrier.h']]], + ['kcarrierac64cool_727',['kCarrierAc64Cool',['../ir__Carrier_8h.html#aa75d5965da484d09f6f4c645cdb23869',1,'ir_Carrier.h']]], + ['kcarrierac64fan_728',['kCarrierAc64Fan',['../ir__Carrier_8h.html#a57655ceea762b18e0dd96724ddf888bd',1,'ir_Carrier.h']]], + ['kcarrierac64fanauto_729',['kCarrierAc64FanAuto',['../ir__Carrier_8h.html#a12d1fb295a0d9cf407040ab544acc245',1,'ir_Carrier.h']]], + ['kcarrierac64fanhigh_730',['kCarrierAc64FanHigh',['../ir__Carrier_8h.html#a099f2e82998bd78d25cec17a4be5f230',1,'ir_Carrier.h']]], + ['kcarrierac64fanlow_731',['kCarrierAc64FanLow',['../ir__Carrier_8h.html#aaeee61e5924bdc8028c4775f96ba14d2',1,'ir_Carrier.h']]], + ['kcarrierac64fanmedium_732',['kCarrierAc64FanMedium',['../ir__Carrier_8h.html#aeb8943f8d9f2bd95a9df6500eea7cba4',1,'ir_Carrier.h']]], + ['kcarrierac64fanoffset_733',['kCarrierAc64FanOffset',['../ir__Carrier_8h.html#abbd2da4887e1c313df40506c82cba836',1,'ir_Carrier.h']]], + ['kcarrierac64fansize_734',['kCarrierAc64FanSize',['../ir__Carrier_8h.html#aebcfb795028fea2d1b4bfde9a045e672',1,'ir_Carrier.h']]], + ['kcarrierac64gap_735',['kCarrierAc64Gap',['../ir__Carrier_8cpp.html#a6f7ba77f1350126d78a23d7ba967e258',1,'ir_Carrier.cpp']]], + ['kcarrierac64hdrmark_736',['kCarrierAc64HdrMark',['../ir__Carrier_8cpp.html#a19dc2108d4490c82c03c87c625bc5f31',1,'ir_Carrier.cpp']]], + ['kcarrierac64hdrspace_737',['kCarrierAc64HdrSpace',['../ir__Carrier_8cpp.html#ad73dbf55f5ffa03d92ec699b23e8ca8d',1,'ir_Carrier.cpp']]], + ['kcarrierac64heat_738',['kCarrierAc64Heat',['../ir__Carrier_8h.html#ac261ba8bff6f103bb9043c85a6f21d58',1,'ir_Carrier.h']]], + ['kcarrierac64maxtemp_739',['kCarrierAc64MaxTemp',['../ir__Carrier_8h.html#a5653bc180a4c849b5e0b33b957255ae4',1,'ir_Carrier.h']]], + ['kcarrierac64minrepeat_740',['kCarrierAc64MinRepeat',['../IRremoteESP8266_8h.html#a8b2b3670dc74ce9fbf3c8b511422a06c',1,'IRremoteESP8266.h']]], + ['kcarrierac64mintemp_741',['kCarrierAc64MinTemp',['../ir__Carrier_8h.html#a9e7a88bf52839ecb34da1966bb8a956b',1,'ir_Carrier.h']]], + ['kcarrierac64modeoffset_742',['kCarrierAc64ModeOffset',['../ir__Carrier_8h.html#a7f2ef38df606cb00f1c859914fc6f085',1,'ir_Carrier.h']]], + ['kcarrierac64modesize_743',['kCarrierAc64ModeSize',['../ir__Carrier_8h.html#a8d28dd57b7ad6b9f4bb2ba11fa4b63f7',1,'ir_Carrier.h']]], + ['kcarrierac64offtimerenableoffset_744',['kCarrierAc64OffTimerEnableOffset',['../ir__Carrier_8h.html#a1afcf0873e42c5cda5328bfe97d97ade',1,'ir_Carrier.h']]], + ['kcarrierac64offtimeroffset_745',['kCarrierAc64OffTimerOffset',['../ir__Carrier_8h.html#a0c9189a86abe1bc41f9db34e4ab77172',1,'ir_Carrier.h']]], + ['kcarrierac64onespace_746',['kCarrierAc64OneSpace',['../ir__Carrier_8cpp.html#a58ea051d56227a4037682f5d612b4cc7',1,'ir_Carrier.cpp']]], + ['kcarrierac64ontimerenableoffset_747',['kCarrierAc64OnTimerEnableOffset',['../ir__Carrier_8h.html#a8a03bb9d7ead5116dff0b81732300b40',1,'ir_Carrier.h']]], + ['kcarrierac64ontimeroffset_748',['kCarrierAc64OnTimerOffset',['../ir__Carrier_8h.html#ad2fd8df9a5114e0fc34a3657aac61f9c',1,'ir_Carrier.h']]], + ['kcarrierac64poweroffset_749',['kCarrierAc64PowerOffset',['../ir__Carrier_8h.html#a943b94e79e98237678b66f6f4a1b6af4',1,'ir_Carrier.h']]], + ['kcarrierac64sleepoffset_750',['kCarrierAc64SleepOffset',['../ir__Carrier_8h.html#a8ae023f5e44d5c29df41ab0f5cd534a0',1,'ir_Carrier.h']]], + ['kcarrierac64swingvoffset_751',['kCarrierAc64SwingVOffset',['../ir__Carrier_8h.html#a186dcc18acb75f98370d71f4640f02ce',1,'ir_Carrier.h']]], + ['kcarrierac64tempoffset_752',['kCarrierAc64TempOffset',['../ir__Carrier_8h.html#a3d3663b7e55cae59f1b8bba5ffbb5fad',1,'ir_Carrier.h']]], + ['kcarrierac64tempsize_753',['kCarrierAc64TempSize',['../ir__Carrier_8h.html#ae9e16d5ab69b493607ce84dfbded150f',1,'ir_Carrier.h']]], + ['kcarrierac64timermax_754',['kCarrierAc64TimerMax',['../ir__Carrier_8h.html#a78a34b51e51dc3b4129f350673c9fa96',1,'ir_Carrier.h']]], + ['kcarrierac64timermin_755',['kCarrierAc64TimerMin',['../ir__Carrier_8h.html#aeebac3e61246f2e148806d4b4e8ac13e',1,'ir_Carrier.h']]], + ['kcarrierac64timersize_756',['kCarrierAc64TimerSize',['../ir__Carrier_8h.html#adced87f4aed397ea8f2bb5ac2749dce5',1,'ir_Carrier.h']]], + ['kcarrierac64zerospace_757',['kCarrierAc64ZeroSpace',['../ir__Carrier_8cpp.html#af28d4332e0f1ad19aa743b993f44cdc7',1,'ir_Carrier.cpp']]], + ['kcarrieracbitmark_758',['kCarrierAcBitMark',['../ir__Carrier_8cpp.html#af4a608f81c745734499ec1842167940b',1,'ir_Carrier.cpp']]], + ['kcarrieracbits_759',['kCarrierAcBits',['../IRremoteESP8266_8h.html#a668d9ac84f7dae61c35534b842d4956b',1,'IRremoteESP8266.h']]], + ['kcarrieracfreq_760',['kCarrierAcFreq',['../ir__Carrier_8cpp.html#a795dc2d9b122bd3794fddbddef571058',1,'ir_Carrier.cpp']]], + ['kcarrieracgap_761',['kCarrierAcGap',['../ir__Carrier_8cpp.html#a00767c0b503a7fc8f0b2ddfac24a4f85',1,'ir_Carrier.cpp']]], + ['kcarrierachdrmark_762',['kCarrierAcHdrMark',['../ir__Carrier_8cpp.html#ad9a7754e77cfcfd6c6032d497bc4528d',1,'ir_Carrier.cpp']]], + ['kcarrierachdrspace_763',['kCarrierAcHdrSpace',['../ir__Carrier_8cpp.html#a8e09857e2fe15d6983ec0384c57140d4',1,'ir_Carrier.cpp']]], + ['kcarrieracminrepeat_764',['kCarrierAcMinRepeat',['../IRremoteESP8266_8h.html#a78c8a8b11179e8fd20bf09fa35f6b886',1,'IRremoteESP8266.h']]], + ['kcarrieraconespace_765',['kCarrierAcOneSpace',['../ir__Carrier_8cpp.html#ab04a214a7c2e0439384736c46ddc6c61',1,'ir_Carrier.cpp']]], + ['kcarrieraczerospace_766',['kCarrierAcZeroSpace',['../ir__Carrier_8cpp.html#a51c9c4bbd6e2927baac15dc60c1e60fa',1,'ir_Carrier.cpp']]], + ['kceilingstr_767',['kCeilingStr',['../IRtext_8cpp.html#a5258c9d80502d5a8e14bb324a394452b',1,'kCeilingStr(): IRtext.cpp'],['../IRtext_8h.html#aa47afe8f4c175954e9439c0c9e48c83e',1,'kCeilingStr(): IRtext.cpp']]], + ['kcelsiusstr_768',['kCelsiusStr',['../IRtext_8cpp.html#af0ad7ca76c659a17872960bcbcfbdbbf',1,'kCelsiusStr(): IRtext.cpp'],['../IRtext_8h.html#aae21484e9f049a7cfa507068abd3915e',1,'kCelsiusStr(): IRtext.cpp']]], + ['kcentrestr_769',['kCentreStr',['../IRtext_8cpp.html#a87a4151e0361c9f75d0d5c00f9bad1ee',1,'kCentreStr(): IRtext.cpp'],['../IRtext_8h.html#aab13bc11db65584fbb8a61c686d67228',1,'kCentreStr(): IRtext.cpp']]], + ['kchangestr_770',['kChangeStr',['../IRtext_8cpp.html#a1f6396eb9bd4327a7a2307e5724c1dd7',1,'kChangeStr(): IRtext.cpp'],['../IRtext_8h.html#a46e6bd06cfbf5f462042d7c720db01ae',1,'kChangeStr(): IRtext.cpp']]], + ['kcirculatestr_771',['kCirculateStr',['../IRtext_8cpp.html#a869ef1f579373ff4b5b61b1cba215680',1,'kCirculateStr(): IRtext.cpp'],['../IRtext_8h.html#a0ba8b339babc7f7f26dbab2399bcc578',1,'kCirculateStr(): IRtext.cpp']]], + ['kcleanstr_772',['kCleanStr',['../IRtext_8cpp.html#ad2d97c52e8df2704654fdbd0a7a0561e',1,'kCleanStr(): IRtext.cpp'],['../IRtext_8h.html#a45c17b23773e9dcded65a82577b00263',1,'kCleanStr(): IRtext.cpp']]], + ['kclockstr_773',['kClockStr',['../IRtext_8cpp.html#ad39bd469d5474159463543184cfae321',1,'kClockStr(): IRtext.cpp'],['../IRtext_8h.html#a6e4b8f591a1d3d399a559d41847b3fa8',1,'kClockStr(): IRtext.cpp']]], + ['kcodestr_774',['kCodeStr',['../IRtext_8cpp.html#a26e4bf74871ce457f42ec839545987f4',1,'kCodeStr(): IRtext.cpp'],['../IRtext_8h.html#a58a9da5cec40746dbe20455c6ef6c8fd',1,'kCodeStr(): IRtext.cpp']]], + ['kcolonspacestr_775',['kColonSpaceStr',['../IRtext_8cpp.html#a5d978c9ac25163a9629b7e8e2d37d25e',1,'kColonSpaceStr(): IRtext.cpp'],['../IRtext_8h.html#aab1b0d2ea5169c1e1d8eff4daef36512',1,'kColonSpaceStr(): IRtext.cpp']]], + ['kcomfortstr_776',['kComfortStr',['../IRtext_8cpp.html#aa7f0cfdb126ff7b0f8db6033bb51f36d',1,'kComfortStr(): IRtext.cpp'],['../IRtext_8h.html#a20037561545d4ba4cfe66c1e103ecde1',1,'kComfortStr(): IRtext.cpp']]], + ['kcommandstr_777',['kCommandStr',['../IRtext_8cpp.html#afd5865ea8c0f8565369dd2c4ee4622d6',1,'kCommandStr(): IRtext.cpp'],['../IRtext_8h.html#afdc9e8cc5c8c5c03749898d4f2d38606',1,'kCommandStr(): IRtext.cpp']]], + ['kcommaspacestr_778',['kCommaSpaceStr',['../IRtext_8cpp.html#ac8a9678d4c9eeee17a9dc28624c0ab49',1,'kCommaSpaceStr(): IRtext.cpp'],['../IRtext_8h.html#a48f5dfcf2e0f13f502980d42e879aec3',1,'kCommaSpaceStr(): IRtext.cpp']]], + ['kcool_779',['kCool',['../namespacestdAc.html#a99ad268c783486f9b3207cb78f48444fab9480fe865ab6bbfb66c8308068a06c2',1,'stdAc']]], + ['kcoolixauto_780',['kCoolixAuto',['../ir__Coolix_8h.html#a73c1ef7c2c80c861256a14a9f256b125',1,'ir_Coolix.h']]], + ['kcoolixbitmark_781',['kCoolixBitMark',['../ir__Coolix_8cpp.html#acd8562a27ec6c0a6c2cf9480082e04cd',1,'ir_Coolix.cpp']]], + ['kcoolixbitmarkticks_782',['kCoolixBitMarkTicks',['../ir__Coolix_8cpp.html#aefaa206b4316a4fd921f7171295d1232',1,'ir_Coolix.cpp']]], + ['kcoolixbits_783',['kCoolixBits',['../IRremoteESP8266_8h.html#aed48c68a637e4b45b80bbf4964ea79f9',1,'IRremoteESP8266.h']]], + ['kcoolixclean_784',['kCoolixClean',['../ir__Coolix_8h.html#a5cc9fcde4a6da54917b4d69bb352bc86',1,'ir_Coolix.h']]], + ['kcoolixcmdfan_785',['kCoolixCmdFan',['../ir__Coolix_8h.html#a7d5ff02f4a0c379322877b3dcf934c77',1,'ir_Coolix.h']]], + ['kcoolixcool_786',['kCoolixCool',['../ir__Coolix_8h.html#ae285ee4206fe45d25bb1d99b848c7e65',1,'ir_Coolix.h']]], + ['kcoolixdefaultrepeat_787',['kCoolixDefaultRepeat',['../IRremoteESP8266_8h.html#aa89410d369d71738c8cbefae6ac3b00f',1,'IRremoteESP8266.h']]], + ['kcoolixdefaultstate_788',['kCoolixDefaultState',['../ir__Coolix_8h.html#ad54ebf20658c33e5ad54fc54a513511e',1,'ir_Coolix.h']]], + ['kcoolixdry_789',['kCoolixDry',['../ir__Coolix_8h.html#a904c4135f61120e71577f6830adae689',1,'ir_Coolix.h']]], + ['kcoolixfan_790',['kCoolixFan',['../ir__Coolix_8h.html#a2e050321c994844f2ff6668ba6973ac4',1,'ir_Coolix.h']]], + ['kcoolixfanauto_791',['kCoolixFanAuto',['../ir__Coolix_8h.html#ac25d3c45ed7d7d30ff2ebf617d8265f0',1,'ir_Coolix.h']]], + ['kcoolixfanauto0_792',['kCoolixFanAuto0',['../ir__Coolix_8h.html#a38cccd1edee2c88c1b080f1d5600ead7',1,'ir_Coolix.h']]], + ['kcoolixfanfixed_793',['kCoolixFanFixed',['../ir__Coolix_8h.html#a37a3a23d8fe30df024cb844f82f90b2a',1,'ir_Coolix.h']]], + ['kcoolixfanmax_794',['kCoolixFanMax',['../ir__Coolix_8h.html#aabb349ee111467088b9a292950aba753',1,'ir_Coolix.h']]], + ['kcoolixfanmed_795',['kCoolixFanMed',['../ir__Coolix_8h.html#a2750626cda2e389df901b459805e09bd',1,'ir_Coolix.h']]], + ['kcoolixfanmin_796',['kCoolixFanMin',['../ir__Coolix_8h.html#a6c0086075cce1698c48cc30e045ab5bf',1,'ir_Coolix.h']]], + ['kcoolixfanoffset_797',['kCoolixFanOffset',['../ir__Coolix_8h.html#a1656f488974bd12db4049dfa8ff43a4e',1,'ir_Coolix.h']]], + ['kcoolixfansize_798',['kCoolixFanSize',['../ir__Coolix_8h.html#a5f4649b5b73766245bc82191cdc0e596',1,'ir_Coolix.h']]], + ['kcoolixfantempcode_799',['kCoolixFanTempCode',['../ir__Coolix_8h.html#a6d2d6f2fd8f5e9a4491623b9351efcba',1,'ir_Coolix.h']]], + ['kcoolixfanzonefollow_800',['kCoolixFanZoneFollow',['../ir__Coolix_8h.html#a5a71c6acd18b3198c7900e2de34c48a3',1,'ir_Coolix.h']]], + ['kcoolixhdrmark_801',['kCoolixHdrMark',['../ir__Coolix_8cpp.html#a746299797d958ccf116e6d1cdab3ad06',1,'ir_Coolix.cpp']]], + ['kcoolixhdrmarkticks_802',['kCoolixHdrMarkTicks',['../ir__Coolix_8cpp.html#a04d520a0fe3d773f377810174e5463a4',1,'ir_Coolix.cpp']]], + ['kcoolixhdrspace_803',['kCoolixHdrSpace',['../ir__Coolix_8cpp.html#ab7ff2a6bd99e0e6a0db3f14350cca84c',1,'ir_Coolix.cpp']]], + ['kcoolixhdrspaceticks_804',['kCoolixHdrSpaceTicks',['../ir__Coolix_8cpp.html#a58951e9800513b019ccb9f04ae55716f',1,'ir_Coolix.cpp']]], + ['kcoolixheat_805',['kCoolixHeat',['../ir__Coolix_8h.html#a234b39696f0b2fac6b37aa309082505e',1,'ir_Coolix.h']]], + ['kcoolixled_806',['kCoolixLed',['../ir__Coolix_8h.html#a68ae46e117caf0d7a3cc2ef9492495f1',1,'ir_Coolix.h']]], + ['kcoolixmingap_807',['kCoolixMinGap',['../ir__Coolix_8cpp.html#a46da2480f6850af899db74a4f2270cdc',1,'ir_Coolix.cpp']]], + ['kcoolixmingapticks_808',['kCoolixMinGapTicks',['../ir__Coolix_8cpp.html#a94f47fbf027fcb90664b302ff123f535',1,'ir_Coolix.cpp']]], + ['kcoolixmodeoffset_809',['kCoolixModeOffset',['../ir__Coolix_8h.html#acd17067177e1cc6776b7932afd9fbdb2',1,'ir_Coolix.h']]], + ['kcoolixmodesize_810',['kCoolixModeSize',['../ir__Coolix_8h.html#a69e5ee4c5eb95ca3346d9d9186a688a8',1,'ir_Coolix.h']]], + ['kcoolixoff_811',['kCoolixOff',['../ir__Coolix_8h.html#aef6f59b83a14b8505f395b2eb8d8ad39',1,'ir_Coolix.h']]], + ['kcoolixonespace_812',['kCoolixOneSpace',['../ir__Coolix_8cpp.html#a97a8439ace71584e36ab7306c3d53749',1,'ir_Coolix.cpp']]], + ['kcoolixonespaceticks_813',['kCoolixOneSpaceTicks',['../ir__Coolix_8cpp.html#a78770eaf597e4aa2ed539248ef10ec11',1,'ir_Coolix.cpp']]], + ['kcoolixprefix_814',['kCoolixPrefix',['../ir__Coolix_8h.html#a1b88ef6651189ba330d8e2847528964b',1,'ir_Coolix.h']]], + ['kcoolixsensortempignorecode_815',['kCoolixSensorTempIgnoreCode',['../ir__Coolix_8h.html#ae3aba531b0c0053424786ec4bb2be934',1,'ir_Coolix.h']]], + ['kcoolixsensortempmax_816',['kCoolixSensorTempMax',['../ir__Coolix_8h.html#a71641b1240ee439e77128165cedf899f',1,'ir_Coolix.h']]], + ['kcoolixsensortempmin_817',['kCoolixSensorTempMin',['../ir__Coolix_8h.html#a48f3f3ad79a53e0758270647db0b089c',1,'ir_Coolix.h']]], + ['kcoolixsensortempoffset_818',['kCoolixSensorTempOffset',['../ir__Coolix_8h.html#a03edec58ad078d7de7436929c463898a',1,'ir_Coolix.h']]], + ['kcoolixsensortempsize_819',['kCoolixSensorTempSize',['../ir__Coolix_8h.html#a979d1d4f84432afc29ac3fcc78353d6c',1,'ir_Coolix.h']]], + ['kcoolixsleep_820',['kCoolixSleep',['../ir__Coolix_8h.html#aa7f9f96e56bd3f6b814bc84b947b2417',1,'ir_Coolix.h']]], + ['kcoolixswing_821',['kCoolixSwing',['../ir__Coolix_8h.html#a799ad5ab7cf43f0aac3c342305f14b90',1,'ir_Coolix.h']]], + ['kcoolixswingh_822',['kCoolixSwingH',['../ir__Coolix_8h.html#a877bd2731dfc86d864e38a5ceb4ede6e',1,'ir_Coolix.h']]], + ['kcoolixswingv_823',['kCoolixSwingV',['../ir__Coolix_8h.html#ab9fcaf25426f1f9ad293e165f8c0bf38',1,'ir_Coolix.h']]], + ['kcoolixtempmap_824',['kCoolixTempMap',['../ir__Coolix_8h.html#a9c8931df1dbed38c8119f6605266c710',1,'ir_Coolix.h']]], + ['kcoolixtempmax_825',['kCoolixTempMax',['../ir__Coolix_8h.html#afbbb02bfeaaf5cb558ca28cdd5cfc4c3',1,'ir_Coolix.h']]], + ['kcoolixtempmin_826',['kCoolixTempMin',['../ir__Coolix_8h.html#accd37cf257fa5fbeb64e28f0d63888fb',1,'ir_Coolix.h']]], + ['kcoolixtempoffset_827',['kCoolixTempOffset',['../ir__Coolix_8h.html#ac49173b671af51026e378d65c7bc696b',1,'ir_Coolix.h']]], + ['kcoolixtemprange_828',['kCoolixTempRange',['../ir__Coolix_8h.html#a74e3e75466fd27672968d660e3fddc9a',1,'ir_Coolix.h']]], + ['kcoolixtempsize_829',['kCoolixTempSize',['../ir__Coolix_8h.html#a7a22c5c9bdd23ef80ffe9d6760c0650e',1,'ir_Coolix.h']]], + ['kcoolixtick_830',['kCoolixTick',['../ir__Coolix_8cpp.html#a61ddf842920e2b3e33fdb856bd911eae',1,'ir_Coolix.cpp']]], + ['kcoolixturbo_831',['kCoolixTurbo',['../ir__Coolix_8h.html#ade957b6f4a6cdb064c709972a5c31a4b',1,'ir_Coolix.h']]], + ['kcoolixunknown_832',['kCoolixUnknown',['../ir__Coolix_8h.html#a2913e31a9dc5b89cbcae940cd5d59497',1,'ir_Coolix.h']]], + ['kcoolixzerospace_833',['kCoolixZeroSpace',['../ir__Coolix_8cpp.html#a1a9ccf6b91e786f310ffe53d55cfd6d1',1,'ir_Coolix.cpp']]], + ['kcoolixzerospaceticks_834',['kCoolixZeroSpaceTicks',['../ir__Coolix_8cpp.html#af1a750cb3e1f142326cd177118c27136',1,'ir_Coolix.cpp']]], + ['kcoolixzonefollowmaskoffset_835',['kCoolixZoneFollowMaskOffset',['../ir__Coolix_8h.html#ae5da4da07b9d1bb715102cafd4a0105e',1,'ir_Coolix.h']]], + ['kcoolstr_836',['kCoolStr',['../IRtext_8cpp.html#a31258a2210b16dc977bcfd96938a8937',1,'kCoolStr(): IRtext.cpp'],['../IRtext_8h.html#ac25d86b97b8e53292dc8d0604ae263a3',1,'kCoolStr(): IRtext.cpp']]], + ['kcoronaacbitmark_837',['kCoronaAcBitMark',['../ir__Corona_8cpp.html#a1ecb863f625463289d34e210885238db',1,'ir_Corona.cpp']]], + ['kcoronaacbits_838',['kCoronaAcBits',['../IRremoteESP8266_8h.html#aaf59be616d7e3a5e605b8d1e08f20686',1,'IRremoteESP8266.h']]], + ['kcoronaacbitsshort_839',['kCoronaAcBitsShort',['../IRremoteESP8266_8h.html#a1191a9293b03aa14426083b6f411a4e3',1,'IRremoteESP8266.h']]], + ['kcoronaacfanauto_840',['kCoronaAcFanAuto',['../ir__Corona_8h.html#a8c97a0c674c000e4486159d628f1aa0a',1,'ir_Corona.h']]], + ['kcoronaacfanhigh_841',['kCoronaAcFanHigh',['../ir__Corona_8h.html#a4f58be196a744892402e287b12502dcb',1,'ir_Corona.h']]], + ['kcoronaacfanlow_842',['kCoronaAcFanLow',['../ir__Corona_8h.html#af9e5c729be856bf4b1bc10568f96c183',1,'ir_Corona.h']]], + ['kcoronaacfanmedium_843',['kCoronaAcFanMedium',['../ir__Corona_8h.html#a9d6b46c006bd6ea54a14b92a2d7a3dff',1,'ir_Corona.h']]], + ['kcoronaacfanoffset_844',['kCoronaAcFanOffset',['../ir__Corona_8h.html#ab9944dc3abdc09c4d616f43aaffccdec',1,'ir_Corona.h']]], + ['kcoronaacfansize_845',['kCoronaAcFanSize',['../ir__Corona_8h.html#a07463e8e2e7d2bf004142ec6b89c7851',1,'ir_Corona.h']]], + ['kcoronaacfreq_846',['kCoronaAcFreq',['../ir__Corona_8cpp.html#a0cb56860c88e9503743bcf94068bbf56',1,'ir_Corona.cpp']]], + ['kcoronaachdrmark_847',['kCoronaAcHdrMark',['../ir__Corona_8cpp.html#a697d84f13a1228dbae3cfb491124689a',1,'ir_Corona.cpp']]], + ['kcoronaachdrspace_848',['kCoronaAcHdrSpace',['../ir__Corona_8cpp.html#ad2425c406aa36c7752832d19f4a735f7',1,'ir_Corona.cpp']]], + ['kcoronaacmaxtemp_849',['kCoronaAcMaxTemp',['../ir__Corona_8h.html#aa6d199e5bb8382443da4e1f303dd7988',1,'ir_Corona.h']]], + ['kcoronaacmintemp_850',['kCoronaAcMinTemp',['../ir__Corona_8h.html#ae984b624da5e2d5ef1405e1b8d9424ba',1,'ir_Corona.h']]], + ['kcoronaacmodecool_851',['kCoronaAcModeCool',['../ir__Corona_8h.html#a6f8bb2e27990014686828b4b7e2c84c6',1,'ir_Corona.h']]], + ['kcoronaacmodedry_852',['kCoronaAcModeDry',['../ir__Corona_8h.html#afd47996b221103ae142363f04014fb4b',1,'ir_Corona.h']]], + ['kcoronaacmodefan_853',['kCoronaAcModeFan',['../ir__Corona_8h.html#ab8098af3e0f9cd82a7c9c771ffd8ad15',1,'ir_Corona.h']]], + ['kcoronaacmodeheat_854',['kCoronaAcModeHeat',['../ir__Corona_8h.html#a7f3c7c051ae3ee07621c47505a87bec1',1,'ir_Corona.h']]], + ['kcoronaacmodeoffset_855',['kCoronaAcModeOffset',['../ir__Corona_8h.html#aa4caa3638ad09dc3a223320651adbd49',1,'ir_Corona.h']]], + ['kcoronaacmodesize_856',['kCoronaAcModeSize',['../ir__Corona_8h.html#a38baa949868e16e67d7c2eb933b5019d',1,'ir_Corona.h']]], + ['kcoronaacofftimersection_857',['kCoronaAcOffTimerSection',['../ir__Corona_8h.html#ac2cfdbf9b3ed3d85c0e298c3de8f357b',1,'ir_Corona.h']]], + ['kcoronaaconespace_858',['kCoronaAcOneSpace',['../ir__Corona_8cpp.html#a6d9c199bdefbbb30b9561c5498c5a76e',1,'ir_Corona.cpp']]], + ['kcoronaacontimersection_859',['kCoronaAcOnTimerSection',['../ir__Corona_8h.html#a711b7b5bd2081ca9b1e7ab25573ff612',1,'ir_Corona.h']]], + ['kcoronaacoverhead_860',['kCoronaAcOverhead',['../ir__Corona_8cpp.html#aaef71b297a7868863a2ad7219bafabeb',1,'ir_Corona.cpp']]], + ['kcoronaacoverheadshort_861',['kCoronaAcOverheadShort',['../ir__Corona_8cpp.html#a56010f67a047f551db681bb0ec8c35f7',1,'ir_Corona.cpp']]], + ['kcoronaacpowerbuttonoffset_862',['kCoronaAcPowerButtonOffset',['../ir__Corona_8h.html#a71b6c16b1b5cffbd1991fea675e5a65e',1,'ir_Corona.h']]], + ['kcoronaacpoweroffset_863',['kCoronaAcPowerOffset',['../ir__Corona_8h.html#ac2258a233d0f1ef3207fdd5abd8c855d',1,'ir_Corona.h']]], + ['kcoronaacpowersaveoffset_864',['kCoronaAcPowerSaveOffset',['../ir__Corona_8h.html#a3bd4f3e2a1001aede28c886e7bbe42ae',1,'ir_Corona.h']]], + ['kcoronaacsectionbytes_865',['kCoronaAcSectionBytes',['../ir__Corona_8h.html#a094063159064053dd5e5059eb0d90f7c',1,'ir_Corona.h']]], + ['kcoronaacsectiondata0base_866',['kCoronaAcSectionData0Base',['../ir__Corona_8h.html#a2d0b1f5a0839839a17947bde624d4c74',1,'ir_Corona.h']]], + ['kcoronaacsectiondata0invpos_867',['kCoronaAcSectionData0InvPos',['../ir__Corona_8h.html#a1a16967cb9024658763c7e6b6b5f8dd3',1,'ir_Corona.h']]], + ['kcoronaacsectiondata0pos_868',['kCoronaAcSectionData0Pos',['../ir__Corona_8h.html#a285f66040fa3db6c9955a97ef6eee4b7',1,'ir_Corona.h']]], + ['kcoronaacsectiondata1invpos_869',['kCoronaAcSectionData1InvPos',['../ir__Corona_8h.html#ad32635d2264331f4ee128e990411a704',1,'ir_Corona.h']]], + ['kcoronaacsectiondata1pos_870',['kCoronaAcSectionData1Pos',['../ir__Corona_8h.html#a1b10ed7cf1c43a3a8be6de6d3cfc12af',1,'ir_Corona.h']]], + ['kcoronaacsectionheader0_871',['kCoronaAcSectionHeader0',['../ir__Corona_8h.html#a39a2c0d214a10f8f9685e9955c0be0a4',1,'ir_Corona.h']]], + ['kcoronaacsectionheader0pos_872',['kCoronaAcSectionHeader0Pos',['../ir__Corona_8h.html#a8641d0234280b8cc3bb255abebea6540',1,'ir_Corona.h']]], + ['kcoronaacsectionheader1_873',['kCoronaAcSectionHeader1',['../ir__Corona_8h.html#a8a661569fc7b97ba2e9e755b944162f8',1,'ir_Corona.h']]], + ['kcoronaacsectionheader1pos_874',['kCoronaAcSectionHeader1Pos',['../ir__Corona_8h.html#adaadcbe7d57b048250f32b44a96d3853',1,'ir_Corona.h']]], + ['kcoronaacsectionlabelbase_875',['kCoronaAcSectionLabelBase',['../ir__Corona_8h.html#a6ff8a3461b87df048878faf49c12d064',1,'ir_Corona.h']]], + ['kcoronaacsectionlabelpos_876',['kCoronaAcSectionLabelPos',['../ir__Corona_8h.html#a5c68109fb92da47236c4100c2db28e2c',1,'ir_Corona.h']]], + ['kcoronaacsections_877',['kCoronaAcSections',['../ir__Corona_8h.html#a37e6cc5e2e186b2f5c5c938496ece111',1,'ir_Corona.h']]], + ['kcoronaacsettingssection_878',['kCoronaAcSettingsSection',['../ir__Corona_8h.html#a5a83a045fd9878eae073f25e6c5b4753',1,'ir_Corona.h']]], + ['kcoronaacspacegap_879',['kCoronaAcSpaceGap',['../ir__Corona_8cpp.html#a50f46039059d2a427bc9bc93c53df4fd',1,'ir_Corona.cpp']]], + ['kcoronaacstatelength_880',['kCoronaAcStateLength',['../IRremoteESP8266_8h.html#ab18df94a82b365ff30caaabb05a9fcaf',1,'IRremoteESP8266.h']]], + ['kcoronaacstatelengthshort_881',['kCoronaAcStateLengthShort',['../IRremoteESP8266_8h.html#a32b65ada4941a9622fbbc60f01b82425',1,'IRremoteESP8266.h']]], + ['kcoronaacswingvtoggleoffset_882',['kCoronaAcSwingVToggleOffset',['../ir__Corona_8h.html#a1475a44b94a8cfe83fb48b3c3d98e148',1,'ir_Corona.h']]], + ['kcoronaactempoffset_883',['kCoronaAcTempOffset',['../ir__Corona_8h.html#ae31731c985397a9a8b66ab933deccd7c',1,'ir_Corona.h']]], + ['kcoronaactempsize_884',['kCoronaAcTempSize',['../ir__Corona_8h.html#a69dac2ce8e51b8e1890c8b7844eab9dd',1,'ir_Corona.h']]], + ['kcoronaactimermax_885',['kCoronaAcTimerMax',['../ir__Corona_8h.html#af0428879b0fd39def7ea41e2906d9127',1,'ir_Corona.h']]], + ['kcoronaactimeroff_886',['kCoronaAcTimerOff',['../ir__Corona_8h.html#af0feaf445fae561c3fa18ec68a19edef',1,'ir_Corona.h']]], + ['kcoronaactimerunitspermin_887',['kCoronaAcTimerUnitsPerMin',['../ir__Corona_8h.html#a7f76e80480abdbdcdaf39186901950a4',1,'ir_Corona.h']]], + ['kcoronaaczerospace_888',['kCoronaAcZeroSpace',['../ir__Corona_8cpp.html#af64bbcaf63ca9d06089de382354eb2d9',1,'ir_Corona.cpp']]], + ['kcoronatolerance_889',['kCoronaTolerance',['../ir__Corona_8cpp.html#aad3726c95bfd7a9f79ba1e0c7058bb7b',1,'ir_Corona.cpp']]], + ['kdaikin128auto_890',['kDaikin128Auto',['../ir__Daikin_8h.html#a1d2a0f9db8e1be93bff12ec23ba212e0',1,'ir_Daikin.h']]], + ['kdaikin128bitceiling_891',['kDaikin128BitCeiling',['../ir__Daikin_8h.html#a0e1d1c1e7544eb455187290dbe4a1520',1,'ir_Daikin.h']]], + ['kdaikin128bitecono_892',['kDaikin128BitEcono',['../ir__Daikin_8h.html#a34add42c4df4db799ddf52e8e5587dee',1,'ir_Daikin.h']]], + ['kdaikin128biteconooffset_893',['kDaikin128BitEconoOffset',['../ir__Daikin_8h.html#af822203d873d9b847c3a7b08d236f82b',1,'ir_Daikin.h']]], + ['kdaikin128bithalfhour_894',['kDaikin128BitHalfHour',['../ir__Daikin_8h.html#abf955f8f24fd37bbe21222ca160b3299',1,'ir_Daikin.h']]], + ['kdaikin128bitmark_895',['kDaikin128BitMark',['../ir__Daikin_8h.html#a5178ac70eb4e134597e504d373d52fcd',1,'ir_Daikin.h']]], + ['kdaikin128bitpowertoggle_896',['kDaikin128BitPowerToggle',['../ir__Daikin_8h.html#a813506d8d3f8b6933379bcfc097e4b29',1,'ir_Daikin.h']]], + ['kdaikin128bitpowertoggleoffset_897',['kDaikin128BitPowerToggleOffset',['../ir__Daikin_8h.html#a05e33573c5050b1e54721a1716d652b5',1,'ir_Daikin.h']]], + ['kdaikin128bits_898',['kDaikin128Bits',['../IRremoteESP8266_8h.html#a5bb2e6f8acbc0123de5ac0fd76e1646a',1,'IRremoteESP8266.h']]], + ['kdaikin128bitsleep_899',['kDaikin128BitSleep',['../ir__Daikin_8h.html#a0cb96f1803fab5bfac8ef79a311308de',1,'ir_Daikin.h']]], + ['kdaikin128bitsleepoffset_900',['kDaikin128BitSleepOffset',['../ir__Daikin_8h.html#a7b4aa1ef19f1c23ef74b45eb90734c6f',1,'ir_Daikin.h']]], + ['kdaikin128bitswing_901',['kDaikin128BitSwing',['../ir__Daikin_8h.html#a8f6ab5b7f9871f08364abf3337ae48b4',1,'ir_Daikin.h']]], + ['kdaikin128bitswingoffset_902',['kDaikin128BitSwingOffset',['../ir__Daikin_8h.html#a7f98cf3863ab58b147dc31c497bc07bc',1,'ir_Daikin.h']]], + ['kdaikin128bittimerenabled_903',['kDaikin128BitTimerEnabled',['../ir__Daikin_8h.html#a1197dadb35f318b000ff6ee7ad3ca8b0',1,'ir_Daikin.h']]], + ['kdaikin128bittimerenabledoffset_904',['kDaikin128BitTimerEnabledOffset',['../ir__Daikin_8h.html#af913ee51e5b90ad12f87dbed9ce349d6',1,'ir_Daikin.h']]], + ['kdaikin128bitwall_905',['kDaikin128BitWall',['../ir__Daikin_8h.html#a842b3b696f95c5515ee4180626d78973',1,'ir_Daikin.h']]], + ['kdaikin128byteclockhours_906',['kDaikin128ByteClockHours',['../ir__Daikin_8h.html#a0d705309d30881fd2fe806e5bf8ae27d',1,'ir_Daikin.h']]], + ['kdaikin128byteclockmins_907',['kDaikin128ByteClockMins',['../ir__Daikin_8h.html#ab8c9af42d68548e1e711a0b38976342b',1,'ir_Daikin.h']]], + ['kdaikin128byteeconolight_908',['kDaikin128ByteEconoLight',['../ir__Daikin_8h.html#a75a3c1f1790006f0005666a023218c79',1,'ir_Daikin.h']]], + ['kdaikin128bytemodefan_909',['kDaikin128ByteModeFan',['../ir__Daikin_8h.html#a8433ab362f79a6bb3570d310a05f1141',1,'ir_Daikin.h']]], + ['kdaikin128byteofftimer_910',['kDaikin128ByteOffTimer',['../ir__Daikin_8h.html#a66e243db1131f58d0840980ca64c0282',1,'ir_Daikin.h']]], + ['kdaikin128byteontimer_911',['kDaikin128ByteOnTimer',['../ir__Daikin_8h.html#af27f1f25a52dc4c182111acd2abc554d',1,'ir_Daikin.h']]], + ['kdaikin128bytepowerswingsleep_912',['kDaikin128BytePowerSwingSleep',['../ir__Daikin_8h.html#a0f5a9f1ac68c516744220ad230805c15',1,'ir_Daikin.h']]], + ['kdaikin128bytetemp_913',['kDaikin128ByteTemp',['../ir__Daikin_8h.html#a4d3d5683aaee8e76138750a0f6ff1465',1,'ir_Daikin.h']]], + ['kdaikin128cool_914',['kDaikin128Cool',['../ir__Daikin_8h.html#a24ee5ffe877d7caa964256e5723af7e1',1,'ir_Daikin.h']]], + ['kdaikin128defaultrepeat_915',['kDaikin128DefaultRepeat',['../IRremoteESP8266_8h.html#a5c116cb58be005468de125f6ee651ccb',1,'IRremoteESP8266.h']]], + ['kdaikin128dry_916',['kDaikin128Dry',['../ir__Daikin_8h.html#ac4da761bf3b0ce12e6513a2718b3a907',1,'ir_Daikin.h']]], + ['kdaikin128fan_917',['kDaikin128Fan',['../ir__Daikin_8h.html#ac1c41d54f27d1653181ac69384f1130f',1,'ir_Daikin.h']]], + ['kdaikin128fanauto_918',['kDaikin128FanAuto',['../ir__Daikin_8h.html#aec2fe4618978c17e60a1ea8b1a89c263',1,'ir_Daikin.h']]], + ['kdaikin128fanhigh_919',['kDaikin128FanHigh',['../ir__Daikin_8h.html#a7ffd52eb15f6ffb5a0ffcddf39aa8f0d',1,'ir_Daikin.h']]], + ['kdaikin128fanlow_920',['kDaikin128FanLow',['../ir__Daikin_8h.html#a505c58ff23c5a551c6e2e356f66e9cc1',1,'ir_Daikin.h']]], + ['kdaikin128fanmed_921',['kDaikin128FanMed',['../ir__Daikin_8h.html#a4eb21add9bfb6774047a8a2c8b87ebbf',1,'ir_Daikin.h']]], + ['kdaikin128fanpowerful_922',['kDaikin128FanPowerful',['../ir__Daikin_8h.html#ae0899153669a6e8848556cd65c26c8b5',1,'ir_Daikin.h']]], + ['kdaikin128fanquiet_923',['kDaikin128FanQuiet',['../ir__Daikin_8h.html#a54777f468236bf4b342240e8c523308d',1,'ir_Daikin.h']]], + ['kdaikin128footermark_924',['kDaikin128FooterMark',['../ir__Daikin_8h.html#ad5668b12e38afa4b44a8e214dac22f2e',1,'ir_Daikin.h']]], + ['kdaikin128freq_925',['kDaikin128Freq',['../ir__Daikin_8h.html#a5a76fc08310d517cb7e182c287e77df1',1,'ir_Daikin.h']]], + ['kdaikin128gap_926',['kDaikin128Gap',['../ir__Daikin_8h.html#a6323c59eb5906ac2887a02f9cd09a329',1,'ir_Daikin.h']]], + ['kdaikin128halfhouroffset_927',['kDaikin128HalfHourOffset',['../ir__Daikin_8h.html#a8fddd8a5dbad2fd49445eaa2104f7da3',1,'ir_Daikin.h']]], + ['kdaikin128hdrmark_928',['kDaikin128HdrMark',['../ir__Daikin_8h.html#a6257375541b6e10bda4083d9529e80f0',1,'ir_Daikin.h']]], + ['kdaikin128hdrspace_929',['kDaikin128HdrSpace',['../ir__Daikin_8h.html#a114a4cef444d4c552b90701cb7debc73',1,'ir_Daikin.h']]], + ['kdaikin128heat_930',['kDaikin128Heat',['../ir__Daikin_8h.html#ada28db809b26e2ae9e927650d4cb4f7a',1,'ir_Daikin.h']]], + ['kdaikin128hoursoffset_931',['kDaikin128HoursOffset',['../ir__Daikin_8h.html#ace543fba33c68e3df4aa4d250ed1e792',1,'ir_Daikin.h']]], + ['kdaikin128hourssize_932',['kDaikin128HoursSize',['../ir__Daikin_8h.html#ac5441402c0ee486f3c752a91f09375ff',1,'ir_Daikin.h']]], + ['kdaikin128leadermark_933',['kDaikin128LeaderMark',['../ir__Daikin_8h.html#ab609b8979a2d2bf4fa5b7164590b2bfb',1,'ir_Daikin.h']]], + ['kdaikin128leaderspace_934',['kDaikin128LeaderSpace',['../ir__Daikin_8h.html#a259bfa510a9ec06049c0a7bf6563eb35',1,'ir_Daikin.h']]], + ['kdaikin128maskfan_935',['kDaikin128MaskFan',['../ir__Daikin_8h.html#ae58228f3b9eae0ec171527ced89e509f',1,'ir_Daikin.h']]], + ['kdaikin128masklight_936',['kDaikin128MaskLight',['../ir__Daikin_8h.html#a8d3d4325f91cbdd8ce0cec25fc0d2022',1,'ir_Daikin.h']]], + ['kdaikin128maxtemp_937',['kDaikin128MaxTemp',['../ir__Daikin_8h.html#a7dcd514d292ef98d70083227d046baad',1,'ir_Daikin.h']]], + ['kdaikin128mintemp_938',['kDaikin128MinTemp',['../ir__Daikin_8h.html#aad27f3ff311f1defc5ac9fb3be0ad504',1,'ir_Daikin.h']]], + ['kdaikin128modesize_939',['kDaikin128ModeSize',['../ir__Daikin_8h.html#a32a97adddfa791cc0e48d9bd847a3a4c',1,'ir_Daikin.h']]], + ['kdaikin128onespace_940',['kDaikin128OneSpace',['../ir__Daikin_8h.html#ac6a9a48ae0037b889a6619361fd090ac',1,'ir_Daikin.h']]], + ['kdaikin128sectionlength_941',['kDaikin128SectionLength',['../ir__Daikin_8h.html#a204a306e7d7071d4b798f7947c232520',1,'ir_Daikin.h']]], + ['kdaikin128sections_942',['kDaikin128Sections',['../ir__Daikin_8h.html#a81f0cfda4d8452d6053cc6999a270b1f',1,'ir_Daikin.h']]], + ['kdaikin128statelength_943',['kDaikin128StateLength',['../IRremoteESP8266_8h.html#a4279ccd14a3af2046e393661a7b4879f',1,'IRremoteESP8266.h']]], + ['kdaikin128timeroffset_944',['kDaikin128TimerOffset',['../ir__Daikin_8h.html#aabde7c45424ae82a812485e8ceb58dbd',1,'ir_Daikin.h']]], + ['kdaikin128timersize_945',['kDaikin128TimerSize',['../ir__Daikin_8h.html#a6f4022c5e4a092eb039c53ea72f51188',1,'ir_Daikin.h']]], + ['kdaikin128zerospace_946',['kDaikin128ZeroSpace',['../ir__Daikin_8h.html#a1ca69805ada8ec451199c18d9da6f02a',1,'ir_Daikin.h']]], + ['kdaikin152bitmark_947',['kDaikin152BitMark',['../ir__Daikin_8h.html#afd50318eaa383a7e85f0d0c2866bc9d5',1,'ir_Daikin.h']]], + ['kdaikin152bits_948',['kDaikin152Bits',['../IRremoteESP8266_8h.html#af056e1ac2d00c6d6440c3dd2ae283f09',1,'IRremoteESP8266.h']]], + ['kdaikin152comfortbyte_949',['kDaikin152ComfortByte',['../ir__Daikin_8h.html#a414b7acd5259122af5b496979fe068dc',1,'ir_Daikin.h']]], + ['kdaikin152comfortoffset_950',['kDaikin152ComfortOffset',['../ir__Daikin_8h.html#a9cc7bb09fb66aa0cf7d0b751505fd3e6',1,'ir_Daikin.h']]], + ['kdaikin152defaultrepeat_951',['kDaikin152DefaultRepeat',['../IRremoteESP8266_8h.html#a9407eebab271524e74bc3ddddb1a2e0b',1,'IRremoteESP8266.h']]], + ['kdaikin152drytemp_952',['kDaikin152DryTemp',['../ir__Daikin_8h.html#a86e9308c00dbdd79546687af412c4156',1,'ir_Daikin.h']]], + ['kdaikin152econobyte_953',['kDaikin152EconoByte',['../ir__Daikin_8h.html#a988782fd6bcf25b098d7c07e38679a78',1,'ir_Daikin.h']]], + ['kdaikin152fanbyte_954',['kDaikin152FanByte',['../ir__Daikin_8h.html#a1972e59df2902335e37b2d66d16048a8',1,'ir_Daikin.h']]], + ['kdaikin152fantemp_955',['kDaikin152FanTemp',['../ir__Daikin_8h.html#ad5c5bb7e8b181c79fe68607c1a4d202f',1,'ir_Daikin.h']]], + ['kdaikin152freq_956',['kDaikin152Freq',['../ir__Daikin_8h.html#aa45492ae186142971975b7da56658a0b',1,'ir_Daikin.h']]], + ['kdaikin152gap_957',['kDaikin152Gap',['../ir__Daikin_8h.html#aee02d3b17db4a382035c00329c6c2a0a',1,'ir_Daikin.h']]], + ['kdaikin152hdrmark_958',['kDaikin152HdrMark',['../ir__Daikin_8h.html#a85fad797a9b43cb317fdb2e2c254a3bb',1,'ir_Daikin.h']]], + ['kdaikin152hdrspace_959',['kDaikin152HdrSpace',['../ir__Daikin_8h.html#a0eb0b1b5fabab75a5956b6b939696a12',1,'ir_Daikin.h']]], + ['kdaikin152leaderbits_960',['kDaikin152LeaderBits',['../ir__Daikin_8h.html#a432454efd5ea7457d34fe014b0d328c1',1,'ir_Daikin.h']]], + ['kdaikin152modebyte_961',['kDaikin152ModeByte',['../ir__Daikin_8h.html#a1aaa767f722926e9aaf02dbcd8029003',1,'ir_Daikin.h']]], + ['kdaikin152onespace_962',['kDaikin152OneSpace',['../ir__Daikin_8h.html#a1f96172c74b261a26ec6d71201f7c589',1,'ir_Daikin.h']]], + ['kdaikin152powerbyte_963',['kDaikin152PowerByte',['../ir__Daikin_8h.html#a67ff6fbdc004d3a29b1d31c5bc47f572',1,'ir_Daikin.h']]], + ['kdaikin152powerfulbyte_964',['kDaikin152PowerfulByte',['../ir__Daikin_8h.html#a720a3019f7bb2f8c458a7b79fbadd08f',1,'ir_Daikin.h']]], + ['kdaikin152quietbyte_965',['kDaikin152QuietByte',['../ir__Daikin_8h.html#ad534758115c401368a428d887faa8768',1,'ir_Daikin.h']]], + ['kdaikin152sensorbyte_966',['kDaikin152SensorByte',['../ir__Daikin_8h.html#a33187d50e8414f943d050a0b1c312168',1,'ir_Daikin.h']]], + ['kdaikin152sensoroffset_967',['kDaikin152SensorOffset',['../ir__Daikin_8h.html#a01ef92b6eb478b1897fdfdcea03d7116',1,'ir_Daikin.h']]], + ['kdaikin152statelength_968',['kDaikin152StateLength',['../IRremoteESP8266_8h.html#ae7579708922ffd3e44295f8770878983',1,'IRremoteESP8266.h']]], + ['kdaikin152swingvbyte_969',['kDaikin152SwingVByte',['../ir__Daikin_8h.html#a9ed39bcce7d0bc73060fba843dfd2b28',1,'ir_Daikin.h']]], + ['kdaikin152tempbyte_970',['kDaikin152TempByte',['../ir__Daikin_8h.html#a5e232b17db30a7e0ba159e2413df8b14',1,'ir_Daikin.h']]], + ['kdaikin152tempsize_971',['kDaikin152TempSize',['../ir__Daikin_8h.html#ad22ee842100e70d95f1ebcdcaf3f2099',1,'ir_Daikin.h']]], + ['kdaikin152zerospace_972',['kDaikin152ZeroSpace',['../ir__Daikin_8h.html#aec201aee71c0e301e8e191ddcaadb2de',1,'ir_Daikin.h']]], + ['kdaikin160bitmark_973',['kDaikin160BitMark',['../ir__Daikin_8h.html#a852c2268ed7a8dd42c629e8a0706b6f5',1,'ir_Daikin.h']]], + ['kdaikin160bits_974',['kDaikin160Bits',['../IRremoteESP8266_8h.html#aa6f1d6dded2ae3500cd52aa0c482a1b6',1,'IRremoteESP8266.h']]], + ['kdaikin160bytefan_975',['kDaikin160ByteFan',['../ir__Daikin_8h.html#a980ae6010c956c92348d3ac88c084247',1,'ir_Daikin.h']]], + ['kdaikin160bytemode_976',['kDaikin160ByteMode',['../ir__Daikin_8h.html#a6c5bcb2c4447dafc53c26775539886e6',1,'ir_Daikin.h']]], + ['kdaikin160bytepower_977',['kDaikin160BytePower',['../ir__Daikin_8h.html#a8e79923cf8aa346ea52791887b54ffbe',1,'ir_Daikin.h']]], + ['kdaikin160byteswingv_978',['kDaikin160ByteSwingV',['../ir__Daikin_8h.html#a35032831d79e96a98527896cd5d52efe',1,'ir_Daikin.h']]], + ['kdaikin160bytetemp_979',['kDaikin160ByteTemp',['../ir__Daikin_8h.html#a1b9eed515f9cfc3508cce7d53fb7a84a',1,'ir_Daikin.h']]], + ['kdaikin160defaultrepeat_980',['kDaikin160DefaultRepeat',['../IRremoteESP8266_8h.html#a82f4f1d8fae51c7e2f1f6753ca6e6053',1,'IRremoteESP8266.h']]], + ['kdaikin160freq_981',['kDaikin160Freq',['../ir__Daikin_8h.html#a69e8abb57aecc6b99c60c5df7e18ff39',1,'ir_Daikin.h']]], + ['kdaikin160gap_982',['kDaikin160Gap',['../ir__Daikin_8h.html#a8d107f0d63ef6951d657a55a370e8a8b',1,'ir_Daikin.h']]], + ['kdaikin160hdrmark_983',['kDaikin160HdrMark',['../ir__Daikin_8h.html#a96043b43ba4d963456206e2d02639325',1,'ir_Daikin.h']]], + ['kdaikin160hdrspace_984',['kDaikin160HdrSpace',['../ir__Daikin_8h.html#aefa7b5de43483951e00bd5d2cdbe5665',1,'ir_Daikin.h']]], + ['kdaikin160maskfan_985',['kDaikin160MaskFan',['../ir__Daikin_8h.html#a623f586183436960361a85f8480c87c6',1,'ir_Daikin.h']]], + ['kdaikin160maskswingv_986',['kDaikin160MaskSwingV',['../ir__Daikin_8h.html#abfaa078f7dfdd1c0bb14ad15fee26604',1,'ir_Daikin.h']]], + ['kdaikin160onespace_987',['kDaikin160OneSpace',['../ir__Daikin_8h.html#a068c2252191675dca6503bfc37e4785e',1,'ir_Daikin.h']]], + ['kdaikin160section1length_988',['kDaikin160Section1Length',['../ir__Daikin_8h.html#a06b59ee56cddcdcd9dfa375663da0c2d',1,'ir_Daikin.h']]], + ['kdaikin160section2length_989',['kDaikin160Section2Length',['../ir__Daikin_8h.html#a7d6194a363661e11167cc972f1b92f68',1,'ir_Daikin.h']]], + ['kdaikin160sections_990',['kDaikin160Sections',['../ir__Daikin_8h.html#afcc5de2994c1cd618437f1c67a5754d0',1,'ir_Daikin.h']]], + ['kdaikin160statelength_991',['kDaikin160StateLength',['../IRremoteESP8266_8h.html#a09f022a12a40a8fae09bfbddfbee6d62',1,'IRremoteESP8266.h']]], + ['kdaikin160swingvauto_992',['kDaikin160SwingVAuto',['../ir__Daikin_8h.html#aa6d9ee84d2c15c69ed8dbbc832285baf',1,'ir_Daikin.h']]], + ['kdaikin160swingvhigh_993',['kDaikin160SwingVHigh',['../ir__Daikin_8h.html#abf542bd70d12534af72fb4ec8df5d265',1,'ir_Daikin.h']]], + ['kdaikin160swingvhighest_994',['kDaikin160SwingVHighest',['../ir__Daikin_8h.html#a2a48ca041acbde68b902a4d0be4aeec5',1,'ir_Daikin.h']]], + ['kdaikin160swingvlow_995',['kDaikin160SwingVLow',['../ir__Daikin_8h.html#a04ff7cb63db6b281ced56283288f05c0',1,'ir_Daikin.h']]], + ['kdaikin160swingvlowest_996',['kDaikin160SwingVLowest',['../ir__Daikin_8h.html#ac4f34c7862802b21dede2ac0b534c8d8',1,'ir_Daikin.h']]], + ['kdaikin160swingvmiddle_997',['kDaikin160SwingVMiddle',['../ir__Daikin_8h.html#a620b644f07f9b664f09417bb362dc216',1,'ir_Daikin.h']]], + ['kdaikin160tempoffset_998',['kDaikin160TempOffset',['../ir__Daikin_8h.html#aa2f7050929bab65dbdb8af5b493dafe2',1,'ir_Daikin.h']]], + ['kdaikin160tempsize_999',['kDaikin160TempSize',['../ir__Daikin_8h.html#adfecac727480010fae8e419ac3f13e73',1,'ir_Daikin.h']]], + ['kdaikin160zerospace_1000',['kDaikin160ZeroSpace',['../ir__Daikin_8h.html#a2b4591126c0b26ab16b5611dbfa4d5f6',1,'ir_Daikin.h']]], + ['kdaikin176bitmark_1001',['kDaikin176BitMark',['../ir__Daikin_8h.html#a4be0185fb8f65c0286cbf55dfd63a40f',1,'ir_Daikin.h']]], + ['kdaikin176bits_1002',['kDaikin176Bits',['../IRremoteESP8266_8h.html#a78baf9c97c548618428d2fcfd7cc91d7',1,'IRremoteESP8266.h']]], + ['kdaikin176bytefan_1003',['kDaikin176ByteFan',['../ir__Daikin_8h.html#a21e4b1854d3f87757ba0f0c10074226c',1,'ir_Daikin.h']]], + ['kdaikin176bytemode_1004',['kDaikin176ByteMode',['../ir__Daikin_8h.html#ad114b4570f96bcbf5358fa1ece354572',1,'ir_Daikin.h']]], + ['kdaikin176bytemodebutton_1005',['kDaikin176ByteModeButton',['../ir__Daikin_8h.html#aacda7563a2aaa9a56c77ce550f24a237',1,'ir_Daikin.h']]], + ['kdaikin176bytepower_1006',['kDaikin176BytePower',['../ir__Daikin_8h.html#aabfb9642dce0ab4169b193955221b938',1,'ir_Daikin.h']]], + ['kdaikin176byteswingh_1007',['kDaikin176ByteSwingH',['../ir__Daikin_8h.html#a4566642e6aaa0d64c531fafe0309dccc',1,'ir_Daikin.h']]], + ['kdaikin176bytetemp_1008',['kDaikin176ByteTemp',['../ir__Daikin_8h.html#afab294c7e8c65e5bf58e85bee4901752',1,'ir_Daikin.h']]], + ['kdaikin176cool_1009',['kDaikin176Cool',['../ir__Daikin_8h.html#ab67e912a9abdda7dcbe52ce90b70a3b5',1,'ir_Daikin.h']]], + ['kdaikin176defaultrepeat_1010',['kDaikin176DefaultRepeat',['../IRremoteESP8266_8h.html#a0228803e8fff3c73227214d4bb3d8b05',1,'IRremoteESP8266.h']]], + ['kdaikin176dryfantemp_1011',['kDaikin176DryFanTemp',['../ir__Daikin_8h.html#a462ad30312f13443f51b510e5b391f42',1,'ir_Daikin.h']]], + ['kdaikin176fanmax_1012',['kDaikin176FanMax',['../ir__Daikin_8h.html#a97e77d2a09bc753c17104f9695a0c0b1',1,'ir_Daikin.h']]], + ['kdaikin176freq_1013',['kDaikin176Freq',['../ir__Daikin_8h.html#a7f0c76e579dad510f21c34ba57cbf8dc',1,'ir_Daikin.h']]], + ['kdaikin176gap_1014',['kDaikin176Gap',['../ir__Daikin_8h.html#a0309c9d689f64e2d57ab09a2bb27bc18',1,'ir_Daikin.h']]], + ['kdaikin176hdrmark_1015',['kDaikin176HdrMark',['../ir__Daikin_8h.html#a9ff1ca660571d09caa0de39ce1370720',1,'ir_Daikin.h']]], + ['kdaikin176hdrspace_1016',['kDaikin176HdrSpace',['../ir__Daikin_8h.html#a64c4874b5d92682911ca84e826e1ff0b',1,'ir_Daikin.h']]], + ['kdaikin176maskfan_1017',['kDaikin176MaskFan',['../ir__Daikin_8h.html#ae7410031c68ae8426caa61bc97909cdf',1,'ir_Daikin.h']]], + ['kdaikin176maskmode_1018',['kDaikin176MaskMode',['../ir__Daikin_8h.html#a65b76b7a85d70a4ed1af359b2babffa1',1,'ir_Daikin.h']]], + ['kdaikin176modebutton_1019',['kDaikin176ModeButton',['../ir__Daikin_8h.html#a5c8602d17e9f70eefd735741b9d714eb',1,'ir_Daikin.h']]], + ['kdaikin176onespace_1020',['kDaikin176OneSpace',['../ir__Daikin_8h.html#a86ed046d66daf884ac0f06722991f5ba',1,'ir_Daikin.h']]], + ['kdaikin176section1length_1021',['kDaikin176Section1Length',['../ir__Daikin_8h.html#a4c5ce7df75834c77c0908cc40dbe02ed',1,'ir_Daikin.h']]], + ['kdaikin176section2length_1022',['kDaikin176Section2Length',['../ir__Daikin_8h.html#a9e2bb25a1d64d2c042e7eef38f5347d0',1,'ir_Daikin.h']]], + ['kdaikin176sections_1023',['kDaikin176Sections',['../ir__Daikin_8h.html#a177d12ac0f4fe8b5c5aeaf8f72579607',1,'ir_Daikin.h']]], + ['kdaikin176statelength_1024',['kDaikin176StateLength',['../IRremoteESP8266_8h.html#aa71fc87dcb6f14b82997e1d2269429d2',1,'IRremoteESP8266.h']]], + ['kdaikin176swinghauto_1025',['kDaikin176SwingHAuto',['../ir__Daikin_8h.html#a326ffcf00330a1759e4f71f8f8603f23',1,'ir_Daikin.h']]], + ['kdaikin176swinghoff_1026',['kDaikin176SwingHOff',['../ir__Daikin_8h.html#a8672ccb9016808c84b1b06de6584188a',1,'ir_Daikin.h']]], + ['kdaikin176tempoffset_1027',['kDaikin176TempOffset',['../ir__Daikin_8h.html#aa5f6cc15ca424e4bf9cc4357d9db79c9',1,'ir_Daikin.h']]], + ['kdaikin176tempsize_1028',['kDaikin176TempSize',['../ir__Daikin_8h.html#a3ef1914f2caf650a90d8412f2c1e2b74',1,'ir_Daikin.h']]], + ['kdaikin176zerospace_1029',['kDaikin176ZeroSpace',['../ir__Daikin_8h.html#a4db8836caa6cae0bab6fbde94409c879',1,'ir_Daikin.h']]], + ['kdaikin216bitmark_1030',['kDaikin216BitMark',['../ir__Daikin_8h.html#ada7cf9c593d716617ff4436755eef4f9',1,'ir_Daikin.h']]], + ['kdaikin216bits_1031',['kDaikin216Bits',['../IRremoteESP8266_8h.html#a317bf475ee4c6ddd802995dc535377d9',1,'IRremoteESP8266.h']]], + ['kdaikin216bytefan_1032',['kDaikin216ByteFan',['../ir__Daikin_8h.html#a832e7a349293058ebc50c17b904fb8f7',1,'ir_Daikin.h']]], + ['kdaikin216bytemode_1033',['kDaikin216ByteMode',['../ir__Daikin_8h.html#a48974eb3ceb40f2f580bd266a60f0392',1,'ir_Daikin.h']]], + ['kdaikin216bytepower_1034',['kDaikin216BytePower',['../ir__Daikin_8h.html#a740c2db81aebd8cb9e18b3f8c6c5b8be',1,'ir_Daikin.h']]], + ['kdaikin216bytepowerful_1035',['kDaikin216BytePowerful',['../ir__Daikin_8h.html#a9a428d988d705beae3ff1f7c0f01cb8d',1,'ir_Daikin.h']]], + ['kdaikin216byteswingh_1036',['kDaikin216ByteSwingH',['../ir__Daikin_8h.html#a20239baacdf9fb981eb0fb84b0ef536a',1,'ir_Daikin.h']]], + ['kdaikin216byteswingv_1037',['kDaikin216ByteSwingV',['../ir__Daikin_8h.html#a9fd16b0fb0d67a7058816d4b4f1659fc',1,'ir_Daikin.h']]], + ['kdaikin216bytetemp_1038',['kDaikin216ByteTemp',['../ir__Daikin_8h.html#a5828687e12d2b7fe1d793235d91750bd',1,'ir_Daikin.h']]], + ['kdaikin216defaultrepeat_1039',['kDaikin216DefaultRepeat',['../IRremoteESP8266_8h.html#a9d14d424d5a93de62f3e6f453db112db',1,'IRremoteESP8266.h']]], + ['kdaikin216freq_1040',['kDaikin216Freq',['../ir__Daikin_8h.html#aa3a9753c90ecb6d7f5ee3e5a16c79217',1,'ir_Daikin.h']]], + ['kdaikin216gap_1041',['kDaikin216Gap',['../ir__Daikin_8h.html#ab807adaab8afbeb97afaa9ddb2ec2c63',1,'ir_Daikin.h']]], + ['kdaikin216hdrmark_1042',['kDaikin216HdrMark',['../ir__Daikin_8h.html#a24163655b3d374aa643506c2bf4a2406',1,'ir_Daikin.h']]], + ['kdaikin216hdrspace_1043',['kDaikin216HdrSpace',['../ir__Daikin_8h.html#a2e69973e9a4aee29668597d09fcd70a4',1,'ir_Daikin.h']]], + ['kdaikin216maskfan_1044',['kDaikin216MaskFan',['../ir__Daikin_8h.html#a88f67ea1fe03ef40b81c5226ff5c72d5',1,'ir_Daikin.h']]], + ['kdaikin216onespace_1045',['kDaikin216OneSpace',['../ir__Daikin_8h.html#a1edeb73093bdea23e6cfb39c31ca1fce',1,'ir_Daikin.h']]], + ['kdaikin216section1length_1046',['kDaikin216Section1Length',['../ir__Daikin_8h.html#a5aacc812feb33ef954adc49086036859',1,'ir_Daikin.h']]], + ['kdaikin216section2length_1047',['kDaikin216Section2Length',['../ir__Daikin_8h.html#aade497bb9aad663a9e1e9403188d2154',1,'ir_Daikin.h']]], + ['kdaikin216sections_1048',['kDaikin216Sections',['../ir__Daikin_8h.html#a0ecd54bb733b982e3e5adf0c13ac9f6b',1,'ir_Daikin.h']]], + ['kdaikin216statelength_1049',['kDaikin216StateLength',['../IRremoteESP8266_8h.html#a70a1a65c1947b440e4ff27477de5ddc7',1,'IRremoteESP8266.h']]], + ['kdaikin216swingoff_1050',['kDaikin216SwingOff',['../ir__Daikin_8h.html#a84d6bb74c705dfbcd558f0b411a2a88e',1,'ir_Daikin.h']]], + ['kdaikin216swingon_1051',['kDaikin216SwingOn',['../ir__Daikin_8h.html#a4b2d77aafd84ed004390b5d4c7ad0455',1,'ir_Daikin.h']]], + ['kdaikin216swingsize_1052',['kDaikin216SwingSize',['../ir__Daikin_8h.html#a90d9e740067051fe294f1b408f7e020b',1,'ir_Daikin.h']]], + ['kdaikin216tempoffset_1053',['kDaikin216TempOffset',['../ir__Daikin_8h.html#a8e497623bb05ff10287ca06ac6ec15f6',1,'ir_Daikin.h']]], + ['kdaikin216tempsize_1054',['kDaikin216TempSize',['../ir__Daikin_8h.html#a3ef59f8474b38d1b0311f1018dbd6225',1,'ir_Daikin.h']]], + ['kdaikin216zerospace_1055',['kDaikin216ZeroSpace',['../ir__Daikin_8h.html#a448250dbb5a3a9733f21a0e347d17999',1,'ir_Daikin.h']]], + ['kdaikin2beepoffset_1056',['kDaikin2BeepOffset',['../ir__Daikin_8h.html#ad7f6110b5e3bf8c3b72ca07b745bae7c',1,'ir_Daikin.h']]], + ['kdaikin2beepsize_1057',['kDaikin2BeepSize',['../ir__Daikin_8h.html#a3a42f10a3427bff7af3c745592fe58fe',1,'ir_Daikin.h']]], + ['kdaikin2bitclean_1058',['kDaikin2BitClean',['../ir__Daikin_8h.html#a6672ff35e765c9ecb14107e7732b0bb2',1,'ir_Daikin.h']]], + ['kdaikin2bitcleanoffset_1059',['kDaikin2BitCleanOffset',['../ir__Daikin_8h.html#a4fa7ed25fb3f2371c3b5c7cf4906a3f3',1,'ir_Daikin.h']]], + ['kdaikin2biteye_1060',['kDaikin2BitEye',['../ir__Daikin_8h.html#a8adb3f3e8508adf8adc530365fceb96b',1,'ir_Daikin.h']]], + ['kdaikin2biteyeauto_1061',['kDaikin2BitEyeAuto',['../ir__Daikin_8h.html#a6a24519db9870520a645e4ad31857e39',1,'ir_Daikin.h']]], + ['kdaikin2biteyeautooffset_1062',['kDaikin2BitEyeAutoOffset',['../ir__Daikin_8h.html#a73db209ad074eeaef1a5317cbee8ab35',1,'ir_Daikin.h']]], + ['kdaikin2biteyeoffset_1063',['kDaikin2BitEyeOffset',['../ir__Daikin_8h.html#a7a4c6e131d9a0e441de549bd5f93074f',1,'ir_Daikin.h']]], + ['kdaikin2bitfreshair_1064',['kDaikin2BitFreshAir',['../ir__Daikin_8h.html#a9ab2c4b0f415ce0042b848e44850b7b8',1,'ir_Daikin.h']]], + ['kdaikin2bitfreshairhigh_1065',['kDaikin2BitFreshAirHigh',['../ir__Daikin_8h.html#a21a3f3c0f39827057d8f459283a72980',1,'ir_Daikin.h']]], + ['kdaikin2bitfreshairhighoffset_1066',['kDaikin2BitFreshAirHighOffset',['../ir__Daikin_8h.html#afd4f5946e5fa5d8f48af32b8934b0f93',1,'ir_Daikin.h']]], + ['kdaikin2bitfreshairoffset_1067',['kDaikin2BitFreshAirOffset',['../ir__Daikin_8h.html#a15e49a577737bdca28c28aeeb4260e57',1,'ir_Daikin.h']]], + ['kdaikin2bitmark_1068',['kDaikin2BitMark',['../ir__Daikin_8h.html#a226f10b7216d4f039cf79af823673a18',1,'ir_Daikin.h']]], + ['kdaikin2bitmold_1069',['kDaikin2BitMold',['../ir__Daikin_8h.html#aa452116afeb7d246cee672d2717e0ff7',1,'ir_Daikin.h']]], + ['kdaikin2bitmoldoffset_1070',['kDaikin2BitMoldOffset',['../ir__Daikin_8h.html#a0e58caeb44ebc6b7c6d06e91fee33795',1,'ir_Daikin.h']]], + ['kdaikin2bitpower_1071',['kDaikin2BitPower',['../ir__Daikin_8h.html#ac7b549d7b68bc245521d7f4e6a4643ab',1,'ir_Daikin.h']]], + ['kdaikin2bitpoweroffset_1072',['kDaikin2BitPowerOffset',['../ir__Daikin_8h.html#a617d14e811cb26b86fef3048151ffc45',1,'ir_Daikin.h']]], + ['kdaikin2bitpurify_1073',['kDaikin2BitPurify',['../ir__Daikin_8h.html#a9c4d6aa579adbfe454aa19f9f604f21c',1,'ir_Daikin.h']]], + ['kdaikin2bitpurifyoffset_1074',['kDaikin2BitPurifyOffset',['../ir__Daikin_8h.html#a847a9646dc86c26da931e5bf6640ddab',1,'ir_Daikin.h']]], + ['kdaikin2bits_1075',['kDaikin2Bits',['../IRremoteESP8266_8h.html#affd9b805fff390d05a83ff4eaa1c98de',1,'IRremoteESP8266.h']]], + ['kdaikin2bitsleeptimer_1076',['kDaikin2BitSleepTimer',['../ir__Daikin_8h.html#a928ae056887b123fdf6b1e2072d03564',1,'ir_Daikin.h']]], + ['kdaikin2bitsleeptimeroffset_1077',['kDaikin2BitSleepTimerOffset',['../ir__Daikin_8h.html#abf7cfde40fd00c3500ed08831434b80f',1,'ir_Daikin.h']]], + ['kdaikin2defaultrepeat_1078',['kDaikin2DefaultRepeat',['../IRremoteESP8266_8h.html#a2dde8fd00f8a28e35da04cff9a3a1908',1,'IRremoteESP8266.h']]], + ['kdaikin2fanbyte_1079',['kDaikin2FanByte',['../ir__Daikin_8h.html#a88608f735885e11734ae83a0cc69dc8d',1,'ir_Daikin.h']]], + ['kdaikin2freq_1080',['kDaikin2Freq',['../ir__Daikin_8h.html#ab82e4836d9023c4ba3041d1226761461',1,'ir_Daikin.h']]], + ['kdaikin2gap_1081',['kDaikin2Gap',['../ir__Daikin_8h.html#afe14712c1be4ca14d5cd41e77d4bada0',1,'ir_Daikin.h']]], + ['kdaikin2hdrmark_1082',['kDaikin2HdrMark',['../ir__Daikin_8h.html#ab679ef183af5b94f53697d434e6540c3',1,'ir_Daikin.h']]], + ['kdaikin2hdrspace_1083',['kDaikin2HdrSpace',['../ir__Daikin_8h.html#a557f8eeaf55ff7fda0cacd0245ac27d3',1,'ir_Daikin.h']]], + ['kdaikin2leadermark_1084',['kDaikin2LeaderMark',['../ir__Daikin_8h.html#a533c7ea8f968502d4b31e14eb2b1f614',1,'ir_Daikin.h']]], + ['kdaikin2leaderspace_1085',['kDaikin2LeaderSpace',['../ir__Daikin_8h.html#a9d48d64e470ff0318bd62b3385433f57',1,'ir_Daikin.h']]], + ['kdaikin2lightoffset_1086',['kDaikin2LightOffset',['../ir__Daikin_8h.html#a0f40d38db7c625df9504798938ba24eb',1,'ir_Daikin.h']]], + ['kdaikin2lightsize_1087',['kDaikin2LightSize',['../ir__Daikin_8h.html#a4dc46fabef2c96a263a504a5f9012e1f',1,'ir_Daikin.h']]], + ['kdaikin2mincooltemp_1088',['kDaikin2MinCoolTemp',['../ir__Daikin_8h.html#a78b37644f9327537d35bec4c0fd8faee',1,'ir_Daikin.h']]], + ['kdaikin2onespace_1089',['kDaikin2OneSpace',['../ir__Daikin_8h.html#a70a96368500562fa95f88dc2f203c194',1,'ir_Daikin.h']]], + ['kdaikin2section1length_1090',['kDaikin2Section1Length',['../ir__Daikin_8h.html#a463878e9bfb22ca3c64a40259598872c',1,'ir_Daikin.h']]], + ['kdaikin2section2length_1091',['kDaikin2Section2Length',['../ir__Daikin_8h.html#a8cb956f86fdf487b1ea7ac388eeda2b5',1,'ir_Daikin.h']]], + ['kdaikin2sections_1092',['kDaikin2Sections',['../ir__Daikin_8h.html#a770cef4efa5d5668b063cf0e26f1b134',1,'ir_Daikin.h']]], + ['kdaikin2statelength_1093',['kDaikin2StateLength',['../IRremoteESP8266_8h.html#a349e4d17f83bb3e707ff19c0255c1644',1,'IRremoteESP8266.h']]], + ['kdaikin2swinghauto_1094',['kDaikin2SwingHAuto',['../ir__Daikin_8h.html#a834a3138b0f9bfdac98d26aa63bc951e',1,'ir_Daikin.h']]], + ['kdaikin2swinghleft_1095',['kDaikin2SwingHLeft',['../ir__Daikin_8h.html#aa9b294b2f12660081171df290a7e874f',1,'ir_Daikin.h']]], + ['kdaikin2swinghleftmax_1096',['kDaikin2SwingHLeftMax',['../ir__Daikin_8h.html#aac08696fc9734996537204c089db2f7c',1,'ir_Daikin.h']]], + ['kdaikin2swinghmiddle_1097',['kDaikin2SwingHMiddle',['../ir__Daikin_8h.html#ab882d68819344e622182b07ded30cccf',1,'ir_Daikin.h']]], + ['kdaikin2swinghright_1098',['kDaikin2SwingHRight',['../ir__Daikin_8h.html#a8d7c79266bedbb722dc1a74c8b727a27',1,'ir_Daikin.h']]], + ['kdaikin2swinghrightmax_1099',['kDaikin2SwingHRightMax',['../ir__Daikin_8h.html#a843ad9ee10eccd799814ca9fff57f481',1,'ir_Daikin.h']]], + ['kdaikin2swinghswing_1100',['kDaikin2SwingHSwing',['../ir__Daikin_8h.html#a3776d46e94a771a6dc94d14257f34d09',1,'ir_Daikin.h']]], + ['kdaikin2swinghwide_1101',['kDaikin2SwingHWide',['../ir__Daikin_8h.html#a93157e048486e564757ba737551cf481',1,'ir_Daikin.h']]], + ['kdaikin2swingvauto_1102',['kDaikin2SwingVAuto',['../ir__Daikin_8h.html#aa91228576ef22854a693c86df5276cbb',1,'ir_Daikin.h']]], + ['kdaikin2swingvbreeze_1103',['kDaikin2SwingVBreeze',['../ir__Daikin_8h.html#a5646d38fff6a985314158796665d9d76',1,'ir_Daikin.h']]], + ['kdaikin2swingvcirculate_1104',['kDaikin2SwingVCirculate',['../ir__Daikin_8h.html#a717bb32ce20e6d65ee78a9e8ba0f5490',1,'ir_Daikin.h']]], + ['kdaikin2swingvhigh_1105',['kDaikin2SwingVHigh',['../ir__Daikin_8h.html#a2d25d46fb289c3450ed6817a45982e27',1,'ir_Daikin.h']]], + ['kdaikin2swingvlow_1106',['kDaikin2SwingVLow',['../ir__Daikin_8h.html#accae3be213670675f8dfc974fe19f2cf',1,'ir_Daikin.h']]], + ['kdaikin2swingvswing_1107',['kDaikin2SwingVSwing',['../ir__Daikin_8h.html#a2a62938481ba7b4374df50867295c07d',1,'ir_Daikin.h']]], + ['kdaikin2tolerance_1108',['kDaikin2Tolerance',['../ir__Daikin_8h.html#ac428e884b15026c0610cc1b0b8b46154',1,'ir_Daikin.h']]], + ['kdaikin2zerospace_1109',['kDaikin2ZeroSpace',['../ir__Daikin_8h.html#a91b023ce8679d8d0e4434e014e746f99',1,'ir_Daikin.h']]], + ['kdaikin64bitmark_1110',['kDaikin64BitMark',['../ir__Daikin_8h.html#a6d89c1acd56b670b2aba65429d6fbf00',1,'ir_Daikin.h']]], + ['kdaikin64bits_1111',['kDaikin64Bits',['../IRremoteESP8266_8h.html#a89266e9211a81eda22475fb5a258484f',1,'IRremoteESP8266.h']]], + ['kdaikin64checksumoffset_1112',['kDaikin64ChecksumOffset',['../ir__Daikin_8h.html#a5c47c0a0b1d2a23620beb2496af958c5',1,'ir_Daikin.h']]], + ['kdaikin64checksumsize_1113',['kDaikin64ChecksumSize',['../ir__Daikin_8h.html#a0c068274c73deb732e70a7daf6684391',1,'ir_Daikin.h']]], + ['kdaikin64clockhourssize_1114',['kDaikin64ClockHoursSize',['../ir__Daikin_8h.html#ae6d8f59a9707bc807a209167231d4399',1,'ir_Daikin.h']]], + ['kdaikin64clockminssize_1115',['kDaikin64ClockMinsSize',['../ir__Daikin_8h.html#a3ab23d9db994fb6dd52208f5f69b4531',1,'ir_Daikin.h']]], + ['kdaikin64clockoffset_1116',['kDaikin64ClockOffset',['../ir__Daikin_8h.html#af204ccf4e6bd33439cec240445785e9c',1,'ir_Daikin.h']]], + ['kdaikin64clocksize_1117',['kDaikin64ClockSize',['../ir__Daikin_8h.html#a110f42ae8aa2651b195c67eef15c4d79',1,'ir_Daikin.h']]], + ['kdaikin64cool_1118',['kDaikin64Cool',['../ir__Daikin_8h.html#a1ed020e8e7b5b741e90c4a27ca9f3a91',1,'ir_Daikin.h']]], + ['kdaikin64defaultrepeat_1119',['kDaikin64DefaultRepeat',['../IRremoteESP8266_8h.html#aca64338c3e3bbe52f8ec5688317041b3',1,'IRremoteESP8266.h']]], + ['kdaikin64dry_1120',['kDaikin64Dry',['../ir__Daikin_8h.html#aa494c8e2a54209c7467fdd7f40655b0b',1,'ir_Daikin.h']]], + ['kdaikin64fan_1121',['kDaikin64Fan',['../ir__Daikin_8h.html#aa1f4bb12be0f74af35ee54a5540f8a7b',1,'ir_Daikin.h']]], + ['kdaikin64fanauto_1122',['kDaikin64FanAuto',['../ir__Daikin_8h.html#a6fbc965cb8194048ed27d586321c01b2',1,'ir_Daikin.h']]], + ['kdaikin64fanhigh_1123',['kDaikin64FanHigh',['../ir__Daikin_8h.html#a122d57c30d1f4ad8f20d44077b0a1970',1,'ir_Daikin.h']]], + ['kdaikin64fanlow_1124',['kDaikin64FanLow',['../ir__Daikin_8h.html#a5a692fdcb373acf101536adb4c18384f',1,'ir_Daikin.h']]], + ['kdaikin64fanmed_1125',['kDaikin64FanMed',['../ir__Daikin_8h.html#a9b2737ba57e38d4c3dfe7bc65de4c944',1,'ir_Daikin.h']]], + ['kdaikin64fanoffset_1126',['kDaikin64FanOffset',['../ir__Daikin_8h.html#a5523d6df96b83aa152adc1cbdac6534f',1,'ir_Daikin.h']]], + ['kdaikin64fanquiet_1127',['kDaikin64FanQuiet',['../ir__Daikin_8h.html#a1a7d78b2ed8ca5b83d6422d659ecb296',1,'ir_Daikin.h']]], + ['kdaikin64fansize_1128',['kDaikin64FanSize',['../ir__Daikin_8h.html#ac907b8f8d46eb7983a1289f23bc02401',1,'ir_Daikin.h']]], + ['kdaikin64fanturbo_1129',['kDaikin64FanTurbo',['../ir__Daikin_8h.html#ae6d370916c0897bc82346136d7922f5d',1,'ir_Daikin.h']]], + ['kdaikin64freq_1130',['kDaikin64Freq',['../ir__Daikin_8h.html#a7b63829df4d0e1de61ed396c3b07e988',1,'ir_Daikin.h']]], + ['kdaikin64gap_1131',['kDaikin64Gap',['../ir__Daikin_8h.html#ae191cb5f6c65b944970158caaf56618d',1,'ir_Daikin.h']]], + ['kdaikin64hdrmark_1132',['kDaikin64HdrMark',['../ir__Daikin_8h.html#abe7b92798de08dfc5f044869891bdec5',1,'ir_Daikin.h']]], + ['kdaikin64hdrspace_1133',['kDaikin64HdrSpace',['../ir__Daikin_8h.html#a1eac122554acda264f9aa48261b2a884',1,'ir_Daikin.h']]], + ['kdaikin64knowngoodstate_1134',['kDaikin64KnownGoodState',['../ir__Daikin_8h.html#a09f0aa8c586b35b79bbceb19e822eb48',1,'ir_Daikin.h']]], + ['kdaikin64ldrmark_1135',['kDaikin64LdrMark',['../ir__Daikin_8h.html#aca20b8ee0fa9a8aa2d676ef12bd5ba97',1,'ir_Daikin.h']]], + ['kdaikin64ldrspace_1136',['kDaikin64LdrSpace',['../ir__Daikin_8h.html#ada1084c119abe58dadcb17eb4cfed072',1,'ir_Daikin.h']]], + ['kdaikin64maxtemp_1137',['kDaikin64MaxTemp',['../ir__Daikin_8h.html#a495e3b77590263a2c043c1ba12489fac',1,'ir_Daikin.h']]], + ['kdaikin64mintemp_1138',['kDaikin64MinTemp',['../ir__Daikin_8h.html#a209cb1798ae64de1f5274fb167ee62ea',1,'ir_Daikin.h']]], + ['kdaikin64modeoffset_1139',['kDaikin64ModeOffset',['../ir__Daikin_8h.html#ac32a0c805d01b5a9fa4d4aeb5546b8e3',1,'ir_Daikin.h']]], + ['kdaikin64modesize_1140',['kDaikin64ModeSize',['../ir__Daikin_8h.html#a451465916f9ae0586cf915005be33315',1,'ir_Daikin.h']]], + ['kdaikin64offtimeenablebit_1141',['kDaikin64OffTimeEnableBit',['../ir__Daikin_8h.html#a5d5c1380e6dd22cef44a76f74049a813',1,'ir_Daikin.h']]], + ['kdaikin64offtimehalfhourbit_1142',['kDaikin64OffTimeHalfHourBit',['../ir__Daikin_8h.html#a766df1d3c0fce7576a3e694b6e0d9242',1,'ir_Daikin.h']]], + ['kdaikin64offtimeoffset_1143',['kDaikin64OffTimeOffset',['../ir__Daikin_8h.html#a3aecddae0a4c0a3123b296dd6b0fb38e',1,'ir_Daikin.h']]], + ['kdaikin64offtimesize_1144',['kDaikin64OffTimeSize',['../ir__Daikin_8h.html#a70e8ae340d5f1ca35b2d6a46020b9dcc',1,'ir_Daikin.h']]], + ['kdaikin64onespace_1145',['kDaikin64OneSpace',['../ir__Daikin_8h.html#ab3129b72f5300893d04b47e72dd420e1',1,'ir_Daikin.h']]], + ['kdaikin64ontimeenablebit_1146',['kDaikin64OnTimeEnableBit',['../ir__Daikin_8h.html#ae264ee33d051149cecc08e3a026feba7',1,'ir_Daikin.h']]], + ['kdaikin64ontimehalfhourbit_1147',['kDaikin64OnTimeHalfHourBit',['../ir__Daikin_8h.html#a0d37e6624946b26dd30c3ed25181cc37',1,'ir_Daikin.h']]], + ['kdaikin64ontimeoffset_1148',['kDaikin64OnTimeOffset',['../ir__Daikin_8h.html#a6b4af969e8b114502f067b039b0a9467',1,'ir_Daikin.h']]], + ['kdaikin64ontimesize_1149',['kDaikin64OnTimeSize',['../ir__Daikin_8h.html#a46c5e1db123959992db9e746e2b3c58a',1,'ir_Daikin.h']]], + ['kdaikin64overhead_1150',['kDaikin64Overhead',['../ir__Daikin_8h.html#af0dafe45d0127430e05f2312e8ba99bb',1,'ir_Daikin.h']]], + ['kdaikin64powertogglebit_1151',['kDaikin64PowerToggleBit',['../ir__Daikin_8h.html#a55ca8803d859f0ffaac3c3547d6b532c',1,'ir_Daikin.h']]], + ['kdaikin64sleepbit_1152',['kDaikin64SleepBit',['../ir__Daikin_8h.html#addbe01f4a4766469fe5fd1cf9972f437',1,'ir_Daikin.h']]], + ['kdaikin64swingvbit_1153',['kDaikin64SwingVBit',['../ir__Daikin_8h.html#a9c7cbb529c760cead772fe03f7f90b1a',1,'ir_Daikin.h']]], + ['kdaikin64tempoffset_1154',['kDaikin64TempOffset',['../ir__Daikin_8h.html#a4b66ea40f97deafc22df18bd0942b5f1',1,'ir_Daikin.h']]], + ['kdaikin64tempsize_1155',['kDaikin64TempSize',['../ir__Daikin_8h.html#acc21945b46b307068e8669c83fbe5837',1,'ir_Daikin.h']]], + ['kdaikin64tolerancedelta_1156',['kDaikin64ToleranceDelta',['../ir__Daikin_8h.html#ae0b22a140c2727de9a347e8ab8d554e9',1,'ir_Daikin.h']]], + ['kdaikin64zerospace_1157',['kDaikin64ZeroSpace',['../ir__Daikin_8h.html#a142e45c289af1e9802254b9c138003fa',1,'ir_Daikin.h']]], + ['kdaikinauto_1158',['kDaikinAuto',['../ir__Daikin_8h.html#af3a0e7c149d020002cdf345a15606542',1,'ir_Daikin.h']]], + ['kdaikinbeeploud_1159',['kDaikinBeepLoud',['../ir__Daikin_8h.html#a4eb2b3899076882e3ed23220138ebac1',1,'ir_Daikin.h']]], + ['kdaikinbeepoff_1160',['kDaikinBeepOff',['../ir__Daikin_8h.html#a8271934c8bbd4b8e4d6aacdee5a038cf',1,'ir_Daikin.h']]], + ['kdaikinbeepquiet_1161',['kDaikinBeepQuiet',['../ir__Daikin_8h.html#a11008f7d6afc934426b88704d47301e7',1,'ir_Daikin.h']]], + ['kdaikinbitcomfort_1162',['kDaikinBitComfort',['../ir__Daikin_8h.html#aede9991f88965161d3f7cf1dba7fdeb7',1,'ir_Daikin.h']]], + ['kdaikinbitcomfortoffset_1163',['kDaikinBitComfortOffset',['../ir__Daikin_8h.html#a2e218dda2eb4ab3a97ea8018192c5f85',1,'ir_Daikin.h']]], + ['kdaikinbitecono_1164',['kDaikinBitEcono',['../ir__Daikin_8h.html#ab579939e749517944e6e497d5e44e922',1,'ir_Daikin.h']]], + ['kdaikinbiteconooffset_1165',['kDaikinBitEconoOffset',['../ir__Daikin_8h.html#aa99539b36ab708397bd1adbd4fd4f378',1,'ir_Daikin.h']]], + ['kdaikinbiteye_1166',['kDaikinBitEye',['../ir__Daikin_8h.html#a98bbaae1b0f16cf6f2428dcf326eda51',1,'ir_Daikin.h']]], + ['kdaikinbitmark_1167',['kDaikinBitMark',['../ir__Daikin_8h.html#ae109b9ea2120f989dac2529345e38adb',1,'ir_Daikin.h']]], + ['kdaikinbitmold_1168',['kDaikinBitMold',['../ir__Daikin_8h.html#a916ad89ccf3c0225a4ca1b36d74c67b2',1,'ir_Daikin.h']]], + ['kdaikinbitmoldoffset_1169',['kDaikinBitMoldOffset',['../ir__Daikin_8h.html#ad794d6ff5b5d05642e2668378d3a1100',1,'ir_Daikin.h']]], + ['kdaikinbitofftimer_1170',['kDaikinBitOffTimer',['../ir__Daikin_8h.html#a5d68046ada1892be65f14d06c2a25b2b',1,'ir_Daikin.h']]], + ['kdaikinbitofftimeroffset_1171',['kDaikinBitOffTimerOffset',['../ir__Daikin_8h.html#a7156bec80ef23aa0e4e212e11d63bdef',1,'ir_Daikin.h']]], + ['kdaikinbitontimer_1172',['kDaikinBitOnTimer',['../ir__Daikin_8h.html#a421a745ce85313d326e00b996b5afd80',1,'ir_Daikin.h']]], + ['kdaikinbitontimeroffset_1173',['kDaikinBitOnTimerOffset',['../ir__Daikin_8h.html#a7a6b740034320cc25fb6d33d36845ca0',1,'ir_Daikin.h']]], + ['kdaikinbitpower_1174',['kDaikinBitPower',['../ir__Daikin_8h.html#ab0d91673bcd73cbbbf5f18d6d73b699e',1,'ir_Daikin.h']]], + ['kdaikinbitpowerful_1175',['kDaikinBitPowerful',['../ir__Daikin_8h.html#a4d03bc31a28d866c3bf855f6482209e8',1,'ir_Daikin.h']]], + ['kdaikinbitpowerfuloffset_1176',['kDaikinBitPowerfulOffset',['../ir__Daikin_8h.html#a772bca7454e28bd3f61cdd24f58b98c8',1,'ir_Daikin.h']]], + ['kdaikinbitpoweroffset_1177',['kDaikinBitPowerOffset',['../ir__Daikin_8h.html#ad3672753b2b06b52cd8afeca3f564af4',1,'ir_Daikin.h']]], + ['kdaikinbits_1178',['kDaikinBits',['../IRremoteESP8266_8h.html#a657f8e60bc1f896d4a46ec101c289485',1,'IRremoteESP8266.h']]], + ['kdaikinbitsensor_1179',['kDaikinBitSensor',['../ir__Daikin_8h.html#a37c7e26d1af184f844ef2c46064137ad',1,'ir_Daikin.h']]], + ['kdaikinbitsensoroffset_1180',['kDaikinBitSensorOffset',['../ir__Daikin_8h.html#a1ccb2c358aef3bf55005cf6b391e9e9b',1,'ir_Daikin.h']]], + ['kdaikinbitsilent_1181',['kDaikinBitSilent',['../ir__Daikin_8h.html#a85249d39c34b1a8b3bb8de4da32bb502',1,'ir_Daikin.h']]], + ['kdaikinbitsilentoffset_1182',['kDaikinBitSilentOffset',['../ir__Daikin_8h.html#a3fb5172c458084319937aa4ec2d6383b',1,'ir_Daikin.h']]], + ['kdaikinbitsshort_1183',['kDaikinBitsShort',['../IRremoteESP8266_8h.html#aebaa8eb786747761fb369cfd34181cb7',1,'IRremoteESP8266.h']]], + ['kdaikinbitweeklytimer_1184',['kDaikinBitWeeklyTimer',['../ir__Daikin_8h.html#a7d58b7c351394a43117e4710acd35cec',1,'ir_Daikin.h']]], + ['kdaikinbitweeklytimeroffset_1185',['kDaikinBitWeeklyTimerOffset',['../ir__Daikin_8h.html#a8ff2c05701327b6f26bee66361e39365',1,'ir_Daikin.h']]], + ['kdaikinbytechecksum1_1186',['kDaikinByteChecksum1',['../ir__Daikin_8h.html#a887d8d38cf4330e1107443471fa119ca',1,'ir_Daikin.h']]], + ['kdaikinbytechecksum2_1187',['kDaikinByteChecksum2',['../ir__Daikin_8h.html#ab27225f21b29e617bf03fc68cc6e8e0f',1,'ir_Daikin.h']]], + ['kdaikinbytechecksum3_1188',['kDaikinByteChecksum3',['../ir__Daikin_8h.html#a7277c453d4deed6abf0a7577b5b4454f',1,'ir_Daikin.h']]], + ['kdaikinbyteclockminshigh_1189',['kDaikinByteClockMinsHigh',['../ir__Daikin_8h.html#ade7d506fd7da26ae1713602c1620f716',1,'ir_Daikin.h']]], + ['kdaikinbyteclockminslow_1190',['kDaikinByteClockMinsLow',['../ir__Daikin_8h.html#a3c096c2f33eca6c6f7f57f0f684a4b43',1,'ir_Daikin.h']]], + ['kdaikinbytecomfort_1191',['kDaikinByteComfort',['../ir__Daikin_8h.html#a3b209715b7ac4e8ef4f15043654e646b',1,'ir_Daikin.h']]], + ['kdaikinbyteecono_1192',['kDaikinByteEcono',['../ir__Daikin_8h.html#ae08470f2e453a2a5b60bdb478fc8c6d7',1,'ir_Daikin.h']]], + ['kdaikinbyteeye_1193',['kDaikinByteEye',['../ir__Daikin_8h.html#ad3e2bb2f17d599c708e64cf08c042331',1,'ir_Daikin.h']]], + ['kdaikinbytefan_1194',['kDaikinByteFan',['../ir__Daikin_8h.html#a9078ad5b6b9afe43ffa0e646c35f3db6',1,'ir_Daikin.h']]], + ['kdaikinbytemold_1195',['kDaikinByteMold',['../ir__Daikin_8h.html#a81e098798e6aa7c0882703dced8ab039',1,'ir_Daikin.h']]], + ['kdaikinbyteofftimer_1196',['kDaikinByteOffTimer',['../ir__Daikin_8h.html#ad7fce891883a25e260cd8c0890d46f59',1,'ir_Daikin.h']]], + ['kdaikinbyteofftimerminshigh_1197',['kDaikinByteOffTimerMinsHigh',['../ir__Daikin_8h.html#a0294c99254e3eef7e7fa2cd169e0e5a9',1,'ir_Daikin.h']]], + ['kdaikinbyteofftimerminslow_1198',['kDaikinByteOffTimerMinsLow',['../ir__Daikin_8h.html#a45855767cf37f1562a7726dbf6419c87',1,'ir_Daikin.h']]], + ['kdaikinbyteontimer_1199',['kDaikinByteOnTimer',['../ir__Daikin_8h.html#a0a685bb92d8e3df4c9bd96b71c48f352',1,'ir_Daikin.h']]], + ['kdaikinbyteontimerminshigh_1200',['kDaikinByteOnTimerMinsHigh',['../ir__Daikin_8h.html#a77ce46689e1a353237edd45e7170bff6',1,'ir_Daikin.h']]], + ['kdaikinbyteontimerminslow_1201',['kDaikinByteOnTimerMinsLow',['../ir__Daikin_8h.html#a7c434f5c6a3febddf3da44e1c2b97872',1,'ir_Daikin.h']]], + ['kdaikinbytepower_1202',['kDaikinBytePower',['../ir__Daikin_8h.html#aa99cac4871f7ef1cdff2f41496989218',1,'ir_Daikin.h']]], + ['kdaikinbytepowerful_1203',['kDaikinBytePowerful',['../ir__Daikin_8h.html#a79b3d4cd40f839a3708fa33abb4b74c4',1,'ir_Daikin.h']]], + ['kdaikinbytesensor_1204',['kDaikinByteSensor',['../ir__Daikin_8h.html#afd18e8b5b4c9c6572659ea46df01a6df',1,'ir_Daikin.h']]], + ['kdaikinbytesilent_1205',['kDaikinByteSilent',['../ir__Daikin_8h.html#aac58a7371777f682cac3189d9905b968',1,'ir_Daikin.h']]], + ['kdaikinbyteswingh_1206',['kDaikinByteSwingH',['../ir__Daikin_8h.html#a58b88a2679bd57d723aa33afca4f2427',1,'ir_Daikin.h']]], + ['kdaikinbytetemp_1207',['kDaikinByteTemp',['../ir__Daikin_8h.html#acd14c2ebc40a8375343595ed8f0109f8',1,'ir_Daikin.h']]], + ['kdaikinbyteweeklytimer_1208',['kDaikinByteWeeklyTimer',['../ir__Daikin_8h.html#ad4eba59910311bdc8b489b27b4b59751',1,'ir_Daikin.h']]], + ['kdaikinclockminshighoffset_1209',['kDaikinClockMinsHighOffset',['../ir__Daikin_8h.html#a1b28496ffacf558f7919029f029c2dc6',1,'ir_Daikin.h']]], + ['kdaikinclockminshighsize_1210',['kDaikinClockMinsHighSize',['../ir__Daikin_8h.html#a1e018d153b13c65e411b3b090efc6d27',1,'ir_Daikin.h']]], + ['kdaikincool_1211',['kDaikinCool',['../ir__Daikin_8h.html#aa57615a0a9f79b97139580a807bf095f',1,'ir_Daikin.h']]], + ['kdaikincurbit_1212',['kDaikinCurBit',['../ir__Daikin_8h.html#afccfde2b46f5fcb425f02a79a9c20494',1,'ir_Daikin.h']]], + ['kdaikincurindex_1213',['kDaikinCurIndex',['../ir__Daikin_8h.html#a5c01a0bfbd92b337d2e4a5c3df381865',1,'ir_Daikin.h']]], + ['kdaikindefaultrepeat_1214',['kDaikinDefaultRepeat',['../IRremoteESP8266_8h.html#af691d5202b7f121a16b2d9871ee14d9c',1,'IRremoteESP8266.h']]], + ['kdaikindowoffset_1215',['kDaikinDoWOffset',['../ir__Daikin_8h.html#a07793a4b1ea8e9aabb77730ccbdf7e15',1,'ir_Daikin.h']]], + ['kdaikindowsize_1216',['kDaikinDoWSize',['../ir__Daikin_8h.html#a7bb34e2fc2c1926167b79889a5036ba0',1,'ir_Daikin.h']]], + ['kdaikindry_1217',['kDaikinDry',['../ir__Daikin_8h.html#ab6143bef74a122c3fba3a3b29df0cf29',1,'ir_Daikin.h']]], + ['kdaikinfan_1218',['kDaikinFan',['../ir__Daikin_8h.html#a616df34328cdac764aecc9ffb0f16f09',1,'ir_Daikin.h']]], + ['kdaikinfanauto_1219',['kDaikinFanAuto',['../ir__Daikin_8h.html#a87807bd5727d9da1b615fca2bd732292',1,'ir_Daikin.h']]], + ['kdaikinfanmax_1220',['kDaikinFanMax',['../ir__Daikin_8h.html#ab483f3913a909884f44f8cd8f779bca0',1,'ir_Daikin.h']]], + ['kdaikinfanmed_1221',['kDaikinFanMed',['../ir__Daikin_8h.html#ab6eb2c902c2b5f927160efc9fb9ab08c',1,'ir_Daikin.h']]], + ['kdaikinfanmin_1222',['kDaikinFanMin',['../ir__Daikin_8h.html#a83ad300b9374e50c22211501ee2d1a7a',1,'ir_Daikin.h']]], + ['kdaikinfanoffset_1223',['kDaikinFanOffset',['../ir__Daikin_8h.html#a48d0d0cb1174069d5b6ee2882761cb88',1,'ir_Daikin.h']]], + ['kdaikinfanquiet_1224',['kDaikinFanQuiet',['../ir__Daikin_8h.html#aae481cf166671c30bccdc7f47aa6666e',1,'ir_Daikin.h']]], + ['kdaikinfansize_1225',['kDaikinFanSize',['../ir__Daikin_8h.html#a1e490e414ff3f5f55b4cca443661cd1a',1,'ir_Daikin.h']]], + ['kdaikinfirstheader64_1226',['kDaikinFirstHeader64',['../ir__Daikin_8h.html#a0bd3b36061d545bb21562622642f4196',1,'ir_Daikin.h']]], + ['kdaikingap_1227',['kDaikinGap',['../ir__Daikin_8h.html#aed68991584125a277593c339ab387276',1,'ir_Daikin.h']]], + ['kdaikinhdrmark_1228',['kDaikinHdrMark',['../ir__Daikin_8h.html#a0a38b3bdfd8f4f7a18f969188388e29e',1,'ir_Daikin.h']]], + ['kdaikinhdrspace_1229',['kDaikinHdrSpace',['../ir__Daikin_8h.html#ac4ca6c53faeec7d7a7ccfb50802087dc',1,'ir_Daikin.h']]], + ['kdaikinheaderlength_1230',['kDaikinHeaderLength',['../ir__Daikin_8h.html#a476ca864b6791439549bb4257ca78b23',1,'ir_Daikin.h']]], + ['kdaikinheat_1231',['kDaikinHeat',['../ir__Daikin_8h.html#a05824dc5af4ed0d3eceda540ad0e7a9f',1,'ir_Daikin.h']]], + ['kdaikinlightbright_1232',['kDaikinLightBright',['../ir__Daikin_8h.html#a20a3103d8d0a672c0c05c1679bf3b2ab',1,'ir_Daikin.h']]], + ['kdaikinlightdim_1233',['kDaikinLightDim',['../ir__Daikin_8h.html#a1093baf5b62fca42f9361715be2198a3',1,'ir_Daikin.h']]], + ['kdaikinlightoff_1234',['kDaikinLightOff',['../ir__Daikin_8h.html#ae57f7d2ea43e865ebf8175a8dbacab45',1,'ir_Daikin.h']]], + ['kdaikinmarkexcess_1235',['kDaikinMarkExcess',['../ir__Daikin_8h.html#a5331e1ee51bd7b001346aa41ee5d26cc',1,'ir_Daikin.h']]], + ['kdaikinmaxtemp_1236',['kDaikinMaxTemp',['../ir__Daikin_8h.html#aab7be756494a5ed23e9202af769e0012',1,'ir_Daikin.h']]], + ['kdaikinmintemp_1237',['kDaikinMinTemp',['../ir__Daikin_8h.html#af257feb15dc282c7d06351ee9eed666b',1,'ir_Daikin.h']]], + ['kdaikinmodeoffset_1238',['kDaikinModeOffset',['../ir__Daikin_8h.html#a9a3aa5ee98496b468c5ba86faa3eeeae',1,'ir_Daikin.h']]], + ['kdaikinmodesize_1239',['kDaikinModeSize',['../ir__Daikin_8h.html#a00fc390085520e5382dbce2633b7142e',1,'ir_Daikin.h']]], + ['kdaikinonespace_1240',['kDaikinOneSpace',['../ir__Daikin_8h.html#a6653082dcfde989bd2c5810809fc18a9',1,'ir_Daikin.h']]], + ['kdaikinontimerminshighoffset_1241',['kDaikinOnTimerMinsHighOffset',['../ir__Daikin_8h.html#a2a4a4254fc853901686982c1410c77c8',1,'ir_Daikin.h']]], + ['kdaikinontimerminshighsize_1242',['kDaikinOnTimerMinsHighSize',['../ir__Daikin_8h.html#a2fc9c203378e49ea1d49557d776de620',1,'ir_Daikin.h']]], + ['kdaikinsection1length_1243',['kDaikinSection1Length',['../ir__Daikin_8h.html#ab3b8aacbebe6c1c5514141102d1ca26f',1,'ir_Daikin.h']]], + ['kdaikinsection2length_1244',['kDaikinSection2Length',['../ir__Daikin_8h.html#a2e65cdf05d22a20f01ae5f6d3e222218',1,'ir_Daikin.h']]], + ['kdaikinsection3length_1245',['kDaikinSection3Length',['../ir__Daikin_8h.html#ae7dbaf6b4034267e4610087f9f2f51e3',1,'ir_Daikin.h']]], + ['kdaikinsections_1246',['kDaikinSections',['../ir__Daikin_8h.html#aad822c70789b861fa5beb839833e0b4c',1,'ir_Daikin.h']]], + ['kdaikinstatelength_1247',['kDaikinStateLength',['../IRremoteESP8266_8h.html#af1fda5b9f355e526dc66cf58824315a7',1,'IRremoteESP8266.h']]], + ['kdaikinstatelengthshort_1248',['kDaikinStateLengthShort',['../IRremoteESP8266_8h.html#ae94c897cb0bd25ca7a4d693c7be9be3d',1,'IRremoteESP8266.h']]], + ['kdaikinswingoff_1249',['kDaikinSwingOff',['../ir__Daikin_8h.html#abc9194f48f63632b87c6139dd8ab6ecf',1,'ir_Daikin.h']]], + ['kdaikinswingoffset_1250',['kDaikinSwingOffset',['../ir__Daikin_8h.html#abeac0c8df9be90fc5b28db4b2284ed10',1,'ir_Daikin.h']]], + ['kdaikinswingon_1251',['kDaikinSwingOn',['../ir__Daikin_8h.html#af19ec29dc79837deca05f6061f2e6524',1,'ir_Daikin.h']]], + ['kdaikinswingsize_1252',['kDaikinSwingSize',['../ir__Daikin_8h.html#a0f7daf6ef2652bc0be591caa2fa0fad6',1,'ir_Daikin.h']]], + ['kdaikintempoffset_1253',['kDaikinTempOffset',['../ir__Daikin_8h.html#a1a38843bdf0f65f29c21b301f6f45ba5',1,'ir_Daikin.h']]], + ['kdaikintempsize_1254',['kDaikinTempSize',['../ir__Daikin_8h.html#aa2eef2bb403846d88df5387912af0a00',1,'ir_Daikin.h']]], + ['kdaikintolerance_1255',['kDaikinTolerance',['../ir__Daikin_8h.html#aea3938d1522df0040ddb9775075d6669',1,'ir_Daikin.h']]], + ['kdaikinunusedtime_1256',['kDaikinUnusedTime',['../ir__Daikin_8h.html#af60d27bb9d08317498b35f62c167f6a4',1,'ir_Daikin.h']]], + ['kdaikinzerospace_1257',['kDaikinZeroSpace',['../ir__Daikin_8h.html#ace5b2c2be3b58f22248eafb2148d059c',1,'ir_Daikin.h']]], + ['kdaysstr_1258',['kDaysStr',['../IRtext_8cpp.html#a4269111ae41c3a673ec0a87fca0fd78b',1,'kDaysStr(): IRtext.cpp'],['../IRtext_8h.html#aa779ae24412ef82ee3d1eade3f0381ae',1,'kDaysStr(): IRtext.cpp']]], + ['kdaystr_1259',['kDayStr',['../IRtext_8cpp.html#ab6fb8803c6a95d1926abb56b7ecb2e09',1,'kDayStr(): IRtext.cpp'],['../IRtext_8h.html#adb64531a5054629613696f9af39420e2',1,'kDayStr(): IRtext.cpp']]], + ['kdefaultesp32timer_1260',['kDefaultESP32Timer',['../IRrecv_8h.html#a80a2d3445a1752d18caf307d7677b709',1,'IRrecv.h']]], + ['kdefaultmessagegap_1261',['kDefaultMessageGap',['../IRsend_8h.html#ad49e9828319afbad49fd5082c50ef4a7',1,'IRsend.h']]], + ['kdelonghiacauto_1262',['kDelonghiAcAuto',['../ir__Delonghi_8h.html#ab10d4fe0b9dbe99ed942b73a6ff61d37',1,'ir_Delonghi.h']]], + ['kdelonghiacbitmark_1263',['kDelonghiAcBitMark',['../ir__Delonghi_8cpp.html#aa70f02d16b78f513e245871d4db0785a',1,'ir_Delonghi.cpp']]], + ['kdelonghiacbits_1264',['kDelonghiAcBits',['../IRremoteESP8266_8h.html#a7b9fba82b602cf38147f0586e037f909',1,'IRremoteESP8266.h']]], + ['kdelonghiacboostbit_1265',['kDelonghiAcBoostBit',['../ir__Delonghi_8h.html#a52c86741107eb5e33780f78fbf5667d5',1,'ir_Delonghi.h']]], + ['kdelonghiacchecksumoffset_1266',['kDelonghiAcChecksumOffset',['../ir__Delonghi_8h.html#a4b5e3d9874b016f60b7f9c26e7cf0cfd',1,'ir_Delonghi.h']]], + ['kdelonghiacchecksumsize_1267',['kDelonghiAcChecksumSize',['../ir__Delonghi_8h.html#a376acfc72923eccd3a1a9cc04453c0fc',1,'ir_Delonghi.h']]], + ['kdelonghiaccool_1268',['kDelonghiAcCool',['../ir__Delonghi_8h.html#a9447cc3a3f6f4e0603ecc99104523119',1,'ir_Delonghi.h']]], + ['kdelonghiacdefaultrepeat_1269',['kDelonghiAcDefaultRepeat',['../IRremoteESP8266_8h.html#a8f18256a0a6893e077e253e5e80da164',1,'IRremoteESP8266.h']]], + ['kdelonghiacdry_1270',['kDelonghiAcDry',['../ir__Delonghi_8h.html#a1c83f080ac1f48548fcfa5d691ef893d',1,'ir_Delonghi.h']]], + ['kdelonghiacfan_1271',['kDelonghiAcFan',['../ir__Delonghi_8h.html#af494534acfb8ae1c0f9c15bc13e2d0c8',1,'ir_Delonghi.h']]], + ['kdelonghiacfanauto_1272',['kDelonghiAcFanAuto',['../ir__Delonghi_8h.html#adf2286936d79d8c899283fa6e3838ebb',1,'ir_Delonghi.h']]], + ['kdelonghiacfanhigh_1273',['kDelonghiAcFanHigh',['../ir__Delonghi_8h.html#a03027eb1a6a382479b44db0699aee30b',1,'ir_Delonghi.h']]], + ['kdelonghiacfanlow_1274',['kDelonghiAcFanLow',['../ir__Delonghi_8h.html#a053a51021679cd5c4720e7ec68fa43eb',1,'ir_Delonghi.h']]], + ['kdelonghiacfanmedium_1275',['kDelonghiAcFanMedium',['../ir__Delonghi_8h.html#ac748c5e0b7c5acb108086f90c088028f',1,'ir_Delonghi.h']]], + ['kdelonghiacfanoffset_1276',['kDelonghiAcFanOffset',['../ir__Delonghi_8h.html#ab9ff55f2717de8401a940b6afd4c13d6',1,'ir_Delonghi.h']]], + ['kdelonghiacfansize_1277',['kDelonghiAcFanSize',['../ir__Delonghi_8h.html#adc3ed20ff78231b8ac2eb82481d3ebb2',1,'ir_Delonghi.h']]], + ['kdelonghiacfreq_1278',['kDelonghiAcFreq',['../ir__Delonghi_8cpp.html#a9425e4f71aa6454a89b55f3b5789d94d',1,'ir_Delonghi.cpp']]], + ['kdelonghiacgap_1279',['kDelonghiAcGap',['../ir__Delonghi_8cpp.html#ab1cd2481fc96811ed822c8c9f63420c3',1,'ir_Delonghi.cpp']]], + ['kdelonghiachdrmark_1280',['kDelonghiAcHdrMark',['../ir__Delonghi_8cpp.html#a0feead944883173788b8d02b7ae94ef8',1,'ir_Delonghi.cpp']]], + ['kdelonghiachdrspace_1281',['kDelonghiAcHdrSpace',['../ir__Delonghi_8cpp.html#a606ea96746b1b6471b1d76f05bdc7e5a',1,'ir_Delonghi.cpp']]], + ['kdelonghiachourssize_1282',['kDelonghiAcHoursSize',['../ir__Delonghi_8h.html#a94e0d6ed9ba66c467d9fb4467ab4e512',1,'ir_Delonghi.h']]], + ['kdelonghiacminssize_1283',['kDelonghiAcMinsSize',['../ir__Delonghi_8h.html#a91ed842a356878349760fe75f6d686b2',1,'ir_Delonghi.h']]], + ['kdelonghiacmodeoffset_1284',['kDelonghiAcModeOffset',['../ir__Delonghi_8h.html#a8044375ad833a12e56974b71ddfc2bc7',1,'ir_Delonghi.h']]], + ['kdelonghiacmodesize_1285',['kDelonghiAcModeSize',['../ir__Delonghi_8h.html#a30dc468cb735389aff3a27846e8a24f1',1,'ir_Delonghi.h']]], + ['kdelonghiacofftimerenablebit_1286',['kDelonghiAcOffTimerEnableBit',['../ir__Delonghi_8h.html#a93b8d905151be16f6d0918d6fd8d27e2',1,'ir_Delonghi.h']]], + ['kdelonghiacofftimerhoursoffset_1287',['kDelonghiAcOffTimerHoursOffset',['../ir__Delonghi_8h.html#a6d7b8115532bf01ae8c53b2ecbbf223b',1,'ir_Delonghi.h']]], + ['kdelonghiacofftimerminsoffset_1288',['kDelonghiAcOffTimerMinsOffset',['../ir__Delonghi_8h.html#a47b2f9c730c23d2c117141653622e04b',1,'ir_Delonghi.h']]], + ['kdelonghiaconespace_1289',['kDelonghiAcOneSpace',['../ir__Delonghi_8cpp.html#a8805fdc60cd3537ba2d94038610a3490',1,'ir_Delonghi.cpp']]], + ['kdelonghiacontimerenablebit_1290',['kDelonghiAcOnTimerEnableBit',['../ir__Delonghi_8h.html#a56d225e53ffcc29c486fce295ff3295b',1,'ir_Delonghi.h']]], + ['kdelonghiacontimerhoursoffset_1291',['kDelonghiAcOnTimerHoursOffset',['../ir__Delonghi_8h.html#a310b01f1ba238a8342261c01f77f0234',1,'ir_Delonghi.h']]], + ['kdelonghiacontimerminsoffset_1292',['kDelonghiAcOnTimerMinsOffset',['../ir__Delonghi_8h.html#a37d9a33640b64833daeb1ccc4e209be1',1,'ir_Delonghi.h']]], + ['kdelonghiacoverhead_1293',['kDelonghiAcOverhead',['../ir__Delonghi_8cpp.html#ac265c123c0cd7492d26f030d129f3475',1,'ir_Delonghi.cpp']]], + ['kdelonghiacpowerbit_1294',['kDelonghiAcPowerBit',['../ir__Delonghi_8h.html#ac89b7d74aaf3d4beaa21849085d2d7e3',1,'ir_Delonghi.h']]], + ['kdelonghiacsleepbit_1295',['kDelonghiAcSleepBit',['../ir__Delonghi_8h.html#aa1f75ea73bac50c6645625393b137391',1,'ir_Delonghi.h']]], + ['kdelonghiactempautodrymode_1296',['kDelonghiAcTempAutoDryMode',['../ir__Delonghi_8h.html#add6f728d2746a089e00a35644d664a6c',1,'ir_Delonghi.h']]], + ['kdelonghiactempfanmode_1297',['kDelonghiAcTempFanMode',['../ir__Delonghi_8h.html#a120ae31fac35c33214317c3187aae15c',1,'ir_Delonghi.h']]], + ['kdelonghiactempmaxc_1298',['kDelonghiAcTempMaxC',['../ir__Delonghi_8h.html#a476922b8d240c46cf092897f6c701e87',1,'ir_Delonghi.h']]], + ['kdelonghiactempmaxf_1299',['kDelonghiAcTempMaxF',['../ir__Delonghi_8h.html#abc11f81bc221aa3789258b7a990633b3',1,'ir_Delonghi.h']]], + ['kdelonghiactempminc_1300',['kDelonghiAcTempMinC',['../ir__Delonghi_8h.html#ad31267284f7dd8f533fc978ed7e92428',1,'ir_Delonghi.h']]], + ['kdelonghiactempminf_1301',['kDelonghiAcTempMinF',['../ir__Delonghi_8h.html#a0311abab5eff5a8c47261db8e3d40ed5',1,'ir_Delonghi.h']]], + ['kdelonghiactempoffset_1302',['kDelonghiAcTempOffset',['../ir__Delonghi_8h.html#a9d02f6520d6d1d7e305ea651099cc9ef',1,'ir_Delonghi.h']]], + ['kdelonghiactempsize_1303',['kDelonghiAcTempSize',['../ir__Delonghi_8h.html#a3fb467e0d2385893c8c7a8daa0505ec1',1,'ir_Delonghi.h']]], + ['kdelonghiactempunitbit_1304',['kDelonghiAcTempUnitBit',['../ir__Delonghi_8h.html#ac9e6f419569558f4bd5f5a6e10d24bb6',1,'ir_Delonghi.h']]], + ['kdelonghiactimermax_1305',['kDelonghiAcTimerMax',['../ir__Delonghi_8h.html#a44d3f0d850c5cd5ad8c0e2dc7c2bd860',1,'ir_Delonghi.h']]], + ['kdelonghiaczerospace_1306',['kDelonghiAcZeroSpace',['../ir__Delonghi_8cpp.html#a4c1a9a70a50c7da9aa6cf91af85c695e',1,'ir_Delonghi.cpp']]], + ['kdenon48bits_1307',['kDenon48Bits',['../IRremoteESP8266_8h.html#ad7389b5b4f01a16dbf940eaae005c805',1,'IRremoteESP8266.h']]], + ['kdenonbitmark_1308',['kDenonBitMark',['../ir__Denon_8cpp.html#a1cd978061cfdc9bf1d5e1142dad86e59',1,'ir_Denon.cpp']]], + ['kdenonbitmarkticks_1309',['kDenonBitMarkTicks',['../ir__Denon_8cpp.html#ae6dddc89296abc186ac524c3f1efbe63',1,'ir_Denon.cpp']]], + ['kdenonbits_1310',['kDenonBits',['../IRremoteESP8266_8h.html#a29160117e25f3dfc1cb899a4a53bc238',1,'IRremoteESP8266.h']]], + ['kdenonhdrmark_1311',['kDenonHdrMark',['../ir__Denon_8cpp.html#a6f7b5da8c723615200109f425df72254',1,'ir_Denon.cpp']]], + ['kdenonhdrmarkticks_1312',['kDenonHdrMarkTicks',['../ir__Denon_8cpp.html#a484a90cdd15de164c931f1c70ab02938',1,'ir_Denon.cpp']]], + ['kdenonhdrspace_1313',['kDenonHdrSpace',['../ir__Denon_8cpp.html#a758b11259a5dcab3e949739cf67106be',1,'ir_Denon.cpp']]], + ['kdenonhdrspaceticks_1314',['kDenonHdrSpaceTicks',['../ir__Denon_8cpp.html#afe6cb1be37dcea0251ebf0fc43640fe1',1,'ir_Denon.cpp']]], + ['kdenonlegacybits_1315',['kDenonLegacyBits',['../IRremoteESP8266_8h.html#aacf2eea1349016ccbc96e97a0976f4ec',1,'IRremoteESP8266.h']]], + ['kdenonmanufacturer_1316',['kDenonManufacturer',['../ir__Denon_8cpp.html#abd89138765e21d25991fd5857506491b',1,'ir_Denon.cpp']]], + ['kdenonmincommandlengthticks_1317',['kDenonMinCommandLengthTicks',['../ir__Denon_8cpp.html#abb20f9f6053e0d46399011de71697a6a',1,'ir_Denon.cpp']]], + ['kdenonmingap_1318',['kDenonMinGap',['../ir__Denon_8cpp.html#a19b3fe79e06b3ece2cb167d5e14b2c11',1,'ir_Denon.cpp']]], + ['kdenonmingapticks_1319',['kDenonMinGapTicks',['../ir__Denon_8cpp.html#a191e0cfcf8167805ef9bfdc05463c313',1,'ir_Denon.cpp']]], + ['kdenononespace_1320',['kDenonOneSpace',['../ir__Denon_8cpp.html#a150b22eeeb64b59a3d9df51904fdda3f',1,'ir_Denon.cpp']]], + ['kdenononespaceticks_1321',['kDenonOneSpaceTicks',['../ir__Denon_8cpp.html#ad15a88b8f6b953918799eac1e814d107',1,'ir_Denon.cpp']]], + ['kdenontick_1322',['kDenonTick',['../ir__Denon_8cpp.html#a6cc0eba04ca4a2362068bf47d1869752',1,'ir_Denon.cpp']]], + ['kdenonzerospace_1323',['kDenonZeroSpace',['../ir__Denon_8cpp.html#ad8f53f000727e66938d086eadb5bf6eb',1,'ir_Denon.cpp']]], + ['kdenonzerospaceticks_1324',['kDenonZeroSpaceTicks',['../ir__Denon_8cpp.html#aed0c86367586cd043d8381499b3a4bdd',1,'ir_Denon.cpp']]], + ['kdishbitmark_1325',['kDishBitMark',['../ir__Dish_8cpp.html#aabe7f9815a2f5e65558b0f482e2ac50e',1,'ir_Dish.cpp']]], + ['kdishbitmarkticks_1326',['kDishBitMarkTicks',['../ir__Dish_8cpp.html#a1cfd9b730c78aac35f6c2cb56367c7bb',1,'ir_Dish.cpp']]], + ['kdishbits_1327',['kDishBits',['../IRremoteESP8266_8h.html#aea0cc15e1c7a6edcd6b60d9ac62d4831',1,'IRremoteESP8266.h']]], + ['kdishhdrmark_1328',['kDishHdrMark',['../ir__Dish_8cpp.html#ac4311aaed27b1f37a41a2a9cced0ecc5',1,'ir_Dish.cpp']]], + ['kdishhdrmarkticks_1329',['kDishHdrMarkTicks',['../ir__Dish_8cpp.html#a8dce19ee6e3a6859bd2d43c0c9e90517',1,'ir_Dish.cpp']]], + ['kdishhdrspace_1330',['kDishHdrSpace',['../ir__Dish_8cpp.html#ac68dfa9e554c919fd51b379621b2fbc4',1,'ir_Dish.cpp']]], + ['kdishhdrspaceticks_1331',['kDishHdrSpaceTicks',['../ir__Dish_8cpp.html#ab212535e169722d7f23b461b011400c2',1,'ir_Dish.cpp']]], + ['kdishminrepeat_1332',['kDishMinRepeat',['../IRremoteESP8266_8h.html#a5c2263819b032e3af4d416ab41126bd8',1,'IRremoteESP8266.h']]], + ['kdishonespace_1333',['kDishOneSpace',['../ir__Dish_8cpp.html#a6f1986377a4571c8eba5f401b772c194',1,'ir_Dish.cpp']]], + ['kdishonespaceticks_1334',['kDishOneSpaceTicks',['../ir__Dish_8cpp.html#ade25414e4747c56303752060d9f89446',1,'ir_Dish.cpp']]], + ['kdishrptspace_1335',['kDishRptSpace',['../ir__Dish_8cpp.html#a67628a3581fe85638f72711581ec0e42',1,'ir_Dish.cpp']]], + ['kdishrptspaceticks_1336',['kDishRptSpaceTicks',['../ir__Dish_8cpp.html#a801af68fd07720f74abcf2712e3228dd',1,'ir_Dish.cpp']]], + ['kdishtick_1337',['kDishTick',['../ir__Dish_8cpp.html#aa1eccae3b18a457c7cec248d483e808a',1,'ir_Dish.cpp']]], + ['kdishzerospace_1338',['kDishZeroSpace',['../ir__Dish_8cpp.html#acde5c5a789af871f7b5aacdf3f0efeb7',1,'ir_Dish.cpp']]], + ['kdishzerospaceticks_1339',['kDishZeroSpaceTicks',['../ir__Dish_8cpp.html#a68a0f2b9e2e457c8a58fa533e0ca5336',1,'ir_Dish.cpp']]], + ['kdisplaytempstr_1340',['kDisplayTempStr',['../IRtext_8cpp.html#a018814e961b4eb51b91680db3be7d17c',1,'kDisplayTempStr(): IRtext.cpp'],['../IRtext_8h.html#a98f3ba92617c82c9091f155eebcdb3f3',1,'kDisplayTempStr(): IRtext.cpp']]], + ['kdoshishabitmark_1341',['kDoshishaBitMark',['../ir__Doshisha_8cpp.html#a50a4feaff92c4a9fbba6128638fdb2fb',1,'ir_Doshisha.cpp']]], + ['kdoshishabits_1342',['kDoshishaBits',['../IRremoteESP8266_8h.html#aedc53534cf6a40144be80abeee498362',1,'IRremoteESP8266.h']]], + ['kdoshishahdrmark_1343',['kDoshishaHdrMark',['../ir__Doshisha_8cpp.html#adbfc15a1abb62540538afc9c645c1875',1,'ir_Doshisha.cpp']]], + ['kdoshishahdrspace_1344',['kDoshishaHdrSpace',['../ir__Doshisha_8cpp.html#a95a58b09fde0ee9ba59fcf838d16f736',1,'ir_Doshisha.cpp']]], + ['kdoshishaonespace_1345',['kDoshishaOneSpace',['../ir__Doshisha_8cpp.html#a48f3b70ddd3bc06c628ebe7ce29e74d3',1,'ir_Doshisha.cpp']]], + ['kdoshishazerospace_1346',['kDoshishaZeroSpace',['../ir__Doshisha_8cpp.html#a055ae27320600bc7e100ea7e147775f9',1,'ir_Doshisha.cpp']]], + ['kdownstr_1347',['kDownStr',['../IRtext_8cpp.html#a24998688cbbe54780843983394e925e5',1,'kDownStr(): IRtext.cpp'],['../IRtext_8h.html#a1f452a2ac1a2b89b9c71cf64c177f6bd',1,'kDownStr(): IRtext.cpp']]], + ['kdry_1348',['kDry',['../namespacestdAc.html#a99ad268c783486f9b3207cb78f48444fa0d254f21cc940f41cf7cc1c8ff46ce1f',1,'stdAc']]], + ['kdrystr_1349',['kDryStr',['../IRtext_8cpp.html#a149780a7bbdd13757ee4336c281ccd9d',1,'kDryStr(): IRtext.cpp'],['../IRtext_8h.html#aa0f25fa3aa8d26f4635c38e563a974f5',1,'kDryStr(): IRtext.cpp']]], + ['kdutydefault_1350',['kDutyDefault',['../IRsend_8h.html#affa33c170fe058b783372852fca7cc5b',1,'IRsend.h']]], + ['kdutymax_1351',['kDutyMax',['../IRsend_8h.html#ac076e3f79a3d8d2dae9fc248a6f571e2',1,'IRsend.h']]], + ['keconostr_1352',['kEconoStr',['../IRtext_8cpp.html#a4e3bee67564fe8f13d1d4f997924f464',1,'kEconoStr(): IRtext.cpp'],['../IRtext_8h.html#ab0b71c4429416a581a393f07e898bade',1,'kEconoStr(): IRtext.cpp']]], + ['kelectraacauto_1353',['kElectraAcAuto',['../ir__Electra_8h.html#a536965f5003a474d68860005883afb5a',1,'ir_Electra.h']]], + ['kelectraacbitmark_1354',['kElectraAcBitMark',['../ir__Electra_8cpp.html#a41f7254b061b099b8131ec4d2a775116',1,'ir_Electra.cpp']]], + ['kelectraacbits_1355',['kElectraAcBits',['../IRremoteESP8266_8h.html#aa46876681f26ccf39c6d341fef041a16',1,'IRremoteESP8266.h']]], + ['kelectraaccleanoffset_1356',['kElectraAcCleanOffset',['../ir__Electra_8h.html#a466b5c998c1e2736214f816f1bab8239',1,'ir_Electra.h']]], + ['kelectraaccool_1357',['kElectraAcCool',['../ir__Electra_8h.html#a6a37f4e24aad54a982994599a1bca59d',1,'ir_Electra.h']]], + ['kelectraacdry_1358',['kElectraAcDry',['../ir__Electra_8h.html#a9b8636631c22e003072bf84a9e30ddff',1,'ir_Electra.h']]], + ['kelectraacfan_1359',['kElectraAcFan',['../ir__Electra_8h.html#a28047c7d083d8bc9d9e34ab210c28185',1,'ir_Electra.h']]], + ['kelectraacfanauto_1360',['kElectraAcFanAuto',['../ir__Electra_8h.html#a48b3067393d4dc1e3461db4535212bff',1,'ir_Electra.h']]], + ['kelectraacfanhigh_1361',['kElectraAcFanHigh',['../ir__Electra_8h.html#a5cbf3118669f056f377b4625e8e97d8c',1,'ir_Electra.h']]], + ['kelectraacfanlow_1362',['kElectraAcFanLow',['../ir__Electra_8h.html#a9a5663e86cb766a4e4579d1b81473c44',1,'ir_Electra.h']]], + ['kelectraacfanmed_1363',['kElectraAcFanMed',['../ir__Electra_8h.html#a4e906bcb7aa6c0fc5c71bd06c43c3993',1,'ir_Electra.h']]], + ['kelectraacfanoffset_1364',['kElectraAcFanOffset',['../ir__Electra_8h.html#a0efe73807b12370aa7c57ff831e56192',1,'ir_Electra.h']]], + ['kelectraacfansize_1365',['kElectraAcFanSize',['../ir__Electra_8h.html#aeb9bddbd47459ae51c1207baac9e6219',1,'ir_Electra.h']]], + ['kelectraachdrmark_1366',['kElectraAcHdrMark',['../ir__Electra_8cpp.html#a1200826684547765f1e526f362408e2e',1,'ir_Electra.cpp']]], + ['kelectraachdrspace_1367',['kElectraAcHdrSpace',['../ir__Electra_8cpp.html#a28cd57057c52b0def3683e71ee92c5d3',1,'ir_Electra.cpp']]], + ['kelectraacheat_1368',['kElectraAcHeat',['../ir__Electra_8h.html#af764a4738f146b752b8e29357af257e3',1,'ir_Electra.h']]], + ['kelectraaclighttogglemask_1369',['kElectraAcLightToggleMask',['../ir__Electra_8h.html#aa51ccef46052dd988ac1bccc4f2303f6',1,'ir_Electra.h']]], + ['kelectraaclighttoggleoff_1370',['kElectraAcLightToggleOff',['../ir__Electra_8h.html#ae98c4a00f003cc98c253b9367226c5c5',1,'ir_Electra.h']]], + ['kelectraaclighttoggleon_1371',['kElectraAcLightToggleOn',['../ir__Electra_8h.html#aa9ca231e98b7e529b081c3aaa1876df9',1,'ir_Electra.h']]], + ['kelectraacmaxtemp_1372',['kElectraAcMaxTemp',['../ir__Electra_8h.html#a3962ca1ae42f006baa1181683cbcbf86',1,'ir_Electra.h']]], + ['kelectraacmessagegap_1373',['kElectraAcMessageGap',['../ir__Electra_8cpp.html#adbcde2296ebf6ea93c7c95ce6d0b264e',1,'ir_Electra.cpp']]], + ['kelectraacminrepeat_1374',['kElectraAcMinRepeat',['../IRremoteESP8266_8h.html#a2ca237d578ca9a59aecac9813ab851ba',1,'IRremoteESP8266.h']]], + ['kelectraacmintemp_1375',['kElectraAcMinTemp',['../ir__Electra_8h.html#ad6f62477d70b59c958ba347c228f8e2b',1,'ir_Electra.h']]], + ['kelectraacmodeoffset_1376',['kElectraAcModeOffset',['../ir__Electra_8h.html#a79ea9dfa776115e5ec4ee816c4eef559',1,'ir_Electra.h']]], + ['kelectraaconespace_1377',['kElectraAcOneSpace',['../ir__Electra_8cpp.html#aeb59d520635a93f5dd7acdbe4327174d',1,'ir_Electra.cpp']]], + ['kelectraacpoweroffset_1378',['kElectraAcPowerOffset',['../ir__Electra_8h.html#a54012f7683397fada44f13c3e57d9ee0',1,'ir_Electra.h']]], + ['kelectraacstatelength_1379',['kElectraAcStateLength',['../IRremoteESP8266_8h.html#a8fb8c5778feaa94114218c36e8e43641',1,'IRremoteESP8266.h']]], + ['kelectraacswinghoffset_1380',['kElectraAcSwingHOffset',['../ir__Electra_8h.html#ac39219316f9b49ead4183cd206b4a3fb',1,'ir_Electra.h']]], + ['kelectraacswingoff_1381',['kElectraAcSwingOff',['../ir__Electra_8h.html#ade2211d0bd695daf490300db856d660a',1,'ir_Electra.h']]], + ['kelectraacswingon_1382',['kElectraAcSwingOn',['../ir__Electra_8h.html#a4ef75911d929752357d727aee339563e',1,'ir_Electra.h']]], + ['kelectraacswingsize_1383',['kElectraAcSwingSize',['../ir__Electra_8h.html#a67c58c049b50d04d4fadd93eee0231cf',1,'ir_Electra.h']]], + ['kelectraacswingvoffset_1384',['kElectraAcSwingVOffset',['../ir__Electra_8h.html#a4a5737e41994fe6c0cd566be354a70fb',1,'ir_Electra.h']]], + ['kelectraactempdelta_1385',['kElectraAcTempDelta',['../ir__Electra_8h.html#ac3310f7b0d4b9fbe22d7192465669487',1,'ir_Electra.h']]], + ['kelectraactempoffset_1386',['kElectraAcTempOffset',['../ir__Electra_8h.html#a928ee72169f9ab56a4209606aa7e5e43',1,'ir_Electra.h']]], + ['kelectraactempsize_1387',['kElectraAcTempSize',['../ir__Electra_8h.html#aeeb469144f4fd02ddd8a802f5cf7c308',1,'ir_Electra.h']]], + ['kelectraacturbooffset_1388',['kElectraAcTurboOffset',['../ir__Electra_8h.html#afbbd997ef8ddf5a4adfd0a37404d6782',1,'ir_Electra.h']]], + ['kelectraaczerospace_1389',['kElectraAcZeroSpace',['../ir__Electra_8cpp.html#a1453e0796cfe6ca169fd3c56e2595082',1,'ir_Electra.cpp']]], + ['kelvinator_1390',['kelvinator',['../classIRac.html#a6e4d8061841a7271205f81bd8e7d6171',1,'IRac::kelvinator()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadab3a52797572065c912c34c976c08c542',1,'KELVINATOR(): IRremoteESP8266.h']]], + ['kepsonbits_1391',['kEpsonBits',['../IRremoteESP8266_8h.html#a77a0ed1143f5bfec87e0c9fde5c2c425',1,'IRremoteESP8266.h']]], + ['kepsonminrepeat_1392',['kEpsonMinRepeat',['../IRremoteESP8266_8h.html#ac8738cb054de937b77269acb973c5133',1,'IRremoteESP8266.h']]], + ['keyeautostr_1393',['kEyeAutoStr',['../IRtext_8cpp.html#ab7c525442638022439c7a277e1edf694',1,'kEyeAutoStr(): IRtext.cpp'],['../IRtext_8h.html#ae1395c08682a2b858261d76b97311f4f',1,'kEyeAutoStr(): IRtext.cpp']]], + ['keyestr_1394',['kEyeStr',['../IRtext_8cpp.html#a1d8dc83e7f15aacd013509e36a49a9d8',1,'kEyeStr(): IRtext.cpp'],['../IRtext_8h.html#a84f6d62456976cc31fe6b1648182a885',1,'kEyeStr(): IRtext.cpp']]], + ['kfalsestr_1395',['kFalseStr',['../IRtext_8cpp.html#a338ee31c8fb5a1c74c0640b279051cd2',1,'kFalseStr(): IRtext.cpp'],['../IRtext_8h.html#a3dc9321c4146369e0e0794e6a4de1988',1,'kFalseStr(): IRtext.cpp']]], + ['kfan_1396',['kFan',['../namespacestdAc.html#a99ad268c783486f9b3207cb78f48444fa03b7310c6ec7018a07ee9e3ffb95a34b',1,'stdAc']]], + ['kfanonlystr_1397',['kFanOnlyStr',['../IRtext_8cpp.html#adada7550fa28466a6db6f4544f8c7063',1,'kFanOnlyStr(): IRtext.cpp'],['../IRtext_8h.html#a220378c7b69db06362af5ad932965628',1,'kFanOnlyStr(): IRtext.cpp']]], + ['kfanstr_1398',['kFanStr',['../IRtext_8cpp.html#aaab703dfae684a786852a55c0f7f61ec',1,'kFanStr(): IRtext.cpp'],['../IRtext_8h.html#af7a0d76c40f3173a3e1367665d789300',1,'kFanStr(): IRtext.cpp']]], + ['kfaststr_1399',['kFastStr',['../IRtext_8cpp.html#ad6084cb569cd62bb1199c6ecc8ac4126',1,'kFastStr(): IRtext.cpp'],['../IRtext_8h.html#a82c26d9c7690ce001223e2a7cf8664d8',1,'kFastStr(): IRtext.cpp']]], + ['kfilterstr_1400',['kFilterStr',['../IRtext_8cpp.html#af287ead64de5dc3b1cbafe7bc945e519',1,'kFilterStr(): IRtext.cpp'],['../IRtext_8h.html#a5b3133e24c729077da411e08119033be',1,'kFilterStr(): IRtext.cpp']]], + ['kfixedstr_1401',['kFixedStr',['../IRtext_8cpp.html#ab45f91a889dae134e48c86586608bfc9',1,'kFixedStr(): IRtext.cpp'],['../IRtext_8h.html#ad9112f221a20ab498c5f133c4cea0b14',1,'kFixedStr(): IRtext.cpp']]], + ['kfnvbasis32_1402',['kFnvBasis32',['../IRrecv_8h.html#a04d9b0c909b377b36af3ece668482ca3',1,'IRrecv.h']]], + ['kfnvprime32_1403',['kFnvPrime32',['../IRrecv_8h.html#abcfcce36d3e2faef742aa3529c22f23f',1,'IRrecv.h']]], + ['kfollowstr_1404',['kFollowStr',['../IRtext_8cpp.html#a5477068666c86b3d605df8cf0240c86f',1,'kFollowStr(): IRtext.cpp'],['../IRtext_8h.html#a47a659e1c6373c4af92f4261148f695b',1,'kFollowStr(): IRtext.cpp']]], + ['kfooter_1405',['kFooter',['../IRrecv_8h.html#a5abb2b821f207ee9cf35f889f86d0ea3',1,'IRrecv.h']]], + ['kfreshstr_1406',['kFreshStr',['../IRtext_8cpp.html#ae416979803b912c932aa5eda837fc471',1,'kFreshStr(): IRtext.cpp'],['../IRtext_8h.html#adc8991e424df3ebf2f47ffc2854057f2',1,'kFreshStr(): IRtext.cpp']]], + ['kfujitsuacbitmark_1407',['kFujitsuAcBitMark',['../ir__Fujitsu_8cpp.html#a2e01906b1317da42fcc204284646e3db',1,'ir_Fujitsu.cpp']]], + ['kfujitsuacbits_1408',['kFujitsuAcBits',['../IRremoteESP8266_8h.html#aecd63891cac014d1b7e344638086ad47',1,'IRremoteESP8266.h']]], + ['kfujitsuaccleanoffset_1409',['kFujitsuAcCleanOffset',['../ir__Fujitsu_8h.html#ae7e7dc770ef9712296d2beeb085d2c1f',1,'ir_Fujitsu.h']]], + ['kfujitsuaccmdecono_1410',['kFujitsuAcCmdEcono',['../ir__Fujitsu_8h.html#a1e1eb4274232c43769f70b40f395a084',1,'ir_Fujitsu.h']]], + ['kfujitsuaccmdpowerful_1411',['kFujitsuAcCmdPowerful',['../ir__Fujitsu_8h.html#a69349537a37674a82b8ca630e6ca1b5a',1,'ir_Fujitsu.h']]], + ['kfujitsuaccmdstayon_1412',['kFujitsuAcCmdStayOn',['../ir__Fujitsu_8h.html#acc729a2cd570761f97c63b98024c157d',1,'ir_Fujitsu.h']]], + ['kfujitsuaccmdstephoriz_1413',['kFujitsuAcCmdStepHoriz',['../ir__Fujitsu_8h.html#ac67e3fa9ab8f1e1146bed1296f9a2131',1,'ir_Fujitsu.h']]], + ['kfujitsuaccmdstepvert_1414',['kFujitsuAcCmdStepVert',['../ir__Fujitsu_8h.html#a5dda60d753d93089fc323bfcd9567afd',1,'ir_Fujitsu.h']]], + ['kfujitsuaccmdtoggleswinghoriz_1415',['kFujitsuAcCmdToggleSwingHoriz',['../ir__Fujitsu_8h.html#a43b5912e65a8e6d3f1c672b155135f27',1,'ir_Fujitsu.h']]], + ['kfujitsuaccmdtoggleswingvert_1416',['kFujitsuAcCmdToggleSwingVert',['../ir__Fujitsu_8h.html#a66960882cee5d109f332917fe1f8067c',1,'ir_Fujitsu.h']]], + ['kfujitsuaccmdturnoff_1417',['kFujitsuAcCmdTurnOff',['../ir__Fujitsu_8h.html#a073903b56c40d89b9999ee9b7dc48f00',1,'ir_Fujitsu.h']]], + ['kfujitsuaccmdturnon_1418',['kFujitsuAcCmdTurnOn',['../ir__Fujitsu_8h.html#a51c2abda78c7d6ced59f88acb857281e',1,'ir_Fujitsu.h']]], + ['kfujitsuacfanauto_1419',['kFujitsuAcFanAuto',['../ir__Fujitsu_8h.html#a55bbb5a5b1760515f070d302c9fa4cbb',1,'ir_Fujitsu.h']]], + ['kfujitsuacfanhigh_1420',['kFujitsuAcFanHigh',['../ir__Fujitsu_8h.html#a30b11ea24865a00b10468015aae77886',1,'ir_Fujitsu.h']]], + ['kfujitsuacfanlow_1421',['kFujitsuAcFanLow',['../ir__Fujitsu_8h.html#aa0162cde862a3c02dd877a3a7933c130',1,'ir_Fujitsu.h']]], + ['kfujitsuacfanmed_1422',['kFujitsuAcFanMed',['../ir__Fujitsu_8h.html#a0efcb8e8a6521e4788a82ff6c556b67b',1,'ir_Fujitsu.h']]], + ['kfujitsuacfanquiet_1423',['kFujitsuAcFanQuiet',['../ir__Fujitsu_8h.html#a9abb4ec5fe9f27c6acd62273329490b6',1,'ir_Fujitsu.h']]], + ['kfujitsuacfansize_1424',['kFujitsuAcFanSize',['../ir__Fujitsu_8h.html#a797e68082ceebea788a215ecbfc279d9',1,'ir_Fujitsu.h']]], + ['kfujitsuacfilteroffset_1425',['kFujitsuAcFilterOffset',['../ir__Fujitsu_8h.html#a3c6349b24651bffb33f2633d3c65144c',1,'ir_Fujitsu.h']]], + ['kfujitsuachdrmark_1426',['kFujitsuAcHdrMark',['../ir__Fujitsu_8cpp.html#a96402e0aed6962a8a72cc736fa9bbc08',1,'ir_Fujitsu.cpp']]], + ['kfujitsuachdrspace_1427',['kFujitsuAcHdrSpace',['../ir__Fujitsu_8cpp.html#a655e37e172ab06dc06ca69f3c06223b2',1,'ir_Fujitsu.cpp']]], + ['kfujitsuacmaxtemp_1428',['kFujitsuAcMaxTemp',['../ir__Fujitsu_8h.html#ad817f46441ac1284e3bbe8417e4f4388',1,'ir_Fujitsu.h']]], + ['kfujitsuacminbits_1429',['kFujitsuAcMinBits',['../IRremoteESP8266_8h.html#a025caa6d0ae6becdd5ee58b5ac6ed61f',1,'IRremoteESP8266.h']]], + ['kfujitsuacmingap_1430',['kFujitsuAcMinGap',['../ir__Fujitsu_8cpp.html#a255fab3b9047b34cf6c4d42c0c82c485',1,'ir_Fujitsu.cpp']]], + ['kfujitsuacminrepeat_1431',['kFujitsuAcMinRepeat',['../IRremoteESP8266_8h.html#a9dd52420366167afb4c8831b4ccd02fa',1,'IRremoteESP8266.h']]], + ['kfujitsuacmintemp_1432',['kFujitsuAcMinTemp',['../ir__Fujitsu_8h.html#a35ec9572b356a7bcfb75947d03b198f7',1,'ir_Fujitsu.h']]], + ['kfujitsuacmodeauto_1433',['kFujitsuAcModeAuto',['../ir__Fujitsu_8h.html#acf0aa6d1d033c893a3acd5b8d7756a5b',1,'ir_Fujitsu.h']]], + ['kfujitsuacmodecool_1434',['kFujitsuAcModeCool',['../ir__Fujitsu_8h.html#a782e226fadab0a256144821cacea2314',1,'ir_Fujitsu.h']]], + ['kfujitsuacmodedry_1435',['kFujitsuAcModeDry',['../ir__Fujitsu_8h.html#ae66f2ed2e554a6befdf0377d01bce257',1,'ir_Fujitsu.h']]], + ['kfujitsuacmodefan_1436',['kFujitsuAcModeFan',['../ir__Fujitsu_8h.html#a7cc07ec4747b5cebc50257ec02297800',1,'ir_Fujitsu.h']]], + ['kfujitsuacmodeheat_1437',['kFujitsuAcModeHeat',['../ir__Fujitsu_8h.html#ad9b47b7419853a4cb1cf072023dac69b',1,'ir_Fujitsu.h']]], + ['kfujitsuaconespace_1438',['kFujitsuAcOneSpace',['../ir__Fujitsu_8cpp.html#a4f5246e6428cc701dbaa18923904713a',1,'ir_Fujitsu.cpp']]], + ['kfujitsuacoutsidequietoffset_1439',['kFujitsuAcOutsideQuietOffset',['../ir__Fujitsu_8h.html#a38522dc07bb7be2dd1ec654d4e60eb4f',1,'ir_Fujitsu.h']]], + ['kfujitsuacstatelength_1440',['kFujitsuAcStateLength',['../IRremoteESP8266_8h.html#ac3aa33a8386f73de0f57fc1ff7c6e7d9',1,'IRremoteESP8266.h']]], + ['kfujitsuacstatelengthshort_1441',['kFujitsuAcStateLengthShort',['../IRremoteESP8266_8h.html#a81cb09663eedbdc3888ee68438f0a5d3',1,'IRremoteESP8266.h']]], + ['kfujitsuacswingboth_1442',['kFujitsuAcSwingBoth',['../ir__Fujitsu_8h.html#a07c5a757b0c3bbe07412813807272434',1,'ir_Fujitsu.h']]], + ['kfujitsuacswinghoriz_1443',['kFujitsuAcSwingHoriz',['../ir__Fujitsu_8h.html#a8875f62d61afb8cbf468207aedcb8982',1,'ir_Fujitsu.h']]], + ['kfujitsuacswingoff_1444',['kFujitsuAcSwingOff',['../ir__Fujitsu_8h.html#a7f8109a1b8fd13a93d6b0255d05413df',1,'ir_Fujitsu.h']]], + ['kfujitsuacswingsize_1445',['kFujitsuAcSwingSize',['../ir__Fujitsu_8h.html#a1eb20884dc6c9bccbe899f779c4b5ad4',1,'ir_Fujitsu.h']]], + ['kfujitsuacswingvert_1446',['kFujitsuAcSwingVert',['../ir__Fujitsu_8h.html#a5c532a43ab11bf7cb353de2081260f40',1,'ir_Fujitsu.h']]], + ['kfujitsuaczerospace_1447',['kFujitsuAcZeroSpace',['../ir__Fujitsu_8cpp.html#a3815b89a2037cd0c8d774217df603d6e',1,'ir_Fujitsu.cpp']]], + ['kgicablebitmark_1448',['kGicableBitMark',['../ir__GICable_8cpp.html#ac315be0b5e02fb4c7109a6f67c4fac8e',1,'ir_GICable.cpp']]], + ['kgicablebits_1449',['kGicableBits',['../IRremoteESP8266_8h.html#aceb5cbd7ba5d8bc11560ba29137b10fa',1,'IRremoteESP8266.h']]], + ['kgicablehdrmark_1450',['kGicableHdrMark',['../ir__GICable_8cpp.html#a0388e7a2030246928029ed1c79ba819d',1,'ir_GICable.cpp']]], + ['kgicablehdrspace_1451',['kGicableHdrSpace',['../ir__GICable_8cpp.html#ab357b0a095155eab6206245008387fc0',1,'ir_GICable.cpp']]], + ['kgicablemincommandlength_1452',['kGicableMinCommandLength',['../ir__GICable_8cpp.html#a79db5de95ff6b42259f0a54fa59f46f6',1,'ir_GICable.cpp']]], + ['kgicablemingap_1453',['kGicableMinGap',['../ir__GICable_8cpp.html#aff7027ab4b933e4a7f5506590c25f699',1,'ir_GICable.cpp']]], + ['kgicableminrepeat_1454',['kGicableMinRepeat',['../IRremoteESP8266_8h.html#ad8142649290db6fc337ac839d4078aef',1,'IRremoteESP8266.h']]], + ['kgicableonespace_1455',['kGicableOneSpace',['../ir__GICable_8cpp.html#a31300a6f41363cbc22d40f26e693b8be',1,'ir_GICable.cpp']]], + ['kgicablerptspace_1456',['kGicableRptSpace',['../ir__GICable_8cpp.html#a9e0d82ed05e210dec2980a7d1a2e081b',1,'ir_GICable.cpp']]], + ['kgicablezerospace_1457',['kGicableZeroSpace',['../ir__GICable_8cpp.html#a1383f274e701ad5c8141beb7703783ff',1,'ir_GICable.cpp']]], + ['kglobalcachefreqindex_1458',['kGlobalCacheFreqIndex',['../ir__GlobalCache_8cpp.html#aaa0bdfe1eb76e8519a111b6588a5a3ff',1,'ir_GlobalCache.cpp']]], + ['kglobalcachemaxrepeat_1459',['kGlobalCacheMaxRepeat',['../ir__GlobalCache_8cpp.html#ae4a19c45ab538e8a386769cd98943a0d',1,'ir_GlobalCache.cpp']]], + ['kglobalcacheminusec_1460',['kGlobalCacheMinUsec',['../ir__GlobalCache_8cpp.html#a133cf089a7b40516fac3b1143981b2a6',1,'ir_GlobalCache.cpp']]], + ['kglobalcacherptindex_1461',['kGlobalCacheRptIndex',['../ir__GlobalCache_8cpp.html#ad4d55ed7e89cfc6d513dae6ecb211fe9',1,'ir_GlobalCache.cpp']]], + ['kglobalcacherptstartindex_1462',['kGlobalCacheRptStartIndex',['../ir__GlobalCache_8cpp.html#afde4c65e9e75558df6ac7aa479bf507a',1,'ir_GlobalCache.cpp']]], + ['kglobalcachestartindex_1463',['kGlobalCacheStartIndex',['../ir__GlobalCache_8cpp.html#a8640be7a67ce3f49452b28bc24912637',1,'ir_GlobalCache.cpp']]], + ['kgoodweatherauto_1464',['kGoodweatherAuto',['../ir__Goodweather_8h.html#a2fc5f0f7d0f68dcff193548830f50528',1,'ir_Goodweather.h']]], + ['kgoodweatherbitairflow_1465',['kGoodweatherBitAirFlow',['../ir__Goodweather_8h.html#ad86cdbc34a6a82c7595cace56d040d64',1,'ir_Goodweather.h']]], + ['kgoodweatherbitcommand_1466',['kGoodweatherBitCommand',['../ir__Goodweather_8h.html#ad6973bf4ac7801097077938e133b1718',1,'ir_Goodweather.h']]], + ['kgoodweatherbiteof_1467',['kGoodweatherBitEOF',['../ir__Goodweather_8h.html#a239d4d1fee77e0d220efb0bc0b3c779a',1,'ir_Goodweather.h']]], + ['kgoodweatherbitfan_1468',['kGoodweatherBitFan',['../ir__Goodweather_8h.html#aa3d5f146109dd671e4d7d86c1dbccba7',1,'ir_Goodweather.h']]], + ['kgoodweatherbitlight_1469',['kGoodweatherBitLight',['../ir__Goodweather_8h.html#a976dc2b37d1fcec4bbc0958861b5a9b0',1,'ir_Goodweather.h']]], + ['kgoodweatherbitmark_1470',['kGoodweatherBitMark',['../ir__Goodweather_8h.html#acb9fb47b2a207997fda0244d1bafbe89',1,'ir_Goodweather.h']]], + ['kgoodweatherbitmode_1471',['kGoodweatherBitMode',['../ir__Goodweather_8h.html#a3795b45c06f6d2db23cc45478bfeeca9',1,'ir_Goodweather.h']]], + ['kgoodweatherbitpower_1472',['kGoodweatherBitPower',['../ir__Goodweather_8h.html#a652b820b22c8381a6035fea7b1ae1b8d',1,'ir_Goodweather.h']]], + ['kgoodweatherbits_1473',['kGoodweatherBits',['../IRremoteESP8266_8h.html#afa2675ce42d00175ec95caa6cd87a425',1,'IRremoteESP8266.h']]], + ['kgoodweatherbitsleep_1474',['kGoodweatherBitSleep',['../ir__Goodweather_8h.html#a763e8033483516c093ad12a378e0c8f8',1,'ir_Goodweather.h']]], + ['kgoodweatherbitswing_1475',['kGoodweatherBitSwing',['../ir__Goodweather_8h.html#a0a3fc264b6a77157174c207688ac2cda',1,'ir_Goodweather.h']]], + ['kgoodweatherbittemp_1476',['kGoodweatherBitTemp',['../ir__Goodweather_8h.html#a692faf9976f90d67d183ff99ed06ee51',1,'ir_Goodweather.h']]], + ['kgoodweatherbitturbo_1477',['kGoodweatherBitTurbo',['../ir__Goodweather_8h.html#afe2ad22bc8ba5ab9cad025e9adaf4d56',1,'ir_Goodweather.h']]], + ['kgoodweathercmdairflow_1478',['kGoodweatherCmdAirFlow',['../ir__Goodweather_8h.html#aa51248353573abd95af37e46f0a2c4a7',1,'ir_Goodweather.h']]], + ['kgoodweathercmddowntemp_1479',['kGoodweatherCmdDownTemp',['../ir__Goodweather_8h.html#a8a0b72bf745b6003fb460a3c917eecff',1,'ir_Goodweather.h']]], + ['kgoodweathercmdfan_1480',['kGoodweatherCmdFan',['../ir__Goodweather_8h.html#a4a0881f87af157fdf9ed3d9f342f1ac5',1,'ir_Goodweather.h']]], + ['kgoodweathercmdhold_1481',['kGoodweatherCmdHold',['../ir__Goodweather_8h.html#ac0f3b1413228cb7e86822c5690f20344',1,'ir_Goodweather.h']]], + ['kgoodweathercmdlight_1482',['kGoodweatherCmdLight',['../ir__Goodweather_8h.html#ae70c4e66b17db9caf4800eb57a50706f',1,'ir_Goodweather.h']]], + ['kgoodweathercmdmode_1483',['kGoodweatherCmdMode',['../ir__Goodweather_8h.html#a6042296931ab29e9dfa5a701f3e42175',1,'ir_Goodweather.h']]], + ['kgoodweathercmdpower_1484',['kGoodweatherCmdPower',['../ir__Goodweather_8h.html#a3f1bf85bb10343512bb276adfc64b3b2',1,'ir_Goodweather.h']]], + ['kgoodweathercmdsleep_1485',['kGoodweatherCmdSleep',['../ir__Goodweather_8h.html#a3f4d72b620c73aec68c2125430ca709d',1,'ir_Goodweather.h']]], + ['kgoodweathercmdswing_1486',['kGoodweatherCmdSwing',['../ir__Goodweather_8h.html#ab4ceedbe859811a9fb394f6ebf233cb5',1,'ir_Goodweather.h']]], + ['kgoodweathercmdtimer_1487',['kGoodweatherCmdTimer',['../ir__Goodweather_8h.html#ad4d247ea6c9fc237e0acda84fdaa2eb6',1,'ir_Goodweather.h']]], + ['kgoodweathercmdturbo_1488',['kGoodweatherCmdTurbo',['../ir__Goodweather_8h.html#aebc6d53b3e7d1769bff47968c19c09c9',1,'ir_Goodweather.h']]], + ['kgoodweathercmduptemp_1489',['kGoodweatherCmdUpTemp',['../ir__Goodweather_8h.html#a51a089b03bd72a247a4c35c2ff3f3dc6',1,'ir_Goodweather.h']]], + ['kgoodweathercommandsize_1490',['kGoodweatherCommandSize',['../ir__Goodweather_8h.html#aa5ae9f1b5f6458a25b31b0d2c7feb508',1,'ir_Goodweather.h']]], + ['kgoodweathercool_1491',['kGoodweatherCool',['../ir__Goodweather_8h.html#a92c807d6ff8a3356e65f04e82b99aba4',1,'ir_Goodweather.h']]], + ['kgoodweatherdry_1492',['kGoodweatherDry',['../ir__Goodweather_8h.html#ac5174a3e2c64361c25adcf7caa5b714c',1,'ir_Goodweather.h']]], + ['kgoodweathereofmask_1493',['kGoodweatherEOFMask',['../ir__Goodweather_8h.html#a3d86da1a2bab92a9f70cc88e2628f266',1,'ir_Goodweather.h']]], + ['kgoodweatherextratolerance_1494',['kGoodweatherExtraTolerance',['../ir__Goodweather_8h.html#aae814dfbd574241d3b434d0bf2d38939',1,'ir_Goodweather.h']]], + ['kgoodweatherfan_1495',['kGoodweatherFan',['../ir__Goodweather_8h.html#ad56f00c7e39df93d28419d6a4afa360b',1,'ir_Goodweather.h']]], + ['kgoodweatherfanauto_1496',['kGoodweatherFanAuto',['../ir__Goodweather_8h.html#a9cc119524ac1cb93395dff3bb44b85cc',1,'ir_Goodweather.h']]], + ['kgoodweatherfanhigh_1497',['kGoodweatherFanHigh',['../ir__Goodweather_8h.html#af2b24de50923a0aabd4379dc6d3ef10f',1,'ir_Goodweather.h']]], + ['kgoodweatherfanlow_1498',['kGoodweatherFanLow',['../ir__Goodweather_8h.html#a7bc7c0cf9f2df574a7c087542991ab9b',1,'ir_Goodweather.h']]], + ['kgoodweatherfanmed_1499',['kGoodweatherFanMed',['../ir__Goodweather_8h.html#a5174245e9369a488332b32dfa416963e',1,'ir_Goodweather.h']]], + ['kgoodweatherfansize_1500',['kGoodweatherFanSize',['../ir__Goodweather_8h.html#a687ae6502d8fe6b4a5bd11468106481e',1,'ir_Goodweather.h']]], + ['kgoodweatherhdrmark_1501',['kGoodweatherHdrMark',['../ir__Goodweather_8h.html#a5c39e33226770babb4b0e89fc0cde709',1,'ir_Goodweather.h']]], + ['kgoodweatherhdrspace_1502',['kGoodweatherHdrSpace',['../ir__Goodweather_8h.html#a837bfeaa111b00e2744c4ada89281bfb',1,'ir_Goodweather.h']]], + ['kgoodweatherheat_1503',['kGoodweatherHeat',['../ir__Goodweather_8h.html#a17d223f03df2718151a426582a224a2e',1,'ir_Goodweather.h']]], + ['kgoodweatherminrepeat_1504',['kGoodweatherMinRepeat',['../IRremoteESP8266_8h.html#a885bc5a3a5ba2d8827a62d07a43d0321',1,'IRremoteESP8266.h']]], + ['kgoodweatheronespace_1505',['kGoodweatherOneSpace',['../ir__Goodweather_8h.html#a8efa251085a8f434cb91c049e65cda56',1,'ir_Goodweather.h']]], + ['kgoodweatherstateinit_1506',['kGoodweatherStateInit',['../ir__Goodweather_8h.html#a5ec0e7ca097241d6bef0cbf2135c8fca',1,'ir_Goodweather.h']]], + ['kgoodweatherswingfast_1507',['kGoodweatherSwingFast',['../ir__Goodweather_8h.html#a2d2fa76fa35cf7d450aaf0b980660514',1,'ir_Goodweather.h']]], + ['kgoodweatherswingoff_1508',['kGoodweatherSwingOff',['../ir__Goodweather_8h.html#aa2c53f56daa2820351924d91b542bb67',1,'ir_Goodweather.h']]], + ['kgoodweatherswingsize_1509',['kGoodweatherSwingSize',['../ir__Goodweather_8h.html#a208e47dc4f9e6a85464b4ce3ecaf5c3e',1,'ir_Goodweather.h']]], + ['kgoodweatherswingslow_1510',['kGoodweatherSwingSlow',['../ir__Goodweather_8h.html#ad2c87d849af2c77088ffc533d279aadb',1,'ir_Goodweather.h']]], + ['kgoodweathertempmax_1511',['kGoodweatherTempMax',['../ir__Goodweather_8h.html#abec401548ce2221a9c668318a33a039c',1,'ir_Goodweather.h']]], + ['kgoodweathertempmin_1512',['kGoodweatherTempMin',['../ir__Goodweather_8h.html#a8e76c0ec1bd5e124d9cee5742a2d1cfe',1,'ir_Goodweather.h']]], + ['kgoodweathertempsize_1513',['kGoodweatherTempSize',['../ir__Goodweather_8h.html#a2ef3336be36de4f34940de28cfe195a8',1,'ir_Goodweather.h']]], + ['kgoodweatherzerospace_1514',['kGoodweatherZeroSpace',['../ir__Goodweather_8h.html#a411cbfb812d102daeaf6a83c742f9a9a',1,'ir_Goodweather.h']]], + ['kgpiounused_1515',['kGpioUnused',['../IRac_8h.html#afd817f0bc02c516b6430098dcecde383',1,'IRac.h']]], + ['kgreeauto_1516',['kGreeAuto',['../ir__Gree_8h.html#a65d2d0192a1baff86b859da1018ef2f8',1,'ir_Gree.h']]], + ['kgreebitmark_1517',['kGreeBitMark',['../ir__Gree_8cpp.html#ad7e23346f6d793cc2469e4c8a5650397',1,'ir_Gree.cpp']]], + ['kgreebits_1518',['kGreeBits',['../IRremoteESP8266_8h.html#acadcc5d03e09784642f008d4d2913c7d',1,'IRremoteESP8266.h']]], + ['kgreeblockfooter_1519',['kGreeBlockFooter',['../ir__Gree_8cpp.html#ae6d01cfa7ee2ef6ff27c1ecd7cd9be51',1,'ir_Gree.cpp']]], + ['kgreeblockfooterbits_1520',['kGreeBlockFooterBits',['../ir__Gree_8cpp.html#ae866eef4c729c703597a266917799cbd',1,'ir_Gree.cpp']]], + ['kgreecool_1521',['kGreeCool',['../ir__Gree_8h.html#a1e1eeab696b43864cec66e6485487cea',1,'ir_Gree.h']]], + ['kgreedefaultrepeat_1522',['kGreeDefaultRepeat',['../IRremoteESP8266_8h.html#a6816d2cb11b99a61fb63e6d0928e6706',1,'IRremoteESP8266.h']]], + ['kgreedisplaytempinside_1523',['kGreeDisplayTempInside',['../ir__Gree_8h.html#a7495e5873f63135490090929ed79e994',1,'ir_Gree.h']]], + ['kgreedisplaytempoff_1524',['kGreeDisplayTempOff',['../ir__Gree_8h.html#aa5881910d1c01b816f3ac22ddf0f89a8',1,'ir_Gree.h']]], + ['kgreedisplaytempoffset_1525',['kGreeDisplayTempOffset',['../ir__Gree_8h.html#ab60baff4d0e83964d6e5b23994949a06',1,'ir_Gree.h']]], + ['kgreedisplaytempoutside_1526',['kGreeDisplayTempOutside',['../ir__Gree_8h.html#a737c90e90897053623b15b5579cdb6a1',1,'ir_Gree.h']]], + ['kgreedisplaytempset_1527',['kGreeDisplayTempSet',['../ir__Gree_8h.html#a20f7d0948b158f83655ee4187a104176',1,'ir_Gree.h']]], + ['kgreedisplaytempsize_1528',['kGreeDisplayTempSize',['../ir__Gree_8h.html#aad94a8d5de27b1a46c03c9e3773cf8ec',1,'ir_Gree.h']]], + ['kgreedry_1529',['kGreeDry',['../ir__Gree_8h.html#aa818bcc036988ee24fe0467d128d174f',1,'ir_Gree.h']]], + ['kgreefan_1530',['kGreeFan',['../ir__Gree_8h.html#aa1513ffe43257664f761e4e1a5c2a38f',1,'ir_Gree.h']]], + ['kgreefanauto_1531',['kGreeFanAuto',['../ir__Gree_8h.html#aaad16357e34078257315aad7155b2cd1',1,'ir_Gree.h']]], + ['kgreefanmax_1532',['kGreeFanMax',['../ir__Gree_8h.html#a8753f860f2f503a4a70609fb000654f2',1,'ir_Gree.h']]], + ['kgreefanmed_1533',['kGreeFanMed',['../ir__Gree_8h.html#a674d096a91a5db4b5b7f1b0650c833de',1,'ir_Gree.h']]], + ['kgreefanmin_1534',['kGreeFanMin',['../ir__Gree_8h.html#a34ca09b196c41acc85a4fa0036f3ac3b',1,'ir_Gree.h']]], + ['kgreefanoffset_1535',['kGreeFanOffset',['../ir__Gree_8h.html#a3227e6075f673408577884feb0e6ef10',1,'ir_Gree.h']]], + ['kgreefansize_1536',['kGreeFanSize',['../ir__Gree_8h.html#a8285633b179fbe513c6f8bd2c316e957',1,'ir_Gree.h']]], + ['kgreehdrmark_1537',['kGreeHdrMark',['../ir__Gree_8cpp.html#aaae182fb09bed73e37a5b5d3aee6a5fb',1,'ir_Gree.cpp']]], + ['kgreehdrspace_1538',['kGreeHdrSpace',['../ir__Gree_8cpp.html#a96b50632219c2b5808aea4ee9077b15c',1,'ir_Gree.cpp']]], + ['kgreeheat_1539',['kGreeHeat',['../ir__Gree_8h.html#ada5dac7b789497bf7a434a809d4070f6',1,'ir_Gree.h']]], + ['kgreeifeeloffset_1540',['kGreeIFeelOffset',['../ir__Gree_8h.html#a7253f3b97bade5353a72bfcf2df7976b',1,'ir_Gree.h']]], + ['kgreelightoffset_1541',['kGreeLightOffset',['../ir__Gree_8h.html#ade795164ac467f2547583b9654e2e471',1,'ir_Gree.h']]], + ['kgreemaxtempc_1542',['kGreeMaxTempC',['../ir__Gree_8h.html#a4c01aedfff06ed5a028c40010ad7bfa0',1,'ir_Gree.h']]], + ['kgreemaxtempf_1543',['kGreeMaxTempF',['../ir__Gree_8h.html#a6495898a7a6ddda1473b55820f4b6c44',1,'ir_Gree.h']]], + ['kgreemintempc_1544',['kGreeMinTempC',['../ir__Gree_8h.html#ad127acfc710e281a7b29023c8d1da8f6',1,'ir_Gree.h']]], + ['kgreemintempf_1545',['kGreeMinTempF',['../ir__Gree_8h.html#acf0ecb1b535894e3e790b668333fb66b',1,'ir_Gree.h']]], + ['kgreemsgspace_1546',['kGreeMsgSpace',['../ir__Gree_8cpp.html#a619ed3a2915196ab91d87db2b5a829fd',1,'ir_Gree.cpp']]], + ['kgreeonespace_1547',['kGreeOneSpace',['../ir__Gree_8cpp.html#ab139138084643ea0fca13b28412904e9',1,'ir_Gree.cpp']]], + ['kgreepower1offset_1548',['kGreePower1Offset',['../ir__Gree_8h.html#a300b990aa836926d38dfea0ee99dc295',1,'ir_Gree.h']]], + ['kgreepower2offset_1549',['kGreePower2Offset',['../ir__Gree_8h.html#af29131d47e6cba73682727cd5e8b243d',1,'ir_Gree.h']]], + ['kgreesleepoffset_1550',['kGreeSleepOffset',['../ir__Gree_8h.html#ab715200758a0a4ee2733baf924729132',1,'ir_Gree.h']]], + ['kgreestatelength_1551',['kGreeStateLength',['../IRremoteESP8266_8h.html#a5558b24542873d8475e1ee0e2439839f',1,'IRremoteESP8266.h']]], + ['kgreeswingauto_1552',['kGreeSwingAuto',['../ir__Gree_8h.html#a414a503ad11c1d1d3b68d8b630df1f3a',1,'ir_Gree.h']]], + ['kgreeswingautooffset_1553',['kGreeSwingAutoOffset',['../ir__Gree_8h.html#a60d3de1ba88a6b06c79205116fbd7869',1,'ir_Gree.h']]], + ['kgreeswingdown_1554',['kGreeSwingDown',['../ir__Gree_8h.html#abbe69b966ceb1f9eb60fe9c3fb18088d',1,'ir_Gree.h']]], + ['kgreeswingdownauto_1555',['kGreeSwingDownAuto',['../ir__Gree_8h.html#abc7d7b7de5dd2eb9c0a6ca28827aeb06',1,'ir_Gree.h']]], + ['kgreeswinglastpos_1556',['kGreeSwingLastPos',['../ir__Gree_8h.html#a630cd8fec01f13bfda0fffc1a0e59199',1,'ir_Gree.h']]], + ['kgreeswingmiddle_1557',['kGreeSwingMiddle',['../ir__Gree_8h.html#a12a7caa871f33a5bb83611b4efc7a42b',1,'ir_Gree.h']]], + ['kgreeswingmiddleauto_1558',['kGreeSwingMiddleAuto',['../ir__Gree_8h.html#ac9f85ef5c1bfeac1e4c759742e2d147f',1,'ir_Gree.h']]], + ['kgreeswingmiddledown_1559',['kGreeSwingMiddleDown',['../ir__Gree_8h.html#acad74b8154d73786e093fa215ab800b0',1,'ir_Gree.h']]], + ['kgreeswingmiddleup_1560',['kGreeSwingMiddleUp',['../ir__Gree_8h.html#aefbdd203df5b35eb61be1d0edd712c80',1,'ir_Gree.h']]], + ['kgreeswingsize_1561',['kGreeSwingSize',['../ir__Gree_8h.html#a287e3c06c9a1efbf7091841f2f689968',1,'ir_Gree.h']]], + ['kgreeswingup_1562',['kGreeSwingUp',['../ir__Gree_8h.html#adad431eb1010951fcf77dc4dac6449c6',1,'ir_Gree.h']]], + ['kgreeswingupauto_1563',['kGreeSwingUpAuto',['../ir__Gree_8h.html#a63f04add215785d4ccfe6ccec03d7667',1,'ir_Gree.h']]], + ['kgreetempextradegreefoffset_1564',['kGreeTempExtraDegreeFOffset',['../ir__Gree_8h.html#abbbca05f6971b4bc2d83d4e5bd79854c',1,'ir_Gree.h']]], + ['kgreetempoffset_1565',['kGreeTempOffset',['../ir__Gree_8h.html#a838def81d0f1253e7371fa237f5f0a34',1,'ir_Gree.h']]], + ['kgreetempsize_1566',['kGreeTempSize',['../ir__Gree_8h.html#a15e8555687b1e6bfc47cd4ee4079b700',1,'ir_Gree.h']]], + ['kgreetimerenabledoffset_1567',['kGreeTimerEnabledOffset',['../ir__Gree_8h.html#aec18110852ca714f58734749ef8d4e7d',1,'ir_Gree.h']]], + ['kgreetimerhalfhroffset_1568',['kGreeTimerHalfHrOffset',['../ir__Gree_8h.html#af0779698759e0b6b41bd1f0b77fbddea',1,'ir_Gree.h']]], + ['kgreetimerhoursoffset_1569',['kGreeTimerHoursOffset',['../ir__Gree_8h.html#a1aeba4b3c5bff86b541291ea29220a60',1,'ir_Gree.h']]], + ['kgreetimerhourssize_1570',['kGreeTimerHoursSize',['../ir__Gree_8h.html#af08673b8c795a0c9a710825ceacd6bdb',1,'ir_Gree.h']]], + ['kgreetimermax_1571',['kGreeTimerMax',['../ir__Gree_8h.html#a76048e03908dd0d22cc8cacfbd99a40b',1,'ir_Gree.h']]], + ['kgreetimertenshroffset_1572',['kGreeTimerTensHrOffset',['../ir__Gree_8h.html#a5ca305d48fde5b5c6792c7734b31b941',1,'ir_Gree.h']]], + ['kgreetimertenshrsize_1573',['kGreeTimerTensHrSize',['../ir__Gree_8h.html#a5d8b007e38dcec0327ed0e38705f05c0',1,'ir_Gree.h']]], + ['kgreeturbooffset_1574',['kGreeTurboOffset',['../ir__Gree_8h.html#a5fe9afa8e66edd95a94404abe00dd1f1',1,'ir_Gree.h']]], + ['kgreeusefahrenheitoffset_1575',['kGreeUseFahrenheitOffset',['../ir__Gree_8h.html#a741c43d31a99fd8b723315d9db0724cc',1,'ir_Gree.h']]], + ['kgreewifioffset_1576',['kGreeWiFiOffset',['../ir__Gree_8h.html#a993dede6398a2c4ec2c1e025f4746768',1,'ir_Gree.h']]], + ['kgreexfanoffset_1577',['kGreeXfanOffset',['../ir__Gree_8h.html#a2388c44b2826823349d02dec581da584',1,'ir_Gree.h']]], + ['kgreezerospace_1578',['kGreeZeroSpace',['../ir__Gree_8cpp.html#aa4694ba8ff0e14cd6b9c4730675c385f',1,'ir_Gree.cpp']]], + ['khaieracauto_1579',['kHaierAcAuto',['../ir__Haier_8h.html#ac33a02f63ee77e0d3050598511730865',1,'ir_Haier.h']]], + ['khaieracbitmark_1580',['kHaierAcBitMark',['../ir__Haier_8cpp.html#a4dec38325834c873c03588a8046f0963',1,'ir_Haier.cpp']]], + ['khaieracbits_1581',['kHaierACBits',['../IRremoteESP8266_8h.html#ad44cfa0951c24d1f0c67b2fba997f720',1,'IRremoteESP8266.h']]], + ['khaieraccmdfan_1582',['kHaierAcCmdFan',['../ir__Haier_8h.html#a447818ec7970e2ca09540afe44ecf90d',1,'ir_Haier.h']]], + ['khaieraccmdhealth_1583',['kHaierAcCmdHealth',['../ir__Haier_8h.html#a83cd0b5f307d9ae3ed0a3c6ed8fef94d',1,'ir_Haier.h']]], + ['khaieraccmdmode_1584',['kHaierAcCmdMode',['../ir__Haier_8h.html#a4543aa4ee28323bb9cb5c077f9bf9da1',1,'ir_Haier.h']]], + ['khaieraccmdoff_1585',['kHaierAcCmdOff',['../ir__Haier_8h.html#a96599917176ee244874926d1a530dd7e',1,'ir_Haier.h']]], + ['khaieraccmdon_1586',['kHaierAcCmdOn',['../ir__Haier_8h.html#a83973c2ad2b7b95611c81628c387e0d8',1,'ir_Haier.h']]], + ['khaieraccmdsleep_1587',['kHaierAcCmdSleep',['../ir__Haier_8h.html#abe52b62dd513395f2a8c7d47fa2fc514',1,'ir_Haier.h']]], + ['khaieraccmdswing_1588',['kHaierAcCmdSwing',['../ir__Haier_8h.html#afab164c2aabf39fdc1e956ff88af19d9',1,'ir_Haier.h']]], + ['khaieraccmdtempdown_1589',['kHaierAcCmdTempDown',['../ir__Haier_8h.html#aecc31139b4e45a7784669554c6fdbb54',1,'ir_Haier.h']]], + ['khaieraccmdtempup_1590',['kHaierAcCmdTempUp',['../ir__Haier_8h.html#aab5363f07920971c31d6acf8e70d392c',1,'ir_Haier.h']]], + ['khaieraccmdtimercancel_1591',['kHaierAcCmdTimerCancel',['../ir__Haier_8h.html#ab780da80fc471f004c5b34dc8f347d00',1,'ir_Haier.h']]], + ['khaieraccmdtimerset_1592',['kHaierAcCmdTimerSet',['../ir__Haier_8h.html#a9bd7c081d460a4ae5e3eac977f3916e4',1,'ir_Haier.h']]], + ['khaieraccool_1593',['kHaierAcCool',['../ir__Haier_8h.html#a83cd81ea1115f42a403ea5ee07a32bbb',1,'ir_Haier.h']]], + ['khaieracdefaultrepeat_1594',['kHaierAcDefaultRepeat',['../IRremoteESP8266_8h.html#a882914932449e33933b6f8e224cbaf3c',1,'IRremoteESP8266.h']]], + ['khaieracdeftemp_1595',['kHaierAcDefTemp',['../ir__Haier_8h.html#a86c9e8176fc01e52e883cadcc1d31763',1,'ir_Haier.h']]], + ['khaieracdry_1596',['kHaierAcDry',['../ir__Haier_8h.html#a3d36fbe1308221248f45044e5a671636',1,'ir_Haier.h']]], + ['khaieracfan_1597',['kHaierAcFan',['../ir__Haier_8h.html#af4049629b2139ca82471dfed1e1ced15',1,'ir_Haier.h']]], + ['khaieracfanauto_1598',['kHaierAcFanAuto',['../ir__Haier_8h.html#a8a34e74f7083caa98ed4afc31294539e',1,'ir_Haier.h']]], + ['khaieracfanhigh_1599',['kHaierAcFanHigh',['../ir__Haier_8h.html#aa4d9e45ca5777707778ef78a3284da19',1,'ir_Haier.h']]], + ['khaieracfanlow_1600',['kHaierAcFanLow',['../ir__Haier_8h.html#ae31e878b09284a6730a11e2017cfd7a8',1,'ir_Haier.h']]], + ['khaieracfanmed_1601',['kHaierAcFanMed',['../ir__Haier_8h.html#a5dfa833768e549964aa0bf8a336c32b0',1,'ir_Haier.h']]], + ['khaierachdr_1602',['kHaierAcHdr',['../ir__Haier_8cpp.html#a0f5dbd2eb92f10bc354e6b0a7a074084',1,'ir_Haier.cpp']]], + ['khaierachdrgap_1603',['kHaierAcHdrGap',['../ir__Haier_8cpp.html#a4c3fe62f8e5abf5d084009bbd4c4f878',1,'ir_Haier.cpp']]], + ['khaierachealthbitoffset_1604',['kHaierAcHealthBitOffset',['../ir__Haier_8h.html#ae2e5e80f891c9bbca2844d808b0b3d1b',1,'ir_Haier.h']]], + ['khaieracheat_1605',['kHaierAcHeat',['../ir__Haier_8h.html#a0edb011bdf85197e63a32d37f8517dd2',1,'ir_Haier.h']]], + ['khaierachourssize_1606',['kHaierAcHoursSize',['../ir__Haier_8h.html#a3db7b7dddae84a5d12101c5cdd06975e',1,'ir_Haier.h']]], + ['khaieracmaxtemp_1607',['kHaierAcMaxTemp',['../ir__Haier_8h.html#a925252489fe34d9932151817d0dbe90b',1,'ir_Haier.h']]], + ['khaieracmaxtime_1608',['kHaierAcMaxTime',['../ir__Haier_8h.html#ae04e48e926a7533c3b62f0ff991e1f88',1,'ir_Haier.h']]], + ['khaieracmingap_1609',['kHaierAcMinGap',['../ir__Haier_8cpp.html#a7ab1f44876a931da765b52e4633e5e82',1,'ir_Haier.cpp']]], + ['khaieracminssize_1610',['kHaierAcMinsSize',['../ir__Haier_8h.html#a105e047084515305e896d8ff776d05e6',1,'ir_Haier.h']]], + ['khaieracmintemp_1611',['kHaierAcMinTemp',['../ir__Haier_8h.html#aafd2a4f38ecf78482a5a94e9c6c23f1c',1,'ir_Haier.h']]], + ['khaieracmodeoffset_1612',['kHaierAcModeOffset',['../ir__Haier_8h.html#a93fdbb1742923cf3f738c8078d5660f8',1,'ir_Haier.h']]], + ['khaieracofftimeroffset_1613',['kHaierAcOffTimerOffset',['../ir__Haier_8h.html#ace8cd6ed41c3f247ada91052d653b515',1,'ir_Haier.h']]], + ['khaieraconespace_1614',['kHaierAcOneSpace',['../ir__Haier_8cpp.html#a43739aa786e08fca2a4a62a680b5c38b',1,'ir_Haier.cpp']]], + ['khaieracontimeroffset_1615',['kHaierAcOnTimerOffset',['../ir__Haier_8h.html#a5189092c278fb5c31efd4f539f905da5',1,'ir_Haier.h']]], + ['khaieracprefix_1616',['kHaierAcPrefix',['../ir__Haier_8h.html#a8502c9bea40205e01e6a01b47354272a',1,'ir_Haier.h']]], + ['khaieracsleepbit_1617',['kHaierAcSleepBit',['../ir__Haier_8h.html#ac63b91acdffa55d440b08aee05bda5dc',1,'ir_Haier.h']]], + ['khaieracsleepbitoffset_1618',['kHaierAcSleepBitOffset',['../ir__Haier_8h.html#ad9f4cbfd8e6a5874d661195858156eec',1,'ir_Haier.h']]], + ['khaieracstatelength_1619',['kHaierACStateLength',['../IRremoteESP8266_8h.html#afb4cd0c1a9c689d862e7095f0ab6dbe5',1,'IRremoteESP8266.h']]], + ['khaieracswingchg_1620',['kHaierAcSwingChg',['../ir__Haier_8h.html#af65a92a0b9d29a52ac882d4457e954e8',1,'ir_Haier.h']]], + ['khaieracswingdown_1621',['kHaierAcSwingDown',['../ir__Haier_8h.html#a2cf3a2102c6d4f9aede44efe853ffaa8',1,'ir_Haier.h']]], + ['khaieracswingoff_1622',['kHaierAcSwingOff',['../ir__Haier_8h.html#ac21f78c3cef931154b3fc953bbebc3b4',1,'ir_Haier.h']]], + ['khaieracswingoffset_1623',['kHaierAcSwingOffset',['../ir__Haier_8h.html#a0872af0b2b3f22f6681917b9c81c3bbd',1,'ir_Haier.h']]], + ['khaieracswingsize_1624',['kHaierAcSwingSize',['../ir__Haier_8h.html#ad032725404a02c0e5a93350f20daf6e1',1,'ir_Haier.h']]], + ['khaieracswingup_1625',['kHaierAcSwingUp',['../ir__Haier_8h.html#a4bff8829604ee927dda5cfc54bd6cfe6',1,'ir_Haier.h']]], + ['khaieractimeoffset_1626',['kHaierAcTimeOffset',['../ir__Haier_8h.html#abb7a8ec83d3c0dbbe4d660d6bf627f23',1,'ir_Haier.h']]], + ['khaieracyrw02auto_1627',['kHaierAcYrw02Auto',['../ir__Haier_8h.html#aa025eeba1c344c50cc98334c97a3c174',1,'ir_Haier.h']]], + ['khaieracyrw02bits_1628',['kHaierACYRW02Bits',['../IRremoteESP8266_8h.html#aab346c5ad482113978e5a2cbb7a06f27',1,'IRremoteESP8266.h']]], + ['khaieracyrw02buttonfan_1629',['kHaierAcYrw02ButtonFan',['../ir__Haier_8h.html#a0f9c265510e1e27f38817f08ef9c622b',1,'ir_Haier.h']]], + ['khaieracyrw02buttonhealth_1630',['kHaierAcYrw02ButtonHealth',['../ir__Haier_8h.html#ab1dc6c0a4ed59446bb69c4dd671c78cd',1,'ir_Haier.h']]], + ['khaieracyrw02buttonmode_1631',['kHaierAcYrw02ButtonMode',['../ir__Haier_8h.html#a74466c50b450b08407c9f226a5d657e5',1,'ir_Haier.h']]], + ['khaieracyrw02buttonpower_1632',['kHaierAcYrw02ButtonPower',['../ir__Haier_8h.html#af36b9c628a697f6c596052ecd143d80b',1,'ir_Haier.h']]], + ['khaieracyrw02buttonsleep_1633',['kHaierAcYrw02ButtonSleep',['../ir__Haier_8h.html#a5c7b8ff351e3d0167ec2c897c4820c40',1,'ir_Haier.h']]], + ['khaieracyrw02buttonswing_1634',['kHaierAcYrw02ButtonSwing',['../ir__Haier_8h.html#aa10c558317448783535e96be5876505c',1,'ir_Haier.h']]], + ['khaieracyrw02buttontempdown_1635',['kHaierAcYrw02ButtonTempDown',['../ir__Haier_8h.html#af4a9e5f7f705c331531ea2863dbbd11d',1,'ir_Haier.h']]], + ['khaieracyrw02buttontempup_1636',['kHaierAcYrw02ButtonTempUp',['../ir__Haier_8h.html#a3b24373f9c812f93eca05ee47e61d6e0',1,'ir_Haier.h']]], + ['khaieracyrw02buttonturbo_1637',['kHaierAcYrw02ButtonTurbo',['../ir__Haier_8h.html#ad80547c526b2eba142297715c0a0636d',1,'ir_Haier.h']]], + ['khaieracyrw02cool_1638',['kHaierAcYrw02Cool',['../ir__Haier_8h.html#a30c5d4e61ae3112a8a3e3622eecbb10b',1,'ir_Haier.h']]], + ['khaieracyrw02defaultrepeat_1639',['kHaierAcYrw02DefaultRepeat',['../IRremoteESP8266_8h.html#a62412e221207dbc2660f93dc265b4218',1,'IRremoteESP8266.h']]], + ['khaieracyrw02dry_1640',['kHaierAcYrw02Dry',['../ir__Haier_8h.html#a66cd902f2d35b4c8f66f085a0950a5fc',1,'ir_Haier.h']]], + ['khaieracyrw02fan_1641',['kHaierAcYrw02Fan',['../ir__Haier_8h.html#a35f50f043a2dda75c59507c1ed845b5d',1,'ir_Haier.h']]], + ['khaieracyrw02fanauto_1642',['kHaierAcYrw02FanAuto',['../ir__Haier_8h.html#ad554d38035ac15e4ea8b855802886989',1,'ir_Haier.h']]], + ['khaieracyrw02fanhigh_1643',['kHaierAcYrw02FanHigh',['../ir__Haier_8h.html#ab47bc48ac77fbf6734a41d10f0a53e4a',1,'ir_Haier.h']]], + ['khaieracyrw02fanlow_1644',['kHaierAcYrw02FanLow',['../ir__Haier_8h.html#a9a0a14ab98e1e52b60b9b9bf611c20cc',1,'ir_Haier.h']]], + ['khaieracyrw02fanmed_1645',['kHaierAcYrw02FanMed',['../ir__Haier_8h.html#a65583649324c6039112e7db26d685afc',1,'ir_Haier.h']]], + ['khaieracyrw02fanoffset_1646',['kHaierAcYrw02FanOffset',['../ir__Haier_8h.html#a0910d1996a451c98383124a39ef65f84',1,'ir_Haier.h']]], + ['khaieracyrw02fansize_1647',['kHaierAcYrw02FanSize',['../ir__Haier_8h.html#aa2c6bd47b47e0ea1b51931fec7daef4d',1,'ir_Haier.h']]], + ['khaieracyrw02healthoffset_1648',['kHaierAcYrw02HealthOffset',['../ir__Haier_8h.html#a4bcb42b359472cf770e0710b5369493b',1,'ir_Haier.h']]], + ['khaieracyrw02heat_1649',['kHaierAcYrw02Heat',['../ir__Haier_8h.html#aa0873975b6649294a3c9943130cb7a38',1,'ir_Haier.h']]], + ['khaieracyrw02modeoffset_1650',['kHaierAcYrw02ModeOffset',['../ir__Haier_8h.html#a027199b609d29ead8aec9bb89178cb30',1,'ir_Haier.h']]], + ['khaieracyrw02power_1651',['kHaierAcYrw02Power',['../ir__Haier_8h.html#abe59df7abf20a66107516054f3a2d32b',1,'ir_Haier.h']]], + ['khaieracyrw02poweroffset_1652',['kHaierAcYrw02PowerOffset',['../ir__Haier_8h.html#a67401152b0aa06fb7922bbca743cd600',1,'ir_Haier.h']]], + ['khaieracyrw02prefix_1653',['kHaierAcYrw02Prefix',['../ir__Haier_8h.html#ac62d0f7ca94e064712f8a7a80da2f11e',1,'ir_Haier.h']]], + ['khaieracyrw02sleep_1654',['kHaierAcYrw02Sleep',['../ir__Haier_8h.html#abb70fe8ca6004246345df3d841047252',1,'ir_Haier.h']]], + ['khaieracyrw02sleepoffset_1655',['kHaierAcYrw02SleepOffset',['../ir__Haier_8h.html#ac651bfee5d261124700c81ec5db184a7',1,'ir_Haier.h']]], + ['khaieracyrw02statelength_1656',['kHaierACYRW02StateLength',['../IRremoteESP8266_8h.html#a8f52b7d4595c117cf0b81ffbd1148cda',1,'IRremoteESP8266.h']]], + ['khaieracyrw02swingauto_1657',['kHaierAcYrw02SwingAuto',['../ir__Haier_8h.html#a95ae88223d910d4d966949241bccff8d',1,'ir_Haier.h']]], + ['khaieracyrw02swingbottom_1658',['kHaierAcYrw02SwingBottom',['../ir__Haier_8h.html#aa4b64385da5e9b2a89e15f70cd8c89e9',1,'ir_Haier.h']]], + ['khaieracyrw02swingdown_1659',['kHaierAcYrw02SwingDown',['../ir__Haier_8h.html#aab380411ac07b2b7f67956a5bbc362fb',1,'ir_Haier.h']]], + ['khaieracyrw02swingmiddle_1660',['kHaierAcYrw02SwingMiddle',['../ir__Haier_8h.html#a32d6dd98a050711bf928bf250b769839',1,'ir_Haier.h']]], + ['khaieracyrw02swingoff_1661',['kHaierAcYrw02SwingOff',['../ir__Haier_8h.html#a62570c15418cf24a94c92b162967f892',1,'ir_Haier.h']]], + ['khaieracyrw02swingtop_1662',['kHaierAcYrw02SwingTop',['../ir__Haier_8h.html#adf10f1bc1b293c684232cb6398631f70',1,'ir_Haier.h']]], + ['khaieracyrw02turbohigh_1663',['kHaierAcYrw02TurboHigh',['../ir__Haier_8h.html#ab096c15c69f242b99fbc1e4d7bd7548e',1,'ir_Haier.h']]], + ['khaieracyrw02turbolow_1664',['kHaierAcYrw02TurboLow',['../ir__Haier_8h.html#a19b7f4aee8115eb77267c415d8b3bd82',1,'ir_Haier.h']]], + ['khaieracyrw02turbooff_1665',['kHaierAcYrw02TurboOff',['../ir__Haier_8h.html#aa06ba46287b5806a6373e921cee34a51',1,'ir_Haier.h']]], + ['khaieracyrw02turbooffset_1666',['kHaierAcYrw02TurboOffset',['../ir__Haier_8h.html#a6581fc8ec43b9ac9f877bf27231554bd',1,'ir_Haier.h']]], + ['khaieracyrw02turbosize_1667',['kHaierAcYrw02TurboSize',['../ir__Haier_8h.html#a6ad469ec094d8af5a68cc94a744079bb',1,'ir_Haier.h']]], + ['khaieraczerospace_1668',['kHaierAcZeroSpace',['../ir__Haier_8cpp.html#af2b1a4f27c7b50a1e60ae00bbbec7a16',1,'ir_Haier.cpp']]], + ['kheader_1669',['kHeader',['../IRrecv_8h.html#a0eac186845b9b998a252a3bdfa72e8ed',1,'IRrecv.h']]], + ['khealthstr_1670',['kHealthStr',['../IRtext_8cpp.html#a12474bbd4a7f700c922bcc1de240894f',1,'kHealthStr(): IRtext.cpp'],['../IRtext_8h.html#a7ef833cf90df2c97ef46c5c4b6225a42',1,'kHealthStr(): IRtext.cpp']]], + ['kheat_1671',['kHeat',['../namespacestdAc.html#a99ad268c783486f9b3207cb78f48444faece059b52386d38cd6da9729cca08b4e',1,'stdAc']]], + ['kheatstr_1672',['kHeatStr',['../IRtext_8cpp.html#a3a16f1dabca01c8f8e5ba1516408ba39',1,'kHeatStr(): IRtext.cpp'],['../IRtext_8h.html#a058df7d2db245e307719d025352d464d',1,'kHeatStr(): IRtext.cpp']]], + ['khigh_1673',['kHigh',['../namespacestdAc.html#a8bb0dbf18fe69f639f4ac0b3ff133383aa022f15e910eb36278094efb6e808a07',1,'stdAc::kHigh()'],['../namespacestdAc.html#ac07f224c7bb47cac55dd01f24770ef43aa022f15e910eb36278094efb6e808a07',1,'stdAc::kHigh()']]], + ['khighest_1674',['kHighest',['../namespacestdAc.html#ac07f224c7bb47cac55dd01f24770ef43a24d8e31603e486f788826bc24e3a2e1d',1,'stdAc']]], + ['khigheststr_1675',['kHighestStr',['../IRtext_8cpp.html#a219f1d54c5ea75bd5c736efc0d7d7275',1,'kHighestStr(): IRtext.cpp'],['../IRtext_8h.html#ad7706307f507466526b4288e33385bde',1,'kHighestStr(): IRtext.cpp']]], + ['khighnibble_1676',['kHighNibble',['../IRutils_8h.html#a26dd96e82207f707c21e696a60b9c032',1,'IRutils.h']]], + ['khighstr_1677',['kHighStr',['../IRtext_8cpp.html#a127a20ad54e671f48a8faa822ff006f4',1,'kHighStr(): IRtext.cpp'],['../IRtext_8h.html#a5b4ade5e08f30c5e9a61c813bb2046f1',1,'kHighStr(): IRtext.cpp']]], + ['khistr_1678',['kHiStr',['../IRtext_8cpp.html#a7f4994ce51aed70ce6b5b4c88b886466',1,'kHiStr(): IRtext.cpp'],['../IRtext_8h.html#aa6fe661cdd9e2f1dc30d6fee2980cadd',1,'kHiStr(): IRtext.cpp']]], + ['khitachiac1auto_1679',['kHitachiAc1Auto',['../ir__Hitachi_8h.html#a2689ef34702107dc3dce3d1cfa260fc9',1,'ir_Hitachi.h']]], + ['khitachiac1bits_1680',['kHitachiAc1Bits',['../IRremoteESP8266_8h.html#aae6947c431d2c9da4fe2fdd9428012c1',1,'IRremoteESP8266.h']]], + ['khitachiac1checksumstartbyte_1681',['kHitachiAc1ChecksumStartByte',['../ir__Hitachi_8h.html#afafa689c5e922b812f63e08941feb2a7',1,'ir_Hitachi.h']]], + ['khitachiac1cool_1682',['kHitachiAc1Cool',['../ir__Hitachi_8h.html#a1146eda7688843d16094acf7a19a75ac',1,'ir_Hitachi.h']]], + ['khitachiac1dry_1683',['kHitachiAc1Dry',['../ir__Hitachi_8h.html#a82895db5201610844da803bf333102a3',1,'ir_Hitachi.h']]], + ['khitachiac1fan_1684',['kHitachiAc1Fan',['../ir__Hitachi_8h.html#ac5a3ba0e0e4ed02d4792d5a8e6a22654',1,'ir_Hitachi.h']]], + ['khitachiac1fanauto_1685',['kHitachiAc1FanAuto',['../ir__Hitachi_8h.html#a6f9adda7b08ec4b8566ceb4d79966689',1,'ir_Hitachi.h']]], + ['khitachiac1fanbyte_1686',['kHitachiAc1FanByte',['../ir__Hitachi_8h.html#afe6b5951ba3b4e7ad5400f30228d106e',1,'ir_Hitachi.h']]], + ['khitachiac1fanhigh_1687',['kHitachiAc1FanHigh',['../ir__Hitachi_8h.html#ace677cf030da9d74eda0f50d54c91411',1,'ir_Hitachi.h']]], + ['khitachiac1fanlow_1688',['kHitachiAc1FanLow',['../ir__Hitachi_8h.html#a011219de5c0e2ba043a8be6345f8cb05',1,'ir_Hitachi.h']]], + ['khitachiac1fanmed_1689',['kHitachiAc1FanMed',['../ir__Hitachi_8h.html#afbc2a535d85adb80cbcbac63e2432b1a',1,'ir_Hitachi.h']]], + ['khitachiac1fanoffset_1690',['kHitachiAc1FanOffset',['../ir__Hitachi_8h.html#af533c283666d80c0b9348f706909f4c4',1,'ir_Hitachi.h']]], + ['khitachiac1fansize_1691',['kHitachiAc1FanSize',['../ir__Hitachi_8h.html#a2b2a24680efaf1eeaf76dacaabef5c1d',1,'ir_Hitachi.h']]], + ['khitachiac1hdrmark_1692',['kHitachiAc1HdrMark',['../ir__Hitachi_8cpp.html#a2b1891174c78be6f960e92b389d25fe7',1,'ir_Hitachi.cpp']]], + ['khitachiac1hdrspace_1693',['kHitachiAc1HdrSpace',['../ir__Hitachi_8cpp.html#a93f34ee53a375dd7f4ccf82458453701',1,'ir_Hitachi.cpp']]], + ['khitachiac1heat_1694',['kHitachiAc1Heat',['../ir__Hitachi_8h.html#abd5d4db30d6be3b990a74d4481e7eabe',1,'ir_Hitachi.h']]], + ['khitachiac1modebyte_1695',['kHitachiAc1ModeByte',['../ir__Hitachi_8h.html#a57e27b66ff6d471c0dd335b610bc6e24',1,'ir_Hitachi.h']]], + ['khitachiac1model_5fa_1696',['kHitachiAc1Model_A',['../ir__Hitachi_8h.html#a5f8fc3bb000d46705e4530ca0a8f7b60',1,'ir_Hitachi.h']]], + ['khitachiac1model_5fb_1697',['kHitachiAc1Model_B',['../ir__Hitachi_8h.html#a2d894a528c538b8a3922e2500241a55b',1,'ir_Hitachi.h']]], + ['khitachiac1modelbyte_1698',['kHitachiAc1ModelByte',['../ir__Hitachi_8h.html#a2e2a76b8b7decef99cfb7b197e8fb7f7',1,'ir_Hitachi.h']]], + ['khitachiac1modeloffset_1699',['kHitachiAc1ModelOffset',['../ir__Hitachi_8h.html#a8a440a64e6e164511e0976dc5b6585ff',1,'ir_Hitachi.h']]], + ['khitachiac1modelsize_1700',['kHitachiAc1ModelSize',['../ir__Hitachi_8h.html#ab74bbcb475b7eaf33f70dbfdb853d8c3',1,'ir_Hitachi.h']]], + ['khitachiac1modeoffset_1701',['kHitachiAc1ModeOffset',['../ir__Hitachi_8h.html#a3f010fa5ae43ee36771be18659d8bc80',1,'ir_Hitachi.h']]], + ['khitachiac1modesize_1702',['kHitachiAc1ModeSize',['../ir__Hitachi_8h.html#a38b456d96602e83e7832e2a7af75f321',1,'ir_Hitachi.h']]], + ['khitachiac1offtimerhighbyte_1703',['kHitachiAc1OffTimerHighByte',['../ir__Hitachi_8h.html#a36e6b7fc328ee247c11f5779487119b6',1,'ir_Hitachi.h']]], + ['khitachiac1offtimerlowbyte_1704',['kHitachiAc1OffTimerLowByte',['../ir__Hitachi_8h.html#ac8eaedd191009b2ddaf1e047ac6ecf11',1,'ir_Hitachi.h']]], + ['khitachiac1ontimerhighbyte_1705',['kHitachiAc1OnTimerHighByte',['../ir__Hitachi_8h.html#aff6907e9999561abceac42e4cce1dc3b',1,'ir_Hitachi.h']]], + ['khitachiac1ontimerlowbyte_1706',['kHitachiAc1OnTimerLowByte',['../ir__Hitachi_8h.html#a95fef3be6809026b714847c709ba655b',1,'ir_Hitachi.h']]], + ['khitachiac1powerbyte_1707',['kHitachiAc1PowerByte',['../ir__Hitachi_8h.html#acda489ff6137ab3ebfb1795a32e1ec8e',1,'ir_Hitachi.h']]], + ['khitachiac1poweroffset_1708',['kHitachiAc1PowerOffset',['../ir__Hitachi_8h.html#a3fdcd0375b85ac2641d9d5cc6e4770f8',1,'ir_Hitachi.h']]], + ['khitachiac1powertoggleoffset_1709',['kHitachiAc1PowerToggleOffset',['../ir__Hitachi_8h.html#aac994777ce070ad69550229824800ee0',1,'ir_Hitachi.h']]], + ['khitachiac1sleep1_1710',['kHitachiAc1Sleep1',['../ir__Hitachi_8h.html#ab4ca89a9d8c8034e6a3d8ff17b09f3d5',1,'ir_Hitachi.h']]], + ['khitachiac1sleep2_1711',['kHitachiAc1Sleep2',['../ir__Hitachi_8h.html#a1e1a1ea1743b38da6bc6be63fa796689',1,'ir_Hitachi.h']]], + ['khitachiac1sleep3_1712',['kHitachiAc1Sleep3',['../ir__Hitachi_8h.html#a17eaa63f13a3c04aede9f485c310a930',1,'ir_Hitachi.h']]], + ['khitachiac1sleep4_1713',['kHitachiAc1Sleep4',['../ir__Hitachi_8h.html#a21360448a538fbd9491aa9dd28e6c545',1,'ir_Hitachi.h']]], + ['khitachiac1sleepbyte_1714',['kHitachiAc1SleepByte',['../ir__Hitachi_8h.html#ac693a15878e7cdc8e1f575502ea82843',1,'ir_Hitachi.h']]], + ['khitachiac1sleepoff_1715',['kHitachiAc1SleepOff',['../ir__Hitachi_8h.html#a96f87cb3838a1e1aab4b8407dcfc5b78',1,'ir_Hitachi.h']]], + ['khitachiac1sleepoffset_1716',['kHitachiAc1SleepOffset',['../ir__Hitachi_8h.html#a277ca55dbfd35258ea40059bdff62488',1,'ir_Hitachi.h']]], + ['khitachiac1sleepsize_1717',['kHitachiAc1SleepSize',['../ir__Hitachi_8h.html#a199cedd7120057f735ffc640f93a9a1a',1,'ir_Hitachi.h']]], + ['khitachiac1statelength_1718',['kHitachiAc1StateLength',['../IRremoteESP8266_8h.html#abb5e2ddb1a8d3c6fa7a94dbe1989ec5d',1,'IRremoteESP8266.h']]], + ['khitachiac1swingbyte_1719',['kHitachiAc1SwingByte',['../ir__Hitachi_8h.html#a5a283583007b26c1b45d8d7afcd55408',1,'ir_Hitachi.h']]], + ['khitachiac1swinghoffset_1720',['kHitachiAc1SwingHOffset',['../ir__Hitachi_8h.html#ab35d4bb6c17fc5bbcb5385a642476238',1,'ir_Hitachi.h']]], + ['khitachiac1swingtoggleoffset_1721',['kHitachiAc1SwingToggleOffset',['../ir__Hitachi_8h.html#a08eac3b64687e83229648c8664d75dc4',1,'ir_Hitachi.h']]], + ['khitachiac1swingvoffset_1722',['kHitachiAc1SwingVOffset',['../ir__Hitachi_8h.html#af4e410f10812d49175cd419ed678535b',1,'ir_Hitachi.h']]], + ['khitachiac1tempauto_1723',['kHitachiAc1TempAuto',['../ir__Hitachi_8h.html#ad402dff999a97b50b392572899522b6a',1,'ir_Hitachi.h']]], + ['khitachiac1tempbyte_1724',['kHitachiAc1TempByte',['../ir__Hitachi_8h.html#a03185c3b2ddb62d12267da014796da56',1,'ir_Hitachi.h']]], + ['khitachiac1tempdelta_1725',['kHitachiAc1TempDelta',['../ir__Hitachi_8h.html#a279c856a2b4d25651b117a8c654cb48d',1,'ir_Hitachi.h']]], + ['khitachiac1tempoffset_1726',['kHitachiAc1TempOffset',['../ir__Hitachi_8h.html#a8a92aa41be23301229ecec1486714b9a',1,'ir_Hitachi.h']]], + ['khitachiac1tempsize_1727',['kHitachiAc1TempSize',['../ir__Hitachi_8h.html#affb52642edc8f2231f0dc83bc5271885',1,'ir_Hitachi.h']]], + ['khitachiac1timersize_1728',['kHitachiAc1TimerSize',['../ir__Hitachi_8h.html#afd7f469f67f55263b0031b325232751b',1,'ir_Hitachi.h']]], + ['khitachiac2bits_1729',['kHitachiAc2Bits',['../IRremoteESP8266_8h.html#a362a0b0b0afc216cf8162a3724cf073a',1,'IRremoteESP8266.h']]], + ['khitachiac2statelength_1730',['kHitachiAc2StateLength',['../IRremoteESP8266_8h.html#a10377a40053a12e091dbff2869db0352',1,'IRremoteESP8266.h']]], + ['khitachiac344bits_1731',['kHitachiAc344Bits',['../IRremoteESP8266_8h.html#a204fc2410c3d555a37b152a01dceead0',1,'IRremoteESP8266.h']]], + ['khitachiac344buttonfan_1732',['kHitachiAc344ButtonFan',['../ir__Hitachi_8h.html#a5f33b956ec83ee0004785a9c44bd5b0b',1,'ir_Hitachi.h']]], + ['khitachiac344buttonpowermode_1733',['kHitachiAc344ButtonPowerMode',['../ir__Hitachi_8h.html#a3816a8ad86e03f8c5870057e7ad86335',1,'ir_Hitachi.h']]], + ['khitachiac344buttonswingh_1734',['kHitachiAc344ButtonSwingH',['../ir__Hitachi_8h.html#a10dea534868d76d99e91458ee28f5fe9',1,'ir_Hitachi.h']]], + ['khitachiac344buttonswingv_1735',['kHitachiAc344ButtonSwingV',['../ir__Hitachi_8h.html#a95c1b0ee7e3802631f4c2708371e7d34',1,'ir_Hitachi.h']]], + ['khitachiac344buttontempdown_1736',['kHitachiAc344ButtonTempDown',['../ir__Hitachi_8h.html#a05d9bd95037669f1d3743d935471db33',1,'ir_Hitachi.h']]], + ['khitachiac344buttontempup_1737',['kHitachiAc344ButtonTempUp',['../ir__Hitachi_8h.html#a74abf2ce4ed5918bf68f485eff179578',1,'ir_Hitachi.h']]], + ['khitachiac344cool_1738',['kHitachiAc344Cool',['../ir__Hitachi_8h.html#a92d4d8dea34a9387e55852b6b5289328',1,'ir_Hitachi.h']]], + ['khitachiac344dry_1739',['kHitachiAc344Dry',['../ir__Hitachi_8h.html#a37697339ddc2ffaf4ee13b5e140adf2c',1,'ir_Hitachi.h']]], + ['khitachiac344fan_1740',['kHitachiAc344Fan',['../ir__Hitachi_8h.html#a296cd0fc1f414a4e15ce228b5a794bcb',1,'ir_Hitachi.h']]], + ['khitachiac344fanauto_1741',['kHitachiAc344FanAuto',['../ir__Hitachi_8h.html#a6439744edb1ae4dd9e8ea2097fac7a9d',1,'ir_Hitachi.h']]], + ['khitachiac344fanhigh_1742',['kHitachiAc344FanHigh',['../ir__Hitachi_8h.html#a83ea1924948ce9ac8266ab64a41f3ebd',1,'ir_Hitachi.h']]], + ['khitachiac344fanlow_1743',['kHitachiAc344FanLow',['../ir__Hitachi_8h.html#acbbb61fde653c84a8e35865fa724872c',1,'ir_Hitachi.h']]], + ['khitachiac344fanmax_1744',['kHitachiAc344FanMax',['../ir__Hitachi_8h.html#af041ed41027b8e444e3069d9a3481c51',1,'ir_Hitachi.h']]], + ['khitachiac344fanmedium_1745',['kHitachiAc344FanMedium',['../ir__Hitachi_8h.html#aa6d47b5c28f758aa297b345cbf853c9a',1,'ir_Hitachi.h']]], + ['khitachiac344fanmin_1746',['kHitachiAc344FanMin',['../ir__Hitachi_8h.html#ac4bafed10c76739698e9a35183beb970',1,'ir_Hitachi.h']]], + ['khitachiac344heat_1747',['kHitachiAc344Heat',['../ir__Hitachi_8h.html#a6c4102910d21dc838efee1fb2477218d',1,'ir_Hitachi.h']]], + ['khitachiac344maxtemp_1748',['kHitachiAc344MaxTemp',['../ir__Hitachi_8h.html#a4a394fc23fb119ba67e3ca53e4b88f7f',1,'ir_Hitachi.h']]], + ['khitachiac344mintemp_1749',['kHitachiAc344MinTemp',['../ir__Hitachi_8h.html#a7322f7769c9c1af2311180474e5b0f57',1,'ir_Hitachi.h']]], + ['khitachiac344statelength_1750',['kHitachiAc344StateLength',['../IRremoteESP8266_8h.html#a2192f6b7c353f7f124dff3b57eab0659',1,'IRremoteESP8266.h']]], + ['khitachiac344swinghauto_1751',['kHitachiAc344SwingHAuto',['../ir__Hitachi_8h.html#a4f93eccee6e3e5f5c49c84034ca25af3',1,'ir_Hitachi.h']]], + ['khitachiac344swinghbyte_1752',['kHitachiAc344SwingHByte',['../ir__Hitachi_8h.html#a132b64e007043ade4f209b0416fd5f4d',1,'ir_Hitachi.h']]], + ['khitachiac344swinghleft_1753',['kHitachiAc344SwingHLeft',['../ir__Hitachi_8h.html#af714a1eb296b05f3fc8167aff5419764',1,'ir_Hitachi.h']]], + ['khitachiac344swinghleftmax_1754',['kHitachiAc344SwingHLeftMax',['../ir__Hitachi_8h.html#ad0c5636ac0ccfd7e9cd087101bd5d204',1,'ir_Hitachi.h']]], + ['khitachiac344swinghmiddle_1755',['kHitachiAc344SwingHMiddle',['../ir__Hitachi_8h.html#a7e4372e02d72723049b378e955070c21',1,'ir_Hitachi.h']]], + ['khitachiac344swinghoffset_1756',['kHitachiAc344SwingHOffset',['../ir__Hitachi_8h.html#a7e8e57b0b37f20a502eb66f13980989c',1,'ir_Hitachi.h']]], + ['khitachiac344swinghright_1757',['kHitachiAc344SwingHRight',['../ir__Hitachi_8h.html#af4b087dec06cfd86920dbf9df22aca63',1,'ir_Hitachi.h']]], + ['khitachiac344swinghrightmax_1758',['kHitachiAc344SwingHRightMax',['../ir__Hitachi_8h.html#a90cffc131be89a36d352c462403f689f',1,'ir_Hitachi.h']]], + ['khitachiac344swinghsize_1759',['kHitachiAc344SwingHSize',['../ir__Hitachi_8h.html#aadd389cd818207920c1e8efef53fde91',1,'ir_Hitachi.h']]], + ['khitachiac344swingvbyte_1760',['kHitachiAc344SwingVByte',['../ir__Hitachi_8h.html#ae40211be39e522ebf9b580b3481f49f3',1,'ir_Hitachi.h']]], + ['khitachiac344swingvoffset_1761',['kHitachiAc344SwingVOffset',['../ir__Hitachi_8h.html#a8b38ef096697f70bdba8f4bd2799e148',1,'ir_Hitachi.h']]], + ['khitachiac3bitmark_1762',['kHitachiAc3BitMark',['../ir__Hitachi_8cpp.html#a68269a88e02a3030749061e5f28f74cc',1,'ir_Hitachi.cpp']]], + ['khitachiac3bits_1763',['kHitachiAc3Bits',['../IRremoteESP8266_8h.html#ac26b896cdc17018269fa881e10e3aabb',1,'IRremoteESP8266.h']]], + ['khitachiac3hdrmark_1764',['kHitachiAc3HdrMark',['../ir__Hitachi_8cpp.html#af0a80a66094e67b4a78e8dfa539cd22f',1,'ir_Hitachi.cpp']]], + ['khitachiac3hdrspace_1765',['kHitachiAc3HdrSpace',['../ir__Hitachi_8cpp.html#aca4dc0b851c69a5e640337d68eb6f412',1,'ir_Hitachi.cpp']]], + ['khitachiac3minbits_1766',['kHitachiAc3MinBits',['../IRremoteESP8266_8h.html#a66ebaf70d2b4018371825c9cd3078a42',1,'IRremoteESP8266.h']]], + ['khitachiac3minstatelength_1767',['kHitachiAc3MinStateLength',['../IRremoteESP8266_8h.html#ac3becb270bfddaa1c64b1f8582dfc902',1,'IRremoteESP8266.h']]], + ['khitachiac3onespace_1768',['kHitachiAc3OneSpace',['../ir__Hitachi_8cpp.html#a0e630e38b4bffd5ec931153c20e41d97',1,'ir_Hitachi.cpp']]], + ['khitachiac3statelength_1769',['kHitachiAc3StateLength',['../IRremoteESP8266_8h.html#a9cc230bac4f902d46049c7b2c2fdbd3d',1,'IRremoteESP8266.h']]], + ['khitachiac3zerospace_1770',['kHitachiAc3ZeroSpace',['../ir__Hitachi_8cpp.html#a7cf96a2734bcc9a5eb390b8647666925',1,'ir_Hitachi.cpp']]], + ['khitachiac424bitmark_1771',['kHitachiAc424BitMark',['../ir__Hitachi_8cpp.html#acf5f9d83873a74688eb0413708e26eed',1,'ir_Hitachi.cpp']]], + ['khitachiac424bits_1772',['kHitachiAc424Bits',['../IRremoteESP8266_8h.html#ab466e28528a0d688a1b91e8af69025cb',1,'IRremoteESP8266.h']]], + ['khitachiac424buttonbyte_1773',['kHitachiAc424ButtonByte',['../ir__Hitachi_8h.html#a057159edca95f9a000c80c7059919e83',1,'ir_Hitachi.h']]], + ['khitachiac424buttonfan_1774',['kHitachiAc424ButtonFan',['../ir__Hitachi_8h.html#a4aa278fb1983213a2506c71debe035aa',1,'ir_Hitachi.h']]], + ['khitachiac424buttonpowermode_1775',['kHitachiAc424ButtonPowerMode',['../ir__Hitachi_8h.html#a2dd37a36c6ad928ad0c3485ae4ea78fd',1,'ir_Hitachi.h']]], + ['khitachiac424buttonswingh_1776',['kHitachiAc424ButtonSwingH',['../ir__Hitachi_8h.html#af3a0d9499fab327bc7dfb5d57562a946',1,'ir_Hitachi.h']]], + ['khitachiac424buttonswingv_1777',['kHitachiAc424ButtonSwingV',['../ir__Hitachi_8h.html#a59d8e5407daf37d38e0c76ab3abdec9d',1,'ir_Hitachi.h']]], + ['khitachiac424buttontempdown_1778',['kHitachiAc424ButtonTempDown',['../ir__Hitachi_8h.html#ad909ee0bc97e24aa70ff6ecd1cffe6c2',1,'ir_Hitachi.h']]], + ['khitachiac424buttontempup_1779',['kHitachiAc424ButtonTempUp',['../ir__Hitachi_8h.html#ac8885804fb276f6327beb2018b204359',1,'ir_Hitachi.h']]], + ['khitachiac424cool_1780',['kHitachiAc424Cool',['../ir__Hitachi_8h.html#a64c1e01c222e6dec001a7052e822d64f',1,'ir_Hitachi.h']]], + ['khitachiac424dry_1781',['kHitachiAc424Dry',['../ir__Hitachi_8h.html#a56bfde42914bc92f47929179cddcbdf3',1,'ir_Hitachi.h']]], + ['khitachiac424fan_1782',['kHitachiAc424Fan',['../ir__Hitachi_8h.html#a35db6fdcedeb3de0ffb0bb72f1e60a0b',1,'ir_Hitachi.h']]], + ['khitachiac424fanauto_1783',['kHitachiAc424FanAuto',['../ir__Hitachi_8h.html#add1ec95cfd4e388f90154b25410471d0',1,'ir_Hitachi.h']]], + ['khitachiac424fanbyte_1784',['kHitachiAc424FanByte',['../ir__Hitachi_8h.html#aa4758708fe16d13cf6f50b7aa9e12bf6',1,'ir_Hitachi.h']]], + ['khitachiac424fanhigh_1785',['kHitachiAc424FanHigh',['../ir__Hitachi_8h.html#aacabc41baea6c3ddf711424a400144a3',1,'ir_Hitachi.h']]], + ['khitachiac424fanlow_1786',['kHitachiAc424FanLow',['../ir__Hitachi_8h.html#acae66b060db5cd03732ccbf808c6049e',1,'ir_Hitachi.h']]], + ['khitachiac424fanmax_1787',['kHitachiAc424FanMax',['../ir__Hitachi_8h.html#a6298e6dee6ff9f5fc57cfc9ccf30c073',1,'ir_Hitachi.h']]], + ['khitachiac424fanmaxdry_1788',['kHitachiAc424FanMaxDry',['../ir__Hitachi_8h.html#af770b29d838610b87463551444548ac0',1,'ir_Hitachi.h']]], + ['khitachiac424fanmedium_1789',['kHitachiAc424FanMedium',['../ir__Hitachi_8h.html#a3d6479f2e76bd84eeda9f5c0772210c5',1,'ir_Hitachi.h']]], + ['khitachiac424fanmin_1790',['kHitachiAc424FanMin',['../ir__Hitachi_8h.html#aacf1d4b99d89a0e24622ca02402c683b',1,'ir_Hitachi.h']]], + ['khitachiac424fantemp_1791',['kHitachiAc424FanTemp',['../ir__Hitachi_8h.html#a874362698fad488da1a477c4f99923aa',1,'ir_Hitachi.h']]], + ['khitachiac424hdrmark_1792',['kHitachiAc424HdrMark',['../ir__Hitachi_8cpp.html#a7b1dcaa7569237831b08ea061fd403fb',1,'ir_Hitachi.cpp']]], + ['khitachiac424hdrspace_1793',['kHitachiAc424HdrSpace',['../ir__Hitachi_8cpp.html#a9309b801d147dd3eba96ed15245f7445',1,'ir_Hitachi.cpp']]], + ['khitachiac424heat_1794',['kHitachiAc424Heat',['../ir__Hitachi_8h.html#a5cfd38c9e7aa2c39dfa38b1ef4b33b4c',1,'ir_Hitachi.h']]], + ['khitachiac424ldrmark_1795',['kHitachiAc424LdrMark',['../ir__Hitachi_8cpp.html#a0e2a88cb5930fb9726a453bdefe33bae',1,'ir_Hitachi.cpp']]], + ['khitachiac424ldrspace_1796',['kHitachiAc424LdrSpace',['../ir__Hitachi_8cpp.html#ad6285b55ed74e0e1087c3eb12d63b39c',1,'ir_Hitachi.cpp']]], + ['khitachiac424maxtemp_1797',['kHitachiAc424MaxTemp',['../ir__Hitachi_8h.html#a22574044b5a9163aca1f0581b9fa9241',1,'ir_Hitachi.h']]], + ['khitachiac424mintemp_1798',['kHitachiAc424MinTemp',['../ir__Hitachi_8h.html#a3d4311f1f28bbe31a22b80556e678b22',1,'ir_Hitachi.h']]], + ['khitachiac424modebyte_1799',['kHitachiAc424ModeByte',['../ir__Hitachi_8h.html#a3c6e0d27a95d94142360efa19a342c99',1,'ir_Hitachi.h']]], + ['khitachiac424onespace_1800',['kHitachiAc424OneSpace',['../ir__Hitachi_8cpp.html#a9b9cd22801f17acac593a8bcf334fd71',1,'ir_Hitachi.cpp']]], + ['khitachiac424powerbyte_1801',['kHitachiAc424PowerByte',['../ir__Hitachi_8h.html#a815e6761376ca4eae649ec837d55dc25',1,'ir_Hitachi.h']]], + ['khitachiac424poweroff_1802',['kHitachiAc424PowerOff',['../ir__Hitachi_8h.html#affc2d076cc0de329466ecbde7186d4eb',1,'ir_Hitachi.h']]], + ['khitachiac424poweron_1803',['kHitachiAc424PowerOn',['../ir__Hitachi_8h.html#a922478904efd86c6ecf7dabec3dd759f',1,'ir_Hitachi.h']]], + ['khitachiac424statelength_1804',['kHitachiAc424StateLength',['../IRremoteESP8266_8h.html#aff17d9c0ccf683895d2c868094679f0a',1,'IRremoteESP8266.h']]], + ['khitachiac424tempbyte_1805',['kHitachiAc424TempByte',['../ir__Hitachi_8h.html#a5de1ae606d6a34e24420b08a73542b94',1,'ir_Hitachi.h']]], + ['khitachiac424tempoffset_1806',['kHitachiAc424TempOffset',['../ir__Hitachi_8h.html#a3adb47220c4c72a62d9296092047900f',1,'ir_Hitachi.h']]], + ['khitachiac424tempsize_1807',['kHitachiAc424TempSize',['../ir__Hitachi_8h.html#ae6738f4a4476e5f34efbeb52e8c413de',1,'ir_Hitachi.h']]], + ['khitachiac424zerospace_1808',['kHitachiAc424ZeroSpace',['../ir__Hitachi_8cpp.html#a0f2032ac476bf344df31dc9351b2b98a',1,'ir_Hitachi.cpp']]], + ['khitachiacauto_1809',['kHitachiAcAuto',['../ir__Hitachi_8h.html#af8c74a8388361162b93339e1b0bc94d9',1,'ir_Hitachi.h']]], + ['khitachiacautotemp_1810',['kHitachiAcAutoTemp',['../ir__Hitachi_8h.html#aaa28bb683fefc065cb115fbfb66994ec',1,'ir_Hitachi.h']]], + ['khitachiacbitmark_1811',['kHitachiAcBitMark',['../ir__Hitachi_8cpp.html#a0993bf3d527a12bfe51c7bbfcf788c59',1,'ir_Hitachi.cpp']]], + ['khitachiacbits_1812',['kHitachiAcBits',['../IRremoteESP8266_8h.html#aec91e459b1e52765c700f8f7a4723f3b',1,'IRremoteESP8266.h']]], + ['khitachiaccool_1813',['kHitachiAcCool',['../ir__Hitachi_8h.html#a2b40b07601fdf8b038c97bb8bd2bec59',1,'ir_Hitachi.h']]], + ['khitachiacdefaultrepeat_1814',['kHitachiAcDefaultRepeat',['../IRremoteESP8266_8h.html#acc8510281d2ff9a808501d375c03ba21',1,'IRremoteESP8266.h']]], + ['khitachiacdry_1815',['kHitachiAcDry',['../ir__Hitachi_8h.html#a19730b13fca736392600580c156ae3c3',1,'ir_Hitachi.h']]], + ['khitachiacfan_1816',['kHitachiAcFan',['../ir__Hitachi_8h.html#a69626883b6fdbd3ccd26bb3123bf1883',1,'ir_Hitachi.h']]], + ['khitachiacfanauto_1817',['kHitachiAcFanAuto',['../ir__Hitachi_8h.html#a6be6f6eae193e784133be63d7cc5d75e',1,'ir_Hitachi.h']]], + ['khitachiacfanhigh_1818',['kHitachiAcFanHigh',['../ir__Hitachi_8h.html#a85ef905a1d3704237141f07defc128f5',1,'ir_Hitachi.h']]], + ['khitachiacfanlow_1819',['kHitachiAcFanLow',['../ir__Hitachi_8h.html#a0add8c3a3d00a81fcc3279af78256de2',1,'ir_Hitachi.h']]], + ['khitachiacfanmed_1820',['kHitachiAcFanMed',['../ir__Hitachi_8h.html#ac88b4cfdce5d69bf07316ddd716c2c11',1,'ir_Hitachi.h']]], + ['khitachiacfreq_1821',['kHitachiAcFreq',['../ir__Hitachi_8h.html#a443eaa664017d7b671bef0e9aa2d643b',1,'ir_Hitachi.h']]], + ['khitachiachdrmark_1822',['kHitachiAcHdrMark',['../ir__Hitachi_8cpp.html#aefe34d17f5c72ee05afb9a6302a450da',1,'ir_Hitachi.cpp']]], + ['khitachiachdrspace_1823',['kHitachiAcHdrSpace',['../ir__Hitachi_8cpp.html#a4a4352723f119ea070be1eba2aafe36b',1,'ir_Hitachi.cpp']]], + ['khitachiacheat_1824',['kHitachiAcHeat',['../ir__Hitachi_8h.html#add2498e77e5585fd8c82a553bb0c22c0',1,'ir_Hitachi.h']]], + ['khitachiacmaxtemp_1825',['kHitachiAcMaxTemp',['../ir__Hitachi_8h.html#a63e17171c40d770d25f24d018aee2c4c',1,'ir_Hitachi.h']]], + ['khitachiacmingap_1826',['kHitachiAcMinGap',['../ir__Hitachi_8cpp.html#a14016b9110c11423c628c8e220e50864',1,'ir_Hitachi.cpp']]], + ['khitachiacmintemp_1827',['kHitachiAcMinTemp',['../ir__Hitachi_8h.html#a9b4f3ea50cc0491f10ff8dc8eabb3ecd',1,'ir_Hitachi.h']]], + ['khitachiaconespace_1828',['kHitachiAcOneSpace',['../ir__Hitachi_8cpp.html#a79a79aaf52a05c021621335586dd928f',1,'ir_Hitachi.cpp']]], + ['khitachiacpoweroffset_1829',['kHitachiAcPowerOffset',['../ir__Hitachi_8h.html#a30062f0646ac63c3612d13f98211e36b',1,'ir_Hitachi.h']]], + ['khitachiacstatelength_1830',['kHitachiAcStateLength',['../IRremoteESP8266_8h.html#a8bef76bac826afbbc51c2a867af15ed8',1,'IRremoteESP8266.h']]], + ['khitachiacswingoffset_1831',['kHitachiAcSwingOffset',['../ir__Hitachi_8h.html#aac1fcff513a4eca2aeb4f13c739165e2',1,'ir_Hitachi.h']]], + ['khitachiaczerospace_1832',['kHitachiAcZeroSpace',['../ir__Hitachi_8cpp.html#a0b03a4abb11d69a8b8da56ca2abc50c8',1,'ir_Hitachi.cpp']]], + ['kholdstr_1833',['kHoldStr',['../IRtext_8cpp.html#a86fd1f86e4a513603449e90a47500986',1,'kHoldStr(): IRtext.cpp'],['../IRtext_8h.html#adb2d0f01f1429b0f3eb7193519fe3d6e',1,'kHoldStr(): IRtext.cpp']]], + ['khoursstr_1834',['kHoursStr',['../IRtext_8cpp.html#ae94260daddf2ea56e54d56bbad66526c',1,'kHoursStr(): IRtext.cpp'],['../IRtext_8h.html#a10ecbc18040f0d0ed88b728c18b0a161',1,'kHoursStr(): IRtext.cpp']]], + ['khourstr_1835',['kHourStr',['../IRtext_8cpp.html#a1d25a0bf2c8a638fff1557a0c5637977',1,'kHourStr(): IRtext.cpp'],['../IRtext_8h.html#a67a94ecb5a557b5335a8085cf1d8cdd6',1,'kHourStr(): IRtext.cpp']]], + ['khumidstr_1836',['kHumidStr',['../IRtext_8cpp.html#aae236cd2e7ed4961360fe687fe38170d',1,'kHumidStr(): IRtext.cpp'],['../IRtext_8h.html#a25365e722200ac40d581c4f585f9ae2f',1,'kHumidStr(): IRtext.cpp']]], + ['kidlestate_1837',['kIdleState',['../IRrecv_8h.html#aabba6fe7d7b97c45173eb7781a5d99bf',1,'IRrecv.h']]], + ['kifeelstr_1838',['kIFeelStr',['../IRtext_8cpp.html#a3c7368d9138477f0eac2a6249ba2606b',1,'kIFeelStr(): IRtext.cpp'],['../IRtext_8h.html#a40f90b18252e14a73dd91527f621e35f',1,'kIFeelStr(): IRtext.cpp']]], + ['kinaxbitmark_1839',['kInaxBitMark',['../ir__Inax_8cpp.html#a84553819866dbfcfad8cba87f6c02e04',1,'ir_Inax.cpp']]], + ['kinaxbits_1840',['kInaxBits',['../IRremoteESP8266_8h.html#af8441f25b32d113096adeaff331c126a',1,'IRremoteESP8266.h']]], + ['kinaxhdrmark_1841',['kInaxHdrMark',['../ir__Inax_8cpp.html#ac467a96d91b6266c3ce9a2a4ec2a8b44',1,'ir_Inax.cpp']]], + ['kinaxhdrspace_1842',['kInaxHdrSpace',['../ir__Inax_8cpp.html#a6ddcc8ca7a5d05cee91e57b3e69cca33',1,'ir_Inax.cpp']]], + ['kinaxmingap_1843',['kInaxMinGap',['../ir__Inax_8cpp.html#a600f49303a77fbdc1d77aae2abe9b9aa',1,'ir_Inax.cpp']]], + ['kinaxminrepeat_1844',['kInaxMinRepeat',['../IRremoteESP8266_8h.html#a37a3d0ae51a6ce850a424fe77d5b22d2',1,'IRremoteESP8266.h']]], + ['kinaxonespace_1845',['kInaxOneSpace',['../ir__Inax_8cpp.html#aeb77e3a51838547a29c1b343eba4c7ef',1,'ir_Inax.cpp']]], + ['kinaxtick_1846',['kInaxTick',['../ir__Inax_8cpp.html#ad437f0beac0893853cc9d5cc214b03c6',1,'ir_Inax.cpp']]], + ['kinaxzerospace_1847',['kInaxZeroSpace',['../ir__Inax_8cpp.html#a115f1f061362c1c3c41e3bb20ea7e1c6',1,'ir_Inax.cpp']]], + ['kinsidestr_1848',['kInsideStr',['../IRtext_8cpp.html#aa94c7a9b472bcd2297b43a5b4008bc51',1,'kInsideStr(): IRtext.cpp'],['../IRtext_8h.html#a55c406749cb48970c11c58ec83ef97eb',1,'kInsideStr(): IRtext.cpp']]], + ['kionstr_1849',['kIonStr',['../IRtext_8cpp.html#afc36ce4beed72e662a8d9d1473dad235',1,'kIonStr(): IRtext.cpp'],['../IRtext_8h.html#add28006fe2f8ac70db1b5048c85be84b',1,'kIonStr(): IRtext.cpp']]], + ['kjvcbitmark_1850',['kJvcBitMark',['../ir__JVC_8cpp.html#a23c11d77431d37bba18776f9341c767f',1,'ir_JVC.cpp']]], + ['kjvcbitmarkticks_1851',['kJvcBitMarkTicks',['../ir__JVC_8cpp.html#aad7cf432a9bd0d2b4df66d5f903a70dd',1,'ir_JVC.cpp']]], + ['kjvcbits_1852',['kJvcBits',['../IRremoteESP8266_8h.html#a7c28467832e7480864a6be0ce87c608f',1,'IRremoteESP8266.h']]], + ['kjvchdrmark_1853',['kJvcHdrMark',['../ir__JVC_8cpp.html#a60d81ad0066288b602054bd24a912f1f',1,'ir_JVC.cpp']]], + ['kjvchdrmarkticks_1854',['kJvcHdrMarkTicks',['../ir__JVC_8cpp.html#abb12fba45b7a366e23849d693953e749',1,'ir_JVC.cpp']]], + ['kjvchdrspace_1855',['kJvcHdrSpace',['../ir__JVC_8cpp.html#a5444718f66ba8b43c1d7d99f7b378a0d',1,'ir_JVC.cpp']]], + ['kjvchdrspaceticks_1856',['kJvcHdrSpaceTicks',['../ir__JVC_8cpp.html#ae7cf6cb7b5ea5fe17a9b182d1ef3b008',1,'ir_JVC.cpp']]], + ['kjvcmingap_1857',['kJvcMinGap',['../ir__JVC_8cpp.html#ac19d8396c10adb687a883d016ec43aa5',1,'ir_JVC.cpp']]], + ['kjvcmingapticks_1858',['kJvcMinGapTicks',['../ir__JVC_8cpp.html#a525e7d672b148c02bdca1f66ab92e6c7',1,'ir_JVC.cpp']]], + ['kjvconespace_1859',['kJvcOneSpace',['../ir__JVC_8cpp.html#a8befef1d03f3a09541c2612c66c0256f',1,'ir_JVC.cpp']]], + ['kjvconespaceticks_1860',['kJvcOneSpaceTicks',['../ir__JVC_8cpp.html#a20d4f7737d71bdbec58694e775669df9',1,'ir_JVC.cpp']]], + ['kjvcrptlength_1861',['kJvcRptLength',['../ir__JVC_8cpp.html#a3896e40881e70c63234fecb88375b5a1',1,'ir_JVC.cpp']]], + ['kjvcrptlengthticks_1862',['kJvcRptLengthTicks',['../ir__JVC_8cpp.html#a75e03cf5739ab0ba67e5cfa426776d16',1,'ir_JVC.cpp']]], + ['kjvctick_1863',['kJvcTick',['../ir__JVC_8cpp.html#acd5a2ba251824cac5311adcc9a813b1a',1,'ir_JVC.cpp']]], + ['kjvczerospace_1864',['kJvcZeroSpace',['../ir__JVC_8cpp.html#a67c790b909f82e044b8c4e7227d9c189',1,'ir_JVC.cpp']]], + ['kjvczerospaceticks_1865',['kJvcZeroSpaceTicks',['../ir__JVC_8cpp.html#a0a5319df3b1e01741cd35a37087342f5',1,'ir_JVC.cpp']]], + ['kkelvinatorauto_1866',['kKelvinatorAuto',['../ir__Kelvinator_8h.html#a879b005fc5493a693b05e3bb7cbc8fbf',1,'ir_Kelvinator.h']]], + ['kkelvinatorautotemp_1867',['kKelvinatorAutoTemp',['../ir__Kelvinator_8h.html#afa9e7ea8c9fb86cb02358cc8221733b0',1,'ir_Kelvinator.h']]], + ['kkelvinatorbasicfanmax_1868',['kKelvinatorBasicFanMax',['../ir__Kelvinator_8h.html#a10624389f033451cf9a6f4530c2dfb98',1,'ir_Kelvinator.h']]], + ['kkelvinatorbasicfansize_1869',['kKelvinatorBasicFanSize',['../ir__Kelvinator_8cpp.html#a35ffe10c5c1b834703fe44c5eeeb4c8f',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorbitmark_1870',['kKelvinatorBitMark',['../ir__Kelvinator_8cpp.html#a2014f9f92f1e24a04341398e7e673807',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorbitmarkticks_1871',['kKelvinatorBitMarkTicks',['../ir__Kelvinator_8cpp.html#a2d6579257ab7f185e4f0fecdbdf03835',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorbits_1872',['kKelvinatorBits',['../IRremoteESP8266_8h.html#acfa71cb3caf4964829bb1f557dee5b86',1,'IRremoteESP8266.h']]], + ['kkelvinatorchecksumstart_1873',['kKelvinatorChecksumStart',['../ir__Kelvinator_8cpp.html#a0afa7cec1db6a5f46c1b30d7ce718ae6',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorcmdfooter_1874',['kKelvinatorCmdFooter',['../ir__Kelvinator_8cpp.html#ad2361e09472fa03376b447114a19513f',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorcmdfooterbits_1875',['kKelvinatorCmdFooterBits',['../ir__Kelvinator_8cpp.html#af6c85d3b30a5949da53ad9400734f203',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorcool_1876',['kKelvinatorCool',['../ir__Kelvinator_8h.html#ad49a2e457470d6e16d001cdae3215606',1,'ir_Kelvinator.h']]], + ['kkelvinatordefaultrepeat_1877',['kKelvinatorDefaultRepeat',['../IRremoteESP8266_8h.html#a94c968c5cc929f189b8e578d2f55b132',1,'IRremoteESP8266.h']]], + ['kkelvinatordry_1878',['kKelvinatorDry',['../ir__Kelvinator_8h.html#a181b3d10b522f9afb29706da42afea55',1,'ir_Kelvinator.h']]], + ['kkelvinatorfan_1879',['kKelvinatorFan',['../ir__Kelvinator_8h.html#a8d6d97be2fd8a5aefa1319d3f662a50c',1,'ir_Kelvinator.h']]], + ['kkelvinatorfanauto_1880',['kKelvinatorFanAuto',['../ir__Kelvinator_8h.html#ac4994c36634ca0ad8791807c9a992976',1,'ir_Kelvinator.h']]], + ['kkelvinatorfanmax_1881',['kKelvinatorFanMax',['../ir__Kelvinator_8h.html#a889ce17d112d1a61420e1064d72c583a',1,'ir_Kelvinator.h']]], + ['kkelvinatorfanmin_1882',['kKelvinatorFanMin',['../ir__Kelvinator_8h.html#a36a9422e2e6c6b7a87e8b2deffd1b189',1,'ir_Kelvinator.h']]], + ['kkelvinatorfanoffset_1883',['kKelvinatorFanOffset',['../ir__Kelvinator_8cpp.html#a4988bb98a4f8798c0b927e981667cfbd',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorfansize_1884',['kKelvinatorFanSize',['../ir__Kelvinator_8cpp.html#a286636ba83aceab9c8518878a6d7209e',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorgapspace_1885',['kKelvinatorGapSpace',['../ir__Kelvinator_8cpp.html#abf66116a235a9d05089182f2f7fd7640',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorgapspaceticks_1886',['kKelvinatorGapSpaceTicks',['../ir__Kelvinator_8cpp.html#a6a81fb4c1cf1ad34f99f3ca87ab74a5c',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorhdrmark_1887',['kKelvinatorHdrMark',['../ir__Kelvinator_8cpp.html#a413e824c6bdd4778e70f496917b3fe30',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorhdrmarkticks_1888',['kKelvinatorHdrMarkTicks',['../ir__Kelvinator_8cpp.html#a8ad828958071c75a80928abfb916c0df',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorhdrspace_1889',['kKelvinatorHdrSpace',['../ir__Kelvinator_8cpp.html#a9cab23fbd5ba62714fda24765db0e7d1',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorhdrspaceticks_1890',['kKelvinatorHdrSpaceTicks',['../ir__Kelvinator_8cpp.html#ab4fbf899dcb2c2d510055215617d5b44',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorheat_1891',['kKelvinatorHeat',['../ir__Kelvinator_8h.html#a080eade5648791e37c76af7a52e85731',1,'ir_Kelvinator.h']]], + ['kkelvinatorionfilteroffset_1892',['kKelvinatorIonFilterOffset',['../ir__Kelvinator_8cpp.html#a5cbdc907f0cb6a47d0c548148933067b',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorlightoffset_1893',['kKelvinatorLightOffset',['../ir__Kelvinator_8cpp.html#a7e757add18951b8e36c2065c5dbefc24',1,'ir_Kelvinator.cpp']]], + ['kkelvinatormaxtemp_1894',['kKelvinatorMaxTemp',['../ir__Kelvinator_8h.html#a14933442e718db1a87bae5d076ad228d',1,'ir_Kelvinator.h']]], + ['kkelvinatormintemp_1895',['kKelvinatorMinTemp',['../ir__Kelvinator_8h.html#a98871ce825dbbe80d072f25253142879',1,'ir_Kelvinator.h']]], + ['kkelvinatormodeoffset_1896',['kKelvinatorModeOffset',['../ir__Kelvinator_8cpp.html#a6a52d11326d5f83653c510393bb2a518',1,'ir_Kelvinator.cpp']]], + ['kkelvinatoronespace_1897',['kKelvinatorOneSpace',['../ir__Kelvinator_8cpp.html#aae5a009282517309b8fdbfdaced9d659',1,'ir_Kelvinator.cpp']]], + ['kkelvinatoronespaceticks_1898',['kKelvinatorOneSpaceTicks',['../ir__Kelvinator_8cpp.html#ac907f4495debdcaf680f6e6941b844d5',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorpoweroffset_1899',['kKelvinatorPowerOffset',['../ir__Kelvinator_8cpp.html#a5a9591e2dd98f68ad6f562e199b1a304',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorquietoffset_1900',['kKelvinatorQuietOffset',['../ir__Kelvinator_8cpp.html#ad354be321ea41c51ead876fd30674546',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorstatelength_1901',['kKelvinatorStateLength',['../IRremoteESP8266_8h.html#af68545e8c2fe9af3719fb74c5d21f0c9',1,'IRremoteESP8266.h']]], + ['kkelvinatortick_1902',['kKelvinatorTick',['../ir__Kelvinator_8cpp.html#a846cbb5609b1dff139a90487000c7393',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorturbooffset_1903',['kKelvinatorTurboOffset',['../ir__Kelvinator_8cpp.html#a21987b6f00c7f2e9bba94c59bc5b804b',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorventswinghoffset_1904',['kKelvinatorVentSwingHOffset',['../ir__Kelvinator_8cpp.html#a551df2c1e21764f12030f6bfa6d5942d',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorventswingoffset_1905',['kKelvinatorVentSwingOffset',['../ir__Kelvinator_8cpp.html#a38012bf9daa0c362a9007107183391ef',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorventswingvoffset_1906',['kKelvinatorVentSwingVOffset',['../ir__Kelvinator_8cpp.html#a64d3767b464d4fe2543560cf5a2a5b21',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorxfanoffset_1907',['kKelvinatorXfanOffset',['../ir__Kelvinator_8cpp.html#a4417448475405306f10166fc9cd98054',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorzerospace_1908',['kKelvinatorZeroSpace',['../ir__Kelvinator_8cpp.html#a10469f76f50285a6084bb088fd601dea',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorzerospaceticks_1909',['kKelvinatorZeroSpaceTicks',['../ir__Kelvinator_8cpp.html#a0abc0fdc3d9ac9f12133a46e95d69432',1,'ir_Kelvinator.cpp']]], + ['klasertagbits_1910',['kLasertagBits',['../IRremoteESP8266_8h.html#a3ea0e89a8b6a3ffa4a2d346abeed851e',1,'IRremoteESP8266.h']]], + ['klasertagdelta_1911',['kLasertagDelta',['../ir__Lasertag_8cpp.html#a5c0e8e9c6dec0480c09fcd339ed62257',1,'ir_Lasertag.cpp']]], + ['klasertagexcess_1912',['kLasertagExcess',['../ir__Lasertag_8cpp.html#afa77dc5a431a8d851320e7623378983e',1,'ir_Lasertag.cpp']]], + ['klasertagmingap_1913',['kLasertagMinGap',['../ir__Lasertag_8cpp.html#a33762e2c44dac34e00d255b41d9f2822',1,'ir_Lasertag.cpp']]], + ['klasertagminrepeat_1914',['kLasertagMinRepeat',['../IRremoteESP8266_8h.html#a9b36135c3df24eab232a5edac8c58c5e',1,'IRremoteESP8266.h']]], + ['klasertagminsamples_1915',['kLasertagMinSamples',['../ir__Lasertag_8cpp.html#acbf98970106cadb43e0703ae2caab0c1',1,'ir_Lasertag.cpp']]], + ['klasertagtick_1916',['kLasertagTick',['../ir__Lasertag_8cpp.html#a878b5d53379f8b1b21dfe19f1f83a626',1,'ir_Lasertag.cpp']]], + ['klasertagtolerance_1917',['kLasertagTolerance',['../ir__Lasertag_8cpp.html#a6146bcf378515d31330b3fec5c967346',1,'ir_Lasertag.cpp']]], + ['klastdecodetype_1918',['kLastDecodeType',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadab09881b84bf9d61af99e62a85cce0b59',1,'IRremoteESP8266.h']]], + ['klastfanspeedenum_1919',['kLastFanspeedEnum',['../namespacestdAc.html#a8bb0dbf18fe69f639f4ac0b3ff133383ab2d2a6993491fd666f1fa0afff5913ad',1,'stdAc']]], + ['klastopmodeenum_1920',['kLastOpmodeEnum',['../namespacestdAc.html#a99ad268c783486f9b3207cb78f48444fa8dd00ffd575f66172d594e78860aad9f',1,'stdAc']]], + ['klaststr_1921',['kLastStr',['../IRtext_8cpp.html#ad7c8430b935afb7aec114788a9c0bf7d',1,'kLastStr(): IRtext.cpp'],['../IRtext_8h.html#aa9ffd7c6e6921607653ed5dc1fea4f32',1,'kLastStr(): IRtext.cpp']]], + ['klastswinghenum_1922',['kLastSwinghEnum',['../namespacestdAc.html#aae50ee315fa9c9ec1a4078da40d6b147ac5bc5e605db47897c114283926ba7fe4',1,'stdAc']]], + ['klastswingvenum_1923',['kLastSwingvEnum',['../namespacestdAc.html#ac07f224c7bb47cac55dd01f24770ef43a4127912afc084d51c71c4ea0c7dd7b30',1,'stdAc']]], + ['kleft_1924',['kLeft',['../namespacestdAc.html#aae50ee315fa9c9ec1a4078da40d6b147a2d5fde1d924910a2a01ecd8e70a87c28',1,'stdAc']]], + ['kleftmax_1925',['kLeftMax',['../namespacestdAc.html#aae50ee315fa9c9ec1a4078da40d6b147a375fe2e8ea70186052eeb2983baa1d7d',1,'stdAc']]], + ['kleftmaxstr_1926',['kLeftMaxStr',['../IRtext_8cpp.html#a1a82999b6eb3b6637f51bb8ce6a46efd',1,'kLeftMaxStr(): IRtext.cpp'],['../IRtext_8h.html#ab2fd48f052fcfed8ca779ca499edcdbf',1,'kLeftMaxStr(): IRtext.cpp']]], + ['kleftstr_1927',['kLeftStr',['../IRtext_8cpp.html#a0bb005966f2ff2da12a542e713f7f1f2',1,'kLeftStr(): IRtext.cpp'],['../IRtext_8h.html#a001f11495c7c9452ceec68455ae524bf',1,'kLeftStr(): IRtext.cpp']]], + ['klegopfbitmark_1928',['kLegoPfBitMark',['../ir__Lego_8cpp.html#afdf76660f62bfefb4a813d57cd84b590',1,'ir_Lego.cpp']]], + ['klegopfbits_1929',['kLegoPfBits',['../IRremoteESP8266_8h.html#a8a7c7659250a81c7c84fc739eafed13e',1,'IRremoteESP8266.h']]], + ['klegopfhdrspace_1930',['kLegoPfHdrSpace',['../ir__Lego_8cpp.html#a140e8707900bfd4e3a9e2722a6b0bfb3',1,'ir_Lego.cpp']]], + ['klegopfmincommandlength_1931',['kLegoPfMinCommandLength',['../ir__Lego_8cpp.html#ad9a0c5184cc422ec1b32edf58c52d2b1',1,'ir_Lego.cpp']]], + ['klegopfminrepeat_1932',['kLegoPfMinRepeat',['../IRremoteESP8266_8h.html#a2614cf3cb840f028eb1dc684aeb1272c',1,'IRremoteESP8266.h']]], + ['klegopfonespace_1933',['kLegoPfOneSpace',['../ir__Lego_8cpp.html#a59a41085f2e8f81e1019fd40782269e3',1,'ir_Lego.cpp']]], + ['klegopfzerospace_1934',['kLegoPfZeroSpace',['../ir__Lego_8cpp.html#ada07e8aaf79cf58c46b301a410d9fb3e',1,'ir_Lego.cpp']]], + ['klg2bitmark_1935',['kLg2BitMark',['../ir__LG_8cpp.html#abf4db4647161db6fb2548b5200c41843',1,'ir_LG.cpp']]], + ['klg2bitmarkticks_1936',['kLg2BitMarkTicks',['../ir__LG_8cpp.html#aae477dcb68b9c5f1b12adf832eb388a1',1,'ir_LG.cpp']]], + ['klg2hdrmark_1937',['kLg2HdrMark',['../ir__LG_8cpp.html#a5ca50077fba2d5130220255e1659e0c3',1,'ir_LG.cpp']]], + ['klg2hdrmarkticks_1938',['kLg2HdrMarkTicks',['../ir__LG_8cpp.html#adb636fb6b634c651364ae954d31b5692',1,'ir_LG.cpp']]], + ['klg2hdrspace_1939',['kLg2HdrSpace',['../ir__LG_8cpp.html#a6637da052fea9320e97cff261f219cdb',1,'ir_LG.cpp']]], + ['klg2hdrspaceticks_1940',['kLg2HdrSpaceTicks',['../ir__LG_8cpp.html#abd2f843416070a93587d07e4d32f1eb5',1,'ir_LG.cpp']]], + ['klg32bits_1941',['kLg32Bits',['../IRremoteESP8266_8h.html#ae3c458814d7221b66d2f267cb2663bd2',1,'IRremoteESP8266.h']]], + ['klg32hdrmark_1942',['kLg32HdrMark',['../ir__LG_8cpp.html#a26cb3fb11b1a0bf0815868767e50f31b',1,'ir_LG.cpp']]], + ['klg32hdrmarkticks_1943',['kLg32HdrMarkTicks',['../ir__LG_8cpp.html#aded50973c0a938d455c1537cb240d5e9',1,'ir_LG.cpp']]], + ['klg32hdrspace_1944',['kLg32HdrSpace',['../ir__LG_8cpp.html#a59ddf2070642615e162c85b7575aff76',1,'ir_LG.cpp']]], + ['klg32hdrspaceticks_1945',['kLg32HdrSpaceTicks',['../ir__LG_8cpp.html#aa029c2c83a96f1ff02610eddd6b946fa',1,'ir_LG.cpp']]], + ['klg32rpthdrmark_1946',['kLg32RptHdrMark',['../ir__LG_8cpp.html#af19a674228bea82c1c588aa9dd974805',1,'ir_LG.cpp']]], + ['klg32rpthdrmarkticks_1947',['kLg32RptHdrMarkTicks',['../ir__LG_8cpp.html#a5c79f7072eee35fc1df10ecd18e2a3d2',1,'ir_LG.cpp']]], + ['klgacauto_1948',['kLgAcAuto',['../ir__LG_8h.html#ae5e45a0f42ce7544d6fb7981a43fb932',1,'ir_LG.h']]], + ['klgacchecksumoffset_1949',['kLgAcChecksumOffset',['../ir__LG_8h.html#aa0b9abe43a870097d886efcd0fd3bb96',1,'ir_LG.h']]], + ['klgacchecksumsize_1950',['kLgAcChecksumSize',['../ir__LG_8h.html#a177d205346380d47ae47b52079e5ffaf',1,'ir_LG.h']]], + ['klgaccool_1951',['kLgAcCool',['../ir__LG_8h.html#a3ba35885488bdda3d87ba344a5c58eb2',1,'ir_LG.h']]], + ['klgacdry_1952',['kLgAcDry',['../ir__LG_8h.html#ab3b9a106551be1217e0c824cffe1ea44',1,'ir_LG.h']]], + ['klgacfan_1953',['kLgAcFan',['../ir__LG_8h.html#afc12144673b8dd0555833427fa757275',1,'ir_LG.h']]], + ['klgacfanauto_1954',['kLgAcFanAuto',['../ir__LG_8h.html#a3dee1dc33f768d36a2216213c90a0a5c',1,'ir_LG.h']]], + ['klgacfanhigh_1955',['kLgAcFanHigh',['../ir__LG_8h.html#a89888f8d36899b5526e4c2ebb1097357',1,'ir_LG.h']]], + ['klgacfanlow_1956',['kLgAcFanLow',['../ir__LG_8h.html#afa3633c1b26d837f85b10a8a8d677efc',1,'ir_LG.h']]], + ['klgacfanmedium_1957',['kLgAcFanMedium',['../ir__LG_8h.html#abe0fb8a8f9d6ab9ebda36d0343841619',1,'ir_LG.h']]], + ['klgacfanoffset_1958',['kLgAcFanOffset',['../ir__LG_8h.html#a428d348215682243f7e5fe03c7580665',1,'ir_LG.h']]], + ['klgacfansize_1959',['kLgAcFanSize',['../ir__LG_8h.html#a4baf7484fee55fdd5cdbf13d11d7f1b9',1,'ir_LG.h']]], + ['klgacheat_1960',['kLgAcHeat',['../ir__LG_8h.html#a6c17d61082cc24f9d714c5d4ac151933',1,'ir_LG.h']]], + ['klgacmaxtemp_1961',['kLgAcMaxTemp',['../ir__LG_8h.html#a0fab7b6e6d1138638bdeadeab85f5090',1,'ir_LG.h']]], + ['klgacmintemp_1962',['kLgAcMinTemp',['../ir__LG_8h.html#ae3bef99e329f057358001cacf67f6d70',1,'ir_LG.h']]], + ['klgacmodeoffset_1963',['kLgAcModeOffset',['../ir__LG_8h.html#abbc65ef461fd214d9ef41ebf62693467',1,'ir_LG.h']]], + ['klgacmodesize_1964',['kLgAcModeSize',['../ir__LG_8h.html#ae9927832fbb45c310666d8de1ebe5f0f',1,'ir_LG.h']]], + ['klgacoffcommand_1965',['kLgAcOffCommand',['../ir__LG_8h.html#aecf8158eec1d9ec0d54056392b512296',1,'ir_LG.h']]], + ['klgacpoweroff_1966',['kLgAcPowerOff',['../ir__LG_8h.html#a3b2681e41071298197d849fbd7649318',1,'ir_LG.h']]], + ['klgacpoweroffset_1967',['kLgAcPowerOffset',['../ir__LG_8h.html#a7cce14305909efe3b904d68f902d42de',1,'ir_LG.h']]], + ['klgacpoweron_1968',['kLgAcPowerOn',['../ir__LG_8h.html#a87d2f6e4e2755aaab4762952b1bf6108',1,'ir_LG.h']]], + ['klgacpowersize_1969',['kLgAcPowerSize',['../ir__LG_8h.html#a624eee0bc9084e4d9d801f8cbdc28d1e',1,'ir_LG.h']]], + ['klgacsignature_1970',['kLgAcSignature',['../ir__LG_8h.html#ab7c3589deb28829ad0313b1505ec196e',1,'ir_LG.h']]], + ['klgacsignatureoffset_1971',['kLgAcSignatureOffset',['../ir__LG_8h.html#a406dff4b4ffa5b809b8ea87ddfd3bf8b',1,'ir_LG.h']]], + ['klgacsignaturesize_1972',['kLgAcSignatureSize',['../ir__LG_8h.html#a7420d729a5dca26d95be3b9907eb477e',1,'ir_LG.h']]], + ['klgactempadjust_1973',['kLgAcTempAdjust',['../ir__LG_8h.html#a16210dc395a86dc4562436047c22600f',1,'ir_LG.h']]], + ['klgactempoffset_1974',['kLgAcTempOffset',['../ir__LG_8h.html#aca5ae781e03e4a88a83303cb0cae0609',1,'ir_LG.h']]], + ['klgactempsize_1975',['kLgAcTempSize',['../ir__LG_8h.html#ad0235a6c5bebb086b75dc65433b3c9e1',1,'ir_LG.h']]], + ['klgbitmark_1976',['kLgBitMark',['../ir__LG_8cpp.html#a9311195710d4c3a2ac48456390a03138',1,'ir_LG.cpp']]], + ['klgbitmarkticks_1977',['kLgBitMarkTicks',['../ir__LG_8cpp.html#a80b2d221b207c8c0faa74f1f39e9920b',1,'ir_LG.cpp']]], + ['klgbits_1978',['kLgBits',['../IRremoteESP8266_8h.html#a256bd6093034b3e4c33324680f3a7102',1,'IRremoteESP8266.h']]], + ['klgdefaultrepeat_1979',['kLgDefaultRepeat',['../IRremoteESP8266_8h.html#a2d6832b3d214e0adad781c205993e461',1,'IRremoteESP8266.h']]], + ['klghdrmark_1980',['kLgHdrMark',['../ir__LG_8cpp.html#a74f253d9e4cc72148233021c47d59f35',1,'ir_LG.cpp']]], + ['klghdrmarkticks_1981',['kLgHdrMarkTicks',['../ir__LG_8cpp.html#a6f1f88f3cefe49b9796a10a9109e560e',1,'ir_LG.cpp']]], + ['klghdrspace_1982',['kLgHdrSpace',['../ir__LG_8cpp.html#a6eaf100cde647fc119d3e993680afd47',1,'ir_LG.cpp']]], + ['klghdrspaceticks_1983',['kLgHdrSpaceTicks',['../ir__LG_8cpp.html#a22d8775d4c8985970b47e449232b45de',1,'ir_LG.cpp']]], + ['klgmingap_1984',['kLgMinGap',['../ir__LG_8cpp.html#a784323468e6b5ebc65bd2870a94fb553',1,'ir_LG.cpp']]], + ['klgmingapticks_1985',['kLgMinGapTicks',['../ir__LG_8cpp.html#aa56fd5b4fe946992aa1b9bdf61b1518b',1,'ir_LG.cpp']]], + ['klgminmessagelength_1986',['kLgMinMessageLength',['../ir__LG_8cpp.html#a4eb3f82ae2ca6c34b58e512848a6dc41',1,'ir_LG.cpp']]], + ['klgminmessagelengthticks_1987',['kLgMinMessageLengthTicks',['../ir__LG_8cpp.html#ab000fc974bdd0723e8bcb4872f33dd72',1,'ir_LG.cpp']]], + ['klgonespace_1988',['kLgOneSpace',['../ir__LG_8cpp.html#a05fe6a47f437efc686cb46ec805da4d4',1,'ir_LG.cpp']]], + ['klgonespaceticks_1989',['kLgOneSpaceTicks',['../ir__LG_8cpp.html#a535b089cd72bd027cbc34eb917d71ae5',1,'ir_LG.cpp']]], + ['klgrptspace_1990',['kLgRptSpace',['../ir__LG_8cpp.html#a834b8f08ee32030c51ea5e2c5bd5a73c',1,'ir_LG.cpp']]], + ['klgrptspaceticks_1991',['kLgRptSpaceTicks',['../ir__LG_8cpp.html#abc43b327c2c752dc5ed2794f08e2eba8',1,'ir_LG.cpp']]], + ['klgtick_1992',['kLgTick',['../ir__LG_8cpp.html#ab8ab28ebf1fae94aa900a3199a6fc191',1,'ir_LG.cpp']]], + ['klgzerospace_1993',['kLgZeroSpace',['../ir__LG_8cpp.html#a981fe3cfc4adf0b3016a008ca1bbf734',1,'ir_LG.cpp']]], + ['klgzerospaceticks_1994',['kLgZeroSpaceTicks',['../ir__LG_8cpp.html#af932345e15db822da67d7796cd5b6584',1,'ir_LG.cpp']]], + ['klightstr_1995',['kLightStr',['../IRtext_8cpp.html#a2912b7dc11fd571706eaaf90e0095a4f',1,'kLightStr(): IRtext.cpp'],['../IRtext_8h.html#a926ebb4be14179afdc55d5524c8eb5da',1,'kLightStr(): IRtext.cpp']]], + ['klighttogglestr_1996',['kLightToggleStr',['../IRtext_8cpp.html#a74a3ef3c72995e19582be04a2716b285',1,'kLightToggleStr(): IRtext.cpp'],['../IRtext_8h.html#af9ac8ce54e78f0d8f7e0043d08e6256c',1,'kLightToggleStr(): IRtext.cpp']]], + ['klostr_1997',['kLoStr',['../IRtext_8cpp.html#a72fc3855eec7026260de3a6b3a25c377',1,'kLoStr(): IRtext.cpp'],['../IRtext_8h.html#abf3295aeb3dfb7048e677d8d6e65e47c',1,'kLoStr(): IRtext.cpp']]], + ['kloudstr_1998',['kLoudStr',['../IRtext_8cpp.html#a3b6d3eed96c5623cc95ebcfb93cb6f96',1,'kLoudStr(): IRtext.cpp'],['../IRtext_8h.html#a7d265b75ed59c0be3c6b72ec0eaf8aa2',1,'kLoudStr(): IRtext.cpp']]], + ['klow_1999',['kLow',['../namespacestdAc.html#a8bb0dbf18fe69f639f4ac0b3ff133383acd8fe42741a3bbc973bbf1d404afeff4',1,'stdAc::kLow()'],['../namespacestdAc.html#ac07f224c7bb47cac55dd01f24770ef43acd8fe42741a3bbc973bbf1d404afeff4',1,'stdAc::kLow()']]], + ['klowerstr_2000',['kLowerStr',['../IRtext_8cpp.html#a518681524ec3c8f8bc993823003fe58a',1,'kLowerStr(): IRtext.cpp'],['../IRtext_8h.html#ae389ed4ed6982d4617ee3f3e82ce388c',1,'kLowerStr(): IRtext.cpp']]], + ['klowest_2001',['kLowest',['../namespacestdAc.html#ac07f224c7bb47cac55dd01f24770ef43a334c684494b7f19d765cf062ae94a314',1,'stdAc']]], + ['kloweststr_2002',['kLowestStr',['../IRtext_8cpp.html#ae0c595955599a398669a372edd339f67',1,'kLowestStr(): IRtext.cpp'],['../IRtext_8h.html#a31a34e51d7f1f9360cc3a7ea3f2bf7a3',1,'kLowestStr(): IRtext.cpp']]], + ['klownibble_2003',['kLowNibble',['../IRutils_8h.html#ad0288cc71e1814a27c27393f06676eec',1,'IRutils.h']]], + ['klowstr_2004',['kLowStr',['../IRtext_8cpp.html#a18f69bf40b866ee1d30d1586757d5f41',1,'kLowStr(): IRtext.cpp'],['../IRtext_8h.html#a09c0f7f1b07f7591bdbe56fd8a18f7ea',1,'kLowStr(): IRtext.cpp']]], + ['klutronbits_2005',['kLutronBits',['../IRremoteESP8266_8h.html#a814dfab515b91887c494237b1f6ebd99',1,'IRremoteESP8266.h']]], + ['klutrondelta_2006',['kLutronDelta',['../ir__Lutron_8cpp.html#a4220004fac195ef46388199ad9624860',1,'ir_Lutron.cpp']]], + ['klutrongap_2007',['kLutronGap',['../ir__Lutron_8cpp.html#a18ffb51db0ae33904a64012cb72d6165',1,'ir_Lutron.cpp']]], + ['klutrontick_2008',['kLutronTick',['../ir__Lutron_8cpp.html#a04a84309978b79c0983c398a497a087a',1,'ir_Lutron.cpp']]], + ['kmagiquestbits_2009',['kMagiquestBits',['../IRremoteESP8266_8h.html#ad756bfec6eabbe2ac10b7847f87fb751',1,'IRremoteESP8266.h']]], + ['kmagiquestgap_2010',['kMagiQuestGap',['../ir__Magiquest_8h.html#aebdea5a1a55547d812f1f7bb2d3ddf1f',1,'ir_Magiquest.h']]], + ['kmagiquestmarkone_2011',['kMagiQuestMarkOne',['../ir__Magiquest_8h.html#a0d5d090015ecf49995514054c29cb4e2',1,'ir_Magiquest.h']]], + ['kmagiquestmarkzero_2012',['kMagiQuestMarkZero',['../ir__Magiquest_8h.html#a7240a15dbb9bc6a1e31575be7837c390',1,'ir_Magiquest.h']]], + ['kmagiquestoneratio_2013',['kMagiQuestOneRatio',['../ir__Magiquest_8h.html#a073cdb7ca4dd35b8fa05d99eb7da5b65',1,'ir_Magiquest.h']]], + ['kmagiquestspaceone_2014',['kMagiQuestSpaceOne',['../ir__Magiquest_8h.html#a92bad440c0291cbb903f08de08d96fb2',1,'ir_Magiquest.h']]], + ['kmagiquestspacezero_2015',['kMagiQuestSpaceZero',['../ir__Magiquest_8h.html#abe557052c5c3bef87e62daf71b4c8654',1,'ir_Magiquest.h']]], + ['kmagiquesttotalusec_2016',['kMagiQuestTotalUsec',['../ir__Magiquest_8h.html#a819dcf22b127f4f7b282d784490a83c3',1,'ir_Magiquest.h']]], + ['kmagiquestzeroratio_2017',['kMagiQuestZeroRatio',['../ir__Magiquest_8h.html#a41e5594b8e1510267e563ed78fbe98b0',1,'ir_Magiquest.h']]], + ['kmanualstr_2018',['kManualStr',['../IRtext_8cpp.html#a619896ae89717b2b0e1d3492bb528cbc',1,'kManualStr(): IRtext.cpp'],['../IRtext_8h.html#aa8d9143da032cdc1accf7f4441b05bc8',1,'kManualStr(): IRtext.cpp']]], + ['kmark_2019',['kMark',['../ir__Lasertag_8cpp.html#a7af2e83face1b9378d216f15a4d379cf',1,'kMark(): ir_Lasertag.cpp'],['../ir__MWM_8cpp.html#a7af2e83face1b9378d216f15a4d379cf',1,'kMark(): ir_MWM.cpp'],['../ir__RC5__RC6_8cpp.html#a7af2e83face1b9378d216f15a4d379cf',1,'kMark(): ir_RC5_RC6.cpp']]], + ['kmarkexcess_2020',['kMarkExcess',['../IRrecv_8h.html#a99bbffe986ad7ba86d2b11e75f4aa50e',1,'IRrecv.h']]], + ['kmarkstate_2021',['kMarkState',['../IRrecv_8h.html#acc85ad22929660bdc17fe185d87edfb2',1,'IRrecv.h']]], + ['kmax_2022',['kMax',['../namespacestdAc.html#a8bb0dbf18fe69f639f4ac0b3ff133383aa0b1ac8aae6b1cfbbe89085c642b3b4b',1,'stdAc']]], + ['kmaxaccurateusecdelay_2023',['kMaxAccurateUsecDelay',['../IRsend_8h.html#a527e66125f3ae6ce87adbc72eab7d0b9',1,'IRsend.h']]], + ['kmaximumstr_2024',['kMaximumStr',['../IRtext_8cpp.html#af346693e98c91c7ce79bb22c7460dcee',1,'kMaximumStr(): IRtext.cpp'],['../IRtext_8h.html#a487173616cc3fced0489c01c11333912',1,'kMaximumStr(): IRtext.cpp']]], + ['kmaxleftstr_2025',['kMaxLeftStr',['../IRtext_8cpp.html#ae8ad7e46c3a33b4b9c5fa6545c9e3822',1,'kMaxLeftStr(): IRtext.cpp'],['../IRtext_8h.html#aac197960695463757652bc643efdcd59',1,'kMaxLeftStr(): IRtext.cpp']]], + ['kmaxrightstr_2026',['kMaxRightStr',['../IRtext_8cpp.html#a1ae3f331adb8ac6d1a27aa3d688fb65f',1,'kMaxRightStr(): IRtext.cpp'],['../IRtext_8h.html#a0f888d5c39cf82b2c02a7caad10c716e',1,'kMaxRightStr(): IRtext.cpp']]], + ['kmaxstr_2027',['kMaxStr',['../IRtext_8cpp.html#ad30e01090f06db0a3cb0c00bb6d2f0ca',1,'kMaxStr(): IRtext.cpp'],['../IRtext_8h.html#a7f4b2ff4134386a09e2bcb5f71f591cb',1,'kMaxStr(): IRtext.cpp']]], + ['kmaxtimeoutms_2028',['kMaxTimeoutMs',['../IRrecv_8h.html#a73391726d7caccb9b498bba73a969784',1,'IRrecv.h']]], + ['kmedium_2029',['kMedium',['../namespacestdAc.html#a8bb0dbf18fe69f639f4ac0b3ff133383a3ce9d817402b59f65fb01ea044bb1ee9',1,'stdAc']]], + ['kmediumstr_2030',['kMediumStr',['../IRtext_8cpp.html#ac59539e93fdc7d8f15f1f55bcbf933c5',1,'kMediumStr(): IRtext.cpp'],['../IRtext_8h.html#a122ee1c6b866267f771888a7d7b2969b',1,'kMediumStr(): IRtext.cpp']]], + ['kmedstr_2031',['kMedStr',['../IRtext_8cpp.html#a4832f8f5118018fa3c6eae1cd652eabf',1,'kMedStr(): IRtext.cpp'],['../IRtext_8h.html#a18f613c7f11f6f746227cfa8cc1e00e0',1,'kMedStr(): IRtext.cpp']]], + ['kmiddle_2032',['kMiddle',['../namespacestdAc.html#ac07f224c7bb47cac55dd01f24770ef43ab3199775e825c139b44e3e9ccf3cbc7e',1,'stdAc::kMiddle()'],['../namespacestdAc.html#aae50ee315fa9c9ec1a4078da40d6b147ab3199775e825c139b44e3e9ccf3cbc7e',1,'stdAc::kMiddle()']]], + ['kmiddlestr_2033',['kMiddleStr',['../IRtext_8cpp.html#a536f05d84867cfae601d4c1a2312d755',1,'kMiddleStr(): IRtext.cpp'],['../IRtext_8h.html#abbd5b682b584b737c76bded900a6ffad',1,'kMiddleStr(): IRtext.cpp']]], + ['kmidea24bits_2034',['kMidea24Bits',['../IRremoteESP8266_8h.html#aff132faa67b1d07890378df5c9b52a14',1,'IRremoteESP8266.h']]], + ['kmidea24mingap_2035',['kMidea24MinGap',['../ir__Midea_8cpp.html#abfee73cafcc017c4742893908200dffc',1,'ir_Midea.cpp']]], + ['kmidea24minrepeat_2036',['kMidea24MinRepeat',['../IRremoteESP8266_8h.html#a8ed4bb62818fc64e4c4b60ef1094059e',1,'IRremoteESP8266.h']]], + ['kmideaacauto_2037',['kMideaACAuto',['../ir__Midea_8h.html#a379f580c4d1832a62fe49d66f7c13af6',1,'ir_Midea.h']]], + ['kmideaaccelsiusoffset_2038',['kMideaACCelsiusOffset',['../ir__Midea_8h.html#a3354c62fbd83c1f0c55aee359d45a1e0',1,'ir_Midea.h']]], + ['kmideaaccool_2039',['kMideaACCool',['../ir__Midea_8h.html#a94b1b18f6aa9c5010699ea9bfcc89b21',1,'ir_Midea.h']]], + ['kmideaacdry_2040',['kMideaACDry',['../ir__Midea_8h.html#a88c2d215406e337b437b99a04c4ca6c4',1,'ir_Midea.h']]], + ['kmideaacfan_2041',['kMideaACFan',['../ir__Midea_8h.html#ac92dd372bb18d43aea73d5ec511e1290',1,'ir_Midea.h']]], + ['kmideaacfanauto_2042',['kMideaACFanAuto',['../ir__Midea_8h.html#a334a64f653b141d67ffda2eca2a9851f',1,'ir_Midea.h']]], + ['kmideaacfanhigh_2043',['kMideaACFanHigh',['../ir__Midea_8h.html#a9c177aff562a19f32d6cf010704ac681',1,'ir_Midea.h']]], + ['kmideaacfanlow_2044',['kMideaACFanLow',['../ir__Midea_8h.html#a90ebe3812e8b554798a2083ddfe9fdff',1,'ir_Midea.h']]], + ['kmideaacfanmed_2045',['kMideaACFanMed',['../ir__Midea_8h.html#a9406c8d9ad79e6a121a29cd5455e8e7d',1,'ir_Midea.h']]], + ['kmideaacfanoffset_2046',['kMideaACFanOffset',['../ir__Midea_8h.html#ac210e7bed85ad46cef1fa15a71d8e4c9',1,'ir_Midea.h']]], + ['kmideaacfansize_2047',['kMideaACFanSize',['../ir__Midea_8h.html#ab2726e607d432d00b625471d51b71b21',1,'ir_Midea.h']]], + ['kmideaacheat_2048',['kMideaACHeat',['../ir__Midea_8h.html#aa0fb74d8406327a9510f0efa8a16a488',1,'ir_Midea.h']]], + ['kmideaacmaxtempc_2049',['kMideaACMaxTempC',['../ir__Midea_8h.html#a0cccc3093cffabe1e512f298c04b3ba1',1,'ir_Midea.h']]], + ['kmideaacmaxtempf_2050',['kMideaACMaxTempF',['../ir__Midea_8h.html#ac7306c86080e934055d5be9728c91629',1,'ir_Midea.h']]], + ['kmideaacmintempc_2051',['kMideaACMinTempC',['../ir__Midea_8h.html#ae849eb79db6c077d617283154edade84',1,'ir_Midea.h']]], + ['kmideaacmintempf_2052',['kMideaACMinTempF',['../ir__Midea_8h.html#a0b0bdf519164f793a129d0e32152069a',1,'ir_Midea.h']]], + ['kmideaacmodeoffset_2053',['kMideaACModeOffset',['../ir__Midea_8h.html#a04fb535d82fe9d44d6898dd7c2e3491e',1,'ir_Midea.h']]], + ['kmideaacpoweroffset_2054',['kMideaACPowerOffset',['../ir__Midea_8h.html#a299cd691572c33f5d4742a9c289c279c',1,'ir_Midea.h']]], + ['kmideaacsleepoffset_2055',['kMideaACSleepOffset',['../ir__Midea_8h.html#a3c968881e59795eadfcb991b36755494',1,'ir_Midea.h']]], + ['kmideaactempoffset_2056',['kMideaACTempOffset',['../ir__Midea_8h.html#aec7e9182f167eb9b094670cf9889a595',1,'ir_Midea.h']]], + ['kmideaactempsize_2057',['kMideaACTempSize',['../ir__Midea_8h.html#aad2041ff636467046b63ceeb9fdfaaea',1,'ir_Midea.h']]], + ['kmideaactoggleswingv_2058',['kMideaACToggleSwingV',['../ir__Midea_8h.html#a5420b72289d3ae99a6dbc5c94914c473',1,'ir_Midea.h']]], + ['kmideabitmark_2059',['kMideaBitMark',['../ir__Midea_8cpp.html#a39dc2d03456f67418519dc0f5efde7e0',1,'ir_Midea.cpp']]], + ['kmideabitmarkticks_2060',['kMideaBitMarkTicks',['../ir__Midea_8cpp.html#ac4d9b1460516aa19913b5bd328c1e176',1,'ir_Midea.cpp']]], + ['kmideabits_2061',['kMideaBits',['../IRremoteESP8266_8h.html#afc98096b1e2945e2eaeb07d70d511239',1,'IRremoteESP8266.h']]], + ['kmideahdrmark_2062',['kMideaHdrMark',['../ir__Midea_8cpp.html#adcaa1ad6e2ba1022f3c90266f4fd0378',1,'ir_Midea.cpp']]], + ['kmideahdrmarkticks_2063',['kMideaHdrMarkTicks',['../ir__Midea_8cpp.html#af63b6cfcc5dc3e501b61c0d55d678f9e',1,'ir_Midea.cpp']]], + ['kmideahdrspace_2064',['kMideaHdrSpace',['../ir__Midea_8cpp.html#a8676eda087a85f6639b547140496c12f',1,'ir_Midea.cpp']]], + ['kmideahdrspaceticks_2065',['kMideaHdrSpaceTicks',['../ir__Midea_8cpp.html#aad99b5d8361733a9ca662735783e061c',1,'ir_Midea.cpp']]], + ['kmideamingap_2066',['kMideaMinGap',['../ir__Midea_8cpp.html#ad9ed8fb4841654fa756614862ac63be7',1,'ir_Midea.cpp']]], + ['kmideamingapticks_2067',['kMideaMinGapTicks',['../ir__Midea_8cpp.html#accd4e69e8fe0957ba013b97879fb1120',1,'ir_Midea.cpp']]], + ['kmideaminrepeat_2068',['kMideaMinRepeat',['../IRremoteESP8266_8h.html#aa8876e8e177b8e71154f8cfb42b19160',1,'IRremoteESP8266.h']]], + ['kmideaonespace_2069',['kMideaOneSpace',['../ir__Midea_8cpp.html#aabe187743f36e664c6069b004e9a82f7',1,'ir_Midea.cpp']]], + ['kmideaonespaceticks_2070',['kMideaOneSpaceTicks',['../ir__Midea_8cpp.html#a2cf0d5df2e5a3d7b1d24fd25ae3d7453',1,'ir_Midea.cpp']]], + ['kmideatick_2071',['kMideaTick',['../ir__Midea_8cpp.html#a878185258a4174978b072ac36aa377e2',1,'ir_Midea.cpp']]], + ['kmideatolerance_2072',['kMideaTolerance',['../ir__Midea_8cpp.html#a55553c3b8e7997fb1257ac2a37a929b6',1,'ir_Midea.cpp']]], + ['kmideazerospace_2073',['kMideaZeroSpace',['../ir__Midea_8cpp.html#a107d1d062e8475b84ec4ab548c3f01ef',1,'ir_Midea.cpp']]], + ['kmideazerospaceticks_2074',['kMideaZeroSpaceTicks',['../ir__Midea_8cpp.html#acd6580988c12ef5614727dd4d1b4c92d',1,'ir_Midea.cpp']]], + ['kmidstr_2075',['kMidStr',['../IRtext_8cpp.html#afd827d424c0bfdcc34b3607440fd2652',1,'kMidStr(): IRtext.cpp'],['../IRtext_8h.html#a571a28fe4174574caac4d93fb09ae196',1,'kMidStr(): IRtext.cpp']]], + ['kmin_2076',['kMin',['../namespacestdAc.html#a8bb0dbf18fe69f639f4ac0b3ff133383a8fbc2f6c44a6d70550df79903eb57d48',1,'stdAc']]], + ['kminimumstr_2077',['kMinimumStr',['../IRtext_8cpp.html#acbd869e5978b6fee053d33d8cf21e11a',1,'kMinimumStr(): IRtext.cpp'],['../IRtext_8h.html#a4f6fee52ae5f7f9c8fe791dbae762607',1,'kMinimumStr(): IRtext.cpp']]], + ['kminstr_2078',['kMinStr',['../IRtext_8cpp.html#a2b0c7369c1a93b8a7d5a87bf37fcee34',1,'kMinStr(): IRtext.cpp'],['../IRtext_8h.html#a4940a3f71a484f936d3e58b9573931a8',1,'kMinStr(): IRtext.cpp']]], + ['kminutesstr_2079',['kMinutesStr',['../IRtext_8cpp.html#a1c05b3e6af04586a0060c58979df002f',1,'kMinutesStr(): IRtext.cpp'],['../IRtext_8h.html#a3358666a695e8d54c23b20dc6a371a38',1,'kMinutesStr(): IRtext.cpp']]], + ['kminutestr_2080',['kMinuteStr',['../IRtext_8cpp.html#acab620931ba510a7bc395bad59169099',1,'kMinuteStr(): IRtext.cpp'],['../IRtext_8h.html#a54df015b1adadb211a30f826999c78f6',1,'kMinuteStr(): IRtext.cpp']]], + ['kmitsubishi112auto_2081',['kMitsubishi112Auto',['../ir__Mitsubishi_8h.html#a6e38f06ff78e3406a4f2cf1e1b453402',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112bitmark_2082',['kMitsubishi112BitMark',['../ir__Mitsubishi_8cpp.html#aef96bbd77d5bd66ed220840c09f54c37',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi112bits_2083',['kMitsubishi112Bits',['../IRremoteESP8266_8h.html#ae8349abe183be965e3d051cb736773a8',1,'IRremoteESP8266.h']]], + ['kmitsubishi112cool_2084',['kMitsubishi112Cool',['../ir__Mitsubishi_8h.html#aa9d1a63a8a275cda1794628f8d516963',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112dry_2085',['kMitsubishi112Dry',['../ir__Mitsubishi_8h.html#a4a3023d0342003b7947b19c9c5c25fb3',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112fanbyte_2086',['kMitsubishi112FanByte',['../ir__Mitsubishi_8h.html#a4312828eb864a67f8cc67a90c1324d3a',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112fanlow_2087',['kMitsubishi112FanLow',['../ir__Mitsubishi_8h.html#a4b8d6d04bb75ed98f6ed5bdff7472f50',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112fanmax_2088',['kMitsubishi112FanMax',['../ir__Mitsubishi_8h.html#a5a3e7c72ed85864b34f8ee298b3adc49',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112fanmed_2089',['kMitsubishi112FanMed',['../ir__Mitsubishi_8h.html#aa8a81057eeccbf528962b31a197b0319',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112fanmin_2090',['kMitsubishi112FanMin',['../ir__Mitsubishi_8h.html#ad8b101130e781d30b5d4072b3c514c78',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112fanoffset_2091',['kMitsubishi112FanOffset',['../ir__Mitsubishi_8h.html#ac000e0d3a59314c115e516f37c29983d',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112fanquiet_2092',['kMitsubishi112FanQuiet',['../ir__Mitsubishi_8h.html#addcf7a99c5ba2f4510754d22a4c0760f',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112fansize_2093',['kMitsubishi112FanSize',['../ir__Mitsubishi_8h.html#ab102138f689d66c2c4c97445931f2dec',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112gap_2094',['kMitsubishi112Gap',['../ir__Mitsubishi_8cpp.html#ab24cc7d395c1620b9519b5d0ce2a2023',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi112hdrmark_2095',['kMitsubishi112HdrMark',['../ir__Mitsubishi_8cpp.html#a3082567d58d6f8e6ef26714ff23f3728',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi112hdrmarktolerance_2096',['kMitsubishi112HdrMarkTolerance',['../ir__Mitsubishi_8cpp.html#a288931e01f8cffa1917fb7bc59710e20',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi112hdrspace_2097',['kMitsubishi112HdrSpace',['../ir__Mitsubishi_8cpp.html#a7b35ecbbc94f7ef622b20f21f83c0fba',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi112heat_2098',['kMitsubishi112Heat',['../ir__Mitsubishi_8h.html#a260b6883e9433b466abf31618b1c4015',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112maxtemp_2099',['kMitsubishi112MaxTemp',['../ir__Mitsubishi_8h.html#afd968ea297ef8856b7266a8cc6e1bba0',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112minrepeat_2100',['kMitsubishi112MinRepeat',['../IRremoteESP8266_8h.html#a6bba58bb0f33feb9a6dfd20637d01d13',1,'IRremoteESP8266.h']]], + ['kmitsubishi112mintemp_2101',['kMitsubishi112MinTemp',['../ir__Mitsubishi_8h.html#acea288a8911a540cb9602d057eccb2a6',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112modebyte_2102',['kMitsubishi112ModeByte',['../ir__Mitsubishi_8h.html#a7e7663483fa89b4283baafba744d707a',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112modeoffset_2103',['kMitsubishi112ModeOffset',['../ir__Mitsubishi_8h.html#a39c8631bfd414738f1934eb28e74b97b',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112onespace_2104',['kMitsubishi112OneSpace',['../ir__Mitsubishi_8cpp.html#a8dd0d824826a7da007e78741015d418a',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi112powerbyte_2105',['kMitsubishi112PowerByte',['../ir__Mitsubishi_8h.html#ab09f78fee2a242dfdb0318a4caf7a2d6',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112poweroffset_2106',['kMitsubishi112PowerOffset',['../ir__Mitsubishi_8h.html#afd78de91190fa6ec8ffcc9132e3a8b35',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112statelength_2107',['kMitsubishi112StateLength',['../IRremoteESP8266_8h.html#a5ff0437b26e325bc2516a3e63c7ffe76',1,'IRremoteESP8266.h']]], + ['kmitsubishi112swinghauto_2108',['kMitsubishi112SwingHAuto',['../ir__Mitsubishi_8h.html#ab55e72c6d2b407868cda075efb24ac92',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swinghbyte_2109',['kMitsubishi112SwingHByte',['../ir__Mitsubishi_8h.html#ac149161c62c9ceee1c3a37d73930a7e8',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swinghleft_2110',['kMitsubishi112SwingHLeft',['../ir__Mitsubishi_8h.html#a8299b42b0972bda8a4bc4f32527c33e9',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swinghleftmax_2111',['kMitsubishi112SwingHLeftMax',['../ir__Mitsubishi_8h.html#a48346e97056af670454bc77a64b904bc',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swinghmiddle_2112',['kMitsubishi112SwingHMiddle',['../ir__Mitsubishi_8h.html#a7adcab7d152d84adef2059339de4bb40',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swinghoffset_2113',['kMitsubishi112SwingHOffset',['../ir__Mitsubishi_8h.html#a42f92264157e170d68046b9970a057ed',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swinghright_2114',['kMitsubishi112SwingHRight',['../ir__Mitsubishi_8h.html#a76cf277572a2b628d4a5353186ca2522',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swinghrightmax_2115',['kMitsubishi112SwingHRightMax',['../ir__Mitsubishi_8h.html#a1ff73f603b6e32075cbc9253d3090b49',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swinghsize_2116',['kMitsubishi112SwingHSize',['../ir__Mitsubishi_8h.html#a9ab977dbab987789d40fae38212f07ba',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swinghwide_2117',['kMitsubishi112SwingHWide',['../ir__Mitsubishi_8h.html#afab80db45769ab2957afc0e4799b46e5',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swingvauto_2118',['kMitsubishi112SwingVAuto',['../ir__Mitsubishi_8h.html#a1e16b172e864a74b426b1f823770cdaa',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swingvbyte_2119',['kMitsubishi112SwingVByte',['../ir__Mitsubishi_8h.html#afbcd99e59a029ccc6276c87a46d560dd',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swingvhigh_2120',['kMitsubishi112SwingVHigh',['../ir__Mitsubishi_8h.html#ab6e345e609d72f9ed903e30f3aa9a26f',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swingvhighest_2121',['kMitsubishi112SwingVHighest',['../ir__Mitsubishi_8h.html#a1cb8c62990dfb98a8ea228ad59cd88e5',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swingvlow_2122',['kMitsubishi112SwingVLow',['../ir__Mitsubishi_8h.html#a515bea322889f619d64ae96c37eaba72',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swingvlowest_2123',['kMitsubishi112SwingVLowest',['../ir__Mitsubishi_8h.html#ac4dd729a11e3ece244df6b1ddc9250f8',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swingvmiddle_2124',['kMitsubishi112SwingVMiddle',['../ir__Mitsubishi_8h.html#a0ae62480999dc4cf8a223b59938a0d68',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swingvoffset_2125',['kMitsubishi112SwingVOffset',['../ir__Mitsubishi_8h.html#ae4f3919271bb464d90a42066e8052c64',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swingvsize_2126',['kMitsubishi112SwingVSize',['../ir__Mitsubishi_8h.html#ae4f466b64691d8aa20e66a982d65ceea',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112tempbyte_2127',['kMitsubishi112TempByte',['../ir__Mitsubishi_8h.html#a4099370512a63ae3414221ab45f05034',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112tempsize_2128',['kMitsubishi112TempSize',['../ir__Mitsubishi_8h.html#a30d0ece1b7db3558ecc03214843c9fec',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112zerospace_2129',['kMitsubishi112ZeroSpace',['../ir__Mitsubishi_8cpp.html#ad70d1567dc2e4ea07a247f2555fc23b4',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi136auto_2130',['kMitsubishi136Auto',['../ir__Mitsubishi_8h.html#ae10977a0d09f4c583b03fa05720c3aed',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136bitmark_2131',['kMitsubishi136BitMark',['../ir__Mitsubishi_8cpp.html#a3aa9c715088a58a8b4a97d5038dbf6d4',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi136bits_2132',['kMitsubishi136Bits',['../IRremoteESP8266_8h.html#aa19f0122b2f906e5473a6ea232c38974',1,'IRremoteESP8266.h']]], + ['kmitsubishi136cool_2133',['kMitsubishi136Cool',['../ir__Mitsubishi_8h.html#a93332579055a07ea291b3caf9ad11944',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136dry_2134',['kMitsubishi136Dry',['../ir__Mitsubishi_8h.html#ad612c480e8664169e2b8e062d47bd8b9',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136fan_2135',['kMitsubishi136Fan',['../ir__Mitsubishi_8h.html#a4445944955b9017fcd6d1ae447f1b0d7',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136fanbyte_2136',['kMitsubishi136FanByte',['../ir__Mitsubishi_8h.html#a62166a745fdf0bbbd4b0eb114073b03e',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136fanlow_2137',['kMitsubishi136FanLow',['../ir__Mitsubishi_8h.html#af0f7177491c4cb053e6811376be956ec',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136fanmax_2138',['kMitsubishi136FanMax',['../ir__Mitsubishi_8h.html#a43a4337e20fbf4f6747a58c15213bd16',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136fanmed_2139',['kMitsubishi136FanMed',['../ir__Mitsubishi_8h.html#a73ff7df8fe65829cfd5875dc5040dec7',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136fanmin_2140',['kMitsubishi136FanMin',['../ir__Mitsubishi_8h.html#a2623eaf6e7d2ceb20ee72faddf46569e',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136fanoffset_2141',['kMitsubishi136FanOffset',['../ir__Mitsubishi_8h.html#aaa194e1e4394d3805477f4b2b78d3a81',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136fanquiet_2142',['kMitsubishi136FanQuiet',['../ir__Mitsubishi_8h.html#af2f7483bbb99216614e01dd5aedc35d5',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136fansize_2143',['kMitsubishi136FanSize',['../ir__Mitsubishi_8h.html#a3fa7836f102aa9c78d7dd287a038baee',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136gap_2144',['kMitsubishi136Gap',['../ir__Mitsubishi_8cpp.html#a3f9e0708bbe8ed3ff98a563c3ff1af2b',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi136hdrmark_2145',['kMitsubishi136HdrMark',['../ir__Mitsubishi_8cpp.html#a49c54ff757d070de54e3739b775bea00',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi136hdrspace_2146',['kMitsubishi136HdrSpace',['../ir__Mitsubishi_8cpp.html#a1ddd09e423c427b3956298c20725188a',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi136heat_2147',['kMitsubishi136Heat',['../ir__Mitsubishi_8h.html#a932f074e9348d35cea119c8141eeb7f2',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136maxtemp_2148',['kMitsubishi136MaxTemp',['../ir__Mitsubishi_8h.html#a2db420b28003dc3e05bf1c86830c61ed',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136minrepeat_2149',['kMitsubishi136MinRepeat',['../IRremoteESP8266_8h.html#a448bd7af5fdab67fb40901a3d6efed21',1,'IRremoteESP8266.h']]], + ['kmitsubishi136mintemp_2150',['kMitsubishi136MinTemp',['../ir__Mitsubishi_8h.html#a5e2e5783d33f927f941271a44d11434c',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136modebyte_2151',['kMitsubishi136ModeByte',['../ir__Mitsubishi_8h.html#a98fbde8559e82a1875235019913e859c',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136modeoffset_2152',['kMitsubishi136ModeOffset',['../ir__Mitsubishi_8h.html#a061d59096df59826d951e83594728893',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136onespace_2153',['kMitsubishi136OneSpace',['../ir__Mitsubishi_8cpp.html#a9a0cfee8b6ea94d3f798d53d30c99d5f',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi136powerbit_2154',['kMitsubishi136PowerBit',['../ir__Mitsubishi_8h.html#abbe2f7821db2a6f4696cf7f9138c509d',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136powerbyte_2155',['kMitsubishi136PowerByte',['../ir__Mitsubishi_8h.html#aca06b9d066d3f1a322bbb0f3d1a874a7',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136poweroffset_2156',['kMitsubishi136PowerOffset',['../ir__Mitsubishi_8h.html#ad235f31bc4b42548373c15e18f29e8b1',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136statelength_2157',['kMitsubishi136StateLength',['../IRremoteESP8266_8h.html#a01adbe4e1afb2ba26a5a60bf5b0b42f6',1,'IRremoteESP8266.h']]], + ['kmitsubishi136swingvauto_2158',['kMitsubishi136SwingVAuto',['../ir__Mitsubishi_8h.html#a828c2cc017cb7d00872137464d2119ae',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136swingvbyte_2159',['kMitsubishi136SwingVByte',['../ir__Mitsubishi_8h.html#ab31414515f89e94ec8b63028e215b5ad',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136swingvhigh_2160',['kMitsubishi136SwingVHigh',['../ir__Mitsubishi_8h.html#a319b36df23511aba8fb16b13eda9333b',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136swingvhighest_2161',['kMitsubishi136SwingVHighest',['../ir__Mitsubishi_8h.html#a5bd1dbb97df91dfec0f9493120ea1269',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136swingvlow_2162',['kMitsubishi136SwingVLow',['../ir__Mitsubishi_8h.html#a1ba4f3f7eb75bb54a752cfb11f196af0',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136swingvlowest_2163',['kMitsubishi136SwingVLowest',['../ir__Mitsubishi_8h.html#ab0701f0127b07780066040bc08e46a2e',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136tempbyte_2164',['kMitsubishi136TempByte',['../ir__Mitsubishi_8h.html#a22bf24adb745489a75fb877fa5cc249a',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136zerospace_2165',['kMitsubishi136ZeroSpace',['../ir__Mitsubishi_8cpp.html#afaf1eca1169f492dcdd8a7266756c827',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi2bitmark_2166',['kMitsubishi2BitMark',['../ir__Mitsubishi_8cpp.html#a8b0e87a15c51c3b62c14b4e7a071207f',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi2hdrmark_2167',['kMitsubishi2HdrMark',['../ir__Mitsubishi_8cpp.html#a2d838e748f1f69165fb6b672955ea95e',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi2hdrspace_2168',['kMitsubishi2HdrSpace',['../ir__Mitsubishi_8cpp.html#acd8994a08389c8d874afcbb8eb9c0861',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi2mingap_2169',['kMitsubishi2MinGap',['../ir__Mitsubishi_8cpp.html#a7fa283a14968b582123a474c86a6fde9',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi2onespace_2170',['kMitsubishi2OneSpace',['../ir__Mitsubishi_8cpp.html#aeee614cef3e95f661dca95b344edcf64',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi2zerospace_2171',['kMitsubishi2ZeroSpace',['../ir__Mitsubishi_8cpp.html#a665522ccd10f4c9fba39e3f8f8a5cb95',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishiacauto_2172',['kMitsubishiAcAuto',['../ir__Mitsubishi_8h.html#a1fdbdc0906594e0efebbd05110877000',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacbitmark_2173',['kMitsubishiAcBitMark',['../ir__Mitsubishi_8cpp.html#a3787c48ffff208ef964886efab7e17ca',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishiacbits_2174',['kMitsubishiACBits',['../IRremoteESP8266_8h.html#a911a47148656b26da2e094a7ced1fc8b',1,'IRremoteESP8266.h']]], + ['kmitsubishiaccool_2175',['kMitsubishiAcCool',['../ir__Mitsubishi_8h.html#a434455f6c76f0ca354b01e6a8a6479e9',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacdry_2176',['kMitsubishiAcDry',['../ir__Mitsubishi_8h.html#a9875c4b91a1b155b5f2e12370c33e031',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacextratolerance_2177',['kMitsubishiAcExtraTolerance',['../ir__Mitsubishi_8cpp.html#a98a0e4182311d584d4de4632eb491f04',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishiacfanauto_2178',['kMitsubishiAcFanAuto',['../ir__Mitsubishi_8h.html#a302cfd0468875cff23c69f71c392ad36',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacfanautooffset_2179',['kMitsubishiAcFanAutoOffset',['../ir__Mitsubishi_8h.html#ab8696268b90bf45314d712c212d68a10',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacfanmax_2180',['kMitsubishiAcFanMax',['../ir__Mitsubishi_8h.html#abbc2b87dfc6b2364d065f66f4d3e540c',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacfanoffset_2181',['kMitsubishiAcFanOffset',['../ir__Mitsubishi_8h.html#ac16a5f7fe9800006de4511fd4ac89d64',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacfanquiet_2182',['kMitsubishiAcFanQuiet',['../ir__Mitsubishi_8h.html#a90799250620dec05385b9e81cfcb83af',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacfanrealmax_2183',['kMitsubishiAcFanRealMax',['../ir__Mitsubishi_8h.html#aa28f81fbd686adb082786e7cda9a17fc',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacfansilent_2184',['kMitsubishiAcFanSilent',['../ir__Mitsubishi_8h.html#a731206548afa4f2672a78dae677f6b44',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacfansize_2185',['kMitsubishiAcFanSize',['../ir__Mitsubishi_8h.html#a565c641228d28357282b211048f1bd1c',1,'ir_Mitsubishi.h']]], + ['kmitsubishiachdrmark_2186',['kMitsubishiAcHdrMark',['../ir__Mitsubishi_8cpp.html#a11fcb08ce6bf9fa5fc50ca0e5c7d2d64',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishiachdrspace_2187',['kMitsubishiAcHdrSpace',['../ir__Mitsubishi_8cpp.html#af0af560129a4666aeba1a4a9ab59e271',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishiacheat_2188',['kMitsubishiAcHeat',['../ir__Mitsubishi_8h.html#a6107df195ecf54ec4ef97b5ab82e911c',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacmaxtemp_2189',['kMitsubishiAcMaxTemp',['../ir__Mitsubishi_8h.html#a8ba3fba3eb9dd63f5ade3cb3bd11269b',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacminrepeat_2190',['kMitsubishiACMinRepeat',['../IRremoteESP8266_8h.html#a376653a421df42d889ac3b2a071de58b',1,'IRremoteESP8266.h']]], + ['kmitsubishiacmintemp_2191',['kMitsubishiAcMinTemp',['../ir__Mitsubishi_8h.html#a2d6d53ccf446fcb03331f4e9757f4169',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacmodeoffset_2192',['kMitsubishiAcModeOffset',['../ir__Mitsubishi_8h.html#ac0037c13e3f90b7bde5a8328faaa3b9b',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacnotimer_2193',['kMitsubishiAcNoTimer',['../ir__Mitsubishi_8h.html#a0f5da97478cd6cdf2ffab161657e4ab6',1,'ir_Mitsubishi.h']]], + ['kmitsubishiaconespace_2194',['kMitsubishiAcOneSpace',['../ir__Mitsubishi_8cpp.html#abdf26b381c5288556257fabf43458775',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishiacpower_2195',['kMitsubishiAcPower',['../ir__Mitsubishi_8h.html#a864c4d936663d68f65ed4525072bd3eb',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacpoweroffset_2196',['kMitsubishiAcPowerOffset',['../ir__Mitsubishi_8h.html#a78749519549fb76a920ca447a4504e72',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacrptmark_2197',['kMitsubishiAcRptMark',['../ir__Mitsubishi_8cpp.html#a541d764aef906909a1a0d40466567c92',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishiacrptspace_2198',['kMitsubishiAcRptSpace',['../ir__Mitsubishi_8cpp.html#a4b120db1bd34c62778597abf05092d0a',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishiacstartstoptimer_2199',['kMitsubishiAcStartStopTimer',['../ir__Mitsubishi_8h.html#aecbdc43fb4bd199c47cb5125816eab59',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacstarttimer_2200',['kMitsubishiAcStartTimer',['../ir__Mitsubishi_8h.html#a4107cbc35f18204f46adb57b0fd0f09c',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacstatelength_2201',['kMitsubishiACStateLength',['../IRremoteESP8266_8h.html#a7d0d6dd6d5741f91a1afb641f11d9bc5',1,'IRremoteESP8266.h']]], + ['kmitsubishiacstoptimer_2202',['kMitsubishiAcStopTimer',['../ir__Mitsubishi_8h.html#a5e59039d523d15b145aa87222d52f2bf',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacvaneauto_2203',['kMitsubishiAcVaneAuto',['../ir__Mitsubishi_8h.html#a1caff28ea3678cc5f655fc7147c5a15e',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacvaneautomove_2204',['kMitsubishiAcVaneAutoMove',['../ir__Mitsubishi_8h.html#a2dc0b1ff66ffc21f626d7d8894a31fbb',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacvanebitoffset_2205',['kMitsubishiAcVaneBitOffset',['../ir__Mitsubishi_8h.html#a0766870a9709320cfff03d0147f8e414',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacvaneoffset_2206',['kMitsubishiAcVaneOffset',['../ir__Mitsubishi_8h.html#a2e928c1f814b71a1c346b3e987d7b857',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacvanesize_2207',['kMitsubishiAcVaneSize',['../ir__Mitsubishi_8h.html#a27d52c41a9309a89e3a2c45b87c501ff',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacwidevaneauto_2208',['kMitsubishiAcWideVaneAuto',['../ir__Mitsubishi_8h.html#a2081e2b8eb778e15b7d9f2f0f332c012',1,'ir_Mitsubishi.h']]], + ['kmitsubishiaczerospace_2209',['kMitsubishiAcZeroSpace',['../ir__Mitsubishi_8cpp.html#a9481515c349154bbb6f56cec2712ba85',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishibitmark_2210',['kMitsubishiBitMark',['../ir__Mitsubishi_8cpp.html#a82c8e081b172080df14bdd6e3e6eb608',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishibitmarkticks_2211',['kMitsubishiBitMarkTicks',['../ir__Mitsubishi_8cpp.html#a6daf88606f40b13bce698c73d00f5faf',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishibits_2212',['kMitsubishiBits',['../IRremoteESP8266_8h.html#abd2187340d0b94996136081413e2ad22',1,'IRremoteESP8266.h']]], + ['kmitsubishiheavy152bits_2213',['kMitsubishiHeavy152Bits',['../IRremoteESP8266_8h.html#ab973b35583dabc7e04b12018fac04cc9',1,'IRremoteESP8266.h']]], + ['kmitsubishiheavy152fanauto_2214',['kMitsubishiHeavy152FanAuto',['../ir__MitsubishiHeavy_8h.html#ae1739c1b5cd00b28a06dfd96413570a8',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152fanecono_2215',['kMitsubishiHeavy152FanEcono',['../ir__MitsubishiHeavy_8h.html#acf0522589438103f805889e980259eb8',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152fanhigh_2216',['kMitsubishiHeavy152FanHigh',['../ir__MitsubishiHeavy_8h.html#a48881ddd596b6945d04465b3f7a9bee6',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152fanlow_2217',['kMitsubishiHeavy152FanLow',['../ir__MitsubishiHeavy_8h.html#acff7254b2ced32550ec9305dbaac3d95',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152fanmax_2218',['kMitsubishiHeavy152FanMax',['../ir__MitsubishiHeavy_8h.html#aa1e9a41137a7dd65fc049ae41856795f',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152fanmed_2219',['kMitsubishiHeavy152FanMed',['../ir__MitsubishiHeavy_8h.html#ac432324a30abcc0e664cf0ff8e974516',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152fanturbo_2220',['kMitsubishiHeavy152FanTurbo',['../ir__MitsubishiHeavy_8h.html#a7665d1ecb52afabd0dd951f2ab54e59b',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152minrepeat_2221',['kMitsubishiHeavy152MinRepeat',['../IRremoteESP8266_8h.html#a789cbb74cf332f8440a4fcdcac188741',1,'IRremoteESP8266.h']]], + ['kmitsubishiheavy152statelength_2222',['kMitsubishiHeavy152StateLength',['../IRremoteESP8266_8h.html#a31d12a44c8c3a3c4533f65b8213e2086',1,'IRremoteESP8266.h']]], + ['kmitsubishiheavy152swinghauto_2223',['kMitsubishiHeavy152SwingHAuto',['../ir__MitsubishiHeavy_8h.html#ac0ed87ce67ece78e2e9f2b49da5ba152',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swinghleft_2224',['kMitsubishiHeavy152SwingHLeft',['../ir__MitsubishiHeavy_8h.html#a1a20549b529745e913565e6d717d9f95',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swinghleftmax_2225',['kMitsubishiHeavy152SwingHLeftMax',['../ir__MitsubishiHeavy_8h.html#a970e6b602f5bbd4d560249966f6de6c9',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swinghleftright_2226',['kMitsubishiHeavy152SwingHLeftRight',['../ir__MitsubishiHeavy_8h.html#a24c71dc5a17affb2f2d136f6846befbc',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swinghmiddle_2227',['kMitsubishiHeavy152SwingHMiddle',['../ir__MitsubishiHeavy_8h.html#af1a02e21631c1efb12a01b3db065916c',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swinghoff_2228',['kMitsubishiHeavy152SwingHOff',['../ir__MitsubishiHeavy_8h.html#a246f8f9c9083f21ee22c2367ece2b9e2',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swinghright_2229',['kMitsubishiHeavy152SwingHRight',['../ir__MitsubishiHeavy_8h.html#aeec05249b3958f5a1cd629b328209e05',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swinghrightleft_2230',['kMitsubishiHeavy152SwingHRightLeft',['../ir__MitsubishiHeavy_8h.html#a43ddc14cc8707aa9743519b1c54eb776',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swinghrightmax_2231',['kMitsubishiHeavy152SwingHRightMax',['../ir__MitsubishiHeavy_8h.html#ae825ed46bf143bc6a01891a5f021c870',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swingvauto_2232',['kMitsubishiHeavy152SwingVAuto',['../ir__MitsubishiHeavy_8h.html#a31c20346b5538d74b58cb1fd499b5751',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swingvhigh_2233',['kMitsubishiHeavy152SwingVHigh',['../ir__MitsubishiHeavy_8h.html#a9ac8e39e46b43fb2276af7dd9724e3d4',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swingvhighest_2234',['kMitsubishiHeavy152SwingVHighest',['../ir__MitsubishiHeavy_8h.html#a554efbb611fd29a5d388d8195aa79993',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swingvlow_2235',['kMitsubishiHeavy152SwingVLow',['../ir__MitsubishiHeavy_8h.html#ad9a0b57ba70d318572b77236c23830a7',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swingvlowest_2236',['kMitsubishiHeavy152SwingVLowest',['../ir__MitsubishiHeavy_8h.html#a02f1b980aa78b4ff314209d16bf0a6e8',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swingvmiddle_2237',['kMitsubishiHeavy152SwingVMiddle',['../ir__MitsubishiHeavy_8h.html#ae5c3ec8b8837dddff01d71c44a4ba813',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swingvoff_2238',['kMitsubishiHeavy152SwingVOff',['../ir__MitsubishiHeavy_8h.html#abb6905210a2f4021d157eeb61eaed7cd',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swingvoffset_2239',['kMitsubishiHeavy152SwingVOffset',['../ir__MitsubishiHeavy_8h.html#ae46f3549243667bbc38d6dc058772699',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swingvsize_2240',['kMitsubishiHeavy152SwingVSize',['../ir__MitsubishiHeavy_8h.html#a9cf7566686359cd5d553881b5eb96131',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy3dmask_2241',['kMitsubishiHeavy3DMask',['../ir__MitsubishiHeavy_8h.html#a16dcde537c9a2b1e8ddab4d6e08abb39',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88bits_2242',['kMitsubishiHeavy88Bits',['../IRremoteESP8266_8h.html#aa80d389140df4ab7071bfb3510b35dda',1,'IRremoteESP8266.h']]], + ['kmitsubishiheavy88cleanoffset_2243',['kMitsubishiHeavy88CleanOffset',['../ir__MitsubishiHeavy_8h.html#ac0a4108b9ce94b3a85c2cb9680c98f4e',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88fanauto_2244',['kMitsubishiHeavy88FanAuto',['../ir__MitsubishiHeavy_8h.html#a607cbc27223765b3dd1f9bfd77932d0f',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88fanecono_2245',['kMitsubishiHeavy88FanEcono',['../ir__MitsubishiHeavy_8h.html#ab5fbaaffd9e0182fc7e60252f89da2c3',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88fanhigh_2246',['kMitsubishiHeavy88FanHigh',['../ir__MitsubishiHeavy_8h.html#aa45b29aaa7d8df7a34dfe6308a6b6412',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88fanlow_2247',['kMitsubishiHeavy88FanLow',['../ir__MitsubishiHeavy_8h.html#a92f0cba1aef78e5ade01c648837e7553',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88fanmed_2248',['kMitsubishiHeavy88FanMed',['../ir__MitsubishiHeavy_8h.html#aade681ee8ed4c4647a997a3caad093ea',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88fanoffset_2249',['kMitsubishiHeavy88FanOffset',['../ir__MitsubishiHeavy_8h.html#a477fe23b5b186f4386e5d0cbded98710',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88fansize_2250',['kMitsubishiHeavy88FanSize',['../ir__MitsubishiHeavy_8h.html#a68ffc738a040b3c95a839362e069fe8a',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88fanturbo_2251',['kMitsubishiHeavy88FanTurbo',['../ir__MitsubishiHeavy_8h.html#a29201ebd9395edb2660337ee00efa1dd',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88minrepeat_2252',['kMitsubishiHeavy88MinRepeat',['../IRremoteESP8266_8h.html#ad7bccde1a9b32c962c99748fb130f711',1,'IRremoteESP8266.h']]], + ['kmitsubishiheavy88statelength_2253',['kMitsubishiHeavy88StateLength',['../IRremoteESP8266_8h.html#a515e5a081c388dd4313b20ff2b6c7955',1,'IRremoteESP8266.h']]], + ['kmitsubishiheavy88swingh3d_2254',['kMitsubishiHeavy88SwingH3D',['../ir__MitsubishiHeavy_8h.html#adfeb87be0ddfc6c06bbcb4a1506d3185',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghauto_2255',['kMitsubishiHeavy88SwingHAuto',['../ir__MitsubishiHeavy_8h.html#ac39f2339ab90bdc6d9c98dd6cf95fce2',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghleft_2256',['kMitsubishiHeavy88SwingHLeft',['../ir__MitsubishiHeavy_8h.html#a32a76b07c6da2b09d04d985544d91af1',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghleftmax_2257',['kMitsubishiHeavy88SwingHLeftMax',['../ir__MitsubishiHeavy_8h.html#a83340e32cff8ca09eb7596ec55a67853',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghleftright_2258',['kMitsubishiHeavy88SwingHLeftRight',['../ir__MitsubishiHeavy_8h.html#a82f7addc930441b6e756d71ce3df24ca',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghmiddle_2259',['kMitsubishiHeavy88SwingHMiddle',['../ir__MitsubishiHeavy_8h.html#a7a4b00b2953f2bc068d83c2618484c69',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghoff_2260',['kMitsubishiHeavy88SwingHOff',['../ir__MitsubishiHeavy_8h.html#a5313aeb4115ca5a795c6ebb9871ce436',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghoffset1_2261',['kMitsubishiHeavy88SwingHOffset1',['../ir__MitsubishiHeavy_8h.html#aeefa28e96d259e4ad5b63b86abf46f39',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghoffset2_2262',['kMitsubishiHeavy88SwingHOffset2',['../ir__MitsubishiHeavy_8h.html#a9efbee563f821dad4006e8c56de9131d',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghright_2263',['kMitsubishiHeavy88SwingHRight',['../ir__MitsubishiHeavy_8h.html#a35224e254d897b9d42e16f9dae04d984',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghrightleft_2264',['kMitsubishiHeavy88SwingHRightLeft',['../ir__MitsubishiHeavy_8h.html#aa913c0f1c61260c533c66aaa12dc83ac',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghrightmax_2265',['kMitsubishiHeavy88SwingHRightMax',['../ir__MitsubishiHeavy_8h.html#a83c481d42999e377a2c50cacc28017b0',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghsize_2266',['kMitsubishiHeavy88SwingHSize',['../ir__MitsubishiHeavy_8h.html#a46a3cb1874cf5d1875e971094527b98f',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvauto_2267',['kMitsubishiHeavy88SwingVAuto',['../ir__MitsubishiHeavy_8h.html#a65c66f030afd2795d3132b3d0be2cabe',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvbyte5offset_2268',['kMitsubishiHeavy88SwingVByte5Offset',['../ir__MitsubishiHeavy_8h.html#adab63d1b0145cbea0953a9fdd34fd3cf',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvbyte5size_2269',['kMitsubishiHeavy88SwingVByte5Size',['../ir__MitsubishiHeavy_8h.html#ae0569562330f8c2af57a78764341c310',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvbyte7offset_2270',['kMitsubishiHeavy88SwingVByte7Offset',['../ir__MitsubishiHeavy_8h.html#a8e864258ce7f01edb3b8d4672bba6312',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvbyte7size_2271',['kMitsubishiHeavy88SwingVByte7Size',['../ir__MitsubishiHeavy_8h.html#a2e0d599b002366cc73d07f876d4fc0f7',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvhigh_2272',['kMitsubishiHeavy88SwingVHigh',['../ir__MitsubishiHeavy_8h.html#af99a8f0925f184f56080ddf3e9a37606',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvhighest_2273',['kMitsubishiHeavy88SwingVHighest',['../ir__MitsubishiHeavy_8h.html#adc2a20b5ca5dda6417c60a1a3c321fc0',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvlow_2274',['kMitsubishiHeavy88SwingVLow',['../ir__MitsubishiHeavy_8h.html#adb086c76e06cbf6c8808470363da5e93',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvlowest_2275',['kMitsubishiHeavy88SwingVLowest',['../ir__MitsubishiHeavy_8h.html#a6f4af31ee9b187648c242aca2851d3ed',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvmiddle_2276',['kMitsubishiHeavy88SwingVMiddle',['../ir__MitsubishiHeavy_8h.html#aeaddb1d80dd777c0fdd8e77661479598',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvoff_2277',['kMitsubishiHeavy88SwingVOff',['../ir__MitsubishiHeavy_8h.html#ad29f5b94153e0fc9943a2c4c02aa1f61',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavyauto_2278',['kMitsubishiHeavyAuto',['../ir__MitsubishiHeavy_8h.html#a1bcb7429a89904e3b431aaaff20e35fa',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavybitmark_2279',['kMitsubishiHeavyBitMark',['../ir__MitsubishiHeavy_8cpp.html#a54b398e130a1893bdc81067c636d6001',1,'ir_MitsubishiHeavy.cpp']]], + ['kmitsubishiheavycleanoffset_2280',['kMitsubishiHeavyCleanOffset',['../ir__MitsubishiHeavy_8h.html#acbcff6b22bf5dee4eeb1dbccc323409a',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavycool_2281',['kMitsubishiHeavyCool',['../ir__MitsubishiHeavy_8h.html#a5d819a9a6372fde79380a6890ffd3168',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavydry_2282',['kMitsubishiHeavyDry',['../ir__MitsubishiHeavy_8h.html#a749f4d74b6cce4ad29a7ab78bb780eaf',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavyfan_2283',['kMitsubishiHeavyFan',['../ir__MitsubishiHeavy_8h.html#a55d9e0b9676da64dfdc888e7941665f8',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavyfilteroffset_2284',['kMitsubishiHeavyFilterOffset',['../ir__MitsubishiHeavy_8h.html#a32232c193503a4a6bab8f783fdebeddf',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavygap_2285',['kMitsubishiHeavyGap',['../ir__MitsubishiHeavy_8cpp.html#a92920bf4a95bccb9b55c623ff6dac96a',1,'ir_MitsubishiHeavy.cpp']]], + ['kmitsubishiheavyhdrmark_2286',['kMitsubishiHeavyHdrMark',['../ir__MitsubishiHeavy_8cpp.html#a9b1724efadc251117733297c424e76f4',1,'ir_MitsubishiHeavy.cpp']]], + ['kmitsubishiheavyhdrspace_2287',['kMitsubishiHeavyHdrSpace',['../ir__MitsubishiHeavy_8cpp.html#a9070250903c1d1653beb54ac3de27033',1,'ir_MitsubishiHeavy.cpp']]], + ['kmitsubishiheavyheat_2288',['kMitsubishiHeavyHeat',['../ir__MitsubishiHeavy_8h.html#a0b76a854d109dd0622155015edd31d74',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavymaxtemp_2289',['kMitsubishiHeavyMaxTemp',['../ir__MitsubishiHeavy_8h.html#a49abbf34671b67eb4ebbe881444180f4',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavymintemp_2290',['kMitsubishiHeavyMinTemp',['../ir__MitsubishiHeavy_8h.html#afa83fd435c67699da272b883277dbb98',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavymodeoffset_2291',['kMitsubishiHeavyModeOffset',['../ir__MitsubishiHeavy_8h.html#a2ac27d9659d3a203c8cc360bda901d10',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavynightoffset_2292',['kMitsubishiHeavyNightOffset',['../ir__MitsubishiHeavy_8h.html#a01b341211034e272bf5d4be00b88cc78',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavyonespace_2293',['kMitsubishiHeavyOneSpace',['../ir__MitsubishiHeavy_8cpp.html#adec6564e4af2886b4c7d44343d98b9dc',1,'ir_MitsubishiHeavy.cpp']]], + ['kmitsubishiheavypoweroffset_2294',['kMitsubishiHeavyPowerOffset',['../ir__MitsubishiHeavy_8h.html#a51d81b3a7d97e423858e00aecd9719c9',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavysiglength_2295',['kMitsubishiHeavySigLength',['../ir__MitsubishiHeavy_8h.html#af08e6fc65b10821e52dd4a0073033d14',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavysilentoffset_2296',['kMitsubishiHeavySilentOffset',['../ir__MitsubishiHeavy_8h.html#a9b7eb89d7a3f08e84339317d1f21ca6f',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavyzerospace_2297',['kMitsubishiHeavyZeroSpace',['../ir__MitsubishiHeavy_8cpp.html#a903c30cee53f76c7dc3d2fef74b6e4b2',1,'ir_MitsubishiHeavy.cpp']]], + ['kmitsubishiheavyzjssig_2298',['kMitsubishiHeavyZjsSig',['../ir__MitsubishiHeavy_8h.html#a01eb89bfc9d4b271a97fea566eb937ff',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavyzmssig_2299',['kMitsubishiHeavyZmsSig',['../ir__MitsubishiHeavy_8h.html#a18761991123d121c8d40531d07922165',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishimincommandlength_2300',['kMitsubishiMinCommandLength',['../ir__Mitsubishi_8cpp.html#ad5a6d37e755ce1faa4cdb024d2bed26a',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishimincommandlengthticks_2301',['kMitsubishiMinCommandLengthTicks',['../ir__Mitsubishi_8cpp.html#a4f69a50c720c7a19f0ee04d262eb5948',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishimingap_2302',['kMitsubishiMinGap',['../ir__Mitsubishi_8cpp.html#a66f6379ca4c0e5f03eda2d81be0a35b2',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishimingapticks_2303',['kMitsubishiMinGapTicks',['../ir__Mitsubishi_8cpp.html#af9e8409306344cf4cd0117f2131fc67a',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishiminrepeat_2304',['kMitsubishiMinRepeat',['../IRremoteESP8266_8h.html#ad88bda81b48f25d30bb5a169d3b6bcec',1,'IRremoteESP8266.h']]], + ['kmitsubishionespace_2305',['kMitsubishiOneSpace',['../ir__Mitsubishi_8cpp.html#ab3c6a50b722402633aaf26e2a4a39ff0',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishionespaceticks_2306',['kMitsubishiOneSpaceTicks',['../ir__Mitsubishi_8cpp.html#a3b12f2aa2c3b4b7ef439f86356aab9cf',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishitick_2307',['kMitsubishiTick',['../ir__Mitsubishi_8cpp.html#a5197eb8b6e8de8fdfb9f056b6f7d9aa5',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishizerospace_2308',['kMitsubishiZeroSpace',['../ir__Mitsubishi_8cpp.html#a9660ac382e9a929f6acb73a32b2a1a3c',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishizerospaceticks_2309',['kMitsubishiZeroSpaceTicks',['../ir__Mitsubishi_8cpp.html#a18f364a0ba491236538bc9d086303d69',1,'ir_Mitsubishi.cpp']]], + ['kmodebitssize_2310',['kModeBitsSize',['../IRutils_8h.html#a5432915ab86062fceadc067a233f1627',1,'IRutils.h']]], + ['kmodelstr_2311',['kModelStr',['../IRtext_8cpp.html#a40905418e2934e539c50c6cfc2c4ffe3',1,'kModelStr(): IRtext.cpp'],['../IRtext_8h.html#a4a553cfcc7ca2a8cea8e1263f5f6c186',1,'kModelStr(): IRtext.cpp']]], + ['kmodestr_2312',['kModeStr',['../IRtext_8cpp.html#a7260c578d290c33b7705cd1439d992ee',1,'kModeStr(): IRtext.cpp'],['../IRtext_8h.html#a6666695e388b607bfd3bb0e6efd4193f',1,'kModeStr(): IRtext.cpp']]], + ['kmouldstr_2313',['kMouldStr',['../IRtext_8cpp.html#ac665ea584a4949565aa35629d791dbc5',1,'kMouldStr(): IRtext.cpp'],['../IRtext_8h.html#a693b29e4764d959dac781a0992f2bf30',1,'kMouldStr(): IRtext.cpp']]], + ['kmovestr_2314',['kMoveStr',['../IRtext_8cpp.html#a321f98699209fb487287c4911a0c0200',1,'kMoveStr(): IRtext.cpp'],['../IRtext_8h.html#ae99940df2a9243fd7fe6f3814c0802dd',1,'kMoveStr(): IRtext.cpp']]], + ['kmultibracketsbits_2315',['kMultibracketsBits',['../IRremoteESP8266_8h.html#aad7be0971479839493615cafcd654fc1',1,'IRremoteESP8266.h']]], + ['kmultibracketsdefaultrepeat_2316',['kMultibracketsDefaultRepeat',['../IRremoteESP8266_8h.html#a5aa418baefd018d5facc08d3bb721fe9',1,'IRremoteESP8266.h']]], + ['kmultibracketsfooterspace_2317',['kMultibracketsFooterSpace',['../ir__Multibrackets_8cpp.html#a738cde2d6a25611bea116d04375dd28a',1,'ir_Multibrackets.cpp']]], + ['kmultibracketsfreq_2318',['kMultibracketsFreq',['../ir__Multibrackets_8cpp.html#a38ba01a3c516f6018199aa9031a5fb4a',1,'ir_Multibrackets.cpp']]], + ['kmultibracketshdrmark_2319',['kMultibracketsHdrMark',['../ir__Multibrackets_8cpp.html#a4eaafbf701604ceb6591b8a8b9c1d202',1,'ir_Multibrackets.cpp']]], + ['kmultibracketstick_2320',['kMultibracketsTick',['../ir__Multibrackets_8cpp.html#aa528fbf06b8d5293d82b7efc2bcd1e9b',1,'ir_Multibrackets.cpp']]], + ['kmultibracketstolerance_2321',['kMultibracketsTolerance',['../ir__Multibrackets_8cpp.html#a242017fb86f015cdecbf31c278c43ccc',1,'ir_Multibrackets.cpp']]], + ['kmwmdelta_2322',['kMWMDelta',['../ir__MWM_8cpp.html#a4e32849a3c799af002d1290a8a33366e',1,'ir_MWM.cpp']]], + ['kmwmexcess_2323',['kMWMExcess',['../ir__MWM_8cpp.html#ab3ff88bfc09c94e70fb74a77dbdd87d7',1,'ir_MWM.cpp']]], + ['kmwmmaxwidth_2324',['kMWMMaxWidth',['../ir__MWM_8cpp.html#a833013dcb331ebce3b885b0ce73c9eaa',1,'ir_MWM.cpp']]], + ['kmwmmingap_2325',['kMWMMinGap',['../ir__MWM_8cpp.html#a4d1f9c5442390a5ba089270c1187e917',1,'ir_MWM.cpp']]], + ['kmwmminsamples_2326',['kMWMMinSamples',['../ir__MWM_8cpp.html#ad386c922a0fcbd0c5b904b9abdd8d582',1,'ir_MWM.cpp']]], + ['kmwmtick_2327',['kMWMTick',['../ir__MWM_8cpp.html#a42c39c0101ccad1e88fa206a26447256',1,'ir_MWM.cpp']]], + ['kmwmtolerance_2328',['kMWMTolerance',['../ir__MWM_8cpp.html#ae3a91ec66f51f50810229b4adc1264fd',1,'ir_MWM.cpp']]], + ['knastr_2329',['kNAStr',['../IRtext_8cpp.html#a1757349137713553454f405872bc4dcd',1,'kNAStr(): IRtext.cpp'],['../IRtext_8h.html#a5d094344fba1715dbde69ff947775264',1,'kNAStr(): IRtext.cpp']]], + ['knecbitmark_2330',['kNecBitMark',['../ir__NEC_8h.html#ab536a800ec8f7259fe7e485ea4aea465',1,'ir_NEC.h']]], + ['knecbitmarkticks_2331',['kNecBitMarkTicks',['../ir__NEC_8h.html#a84ca60f84d64d65872b40a87819eccc1',1,'ir_NEC.h']]], + ['knecbits_2332',['kNECBits',['../IRremoteESP8266_8h.html#a65e03baf646815b4b02f943bdd74a097',1,'IRremoteESP8266.h']]], + ['knechdrmark_2333',['kNecHdrMark',['../ir__NEC_8h.html#ac727ede47d30ec76b03e4a41b48ce8c7',1,'ir_NEC.h']]], + ['knechdrmarkticks_2334',['kNecHdrMarkTicks',['../ir__NEC_8h.html#ab1486c07a09bc4324c03b1c887f5c5f7',1,'ir_NEC.h']]], + ['knechdrspace_2335',['kNecHdrSpace',['../ir__NEC_8h.html#a8279410369d6ed266502615d3ff1750b',1,'ir_NEC.h']]], + ['knechdrspaceticks_2336',['kNecHdrSpaceTicks',['../ir__NEC_8h.html#a4470ee927c0c3447bdda20c52b0f8566',1,'ir_NEC.h']]], + ['knecmincommandlength_2337',['kNecMinCommandLength',['../ir__NEC_8h.html#ac7b8d897d9e5bbf29b9b1b899a2ef7d8',1,'ir_NEC.h']]], + ['knecmincommandlengthticks_2338',['kNecMinCommandLengthTicks',['../ir__NEC_8h.html#a78e411960e643495987b1cb53268bc46',1,'ir_NEC.h']]], + ['knecmingap_2339',['kNecMinGap',['../ir__NEC_8h.html#a3d6ecc128599df57dc98e97e51b2264e',1,'ir_NEC.h']]], + ['knecmingapticks_2340',['kNecMinGapTicks',['../ir__NEC_8h.html#a2e6d938510a34aa1217a56aa51ece9f5',1,'ir_NEC.h']]], + ['kneconespace_2341',['kNecOneSpace',['../ir__NEC_8h.html#af57080e9b7513d1c8e7e781f3d502fbd',1,'ir_NEC.h']]], + ['kneconespaceticks_2342',['kNecOneSpaceTicks',['../ir__NEC_8h.html#a2f1e5412d44816f92e4b6c72e16e8b1f',1,'ir_NEC.h']]], + ['knecrptlength_2343',['kNecRptLength',['../ir__NEC_8h.html#af4ab20595dfda177fbb06dd821ea14c7',1,'ir_NEC.h']]], + ['knecrptspace_2344',['kNecRptSpace',['../ir__NEC_8h.html#a9538478446b1ae5d72c8366dd6a11673',1,'ir_NEC.h']]], + ['knecrptspaceticks_2345',['kNecRptSpaceTicks',['../ir__NEC_8h.html#a91b5296d480008a4b44c5b084756f04b',1,'ir_NEC.h']]], + ['knectick_2346',['kNecTick',['../ir__NEC_8h.html#abe1ec110798236c7b626f7efe4cc5657',1,'ir_NEC.h']]], + ['kneczerospace_2347',['kNecZeroSpace',['../ir__NEC_8h.html#a00573a6bdb348339b9898173b644b693',1,'ir_NEC.h']]], + ['kneczerospaceticks_2348',['kNecZeroSpaceTicks',['../ir__NEC_8h.html#a80f316535d761c64f1d5752ef80a65ff',1,'ir_NEC.h']]], + ['kneoclima8cheatoffset_2349',['kNeoclima8CHeatOffset',['../ir__Neoclima_8h.html#a4e9654ac35708a22912448eef3eb2b35',1,'ir_Neoclima.h']]], + ['kneoclimaauto_2350',['kNeoclimaAuto',['../ir__Neoclima_8h.html#a4574742c21aae9aafaff9b10f9423006',1,'ir_Neoclima.h']]], + ['kneoclimabitmark_2351',['kNeoclimaBitMark',['../ir__Neoclima_8cpp.html#ae34236a830ec2d200575ac33fda43689',1,'ir_Neoclima.cpp']]], + ['kneoclimabits_2352',['kNeoclimaBits',['../IRremoteESP8266_8h.html#afff9132e57296b4d7e04ec9e1e5ab04f',1,'IRremoteESP8266.h']]], + ['kneoclimabutton8cheat_2353',['kNeoclimaButton8CHeat',['../ir__Neoclima_8h.html#ad337d964ff800bea5c55f1fe69dfb7ff',1,'ir_Neoclima.h']]], + ['kneoclimabuttonairflow_2354',['kNeoclimaButtonAirFlow',['../ir__Neoclima_8h.html#ab5fff838f8e5ac9ff213fc69346ffa7c',1,'ir_Neoclima.h']]], + ['kneoclimabuttoneye_2355',['kNeoclimaButtonEye',['../ir__Neoclima_8h.html#a6cabdccd3c8d52cb2817f99454bdc884',1,'ir_Neoclima.h']]], + ['kneoclimabuttonfanspeed_2356',['kNeoclimaButtonFanSpeed',['../ir__Neoclima_8h.html#ab41ffd863516b79b6c7e9b69e7d5a272',1,'ir_Neoclima.h']]], + ['kneoclimabuttonfollow_2357',['kNeoclimaButtonFollow',['../ir__Neoclima_8h.html#a592017dce3bfa4ea2f0f341a818aff72',1,'ir_Neoclima.h']]], + ['kneoclimabuttonfresh_2358',['kNeoclimaButtonFresh',['../ir__Neoclima_8h.html#a6a965f2dc7860879ccaf410405095e9c',1,'ir_Neoclima.h']]], + ['kneoclimabuttonhold_2359',['kNeoclimaButtonHold',['../ir__Neoclima_8h.html#aada6fdb6572bd7d841de89f1d1eed3fe',1,'ir_Neoclima.h']]], + ['kneoclimabuttonion_2360',['kNeoclimaButtonIon',['../ir__Neoclima_8h.html#a05dccf1c19237d315bb78f387f8fd57f',1,'ir_Neoclima.h']]], + ['kneoclimabuttonlight_2361',['kNeoclimaButtonLight',['../ir__Neoclima_8h.html#ac66b472b31f6183f4615584561baa284',1,'ir_Neoclima.h']]], + ['kneoclimabuttonmode_2362',['kNeoclimaButtonMode',['../ir__Neoclima_8h.html#a4cfee4b0898f1504be5cbd129cd99278',1,'ir_Neoclima.h']]], + ['kneoclimabuttonoffset_2363',['kNeoclimaButtonOffset',['../ir__Neoclima_8h.html#a08ae86c15defd78ecac0f322f84190d3',1,'ir_Neoclima.h']]], + ['kneoclimabuttonpower_2364',['kNeoclimaButtonPower',['../ir__Neoclima_8h.html#a047d19978c58b35dcd6a069fce04af87',1,'ir_Neoclima.h']]], + ['kneoclimabuttonsize_2365',['kNeoclimaButtonSize',['../ir__Neoclima_8h.html#aac90dbf9fe499df2edf64df44f449e57',1,'ir_Neoclima.h']]], + ['kneoclimabuttonsleep_2366',['kNeoclimaButtonSleep',['../ir__Neoclima_8h.html#adcbe2a89eecf41fe1fe2b8c62428084e',1,'ir_Neoclima.h']]], + ['kneoclimabuttonswing_2367',['kNeoclimaButtonSwing',['../ir__Neoclima_8h.html#aeea180bef85a40d8c7fe3f5facf7b199',1,'ir_Neoclima.h']]], + ['kneoclimabuttontempdown_2368',['kNeoclimaButtonTempDown',['../ir__Neoclima_8h.html#aee91f1ebdf89b6fe9f3b31937d1185a0',1,'ir_Neoclima.h']]], + ['kneoclimabuttontempup_2369',['kNeoclimaButtonTempUp',['../ir__Neoclima_8h.html#abb093132f77d179ab02fc4a022d55236',1,'ir_Neoclima.h']]], + ['kneoclimabuttonturbo_2370',['kNeoclimaButtonTurbo',['../ir__Neoclima_8h.html#af156d94f9e47e8b5e2e2493308cca04c',1,'ir_Neoclima.h']]], + ['kneoclimacool_2371',['kNeoclimaCool',['../ir__Neoclima_8h.html#ac5d874e5ffce72ce68176f38e780c439',1,'ir_Neoclima.h']]], + ['kneoclimadry_2372',['kNeoclimaDry',['../ir__Neoclima_8h.html#ab68ba4480e1bcb685579c5f902d0709e',1,'ir_Neoclima.h']]], + ['kneoclimaeyeoffset_2373',['kNeoclimaEyeOffset',['../ir__Neoclima_8h.html#ad7baeea22b87a69150c65b2c049ee0b2',1,'ir_Neoclima.h']]], + ['kneoclimafan_2374',['kNeoclimaFan',['../ir__Neoclima_8h.html#aa6166bd65d80a708d790dbf703c83ea2',1,'ir_Neoclima.h']]], + ['kneoclimafanauto_2375',['kNeoclimaFanAuto',['../ir__Neoclima_8h.html#a7885fdbc4ae3336aac74d7ee3d8c3258',1,'ir_Neoclima.h']]], + ['kneoclimafanhigh_2376',['kNeoclimaFanHigh',['../ir__Neoclima_8h.html#a57ddf91c1cbb157b3a53b1082bac2d75',1,'ir_Neoclima.h']]], + ['kneoclimafanlow_2377',['kNeoclimaFanLow',['../ir__Neoclima_8h.html#ac9031328be51a46543ebd4360aaca55a',1,'ir_Neoclima.h']]], + ['kneoclimafanmed_2378',['kNeoclimaFanMed',['../ir__Neoclima_8h.html#a11faf2a34faf44460795b50bfbdab402',1,'ir_Neoclima.h']]], + ['kneoclimafanoffest_2379',['kNeoclimaFanOffest',['../ir__Neoclima_8h.html#a32f614475b5f00f8ccdf12498c519713',1,'ir_Neoclima.h']]], + ['kneoclimafansize_2380',['kNeoclimaFanSize',['../ir__Neoclima_8h.html#a888cbc3f0a38137cb909188b6fff91b1',1,'ir_Neoclima.h']]], + ['kneoclimafollowme_2381',['kNeoclimaFollowMe',['../ir__Neoclima_8h.html#a493c1e6b8b8909f4201cd506a1f4804a',1,'ir_Neoclima.h']]], + ['kneoclimafreshoffset_2382',['kNeoclimaFreshOffset',['../ir__Neoclima_8h.html#af19f0f77ece049bdef26930be1b0309f',1,'ir_Neoclima.h']]], + ['kneoclimahdrmark_2383',['kNeoclimaHdrMark',['../ir__Neoclima_8cpp.html#aa392821c0ce822a7b7d67efd202bedd5',1,'ir_Neoclima.cpp']]], + ['kneoclimahdrspace_2384',['kNeoclimaHdrSpace',['../ir__Neoclima_8cpp.html#a3714ad66d75162ccb286152b70375588',1,'ir_Neoclima.cpp']]], + ['kneoclimaheat_2385',['kNeoclimaHeat',['../ir__Neoclima_8h.html#a5a5e53801c0f8e554c391ed56404b926',1,'ir_Neoclima.h']]], + ['kneoclimaholdoffset_2386',['kNeoclimaHoldOffset',['../ir__Neoclima_8h.html#a3a91e7504c7820223021dcc2cbbf9f2a',1,'ir_Neoclima.h']]], + ['kneoclimaionoffset_2387',['kNeoclimaIonOffset',['../ir__Neoclima_8h.html#ad420932425fbe261368938e604dfb0c1',1,'ir_Neoclima.h']]], + ['kneoclimalightoffset_2388',['kNeoclimaLightOffset',['../ir__Neoclima_8h.html#af58a863257c5d436b299ac8cbcb57686',1,'ir_Neoclima.h']]], + ['kneoclimamaxtemp_2389',['kNeoclimaMaxTemp',['../ir__Neoclima_8h.html#a755ef8290df8a3e19f236839bee42412',1,'ir_Neoclima.h']]], + ['kneoclimamingap_2390',['kNeoclimaMinGap',['../ir__Neoclima_8cpp.html#a0e54c73eff563f6c3ec39a0951dd3d2d',1,'ir_Neoclima.cpp']]], + ['kneoclimaminrepeat_2391',['kNeoclimaMinRepeat',['../IRremoteESP8266_8h.html#a16fc26a3ff66a66068ac9638554df847',1,'IRremoteESP8266.h']]], + ['kneoclimamintemp_2392',['kNeoclimaMinTemp',['../ir__Neoclima_8h.html#adc979ad2ac64481f13b1085b1fdd13c4',1,'ir_Neoclima.h']]], + ['kneoclimamodeoffset_2393',['kNeoclimaModeOffset',['../ir__Neoclima_8h.html#a823a960610ef3387099d2a2103dd0b56',1,'ir_Neoclima.h']]], + ['kneoclimaonespace_2394',['kNeoclimaOneSpace',['../ir__Neoclima_8cpp.html#a5fd5f3b7f04134190aafc65762528da0',1,'ir_Neoclima.cpp']]], + ['kneoclimapoweroffset_2395',['kNeoclimaPowerOffset',['../ir__Neoclima_8h.html#a9b881e5400fe9bcd3b1422aeb355cf7c',1,'ir_Neoclima.h']]], + ['kneoclimasleepoffset_2396',['kNeoclimaSleepOffset',['../ir__Neoclima_8h.html#ac0c978cdc30827c7390b93a9a4f05d24',1,'ir_Neoclima.h']]], + ['kneoclimastatelength_2397',['kNeoclimaStateLength',['../IRremoteESP8266_8h.html#a5a871ed6d145c5ea3d50e96600c02e31',1,'IRremoteESP8266.h']]], + ['kneoclimaswinghoffset_2398',['kNeoclimaSwingHOffset',['../ir__Neoclima_8h.html#a5f2e8ccaa590386b0947b0f291ebcb09',1,'ir_Neoclima.h']]], + ['kneoclimaswingvoff_2399',['kNeoclimaSwingVOff',['../ir__Neoclima_8h.html#ad230a8c18e6edb5709cb29033f1fd221',1,'ir_Neoclima.h']]], + ['kneoclimaswingvoffset_2400',['kNeoclimaSwingVOffset',['../ir__Neoclima_8h.html#a91b63c4712093684625a16c76bcc6784',1,'ir_Neoclima.h']]], + ['kneoclimaswingvon_2401',['kNeoclimaSwingVOn',['../ir__Neoclima_8h.html#a7021804eb30e7a7c5b9c9ababb1b8cad',1,'ir_Neoclima.h']]], + ['kneoclimaswingvsize_2402',['kNeoclimaSwingVSize',['../ir__Neoclima_8h.html#ab4b49ec2c326d0e94eba23e7a93b6fc6',1,'ir_Neoclima.h']]], + ['kneoclimatempoffset_2403',['kNeoclimaTempOffset',['../ir__Neoclima_8h.html#a5c3470f6c773b4c557e6996f8c29a573',1,'ir_Neoclima.h']]], + ['kneoclimatempsize_2404',['kNeoclimaTempSize',['../ir__Neoclima_8h.html#af848fc3f4ce46c8786fd2b3e129b1e48',1,'ir_Neoclima.h']]], + ['kneoclimaturbooffset_2405',['kNeoclimaTurboOffset',['../ir__Neoclima_8h.html#ae23c6faf5f54ff12d592360b42d69971',1,'ir_Neoclima.h']]], + ['kneoclimazerospace_2406',['kNeoclimaZeroSpace',['../ir__Neoclima_8cpp.html#a0b98d84da4651d8d31f8f1d84621c21e',1,'ir_Neoclima.cpp']]], + ['knibblesize_2407',['kNibbleSize',['../IRutils_8h.html#aa72cd082cdde3d8d7473ed9d11ff6846',1,'IRutils.h']]], + ['knightstr_2408',['kNightStr',['../IRtext_8cpp.html#a01908d3c0f79bc015a699fc0576a8771',1,'kNightStr(): IRtext.cpp'],['../IRtext_8h.html#afe6519eaae5b1fb4d110529ce98f05b0',1,'kNightStr(): IRtext.cpp']]], + ['knikaibitmark_2409',['kNikaiBitMark',['../ir__Nikai_8cpp.html#ad665145b0ee9cc722d9fde43cbd3fd82',1,'ir_Nikai.cpp']]], + ['knikaibitmarkticks_2410',['kNikaiBitMarkTicks',['../ir__Nikai_8cpp.html#ac10d1b4c45af3ddbf3c50b85dbb0c2f0',1,'ir_Nikai.cpp']]], + ['knikaibits_2411',['kNikaiBits',['../IRremoteESP8266_8h.html#a9fce002592f9e2488b1b717d0b1a6a40',1,'IRremoteESP8266.h']]], + ['knikaihdrmark_2412',['kNikaiHdrMark',['../ir__Nikai_8cpp.html#ae0656b931e18e6e011a7c74cfaf4384b',1,'ir_Nikai.cpp']]], + ['knikaihdrmarkticks_2413',['kNikaiHdrMarkTicks',['../ir__Nikai_8cpp.html#a11671cee9a312ece8f1c90596eddd7ac',1,'ir_Nikai.cpp']]], + ['knikaihdrspace_2414',['kNikaiHdrSpace',['../ir__Nikai_8cpp.html#ae801e20e669f3039888bf48074988b84',1,'ir_Nikai.cpp']]], + ['knikaihdrspaceticks_2415',['kNikaiHdrSpaceTicks',['../ir__Nikai_8cpp.html#a83885a2fc573f947afe5015cd2f4d953',1,'ir_Nikai.cpp']]], + ['knikaimingap_2416',['kNikaiMinGap',['../ir__Nikai_8cpp.html#ad88846eaa7559df7fb944283fd292da1',1,'ir_Nikai.cpp']]], + ['knikaimingapticks_2417',['kNikaiMinGapTicks',['../ir__Nikai_8cpp.html#afdf938a763f30e3c5e534eba269dff1f',1,'ir_Nikai.cpp']]], + ['knikaionespace_2418',['kNikaiOneSpace',['../ir__Nikai_8cpp.html#a4bb69ab22b2abcd20ffff90f9267fa43',1,'ir_Nikai.cpp']]], + ['knikaionespaceticks_2419',['kNikaiOneSpaceTicks',['../ir__Nikai_8cpp.html#a25a4d289b7fad06c31312df552ee81ab',1,'ir_Nikai.cpp']]], + ['knikaitick_2420',['kNikaiTick',['../ir__Nikai_8cpp.html#a70eb8953509420081d0a294203eeb34b',1,'ir_Nikai.cpp']]], + ['knikaizerospace_2421',['kNikaiZeroSpace',['../ir__Nikai_8cpp.html#aa9af57c5c936107b00096e16cc6f57d9',1,'ir_Nikai.cpp']]], + ['knikaizerospaceticks_2422',['kNikaiZeroSpaceTicks',['../ir__Nikai_8cpp.html#a8df777a744c018e27c6969c2109d6d79',1,'ir_Nikai.cpp']]], + ['knorepeat_2423',['kNoRepeat',['../IRremoteESP8266_8h.html#a1a49dde7ffbd753f7756cf0c9dc6d826',1,'IRremoteESP8266.h']]], + ['knostr_2424',['kNoStr',['../IRtext_8cpp.html#a07897ceb4a6607d87ef37a517908a4b5',1,'kNoStr(): IRtext.cpp'],['../IRtext_8h.html#a51c9fb58ee7d01e96e2571018aea746d',1,'kNoStr(): IRtext.cpp']]], + ['knowstr_2425',['kNowStr',['../IRtext_8cpp.html#a09d8590020bcf998746528d0e50f7a20',1,'kNowStr(): IRtext.cpp'],['../IRtext_8h.html#a6a3c0965a32c36d9b5aa4918b473cc12',1,'kNowStr(): IRtext.cpp']]], + ['koff_2426',['kOff',['../namespacestdAc.html#a99ad268c783486f9b3207cb78f48444facc9ab5e60ac2a9a675ba64bf4bb49dc8',1,'stdAc::kOff()'],['../namespacestdAc.html#ac07f224c7bb47cac55dd01f24770ef43acc9ab5e60ac2a9a675ba64bf4bb49dc8',1,'stdAc::kOff()'],['../namespacestdAc.html#aae50ee315fa9c9ec1a4078da40d6b147acc9ab5e60ac2a9a675ba64bf4bb49dc8',1,'stdAc::kOff()']]], + ['koffstr_2427',['kOffStr',['../IRtext_8cpp.html#a9ce19a214db45b8cff83032ffa1ccdd8',1,'kOffStr(): IRtext.cpp'],['../IRtext_8h.html#a95f119413a113c9a2e8c246892b8c52a',1,'kOffStr(): IRtext.cpp']]], + ['kofftimerstr_2428',['kOffTimerStr',['../IRtext_8cpp.html#ae5faab97b26f9e877f79f49002bbba2c',1,'kOffTimerStr(): IRtext.cpp'],['../IRtext_8h.html#a818275085f8a8d7c083b66f081689b1f',1,'kOffTimerStr(): IRtext.cpp']]], + ['konstr_2429',['kOnStr',['../IRtext_8cpp.html#ab3f42c8df156baa46326a57193f78c51',1,'kOnStr(): IRtext.cpp'],['../IRtext_8h.html#aaf4ffad7f827a2ce8512e644bc9c25c7',1,'kOnStr(): IRtext.cpp']]], + ['kontimerstr_2430',['kOnTimerStr',['../IRtext_8cpp.html#adaecb1b5526f2bb3a1334e816a414273',1,'kOnTimerStr(): IRtext.cpp'],['../IRtext_8h.html#a9f355a0d834790287d95eea30b57564d',1,'kOnTimerStr(): IRtext.cpp']]], + ['koutsidequietstr_2431',['kOutsideQuietStr',['../IRtext_8cpp.html#a103f2a8a2a6d351cd8ea259de3c454ef',1,'kOutsideQuietStr(): IRtext.cpp'],['../IRtext_8h.html#afaf12ae53365f790b47ff3790e94cc1c',1,'kOutsideQuietStr(): IRtext.cpp']]], + ['koutsidestr_2432',['kOutsideStr',['../IRtext_8cpp.html#a8465ee1e8b1e5dd58a9cf872c9569e01',1,'kOutsideStr(): IRtext.cpp'],['../IRtext_8h.html#ada5c81e0fcc4073d6f51e7447e8c5da0',1,'kOutsideStr(): IRtext.cpp']]], + ['kpanasonicacauto_2433',['kPanasonicAcAuto',['../ir__Panasonic_8h.html#aa7c839a4342205c384870e8a4f5ec36b',1,'ir_Panasonic.h']]], + ['kpanasonicacbits_2434',['kPanasonicAcBits',['../IRremoteESP8266_8h.html#a210f5c78b0f90b64dd5037698141433a',1,'IRremoteESP8266.h']]], + ['kpanasonicacchecksuminit_2435',['kPanasonicAcChecksumInit',['../ir__Panasonic_8h.html#a49329b4fef403696effcbcc5c8a86cd2',1,'ir_Panasonic.h']]], + ['kpanasonicaccool_2436',['kPanasonicAcCool',['../ir__Panasonic_8h.html#acfaa3d61fbb13fc6cd8d354f1c0a8dc7',1,'ir_Panasonic.h']]], + ['kpanasonicacdefaultrepeat_2437',['kPanasonicAcDefaultRepeat',['../IRremoteESP8266_8h.html#af6b7c6ad564253cb128ac92c00e86f0c',1,'IRremoteESP8266.h']]], + ['kpanasonicacdry_2438',['kPanasonicAcDry',['../ir__Panasonic_8h.html#a2d211bd2150a67819453f3220dc0cc91',1,'ir_Panasonic.h']]], + ['kpanasonicacexcess_2439',['kPanasonicAcExcess',['../ir__Panasonic_8h.html#adde8b69377faa9a4566dc15e95711257',1,'ir_Panasonic.h']]], + ['kpanasonicacfan_2440',['kPanasonicAcFan',['../ir__Panasonic_8h.html#a87e4dd423bbd1f879a9d5da31e1fea5e',1,'ir_Panasonic.h']]], + ['kpanasonicacfanauto_2441',['kPanasonicAcFanAuto',['../ir__Panasonic_8h.html#a7d4486fd68969af4f7230f12e865c698',1,'ir_Panasonic.h']]], + ['kpanasonicacfandelta_2442',['kPanasonicAcFanDelta',['../ir__Panasonic_8h.html#a2210f85a17fba2bbdfbb883e9fb57e52',1,'ir_Panasonic.h']]], + ['kpanasonicacfanmax_2443',['kPanasonicAcFanMax',['../ir__Panasonic_8h.html#aa4599c84d72ab9c622b642870efb9cf1',1,'ir_Panasonic.h']]], + ['kpanasonicacfanmed_2444',['kPanasonicAcFanMed',['../ir__Panasonic_8h.html#a978004e8e2c4122fec81c5a972b842a0',1,'ir_Panasonic.h']]], + ['kpanasonicacfanmin_2445',['kPanasonicAcFanMin',['../ir__Panasonic_8h.html#a450c7951a525817d27351fb7c8ff2df9',1,'ir_Panasonic.h']]], + ['kpanasonicacfanmodetemp_2446',['kPanasonicAcFanModeTemp',['../ir__Panasonic_8h.html#a76543f9d81c2d109e04359f0c61dcb99',1,'ir_Panasonic.h']]], + ['kpanasonicacheat_2447',['kPanasonicAcHeat',['../ir__Panasonic_8h.html#ac37bb7dd975a9aa803edfc108a5071ed',1,'ir_Panasonic.h']]], + ['kpanasonicacionfilterbyte_2448',['kPanasonicAcIonFilterByte',['../ir__Panasonic_8h.html#a16c946660d2ee3821dd2e30a69144a38',1,'ir_Panasonic.h']]], + ['kpanasonicacionfilteroffset_2449',['kPanasonicAcIonFilterOffset',['../ir__Panasonic_8h.html#a5c1b18d1b834e9d46cbd29c74a1b8269',1,'ir_Panasonic.h']]], + ['kpanasonicacmaxtemp_2450',['kPanasonicAcMaxTemp',['../ir__Panasonic_8h.html#a95fe6bc5b2565bf29d1a6dcee2f0c39f',1,'ir_Panasonic.h']]], + ['kpanasonicacmessagegap_2451',['kPanasonicAcMessageGap',['../ir__Panasonic_8cpp.html#a962cde97e8d98ad32f0b59172b641d6d',1,'ir_Panasonic.cpp']]], + ['kpanasonicacmintemp_2452',['kPanasonicAcMinTemp',['../ir__Panasonic_8h.html#a7861e8477904e1a572bcf35286fd3733',1,'ir_Panasonic.h']]], + ['kpanasonicacofftimeroffset_2453',['kPanasonicAcOffTimerOffset',['../ir__Panasonic_8h.html#a477b61044f1db5c296f13a404c536046',1,'ir_Panasonic.h']]], + ['kpanasonicacontimeroffset_2454',['kPanasonicAcOnTimerOffset',['../ir__Panasonic_8h.html#a64350202f82aabfd1673f0dda4d3c13d',1,'ir_Panasonic.h']]], + ['kpanasonicacpowerfulckpoffset_2455',['kPanasonicAcPowerfulCkpOffset',['../ir__Panasonic_8h.html#aa839301a08c8e49548f497e786dbb6fa',1,'ir_Panasonic.h']]], + ['kpanasonicacpowerfuloffset_2456',['kPanasonicAcPowerfulOffset',['../ir__Panasonic_8h.html#a27e9b1af4b65830015576beed69cb27d',1,'ir_Panasonic.h']]], + ['kpanasonicacpoweroffset_2457',['kPanasonicAcPowerOffset',['../ir__Panasonic_8h.html#a9e9b3d0c77ef93ab472ce14ed1534c77',1,'ir_Panasonic.h']]], + ['kpanasonicacquietckpoffset_2458',['kPanasonicAcQuietCkpOffset',['../ir__Panasonic_8h.html#a5a3779cd6fd8d573ae14ed4a6d676dba',1,'ir_Panasonic.h']]], + ['kpanasonicacquietoffset_2459',['kPanasonicAcQuietOffset',['../ir__Panasonic_8h.html#a1ec8db8798f79dead05233ee6333700d',1,'ir_Panasonic.h']]], + ['kpanasonicacsection1length_2460',['kPanasonicAcSection1Length',['../ir__Panasonic_8cpp.html#a34c6c085d468ed4b35f814452335d334',1,'ir_Panasonic.cpp']]], + ['kpanasonicacsectiongap_2461',['kPanasonicAcSectionGap',['../ir__Panasonic_8cpp.html#a3cf28f1268e8a35da220d42deda7c456',1,'ir_Panasonic.cpp']]], + ['kpanasonicacshortbits_2462',['kPanasonicAcShortBits',['../IRremoteESP8266_8h.html#a2fd1f84669f7994bb3c235a508333c6c',1,'IRremoteESP8266.h']]], + ['kpanasonicacstatelength_2463',['kPanasonicAcStateLength',['../IRremoteESP8266_8h.html#ab21d86545b57738354e7a3b833d38f94',1,'IRremoteESP8266.h']]], + ['kpanasonicacstateshortlength_2464',['kPanasonicAcStateShortLength',['../IRremoteESP8266_8h.html#a0a6ca8c1dfa6f313421ddf268d76d8e6',1,'IRremoteESP8266.h']]], + ['kpanasonicacswinghauto_2465',['kPanasonicAcSwingHAuto',['../ir__Panasonic_8h.html#a91e2933692ad98acf054c7a69f6c2018',1,'ir_Panasonic.h']]], + ['kpanasonicacswinghfullleft_2466',['kPanasonicAcSwingHFullLeft',['../ir__Panasonic_8h.html#abf1d8c53a1b69d99019c6878f9ec220d',1,'ir_Panasonic.h']]], + ['kpanasonicacswinghfullright_2467',['kPanasonicAcSwingHFullRight',['../ir__Panasonic_8h.html#a0e1b7a7591a0f14b2f8be3cb222f1187',1,'ir_Panasonic.h']]], + ['kpanasonicacswinghleft_2468',['kPanasonicAcSwingHLeft',['../ir__Panasonic_8h.html#a853f2c2922e03a975bdd11efc474fa7e',1,'ir_Panasonic.h']]], + ['kpanasonicacswinghmiddle_2469',['kPanasonicAcSwingHMiddle',['../ir__Panasonic_8h.html#afad8a7257fc178321867f16939fff7c7',1,'ir_Panasonic.h']]], + ['kpanasonicacswinghright_2470',['kPanasonicAcSwingHRight',['../ir__Panasonic_8h.html#a282900f1c494efdc6ee057357e624d2e',1,'ir_Panasonic.h']]], + ['kpanasonicacswingvauto_2471',['kPanasonicAcSwingVAuto',['../ir__Panasonic_8h.html#a218e2ea8c76966105c71edcb6e46cd12',1,'ir_Panasonic.h']]], + ['kpanasonicacswingvhigh_2472',['kPanasonicAcSwingVHigh',['../ir__Panasonic_8h.html#a25c63195112c5aedc5b5bad40441c55a',1,'ir_Panasonic.h']]], + ['kpanasonicacswingvhighest_2473',['kPanasonicAcSwingVHighest',['../ir__Panasonic_8h.html#ac1cea523d6e1da08d333e0b4acec81af',1,'ir_Panasonic.h']]], + ['kpanasonicacswingvlow_2474',['kPanasonicAcSwingVLow',['../ir__Panasonic_8h.html#a3ae9b6c5581f1bfb5b31e252052a6c9d',1,'ir_Panasonic.h']]], + ['kpanasonicacswingvlowest_2475',['kPanasonicAcSwingVLowest',['../ir__Panasonic_8h.html#af269e81dae5989c33199d607adcc04a0',1,'ir_Panasonic.h']]], + ['kpanasonicacswingvmiddle_2476',['kPanasonicAcSwingVMiddle',['../ir__Panasonic_8h.html#a5d46c8234f97e10695507b17a7483d51',1,'ir_Panasonic.h']]], + ['kpanasonicactempoffset_2477',['kPanasonicAcTempOffset',['../ir__Panasonic_8h.html#a203e0351cd53db8376312a3289503175',1,'ir_Panasonic.h']]], + ['kpanasonicactempsize_2478',['kPanasonicAcTempSize',['../ir__Panasonic_8h.html#af30649a3489a4a1dc1f655d15c00e991',1,'ir_Panasonic.h']]], + ['kpanasonicactimemax_2479',['kPanasonicAcTimeMax',['../ir__Panasonic_8h.html#a61378ccad09d1a2e900123a8cbd34858',1,'ir_Panasonic.h']]], + ['kpanasonicactimeoverflowsize_2480',['kPanasonicAcTimeOverflowSize',['../ir__Panasonic_8h.html#ad7942b5ffbb2b1f7a5d9b3719592622b',1,'ir_Panasonic.h']]], + ['kpanasonicactimesize_2481',['kPanasonicAcTimeSize',['../ir__Panasonic_8h.html#a16577844a2f5ca46e2dff076952f2963',1,'ir_Panasonic.h']]], + ['kpanasonicactimespecial_2482',['kPanasonicAcTimeSpecial',['../ir__Panasonic_8h.html#aefb20e7cdbbc27e3c0725a8660a84a28',1,'ir_Panasonic.h']]], + ['kpanasonicactolerance_2483',['kPanasonicAcTolerance',['../ir__Panasonic_8h.html#a586a655b3afd82c38588fc1b61089aa1',1,'ir_Panasonic.h']]], + ['kpanasonicbitmark_2484',['kPanasonicBitMark',['../ir__Panasonic_8cpp.html#a428cd02c5dc3dc571e495efa0707cc99',1,'ir_Panasonic.cpp']]], + ['kpanasonicbitmarkticks_2485',['kPanasonicBitMarkTicks',['../ir__Panasonic_8cpp.html#aa0b259da4bc3dbf6c8b2ca31de759f55',1,'ir_Panasonic.cpp']]], + ['kpanasonicbits_2486',['kPanasonicBits',['../IRremoteESP8266_8h.html#aa148f54492be1cf8a8b285a96861a0b7',1,'IRremoteESP8266.h']]], + ['kpanasonicckp_2487',['kPanasonicCkp',['../IRsend_8h.html#a1b797a5e5176ac0eef49810bf7f40e6fa537e8c640473597d2a1cb832498f9cb0',1,'IRsend.h']]], + ['kpanasonicdke_2488',['kPanasonicDke',['../IRsend_8h.html#a1b797a5e5176ac0eef49810bf7f40e6fac8df2e0cfd553b0103f4c06a0fd573fd',1,'IRsend.h']]], + ['kpanasonicendgap_2489',['kPanasonicEndGap',['../ir__Panasonic_8cpp.html#a3cb2f7a925bb8374a90e3156febabb39',1,'ir_Panasonic.cpp']]], + ['kpanasonicfreq_2490',['kPanasonicFreq',['../ir__Panasonic_8h.html#af344612d7f1c0d3f8271c312f310243e',1,'ir_Panasonic.h']]], + ['kpanasonichdrmark_2491',['kPanasonicHdrMark',['../ir__Panasonic_8cpp.html#a0d36b699fead0e229c583dae94f5e8f9',1,'ir_Panasonic.cpp']]], + ['kpanasonichdrmarkticks_2492',['kPanasonicHdrMarkTicks',['../ir__Panasonic_8cpp.html#a0f2d448b87f30840ee38c27032cd10bd',1,'ir_Panasonic.cpp']]], + ['kpanasonichdrspace_2493',['kPanasonicHdrSpace',['../ir__Panasonic_8cpp.html#ae56b3eb80f186a63b0f69c6b4e9efce8',1,'ir_Panasonic.cpp']]], + ['kpanasonichdrspaceticks_2494',['kPanasonicHdrSpaceTicks',['../ir__Panasonic_8cpp.html#a5fa430a5612bd21eb859356cc9c62a3c',1,'ir_Panasonic.cpp']]], + ['kpanasonicjke_2495',['kPanasonicJke',['../IRsend_8h.html#a1b797a5e5176ac0eef49810bf7f40e6fabf39cff180c071fbc44601eeded236c4',1,'IRsend.h']]], + ['kpanasonicknowngoodstate_2496',['kPanasonicKnownGoodState',['../ir__Panasonic_8h.html#a88a9678f8b00efa173b800b0b8441f87',1,'ir_Panasonic.h']]], + ['kpanasoniclke_2497',['kPanasonicLke',['../IRsend_8h.html#a1b797a5e5176ac0eef49810bf7f40e6fa71ceb4b576a03a47f0d945323b896cd6',1,'IRsend.h']]], + ['kpanasonicmanufacturer_2498',['kPanasonicManufacturer',['../IRremoteESP8266_8h.html#a1dd1a9799e5d20d39e82ff678bf07b47',1,'IRremoteESP8266.h']]], + ['kpanasonicmincommandlength_2499',['kPanasonicMinCommandLength',['../ir__Panasonic_8cpp.html#a5f191fff3eeb722cb03bee859a016132',1,'ir_Panasonic.cpp']]], + ['kpanasonicmincommandlengthticks_2500',['kPanasonicMinCommandLengthTicks',['../ir__Panasonic_8cpp.html#aba420f9aa4c3e6f261e422962362ce31',1,'ir_Panasonic.cpp']]], + ['kpanasonicmingap_2501',['kPanasonicMinGap',['../ir__Panasonic_8cpp.html#a61592f3569c0ee4825cca185fb43236d',1,'ir_Panasonic.cpp']]], + ['kpanasonicmingapticks_2502',['kPanasonicMinGapTicks',['../ir__Panasonic_8cpp.html#aa605847e951b22f1f31b82e6b04c4bab',1,'ir_Panasonic.cpp']]], + ['kpanasonicnke_2503',['kPanasonicNke',['../IRsend_8h.html#a1b797a5e5176ac0eef49810bf7f40e6faf70fc847e204f60ab1dc5ecb330fc790',1,'IRsend.h']]], + ['kpanasoniconespace_2504',['kPanasonicOneSpace',['../ir__Panasonic_8cpp.html#a9069f2ab94cacbd301d7615795c155b1',1,'ir_Panasonic.cpp']]], + ['kpanasoniconespaceticks_2505',['kPanasonicOneSpaceTicks',['../ir__Panasonic_8cpp.html#aa7a8cb818a098bb8ec395af7f5dbc6d7',1,'ir_Panasonic.cpp']]], + ['kpanasonicrkr_2506',['kPanasonicRkr',['../IRsend_8h.html#a1b797a5e5176ac0eef49810bf7f40e6fab809a062f38eb61589cf5aa2db5789db',1,'IRsend.h']]], + ['kpanasonictick_2507',['kPanasonicTick',['../ir__Panasonic_8cpp.html#ab2fddd81fb53066257aeaa60069527a8',1,'ir_Panasonic.cpp']]], + ['kpanasonicunknown_2508',['kPanasonicUnknown',['../IRsend_8h.html#a1b797a5e5176ac0eef49810bf7f40e6fa3b23623c9580717d0ade5137200ae2a4',1,'IRsend.h']]], + ['kpanasoniczerospace_2509',['kPanasonicZeroSpace',['../ir__Panasonic_8cpp.html#a43f64a8326fd2447653c81488673fd21',1,'ir_Panasonic.cpp']]], + ['kpanasoniczerospaceticks_2510',['kPanasonicZeroSpaceTicks',['../ir__Panasonic_8cpp.html#a58fef1468dbd4c3963be58754f38b125',1,'ir_Panasonic.cpp']]], + ['kperiodoffset_2511',['kPeriodOffset',['../IRsend_8h.html#a3a451a4e72e39a4bbf75c62af0ac62f5',1,'IRsend.h']]], + ['kpioneerbitmark_2512',['kPioneerBitMark',['../ir__Pioneer_8cpp.html#a6117fd080ad88efcf943aef53dadd1ad',1,'ir_Pioneer.cpp']]], + ['kpioneerbitmarkticks_2513',['kPioneerBitMarkTicks',['../ir__Pioneer_8cpp.html#a1cd60e52b21df3b10ac5f668cf61df16',1,'ir_Pioneer.cpp']]], + ['kpioneerbits_2514',['kPioneerBits',['../IRremoteESP8266_8h.html#a6a7ccd31e0a6f967a219b1a53b89653b',1,'IRremoteESP8266.h']]], + ['kpioneerhdrmark_2515',['kPioneerHdrMark',['../ir__Pioneer_8cpp.html#a03c4df7d9eba6ab56df0451a18e5adbd',1,'ir_Pioneer.cpp']]], + ['kpioneerhdrmarkticks_2516',['kPioneerHdrMarkTicks',['../ir__Pioneer_8cpp.html#a9fc6ba8a158cae2d0d67af8e6cddd169',1,'ir_Pioneer.cpp']]], + ['kpioneerhdrspace_2517',['kPioneerHdrSpace',['../ir__Pioneer_8cpp.html#a1308ff993ce7d030bdef919d65f35e62',1,'ir_Pioneer.cpp']]], + ['kpioneerhdrspaceticks_2518',['kPioneerHdrSpaceTicks',['../ir__Pioneer_8cpp.html#a6c2ab5c384101f9184fd0960f21d13a5',1,'ir_Pioneer.cpp']]], + ['kpioneermincommandlength_2519',['kPioneerMinCommandLength',['../ir__Pioneer_8cpp.html#a22cb7d70bb0eb3b0ce6c7da3631d832f',1,'ir_Pioneer.cpp']]], + ['kpioneermincommandlengthticks_2520',['kPioneerMinCommandLengthTicks',['../ir__Pioneer_8cpp.html#a472ab59d00c439cc8832081492e742cc',1,'ir_Pioneer.cpp']]], + ['kpioneermingap_2521',['kPioneerMinGap',['../ir__Pioneer_8cpp.html#adc67bf557bd3474f18dfaa3125c1af41',1,'ir_Pioneer.cpp']]], + ['kpioneermingapticks_2522',['kPioneerMinGapTicks',['../ir__Pioneer_8cpp.html#abe0ebf83502225b39926ab745a8f8be2',1,'ir_Pioneer.cpp']]], + ['kpioneeronespace_2523',['kPioneerOneSpace',['../ir__Pioneer_8cpp.html#a5238b059346168128184bca93de16a54',1,'ir_Pioneer.cpp']]], + ['kpioneeronespaceticks_2524',['kPioneerOneSpaceTicks',['../ir__Pioneer_8cpp.html#af637842c88b54a022ac1ba3fef3fa041',1,'ir_Pioneer.cpp']]], + ['kpioneertick_2525',['kPioneerTick',['../ir__Pioneer_8cpp.html#a63de2364627344f86537ac82447c5cb4',1,'ir_Pioneer.cpp']]], + ['kpioneerzerospace_2526',['kPioneerZeroSpace',['../ir__Pioneer_8cpp.html#a3c6428f201dd3e32c171d6db44269d67',1,'ir_Pioneer.cpp']]], + ['kpioneerzerospaceticks_2527',['kPioneerZeroSpaceTicks',['../ir__Pioneer_8cpp.html#acdeea63204ce47f1556fa31bbed8a4a4',1,'ir_Pioneer.cpp']]], + ['kpowerbuttonstr_2528',['kPowerButtonStr',['../IRtext_8cpp.html#a69d36084b1410a06aa780edcda9428dd',1,'kPowerButtonStr(): IRtext.cpp'],['../IRtext_8h.html#adb54b8d070a4ba7f08b7d2d0f1c03d1c',1,'kPowerButtonStr(): IRtext.cpp']]], + ['kpowerfulstr_2529',['kPowerfulStr',['../IRtext_8cpp.html#a5dfc12bfa12ddf7da3ab6c216258284a',1,'kPowerfulStr(): IRtext.cpp'],['../IRtext_8h.html#a7980630cd028febca8245730dffa684b',1,'kPowerfulStr(): IRtext.cpp']]], + ['kpowerstr_2530',['kPowerStr',['../IRtext_8cpp.html#a5b4b43efe1f1c27d6aee90ebb3500792',1,'kPowerStr(): IRtext.cpp'],['../IRtext_8h.html#a47a76dc8d87d9694a36c6417d7e19dda',1,'kPowerStr(): IRtext.cpp']]], + ['kpowertogglestr_2531',['kPowerToggleStr',['../IRtext_8cpp.html#a2f7e242dc28cf61fb718bb5c1b681642',1,'kPowerToggleStr(): IRtext.cpp'],['../IRtext_8h.html#afd802a94c6146efb7812ef89f3bf0cc5',1,'kPowerToggleStr(): IRtext.cpp']]], + ['kpreviouspowerstr_2532',['kPreviousPowerStr',['../IRtext_8cpp.html#a2a5cd83ac519798debd7065eb03d5d72',1,'kPreviousPowerStr(): IRtext.cpp'],['../IRtext_8h.html#a9833364e538f50be227ff6c0b01f8f7c',1,'kPreviousPowerStr(): IRtext.cpp']]], + ['kprontodataoffset_2533',['kProntoDataOffset',['../ir__Pronto_8cpp.html#ac073b9ac759e09091b3d80af747656a1',1,'ir_Pronto.cpp']]], + ['kprontofreqfactor_2534',['kProntoFreqFactor',['../ir__Pronto_8cpp.html#aa63eef9baeb563c8494d85d13b956db8',1,'ir_Pronto.cpp']]], + ['kprontofreqoffset_2535',['kProntoFreqOffset',['../ir__Pronto_8cpp.html#a2fae4105559199e292121bcb847d9d52',1,'ir_Pronto.cpp']]], + ['kprontominlength_2536',['kProntoMinLength',['../IRremoteESP8266_8h.html#a25dd42234e21d41b0b4bc97e1fe921c4',1,'IRremoteESP8266.h']]], + ['kprontoseq1lenoffset_2537',['kProntoSeq1LenOffset',['../ir__Pronto_8cpp.html#a1df51305dddf233fc3963856e288366f',1,'ir_Pronto.cpp']]], + ['kprontoseq2lenoffset_2538',['kProntoSeq2LenOffset',['../ir__Pronto_8cpp.html#a708744a9f82547e5abc17d7ed866a648',1,'ir_Pronto.cpp']]], + ['kprontotypeoffset_2539',['kProntoTypeOffset',['../ir__Pronto_8cpp.html#a603ff34f28f270a98bf0bebdaf19bfbc',1,'ir_Pronto.cpp']]], + ['kprotocolstr_2540',['kProtocolStr',['../IRtext_8cpp.html#afb9e901ded9e88a48218282a7446ff63',1,'kProtocolStr(): IRtext.cpp'],['../IRtext_8h.html#ac50f97a0d33041fe4bba6e02c500c8ef',1,'kProtocolStr(): IRtext.cpp']]], + ['kpurifystr_2541',['kPurifyStr',['../IRtext_8cpp.html#a85c2b59f6cba1878648d3d8fe9d7f9a4',1,'kPurifyStr(): IRtext.cpp'],['../IRtext_8h.html#aae574dbb4b9f70db0e64386d61c21beb',1,'kPurifyStr(): IRtext.cpp']]], + ['kquietstr_2542',['kQuietStr',['../IRtext_8cpp.html#a6f85e3119eb884455f474ff909be6b53',1,'kQuietStr(): IRtext.cpp'],['../IRtext_8h.html#a7086660370d73d6f499972cf802db8f7',1,'kQuietStr(): IRtext.cpp']]], + ['krawbuf_2543',['kRawBuf',['../IRrecv_8h.html#aadfa37def10a1adeaf2cf4c09d7504e3',1,'IRrecv.h']]], + ['krawtick_2544',['kRawTick',['../IRrecv_8h.html#a373dde69c312b0122665e581eea1297b',1,'IRrecv.h']]], + ['krc5bits_2545',['kRC5Bits',['../IRremoteESP8266_8h.html#ad0935984e6518e340562665742199483',1,'IRremoteESP8266.h']]], + ['krc5mincommandlength_2546',['kRc5MinCommandLength',['../ir__RC5__RC6_8cpp.html#a32b5997148b53fd2984388f6d0384c35',1,'ir_RC5_RC6.cpp']]], + ['krc5mingap_2547',['kRc5MinGap',['../ir__RC5__RC6_8cpp.html#a26580409f593179d838c465647e35c41',1,'ir_RC5_RC6.cpp']]], + ['krc5rawbits_2548',['kRC5RawBits',['../IRremoteESP8266_8h.html#a955183d3358fcafea853014ddd890574',1,'IRremoteESP8266.h']]], + ['krc5samplesmin_2549',['kRc5SamplesMin',['../ir__RC5__RC6_8cpp.html#aa206173838597c760b4a01c36bbc771a',1,'ir_RC5_RC6.cpp']]], + ['krc5t1_2550',['kRc5T1',['../ir__RC5__RC6_8cpp.html#aa42cae15fa77a196eb8f198de09e19eb',1,'ir_RC5_RC6.cpp']]], + ['krc5togglemask_2551',['kRc5ToggleMask',['../ir__RC5__RC6_8cpp.html#ae3485c1c157d6d84a0385cb1bfb8833a',1,'ir_RC5_RC6.cpp']]], + ['krc5xbits_2552',['kRC5XBits',['../IRremoteESP8266_8h.html#abec3ebb217126560e824fa8b66d495bc',1,'IRremoteESP8266.h']]], + ['krc6_5f36bits_2553',['kRC6_36Bits',['../IRremoteESP8266_8h.html#a30a2cb328aa0d47f53aba56055ac74e0',1,'IRremoteESP8266.h']]], + ['krc6_5f36togglemask_2554',['kRc6_36ToggleMask',['../ir__RC5__RC6_8cpp.html#a31ae862ce2a43edd99bda647262b18fa',1,'ir_RC5_RC6.cpp']]], + ['krc6hdrmark_2555',['kRc6HdrMark',['../ir__RC5__RC6_8cpp.html#ae05bbb9f690cc92feb0a9c14b3b8c477',1,'ir_RC5_RC6.cpp']]], + ['krc6hdrmarkticks_2556',['kRc6HdrMarkTicks',['../ir__RC5__RC6_8cpp.html#aff2a5bc05ddf61d289c44a4fd093009c',1,'ir_RC5_RC6.cpp']]], + ['krc6hdrspace_2557',['kRc6HdrSpace',['../ir__RC5__RC6_8cpp.html#a0196311c9b116cf48c8f901fb6c93ac3',1,'ir_RC5_RC6.cpp']]], + ['krc6hdrspaceticks_2558',['kRc6HdrSpaceTicks',['../ir__RC5__RC6_8cpp.html#a35a9cc59fe5251a34c88e34b6a507fd3',1,'ir_RC5_RC6.cpp']]], + ['krc6mode0bits_2559',['kRC6Mode0Bits',['../IRremoteESP8266_8h.html#a84a6d3e15e98f7a4917d252d5665534a',1,'IRremoteESP8266.h']]], + ['krc6rptlength_2560',['kRc6RptLength',['../ir__RC5__RC6_8cpp.html#a4989f36b790a99545e708c8681b6b961',1,'ir_RC5_RC6.cpp']]], + ['krc6rptlengthticks_2561',['kRc6RptLengthTicks',['../ir__RC5__RC6_8cpp.html#acf2dc0074bfe7671deb8985eba4396e3',1,'ir_RC5_RC6.cpp']]], + ['krc6tick_2562',['kRc6Tick',['../ir__RC5__RC6_8cpp.html#aad98dc2541039634817609d4e297322f',1,'ir_RC5_RC6.cpp']]], + ['krc6togglemask_2563',['kRc6ToggleMask',['../ir__RC5__RC6_8cpp.html#a4df09270c1e9cda504026189e30829ff',1,'ir_RC5_RC6.cpp']]], + ['krcmmbitmark_2564',['kRcmmBitMark',['../ir__RCMM_8cpp.html#ad768f62bbd7e4df567c3e53ea0a8ed06',1,'ir_RCMM.cpp']]], + ['krcmmbitmarkticks_2565',['kRcmmBitMarkTicks',['../ir__RCMM_8cpp.html#a48aeb7992d30f8c7cfa04dbd14ea0996',1,'ir_RCMM.cpp']]], + ['krcmmbits_2566',['kRCMMBits',['../IRremoteESP8266_8h.html#a2bfaf393c2d77a594f2a0a5a763e84f5',1,'IRremoteESP8266.h']]], + ['krcmmbitspace0_2567',['kRcmmBitSpace0',['../ir__RCMM_8cpp.html#a34a7b22107461be18500f6d1ddf979e3',1,'ir_RCMM.cpp']]], + ['krcmmbitspace0ticks_2568',['kRcmmBitSpace0Ticks',['../ir__RCMM_8cpp.html#a0864042e8c098169d1d221fbd798cda3',1,'ir_RCMM.cpp']]], + ['krcmmbitspace1_2569',['kRcmmBitSpace1',['../ir__RCMM_8cpp.html#a812b9895f0eccaaf78752dc7030022aa',1,'ir_RCMM.cpp']]], + ['krcmmbitspace1ticks_2570',['kRcmmBitSpace1Ticks',['../ir__RCMM_8cpp.html#a89f945e0a91feccd505f0b8310a9ebb9',1,'ir_RCMM.cpp']]], + ['krcmmbitspace2_2571',['kRcmmBitSpace2',['../ir__RCMM_8cpp.html#aff0db6a8f28d3a307cd7bbb6dc90e3e3',1,'ir_RCMM.cpp']]], + ['krcmmbitspace2ticks_2572',['kRcmmBitSpace2Ticks',['../ir__RCMM_8cpp.html#a592dda1dd9239c9a015163b80cddf859',1,'ir_RCMM.cpp']]], + ['krcmmbitspace3_2573',['kRcmmBitSpace3',['../ir__RCMM_8cpp.html#a5e6351cbcb4c576871584dbf61d87d33',1,'ir_RCMM.cpp']]], + ['krcmmbitspace3ticks_2574',['kRcmmBitSpace3Ticks',['../ir__RCMM_8cpp.html#aa3f7d7e37ffa6bf9649eef7720770767',1,'ir_RCMM.cpp']]], + ['krcmmexcess_2575',['kRcmmExcess',['../ir__RCMM_8cpp.html#a3845e23031e92fd008157b0f95827432',1,'ir_RCMM.cpp']]], + ['krcmmhdrmark_2576',['kRcmmHdrMark',['../ir__RCMM_8cpp.html#a7fc5d5c1dc89ef0615fcaebaacc504df',1,'ir_RCMM.cpp']]], + ['krcmmhdrmarkticks_2577',['kRcmmHdrMarkTicks',['../ir__RCMM_8cpp.html#a00e93c94548ac081083ed2cabd614330',1,'ir_RCMM.cpp']]], + ['krcmmhdrspace_2578',['kRcmmHdrSpace',['../ir__RCMM_8cpp.html#af4dc2548c8069caf889612b3b28895ea',1,'ir_RCMM.cpp']]], + ['krcmmhdrspaceticks_2579',['kRcmmHdrSpaceTicks',['../ir__RCMM_8cpp.html#a87cd8bb5322fb38aecd20362a7df5016',1,'ir_RCMM.cpp']]], + ['krcmmmingap_2580',['kRcmmMinGap',['../ir__RCMM_8cpp.html#a94f9533bf18c0a2c2b6511ffa95ff5dc',1,'ir_RCMM.cpp']]], + ['krcmmmingapticks_2581',['kRcmmMinGapTicks',['../ir__RCMM_8cpp.html#aacb274f2da878aed511f6ab400cd51e9',1,'ir_RCMM.cpp']]], + ['krcmmrptlength_2582',['kRcmmRptLength',['../ir__RCMM_8cpp.html#a1dccf2b944d4eeb8b7dd2a1f66548a68',1,'ir_RCMM.cpp']]], + ['krcmmrptlengthticks_2583',['kRcmmRptLengthTicks',['../ir__RCMM_8cpp.html#a4cd637fa0a6071f9ea0b52c346ffe7f0',1,'ir_RCMM.cpp']]], + ['krcmmtick_2584',['kRcmmTick',['../ir__RCMM_8cpp.html#a9e1a3a26185d58ff675eec7485bc671f',1,'ir_RCMM.cpp']]], + ['krcmmtolerance_2585',['kRcmmTolerance',['../ir__RCMM_8cpp.html#a4b95480078186b3498ca6426e5bbc428',1,'ir_RCMM.cpp']]], + ['krcz01channelmask_2586',['kRcz01ChannelMask',['../ir__Doshisha_8cpp.html#a085b3d47e4cf8d8b4ba999ae58ec3533',1,'ir_Doshisha.cpp']]], + ['krcz01commandlevel1_2587',['kRcz01CommandLevel1',['../ir__Doshisha_8cpp.html#a436b801a282374de0f28e27828e1c4bf',1,'ir_Doshisha.cpp']]], + ['krcz01commandlevel2_2588',['kRcz01CommandLevel2',['../ir__Doshisha_8cpp.html#a311ef41fff985236216238565219bfe7',1,'ir_Doshisha.cpp']]], + ['krcz01commandlevel3_2589',['kRcz01CommandLevel3',['../ir__Doshisha_8cpp.html#a879bd44f482c87fbaf9fecaad8ed4c6d',1,'ir_Doshisha.cpp']]], + ['krcz01commandlevel4_2590',['kRcz01CommandLevel4',['../ir__Doshisha_8cpp.html#a52bad85f1a3918e3031297a6c6074b45',1,'ir_Doshisha.cpp']]], + ['krcz01commandleveldown_2591',['kRcz01CommandLevelDown',['../ir__Doshisha_8cpp.html#a1678269506503f1abf871ed0af6dcc2b',1,'ir_Doshisha.cpp']]], + ['krcz01commandlevelup_2592',['kRcz01CommandLevelUp',['../ir__Doshisha_8cpp.html#a4eba011d2b110a5348783534e957660e',1,'ir_Doshisha.cpp']]], + ['krcz01commandmask_2593',['kRcz01CommandMask',['../ir__Doshisha_8cpp.html#a148e2f676f895f4e3b77b39780e2ca94',1,'ir_Doshisha.cpp']]], + ['krcz01commandnightlight_2594',['kRcz01CommandNightLight',['../ir__Doshisha_8cpp.html#a47e9d5bf353cf8aef8199fb74693aa0f',1,'ir_Doshisha.cpp']]], + ['krcz01commandoff_2595',['kRcz01CommandOff',['../ir__Doshisha_8cpp.html#a97fd32975ab9fafa85e0704964780773',1,'ir_Doshisha.cpp']]], + ['krcz01commandon_2596',['kRcz01CommandOn',['../ir__Doshisha_8cpp.html#a7377eac8b1d938903fd43d7505dd8a49',1,'ir_Doshisha.cpp']]], + ['krcz01commandswitchchannel_2597',['kRcz01CommandSwitchChannel',['../ir__Doshisha_8cpp.html#afcd3fe98c34ef9572c1a68bd143e128b',1,'ir_Doshisha.cpp']]], + ['krcz01commandtimmer30_2598',['kRcz01CommandTimmer30',['../ir__Doshisha_8cpp.html#a3deebab67d01756f7776f0d11cbdef6e',1,'ir_Doshisha.cpp']]], + ['krcz01commandtimmer60_2599',['kRcz01CommandTimmer60',['../ir__Doshisha_8cpp.html#abac6b50227512508aeb5b6042a8380fd',1,'ir_Doshisha.cpp']]], + ['krcz01signature_2600',['kRcz01Signature',['../ir__Doshisha_8cpp.html#a35c6dff74ae1702933e33f02f743f616',1,'ir_Doshisha.cpp']]], + ['krcz01signaturemask_2601',['kRcz01SignatureMask',['../ir__Doshisha_8cpp.html#a1f3b9cdfba7cc7515611d7145b7318a5',1,'ir_Doshisha.cpp']]], + ['krepeat_2602',['kRepeat',['../IRrecv_8h.html#ae8b11750ba7f2e2d56343f770720ed89',1,'IRrecv.h']]], + ['krepeatstr_2603',['kRepeatStr',['../IRtext_8cpp.html#ad55ef2e023915f39c7ce77e7eeb1ad76',1,'kRepeatStr(): IRtext.cpp'],['../IRtext_8h.html#a74a53cc1564f75b36269eb1ca8c6235b',1,'kRepeatStr(): IRtext.cpp']]], + ['kright_2604',['kRight',['../namespacestdAc.html#aae50ee315fa9c9ec1a4078da40d6b147a2dd2b017192f8a09367d48c7648213c9',1,'stdAc']]], + ['krightmax_2605',['kRightMax',['../namespacestdAc.html#aae50ee315fa9c9ec1a4078da40d6b147a856bf9929ade459f451be17c97db4b32',1,'stdAc']]], + ['krightmaxstr_2606',['kRightMaxStr',['../IRtext_8cpp.html#af3e63659779f5fdb4aded4861521e564',1,'kRightMaxStr(): IRtext.cpp'],['../IRtext_8h.html#ac7a90008560fd1e7b4ed240f354d8fae',1,'kRightMaxStr(): IRtext.cpp']]], + ['krightstr_2607',['kRightStr',['../IRtext_8cpp.html#aacc9b0b21efb6053b75ed117d4ab9105',1,'kRightStr(): IRtext.cpp'],['../IRtext_8h.html#a953f9c48fcf87e81bf6f383e8fe8b1dd',1,'kRightStr(): IRtext.cpp']]], + ['kroomstr_2608',['kRoomStr',['../IRtext_8cpp.html#ab3f02ff54af9a94fd57d098838a4a642',1,'kRoomStr(): IRtext.cpp'],['../IRtext_8h.html#a5358a85538e4643c1cc109a7a0b90079',1,'kRoomStr(): IRtext.cpp']]], + ['ksamsung36bits_2609',['kSamsung36Bits',['../IRremoteESP8266_8h.html#a5e1e6f30a41f0d94652429a9e1034179',1,'IRremoteESP8266.h']]], + ['ksamsungacauto_2610',['kSamsungAcAuto',['../ir__Samsung_8h.html#a1b05ff970f45c57b13fc13d11e95396b',1,'ir_Samsung.h']]], + ['ksamsungacautotemp_2611',['kSamsungAcAutoTemp',['../ir__Samsung_8h.html#a87bb469afc0e2b6bad44634f3ba5e0ef',1,'ir_Samsung.h']]], + ['ksamsungacbeepoffset_2612',['kSamsungAcBeepOffset',['../ir__Samsung_8h.html#a12ae1e43d05d39c39d335c97223e003e',1,'ir_Samsung.h']]], + ['ksamsungacbitmark_2613',['kSamsungAcBitMark',['../ir__Samsung_8cpp.html#a37e6f36939f1a12ffe52907bbb64a4cf',1,'ir_Samsung.cpp']]], + ['ksamsungacbits_2614',['kSamsungAcBits',['../IRremoteESP8266_8h.html#adebe85ab48eb876ec15daacca246797c',1,'IRremoteESP8266.h']]], + ['ksamsungacbreezeoffset_2615',['kSamsungAcBreezeOffset',['../ir__Samsung_8h.html#a31d5463b3819fe41ce078b085c395a40',1,'ir_Samsung.h']]], + ['ksamsungacbreezeon_2616',['kSamsungAcBreezeOn',['../ir__Samsung_8h.html#a06299ba6942969f7b9472e752b50d4d7',1,'ir_Samsung.h']]], + ['ksamsungacbreezesize_2617',['kSamsungAcBreezeSize',['../ir__Samsung_8h.html#a1f6ec492aa58cb704147213e3b6f9f24',1,'ir_Samsung.h']]], + ['ksamsungacclean10offset_2618',['kSamsungAcClean10Offset',['../ir__Samsung_8h.html#a0982038a8c3e27972e69b83c350a0ff3',1,'ir_Samsung.h']]], + ['ksamsungacclean11offset_2619',['kSamsungAcClean11Offset',['../ir__Samsung_8h.html#a87666330f9a410ced00bf15c5f22daf2',1,'ir_Samsung.h']]], + ['ksamsungaccool_2620',['kSamsungAcCool',['../ir__Samsung_8h.html#a24d40e01f046f887b7d41dad67ad7555',1,'ir_Samsung.h']]], + ['ksamsungacdefaultrepeat_2621',['kSamsungAcDefaultRepeat',['../IRremoteESP8266_8h.html#a973f4e0189fc10805f67b67f708be1e4',1,'IRremoteESP8266.h']]], + ['ksamsungacdisplayoffset_2622',['kSamsungAcDisplayOffset',['../ir__Samsung_8h.html#af47c9229cbe569b93ad5f4986c4484ab',1,'ir_Samsung.h']]], + ['ksamsungacdry_2623',['kSamsungAcDry',['../ir__Samsung_8h.html#a6423976c7a41f526e7a878cecb257bbd',1,'ir_Samsung.h']]], + ['ksamsungacextendedbits_2624',['kSamsungAcExtendedBits',['../IRremoteESP8266_8h.html#a296e700965e70a622fe99675ff0438af',1,'IRremoteESP8266.h']]], + ['ksamsungacextendedstatelength_2625',['kSamsungAcExtendedStateLength',['../IRremoteESP8266_8h.html#a28039071f1130e9bc86efddd8265cbf9',1,'IRremoteESP8266.h']]], + ['ksamsungacfan_2626',['kSamsungAcFan',['../ir__Samsung_8h.html#a61d825254b26894a2f097ad92a7dbff2',1,'ir_Samsung.h']]], + ['ksamsungacfanauto_2627',['kSamsungAcFanAuto',['../ir__Samsung_8h.html#a37b29911f4d2b71dcdbd18a5d6dc301a',1,'ir_Samsung.h']]], + ['ksamsungacfanauto2_2628',['kSamsungAcFanAuto2',['../ir__Samsung_8h.html#aafa4319fb523b14d58371f757497e82a',1,'ir_Samsung.h']]], + ['ksamsungacfanhigh_2629',['kSamsungAcFanHigh',['../ir__Samsung_8h.html#a52cccad28fad5b9886ef408af02f56f9',1,'ir_Samsung.h']]], + ['ksamsungacfanlow_2630',['kSamsungAcFanLow',['../ir__Samsung_8h.html#a6f16b5b3f2dea3461f5d44379e8b8634',1,'ir_Samsung.h']]], + ['ksamsungacfanmed_2631',['kSamsungAcFanMed',['../ir__Samsung_8h.html#a798c3544dbd6bb6c8622cf45f88abc14',1,'ir_Samsung.h']]], + ['ksamsungacfanoffest_2632',['kSamsungAcFanOffest',['../ir__Samsung_8h.html#a1dd4a351c1a036972f741fbdafb05a7e',1,'ir_Samsung.h']]], + ['ksamsungacfansize_2633',['kSamsungAcFanSize',['../ir__Samsung_8h.html#a5b055e9951e23ba44bf1fdeed805b332',1,'ir_Samsung.h']]], + ['ksamsungacfanturbo_2634',['kSamsungAcFanTurbo',['../ir__Samsung_8h.html#af6c1432748eaa19df35531b87d197095',1,'ir_Samsung.h']]], + ['ksamsungachdrmark_2635',['kSamsungAcHdrMark',['../ir__Samsung_8cpp.html#ab7385ca5b7b417753b253a0f7cb3721b',1,'ir_Samsung.cpp']]], + ['ksamsungachdrspace_2636',['kSamsungAcHdrSpace',['../ir__Samsung_8cpp.html#a1b1f903fff13b10fb2431be9373e27cb',1,'ir_Samsung.cpp']]], + ['ksamsungacheat_2637',['kSamsungAcHeat',['../ir__Samsung_8h.html#a44ce6be7046ec4b4fe9caba7b71b8f0d',1,'ir_Samsung.h']]], + ['ksamsungacionoffset_2638',['kSamsungAcIonOffset',['../ir__Samsung_8h.html#aa7bbd222553072c092158421d1b9977f',1,'ir_Samsung.h']]], + ['ksamsungacmaxtemp_2639',['kSamsungAcMaxTemp',['../ir__Samsung_8h.html#a0a994796db81a3d56dd2c27cad448a71',1,'ir_Samsung.h']]], + ['ksamsungacmintemp_2640',['kSamsungAcMinTemp',['../ir__Samsung_8h.html#ad5f46ccb96335519f5633c33de0d8018',1,'ir_Samsung.h']]], + ['ksamsungacmodeoffset_2641',['kSamsungAcModeOffset',['../ir__Samsung_8h.html#a64b2aceb5c0d4dbea2d4697efe65aef2',1,'ir_Samsung.h']]], + ['ksamsungaconespace_2642',['kSamsungAcOneSpace',['../ir__Samsung_8cpp.html#ab106d9b7efb165eed83ae2ccef9a49b4',1,'ir_Samsung.cpp']]], + ['ksamsungacpower1offset_2643',['kSamsungAcPower1Offset',['../ir__Samsung_8h.html#aa6a4ff05acfabf24e4dfc126e583c46c',1,'ir_Samsung.h']]], + ['ksamsungacpower6offset_2644',['kSamsungAcPower6Offset',['../ir__Samsung_8h.html#a90591c7d6069d81493f894328d595187',1,'ir_Samsung.h']]], + ['ksamsungacpower6size_2645',['kSamsungAcPower6Size',['../ir__Samsung_8h.html#ace0a7a2cfedbb77d05de53abc5906992',1,'ir_Samsung.h']]], + ['ksamsungacpowerful10offset_2646',['kSamsungAcPowerful10Offset',['../ir__Samsung_8h.html#a7f92d734af799e058723e898d3ebdd30',1,'ir_Samsung.h']]], + ['ksamsungacpowerful10on_2647',['kSamsungAcPowerful10On',['../ir__Samsung_8h.html#aa05bb4788febba1f56b2b3929ac273a3',1,'ir_Samsung.h']]], + ['ksamsungacpowerful10size_2648',['kSamsungAcPowerful10Size',['../ir__Samsung_8h.html#a19ede17e420f68ea552497461e69006a',1,'ir_Samsung.h']]], + ['ksamsungacpowerfulmask8_2649',['kSamsungAcPowerfulMask8',['../ir__Samsung_8h.html#a39e23325e35688a3641c467b720381ce',1,'ir_Samsung.h']]], + ['ksamsungacpowersection_2650',['kSamsungAcPowerSection',['../ir__Samsung_8h.html#a9264b5d640d9052c153562fd38415676',1,'ir_Samsung.h']]], + ['ksamsungacquiet1offset_2651',['kSamsungAcQuiet1Offset',['../ir__Samsung_8h.html#ab029485b433f7eef6413d8194790c566',1,'ir_Samsung.h']]], + ['ksamsungacquiet5offset_2652',['kSamsungAcQuiet5Offset',['../ir__Samsung_8h.html#ae10abd66772da9bab4ba266f29e7ec75',1,'ir_Samsung.h']]], + ['ksamsungacsectiongap_2653',['kSamsungAcSectionGap',['../ir__Samsung_8cpp.html#a9752fc615c215a93c1ee65edca3a359e',1,'ir_Samsung.cpp']]], + ['ksamsungacsectionlength_2654',['kSamsungAcSectionLength',['../ir__Samsung_8h.html#ad3faedf7b111f1b91d671666e38ce6f3',1,'ir_Samsung.h']]], + ['ksamsungacsectionmark_2655',['kSamsungAcSectionMark',['../ir__Samsung_8cpp.html#a4304073cddaa2da9613dedce499fee56',1,'ir_Samsung.cpp']]], + ['ksamsungacsections_2656',['kSamsungAcSections',['../ir__Samsung_8cpp.html#a86185d98d6e891a17688d9d2a0fa7114',1,'ir_Samsung.cpp']]], + ['ksamsungacsectionspace_2657',['kSamsungAcSectionSpace',['../ir__Samsung_8cpp.html#a4837f502ef9b7c972ec409cf4fc3c605',1,'ir_Samsung.cpp']]], + ['ksamsungacstatelength_2658',['kSamsungAcStateLength',['../IRremoteESP8266_8h.html#a2d07d8c8917fee072a261d00e67e0d36',1,'IRremoteESP8266.h']]], + ['ksamsungacswingmove_2659',['kSamsungAcSwingMove',['../ir__Samsung_8h.html#ab2d2b422e3972f77aef23f77c7cfbbac',1,'ir_Samsung.h']]], + ['ksamsungacswingoffset_2660',['kSamsungAcSwingOffset',['../ir__Samsung_8h.html#ab71772d77c56cf4d01f3ce4ab751a55c',1,'ir_Samsung.h']]], + ['ksamsungacswingsize_2661',['kSamsungAcSwingSize',['../ir__Samsung_8h.html#a1b50618058108826f9103f46bf7677ee',1,'ir_Samsung.h']]], + ['ksamsungacswingstop_2662',['kSamsungAcSwingStop',['../ir__Samsung_8h.html#a37c1720d66c4ba02e368946e53036367',1,'ir_Samsung.h']]], + ['ksamsungaczerospace_2663',['kSamsungAcZeroSpace',['../ir__Samsung_8cpp.html#a7492a25e730f93f22c099ab687621b18',1,'ir_Samsung.cpp']]], + ['ksamsungbitmark_2664',['kSamsungBitMark',['../ir__Samsung_8cpp.html#a03f9ae317a7a701437c8015dfde4401f',1,'ir_Samsung.cpp']]], + ['ksamsungbitmarkticks_2665',['kSamsungBitMarkTicks',['../ir__Samsung_8cpp.html#afe1663f83396f7e5cf9bfc32f321e539',1,'ir_Samsung.cpp']]], + ['ksamsungbits_2666',['kSamsungBits',['../IRremoteESP8266_8h.html#a7c1c015cce09284799cbf5a2f21ee170',1,'IRremoteESP8266.h']]], + ['ksamsunghdrmark_2667',['kSamsungHdrMark',['../ir__Samsung_8cpp.html#a3d0598585af609af4c8d5004789d2df7',1,'ir_Samsung.cpp']]], + ['ksamsunghdrmarkticks_2668',['kSamsungHdrMarkTicks',['../ir__Samsung_8cpp.html#a0c81f486877d24bfd40215b089c52f2a',1,'ir_Samsung.cpp']]], + ['ksamsunghdrspace_2669',['kSamsungHdrSpace',['../ir__Samsung_8cpp.html#a2f55c53bfc72de06ff202c8ec401163d',1,'ir_Samsung.cpp']]], + ['ksamsunghdrspaceticks_2670',['kSamsungHdrSpaceTicks',['../ir__Samsung_8cpp.html#a1ae96cedfa4ed26869d295cfbb8056dd',1,'ir_Samsung.cpp']]], + ['ksamsungmingap_2671',['kSamsungMinGap',['../ir__Samsung_8cpp.html#ab13edb242547803b386aa8539a4b9470',1,'ir_Samsung.cpp']]], + ['ksamsungmingapticks_2672',['kSamsungMinGapTicks',['../ir__Samsung_8cpp.html#a55d79dcfcd43f05ebe456a9a2fce3ff0',1,'ir_Samsung.cpp']]], + ['ksamsungminmessagelength_2673',['kSamsungMinMessageLength',['../ir__Samsung_8cpp.html#ae2ec2e45f91f872e85c250c7aac0efc1',1,'ir_Samsung.cpp']]], + ['ksamsungminmessagelengthticks_2674',['kSamsungMinMessageLengthTicks',['../ir__Samsung_8cpp.html#a6d436a1b71158ff9b5d7ae21344cd7d2',1,'ir_Samsung.cpp']]], + ['ksamsungonespace_2675',['kSamsungOneSpace',['../ir__Samsung_8cpp.html#ab486b048d13f44623ee291d4221c2a1b',1,'ir_Samsung.cpp']]], + ['ksamsungonespaceticks_2676',['kSamsungOneSpaceTicks',['../ir__Samsung_8cpp.html#a484a1e3ce3dcbbef15be559bfb5822d0',1,'ir_Samsung.cpp']]], + ['ksamsungrptspace_2677',['kSamsungRptSpace',['../ir__Samsung_8cpp.html#a1cc2f3bcd7f2ca36f0a726828c14aa74',1,'ir_Samsung.cpp']]], + ['ksamsungrptspaceticks_2678',['kSamsungRptSpaceTicks',['../ir__Samsung_8cpp.html#a6864f78ad1428358acbc8b46796e50cc',1,'ir_Samsung.cpp']]], + ['ksamsungtick_2679',['kSamsungTick',['../ir__Samsung_8cpp.html#accd7d51c2714bd383170831372f57bc5',1,'ir_Samsung.cpp']]], + ['ksamsungzerospace_2680',['kSamsungZeroSpace',['../ir__Samsung_8cpp.html#ae2c828a3d099d6195208a3794022587e',1,'ir_Samsung.cpp']]], + ['ksamsungzerospaceticks_2681',['kSamsungZeroSpaceTicks',['../ir__Samsung_8cpp.html#aea63a73a5b0af2c173bc473ee2447a93',1,'ir_Samsung.cpp']]], + ['ksanyolc7461addressbits_2682',['kSanyoLC7461AddressBits',['../IRremoteESP8266_8h.html#a7e15e988acbea0fb4dfaee6f5bfa12d0',1,'IRremoteESP8266.h']]], + ['ksanyolc7461addressmask_2683',['kSanyoLc7461AddressMask',['../ir__Sanyo_8cpp.html#a785ccc066e433f11791f8a30243944d3',1,'ir_Sanyo.cpp']]], + ['ksanyolc7461bitmark_2684',['kSanyoLc7461BitMark',['../ir__Sanyo_8cpp.html#a1360ba5ac3f30715c00a6a65155cfec8',1,'ir_Sanyo.cpp']]], + ['ksanyolc7461bits_2685',['kSanyoLC7461Bits',['../IRremoteESP8266_8h.html#ad067db05b273337e0df38d529094c9e8',1,'IRremoteESP8266.h']]], + ['ksanyolc7461commandbits_2686',['kSanyoLC7461CommandBits',['../IRremoteESP8266_8h.html#a5cd69a192be51634ce72a40398a6c0d7',1,'IRremoteESP8266.h']]], + ['ksanyolc7461commandmask_2687',['kSanyoLc7461CommandMask',['../ir__Sanyo_8cpp.html#abdd072e210a7616d564a9d4a7f798ad3',1,'ir_Sanyo.cpp']]], + ['ksanyolc7461hdrmark_2688',['kSanyoLc7461HdrMark',['../ir__Sanyo_8cpp.html#a0b2e520442dd96f8cd77969230713277',1,'ir_Sanyo.cpp']]], + ['ksanyolc7461hdrspace_2689',['kSanyoLc7461HdrSpace',['../ir__Sanyo_8cpp.html#aa9ca2469e22f66d6e5e3f4ef952484ba',1,'ir_Sanyo.cpp']]], + ['ksanyolc7461mincommandlength_2690',['kSanyoLc7461MinCommandLength',['../ir__Sanyo_8cpp.html#a237fac9264bba0014124a815133868b2',1,'ir_Sanyo.cpp']]], + ['ksanyolc7461mingap_2691',['kSanyoLc7461MinGap',['../ir__Sanyo_8cpp.html#aff7f31500dbe9939e223bed6b6c631a8',1,'ir_Sanyo.cpp']]], + ['ksanyolc7461onespace_2692',['kSanyoLc7461OneSpace',['../ir__Sanyo_8cpp.html#a52716e37d6943b01e9df37956f1a83de',1,'ir_Sanyo.cpp']]], + ['ksanyolc7461zerospace_2693',['kSanyoLc7461ZeroSpace',['../ir__Sanyo_8cpp.html#a4e386992c8fca642c259e86e34729a4d',1,'ir_Sanyo.cpp']]], + ['ksanyosa8650bbits_2694',['kSanyoSA8650BBits',['../IRremoteESP8266_8h.html#a2c572c8bfa811b7dc3a8a537cc642b85',1,'IRremoteESP8266.h']]], + ['ksanyosa8650bdoublespaceusecs_2695',['kSanyoSa8650bDoubleSpaceUsecs',['../ir__Sanyo_8cpp.html#a828caf6fd05e81cedee67c558b88a0b6',1,'ir_Sanyo.cpp']]], + ['ksanyosa8650bhdrmark_2696',['kSanyoSa8650bHdrMark',['../ir__Sanyo_8cpp.html#a9d0472d183a96b8ca71a2b704a06cac8',1,'ir_Sanyo.cpp']]], + ['ksanyosa8650bhdrspace_2697',['kSanyoSa8650bHdrSpace',['../ir__Sanyo_8cpp.html#ab432df3bd299b72b4449672d611798b7',1,'ir_Sanyo.cpp']]], + ['ksanyosa8650bonemark_2698',['kSanyoSa8650bOneMark',['../ir__Sanyo_8cpp.html#a8854c7bd32c1ec53e8e1869cd9dd8cdd',1,'ir_Sanyo.cpp']]], + ['ksanyosa8650brptlength_2699',['kSanyoSa8650bRptLength',['../ir__Sanyo_8cpp.html#a327ee6de7027aacfa9aa6ee8bdc74e3e',1,'ir_Sanyo.cpp']]], + ['ksanyosa8650bzeromark_2700',['kSanyoSa8650bZeroMark',['../ir__Sanyo_8cpp.html#a516a45a7934f23274fa302d7e711b43c',1,'ir_Sanyo.cpp']]], + ['ksavestr_2701',['kSaveStr',['../IRtext_8cpp.html#a24f9462727ee596a3ae16393c33e3ebc',1,'kSaveStr(): IRtext.cpp'],['../IRtext_8h.html#acb40b78a5269c43cc3e4f44d3da01069',1,'kSaveStr(): IRtext.cpp']]], + ['ksecondsstr_2702',['kSecondsStr',['../IRtext_8cpp.html#a282cb9785839a9da66a9333d788c0fb1',1,'kSecondsStr(): IRtext.cpp'],['../IRtext_8h.html#ad736b59d3fe45b3c06bd301af4d7b455',1,'kSecondsStr(): IRtext.cpp']]], + ['ksecondstr_2703',['kSecondStr',['../IRtext_8cpp.html#a5ec55e16709cbd2c4b1ff8c72c01c1f5',1,'kSecondStr(): IRtext.cpp'],['../IRtext_8h.html#ad3489e1c008bc517b8bf0271c40252d1',1,'kSecondStr(): IRtext.cpp']]], + ['ksensorstr_2704',['kSensorStr',['../IRtext_8cpp.html#aa7e6eab2fbc832f98d6560f62453c934',1,'kSensorStr(): IRtext.cpp'],['../IRtext_8h.html#a56ee9a96dd0a7ee0a5f95c286f6ea7e8',1,'kSensorStr(): IRtext.cpp']]], + ['ksensortempstr_2705',['kSensorTempStr',['../IRtext_8cpp.html#a756daa989457676d2af255428a01e1d5',1,'kSensorTempStr(): IRtext.cpp'],['../IRtext_8h.html#a03e76a09bade0c229fea1ce31fe8c9a1',1,'kSensorTempStr(): IRtext.cpp']]], + ['ksetstr_2706',['kSetStr',['../IRtext_8cpp.html#a27b5e437df44d4d41db9b296a1f236a1',1,'kSetStr(): IRtext.cpp'],['../IRtext_8h.html#a31d3426b8a8d1a35c47c88ef00023fce',1,'kSetStr(): IRtext.cpp']]], + ['ksharpacauto_2707',['kSharpAcAuto',['../ir__Sharp_8h.html#ad4e228b234598a84e11a76e7f2d27199',1,'ir_Sharp.h']]], + ['ksharpacbitcleanoffset_2708',['kSharpAcBitCleanOffset',['../ir__Sharp_8h.html#a3460827972f31d05070c638a57782286',1,'ir_Sharp.h']]], + ['ksharpacbitionoffset_2709',['kSharpAcBitIonOffset',['../ir__Sharp_8h.html#a73f967e9950d04941ed9f6815815fb23',1,'ir_Sharp.h']]], + ['ksharpacbitmark_2710',['kSharpAcBitMark',['../ir__Sharp_8h.html#ae73dd2c91b531bf3a52641b36f56ead7',1,'ir_Sharp.h']]], + ['ksharpacbits_2711',['kSharpAcBits',['../IRremoteESP8266_8h.html#a6c106a982acced5d8aeef98644002ca2',1,'IRremoteESP8266.h']]], + ['ksharpacbittimerenabled_2712',['kSharpAcBitTimerEnabled',['../ir__Sharp_8h.html#a083863299df4ff081be0add9d5082700',1,'ir_Sharp.h']]], + ['ksharpacbittimertype_2713',['kSharpAcBitTimerType',['../ir__Sharp_8h.html#ad47cf2f20c4589b9cbe6b583d62b4675',1,'ir_Sharp.h']]], + ['ksharpacbyteclean_2714',['kSharpAcByteClean',['../ir__Sharp_8h.html#a2f4a4ddf407413a52d45c955ebd5bcd5',1,'ir_Sharp.h']]], + ['ksharpacbytefan_2715',['kSharpAcByteFan',['../ir__Sharp_8h.html#a24139aa535ca54dcf45558da5ee2ac56',1,'ir_Sharp.h']]], + ['ksharpacbyteion_2716',['kSharpAcByteIon',['../ir__Sharp_8h.html#aaceee11c539050ba5ac368b9612131a4',1,'ir_Sharp.h']]], + ['ksharpacbytemode_2717',['kSharpAcByteMode',['../ir__Sharp_8h.html#af7d8a2ab79ae4f2ad48e569576fd34e8',1,'ir_Sharp.h']]], + ['ksharpacbytepowerspecial_2718',['kSharpAcBytePowerSpecial',['../ir__Sharp_8h.html#a44d180bd3babec15143ba8ea8aa18906',1,'ir_Sharp.h']]], + ['ksharpacbytespecial_2719',['kSharpAcByteSpecial',['../ir__Sharp_8h.html#a78ba1ef4993661f9dfaad776dff1b43e',1,'ir_Sharp.h']]], + ['ksharpacbyteswing_2720',['kSharpAcByteSwing',['../ir__Sharp_8h.html#aee580a3c6cfd75f75f46852d0f3df0db',1,'ir_Sharp.h']]], + ['ksharpacbytetemp_2721',['kSharpAcByteTemp',['../ir__Sharp_8h.html#a1b67ab12ed664517124fe3c1d7325927',1,'ir_Sharp.h']]], + ['ksharpacbytetimer_2722',['kSharpAcByteTimer',['../ir__Sharp_8h.html#af2fc9b6abae8ca6ca0d01b8c924386be',1,'ir_Sharp.h']]], + ['ksharpaccool_2723',['kSharpAcCool',['../ir__Sharp_8h.html#ae828d7e915f69cc1e9538839fc51c895',1,'ir_Sharp.h']]], + ['ksharpacdefaultrepeat_2724',['kSharpAcDefaultRepeat',['../IRremoteESP8266_8h.html#a7f0438831899e3df16f9002717c818b9',1,'IRremoteESP8266.h']]], + ['ksharpacdry_2725',['kSharpAcDry',['../ir__Sharp_8h.html#a50ae949b473ed4a6482fa00d747b2c0f',1,'ir_Sharp.h']]], + ['ksharpacfanauto_2726',['kSharpAcFanAuto',['../ir__Sharp_8h.html#a2ef78269271593420ea2bdc20025ca69',1,'ir_Sharp.h']]], + ['ksharpacfanhigh_2727',['kSharpAcFanHigh',['../ir__Sharp_8h.html#af29136d64c2f2a2515918ccf0ff0f594',1,'ir_Sharp.h']]], + ['ksharpacfanmax_2728',['kSharpAcFanMax',['../ir__Sharp_8h.html#a8b0aaa58a5f4caabea84e3b448793054',1,'ir_Sharp.h']]], + ['ksharpacfanmed_2729',['kSharpAcFanMed',['../ir__Sharp_8h.html#a7607f054da76f5e1508abf42d9cd71fc',1,'ir_Sharp.h']]], + ['ksharpacfanmin_2730',['kSharpAcFanMin',['../ir__Sharp_8h.html#a2372fdfbb0d8c2163a3eae5b8eda570a',1,'ir_Sharp.h']]], + ['ksharpacfanoffset_2731',['kSharpAcFanOffset',['../ir__Sharp_8h.html#ae95f02db8d9799ce726f5f467922a36c',1,'ir_Sharp.h']]], + ['ksharpacfansize_2732',['kSharpAcFanSize',['../ir__Sharp_8h.html#a2640f5c4eb0b4e62b9e2124a1fbfb6d2',1,'ir_Sharp.h']]], + ['ksharpacgap_2733',['kSharpAcGap',['../ir__Sharp_8h.html#a777eb0358ce3ef4528f086ff9ff7cd8d',1,'ir_Sharp.h']]], + ['ksharpachdrmark_2734',['kSharpAcHdrMark',['../ir__Sharp_8h.html#aff6f1e55de051762a0def881a5bb555c',1,'ir_Sharp.h']]], + ['ksharpachdrspace_2735',['kSharpAcHdrSpace',['../ir__Sharp_8h.html#a0ea5ff96afd358a8ad1be8d8ed808f04',1,'ir_Sharp.h']]], + ['ksharpacheat_2736',['kSharpAcHeat',['../ir__Sharp_8h.html#ab546d06a0b1f3477f88282f764f208cb',1,'ir_Sharp.h']]], + ['ksharpacmaxtemp_2737',['kSharpAcMaxTemp',['../ir__Sharp_8h.html#a6cfb060ea8c2f650fdd73b055cfda00a',1,'ir_Sharp.h']]], + ['ksharpacmintemp_2738',['kSharpAcMinTemp',['../ir__Sharp_8h.html#ad9ac5214b6cc780d9424ec7d038fe837',1,'ir_Sharp.h']]], + ['ksharpacmodesize_2739',['kSharpAcModeSize',['../ir__Sharp_8h.html#a7dfcf91a08bc37884cc4882c60004736',1,'ir_Sharp.h']]], + ['ksharpacofftimertype_2740',['kSharpAcOffTimerType',['../ir__Sharp_8h.html#ada633bea9c6c2ffd234c8262e92cebd5',1,'ir_Sharp.h']]], + ['ksharpaconespace_2741',['kSharpAcOneSpace',['../ir__Sharp_8h.html#a20e8eb7c8763fbddb20530badbaab38b',1,'ir_Sharp.h']]], + ['ksharpacontimertype_2742',['kSharpAcOnTimerType',['../ir__Sharp_8h.html#adce8625b00931645c7ccf54edf263c59',1,'ir_Sharp.h']]], + ['ksharpacpoweroff_2743',['kSharpAcPowerOff',['../ir__Sharp_8h.html#a5c13882a47bdd289507e8a5a23ec99d6',1,'ir_Sharp.h']]], + ['ksharpacpoweron_2744',['kSharpAcPowerOn',['../ir__Sharp_8h.html#af485487ea50dd2f9bc153e5f83dc5cf9',1,'ir_Sharp.h']]], + ['ksharpacpoweronfromoff_2745',['kSharpAcPowerOnFromOff',['../ir__Sharp_8h.html#ae484cf776fa47542f4d693c29052fc9f',1,'ir_Sharp.h']]], + ['ksharpacpowersetspecialoff_2746',['kSharpAcPowerSetSpecialOff',['../ir__Sharp_8h.html#a93b22ba4b5e68f8185ed28a6bb7c05dd',1,'ir_Sharp.h']]], + ['ksharpacpowersetspecialoffset_2747',['kSharpAcPowerSetSpecialOffset',['../ir__Sharp_8h.html#a0603455573e1dd203a5f6718efc12085',1,'ir_Sharp.h']]], + ['ksharpacpowersetspecialon_2748',['kSharpAcPowerSetSpecialOn',['../ir__Sharp_8h.html#a67aff6b22c0cfb89debb8ade7239f07e',1,'ir_Sharp.h']]], + ['ksharpacpowerspecialsize_2749',['kSharpAcPowerSpecialSize',['../ir__Sharp_8h.html#a233d545e942de27ec9e96d0d5e7afdb3',1,'ir_Sharp.h']]], + ['ksharpacpowertimersetting_2750',['kSharpAcPowerTimerSetting',['../ir__Sharp_8h.html#a208cb9446ea1f42db42a1f6e24b61219',1,'ir_Sharp.h']]], + ['ksharpacpowerunknown_2751',['kSharpAcPowerUnknown',['../ir__Sharp_8h.html#ab20172b860fa1401607f0678c682640f',1,'ir_Sharp.h']]], + ['ksharpacspecialfan_2752',['kSharpAcSpecialFan',['../ir__Sharp_8h.html#a6c1a1c535150f973eecb1a131d0c4780',1,'ir_Sharp.h']]], + ['ksharpacspecialpower_2753',['kSharpAcSpecialPower',['../ir__Sharp_8h.html#a843585897995ee15e39af0d452d8660d',1,'ir_Sharp.h']]], + ['ksharpacspecialswing_2754',['kSharpAcSpecialSwing',['../ir__Sharp_8h.html#a34127a7df393d2a5a84ca90e60e8507a',1,'ir_Sharp.h']]], + ['ksharpacspecialtempecono_2755',['kSharpAcSpecialTempEcono',['../ir__Sharp_8h.html#af2dcb54fc26802d1818ef88e6ddfc819',1,'ir_Sharp.h']]], + ['ksharpacspecialtimer_2756',['kSharpAcSpecialTimer',['../ir__Sharp_8h.html#a539b21c344db53fbfd4f17c91ab98139',1,'ir_Sharp.h']]], + ['ksharpacspecialtimerhalfhour_2757',['kSharpAcSpecialTimerHalfHour',['../ir__Sharp_8h.html#a1f9bf40a4af95689947c09559ed049bf',1,'ir_Sharp.h']]], + ['ksharpacspecialturbo_2758',['kSharpAcSpecialTurbo',['../ir__Sharp_8h.html#a270bb2bc83d4eb8974f498dd8eb299bb',1,'ir_Sharp.h']]], + ['ksharpacstatelength_2759',['kSharpAcStateLength',['../IRremoteESP8266_8h.html#a5192edb9406a8572e393918bab69e3c6',1,'IRremoteESP8266.h']]], + ['ksharpacswingnotoggle_2760',['kSharpAcSwingNoToggle',['../ir__Sharp_8h.html#a9c56d4f694ea69921ba2cb75f67426d6',1,'ir_Sharp.h']]], + ['ksharpacswingoffset_2761',['kSharpAcSwingOffset',['../ir__Sharp_8h.html#a61c5356e645867fa2eeda02c83e5b9ae',1,'ir_Sharp.h']]], + ['ksharpacswingsize_2762',['kSharpAcSwingSize',['../ir__Sharp_8h.html#aafec87d2ddea0fd56d176f1b5f80a6fa',1,'ir_Sharp.h']]], + ['ksharpacswingtoggle_2763',['kSharpAcSwingToggle',['../ir__Sharp_8h.html#aa6db653d25f67214819292b8f86af0e6',1,'ir_Sharp.h']]], + ['ksharpactimerhoursmax_2764',['kSharpAcTimerHoursMax',['../ir__Sharp_8h.html#a63af01993ba1e539dfb8dae67f42b9ae',1,'ir_Sharp.h']]], + ['ksharpactimerhoursoff_2765',['kSharpAcTimerHoursOff',['../ir__Sharp_8h.html#a462c10c12d828ba58d589cc365bd7be3',1,'ir_Sharp.h']]], + ['ksharpactimerhoursoffset_2766',['kSharpAcTimerHoursOffset',['../ir__Sharp_8h.html#aeb8d6ca49ba029bdb3663ff6b9c2cc4d',1,'ir_Sharp.h']]], + ['ksharpactimerhourssize_2767',['kSharpAcTimerHoursSize',['../ir__Sharp_8h.html#a965ed2ef8ba32a325ec41a351d88c17d',1,'ir_Sharp.h']]], + ['ksharpactimerincrement_2768',['kSharpAcTimerIncrement',['../ir__Sharp_8h.html#af32638e308a7034eb013b7ea9569273e',1,'ir_Sharp.h']]], + ['ksharpaczerospace_2769',['kSharpAcZeroSpace',['../ir__Sharp_8h.html#a5310e0404daae1a6e534dbaeaa9a9939',1,'ir_Sharp.h']]], + ['ksharpaddressbits_2770',['kSharpAddressBits',['../IRremoteESP8266_8h.html#a79c2f3cc459267cf0261124ddef47f5e',1,'IRremoteESP8266.h']]], + ['ksharpaddressmask_2771',['kSharpAddressMask',['../ir__Sharp_8cpp.html#a84fba003383cd4652fc804b97002f464',1,'ir_Sharp.cpp']]], + ['ksharpbitmark_2772',['kSharpBitMark',['../ir__Sharp_8cpp.html#ae2adc2bffb2b024faab8da363621733f',1,'ir_Sharp.cpp']]], + ['ksharpbitmarkticks_2773',['kSharpBitMarkTicks',['../ir__Sharp_8cpp.html#aa64bd0c359add4038c0143b5774627bb',1,'ir_Sharp.cpp']]], + ['ksharpbits_2774',['kSharpBits',['../IRremoteESP8266_8h.html#a8a74f9d7cec751cc0945fd89fa6237ae',1,'IRremoteESP8266.h']]], + ['ksharpcommandbits_2775',['kSharpCommandBits',['../IRremoteESP8266_8h.html#ae4cdfc8e358ec738d20c1bda49842ccf',1,'IRremoteESP8266.h']]], + ['ksharpcommandmask_2776',['kSharpCommandMask',['../ir__Sharp_8cpp.html#ad44eda54ade4bef4fdf4451fdb784950',1,'ir_Sharp.cpp']]], + ['ksharpgap_2777',['kSharpGap',['../ir__Sharp_8cpp.html#a77015be2a04274bcb332ec21cb75251e',1,'ir_Sharp.cpp']]], + ['ksharpgapticks_2778',['kSharpGapTicks',['../ir__Sharp_8cpp.html#a4aa110ec2934797f71ddf9bcd34498d1',1,'ir_Sharp.cpp']]], + ['ksharponespace_2779',['kSharpOneSpace',['../ir__Sharp_8cpp.html#a3359539480a203db37c2cf2efd88fdcc',1,'ir_Sharp.cpp']]], + ['ksharponespaceticks_2780',['kSharpOneSpaceTicks',['../ir__Sharp_8cpp.html#a12e18dfd195faae6ca581936434c9063',1,'ir_Sharp.cpp']]], + ['ksharptick_2781',['kSharpTick',['../ir__Sharp_8cpp.html#af417ab19220576243753903657923ba7',1,'ir_Sharp.cpp']]], + ['ksharptogglemask_2782',['kSharpToggleMask',['../ir__Sharp_8cpp.html#a2701123f01683c6927c23c7699bce13a',1,'ir_Sharp.cpp']]], + ['ksharpzerospace_2783',['kSharpZeroSpace',['../ir__Sharp_8cpp.html#ac2ad6123d938999e234896e1635e3063',1,'ir_Sharp.cpp']]], + ['ksharpzerospaceticks_2784',['kSharpZeroSpaceTicks',['../ir__Sharp_8cpp.html#af8c638f77ff29c2d20555343be80e5f0',1,'ir_Sharp.cpp']]], + ['ksherwoodbits_2785',['kSherwoodBits',['../IRremoteESP8266_8h.html#a94abd640c9e7aa225f4a8873a1ddea6a',1,'IRremoteESP8266.h']]], + ['ksherwoodminrepeat_2786',['kSherwoodMinRepeat',['../IRremoteESP8266_8h.html#a2e00b92b55657fc4e140eb85e3a414dc',1,'IRremoteESP8266.h']]], + ['ksilentstr_2787',['kSilentStr',['../IRtext_8cpp.html#a398d3c627c5b95c5d7adfb5308fc7de0',1,'kSilentStr(): IRtext.cpp'],['../IRtext_8h.html#a8efb4256a49dc0acd27d6995851d585e',1,'kSilentStr(): IRtext.cpp']]], + ['ksinglerepeat_2788',['kSingleRepeat',['../IRremoteESP8266_8h.html#a46835b1e2d279570fd818749e88180d4',1,'IRremoteESP8266.h']]], + ['ksleepstr_2789',['kSleepStr',['../IRtext_8cpp.html#a38068788c0ef50e6034dbcffeec1eb36',1,'kSleepStr(): IRtext.cpp'],['../IRtext_8h.html#af9ac743c367e179723b128ad69f124c5',1,'kSleepStr(): IRtext.cpp']]], + ['ksleeptimerstr_2790',['kSleepTimerStr',['../IRtext_8cpp.html#a3402e1f6d78e3c59b71bd0dfdf020b51',1,'kSleepTimerStr(): IRtext.cpp'],['../IRtext_8h.html#a86639857f884487cf3bedc91e71d6faa',1,'kSleepTimerStr(): IRtext.cpp']]], + ['kslowstr_2791',['kSlowStr',['../IRtext_8cpp.html#a3131a17a06dff31058579b301227a04f',1,'kSlowStr(): IRtext.cpp'],['../IRtext_8h.html#a171736ab5e3d59198ed740ea5fd93473',1,'kSlowStr(): IRtext.cpp']]], + ['ksony12bits_2792',['kSony12Bits',['../IRremoteESP8266_8h.html#aa16fdf708a67dbe22c85ad4bac9b05b6',1,'IRremoteESP8266.h']]], + ['ksony15bits_2793',['kSony15Bits',['../IRremoteESP8266_8h.html#ad868d68d289d618ace266519afa059f4',1,'IRremoteESP8266.h']]], + ['ksony20bits_2794',['kSony20Bits',['../IRremoteESP8266_8h.html#aa9cd1ff8036f6c3a288c4f34af4a5eb4',1,'IRremoteESP8266.h']]], + ['ksonyaltfreq_2795',['kSonyAltFreq',['../ir__Sony_8cpp.html#a05912a15a9a6a4a78416600adc7e526b',1,'ir_Sony.cpp']]], + ['ksonyhdrmark_2796',['kSonyHdrMark',['../ir__Sony_8cpp.html#afac5a232c82e81ac257ddfc94aa4f379',1,'ir_Sony.cpp']]], + ['ksonyhdrmarkticks_2797',['kSonyHdrMarkTicks',['../ir__Sony_8cpp.html#a89abc5f0556f38d462202d1de78cbddb',1,'ir_Sony.cpp']]], + ['ksonyminbits_2798',['kSonyMinBits',['../IRremoteESP8266_8h.html#a6f0794107a7643e0bec8de6de9e7621b',1,'IRremoteESP8266.h']]], + ['ksonymingap_2799',['kSonyMinGap',['../ir__Sony_8cpp.html#abfe3a5e1fa2a38ee556326b1ea0e7e11',1,'ir_Sony.cpp']]], + ['ksonymingapticks_2800',['kSonyMinGapTicks',['../ir__Sony_8cpp.html#a150d62f71f79295153bac4694bae0aa3',1,'ir_Sony.cpp']]], + ['ksonyminrepeat_2801',['kSonyMinRepeat',['../IRremoteESP8266_8h.html#a112408429fb4a5cca22a66a351453bad',1,'IRremoteESP8266.h']]], + ['ksonyonemark_2802',['kSonyOneMark',['../ir__Sony_8cpp.html#a490e7ca2b0f81848ae42eb57d0023d13',1,'ir_Sony.cpp']]], + ['ksonyonemarkticks_2803',['kSonyOneMarkTicks',['../ir__Sony_8cpp.html#ad41c0d0496661c2e066056de6974bfe9',1,'ir_Sony.cpp']]], + ['ksonyrptlength_2804',['kSonyRptLength',['../ir__Sony_8cpp.html#a24578b92cf53caa48fa3660f16ec90ec',1,'ir_Sony.cpp']]], + ['ksonyrptlengthticks_2805',['kSonyRptLengthTicks',['../ir__Sony_8cpp.html#a0a7f67ba27e03c35d5df35a2a14a1e19',1,'ir_Sony.cpp']]], + ['ksonyspace_2806',['kSonySpace',['../ir__Sony_8cpp.html#ad09a9eb0dc0b809cea0d0a2a8ff6b9fb',1,'ir_Sony.cpp']]], + ['ksonyspaceticks_2807',['kSonySpaceTicks',['../ir__Sony_8cpp.html#a80dccfab869821cadaf02df664d91eda',1,'ir_Sony.cpp']]], + ['ksonystdfreq_2808',['kSonyStdFreq',['../ir__Sony_8cpp.html#a5e5b14c45909411d160e051f0bc7c63d',1,'ir_Sony.cpp']]], + ['ksonytick_2809',['kSonyTick',['../ir__Sony_8cpp.html#a7ced75a5e9f06f5c68132665d27e01b8',1,'ir_Sony.cpp']]], + ['ksonyzeromark_2810',['kSonyZeroMark',['../ir__Sony_8cpp.html#a7808995a9d2755681f1461d578d5480b',1,'ir_Sony.cpp']]], + ['ksonyzeromarkticks_2811',['kSonyZeroMarkTicks',['../ir__Sony_8cpp.html#a542aed17f98a11ca89456eec507a5225',1,'ir_Sony.cpp']]], + ['kspace_2812',['kSpace',['../ir__Lasertag_8cpp.html#a7c41a2a72148172c93e39d5a2fd64036',1,'kSpace(): ir_Lasertag.cpp'],['../ir__MWM_8cpp.html#a7c41a2a72148172c93e39d5a2fd64036',1,'kSpace(): ir_MWM.cpp'],['../ir__RC5__RC6_8cpp.html#a7c41a2a72148172c93e39d5a2fd64036',1,'kSpace(): ir_RC5_RC6.cpp']]], + ['kspacelbracestr_2813',['kSpaceLBraceStr',['../IRtext_8cpp.html#a156ef0014809a3509e7b254a9585e0a1',1,'kSpaceLBraceStr(): IRtext.cpp'],['../IRtext_8h.html#a42a2d6b1e764138a5e20b7a34e0cff03',1,'kSpaceLBraceStr(): IRtext.cpp']]], + ['kspacestate_2814',['kSpaceState',['../IRrecv_8h.html#acc0d1931164a8967c210eb03a2d03e2a',1,'IRrecv.h']]], + ['kstartoffset_2815',['kStartOffset',['../IRrecv_8h.html#a44a836a34428f8f75b1ae566de4bb972',1,'IRrecv.h']]], + ['kstartstr_2816',['kStartStr',['../IRtext_8cpp.html#a2075a48eed571455a88e7dfbc3a547ef',1,'kStartStr(): IRtext.cpp'],['../IRtext_8h.html#ad030c0930697d3c295f3783e8519995c',1,'kStartStr(): IRtext.cpp']]], + ['kstatesizemax_2817',['kStateSizeMax',['../IRrecv_8h.html#ab7d82cf4c0937c9b1d59d75f6f347ab2',1,'IRrecv.h']]], + ['kstepstr_2818',['kStepStr',['../IRtext_8cpp.html#ac6c64c4bdc955b6528616db3a4b303c1',1,'kStepStr(): IRtext.cpp'],['../IRtext_8h.html#ad8cc5f179089e8497a9670492429d7e3',1,'kStepStr(): IRtext.cpp']]], + ['kstopstate_2819',['kStopState',['../IRrecv_8h.html#a0e87ae8496a061e394bc9f7f3415a9b3',1,'IRrecv.h']]], + ['kstopstr_2820',['kStopStr',['../IRtext_8cpp.html#a0466188f9064d18622304cd375b18390',1,'kStopStr(): IRtext.cpp'],['../IRtext_8h.html#a7037a67c71778fe06f9dc9b4363f6f9b',1,'kStopStr(): IRtext.cpp']]], + ['ksuperstr_2821',['kSuperStr',['../IRtext_8cpp.html#a81e6c76017bc819882a043ac8fcc2854',1,'kSuperStr(): IRtext.cpp'],['../IRtext_8h.html#af83fbe756a22ef800d40bc738be886c7',1,'kSuperStr(): IRtext.cpp']]], + ['kswinghstr_2822',['kSwingHStr',['../IRtext_8cpp.html#a12d4e0afe0f6b96af817ebc95eb0b6f4',1,'kSwingHStr(): IRtext.cpp'],['../IRtext_8h.html#acfad569446290c1da0c102b98344411c',1,'kSwingHStr(): IRtext.cpp']]], + ['kswingstr_2823',['kSwingStr',['../IRtext_8cpp.html#a106174aef3a46450c0a16bef7c36a8c5',1,'kSwingStr(): IRtext.cpp'],['../IRtext_8h.html#a56d1a94eae3422758b2762da008e243c',1,'kSwingStr(): IRtext.cpp']]], + ['kswingvmodestr_2824',['kSwingVModeStr',['../IRtext_8cpp.html#ab71be957190939e2b4643f2e56e1201f',1,'kSwingVModeStr(): IRtext.cpp'],['../IRtext_8h.html#a0c801e35becc1eab4cdf0076e1c99485',1,'kSwingVModeStr(): IRtext.cpp']]], + ['kswingvstr_2825',['kSwingVStr',['../IRtext_8cpp.html#a6dc1ec788e0659e82219534b5dbb79bc',1,'kSwingVStr(): IRtext.cpp'],['../IRtext_8h.html#a8415af77afcb671c3729d604be51fd22',1,'kSwingVStr(): IRtext.cpp']]], + ['kswingvtogglestr_2826',['kSwingVToggleStr',['../IRtext_8cpp.html#a3efcf06e5ac4d6309bad1b1d0e49a933',1,'kSwingVToggleStr(): IRtext.cpp'],['../IRtext_8h.html#a27ae4d475898878bd8e71111066629c6',1,'kSwingVToggleStr(): IRtext.cpp']]], + ['ksymphonybits_2827',['kSymphonyBits',['../IRremoteESP8266_8h.html#abb5b89578ab0757999530c0383f38533',1,'IRremoteESP8266.h']]], + ['ksymphonydefaultrepeat_2828',['kSymphonyDefaultRepeat',['../IRremoteESP8266_8h.html#a219b8495f77932c200680f7a2b133880',1,'IRremoteESP8266.h']]], + ['ksymphonyfootergap_2829',['kSymphonyFooterGap',['../ir__Symphony_8cpp.html#a363cf54f4e752932d5e341975c2445f4',1,'ir_Symphony.cpp']]], + ['ksymphonyonemark_2830',['kSymphonyOneMark',['../ir__Symphony_8cpp.html#a469bfa8046ba75f9ba7cda4996dd785d',1,'ir_Symphony.cpp']]], + ['ksymphonyonespace_2831',['kSymphonyOneSpace',['../ir__Symphony_8cpp.html#ab699747bdf28d5a89920041e9c5bb01b',1,'ir_Symphony.cpp']]], + ['ksymphonyzeromark_2832',['kSymphonyZeroMark',['../ir__Symphony_8cpp.html#a58f27b1b9da16ffe73448c7ae3998fc9',1,'ir_Symphony.cpp']]], + ['ksymphonyzerospace_2833',['kSymphonyZeroSpace',['../ir__Symphony_8cpp.html#a9aaf8db419618de847573d2019155287',1,'ir_Symphony.cpp']]], + ['ktcl112acauto_2834',['kTcl112AcAuto',['../ir__Tcl_8h.html#a11a982cc182e446d53ded658cb7a08b6',1,'ir_Tcl.h']]], + ['ktcl112acbiteconooffset_2835',['kTcl112AcBitEconoOffset',['../ir__Tcl_8h.html#a97c8948de72d702b859a7abccfbc423e',1,'ir_Tcl.h']]], + ['ktcl112acbithealthoffset_2836',['kTcl112AcBitHealthOffset',['../ir__Tcl_8h.html#a2acb2c5cd2f8b729047f9eecf93f96af',1,'ir_Tcl.h']]], + ['ktcl112acbitlightoffset_2837',['kTcl112AcBitLightOffset',['../ir__Tcl_8h.html#ad87c878f7a30a05418a5babfc52c0e9e',1,'ir_Tcl.h']]], + ['ktcl112acbitmark_2838',['kTcl112AcBitMark',['../ir__Tcl_8h.html#a45360de532d2262246bf57cb7c08604d',1,'ir_Tcl.h']]], + ['ktcl112acbits_2839',['kTcl112AcBits',['../IRremoteESP8266_8h.html#a4a60d79056d70d3d56067b0bb2ec00f4',1,'IRremoteESP8266.h']]], + ['ktcl112acbitswinghoffset_2840',['kTcl112AcBitSwingHOffset',['../ir__Tcl_8h.html#ad807894f92249e44d1725f18de013369',1,'ir_Tcl.h']]], + ['ktcl112acbitturbooffset_2841',['kTcl112AcBitTurboOffset',['../ir__Tcl_8h.html#a7a6e09c1b4620e96820b3b3c54fb0e18',1,'ir_Tcl.h']]], + ['ktcl112accool_2842',['kTcl112AcCool',['../ir__Tcl_8h.html#a4a4b778086b3ebf856b750fe0c4bd2c0',1,'ir_Tcl.h']]], + ['ktcl112acdefaultrepeat_2843',['kTcl112AcDefaultRepeat',['../IRremoteESP8266_8h.html#a97c82cec6d72845d9ab8a201b0fa5034',1,'IRremoteESP8266.h']]], + ['ktcl112acdry_2844',['kTcl112AcDry',['../ir__Tcl_8h.html#a1d9ec40c278fedf87acb7420ef861101',1,'ir_Tcl.h']]], + ['ktcl112acfan_2845',['kTcl112AcFan',['../ir__Tcl_8h.html#ae07f3dd0a84be27bcb13ba60f4fd025b',1,'ir_Tcl.h']]], + ['ktcl112acfanauto_2846',['kTcl112AcFanAuto',['../ir__Tcl_8h.html#a099935d6d2bf6ebb28332005036c59c0',1,'ir_Tcl.h']]], + ['ktcl112acfanhigh_2847',['kTcl112AcFanHigh',['../ir__Tcl_8h.html#aab9672bac3e83b2e3b3d2cc5f1aa0e1f',1,'ir_Tcl.h']]], + ['ktcl112acfanlow_2848',['kTcl112AcFanLow',['../ir__Tcl_8h.html#a5114fe3f978672fc62c0cd16f6d46dd7',1,'ir_Tcl.h']]], + ['ktcl112acfanmed_2849',['kTcl112AcFanMed',['../ir__Tcl_8h.html#ad8f34f1972da347a169e2eb4ddf3d835',1,'ir_Tcl.h']]], + ['ktcl112acfansize_2850',['kTcl112AcFanSize',['../ir__Tcl_8h.html#a802bbb6258edf6dcdd05a383db28e9d3',1,'ir_Tcl.h']]], + ['ktcl112acgap_2851',['kTcl112AcGap',['../ir__Tcl_8h.html#a9ccdf5ce9ce325b9813dadbdc855a469',1,'ir_Tcl.h']]], + ['ktcl112achalfdegreeoffset_2852',['kTcl112AcHalfDegreeOffset',['../ir__Tcl_8h.html#a1ba7d7fa8df2243330eafce097209651',1,'ir_Tcl.h']]], + ['ktcl112achdrmark_2853',['kTcl112AcHdrMark',['../ir__Tcl_8h.html#a56f9f7daf3ada77f8f844afd46a80de9',1,'ir_Tcl.h']]], + ['ktcl112achdrmarktolerance_2854',['kTcl112AcHdrMarkTolerance',['../ir__Tcl_8h.html#ab9d980747b2ddd1b7fb04f00d71af1e7',1,'ir_Tcl.h']]], + ['ktcl112achdrspace_2855',['kTcl112AcHdrSpace',['../ir__Tcl_8h.html#a9135b4d7496383ad3a7da7c3ac7c92b4',1,'ir_Tcl.h']]], + ['ktcl112acheat_2856',['kTcl112AcHeat',['../ir__Tcl_8h.html#ae573f856f0bdf50406e9be84b1aa8ade',1,'ir_Tcl.h']]], + ['ktcl112acmodesize_2857',['kTcl112AcModeSize',['../ir__Tcl_8h.html#a07e49881d14cb1c84cfbf3695ae64580',1,'ir_Tcl.h']]], + ['ktcl112aconespace_2858',['kTcl112AcOneSpace',['../ir__Tcl_8h.html#af1e67019978260ba3f514cd895b54dad',1,'ir_Tcl.h']]], + ['ktcl112acpoweroffset_2859',['kTcl112AcPowerOffset',['../ir__Tcl_8h.html#ad36204b310ec8a069f631322d806aa7f',1,'ir_Tcl.h']]], + ['ktcl112acstatelength_2860',['kTcl112AcStateLength',['../IRremoteESP8266_8h.html#a23ba2f5af02242e14ae7eefcd066152e',1,'IRremoteESP8266.h']]], + ['ktcl112acswingvoff_2861',['kTcl112AcSwingVOff',['../ir__Tcl_8h.html#aa78e1b544f392c251093d458e5d21e12',1,'ir_Tcl.h']]], + ['ktcl112acswingvoffset_2862',['kTcl112AcSwingVOffset',['../ir__Tcl_8h.html#ab0412b0d865eaf788a5672300575b1d8',1,'ir_Tcl.h']]], + ['ktcl112acswingvon_2863',['kTcl112AcSwingVOn',['../ir__Tcl_8h.html#a5406fbabd66478d601aebc6939a3788f',1,'ir_Tcl.h']]], + ['ktcl112acswingvsize_2864',['kTcl112AcSwingVSize',['../ir__Tcl_8h.html#a7bacb40b18b280da13b2d1b781c825e5',1,'ir_Tcl.h']]], + ['ktcl112actempmax_2865',['kTcl112AcTempMax',['../ir__Tcl_8h.html#a60efbe31031e1e9c3a17c7d80cac54cb',1,'ir_Tcl.h']]], + ['ktcl112actempmin_2866',['kTcl112AcTempMin',['../ir__Tcl_8h.html#a30fe65ec015bc4d91cd35ead9cc43dcc',1,'ir_Tcl.h']]], + ['ktcl112actolerance_2867',['kTcl112AcTolerance',['../ir__Tcl_8h.html#a13bbe794b2b59763f7f93f15a3f26820',1,'ir_Tcl.h']]], + ['ktcl112aczerospace_2868',['kTcl112AcZeroSpace',['../ir__Tcl_8h.html#abc05edaeb1a4fa7e6ccf9bda1f66b483',1,'ir_Tcl.h']]], + ['ktecoauto_2869',['kTecoAuto',['../ir__Teco_8h.html#a79178aa25d9f60c0a838285369e1b910',1,'ir_Teco.h']]], + ['ktecobitmark_2870',['kTecoBitMark',['../ir__Teco_8cpp.html#a0aa2e352f4a61027b17467e92863883b',1,'ir_Teco.cpp']]], + ['ktecobits_2871',['kTecoBits',['../IRremoteESP8266_8h.html#aee01958e9d97a70a6881cf560ca0ca9d',1,'IRremoteESP8266.h']]], + ['ktecocool_2872',['kTecoCool',['../ir__Teco_8h.html#a554686c72b6bc487d03c9461f9633a6b',1,'ir_Teco.h']]], + ['ktecodefaultrepeat_2873',['kTecoDefaultRepeat',['../IRremoteESP8266_8h.html#a095362359f34c1ee5ab71d56e6d64f64',1,'IRremoteESP8266.h']]], + ['ktecodry_2874',['kTecoDry',['../ir__Teco_8h.html#af7efcf371967eb97fd31d54016a82006',1,'ir_Teco.h']]], + ['ktecofan_2875',['kTecoFan',['../ir__Teco_8h.html#a7385fe198242c9203e3a5d5ffb7beb4d',1,'ir_Teco.h']]], + ['ktecofanauto_2876',['kTecoFanAuto',['../ir__Teco_8h.html#a43e58c0158efac1c4e5497c619b5674c',1,'ir_Teco.h']]], + ['ktecofanhigh_2877',['kTecoFanHigh',['../ir__Teco_8h.html#a0a73f5f892e7f9812793fbf5dab458dd',1,'ir_Teco.h']]], + ['ktecofanlow_2878',['kTecoFanLow',['../ir__Teco_8h.html#abac7443a86fb304376dd94a9c10e6940',1,'ir_Teco.h']]], + ['ktecofanmed_2879',['kTecoFanMed',['../ir__Teco_8h.html#a35f313943f9e2f5b69d5237fdaa64914',1,'ir_Teco.h']]], + ['ktecofanoffset_2880',['kTecoFanOffset',['../ir__Teco_8h.html#ae70841ad987ac89abaaf99b11655eaae',1,'ir_Teco.h']]], + ['ktecofansize_2881',['kTecoFanSize',['../ir__Teco_8h.html#a45734d2be952e3faa796d86245eaf241',1,'ir_Teco.h']]], + ['ktecogap_2882',['kTecoGap',['../ir__Teco_8cpp.html#a6a153d84287fba3bd11e3e5054fd7e30',1,'ir_Teco.cpp']]], + ['ktecohdrmark_2883',['kTecoHdrMark',['../ir__Teco_8cpp.html#ada983ce2d6f03949cddfe06191ab05d9',1,'ir_Teco.cpp']]], + ['ktecohdrspace_2884',['kTecoHdrSpace',['../ir__Teco_8cpp.html#acf417d42fd39dbaf06282162ab5b17e2',1,'ir_Teco.cpp']]], + ['ktecoheat_2885',['kTecoHeat',['../ir__Teco_8h.html#ab6f9dbeb2838b124be12d08fd9b209bb',1,'ir_Teco.h']]], + ['ktecohumidoffset_2886',['kTecoHumidOffset',['../ir__Teco_8h.html#ad95126f6815d24b5d1b38e44677f3d7e',1,'ir_Teco.h']]], + ['ktecolightoffset_2887',['kTecoLightOffset',['../ir__Teco_8h.html#a5dc2cb366974b2baa9f7cbfb26d90415',1,'ir_Teco.h']]], + ['ktecomaxtemp_2888',['kTecoMaxTemp',['../ir__Teco_8h.html#a1c24aa0cc4d475a5eb97d5208f4dcf06',1,'ir_Teco.h']]], + ['ktecomintemp_2889',['kTecoMinTemp',['../ir__Teco_8h.html#a54da99bfcbea5e076c3ca2934e769ab1',1,'ir_Teco.h']]], + ['ktecomodeoffset_2890',['kTecoModeOffset',['../ir__Teco_8h.html#a1aca7a8a2822cd1494dabeda5b11b9be',1,'ir_Teco.h']]], + ['ktecoonespace_2891',['kTecoOneSpace',['../ir__Teco_8cpp.html#a62eccbf6773ea8fbc18432627c62d0d5',1,'ir_Teco.cpp']]], + ['ktecopoweroffset_2892',['kTecoPowerOffset',['../ir__Teco_8h.html#a4eec88582ed29e424549497deb9eceef',1,'ir_Teco.h']]], + ['ktecoreset_2893',['kTecoReset',['../ir__Teco_8h.html#acf559a2cd772835ce46c3f673cd95806',1,'ir_Teco.h']]], + ['ktecosaveoffset_2894',['kTecoSaveOffset',['../ir__Teco_8h.html#a63d5efa7cfc84ee22d3575cc713d1f62',1,'ir_Teco.h']]], + ['ktecosleepoffset_2895',['kTecoSleepOffset',['../ir__Teco_8h.html#ae7da65034a8a84e79ebb1497e56e38fe',1,'ir_Teco.h']]], + ['ktecoswingoffset_2896',['kTecoSwingOffset',['../ir__Teco_8h.html#aaa821eb3ad9a5edadba2b83b6d2094b6',1,'ir_Teco.h']]], + ['ktecotempoffset_2897',['kTecoTempOffset',['../ir__Teco_8h.html#ae887d9c5702d63e4b4fa5250ed5bf0d9',1,'ir_Teco.h']]], + ['ktecotempsize_2898',['kTecoTempSize',['../ir__Teco_8h.html#a635db8dbba35e4326958fca6dfe67603',1,'ir_Teco.h']]], + ['ktecotimerhalfhouroffset_2899',['kTecoTimerHalfHourOffset',['../ir__Teco_8h.html#a2692a59900c10b6da6662fac5a312e04',1,'ir_Teco.h']]], + ['ktecotimeronoffset_2900',['kTecoTimerOnOffset',['../ir__Teco_8h.html#a7bcf79fa5e5280ad35c9a9512b2fdc7f',1,'ir_Teco.h']]], + ['ktecotimertenshoursoffset_2901',['kTecoTimerTensHoursOffset',['../ir__Teco_8h.html#adaa73601e31fa7217d371645d835f0ca',1,'ir_Teco.h']]], + ['ktecotimertenshourssize_2902',['kTecoTimerTensHoursSize',['../ir__Teco_8h.html#a57bf1b777b9b56aad4f224b6bba1218c',1,'ir_Teco.h']]], + ['ktecotimerunithoursoffset_2903',['kTecoTimerUnitHoursOffset',['../ir__Teco_8h.html#ac47fc38319e7e1d90d42c789b806cdbd',1,'ir_Teco.h']]], + ['ktecotimerunithourssize_2904',['kTecoTimerUnitHoursSize',['../ir__Teco_8h.html#a54ac664e32ce0d8b4d8d4d4d459dbc46',1,'ir_Teco.h']]], + ['ktecozerospace_2905',['kTecoZeroSpace',['../ir__Teco_8cpp.html#a8dc1f6ea44519a0930b48f69a83a7363',1,'ir_Teco.cpp']]], + ['ktempdownstr_2906',['kTempDownStr',['../IRtext_8cpp.html#a3fa3262c5631c9357a5723c70dc3be12',1,'kTempDownStr(): IRtext.cpp'],['../IRtext_8h.html#a3d367a899d7e8ed20844bb3c48bf6395',1,'kTempDownStr(): IRtext.cpp']]], + ['ktempstr_2907',['kTempStr',['../IRtext_8cpp.html#a487bd9a4225536aba2595be0b5cb8039',1,'kTempStr(): IRtext.cpp'],['../IRtext_8h.html#a87652df1cf724353547f27a9ebde5edb',1,'kTempStr(): IRtext.cpp']]], + ['ktempupstr_2908',['kTempUpStr',['../IRtext_8cpp.html#a7c4f18322b600aaaf5a8716654d05dc3',1,'kTempUpStr(): IRtext.cpp'],['../IRtext_8h.html#a71687df5bc94e4ca18cf59c9ff238e86',1,'kTempUpStr(): IRtext.cpp']]], + ['kthreeletterdayofweekstr_2909',['kThreeLetterDayOfWeekStr',['../IRtext_8cpp.html#ae16da0464743313a1fbeae92dcfcebbd',1,'kThreeLetterDayOfWeekStr(): IRtext.cpp'],['../IRtext_8h.html#a837ecfeff9a1bc7546016229e9f2ddfb',1,'kThreeLetterDayOfWeekStr(): IRtext.cpp']]], + ['ktimeoutms_2910',['kTimeoutMs',['../IRrecv_8h.html#ad37e9659aaef29c541802d9759e0ab7b',1,'IRrecv.h']]], + ['ktimerstr_2911',['kTimerStr',['../IRtext_8cpp.html#a2b5219ba887cfbc578fb880ebada832a',1,'kTimerStr(): IRtext.cpp'],['../IRtext_8h.html#a36fa3584a89f6e48757eba8f3df7e109',1,'kTimerStr(): IRtext.cpp']]], + ['ktimesep_2912',['kTimeSep',['../IRtext_8cpp.html#a277b588db53ec31ab7b0d287310c6d50',1,'kTimeSep(): IRtext.cpp'],['../IRtext_8h.html#a277b588db53ec31ab7b0d287310c6d50',1,'kTimeSep(): IRtext.cpp']]], + ['ktogglestr_2913',['kToggleStr',['../IRtext_8cpp.html#a33860b90859d19191c9759b099283b37',1,'kToggleStr(): IRtext.cpp'],['../IRtext_8h.html#a05b1e2f809dadf05e22e1cb1d1a7f07e',1,'kToggleStr(): IRtext.cpp']]], + ['ktolerance_2914',['kTolerance',['../IRrecv_8h.html#a7884008b3a738dfc7bd8658655e10272',1,'IRrecv.h']]], + ['ktopstr_2915',['kTopStr',['../IRtext_8cpp.html#a65a8bf89c9dd0277607478277c0c7088',1,'kTopStr(): IRtext.cpp'],['../IRtext_8h.html#a6bb6abfc54409b801dcb591f036635d2',1,'kTopStr(): IRtext.cpp']]], + ['ktoshibaacauto_2916',['kToshibaAcAuto',['../ir__Toshiba_8h.html#a4730189595a884ae6535805948e096aa',1,'ir_Toshiba.h']]], + ['ktoshibaacbitmark_2917',['kToshibaAcBitMark',['../ir__Toshiba_8cpp.html#adff1c244103ff274243b8e20ca209866',1,'ir_Toshiba.cpp']]], + ['ktoshibaacbits_2918',['kToshibaACBits',['../IRremoteESP8266_8h.html#a172dde7867fa9a68902c3ad7ea9629b0',1,'IRremoteESP8266.h']]], + ['ktoshibaaccool_2919',['kToshibaAcCool',['../ir__Toshiba_8h.html#a2f30e65bb092365d1a8bcb1f3395333a',1,'ir_Toshiba.h']]], + ['ktoshibaacdry_2920',['kToshibaAcDry',['../ir__Toshiba_8h.html#a10b77d1038efc59775398789c33af91e',1,'ir_Toshiba.h']]], + ['ktoshibaacfanauto_2921',['kToshibaAcFanAuto',['../ir__Toshiba_8h.html#a69f52e19a5b0e68abda00b680fbef7f6',1,'ir_Toshiba.h']]], + ['ktoshibaacfanmax_2922',['kToshibaAcFanMax',['../ir__Toshiba_8h.html#a0f6ffde3491f464166d6064d7dfe5ba4',1,'ir_Toshiba.h']]], + ['ktoshibaacfanmed_2923',['kToshibaAcFanMed',['../ir__Toshiba_8h.html#a3ff967af7d1a30c7c5cb958eaa5cbd58',1,'ir_Toshiba.h']]], + ['ktoshibaacfanmin_2924',['kToshibaAcFanMin',['../ir__Toshiba_8h.html#ab2c5eea9ccabf2e0e56bc03baec5d898',1,'ir_Toshiba.h']]], + ['ktoshibaacfanoffset_2925',['kToshibaAcFanOffset',['../ir__Toshiba_8h.html#a8276d25876329968bbf36eac3598972c',1,'ir_Toshiba.h']]], + ['ktoshibaacfansize_2926',['kToshibaAcFanSize',['../ir__Toshiba_8h.html#a5a91c19e799721560a5a9ef77a245888',1,'ir_Toshiba.h']]], + ['ktoshibaachdrmark_2927',['kToshibaAcHdrMark',['../ir__Toshiba_8cpp.html#a2eac25ff2a381ad6690623641153a780',1,'ir_Toshiba.cpp']]], + ['ktoshibaachdrspace_2928',['kToshibaAcHdrSpace',['../ir__Toshiba_8cpp.html#a0ae9047d5a204f320c06736fa40d0a7d',1,'ir_Toshiba.cpp']]], + ['ktoshibaacheat_2929',['kToshibaAcHeat',['../ir__Toshiba_8h.html#aa9ec24f9a5e460aa7017f642ce7a4c0d',1,'ir_Toshiba.h']]], + ['ktoshibaacmaxtemp_2930',['kToshibaAcMaxTemp',['../ir__Toshiba_8h.html#a475028a2a519e3310506ceac0a5dc4e6',1,'ir_Toshiba.h']]], + ['ktoshibaacmingap_2931',['kToshibaAcMinGap',['../ir__Toshiba_8cpp.html#ade7642284aa7c6a638b9fab45610cc59',1,'ir_Toshiba.cpp']]], + ['ktoshibaacminrepeat_2932',['kToshibaACMinRepeat',['../IRremoteESP8266_8h.html#a8fca6a7c3cd608ff49cab35f24af0546',1,'IRremoteESP8266.h']]], + ['ktoshibaacmintemp_2933',['kToshibaAcMinTemp',['../ir__Toshiba_8h.html#ad0e8e76aabc38ac7ba2f13a009de98e0',1,'ir_Toshiba.h']]], + ['ktoshibaacmodeoffset_2934',['kToshibaAcModeOffset',['../ir__Toshiba_8h.html#a4e097e34b0f2dd9eaacf94d043f726d0',1,'ir_Toshiba.h']]], + ['ktoshibaacmodesize_2935',['kToshibaAcModeSize',['../ir__Toshiba_8h.html#a920d55af8e499a7c2293a7d8180104da',1,'ir_Toshiba.h']]], + ['ktoshibaaconespace_2936',['kToshibaAcOneSpace',['../ir__Toshiba_8cpp.html#a787330c9e5f9d30e8df157acc15f56dd',1,'ir_Toshiba.cpp']]], + ['ktoshibaacpoweroffset_2937',['kToshibaAcPowerOffset',['../ir__Toshiba_8h.html#adfd3caac2bd0b636508afbbf67b04dcd',1,'ir_Toshiba.h']]], + ['ktoshibaacstatelength_2938',['kToshibaACStateLength',['../IRremoteESP8266_8h.html#ad3be6a1b9241c20bb1464a2cb80b97d2',1,'IRremoteESP8266.h']]], + ['ktoshibaactempoffset_2939',['kToshibaAcTempOffset',['../ir__Toshiba_8h.html#a68be75c21288e249d7b44fe9648de91f',1,'ir_Toshiba.h']]], + ['ktoshibaactempsize_2940',['kToshibaAcTempSize',['../ir__Toshiba_8h.html#a89ec8108586e0d5b9f58a160f4db37c8',1,'ir_Toshiba.h']]], + ['ktoshibaaczerospace_2941',['kToshibaAcZeroSpace',['../ir__Toshiba_8cpp.html#ab2fc2833cfb31d872894073687eebd99',1,'ir_Toshiba.cpp']]], + ['ktrotecauto_2942',['kTrotecAuto',['../ir__Trotec_8h.html#a53b2687b96f8e69ec6f57dd2ac7a6dfa',1,'ir_Trotec.h']]], + ['ktrotecbitmark_2943',['kTrotecBitMark',['../ir__Trotec_8cpp.html#a870b2da19855eff625a2834ca7fd8765',1,'ir_Trotec.cpp']]], + ['ktrotecbits_2944',['kTrotecBits',['../IRremoteESP8266_8h.html#ab819cb0a34937714dcb10059799c26e2',1,'IRremoteESP8266.h']]], + ['ktroteccool_2945',['kTrotecCool',['../ir__Trotec_8h.html#add33a35046e4270ad9ff3b998526d5d1',1,'ir_Trotec.h']]], + ['ktrotecdefaultrepeat_2946',['kTrotecDefaultRepeat',['../IRremoteESP8266_8h.html#a4c0411462f2854a8606deca09ed15df5',1,'IRremoteESP8266.h']]], + ['ktrotecdeftemp_2947',['kTrotecDefTemp',['../ir__Trotec_8h.html#ac28d1d0ea6db18716a7d9d21e84178c0',1,'ir_Trotec.h']]], + ['ktrotecdry_2948',['kTrotecDry',['../ir__Trotec_8h.html#abdaa1836c6bc90b1d5813df028a76e21',1,'ir_Trotec.h']]], + ['ktrotecfan_2949',['kTrotecFan',['../ir__Trotec_8h.html#a9309d528d50dd542a5184a51fb101a6a',1,'ir_Trotec.h']]], + ['ktrotecfanhigh_2950',['kTrotecFanHigh',['../ir__Trotec_8h.html#ae780f0bb6b9b83f3dbcc1c1e282e5436',1,'ir_Trotec.h']]], + ['ktrotecfanlow_2951',['kTrotecFanLow',['../ir__Trotec_8h.html#aa1c3695c1becc935d2a3b2691996a17b',1,'ir_Trotec.h']]], + ['ktrotecfanmed_2952',['kTrotecFanMed',['../ir__Trotec_8h.html#abae1944f529099ff4736b6cb13bcbeda',1,'ir_Trotec.h']]], + ['ktrotecfanoffset_2953',['kTrotecFanOffset',['../ir__Trotec_8h.html#a3b9034b96268707f7b6fc45a16499479',1,'ir_Trotec.h']]], + ['ktrotecfansize_2954',['kTrotecFanSize',['../ir__Trotec_8h.html#a89d7de622d0f53f800c1a5a2887a81e4',1,'ir_Trotec.h']]], + ['ktrotecgap_2955',['kTrotecGap',['../ir__Trotec_8cpp.html#a753ba93d7b757dc58fcf1b4a6bb65ff6',1,'ir_Trotec.cpp']]], + ['ktrotecgapend_2956',['kTrotecGapEnd',['../ir__Trotec_8cpp.html#a5fcc4a020bcebfe90abe12d4a47de372',1,'ir_Trotec.cpp']]], + ['ktrotechdrmark_2957',['kTrotecHdrMark',['../ir__Trotec_8cpp.html#a809faed7ee2fef78a5b8271a2c5ddd10',1,'ir_Trotec.cpp']]], + ['ktrotechdrspace_2958',['kTrotecHdrSpace',['../ir__Trotec_8cpp.html#a5d42cd98bf737dd8161572afa393be1e',1,'ir_Trotec.cpp']]], + ['ktrotecintro1_2959',['kTrotecIntro1',['../ir__Trotec_8h.html#aabc5c6a9b4867c25d84ffe2839e88564',1,'ir_Trotec.h']]], + ['ktrotecintro2_2960',['kTrotecIntro2',['../ir__Trotec_8h.html#ac33de8b2fc4b70bb272a56f6bbb68e34',1,'ir_Trotec.h']]], + ['ktrotecmaxtemp_2961',['kTrotecMaxTemp',['../ir__Trotec_8h.html#abfe4004dcac892f575ec1efb09567595',1,'ir_Trotec.h']]], + ['ktrotecmaxtimer_2962',['kTrotecMaxTimer',['../ir__Trotec_8h.html#a8467d1b9983d5750a61817cacb148efd',1,'ir_Trotec.h']]], + ['ktrotecmintemp_2963',['kTrotecMinTemp',['../ir__Trotec_8h.html#a091904af9fee2384e137feab274af7f8',1,'ir_Trotec.h']]], + ['ktrotecmodeoffset_2964',['kTrotecModeOffset',['../ir__Trotec_8h.html#aa0d48802845d5cf0410550bb98e4cbb5',1,'ir_Trotec.h']]], + ['ktrotecmodesize_2965',['kTrotecModeSize',['../ir__Trotec_8h.html#ae45ea2f0f8b5d09568c0322e1735ca85',1,'ir_Trotec.h']]], + ['ktroteconespace_2966',['kTrotecOneSpace',['../ir__Trotec_8cpp.html#a570aa73a82089906971932212d99a283',1,'ir_Trotec.cpp']]], + ['ktrotecpowerbitoffset_2967',['kTrotecPowerBitOffset',['../ir__Trotec_8h.html#a11fcdfe886385de6363d06371cdcff43',1,'ir_Trotec.h']]], + ['ktrotecsleepbitoffset_2968',['kTrotecSleepBitOffset',['../ir__Trotec_8h.html#af81754a025119a3dc9924df5508b18c0',1,'ir_Trotec.h']]], + ['ktrotecstatelength_2969',['kTrotecStateLength',['../IRremoteESP8266_8h.html#ae1d2aa52fef81f03b92c35f4970728d2',1,'IRremoteESP8266.h']]], + ['ktrotectempoffset_2970',['kTrotecTempOffset',['../ir__Trotec_8h.html#a08a844aefec8d0440365c9204a01034c',1,'ir_Trotec.h']]], + ['ktrotectempsize_2971',['kTrotecTempSize',['../ir__Trotec_8h.html#a1141680a808f41513548a8747c37f975',1,'ir_Trotec.h']]], + ['ktrotectimerbitoffset_2972',['kTrotecTimerBitOffset',['../ir__Trotec_8h.html#aad59f1284ec04736a3c6629c3cd87731',1,'ir_Trotec.h']]], + ['ktroteczerospace_2973',['kTrotecZeroSpace',['../ir__Trotec_8cpp.html#a8e8f85e7b8a8157eb425316b5108d717',1,'ir_Trotec.cpp']]], + ['ktruestr_2974',['kTrueStr',['../IRtext_8cpp.html#a28a627d6f48d7d06a560f9613e4550fa',1,'kTrueStr(): IRtext.cpp'],['../IRtext_8h.html#aca6e78a25b9dacd2508069f0a6b919c0',1,'kTrueStr(): IRtext.cpp']]], + ['kturbostr_2975',['kTurboStr',['../IRtext_8cpp.html#a9f3f7395d980887699ac5a0c146d37d2',1,'kTurboStr(): IRtext.cpp'],['../IRtext_8h.html#a3ced6d2a545174133308d7803157f7f8',1,'kTurboStr(): IRtext.cpp']]], + ['kunknownstr_2976',['kUnknownStr',['../IRtext_8cpp.html#a9c6c6d47ce3eb07cc607faa600978029',1,'kUnknownStr(): IRtext.cpp'],['../IRtext_8h.html#aa59176b31741b60729d4279817a7da1b',1,'kUnknownStr(): IRtext.cpp']]], + ['kunknownthreshold_2977',['kUnknownThreshold',['../IRrecv_8h.html#aa6b5a940c7a0432aa82a8d823202cd7f',1,'IRrecv.h']]], + ['kupperstr_2978',['kUpperStr',['../IRtext_8cpp.html#a887bb7c61f38014d21b025c67102fa0b',1,'kUpperStr(): IRtext.cpp'],['../IRtext_8h.html#a5aea60591627481d90688f655b2eb82a',1,'kUpperStr(): IRtext.cpp']]], + ['kupstr_2979',['kUpStr',['../IRtext_8cpp.html#ab970b3d5239f08f21a8e5e2eae49739f',1,'kUpStr(): IRtext.cpp'],['../IRtext_8h.html#a8672abbd2a279c032f0435ed75143b1a',1,'kUpStr(): IRtext.cpp']]], + ['kusedeftol_2980',['kUseDefTol',['../IRrecv_8h.html#a05025e8bd724ae2d0c7fea6e924ca84c',1,'IRrecv.h']]], + ['kvestelacauto_2981',['kVestelAcAuto',['../ir__Vestel_8h.html#a157e879cbe3b216075e3b7b2db5fdc3c',1,'ir_Vestel.h']]], + ['kvestelacbitmark_2982',['kVestelAcBitMark',['../ir__Vestel_8h.html#a70d7198002c61529956625986aa533f0',1,'ir_Vestel.h']]], + ['kvestelacbits_2983',['kVestelAcBits',['../IRremoteESP8266_8h.html#ae31945a1ce90b2d4c33b5c91d980d3a7',1,'IRremoteESP8266.h']]], + ['kvestelacchecksumoffset_2984',['kVestelAcChecksumOffset',['../ir__Vestel_8h.html#ac3fa10d1dba540a82b77cc88b01f9a7e',1,'ir_Vestel.h']]], + ['kvestelacchecksumsize_2985',['kVestelAcChecksumSize',['../ir__Vestel_8h.html#a61979a3b944ce7309c5b3f5b24b0a14c',1,'ir_Vestel.h']]], + ['kvestelaccool_2986',['kVestelAcCool',['../ir__Vestel_8h.html#aa2ec681dd63a976a6b2b182ae590e020',1,'ir_Vestel.h']]], + ['kvestelacdry_2987',['kVestelAcDry',['../ir__Vestel_8h.html#a21a255842a75a932a3a0735851d9c197',1,'ir_Vestel.h']]], + ['kvestelacfan_2988',['kVestelAcFan',['../ir__Vestel_8h.html#aeabf5404a3f66fd1428b6e4c09f24c08',1,'ir_Vestel.h']]], + ['kvestelacfanauto_2989',['kVestelAcFanAuto',['../ir__Vestel_8h.html#ac2f3175c25844414de2c2489595dd851',1,'ir_Vestel.h']]], + ['kvestelacfanautocool_2990',['kVestelAcFanAutoCool',['../ir__Vestel_8h.html#ab40dc2ebe05c77e701e2d5acf16b2658',1,'ir_Vestel.h']]], + ['kvestelacfanautohot_2991',['kVestelAcFanAutoHot',['../ir__Vestel_8h.html#a95dee8baacedb7aa62edbdecf766cdc1',1,'ir_Vestel.h']]], + ['kvestelacfanhigh_2992',['kVestelAcFanHigh',['../ir__Vestel_8h.html#acae63d91ee2a2b448fe1a68b2472e4a3',1,'ir_Vestel.h']]], + ['kvestelacfanlow_2993',['kVestelAcFanLow',['../ir__Vestel_8h.html#a21ce5e539ecb764be8dbad33914f4b87',1,'ir_Vestel.h']]], + ['kvestelacfanmed_2994',['kVestelAcFanMed',['../ir__Vestel_8h.html#a265fa70e0e38caefb45ed007eb25a430',1,'ir_Vestel.h']]], + ['kvestelacfanoffset_2995',['kVestelAcFanOffset',['../ir__Vestel_8h.html#af0f1c1989322f256b7b1b5dba613feba',1,'ir_Vestel.h']]], + ['kvestelacfansize_2996',['kVestelAcFanSize',['../ir__Vestel_8h.html#ae61e23edfb71206e736497ab479c08ad',1,'ir_Vestel.h']]], + ['kvestelachdrmark_2997',['kVestelAcHdrMark',['../ir__Vestel_8h.html#a32871ab992bfee13918a50f04508a95a',1,'ir_Vestel.h']]], + ['kvestelachdrspace_2998',['kVestelAcHdrSpace',['../ir__Vestel_8h.html#a2389409048e409b411ea8416829c06ef',1,'ir_Vestel.h']]], + ['kvestelacheat_2999',['kVestelAcHeat',['../ir__Vestel_8h.html#a33d36614992862c41f5e48548b0a45f1',1,'ir_Vestel.h']]], + ['kvestelachouroffset_3000',['kVestelAcHourOffset',['../ir__Vestel_8h.html#af4c3729a4b9df092e01d74109f539cca',1,'ir_Vestel.h']]], + ['kvestelachoursize_3001',['kVestelAcHourSize',['../ir__Vestel_8h.html#a2c0fd442d92620ca062637d01258bacf',1,'ir_Vestel.h']]], + ['kvestelacion_3002',['kVestelAcIon',['../ir__Vestel_8h.html#a6a661c914fd67e261e2148d797789339',1,'ir_Vestel.h']]], + ['kvestelacionoffset_3003',['kVestelAcIonOffset',['../ir__Vestel_8h.html#a9b1cd19c4b0037714f1c47ba031edd0b',1,'ir_Vestel.h']]], + ['kvestelacmaxtemp_3004',['kVestelAcMaxTemp',['../ir__Vestel_8h.html#a4e49902b2e4fe049fd5969b4532cc7b4',1,'ir_Vestel.h']]], + ['kvestelacmintempc_3005',['kVestelAcMinTempC',['../ir__Vestel_8h.html#ae597f05d0886a5a2aa8c43db187a657b',1,'ir_Vestel.h']]], + ['kvestelacmintemph_3006',['kVestelAcMinTempH',['../ir__Vestel_8h.html#a06977d297c84adac7927c80c7b0e7297',1,'ir_Vestel.h']]], + ['kvestelacminuteoffset_3007',['kVestelAcMinuteOffset',['../ir__Vestel_8h.html#a7c5f318a30e86394af19265e73b68034',1,'ir_Vestel.h']]], + ['kvestelacminutesize_3008',['kVestelAcMinuteSize',['../ir__Vestel_8h.html#a8abd51cd0d0404ae8bb139690bf55eb0',1,'ir_Vestel.h']]], + ['kvestelacmodeoffset_3009',['kVestelAcModeOffset',['../ir__Vestel_8h.html#a5334689cb0fbeaee67133f1f86bdce58',1,'ir_Vestel.h']]], + ['kvestelacnormal_3010',['kVestelAcNormal',['../ir__Vestel_8h.html#afa4c0fafcc806cd22dfb45475631d754',1,'ir_Vestel.h']]], + ['kvestelacofftimeoffset_3011',['kVestelAcOffTimeOffset',['../ir__Vestel_8h.html#a64ce11367a28d6481801ac3ac641df4b',1,'ir_Vestel.h']]], + ['kvestelacofftimerflagoffset_3012',['kVestelAcOffTimerFlagOffset',['../ir__Vestel_8h.html#ab36bed197f2c2b65599667b4cdf8225b',1,'ir_Vestel.h']]], + ['kvestelaconespace_3013',['kVestelAcOneSpace',['../ir__Vestel_8h.html#a507a849ef5e031f40ecc0e5db6ac8dd6',1,'ir_Vestel.h']]], + ['kvestelacontimeoffset_3014',['kVestelAcOnTimeOffset',['../ir__Vestel_8h.html#a51e257abca02cb1c97de4a5418fb7e61',1,'ir_Vestel.h']]], + ['kvestelacontimerflagoffset_3015',['kVestelAcOnTimerFlagOffset',['../ir__Vestel_8h.html#a8aa66163683538129fbdaf21746a9144',1,'ir_Vestel.h']]], + ['kvestelacpoweroffset_3016',['kVestelAcPowerOffset',['../ir__Vestel_8h.html#ab1c5709fa37fc711929688bd72c300be',1,'ir_Vestel.h']]], + ['kvestelacpowersize_3017',['kVestelAcPowerSize',['../ir__Vestel_8h.html#a884236b7213902c5e7d79327effc8f97',1,'ir_Vestel.h']]], + ['kvestelacsleep_3018',['kVestelAcSleep',['../ir__Vestel_8h.html#abc4701f0a44ed48a139d192f86a7169b',1,'ir_Vestel.h']]], + ['kvestelacstatedefault_3019',['kVestelAcStateDefault',['../ir__Vestel_8h.html#a4207797ae1043280ec6364de5981a791',1,'ir_Vestel.h']]], + ['kvestelacswing_3020',['kVestelAcSwing',['../ir__Vestel_8h.html#aeb764aa28cb134348e64fde5cb4d40f0',1,'ir_Vestel.h']]], + ['kvestelacswingoffset_3021',['kVestelAcSwingOffset',['../ir__Vestel_8h.html#ad3249b7c42070013c7c81d3feb0b1a43',1,'ir_Vestel.h']]], + ['kvestelactempoffset_3022',['kVestelAcTempOffset',['../ir__Vestel_8h.html#a9cf24276d722ee54a17c8beaf2b415cd',1,'ir_Vestel.h']]], + ['kvestelactimerflagoffset_3023',['kVestelAcTimerFlagOffset',['../ir__Vestel_8h.html#a0e53cb471d133b13cfa8fd3204d70776',1,'ir_Vestel.h']]], + ['kvestelactimerhoursize_3024',['kVestelAcTimerHourSize',['../ir__Vestel_8h.html#ad52ad7c6b1efb7eee74a276dbca330e3',1,'ir_Vestel.h']]], + ['kvestelactimerminssize_3025',['kVestelAcTimerMinsSize',['../ir__Vestel_8h.html#a7696fac000df0fd5136b7cbd96393b9e',1,'ir_Vestel.h']]], + ['kvestelactimersize_3026',['kVestelAcTimerSize',['../ir__Vestel_8h.html#a43f134a4db94790c671380be29fb8e2c',1,'ir_Vestel.h']]], + ['kvestelactimestatedefault_3027',['kVestelAcTimeStateDefault',['../ir__Vestel_8h.html#aaf4d9b6a41269ede2101d45cc1549794',1,'ir_Vestel.h']]], + ['kvestelactolerance_3028',['kVestelAcTolerance',['../ir__Vestel_8h.html#a4abe236ac8a801aa03ab843c3e418711',1,'ir_Vestel.h']]], + ['kvestelacturbo_3029',['kVestelAcTurbo',['../ir__Vestel_8h.html#a85b8b744f201b1666f9608f693a61059',1,'ir_Vestel.h']]], + ['kvestelacturbosleepoffset_3030',['kVestelAcTurboSleepOffset',['../ir__Vestel_8h.html#a97c21dc060558aa4f543f2d05385f674',1,'ir_Vestel.h']]], + ['kvestelaczerospace_3031',['kVestelAcZeroSpace',['../ir__Vestel_8h.html#a2094b0ff279fb1696b51e57d657efd13',1,'ir_Vestel.h']]], + ['kwallstr_3032',['kWallStr',['../IRtext_8cpp.html#a860a71561b888c82318daad9f2c34592',1,'kWallStr(): IRtext.cpp'],['../IRtext_8h.html#add1af6d900b500ca7affff3c9ff02d29',1,'kWallStr(): IRtext.cpp']]], + ['kweeklytimerstr_3033',['kWeeklyTimerStr',['../IRtext_8cpp.html#aaf0b7bf26b4710a4c032cec9e55c545a',1,'kWeeklyTimerStr(): IRtext.cpp'],['../IRtext_8h.html#ab59fa6f63401196c0ff32aba6da9d9aa',1,'kWeeklyTimerStr(): IRtext.cpp']]], + ['kwhirlpoolacalttempoffset_3034',['kWhirlpoolAcAltTempOffset',['../ir__Whirlpool_8h.html#a5cdc8be18d6489572d7c16dbbcc0c838',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacalttemppos_3035',['kWhirlpoolAcAltTempPos',['../ir__Whirlpool_8h.html#a019206ce06ef164cc3abb586183d0789',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacauto_3036',['kWhirlpoolAcAuto',['../ir__Whirlpool_8h.html#a2f3cc5447f8042e9c2eae0c2e0dc1b80',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacautotemp_3037',['kWhirlpoolAcAutoTemp',['../ir__Whirlpool_8h.html#a314b66dc86a7f622d73d3973d9dca86d',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacbitmark_3038',['kWhirlpoolAcBitMark',['../ir__Whirlpool_8cpp.html#a5c076ca2e18927f8b0594cb74a7de1ff',1,'ir_Whirlpool.cpp']]], + ['kwhirlpoolacbits_3039',['kWhirlpoolAcBits',['../IRremoteESP8266_8h.html#a149bd4f3fb9c83e683095d393209ede3',1,'IRremoteESP8266.h']]], + ['kwhirlpoolacchecksumbyte1_3040',['kWhirlpoolAcChecksumByte1',['../ir__Whirlpool_8h.html#ab199c13354730c715debbeed63182cbd',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacchecksumbyte2_3041',['kWhirlpoolAcChecksumByte2',['../ir__Whirlpool_8h.html#a37d1a2fd814ccf83062325225bddb9be',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacclockpos_3042',['kWhirlpoolAcClockPos',['../ir__Whirlpool_8h.html#ad624453fc485adaaa156bfde374208a4',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommand6thsense_3043',['kWhirlpoolAcCommand6thSense',['../ir__Whirlpool_8h.html#a48b1309aab30dd871ce047881680efa2',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandfanspeed_3044',['kWhirlpoolAcCommandFanSpeed',['../ir__Whirlpool_8h.html#a4712f7dd6c5631f6aa692eeb99fa3963',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandifeel_3045',['kWhirlpoolAcCommandIFeel',['../ir__Whirlpool_8h.html#a5cb95c379d033d7f5b0c81755f1d376f',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandlight_3046',['kWhirlpoolAcCommandLight',['../ir__Whirlpool_8h.html#af6ae6f50d9dbfa610b7033181e4f7eb1',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandmode_3047',['kWhirlpoolAcCommandMode',['../ir__Whirlpool_8h.html#ab03770a941b7277a66fe65003497e183',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandofftimer_3048',['kWhirlpoolAcCommandOffTimer',['../ir__Whirlpool_8h.html#a072883e3780aa0970183ab330db26118',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandontimer_3049',['kWhirlpoolAcCommandOnTimer',['../ir__Whirlpool_8h.html#a54cbadf2ded73e66d6d12b6622249bdc',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandpos_3050',['kWhirlpoolAcCommandPos',['../ir__Whirlpool_8h.html#a1a3bc2210991ccfd418a5137dc7e0aa8',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandpower_3051',['kWhirlpoolAcCommandPower',['../ir__Whirlpool_8h.html#ac215c2827ebfe25a896d53e576b643d1',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandsleep_3052',['kWhirlpoolAcCommandSleep',['../ir__Whirlpool_8h.html#a695c9d69953ad2663512ede38e619b09',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandsuper_3053',['kWhirlpoolAcCommandSuper',['../ir__Whirlpool_8h.html#a4da2162e70a7257c5f4149e8556816d4',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandswing_3054',['kWhirlpoolAcCommandSwing',['../ir__Whirlpool_8h.html#a320e57c0727a74f049883c77233647a9',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandtemp_3055',['kWhirlpoolAcCommandTemp',['../ir__Whirlpool_8h.html#a6e567d58af9bc3fb246e3d47a09fb065',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccool_3056',['kWhirlpoolAcCool',['../ir__Whirlpool_8h.html#a9574c0a604ffee1df43222344f649db8',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacdefaultrepeat_3057',['kWhirlpoolAcDefaultRepeat',['../IRremoteESP8266_8h.html#a3b41358898f69d96bdeece17ead13ee0',1,'IRremoteESP8266.h']]], + ['kwhirlpoolacdry_3058',['kWhirlpoolAcDry',['../ir__Whirlpool_8h.html#ab7433a4e3e8ad7ee665ab234df43e45f',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacfan_3059',['kWhirlpoolAcFan',['../ir__Whirlpool_8h.html#a91ecddbde81174268fdde3679565daeb',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacfanauto_3060',['kWhirlpoolAcFanAuto',['../ir__Whirlpool_8h.html#a133a436db244935a812beba78a1a9d05',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacfanhigh_3061',['kWhirlpoolAcFanHigh',['../ir__Whirlpool_8h.html#a93affe2700e13830ff09ee16801be56d',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacfanlow_3062',['kWhirlpoolAcFanLow',['../ir__Whirlpool_8h.html#abdbd00636661a234d9e30521144d76e1',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacfanmedium_3063',['kWhirlpoolAcFanMedium',['../ir__Whirlpool_8h.html#acf1ae9526d2fd3f49d484608730f607d',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacfanoffset_3064',['kWhirlpoolAcFanOffset',['../ir__Whirlpool_8h.html#a2cbca4b466aab8816efa70d1653bc895',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacfanpos_3065',['kWhirlpoolAcFanPos',['../ir__Whirlpool_8h.html#a02d5f4fe0837c9f9738cfb46f83c2ed9',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacfansize_3066',['kWhirlpoolAcFanSize',['../ir__Whirlpool_8h.html#ae26fab46c0f06c04f4d51b61e623873c',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacgap_3067',['kWhirlpoolAcGap',['../ir__Whirlpool_8cpp.html#a5946b0c81f68442645f795f4f6518972',1,'ir_Whirlpool.cpp']]], + ['kwhirlpoolachdrmark_3068',['kWhirlpoolAcHdrMark',['../ir__Whirlpool_8cpp.html#ad2f759eb7426cfe5fb3421f101c926bb',1,'ir_Whirlpool.cpp']]], + ['kwhirlpoolachdrspace_3069',['kWhirlpoolAcHdrSpace',['../ir__Whirlpool_8cpp.html#a7a83a305cc6ebb7be7163bd1c3fb679d',1,'ir_Whirlpool.cpp']]], + ['kwhirlpoolacheat_3070',['kWhirlpoolAcHeat',['../ir__Whirlpool_8h.html#a1e9290ec94cca537b5c44d2e4326b59c',1,'ir_Whirlpool.h']]], + ['kwhirlpoolachouroffset_3071',['kWhirlpoolAcHourOffset',['../ir__Whirlpool_8h.html#a8940e79b0e5b9f4bcf2a3e518cc59432',1,'ir_Whirlpool.h']]], + ['kwhirlpoolachoursize_3072',['kWhirlpoolAcHourSize',['../ir__Whirlpool_8h.html#ac50066e7e496cb7af6ecdb21cee7f2c9',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaclightoffset_3073',['kWhirlpoolAcLightOffset',['../ir__Whirlpool_8h.html#a5a5fbcfa7f383fb72f96c414adea8966',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacmaxtemp_3074',['kWhirlpoolAcMaxTemp',['../ir__Whirlpool_8h.html#a08171b333f214963e21a0c574783299f',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacmingap_3075',['kWhirlpoolAcMinGap',['../ir__Whirlpool_8cpp.html#aa6e5e114daf18d77914a08f831c37c7d',1,'ir_Whirlpool.cpp']]], + ['kwhirlpoolacmintemp_3076',['kWhirlpoolAcMinTemp',['../ir__Whirlpool_8h.html#aeffef97e3247609d5731b525692f1e7b',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacminuteoffset_3077',['kWhirlpoolAcMinuteOffset',['../ir__Whirlpool_8h.html#ae22595d5d1ffdc4c6b02080cd38d14d7',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacminutesize_3078',['kWhirlpoolAcMinuteSize',['../ir__Whirlpool_8h.html#a3a5cecc4480a1cb3da19f246902ab1d9',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacmodeoffset_3079',['kWhirlpoolAcModeOffset',['../ir__Whirlpool_8h.html#a662d0ab4b5f2b40bc2427e2b8d18351e',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacmodepos_3080',['kWhirlpoolAcModePos',['../ir__Whirlpool_8h.html#a6a7e8449c00a260c1ef740ebc4a08d50',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacofftimerpos_3081',['kWhirlpoolAcOffTimerPos',['../ir__Whirlpool_8h.html#a48a18046ded6bae11cd87d41d615d05f',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaconespace_3082',['kWhirlpoolAcOneSpace',['../ir__Whirlpool_8cpp.html#a7680ed11a0bc6b2f9340e3557681a470',1,'ir_Whirlpool.cpp']]], + ['kwhirlpoolacontimerpos_3083',['kWhirlpoolAcOnTimerPos',['../ir__Whirlpool_8h.html#ad10d9924f4d57547f7dc8ea085e1666f',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacpowertoggleoffset_3084',['kWhirlpoolAcPowerToggleOffset',['../ir__Whirlpool_8h.html#a1db76f65f3f10e73a0fdee65850934a2',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacpowertogglepos_3085',['kWhirlpoolAcPowerTogglePos',['../ir__Whirlpool_8h.html#a353f4f6101a152fdcfe7f13b8f8764d8',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacsections_3086',['kWhirlpoolAcSections',['../ir__Whirlpool_8cpp.html#a75ebed07d288ac32a0138035279b41c7',1,'ir_Whirlpool.cpp']]], + ['kwhirlpoolacsleepoffset_3087',['kWhirlpoolAcSleepOffset',['../ir__Whirlpool_8h.html#a83961870cfae146cbb519560ff609fc3',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacsleeppos_3088',['kWhirlpoolAcSleepPos',['../ir__Whirlpool_8h.html#a739f14122bce3a130d441bb0a47b4666',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacstatelength_3089',['kWhirlpoolAcStateLength',['../IRremoteESP8266_8h.html#a0fff60a43f776fb999d0f1f91d88154f',1,'IRremoteESP8266.h']]], + ['kwhirlpoolacsupermask_3090',['kWhirlpoolAcSuperMask',['../ir__Whirlpool_8h.html#a1946501e50abd9e1c0a3e07007a98c24',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacsuperpos_3091',['kWhirlpoolAcSuperPos',['../ir__Whirlpool_8h.html#a68e051a102449fc6712f709b166a99b9',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacswing1offset_3092',['kWhirlpoolAcSwing1Offset',['../ir__Whirlpool_8h.html#adeba9b215f8044e64df2bf805eecaa3b',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacswing2offset_3093',['kWhirlpoolAcSwing2Offset',['../ir__Whirlpool_8h.html#a3290f0b70f3eafdd885d4a08c6d5d5a3',1,'ir_Whirlpool.h']]], + ['kwhirlpoolactemppos_3094',['kWhirlpoolAcTempPos',['../ir__Whirlpool_8h.html#a15a3ef7abed2fca2881d4f5ccc969522',1,'ir_Whirlpool.h']]], + ['kwhirlpoolactimerenableoffset_3095',['kWhirlpoolAcTimerEnableOffset',['../ir__Whirlpool_8h.html#ab4694ec5e153e41f6cf56920e2291970',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaczerospace_3096',['kWhirlpoolAcZeroSpace',['../ir__Whirlpool_8cpp.html#af03c9ee4d432bbce7d2ee214dd5ca095',1,'ir_Whirlpool.cpp']]], + ['kwhynterbitmark_3097',['kWhynterBitMark',['../ir__Whynter_8cpp.html#a032043e058989b6402d8af99d2c20552',1,'ir_Whynter.cpp']]], + ['kwhynterbitmarkticks_3098',['kWhynterBitMarkTicks',['../ir__Whynter_8cpp.html#acfd8f04e0453ec1b9cd85837053a47e2',1,'ir_Whynter.cpp']]], + ['kwhynterbits_3099',['kWhynterBits',['../IRremoteESP8266_8h.html#a4553f6670e241a67104d45216a4ebd98',1,'IRremoteESP8266.h']]], + ['kwhynterhdrmark_3100',['kWhynterHdrMark',['../ir__Whynter_8cpp.html#a7d62b0e658fe6f697d41d6932e4e6662',1,'ir_Whynter.cpp']]], + ['kwhynterhdrmarkticks_3101',['kWhynterHdrMarkTicks',['../ir__Whynter_8cpp.html#a34da808cebff09fc038589c035f2d2fe',1,'ir_Whynter.cpp']]], + ['kwhynterhdrspace_3102',['kWhynterHdrSpace',['../ir__Whynter_8cpp.html#ad20c874e642238e299a44ead2ea592f1',1,'ir_Whynter.cpp']]], + ['kwhynterhdrspaceticks_3103',['kWhynterHdrSpaceTicks',['../ir__Whynter_8cpp.html#a8090f73380ea212e904402555156364d',1,'ir_Whynter.cpp']]], + ['kwhyntermincommandlength_3104',['kWhynterMinCommandLength',['../ir__Whynter_8cpp.html#a5e584a8d6aa8a146c9c8e74839b28e8f',1,'ir_Whynter.cpp']]], + ['kwhyntermincommandlengthticks_3105',['kWhynterMinCommandLengthTicks',['../ir__Whynter_8cpp.html#a65e8195824053403967573b7603059e7',1,'ir_Whynter.cpp']]], + ['kwhyntermingap_3106',['kWhynterMinGap',['../ir__Whynter_8cpp.html#ad09957f4c9c76d76ab55a74f440dad5f',1,'ir_Whynter.cpp']]], + ['kwhyntermingapticks_3107',['kWhynterMinGapTicks',['../ir__Whynter_8cpp.html#a89af5f0ab7af456f58052bf9256620a2',1,'ir_Whynter.cpp']]], + ['kwhynteronespace_3108',['kWhynterOneSpace',['../ir__Whynter_8cpp.html#a78993c22d94b107a37f61cddad728003',1,'ir_Whynter.cpp']]], + ['kwhynteronespaceticks_3109',['kWhynterOneSpaceTicks',['../ir__Whynter_8cpp.html#a95a5903a8f057df2b6587a331fec6f18',1,'ir_Whynter.cpp']]], + ['kwhyntertick_3110',['kWhynterTick',['../ir__Whynter_8cpp.html#a8f704cdf6cfd11455101919d7a772389',1,'ir_Whynter.cpp']]], + ['kwhynterzerospace_3111',['kWhynterZeroSpace',['../ir__Whynter_8cpp.html#a426deb9a35a1a6afdcbcfa58c6943490',1,'ir_Whynter.cpp']]], + ['kwhynterzerospaceticks_3112',['kWhynterZeroSpaceTicks',['../ir__Whynter_8cpp.html#ae38da416cd065b561287ebd2fe0257f0',1,'ir_Whynter.cpp']]], + ['kwide_3113',['kWide',['../namespacestdAc.html#aae50ee315fa9c9ec1a4078da40d6b147a9934dc3d02540583d5f13be6716739cd',1,'stdAc']]], + ['kwidestr_3114',['kWideStr',['../IRtext_8cpp.html#a19875c78e68ba6fdd78df3526f82969c',1,'kWideStr(): IRtext.cpp'],['../IRtext_8h.html#a6fe3dbd6899e85e79e517f71cc74a87b',1,'kWideStr(): IRtext.cpp']]], + ['kwifistr_3115',['kWifiStr',['../IRtext_8cpp.html#a3f2dddbcbc03e31ed6f1081fce001ea4',1,'kWifiStr(): IRtext.cpp'],['../IRtext_8h.html#a8bc9343f209803dbab3e765e39b41b4d',1,'kWifiStr(): IRtext.cpp']]], + ['kxfanstr_3116',['kXFanStr',['../IRtext_8cpp.html#ada36ab4b7555d38a76c4477971736cb7',1,'kXFanStr(): IRtext.cpp'],['../IRtext_8h.html#a7ddc859861308f2f9077abcec2a4b571',1,'kXFanStr(): IRtext.cpp']]], + ['kyesstr_3117',['kYesStr',['../IRtext_8cpp.html#a96492aa94d18702db41a639ae2a45423',1,'kYesStr(): IRtext.cpp'],['../IRtext_8h.html#a95ca78b5cc3caa31c564a28480379fae',1,'kYesStr(): IRtext.cpp']]], + ['kzepealbits_3118',['kZepealBits',['../IRremoteESP8266_8h.html#af09c9402a1c4fa24f692994498641296',1,'IRremoteESP8266.h']]], + ['kzepealcommandoffon_3119',['kZepealCommandOffOn',['../ir__Zepeal_8cpp.html#a37af9800da3144c218d422e54066e837',1,'ir_Zepeal.cpp']]], + ['kzepealcommandofftimer_3120',['kZepealCommandOffTimer',['../ir__Zepeal_8cpp.html#a87b136a95af4437182530d6f7cbc69ee',1,'ir_Zepeal.cpp']]], + ['kzepealcommandontimer_3121',['kZepealCommandOnTimer',['../ir__Zepeal_8cpp.html#aed4491019bb6575c113404a095e8b116',1,'ir_Zepeal.cpp']]], + ['kzepealcommandrhythm_3122',['kZepealCommandRhythm',['../ir__Zepeal_8cpp.html#aa3960b3bdaa77c060543881bdf71e46c',1,'ir_Zepeal.cpp']]], + ['kzepealcommandspeed_3123',['kZepealCommandSpeed',['../ir__Zepeal_8cpp.html#a1189a81901daaf4b8b45e8f45caf0f49',1,'ir_Zepeal.cpp']]], + ['kzepealfootermark_3124',['kZepealFooterMark',['../ir__Zepeal_8cpp.html#a83167e93978d9cec8cf2dfac980582ba',1,'ir_Zepeal.cpp']]], + ['kzepealgap_3125',['kZepealGap',['../ir__Zepeal_8cpp.html#ab5bea0fe08e14fa3d1812bea018f44f0',1,'ir_Zepeal.cpp']]], + ['kzepealhdrmark_3126',['kZepealHdrMark',['../ir__Zepeal_8cpp.html#abee2a1537cfff9481d3060fba94a4b04',1,'ir_Zepeal.cpp']]], + ['kzepealhdrspace_3127',['kZepealHdrSpace',['../ir__Zepeal_8cpp.html#ad49be13d3dd108a18e4e641a40ff0408',1,'ir_Zepeal.cpp']]], + ['kzepealminrepeat_3128',['kZepealMinRepeat',['../IRremoteESP8266_8h.html#afb5c734e808d8f108f976f0556bf6e58',1,'IRremoteESP8266.h']]], + ['kzepealonemark_3129',['kZepealOneMark',['../ir__Zepeal_8cpp.html#a4d9919883561086dd3e3060e93983480',1,'ir_Zepeal.cpp']]], + ['kzepealonespace_3130',['kZepealOneSpace',['../ir__Zepeal_8cpp.html#a88702dbff33a9dddcfd4b255637460a0',1,'ir_Zepeal.cpp']]], + ['kzepealsignature_3131',['kZepealSignature',['../ir__Zepeal_8cpp.html#a7994e564096ac01b77d9ebe3a753167d',1,'ir_Zepeal.cpp']]], + ['kzepealtolerance_3132',['kZepealTolerance',['../ir__Zepeal_8cpp.html#ab35f666ef98b24b8b4bacdf462a9fbe6',1,'ir_Zepeal.cpp']]], + ['kzepealzeromark_3133',['kZepealZeroMark',['../ir__Zepeal_8cpp.html#a94eac58ef78ea4e39687f54e381c3a00',1,'ir_Zepeal.cpp']]], + ['kzepealzerospace_3134',['kZepealZeroSpace',['../ir__Zepeal_8cpp.html#a1af802b587e8f0a88ae87ab964fde690',1,'ir_Zepeal.cpp']]], + ['kzonefollowstr_3135',['kZoneFollowStr',['../IRtext_8cpp.html#a9a112fb47e39e35d096fe09266d37db1',1,'kZoneFollowStr(): IRtext.cpp'],['../IRtext_8h.html#a100dc6d7c4d53bffa00a24a582ace80f',1,'kZoneFollowStr(): IRtext.cpp']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_c.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_c.html new file mode 100644 index 000000000..da60ab8d5 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_c.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_c.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_c.js new file mode 100644 index 000000000..4d332bcdd --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_c.js @@ -0,0 +1,15 @@ +var searchData= +[ + ['lasertag_3136',['LASERTAG',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada92eadf4fa6dd16da5b79a2fcbf729894',1,'IRremoteESP8266.h']]], + ['ledflag_3137',['ledFlag',['../classIRCoolixAC.html#a03ba5e0a6cb47a7bb054155c2111a69c',1,'IRCoolixAC']]], + ['ledoff_3138',['ledOff',['../classIRsend.html#ae71cc5aa99f894785fb4f7abc05841b2',1,'IRsend']]], + ['ledon_3139',['ledOn',['../classIRsend.html#a13d804171fa7c14aff4def38c6ffb6c8',1,'IRsend']]], + ['legopf_3140',['LEGOPF',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada9a31bf5555b17ea7b115a5c2550fc1de',1,'IRremoteESP8266.h']]], + ['lg_3141',['lg',['../classIRac.html#afad31ecf9eae573882d53dd6629485fb',1,'IRac::lg()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadadf6c249ac7d923229f9e623eff9a61f4',1,'LG(): IRremoteESP8266.h']]], + ['lg2_3142',['LG2',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada8402547ec0b99b9b0efe97dec65badf9',1,'IRremoteESP8266.h']]], + ['lg_5fac_5fremote_5fmodel_5ft_3143',['lg_ac_remote_model_t',['../IRsend_8h.html#a50c54713e16502d280723334879dc83b',1,'IRsend.h']]], + ['light_3144',['light',['../structstdAc_1_1state__t.html#a51c3a5c4703ea49b420d70aeb18b6b9b',1,'stdAc::state_t']]], + ['llword_3145',['llword',['../unionmagiquest.html#ad57fbc75ab289c3e93b94be0b2187d65',1,'magiquest']]], + ['lutron_3146',['LUTRON',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada76cc459b9e26d82ed82cf120272fd8cb',1,'IRremoteESP8266.h']]], + ['lword_3147',['lword',['../unionmagiquest.html#ac87102145311831a232002b52fe2d02c',1,'magiquest']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_d.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_d.html new file mode 100644 index 000000000..bc376fec3 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_d.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_d.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_d.js new file mode 100644 index 000000000..d968b1b91 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_d.js @@ -0,0 +1,39 @@ +var searchData= +[ + ['magiquest_3148',['magiquest',['../unionmagiquest.html',1,'magiquest'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada3be750ce1687bc1a92fee05b0c511100',1,'MAGIQUEST(): IRremoteESP8266.h']]], + ['magnitude_3149',['magnitude',['../unionmagiquest.html#a8f687419a00322a04aab223dec093d6e',1,'magiquest']]], + ['mark_3150',['mark',['../classIRsend.html#a7399389d40bfe24bc062ffca88fc3780',1,'IRsend']]], + ['markassent_3151',['markAsSent',['../classIRac.html#ad0e45b13f477e29823b8c138704536c4',1,'IRac']]], + ['match_3152',['match',['../classIRrecv.html#a8bc218dae714ab189a3da4fff269cdaa',1,'IRrecv']]], + ['match_5fresult_5ft_3153',['match_result_t',['../structmatch__result__t.html',1,'']]], + ['matchatleast_3154',['matchAtLeast',['../classIRrecv.html#ae7bfd4ff689c7563c65c4e6e8c58187a',1,'IRrecv']]], + ['matchbytes_3155',['matchBytes',['../classIRrecv.html#adc2c9bc4c4e5741cfac7468126bf8ca6',1,'IRrecv']]], + ['matchdata_3156',['matchData',['../classIRrecv.html#a5361439cb69b1069553544e486502d2e',1,'IRrecv']]], + ['matchgeneric_3157',['matchGeneric',['../classIRrecv.html#ab783f52acc2ff4052313d6947563e4fd',1,'IRrecv::matchGeneric(volatile uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, const uint16_t hdrmark, const uint32_t hdrspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t footerspace, const bool atleast=false, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true)'],['../classIRrecv.html#a4448c1658383962d735353352987c9aa',1,'IRrecv::matchGeneric(volatile uint16_t *data_ptr, uint8_t *result_ptr, const uint16_t remaining, const uint16_t nbits, const uint16_t hdrmark, const uint32_t hdrspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t footerspace, const bool atleast=false, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true)']]], + ['matchgenericconstbittime_3158',['matchGenericConstBitTime',['../classIRrecv.html#a4582d75ef1d11aee35fce86c38dcccf0',1,'IRrecv']]], + ['matchmanchester_3159',['matchManchester',['../classIRrecv.html#ade70777ad0e047e11b99b03d8f5e3728',1,'IRrecv']]], + ['matchmanchesterdata_3160',['matchManchesterData',['../classIRrecv.html#ab44403411a217eb8ea75271575f8ab83',1,'IRrecv']]], + ['matchmark_3161',['matchMark',['../classIRrecv.html#ae78ef12b8194db5d3cb5a2605d29830d',1,'IRrecv']]], + ['matchspace_3162',['matchSpace',['../classIRrecv.html#a9fd363e8b2edee2ed3c473349ecc58fc',1,'IRrecv']]], + ['midea_3163',['midea',['../classIRac.html#a5b9c72198497eca0121945b557691309',1,'IRac::midea()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada1571f3cf72caf1cf23481802b450382a',1,'MIDEA(): IRremoteESP8266.h']]], + ['midea24_3164',['MIDEA24',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada59b5ac5c1d354e50932dc0208d9b0b43',1,'IRremoteESP8266.h']]], + ['minrepeats_3165',['minRepeats',['../classIRsend.html#ae02772f34180163861b7e4eb3520db2a',1,'IRsend']]], + ['minstostring_3166',['minsToString',['../namespaceirutils.html#aebab40a2c69624adc1a5a8a6db72952f',1,'irutils']]], + ['mitsubishi_3167',['mitsubishi',['../classIRac.html#aaa60bcac75dc5dda40c78f8c227b19a3',1,'IRac::mitsubishi()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadab98915357fe1cb91de0536136be20d07',1,'MITSUBISHI(): IRremoteESP8266.h']]], + ['mitsubishi112_3168',['mitsubishi112',['../classIRac.html#a2438b6e4403d5952adb299083e038e10',1,'IRac::mitsubishi112()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadab8e5875a5959b72ca7ff17bccff97c4d',1,'MITSUBISHI112(): IRremoteESP8266.h']]], + ['mitsubishi136_3169',['mitsubishi136',['../classIRac.html#aa3033eb835cf3cd313ee2c2f38357e8e',1,'IRac::mitsubishi136()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada3c73724a654627a04cc96e280b9630fe',1,'MITSUBISHI136(): IRremoteESP8266.h']]], + ['mitsubishi2_3170',['MITSUBISHI2',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada66368850d567cbeb3b2c2233cae34cd0',1,'IRremoteESP8266.h']]], + ['mitsubishi_5fac_3171',['MITSUBISHI_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada45198cb83bbf76b320eaa91d09c44b38',1,'IRremoteESP8266.h']]], + ['mitsubishi_5fheavy_5f152_3172',['MITSUBISHI_HEAVY_152',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada15c8d1d51d5f9e42fd03638cbdfb7cbf',1,'IRremoteESP8266.h']]], + ['mitsubishi_5fheavy_5f88_3173',['MITSUBISHI_HEAVY_88',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadad303f6c0494d33354cb7c11af258f663',1,'IRremoteESP8266.h']]], + ['mitsubishiheavy152_3174',['mitsubishiHeavy152',['../classIRac.html#a635b89320d878c1e3f270d7146cb9b00',1,'IRac']]], + ['mitsubishiheavy88_3175',['mitsubishiHeavy88',['../classIRac.html#af6c9084c5e902f98a03ad0eaf3b9448e',1,'IRac']]], + ['mode_3176',['mode',['../structstdAc_1_1state__t.html#ae5e4b17fac2ea36300f796670337d7a7',1,'stdAc::state_t']]], + ['mode_5fstate_3177',['mode_state',['../classIRToshibaAC.html#a5bb8b6cef598bb8273369b3fa7ade1b0',1,'IRToshibaAC']]], + ['model_3178',['model',['../structstdAc_1_1state__t.html#aa1a57a63b2ea80c1f9c4a1bcf16a4c62',1,'stdAc::state_t']]], + ['modeltostr_3179',['modelToStr',['../namespaceirutils.html#ae89b70ce66617a8707c1951eadbc6fbd',1,'irutils']]], + ['modulation_3180',['modulation',['../classIRsend.html#a11e26c03c87e2bed756eb7f318570bd8',1,'IRsend']]], + ['mstostring_3181',['msToString',['../namespaceirutils.html#a9c59c8dd886c283fdb8adc9082c6890a',1,'irutils']]], + ['multibrackets_3182',['MULTIBRACKETS',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadaaebb72f3ad9ff2a706d8041763de6e49',1,'IRremoteESP8266.h']]], + ['mwm_3183',['MWM',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada8a6938c955212e1fb81fb511437cbe56',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_e.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_e.html new file mode 100644 index 000000000..2e3c74dc6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_e.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_e.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_e.js new file mode 100644 index 000000000..55dcd37aa --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_e.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['nec_3184',['NEC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada0811f93a25b0873e21979d569eeac05e',1,'IRremoteESP8266.h']]], + ['nec_5flike_3185',['NEC_LIKE',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada97acfde550d201fa0abc3120098fb471',1,'IRremoteESP8266.h']]], + ['neoclima_3186',['neoclima',['../classIRac.html#a0e468b705922e58308c5e340499f2391',1,'IRac::neoclima()'],['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadac698e0c030768ed91207b0e63910c3e7',1,'NEOCLIMA(): IRremoteESP8266.h']]], + ['next_3187',['next',['../classIRac.html#ae85d7ac0c58028b2547518f88d3e98fe',1,'IRac']]], + ['nikai_3188',['NIKAI',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada0bc180c4ab5e68798451f4799f7f9377',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_f.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_f.html new file mode 100644 index 000000000..246f8ab12 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_f.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_f.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_f.js new file mode 100644 index 000000000..5a8f7d74d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/all_f.js @@ -0,0 +1,12 @@ +var searchData= +[ + ['off_3189',['off',['../classIRAmcorAc.html#a5c67c2acde4964bf863d5ae73555ea1a',1,'IRAmcorAc::off()'],['../classIRArgoAC.html#ab5ab7cc22bbce59bb02ca60431dca3fb',1,'IRArgoAC::off()'],['../classIRCarrierAc64.html#ac7a262d768626f01dac94f5e2891c98e',1,'IRCarrierAc64::off()'],['../classIRCoolixAC.html#a7538665a38e193ecd3a0bed41e9f1417',1,'IRCoolixAC::off()'],['../classIRCoronaAc.html#a3744c68ec90d89999be4db5bd6ffe2a3',1,'IRCoronaAc::off()'],['../classIRDaikinESP.html#a5d1d22f45d877660719916ca546bd3af',1,'IRDaikinESP::off()'],['../classIRDaikin2.html#a84a48dfceb4d7137eb485e6897ccceac',1,'IRDaikin2::off()'],['../classIRDaikin216.html#a086d8cea2d6dd0f74c5cbece79d91567',1,'IRDaikin216::off()'],['../classIRDaikin160.html#a95f8c71bbf861d3c884656364e04b02a',1,'IRDaikin160::off()'],['../classIRDaikin176.html#a4ad81df1fe4921abee3634bf19b0d0f7',1,'IRDaikin176::off()'],['../classIRDaikin152.html#a035588ad676a54d2b6ada8cefe10e114',1,'IRDaikin152::off()'],['../classIRDelonghiAc.html#aa2f8f1d5da390bd5e5b36102dd40f5c8',1,'IRDelonghiAc::off()'],['../classIRElectraAc.html#afe3a9b789eafbef19d015cdebf71dc0d',1,'IRElectraAc::off()'],['../classIRFujitsuAC.html#ae7a320c2d2b8afbd9a04251053831cdd',1,'IRFujitsuAC::off()'],['../classIRGoodweatherAc.html#ad6863d837140951fcc0faf629025d48e',1,'IRGoodweatherAc::off()'],['../classIRGreeAC.html#a4cce897175ed731ab62402133089ed4f',1,'IRGreeAC::off()'],['../classIRHaierACYRW02.html#a9837ba26574f8bd452d616173819a9a4',1,'IRHaierACYRW02::off()'],['../classIRHitachiAc.html#a62be5ca181c8c9d11b65b38b1ed178b5',1,'IRHitachiAc::off()'],['../classIRHitachiAc1.html#a646b554980706d0dd2ac762be8458cdb',1,'IRHitachiAc1::off()'],['../classIRHitachiAc424.html#a0815a09fc49449bac03d996c63040a5f',1,'IRHitachiAc424::off()'],['../classIRKelvinatorAC.html#a4a759df902d1465c9520da7c7c595abc',1,'IRKelvinatorAC::off()'],['../classIRLgAc.html#a6d3d50b34575fecb93ed8bd5897c3f7c',1,'IRLgAc::off()'],['../classIRMideaAC.html#a29fbafcf47dc41475d009c4c92b2917b',1,'IRMideaAC::off()'],['../classIRMitsubishiAC.html#ac204620341200994c28411f53d5aa046',1,'IRMitsubishiAC::off()'],['../classIRMitsubishi136.html#a4122014509e9e755881920650f19baf3',1,'IRMitsubishi136::off()'],['../classIRMitsubishi112.html#ab5b6370edf2626da2e9f124a218678a8',1,'IRMitsubishi112::off()'],['../classIRMitsubishiHeavy152Ac.html#a93b603cc37d2dc7e3e7005ce21a0b2d7',1,'IRMitsubishiHeavy152Ac::off()'],['../classIRMitsubishiHeavy88Ac.html#a45c56c0454755d704a3df1f1f3647130',1,'IRMitsubishiHeavy88Ac::off()'],['../classIRNeoclimaAc.html#a9a277308bf8d8b0cd06a28964e7cbafb',1,'IRNeoclimaAc::off()'],['../classIRPanasonicAc.html#a03b706293c1c5b348bba536e6d8d33f5',1,'IRPanasonicAc::off()'],['../classIRSamsungAc.html#a34cb19bb4902441a2b9f10892eb17d83',1,'IRSamsungAc::off()'],['../classIRSharpAc.html#a178925a1d7ca01aae5c107fab5b32e93',1,'IRSharpAc::off()'],['../classIRTcl112Ac.html#ab2e39430629fcada55a584cff66d2749',1,'IRTcl112Ac::off()'],['../classIRTecoAc.html#ade1b1541bf2de053c78657af1ebcd001',1,'IRTecoAc::off()'],['../classIRToshibaAC.html#a70b145f7b9c46790e4e5da812bb66e58',1,'IRToshibaAC::off()'],['../classIRTrotecESP.html#a8f300ddaf255de1cdfee10b76b1f08e0',1,'IRTrotecESP::off()'],['../classIRVestelAc.html#a59e90e51e3518ef26bb382903ce67357',1,'IRVestelAc::off()']]], + ['offtimeperiod_3190',['offTimePeriod',['../classIRsend.html#a9e45c9e4f54db86c1f3e506cd72fe4c1',1,'IRsend']]], + ['on_3191',['on',['../classIRAmcorAc.html#adff3f4b9f57815a4062443f3e4dab78c',1,'IRAmcorAc::on()'],['../classIRArgoAC.html#a70497752f7afd8e3274cf4d8b1e22628',1,'IRArgoAC::on()'],['../classIRCarrierAc64.html#a39c13b713e36fbf94605f251b36bdfae',1,'IRCarrierAc64::on()'],['../classIRCoolixAC.html#a59c414fe0e951cd50083ab1fc45286ed',1,'IRCoolixAC::on()'],['../classIRCoronaAc.html#a7fe14d62eaccdc2db8db168c90a3cd87',1,'IRCoronaAc::on()'],['../classIRDaikinESP.html#a502e9dea10605d52e291d49af26b07eb',1,'IRDaikinESP::on()'],['../classIRDaikin2.html#a009ac70fd8b8695f3d931a42667fdb66',1,'IRDaikin2::on()'],['../classIRDaikin216.html#a09f54bb4ed1d553b4bbf6ffe6992a755',1,'IRDaikin216::on()'],['../classIRDaikin160.html#a2b6c282ad5cb2a702857532ab020110b',1,'IRDaikin160::on()'],['../classIRDaikin176.html#a3ca59ccdad4b7958fc4dc1a4b0593f38',1,'IRDaikin176::on()'],['../classIRDaikin152.html#a10ee74aa43e3940d657ac88cb03b9138',1,'IRDaikin152::on()'],['../classIRDelonghiAc.html#ab21d64ace3107a8f3359b3828bc2cab5',1,'IRDelonghiAc::on()'],['../classIRElectraAc.html#a99e29f982435b01c726d0234a433cfa6',1,'IRElectraAc::on()'],['../classIRFujitsuAC.html#adcb24818d088c879beb7d76ada332f43',1,'IRFujitsuAC::on()'],['../classIRGoodweatherAc.html#a1e3c2a9f47376062ab66318d6af4324b',1,'IRGoodweatherAc::on()'],['../classIRGreeAC.html#a69e399e411a19e5669e752d52ae66f15',1,'IRGreeAC::on()'],['../classIRHaierACYRW02.html#aaeb257d68235278be272e521fdec7331',1,'IRHaierACYRW02::on()'],['../classIRHitachiAc.html#a855e95d55d4ebfb3958b9d80a7b42c6f',1,'IRHitachiAc::on()'],['../classIRHitachiAc1.html#aea4fe1fddb56c8df31077b301e9c6473',1,'IRHitachiAc1::on()'],['../classIRHitachiAc424.html#ad414bca642af40ed81a6cbf93a0bf40b',1,'IRHitachiAc424::on()'],['../classIRKelvinatorAC.html#a714d0e70f2996694e2c46afdd9996341',1,'IRKelvinatorAC::on()'],['../classIRLgAc.html#a171358340c1ba8f90fef0c5454f2aa41',1,'IRLgAc::on()'],['../classIRMideaAC.html#af8dde03cb641a5af4f2ef0dcf70f1ca0',1,'IRMideaAC::on()'],['../classIRMitsubishiAC.html#a2946d1b3b641d7b991c0d296d5c5e77e',1,'IRMitsubishiAC::on()'],['../classIRMitsubishi136.html#a74180e99a5f4f1f4b740b442a1b74a06',1,'IRMitsubishi136::on()'],['../classIRMitsubishi112.html#accd250f130b4d0cd61593982b84b9138',1,'IRMitsubishi112::on()'],['../classIRMitsubishiHeavy152Ac.html#a5c7aec50b53fdc3af591e077a4a268e4',1,'IRMitsubishiHeavy152Ac::on()'],['../classIRMitsubishiHeavy88Ac.html#a44ce2c4f03b8b8973922f5bf59a19d2c',1,'IRMitsubishiHeavy88Ac::on()'],['../classIRNeoclimaAc.html#ab4a23cefef02351883dc4088dec51071',1,'IRNeoclimaAc::on()'],['../classIRPanasonicAc.html#a88e6b0f607b17266567306576e623a0c',1,'IRPanasonicAc::on()'],['../classIRSamsungAc.html#a68cf52997489a1c835662c7cdf23463c',1,'IRSamsungAc::on()'],['../classIRSharpAc.html#a5c8dad46c2965fc0d87780a8bd8b98f4',1,'IRSharpAc::on()'],['../classIRTcl112Ac.html#a0bbf7f0b9753b516fda0544c17b15b8a',1,'IRTcl112Ac::on()'],['../classIRTecoAc.html#af26015e5c663c346cf7db6d8af3f8c60',1,'IRTecoAc::on()'],['../classIRToshibaAC.html#abdc35338e4a18132d56bf6b46ddea590',1,'IRToshibaAC::on()'],['../classIRTrotecESP.html#a86c050edab8409a9b38d28f311f19404',1,'IRTrotecESP::on()'],['../classIRVestelAc.html#a4ed05fb5cbdfa5677ca238616bf03922',1,'IRVestelAc::on()']]], + ['ontimeperiod_3192',['onTimePeriod',['../classIRsend.html#aaaa65f31dbea033f8130e847b0366d94',1,'IRsend']]], + ['opmode_5ft_3193',['opmode_t',['../namespacestdAc.html#a99ad268c783486f9b3207cb78f48444f',1,'stdAc']]], + ['opmodetostring_3194',['opmodeToString',['../classIRac.html#a6dd1b87f2477bc3721d207b1fed482b8',1,'IRac']]], + ['outputoff_3195',['outputOff',['../classIRsend.html#a5e80df8b2ee534dbd6ddc30a852a2791',1,'IRsend']]], + ['outputon_3196',['outputOn',['../classIRsend.html#a4acfc45b339e724e2dbdff24762dfa7d',1,'IRsend']]], + ['overflow_3197',['overflow',['../structirparams__t.html#aa39b4f38e0ffcd470766373e03548e58',1,'irparams_t::overflow()'],['../classdecode__results.html#a821bc53c006bab3283c6b8592f0c43d3',1,'decode_results::overflow()']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_0.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_0.html new file mode 100644 index 000000000..f7e4c14e1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_0.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_0.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_0.js new file mode 100644 index 000000000..1e99ee58b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['decode_5fresults_3525',['decode_results',['../classdecode__results.html',1,'']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_1.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_1.html new file mode 100644 index 000000000..c7ff4b311 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_1.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_1.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_1.js new file mode 100644 index 000000000..49407fd27 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_1.js @@ -0,0 +1,51 @@ +var searchData= +[ + ['irac_3526',['IRac',['../classIRac.html',1,'']]], + ['iramcorac_3527',['IRAmcorAc',['../classIRAmcorAc.html',1,'']]], + ['irargoac_3528',['IRArgoAC',['../classIRArgoAC.html',1,'']]], + ['ircarrierac64_3529',['IRCarrierAc64',['../classIRCarrierAc64.html',1,'']]], + ['ircoolixac_3530',['IRCoolixAC',['../classIRCoolixAC.html',1,'']]], + ['ircoronaac_3531',['IRCoronaAc',['../classIRCoronaAc.html',1,'']]], + ['irdaikin128_3532',['IRDaikin128',['../classIRDaikin128.html',1,'']]], + ['irdaikin152_3533',['IRDaikin152',['../classIRDaikin152.html',1,'']]], + ['irdaikin160_3534',['IRDaikin160',['../classIRDaikin160.html',1,'']]], + ['irdaikin176_3535',['IRDaikin176',['../classIRDaikin176.html',1,'']]], + ['irdaikin2_3536',['IRDaikin2',['../classIRDaikin2.html',1,'']]], + ['irdaikin216_3537',['IRDaikin216',['../classIRDaikin216.html',1,'']]], + ['irdaikin64_3538',['IRDaikin64',['../classIRDaikin64.html',1,'']]], + ['irdaikinesp_3539',['IRDaikinESP',['../classIRDaikinESP.html',1,'']]], + ['irdelonghiac_3540',['IRDelonghiAc',['../classIRDelonghiAc.html',1,'']]], + ['irelectraac_3541',['IRElectraAc',['../classIRElectraAc.html',1,'']]], + ['irfujitsuac_3542',['IRFujitsuAC',['../classIRFujitsuAC.html',1,'']]], + ['irgoodweatherac_3543',['IRGoodweatherAc',['../classIRGoodweatherAc.html',1,'']]], + ['irgreeac_3544',['IRGreeAC',['../classIRGreeAC.html',1,'']]], + ['irhaierac_3545',['IRHaierAC',['../classIRHaierAC.html',1,'']]], + ['irhaieracyrw02_3546',['IRHaierACYRW02',['../classIRHaierACYRW02.html',1,'']]], + ['irhitachiac_3547',['IRHitachiAc',['../classIRHitachiAc.html',1,'']]], + ['irhitachiac1_3548',['IRHitachiAc1',['../classIRHitachiAc1.html',1,'']]], + ['irhitachiac3_3549',['IRHitachiAc3',['../classIRHitachiAc3.html',1,'']]], + ['irhitachiac344_3550',['IRHitachiAc344',['../classIRHitachiAc344.html',1,'']]], + ['irhitachiac424_3551',['IRHitachiAc424',['../classIRHitachiAc424.html',1,'']]], + ['irkelvinatorac_3552',['IRKelvinatorAC',['../classIRKelvinatorAC.html',1,'']]], + ['irlgac_3553',['IRLgAc',['../classIRLgAc.html',1,'']]], + ['irmideaac_3554',['IRMideaAC',['../classIRMideaAC.html',1,'']]], + ['irmitsubishi112_3555',['IRMitsubishi112',['../classIRMitsubishi112.html',1,'']]], + ['irmitsubishi136_3556',['IRMitsubishi136',['../classIRMitsubishi136.html',1,'']]], + ['irmitsubishiac_3557',['IRMitsubishiAC',['../classIRMitsubishiAC.html',1,'']]], + ['irmitsubishiheavy152ac_3558',['IRMitsubishiHeavy152Ac',['../classIRMitsubishiHeavy152Ac.html',1,'']]], + ['irmitsubishiheavy88ac_3559',['IRMitsubishiHeavy88Ac',['../classIRMitsubishiHeavy88Ac.html',1,'']]], + ['irneoclimaac_3560',['IRNeoclimaAc',['../classIRNeoclimaAc.html',1,'']]], + ['irpanasonicac_3561',['IRPanasonicAc',['../classIRPanasonicAc.html',1,'']]], + ['irparams_5ft_3562',['irparams_t',['../structirparams__t.html',1,'']]], + ['irrecv_3563',['IRrecv',['../classIRrecv.html',1,'']]], + ['irsamsungac_3564',['IRSamsungAc',['../classIRSamsungAc.html',1,'']]], + ['irsend_3565',['IRsend',['../classIRsend.html',1,'']]], + ['irsharpac_3566',['IRSharpAc',['../classIRSharpAc.html',1,'']]], + ['irtcl112ac_3567',['IRTcl112Ac',['../classIRTcl112Ac.html',1,'']]], + ['irtecoac_3568',['IRTecoAc',['../classIRTecoAc.html',1,'']]], + ['irtimer_3569',['IRtimer',['../classIRtimer.html',1,'']]], + ['irtoshibaac_3570',['IRToshibaAC',['../classIRToshibaAC.html',1,'']]], + ['irtrotecesp_3571',['IRTrotecESP',['../classIRTrotecESP.html',1,'']]], + ['irvestelac_3572',['IRVestelAc',['../classIRVestelAc.html',1,'']]], + ['irwhirlpoolac_3573',['IRWhirlpoolAc',['../classIRWhirlpoolAc.html',1,'']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_2.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_2.html new file mode 100644 index 000000000..0d1e8a0cd --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_2.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_2.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_2.js new file mode 100644 index 000000000..6b48c0d25 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_2.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['magiquest_3574',['magiquest',['../unionmagiquest.html',1,'']]], + ['match_5fresult_5ft_3575',['match_result_t',['../structmatch__result__t.html',1,'']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_3.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_3.html new file mode 100644 index 000000000..21025456b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_3.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_3.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_3.js new file mode 100644 index 000000000..5c2121b37 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_3.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['state_5ft_3576',['state_t',['../structstdAc_1_1state__t.html',1,'stdAc']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_4.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_4.html new file mode 100644 index 000000000..095ab5952 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_4.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_4.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_4.js new file mode 100644 index 000000000..a4b18ce82 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/classes_4.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['timerms_3577',['TimerMs',['../classTimerMs.html',1,'']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/close.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/close.png new file mode 100644 index 000000000..9342d3dfe Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/close.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_0.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_0.html new file mode 100644 index 000000000..9669700af --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_0.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_0.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_0.js new file mode 100644 index 000000000..f1f1a5972 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['decode_5ftype_5ft_6976',['decode_type_t',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fad',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_1.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_1.html new file mode 100644 index 000000000..dfec174d1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_1.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_1.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_1.js new file mode 100644 index 000000000..6f4ff342e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_1.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['fanspeed_5ft_6977',['fanspeed_t',['../namespacestdAc.html#a8bb0dbf18fe69f639f4ac0b3ff133383',1,'stdAc']]], + ['fujitsu_5fac_5fremote_5fmodel_5ft_6978',['fujitsu_ac_remote_model_t',['../IRsend_8h.html#a7204e78a1fe37a819c0b66f87a685dc0',1,'IRsend.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_2.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_2.html new file mode 100644 index 000000000..db70c3668 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_2.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_2.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_2.js new file mode 100644 index 000000000..a09539dd4 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_2.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['gree_5fac_5fremote_5fmodel_5ft_6979',['gree_ac_remote_model_t',['../IRsend_8h.html#af65070c92b97fa00b2de3818c46039c9',1,'IRsend.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_3.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_3.html new file mode 100644 index 000000000..fb7ec1764 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_3.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_3.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_3.js new file mode 100644 index 000000000..22a2e8dcd --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_3.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['hitachi_5fac1_5fremote_5fmodel_5ft_6980',['hitachi_ac1_remote_model_t',['../IRsend_8h.html#acd0c6107b5a6cab2080b18a8de14ea49',1,'IRsend.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_4.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_4.html new file mode 100644 index 000000000..b8b51ef8f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_4.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_4.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_4.js new file mode 100644 index 000000000..9f8fd8ed4 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_4.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['lg_5fac_5fremote_5fmodel_5ft_6981',['lg_ac_remote_model_t',['../IRsend_8h.html#a50c54713e16502d280723334879dc83b',1,'IRsend.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_5.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_5.html new file mode 100644 index 000000000..d39b033aa --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_5.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_5.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_5.js new file mode 100644 index 000000000..575ca6e52 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_5.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['opmode_5ft_6982',['opmode_t',['../namespacestdAc.html#a99ad268c783486f9b3207cb78f48444f',1,'stdAc']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_6.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_6.html new file mode 100644 index 000000000..7dd141e97 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_6.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_6.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_6.js new file mode 100644 index 000000000..b72fde82b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_6.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['panasonic_5fac_5fremote_5fmodel_5ft_6983',['panasonic_ac_remote_model_t',['../IRsend_8h.html#a1b797a5e5176ac0eef49810bf7f40e6f',1,'IRsend.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_7.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_7.html new file mode 100644 index 000000000..2836f52ee --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_7.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_7.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_7.js new file mode 100644 index 000000000..02ccbf16b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_7.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['swingh_5ft_6984',['swingh_t',['../namespacestdAc.html#aae50ee315fa9c9ec1a4078da40d6b147',1,'stdAc']]], + ['swingv_5ft_6985',['swingv_t',['../namespacestdAc.html#ac07f224c7bb47cac55dd01f24770ef43',1,'stdAc']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_8.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_8.html new file mode 100644 index 000000000..cf04f764b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_8.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_8.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_8.js new file mode 100644 index 000000000..2f78a824e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enums_8.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['whirlpool_5fac_5fremote_5fmodel_5ft_6986',['whirlpool_ac_remote_model_t',['../IRsend_8h.html#ab4e3ebf2fdf3c6a46da89a3e6ebcd2e2',1,'IRsend.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_0.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_0.html new file mode 100644 index 000000000..928624899 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_0.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_0.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_0.js new file mode 100644 index 000000000..c19cd973e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_0.js @@ -0,0 +1,13 @@ +var searchData= +[ + ['airwell_6987',['AIRWELL',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada0cd75c2edaa4c674d679dbb39635990a',1,'IRremoteESP8266.h']]], + ['aiwa_5frc_5ft501_6988',['AIWA_RC_T501',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada7dc14b2c4769ef9de663c2e2165d8f75',1,'IRremoteESP8266.h']]], + ['akb75215403_6989',['AKB75215403',['../IRsend_8h.html#a50c54713e16502d280723334879dc83ba37d3851f43307f1e1eac46c5fbf3f08a',1,'IRsend.h']]], + ['amcor_6990',['AMCOR',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada1325ba25674d7a99562f15a1b392086b',1,'IRremoteESP8266.h']]], + ['ardb1_6991',['ARDB1',['../IRsend_8h.html#a7204e78a1fe37a819c0b66f87a685dc0a6f6fcd0be917d91b71c1b80b5446ee5b',1,'IRsend.h']]], + ['argo_6992',['ARGO',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadac9ff1fa84905b54238b16d31197efb72',1,'IRremoteESP8266.h']]], + ['arjw2_6993',['ARJW2',['../IRsend_8h.html#a7204e78a1fe37a819c0b66f87a685dc0acbca1f3d199103d8cb9d856b9089cdc4',1,'IRsend.h']]], + ['arrah2e_6994',['ARRAH2E',['../IRsend_8h.html#a7204e78a1fe37a819c0b66f87a685dc0a6ccf47af1067e794e02e21f03389297b',1,'IRsend.h']]], + ['arreb1e_6995',['ARREB1E',['../IRsend_8h.html#a7204e78a1fe37a819c0b66f87a685dc0a2443ff6f0181dbc1af275c709d67147a',1,'IRsend.h']]], + ['arry4_6996',['ARRY4',['../IRsend_8h.html#a7204e78a1fe37a819c0b66f87a685dc0aee3994c5a4a8447463d67df2cdf5a946',1,'IRsend.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_1.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_1.html new file mode 100644 index 000000000..e22a79fb9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_1.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_1.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_1.js new file mode 100644 index 000000000..62123eb2c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_1.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['carrier_5fac_6997',['CARRIER_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada4d7328071e0a48bc828fccb02f969c20',1,'IRremoteESP8266.h']]], + ['carrier_5fac40_6998',['CARRIER_AC40',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada1340c578f7986b0ed126744127af3907',1,'IRremoteESP8266.h']]], + ['carrier_5fac64_6999',['CARRIER_AC64',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada4122973f5d8ce282457d348857ba0af0',1,'IRremoteESP8266.h']]], + ['coolix_7000',['COOLIX',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadae561d1d82d90c1b54a1a502431749873',1,'IRremoteESP8266.h']]], + ['corona_5fac_7001',['CORONA_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadaf61f2c360f487309cfa466a44fcae106',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_10.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_10.html new file mode 100644 index 000000000..7107c3d7d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_10.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_10.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_10.js new file mode 100644 index 000000000..c5c4d155a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_10.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['tcl112ac_7109',['TCL112AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadac4a6ebe702365620ed65ac6f484afda6',1,'IRremoteESP8266.h']]], + ['teco_7110',['TECO',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada3a15ee4466478d484508acc3d4d7a050',1,'IRremoteESP8266.h']]], + ['toshiba_5fac_7111',['TOSHIBA_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada66de3fced9e8f97d1919bcf4d5726f3e',1,'IRremoteESP8266.h']]], + ['trotec_7112',['TROTEC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada7d0f8056d221b37f68f80bace2b794b9',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_11.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_11.html new file mode 100644 index 000000000..aab485d35 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_11.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_11.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_11.js new file mode 100644 index 000000000..4bd54ec38 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_11.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['unknown_7113',['UNKNOWN',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada6ce26a62afab55d7606ad4e92428b30c',1,'IRremoteESP8266.h']]], + ['unused_7114',['UNUSED',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadaa09b651ef326a9d8efcee5cc5b720ab4',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_12.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_12.html new file mode 100644 index 000000000..9d9425504 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_12.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_12.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_12.js new file mode 100644 index 000000000..47989297d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_12.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['vestel_5fac_7115',['VESTEL_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada165413c6395bde985757b5b446f76569',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_13.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_13.html new file mode 100644 index 000000000..f7dea3e56 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_13.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_13.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_13.js new file mode 100644 index 000000000..7380f07ea --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_13.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['whirlpool_5fac_7116',['WHIRLPOOL_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada9faf927323d110269541b356f079b85a',1,'IRremoteESP8266.h']]], + ['whynter_7117',['WHYNTER',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada458cdd7fa2b29dc8617c694696580c0c',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_14.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_14.html new file mode 100644 index 000000000..6a7874ada --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_14.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_14.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_14.js new file mode 100644 index 000000000..8e1d3c7ff --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_14.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['yaw1f_7118',['YAW1F',['../IRsend_8h.html#af65070c92b97fa00b2de3818c46039c9a6b29d752ac8bafc8fedabc1282fccfb6',1,'IRsend.h']]], + ['ybofb_7119',['YBOFB',['../IRsend_8h.html#af65070c92b97fa00b2de3818c46039c9a5d6dadebb4f337aa20ea06a87ae9b34a',1,'IRsend.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_15.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_15.html new file mode 100644 index 000000000..1e778765b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_15.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_15.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_15.js new file mode 100644 index 000000000..7ae142fc9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_15.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['zepeal_7120',['ZEPEAL',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada1622e3d0835b4d47add716811c7bf797',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_2.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_2.html new file mode 100644 index 000000000..01a77bf7a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_2.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_2.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_2.js new file mode 100644 index 000000000..164f437b3 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_2.js @@ -0,0 +1,17 @@ +var searchData= +[ + ['daikin_7002',['DAIKIN',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadad8dc0597fd237d7098246334f3b5f37e',1,'IRremoteESP8266.h']]], + ['daikin128_7003',['DAIKIN128',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada4b26fb376f6375dd6d1d4be186438f88',1,'IRremoteESP8266.h']]], + ['daikin152_7004',['DAIKIN152',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadad3f5f7ca39aee5fdab671a1b0d647ae4',1,'IRremoteESP8266.h']]], + ['daikin160_7005',['DAIKIN160',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada4db6a848df3aed4289801e1b2bbbf6aa',1,'IRremoteESP8266.h']]], + ['daikin176_7006',['DAIKIN176',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada57f78a3b04d904f19d10bac13483deab',1,'IRremoteESP8266.h']]], + ['daikin2_7007',['DAIKIN2',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadab37b344f84d575ec78a92ca55e153586',1,'IRremoteESP8266.h']]], + ['daikin216_7008',['DAIKIN216',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadaa833fa3a20c3cbb7e6206dac4da30ffb',1,'IRremoteESP8266.h']]], + ['daikin64_7009',['DAIKIN64',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada70581853ce4883b747d22fdfd74409c4',1,'IRremoteESP8266.h']]], + ['delonghi_5fac_7010',['DELONGHI_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada149190c9dec98e9c3f4a2bd530b154a3',1,'IRremoteESP8266.h']]], + ['denon_7011',['DENON',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada2bda37b76abb290d1675c3e027e3c2e1',1,'IRremoteESP8266.h']]], + ['dg11j13a_7012',['DG11J13A',['../IRsend_8h.html#ab4e3ebf2fdf3c6a46da89a3e6ebcd2e2a868d69f0605cf9151b0163a3481e2fb9',1,'IRsend.h']]], + ['dg11j191_7013',['DG11J191',['../IRsend_8h.html#ab4e3ebf2fdf3c6a46da89a3e6ebcd2e2adaecfc16f36975f231db2507a8a36c0c',1,'IRsend.h']]], + ['dish_7014',['DISH',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadac27c6ac38ba872593af8e46ac2fdc85a',1,'IRremoteESP8266.h']]], + ['doshisha_7015',['DOSHISHA',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadab4566b260773b60c85450f40fa5b4341',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_3.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_3.html new file mode 100644 index 000000000..4e761d602 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_3.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_3.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_3.js new file mode 100644 index 000000000..7794084e0 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_3.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['electra_5fac_7016',['ELECTRA_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada05f193ef4ead3e54624bd92dc3203fac',1,'IRremoteESP8266.h']]], + ['epson_7017',['EPSON',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadaaf677fd380c38297264a10732631927c',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_4.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_4.html new file mode 100644 index 000000000..e2977a05c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_4.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_4.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_4.js new file mode 100644 index 000000000..a1b41ed5e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_4.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['fujitsu_5fac_7018',['FUJITSU_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadad8cf99a3a8776d644b78313306a2108c',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_5.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_5.html new file mode 100644 index 000000000..eabdd4be2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_5.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_5.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_5.js new file mode 100644 index 000000000..3a9434783 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_5.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['ge6711ar2853m_7019',['GE6711AR2853M',['../IRsend_8h.html#a50c54713e16502d280723334879dc83bada534bddbb58907faa6c7eae385ec790',1,'IRsend.h']]], + ['gicable_7020',['GICABLE',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadac8f9010b746a07a7a6329d1b336b68cf',1,'IRremoteESP8266.h']]], + ['globalcache_7021',['GLOBALCACHE',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadaf8c11b983768907fdb625ff9fb3729d2',1,'IRremoteESP8266.h']]], + ['goodweather_7022',['GOODWEATHER',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada9e8d893590b745f6b1b5ffcb556d9cba',1,'IRremoteESP8266.h']]], + ['gree_7023',['GREE',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadae3a5e7c315f6f88b34a4c856f280ed83',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_6.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_6.html new file mode 100644 index 000000000..24764919a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_6.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_6.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_6.js new file mode 100644 index 000000000..ddc065eb8 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_6.js @@ -0,0 +1,11 @@ +var searchData= +[ + ['haier_5fac_7024',['HAIER_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada1f232bcdf330ec2e353196941b9f1628',1,'IRremoteESP8266.h']]], + ['haier_5fac_5fyrw02_7025',['HAIER_AC_YRW02',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadaacda5821835865551f6df46c76282fa4',1,'IRremoteESP8266.h']]], + ['hitachi_5fac_7026',['HITACHI_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada9020fb54ac69d8aec0185f7e80c962ca',1,'IRremoteESP8266.h']]], + ['hitachi_5fac1_7027',['HITACHI_AC1',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada7d9a74161d95e62bece3c0e48900cb35',1,'IRremoteESP8266.h']]], + ['hitachi_5fac2_7028',['HITACHI_AC2',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadab5a44068d519506efa8a3113aa44c9c0',1,'IRremoteESP8266.h']]], + ['hitachi_5fac3_7029',['HITACHI_AC3',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadac3487c47b14da6af922f5b27992b30f3',1,'IRremoteESP8266.h']]], + ['hitachi_5fac344_7030',['HITACHI_AC344',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada1e147eb39adc40e4181940cc2357f070',1,'IRremoteESP8266.h']]], + ['hitachi_5fac424_7031',['HITACHI_AC424',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada85af068f8964d4359512265d8cc27a31',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_7.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_7.html new file mode 100644 index 000000000..5d5ce7ee6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_7.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_7.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_7.js new file mode 100644 index 000000000..32f72ebfa --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_7.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['inax_7032',['INAX',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadafc566aab3afb8face6d8965ca4d0eab7',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_8.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_8.html new file mode 100644 index 000000000..be088de03 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_8.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_8.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_8.js new file mode 100644 index 000000000..b6c589bc7 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_8.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['jvc_7033',['JVC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada5b6f507fb4bbd70ee70be4e2e0b0371d',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_9.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_9.html new file mode 100644 index 000000000..b521e0972 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_9.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_9.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_9.js new file mode 100644 index 000000000..c79d90305 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_9.js @@ -0,0 +1,35 @@ +var searchData= +[ + ['kauto_7034',['kAuto',['../namespacestdAc.html#a99ad268c783486f9b3207cb78f48444faa8c857c2f1b000c92f9794ebf53888d7',1,'stdAc::kAuto()'],['../namespacestdAc.html#a8bb0dbf18fe69f639f4ac0b3ff133383aa8c857c2f1b000c92f9794ebf53888d7',1,'stdAc::kAuto()'],['../namespacestdAc.html#ac07f224c7bb47cac55dd01f24770ef43aa8c857c2f1b000c92f9794ebf53888d7',1,'stdAc::kAuto()'],['../namespacestdAc.html#aae50ee315fa9c9ec1a4078da40d6b147aa8c857c2f1b000c92f9794ebf53888d7',1,'stdAc::kAuto()']]], + ['kcool_7035',['kCool',['../namespacestdAc.html#a99ad268c783486f9b3207cb78f48444fab9480fe865ab6bbfb66c8308068a06c2',1,'stdAc']]], + ['kdry_7036',['kDry',['../namespacestdAc.html#a99ad268c783486f9b3207cb78f48444fa0d254f21cc940f41cf7cc1c8ff46ce1f',1,'stdAc']]], + ['kelvinator_7037',['KELVINATOR',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadab3a52797572065c912c34c976c08c542',1,'IRremoteESP8266.h']]], + ['kfan_7038',['kFan',['../namespacestdAc.html#a99ad268c783486f9b3207cb78f48444fa03b7310c6ec7018a07ee9e3ffb95a34b',1,'stdAc']]], + ['kheat_7039',['kHeat',['../namespacestdAc.html#a99ad268c783486f9b3207cb78f48444faece059b52386d38cd6da9729cca08b4e',1,'stdAc']]], + ['khigh_7040',['kHigh',['../namespacestdAc.html#a8bb0dbf18fe69f639f4ac0b3ff133383aa022f15e910eb36278094efb6e808a07',1,'stdAc::kHigh()'],['../namespacestdAc.html#ac07f224c7bb47cac55dd01f24770ef43aa022f15e910eb36278094efb6e808a07',1,'stdAc::kHigh()']]], + ['khighest_7041',['kHighest',['../namespacestdAc.html#ac07f224c7bb47cac55dd01f24770ef43a24d8e31603e486f788826bc24e3a2e1d',1,'stdAc']]], + ['klastdecodetype_7042',['kLastDecodeType',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadab09881b84bf9d61af99e62a85cce0b59',1,'IRremoteESP8266.h']]], + ['klastfanspeedenum_7043',['kLastFanspeedEnum',['../namespacestdAc.html#a8bb0dbf18fe69f639f4ac0b3ff133383ab2d2a6993491fd666f1fa0afff5913ad',1,'stdAc']]], + ['klastopmodeenum_7044',['kLastOpmodeEnum',['../namespacestdAc.html#a99ad268c783486f9b3207cb78f48444fa8dd00ffd575f66172d594e78860aad9f',1,'stdAc']]], + ['klastswinghenum_7045',['kLastSwinghEnum',['../namespacestdAc.html#aae50ee315fa9c9ec1a4078da40d6b147ac5bc5e605db47897c114283926ba7fe4',1,'stdAc']]], + ['klastswingvenum_7046',['kLastSwingvEnum',['../namespacestdAc.html#ac07f224c7bb47cac55dd01f24770ef43a4127912afc084d51c71c4ea0c7dd7b30',1,'stdAc']]], + ['kleft_7047',['kLeft',['../namespacestdAc.html#aae50ee315fa9c9ec1a4078da40d6b147a2d5fde1d924910a2a01ecd8e70a87c28',1,'stdAc']]], + ['kleftmax_7048',['kLeftMax',['../namespacestdAc.html#aae50ee315fa9c9ec1a4078da40d6b147a375fe2e8ea70186052eeb2983baa1d7d',1,'stdAc']]], + ['klow_7049',['kLow',['../namespacestdAc.html#a8bb0dbf18fe69f639f4ac0b3ff133383acd8fe42741a3bbc973bbf1d404afeff4',1,'stdAc::kLow()'],['../namespacestdAc.html#ac07f224c7bb47cac55dd01f24770ef43acd8fe42741a3bbc973bbf1d404afeff4',1,'stdAc::kLow()']]], + ['klowest_7050',['kLowest',['../namespacestdAc.html#ac07f224c7bb47cac55dd01f24770ef43a334c684494b7f19d765cf062ae94a314',1,'stdAc']]], + ['kmax_7051',['kMax',['../namespacestdAc.html#a8bb0dbf18fe69f639f4ac0b3ff133383aa0b1ac8aae6b1cfbbe89085c642b3b4b',1,'stdAc']]], + ['kmedium_7052',['kMedium',['../namespacestdAc.html#a8bb0dbf18fe69f639f4ac0b3ff133383a3ce9d817402b59f65fb01ea044bb1ee9',1,'stdAc']]], + ['kmiddle_7053',['kMiddle',['../namespacestdAc.html#ac07f224c7bb47cac55dd01f24770ef43ab3199775e825c139b44e3e9ccf3cbc7e',1,'stdAc::kMiddle()'],['../namespacestdAc.html#aae50ee315fa9c9ec1a4078da40d6b147ab3199775e825c139b44e3e9ccf3cbc7e',1,'stdAc::kMiddle()']]], + ['kmin_7054',['kMin',['../namespacestdAc.html#a8bb0dbf18fe69f639f4ac0b3ff133383a8fbc2f6c44a6d70550df79903eb57d48',1,'stdAc']]], + ['koff_7055',['kOff',['../namespacestdAc.html#a99ad268c783486f9b3207cb78f48444facc9ab5e60ac2a9a675ba64bf4bb49dc8',1,'stdAc::kOff()'],['../namespacestdAc.html#ac07f224c7bb47cac55dd01f24770ef43acc9ab5e60ac2a9a675ba64bf4bb49dc8',1,'stdAc::kOff()'],['../namespacestdAc.html#aae50ee315fa9c9ec1a4078da40d6b147acc9ab5e60ac2a9a675ba64bf4bb49dc8',1,'stdAc::kOff()']]], + ['kpanasonicckp_7056',['kPanasonicCkp',['../IRsend_8h.html#a1b797a5e5176ac0eef49810bf7f40e6fa537e8c640473597d2a1cb832498f9cb0',1,'IRsend.h']]], + ['kpanasonicdke_7057',['kPanasonicDke',['../IRsend_8h.html#a1b797a5e5176ac0eef49810bf7f40e6fac8df2e0cfd553b0103f4c06a0fd573fd',1,'IRsend.h']]], + ['kpanasonicjke_7058',['kPanasonicJke',['../IRsend_8h.html#a1b797a5e5176ac0eef49810bf7f40e6fabf39cff180c071fbc44601eeded236c4',1,'IRsend.h']]], + ['kpanasoniclke_7059',['kPanasonicLke',['../IRsend_8h.html#a1b797a5e5176ac0eef49810bf7f40e6fa71ceb4b576a03a47f0d945323b896cd6',1,'IRsend.h']]], + ['kpanasonicnke_7060',['kPanasonicNke',['../IRsend_8h.html#a1b797a5e5176ac0eef49810bf7f40e6faf70fc847e204f60ab1dc5ecb330fc790',1,'IRsend.h']]], + ['kpanasonicrkr_7061',['kPanasonicRkr',['../IRsend_8h.html#a1b797a5e5176ac0eef49810bf7f40e6fab809a062f38eb61589cf5aa2db5789db',1,'IRsend.h']]], + ['kpanasonicunknown_7062',['kPanasonicUnknown',['../IRsend_8h.html#a1b797a5e5176ac0eef49810bf7f40e6fa3b23623c9580717d0ade5137200ae2a4',1,'IRsend.h']]], + ['kright_7063',['kRight',['../namespacestdAc.html#aae50ee315fa9c9ec1a4078da40d6b147a2dd2b017192f8a09367d48c7648213c9',1,'stdAc']]], + ['krightmax_7064',['kRightMax',['../namespacestdAc.html#aae50ee315fa9c9ec1a4078da40d6b147a856bf9929ade459f451be17c97db4b32',1,'stdAc']]], + ['kwide_7065',['kWide',['../namespacestdAc.html#aae50ee315fa9c9ec1a4078da40d6b147a9934dc3d02540583d5f13be6716739cd',1,'stdAc']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_a.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_a.html new file mode 100644 index 000000000..ea342169a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_a.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_a.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_a.js new file mode 100644 index 000000000..c9b03ff30 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_a.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['lasertag_7066',['LASERTAG',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada92eadf4fa6dd16da5b79a2fcbf729894',1,'IRremoteESP8266.h']]], + ['legopf_7067',['LEGOPF',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada9a31bf5555b17ea7b115a5c2550fc1de',1,'IRremoteESP8266.h']]], + ['lg_7068',['LG',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadadf6c249ac7d923229f9e623eff9a61f4',1,'IRremoteESP8266.h']]], + ['lg2_7069',['LG2',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada8402547ec0b99b9b0efe97dec65badf9',1,'IRremoteESP8266.h']]], + ['lutron_7070',['LUTRON',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada76cc459b9e26d82ed82cf120272fd8cb',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_b.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_b.html new file mode 100644 index 000000000..0bb27ce3b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_b.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_b.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_b.js new file mode 100644 index 000000000..c4d23b604 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_b.js @@ -0,0 +1,15 @@ +var searchData= +[ + ['magiquest_7071',['MAGIQUEST',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada3be750ce1687bc1a92fee05b0c511100',1,'IRremoteESP8266.h']]], + ['midea_7072',['MIDEA',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada1571f3cf72caf1cf23481802b450382a',1,'IRremoteESP8266.h']]], + ['midea24_7073',['MIDEA24',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada59b5ac5c1d354e50932dc0208d9b0b43',1,'IRremoteESP8266.h']]], + ['mitsubishi_7074',['MITSUBISHI',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadab98915357fe1cb91de0536136be20d07',1,'IRremoteESP8266.h']]], + ['mitsubishi112_7075',['MITSUBISHI112',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadab8e5875a5959b72ca7ff17bccff97c4d',1,'IRremoteESP8266.h']]], + ['mitsubishi136_7076',['MITSUBISHI136',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada3c73724a654627a04cc96e280b9630fe',1,'IRremoteESP8266.h']]], + ['mitsubishi2_7077',['MITSUBISHI2',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada66368850d567cbeb3b2c2233cae34cd0',1,'IRremoteESP8266.h']]], + ['mitsubishi_5fac_7078',['MITSUBISHI_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada45198cb83bbf76b320eaa91d09c44b38',1,'IRremoteESP8266.h']]], + ['mitsubishi_5fheavy_5f152_7079',['MITSUBISHI_HEAVY_152',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada15c8d1d51d5f9e42fd03638cbdfb7cbf',1,'IRremoteESP8266.h']]], + ['mitsubishi_5fheavy_5f88_7080',['MITSUBISHI_HEAVY_88',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadad303f6c0494d33354cb7c11af258f663',1,'IRremoteESP8266.h']]], + ['multibrackets_7081',['MULTIBRACKETS',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadaaebb72f3ad9ff2a706d8041763de6e49',1,'IRremoteESP8266.h']]], + ['mwm_7082',['MWM',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada8a6938c955212e1fb81fb511437cbe56',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_c.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_c.html new file mode 100644 index 000000000..1ee90d91d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_c.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_c.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_c.js new file mode 100644 index 000000000..c1f6db3ae --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_c.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['nec_7083',['NEC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada0811f93a25b0873e21979d569eeac05e',1,'IRremoteESP8266.h']]], + ['nec_5flike_7084',['NEC_LIKE',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada97acfde550d201fa0abc3120098fb471',1,'IRremoteESP8266.h']]], + ['neoclima_7085',['NEOCLIMA',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadac698e0c030768ed91207b0e63910c3e7',1,'IRremoteESP8266.h']]], + ['nikai_7086',['NIKAI',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada0bc180c4ab5e68798451f4799f7f9377',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_d.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_d.html new file mode 100644 index 000000000..e1b3b48a0 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_d.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_d.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_d.js new file mode 100644 index 000000000..2495af799 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_d.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['panasonic_7087',['PANASONIC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadaf87c99938d26a1f77d4f082c070d4660',1,'IRremoteESP8266.h']]], + ['panasonic_5fac_7088',['PANASONIC_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada02178d0c70511011d5f381291bb7e491',1,'IRremoteESP8266.h']]], + ['pioneer_7089',['PIONEER',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadadf49fef8f6e9740c92af2e25384f7846',1,'IRremoteESP8266.h']]], + ['pronto_7090',['PRONTO',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada5b68c32f80c4afa6e61039843b2d1f97',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_e.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_e.html new file mode 100644 index 000000000..c5d31975c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_e.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_e.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_e.js new file mode 100644 index 000000000..f1be901f7 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_e.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['r_5flt0541_5fhta_5fa_7091',['R_LT0541_HTA_A',['../IRsend_8h.html#acd0c6107b5a6cab2080b18a8de14ea49afed7c9dd67250bb1e72081e5f05b35f8',1,'IRsend.h']]], + ['r_5flt0541_5fhta_5fb_7092',['R_LT0541_HTA_B',['../IRsend_8h.html#acd0c6107b5a6cab2080b18a8de14ea49a03b6e058b4cfeb6719906bc3cd57594f',1,'IRsend.h']]], + ['raw_7093',['RAW',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadabdeded99fe7d3f2773014a9a2cfb73d7',1,'IRremoteESP8266.h']]], + ['rc5_7094',['RC5',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadac3c0a3883a1488209bcd91730ece33b2',1,'IRremoteESP8266.h']]], + ['rc5x_7095',['RC5X',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada8a3ac4419806a34ba566bfcbbb0e4f1d',1,'IRremoteESP8266.h']]], + ['rc6_7096',['RC6',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada7f7247f15587eb3812846f424b941abe',1,'IRremoteESP8266.h']]], + ['rcmm_7097',['RCMM',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada79204b7ae26be334cebf3ea8268c34ab',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_f.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_f.html new file mode 100644 index 000000000..5de961d49 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_f.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_f.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_f.js new file mode 100644 index 000000000..9af6f712f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/enumvalues_f.js @@ -0,0 +1,14 @@ +var searchData= +[ + ['samsung_7098',['SAMSUNG',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada2b451b6e7bebbf070d0913ec77d5d438',1,'IRremoteESP8266.h']]], + ['samsung36_7099',['SAMSUNG36',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadaa0d1be0c368e3594bc546c241d031fd4',1,'IRremoteESP8266.h']]], + ['samsung_5fac_7100',['SAMSUNG_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada39f991023009d760432489e7ad7ad4df',1,'IRremoteESP8266.h']]], + ['sanyo_7101',['SANYO',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadac1cf5078ebfd7ff83c70e8ec8522b288',1,'IRremoteESP8266.h']]], + ['sanyo_5flc7461_7102',['SANYO_LC7461',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada558721044a11b1d4b491343f02267e1d',1,'IRremoteESP8266.h']]], + ['sharp_7103',['SHARP',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fadaad63db67a2284cd7e3ffe382b6d6ea82',1,'IRremoteESP8266.h']]], + ['sharp_5fac_7104',['SHARP_AC',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada353a9d71906702ae10aa4f803a04ca68',1,'IRremoteESP8266.h']]], + ['sherwood_7105',['SHERWOOD',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada1412522651b0c8f1a35e1db3807466bb',1,'IRremoteESP8266.h']]], + ['sony_7106',['SONY',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada72d58193d4d25517202d22b7e57a65c3',1,'IRremoteESP8266.h']]], + ['sony_5f38k_7107',['SONY_38K',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada0027bcfbb78c0c2b951dfff1102a027b',1,'IRremoteESP8266.h']]], + ['symphony_7108',['SYMPHONY',['../IRremoteESP8266_8h.html#ad5b287a488a8c1b7b8661f029ab56fada44c4a84d776e02328ef3b169e743e5ec',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_0.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_0.html new file mode 100644 index 000000000..737608e10 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_0.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_0.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_0.js new file mode 100644 index 000000000..b09800636 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_0.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['de_2dch_2eh_3581',['de-CH.h',['../de-CH_8h.html',1,'']]], + ['de_2dde_2eh_3582',['de-DE.h',['../de-DE_8h.html',1,'']]], + ['defaults_2eh_3583',['defaults.h',['../defaults_8h.html',1,'']]], + ['doxygen_5findex_2emd_3584',['doxygen_index.md',['../doxygen__index_8md.html',1,'']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_1.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_1.html new file mode 100644 index 000000000..f27a62dee --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_1.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_1.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_1.js new file mode 100644 index 000000000..cf4d29ee1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_1.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['en_2dau_2eh_3585',['en-AU.h',['../en-AU_8h.html',1,'']]], + ['en_2die_2eh_3586',['en-IE.h',['../en-IE_8h.html',1,'']]], + ['en_2duk_2eh_3587',['en-UK.h',['../en-UK_8h.html',1,'']]], + ['en_2dus_2eh_3588',['en-US.h',['../en-US_8h.html',1,'']]], + ['es_2des_2eh_3589',['es-ES.h',['../es-ES_8h.html',1,'']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_2.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_2.html new file mode 100644 index 000000000..a45066e93 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_2.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_2.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_2.js new file mode 100644 index 000000000..67cf50118 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_2.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['fr_2dfr_2eh_3590',['fr-FR.h',['../fr-FR_8h.html',1,'']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_3.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_3.html new file mode 100644 index 000000000..1076bc5a1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_3.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_3.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_3.js new file mode 100644 index 000000000..77fc9aa49 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_3.js @@ -0,0 +1,104 @@ +var searchData= +[ + ['i18n_2eh_3591',['i18n.h',['../i18n_8h.html',1,'']]], + ['ir_5fairwell_2ecpp_3592',['ir_Airwell.cpp',['../ir__Airwell_8cpp.html',1,'']]], + ['ir_5faiwa_2ecpp_3593',['ir_Aiwa.cpp',['../ir__Aiwa_8cpp.html',1,'']]], + ['ir_5famcor_2ecpp_3594',['ir_Amcor.cpp',['../ir__Amcor_8cpp.html',1,'']]], + ['ir_5famcor_2eh_3595',['ir_Amcor.h',['../ir__Amcor_8h.html',1,'']]], + ['ir_5fargo_2ecpp_3596',['ir_Argo.cpp',['../ir__Argo_8cpp.html',1,'']]], + ['ir_5fargo_2eh_3597',['ir_Argo.h',['../ir__Argo_8h.html',1,'']]], + ['ir_5fcarrier_2ecpp_3598',['ir_Carrier.cpp',['../ir__Carrier_8cpp.html',1,'']]], + ['ir_5fcarrier_2eh_3599',['ir_Carrier.h',['../ir__Carrier_8h.html',1,'']]], + ['ir_5fcoolix_2ecpp_3600',['ir_Coolix.cpp',['../ir__Coolix_8cpp.html',1,'']]], + ['ir_5fcoolix_2eh_3601',['ir_Coolix.h',['../ir__Coolix_8h.html',1,'']]], + ['ir_5fcorona_2ecpp_3602',['ir_Corona.cpp',['../ir__Corona_8cpp.html',1,'']]], + ['ir_5fcorona_2eh_3603',['ir_Corona.h',['../ir__Corona_8h.html',1,'']]], + ['ir_5fdaikin_2ecpp_3604',['ir_Daikin.cpp',['../ir__Daikin_8cpp.html',1,'']]], + ['ir_5fdaikin_2eh_3605',['ir_Daikin.h',['../ir__Daikin_8h.html',1,'']]], + ['ir_5fdelonghi_2ecpp_3606',['ir_Delonghi.cpp',['../ir__Delonghi_8cpp.html',1,'']]], + ['ir_5fdelonghi_2eh_3607',['ir_Delonghi.h',['../ir__Delonghi_8h.html',1,'']]], + ['ir_5fdenon_2ecpp_3608',['ir_Denon.cpp',['../ir__Denon_8cpp.html',1,'']]], + ['ir_5fdish_2ecpp_3609',['ir_Dish.cpp',['../ir__Dish_8cpp.html',1,'']]], + ['ir_5fdoshisha_2ecpp_3610',['ir_Doshisha.cpp',['../ir__Doshisha_8cpp.html',1,'']]], + ['ir_5felectra_2ecpp_3611',['ir_Electra.cpp',['../ir__Electra_8cpp.html',1,'']]], + ['ir_5felectra_2eh_3612',['ir_Electra.h',['../ir__Electra_8h.html',1,'']]], + ['ir_5fepson_2ecpp_3613',['ir_Epson.cpp',['../ir__Epson_8cpp.html',1,'']]], + ['ir_5ffujitsu_2ecpp_3614',['ir_Fujitsu.cpp',['../ir__Fujitsu_8cpp.html',1,'']]], + ['ir_5ffujitsu_2eh_3615',['ir_Fujitsu.h',['../ir__Fujitsu_8h.html',1,'']]], + ['ir_5fgicable_2ecpp_3616',['ir_GICable.cpp',['../ir__GICable_8cpp.html',1,'']]], + ['ir_5fglobalcache_2ecpp_3617',['ir_GlobalCache.cpp',['../ir__GlobalCache_8cpp.html',1,'']]], + ['ir_5fgoodweather_2ecpp_3618',['ir_Goodweather.cpp',['../ir__Goodweather_8cpp.html',1,'']]], + ['ir_5fgoodweather_2eh_3619',['ir_Goodweather.h',['../ir__Goodweather_8h.html',1,'']]], + ['ir_5fgree_2ecpp_3620',['ir_Gree.cpp',['../ir__Gree_8cpp.html',1,'']]], + ['ir_5fgree_2eh_3621',['ir_Gree.h',['../ir__Gree_8h.html',1,'']]], + ['ir_5fhaier_2ecpp_3622',['ir_Haier.cpp',['../ir__Haier_8cpp.html',1,'']]], + ['ir_5fhaier_2eh_3623',['ir_Haier.h',['../ir__Haier_8h.html',1,'']]], + ['ir_5fhitachi_2ecpp_3624',['ir_Hitachi.cpp',['../ir__Hitachi_8cpp.html',1,'']]], + ['ir_5fhitachi_2eh_3625',['ir_Hitachi.h',['../ir__Hitachi_8h.html',1,'']]], + ['ir_5finax_2ecpp_3626',['ir_Inax.cpp',['../ir__Inax_8cpp.html',1,'']]], + ['ir_5fjvc_2ecpp_3627',['ir_JVC.cpp',['../ir__JVC_8cpp.html',1,'']]], + ['ir_5fkelvinator_2ecpp_3628',['ir_Kelvinator.cpp',['../ir__Kelvinator_8cpp.html',1,'']]], + ['ir_5fkelvinator_2eh_3629',['ir_Kelvinator.h',['../ir__Kelvinator_8h.html',1,'']]], + ['ir_5flasertag_2ecpp_3630',['ir_Lasertag.cpp',['../ir__Lasertag_8cpp.html',1,'']]], + ['ir_5flego_2ecpp_3631',['ir_Lego.cpp',['../ir__Lego_8cpp.html',1,'']]], + ['ir_5flg_2ecpp_3632',['ir_LG.cpp',['../ir__LG_8cpp.html',1,'']]], + ['ir_5flg_2eh_3633',['ir_LG.h',['../ir__LG_8h.html',1,'']]], + ['ir_5flutron_2ecpp_3634',['ir_Lutron.cpp',['../ir__Lutron_8cpp.html',1,'']]], + ['ir_5fmagiquest_2ecpp_3635',['ir_Magiquest.cpp',['../ir__Magiquest_8cpp.html',1,'']]], + ['ir_5fmagiquest_2eh_3636',['ir_Magiquest.h',['../ir__Magiquest_8h.html',1,'']]], + ['ir_5fmidea_2ecpp_3637',['ir_Midea.cpp',['../ir__Midea_8cpp.html',1,'']]], + ['ir_5fmidea_2eh_3638',['ir_Midea.h',['../ir__Midea_8h.html',1,'']]], + ['ir_5fmitsubishi_2ecpp_3639',['ir_Mitsubishi.cpp',['../ir__Mitsubishi_8cpp.html',1,'']]], + ['ir_5fmitsubishi_2eh_3640',['ir_Mitsubishi.h',['../ir__Mitsubishi_8h.html',1,'']]], + ['ir_5fmitsubishiheavy_2ecpp_3641',['ir_MitsubishiHeavy.cpp',['../ir__MitsubishiHeavy_8cpp.html',1,'']]], + ['ir_5fmitsubishiheavy_2eh_3642',['ir_MitsubishiHeavy.h',['../ir__MitsubishiHeavy_8h.html',1,'']]], + ['ir_5fmultibrackets_2ecpp_3643',['ir_Multibrackets.cpp',['../ir__Multibrackets_8cpp.html',1,'']]], + ['ir_5fmwm_2ecpp_3644',['ir_MWM.cpp',['../ir__MWM_8cpp.html',1,'']]], + ['ir_5fnec_2ecpp_3645',['ir_NEC.cpp',['../ir__NEC_8cpp.html',1,'']]], + ['ir_5fnec_2eh_3646',['ir_NEC.h',['../ir__NEC_8h.html',1,'']]], + ['ir_5fneoclima_2ecpp_3647',['ir_Neoclima.cpp',['../ir__Neoclima_8cpp.html',1,'']]], + ['ir_5fneoclima_2eh_3648',['ir_Neoclima.h',['../ir__Neoclima_8h.html',1,'']]], + ['ir_5fnikai_2ecpp_3649',['ir_Nikai.cpp',['../ir__Nikai_8cpp.html',1,'']]], + ['ir_5fpanasonic_2ecpp_3650',['ir_Panasonic.cpp',['../ir__Panasonic_8cpp.html',1,'']]], + ['ir_5fpanasonic_2eh_3651',['ir_Panasonic.h',['../ir__Panasonic_8h.html',1,'']]], + ['ir_5fpioneer_2ecpp_3652',['ir_Pioneer.cpp',['../ir__Pioneer_8cpp.html',1,'']]], + ['ir_5fpronto_2ecpp_3653',['ir_Pronto.cpp',['../ir__Pronto_8cpp.html',1,'']]], + ['ir_5frc5_5frc6_2ecpp_3654',['ir_RC5_RC6.cpp',['../ir__RC5__RC6_8cpp.html',1,'']]], + ['ir_5frcmm_2ecpp_3655',['ir_RCMM.cpp',['../ir__RCMM_8cpp.html',1,'']]], + ['ir_5fsamsung_2ecpp_3656',['ir_Samsung.cpp',['../ir__Samsung_8cpp.html',1,'']]], + ['ir_5fsamsung_2eh_3657',['ir_Samsung.h',['../ir__Samsung_8h.html',1,'']]], + ['ir_5fsanyo_2ecpp_3658',['ir_Sanyo.cpp',['../ir__Sanyo_8cpp.html',1,'']]], + ['ir_5fsharp_2ecpp_3659',['ir_Sharp.cpp',['../ir__Sharp_8cpp.html',1,'']]], + ['ir_5fsharp_2eh_3660',['ir_Sharp.h',['../ir__Sharp_8h.html',1,'']]], + ['ir_5fsherwood_2ecpp_3661',['ir_Sherwood.cpp',['../ir__Sherwood_8cpp.html',1,'']]], + ['ir_5fsony_2ecpp_3662',['ir_Sony.cpp',['../ir__Sony_8cpp.html',1,'']]], + ['ir_5fsymphony_2ecpp_3663',['ir_Symphony.cpp',['../ir__Symphony_8cpp.html',1,'']]], + ['ir_5ftcl_2ecpp_3664',['ir_Tcl.cpp',['../ir__Tcl_8cpp.html',1,'']]], + ['ir_5ftcl_2eh_3665',['ir_Tcl.h',['../ir__Tcl_8h.html',1,'']]], + ['ir_5fteco_2ecpp_3666',['ir_Teco.cpp',['../ir__Teco_8cpp.html',1,'']]], + ['ir_5fteco_2eh_3667',['ir_Teco.h',['../ir__Teco_8h.html',1,'']]], + ['ir_5ftoshiba_2ecpp_3668',['ir_Toshiba.cpp',['../ir__Toshiba_8cpp.html',1,'']]], + ['ir_5ftoshiba_2eh_3669',['ir_Toshiba.h',['../ir__Toshiba_8h.html',1,'']]], + ['ir_5ftrotec_2ecpp_3670',['ir_Trotec.cpp',['../ir__Trotec_8cpp.html',1,'']]], + ['ir_5ftrotec_2eh_3671',['ir_Trotec.h',['../ir__Trotec_8h.html',1,'']]], + ['ir_5fvestel_2ecpp_3672',['ir_Vestel.cpp',['../ir__Vestel_8cpp.html',1,'']]], + ['ir_5fvestel_2eh_3673',['ir_Vestel.h',['../ir__Vestel_8h.html',1,'']]], + ['ir_5fwhirlpool_2ecpp_3674',['ir_Whirlpool.cpp',['../ir__Whirlpool_8cpp.html',1,'']]], + ['ir_5fwhirlpool_2eh_3675',['ir_Whirlpool.h',['../ir__Whirlpool_8h.html',1,'']]], + ['ir_5fwhynter_2ecpp_3676',['ir_Whynter.cpp',['../ir__Whynter_8cpp.html',1,'']]], + ['ir_5fzepeal_2ecpp_3677',['ir_Zepeal.cpp',['../ir__Zepeal_8cpp.html',1,'']]], + ['irac_2ecpp_3678',['IRac.cpp',['../IRac_8cpp.html',1,'']]], + ['irac_2eh_3679',['IRac.h',['../IRac_8h.html',1,'']]], + ['irrecv_2ecpp_3680',['IRrecv.cpp',['../IRrecv_8cpp.html',1,'']]], + ['irrecv_2eh_3681',['IRrecv.h',['../IRrecv_8h.html',1,'']]], + ['irremoteesp8266_2eh_3682',['IRremoteESP8266.h',['../IRremoteESP8266_8h.html',1,'']]], + ['irsend_2ecpp_3683',['IRsend.cpp',['../IRsend_8cpp.html',1,'']]], + ['irsend_2eh_3684',['IRsend.h',['../IRsend_8h.html',1,'']]], + ['irtext_2ecpp_3685',['IRtext.cpp',['../IRtext_8cpp.html',1,'']]], + ['irtext_2eh_3686',['IRtext.h',['../IRtext_8h.html',1,'']]], + ['irtimer_2ecpp_3687',['IRtimer.cpp',['../IRtimer_8cpp.html',1,'']]], + ['irtimer_2eh_3688',['IRtimer.h',['../IRtimer_8h.html',1,'']]], + ['irutils_2ecpp_3689',['IRutils.cpp',['../IRutils_8cpp.html',1,'']]], + ['irutils_2eh_3690',['IRutils.h',['../IRutils_8h.html',1,'']]], + ['it_2dit_2eh_3691',['it-IT.h',['../it-IT_8h.html',1,'']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_4.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_4.html new file mode 100644 index 000000000..e5cd7f43a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_4.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_4.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_4.js new file mode 100644 index 000000000..7ac14309d --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_4.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['readme_2emd_3692',['README.md',['../README_8md.html',1,'']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_5.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_5.html new file mode 100644 index 000000000..2cc480f29 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_5.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_5.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_5.js new file mode 100644 index 000000000..8fcced443 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/files_5.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['zh_2dcn_2eh_3693',['zh-CN.h',['../zh-CN_8h.html',1,'']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_0.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_0.html new file mode 100644 index 000000000..e17c71111 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_0.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_0.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_0.js new file mode 100644 index 000000000..597eca1db --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_0.js @@ -0,0 +1,17 @@ +var searchData= +[ + ['_5fcancelofftimer_3694',['_cancelOffTimer',['../classIRCarrierAc64.html#a4a0fdf34836b1c954b27c9b242324679',1,'IRCarrierAc64']]], + ['_5fcancelontimer_3695',['_cancelOnTimer',['../classIRCarrierAc64.html#a43e7be5a1a6fe2dbfe245e99d2205779',1,'IRCarrierAc64']]], + ['_5fdelaymicroseconds_3696',['_delayMicroseconds',['../classIRsend.html#a61ceb32aa53f538b93377b10e58b45c9',1,'IRsend']]], + ['_5fgettime_3697',['_getTime',['../classIRPanasonicAc.html#ab0a592b759daf90be548ac69ae99f40f',1,'IRPanasonicAc']]], + ['_5fgettimer_3698',['_getTimer',['../classIRCoronaAc.html#a419053fbf9ef27e937db0ff7519927bd',1,'IRCoronaAc::_getTimer()'],['../classIRVestelAc.html#ad3f095d248ad3c84a777ed9f2d3b001e',1,'IRVestelAc::_getTimer()']]], + ['_5fmatchgeneric_3699',['_matchGeneric',['../classIRrecv.html#af0b300fe6fdff58324525e8208be3024',1,'IRrecv']]], + ['_5fsendsony_3700',['_sendSony',['../classIRsend.html#a21352b4499f976872a74bae36ea10338',1,'IRsend']]], + ['_5fsetmode_3701',['_setMode',['../classIRWhirlpoolAc.html#a60fd8da35d6e0137711e114a5307d664',1,'IRWhirlpoolAc']]], + ['_5fsetpower_3702',['_setPower',['../classIRCoronaAc.html#a4b05b7e34e0f2e66f59ff279c6970478',1,'IRCoronaAc']]], + ['_5fsettemp_3703',['_setTemp',['../classIRLgAc.html#a39aca9861608211c8e74c89a7ccc97cd',1,'IRLgAc::_setTemp()'],['../classIRWhirlpoolAc.html#abb221e09077efd96304f84e8ca130458',1,'IRWhirlpoolAc::_setTemp()']]], + ['_5fsettime_3704',['_setTime',['../classIRPanasonicAc.html#a51e306dd7a3e4d580ed5396fcd166141',1,'IRPanasonicAc']]], + ['_5fsettimer_3705',['_setTimer',['../classIRCoronaAc.html#a0ea9319987de7cb7f3dcb9fbefb60a2c',1,'IRCoronaAc::_setTimer()'],['../classIRVestelAc.html#a726178a16458c84d031aec07355d0dd2',1,'IRVestelAc::_setTimer()']]], + ['_5ftostring_3706',['_toString',['../classIRHitachiAc424.html#af7ab654c4eecf770a70399f6b9959db3',1,'IRHitachiAc424']]], + ['_5fvalidtolerance_3707',['_validTolerance',['../classIRrecv.html#a0b4221970de0d027b5ae99648fa1c003',1,'IRrecv']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_1.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_1.html new file mode 100644 index 000000000..0ddac0a4f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_1.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_1.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_1.js new file mode 100644 index 000000000..37bfc00b2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_1.js @@ -0,0 +1,14 @@ +var searchData= +[ + ['add_3708',['add',['../classIRtimer.html#aa8e3ff975ae5468b4727790c828fa032',1,'IRtimer::add()'],['../classTimerMs.html#a77bfc23a029a9172c3dbac03f746b0cb',1,'TimerMs::add()']]], + ['addbooltostring_3709',['addBoolToString',['../namespaceirutils.html#a12ba9cf1830a886649a80c3cc5fdce2b',1,'irutils']]], + ['adddaytostring_3710',['addDayToString',['../namespaceirutils.html#a6ead1d10578c64627f8a24b5d8a7444f',1,'irutils']]], + ['addfantostring_3711',['addFanToString',['../namespaceirutils.html#ae023bbabc452173d348c14eac7d86ab4',1,'irutils']]], + ['addinttostring_3712',['addIntToString',['../namespaceirutils.html#a772e623c4b60208200e02afbaec66651',1,'irutils']]], + ['addlabeledstring_3713',['addLabeledString',['../namespaceirutils.html#ac98793392d1e65c1b8d6895eb9d9b75b',1,'irutils']]], + ['addmodeltostring_3714',['addModelToString',['../namespaceirutils.html#a06e5a5c2b6f6649035dfa5eb19801367',1,'irutils']]], + ['addmodetostring_3715',['addModeToString',['../namespaceirutils.html#a8b74ae0258e98aa0eaebc6f3efe1481e',1,'irutils']]], + ['addtemptostring_3716',['addTempToString',['../namespaceirutils.html#a0cef0634f4db979a93b7dc19cc2b4a85',1,'irutils']]], + ['amcor_3717',['amcor',['../classIRac.html#a4bad16621b232572e14fe4a53f678131',1,'IRac']]], + ['argo_3718',['argo',['../classIRac.html#aa06ee1314529dbf96f4e6f3c28ea6821',1,'IRac']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_10.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_10.html new file mode 100644 index 000000000..09422e1e5 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_10.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_10.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_10.js new file mode 100644 index 000000000..9f5b65adc --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_10.js @@ -0,0 +1,13 @@ +var searchData= +[ + ['recoversavedstate_4090',['recoverSavedState',['../classIRCoolixAC.html#a134cb36681c3fab53074b402bba0a45c',1,'IRCoolixAC']]], + ['reset_4091',['reset',['../classIRtimer.html#aaaf886de2c9533a8c791242dc575db1a',1,'IRtimer::reset()'],['../classTimerMs.html#a25ab025793a4d432e7d4180cbd31157b',1,'TimerMs::reset()']]], + ['resultactostring_4092',['resultAcToString',['../namespaceIRAcUtils.html#ac3d2683bc26edc2bf58916187b5349c3',1,'IRAcUtils']]], + ['resulttohexidecimal_4093',['resultToHexidecimal',['../IRutils_8cpp.html#a25a669d53f231de6152f8e60cedf39f7',1,'resultToHexidecimal(const decode_results *const result): IRutils.cpp'],['../IRutils_8h.html#a25a669d53f231de6152f8e60cedf39f7',1,'resultToHexidecimal(const decode_results *const result): IRutils.cpp']]], + ['resulttohumanreadablebasic_4094',['resultToHumanReadableBasic',['../IRutils_8cpp.html#a0cc6ae1b9649b1ea1d2bfe7e7b03b6d8',1,'resultToHumanReadableBasic(const decode_results *const results): IRutils.cpp'],['../IRutils_8h.html#a0cc6ae1b9649b1ea1d2bfe7e7b03b6d8',1,'resultToHumanReadableBasic(const decode_results *const results): IRutils.cpp']]], + ['resulttorawarray_4095',['resultToRawArray',['../IRutils_8cpp.html#a7b3bbfa1f2bf2dea2fc40a2fefe05a2a',1,'resultToRawArray(const decode_results *const decode): IRutils.cpp'],['../IRutils_8h.html#a7b3bbfa1f2bf2dea2fc40a2fefe05a2a',1,'resultToRawArray(const decode_results *const decode): IRutils.cpp']]], + ['resulttosourcecode_4096',['resultToSourceCode',['../IRutils_8cpp.html#a10fc00c8b399dddb67a228325e6e2f79',1,'resultToSourceCode(const decode_results *const results): IRutils.cpp'],['../IRutils_8h.html#a10fc00c8b399dddb67a228325e6e2f79',1,'resultToSourceCode(const decode_results *const results): IRutils.cpp']]], + ['resulttotiminginfo_4097',['resultToTimingInfo',['../IRutils_8cpp.html#afbfdef125ff077431f3abc27a1eeb800',1,'resultToTimingInfo(const decode_results *const results): IRutils.cpp'],['../IRutils_8h.html#afbfdef125ff077431f3abc27a1eeb800',1,'resultToTimingInfo(const decode_results *const results): IRutils.cpp']]], + ['resume_4098',['resume',['../classIRrecv.html#a6b5beb7348d807d8d98ae929d005510e',1,'IRrecv']]], + ['reversebits_4099',['reverseBits',['../IRutils_8cpp.html#a366219b6f1c46f41c6573b3e5e875e41',1,'reverseBits(uint64_t input, uint16_t nbits): IRutils.cpp'],['../IRutils_8h.html#a366219b6f1c46f41c6573b3e5e875e41',1,'reverseBits(uint64_t input, uint16_t nbits): IRutils.cpp']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_11.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_11.html new file mode 100644 index 000000000..1cde7b49e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_11.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_11.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_11.js new file mode 100644 index 000000000..a8ba75f82 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_11.js @@ -0,0 +1,218 @@ +var searchData= +[ + ['samsung_4100',['samsung',['../classIRac.html#a619c659a11c258ea9623eaa37689ba4c',1,'IRac']]], + ['send_4101',['send',['../classIRAmcorAc.html#a4fa894c01a8baabfeadb39634a850fd9',1,'IRAmcorAc::send()'],['../classIRArgoAC.html#a0e4793a4f6fc537ec1450f5a42206dae',1,'IRArgoAC::send()'],['../classIRCarrierAc64.html#aace8aa2d125c6e80bcdd6d96eac722c2',1,'IRCarrierAc64::send()'],['../classIRCoolixAC.html#aaaa681d6cfcf04d110b913e8bb27a53c',1,'IRCoolixAC::send()'],['../classIRCoronaAc.html#aa0c8a1ef4473a3c7d02e1a04c7678fa6',1,'IRCoronaAc::send()'],['../classIRDaikinESP.html#a9f0d2641b54e97da943fceb0ba3f67eb',1,'IRDaikinESP::send()'],['../classIRDaikin2.html#aae2db88038d8d02617f16588e6a82b64',1,'IRDaikin2::send()'],['../classIRDaikin216.html#ab1061620f838cf7774c16c593b4ada8c',1,'IRDaikin216::send()'],['../classIRDaikin160.html#a0e1c74070c03be02e40fdd05ed56465c',1,'IRDaikin160::send()'],['../classIRDaikin176.html#affd71592fa8ed05816d94edbf94d2c0a',1,'IRDaikin176::send()'],['../classIRDaikin128.html#aae7fec91ad2265e8b0378c6b99379e89',1,'IRDaikin128::send()'],['../classIRDaikin152.html#a205de6821effc077f51d941d369791e4',1,'IRDaikin152::send()'],['../classIRDaikin64.html#a904eec38045d9ddc8a97ab33c8a2ac4d',1,'IRDaikin64::send()'],['../classIRDelonghiAc.html#afba831b6884771b84bab684732e0f4f5',1,'IRDelonghiAc::send()'],['../classIRElectraAc.html#a30170a65de1161e26daeddf694f8afdb',1,'IRElectraAc::send()'],['../classIRFujitsuAC.html#a1f1aa593cc4503d14c0fbea5cd9823a1',1,'IRFujitsuAC::send()'],['../classIRGoodweatherAc.html#abcc3c9d9b0912b09d3c0b0c1affb8cc8',1,'IRGoodweatherAc::send()'],['../classIRGreeAC.html#a9823578040c2d15e2b3e8e3a17a9e220',1,'IRGreeAC::send()'],['../classIRHaierAC.html#a9fe53d04965efca6daf234f20d20eb5a',1,'IRHaierAC::send()'],['../classIRHaierACYRW02.html#a65a5d5840dddac505b009e899a0dada7',1,'IRHaierACYRW02::send()'],['../classIRHitachiAc.html#afc53e562370bbaba8b5dda26a62de427',1,'IRHitachiAc::send()'],['../classIRHitachiAc1.html#aafad51c226066b8697cf00661ef38d99',1,'IRHitachiAc1::send()'],['../classIRHitachiAc424.html#adf15121bb329e1bb061f9e5efb848764',1,'IRHitachiAc424::send()'],['../classIRHitachiAc3.html#ab95fd527a4841c44d6e91c8b4afee8b4',1,'IRHitachiAc3::send()'],['../classIRHitachiAc344.html#ae9b33c0adfc1506b1d9ede1e3285c3e3',1,'IRHitachiAc344::send()'],['../classIRKelvinatorAC.html#aa55fbfefbaca1acf5bc9ba796bea8464',1,'IRKelvinatorAC::send()'],['../classIRLgAc.html#aea85c840161b48f2e8d31e7e6e7da532',1,'IRLgAc::send()'],['../classIRMideaAC.html#af66b9f76ad794450a0a7eace4bb59300',1,'IRMideaAC::send()'],['../classIRMitsubishiAC.html#a2467ad33d88af8f6244e7cd0620e012e',1,'IRMitsubishiAC::send()'],['../classIRMitsubishi136.html#a41295e551acf428e76b9b404af2381ad',1,'IRMitsubishi136::send()'],['../classIRMitsubishi112.html#a8f813da813b1a281654147ada2e63eba',1,'IRMitsubishi112::send()'],['../classIRMitsubishiHeavy152Ac.html#acc53c5c136c6987c420d48bddcf9b2da',1,'IRMitsubishiHeavy152Ac::send()'],['../classIRMitsubishiHeavy88Ac.html#a707cb3ec3e3c18bedeb12205580d5048',1,'IRMitsubishiHeavy88Ac::send()'],['../classIRNeoclimaAc.html#a2220bbb1d928b8f6490cd43b702ef430',1,'IRNeoclimaAc::send()'],['../classIRPanasonicAc.html#a778420ebe52aa6422ba5633ce91676df',1,'IRPanasonicAc::send()'],['../classIRSamsungAc.html#a8128429fcb1828a049784d832cafc9fe',1,'IRSamsungAc::send()'],['../classIRSharpAc.html#a829872744bf9fef51dccd89584ddffe6',1,'IRSharpAc::send()'],['../classIRTcl112Ac.html#a9aa8c67e167a3d241157306d0668ff15',1,'IRTcl112Ac::send()'],['../classIRTecoAc.html#ad5785e93e8c0c95a8618b0e371adaa79',1,'IRTecoAc::send()'],['../classIRToshibaAC.html#a14b155d3a20fb9c127eb7f3fe1fd16cd',1,'IRToshibaAC::send()'],['../classIRTrotecESP.html#add228d50195d7b9b43346a90bf959512',1,'IRTrotecESP::send()'],['../classIRVestelAc.html#a606497754b381e70d13ddef5643c9d0b',1,'IRVestelAc::send()'],['../classIRWhirlpoolAc.html#a0c043b3d7cc993940941351e6c63b5cc',1,'IRWhirlpoolAc::send()'],['../classIRsend.html#a204eedc3ad182fb2f40c42ef58f78cfc',1,'IRsend::send(const decode_type_t type, const uint64_t data, const uint16_t nbits, const uint16_t repeat=kNoRepeat)'],['../classIRsend.html#ac684c209ea8722f0a377070752df0040',1,'IRsend::send(const decode_type_t type, const uint8_t *state, const uint16_t nbytes)']]], + ['sendac_4102',['sendAc',['../classIRac.html#a0cea80b7bab92c9dc4f18c61f5762130',1,'IRac::sendAc(void)'],['../classIRac.html#aa33c42968acafc5cf479574483f94ea9',1,'IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev=NULL)'],['../classIRac.html#ad60fbe1488efe2d02307d81b090b3b72',1,'IRac::sendAc(const decode_type_t vendor, const int16_t model, const bool power, const stdAc::opmode_t mode, const float degrees, const bool celsius, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool econo, const bool light, const bool filter, const bool clean, const bool beep, const int16_t sleep=-1, const int16_t clock=-1)']]], + ['sendairwell_4103',['sendAirwell',['../classIRsend.html#a5b180d3845b45af38a19b72e6fa8e0c0',1,'IRsend']]], + ['sendaiwarct501_4104',['sendAiwaRCT501',['../classIRsend.html#ad39a4b13ad2e8500c95db49265e7c771',1,'IRsend']]], + ['sendamcor_4105',['sendAmcor',['../classIRsend.html#acd64b100eb155f90451d467188a83e92',1,'IRsend']]], + ['sendargo_4106',['sendArgo',['../classIRsend.html#a59668b767e4ad4966fe0bc259c3bd34f',1,'IRsend']]], + ['sendcarrierac_4107',['sendCarrierAC',['../classIRsend.html#a9e859a8b5eaea2e64978c8f93b78d159',1,'IRsend']]], + ['sendcarrierac40_4108',['sendCarrierAC40',['../classIRsend.html#a4342b775777d2ff9371f48aa39ad9b69',1,'IRsend']]], + ['sendcarrierac64_4109',['sendCarrierAC64',['../classIRsend.html#abf755688d87fcef5aee86c6a2c89e7c4',1,'IRsend']]], + ['sendcoolix_4110',['sendCOOLIX',['../classIRsend.html#a088af5f0d76965c61fe5716f7b8f2b61',1,'IRsend']]], + ['sendcoronaac_4111',['sendCoronaAc',['../classIRsend.html#a81f82b8248b324799a48a7685d62aaa5',1,'IRsend']]], + ['senddaikin_4112',['sendDaikin',['../classIRsend.html#a3010546144b5ca3b3c94f5881050dbd0',1,'IRsend']]], + ['senddaikin128_4113',['sendDaikin128',['../classIRsend.html#a72a41a704d48750c144c6467ae9a1430',1,'IRsend']]], + ['senddaikin152_4114',['sendDaikin152',['../classIRsend.html#a4ad420eb86e0ae38b12e983f7eaa912c',1,'IRsend']]], + ['senddaikin160_4115',['sendDaikin160',['../classIRsend.html#ab144a86def38f9f5c98701742683c004',1,'IRsend']]], + ['senddaikin176_4116',['sendDaikin176',['../classIRsend.html#ac4b5bcb95d3aff70b2f84074177e9e92',1,'IRsend']]], + ['senddaikin2_4117',['sendDaikin2',['../classIRsend.html#a34262e579cbb6634459bc09c5b15dfa0',1,'IRsend']]], + ['senddaikin216_4118',['sendDaikin216',['../classIRsend.html#aa99bfdaa71ff5bf088faaa17d304f45d',1,'IRsend']]], + ['senddaikin64_4119',['sendDaikin64',['../classIRsend.html#aa403d2192a6eb57910e6f84695475b27',1,'IRsend']]], + ['senddata_4120',['sendData',['../classIRsend.html#a4f8cd77dab7ce6c406029fe87674858f',1,'IRsend']]], + ['senddelonghiac_4121',['sendDelonghiAc',['../classIRsend.html#a35dc18f9abbffa8da40816a8a9df1093',1,'IRsend']]], + ['senddenon_4122',['sendDenon',['../classIRsend.html#a2618e000bf91cf1585329308a078653a',1,'IRsend']]], + ['senddish_4123',['sendDISH',['../classIRsend.html#ac7a72d61af219d983409911bdc1769b8',1,'IRsend']]], + ['senddoshisha_4124',['sendDoshisha',['../classIRsend.html#a3a9a8247e470975137b37f474bb97639',1,'IRsend']]], + ['sendelectraac_4125',['sendElectraAC',['../classIRsend.html#a52526c4e7bc4402e57ecf81e0047d49c',1,'IRsend']]], + ['sendepson_4126',['sendEpson',['../classIRsend.html#a063168fd82f6a88cca7253b42b9c0b28',1,'IRsend']]], + ['sendextended_4127',['sendExtended',['../classIRSamsungAc.html#a16a8dbd8f3fd34a6e681125b276acfd9',1,'IRSamsungAc']]], + ['sendfujitsuac_4128',['sendFujitsuAC',['../classIRsend.html#a1a3d3f83d0b7a59ff5510b038f658eb6',1,'IRsend']]], + ['sendgc_4129',['sendGC',['../classIRsend.html#acf987a501326d9c945cd8dbeb0806e17',1,'IRsend']]], + ['sendgeneric_4130',['sendGeneric',['../classIRsend.html#a5215fd797dfd490816f31bb99b38c273',1,'IRsend::sendGeneric(const uint16_t headermark, const uint32_t headerspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t gap, const uint64_t data, const uint16_t nbits, const uint16_t frequency, const bool MSBfirst, const uint16_t repeat, const uint8_t dutycycle)'],['../classIRsend.html#aaace48306af9c020c18848db1a05e641',1,'IRsend::sendGeneric(const uint16_t headermark, const uint32_t headerspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t gap, const uint32_t mesgtime, const uint64_t data, const uint16_t nbits, const uint16_t frequency, const bool MSBfirst, const uint16_t repeat, const uint8_t dutycycle)'],['../classIRsend.html#a4f5ad649827692b4b42d15b45c7f684b',1,'IRsend::sendGeneric(const uint16_t headermark, const uint32_t headerspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t gap, const uint8_t *dataptr, const uint16_t nbytes, const uint16_t frequency, const bool MSBfirst, const uint16_t repeat, const uint8_t dutycycle)']]], + ['sendgicable_4131',['sendGICable',['../classIRsend.html#a61dd16bc150473bbfd998dada72b205f',1,'IRsend']]], + ['sendgoodweather_4132',['sendGoodweather',['../classIRsend.html#a8e2d98ae5c39ee07a61f08facecbaa1e',1,'IRsend']]], + ['sendgree_4133',['sendGree',['../classIRsend.html#aca81ea348ceb6b0c9e62073b57bc0b17',1,'IRsend::sendGree(const uint64_t data, const uint16_t nbits=kGreeBits, const uint16_t repeat=kGreeDefaultRepeat)'],['../classIRsend.html#af788e7d9a2ad2483313434f9b5196753',1,'IRsend::sendGree(const uint8_t data[], const uint16_t nbytes=kGreeStateLength, const uint16_t repeat=kGreeDefaultRepeat)']]], + ['sendhaierac_4134',['sendHaierAC',['../classIRsend.html#a6b4b9144d56dda302f5b321f1c5017ff',1,'IRsend']]], + ['sendhaieracyrw02_4135',['sendHaierACYRW02',['../classIRsend.html#a6aa1c1a6880872c87a46e4e0ead5d9b0',1,'IRsend']]], + ['sendhitachiac_4136',['sendHitachiAC',['../classIRsend.html#a8e6079b8b1b69ad7d7f8d05c492becbe',1,'IRsend']]], + ['sendhitachiac1_4137',['sendHitachiAC1',['../classIRsend.html#a5be9a87ce052e4f056766919247e0b22',1,'IRsend']]], + ['sendhitachiac2_4138',['sendHitachiAC2',['../classIRsend.html#a451b1913608a4ba8c26d9af8c85d16f1',1,'IRsend']]], + ['sendhitachiac3_4139',['sendHitachiAc3',['../classIRsend.html#aec7e67f4292622521b5a0a8cfdd21d84',1,'IRsend']]], + ['sendhitachiac344_4140',['sendHitachiAc344',['../classIRsend.html#a5fb28d54f2832651d992450673d05c01',1,'IRsend']]], + ['sendhitachiac424_4141',['sendHitachiAc424',['../classIRsend.html#a2a9676de30bb868b313cc9c30025f790',1,'IRsend']]], + ['sendinax_4142',['sendInax',['../classIRsend.html#a5fa5ff62276d9d680fb1255cc8b99eec',1,'IRsend']]], + ['sendjvc_4143',['sendJVC',['../classIRsend.html#aaa10c899768a5b4cdb1a7913d06141ca',1,'IRsend']]], + ['sendkelvinator_4144',['sendKelvinator',['../classIRsend.html#a8cba9df982fc91f895196d61d2e65b0e',1,'IRsend']]], + ['sendlasertag_4145',['sendLasertag',['../classIRsend.html#a55a79f9727590044751f291a4df83892',1,'IRsend']]], + ['sendlegopf_4146',['sendLegoPf',['../classIRsend.html#a4e38273aeacf01873a013c02d41a44e4',1,'IRsend']]], + ['sendlg_4147',['sendLG',['../classIRsend.html#a079a84c82f360d6d55fde5c27634f51c',1,'IRsend']]], + ['sendlg2_4148',['sendLG2',['../classIRsend.html#a5b6be1ceac8a4bc4ef55dc12eb060531',1,'IRsend']]], + ['sendlutron_4149',['sendLutron',['../classIRsend.html#a85f2a98255d3af7b7407c082ea7b7c16',1,'IRsend']]], + ['sendmagiquest_4150',['sendMagiQuest',['../classIRsend.html#af1d0e9ec0f735fc5fb9011d4f4cb8327',1,'IRsend']]], + ['sendmanchester_4151',['sendManchester',['../classIRsend.html#a7862231cbb1d50f42996c25e2f05b93e',1,'IRsend']]], + ['sendmanchesterdata_4152',['sendManchesterData',['../classIRsend.html#aa76aa33785827c1278eb57d1c15236f8',1,'IRsend']]], + ['sendmidea_4153',['sendMidea',['../classIRsend.html#a37d91b3a77b36509abdc53e2fec20a67',1,'IRsend']]], + ['sendmidea24_4154',['sendMidea24',['../classIRsend.html#a103d79e8df7954e9ab6284fa9f3daf02',1,'IRsend']]], + ['sendmitsubishi_4155',['sendMitsubishi',['../classIRsend.html#a59e8941a25c5c0bbc839fba5b1a22813',1,'IRsend']]], + ['sendmitsubishi112_4156',['sendMitsubishi112',['../classIRsend.html#a0a55e688c6aad015494168f25eb337b5',1,'IRsend']]], + ['sendmitsubishi136_4157',['sendMitsubishi136',['../classIRsend.html#a988a8b7dda3563977d537d6ac448ebc8',1,'IRsend']]], + ['sendmitsubishi2_4158',['sendMitsubishi2',['../classIRsend.html#ac54e50a6819f5c39e060891f1f6ea0f2',1,'IRsend']]], + ['sendmitsubishiac_4159',['sendMitsubishiAC',['../classIRsend.html#a3600527a82f9f22387c9f16ae51fb06f',1,'IRsend']]], + ['sendmitsubishiheavy152_4160',['sendMitsubishiHeavy152',['../classIRsend.html#ae1cffc4882c63f192c231397d19a4032',1,'IRsend']]], + ['sendmitsubishiheavy88_4161',['sendMitsubishiHeavy88',['../classIRsend.html#afaf4fd0c3dabd1bd6f8fe421294c5063',1,'IRsend']]], + ['sendmultibrackets_4162',['sendMultibrackets',['../classIRsend.html#a9026d42480b85270e560e122b8be3b6c',1,'IRsend']]], + ['sendmwm_4163',['sendMWM',['../classIRsend.html#a98301801daf929ec8ce022987ae394f2',1,'IRsend']]], + ['sendnec_4164',['sendNEC',['../classIRsend.html#a324c9e455c0bae51ebe9bc07e915c043',1,'IRsend']]], + ['sendneoclima_4165',['sendNeoclima',['../classIRsend.html#a71e1b5e780851210465bbf061b9c095b',1,'IRsend']]], + ['sendnikai_4166',['sendNikai',['../classIRsend.html#a693e6616b81509cf27d1345c140acc96',1,'IRsend']]], + ['sendoff_4167',['sendOff',['../classIRSamsungAc.html#a96e2ae87f3ffcf1ad812f256f31e4898',1,'IRSamsungAc']]], + ['sendon_4168',['sendOn',['../classIRSamsungAc.html#a7e6980c829dfd143d4d19abaf5d65678',1,'IRSamsungAc']]], + ['sendpanasonic_4169',['sendPanasonic',['../classIRsend.html#a92192475f89b19cfdf7fd0416a263145',1,'IRsend']]], + ['sendpanasonic64_4170',['sendPanasonic64',['../classIRsend.html#adc4fd287f3546f7ff0b67e177a42b560',1,'IRsend']]], + ['sendpanasonicac_4171',['sendPanasonicAC',['../classIRsend.html#a10a3c387a328dbb11733a251f4db7614',1,'IRsend']]], + ['sendpioneer_4172',['sendPioneer',['../classIRsend.html#a11f099f3768a659d1f996589cea8a313',1,'IRsend']]], + ['sendpronto_4173',['sendPronto',['../classIRsend.html#a0b349351e2ba19f87e6b01cde7e67c49',1,'IRsend']]], + ['sendraw_4174',['sendRaw',['../classIRsend.html#a2b9b84f828918f933bd1764d113b53f8',1,'IRsend']]], + ['sendrc5_4175',['sendRC5',['../classIRsend.html#a2bd2ccb27ecd57e14b36f76d82af308a',1,'IRsend']]], + ['sendrc6_4176',['sendRC6',['../classIRsend.html#a2192a95e0d162f9b1775fc2a47f65c37',1,'IRsend']]], + ['sendrcmm_4177',['sendRCMM',['../classIRsend.html#a3cafe475a58234a0d3aa655a2464be75',1,'IRsend']]], + ['sendsamsung_4178',['sendSAMSUNG',['../classIRsend.html#a5252dd159aad713c099de6728ac56d81',1,'IRsend']]], + ['sendsamsung36_4179',['sendSamsung36',['../classIRsend.html#ab5dcd4ec5ddb0b0351870ddf54e5ba66',1,'IRsend']]], + ['sendsamsungac_4180',['sendSamsungAC',['../classIRsend.html#a2773d251da1d35b964810c8cc4cb438b',1,'IRsend']]], + ['sendsanyolc7461_4181',['sendSanyoLC7461',['../classIRsend.html#aa23e51a97a0ec1907d22623fed6dd223',1,'IRsend']]], + ['sendsharp_4182',['sendSharp',['../classIRsend.html#a801ae78ac5a72116c566c4ac5f99c6bd',1,'IRsend']]], + ['sendsharpac_4183',['sendSharpAc',['../classIRsend.html#a438e4c9d50e62da7d772d8d638728213',1,'IRsend']]], + ['sendsharpraw_4184',['sendSharpRaw',['../classIRsend.html#aa1f12fd537ca8c21c183ee41d17a3afc',1,'IRsend']]], + ['sendsherwood_4185',['sendSherwood',['../classIRsend.html#afb3a89acfb868c92a997a3000e70c6e8',1,'IRsend']]], + ['sendsony_4186',['sendSony',['../classIRsend.html#a02bb64503474a0841c51664cf4668d85',1,'IRsend']]], + ['sendsony38_4187',['sendSony38',['../classIRsend.html#a558442f49b32453f0fb987c29e1ec6d3',1,'IRsend']]], + ['sendsymphony_4188',['sendSymphony',['../classIRsend.html#a1f1d5a30660ab0061f64d559d4916d4e',1,'IRsend']]], + ['sendtcl112ac_4189',['sendTcl112Ac',['../classIRsend.html#a2dedce2841e4a6445a98f03393fce823',1,'IRsend']]], + ['sendteco_4190',['sendTeco',['../classIRsend.html#ac6300f977fe94119813481ba682ce33f',1,'IRsend']]], + ['sendtoshibaac_4191',['sendToshibaAC',['../classIRsend.html#a4ef8e028135536dc1f5a63be85ef7d49',1,'IRsend']]], + ['sendtrotec_4192',['sendTrotec',['../classIRsend.html#a135796327b5db127473f4d198e663c00',1,'IRsend']]], + ['sendvestelac_4193',['sendVestelAc',['../classIRsend.html#a129a40f9d344cb0fadfd4cca53ca6b44',1,'IRsend']]], + ['sendwhirlpoolac_4194',['sendWhirlpoolAC',['../classIRsend.html#aa440a50000a259072f93ad6c0e42ec22',1,'IRsend']]], + ['sendwhynter_4195',['sendWhynter',['../classIRsend.html#a07188366deed3dd902cba80a711cf220',1,'IRsend']]], + ['sendzepeal_4196',['sendZepeal',['../classIRsend.html#a9bcba8bbac41d679b5b930e67d3e1b7f',1,'IRsend']]], + ['serialprintuint64_4197',['serialPrintUint64',['../IRutils_8cpp.html#ad2b0a4b9a1a7fca3d5f5afc14b682433',1,'serialPrintUint64(uint64_t input, uint8_t base): IRutils.cpp'],['../IRutils_8h.html#a315d5f05fb572564025bc9ce9b820243',1,'serialPrintUint64(uint64_t input, uint8_t base=10): IRutils.cpp']]], + ['set3d_4198',['set3D',['../classIRMitsubishiHeavy152Ac.html#ab22654d492a4b0e82efcd0c96fc9bbe3',1,'IRMitsubishiHeavy152Ac::set3D()'],['../classIRMitsubishiHeavy88Ac.html#ae0b7eac743a8de6852722f067e010ba7',1,'IRMitsubishiHeavy88Ac::set3D()']]], + ['set8cheat_4199',['set8CHeat',['../classIRNeoclimaAc.html#a3176c5fe3251bd6a31a3a0ddc2c294be',1,'IRNeoclimaAc']]], + ['setauto_4200',['setAuto',['../classIRVestelAc.html#a2509eed2e0d7b23595bbe6dd7df17d74',1,'IRVestelAc']]], + ['setbeep_4201',['setBeep',['../classIRDaikin2.html#a4c0588887a45403a0a9f2cf95f847889',1,'IRDaikin2::setBeep()'],['../classIRSamsungAc.html#a092ccbea031dd4be747076530117649d',1,'IRSamsungAc::setBeep()']]], + ['setbit_4202',['setBit',['../namespaceirutils.html#a316301577d2ff338bfba6605df2cc46b',1,'irutils::setBit(const uint64_t data, const uint8_t position, const bool on, const uint8_t size)'],['../namespaceirutils.html#a2e9e858b490fa3328b4c5bd01adedb8c',1,'irutils::setBit(const uint8_t data, const uint8_t position, const bool on)'],['../namespaceirutils.html#ac1b3de6e733d9c4d614a8239f5bd3220',1,'irutils::setBit(uint8_t *const data, const uint8_t position, const bool on)'],['../namespaceirutils.html#a86bbcf05c1601712b1d587b87035f09b',1,'irutils::setBit(uint32_t *const data, const uint8_t position, const bool on)'],['../namespaceirutils.html#a9e7814e2274f02df0dac0106c293c487',1,'irutils::setBit(uint64_t *const data, const uint8_t position, const bool on)']]], + ['setbits_4203',['setBits',['../namespaceirutils.html#ab4f5e3eb26e111909ddc93a8b018ba78',1,'irutils::setBits(uint8_t *const dst, const uint8_t offset, const uint8_t nbits, const uint8_t data)'],['../namespaceirutils.html#a3fd8b18a76f0ae8f730b4de55fc9486e',1,'irutils::setBits(uint32_t *const dst, const uint8_t offset, const uint8_t nbits, const uint32_t data)'],['../namespaceirutils.html#a4dfb0984a9ea38602805987a7845839c',1,'irutils::setBits(uint64_t *const dst, const uint8_t offset, const uint8_t nbits, const uint64_t data)']]], + ['setboost_4204',['setBoost',['../classIRDelonghiAc.html#a827d1e43e9252657147226aa3f8e4eb8',1,'IRDelonghiAc']]], + ['setbreeze_4205',['setBreeze',['../classIRSamsungAc.html#a310a73f15a0274fbaf15b981abaae592',1,'IRSamsungAc']]], + ['setbutton_4206',['setButton',['../classIRHaierACYRW02.html#aa0f1561e2446f6231f722581f5bae34d',1,'IRHaierACYRW02::setButton()'],['../classIRHitachiAc424.html#af4ded7ea8aa94271d5135eebd3bb80a8',1,'IRHitachiAc424::setButton()'],['../classIRNeoclimaAc.html#a7e2e6e646411b4f5ea3c1ce1e944581c',1,'IRNeoclimaAc::setButton()']]], + ['setclean_4207',['setClean',['../classIRCoolixAC.html#a0087ac58749ef946632fbb5a8b41fe0d',1,'IRCoolixAC::setClean()'],['../classIRDaikin2.html#a21e09b867710a225d5cf53006f723326',1,'IRDaikin2::setClean()'],['../classIRElectraAc.html#a4aa44fc40196067469dfa8a722e33115',1,'IRElectraAc::setClean()'],['../classIRFujitsuAC.html#a7f6f18ea39bf28717cb65ff348b1b2f5',1,'IRFujitsuAC::setClean()'],['../classIRMitsubishiHeavy152Ac.html#a11678e7eb906414770938f6efce266f1',1,'IRMitsubishiHeavy152Ac::setClean()'],['../classIRMitsubishiHeavy88Ac.html#a65968304e4aaf025dfefc49d5d777cbd',1,'IRMitsubishiHeavy88Ac::setClean()'],['../classIRSamsungAc.html#a911ca57dfb0e6787cba330e8d49b2496',1,'IRSamsungAc::setClean()'],['../classIRSharpAc.html#ace6e7b98496a594031809fe8a535c429',1,'IRSharpAc::setClean()']]], + ['setclock_4208',['setClock',['../classIRDaikin128.html#aa9928ac010ec79ddab4f551eedf2f5d9',1,'IRDaikin128::setClock()'],['../classIRDaikin64.html#a655f1cec5e28f79e5718573678c535ec',1,'IRDaikin64::setClock()'],['../classIRMitsubishiAC.html#a7abe34adf36bdd1a65a17f56ee8af1f6',1,'IRMitsubishiAC::setClock()'],['../classIRPanasonicAc.html#a3f76c6aca94f52c227c2e259512fd101',1,'IRPanasonicAc::setClock()'],['../classIRWhirlpoolAc.html#aab09aae7de733414bf480c3df22b83f8',1,'IRWhirlpoolAc::setClock()']]], + ['setcmd_4209',['setCmd',['../classIRFujitsuAC.html#a7579944c11b3d31bb069303926307617',1,'IRFujitsuAC']]], + ['setcomfort_4210',['setComfort',['../classIRDaikinESP.html#aaa15c0be7ffb8e845a03d193583a58d1',1,'IRDaikinESP::setComfort()'],['../classIRDaikin152.html#a95de2dc0a90fe4212cb60973b9430486',1,'IRDaikin152::setComfort()']]], + ['setcommand_4211',['setCommand',['../classIRGoodweatherAc.html#a4e266f42b7a82c49208e2acc7813e07b',1,'IRGoodweatherAc::setCommand()'],['../classIRHaierAC.html#ade34c951e72a794c2ff7fa0d1595d68f',1,'IRHaierAC::setCommand()'],['../classIRWhirlpoolAc.html#aaea26b1388489dff70a98fde1e6185be',1,'IRWhirlpoolAc::setCommand()']]], + ['setcurrentday_4212',['setCurrentDay',['../classIRDaikinESP.html#a5465b9857fd73b82362f766368717d16',1,'IRDaikinESP']]], + ['setcurrenttime_4213',['setCurrentTime',['../classIRDaikinESP.html#ae6559268982ae0968358a885c7dbba6e',1,'IRDaikinESP::setCurrentTime()'],['../classIRDaikin2.html#a8b32b1b9a87c9b671af6aeedb709d520',1,'IRDaikin2::setCurrentTime()']]], + ['setcurrtime_4214',['setCurrTime',['../classIRHaierAC.html#a53500ebdec058d27396e5906a572fe15',1,'IRHaierAC']]], + ['setdisplay_4215',['setDisplay',['../classIRSamsungAc.html#ad20199bed3a01208ec694b9d4eb7ef98',1,'IRSamsungAc']]], + ['setdisplaytempsource_4216',['setDisplayTempSource',['../classIRGreeAC.html#a1d073c31ea169d0e5cf33c8592982035',1,'IRGreeAC']]], + ['setecono_4217',['setEcono',['../classIRCoronaAc.html#abb5624317fff60674bed410be3a3fa52',1,'IRCoronaAc::setEcono()'],['../classIRDaikinESP.html#a12129aedd6320522a9b6e811e347089c',1,'IRDaikinESP::setEcono()'],['../classIRDaikin2.html#a42a44a6cefa6bf6f45148d39c216ebc0',1,'IRDaikin2::setEcono()'],['../classIRDaikin128.html#a07fb5289ee476e0335fec4845254b7ce',1,'IRDaikin128::setEcono()'],['../classIRDaikin152.html#a8062d16f7aefb7586e3d3bdfea8755b4',1,'IRDaikin152::setEcono()'],['../classIRMitsubishiHeavy152Ac.html#ab3964219ee3c0c5112bb38c892a01784',1,'IRMitsubishiHeavy152Ac::setEcono()'],['../classIRMitsubishiHeavy88Ac.html#a7612448f1cceaa6aeee1697f51adaf43',1,'IRMitsubishiHeavy88Ac::setEcono()'],['../classIRTcl112Ac.html#a48ac7acfa8fed8e9da39907282f4f377',1,'IRTcl112Ac::setEcono()']]], + ['seteconotoggle_4218',['setEconoToggle',['../classIRSharpAc.html#ae3495676b8bffecba5c56fbf1ab9ee4d',1,'IRSharpAc']]], + ['seteye_4219',['setEye',['../classIRDaikin2.html#a5ba8e5d5dd4aba45a90de1d450a7a88b',1,'IRDaikin2::setEye()'],['../classIRNeoclimaAc.html#aaf433cab785db382c55a420e68e7d7ec',1,'IRNeoclimaAc::setEye()']]], + ['seteyeauto_4220',['setEyeAuto',['../classIRDaikin2.html#a975c2fdb261d6d2b6c8e196fbd074899',1,'IRDaikin2']]], + ['setfan_4221',['setFan',['../classIRAmcorAc.html#acf26fc65363e2734e4dc6eb562812553',1,'IRAmcorAc::setFan()'],['../classIRArgoAC.html#a8144f003628e128ec6630aef49ed5cb5',1,'IRArgoAC::setFan()'],['../classIRCarrierAc64.html#a312027468b508e9d38dd9e23ee99f9e4',1,'IRCarrierAc64::setFan()'],['../classIRCoolixAC.html#aff4189cb1000c6db7d88624fbadbe0cb',1,'IRCoolixAC::setFan()'],['../classIRCoronaAc.html#aa4da12502bf85438846bdde56391ee5c',1,'IRCoronaAc::setFan()'],['../classIRDaikinESP.html#a1f191f45e473482a86aad9a1c879e083',1,'IRDaikinESP::setFan()'],['../classIRDaikin2.html#af9f3ddbdd1f1d5d99c84846b73c5daa1',1,'IRDaikin2::setFan()'],['../classIRDaikin216.html#a8fadfb1e61deca74a2d1b9c1d5ae62e1',1,'IRDaikin216::setFan()'],['../classIRDaikin160.html#a7f507c64dc7a9fa1e9391e9e8473af1b',1,'IRDaikin160::setFan()'],['../classIRDaikin176.html#a050a9943dc7d8289472e6b9dbdcb06c1',1,'IRDaikin176::setFan()'],['../classIRDaikin128.html#a0495834250e97e7831e9906ab548fe44',1,'IRDaikin128::setFan()'],['../classIRDaikin152.html#a385a4f65dfccd0a9e94be06ae60c5343',1,'IRDaikin152::setFan()'],['../classIRDaikin64.html#af39206f90b99fd5ee340923b196368b8',1,'IRDaikin64::setFan()'],['../classIRDelonghiAc.html#a440f1e0efa18c6b1a8e18e0a97fbfb79',1,'IRDelonghiAc::setFan()'],['../classIRElectraAc.html#aa338ce18cafaf9c7b9aa3385e681bbe7',1,'IRElectraAc::setFan()'],['../classIRGoodweatherAc.html#af8cf9ba59af548677e586cd59e8a6cc2',1,'IRGoodweatherAc::setFan()'],['../classIRGreeAC.html#a9bb570e71df5002298505d49473e6bac',1,'IRGreeAC::setFan()'],['../classIRHaierAC.html#a42ee1c5889f07bf7615c8f853bca2261',1,'IRHaierAC::setFan()'],['../classIRHaierACYRW02.html#ae9c3a7bffc08d9d5204616823f709889',1,'IRHaierACYRW02::setFan()'],['../classIRHitachiAc.html#a0760b07502b976880ee8499dc6fa61ff',1,'IRHitachiAc::setFan()'],['../classIRHitachiAc1.html#a7294dc1324877d4a64f7b4373d97d745',1,'IRHitachiAc1::setFan()'],['../classIRHitachiAc424.html#afd69bcff56224f39af92fc2d334b67bb',1,'IRHitachiAc424::setFan()'],['../classIRKelvinatorAC.html#af08e94be9699983c0087c9b059aad319',1,'IRKelvinatorAC::setFan()'],['../classIRLgAc.html#a0f1901a21ffb93641d3481417d74bb4e',1,'IRLgAc::setFan()'],['../classIRMideaAC.html#a546eeca4eea015899a5ad9f5d1c6fafb',1,'IRMideaAC::setFan()'],['../classIRMitsubishiAC.html#a4e88e50b2eddd0233aade5c1bf7819f1',1,'IRMitsubishiAC::setFan()'],['../classIRMitsubishi136.html#a2aa62126614f734ec3d1b7b3cb653e9e',1,'IRMitsubishi136::setFan()'],['../classIRMitsubishi112.html#ab681e78572c869a8c57079a660fe1505',1,'IRMitsubishi112::setFan()'],['../classIRMitsubishiHeavy152Ac.html#ac8d8eceba935aa626cb229d1c41081bb',1,'IRMitsubishiHeavy152Ac::setFan()'],['../classIRMitsubishiHeavy88Ac.html#a4f8c934a82091547c36da512329e76d7',1,'IRMitsubishiHeavy88Ac::setFan()'],['../classIRNeoclimaAc.html#a8db9d2d446e8614b2fc4583a454d7cee',1,'IRNeoclimaAc::setFan()'],['../classIRPanasonicAc.html#a8d77292226f55601c30ee53252ba83cd',1,'IRPanasonicAc::setFan()'],['../classIRSamsungAc.html#a6c7571e14fe6629348273a2b49a0a824',1,'IRSamsungAc::setFan()'],['../classIRSharpAc.html#a5138068f8ba4c51939ff3bb14f0aae45',1,'IRSharpAc::setFan()'],['../classIRTcl112Ac.html#a0dab8ad6675c4ec122d0d7e28a557cba',1,'IRTcl112Ac::setFan()'],['../classIRTecoAc.html#afda9a33ca450568f968217bedc9ad7f2',1,'IRTecoAc::setFan()'],['../classIRToshibaAC.html#a020ba3e95c607f52ce091193fc5825fc',1,'IRToshibaAC::setFan()'],['../classIRVestelAc.html#af53dfd0a0372c878b6ba2ca1cfc21ccd',1,'IRVestelAc::setFan()'],['../classIRWhirlpoolAc.html#a8da28ee25fdc91d55a9f6ab5dab3af81',1,'IRWhirlpoolAc::setFan()']]], + ['setfanspeed_4222',['setFanSpeed',['../classIRFujitsuAC.html#af0fc10ec0a606434477cb41c60eb49e5',1,'IRFujitsuAC']]], + ['setfilter_4223',['setFilter',['../classIRFujitsuAC.html#aec0048efe87f60406c76ad6bc3ffbc61',1,'IRFujitsuAC::setFilter()'],['../classIRMitsubishiHeavy152Ac.html#aaf76ac48228d3a7b8490e684407e65b1',1,'IRMitsubishiHeavy152Ac::setFilter()']]], + ['setflap_4224',['setFlap',['../classIRArgoAC.html#a55a6402ffc3fe7fb59775050901416ca',1,'IRArgoAC']]], + ['setfresh_4225',['setFresh',['../classIRNeoclimaAc.html#a6354d8b902ffc1e7c044a61185504404',1,'IRNeoclimaAc']]], + ['setfreshair_4226',['setFreshAir',['../classIRDaikin2.html#a6e0596c7b9f9b43b8d241340ae08e886',1,'IRDaikin2']]], + ['setfreshairhigh_4227',['setFreshAirHigh',['../classIRDaikin2.html#a044471f2298a1942bcc2f859f9459924',1,'IRDaikin2']]], + ['sethealth_4228',['setHealth',['../classIRHaierAC.html#a48c9ae91809d63156eeb3889f2e908f4',1,'IRHaierAC::setHealth()'],['../classIRHaierACYRW02.html#a79673650a2285f029a35ab69edeb0e74',1,'IRHaierACYRW02::setHealth()'],['../classIRTcl112Ac.html#a28ed509977d8642174bc6c9aa97ae1c3',1,'IRTcl112Ac::setHealth()']]], + ['sethold_4229',['setHold',['../classIRNeoclimaAc.html#a2eb4e0a2ff39ceb1b6b571998d91b31e',1,'IRNeoclimaAc']]], + ['sethumid_4230',['setHumid',['../classIRTecoAc.html#a4ab07a7c95f34d3b292926c719aeb303',1,'IRTecoAc']]], + ['setifeel_4231',['setIFeel',['../classIRGreeAC.html#a68a670156a5e0a91a8a3cf9225263e0b',1,'IRGreeAC::setIFeel()'],['../classIRArgoAC.html#ae59f903855961441b676b7f662602554',1,'IRArgoAC::setiFeel()']]], + ['setinvertedstates_4232',['setInvertedStates',['../classIRHitachiAc424.html#ad18528cf83e863b98cb1609eec970ac5',1,'IRHitachiAc424::setInvertedStates()'],['../classIRHitachiAc3.html#af37c710449cd32df4753509749e31cad',1,'IRHitachiAc3::setInvertedStates()']]], + ['setion_4233',['setIon',['../classIRNeoclimaAc.html#a504fc5e371746fda8e7eb7cc0abf137a',1,'IRNeoclimaAc::setIon()'],['../classIRPanasonicAc.html#a5a1c4f5b9eb7a3a1a81a6acd0491c3cd',1,'IRPanasonicAc::setIon()'],['../classIRSamsungAc.html#aeee65ca6d2100635a517077f01053bed',1,'IRSamsungAc::setIon()'],['../classIRSharpAc.html#af6a390362bc5b40eecc6564b16b3379b',1,'IRSharpAc::setIon()'],['../classIRVestelAc.html#acf860da68a15d463dab437a808c9c8c6',1,'IRVestelAc::setIon()']]], + ['setionfilter_4234',['setIonFilter',['../classIRKelvinatorAC.html#a6a219c481ddc21d93028f5c799c25883',1,'IRKelvinatorAC']]], + ['setled_4235',['setLed',['../classIRCoolixAC.html#a3132f99cffa108129dff64a0b68bd614',1,'IRCoolixAC']]], + ['setlight_4236',['setLight',['../classIRDaikin2.html#a7ecadb3335e9b22729a89b4c41456242',1,'IRDaikin2::setLight()'],['../classIRGoodweatherAc.html#a3f149ff426b236ba9f90659a6daf4a9c',1,'IRGoodweatherAc::setLight()'],['../classIRGreeAC.html#a702bbba38e11bb8f3428ee707fc82311',1,'IRGreeAC::setLight()'],['../classIRKelvinatorAC.html#a870890c2bc8510f8f7351ca21db8d855',1,'IRKelvinatorAC::setLight()'],['../classIRNeoclimaAc.html#a1d7a6ec6d319544bee907a23a1d14084',1,'IRNeoclimaAc::setLight()'],['../classIRTcl112Ac.html#a7dec5b0559f996df8a4fc259ab6012e9',1,'IRTcl112Ac::setLight()'],['../classIRTecoAc.html#a25d97c1e7be31d80a4ffad0026e633d7',1,'IRTecoAc::setLight()'],['../classIRWhirlpoolAc.html#a70b4c0467a7747f9cf9e106af1025771',1,'IRWhirlpoolAc::setLight()']]], + ['setlighttoggle_4237',['setLightToggle',['../classIRDaikin128.html#a6361c789141ccecb729c104e71ddcc41',1,'IRDaikin128::setLightToggle()'],['../classIRElectraAc.html#a15373982641e36f4b68258368700be7d',1,'IRElectraAc::setLightToggle()']]], + ['setmax_4238',['setMax',['../classIRAmcorAc.html#a1250c6b106378286d9db013296c9b16f',1,'IRAmcorAc::setMax()'],['../classIRArgoAC.html#a909c1f74e9452d0e19fc3ffd28b1b81b',1,'IRArgoAC::setMax()']]], + ['setmode_4239',['setMode',['../classIRAmcorAc.html#afa9c2d080ed5c4c7bc64eb13a07eab68',1,'IRAmcorAc::setMode()'],['../classIRArgoAC.html#a8575f0ef967b09308ed6a453857e65c7',1,'IRArgoAC::setMode()'],['../classIRCarrierAc64.html#ae462eeec49ff91358f1b9921750ee36d',1,'IRCarrierAc64::setMode()'],['../classIRCoolixAC.html#a5c0094d32aca6a5323f4dc72a03f02e9',1,'IRCoolixAC::setMode()'],['../classIRCoronaAc.html#aedeeedd176c89e5b7b650a4311e712be',1,'IRCoronaAc::setMode()'],['../classIRDaikinESP.html#af0f463201c877d33fa8680053dda7551',1,'IRDaikinESP::setMode()'],['../classIRDaikin2.html#a24ef3b53f22fe3557ed2dbc98a5bc6d2',1,'IRDaikin2::setMode()'],['../classIRDaikin216.html#a1d0dfce75ac95df9125b2cfe7c955080',1,'IRDaikin216::setMode()'],['../classIRDaikin160.html#a48e6fff63fd8b894c649fb495a467faa',1,'IRDaikin160::setMode()'],['../classIRDaikin176.html#a7ce82479f5ae2721baae8119b711c112',1,'IRDaikin176::setMode()'],['../classIRDaikin128.html#a9693e9931449f39253ca9102ac5cbfe9',1,'IRDaikin128::setMode()'],['../classIRDaikin152.html#aad0a46c751b73792282d6614103f57d8',1,'IRDaikin152::setMode()'],['../classIRDaikin64.html#a04dff0d273457a7bc3f3e0e1af4f7cd9',1,'IRDaikin64::setMode()'],['../classIRDelonghiAc.html#a62392c26321f038a84d99d54039bcfae',1,'IRDelonghiAc::setMode()'],['../classIRElectraAc.html#a911b7410fd2f29464c1505e183c04c5d',1,'IRElectraAc::setMode()'],['../classIRFujitsuAC.html#ac125c320f9794aae931bc59ba332a4a8',1,'IRFujitsuAC::setMode()'],['../classIRGoodweatherAc.html#a8eed6b70b7b1c2e8a9620db7462e1fb5',1,'IRGoodweatherAc::setMode()'],['../classIRGreeAC.html#a9d9dbd416e3dc270fcfda620b3bb4fe2',1,'IRGreeAC::setMode()'],['../classIRHaierAC.html#a3ad0317f2fd4f57d8ce61353ab3e48c7',1,'IRHaierAC::setMode()'],['../classIRHaierACYRW02.html#ae762c5f5422b4af612fa00f7c26452ed',1,'IRHaierACYRW02::setMode()'],['../classIRHitachiAc.html#a208f73a42484a1555145b41849e8c51f',1,'IRHitachiAc::setMode()'],['../classIRHitachiAc1.html#a1f3ced601e1131b70f840820ecb3feaa',1,'IRHitachiAc1::setMode()'],['../classIRHitachiAc424.html#a373a51d207674e35e00762b057f73cd5',1,'IRHitachiAc424::setMode()'],['../classIRKelvinatorAC.html#af55cc77892bc960587037c337b90d1bc',1,'IRKelvinatorAC::setMode()'],['../classIRLgAc.html#a5e1b21d9121c6bf6507f615f470b5890',1,'IRLgAc::setMode()'],['../classIRMideaAC.html#a3b92f25a82741ae404e8f9af8dbca3a8',1,'IRMideaAC::setMode()'],['../classIRMitsubishiAC.html#a2b4e2f00ee5a385172b13e8d9858ac0b',1,'IRMitsubishiAC::setMode()'],['../classIRMitsubishi136.html#aaef2ed81bdeb183995e2342c2ca17a8b',1,'IRMitsubishi136::setMode()'],['../classIRMitsubishi112.html#a0c1434e1d8dd513007400042324e868e',1,'IRMitsubishi112::setMode()'],['../classIRMitsubishiHeavy152Ac.html#a5a68388f337d7ba80289359903a1d01d',1,'IRMitsubishiHeavy152Ac::setMode()'],['../classIRMitsubishiHeavy88Ac.html#a1802cc8a382d6161b83f8947137d941d',1,'IRMitsubishiHeavy88Ac::setMode()'],['../classIRNeoclimaAc.html#adabd715c4a2ec34dd88330b97a1f0ecd',1,'IRNeoclimaAc::setMode()'],['../classIRPanasonicAc.html#add025b64e736d5120abeb2564a2849a4',1,'IRPanasonicAc::setMode()'],['../classIRSamsungAc.html#a708d9c6c91d774d6eeadbc0bd7f350af',1,'IRSamsungAc::setMode()'],['../classIRSharpAc.html#ab51c207de90391cb7190e3ec95adc16e',1,'IRSharpAc::setMode()'],['../classIRTcl112Ac.html#a1a050c9b238691ba6d4764beeb788778',1,'IRTcl112Ac::setMode()'],['../classIRTecoAc.html#aba404540b723fa4687a4fda954221130',1,'IRTecoAc::setMode()'],['../classIRToshibaAC.html#aa001cddc464d6cbcc342e5e4c7af13ff',1,'IRToshibaAC::setMode()'],['../classIRTrotecESP.html#a5d34e8d1e1be765e51cbfb6874482997',1,'IRTrotecESP::setMode()'],['../classIRVestelAc.html#a470e14ab5623386c0fa2b02fd15ea1d8',1,'IRVestelAc::setMode()'],['../classIRWhirlpoolAc.html#ab09869929f5cc1fd0cc5dede93bba1c5',1,'IRWhirlpoolAc::setMode()']]], + ['setmodel_4240',['setModel',['../classIRFujitsuAC.html#a5393698000d8becf33ff332b32b97c73',1,'IRFujitsuAC::setModel()'],['../classIRGreeAC.html#a1075a08c30a2de97892e0842cb30e451',1,'IRGreeAC::setModel()'],['../classIRHitachiAc1.html#abb8c2c87e87f9d538f171e842c9d309a',1,'IRHitachiAc1::setModel()'],['../classIRLgAc.html#ae4b8758ecf10bd7e25ed401593692821',1,'IRLgAc::setModel()'],['../classIRPanasonicAc.html#a342531bfea3b05484de84e537bde390c',1,'IRPanasonicAc::setModel()'],['../classIRWhirlpoolAc.html#accfa1660ed792acc3cf48ff60d9570f0',1,'IRWhirlpoolAc::setModel()']]], + ['setmold_4241',['setMold',['../classIRDaikinESP.html#a1616d08c8fd3c628fc45a76c32743ac9',1,'IRDaikinESP::setMold()'],['../classIRDaikin2.html#ad53e046e545f3b6c5418dfbaf58653ca',1,'IRDaikin2::setMold()']]], + ['setnight_4242',['setNight',['../classIRArgoAC.html#a769dd3b538653940e41883848bc1e19c',1,'IRArgoAC::setNight()'],['../classIRMitsubishiHeavy152Ac.html#a6920a1aad327e2f347b09da12f11cf8c',1,'IRMitsubishiHeavy152Ac::setNight()']]], + ['setofftime_4243',['setOffTime',['../classIRDaikin64.html#a46a0b1e2438087ba557494b0b4fce4a5',1,'IRDaikin64']]], + ['setofftimeenabled_4244',['setOffTimeEnabled',['../classIRDaikin64.html#aea59ae39ddd0fc33a6941d0affceae9a',1,'IRDaikin64']]], + ['setofftimer_4245',['setOffTimer',['../classIRCarrierAc64.html#a92b1066e783db1bdffabfdc57699deef',1,'IRCarrierAc64::setOffTimer()'],['../classIRCoronaAc.html#a00f269b6389bf65d1816e80b835aa9b0',1,'IRCoronaAc::setOffTimer()'],['../classIRDaikin128.html#a30ca067676dfde963986e25c84616368',1,'IRDaikin128::setOffTimer()'],['../classIRDelonghiAc.html#a9602c652b10b06c6eeae0e6158c42c68',1,'IRDelonghiAc::setOffTimer()'],['../classIRHaierAC.html#aa16b36aa7ef07628343dbd2dfe5157a2',1,'IRHaierAC::setOffTimer()'],['../classIRHitachiAc1.html#a62e9c7b68e63d1791d79805f2bce99df',1,'IRHitachiAc1::setOffTimer()'],['../classIRPanasonicAc.html#a08e097f40cee6c614ec1a8de716222cf',1,'IRPanasonicAc::setOffTimer()'],['../classIRVestelAc.html#acc61cd785d2f668a86ecefb243d63549',1,'IRVestelAc::setOffTimer()'],['../classIRWhirlpoolAc.html#a69f3555c9b27f3cfd9167ed3239804b8',1,'IRWhirlpoolAc::setOffTimer()']]], + ['setofftimeractive_4246',['setOffTimerActive',['../classIRVestelAc.html#a8a023f5594b446f0c20f66c4ee584d8e',1,'IRVestelAc']]], + ['setofftimerenabled_4247',['setOffTimerEnabled',['../classIRDaikin128.html#aac8a178bdaf7de7a183991e710a9a9d8',1,'IRDaikin128::setOffTimerEnabled()'],['../classIRDelonghiAc.html#a5cf81c9864f3c3728d4dd65e4d9c49c8',1,'IRDelonghiAc::setOffTimerEnabled()']]], + ['setontime_4248',['setOnTime',['../classIRDaikin64.html#aaada482820a90492a933f368fafaebb7',1,'IRDaikin64']]], + ['setontimeenabled_4249',['setOnTimeEnabled',['../classIRDaikin64.html#a8e7a7c1f775f8ddf9d48a96915751c7a',1,'IRDaikin64']]], + ['setontimer_4250',['setOnTimer',['../classIRCarrierAc64.html#a9049a8d91200b878cc2a1b9b80a280ea',1,'IRCarrierAc64::setOnTimer()'],['../classIRCoronaAc.html#aae4142f45cc9c2b3e392b72cb404a2d8',1,'IRCoronaAc::setOnTimer()'],['../classIRDaikin128.html#a21773493eafae741b5716ac569eaf0a8',1,'IRDaikin128::setOnTimer()'],['../classIRDelonghiAc.html#a9a478f463a632893be7c4f5223c188ad',1,'IRDelonghiAc::setOnTimer()'],['../classIRHaierAC.html#aa5e95aa05749f6d35dd31b021fea2f5b',1,'IRHaierAC::setOnTimer()'],['../classIRHitachiAc1.html#a51ed6155f228628942ba08ea2ff5c547',1,'IRHitachiAc1::setOnTimer()'],['../classIRPanasonicAc.html#a51fdaa11e4e3f77189a94007a5acbec2',1,'IRPanasonicAc::setOnTimer()'],['../classIRVestelAc.html#af19bb7704326eb5688f2a2fa08e10ee2',1,'IRVestelAc::setOnTimer()'],['../classIRWhirlpoolAc.html#a1cb0e346e6f40b65b98a768df7fdace8',1,'IRWhirlpoolAc::setOnTimer()']]], + ['setontimeractive_4251',['setOnTimerActive',['../classIRVestelAc.html#a16ef4ecb7c76bef89b6e0ca36746d606',1,'IRVestelAc']]], + ['setontimerenabled_4252',['setOnTimerEnabled',['../classIRDaikin128.html#a07f693fac3de101c91c190e5e70edb57',1,'IRDaikin128::setOnTimerEnabled()'],['../classIRDelonghiAc.html#af6b956c273284e287093260039003362',1,'IRDelonghiAc::setOnTimerEnabled()']]], + ['setoutsidequiet_4253',['setOutsideQuiet',['../classIRFujitsuAC.html#a9a0533cba18739e52014307bf4b1ad07',1,'IRFujitsuAC']]], + ['setpower_4254',['setPower',['../classIRAmcorAc.html#a2ccfb2c2f0feb8a8cea9e10e30035988',1,'IRAmcorAc::setPower()'],['../classIRArgoAC.html#a991f73d84952c1d8ac86c579d1b01785',1,'IRArgoAC::setPower()'],['../classIRCarrierAc64.html#a8acf59cbf3b02381b5188324030b7727',1,'IRCarrierAc64::setPower()'],['../classIRCoolixAC.html#a41dc75b29e7a05eff5f16161cb9b3eeb',1,'IRCoolixAC::setPower()'],['../classIRCoronaAc.html#adc636402b51e0c78c4797aea5f80915d',1,'IRCoronaAc::setPower()'],['../classIRDaikinESP.html#aa0fb65d01bb203d17d923504ddd60984',1,'IRDaikinESP::setPower()'],['../classIRDaikin2.html#a3adfe1a80a702b7098ccd0e18225396e',1,'IRDaikin2::setPower()'],['../classIRDaikin216.html#a130a98bb2422a228977dea8a4e068ace',1,'IRDaikin216::setPower()'],['../classIRDaikin160.html#af1a800ef7494c49a868d01039f5c37e4',1,'IRDaikin160::setPower()'],['../classIRDaikin176.html#a58c755ba53d1f14a51b0c64ff4ef0669',1,'IRDaikin176::setPower()'],['../classIRDaikin152.html#a887f7340b9c3e7933f5d06bc5f59ee91',1,'IRDaikin152::setPower()'],['../classIRDelonghiAc.html#aa1ebbf63aa2331b87b95df9c5bdb41dc',1,'IRDelonghiAc::setPower()'],['../classIRElectraAc.html#abd04ffe9a77a97d4fafbcecd3a7949a4',1,'IRElectraAc::setPower()'],['../classIRFujitsuAC.html#a8d8211f20c8ec299e1fcb588a0846ac2',1,'IRFujitsuAC::setPower()'],['../classIRGoodweatherAc.html#ac49e30082777b10fe9edf6ec7bd76ea5',1,'IRGoodweatherAc::setPower()'],['../classIRGreeAC.html#a16b8c6af038752cd2b416cdcf9e2fb51',1,'IRGreeAC::setPower()'],['../classIRHaierACYRW02.html#a32e4a52cf31b43ad96ff3d8f0f390620',1,'IRHaierACYRW02::setPower()'],['../classIRHitachiAc.html#ad78a7176ded93735a296eefbf75cbc06',1,'IRHitachiAc::setPower()'],['../classIRHitachiAc1.html#a4dd034793018ea58d0cc32e7a47e8f35',1,'IRHitachiAc1::setPower()'],['../classIRHitachiAc424.html#a7b0b2e2c631d1bce2dd4677bb71e79b4',1,'IRHitachiAc424::setPower()'],['../classIRKelvinatorAC.html#a517a0193a9236a28a20d1760d7401efd',1,'IRKelvinatorAC::setPower()'],['../classIRLgAc.html#a175e6482fd1565d43906c527f911b59e',1,'IRLgAc::setPower()'],['../classIRMideaAC.html#ab8341f8d3d553d8b0ed9270cc15fc8ec',1,'IRMideaAC::setPower()'],['../classIRMitsubishiAC.html#a13f26de3c35b01470176b6fd9efda566',1,'IRMitsubishiAC::setPower()'],['../classIRMitsubishi136.html#a4bf52b3784faaca95ff97a09b8be322a',1,'IRMitsubishi136::setPower()'],['../classIRMitsubishi112.html#a0545da32a5048bc9d857ffb05767d3a6',1,'IRMitsubishi112::setPower()'],['../classIRMitsubishiHeavy152Ac.html#a08202752226ff3295eb8ccd637b0158b',1,'IRMitsubishiHeavy152Ac::setPower()'],['../classIRMitsubishiHeavy88Ac.html#ac2ee9dd82e84a3735e8a0c69e64cb02e',1,'IRMitsubishiHeavy88Ac::setPower()'],['../classIRNeoclimaAc.html#ac19bea3b79cdfc868bd137b0a70c0718',1,'IRNeoclimaAc::setPower()'],['../classIRPanasonicAc.html#ad60bf8a88d041f8e8ab3d728831ee8f3',1,'IRPanasonicAc::setPower()'],['../classIRSamsungAc.html#a4af21fa0dcbf5595386f67db676a443c',1,'IRSamsungAc::setPower()'],['../classIRSharpAc.html#a6b57a66878f125f86d2aed8bd7545000',1,'IRSharpAc::setPower()'],['../classIRTcl112Ac.html#ad2367d2481f94f14b9c4f7b378711b7e',1,'IRTcl112Ac::setPower()'],['../classIRTecoAc.html#a989e48a889b36ec36386a532c81872d9',1,'IRTecoAc::setPower()'],['../classIRToshibaAC.html#a100f01c014582e162f9fd287beb91dff',1,'IRToshibaAC::setPower()'],['../classIRTrotecESP.html#a0f3f5f5db367cb5a9adb936fada94fd5',1,'IRTrotecESP::setPower()'],['../classIRVestelAc.html#a01e06ff3916d4a14f9ca49f22918a47b',1,'IRVestelAc::setPower()']]], + ['setpowerbutton_4255',['setPowerButton',['../classIRCoronaAc.html#a518471d42a62863953c97334cad348be',1,'IRCoronaAc']]], + ['setpowerful_4256',['setPowerful',['../classIRDaikinESP.html#a4c0da54ee1639a3bf813cb3f3afee064',1,'IRDaikinESP::setPowerful()'],['../classIRDaikin2.html#a6538104cdcf1b55e480aaddd51116d9a',1,'IRDaikin2::setPowerful()'],['../classIRDaikin216.html#a5cb6e958f3b9789828738defe4d12c7b',1,'IRDaikin216::setPowerful()'],['../classIRDaikin128.html#aeb3aa5013b1746ed714146ca7f233119',1,'IRDaikin128::setPowerful()'],['../classIRDaikin152.html#a6477111b5662146e937c10cf02423e10',1,'IRDaikin152::setPowerful()'],['../classIRPanasonicAc.html#a6357688bc9cca92ab222343ee045f4f4',1,'IRPanasonicAc::setPowerful()'],['../classIRSamsungAc.html#ab657b79740e0f84c09611ea3b10d06f0',1,'IRSamsungAc::setPowerful()']]], + ['setpowerspecial_4257',['setPowerSpecial',['../classIRSharpAc.html#af7dd64c6d82a8502d2ee176f7b0f5abb',1,'IRSharpAc']]], + ['setpowertoggle_4258',['setPowerToggle',['../classIRDaikin128.html#a5d7edaa44f0c9ca55ef1040dd42e42e3',1,'IRDaikin128::setPowerToggle()'],['../classIRDaikin64.html#ac7f673619842d217d4eda893da2f35fd',1,'IRDaikin64::setPowerToggle()'],['../classIRHitachiAc1.html#ae30430edd92ec4b848c8a105a78e8068',1,'IRHitachiAc1::setPowerToggle()'],['../classIRWhirlpoolAc.html#a61bec25edce5bc244acb41f79df561e7',1,'IRWhirlpoolAc::setPowerToggle()']]], + ['setpurify_4259',['setPurify',['../classIRDaikin2.html#accd4430e998a8c9be80b5a708be9337e',1,'IRDaikin2']]], + ['setquiet_4260',['setQuiet',['../classIRDaikinESP.html#a4927eb8b2db2540efa90b37f4c3cc733',1,'IRDaikinESP::setQuiet()'],['../classIRDaikin2.html#a61ca7e72f850d0f9600fa9d8a336a8ef',1,'IRDaikin2::setQuiet()'],['../classIRDaikin216.html#a062528f54412cd3d2339c7bf82305ebb',1,'IRDaikin216::setQuiet()'],['../classIRDaikin128.html#a89c49332006831debbabbfcb5ec30249',1,'IRDaikin128::setQuiet()'],['../classIRDaikin152.html#a3aadf5f0ae11c5c6c53f351dd6b9c1a4',1,'IRDaikin152::setQuiet()'],['../classIRDaikin64.html#a7e3fb8debcefb76e76dda5612e28f377',1,'IRDaikin64::setQuiet()'],['../classIRKelvinatorAC.html#a2a3ca238649c55cd4f6f92f48eddf9ac',1,'IRKelvinatorAC::setQuiet()'],['../classIRMitsubishi136.html#a70c8a44f93e90ba025a8909c004c3a7b',1,'IRMitsubishi136::setQuiet()'],['../classIRMitsubishi112.html#a9fbbfb7bb1f6cccfcdcfbc4dcc335169',1,'IRMitsubishi112::setQuiet()'],['../classIRPanasonicAc.html#a51b6ae49cb490f697adeaf7f9f466518',1,'IRPanasonicAc::setQuiet()'],['../classIRSamsungAc.html#a6b3dd7d83c613a06f3499f1c8b26a67b',1,'IRSamsungAc::setQuiet()']]], + ['setraw_4261',['setRaw',['../classIRAmcorAc.html#ac0520033d7a59c817ca8ec08462fe39b',1,'IRAmcorAc::setRaw()'],['../classIRArgoAC.html#a98db56256eb71bf2e8da419007145e2b',1,'IRArgoAC::setRaw()'],['../classIRCarrierAc64.html#af49cf0b53bf8ff946a63bae94be0251d',1,'IRCarrierAc64::setRaw()'],['../classIRCoolixAC.html#aed28d08743c529a5715331255a8d5507',1,'IRCoolixAC::setRaw()'],['../classIRCoronaAc.html#a9ccf78675a3c175209c8d0ef08e2e671',1,'IRCoronaAc::setRaw()'],['../classIRDaikinESP.html#a7c69fc77ead837e5b4f1ececd9f43ca9',1,'IRDaikinESP::setRaw()'],['../classIRDaikin2.html#a132001e73eb5744a3a174c5517c9bbda',1,'IRDaikin2::setRaw()'],['../classIRDaikin216.html#a49f6a2ffc2e76ec4ff020e773bd70160',1,'IRDaikin216::setRaw()'],['../classIRDaikin160.html#a22e8a1600f612dd4326b2f9722d3a269',1,'IRDaikin160::setRaw()'],['../classIRDaikin176.html#a51e5f74b532eca958c09998727064e8d',1,'IRDaikin176::setRaw()'],['../classIRDaikin128.html#a25db29e01def45e8850ac9da68aa7ea7',1,'IRDaikin128::setRaw()'],['../classIRDaikin152.html#aab10e030ebe66e44607e9f35af1eb4cb',1,'IRDaikin152::setRaw()'],['../classIRDaikin64.html#a5f081026aca2bccc6fdeef8199e80779',1,'IRDaikin64::setRaw()'],['../classIRDelonghiAc.html#a219bafa7839f10acca33526cf585152a',1,'IRDelonghiAc::setRaw()'],['../classIRElectraAc.html#ae57c51cd3f5d1ebfb2fe7b926d149dd6',1,'IRElectraAc::setRaw()'],['../classIRFujitsuAC.html#a9b89d756948affa7029eeeed51916cbb',1,'IRFujitsuAC::setRaw()'],['../classIRGoodweatherAc.html#a2eae4bbdb14fea9e3004d656f852df59',1,'IRGoodweatherAc::setRaw()'],['../classIRGreeAC.html#a588f526f2f5500c7c2933ca91ccaf865',1,'IRGreeAC::setRaw()'],['../classIRHaierAC.html#a152961e20b5a5bed2ea03cbc65d65ce9',1,'IRHaierAC::setRaw()'],['../classIRHaierACYRW02.html#a389e711e128533c409731d2c87868c85',1,'IRHaierACYRW02::setRaw()'],['../classIRHitachiAc.html#a3b67215c162ef508c68c49b621c5199b',1,'IRHitachiAc::setRaw()'],['../classIRHitachiAc1.html#ae2d40bc477e30ee574f5c5e2ba4e09c2',1,'IRHitachiAc1::setRaw()'],['../classIRHitachiAc424.html#adc24b8b984ff20cebdf81f65843bb283',1,'IRHitachiAc424::setRaw()'],['../classIRHitachiAc3.html#acff4faf79a30df7b7e7c183dec4153a7',1,'IRHitachiAc3::setRaw()'],['../classIRHitachiAc344.html#a31c8984cfea8364734da6f32fe9a2337',1,'IRHitachiAc344::setRaw()'],['../classIRKelvinatorAC.html#a4a32bbf1a7ee8a089ea1e4e7c750433b',1,'IRKelvinatorAC::setRaw()'],['../classIRLgAc.html#a0da8ea4946826736f526386dc4d115cc',1,'IRLgAc::setRaw()'],['../classIRMideaAC.html#ab24da22531f5b2823551501642ec1b94',1,'IRMideaAC::setRaw()'],['../classIRMitsubishiAC.html#ac7bb79f91d5a9296c2b2b74aae1bfb53',1,'IRMitsubishiAC::setRaw()'],['../classIRMitsubishi136.html#abf0487a6fb163bf896e09b2cae6ee939',1,'IRMitsubishi136::setRaw()'],['../classIRMitsubishi112.html#a5c82f92d4a1ba1477ae7738ed5ade368',1,'IRMitsubishi112::setRaw()'],['../classIRMitsubishiHeavy152Ac.html#a8d42a2d87bf889ab4b233ea0c239f4c2',1,'IRMitsubishiHeavy152Ac::setRaw()'],['../classIRMitsubishiHeavy88Ac.html#abf01e448da9ec6e3b4512f58c3020299',1,'IRMitsubishiHeavy88Ac::setRaw()'],['../classIRNeoclimaAc.html#a607ea7df35572578ef86da7f505ab407',1,'IRNeoclimaAc::setRaw()'],['../classIRPanasonicAc.html#a63308883e8447aa5cdf7d29107be220f',1,'IRPanasonicAc::setRaw()'],['../classIRSamsungAc.html#a95377e8c73b51e73e78b51a2b2fa16d4',1,'IRSamsungAc::setRaw()'],['../classIRSharpAc.html#a89b18c4ee29afa56ebed5fa32e578df7',1,'IRSharpAc::setRaw()'],['../classIRTcl112Ac.html#a5b0994f37df6846137b564eeb322f21b',1,'IRTcl112Ac::setRaw()'],['../classIRTecoAc.html#a1ef3423214f55a2e2695cc1180f94bcc',1,'IRTecoAc::setRaw()'],['../classIRToshibaAC.html#ae74ff9241303eb4c7f3593f73e781c73',1,'IRToshibaAC::setRaw()'],['../classIRTrotecESP.html#a4ffe5ee2559828a61af710bb7d892b6c',1,'IRTrotecESP::setRaw()'],['../classIRVestelAc.html#a617bf1f4b5596d5ad005237e8445c12e',1,'IRVestelAc::setRaw(const uint8_t *newState)'],['../classIRVestelAc.html#a5cc86216d33f228c0648d6c66526b0eb',1,'IRVestelAc::setRaw(const uint64_t newState)'],['../classIRWhirlpoolAc.html#afa9c66ea36c970f80c88a0489448ab5b',1,'IRWhirlpoolAc::setRaw()']]], + ['setroomtemp_4262',['setRoomTemp',['../classIRArgoAC.html#aec5a2edc6f414aab201a18defaa78c5b',1,'IRArgoAC']]], + ['setsave_4263',['setSave',['../classIRTecoAc.html#a0f7d203d44d4040be3a4b28fcd5dd34c',1,'IRTecoAc']]], + ['setsensor_4264',['setSensor',['../classIRDaikinESP.html#ae1c95533934fffb29eed3e9a27e8f636',1,'IRDaikinESP::setSensor()'],['../classIRDaikin152.html#af418dbf2bb79dab0193801167dfb5b78',1,'IRDaikin152::setSensor()']]], + ['setsensortemp_4265',['setSensorTemp',['../classIRCoolixAC.html#a05e660b2b61b9a312e29688289f4bf3e',1,'IRCoolixAC']]], + ['setsensortempraw_4266',['setSensorTempRaw',['../classIRCoolixAC.html#a425c3f5fb26330266156c133fb9104eb',1,'IRCoolixAC']]], + ['setsilent_4267',['setSilent',['../classIRMitsubishiHeavy152Ac.html#ab398b9ea2965f059903137ab088791c0',1,'IRMitsubishiHeavy152Ac']]], + ['setsleep_4268',['setSleep',['../classIRCarrierAc64.html#aa729dbef39afeeed8e83f26b927d3b21',1,'IRCarrierAc64::setSleep()'],['../classIRCoolixAC.html#a4ee44167eca3fc88115fef3e845a3768',1,'IRCoolixAC::setSleep()'],['../classIRDaikin128.html#ac43854ae557ec5582f2bfd9150fd57f2',1,'IRDaikin128::setSleep()'],['../classIRDaikin64.html#a7faf8e018179fed2b091a78d0d69a9b8',1,'IRDaikin64::setSleep()'],['../classIRDelonghiAc.html#aa74806e520b2b01a5b0c87ee32ce427e',1,'IRDelonghiAc::setSleep()'],['../classIRGoodweatherAc.html#a30987629a159c5112649f0973895c9c1',1,'IRGoodweatherAc::setSleep()'],['../classIRGreeAC.html#ac9c11817d15bc5c82732a901cd95e07c',1,'IRGreeAC::setSleep()'],['../classIRHaierAC.html#acb72b89fa53b565f9d32db4d8960f988',1,'IRHaierAC::setSleep()'],['../classIRHaierACYRW02.html#ad63834eb1a91ed974af988c385570457',1,'IRHaierACYRW02::setSleep()'],['../classIRHitachiAc1.html#a2ddb6a5d446b379884828e81df0806ee',1,'IRHitachiAc1::setSleep()'],['../classIRMideaAC.html#a1e008ff673450060bf39a65f1cb926e6',1,'IRMideaAC::setSleep()'],['../classIRNeoclimaAc.html#ad01a62fb369c6894333adb2fe0f52b79',1,'IRNeoclimaAc::setSleep()'],['../classIRTecoAc.html#a1e989a4fbd21c507ba13014b1e336ce2',1,'IRTecoAc::setSleep()'],['../classIRTrotecESP.html#a41c558c6937e61e77269139f96135420',1,'IRTrotecESP::setSleep()'],['../classIRVestelAc.html#a4b93d5585b7fb9d509e7fcf84e2b4abc',1,'IRVestelAc::setSleep()'],['../classIRWhirlpoolAc.html#a6eaa24abc9eac64d9cbe79205a239474',1,'IRWhirlpoolAc::setSleep()']]], + ['setspecial_4269',['setSpecial',['../classIRSharpAc.html#ad7d2eca8b863569a1b17fdca4930d84f',1,'IRSharpAc']]], + ['setspeed_4270',['setSpeed',['../classIRTrotecESP.html#a268146141ce0358c2353c0ff59cfbad3',1,'IRTrotecESP']]], + ['setstartclock_4271',['setStartClock',['../classIRMitsubishiAC.html#a22d8c0dfd8098cb274d915476ed4caae',1,'IRMitsubishiAC']]], + ['setstopclock_4272',['setStopClock',['../classIRMitsubishiAC.html#a228dafbf1ea3e9c3487506a5ca2ea274',1,'IRMitsubishiAC']]], + ['setsuper_4273',['setSuper',['../classIRWhirlpoolAc.html#a19a14674b0bae79d3aee81b8d48aacc7',1,'IRWhirlpoolAc']]], + ['setswing_4274',['setSwing',['../classIRCoolixAC.html#a57e3641e20f072df238b305045e74246',1,'IRCoolixAC::setSwing()'],['../classIRFujitsuAC.html#a60ab8f21b5561e94a322b72a606468b9',1,'IRFujitsuAC::setSwing()'],['../classIRGoodweatherAc.html#a4d11a6885a5e7851e7c941b559159c35',1,'IRGoodweatherAc::setSwing()'],['../classIRHaierAC.html#a28c8bf6e0f45e074bf5eb13c25805627',1,'IRHaierAC::setSwing()'],['../classIRHaierACYRW02.html#ab9152dd09dec2db522dd96778f3b1556',1,'IRHaierACYRW02::setSwing()'],['../classIRSamsungAc.html#aaa7aaca1134e1565f527fcaa96a2fa6e',1,'IRSamsungAc::setSwing()'],['../classIRTecoAc.html#aaaeb10176c0b73e72fdb63b53fdcd5d0',1,'IRTecoAc::setSwing()'],['../classIRVestelAc.html#a6c98427df6e5e8081a6dcbfcd436ff0d',1,'IRVestelAc::setSwing()'],['../classIRWhirlpoolAc.html#a6fec80710ba87599840e576f37e0c944',1,'IRWhirlpoolAc::setSwing()']]], + ['setswingh_4275',['setSwingH',['../classIRElectraAc.html#afcd40681003d57b4f1b652175fc276a8',1,'IRElectraAc::setSwingH()'],['../classIRHitachiAc1.html#af6cc42d52dfed89e23d3d180e7b69af9',1,'IRHitachiAc1::setSwingH()'],['../classIRHitachiAc344.html#a5651cb90ba9b87ef841f8987bad267d4',1,'IRHitachiAc344::setSwingH()'],['../classIRMitsubishi112.html#a99f97b04ac22a7942ea371f470faaf49',1,'IRMitsubishi112::setSwingH()'],['../classIRNeoclimaAc.html#a1aeebc60d7bbd0fb801ad88f639cb6a0',1,'IRNeoclimaAc::setSwingH()']]], + ['setswinghorizontal_4276',['setSwingHorizontal',['../classIRDaikinESP.html#a5a7ec7b00811138879c636b03ae58606',1,'IRDaikinESP::setSwingHorizontal()'],['../classIRDaikin2.html#a75b6d6fb5bab0a9c951ad35e3e1d07c5',1,'IRDaikin2::setSwingHorizontal()'],['../classIRDaikin216.html#af8a1525cbe8d813c419d17ee6776a7d9',1,'IRDaikin216::setSwingHorizontal()'],['../classIRDaikin176.html#a9e63cf22410ffad45f6b308674079ee8',1,'IRDaikin176::setSwingHorizontal()'],['../classIRHitachiAc.html#ae70600f4a6f9fd7579221b11cd73062f',1,'IRHitachiAc::setSwingHorizontal()'],['../classIRKelvinatorAC.html#a2f1731f71bc74fb7ad6fec1210ecb1c7',1,'IRKelvinatorAC::setSwingHorizontal()'],['../classIRMitsubishiHeavy152Ac.html#a8713144e057424809292494a663dcd22',1,'IRMitsubishiHeavy152Ac::setSwingHorizontal()'],['../classIRMitsubishiHeavy88Ac.html#aaceffdd4e631fb2d4c404de0c8ff8cdb',1,'IRMitsubishiHeavy88Ac::setSwingHorizontal()'],['../classIRPanasonicAc.html#a32f3f07813165a39359887485dd87254',1,'IRPanasonicAc::setSwingHorizontal()'],['../classIRTcl112Ac.html#aedc63c59a924d64048bc034a752ce7ed',1,'IRTcl112Ac::setSwingHorizontal()']]], + ['setswingtoggle_4277',['setSwingToggle',['../classIRHitachiAc1.html#a24ec128b6bb27cfc4be4dda9ece003d6',1,'IRHitachiAc1::setSwingToggle()'],['../classIRSharpAc.html#a0d397009ecf213111207fcebb12b95fb',1,'IRSharpAc::setSwingToggle()']]], + ['setswingv_4278',['setSwingV',['../classIRCarrierAc64.html#a61a3f9f29cabc0634a9a74fc2227d8c5',1,'IRCarrierAc64::setSwingV()'],['../classIRDaikin152.html#ad151bb85529d46f7e3e3e65dbf446ff0',1,'IRDaikin152::setSwingV()'],['../classIRElectraAc.html#ae5b33942670e0033cbb9b9c7a1524e93',1,'IRElectraAc::setSwingV()'],['../classIRHitachiAc1.html#a1bcc61a9a33a3ddec41d44d52e7df0d3',1,'IRHitachiAc1::setSwingV()'],['../classIRHitachiAc344.html#a3982f110de8ff9881cf4070902294285',1,'IRHitachiAc344::setSwingV()'],['../classIRMitsubishi136.html#a0d54bc6dd55da18b05f723a1b61e575e',1,'IRMitsubishi136::setSwingV()'],['../classIRMitsubishi112.html#ae33b469f1b67616f101f4a3df874fb78',1,'IRMitsubishi112::setSwingV()'],['../classIRNeoclimaAc.html#aa6e5f6f092f52c5c289642c9576c8bc0',1,'IRNeoclimaAc::setSwingV()']]], + ['setswingvertical_4279',['setSwingVertical',['../classIRDaikinESP.html#a9200ef5751df5d488d7e08b138ec6356',1,'IRDaikinESP::setSwingVertical()'],['../classIRDaikin2.html#a35e72dc8e7967ee8ca8e84a6344468f3',1,'IRDaikin2::setSwingVertical()'],['../classIRDaikin216.html#a851484d5a37ceb1b0fc32e2e4bc2bcbb',1,'IRDaikin216::setSwingVertical()'],['../classIRDaikin160.html#a1683a255393f233d3e5b46d186d62881',1,'IRDaikin160::setSwingVertical()'],['../classIRDaikin128.html#a961aceb41145001003a50c5988f04c4d',1,'IRDaikin128::setSwingVertical()'],['../classIRDaikin64.html#afca186067111fa7181916a218c2800ec',1,'IRDaikin64::setSwingVertical()'],['../classIRGreeAC.html#a1b571dea8a5bf553554e45074f3a01c0',1,'IRGreeAC::setSwingVertical()'],['../classIRHitachiAc.html#a7e3ee78e4835fe402095b544c1e52f9f',1,'IRHitachiAc::setSwingVertical()'],['../classIRKelvinatorAC.html#a7334fbf8f2a67b33562ecea6b6e66f0e',1,'IRKelvinatorAC::setSwingVertical()'],['../classIRMitsubishiHeavy152Ac.html#aea3ac937feff058feef321bfe7357145',1,'IRMitsubishiHeavy152Ac::setSwingVertical()'],['../classIRMitsubishiHeavy88Ac.html#a9406e1890483703afb7b383e1363f8ec',1,'IRMitsubishiHeavy88Ac::setSwingVertical()'],['../classIRPanasonicAc.html#a48f31b1f85c92fac22f85a1aa8074c6e',1,'IRPanasonicAc::setSwingVertical()'],['../classIRTcl112Ac.html#a53f702dcc66de81f6e7e03d538a6946d',1,'IRTcl112Ac::setSwingVertical()']]], + ['setswingvtoggle_4280',['setSwingVToggle',['../classIRCoronaAc.html#a7cb31da86353ec637239cb747890bd7b',1,'IRCoronaAc::setSwingVToggle()'],['../classIRHitachiAc424.html#a220fd85bd213dd13ee9c609d4d7d20c1',1,'IRHitachiAc424::setSwingVToggle()'],['../classIRMideaAC.html#a7fce182bff4f5bc2c6679b20f344837b',1,'IRMideaAC::setSwingVToggle()']]], + ['settemp_4281',['setTemp',['../classIRAmcorAc.html#af4b2c476b76534687f14e9be963e9522',1,'IRAmcorAc::setTemp()'],['../classIRArgoAC.html#abad424a3cf1894715baa03780fa9b53b',1,'IRArgoAC::setTemp()'],['../classIRCarrierAc64.html#a79e193514ac6d07be537a78887426311',1,'IRCarrierAc64::setTemp()'],['../classIRCoolixAC.html#a1d4b4fb810b9f3835ee585b2aa66088f',1,'IRCoolixAC::setTemp()'],['../classIRCoronaAc.html#a9b1d5223cbb6ae6ba07f32871b27d9c6',1,'IRCoronaAc::setTemp()'],['../classIRDaikinESP.html#a631db8830684b745711667aed73a6433',1,'IRDaikinESP::setTemp()'],['../classIRDaikin2.html#a7f752c785fe180d5038e35bb07ff965a',1,'IRDaikin2::setTemp()'],['../classIRDaikin216.html#a8735732d3264eec119127d4353990669',1,'IRDaikin216::setTemp()'],['../classIRDaikin160.html#abedd99ed838478a7ef856537c6fabb82',1,'IRDaikin160::setTemp()'],['../classIRDaikin176.html#acb3b296f4c87a5a37258c666ef886ff3',1,'IRDaikin176::setTemp()'],['../classIRDaikin128.html#aba143a1b80e6de7d1c7b987eeda6b0db',1,'IRDaikin128::setTemp()'],['../classIRDaikin152.html#a97567ade1c0262b3f95f23f171936d8c',1,'IRDaikin152::setTemp()'],['../classIRDaikin64.html#adb1eb657998c05a143365755da0a1e81',1,'IRDaikin64::setTemp()'],['../classIRDelonghiAc.html#a08cc3e32c50277e3f986ed2c3945ce0d',1,'IRDelonghiAc::setTemp()'],['../classIRElectraAc.html#a5f986d9a376b6d5348fcb021d66d235b',1,'IRElectraAc::setTemp()'],['../classIRFujitsuAC.html#ab56c02fc0311ee7f28e780948cbc6a75',1,'IRFujitsuAC::setTemp()'],['../classIRGoodweatherAc.html#a8b1c90f69a3a2e412020d07809d180cc',1,'IRGoodweatherAc::setTemp()'],['../classIRGreeAC.html#a1890c6d134183beb89b791ec565623bb',1,'IRGreeAC::setTemp()'],['../classIRHaierAC.html#a9fb2a375cc1b8692fe4d5dcdd765cc46',1,'IRHaierAC::setTemp()'],['../classIRHaierACYRW02.html#a80170879e7bd391e360d41f18f6fa52b',1,'IRHaierACYRW02::setTemp()'],['../classIRHitachiAc.html#a9f416886ae341cdb6d449572e4d168a9',1,'IRHitachiAc::setTemp()'],['../classIRHitachiAc1.html#a10ba2dcbe447e505cbaa1a9b63f4823c',1,'IRHitachiAc1::setTemp()'],['../classIRHitachiAc424.html#a5cca8f31d07ce87b6e4a0ff0c22b1be8',1,'IRHitachiAc424::setTemp()'],['../classIRKelvinatorAC.html#ab098a376c7393d377abcc6c1f504d372',1,'IRKelvinatorAC::setTemp()'],['../classIRLgAc.html#ad9924a8bc9737ec6007d76ec47b34142',1,'IRLgAc::setTemp()'],['../classIRMideaAC.html#a42f79e73f418d5267eed7ba5b0e266f5',1,'IRMideaAC::setTemp()'],['../classIRMitsubishiAC.html#afd629013630747400e005fab8407d711',1,'IRMitsubishiAC::setTemp()'],['../classIRMitsubishi136.html#ac19c9234a5f65cae50b64d56c4bebb8f',1,'IRMitsubishi136::setTemp()'],['../classIRMitsubishi112.html#a03ba44a6d2f152b7afade423f12c8726',1,'IRMitsubishi112::setTemp()'],['../classIRMitsubishiHeavy152Ac.html#ad4f9ae94b8ab1fff8fc99b8d7818a8fe',1,'IRMitsubishiHeavy152Ac::setTemp()'],['../classIRMitsubishiHeavy88Ac.html#aa4a92e5334aebdca5d2b26b642e9b9e8',1,'IRMitsubishiHeavy88Ac::setTemp()'],['../classIRNeoclimaAc.html#a59e27fa001f9ab674b69eb2c41b6393c',1,'IRNeoclimaAc::setTemp()'],['../classIRPanasonicAc.html#a58376c311177e701333f4915515d49f1',1,'IRPanasonicAc::setTemp()'],['../classIRSamsungAc.html#a94a71e82321343220836aa614b231bd0',1,'IRSamsungAc::setTemp()'],['../classIRSharpAc.html#a151f88799cdab6fda4cfef83b30e5917',1,'IRSharpAc::setTemp()'],['../classIRTcl112Ac.html#a110bae0201b63db0409c352dd8d62786',1,'IRTcl112Ac::setTemp()'],['../classIRTecoAc.html#a405106cb572dac338d79da48fe7a7cb3',1,'IRTecoAc::setTemp()'],['../classIRToshibaAC.html#a923fad1f637e1851a77a063978994604',1,'IRToshibaAC::setTemp()'],['../classIRTrotecESP.html#ad467e7fe9ff61fec4ec10b367c0f9279',1,'IRTrotecESP::setTemp()'],['../classIRVestelAc.html#a8c4eddfba4edfa16e317e12677736756',1,'IRVestelAc::setTemp()'],['../classIRWhirlpoolAc.html#afff1ae75ffa362abb791c97c20023755',1,'IRWhirlpoolAc::setTemp()']]], + ['settempraw_4282',['setTempRaw',['../classIRCoolixAC.html#ae9371280e92daa8e1441523026f1ef0a',1,'IRCoolixAC']]], + ['settempunit_4283',['setTempUnit',['../classIRDelonghiAc.html#a4e3681e49065ba232577ca05157a5ef2',1,'IRDelonghiAc']]], + ['settime_4284',['setTime',['../classIRArgoAC.html#ae285801cde19da82e128098097624852',1,'IRArgoAC::setTime()'],['../classIRHaierAC.html#a81ca00cf5b49308c2609b717d34958ad',1,'IRHaierAC::setTime()'],['../classIRVestelAc.html#afc5dedf83855a8fea8b29494bfb07d64',1,'IRVestelAc::setTime()'],['../classIRWhirlpoolAc.html#a40289737223c14c8a1e723e7a28bad13',1,'IRWhirlpoolAc::setTime()']]], + ['settimer_4285',['setTimer',['../classIRDaikin128.html#a8498de57fc1bdb2f71a678f7877d3125',1,'IRDaikin128::setTimer()'],['../classIRGreeAC.html#a84debd45d2f2ba221f825257e0bc6294',1,'IRGreeAC::setTimer()'],['../classIRMitsubishiAC.html#acb56c91ef0db6ace7782d356af2dcd4d',1,'IRMitsubishiAC::setTimer()'],['../classIRSharpAc.html#a8782543c33e48af0a09e548276eb6413',1,'IRSharpAc::setTimer()'],['../classIRTecoAc.html#a88a84e22d53a204da754c04210fadd04',1,'IRTecoAc::setTimer()'],['../classIRTrotecESP.html#a92bfed0f247b21c77737b720151dbb88',1,'IRTrotecESP::setTimer()'],['../classIRVestelAc.html#a7c66e1ec13c827714eaa2233f50f072b',1,'IRVestelAc::setTimer()']]], + ['settimeractive_4286',['setTimerActive',['../classIRVestelAc.html#a77f78e534b19a8dca776b17aa06739aa',1,'IRVestelAc']]], + ['settimerenabled_4287',['setTimerEnabled',['../classIRGreeAC.html#a1002d6dfe409076fa7ef252589d5043c',1,'IRGreeAC']]], + ['settolerance_4288',['setTolerance',['../classIRrecv.html#aa091c449db70c65fd0221669df7438ea',1,'IRrecv']]], + ['setturbo_4289',['setTurbo',['../classIRCoolixAC.html#a65a04ec9028025155792be5ba0f81927',1,'IRCoolixAC::setTurbo()'],['../classIRDaikin64.html#a734cc23f79a4de4099a4ceb1aff14762',1,'IRDaikin64::setTurbo()'],['../classIRElectraAc.html#adb40e95465788b03e4cb845bd481f7ed',1,'IRElectraAc::setTurbo()'],['../classIRGoodweatherAc.html#a7827fc5a8f85b284c0121727dba34f11',1,'IRGoodweatherAc::setTurbo()'],['../classIRGreeAC.html#ae873023ad81f7dcb12ee5b061e160bea',1,'IRGreeAC::setTurbo()'],['../classIRHaierACYRW02.html#aba5f028ee1ebf7be2d4de5a66237f01b',1,'IRHaierACYRW02::setTurbo()'],['../classIRKelvinatorAC.html#a7d9c44970e85f23c83723f27e96260ee',1,'IRKelvinatorAC::setTurbo()'],['../classIRMitsubishiHeavy152Ac.html#a275e8ae44e2018a848b3e8f0893c8023',1,'IRMitsubishiHeavy152Ac::setTurbo()'],['../classIRMitsubishiHeavy88Ac.html#a39ac892d349180327cce92c6f82bea30',1,'IRMitsubishiHeavy88Ac::setTurbo()'],['../classIRNeoclimaAc.html#aa2a9563d9e3c5c95dfa512c0bb87e16f',1,'IRNeoclimaAc::setTurbo()'],['../classIRSharpAc.html#a8a184ae8eeb07704b9b69849421e3172',1,'IRSharpAc::setTurbo()'],['../classIRTcl112Ac.html#a99e3b3e2f0cc627b6d872d04b35d6230',1,'IRTcl112Ac::setTurbo()'],['../classIRVestelAc.html#afa762d0fa63ecc7444c1c107f8f07cdb',1,'IRVestelAc::setTurbo()']]], + ['setunknownthreshold_4290',['setUnknownThreshold',['../classIRrecv.html#a02693553aad1decd67bdae60402e48bf',1,'IRrecv']]], + ['setusecelsius_4291',['setUseCelsius',['../classIRMideaAC.html#a1eeb72ddd2b9867c2f9c392080b9c1ed',1,'IRMideaAC']]], + ['setusefahrenheit_4292',['setUseFahrenheit',['../classIRGreeAC.html#af559afaa9da5fd27cdb516355da67bd6',1,'IRGreeAC']]], + ['setvane_4293',['setVane',['../classIRMitsubishiAC.html#abb247f1dca5cf23a7b8a16852dcf32f1',1,'IRMitsubishiAC']]], + ['setweeklytimerenable_4294',['setWeeklyTimerEnable',['../classIRDaikinESP.html#a0db67d46b13acfad9b94c7e4691777b8',1,'IRDaikinESP']]], + ['setwidevane_4295',['setWideVane',['../classIRMitsubishiAC.html#a02b2b3d7456e6123c60dca70de346c25',1,'IRMitsubishiAC']]], + ['setwifi_4296',['setWiFi',['../classIRGreeAC.html#afde745ceaa97f9608195b2ba9fce6c5c',1,'IRGreeAC']]], + ['setxfan_4297',['setXFan',['../classIRGreeAC.html#af465c607222fa433f54c2ce56ced2474',1,'IRGreeAC::setXFan()'],['../classIRKelvinatorAC.html#af02da81109109cf1cb44057fd1a40164',1,'IRKelvinatorAC::setXFan()']]], + ['setzonefollow_4298',['setZoneFollow',['../classIRCoolixAC.html#a0c0f39d8e2e79d8259000695263ec3fa',1,'IRCoolixAC']]], + ['sharp_4299',['sharp',['../classIRac.html#a7b6d8b4e554a89f339f896fe4233ed15',1,'IRac']]], + ['space_4300',['space',['../classIRsend.html#a0417b10d4e16718a87f8b2062a7d04a1',1,'IRsend']]], + ['statereset_4301',['stateReset',['../classIRAmcorAc.html#a018ab4ca4d738d848d3388ea1300b83b',1,'IRAmcorAc::stateReset()'],['../classIRArgoAC.html#af34a99bc37c4496c9fd68856aa065a13',1,'IRArgoAC::stateReset()'],['../classIRCarrierAc64.html#abe58c8f97ab4c34fd0cf198b07589694',1,'IRCarrierAc64::stateReset()'],['../classIRCoolixAC.html#a88a44b7ba5ac7d5654de4592bd41c207',1,'IRCoolixAC::stateReset()'],['../classIRCoronaAc.html#a47726d4ff93528bd8a5a6f1b47ba7141',1,'IRCoronaAc::stateReset()'],['../classIRDaikinESP.html#a49f6b90336225f7e94b8aefd066e1993',1,'IRDaikinESP::stateReset()'],['../classIRDaikin2.html#a9b49e90604bf6b1abb93581eecfc6c88',1,'IRDaikin2::stateReset()'],['../classIRDaikin216.html#adbc856e6531b38963db5680d279a4767',1,'IRDaikin216::stateReset()'],['../classIRDaikin160.html#ade56e55c8a0c81f0803dec2cda4625b0',1,'IRDaikin160::stateReset()'],['../classIRDaikin176.html#ab86a1b458a1be5d7fe5fcb7e287ef1d3',1,'IRDaikin176::stateReset()'],['../classIRDaikin128.html#ab604a7594c3b0131c5d977e3fc3b3565',1,'IRDaikin128::stateReset()'],['../classIRDaikin152.html#a278291def7d0e14552e7fbe9a56346bd',1,'IRDaikin152::stateReset()'],['../classIRDaikin64.html#af5a691404b8026cf1da45502f1c019f4',1,'IRDaikin64::stateReset()'],['../classIRDelonghiAc.html#aac444790a16678a1e88f1adef02829ba',1,'IRDelonghiAc::stateReset()'],['../classIRElectraAc.html#ab8035c14158fcf3758f46f6976b814f7',1,'IRElectraAc::stateReset()'],['../classIRFujitsuAC.html#a603a0e1870f406e4e746a7bb4c37fb70',1,'IRFujitsuAC::stateReset()'],['../classIRGoodweatherAc.html#ae7f8873ad58e553dc89307220628bebf',1,'IRGoodweatherAc::stateReset()'],['../classIRGreeAC.html#a61356a0dfb4656ac438c3629c591b165',1,'IRGreeAC::stateReset()'],['../classIRHaierAC.html#a62fbae1d2bac01ac3a2194274aa839d9',1,'IRHaierAC::stateReset()'],['../classIRHaierACYRW02.html#a106e7ffa0d69cdf976087c6e190d03ea',1,'IRHaierACYRW02::stateReset()'],['../classIRHitachiAc.html#a0564c00c60e64e57e20f3c1a4bd3d894',1,'IRHitachiAc::stateReset()'],['../classIRHitachiAc1.html#a9764b329d982d018b15098b3044f9596',1,'IRHitachiAc1::stateReset()'],['../classIRHitachiAc424.html#afd8d5b21086b34cdc07b498157240f8f',1,'IRHitachiAc424::stateReset()'],['../classIRHitachiAc3.html#a7bdcddf9c7f85b7cb43a92198e422549',1,'IRHitachiAc3::stateReset()'],['../classIRHitachiAc344.html#ab0174472d44790a5516b8f4377a89f22',1,'IRHitachiAc344::stateReset()'],['../classIRKelvinatorAC.html#ad6fefe85023c3fc318b0e45924874f9f',1,'IRKelvinatorAC::stateReset()'],['../classIRLgAc.html#a5959000c9f0b2cf64742d6a2f1c4c9b9',1,'IRLgAc::stateReset()'],['../classIRMideaAC.html#acc584e07406e1811acfb26f6cd5383cd',1,'IRMideaAC::stateReset()'],['../classIRMitsubishiAC.html#a8da4be360c8e2fd3a5a40cb4049b5d84',1,'IRMitsubishiAC::stateReset()'],['../classIRMitsubishi136.html#a67556dab7ed42c68a274f4f24ecc35bb',1,'IRMitsubishi136::stateReset()'],['../classIRMitsubishi112.html#a9c601ba34e10d5c63886c2c5b405d9ae',1,'IRMitsubishi112::stateReset()'],['../classIRMitsubishiHeavy152Ac.html#a0b239cacd3a8a96f2e3d7047f26119da',1,'IRMitsubishiHeavy152Ac::stateReset()'],['../classIRMitsubishiHeavy88Ac.html#a1cf118f435c99372c89a140a79c67f1f',1,'IRMitsubishiHeavy88Ac::stateReset()'],['../classIRNeoclimaAc.html#a5ce32a6e6195b246696cb609994f3762',1,'IRNeoclimaAc::stateReset()'],['../classIRPanasonicAc.html#a9a9fbf531f04c486edf913c382351b2b',1,'IRPanasonicAc::stateReset()'],['../classIRSamsungAc.html#a52186401655966b3103d3d73fb77e7f0',1,'IRSamsungAc::stateReset()'],['../classIRSharpAc.html#aa151c704ba4f5690a7cfadaf90c4b60d',1,'IRSharpAc::stateReset()'],['../classIRTcl112Ac.html#a049f475c1af7b62b9f3482dcf9e66d4a',1,'IRTcl112Ac::stateReset()'],['../classIRTecoAc.html#ad53e6f3d3693ee6efb419326a3d4c492',1,'IRTecoAc::stateReset()'],['../classIRToshibaAC.html#a3d3c3df261b4db7a9d831c94cc206e8a',1,'IRToshibaAC::stateReset()'],['../classIRTrotecESP.html#a86c3415d8c1880c325bc22c2c4ca44e0',1,'IRTrotecESP::stateReset()'],['../classIRVestelAc.html#a921100234f5751f8b94d9673a5d217f9',1,'IRVestelAc::stateReset()'],['../classIRWhirlpoolAc.html#a371a6f48a2f4f66e4243dacbbf4471be',1,'IRWhirlpoolAc::stateReset()']]], + ['stephoriz_4302',['stepHoriz',['../classIRFujitsuAC.html#a53c48bc1f32c849263a3aa86ff06b1d4',1,'IRFujitsuAC']]], + ['stepvert_4303',['stepVert',['../classIRFujitsuAC.html#a942f106c27ce04094b5b615f2e174022',1,'IRFujitsuAC']]], + ['strtobool_4304',['strToBool',['../classIRac.html#a3dba736fe25bd3a3a47b9ec7dae51728',1,'IRac']]], + ['strtodecodetype_4305',['strToDecodeType',['../IRutils_8cpp.html#ae1614f315c1ebc44eaf1ac62055cc1ff',1,'strToDecodeType(const char *const str): IRutils.cpp'],['../IRutils_8h.html#a10b9312e4ac9c96d895af83db01ed72e',1,'strToDecodeType(const char *str): IRutils.cpp']]], + ['strtofanspeed_4306',['strToFanspeed',['../classIRac.html#a7173b12c155d04dd1db07a055f4ecb03',1,'IRac']]], + ['strtomodel_4307',['strToModel',['../classIRac.html#a7036fbbb918d644a98b5efa16374a256',1,'IRac']]], + ['strtoopmode_4308',['strToOpmode',['../classIRac.html#a251fa76ddacc84d2655bac723b7dea28',1,'IRac']]], + ['strtoswingh_4309',['strToSwingH',['../classIRac.html#a294d6040909519f465945245df56e56d',1,'IRac']]], + ['strtoswingv_4310',['strToSwingV',['../classIRac.html#a538c861d79afabb11fb8becedd3962f8',1,'IRac']]], + ['sumbytes_4311',['sumBytes',['../IRutils_8cpp.html#abfbd3d7cc33d0aac341e6619f3390108',1,'sumBytes(const uint8_t *const start, const uint16_t length, const uint8_t init): IRutils.cpp'],['../IRutils_8h.html#a3f33bdd680bea210b212d4e9925eb8eb',1,'sumBytes(const uint8_t *const start, const uint16_t length, const uint8_t init=0): IRutils.cpp']]], + ['sumnibbles_4312',['sumNibbles',['../namespaceirutils.html#a4752ecc3eafa3ca2e13344a52519b343',1,'irutils::sumNibbles(const uint8_t *const start, const uint16_t length, const uint8_t init)'],['../namespaceirutils.html#aeb5202fa0093ee6b7e07d4290229fbd2',1,'irutils::sumNibbles(const uint64_t data, const uint8_t count, const uint8_t init, const bool nibbleonly)']]], + ['swinghtostring_4313',['swinghToString',['../classIRac.html#a21c9d71bbf229fd8369480e50a7c3689',1,'IRac']]], + ['swingvtostring_4314',['swingvToString',['../classIRac.html#a641b59e48183a8f6d9b739ce7210f142',1,'IRac']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_12.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_12.html new file mode 100644 index 000000000..48e591559 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_12.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_12.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_12.js new file mode 100644 index 000000000..9efc7ec0e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_12.js @@ -0,0 +1,21 @@ +var searchData= +[ + ['tcl112_4315',['tcl112',['../classIRac.html#a3028bd9e83956d57b592bb96638b3f59',1,'IRac']]], + ['teco_4316',['teco',['../classIRac.html#a9e612e04e270dd5710e8a63a64b56064',1,'IRac']]], + ['tickshigh_4317',['ticksHigh',['../classIRrecv.html#a573dbb20695f2ffc808623df8c36280c',1,'IRrecv']]], + ['tickslow_4318',['ticksLow',['../classIRrecv.html#ac08e50c5eec10c0095157f4bdd4051c8',1,'IRrecv']]], + ['timerms_4319',['TimerMs',['../classTimerMs.html#a7bf7f8d2fcf76b27b34ea4705810eef5',1,'TimerMs']]], + ['tocommon_4320',['toCommon',['../classIRAmcorAc.html#aac4ae204cf0c393c18e5de96c4ba44ab',1,'IRAmcorAc::toCommon()'],['../classIRArgoAC.html#a4b1fda530b50c30cb863a3c146f4c81b',1,'IRArgoAC::toCommon()'],['../classIRCarrierAc64.html#a7c4a84d0d9f1e78ba611e118ddb90635',1,'IRCarrierAc64::toCommon()'],['../classIRCoolixAC.html#acadeabae7017e49c944eb22528297b3a',1,'IRCoolixAC::toCommon()'],['../classIRCoronaAc.html#a78dee47464e312d57e660b34c10bb13c',1,'IRCoronaAc::toCommon()'],['../classIRDaikinESP.html#a6bc97a753db054ce2ed59809845e23f1',1,'IRDaikinESP::toCommon()'],['../classIRDaikin2.html#a090407aff4ef81714e31ef28ac41d8e2',1,'IRDaikin2::toCommon()'],['../classIRDaikin216.html#ac477511261d7f135ee4f909eb5512f9a',1,'IRDaikin216::toCommon()'],['../classIRDaikin160.html#a0641f2e7f86412a36dcbe98b9049d322',1,'IRDaikin160::toCommon()'],['../classIRDaikin176.html#ac99fcb66d866196b51ad11384154f8ae',1,'IRDaikin176::toCommon()'],['../classIRDaikin128.html#a54de8ff37216f7a3a2cc744d97c2e1c6',1,'IRDaikin128::toCommon()'],['../classIRDaikin152.html#a96fee4c7cee70cc9249c556b277b2f74',1,'IRDaikin152::toCommon()'],['../classIRDaikin64.html#ad57748fa03e79a277508aa42b08c8f83',1,'IRDaikin64::toCommon()'],['../classIRDelonghiAc.html#a2cdcd20dffb763a5f9ff7bd264c1d3e8',1,'IRDelonghiAc::toCommon()'],['../classIRElectraAc.html#ad10aba2fa72f4b839538fc5a99c696ad',1,'IRElectraAc::toCommon()'],['../classIRFujitsuAC.html#adfd6ff9d4449eae7a5268b26058a483f',1,'IRFujitsuAC::toCommon()'],['../classIRGoodweatherAc.html#ae616e9fc03406ec88b5c5ddcde5f2f2c',1,'IRGoodweatherAc::toCommon()'],['../classIRGreeAC.html#ac28c640aa4b5dd0dbbca42b056f877f7',1,'IRGreeAC::toCommon()'],['../classIRHaierAC.html#a1e74862d6ab7e65108a7b1a3b7af7e91',1,'IRHaierAC::toCommon()'],['../classIRHaierACYRW02.html#aff86d2e3e1d357f0eecf6322964e7c16',1,'IRHaierACYRW02::toCommon()'],['../classIRHitachiAc.html#aa1ec8cc4b5025272c72dc69c6d6486a3',1,'IRHitachiAc::toCommon()'],['../classIRHitachiAc1.html#aef93034682210a6c564fbea4461ab47e',1,'IRHitachiAc1::toCommon()'],['../classIRHitachiAc424.html#a36711772ebdf385e0a95564f8a552634',1,'IRHitachiAc424::toCommon()'],['../classIRHitachiAc344.html#a146203ad02a3df4037b97c0416ba828e',1,'IRHitachiAc344::toCommon()'],['../classIRKelvinatorAC.html#a1e900aa29dad75f74de2bb797d475b20',1,'IRKelvinatorAC::toCommon()'],['../classIRLgAc.html#a75c52ef31270f25651521ae2be558faa',1,'IRLgAc::toCommon()'],['../classIRMideaAC.html#a62086b58f71908b75e28a61bd4f6bf15',1,'IRMideaAC::toCommon()'],['../classIRMitsubishiAC.html#a42338266a34940e657e5226c81f2fd06',1,'IRMitsubishiAC::toCommon()'],['../classIRMitsubishi136.html#a938360f488ec923e138744b6f80477bb',1,'IRMitsubishi136::toCommon()'],['../classIRMitsubishi112.html#aadde5055371b418fd733a2e93d12b478',1,'IRMitsubishi112::toCommon()'],['../classIRMitsubishiHeavy152Ac.html#af9cbfb13cd48d5d503756c50df8fc7b7',1,'IRMitsubishiHeavy152Ac::toCommon()'],['../classIRMitsubishiHeavy88Ac.html#a3f80427169359dc72367e6ee4e52c42f',1,'IRMitsubishiHeavy88Ac::toCommon()'],['../classIRNeoclimaAc.html#a455397211c7cb8074f6b7358dc6a5b9e',1,'IRNeoclimaAc::toCommon()'],['../classIRPanasonicAc.html#af2218f117db06424ced00ba6c0cc3234',1,'IRPanasonicAc::toCommon()'],['../classIRSamsungAc.html#a01e9279d541f64ebfa433c35a3651796',1,'IRSamsungAc::toCommon()'],['../classIRSharpAc.html#aaade155b2128ba11c2e91bba676c72d9',1,'IRSharpAc::toCommon()'],['../classIRTcl112Ac.html#af5813975bfe55a76d202f8c7f48df82d',1,'IRTcl112Ac::toCommon()'],['../classIRTecoAc.html#af3953289854dabf105c6612f14ef5da0',1,'IRTecoAc::toCommon()'],['../classIRToshibaAC.html#acda90e0171043c3a673ffac52ef9b4b5',1,'IRToshibaAC::toCommon()'],['../classIRTrotecESP.html#ac224a0a18a64ce9802c3f25fafa20a04',1,'IRTrotecESP::toCommon()'],['../classIRVestelAc.html#adb7ab58e91f13b999b62559fc7add91a',1,'IRVestelAc::toCommon()'],['../classIRWhirlpoolAc.html#a961da338e344fd975934f9f69d97f5b5',1,'IRWhirlpoolAc::toCommon()']]], + ['tocommonfanspeed_4321',['toCommonFanSpeed',['../classIRAmcorAc.html#a951aa81d98c66138f61069431e13f35a',1,'IRAmcorAc::toCommonFanSpeed()'],['../classIRArgoAC.html#a334afe3ce6536089bc2832985067f029',1,'IRArgoAC::toCommonFanSpeed()'],['../classIRCarrierAc64.html#a5a9149acc82fcc22a5be8dcbe791ab77',1,'IRCarrierAc64::toCommonFanSpeed()'],['../classIRCoolixAC.html#a6a0e7219c667eb06897b47a7c36f5fbc',1,'IRCoolixAC::toCommonFanSpeed()'],['../classIRCoronaAc.html#a6d5d0015f01acc97badff7edda964485',1,'IRCoronaAc::toCommonFanSpeed()'],['../classIRDaikinESP.html#a6855a423f10a2230953646d478400574',1,'IRDaikinESP::toCommonFanSpeed()'],['../classIRDaikin176.html#a6f9b7dddcf98c7a42495c900dddf505d',1,'IRDaikin176::toCommonFanSpeed()'],['../classIRDaikin128.html#a1c53a27678731229308e355eb94ec762',1,'IRDaikin128::toCommonFanSpeed()'],['../classIRDaikin64.html#acd24c4932e2bfd6bffbb9a90da2028a6',1,'IRDaikin64::toCommonFanSpeed()'],['../classIRDelonghiAc.html#a231e26843e3616e7455fd020dbb8807b',1,'IRDelonghiAc::toCommonFanSpeed()'],['../classIRElectraAc.html#a5d53fb85582344cfdbfa33da6acbdb7d',1,'IRElectraAc::toCommonFanSpeed()'],['../classIRFujitsuAC.html#a93a35e42d887b5ca6414b295a4a91526',1,'IRFujitsuAC::toCommonFanSpeed()'],['../classIRGoodweatherAc.html#aff899c76d5b808ee35c9f88c116b5dc4',1,'IRGoodweatherAc::toCommonFanSpeed()'],['../classIRGreeAC.html#ade6cb54e99b6dab1df708cbf25fc5967',1,'IRGreeAC::toCommonFanSpeed()'],['../classIRHaierAC.html#ad67ee0b7299d041aad77382dde893229',1,'IRHaierAC::toCommonFanSpeed()'],['../classIRHaierACYRW02.html#a15402e3ba2a9875d5b49f6dab3e85034',1,'IRHaierACYRW02::toCommonFanSpeed()'],['../classIRHitachiAc.html#afba02d48c4a023ed800abf38d5314c7e',1,'IRHitachiAc::toCommonFanSpeed()'],['../classIRHitachiAc1.html#a99f205391deb75d23d08d63e1feff0d4',1,'IRHitachiAc1::toCommonFanSpeed()'],['../classIRHitachiAc424.html#a16abdf55ea3ae4b06e2a23dad3496738',1,'IRHitachiAc424::toCommonFanSpeed()'],['../classIRKelvinatorAC.html#a0ebd262c554c5c843bc3f710570e1401',1,'IRKelvinatorAC::toCommonFanSpeed()'],['../classIRLgAc.html#af47317ba139a4b1e5961b9a45db974df',1,'IRLgAc::toCommonFanSpeed()'],['../classIRMideaAC.html#acd89d4864a46b146ac4f648c4406ded5',1,'IRMideaAC::toCommonFanSpeed()'],['../classIRMitsubishiAC.html#aa7dd30cde520b14575d7fcd992c3bbf1',1,'IRMitsubishiAC::toCommonFanSpeed()'],['../classIRMitsubishi136.html#aaf9f9f17f3ac59ef325b57b9110faa34',1,'IRMitsubishi136::toCommonFanSpeed()'],['../classIRMitsubishi112.html#aaeee082d9adbf7b0d91316c703571f1a',1,'IRMitsubishi112::toCommonFanSpeed()'],['../classIRMitsubishiHeavy152Ac.html#a5e26c3121aceb944fc688e6f641dd5b1',1,'IRMitsubishiHeavy152Ac::toCommonFanSpeed()'],['../classIRMitsubishiHeavy88Ac.html#aa5dae03951ba9a9aeac62184c27f9439',1,'IRMitsubishiHeavy88Ac::toCommonFanSpeed()'],['../classIRNeoclimaAc.html#a5d87285928bd8bfa2abad92fbdf384b5',1,'IRNeoclimaAc::toCommonFanSpeed()'],['../classIRPanasonicAc.html#a1eff8e4d670abc303a02d8baeeb58f8c',1,'IRPanasonicAc::toCommonFanSpeed()'],['../classIRSamsungAc.html#a2905b33c273d2be6cabfc3b16b51a5b4',1,'IRSamsungAc::toCommonFanSpeed()'],['../classIRSharpAc.html#a520666e591965b3b3b2421e06260976a',1,'IRSharpAc::toCommonFanSpeed()'],['../classIRTcl112Ac.html#a66843ee5b53ce9be1aef3774b8df5c84',1,'IRTcl112Ac::toCommonFanSpeed()'],['../classIRTecoAc.html#ac3ad2828770440695969d696ca6ff46d',1,'IRTecoAc::toCommonFanSpeed()'],['../classIRToshibaAC.html#a6c77121c9aba3928e676394f88e88dee',1,'IRToshibaAC::toCommonFanSpeed()'],['../classIRTrotecESP.html#a4aaf17993757533370290fffb728befc',1,'IRTrotecESP::toCommonFanSpeed()'],['../classIRVestelAc.html#a6dfd46f56f2d6b15344722cde0741500',1,'IRVestelAc::toCommonFanSpeed()'],['../classIRWhirlpoolAc.html#a61ef6661a985763540b7c2273b8b1b9c',1,'IRWhirlpoolAc::toCommonFanSpeed()']]], + ['tocommonmode_4322',['toCommonMode',['../classIRAmcorAc.html#a6da2f34f1e044f815e94ede578f4c26f',1,'IRAmcorAc::toCommonMode()'],['../classIRArgoAC.html#a8ccd3f5398f50548fda3a9e0172fb5fa',1,'IRArgoAC::toCommonMode()'],['../classIRCarrierAc64.html#ab17b24d0306b8983886d15175898909e',1,'IRCarrierAc64::toCommonMode()'],['../classIRCoolixAC.html#a789fb5d5eab2e78d392c8e0b9a194b18',1,'IRCoolixAC::toCommonMode()'],['../classIRCoronaAc.html#a04ca6532beb099893eb1dd5d01bb4d31',1,'IRCoronaAc::toCommonMode()'],['../classIRDaikinESP.html#a3a7543204520da36547c163a96e30deb',1,'IRDaikinESP::toCommonMode()'],['../classIRDaikin176.html#aa0b9c96d3bf08400a5110bcfa9f1ec9d',1,'IRDaikin176::toCommonMode()'],['../classIRDaikin128.html#a105a4fc511feba96afc956bb36d2dc50',1,'IRDaikin128::toCommonMode()'],['../classIRDaikin64.html#a80b9dd0fbf935bed5035463af2ad0102',1,'IRDaikin64::toCommonMode()'],['../classIRDelonghiAc.html#a5a3eef369009836a629369cf835741c4',1,'IRDelonghiAc::toCommonMode()'],['../classIRElectraAc.html#a01bd399c3b8908083b95f31d97ddb26f',1,'IRElectraAc::toCommonMode()'],['../classIRFujitsuAC.html#a96140e74d31631581003064f70041d02',1,'IRFujitsuAC::toCommonMode()'],['../classIRGoodweatherAc.html#ab3bcd1354b715179f67499c28fb219fb',1,'IRGoodweatherAc::toCommonMode()'],['../classIRGreeAC.html#a3f393071163fd1577c772a8515e2b5a9',1,'IRGreeAC::toCommonMode()'],['../classIRHaierAC.html#a4d73f75516afff0ef18bdbb7ed9c26ed',1,'IRHaierAC::toCommonMode()'],['../classIRHaierACYRW02.html#a24007a5be360c93ec157b95c8cc06493',1,'IRHaierACYRW02::toCommonMode()'],['../classIRHitachiAc.html#ab7edc0f5571100e1778779081e1c1114',1,'IRHitachiAc::toCommonMode()'],['../classIRHitachiAc1.html#a5cbca62775089593fe2447a77d84b3d5',1,'IRHitachiAc1::toCommonMode()'],['../classIRHitachiAc424.html#a2a725d8dc2178975c977a7496792e667',1,'IRHitachiAc424::toCommonMode()'],['../classIRKelvinatorAC.html#ae2683d38ae72b99e6843e37d36f96db2',1,'IRKelvinatorAC::toCommonMode()'],['../classIRLgAc.html#ac3436968a4445f0210403c353d766b73',1,'IRLgAc::toCommonMode()'],['../classIRMideaAC.html#ac2e0ff374678aadd7fea80194aef8bca',1,'IRMideaAC::toCommonMode()'],['../classIRMitsubishiAC.html#a7eae5da584faf41139be597d6a5e7210',1,'IRMitsubishiAC::toCommonMode()'],['../classIRMitsubishi136.html#a2771fd09b2e953b037c0c65c4e4029ee',1,'IRMitsubishi136::toCommonMode()'],['../classIRMitsubishi112.html#a6da77ebe6e03cfc09aa35e531c292ed1',1,'IRMitsubishi112::toCommonMode()'],['../classIRMitsubishiHeavy152Ac.html#a9faaff371ad3ec33de5646a1afd1992a',1,'IRMitsubishiHeavy152Ac::toCommonMode()'],['../classIRNeoclimaAc.html#a2a220b673c96e54e675d8296aa8b2303',1,'IRNeoclimaAc::toCommonMode()'],['../classIRPanasonicAc.html#a1ace0180b9ac3f4bd17357a03c64792e',1,'IRPanasonicAc::toCommonMode()'],['../classIRSamsungAc.html#a39820a05a9650e9da8a44109234a8d87',1,'IRSamsungAc::toCommonMode()'],['../classIRSharpAc.html#a5e8fca86bcf138bb7c1fd1b4e4384b5f',1,'IRSharpAc::toCommonMode()'],['../classIRTcl112Ac.html#a230a8d768089d869efdea6589b0a9e37',1,'IRTcl112Ac::toCommonMode()'],['../classIRTecoAc.html#ac6c7011b31208887de6d15edbffb211a',1,'IRTecoAc::toCommonMode()'],['../classIRToshibaAC.html#a77871a927ee67460b7bdcb8f204297bc',1,'IRToshibaAC::toCommonMode()'],['../classIRTrotecESP.html#a2b28b06bd25234427d90172b27d57092',1,'IRTrotecESP::toCommonMode()'],['../classIRVestelAc.html#add602c0f052c8ada3b3b5748dda50a58',1,'IRVestelAc::toCommonMode()'],['../classIRWhirlpoolAc.html#a748caa4e22f2f1f47e6334b1a031c4d8',1,'IRWhirlpoolAc::toCommonMode()']]], + ['tocommonswingh_4323',['toCommonSwingH',['../classIRDaikin2.html#a85bb152a4bdcc2798270ee58a3cfe2ae',1,'IRDaikin2::toCommonSwingH()'],['../classIRDaikin176.html#a6a3b66c9777992ed9fcab4e26c1d74dc',1,'IRDaikin176::toCommonSwingH()'],['../classIRHitachiAc344.html#a31562e32ccdf179032e75334b16279f0',1,'IRHitachiAc344::toCommonSwingH()'],['../classIRMitsubishiAC.html#ad7446e0a4ea8d349004c2b4224e69cd9',1,'IRMitsubishiAC::toCommonSwingH()'],['../classIRMitsubishi112.html#a17cfee6dc9ddc38465539ca46f29b263',1,'IRMitsubishi112::toCommonSwingH()'],['../classIRMitsubishiHeavy152Ac.html#afb9e039776c77e898928e9139a21a2b8',1,'IRMitsubishiHeavy152Ac::toCommonSwingH()'],['../classIRMitsubishiHeavy88Ac.html#aead69a01407729240055bd64e583b51b',1,'IRMitsubishiHeavy88Ac::toCommonSwingH()'],['../classIRPanasonicAc.html#aa4241990c350ca936c73b8391c2a11fc',1,'IRPanasonicAc::toCommonSwingH()']]], + ['tocommonswingv_4324',['toCommonSwingV',['../classIRDaikin2.html#a1f3e17757bd4beb0330d75ec3df9788b',1,'IRDaikin2::toCommonSwingV()'],['../classIRDaikin160.html#afae9b50e59c0efa46b96eef9f05a95b7',1,'IRDaikin160::toCommonSwingV()'],['../classIRGreeAC.html#a537d17801a90e22ad2baba7145b038cb',1,'IRGreeAC::toCommonSwingV()'],['../classIRHaierAC.html#aac354e2e4ad72d91667509398078b309',1,'IRHaierAC::toCommonSwingV()'],['../classIRHaierACYRW02.html#a0e426a3479fd80bb3816f016fac22f19',1,'IRHaierACYRW02::toCommonSwingV()'],['../classIRMitsubishiAC.html#a173e3c22f4173f235e7213e41925fdd9',1,'IRMitsubishiAC::toCommonSwingV()'],['../classIRMitsubishi136.html#aca5e6ac2d886083c8c56e2949f9d11e9',1,'IRMitsubishi136::toCommonSwingV()'],['../classIRMitsubishi112.html#a0e577d8554a090d7f2ac2a9ddd3bf15c',1,'IRMitsubishi112::toCommonSwingV()'],['../classIRMitsubishiHeavy152Ac.html#ae4dd9b8f0b5b4becb07618e859a09a51',1,'IRMitsubishiHeavy152Ac::toCommonSwingV()'],['../classIRMitsubishiHeavy88Ac.html#a0597303839e79c97b0fafe6c9ddbcf9a',1,'IRMitsubishiHeavy88Ac::toCommonSwingV()'],['../classIRPanasonicAc.html#adae801e0a2641c196a59d65c26404a13',1,'IRPanasonicAc::toCommonSwingV()']]], + ['togglerc5_4325',['toggleRC5',['../classIRsend.html#a42a78d4a3ef0f88b54bee488320344da',1,'IRsend']]], + ['togglerc6_4326',['toggleRC6',['../classIRsend.html#a5a0e8778394021ea12a8b8c2daf0add6',1,'IRsend']]], + ['toggleswinghoriz_4327',['toggleSwingHoriz',['../classIRFujitsuAC.html#aeba829bb9a9934ad9246a5ba4f4c03fc',1,'IRFujitsuAC']]], + ['toggleswingvert_4328',['toggleSwingVert',['../classIRFujitsuAC.html#a6dc9cc4bda83215fa97896c41b01e584',1,'IRFujitsuAC']]], + ['toshiba_4329',['toshiba',['../classIRac.html#a384e62cc56ebbdd790ebcd500ce56fc5',1,'IRac']]], + ['tostring_4330',['toString',['../classIRAmcorAc.html#a2435fd76c642e4a64c7e2330236dcaa6',1,'IRAmcorAc::toString()'],['../classIRArgoAC.html#ad9f52d54687754c0b8d676cb75a3b1bf',1,'IRArgoAC::toString()'],['../classIRCarrierAc64.html#acede081614a80ae46345d4ae45e39ab2',1,'IRCarrierAc64::toString()'],['../classIRCoolixAC.html#ad1282b4071f003ab35d2a97287ba6d2d',1,'IRCoolixAC::toString()'],['../classIRCoronaAc.html#a13e87d763ffd0d25a9d09010828c2124',1,'IRCoronaAc::toString()'],['../classIRDaikinESP.html#a38e705d3ed5128e400efd971e50518d5',1,'IRDaikinESP::toString()'],['../classIRDaikin2.html#a5804ef19f37ee7b8a525bc8db5146c73',1,'IRDaikin2::toString()'],['../classIRDaikin216.html#a5b9ea30424aa3abd9fdee95c78ba9e40',1,'IRDaikin216::toString()'],['../classIRDaikin160.html#a5d9ff2f09b95023c595e9c4794cb29b8',1,'IRDaikin160::toString()'],['../classIRDaikin176.html#a5ff8d589c7e97bd48b50e0ae01356783',1,'IRDaikin176::toString()'],['../classIRDaikin128.html#a48fc2a4080400f83260d2c861c831a28',1,'IRDaikin128::toString()'],['../classIRDaikin152.html#abb9253e8fe7e9bdf786246ce7ab8c54b',1,'IRDaikin152::toString()'],['../classIRDaikin64.html#aa19ba82f1dd405633f078eaf5cb915b8',1,'IRDaikin64::toString()'],['../classIRDelonghiAc.html#a386fb70137a7c2100d05f3202c224887',1,'IRDelonghiAc::toString()'],['../classIRElectraAc.html#a2b1f49b99ec17e211c6cc63d4f72f6a4',1,'IRElectraAc::toString()'],['../classIRFujitsuAC.html#ad779b8b86849ab4c6fe3cfc4afe2c7b8',1,'IRFujitsuAC::toString()'],['../classIRGoodweatherAc.html#a8c298ad0ab98789aa4eb419ed134ee03',1,'IRGoodweatherAc::toString()'],['../classIRGreeAC.html#a1f18b275e0e3d10fbc952d1da9613074',1,'IRGreeAC::toString()'],['../classIRHaierAC.html#a7effff64e7c9c20b7d9e6c2c10e0ffbc',1,'IRHaierAC::toString()'],['../classIRHaierACYRW02.html#a3858dd619f4ea4071b248bb5fb64fb08',1,'IRHaierACYRW02::toString()'],['../classIRHitachiAc.html#a9d927f191807b52fbd4f5d411e0c6519',1,'IRHitachiAc::toString()'],['../classIRHitachiAc1.html#ac70d5ed48897559d7e2ff0f843c79ddc',1,'IRHitachiAc1::toString()'],['../classIRHitachiAc424.html#abc1c122c68d62b582a7e38cdaf9febe7',1,'IRHitachiAc424::toString()'],['../classIRHitachiAc344.html#a5286ffe0ad72f82f66ad19bd6c3bdacc',1,'IRHitachiAc344::toString()'],['../classIRKelvinatorAC.html#a2cc438f41b6f4ed2f9df42acc1ffccfe',1,'IRKelvinatorAC::toString()'],['../classIRLgAc.html#a4546e2e0f63aac0bb9bd54f4f93c5f6c',1,'IRLgAc::toString()'],['../classIRMideaAC.html#a4980fbb52145e1d12a6fa5601f75018a',1,'IRMideaAC::toString()'],['../classIRMitsubishiAC.html#a28cfd4bb4d3372fb983f737c7e86b530',1,'IRMitsubishiAC::toString()'],['../classIRMitsubishi136.html#a8e49c540665a724c895674edef31d980',1,'IRMitsubishi136::toString()'],['../classIRMitsubishi112.html#ab99894eb185d13c5bd097c287fdbddeb',1,'IRMitsubishi112::toString()'],['../classIRMitsubishiHeavy152Ac.html#a9082e1498220f7b641f5f265d1131c0a',1,'IRMitsubishiHeavy152Ac::toString()'],['../classIRMitsubishiHeavy88Ac.html#a7c77e68371e70eb5fd565d8ac815950e',1,'IRMitsubishiHeavy88Ac::toString()'],['../classIRNeoclimaAc.html#a9e6a036411583bad6daf1ef2e60e013c',1,'IRNeoclimaAc::toString()'],['../classIRPanasonicAc.html#ada0b3e2bf11123d0a2f5df8692ae73ad',1,'IRPanasonicAc::toString()'],['../classIRSamsungAc.html#a82de7f9c7b4984f002ea3849b4e95ff2',1,'IRSamsungAc::toString()'],['../classIRSharpAc.html#afee9b0acec54d1683404b7af66c73046',1,'IRSharpAc::toString()'],['../classIRTcl112Ac.html#a381c019f805973000ac5ddb6c70e2773',1,'IRTcl112Ac::toString()'],['../classIRTecoAc.html#a7f085b545dac637927ae58fca13e5c5f',1,'IRTecoAc::toString()'],['../classIRToshibaAC.html#a5bbf6a725f496ac40ec2fac8f9a0dc1c',1,'IRToshibaAC::toString()'],['../classIRTrotecESP.html#a06783a7571b684be20ee5485f30ceb3c',1,'IRTrotecESP::toString()'],['../classIRVestelAc.html#a5fd0630ad7c1d5da3b1bfc5aefc443ec',1,'IRVestelAc::toString()'],['../classIRWhirlpoolAc.html#ad599025e8413f23d13a9783ff4c1fe93',1,'IRWhirlpoolAc::toString()']]], + ['trotec_4331',['trotec',['../classIRac.html#aed1a012c0546c2b1d53e86871a42ba1a',1,'IRac']]], + ['typetostring_4332',['typeToString',['../IRutils_8cpp.html#a9e98a1b929f36dfa75c2e325bf281cd1',1,'typeToString(const decode_type_t protocol, const bool isRepeat): IRutils.cpp'],['../IRutils_8h.html#a7f49135f3d160700eb12ff6b7309341c',1,'typeToString(const decode_type_t protocol, const bool isRepeat=false): IRutils.cpp']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_13.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_13.html new file mode 100644 index 000000000..f1fc553fe --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_13.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_13.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_13.js new file mode 100644 index 000000000..dab397642 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_13.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['uint64tostring_4333',['uint64ToString',['../IRutils_8cpp.html#a9f6ddef74b41ef6f8d2805fcfc396420',1,'uint64ToString(uint64_t input, uint8_t base): IRutils.cpp'],['../IRutils_8h.html#a781650451d38303e80da677539f574ee',1,'uint64ToString(uint64_t input, uint8_t base=10): IRutils.cpp']]], + ['uint8tobcd_4334',['uint8ToBcd',['../namespaceirutils.html#a534704a52b75acd46f687cc0a2b91bf1',1,'irutils']]], + ['updatesavedstate_4335',['updateSavedState',['../classIRCoolixAC.html#a1f39630b328939307bb08c18e56e9ad3',1,'IRCoolixAC']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_14.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_14.html new file mode 100644 index 000000000..0302cd989 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_14.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_14.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_14.js new file mode 100644 index 000000000..dd25196f9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_14.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['validchecksum_4336',['validChecksum',['../classIRAmcorAc.html#a1ad297a62ac3152c9d957cef38757d28',1,'IRAmcorAc::validChecksum()'],['../classIRArgoAC.html#acfa5a9df8273123e6f4c48684ef60006',1,'IRArgoAC::validChecksum()'],['../classIRCarrierAc64.html#affa23f178e079cd3a6c933240759fe80',1,'IRCarrierAc64::validChecksum()'],['../classIRDaikinESP.html#ad766e60827f80b96a66449bddc621d87',1,'IRDaikinESP::validChecksum()'],['../classIRDaikin2.html#ade5c0dbfe38d9ac0c4bc009c897af04d',1,'IRDaikin2::validChecksum()'],['../classIRDaikin216.html#a663c11977545ba01b34715a61a26ab88',1,'IRDaikin216::validChecksum()'],['../classIRDaikin160.html#a0d9f3af404e3b6c116e8c27e938f8479',1,'IRDaikin160::validChecksum()'],['../classIRDaikin176.html#abc97abc68f535f7ad801b393e0a795d5',1,'IRDaikin176::validChecksum()'],['../classIRDaikin128.html#ad0b16e48bff00c5cdeffa1419c003946',1,'IRDaikin128::validChecksum()'],['../classIRDaikin152.html#ade1c641eecea63857115fc20f1811fe7',1,'IRDaikin152::validChecksum()'],['../classIRDaikin64.html#ab04287881112ff21d1ea541c0f21b507',1,'IRDaikin64::validChecksum()'],['../classIRDelonghiAc.html#ae39b20bcea2b7090ac2e29d8cd28e5f6',1,'IRDelonghiAc::validChecksum()'],['../classIRElectraAc.html#a60034a18e7574844fb59a03e7789f419',1,'IRElectraAc::validChecksum()'],['../classIRFujitsuAC.html#a26153c647d127356e47d35a7456c6235',1,'IRFujitsuAC::validChecksum()'],['../classIRGreeAC.html#a74e7df0634f0a60110db8c033d9d5b1d',1,'IRGreeAC::validChecksum()'],['../classIRHaierAC.html#ad7aae554b8f0a76493efc2a43ac0f780',1,'IRHaierAC::validChecksum()'],['../classIRHaierACYRW02.html#a3f6d071d215b0316cccc2e94c4786954',1,'IRHaierACYRW02::validChecksum()'],['../classIRHitachiAc.html#a2549c1fd2e8a603eb8924fbba8b26e87',1,'IRHitachiAc::validChecksum()'],['../classIRHitachiAc1.html#aa6b7ab76567ee15aa08b1594c67bd29d',1,'IRHitachiAc1::validChecksum()'],['../classIRKelvinatorAC.html#aaa915fa5eb3f7e5c7a3dc143b6fda826',1,'IRKelvinatorAC::validChecksum()'],['../classIRLgAc.html#a51748fa24de24049a2fafb4590e84176',1,'IRLgAc::validChecksum()'],['../classIRMideaAC.html#a971ab4af0267bb732834e7e1f7b8e354',1,'IRMideaAC::validChecksum()'],['../classIRMitsubishiAC.html#ad74885e17434aa9038dc19ad74de4cd0',1,'IRMitsubishiAC::validChecksum()'],['../classIRMitsubishi136.html#a666d1268a93e96b50ac9012c09320de9',1,'IRMitsubishi136::validChecksum()'],['../classIRMitsubishiHeavy152Ac.html#abef94200719da0c14e211315ffc8bede',1,'IRMitsubishiHeavy152Ac::validChecksum()'],['../classIRMitsubishiHeavy88Ac.html#aabd9d8f81108f20f1d7adff3ac6c2fd4',1,'IRMitsubishiHeavy88Ac::validChecksum()'],['../classIRNeoclimaAc.html#a32e4b4444e0a97b6da4447e977f74f94',1,'IRNeoclimaAc::validChecksum()'],['../classIRPanasonicAc.html#a6a084754596f7840dd308041d11a822d',1,'IRPanasonicAc::validChecksum()'],['../classIRSamsungAc.html#a4f7339bce78ce2b656fc597b4c88db22',1,'IRSamsungAc::validChecksum()'],['../classIRSharpAc.html#acb7fb0ac19e09da02d36cb73c808420d',1,'IRSharpAc::validChecksum()'],['../classIRTcl112Ac.html#a204bc37ffadf72ed31b305197c4803f4',1,'IRTcl112Ac::validChecksum()'],['../classIRToshibaAC.html#adc7c1eee14e4de896121ad06e88b61eb',1,'IRToshibaAC::validChecksum()'],['../classIRTrotecESP.html#ae08748e33ed12c536b18f6d0dc4da1c7',1,'IRTrotecESP::validChecksum()'],['../classIRVestelAc.html#ad3bcc08fb4242af7dcc65e534816a219',1,'IRVestelAc::validChecksum()'],['../classIRWhirlpoolAc.html#a2d891069ebdecc62b03e8c92befa15c6',1,'IRWhirlpoolAc::validChecksum()']]], + ['validsection_4337',['validSection',['../classIRCoronaAc.html#af36894d88e7fb45affc883ba0b077862',1,'IRCoronaAc']]], + ['vestel_4338',['vestel',['../classIRac.html#a9b1cd1a4d44bc56e62128b9dbc178bba',1,'IRac']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_15.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_15.html new file mode 100644 index 000000000..18cf76b24 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_15.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_15.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_15.js new file mode 100644 index 000000000..21b364b8b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_15.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['whirlpool_4339',['whirlpool',['../classIRac.html#ae5f7a03589f614c03c5ad8629100b05a',1,'IRac']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_16.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_16.html new file mode 100644 index 000000000..9182391d2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_16.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_16.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_16.js new file mode 100644 index 000000000..a9612ad4b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_16.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['xorbytes_4340',['xorBytes',['../IRutils_8cpp.html#aaa2a3fb714375e61051a0b24623b9cc9',1,'xorBytes(const uint8_t *const start, const uint16_t length, const uint8_t init): IRutils.cpp'],['../IRutils_8h.html#ab030689a93499311ee8e6621ac8757aa',1,'xorBytes(const uint8_t *const start, const uint16_t length, const uint8_t init=0): IRutils.cpp']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_17.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_17.html new file mode 100644 index 000000000..807950604 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_17.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_17.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_17.js new file mode 100644 index 000000000..4d4a5aec2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_17.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['_7eirrecv_4341',['~IRrecv',['../classIRrecv.html#a87d4cca5e350177cb0922842dda1eb5b',1,'IRrecv']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_2.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_2.html new file mode 100644 index 000000000..2737c5ac1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_2.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_2.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_2.js new file mode 100644 index 000000000..42aa9fc12 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_2.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['bcdtouint8_3719',['bcdToUint8',['../namespaceirutils.html#af18c4abfd0ed9f4b3a099ecec1999ee7',1,'irutils']]], + ['begin_3720',['begin',['../classIRAmcorAc.html#aa723533eea981f79844f241d5bb84654',1,'IRAmcorAc::begin()'],['../classIRArgoAC.html#aca61a63c37797699540c180354809bd8',1,'IRArgoAC::begin()'],['../classIRCarrierAc64.html#a7d9800edffad8a529971535ada5c00ad',1,'IRCarrierAc64::begin()'],['../classIRCoolixAC.html#a506a5ab28865d0243d75ebb7fe62e4ea',1,'IRCoolixAC::begin()'],['../classIRCoronaAc.html#a7db1a8eb9c3c7f76091b2707458e54a9',1,'IRCoronaAc::begin()'],['../classIRDaikinESP.html#accd087c48f246a71898cc6fd7afc2cc7',1,'IRDaikinESP::begin()'],['../classIRDaikin2.html#a6a7b5c28feec523ee81e99a9c32da26e',1,'IRDaikin2::begin()'],['../classIRDaikin216.html#a95be01fb6e672ebd12f2ebca0406ba15',1,'IRDaikin216::begin()'],['../classIRDaikin160.html#a62bb5f66cd99711e388eaa1be9faf617',1,'IRDaikin160::begin()'],['../classIRDaikin176.html#aa742f7d9ae3c9e57cae0e471d7fe59d1',1,'IRDaikin176::begin()'],['../classIRDaikin128.html#af86dba9e085b771c8c3caaebb9f8ee84',1,'IRDaikin128::begin()'],['../classIRDaikin152.html#a2746854350ca7d3a71699439f9843381',1,'IRDaikin152::begin()'],['../classIRDaikin64.html#a291d5f702b4ce763507c731db08b48f2',1,'IRDaikin64::begin()'],['../classIRDelonghiAc.html#a8d5e4f95e929c2365b2be47f42c6328c',1,'IRDelonghiAc::begin()'],['../classIRElectraAc.html#afff519ff9e81ec4aa03ff337f8efef13',1,'IRElectraAc::begin()'],['../classIRFujitsuAC.html#af0dc3fffdafae5970bc367f31029464b',1,'IRFujitsuAC::begin()'],['../classIRGoodweatherAc.html#abace3c8b25d4737a83fe33f94fc741d9',1,'IRGoodweatherAc::begin()'],['../classIRGreeAC.html#a44cf8f0e09248741094af4b35321ab1c',1,'IRGreeAC::begin()'],['../classIRHaierAC.html#ab92fd48ccb5707cb6d14e9d46ce42e17',1,'IRHaierAC::begin()'],['../classIRHaierACYRW02.html#addc01e60e8c4045fab6f22c852eb620f',1,'IRHaierACYRW02::begin()'],['../classIRHitachiAc.html#a62817c840f352bb01a394c37fc95f0f0',1,'IRHitachiAc::begin()'],['../classIRHitachiAc1.html#a28d5d351003d3e0bc1506b06cac8b3d6',1,'IRHitachiAc1::begin()'],['../classIRHitachiAc424.html#a11866bba49e9b976eb22b1039787ecae',1,'IRHitachiAc424::begin()'],['../classIRHitachiAc3.html#a6d79ac7b8ce977e8059019349d6991a7',1,'IRHitachiAc3::begin()'],['../classIRKelvinatorAC.html#a4591bf4e8131aa2a228cbc611156e7f4',1,'IRKelvinatorAC::begin()'],['../classIRLgAc.html#ac08ada1c67ace5ee2ebe4d325aa8c25d',1,'IRLgAc::begin()'],['../classIRMideaAC.html#ac36b6aa76b6b98ab186cd1d5ad9246b4',1,'IRMideaAC::begin()'],['../classIRMitsubishiAC.html#aa6e58080fd811f5b6d0f90c4ef5917df',1,'IRMitsubishiAC::begin()'],['../classIRMitsubishi136.html#abbcd8307862beee2899d2b9900537520',1,'IRMitsubishi136::begin()'],['../classIRMitsubishi112.html#a1d00958556872286b1818d0dbf02e112',1,'IRMitsubishi112::begin()'],['../classIRMitsubishiHeavy152Ac.html#afd649a53d9f7d9b31b7a5732d6cd0857',1,'IRMitsubishiHeavy152Ac::begin()'],['../classIRMitsubishiHeavy88Ac.html#a9bcf18c942ad4df4856bd319215a2002',1,'IRMitsubishiHeavy88Ac::begin()'],['../classIRNeoclimaAc.html#a8f82159b94d86cc4e3d4719441bfa96e',1,'IRNeoclimaAc::begin()'],['../classIRPanasonicAc.html#af48075dc4eb84fcc7f718375d4b0e00a',1,'IRPanasonicAc::begin()'],['../classIRSamsungAc.html#a89f1f902042cd6c6ba9d0f0c6d2cc581',1,'IRSamsungAc::begin()'],['../classIRSharpAc.html#ab87e5b599b7e8fc387fff25b5e13e34f',1,'IRSharpAc::begin()'],['../classIRTcl112Ac.html#a5b9983ab4027951679f0dc31b33cbadf',1,'IRTcl112Ac::begin()'],['../classIRTecoAc.html#a3b23a8556686c83b146101fc31b0dff3',1,'IRTecoAc::begin()'],['../classIRToshibaAC.html#a41e847f399e42c91b0f4aa2ef5d36cba',1,'IRToshibaAC::begin()'],['../classIRTrotecESP.html#a093b874287adb8ef2cc60c832765ff58',1,'IRTrotecESP::begin()'],['../classIRVestelAc.html#a794808d49eb6ce1521ff800b2b15a580',1,'IRVestelAc::begin()'],['../classIRWhirlpoolAc.html#a21db8b31504d416efb2511a33bdc2209',1,'IRWhirlpoolAc::begin()'],['../classIRsend.html#a386f026bf739b0718efde4cffa6ce129',1,'IRsend::begin()']]], + ['booltostring_3721',['boolToString',['../classIRac.html#a9bbd9e6b72e82a752df56e8c489668cf',1,'IRac']]], + ['buildfromstate_3722',['buildFromState',['../classIRFujitsuAC.html#a6fc8d7d0f649185e0858974394636a8d',1,'IRFujitsuAC']]], + ['buildstate_3723',['buildState',['../classIRFujitsuAC.html#ac885c7952253fcee9bf5b4a889b54da9',1,'IRFujitsuAC']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_3.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_3.html new file mode 100644 index 000000000..6da86e7da --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_3.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_3.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_3.js new file mode 100644 index 000000000..0498304c7 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_3.js @@ -0,0 +1,34 @@ +var searchData= +[ + ['calcblockchecksum_3724',['calcBlockChecksum',['../classIRKelvinatorAC.html#a22f561397c526ed6cc3f69a5d527d8d6',1,'IRKelvinatorAC']]], + ['calcchecksum_3725',['calcChecksum',['../classIRAmcorAc.html#aec764cf4d88bb3fcbe3f36d24780f6a9',1,'IRAmcorAc::calcChecksum()'],['../classIRArgoAC.html#acab2fe3b9f77f57f0e99da0bec0d7392',1,'IRArgoAC::calcChecksum()'],['../classIRCarrierAc64.html#a20676dcf4b0a6510cc3bce282fbf8504',1,'IRCarrierAc64::calcChecksum()'],['../classIRDaikin64.html#ac29c18fde1b0cd98991e68c0f672d0e9',1,'IRDaikin64::calcChecksum()'],['../classIRDelonghiAc.html#a14d7629bb888deb02e83886191f44c2d',1,'IRDelonghiAc::calcChecksum()'],['../classIRElectraAc.html#aa8063d07e41ca2cc0fd27093a2e67bb2',1,'IRElectraAc::calcChecksum()'],['../classIRHitachiAc.html#a6e5da77c12ad105439eb159b6a58104a',1,'IRHitachiAc::calcChecksum()'],['../classIRHitachiAc1.html#a6995513d5b59cd7b14cfff39c8843e8d',1,'IRHitachiAc1::calcChecksum()'],['../classIRLgAc.html#a96024e736cf87e65b4e2db7c4c269520',1,'IRLgAc::calcChecksum()'],['../classIRMideaAC.html#ac8733348b311ecf8eed87021cdf4ee31',1,'IRMideaAC::calcChecksum()'],['../classIRNeoclimaAc.html#ac75f316cd1813cdb4e8a6d45d10ddd57',1,'IRNeoclimaAc::calcChecksum()'],['../classIRPanasonicAc.html#a0e38b0f3c54e49cdb59f92279e19840f',1,'IRPanasonicAc::calcChecksum()'],['../classIRSamsungAc.html#a00f9b2a1480d2ed45bdea5d236c77d0f',1,'IRSamsungAc::calcChecksum()'],['../classIRSharpAc.html#af3655c9c394b1391572e8ffab70881ff',1,'IRSharpAc::calcChecksum()'],['../classIRTcl112Ac.html#a0973a1c8a53661ee7720ecb5d08e6dcc',1,'IRTcl112Ac::calcChecksum()'],['../classIRToshibaAC.html#a0d91d32d0d9d722f750eb423d88509f4',1,'IRToshibaAC::calcChecksum()'],['../classIRTrotecESP.html#ac1fdbcbbb8dd1ca50ccf2b55c7281c89',1,'IRTrotecESP::calcChecksum()'],['../classIRVestelAc.html#ac0ba3de4de70350c5325b3d5e0b39e58',1,'IRVestelAc::calcChecksum()']]], + ['calcfirstchecksum_3726',['calcFirstChecksum',['../classIRDaikin128.html#a25b25f6b73bb5f1fd17a16080179d4bc',1,'IRDaikin128']]], + ['calcsecondchecksum_3727',['calcSecondChecksum',['../classIRDaikin128.html#aea8da64300afe0d62ddf3082a72251f2',1,'IRDaikin128']]], + ['calculatechecksum_3728',['calculateChecksum',['../classIRMitsubishiAC.html#aaadefc5880dcd48e3fb2f12b59101f71',1,'IRMitsubishiAC']]], + ['calcusecperiod_3729',['calcUSecPeriod',['../classIRsend.html#ae9e68c0ed22e27c8f7ff82cec7ca3e33',1,'IRsend']]], + ['calibrate_3730',['calibrate',['../classIRAmcorAc.html#a6206e866e859bc4690cb014c49c1ff80',1,'IRAmcorAc::calibrate()'],['../classIRArgoAC.html#a63cd2f350a7f249c020439543ef3c6d5',1,'IRArgoAC::calibrate()'],['../classIRCarrierAc64.html#a0718376156750e66f98ea0549c75b21b',1,'IRCarrierAc64::calibrate()'],['../classIRCoolixAC.html#a9e39ce5050888210d6ba9b79ae3763e3',1,'IRCoolixAC::calibrate()'],['../classIRCoronaAc.html#a5b10141e4a6e3d8511fb7f9f46d00a96',1,'IRCoronaAc::calibrate()'],['../classIRDaikinESP.html#a638a49f49275a2ab0affb09088794e1b',1,'IRDaikinESP::calibrate()'],['../classIRDaikin2.html#a96c62125bddf113c6524960062d05a57',1,'IRDaikin2::calibrate()'],['../classIRDaikin216.html#a49d7501966528c0a690cfb505f163e26',1,'IRDaikin216::calibrate()'],['../classIRDaikin160.html#a608b5556f316c31e3a8aa73684e4e10d',1,'IRDaikin160::calibrate()'],['../classIRDaikin176.html#a1f5989110782c18aa18e3757c50f4a31',1,'IRDaikin176::calibrate()'],['../classIRDaikin128.html#a281396f4c632899648694e3139c3acd0',1,'IRDaikin128::calibrate()'],['../classIRDaikin152.html#a82fa8bfb3384ed09473345b6e194c3ba',1,'IRDaikin152::calibrate()'],['../classIRDaikin64.html#a12a1e21ba1b06f9b3ffac56691ff2206',1,'IRDaikin64::calibrate()'],['../classIRDelonghiAc.html#aab8f78adcd7fcbea0be753a4fc7696e0',1,'IRDelonghiAc::calibrate()'],['../classIRElectraAc.html#af333e90117ab035ff92389d4eefb3649',1,'IRElectraAc::calibrate()'],['../classIRFujitsuAC.html#a8bb6d8456561dfb04ccac95e0e489558',1,'IRFujitsuAC::calibrate()'],['../classIRGoodweatherAc.html#a8a747144587cf38d64bb32a7f86432b3',1,'IRGoodweatherAc::calibrate()'],['../classIRGreeAC.html#a8069d00a16ed04fd6fa10d84b364bca7',1,'IRGreeAC::calibrate()'],['../classIRHaierAC.html#a448b1d5db05f7722db4758e968ea3171',1,'IRHaierAC::calibrate()'],['../classIRHaierACYRW02.html#a2081b29d0526e339a6b94fc41c854197',1,'IRHaierACYRW02::calibrate()'],['../classIRHitachiAc.html#aaabd743da491ef5d73c4b8c46f11241a',1,'IRHitachiAc::calibrate()'],['../classIRHitachiAc1.html#a847a26df2e19668b147cba2eef595a21',1,'IRHitachiAc1::calibrate()'],['../classIRHitachiAc424.html#aae5e5c13767f335331c5fab8d8ba55d6',1,'IRHitachiAc424::calibrate()'],['../classIRHitachiAc3.html#a02e065c08f9ec4a3d9e6f71432087595',1,'IRHitachiAc3::calibrate()'],['../classIRKelvinatorAC.html#aee8863c1678b09432618bb4ca734db95',1,'IRKelvinatorAC::calibrate()'],['../classIRLgAc.html#a4fd11e935c781319b29f606f2f4b2570',1,'IRLgAc::calibrate()'],['../classIRMideaAC.html#a4077604c2af56783f95a0a64eda7148b',1,'IRMideaAC::calibrate()'],['../classIRMitsubishiAC.html#a973c876e34942776ac98f27de96c5228',1,'IRMitsubishiAC::calibrate()'],['../classIRMitsubishi136.html#a76133542efc3763cb7edc9809ad8d93c',1,'IRMitsubishi136::calibrate()'],['../classIRMitsubishi112.html#ad148250070a3f4ac57ed6cb957ffdefb',1,'IRMitsubishi112::calibrate()'],['../classIRMitsubishiHeavy152Ac.html#a5d4c4ce0e69ed33a2f1db2af127c13c5',1,'IRMitsubishiHeavy152Ac::calibrate()'],['../classIRMitsubishiHeavy88Ac.html#a027423ffbee92ef65b02423f7cbaeca8',1,'IRMitsubishiHeavy88Ac::calibrate()'],['../classIRNeoclimaAc.html#a636dd97ca22c847f966eca8112c8eede',1,'IRNeoclimaAc::calibrate()'],['../classIRPanasonicAc.html#a3f850333f2aa7ce40856c99ef85ffd79',1,'IRPanasonicAc::calibrate()'],['../classIRSamsungAc.html#a5cc7486ae41f61cbe0bb053dd7c9e9e3',1,'IRSamsungAc::calibrate()'],['../classIRSharpAc.html#ac37b1a5679ce90e84f6f95c5df1526bb',1,'IRSharpAc::calibrate()'],['../classIRTcl112Ac.html#a435744e4c6ef31b362d15523ce0584f5',1,'IRTcl112Ac::calibrate()'],['../classIRTecoAc.html#ad700578cbae74857483372597a399ff3',1,'IRTecoAc::calibrate()'],['../classIRToshibaAC.html#a74c66bba288cb3cbb43008edb7b376bf',1,'IRToshibaAC::calibrate()'],['../classIRTrotecESP.html#a56de318a27011e0bddb40738c18dbcf2',1,'IRTrotecESP::calibrate()'],['../classIRVestelAc.html#aae91667d96d86de824a20c256c311f15',1,'IRVestelAc::calibrate()'],['../classIRWhirlpoolAc.html#a006c59c1c84c62fccd3730bec30ef5e8',1,'IRWhirlpoolAc::calibrate()'],['../classIRsend.html#ad1776aa6c699f9eeca1eef9bb4fe355b',1,'IRsend::calibrate()']]], + ['cancelofftimer_3731',['cancelOffTimer',['../classIRPanasonicAc.html#a6d202284320c59205cb0d02cb613cada',1,'IRPanasonicAc']]], + ['cancelontimer_3732',['cancelOnTimer',['../classIRPanasonicAc.html#a102e7c029a923e121e40326859f2e4a3',1,'IRPanasonicAc']]], + ['canceltimers_3733',['cancelTimers',['../classIRHaierAC.html#a1cccc733f74232751f95c32e47795638',1,'IRHaierAC']]], + ['carrier64_3734',['carrier64',['../classIRac.html#a8090f2d79a31b81a0342b2e9efb9d555',1,'IRac']]], + ['celsiustofahrenheit_3735',['celsiusToFahrenheit',['../IRutils_8cpp.html#a19b940e26a4f8ddcaf86cce1ec62d563',1,'celsiusToFahrenheit(const float deg): IRutils.cpp'],['../IRutils_8h.html#a19b940e26a4f8ddcaf86cce1ec62d563',1,'celsiusToFahrenheit(const float deg): IRutils.cpp']]], + ['checksum_3736',['checksum',['../classIRAmcorAc.html#a67244a75731be6a3bd96ecc0384d0113',1,'IRAmcorAc::checksum()'],['../classIRArgoAC.html#ab0fe4e42d1c1201a92f5c4738b869763',1,'IRArgoAC::checksum()'],['../classIRCarrierAc64.html#a005fab56acf94fe97db7fa92651b2882',1,'IRCarrierAc64::checksum()'],['../classIRCoronaAc.html#ae0257fdafacf7fd2e7ac6ca3f8ae3168',1,'IRCoronaAc::checksum()'],['../classIRDaikinESP.html#ac8ac2a0674dc5cfaf514d319b51b20ab',1,'IRDaikinESP::checksum()'],['../classIRDaikin2.html#abb8e4ad1f8c3ada4211541e5a6e23e64',1,'IRDaikin2::checksum()'],['../classIRDaikin216.html#af2c951901b3b9db9f285a4e9b563ea5e',1,'IRDaikin216::checksum()'],['../classIRDaikin160.html#a34090a598e2b25ee4688c8fbac933638',1,'IRDaikin160::checksum()'],['../classIRDaikin176.html#a4cfe2c4ca95adbf66e149b322d58a843',1,'IRDaikin176::checksum()'],['../classIRDaikin128.html#a747c906808c269581de6cf9b02e5c0a7',1,'IRDaikin128::checksum()'],['../classIRDaikin152.html#a0e208d3e1938abcb320665fffd6ed0e3',1,'IRDaikin152::checksum()'],['../classIRDaikin64.html#a27e2f82b2f13f1e63e981af8f1d3912a',1,'IRDaikin64::checksum()'],['../classIRDelonghiAc.html#ae4c4e7140a763eee159991f5c8afc54f',1,'IRDelonghiAc::checksum()'],['../classIRElectraAc.html#a73dc5b9a038669cc1f00f5b64ad458d1',1,'IRElectraAc::checksum()'],['../classIRGreeAC.html#aaa6b2702d79a7a3db454b99d71064679',1,'IRGreeAC::checksum()'],['../classIRHaierAC.html#ab7faae274ff7f30bf7df3c58d6e7e210',1,'IRHaierAC::checksum()'],['../classIRHaierACYRW02.html#a18045defdd5641ae13c7c75dda0cf23a',1,'IRHaierACYRW02::checksum()'],['../classIRHitachiAc.html#a3b65ccbd6de6b5dcb5a794b471e363f5',1,'IRHitachiAc::checksum()'],['../classIRHitachiAc1.html#aa6687d6282b134d508d6534e8446b341',1,'IRHitachiAc1::checksum()'],['../classIRKelvinatorAC.html#a09acf66b92d3fde6692ec02ff8e62dab',1,'IRKelvinatorAC::checksum()'],['../classIRLgAc.html#a438cbbb77668205c3f2b59b8f28585cd',1,'IRLgAc::checksum()'],['../classIRMideaAC.html#a418b7cbb4b388dba732176d891bb499d',1,'IRMideaAC::checksum()'],['../classIRMitsubishiAC.html#a7c5b1e5c53d99f1564d8a0424f626adb',1,'IRMitsubishiAC::checksum()'],['../classIRMitsubishi136.html#aa2c6fe9b28462052cf6627960126a783',1,'IRMitsubishi136::checksum()'],['../classIRMitsubishi112.html#a65ee232bfc09d05724b8ec5ada538ccf',1,'IRMitsubishi112::checksum()'],['../classIRMitsubishiHeavy152Ac.html#a14cdcaeefef283f707d0fae5108d65f4',1,'IRMitsubishiHeavy152Ac::checksum()'],['../classIRMitsubishiHeavy88Ac.html#acb03ef0da10d3fec14c71bfa087a02b8',1,'IRMitsubishiHeavy88Ac::checksum()'],['../classIRNeoclimaAc.html#acba18ea35a59f6f1ccbcfd75e7979feb',1,'IRNeoclimaAc::checksum()'],['../classIRSamsungAc.html#a75c5886916dd3ef3aa6f96f04934048d',1,'IRSamsungAc::checksum()'],['../classIRSharpAc.html#ad87f46ad9220213d77022dc34920d802',1,'IRSharpAc::checksum()'],['../classIRTcl112Ac.html#a2486f46c7db6a3dfbe3af9c842ff37fa',1,'IRTcl112Ac::checksum()'],['../classIRToshibaAC.html#a5aa2c6fc3b07830f872f98906df7e9ec',1,'IRToshibaAC::checksum()'],['../classIRTrotecESP.html#a5e416e083653ab365f65b3f645f60e8c',1,'IRTrotecESP::checksum()'],['../classIRVestelAc.html#a7a9046e7b5ff57864862bf5f7ad23c4d',1,'IRVestelAc::checksum()'],['../classIRWhirlpoolAc.html#a7790be3df6c4609e5c08c17c5ee52047',1,'IRWhirlpoolAc::checksum()']]], + ['checkzjssig_3737',['checkZjsSig',['../classIRMitsubishiHeavy88Ac.html#a6aaf8ae4c9b52d73229b20414099f309',1,'IRMitsubishiHeavy88Ac']]], + ['checkzmssig_3738',['checkZmsSig',['../classIRMitsubishiHeavy152Ac.html#a3d1c9d2c98945d21eb1ce82fac1771d2',1,'IRMitsubishiHeavy152Ac']]], + ['cleanstate_3739',['cleanState',['../classIRac.html#aad988dc123495012758307213a933f37',1,'IRac']]], + ['clearontimerflag_3740',['clearOnTimerFlag',['../classIRDaikin2.html#a3587ce954ba94e347d08d73974b50d72',1,'IRDaikin2::clearOnTimerFlag()'],['../classIRDaikin128.html#a8f0bd823535a5bf8b2642eed698b9a71',1,'IRDaikin128::clearOnTimerFlag()']]], + ['clearpowerspecial_3741',['clearPowerSpecial',['../classIRSharpAc.html#a3c98c96a66dff560941e461a70efdb1a',1,'IRSharpAc']]], + ['clearsensortemp_3742',['clearSensorTemp',['../classIRCoolixAC.html#a5deca09ced33931f089f5cd3c07eac4a',1,'IRCoolixAC']]], + ['clearsleeptimerflag_3743',['clearSleepTimerFlag',['../classIRDaikin2.html#a0c165ff91a712e61910ef25e9728e066',1,'IRDaikin2::clearSleepTimerFlag()'],['../classIRDaikin128.html#a5517a481892dd55f4528103037a0d408',1,'IRDaikin128::clearSleepTimerFlag()']]], + ['cmpstates_3744',['cmpStates',['../classIRac.html#a3ba4eee08650dfcdd6d492a67c86f016',1,'IRac']]], + ['compare_3745',['compare',['../classIRrecv.html#ad7347c72b14d9f2f20f65bcf235ab3dc',1,'IRrecv']]], + ['convertfan_3746',['convertFan',['../classIRAmcorAc.html#ad0f8b7cdf5942c3680639d410f53d18c',1,'IRAmcorAc::convertFan()'],['../classIRArgoAC.html#acd147993fb998a0e7015173b9514d4a2',1,'IRArgoAC::convertFan()'],['../classIRCarrierAc64.html#a255e6679397434877f1c6c9ac70fff50',1,'IRCarrierAc64::convertFan()'],['../classIRCoolixAC.html#a7ffa1cfcf82bd905b0f607401200c895',1,'IRCoolixAC::convertFan()'],['../classIRCoronaAc.html#a6826036fcabbb45e7369f42912fae02f',1,'IRCoronaAc::convertFan()'],['../classIRDaikinESP.html#ab58be19636d41d60b9c62d658ca18cae',1,'IRDaikinESP::convertFan()'],['../classIRDaikin2.html#ad147ea14695c9498bb091862e172dc81',1,'IRDaikin2::convertFan()'],['../classIRDaikin216.html#a520cc65161290f15022b4108f7049a83',1,'IRDaikin216::convertFan()'],['../classIRDaikin160.html#a32658c0f24d0b0c398d54ef648d717a9',1,'IRDaikin160::convertFan()'],['../classIRDaikin176.html#ae3dda9a55f851b5253d0677835a2c3dd',1,'IRDaikin176::convertFan()'],['../classIRDaikin128.html#a983c13bc608fbfa32d7ea2c36dc84116',1,'IRDaikin128::convertFan()'],['../classIRDaikin152.html#a5e2e79252602ca3493baf00cf3fe7787',1,'IRDaikin152::convertFan()'],['../classIRDaikin64.html#a109ff0c33b0a7dfd763683538915c811',1,'IRDaikin64::convertFan()'],['../classIRDelonghiAc.html#aeff2970b20963ae59b99464ae683113f',1,'IRDelonghiAc::convertFan()'],['../classIRElectraAc.html#afcf3ef62d69e370cb88dd2036e5a1357',1,'IRElectraAc::convertFan()'],['../classIRFujitsuAC.html#a111060b7c93e77fdbd1dc96fc8a6c10f',1,'IRFujitsuAC::convertFan()'],['../classIRGoodweatherAc.html#abb443826453a65e87f6dedddf2dd74d5',1,'IRGoodweatherAc::convertFan()'],['../classIRGreeAC.html#a39aa0e4759330aef39382813d3aa96a4',1,'IRGreeAC::convertFan()'],['../classIRHaierAC.html#a58628dd19a7247fc5358c0dc8c30baba',1,'IRHaierAC::convertFan()'],['../classIRHaierACYRW02.html#a66e42d018f3d86b136624a347d333401',1,'IRHaierACYRW02::convertFan()'],['../classIRHitachiAc.html#a5c632c9efc42d9378fdefe608c9bb771',1,'IRHitachiAc::convertFan()'],['../classIRHitachiAc1.html#a96c22fddcd7dfcc5b8f205cc5c7efdef',1,'IRHitachiAc1::convertFan()'],['../classIRHitachiAc424.html#a4f502b779f9fe4aca3a2f649c4cfbda3',1,'IRHitachiAc424::convertFan()'],['../classIRLgAc.html#a71ce8d1be4222ecae26fcea3b71a1ba6',1,'IRLgAc::convertFan()'],['../classIRMideaAC.html#a08a8e49986ce808fd7edd8aee7399a64',1,'IRMideaAC::convertFan()'],['../classIRMitsubishiAC.html#a58ce95e1ae198a9855ee5e81335570cf',1,'IRMitsubishiAC::convertFan()'],['../classIRMitsubishi136.html#a81e691b386950859d1ad0a3c7faf7e49',1,'IRMitsubishi136::convertFan()'],['../classIRMitsubishi112.html#a4194e5b076687b79153bc8cd50c9bc86',1,'IRMitsubishi112::convertFan()'],['../classIRMitsubishiHeavy152Ac.html#ae11040290301b5fe66dfe79e8ea9512b',1,'IRMitsubishiHeavy152Ac::convertFan()'],['../classIRMitsubishiHeavy88Ac.html#acd69c45dbc3f5a150e17b82b5eae7b3f',1,'IRMitsubishiHeavy88Ac::convertFan()'],['../classIRNeoclimaAc.html#a8c3ac622428f118b28d53a3a82740993',1,'IRNeoclimaAc::convertFan()'],['../classIRPanasonicAc.html#aeada51b2d1ff51ff81dfc5c996b416df',1,'IRPanasonicAc::convertFan()'],['../classIRSamsungAc.html#a6be52cc6980ad0bf80261c2a48eb3c87',1,'IRSamsungAc::convertFan()'],['../classIRSharpAc.html#a9b58f12bc44639694a8422a2b9b78a88',1,'IRSharpAc::convertFan()'],['../classIRTcl112Ac.html#a3f8178f8f646ed9892eefa40bbff4fb1',1,'IRTcl112Ac::convertFan()'],['../classIRTecoAc.html#a262aead12607ff962dd97c73e6dea078',1,'IRTecoAc::convertFan()'],['../classIRToshibaAC.html#aeef5cfb840f3058629b486232b7efb22',1,'IRToshibaAC::convertFan()'],['../classIRTrotecESP.html#a905d4d5bd298db8c2e1a9b004fd541e8',1,'IRTrotecESP::convertFan()'],['../classIRVestelAc.html#aa7702b0e50b6c8073cd7740a630b19dd',1,'IRVestelAc::convertFan()'],['../classIRWhirlpoolAc.html#a3004feef0ec5fe327d6a43d68d029377',1,'IRWhirlpoolAc::convertFan()']]], + ['convertmode_3747',['convertMode',['../classIRAmcorAc.html#ab57117e1072b5265ac9ab5be6d58bccc',1,'IRAmcorAc::convertMode()'],['../classIRArgoAC.html#ad242e7b18dea9768b9fad6b1e0e12f65',1,'IRArgoAC::convertMode()'],['../classIRCarrierAc64.html#a8e94b1526b26cec55f1e700c86aaf74e',1,'IRCarrierAc64::convertMode()'],['../classIRCoolixAC.html#acfb0d2c20322cb4d3cd681a3a54b30fe',1,'IRCoolixAC::convertMode()'],['../classIRCoronaAc.html#a9f9cf8e38285cb2f3caf79e14516bda1',1,'IRCoronaAc::convertMode()'],['../classIRDaikinESP.html#aa96f52596148cab1f806faf190a0aa0a',1,'IRDaikinESP::convertMode()'],['../classIRDaikin2.html#a10aae6ec9783eac9d89ff98b947767dd',1,'IRDaikin2::convertMode()'],['../classIRDaikin216.html#a4fa9eca71ee6ad66b3fffd8b779f5fb0',1,'IRDaikin216::convertMode()'],['../classIRDaikin160.html#ac69861fdbde341fc75d90a5e4918aa56',1,'IRDaikin160::convertMode()'],['../classIRDaikin176.html#ab07fd6eab0ac6132625a291dae8cfc78',1,'IRDaikin176::convertMode()'],['../classIRDaikin128.html#a0bad4830267887299b2773075a16b283',1,'IRDaikin128::convertMode()'],['../classIRDaikin152.html#a25592419c95c0271d8a0c4203a2919c3',1,'IRDaikin152::convertMode()'],['../classIRDaikin64.html#a595d91c0294c9482aa453f077eebf882',1,'IRDaikin64::convertMode()'],['../classIRDelonghiAc.html#a51a6eab431f81fa448a48c0ec071e706',1,'IRDelonghiAc::convertMode()'],['../classIRElectraAc.html#a0026a1981e713ce1f6916203717e0a00',1,'IRElectraAc::convertMode()'],['../classIRFujitsuAC.html#a242504a5b97c19ff7e369efcadd3916e',1,'IRFujitsuAC::convertMode()'],['../classIRGoodweatherAc.html#aef14e2b6c220e556300d286922da1f54',1,'IRGoodweatherAc::convertMode()'],['../classIRGreeAC.html#a609e87ad4926f150b44426caf79fd38e',1,'IRGreeAC::convertMode()'],['../classIRHaierAC.html#af6188dbed5cae022b4fd1eef358f594c',1,'IRHaierAC::convertMode()'],['../classIRHaierACYRW02.html#a9a51f3d4b4c60ed7d99f9836a57bb3e5',1,'IRHaierACYRW02::convertMode()'],['../classIRHitachiAc.html#af1bdc5e22e5e24218421bd3bbb436301',1,'IRHitachiAc::convertMode()'],['../classIRHitachiAc1.html#a6211c96f463353791e5d922d9939f23c',1,'IRHitachiAc1::convertMode()'],['../classIRHitachiAc424.html#a974bf3ada7117e463b8c23e2158902be',1,'IRHitachiAc424::convertMode()'],['../classIRKelvinatorAC.html#acc9d70a94dd3813005ca0381b80a35e4',1,'IRKelvinatorAC::convertMode()'],['../classIRLgAc.html#a114eca216b7c9c7be33d4527f848311e',1,'IRLgAc::convertMode()'],['../classIRMideaAC.html#a0ca16c8bc2232be467baba8ea69b40d4',1,'IRMideaAC::convertMode()'],['../classIRMitsubishiAC.html#a86d069e406d247bafbefbdd09b22894f',1,'IRMitsubishiAC::convertMode()'],['../classIRMitsubishi136.html#a43b8ff1083d09563a5d3a25b24e480ea',1,'IRMitsubishi136::convertMode()'],['../classIRMitsubishi112.html#aa41d6ec8bc6dc91891aaddbd996f6040',1,'IRMitsubishi112::convertMode()'],['../classIRMitsubishiHeavy152Ac.html#a067ca776edc19a577e8bcda5013e1d0f',1,'IRMitsubishiHeavy152Ac::convertMode()'],['../classIRMitsubishiHeavy88Ac.html#ad0419d176d70935fc535cdcc47ffba02',1,'IRMitsubishiHeavy88Ac::convertMode()'],['../classIRNeoclimaAc.html#a61335773816ecbbeb949e5da78d07e50',1,'IRNeoclimaAc::convertMode()'],['../classIRPanasonicAc.html#a3f3bc3e4b73338351f33f26c635075bb',1,'IRPanasonicAc::convertMode()'],['../classIRSamsungAc.html#a76f7fed436bdfcd9c9a9da8dd99cb9f7',1,'IRSamsungAc::convertMode()'],['../classIRSharpAc.html#a340d60b4b24c10479b3fed4409e0834b',1,'IRSharpAc::convertMode()'],['../classIRTcl112Ac.html#ac063653636319a9451590b08abbfecdc',1,'IRTcl112Ac::convertMode()'],['../classIRTecoAc.html#a5f95c5aacd8fc312acd0f36fd9dc33f2',1,'IRTecoAc::convertMode()'],['../classIRToshibaAC.html#a1cdcb695e128d57c721623cfdc9a8e8d',1,'IRToshibaAC::convertMode()'],['../classIRTrotecESP.html#a114a7022f0382275a55a2775d3d8e894',1,'IRTrotecESP::convertMode()'],['../classIRVestelAc.html#a5bb967d4972374254dad2c0a6fac7ed2',1,'IRVestelAc::convertMode()'],['../classIRWhirlpoolAc.html#afbf2f473c98f480d68c8bb28e1202d56',1,'IRWhirlpoolAc::convertMode()']]], + ['convertswingh_3748',['convertSwingH',['../classIRDaikin2.html#a79a989ad0221157c4dd8d992cc2863dc',1,'IRDaikin2::convertSwingH()'],['../classIRDaikin176.html#a2387b8dff2a9c9cd164034977b03f192',1,'IRDaikin176::convertSwingH()'],['../classIRHitachiAc344.html#a34d0fa5b522b51dac46f33cbb0a0a389',1,'IRHitachiAc344::convertSwingH()'],['../classIRMitsubishiAC.html#a8235a527a178486bb58ce62749aaf2fb',1,'IRMitsubishiAC::convertSwingH()'],['../classIRMitsubishi112.html#ab17598ce693475ef167525b8408e2da4',1,'IRMitsubishi112::convertSwingH()'],['../classIRMitsubishiHeavy152Ac.html#a0183cf4fcefb60ac61060dde698efbd1',1,'IRMitsubishiHeavy152Ac::convertSwingH()'],['../classIRMitsubishiHeavy88Ac.html#a8b995256a6651822731da7a912c01f19',1,'IRMitsubishiHeavy88Ac::convertSwingH()'],['../classIRPanasonicAc.html#abb17db3452ae347101dc6eaa8e84433b',1,'IRPanasonicAc::convertSwingH()']]], + ['convertswingv_3749',['convertSwingV',['../classIRArgoAC.html#ac23ff32b45c3fc5402e7e303ad9b5d54',1,'IRArgoAC::convertSwingV()'],['../classIRDaikin2.html#aa3de8468b869989ec52a5f9f57ff4a77',1,'IRDaikin2::convertSwingV()'],['../classIRDaikin160.html#a615f599f3bc3e8dec5e5ef92512a2301',1,'IRDaikin160::convertSwingV()'],['../classIRGoodweatherAc.html#a3b37c04fd9b60b63052d93374fc15d4f',1,'IRGoodweatherAc::convertSwingV()'],['../classIRGreeAC.html#ae3717400d1dc0336bcc5fa17c1397a9b',1,'IRGreeAC::convertSwingV()'],['../classIRHaierAC.html#a34053c32ba50ff3b81b208d068efe2a4',1,'IRHaierAC::convertSwingV()'],['../classIRHaierACYRW02.html#a1f7dffe29fbe67989b2f425d629850db',1,'IRHaierACYRW02::convertSwingV()'],['../classIRMitsubishiAC.html#ab561f6421b2f3e0d92d9fab685da639a',1,'IRMitsubishiAC::convertSwingV()'],['../classIRMitsubishi136.html#a59dee0c57d3ca2bdf4c7839142d23059',1,'IRMitsubishi136::convertSwingV()'],['../classIRMitsubishi112.html#a95c545497e0acc6f78ec229a2ada9de0',1,'IRMitsubishi112::convertSwingV()'],['../classIRMitsubishiHeavy152Ac.html#a93f2678fce3b35cfe3e31221d3355291',1,'IRMitsubishiHeavy152Ac::convertSwingV()'],['../classIRMitsubishiHeavy88Ac.html#abeba5346e1fc2223838fbc5d3ed03f23',1,'IRMitsubishiHeavy88Ac::convertSwingV()'],['../classIRPanasonicAc.html#a024e64fe32848e9b0b72e9c04db0fd98',1,'IRPanasonicAc::convertSwingV()']]], + ['coolix_3750',['coolix',['../classIRac.html#a4750db3b06db51f5a23c22538c41b7b3',1,'IRac']]], + ['copyirparams_3751',['copyIrParams',['../classIRrecv.html#ab017a0f9256954bb7d943e3c6b7e31bf',1,'IRrecv']]], + ['corona_3752',['corona',['../classIRac.html#adcf2bdb1ef6dc057532ae7d188557dac',1,'IRac']]], + ['countbits_3753',['countBits',['../IRutils_8cpp.html#a84621a9f7fb2d57bd425f9f0d662cf7d',1,'countBits(const uint8_t *const start, const uint16_t length, const bool ones, const uint16_t init): IRutils.cpp'],['../IRutils_8cpp.html#aae8042367bb94df81672603270fa7342',1,'countBits(const uint64_t data, const uint8_t length, const bool ones, const uint16_t init): IRutils.cpp'],['../IRutils_8h.html#a27816eac50afafa9e53ba4b53675da20',1,'countBits(const uint8_t *const start, const uint16_t length, const bool ones=true, const uint16_t init=0): IRutils.cpp'],['../IRutils_8h.html#a5a719829db11f5d5560b4367c0d2d365',1,'countBits(const uint64_t data, const uint8_t length, const bool ones=true, const uint16_t init=0): IRutils.cpp']]], + ['crudenoisefilter_3754',['crudeNoiseFilter',['../classIRrecv.html#ae833bdb8fccc676043fc4ccae432fab1',1,'IRrecv']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_4.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_4.html new file mode 100644 index 000000000..911304e60 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_4.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_4.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_4.js new file mode 100644 index 000000000..25bed5a59 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_4.js @@ -0,0 +1,95 @@ +var searchData= +[ + ['daikin_3755',['daikin',['../classIRac.html#afb6d77bbeb5b2465437cef4f58b83e0e',1,'IRac']]], + ['daikin128_3756',['daikin128',['../classIRac.html#a8fe7c254e1bcb32b6b6fdc1f91693a50',1,'IRac']]], + ['daikin152_3757',['daikin152',['../classIRac.html#a6dff8e608e3e9fecffe71c3fd1ebe74e',1,'IRac']]], + ['daikin160_3758',['daikin160',['../classIRac.html#a3b34f44d713efa52f30d43405cde831c',1,'IRac']]], + ['daikin176_3759',['daikin176',['../classIRac.html#aaae173fd58a7b53c3f4d2edbf7c4afe7',1,'IRac']]], + ['daikin2_3760',['daikin2',['../classIRac.html#a89eddc0e1b3c41c608208d2752dc954c',1,'IRac']]], + ['daikin216_3761',['daikin216',['../classIRac.html#a101ac8b9e9564e557ef1a1f61ff111d9',1,'IRac']]], + ['daikin64_3762',['daikin64',['../classIRac.html#a074db6fc0cff2878d80a397020e1b249',1,'IRac']]], + ['decode_3763',['decode',['../classIRrecv.html#aeaa5c07a8b46f8fbb982f996cc1f9f4b',1,'IRrecv']]], + ['decodeairwell_3764',['decodeAirwell',['../classIRrecv.html#acf4635d5ee146a82498cb0c269b6af41',1,'IRrecv']]], + ['decodeaiwarct501_3765',['decodeAiwaRCT501',['../classIRrecv.html#aa4d678376a4c0f8ea953474a6f5ef9d2',1,'IRrecv']]], + ['decodeamcor_3766',['decodeAmcor',['../classIRrecv.html#a8d81fcfb47e36925975d313027689a44',1,'IRrecv']]], + ['decodeargo_3767',['decodeArgo',['../classIRrecv.html#a94f12dc000a6e7b75ea8680fd48fc487',1,'IRrecv']]], + ['decodecarrierac_3768',['decodeCarrierAC',['../classIRrecv.html#acf3d1c37038120a5c0996d92577ce74a',1,'IRrecv']]], + ['decodecarrierac40_3769',['decodeCarrierAC40',['../classIRrecv.html#a4bdb35ec34f49401a6b9becd15b8a3b5',1,'IRrecv']]], + ['decodecarrierac64_3770',['decodeCarrierAC64',['../classIRrecv.html#a79d03c31da48a385ab47cc8f342ef9b3',1,'IRrecv']]], + ['decodecoolix_3771',['decodeCOOLIX',['../classIRrecv.html#a964af7e72e2133688f0596c718cb98ca',1,'IRrecv']]], + ['decodecoronaac_3772',['decodeCoronaAc',['../classIRrecv.html#a981cba14551c93af57f9c1c0e1775d12',1,'IRrecv']]], + ['decodedaikin_3773',['decodeDaikin',['../classIRrecv.html#a141f0de9f4cae8daeb025aff3904ecaa',1,'IRrecv']]], + ['decodedaikin128_3774',['decodeDaikin128',['../classIRrecv.html#ac7188577c874d9f8f19304a3ec775415',1,'IRrecv']]], + ['decodedaikin152_3775',['decodeDaikin152',['../classIRrecv.html#ab20a6586b4e56cc428012ec96f5ccc2c',1,'IRrecv']]], + ['decodedaikin160_3776',['decodeDaikin160',['../classIRrecv.html#af0b9822defe6b29099079d664d9dc413',1,'IRrecv']]], + ['decodedaikin176_3777',['decodeDaikin176',['../classIRrecv.html#aa142d1340201b6fdc5b462f46fe21ee0',1,'IRrecv']]], + ['decodedaikin2_3778',['decodeDaikin2',['../classIRrecv.html#a4c4799a0d45ea5562159c46939617d80',1,'IRrecv']]], + ['decodedaikin216_3779',['decodeDaikin216',['../classIRrecv.html#a7f860686a5c58aa8f4d1842cfb15b2f9',1,'IRrecv']]], + ['decodedaikin64_3780',['decodeDaikin64',['../classIRrecv.html#a030701f081a9c6eab0c07b75433b524c',1,'IRrecv']]], + ['decodedelonghiac_3781',['decodeDelonghiAc',['../classIRrecv.html#a8c91cc83770d243e942387cc16e9ca6f',1,'IRrecv']]], + ['decodedenon_3782',['decodeDenon',['../classIRrecv.html#a0b1bd1c817cb43bc3755126191b7f4a2',1,'IRrecv']]], + ['decodedish_3783',['decodeDISH',['../classIRrecv.html#a851776d9178aeb706d9a1abd3f254e31',1,'IRrecv']]], + ['decodedoshisha_3784',['decodeDoshisha',['../classIRrecv.html#a675c45e6b32aaeca3de734ccf2f0c819',1,'IRrecv']]], + ['decodeelectraac_3785',['decodeElectraAC',['../classIRrecv.html#ad3a7be8afc36451c8e28e27f3c3e9aaa',1,'IRrecv']]], + ['decodeepson_3786',['decodeEpson',['../classIRrecv.html#aaadef8415f273ba25f4086fecd681d2e',1,'IRrecv']]], + ['decodefujitsuac_3787',['decodeFujitsuAC',['../classIRrecv.html#aa3778bdf994bf9c99ac48ef95434a826',1,'IRrecv']]], + ['decodegicable_3788',['decodeGICable',['../classIRrecv.html#afade8dac9b1d023e5e0946e6b2c08aea',1,'IRrecv']]], + ['decodegoodweather_3789',['decodeGoodweather',['../classIRrecv.html#a64650ce7dbaf5fc860a6a253d906e9de',1,'IRrecv']]], + ['decodegree_3790',['decodeGree',['../classIRrecv.html#a2e756342d7524a13d53d6c656700638c',1,'IRrecv']]], + ['decodehaierac_3791',['decodeHaierAC',['../classIRrecv.html#ad97403174f05197a7fa9a4a0107e3111',1,'IRrecv']]], + ['decodehaieracyrw02_3792',['decodeHaierACYRW02',['../classIRrecv.html#a281fb9d972fee75db49209c42f649822',1,'IRrecv']]], + ['decodehash_3793',['decodeHash',['../classIRrecv.html#a7c15fbfa7936ca474712a1953911fd06',1,'IRrecv']]], + ['decodehitachiac_3794',['decodeHitachiAC',['../classIRrecv.html#aa42facfffc0e304005272b6ddd4583c8',1,'IRrecv']]], + ['decodehitachiac1_3795',['decodeHitachiAC1',['../classIRrecv.html#a122e0dcbf14c90ec2d77399acce21459',1,'IRrecv']]], + ['decodehitachiac3_3796',['decodeHitachiAc3',['../classIRrecv.html#a113bc834eff00f55d5545ce3fa1ab203',1,'IRrecv']]], + ['decodehitachiac424_3797',['decodeHitachiAc424',['../classIRrecv.html#a01c3dda56d6d916076fa1affa2213129',1,'IRrecv']]], + ['decodeinax_3798',['decodeInax',['../classIRrecv.html#a94545c6a8da027b9cb0e23ecba4c29d8',1,'IRrecv']]], + ['decodejvc_3799',['decodeJVC',['../classIRrecv.html#a25ab71efc223a418e9630d8421f44bc9',1,'IRrecv']]], + ['decodekelvinator_3800',['decodeKelvinator',['../classIRrecv.html#a0ac82f20b48b2d71ee07eb392578b226',1,'IRrecv']]], + ['decodelasertag_3801',['decodeLasertag',['../classIRrecv.html#ae4af614a45ea65cb3304ef5bd7965122',1,'IRrecv']]], + ['decodelegopf_3802',['decodeLegoPf',['../classIRrecv.html#aea75ad0ba1d8fec33de16501940f2553',1,'IRrecv']]], + ['decodelg_3803',['decodeLG',['../classIRrecv.html#afe70015c36b1477a5de0c193163e13a7',1,'IRrecv']]], + ['decodelutron_3804',['decodeLutron',['../classIRrecv.html#a6093c4404a9a9d415c5bfeab5ec53be5',1,'IRrecv']]], + ['decodemagiquest_3805',['decodeMagiQuest',['../classIRrecv.html#a6f3bfcc6767484151dee758bcf94fb0b',1,'IRrecv']]], + ['decodemidea_3806',['decodeMidea',['../classIRrecv.html#a255b15601f7439a09ab5e77ad78816fb',1,'IRrecv']]], + ['decodemidea24_3807',['decodeMidea24',['../classIRrecv.html#a62a04019308b29ae2aea4b3a83ba9155',1,'IRrecv']]], + ['decodemitsubishi_3808',['decodeMitsubishi',['../classIRrecv.html#a6efe3be80f0ebef3ff94ed0e56c5c52a',1,'IRrecv']]], + ['decodemitsubishi112_3809',['decodeMitsubishi112',['../classIRrecv.html#ae0690ff3cb5a5cdcdb6a514bb7bf0cdd',1,'IRrecv']]], + ['decodemitsubishi136_3810',['decodeMitsubishi136',['../classIRrecv.html#a87b3ee57dbdf762a0e305ddd43eec629',1,'IRrecv']]], + ['decodemitsubishi2_3811',['decodeMitsubishi2',['../classIRrecv.html#a9514197850491a5b8c30ae9ffc89d895',1,'IRrecv']]], + ['decodemitsubishiac_3812',['decodeMitsubishiAC',['../classIRrecv.html#a942c5f41df5cbff32a8b7703673cb621',1,'IRrecv']]], + ['decodemitsubishiheavy_3813',['decodeMitsubishiHeavy',['../classIRrecv.html#aef9cedf79793806df4cc5376710781bc',1,'IRrecv']]], + ['decodemultibrackets_3814',['decodeMultibrackets',['../classIRrecv.html#af61afacc9865232643164ba824e665ab',1,'IRrecv']]], + ['decodemwm_3815',['decodeMWM',['../classIRrecv.html#a27518b5d792cdf3ab333b324f409f328',1,'IRrecv']]], + ['decodenec_3816',['decodeNEC',['../classIRrecv.html#a52b844f80df7f64edf9ce9cc189ac5b9',1,'IRrecv']]], + ['decodeneoclima_3817',['decodeNeoclima',['../classIRrecv.html#a4729ee949e533448b481ae33bbbf1adf',1,'IRrecv']]], + ['decodenikai_3818',['decodeNikai',['../classIRrecv.html#abbcbf5fc07d7e37d7724acc37bb5f592',1,'IRrecv']]], + ['decodepanasonic_3819',['decodePanasonic',['../classIRrecv.html#aa8dd5f24d28576c6db03cc463bd0a865',1,'IRrecv']]], + ['decodepanasonicac_3820',['decodePanasonicAC',['../classIRrecv.html#a0f78e180ed731e8fb16d1c85aa721c95',1,'IRrecv']]], + ['decodepioneer_3821',['decodePioneer',['../classIRrecv.html#a78a9487cbe8a562392a07a4090b3091e',1,'IRrecv']]], + ['decoderc5_3822',['decodeRC5',['../classIRrecv.html#adab9dffbeceee514520fababd0e721bd',1,'IRrecv']]], + ['decoderc6_3823',['decodeRC6',['../classIRrecv.html#a67316499ef37db82e3b3ecaac25c5980',1,'IRrecv']]], + ['decodercmm_3824',['decodeRCMM',['../classIRrecv.html#a0e7bf769cb5bebf174e852e4b0b08cf3',1,'IRrecv']]], + ['decodesamsung_3825',['decodeSAMSUNG',['../classIRrecv.html#a18b6cf177364faf11b9a076dd2025eec',1,'IRrecv']]], + ['decodesamsung36_3826',['decodeSamsung36',['../classIRrecv.html#a290a9e6a0b12ef1fe02a92a456c8ad57',1,'IRrecv']]], + ['decodesamsungac_3827',['decodeSamsungAC',['../classIRrecv.html#ae779c76ebd0f3cd1fc13abaa55f80d67',1,'IRrecv']]], + ['decodesanyolc7461_3828',['decodeSanyoLC7461',['../classIRrecv.html#a201a5a78f43c2ac216fae4a2ba4d14ec',1,'IRrecv']]], + ['decodesharp_3829',['decodeSharp',['../classIRrecv.html#a3390d63ba21a835d7c74c261532a22a7',1,'IRrecv']]], + ['decodesharpac_3830',['decodeSharpAc',['../classIRrecv.html#a8a9b920079f783e236f8a938e20b9743',1,'IRrecv']]], + ['decodesony_3831',['decodeSony',['../classIRrecv.html#ab03227955cf7d1d00c1620c55d7f9f18',1,'IRrecv']]], + ['decodesymphony_3832',['decodeSymphony',['../classIRrecv.html#a61cdf4d891654521afbc6ca9fb415745',1,'IRrecv']]], + ['decodeteco_3833',['decodeTeco',['../classIRrecv.html#a950711d7df8dfe4cda86f53650cd9f56',1,'IRrecv']]], + ['decodetoshibaac_3834',['decodeToshibaAC',['../classIRrecv.html#a01228e51ede905beac689967bb14b538',1,'IRrecv']]], + ['decodetostate_3835',['decodeToState',['../namespaceIRAcUtils.html#ac5eb498bf12cb6cba023c9c1e9726949',1,'IRAcUtils']]], + ['decodetrotec_3836',['decodeTrotec',['../classIRrecv.html#ae2920c488173f3fa37f5325438157ced',1,'IRrecv']]], + ['decodevestelac_3837',['decodeVestelAc',['../classIRrecv.html#a5d48b3c91434c18c7726cca504d75b73',1,'IRrecv']]], + ['decodewhirlpoolac_3838',['decodeWhirlpoolAC',['../classIRrecv.html#a0d1eec83cf092f5621cb34b3e94777c4',1,'IRrecv']]], + ['decodewhynter_3839',['decodeWhynter',['../classIRrecv.html#a66289f6a462557ad26e6c0a64f36cf02',1,'IRrecv']]], + ['decodezepeal_3840',['decodeZepeal',['../classIRrecv.html#a72afd857c8b2e0192021a40afc96c2d8',1,'IRrecv']]], + ['defaultbits_3841',['defaultBits',['../classIRsend.html#a70a2256bee8ad9b8ea8571dd4f26596f',1,'IRsend']]], + ['delonghiac_3842',['delonghiac',['../classIRac.html#af290b0b08cff5121bb88c62051ed1074',1,'IRac']]], + ['disableirin_3843',['disableIRIn',['../classIRrecv.html#a9f4a719e756ad78c7dd47186f8bef087',1,'IRrecv']]], + ['disableofftimer_3844',['disableOffTimer',['../classIRDaikinESP.html#a1e4e05ad0799002d0ab25db92dcaac06',1,'IRDaikinESP::disableOffTimer()'],['../classIRDaikin2.html#a6c8ad4c34713d61942c80b6052e6283a',1,'IRDaikin2::disableOffTimer()']]], + ['disableontimer_3845',['disableOnTimer',['../classIRDaikinESP.html#a0733e4a15d76baac23493926ef1765b1',1,'IRDaikinESP::disableOnTimer()'],['../classIRDaikin2.html#ab0e77969a86af9637cb9aa4b4befd4aa',1,'IRDaikin2::disableOnTimer()']]], + ['disablesleeptimer_3846',['disableSleepTimer',['../classIRDaikin2.html#a5461cf51967d3fe67489384c82daac47',1,'IRDaikin2']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_5.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_5.html new file mode 100644 index 000000000..61b920db6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_5.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_5.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_5.js new file mode 100644 index 000000000..17a079595 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_5.js @@ -0,0 +1,26 @@ +var searchData= +[ + ['elapsed_3847',['elapsed',['../classIRtimer.html#ad655e585f053580d49d8de7d52cd62a1',1,'IRtimer::elapsed()'],['../classTimerMs.html#ad4aa759c58727393f69863b3461dfc09',1,'TimerMs::elapsed()']]], + ['electra_3848',['electra',['../classIRac.html#abb847bd5e09feb293432b8a8cf0dd9de',1,'IRac']]], + ['enableirin_3849',['enableIRIn',['../classIRrecv.html#a52c05ec6d8f3dbfb75f21f3b4fe7be3d',1,'IRrecv']]], + ['enableirout_3850',['enableIROut',['../classIRsend.html#ab3b6d36c9b5d26c400526717d433ed2d',1,'IRsend']]], + ['enableofftimer_3851',['enableOffTimer',['../classIRDaikinESP.html#a8a5686066bfc86f1d7cc454e793d3357',1,'IRDaikinESP::enableOffTimer()'],['../classIRDaikin2.html#afc7ba7d7de2976e010a72778091d633a',1,'IRDaikin2::enableOffTimer()'],['../classIRWhirlpoolAc.html#abb1c3685d90d81b44e72050cd0e042f6',1,'IRWhirlpoolAc::enableOffTimer()']]], + ['enableontimer_3852',['enableOnTimer',['../classIRDaikinESP.html#aac4d0f5f60c9f4c41d3bb1e0f24bc4bc',1,'IRDaikinESP::enableOnTimer()'],['../classIRDaikin2.html#a91ec5f7c67cb87102a5eb030e0763b50',1,'IRDaikin2::enableOnTimer()'],['../classIRWhirlpoolAc.html#aa3edd58882cf4fc65172e490c9e0bb2e',1,'IRWhirlpoolAc::enableOnTimer()']]], + ['enablesleeptimer_3853',['enableSleepTimer',['../classIRDaikin2.html#a9c86782a98a54818ae92419eec5a060b',1,'IRDaikin2']]], + ['enabletimer_3854',['enableTimer',['../classIRWhirlpoolAc.html#ad07804318721bc5dd60f7322e02c9696',1,'IRWhirlpoolAc']]], + ['encodedoshisha_3855',['encodeDoshisha',['../classIRsend.html#a0522a2256e8358df715065530be6317d',1,'IRsend']]], + ['encodejvc_3856',['encodeJVC',['../classIRsend.html#a6303b991c0545443e7ccf63ba89dbf18',1,'IRsend']]], + ['encodelg_3857',['encodeLG',['../classIRsend.html#a109b67a68e7a33900cb5c5017ed4578b',1,'IRsend']]], + ['encodemagiquest_3858',['encodeMagiQuest',['../classIRsend.html#a4ee40126279dbde8bb02888115577563',1,'IRsend']]], + ['encodenec_3859',['encodeNEC',['../classIRsend.html#ab2e1ce918e4e06b955c3d2a089ce189c',1,'IRsend']]], + ['encodepanasonic_3860',['encodePanasonic',['../classIRsend.html#a8340497ae75f00c844e53dfc73700d9c',1,'IRsend']]], + ['encodepioneer_3861',['encodePioneer',['../classIRsend.html#ae0686829eba31587b71034a1c0495971',1,'IRsend']]], + ['encoderc5_3862',['encodeRC5',['../classIRsend.html#a88457fd4cc01d6e8097e04c022ede74a',1,'IRsend']]], + ['encoderc5x_3863',['encodeRC5X',['../classIRsend.html#ae760ef1be11f25f7a61237f96a8871d9',1,'IRsend']]], + ['encoderc6_3864',['encodeRC6',['../classIRsend.html#ac0e341462426ea146b944502a6d3fde0',1,'IRsend']]], + ['encodesamsung_3865',['encodeSAMSUNG',['../classIRsend.html#a4ab0579bd854306b2667de19207e4ffb',1,'IRsend']]], + ['encodesanyolc7461_3866',['encodeSanyoLC7461',['../classIRsend.html#a864bef0dc48f6af4b59057362906cf5d',1,'IRsend']]], + ['encodesharp_3867',['encodeSharp',['../classIRsend.html#a8f4c7a36380ba31155eba5ff8f5f631e',1,'IRsend']]], + ['encodesony_3868',['encodeSony',['../classIRsend.html#aa0aea2cb04f0a7ee9056f15fecfc08c3',1,'IRsend']]], + ['encodetime_3869',['encodeTime',['../classIRPanasonicAc.html#a0eee4ad6105d35ee6c34c4666174b04b',1,'IRPanasonicAc']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_6.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_6.html new file mode 100644 index 000000000..dc70a4a07 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_6.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_6.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_6.js new file mode 100644 index 000000000..5cf543885 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_6.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['fahrenheittocelsius_3870',['fahrenheitToCelsius',['../IRutils_8cpp.html#a83538e86145850c24b1c824723089502',1,'fahrenheitToCelsius(const float deg): IRutils.cpp'],['../IRutils_8h.html#a83538e86145850c24b1c824723089502',1,'fahrenheitToCelsius(const float deg): IRutils.cpp']]], + ['fanspeedtostring_3871',['fanspeedToString',['../classIRac.html#ab8d8a1ce5de8970c07c90fb41731e2e6',1,'IRac']]], + ['fixchecksum_3872',['fixChecksum',['../classIRPanasonicAc.html#aa40bef35000ddf6d14e286b3f2044897',1,'IRPanasonicAc']]], + ['fixup_3873',['fixup',['../classIRGreeAC.html#a5bbdcc83f9d49e32379cd27cad0ba130',1,'IRGreeAC::fixup()'],['../classIRKelvinatorAC.html#a389af589003c39794ae5d4bd572fa485',1,'IRKelvinatorAC::fixup()']]], + ['fujitsu_3874',['fujitsu',['../classIRac.html#a23cf80270562ca28ae1f1da2bbb559e7',1,'IRac']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_7.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_7.html new file mode 100644 index 000000000..7de310677 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_7.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_7.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_7.js new file mode 100644 index 000000000..e0bde456f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_7.js @@ -0,0 +1,114 @@ +var searchData= +[ + ['get3d_3875',['get3D',['../classIRMitsubishiHeavy152Ac.html#ab55c9e587d472baf6a6d9cb61c733b08',1,'IRMitsubishiHeavy152Ac::get3D()'],['../classIRMitsubishiHeavy88Ac.html#ad5171595fef2360f50d7991897c40632',1,'IRMitsubishiHeavy88Ac::get3D()']]], + ['get8cheat_3876',['get8CHeat',['../classIRNeoclimaAc.html#aee5b855ce2decb455eaaceb6b4913368',1,'IRNeoclimaAc']]], + ['getbeep_3877',['getBeep',['../classIRDaikin2.html#ab6cc9737950ac0ab476bb240897902ec',1,'IRDaikin2::getBeep()'],['../classIRSamsungAc.html#ab13b10f80e8e1169f0b01239f357b3ba',1,'IRSamsungAc::getBeep()']]], + ['getbit_3878',['getBit',['../namespaceirutils.html#ac0756774b20e4f7c836abee466800ee6',1,'irutils::getBit(const uint64_t data, const uint8_t position, const uint8_t size)'],['../namespaceirutils.html#a27f90f74ed0b7af37c7bd8cd2a059dee',1,'irutils::getBit(const uint8_t data, const uint8_t position)']]], + ['getboost_3879',['getBoost',['../classIRDelonghiAc.html#abf9fd996c60573eca50b5e165cbcbf63',1,'IRDelonghiAc']]], + ['getbreeze_3880',['getBreeze',['../classIRSamsungAc.html#ad46fed65fb1375bf3a3940aa2cb311d5',1,'IRSamsungAc']]], + ['getbufsize_3881',['getBufSize',['../classIRrecv.html#a69ab02ea6823ccf18d1f6be87ca1b92e',1,'IRrecv']]], + ['getbutton_3882',['getButton',['../classIRHaierACYRW02.html#af4df303e5662aa63cba715ff49e09b75',1,'IRHaierACYRW02::getButton()'],['../classIRHitachiAc424.html#a32fa646e61cbaca805f33995344732cc',1,'IRHitachiAc424::getButton()'],['../classIRNeoclimaAc.html#a747fec9ea02220e6cf7465f5f9bb800a',1,'IRNeoclimaAc::getButton()']]], + ['getclean_3883',['getClean',['../classIRCoolixAC.html#a272f94ef641041835a650dd4fbdda7bf',1,'IRCoolixAC::getClean()'],['../classIRDaikin2.html#a7930bbca261f07ef1c129cd6a2c848b4',1,'IRDaikin2::getClean()'],['../classIRElectraAc.html#aa06b1246aaa3f25b239b50e395258b7a',1,'IRElectraAc::getClean()'],['../classIRFujitsuAC.html#a4bf872038fc175d1496eae25e9fcdce3',1,'IRFujitsuAC::getClean()'],['../classIRMitsubishiHeavy152Ac.html#a8e7c2759efe24e580d5886600f513648',1,'IRMitsubishiHeavy152Ac::getClean()'],['../classIRMitsubishiHeavy88Ac.html#a54eafb2474559371393c3ec3ba560d3a',1,'IRMitsubishiHeavy88Ac::getClean()'],['../classIRSamsungAc.html#a789edd6c6b0cb291753204d1e9c78fc8',1,'IRSamsungAc::getClean()'],['../classIRSharpAc.html#a599032d1101f15b98ffa9aa3039bc7d6',1,'IRSharpAc::getClean()']]], + ['getclock_3884',['getClock',['../classIRDaikin128.html#a6ef4d58f53b35619e8cc44fae6125490',1,'IRDaikin128::getClock()'],['../classIRDaikin64.html#a676ecda2ad53f78ef5cbf470f524918e',1,'IRDaikin64::getClock()'],['../classIRMitsubishiAC.html#a8918c5b8a72d58282b160c8fde9866ad',1,'IRMitsubishiAC::getClock()'],['../classIRPanasonicAc.html#a084479e8f23f7dbb8f155209b36efb3b',1,'IRPanasonicAc::getClock()'],['../classIRWhirlpoolAc.html#a329e06f4c44fa9aef42952f2d123b7a8',1,'IRWhirlpoolAc::getClock()']]], + ['getcmd_3885',['getCmd',['../classIRFujitsuAC.html#a758d209fd0e07cb200b2d4a232b6b0a2',1,'IRFujitsuAC']]], + ['getcomfort_3886',['getComfort',['../classIRDaikinESP.html#a4377e48a16a6ed1cb4fb2b711e672b16',1,'IRDaikinESP::getComfort()'],['../classIRDaikin152.html#a22cc2073fd7d4a609c335172ff6720cf',1,'IRDaikin152::getComfort()']]], + ['getcommand_3887',['getCommand',['../classIRGoodweatherAc.html#aa2a24e8c783cb5b463a95fa05779456e',1,'IRGoodweatherAc::getCommand()'],['../classIRHaierAC.html#a3a291fccea5f4b32f83da2605d2a82e0',1,'IRHaierAC::getCommand()'],['../classIRWhirlpoolAc.html#ab1c34a9498bc2c8da8e4bdcfe4bf011a',1,'IRWhirlpoolAc::getCommand()']]], + ['getcorrectedrawlength_3888',['getCorrectedRawLength',['../IRutils_8cpp.html#aad5f25cf6a2dded8b48f4a6dd16857be',1,'getCorrectedRawLength(const decode_results *const results): IRutils.cpp'],['../IRutils_8h.html#aad5f25cf6a2dded8b48f4a6dd16857be',1,'getCorrectedRawLength(const decode_results *const results): IRutils.cpp']]], + ['getcurrentday_3889',['getCurrentDay',['../classIRDaikinESP.html#ad0ecc69b2ab3e7678c8e4e8d64949077',1,'IRDaikinESP']]], + ['getcurrenttime_3890',['getCurrentTime',['../classIRDaikinESP.html#a724c204890e6810d150ed54794c9a505',1,'IRDaikinESP::getCurrentTime()'],['../classIRDaikin2.html#a94dc89b80dfdee2afa718314ec522b53',1,'IRDaikin2::getCurrentTime()']]], + ['getcurrtime_3891',['getCurrTime',['../classIRHaierAC.html#aa0e05983088035f6d85c520843922c25',1,'IRHaierAC']]], + ['getdisplay_3892',['getDisplay',['../classIRSamsungAc.html#a890aa3cab0918fda56daf0bf84ecc5c1',1,'IRSamsungAc']]], + ['getdisplaytempsource_3893',['getDisplayTempSource',['../classIRGreeAC.html#adea5a2d2b3a9d699c722e7a93784809e',1,'IRGreeAC']]], + ['getecono_3894',['getEcono',['../classIRCoronaAc.html#a0b8413e2a7aeecc5c0c55049c1705c38',1,'IRCoronaAc::getEcono()'],['../classIRDaikinESP.html#a84337719e737ea4dc1e1fb10f6f7df92',1,'IRDaikinESP::getEcono()'],['../classIRDaikin2.html#ad8098fa67e8808eebfad7611b6fc7881',1,'IRDaikin2::getEcono()'],['../classIRDaikin128.html#a0c05f4c6f996d56d56075e20a46f2c2c',1,'IRDaikin128::getEcono()'],['../classIRDaikin152.html#a9946c73f0c5906fbb2f39119e00531e5',1,'IRDaikin152::getEcono()'],['../classIRMitsubishiHeavy152Ac.html#aa7814232c84ff918f1d05ec105abf851',1,'IRMitsubishiHeavy152Ac::getEcono()'],['../classIRMitsubishiHeavy88Ac.html#af3accae413215cdd45a180f22bbe443e',1,'IRMitsubishiHeavy88Ac::getEcono()'],['../classIRTcl112Ac.html#afabe458a354d822f3ff929a461b6e046',1,'IRTcl112Ac::getEcono()']]], + ['geteconotoggle_3895',['getEconoToggle',['../classIRSharpAc.html#a701542019d3a823ba203f0db3cfce353',1,'IRSharpAc']]], + ['geteye_3896',['getEye',['../classIRDaikin2.html#a02fbd472d3c79b2391fc11da692c8998',1,'IRDaikin2::getEye()'],['../classIRNeoclimaAc.html#a15b91e2c854537d94cbabd7cd9bd30e4',1,'IRNeoclimaAc::getEye()']]], + ['geteyeauto_3897',['getEyeAuto',['../classIRDaikin2.html#a0cae45648292bdee8092a30338975ed0',1,'IRDaikin2']]], + ['getfan_3898',['getFan',['../classIRAmcorAc.html#a8ba84d83fc426ee5b75e0be27fd22d9c',1,'IRAmcorAc::getFan()'],['../classIRArgoAC.html#a413e60e09f1abcf231a173e1374e51e0',1,'IRArgoAC::getFan()'],['../classIRCarrierAc64.html#a93bb27688657af434d57f0dd9a159566',1,'IRCarrierAc64::getFan()'],['../classIRCoolixAC.html#a937c0084f79eaef2a160331993dfb881',1,'IRCoolixAC::getFan()'],['../classIRCoronaAc.html#aa51ccd3684009d5a56bbde73eab7ccfa',1,'IRCoronaAc::getFan()'],['../classIRDaikinESP.html#addad5838bb00885df8af258a61fa4131',1,'IRDaikinESP::getFan()'],['../classIRDaikin2.html#aafe89842b356c288dd38d256f9eb050c',1,'IRDaikin2::getFan()'],['../classIRDaikin216.html#a0905e04fc3d21249b057aa79721c1614',1,'IRDaikin216::getFan()'],['../classIRDaikin160.html#a2eb3987f87d19e1ab01dac111ae2d16b',1,'IRDaikin160::getFan()'],['../classIRDaikin176.html#a59c3d23a5e1b7c69c05690cf7984dab8',1,'IRDaikin176::getFan()'],['../classIRDaikin128.html#a68a7bdb134ea62913f51844f976beab1',1,'IRDaikin128::getFan()'],['../classIRDaikin152.html#a64eacdc63547026477b5f861e7da62ea',1,'IRDaikin152::getFan()'],['../classIRDaikin64.html#abdd4bc3d5464b5297b4f2fd0e7a831e1',1,'IRDaikin64::getFan()'],['../classIRDelonghiAc.html#afd2ed0ec70e3912335a9174bca7e7f5e',1,'IRDelonghiAc::getFan()'],['../classIRElectraAc.html#a6e8b30452671c26777ba2bc556bc8dce',1,'IRElectraAc::getFan()'],['../classIRGoodweatherAc.html#ac1ac922370ad09a80dd4e7158b279b9f',1,'IRGoodweatherAc::getFan()'],['../classIRGreeAC.html#a0bf5a552490c7500f0584affacac13d0',1,'IRGreeAC::getFan()'],['../classIRHaierAC.html#a5b15678e94acc14a0bb86bff61230e93',1,'IRHaierAC::getFan()'],['../classIRHaierACYRW02.html#a6de2fb6111049720913eb28bf6f64a00',1,'IRHaierACYRW02::getFan()'],['../classIRHitachiAc.html#a6a5f5b9544e93e842f76a2f4994c1665',1,'IRHitachiAc::getFan()'],['../classIRHitachiAc1.html#af1c6acc2ff9946af7091695b616c2cac',1,'IRHitachiAc1::getFan()'],['../classIRHitachiAc424.html#ab3ecfb8b6fb503ba3eed023609f2fe7b',1,'IRHitachiAc424::getFan()'],['../classIRKelvinatorAC.html#a64ce2ccf879217410269230218e0c76b',1,'IRKelvinatorAC::getFan()'],['../classIRLgAc.html#a10d666ca13c99696a53dca7f5773d7de',1,'IRLgAc::getFan()'],['../classIRMideaAC.html#ab793e409c666e001242623a2607786e7',1,'IRMideaAC::getFan()'],['../classIRMitsubishiAC.html#a06cb4179b92af1b1d3c167659c30db95',1,'IRMitsubishiAC::getFan()'],['../classIRMitsubishi136.html#a61b0a21a32eb1211cab201587de6f7ce',1,'IRMitsubishi136::getFan()'],['../classIRMitsubishi112.html#a00446fe1fdf27012acd41303b711e575',1,'IRMitsubishi112::getFan()'],['../classIRMitsubishiHeavy152Ac.html#a957abe79b7966da644db091ffe75d73b',1,'IRMitsubishiHeavy152Ac::getFan()'],['../classIRMitsubishiHeavy88Ac.html#ac00255061012eef8d62f44e478839d7e',1,'IRMitsubishiHeavy88Ac::getFan()'],['../classIRNeoclimaAc.html#a8690eda2de7b00029f70304131388890',1,'IRNeoclimaAc::getFan()'],['../classIRPanasonicAc.html#a302ba64400c820a5a0d822315516564a',1,'IRPanasonicAc::getFan()'],['../classIRSamsungAc.html#a6461c72b2598d1bdc14263552b5b0c98',1,'IRSamsungAc::getFan()'],['../classIRSharpAc.html#abae439959603f62b0fe5aea8ec93afb5',1,'IRSharpAc::getFan()'],['../classIRTcl112Ac.html#af59bcc28ac97869595a5ad928300908b',1,'IRTcl112Ac::getFan()'],['../classIRTecoAc.html#a420b209010276b30c9bc322b7393b3be',1,'IRTecoAc::getFan()'],['../classIRToshibaAC.html#afd2000b62b79afde107ebc8a513724ab',1,'IRToshibaAC::getFan()'],['../classIRVestelAc.html#a492abc867ad5b766715eaa301c71f3c8',1,'IRVestelAc::getFan()'],['../classIRWhirlpoolAc.html#a80fedb2ddec4a3dbb2c96b5a76a26e1a',1,'IRWhirlpoolAc::getFan()']]], + ['getfanspeed_3899',['getFanSpeed',['../classIRFujitsuAC.html#aacb180bb884b80c1f8bbbed7e2dd23d5',1,'IRFujitsuAC']]], + ['getfilter_3900',['getFilter',['../classIRFujitsuAC.html#a430ed6a4b946d1b4527741b42e12a25c',1,'IRFujitsuAC::getFilter()'],['../classIRMitsubishiHeavy152Ac.html#aaf2864f7187acd1b75d9daad2d504c13',1,'IRMitsubishiHeavy152Ac::getFilter()']]], + ['getflap_3901',['getFlap',['../classIRArgoAC.html#a2285908626731c2feaa85635f3ce1ff1',1,'IRArgoAC']]], + ['getfollow_3902',['getFollow',['../classIRNeoclimaAc.html#af4ed34fe7b151bcc5ff6922a54427da0',1,'IRNeoclimaAc']]], + ['getfresh_3903',['getFresh',['../classIRNeoclimaAc.html#a2c411cf55667339ff8e3664a6d0ee843',1,'IRNeoclimaAc']]], + ['getfreshair_3904',['getFreshAir',['../classIRDaikin2.html#aad50061042e14f665e5ecbd85ac48741',1,'IRDaikin2']]], + ['getfreshairhigh_3905',['getFreshAirHigh',['../classIRDaikin2.html#a72c8d47c2e6664eb0e40efe6933e4ac1',1,'IRDaikin2']]], + ['gethealth_3906',['getHealth',['../classIRHaierAC.html#a5c69955fe18f4ddb0286084f3fb39228',1,'IRHaierAC::getHealth()'],['../classIRHaierACYRW02.html#a97fc67cddf50a51b0db6c4e22fcaafa1',1,'IRHaierACYRW02::getHealth()'],['../classIRTcl112Ac.html#adf484b6a4097dd8834c202c81fea0ad4',1,'IRTcl112Ac::getHealth()']]], + ['gethold_3907',['getHold',['../classIRNeoclimaAc.html#a63045d768858265ed1bbc4c337de79eb',1,'IRNeoclimaAc']]], + ['gethumid_3908',['getHumid',['../classIRTecoAc.html#a30012508c6ba93ad07185a13795c5909',1,'IRTecoAc']]], + ['getifeel_3909',['getiFeel',['../classIRArgoAC.html#abc802d8ab9dbd9f918bc2aa36d2ea414',1,'IRArgoAC::getiFeel()'],['../classIRGreeAC.html#ae1f8352fc32fa773bb33243cc32657a2',1,'IRGreeAC::getIFeel()']]], + ['getion_3910',['getIon',['../classIRNeoclimaAc.html#a908a65189ba6eb8141d50da000feec0a',1,'IRNeoclimaAc::getIon()'],['../classIRPanasonicAc.html#a6d6909b7b96815c227f0009dcbd3ce8c',1,'IRPanasonicAc::getIon()'],['../classIRSamsungAc.html#aab1ebb523ca45431a0127b82cb4ce36f',1,'IRSamsungAc::getIon()'],['../classIRSharpAc.html#a1de89912129d0a1fffbd51625a1eeab7',1,'IRSharpAc::getIon()'],['../classIRVestelAc.html#a835f194f14479c25a3d651f324e6436c',1,'IRVestelAc::getIon()']]], + ['getionfilter_3911',['getIonFilter',['../classIRKelvinatorAC.html#a81127edca40e504c432b2079030f84a5',1,'IRKelvinatorAC']]], + ['getled_3912',['getLed',['../classIRCoolixAC.html#aa7712ebbf103c4d61dc645cb42dcf3f0',1,'IRCoolixAC']]], + ['getlight_3913',['getLight',['../classIRDaikin2.html#ada92da390d8b4247a014057c3d6fa296',1,'IRDaikin2::getLight()'],['../classIRGoodweatherAc.html#a90454990d7f9cde54ab5a11170d5e97d',1,'IRGoodweatherAc::getLight()'],['../classIRGreeAC.html#ae63281a9caf850429857cc3fa99ccf05',1,'IRGreeAC::getLight()'],['../classIRKelvinatorAC.html#a85e77c7a1b763373b0732d125923f53f',1,'IRKelvinatorAC::getLight()'],['../classIRNeoclimaAc.html#ad87fc87e34c3de56c4bbe35443e92226',1,'IRNeoclimaAc::getLight()'],['../classIRTcl112Ac.html#ae711a585331ffab24f96b0bb0f3960ed',1,'IRTcl112Ac::getLight()'],['../classIRTecoAc.html#a12a2bb7a5d3c90139dba85d54a535b8f',1,'IRTecoAc::getLight()'],['../classIRWhirlpoolAc.html#a87f2274da6101e1c2e78eb4e68aadff0',1,'IRWhirlpoolAc::getLight()']]], + ['getlighttoggle_3914',['getLightToggle',['../classIRDaikin128.html#a3e279e67bbafc0dc74dbd847e2e8ad75',1,'IRDaikin128::getLightToggle()'],['../classIRElectraAc.html#a63bc44235b18e11531479dc2f633f94b',1,'IRElectraAc::getLightToggle()']]], + ['getmax_3915',['getMax',['../classIRAmcorAc.html#a61659b6b54d652713efdf408a09db087',1,'IRAmcorAc::getMax()'],['../classIRArgoAC.html#aff24da9d975bf1f6df0a83be2ad7a913',1,'IRArgoAC::getMax()']]], + ['getmode_3916',['getMode',['../classIRAmcorAc.html#a30fd2a228e63e6b9a1544c3c1ec910f7',1,'IRAmcorAc::getMode()'],['../classIRArgoAC.html#a532a313f22c716b60cee070d9ba0839d',1,'IRArgoAC::getMode()'],['../classIRCarrierAc64.html#a4f8e0435a086ec934b10e9bd66f2ae85',1,'IRCarrierAc64::getMode()'],['../classIRCoolixAC.html#a16772a297404e2c54f951c49bfc608de',1,'IRCoolixAC::getMode()'],['../classIRCoronaAc.html#aa6ccd147a1da55d5e9596159008d40de',1,'IRCoronaAc::getMode()'],['../classIRDaikinESP.html#a164452703a7a6d46766acc85aab63898',1,'IRDaikinESP::getMode()'],['../classIRDaikin2.html#a681279a765159550ac1ec84895fff4d2',1,'IRDaikin2::getMode()'],['../classIRDaikin216.html#a21b3e93f98ac55e743efe38c20617d6a',1,'IRDaikin216::getMode()'],['../classIRDaikin160.html#a2b890fe446db67acd828fefd4afef84f',1,'IRDaikin160::getMode()'],['../classIRDaikin176.html#a1fc59660d77eb9dc3a8361d7d4698cd9',1,'IRDaikin176::getMode()'],['../classIRDaikin128.html#aa3d96e14663c498a6e0938ba04a02f87',1,'IRDaikin128::getMode()'],['../classIRDaikin152.html#af4c6c468f3075ffa83694a0da15a707b',1,'IRDaikin152::getMode()'],['../classIRDaikin64.html#a96624667a4494087074792562090b552',1,'IRDaikin64::getMode()'],['../classIRDelonghiAc.html#a89d9fa5b2c4a59b46cac111418232090',1,'IRDelonghiAc::getMode()'],['../classIRElectraAc.html#a473a794960bc07837e407830a3ea528b',1,'IRElectraAc::getMode()'],['../classIRFujitsuAC.html#a5f9630d81acffc74434ce852b9523d17',1,'IRFujitsuAC::getMode()'],['../classIRGoodweatherAc.html#a622e11c7b236fa127008f990819eca75',1,'IRGoodweatherAc::getMode()'],['../classIRGreeAC.html#abb5c4a29000c8b22b25e150e7ef5a6c3',1,'IRGreeAC::getMode()'],['../classIRHaierAC.html#aa180c60030d9972807238cceba886ff5',1,'IRHaierAC::getMode()'],['../classIRHaierACYRW02.html#aec7359fb8c796fc45577a40370f874c9',1,'IRHaierACYRW02::getMode()'],['../classIRHitachiAc.html#a414a4083e15deb1890a1eab4827d78ac',1,'IRHitachiAc::getMode()'],['../classIRHitachiAc1.html#afc4fdc94989297b73e08e9c82bd00733',1,'IRHitachiAc1::getMode()'],['../classIRHitachiAc424.html#ac1bf6df8277d50dcad8e389b21971e24',1,'IRHitachiAc424::getMode()'],['../classIRHitachiAc3.html#a511c9b731a0367fd05b32b42a69adec2',1,'IRHitachiAc3::getMode()'],['../classIRKelvinatorAC.html#a7a0f8f587fdda24db12db7aace478fd6',1,'IRKelvinatorAC::getMode()'],['../classIRLgAc.html#a19752b31eb74aad0cc9538a2f0af8b8c',1,'IRLgAc::getMode()'],['../classIRMideaAC.html#a1b5d19958e11a85d1af09b15631af124',1,'IRMideaAC::getMode()'],['../classIRMitsubishiAC.html#a069fd1d3bea102968e74b312fdf01548',1,'IRMitsubishiAC::getMode()'],['../classIRMitsubishi136.html#a3176aec8444f500bdea6e650cee2dbcc',1,'IRMitsubishi136::getMode()'],['../classIRMitsubishi112.html#ac2006f1e33f2a0cebcb6c23fcac389bb',1,'IRMitsubishi112::getMode()'],['../classIRMitsubishiHeavy152Ac.html#af0a51f8195492aac62bea483cb9a392c',1,'IRMitsubishiHeavy152Ac::getMode()'],['../classIRMitsubishiHeavy88Ac.html#ae8e1263a77b8fb04c2a4a5d6ce9805f9',1,'IRMitsubishiHeavy88Ac::getMode()'],['../classIRNeoclimaAc.html#ad2a43e0405a44787bb177bf13a324dde',1,'IRNeoclimaAc::getMode()'],['../classIRPanasonicAc.html#a5ffd59dd87b047e172ba74866267a9f3',1,'IRPanasonicAc::getMode()'],['../classIRSamsungAc.html#a740a874ee2c492027623943043a1ebf6',1,'IRSamsungAc::getMode()'],['../classIRSharpAc.html#adbccabd2ec614c8b921a02af8b529b4e',1,'IRSharpAc::getMode()'],['../classIRTcl112Ac.html#ad1b6538977bc464f1e6719b5cea89945',1,'IRTcl112Ac::getMode()'],['../classIRTecoAc.html#a4200081a4d42f2ec06935f71c4870e67',1,'IRTecoAc::getMode()'],['../classIRToshibaAC.html#aba5db1f6c8665443f26875ee9716302f',1,'IRToshibaAC::getMode()'],['../classIRTrotecESP.html#ab1b08911e9b76a06a08f4c7b8a2244c0',1,'IRTrotecESP::getMode()'],['../classIRVestelAc.html#ae5b3d9f1420f4d1951ba148399ccbd41',1,'IRVestelAc::getMode()'],['../classIRWhirlpoolAc.html#a4d2896e42e9c5ee1e8dc8f7e917618dc',1,'IRWhirlpoolAc::getMode()']]], + ['getmodel_3917',['getModel',['../classIRFujitsuAC.html#a35c6bfb730014f3a24676f94e8308163',1,'IRFujitsuAC::getModel()'],['../classIRGreeAC.html#a3780fc11488a2b40f3c1a50bb94783c7',1,'IRGreeAC::getModel()'],['../classIRHitachiAc1.html#a9ad677e1a2d7acba032701051538b08a',1,'IRHitachiAc1::getModel()'],['../classIRLgAc.html#aa49cde438a42a5415e127cc95da465ac',1,'IRLgAc::getModel()'],['../classIRPanasonicAc.html#a625be846baf3ec556a59379785e642e8',1,'IRPanasonicAc::getModel()'],['../classIRWhirlpoolAc.html#ac55e17fde1ef2acf6524d936732a0469',1,'IRWhirlpoolAc::getModel()']]], + ['getmold_3918',['getMold',['../classIRDaikinESP.html#ad593ac32c01752f56e9476af234cf813',1,'IRDaikinESP::getMold()'],['../classIRDaikin2.html#a330b3a8f25bd2d053dab318126b32569',1,'IRDaikin2::getMold()']]], + ['getnight_3919',['getNight',['../classIRArgoAC.html#adca87781240cf9c22e6bbaad9d59537c',1,'IRArgoAC::getNight()'],['../classIRMitsubishiHeavy152Ac.html#a659036b987991f39daa13fbd23b35f35',1,'IRMitsubishiHeavy152Ac::getNight()']]], + ['getnormalstate_3920',['getNormalState',['../classIRCoolixAC.html#a458618f926f8b57e4b9bdeae0d13a70d',1,'IRCoolixAC']]], + ['getofftime_3921',['getOffTime',['../classIRDaikinESP.html#a5213017d706cd6bce88cbfb65150bdb5',1,'IRDaikinESP::getOffTime()'],['../classIRDaikin2.html#af3a47c7b99cec3b108b5173cf1ae7da4',1,'IRDaikin2::getOffTime()'],['../classIRDaikin64.html#a7f163901c3b5065e393e3ae0e01d599a',1,'IRDaikin64::getOffTime()']]], + ['getofftimeenabled_3922',['getOffTimeEnabled',['../classIRDaikin64.html#a9ebf2deb196caece88c286d8c03bb69a',1,'IRDaikin64']]], + ['getofftimer_3923',['getOffTimer',['../classIRCarrierAc64.html#a6a28f83442d695385f76f13913c76542',1,'IRCarrierAc64::getOffTimer()'],['../classIRCoronaAc.html#a4602f36769e6b135fec8802a3b087adf',1,'IRCoronaAc::getOffTimer()'],['../classIRDaikin128.html#a6a18b029d75b006de5aeac2efb8e08e2',1,'IRDaikin128::getOffTimer()'],['../classIRDelonghiAc.html#acd32fa9acbc9782df9aa00325efea2a7',1,'IRDelonghiAc::getOffTimer()'],['../classIRHaierAC.html#a8b5c970b3204aa447d86dc2941dbd7b1',1,'IRHaierAC::getOffTimer()'],['../classIRHitachiAc1.html#ab99d73871d3510a830f988628dc5e33d',1,'IRHitachiAc1::getOffTimer()'],['../classIRPanasonicAc.html#a4bce377d32504f666662f1d93645761f',1,'IRPanasonicAc::getOffTimer()'],['../classIRVestelAc.html#a575ba7c6aee1d2377975ef0ef938775a',1,'IRVestelAc::getOffTimer()'],['../classIRWhirlpoolAc.html#a05e1308970e0169d6a081baf120efd9f',1,'IRWhirlpoolAc::getOffTimer()']]], + ['getofftimerenabled_3924',['getOffTimerEnabled',['../classIRDaikinESP.html#af6388cd6d2189f9067b708d46917a83a',1,'IRDaikinESP::getOffTimerEnabled()'],['../classIRDaikin2.html#a7a413002b64497a5fce7cdcdd6924e8f',1,'IRDaikin2::getOffTimerEnabled()'],['../classIRDaikin128.html#a4234e0e3ff261afa9d5ec6a8b92d8f53',1,'IRDaikin128::getOffTimerEnabled()'],['../classIRDelonghiAc.html#ac1b91f6d4bb5e41e43fc7e4b9a3187a3',1,'IRDelonghiAc::getOffTimerEnabled()']]], + ['getontime_3925',['getOnTime',['../classIRDaikinESP.html#a8a6730accc69647cbc12ebc99b2cfb77',1,'IRDaikinESP::getOnTime()'],['../classIRDaikin2.html#ad62f28698595be7717f0f29a5396853d',1,'IRDaikin2::getOnTime()'],['../classIRDaikin64.html#a9b316390ffc3e81d423d3e4b326be7d4',1,'IRDaikin64::getOnTime()']]], + ['getontimeenabled_3926',['getOnTimeEnabled',['../classIRDaikin64.html#a0b9795a5536566fe2f9b713aaff4b9ee',1,'IRDaikin64']]], + ['getontimer_3927',['getOnTimer',['../classIRCarrierAc64.html#a071ebd204e56e2cd771281b1c42b9cb5',1,'IRCarrierAc64::getOnTimer()'],['../classIRCoronaAc.html#a7beec38ab35dbebe955c4da188de25d5',1,'IRCoronaAc::getOnTimer()'],['../classIRDaikin128.html#a3b8a36d99a7cbf87bac8480f16c3d583',1,'IRDaikin128::getOnTimer()'],['../classIRDelonghiAc.html#a03f6d037d62d3c641b45ec97a1bff715',1,'IRDelonghiAc::getOnTimer()'],['../classIRHaierAC.html#a99d3339eb5ecdbf1c86e85408507af7b',1,'IRHaierAC::getOnTimer()'],['../classIRHitachiAc1.html#a9d5846c1efcc8fae1eeb6079a61cb18b',1,'IRHitachiAc1::getOnTimer()'],['../classIRPanasonicAc.html#a51d50a59e09f0911022c59ab60bf4889',1,'IRPanasonicAc::getOnTimer()'],['../classIRVestelAc.html#aa39e3047ea694ada9cc7e992e7b03e32',1,'IRVestelAc::getOnTimer()'],['../classIRWhirlpoolAc.html#a26c00db3316585e32d64428d6732fcd0',1,'IRWhirlpoolAc::getOnTimer()']]], + ['getontimerenabled_3928',['getOnTimerEnabled',['../classIRDaikinESP.html#a45e473403547c8ec95a50aeb1ed93607',1,'IRDaikinESP::getOnTimerEnabled()'],['../classIRDaikin2.html#a8921edb7885d728ee5294fa03cb13a87',1,'IRDaikin2::getOnTimerEnabled()'],['../classIRDaikin128.html#a450948bdbdc22da751c8f1abc2da642d',1,'IRDaikin128::getOnTimerEnabled()'],['../classIRDelonghiAc.html#a0911f40ee5838bfc6b7deb3193e6a62a',1,'IRDelonghiAc::getOnTimerEnabled()']]], + ['getoutsidequiet_3929',['getOutsideQuiet',['../classIRFujitsuAC.html#a404a06b5022899e622e629ec099864f5',1,'IRFujitsuAC']]], + ['getpower_3930',['getPower',['../classIRAmcorAc.html#a141e2af9eb4530b175a430dee31bc5ae',1,'IRAmcorAc::getPower()'],['../classIRArgoAC.html#a10812d30095c4adc24cb3eee25e2d246',1,'IRArgoAC::getPower()'],['../classIRCarrierAc64.html#ad50ebb44815e55cc0a99f4762939dc54',1,'IRCarrierAc64::getPower()'],['../classIRCoolixAC.html#a150e3b827d8002e77135955079c78704',1,'IRCoolixAC::getPower()'],['../classIRCoronaAc.html#a313c5489b53bba5747e871ec0a7af417',1,'IRCoronaAc::getPower()'],['../classIRDaikinESP.html#a1d72647db12276493d8e093a4feda44e',1,'IRDaikinESP::getPower()'],['../classIRDaikin2.html#a2f25c4ff097f82a91c062aacd5ebabfc',1,'IRDaikin2::getPower()'],['../classIRDaikin216.html#a2b1e1dd2a059466ab5e5c8ab7eb4f2b4',1,'IRDaikin216::getPower()'],['../classIRDaikin160.html#ad472f0d0680da6ab83a1b636bc00e271',1,'IRDaikin160::getPower()'],['../classIRDaikin176.html#ad564616fc1bf90c00c594c2d3cb5394d',1,'IRDaikin176::getPower()'],['../classIRDaikin152.html#a8581147072fecf6ebd0dd2da50a63f05',1,'IRDaikin152::getPower()'],['../classIRDelonghiAc.html#ae077f0e444fcf24b1e0343e93244b7e8',1,'IRDelonghiAc::getPower()'],['../classIRElectraAc.html#aed11407cd8be470baf5d4667e28e1273',1,'IRElectraAc::getPower()'],['../classIRFujitsuAC.html#a5d03a83db8bc2084ae2acea17c2c7ae2',1,'IRFujitsuAC::getPower()'],['../classIRGoodweatherAc.html#a6f7db9f499c4fea860976bb273ba15df',1,'IRGoodweatherAc::getPower()'],['../classIRGreeAC.html#ac2c97551e02c6cce1b9983cc902f5f1a',1,'IRGreeAC::getPower()'],['../classIRHaierACYRW02.html#a446ee5873e80fa474d322ca5ff598fb5',1,'IRHaierACYRW02::getPower()'],['../classIRHitachiAc.html#a3be8c7ded012c2ad5cab59ee6fe3c88e',1,'IRHitachiAc::getPower()'],['../classIRHitachiAc1.html#ab4756a44153997ff686e8a14369407c0',1,'IRHitachiAc1::getPower()'],['../classIRHitachiAc424.html#ae4d3370d89253ec0861a60b84b2d078c',1,'IRHitachiAc424::getPower()'],['../classIRKelvinatorAC.html#a3dc660afab763c9a4b0cfc5d8e14d220',1,'IRKelvinatorAC::getPower()'],['../classIRLgAc.html#ac09b8af7cc2d46881d3a710068acb5bd',1,'IRLgAc::getPower()'],['../classIRMideaAC.html#a2035653f3ac503a8d30563fded46cab2',1,'IRMideaAC::getPower()'],['../classIRMitsubishiAC.html#aa5fb3f328b6c8a553d25088ec9e858d7',1,'IRMitsubishiAC::getPower()'],['../classIRMitsubishi136.html#a371faf10c80560e1ad59c70d66147723',1,'IRMitsubishi136::getPower()'],['../classIRMitsubishi112.html#afb9ea09a7a9724410470944f6decaeed',1,'IRMitsubishi112::getPower()'],['../classIRMitsubishiHeavy152Ac.html#a1e1d742e255685d1b16935d6031b25fc',1,'IRMitsubishiHeavy152Ac::getPower()'],['../classIRMitsubishiHeavy88Ac.html#a05c50ad07ba7be443414792c7e585354',1,'IRMitsubishiHeavy88Ac::getPower()'],['../classIRNeoclimaAc.html#a635e81f673155eb123dab84a78ff86d5',1,'IRNeoclimaAc::getPower()'],['../classIRPanasonicAc.html#a2d50ed3994f6cc6e205d2c5fb6c0cc55',1,'IRPanasonicAc::getPower()'],['../classIRSamsungAc.html#a26fb214fdf3af4d39a898a1721583cf3',1,'IRSamsungAc::getPower()'],['../classIRSharpAc.html#a49c6c86c901a8d02d7a0d67bfcc397af',1,'IRSharpAc::getPower()'],['../classIRTcl112Ac.html#a36e3b74c79ec42a0922893a3ccd5d045',1,'IRTcl112Ac::getPower()'],['../classIRTecoAc.html#a66c39da54baa6d0c56418ff8027a12a6',1,'IRTecoAc::getPower()'],['../classIRToshibaAC.html#a6d69c147e786aa642906f24c9781bb0f',1,'IRToshibaAC::getPower()'],['../classIRTrotecESP.html#a2e303fe918f79281df98cffb9d2cd539',1,'IRTrotecESP::getPower()'],['../classIRVestelAc.html#a1d6cdc9ad13ebbf1e9a4a83f95244ced',1,'IRVestelAc::getPower()']]], + ['getpowerbutton_3931',['getPowerButton',['../classIRCoronaAc.html#ae38a9860cc3fe73909ba20260ad9a51a',1,'IRCoronaAc']]], + ['getpowerful_3932',['getPowerful',['../classIRDaikinESP.html#a827c3dc88027b043271a469bc41c4bb1',1,'IRDaikinESP::getPowerful()'],['../classIRDaikin2.html#abad28f7287f4d90d196eb0eb7f93ed43',1,'IRDaikin2::getPowerful()'],['../classIRDaikin216.html#acf94e292df8f45233e115324a95a5e83',1,'IRDaikin216::getPowerful()'],['../classIRDaikin128.html#a50f2de409b3e8966f8406b659aaaedac',1,'IRDaikin128::getPowerful()'],['../classIRDaikin152.html#a20ec24a0ef288cabb93080b4fa0f71fe',1,'IRDaikin152::getPowerful()'],['../classIRPanasonicAc.html#a736b77df0563705095d8f4241a80b1cb',1,'IRPanasonicAc::getPowerful()'],['../classIRSamsungAc.html#ac43367d5aec71e1dcb5b178427268412',1,'IRSamsungAc::getPowerful()']]], + ['getpowerspecial_3933',['getPowerSpecial',['../classIRSharpAc.html#aeb5d032c42863b6c3e2665c0719b9341',1,'IRSharpAc']]], + ['getpowertoggle_3934',['getPowerToggle',['../classIRDaikin128.html#a0b6b298a0287411f6fe34ec1a0032ff1',1,'IRDaikin128::getPowerToggle()'],['../classIRDaikin64.html#a7921b6a9e776a1802b98e25c0ac4d2dc',1,'IRDaikin64::getPowerToggle()'],['../classIRHitachiAc1.html#a384412f40bfde7a9934fbb7eb2813641',1,'IRHitachiAc1::getPowerToggle()'],['../classIRWhirlpoolAc.html#a08150bcdcf13f0dfb3a7608b2d354a1e',1,'IRWhirlpoolAc::getPowerToggle()']]], + ['getpurify_3935',['getPurify',['../classIRDaikin2.html#a3e2785832ae78bafa655aa61853a47bf',1,'IRDaikin2']]], + ['getquiet_3936',['getQuiet',['../classIRDaikinESP.html#a25dcfbeacce65f9a89d14a87f759c483',1,'IRDaikinESP::getQuiet()'],['../classIRDaikin2.html#a237eb163e3dd1bf8e45ae2324f0b7dcf',1,'IRDaikin2::getQuiet()'],['../classIRDaikin216.html#aaa0f1aa62f8afd3d489a33af1c1067bc',1,'IRDaikin216::getQuiet()'],['../classIRDaikin128.html#a685bbc2afeecdef69180229b64e1d54b',1,'IRDaikin128::getQuiet()'],['../classIRDaikin152.html#adc8878ec0f6ea2d4fc2fa756a2e9ef4e',1,'IRDaikin152::getQuiet()'],['../classIRDaikin64.html#a431e41baa2881f397b5bf8ee2b79fec9',1,'IRDaikin64::getQuiet()'],['../classIRKelvinatorAC.html#a467c0d63911a87bed8815a5b636d6d75',1,'IRKelvinatorAC::getQuiet()'],['../classIRMitsubishi136.html#afaf690f15d21fea1070b33b2720e98fa',1,'IRMitsubishi136::getQuiet()'],['../classIRMitsubishi112.html#a3b3b78ba5114d783ab7696f3e4687002',1,'IRMitsubishi112::getQuiet()'],['../classIRPanasonicAc.html#a8d7dfc9b5f7c7a4523c0bfa4e0bc415a',1,'IRPanasonicAc::getQuiet()'],['../classIRSamsungAc.html#a0baaf3d40419bb744204bdb30d4aa9b9',1,'IRSamsungAc::getQuiet()']]], + ['getraw_3937',['getRaw',['../classIRAmcorAc.html#aa2b99d815e499edf3ae53aebb35cbe9b',1,'IRAmcorAc::getRaw()'],['../classIRArgoAC.html#ac9e8b45dbbef453a54e3593d7e2927fb',1,'IRArgoAC::getRaw()'],['../classIRCarrierAc64.html#ad40279db2c9bd3d1abb5a6e028ec0d80',1,'IRCarrierAc64::getRaw()'],['../classIRCoolixAC.html#aa231938dfcff03325383205edc9c88d2',1,'IRCoolixAC::getRaw()'],['../classIRCoronaAc.html#ac2ba3b4bcefb801da345c9da5daa85fc',1,'IRCoronaAc::getRaw()'],['../classIRDaikinESP.html#ab100221dacc23402f486dee038df046d',1,'IRDaikinESP::getRaw()'],['../classIRDaikin2.html#aaf2ac0fc5924829a1209bd5e0b608b5f',1,'IRDaikin2::getRaw()'],['../classIRDaikin216.html#ac41b3de39ffc6ccd097085c727329531',1,'IRDaikin216::getRaw()'],['../classIRDaikin160.html#aeb68f80476362b0581fcb273b13cdf1e',1,'IRDaikin160::getRaw()'],['../classIRDaikin176.html#a86896be45037015683299004f2eb4d22',1,'IRDaikin176::getRaw()'],['../classIRDaikin128.html#a05669c2b1a6720b95d9a5fb898179a10',1,'IRDaikin128::getRaw()'],['../classIRDaikin152.html#a4af01f8a2459493762977f8ed260c4e6',1,'IRDaikin152::getRaw()'],['../classIRDaikin64.html#a1f8df45c67771ffca620f8c2f17af2e0',1,'IRDaikin64::getRaw()'],['../classIRDelonghiAc.html#a9e6934607f162df3d259d8fb95319d67',1,'IRDelonghiAc::getRaw()'],['../classIRElectraAc.html#a7674d29474ecbbb6366d96056794314c',1,'IRElectraAc::getRaw()'],['../classIRFujitsuAC.html#ae4dce44cab1f26756d63728cb8d55e65',1,'IRFujitsuAC::getRaw()'],['../classIRGoodweatherAc.html#a82d973e562b2425e8823fbc7332c06de',1,'IRGoodweatherAc::getRaw()'],['../classIRGreeAC.html#afa1595d4f69200b0076db1b9f8f2ea73',1,'IRGreeAC::getRaw()'],['../classIRHaierAC.html#abf72eed86c2c86c4f0f5f49f6a788b82',1,'IRHaierAC::getRaw()'],['../classIRHaierACYRW02.html#abca7bbe8c723551723f24f186343b764',1,'IRHaierACYRW02::getRaw()'],['../classIRHitachiAc.html#a8dafb9436f63cfc2d7e4f558fbd6e1ab',1,'IRHitachiAc::getRaw()'],['../classIRHitachiAc1.html#ad850b6364603880ccc444381e85af564',1,'IRHitachiAc1::getRaw()'],['../classIRHitachiAc424.html#acd8388f938feeaf6808ff65779435b5d',1,'IRHitachiAc424::getRaw()'],['../classIRHitachiAc3.html#a915605ca6d0bf3ff6fc9b376ddd394ae',1,'IRHitachiAc3::getRaw()'],['../classIRKelvinatorAC.html#a09149dd7bc45ca50b0c490b9c1f1e6f4',1,'IRKelvinatorAC::getRaw()'],['../classIRLgAc.html#afcb529d2f2c9016388264b80e6a99351',1,'IRLgAc::getRaw()'],['../classIRMideaAC.html#ae0b2c3a5a0a1d84eaeb462bbbe944d97',1,'IRMideaAC::getRaw()'],['../classIRMitsubishiAC.html#a1f2d0ea70bdeb71efab4c20ccd876aa9',1,'IRMitsubishiAC::getRaw()'],['../classIRMitsubishi136.html#a61cceec2bf241a75be1389391e8f3d9a',1,'IRMitsubishi136::getRaw()'],['../classIRMitsubishi112.html#a5e47e892921b8464652b55f41f42fd9a',1,'IRMitsubishi112::getRaw()'],['../classIRMitsubishiHeavy152Ac.html#a34ae73479c76b08512eaa87ed0662c0a',1,'IRMitsubishiHeavy152Ac::getRaw()'],['../classIRMitsubishiHeavy88Ac.html#af96915ac45861327ed7d55803dadd4fd',1,'IRMitsubishiHeavy88Ac::getRaw()'],['../classIRNeoclimaAc.html#a1f67329cad92d4252b0d33effce6380e',1,'IRNeoclimaAc::getRaw()'],['../classIRPanasonicAc.html#ad65c2bcdc3984a986f5ef2f03b5574d4',1,'IRPanasonicAc::getRaw()'],['../classIRSamsungAc.html#a96c6ac410053f0f2804160040d9fcf12',1,'IRSamsungAc::getRaw()'],['../classIRSharpAc.html#a9d680b0145c376060bd2d2e4c2630162',1,'IRSharpAc::getRaw()'],['../classIRTcl112Ac.html#a517375b764d1381aa5a7d4ec962346ec',1,'IRTcl112Ac::getRaw()'],['../classIRTecoAc.html#a7726e9d638cb81c7a4010112887a0ffe',1,'IRTecoAc::getRaw()'],['../classIRToshibaAC.html#a3572a06423851d2c4da5f85133a1a8ff',1,'IRToshibaAC::getRaw()'],['../classIRTrotecESP.html#a412dd2cf9dcb711003bcbb5b579cb2b8',1,'IRTrotecESP::getRaw()'],['../classIRVestelAc.html#afffd1dbcdec22ecca4efe9a996bf27e5',1,'IRVestelAc::getRaw()'],['../classIRWhirlpoolAc.html#a788a6a5373256e10200969cc5c73da63',1,'IRWhirlpoolAc::getRaw()']]], + ['getrclevel_3938',['getRClevel',['../classIRrecv.html#a8e32daaa903a8e42dad7faaf405b33dc',1,'IRrecv']]], + ['getroomtemp_3939',['getRoomTemp',['../classIRArgoAC.html#a5e4d8447c8851d2fce656abce6c4d368',1,'IRArgoAC']]], + ['getsave_3940',['getSave',['../classIRTecoAc.html#a0b4eea3d89f3aef649e32ee1b8bf65a3',1,'IRTecoAc']]], + ['getsectionbyte_3941',['getSectionByte',['../classIRCoronaAc.html#aed9181df842370739a5b4977b20769f9',1,'IRCoronaAc']]], + ['getsensor_3942',['getSensor',['../classIRDaikinESP.html#ac22369a04bb8f428a127b3625d9989fc',1,'IRDaikinESP::getSensor()'],['../classIRDaikin152.html#a88d4d0d41f33f71d4a846f6c2547f597',1,'IRDaikin152::getSensor()']]], + ['getsensortemp_3943',['getSensorTemp',['../classIRCoolixAC.html#aebbed796cab76248138e124aac1d535a',1,'IRCoolixAC']]], + ['getsilent_3944',['getSilent',['../classIRMitsubishiHeavy152Ac.html#a93aa735996a31d6f1928aa35d704bd24',1,'IRMitsubishiHeavy152Ac']]], + ['getsleep_3945',['getSleep',['../classIRCarrierAc64.html#a24f208b955af86f6927ac97b7f7066d5',1,'IRCarrierAc64::getSleep()'],['../classIRCoolixAC.html#a0b22f5427254c3f784f468d53909882c',1,'IRCoolixAC::getSleep()'],['../classIRDaikin128.html#a0cab507cdea112168757e1ab1a5a1dbe',1,'IRDaikin128::getSleep()'],['../classIRDaikin64.html#a32f4b90d4071cdbc4f37dd401e2d771f',1,'IRDaikin64::getSleep()'],['../classIRDelonghiAc.html#ab9baadd8f41c6dc7f89e71415e0e57b5',1,'IRDelonghiAc::getSleep()'],['../classIRGoodweatherAc.html#acf84e27fedc3c30a03c7d83e4843f8e0',1,'IRGoodweatherAc::getSleep()'],['../classIRGreeAC.html#abd106daa5324a454c5ced13e2fed2a1b',1,'IRGreeAC::getSleep()'],['../classIRHaierAC.html#a0ac7155d5ba294ce50b9436a35aa166b',1,'IRHaierAC::getSleep()'],['../classIRHaierACYRW02.html#acecf20cbe6065a4096ee5a353d2161c9',1,'IRHaierACYRW02::getSleep()'],['../classIRHitachiAc1.html#ab2e82cce1d9dc6e6ce66f2382ffcf4d4',1,'IRHitachiAc1::getSleep()'],['../classIRMideaAC.html#af4b76f42fd9be5eed9b546be7b0c34db',1,'IRMideaAC::getSleep()'],['../classIRNeoclimaAc.html#a8565f8f39127ed51eec7f7883319da61',1,'IRNeoclimaAc::getSleep()'],['../classIRTecoAc.html#a3eebb19e029aa882e161eb2bd6cfe333',1,'IRTecoAc::getSleep()'],['../classIRTrotecESP.html#a28558241d4dd18e191c6fab2c21f973e',1,'IRTrotecESP::getSleep()'],['../classIRVestelAc.html#a54f97dfe120c96b8c041550ed26d46f2',1,'IRVestelAc::getSleep()'],['../classIRWhirlpoolAc.html#a83c1b70e9c3b256b9e77ff6fb7fe0bde',1,'IRWhirlpoolAc::getSleep()']]], + ['getsleeptime_3946',['getSleepTime',['../classIRDaikin2.html#a31af96f9a05b3adea2e2ae84d3d242b9',1,'IRDaikin2']]], + ['getsleeptimerenabled_3947',['getSleepTimerEnabled',['../classIRDaikin2.html#ae4944acaa5c9d381a1875f4d0b16590a',1,'IRDaikin2']]], + ['getspecial_3948',['getSpecial',['../classIRSharpAc.html#a18fb9e6f965682e4faae3d1ecc2561cb',1,'IRSharpAc']]], + ['getspeed_3949',['getSpeed',['../classIRTrotecESP.html#ae57c9ab5bc2196f5028ea1af1bdb5428',1,'IRTrotecESP']]], + ['getstartclock_3950',['getStartClock',['../classIRMitsubishiAC.html#a0e0d8fa3bec35107929aaa9e9b4b5818',1,'IRMitsubishiAC']]], + ['getstate_3951',['getState',['../classIRac.html#af0122722691881b04c312bb30efcc3f2',1,'IRac']]], + ['getstatelength_3952',['getStateLength',['../classIRFujitsuAC.html#a02636372996211d464c7394329921ea0',1,'IRFujitsuAC']]], + ['getstateprev_3953',['getStatePrev',['../classIRac.html#adf582223eae0127491c7f1db38f101d3',1,'IRac']]], + ['getstopclock_3954',['getStopClock',['../classIRMitsubishiAC.html#a9b6266611d7cf75337557533a32796c2',1,'IRMitsubishiAC']]], + ['getsuper_3955',['getSuper',['../classIRWhirlpoolAc.html#a8bcf542e3499d05c4028157c803a0965',1,'IRWhirlpoolAc']]], + ['getswing_3956',['getSwing',['../classIRCoolixAC.html#a4846bb6a16802158dca3a8b1b7f5b6ff',1,'IRCoolixAC::getSwing()'],['../classIRFujitsuAC.html#af6f05f1375c3c4662d10026028fadbed',1,'IRFujitsuAC::getSwing()'],['../classIRGoodweatherAc.html#a96c844ec310323b62d9127ff250c3629',1,'IRGoodweatherAc::getSwing()'],['../classIRHaierAC.html#aa18839d213e4cd46405c683ec67fa23e',1,'IRHaierAC::getSwing()'],['../classIRHaierACYRW02.html#a88b15d20c007926ab5871b8e6a9fbe3f',1,'IRHaierACYRW02::getSwing()'],['../classIRSamsungAc.html#a5e6a7caccfdcb23cdb7d1341376c2343',1,'IRSamsungAc::getSwing()'],['../classIRTecoAc.html#a152fb025a2ba4410864637e8fdcef27a',1,'IRTecoAc::getSwing()'],['../classIRVestelAc.html#a991f8ca21319cb39b6c4cd358de4dbf4',1,'IRVestelAc::getSwing()'],['../classIRWhirlpoolAc.html#abac55fcea520ea4bbef3fa76223e2efc',1,'IRWhirlpoolAc::getSwing()']]], + ['getswingh_3957',['getSwingH',['../classIRElectraAc.html#a40e8f0ae2e57c3adf756b12524b36e6d',1,'IRElectraAc::getSwingH()'],['../classIRHitachiAc1.html#ac5bfde2c87281d3e7f427cb7ea601e85',1,'IRHitachiAc1::getSwingH()'],['../classIRHitachiAc344.html#a33ad0fe4939b2e2456a3d8a09da5a161',1,'IRHitachiAc344::getSwingH()'],['../classIRMitsubishi112.html#a05a343020c64f0ef95c365adcb337140',1,'IRMitsubishi112::getSwingH()'],['../classIRNeoclimaAc.html#a133fb28183fc33702bd8afb7c8886cb2',1,'IRNeoclimaAc::getSwingH()']]], + ['getswinghorizontal_3958',['getSwingHorizontal',['../classIRDaikinESP.html#a0a551cc1c22b5378015e8722919534aa',1,'IRDaikinESP::getSwingHorizontal()'],['../classIRDaikin2.html#a338a70b5d7f71da467a0f32b4a057f13',1,'IRDaikin2::getSwingHorizontal()'],['../classIRDaikin216.html#a4b5c648e6568bf1dd24932e108c560d9',1,'IRDaikin216::getSwingHorizontal()'],['../classIRDaikin176.html#aac0a1b9b5e618b31c651b9abc158a552',1,'IRDaikin176::getSwingHorizontal()'],['../classIRHitachiAc.html#a080f87358270eb1482d4a5d4b873f22c',1,'IRHitachiAc::getSwingHorizontal()'],['../classIRKelvinatorAC.html#abe27eb5ec7eb4c4b766a47b551422af3',1,'IRKelvinatorAC::getSwingHorizontal()'],['../classIRMitsubishiHeavy152Ac.html#a587eddf4684bdcb6c399b3f9c6cec684',1,'IRMitsubishiHeavy152Ac::getSwingHorizontal()'],['../classIRMitsubishiHeavy88Ac.html#ae538830313d02aa1ecc671188687dd35',1,'IRMitsubishiHeavy88Ac::getSwingHorizontal()'],['../classIRPanasonicAc.html#a37d9b268b3c8527be0939e0a24b02ef6',1,'IRPanasonicAc::getSwingHorizontal()'],['../classIRTcl112Ac.html#a7080def7f41498fc5af723e852c2e75c',1,'IRTcl112Ac::getSwingHorizontal()']]], + ['getswingtoggle_3959',['getSwingToggle',['../classIRHitachiAc1.html#ac4a5d4d5f9b4ae000d0acb232a1e2752',1,'IRHitachiAc1::getSwingToggle()'],['../classIRSharpAc.html#ae0327e90a68638c254706a99ed40f173',1,'IRSharpAc::getSwingToggle()']]], + ['getswingv_3960',['getSwingV',['../classIRCarrierAc64.html#a78aac688a4b040b2b6102fac8b028bde',1,'IRCarrierAc64::getSwingV()'],['../classIRDaikin152.html#a74ee60e666520513b33927178f15bc7e',1,'IRDaikin152::getSwingV()'],['../classIRElectraAc.html#a9cd2a7d7716f855dca6be12e3cdc3d24',1,'IRElectraAc::getSwingV()'],['../classIRHitachiAc1.html#a24216e1bc4cf9e9187e9031cee1684dc',1,'IRHitachiAc1::getSwingV()'],['../classIRHitachiAc344.html#a4e011e409f1bf97c8bd4043e2d069020',1,'IRHitachiAc344::getSwingV()'],['../classIRMitsubishi136.html#af2cacca74c4a6ade5f9689674bb707ea',1,'IRMitsubishi136::getSwingV()'],['../classIRMitsubishi112.html#a6d1e939169686978c83a2b26ebc3b8c2',1,'IRMitsubishi112::getSwingV()'],['../classIRNeoclimaAc.html#a3007ed9857bb212de05b7757ee0691e3',1,'IRNeoclimaAc::getSwingV()']]], + ['getswingvertical_3961',['getSwingVertical',['../classIRDaikinESP.html#a95f87fd97248e13c6339b71702a79e3a',1,'IRDaikinESP::getSwingVertical()'],['../classIRDaikin2.html#aa1d07be72001f06b6a8dfc279ffc40f5',1,'IRDaikin2::getSwingVertical()'],['../classIRDaikin216.html#ae72a3858a0023dac48fe755fd1bb1677',1,'IRDaikin216::getSwingVertical()'],['../classIRDaikin160.html#a5ed62940052f79587c92eaf92e30cf53',1,'IRDaikin160::getSwingVertical()'],['../classIRDaikin128.html#a60c21eaff6bf860ae25b974a0fd04e11',1,'IRDaikin128::getSwingVertical()'],['../classIRDaikin64.html#a7d538ad1ae23b92c1d82ae85ddd55ef1',1,'IRDaikin64::getSwingVertical()'],['../classIRHitachiAc.html#a9f507cc12bd3a5639777af0329a6dd5c',1,'IRHitachiAc::getSwingVertical()'],['../classIRKelvinatorAC.html#a69aaabc1f34e061272a76e4dc3c98bf1',1,'IRKelvinatorAC::getSwingVertical()'],['../classIRMitsubishiHeavy152Ac.html#a73c59d829a82306edf22acbd930650e0',1,'IRMitsubishiHeavy152Ac::getSwingVertical()'],['../classIRMitsubishiHeavy88Ac.html#ae836aee7dfb729f6b978b0b4ac8e9d3c',1,'IRMitsubishiHeavy88Ac::getSwingVertical()'],['../classIRPanasonicAc.html#a7a35303cd4fb4b23c0e5a25777d5819c',1,'IRPanasonicAc::getSwingVertical()'],['../classIRTcl112Ac.html#a0b75d06b14c1b7e2d2eb3a8779160ae5',1,'IRTcl112Ac::getSwingVertical()']]], + ['getswingverticalauto_3962',['getSwingVerticalAuto',['../classIRGreeAC.html#a4105bcde953896b12df050b12f1a45cc',1,'IRGreeAC']]], + ['getswingverticalposition_3963',['getSwingVerticalPosition',['../classIRGreeAC.html#a7b1b840483ef92102dd61fefd52ccd8b',1,'IRGreeAC']]], + ['getswingvtoggle_3964',['getSwingVToggle',['../classIRCoronaAc.html#ab10588a662031607ed4d01603a4471d6',1,'IRCoronaAc::getSwingVToggle()'],['../classIRHitachiAc424.html#ab697f595b6323288b6fd86f2a2911333',1,'IRHitachiAc424::getSwingVToggle()'],['../classIRMideaAC.html#a50b260d69bc0df8851bfccb003971dfe',1,'IRMideaAC::getSwingVToggle()']]], + ['gettemp_3965',['getTemp',['../classIRAmcorAc.html#a2f3e4765a3ae65ffda197f5a58070bf3',1,'IRAmcorAc::getTemp()'],['../classIRArgoAC.html#af5c4cfd3cac33f223e2807ec831df0a9',1,'IRArgoAC::getTemp()'],['../classIRCarrierAc64.html#a799edf21e766b8ae2638a9b1e1d18ac1',1,'IRCarrierAc64::getTemp()'],['../classIRCoolixAC.html#af90462598f294a75b35e20d986251942',1,'IRCoolixAC::getTemp()'],['../classIRCoronaAc.html#ac951434588fd9fa2de630db9ae844840',1,'IRCoronaAc::getTemp()'],['../classIRDaikinESP.html#a43c6675b688cad1ca714ecd726dbb411',1,'IRDaikinESP::getTemp()'],['../classIRDaikin2.html#aa1d39acc14bff5d55e918cb123c66e83',1,'IRDaikin2::getTemp()'],['../classIRDaikin216.html#a65b37310c01075c34cedd5ca1c8a2c37',1,'IRDaikin216::getTemp()'],['../classIRDaikin160.html#ae9cee15343fce5b0f32a4f2ff13a9dbe',1,'IRDaikin160::getTemp()'],['../classIRDaikin176.html#aa9015826e70e4ef1a319db4b2a3fba5f',1,'IRDaikin176::getTemp()'],['../classIRDaikin128.html#a0b5aa11a597bded38c067a9e9a01fd45',1,'IRDaikin128::getTemp()'],['../classIRDaikin152.html#af0a1f8bf9fe412186b53977d225032b2',1,'IRDaikin152::getTemp()'],['../classIRDaikin64.html#abeff1ec38e2d3c9fa12d59e506e7b699',1,'IRDaikin64::getTemp()'],['../classIRDelonghiAc.html#a5664302ab883fc88c23c8bb2aa020cb9',1,'IRDelonghiAc::getTemp()'],['../classIRElectraAc.html#ae92bd241a14058ece0e6d27332f9a3fa',1,'IRElectraAc::getTemp()'],['../classIRFujitsuAC.html#a9209df913f46821a66a390b8cff37acf',1,'IRFujitsuAC::getTemp()'],['../classIRGoodweatherAc.html#a796089c84e265cd7f1b2b82edc6b2367',1,'IRGoodweatherAc::getTemp()'],['../classIRGreeAC.html#a3e935c044cdccfb988a97d5fb0c4068b',1,'IRGreeAC::getTemp()'],['../classIRHaierAC.html#af137371c6766ee068a0200ff1facd8b0',1,'IRHaierAC::getTemp()'],['../classIRHaierACYRW02.html#a9cb0edcb5f36054e4e024c38ec3f26b9',1,'IRHaierACYRW02::getTemp()'],['../classIRHitachiAc.html#a85e0b2dfa45e894d1a89a2f862c6aa69',1,'IRHitachiAc::getTemp()'],['../classIRHitachiAc1.html#ac5c55a06a32134bb3e30b83cce2feeaa',1,'IRHitachiAc1::getTemp()'],['../classIRHitachiAc424.html#aa405408fd31795b714486af88a86112e',1,'IRHitachiAc424::getTemp()'],['../classIRKelvinatorAC.html#aabda77a2381526f4be86f05b311248db',1,'IRKelvinatorAC::getTemp()'],['../classIRLgAc.html#a029399c5926bd4f1ff0b26175bc4af79',1,'IRLgAc::getTemp()'],['../classIRMideaAC.html#a546ab6d3e317e6219ad371fd0825520d',1,'IRMideaAC::getTemp()'],['../classIRMitsubishiAC.html#a9881be01c53dce83bd1eae8a32f150f4',1,'IRMitsubishiAC::getTemp()'],['../classIRMitsubishi136.html#a34bc0e7666264a7e567e45405a57e3e0',1,'IRMitsubishi136::getTemp()'],['../classIRMitsubishi112.html#a4bfd306fecfcaa4c20589440ecfb35db',1,'IRMitsubishi112::getTemp()'],['../classIRMitsubishiHeavy152Ac.html#a7ec864271cf232cab7b8bd778bc36cb4',1,'IRMitsubishiHeavy152Ac::getTemp()'],['../classIRMitsubishiHeavy88Ac.html#afd629c9951a390b7809bc6ac4d3aeeb1',1,'IRMitsubishiHeavy88Ac::getTemp()'],['../classIRNeoclimaAc.html#aaa1a625af6cf094823b58f1fe43deb3a',1,'IRNeoclimaAc::getTemp()'],['../classIRPanasonicAc.html#af8a5607c317e541752fada6ca79ee80f',1,'IRPanasonicAc::getTemp()'],['../classIRSamsungAc.html#a11a6c86f2e4a918e1587ef564c63dddd',1,'IRSamsungAc::getTemp()'],['../classIRSharpAc.html#a1f75c17cc396162e776f3c6cd1848f50',1,'IRSharpAc::getTemp()'],['../classIRTcl112Ac.html#a61bf139cc737b99e5d68294c353eb353',1,'IRTcl112Ac::getTemp()'],['../classIRTecoAc.html#a40e717564222c5c1e4fdce13eba5efc3',1,'IRTecoAc::getTemp()'],['../classIRToshibaAC.html#ab2a9b47d49c5608c97a7c6968c43037d',1,'IRToshibaAC::getTemp()'],['../classIRTrotecESP.html#adcfae2ee1e58cd6a78805c72d7a8a942',1,'IRTrotecESP::getTemp()'],['../classIRVestelAc.html#a835ab977fa0dbf47776e5d618d59c819',1,'IRVestelAc::getTemp()'],['../classIRWhirlpoolAc.html#a4a73ee67cb2eb4407e78add1009cdd51',1,'IRWhirlpoolAc::getTemp()']]], + ['gettempoffset_3966',['getTempOffset',['../classIRWhirlpoolAc.html#a2d6111c9b97745d197f0b5d4d4610b3d',1,'IRWhirlpoolAc']]], + ['gettempraw_3967',['getTempRaw',['../classIRCoolixAC.html#a559634f3c6aee54683d4b6ccbbc7a884',1,'IRCoolixAC']]], + ['gettempunit_3968',['getTempUnit',['../classIRDelonghiAc.html#a8bbe27e1e87fbfc6b126c7f135886632',1,'IRDelonghiAc']]], + ['gettime_3969',['getTime',['../classIRHaierAC.html#a60e891775fbc3a77ee487cde26f650c5',1,'IRHaierAC::getTime()'],['../classIRVestelAc.html#a3542ec93c30ec3bc1bb4e242edcf1def',1,'IRVestelAc::getTime()'],['../classIRWhirlpoolAc.html#a27aba1f22b55aa6f72686e0a722682b0',1,'IRWhirlpoolAc::getTime()']]], + ['gettimer_3970',['getTimer',['../classIRDaikin128.html#ab35fa1fdd65db9d9cd7fbaffdd4ecd85',1,'IRDaikin128::getTimer()'],['../classIRGreeAC.html#a7a56024e2840306e071e03d1fae53ce9',1,'IRGreeAC::getTimer()'],['../classIRMitsubishiAC.html#a8bb8e92a00f8d9dfff31589d435c9ae5',1,'IRMitsubishiAC::getTimer()'],['../classIRTecoAc.html#a0bff25b2c686e397b62300ce5cad90f7',1,'IRTecoAc::getTimer()'],['../classIRTrotecESP.html#ae372b3120f0253c5a1607460817d36f6',1,'IRTrotecESP::getTimer()'],['../classIRVestelAc.html#aca4faedc9d82e357c8974fc6143b6e77',1,'IRVestelAc::getTimer()']]], + ['gettimerenabled_3971',['getTimerEnabled',['../classIRGreeAC.html#aeec03eb7f506a0ba62c28469b789b0da',1,'IRGreeAC::getTimerEnabled()'],['../classIRSharpAc.html#abd7c061b343b4f096019f42ad6162940',1,'IRSharpAc::getTimerEnabled()'],['../classIRTecoAc.html#a3524f149cd3076e757a1b3228bdf12f2',1,'IRTecoAc::getTimerEnabled()']]], + ['gettimertime_3972',['getTimerTime',['../classIRSharpAc.html#a72044d8afb1349a29cd8adcc8644c7ac',1,'IRSharpAc']]], + ['gettimertype_3973',['getTimerType',['../classIRSharpAc.html#a9357c50c356b29cc444bf9aafb7df146',1,'IRSharpAc']]], + ['gettolerance_3974',['getTolerance',['../classIRrecv.html#a144f64da3b44708394c06b0fbefb6347',1,'IRrecv']]], + ['getturbo_3975',['getTurbo',['../classIRCoolixAC.html#ab5f87216fb91bbb437c0899b0742a63f',1,'IRCoolixAC::getTurbo()'],['../classIRDaikin64.html#ade80a5ea137c32bdedd794d64925a2d3',1,'IRDaikin64::getTurbo()'],['../classIRElectraAc.html#a75cae6845498eec84109374a2fefcced',1,'IRElectraAc::getTurbo()'],['../classIRGoodweatherAc.html#a983eca3c2ec1233184939702f43557eb',1,'IRGoodweatherAc::getTurbo()'],['../classIRGreeAC.html#a6e319c8584d0cb82223fd190fa4bde29',1,'IRGreeAC::getTurbo()'],['../classIRHaierACYRW02.html#a4ccd26dad24915b81ae5fb94d18fb85a',1,'IRHaierACYRW02::getTurbo()'],['../classIRKelvinatorAC.html#aff32ab0524f4afeb9b53aa65b8df8e36',1,'IRKelvinatorAC::getTurbo()'],['../classIRMitsubishiHeavy152Ac.html#acf2a73ccddb87bd66c39670bd1d3caba',1,'IRMitsubishiHeavy152Ac::getTurbo()'],['../classIRMitsubishiHeavy88Ac.html#a179ecc619e9eea4adb601309421e5fc0',1,'IRMitsubishiHeavy88Ac::getTurbo()'],['../classIRNeoclimaAc.html#a6cf241f0392744a91b703475ee88bfa1',1,'IRNeoclimaAc::getTurbo()'],['../classIRSharpAc.html#aad2ec46f8da6fd84bc0523f40d6bd57d',1,'IRSharpAc::getTurbo()'],['../classIRTcl112Ac.html#a0de33a2175eada44030d3640d940b697',1,'IRTcl112Ac::getTurbo()'],['../classIRVestelAc.html#a9ce168cc9422e54d631aed571cfe66be',1,'IRVestelAc::getTurbo()']]], + ['getusecelsius_3976',['getUseCelsius',['../classIRMideaAC.html#aa88de606a914e33e8beb75a069137b52',1,'IRMideaAC']]], + ['getusefahrenheit_3977',['getUseFahrenheit',['../classIRGreeAC.html#aad6acfb8a697aba851bb34b14bc94ac1',1,'IRGreeAC']]], + ['getvane_3978',['getVane',['../classIRMitsubishiAC.html#acd98301535e7e161f8fdf42877f3e482',1,'IRMitsubishiAC']]], + ['getweeklytimerenable_3979',['getWeeklyTimerEnable',['../classIRDaikinESP.html#a9ee2013c069496884c62b6e9a58d01db',1,'IRDaikinESP']]], + ['getwidevane_3980',['getWideVane',['../classIRMitsubishiAC.html#a217dba9f9dcc6f75d466b0b7beca3aea',1,'IRMitsubishiAC']]], + ['getwifi_3981',['getWiFi',['../classIRGreeAC.html#a967afbe980bae858ce0e4daea6628c37',1,'IRGreeAC']]], + ['getxfan_3982',['getXFan',['../classIRGreeAC.html#acb677dde02be1a3461a7c8bc2406194f',1,'IRGreeAC::getXFan()'],['../classIRKelvinatorAC.html#a2e511ca0a8876928412c2db9214e7fe2',1,'IRKelvinatorAC::getXFan()']]], + ['getzonefollow_3983',['getZoneFollow',['../classIRCoolixAC.html#a647a41d63301e3d95460323d1fe0ce4a',1,'IRCoolixAC']]], + ['goodweather_3984',['goodweather',['../classIRac.html#ac47ff5c6faf41e6fb37df258a8bafc08',1,'IRac']]], + ['gree_3985',['gree',['../classIRac.html#ab66e48b039c9990bf97cd8c2512a6c70',1,'IRac']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_8.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_8.html new file mode 100644 index 000000000..7422be245 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_8.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_8.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_8.js new file mode 100644 index 000000000..60ae567c3 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_8.js @@ -0,0 +1,15 @@ +var searchData= +[ + ['haier_3986',['haier',['../classIRac.html#ae0a29a4cb8c7a4707a7725c576822a58',1,'IRac']]], + ['haieryrwo2_3987',['haierYrwo2',['../classIRac.html#a7bc779a162dd9a1b4c925febec443353',1,'IRac']]], + ['handlespecialstate_3988',['handleSpecialState',['../classIRCoolixAC.html#af78090c6d8b45b4202a80f1223640390',1,'IRCoolixAC']]], + ['handletoggles_3989',['handleToggles',['../classIRac.html#a36833999dce4ad608a5a0f084988cfd1',1,'IRac']]], + ['hasacstate_3990',['hasACState',['../IRutils_8cpp.html#a6efd4986db60709d3501606ec7ab5382',1,'hasACState(const decode_type_t protocol): IRutils.cpp'],['../IRutils_8h.html#a6efd4986db60709d3501606ec7ab5382',1,'hasACState(const decode_type_t protocol): IRutils.cpp']]], + ['hasinvertedstates_3991',['hasInvertedStates',['../classIRHitachiAc3.html#ac06b36245c85480d97c1a9f49cfaa005',1,'IRHitachiAc3']]], + ['hasstatechanged_3992',['hasStateChanged',['../classIRac.html#a35258c35a2d2b19886292b22b2aa053a',1,'IRac']]], + ['hitachi_3993',['hitachi',['../classIRac.html#acd0f2fcf03aabf947a19a195000add3c',1,'IRac']]], + ['hitachi1_3994',['hitachi1',['../classIRac.html#ac8807d62f6ae87af72d44b50bed3f17b',1,'IRac']]], + ['hitachi344_3995',['hitachi344',['../classIRac.html#a0bc34635a1a349816344916a82585460',1,'IRac']]], + ['hitachi424_3996',['hitachi424',['../classIRac.html#aec6de0752ddd3a3e7c6824cb1b692508',1,'IRac']]], + ['htmlescape_3997',['htmlEscape',['../namespaceirutils.html#a6e55c6fdcc82e1ef8bd5f73df83609a7',1,'irutils']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_9.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_9.html new file mode 100644 index 000000000..befd4faaa --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_9.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_9.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_9.js new file mode 100644 index 000000000..97c6d2069 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_9.js @@ -0,0 +1,64 @@ +var searchData= +[ + ['initstate_3998',['initState',['../classIRac.html#af1c4ae70e61298c0be8d350d67e7c342',1,'IRac::initState(stdAc::state_t *state, const decode_type_t vendor, const int16_t model, const bool power, const stdAc::opmode_t mode, const float degrees, const bool celsius, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool quiet, const bool turbo, const bool econo, const bool light, const bool filter, const bool clean, const bool beep, const int16_t sleep, const int16_t clock)'],['../classIRac.html#a165b7fdb9b3a02b1fb5ff2c2c3747958',1,'IRac::initState(stdAc::state_t *state)']]], + ['invertbits_3999',['invertBits',['../IRutils_8cpp.html#a1a85904f25c8ec77fb554d238c59cfdb',1,'invertBits(const uint64_t data, const uint16_t nbits): IRutils.cpp'],['../IRutils_8h.html#a1a85904f25c8ec77fb554d238c59cfdb',1,'invertBits(const uint64_t data, const uint16_t nbits): IRutils.cpp']]], + ['irac_4000',['IRac',['../classIRac.html#abb0864e277d4f6c68a92c2729112a40d',1,'IRac']]], + ['iramcorac_4001',['IRAmcorAc',['../classIRAmcorAc.html#a92db59a33c861dcd3b2960e9711f97c4',1,'IRAmcorAc']]], + ['irargoac_4002',['IRArgoAC',['../classIRArgoAC.html#ad6c2250738397441b8f956d1477b7d70',1,'IRArgoAC']]], + ['ircarrierac64_4003',['IRCarrierAc64',['../classIRCarrierAc64.html#ac225c0f24a0e385a145375ff447ab79b',1,'IRCarrierAc64']]], + ['ircoolixac_4004',['IRCoolixAC',['../classIRCoolixAC.html#a043ad3b74e964e39b111e1fcf9e55f42',1,'IRCoolixAC']]], + ['ircoronaac_4005',['IRCoronaAc',['../classIRCoronaAc.html#aa96f1ffce21cdec5b3901ebbb1c63fbb',1,'IRCoronaAc']]], + ['irdaikin128_4006',['IRDaikin128',['../classIRDaikin128.html#aa669739541daf1a2b39ce1cd0424c43b',1,'IRDaikin128']]], + ['irdaikin152_4007',['IRDaikin152',['../classIRDaikin152.html#a68dce79bab5890d9aea325a45ef8e4a3',1,'IRDaikin152']]], + ['irdaikin160_4008',['IRDaikin160',['../classIRDaikin160.html#a76fb744b041c38abb730bce0538a497a',1,'IRDaikin160']]], + ['irdaikin176_4009',['IRDaikin176',['../classIRDaikin176.html#accfe7c3f34351844d12059455f65f312',1,'IRDaikin176']]], + ['irdaikin2_4010',['IRDaikin2',['../classIRDaikin2.html#a3ffe908313f162b92e92307578592fca',1,'IRDaikin2']]], + ['irdaikin216_4011',['IRDaikin216',['../classIRDaikin216.html#ad802bde79e5ee2d16e3b09fbc8bbe8df',1,'IRDaikin216']]], + ['irdaikin64_4012',['IRDaikin64',['../classIRDaikin64.html#a88855df33ce903884b21d2ef4771e94f',1,'IRDaikin64']]], + ['irdaikinesp_4013',['IRDaikinESP',['../classIRDaikinESP.html#a2652cb45e07e8a4329c16cded9f6ad9a',1,'IRDaikinESP']]], + ['irdelonghiac_4014',['IRDelonghiAc',['../classIRDelonghiAc.html#aa6f8661cf6baa369a0a5b9d775c392e0',1,'IRDelonghiAc']]], + ['irelectraac_4015',['IRElectraAc',['../classIRElectraAc.html#a2f56ad22943c3d261b1d2ef88d86e300',1,'IRElectraAc']]], + ['irfujitsuac_4016',['IRFujitsuAC',['../classIRFujitsuAC.html#acdb70f239884507f540b872ba25747ce',1,'IRFujitsuAC']]], + ['irgoodweatherac_4017',['IRGoodweatherAc',['../classIRGoodweatherAc.html#a681feff1a58125cde97b2d7ed0ba775e',1,'IRGoodweatherAc']]], + ['irgreeac_4018',['IRGreeAC',['../classIRGreeAC.html#abf7ead6ebee4bc776f83fb55f6fe6b63',1,'IRGreeAC']]], + ['irhaierac_4019',['IRHaierAC',['../classIRHaierAC.html#a0b78060cbd150cd886a409adc2dea49c',1,'IRHaierAC']]], + ['irhaieracyrw02_4020',['IRHaierACYRW02',['../classIRHaierACYRW02.html#afd9354c36df33434840bbc5f38d4e7ed',1,'IRHaierACYRW02']]], + ['irhitachiac_4021',['IRHitachiAc',['../classIRHitachiAc.html#a4c43e95e0cc28339e7162d7090ae16bf',1,'IRHitachiAc']]], + ['irhitachiac1_4022',['IRHitachiAc1',['../classIRHitachiAc1.html#ac00cfd9a60e08d34f292878de47f622f',1,'IRHitachiAc1']]], + ['irhitachiac3_4023',['IRHitachiAc3',['../classIRHitachiAc3.html#adef0e7ad217f078ce418e3aa82b9cb86',1,'IRHitachiAc3']]], + ['irhitachiac344_4024',['IRHitachiAc344',['../classIRHitachiAc344.html#afbff8a1dd2777880d2d1713d07e1d419',1,'IRHitachiAc344']]], + ['irhitachiac424_4025',['IRHitachiAc424',['../classIRHitachiAc424.html#add708c10a56d20621ef65a0ddcc2aac1',1,'IRHitachiAc424']]], + ['irkelvinatorac_4026',['IRKelvinatorAC',['../classIRKelvinatorAC.html#a111dd384b1898a4fb880a19b6d1b1635',1,'IRKelvinatorAC']]], + ['irlgac_4027',['IRLgAc',['../classIRLgAc.html#a290636496526a9ed2057532649709375',1,'IRLgAc']]], + ['irmideaac_4028',['IRMideaAC',['../classIRMideaAC.html#a1ef2f532a1e6c6bfe89617d3fd0d9082',1,'IRMideaAC']]], + ['irmitsubishi112_4029',['IRMitsubishi112',['../classIRMitsubishi112.html#adea6f3b7b7619b0bf6da4a94cec9d712',1,'IRMitsubishi112']]], + ['irmitsubishi136_4030',['IRMitsubishi136',['../classIRMitsubishi136.html#ad92926b993869d0695f11ddb999b2090',1,'IRMitsubishi136']]], + ['irmitsubishiac_4031',['IRMitsubishiAC',['../classIRMitsubishiAC.html#a83fabfd9ebed5cef8dd2a18a85fdf4e6',1,'IRMitsubishiAC']]], + ['irmitsubishiheavy152ac_4032',['IRMitsubishiHeavy152Ac',['../classIRMitsubishiHeavy152Ac.html#a704e9f96c2d0a07f9ba16a400d9c97aa',1,'IRMitsubishiHeavy152Ac']]], + ['irmitsubishiheavy88ac_4033',['IRMitsubishiHeavy88Ac',['../classIRMitsubishiHeavy88Ac.html#aceabecf4a615e807a4636ff5990d77d7',1,'IRMitsubishiHeavy88Ac']]], + ['irneoclimaac_4034',['IRNeoclimaAc',['../classIRNeoclimaAc.html#a99ed2962176e5f12f8387fab977c6395',1,'IRNeoclimaAc']]], + ['irpanasonicac_4035',['IRPanasonicAc',['../classIRPanasonicAc.html#ae8b0f4518ee1a913d47a7101b0a11185',1,'IRPanasonicAc']]], + ['irrecv_4036',['IRrecv',['../classIRrecv.html#a8fe4d26ef1f863db1db9994fed5fc209',1,'IRrecv::IRrecv(const uint16_t recvpin, const uint16_t bufsize=kRawBuf, const uint8_t timeout=kTimeoutMs, const bool save_buffer=false, const uint8_t timer_num=kDefaultESP32Timer)'],['../classIRrecv.html#a3bb1bcc1c1a3184294dd35c8f6f758b1',1,'IRrecv::IRrecv(const uint16_t recvpin, const uint16_t bufsize=kRawBuf, const uint8_t timeout=kTimeoutMs, const bool save_buffer=false)']]], + ['irsamsungac_4037',['IRSamsungAc',['../classIRSamsungAc.html#a0db771b80d7d7a63b5ecb4b25efee609',1,'IRSamsungAc']]], + ['irsend_4038',['IRsend',['../classIRsend.html#a792780b7de996c90c86dd7b700eaf271',1,'IRsend']]], + ['irsharpac_4039',['IRSharpAc',['../classIRSharpAc.html#a30b5f8f634a41c943b4e1453d12bc980',1,'IRSharpAc']]], + ['irtcl112ac_4040',['IRTcl112Ac',['../classIRTcl112Ac.html#a061bdfdf4444cb5e06fa90824985c1ec',1,'IRTcl112Ac']]], + ['irtecoac_4041',['IRTecoAc',['../classIRTecoAc.html#a56e3f31a080bfd565570bf3b165e71d4',1,'IRTecoAc']]], + ['irtimer_4042',['IRtimer',['../classIRtimer.html#a09d64d689137ef8ca68973bb9e550e76',1,'IRtimer']]], + ['irtoshibaac_4043',['IRToshibaAC',['../classIRToshibaAC.html#abf2b3db316f7d6acb20c4f7ea2476ec2',1,'IRToshibaAC']]], + ['irtrotecesp_4044',['IRTrotecESP',['../classIRTrotecESP.html#a1b56b6e55bf133ccab6a482090408ee5',1,'IRTrotecESP']]], + ['irvestelac_4045',['IRVestelAc',['../classIRVestelAc.html#af1583ef81331edf112a0d04771c2cbec',1,'IRVestelAc']]], + ['irwhirlpoolac_4046',['IRWhirlpoolAc',['../classIRWhirlpoolAc.html#a89bc9d440a5f7d04a602d7bc73904bc2',1,'IRWhirlpoolAc']]], + ['isofftimeractive_4047',['isOffTimerActive',['../classIRVestelAc.html#aa756171e82ed1b43593b81aa3a63b812',1,'IRVestelAc']]], + ['isofftimerenabled_4048',['isOffTimerEnabled',['../classIRPanasonicAc.html#ac8e218b4886d66889734b01232767c8a',1,'IRPanasonicAc::isOffTimerEnabled()'],['../classIRWhirlpoolAc.html#a1bc1366524cf3c7fb426e908a166801f',1,'IRWhirlpoolAc::isOffTimerEnabled()']]], + ['isontimeractive_4049',['isOnTimerActive',['../classIRVestelAc.html#a67f0e970af50fcf6e01e4cac85c5862a',1,'IRVestelAc']]], + ['isontimerenabled_4050',['isOnTimerEnabled',['../classIRPanasonicAc.html#a04cbf8f5063a3892020d383c77abc57c',1,'IRPanasonicAc::isOnTimerEnabled()'],['../classIRWhirlpoolAc.html#aff1b8c2d063b376725a5a77745f6be3a',1,'IRWhirlpoolAc::isOnTimerEnabled()']]], + ['ispowerspecial_4051',['isPowerSpecial',['../classIRSharpAc.html#a57072f2458897ffb9184769aca10b944',1,'IRSharpAc']]], + ['isprotocolsupported_4052',['isProtocolSupported',['../classIRac.html#ad9c2fc9d07db70704f78a2d5f7be5b1c',1,'IRac']]], + ['isspecialstate_4053',['isSpecialState',['../classIRCoolixAC.html#a51bde954328ca5887a8353ba5562b3db',1,'IRCoolixAC']]], + ['isswingvtoggle_4054',['isSwingVToggle',['../classIRMideaAC.html#a848076f02a38a32c691a4617586862cc',1,'IRMideaAC']]], + ['istimecommand_4055',['isTimeCommand',['../classIRVestelAc.html#ae811a07c1a8d82e7068c39b9ca73aaf1',1,'IRVestelAc']]], + ['istimeractive_4056',['isTimerActive',['../classIRVestelAc.html#a160b73df8e1eda984f9bfbff3df7fa63',1,'IRVestelAc']]], + ['istimerenabled_4057',['isTimerEnabled',['../classIRWhirlpoolAc.html#a5a713ffed99ab3450257d83e2d6e15ee',1,'IRWhirlpoolAc']]], + ['isvalidlgac_4058',['isValidLgAc',['../classIRLgAc.html#a5984041eb12603ac1a277c28b355322a',1,'IRLgAc']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_a.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_a.html new file mode 100644 index 000000000..a81e96336 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_a.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_a.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_a.js new file mode 100644 index 000000000..42993aa20 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_a.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['kelvinator_4059',['kelvinator',['../classIRac.html#a6e4d8061841a7271205f81bd8e7d6171',1,'IRac']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_b.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_b.html new file mode 100644 index 000000000..345265d62 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_b.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_b.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_b.js new file mode 100644 index 000000000..18f4d0950 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_b.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['ledoff_4060',['ledOff',['../classIRsend.html#ae71cc5aa99f894785fb4f7abc05841b2',1,'IRsend']]], + ['ledon_4061',['ledOn',['../classIRsend.html#a13d804171fa7c14aff4def38c6ffb6c8',1,'IRsend']]], + ['lg_4062',['lg',['../classIRac.html#afad31ecf9eae573882d53dd6629485fb',1,'IRac']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_c.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_c.html new file mode 100644 index 000000000..858bfd6c9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_c.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_c.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_c.js new file mode 100644 index 000000000..a9f6f2360 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_c.js @@ -0,0 +1,25 @@ +var searchData= +[ + ['mark_4063',['mark',['../classIRsend.html#a7399389d40bfe24bc062ffca88fc3780',1,'IRsend']]], + ['markassent_4064',['markAsSent',['../classIRac.html#ad0e45b13f477e29823b8c138704536c4',1,'IRac']]], + ['match_4065',['match',['../classIRrecv.html#a8bc218dae714ab189a3da4fff269cdaa',1,'IRrecv']]], + ['matchatleast_4066',['matchAtLeast',['../classIRrecv.html#ae7bfd4ff689c7563c65c4e6e8c58187a',1,'IRrecv']]], + ['matchbytes_4067',['matchBytes',['../classIRrecv.html#adc2c9bc4c4e5741cfac7468126bf8ca6',1,'IRrecv']]], + ['matchdata_4068',['matchData',['../classIRrecv.html#a5361439cb69b1069553544e486502d2e',1,'IRrecv']]], + ['matchgeneric_4069',['matchGeneric',['../classIRrecv.html#ab783f52acc2ff4052313d6947563e4fd',1,'IRrecv::matchGeneric(volatile uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, const uint16_t hdrmark, const uint32_t hdrspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t footerspace, const bool atleast=false, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true)'],['../classIRrecv.html#a4448c1658383962d735353352987c9aa',1,'IRrecv::matchGeneric(volatile uint16_t *data_ptr, uint8_t *result_ptr, const uint16_t remaining, const uint16_t nbits, const uint16_t hdrmark, const uint32_t hdrspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, const uint16_t footermark, const uint32_t footerspace, const bool atleast=false, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true)']]], + ['matchgenericconstbittime_4070',['matchGenericConstBitTime',['../classIRrecv.html#a4582d75ef1d11aee35fce86c38dcccf0',1,'IRrecv']]], + ['matchmanchester_4071',['matchManchester',['../classIRrecv.html#ade70777ad0e047e11b99b03d8f5e3728',1,'IRrecv']]], + ['matchmanchesterdata_4072',['matchManchesterData',['../classIRrecv.html#ab44403411a217eb8ea75271575f8ab83',1,'IRrecv']]], + ['matchmark_4073',['matchMark',['../classIRrecv.html#ae78ef12b8194db5d3cb5a2605d29830d',1,'IRrecv']]], + ['matchspace_4074',['matchSpace',['../classIRrecv.html#a9fd363e8b2edee2ed3c473349ecc58fc',1,'IRrecv']]], + ['midea_4075',['midea',['../classIRac.html#a5b9c72198497eca0121945b557691309',1,'IRac']]], + ['minrepeats_4076',['minRepeats',['../classIRsend.html#ae02772f34180163861b7e4eb3520db2a',1,'IRsend']]], + ['minstostring_4077',['minsToString',['../namespaceirutils.html#aebab40a2c69624adc1a5a8a6db72952f',1,'irutils']]], + ['mitsubishi_4078',['mitsubishi',['../classIRac.html#aaa60bcac75dc5dda40c78f8c227b19a3',1,'IRac']]], + ['mitsubishi112_4079',['mitsubishi112',['../classIRac.html#a2438b6e4403d5952adb299083e038e10',1,'IRac']]], + ['mitsubishi136_4080',['mitsubishi136',['../classIRac.html#aa3033eb835cf3cd313ee2c2f38357e8e',1,'IRac']]], + ['mitsubishiheavy152_4081',['mitsubishiHeavy152',['../classIRac.html#a635b89320d878c1e3f270d7146cb9b00',1,'IRac']]], + ['mitsubishiheavy88_4082',['mitsubishiHeavy88',['../classIRac.html#af6c9084c5e902f98a03ad0eaf3b9448e',1,'IRac']]], + ['modeltostr_4083',['modelToStr',['../namespaceirutils.html#ae89b70ce66617a8707c1951eadbc6fbd',1,'irutils']]], + ['mstostring_4084',['msToString',['../namespaceirutils.html#a9c59c8dd886c283fdb8adc9082c6890a',1,'irutils']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_d.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_d.html new file mode 100644 index 000000000..2f09f51ba --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_d.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_d.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_d.js new file mode 100644 index 000000000..d3ffd6eff --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_d.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['neoclima_4085',['neoclima',['../classIRac.html#a0e468b705922e58308c5e340499f2391',1,'IRac']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_e.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_e.html new file mode 100644 index 000000000..ee5afa650 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_e.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_e.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_e.js new file mode 100644 index 000000000..1fc2ce013 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_e.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['off_4086',['off',['../classIRAmcorAc.html#a5c67c2acde4964bf863d5ae73555ea1a',1,'IRAmcorAc::off()'],['../classIRArgoAC.html#ab5ab7cc22bbce59bb02ca60431dca3fb',1,'IRArgoAC::off()'],['../classIRCarrierAc64.html#ac7a262d768626f01dac94f5e2891c98e',1,'IRCarrierAc64::off()'],['../classIRCoolixAC.html#a7538665a38e193ecd3a0bed41e9f1417',1,'IRCoolixAC::off()'],['../classIRCoronaAc.html#a3744c68ec90d89999be4db5bd6ffe2a3',1,'IRCoronaAc::off()'],['../classIRDaikinESP.html#a5d1d22f45d877660719916ca546bd3af',1,'IRDaikinESP::off()'],['../classIRDaikin2.html#a84a48dfceb4d7137eb485e6897ccceac',1,'IRDaikin2::off()'],['../classIRDaikin216.html#a086d8cea2d6dd0f74c5cbece79d91567',1,'IRDaikin216::off()'],['../classIRDaikin160.html#a95f8c71bbf861d3c884656364e04b02a',1,'IRDaikin160::off()'],['../classIRDaikin176.html#a4ad81df1fe4921abee3634bf19b0d0f7',1,'IRDaikin176::off()'],['../classIRDaikin152.html#a035588ad676a54d2b6ada8cefe10e114',1,'IRDaikin152::off()'],['../classIRDelonghiAc.html#aa2f8f1d5da390bd5e5b36102dd40f5c8',1,'IRDelonghiAc::off()'],['../classIRElectraAc.html#afe3a9b789eafbef19d015cdebf71dc0d',1,'IRElectraAc::off()'],['../classIRFujitsuAC.html#ae7a320c2d2b8afbd9a04251053831cdd',1,'IRFujitsuAC::off()'],['../classIRGoodweatherAc.html#ad6863d837140951fcc0faf629025d48e',1,'IRGoodweatherAc::off()'],['../classIRGreeAC.html#a4cce897175ed731ab62402133089ed4f',1,'IRGreeAC::off()'],['../classIRHaierACYRW02.html#a9837ba26574f8bd452d616173819a9a4',1,'IRHaierACYRW02::off()'],['../classIRHitachiAc.html#a62be5ca181c8c9d11b65b38b1ed178b5',1,'IRHitachiAc::off()'],['../classIRHitachiAc1.html#a646b554980706d0dd2ac762be8458cdb',1,'IRHitachiAc1::off()'],['../classIRHitachiAc424.html#a0815a09fc49449bac03d996c63040a5f',1,'IRHitachiAc424::off()'],['../classIRKelvinatorAC.html#a4a759df902d1465c9520da7c7c595abc',1,'IRKelvinatorAC::off()'],['../classIRLgAc.html#a6d3d50b34575fecb93ed8bd5897c3f7c',1,'IRLgAc::off()'],['../classIRMideaAC.html#a29fbafcf47dc41475d009c4c92b2917b',1,'IRMideaAC::off()'],['../classIRMitsubishiAC.html#ac204620341200994c28411f53d5aa046',1,'IRMitsubishiAC::off()'],['../classIRMitsubishi136.html#a4122014509e9e755881920650f19baf3',1,'IRMitsubishi136::off()'],['../classIRMitsubishi112.html#ab5b6370edf2626da2e9f124a218678a8',1,'IRMitsubishi112::off()'],['../classIRMitsubishiHeavy152Ac.html#a93b603cc37d2dc7e3e7005ce21a0b2d7',1,'IRMitsubishiHeavy152Ac::off()'],['../classIRMitsubishiHeavy88Ac.html#a45c56c0454755d704a3df1f1f3647130',1,'IRMitsubishiHeavy88Ac::off()'],['../classIRNeoclimaAc.html#a9a277308bf8d8b0cd06a28964e7cbafb',1,'IRNeoclimaAc::off()'],['../classIRPanasonicAc.html#a03b706293c1c5b348bba536e6d8d33f5',1,'IRPanasonicAc::off()'],['../classIRSamsungAc.html#a34cb19bb4902441a2b9f10892eb17d83',1,'IRSamsungAc::off()'],['../classIRSharpAc.html#a178925a1d7ca01aae5c107fab5b32e93',1,'IRSharpAc::off()'],['../classIRTcl112Ac.html#ab2e39430629fcada55a584cff66d2749',1,'IRTcl112Ac::off()'],['../classIRTecoAc.html#ade1b1541bf2de053c78657af1ebcd001',1,'IRTecoAc::off()'],['../classIRToshibaAC.html#a70b145f7b9c46790e4e5da812bb66e58',1,'IRToshibaAC::off()'],['../classIRTrotecESP.html#a8f300ddaf255de1cdfee10b76b1f08e0',1,'IRTrotecESP::off()'],['../classIRVestelAc.html#a59e90e51e3518ef26bb382903ce67357',1,'IRVestelAc::off()']]], + ['on_4087',['on',['../classIRAmcorAc.html#adff3f4b9f57815a4062443f3e4dab78c',1,'IRAmcorAc::on()'],['../classIRArgoAC.html#a70497752f7afd8e3274cf4d8b1e22628',1,'IRArgoAC::on()'],['../classIRCarrierAc64.html#a39c13b713e36fbf94605f251b36bdfae',1,'IRCarrierAc64::on()'],['../classIRCoolixAC.html#a59c414fe0e951cd50083ab1fc45286ed',1,'IRCoolixAC::on()'],['../classIRCoronaAc.html#a7fe14d62eaccdc2db8db168c90a3cd87',1,'IRCoronaAc::on()'],['../classIRDaikinESP.html#a502e9dea10605d52e291d49af26b07eb',1,'IRDaikinESP::on()'],['../classIRDaikin2.html#a009ac70fd8b8695f3d931a42667fdb66',1,'IRDaikin2::on()'],['../classIRDaikin216.html#a09f54bb4ed1d553b4bbf6ffe6992a755',1,'IRDaikin216::on()'],['../classIRDaikin160.html#a2b6c282ad5cb2a702857532ab020110b',1,'IRDaikin160::on()'],['../classIRDaikin176.html#a3ca59ccdad4b7958fc4dc1a4b0593f38',1,'IRDaikin176::on()'],['../classIRDaikin152.html#a10ee74aa43e3940d657ac88cb03b9138',1,'IRDaikin152::on()'],['../classIRDelonghiAc.html#ab21d64ace3107a8f3359b3828bc2cab5',1,'IRDelonghiAc::on()'],['../classIRElectraAc.html#a99e29f982435b01c726d0234a433cfa6',1,'IRElectraAc::on()'],['../classIRFujitsuAC.html#adcb24818d088c879beb7d76ada332f43',1,'IRFujitsuAC::on()'],['../classIRGoodweatherAc.html#a1e3c2a9f47376062ab66318d6af4324b',1,'IRGoodweatherAc::on()'],['../classIRGreeAC.html#a69e399e411a19e5669e752d52ae66f15',1,'IRGreeAC::on()'],['../classIRHaierACYRW02.html#aaeb257d68235278be272e521fdec7331',1,'IRHaierACYRW02::on()'],['../classIRHitachiAc.html#a855e95d55d4ebfb3958b9d80a7b42c6f',1,'IRHitachiAc::on()'],['../classIRHitachiAc1.html#aea4fe1fddb56c8df31077b301e9c6473',1,'IRHitachiAc1::on()'],['../classIRHitachiAc424.html#ad414bca642af40ed81a6cbf93a0bf40b',1,'IRHitachiAc424::on()'],['../classIRKelvinatorAC.html#a714d0e70f2996694e2c46afdd9996341',1,'IRKelvinatorAC::on()'],['../classIRLgAc.html#a171358340c1ba8f90fef0c5454f2aa41',1,'IRLgAc::on()'],['../classIRMideaAC.html#af8dde03cb641a5af4f2ef0dcf70f1ca0',1,'IRMideaAC::on()'],['../classIRMitsubishiAC.html#a2946d1b3b641d7b991c0d296d5c5e77e',1,'IRMitsubishiAC::on()'],['../classIRMitsubishi136.html#a74180e99a5f4f1f4b740b442a1b74a06',1,'IRMitsubishi136::on()'],['../classIRMitsubishi112.html#accd250f130b4d0cd61593982b84b9138',1,'IRMitsubishi112::on()'],['../classIRMitsubishiHeavy152Ac.html#a5c7aec50b53fdc3af591e077a4a268e4',1,'IRMitsubishiHeavy152Ac::on()'],['../classIRMitsubishiHeavy88Ac.html#a44ce2c4f03b8b8973922f5bf59a19d2c',1,'IRMitsubishiHeavy88Ac::on()'],['../classIRNeoclimaAc.html#ab4a23cefef02351883dc4088dec51071',1,'IRNeoclimaAc::on()'],['../classIRPanasonicAc.html#a88e6b0f607b17266567306576e623a0c',1,'IRPanasonicAc::on()'],['../classIRSamsungAc.html#a68cf52997489a1c835662c7cdf23463c',1,'IRSamsungAc::on()'],['../classIRSharpAc.html#a5c8dad46c2965fc0d87780a8bd8b98f4',1,'IRSharpAc::on()'],['../classIRTcl112Ac.html#a0bbf7f0b9753b516fda0544c17b15b8a',1,'IRTcl112Ac::on()'],['../classIRTecoAc.html#af26015e5c663c346cf7db6d8af3f8c60',1,'IRTecoAc::on()'],['../classIRToshibaAC.html#abdc35338e4a18132d56bf6b46ddea590',1,'IRToshibaAC::on()'],['../classIRTrotecESP.html#a86c050edab8409a9b38d28f311f19404',1,'IRTrotecESP::on()'],['../classIRVestelAc.html#a4ed05fb5cbdfa5677ca238616bf03922',1,'IRVestelAc::on()']]], + ['opmodetostring_4088',['opmodeToString',['../classIRac.html#a6dd1b87f2477bc3721d207b1fed482b8',1,'IRac']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_f.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_f.html new file mode 100644 index 000000000..f17c412c9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_f.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_f.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_f.js new file mode 100644 index 000000000..83b7a1a88 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/functions_f.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['panasonic_4089',['panasonic',['../classIRac.html#af873db2b9735127eb6f079861daed67a',1,'IRac']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/mag_sel.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/mag_sel.png new file mode 100644 index 000000000..39c0ed52a Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/mag_sel.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/namespaces_0.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/namespaces_0.html new file mode 100644 index 000000000..76996d1c2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/namespaces_0.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/namespaces_0.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/namespaces_0.js new file mode 100644 index 000000000..f3d7c6876 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/namespaces_0.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['iracutils_3578',['IRAcUtils',['../namespaceIRAcUtils.html',1,'']]], + ['irutils_3579',['irutils',['../namespaceirutils.html',1,'']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/namespaces_1.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/namespaces_1.html new file mode 100644 index 000000000..c69e3662f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/namespaces_1.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/namespaces_1.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/namespaces_1.js new file mode 100644 index 000000000..cc0a30d3e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/namespaces_1.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['stdac_3580',['stdAc',['../namespacestdAc.html',1,'']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/nomatches.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/nomatches.html new file mode 100644 index 000000000..437732089 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/nomatches.html @@ -0,0 +1,12 @@ + + + + + + + +
    +
    No Matches
    +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_0.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_0.html new file mode 100644 index 000000000..9a6a29ad3 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_0.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_0.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_0.js new file mode 100644 index 000000000..09c98c152 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['deprecated_20list_7122',['Deprecated List',['../deprecated.html',1,'']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_1.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_1.html new file mode 100644 index 000000000..132ee038e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_1.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_1.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_1.js new file mode 100644 index 000000000..19c13b8cf --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_1.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['irremoteesp8266_20library_20api_20documentation_7123',['IRremoteESP8266 Library API Documentation',['../index.html',1,'']]], + ['internationalisation_20_28i18n_29_20_26_20locale_20files_7124',['Internationalisation (I18N) & Locale Files',['../md_src_locale_README.html',1,'']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_2.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_2.html new file mode 100644 index 000000000..6109d4704 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_2.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_2.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_2.js new file mode 100644 index 000000000..08bad4bef --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/pages_2.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['todo_20list_7125',['Todo List',['../todo.html',1,'']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/related_0.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/related_0.html new file mode 100644 index 000000000..bbe15faaa --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/related_0.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/related_0.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/related_0.js new file mode 100644 index 000000000..ae64177b7 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/related_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['irhitachiac344_7121',['IRHitachiAc344',['../classIRHitachiAc424.html#a3c885313a79bf8c02bc5eb9f7d80088b',1,'IRHitachiAc424']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/search.css b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/search.css new file mode 100644 index 000000000..3cf9df94a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/search.css @@ -0,0 +1,271 @@ +/*---------------- Search Box */ + +#FSearchBox { + float: left; +} + +#MSearchBox { + white-space : nowrap; + float: none; + margin-top: 8px; + right: 0px; + width: 170px; + height: 24px; + z-index: 102; +} + +#MSearchBox .left +{ + display:block; + position:absolute; + left:10px; + width:20px; + height:19px; + background:url('search_l.png') no-repeat; + background-position:right; +} + +#MSearchSelect { + display:block; + position:absolute; + width:20px; + height:19px; +} + +.left #MSearchSelect { + left:4px; +} + +.right #MSearchSelect { + right:5px; +} + +#MSearchField { + display:block; + position:absolute; + height:19px; + background:url('search_m.png') repeat-x; + border:none; + width:115px; + margin-left:20px; + padding-left:4px; + color: #909090; + outline: none; + font: 9pt Arial, Verdana, sans-serif; + -webkit-border-radius: 0px; +} + +#FSearchBox #MSearchField { + margin-left:15px; +} + +#MSearchBox .right { + display:block; + position:absolute; + right:10px; + top:8px; + width:20px; + height:19px; + background:url('search_r.png') no-repeat; + background-position:left; +} + +#MSearchClose { + display: none; + position: absolute; + top: 4px; + background : none; + border: none; + margin: 0px 4px 0px 0px; + padding: 0px 0px; + outline: none; +} + +.left #MSearchClose { + left: 6px; +} + +.right #MSearchClose { + right: 2px; +} + +.MSearchBoxActive #MSearchField { + color: #000000; +} + +/*---------------- Search filter selection */ + +#MSearchSelectWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid #90A5CE; + background-color: #F9FAFC; + z-index: 10001; + padding-top: 4px; + padding-bottom: 4px; + -moz-border-radius: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); +} + +.SelectItem { + font: 8pt Arial, Verdana, sans-serif; + padding-left: 2px; + padding-right: 12px; + border: 0px; +} + +span.SelectionMark { + margin-right: 4px; + font-family: monospace; + outline-style: none; + text-decoration: none; +} + +a.SelectItem { + display: block; + outline-style: none; + color: #000000; + text-decoration: none; + padding-left: 6px; + padding-right: 12px; +} + +a.SelectItem:focus, +a.SelectItem:active { + color: #000000; + outline-style: none; + text-decoration: none; +} + +a.SelectItem:hover { + color: #FFFFFF; + background-color: #3D578C; + outline-style: none; + text-decoration: none; + cursor: pointer; + display: block; +} + +/*---------------- Search results window */ + +iframe#MSearchResults { + width: 60ex; + height: 15em; +} + +#MSearchResultsWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid #000; + background-color: #EEF1F7; + z-index:10000; +} + +/* ----------------------------------- */ + + +#SRIndex { + clear:both; + padding-bottom: 15px; +} + +.SREntry { + font-size: 10pt; + padding-left: 1ex; +} + +.SRPage .SREntry { + font-size: 8pt; + padding: 1px 5px; +} + +body.SRPage { + margin: 5px 2px; +} + +.SRChildren { + padding-left: 3ex; padding-bottom: .5em +} + +.SRPage .SRChildren { + display: none; +} + +.SRSymbol { + font-weight: bold; + color: #425E97; + font-family: Arial, Verdana, sans-serif; + text-decoration: none; + outline: none; +} + +a.SRScope { + display: block; + color: #425E97; + font-family: Arial, Verdana, sans-serif; + text-decoration: none; + outline: none; +} + +a.SRSymbol:focus, a.SRSymbol:active, +a.SRScope:focus, a.SRScope:active { + text-decoration: underline; +} + +span.SRScope { + padding-left: 4px; +} + +.SRPage .SRStatus { + padding: 2px 5px; + font-size: 8pt; + font-style: italic; +} + +.SRResult { + display: none; +} + +DIV.searchresults { + margin-left: 10px; + margin-right: 10px; +} + +/*---------------- External search page results */ + +.searchresult { + background-color: #F0F3F8; +} + +.pages b { + color: white; + padding: 5px 5px 3px 5px; + background-image: url("../tab_a.png"); + background-repeat: repeat-x; + text-shadow: 0 1px 1px #000000; +} + +.pages { + line-height: 17px; + margin-left: 4px; + text-decoration: none; +} + +.hl { + font-weight: bold; +} + +#searchresults { + margin-bottom: 20px; +} + +.searchpages { + margin-top: 10px; +} + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/search.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/search.js new file mode 100644 index 000000000..a554ab9cb --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/search.js @@ -0,0 +1,814 @@ +/* + @licstart The following is the entire license notice for the + JavaScript code in this file. + + Copyright (C) 1997-2017 by Dimitri van Heesch + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + @licend The above is the entire license notice + for the JavaScript code in this file + */ +function convertToId(search) +{ + var result = ''; + for (i=0;i do a search + { + this.Search(); + } + } + + this.OnSearchSelectKey = function(evt) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==40 && this.searchIndex0) // Up + { + this.searchIndex--; + this.OnSelectItem(this.searchIndex); + } + else if (e.keyCode==13 || e.keyCode==27) + { + this.OnSelectItem(this.searchIndex); + this.CloseSelectionWindow(); + this.DOMSearchField().focus(); + } + return false; + } + + // --------- Actions + + // Closes the results window. + this.CloseResultsWindow = function() + { + this.DOMPopupSearchResultsWindow().style.display = 'none'; + this.DOMSearchClose().style.display = 'none'; + this.Activate(false); + } + + this.CloseSelectionWindow = function() + { + this.DOMSearchSelectWindow().style.display = 'none'; + } + + // Performs a search. + this.Search = function() + { + this.keyTimeout = 0; + + // strip leading whitespace + var searchValue = this.DOMSearchField().value.replace(/^ +/, ""); + + var code = searchValue.toLowerCase().charCodeAt(0); + var idxChar = searchValue.substr(0, 1).toLowerCase(); + if ( 0xD800 <= code && code <= 0xDBFF && searchValue > 1) // surrogate pair + { + idxChar = searchValue.substr(0, 2); + } + + var resultsPage; + var resultsPageWithSearch; + var hasResultsPage; + + var idx = indexSectionsWithContent[this.searchIndex].indexOf(idxChar); + if (idx!=-1) + { + var hexCode=idx.toString(16); + resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + '.html'; + resultsPageWithSearch = resultsPage+'?'+escape(searchValue); + hasResultsPage = true; + } + else // nothing available for this search term + { + resultsPage = this.resultsPath + '/nomatches.html'; + resultsPageWithSearch = resultsPage; + hasResultsPage = false; + } + + window.frames.MSearchResults.location = resultsPageWithSearch; + var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow(); + + if (domPopupSearchResultsWindow.style.display!='block') + { + var domSearchBox = this.DOMSearchBox(); + this.DOMSearchClose().style.display = 'inline'; + if (this.insideFrame) + { + var domPopupSearchResults = this.DOMPopupSearchResults(); + domPopupSearchResultsWindow.style.position = 'relative'; + domPopupSearchResultsWindow.style.display = 'block'; + var width = document.body.clientWidth - 8; // the -8 is for IE :-( + domPopupSearchResultsWindow.style.width = width + 'px'; + domPopupSearchResults.style.width = width + 'px'; + } + else + { + var domPopupSearchResults = this.DOMPopupSearchResults(); + var left = getXPos(domSearchBox) + 150; // domSearchBox.offsetWidth; + var top = getYPos(domSearchBox) + 20; // domSearchBox.offsetHeight + 1; + domPopupSearchResultsWindow.style.display = 'block'; + left -= domPopupSearchResults.offsetWidth; + domPopupSearchResultsWindow.style.top = top + 'px'; + domPopupSearchResultsWindow.style.left = left + 'px'; + } + } + + this.lastSearchValue = searchValue; + this.lastResultsPage = resultsPage; + } + + // -------- Activation Functions + + // Activates or deactivates the search panel, resetting things to + // their default values if necessary. + this.Activate = function(isActive) + { + if (isActive || // open it + this.DOMPopupSearchResultsWindow().style.display == 'block' + ) + { + this.DOMSearchBox().className = 'MSearchBoxActive'; + + var searchField = this.DOMSearchField(); + + if (searchField.value == this.searchLabel) // clear "Search" term upon entry + { + searchField.value = ''; + this.searchActive = true; + } + } + else if (!isActive) // directly remove the panel + { + this.DOMSearchBox().className = 'MSearchBoxInactive'; + this.DOMSearchField().value = this.searchLabel; + this.searchActive = false; + this.lastSearchValue = '' + this.lastResultsPage = ''; + } + } +} + +// ----------------------------------------------------------------------- + +// The class that handles everything on the search results page. +function SearchResults(name) +{ + // The number of matches from the last run of . + this.lastMatchCount = 0; + this.lastKey = 0; + this.repeatOn = false; + + // Toggles the visibility of the passed element ID. + this.FindChildElement = function(id) + { + var parentElement = document.getElementById(id); + var element = parentElement.firstChild; + + while (element && element!=parentElement) + { + if (element.nodeName == 'DIV' && element.className == 'SRChildren') + { + return element; + } + + if (element.nodeName == 'DIV' && element.hasChildNodes()) + { + element = element.firstChild; + } + else if (element.nextSibling) + { + element = element.nextSibling; + } + else + { + do + { + element = element.parentNode; + } + while (element && element!=parentElement && !element.nextSibling); + + if (element && element!=parentElement) + { + element = element.nextSibling; + } + } + } + } + + this.Toggle = function(id) + { + var element = this.FindChildElement(id); + if (element) + { + if (element.style.display == 'block') + { + element.style.display = 'none'; + } + else + { + element.style.display = 'block'; + } + } + } + + // Searches for the passed string. If there is no parameter, + // it takes it from the URL query. + // + // Always returns true, since other documents may try to call it + // and that may or may not be possible. + this.Search = function(search) + { + if (!search) // get search word from URL + { + search = window.location.search; + search = search.substring(1); // Remove the leading '?' + search = unescape(search); + } + + search = search.replace(/^ +/, ""); // strip leading spaces + search = search.replace(/ +$/, ""); // strip trailing spaces + search = search.toLowerCase(); + search = convertToId(search); + + var resultRows = document.getElementsByTagName("div"); + var matches = 0; + + var i = 0; + while (i < resultRows.length) + { + var row = resultRows.item(i); + if (row.className == "SRResult") + { + var rowMatchName = row.id.toLowerCase(); + rowMatchName = rowMatchName.replace(/^sr\d*_/, ''); // strip 'sr123_' + + if (search.length<=rowMatchName.length && + rowMatchName.substr(0, search.length)==search) + { + row.style.display = 'block'; + matches++; + } + else + { + row.style.display = 'none'; + } + } + i++; + } + document.getElementById("Searching").style.display='none'; + if (matches == 0) // no results + { + document.getElementById("NoMatches").style.display='block'; + } + else // at least one result + { + document.getElementById("NoMatches").style.display='none'; + } + this.lastMatchCount = matches; + return true; + } + + // return the first item with index index or higher that is visible + this.NavNext = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index++; + } + return focusItem; + } + + this.NavPrev = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index--; + } + return focusItem; + } + + this.ProcessKeys = function(e) + { + if (e.type == "keydown") + { + this.repeatOn = false; + this.lastKey = e.keyCode; + } + else if (e.type == "keypress") + { + if (!this.repeatOn) + { + if (this.lastKey) this.repeatOn = true; + return false; // ignore first keypress after keydown + } + } + else if (e.type == "keyup") + { + this.lastKey = 0; + this.repeatOn = false; + } + return this.lastKey!=0; + } + + this.Nav = function(evt,itemIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + var newIndex = itemIndex-1; + var focusItem = this.NavPrev(newIndex); + if (focusItem) + { + var child = this.FindChildElement(focusItem.parentNode.parentNode.id); + if (child && child.style.display == 'block') // children visible + { + var n=0; + var tmpElem; + while (1) // search for last child + { + tmpElem = document.getElementById('Item'+newIndex+'_c'+n); + if (tmpElem) + { + focusItem = tmpElem; + } + else // found it! + { + break; + } + n++; + } + } + } + if (focusItem) + { + focusItem.focus(); + } + else // return focus to search field + { + parent.document.getElementById("MSearchField").focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = itemIndex+1; + var focusItem; + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem && elem.style.display == 'block') // children visible + { + focusItem = document.getElementById('Item'+itemIndex+'_c0'); + } + if (!focusItem) focusItem = this.NavNext(newIndex); + if (focusItem) focusItem.focus(); + } + else if (this.lastKey==39) // Right + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'block'; + } + else if (this.lastKey==37) // Left + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'none'; + } + else if (this.lastKey==27) // Escape + { + parent.searchBox.CloseResultsWindow(); + parent.document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } + + this.NavChild = function(evt,itemIndex,childIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + if (childIndex>0) + { + var newIndex = childIndex-1; + document.getElementById('Item'+itemIndex+'_c'+newIndex).focus(); + } + else // already at first child, jump to parent + { + document.getElementById('Item'+itemIndex).focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = childIndex+1; + var elem = document.getElementById('Item'+itemIndex+'_c'+newIndex); + if (!elem) // last child, jump to parent next parent + { + elem = this.NavNext(itemIndex+1); + } + if (elem) + { + elem.focus(); + } + } + else if (this.lastKey==27) // Escape + { + parent.searchBox.CloseResultsWindow(); + parent.document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } +} + +function setKeyActions(elem,action) +{ + elem.setAttribute('onkeydown',action); + elem.setAttribute('onkeypress',action); + elem.setAttribute('onkeyup',action); +} + +function setClassAttr(elem,attr) +{ + elem.setAttribute('class',attr); + elem.setAttribute('className',attr); +} + +function createResults() +{ + var results = document.getElementById("SRResults"); + for (var e=0; e + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/typedefs_0.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/typedefs_0.js new file mode 100644 index 000000000..d482b28e6 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/typedefs_0.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['string_6975',['String',['../IRremoteESP8266_8h.html#afbeda3fd1bdc8c37d01bdf9f5c8274ff',1,'IRremoteESP8266.h']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_0.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_0.html new file mode 100644 index 000000000..bf3eba5cc --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_0.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_0.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_0.js new file mode 100644 index 000000000..5dc345ec5 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_0.js @@ -0,0 +1,36 @@ +var searchData= +[ + ['_5fclean_4342',['_clean',['../classIRFujitsuAC.html#acf7808cfeb6e15cea1d5ee8196075e04',1,'IRFujitsuAC']]], + ['_5fcmd_4343',['_cmd',['../classIRFujitsuAC.html#a5e66bc4a24b892525cfa02bb4d741cbf',1,'IRFujitsuAC']]], + ['_5fdesiredtemp_4344',['_desiredtemp',['../classIRWhirlpoolAc.html#aee17cfa10f19e0df992b25cff58e9613',1,'IRWhirlpoolAc']]], + ['_5fdutycycle_4345',['_dutycycle',['../classIRsend.html#a602e96e8cdbd6af41d288d905043e51f',1,'IRsend']]], + ['_5ffan_4346',['_fan',['../classIRSharpAc.html#ad0f4e6025f2952c477bbd3f72a64d2fe',1,'IRSharpAc']]], + ['_5ffanspeed_4347',['_fanSpeed',['../classIRFujitsuAC.html#a537f02328039c044f7152bf0a61a05c9',1,'IRFujitsuAC']]], + ['_5ffilter_4348',['_filter',['../classIRFujitsuAC.html#a4a2f96f4f1cd6650d48ebc3b13fd561c',1,'IRFujitsuAC']]], + ['_5fforcepower_4349',['_forcepower',['../classIRSamsungAc.html#a022c96bfab671b1d0b6b5b331be31993',1,'IRSamsungAc']]], + ['_5ffreq_5funittest_4350',['_freq_unittest',['../classIRsend.html#a2caec2f35ecdb890b1e34d9eb3642363',1,'IRsend']]], + ['_5finverted_4351',['_inverted',['../classIRac.html#a9cfaa0b92819f06b3aa5b3e9e48b9d51',1,'IRac']]], + ['_5firsend_4352',['_irsend',['../classIRAmcorAc.html#a6245bb51fa206031c3348e3eb6cb096d',1,'IRAmcorAc::_irsend()'],['../classIRArgoAC.html#a1abd8d958c3e153c4f2aaf7a3716414e',1,'IRArgoAC::_irsend()'],['../classIRCarrierAc64.html#a17270f2b1d6cab828e2a51fc23b36437',1,'IRCarrierAc64::_irsend()'],['../classIRCoolixAC.html#a6c7033e72fb860bca600ba6ea6e7afef',1,'IRCoolixAC::_irsend()'],['../classIRCoronaAc.html#afba5a3c3cff3859303a91d136ad00b66',1,'IRCoronaAc::_irsend()'],['../classIRDaikinESP.html#a2f5a8cb170d54f06bfa3eeb9b8ff838e',1,'IRDaikinESP::_irsend()'],['../classIRDaikin2.html#aa8ba00ae2c09af098146452164c4cb3b',1,'IRDaikin2::_irsend()'],['../classIRDaikin216.html#ac0e88b92a5c75138ce5b3a31f0c09be2',1,'IRDaikin216::_irsend()'],['../classIRDaikin160.html#a3094f35b359d8774a95dd3896c0e45e4',1,'IRDaikin160::_irsend()'],['../classIRDaikin176.html#a24f7022eb1c1936f5ee95ac0d732584c',1,'IRDaikin176::_irsend()'],['../classIRDaikin128.html#a1f155cc34e6c21d206962239d0135d1b',1,'IRDaikin128::_irsend()'],['../classIRDaikin152.html#a9b203215156d48dabac0fa8fd19dc613',1,'IRDaikin152::_irsend()'],['../classIRDaikin64.html#a6eb57b0eb12dab12bd9cf2fe4fded2c7',1,'IRDaikin64::_irsend()'],['../classIRDelonghiAc.html#a8cbe8b6857b7492c108118b4eda3ecb0',1,'IRDelonghiAc::_irsend()'],['../classIRElectraAc.html#af8732b31f2a4421226220dd8a4a4f985',1,'IRElectraAc::_irsend()'],['../classIRFujitsuAC.html#a2b7fec218b3530b06ce8b49f472e9595',1,'IRFujitsuAC::_irsend()'],['../classIRGoodweatherAc.html#acf606eb9e024c99407138dbd058e98d9',1,'IRGoodweatherAc::_irsend()'],['../classIRGreeAC.html#a36390655badf0ad5b5809499a8634f70',1,'IRGreeAC::_irsend()'],['../classIRHaierAC.html#aec69643fe633a57d635754690225fdd1',1,'IRHaierAC::_irsend()'],['../classIRHaierACYRW02.html#a24dd00bfa5e062c5c7f459bcd60213b7',1,'IRHaierACYRW02::_irsend()'],['../classIRHitachiAc.html#a0e296fa54cc4c56e16c6fc58c7ad827f',1,'IRHitachiAc::_irsend()'],['../classIRHitachiAc1.html#a61ad6289fc3719a850299788e642b98b',1,'IRHitachiAc1::_irsend()'],['../classIRHitachiAc424.html#a39157a1bda46304429570be2880c6ec4',1,'IRHitachiAc424::_irsend()'],['../classIRHitachiAc3.html#a8dc3b713e29f3ea96a106868451ba728',1,'IRHitachiAc3::_irsend()'],['../classIRKelvinatorAC.html#ae3571bf6de20e47f81ad1da8f1d13118',1,'IRKelvinatorAC::_irsend()'],['../classIRLgAc.html#a779f321b65db6ad05ab3e578b38cf093',1,'IRLgAc::_irsend()'],['../classIRMideaAC.html#ae2b6068355ecdc360c4c2ca2fd8d921b',1,'IRMideaAC::_irsend()'],['../classIRMitsubishiAC.html#a6753b676690f35bc8ba73504fdc34946',1,'IRMitsubishiAC::_irsend()'],['../classIRMitsubishi136.html#acd14c7bb6b26d0603ee552a000e16d43',1,'IRMitsubishi136::_irsend()'],['../classIRMitsubishi112.html#af858d640f9b2fca053287f280c8a27c0',1,'IRMitsubishi112::_irsend()'],['../classIRMitsubishiHeavy152Ac.html#a1ebd4c8b06d64e0944358156f58d414e',1,'IRMitsubishiHeavy152Ac::_irsend()'],['../classIRMitsubishiHeavy88Ac.html#a1e999c9ee028d35c03cd6b4751bcb8be',1,'IRMitsubishiHeavy88Ac::_irsend()'],['../classIRNeoclimaAc.html#a43e42b1c7e68e5a85ed10454c6210be5',1,'IRNeoclimaAc::_irsend()'],['../classIRPanasonicAc.html#a065dcc65ef3dbb8f2384f883fb97d102',1,'IRPanasonicAc::_irsend()'],['../classIRSamsungAc.html#a5815878dbebe512c41c26924cf9f5eeb',1,'IRSamsungAc::_irsend()'],['../classIRSharpAc.html#a10ee598c31c0f8179ace953ed88e37c6',1,'IRSharpAc::_irsend()'],['../classIRTcl112Ac.html#a3f10e710a44c3a80f4f9ed5247b28058',1,'IRTcl112Ac::_irsend()'],['../classIRTecoAc.html#a283ff8b73ef2998f0668d0a03cba0938',1,'IRTecoAc::_irsend()'],['../classIRToshibaAC.html#a694609136a9cbdb9af5f8bb98411c2eb',1,'IRToshibaAC::_irsend()'],['../classIRTrotecESP.html#a1faa968fc2651dc1774160950e97a74e',1,'IRTrotecESP::_irsend()'],['../classIRVestelAc.html#a56d35fc5d39c97b4c6f2decf176e2cae',1,'IRVestelAc::_irsend()'],['../classIRWhirlpoolAc.html#af4fdac2382048e2776c787bebd482e9e',1,'IRWhirlpoolAc::_irsend()']]], + ['_5firtimer_5funittest_5fnow_4353',['_IRtimer_unittest_now',['../IRtimer_8cpp.html#a4ac531aa761a28d68edbc12967038180',1,'IRtimer.cpp']]], + ['_5flastsentpowerstate_4354',['_lastsentpowerstate',['../classIRSamsungAc.html#af1c6712dc05a451e815675abe972d9b4',1,'IRSamsungAc']]], + ['_5fmode_4355',['_mode',['../classIRFujitsuAC.html#a1b22f3bb3dc43e370aabad5b6efd7ca5',1,'IRFujitsuAC::_mode()'],['../classIRSharpAc.html#a169d5636aead556234dc301729050619',1,'IRSharpAc::_mode()']]], + ['_5fmodel_4356',['_model',['../classIRFujitsuAC.html#a181c71dbd46ceabdcfe08448ee32bba7',1,'IRFujitsuAC::_model()'],['../classIRGreeAC.html#ae357bf1611f349e2686f4f46c2581c47',1,'IRGreeAC::_model()']]], + ['_5fmodulation_4357',['_modulation',['../classIRac.html#acc6b7380f11c38d13fffa99ca2189a9b',1,'IRac']]], + ['_5foutsidequiet_4358',['_outsideQuiet',['../classIRFujitsuAC.html#a20a794245e0bc44607faf7927a285672',1,'IRFujitsuAC']]], + ['_5fpin_4359',['_pin',['../classIRac.html#aba78a2510d8cdcaf4c601e8b0574ae6c',1,'IRac']]], + ['_5fprev_4360',['_prev',['../classIRac.html#a8c63dc78c49f3714887fea0feefffd44',1,'IRac']]], + ['_5fprevioustemp_4361',['_previoustemp',['../classIRHitachiAc.html#a1368dcd7f4c0049822fd2b9b1e0acb5e',1,'IRHitachiAc::_previoustemp()'],['../classIRHitachiAc424.html#aba6c17936775e268744af23a4a533f92',1,'IRHitachiAc424::_previoustemp()']]], + ['_5fprotocol_4362',['_protocol',['../classIRLgAc.html#a9bd32e865a7358bbf32830d888e2786a',1,'IRLgAc']]], + ['_5fsaved_5ftemp_4363',['_saved_temp',['../classIRDaikin176.html#a8f1d6c765bf09c1a3dc9678c3939a5be',1,'IRDaikin176::_saved_temp()'],['../classIRDelonghiAc.html#a724aa5748e714a7f0109a2f3502cd1d1',1,'IRDelonghiAc::_saved_temp()']]], + ['_5fsaved_5ftemp_5funits_4364',['_saved_temp_units',['../classIRDelonghiAc.html#a14fba6ccbc25da76744d28e7a40c385b',1,'IRDelonghiAc']]], + ['_5fstate_5flength_4365',['_state_length',['../classIRFujitsuAC.html#aea1819d0041f305e2c990f6f3eced865',1,'IRFujitsuAC']]], + ['_5fstate_5flength_5fshort_4366',['_state_length_short',['../classIRFujitsuAC.html#a7093cf32cd2e856ff692aebc732c1d50',1,'IRFujitsuAC']]], + ['_5fswingh_4367',['_swingh',['../classIRPanasonicAc.html#ad0300ee66bcab38e13724520cb3226f9',1,'IRPanasonicAc']]], + ['_5fswingmode_4368',['_swingMode',['../classIRFujitsuAC.html#a74a00fbba55b457b68f61481ce9ffbaa',1,'IRFujitsuAC']]], + ['_5fswingvtoggle_4369',['_SwingVToggle',['../classIRMideaAC.html#adb4318940487aea09116fe6b9f061470',1,'IRMideaAC']]], + ['_5ftemp_4370',['_temp',['../classIRFujitsuAC.html#afcff35df74885c63651134ba85359694',1,'IRFujitsuAC::_temp()'],['../classIRLgAc.html#a1eeb727ee96c26b784a607aabd4577c9',1,'IRLgAc::_temp()'],['../classIRPanasonicAc.html#af6511e3c9745ff6750dc6fc3fdda21b3',1,'IRPanasonicAc::_temp()'],['../classIRSharpAc.html#a1d0a6274534123133217175920c7cd95',1,'IRSharpAc::_temp()']]], + ['_5ftimer_5fnum_4371',['_timer_num',['../classIRrecv.html#aff11c0c20735b16ce411088003607911',1,'IRrecv']]], + ['_5ftimerms_5funittest_5fnow_4372',['_TimerMs_unittest_now',['../IRtimer_8cpp.html#aed35ce7fa92ebb856a03f81e756cb2c6',1,'IRtimer.cpp']]], + ['_5ftolerance_4373',['_tolerance',['../classIRrecv.html#a0459a65dd31b215713ad66a1e4f3540e',1,'IRrecv']]], + ['_5funknown_5fthreshold_4374',['_unknown_threshold',['../classIRrecv.html#adb8cbc5c1cb739f33f5be25b3a6c79bd',1,'IRrecv']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_1.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_1.html new file mode 100644 index 000000000..49fe59a12 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_1.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_1.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_1.js new file mode 100644 index 000000000..3f8cb0a00 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_1.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['address_4375',['address',['../classdecode__results.html#a2858c3a5e28eccca95d44aaa87b70e9e',1,'decode_results']]], + ['argo_4376',['argo',['../classIRArgoAC.html#ab607bde051712a57fe9c0a0cf9da20ac',1,'IRArgoAC']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_10.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_10.html new file mode 100644 index 000000000..92982ac57 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_10.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_10.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_10.js new file mode 100644 index 000000000..d1ff18c76 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_10.js @@ -0,0 +1,11 @@ +var searchData= +[ + ['rawbuf_6946',['rawbuf',['../structirparams__t.html#a6f8a82b51fa206a8cb195e5838aa0cb3',1,'irparams_t::rawbuf()'],['../classdecode__results.html#a19043dc161cd5e0d3dcc82b5a7470e49',1,'decode_results::rawbuf()']]], + ['rawlen_6947',['rawlen',['../structirparams__t.html#a08e83386c65a90038e0d4922f1f6aa84',1,'irparams_t::rawlen()'],['../classdecode__results.html#a913e19fc5032fa1f97cf8afe0fa450ec',1,'decode_results::rawlen()']]], + ['rcvstate_6948',['rcvstate',['../structirparams__t.html#a63354788dab4569f4092cd05e77f0260',1,'irparams_t']]], + ['recvpin_6949',['recvpin',['../structirparams__t.html#a50da5aa1c42a69b01d50ea688db67d14',1,'irparams_t']]], + ['remote_6950',['remote',['../classIRDaikinESP.html#ac24751c23f6b27cb26dcd51e91c63c9b',1,'IRDaikinESP::remote()'],['../classIRGoodweatherAc.html#af511a0703a4cbc77f5b8a520abf11f2f',1,'IRGoodweatherAc::remote()'],['../classIRSharpAc.html#a411a4db0579ed84b54533dcde153d5da',1,'IRSharpAc::remote()']]], + ['remote_5fstate_6951',['remote_state',['../classIRAmcorAc.html#acef1c3896f03afd5d10d5cbb7ed105ce',1,'IRAmcorAc::remote_state()'],['../classIRCarrierAc64.html#a257272c7cb54f5854e79053c8223a43e',1,'IRCarrierAc64::remote_state()'],['../classIRCoolixAC.html#a03bf575961d4d924275cb16a45edaa46',1,'IRCoolixAC::remote_state()'],['../classIRCoronaAc.html#afcf0b21ac5c438dc560612a785a29864',1,'IRCoronaAc::remote_state()'],['../classIRDaikin2.html#a0b28396956687a4009cab7c860b9ce4b',1,'IRDaikin2::remote_state()'],['../classIRDaikin216.html#abf9bab0a52f9227d54f583488b024a85',1,'IRDaikin216::remote_state()'],['../classIRDaikin160.html#a17fb5726060e8872735559654a72cb22',1,'IRDaikin160::remote_state()'],['../classIRDaikin176.html#adb6863da11f0569524f0beb31681d0b5',1,'IRDaikin176::remote_state()'],['../classIRDaikin128.html#af1b36cc2f51cd145da3bfe7ec3d9134a',1,'IRDaikin128::remote_state()'],['../classIRDaikin152.html#aa16c89c0cb6d83aef83d293466dab197',1,'IRDaikin152::remote_state()'],['../classIRDaikin64.html#aa279d6df0d130e727c3a1500b283eda0',1,'IRDaikin64::remote_state()'],['../classIRDelonghiAc.html#a3b3364143c52dc2a29d9db43612c07b1',1,'IRDelonghiAc::remote_state()'],['../classIRElectraAc.html#a3f423f5d896e4bfc2f3a0ce04b596289',1,'IRElectraAc::remote_state()'],['../classIRFujitsuAC.html#a851b9192e1f18f6a4b2f1726d49ef33b',1,'IRFujitsuAC::remote_state()'],['../classIRGreeAC.html#a9e0cb21278ac3c9a72738ab8e6e09096',1,'IRGreeAC::remote_state()'],['../classIRHaierAC.html#a609abaeab9df642fdaccd77235a84eed',1,'IRHaierAC::remote_state()'],['../classIRHaierACYRW02.html#a08069ef89f5c5e2c1ba8563cdad24578',1,'IRHaierACYRW02::remote_state()'],['../classIRHitachiAc.html#a44b3d360b2a8044782b73f7f4a533a99',1,'IRHitachiAc::remote_state()'],['../classIRHitachiAc1.html#a13340cba808d457d6093f1c9efffc419',1,'IRHitachiAc1::remote_state()'],['../classIRHitachiAc424.html#a58bac4ef7f46ef1e9f38c1a144e2ca41',1,'IRHitachiAc424::remote_state()'],['../classIRHitachiAc3.html#a5602ded229a41796c205519449f7d509',1,'IRHitachiAc3::remote_state()'],['../classIRKelvinatorAC.html#a70f75821274e53cc5ed64ac53a6e32b4',1,'IRKelvinatorAC::remote_state()'],['../classIRLgAc.html#a481133671657b13ecce1bd08f710089d',1,'IRLgAc::remote_state()'],['../classIRMideaAC.html#a8f122367cc407e7bb658fe7f3132effb',1,'IRMideaAC::remote_state()'],['../classIRMitsubishiAC.html#ac0a149b9705371e59c45ece162bc1aab',1,'IRMitsubishiAC::remote_state()'],['../classIRMitsubishi136.html#ad1e80d693d3558f0bed4c0f7995bddd5',1,'IRMitsubishi136::remote_state()'],['../classIRMitsubishi112.html#a64a40e57208d08b5cd6ef87a7c8d6671',1,'IRMitsubishi112::remote_state()'],['../classIRMitsubishiHeavy152Ac.html#a6d333f238bf1b42e39919d4897080aa8',1,'IRMitsubishiHeavy152Ac::remote_state()'],['../classIRMitsubishiHeavy88Ac.html#a46be0e755530f59fad7d3f9050ecc107',1,'IRMitsubishiHeavy88Ac::remote_state()'],['../classIRNeoclimaAc.html#a336507e0635ede3b9ebf53881ece50bb',1,'IRNeoclimaAc::remote_state()'],['../classIRPanasonicAc.html#a85d5118c0ed947cc77f2ed94b0d44e4a',1,'IRPanasonicAc::remote_state()'],['../classIRSamsungAc.html#a5966a3b665ce034de807de1955396e10',1,'IRSamsungAc::remote_state()'],['../classIRTcl112Ac.html#a6eda1148a977a3ccf0c6c30239fca4c8',1,'IRTcl112Ac::remote_state()'],['../classIRTecoAc.html#a3c2ad7587ed4f5589deb20d8dc16b1e4',1,'IRTecoAc::remote_state()'],['../classIRToshibaAC.html#aab228aa6db2255dddf98a46a25cbb0f0',1,'IRToshibaAC::remote_state()'],['../classIRTrotecESP.html#afccba55e2c3d42c716591c10bc9afa18',1,'IRTrotecESP::remote_state()'],['../classIRVestelAc.html#a74d889a0db2fa63a2e38aaa15819568c',1,'IRVestelAc::remote_state()'],['../classIRWhirlpoolAc.html#a65333985c39773896071081ebcca4821',1,'IRWhirlpoolAc::remote_state()']]], + ['remote_5ftime_5fstate_6952',['remote_time_state',['../classIRVestelAc.html#a9b10e4a0c1f71aecbeb385666d1a53bd',1,'IRVestelAc']]], + ['repeat_6953',['repeat',['../classdecode__results.html#a09da48786fe3966cd5621840fd771bfa',1,'decode_results']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_11.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_11.html new file mode 100644 index 000000000..94f1a8cf9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_11.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_11.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_11.js new file mode 100644 index 000000000..7b6252538 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_11.js @@ -0,0 +1,15 @@ +var searchData= +[ + ['saved_5fstate_6954',['saved_state',['../classIRCoolixAC.html#aec0bce8019d7d49a30915394bee56b9a',1,'IRCoolixAC']]], + ['scrap_6955',['scrap',['../unionmagiquest.html#afd0bcf9a87f0fa2db87b68b211952a73',1,'magiquest']]], + ['sleep_6956',['sleep',['../structstdAc_1_1state__t.html#a94fa6098d7422292a1c6943973cd106a',1,'stdAc::state_t']]], + ['sleepflag_6957',['sleepFlag',['../classIRCoolixAC.html#a26560e04d1f77830e40e5570845b9e06',1,'IRCoolixAC']]], + ['start_6958',['start',['../classIRtimer.html#aaa087b8688ff8150e0fc1ec6d5c4a52a',1,'IRtimer::start()'],['../classTimerMs.html#a15ad2e08a5931397391d48f040722f65',1,'TimerMs::start()']]], + ['state_6959',['state',['../classdecode__results.html#aaeb4b1b2e950bdd181582c385b2f4305',1,'decode_results']]], + ['success_6960',['success',['../structmatch__result__t.html#a13fe18ae6cf89364df443a64295b2f90',1,'match_result_t']]], + ['swingflag_6961',['swingFlag',['../classIRCoolixAC.html#a6d61903a90cebef56b931bebbfa5cba3',1,'IRCoolixAC']]], + ['swingh_6962',['swingh',['../structstdAc_1_1state__t.html#a761bb702891ed1fa35906929a4c8a3f8',1,'stdAc::state_t']]], + ['swinghflag_6963',['swingHFlag',['../classIRCoolixAC.html#a1c5fb27fb58d4d1a1fd8c9931eba58c4',1,'IRCoolixAC']]], + ['swingv_6964',['swingv',['../structstdAc_1_1state__t.html#a35477d368350d8981ad8b7b09505857e',1,'stdAc::state_t']]], + ['swingvflag_6965',['swingVFlag',['../classIRCoolixAC.html#adf18ad8494466f6301176ce10aa3a075',1,'IRCoolixAC']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_12.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_12.html new file mode 100644 index 000000000..61c013a4e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_12.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_12.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_12.js new file mode 100644 index 000000000..97e250db2 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_12.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['timeout_6966',['timeout',['../structirparams__t.html#a132d6448ad59f03f6b35c4b04a6d1af4',1,'irparams_t']]], + ['timer_6967',['timer',['../structirparams__t.html#a6d4594a4d6bf8a2587095be7adfc018d',1,'irparams_t']]], + ['turbo_6968',['turbo',['../structstdAc_1_1state__t.html#aae084b686685f2b2a07ccdda649e358c',1,'stdAc::state_t']]], + ['turboflag_6969',['turboFlag',['../classIRCoolixAC.html#a60a8a848951555dba34f2a317d6611ea',1,'IRCoolixAC']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_13.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_13.html new file mode 100644 index 000000000..87b7ca676 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_13.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_13.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_13.js new file mode 100644 index 000000000..738a0e612 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_13.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['use_5ftime_5fstate_6970',['use_time_state',['../classIRVestelAc.html#af1b622c50a4952fb3edaf483e1bf9328',1,'IRVestelAc']]], + ['used_6971',['used',['../structmatch__result__t.html#a26cea305aa83ed65b88ac0b6ed6de54a',1,'match_result_t']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_14.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_14.html new file mode 100644 index 000000000..874fe5958 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_14.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_14.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_14.js new file mode 100644 index 000000000..20f2534d1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_14.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['value_6972',['value',['../classdecode__results.html#a033502b7a6b4b0412e5a2062e33c5f47',1,'decode_results']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_15.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_15.html new file mode 100644 index 000000000..3ca879906 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_15.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_15.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_15.js new file mode 100644 index 000000000..6837a7b68 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_15.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['wand_5fid_6973',['wand_id',['../unionmagiquest.html#a1b159cd47635d548e1d4198cd6d41e93',1,'magiquest']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_16.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_16.html new file mode 100644 index 000000000..2b5a4330f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_16.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_16.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_16.js new file mode 100644 index 000000000..f11625d47 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_16.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['zonefollowflag_6974',['zoneFollowFlag',['../classIRCoolixAC.html#a9cb37ed201fcf842c153f0414d9bfd9f',1,'IRCoolixAC']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_2.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_2.html new file mode 100644 index 000000000..0c8a18cf9 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_2.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_2.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_2.js new file mode 100644 index 000000000..a68ff94f4 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_2.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['beep_4377',['beep',['../structstdAc_1_1state__t.html#a468ce4cf8b68467964b1f1840257663d',1,'stdAc::state_t']]], + ['bits_4378',['bits',['../classdecode__results.html#aa5ba2fd53bdb36bdc120d8eabd9f36d7',1,'decode_results']]], + ['bufsize_4379',['bufsize',['../structirparams__t.html#a2b34d697b85ee6a0ce08344c941e50ec',1,'irparams_t']]], + ['byte_4380',['byte',['../unionmagiquest.html#af1a9c9a147a1610fe5f0e77ca3e09e44',1,'magiquest']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_3.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_3.html new file mode 100644 index 000000000..19a31fc28 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_3.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_3.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_3.js new file mode 100644 index 000000000..5ed66be69 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_3.js @@ -0,0 +1,10 @@ +var searchData= +[ + ['celsius_4381',['celsius',['../structstdAc_1_1state__t.html#a235b17f3979b155b368bfdc2b14123f5',1,'stdAc::state_t']]], + ['clean_4382',['clean',['../structstdAc_1_1state__t.html#a703fa57ade60d68deccbb2a59258b32a',1,'stdAc::state_t']]], + ['cleanflag_4383',['cleanFlag',['../classIRCoolixAC.html#a9280bc7517713dae451a64e35674804d',1,'IRCoolixAC']]], + ['clock_4384',['clock',['../structstdAc_1_1state__t.html#ab1d76172930ebfe992fd9b700369e787',1,'stdAc::state_t']]], + ['cmd_4385',['cmd',['../unionmagiquest.html#a71f7646ffd59f0478ae28fad2d724a44',1,'magiquest']]], + ['command_4386',['command',['../classdecode__results.html#a9b750d09f713b0693472f815fd0fd402',1,'decode_results']]], + ['cool_5fmode_4387',['cool_mode',['../classIRArgoAC.html#a74e7e489d743f213664d9259f1e7a431',1,'IRArgoAC']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_4.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_4.html new file mode 100644 index 000000000..bdc37be7f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_4.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_4.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_4.js new file mode 100644 index 000000000..1f911c339 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_4.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['data_4388',['data',['../structmatch__result__t.html#ae88be61a6d1ffa7c3525aa958f4c0d25',1,'match_result_t']]], + ['decode_5ftype_4389',['decode_type',['../classdecode__results.html#a9c0e9f161b9c90dc10b7561d4c0b50fa',1,'decode_results']]], + ['degrees_4390',['degrees',['../structstdAc_1_1state__t.html#a3d1ff0ff2e0035db4ee8ead5c53b2dbd',1,'stdAc::state_t']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_5.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_5.html new file mode 100644 index 000000000..6aa2249b4 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_5.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_5.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_5.js new file mode 100644 index 000000000..fdbe17906 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_5.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['econo_4391',['econo',['../structstdAc_1_1state__t.html#a580c826c6d9671715adfe8445531b957',1,'stdAc::state_t']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_6.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_6.html new file mode 100644 index 000000000..ce4a90635 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_6.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_6.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_6.js new file mode 100644 index 000000000..d6e83ad6b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_6.js @@ -0,0 +1,6 @@ +var searchData= +[ + ['fanspeed_4392',['fanspeed',['../structstdAc_1_1state__t.html#a28a50c877a0eaa71689ccc3bf9c957d7',1,'stdAc::state_t']]], + ['filter_4393',['filter',['../structstdAc_1_1state__t.html#a41e4b957f9e011ddb32d35bfcd56c0e7',1,'stdAc::state_t']]], + ['flap_5fmode_4394',['flap_mode',['../classIRArgoAC.html#abfc383d92ced7d47945cc5ac996e5fc4',1,'IRArgoAC']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_7.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_7.html new file mode 100644 index 000000000..39ffd4746 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_7.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_7.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_7.js new file mode 100644 index 000000000..adfaa07ee --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_7.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['heat_5fmode_4395',['heat_mode',['../classIRArgoAC.html#a255762f71502b9ffeb0686759991ec53',1,'IRArgoAC']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_8.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_8.html new file mode 100644 index 000000000..37a2eddfa --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_8.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_8.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_8.js new file mode 100644 index 000000000..e951bfb37 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_8.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['irparams_4396',['irparams',['../IRrecv_8cpp.html#a5620be27a7445f25d43dbe3432ed6fd1',1,'IRrecv.cpp']]], + ['irparams_5fsave_4397',['irparams_save',['../classIRrecv.html#a6fdac84ce51ce119972bf121ccc95aab',1,'IRrecv::irparams_save()'],['../IRrecv_8cpp.html#a96e84ae171529ee954c53e2e938dd998',1,'irparams_save(): IRrecv.cpp']]], + ['irpin_4398',['IRpin',['../classIRsend.html#ae4a6ea1e72f4861167002d6e7bf17b7c',1,'IRsend']]], + ['irremote_5fmux_4399',['irremote_mux',['../IRrecv_8cpp.html#ad2612f65707186ef7df0179d3636b4ea',1,'IRrecv.cpp']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_9.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_9.html new file mode 100644 index 000000000..21e5a4f3c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_9.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_9.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_9.js new file mode 100644 index 000000000..005123ec5 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_9.js @@ -0,0 +1,2528 @@ +var searchData= +[ + ['k3dstr_4400',['k3DStr',['../IRtext_8cpp.html#aedbfd5e861447c2cde9f7bb6aade1370',1,'k3DStr(): IRtext.cpp'],['../IRtext_8h.html#a084c940b7221cd1d85d4a3b58063051d',1,'k3DStr(): IRtext.cpp']]], + ['k6thsensestr_4401',['k6thSenseStr',['../IRtext_8cpp.html#ad0bfc24932f22a599c7e7bf04fb57b10',1,'k6thSenseStr(): IRtext.cpp'],['../IRtext_8h.html#a7425119d393b134c4659db9d35691e35',1,'k6thSenseStr(): IRtext.cpp']]], + ['k8cheatstr_4402',['k8CHeatStr',['../IRtext_8cpp.html#ac6ab822edcfe7768cd1a8b0426a1bd59',1,'k8CHeatStr(): IRtext.cpp'],['../IRtext_8h.html#acfcc1bc573f4520f3e37977a949b74e8',1,'k8CHeatStr(): IRtext.cpp']]], + ['kairflowstr_4403',['kAirFlowStr',['../IRtext_8cpp.html#a7ecf1c6454bbf9963ca85a2bd7d4a34a',1,'kAirFlowStr(): IRtext.cpp'],['../IRtext_8h.html#a0f7e35a10e28e403da578c85b0e6b180',1,'kAirFlowStr(): IRtext.cpp']]], + ['kairwellbits_4404',['kAirwellBits',['../IRremoteESP8266_8h.html#a570219a14f2d19c7a6ce0aecd37a3b1f',1,'IRremoteESP8266.h']]], + ['kairwellfootermark_4405',['kAirwellFooterMark',['../ir__Airwell_8cpp.html#a2f41c6fe12eb5b3369ffb67fc6333431',1,'ir_Airwell.cpp']]], + ['kairwellhalfclockperiod_4406',['kAirwellHalfClockPeriod',['../ir__Airwell_8cpp.html#a955f70631a1bc9be8453ccc9fbb3ecfc',1,'ir_Airwell.cpp']]], + ['kairwellhdrmark_4407',['kAirwellHdrMark',['../ir__Airwell_8cpp.html#ad0c7b6c28df61b706eef2ec05506d8c2',1,'ir_Airwell.cpp']]], + ['kairwellhdrspace_4408',['kAirwellHdrSpace',['../ir__Airwell_8cpp.html#ad7e80d679eaa5742f261619cc1115567',1,'ir_Airwell.cpp']]], + ['kairwellminrepeats_4409',['kAirwellMinRepeats',['../IRremoteESP8266_8h.html#a669217ae5aa0baa159f7452f53551875',1,'IRremoteESP8266.h']]], + ['kairwelloverhead_4410',['kAirwellOverhead',['../ir__Airwell_8cpp.html#a8365fb4b254f5eeb6fed59cdc627fead',1,'ir_Airwell.cpp']]], + ['kaiwarct501bits_4411',['kAiwaRcT501Bits',['../IRremoteESP8266_8h.html#a9078adf040d21c9c3eb10ed69f9dced6',1,'IRremoteESP8266.h']]], + ['kaiwarct501minrepeats_4412',['kAiwaRcT501MinRepeats',['../IRremoteESP8266_8h.html#ad796714d955b6cc8e207b03058eae5a3',1,'IRremoteESP8266.h']]], + ['kaiwarct501postbits_4413',['kAiwaRcT501PostBits',['../ir__Aiwa_8cpp.html#a1ad2ad119febec79cb20bf2356ae4dd4',1,'ir_Aiwa.cpp']]], + ['kaiwarct501postdata_4414',['kAiwaRcT501PostData',['../ir__Aiwa_8cpp.html#a5c8aa67edc9ceed9dc398f878930b1cb',1,'ir_Aiwa.cpp']]], + ['kaiwarct501prebits_4415',['kAiwaRcT501PreBits',['../ir__Aiwa_8cpp.html#a614f30df204126f234ce1d256406f075',1,'ir_Aiwa.cpp']]], + ['kaiwarct501predata_4416',['kAiwaRcT501PreData',['../ir__Aiwa_8cpp.html#a9aafbd2938553c9b97dac6f4e3edee6e',1,'ir_Aiwa.cpp']]], + ['kallprotocolnamesstr_4417',['kAllProtocolNamesStr',['../IRtext_8cpp.html#a3ef36cf85e44181ecc4d11085b7abed6',1,'kAllProtocolNamesStr(): IRtext.cpp'],['../IRtext_8h.html#aa0dfe94cd4cba3bec642328f399dc775',1,'kAllProtocolNamesStr(): IRtext.cpp']]], + ['kalokabits_4418',['kAlokaBits',['../IRremoteESP8266_8h.html#a864918ca63a5fe7345688a72d61ddf23',1,'IRremoteESP8266.h']]], + ['kalokaledblue_4419',['kAlokaLedBlue',['../ir__NEC_8h.html#a49908cff59d8e7a4926638c74b796c61',1,'ir_NEC.h']]], + ['kalokaledgreen_4420',['kAlokaLedGreen',['../ir__NEC_8h.html#aa6c6afc878f4b2a8d4b9349bf6766fb6',1,'ir_NEC.h']]], + ['kalokaledlightgreen_4421',['kAlokaLedLightGreen',['../ir__NEC_8h.html#ab2daa6b17fd2d5e30fc47105e4c3c6b6',1,'ir_NEC.h']]], + ['kalokaledmidblue_4422',['kAlokaLedMidBlue',['../ir__NEC_8h.html#a47d88027186cd96216bea935ca93d7bc',1,'ir_NEC.h']]], + ['kalokaledorange_4423',['kAlokaLedOrange',['../ir__NEC_8h.html#a40f8ae5d6ec8f6aa887c73f032ce03bb',1,'ir_NEC.h']]], + ['kalokaledpink_4424',['kAlokaLedPink',['../ir__NEC_8h.html#a53cf14e43062b82259e8d171a992ceff',1,'ir_NEC.h']]], + ['kalokaledpinkred_4425',['kAlokaLedPinkRed',['../ir__NEC_8h.html#a20ef8a4a844577849b4b3bc7a86fe352',1,'ir_NEC.h']]], + ['kalokaledrainbow_4426',['kAlokaLedRainbow',['../ir__NEC_8h.html#a724ce8d8c71c07a019ed2ddfba269151',1,'ir_NEC.h']]], + ['kalokaledred_4427',['kAlokaLedRed',['../ir__NEC_8h.html#ade8f47e4607be919ca05b6dd6ed23ae9',1,'ir_NEC.h']]], + ['kalokaledtreegrow_4428',['kAlokaLedTreeGrow',['../ir__NEC_8h.html#a5ecb76db25229f9f05044e54239144ee',1,'ir_NEC.h']]], + ['kalokaledwhite_4429',['kAlokaLedWhite',['../ir__NEC_8h.html#a0c0b35e9d905de0b299e38e5807f363e',1,'ir_NEC.h']]], + ['kalokaledyellow_4430',['kAlokaLedYellow',['../ir__NEC_8h.html#a1853a0e8856b8af97f458a180c41d6d5',1,'ir_NEC.h']]], + ['kalokanightfade_4431',['kAlokaNightFade',['../ir__NEC_8h.html#adb8489faf42032a38187759b5f1037a1',1,'ir_NEC.h']]], + ['kalokanighttimer_4432',['kAlokaNightTimer',['../ir__NEC_8h.html#a1b48b8bbd71fbe3728487f36123f4e4b',1,'ir_NEC.h']]], + ['kalokapower_4433',['kAlokaPower',['../ir__NEC_8h.html#a147ecbccf8f11976f65b3f374b6ab2d0',1,'ir_NEC.h']]], + ['kamcorauto_4434',['kAmcorAuto',['../ir__Amcor_8h.html#a9c02a27d5ed80963ff3b1ff32fc261c5',1,'ir_Amcor.h']]], + ['kamcorbits_4435',['kAmcorBits',['../IRremoteESP8266_8h.html#a34bcab75a8ab94adfd46a245dd0748db',1,'IRremoteESP8266.h']]], + ['kamcorchecksumbyte_4436',['kAmcorChecksumByte',['../ir__Amcor_8h.html#a6c60b38dd5b08d5787e346a55dfe0111',1,'ir_Amcor.h']]], + ['kamcorcool_4437',['kAmcorCool',['../ir__Amcor_8h.html#a221c452a3323bd4d39a6084f84ecefbd',1,'ir_Amcor.h']]], + ['kamcordefaultrepeat_4438',['kAmcorDefaultRepeat',['../IRremoteESP8266_8h.html#a746e1ce73c2ebd9bd1f5300494820a0c',1,'IRremoteESP8266.h']]], + ['kamcordry_4439',['kAmcorDry',['../ir__Amcor_8h.html#a4d285053d14cf85d0c17e738c53538cd',1,'ir_Amcor.h']]], + ['kamcorfan_4440',['kAmcorFan',['../ir__Amcor_8h.html#a5fa0c6e3a73c94fc419ff8d1aa1423c2',1,'ir_Amcor.h']]], + ['kamcorfanauto_4441',['kAmcorFanAuto',['../ir__Amcor_8h.html#a3199dbace6444ed6ca7ff2e55a8a3a24',1,'ir_Amcor.h']]], + ['kamcorfanmax_4442',['kAmcorFanMax',['../ir__Amcor_8h.html#a08ea054d4121220ba758a0e0cacef8ca',1,'ir_Amcor.h']]], + ['kamcorfanmed_4443',['kAmcorFanMed',['../ir__Amcor_8h.html#a9ef019a27cf0724ff1f1ff39e06c0c87',1,'ir_Amcor.h']]], + ['kamcorfanmin_4444',['kAmcorFanMin',['../ir__Amcor_8h.html#a0276f72dc5b39557850838c8c70fd157',1,'ir_Amcor.h']]], + ['kamcorfanoffset_4445',['kAmcorFanOffset',['../ir__Amcor_8h.html#aaa3beed08599db5e155b3b54a3fc60bd',1,'ir_Amcor.h']]], + ['kamcorfansize_4446',['kAmcorFanSize',['../ir__Amcor_8h.html#a4a6d1ad01cd89d8064efdd29311948b7',1,'ir_Amcor.h']]], + ['kamcorfootermark_4447',['kAmcorFooterMark',['../ir__Amcor_8cpp.html#a3f877b05b07810ff43712dd4412af4f5',1,'ir_Amcor.cpp']]], + ['kamcorgap_4448',['kAmcorGap',['../ir__Amcor_8cpp.html#a090f83ec3d4f3fd10baa16bf512dca23',1,'ir_Amcor.cpp']]], + ['kamcorhdrmark_4449',['kAmcorHdrMark',['../ir__Amcor_8cpp.html#ab528f545e9af4ffb0f13d5674cfd1589',1,'ir_Amcor.cpp']]], + ['kamcorhdrspace_4450',['kAmcorHdrSpace',['../ir__Amcor_8cpp.html#ae0e00c60c4220d27ef7051b45f2ae8b5',1,'ir_Amcor.cpp']]], + ['kamcorheat_4451',['kAmcorHeat',['../ir__Amcor_8h.html#a9467539574a0030d166fac79684216f8',1,'ir_Amcor.h']]], + ['kamcormax_4452',['kAmcorMax',['../ir__Amcor_8h.html#afac44479dc50e3885e474d2cf8d1f878',1,'ir_Amcor.h']]], + ['kamcormaxoffset_4453',['kAmcorMaxOffset',['../ir__Amcor_8h.html#a2740428d3e431ff7b04e85ec73009660',1,'ir_Amcor.h']]], + ['kamcormaxsize_4454',['kAmcorMaxSize',['../ir__Amcor_8h.html#a01d5ae3a2abe48f35971ad5373230ff8',1,'ir_Amcor.h']]], + ['kamcormaxtemp_4455',['kAmcorMaxTemp',['../ir__Amcor_8h.html#a6460abc4e2b44e4ef3f680c7e195c019',1,'ir_Amcor.h']]], + ['kamcormintemp_4456',['kAmcorMinTemp',['../ir__Amcor_8h.html#a2d952bf3f43cb55253a89db1bcc0b568',1,'ir_Amcor.h']]], + ['kamcormodefanbyte_4457',['kAmcorModeFanByte',['../ir__Amcor_8h.html#a077021dbba23d1727caf1fe037e5bd88',1,'ir_Amcor.h']]], + ['kamcormodeoffset_4458',['kAmcorModeOffset',['../ir__Amcor_8h.html#a1aebade414c6d493d5fd1ae8d9b4f626',1,'ir_Amcor.h']]], + ['kamcormodesize_4459',['kAmcorModeSize',['../ir__Amcor_8h.html#aa306915bcc7fcf7209584d84dc5d1aa4',1,'ir_Amcor.h']]], + ['kamcoronemark_4460',['kAmcorOneMark',['../ir__Amcor_8cpp.html#a402a3643dc6b85813eb5f28d742c4e7f',1,'ir_Amcor.cpp']]], + ['kamcoronespace_4461',['kAmcorOneSpace',['../ir__Amcor_8cpp.html#a51163573fdc7b8017c7311f0e4011b1b',1,'ir_Amcor.cpp']]], + ['kamcorpowerbyte_4462',['kAmcorPowerByte',['../ir__Amcor_8h.html#a47e85c75d262d9091f27c7ddca141ab7',1,'ir_Amcor.h']]], + ['kamcorpoweroff_4463',['kAmcorPowerOff',['../ir__Amcor_8h.html#aeccd11f34ca0a93f682ab6c144f07fb7',1,'ir_Amcor.h']]], + ['kamcorpoweroffset_4464',['kAmcorPowerOffset',['../ir__Amcor_8h.html#aeebaa4acca33937e47df058885d3167f',1,'ir_Amcor.h']]], + ['kamcorpoweron_4465',['kAmcorPowerOn',['../ir__Amcor_8h.html#adf21c2364e64c818ba5379e78cae9d5c',1,'ir_Amcor.h']]], + ['kamcorpowersize_4466',['kAmcorPowerSize',['../ir__Amcor_8h.html#a6a4e3568f341a7a60bdf7a4dc56fd482',1,'ir_Amcor.h']]], + ['kamcorspecialbyte_4467',['kAmcorSpecialByte',['../ir__Amcor_8h.html#aa73133f5a673eebd7e8ca99155138cb7',1,'ir_Amcor.h']]], + ['kamcorstatelength_4468',['kAmcorStateLength',['../IRremoteESP8266_8h.html#a62866e6918602533d590912487150bc7',1,'IRremoteESP8266.h']]], + ['kamcortempbyte_4469',['kAmcorTempByte',['../ir__Amcor_8h.html#a9d352d1da6a93fc990786662fb3698de',1,'ir_Amcor.h']]], + ['kamcortempoffset_4470',['kAmcorTempOffset',['../ir__Amcor_8h.html#ae7113af741d2edfebf0fc4d4cc181b2d',1,'ir_Amcor.h']]], + ['kamcortempsize_4471',['kAmcorTempSize',['../ir__Amcor_8h.html#a4c5fb23ff11e99a2b860553b145e33bb',1,'ir_Amcor.h']]], + ['kamcortolerance_4472',['kAmcorTolerance',['../ir__Amcor_8cpp.html#ad7a4b72f06c5e71002a44c3e4d483bef',1,'ir_Amcor.cpp']]], + ['kamcorventoffset_4473',['kAmcorVentOffset',['../ir__Amcor_8h.html#aa231f74cdba0fe6813c2d6c77268d300',1,'ir_Amcor.h']]], + ['kamcorventon_4474',['kAmcorVentOn',['../ir__Amcor_8h.html#a0774a9180ab233da61c77c717be02521',1,'ir_Amcor.h']]], + ['kamcorventsize_4475',['kAmcorVentSize',['../ir__Amcor_8h.html#a55cd6972c20ddc0fa24ee8f42b50e46f',1,'ir_Amcor.h']]], + ['kamcorzeromark_4476',['kAmcorZeroMark',['../ir__Amcor_8cpp.html#a6f16bcf81087461a4e196a2c670f29ee',1,'ir_Amcor.cpp']]], + ['kamcorzerospace_4477',['kAmcorZeroSpace',['../ir__Amcor_8cpp.html#a0cbb87d1a5bb594cf428c79cd96c8733',1,'ir_Amcor.cpp']]], + ['kargoauto_4478',['kArgoAuto',['../ir__Argo_8h.html#a527fa5776cb58f88013de5062c620b12',1,'ir_Argo.h']]], + ['kargobitmark_4479',['kArgoBitMark',['../ir__Argo_8cpp.html#aa15902c11e3a7d3cbb25504764b163c1',1,'ir_Argo.cpp']]], + ['kargobits_4480',['kArgoBits',['../IRremoteESP8266_8h.html#a351efcd1805c87bd338de81dab3f8fb2',1,'IRremoteESP8266.h']]], + ['kargocool_4481',['kArgoCool',['../ir__Argo_8h.html#ab331356887b5f8f04f5ffdf9031fde71',1,'ir_Argo.h']]], + ['kargodefaultrepeat_4482',['kArgoDefaultRepeat',['../IRremoteESP8266_8h.html#a9a2190c526885753c676db666e48b764',1,'IRremoteESP8266.h']]], + ['kargodry_4483',['kArgoDry',['../ir__Argo_8h.html#ae119706139f65f730db477d060a7bc5d',1,'ir_Argo.h']]], + ['kargofan1_4484',['kArgoFan1',['../ir__Argo_8h.html#abfbde2676afb8b027a26a49d947a1396',1,'ir_Argo.h']]], + ['kargofan2_4485',['kArgoFan2',['../ir__Argo_8h.html#a7b544220198b6aa311da78bc02b0e211',1,'ir_Argo.h']]], + ['kargofan3_4486',['kArgoFan3',['../ir__Argo_8h.html#aa34af62e7134bbca2028d74ba7dfed4e',1,'ir_Argo.h']]], + ['kargofanauto_4487',['kArgoFanAuto',['../ir__Argo_8h.html#a3b17c0ba868b439135e6e016452f1623',1,'ir_Argo.h']]], + ['kargofanoffset_4488',['kArgoFanOffset',['../ir__Argo_8h.html#ab652e466dfce6bfabab04f70e23e6bc9',1,'ir_Argo.h']]], + ['kargofansize_4489',['kArgoFanSize',['../ir__Argo_8h.html#a032348f63ce0e391120161f2547ab280',1,'ir_Argo.h']]], + ['kargoflap1_4490',['kArgoFlap1',['../ir__Argo_8h.html#a477dac25a687b9d875cf9e94623d5e84',1,'ir_Argo.h']]], + ['kargoflap2_4491',['kArgoFlap2',['../ir__Argo_8h.html#aa72401adcdd23c12d36f98370c605ef6',1,'ir_Argo.h']]], + ['kargoflap3_4492',['kArgoFlap3',['../ir__Argo_8h.html#ab18e2931823d631b533c14f417ed4adb',1,'ir_Argo.h']]], + ['kargoflap4_4493',['kArgoFlap4',['../ir__Argo_8h.html#a59204076030de56e1160fc599879b142',1,'ir_Argo.h']]], + ['kargoflap5_4494',['kArgoFlap5',['../ir__Argo_8h.html#a5a3f4c1b1303b177a924c61dfdcce3e6',1,'ir_Argo.h']]], + ['kargoflap6_4495',['kArgoFlap6',['../ir__Argo_8h.html#ac11d6b575b4abc7ac5aec9006ac41634',1,'ir_Argo.h']]], + ['kargoflapauto_4496',['kArgoFlapAuto',['../ir__Argo_8h.html#af7f4a97011f94e4bf453e7cfd01fd780',1,'ir_Argo.h']]], + ['kargoflapfull_4497',['kArgoFlapFull',['../ir__Argo_8h.html#a8befe8d8b6826fc79176b66eea8352b7',1,'ir_Argo.h']]], + ['kargogap_4498',['kArgoGap',['../ir__Argo_8cpp.html#a1a28fc063dea8beacbaac39cf8e9b81b',1,'ir_Argo.cpp']]], + ['kargohdrmark_4499',['kArgoHdrMark',['../ir__Argo_8cpp.html#a5c25d5a07e397fe86378021e7c3f2980',1,'ir_Argo.cpp']]], + ['kargohdrspace_4500',['kArgoHdrSpace',['../ir__Argo_8cpp.html#a10e8a2ac55f8b123093cd92757d1603d',1,'ir_Argo.cpp']]], + ['kargoheat_4501',['kArgoHeat',['../ir__Argo_8h.html#a431536a03ef985b53a4147df5a043b21',1,'ir_Argo.h']]], + ['kargoheatauto_4502',['kArgoHeatAuto',['../ir__Argo_8h.html#a154f8b3e0d600d87b2822027bf0c6619',1,'ir_Argo.h']]], + ['kargoheatbit_4503',['kArgoHeatBit',['../ir__Argo_8h.html#ada4b42336f3d423e3ef1060605c7f7f1',1,'ir_Argo.h']]], + ['kargoheatblink_4504',['kArgoHeatBlink',['../ir__Argo_8h.html#ad29933c939f9364399dfa0f7eaa8cce6',1,'ir_Argo.h']]], + ['kargoifeelbitoffset_4505',['kArgoIFeelBitOffset',['../ir__Argo_8h.html#a0dc059f228415b3cc7a22b50fff71e9c',1,'ir_Argo.h']]], + ['kargomaxbitoffset_4506',['kArgoMaxBitOffset',['../ir__Argo_8h.html#af487de7857781edbe368a2ba724fc7c7',1,'ir_Argo.h']]], + ['kargomaxroomtemp_4507',['kArgoMaxRoomTemp',['../ir__Argo_8h.html#a27427d4479dc126e8782985008d4dd7d',1,'ir_Argo.h']]], + ['kargomaxtemp_4508',['kArgoMaxTemp',['../ir__Argo_8h.html#a2409d2f472fb950c070fa5c0a07f69ce',1,'ir_Argo.h']]], + ['kargomintemp_4509',['kArgoMinTemp',['../ir__Argo_8h.html#a4bc4e4cfe12af43730cb128f4043ad11',1,'ir_Argo.h']]], + ['kargomodeoffset_4510',['kArgoModeOffset',['../ir__Argo_8h.html#a127045d26371fa051310208b0a3d0316',1,'ir_Argo.h']]], + ['kargomodesize_4511',['kArgoModeSize',['../ir__Argo_8h.html#a98e4d25798fb992200ade3dd5e53a401',1,'ir_Argo.h']]], + ['kargonightbitoffset_4512',['kArgoNightBitOffset',['../ir__Argo_8h.html#a4d0f78fc9017ed0ff93c77794a411738',1,'ir_Argo.h']]], + ['kargooff_4513',['kArgoOff',['../ir__Argo_8h.html#af3c6e4f7b18095179ea9e20e45e1890a',1,'ir_Argo.h']]], + ['kargoonespace_4514',['kArgoOneSpace',['../ir__Argo_8cpp.html#a47131b446d160fed9c7af1886d3580e4',1,'ir_Argo.cpp']]], + ['kargopowerbitoffset_4515',['kArgoPowerBitOffset',['../ir__Argo_8h.html#a26c8b660b323ac8a8f1bbf30d7f40bf7',1,'ir_Argo.h']]], + ['kargoroomtemphighoffset_4516',['kArgoRoomTempHighOffset',['../ir__Argo_8h.html#abe1b434b09b0c42d0d7c90496d180aeb',1,'ir_Argo.h']]], + ['kargoroomtemphighsize_4517',['kArgoRoomTempHighSize',['../ir__Argo_8h.html#a6fdcdd90f37c2f4572815b279379484d',1,'ir_Argo.h']]], + ['kargoroomtemplowoffset_4518',['kArgoRoomTempLowOffset',['../ir__Argo_8h.html#a1272f85bf89b7f0326352ae7a05b2244',1,'ir_Argo.h']]], + ['kargoroomtemplowsize_4519',['kArgoRoomTempLowSize',['../ir__Argo_8h.html#a2cd767383014feb1c6cdea45715e49c7',1,'ir_Argo.h']]], + ['kargostatelength_4520',['kArgoStateLength',['../IRremoteESP8266_8h.html#a5f38a56eacd9964a8514cb57de287a45',1,'IRremoteESP8266.h']]], + ['kargotempdelta_4521',['kArgoTempDelta',['../ir__Argo_8h.html#a7256560730a73dcaaa60cdfc8140fc0b',1,'ir_Argo.h']]], + ['kargotemphighoffset_4522',['kArgoTempHighOffset',['../ir__Argo_8h.html#af06b47b51a4b837ee92a2e2774d214e3',1,'ir_Argo.h']]], + ['kargotemphighsize_4523',['kArgoTempHighSize',['../ir__Argo_8h.html#af2b0c18a612c097f6356ff04ce9c78d0',1,'ir_Argo.h']]], + ['kargotemplowoffset_4524',['kArgoTempLowOffset',['../ir__Argo_8h.html#a17137f6bec2d629cca04a859bb48dae8',1,'ir_Argo.h']]], + ['kargotemplowsize_4525',['kArgoTempLowSize',['../ir__Argo_8h.html#aa50679112dc998ff06588d9a35ff313c',1,'ir_Argo.h']]], + ['kargozerospace_4526',['kArgoZeroSpace',['../ir__Argo_8cpp.html#a5e06b6d522b35f503ca1e5db27f32ff6',1,'ir_Argo.cpp']]], + ['kautomaticstr_4527',['kAutomaticStr',['../IRtext_8cpp.html#a66a32b6387a99572644e91f3299910a6',1,'kAutomaticStr(): IRtext.cpp'],['../IRtext_8h.html#a0fc9126a02b933a2af702cd6fdcb47ea',1,'kAutomaticStr(): IRtext.cpp']]], + ['kautostr_4528',['kAutoStr',['../IRtext_8cpp.html#ae8ec328761b0218d0b18479a972b1121',1,'kAutoStr(): IRtext.cpp'],['../IRtext_8h.html#a15a085c4f9e89926d2c165de4b1755d9',1,'kAutoStr(): IRtext.cpp']]], + ['kbeepstr_4529',['kBeepStr',['../IRtext_8cpp.html#a429f5c2f5aea162bd1568e8489aecb28',1,'kBeepStr(): IRtext.cpp'],['../IRtext_8h.html#a2e98c29968ade682d94f35e28364c878',1,'kBeepStr(): IRtext.cpp']]], + ['kbitsstr_4530',['kBitsStr',['../IRtext_8cpp.html#aaabaca413c37bb6b18dc13daf5b335c1',1,'kBitsStr(): IRtext.cpp'],['../IRtext_8h.html#aaf3e1b0041b00b261dfd949b41569d94',1,'kBitsStr(): IRtext.cpp']]], + ['kbottomstr_4531',['kBottomStr',['../IRtext_8cpp.html#ab0bd355efc13bd278a0e33765a783cd0',1,'kBottomStr(): IRtext.cpp'],['../IRtext_8h.html#accfb2322a40cfaf6707394e43f39e2a3',1,'kBottomStr(): IRtext.cpp']]], + ['kbreezestr_4532',['kBreezeStr',['../IRtext_8cpp.html#ab0317e8cf720936fb02816e7827bea9e',1,'kBreezeStr(): IRtext.cpp'],['../IRtext_8h.html#af4f31b53c295a877507e3ef5a5fbbc9d',1,'kBreezeStr(): IRtext.cpp']]], + ['kbuttonstr_4533',['kButtonStr',['../IRtext_8cpp.html#a6ee11e0a45632c54e34bed14c3a971ce',1,'kButtonStr(): IRtext.cpp'],['../IRtext_8h.html#a58bf62453a96d4e84bd1da3449b8799e',1,'kButtonStr(): IRtext.cpp']]], + ['kcancelstr_4534',['kCancelStr',['../IRtext_8cpp.html#af79c3879bac5ca97947f16c3a6a03321',1,'kCancelStr(): IRtext.cpp'],['../IRtext_8h.html#ab64c4cdebbc72cbb62ae6cd9a449876b',1,'kCancelStr(): IRtext.cpp']]], + ['kcarrierac40bitmark_4535',['kCarrierAc40BitMark',['../ir__Carrier_8cpp.html#a3f8996aa3a7b9b871bc6556f98efb345',1,'ir_Carrier.cpp']]], + ['kcarrierac40bits_4536',['kCarrierAc40Bits',['../IRremoteESP8266_8h.html#a56d1176a7b3fe59aeb3f4f39926c617d',1,'IRremoteESP8266.h']]], + ['kcarrierac40gap_4537',['kCarrierAc40Gap',['../ir__Carrier_8cpp.html#aa5f0d39a4e12645a6fb477efb3191384',1,'ir_Carrier.cpp']]], + ['kcarrierac40hdrmark_4538',['kCarrierAc40HdrMark',['../ir__Carrier_8cpp.html#a4b77665ded6dab393779d2763bc367f0',1,'ir_Carrier.cpp']]], + ['kcarrierac40hdrspace_4539',['kCarrierAc40HdrSpace',['../ir__Carrier_8cpp.html#a5ea98bc575a7ac8d7f5da937feeaeed4',1,'ir_Carrier.cpp']]], + ['kcarrierac40minrepeat_4540',['kCarrierAc40MinRepeat',['../IRremoteESP8266_8h.html#a222aa743f398883a4910fbbb6d408bdc',1,'IRremoteESP8266.h']]], + ['kcarrierac40onespace_4541',['kCarrierAc40OneSpace',['../ir__Carrier_8cpp.html#a79073c06820817e077c5bd8d9b8acfbd',1,'ir_Carrier.cpp']]], + ['kcarrierac40zerospace_4542',['kCarrierAc40ZeroSpace',['../ir__Carrier_8cpp.html#a2ee9b60c12887983a6f4f123db6fd5e9',1,'ir_Carrier.cpp']]], + ['kcarrierac64bitmark_4543',['kCarrierAc64BitMark',['../ir__Carrier_8cpp.html#ae32b2dab6a654fa293f54684da45c5c0',1,'ir_Carrier.cpp']]], + ['kcarrierac64bits_4544',['kCarrierAc64Bits',['../IRremoteESP8266_8h.html#a41bc7ab7289e499ad33901da3eab661a',1,'IRremoteESP8266.h']]], + ['kcarrierac64checksumoffset_4545',['kCarrierAc64ChecksumOffset',['../ir__Carrier_8h.html#a3aa65474b5be8c77d498b7e83d8b8f31',1,'ir_Carrier.h']]], + ['kcarrierac64checksumsize_4546',['kCarrierAc64ChecksumSize',['../ir__Carrier_8h.html#a0b446c17c4965508f335e68c786f0596',1,'ir_Carrier.h']]], + ['kcarrierac64cool_4547',['kCarrierAc64Cool',['../ir__Carrier_8h.html#aa75d5965da484d09f6f4c645cdb23869',1,'ir_Carrier.h']]], + ['kcarrierac64fan_4548',['kCarrierAc64Fan',['../ir__Carrier_8h.html#a57655ceea762b18e0dd96724ddf888bd',1,'ir_Carrier.h']]], + ['kcarrierac64fanauto_4549',['kCarrierAc64FanAuto',['../ir__Carrier_8h.html#a12d1fb295a0d9cf407040ab544acc245',1,'ir_Carrier.h']]], + ['kcarrierac64fanhigh_4550',['kCarrierAc64FanHigh',['../ir__Carrier_8h.html#a099f2e82998bd78d25cec17a4be5f230',1,'ir_Carrier.h']]], + ['kcarrierac64fanlow_4551',['kCarrierAc64FanLow',['../ir__Carrier_8h.html#aaeee61e5924bdc8028c4775f96ba14d2',1,'ir_Carrier.h']]], + ['kcarrierac64fanmedium_4552',['kCarrierAc64FanMedium',['../ir__Carrier_8h.html#aeb8943f8d9f2bd95a9df6500eea7cba4',1,'ir_Carrier.h']]], + ['kcarrierac64fanoffset_4553',['kCarrierAc64FanOffset',['../ir__Carrier_8h.html#abbd2da4887e1c313df40506c82cba836',1,'ir_Carrier.h']]], + ['kcarrierac64fansize_4554',['kCarrierAc64FanSize',['../ir__Carrier_8h.html#aebcfb795028fea2d1b4bfde9a045e672',1,'ir_Carrier.h']]], + ['kcarrierac64gap_4555',['kCarrierAc64Gap',['../ir__Carrier_8cpp.html#a6f7ba77f1350126d78a23d7ba967e258',1,'ir_Carrier.cpp']]], + ['kcarrierac64hdrmark_4556',['kCarrierAc64HdrMark',['../ir__Carrier_8cpp.html#a19dc2108d4490c82c03c87c625bc5f31',1,'ir_Carrier.cpp']]], + ['kcarrierac64hdrspace_4557',['kCarrierAc64HdrSpace',['../ir__Carrier_8cpp.html#ad73dbf55f5ffa03d92ec699b23e8ca8d',1,'ir_Carrier.cpp']]], + ['kcarrierac64heat_4558',['kCarrierAc64Heat',['../ir__Carrier_8h.html#ac261ba8bff6f103bb9043c85a6f21d58',1,'ir_Carrier.h']]], + ['kcarrierac64maxtemp_4559',['kCarrierAc64MaxTemp',['../ir__Carrier_8h.html#a5653bc180a4c849b5e0b33b957255ae4',1,'ir_Carrier.h']]], + ['kcarrierac64minrepeat_4560',['kCarrierAc64MinRepeat',['../IRremoteESP8266_8h.html#a8b2b3670dc74ce9fbf3c8b511422a06c',1,'IRremoteESP8266.h']]], + ['kcarrierac64mintemp_4561',['kCarrierAc64MinTemp',['../ir__Carrier_8h.html#a9e7a88bf52839ecb34da1966bb8a956b',1,'ir_Carrier.h']]], + ['kcarrierac64modeoffset_4562',['kCarrierAc64ModeOffset',['../ir__Carrier_8h.html#a7f2ef38df606cb00f1c859914fc6f085',1,'ir_Carrier.h']]], + ['kcarrierac64modesize_4563',['kCarrierAc64ModeSize',['../ir__Carrier_8h.html#a8d28dd57b7ad6b9f4bb2ba11fa4b63f7',1,'ir_Carrier.h']]], + ['kcarrierac64offtimerenableoffset_4564',['kCarrierAc64OffTimerEnableOffset',['../ir__Carrier_8h.html#a1afcf0873e42c5cda5328bfe97d97ade',1,'ir_Carrier.h']]], + ['kcarrierac64offtimeroffset_4565',['kCarrierAc64OffTimerOffset',['../ir__Carrier_8h.html#a0c9189a86abe1bc41f9db34e4ab77172',1,'ir_Carrier.h']]], + ['kcarrierac64onespace_4566',['kCarrierAc64OneSpace',['../ir__Carrier_8cpp.html#a58ea051d56227a4037682f5d612b4cc7',1,'ir_Carrier.cpp']]], + ['kcarrierac64ontimerenableoffset_4567',['kCarrierAc64OnTimerEnableOffset',['../ir__Carrier_8h.html#a8a03bb9d7ead5116dff0b81732300b40',1,'ir_Carrier.h']]], + ['kcarrierac64ontimeroffset_4568',['kCarrierAc64OnTimerOffset',['../ir__Carrier_8h.html#ad2fd8df9a5114e0fc34a3657aac61f9c',1,'ir_Carrier.h']]], + ['kcarrierac64poweroffset_4569',['kCarrierAc64PowerOffset',['../ir__Carrier_8h.html#a943b94e79e98237678b66f6f4a1b6af4',1,'ir_Carrier.h']]], + ['kcarrierac64sleepoffset_4570',['kCarrierAc64SleepOffset',['../ir__Carrier_8h.html#a8ae023f5e44d5c29df41ab0f5cd534a0',1,'ir_Carrier.h']]], + ['kcarrierac64swingvoffset_4571',['kCarrierAc64SwingVOffset',['../ir__Carrier_8h.html#a186dcc18acb75f98370d71f4640f02ce',1,'ir_Carrier.h']]], + ['kcarrierac64tempoffset_4572',['kCarrierAc64TempOffset',['../ir__Carrier_8h.html#a3d3663b7e55cae59f1b8bba5ffbb5fad',1,'ir_Carrier.h']]], + ['kcarrierac64tempsize_4573',['kCarrierAc64TempSize',['../ir__Carrier_8h.html#ae9e16d5ab69b493607ce84dfbded150f',1,'ir_Carrier.h']]], + ['kcarrierac64timermax_4574',['kCarrierAc64TimerMax',['../ir__Carrier_8h.html#a78a34b51e51dc3b4129f350673c9fa96',1,'ir_Carrier.h']]], + ['kcarrierac64timermin_4575',['kCarrierAc64TimerMin',['../ir__Carrier_8h.html#aeebac3e61246f2e148806d4b4e8ac13e',1,'ir_Carrier.h']]], + ['kcarrierac64timersize_4576',['kCarrierAc64TimerSize',['../ir__Carrier_8h.html#adced87f4aed397ea8f2bb5ac2749dce5',1,'ir_Carrier.h']]], + ['kcarrierac64zerospace_4577',['kCarrierAc64ZeroSpace',['../ir__Carrier_8cpp.html#af28d4332e0f1ad19aa743b993f44cdc7',1,'ir_Carrier.cpp']]], + ['kcarrieracbitmark_4578',['kCarrierAcBitMark',['../ir__Carrier_8cpp.html#af4a608f81c745734499ec1842167940b',1,'ir_Carrier.cpp']]], + ['kcarrieracbits_4579',['kCarrierAcBits',['../IRremoteESP8266_8h.html#a668d9ac84f7dae61c35534b842d4956b',1,'IRremoteESP8266.h']]], + ['kcarrieracfreq_4580',['kCarrierAcFreq',['../ir__Carrier_8cpp.html#a795dc2d9b122bd3794fddbddef571058',1,'ir_Carrier.cpp']]], + ['kcarrieracgap_4581',['kCarrierAcGap',['../ir__Carrier_8cpp.html#a00767c0b503a7fc8f0b2ddfac24a4f85',1,'ir_Carrier.cpp']]], + ['kcarrierachdrmark_4582',['kCarrierAcHdrMark',['../ir__Carrier_8cpp.html#ad9a7754e77cfcfd6c6032d497bc4528d',1,'ir_Carrier.cpp']]], + ['kcarrierachdrspace_4583',['kCarrierAcHdrSpace',['../ir__Carrier_8cpp.html#a8e09857e2fe15d6983ec0384c57140d4',1,'ir_Carrier.cpp']]], + ['kcarrieracminrepeat_4584',['kCarrierAcMinRepeat',['../IRremoteESP8266_8h.html#a78c8a8b11179e8fd20bf09fa35f6b886',1,'IRremoteESP8266.h']]], + ['kcarrieraconespace_4585',['kCarrierAcOneSpace',['../ir__Carrier_8cpp.html#ab04a214a7c2e0439384736c46ddc6c61',1,'ir_Carrier.cpp']]], + ['kcarrieraczerospace_4586',['kCarrierAcZeroSpace',['../ir__Carrier_8cpp.html#a51c9c4bbd6e2927baac15dc60c1e60fa',1,'ir_Carrier.cpp']]], + ['kceilingstr_4587',['kCeilingStr',['../IRtext_8cpp.html#a5258c9d80502d5a8e14bb324a394452b',1,'kCeilingStr(): IRtext.cpp'],['../IRtext_8h.html#aa47afe8f4c175954e9439c0c9e48c83e',1,'kCeilingStr(): IRtext.cpp']]], + ['kcelsiusstr_4588',['kCelsiusStr',['../IRtext_8cpp.html#af0ad7ca76c659a17872960bcbcfbdbbf',1,'kCelsiusStr(): IRtext.cpp'],['../IRtext_8h.html#aae21484e9f049a7cfa507068abd3915e',1,'kCelsiusStr(): IRtext.cpp']]], + ['kcentrestr_4589',['kCentreStr',['../IRtext_8cpp.html#a87a4151e0361c9f75d0d5c00f9bad1ee',1,'kCentreStr(): IRtext.cpp'],['../IRtext_8h.html#aab13bc11db65584fbb8a61c686d67228',1,'kCentreStr(): IRtext.cpp']]], + ['kchangestr_4590',['kChangeStr',['../IRtext_8cpp.html#a1f6396eb9bd4327a7a2307e5724c1dd7',1,'kChangeStr(): IRtext.cpp'],['../IRtext_8h.html#a46e6bd06cfbf5f462042d7c720db01ae',1,'kChangeStr(): IRtext.cpp']]], + ['kcirculatestr_4591',['kCirculateStr',['../IRtext_8cpp.html#a869ef1f579373ff4b5b61b1cba215680',1,'kCirculateStr(): IRtext.cpp'],['../IRtext_8h.html#a0ba8b339babc7f7f26dbab2399bcc578',1,'kCirculateStr(): IRtext.cpp']]], + ['kcleanstr_4592',['kCleanStr',['../IRtext_8cpp.html#ad2d97c52e8df2704654fdbd0a7a0561e',1,'kCleanStr(): IRtext.cpp'],['../IRtext_8h.html#a45c17b23773e9dcded65a82577b00263',1,'kCleanStr(): IRtext.cpp']]], + ['kclockstr_4593',['kClockStr',['../IRtext_8cpp.html#ad39bd469d5474159463543184cfae321',1,'kClockStr(): IRtext.cpp'],['../IRtext_8h.html#a6e4b8f591a1d3d399a559d41847b3fa8',1,'kClockStr(): IRtext.cpp']]], + ['kcodestr_4594',['kCodeStr',['../IRtext_8cpp.html#a26e4bf74871ce457f42ec839545987f4',1,'kCodeStr(): IRtext.cpp'],['../IRtext_8h.html#a58a9da5cec40746dbe20455c6ef6c8fd',1,'kCodeStr(): IRtext.cpp']]], + ['kcolonspacestr_4595',['kColonSpaceStr',['../IRtext_8cpp.html#a5d978c9ac25163a9629b7e8e2d37d25e',1,'kColonSpaceStr(): IRtext.cpp'],['../IRtext_8h.html#aab1b0d2ea5169c1e1d8eff4daef36512',1,'kColonSpaceStr(): IRtext.cpp']]], + ['kcomfortstr_4596',['kComfortStr',['../IRtext_8cpp.html#aa7f0cfdb126ff7b0f8db6033bb51f36d',1,'kComfortStr(): IRtext.cpp'],['../IRtext_8h.html#a20037561545d4ba4cfe66c1e103ecde1',1,'kComfortStr(): IRtext.cpp']]], + ['kcommandstr_4597',['kCommandStr',['../IRtext_8cpp.html#afd5865ea8c0f8565369dd2c4ee4622d6',1,'kCommandStr(): IRtext.cpp'],['../IRtext_8h.html#afdc9e8cc5c8c5c03749898d4f2d38606',1,'kCommandStr(): IRtext.cpp']]], + ['kcommaspacestr_4598',['kCommaSpaceStr',['../IRtext_8cpp.html#ac8a9678d4c9eeee17a9dc28624c0ab49',1,'kCommaSpaceStr(): IRtext.cpp'],['../IRtext_8h.html#a48f5dfcf2e0f13f502980d42e879aec3',1,'kCommaSpaceStr(): IRtext.cpp']]], + ['kcoolixauto_4599',['kCoolixAuto',['../ir__Coolix_8h.html#a73c1ef7c2c80c861256a14a9f256b125',1,'ir_Coolix.h']]], + ['kcoolixbitmark_4600',['kCoolixBitMark',['../ir__Coolix_8cpp.html#acd8562a27ec6c0a6c2cf9480082e04cd',1,'ir_Coolix.cpp']]], + ['kcoolixbitmarkticks_4601',['kCoolixBitMarkTicks',['../ir__Coolix_8cpp.html#aefaa206b4316a4fd921f7171295d1232',1,'ir_Coolix.cpp']]], + ['kcoolixbits_4602',['kCoolixBits',['../IRremoteESP8266_8h.html#aed48c68a637e4b45b80bbf4964ea79f9',1,'IRremoteESP8266.h']]], + ['kcoolixclean_4603',['kCoolixClean',['../ir__Coolix_8h.html#a5cc9fcde4a6da54917b4d69bb352bc86',1,'ir_Coolix.h']]], + ['kcoolixcmdfan_4604',['kCoolixCmdFan',['../ir__Coolix_8h.html#a7d5ff02f4a0c379322877b3dcf934c77',1,'ir_Coolix.h']]], + ['kcoolixcool_4605',['kCoolixCool',['../ir__Coolix_8h.html#ae285ee4206fe45d25bb1d99b848c7e65',1,'ir_Coolix.h']]], + ['kcoolixdefaultrepeat_4606',['kCoolixDefaultRepeat',['../IRremoteESP8266_8h.html#aa89410d369d71738c8cbefae6ac3b00f',1,'IRremoteESP8266.h']]], + ['kcoolixdefaultstate_4607',['kCoolixDefaultState',['../ir__Coolix_8h.html#ad54ebf20658c33e5ad54fc54a513511e',1,'ir_Coolix.h']]], + ['kcoolixdry_4608',['kCoolixDry',['../ir__Coolix_8h.html#a904c4135f61120e71577f6830adae689',1,'ir_Coolix.h']]], + ['kcoolixfan_4609',['kCoolixFan',['../ir__Coolix_8h.html#a2e050321c994844f2ff6668ba6973ac4',1,'ir_Coolix.h']]], + ['kcoolixfanauto_4610',['kCoolixFanAuto',['../ir__Coolix_8h.html#ac25d3c45ed7d7d30ff2ebf617d8265f0',1,'ir_Coolix.h']]], + ['kcoolixfanauto0_4611',['kCoolixFanAuto0',['../ir__Coolix_8h.html#a38cccd1edee2c88c1b080f1d5600ead7',1,'ir_Coolix.h']]], + ['kcoolixfanfixed_4612',['kCoolixFanFixed',['../ir__Coolix_8h.html#a37a3a23d8fe30df024cb844f82f90b2a',1,'ir_Coolix.h']]], + ['kcoolixfanmax_4613',['kCoolixFanMax',['../ir__Coolix_8h.html#aabb349ee111467088b9a292950aba753',1,'ir_Coolix.h']]], + ['kcoolixfanmed_4614',['kCoolixFanMed',['../ir__Coolix_8h.html#a2750626cda2e389df901b459805e09bd',1,'ir_Coolix.h']]], + ['kcoolixfanmin_4615',['kCoolixFanMin',['../ir__Coolix_8h.html#a6c0086075cce1698c48cc30e045ab5bf',1,'ir_Coolix.h']]], + ['kcoolixfanoffset_4616',['kCoolixFanOffset',['../ir__Coolix_8h.html#a1656f488974bd12db4049dfa8ff43a4e',1,'ir_Coolix.h']]], + ['kcoolixfansize_4617',['kCoolixFanSize',['../ir__Coolix_8h.html#a5f4649b5b73766245bc82191cdc0e596',1,'ir_Coolix.h']]], + ['kcoolixfantempcode_4618',['kCoolixFanTempCode',['../ir__Coolix_8h.html#a6d2d6f2fd8f5e9a4491623b9351efcba',1,'ir_Coolix.h']]], + ['kcoolixfanzonefollow_4619',['kCoolixFanZoneFollow',['../ir__Coolix_8h.html#a5a71c6acd18b3198c7900e2de34c48a3',1,'ir_Coolix.h']]], + ['kcoolixhdrmark_4620',['kCoolixHdrMark',['../ir__Coolix_8cpp.html#a746299797d958ccf116e6d1cdab3ad06',1,'ir_Coolix.cpp']]], + ['kcoolixhdrmarkticks_4621',['kCoolixHdrMarkTicks',['../ir__Coolix_8cpp.html#a04d520a0fe3d773f377810174e5463a4',1,'ir_Coolix.cpp']]], + ['kcoolixhdrspace_4622',['kCoolixHdrSpace',['../ir__Coolix_8cpp.html#ab7ff2a6bd99e0e6a0db3f14350cca84c',1,'ir_Coolix.cpp']]], + ['kcoolixhdrspaceticks_4623',['kCoolixHdrSpaceTicks',['../ir__Coolix_8cpp.html#a58951e9800513b019ccb9f04ae55716f',1,'ir_Coolix.cpp']]], + ['kcoolixheat_4624',['kCoolixHeat',['../ir__Coolix_8h.html#a234b39696f0b2fac6b37aa309082505e',1,'ir_Coolix.h']]], + ['kcoolixled_4625',['kCoolixLed',['../ir__Coolix_8h.html#a68ae46e117caf0d7a3cc2ef9492495f1',1,'ir_Coolix.h']]], + ['kcoolixmingap_4626',['kCoolixMinGap',['../ir__Coolix_8cpp.html#a46da2480f6850af899db74a4f2270cdc',1,'ir_Coolix.cpp']]], + ['kcoolixmingapticks_4627',['kCoolixMinGapTicks',['../ir__Coolix_8cpp.html#a94f47fbf027fcb90664b302ff123f535',1,'ir_Coolix.cpp']]], + ['kcoolixmodeoffset_4628',['kCoolixModeOffset',['../ir__Coolix_8h.html#acd17067177e1cc6776b7932afd9fbdb2',1,'ir_Coolix.h']]], + ['kcoolixmodesize_4629',['kCoolixModeSize',['../ir__Coolix_8h.html#a69e5ee4c5eb95ca3346d9d9186a688a8',1,'ir_Coolix.h']]], + ['kcoolixoff_4630',['kCoolixOff',['../ir__Coolix_8h.html#aef6f59b83a14b8505f395b2eb8d8ad39',1,'ir_Coolix.h']]], + ['kcoolixonespace_4631',['kCoolixOneSpace',['../ir__Coolix_8cpp.html#a97a8439ace71584e36ab7306c3d53749',1,'ir_Coolix.cpp']]], + ['kcoolixonespaceticks_4632',['kCoolixOneSpaceTicks',['../ir__Coolix_8cpp.html#a78770eaf597e4aa2ed539248ef10ec11',1,'ir_Coolix.cpp']]], + ['kcoolixprefix_4633',['kCoolixPrefix',['../ir__Coolix_8h.html#a1b88ef6651189ba330d8e2847528964b',1,'ir_Coolix.h']]], + ['kcoolixsensortempignorecode_4634',['kCoolixSensorTempIgnoreCode',['../ir__Coolix_8h.html#ae3aba531b0c0053424786ec4bb2be934',1,'ir_Coolix.h']]], + ['kcoolixsensortempmax_4635',['kCoolixSensorTempMax',['../ir__Coolix_8h.html#a71641b1240ee439e77128165cedf899f',1,'ir_Coolix.h']]], + ['kcoolixsensortempmin_4636',['kCoolixSensorTempMin',['../ir__Coolix_8h.html#a48f3f3ad79a53e0758270647db0b089c',1,'ir_Coolix.h']]], + ['kcoolixsensortempoffset_4637',['kCoolixSensorTempOffset',['../ir__Coolix_8h.html#a03edec58ad078d7de7436929c463898a',1,'ir_Coolix.h']]], + ['kcoolixsensortempsize_4638',['kCoolixSensorTempSize',['../ir__Coolix_8h.html#a979d1d4f84432afc29ac3fcc78353d6c',1,'ir_Coolix.h']]], + ['kcoolixsleep_4639',['kCoolixSleep',['../ir__Coolix_8h.html#aa7f9f96e56bd3f6b814bc84b947b2417',1,'ir_Coolix.h']]], + ['kcoolixswing_4640',['kCoolixSwing',['../ir__Coolix_8h.html#a799ad5ab7cf43f0aac3c342305f14b90',1,'ir_Coolix.h']]], + ['kcoolixswingh_4641',['kCoolixSwingH',['../ir__Coolix_8h.html#a877bd2731dfc86d864e38a5ceb4ede6e',1,'ir_Coolix.h']]], + ['kcoolixswingv_4642',['kCoolixSwingV',['../ir__Coolix_8h.html#ab9fcaf25426f1f9ad293e165f8c0bf38',1,'ir_Coolix.h']]], + ['kcoolixtempmap_4643',['kCoolixTempMap',['../ir__Coolix_8h.html#a9c8931df1dbed38c8119f6605266c710',1,'ir_Coolix.h']]], + ['kcoolixtempmax_4644',['kCoolixTempMax',['../ir__Coolix_8h.html#afbbb02bfeaaf5cb558ca28cdd5cfc4c3',1,'ir_Coolix.h']]], + ['kcoolixtempmin_4645',['kCoolixTempMin',['../ir__Coolix_8h.html#accd37cf257fa5fbeb64e28f0d63888fb',1,'ir_Coolix.h']]], + ['kcoolixtempoffset_4646',['kCoolixTempOffset',['../ir__Coolix_8h.html#ac49173b671af51026e378d65c7bc696b',1,'ir_Coolix.h']]], + ['kcoolixtemprange_4647',['kCoolixTempRange',['../ir__Coolix_8h.html#a74e3e75466fd27672968d660e3fddc9a',1,'ir_Coolix.h']]], + ['kcoolixtempsize_4648',['kCoolixTempSize',['../ir__Coolix_8h.html#a7a22c5c9bdd23ef80ffe9d6760c0650e',1,'ir_Coolix.h']]], + ['kcoolixtick_4649',['kCoolixTick',['../ir__Coolix_8cpp.html#a61ddf842920e2b3e33fdb856bd911eae',1,'ir_Coolix.cpp']]], + ['kcoolixturbo_4650',['kCoolixTurbo',['../ir__Coolix_8h.html#ade957b6f4a6cdb064c709972a5c31a4b',1,'ir_Coolix.h']]], + ['kcoolixunknown_4651',['kCoolixUnknown',['../ir__Coolix_8h.html#a2913e31a9dc5b89cbcae940cd5d59497',1,'ir_Coolix.h']]], + ['kcoolixzerospace_4652',['kCoolixZeroSpace',['../ir__Coolix_8cpp.html#a1a9ccf6b91e786f310ffe53d55cfd6d1',1,'ir_Coolix.cpp']]], + ['kcoolixzerospaceticks_4653',['kCoolixZeroSpaceTicks',['../ir__Coolix_8cpp.html#af1a750cb3e1f142326cd177118c27136',1,'ir_Coolix.cpp']]], + ['kcoolixzonefollowmaskoffset_4654',['kCoolixZoneFollowMaskOffset',['../ir__Coolix_8h.html#ae5da4da07b9d1bb715102cafd4a0105e',1,'ir_Coolix.h']]], + ['kcoolstr_4655',['kCoolStr',['../IRtext_8cpp.html#a31258a2210b16dc977bcfd96938a8937',1,'kCoolStr(): IRtext.cpp'],['../IRtext_8h.html#ac25d86b97b8e53292dc8d0604ae263a3',1,'kCoolStr(): IRtext.cpp']]], + ['kcoronaacbitmark_4656',['kCoronaAcBitMark',['../ir__Corona_8cpp.html#a1ecb863f625463289d34e210885238db',1,'ir_Corona.cpp']]], + ['kcoronaacbits_4657',['kCoronaAcBits',['../IRremoteESP8266_8h.html#aaf59be616d7e3a5e605b8d1e08f20686',1,'IRremoteESP8266.h']]], + ['kcoronaacbitsshort_4658',['kCoronaAcBitsShort',['../IRremoteESP8266_8h.html#a1191a9293b03aa14426083b6f411a4e3',1,'IRremoteESP8266.h']]], + ['kcoronaacfanauto_4659',['kCoronaAcFanAuto',['../ir__Corona_8h.html#a8c97a0c674c000e4486159d628f1aa0a',1,'ir_Corona.h']]], + ['kcoronaacfanhigh_4660',['kCoronaAcFanHigh',['../ir__Corona_8h.html#a4f58be196a744892402e287b12502dcb',1,'ir_Corona.h']]], + ['kcoronaacfanlow_4661',['kCoronaAcFanLow',['../ir__Corona_8h.html#af9e5c729be856bf4b1bc10568f96c183',1,'ir_Corona.h']]], + ['kcoronaacfanmedium_4662',['kCoronaAcFanMedium',['../ir__Corona_8h.html#a9d6b46c006bd6ea54a14b92a2d7a3dff',1,'ir_Corona.h']]], + ['kcoronaacfanoffset_4663',['kCoronaAcFanOffset',['../ir__Corona_8h.html#ab9944dc3abdc09c4d616f43aaffccdec',1,'ir_Corona.h']]], + ['kcoronaacfansize_4664',['kCoronaAcFanSize',['../ir__Corona_8h.html#a07463e8e2e7d2bf004142ec6b89c7851',1,'ir_Corona.h']]], + ['kcoronaacfreq_4665',['kCoronaAcFreq',['../ir__Corona_8cpp.html#a0cb56860c88e9503743bcf94068bbf56',1,'ir_Corona.cpp']]], + ['kcoronaachdrmark_4666',['kCoronaAcHdrMark',['../ir__Corona_8cpp.html#a697d84f13a1228dbae3cfb491124689a',1,'ir_Corona.cpp']]], + ['kcoronaachdrspace_4667',['kCoronaAcHdrSpace',['../ir__Corona_8cpp.html#ad2425c406aa36c7752832d19f4a735f7',1,'ir_Corona.cpp']]], + ['kcoronaacmaxtemp_4668',['kCoronaAcMaxTemp',['../ir__Corona_8h.html#aa6d199e5bb8382443da4e1f303dd7988',1,'ir_Corona.h']]], + ['kcoronaacmintemp_4669',['kCoronaAcMinTemp',['../ir__Corona_8h.html#ae984b624da5e2d5ef1405e1b8d9424ba',1,'ir_Corona.h']]], + ['kcoronaacmodecool_4670',['kCoronaAcModeCool',['../ir__Corona_8h.html#a6f8bb2e27990014686828b4b7e2c84c6',1,'ir_Corona.h']]], + ['kcoronaacmodedry_4671',['kCoronaAcModeDry',['../ir__Corona_8h.html#afd47996b221103ae142363f04014fb4b',1,'ir_Corona.h']]], + ['kcoronaacmodefan_4672',['kCoronaAcModeFan',['../ir__Corona_8h.html#ab8098af3e0f9cd82a7c9c771ffd8ad15',1,'ir_Corona.h']]], + ['kcoronaacmodeheat_4673',['kCoronaAcModeHeat',['../ir__Corona_8h.html#a7f3c7c051ae3ee07621c47505a87bec1',1,'ir_Corona.h']]], + ['kcoronaacmodeoffset_4674',['kCoronaAcModeOffset',['../ir__Corona_8h.html#aa4caa3638ad09dc3a223320651adbd49',1,'ir_Corona.h']]], + ['kcoronaacmodesize_4675',['kCoronaAcModeSize',['../ir__Corona_8h.html#a38baa949868e16e67d7c2eb933b5019d',1,'ir_Corona.h']]], + ['kcoronaacofftimersection_4676',['kCoronaAcOffTimerSection',['../ir__Corona_8h.html#ac2cfdbf9b3ed3d85c0e298c3de8f357b',1,'ir_Corona.h']]], + ['kcoronaaconespace_4677',['kCoronaAcOneSpace',['../ir__Corona_8cpp.html#a6d9c199bdefbbb30b9561c5498c5a76e',1,'ir_Corona.cpp']]], + ['kcoronaacontimersection_4678',['kCoronaAcOnTimerSection',['../ir__Corona_8h.html#a711b7b5bd2081ca9b1e7ab25573ff612',1,'ir_Corona.h']]], + ['kcoronaacoverhead_4679',['kCoronaAcOverhead',['../ir__Corona_8cpp.html#aaef71b297a7868863a2ad7219bafabeb',1,'ir_Corona.cpp']]], + ['kcoronaacoverheadshort_4680',['kCoronaAcOverheadShort',['../ir__Corona_8cpp.html#a56010f67a047f551db681bb0ec8c35f7',1,'ir_Corona.cpp']]], + ['kcoronaacpowerbuttonoffset_4681',['kCoronaAcPowerButtonOffset',['../ir__Corona_8h.html#a71b6c16b1b5cffbd1991fea675e5a65e',1,'ir_Corona.h']]], + ['kcoronaacpoweroffset_4682',['kCoronaAcPowerOffset',['../ir__Corona_8h.html#ac2258a233d0f1ef3207fdd5abd8c855d',1,'ir_Corona.h']]], + ['kcoronaacpowersaveoffset_4683',['kCoronaAcPowerSaveOffset',['../ir__Corona_8h.html#a3bd4f3e2a1001aede28c886e7bbe42ae',1,'ir_Corona.h']]], + ['kcoronaacsectionbytes_4684',['kCoronaAcSectionBytes',['../ir__Corona_8h.html#a094063159064053dd5e5059eb0d90f7c',1,'ir_Corona.h']]], + ['kcoronaacsectiondata0base_4685',['kCoronaAcSectionData0Base',['../ir__Corona_8h.html#a2d0b1f5a0839839a17947bde624d4c74',1,'ir_Corona.h']]], + ['kcoronaacsectiondata0invpos_4686',['kCoronaAcSectionData0InvPos',['../ir__Corona_8h.html#a1a16967cb9024658763c7e6b6b5f8dd3',1,'ir_Corona.h']]], + ['kcoronaacsectiondata0pos_4687',['kCoronaAcSectionData0Pos',['../ir__Corona_8h.html#a285f66040fa3db6c9955a97ef6eee4b7',1,'ir_Corona.h']]], + ['kcoronaacsectiondata1invpos_4688',['kCoronaAcSectionData1InvPos',['../ir__Corona_8h.html#ad32635d2264331f4ee128e990411a704',1,'ir_Corona.h']]], + ['kcoronaacsectiondata1pos_4689',['kCoronaAcSectionData1Pos',['../ir__Corona_8h.html#a1b10ed7cf1c43a3a8be6de6d3cfc12af',1,'ir_Corona.h']]], + ['kcoronaacsectionheader0_4690',['kCoronaAcSectionHeader0',['../ir__Corona_8h.html#a39a2c0d214a10f8f9685e9955c0be0a4',1,'ir_Corona.h']]], + ['kcoronaacsectionheader0pos_4691',['kCoronaAcSectionHeader0Pos',['../ir__Corona_8h.html#a8641d0234280b8cc3bb255abebea6540',1,'ir_Corona.h']]], + ['kcoronaacsectionheader1_4692',['kCoronaAcSectionHeader1',['../ir__Corona_8h.html#a8a661569fc7b97ba2e9e755b944162f8',1,'ir_Corona.h']]], + ['kcoronaacsectionheader1pos_4693',['kCoronaAcSectionHeader1Pos',['../ir__Corona_8h.html#adaadcbe7d57b048250f32b44a96d3853',1,'ir_Corona.h']]], + ['kcoronaacsectionlabelbase_4694',['kCoronaAcSectionLabelBase',['../ir__Corona_8h.html#a6ff8a3461b87df048878faf49c12d064',1,'ir_Corona.h']]], + ['kcoronaacsectionlabelpos_4695',['kCoronaAcSectionLabelPos',['../ir__Corona_8h.html#a5c68109fb92da47236c4100c2db28e2c',1,'ir_Corona.h']]], + ['kcoronaacsections_4696',['kCoronaAcSections',['../ir__Corona_8h.html#a37e6cc5e2e186b2f5c5c938496ece111',1,'ir_Corona.h']]], + ['kcoronaacsettingssection_4697',['kCoronaAcSettingsSection',['../ir__Corona_8h.html#a5a83a045fd9878eae073f25e6c5b4753',1,'ir_Corona.h']]], + ['kcoronaacspacegap_4698',['kCoronaAcSpaceGap',['../ir__Corona_8cpp.html#a50f46039059d2a427bc9bc93c53df4fd',1,'ir_Corona.cpp']]], + ['kcoronaacstatelength_4699',['kCoronaAcStateLength',['../IRremoteESP8266_8h.html#ab18df94a82b365ff30caaabb05a9fcaf',1,'IRremoteESP8266.h']]], + ['kcoronaacstatelengthshort_4700',['kCoronaAcStateLengthShort',['../IRremoteESP8266_8h.html#a32b65ada4941a9622fbbc60f01b82425',1,'IRremoteESP8266.h']]], + ['kcoronaacswingvtoggleoffset_4701',['kCoronaAcSwingVToggleOffset',['../ir__Corona_8h.html#a1475a44b94a8cfe83fb48b3c3d98e148',1,'ir_Corona.h']]], + ['kcoronaactempoffset_4702',['kCoronaAcTempOffset',['../ir__Corona_8h.html#ae31731c985397a9a8b66ab933deccd7c',1,'ir_Corona.h']]], + ['kcoronaactempsize_4703',['kCoronaAcTempSize',['../ir__Corona_8h.html#a69dac2ce8e51b8e1890c8b7844eab9dd',1,'ir_Corona.h']]], + ['kcoronaactimermax_4704',['kCoronaAcTimerMax',['../ir__Corona_8h.html#af0428879b0fd39def7ea41e2906d9127',1,'ir_Corona.h']]], + ['kcoronaactimeroff_4705',['kCoronaAcTimerOff',['../ir__Corona_8h.html#af0feaf445fae561c3fa18ec68a19edef',1,'ir_Corona.h']]], + ['kcoronaactimerunitspermin_4706',['kCoronaAcTimerUnitsPerMin',['../ir__Corona_8h.html#a7f76e80480abdbdcdaf39186901950a4',1,'ir_Corona.h']]], + ['kcoronaaczerospace_4707',['kCoronaAcZeroSpace',['../ir__Corona_8cpp.html#af64bbcaf63ca9d06089de382354eb2d9',1,'ir_Corona.cpp']]], + ['kcoronatolerance_4708',['kCoronaTolerance',['../ir__Corona_8cpp.html#aad3726c95bfd7a9f79ba1e0c7058bb7b',1,'ir_Corona.cpp']]], + ['kdaikin128auto_4709',['kDaikin128Auto',['../ir__Daikin_8h.html#a1d2a0f9db8e1be93bff12ec23ba212e0',1,'ir_Daikin.h']]], + ['kdaikin128bitceiling_4710',['kDaikin128BitCeiling',['../ir__Daikin_8h.html#a0e1d1c1e7544eb455187290dbe4a1520',1,'ir_Daikin.h']]], + ['kdaikin128bitecono_4711',['kDaikin128BitEcono',['../ir__Daikin_8h.html#a34add42c4df4db799ddf52e8e5587dee',1,'ir_Daikin.h']]], + ['kdaikin128biteconooffset_4712',['kDaikin128BitEconoOffset',['../ir__Daikin_8h.html#af822203d873d9b847c3a7b08d236f82b',1,'ir_Daikin.h']]], + ['kdaikin128bithalfhour_4713',['kDaikin128BitHalfHour',['../ir__Daikin_8h.html#abf955f8f24fd37bbe21222ca160b3299',1,'ir_Daikin.h']]], + ['kdaikin128bitmark_4714',['kDaikin128BitMark',['../ir__Daikin_8h.html#a5178ac70eb4e134597e504d373d52fcd',1,'ir_Daikin.h']]], + ['kdaikin128bitpowertoggle_4715',['kDaikin128BitPowerToggle',['../ir__Daikin_8h.html#a813506d8d3f8b6933379bcfc097e4b29',1,'ir_Daikin.h']]], + ['kdaikin128bitpowertoggleoffset_4716',['kDaikin128BitPowerToggleOffset',['../ir__Daikin_8h.html#a05e33573c5050b1e54721a1716d652b5',1,'ir_Daikin.h']]], + ['kdaikin128bits_4717',['kDaikin128Bits',['../IRremoteESP8266_8h.html#a5bb2e6f8acbc0123de5ac0fd76e1646a',1,'IRremoteESP8266.h']]], + ['kdaikin128bitsleep_4718',['kDaikin128BitSleep',['../ir__Daikin_8h.html#a0cb96f1803fab5bfac8ef79a311308de',1,'ir_Daikin.h']]], + ['kdaikin128bitsleepoffset_4719',['kDaikin128BitSleepOffset',['../ir__Daikin_8h.html#a7b4aa1ef19f1c23ef74b45eb90734c6f',1,'ir_Daikin.h']]], + ['kdaikin128bitswing_4720',['kDaikin128BitSwing',['../ir__Daikin_8h.html#a8f6ab5b7f9871f08364abf3337ae48b4',1,'ir_Daikin.h']]], + ['kdaikin128bitswingoffset_4721',['kDaikin128BitSwingOffset',['../ir__Daikin_8h.html#a7f98cf3863ab58b147dc31c497bc07bc',1,'ir_Daikin.h']]], + ['kdaikin128bittimerenabled_4722',['kDaikin128BitTimerEnabled',['../ir__Daikin_8h.html#a1197dadb35f318b000ff6ee7ad3ca8b0',1,'ir_Daikin.h']]], + ['kdaikin128bittimerenabledoffset_4723',['kDaikin128BitTimerEnabledOffset',['../ir__Daikin_8h.html#af913ee51e5b90ad12f87dbed9ce349d6',1,'ir_Daikin.h']]], + ['kdaikin128bitwall_4724',['kDaikin128BitWall',['../ir__Daikin_8h.html#a842b3b696f95c5515ee4180626d78973',1,'ir_Daikin.h']]], + ['kdaikin128byteclockhours_4725',['kDaikin128ByteClockHours',['../ir__Daikin_8h.html#a0d705309d30881fd2fe806e5bf8ae27d',1,'ir_Daikin.h']]], + ['kdaikin128byteclockmins_4726',['kDaikin128ByteClockMins',['../ir__Daikin_8h.html#ab8c9af42d68548e1e711a0b38976342b',1,'ir_Daikin.h']]], + ['kdaikin128byteeconolight_4727',['kDaikin128ByteEconoLight',['../ir__Daikin_8h.html#a75a3c1f1790006f0005666a023218c79',1,'ir_Daikin.h']]], + ['kdaikin128bytemodefan_4728',['kDaikin128ByteModeFan',['../ir__Daikin_8h.html#a8433ab362f79a6bb3570d310a05f1141',1,'ir_Daikin.h']]], + ['kdaikin128byteofftimer_4729',['kDaikin128ByteOffTimer',['../ir__Daikin_8h.html#a66e243db1131f58d0840980ca64c0282',1,'ir_Daikin.h']]], + ['kdaikin128byteontimer_4730',['kDaikin128ByteOnTimer',['../ir__Daikin_8h.html#af27f1f25a52dc4c182111acd2abc554d',1,'ir_Daikin.h']]], + ['kdaikin128bytepowerswingsleep_4731',['kDaikin128BytePowerSwingSleep',['../ir__Daikin_8h.html#a0f5a9f1ac68c516744220ad230805c15',1,'ir_Daikin.h']]], + ['kdaikin128bytetemp_4732',['kDaikin128ByteTemp',['../ir__Daikin_8h.html#a4d3d5683aaee8e76138750a0f6ff1465',1,'ir_Daikin.h']]], + ['kdaikin128cool_4733',['kDaikin128Cool',['../ir__Daikin_8h.html#a24ee5ffe877d7caa964256e5723af7e1',1,'ir_Daikin.h']]], + ['kdaikin128defaultrepeat_4734',['kDaikin128DefaultRepeat',['../IRremoteESP8266_8h.html#a5c116cb58be005468de125f6ee651ccb',1,'IRremoteESP8266.h']]], + ['kdaikin128dry_4735',['kDaikin128Dry',['../ir__Daikin_8h.html#ac4da761bf3b0ce12e6513a2718b3a907',1,'ir_Daikin.h']]], + ['kdaikin128fan_4736',['kDaikin128Fan',['../ir__Daikin_8h.html#ac1c41d54f27d1653181ac69384f1130f',1,'ir_Daikin.h']]], + ['kdaikin128fanauto_4737',['kDaikin128FanAuto',['../ir__Daikin_8h.html#aec2fe4618978c17e60a1ea8b1a89c263',1,'ir_Daikin.h']]], + ['kdaikin128fanhigh_4738',['kDaikin128FanHigh',['../ir__Daikin_8h.html#a7ffd52eb15f6ffb5a0ffcddf39aa8f0d',1,'ir_Daikin.h']]], + ['kdaikin128fanlow_4739',['kDaikin128FanLow',['../ir__Daikin_8h.html#a505c58ff23c5a551c6e2e356f66e9cc1',1,'ir_Daikin.h']]], + ['kdaikin128fanmed_4740',['kDaikin128FanMed',['../ir__Daikin_8h.html#a4eb21add9bfb6774047a8a2c8b87ebbf',1,'ir_Daikin.h']]], + ['kdaikin128fanpowerful_4741',['kDaikin128FanPowerful',['../ir__Daikin_8h.html#ae0899153669a6e8848556cd65c26c8b5',1,'ir_Daikin.h']]], + ['kdaikin128fanquiet_4742',['kDaikin128FanQuiet',['../ir__Daikin_8h.html#a54777f468236bf4b342240e8c523308d',1,'ir_Daikin.h']]], + ['kdaikin128footermark_4743',['kDaikin128FooterMark',['../ir__Daikin_8h.html#ad5668b12e38afa4b44a8e214dac22f2e',1,'ir_Daikin.h']]], + ['kdaikin128freq_4744',['kDaikin128Freq',['../ir__Daikin_8h.html#a5a76fc08310d517cb7e182c287e77df1',1,'ir_Daikin.h']]], + ['kdaikin128gap_4745',['kDaikin128Gap',['../ir__Daikin_8h.html#a6323c59eb5906ac2887a02f9cd09a329',1,'ir_Daikin.h']]], + ['kdaikin128halfhouroffset_4746',['kDaikin128HalfHourOffset',['../ir__Daikin_8h.html#a8fddd8a5dbad2fd49445eaa2104f7da3',1,'ir_Daikin.h']]], + ['kdaikin128hdrmark_4747',['kDaikin128HdrMark',['../ir__Daikin_8h.html#a6257375541b6e10bda4083d9529e80f0',1,'ir_Daikin.h']]], + ['kdaikin128hdrspace_4748',['kDaikin128HdrSpace',['../ir__Daikin_8h.html#a114a4cef444d4c552b90701cb7debc73',1,'ir_Daikin.h']]], + ['kdaikin128heat_4749',['kDaikin128Heat',['../ir__Daikin_8h.html#ada28db809b26e2ae9e927650d4cb4f7a',1,'ir_Daikin.h']]], + ['kdaikin128hoursoffset_4750',['kDaikin128HoursOffset',['../ir__Daikin_8h.html#ace543fba33c68e3df4aa4d250ed1e792',1,'ir_Daikin.h']]], + ['kdaikin128hourssize_4751',['kDaikin128HoursSize',['../ir__Daikin_8h.html#ac5441402c0ee486f3c752a91f09375ff',1,'ir_Daikin.h']]], + ['kdaikin128leadermark_4752',['kDaikin128LeaderMark',['../ir__Daikin_8h.html#ab609b8979a2d2bf4fa5b7164590b2bfb',1,'ir_Daikin.h']]], + ['kdaikin128leaderspace_4753',['kDaikin128LeaderSpace',['../ir__Daikin_8h.html#a259bfa510a9ec06049c0a7bf6563eb35',1,'ir_Daikin.h']]], + ['kdaikin128maskfan_4754',['kDaikin128MaskFan',['../ir__Daikin_8h.html#ae58228f3b9eae0ec171527ced89e509f',1,'ir_Daikin.h']]], + ['kdaikin128masklight_4755',['kDaikin128MaskLight',['../ir__Daikin_8h.html#a8d3d4325f91cbdd8ce0cec25fc0d2022',1,'ir_Daikin.h']]], + ['kdaikin128maxtemp_4756',['kDaikin128MaxTemp',['../ir__Daikin_8h.html#a7dcd514d292ef98d70083227d046baad',1,'ir_Daikin.h']]], + ['kdaikin128mintemp_4757',['kDaikin128MinTemp',['../ir__Daikin_8h.html#aad27f3ff311f1defc5ac9fb3be0ad504',1,'ir_Daikin.h']]], + ['kdaikin128modesize_4758',['kDaikin128ModeSize',['../ir__Daikin_8h.html#a32a97adddfa791cc0e48d9bd847a3a4c',1,'ir_Daikin.h']]], + ['kdaikin128onespace_4759',['kDaikin128OneSpace',['../ir__Daikin_8h.html#ac6a9a48ae0037b889a6619361fd090ac',1,'ir_Daikin.h']]], + ['kdaikin128sectionlength_4760',['kDaikin128SectionLength',['../ir__Daikin_8h.html#a204a306e7d7071d4b798f7947c232520',1,'ir_Daikin.h']]], + ['kdaikin128sections_4761',['kDaikin128Sections',['../ir__Daikin_8h.html#a81f0cfda4d8452d6053cc6999a270b1f',1,'ir_Daikin.h']]], + ['kdaikin128statelength_4762',['kDaikin128StateLength',['../IRremoteESP8266_8h.html#a4279ccd14a3af2046e393661a7b4879f',1,'IRremoteESP8266.h']]], + ['kdaikin128timeroffset_4763',['kDaikin128TimerOffset',['../ir__Daikin_8h.html#aabde7c45424ae82a812485e8ceb58dbd',1,'ir_Daikin.h']]], + ['kdaikin128timersize_4764',['kDaikin128TimerSize',['../ir__Daikin_8h.html#a6f4022c5e4a092eb039c53ea72f51188',1,'ir_Daikin.h']]], + ['kdaikin128zerospace_4765',['kDaikin128ZeroSpace',['../ir__Daikin_8h.html#a1ca69805ada8ec451199c18d9da6f02a',1,'ir_Daikin.h']]], + ['kdaikin152bitmark_4766',['kDaikin152BitMark',['../ir__Daikin_8h.html#afd50318eaa383a7e85f0d0c2866bc9d5',1,'ir_Daikin.h']]], + ['kdaikin152bits_4767',['kDaikin152Bits',['../IRremoteESP8266_8h.html#af056e1ac2d00c6d6440c3dd2ae283f09',1,'IRremoteESP8266.h']]], + ['kdaikin152comfortbyte_4768',['kDaikin152ComfortByte',['../ir__Daikin_8h.html#a414b7acd5259122af5b496979fe068dc',1,'ir_Daikin.h']]], + ['kdaikin152comfortoffset_4769',['kDaikin152ComfortOffset',['../ir__Daikin_8h.html#a9cc7bb09fb66aa0cf7d0b751505fd3e6',1,'ir_Daikin.h']]], + ['kdaikin152defaultrepeat_4770',['kDaikin152DefaultRepeat',['../IRremoteESP8266_8h.html#a9407eebab271524e74bc3ddddb1a2e0b',1,'IRremoteESP8266.h']]], + ['kdaikin152drytemp_4771',['kDaikin152DryTemp',['../ir__Daikin_8h.html#a86e9308c00dbdd79546687af412c4156',1,'ir_Daikin.h']]], + ['kdaikin152econobyte_4772',['kDaikin152EconoByte',['../ir__Daikin_8h.html#a988782fd6bcf25b098d7c07e38679a78',1,'ir_Daikin.h']]], + ['kdaikin152fanbyte_4773',['kDaikin152FanByte',['../ir__Daikin_8h.html#a1972e59df2902335e37b2d66d16048a8',1,'ir_Daikin.h']]], + ['kdaikin152fantemp_4774',['kDaikin152FanTemp',['../ir__Daikin_8h.html#ad5c5bb7e8b181c79fe68607c1a4d202f',1,'ir_Daikin.h']]], + ['kdaikin152freq_4775',['kDaikin152Freq',['../ir__Daikin_8h.html#aa45492ae186142971975b7da56658a0b',1,'ir_Daikin.h']]], + ['kdaikin152gap_4776',['kDaikin152Gap',['../ir__Daikin_8h.html#aee02d3b17db4a382035c00329c6c2a0a',1,'ir_Daikin.h']]], + ['kdaikin152hdrmark_4777',['kDaikin152HdrMark',['../ir__Daikin_8h.html#a85fad797a9b43cb317fdb2e2c254a3bb',1,'ir_Daikin.h']]], + ['kdaikin152hdrspace_4778',['kDaikin152HdrSpace',['../ir__Daikin_8h.html#a0eb0b1b5fabab75a5956b6b939696a12',1,'ir_Daikin.h']]], + ['kdaikin152leaderbits_4779',['kDaikin152LeaderBits',['../ir__Daikin_8h.html#a432454efd5ea7457d34fe014b0d328c1',1,'ir_Daikin.h']]], + ['kdaikin152modebyte_4780',['kDaikin152ModeByte',['../ir__Daikin_8h.html#a1aaa767f722926e9aaf02dbcd8029003',1,'ir_Daikin.h']]], + ['kdaikin152onespace_4781',['kDaikin152OneSpace',['../ir__Daikin_8h.html#a1f96172c74b261a26ec6d71201f7c589',1,'ir_Daikin.h']]], + ['kdaikin152powerbyte_4782',['kDaikin152PowerByte',['../ir__Daikin_8h.html#a67ff6fbdc004d3a29b1d31c5bc47f572',1,'ir_Daikin.h']]], + ['kdaikin152powerfulbyte_4783',['kDaikin152PowerfulByte',['../ir__Daikin_8h.html#a720a3019f7bb2f8c458a7b79fbadd08f',1,'ir_Daikin.h']]], + ['kdaikin152quietbyte_4784',['kDaikin152QuietByte',['../ir__Daikin_8h.html#ad534758115c401368a428d887faa8768',1,'ir_Daikin.h']]], + ['kdaikin152sensorbyte_4785',['kDaikin152SensorByte',['../ir__Daikin_8h.html#a33187d50e8414f943d050a0b1c312168',1,'ir_Daikin.h']]], + ['kdaikin152sensoroffset_4786',['kDaikin152SensorOffset',['../ir__Daikin_8h.html#a01ef92b6eb478b1897fdfdcea03d7116',1,'ir_Daikin.h']]], + ['kdaikin152statelength_4787',['kDaikin152StateLength',['../IRremoteESP8266_8h.html#ae7579708922ffd3e44295f8770878983',1,'IRremoteESP8266.h']]], + ['kdaikin152swingvbyte_4788',['kDaikin152SwingVByte',['../ir__Daikin_8h.html#a9ed39bcce7d0bc73060fba843dfd2b28',1,'ir_Daikin.h']]], + ['kdaikin152tempbyte_4789',['kDaikin152TempByte',['../ir__Daikin_8h.html#a5e232b17db30a7e0ba159e2413df8b14',1,'ir_Daikin.h']]], + ['kdaikin152tempsize_4790',['kDaikin152TempSize',['../ir__Daikin_8h.html#ad22ee842100e70d95f1ebcdcaf3f2099',1,'ir_Daikin.h']]], + ['kdaikin152zerospace_4791',['kDaikin152ZeroSpace',['../ir__Daikin_8h.html#aec201aee71c0e301e8e191ddcaadb2de',1,'ir_Daikin.h']]], + ['kdaikin160bitmark_4792',['kDaikin160BitMark',['../ir__Daikin_8h.html#a852c2268ed7a8dd42c629e8a0706b6f5',1,'ir_Daikin.h']]], + ['kdaikin160bits_4793',['kDaikin160Bits',['../IRremoteESP8266_8h.html#aa6f1d6dded2ae3500cd52aa0c482a1b6',1,'IRremoteESP8266.h']]], + ['kdaikin160bytefan_4794',['kDaikin160ByteFan',['../ir__Daikin_8h.html#a980ae6010c956c92348d3ac88c084247',1,'ir_Daikin.h']]], + ['kdaikin160bytemode_4795',['kDaikin160ByteMode',['../ir__Daikin_8h.html#a6c5bcb2c4447dafc53c26775539886e6',1,'ir_Daikin.h']]], + ['kdaikin160bytepower_4796',['kDaikin160BytePower',['../ir__Daikin_8h.html#a8e79923cf8aa346ea52791887b54ffbe',1,'ir_Daikin.h']]], + ['kdaikin160byteswingv_4797',['kDaikin160ByteSwingV',['../ir__Daikin_8h.html#a35032831d79e96a98527896cd5d52efe',1,'ir_Daikin.h']]], + ['kdaikin160bytetemp_4798',['kDaikin160ByteTemp',['../ir__Daikin_8h.html#a1b9eed515f9cfc3508cce7d53fb7a84a',1,'ir_Daikin.h']]], + ['kdaikin160defaultrepeat_4799',['kDaikin160DefaultRepeat',['../IRremoteESP8266_8h.html#a82f4f1d8fae51c7e2f1f6753ca6e6053',1,'IRremoteESP8266.h']]], + ['kdaikin160freq_4800',['kDaikin160Freq',['../ir__Daikin_8h.html#a69e8abb57aecc6b99c60c5df7e18ff39',1,'ir_Daikin.h']]], + ['kdaikin160gap_4801',['kDaikin160Gap',['../ir__Daikin_8h.html#a8d107f0d63ef6951d657a55a370e8a8b',1,'ir_Daikin.h']]], + ['kdaikin160hdrmark_4802',['kDaikin160HdrMark',['../ir__Daikin_8h.html#a96043b43ba4d963456206e2d02639325',1,'ir_Daikin.h']]], + ['kdaikin160hdrspace_4803',['kDaikin160HdrSpace',['../ir__Daikin_8h.html#aefa7b5de43483951e00bd5d2cdbe5665',1,'ir_Daikin.h']]], + ['kdaikin160maskfan_4804',['kDaikin160MaskFan',['../ir__Daikin_8h.html#a623f586183436960361a85f8480c87c6',1,'ir_Daikin.h']]], + ['kdaikin160maskswingv_4805',['kDaikin160MaskSwingV',['../ir__Daikin_8h.html#abfaa078f7dfdd1c0bb14ad15fee26604',1,'ir_Daikin.h']]], + ['kdaikin160onespace_4806',['kDaikin160OneSpace',['../ir__Daikin_8h.html#a068c2252191675dca6503bfc37e4785e',1,'ir_Daikin.h']]], + ['kdaikin160section1length_4807',['kDaikin160Section1Length',['../ir__Daikin_8h.html#a06b59ee56cddcdcd9dfa375663da0c2d',1,'ir_Daikin.h']]], + ['kdaikin160section2length_4808',['kDaikin160Section2Length',['../ir__Daikin_8h.html#a7d6194a363661e11167cc972f1b92f68',1,'ir_Daikin.h']]], + ['kdaikin160sections_4809',['kDaikin160Sections',['../ir__Daikin_8h.html#afcc5de2994c1cd618437f1c67a5754d0',1,'ir_Daikin.h']]], + ['kdaikin160statelength_4810',['kDaikin160StateLength',['../IRremoteESP8266_8h.html#a09f022a12a40a8fae09bfbddfbee6d62',1,'IRremoteESP8266.h']]], + ['kdaikin160swingvauto_4811',['kDaikin160SwingVAuto',['../ir__Daikin_8h.html#aa6d9ee84d2c15c69ed8dbbc832285baf',1,'ir_Daikin.h']]], + ['kdaikin160swingvhigh_4812',['kDaikin160SwingVHigh',['../ir__Daikin_8h.html#abf542bd70d12534af72fb4ec8df5d265',1,'ir_Daikin.h']]], + ['kdaikin160swingvhighest_4813',['kDaikin160SwingVHighest',['../ir__Daikin_8h.html#a2a48ca041acbde68b902a4d0be4aeec5',1,'ir_Daikin.h']]], + ['kdaikin160swingvlow_4814',['kDaikin160SwingVLow',['../ir__Daikin_8h.html#a04ff7cb63db6b281ced56283288f05c0',1,'ir_Daikin.h']]], + ['kdaikin160swingvlowest_4815',['kDaikin160SwingVLowest',['../ir__Daikin_8h.html#ac4f34c7862802b21dede2ac0b534c8d8',1,'ir_Daikin.h']]], + ['kdaikin160swingvmiddle_4816',['kDaikin160SwingVMiddle',['../ir__Daikin_8h.html#a620b644f07f9b664f09417bb362dc216',1,'ir_Daikin.h']]], + ['kdaikin160tempoffset_4817',['kDaikin160TempOffset',['../ir__Daikin_8h.html#aa2f7050929bab65dbdb8af5b493dafe2',1,'ir_Daikin.h']]], + ['kdaikin160tempsize_4818',['kDaikin160TempSize',['../ir__Daikin_8h.html#adfecac727480010fae8e419ac3f13e73',1,'ir_Daikin.h']]], + ['kdaikin160zerospace_4819',['kDaikin160ZeroSpace',['../ir__Daikin_8h.html#a2b4591126c0b26ab16b5611dbfa4d5f6',1,'ir_Daikin.h']]], + ['kdaikin176bitmark_4820',['kDaikin176BitMark',['../ir__Daikin_8h.html#a4be0185fb8f65c0286cbf55dfd63a40f',1,'ir_Daikin.h']]], + ['kdaikin176bits_4821',['kDaikin176Bits',['../IRremoteESP8266_8h.html#a78baf9c97c548618428d2fcfd7cc91d7',1,'IRremoteESP8266.h']]], + ['kdaikin176bytefan_4822',['kDaikin176ByteFan',['../ir__Daikin_8h.html#a21e4b1854d3f87757ba0f0c10074226c',1,'ir_Daikin.h']]], + ['kdaikin176bytemode_4823',['kDaikin176ByteMode',['../ir__Daikin_8h.html#ad114b4570f96bcbf5358fa1ece354572',1,'ir_Daikin.h']]], + ['kdaikin176bytemodebutton_4824',['kDaikin176ByteModeButton',['../ir__Daikin_8h.html#aacda7563a2aaa9a56c77ce550f24a237',1,'ir_Daikin.h']]], + ['kdaikin176bytepower_4825',['kDaikin176BytePower',['../ir__Daikin_8h.html#aabfb9642dce0ab4169b193955221b938',1,'ir_Daikin.h']]], + ['kdaikin176byteswingh_4826',['kDaikin176ByteSwingH',['../ir__Daikin_8h.html#a4566642e6aaa0d64c531fafe0309dccc',1,'ir_Daikin.h']]], + ['kdaikin176bytetemp_4827',['kDaikin176ByteTemp',['../ir__Daikin_8h.html#afab294c7e8c65e5bf58e85bee4901752',1,'ir_Daikin.h']]], + ['kdaikin176cool_4828',['kDaikin176Cool',['../ir__Daikin_8h.html#ab67e912a9abdda7dcbe52ce90b70a3b5',1,'ir_Daikin.h']]], + ['kdaikin176defaultrepeat_4829',['kDaikin176DefaultRepeat',['../IRremoteESP8266_8h.html#a0228803e8fff3c73227214d4bb3d8b05',1,'IRremoteESP8266.h']]], + ['kdaikin176dryfantemp_4830',['kDaikin176DryFanTemp',['../ir__Daikin_8h.html#a462ad30312f13443f51b510e5b391f42',1,'ir_Daikin.h']]], + ['kdaikin176fanmax_4831',['kDaikin176FanMax',['../ir__Daikin_8h.html#a97e77d2a09bc753c17104f9695a0c0b1',1,'ir_Daikin.h']]], + ['kdaikin176freq_4832',['kDaikin176Freq',['../ir__Daikin_8h.html#a7f0c76e579dad510f21c34ba57cbf8dc',1,'ir_Daikin.h']]], + ['kdaikin176gap_4833',['kDaikin176Gap',['../ir__Daikin_8h.html#a0309c9d689f64e2d57ab09a2bb27bc18',1,'ir_Daikin.h']]], + ['kdaikin176hdrmark_4834',['kDaikin176HdrMark',['../ir__Daikin_8h.html#a9ff1ca660571d09caa0de39ce1370720',1,'ir_Daikin.h']]], + ['kdaikin176hdrspace_4835',['kDaikin176HdrSpace',['../ir__Daikin_8h.html#a64c4874b5d92682911ca84e826e1ff0b',1,'ir_Daikin.h']]], + ['kdaikin176maskfan_4836',['kDaikin176MaskFan',['../ir__Daikin_8h.html#ae7410031c68ae8426caa61bc97909cdf',1,'ir_Daikin.h']]], + ['kdaikin176maskmode_4837',['kDaikin176MaskMode',['../ir__Daikin_8h.html#a65b76b7a85d70a4ed1af359b2babffa1',1,'ir_Daikin.h']]], + ['kdaikin176modebutton_4838',['kDaikin176ModeButton',['../ir__Daikin_8h.html#a5c8602d17e9f70eefd735741b9d714eb',1,'ir_Daikin.h']]], + ['kdaikin176onespace_4839',['kDaikin176OneSpace',['../ir__Daikin_8h.html#a86ed046d66daf884ac0f06722991f5ba',1,'ir_Daikin.h']]], + ['kdaikin176section1length_4840',['kDaikin176Section1Length',['../ir__Daikin_8h.html#a4c5ce7df75834c77c0908cc40dbe02ed',1,'ir_Daikin.h']]], + ['kdaikin176section2length_4841',['kDaikin176Section2Length',['../ir__Daikin_8h.html#a9e2bb25a1d64d2c042e7eef38f5347d0',1,'ir_Daikin.h']]], + ['kdaikin176sections_4842',['kDaikin176Sections',['../ir__Daikin_8h.html#a177d12ac0f4fe8b5c5aeaf8f72579607',1,'ir_Daikin.h']]], + ['kdaikin176statelength_4843',['kDaikin176StateLength',['../IRremoteESP8266_8h.html#aa71fc87dcb6f14b82997e1d2269429d2',1,'IRremoteESP8266.h']]], + ['kdaikin176swinghauto_4844',['kDaikin176SwingHAuto',['../ir__Daikin_8h.html#a326ffcf00330a1759e4f71f8f8603f23',1,'ir_Daikin.h']]], + ['kdaikin176swinghoff_4845',['kDaikin176SwingHOff',['../ir__Daikin_8h.html#a8672ccb9016808c84b1b06de6584188a',1,'ir_Daikin.h']]], + ['kdaikin176tempoffset_4846',['kDaikin176TempOffset',['../ir__Daikin_8h.html#aa5f6cc15ca424e4bf9cc4357d9db79c9',1,'ir_Daikin.h']]], + ['kdaikin176tempsize_4847',['kDaikin176TempSize',['../ir__Daikin_8h.html#a3ef1914f2caf650a90d8412f2c1e2b74',1,'ir_Daikin.h']]], + ['kdaikin176zerospace_4848',['kDaikin176ZeroSpace',['../ir__Daikin_8h.html#a4db8836caa6cae0bab6fbde94409c879',1,'ir_Daikin.h']]], + ['kdaikin216bitmark_4849',['kDaikin216BitMark',['../ir__Daikin_8h.html#ada7cf9c593d716617ff4436755eef4f9',1,'ir_Daikin.h']]], + ['kdaikin216bits_4850',['kDaikin216Bits',['../IRremoteESP8266_8h.html#a317bf475ee4c6ddd802995dc535377d9',1,'IRremoteESP8266.h']]], + ['kdaikin216bytefan_4851',['kDaikin216ByteFan',['../ir__Daikin_8h.html#a832e7a349293058ebc50c17b904fb8f7',1,'ir_Daikin.h']]], + ['kdaikin216bytemode_4852',['kDaikin216ByteMode',['../ir__Daikin_8h.html#a48974eb3ceb40f2f580bd266a60f0392',1,'ir_Daikin.h']]], + ['kdaikin216bytepower_4853',['kDaikin216BytePower',['../ir__Daikin_8h.html#a740c2db81aebd8cb9e18b3f8c6c5b8be',1,'ir_Daikin.h']]], + ['kdaikin216bytepowerful_4854',['kDaikin216BytePowerful',['../ir__Daikin_8h.html#a9a428d988d705beae3ff1f7c0f01cb8d',1,'ir_Daikin.h']]], + ['kdaikin216byteswingh_4855',['kDaikin216ByteSwingH',['../ir__Daikin_8h.html#a20239baacdf9fb981eb0fb84b0ef536a',1,'ir_Daikin.h']]], + ['kdaikin216byteswingv_4856',['kDaikin216ByteSwingV',['../ir__Daikin_8h.html#a9fd16b0fb0d67a7058816d4b4f1659fc',1,'ir_Daikin.h']]], + ['kdaikin216bytetemp_4857',['kDaikin216ByteTemp',['../ir__Daikin_8h.html#a5828687e12d2b7fe1d793235d91750bd',1,'ir_Daikin.h']]], + ['kdaikin216defaultrepeat_4858',['kDaikin216DefaultRepeat',['../IRremoteESP8266_8h.html#a9d14d424d5a93de62f3e6f453db112db',1,'IRremoteESP8266.h']]], + ['kdaikin216freq_4859',['kDaikin216Freq',['../ir__Daikin_8h.html#aa3a9753c90ecb6d7f5ee3e5a16c79217',1,'ir_Daikin.h']]], + ['kdaikin216gap_4860',['kDaikin216Gap',['../ir__Daikin_8h.html#ab807adaab8afbeb97afaa9ddb2ec2c63',1,'ir_Daikin.h']]], + ['kdaikin216hdrmark_4861',['kDaikin216HdrMark',['../ir__Daikin_8h.html#a24163655b3d374aa643506c2bf4a2406',1,'ir_Daikin.h']]], + ['kdaikin216hdrspace_4862',['kDaikin216HdrSpace',['../ir__Daikin_8h.html#a2e69973e9a4aee29668597d09fcd70a4',1,'ir_Daikin.h']]], + ['kdaikin216maskfan_4863',['kDaikin216MaskFan',['../ir__Daikin_8h.html#a88f67ea1fe03ef40b81c5226ff5c72d5',1,'ir_Daikin.h']]], + ['kdaikin216onespace_4864',['kDaikin216OneSpace',['../ir__Daikin_8h.html#a1edeb73093bdea23e6cfb39c31ca1fce',1,'ir_Daikin.h']]], + ['kdaikin216section1length_4865',['kDaikin216Section1Length',['../ir__Daikin_8h.html#a5aacc812feb33ef954adc49086036859',1,'ir_Daikin.h']]], + ['kdaikin216section2length_4866',['kDaikin216Section2Length',['../ir__Daikin_8h.html#aade497bb9aad663a9e1e9403188d2154',1,'ir_Daikin.h']]], + ['kdaikin216sections_4867',['kDaikin216Sections',['../ir__Daikin_8h.html#a0ecd54bb733b982e3e5adf0c13ac9f6b',1,'ir_Daikin.h']]], + ['kdaikin216statelength_4868',['kDaikin216StateLength',['../IRremoteESP8266_8h.html#a70a1a65c1947b440e4ff27477de5ddc7',1,'IRremoteESP8266.h']]], + ['kdaikin216swingoff_4869',['kDaikin216SwingOff',['../ir__Daikin_8h.html#a84d6bb74c705dfbcd558f0b411a2a88e',1,'ir_Daikin.h']]], + ['kdaikin216swingon_4870',['kDaikin216SwingOn',['../ir__Daikin_8h.html#a4b2d77aafd84ed004390b5d4c7ad0455',1,'ir_Daikin.h']]], + ['kdaikin216swingsize_4871',['kDaikin216SwingSize',['../ir__Daikin_8h.html#a90d9e740067051fe294f1b408f7e020b',1,'ir_Daikin.h']]], + ['kdaikin216tempoffset_4872',['kDaikin216TempOffset',['../ir__Daikin_8h.html#a8e497623bb05ff10287ca06ac6ec15f6',1,'ir_Daikin.h']]], + ['kdaikin216tempsize_4873',['kDaikin216TempSize',['../ir__Daikin_8h.html#a3ef59f8474b38d1b0311f1018dbd6225',1,'ir_Daikin.h']]], + ['kdaikin216zerospace_4874',['kDaikin216ZeroSpace',['../ir__Daikin_8h.html#a448250dbb5a3a9733f21a0e347d17999',1,'ir_Daikin.h']]], + ['kdaikin2beepoffset_4875',['kDaikin2BeepOffset',['../ir__Daikin_8h.html#ad7f6110b5e3bf8c3b72ca07b745bae7c',1,'ir_Daikin.h']]], + ['kdaikin2beepsize_4876',['kDaikin2BeepSize',['../ir__Daikin_8h.html#a3a42f10a3427bff7af3c745592fe58fe',1,'ir_Daikin.h']]], + ['kdaikin2bitclean_4877',['kDaikin2BitClean',['../ir__Daikin_8h.html#a6672ff35e765c9ecb14107e7732b0bb2',1,'ir_Daikin.h']]], + ['kdaikin2bitcleanoffset_4878',['kDaikin2BitCleanOffset',['../ir__Daikin_8h.html#a4fa7ed25fb3f2371c3b5c7cf4906a3f3',1,'ir_Daikin.h']]], + ['kdaikin2biteye_4879',['kDaikin2BitEye',['../ir__Daikin_8h.html#a8adb3f3e8508adf8adc530365fceb96b',1,'ir_Daikin.h']]], + ['kdaikin2biteyeauto_4880',['kDaikin2BitEyeAuto',['../ir__Daikin_8h.html#a6a24519db9870520a645e4ad31857e39',1,'ir_Daikin.h']]], + ['kdaikin2biteyeautooffset_4881',['kDaikin2BitEyeAutoOffset',['../ir__Daikin_8h.html#a73db209ad074eeaef1a5317cbee8ab35',1,'ir_Daikin.h']]], + ['kdaikin2biteyeoffset_4882',['kDaikin2BitEyeOffset',['../ir__Daikin_8h.html#a7a4c6e131d9a0e441de549bd5f93074f',1,'ir_Daikin.h']]], + ['kdaikin2bitfreshair_4883',['kDaikin2BitFreshAir',['../ir__Daikin_8h.html#a9ab2c4b0f415ce0042b848e44850b7b8',1,'ir_Daikin.h']]], + ['kdaikin2bitfreshairhigh_4884',['kDaikin2BitFreshAirHigh',['../ir__Daikin_8h.html#a21a3f3c0f39827057d8f459283a72980',1,'ir_Daikin.h']]], + ['kdaikin2bitfreshairhighoffset_4885',['kDaikin2BitFreshAirHighOffset',['../ir__Daikin_8h.html#afd4f5946e5fa5d8f48af32b8934b0f93',1,'ir_Daikin.h']]], + ['kdaikin2bitfreshairoffset_4886',['kDaikin2BitFreshAirOffset',['../ir__Daikin_8h.html#a15e49a577737bdca28c28aeeb4260e57',1,'ir_Daikin.h']]], + ['kdaikin2bitmark_4887',['kDaikin2BitMark',['../ir__Daikin_8h.html#a226f10b7216d4f039cf79af823673a18',1,'ir_Daikin.h']]], + ['kdaikin2bitmold_4888',['kDaikin2BitMold',['../ir__Daikin_8h.html#aa452116afeb7d246cee672d2717e0ff7',1,'ir_Daikin.h']]], + ['kdaikin2bitmoldoffset_4889',['kDaikin2BitMoldOffset',['../ir__Daikin_8h.html#a0e58caeb44ebc6b7c6d06e91fee33795',1,'ir_Daikin.h']]], + ['kdaikin2bitpower_4890',['kDaikin2BitPower',['../ir__Daikin_8h.html#ac7b549d7b68bc245521d7f4e6a4643ab',1,'ir_Daikin.h']]], + ['kdaikin2bitpoweroffset_4891',['kDaikin2BitPowerOffset',['../ir__Daikin_8h.html#a617d14e811cb26b86fef3048151ffc45',1,'ir_Daikin.h']]], + ['kdaikin2bitpurify_4892',['kDaikin2BitPurify',['../ir__Daikin_8h.html#a9c4d6aa579adbfe454aa19f9f604f21c',1,'ir_Daikin.h']]], + ['kdaikin2bitpurifyoffset_4893',['kDaikin2BitPurifyOffset',['../ir__Daikin_8h.html#a847a9646dc86c26da931e5bf6640ddab',1,'ir_Daikin.h']]], + ['kdaikin2bits_4894',['kDaikin2Bits',['../IRremoteESP8266_8h.html#affd9b805fff390d05a83ff4eaa1c98de',1,'IRremoteESP8266.h']]], + ['kdaikin2bitsleeptimer_4895',['kDaikin2BitSleepTimer',['../ir__Daikin_8h.html#a928ae056887b123fdf6b1e2072d03564',1,'ir_Daikin.h']]], + ['kdaikin2bitsleeptimeroffset_4896',['kDaikin2BitSleepTimerOffset',['../ir__Daikin_8h.html#abf7cfde40fd00c3500ed08831434b80f',1,'ir_Daikin.h']]], + ['kdaikin2defaultrepeat_4897',['kDaikin2DefaultRepeat',['../IRremoteESP8266_8h.html#a2dde8fd00f8a28e35da04cff9a3a1908',1,'IRremoteESP8266.h']]], + ['kdaikin2fanbyte_4898',['kDaikin2FanByte',['../ir__Daikin_8h.html#a88608f735885e11734ae83a0cc69dc8d',1,'ir_Daikin.h']]], + ['kdaikin2freq_4899',['kDaikin2Freq',['../ir__Daikin_8h.html#ab82e4836d9023c4ba3041d1226761461',1,'ir_Daikin.h']]], + ['kdaikin2gap_4900',['kDaikin2Gap',['../ir__Daikin_8h.html#afe14712c1be4ca14d5cd41e77d4bada0',1,'ir_Daikin.h']]], + ['kdaikin2hdrmark_4901',['kDaikin2HdrMark',['../ir__Daikin_8h.html#ab679ef183af5b94f53697d434e6540c3',1,'ir_Daikin.h']]], + ['kdaikin2hdrspace_4902',['kDaikin2HdrSpace',['../ir__Daikin_8h.html#a557f8eeaf55ff7fda0cacd0245ac27d3',1,'ir_Daikin.h']]], + ['kdaikin2leadermark_4903',['kDaikin2LeaderMark',['../ir__Daikin_8h.html#a533c7ea8f968502d4b31e14eb2b1f614',1,'ir_Daikin.h']]], + ['kdaikin2leaderspace_4904',['kDaikin2LeaderSpace',['../ir__Daikin_8h.html#a9d48d64e470ff0318bd62b3385433f57',1,'ir_Daikin.h']]], + ['kdaikin2lightoffset_4905',['kDaikin2LightOffset',['../ir__Daikin_8h.html#a0f40d38db7c625df9504798938ba24eb',1,'ir_Daikin.h']]], + ['kdaikin2lightsize_4906',['kDaikin2LightSize',['../ir__Daikin_8h.html#a4dc46fabef2c96a263a504a5f9012e1f',1,'ir_Daikin.h']]], + ['kdaikin2mincooltemp_4907',['kDaikin2MinCoolTemp',['../ir__Daikin_8h.html#a78b37644f9327537d35bec4c0fd8faee',1,'ir_Daikin.h']]], + ['kdaikin2onespace_4908',['kDaikin2OneSpace',['../ir__Daikin_8h.html#a70a96368500562fa95f88dc2f203c194',1,'ir_Daikin.h']]], + ['kdaikin2section1length_4909',['kDaikin2Section1Length',['../ir__Daikin_8h.html#a463878e9bfb22ca3c64a40259598872c',1,'ir_Daikin.h']]], + ['kdaikin2section2length_4910',['kDaikin2Section2Length',['../ir__Daikin_8h.html#a8cb956f86fdf487b1ea7ac388eeda2b5',1,'ir_Daikin.h']]], + ['kdaikin2sections_4911',['kDaikin2Sections',['../ir__Daikin_8h.html#a770cef4efa5d5668b063cf0e26f1b134',1,'ir_Daikin.h']]], + ['kdaikin2statelength_4912',['kDaikin2StateLength',['../IRremoteESP8266_8h.html#a349e4d17f83bb3e707ff19c0255c1644',1,'IRremoteESP8266.h']]], + ['kdaikin2swinghauto_4913',['kDaikin2SwingHAuto',['../ir__Daikin_8h.html#a834a3138b0f9bfdac98d26aa63bc951e',1,'ir_Daikin.h']]], + ['kdaikin2swinghleft_4914',['kDaikin2SwingHLeft',['../ir__Daikin_8h.html#aa9b294b2f12660081171df290a7e874f',1,'ir_Daikin.h']]], + ['kdaikin2swinghleftmax_4915',['kDaikin2SwingHLeftMax',['../ir__Daikin_8h.html#aac08696fc9734996537204c089db2f7c',1,'ir_Daikin.h']]], + ['kdaikin2swinghmiddle_4916',['kDaikin2SwingHMiddle',['../ir__Daikin_8h.html#ab882d68819344e622182b07ded30cccf',1,'ir_Daikin.h']]], + ['kdaikin2swinghright_4917',['kDaikin2SwingHRight',['../ir__Daikin_8h.html#a8d7c79266bedbb722dc1a74c8b727a27',1,'ir_Daikin.h']]], + ['kdaikin2swinghrightmax_4918',['kDaikin2SwingHRightMax',['../ir__Daikin_8h.html#a843ad9ee10eccd799814ca9fff57f481',1,'ir_Daikin.h']]], + ['kdaikin2swinghswing_4919',['kDaikin2SwingHSwing',['../ir__Daikin_8h.html#a3776d46e94a771a6dc94d14257f34d09',1,'ir_Daikin.h']]], + ['kdaikin2swinghwide_4920',['kDaikin2SwingHWide',['../ir__Daikin_8h.html#a93157e048486e564757ba737551cf481',1,'ir_Daikin.h']]], + ['kdaikin2swingvauto_4921',['kDaikin2SwingVAuto',['../ir__Daikin_8h.html#aa91228576ef22854a693c86df5276cbb',1,'ir_Daikin.h']]], + ['kdaikin2swingvbreeze_4922',['kDaikin2SwingVBreeze',['../ir__Daikin_8h.html#a5646d38fff6a985314158796665d9d76',1,'ir_Daikin.h']]], + ['kdaikin2swingvcirculate_4923',['kDaikin2SwingVCirculate',['../ir__Daikin_8h.html#a717bb32ce20e6d65ee78a9e8ba0f5490',1,'ir_Daikin.h']]], + ['kdaikin2swingvhigh_4924',['kDaikin2SwingVHigh',['../ir__Daikin_8h.html#a2d25d46fb289c3450ed6817a45982e27',1,'ir_Daikin.h']]], + ['kdaikin2swingvlow_4925',['kDaikin2SwingVLow',['../ir__Daikin_8h.html#accae3be213670675f8dfc974fe19f2cf',1,'ir_Daikin.h']]], + ['kdaikin2swingvswing_4926',['kDaikin2SwingVSwing',['../ir__Daikin_8h.html#a2a62938481ba7b4374df50867295c07d',1,'ir_Daikin.h']]], + ['kdaikin2tolerance_4927',['kDaikin2Tolerance',['../ir__Daikin_8h.html#ac428e884b15026c0610cc1b0b8b46154',1,'ir_Daikin.h']]], + ['kdaikin2zerospace_4928',['kDaikin2ZeroSpace',['../ir__Daikin_8h.html#a91b023ce8679d8d0e4434e014e746f99',1,'ir_Daikin.h']]], + ['kdaikin64bitmark_4929',['kDaikin64BitMark',['../ir__Daikin_8h.html#a6d89c1acd56b670b2aba65429d6fbf00',1,'ir_Daikin.h']]], + ['kdaikin64bits_4930',['kDaikin64Bits',['../IRremoteESP8266_8h.html#a89266e9211a81eda22475fb5a258484f',1,'IRremoteESP8266.h']]], + ['kdaikin64checksumoffset_4931',['kDaikin64ChecksumOffset',['../ir__Daikin_8h.html#a5c47c0a0b1d2a23620beb2496af958c5',1,'ir_Daikin.h']]], + ['kdaikin64checksumsize_4932',['kDaikin64ChecksumSize',['../ir__Daikin_8h.html#a0c068274c73deb732e70a7daf6684391',1,'ir_Daikin.h']]], + ['kdaikin64clockhourssize_4933',['kDaikin64ClockHoursSize',['../ir__Daikin_8h.html#ae6d8f59a9707bc807a209167231d4399',1,'ir_Daikin.h']]], + ['kdaikin64clockminssize_4934',['kDaikin64ClockMinsSize',['../ir__Daikin_8h.html#a3ab23d9db994fb6dd52208f5f69b4531',1,'ir_Daikin.h']]], + ['kdaikin64clockoffset_4935',['kDaikin64ClockOffset',['../ir__Daikin_8h.html#af204ccf4e6bd33439cec240445785e9c',1,'ir_Daikin.h']]], + ['kdaikin64clocksize_4936',['kDaikin64ClockSize',['../ir__Daikin_8h.html#a110f42ae8aa2651b195c67eef15c4d79',1,'ir_Daikin.h']]], + ['kdaikin64cool_4937',['kDaikin64Cool',['../ir__Daikin_8h.html#a1ed020e8e7b5b741e90c4a27ca9f3a91',1,'ir_Daikin.h']]], + ['kdaikin64defaultrepeat_4938',['kDaikin64DefaultRepeat',['../IRremoteESP8266_8h.html#aca64338c3e3bbe52f8ec5688317041b3',1,'IRremoteESP8266.h']]], + ['kdaikin64dry_4939',['kDaikin64Dry',['../ir__Daikin_8h.html#aa494c8e2a54209c7467fdd7f40655b0b',1,'ir_Daikin.h']]], + ['kdaikin64fan_4940',['kDaikin64Fan',['../ir__Daikin_8h.html#aa1f4bb12be0f74af35ee54a5540f8a7b',1,'ir_Daikin.h']]], + ['kdaikin64fanauto_4941',['kDaikin64FanAuto',['../ir__Daikin_8h.html#a6fbc965cb8194048ed27d586321c01b2',1,'ir_Daikin.h']]], + ['kdaikin64fanhigh_4942',['kDaikin64FanHigh',['../ir__Daikin_8h.html#a122d57c30d1f4ad8f20d44077b0a1970',1,'ir_Daikin.h']]], + ['kdaikin64fanlow_4943',['kDaikin64FanLow',['../ir__Daikin_8h.html#a5a692fdcb373acf101536adb4c18384f',1,'ir_Daikin.h']]], + ['kdaikin64fanmed_4944',['kDaikin64FanMed',['../ir__Daikin_8h.html#a9b2737ba57e38d4c3dfe7bc65de4c944',1,'ir_Daikin.h']]], + ['kdaikin64fanoffset_4945',['kDaikin64FanOffset',['../ir__Daikin_8h.html#a5523d6df96b83aa152adc1cbdac6534f',1,'ir_Daikin.h']]], + ['kdaikin64fanquiet_4946',['kDaikin64FanQuiet',['../ir__Daikin_8h.html#a1a7d78b2ed8ca5b83d6422d659ecb296',1,'ir_Daikin.h']]], + ['kdaikin64fansize_4947',['kDaikin64FanSize',['../ir__Daikin_8h.html#ac907b8f8d46eb7983a1289f23bc02401',1,'ir_Daikin.h']]], + ['kdaikin64fanturbo_4948',['kDaikin64FanTurbo',['../ir__Daikin_8h.html#ae6d370916c0897bc82346136d7922f5d',1,'ir_Daikin.h']]], + ['kdaikin64freq_4949',['kDaikin64Freq',['../ir__Daikin_8h.html#a7b63829df4d0e1de61ed396c3b07e988',1,'ir_Daikin.h']]], + ['kdaikin64gap_4950',['kDaikin64Gap',['../ir__Daikin_8h.html#ae191cb5f6c65b944970158caaf56618d',1,'ir_Daikin.h']]], + ['kdaikin64hdrmark_4951',['kDaikin64HdrMark',['../ir__Daikin_8h.html#abe7b92798de08dfc5f044869891bdec5',1,'ir_Daikin.h']]], + ['kdaikin64hdrspace_4952',['kDaikin64HdrSpace',['../ir__Daikin_8h.html#a1eac122554acda264f9aa48261b2a884',1,'ir_Daikin.h']]], + ['kdaikin64knowngoodstate_4953',['kDaikin64KnownGoodState',['../ir__Daikin_8h.html#a09f0aa8c586b35b79bbceb19e822eb48',1,'ir_Daikin.h']]], + ['kdaikin64ldrmark_4954',['kDaikin64LdrMark',['../ir__Daikin_8h.html#aca20b8ee0fa9a8aa2d676ef12bd5ba97',1,'ir_Daikin.h']]], + ['kdaikin64ldrspace_4955',['kDaikin64LdrSpace',['../ir__Daikin_8h.html#ada1084c119abe58dadcb17eb4cfed072',1,'ir_Daikin.h']]], + ['kdaikin64maxtemp_4956',['kDaikin64MaxTemp',['../ir__Daikin_8h.html#a495e3b77590263a2c043c1ba12489fac',1,'ir_Daikin.h']]], + ['kdaikin64mintemp_4957',['kDaikin64MinTemp',['../ir__Daikin_8h.html#a209cb1798ae64de1f5274fb167ee62ea',1,'ir_Daikin.h']]], + ['kdaikin64modeoffset_4958',['kDaikin64ModeOffset',['../ir__Daikin_8h.html#ac32a0c805d01b5a9fa4d4aeb5546b8e3',1,'ir_Daikin.h']]], + ['kdaikin64modesize_4959',['kDaikin64ModeSize',['../ir__Daikin_8h.html#a451465916f9ae0586cf915005be33315',1,'ir_Daikin.h']]], + ['kdaikin64offtimeenablebit_4960',['kDaikin64OffTimeEnableBit',['../ir__Daikin_8h.html#a5d5c1380e6dd22cef44a76f74049a813',1,'ir_Daikin.h']]], + ['kdaikin64offtimehalfhourbit_4961',['kDaikin64OffTimeHalfHourBit',['../ir__Daikin_8h.html#a766df1d3c0fce7576a3e694b6e0d9242',1,'ir_Daikin.h']]], + ['kdaikin64offtimeoffset_4962',['kDaikin64OffTimeOffset',['../ir__Daikin_8h.html#a3aecddae0a4c0a3123b296dd6b0fb38e',1,'ir_Daikin.h']]], + ['kdaikin64offtimesize_4963',['kDaikin64OffTimeSize',['../ir__Daikin_8h.html#a70e8ae340d5f1ca35b2d6a46020b9dcc',1,'ir_Daikin.h']]], + ['kdaikin64onespace_4964',['kDaikin64OneSpace',['../ir__Daikin_8h.html#ab3129b72f5300893d04b47e72dd420e1',1,'ir_Daikin.h']]], + ['kdaikin64ontimeenablebit_4965',['kDaikin64OnTimeEnableBit',['../ir__Daikin_8h.html#ae264ee33d051149cecc08e3a026feba7',1,'ir_Daikin.h']]], + ['kdaikin64ontimehalfhourbit_4966',['kDaikin64OnTimeHalfHourBit',['../ir__Daikin_8h.html#a0d37e6624946b26dd30c3ed25181cc37',1,'ir_Daikin.h']]], + ['kdaikin64ontimeoffset_4967',['kDaikin64OnTimeOffset',['../ir__Daikin_8h.html#a6b4af969e8b114502f067b039b0a9467',1,'ir_Daikin.h']]], + ['kdaikin64ontimesize_4968',['kDaikin64OnTimeSize',['../ir__Daikin_8h.html#a46c5e1db123959992db9e746e2b3c58a',1,'ir_Daikin.h']]], + ['kdaikin64overhead_4969',['kDaikin64Overhead',['../ir__Daikin_8h.html#af0dafe45d0127430e05f2312e8ba99bb',1,'ir_Daikin.h']]], + ['kdaikin64powertogglebit_4970',['kDaikin64PowerToggleBit',['../ir__Daikin_8h.html#a55ca8803d859f0ffaac3c3547d6b532c',1,'ir_Daikin.h']]], + ['kdaikin64sleepbit_4971',['kDaikin64SleepBit',['../ir__Daikin_8h.html#addbe01f4a4766469fe5fd1cf9972f437',1,'ir_Daikin.h']]], + ['kdaikin64swingvbit_4972',['kDaikin64SwingVBit',['../ir__Daikin_8h.html#a9c7cbb529c760cead772fe03f7f90b1a',1,'ir_Daikin.h']]], + ['kdaikin64tempoffset_4973',['kDaikin64TempOffset',['../ir__Daikin_8h.html#a4b66ea40f97deafc22df18bd0942b5f1',1,'ir_Daikin.h']]], + ['kdaikin64tempsize_4974',['kDaikin64TempSize',['../ir__Daikin_8h.html#acc21945b46b307068e8669c83fbe5837',1,'ir_Daikin.h']]], + ['kdaikin64tolerancedelta_4975',['kDaikin64ToleranceDelta',['../ir__Daikin_8h.html#ae0b22a140c2727de9a347e8ab8d554e9',1,'ir_Daikin.h']]], + ['kdaikin64zerospace_4976',['kDaikin64ZeroSpace',['../ir__Daikin_8h.html#a142e45c289af1e9802254b9c138003fa',1,'ir_Daikin.h']]], + ['kdaikinauto_4977',['kDaikinAuto',['../ir__Daikin_8h.html#af3a0e7c149d020002cdf345a15606542',1,'ir_Daikin.h']]], + ['kdaikinbeeploud_4978',['kDaikinBeepLoud',['../ir__Daikin_8h.html#a4eb2b3899076882e3ed23220138ebac1',1,'ir_Daikin.h']]], + ['kdaikinbeepoff_4979',['kDaikinBeepOff',['../ir__Daikin_8h.html#a8271934c8bbd4b8e4d6aacdee5a038cf',1,'ir_Daikin.h']]], + ['kdaikinbeepquiet_4980',['kDaikinBeepQuiet',['../ir__Daikin_8h.html#a11008f7d6afc934426b88704d47301e7',1,'ir_Daikin.h']]], + ['kdaikinbitcomfort_4981',['kDaikinBitComfort',['../ir__Daikin_8h.html#aede9991f88965161d3f7cf1dba7fdeb7',1,'ir_Daikin.h']]], + ['kdaikinbitcomfortoffset_4982',['kDaikinBitComfortOffset',['../ir__Daikin_8h.html#a2e218dda2eb4ab3a97ea8018192c5f85',1,'ir_Daikin.h']]], + ['kdaikinbitecono_4983',['kDaikinBitEcono',['../ir__Daikin_8h.html#ab579939e749517944e6e497d5e44e922',1,'ir_Daikin.h']]], + ['kdaikinbiteconooffset_4984',['kDaikinBitEconoOffset',['../ir__Daikin_8h.html#aa99539b36ab708397bd1adbd4fd4f378',1,'ir_Daikin.h']]], + ['kdaikinbiteye_4985',['kDaikinBitEye',['../ir__Daikin_8h.html#a98bbaae1b0f16cf6f2428dcf326eda51',1,'ir_Daikin.h']]], + ['kdaikinbitmark_4986',['kDaikinBitMark',['../ir__Daikin_8h.html#ae109b9ea2120f989dac2529345e38adb',1,'ir_Daikin.h']]], + ['kdaikinbitmold_4987',['kDaikinBitMold',['../ir__Daikin_8h.html#a916ad89ccf3c0225a4ca1b36d74c67b2',1,'ir_Daikin.h']]], + ['kdaikinbitmoldoffset_4988',['kDaikinBitMoldOffset',['../ir__Daikin_8h.html#ad794d6ff5b5d05642e2668378d3a1100',1,'ir_Daikin.h']]], + ['kdaikinbitofftimer_4989',['kDaikinBitOffTimer',['../ir__Daikin_8h.html#a5d68046ada1892be65f14d06c2a25b2b',1,'ir_Daikin.h']]], + ['kdaikinbitofftimeroffset_4990',['kDaikinBitOffTimerOffset',['../ir__Daikin_8h.html#a7156bec80ef23aa0e4e212e11d63bdef',1,'ir_Daikin.h']]], + ['kdaikinbitontimer_4991',['kDaikinBitOnTimer',['../ir__Daikin_8h.html#a421a745ce85313d326e00b996b5afd80',1,'ir_Daikin.h']]], + ['kdaikinbitontimeroffset_4992',['kDaikinBitOnTimerOffset',['../ir__Daikin_8h.html#a7a6b740034320cc25fb6d33d36845ca0',1,'ir_Daikin.h']]], + ['kdaikinbitpower_4993',['kDaikinBitPower',['../ir__Daikin_8h.html#ab0d91673bcd73cbbbf5f18d6d73b699e',1,'ir_Daikin.h']]], + ['kdaikinbitpowerful_4994',['kDaikinBitPowerful',['../ir__Daikin_8h.html#a4d03bc31a28d866c3bf855f6482209e8',1,'ir_Daikin.h']]], + ['kdaikinbitpowerfuloffset_4995',['kDaikinBitPowerfulOffset',['../ir__Daikin_8h.html#a772bca7454e28bd3f61cdd24f58b98c8',1,'ir_Daikin.h']]], + ['kdaikinbitpoweroffset_4996',['kDaikinBitPowerOffset',['../ir__Daikin_8h.html#ad3672753b2b06b52cd8afeca3f564af4',1,'ir_Daikin.h']]], + ['kdaikinbits_4997',['kDaikinBits',['../IRremoteESP8266_8h.html#a657f8e60bc1f896d4a46ec101c289485',1,'IRremoteESP8266.h']]], + ['kdaikinbitsensor_4998',['kDaikinBitSensor',['../ir__Daikin_8h.html#a37c7e26d1af184f844ef2c46064137ad',1,'ir_Daikin.h']]], + ['kdaikinbitsensoroffset_4999',['kDaikinBitSensorOffset',['../ir__Daikin_8h.html#a1ccb2c358aef3bf55005cf6b391e9e9b',1,'ir_Daikin.h']]], + ['kdaikinbitsilent_5000',['kDaikinBitSilent',['../ir__Daikin_8h.html#a85249d39c34b1a8b3bb8de4da32bb502',1,'ir_Daikin.h']]], + ['kdaikinbitsilentoffset_5001',['kDaikinBitSilentOffset',['../ir__Daikin_8h.html#a3fb5172c458084319937aa4ec2d6383b',1,'ir_Daikin.h']]], + ['kdaikinbitsshort_5002',['kDaikinBitsShort',['../IRremoteESP8266_8h.html#aebaa8eb786747761fb369cfd34181cb7',1,'IRremoteESP8266.h']]], + ['kdaikinbitweeklytimer_5003',['kDaikinBitWeeklyTimer',['../ir__Daikin_8h.html#a7d58b7c351394a43117e4710acd35cec',1,'ir_Daikin.h']]], + ['kdaikinbitweeklytimeroffset_5004',['kDaikinBitWeeklyTimerOffset',['../ir__Daikin_8h.html#a8ff2c05701327b6f26bee66361e39365',1,'ir_Daikin.h']]], + ['kdaikinbytechecksum1_5005',['kDaikinByteChecksum1',['../ir__Daikin_8h.html#a887d8d38cf4330e1107443471fa119ca',1,'ir_Daikin.h']]], + ['kdaikinbytechecksum2_5006',['kDaikinByteChecksum2',['../ir__Daikin_8h.html#ab27225f21b29e617bf03fc68cc6e8e0f',1,'ir_Daikin.h']]], + ['kdaikinbytechecksum3_5007',['kDaikinByteChecksum3',['../ir__Daikin_8h.html#a7277c453d4deed6abf0a7577b5b4454f',1,'ir_Daikin.h']]], + ['kdaikinbyteclockminshigh_5008',['kDaikinByteClockMinsHigh',['../ir__Daikin_8h.html#ade7d506fd7da26ae1713602c1620f716',1,'ir_Daikin.h']]], + ['kdaikinbyteclockminslow_5009',['kDaikinByteClockMinsLow',['../ir__Daikin_8h.html#a3c096c2f33eca6c6f7f57f0f684a4b43',1,'ir_Daikin.h']]], + ['kdaikinbytecomfort_5010',['kDaikinByteComfort',['../ir__Daikin_8h.html#a3b209715b7ac4e8ef4f15043654e646b',1,'ir_Daikin.h']]], + ['kdaikinbyteecono_5011',['kDaikinByteEcono',['../ir__Daikin_8h.html#ae08470f2e453a2a5b60bdb478fc8c6d7',1,'ir_Daikin.h']]], + ['kdaikinbyteeye_5012',['kDaikinByteEye',['../ir__Daikin_8h.html#ad3e2bb2f17d599c708e64cf08c042331',1,'ir_Daikin.h']]], + ['kdaikinbytefan_5013',['kDaikinByteFan',['../ir__Daikin_8h.html#a9078ad5b6b9afe43ffa0e646c35f3db6',1,'ir_Daikin.h']]], + ['kdaikinbytemold_5014',['kDaikinByteMold',['../ir__Daikin_8h.html#a81e098798e6aa7c0882703dced8ab039',1,'ir_Daikin.h']]], + ['kdaikinbyteofftimer_5015',['kDaikinByteOffTimer',['../ir__Daikin_8h.html#ad7fce891883a25e260cd8c0890d46f59',1,'ir_Daikin.h']]], + ['kdaikinbyteofftimerminshigh_5016',['kDaikinByteOffTimerMinsHigh',['../ir__Daikin_8h.html#a0294c99254e3eef7e7fa2cd169e0e5a9',1,'ir_Daikin.h']]], + ['kdaikinbyteofftimerminslow_5017',['kDaikinByteOffTimerMinsLow',['../ir__Daikin_8h.html#a45855767cf37f1562a7726dbf6419c87',1,'ir_Daikin.h']]], + ['kdaikinbyteontimer_5018',['kDaikinByteOnTimer',['../ir__Daikin_8h.html#a0a685bb92d8e3df4c9bd96b71c48f352',1,'ir_Daikin.h']]], + ['kdaikinbyteontimerminshigh_5019',['kDaikinByteOnTimerMinsHigh',['../ir__Daikin_8h.html#a77ce46689e1a353237edd45e7170bff6',1,'ir_Daikin.h']]], + ['kdaikinbyteontimerminslow_5020',['kDaikinByteOnTimerMinsLow',['../ir__Daikin_8h.html#a7c434f5c6a3febddf3da44e1c2b97872',1,'ir_Daikin.h']]], + ['kdaikinbytepower_5021',['kDaikinBytePower',['../ir__Daikin_8h.html#aa99cac4871f7ef1cdff2f41496989218',1,'ir_Daikin.h']]], + ['kdaikinbytepowerful_5022',['kDaikinBytePowerful',['../ir__Daikin_8h.html#a79b3d4cd40f839a3708fa33abb4b74c4',1,'ir_Daikin.h']]], + ['kdaikinbytesensor_5023',['kDaikinByteSensor',['../ir__Daikin_8h.html#afd18e8b5b4c9c6572659ea46df01a6df',1,'ir_Daikin.h']]], + ['kdaikinbytesilent_5024',['kDaikinByteSilent',['../ir__Daikin_8h.html#aac58a7371777f682cac3189d9905b968',1,'ir_Daikin.h']]], + ['kdaikinbyteswingh_5025',['kDaikinByteSwingH',['../ir__Daikin_8h.html#a58b88a2679bd57d723aa33afca4f2427',1,'ir_Daikin.h']]], + ['kdaikinbytetemp_5026',['kDaikinByteTemp',['../ir__Daikin_8h.html#acd14c2ebc40a8375343595ed8f0109f8',1,'ir_Daikin.h']]], + ['kdaikinbyteweeklytimer_5027',['kDaikinByteWeeklyTimer',['../ir__Daikin_8h.html#ad4eba59910311bdc8b489b27b4b59751',1,'ir_Daikin.h']]], + ['kdaikinclockminshighoffset_5028',['kDaikinClockMinsHighOffset',['../ir__Daikin_8h.html#a1b28496ffacf558f7919029f029c2dc6',1,'ir_Daikin.h']]], + ['kdaikinclockminshighsize_5029',['kDaikinClockMinsHighSize',['../ir__Daikin_8h.html#a1e018d153b13c65e411b3b090efc6d27',1,'ir_Daikin.h']]], + ['kdaikincool_5030',['kDaikinCool',['../ir__Daikin_8h.html#aa57615a0a9f79b97139580a807bf095f',1,'ir_Daikin.h']]], + ['kdaikincurbit_5031',['kDaikinCurBit',['../ir__Daikin_8h.html#afccfde2b46f5fcb425f02a79a9c20494',1,'ir_Daikin.h']]], + ['kdaikincurindex_5032',['kDaikinCurIndex',['../ir__Daikin_8h.html#a5c01a0bfbd92b337d2e4a5c3df381865',1,'ir_Daikin.h']]], + ['kdaikindefaultrepeat_5033',['kDaikinDefaultRepeat',['../IRremoteESP8266_8h.html#af691d5202b7f121a16b2d9871ee14d9c',1,'IRremoteESP8266.h']]], + ['kdaikindowoffset_5034',['kDaikinDoWOffset',['../ir__Daikin_8h.html#a07793a4b1ea8e9aabb77730ccbdf7e15',1,'ir_Daikin.h']]], + ['kdaikindowsize_5035',['kDaikinDoWSize',['../ir__Daikin_8h.html#a7bb34e2fc2c1926167b79889a5036ba0',1,'ir_Daikin.h']]], + ['kdaikindry_5036',['kDaikinDry',['../ir__Daikin_8h.html#ab6143bef74a122c3fba3a3b29df0cf29',1,'ir_Daikin.h']]], + ['kdaikinfan_5037',['kDaikinFan',['../ir__Daikin_8h.html#a616df34328cdac764aecc9ffb0f16f09',1,'ir_Daikin.h']]], + ['kdaikinfanauto_5038',['kDaikinFanAuto',['../ir__Daikin_8h.html#a87807bd5727d9da1b615fca2bd732292',1,'ir_Daikin.h']]], + ['kdaikinfanmax_5039',['kDaikinFanMax',['../ir__Daikin_8h.html#ab483f3913a909884f44f8cd8f779bca0',1,'ir_Daikin.h']]], + ['kdaikinfanmed_5040',['kDaikinFanMed',['../ir__Daikin_8h.html#ab6eb2c902c2b5f927160efc9fb9ab08c',1,'ir_Daikin.h']]], + ['kdaikinfanmin_5041',['kDaikinFanMin',['../ir__Daikin_8h.html#a83ad300b9374e50c22211501ee2d1a7a',1,'ir_Daikin.h']]], + ['kdaikinfanoffset_5042',['kDaikinFanOffset',['../ir__Daikin_8h.html#a48d0d0cb1174069d5b6ee2882761cb88',1,'ir_Daikin.h']]], + ['kdaikinfanquiet_5043',['kDaikinFanQuiet',['../ir__Daikin_8h.html#aae481cf166671c30bccdc7f47aa6666e',1,'ir_Daikin.h']]], + ['kdaikinfansize_5044',['kDaikinFanSize',['../ir__Daikin_8h.html#a1e490e414ff3f5f55b4cca443661cd1a',1,'ir_Daikin.h']]], + ['kdaikinfirstheader64_5045',['kDaikinFirstHeader64',['../ir__Daikin_8h.html#a0bd3b36061d545bb21562622642f4196',1,'ir_Daikin.h']]], + ['kdaikingap_5046',['kDaikinGap',['../ir__Daikin_8h.html#aed68991584125a277593c339ab387276',1,'ir_Daikin.h']]], + ['kdaikinhdrmark_5047',['kDaikinHdrMark',['../ir__Daikin_8h.html#a0a38b3bdfd8f4f7a18f969188388e29e',1,'ir_Daikin.h']]], + ['kdaikinhdrspace_5048',['kDaikinHdrSpace',['../ir__Daikin_8h.html#ac4ca6c53faeec7d7a7ccfb50802087dc',1,'ir_Daikin.h']]], + ['kdaikinheaderlength_5049',['kDaikinHeaderLength',['../ir__Daikin_8h.html#a476ca864b6791439549bb4257ca78b23',1,'ir_Daikin.h']]], + ['kdaikinheat_5050',['kDaikinHeat',['../ir__Daikin_8h.html#a05824dc5af4ed0d3eceda540ad0e7a9f',1,'ir_Daikin.h']]], + ['kdaikinlightbright_5051',['kDaikinLightBright',['../ir__Daikin_8h.html#a20a3103d8d0a672c0c05c1679bf3b2ab',1,'ir_Daikin.h']]], + ['kdaikinlightdim_5052',['kDaikinLightDim',['../ir__Daikin_8h.html#a1093baf5b62fca42f9361715be2198a3',1,'ir_Daikin.h']]], + ['kdaikinlightoff_5053',['kDaikinLightOff',['../ir__Daikin_8h.html#ae57f7d2ea43e865ebf8175a8dbacab45',1,'ir_Daikin.h']]], + ['kdaikinmarkexcess_5054',['kDaikinMarkExcess',['../ir__Daikin_8h.html#a5331e1ee51bd7b001346aa41ee5d26cc',1,'ir_Daikin.h']]], + ['kdaikinmaxtemp_5055',['kDaikinMaxTemp',['../ir__Daikin_8h.html#aab7be756494a5ed23e9202af769e0012',1,'ir_Daikin.h']]], + ['kdaikinmintemp_5056',['kDaikinMinTemp',['../ir__Daikin_8h.html#af257feb15dc282c7d06351ee9eed666b',1,'ir_Daikin.h']]], + ['kdaikinmodeoffset_5057',['kDaikinModeOffset',['../ir__Daikin_8h.html#a9a3aa5ee98496b468c5ba86faa3eeeae',1,'ir_Daikin.h']]], + ['kdaikinmodesize_5058',['kDaikinModeSize',['../ir__Daikin_8h.html#a00fc390085520e5382dbce2633b7142e',1,'ir_Daikin.h']]], + ['kdaikinonespace_5059',['kDaikinOneSpace',['../ir__Daikin_8h.html#a6653082dcfde989bd2c5810809fc18a9',1,'ir_Daikin.h']]], + ['kdaikinontimerminshighoffset_5060',['kDaikinOnTimerMinsHighOffset',['../ir__Daikin_8h.html#a2a4a4254fc853901686982c1410c77c8',1,'ir_Daikin.h']]], + ['kdaikinontimerminshighsize_5061',['kDaikinOnTimerMinsHighSize',['../ir__Daikin_8h.html#a2fc9c203378e49ea1d49557d776de620',1,'ir_Daikin.h']]], + ['kdaikinsection1length_5062',['kDaikinSection1Length',['../ir__Daikin_8h.html#ab3b8aacbebe6c1c5514141102d1ca26f',1,'ir_Daikin.h']]], + ['kdaikinsection2length_5063',['kDaikinSection2Length',['../ir__Daikin_8h.html#a2e65cdf05d22a20f01ae5f6d3e222218',1,'ir_Daikin.h']]], + ['kdaikinsection3length_5064',['kDaikinSection3Length',['../ir__Daikin_8h.html#ae7dbaf6b4034267e4610087f9f2f51e3',1,'ir_Daikin.h']]], + ['kdaikinsections_5065',['kDaikinSections',['../ir__Daikin_8h.html#aad822c70789b861fa5beb839833e0b4c',1,'ir_Daikin.h']]], + ['kdaikinstatelength_5066',['kDaikinStateLength',['../IRremoteESP8266_8h.html#af1fda5b9f355e526dc66cf58824315a7',1,'IRremoteESP8266.h']]], + ['kdaikinstatelengthshort_5067',['kDaikinStateLengthShort',['../IRremoteESP8266_8h.html#ae94c897cb0bd25ca7a4d693c7be9be3d',1,'IRremoteESP8266.h']]], + ['kdaikinswingoff_5068',['kDaikinSwingOff',['../ir__Daikin_8h.html#abc9194f48f63632b87c6139dd8ab6ecf',1,'ir_Daikin.h']]], + ['kdaikinswingoffset_5069',['kDaikinSwingOffset',['../ir__Daikin_8h.html#abeac0c8df9be90fc5b28db4b2284ed10',1,'ir_Daikin.h']]], + ['kdaikinswingon_5070',['kDaikinSwingOn',['../ir__Daikin_8h.html#af19ec29dc79837deca05f6061f2e6524',1,'ir_Daikin.h']]], + ['kdaikinswingsize_5071',['kDaikinSwingSize',['../ir__Daikin_8h.html#a0f7daf6ef2652bc0be591caa2fa0fad6',1,'ir_Daikin.h']]], + ['kdaikintempoffset_5072',['kDaikinTempOffset',['../ir__Daikin_8h.html#a1a38843bdf0f65f29c21b301f6f45ba5',1,'ir_Daikin.h']]], + ['kdaikintempsize_5073',['kDaikinTempSize',['../ir__Daikin_8h.html#aa2eef2bb403846d88df5387912af0a00',1,'ir_Daikin.h']]], + ['kdaikintolerance_5074',['kDaikinTolerance',['../ir__Daikin_8h.html#aea3938d1522df0040ddb9775075d6669',1,'ir_Daikin.h']]], + ['kdaikinunusedtime_5075',['kDaikinUnusedTime',['../ir__Daikin_8h.html#af60d27bb9d08317498b35f62c167f6a4',1,'ir_Daikin.h']]], + ['kdaikinzerospace_5076',['kDaikinZeroSpace',['../ir__Daikin_8h.html#ace5b2c2be3b58f22248eafb2148d059c',1,'ir_Daikin.h']]], + ['kdaysstr_5077',['kDaysStr',['../IRtext_8cpp.html#a4269111ae41c3a673ec0a87fca0fd78b',1,'kDaysStr(): IRtext.cpp'],['../IRtext_8h.html#aa779ae24412ef82ee3d1eade3f0381ae',1,'kDaysStr(): IRtext.cpp']]], + ['kdaystr_5078',['kDayStr',['../IRtext_8cpp.html#ab6fb8803c6a95d1926abb56b7ecb2e09',1,'kDayStr(): IRtext.cpp'],['../IRtext_8h.html#adb64531a5054629613696f9af39420e2',1,'kDayStr(): IRtext.cpp']]], + ['kdefaultesp32timer_5079',['kDefaultESP32Timer',['../IRrecv_8h.html#a80a2d3445a1752d18caf307d7677b709',1,'IRrecv.h']]], + ['kdefaultmessagegap_5080',['kDefaultMessageGap',['../IRsend_8h.html#ad49e9828319afbad49fd5082c50ef4a7',1,'IRsend.h']]], + ['kdelonghiacauto_5081',['kDelonghiAcAuto',['../ir__Delonghi_8h.html#ab10d4fe0b9dbe99ed942b73a6ff61d37',1,'ir_Delonghi.h']]], + ['kdelonghiacbitmark_5082',['kDelonghiAcBitMark',['../ir__Delonghi_8cpp.html#aa70f02d16b78f513e245871d4db0785a',1,'ir_Delonghi.cpp']]], + ['kdelonghiacbits_5083',['kDelonghiAcBits',['../IRremoteESP8266_8h.html#a7b9fba82b602cf38147f0586e037f909',1,'IRremoteESP8266.h']]], + ['kdelonghiacboostbit_5084',['kDelonghiAcBoostBit',['../ir__Delonghi_8h.html#a52c86741107eb5e33780f78fbf5667d5',1,'ir_Delonghi.h']]], + ['kdelonghiacchecksumoffset_5085',['kDelonghiAcChecksumOffset',['../ir__Delonghi_8h.html#a4b5e3d9874b016f60b7f9c26e7cf0cfd',1,'ir_Delonghi.h']]], + ['kdelonghiacchecksumsize_5086',['kDelonghiAcChecksumSize',['../ir__Delonghi_8h.html#a376acfc72923eccd3a1a9cc04453c0fc',1,'ir_Delonghi.h']]], + ['kdelonghiaccool_5087',['kDelonghiAcCool',['../ir__Delonghi_8h.html#a9447cc3a3f6f4e0603ecc99104523119',1,'ir_Delonghi.h']]], + ['kdelonghiacdefaultrepeat_5088',['kDelonghiAcDefaultRepeat',['../IRremoteESP8266_8h.html#a8f18256a0a6893e077e253e5e80da164',1,'IRremoteESP8266.h']]], + ['kdelonghiacdry_5089',['kDelonghiAcDry',['../ir__Delonghi_8h.html#a1c83f080ac1f48548fcfa5d691ef893d',1,'ir_Delonghi.h']]], + ['kdelonghiacfan_5090',['kDelonghiAcFan',['../ir__Delonghi_8h.html#af494534acfb8ae1c0f9c15bc13e2d0c8',1,'ir_Delonghi.h']]], + ['kdelonghiacfanauto_5091',['kDelonghiAcFanAuto',['../ir__Delonghi_8h.html#adf2286936d79d8c899283fa6e3838ebb',1,'ir_Delonghi.h']]], + ['kdelonghiacfanhigh_5092',['kDelonghiAcFanHigh',['../ir__Delonghi_8h.html#a03027eb1a6a382479b44db0699aee30b',1,'ir_Delonghi.h']]], + ['kdelonghiacfanlow_5093',['kDelonghiAcFanLow',['../ir__Delonghi_8h.html#a053a51021679cd5c4720e7ec68fa43eb',1,'ir_Delonghi.h']]], + ['kdelonghiacfanmedium_5094',['kDelonghiAcFanMedium',['../ir__Delonghi_8h.html#ac748c5e0b7c5acb108086f90c088028f',1,'ir_Delonghi.h']]], + ['kdelonghiacfanoffset_5095',['kDelonghiAcFanOffset',['../ir__Delonghi_8h.html#ab9ff55f2717de8401a940b6afd4c13d6',1,'ir_Delonghi.h']]], + ['kdelonghiacfansize_5096',['kDelonghiAcFanSize',['../ir__Delonghi_8h.html#adc3ed20ff78231b8ac2eb82481d3ebb2',1,'ir_Delonghi.h']]], + ['kdelonghiacfreq_5097',['kDelonghiAcFreq',['../ir__Delonghi_8cpp.html#a9425e4f71aa6454a89b55f3b5789d94d',1,'ir_Delonghi.cpp']]], + ['kdelonghiacgap_5098',['kDelonghiAcGap',['../ir__Delonghi_8cpp.html#ab1cd2481fc96811ed822c8c9f63420c3',1,'ir_Delonghi.cpp']]], + ['kdelonghiachdrmark_5099',['kDelonghiAcHdrMark',['../ir__Delonghi_8cpp.html#a0feead944883173788b8d02b7ae94ef8',1,'ir_Delonghi.cpp']]], + ['kdelonghiachdrspace_5100',['kDelonghiAcHdrSpace',['../ir__Delonghi_8cpp.html#a606ea96746b1b6471b1d76f05bdc7e5a',1,'ir_Delonghi.cpp']]], + ['kdelonghiachourssize_5101',['kDelonghiAcHoursSize',['../ir__Delonghi_8h.html#a94e0d6ed9ba66c467d9fb4467ab4e512',1,'ir_Delonghi.h']]], + ['kdelonghiacminssize_5102',['kDelonghiAcMinsSize',['../ir__Delonghi_8h.html#a91ed842a356878349760fe75f6d686b2',1,'ir_Delonghi.h']]], + ['kdelonghiacmodeoffset_5103',['kDelonghiAcModeOffset',['../ir__Delonghi_8h.html#a8044375ad833a12e56974b71ddfc2bc7',1,'ir_Delonghi.h']]], + ['kdelonghiacmodesize_5104',['kDelonghiAcModeSize',['../ir__Delonghi_8h.html#a30dc468cb735389aff3a27846e8a24f1',1,'ir_Delonghi.h']]], + ['kdelonghiacofftimerenablebit_5105',['kDelonghiAcOffTimerEnableBit',['../ir__Delonghi_8h.html#a93b8d905151be16f6d0918d6fd8d27e2',1,'ir_Delonghi.h']]], + ['kdelonghiacofftimerhoursoffset_5106',['kDelonghiAcOffTimerHoursOffset',['../ir__Delonghi_8h.html#a6d7b8115532bf01ae8c53b2ecbbf223b',1,'ir_Delonghi.h']]], + ['kdelonghiacofftimerminsoffset_5107',['kDelonghiAcOffTimerMinsOffset',['../ir__Delonghi_8h.html#a47b2f9c730c23d2c117141653622e04b',1,'ir_Delonghi.h']]], + ['kdelonghiaconespace_5108',['kDelonghiAcOneSpace',['../ir__Delonghi_8cpp.html#a8805fdc60cd3537ba2d94038610a3490',1,'ir_Delonghi.cpp']]], + ['kdelonghiacontimerenablebit_5109',['kDelonghiAcOnTimerEnableBit',['../ir__Delonghi_8h.html#a56d225e53ffcc29c486fce295ff3295b',1,'ir_Delonghi.h']]], + ['kdelonghiacontimerhoursoffset_5110',['kDelonghiAcOnTimerHoursOffset',['../ir__Delonghi_8h.html#a310b01f1ba238a8342261c01f77f0234',1,'ir_Delonghi.h']]], + ['kdelonghiacontimerminsoffset_5111',['kDelonghiAcOnTimerMinsOffset',['../ir__Delonghi_8h.html#a37d9a33640b64833daeb1ccc4e209be1',1,'ir_Delonghi.h']]], + ['kdelonghiacoverhead_5112',['kDelonghiAcOverhead',['../ir__Delonghi_8cpp.html#ac265c123c0cd7492d26f030d129f3475',1,'ir_Delonghi.cpp']]], + ['kdelonghiacpowerbit_5113',['kDelonghiAcPowerBit',['../ir__Delonghi_8h.html#ac89b7d74aaf3d4beaa21849085d2d7e3',1,'ir_Delonghi.h']]], + ['kdelonghiacsleepbit_5114',['kDelonghiAcSleepBit',['../ir__Delonghi_8h.html#aa1f75ea73bac50c6645625393b137391',1,'ir_Delonghi.h']]], + ['kdelonghiactempautodrymode_5115',['kDelonghiAcTempAutoDryMode',['../ir__Delonghi_8h.html#add6f728d2746a089e00a35644d664a6c',1,'ir_Delonghi.h']]], + ['kdelonghiactempfanmode_5116',['kDelonghiAcTempFanMode',['../ir__Delonghi_8h.html#a120ae31fac35c33214317c3187aae15c',1,'ir_Delonghi.h']]], + ['kdelonghiactempmaxc_5117',['kDelonghiAcTempMaxC',['../ir__Delonghi_8h.html#a476922b8d240c46cf092897f6c701e87',1,'ir_Delonghi.h']]], + ['kdelonghiactempmaxf_5118',['kDelonghiAcTempMaxF',['../ir__Delonghi_8h.html#abc11f81bc221aa3789258b7a990633b3',1,'ir_Delonghi.h']]], + ['kdelonghiactempminc_5119',['kDelonghiAcTempMinC',['../ir__Delonghi_8h.html#ad31267284f7dd8f533fc978ed7e92428',1,'ir_Delonghi.h']]], + ['kdelonghiactempminf_5120',['kDelonghiAcTempMinF',['../ir__Delonghi_8h.html#a0311abab5eff5a8c47261db8e3d40ed5',1,'ir_Delonghi.h']]], + ['kdelonghiactempoffset_5121',['kDelonghiAcTempOffset',['../ir__Delonghi_8h.html#a9d02f6520d6d1d7e305ea651099cc9ef',1,'ir_Delonghi.h']]], + ['kdelonghiactempsize_5122',['kDelonghiAcTempSize',['../ir__Delonghi_8h.html#a3fb467e0d2385893c8c7a8daa0505ec1',1,'ir_Delonghi.h']]], + ['kdelonghiactempunitbit_5123',['kDelonghiAcTempUnitBit',['../ir__Delonghi_8h.html#ac9e6f419569558f4bd5f5a6e10d24bb6',1,'ir_Delonghi.h']]], + ['kdelonghiactimermax_5124',['kDelonghiAcTimerMax',['../ir__Delonghi_8h.html#a44d3f0d850c5cd5ad8c0e2dc7c2bd860',1,'ir_Delonghi.h']]], + ['kdelonghiaczerospace_5125',['kDelonghiAcZeroSpace',['../ir__Delonghi_8cpp.html#a4c1a9a70a50c7da9aa6cf91af85c695e',1,'ir_Delonghi.cpp']]], + ['kdenon48bits_5126',['kDenon48Bits',['../IRremoteESP8266_8h.html#ad7389b5b4f01a16dbf940eaae005c805',1,'IRremoteESP8266.h']]], + ['kdenonbitmark_5127',['kDenonBitMark',['../ir__Denon_8cpp.html#a1cd978061cfdc9bf1d5e1142dad86e59',1,'ir_Denon.cpp']]], + ['kdenonbitmarkticks_5128',['kDenonBitMarkTicks',['../ir__Denon_8cpp.html#ae6dddc89296abc186ac524c3f1efbe63',1,'ir_Denon.cpp']]], + ['kdenonbits_5129',['kDenonBits',['../IRremoteESP8266_8h.html#a29160117e25f3dfc1cb899a4a53bc238',1,'IRremoteESP8266.h']]], + ['kdenonhdrmark_5130',['kDenonHdrMark',['../ir__Denon_8cpp.html#a6f7b5da8c723615200109f425df72254',1,'ir_Denon.cpp']]], + ['kdenonhdrmarkticks_5131',['kDenonHdrMarkTicks',['../ir__Denon_8cpp.html#a484a90cdd15de164c931f1c70ab02938',1,'ir_Denon.cpp']]], + ['kdenonhdrspace_5132',['kDenonHdrSpace',['../ir__Denon_8cpp.html#a758b11259a5dcab3e949739cf67106be',1,'ir_Denon.cpp']]], + ['kdenonhdrspaceticks_5133',['kDenonHdrSpaceTicks',['../ir__Denon_8cpp.html#afe6cb1be37dcea0251ebf0fc43640fe1',1,'ir_Denon.cpp']]], + ['kdenonlegacybits_5134',['kDenonLegacyBits',['../IRremoteESP8266_8h.html#aacf2eea1349016ccbc96e97a0976f4ec',1,'IRremoteESP8266.h']]], + ['kdenonmanufacturer_5135',['kDenonManufacturer',['../ir__Denon_8cpp.html#abd89138765e21d25991fd5857506491b',1,'ir_Denon.cpp']]], + ['kdenonmincommandlengthticks_5136',['kDenonMinCommandLengthTicks',['../ir__Denon_8cpp.html#abb20f9f6053e0d46399011de71697a6a',1,'ir_Denon.cpp']]], + ['kdenonmingap_5137',['kDenonMinGap',['../ir__Denon_8cpp.html#a19b3fe79e06b3ece2cb167d5e14b2c11',1,'ir_Denon.cpp']]], + ['kdenonmingapticks_5138',['kDenonMinGapTicks',['../ir__Denon_8cpp.html#a191e0cfcf8167805ef9bfdc05463c313',1,'ir_Denon.cpp']]], + ['kdenononespace_5139',['kDenonOneSpace',['../ir__Denon_8cpp.html#a150b22eeeb64b59a3d9df51904fdda3f',1,'ir_Denon.cpp']]], + ['kdenononespaceticks_5140',['kDenonOneSpaceTicks',['../ir__Denon_8cpp.html#ad15a88b8f6b953918799eac1e814d107',1,'ir_Denon.cpp']]], + ['kdenontick_5141',['kDenonTick',['../ir__Denon_8cpp.html#a6cc0eba04ca4a2362068bf47d1869752',1,'ir_Denon.cpp']]], + ['kdenonzerospace_5142',['kDenonZeroSpace',['../ir__Denon_8cpp.html#ad8f53f000727e66938d086eadb5bf6eb',1,'ir_Denon.cpp']]], + ['kdenonzerospaceticks_5143',['kDenonZeroSpaceTicks',['../ir__Denon_8cpp.html#aed0c86367586cd043d8381499b3a4bdd',1,'ir_Denon.cpp']]], + ['kdishbitmark_5144',['kDishBitMark',['../ir__Dish_8cpp.html#aabe7f9815a2f5e65558b0f482e2ac50e',1,'ir_Dish.cpp']]], + ['kdishbitmarkticks_5145',['kDishBitMarkTicks',['../ir__Dish_8cpp.html#a1cfd9b730c78aac35f6c2cb56367c7bb',1,'ir_Dish.cpp']]], + ['kdishbits_5146',['kDishBits',['../IRremoteESP8266_8h.html#aea0cc15e1c7a6edcd6b60d9ac62d4831',1,'IRremoteESP8266.h']]], + ['kdishhdrmark_5147',['kDishHdrMark',['../ir__Dish_8cpp.html#ac4311aaed27b1f37a41a2a9cced0ecc5',1,'ir_Dish.cpp']]], + ['kdishhdrmarkticks_5148',['kDishHdrMarkTicks',['../ir__Dish_8cpp.html#a8dce19ee6e3a6859bd2d43c0c9e90517',1,'ir_Dish.cpp']]], + ['kdishhdrspace_5149',['kDishHdrSpace',['../ir__Dish_8cpp.html#ac68dfa9e554c919fd51b379621b2fbc4',1,'ir_Dish.cpp']]], + ['kdishhdrspaceticks_5150',['kDishHdrSpaceTicks',['../ir__Dish_8cpp.html#ab212535e169722d7f23b461b011400c2',1,'ir_Dish.cpp']]], + ['kdishminrepeat_5151',['kDishMinRepeat',['../IRremoteESP8266_8h.html#a5c2263819b032e3af4d416ab41126bd8',1,'IRremoteESP8266.h']]], + ['kdishonespace_5152',['kDishOneSpace',['../ir__Dish_8cpp.html#a6f1986377a4571c8eba5f401b772c194',1,'ir_Dish.cpp']]], + ['kdishonespaceticks_5153',['kDishOneSpaceTicks',['../ir__Dish_8cpp.html#ade25414e4747c56303752060d9f89446',1,'ir_Dish.cpp']]], + ['kdishrptspace_5154',['kDishRptSpace',['../ir__Dish_8cpp.html#a67628a3581fe85638f72711581ec0e42',1,'ir_Dish.cpp']]], + ['kdishrptspaceticks_5155',['kDishRptSpaceTicks',['../ir__Dish_8cpp.html#a801af68fd07720f74abcf2712e3228dd',1,'ir_Dish.cpp']]], + ['kdishtick_5156',['kDishTick',['../ir__Dish_8cpp.html#aa1eccae3b18a457c7cec248d483e808a',1,'ir_Dish.cpp']]], + ['kdishzerospace_5157',['kDishZeroSpace',['../ir__Dish_8cpp.html#acde5c5a789af871f7b5aacdf3f0efeb7',1,'ir_Dish.cpp']]], + ['kdishzerospaceticks_5158',['kDishZeroSpaceTicks',['../ir__Dish_8cpp.html#a68a0f2b9e2e457c8a58fa533e0ca5336',1,'ir_Dish.cpp']]], + ['kdisplaytempstr_5159',['kDisplayTempStr',['../IRtext_8cpp.html#a018814e961b4eb51b91680db3be7d17c',1,'kDisplayTempStr(): IRtext.cpp'],['../IRtext_8h.html#a98f3ba92617c82c9091f155eebcdb3f3',1,'kDisplayTempStr(): IRtext.cpp']]], + ['kdoshishabitmark_5160',['kDoshishaBitMark',['../ir__Doshisha_8cpp.html#a50a4feaff92c4a9fbba6128638fdb2fb',1,'ir_Doshisha.cpp']]], + ['kdoshishabits_5161',['kDoshishaBits',['../IRremoteESP8266_8h.html#aedc53534cf6a40144be80abeee498362',1,'IRremoteESP8266.h']]], + ['kdoshishahdrmark_5162',['kDoshishaHdrMark',['../ir__Doshisha_8cpp.html#adbfc15a1abb62540538afc9c645c1875',1,'ir_Doshisha.cpp']]], + ['kdoshishahdrspace_5163',['kDoshishaHdrSpace',['../ir__Doshisha_8cpp.html#a95a58b09fde0ee9ba59fcf838d16f736',1,'ir_Doshisha.cpp']]], + ['kdoshishaonespace_5164',['kDoshishaOneSpace',['../ir__Doshisha_8cpp.html#a48f3b70ddd3bc06c628ebe7ce29e74d3',1,'ir_Doshisha.cpp']]], + ['kdoshishazerospace_5165',['kDoshishaZeroSpace',['../ir__Doshisha_8cpp.html#a055ae27320600bc7e100ea7e147775f9',1,'ir_Doshisha.cpp']]], + ['kdownstr_5166',['kDownStr',['../IRtext_8cpp.html#a24998688cbbe54780843983394e925e5',1,'kDownStr(): IRtext.cpp'],['../IRtext_8h.html#a1f452a2ac1a2b89b9c71cf64c177f6bd',1,'kDownStr(): IRtext.cpp']]], + ['kdrystr_5167',['kDryStr',['../IRtext_8cpp.html#a149780a7bbdd13757ee4336c281ccd9d',1,'kDryStr(): IRtext.cpp'],['../IRtext_8h.html#aa0f25fa3aa8d26f4635c38e563a974f5',1,'kDryStr(): IRtext.cpp']]], + ['kdutydefault_5168',['kDutyDefault',['../IRsend_8h.html#affa33c170fe058b783372852fca7cc5b',1,'IRsend.h']]], + ['kdutymax_5169',['kDutyMax',['../IRsend_8h.html#ac076e3f79a3d8d2dae9fc248a6f571e2',1,'IRsend.h']]], + ['keconostr_5170',['kEconoStr',['../IRtext_8cpp.html#a4e3bee67564fe8f13d1d4f997924f464',1,'kEconoStr(): IRtext.cpp'],['../IRtext_8h.html#ab0b71c4429416a581a393f07e898bade',1,'kEconoStr(): IRtext.cpp']]], + ['kelectraacauto_5171',['kElectraAcAuto',['../ir__Electra_8h.html#a536965f5003a474d68860005883afb5a',1,'ir_Electra.h']]], + ['kelectraacbitmark_5172',['kElectraAcBitMark',['../ir__Electra_8cpp.html#a41f7254b061b099b8131ec4d2a775116',1,'ir_Electra.cpp']]], + ['kelectraacbits_5173',['kElectraAcBits',['../IRremoteESP8266_8h.html#aa46876681f26ccf39c6d341fef041a16',1,'IRremoteESP8266.h']]], + ['kelectraaccleanoffset_5174',['kElectraAcCleanOffset',['../ir__Electra_8h.html#a466b5c998c1e2736214f816f1bab8239',1,'ir_Electra.h']]], + ['kelectraaccool_5175',['kElectraAcCool',['../ir__Electra_8h.html#a6a37f4e24aad54a982994599a1bca59d',1,'ir_Electra.h']]], + ['kelectraacdry_5176',['kElectraAcDry',['../ir__Electra_8h.html#a9b8636631c22e003072bf84a9e30ddff',1,'ir_Electra.h']]], + ['kelectraacfan_5177',['kElectraAcFan',['../ir__Electra_8h.html#a28047c7d083d8bc9d9e34ab210c28185',1,'ir_Electra.h']]], + ['kelectraacfanauto_5178',['kElectraAcFanAuto',['../ir__Electra_8h.html#a48b3067393d4dc1e3461db4535212bff',1,'ir_Electra.h']]], + ['kelectraacfanhigh_5179',['kElectraAcFanHigh',['../ir__Electra_8h.html#a5cbf3118669f056f377b4625e8e97d8c',1,'ir_Electra.h']]], + ['kelectraacfanlow_5180',['kElectraAcFanLow',['../ir__Electra_8h.html#a9a5663e86cb766a4e4579d1b81473c44',1,'ir_Electra.h']]], + ['kelectraacfanmed_5181',['kElectraAcFanMed',['../ir__Electra_8h.html#a4e906bcb7aa6c0fc5c71bd06c43c3993',1,'ir_Electra.h']]], + ['kelectraacfanoffset_5182',['kElectraAcFanOffset',['../ir__Electra_8h.html#a0efe73807b12370aa7c57ff831e56192',1,'ir_Electra.h']]], + ['kelectraacfansize_5183',['kElectraAcFanSize',['../ir__Electra_8h.html#aeb9bddbd47459ae51c1207baac9e6219',1,'ir_Electra.h']]], + ['kelectraachdrmark_5184',['kElectraAcHdrMark',['../ir__Electra_8cpp.html#a1200826684547765f1e526f362408e2e',1,'ir_Electra.cpp']]], + ['kelectraachdrspace_5185',['kElectraAcHdrSpace',['../ir__Electra_8cpp.html#a28cd57057c52b0def3683e71ee92c5d3',1,'ir_Electra.cpp']]], + ['kelectraacheat_5186',['kElectraAcHeat',['../ir__Electra_8h.html#af764a4738f146b752b8e29357af257e3',1,'ir_Electra.h']]], + ['kelectraaclighttogglemask_5187',['kElectraAcLightToggleMask',['../ir__Electra_8h.html#aa51ccef46052dd988ac1bccc4f2303f6',1,'ir_Electra.h']]], + ['kelectraaclighttoggleoff_5188',['kElectraAcLightToggleOff',['../ir__Electra_8h.html#ae98c4a00f003cc98c253b9367226c5c5',1,'ir_Electra.h']]], + ['kelectraaclighttoggleon_5189',['kElectraAcLightToggleOn',['../ir__Electra_8h.html#aa9ca231e98b7e529b081c3aaa1876df9',1,'ir_Electra.h']]], + ['kelectraacmaxtemp_5190',['kElectraAcMaxTemp',['../ir__Electra_8h.html#a3962ca1ae42f006baa1181683cbcbf86',1,'ir_Electra.h']]], + ['kelectraacmessagegap_5191',['kElectraAcMessageGap',['../ir__Electra_8cpp.html#adbcde2296ebf6ea93c7c95ce6d0b264e',1,'ir_Electra.cpp']]], + ['kelectraacminrepeat_5192',['kElectraAcMinRepeat',['../IRremoteESP8266_8h.html#a2ca237d578ca9a59aecac9813ab851ba',1,'IRremoteESP8266.h']]], + ['kelectraacmintemp_5193',['kElectraAcMinTemp',['../ir__Electra_8h.html#ad6f62477d70b59c958ba347c228f8e2b',1,'ir_Electra.h']]], + ['kelectraacmodeoffset_5194',['kElectraAcModeOffset',['../ir__Electra_8h.html#a79ea9dfa776115e5ec4ee816c4eef559',1,'ir_Electra.h']]], + ['kelectraaconespace_5195',['kElectraAcOneSpace',['../ir__Electra_8cpp.html#aeb59d520635a93f5dd7acdbe4327174d',1,'ir_Electra.cpp']]], + ['kelectraacpoweroffset_5196',['kElectraAcPowerOffset',['../ir__Electra_8h.html#a54012f7683397fada44f13c3e57d9ee0',1,'ir_Electra.h']]], + ['kelectraacstatelength_5197',['kElectraAcStateLength',['../IRremoteESP8266_8h.html#a8fb8c5778feaa94114218c36e8e43641',1,'IRremoteESP8266.h']]], + ['kelectraacswinghoffset_5198',['kElectraAcSwingHOffset',['../ir__Electra_8h.html#ac39219316f9b49ead4183cd206b4a3fb',1,'ir_Electra.h']]], + ['kelectraacswingoff_5199',['kElectraAcSwingOff',['../ir__Electra_8h.html#ade2211d0bd695daf490300db856d660a',1,'ir_Electra.h']]], + ['kelectraacswingon_5200',['kElectraAcSwingOn',['../ir__Electra_8h.html#a4ef75911d929752357d727aee339563e',1,'ir_Electra.h']]], + ['kelectraacswingsize_5201',['kElectraAcSwingSize',['../ir__Electra_8h.html#a67c58c049b50d04d4fadd93eee0231cf',1,'ir_Electra.h']]], + ['kelectraacswingvoffset_5202',['kElectraAcSwingVOffset',['../ir__Electra_8h.html#a4a5737e41994fe6c0cd566be354a70fb',1,'ir_Electra.h']]], + ['kelectraactempdelta_5203',['kElectraAcTempDelta',['../ir__Electra_8h.html#ac3310f7b0d4b9fbe22d7192465669487',1,'ir_Electra.h']]], + ['kelectraactempoffset_5204',['kElectraAcTempOffset',['../ir__Electra_8h.html#a928ee72169f9ab56a4209606aa7e5e43',1,'ir_Electra.h']]], + ['kelectraactempsize_5205',['kElectraAcTempSize',['../ir__Electra_8h.html#aeeb469144f4fd02ddd8a802f5cf7c308',1,'ir_Electra.h']]], + ['kelectraacturbooffset_5206',['kElectraAcTurboOffset',['../ir__Electra_8h.html#afbbd997ef8ddf5a4adfd0a37404d6782',1,'ir_Electra.h']]], + ['kelectraaczerospace_5207',['kElectraAcZeroSpace',['../ir__Electra_8cpp.html#a1453e0796cfe6ca169fd3c56e2595082',1,'ir_Electra.cpp']]], + ['kepsonbits_5208',['kEpsonBits',['../IRremoteESP8266_8h.html#a77a0ed1143f5bfec87e0c9fde5c2c425',1,'IRremoteESP8266.h']]], + ['kepsonminrepeat_5209',['kEpsonMinRepeat',['../IRremoteESP8266_8h.html#ac8738cb054de937b77269acb973c5133',1,'IRremoteESP8266.h']]], + ['keyeautostr_5210',['kEyeAutoStr',['../IRtext_8cpp.html#ab7c525442638022439c7a277e1edf694',1,'kEyeAutoStr(): IRtext.cpp'],['../IRtext_8h.html#ae1395c08682a2b858261d76b97311f4f',1,'kEyeAutoStr(): IRtext.cpp']]], + ['keyestr_5211',['kEyeStr',['../IRtext_8cpp.html#a1d8dc83e7f15aacd013509e36a49a9d8',1,'kEyeStr(): IRtext.cpp'],['../IRtext_8h.html#a84f6d62456976cc31fe6b1648182a885',1,'kEyeStr(): IRtext.cpp']]], + ['kfalsestr_5212',['kFalseStr',['../IRtext_8cpp.html#a338ee31c8fb5a1c74c0640b279051cd2',1,'kFalseStr(): IRtext.cpp'],['../IRtext_8h.html#a3dc9321c4146369e0e0794e6a4de1988',1,'kFalseStr(): IRtext.cpp']]], + ['kfanonlystr_5213',['kFanOnlyStr',['../IRtext_8cpp.html#adada7550fa28466a6db6f4544f8c7063',1,'kFanOnlyStr(): IRtext.cpp'],['../IRtext_8h.html#a220378c7b69db06362af5ad932965628',1,'kFanOnlyStr(): IRtext.cpp']]], + ['kfanstr_5214',['kFanStr',['../IRtext_8cpp.html#aaab703dfae684a786852a55c0f7f61ec',1,'kFanStr(): IRtext.cpp'],['../IRtext_8h.html#af7a0d76c40f3173a3e1367665d789300',1,'kFanStr(): IRtext.cpp']]], + ['kfaststr_5215',['kFastStr',['../IRtext_8cpp.html#ad6084cb569cd62bb1199c6ecc8ac4126',1,'kFastStr(): IRtext.cpp'],['../IRtext_8h.html#a82c26d9c7690ce001223e2a7cf8664d8',1,'kFastStr(): IRtext.cpp']]], + ['kfilterstr_5216',['kFilterStr',['../IRtext_8cpp.html#af287ead64de5dc3b1cbafe7bc945e519',1,'kFilterStr(): IRtext.cpp'],['../IRtext_8h.html#a5b3133e24c729077da411e08119033be',1,'kFilterStr(): IRtext.cpp']]], + ['kfixedstr_5217',['kFixedStr',['../IRtext_8cpp.html#ab45f91a889dae134e48c86586608bfc9',1,'kFixedStr(): IRtext.cpp'],['../IRtext_8h.html#ad9112f221a20ab498c5f133c4cea0b14',1,'kFixedStr(): IRtext.cpp']]], + ['kfnvbasis32_5218',['kFnvBasis32',['../IRrecv_8h.html#a04d9b0c909b377b36af3ece668482ca3',1,'IRrecv.h']]], + ['kfnvprime32_5219',['kFnvPrime32',['../IRrecv_8h.html#abcfcce36d3e2faef742aa3529c22f23f',1,'IRrecv.h']]], + ['kfollowstr_5220',['kFollowStr',['../IRtext_8cpp.html#a5477068666c86b3d605df8cf0240c86f',1,'kFollowStr(): IRtext.cpp'],['../IRtext_8h.html#a47a659e1c6373c4af92f4261148f695b',1,'kFollowStr(): IRtext.cpp']]], + ['kfooter_5221',['kFooter',['../IRrecv_8h.html#a5abb2b821f207ee9cf35f889f86d0ea3',1,'IRrecv.h']]], + ['kfreshstr_5222',['kFreshStr',['../IRtext_8cpp.html#ae416979803b912c932aa5eda837fc471',1,'kFreshStr(): IRtext.cpp'],['../IRtext_8h.html#adc8991e424df3ebf2f47ffc2854057f2',1,'kFreshStr(): IRtext.cpp']]], + ['kfujitsuacbitmark_5223',['kFujitsuAcBitMark',['../ir__Fujitsu_8cpp.html#a2e01906b1317da42fcc204284646e3db',1,'ir_Fujitsu.cpp']]], + ['kfujitsuacbits_5224',['kFujitsuAcBits',['../IRremoteESP8266_8h.html#aecd63891cac014d1b7e344638086ad47',1,'IRremoteESP8266.h']]], + ['kfujitsuaccleanoffset_5225',['kFujitsuAcCleanOffset',['../ir__Fujitsu_8h.html#ae7e7dc770ef9712296d2beeb085d2c1f',1,'ir_Fujitsu.h']]], + ['kfujitsuaccmdecono_5226',['kFujitsuAcCmdEcono',['../ir__Fujitsu_8h.html#a1e1eb4274232c43769f70b40f395a084',1,'ir_Fujitsu.h']]], + ['kfujitsuaccmdpowerful_5227',['kFujitsuAcCmdPowerful',['../ir__Fujitsu_8h.html#a69349537a37674a82b8ca630e6ca1b5a',1,'ir_Fujitsu.h']]], + ['kfujitsuaccmdstayon_5228',['kFujitsuAcCmdStayOn',['../ir__Fujitsu_8h.html#acc729a2cd570761f97c63b98024c157d',1,'ir_Fujitsu.h']]], + ['kfujitsuaccmdstephoriz_5229',['kFujitsuAcCmdStepHoriz',['../ir__Fujitsu_8h.html#ac67e3fa9ab8f1e1146bed1296f9a2131',1,'ir_Fujitsu.h']]], + ['kfujitsuaccmdstepvert_5230',['kFujitsuAcCmdStepVert',['../ir__Fujitsu_8h.html#a5dda60d753d93089fc323bfcd9567afd',1,'ir_Fujitsu.h']]], + ['kfujitsuaccmdtoggleswinghoriz_5231',['kFujitsuAcCmdToggleSwingHoriz',['../ir__Fujitsu_8h.html#a43b5912e65a8e6d3f1c672b155135f27',1,'ir_Fujitsu.h']]], + ['kfujitsuaccmdtoggleswingvert_5232',['kFujitsuAcCmdToggleSwingVert',['../ir__Fujitsu_8h.html#a66960882cee5d109f332917fe1f8067c',1,'ir_Fujitsu.h']]], + ['kfujitsuaccmdturnoff_5233',['kFujitsuAcCmdTurnOff',['../ir__Fujitsu_8h.html#a073903b56c40d89b9999ee9b7dc48f00',1,'ir_Fujitsu.h']]], + ['kfujitsuaccmdturnon_5234',['kFujitsuAcCmdTurnOn',['../ir__Fujitsu_8h.html#a51c2abda78c7d6ced59f88acb857281e',1,'ir_Fujitsu.h']]], + ['kfujitsuacfanauto_5235',['kFujitsuAcFanAuto',['../ir__Fujitsu_8h.html#a55bbb5a5b1760515f070d302c9fa4cbb',1,'ir_Fujitsu.h']]], + ['kfujitsuacfanhigh_5236',['kFujitsuAcFanHigh',['../ir__Fujitsu_8h.html#a30b11ea24865a00b10468015aae77886',1,'ir_Fujitsu.h']]], + ['kfujitsuacfanlow_5237',['kFujitsuAcFanLow',['../ir__Fujitsu_8h.html#aa0162cde862a3c02dd877a3a7933c130',1,'ir_Fujitsu.h']]], + ['kfujitsuacfanmed_5238',['kFujitsuAcFanMed',['../ir__Fujitsu_8h.html#a0efcb8e8a6521e4788a82ff6c556b67b',1,'ir_Fujitsu.h']]], + ['kfujitsuacfanquiet_5239',['kFujitsuAcFanQuiet',['../ir__Fujitsu_8h.html#a9abb4ec5fe9f27c6acd62273329490b6',1,'ir_Fujitsu.h']]], + ['kfujitsuacfansize_5240',['kFujitsuAcFanSize',['../ir__Fujitsu_8h.html#a797e68082ceebea788a215ecbfc279d9',1,'ir_Fujitsu.h']]], + ['kfujitsuacfilteroffset_5241',['kFujitsuAcFilterOffset',['../ir__Fujitsu_8h.html#a3c6349b24651bffb33f2633d3c65144c',1,'ir_Fujitsu.h']]], + ['kfujitsuachdrmark_5242',['kFujitsuAcHdrMark',['../ir__Fujitsu_8cpp.html#a96402e0aed6962a8a72cc736fa9bbc08',1,'ir_Fujitsu.cpp']]], + ['kfujitsuachdrspace_5243',['kFujitsuAcHdrSpace',['../ir__Fujitsu_8cpp.html#a655e37e172ab06dc06ca69f3c06223b2',1,'ir_Fujitsu.cpp']]], + ['kfujitsuacmaxtemp_5244',['kFujitsuAcMaxTemp',['../ir__Fujitsu_8h.html#ad817f46441ac1284e3bbe8417e4f4388',1,'ir_Fujitsu.h']]], + ['kfujitsuacminbits_5245',['kFujitsuAcMinBits',['../IRremoteESP8266_8h.html#a025caa6d0ae6becdd5ee58b5ac6ed61f',1,'IRremoteESP8266.h']]], + ['kfujitsuacmingap_5246',['kFujitsuAcMinGap',['../ir__Fujitsu_8cpp.html#a255fab3b9047b34cf6c4d42c0c82c485',1,'ir_Fujitsu.cpp']]], + ['kfujitsuacminrepeat_5247',['kFujitsuAcMinRepeat',['../IRremoteESP8266_8h.html#a9dd52420366167afb4c8831b4ccd02fa',1,'IRremoteESP8266.h']]], + ['kfujitsuacmintemp_5248',['kFujitsuAcMinTemp',['../ir__Fujitsu_8h.html#a35ec9572b356a7bcfb75947d03b198f7',1,'ir_Fujitsu.h']]], + ['kfujitsuacmodeauto_5249',['kFujitsuAcModeAuto',['../ir__Fujitsu_8h.html#acf0aa6d1d033c893a3acd5b8d7756a5b',1,'ir_Fujitsu.h']]], + ['kfujitsuacmodecool_5250',['kFujitsuAcModeCool',['../ir__Fujitsu_8h.html#a782e226fadab0a256144821cacea2314',1,'ir_Fujitsu.h']]], + ['kfujitsuacmodedry_5251',['kFujitsuAcModeDry',['../ir__Fujitsu_8h.html#ae66f2ed2e554a6befdf0377d01bce257',1,'ir_Fujitsu.h']]], + ['kfujitsuacmodefan_5252',['kFujitsuAcModeFan',['../ir__Fujitsu_8h.html#a7cc07ec4747b5cebc50257ec02297800',1,'ir_Fujitsu.h']]], + ['kfujitsuacmodeheat_5253',['kFujitsuAcModeHeat',['../ir__Fujitsu_8h.html#ad9b47b7419853a4cb1cf072023dac69b',1,'ir_Fujitsu.h']]], + ['kfujitsuaconespace_5254',['kFujitsuAcOneSpace',['../ir__Fujitsu_8cpp.html#a4f5246e6428cc701dbaa18923904713a',1,'ir_Fujitsu.cpp']]], + ['kfujitsuacoutsidequietoffset_5255',['kFujitsuAcOutsideQuietOffset',['../ir__Fujitsu_8h.html#a38522dc07bb7be2dd1ec654d4e60eb4f',1,'ir_Fujitsu.h']]], + ['kfujitsuacstatelength_5256',['kFujitsuAcStateLength',['../IRremoteESP8266_8h.html#ac3aa33a8386f73de0f57fc1ff7c6e7d9',1,'IRremoteESP8266.h']]], + ['kfujitsuacstatelengthshort_5257',['kFujitsuAcStateLengthShort',['../IRremoteESP8266_8h.html#a81cb09663eedbdc3888ee68438f0a5d3',1,'IRremoteESP8266.h']]], + ['kfujitsuacswingboth_5258',['kFujitsuAcSwingBoth',['../ir__Fujitsu_8h.html#a07c5a757b0c3bbe07412813807272434',1,'ir_Fujitsu.h']]], + ['kfujitsuacswinghoriz_5259',['kFujitsuAcSwingHoriz',['../ir__Fujitsu_8h.html#a8875f62d61afb8cbf468207aedcb8982',1,'ir_Fujitsu.h']]], + ['kfujitsuacswingoff_5260',['kFujitsuAcSwingOff',['../ir__Fujitsu_8h.html#a7f8109a1b8fd13a93d6b0255d05413df',1,'ir_Fujitsu.h']]], + ['kfujitsuacswingsize_5261',['kFujitsuAcSwingSize',['../ir__Fujitsu_8h.html#a1eb20884dc6c9bccbe899f779c4b5ad4',1,'ir_Fujitsu.h']]], + ['kfujitsuacswingvert_5262',['kFujitsuAcSwingVert',['../ir__Fujitsu_8h.html#a5c532a43ab11bf7cb353de2081260f40',1,'ir_Fujitsu.h']]], + ['kfujitsuaczerospace_5263',['kFujitsuAcZeroSpace',['../ir__Fujitsu_8cpp.html#a3815b89a2037cd0c8d774217df603d6e',1,'ir_Fujitsu.cpp']]], + ['kgicablebitmark_5264',['kGicableBitMark',['../ir__GICable_8cpp.html#ac315be0b5e02fb4c7109a6f67c4fac8e',1,'ir_GICable.cpp']]], + ['kgicablebits_5265',['kGicableBits',['../IRremoteESP8266_8h.html#aceb5cbd7ba5d8bc11560ba29137b10fa',1,'IRremoteESP8266.h']]], + ['kgicablehdrmark_5266',['kGicableHdrMark',['../ir__GICable_8cpp.html#a0388e7a2030246928029ed1c79ba819d',1,'ir_GICable.cpp']]], + ['kgicablehdrspace_5267',['kGicableHdrSpace',['../ir__GICable_8cpp.html#ab357b0a095155eab6206245008387fc0',1,'ir_GICable.cpp']]], + ['kgicablemincommandlength_5268',['kGicableMinCommandLength',['../ir__GICable_8cpp.html#a79db5de95ff6b42259f0a54fa59f46f6',1,'ir_GICable.cpp']]], + ['kgicablemingap_5269',['kGicableMinGap',['../ir__GICable_8cpp.html#aff7027ab4b933e4a7f5506590c25f699',1,'ir_GICable.cpp']]], + ['kgicableminrepeat_5270',['kGicableMinRepeat',['../IRremoteESP8266_8h.html#ad8142649290db6fc337ac839d4078aef',1,'IRremoteESP8266.h']]], + ['kgicableonespace_5271',['kGicableOneSpace',['../ir__GICable_8cpp.html#a31300a6f41363cbc22d40f26e693b8be',1,'ir_GICable.cpp']]], + ['kgicablerptspace_5272',['kGicableRptSpace',['../ir__GICable_8cpp.html#a9e0d82ed05e210dec2980a7d1a2e081b',1,'ir_GICable.cpp']]], + ['kgicablezerospace_5273',['kGicableZeroSpace',['../ir__GICable_8cpp.html#a1383f274e701ad5c8141beb7703783ff',1,'ir_GICable.cpp']]], + ['kglobalcachefreqindex_5274',['kGlobalCacheFreqIndex',['../ir__GlobalCache_8cpp.html#aaa0bdfe1eb76e8519a111b6588a5a3ff',1,'ir_GlobalCache.cpp']]], + ['kglobalcachemaxrepeat_5275',['kGlobalCacheMaxRepeat',['../ir__GlobalCache_8cpp.html#ae4a19c45ab538e8a386769cd98943a0d',1,'ir_GlobalCache.cpp']]], + ['kglobalcacheminusec_5276',['kGlobalCacheMinUsec',['../ir__GlobalCache_8cpp.html#a133cf089a7b40516fac3b1143981b2a6',1,'ir_GlobalCache.cpp']]], + ['kglobalcacherptindex_5277',['kGlobalCacheRptIndex',['../ir__GlobalCache_8cpp.html#ad4d55ed7e89cfc6d513dae6ecb211fe9',1,'ir_GlobalCache.cpp']]], + ['kglobalcacherptstartindex_5278',['kGlobalCacheRptStartIndex',['../ir__GlobalCache_8cpp.html#afde4c65e9e75558df6ac7aa479bf507a',1,'ir_GlobalCache.cpp']]], + ['kglobalcachestartindex_5279',['kGlobalCacheStartIndex',['../ir__GlobalCache_8cpp.html#a8640be7a67ce3f49452b28bc24912637',1,'ir_GlobalCache.cpp']]], + ['kgoodweatherauto_5280',['kGoodweatherAuto',['../ir__Goodweather_8h.html#a2fc5f0f7d0f68dcff193548830f50528',1,'ir_Goodweather.h']]], + ['kgoodweatherbitairflow_5281',['kGoodweatherBitAirFlow',['../ir__Goodweather_8h.html#ad86cdbc34a6a82c7595cace56d040d64',1,'ir_Goodweather.h']]], + ['kgoodweatherbitcommand_5282',['kGoodweatherBitCommand',['../ir__Goodweather_8h.html#ad6973bf4ac7801097077938e133b1718',1,'ir_Goodweather.h']]], + ['kgoodweatherbiteof_5283',['kGoodweatherBitEOF',['../ir__Goodweather_8h.html#a239d4d1fee77e0d220efb0bc0b3c779a',1,'ir_Goodweather.h']]], + ['kgoodweatherbitfan_5284',['kGoodweatherBitFan',['../ir__Goodweather_8h.html#aa3d5f146109dd671e4d7d86c1dbccba7',1,'ir_Goodweather.h']]], + ['kgoodweatherbitlight_5285',['kGoodweatherBitLight',['../ir__Goodweather_8h.html#a976dc2b37d1fcec4bbc0958861b5a9b0',1,'ir_Goodweather.h']]], + ['kgoodweatherbitmark_5286',['kGoodweatherBitMark',['../ir__Goodweather_8h.html#acb9fb47b2a207997fda0244d1bafbe89',1,'ir_Goodweather.h']]], + ['kgoodweatherbitmode_5287',['kGoodweatherBitMode',['../ir__Goodweather_8h.html#a3795b45c06f6d2db23cc45478bfeeca9',1,'ir_Goodweather.h']]], + ['kgoodweatherbitpower_5288',['kGoodweatherBitPower',['../ir__Goodweather_8h.html#a652b820b22c8381a6035fea7b1ae1b8d',1,'ir_Goodweather.h']]], + ['kgoodweatherbits_5289',['kGoodweatherBits',['../IRremoteESP8266_8h.html#afa2675ce42d00175ec95caa6cd87a425',1,'IRremoteESP8266.h']]], + ['kgoodweatherbitsleep_5290',['kGoodweatherBitSleep',['../ir__Goodweather_8h.html#a763e8033483516c093ad12a378e0c8f8',1,'ir_Goodweather.h']]], + ['kgoodweatherbitswing_5291',['kGoodweatherBitSwing',['../ir__Goodweather_8h.html#a0a3fc264b6a77157174c207688ac2cda',1,'ir_Goodweather.h']]], + ['kgoodweatherbittemp_5292',['kGoodweatherBitTemp',['../ir__Goodweather_8h.html#a692faf9976f90d67d183ff99ed06ee51',1,'ir_Goodweather.h']]], + ['kgoodweatherbitturbo_5293',['kGoodweatherBitTurbo',['../ir__Goodweather_8h.html#afe2ad22bc8ba5ab9cad025e9adaf4d56',1,'ir_Goodweather.h']]], + ['kgoodweathercmdairflow_5294',['kGoodweatherCmdAirFlow',['../ir__Goodweather_8h.html#aa51248353573abd95af37e46f0a2c4a7',1,'ir_Goodweather.h']]], + ['kgoodweathercmddowntemp_5295',['kGoodweatherCmdDownTemp',['../ir__Goodweather_8h.html#a8a0b72bf745b6003fb460a3c917eecff',1,'ir_Goodweather.h']]], + ['kgoodweathercmdfan_5296',['kGoodweatherCmdFan',['../ir__Goodweather_8h.html#a4a0881f87af157fdf9ed3d9f342f1ac5',1,'ir_Goodweather.h']]], + ['kgoodweathercmdhold_5297',['kGoodweatherCmdHold',['../ir__Goodweather_8h.html#ac0f3b1413228cb7e86822c5690f20344',1,'ir_Goodweather.h']]], + ['kgoodweathercmdlight_5298',['kGoodweatherCmdLight',['../ir__Goodweather_8h.html#ae70c4e66b17db9caf4800eb57a50706f',1,'ir_Goodweather.h']]], + ['kgoodweathercmdmode_5299',['kGoodweatherCmdMode',['../ir__Goodweather_8h.html#a6042296931ab29e9dfa5a701f3e42175',1,'ir_Goodweather.h']]], + ['kgoodweathercmdpower_5300',['kGoodweatherCmdPower',['../ir__Goodweather_8h.html#a3f1bf85bb10343512bb276adfc64b3b2',1,'ir_Goodweather.h']]], + ['kgoodweathercmdsleep_5301',['kGoodweatherCmdSleep',['../ir__Goodweather_8h.html#a3f4d72b620c73aec68c2125430ca709d',1,'ir_Goodweather.h']]], + ['kgoodweathercmdswing_5302',['kGoodweatherCmdSwing',['../ir__Goodweather_8h.html#ab4ceedbe859811a9fb394f6ebf233cb5',1,'ir_Goodweather.h']]], + ['kgoodweathercmdtimer_5303',['kGoodweatherCmdTimer',['../ir__Goodweather_8h.html#ad4d247ea6c9fc237e0acda84fdaa2eb6',1,'ir_Goodweather.h']]], + ['kgoodweathercmdturbo_5304',['kGoodweatherCmdTurbo',['../ir__Goodweather_8h.html#aebc6d53b3e7d1769bff47968c19c09c9',1,'ir_Goodweather.h']]], + ['kgoodweathercmduptemp_5305',['kGoodweatherCmdUpTemp',['../ir__Goodweather_8h.html#a51a089b03bd72a247a4c35c2ff3f3dc6',1,'ir_Goodweather.h']]], + ['kgoodweathercommandsize_5306',['kGoodweatherCommandSize',['../ir__Goodweather_8h.html#aa5ae9f1b5f6458a25b31b0d2c7feb508',1,'ir_Goodweather.h']]], + ['kgoodweathercool_5307',['kGoodweatherCool',['../ir__Goodweather_8h.html#a92c807d6ff8a3356e65f04e82b99aba4',1,'ir_Goodweather.h']]], + ['kgoodweatherdry_5308',['kGoodweatherDry',['../ir__Goodweather_8h.html#ac5174a3e2c64361c25adcf7caa5b714c',1,'ir_Goodweather.h']]], + ['kgoodweathereofmask_5309',['kGoodweatherEOFMask',['../ir__Goodweather_8h.html#a3d86da1a2bab92a9f70cc88e2628f266',1,'ir_Goodweather.h']]], + ['kgoodweatherextratolerance_5310',['kGoodweatherExtraTolerance',['../ir__Goodweather_8h.html#aae814dfbd574241d3b434d0bf2d38939',1,'ir_Goodweather.h']]], + ['kgoodweatherfan_5311',['kGoodweatherFan',['../ir__Goodweather_8h.html#ad56f00c7e39df93d28419d6a4afa360b',1,'ir_Goodweather.h']]], + ['kgoodweatherfanauto_5312',['kGoodweatherFanAuto',['../ir__Goodweather_8h.html#a9cc119524ac1cb93395dff3bb44b85cc',1,'ir_Goodweather.h']]], + ['kgoodweatherfanhigh_5313',['kGoodweatherFanHigh',['../ir__Goodweather_8h.html#af2b24de50923a0aabd4379dc6d3ef10f',1,'ir_Goodweather.h']]], + ['kgoodweatherfanlow_5314',['kGoodweatherFanLow',['../ir__Goodweather_8h.html#a7bc7c0cf9f2df574a7c087542991ab9b',1,'ir_Goodweather.h']]], + ['kgoodweatherfanmed_5315',['kGoodweatherFanMed',['../ir__Goodweather_8h.html#a5174245e9369a488332b32dfa416963e',1,'ir_Goodweather.h']]], + ['kgoodweatherfansize_5316',['kGoodweatherFanSize',['../ir__Goodweather_8h.html#a687ae6502d8fe6b4a5bd11468106481e',1,'ir_Goodweather.h']]], + ['kgoodweatherhdrmark_5317',['kGoodweatherHdrMark',['../ir__Goodweather_8h.html#a5c39e33226770babb4b0e89fc0cde709',1,'ir_Goodweather.h']]], + ['kgoodweatherhdrspace_5318',['kGoodweatherHdrSpace',['../ir__Goodweather_8h.html#a837bfeaa111b00e2744c4ada89281bfb',1,'ir_Goodweather.h']]], + ['kgoodweatherheat_5319',['kGoodweatherHeat',['../ir__Goodweather_8h.html#a17d223f03df2718151a426582a224a2e',1,'ir_Goodweather.h']]], + ['kgoodweatherminrepeat_5320',['kGoodweatherMinRepeat',['../IRremoteESP8266_8h.html#a885bc5a3a5ba2d8827a62d07a43d0321',1,'IRremoteESP8266.h']]], + ['kgoodweatheronespace_5321',['kGoodweatherOneSpace',['../ir__Goodweather_8h.html#a8efa251085a8f434cb91c049e65cda56',1,'ir_Goodweather.h']]], + ['kgoodweatherstateinit_5322',['kGoodweatherStateInit',['../ir__Goodweather_8h.html#a5ec0e7ca097241d6bef0cbf2135c8fca',1,'ir_Goodweather.h']]], + ['kgoodweatherswingfast_5323',['kGoodweatherSwingFast',['../ir__Goodweather_8h.html#a2d2fa76fa35cf7d450aaf0b980660514',1,'ir_Goodweather.h']]], + ['kgoodweatherswingoff_5324',['kGoodweatherSwingOff',['../ir__Goodweather_8h.html#aa2c53f56daa2820351924d91b542bb67',1,'ir_Goodweather.h']]], + ['kgoodweatherswingsize_5325',['kGoodweatherSwingSize',['../ir__Goodweather_8h.html#a208e47dc4f9e6a85464b4ce3ecaf5c3e',1,'ir_Goodweather.h']]], + ['kgoodweatherswingslow_5326',['kGoodweatherSwingSlow',['../ir__Goodweather_8h.html#ad2c87d849af2c77088ffc533d279aadb',1,'ir_Goodweather.h']]], + ['kgoodweathertempmax_5327',['kGoodweatherTempMax',['../ir__Goodweather_8h.html#abec401548ce2221a9c668318a33a039c',1,'ir_Goodweather.h']]], + ['kgoodweathertempmin_5328',['kGoodweatherTempMin',['../ir__Goodweather_8h.html#a8e76c0ec1bd5e124d9cee5742a2d1cfe',1,'ir_Goodweather.h']]], + ['kgoodweathertempsize_5329',['kGoodweatherTempSize',['../ir__Goodweather_8h.html#a2ef3336be36de4f34940de28cfe195a8',1,'ir_Goodweather.h']]], + ['kgoodweatherzerospace_5330',['kGoodweatherZeroSpace',['../ir__Goodweather_8h.html#a411cbfb812d102daeaf6a83c742f9a9a',1,'ir_Goodweather.h']]], + ['kgpiounused_5331',['kGpioUnused',['../IRac_8h.html#afd817f0bc02c516b6430098dcecde383',1,'IRac.h']]], + ['kgreeauto_5332',['kGreeAuto',['../ir__Gree_8h.html#a65d2d0192a1baff86b859da1018ef2f8',1,'ir_Gree.h']]], + ['kgreebitmark_5333',['kGreeBitMark',['../ir__Gree_8cpp.html#ad7e23346f6d793cc2469e4c8a5650397',1,'ir_Gree.cpp']]], + ['kgreebits_5334',['kGreeBits',['../IRremoteESP8266_8h.html#acadcc5d03e09784642f008d4d2913c7d',1,'IRremoteESP8266.h']]], + ['kgreeblockfooter_5335',['kGreeBlockFooter',['../ir__Gree_8cpp.html#ae6d01cfa7ee2ef6ff27c1ecd7cd9be51',1,'ir_Gree.cpp']]], + ['kgreeblockfooterbits_5336',['kGreeBlockFooterBits',['../ir__Gree_8cpp.html#ae866eef4c729c703597a266917799cbd',1,'ir_Gree.cpp']]], + ['kgreecool_5337',['kGreeCool',['../ir__Gree_8h.html#a1e1eeab696b43864cec66e6485487cea',1,'ir_Gree.h']]], + ['kgreedefaultrepeat_5338',['kGreeDefaultRepeat',['../IRremoteESP8266_8h.html#a6816d2cb11b99a61fb63e6d0928e6706',1,'IRremoteESP8266.h']]], + ['kgreedisplaytempinside_5339',['kGreeDisplayTempInside',['../ir__Gree_8h.html#a7495e5873f63135490090929ed79e994',1,'ir_Gree.h']]], + ['kgreedisplaytempoff_5340',['kGreeDisplayTempOff',['../ir__Gree_8h.html#aa5881910d1c01b816f3ac22ddf0f89a8',1,'ir_Gree.h']]], + ['kgreedisplaytempoffset_5341',['kGreeDisplayTempOffset',['../ir__Gree_8h.html#ab60baff4d0e83964d6e5b23994949a06',1,'ir_Gree.h']]], + ['kgreedisplaytempoutside_5342',['kGreeDisplayTempOutside',['../ir__Gree_8h.html#a737c90e90897053623b15b5579cdb6a1',1,'ir_Gree.h']]], + ['kgreedisplaytempset_5343',['kGreeDisplayTempSet',['../ir__Gree_8h.html#a20f7d0948b158f83655ee4187a104176',1,'ir_Gree.h']]], + ['kgreedisplaytempsize_5344',['kGreeDisplayTempSize',['../ir__Gree_8h.html#aad94a8d5de27b1a46c03c9e3773cf8ec',1,'ir_Gree.h']]], + ['kgreedry_5345',['kGreeDry',['../ir__Gree_8h.html#aa818bcc036988ee24fe0467d128d174f',1,'ir_Gree.h']]], + ['kgreefan_5346',['kGreeFan',['../ir__Gree_8h.html#aa1513ffe43257664f761e4e1a5c2a38f',1,'ir_Gree.h']]], + ['kgreefanauto_5347',['kGreeFanAuto',['../ir__Gree_8h.html#aaad16357e34078257315aad7155b2cd1',1,'ir_Gree.h']]], + ['kgreefanmax_5348',['kGreeFanMax',['../ir__Gree_8h.html#a8753f860f2f503a4a70609fb000654f2',1,'ir_Gree.h']]], + ['kgreefanmed_5349',['kGreeFanMed',['../ir__Gree_8h.html#a674d096a91a5db4b5b7f1b0650c833de',1,'ir_Gree.h']]], + ['kgreefanmin_5350',['kGreeFanMin',['../ir__Gree_8h.html#a34ca09b196c41acc85a4fa0036f3ac3b',1,'ir_Gree.h']]], + ['kgreefanoffset_5351',['kGreeFanOffset',['../ir__Gree_8h.html#a3227e6075f673408577884feb0e6ef10',1,'ir_Gree.h']]], + ['kgreefansize_5352',['kGreeFanSize',['../ir__Gree_8h.html#a8285633b179fbe513c6f8bd2c316e957',1,'ir_Gree.h']]], + ['kgreehdrmark_5353',['kGreeHdrMark',['../ir__Gree_8cpp.html#aaae182fb09bed73e37a5b5d3aee6a5fb',1,'ir_Gree.cpp']]], + ['kgreehdrspace_5354',['kGreeHdrSpace',['../ir__Gree_8cpp.html#a96b50632219c2b5808aea4ee9077b15c',1,'ir_Gree.cpp']]], + ['kgreeheat_5355',['kGreeHeat',['../ir__Gree_8h.html#ada5dac7b789497bf7a434a809d4070f6',1,'ir_Gree.h']]], + ['kgreeifeeloffset_5356',['kGreeIFeelOffset',['../ir__Gree_8h.html#a7253f3b97bade5353a72bfcf2df7976b',1,'ir_Gree.h']]], + ['kgreelightoffset_5357',['kGreeLightOffset',['../ir__Gree_8h.html#ade795164ac467f2547583b9654e2e471',1,'ir_Gree.h']]], + ['kgreemaxtempc_5358',['kGreeMaxTempC',['../ir__Gree_8h.html#a4c01aedfff06ed5a028c40010ad7bfa0',1,'ir_Gree.h']]], + ['kgreemaxtempf_5359',['kGreeMaxTempF',['../ir__Gree_8h.html#a6495898a7a6ddda1473b55820f4b6c44',1,'ir_Gree.h']]], + ['kgreemintempc_5360',['kGreeMinTempC',['../ir__Gree_8h.html#ad127acfc710e281a7b29023c8d1da8f6',1,'ir_Gree.h']]], + ['kgreemintempf_5361',['kGreeMinTempF',['../ir__Gree_8h.html#acf0ecb1b535894e3e790b668333fb66b',1,'ir_Gree.h']]], + ['kgreemsgspace_5362',['kGreeMsgSpace',['../ir__Gree_8cpp.html#a619ed3a2915196ab91d87db2b5a829fd',1,'ir_Gree.cpp']]], + ['kgreeonespace_5363',['kGreeOneSpace',['../ir__Gree_8cpp.html#ab139138084643ea0fca13b28412904e9',1,'ir_Gree.cpp']]], + ['kgreepower1offset_5364',['kGreePower1Offset',['../ir__Gree_8h.html#a300b990aa836926d38dfea0ee99dc295',1,'ir_Gree.h']]], + ['kgreepower2offset_5365',['kGreePower2Offset',['../ir__Gree_8h.html#af29131d47e6cba73682727cd5e8b243d',1,'ir_Gree.h']]], + ['kgreesleepoffset_5366',['kGreeSleepOffset',['../ir__Gree_8h.html#ab715200758a0a4ee2733baf924729132',1,'ir_Gree.h']]], + ['kgreestatelength_5367',['kGreeStateLength',['../IRremoteESP8266_8h.html#a5558b24542873d8475e1ee0e2439839f',1,'IRremoteESP8266.h']]], + ['kgreeswingauto_5368',['kGreeSwingAuto',['../ir__Gree_8h.html#a414a503ad11c1d1d3b68d8b630df1f3a',1,'ir_Gree.h']]], + ['kgreeswingautooffset_5369',['kGreeSwingAutoOffset',['../ir__Gree_8h.html#a60d3de1ba88a6b06c79205116fbd7869',1,'ir_Gree.h']]], + ['kgreeswingdown_5370',['kGreeSwingDown',['../ir__Gree_8h.html#abbe69b966ceb1f9eb60fe9c3fb18088d',1,'ir_Gree.h']]], + ['kgreeswingdownauto_5371',['kGreeSwingDownAuto',['../ir__Gree_8h.html#abc7d7b7de5dd2eb9c0a6ca28827aeb06',1,'ir_Gree.h']]], + ['kgreeswinglastpos_5372',['kGreeSwingLastPos',['../ir__Gree_8h.html#a630cd8fec01f13bfda0fffc1a0e59199',1,'ir_Gree.h']]], + ['kgreeswingmiddle_5373',['kGreeSwingMiddle',['../ir__Gree_8h.html#a12a7caa871f33a5bb83611b4efc7a42b',1,'ir_Gree.h']]], + ['kgreeswingmiddleauto_5374',['kGreeSwingMiddleAuto',['../ir__Gree_8h.html#ac9f85ef5c1bfeac1e4c759742e2d147f',1,'ir_Gree.h']]], + ['kgreeswingmiddledown_5375',['kGreeSwingMiddleDown',['../ir__Gree_8h.html#acad74b8154d73786e093fa215ab800b0',1,'ir_Gree.h']]], + ['kgreeswingmiddleup_5376',['kGreeSwingMiddleUp',['../ir__Gree_8h.html#aefbdd203df5b35eb61be1d0edd712c80',1,'ir_Gree.h']]], + ['kgreeswingsize_5377',['kGreeSwingSize',['../ir__Gree_8h.html#a287e3c06c9a1efbf7091841f2f689968',1,'ir_Gree.h']]], + ['kgreeswingup_5378',['kGreeSwingUp',['../ir__Gree_8h.html#adad431eb1010951fcf77dc4dac6449c6',1,'ir_Gree.h']]], + ['kgreeswingupauto_5379',['kGreeSwingUpAuto',['../ir__Gree_8h.html#a63f04add215785d4ccfe6ccec03d7667',1,'ir_Gree.h']]], + ['kgreetempextradegreefoffset_5380',['kGreeTempExtraDegreeFOffset',['../ir__Gree_8h.html#abbbca05f6971b4bc2d83d4e5bd79854c',1,'ir_Gree.h']]], + ['kgreetempoffset_5381',['kGreeTempOffset',['../ir__Gree_8h.html#a838def81d0f1253e7371fa237f5f0a34',1,'ir_Gree.h']]], + ['kgreetempsize_5382',['kGreeTempSize',['../ir__Gree_8h.html#a15e8555687b1e6bfc47cd4ee4079b700',1,'ir_Gree.h']]], + ['kgreetimerenabledoffset_5383',['kGreeTimerEnabledOffset',['../ir__Gree_8h.html#aec18110852ca714f58734749ef8d4e7d',1,'ir_Gree.h']]], + ['kgreetimerhalfhroffset_5384',['kGreeTimerHalfHrOffset',['../ir__Gree_8h.html#af0779698759e0b6b41bd1f0b77fbddea',1,'ir_Gree.h']]], + ['kgreetimerhoursoffset_5385',['kGreeTimerHoursOffset',['../ir__Gree_8h.html#a1aeba4b3c5bff86b541291ea29220a60',1,'ir_Gree.h']]], + ['kgreetimerhourssize_5386',['kGreeTimerHoursSize',['../ir__Gree_8h.html#af08673b8c795a0c9a710825ceacd6bdb',1,'ir_Gree.h']]], + ['kgreetimermax_5387',['kGreeTimerMax',['../ir__Gree_8h.html#a76048e03908dd0d22cc8cacfbd99a40b',1,'ir_Gree.h']]], + ['kgreetimertenshroffset_5388',['kGreeTimerTensHrOffset',['../ir__Gree_8h.html#a5ca305d48fde5b5c6792c7734b31b941',1,'ir_Gree.h']]], + ['kgreetimertenshrsize_5389',['kGreeTimerTensHrSize',['../ir__Gree_8h.html#a5d8b007e38dcec0327ed0e38705f05c0',1,'ir_Gree.h']]], + ['kgreeturbooffset_5390',['kGreeTurboOffset',['../ir__Gree_8h.html#a5fe9afa8e66edd95a94404abe00dd1f1',1,'ir_Gree.h']]], + ['kgreeusefahrenheitoffset_5391',['kGreeUseFahrenheitOffset',['../ir__Gree_8h.html#a741c43d31a99fd8b723315d9db0724cc',1,'ir_Gree.h']]], + ['kgreewifioffset_5392',['kGreeWiFiOffset',['../ir__Gree_8h.html#a993dede6398a2c4ec2c1e025f4746768',1,'ir_Gree.h']]], + ['kgreexfanoffset_5393',['kGreeXfanOffset',['../ir__Gree_8h.html#a2388c44b2826823349d02dec581da584',1,'ir_Gree.h']]], + ['kgreezerospace_5394',['kGreeZeroSpace',['../ir__Gree_8cpp.html#aa4694ba8ff0e14cd6b9c4730675c385f',1,'ir_Gree.cpp']]], + ['khaieracauto_5395',['kHaierAcAuto',['../ir__Haier_8h.html#ac33a02f63ee77e0d3050598511730865',1,'ir_Haier.h']]], + ['khaieracbitmark_5396',['kHaierAcBitMark',['../ir__Haier_8cpp.html#a4dec38325834c873c03588a8046f0963',1,'ir_Haier.cpp']]], + ['khaieracbits_5397',['kHaierACBits',['../IRremoteESP8266_8h.html#ad44cfa0951c24d1f0c67b2fba997f720',1,'IRremoteESP8266.h']]], + ['khaieraccmdfan_5398',['kHaierAcCmdFan',['../ir__Haier_8h.html#a447818ec7970e2ca09540afe44ecf90d',1,'ir_Haier.h']]], + ['khaieraccmdhealth_5399',['kHaierAcCmdHealth',['../ir__Haier_8h.html#a83cd0b5f307d9ae3ed0a3c6ed8fef94d',1,'ir_Haier.h']]], + ['khaieraccmdmode_5400',['kHaierAcCmdMode',['../ir__Haier_8h.html#a4543aa4ee28323bb9cb5c077f9bf9da1',1,'ir_Haier.h']]], + ['khaieraccmdoff_5401',['kHaierAcCmdOff',['../ir__Haier_8h.html#a96599917176ee244874926d1a530dd7e',1,'ir_Haier.h']]], + ['khaieraccmdon_5402',['kHaierAcCmdOn',['../ir__Haier_8h.html#a83973c2ad2b7b95611c81628c387e0d8',1,'ir_Haier.h']]], + ['khaieraccmdsleep_5403',['kHaierAcCmdSleep',['../ir__Haier_8h.html#abe52b62dd513395f2a8c7d47fa2fc514',1,'ir_Haier.h']]], + ['khaieraccmdswing_5404',['kHaierAcCmdSwing',['../ir__Haier_8h.html#afab164c2aabf39fdc1e956ff88af19d9',1,'ir_Haier.h']]], + ['khaieraccmdtempdown_5405',['kHaierAcCmdTempDown',['../ir__Haier_8h.html#aecc31139b4e45a7784669554c6fdbb54',1,'ir_Haier.h']]], + ['khaieraccmdtempup_5406',['kHaierAcCmdTempUp',['../ir__Haier_8h.html#aab5363f07920971c31d6acf8e70d392c',1,'ir_Haier.h']]], + ['khaieraccmdtimercancel_5407',['kHaierAcCmdTimerCancel',['../ir__Haier_8h.html#ab780da80fc471f004c5b34dc8f347d00',1,'ir_Haier.h']]], + ['khaieraccmdtimerset_5408',['kHaierAcCmdTimerSet',['../ir__Haier_8h.html#a9bd7c081d460a4ae5e3eac977f3916e4',1,'ir_Haier.h']]], + ['khaieraccool_5409',['kHaierAcCool',['../ir__Haier_8h.html#a83cd81ea1115f42a403ea5ee07a32bbb',1,'ir_Haier.h']]], + ['khaieracdefaultrepeat_5410',['kHaierAcDefaultRepeat',['../IRremoteESP8266_8h.html#a882914932449e33933b6f8e224cbaf3c',1,'IRremoteESP8266.h']]], + ['khaieracdeftemp_5411',['kHaierAcDefTemp',['../ir__Haier_8h.html#a86c9e8176fc01e52e883cadcc1d31763',1,'ir_Haier.h']]], + ['khaieracdry_5412',['kHaierAcDry',['../ir__Haier_8h.html#a3d36fbe1308221248f45044e5a671636',1,'ir_Haier.h']]], + ['khaieracfan_5413',['kHaierAcFan',['../ir__Haier_8h.html#af4049629b2139ca82471dfed1e1ced15',1,'ir_Haier.h']]], + ['khaieracfanauto_5414',['kHaierAcFanAuto',['../ir__Haier_8h.html#a8a34e74f7083caa98ed4afc31294539e',1,'ir_Haier.h']]], + ['khaieracfanhigh_5415',['kHaierAcFanHigh',['../ir__Haier_8h.html#aa4d9e45ca5777707778ef78a3284da19',1,'ir_Haier.h']]], + ['khaieracfanlow_5416',['kHaierAcFanLow',['../ir__Haier_8h.html#ae31e878b09284a6730a11e2017cfd7a8',1,'ir_Haier.h']]], + ['khaieracfanmed_5417',['kHaierAcFanMed',['../ir__Haier_8h.html#a5dfa833768e549964aa0bf8a336c32b0',1,'ir_Haier.h']]], + ['khaierachdr_5418',['kHaierAcHdr',['../ir__Haier_8cpp.html#a0f5dbd2eb92f10bc354e6b0a7a074084',1,'ir_Haier.cpp']]], + ['khaierachdrgap_5419',['kHaierAcHdrGap',['../ir__Haier_8cpp.html#a4c3fe62f8e5abf5d084009bbd4c4f878',1,'ir_Haier.cpp']]], + ['khaierachealthbitoffset_5420',['kHaierAcHealthBitOffset',['../ir__Haier_8h.html#ae2e5e80f891c9bbca2844d808b0b3d1b',1,'ir_Haier.h']]], + ['khaieracheat_5421',['kHaierAcHeat',['../ir__Haier_8h.html#a0edb011bdf85197e63a32d37f8517dd2',1,'ir_Haier.h']]], + ['khaierachourssize_5422',['kHaierAcHoursSize',['../ir__Haier_8h.html#a3db7b7dddae84a5d12101c5cdd06975e',1,'ir_Haier.h']]], + ['khaieracmaxtemp_5423',['kHaierAcMaxTemp',['../ir__Haier_8h.html#a925252489fe34d9932151817d0dbe90b',1,'ir_Haier.h']]], + ['khaieracmaxtime_5424',['kHaierAcMaxTime',['../ir__Haier_8h.html#ae04e48e926a7533c3b62f0ff991e1f88',1,'ir_Haier.h']]], + ['khaieracmingap_5425',['kHaierAcMinGap',['../ir__Haier_8cpp.html#a7ab1f44876a931da765b52e4633e5e82',1,'ir_Haier.cpp']]], + ['khaieracminssize_5426',['kHaierAcMinsSize',['../ir__Haier_8h.html#a105e047084515305e896d8ff776d05e6',1,'ir_Haier.h']]], + ['khaieracmintemp_5427',['kHaierAcMinTemp',['../ir__Haier_8h.html#aafd2a4f38ecf78482a5a94e9c6c23f1c',1,'ir_Haier.h']]], + ['khaieracmodeoffset_5428',['kHaierAcModeOffset',['../ir__Haier_8h.html#a93fdbb1742923cf3f738c8078d5660f8',1,'ir_Haier.h']]], + ['khaieracofftimeroffset_5429',['kHaierAcOffTimerOffset',['../ir__Haier_8h.html#ace8cd6ed41c3f247ada91052d653b515',1,'ir_Haier.h']]], + ['khaieraconespace_5430',['kHaierAcOneSpace',['../ir__Haier_8cpp.html#a43739aa786e08fca2a4a62a680b5c38b',1,'ir_Haier.cpp']]], + ['khaieracontimeroffset_5431',['kHaierAcOnTimerOffset',['../ir__Haier_8h.html#a5189092c278fb5c31efd4f539f905da5',1,'ir_Haier.h']]], + ['khaieracprefix_5432',['kHaierAcPrefix',['../ir__Haier_8h.html#a8502c9bea40205e01e6a01b47354272a',1,'ir_Haier.h']]], + ['khaieracsleepbit_5433',['kHaierAcSleepBit',['../ir__Haier_8h.html#ac63b91acdffa55d440b08aee05bda5dc',1,'ir_Haier.h']]], + ['khaieracsleepbitoffset_5434',['kHaierAcSleepBitOffset',['../ir__Haier_8h.html#ad9f4cbfd8e6a5874d661195858156eec',1,'ir_Haier.h']]], + ['khaieracstatelength_5435',['kHaierACStateLength',['../IRremoteESP8266_8h.html#afb4cd0c1a9c689d862e7095f0ab6dbe5',1,'IRremoteESP8266.h']]], + ['khaieracswingchg_5436',['kHaierAcSwingChg',['../ir__Haier_8h.html#af65a92a0b9d29a52ac882d4457e954e8',1,'ir_Haier.h']]], + ['khaieracswingdown_5437',['kHaierAcSwingDown',['../ir__Haier_8h.html#a2cf3a2102c6d4f9aede44efe853ffaa8',1,'ir_Haier.h']]], + ['khaieracswingoff_5438',['kHaierAcSwingOff',['../ir__Haier_8h.html#ac21f78c3cef931154b3fc953bbebc3b4',1,'ir_Haier.h']]], + ['khaieracswingoffset_5439',['kHaierAcSwingOffset',['../ir__Haier_8h.html#a0872af0b2b3f22f6681917b9c81c3bbd',1,'ir_Haier.h']]], + ['khaieracswingsize_5440',['kHaierAcSwingSize',['../ir__Haier_8h.html#ad032725404a02c0e5a93350f20daf6e1',1,'ir_Haier.h']]], + ['khaieracswingup_5441',['kHaierAcSwingUp',['../ir__Haier_8h.html#a4bff8829604ee927dda5cfc54bd6cfe6',1,'ir_Haier.h']]], + ['khaieractimeoffset_5442',['kHaierAcTimeOffset',['../ir__Haier_8h.html#abb7a8ec83d3c0dbbe4d660d6bf627f23',1,'ir_Haier.h']]], + ['khaieracyrw02auto_5443',['kHaierAcYrw02Auto',['../ir__Haier_8h.html#aa025eeba1c344c50cc98334c97a3c174',1,'ir_Haier.h']]], + ['khaieracyrw02bits_5444',['kHaierACYRW02Bits',['../IRremoteESP8266_8h.html#aab346c5ad482113978e5a2cbb7a06f27',1,'IRremoteESP8266.h']]], + ['khaieracyrw02buttonfan_5445',['kHaierAcYrw02ButtonFan',['../ir__Haier_8h.html#a0f9c265510e1e27f38817f08ef9c622b',1,'ir_Haier.h']]], + ['khaieracyrw02buttonhealth_5446',['kHaierAcYrw02ButtonHealth',['../ir__Haier_8h.html#ab1dc6c0a4ed59446bb69c4dd671c78cd',1,'ir_Haier.h']]], + ['khaieracyrw02buttonmode_5447',['kHaierAcYrw02ButtonMode',['../ir__Haier_8h.html#a74466c50b450b08407c9f226a5d657e5',1,'ir_Haier.h']]], + ['khaieracyrw02buttonpower_5448',['kHaierAcYrw02ButtonPower',['../ir__Haier_8h.html#af36b9c628a697f6c596052ecd143d80b',1,'ir_Haier.h']]], + ['khaieracyrw02buttonsleep_5449',['kHaierAcYrw02ButtonSleep',['../ir__Haier_8h.html#a5c7b8ff351e3d0167ec2c897c4820c40',1,'ir_Haier.h']]], + ['khaieracyrw02buttonswing_5450',['kHaierAcYrw02ButtonSwing',['../ir__Haier_8h.html#aa10c558317448783535e96be5876505c',1,'ir_Haier.h']]], + ['khaieracyrw02buttontempdown_5451',['kHaierAcYrw02ButtonTempDown',['../ir__Haier_8h.html#af4a9e5f7f705c331531ea2863dbbd11d',1,'ir_Haier.h']]], + ['khaieracyrw02buttontempup_5452',['kHaierAcYrw02ButtonTempUp',['../ir__Haier_8h.html#a3b24373f9c812f93eca05ee47e61d6e0',1,'ir_Haier.h']]], + ['khaieracyrw02buttonturbo_5453',['kHaierAcYrw02ButtonTurbo',['../ir__Haier_8h.html#ad80547c526b2eba142297715c0a0636d',1,'ir_Haier.h']]], + ['khaieracyrw02cool_5454',['kHaierAcYrw02Cool',['../ir__Haier_8h.html#a30c5d4e61ae3112a8a3e3622eecbb10b',1,'ir_Haier.h']]], + ['khaieracyrw02defaultrepeat_5455',['kHaierAcYrw02DefaultRepeat',['../IRremoteESP8266_8h.html#a62412e221207dbc2660f93dc265b4218',1,'IRremoteESP8266.h']]], + ['khaieracyrw02dry_5456',['kHaierAcYrw02Dry',['../ir__Haier_8h.html#a66cd902f2d35b4c8f66f085a0950a5fc',1,'ir_Haier.h']]], + ['khaieracyrw02fan_5457',['kHaierAcYrw02Fan',['../ir__Haier_8h.html#a35f50f043a2dda75c59507c1ed845b5d',1,'ir_Haier.h']]], + ['khaieracyrw02fanauto_5458',['kHaierAcYrw02FanAuto',['../ir__Haier_8h.html#ad554d38035ac15e4ea8b855802886989',1,'ir_Haier.h']]], + ['khaieracyrw02fanhigh_5459',['kHaierAcYrw02FanHigh',['../ir__Haier_8h.html#ab47bc48ac77fbf6734a41d10f0a53e4a',1,'ir_Haier.h']]], + ['khaieracyrw02fanlow_5460',['kHaierAcYrw02FanLow',['../ir__Haier_8h.html#a9a0a14ab98e1e52b60b9b9bf611c20cc',1,'ir_Haier.h']]], + ['khaieracyrw02fanmed_5461',['kHaierAcYrw02FanMed',['../ir__Haier_8h.html#a65583649324c6039112e7db26d685afc',1,'ir_Haier.h']]], + ['khaieracyrw02fanoffset_5462',['kHaierAcYrw02FanOffset',['../ir__Haier_8h.html#a0910d1996a451c98383124a39ef65f84',1,'ir_Haier.h']]], + ['khaieracyrw02fansize_5463',['kHaierAcYrw02FanSize',['../ir__Haier_8h.html#aa2c6bd47b47e0ea1b51931fec7daef4d',1,'ir_Haier.h']]], + ['khaieracyrw02healthoffset_5464',['kHaierAcYrw02HealthOffset',['../ir__Haier_8h.html#a4bcb42b359472cf770e0710b5369493b',1,'ir_Haier.h']]], + ['khaieracyrw02heat_5465',['kHaierAcYrw02Heat',['../ir__Haier_8h.html#aa0873975b6649294a3c9943130cb7a38',1,'ir_Haier.h']]], + ['khaieracyrw02modeoffset_5466',['kHaierAcYrw02ModeOffset',['../ir__Haier_8h.html#a027199b609d29ead8aec9bb89178cb30',1,'ir_Haier.h']]], + ['khaieracyrw02power_5467',['kHaierAcYrw02Power',['../ir__Haier_8h.html#abe59df7abf20a66107516054f3a2d32b',1,'ir_Haier.h']]], + ['khaieracyrw02poweroffset_5468',['kHaierAcYrw02PowerOffset',['../ir__Haier_8h.html#a67401152b0aa06fb7922bbca743cd600',1,'ir_Haier.h']]], + ['khaieracyrw02prefix_5469',['kHaierAcYrw02Prefix',['../ir__Haier_8h.html#ac62d0f7ca94e064712f8a7a80da2f11e',1,'ir_Haier.h']]], + ['khaieracyrw02sleep_5470',['kHaierAcYrw02Sleep',['../ir__Haier_8h.html#abb70fe8ca6004246345df3d841047252',1,'ir_Haier.h']]], + ['khaieracyrw02sleepoffset_5471',['kHaierAcYrw02SleepOffset',['../ir__Haier_8h.html#ac651bfee5d261124700c81ec5db184a7',1,'ir_Haier.h']]], + ['khaieracyrw02statelength_5472',['kHaierACYRW02StateLength',['../IRremoteESP8266_8h.html#a8f52b7d4595c117cf0b81ffbd1148cda',1,'IRremoteESP8266.h']]], + ['khaieracyrw02swingauto_5473',['kHaierAcYrw02SwingAuto',['../ir__Haier_8h.html#a95ae88223d910d4d966949241bccff8d',1,'ir_Haier.h']]], + ['khaieracyrw02swingbottom_5474',['kHaierAcYrw02SwingBottom',['../ir__Haier_8h.html#aa4b64385da5e9b2a89e15f70cd8c89e9',1,'ir_Haier.h']]], + ['khaieracyrw02swingdown_5475',['kHaierAcYrw02SwingDown',['../ir__Haier_8h.html#aab380411ac07b2b7f67956a5bbc362fb',1,'ir_Haier.h']]], + ['khaieracyrw02swingmiddle_5476',['kHaierAcYrw02SwingMiddle',['../ir__Haier_8h.html#a32d6dd98a050711bf928bf250b769839',1,'ir_Haier.h']]], + ['khaieracyrw02swingoff_5477',['kHaierAcYrw02SwingOff',['../ir__Haier_8h.html#a62570c15418cf24a94c92b162967f892',1,'ir_Haier.h']]], + ['khaieracyrw02swingtop_5478',['kHaierAcYrw02SwingTop',['../ir__Haier_8h.html#adf10f1bc1b293c684232cb6398631f70',1,'ir_Haier.h']]], + ['khaieracyrw02turbohigh_5479',['kHaierAcYrw02TurboHigh',['../ir__Haier_8h.html#ab096c15c69f242b99fbc1e4d7bd7548e',1,'ir_Haier.h']]], + ['khaieracyrw02turbolow_5480',['kHaierAcYrw02TurboLow',['../ir__Haier_8h.html#a19b7f4aee8115eb77267c415d8b3bd82',1,'ir_Haier.h']]], + ['khaieracyrw02turbooff_5481',['kHaierAcYrw02TurboOff',['../ir__Haier_8h.html#aa06ba46287b5806a6373e921cee34a51',1,'ir_Haier.h']]], + ['khaieracyrw02turbooffset_5482',['kHaierAcYrw02TurboOffset',['../ir__Haier_8h.html#a6581fc8ec43b9ac9f877bf27231554bd',1,'ir_Haier.h']]], + ['khaieracyrw02turbosize_5483',['kHaierAcYrw02TurboSize',['../ir__Haier_8h.html#a6ad469ec094d8af5a68cc94a744079bb',1,'ir_Haier.h']]], + ['khaieraczerospace_5484',['kHaierAcZeroSpace',['../ir__Haier_8cpp.html#af2b1a4f27c7b50a1e60ae00bbbec7a16',1,'ir_Haier.cpp']]], + ['kheader_5485',['kHeader',['../IRrecv_8h.html#a0eac186845b9b998a252a3bdfa72e8ed',1,'IRrecv.h']]], + ['khealthstr_5486',['kHealthStr',['../IRtext_8cpp.html#a12474bbd4a7f700c922bcc1de240894f',1,'kHealthStr(): IRtext.cpp'],['../IRtext_8h.html#a7ef833cf90df2c97ef46c5c4b6225a42',1,'kHealthStr(): IRtext.cpp']]], + ['kheatstr_5487',['kHeatStr',['../IRtext_8cpp.html#a3a16f1dabca01c8f8e5ba1516408ba39',1,'kHeatStr(): IRtext.cpp'],['../IRtext_8h.html#a058df7d2db245e307719d025352d464d',1,'kHeatStr(): IRtext.cpp']]], + ['khigheststr_5488',['kHighestStr',['../IRtext_8cpp.html#a219f1d54c5ea75bd5c736efc0d7d7275',1,'kHighestStr(): IRtext.cpp'],['../IRtext_8h.html#ad7706307f507466526b4288e33385bde',1,'kHighestStr(): IRtext.cpp']]], + ['khighnibble_5489',['kHighNibble',['../IRutils_8h.html#a26dd96e82207f707c21e696a60b9c032',1,'IRutils.h']]], + ['khighstr_5490',['kHighStr',['../IRtext_8cpp.html#a127a20ad54e671f48a8faa822ff006f4',1,'kHighStr(): IRtext.cpp'],['../IRtext_8h.html#a5b4ade5e08f30c5e9a61c813bb2046f1',1,'kHighStr(): IRtext.cpp']]], + ['khistr_5491',['kHiStr',['../IRtext_8cpp.html#a7f4994ce51aed70ce6b5b4c88b886466',1,'kHiStr(): IRtext.cpp'],['../IRtext_8h.html#aa6fe661cdd9e2f1dc30d6fee2980cadd',1,'kHiStr(): IRtext.cpp']]], + ['khitachiac1auto_5492',['kHitachiAc1Auto',['../ir__Hitachi_8h.html#a2689ef34702107dc3dce3d1cfa260fc9',1,'ir_Hitachi.h']]], + ['khitachiac1bits_5493',['kHitachiAc1Bits',['../IRremoteESP8266_8h.html#aae6947c431d2c9da4fe2fdd9428012c1',1,'IRremoteESP8266.h']]], + ['khitachiac1checksumstartbyte_5494',['kHitachiAc1ChecksumStartByte',['../ir__Hitachi_8h.html#afafa689c5e922b812f63e08941feb2a7',1,'ir_Hitachi.h']]], + ['khitachiac1cool_5495',['kHitachiAc1Cool',['../ir__Hitachi_8h.html#a1146eda7688843d16094acf7a19a75ac',1,'ir_Hitachi.h']]], + ['khitachiac1dry_5496',['kHitachiAc1Dry',['../ir__Hitachi_8h.html#a82895db5201610844da803bf333102a3',1,'ir_Hitachi.h']]], + ['khitachiac1fan_5497',['kHitachiAc1Fan',['../ir__Hitachi_8h.html#ac5a3ba0e0e4ed02d4792d5a8e6a22654',1,'ir_Hitachi.h']]], + ['khitachiac1fanauto_5498',['kHitachiAc1FanAuto',['../ir__Hitachi_8h.html#a6f9adda7b08ec4b8566ceb4d79966689',1,'ir_Hitachi.h']]], + ['khitachiac1fanbyte_5499',['kHitachiAc1FanByte',['../ir__Hitachi_8h.html#afe6b5951ba3b4e7ad5400f30228d106e',1,'ir_Hitachi.h']]], + ['khitachiac1fanhigh_5500',['kHitachiAc1FanHigh',['../ir__Hitachi_8h.html#ace677cf030da9d74eda0f50d54c91411',1,'ir_Hitachi.h']]], + ['khitachiac1fanlow_5501',['kHitachiAc1FanLow',['../ir__Hitachi_8h.html#a011219de5c0e2ba043a8be6345f8cb05',1,'ir_Hitachi.h']]], + ['khitachiac1fanmed_5502',['kHitachiAc1FanMed',['../ir__Hitachi_8h.html#afbc2a535d85adb80cbcbac63e2432b1a',1,'ir_Hitachi.h']]], + ['khitachiac1fanoffset_5503',['kHitachiAc1FanOffset',['../ir__Hitachi_8h.html#af533c283666d80c0b9348f706909f4c4',1,'ir_Hitachi.h']]], + ['khitachiac1fansize_5504',['kHitachiAc1FanSize',['../ir__Hitachi_8h.html#a2b2a24680efaf1eeaf76dacaabef5c1d',1,'ir_Hitachi.h']]], + ['khitachiac1hdrmark_5505',['kHitachiAc1HdrMark',['../ir__Hitachi_8cpp.html#a2b1891174c78be6f960e92b389d25fe7',1,'ir_Hitachi.cpp']]], + ['khitachiac1hdrspace_5506',['kHitachiAc1HdrSpace',['../ir__Hitachi_8cpp.html#a93f34ee53a375dd7f4ccf82458453701',1,'ir_Hitachi.cpp']]], + ['khitachiac1heat_5507',['kHitachiAc1Heat',['../ir__Hitachi_8h.html#abd5d4db30d6be3b990a74d4481e7eabe',1,'ir_Hitachi.h']]], + ['khitachiac1modebyte_5508',['kHitachiAc1ModeByte',['../ir__Hitachi_8h.html#a57e27b66ff6d471c0dd335b610bc6e24',1,'ir_Hitachi.h']]], + ['khitachiac1model_5fa_5509',['kHitachiAc1Model_A',['../ir__Hitachi_8h.html#a5f8fc3bb000d46705e4530ca0a8f7b60',1,'ir_Hitachi.h']]], + ['khitachiac1model_5fb_5510',['kHitachiAc1Model_B',['../ir__Hitachi_8h.html#a2d894a528c538b8a3922e2500241a55b',1,'ir_Hitachi.h']]], + ['khitachiac1modelbyte_5511',['kHitachiAc1ModelByte',['../ir__Hitachi_8h.html#a2e2a76b8b7decef99cfb7b197e8fb7f7',1,'ir_Hitachi.h']]], + ['khitachiac1modeloffset_5512',['kHitachiAc1ModelOffset',['../ir__Hitachi_8h.html#a8a440a64e6e164511e0976dc5b6585ff',1,'ir_Hitachi.h']]], + ['khitachiac1modelsize_5513',['kHitachiAc1ModelSize',['../ir__Hitachi_8h.html#ab74bbcb475b7eaf33f70dbfdb853d8c3',1,'ir_Hitachi.h']]], + ['khitachiac1modeoffset_5514',['kHitachiAc1ModeOffset',['../ir__Hitachi_8h.html#a3f010fa5ae43ee36771be18659d8bc80',1,'ir_Hitachi.h']]], + ['khitachiac1modesize_5515',['kHitachiAc1ModeSize',['../ir__Hitachi_8h.html#a38b456d96602e83e7832e2a7af75f321',1,'ir_Hitachi.h']]], + ['khitachiac1offtimerhighbyte_5516',['kHitachiAc1OffTimerHighByte',['../ir__Hitachi_8h.html#a36e6b7fc328ee247c11f5779487119b6',1,'ir_Hitachi.h']]], + ['khitachiac1offtimerlowbyte_5517',['kHitachiAc1OffTimerLowByte',['../ir__Hitachi_8h.html#ac8eaedd191009b2ddaf1e047ac6ecf11',1,'ir_Hitachi.h']]], + ['khitachiac1ontimerhighbyte_5518',['kHitachiAc1OnTimerHighByte',['../ir__Hitachi_8h.html#aff6907e9999561abceac42e4cce1dc3b',1,'ir_Hitachi.h']]], + ['khitachiac1ontimerlowbyte_5519',['kHitachiAc1OnTimerLowByte',['../ir__Hitachi_8h.html#a95fef3be6809026b714847c709ba655b',1,'ir_Hitachi.h']]], + ['khitachiac1powerbyte_5520',['kHitachiAc1PowerByte',['../ir__Hitachi_8h.html#acda489ff6137ab3ebfb1795a32e1ec8e',1,'ir_Hitachi.h']]], + ['khitachiac1poweroffset_5521',['kHitachiAc1PowerOffset',['../ir__Hitachi_8h.html#a3fdcd0375b85ac2641d9d5cc6e4770f8',1,'ir_Hitachi.h']]], + ['khitachiac1powertoggleoffset_5522',['kHitachiAc1PowerToggleOffset',['../ir__Hitachi_8h.html#aac994777ce070ad69550229824800ee0',1,'ir_Hitachi.h']]], + ['khitachiac1sleep1_5523',['kHitachiAc1Sleep1',['../ir__Hitachi_8h.html#ab4ca89a9d8c8034e6a3d8ff17b09f3d5',1,'ir_Hitachi.h']]], + ['khitachiac1sleep2_5524',['kHitachiAc1Sleep2',['../ir__Hitachi_8h.html#a1e1a1ea1743b38da6bc6be63fa796689',1,'ir_Hitachi.h']]], + ['khitachiac1sleep3_5525',['kHitachiAc1Sleep3',['../ir__Hitachi_8h.html#a17eaa63f13a3c04aede9f485c310a930',1,'ir_Hitachi.h']]], + ['khitachiac1sleep4_5526',['kHitachiAc1Sleep4',['../ir__Hitachi_8h.html#a21360448a538fbd9491aa9dd28e6c545',1,'ir_Hitachi.h']]], + ['khitachiac1sleepbyte_5527',['kHitachiAc1SleepByte',['../ir__Hitachi_8h.html#ac693a15878e7cdc8e1f575502ea82843',1,'ir_Hitachi.h']]], + ['khitachiac1sleepoff_5528',['kHitachiAc1SleepOff',['../ir__Hitachi_8h.html#a96f87cb3838a1e1aab4b8407dcfc5b78',1,'ir_Hitachi.h']]], + ['khitachiac1sleepoffset_5529',['kHitachiAc1SleepOffset',['../ir__Hitachi_8h.html#a277ca55dbfd35258ea40059bdff62488',1,'ir_Hitachi.h']]], + ['khitachiac1sleepsize_5530',['kHitachiAc1SleepSize',['../ir__Hitachi_8h.html#a199cedd7120057f735ffc640f93a9a1a',1,'ir_Hitachi.h']]], + ['khitachiac1statelength_5531',['kHitachiAc1StateLength',['../IRremoteESP8266_8h.html#abb5e2ddb1a8d3c6fa7a94dbe1989ec5d',1,'IRremoteESP8266.h']]], + ['khitachiac1swingbyte_5532',['kHitachiAc1SwingByte',['../ir__Hitachi_8h.html#a5a283583007b26c1b45d8d7afcd55408',1,'ir_Hitachi.h']]], + ['khitachiac1swinghoffset_5533',['kHitachiAc1SwingHOffset',['../ir__Hitachi_8h.html#ab35d4bb6c17fc5bbcb5385a642476238',1,'ir_Hitachi.h']]], + ['khitachiac1swingtoggleoffset_5534',['kHitachiAc1SwingToggleOffset',['../ir__Hitachi_8h.html#a08eac3b64687e83229648c8664d75dc4',1,'ir_Hitachi.h']]], + ['khitachiac1swingvoffset_5535',['kHitachiAc1SwingVOffset',['../ir__Hitachi_8h.html#af4e410f10812d49175cd419ed678535b',1,'ir_Hitachi.h']]], + ['khitachiac1tempauto_5536',['kHitachiAc1TempAuto',['../ir__Hitachi_8h.html#ad402dff999a97b50b392572899522b6a',1,'ir_Hitachi.h']]], + ['khitachiac1tempbyte_5537',['kHitachiAc1TempByte',['../ir__Hitachi_8h.html#a03185c3b2ddb62d12267da014796da56',1,'ir_Hitachi.h']]], + ['khitachiac1tempdelta_5538',['kHitachiAc1TempDelta',['../ir__Hitachi_8h.html#a279c856a2b4d25651b117a8c654cb48d',1,'ir_Hitachi.h']]], + ['khitachiac1tempoffset_5539',['kHitachiAc1TempOffset',['../ir__Hitachi_8h.html#a8a92aa41be23301229ecec1486714b9a',1,'ir_Hitachi.h']]], + ['khitachiac1tempsize_5540',['kHitachiAc1TempSize',['../ir__Hitachi_8h.html#affb52642edc8f2231f0dc83bc5271885',1,'ir_Hitachi.h']]], + ['khitachiac1timersize_5541',['kHitachiAc1TimerSize',['../ir__Hitachi_8h.html#afd7f469f67f55263b0031b325232751b',1,'ir_Hitachi.h']]], + ['khitachiac2bits_5542',['kHitachiAc2Bits',['../IRremoteESP8266_8h.html#a362a0b0b0afc216cf8162a3724cf073a',1,'IRremoteESP8266.h']]], + ['khitachiac2statelength_5543',['kHitachiAc2StateLength',['../IRremoteESP8266_8h.html#a10377a40053a12e091dbff2869db0352',1,'IRremoteESP8266.h']]], + ['khitachiac344bits_5544',['kHitachiAc344Bits',['../IRremoteESP8266_8h.html#a204fc2410c3d555a37b152a01dceead0',1,'IRremoteESP8266.h']]], + ['khitachiac344buttonfan_5545',['kHitachiAc344ButtonFan',['../ir__Hitachi_8h.html#a5f33b956ec83ee0004785a9c44bd5b0b',1,'ir_Hitachi.h']]], + ['khitachiac344buttonpowermode_5546',['kHitachiAc344ButtonPowerMode',['../ir__Hitachi_8h.html#a3816a8ad86e03f8c5870057e7ad86335',1,'ir_Hitachi.h']]], + ['khitachiac344buttonswingh_5547',['kHitachiAc344ButtonSwingH',['../ir__Hitachi_8h.html#a10dea534868d76d99e91458ee28f5fe9',1,'ir_Hitachi.h']]], + ['khitachiac344buttonswingv_5548',['kHitachiAc344ButtonSwingV',['../ir__Hitachi_8h.html#a95c1b0ee7e3802631f4c2708371e7d34',1,'ir_Hitachi.h']]], + ['khitachiac344buttontempdown_5549',['kHitachiAc344ButtonTempDown',['../ir__Hitachi_8h.html#a05d9bd95037669f1d3743d935471db33',1,'ir_Hitachi.h']]], + ['khitachiac344buttontempup_5550',['kHitachiAc344ButtonTempUp',['../ir__Hitachi_8h.html#a74abf2ce4ed5918bf68f485eff179578',1,'ir_Hitachi.h']]], + ['khitachiac344cool_5551',['kHitachiAc344Cool',['../ir__Hitachi_8h.html#a92d4d8dea34a9387e55852b6b5289328',1,'ir_Hitachi.h']]], + ['khitachiac344dry_5552',['kHitachiAc344Dry',['../ir__Hitachi_8h.html#a37697339ddc2ffaf4ee13b5e140adf2c',1,'ir_Hitachi.h']]], + ['khitachiac344fan_5553',['kHitachiAc344Fan',['../ir__Hitachi_8h.html#a296cd0fc1f414a4e15ce228b5a794bcb',1,'ir_Hitachi.h']]], + ['khitachiac344fanauto_5554',['kHitachiAc344FanAuto',['../ir__Hitachi_8h.html#a6439744edb1ae4dd9e8ea2097fac7a9d',1,'ir_Hitachi.h']]], + ['khitachiac344fanhigh_5555',['kHitachiAc344FanHigh',['../ir__Hitachi_8h.html#a83ea1924948ce9ac8266ab64a41f3ebd',1,'ir_Hitachi.h']]], + ['khitachiac344fanlow_5556',['kHitachiAc344FanLow',['../ir__Hitachi_8h.html#acbbb61fde653c84a8e35865fa724872c',1,'ir_Hitachi.h']]], + ['khitachiac344fanmax_5557',['kHitachiAc344FanMax',['../ir__Hitachi_8h.html#af041ed41027b8e444e3069d9a3481c51',1,'ir_Hitachi.h']]], + ['khitachiac344fanmedium_5558',['kHitachiAc344FanMedium',['../ir__Hitachi_8h.html#aa6d47b5c28f758aa297b345cbf853c9a',1,'ir_Hitachi.h']]], + ['khitachiac344fanmin_5559',['kHitachiAc344FanMin',['../ir__Hitachi_8h.html#ac4bafed10c76739698e9a35183beb970',1,'ir_Hitachi.h']]], + ['khitachiac344heat_5560',['kHitachiAc344Heat',['../ir__Hitachi_8h.html#a6c4102910d21dc838efee1fb2477218d',1,'ir_Hitachi.h']]], + ['khitachiac344maxtemp_5561',['kHitachiAc344MaxTemp',['../ir__Hitachi_8h.html#a4a394fc23fb119ba67e3ca53e4b88f7f',1,'ir_Hitachi.h']]], + ['khitachiac344mintemp_5562',['kHitachiAc344MinTemp',['../ir__Hitachi_8h.html#a7322f7769c9c1af2311180474e5b0f57',1,'ir_Hitachi.h']]], + ['khitachiac344statelength_5563',['kHitachiAc344StateLength',['../IRremoteESP8266_8h.html#a2192f6b7c353f7f124dff3b57eab0659',1,'IRremoteESP8266.h']]], + ['khitachiac344swinghauto_5564',['kHitachiAc344SwingHAuto',['../ir__Hitachi_8h.html#a4f93eccee6e3e5f5c49c84034ca25af3',1,'ir_Hitachi.h']]], + ['khitachiac344swinghbyte_5565',['kHitachiAc344SwingHByte',['../ir__Hitachi_8h.html#a132b64e007043ade4f209b0416fd5f4d',1,'ir_Hitachi.h']]], + ['khitachiac344swinghleft_5566',['kHitachiAc344SwingHLeft',['../ir__Hitachi_8h.html#af714a1eb296b05f3fc8167aff5419764',1,'ir_Hitachi.h']]], + ['khitachiac344swinghleftmax_5567',['kHitachiAc344SwingHLeftMax',['../ir__Hitachi_8h.html#ad0c5636ac0ccfd7e9cd087101bd5d204',1,'ir_Hitachi.h']]], + ['khitachiac344swinghmiddle_5568',['kHitachiAc344SwingHMiddle',['../ir__Hitachi_8h.html#a7e4372e02d72723049b378e955070c21',1,'ir_Hitachi.h']]], + ['khitachiac344swinghoffset_5569',['kHitachiAc344SwingHOffset',['../ir__Hitachi_8h.html#a7e8e57b0b37f20a502eb66f13980989c',1,'ir_Hitachi.h']]], + ['khitachiac344swinghright_5570',['kHitachiAc344SwingHRight',['../ir__Hitachi_8h.html#af4b087dec06cfd86920dbf9df22aca63',1,'ir_Hitachi.h']]], + ['khitachiac344swinghrightmax_5571',['kHitachiAc344SwingHRightMax',['../ir__Hitachi_8h.html#a90cffc131be89a36d352c462403f689f',1,'ir_Hitachi.h']]], + ['khitachiac344swinghsize_5572',['kHitachiAc344SwingHSize',['../ir__Hitachi_8h.html#aadd389cd818207920c1e8efef53fde91',1,'ir_Hitachi.h']]], + ['khitachiac344swingvbyte_5573',['kHitachiAc344SwingVByte',['../ir__Hitachi_8h.html#ae40211be39e522ebf9b580b3481f49f3',1,'ir_Hitachi.h']]], + ['khitachiac344swingvoffset_5574',['kHitachiAc344SwingVOffset',['../ir__Hitachi_8h.html#a8b38ef096697f70bdba8f4bd2799e148',1,'ir_Hitachi.h']]], + ['khitachiac3bitmark_5575',['kHitachiAc3BitMark',['../ir__Hitachi_8cpp.html#a68269a88e02a3030749061e5f28f74cc',1,'ir_Hitachi.cpp']]], + ['khitachiac3bits_5576',['kHitachiAc3Bits',['../IRremoteESP8266_8h.html#ac26b896cdc17018269fa881e10e3aabb',1,'IRremoteESP8266.h']]], + ['khitachiac3hdrmark_5577',['kHitachiAc3HdrMark',['../ir__Hitachi_8cpp.html#af0a80a66094e67b4a78e8dfa539cd22f',1,'ir_Hitachi.cpp']]], + ['khitachiac3hdrspace_5578',['kHitachiAc3HdrSpace',['../ir__Hitachi_8cpp.html#aca4dc0b851c69a5e640337d68eb6f412',1,'ir_Hitachi.cpp']]], + ['khitachiac3minbits_5579',['kHitachiAc3MinBits',['../IRremoteESP8266_8h.html#a66ebaf70d2b4018371825c9cd3078a42',1,'IRremoteESP8266.h']]], + ['khitachiac3minstatelength_5580',['kHitachiAc3MinStateLength',['../IRremoteESP8266_8h.html#ac3becb270bfddaa1c64b1f8582dfc902',1,'IRremoteESP8266.h']]], + ['khitachiac3onespace_5581',['kHitachiAc3OneSpace',['../ir__Hitachi_8cpp.html#a0e630e38b4bffd5ec931153c20e41d97',1,'ir_Hitachi.cpp']]], + ['khitachiac3statelength_5582',['kHitachiAc3StateLength',['../IRremoteESP8266_8h.html#a9cc230bac4f902d46049c7b2c2fdbd3d',1,'IRremoteESP8266.h']]], + ['khitachiac3zerospace_5583',['kHitachiAc3ZeroSpace',['../ir__Hitachi_8cpp.html#a7cf96a2734bcc9a5eb390b8647666925',1,'ir_Hitachi.cpp']]], + ['khitachiac424bitmark_5584',['kHitachiAc424BitMark',['../ir__Hitachi_8cpp.html#acf5f9d83873a74688eb0413708e26eed',1,'ir_Hitachi.cpp']]], + ['khitachiac424bits_5585',['kHitachiAc424Bits',['../IRremoteESP8266_8h.html#ab466e28528a0d688a1b91e8af69025cb',1,'IRremoteESP8266.h']]], + ['khitachiac424buttonbyte_5586',['kHitachiAc424ButtonByte',['../ir__Hitachi_8h.html#a057159edca95f9a000c80c7059919e83',1,'ir_Hitachi.h']]], + ['khitachiac424buttonfan_5587',['kHitachiAc424ButtonFan',['../ir__Hitachi_8h.html#a4aa278fb1983213a2506c71debe035aa',1,'ir_Hitachi.h']]], + ['khitachiac424buttonpowermode_5588',['kHitachiAc424ButtonPowerMode',['../ir__Hitachi_8h.html#a2dd37a36c6ad928ad0c3485ae4ea78fd',1,'ir_Hitachi.h']]], + ['khitachiac424buttonswingh_5589',['kHitachiAc424ButtonSwingH',['../ir__Hitachi_8h.html#af3a0d9499fab327bc7dfb5d57562a946',1,'ir_Hitachi.h']]], + ['khitachiac424buttonswingv_5590',['kHitachiAc424ButtonSwingV',['../ir__Hitachi_8h.html#a59d8e5407daf37d38e0c76ab3abdec9d',1,'ir_Hitachi.h']]], + ['khitachiac424buttontempdown_5591',['kHitachiAc424ButtonTempDown',['../ir__Hitachi_8h.html#ad909ee0bc97e24aa70ff6ecd1cffe6c2',1,'ir_Hitachi.h']]], + ['khitachiac424buttontempup_5592',['kHitachiAc424ButtonTempUp',['../ir__Hitachi_8h.html#ac8885804fb276f6327beb2018b204359',1,'ir_Hitachi.h']]], + ['khitachiac424cool_5593',['kHitachiAc424Cool',['../ir__Hitachi_8h.html#a64c1e01c222e6dec001a7052e822d64f',1,'ir_Hitachi.h']]], + ['khitachiac424dry_5594',['kHitachiAc424Dry',['../ir__Hitachi_8h.html#a56bfde42914bc92f47929179cddcbdf3',1,'ir_Hitachi.h']]], + ['khitachiac424fan_5595',['kHitachiAc424Fan',['../ir__Hitachi_8h.html#a35db6fdcedeb3de0ffb0bb72f1e60a0b',1,'ir_Hitachi.h']]], + ['khitachiac424fanauto_5596',['kHitachiAc424FanAuto',['../ir__Hitachi_8h.html#add1ec95cfd4e388f90154b25410471d0',1,'ir_Hitachi.h']]], + ['khitachiac424fanbyte_5597',['kHitachiAc424FanByte',['../ir__Hitachi_8h.html#aa4758708fe16d13cf6f50b7aa9e12bf6',1,'ir_Hitachi.h']]], + ['khitachiac424fanhigh_5598',['kHitachiAc424FanHigh',['../ir__Hitachi_8h.html#aacabc41baea6c3ddf711424a400144a3',1,'ir_Hitachi.h']]], + ['khitachiac424fanlow_5599',['kHitachiAc424FanLow',['../ir__Hitachi_8h.html#acae66b060db5cd03732ccbf808c6049e',1,'ir_Hitachi.h']]], + ['khitachiac424fanmax_5600',['kHitachiAc424FanMax',['../ir__Hitachi_8h.html#a6298e6dee6ff9f5fc57cfc9ccf30c073',1,'ir_Hitachi.h']]], + ['khitachiac424fanmaxdry_5601',['kHitachiAc424FanMaxDry',['../ir__Hitachi_8h.html#af770b29d838610b87463551444548ac0',1,'ir_Hitachi.h']]], + ['khitachiac424fanmedium_5602',['kHitachiAc424FanMedium',['../ir__Hitachi_8h.html#a3d6479f2e76bd84eeda9f5c0772210c5',1,'ir_Hitachi.h']]], + ['khitachiac424fanmin_5603',['kHitachiAc424FanMin',['../ir__Hitachi_8h.html#aacf1d4b99d89a0e24622ca02402c683b',1,'ir_Hitachi.h']]], + ['khitachiac424fantemp_5604',['kHitachiAc424FanTemp',['../ir__Hitachi_8h.html#a874362698fad488da1a477c4f99923aa',1,'ir_Hitachi.h']]], + ['khitachiac424hdrmark_5605',['kHitachiAc424HdrMark',['../ir__Hitachi_8cpp.html#a7b1dcaa7569237831b08ea061fd403fb',1,'ir_Hitachi.cpp']]], + ['khitachiac424hdrspace_5606',['kHitachiAc424HdrSpace',['../ir__Hitachi_8cpp.html#a9309b801d147dd3eba96ed15245f7445',1,'ir_Hitachi.cpp']]], + ['khitachiac424heat_5607',['kHitachiAc424Heat',['../ir__Hitachi_8h.html#a5cfd38c9e7aa2c39dfa38b1ef4b33b4c',1,'ir_Hitachi.h']]], + ['khitachiac424ldrmark_5608',['kHitachiAc424LdrMark',['../ir__Hitachi_8cpp.html#a0e2a88cb5930fb9726a453bdefe33bae',1,'ir_Hitachi.cpp']]], + ['khitachiac424ldrspace_5609',['kHitachiAc424LdrSpace',['../ir__Hitachi_8cpp.html#ad6285b55ed74e0e1087c3eb12d63b39c',1,'ir_Hitachi.cpp']]], + ['khitachiac424maxtemp_5610',['kHitachiAc424MaxTemp',['../ir__Hitachi_8h.html#a22574044b5a9163aca1f0581b9fa9241',1,'ir_Hitachi.h']]], + ['khitachiac424mintemp_5611',['kHitachiAc424MinTemp',['../ir__Hitachi_8h.html#a3d4311f1f28bbe31a22b80556e678b22',1,'ir_Hitachi.h']]], + ['khitachiac424modebyte_5612',['kHitachiAc424ModeByte',['../ir__Hitachi_8h.html#a3c6e0d27a95d94142360efa19a342c99',1,'ir_Hitachi.h']]], + ['khitachiac424onespace_5613',['kHitachiAc424OneSpace',['../ir__Hitachi_8cpp.html#a9b9cd22801f17acac593a8bcf334fd71',1,'ir_Hitachi.cpp']]], + ['khitachiac424powerbyte_5614',['kHitachiAc424PowerByte',['../ir__Hitachi_8h.html#a815e6761376ca4eae649ec837d55dc25',1,'ir_Hitachi.h']]], + ['khitachiac424poweroff_5615',['kHitachiAc424PowerOff',['../ir__Hitachi_8h.html#affc2d076cc0de329466ecbde7186d4eb',1,'ir_Hitachi.h']]], + ['khitachiac424poweron_5616',['kHitachiAc424PowerOn',['../ir__Hitachi_8h.html#a922478904efd86c6ecf7dabec3dd759f',1,'ir_Hitachi.h']]], + ['khitachiac424statelength_5617',['kHitachiAc424StateLength',['../IRremoteESP8266_8h.html#aff17d9c0ccf683895d2c868094679f0a',1,'IRremoteESP8266.h']]], + ['khitachiac424tempbyte_5618',['kHitachiAc424TempByte',['../ir__Hitachi_8h.html#a5de1ae606d6a34e24420b08a73542b94',1,'ir_Hitachi.h']]], + ['khitachiac424tempoffset_5619',['kHitachiAc424TempOffset',['../ir__Hitachi_8h.html#a3adb47220c4c72a62d9296092047900f',1,'ir_Hitachi.h']]], + ['khitachiac424tempsize_5620',['kHitachiAc424TempSize',['../ir__Hitachi_8h.html#ae6738f4a4476e5f34efbeb52e8c413de',1,'ir_Hitachi.h']]], + ['khitachiac424zerospace_5621',['kHitachiAc424ZeroSpace',['../ir__Hitachi_8cpp.html#a0f2032ac476bf344df31dc9351b2b98a',1,'ir_Hitachi.cpp']]], + ['khitachiacauto_5622',['kHitachiAcAuto',['../ir__Hitachi_8h.html#af8c74a8388361162b93339e1b0bc94d9',1,'ir_Hitachi.h']]], + ['khitachiacautotemp_5623',['kHitachiAcAutoTemp',['../ir__Hitachi_8h.html#aaa28bb683fefc065cb115fbfb66994ec',1,'ir_Hitachi.h']]], + ['khitachiacbitmark_5624',['kHitachiAcBitMark',['../ir__Hitachi_8cpp.html#a0993bf3d527a12bfe51c7bbfcf788c59',1,'ir_Hitachi.cpp']]], + ['khitachiacbits_5625',['kHitachiAcBits',['../IRremoteESP8266_8h.html#aec91e459b1e52765c700f8f7a4723f3b',1,'IRremoteESP8266.h']]], + ['khitachiaccool_5626',['kHitachiAcCool',['../ir__Hitachi_8h.html#a2b40b07601fdf8b038c97bb8bd2bec59',1,'ir_Hitachi.h']]], + ['khitachiacdefaultrepeat_5627',['kHitachiAcDefaultRepeat',['../IRremoteESP8266_8h.html#acc8510281d2ff9a808501d375c03ba21',1,'IRremoteESP8266.h']]], + ['khitachiacdry_5628',['kHitachiAcDry',['../ir__Hitachi_8h.html#a19730b13fca736392600580c156ae3c3',1,'ir_Hitachi.h']]], + ['khitachiacfan_5629',['kHitachiAcFan',['../ir__Hitachi_8h.html#a69626883b6fdbd3ccd26bb3123bf1883',1,'ir_Hitachi.h']]], + ['khitachiacfanauto_5630',['kHitachiAcFanAuto',['../ir__Hitachi_8h.html#a6be6f6eae193e784133be63d7cc5d75e',1,'ir_Hitachi.h']]], + ['khitachiacfanhigh_5631',['kHitachiAcFanHigh',['../ir__Hitachi_8h.html#a85ef905a1d3704237141f07defc128f5',1,'ir_Hitachi.h']]], + ['khitachiacfanlow_5632',['kHitachiAcFanLow',['../ir__Hitachi_8h.html#a0add8c3a3d00a81fcc3279af78256de2',1,'ir_Hitachi.h']]], + ['khitachiacfanmed_5633',['kHitachiAcFanMed',['../ir__Hitachi_8h.html#ac88b4cfdce5d69bf07316ddd716c2c11',1,'ir_Hitachi.h']]], + ['khitachiacfreq_5634',['kHitachiAcFreq',['../ir__Hitachi_8h.html#a443eaa664017d7b671bef0e9aa2d643b',1,'ir_Hitachi.h']]], + ['khitachiachdrmark_5635',['kHitachiAcHdrMark',['../ir__Hitachi_8cpp.html#aefe34d17f5c72ee05afb9a6302a450da',1,'ir_Hitachi.cpp']]], + ['khitachiachdrspace_5636',['kHitachiAcHdrSpace',['../ir__Hitachi_8cpp.html#a4a4352723f119ea070be1eba2aafe36b',1,'ir_Hitachi.cpp']]], + ['khitachiacheat_5637',['kHitachiAcHeat',['../ir__Hitachi_8h.html#add2498e77e5585fd8c82a553bb0c22c0',1,'ir_Hitachi.h']]], + ['khitachiacmaxtemp_5638',['kHitachiAcMaxTemp',['../ir__Hitachi_8h.html#a63e17171c40d770d25f24d018aee2c4c',1,'ir_Hitachi.h']]], + ['khitachiacmingap_5639',['kHitachiAcMinGap',['../ir__Hitachi_8cpp.html#a14016b9110c11423c628c8e220e50864',1,'ir_Hitachi.cpp']]], + ['khitachiacmintemp_5640',['kHitachiAcMinTemp',['../ir__Hitachi_8h.html#a9b4f3ea50cc0491f10ff8dc8eabb3ecd',1,'ir_Hitachi.h']]], + ['khitachiaconespace_5641',['kHitachiAcOneSpace',['../ir__Hitachi_8cpp.html#a79a79aaf52a05c021621335586dd928f',1,'ir_Hitachi.cpp']]], + ['khitachiacpoweroffset_5642',['kHitachiAcPowerOffset',['../ir__Hitachi_8h.html#a30062f0646ac63c3612d13f98211e36b',1,'ir_Hitachi.h']]], + ['khitachiacstatelength_5643',['kHitachiAcStateLength',['../IRremoteESP8266_8h.html#a8bef76bac826afbbc51c2a867af15ed8',1,'IRremoteESP8266.h']]], + ['khitachiacswingoffset_5644',['kHitachiAcSwingOffset',['../ir__Hitachi_8h.html#aac1fcff513a4eca2aeb4f13c739165e2',1,'ir_Hitachi.h']]], + ['khitachiaczerospace_5645',['kHitachiAcZeroSpace',['../ir__Hitachi_8cpp.html#a0b03a4abb11d69a8b8da56ca2abc50c8',1,'ir_Hitachi.cpp']]], + ['kholdstr_5646',['kHoldStr',['../IRtext_8cpp.html#a86fd1f86e4a513603449e90a47500986',1,'kHoldStr(): IRtext.cpp'],['../IRtext_8h.html#adb2d0f01f1429b0f3eb7193519fe3d6e',1,'kHoldStr(): IRtext.cpp']]], + ['khoursstr_5647',['kHoursStr',['../IRtext_8cpp.html#ae94260daddf2ea56e54d56bbad66526c',1,'kHoursStr(): IRtext.cpp'],['../IRtext_8h.html#a10ecbc18040f0d0ed88b728c18b0a161',1,'kHoursStr(): IRtext.cpp']]], + ['khourstr_5648',['kHourStr',['../IRtext_8cpp.html#a1d25a0bf2c8a638fff1557a0c5637977',1,'kHourStr(): IRtext.cpp'],['../IRtext_8h.html#a67a94ecb5a557b5335a8085cf1d8cdd6',1,'kHourStr(): IRtext.cpp']]], + ['khumidstr_5649',['kHumidStr',['../IRtext_8cpp.html#aae236cd2e7ed4961360fe687fe38170d',1,'kHumidStr(): IRtext.cpp'],['../IRtext_8h.html#a25365e722200ac40d581c4f585f9ae2f',1,'kHumidStr(): IRtext.cpp']]], + ['kidlestate_5650',['kIdleState',['../IRrecv_8h.html#aabba6fe7d7b97c45173eb7781a5d99bf',1,'IRrecv.h']]], + ['kifeelstr_5651',['kIFeelStr',['../IRtext_8cpp.html#a3c7368d9138477f0eac2a6249ba2606b',1,'kIFeelStr(): IRtext.cpp'],['../IRtext_8h.html#a40f90b18252e14a73dd91527f621e35f',1,'kIFeelStr(): IRtext.cpp']]], + ['kinaxbitmark_5652',['kInaxBitMark',['../ir__Inax_8cpp.html#a84553819866dbfcfad8cba87f6c02e04',1,'ir_Inax.cpp']]], + ['kinaxbits_5653',['kInaxBits',['../IRremoteESP8266_8h.html#af8441f25b32d113096adeaff331c126a',1,'IRremoteESP8266.h']]], + ['kinaxhdrmark_5654',['kInaxHdrMark',['../ir__Inax_8cpp.html#ac467a96d91b6266c3ce9a2a4ec2a8b44',1,'ir_Inax.cpp']]], + ['kinaxhdrspace_5655',['kInaxHdrSpace',['../ir__Inax_8cpp.html#a6ddcc8ca7a5d05cee91e57b3e69cca33',1,'ir_Inax.cpp']]], + ['kinaxmingap_5656',['kInaxMinGap',['../ir__Inax_8cpp.html#a600f49303a77fbdc1d77aae2abe9b9aa',1,'ir_Inax.cpp']]], + ['kinaxminrepeat_5657',['kInaxMinRepeat',['../IRremoteESP8266_8h.html#a37a3d0ae51a6ce850a424fe77d5b22d2',1,'IRremoteESP8266.h']]], + ['kinaxonespace_5658',['kInaxOneSpace',['../ir__Inax_8cpp.html#aeb77e3a51838547a29c1b343eba4c7ef',1,'ir_Inax.cpp']]], + ['kinaxtick_5659',['kInaxTick',['../ir__Inax_8cpp.html#ad437f0beac0893853cc9d5cc214b03c6',1,'ir_Inax.cpp']]], + ['kinaxzerospace_5660',['kInaxZeroSpace',['../ir__Inax_8cpp.html#a115f1f061362c1c3c41e3bb20ea7e1c6',1,'ir_Inax.cpp']]], + ['kinsidestr_5661',['kInsideStr',['../IRtext_8cpp.html#aa94c7a9b472bcd2297b43a5b4008bc51',1,'kInsideStr(): IRtext.cpp'],['../IRtext_8h.html#a55c406749cb48970c11c58ec83ef97eb',1,'kInsideStr(): IRtext.cpp']]], + ['kionstr_5662',['kIonStr',['../IRtext_8cpp.html#afc36ce4beed72e662a8d9d1473dad235',1,'kIonStr(): IRtext.cpp'],['../IRtext_8h.html#add28006fe2f8ac70db1b5048c85be84b',1,'kIonStr(): IRtext.cpp']]], + ['kjvcbitmark_5663',['kJvcBitMark',['../ir__JVC_8cpp.html#a23c11d77431d37bba18776f9341c767f',1,'ir_JVC.cpp']]], + ['kjvcbitmarkticks_5664',['kJvcBitMarkTicks',['../ir__JVC_8cpp.html#aad7cf432a9bd0d2b4df66d5f903a70dd',1,'ir_JVC.cpp']]], + ['kjvcbits_5665',['kJvcBits',['../IRremoteESP8266_8h.html#a7c28467832e7480864a6be0ce87c608f',1,'IRremoteESP8266.h']]], + ['kjvchdrmark_5666',['kJvcHdrMark',['../ir__JVC_8cpp.html#a60d81ad0066288b602054bd24a912f1f',1,'ir_JVC.cpp']]], + ['kjvchdrmarkticks_5667',['kJvcHdrMarkTicks',['../ir__JVC_8cpp.html#abb12fba45b7a366e23849d693953e749',1,'ir_JVC.cpp']]], + ['kjvchdrspace_5668',['kJvcHdrSpace',['../ir__JVC_8cpp.html#a5444718f66ba8b43c1d7d99f7b378a0d',1,'ir_JVC.cpp']]], + ['kjvchdrspaceticks_5669',['kJvcHdrSpaceTicks',['../ir__JVC_8cpp.html#ae7cf6cb7b5ea5fe17a9b182d1ef3b008',1,'ir_JVC.cpp']]], + ['kjvcmingap_5670',['kJvcMinGap',['../ir__JVC_8cpp.html#ac19d8396c10adb687a883d016ec43aa5',1,'ir_JVC.cpp']]], + ['kjvcmingapticks_5671',['kJvcMinGapTicks',['../ir__JVC_8cpp.html#a525e7d672b148c02bdca1f66ab92e6c7',1,'ir_JVC.cpp']]], + ['kjvconespace_5672',['kJvcOneSpace',['../ir__JVC_8cpp.html#a8befef1d03f3a09541c2612c66c0256f',1,'ir_JVC.cpp']]], + ['kjvconespaceticks_5673',['kJvcOneSpaceTicks',['../ir__JVC_8cpp.html#a20d4f7737d71bdbec58694e775669df9',1,'ir_JVC.cpp']]], + ['kjvcrptlength_5674',['kJvcRptLength',['../ir__JVC_8cpp.html#a3896e40881e70c63234fecb88375b5a1',1,'ir_JVC.cpp']]], + ['kjvcrptlengthticks_5675',['kJvcRptLengthTicks',['../ir__JVC_8cpp.html#a75e03cf5739ab0ba67e5cfa426776d16',1,'ir_JVC.cpp']]], + ['kjvctick_5676',['kJvcTick',['../ir__JVC_8cpp.html#acd5a2ba251824cac5311adcc9a813b1a',1,'ir_JVC.cpp']]], + ['kjvczerospace_5677',['kJvcZeroSpace',['../ir__JVC_8cpp.html#a67c790b909f82e044b8c4e7227d9c189',1,'ir_JVC.cpp']]], + ['kjvczerospaceticks_5678',['kJvcZeroSpaceTicks',['../ir__JVC_8cpp.html#a0a5319df3b1e01741cd35a37087342f5',1,'ir_JVC.cpp']]], + ['kkelvinatorauto_5679',['kKelvinatorAuto',['../ir__Kelvinator_8h.html#a879b005fc5493a693b05e3bb7cbc8fbf',1,'ir_Kelvinator.h']]], + ['kkelvinatorautotemp_5680',['kKelvinatorAutoTemp',['../ir__Kelvinator_8h.html#afa9e7ea8c9fb86cb02358cc8221733b0',1,'ir_Kelvinator.h']]], + ['kkelvinatorbasicfanmax_5681',['kKelvinatorBasicFanMax',['../ir__Kelvinator_8h.html#a10624389f033451cf9a6f4530c2dfb98',1,'ir_Kelvinator.h']]], + ['kkelvinatorbasicfansize_5682',['kKelvinatorBasicFanSize',['../ir__Kelvinator_8cpp.html#a35ffe10c5c1b834703fe44c5eeeb4c8f',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorbitmark_5683',['kKelvinatorBitMark',['../ir__Kelvinator_8cpp.html#a2014f9f92f1e24a04341398e7e673807',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorbitmarkticks_5684',['kKelvinatorBitMarkTicks',['../ir__Kelvinator_8cpp.html#a2d6579257ab7f185e4f0fecdbdf03835',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorbits_5685',['kKelvinatorBits',['../IRremoteESP8266_8h.html#acfa71cb3caf4964829bb1f557dee5b86',1,'IRremoteESP8266.h']]], + ['kkelvinatorchecksumstart_5686',['kKelvinatorChecksumStart',['../ir__Kelvinator_8cpp.html#a0afa7cec1db6a5f46c1b30d7ce718ae6',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorcmdfooter_5687',['kKelvinatorCmdFooter',['../ir__Kelvinator_8cpp.html#ad2361e09472fa03376b447114a19513f',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorcmdfooterbits_5688',['kKelvinatorCmdFooterBits',['../ir__Kelvinator_8cpp.html#af6c85d3b30a5949da53ad9400734f203',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorcool_5689',['kKelvinatorCool',['../ir__Kelvinator_8h.html#ad49a2e457470d6e16d001cdae3215606',1,'ir_Kelvinator.h']]], + ['kkelvinatordefaultrepeat_5690',['kKelvinatorDefaultRepeat',['../IRremoteESP8266_8h.html#a94c968c5cc929f189b8e578d2f55b132',1,'IRremoteESP8266.h']]], + ['kkelvinatordry_5691',['kKelvinatorDry',['../ir__Kelvinator_8h.html#a181b3d10b522f9afb29706da42afea55',1,'ir_Kelvinator.h']]], + ['kkelvinatorfan_5692',['kKelvinatorFan',['../ir__Kelvinator_8h.html#a8d6d97be2fd8a5aefa1319d3f662a50c',1,'ir_Kelvinator.h']]], + ['kkelvinatorfanauto_5693',['kKelvinatorFanAuto',['../ir__Kelvinator_8h.html#ac4994c36634ca0ad8791807c9a992976',1,'ir_Kelvinator.h']]], + ['kkelvinatorfanmax_5694',['kKelvinatorFanMax',['../ir__Kelvinator_8h.html#a889ce17d112d1a61420e1064d72c583a',1,'ir_Kelvinator.h']]], + ['kkelvinatorfanmin_5695',['kKelvinatorFanMin',['../ir__Kelvinator_8h.html#a36a9422e2e6c6b7a87e8b2deffd1b189',1,'ir_Kelvinator.h']]], + ['kkelvinatorfanoffset_5696',['kKelvinatorFanOffset',['../ir__Kelvinator_8cpp.html#a4988bb98a4f8798c0b927e981667cfbd',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorfansize_5697',['kKelvinatorFanSize',['../ir__Kelvinator_8cpp.html#a286636ba83aceab9c8518878a6d7209e',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorgapspace_5698',['kKelvinatorGapSpace',['../ir__Kelvinator_8cpp.html#abf66116a235a9d05089182f2f7fd7640',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorgapspaceticks_5699',['kKelvinatorGapSpaceTicks',['../ir__Kelvinator_8cpp.html#a6a81fb4c1cf1ad34f99f3ca87ab74a5c',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorhdrmark_5700',['kKelvinatorHdrMark',['../ir__Kelvinator_8cpp.html#a413e824c6bdd4778e70f496917b3fe30',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorhdrmarkticks_5701',['kKelvinatorHdrMarkTicks',['../ir__Kelvinator_8cpp.html#a8ad828958071c75a80928abfb916c0df',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorhdrspace_5702',['kKelvinatorHdrSpace',['../ir__Kelvinator_8cpp.html#a9cab23fbd5ba62714fda24765db0e7d1',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorhdrspaceticks_5703',['kKelvinatorHdrSpaceTicks',['../ir__Kelvinator_8cpp.html#ab4fbf899dcb2c2d510055215617d5b44',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorheat_5704',['kKelvinatorHeat',['../ir__Kelvinator_8h.html#a080eade5648791e37c76af7a52e85731',1,'ir_Kelvinator.h']]], + ['kkelvinatorionfilteroffset_5705',['kKelvinatorIonFilterOffset',['../ir__Kelvinator_8cpp.html#a5cbdc907f0cb6a47d0c548148933067b',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorlightoffset_5706',['kKelvinatorLightOffset',['../ir__Kelvinator_8cpp.html#a7e757add18951b8e36c2065c5dbefc24',1,'ir_Kelvinator.cpp']]], + ['kkelvinatormaxtemp_5707',['kKelvinatorMaxTemp',['../ir__Kelvinator_8h.html#a14933442e718db1a87bae5d076ad228d',1,'ir_Kelvinator.h']]], + ['kkelvinatormintemp_5708',['kKelvinatorMinTemp',['../ir__Kelvinator_8h.html#a98871ce825dbbe80d072f25253142879',1,'ir_Kelvinator.h']]], + ['kkelvinatormodeoffset_5709',['kKelvinatorModeOffset',['../ir__Kelvinator_8cpp.html#a6a52d11326d5f83653c510393bb2a518',1,'ir_Kelvinator.cpp']]], + ['kkelvinatoronespace_5710',['kKelvinatorOneSpace',['../ir__Kelvinator_8cpp.html#aae5a009282517309b8fdbfdaced9d659',1,'ir_Kelvinator.cpp']]], + ['kkelvinatoronespaceticks_5711',['kKelvinatorOneSpaceTicks',['../ir__Kelvinator_8cpp.html#ac907f4495debdcaf680f6e6941b844d5',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorpoweroffset_5712',['kKelvinatorPowerOffset',['../ir__Kelvinator_8cpp.html#a5a9591e2dd98f68ad6f562e199b1a304',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorquietoffset_5713',['kKelvinatorQuietOffset',['../ir__Kelvinator_8cpp.html#ad354be321ea41c51ead876fd30674546',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorstatelength_5714',['kKelvinatorStateLength',['../IRremoteESP8266_8h.html#af68545e8c2fe9af3719fb74c5d21f0c9',1,'IRremoteESP8266.h']]], + ['kkelvinatortick_5715',['kKelvinatorTick',['../ir__Kelvinator_8cpp.html#a846cbb5609b1dff139a90487000c7393',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorturbooffset_5716',['kKelvinatorTurboOffset',['../ir__Kelvinator_8cpp.html#a21987b6f00c7f2e9bba94c59bc5b804b',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorventswinghoffset_5717',['kKelvinatorVentSwingHOffset',['../ir__Kelvinator_8cpp.html#a551df2c1e21764f12030f6bfa6d5942d',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorventswingoffset_5718',['kKelvinatorVentSwingOffset',['../ir__Kelvinator_8cpp.html#a38012bf9daa0c362a9007107183391ef',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorventswingvoffset_5719',['kKelvinatorVentSwingVOffset',['../ir__Kelvinator_8cpp.html#a64d3767b464d4fe2543560cf5a2a5b21',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorxfanoffset_5720',['kKelvinatorXfanOffset',['../ir__Kelvinator_8cpp.html#a4417448475405306f10166fc9cd98054',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorzerospace_5721',['kKelvinatorZeroSpace',['../ir__Kelvinator_8cpp.html#a10469f76f50285a6084bb088fd601dea',1,'ir_Kelvinator.cpp']]], + ['kkelvinatorzerospaceticks_5722',['kKelvinatorZeroSpaceTicks',['../ir__Kelvinator_8cpp.html#a0abc0fdc3d9ac9f12133a46e95d69432',1,'ir_Kelvinator.cpp']]], + ['klasertagbits_5723',['kLasertagBits',['../IRremoteESP8266_8h.html#a3ea0e89a8b6a3ffa4a2d346abeed851e',1,'IRremoteESP8266.h']]], + ['klasertagdelta_5724',['kLasertagDelta',['../ir__Lasertag_8cpp.html#a5c0e8e9c6dec0480c09fcd339ed62257',1,'ir_Lasertag.cpp']]], + ['klasertagexcess_5725',['kLasertagExcess',['../ir__Lasertag_8cpp.html#afa77dc5a431a8d851320e7623378983e',1,'ir_Lasertag.cpp']]], + ['klasertagmingap_5726',['kLasertagMinGap',['../ir__Lasertag_8cpp.html#a33762e2c44dac34e00d255b41d9f2822',1,'ir_Lasertag.cpp']]], + ['klasertagminrepeat_5727',['kLasertagMinRepeat',['../IRremoteESP8266_8h.html#a9b36135c3df24eab232a5edac8c58c5e',1,'IRremoteESP8266.h']]], + ['klasertagminsamples_5728',['kLasertagMinSamples',['../ir__Lasertag_8cpp.html#acbf98970106cadb43e0703ae2caab0c1',1,'ir_Lasertag.cpp']]], + ['klasertagtick_5729',['kLasertagTick',['../ir__Lasertag_8cpp.html#a878b5d53379f8b1b21dfe19f1f83a626',1,'ir_Lasertag.cpp']]], + ['klasertagtolerance_5730',['kLasertagTolerance',['../ir__Lasertag_8cpp.html#a6146bcf378515d31330b3fec5c967346',1,'ir_Lasertag.cpp']]], + ['klaststr_5731',['kLastStr',['../IRtext_8cpp.html#ad7c8430b935afb7aec114788a9c0bf7d',1,'kLastStr(): IRtext.cpp'],['../IRtext_8h.html#aa9ffd7c6e6921607653ed5dc1fea4f32',1,'kLastStr(): IRtext.cpp']]], + ['kleftmaxstr_5732',['kLeftMaxStr',['../IRtext_8cpp.html#a1a82999b6eb3b6637f51bb8ce6a46efd',1,'kLeftMaxStr(): IRtext.cpp'],['../IRtext_8h.html#ab2fd48f052fcfed8ca779ca499edcdbf',1,'kLeftMaxStr(): IRtext.cpp']]], + ['kleftstr_5733',['kLeftStr',['../IRtext_8cpp.html#a0bb005966f2ff2da12a542e713f7f1f2',1,'kLeftStr(): IRtext.cpp'],['../IRtext_8h.html#a001f11495c7c9452ceec68455ae524bf',1,'kLeftStr(): IRtext.cpp']]], + ['klegopfbitmark_5734',['kLegoPfBitMark',['../ir__Lego_8cpp.html#afdf76660f62bfefb4a813d57cd84b590',1,'ir_Lego.cpp']]], + ['klegopfbits_5735',['kLegoPfBits',['../IRremoteESP8266_8h.html#a8a7c7659250a81c7c84fc739eafed13e',1,'IRremoteESP8266.h']]], + ['klegopfhdrspace_5736',['kLegoPfHdrSpace',['../ir__Lego_8cpp.html#a140e8707900bfd4e3a9e2722a6b0bfb3',1,'ir_Lego.cpp']]], + ['klegopfmincommandlength_5737',['kLegoPfMinCommandLength',['../ir__Lego_8cpp.html#ad9a0c5184cc422ec1b32edf58c52d2b1',1,'ir_Lego.cpp']]], + ['klegopfminrepeat_5738',['kLegoPfMinRepeat',['../IRremoteESP8266_8h.html#a2614cf3cb840f028eb1dc684aeb1272c',1,'IRremoteESP8266.h']]], + ['klegopfonespace_5739',['kLegoPfOneSpace',['../ir__Lego_8cpp.html#a59a41085f2e8f81e1019fd40782269e3',1,'ir_Lego.cpp']]], + ['klegopfzerospace_5740',['kLegoPfZeroSpace',['../ir__Lego_8cpp.html#ada07e8aaf79cf58c46b301a410d9fb3e',1,'ir_Lego.cpp']]], + ['klg2bitmark_5741',['kLg2BitMark',['../ir__LG_8cpp.html#abf4db4647161db6fb2548b5200c41843',1,'ir_LG.cpp']]], + ['klg2bitmarkticks_5742',['kLg2BitMarkTicks',['../ir__LG_8cpp.html#aae477dcb68b9c5f1b12adf832eb388a1',1,'ir_LG.cpp']]], + ['klg2hdrmark_5743',['kLg2HdrMark',['../ir__LG_8cpp.html#a5ca50077fba2d5130220255e1659e0c3',1,'ir_LG.cpp']]], + ['klg2hdrmarkticks_5744',['kLg2HdrMarkTicks',['../ir__LG_8cpp.html#adb636fb6b634c651364ae954d31b5692',1,'ir_LG.cpp']]], + ['klg2hdrspace_5745',['kLg2HdrSpace',['../ir__LG_8cpp.html#a6637da052fea9320e97cff261f219cdb',1,'ir_LG.cpp']]], + ['klg2hdrspaceticks_5746',['kLg2HdrSpaceTicks',['../ir__LG_8cpp.html#abd2f843416070a93587d07e4d32f1eb5',1,'ir_LG.cpp']]], + ['klg32bits_5747',['kLg32Bits',['../IRremoteESP8266_8h.html#ae3c458814d7221b66d2f267cb2663bd2',1,'IRremoteESP8266.h']]], + ['klg32hdrmark_5748',['kLg32HdrMark',['../ir__LG_8cpp.html#a26cb3fb11b1a0bf0815868767e50f31b',1,'ir_LG.cpp']]], + ['klg32hdrmarkticks_5749',['kLg32HdrMarkTicks',['../ir__LG_8cpp.html#aded50973c0a938d455c1537cb240d5e9',1,'ir_LG.cpp']]], + ['klg32hdrspace_5750',['kLg32HdrSpace',['../ir__LG_8cpp.html#a59ddf2070642615e162c85b7575aff76',1,'ir_LG.cpp']]], + ['klg32hdrspaceticks_5751',['kLg32HdrSpaceTicks',['../ir__LG_8cpp.html#aa029c2c83a96f1ff02610eddd6b946fa',1,'ir_LG.cpp']]], + ['klg32rpthdrmark_5752',['kLg32RptHdrMark',['../ir__LG_8cpp.html#af19a674228bea82c1c588aa9dd974805',1,'ir_LG.cpp']]], + ['klg32rpthdrmarkticks_5753',['kLg32RptHdrMarkTicks',['../ir__LG_8cpp.html#a5c79f7072eee35fc1df10ecd18e2a3d2',1,'ir_LG.cpp']]], + ['klgacauto_5754',['kLgAcAuto',['../ir__LG_8h.html#ae5e45a0f42ce7544d6fb7981a43fb932',1,'ir_LG.h']]], + ['klgacchecksumoffset_5755',['kLgAcChecksumOffset',['../ir__LG_8h.html#aa0b9abe43a870097d886efcd0fd3bb96',1,'ir_LG.h']]], + ['klgacchecksumsize_5756',['kLgAcChecksumSize',['../ir__LG_8h.html#a177d205346380d47ae47b52079e5ffaf',1,'ir_LG.h']]], + ['klgaccool_5757',['kLgAcCool',['../ir__LG_8h.html#a3ba35885488bdda3d87ba344a5c58eb2',1,'ir_LG.h']]], + ['klgacdry_5758',['kLgAcDry',['../ir__LG_8h.html#ab3b9a106551be1217e0c824cffe1ea44',1,'ir_LG.h']]], + ['klgacfan_5759',['kLgAcFan',['../ir__LG_8h.html#afc12144673b8dd0555833427fa757275',1,'ir_LG.h']]], + ['klgacfanauto_5760',['kLgAcFanAuto',['../ir__LG_8h.html#a3dee1dc33f768d36a2216213c90a0a5c',1,'ir_LG.h']]], + ['klgacfanhigh_5761',['kLgAcFanHigh',['../ir__LG_8h.html#a89888f8d36899b5526e4c2ebb1097357',1,'ir_LG.h']]], + ['klgacfanlow_5762',['kLgAcFanLow',['../ir__LG_8h.html#afa3633c1b26d837f85b10a8a8d677efc',1,'ir_LG.h']]], + ['klgacfanmedium_5763',['kLgAcFanMedium',['../ir__LG_8h.html#abe0fb8a8f9d6ab9ebda36d0343841619',1,'ir_LG.h']]], + ['klgacfanoffset_5764',['kLgAcFanOffset',['../ir__LG_8h.html#a428d348215682243f7e5fe03c7580665',1,'ir_LG.h']]], + ['klgacfansize_5765',['kLgAcFanSize',['../ir__LG_8h.html#a4baf7484fee55fdd5cdbf13d11d7f1b9',1,'ir_LG.h']]], + ['klgacheat_5766',['kLgAcHeat',['../ir__LG_8h.html#a6c17d61082cc24f9d714c5d4ac151933',1,'ir_LG.h']]], + ['klgacmaxtemp_5767',['kLgAcMaxTemp',['../ir__LG_8h.html#a0fab7b6e6d1138638bdeadeab85f5090',1,'ir_LG.h']]], + ['klgacmintemp_5768',['kLgAcMinTemp',['../ir__LG_8h.html#ae3bef99e329f057358001cacf67f6d70',1,'ir_LG.h']]], + ['klgacmodeoffset_5769',['kLgAcModeOffset',['../ir__LG_8h.html#abbc65ef461fd214d9ef41ebf62693467',1,'ir_LG.h']]], + ['klgacmodesize_5770',['kLgAcModeSize',['../ir__LG_8h.html#ae9927832fbb45c310666d8de1ebe5f0f',1,'ir_LG.h']]], + ['klgacoffcommand_5771',['kLgAcOffCommand',['../ir__LG_8h.html#aecf8158eec1d9ec0d54056392b512296',1,'ir_LG.h']]], + ['klgacpoweroff_5772',['kLgAcPowerOff',['../ir__LG_8h.html#a3b2681e41071298197d849fbd7649318',1,'ir_LG.h']]], + ['klgacpoweroffset_5773',['kLgAcPowerOffset',['../ir__LG_8h.html#a7cce14305909efe3b904d68f902d42de',1,'ir_LG.h']]], + ['klgacpoweron_5774',['kLgAcPowerOn',['../ir__LG_8h.html#a87d2f6e4e2755aaab4762952b1bf6108',1,'ir_LG.h']]], + ['klgacpowersize_5775',['kLgAcPowerSize',['../ir__LG_8h.html#a624eee0bc9084e4d9d801f8cbdc28d1e',1,'ir_LG.h']]], + ['klgacsignature_5776',['kLgAcSignature',['../ir__LG_8h.html#ab7c3589deb28829ad0313b1505ec196e',1,'ir_LG.h']]], + ['klgacsignatureoffset_5777',['kLgAcSignatureOffset',['../ir__LG_8h.html#a406dff4b4ffa5b809b8ea87ddfd3bf8b',1,'ir_LG.h']]], + ['klgacsignaturesize_5778',['kLgAcSignatureSize',['../ir__LG_8h.html#a7420d729a5dca26d95be3b9907eb477e',1,'ir_LG.h']]], + ['klgactempadjust_5779',['kLgAcTempAdjust',['../ir__LG_8h.html#a16210dc395a86dc4562436047c22600f',1,'ir_LG.h']]], + ['klgactempoffset_5780',['kLgAcTempOffset',['../ir__LG_8h.html#aca5ae781e03e4a88a83303cb0cae0609',1,'ir_LG.h']]], + ['klgactempsize_5781',['kLgAcTempSize',['../ir__LG_8h.html#ad0235a6c5bebb086b75dc65433b3c9e1',1,'ir_LG.h']]], + ['klgbitmark_5782',['kLgBitMark',['../ir__LG_8cpp.html#a9311195710d4c3a2ac48456390a03138',1,'ir_LG.cpp']]], + ['klgbitmarkticks_5783',['kLgBitMarkTicks',['../ir__LG_8cpp.html#a80b2d221b207c8c0faa74f1f39e9920b',1,'ir_LG.cpp']]], + ['klgbits_5784',['kLgBits',['../IRremoteESP8266_8h.html#a256bd6093034b3e4c33324680f3a7102',1,'IRremoteESP8266.h']]], + ['klgdefaultrepeat_5785',['kLgDefaultRepeat',['../IRremoteESP8266_8h.html#a2d6832b3d214e0adad781c205993e461',1,'IRremoteESP8266.h']]], + ['klghdrmark_5786',['kLgHdrMark',['../ir__LG_8cpp.html#a74f253d9e4cc72148233021c47d59f35',1,'ir_LG.cpp']]], + ['klghdrmarkticks_5787',['kLgHdrMarkTicks',['../ir__LG_8cpp.html#a6f1f88f3cefe49b9796a10a9109e560e',1,'ir_LG.cpp']]], + ['klghdrspace_5788',['kLgHdrSpace',['../ir__LG_8cpp.html#a6eaf100cde647fc119d3e993680afd47',1,'ir_LG.cpp']]], + ['klghdrspaceticks_5789',['kLgHdrSpaceTicks',['../ir__LG_8cpp.html#a22d8775d4c8985970b47e449232b45de',1,'ir_LG.cpp']]], + ['klgmingap_5790',['kLgMinGap',['../ir__LG_8cpp.html#a784323468e6b5ebc65bd2870a94fb553',1,'ir_LG.cpp']]], + ['klgmingapticks_5791',['kLgMinGapTicks',['../ir__LG_8cpp.html#aa56fd5b4fe946992aa1b9bdf61b1518b',1,'ir_LG.cpp']]], + ['klgminmessagelength_5792',['kLgMinMessageLength',['../ir__LG_8cpp.html#a4eb3f82ae2ca6c34b58e512848a6dc41',1,'ir_LG.cpp']]], + ['klgminmessagelengthticks_5793',['kLgMinMessageLengthTicks',['../ir__LG_8cpp.html#ab000fc974bdd0723e8bcb4872f33dd72',1,'ir_LG.cpp']]], + ['klgonespace_5794',['kLgOneSpace',['../ir__LG_8cpp.html#a05fe6a47f437efc686cb46ec805da4d4',1,'ir_LG.cpp']]], + ['klgonespaceticks_5795',['kLgOneSpaceTicks',['../ir__LG_8cpp.html#a535b089cd72bd027cbc34eb917d71ae5',1,'ir_LG.cpp']]], + ['klgrptspace_5796',['kLgRptSpace',['../ir__LG_8cpp.html#a834b8f08ee32030c51ea5e2c5bd5a73c',1,'ir_LG.cpp']]], + ['klgrptspaceticks_5797',['kLgRptSpaceTicks',['../ir__LG_8cpp.html#abc43b327c2c752dc5ed2794f08e2eba8',1,'ir_LG.cpp']]], + ['klgtick_5798',['kLgTick',['../ir__LG_8cpp.html#ab8ab28ebf1fae94aa900a3199a6fc191',1,'ir_LG.cpp']]], + ['klgzerospace_5799',['kLgZeroSpace',['../ir__LG_8cpp.html#a981fe3cfc4adf0b3016a008ca1bbf734',1,'ir_LG.cpp']]], + ['klgzerospaceticks_5800',['kLgZeroSpaceTicks',['../ir__LG_8cpp.html#af932345e15db822da67d7796cd5b6584',1,'ir_LG.cpp']]], + ['klightstr_5801',['kLightStr',['../IRtext_8cpp.html#a2912b7dc11fd571706eaaf90e0095a4f',1,'kLightStr(): IRtext.cpp'],['../IRtext_8h.html#a926ebb4be14179afdc55d5524c8eb5da',1,'kLightStr(): IRtext.cpp']]], + ['klighttogglestr_5802',['kLightToggleStr',['../IRtext_8cpp.html#a74a3ef3c72995e19582be04a2716b285',1,'kLightToggleStr(): IRtext.cpp'],['../IRtext_8h.html#af9ac8ce54e78f0d8f7e0043d08e6256c',1,'kLightToggleStr(): IRtext.cpp']]], + ['klostr_5803',['kLoStr',['../IRtext_8cpp.html#a72fc3855eec7026260de3a6b3a25c377',1,'kLoStr(): IRtext.cpp'],['../IRtext_8h.html#abf3295aeb3dfb7048e677d8d6e65e47c',1,'kLoStr(): IRtext.cpp']]], + ['kloudstr_5804',['kLoudStr',['../IRtext_8cpp.html#a3b6d3eed96c5623cc95ebcfb93cb6f96',1,'kLoudStr(): IRtext.cpp'],['../IRtext_8h.html#a7d265b75ed59c0be3c6b72ec0eaf8aa2',1,'kLoudStr(): IRtext.cpp']]], + ['klowerstr_5805',['kLowerStr',['../IRtext_8cpp.html#a518681524ec3c8f8bc993823003fe58a',1,'kLowerStr(): IRtext.cpp'],['../IRtext_8h.html#ae389ed4ed6982d4617ee3f3e82ce388c',1,'kLowerStr(): IRtext.cpp']]], + ['kloweststr_5806',['kLowestStr',['../IRtext_8cpp.html#ae0c595955599a398669a372edd339f67',1,'kLowestStr(): IRtext.cpp'],['../IRtext_8h.html#a31a34e51d7f1f9360cc3a7ea3f2bf7a3',1,'kLowestStr(): IRtext.cpp']]], + ['klownibble_5807',['kLowNibble',['../IRutils_8h.html#ad0288cc71e1814a27c27393f06676eec',1,'IRutils.h']]], + ['klowstr_5808',['kLowStr',['../IRtext_8cpp.html#a18f69bf40b866ee1d30d1586757d5f41',1,'kLowStr(): IRtext.cpp'],['../IRtext_8h.html#a09c0f7f1b07f7591bdbe56fd8a18f7ea',1,'kLowStr(): IRtext.cpp']]], + ['klutronbits_5809',['kLutronBits',['../IRremoteESP8266_8h.html#a814dfab515b91887c494237b1f6ebd99',1,'IRremoteESP8266.h']]], + ['klutrondelta_5810',['kLutronDelta',['../ir__Lutron_8cpp.html#a4220004fac195ef46388199ad9624860',1,'ir_Lutron.cpp']]], + ['klutrongap_5811',['kLutronGap',['../ir__Lutron_8cpp.html#a18ffb51db0ae33904a64012cb72d6165',1,'ir_Lutron.cpp']]], + ['klutrontick_5812',['kLutronTick',['../ir__Lutron_8cpp.html#a04a84309978b79c0983c398a497a087a',1,'ir_Lutron.cpp']]], + ['kmagiquestbits_5813',['kMagiquestBits',['../IRremoteESP8266_8h.html#ad756bfec6eabbe2ac10b7847f87fb751',1,'IRremoteESP8266.h']]], + ['kmagiquestgap_5814',['kMagiQuestGap',['../ir__Magiquest_8h.html#aebdea5a1a55547d812f1f7bb2d3ddf1f',1,'ir_Magiquest.h']]], + ['kmagiquestmarkone_5815',['kMagiQuestMarkOne',['../ir__Magiquest_8h.html#a0d5d090015ecf49995514054c29cb4e2',1,'ir_Magiquest.h']]], + ['kmagiquestmarkzero_5816',['kMagiQuestMarkZero',['../ir__Magiquest_8h.html#a7240a15dbb9bc6a1e31575be7837c390',1,'ir_Magiquest.h']]], + ['kmagiquestoneratio_5817',['kMagiQuestOneRatio',['../ir__Magiquest_8h.html#a073cdb7ca4dd35b8fa05d99eb7da5b65',1,'ir_Magiquest.h']]], + ['kmagiquestspaceone_5818',['kMagiQuestSpaceOne',['../ir__Magiquest_8h.html#a92bad440c0291cbb903f08de08d96fb2',1,'ir_Magiquest.h']]], + ['kmagiquestspacezero_5819',['kMagiQuestSpaceZero',['../ir__Magiquest_8h.html#abe557052c5c3bef87e62daf71b4c8654',1,'ir_Magiquest.h']]], + ['kmagiquesttotalusec_5820',['kMagiQuestTotalUsec',['../ir__Magiquest_8h.html#a819dcf22b127f4f7b282d784490a83c3',1,'ir_Magiquest.h']]], + ['kmagiquestzeroratio_5821',['kMagiQuestZeroRatio',['../ir__Magiquest_8h.html#a41e5594b8e1510267e563ed78fbe98b0',1,'ir_Magiquest.h']]], + ['kmanualstr_5822',['kManualStr',['../IRtext_8cpp.html#a619896ae89717b2b0e1d3492bb528cbc',1,'kManualStr(): IRtext.cpp'],['../IRtext_8h.html#aa8d9143da032cdc1accf7f4441b05bc8',1,'kManualStr(): IRtext.cpp']]], + ['kmark_5823',['kMark',['../ir__Lasertag_8cpp.html#a7af2e83face1b9378d216f15a4d379cf',1,'kMark(): ir_Lasertag.cpp'],['../ir__MWM_8cpp.html#a7af2e83face1b9378d216f15a4d379cf',1,'kMark(): ir_MWM.cpp'],['../ir__RC5__RC6_8cpp.html#a7af2e83face1b9378d216f15a4d379cf',1,'kMark(): ir_RC5_RC6.cpp']]], + ['kmarkexcess_5824',['kMarkExcess',['../IRrecv_8h.html#a99bbffe986ad7ba86d2b11e75f4aa50e',1,'IRrecv.h']]], + ['kmarkstate_5825',['kMarkState',['../IRrecv_8h.html#acc85ad22929660bdc17fe185d87edfb2',1,'IRrecv.h']]], + ['kmaxaccurateusecdelay_5826',['kMaxAccurateUsecDelay',['../IRsend_8h.html#a527e66125f3ae6ce87adbc72eab7d0b9',1,'IRsend.h']]], + ['kmaximumstr_5827',['kMaximumStr',['../IRtext_8cpp.html#af346693e98c91c7ce79bb22c7460dcee',1,'kMaximumStr(): IRtext.cpp'],['../IRtext_8h.html#a487173616cc3fced0489c01c11333912',1,'kMaximumStr(): IRtext.cpp']]], + ['kmaxleftstr_5828',['kMaxLeftStr',['../IRtext_8cpp.html#ae8ad7e46c3a33b4b9c5fa6545c9e3822',1,'kMaxLeftStr(): IRtext.cpp'],['../IRtext_8h.html#aac197960695463757652bc643efdcd59',1,'kMaxLeftStr(): IRtext.cpp']]], + ['kmaxrightstr_5829',['kMaxRightStr',['../IRtext_8cpp.html#a1ae3f331adb8ac6d1a27aa3d688fb65f',1,'kMaxRightStr(): IRtext.cpp'],['../IRtext_8h.html#a0f888d5c39cf82b2c02a7caad10c716e',1,'kMaxRightStr(): IRtext.cpp']]], + ['kmaxstr_5830',['kMaxStr',['../IRtext_8cpp.html#ad30e01090f06db0a3cb0c00bb6d2f0ca',1,'kMaxStr(): IRtext.cpp'],['../IRtext_8h.html#a7f4b2ff4134386a09e2bcb5f71f591cb',1,'kMaxStr(): IRtext.cpp']]], + ['kmaxtimeoutms_5831',['kMaxTimeoutMs',['../IRrecv_8h.html#a73391726d7caccb9b498bba73a969784',1,'IRrecv.h']]], + ['kmediumstr_5832',['kMediumStr',['../IRtext_8cpp.html#ac59539e93fdc7d8f15f1f55bcbf933c5',1,'kMediumStr(): IRtext.cpp'],['../IRtext_8h.html#a122ee1c6b866267f771888a7d7b2969b',1,'kMediumStr(): IRtext.cpp']]], + ['kmedstr_5833',['kMedStr',['../IRtext_8cpp.html#a4832f8f5118018fa3c6eae1cd652eabf',1,'kMedStr(): IRtext.cpp'],['../IRtext_8h.html#a18f613c7f11f6f746227cfa8cc1e00e0',1,'kMedStr(): IRtext.cpp']]], + ['kmiddlestr_5834',['kMiddleStr',['../IRtext_8cpp.html#a536f05d84867cfae601d4c1a2312d755',1,'kMiddleStr(): IRtext.cpp'],['../IRtext_8h.html#abbd5b682b584b737c76bded900a6ffad',1,'kMiddleStr(): IRtext.cpp']]], + ['kmidea24bits_5835',['kMidea24Bits',['../IRremoteESP8266_8h.html#aff132faa67b1d07890378df5c9b52a14',1,'IRremoteESP8266.h']]], + ['kmidea24mingap_5836',['kMidea24MinGap',['../ir__Midea_8cpp.html#abfee73cafcc017c4742893908200dffc',1,'ir_Midea.cpp']]], + ['kmidea24minrepeat_5837',['kMidea24MinRepeat',['../IRremoteESP8266_8h.html#a8ed4bb62818fc64e4c4b60ef1094059e',1,'IRremoteESP8266.h']]], + ['kmideaacauto_5838',['kMideaACAuto',['../ir__Midea_8h.html#a379f580c4d1832a62fe49d66f7c13af6',1,'ir_Midea.h']]], + ['kmideaaccelsiusoffset_5839',['kMideaACCelsiusOffset',['../ir__Midea_8h.html#a3354c62fbd83c1f0c55aee359d45a1e0',1,'ir_Midea.h']]], + ['kmideaaccool_5840',['kMideaACCool',['../ir__Midea_8h.html#a94b1b18f6aa9c5010699ea9bfcc89b21',1,'ir_Midea.h']]], + ['kmideaacdry_5841',['kMideaACDry',['../ir__Midea_8h.html#a88c2d215406e337b437b99a04c4ca6c4',1,'ir_Midea.h']]], + ['kmideaacfan_5842',['kMideaACFan',['../ir__Midea_8h.html#ac92dd372bb18d43aea73d5ec511e1290',1,'ir_Midea.h']]], + ['kmideaacfanauto_5843',['kMideaACFanAuto',['../ir__Midea_8h.html#a334a64f653b141d67ffda2eca2a9851f',1,'ir_Midea.h']]], + ['kmideaacfanhigh_5844',['kMideaACFanHigh',['../ir__Midea_8h.html#a9c177aff562a19f32d6cf010704ac681',1,'ir_Midea.h']]], + ['kmideaacfanlow_5845',['kMideaACFanLow',['../ir__Midea_8h.html#a90ebe3812e8b554798a2083ddfe9fdff',1,'ir_Midea.h']]], + ['kmideaacfanmed_5846',['kMideaACFanMed',['../ir__Midea_8h.html#a9406c8d9ad79e6a121a29cd5455e8e7d',1,'ir_Midea.h']]], + ['kmideaacfanoffset_5847',['kMideaACFanOffset',['../ir__Midea_8h.html#ac210e7bed85ad46cef1fa15a71d8e4c9',1,'ir_Midea.h']]], + ['kmideaacfansize_5848',['kMideaACFanSize',['../ir__Midea_8h.html#ab2726e607d432d00b625471d51b71b21',1,'ir_Midea.h']]], + ['kmideaacheat_5849',['kMideaACHeat',['../ir__Midea_8h.html#aa0fb74d8406327a9510f0efa8a16a488',1,'ir_Midea.h']]], + ['kmideaacmaxtempc_5850',['kMideaACMaxTempC',['../ir__Midea_8h.html#a0cccc3093cffabe1e512f298c04b3ba1',1,'ir_Midea.h']]], + ['kmideaacmaxtempf_5851',['kMideaACMaxTempF',['../ir__Midea_8h.html#ac7306c86080e934055d5be9728c91629',1,'ir_Midea.h']]], + ['kmideaacmintempc_5852',['kMideaACMinTempC',['../ir__Midea_8h.html#ae849eb79db6c077d617283154edade84',1,'ir_Midea.h']]], + ['kmideaacmintempf_5853',['kMideaACMinTempF',['../ir__Midea_8h.html#a0b0bdf519164f793a129d0e32152069a',1,'ir_Midea.h']]], + ['kmideaacmodeoffset_5854',['kMideaACModeOffset',['../ir__Midea_8h.html#a04fb535d82fe9d44d6898dd7c2e3491e',1,'ir_Midea.h']]], + ['kmideaacpoweroffset_5855',['kMideaACPowerOffset',['../ir__Midea_8h.html#a299cd691572c33f5d4742a9c289c279c',1,'ir_Midea.h']]], + ['kmideaacsleepoffset_5856',['kMideaACSleepOffset',['../ir__Midea_8h.html#a3c968881e59795eadfcb991b36755494',1,'ir_Midea.h']]], + ['kmideaactempoffset_5857',['kMideaACTempOffset',['../ir__Midea_8h.html#aec7e9182f167eb9b094670cf9889a595',1,'ir_Midea.h']]], + ['kmideaactempsize_5858',['kMideaACTempSize',['../ir__Midea_8h.html#aad2041ff636467046b63ceeb9fdfaaea',1,'ir_Midea.h']]], + ['kmideaactoggleswingv_5859',['kMideaACToggleSwingV',['../ir__Midea_8h.html#a5420b72289d3ae99a6dbc5c94914c473',1,'ir_Midea.h']]], + ['kmideabitmark_5860',['kMideaBitMark',['../ir__Midea_8cpp.html#a39dc2d03456f67418519dc0f5efde7e0',1,'ir_Midea.cpp']]], + ['kmideabitmarkticks_5861',['kMideaBitMarkTicks',['../ir__Midea_8cpp.html#ac4d9b1460516aa19913b5bd328c1e176',1,'ir_Midea.cpp']]], + ['kmideabits_5862',['kMideaBits',['../IRremoteESP8266_8h.html#afc98096b1e2945e2eaeb07d70d511239',1,'IRremoteESP8266.h']]], + ['kmideahdrmark_5863',['kMideaHdrMark',['../ir__Midea_8cpp.html#adcaa1ad6e2ba1022f3c90266f4fd0378',1,'ir_Midea.cpp']]], + ['kmideahdrmarkticks_5864',['kMideaHdrMarkTicks',['../ir__Midea_8cpp.html#af63b6cfcc5dc3e501b61c0d55d678f9e',1,'ir_Midea.cpp']]], + ['kmideahdrspace_5865',['kMideaHdrSpace',['../ir__Midea_8cpp.html#a8676eda087a85f6639b547140496c12f',1,'ir_Midea.cpp']]], + ['kmideahdrspaceticks_5866',['kMideaHdrSpaceTicks',['../ir__Midea_8cpp.html#aad99b5d8361733a9ca662735783e061c',1,'ir_Midea.cpp']]], + ['kmideamingap_5867',['kMideaMinGap',['../ir__Midea_8cpp.html#ad9ed8fb4841654fa756614862ac63be7',1,'ir_Midea.cpp']]], + ['kmideamingapticks_5868',['kMideaMinGapTicks',['../ir__Midea_8cpp.html#accd4e69e8fe0957ba013b97879fb1120',1,'ir_Midea.cpp']]], + ['kmideaminrepeat_5869',['kMideaMinRepeat',['../IRremoteESP8266_8h.html#aa8876e8e177b8e71154f8cfb42b19160',1,'IRremoteESP8266.h']]], + ['kmideaonespace_5870',['kMideaOneSpace',['../ir__Midea_8cpp.html#aabe187743f36e664c6069b004e9a82f7',1,'ir_Midea.cpp']]], + ['kmideaonespaceticks_5871',['kMideaOneSpaceTicks',['../ir__Midea_8cpp.html#a2cf0d5df2e5a3d7b1d24fd25ae3d7453',1,'ir_Midea.cpp']]], + ['kmideatick_5872',['kMideaTick',['../ir__Midea_8cpp.html#a878185258a4174978b072ac36aa377e2',1,'ir_Midea.cpp']]], + ['kmideatolerance_5873',['kMideaTolerance',['../ir__Midea_8cpp.html#a55553c3b8e7997fb1257ac2a37a929b6',1,'ir_Midea.cpp']]], + ['kmideazerospace_5874',['kMideaZeroSpace',['../ir__Midea_8cpp.html#a107d1d062e8475b84ec4ab548c3f01ef',1,'ir_Midea.cpp']]], + ['kmideazerospaceticks_5875',['kMideaZeroSpaceTicks',['../ir__Midea_8cpp.html#acd6580988c12ef5614727dd4d1b4c92d',1,'ir_Midea.cpp']]], + ['kmidstr_5876',['kMidStr',['../IRtext_8cpp.html#afd827d424c0bfdcc34b3607440fd2652',1,'kMidStr(): IRtext.cpp'],['../IRtext_8h.html#a571a28fe4174574caac4d93fb09ae196',1,'kMidStr(): IRtext.cpp']]], + ['kminimumstr_5877',['kMinimumStr',['../IRtext_8cpp.html#acbd869e5978b6fee053d33d8cf21e11a',1,'kMinimumStr(): IRtext.cpp'],['../IRtext_8h.html#a4f6fee52ae5f7f9c8fe791dbae762607',1,'kMinimumStr(): IRtext.cpp']]], + ['kminstr_5878',['kMinStr',['../IRtext_8cpp.html#a2b0c7369c1a93b8a7d5a87bf37fcee34',1,'kMinStr(): IRtext.cpp'],['../IRtext_8h.html#a4940a3f71a484f936d3e58b9573931a8',1,'kMinStr(): IRtext.cpp']]], + ['kminutesstr_5879',['kMinutesStr',['../IRtext_8cpp.html#a1c05b3e6af04586a0060c58979df002f',1,'kMinutesStr(): IRtext.cpp'],['../IRtext_8h.html#a3358666a695e8d54c23b20dc6a371a38',1,'kMinutesStr(): IRtext.cpp']]], + ['kminutestr_5880',['kMinuteStr',['../IRtext_8cpp.html#acab620931ba510a7bc395bad59169099',1,'kMinuteStr(): IRtext.cpp'],['../IRtext_8h.html#a54df015b1adadb211a30f826999c78f6',1,'kMinuteStr(): IRtext.cpp']]], + ['kmitsubishi112auto_5881',['kMitsubishi112Auto',['../ir__Mitsubishi_8h.html#a6e38f06ff78e3406a4f2cf1e1b453402',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112bitmark_5882',['kMitsubishi112BitMark',['../ir__Mitsubishi_8cpp.html#aef96bbd77d5bd66ed220840c09f54c37',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi112bits_5883',['kMitsubishi112Bits',['../IRremoteESP8266_8h.html#ae8349abe183be965e3d051cb736773a8',1,'IRremoteESP8266.h']]], + ['kmitsubishi112cool_5884',['kMitsubishi112Cool',['../ir__Mitsubishi_8h.html#aa9d1a63a8a275cda1794628f8d516963',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112dry_5885',['kMitsubishi112Dry',['../ir__Mitsubishi_8h.html#a4a3023d0342003b7947b19c9c5c25fb3',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112fanbyte_5886',['kMitsubishi112FanByte',['../ir__Mitsubishi_8h.html#a4312828eb864a67f8cc67a90c1324d3a',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112fanlow_5887',['kMitsubishi112FanLow',['../ir__Mitsubishi_8h.html#a4b8d6d04bb75ed98f6ed5bdff7472f50',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112fanmax_5888',['kMitsubishi112FanMax',['../ir__Mitsubishi_8h.html#a5a3e7c72ed85864b34f8ee298b3adc49',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112fanmed_5889',['kMitsubishi112FanMed',['../ir__Mitsubishi_8h.html#aa8a81057eeccbf528962b31a197b0319',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112fanmin_5890',['kMitsubishi112FanMin',['../ir__Mitsubishi_8h.html#ad8b101130e781d30b5d4072b3c514c78',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112fanoffset_5891',['kMitsubishi112FanOffset',['../ir__Mitsubishi_8h.html#ac000e0d3a59314c115e516f37c29983d',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112fanquiet_5892',['kMitsubishi112FanQuiet',['../ir__Mitsubishi_8h.html#addcf7a99c5ba2f4510754d22a4c0760f',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112fansize_5893',['kMitsubishi112FanSize',['../ir__Mitsubishi_8h.html#ab102138f689d66c2c4c97445931f2dec',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112gap_5894',['kMitsubishi112Gap',['../ir__Mitsubishi_8cpp.html#ab24cc7d395c1620b9519b5d0ce2a2023',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi112hdrmark_5895',['kMitsubishi112HdrMark',['../ir__Mitsubishi_8cpp.html#a3082567d58d6f8e6ef26714ff23f3728',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi112hdrmarktolerance_5896',['kMitsubishi112HdrMarkTolerance',['../ir__Mitsubishi_8cpp.html#a288931e01f8cffa1917fb7bc59710e20',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi112hdrspace_5897',['kMitsubishi112HdrSpace',['../ir__Mitsubishi_8cpp.html#a7b35ecbbc94f7ef622b20f21f83c0fba',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi112heat_5898',['kMitsubishi112Heat',['../ir__Mitsubishi_8h.html#a260b6883e9433b466abf31618b1c4015',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112maxtemp_5899',['kMitsubishi112MaxTemp',['../ir__Mitsubishi_8h.html#afd968ea297ef8856b7266a8cc6e1bba0',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112minrepeat_5900',['kMitsubishi112MinRepeat',['../IRremoteESP8266_8h.html#a6bba58bb0f33feb9a6dfd20637d01d13',1,'IRremoteESP8266.h']]], + ['kmitsubishi112mintemp_5901',['kMitsubishi112MinTemp',['../ir__Mitsubishi_8h.html#acea288a8911a540cb9602d057eccb2a6',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112modebyte_5902',['kMitsubishi112ModeByte',['../ir__Mitsubishi_8h.html#a7e7663483fa89b4283baafba744d707a',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112modeoffset_5903',['kMitsubishi112ModeOffset',['../ir__Mitsubishi_8h.html#a39c8631bfd414738f1934eb28e74b97b',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112onespace_5904',['kMitsubishi112OneSpace',['../ir__Mitsubishi_8cpp.html#a8dd0d824826a7da007e78741015d418a',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi112powerbyte_5905',['kMitsubishi112PowerByte',['../ir__Mitsubishi_8h.html#ab09f78fee2a242dfdb0318a4caf7a2d6',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112poweroffset_5906',['kMitsubishi112PowerOffset',['../ir__Mitsubishi_8h.html#afd78de91190fa6ec8ffcc9132e3a8b35',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112statelength_5907',['kMitsubishi112StateLength',['../IRremoteESP8266_8h.html#a5ff0437b26e325bc2516a3e63c7ffe76',1,'IRremoteESP8266.h']]], + ['kmitsubishi112swinghauto_5908',['kMitsubishi112SwingHAuto',['../ir__Mitsubishi_8h.html#ab55e72c6d2b407868cda075efb24ac92',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swinghbyte_5909',['kMitsubishi112SwingHByte',['../ir__Mitsubishi_8h.html#ac149161c62c9ceee1c3a37d73930a7e8',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swinghleft_5910',['kMitsubishi112SwingHLeft',['../ir__Mitsubishi_8h.html#a8299b42b0972bda8a4bc4f32527c33e9',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swinghleftmax_5911',['kMitsubishi112SwingHLeftMax',['../ir__Mitsubishi_8h.html#a48346e97056af670454bc77a64b904bc',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swinghmiddle_5912',['kMitsubishi112SwingHMiddle',['../ir__Mitsubishi_8h.html#a7adcab7d152d84adef2059339de4bb40',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swinghoffset_5913',['kMitsubishi112SwingHOffset',['../ir__Mitsubishi_8h.html#a42f92264157e170d68046b9970a057ed',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swinghright_5914',['kMitsubishi112SwingHRight',['../ir__Mitsubishi_8h.html#a76cf277572a2b628d4a5353186ca2522',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swinghrightmax_5915',['kMitsubishi112SwingHRightMax',['../ir__Mitsubishi_8h.html#a1ff73f603b6e32075cbc9253d3090b49',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swinghsize_5916',['kMitsubishi112SwingHSize',['../ir__Mitsubishi_8h.html#a9ab977dbab987789d40fae38212f07ba',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swinghwide_5917',['kMitsubishi112SwingHWide',['../ir__Mitsubishi_8h.html#afab80db45769ab2957afc0e4799b46e5',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swingvauto_5918',['kMitsubishi112SwingVAuto',['../ir__Mitsubishi_8h.html#a1e16b172e864a74b426b1f823770cdaa',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swingvbyte_5919',['kMitsubishi112SwingVByte',['../ir__Mitsubishi_8h.html#afbcd99e59a029ccc6276c87a46d560dd',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swingvhigh_5920',['kMitsubishi112SwingVHigh',['../ir__Mitsubishi_8h.html#ab6e345e609d72f9ed903e30f3aa9a26f',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swingvhighest_5921',['kMitsubishi112SwingVHighest',['../ir__Mitsubishi_8h.html#a1cb8c62990dfb98a8ea228ad59cd88e5',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swingvlow_5922',['kMitsubishi112SwingVLow',['../ir__Mitsubishi_8h.html#a515bea322889f619d64ae96c37eaba72',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swingvlowest_5923',['kMitsubishi112SwingVLowest',['../ir__Mitsubishi_8h.html#ac4dd729a11e3ece244df6b1ddc9250f8',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swingvmiddle_5924',['kMitsubishi112SwingVMiddle',['../ir__Mitsubishi_8h.html#a0ae62480999dc4cf8a223b59938a0d68',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swingvoffset_5925',['kMitsubishi112SwingVOffset',['../ir__Mitsubishi_8h.html#ae4f3919271bb464d90a42066e8052c64',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112swingvsize_5926',['kMitsubishi112SwingVSize',['../ir__Mitsubishi_8h.html#ae4f466b64691d8aa20e66a982d65ceea',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112tempbyte_5927',['kMitsubishi112TempByte',['../ir__Mitsubishi_8h.html#a4099370512a63ae3414221ab45f05034',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112tempsize_5928',['kMitsubishi112TempSize',['../ir__Mitsubishi_8h.html#a30d0ece1b7db3558ecc03214843c9fec',1,'ir_Mitsubishi.h']]], + ['kmitsubishi112zerospace_5929',['kMitsubishi112ZeroSpace',['../ir__Mitsubishi_8cpp.html#ad70d1567dc2e4ea07a247f2555fc23b4',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi136auto_5930',['kMitsubishi136Auto',['../ir__Mitsubishi_8h.html#ae10977a0d09f4c583b03fa05720c3aed',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136bitmark_5931',['kMitsubishi136BitMark',['../ir__Mitsubishi_8cpp.html#a3aa9c715088a58a8b4a97d5038dbf6d4',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi136bits_5932',['kMitsubishi136Bits',['../IRremoteESP8266_8h.html#aa19f0122b2f906e5473a6ea232c38974',1,'IRremoteESP8266.h']]], + ['kmitsubishi136cool_5933',['kMitsubishi136Cool',['../ir__Mitsubishi_8h.html#a93332579055a07ea291b3caf9ad11944',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136dry_5934',['kMitsubishi136Dry',['../ir__Mitsubishi_8h.html#ad612c480e8664169e2b8e062d47bd8b9',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136fan_5935',['kMitsubishi136Fan',['../ir__Mitsubishi_8h.html#a4445944955b9017fcd6d1ae447f1b0d7',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136fanbyte_5936',['kMitsubishi136FanByte',['../ir__Mitsubishi_8h.html#a62166a745fdf0bbbd4b0eb114073b03e',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136fanlow_5937',['kMitsubishi136FanLow',['../ir__Mitsubishi_8h.html#af0f7177491c4cb053e6811376be956ec',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136fanmax_5938',['kMitsubishi136FanMax',['../ir__Mitsubishi_8h.html#a43a4337e20fbf4f6747a58c15213bd16',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136fanmed_5939',['kMitsubishi136FanMed',['../ir__Mitsubishi_8h.html#a73ff7df8fe65829cfd5875dc5040dec7',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136fanmin_5940',['kMitsubishi136FanMin',['../ir__Mitsubishi_8h.html#a2623eaf6e7d2ceb20ee72faddf46569e',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136fanoffset_5941',['kMitsubishi136FanOffset',['../ir__Mitsubishi_8h.html#aaa194e1e4394d3805477f4b2b78d3a81',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136fanquiet_5942',['kMitsubishi136FanQuiet',['../ir__Mitsubishi_8h.html#af2f7483bbb99216614e01dd5aedc35d5',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136fansize_5943',['kMitsubishi136FanSize',['../ir__Mitsubishi_8h.html#a3fa7836f102aa9c78d7dd287a038baee',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136gap_5944',['kMitsubishi136Gap',['../ir__Mitsubishi_8cpp.html#a3f9e0708bbe8ed3ff98a563c3ff1af2b',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi136hdrmark_5945',['kMitsubishi136HdrMark',['../ir__Mitsubishi_8cpp.html#a49c54ff757d070de54e3739b775bea00',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi136hdrspace_5946',['kMitsubishi136HdrSpace',['../ir__Mitsubishi_8cpp.html#a1ddd09e423c427b3956298c20725188a',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi136heat_5947',['kMitsubishi136Heat',['../ir__Mitsubishi_8h.html#a932f074e9348d35cea119c8141eeb7f2',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136maxtemp_5948',['kMitsubishi136MaxTemp',['../ir__Mitsubishi_8h.html#a2db420b28003dc3e05bf1c86830c61ed',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136minrepeat_5949',['kMitsubishi136MinRepeat',['../IRremoteESP8266_8h.html#a448bd7af5fdab67fb40901a3d6efed21',1,'IRremoteESP8266.h']]], + ['kmitsubishi136mintemp_5950',['kMitsubishi136MinTemp',['../ir__Mitsubishi_8h.html#a5e2e5783d33f927f941271a44d11434c',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136modebyte_5951',['kMitsubishi136ModeByte',['../ir__Mitsubishi_8h.html#a98fbde8559e82a1875235019913e859c',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136modeoffset_5952',['kMitsubishi136ModeOffset',['../ir__Mitsubishi_8h.html#a061d59096df59826d951e83594728893',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136onespace_5953',['kMitsubishi136OneSpace',['../ir__Mitsubishi_8cpp.html#a9a0cfee8b6ea94d3f798d53d30c99d5f',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi136powerbit_5954',['kMitsubishi136PowerBit',['../ir__Mitsubishi_8h.html#abbe2f7821db2a6f4696cf7f9138c509d',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136powerbyte_5955',['kMitsubishi136PowerByte',['../ir__Mitsubishi_8h.html#aca06b9d066d3f1a322bbb0f3d1a874a7',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136poweroffset_5956',['kMitsubishi136PowerOffset',['../ir__Mitsubishi_8h.html#ad235f31bc4b42548373c15e18f29e8b1',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136statelength_5957',['kMitsubishi136StateLength',['../IRremoteESP8266_8h.html#a01adbe4e1afb2ba26a5a60bf5b0b42f6',1,'IRremoteESP8266.h']]], + ['kmitsubishi136swingvauto_5958',['kMitsubishi136SwingVAuto',['../ir__Mitsubishi_8h.html#a828c2cc017cb7d00872137464d2119ae',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136swingvbyte_5959',['kMitsubishi136SwingVByte',['../ir__Mitsubishi_8h.html#ab31414515f89e94ec8b63028e215b5ad',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136swingvhigh_5960',['kMitsubishi136SwingVHigh',['../ir__Mitsubishi_8h.html#a319b36df23511aba8fb16b13eda9333b',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136swingvhighest_5961',['kMitsubishi136SwingVHighest',['../ir__Mitsubishi_8h.html#a5bd1dbb97df91dfec0f9493120ea1269',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136swingvlow_5962',['kMitsubishi136SwingVLow',['../ir__Mitsubishi_8h.html#a1ba4f3f7eb75bb54a752cfb11f196af0',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136swingvlowest_5963',['kMitsubishi136SwingVLowest',['../ir__Mitsubishi_8h.html#ab0701f0127b07780066040bc08e46a2e',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136tempbyte_5964',['kMitsubishi136TempByte',['../ir__Mitsubishi_8h.html#a22bf24adb745489a75fb877fa5cc249a',1,'ir_Mitsubishi.h']]], + ['kmitsubishi136zerospace_5965',['kMitsubishi136ZeroSpace',['../ir__Mitsubishi_8cpp.html#afaf1eca1169f492dcdd8a7266756c827',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi2bitmark_5966',['kMitsubishi2BitMark',['../ir__Mitsubishi_8cpp.html#a8b0e87a15c51c3b62c14b4e7a071207f',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi2hdrmark_5967',['kMitsubishi2HdrMark',['../ir__Mitsubishi_8cpp.html#a2d838e748f1f69165fb6b672955ea95e',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi2hdrspace_5968',['kMitsubishi2HdrSpace',['../ir__Mitsubishi_8cpp.html#acd8994a08389c8d874afcbb8eb9c0861',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi2mingap_5969',['kMitsubishi2MinGap',['../ir__Mitsubishi_8cpp.html#a7fa283a14968b582123a474c86a6fde9',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi2onespace_5970',['kMitsubishi2OneSpace',['../ir__Mitsubishi_8cpp.html#aeee614cef3e95f661dca95b344edcf64',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishi2zerospace_5971',['kMitsubishi2ZeroSpace',['../ir__Mitsubishi_8cpp.html#a665522ccd10f4c9fba39e3f8f8a5cb95',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishiacauto_5972',['kMitsubishiAcAuto',['../ir__Mitsubishi_8h.html#a1fdbdc0906594e0efebbd05110877000',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacbitmark_5973',['kMitsubishiAcBitMark',['../ir__Mitsubishi_8cpp.html#a3787c48ffff208ef964886efab7e17ca',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishiacbits_5974',['kMitsubishiACBits',['../IRremoteESP8266_8h.html#a911a47148656b26da2e094a7ced1fc8b',1,'IRremoteESP8266.h']]], + ['kmitsubishiaccool_5975',['kMitsubishiAcCool',['../ir__Mitsubishi_8h.html#a434455f6c76f0ca354b01e6a8a6479e9',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacdry_5976',['kMitsubishiAcDry',['../ir__Mitsubishi_8h.html#a9875c4b91a1b155b5f2e12370c33e031',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacextratolerance_5977',['kMitsubishiAcExtraTolerance',['../ir__Mitsubishi_8cpp.html#a98a0e4182311d584d4de4632eb491f04',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishiacfanauto_5978',['kMitsubishiAcFanAuto',['../ir__Mitsubishi_8h.html#a302cfd0468875cff23c69f71c392ad36',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacfanautooffset_5979',['kMitsubishiAcFanAutoOffset',['../ir__Mitsubishi_8h.html#ab8696268b90bf45314d712c212d68a10',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacfanmax_5980',['kMitsubishiAcFanMax',['../ir__Mitsubishi_8h.html#abbc2b87dfc6b2364d065f66f4d3e540c',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacfanoffset_5981',['kMitsubishiAcFanOffset',['../ir__Mitsubishi_8h.html#ac16a5f7fe9800006de4511fd4ac89d64',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacfanquiet_5982',['kMitsubishiAcFanQuiet',['../ir__Mitsubishi_8h.html#a90799250620dec05385b9e81cfcb83af',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacfanrealmax_5983',['kMitsubishiAcFanRealMax',['../ir__Mitsubishi_8h.html#aa28f81fbd686adb082786e7cda9a17fc',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacfansilent_5984',['kMitsubishiAcFanSilent',['../ir__Mitsubishi_8h.html#a731206548afa4f2672a78dae677f6b44',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacfansize_5985',['kMitsubishiAcFanSize',['../ir__Mitsubishi_8h.html#a565c641228d28357282b211048f1bd1c',1,'ir_Mitsubishi.h']]], + ['kmitsubishiachdrmark_5986',['kMitsubishiAcHdrMark',['../ir__Mitsubishi_8cpp.html#a11fcb08ce6bf9fa5fc50ca0e5c7d2d64',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishiachdrspace_5987',['kMitsubishiAcHdrSpace',['../ir__Mitsubishi_8cpp.html#af0af560129a4666aeba1a4a9ab59e271',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishiacheat_5988',['kMitsubishiAcHeat',['../ir__Mitsubishi_8h.html#a6107df195ecf54ec4ef97b5ab82e911c',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacmaxtemp_5989',['kMitsubishiAcMaxTemp',['../ir__Mitsubishi_8h.html#a8ba3fba3eb9dd63f5ade3cb3bd11269b',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacminrepeat_5990',['kMitsubishiACMinRepeat',['../IRremoteESP8266_8h.html#a376653a421df42d889ac3b2a071de58b',1,'IRremoteESP8266.h']]], + ['kmitsubishiacmintemp_5991',['kMitsubishiAcMinTemp',['../ir__Mitsubishi_8h.html#a2d6d53ccf446fcb03331f4e9757f4169',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacmodeoffset_5992',['kMitsubishiAcModeOffset',['../ir__Mitsubishi_8h.html#ac0037c13e3f90b7bde5a8328faaa3b9b',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacnotimer_5993',['kMitsubishiAcNoTimer',['../ir__Mitsubishi_8h.html#a0f5da97478cd6cdf2ffab161657e4ab6',1,'ir_Mitsubishi.h']]], + ['kmitsubishiaconespace_5994',['kMitsubishiAcOneSpace',['../ir__Mitsubishi_8cpp.html#abdf26b381c5288556257fabf43458775',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishiacpower_5995',['kMitsubishiAcPower',['../ir__Mitsubishi_8h.html#a864c4d936663d68f65ed4525072bd3eb',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacpoweroffset_5996',['kMitsubishiAcPowerOffset',['../ir__Mitsubishi_8h.html#a78749519549fb76a920ca447a4504e72',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacrptmark_5997',['kMitsubishiAcRptMark',['../ir__Mitsubishi_8cpp.html#a541d764aef906909a1a0d40466567c92',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishiacrptspace_5998',['kMitsubishiAcRptSpace',['../ir__Mitsubishi_8cpp.html#a4b120db1bd34c62778597abf05092d0a',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishiacstartstoptimer_5999',['kMitsubishiAcStartStopTimer',['../ir__Mitsubishi_8h.html#aecbdc43fb4bd199c47cb5125816eab59',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacstarttimer_6000',['kMitsubishiAcStartTimer',['../ir__Mitsubishi_8h.html#a4107cbc35f18204f46adb57b0fd0f09c',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacstatelength_6001',['kMitsubishiACStateLength',['../IRremoteESP8266_8h.html#a7d0d6dd6d5741f91a1afb641f11d9bc5',1,'IRremoteESP8266.h']]], + ['kmitsubishiacstoptimer_6002',['kMitsubishiAcStopTimer',['../ir__Mitsubishi_8h.html#a5e59039d523d15b145aa87222d52f2bf',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacvaneauto_6003',['kMitsubishiAcVaneAuto',['../ir__Mitsubishi_8h.html#a1caff28ea3678cc5f655fc7147c5a15e',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacvaneautomove_6004',['kMitsubishiAcVaneAutoMove',['../ir__Mitsubishi_8h.html#a2dc0b1ff66ffc21f626d7d8894a31fbb',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacvanebitoffset_6005',['kMitsubishiAcVaneBitOffset',['../ir__Mitsubishi_8h.html#a0766870a9709320cfff03d0147f8e414',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacvaneoffset_6006',['kMitsubishiAcVaneOffset',['../ir__Mitsubishi_8h.html#a2e928c1f814b71a1c346b3e987d7b857',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacvanesize_6007',['kMitsubishiAcVaneSize',['../ir__Mitsubishi_8h.html#a27d52c41a9309a89e3a2c45b87c501ff',1,'ir_Mitsubishi.h']]], + ['kmitsubishiacwidevaneauto_6008',['kMitsubishiAcWideVaneAuto',['../ir__Mitsubishi_8h.html#a2081e2b8eb778e15b7d9f2f0f332c012',1,'ir_Mitsubishi.h']]], + ['kmitsubishiaczerospace_6009',['kMitsubishiAcZeroSpace',['../ir__Mitsubishi_8cpp.html#a9481515c349154bbb6f56cec2712ba85',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishibitmark_6010',['kMitsubishiBitMark',['../ir__Mitsubishi_8cpp.html#a82c8e081b172080df14bdd6e3e6eb608',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishibitmarkticks_6011',['kMitsubishiBitMarkTicks',['../ir__Mitsubishi_8cpp.html#a6daf88606f40b13bce698c73d00f5faf',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishibits_6012',['kMitsubishiBits',['../IRremoteESP8266_8h.html#abd2187340d0b94996136081413e2ad22',1,'IRremoteESP8266.h']]], + ['kmitsubishiheavy152bits_6013',['kMitsubishiHeavy152Bits',['../IRremoteESP8266_8h.html#ab973b35583dabc7e04b12018fac04cc9',1,'IRremoteESP8266.h']]], + ['kmitsubishiheavy152fanauto_6014',['kMitsubishiHeavy152FanAuto',['../ir__MitsubishiHeavy_8h.html#ae1739c1b5cd00b28a06dfd96413570a8',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152fanecono_6015',['kMitsubishiHeavy152FanEcono',['../ir__MitsubishiHeavy_8h.html#acf0522589438103f805889e980259eb8',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152fanhigh_6016',['kMitsubishiHeavy152FanHigh',['../ir__MitsubishiHeavy_8h.html#a48881ddd596b6945d04465b3f7a9bee6',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152fanlow_6017',['kMitsubishiHeavy152FanLow',['../ir__MitsubishiHeavy_8h.html#acff7254b2ced32550ec9305dbaac3d95',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152fanmax_6018',['kMitsubishiHeavy152FanMax',['../ir__MitsubishiHeavy_8h.html#aa1e9a41137a7dd65fc049ae41856795f',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152fanmed_6019',['kMitsubishiHeavy152FanMed',['../ir__MitsubishiHeavy_8h.html#ac432324a30abcc0e664cf0ff8e974516',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152fanturbo_6020',['kMitsubishiHeavy152FanTurbo',['../ir__MitsubishiHeavy_8h.html#a7665d1ecb52afabd0dd951f2ab54e59b',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152minrepeat_6021',['kMitsubishiHeavy152MinRepeat',['../IRremoteESP8266_8h.html#a789cbb74cf332f8440a4fcdcac188741',1,'IRremoteESP8266.h']]], + ['kmitsubishiheavy152statelength_6022',['kMitsubishiHeavy152StateLength',['../IRremoteESP8266_8h.html#a31d12a44c8c3a3c4533f65b8213e2086',1,'IRremoteESP8266.h']]], + ['kmitsubishiheavy152swinghauto_6023',['kMitsubishiHeavy152SwingHAuto',['../ir__MitsubishiHeavy_8h.html#ac0ed87ce67ece78e2e9f2b49da5ba152',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swinghleft_6024',['kMitsubishiHeavy152SwingHLeft',['../ir__MitsubishiHeavy_8h.html#a1a20549b529745e913565e6d717d9f95',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swinghleftmax_6025',['kMitsubishiHeavy152SwingHLeftMax',['../ir__MitsubishiHeavy_8h.html#a970e6b602f5bbd4d560249966f6de6c9',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swinghleftright_6026',['kMitsubishiHeavy152SwingHLeftRight',['../ir__MitsubishiHeavy_8h.html#a24c71dc5a17affb2f2d136f6846befbc',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swinghmiddle_6027',['kMitsubishiHeavy152SwingHMiddle',['../ir__MitsubishiHeavy_8h.html#af1a02e21631c1efb12a01b3db065916c',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swinghoff_6028',['kMitsubishiHeavy152SwingHOff',['../ir__MitsubishiHeavy_8h.html#a246f8f9c9083f21ee22c2367ece2b9e2',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swinghright_6029',['kMitsubishiHeavy152SwingHRight',['../ir__MitsubishiHeavy_8h.html#aeec05249b3958f5a1cd629b328209e05',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swinghrightleft_6030',['kMitsubishiHeavy152SwingHRightLeft',['../ir__MitsubishiHeavy_8h.html#a43ddc14cc8707aa9743519b1c54eb776',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swinghrightmax_6031',['kMitsubishiHeavy152SwingHRightMax',['../ir__MitsubishiHeavy_8h.html#ae825ed46bf143bc6a01891a5f021c870',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swingvauto_6032',['kMitsubishiHeavy152SwingVAuto',['../ir__MitsubishiHeavy_8h.html#a31c20346b5538d74b58cb1fd499b5751',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swingvhigh_6033',['kMitsubishiHeavy152SwingVHigh',['../ir__MitsubishiHeavy_8h.html#a9ac8e39e46b43fb2276af7dd9724e3d4',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swingvhighest_6034',['kMitsubishiHeavy152SwingVHighest',['../ir__MitsubishiHeavy_8h.html#a554efbb611fd29a5d388d8195aa79993',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swingvlow_6035',['kMitsubishiHeavy152SwingVLow',['../ir__MitsubishiHeavy_8h.html#ad9a0b57ba70d318572b77236c23830a7',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swingvlowest_6036',['kMitsubishiHeavy152SwingVLowest',['../ir__MitsubishiHeavy_8h.html#a02f1b980aa78b4ff314209d16bf0a6e8',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swingvmiddle_6037',['kMitsubishiHeavy152SwingVMiddle',['../ir__MitsubishiHeavy_8h.html#ae5c3ec8b8837dddff01d71c44a4ba813',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swingvoff_6038',['kMitsubishiHeavy152SwingVOff',['../ir__MitsubishiHeavy_8h.html#abb6905210a2f4021d157eeb61eaed7cd',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swingvoffset_6039',['kMitsubishiHeavy152SwingVOffset',['../ir__MitsubishiHeavy_8h.html#ae46f3549243667bbc38d6dc058772699',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy152swingvsize_6040',['kMitsubishiHeavy152SwingVSize',['../ir__MitsubishiHeavy_8h.html#a9cf7566686359cd5d553881b5eb96131',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy3dmask_6041',['kMitsubishiHeavy3DMask',['../ir__MitsubishiHeavy_8h.html#a16dcde537c9a2b1e8ddab4d6e08abb39',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88bits_6042',['kMitsubishiHeavy88Bits',['../IRremoteESP8266_8h.html#aa80d389140df4ab7071bfb3510b35dda',1,'IRremoteESP8266.h']]], + ['kmitsubishiheavy88cleanoffset_6043',['kMitsubishiHeavy88CleanOffset',['../ir__MitsubishiHeavy_8h.html#ac0a4108b9ce94b3a85c2cb9680c98f4e',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88fanauto_6044',['kMitsubishiHeavy88FanAuto',['../ir__MitsubishiHeavy_8h.html#a607cbc27223765b3dd1f9bfd77932d0f',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88fanecono_6045',['kMitsubishiHeavy88FanEcono',['../ir__MitsubishiHeavy_8h.html#ab5fbaaffd9e0182fc7e60252f89da2c3',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88fanhigh_6046',['kMitsubishiHeavy88FanHigh',['../ir__MitsubishiHeavy_8h.html#aa45b29aaa7d8df7a34dfe6308a6b6412',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88fanlow_6047',['kMitsubishiHeavy88FanLow',['../ir__MitsubishiHeavy_8h.html#a92f0cba1aef78e5ade01c648837e7553',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88fanmed_6048',['kMitsubishiHeavy88FanMed',['../ir__MitsubishiHeavy_8h.html#aade681ee8ed4c4647a997a3caad093ea',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88fanoffset_6049',['kMitsubishiHeavy88FanOffset',['../ir__MitsubishiHeavy_8h.html#a477fe23b5b186f4386e5d0cbded98710',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88fansize_6050',['kMitsubishiHeavy88FanSize',['../ir__MitsubishiHeavy_8h.html#a68ffc738a040b3c95a839362e069fe8a',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88fanturbo_6051',['kMitsubishiHeavy88FanTurbo',['../ir__MitsubishiHeavy_8h.html#a29201ebd9395edb2660337ee00efa1dd',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88minrepeat_6052',['kMitsubishiHeavy88MinRepeat',['../IRremoteESP8266_8h.html#ad7bccde1a9b32c962c99748fb130f711',1,'IRremoteESP8266.h']]], + ['kmitsubishiheavy88statelength_6053',['kMitsubishiHeavy88StateLength',['../IRremoteESP8266_8h.html#a515e5a081c388dd4313b20ff2b6c7955',1,'IRremoteESP8266.h']]], + ['kmitsubishiheavy88swingh3d_6054',['kMitsubishiHeavy88SwingH3D',['../ir__MitsubishiHeavy_8h.html#adfeb87be0ddfc6c06bbcb4a1506d3185',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghauto_6055',['kMitsubishiHeavy88SwingHAuto',['../ir__MitsubishiHeavy_8h.html#ac39f2339ab90bdc6d9c98dd6cf95fce2',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghleft_6056',['kMitsubishiHeavy88SwingHLeft',['../ir__MitsubishiHeavy_8h.html#a32a76b07c6da2b09d04d985544d91af1',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghleftmax_6057',['kMitsubishiHeavy88SwingHLeftMax',['../ir__MitsubishiHeavy_8h.html#a83340e32cff8ca09eb7596ec55a67853',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghleftright_6058',['kMitsubishiHeavy88SwingHLeftRight',['../ir__MitsubishiHeavy_8h.html#a82f7addc930441b6e756d71ce3df24ca',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghmiddle_6059',['kMitsubishiHeavy88SwingHMiddle',['../ir__MitsubishiHeavy_8h.html#a7a4b00b2953f2bc068d83c2618484c69',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghoff_6060',['kMitsubishiHeavy88SwingHOff',['../ir__MitsubishiHeavy_8h.html#a5313aeb4115ca5a795c6ebb9871ce436',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghoffset1_6061',['kMitsubishiHeavy88SwingHOffset1',['../ir__MitsubishiHeavy_8h.html#aeefa28e96d259e4ad5b63b86abf46f39',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghoffset2_6062',['kMitsubishiHeavy88SwingHOffset2',['../ir__MitsubishiHeavy_8h.html#a9efbee563f821dad4006e8c56de9131d',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghright_6063',['kMitsubishiHeavy88SwingHRight',['../ir__MitsubishiHeavy_8h.html#a35224e254d897b9d42e16f9dae04d984',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghrightleft_6064',['kMitsubishiHeavy88SwingHRightLeft',['../ir__MitsubishiHeavy_8h.html#aa913c0f1c61260c533c66aaa12dc83ac',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghrightmax_6065',['kMitsubishiHeavy88SwingHRightMax',['../ir__MitsubishiHeavy_8h.html#a83c481d42999e377a2c50cacc28017b0',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swinghsize_6066',['kMitsubishiHeavy88SwingHSize',['../ir__MitsubishiHeavy_8h.html#a46a3cb1874cf5d1875e971094527b98f',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvauto_6067',['kMitsubishiHeavy88SwingVAuto',['../ir__MitsubishiHeavy_8h.html#a65c66f030afd2795d3132b3d0be2cabe',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvbyte5offset_6068',['kMitsubishiHeavy88SwingVByte5Offset',['../ir__MitsubishiHeavy_8h.html#adab63d1b0145cbea0953a9fdd34fd3cf',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvbyte5size_6069',['kMitsubishiHeavy88SwingVByte5Size',['../ir__MitsubishiHeavy_8h.html#ae0569562330f8c2af57a78764341c310',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvbyte7offset_6070',['kMitsubishiHeavy88SwingVByte7Offset',['../ir__MitsubishiHeavy_8h.html#a8e864258ce7f01edb3b8d4672bba6312',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvbyte7size_6071',['kMitsubishiHeavy88SwingVByte7Size',['../ir__MitsubishiHeavy_8h.html#a2e0d599b002366cc73d07f876d4fc0f7',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvhigh_6072',['kMitsubishiHeavy88SwingVHigh',['../ir__MitsubishiHeavy_8h.html#af99a8f0925f184f56080ddf3e9a37606',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvhighest_6073',['kMitsubishiHeavy88SwingVHighest',['../ir__MitsubishiHeavy_8h.html#adc2a20b5ca5dda6417c60a1a3c321fc0',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvlow_6074',['kMitsubishiHeavy88SwingVLow',['../ir__MitsubishiHeavy_8h.html#adb086c76e06cbf6c8808470363da5e93',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvlowest_6075',['kMitsubishiHeavy88SwingVLowest',['../ir__MitsubishiHeavy_8h.html#a6f4af31ee9b187648c242aca2851d3ed',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvmiddle_6076',['kMitsubishiHeavy88SwingVMiddle',['../ir__MitsubishiHeavy_8h.html#aeaddb1d80dd777c0fdd8e77661479598',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavy88swingvoff_6077',['kMitsubishiHeavy88SwingVOff',['../ir__MitsubishiHeavy_8h.html#ad29f5b94153e0fc9943a2c4c02aa1f61',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavyauto_6078',['kMitsubishiHeavyAuto',['../ir__MitsubishiHeavy_8h.html#a1bcb7429a89904e3b431aaaff20e35fa',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavybitmark_6079',['kMitsubishiHeavyBitMark',['../ir__MitsubishiHeavy_8cpp.html#a54b398e130a1893bdc81067c636d6001',1,'ir_MitsubishiHeavy.cpp']]], + ['kmitsubishiheavycleanoffset_6080',['kMitsubishiHeavyCleanOffset',['../ir__MitsubishiHeavy_8h.html#acbcff6b22bf5dee4eeb1dbccc323409a',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavycool_6081',['kMitsubishiHeavyCool',['../ir__MitsubishiHeavy_8h.html#a5d819a9a6372fde79380a6890ffd3168',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavydry_6082',['kMitsubishiHeavyDry',['../ir__MitsubishiHeavy_8h.html#a749f4d74b6cce4ad29a7ab78bb780eaf',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavyfan_6083',['kMitsubishiHeavyFan',['../ir__MitsubishiHeavy_8h.html#a55d9e0b9676da64dfdc888e7941665f8',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavyfilteroffset_6084',['kMitsubishiHeavyFilterOffset',['../ir__MitsubishiHeavy_8h.html#a32232c193503a4a6bab8f783fdebeddf',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavygap_6085',['kMitsubishiHeavyGap',['../ir__MitsubishiHeavy_8cpp.html#a92920bf4a95bccb9b55c623ff6dac96a',1,'ir_MitsubishiHeavy.cpp']]], + ['kmitsubishiheavyhdrmark_6086',['kMitsubishiHeavyHdrMark',['../ir__MitsubishiHeavy_8cpp.html#a9b1724efadc251117733297c424e76f4',1,'ir_MitsubishiHeavy.cpp']]], + ['kmitsubishiheavyhdrspace_6087',['kMitsubishiHeavyHdrSpace',['../ir__MitsubishiHeavy_8cpp.html#a9070250903c1d1653beb54ac3de27033',1,'ir_MitsubishiHeavy.cpp']]], + ['kmitsubishiheavyheat_6088',['kMitsubishiHeavyHeat',['../ir__MitsubishiHeavy_8h.html#a0b76a854d109dd0622155015edd31d74',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavymaxtemp_6089',['kMitsubishiHeavyMaxTemp',['../ir__MitsubishiHeavy_8h.html#a49abbf34671b67eb4ebbe881444180f4',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavymintemp_6090',['kMitsubishiHeavyMinTemp',['../ir__MitsubishiHeavy_8h.html#afa83fd435c67699da272b883277dbb98',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavymodeoffset_6091',['kMitsubishiHeavyModeOffset',['../ir__MitsubishiHeavy_8h.html#a2ac27d9659d3a203c8cc360bda901d10',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavynightoffset_6092',['kMitsubishiHeavyNightOffset',['../ir__MitsubishiHeavy_8h.html#a01b341211034e272bf5d4be00b88cc78',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavyonespace_6093',['kMitsubishiHeavyOneSpace',['../ir__MitsubishiHeavy_8cpp.html#adec6564e4af2886b4c7d44343d98b9dc',1,'ir_MitsubishiHeavy.cpp']]], + ['kmitsubishiheavypoweroffset_6094',['kMitsubishiHeavyPowerOffset',['../ir__MitsubishiHeavy_8h.html#a51d81b3a7d97e423858e00aecd9719c9',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavysiglength_6095',['kMitsubishiHeavySigLength',['../ir__MitsubishiHeavy_8h.html#af08e6fc65b10821e52dd4a0073033d14',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavysilentoffset_6096',['kMitsubishiHeavySilentOffset',['../ir__MitsubishiHeavy_8h.html#a9b7eb89d7a3f08e84339317d1f21ca6f',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavyzerospace_6097',['kMitsubishiHeavyZeroSpace',['../ir__MitsubishiHeavy_8cpp.html#a903c30cee53f76c7dc3d2fef74b6e4b2',1,'ir_MitsubishiHeavy.cpp']]], + ['kmitsubishiheavyzjssig_6098',['kMitsubishiHeavyZjsSig',['../ir__MitsubishiHeavy_8h.html#a01eb89bfc9d4b271a97fea566eb937ff',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishiheavyzmssig_6099',['kMitsubishiHeavyZmsSig',['../ir__MitsubishiHeavy_8h.html#a18761991123d121c8d40531d07922165',1,'ir_MitsubishiHeavy.h']]], + ['kmitsubishimincommandlength_6100',['kMitsubishiMinCommandLength',['../ir__Mitsubishi_8cpp.html#ad5a6d37e755ce1faa4cdb024d2bed26a',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishimincommandlengthticks_6101',['kMitsubishiMinCommandLengthTicks',['../ir__Mitsubishi_8cpp.html#a4f69a50c720c7a19f0ee04d262eb5948',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishimingap_6102',['kMitsubishiMinGap',['../ir__Mitsubishi_8cpp.html#a66f6379ca4c0e5f03eda2d81be0a35b2',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishimingapticks_6103',['kMitsubishiMinGapTicks',['../ir__Mitsubishi_8cpp.html#af9e8409306344cf4cd0117f2131fc67a',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishiminrepeat_6104',['kMitsubishiMinRepeat',['../IRremoteESP8266_8h.html#ad88bda81b48f25d30bb5a169d3b6bcec',1,'IRremoteESP8266.h']]], + ['kmitsubishionespace_6105',['kMitsubishiOneSpace',['../ir__Mitsubishi_8cpp.html#ab3c6a50b722402633aaf26e2a4a39ff0',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishionespaceticks_6106',['kMitsubishiOneSpaceTicks',['../ir__Mitsubishi_8cpp.html#a3b12f2aa2c3b4b7ef439f86356aab9cf',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishitick_6107',['kMitsubishiTick',['../ir__Mitsubishi_8cpp.html#a5197eb8b6e8de8fdfb9f056b6f7d9aa5',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishizerospace_6108',['kMitsubishiZeroSpace',['../ir__Mitsubishi_8cpp.html#a9660ac382e9a929f6acb73a32b2a1a3c',1,'ir_Mitsubishi.cpp']]], + ['kmitsubishizerospaceticks_6109',['kMitsubishiZeroSpaceTicks',['../ir__Mitsubishi_8cpp.html#a18f364a0ba491236538bc9d086303d69',1,'ir_Mitsubishi.cpp']]], + ['kmodebitssize_6110',['kModeBitsSize',['../IRutils_8h.html#a5432915ab86062fceadc067a233f1627',1,'IRutils.h']]], + ['kmodelstr_6111',['kModelStr',['../IRtext_8cpp.html#a40905418e2934e539c50c6cfc2c4ffe3',1,'kModelStr(): IRtext.cpp'],['../IRtext_8h.html#a4a553cfcc7ca2a8cea8e1263f5f6c186',1,'kModelStr(): IRtext.cpp']]], + ['kmodestr_6112',['kModeStr',['../IRtext_8cpp.html#a7260c578d290c33b7705cd1439d992ee',1,'kModeStr(): IRtext.cpp'],['../IRtext_8h.html#a6666695e388b607bfd3bb0e6efd4193f',1,'kModeStr(): IRtext.cpp']]], + ['kmouldstr_6113',['kMouldStr',['../IRtext_8cpp.html#ac665ea584a4949565aa35629d791dbc5',1,'kMouldStr(): IRtext.cpp'],['../IRtext_8h.html#a693b29e4764d959dac781a0992f2bf30',1,'kMouldStr(): IRtext.cpp']]], + ['kmovestr_6114',['kMoveStr',['../IRtext_8cpp.html#a321f98699209fb487287c4911a0c0200',1,'kMoveStr(): IRtext.cpp'],['../IRtext_8h.html#ae99940df2a9243fd7fe6f3814c0802dd',1,'kMoveStr(): IRtext.cpp']]], + ['kmultibracketsbits_6115',['kMultibracketsBits',['../IRremoteESP8266_8h.html#aad7be0971479839493615cafcd654fc1',1,'IRremoteESP8266.h']]], + ['kmultibracketsdefaultrepeat_6116',['kMultibracketsDefaultRepeat',['../IRremoteESP8266_8h.html#a5aa418baefd018d5facc08d3bb721fe9',1,'IRremoteESP8266.h']]], + ['kmultibracketsfooterspace_6117',['kMultibracketsFooterSpace',['../ir__Multibrackets_8cpp.html#a738cde2d6a25611bea116d04375dd28a',1,'ir_Multibrackets.cpp']]], + ['kmultibracketsfreq_6118',['kMultibracketsFreq',['../ir__Multibrackets_8cpp.html#a38ba01a3c516f6018199aa9031a5fb4a',1,'ir_Multibrackets.cpp']]], + ['kmultibracketshdrmark_6119',['kMultibracketsHdrMark',['../ir__Multibrackets_8cpp.html#a4eaafbf701604ceb6591b8a8b9c1d202',1,'ir_Multibrackets.cpp']]], + ['kmultibracketstick_6120',['kMultibracketsTick',['../ir__Multibrackets_8cpp.html#aa528fbf06b8d5293d82b7efc2bcd1e9b',1,'ir_Multibrackets.cpp']]], + ['kmultibracketstolerance_6121',['kMultibracketsTolerance',['../ir__Multibrackets_8cpp.html#a242017fb86f015cdecbf31c278c43ccc',1,'ir_Multibrackets.cpp']]], + ['kmwmdelta_6122',['kMWMDelta',['../ir__MWM_8cpp.html#a4e32849a3c799af002d1290a8a33366e',1,'ir_MWM.cpp']]], + ['kmwmexcess_6123',['kMWMExcess',['../ir__MWM_8cpp.html#ab3ff88bfc09c94e70fb74a77dbdd87d7',1,'ir_MWM.cpp']]], + ['kmwmmaxwidth_6124',['kMWMMaxWidth',['../ir__MWM_8cpp.html#a833013dcb331ebce3b885b0ce73c9eaa',1,'ir_MWM.cpp']]], + ['kmwmmingap_6125',['kMWMMinGap',['../ir__MWM_8cpp.html#a4d1f9c5442390a5ba089270c1187e917',1,'ir_MWM.cpp']]], + ['kmwmminsamples_6126',['kMWMMinSamples',['../ir__MWM_8cpp.html#ad386c922a0fcbd0c5b904b9abdd8d582',1,'ir_MWM.cpp']]], + ['kmwmtick_6127',['kMWMTick',['../ir__MWM_8cpp.html#a42c39c0101ccad1e88fa206a26447256',1,'ir_MWM.cpp']]], + ['kmwmtolerance_6128',['kMWMTolerance',['../ir__MWM_8cpp.html#ae3a91ec66f51f50810229b4adc1264fd',1,'ir_MWM.cpp']]], + ['knastr_6129',['kNAStr',['../IRtext_8cpp.html#a1757349137713553454f405872bc4dcd',1,'kNAStr(): IRtext.cpp'],['../IRtext_8h.html#a5d094344fba1715dbde69ff947775264',1,'kNAStr(): IRtext.cpp']]], + ['knecbitmark_6130',['kNecBitMark',['../ir__NEC_8h.html#ab536a800ec8f7259fe7e485ea4aea465',1,'ir_NEC.h']]], + ['knecbitmarkticks_6131',['kNecBitMarkTicks',['../ir__NEC_8h.html#a84ca60f84d64d65872b40a87819eccc1',1,'ir_NEC.h']]], + ['knecbits_6132',['kNECBits',['../IRremoteESP8266_8h.html#a65e03baf646815b4b02f943bdd74a097',1,'IRremoteESP8266.h']]], + ['knechdrmark_6133',['kNecHdrMark',['../ir__NEC_8h.html#ac727ede47d30ec76b03e4a41b48ce8c7',1,'ir_NEC.h']]], + ['knechdrmarkticks_6134',['kNecHdrMarkTicks',['../ir__NEC_8h.html#ab1486c07a09bc4324c03b1c887f5c5f7',1,'ir_NEC.h']]], + ['knechdrspace_6135',['kNecHdrSpace',['../ir__NEC_8h.html#a8279410369d6ed266502615d3ff1750b',1,'ir_NEC.h']]], + ['knechdrspaceticks_6136',['kNecHdrSpaceTicks',['../ir__NEC_8h.html#a4470ee927c0c3447bdda20c52b0f8566',1,'ir_NEC.h']]], + ['knecmincommandlength_6137',['kNecMinCommandLength',['../ir__NEC_8h.html#ac7b8d897d9e5bbf29b9b1b899a2ef7d8',1,'ir_NEC.h']]], + ['knecmincommandlengthticks_6138',['kNecMinCommandLengthTicks',['../ir__NEC_8h.html#a78e411960e643495987b1cb53268bc46',1,'ir_NEC.h']]], + ['knecmingap_6139',['kNecMinGap',['../ir__NEC_8h.html#a3d6ecc128599df57dc98e97e51b2264e',1,'ir_NEC.h']]], + ['knecmingapticks_6140',['kNecMinGapTicks',['../ir__NEC_8h.html#a2e6d938510a34aa1217a56aa51ece9f5',1,'ir_NEC.h']]], + ['kneconespace_6141',['kNecOneSpace',['../ir__NEC_8h.html#af57080e9b7513d1c8e7e781f3d502fbd',1,'ir_NEC.h']]], + ['kneconespaceticks_6142',['kNecOneSpaceTicks',['../ir__NEC_8h.html#a2f1e5412d44816f92e4b6c72e16e8b1f',1,'ir_NEC.h']]], + ['knecrptlength_6143',['kNecRptLength',['../ir__NEC_8h.html#af4ab20595dfda177fbb06dd821ea14c7',1,'ir_NEC.h']]], + ['knecrptspace_6144',['kNecRptSpace',['../ir__NEC_8h.html#a9538478446b1ae5d72c8366dd6a11673',1,'ir_NEC.h']]], + ['knecrptspaceticks_6145',['kNecRptSpaceTicks',['../ir__NEC_8h.html#a91b5296d480008a4b44c5b084756f04b',1,'ir_NEC.h']]], + ['knectick_6146',['kNecTick',['../ir__NEC_8h.html#abe1ec110798236c7b626f7efe4cc5657',1,'ir_NEC.h']]], + ['kneczerospace_6147',['kNecZeroSpace',['../ir__NEC_8h.html#a00573a6bdb348339b9898173b644b693',1,'ir_NEC.h']]], + ['kneczerospaceticks_6148',['kNecZeroSpaceTicks',['../ir__NEC_8h.html#a80f316535d761c64f1d5752ef80a65ff',1,'ir_NEC.h']]], + ['kneoclima8cheatoffset_6149',['kNeoclima8CHeatOffset',['../ir__Neoclima_8h.html#a4e9654ac35708a22912448eef3eb2b35',1,'ir_Neoclima.h']]], + ['kneoclimaauto_6150',['kNeoclimaAuto',['../ir__Neoclima_8h.html#a4574742c21aae9aafaff9b10f9423006',1,'ir_Neoclima.h']]], + ['kneoclimabitmark_6151',['kNeoclimaBitMark',['../ir__Neoclima_8cpp.html#ae34236a830ec2d200575ac33fda43689',1,'ir_Neoclima.cpp']]], + ['kneoclimabits_6152',['kNeoclimaBits',['../IRremoteESP8266_8h.html#afff9132e57296b4d7e04ec9e1e5ab04f',1,'IRremoteESP8266.h']]], + ['kneoclimabutton8cheat_6153',['kNeoclimaButton8CHeat',['../ir__Neoclima_8h.html#ad337d964ff800bea5c55f1fe69dfb7ff',1,'ir_Neoclima.h']]], + ['kneoclimabuttonairflow_6154',['kNeoclimaButtonAirFlow',['../ir__Neoclima_8h.html#ab5fff838f8e5ac9ff213fc69346ffa7c',1,'ir_Neoclima.h']]], + ['kneoclimabuttoneye_6155',['kNeoclimaButtonEye',['../ir__Neoclima_8h.html#a6cabdccd3c8d52cb2817f99454bdc884',1,'ir_Neoclima.h']]], + ['kneoclimabuttonfanspeed_6156',['kNeoclimaButtonFanSpeed',['../ir__Neoclima_8h.html#ab41ffd863516b79b6c7e9b69e7d5a272',1,'ir_Neoclima.h']]], + ['kneoclimabuttonfollow_6157',['kNeoclimaButtonFollow',['../ir__Neoclima_8h.html#a592017dce3bfa4ea2f0f341a818aff72',1,'ir_Neoclima.h']]], + ['kneoclimabuttonfresh_6158',['kNeoclimaButtonFresh',['../ir__Neoclima_8h.html#a6a965f2dc7860879ccaf410405095e9c',1,'ir_Neoclima.h']]], + ['kneoclimabuttonhold_6159',['kNeoclimaButtonHold',['../ir__Neoclima_8h.html#aada6fdb6572bd7d841de89f1d1eed3fe',1,'ir_Neoclima.h']]], + ['kneoclimabuttonion_6160',['kNeoclimaButtonIon',['../ir__Neoclima_8h.html#a05dccf1c19237d315bb78f387f8fd57f',1,'ir_Neoclima.h']]], + ['kneoclimabuttonlight_6161',['kNeoclimaButtonLight',['../ir__Neoclima_8h.html#ac66b472b31f6183f4615584561baa284',1,'ir_Neoclima.h']]], + ['kneoclimabuttonmode_6162',['kNeoclimaButtonMode',['../ir__Neoclima_8h.html#a4cfee4b0898f1504be5cbd129cd99278',1,'ir_Neoclima.h']]], + ['kneoclimabuttonoffset_6163',['kNeoclimaButtonOffset',['../ir__Neoclima_8h.html#a08ae86c15defd78ecac0f322f84190d3',1,'ir_Neoclima.h']]], + ['kneoclimabuttonpower_6164',['kNeoclimaButtonPower',['../ir__Neoclima_8h.html#a047d19978c58b35dcd6a069fce04af87',1,'ir_Neoclima.h']]], + ['kneoclimabuttonsize_6165',['kNeoclimaButtonSize',['../ir__Neoclima_8h.html#aac90dbf9fe499df2edf64df44f449e57',1,'ir_Neoclima.h']]], + ['kneoclimabuttonsleep_6166',['kNeoclimaButtonSleep',['../ir__Neoclima_8h.html#adcbe2a89eecf41fe1fe2b8c62428084e',1,'ir_Neoclima.h']]], + ['kneoclimabuttonswing_6167',['kNeoclimaButtonSwing',['../ir__Neoclima_8h.html#aeea180bef85a40d8c7fe3f5facf7b199',1,'ir_Neoclima.h']]], + ['kneoclimabuttontempdown_6168',['kNeoclimaButtonTempDown',['../ir__Neoclima_8h.html#aee91f1ebdf89b6fe9f3b31937d1185a0',1,'ir_Neoclima.h']]], + ['kneoclimabuttontempup_6169',['kNeoclimaButtonTempUp',['../ir__Neoclima_8h.html#abb093132f77d179ab02fc4a022d55236',1,'ir_Neoclima.h']]], + ['kneoclimabuttonturbo_6170',['kNeoclimaButtonTurbo',['../ir__Neoclima_8h.html#af156d94f9e47e8b5e2e2493308cca04c',1,'ir_Neoclima.h']]], + ['kneoclimacool_6171',['kNeoclimaCool',['../ir__Neoclima_8h.html#ac5d874e5ffce72ce68176f38e780c439',1,'ir_Neoclima.h']]], + ['kneoclimadry_6172',['kNeoclimaDry',['../ir__Neoclima_8h.html#ab68ba4480e1bcb685579c5f902d0709e',1,'ir_Neoclima.h']]], + ['kneoclimaeyeoffset_6173',['kNeoclimaEyeOffset',['../ir__Neoclima_8h.html#ad7baeea22b87a69150c65b2c049ee0b2',1,'ir_Neoclima.h']]], + ['kneoclimafan_6174',['kNeoclimaFan',['../ir__Neoclima_8h.html#aa6166bd65d80a708d790dbf703c83ea2',1,'ir_Neoclima.h']]], + ['kneoclimafanauto_6175',['kNeoclimaFanAuto',['../ir__Neoclima_8h.html#a7885fdbc4ae3336aac74d7ee3d8c3258',1,'ir_Neoclima.h']]], + ['kneoclimafanhigh_6176',['kNeoclimaFanHigh',['../ir__Neoclima_8h.html#a57ddf91c1cbb157b3a53b1082bac2d75',1,'ir_Neoclima.h']]], + ['kneoclimafanlow_6177',['kNeoclimaFanLow',['../ir__Neoclima_8h.html#ac9031328be51a46543ebd4360aaca55a',1,'ir_Neoclima.h']]], + ['kneoclimafanmed_6178',['kNeoclimaFanMed',['../ir__Neoclima_8h.html#a11faf2a34faf44460795b50bfbdab402',1,'ir_Neoclima.h']]], + ['kneoclimafanoffest_6179',['kNeoclimaFanOffest',['../ir__Neoclima_8h.html#a32f614475b5f00f8ccdf12498c519713',1,'ir_Neoclima.h']]], + ['kneoclimafansize_6180',['kNeoclimaFanSize',['../ir__Neoclima_8h.html#a888cbc3f0a38137cb909188b6fff91b1',1,'ir_Neoclima.h']]], + ['kneoclimafollowme_6181',['kNeoclimaFollowMe',['../ir__Neoclima_8h.html#a493c1e6b8b8909f4201cd506a1f4804a',1,'ir_Neoclima.h']]], + ['kneoclimafreshoffset_6182',['kNeoclimaFreshOffset',['../ir__Neoclima_8h.html#af19f0f77ece049bdef26930be1b0309f',1,'ir_Neoclima.h']]], + ['kneoclimahdrmark_6183',['kNeoclimaHdrMark',['../ir__Neoclima_8cpp.html#aa392821c0ce822a7b7d67efd202bedd5',1,'ir_Neoclima.cpp']]], + ['kneoclimahdrspace_6184',['kNeoclimaHdrSpace',['../ir__Neoclima_8cpp.html#a3714ad66d75162ccb286152b70375588',1,'ir_Neoclima.cpp']]], + ['kneoclimaheat_6185',['kNeoclimaHeat',['../ir__Neoclima_8h.html#a5a5e53801c0f8e554c391ed56404b926',1,'ir_Neoclima.h']]], + ['kneoclimaholdoffset_6186',['kNeoclimaHoldOffset',['../ir__Neoclima_8h.html#a3a91e7504c7820223021dcc2cbbf9f2a',1,'ir_Neoclima.h']]], + ['kneoclimaionoffset_6187',['kNeoclimaIonOffset',['../ir__Neoclima_8h.html#ad420932425fbe261368938e604dfb0c1',1,'ir_Neoclima.h']]], + ['kneoclimalightoffset_6188',['kNeoclimaLightOffset',['../ir__Neoclima_8h.html#af58a863257c5d436b299ac8cbcb57686',1,'ir_Neoclima.h']]], + ['kneoclimamaxtemp_6189',['kNeoclimaMaxTemp',['../ir__Neoclima_8h.html#a755ef8290df8a3e19f236839bee42412',1,'ir_Neoclima.h']]], + ['kneoclimamingap_6190',['kNeoclimaMinGap',['../ir__Neoclima_8cpp.html#a0e54c73eff563f6c3ec39a0951dd3d2d',1,'ir_Neoclima.cpp']]], + ['kneoclimaminrepeat_6191',['kNeoclimaMinRepeat',['../IRremoteESP8266_8h.html#a16fc26a3ff66a66068ac9638554df847',1,'IRremoteESP8266.h']]], + ['kneoclimamintemp_6192',['kNeoclimaMinTemp',['../ir__Neoclima_8h.html#adc979ad2ac64481f13b1085b1fdd13c4',1,'ir_Neoclima.h']]], + ['kneoclimamodeoffset_6193',['kNeoclimaModeOffset',['../ir__Neoclima_8h.html#a823a960610ef3387099d2a2103dd0b56',1,'ir_Neoclima.h']]], + ['kneoclimaonespace_6194',['kNeoclimaOneSpace',['../ir__Neoclima_8cpp.html#a5fd5f3b7f04134190aafc65762528da0',1,'ir_Neoclima.cpp']]], + ['kneoclimapoweroffset_6195',['kNeoclimaPowerOffset',['../ir__Neoclima_8h.html#a9b881e5400fe9bcd3b1422aeb355cf7c',1,'ir_Neoclima.h']]], + ['kneoclimasleepoffset_6196',['kNeoclimaSleepOffset',['../ir__Neoclima_8h.html#ac0c978cdc30827c7390b93a9a4f05d24',1,'ir_Neoclima.h']]], + ['kneoclimastatelength_6197',['kNeoclimaStateLength',['../IRremoteESP8266_8h.html#a5a871ed6d145c5ea3d50e96600c02e31',1,'IRremoteESP8266.h']]], + ['kneoclimaswinghoffset_6198',['kNeoclimaSwingHOffset',['../ir__Neoclima_8h.html#a5f2e8ccaa590386b0947b0f291ebcb09',1,'ir_Neoclima.h']]], + ['kneoclimaswingvoff_6199',['kNeoclimaSwingVOff',['../ir__Neoclima_8h.html#ad230a8c18e6edb5709cb29033f1fd221',1,'ir_Neoclima.h']]], + ['kneoclimaswingvoffset_6200',['kNeoclimaSwingVOffset',['../ir__Neoclima_8h.html#a91b63c4712093684625a16c76bcc6784',1,'ir_Neoclima.h']]], + ['kneoclimaswingvon_6201',['kNeoclimaSwingVOn',['../ir__Neoclima_8h.html#a7021804eb30e7a7c5b9c9ababb1b8cad',1,'ir_Neoclima.h']]], + ['kneoclimaswingvsize_6202',['kNeoclimaSwingVSize',['../ir__Neoclima_8h.html#ab4b49ec2c326d0e94eba23e7a93b6fc6',1,'ir_Neoclima.h']]], + ['kneoclimatempoffset_6203',['kNeoclimaTempOffset',['../ir__Neoclima_8h.html#a5c3470f6c773b4c557e6996f8c29a573',1,'ir_Neoclima.h']]], + ['kneoclimatempsize_6204',['kNeoclimaTempSize',['../ir__Neoclima_8h.html#af848fc3f4ce46c8786fd2b3e129b1e48',1,'ir_Neoclima.h']]], + ['kneoclimaturbooffset_6205',['kNeoclimaTurboOffset',['../ir__Neoclima_8h.html#ae23c6faf5f54ff12d592360b42d69971',1,'ir_Neoclima.h']]], + ['kneoclimazerospace_6206',['kNeoclimaZeroSpace',['../ir__Neoclima_8cpp.html#a0b98d84da4651d8d31f8f1d84621c21e',1,'ir_Neoclima.cpp']]], + ['knibblesize_6207',['kNibbleSize',['../IRutils_8h.html#aa72cd082cdde3d8d7473ed9d11ff6846',1,'IRutils.h']]], + ['knightstr_6208',['kNightStr',['../IRtext_8cpp.html#a01908d3c0f79bc015a699fc0576a8771',1,'kNightStr(): IRtext.cpp'],['../IRtext_8h.html#afe6519eaae5b1fb4d110529ce98f05b0',1,'kNightStr(): IRtext.cpp']]], + ['knikaibitmark_6209',['kNikaiBitMark',['../ir__Nikai_8cpp.html#ad665145b0ee9cc722d9fde43cbd3fd82',1,'ir_Nikai.cpp']]], + ['knikaibitmarkticks_6210',['kNikaiBitMarkTicks',['../ir__Nikai_8cpp.html#ac10d1b4c45af3ddbf3c50b85dbb0c2f0',1,'ir_Nikai.cpp']]], + ['knikaibits_6211',['kNikaiBits',['../IRremoteESP8266_8h.html#a9fce002592f9e2488b1b717d0b1a6a40',1,'IRremoteESP8266.h']]], + ['knikaihdrmark_6212',['kNikaiHdrMark',['../ir__Nikai_8cpp.html#ae0656b931e18e6e011a7c74cfaf4384b',1,'ir_Nikai.cpp']]], + ['knikaihdrmarkticks_6213',['kNikaiHdrMarkTicks',['../ir__Nikai_8cpp.html#a11671cee9a312ece8f1c90596eddd7ac',1,'ir_Nikai.cpp']]], + ['knikaihdrspace_6214',['kNikaiHdrSpace',['../ir__Nikai_8cpp.html#ae801e20e669f3039888bf48074988b84',1,'ir_Nikai.cpp']]], + ['knikaihdrspaceticks_6215',['kNikaiHdrSpaceTicks',['../ir__Nikai_8cpp.html#a83885a2fc573f947afe5015cd2f4d953',1,'ir_Nikai.cpp']]], + ['knikaimingap_6216',['kNikaiMinGap',['../ir__Nikai_8cpp.html#ad88846eaa7559df7fb944283fd292da1',1,'ir_Nikai.cpp']]], + ['knikaimingapticks_6217',['kNikaiMinGapTicks',['../ir__Nikai_8cpp.html#afdf938a763f30e3c5e534eba269dff1f',1,'ir_Nikai.cpp']]], + ['knikaionespace_6218',['kNikaiOneSpace',['../ir__Nikai_8cpp.html#a4bb69ab22b2abcd20ffff90f9267fa43',1,'ir_Nikai.cpp']]], + ['knikaionespaceticks_6219',['kNikaiOneSpaceTicks',['../ir__Nikai_8cpp.html#a25a4d289b7fad06c31312df552ee81ab',1,'ir_Nikai.cpp']]], + ['knikaitick_6220',['kNikaiTick',['../ir__Nikai_8cpp.html#a70eb8953509420081d0a294203eeb34b',1,'ir_Nikai.cpp']]], + ['knikaizerospace_6221',['kNikaiZeroSpace',['../ir__Nikai_8cpp.html#aa9af57c5c936107b00096e16cc6f57d9',1,'ir_Nikai.cpp']]], + ['knikaizerospaceticks_6222',['kNikaiZeroSpaceTicks',['../ir__Nikai_8cpp.html#a8df777a744c018e27c6969c2109d6d79',1,'ir_Nikai.cpp']]], + ['knorepeat_6223',['kNoRepeat',['../IRremoteESP8266_8h.html#a1a49dde7ffbd753f7756cf0c9dc6d826',1,'IRremoteESP8266.h']]], + ['knostr_6224',['kNoStr',['../IRtext_8cpp.html#a07897ceb4a6607d87ef37a517908a4b5',1,'kNoStr(): IRtext.cpp'],['../IRtext_8h.html#a51c9fb58ee7d01e96e2571018aea746d',1,'kNoStr(): IRtext.cpp']]], + ['knowstr_6225',['kNowStr',['../IRtext_8cpp.html#a09d8590020bcf998746528d0e50f7a20',1,'kNowStr(): IRtext.cpp'],['../IRtext_8h.html#a6a3c0965a32c36d9b5aa4918b473cc12',1,'kNowStr(): IRtext.cpp']]], + ['koffstr_6226',['kOffStr',['../IRtext_8cpp.html#a9ce19a214db45b8cff83032ffa1ccdd8',1,'kOffStr(): IRtext.cpp'],['../IRtext_8h.html#a95f119413a113c9a2e8c246892b8c52a',1,'kOffStr(): IRtext.cpp']]], + ['kofftimerstr_6227',['kOffTimerStr',['../IRtext_8cpp.html#ae5faab97b26f9e877f79f49002bbba2c',1,'kOffTimerStr(): IRtext.cpp'],['../IRtext_8h.html#a818275085f8a8d7c083b66f081689b1f',1,'kOffTimerStr(): IRtext.cpp']]], + ['konstr_6228',['kOnStr',['../IRtext_8cpp.html#ab3f42c8df156baa46326a57193f78c51',1,'kOnStr(): IRtext.cpp'],['../IRtext_8h.html#aaf4ffad7f827a2ce8512e644bc9c25c7',1,'kOnStr(): IRtext.cpp']]], + ['kontimerstr_6229',['kOnTimerStr',['../IRtext_8cpp.html#adaecb1b5526f2bb3a1334e816a414273',1,'kOnTimerStr(): IRtext.cpp'],['../IRtext_8h.html#a9f355a0d834790287d95eea30b57564d',1,'kOnTimerStr(): IRtext.cpp']]], + ['koutsidequietstr_6230',['kOutsideQuietStr',['../IRtext_8cpp.html#a103f2a8a2a6d351cd8ea259de3c454ef',1,'kOutsideQuietStr(): IRtext.cpp'],['../IRtext_8h.html#afaf12ae53365f790b47ff3790e94cc1c',1,'kOutsideQuietStr(): IRtext.cpp']]], + ['koutsidestr_6231',['kOutsideStr',['../IRtext_8cpp.html#a8465ee1e8b1e5dd58a9cf872c9569e01',1,'kOutsideStr(): IRtext.cpp'],['../IRtext_8h.html#ada5c81e0fcc4073d6f51e7447e8c5da0',1,'kOutsideStr(): IRtext.cpp']]], + ['kpanasonicacauto_6232',['kPanasonicAcAuto',['../ir__Panasonic_8h.html#aa7c839a4342205c384870e8a4f5ec36b',1,'ir_Panasonic.h']]], + ['kpanasonicacbits_6233',['kPanasonicAcBits',['../IRremoteESP8266_8h.html#a210f5c78b0f90b64dd5037698141433a',1,'IRremoteESP8266.h']]], + ['kpanasonicacchecksuminit_6234',['kPanasonicAcChecksumInit',['../ir__Panasonic_8h.html#a49329b4fef403696effcbcc5c8a86cd2',1,'ir_Panasonic.h']]], + ['kpanasonicaccool_6235',['kPanasonicAcCool',['../ir__Panasonic_8h.html#acfaa3d61fbb13fc6cd8d354f1c0a8dc7',1,'ir_Panasonic.h']]], + ['kpanasonicacdefaultrepeat_6236',['kPanasonicAcDefaultRepeat',['../IRremoteESP8266_8h.html#af6b7c6ad564253cb128ac92c00e86f0c',1,'IRremoteESP8266.h']]], + ['kpanasonicacdry_6237',['kPanasonicAcDry',['../ir__Panasonic_8h.html#a2d211bd2150a67819453f3220dc0cc91',1,'ir_Panasonic.h']]], + ['kpanasonicacexcess_6238',['kPanasonicAcExcess',['../ir__Panasonic_8h.html#adde8b69377faa9a4566dc15e95711257',1,'ir_Panasonic.h']]], + ['kpanasonicacfan_6239',['kPanasonicAcFan',['../ir__Panasonic_8h.html#a87e4dd423bbd1f879a9d5da31e1fea5e',1,'ir_Panasonic.h']]], + ['kpanasonicacfanauto_6240',['kPanasonicAcFanAuto',['../ir__Panasonic_8h.html#a7d4486fd68969af4f7230f12e865c698',1,'ir_Panasonic.h']]], + ['kpanasonicacfandelta_6241',['kPanasonicAcFanDelta',['../ir__Panasonic_8h.html#a2210f85a17fba2bbdfbb883e9fb57e52',1,'ir_Panasonic.h']]], + ['kpanasonicacfanmax_6242',['kPanasonicAcFanMax',['../ir__Panasonic_8h.html#aa4599c84d72ab9c622b642870efb9cf1',1,'ir_Panasonic.h']]], + ['kpanasonicacfanmed_6243',['kPanasonicAcFanMed',['../ir__Panasonic_8h.html#a978004e8e2c4122fec81c5a972b842a0',1,'ir_Panasonic.h']]], + ['kpanasonicacfanmin_6244',['kPanasonicAcFanMin',['../ir__Panasonic_8h.html#a450c7951a525817d27351fb7c8ff2df9',1,'ir_Panasonic.h']]], + ['kpanasonicacfanmodetemp_6245',['kPanasonicAcFanModeTemp',['../ir__Panasonic_8h.html#a76543f9d81c2d109e04359f0c61dcb99',1,'ir_Panasonic.h']]], + ['kpanasonicacheat_6246',['kPanasonicAcHeat',['../ir__Panasonic_8h.html#ac37bb7dd975a9aa803edfc108a5071ed',1,'ir_Panasonic.h']]], + ['kpanasonicacionfilterbyte_6247',['kPanasonicAcIonFilterByte',['../ir__Panasonic_8h.html#a16c946660d2ee3821dd2e30a69144a38',1,'ir_Panasonic.h']]], + ['kpanasonicacionfilteroffset_6248',['kPanasonicAcIonFilterOffset',['../ir__Panasonic_8h.html#a5c1b18d1b834e9d46cbd29c74a1b8269',1,'ir_Panasonic.h']]], + ['kpanasonicacmaxtemp_6249',['kPanasonicAcMaxTemp',['../ir__Panasonic_8h.html#a95fe6bc5b2565bf29d1a6dcee2f0c39f',1,'ir_Panasonic.h']]], + ['kpanasonicacmessagegap_6250',['kPanasonicAcMessageGap',['../ir__Panasonic_8cpp.html#a962cde97e8d98ad32f0b59172b641d6d',1,'ir_Panasonic.cpp']]], + ['kpanasonicacmintemp_6251',['kPanasonicAcMinTemp',['../ir__Panasonic_8h.html#a7861e8477904e1a572bcf35286fd3733',1,'ir_Panasonic.h']]], + ['kpanasonicacofftimeroffset_6252',['kPanasonicAcOffTimerOffset',['../ir__Panasonic_8h.html#a477b61044f1db5c296f13a404c536046',1,'ir_Panasonic.h']]], + ['kpanasonicacontimeroffset_6253',['kPanasonicAcOnTimerOffset',['../ir__Panasonic_8h.html#a64350202f82aabfd1673f0dda4d3c13d',1,'ir_Panasonic.h']]], + ['kpanasonicacpowerfulckpoffset_6254',['kPanasonicAcPowerfulCkpOffset',['../ir__Panasonic_8h.html#aa839301a08c8e49548f497e786dbb6fa',1,'ir_Panasonic.h']]], + ['kpanasonicacpowerfuloffset_6255',['kPanasonicAcPowerfulOffset',['../ir__Panasonic_8h.html#a27e9b1af4b65830015576beed69cb27d',1,'ir_Panasonic.h']]], + ['kpanasonicacpoweroffset_6256',['kPanasonicAcPowerOffset',['../ir__Panasonic_8h.html#a9e9b3d0c77ef93ab472ce14ed1534c77',1,'ir_Panasonic.h']]], + ['kpanasonicacquietckpoffset_6257',['kPanasonicAcQuietCkpOffset',['../ir__Panasonic_8h.html#a5a3779cd6fd8d573ae14ed4a6d676dba',1,'ir_Panasonic.h']]], + ['kpanasonicacquietoffset_6258',['kPanasonicAcQuietOffset',['../ir__Panasonic_8h.html#a1ec8db8798f79dead05233ee6333700d',1,'ir_Panasonic.h']]], + ['kpanasonicacsection1length_6259',['kPanasonicAcSection1Length',['../ir__Panasonic_8cpp.html#a34c6c085d468ed4b35f814452335d334',1,'ir_Panasonic.cpp']]], + ['kpanasonicacsectiongap_6260',['kPanasonicAcSectionGap',['../ir__Panasonic_8cpp.html#a3cf28f1268e8a35da220d42deda7c456',1,'ir_Panasonic.cpp']]], + ['kpanasonicacshortbits_6261',['kPanasonicAcShortBits',['../IRremoteESP8266_8h.html#a2fd1f84669f7994bb3c235a508333c6c',1,'IRremoteESP8266.h']]], + ['kpanasonicacstatelength_6262',['kPanasonicAcStateLength',['../IRremoteESP8266_8h.html#ab21d86545b57738354e7a3b833d38f94',1,'IRremoteESP8266.h']]], + ['kpanasonicacstateshortlength_6263',['kPanasonicAcStateShortLength',['../IRremoteESP8266_8h.html#a0a6ca8c1dfa6f313421ddf268d76d8e6',1,'IRremoteESP8266.h']]], + ['kpanasonicacswinghauto_6264',['kPanasonicAcSwingHAuto',['../ir__Panasonic_8h.html#a91e2933692ad98acf054c7a69f6c2018',1,'ir_Panasonic.h']]], + ['kpanasonicacswinghfullleft_6265',['kPanasonicAcSwingHFullLeft',['../ir__Panasonic_8h.html#abf1d8c53a1b69d99019c6878f9ec220d',1,'ir_Panasonic.h']]], + ['kpanasonicacswinghfullright_6266',['kPanasonicAcSwingHFullRight',['../ir__Panasonic_8h.html#a0e1b7a7591a0f14b2f8be3cb222f1187',1,'ir_Panasonic.h']]], + ['kpanasonicacswinghleft_6267',['kPanasonicAcSwingHLeft',['../ir__Panasonic_8h.html#a853f2c2922e03a975bdd11efc474fa7e',1,'ir_Panasonic.h']]], + ['kpanasonicacswinghmiddle_6268',['kPanasonicAcSwingHMiddle',['../ir__Panasonic_8h.html#afad8a7257fc178321867f16939fff7c7',1,'ir_Panasonic.h']]], + ['kpanasonicacswinghright_6269',['kPanasonicAcSwingHRight',['../ir__Panasonic_8h.html#a282900f1c494efdc6ee057357e624d2e',1,'ir_Panasonic.h']]], + ['kpanasonicacswingvauto_6270',['kPanasonicAcSwingVAuto',['../ir__Panasonic_8h.html#a218e2ea8c76966105c71edcb6e46cd12',1,'ir_Panasonic.h']]], + ['kpanasonicacswingvhigh_6271',['kPanasonicAcSwingVHigh',['../ir__Panasonic_8h.html#a25c63195112c5aedc5b5bad40441c55a',1,'ir_Panasonic.h']]], + ['kpanasonicacswingvhighest_6272',['kPanasonicAcSwingVHighest',['../ir__Panasonic_8h.html#ac1cea523d6e1da08d333e0b4acec81af',1,'ir_Panasonic.h']]], + ['kpanasonicacswingvlow_6273',['kPanasonicAcSwingVLow',['../ir__Panasonic_8h.html#a3ae9b6c5581f1bfb5b31e252052a6c9d',1,'ir_Panasonic.h']]], + ['kpanasonicacswingvlowest_6274',['kPanasonicAcSwingVLowest',['../ir__Panasonic_8h.html#af269e81dae5989c33199d607adcc04a0',1,'ir_Panasonic.h']]], + ['kpanasonicacswingvmiddle_6275',['kPanasonicAcSwingVMiddle',['../ir__Panasonic_8h.html#a5d46c8234f97e10695507b17a7483d51',1,'ir_Panasonic.h']]], + ['kpanasonicactempoffset_6276',['kPanasonicAcTempOffset',['../ir__Panasonic_8h.html#a203e0351cd53db8376312a3289503175',1,'ir_Panasonic.h']]], + ['kpanasonicactempsize_6277',['kPanasonicAcTempSize',['../ir__Panasonic_8h.html#af30649a3489a4a1dc1f655d15c00e991',1,'ir_Panasonic.h']]], + ['kpanasonicactimemax_6278',['kPanasonicAcTimeMax',['../ir__Panasonic_8h.html#a61378ccad09d1a2e900123a8cbd34858',1,'ir_Panasonic.h']]], + ['kpanasonicactimeoverflowsize_6279',['kPanasonicAcTimeOverflowSize',['../ir__Panasonic_8h.html#ad7942b5ffbb2b1f7a5d9b3719592622b',1,'ir_Panasonic.h']]], + ['kpanasonicactimesize_6280',['kPanasonicAcTimeSize',['../ir__Panasonic_8h.html#a16577844a2f5ca46e2dff076952f2963',1,'ir_Panasonic.h']]], + ['kpanasonicactimespecial_6281',['kPanasonicAcTimeSpecial',['../ir__Panasonic_8h.html#aefb20e7cdbbc27e3c0725a8660a84a28',1,'ir_Panasonic.h']]], + ['kpanasonicactolerance_6282',['kPanasonicAcTolerance',['../ir__Panasonic_8h.html#a586a655b3afd82c38588fc1b61089aa1',1,'ir_Panasonic.h']]], + ['kpanasonicbitmark_6283',['kPanasonicBitMark',['../ir__Panasonic_8cpp.html#a428cd02c5dc3dc571e495efa0707cc99',1,'ir_Panasonic.cpp']]], + ['kpanasonicbitmarkticks_6284',['kPanasonicBitMarkTicks',['../ir__Panasonic_8cpp.html#aa0b259da4bc3dbf6c8b2ca31de759f55',1,'ir_Panasonic.cpp']]], + ['kpanasonicbits_6285',['kPanasonicBits',['../IRremoteESP8266_8h.html#aa148f54492be1cf8a8b285a96861a0b7',1,'IRremoteESP8266.h']]], + ['kpanasonicendgap_6286',['kPanasonicEndGap',['../ir__Panasonic_8cpp.html#a3cb2f7a925bb8374a90e3156febabb39',1,'ir_Panasonic.cpp']]], + ['kpanasonicfreq_6287',['kPanasonicFreq',['../ir__Panasonic_8h.html#af344612d7f1c0d3f8271c312f310243e',1,'ir_Panasonic.h']]], + ['kpanasonichdrmark_6288',['kPanasonicHdrMark',['../ir__Panasonic_8cpp.html#a0d36b699fead0e229c583dae94f5e8f9',1,'ir_Panasonic.cpp']]], + ['kpanasonichdrmarkticks_6289',['kPanasonicHdrMarkTicks',['../ir__Panasonic_8cpp.html#a0f2d448b87f30840ee38c27032cd10bd',1,'ir_Panasonic.cpp']]], + ['kpanasonichdrspace_6290',['kPanasonicHdrSpace',['../ir__Panasonic_8cpp.html#ae56b3eb80f186a63b0f69c6b4e9efce8',1,'ir_Panasonic.cpp']]], + ['kpanasonichdrspaceticks_6291',['kPanasonicHdrSpaceTicks',['../ir__Panasonic_8cpp.html#a5fa430a5612bd21eb859356cc9c62a3c',1,'ir_Panasonic.cpp']]], + ['kpanasonicknowngoodstate_6292',['kPanasonicKnownGoodState',['../ir__Panasonic_8h.html#a88a9678f8b00efa173b800b0b8441f87',1,'ir_Panasonic.h']]], + ['kpanasonicmanufacturer_6293',['kPanasonicManufacturer',['../IRremoteESP8266_8h.html#a1dd1a9799e5d20d39e82ff678bf07b47',1,'IRremoteESP8266.h']]], + ['kpanasonicmincommandlength_6294',['kPanasonicMinCommandLength',['../ir__Panasonic_8cpp.html#a5f191fff3eeb722cb03bee859a016132',1,'ir_Panasonic.cpp']]], + ['kpanasonicmincommandlengthticks_6295',['kPanasonicMinCommandLengthTicks',['../ir__Panasonic_8cpp.html#aba420f9aa4c3e6f261e422962362ce31',1,'ir_Panasonic.cpp']]], + ['kpanasonicmingap_6296',['kPanasonicMinGap',['../ir__Panasonic_8cpp.html#a61592f3569c0ee4825cca185fb43236d',1,'ir_Panasonic.cpp']]], + ['kpanasonicmingapticks_6297',['kPanasonicMinGapTicks',['../ir__Panasonic_8cpp.html#aa605847e951b22f1f31b82e6b04c4bab',1,'ir_Panasonic.cpp']]], + ['kpanasoniconespace_6298',['kPanasonicOneSpace',['../ir__Panasonic_8cpp.html#a9069f2ab94cacbd301d7615795c155b1',1,'ir_Panasonic.cpp']]], + ['kpanasoniconespaceticks_6299',['kPanasonicOneSpaceTicks',['../ir__Panasonic_8cpp.html#aa7a8cb818a098bb8ec395af7f5dbc6d7',1,'ir_Panasonic.cpp']]], + ['kpanasonictick_6300',['kPanasonicTick',['../ir__Panasonic_8cpp.html#ab2fddd81fb53066257aeaa60069527a8',1,'ir_Panasonic.cpp']]], + ['kpanasoniczerospace_6301',['kPanasonicZeroSpace',['../ir__Panasonic_8cpp.html#a43f64a8326fd2447653c81488673fd21',1,'ir_Panasonic.cpp']]], + ['kpanasoniczerospaceticks_6302',['kPanasonicZeroSpaceTicks',['../ir__Panasonic_8cpp.html#a58fef1468dbd4c3963be58754f38b125',1,'ir_Panasonic.cpp']]], + ['kperiodoffset_6303',['kPeriodOffset',['../IRsend_8h.html#a3a451a4e72e39a4bbf75c62af0ac62f5',1,'IRsend.h']]], + ['kpioneerbitmark_6304',['kPioneerBitMark',['../ir__Pioneer_8cpp.html#a6117fd080ad88efcf943aef53dadd1ad',1,'ir_Pioneer.cpp']]], + ['kpioneerbitmarkticks_6305',['kPioneerBitMarkTicks',['../ir__Pioneer_8cpp.html#a1cd60e52b21df3b10ac5f668cf61df16',1,'ir_Pioneer.cpp']]], + ['kpioneerbits_6306',['kPioneerBits',['../IRremoteESP8266_8h.html#a6a7ccd31e0a6f967a219b1a53b89653b',1,'IRremoteESP8266.h']]], + ['kpioneerhdrmark_6307',['kPioneerHdrMark',['../ir__Pioneer_8cpp.html#a03c4df7d9eba6ab56df0451a18e5adbd',1,'ir_Pioneer.cpp']]], + ['kpioneerhdrmarkticks_6308',['kPioneerHdrMarkTicks',['../ir__Pioneer_8cpp.html#a9fc6ba8a158cae2d0d67af8e6cddd169',1,'ir_Pioneer.cpp']]], + ['kpioneerhdrspace_6309',['kPioneerHdrSpace',['../ir__Pioneer_8cpp.html#a1308ff993ce7d030bdef919d65f35e62',1,'ir_Pioneer.cpp']]], + ['kpioneerhdrspaceticks_6310',['kPioneerHdrSpaceTicks',['../ir__Pioneer_8cpp.html#a6c2ab5c384101f9184fd0960f21d13a5',1,'ir_Pioneer.cpp']]], + ['kpioneermincommandlength_6311',['kPioneerMinCommandLength',['../ir__Pioneer_8cpp.html#a22cb7d70bb0eb3b0ce6c7da3631d832f',1,'ir_Pioneer.cpp']]], + ['kpioneermincommandlengthticks_6312',['kPioneerMinCommandLengthTicks',['../ir__Pioneer_8cpp.html#a472ab59d00c439cc8832081492e742cc',1,'ir_Pioneer.cpp']]], + ['kpioneermingap_6313',['kPioneerMinGap',['../ir__Pioneer_8cpp.html#adc67bf557bd3474f18dfaa3125c1af41',1,'ir_Pioneer.cpp']]], + ['kpioneermingapticks_6314',['kPioneerMinGapTicks',['../ir__Pioneer_8cpp.html#abe0ebf83502225b39926ab745a8f8be2',1,'ir_Pioneer.cpp']]], + ['kpioneeronespace_6315',['kPioneerOneSpace',['../ir__Pioneer_8cpp.html#a5238b059346168128184bca93de16a54',1,'ir_Pioneer.cpp']]], + ['kpioneeronespaceticks_6316',['kPioneerOneSpaceTicks',['../ir__Pioneer_8cpp.html#af637842c88b54a022ac1ba3fef3fa041',1,'ir_Pioneer.cpp']]], + ['kpioneertick_6317',['kPioneerTick',['../ir__Pioneer_8cpp.html#a63de2364627344f86537ac82447c5cb4',1,'ir_Pioneer.cpp']]], + ['kpioneerzerospace_6318',['kPioneerZeroSpace',['../ir__Pioneer_8cpp.html#a3c6428f201dd3e32c171d6db44269d67',1,'ir_Pioneer.cpp']]], + ['kpioneerzerospaceticks_6319',['kPioneerZeroSpaceTicks',['../ir__Pioneer_8cpp.html#acdeea63204ce47f1556fa31bbed8a4a4',1,'ir_Pioneer.cpp']]], + ['kpowerbuttonstr_6320',['kPowerButtonStr',['../IRtext_8cpp.html#a69d36084b1410a06aa780edcda9428dd',1,'kPowerButtonStr(): IRtext.cpp'],['../IRtext_8h.html#adb54b8d070a4ba7f08b7d2d0f1c03d1c',1,'kPowerButtonStr(): IRtext.cpp']]], + ['kpowerfulstr_6321',['kPowerfulStr',['../IRtext_8cpp.html#a5dfc12bfa12ddf7da3ab6c216258284a',1,'kPowerfulStr(): IRtext.cpp'],['../IRtext_8h.html#a7980630cd028febca8245730dffa684b',1,'kPowerfulStr(): IRtext.cpp']]], + ['kpowerstr_6322',['kPowerStr',['../IRtext_8cpp.html#a5b4b43efe1f1c27d6aee90ebb3500792',1,'kPowerStr(): IRtext.cpp'],['../IRtext_8h.html#a47a76dc8d87d9694a36c6417d7e19dda',1,'kPowerStr(): IRtext.cpp']]], + ['kpowertogglestr_6323',['kPowerToggleStr',['../IRtext_8cpp.html#a2f7e242dc28cf61fb718bb5c1b681642',1,'kPowerToggleStr(): IRtext.cpp'],['../IRtext_8h.html#afd802a94c6146efb7812ef89f3bf0cc5',1,'kPowerToggleStr(): IRtext.cpp']]], + ['kpreviouspowerstr_6324',['kPreviousPowerStr',['../IRtext_8cpp.html#a2a5cd83ac519798debd7065eb03d5d72',1,'kPreviousPowerStr(): IRtext.cpp'],['../IRtext_8h.html#a9833364e538f50be227ff6c0b01f8f7c',1,'kPreviousPowerStr(): IRtext.cpp']]], + ['kprontodataoffset_6325',['kProntoDataOffset',['../ir__Pronto_8cpp.html#ac073b9ac759e09091b3d80af747656a1',1,'ir_Pronto.cpp']]], + ['kprontofreqfactor_6326',['kProntoFreqFactor',['../ir__Pronto_8cpp.html#aa63eef9baeb563c8494d85d13b956db8',1,'ir_Pronto.cpp']]], + ['kprontofreqoffset_6327',['kProntoFreqOffset',['../ir__Pronto_8cpp.html#a2fae4105559199e292121bcb847d9d52',1,'ir_Pronto.cpp']]], + ['kprontominlength_6328',['kProntoMinLength',['../IRremoteESP8266_8h.html#a25dd42234e21d41b0b4bc97e1fe921c4',1,'IRremoteESP8266.h']]], + ['kprontoseq1lenoffset_6329',['kProntoSeq1LenOffset',['../ir__Pronto_8cpp.html#a1df51305dddf233fc3963856e288366f',1,'ir_Pronto.cpp']]], + ['kprontoseq2lenoffset_6330',['kProntoSeq2LenOffset',['../ir__Pronto_8cpp.html#a708744a9f82547e5abc17d7ed866a648',1,'ir_Pronto.cpp']]], + ['kprontotypeoffset_6331',['kProntoTypeOffset',['../ir__Pronto_8cpp.html#a603ff34f28f270a98bf0bebdaf19bfbc',1,'ir_Pronto.cpp']]], + ['kprotocolstr_6332',['kProtocolStr',['../IRtext_8cpp.html#afb9e901ded9e88a48218282a7446ff63',1,'kProtocolStr(): IRtext.cpp'],['../IRtext_8h.html#ac50f97a0d33041fe4bba6e02c500c8ef',1,'kProtocolStr(): IRtext.cpp']]], + ['kpurifystr_6333',['kPurifyStr',['../IRtext_8cpp.html#a85c2b59f6cba1878648d3d8fe9d7f9a4',1,'kPurifyStr(): IRtext.cpp'],['../IRtext_8h.html#aae574dbb4b9f70db0e64386d61c21beb',1,'kPurifyStr(): IRtext.cpp']]], + ['kquietstr_6334',['kQuietStr',['../IRtext_8cpp.html#a6f85e3119eb884455f474ff909be6b53',1,'kQuietStr(): IRtext.cpp'],['../IRtext_8h.html#a7086660370d73d6f499972cf802db8f7',1,'kQuietStr(): IRtext.cpp']]], + ['krawbuf_6335',['kRawBuf',['../IRrecv_8h.html#aadfa37def10a1adeaf2cf4c09d7504e3',1,'IRrecv.h']]], + ['krawtick_6336',['kRawTick',['../IRrecv_8h.html#a373dde69c312b0122665e581eea1297b',1,'IRrecv.h']]], + ['krc5bits_6337',['kRC5Bits',['../IRremoteESP8266_8h.html#ad0935984e6518e340562665742199483',1,'IRremoteESP8266.h']]], + ['krc5mincommandlength_6338',['kRc5MinCommandLength',['../ir__RC5__RC6_8cpp.html#a32b5997148b53fd2984388f6d0384c35',1,'ir_RC5_RC6.cpp']]], + ['krc5mingap_6339',['kRc5MinGap',['../ir__RC5__RC6_8cpp.html#a26580409f593179d838c465647e35c41',1,'ir_RC5_RC6.cpp']]], + ['krc5rawbits_6340',['kRC5RawBits',['../IRremoteESP8266_8h.html#a955183d3358fcafea853014ddd890574',1,'IRremoteESP8266.h']]], + ['krc5samplesmin_6341',['kRc5SamplesMin',['../ir__RC5__RC6_8cpp.html#aa206173838597c760b4a01c36bbc771a',1,'ir_RC5_RC6.cpp']]], + ['krc5t1_6342',['kRc5T1',['../ir__RC5__RC6_8cpp.html#aa42cae15fa77a196eb8f198de09e19eb',1,'ir_RC5_RC6.cpp']]], + ['krc5togglemask_6343',['kRc5ToggleMask',['../ir__RC5__RC6_8cpp.html#ae3485c1c157d6d84a0385cb1bfb8833a',1,'ir_RC5_RC6.cpp']]], + ['krc5xbits_6344',['kRC5XBits',['../IRremoteESP8266_8h.html#abec3ebb217126560e824fa8b66d495bc',1,'IRremoteESP8266.h']]], + ['krc6_5f36bits_6345',['kRC6_36Bits',['../IRremoteESP8266_8h.html#a30a2cb328aa0d47f53aba56055ac74e0',1,'IRremoteESP8266.h']]], + ['krc6_5f36togglemask_6346',['kRc6_36ToggleMask',['../ir__RC5__RC6_8cpp.html#a31ae862ce2a43edd99bda647262b18fa',1,'ir_RC5_RC6.cpp']]], + ['krc6hdrmark_6347',['kRc6HdrMark',['../ir__RC5__RC6_8cpp.html#ae05bbb9f690cc92feb0a9c14b3b8c477',1,'ir_RC5_RC6.cpp']]], + ['krc6hdrmarkticks_6348',['kRc6HdrMarkTicks',['../ir__RC5__RC6_8cpp.html#aff2a5bc05ddf61d289c44a4fd093009c',1,'ir_RC5_RC6.cpp']]], + ['krc6hdrspace_6349',['kRc6HdrSpace',['../ir__RC5__RC6_8cpp.html#a0196311c9b116cf48c8f901fb6c93ac3',1,'ir_RC5_RC6.cpp']]], + ['krc6hdrspaceticks_6350',['kRc6HdrSpaceTicks',['../ir__RC5__RC6_8cpp.html#a35a9cc59fe5251a34c88e34b6a507fd3',1,'ir_RC5_RC6.cpp']]], + ['krc6mode0bits_6351',['kRC6Mode0Bits',['../IRremoteESP8266_8h.html#a84a6d3e15e98f7a4917d252d5665534a',1,'IRremoteESP8266.h']]], + ['krc6rptlength_6352',['kRc6RptLength',['../ir__RC5__RC6_8cpp.html#a4989f36b790a99545e708c8681b6b961',1,'ir_RC5_RC6.cpp']]], + ['krc6rptlengthticks_6353',['kRc6RptLengthTicks',['../ir__RC5__RC6_8cpp.html#acf2dc0074bfe7671deb8985eba4396e3',1,'ir_RC5_RC6.cpp']]], + ['krc6tick_6354',['kRc6Tick',['../ir__RC5__RC6_8cpp.html#aad98dc2541039634817609d4e297322f',1,'ir_RC5_RC6.cpp']]], + ['krc6togglemask_6355',['kRc6ToggleMask',['../ir__RC5__RC6_8cpp.html#a4df09270c1e9cda504026189e30829ff',1,'ir_RC5_RC6.cpp']]], + ['krcmmbitmark_6356',['kRcmmBitMark',['../ir__RCMM_8cpp.html#ad768f62bbd7e4df567c3e53ea0a8ed06',1,'ir_RCMM.cpp']]], + ['krcmmbitmarkticks_6357',['kRcmmBitMarkTicks',['../ir__RCMM_8cpp.html#a48aeb7992d30f8c7cfa04dbd14ea0996',1,'ir_RCMM.cpp']]], + ['krcmmbits_6358',['kRCMMBits',['../IRremoteESP8266_8h.html#a2bfaf393c2d77a594f2a0a5a763e84f5',1,'IRremoteESP8266.h']]], + ['krcmmbitspace0_6359',['kRcmmBitSpace0',['../ir__RCMM_8cpp.html#a34a7b22107461be18500f6d1ddf979e3',1,'ir_RCMM.cpp']]], + ['krcmmbitspace0ticks_6360',['kRcmmBitSpace0Ticks',['../ir__RCMM_8cpp.html#a0864042e8c098169d1d221fbd798cda3',1,'ir_RCMM.cpp']]], + ['krcmmbitspace1_6361',['kRcmmBitSpace1',['../ir__RCMM_8cpp.html#a812b9895f0eccaaf78752dc7030022aa',1,'ir_RCMM.cpp']]], + ['krcmmbitspace1ticks_6362',['kRcmmBitSpace1Ticks',['../ir__RCMM_8cpp.html#a89f945e0a91feccd505f0b8310a9ebb9',1,'ir_RCMM.cpp']]], + ['krcmmbitspace2_6363',['kRcmmBitSpace2',['../ir__RCMM_8cpp.html#aff0db6a8f28d3a307cd7bbb6dc90e3e3',1,'ir_RCMM.cpp']]], + ['krcmmbitspace2ticks_6364',['kRcmmBitSpace2Ticks',['../ir__RCMM_8cpp.html#a592dda1dd9239c9a015163b80cddf859',1,'ir_RCMM.cpp']]], + ['krcmmbitspace3_6365',['kRcmmBitSpace3',['../ir__RCMM_8cpp.html#a5e6351cbcb4c576871584dbf61d87d33',1,'ir_RCMM.cpp']]], + ['krcmmbitspace3ticks_6366',['kRcmmBitSpace3Ticks',['../ir__RCMM_8cpp.html#aa3f7d7e37ffa6bf9649eef7720770767',1,'ir_RCMM.cpp']]], + ['krcmmexcess_6367',['kRcmmExcess',['../ir__RCMM_8cpp.html#a3845e23031e92fd008157b0f95827432',1,'ir_RCMM.cpp']]], + ['krcmmhdrmark_6368',['kRcmmHdrMark',['../ir__RCMM_8cpp.html#a7fc5d5c1dc89ef0615fcaebaacc504df',1,'ir_RCMM.cpp']]], + ['krcmmhdrmarkticks_6369',['kRcmmHdrMarkTicks',['../ir__RCMM_8cpp.html#a00e93c94548ac081083ed2cabd614330',1,'ir_RCMM.cpp']]], + ['krcmmhdrspace_6370',['kRcmmHdrSpace',['../ir__RCMM_8cpp.html#af4dc2548c8069caf889612b3b28895ea',1,'ir_RCMM.cpp']]], + ['krcmmhdrspaceticks_6371',['kRcmmHdrSpaceTicks',['../ir__RCMM_8cpp.html#a87cd8bb5322fb38aecd20362a7df5016',1,'ir_RCMM.cpp']]], + ['krcmmmingap_6372',['kRcmmMinGap',['../ir__RCMM_8cpp.html#a94f9533bf18c0a2c2b6511ffa95ff5dc',1,'ir_RCMM.cpp']]], + ['krcmmmingapticks_6373',['kRcmmMinGapTicks',['../ir__RCMM_8cpp.html#aacb274f2da878aed511f6ab400cd51e9',1,'ir_RCMM.cpp']]], + ['krcmmrptlength_6374',['kRcmmRptLength',['../ir__RCMM_8cpp.html#a1dccf2b944d4eeb8b7dd2a1f66548a68',1,'ir_RCMM.cpp']]], + ['krcmmrptlengthticks_6375',['kRcmmRptLengthTicks',['../ir__RCMM_8cpp.html#a4cd637fa0a6071f9ea0b52c346ffe7f0',1,'ir_RCMM.cpp']]], + ['krcmmtick_6376',['kRcmmTick',['../ir__RCMM_8cpp.html#a9e1a3a26185d58ff675eec7485bc671f',1,'ir_RCMM.cpp']]], + ['krcmmtolerance_6377',['kRcmmTolerance',['../ir__RCMM_8cpp.html#a4b95480078186b3498ca6426e5bbc428',1,'ir_RCMM.cpp']]], + ['krcz01channelmask_6378',['kRcz01ChannelMask',['../ir__Doshisha_8cpp.html#a085b3d47e4cf8d8b4ba999ae58ec3533',1,'ir_Doshisha.cpp']]], + ['krcz01commandlevel1_6379',['kRcz01CommandLevel1',['../ir__Doshisha_8cpp.html#a436b801a282374de0f28e27828e1c4bf',1,'ir_Doshisha.cpp']]], + ['krcz01commandlevel2_6380',['kRcz01CommandLevel2',['../ir__Doshisha_8cpp.html#a311ef41fff985236216238565219bfe7',1,'ir_Doshisha.cpp']]], + ['krcz01commandlevel3_6381',['kRcz01CommandLevel3',['../ir__Doshisha_8cpp.html#a879bd44f482c87fbaf9fecaad8ed4c6d',1,'ir_Doshisha.cpp']]], + ['krcz01commandlevel4_6382',['kRcz01CommandLevel4',['../ir__Doshisha_8cpp.html#a52bad85f1a3918e3031297a6c6074b45',1,'ir_Doshisha.cpp']]], + ['krcz01commandleveldown_6383',['kRcz01CommandLevelDown',['../ir__Doshisha_8cpp.html#a1678269506503f1abf871ed0af6dcc2b',1,'ir_Doshisha.cpp']]], + ['krcz01commandlevelup_6384',['kRcz01CommandLevelUp',['../ir__Doshisha_8cpp.html#a4eba011d2b110a5348783534e957660e',1,'ir_Doshisha.cpp']]], + ['krcz01commandmask_6385',['kRcz01CommandMask',['../ir__Doshisha_8cpp.html#a148e2f676f895f4e3b77b39780e2ca94',1,'ir_Doshisha.cpp']]], + ['krcz01commandnightlight_6386',['kRcz01CommandNightLight',['../ir__Doshisha_8cpp.html#a47e9d5bf353cf8aef8199fb74693aa0f',1,'ir_Doshisha.cpp']]], + ['krcz01commandoff_6387',['kRcz01CommandOff',['../ir__Doshisha_8cpp.html#a97fd32975ab9fafa85e0704964780773',1,'ir_Doshisha.cpp']]], + ['krcz01commandon_6388',['kRcz01CommandOn',['../ir__Doshisha_8cpp.html#a7377eac8b1d938903fd43d7505dd8a49',1,'ir_Doshisha.cpp']]], + ['krcz01commandswitchchannel_6389',['kRcz01CommandSwitchChannel',['../ir__Doshisha_8cpp.html#afcd3fe98c34ef9572c1a68bd143e128b',1,'ir_Doshisha.cpp']]], + ['krcz01commandtimmer30_6390',['kRcz01CommandTimmer30',['../ir__Doshisha_8cpp.html#a3deebab67d01756f7776f0d11cbdef6e',1,'ir_Doshisha.cpp']]], + ['krcz01commandtimmer60_6391',['kRcz01CommandTimmer60',['../ir__Doshisha_8cpp.html#abac6b50227512508aeb5b6042a8380fd',1,'ir_Doshisha.cpp']]], + ['krcz01signature_6392',['kRcz01Signature',['../ir__Doshisha_8cpp.html#a35c6dff74ae1702933e33f02f743f616',1,'ir_Doshisha.cpp']]], + ['krcz01signaturemask_6393',['kRcz01SignatureMask',['../ir__Doshisha_8cpp.html#a1f3b9cdfba7cc7515611d7145b7318a5',1,'ir_Doshisha.cpp']]], + ['krepeat_6394',['kRepeat',['../IRrecv_8h.html#ae8b11750ba7f2e2d56343f770720ed89',1,'IRrecv.h']]], + ['krepeatstr_6395',['kRepeatStr',['../IRtext_8cpp.html#ad55ef2e023915f39c7ce77e7eeb1ad76',1,'kRepeatStr(): IRtext.cpp'],['../IRtext_8h.html#a74a53cc1564f75b36269eb1ca8c6235b',1,'kRepeatStr(): IRtext.cpp']]], + ['krightmaxstr_6396',['kRightMaxStr',['../IRtext_8cpp.html#af3e63659779f5fdb4aded4861521e564',1,'kRightMaxStr(): IRtext.cpp'],['../IRtext_8h.html#ac7a90008560fd1e7b4ed240f354d8fae',1,'kRightMaxStr(): IRtext.cpp']]], + ['krightstr_6397',['kRightStr',['../IRtext_8cpp.html#aacc9b0b21efb6053b75ed117d4ab9105',1,'kRightStr(): IRtext.cpp'],['../IRtext_8h.html#a953f9c48fcf87e81bf6f383e8fe8b1dd',1,'kRightStr(): IRtext.cpp']]], + ['kroomstr_6398',['kRoomStr',['../IRtext_8cpp.html#ab3f02ff54af9a94fd57d098838a4a642',1,'kRoomStr(): IRtext.cpp'],['../IRtext_8h.html#a5358a85538e4643c1cc109a7a0b90079',1,'kRoomStr(): IRtext.cpp']]], + ['ksamsung36bits_6399',['kSamsung36Bits',['../IRremoteESP8266_8h.html#a5e1e6f30a41f0d94652429a9e1034179',1,'IRremoteESP8266.h']]], + ['ksamsungacauto_6400',['kSamsungAcAuto',['../ir__Samsung_8h.html#a1b05ff970f45c57b13fc13d11e95396b',1,'ir_Samsung.h']]], + ['ksamsungacautotemp_6401',['kSamsungAcAutoTemp',['../ir__Samsung_8h.html#a87bb469afc0e2b6bad44634f3ba5e0ef',1,'ir_Samsung.h']]], + ['ksamsungacbeepoffset_6402',['kSamsungAcBeepOffset',['../ir__Samsung_8h.html#a12ae1e43d05d39c39d335c97223e003e',1,'ir_Samsung.h']]], + ['ksamsungacbitmark_6403',['kSamsungAcBitMark',['../ir__Samsung_8cpp.html#a37e6f36939f1a12ffe52907bbb64a4cf',1,'ir_Samsung.cpp']]], + ['ksamsungacbits_6404',['kSamsungAcBits',['../IRremoteESP8266_8h.html#adebe85ab48eb876ec15daacca246797c',1,'IRremoteESP8266.h']]], + ['ksamsungacbreezeoffset_6405',['kSamsungAcBreezeOffset',['../ir__Samsung_8h.html#a31d5463b3819fe41ce078b085c395a40',1,'ir_Samsung.h']]], + ['ksamsungacbreezeon_6406',['kSamsungAcBreezeOn',['../ir__Samsung_8h.html#a06299ba6942969f7b9472e752b50d4d7',1,'ir_Samsung.h']]], + ['ksamsungacbreezesize_6407',['kSamsungAcBreezeSize',['../ir__Samsung_8h.html#a1f6ec492aa58cb704147213e3b6f9f24',1,'ir_Samsung.h']]], + ['ksamsungacclean10offset_6408',['kSamsungAcClean10Offset',['../ir__Samsung_8h.html#a0982038a8c3e27972e69b83c350a0ff3',1,'ir_Samsung.h']]], + ['ksamsungacclean11offset_6409',['kSamsungAcClean11Offset',['../ir__Samsung_8h.html#a87666330f9a410ced00bf15c5f22daf2',1,'ir_Samsung.h']]], + ['ksamsungaccool_6410',['kSamsungAcCool',['../ir__Samsung_8h.html#a24d40e01f046f887b7d41dad67ad7555',1,'ir_Samsung.h']]], + ['ksamsungacdefaultrepeat_6411',['kSamsungAcDefaultRepeat',['../IRremoteESP8266_8h.html#a973f4e0189fc10805f67b67f708be1e4',1,'IRremoteESP8266.h']]], + ['ksamsungacdisplayoffset_6412',['kSamsungAcDisplayOffset',['../ir__Samsung_8h.html#af47c9229cbe569b93ad5f4986c4484ab',1,'ir_Samsung.h']]], + ['ksamsungacdry_6413',['kSamsungAcDry',['../ir__Samsung_8h.html#a6423976c7a41f526e7a878cecb257bbd',1,'ir_Samsung.h']]], + ['ksamsungacextendedbits_6414',['kSamsungAcExtendedBits',['../IRremoteESP8266_8h.html#a296e700965e70a622fe99675ff0438af',1,'IRremoteESP8266.h']]], + ['ksamsungacextendedstatelength_6415',['kSamsungAcExtendedStateLength',['../IRremoteESP8266_8h.html#a28039071f1130e9bc86efddd8265cbf9',1,'IRremoteESP8266.h']]], + ['ksamsungacfan_6416',['kSamsungAcFan',['../ir__Samsung_8h.html#a61d825254b26894a2f097ad92a7dbff2',1,'ir_Samsung.h']]], + ['ksamsungacfanauto_6417',['kSamsungAcFanAuto',['../ir__Samsung_8h.html#a37b29911f4d2b71dcdbd18a5d6dc301a',1,'ir_Samsung.h']]], + ['ksamsungacfanauto2_6418',['kSamsungAcFanAuto2',['../ir__Samsung_8h.html#aafa4319fb523b14d58371f757497e82a',1,'ir_Samsung.h']]], + ['ksamsungacfanhigh_6419',['kSamsungAcFanHigh',['../ir__Samsung_8h.html#a52cccad28fad5b9886ef408af02f56f9',1,'ir_Samsung.h']]], + ['ksamsungacfanlow_6420',['kSamsungAcFanLow',['../ir__Samsung_8h.html#a6f16b5b3f2dea3461f5d44379e8b8634',1,'ir_Samsung.h']]], + ['ksamsungacfanmed_6421',['kSamsungAcFanMed',['../ir__Samsung_8h.html#a798c3544dbd6bb6c8622cf45f88abc14',1,'ir_Samsung.h']]], + ['ksamsungacfanoffest_6422',['kSamsungAcFanOffest',['../ir__Samsung_8h.html#a1dd4a351c1a036972f741fbdafb05a7e',1,'ir_Samsung.h']]], + ['ksamsungacfansize_6423',['kSamsungAcFanSize',['../ir__Samsung_8h.html#a5b055e9951e23ba44bf1fdeed805b332',1,'ir_Samsung.h']]], + ['ksamsungacfanturbo_6424',['kSamsungAcFanTurbo',['../ir__Samsung_8h.html#af6c1432748eaa19df35531b87d197095',1,'ir_Samsung.h']]], + ['ksamsungachdrmark_6425',['kSamsungAcHdrMark',['../ir__Samsung_8cpp.html#ab7385ca5b7b417753b253a0f7cb3721b',1,'ir_Samsung.cpp']]], + ['ksamsungachdrspace_6426',['kSamsungAcHdrSpace',['../ir__Samsung_8cpp.html#a1b1f903fff13b10fb2431be9373e27cb',1,'ir_Samsung.cpp']]], + ['ksamsungacheat_6427',['kSamsungAcHeat',['../ir__Samsung_8h.html#a44ce6be7046ec4b4fe9caba7b71b8f0d',1,'ir_Samsung.h']]], + ['ksamsungacionoffset_6428',['kSamsungAcIonOffset',['../ir__Samsung_8h.html#aa7bbd222553072c092158421d1b9977f',1,'ir_Samsung.h']]], + ['ksamsungacmaxtemp_6429',['kSamsungAcMaxTemp',['../ir__Samsung_8h.html#a0a994796db81a3d56dd2c27cad448a71',1,'ir_Samsung.h']]], + ['ksamsungacmintemp_6430',['kSamsungAcMinTemp',['../ir__Samsung_8h.html#ad5f46ccb96335519f5633c33de0d8018',1,'ir_Samsung.h']]], + ['ksamsungacmodeoffset_6431',['kSamsungAcModeOffset',['../ir__Samsung_8h.html#a64b2aceb5c0d4dbea2d4697efe65aef2',1,'ir_Samsung.h']]], + ['ksamsungaconespace_6432',['kSamsungAcOneSpace',['../ir__Samsung_8cpp.html#ab106d9b7efb165eed83ae2ccef9a49b4',1,'ir_Samsung.cpp']]], + ['ksamsungacpower1offset_6433',['kSamsungAcPower1Offset',['../ir__Samsung_8h.html#aa6a4ff05acfabf24e4dfc126e583c46c',1,'ir_Samsung.h']]], + ['ksamsungacpower6offset_6434',['kSamsungAcPower6Offset',['../ir__Samsung_8h.html#a90591c7d6069d81493f894328d595187',1,'ir_Samsung.h']]], + ['ksamsungacpower6size_6435',['kSamsungAcPower6Size',['../ir__Samsung_8h.html#ace0a7a2cfedbb77d05de53abc5906992',1,'ir_Samsung.h']]], + ['ksamsungacpowerful10offset_6436',['kSamsungAcPowerful10Offset',['../ir__Samsung_8h.html#a7f92d734af799e058723e898d3ebdd30',1,'ir_Samsung.h']]], + ['ksamsungacpowerful10on_6437',['kSamsungAcPowerful10On',['../ir__Samsung_8h.html#aa05bb4788febba1f56b2b3929ac273a3',1,'ir_Samsung.h']]], + ['ksamsungacpowerful10size_6438',['kSamsungAcPowerful10Size',['../ir__Samsung_8h.html#a19ede17e420f68ea552497461e69006a',1,'ir_Samsung.h']]], + ['ksamsungacpowerfulmask8_6439',['kSamsungAcPowerfulMask8',['../ir__Samsung_8h.html#a39e23325e35688a3641c467b720381ce',1,'ir_Samsung.h']]], + ['ksamsungacpowersection_6440',['kSamsungAcPowerSection',['../ir__Samsung_8h.html#a9264b5d640d9052c153562fd38415676',1,'ir_Samsung.h']]], + ['ksamsungacquiet1offset_6441',['kSamsungAcQuiet1Offset',['../ir__Samsung_8h.html#ab029485b433f7eef6413d8194790c566',1,'ir_Samsung.h']]], + ['ksamsungacquiet5offset_6442',['kSamsungAcQuiet5Offset',['../ir__Samsung_8h.html#ae10abd66772da9bab4ba266f29e7ec75',1,'ir_Samsung.h']]], + ['ksamsungacsectiongap_6443',['kSamsungAcSectionGap',['../ir__Samsung_8cpp.html#a9752fc615c215a93c1ee65edca3a359e',1,'ir_Samsung.cpp']]], + ['ksamsungacsectionlength_6444',['kSamsungAcSectionLength',['../ir__Samsung_8h.html#ad3faedf7b111f1b91d671666e38ce6f3',1,'ir_Samsung.h']]], + ['ksamsungacsectionmark_6445',['kSamsungAcSectionMark',['../ir__Samsung_8cpp.html#a4304073cddaa2da9613dedce499fee56',1,'ir_Samsung.cpp']]], + ['ksamsungacsections_6446',['kSamsungAcSections',['../ir__Samsung_8cpp.html#a86185d98d6e891a17688d9d2a0fa7114',1,'ir_Samsung.cpp']]], + ['ksamsungacsectionspace_6447',['kSamsungAcSectionSpace',['../ir__Samsung_8cpp.html#a4837f502ef9b7c972ec409cf4fc3c605',1,'ir_Samsung.cpp']]], + ['ksamsungacstatelength_6448',['kSamsungAcStateLength',['../IRremoteESP8266_8h.html#a2d07d8c8917fee072a261d00e67e0d36',1,'IRremoteESP8266.h']]], + ['ksamsungacswingmove_6449',['kSamsungAcSwingMove',['../ir__Samsung_8h.html#ab2d2b422e3972f77aef23f77c7cfbbac',1,'ir_Samsung.h']]], + ['ksamsungacswingoffset_6450',['kSamsungAcSwingOffset',['../ir__Samsung_8h.html#ab71772d77c56cf4d01f3ce4ab751a55c',1,'ir_Samsung.h']]], + ['ksamsungacswingsize_6451',['kSamsungAcSwingSize',['../ir__Samsung_8h.html#a1b50618058108826f9103f46bf7677ee',1,'ir_Samsung.h']]], + ['ksamsungacswingstop_6452',['kSamsungAcSwingStop',['../ir__Samsung_8h.html#a37c1720d66c4ba02e368946e53036367',1,'ir_Samsung.h']]], + ['ksamsungaczerospace_6453',['kSamsungAcZeroSpace',['../ir__Samsung_8cpp.html#a7492a25e730f93f22c099ab687621b18',1,'ir_Samsung.cpp']]], + ['ksamsungbitmark_6454',['kSamsungBitMark',['../ir__Samsung_8cpp.html#a03f9ae317a7a701437c8015dfde4401f',1,'ir_Samsung.cpp']]], + ['ksamsungbitmarkticks_6455',['kSamsungBitMarkTicks',['../ir__Samsung_8cpp.html#afe1663f83396f7e5cf9bfc32f321e539',1,'ir_Samsung.cpp']]], + ['ksamsungbits_6456',['kSamsungBits',['../IRremoteESP8266_8h.html#a7c1c015cce09284799cbf5a2f21ee170',1,'IRremoteESP8266.h']]], + ['ksamsunghdrmark_6457',['kSamsungHdrMark',['../ir__Samsung_8cpp.html#a3d0598585af609af4c8d5004789d2df7',1,'ir_Samsung.cpp']]], + ['ksamsunghdrmarkticks_6458',['kSamsungHdrMarkTicks',['../ir__Samsung_8cpp.html#a0c81f486877d24bfd40215b089c52f2a',1,'ir_Samsung.cpp']]], + ['ksamsunghdrspace_6459',['kSamsungHdrSpace',['../ir__Samsung_8cpp.html#a2f55c53bfc72de06ff202c8ec401163d',1,'ir_Samsung.cpp']]], + ['ksamsunghdrspaceticks_6460',['kSamsungHdrSpaceTicks',['../ir__Samsung_8cpp.html#a1ae96cedfa4ed26869d295cfbb8056dd',1,'ir_Samsung.cpp']]], + ['ksamsungmingap_6461',['kSamsungMinGap',['../ir__Samsung_8cpp.html#ab13edb242547803b386aa8539a4b9470',1,'ir_Samsung.cpp']]], + ['ksamsungmingapticks_6462',['kSamsungMinGapTicks',['../ir__Samsung_8cpp.html#a55d79dcfcd43f05ebe456a9a2fce3ff0',1,'ir_Samsung.cpp']]], + ['ksamsungminmessagelength_6463',['kSamsungMinMessageLength',['../ir__Samsung_8cpp.html#ae2ec2e45f91f872e85c250c7aac0efc1',1,'ir_Samsung.cpp']]], + ['ksamsungminmessagelengthticks_6464',['kSamsungMinMessageLengthTicks',['../ir__Samsung_8cpp.html#a6d436a1b71158ff9b5d7ae21344cd7d2',1,'ir_Samsung.cpp']]], + ['ksamsungonespace_6465',['kSamsungOneSpace',['../ir__Samsung_8cpp.html#ab486b048d13f44623ee291d4221c2a1b',1,'ir_Samsung.cpp']]], + ['ksamsungonespaceticks_6466',['kSamsungOneSpaceTicks',['../ir__Samsung_8cpp.html#a484a1e3ce3dcbbef15be559bfb5822d0',1,'ir_Samsung.cpp']]], + ['ksamsungrptspace_6467',['kSamsungRptSpace',['../ir__Samsung_8cpp.html#a1cc2f3bcd7f2ca36f0a726828c14aa74',1,'ir_Samsung.cpp']]], + ['ksamsungrptspaceticks_6468',['kSamsungRptSpaceTicks',['../ir__Samsung_8cpp.html#a6864f78ad1428358acbc8b46796e50cc',1,'ir_Samsung.cpp']]], + ['ksamsungtick_6469',['kSamsungTick',['../ir__Samsung_8cpp.html#accd7d51c2714bd383170831372f57bc5',1,'ir_Samsung.cpp']]], + ['ksamsungzerospace_6470',['kSamsungZeroSpace',['../ir__Samsung_8cpp.html#ae2c828a3d099d6195208a3794022587e',1,'ir_Samsung.cpp']]], + ['ksamsungzerospaceticks_6471',['kSamsungZeroSpaceTicks',['../ir__Samsung_8cpp.html#aea63a73a5b0af2c173bc473ee2447a93',1,'ir_Samsung.cpp']]], + ['ksanyolc7461addressbits_6472',['kSanyoLC7461AddressBits',['../IRremoteESP8266_8h.html#a7e15e988acbea0fb4dfaee6f5bfa12d0',1,'IRremoteESP8266.h']]], + ['ksanyolc7461addressmask_6473',['kSanyoLc7461AddressMask',['../ir__Sanyo_8cpp.html#a785ccc066e433f11791f8a30243944d3',1,'ir_Sanyo.cpp']]], + ['ksanyolc7461bitmark_6474',['kSanyoLc7461BitMark',['../ir__Sanyo_8cpp.html#a1360ba5ac3f30715c00a6a65155cfec8',1,'ir_Sanyo.cpp']]], + ['ksanyolc7461bits_6475',['kSanyoLC7461Bits',['../IRremoteESP8266_8h.html#ad067db05b273337e0df38d529094c9e8',1,'IRremoteESP8266.h']]], + ['ksanyolc7461commandbits_6476',['kSanyoLC7461CommandBits',['../IRremoteESP8266_8h.html#a5cd69a192be51634ce72a40398a6c0d7',1,'IRremoteESP8266.h']]], + ['ksanyolc7461commandmask_6477',['kSanyoLc7461CommandMask',['../ir__Sanyo_8cpp.html#abdd072e210a7616d564a9d4a7f798ad3',1,'ir_Sanyo.cpp']]], + ['ksanyolc7461hdrmark_6478',['kSanyoLc7461HdrMark',['../ir__Sanyo_8cpp.html#a0b2e520442dd96f8cd77969230713277',1,'ir_Sanyo.cpp']]], + ['ksanyolc7461hdrspace_6479',['kSanyoLc7461HdrSpace',['../ir__Sanyo_8cpp.html#aa9ca2469e22f66d6e5e3f4ef952484ba',1,'ir_Sanyo.cpp']]], + ['ksanyolc7461mincommandlength_6480',['kSanyoLc7461MinCommandLength',['../ir__Sanyo_8cpp.html#a237fac9264bba0014124a815133868b2',1,'ir_Sanyo.cpp']]], + ['ksanyolc7461mingap_6481',['kSanyoLc7461MinGap',['../ir__Sanyo_8cpp.html#aff7f31500dbe9939e223bed6b6c631a8',1,'ir_Sanyo.cpp']]], + ['ksanyolc7461onespace_6482',['kSanyoLc7461OneSpace',['../ir__Sanyo_8cpp.html#a52716e37d6943b01e9df37956f1a83de',1,'ir_Sanyo.cpp']]], + ['ksanyolc7461zerospace_6483',['kSanyoLc7461ZeroSpace',['../ir__Sanyo_8cpp.html#a4e386992c8fca642c259e86e34729a4d',1,'ir_Sanyo.cpp']]], + ['ksanyosa8650bbits_6484',['kSanyoSA8650BBits',['../IRremoteESP8266_8h.html#a2c572c8bfa811b7dc3a8a537cc642b85',1,'IRremoteESP8266.h']]], + ['ksanyosa8650bdoublespaceusecs_6485',['kSanyoSa8650bDoubleSpaceUsecs',['../ir__Sanyo_8cpp.html#a828caf6fd05e81cedee67c558b88a0b6',1,'ir_Sanyo.cpp']]], + ['ksanyosa8650bhdrmark_6486',['kSanyoSa8650bHdrMark',['../ir__Sanyo_8cpp.html#a9d0472d183a96b8ca71a2b704a06cac8',1,'ir_Sanyo.cpp']]], + ['ksanyosa8650bhdrspace_6487',['kSanyoSa8650bHdrSpace',['../ir__Sanyo_8cpp.html#ab432df3bd299b72b4449672d611798b7',1,'ir_Sanyo.cpp']]], + ['ksanyosa8650bonemark_6488',['kSanyoSa8650bOneMark',['../ir__Sanyo_8cpp.html#a8854c7bd32c1ec53e8e1869cd9dd8cdd',1,'ir_Sanyo.cpp']]], + ['ksanyosa8650brptlength_6489',['kSanyoSa8650bRptLength',['../ir__Sanyo_8cpp.html#a327ee6de7027aacfa9aa6ee8bdc74e3e',1,'ir_Sanyo.cpp']]], + ['ksanyosa8650bzeromark_6490',['kSanyoSa8650bZeroMark',['../ir__Sanyo_8cpp.html#a516a45a7934f23274fa302d7e711b43c',1,'ir_Sanyo.cpp']]], + ['ksavestr_6491',['kSaveStr',['../IRtext_8cpp.html#a24f9462727ee596a3ae16393c33e3ebc',1,'kSaveStr(): IRtext.cpp'],['../IRtext_8h.html#acb40b78a5269c43cc3e4f44d3da01069',1,'kSaveStr(): IRtext.cpp']]], + ['ksecondsstr_6492',['kSecondsStr',['../IRtext_8cpp.html#a282cb9785839a9da66a9333d788c0fb1',1,'kSecondsStr(): IRtext.cpp'],['../IRtext_8h.html#ad736b59d3fe45b3c06bd301af4d7b455',1,'kSecondsStr(): IRtext.cpp']]], + ['ksecondstr_6493',['kSecondStr',['../IRtext_8cpp.html#a5ec55e16709cbd2c4b1ff8c72c01c1f5',1,'kSecondStr(): IRtext.cpp'],['../IRtext_8h.html#ad3489e1c008bc517b8bf0271c40252d1',1,'kSecondStr(): IRtext.cpp']]], + ['ksensorstr_6494',['kSensorStr',['../IRtext_8cpp.html#aa7e6eab2fbc832f98d6560f62453c934',1,'kSensorStr(): IRtext.cpp'],['../IRtext_8h.html#a56ee9a96dd0a7ee0a5f95c286f6ea7e8',1,'kSensorStr(): IRtext.cpp']]], + ['ksensortempstr_6495',['kSensorTempStr',['../IRtext_8cpp.html#a756daa989457676d2af255428a01e1d5',1,'kSensorTempStr(): IRtext.cpp'],['../IRtext_8h.html#a03e76a09bade0c229fea1ce31fe8c9a1',1,'kSensorTempStr(): IRtext.cpp']]], + ['ksetstr_6496',['kSetStr',['../IRtext_8cpp.html#a27b5e437df44d4d41db9b296a1f236a1',1,'kSetStr(): IRtext.cpp'],['../IRtext_8h.html#a31d3426b8a8d1a35c47c88ef00023fce',1,'kSetStr(): IRtext.cpp']]], + ['ksharpacauto_6497',['kSharpAcAuto',['../ir__Sharp_8h.html#ad4e228b234598a84e11a76e7f2d27199',1,'ir_Sharp.h']]], + ['ksharpacbitcleanoffset_6498',['kSharpAcBitCleanOffset',['../ir__Sharp_8h.html#a3460827972f31d05070c638a57782286',1,'ir_Sharp.h']]], + ['ksharpacbitionoffset_6499',['kSharpAcBitIonOffset',['../ir__Sharp_8h.html#a73f967e9950d04941ed9f6815815fb23',1,'ir_Sharp.h']]], + ['ksharpacbitmark_6500',['kSharpAcBitMark',['../ir__Sharp_8h.html#ae73dd2c91b531bf3a52641b36f56ead7',1,'ir_Sharp.h']]], + ['ksharpacbits_6501',['kSharpAcBits',['../IRremoteESP8266_8h.html#a6c106a982acced5d8aeef98644002ca2',1,'IRremoteESP8266.h']]], + ['ksharpacbittimerenabled_6502',['kSharpAcBitTimerEnabled',['../ir__Sharp_8h.html#a083863299df4ff081be0add9d5082700',1,'ir_Sharp.h']]], + ['ksharpacbittimertype_6503',['kSharpAcBitTimerType',['../ir__Sharp_8h.html#ad47cf2f20c4589b9cbe6b583d62b4675',1,'ir_Sharp.h']]], + ['ksharpacbyteclean_6504',['kSharpAcByteClean',['../ir__Sharp_8h.html#a2f4a4ddf407413a52d45c955ebd5bcd5',1,'ir_Sharp.h']]], + ['ksharpacbytefan_6505',['kSharpAcByteFan',['../ir__Sharp_8h.html#a24139aa535ca54dcf45558da5ee2ac56',1,'ir_Sharp.h']]], + ['ksharpacbyteion_6506',['kSharpAcByteIon',['../ir__Sharp_8h.html#aaceee11c539050ba5ac368b9612131a4',1,'ir_Sharp.h']]], + ['ksharpacbytemode_6507',['kSharpAcByteMode',['../ir__Sharp_8h.html#af7d8a2ab79ae4f2ad48e569576fd34e8',1,'ir_Sharp.h']]], + ['ksharpacbytepowerspecial_6508',['kSharpAcBytePowerSpecial',['../ir__Sharp_8h.html#a44d180bd3babec15143ba8ea8aa18906',1,'ir_Sharp.h']]], + ['ksharpacbytespecial_6509',['kSharpAcByteSpecial',['../ir__Sharp_8h.html#a78ba1ef4993661f9dfaad776dff1b43e',1,'ir_Sharp.h']]], + ['ksharpacbyteswing_6510',['kSharpAcByteSwing',['../ir__Sharp_8h.html#aee580a3c6cfd75f75f46852d0f3df0db',1,'ir_Sharp.h']]], + ['ksharpacbytetemp_6511',['kSharpAcByteTemp',['../ir__Sharp_8h.html#a1b67ab12ed664517124fe3c1d7325927',1,'ir_Sharp.h']]], + ['ksharpacbytetimer_6512',['kSharpAcByteTimer',['../ir__Sharp_8h.html#af2fc9b6abae8ca6ca0d01b8c924386be',1,'ir_Sharp.h']]], + ['ksharpaccool_6513',['kSharpAcCool',['../ir__Sharp_8h.html#ae828d7e915f69cc1e9538839fc51c895',1,'ir_Sharp.h']]], + ['ksharpacdefaultrepeat_6514',['kSharpAcDefaultRepeat',['../IRremoteESP8266_8h.html#a7f0438831899e3df16f9002717c818b9',1,'IRremoteESP8266.h']]], + ['ksharpacdry_6515',['kSharpAcDry',['../ir__Sharp_8h.html#a50ae949b473ed4a6482fa00d747b2c0f',1,'ir_Sharp.h']]], + ['ksharpacfanauto_6516',['kSharpAcFanAuto',['../ir__Sharp_8h.html#a2ef78269271593420ea2bdc20025ca69',1,'ir_Sharp.h']]], + ['ksharpacfanhigh_6517',['kSharpAcFanHigh',['../ir__Sharp_8h.html#af29136d64c2f2a2515918ccf0ff0f594',1,'ir_Sharp.h']]], + ['ksharpacfanmax_6518',['kSharpAcFanMax',['../ir__Sharp_8h.html#a8b0aaa58a5f4caabea84e3b448793054',1,'ir_Sharp.h']]], + ['ksharpacfanmed_6519',['kSharpAcFanMed',['../ir__Sharp_8h.html#a7607f054da76f5e1508abf42d9cd71fc',1,'ir_Sharp.h']]], + ['ksharpacfanmin_6520',['kSharpAcFanMin',['../ir__Sharp_8h.html#a2372fdfbb0d8c2163a3eae5b8eda570a',1,'ir_Sharp.h']]], + ['ksharpacfanoffset_6521',['kSharpAcFanOffset',['../ir__Sharp_8h.html#ae95f02db8d9799ce726f5f467922a36c',1,'ir_Sharp.h']]], + ['ksharpacfansize_6522',['kSharpAcFanSize',['../ir__Sharp_8h.html#a2640f5c4eb0b4e62b9e2124a1fbfb6d2',1,'ir_Sharp.h']]], + ['ksharpacgap_6523',['kSharpAcGap',['../ir__Sharp_8h.html#a777eb0358ce3ef4528f086ff9ff7cd8d',1,'ir_Sharp.h']]], + ['ksharpachdrmark_6524',['kSharpAcHdrMark',['../ir__Sharp_8h.html#aff6f1e55de051762a0def881a5bb555c',1,'ir_Sharp.h']]], + ['ksharpachdrspace_6525',['kSharpAcHdrSpace',['../ir__Sharp_8h.html#a0ea5ff96afd358a8ad1be8d8ed808f04',1,'ir_Sharp.h']]], + ['ksharpacheat_6526',['kSharpAcHeat',['../ir__Sharp_8h.html#ab546d06a0b1f3477f88282f764f208cb',1,'ir_Sharp.h']]], + ['ksharpacmaxtemp_6527',['kSharpAcMaxTemp',['../ir__Sharp_8h.html#a6cfb060ea8c2f650fdd73b055cfda00a',1,'ir_Sharp.h']]], + ['ksharpacmintemp_6528',['kSharpAcMinTemp',['../ir__Sharp_8h.html#ad9ac5214b6cc780d9424ec7d038fe837',1,'ir_Sharp.h']]], + ['ksharpacmodesize_6529',['kSharpAcModeSize',['../ir__Sharp_8h.html#a7dfcf91a08bc37884cc4882c60004736',1,'ir_Sharp.h']]], + ['ksharpacofftimertype_6530',['kSharpAcOffTimerType',['../ir__Sharp_8h.html#ada633bea9c6c2ffd234c8262e92cebd5',1,'ir_Sharp.h']]], + ['ksharpaconespace_6531',['kSharpAcOneSpace',['../ir__Sharp_8h.html#a20e8eb7c8763fbddb20530badbaab38b',1,'ir_Sharp.h']]], + ['ksharpacontimertype_6532',['kSharpAcOnTimerType',['../ir__Sharp_8h.html#adce8625b00931645c7ccf54edf263c59',1,'ir_Sharp.h']]], + ['ksharpacpoweroff_6533',['kSharpAcPowerOff',['../ir__Sharp_8h.html#a5c13882a47bdd289507e8a5a23ec99d6',1,'ir_Sharp.h']]], + ['ksharpacpoweron_6534',['kSharpAcPowerOn',['../ir__Sharp_8h.html#af485487ea50dd2f9bc153e5f83dc5cf9',1,'ir_Sharp.h']]], + ['ksharpacpoweronfromoff_6535',['kSharpAcPowerOnFromOff',['../ir__Sharp_8h.html#ae484cf776fa47542f4d693c29052fc9f',1,'ir_Sharp.h']]], + ['ksharpacpowersetspecialoff_6536',['kSharpAcPowerSetSpecialOff',['../ir__Sharp_8h.html#a93b22ba4b5e68f8185ed28a6bb7c05dd',1,'ir_Sharp.h']]], + ['ksharpacpowersetspecialoffset_6537',['kSharpAcPowerSetSpecialOffset',['../ir__Sharp_8h.html#a0603455573e1dd203a5f6718efc12085',1,'ir_Sharp.h']]], + ['ksharpacpowersetspecialon_6538',['kSharpAcPowerSetSpecialOn',['../ir__Sharp_8h.html#a67aff6b22c0cfb89debb8ade7239f07e',1,'ir_Sharp.h']]], + ['ksharpacpowerspecialsize_6539',['kSharpAcPowerSpecialSize',['../ir__Sharp_8h.html#a233d545e942de27ec9e96d0d5e7afdb3',1,'ir_Sharp.h']]], + ['ksharpacpowertimersetting_6540',['kSharpAcPowerTimerSetting',['../ir__Sharp_8h.html#a208cb9446ea1f42db42a1f6e24b61219',1,'ir_Sharp.h']]], + ['ksharpacpowerunknown_6541',['kSharpAcPowerUnknown',['../ir__Sharp_8h.html#ab20172b860fa1401607f0678c682640f',1,'ir_Sharp.h']]], + ['ksharpacspecialfan_6542',['kSharpAcSpecialFan',['../ir__Sharp_8h.html#a6c1a1c535150f973eecb1a131d0c4780',1,'ir_Sharp.h']]], + ['ksharpacspecialpower_6543',['kSharpAcSpecialPower',['../ir__Sharp_8h.html#a843585897995ee15e39af0d452d8660d',1,'ir_Sharp.h']]], + ['ksharpacspecialswing_6544',['kSharpAcSpecialSwing',['../ir__Sharp_8h.html#a34127a7df393d2a5a84ca90e60e8507a',1,'ir_Sharp.h']]], + ['ksharpacspecialtempecono_6545',['kSharpAcSpecialTempEcono',['../ir__Sharp_8h.html#af2dcb54fc26802d1818ef88e6ddfc819',1,'ir_Sharp.h']]], + ['ksharpacspecialtimer_6546',['kSharpAcSpecialTimer',['../ir__Sharp_8h.html#a539b21c344db53fbfd4f17c91ab98139',1,'ir_Sharp.h']]], + ['ksharpacspecialtimerhalfhour_6547',['kSharpAcSpecialTimerHalfHour',['../ir__Sharp_8h.html#a1f9bf40a4af95689947c09559ed049bf',1,'ir_Sharp.h']]], + ['ksharpacspecialturbo_6548',['kSharpAcSpecialTurbo',['../ir__Sharp_8h.html#a270bb2bc83d4eb8974f498dd8eb299bb',1,'ir_Sharp.h']]], + ['ksharpacstatelength_6549',['kSharpAcStateLength',['../IRremoteESP8266_8h.html#a5192edb9406a8572e393918bab69e3c6',1,'IRremoteESP8266.h']]], + ['ksharpacswingnotoggle_6550',['kSharpAcSwingNoToggle',['../ir__Sharp_8h.html#a9c56d4f694ea69921ba2cb75f67426d6',1,'ir_Sharp.h']]], + ['ksharpacswingoffset_6551',['kSharpAcSwingOffset',['../ir__Sharp_8h.html#a61c5356e645867fa2eeda02c83e5b9ae',1,'ir_Sharp.h']]], + ['ksharpacswingsize_6552',['kSharpAcSwingSize',['../ir__Sharp_8h.html#aafec87d2ddea0fd56d176f1b5f80a6fa',1,'ir_Sharp.h']]], + ['ksharpacswingtoggle_6553',['kSharpAcSwingToggle',['../ir__Sharp_8h.html#aa6db653d25f67214819292b8f86af0e6',1,'ir_Sharp.h']]], + ['ksharpactimerhoursmax_6554',['kSharpAcTimerHoursMax',['../ir__Sharp_8h.html#a63af01993ba1e539dfb8dae67f42b9ae',1,'ir_Sharp.h']]], + ['ksharpactimerhoursoff_6555',['kSharpAcTimerHoursOff',['../ir__Sharp_8h.html#a462c10c12d828ba58d589cc365bd7be3',1,'ir_Sharp.h']]], + ['ksharpactimerhoursoffset_6556',['kSharpAcTimerHoursOffset',['../ir__Sharp_8h.html#aeb8d6ca49ba029bdb3663ff6b9c2cc4d',1,'ir_Sharp.h']]], + ['ksharpactimerhourssize_6557',['kSharpAcTimerHoursSize',['../ir__Sharp_8h.html#a965ed2ef8ba32a325ec41a351d88c17d',1,'ir_Sharp.h']]], + ['ksharpactimerincrement_6558',['kSharpAcTimerIncrement',['../ir__Sharp_8h.html#af32638e308a7034eb013b7ea9569273e',1,'ir_Sharp.h']]], + ['ksharpaczerospace_6559',['kSharpAcZeroSpace',['../ir__Sharp_8h.html#a5310e0404daae1a6e534dbaeaa9a9939',1,'ir_Sharp.h']]], + ['ksharpaddressbits_6560',['kSharpAddressBits',['../IRremoteESP8266_8h.html#a79c2f3cc459267cf0261124ddef47f5e',1,'IRremoteESP8266.h']]], + ['ksharpaddressmask_6561',['kSharpAddressMask',['../ir__Sharp_8cpp.html#a84fba003383cd4652fc804b97002f464',1,'ir_Sharp.cpp']]], + ['ksharpbitmark_6562',['kSharpBitMark',['../ir__Sharp_8cpp.html#ae2adc2bffb2b024faab8da363621733f',1,'ir_Sharp.cpp']]], + ['ksharpbitmarkticks_6563',['kSharpBitMarkTicks',['../ir__Sharp_8cpp.html#aa64bd0c359add4038c0143b5774627bb',1,'ir_Sharp.cpp']]], + ['ksharpbits_6564',['kSharpBits',['../IRremoteESP8266_8h.html#a8a74f9d7cec751cc0945fd89fa6237ae',1,'IRremoteESP8266.h']]], + ['ksharpcommandbits_6565',['kSharpCommandBits',['../IRremoteESP8266_8h.html#ae4cdfc8e358ec738d20c1bda49842ccf',1,'IRremoteESP8266.h']]], + ['ksharpcommandmask_6566',['kSharpCommandMask',['../ir__Sharp_8cpp.html#ad44eda54ade4bef4fdf4451fdb784950',1,'ir_Sharp.cpp']]], + ['ksharpgap_6567',['kSharpGap',['../ir__Sharp_8cpp.html#a77015be2a04274bcb332ec21cb75251e',1,'ir_Sharp.cpp']]], + ['ksharpgapticks_6568',['kSharpGapTicks',['../ir__Sharp_8cpp.html#a4aa110ec2934797f71ddf9bcd34498d1',1,'ir_Sharp.cpp']]], + ['ksharponespace_6569',['kSharpOneSpace',['../ir__Sharp_8cpp.html#a3359539480a203db37c2cf2efd88fdcc',1,'ir_Sharp.cpp']]], + ['ksharponespaceticks_6570',['kSharpOneSpaceTicks',['../ir__Sharp_8cpp.html#a12e18dfd195faae6ca581936434c9063',1,'ir_Sharp.cpp']]], + ['ksharptick_6571',['kSharpTick',['../ir__Sharp_8cpp.html#af417ab19220576243753903657923ba7',1,'ir_Sharp.cpp']]], + ['ksharptogglemask_6572',['kSharpToggleMask',['../ir__Sharp_8cpp.html#a2701123f01683c6927c23c7699bce13a',1,'ir_Sharp.cpp']]], + ['ksharpzerospace_6573',['kSharpZeroSpace',['../ir__Sharp_8cpp.html#ac2ad6123d938999e234896e1635e3063',1,'ir_Sharp.cpp']]], + ['ksharpzerospaceticks_6574',['kSharpZeroSpaceTicks',['../ir__Sharp_8cpp.html#af8c638f77ff29c2d20555343be80e5f0',1,'ir_Sharp.cpp']]], + ['ksherwoodbits_6575',['kSherwoodBits',['../IRremoteESP8266_8h.html#a94abd640c9e7aa225f4a8873a1ddea6a',1,'IRremoteESP8266.h']]], + ['ksherwoodminrepeat_6576',['kSherwoodMinRepeat',['../IRremoteESP8266_8h.html#a2e00b92b55657fc4e140eb85e3a414dc',1,'IRremoteESP8266.h']]], + ['ksilentstr_6577',['kSilentStr',['../IRtext_8cpp.html#a398d3c627c5b95c5d7adfb5308fc7de0',1,'kSilentStr(): IRtext.cpp'],['../IRtext_8h.html#a8efb4256a49dc0acd27d6995851d585e',1,'kSilentStr(): IRtext.cpp']]], + ['ksinglerepeat_6578',['kSingleRepeat',['../IRremoteESP8266_8h.html#a46835b1e2d279570fd818749e88180d4',1,'IRremoteESP8266.h']]], + ['ksleepstr_6579',['kSleepStr',['../IRtext_8cpp.html#a38068788c0ef50e6034dbcffeec1eb36',1,'kSleepStr(): IRtext.cpp'],['../IRtext_8h.html#af9ac743c367e179723b128ad69f124c5',1,'kSleepStr(): IRtext.cpp']]], + ['ksleeptimerstr_6580',['kSleepTimerStr',['../IRtext_8cpp.html#a3402e1f6d78e3c59b71bd0dfdf020b51',1,'kSleepTimerStr(): IRtext.cpp'],['../IRtext_8h.html#a86639857f884487cf3bedc91e71d6faa',1,'kSleepTimerStr(): IRtext.cpp']]], + ['kslowstr_6581',['kSlowStr',['../IRtext_8cpp.html#a3131a17a06dff31058579b301227a04f',1,'kSlowStr(): IRtext.cpp'],['../IRtext_8h.html#a171736ab5e3d59198ed740ea5fd93473',1,'kSlowStr(): IRtext.cpp']]], + ['ksony12bits_6582',['kSony12Bits',['../IRremoteESP8266_8h.html#aa16fdf708a67dbe22c85ad4bac9b05b6',1,'IRremoteESP8266.h']]], + ['ksony15bits_6583',['kSony15Bits',['../IRremoteESP8266_8h.html#ad868d68d289d618ace266519afa059f4',1,'IRremoteESP8266.h']]], + ['ksony20bits_6584',['kSony20Bits',['../IRremoteESP8266_8h.html#aa9cd1ff8036f6c3a288c4f34af4a5eb4',1,'IRremoteESP8266.h']]], + ['ksonyaltfreq_6585',['kSonyAltFreq',['../ir__Sony_8cpp.html#a05912a15a9a6a4a78416600adc7e526b',1,'ir_Sony.cpp']]], + ['ksonyhdrmark_6586',['kSonyHdrMark',['../ir__Sony_8cpp.html#afac5a232c82e81ac257ddfc94aa4f379',1,'ir_Sony.cpp']]], + ['ksonyhdrmarkticks_6587',['kSonyHdrMarkTicks',['../ir__Sony_8cpp.html#a89abc5f0556f38d462202d1de78cbddb',1,'ir_Sony.cpp']]], + ['ksonyminbits_6588',['kSonyMinBits',['../IRremoteESP8266_8h.html#a6f0794107a7643e0bec8de6de9e7621b',1,'IRremoteESP8266.h']]], + ['ksonymingap_6589',['kSonyMinGap',['../ir__Sony_8cpp.html#abfe3a5e1fa2a38ee556326b1ea0e7e11',1,'ir_Sony.cpp']]], + ['ksonymingapticks_6590',['kSonyMinGapTicks',['../ir__Sony_8cpp.html#a150d62f71f79295153bac4694bae0aa3',1,'ir_Sony.cpp']]], + ['ksonyminrepeat_6591',['kSonyMinRepeat',['../IRremoteESP8266_8h.html#a112408429fb4a5cca22a66a351453bad',1,'IRremoteESP8266.h']]], + ['ksonyonemark_6592',['kSonyOneMark',['../ir__Sony_8cpp.html#a490e7ca2b0f81848ae42eb57d0023d13',1,'ir_Sony.cpp']]], + ['ksonyonemarkticks_6593',['kSonyOneMarkTicks',['../ir__Sony_8cpp.html#ad41c0d0496661c2e066056de6974bfe9',1,'ir_Sony.cpp']]], + ['ksonyrptlength_6594',['kSonyRptLength',['../ir__Sony_8cpp.html#a24578b92cf53caa48fa3660f16ec90ec',1,'ir_Sony.cpp']]], + ['ksonyrptlengthticks_6595',['kSonyRptLengthTicks',['../ir__Sony_8cpp.html#a0a7f67ba27e03c35d5df35a2a14a1e19',1,'ir_Sony.cpp']]], + ['ksonyspace_6596',['kSonySpace',['../ir__Sony_8cpp.html#ad09a9eb0dc0b809cea0d0a2a8ff6b9fb',1,'ir_Sony.cpp']]], + ['ksonyspaceticks_6597',['kSonySpaceTicks',['../ir__Sony_8cpp.html#a80dccfab869821cadaf02df664d91eda',1,'ir_Sony.cpp']]], + ['ksonystdfreq_6598',['kSonyStdFreq',['../ir__Sony_8cpp.html#a5e5b14c45909411d160e051f0bc7c63d',1,'ir_Sony.cpp']]], + ['ksonytick_6599',['kSonyTick',['../ir__Sony_8cpp.html#a7ced75a5e9f06f5c68132665d27e01b8',1,'ir_Sony.cpp']]], + ['ksonyzeromark_6600',['kSonyZeroMark',['../ir__Sony_8cpp.html#a7808995a9d2755681f1461d578d5480b',1,'ir_Sony.cpp']]], + ['ksonyzeromarkticks_6601',['kSonyZeroMarkTicks',['../ir__Sony_8cpp.html#a542aed17f98a11ca89456eec507a5225',1,'ir_Sony.cpp']]], + ['kspace_6602',['kSpace',['../ir__Lasertag_8cpp.html#a7c41a2a72148172c93e39d5a2fd64036',1,'kSpace(): ir_Lasertag.cpp'],['../ir__MWM_8cpp.html#a7c41a2a72148172c93e39d5a2fd64036',1,'kSpace(): ir_MWM.cpp'],['../ir__RC5__RC6_8cpp.html#a7c41a2a72148172c93e39d5a2fd64036',1,'kSpace(): ir_RC5_RC6.cpp']]], + ['kspacelbracestr_6603',['kSpaceLBraceStr',['../IRtext_8cpp.html#a156ef0014809a3509e7b254a9585e0a1',1,'kSpaceLBraceStr(): IRtext.cpp'],['../IRtext_8h.html#a42a2d6b1e764138a5e20b7a34e0cff03',1,'kSpaceLBraceStr(): IRtext.cpp']]], + ['kspacestate_6604',['kSpaceState',['../IRrecv_8h.html#acc0d1931164a8967c210eb03a2d03e2a',1,'IRrecv.h']]], + ['kstartoffset_6605',['kStartOffset',['../IRrecv_8h.html#a44a836a34428f8f75b1ae566de4bb972',1,'IRrecv.h']]], + ['kstartstr_6606',['kStartStr',['../IRtext_8cpp.html#a2075a48eed571455a88e7dfbc3a547ef',1,'kStartStr(): IRtext.cpp'],['../IRtext_8h.html#ad030c0930697d3c295f3783e8519995c',1,'kStartStr(): IRtext.cpp']]], + ['kstatesizemax_6607',['kStateSizeMax',['../IRrecv_8h.html#ab7d82cf4c0937c9b1d59d75f6f347ab2',1,'IRrecv.h']]], + ['kstepstr_6608',['kStepStr',['../IRtext_8cpp.html#ac6c64c4bdc955b6528616db3a4b303c1',1,'kStepStr(): IRtext.cpp'],['../IRtext_8h.html#ad8cc5f179089e8497a9670492429d7e3',1,'kStepStr(): IRtext.cpp']]], + ['kstopstate_6609',['kStopState',['../IRrecv_8h.html#a0e87ae8496a061e394bc9f7f3415a9b3',1,'IRrecv.h']]], + ['kstopstr_6610',['kStopStr',['../IRtext_8cpp.html#a0466188f9064d18622304cd375b18390',1,'kStopStr(): IRtext.cpp'],['../IRtext_8h.html#a7037a67c71778fe06f9dc9b4363f6f9b',1,'kStopStr(): IRtext.cpp']]], + ['ksuperstr_6611',['kSuperStr',['../IRtext_8cpp.html#a81e6c76017bc819882a043ac8fcc2854',1,'kSuperStr(): IRtext.cpp'],['../IRtext_8h.html#af83fbe756a22ef800d40bc738be886c7',1,'kSuperStr(): IRtext.cpp']]], + ['kswinghstr_6612',['kSwingHStr',['../IRtext_8cpp.html#a12d4e0afe0f6b96af817ebc95eb0b6f4',1,'kSwingHStr(): IRtext.cpp'],['../IRtext_8h.html#acfad569446290c1da0c102b98344411c',1,'kSwingHStr(): IRtext.cpp']]], + ['kswingstr_6613',['kSwingStr',['../IRtext_8cpp.html#a106174aef3a46450c0a16bef7c36a8c5',1,'kSwingStr(): IRtext.cpp'],['../IRtext_8h.html#a56d1a94eae3422758b2762da008e243c',1,'kSwingStr(): IRtext.cpp']]], + ['kswingvmodestr_6614',['kSwingVModeStr',['../IRtext_8cpp.html#ab71be957190939e2b4643f2e56e1201f',1,'kSwingVModeStr(): IRtext.cpp'],['../IRtext_8h.html#a0c801e35becc1eab4cdf0076e1c99485',1,'kSwingVModeStr(): IRtext.cpp']]], + ['kswingvstr_6615',['kSwingVStr',['../IRtext_8cpp.html#a6dc1ec788e0659e82219534b5dbb79bc',1,'kSwingVStr(): IRtext.cpp'],['../IRtext_8h.html#a8415af77afcb671c3729d604be51fd22',1,'kSwingVStr(): IRtext.cpp']]], + ['kswingvtogglestr_6616',['kSwingVToggleStr',['../IRtext_8cpp.html#a3efcf06e5ac4d6309bad1b1d0e49a933',1,'kSwingVToggleStr(): IRtext.cpp'],['../IRtext_8h.html#a27ae4d475898878bd8e71111066629c6',1,'kSwingVToggleStr(): IRtext.cpp']]], + ['ksymphonybits_6617',['kSymphonyBits',['../IRremoteESP8266_8h.html#abb5b89578ab0757999530c0383f38533',1,'IRremoteESP8266.h']]], + ['ksymphonydefaultrepeat_6618',['kSymphonyDefaultRepeat',['../IRremoteESP8266_8h.html#a219b8495f77932c200680f7a2b133880',1,'IRremoteESP8266.h']]], + ['ksymphonyfootergap_6619',['kSymphonyFooterGap',['../ir__Symphony_8cpp.html#a363cf54f4e752932d5e341975c2445f4',1,'ir_Symphony.cpp']]], + ['ksymphonyonemark_6620',['kSymphonyOneMark',['../ir__Symphony_8cpp.html#a469bfa8046ba75f9ba7cda4996dd785d',1,'ir_Symphony.cpp']]], + ['ksymphonyonespace_6621',['kSymphonyOneSpace',['../ir__Symphony_8cpp.html#ab699747bdf28d5a89920041e9c5bb01b',1,'ir_Symphony.cpp']]], + ['ksymphonyzeromark_6622',['kSymphonyZeroMark',['../ir__Symphony_8cpp.html#a58f27b1b9da16ffe73448c7ae3998fc9',1,'ir_Symphony.cpp']]], + ['ksymphonyzerospace_6623',['kSymphonyZeroSpace',['../ir__Symphony_8cpp.html#a9aaf8db419618de847573d2019155287',1,'ir_Symphony.cpp']]], + ['ktcl112acauto_6624',['kTcl112AcAuto',['../ir__Tcl_8h.html#a11a982cc182e446d53ded658cb7a08b6',1,'ir_Tcl.h']]], + ['ktcl112acbiteconooffset_6625',['kTcl112AcBitEconoOffset',['../ir__Tcl_8h.html#a97c8948de72d702b859a7abccfbc423e',1,'ir_Tcl.h']]], + ['ktcl112acbithealthoffset_6626',['kTcl112AcBitHealthOffset',['../ir__Tcl_8h.html#a2acb2c5cd2f8b729047f9eecf93f96af',1,'ir_Tcl.h']]], + ['ktcl112acbitlightoffset_6627',['kTcl112AcBitLightOffset',['../ir__Tcl_8h.html#ad87c878f7a30a05418a5babfc52c0e9e',1,'ir_Tcl.h']]], + ['ktcl112acbitmark_6628',['kTcl112AcBitMark',['../ir__Tcl_8h.html#a45360de532d2262246bf57cb7c08604d',1,'ir_Tcl.h']]], + ['ktcl112acbits_6629',['kTcl112AcBits',['../IRremoteESP8266_8h.html#a4a60d79056d70d3d56067b0bb2ec00f4',1,'IRremoteESP8266.h']]], + ['ktcl112acbitswinghoffset_6630',['kTcl112AcBitSwingHOffset',['../ir__Tcl_8h.html#ad807894f92249e44d1725f18de013369',1,'ir_Tcl.h']]], + ['ktcl112acbitturbooffset_6631',['kTcl112AcBitTurboOffset',['../ir__Tcl_8h.html#a7a6e09c1b4620e96820b3b3c54fb0e18',1,'ir_Tcl.h']]], + ['ktcl112accool_6632',['kTcl112AcCool',['../ir__Tcl_8h.html#a4a4b778086b3ebf856b750fe0c4bd2c0',1,'ir_Tcl.h']]], + ['ktcl112acdefaultrepeat_6633',['kTcl112AcDefaultRepeat',['../IRremoteESP8266_8h.html#a97c82cec6d72845d9ab8a201b0fa5034',1,'IRremoteESP8266.h']]], + ['ktcl112acdry_6634',['kTcl112AcDry',['../ir__Tcl_8h.html#a1d9ec40c278fedf87acb7420ef861101',1,'ir_Tcl.h']]], + ['ktcl112acfan_6635',['kTcl112AcFan',['../ir__Tcl_8h.html#ae07f3dd0a84be27bcb13ba60f4fd025b',1,'ir_Tcl.h']]], + ['ktcl112acfanauto_6636',['kTcl112AcFanAuto',['../ir__Tcl_8h.html#a099935d6d2bf6ebb28332005036c59c0',1,'ir_Tcl.h']]], + ['ktcl112acfanhigh_6637',['kTcl112AcFanHigh',['../ir__Tcl_8h.html#aab9672bac3e83b2e3b3d2cc5f1aa0e1f',1,'ir_Tcl.h']]], + ['ktcl112acfanlow_6638',['kTcl112AcFanLow',['../ir__Tcl_8h.html#a5114fe3f978672fc62c0cd16f6d46dd7',1,'ir_Tcl.h']]], + ['ktcl112acfanmed_6639',['kTcl112AcFanMed',['../ir__Tcl_8h.html#ad8f34f1972da347a169e2eb4ddf3d835',1,'ir_Tcl.h']]], + ['ktcl112acfansize_6640',['kTcl112AcFanSize',['../ir__Tcl_8h.html#a802bbb6258edf6dcdd05a383db28e9d3',1,'ir_Tcl.h']]], + ['ktcl112acgap_6641',['kTcl112AcGap',['../ir__Tcl_8h.html#a9ccdf5ce9ce325b9813dadbdc855a469',1,'ir_Tcl.h']]], + ['ktcl112achalfdegreeoffset_6642',['kTcl112AcHalfDegreeOffset',['../ir__Tcl_8h.html#a1ba7d7fa8df2243330eafce097209651',1,'ir_Tcl.h']]], + ['ktcl112achdrmark_6643',['kTcl112AcHdrMark',['../ir__Tcl_8h.html#a56f9f7daf3ada77f8f844afd46a80de9',1,'ir_Tcl.h']]], + ['ktcl112achdrmarktolerance_6644',['kTcl112AcHdrMarkTolerance',['../ir__Tcl_8h.html#ab9d980747b2ddd1b7fb04f00d71af1e7',1,'ir_Tcl.h']]], + ['ktcl112achdrspace_6645',['kTcl112AcHdrSpace',['../ir__Tcl_8h.html#a9135b4d7496383ad3a7da7c3ac7c92b4',1,'ir_Tcl.h']]], + ['ktcl112acheat_6646',['kTcl112AcHeat',['../ir__Tcl_8h.html#ae573f856f0bdf50406e9be84b1aa8ade',1,'ir_Tcl.h']]], + ['ktcl112acmodesize_6647',['kTcl112AcModeSize',['../ir__Tcl_8h.html#a07e49881d14cb1c84cfbf3695ae64580',1,'ir_Tcl.h']]], + ['ktcl112aconespace_6648',['kTcl112AcOneSpace',['../ir__Tcl_8h.html#af1e67019978260ba3f514cd895b54dad',1,'ir_Tcl.h']]], + ['ktcl112acpoweroffset_6649',['kTcl112AcPowerOffset',['../ir__Tcl_8h.html#ad36204b310ec8a069f631322d806aa7f',1,'ir_Tcl.h']]], + ['ktcl112acstatelength_6650',['kTcl112AcStateLength',['../IRremoteESP8266_8h.html#a23ba2f5af02242e14ae7eefcd066152e',1,'IRremoteESP8266.h']]], + ['ktcl112acswingvoff_6651',['kTcl112AcSwingVOff',['../ir__Tcl_8h.html#aa78e1b544f392c251093d458e5d21e12',1,'ir_Tcl.h']]], + ['ktcl112acswingvoffset_6652',['kTcl112AcSwingVOffset',['../ir__Tcl_8h.html#ab0412b0d865eaf788a5672300575b1d8',1,'ir_Tcl.h']]], + ['ktcl112acswingvon_6653',['kTcl112AcSwingVOn',['../ir__Tcl_8h.html#a5406fbabd66478d601aebc6939a3788f',1,'ir_Tcl.h']]], + ['ktcl112acswingvsize_6654',['kTcl112AcSwingVSize',['../ir__Tcl_8h.html#a7bacb40b18b280da13b2d1b781c825e5',1,'ir_Tcl.h']]], + ['ktcl112actempmax_6655',['kTcl112AcTempMax',['../ir__Tcl_8h.html#a60efbe31031e1e9c3a17c7d80cac54cb',1,'ir_Tcl.h']]], + ['ktcl112actempmin_6656',['kTcl112AcTempMin',['../ir__Tcl_8h.html#a30fe65ec015bc4d91cd35ead9cc43dcc',1,'ir_Tcl.h']]], + ['ktcl112actolerance_6657',['kTcl112AcTolerance',['../ir__Tcl_8h.html#a13bbe794b2b59763f7f93f15a3f26820',1,'ir_Tcl.h']]], + ['ktcl112aczerospace_6658',['kTcl112AcZeroSpace',['../ir__Tcl_8h.html#abc05edaeb1a4fa7e6ccf9bda1f66b483',1,'ir_Tcl.h']]], + ['ktecoauto_6659',['kTecoAuto',['../ir__Teco_8h.html#a79178aa25d9f60c0a838285369e1b910',1,'ir_Teco.h']]], + ['ktecobitmark_6660',['kTecoBitMark',['../ir__Teco_8cpp.html#a0aa2e352f4a61027b17467e92863883b',1,'ir_Teco.cpp']]], + ['ktecobits_6661',['kTecoBits',['../IRremoteESP8266_8h.html#aee01958e9d97a70a6881cf560ca0ca9d',1,'IRremoteESP8266.h']]], + ['ktecocool_6662',['kTecoCool',['../ir__Teco_8h.html#a554686c72b6bc487d03c9461f9633a6b',1,'ir_Teco.h']]], + ['ktecodefaultrepeat_6663',['kTecoDefaultRepeat',['../IRremoteESP8266_8h.html#a095362359f34c1ee5ab71d56e6d64f64',1,'IRremoteESP8266.h']]], + ['ktecodry_6664',['kTecoDry',['../ir__Teco_8h.html#af7efcf371967eb97fd31d54016a82006',1,'ir_Teco.h']]], + ['ktecofan_6665',['kTecoFan',['../ir__Teco_8h.html#a7385fe198242c9203e3a5d5ffb7beb4d',1,'ir_Teco.h']]], + ['ktecofanauto_6666',['kTecoFanAuto',['../ir__Teco_8h.html#a43e58c0158efac1c4e5497c619b5674c',1,'ir_Teco.h']]], + ['ktecofanhigh_6667',['kTecoFanHigh',['../ir__Teco_8h.html#a0a73f5f892e7f9812793fbf5dab458dd',1,'ir_Teco.h']]], + ['ktecofanlow_6668',['kTecoFanLow',['../ir__Teco_8h.html#abac7443a86fb304376dd94a9c10e6940',1,'ir_Teco.h']]], + ['ktecofanmed_6669',['kTecoFanMed',['../ir__Teco_8h.html#a35f313943f9e2f5b69d5237fdaa64914',1,'ir_Teco.h']]], + ['ktecofanoffset_6670',['kTecoFanOffset',['../ir__Teco_8h.html#ae70841ad987ac89abaaf99b11655eaae',1,'ir_Teco.h']]], + ['ktecofansize_6671',['kTecoFanSize',['../ir__Teco_8h.html#a45734d2be952e3faa796d86245eaf241',1,'ir_Teco.h']]], + ['ktecogap_6672',['kTecoGap',['../ir__Teco_8cpp.html#a6a153d84287fba3bd11e3e5054fd7e30',1,'ir_Teco.cpp']]], + ['ktecohdrmark_6673',['kTecoHdrMark',['../ir__Teco_8cpp.html#ada983ce2d6f03949cddfe06191ab05d9',1,'ir_Teco.cpp']]], + ['ktecohdrspace_6674',['kTecoHdrSpace',['../ir__Teco_8cpp.html#acf417d42fd39dbaf06282162ab5b17e2',1,'ir_Teco.cpp']]], + ['ktecoheat_6675',['kTecoHeat',['../ir__Teco_8h.html#ab6f9dbeb2838b124be12d08fd9b209bb',1,'ir_Teco.h']]], + ['ktecohumidoffset_6676',['kTecoHumidOffset',['../ir__Teco_8h.html#ad95126f6815d24b5d1b38e44677f3d7e',1,'ir_Teco.h']]], + ['ktecolightoffset_6677',['kTecoLightOffset',['../ir__Teco_8h.html#a5dc2cb366974b2baa9f7cbfb26d90415',1,'ir_Teco.h']]], + ['ktecomaxtemp_6678',['kTecoMaxTemp',['../ir__Teco_8h.html#a1c24aa0cc4d475a5eb97d5208f4dcf06',1,'ir_Teco.h']]], + ['ktecomintemp_6679',['kTecoMinTemp',['../ir__Teco_8h.html#a54da99bfcbea5e076c3ca2934e769ab1',1,'ir_Teco.h']]], + ['ktecomodeoffset_6680',['kTecoModeOffset',['../ir__Teco_8h.html#a1aca7a8a2822cd1494dabeda5b11b9be',1,'ir_Teco.h']]], + ['ktecoonespace_6681',['kTecoOneSpace',['../ir__Teco_8cpp.html#a62eccbf6773ea8fbc18432627c62d0d5',1,'ir_Teco.cpp']]], + ['ktecopoweroffset_6682',['kTecoPowerOffset',['../ir__Teco_8h.html#a4eec88582ed29e424549497deb9eceef',1,'ir_Teco.h']]], + ['ktecoreset_6683',['kTecoReset',['../ir__Teco_8h.html#acf559a2cd772835ce46c3f673cd95806',1,'ir_Teco.h']]], + ['ktecosaveoffset_6684',['kTecoSaveOffset',['../ir__Teco_8h.html#a63d5efa7cfc84ee22d3575cc713d1f62',1,'ir_Teco.h']]], + ['ktecosleepoffset_6685',['kTecoSleepOffset',['../ir__Teco_8h.html#ae7da65034a8a84e79ebb1497e56e38fe',1,'ir_Teco.h']]], + ['ktecoswingoffset_6686',['kTecoSwingOffset',['../ir__Teco_8h.html#aaa821eb3ad9a5edadba2b83b6d2094b6',1,'ir_Teco.h']]], + ['ktecotempoffset_6687',['kTecoTempOffset',['../ir__Teco_8h.html#ae887d9c5702d63e4b4fa5250ed5bf0d9',1,'ir_Teco.h']]], + ['ktecotempsize_6688',['kTecoTempSize',['../ir__Teco_8h.html#a635db8dbba35e4326958fca6dfe67603',1,'ir_Teco.h']]], + ['ktecotimerhalfhouroffset_6689',['kTecoTimerHalfHourOffset',['../ir__Teco_8h.html#a2692a59900c10b6da6662fac5a312e04',1,'ir_Teco.h']]], + ['ktecotimeronoffset_6690',['kTecoTimerOnOffset',['../ir__Teco_8h.html#a7bcf79fa5e5280ad35c9a9512b2fdc7f',1,'ir_Teco.h']]], + ['ktecotimertenshoursoffset_6691',['kTecoTimerTensHoursOffset',['../ir__Teco_8h.html#adaa73601e31fa7217d371645d835f0ca',1,'ir_Teco.h']]], + ['ktecotimertenshourssize_6692',['kTecoTimerTensHoursSize',['../ir__Teco_8h.html#a57bf1b777b9b56aad4f224b6bba1218c',1,'ir_Teco.h']]], + ['ktecotimerunithoursoffset_6693',['kTecoTimerUnitHoursOffset',['../ir__Teco_8h.html#ac47fc38319e7e1d90d42c789b806cdbd',1,'ir_Teco.h']]], + ['ktecotimerunithourssize_6694',['kTecoTimerUnitHoursSize',['../ir__Teco_8h.html#a54ac664e32ce0d8b4d8d4d4d459dbc46',1,'ir_Teco.h']]], + ['ktecozerospace_6695',['kTecoZeroSpace',['../ir__Teco_8cpp.html#a8dc1f6ea44519a0930b48f69a83a7363',1,'ir_Teco.cpp']]], + ['ktempdownstr_6696',['kTempDownStr',['../IRtext_8cpp.html#a3fa3262c5631c9357a5723c70dc3be12',1,'kTempDownStr(): IRtext.cpp'],['../IRtext_8h.html#a3d367a899d7e8ed20844bb3c48bf6395',1,'kTempDownStr(): IRtext.cpp']]], + ['ktempstr_6697',['kTempStr',['../IRtext_8cpp.html#a487bd9a4225536aba2595be0b5cb8039',1,'kTempStr(): IRtext.cpp'],['../IRtext_8h.html#a87652df1cf724353547f27a9ebde5edb',1,'kTempStr(): IRtext.cpp']]], + ['ktempupstr_6698',['kTempUpStr',['../IRtext_8cpp.html#a7c4f18322b600aaaf5a8716654d05dc3',1,'kTempUpStr(): IRtext.cpp'],['../IRtext_8h.html#a71687df5bc94e4ca18cf59c9ff238e86',1,'kTempUpStr(): IRtext.cpp']]], + ['kthreeletterdayofweekstr_6699',['kThreeLetterDayOfWeekStr',['../IRtext_8cpp.html#ae16da0464743313a1fbeae92dcfcebbd',1,'kThreeLetterDayOfWeekStr(): IRtext.cpp'],['../IRtext_8h.html#a837ecfeff9a1bc7546016229e9f2ddfb',1,'kThreeLetterDayOfWeekStr(): IRtext.cpp']]], + ['ktimeoutms_6700',['kTimeoutMs',['../IRrecv_8h.html#ad37e9659aaef29c541802d9759e0ab7b',1,'IRrecv.h']]], + ['ktimerstr_6701',['kTimerStr',['../IRtext_8cpp.html#a2b5219ba887cfbc578fb880ebada832a',1,'kTimerStr(): IRtext.cpp'],['../IRtext_8h.html#a36fa3584a89f6e48757eba8f3df7e109',1,'kTimerStr(): IRtext.cpp']]], + ['ktimesep_6702',['kTimeSep',['../IRtext_8cpp.html#a277b588db53ec31ab7b0d287310c6d50',1,'kTimeSep(): IRtext.cpp'],['../IRtext_8h.html#a277b588db53ec31ab7b0d287310c6d50',1,'kTimeSep(): IRtext.cpp']]], + ['ktogglestr_6703',['kToggleStr',['../IRtext_8cpp.html#a33860b90859d19191c9759b099283b37',1,'kToggleStr(): IRtext.cpp'],['../IRtext_8h.html#a05b1e2f809dadf05e22e1cb1d1a7f07e',1,'kToggleStr(): IRtext.cpp']]], + ['ktolerance_6704',['kTolerance',['../IRrecv_8h.html#a7884008b3a738dfc7bd8658655e10272',1,'IRrecv.h']]], + ['ktopstr_6705',['kTopStr',['../IRtext_8cpp.html#a65a8bf89c9dd0277607478277c0c7088',1,'kTopStr(): IRtext.cpp'],['../IRtext_8h.html#a6bb6abfc54409b801dcb591f036635d2',1,'kTopStr(): IRtext.cpp']]], + ['ktoshibaacauto_6706',['kToshibaAcAuto',['../ir__Toshiba_8h.html#a4730189595a884ae6535805948e096aa',1,'ir_Toshiba.h']]], + ['ktoshibaacbitmark_6707',['kToshibaAcBitMark',['../ir__Toshiba_8cpp.html#adff1c244103ff274243b8e20ca209866',1,'ir_Toshiba.cpp']]], + ['ktoshibaacbits_6708',['kToshibaACBits',['../IRremoteESP8266_8h.html#a172dde7867fa9a68902c3ad7ea9629b0',1,'IRremoteESP8266.h']]], + ['ktoshibaaccool_6709',['kToshibaAcCool',['../ir__Toshiba_8h.html#a2f30e65bb092365d1a8bcb1f3395333a',1,'ir_Toshiba.h']]], + ['ktoshibaacdry_6710',['kToshibaAcDry',['../ir__Toshiba_8h.html#a10b77d1038efc59775398789c33af91e',1,'ir_Toshiba.h']]], + ['ktoshibaacfanauto_6711',['kToshibaAcFanAuto',['../ir__Toshiba_8h.html#a69f52e19a5b0e68abda00b680fbef7f6',1,'ir_Toshiba.h']]], + ['ktoshibaacfanmax_6712',['kToshibaAcFanMax',['../ir__Toshiba_8h.html#a0f6ffde3491f464166d6064d7dfe5ba4',1,'ir_Toshiba.h']]], + ['ktoshibaacfanmed_6713',['kToshibaAcFanMed',['../ir__Toshiba_8h.html#a3ff967af7d1a30c7c5cb958eaa5cbd58',1,'ir_Toshiba.h']]], + ['ktoshibaacfanmin_6714',['kToshibaAcFanMin',['../ir__Toshiba_8h.html#ab2c5eea9ccabf2e0e56bc03baec5d898',1,'ir_Toshiba.h']]], + ['ktoshibaacfanoffset_6715',['kToshibaAcFanOffset',['../ir__Toshiba_8h.html#a8276d25876329968bbf36eac3598972c',1,'ir_Toshiba.h']]], + ['ktoshibaacfansize_6716',['kToshibaAcFanSize',['../ir__Toshiba_8h.html#a5a91c19e799721560a5a9ef77a245888',1,'ir_Toshiba.h']]], + ['ktoshibaachdrmark_6717',['kToshibaAcHdrMark',['../ir__Toshiba_8cpp.html#a2eac25ff2a381ad6690623641153a780',1,'ir_Toshiba.cpp']]], + ['ktoshibaachdrspace_6718',['kToshibaAcHdrSpace',['../ir__Toshiba_8cpp.html#a0ae9047d5a204f320c06736fa40d0a7d',1,'ir_Toshiba.cpp']]], + ['ktoshibaacheat_6719',['kToshibaAcHeat',['../ir__Toshiba_8h.html#aa9ec24f9a5e460aa7017f642ce7a4c0d',1,'ir_Toshiba.h']]], + ['ktoshibaacmaxtemp_6720',['kToshibaAcMaxTemp',['../ir__Toshiba_8h.html#a475028a2a519e3310506ceac0a5dc4e6',1,'ir_Toshiba.h']]], + ['ktoshibaacmingap_6721',['kToshibaAcMinGap',['../ir__Toshiba_8cpp.html#ade7642284aa7c6a638b9fab45610cc59',1,'ir_Toshiba.cpp']]], + ['ktoshibaacminrepeat_6722',['kToshibaACMinRepeat',['../IRremoteESP8266_8h.html#a8fca6a7c3cd608ff49cab35f24af0546',1,'IRremoteESP8266.h']]], + ['ktoshibaacmintemp_6723',['kToshibaAcMinTemp',['../ir__Toshiba_8h.html#ad0e8e76aabc38ac7ba2f13a009de98e0',1,'ir_Toshiba.h']]], + ['ktoshibaacmodeoffset_6724',['kToshibaAcModeOffset',['../ir__Toshiba_8h.html#a4e097e34b0f2dd9eaacf94d043f726d0',1,'ir_Toshiba.h']]], + ['ktoshibaacmodesize_6725',['kToshibaAcModeSize',['../ir__Toshiba_8h.html#a920d55af8e499a7c2293a7d8180104da',1,'ir_Toshiba.h']]], + ['ktoshibaaconespace_6726',['kToshibaAcOneSpace',['../ir__Toshiba_8cpp.html#a787330c9e5f9d30e8df157acc15f56dd',1,'ir_Toshiba.cpp']]], + ['ktoshibaacpoweroffset_6727',['kToshibaAcPowerOffset',['../ir__Toshiba_8h.html#adfd3caac2bd0b636508afbbf67b04dcd',1,'ir_Toshiba.h']]], + ['ktoshibaacstatelength_6728',['kToshibaACStateLength',['../IRremoteESP8266_8h.html#ad3be6a1b9241c20bb1464a2cb80b97d2',1,'IRremoteESP8266.h']]], + ['ktoshibaactempoffset_6729',['kToshibaAcTempOffset',['../ir__Toshiba_8h.html#a68be75c21288e249d7b44fe9648de91f',1,'ir_Toshiba.h']]], + ['ktoshibaactempsize_6730',['kToshibaAcTempSize',['../ir__Toshiba_8h.html#a89ec8108586e0d5b9f58a160f4db37c8',1,'ir_Toshiba.h']]], + ['ktoshibaaczerospace_6731',['kToshibaAcZeroSpace',['../ir__Toshiba_8cpp.html#ab2fc2833cfb31d872894073687eebd99',1,'ir_Toshiba.cpp']]], + ['ktrotecauto_6732',['kTrotecAuto',['../ir__Trotec_8h.html#a53b2687b96f8e69ec6f57dd2ac7a6dfa',1,'ir_Trotec.h']]], + ['ktrotecbitmark_6733',['kTrotecBitMark',['../ir__Trotec_8cpp.html#a870b2da19855eff625a2834ca7fd8765',1,'ir_Trotec.cpp']]], + ['ktrotecbits_6734',['kTrotecBits',['../IRremoteESP8266_8h.html#ab819cb0a34937714dcb10059799c26e2',1,'IRremoteESP8266.h']]], + ['ktroteccool_6735',['kTrotecCool',['../ir__Trotec_8h.html#add33a35046e4270ad9ff3b998526d5d1',1,'ir_Trotec.h']]], + ['ktrotecdefaultrepeat_6736',['kTrotecDefaultRepeat',['../IRremoteESP8266_8h.html#a4c0411462f2854a8606deca09ed15df5',1,'IRremoteESP8266.h']]], + ['ktrotecdeftemp_6737',['kTrotecDefTemp',['../ir__Trotec_8h.html#ac28d1d0ea6db18716a7d9d21e84178c0',1,'ir_Trotec.h']]], + ['ktrotecdry_6738',['kTrotecDry',['../ir__Trotec_8h.html#abdaa1836c6bc90b1d5813df028a76e21',1,'ir_Trotec.h']]], + ['ktrotecfan_6739',['kTrotecFan',['../ir__Trotec_8h.html#a9309d528d50dd542a5184a51fb101a6a',1,'ir_Trotec.h']]], + ['ktrotecfanhigh_6740',['kTrotecFanHigh',['../ir__Trotec_8h.html#ae780f0bb6b9b83f3dbcc1c1e282e5436',1,'ir_Trotec.h']]], + ['ktrotecfanlow_6741',['kTrotecFanLow',['../ir__Trotec_8h.html#aa1c3695c1becc935d2a3b2691996a17b',1,'ir_Trotec.h']]], + ['ktrotecfanmed_6742',['kTrotecFanMed',['../ir__Trotec_8h.html#abae1944f529099ff4736b6cb13bcbeda',1,'ir_Trotec.h']]], + ['ktrotecfanoffset_6743',['kTrotecFanOffset',['../ir__Trotec_8h.html#a3b9034b96268707f7b6fc45a16499479',1,'ir_Trotec.h']]], + ['ktrotecfansize_6744',['kTrotecFanSize',['../ir__Trotec_8h.html#a89d7de622d0f53f800c1a5a2887a81e4',1,'ir_Trotec.h']]], + ['ktrotecgap_6745',['kTrotecGap',['../ir__Trotec_8cpp.html#a753ba93d7b757dc58fcf1b4a6bb65ff6',1,'ir_Trotec.cpp']]], + ['ktrotecgapend_6746',['kTrotecGapEnd',['../ir__Trotec_8cpp.html#a5fcc4a020bcebfe90abe12d4a47de372',1,'ir_Trotec.cpp']]], + ['ktrotechdrmark_6747',['kTrotecHdrMark',['../ir__Trotec_8cpp.html#a809faed7ee2fef78a5b8271a2c5ddd10',1,'ir_Trotec.cpp']]], + ['ktrotechdrspace_6748',['kTrotecHdrSpace',['../ir__Trotec_8cpp.html#a5d42cd98bf737dd8161572afa393be1e',1,'ir_Trotec.cpp']]], + ['ktrotecintro1_6749',['kTrotecIntro1',['../ir__Trotec_8h.html#aabc5c6a9b4867c25d84ffe2839e88564',1,'ir_Trotec.h']]], + ['ktrotecintro2_6750',['kTrotecIntro2',['../ir__Trotec_8h.html#ac33de8b2fc4b70bb272a56f6bbb68e34',1,'ir_Trotec.h']]], + ['ktrotecmaxtemp_6751',['kTrotecMaxTemp',['../ir__Trotec_8h.html#abfe4004dcac892f575ec1efb09567595',1,'ir_Trotec.h']]], + ['ktrotecmaxtimer_6752',['kTrotecMaxTimer',['../ir__Trotec_8h.html#a8467d1b9983d5750a61817cacb148efd',1,'ir_Trotec.h']]], + ['ktrotecmintemp_6753',['kTrotecMinTemp',['../ir__Trotec_8h.html#a091904af9fee2384e137feab274af7f8',1,'ir_Trotec.h']]], + ['ktrotecmodeoffset_6754',['kTrotecModeOffset',['../ir__Trotec_8h.html#aa0d48802845d5cf0410550bb98e4cbb5',1,'ir_Trotec.h']]], + ['ktrotecmodesize_6755',['kTrotecModeSize',['../ir__Trotec_8h.html#ae45ea2f0f8b5d09568c0322e1735ca85',1,'ir_Trotec.h']]], + ['ktroteconespace_6756',['kTrotecOneSpace',['../ir__Trotec_8cpp.html#a570aa73a82089906971932212d99a283',1,'ir_Trotec.cpp']]], + ['ktrotecpowerbitoffset_6757',['kTrotecPowerBitOffset',['../ir__Trotec_8h.html#a11fcdfe886385de6363d06371cdcff43',1,'ir_Trotec.h']]], + ['ktrotecsleepbitoffset_6758',['kTrotecSleepBitOffset',['../ir__Trotec_8h.html#af81754a025119a3dc9924df5508b18c0',1,'ir_Trotec.h']]], + ['ktrotecstatelength_6759',['kTrotecStateLength',['../IRremoteESP8266_8h.html#ae1d2aa52fef81f03b92c35f4970728d2',1,'IRremoteESP8266.h']]], + ['ktrotectempoffset_6760',['kTrotecTempOffset',['../ir__Trotec_8h.html#a08a844aefec8d0440365c9204a01034c',1,'ir_Trotec.h']]], + ['ktrotectempsize_6761',['kTrotecTempSize',['../ir__Trotec_8h.html#a1141680a808f41513548a8747c37f975',1,'ir_Trotec.h']]], + ['ktrotectimerbitoffset_6762',['kTrotecTimerBitOffset',['../ir__Trotec_8h.html#aad59f1284ec04736a3c6629c3cd87731',1,'ir_Trotec.h']]], + ['ktroteczerospace_6763',['kTrotecZeroSpace',['../ir__Trotec_8cpp.html#a8e8f85e7b8a8157eb425316b5108d717',1,'ir_Trotec.cpp']]], + ['ktruestr_6764',['kTrueStr',['../IRtext_8cpp.html#a28a627d6f48d7d06a560f9613e4550fa',1,'kTrueStr(): IRtext.cpp'],['../IRtext_8h.html#aca6e78a25b9dacd2508069f0a6b919c0',1,'kTrueStr(): IRtext.cpp']]], + ['kturbostr_6765',['kTurboStr',['../IRtext_8cpp.html#a9f3f7395d980887699ac5a0c146d37d2',1,'kTurboStr(): IRtext.cpp'],['../IRtext_8h.html#a3ced6d2a545174133308d7803157f7f8',1,'kTurboStr(): IRtext.cpp']]], + ['kunknownstr_6766',['kUnknownStr',['../IRtext_8cpp.html#a9c6c6d47ce3eb07cc607faa600978029',1,'kUnknownStr(): IRtext.cpp'],['../IRtext_8h.html#aa59176b31741b60729d4279817a7da1b',1,'kUnknownStr(): IRtext.cpp']]], + ['kunknownthreshold_6767',['kUnknownThreshold',['../IRrecv_8h.html#aa6b5a940c7a0432aa82a8d823202cd7f',1,'IRrecv.h']]], + ['kupperstr_6768',['kUpperStr',['../IRtext_8cpp.html#a887bb7c61f38014d21b025c67102fa0b',1,'kUpperStr(): IRtext.cpp'],['../IRtext_8h.html#a5aea60591627481d90688f655b2eb82a',1,'kUpperStr(): IRtext.cpp']]], + ['kupstr_6769',['kUpStr',['../IRtext_8cpp.html#ab970b3d5239f08f21a8e5e2eae49739f',1,'kUpStr(): IRtext.cpp'],['../IRtext_8h.html#a8672abbd2a279c032f0435ed75143b1a',1,'kUpStr(): IRtext.cpp']]], + ['kusedeftol_6770',['kUseDefTol',['../IRrecv_8h.html#a05025e8bd724ae2d0c7fea6e924ca84c',1,'IRrecv.h']]], + ['kvestelacauto_6771',['kVestelAcAuto',['../ir__Vestel_8h.html#a157e879cbe3b216075e3b7b2db5fdc3c',1,'ir_Vestel.h']]], + ['kvestelacbitmark_6772',['kVestelAcBitMark',['../ir__Vestel_8h.html#a70d7198002c61529956625986aa533f0',1,'ir_Vestel.h']]], + ['kvestelacbits_6773',['kVestelAcBits',['../IRremoteESP8266_8h.html#ae31945a1ce90b2d4c33b5c91d980d3a7',1,'IRremoteESP8266.h']]], + ['kvestelacchecksumoffset_6774',['kVestelAcChecksumOffset',['../ir__Vestel_8h.html#ac3fa10d1dba540a82b77cc88b01f9a7e',1,'ir_Vestel.h']]], + ['kvestelacchecksumsize_6775',['kVestelAcChecksumSize',['../ir__Vestel_8h.html#a61979a3b944ce7309c5b3f5b24b0a14c',1,'ir_Vestel.h']]], + ['kvestelaccool_6776',['kVestelAcCool',['../ir__Vestel_8h.html#aa2ec681dd63a976a6b2b182ae590e020',1,'ir_Vestel.h']]], + ['kvestelacdry_6777',['kVestelAcDry',['../ir__Vestel_8h.html#a21a255842a75a932a3a0735851d9c197',1,'ir_Vestel.h']]], + ['kvestelacfan_6778',['kVestelAcFan',['../ir__Vestel_8h.html#aeabf5404a3f66fd1428b6e4c09f24c08',1,'ir_Vestel.h']]], + ['kvestelacfanauto_6779',['kVestelAcFanAuto',['../ir__Vestel_8h.html#ac2f3175c25844414de2c2489595dd851',1,'ir_Vestel.h']]], + ['kvestelacfanautocool_6780',['kVestelAcFanAutoCool',['../ir__Vestel_8h.html#ab40dc2ebe05c77e701e2d5acf16b2658',1,'ir_Vestel.h']]], + ['kvestelacfanautohot_6781',['kVestelAcFanAutoHot',['../ir__Vestel_8h.html#a95dee8baacedb7aa62edbdecf766cdc1',1,'ir_Vestel.h']]], + ['kvestelacfanhigh_6782',['kVestelAcFanHigh',['../ir__Vestel_8h.html#acae63d91ee2a2b448fe1a68b2472e4a3',1,'ir_Vestel.h']]], + ['kvestelacfanlow_6783',['kVestelAcFanLow',['../ir__Vestel_8h.html#a21ce5e539ecb764be8dbad33914f4b87',1,'ir_Vestel.h']]], + ['kvestelacfanmed_6784',['kVestelAcFanMed',['../ir__Vestel_8h.html#a265fa70e0e38caefb45ed007eb25a430',1,'ir_Vestel.h']]], + ['kvestelacfanoffset_6785',['kVestelAcFanOffset',['../ir__Vestel_8h.html#af0f1c1989322f256b7b1b5dba613feba',1,'ir_Vestel.h']]], + ['kvestelacfansize_6786',['kVestelAcFanSize',['../ir__Vestel_8h.html#ae61e23edfb71206e736497ab479c08ad',1,'ir_Vestel.h']]], + ['kvestelachdrmark_6787',['kVestelAcHdrMark',['../ir__Vestel_8h.html#a32871ab992bfee13918a50f04508a95a',1,'ir_Vestel.h']]], + ['kvestelachdrspace_6788',['kVestelAcHdrSpace',['../ir__Vestel_8h.html#a2389409048e409b411ea8416829c06ef',1,'ir_Vestel.h']]], + ['kvestelacheat_6789',['kVestelAcHeat',['../ir__Vestel_8h.html#a33d36614992862c41f5e48548b0a45f1',1,'ir_Vestel.h']]], + ['kvestelachouroffset_6790',['kVestelAcHourOffset',['../ir__Vestel_8h.html#af4c3729a4b9df092e01d74109f539cca',1,'ir_Vestel.h']]], + ['kvestelachoursize_6791',['kVestelAcHourSize',['../ir__Vestel_8h.html#a2c0fd442d92620ca062637d01258bacf',1,'ir_Vestel.h']]], + ['kvestelacion_6792',['kVestelAcIon',['../ir__Vestel_8h.html#a6a661c914fd67e261e2148d797789339',1,'ir_Vestel.h']]], + ['kvestelacionoffset_6793',['kVestelAcIonOffset',['../ir__Vestel_8h.html#a9b1cd19c4b0037714f1c47ba031edd0b',1,'ir_Vestel.h']]], + ['kvestelacmaxtemp_6794',['kVestelAcMaxTemp',['../ir__Vestel_8h.html#a4e49902b2e4fe049fd5969b4532cc7b4',1,'ir_Vestel.h']]], + ['kvestelacmintempc_6795',['kVestelAcMinTempC',['../ir__Vestel_8h.html#ae597f05d0886a5a2aa8c43db187a657b',1,'ir_Vestel.h']]], + ['kvestelacmintemph_6796',['kVestelAcMinTempH',['../ir__Vestel_8h.html#a06977d297c84adac7927c80c7b0e7297',1,'ir_Vestel.h']]], + ['kvestelacminuteoffset_6797',['kVestelAcMinuteOffset',['../ir__Vestel_8h.html#a7c5f318a30e86394af19265e73b68034',1,'ir_Vestel.h']]], + ['kvestelacminutesize_6798',['kVestelAcMinuteSize',['../ir__Vestel_8h.html#a8abd51cd0d0404ae8bb139690bf55eb0',1,'ir_Vestel.h']]], + ['kvestelacmodeoffset_6799',['kVestelAcModeOffset',['../ir__Vestel_8h.html#a5334689cb0fbeaee67133f1f86bdce58',1,'ir_Vestel.h']]], + ['kvestelacnormal_6800',['kVestelAcNormal',['../ir__Vestel_8h.html#afa4c0fafcc806cd22dfb45475631d754',1,'ir_Vestel.h']]], + ['kvestelacofftimeoffset_6801',['kVestelAcOffTimeOffset',['../ir__Vestel_8h.html#a64ce11367a28d6481801ac3ac641df4b',1,'ir_Vestel.h']]], + ['kvestelacofftimerflagoffset_6802',['kVestelAcOffTimerFlagOffset',['../ir__Vestel_8h.html#ab36bed197f2c2b65599667b4cdf8225b',1,'ir_Vestel.h']]], + ['kvestelaconespace_6803',['kVestelAcOneSpace',['../ir__Vestel_8h.html#a507a849ef5e031f40ecc0e5db6ac8dd6',1,'ir_Vestel.h']]], + ['kvestelacontimeoffset_6804',['kVestelAcOnTimeOffset',['../ir__Vestel_8h.html#a51e257abca02cb1c97de4a5418fb7e61',1,'ir_Vestel.h']]], + ['kvestelacontimerflagoffset_6805',['kVestelAcOnTimerFlagOffset',['../ir__Vestel_8h.html#a8aa66163683538129fbdaf21746a9144',1,'ir_Vestel.h']]], + ['kvestelacpoweroffset_6806',['kVestelAcPowerOffset',['../ir__Vestel_8h.html#ab1c5709fa37fc711929688bd72c300be',1,'ir_Vestel.h']]], + ['kvestelacpowersize_6807',['kVestelAcPowerSize',['../ir__Vestel_8h.html#a884236b7213902c5e7d79327effc8f97',1,'ir_Vestel.h']]], + ['kvestelacsleep_6808',['kVestelAcSleep',['../ir__Vestel_8h.html#abc4701f0a44ed48a139d192f86a7169b',1,'ir_Vestel.h']]], + ['kvestelacstatedefault_6809',['kVestelAcStateDefault',['../ir__Vestel_8h.html#a4207797ae1043280ec6364de5981a791',1,'ir_Vestel.h']]], + ['kvestelacswing_6810',['kVestelAcSwing',['../ir__Vestel_8h.html#aeb764aa28cb134348e64fde5cb4d40f0',1,'ir_Vestel.h']]], + ['kvestelacswingoffset_6811',['kVestelAcSwingOffset',['../ir__Vestel_8h.html#ad3249b7c42070013c7c81d3feb0b1a43',1,'ir_Vestel.h']]], + ['kvestelactempoffset_6812',['kVestelAcTempOffset',['../ir__Vestel_8h.html#a9cf24276d722ee54a17c8beaf2b415cd',1,'ir_Vestel.h']]], + ['kvestelactimerflagoffset_6813',['kVestelAcTimerFlagOffset',['../ir__Vestel_8h.html#a0e53cb471d133b13cfa8fd3204d70776',1,'ir_Vestel.h']]], + ['kvestelactimerhoursize_6814',['kVestelAcTimerHourSize',['../ir__Vestel_8h.html#ad52ad7c6b1efb7eee74a276dbca330e3',1,'ir_Vestel.h']]], + ['kvestelactimerminssize_6815',['kVestelAcTimerMinsSize',['../ir__Vestel_8h.html#a7696fac000df0fd5136b7cbd96393b9e',1,'ir_Vestel.h']]], + ['kvestelactimersize_6816',['kVestelAcTimerSize',['../ir__Vestel_8h.html#a43f134a4db94790c671380be29fb8e2c',1,'ir_Vestel.h']]], + ['kvestelactimestatedefault_6817',['kVestelAcTimeStateDefault',['../ir__Vestel_8h.html#aaf4d9b6a41269ede2101d45cc1549794',1,'ir_Vestel.h']]], + ['kvestelactolerance_6818',['kVestelAcTolerance',['../ir__Vestel_8h.html#a4abe236ac8a801aa03ab843c3e418711',1,'ir_Vestel.h']]], + ['kvestelacturbo_6819',['kVestelAcTurbo',['../ir__Vestel_8h.html#a85b8b744f201b1666f9608f693a61059',1,'ir_Vestel.h']]], + ['kvestelacturbosleepoffset_6820',['kVestelAcTurboSleepOffset',['../ir__Vestel_8h.html#a97c21dc060558aa4f543f2d05385f674',1,'ir_Vestel.h']]], + ['kvestelaczerospace_6821',['kVestelAcZeroSpace',['../ir__Vestel_8h.html#a2094b0ff279fb1696b51e57d657efd13',1,'ir_Vestel.h']]], + ['kwallstr_6822',['kWallStr',['../IRtext_8cpp.html#a860a71561b888c82318daad9f2c34592',1,'kWallStr(): IRtext.cpp'],['../IRtext_8h.html#add1af6d900b500ca7affff3c9ff02d29',1,'kWallStr(): IRtext.cpp']]], + ['kweeklytimerstr_6823',['kWeeklyTimerStr',['../IRtext_8cpp.html#aaf0b7bf26b4710a4c032cec9e55c545a',1,'kWeeklyTimerStr(): IRtext.cpp'],['../IRtext_8h.html#ab59fa6f63401196c0ff32aba6da9d9aa',1,'kWeeklyTimerStr(): IRtext.cpp']]], + ['kwhirlpoolacalttempoffset_6824',['kWhirlpoolAcAltTempOffset',['../ir__Whirlpool_8h.html#a5cdc8be18d6489572d7c16dbbcc0c838',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacalttemppos_6825',['kWhirlpoolAcAltTempPos',['../ir__Whirlpool_8h.html#a019206ce06ef164cc3abb586183d0789',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacauto_6826',['kWhirlpoolAcAuto',['../ir__Whirlpool_8h.html#a2f3cc5447f8042e9c2eae0c2e0dc1b80',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacautotemp_6827',['kWhirlpoolAcAutoTemp',['../ir__Whirlpool_8h.html#a314b66dc86a7f622d73d3973d9dca86d',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacbitmark_6828',['kWhirlpoolAcBitMark',['../ir__Whirlpool_8cpp.html#a5c076ca2e18927f8b0594cb74a7de1ff',1,'ir_Whirlpool.cpp']]], + ['kwhirlpoolacbits_6829',['kWhirlpoolAcBits',['../IRremoteESP8266_8h.html#a149bd4f3fb9c83e683095d393209ede3',1,'IRremoteESP8266.h']]], + ['kwhirlpoolacchecksumbyte1_6830',['kWhirlpoolAcChecksumByte1',['../ir__Whirlpool_8h.html#ab199c13354730c715debbeed63182cbd',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacchecksumbyte2_6831',['kWhirlpoolAcChecksumByte2',['../ir__Whirlpool_8h.html#a37d1a2fd814ccf83062325225bddb9be',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacclockpos_6832',['kWhirlpoolAcClockPos',['../ir__Whirlpool_8h.html#ad624453fc485adaaa156bfde374208a4',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommand6thsense_6833',['kWhirlpoolAcCommand6thSense',['../ir__Whirlpool_8h.html#a48b1309aab30dd871ce047881680efa2',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandfanspeed_6834',['kWhirlpoolAcCommandFanSpeed',['../ir__Whirlpool_8h.html#a4712f7dd6c5631f6aa692eeb99fa3963',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandifeel_6835',['kWhirlpoolAcCommandIFeel',['../ir__Whirlpool_8h.html#a5cb95c379d033d7f5b0c81755f1d376f',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandlight_6836',['kWhirlpoolAcCommandLight',['../ir__Whirlpool_8h.html#af6ae6f50d9dbfa610b7033181e4f7eb1',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandmode_6837',['kWhirlpoolAcCommandMode',['../ir__Whirlpool_8h.html#ab03770a941b7277a66fe65003497e183',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandofftimer_6838',['kWhirlpoolAcCommandOffTimer',['../ir__Whirlpool_8h.html#a072883e3780aa0970183ab330db26118',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandontimer_6839',['kWhirlpoolAcCommandOnTimer',['../ir__Whirlpool_8h.html#a54cbadf2ded73e66d6d12b6622249bdc',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandpos_6840',['kWhirlpoolAcCommandPos',['../ir__Whirlpool_8h.html#a1a3bc2210991ccfd418a5137dc7e0aa8',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandpower_6841',['kWhirlpoolAcCommandPower',['../ir__Whirlpool_8h.html#ac215c2827ebfe25a896d53e576b643d1',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandsleep_6842',['kWhirlpoolAcCommandSleep',['../ir__Whirlpool_8h.html#a695c9d69953ad2663512ede38e619b09',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandsuper_6843',['kWhirlpoolAcCommandSuper',['../ir__Whirlpool_8h.html#a4da2162e70a7257c5f4149e8556816d4',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandswing_6844',['kWhirlpoolAcCommandSwing',['../ir__Whirlpool_8h.html#a320e57c0727a74f049883c77233647a9',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccommandtemp_6845',['kWhirlpoolAcCommandTemp',['../ir__Whirlpool_8h.html#a6e567d58af9bc3fb246e3d47a09fb065',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaccool_6846',['kWhirlpoolAcCool',['../ir__Whirlpool_8h.html#a9574c0a604ffee1df43222344f649db8',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacdefaultrepeat_6847',['kWhirlpoolAcDefaultRepeat',['../IRremoteESP8266_8h.html#a3b41358898f69d96bdeece17ead13ee0',1,'IRremoteESP8266.h']]], + ['kwhirlpoolacdry_6848',['kWhirlpoolAcDry',['../ir__Whirlpool_8h.html#ab7433a4e3e8ad7ee665ab234df43e45f',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacfan_6849',['kWhirlpoolAcFan',['../ir__Whirlpool_8h.html#a91ecddbde81174268fdde3679565daeb',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacfanauto_6850',['kWhirlpoolAcFanAuto',['../ir__Whirlpool_8h.html#a133a436db244935a812beba78a1a9d05',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacfanhigh_6851',['kWhirlpoolAcFanHigh',['../ir__Whirlpool_8h.html#a93affe2700e13830ff09ee16801be56d',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacfanlow_6852',['kWhirlpoolAcFanLow',['../ir__Whirlpool_8h.html#abdbd00636661a234d9e30521144d76e1',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacfanmedium_6853',['kWhirlpoolAcFanMedium',['../ir__Whirlpool_8h.html#acf1ae9526d2fd3f49d484608730f607d',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacfanoffset_6854',['kWhirlpoolAcFanOffset',['../ir__Whirlpool_8h.html#a2cbca4b466aab8816efa70d1653bc895',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacfanpos_6855',['kWhirlpoolAcFanPos',['../ir__Whirlpool_8h.html#a02d5f4fe0837c9f9738cfb46f83c2ed9',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacfansize_6856',['kWhirlpoolAcFanSize',['../ir__Whirlpool_8h.html#ae26fab46c0f06c04f4d51b61e623873c',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacgap_6857',['kWhirlpoolAcGap',['../ir__Whirlpool_8cpp.html#a5946b0c81f68442645f795f4f6518972',1,'ir_Whirlpool.cpp']]], + ['kwhirlpoolachdrmark_6858',['kWhirlpoolAcHdrMark',['../ir__Whirlpool_8cpp.html#ad2f759eb7426cfe5fb3421f101c926bb',1,'ir_Whirlpool.cpp']]], + ['kwhirlpoolachdrspace_6859',['kWhirlpoolAcHdrSpace',['../ir__Whirlpool_8cpp.html#a7a83a305cc6ebb7be7163bd1c3fb679d',1,'ir_Whirlpool.cpp']]], + ['kwhirlpoolacheat_6860',['kWhirlpoolAcHeat',['../ir__Whirlpool_8h.html#a1e9290ec94cca537b5c44d2e4326b59c',1,'ir_Whirlpool.h']]], + ['kwhirlpoolachouroffset_6861',['kWhirlpoolAcHourOffset',['../ir__Whirlpool_8h.html#a8940e79b0e5b9f4bcf2a3e518cc59432',1,'ir_Whirlpool.h']]], + ['kwhirlpoolachoursize_6862',['kWhirlpoolAcHourSize',['../ir__Whirlpool_8h.html#ac50066e7e496cb7af6ecdb21cee7f2c9',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaclightoffset_6863',['kWhirlpoolAcLightOffset',['../ir__Whirlpool_8h.html#a5a5fbcfa7f383fb72f96c414adea8966',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacmaxtemp_6864',['kWhirlpoolAcMaxTemp',['../ir__Whirlpool_8h.html#a08171b333f214963e21a0c574783299f',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacmingap_6865',['kWhirlpoolAcMinGap',['../ir__Whirlpool_8cpp.html#aa6e5e114daf18d77914a08f831c37c7d',1,'ir_Whirlpool.cpp']]], + ['kwhirlpoolacmintemp_6866',['kWhirlpoolAcMinTemp',['../ir__Whirlpool_8h.html#aeffef97e3247609d5731b525692f1e7b',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacminuteoffset_6867',['kWhirlpoolAcMinuteOffset',['../ir__Whirlpool_8h.html#ae22595d5d1ffdc4c6b02080cd38d14d7',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacminutesize_6868',['kWhirlpoolAcMinuteSize',['../ir__Whirlpool_8h.html#a3a5cecc4480a1cb3da19f246902ab1d9',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacmodeoffset_6869',['kWhirlpoolAcModeOffset',['../ir__Whirlpool_8h.html#a662d0ab4b5f2b40bc2427e2b8d18351e',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacmodepos_6870',['kWhirlpoolAcModePos',['../ir__Whirlpool_8h.html#a6a7e8449c00a260c1ef740ebc4a08d50',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacofftimerpos_6871',['kWhirlpoolAcOffTimerPos',['../ir__Whirlpool_8h.html#a48a18046ded6bae11cd87d41d615d05f',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaconespace_6872',['kWhirlpoolAcOneSpace',['../ir__Whirlpool_8cpp.html#a7680ed11a0bc6b2f9340e3557681a470',1,'ir_Whirlpool.cpp']]], + ['kwhirlpoolacontimerpos_6873',['kWhirlpoolAcOnTimerPos',['../ir__Whirlpool_8h.html#ad10d9924f4d57547f7dc8ea085e1666f',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacpowertoggleoffset_6874',['kWhirlpoolAcPowerToggleOffset',['../ir__Whirlpool_8h.html#a1db76f65f3f10e73a0fdee65850934a2',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacpowertogglepos_6875',['kWhirlpoolAcPowerTogglePos',['../ir__Whirlpool_8h.html#a353f4f6101a152fdcfe7f13b8f8764d8',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacsections_6876',['kWhirlpoolAcSections',['../ir__Whirlpool_8cpp.html#a75ebed07d288ac32a0138035279b41c7',1,'ir_Whirlpool.cpp']]], + ['kwhirlpoolacsleepoffset_6877',['kWhirlpoolAcSleepOffset',['../ir__Whirlpool_8h.html#a83961870cfae146cbb519560ff609fc3',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacsleeppos_6878',['kWhirlpoolAcSleepPos',['../ir__Whirlpool_8h.html#a739f14122bce3a130d441bb0a47b4666',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacstatelength_6879',['kWhirlpoolAcStateLength',['../IRremoteESP8266_8h.html#a0fff60a43f776fb999d0f1f91d88154f',1,'IRremoteESP8266.h']]], + ['kwhirlpoolacsupermask_6880',['kWhirlpoolAcSuperMask',['../ir__Whirlpool_8h.html#a1946501e50abd9e1c0a3e07007a98c24',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacsuperpos_6881',['kWhirlpoolAcSuperPos',['../ir__Whirlpool_8h.html#a68e051a102449fc6712f709b166a99b9',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacswing1offset_6882',['kWhirlpoolAcSwing1Offset',['../ir__Whirlpool_8h.html#adeba9b215f8044e64df2bf805eecaa3b',1,'ir_Whirlpool.h']]], + ['kwhirlpoolacswing2offset_6883',['kWhirlpoolAcSwing2Offset',['../ir__Whirlpool_8h.html#a3290f0b70f3eafdd885d4a08c6d5d5a3',1,'ir_Whirlpool.h']]], + ['kwhirlpoolactemppos_6884',['kWhirlpoolAcTempPos',['../ir__Whirlpool_8h.html#a15a3ef7abed2fca2881d4f5ccc969522',1,'ir_Whirlpool.h']]], + ['kwhirlpoolactimerenableoffset_6885',['kWhirlpoolAcTimerEnableOffset',['../ir__Whirlpool_8h.html#ab4694ec5e153e41f6cf56920e2291970',1,'ir_Whirlpool.h']]], + ['kwhirlpoolaczerospace_6886',['kWhirlpoolAcZeroSpace',['../ir__Whirlpool_8cpp.html#af03c9ee4d432bbce7d2ee214dd5ca095',1,'ir_Whirlpool.cpp']]], + ['kwhynterbitmark_6887',['kWhynterBitMark',['../ir__Whynter_8cpp.html#a032043e058989b6402d8af99d2c20552',1,'ir_Whynter.cpp']]], + ['kwhynterbitmarkticks_6888',['kWhynterBitMarkTicks',['../ir__Whynter_8cpp.html#acfd8f04e0453ec1b9cd85837053a47e2',1,'ir_Whynter.cpp']]], + ['kwhynterbits_6889',['kWhynterBits',['../IRremoteESP8266_8h.html#a4553f6670e241a67104d45216a4ebd98',1,'IRremoteESP8266.h']]], + ['kwhynterhdrmark_6890',['kWhynterHdrMark',['../ir__Whynter_8cpp.html#a7d62b0e658fe6f697d41d6932e4e6662',1,'ir_Whynter.cpp']]], + ['kwhynterhdrmarkticks_6891',['kWhynterHdrMarkTicks',['../ir__Whynter_8cpp.html#a34da808cebff09fc038589c035f2d2fe',1,'ir_Whynter.cpp']]], + ['kwhynterhdrspace_6892',['kWhynterHdrSpace',['../ir__Whynter_8cpp.html#ad20c874e642238e299a44ead2ea592f1',1,'ir_Whynter.cpp']]], + ['kwhynterhdrspaceticks_6893',['kWhynterHdrSpaceTicks',['../ir__Whynter_8cpp.html#a8090f73380ea212e904402555156364d',1,'ir_Whynter.cpp']]], + ['kwhyntermincommandlength_6894',['kWhynterMinCommandLength',['../ir__Whynter_8cpp.html#a5e584a8d6aa8a146c9c8e74839b28e8f',1,'ir_Whynter.cpp']]], + ['kwhyntermincommandlengthticks_6895',['kWhynterMinCommandLengthTicks',['../ir__Whynter_8cpp.html#a65e8195824053403967573b7603059e7',1,'ir_Whynter.cpp']]], + ['kwhyntermingap_6896',['kWhynterMinGap',['../ir__Whynter_8cpp.html#ad09957f4c9c76d76ab55a74f440dad5f',1,'ir_Whynter.cpp']]], + ['kwhyntermingapticks_6897',['kWhynterMinGapTicks',['../ir__Whynter_8cpp.html#a89af5f0ab7af456f58052bf9256620a2',1,'ir_Whynter.cpp']]], + ['kwhynteronespace_6898',['kWhynterOneSpace',['../ir__Whynter_8cpp.html#a78993c22d94b107a37f61cddad728003',1,'ir_Whynter.cpp']]], + ['kwhynteronespaceticks_6899',['kWhynterOneSpaceTicks',['../ir__Whynter_8cpp.html#a95a5903a8f057df2b6587a331fec6f18',1,'ir_Whynter.cpp']]], + ['kwhyntertick_6900',['kWhynterTick',['../ir__Whynter_8cpp.html#a8f704cdf6cfd11455101919d7a772389',1,'ir_Whynter.cpp']]], + ['kwhynterzerospace_6901',['kWhynterZeroSpace',['../ir__Whynter_8cpp.html#a426deb9a35a1a6afdcbcfa58c6943490',1,'ir_Whynter.cpp']]], + ['kwhynterzerospaceticks_6902',['kWhynterZeroSpaceTicks',['../ir__Whynter_8cpp.html#ae38da416cd065b561287ebd2fe0257f0',1,'ir_Whynter.cpp']]], + ['kwidestr_6903',['kWideStr',['../IRtext_8cpp.html#a19875c78e68ba6fdd78df3526f82969c',1,'kWideStr(): IRtext.cpp'],['../IRtext_8h.html#a6fe3dbd6899e85e79e517f71cc74a87b',1,'kWideStr(): IRtext.cpp']]], + ['kwifistr_6904',['kWifiStr',['../IRtext_8cpp.html#a3f2dddbcbc03e31ed6f1081fce001ea4',1,'kWifiStr(): IRtext.cpp'],['../IRtext_8h.html#a8bc9343f209803dbab3e765e39b41b4d',1,'kWifiStr(): IRtext.cpp']]], + ['kxfanstr_6905',['kXFanStr',['../IRtext_8cpp.html#ada36ab4b7555d38a76c4477971736cb7',1,'kXFanStr(): IRtext.cpp'],['../IRtext_8h.html#a7ddc859861308f2f9077abcec2a4b571',1,'kXFanStr(): IRtext.cpp']]], + ['kyesstr_6906',['kYesStr',['../IRtext_8cpp.html#a96492aa94d18702db41a639ae2a45423',1,'kYesStr(): IRtext.cpp'],['../IRtext_8h.html#a95ca78b5cc3caa31c564a28480379fae',1,'kYesStr(): IRtext.cpp']]], + ['kzepealbits_6907',['kZepealBits',['../IRremoteESP8266_8h.html#af09c9402a1c4fa24f692994498641296',1,'IRremoteESP8266.h']]], + ['kzepealcommandoffon_6908',['kZepealCommandOffOn',['../ir__Zepeal_8cpp.html#a37af9800da3144c218d422e54066e837',1,'ir_Zepeal.cpp']]], + ['kzepealcommandofftimer_6909',['kZepealCommandOffTimer',['../ir__Zepeal_8cpp.html#a87b136a95af4437182530d6f7cbc69ee',1,'ir_Zepeal.cpp']]], + ['kzepealcommandontimer_6910',['kZepealCommandOnTimer',['../ir__Zepeal_8cpp.html#aed4491019bb6575c113404a095e8b116',1,'ir_Zepeal.cpp']]], + ['kzepealcommandrhythm_6911',['kZepealCommandRhythm',['../ir__Zepeal_8cpp.html#aa3960b3bdaa77c060543881bdf71e46c',1,'ir_Zepeal.cpp']]], + ['kzepealcommandspeed_6912',['kZepealCommandSpeed',['../ir__Zepeal_8cpp.html#a1189a81901daaf4b8b45e8f45caf0f49',1,'ir_Zepeal.cpp']]], + ['kzepealfootermark_6913',['kZepealFooterMark',['../ir__Zepeal_8cpp.html#a83167e93978d9cec8cf2dfac980582ba',1,'ir_Zepeal.cpp']]], + ['kzepealgap_6914',['kZepealGap',['../ir__Zepeal_8cpp.html#ab5bea0fe08e14fa3d1812bea018f44f0',1,'ir_Zepeal.cpp']]], + ['kzepealhdrmark_6915',['kZepealHdrMark',['../ir__Zepeal_8cpp.html#abee2a1537cfff9481d3060fba94a4b04',1,'ir_Zepeal.cpp']]], + ['kzepealhdrspace_6916',['kZepealHdrSpace',['../ir__Zepeal_8cpp.html#ad49be13d3dd108a18e4e641a40ff0408',1,'ir_Zepeal.cpp']]], + ['kzepealminrepeat_6917',['kZepealMinRepeat',['../IRremoteESP8266_8h.html#afb5c734e808d8f108f976f0556bf6e58',1,'IRremoteESP8266.h']]], + ['kzepealonemark_6918',['kZepealOneMark',['../ir__Zepeal_8cpp.html#a4d9919883561086dd3e3060e93983480',1,'ir_Zepeal.cpp']]], + ['kzepealonespace_6919',['kZepealOneSpace',['../ir__Zepeal_8cpp.html#a88702dbff33a9dddcfd4b255637460a0',1,'ir_Zepeal.cpp']]], + ['kzepealsignature_6920',['kZepealSignature',['../ir__Zepeal_8cpp.html#a7994e564096ac01b77d9ebe3a753167d',1,'ir_Zepeal.cpp']]], + ['kzepealtolerance_6921',['kZepealTolerance',['../ir__Zepeal_8cpp.html#ab35f666ef98b24b8b4bacdf462a9fbe6',1,'ir_Zepeal.cpp']]], + ['kzepealzeromark_6922',['kZepealZeroMark',['../ir__Zepeal_8cpp.html#a94eac58ef78ea4e39687f54e381c3a00',1,'ir_Zepeal.cpp']]], + ['kzepealzerospace_6923',['kZepealZeroSpace',['../ir__Zepeal_8cpp.html#a1af802b587e8f0a88ae87ab964fde690',1,'ir_Zepeal.cpp']]], + ['kzonefollowstr_6924',['kZoneFollowStr',['../IRtext_8cpp.html#a9a112fb47e39e35d096fe09266d37db1',1,'kZoneFollowStr(): IRtext.cpp'],['../IRtext_8h.html#a100dc6d7c4d53bffa00a24a582ace80f',1,'kZoneFollowStr(): IRtext.cpp']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_a.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_a.html new file mode 100644 index 000000000..1f6505537 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_a.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_a.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_a.js new file mode 100644 index 000000000..20f9d2d12 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_a.js @@ -0,0 +1,7 @@ +var searchData= +[ + ['ledflag_6925',['ledFlag',['../classIRCoolixAC.html#a03ba5e0a6cb47a7bb054155c2111a69c',1,'IRCoolixAC']]], + ['light_6926',['light',['../structstdAc_1_1state__t.html#a51c3a5c4703ea49b420d70aeb18b6b9b',1,'stdAc::state_t']]], + ['llword_6927',['llword',['../unionmagiquest.html#ad57fbc75ab289c3e93b94be0b2187d65',1,'magiquest']]], + ['lword_6928',['lword',['../unionmagiquest.html#ac87102145311831a232002b52fe2d02c',1,'magiquest']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_b.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_b.html new file mode 100644 index 000000000..c02d066f5 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_b.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_b.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_b.js new file mode 100644 index 000000000..161ca5933 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_b.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['magnitude_6929',['magnitude',['../unionmagiquest.html#a8f687419a00322a04aab223dec093d6e',1,'magiquest']]], + ['mode_6930',['mode',['../structstdAc_1_1state__t.html#ae5e4b17fac2ea36300f796670337d7a7',1,'stdAc::state_t']]], + ['mode_5fstate_6931',['mode_state',['../classIRToshibaAC.html#a5bb8b6cef598bb8273369b3fa7ade1b0',1,'IRToshibaAC']]], + ['model_6932',['model',['../structstdAc_1_1state__t.html#aa1a57a63b2ea80c1f9c4a1bcf16a4c62',1,'stdAc::state_t']]], + ['modulation_6933',['modulation',['../classIRsend.html#a11e26c03c87e2bed756eb7f318570bd8',1,'IRsend']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_c.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_c.html new file mode 100644 index 000000000..4b866c6ce --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_c.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_c.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_c.js new file mode 100644 index 000000000..051529e01 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_c.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['next_6934',['next',['../classIRac.html#ae85d7ac0c58028b2547518f88d3e98fe',1,'IRac']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_d.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_d.html new file mode 100644 index 000000000..84d878b81 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_d.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_d.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_d.js new file mode 100644 index 000000000..9f444e314 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_d.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['offtimeperiod_6935',['offTimePeriod',['../classIRsend.html#a9e45c9e4f54db86c1f3e506cd72fe4c1',1,'IRsend']]], + ['ontimeperiod_6936',['onTimePeriod',['../classIRsend.html#aaaa65f31dbea033f8130e847b0366d94',1,'IRsend']]], + ['outputoff_6937',['outputOff',['../classIRsend.html#a5e80df8b2ee534dbd6ddc30a852a2791',1,'IRsend']]], + ['outputon_6938',['outputOn',['../classIRsend.html#a4acfc45b339e724e2dbdff24762dfa7d',1,'IRsend']]], + ['overflow_6939',['overflow',['../structirparams__t.html#aa39b4f38e0ffcd470766373e03548e58',1,'irparams_t::overflow()'],['../classdecode__results.html#a821bc53c006bab3283c6b8592f0c43d3',1,'decode_results::overflow()']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_e.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_e.html new file mode 100644 index 000000000..b0d9b7b20 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_e.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_e.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_e.js new file mode 100644 index 000000000..d2027848f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_e.js @@ -0,0 +1,8 @@ +var searchData= +[ + ['padding_6940',['padding',['../unionmagiquest.html#a28ca4be56c78ef762f87171506dc6e93',1,'magiquest']]], + ['periodoffset_6941',['periodOffset',['../classIRsend.html#a1b5180cbf4f88f19fca3f677e1e91b96',1,'IRsend']]], + ['power_6942',['power',['../structstdAc_1_1state__t.html#ab85d37cc99bbbc4915331369c4ea622e',1,'stdAc::state_t']]], + ['powerflag_6943',['powerFlag',['../classIRCoolixAC.html#a5984ff64ff14df92291618a647da08f9',1,'IRCoolixAC']]], + ['protocol_6944',['protocol',['../structstdAc_1_1state__t.html#af59897778be0e571f77dd11337352c27',1,'stdAc::state_t']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_f.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_f.html new file mode 100644 index 000000000..a708dbf04 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_f.html @@ -0,0 +1,30 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_f.js b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_f.js new file mode 100644 index 000000000..7f57cab0a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/search/variables_f.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['quiet_6945',['quiet',['../structstdAc_1_1state__t.html#a251ad14e187a9905137e9e4e010c3e34',1,'stdAc::state_t']]] +]; diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/splitbar.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/splitbar.png new file mode 100644 index 000000000..fe895f2c5 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/splitbar.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structirparams__t-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structirparams__t-members.html new file mode 100644 index 000000000..0c526f445 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structirparams__t-members.html @@ -0,0 +1,87 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
    +
    + + + + + + +
    +
    IRremoteESP8266 +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + +
    +
    +
    +
    irparams_t Member List
    +
    +
    + +

    This is the complete list of members for irparams_t, including all inherited members.

    + + + + + + + + + +
    bufsizeirparams_t
    overflowirparams_t
    rawbufirparams_t
    rawlenirparams_t
    rcvstateirparams_t
    recvpinirparams_t
    timeoutirparams_t
    timerirparams_t
    + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structirparams__t.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structirparams__t.html new file mode 100644 index 000000000..74d3bcddf --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structirparams__t.html @@ -0,0 +1,222 @@ + + + + + + + +IRremoteESP8266: irparams_t Struct Reference + + + + + + + + + +
    +
    + + + + + + +
    +
    IRremoteESP8266 +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + +
    +
    + +
    +
    irparams_t Struct Reference
    +
    +
    + +

    Information for the interrupt handler. + More...

    + +

    #include <IRrecv.h>

    + + + + + + + + + + + + + + + + + + +

    +Public Attributes

    uint8_t recvpin
     
    uint8_t rcvstate
     
    uint16_t timer
     
    uint16_t bufsize
     
    uint16_t * rawbuf
     
    uint16_t rawlen
     
    uint8_t overflow
     
    uint8_t timeout
     
    +

    Detailed Description

    +

    Information for the interrupt handler.

    +

    Member Data Documentation

    + +

    ◆ bufsize

    + +
    +
    + + + + +
    uint16_t irparams_t::bufsize
    +
    + +
    +
    + +

    ◆ overflow

    + +
    +
    + + + + +
    uint8_t irparams_t::overflow
    +
    + +
    +
    + +

    ◆ rawbuf

    + +
    +
    + + + + +
    uint16_t* irparams_t::rawbuf
    +
    + +
    +
    + +

    ◆ rawlen

    + +
    +
    + + + + +
    uint16_t irparams_t::rawlen
    +
    + +
    +
    + +

    ◆ rcvstate

    + +
    +
    + + + + +
    uint8_t irparams_t::rcvstate
    +
    + +
    +
    + +

    ◆ recvpin

    + +
    +
    + + + + +
    uint8_t irparams_t::recvpin
    +
    + +
    +
    + +

    ◆ timeout

    + +
    +
    + + + + +
    uint8_t irparams_t::timeout
    +
    + +
    +
    + +

    ◆ timer

    + +
    +
    + + + + +
    uint16_t irparams_t::timer
    +
    + +
    +
    +
    The documentation for this struct was generated from the following file: +
    + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structmatch__result__t-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structmatch__result__t-members.html new file mode 100644 index 000000000..4a624fb26 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structmatch__result__t-members.html @@ -0,0 +1,82 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
    +
    + + + + + + +
    +
    IRremoteESP8266 +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + +
    +
    +
    +
    match_result_t Member List
    +
    +
    + +

    This is the complete list of members for match_result_t, including all inherited members.

    + + + + +
    datamatch_result_t
    successmatch_result_t
    usedmatch_result_t
    + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structmatch__result__t.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structmatch__result__t.html new file mode 100644 index 000000000..db08c0b2f --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structmatch__result__t.html @@ -0,0 +1,142 @@ + + + + + + + +IRremoteESP8266: match_result_t Struct Reference + + + + + + + + + +
    +
    + + + + + + +
    +
    IRremoteESP8266 +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + +
    +
    + +
    +
    match_result_t Struct Reference
    +
    +
    + +

    Results from a data match. + More...

    + +

    #include <IRrecv.h>

    + + + + + + + + +

    +Public Attributes

    bool success
     
    uint64_t data
     
    uint16_t used
     
    +

    Detailed Description

    +

    Results from a data match.

    +

    Member Data Documentation

    + +

    ◆ data

    + +
    +
    + + + + +
    uint64_t match_result_t::data
    +
    + +
    +
    + +

    ◆ success

    + +
    +
    + + + + +
    bool match_result_t::success
    +
    + +
    +
    + +

    ◆ used

    + +
    +
    + + + + +
    uint16_t match_result_t::used
    +
    + +
    +
    +
    The documentation for this struct was generated from the following file: +
    + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structstdAc_1_1state__t-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structstdAc_1_1state__t-members.html new file mode 100644 index 000000000..00b774f43 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structstdAc_1_1state__t-members.html @@ -0,0 +1,101 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
    +
    + + + + + + +
    +
    IRremoteESP8266 +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    stdAc::state_t Member List
    +
    + + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structstdAc_1_1state__t.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structstdAc_1_1state__t.html new file mode 100644 index 000000000..28ece11ce --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/structstdAc_1_1state__t.html @@ -0,0 +1,386 @@ + + + + + + + +IRremoteESP8266: stdAc::state_t Struct Reference + + + + + + + + + +
    +
    + + + + + + +
    +
    IRremoteESP8266 +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    + +
    +
    stdAc::state_t Struct Reference
    +
    +
    + +

    Structure to hold a common A/C state. + More...

    + +

    #include <IRsend.h>

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    +Public Attributes

    decode_type_t protocol
     
    int16_t model
     
    bool power
     
    stdAc::opmode_t mode
     
    float degrees
     
    bool celsius
     
    stdAc::fanspeed_t fanspeed
     
    stdAc::swingv_t swingv
     
    stdAc::swingh_t swingh
     
    bool quiet
     
    bool turbo
     
    bool econo
     
    bool light
     
    bool filter
     
    bool clean
     
    bool beep
     
    int16_t sleep
     
    int16_t clock
     
    +

    Detailed Description

    +

    Structure to hold a common A/C state.

    +

    Member Data Documentation

    + +

    ◆ beep

    + +
    +
    + + + + +
    bool stdAc::state_t::beep
    +
    + +
    +
    + +

    ◆ celsius

    + +
    +
    + + + + +
    bool stdAc::state_t::celsius
    +
    + +
    +
    + +

    ◆ clean

    + +
    +
    + + + + +
    bool stdAc::state_t::clean
    +
    + +
    +
    + +

    ◆ clock

    + +
    +
    + + + + +
    int16_t stdAc::state_t::clock
    +
    + +
    +
    + +

    ◆ degrees

    + +
    +
    + + + + +
    float stdAc::state_t::degrees
    +
    + +
    +
    + +

    ◆ econo

    + +
    +
    + + + + +
    bool stdAc::state_t::econo
    +
    + +
    +
    + +

    ◆ fanspeed

    + +
    +
    + + + + +
    stdAc::fanspeed_t stdAc::state_t::fanspeed
    +
    + +
    +
    + +

    ◆ filter

    + +
    +
    + + + + +
    bool stdAc::state_t::filter
    +
    + +
    +
    + +

    ◆ light

    + +
    +
    + + + + +
    bool stdAc::state_t::light
    +
    + +
    +
    + +

    ◆ mode

    + +
    +
    + + + + +
    stdAc::opmode_t stdAc::state_t::mode
    +
    + +
    +
    + +

    ◆ model

    + +
    +
    + + + + +
    int16_t stdAc::state_t::model
    +
    + +
    +
    + +

    ◆ power

    + +
    +
    + + + + +
    bool stdAc::state_t::power
    +
    + +
    +
    + +

    ◆ protocol

    + +
    +
    + + + + +
    decode_type_t stdAc::state_t::protocol
    +
    + +
    +
    + +

    ◆ quiet

    + +
    +
    + + + + +
    bool stdAc::state_t::quiet
    +
    + +
    +
    + +

    ◆ sleep

    + +
    +
    + + + + +
    int16_t stdAc::state_t::sleep
    +
    + +
    +
    + +

    ◆ swingh

    + +
    +
    + + + + +
    stdAc::swingh_t stdAc::state_t::swingh
    +
    + +
    +
    + +

    ◆ swingv

    + +
    +
    + + + + +
    stdAc::swingv_t stdAc::state_t::swingv
    +
    + +
    +
    + +

    ◆ turbo

    + +
    +
    + + + + +
    bool stdAc::state_t::turbo
    +
    + +
    +
    +
    The documentation for this struct was generated from the following file: +
    + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/sync_off.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/sync_off.png new file mode 100644 index 000000000..3b443fc62 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/sync_off.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/sync_on.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/sync_on.png new file mode 100644 index 000000000..e08320fb6 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/sync_on.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/tab_a.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/tab_a.png new file mode 100644 index 000000000..3b725c41c Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/tab_a.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/tab_b.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/tab_b.png new file mode 100644 index 000000000..e2b4a8638 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/tab_b.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/tab_h.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/tab_h.png new file mode 100644 index 000000000..fd5cb7054 Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/tab_h.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/tab_s.png b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/tab_s.png new file mode 100644 index 000000000..ab478c95b Binary files /dev/null and b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/tab_s.png differ diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/tabs.css b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/tabs.css new file mode 100644 index 000000000..7d45d36c1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/tabs.css @@ -0,0 +1 @@ +.sm{position:relative;z-index:9999}.sm,.sm ul,.sm li{display:block;list-style:none;margin:0;padding:0;line-height:normal;direction:ltr;text-align:left;-webkit-tap-highlight-color:rgba(0,0,0,0)}.sm-rtl,.sm-rtl ul,.sm-rtl li{direction:rtl;text-align:right}.sm>li>h1,.sm>li>h2,.sm>li>h3,.sm>li>h4,.sm>li>h5,.sm>li>h6{margin:0;padding:0}.sm ul{display:none}.sm li,.sm a{position:relative}.sm a{display:block}.sm a.disabled{cursor:not-allowed}.sm:after{content:"\00a0";display:block;height:0;font:0px/0 serif;clear:both;visibility:hidden;overflow:hidden}.sm,.sm *,.sm *:before,.sm *:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sm-dox{background-image:url("tab_b.png")}.sm-dox a,.sm-dox a:focus,.sm-dox a:hover,.sm-dox a:active{padding:0px 12px;padding-right:43px;font-family:"Lucida Grande","Geneva","Helvetica",Arial,sans-serif;font-size:13px;font-weight:bold;line-height:36px;text-decoration:none;text-shadow:0px 1px 1px rgba(255,255,255,0.9);color:#283A5D;outline:none}.sm-dox a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:#fff;text-shadow:0px 1px 1px #000}.sm-dox a.current{color:#D23600}.sm-dox a.disabled{color:#bbb}.sm-dox a span.sub-arrow{position:absolute;top:50%;margin-top:-14px;left:auto;right:3px;width:28px;height:28px;overflow:hidden;font:bold 12px/28px monospace !important;text-align:center;text-shadow:none;background:rgba(255,255,255,0.5);border-radius:5px}.sm-dox a.highlighted span.sub-arrow:before{display:block;content:'-'}.sm-dox>li:first-child>a,.sm-dox>li:first-child>:not(ul) a{border-radius:5px 5px 0 0}.sm-dox>li:last-child>a,.sm-dox>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul{border-radius:0 0 5px 5px}.sm-dox>li:last-child>a.highlighted,.sm-dox>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted{border-radius:0}.sm-dox ul{background:rgba(162,162,162,0.1)}.sm-dox ul a,.sm-dox ul a:focus,.sm-dox ul a:hover,.sm-dox ul a:active{font-size:12px;border-left:8px solid transparent;line-height:36px;text-shadow:none;background-color:white;background-image:none}.sm-dox ul a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:#fff;text-shadow:0px 1px 1px #000}.sm-dox ul ul a,.sm-dox ul ul a:hover,.sm-dox ul ul a:focus,.sm-dox ul ul a:active{border-left:16px solid transparent}.sm-dox ul ul ul a,.sm-dox ul ul ul a:hover,.sm-dox ul ul ul a:focus,.sm-dox ul ul ul a:active{border-left:24px solid transparent}.sm-dox ul ul ul ul a,.sm-dox ul ul ul ul a:hover,.sm-dox ul ul ul ul a:focus,.sm-dox ul ul ul ul a:active{border-left:32px solid transparent}.sm-dox ul ul ul ul ul a,.sm-dox ul ul ul ul ul a:hover,.sm-dox ul ul ul ul ul a:focus,.sm-dox ul ul ul ul ul a:active{border-left:40px solid transparent}@media (min-width: 768px){.sm-dox ul{position:absolute;width:12em}.sm-dox li{float:left}.sm-dox.sm-rtl li{float:right}.sm-dox ul li,.sm-dox.sm-rtl ul li,.sm-dox.sm-vertical li{float:none}.sm-dox a{white-space:nowrap}.sm-dox ul a,.sm-dox.sm-vertical a{white-space:normal}.sm-dox .sm-nowrap>li>a,.sm-dox .sm-nowrap>li>:not(ul) a{white-space:nowrap}.sm-dox{padding:0 10px;background-image:url("tab_b.png");line-height:36px}.sm-dox a span.sub-arrow{top:50%;margin-top:-2px;right:12px;width:0;height:0;border-width:4px;border-style:solid dashed dashed dashed;border-color:#283A5D transparent transparent transparent;background:transparent;border-radius:0}.sm-dox a,.sm-dox a:focus,.sm-dox a:active,.sm-dox a:hover,.sm-dox a.highlighted{padding:0px 12px;background-image:url("tab_s.png");background-repeat:no-repeat;background-position:right;border-radius:0 !important}.sm-dox a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:#fff;text-shadow:0px 1px 1px #000}.sm-dox a:hover span.sub-arrow{border-color:#fff transparent transparent transparent}.sm-dox a.has-submenu{padding-right:24px}.sm-dox li{border-top:0}.sm-dox>li>ul:before,.sm-dox>li>ul:after{content:'';position:absolute;top:-18px;left:30px;width:0;height:0;overflow:hidden;border-width:9px;border-style:dashed dashed solid dashed;border-color:transparent transparent #bbb transparent}.sm-dox>li>ul:after{top:-16px;left:31px;border-width:8px;border-color:transparent transparent #fff transparent}.sm-dox ul{border:1px solid #bbb;padding:5px 0;background:#fff;border-radius:5px !important;box-shadow:0 5px 9px rgba(0,0,0,0.2)}.sm-dox ul a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-color:transparent transparent transparent #555;border-style:dashed dashed dashed solid}.sm-dox ul a,.sm-dox ul a:hover,.sm-dox ul a:focus,.sm-dox ul a:active,.sm-dox ul a.highlighted{color:#555;background-image:none;border:0 !important;color:#555;background-image:none}.sm-dox ul a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:#fff;text-shadow:0px 1px 1px #000}.sm-dox ul a:hover span.sub-arrow{border-color:transparent transparent transparent #fff}.sm-dox span.scroll-up,.sm-dox span.scroll-down{position:absolute;display:none;visibility:hidden;overflow:hidden;background:#fff;height:36px}.sm-dox span.scroll-up:hover,.sm-dox span.scroll-down:hover{background:#eee}.sm-dox span.scroll-up:hover span.scroll-up-arrow,.sm-dox span.scroll-up:hover span.scroll-down-arrow{border-color:transparent transparent #D23600 transparent}.sm-dox span.scroll-down:hover span.scroll-down-arrow{border-color:#D23600 transparent transparent transparent}.sm-dox span.scroll-up-arrow,.sm-dox span.scroll-down-arrow{position:absolute;top:0;left:50%;margin-left:-6px;width:0;height:0;overflow:hidden;border-width:6px;border-style:dashed dashed solid dashed;border-color:transparent transparent #555 transparent}.sm-dox span.scroll-down-arrow{top:8px;border-style:solid dashed dashed dashed;border-color:#555 transparent transparent transparent}.sm-dox.sm-rtl a.has-submenu{padding-right:12px;padding-left:24px}.sm-dox.sm-rtl a span.sub-arrow{right:auto;left:12px}.sm-dox.sm-rtl.sm-vertical a.has-submenu{padding:10px 20px}.sm-dox.sm-rtl.sm-vertical a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-rtl>li>ul:before{left:auto;right:30px}.sm-dox.sm-rtl>li>ul:after{left:auto;right:31px}.sm-dox.sm-rtl ul a.has-submenu{padding:10px 20px !important}.sm-dox.sm-rtl ul a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-vertical{padding:10px 0;border-radius:5px}.sm-dox.sm-vertical a{padding:10px 20px}.sm-dox.sm-vertical a:hover,.sm-dox.sm-vertical a:focus,.sm-dox.sm-vertical a:active,.sm-dox.sm-vertical a.highlighted{background:#fff}.sm-dox.sm-vertical a.disabled{background-image:url("tab_b.png")}.sm-dox.sm-vertical a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-style:dashed dashed dashed solid;border-color:transparent transparent transparent #555}.sm-dox.sm-vertical>li>ul:before,.sm-dox.sm-vertical>li>ul:after{display:none}.sm-dox.sm-vertical ul a{padding:10px 20px}.sm-dox.sm-vertical ul a:hover,.sm-dox.sm-vertical ul a:focus,.sm-dox.sm-vertical ul a:active,.sm-dox.sm-vertical ul a.highlighted{background:#eee}.sm-dox.sm-vertical ul a.disabled{background:#fff}} diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/todo.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/todo.html new file mode 100644 index 000000000..8331a61db --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/todo.html @@ -0,0 +1,99 @@ + + + + + + + +IRremoteESP8266: Todo List + + + + + + + + + +
    +
    + + + + + + +
    +
    IRremoteESP8266 +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + +
    +
    +
    +
    Todo List
    +
    +
    +
    +
    Member IRrecv::decodeLasertag (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kLasertagBits, const bool strict=true)
    +
    Convert to using matchManchester() if we can.
    +
    Member IRrecv::decodeRC5 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kRC5XBits, const bool strict=true)
    +
    Serious testing of the RC-5X and strict aspects needs to be done.
    +
    Member IRrecv::decodeRC6 (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kRC6Mode0Bits, const bool strict=false)
    +
    Testing of the strict compliance aspects.
    +
    Member IRrecv::decodeSharp (decode_results *results, uint16_t offset=kStartOffset, const uint16_t nbits=kSharpBits, const bool strict=true, const bool expansion=true)
    +
    Need to ensure capture of the inverted message as it can be missed due to the interrupt timeout used to detect an end of message. Several compliance checks are disabled until that is resolved.
    +
    Member IRrecv::matchManchesterData (volatile const uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, const uint16_t nbits, const uint16_t half_period, const uint16_t starting_balance=0, const uint8_t tolerance=kUseDefTol, const int16_t excess=kMarkExcess, const bool MSBfirst=true, const bool GEThomas=true)
    +
    Clean up and optimise this. It is just "get it working code" atm.
    +
    Member IRSamsungAc::getSwing (void)
    +
    (Hollako) Explain why sometimes the LSB of remote_state[9] is a 1. e.g. 0xAE or 0XAF for swing move.
    +
    Member IRSamsungAc::setSwing (const bool on)
    +
    (Hollako) Explain why sometimes the LSB of remote_state[9] is a 1. e.g. 0xAE or 0XAF for swing move.
    +
    Member IRsend::sendLasertag (uint64_t data, uint16_t nbits=kLasertagBits, uint16_t repeat=kLasertagMinRepeat)
    +
    Convert this to use sendManchester() if we can.`
    +
    Member IRsend::sendRC5 (const uint64_t data, uint16_t nbits=kRC5XBits, const uint16_t repeat=kNoRepeat)
    +
    Testing of the RC-5X components.
    +
    Member IRsend::sendSAMSUNG (const uint64_t data, const uint16_t nbits=kSamsungBits, const uint16_t repeat=kNoRepeat)
    +
    Confirm that is actually how Samsung sends a repeat. The refdoc doesn't indicate it is true.
    +
    +
    +
    + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/unionmagiquest-members.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/unionmagiquest-members.html new file mode 100644 index 000000000..0976ba9fe --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/unionmagiquest-members.html @@ -0,0 +1,87 @@ + + + + + + + +IRremoteESP8266: Member List + + + + + + + + + +
    +
    + + + + + + +
    +
    IRremoteESP8266 +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + +
    +
    +
    +
    magiquest Member List
    +
    +
    + +

    This is the complete list of members for magiquest, including all inherited members.

    + + + + + + + + + +
    bytemagiquest
    cmdmagiquest
    llwordmagiquest
    lwordmagiquest
    magnitudemagiquest
    paddingmagiquest
    scrapmagiquest
    wand_idmagiquest
    + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/unionmagiquest.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/unionmagiquest.html new file mode 100644 index 000000000..fb5f336ff --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/unionmagiquest.html @@ -0,0 +1,223 @@ + + + + + + + +IRremoteESP8266: magiquest Union Reference + + + + + + + + + +
    +
    + + + + + + +
    +
    IRremoteESP8266 +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + +
    +
    + +
    +
    magiquest Union Reference
    +
    +
    + +

    MagiQuest packet is both Wand ID and magnitude of swish and flick. + More...

    + +

    #include <ir_Magiquest.h>

    + + + + + + + + + + + + + + + + + + + +

    +Public Attributes

    uint64_t llword
     
    uint8_t byte [8]
     
    uint32_t lword [2]
     
    struct {
       uint16_t   magnitude
     
       uint32_t   wand_id
     
       uint8_t   padding
     
       uint8_t   scrap
     
    cmd
     
    +

    Detailed Description

    +

    MagiQuest packet is both Wand ID and magnitude of swish and flick.

    +

    Member Data Documentation

    + +

    ◆ byte

    + +
    +
    + + + + +
    uint8_t magiquest::byte[8]
    +
    + +
    +
    + +

    ◆ cmd

    + +
    +
    + + + + +
    struct { ... } magiquest::cmd
    +
    + +
    +
    + +

    ◆ llword

    + +
    +
    + + + + +
    uint64_t magiquest::llword
    +
    + +
    +
    + +

    ◆ lword

    + +
    +
    + + + + +
    uint32_t magiquest::lword[2]
    +
    + +
    +
    + +

    ◆ magnitude

    + +
    +
    + + + + +
    uint16_t magiquest::magnitude
    +
    + +
    +
    + +

    ◆ padding

    + +
    +
    + + + + +
    uint8_t magiquest::padding
    +
    + +
    +
    + +

    ◆ scrap

    + +
    +
    + + + + +
    uint8_t magiquest::scrap
    +
    + +
    +
    + +

    ◆ wand_id

    + +
    +
    + + + + +
    uint32_t magiquest::wand_id
    +
    + +
    +
    +
    The documentation for this union was generated from the following file: +
    + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/zh-CN_8h.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/zh-CN_8h.html new file mode 100644 index 000000000..30e00c752 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/zh-CN_8h.html @@ -0,0 +1,82 @@ + + + + + + + +IRremoteESP8266: src/locale/zh-CN.h File Reference + + + + + + + + + +
    +
    + + + + + + +
    +
    IRremoteESP8266 +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    zh-CN.h File Reference
    +
    + + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/zh-CN_8h_source.html b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/zh-CN_8h_source.html new file mode 100644 index 000000000..a5b0277da --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen/html/zh-CN_8h_source.html @@ -0,0 +1,545 @@ + + + + + + + +IRremoteESP8266: src/locale/zh-CN.h Source File + + + + + + + + + +
    +
    + + + + + + +
    +
    IRremoteESP8266 +
    +
    +
    + + + + + + + + +
    +
    + + +
    + +
    + + +
    +
    +
    +
    zh-CN.h
    +
    +
    +Go to the documentation of this file.
    1 // Copyright 2020 - MiaoYi (@Caffreyfans)
    +
    2 // Locale/language file for China / Simplified.
    +
    3 // This file will override the default values located in `defaults.h`.
    +
    4 #ifndef LOCALE_ZH_CN_H_
    +
    5 #define LOCALE_ZH_CN_H_
    +
    6 
    +
    7 #ifndef D_STR_UNKNOWN
    +
    8 #define D_STR_UNKNOWN "未知"
    +
    9 #endif // D_STR_UNKNOWN
    +
    10 #ifndef D_STR_PROTOCOL
    +
    11 #define D_STR_PROTOCOL "协议"
    +
    12 #endif // D_STR_PROTOCOL
    +
    13 #ifndef D_STR_POWER
    +
    14 #define D_STR_POWER "电源"
    +
    15 #endif // D_STR_POWER
    +
    16 #ifndef D_STR_PREVIOUS
    +
    17 #define D_STR_PREVIOUS "以前"
    +
    18 #endif // D_STR_PREVIOUS
    +
    19 #ifndef D_STR_ON
    +
    20 #define D_STR_ON "开"
    +
    21 #endif // D_STR_ON
    +
    22 #ifndef D_STR_OFF
    +
    23 #define D_STR_OFF "关"
    +
    24 #endif // D_STR_OFF
    +
    25 #ifndef D_STR_MODE
    +
    26 #define D_STR_MODE "模式"
    +
    27 #endif // D_STR_MODE
    +
    28 #ifndef D_STR_TOGGLE
    +
    29 #define D_STR_TOGGLE "切换"
    +
    30 #endif // D_STR_TOGGLE
    +
    31 #ifndef D_STR_TURBO
    +
    32 #define D_STR_TURBO "强力"
    +
    33 #endif // D_STR_TURBO
    +
    34 #ifndef D_STR_SUPER
    +
    35 #define D_STR_SUPER "超级"
    +
    36 #endif // D_STR_SUPER
    +
    37 #ifndef D_STR_SLEEP
    +
    38 #define D_STR_SLEEP "睡眠"
    +
    39 #endif // D_STR_SLEEP
    +
    40 #ifndef D_STR_LIGHT
    +
    41 #define D_STR_LIGHT "灯光"
    +
    42 #endif // D_STR_LIGHT
    +
    43 #ifndef D_STR_POWERFUL
    +
    44 #define D_STR_POWERFUL "强劲模式"
    +
    45 #endif // D_STR_POWERFUL
    +
    46 #ifndef D_STR_QUIET
    +
    47 #define D_STR_QUIET "安静"
    +
    48 #endif // D_STR_QUIET
    +
    49 #ifndef D_STR_ECONO
    +
    50 #define D_STR_ECONO "经济"
    +
    51 #endif // D_STR_ECONO
    +
    52 #ifndef D_STR_SWING
    +
    53 #define D_STR_SWING "扫风"
    +
    54 #endif // D_STR_SWING
    +
    55 #ifndef D_STR_SWINGH
    +
    56 #define D_STR_SWINGH D_STR_SWING"(H)" // Set `D_STR_SWING` first!
    +
    57 #endif // D_STR_SWINGH
    +
    58 #ifndef D_STR_SWINGV
    +
    59 #define D_STR_SWINGV D_STR_SWING"(V)" // Set `D_STR_SWING` first!
    +
    60 #endif // D_STR_SWINGV
    +
    61 #ifndef D_STR_BEEP
    +
    62 #define D_STR_BEEP "蜂鸣"
    +
    63 #endif // D_STR_BEEP
    +
    64 #ifndef D_STR_MOULD
    +
    65 #define D_STR_MOULD "模子"
    +
    66 #endif // D_STR_MOULD
    +
    67 #ifndef D_STR_CLEAN
    +
    68 #define D_STR_CLEAN "清洁"
    +
    69 #endif // D_STR_CLEAN
    +
    70 #ifndef D_STR_PURIFY
    +
    71 #define D_STR_PURIFY "净化"
    +
    72 #endif // D_STR_PURIFY
    +
    73 #ifndef D_STR_TIMER
    +
    74 #define D_STR_TIMER "计时器"
    +
    75 #endif // D_STR_TIMER
    +
    76 #ifndef D_STR_ONTIMER
    +
    77 #define D_STR_ONTIMER D_STR_ON " " D_STR_TIMER // Set `D_STR_ON` first!
    +
    78 #endif // D_STR_ONTIMER
    +
    79 #ifndef D_STR_OFFTIMER
    +
    80 #define D_STR_OFFTIMER D_STR_OFF " " D_STR_TIMER // Set `D_STR_OFF` first!
    +
    81 #endif // D_STR_OFFTIMER
    +
    82 #ifndef D_STR_CLOCK
    +
    83 #define D_STR_CLOCK "时钟"
    +
    84 #endif // D_STR_CLOCK
    +
    85 #ifndef D_STR_COMMAND
    +
    86 #define D_STR_COMMAND "命令"
    +
    87 #endif // D_STR_COMMAND
    +
    88 #ifndef D_STR_XFAN
    +
    89 #define D_STR_XFAN "XFan"
    +
    90 #endif // D_STR_XFAN
    +
    91 #ifndef D_STR_HEALTH
    +
    92 #define D_STR_HEALTH "健康"
    +
    93 #endif // D_STR_HEALTH
    +
    94 #ifndef D_STR_MODEL
    +
    95 #define D_STR_MODEL "模式"
    +
    96 #endif // D_STR_MODEL
    +
    97 #ifndef D_STR_TEMP
    +
    98 #define D_STR_TEMP "温度"
    +
    99 #endif // D_STR_TEMP
    +
    100 #ifndef D_STR_IFEEL
    +
    101 #define D_STR_IFEEL "IFeel"
    +
    102 #endif // D_STR_IFEEL
    +
    103 #ifndef D_STR_HUMID
    +
    104 #define D_STR_HUMID "湿度"
    +
    105 #endif // D_STR_HUMID
    +
    106 #ifndef D_STR_SAVE
    +
    107 #define D_STR_SAVE "保存"
    +
    108 #endif // D_STR_SAVE
    +
    109 #ifndef D_STR_EYE
    +
    110 #define D_STR_EYE "眼"
    +
    111 #endif // D_STR_EYE
    +
    112 #ifndef D_STR_FOLLOW
    +
    113 #define D_STR_FOLLOW "跟随"
    +
    114 #endif // D_STR_FOLLOW
    +
    115 #ifndef D_STR_ION
    +
    116 #define D_STR_ION "Ion"
    +
    117 #endif // D_STR_ION
    +
    118 #ifndef D_STR_FRESH
    +
    119 #define D_STR_FRESH "刷新"
    +
    120 #endif // D_STR_FRESH
    +
    121 #ifndef D_STR_HOLD
    +
    122 #define D_STR_HOLD "保持"
    +
    123 #endif // D_STR_HOLD
    +
    124 #ifndef D_STR_8C_HEAT
    +
    125 #define D_STR_8C_HEAT "8C " D_STR_HEAT // Set `D_STR_HEAT` first!
    +
    126 #endif // D_STR_8C_HEAT
    +
    127 #ifndef D_STR_BUTTON
    +
    128 #define D_STR_BUTTON "按钮"
    +
    129 #endif // D_STR_BUTTON
    +
    130 #ifndef D_STR_NIGHT
    +
    131 #define D_STR_NIGHT "夜间"
    +
    132 #endif // D_STR_NIGHT
    +
    133 #ifndef D_STR_SILENT
    +
    134 #define D_STR_SILENT "安静"
    +
    135 #endif // D_STR_SILENT
    +
    136 #ifndef D_STR_FILTER
    +
    137 #define D_STR_FILTER "过滤"
    +
    138 #endif // D_STR_FILTER
    +
    139 #ifndef D_STR_3D
    +
    140 #define D_STR_3D "3D"
    +
    141 #endif // D_STR_3D
    +
    142 #ifndef D_STR_CELSIUS
    +
    143 #define D_STR_CELSIUS "摄氏度"
    +
    144 #endif // D_STR_CELSIUS
    +
    145 #ifndef D_STR_UP
    +
    146 #define D_STR_UP "上"
    +
    147 #endif // D_STR_UP
    +
    148 #ifndef D_STR_TEMPUP
    +
    149 #define D_STR_TEMPUP D_STR_TEMP " " D_STR_UP // Set `D_STR_TEMP` first!
    +
    150 #endif // D_STR_TEMPUP
    +
    151 #ifndef D_STR_DOWN
    +
    152 #define D_STR_DOWN "下"
    +
    153 #endif // D_STR_DOWN
    +
    154 #ifndef D_STR_TEMPDOWN
    +
    155 #define D_STR_TEMPDOWN D_STR_TEMP " " D_STR_DOWN // Set `D_STR_TEMP` first!
    +
    156 #endif // D_STR_TEMPDOWN
    +
    157 #ifndef D_STR_CHANGE
    +
    158 #define D_STR_CHANGE "改变"
    +
    159 #endif // D_STR_CHANGE
    +
    160 #ifndef D_STR_START
    +
    161 #define D_STR_START "开始"
    +
    162 #endif // D_STR_START
    +
    163 #ifndef D_STR_STOP
    +
    164 #define D_STR_STOP "结束"
    +
    165 #endif // D_STR_STOP
    +
    166 #ifndef D_STR_MOVE
    +
    167 #define D_STR_MOVE "移动"
    +
    168 #endif // D_STR_MOVE
    +
    169 #ifndef D_STR_SET
    +
    170 #define D_STR_SET "设置"
    +
    171 #endif // D_STR_SET
    +
    172 #ifndef D_STR_CANCEL
    +
    173 #define D_STR_CANCEL "取消"
    +
    174 #endif // D_STR_CANCEL
    +
    175 #ifndef D_STR_COMFORT
    +
    176 #define D_STR_COMFORT "舒适"
    +
    177 #endif // D_STR_COMFORT
    +
    178 #ifndef D_STR_SENSOR
    +
    179 #define D_STR_SENSOR "传感器"
    +
    180 #endif // D_STR_SENSOR
    +
    181 #ifndef D_STR_WEEKLY
    +
    182 #define D_STR_WEEKLY "每周"
    +
    183 #endif // D_STR_WEEKLY
    +
    184 #ifndef D_STR_WEEKLYTIMER
    +
    185 #define D_STR_WEEKLYTIMER D_STR_WEEKLY " " D_STR_TIMER // Needs `D_STR_WEEKLY`!
    +
    186 #endif // D_STR_WEEKLYTIMER
    +
    187 #ifndef D_STR_WIFI
    +
    188 #define D_STR_WIFI "WiFi"
    +
    189 #endif // D_STR_WIFI
    +
    190 #ifndef D_STR_LAST
    +
    191 #define D_STR_LAST "最近"
    +
    192 #endif // D_STR_LAST
    +
    193 #ifndef D_STR_FAST
    +
    194 #define D_STR_FAST "快"
    +
    195 #endif // D_STR_FAST
    +
    196 #ifndef D_STR_SLOW
    +
    197 #define D_STR_SLOW "慢"
    +
    198 #endif // D_STR_SLOW
    +
    199 #ifndef D_STR_AIRFLOW
    +
    200 #define D_STR_AIRFLOW "空气流动"
    +
    201 #endif // D_STR_AIRFLOW
    +
    202 #ifndef D_STR_STEP
    +
    203 #define D_STR_STEP "步"
    +
    204 #endif // D_STR_STEP
    +
    205 #ifndef D_STR_NA
    +
    206 #define D_STR_NA "不适用"
    +
    207 #endif // D_STR_NA
    +
    208 #ifndef D_STR_OUTSIDE
    +
    209 #define D_STR_OUTSIDE "室外"
    +
    210 #endif // D_STR_OUTSIDE
    +
    211 #ifndef D_STR_LOUD
    +
    212 #define D_STR_LOUD "大声"
    +
    213 #endif // D_STR_LOUD
    +
    214 #ifndef D_STR_UPPER
    +
    215 #define D_STR_UPPER "更高"
    +
    216 #endif // D_STR_UPPER
    +
    217 #ifndef D_STR_LOWER
    +
    218 #define D_STR_LOWER "更低"
    +
    219 #endif // D_STR_LOWER
    +
    220 #ifndef D_STR_BREEZE
    +
    221 #define D_STR_BREEZE "微风"
    +
    222 #endif // D_STR_BREEZE
    +
    223 #ifndef D_STR_CIRCULATE
    +
    224 #define D_STR_CIRCULATE "流通"
    +
    225 #endif // D_STR_CIRCULATE
    +
    226 #ifndef D_STR_CEILING
    +
    227 #define D_STR_CEILING "天花板"
    +
    228 #endif // D_STR_CEILING
    +
    229 #ifndef D_STR_WALL
    +
    230 #define D_STR_WALL "墙"
    +
    231 #endif // D_STR_WALL
    +
    232 #ifndef D_STR_ROOM
    +
    233 #define D_STR_ROOM "房间"
    +
    234 #endif // D_STR_ROOM
    +
    235 #ifndef D_STR_6THSENSE
    +
    236 #define D_STR_6THSENSE "第六感"
    +
    237 #endif // D_STR_6THSENSE
    +
    238 #ifndef D_STR_ZONEFOLLOW
    +
    239 #define D_STR_ZONEFOLLOW "区域跟随"
    +
    240 #endif // D_STR_ZONEFOLLOW
    +
    241 #ifndef D_STR_FIXED
    +
    242 #define D_STR_FIXED "固定"
    +
    243 #endif // D_STR_FIXED
    +
    244 
    +
    245 #ifndef D_STR_AUTO
    +
    246 #define D_STR_AUTO "自动"
    +
    247 #endif // D_STR_AUTO
    +
    248 #ifndef D_STR_AUTOMATIC
    +
    249 #define D_STR_AUTOMATIC "自动的"
    +
    250 #endif // D_STR_AUTOMATIC
    +
    251 #ifndef D_STR_MANUAL
    +
    252 #define D_STR_MANUAL "手动"
    +
    253 #endif // D_STR_MANUAL
    +
    254 #ifndef D_STR_COOL
    +
    255 #define D_STR_COOL "制冷"
    +
    256 #endif // D_STR_COOL
    +
    257 #ifndef D_STR_HEAT
    +
    258 #define D_STR_HEAT "加热"
    +
    259 #endif // D_STR_HEAT
    +
    260 #ifndef D_STR_FAN
    +
    261 #define D_STR_FAN "风扇"
    +
    262 #endif // D_STR_FAN
    +
    263 #ifndef D_STR_FANONLY
    +
    264 #define D_STR_FANONLY "仅风扇"
    +
    265 #endif // D_STR_FANONLY
    +
    266 #ifndef D_STR_DRY
    +
    267 #define D_STR_DRY "干燥"
    +
    268 #endif // D_STR_DRY
    +
    269 
    +
    270 #ifndef D_STR_MAX
    +
    271 #define D_STR_MAX "最大"
    +
    272 #endif // D_STR_MAX
    +
    273 #ifndef D_STR_MAXIMUM
    +
    274 #define D_STR_MAXIMUM "最小"
    +
    275 #endif // D_STR_MAXIMUM
    +
    276 #ifndef D_STR_MIN
    +
    277 #define D_STR_MIN "最低"
    +
    278 #endif // D_STR_MIN
    +
    279 #ifndef D_STR_MINIMUM
    +
    280 #define D_STR_MINIMUM "最低"
    +
    281 #endif // D_STR_MINIMUM
    +
    282 #ifndef D_STR_MED
    +
    283 #define D_STR_MED "中"
    +
    284 #endif // D_STR_MED
    +
    285 #ifndef D_STR_MEDIUM
    +
    286 #define D_STR_MEDIUM "中"
    +
    287 #endif // D_STR_MEDIUM
    +
    288 
    +
    289 #ifndef D_STR_HIGHEST
    +
    290 #define D_STR_HIGHEST "最高"
    +
    291 #endif // D_STR_HIGHEST
    +
    292 #ifndef D_STR_HIGH
    +
    293 #define D_STR_HIGH "高"
    +
    294 #endif // D_STR_HIGH
    +
    295 #ifndef D_STR_HI
    +
    296 #define D_STR_HI "嗨"
    +
    297 #endif // D_STR_HI
    +
    298 #ifndef D_STR_MID
    +
    299 #define D_STR_MID "中"
    +
    300 #endif // D_STR_MID
    +
    301 #ifndef D_STR_MIDDLE
    +
    302 #define D_STR_MIDDLE "居中"
    +
    303 #endif // D_STR_MIDDLE
    +
    304 #ifndef D_STR_LOW
    +
    305 #define D_STR_LOW "低"
    +
    306 #endif // D_STR_LOW
    +
    307 #ifndef D_STR_LO
    +
    308 #define D_STR_LO "低"
    +
    309 #endif // D_STR_LO
    +
    310 #ifndef D_STR_LOWEST
    +
    311 #define D_STR_LOWEST "最低"
    +
    312 #endif // D_STR_LOWEST
    +
    313 #ifndef D_STR_RIGHT
    +
    314 #define D_STR_RIGHT "右"
    +
    315 #endif // D_STR_RIGHT
    +
    316 #ifndef D_STR_MAXRIGHT
    +
    317 #define D_STR_MAXRIGHT D_STR_MAX " " D_STR_RIGHT // Set `D_STR_MAX` first!
    +
    318 #endif // D_STR_MAXRIGHT
    +
    319 #ifndef D_STR_RIGHTMAX_NOSPACE
    +
    320 #define D_STR_RIGHTMAX_NOSPACE D_STR_RIGHT D_STR_MAX // Set `D_STR_MAX` first!
    +
    321 #endif // D_STR_RIGHTMAX_NOSPACE
    +
    322 #ifndef D_STR_LEFT
    +
    323 #define D_STR_LEFT "左"
    +
    324 #endif // D_STR_LEFT
    +
    325 #ifndef D_STR_MAXLEFT
    +
    326 #define D_STR_MAXLEFT D_STR_MAX " " D_STR_LEFT // Set `D_STR_MAX` first!
    +
    327 #endif // D_STR_MAXLEFT
    +
    328 #ifndef D_STR_LEFTMAX_NOSPACE
    +
    329 #define D_STR_LEFTMAX_NOSPACE D_STR_LEFT D_STR_MAX // Set `D_STR_MAX` first!
    +
    330 #endif // D_STR_LEFTMAX_NOSPACE
    +
    331 #ifndef D_STR_WIDE
    +
    332 #define D_STR_WIDE "扫风"
    +
    333 #endif // D_STR_WIDE
    +
    334 #ifndef D_STR_CENTRE
    +
    335 #define D_STR_CENTRE "中间"
    +
    336 #endif // D_STR_CENTRE
    +
    337 #ifndef D_STR_TOP
    +
    338 #define D_STR_TOP "上部"
    +
    339 #endif // D_STR_TOP
    +
    340 #ifndef D_STR_BOTTOM
    +
    341 #define D_STR_BOTTOM "底部"
    +
    342 #endif // D_STR_BOTTOM
    +
    343 
    +
    344 // Compound words/phrases/descriptions from pre-defined words.
    +
    345 // Note: Obviously these need to be defined *after* their component words.
    +
    346 #ifndef D_STR_EYEAUTO
    +
    347 #define D_STR_EYEAUTO D_STR_EYE " " D_STR_AUTO
    +
    348 #endif // D_STR_EYEAUTO
    +
    349 #ifndef D_STR_LIGHTTOGGLE
    +
    350 #define D_STR_LIGHTTOGGLE D_STR_LIGHT " " D_STR_TOGGLE
    +
    351 #endif // D_STR_LIGHTTOGGLE
    +
    352 #ifndef D_STR_OUTSIDEQUIET
    +
    353 #define D_STR_OUTSIDEQUIET D_STR_OUTSIDE " " D_STR_QUIET
    +
    354 #endif // D_STR_OUTSIDEQUIET
    +
    355 #ifndef D_STR_POWERTOGGLE
    +
    356 #define D_STR_POWERTOGGLE D_STR_POWER " " D_STR_TOGGLE
    +
    357 #endif // D_STR_POWERTOGGLE
    +
    358 #ifndef D_STR_PREVIOUSPOWER
    +
    359 #define D_STR_PREVIOUSPOWER D_STR_PREVIOUS " " D_STR_POWER
    +
    360 #endif // D_STR_PREVIOUSPOWER
    +
    361 #ifndef D_STR_SENSORTEMP
    +
    362 #define D_STR_SENSORTEMP D_STR_SENSOR " " D_STR_TEMP
    +
    363 #endif // D_STR_SENSORTEMP
    +
    364 #ifndef D_STR_SLEEP_TIMER
    +
    365 #define D_STR_SLEEP_TIMER D_STR_SLEEP " " D_STR_TIMER
    +
    366 #endif // D_STR_SLEEP_TIMER
    +
    367 #ifndef D_STR_SWINGVMODE
    +
    368 #define D_STR_SWINGVMODE D_STR_SWINGV " " D_STR_MODE
    +
    369 #endif // D_STR_SWINGVMODE
    +
    370 #ifndef D_STR_SWINGVTOGGLE
    +
    371 #define D_STR_SWINGVTOGGLE D_STR_SWINGV " " D_STR_TOGGLE
    +
    372 #endif // D_STR_SWINGVTOGGLE
    +
    373 
    +
    374 // Separators
    +
    375 #ifndef D_CHR_TIME_SEP
    +
    376 #define D_CHR_TIME_SEP ':'
    +
    377 #endif // D_CHR_TIME_SEP
    +
    378 #ifndef D_STR_SPACELBRACE
    +
    379 #define D_STR_SPACELBRACE " ("
    +
    380 #endif // D_STR_SPACELBRACE
    +
    381 #ifndef D_STR_COMMASPACE
    +
    382 #define D_STR_COMMASPACE ", "
    +
    383 #endif // D_STR_COMMASPACE
    +
    384 #ifndef D_STR_COLONSPACE
    +
    385 #define D_STR_COLONSPACE ": "
    +
    386 #endif // D_STR_COLONSPACE
    +
    387 
    +
    388 #ifndef D_STR_DAY
    +
    389 #define D_STR_DAY "天"
    +
    390 #endif // D_STR_DAY
    +
    391 #ifndef D_STR_DAYS
    +
    392 #define D_STR_DAYS D_STR_DAY "s"
    +
    393 #endif // D_STR_DAYS
    +
    394 #ifndef D_STR_HOUR
    +
    395 #define D_STR_HOUR "时"
    +
    396 #endif // D_STR_HOUR
    +
    397 #ifndef D_STR_HOURS
    +
    398 #define D_STR_HOURS D_STR_HOUR "s"
    +
    399 #endif // D_STR_HOURS
    +
    400 #ifndef D_STR_MINUTE
    +
    401 #define D_STR_MINUTE "分"
    +
    402 #endif // D_STR_MINUTE
    +
    403 #ifndef D_STR_MINUTES
    +
    404 #define D_STR_MINUTES D_STR_MINUTE "s"
    +
    405 #endif // D_STR_MINUTES
    +
    406 #ifndef D_STR_SECOND
    +
    407 #define D_STR_SECOND "秒"
    +
    408 #endif // D_STR_SECOND
    +
    409 #ifndef D_STR_SECONDS
    +
    410 #define D_STR_SECONDS D_STR_SECOND "s"
    +
    411 #endif // D_STR_SECONDS
    +
    412 #ifndef D_STR_NOW
    +
    413 #define D_STR_NOW "现在"
    +
    414 #endif // D_STR_NOW
    +
    415 /* This is not three letter days. Disabled.
    +
    416 #ifndef D_STR_THREELETTERDAYS
    +
    417 #define D_STR_THREELETTERDAYS "周一至周末"
    +
    418 #endif // D_STR_THREELETTERDAYS
    +
    419 */
    +
    420 
    +
    421 #ifndef D_STR_YES
    +
    422 #define D_STR_YES "是"
    +
    423 #endif // D_STR_YES
    +
    424 #ifndef D_STR_NO
    +
    425 #define D_STR_NO "否"
    +
    426 #endif // D_STR_NO
    +
    427 #ifndef D_STR_TRUE
    +
    428 #define D_STR_TRUE "正确"
    +
    429 #endif // D_STR_TRUE
    +
    430 #ifndef D_STR_FALSE
    +
    431 #define D_STR_FALSE "错误"
    +
    432 #endif // D_STR_FALSE
    +
    433 
    +
    434 #ifndef D_STR_REPEAT
    +
    435 #define D_STR_REPEAT "重复"
    +
    436 #endif // D_STR_REPEAT
    +
    437 #ifndef D_STR_CODE
    +
    438 #define D_STR_CODE "代码"
    +
    439 #endif // D_STR_CODE
    +
    440 #ifndef D_STR_BITS
    +
    441 #define D_STR_BITS "位"
    +
    442 #endif // D_STR_BITS
    +
    443 
    +
    444 // IRrecvDumpV2+
    +
    445 #ifndef D_STR_TIMESTAMP
    +
    446 #define D_STR_TIMESTAMP "时间戳记"
    +
    447 #endif // D_STR_TIMESTAMP
    +
    448 #ifndef D_STR_LIBRARY
    +
    449 #define D_STR_LIBRARY "库文件"
    +
    450 #endif // D_STR_LIBRARY
    +
    451 #ifndef D_STR_MESGDESC
    +
    452 #define D_STR_MESGDESC "等等信息"
    +
    453 #endif // D_STR_MESGDESC
    +
    454 #ifndef D_STR_IRRECVDUMP_STARTUP
    +
    455 #define D_STR_IRRECVDUMP_STARTUP \
    +
    456  "IRrecvDump 运行当中,等待红外信息输入位于引脚 %d"
    +
    457 #endif // D_STR_IRRECVDUMP_STARTUP
    +
    458 #ifndef D_WARN_BUFFERFULL
    +
    459 #define D_WARN_BUFFERFULL \
    +
    460  "警告: 红外编码数组过大(>= %d). " \
    +
    461  "在解决此问题之前,不应信任此结果. " \
    +
    462  "编辑并增加 `kCaptureBufferSize` 变量."
    +
    463 #endif // D_WARN_BUFFERFULL
    +
    464 
    +
    465 #endif // LOCALE_ZH_CN_H_
    +
    + + + + diff --git a/lib/IRremoteESP8266-2.7.8/docs/doxygen_index.md b/lib/IRremoteESP8266-2.7.8/docs/doxygen_index.md new file mode 100644 index 000000000..95607645e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/docs/doxygen_index.md @@ -0,0 +1,60 @@ +# IRremoteESP8266 Library API Documentation {#mainpage} + +## Getting Started + +### The basics +For sending messages, look at the IRsend class. + +For receiving messages, look at the IRrecv & decode_results classes. + +### Air Conditioners +For _generic_ Air Conditioner control, look at the IRac class & the +stdAc::state_t structure. + +For _detailed_ Air Conditioner control, you need to determine what protocol the +library detects your remote/Air Conditioner to be, look into the appropriate +`src/ir_Protocol.[h|cpp]` files and use the appropriate class object. +e.g. if `IRrecvDumpV2` (or better) detects the protocol as `KELVINATOR`, +open the `src/ir_Kelvinator.*` files, and examine the IRKelvinatorAC class the +methods available to create/decode/send `KELVINATOR` messages with all the +abilities the library offers. You can also select it from the +[Classes](annotated.html) menu above. + +Various native constants & options for a given Protocol's class object can be +found in the associated header file for that protocol. + +## Examples +Most of the common uses of this library's APIs have demonstration code +available under the [examples](https://github.com/crankyoldgit/IRremoteESP8266/tree/master/examples) +directory. It ranges from trivial examples to complex real-world project code. + +## Tuning +The most commonly used & needed knobs for controlling aspects of this library +are available via run-time class methods or at class-object instantiation. +Again, you are referred to the IRsend & IRrecv classes. + +### Advanced +Certain addition constants and options are available as compile-time tweaks. +You should inspect [IRremoteESP8266.h](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/IRremoteESP8266.h), +[IRsend.h](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/IRsend.h), +& [IRrecv.h](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/IRrecv.h) +for General, Sending, & Receiving tweaks respectively. + +#### Protocol timings +Generally you should never need to adjust the timing parameters for a given +protocol or device. However, occasionally some individual devices just want to +be special. +If you are having problems decoding/receiving a message, look into the +`tolerance`, `kTolerance`, or IRrecv::setTolerance constants/methods etc first. +However, if your problems is sending, or adjusting the tolerance doesn't work +you may need to tweak per-protocol timing values. These are stored as +constants in the `ir_ProtocolName.cpp` file for the given protocol. This is +typically a step of last resort. + +#### Reducing code size & flash usage. +You can disable most protocols by either modifying the appropriate `#‍define`s +in [IRremoteESP8266.h](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/IRremoteESP8266.h) +or passing the appropriate compile-time flags, as documented in the same file. + +Avoid using the A/C classes, especially the IRac class as they will force the +compiler to include large amounts of code you may not need. diff --git a/lib/IRremoteESP8266-2.7.8/examples/BlynkIrRemote/BlynkIrRemote.ino b/lib/IRremoteESP8266-2.7.8/examples/BlynkIrRemote/BlynkIrRemote.ino new file mode 100644 index 000000000..6e659bd64 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/BlynkIrRemote/BlynkIrRemote.ino @@ -0,0 +1,196 @@ +/************************************************************* + Emulate a physical remote via an iOS and Android App. + Copyright Gaurav Barwalia 2020 + + Download latest Blynk library here: + https://github.com/blynkkk/blynk-library/releases/latest + + Blynk is a platform with iOS and Android apps to control + Arduino, Raspberry Pi and the likes over the Internet. + You can easily build graphic interfaces for all your + projects by simply dragging and dropping widgets. + + Downloads, docs, tutorials: http://www.blynk.cc + Sketch generator: http://examples.blynk.cc + Blynk community: http://community.blynk.cc + Follow us: http://www.fb.com/blynkapp + http://twitter.com/blynk_app + + Blynk library is licensed under MIT license + This example code is in public domain. + + ************************************************************* + This example runs directly on ESP8266 chip. + + Note: This requires ESP8266 support package: + https://github.com/esp8266/Arduino + + Please be sure to select the right ESP8266 module + in the Tools -> Board menu! + + Change WiFi ssid, pass, and Blynk auth token to run :) + Feel free to apply it to any other example. It's simple! + *************************************************************/ + + /* + // After decoding received below codes + + // Power button + +18:12:33.993 -> Protocol : NEC +18:12:33.993 -> Code : 0x1FE50AF (32 Bits) +18:12:33.993 -> uint16_t rawData[71] = {9040, 4452, 606, 532, 606, 534, 630, 508, 604, 534, 604, 534, 604, 534, 630, 506, 606, 1646, 632, 1620, 606, 1646, 632, 1620, 630, 1620, 632, 1620, 630, 1620, 606, 1646, 632, 506, 632, 506, 632, 1620, 632, 506, 632, 1620, 632, 506, 632, 508, 632, 506, 632, 506, 632, 1620, 632, 506, 632, 1624, 628, 506, 632, 1620, 632, 1618, 632, 1620, 632, 1620, 632, 39016, 9040, 2216, 630}; // NEC 1FE50AF +18:12:34.027 -> uint32_t address = 0x80; +18:12:34.027 -> uint32_t command = 0xA; +18:12:34.027 -> uint64_t data = 0x1FE50AF; + +//mute button + +18:13:27.215 -> Protocol : NEC +18:13:27.215 -> Code : 0x1FE30CF (32 Bits) +18:13:27.215 -> uint16_t rawData[71] = {9094, 4398, 660, 478, 658, 480, 658, 480, 658, 480, 658, 480, 658, 480, 660, 480, 658, 1594, 658, 1594, 658, 1594, 658, 1594, 658, 1592, 658, 1594, 658, 1592, 658, 1594, 660, 480, 658, 480, 658, 480, 658, 1592, 658, 1592, 658, 480, 658, 480, 660, 478, 660, 478, 658, 1594, 658, 1592, 658, 480, 658, 480, 658, 1594, 658, 1592, 658, 1594, 658, 1594, 658, 38986, 9094, 2162, 658}; // NEC 1FE30CF +18:13:27.285 -> uint32_t address = 0x80; +18:13:27.285 -> uint32_t command = 0xC; +18:13:27.285 -> uint64_t data = 0x1FE30CF; + +//Vol. low + +18:14:44.427 -> Protocol : NEC +18:14:44.427 -> Code : 0x1FEC03F (32 Bits) +18:14:44.427 -> uint16_t rawData[71] = {9120, 4374, 658, 478, 658, 480, 658, 480, 658, 480, 658, 482, 658, 478, 658, 480, 658, 1594, 658, 1594, 658, 1592, 660, 1594, 658, 1592, 658, 1594, 658, 1594, 658, 1592, 660, 480, 658, 1594, 658, 1594, 658, 480, 658, 480, 660, 480, 658, 480, 658, 480, 658, 480, 658, 480, 658, 480, 658, 1594, 660, 1592, 658, 1594, 658, 1594, 658, 1592, 658, 1594, 658, 39002, 9094, 2162, 658}; // NEC 1FEC03F +18:14:44.497 -> uint32_t address = 0x80; +18:14:44.497 -> uint32_t command = 0x3; +18:14:44.497 -> uint64_t data = 0x1FEC03F; + +//VOl. High + +18:15:11.677 -> Protocol : NEC +18:15:11.677 -> Code : 0x1FE40BF (32 Bits) +18:15:11.677 -> uint16_t rawData[67] = {9068, 4426, 630, 506, 632, 508, 630, 508, 630, 508, 630, 508, 630, 508, 630, 508, 630, 1622, 630, 1622, 630, 1622, 630, 1622, 656, 1594, 630, 1622, 632, 1620, 630, 1622, 630, 508, 630, 508, 630, 1622, 630, 508, 630, 508, 630, 508, 630, 508, 630, 508, 630, 508, 630, 1622, 656, 482, 630, 1622, 630, 1622, 630, 1622, 630, 1622, 630, 1622, 632, 1620, 630}; // NEC 1FE40BF +18:15:11.747 -> uint32_t address = 0x80; +18:15:11.747 -> uint32_t command = 0x2; +18:15:11.747 -> uint64_t data = 0x1FE40BF; + +//Play/Pause + +18:15:38.529 -> Protocol : NEC +18:15:38.529 -> Code : 0x1FE32CD (32 Bits) +18:15:38.529 -> uint16_t rawData[71] = {9092, 4400, 632, 504, 658, 480, 658, 480, 632, 506, 658, 480, 658, 480, 658, 482, 632, 1620, 658, 1594, 658, 1594, 632, 1618, 658, 1594, 658, 1594, 632, 1620, 632, 1618, 634, 506, 658, 480, 658, 480, 632, 1620, 658, 1598, 656, 478, 658, 478, 658, 1594, 658, 482, 632, 1618, 632, 1618, 634, 506, 632, 506, 658, 1594, 632, 1620, 658, 480, 632, 1620, 658, 38998, 9094, 2162, 660}; // NEC 1FE32CD +18:15:38.564 -> uint32_t address = 0x80; +18:15:38.564 -> uint32_t command = 0x4C; +18:15:38.564 -> uint64_t data = 0x1FE32CD; + +//Song Back + +18:16:07.527 -> Protocol : NEC +18:16:07.527 -> Code : 0x1FEA05F (32 Bits) +18:16:07.562 -> uint16_t rawData[71] = {9590, 3902, 684, 452, 686, 456, 652, 480, 660, 480, 684, 456, 656, 480, 658, 480, 684, 1568, 658, 1594, 658, 1594, 686, 1566, 658, 1594, 684, 1568, 658, 1594, 658, 1594, 686, 454, 684, 1568, 686, 454, 658, 1594, 684, 454, 686, 454, 658, 480, 660, 480, 684, 454, 658, 482, 658, 1594, 682, 456, 658, 1596, 658, 1594, 686, 1568, 660, 1592, 684, 1568, 686, 38982, 9098, 2162, 684}; // NEC 1FEA05F +18:16:07.597 -> uint32_t address = 0x80; +18:16:07.597 -> uint32_t command = 0x5; +18:16:07.597 -> uint64_t data = 0x1FEA05F; + +//Song Forward + +18:17:20.541 -> Protocol : NEC +18:17:20.541 -> Code : 0x1FEE01F (32 Bits) +18:17:20.575 -> uint16_t rawData[71] = {9068, 4424, 632, 506, 630, 506, 632, 508, 606, 532, 632, 506, 630, 508, 630, 508, 632, 1620, 632, 1620, 632, 1620, 604, 1646, 606, 1646, 630, 1622, 604, 1646, 632, 1620, 606, 534, 630, 1622, 604, 1646, 630, 1622, 604, 534, 630, 508, 604, 534, 606, 534, 630, 508, 630, 508, 606, 534, 606, 532, 630, 1622, 604, 1646, 632, 1620, 604, 1648, 604, 1646, 604, 39040, 9040, 2216, 604}; // NEC 1FEE01F +18:17:20.610 -> uint32_t address = 0x80; +18:17:20.610 -> uint32_t command = 0x7; +18:17:20.610 -> uint64_t data = 0x1FEE01F; + + */ + +// check complete video tutorial here for program explanation https://www.youtube.com/watch?v=LqmkDKu54XY&t=17s + +/* Comment this out to disable prints and save space */ +#define BLYNK_PRINT Serial + +#if defined(ESP8266) +#include +#include +#else +#include +#endif // ESP8266 +#if defined(ESP32) +#include +#endif // ESP32 + +// IR library +#include +#include + +const uint16_t kIrLed = 4; // ESP8266 GPIO pin to use. Recommended: 4 (D2). +IRsend irsend(kIrLed); // Set the GPIO to be used to sending the message. + +// You should get Auth Token in the Blynk App. +// Go to the Project Settings (nut icon). +char auth[] = "YourAuthToken"; + +// Your WiFi credentials. +// Set password to "" for open networks. +char ssid[] = "YourNetworkName"; +char pass[] = "YourPassword"; + + BLYNK_WRITE(V51) { // Power button + if (param.asInt() == 0) { + // Serial.println("NEC"); + irsend.sendNEC(0x1FE50AF); + } + } + + BLYNK_WRITE(V52) { // Mute button + if (param.asInt() == 0) { + // Serial.println("NEC"); + irsend.sendNEC(0x1FE30CF); + } + } + + BLYNK_WRITE(V53) { // Song Forward + if (param.asInt() == 0) { + // Serial.println("NEC"); + irsend.sendNEC(0x1FEE01F); + } + } + + BLYNK_WRITE(V54) { // Song Backward + if (param.asInt() == 0) { + // Serial.println("NEC"); + irsend.sendNEC(0x1FEA05F); + delay(10); // double tap back button to back one song + irsend.sendNEC(0x1FEA05F); + } + } + + BLYNK_WRITE(V55) { // Volume -- + if (param.asInt() == 0) { + // Serial.println("NEC"); + irsend.sendNEC(0x1FEC03F); + } + } + + BLYNK_WRITE(V56) { // Volume ++ + if (param.asInt() == 0) { + // Serial.println("NEC"); + irsend.sendNEC(0x1FE40BF); + } + } + + BLYNK_WRITE(V57) { // Play/Pause + if (param.asInt() == 0) { + // Serial.println("NEC"); + irsend.sendNEC(0x1FE32CD); + } + } + +void setup() { +#if defined(BLYNK_PRINT) + // Debug console + Serial.begin(115200); +#endif // BLYNK_PRINT + + Blynk.begin(auth, ssid, pass); +} + +void loop() { + Blynk.run(); +} diff --git a/lib/IRremoteESP8266-2.7.8/examples/BlynkIrRemote/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/BlynkIrRemote/platformio.ini new file mode 100644 index 000000000..c89beccfa --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/BlynkIrRemote/platformio.ini @@ -0,0 +1,35 @@ +[platformio] +src_dir = . + +[env] +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +framework = arduino +platform = espressif8266 +monitor_speed = 115200 +build_flags = ; -D_IR_LOCALE_=en-AU + +[common] +lib_deps_builtin = +lib_deps_external = + Blynk + +[common_esp8266] +lib_deps_external = + ${common.lib_deps_builtin} + ${common.lib_deps_external} + +[common_esp32] +lib_deps_external = + ${common.lib_deps_builtin} + ${common.lib_deps_external} + +[env:nodemcuv2] +board = nodemcuv2 +lib_deps = ${common_esp8266.lib_deps_external} + +[env:esp32dev] +platform = espressif32 +board = esp32dev +lib_deps = ${common_esp32.lib_deps_external} diff --git a/lib/IRremoteESP8266-2.7.5/examples/CommonAcControl/CommonAcControl.ino b/lib/IRremoteESP8266-2.7.8/examples/CommonAcControl/CommonAcControl.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.5/examples/CommonAcControl/CommonAcControl.ino rename to lib/IRremoteESP8266-2.7.8/examples/CommonAcControl/CommonAcControl.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/CommonAcControl/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/CommonAcControl/platformio.ini new file mode 100644 index 000000000..b71195045 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/CommonAcControl/platformio.ini @@ -0,0 +1,26 @@ +[platformio] +src_dir = . + +[env] +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +framework = arduino +monitor_speed = 115200 +build_flags = ; -D_IR_LOCALE_=en-AU + +[env:nodemcuv2] +platform = espressif8266 +board = nodemcuv2 + +[env:esp32dev] +platform = espressif32 +board = esp32dev + +; Build the program forcing the compiler to treat all warnings as errors. +[env:shakedown_all_protocols] +platform = espressif8266 +board = nodemcuv2 +build_flags = + ${env.build_flags} + -Werror diff --git a/lib/IRremoteESP8266-2.7.5/examples/ControlSamsungAC/ControlSamsungAC.ino b/lib/IRremoteESP8266-2.7.8/examples/ControlSamsungAC/ControlSamsungAC.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.5/examples/ControlSamsungAC/ControlSamsungAC.ino rename to lib/IRremoteESP8266-2.7.8/examples/ControlSamsungAC/ControlSamsungAC.ino diff --git a/lib/IRremoteESP8266-2.7.5/examples/CommonAcControl/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/ControlSamsungAC/platformio.ini similarity index 92% rename from lib/IRremoteESP8266-2.7.5/examples/CommonAcControl/platformio.ini rename to lib/IRremoteESP8266-2.7.8/examples/ControlSamsungAC/platformio.ini index e6f6320da..6bda1bb71 100644 --- a/lib/IRremoteESP8266-2.7.5/examples/CommonAcControl/platformio.ini +++ b/lib/IRremoteESP8266-2.7.8/examples/ControlSamsungAC/platformio.ini @@ -6,6 +6,7 @@ lib_extra_dirs = ../../ lib_ldf_mode = deep+ lib_ignore = examples framework = arduino +monitor_speed = 115200 build_flags = ; -D_IR_LOCALE_=en-AU [env:nodemcuv2] diff --git a/lib/IRremoteESP8266-2.7.5/examples/DumbIRRepeater/DumbIRRepeater.ino b/lib/IRremoteESP8266-2.7.8/examples/DumbIRRepeater/DumbIRRepeater.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.5/examples/DumbIRRepeater/DumbIRRepeater.ino rename to lib/IRremoteESP8266-2.7.8/examples/DumbIRRepeater/DumbIRRepeater.ino diff --git a/lib/IRremoteESP8266-2.7.5/examples/ControlSamsungAC/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/DumbIRRepeater/platformio.ini similarity index 92% rename from lib/IRremoteESP8266-2.7.5/examples/ControlSamsungAC/platformio.ini rename to lib/IRremoteESP8266-2.7.8/examples/DumbIRRepeater/platformio.ini index e6f6320da..6bda1bb71 100644 --- a/lib/IRremoteESP8266-2.7.5/examples/ControlSamsungAC/platformio.ini +++ b/lib/IRremoteESP8266-2.7.8/examples/DumbIRRepeater/platformio.ini @@ -6,6 +6,7 @@ lib_extra_dirs = ../../ lib_ldf_mode = deep+ lib_ignore = examples framework = arduino +monitor_speed = 115200 build_flags = ; -D_IR_LOCALE_=en-AU [env:nodemcuv2] diff --git a/lib/IRremoteESP8266-2.7.5/examples/IRGCSendDemo/IRGCSendDemo.ino b/lib/IRremoteESP8266-2.7.8/examples/IRGCSendDemo/IRGCSendDemo.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.5/examples/IRGCSendDemo/IRGCSendDemo.ino rename to lib/IRremoteESP8266-2.7.8/examples/IRGCSendDemo/IRGCSendDemo.ino diff --git a/lib/IRremoteESP8266-2.7.5/examples/DumbIRRepeater/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/IRGCSendDemo/platformio.ini similarity index 92% rename from lib/IRremoteESP8266-2.7.5/examples/DumbIRRepeater/platformio.ini rename to lib/IRremoteESP8266-2.7.8/examples/IRGCSendDemo/platformio.ini index e6f6320da..6bda1bb71 100644 --- a/lib/IRremoteESP8266-2.7.5/examples/DumbIRRepeater/platformio.ini +++ b/lib/IRremoteESP8266-2.7.8/examples/IRGCSendDemo/platformio.ini @@ -6,6 +6,7 @@ lib_extra_dirs = ../../ lib_ldf_mode = deep+ lib_ignore = examples framework = arduino +monitor_speed = 115200 build_flags = ; -D_IR_LOCALE_=en-AU [env:nodemcuv2] diff --git a/lib/IRremoteESP8266-2.7.5/examples/IRGCTCPServer/IRGCTCPServer.ino b/lib/IRremoteESP8266-2.7.8/examples/IRGCTCPServer/IRGCTCPServer.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.5/examples/IRGCTCPServer/IRGCTCPServer.ino rename to lib/IRremoteESP8266-2.7.8/examples/IRGCTCPServer/IRGCTCPServer.ino diff --git a/lib/IRremoteESP8266-2.7.5/examples/IRGCSendDemo/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/IRGCTCPServer/platformio.ini similarity index 92% rename from lib/IRremoteESP8266-2.7.5/examples/IRGCSendDemo/platformio.ini rename to lib/IRremoteESP8266-2.7.8/examples/IRGCTCPServer/platformio.ini index e6f6320da..6bda1bb71 100644 --- a/lib/IRremoteESP8266-2.7.5/examples/IRGCSendDemo/platformio.ini +++ b/lib/IRremoteESP8266-2.7.8/examples/IRGCTCPServer/platformio.ini @@ -6,6 +6,7 @@ lib_extra_dirs = ../../ lib_ldf_mode = deep+ lib_ignore = examples framework = arduino +monitor_speed = 115200 build_flags = ; -D_IR_LOCALE_=en-AU [env:nodemcuv2] diff --git a/lib/IRremoteESP8266-2.7.5/examples/IRMQTTServer/IRMQTTServer.h b/lib/IRremoteESP8266-2.7.8/examples/IRMQTTServer/IRMQTTServer.h similarity index 96% rename from lib/IRremoteESP8266-2.7.5/examples/IRMQTTServer/IRMQTTServer.h rename to lib/IRremoteESP8266-2.7.8/examples/IRMQTTServer/IRMQTTServer.h index b6fe281da..b283e330f 100644 --- a/lib/IRremoteESP8266-2.7.5/examples/IRMQTTServer/IRMQTTServer.h +++ b/lib/IRremoteESP8266-2.7.8/examples/IRMQTTServer/IRMQTTServer.h @@ -102,11 +102,23 @@ const uint32_t kMqttReconnectTime = 5000; // Delay(ms) between reconnect tries. #define MQTT_CLIMATE_STAT "stat" // Sub-topic for the climate stat topics. // Enable sending/receiving climate via JSON. `true` cost ~5k of program space. #define MQTT_CLIMATE_JSON false + // Use Home Assistant-style operation modes. -// i.e. Change the climate mode to "off" when turning the power "off". +// TL;DR: Power and Mode are linked together. One changes the other. +// i.e. +// - When power is set to "off", the mode is set to "off". +// - When the mode changes from "off" to something else, power is set to "on". // See: https://www.home-assistant.io/components/climate.mqtt/#modes -// Change to false, if your home automation system doesn't like this. +// *** WARNING *** +// This setting will cause IRMQTTServer to forget what the previous operation +// mode was. e.g. a power "on" -> "off" -> "on" will cause it to use the +// default mode for your A/C, not the previous mode. +// Typically this is "Auto" or "Cool" mode. +// Change to false, if your home automation system doesn't like this, or if +// you want IRMQTTServer to be the authoritative source for controling your +// A/C. #define MQTT_CLIMATE_HA_MODE true + // Do we send an IR message when we reboot and recover the existing A/C state? // If set to `false` you may miss requested state changes while the ESP was // down. If set to `true`, it will resend the previous desired state sent to the @@ -239,7 +251,7 @@ const uint16_t kJsonAcStateMaxSize = 1024; // Bytes // ----------------- End of User Configuration Section ------------------------- // Constants -#define _MY_VERSION_ "v1.4.7" +#define _MY_VERSION_ "v1.5.0" const uint8_t kRebootTime = 15; // Seconds const uint8_t kQuickDisplayTime = 2; // Seconds diff --git a/lib/IRremoteESP8266-2.7.5/examples/IRMQTTServer/IRMQTTServer.ino b/lib/IRremoteESP8266-2.7.8/examples/IRMQTTServer/IRMQTTServer.ino similarity index 94% rename from lib/IRremoteESP8266-2.7.5/examples/IRMQTTServer/IRMQTTServer.ino rename to lib/IRremoteESP8266-2.7.8/examples/IRMQTTServer/IRMQTTServer.ino index af98e3166..6bf504b0e 100644 --- a/lib/IRremoteESP8266-2.7.5/examples/IRMQTTServer/IRMQTTServer.ino +++ b/lib/IRremoteESP8266-2.7.8/examples/IRMQTTServer/IRMQTTServer.ino @@ -358,12 +358,17 @@ #include #include #if MQTT_ENABLE +#include // -------------------------------------------------------------------- // * * * IMPORTANT * * * // You must change to have the following value. // #define MQTT_MAX_PACKET_SIZE 768 // -------------------------------------------------------------------- -#include +// Check that the user has set MQTT_MAX_PACKET_SIZE to an appropriate size. +#if MQTT_MAX_PACKET_SIZE < 768 +#error "MQTT_MAX_PACKET_SIZE in is too small. "\ + "Increase the value per comments." +#endif // MQTT_MAX_PACKET_SIZE < 768 #endif // MQTT_ENABLE #include // NOLINT(build/include) #include @@ -622,7 +627,7 @@ bool loadConfigFile(void) { String timeElapsed(uint32_t const msec) { String result = msToString(msec); - if (result.equalsIgnoreCase("Now")) + if (result.equalsIgnoreCase(D_STR_NOW)) return result; else return result + F(" ago"); @@ -642,7 +647,7 @@ String timeSince(uint32_t const start) { String gpioToString(const int16_t gpio) { if (gpio == kGpioUnused) - return F("Unused"); + return F(D_STR_UNUSED); else return String(gpio); } @@ -715,13 +720,13 @@ void handleRoot(void) { html += F( "

    Send a simple IR message

    " "

    " - "Type: "); + D_STR_PROTOCOL ": "); html += htmlSelectAcStateProtocol(KEY_TYPE, decode_type_t::NEC, true); html += F( - " Code: 0x" - " Bit size: " - " " + D_STR_BITS ": " + "" - " Repeats: " - " " + " " D_STR_REPEAT ": " + " " "
    " "

    " "

    Send a complex (Air Conditioner) IR message

    " "

    " - "Type: "); + D_STR_PROTOCOL ": "); html += htmlSelectAcStateProtocol(KEY_TYPE, decode_type_t::KELVINATOR, false); html += F( - " State code: 0x" - "" - " " + " " "
    " "

    " "

    Send an IRremote Raw IR message

    " "

    " - "" - "String: (freq,array data) " + "String: (freq,array data) GlobalCache" " IR message

    " "" - "" - "String: 1:1,1," + "String: 1:1,1,Pronto code IR message

    " "" - "" - "String (comma separated): " + "String (comma separated): " - " Repeats: " + " " D_STR_REPEAT ": " " " "

    " "
    "); @@ -825,7 +830,7 @@ String addJsReloadUrl(const String url, const uint16_t timeout_s, if (notify && timeout_s) { html += F(" document.write(\"You will be redirected to the main page in "); html += String(timeout_s); - html += F(" seconds.\");\n"); + html += F(" " D_STR_SECONDS ".\");\n"); } html += F(" setTimeout('Redirect()', "); html += String(timeout_s * 1000); // Convert to mSecs @@ -848,35 +853,44 @@ void handleExamples(void) { html += htmlMenu(); html += F( "

    Hardcoded examples

    " - "

    " - "Sherwood Amp On (GlobalCache)

    " - "

    " - "Sherwood Amp Off (Raw)

    " - "

    " + "

    Sherwood Amp " D_STR_ON " (GlobalCache)

    " + "

    Sherwood Amp " D_STR_OFF " (Raw)

    " + "

    " "Sherwood Amp Input TAPE (Pronto)

    " - "

    TV on (Samsung)

    " - "

    Power Off (Sony 12bit)

    " - "

    " - "Panasonic A/C LKE model, On, Auto mode, Min fan, 23C" + "

    TV " D_STR_ON + " (Samsung)

    " + "

    " D_STR_POWER + " " D_STR_OFF " (Sony 12 " D_STR_BITS ")

    " + "

    " + "Panasonic A/C " D_STR_MODEL " LKE, " D_STR_ON ", " D_STR_AUTO " " + D_STR_MODE ", " D_STR_MIN " " D_STR_FAN ", 23C" " (via HTTP aircon interface)

    " - "

    " - "Change just the temp to 27C (via HTTP aircon interface)

    " - "

    " - "Turn OFF the current A/C (via HTTP aircon interface)

    " + "

    " + "Change just the " D_STR_TEMP " to 27C " + "(via HTTP aircon interface)

    " + "

    " + "Turn " D_STR_OFF " the current A/C (" + "via HTTP aircon interface)

    " "

    "); html += htmlEnd(); server.send(200, "text/html", html); @@ -996,7 +1010,9 @@ String htmlSelectSwingh(const String name, const stdAc::swingh_t def) { String htmlHeader(const String title, const String h1_text) { String html = F(""); html += title; - html += F("

    "); + html += F("" + "

    "); if (h1_text.length()) html += h1_text; else @@ -1042,20 +1058,20 @@ void handleAirCon(void) { "" + "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" - "" " -const char HTTP_SNS_TEMP[] PROGMEM = "{s}%s " D_TEMPERATURE "{m}%s°%c{e}"; -const char HTTP_SNS_HUM[] PROGMEM = "{s}%s " D_HUMIDITY "{m}%s%%{e}"; -const char HTTP_SNS_DEW[] PROGMEM = "{s}%s " D_DEWPOINT "{m}%s°%c{e}"; -const char HTTP_SNS_PRESSURE[] PROGMEM = "{s}%s " D_PRESSURE "{m}%s %s{e}"; -const char HTTP_SNS_SEAPRESSURE[] PROGMEM = "{s}%s " D_PRESSUREATSEALEVEL "{m}%s %s{e}"; -const char HTTP_SNS_ANALOG[] PROGMEM = "{s}%s " D_ANALOG_INPUT "%d{m}%d{e}"; -const char HTTP_SNS_ILLUMINANCE[] PROGMEM = "{s}%s " D_ILLUMINANCE "{m}%d " D_UNIT_LUX "{e}"; -const char HTTP_SNS_CO2[] PROGMEM = "{s}%s " D_CO2 "{m}%d " D_UNIT_PARTS_PER_MILLION "{e}"; -const char HTTP_SNS_CO2EAVG[] PROGMEM = "{s}%s " D_ECO2 "{m}%d " D_UNIT_PARTS_PER_MILLION "{e}"; -const char HTTP_SNS_GALLONS[] PROGMEM = "{s}%s " D_TOTAL_USAGE "{m}%s " D_UNIT_GALLONS " {e}"; -const char HTTP_SNS_GPM[] PROGMEM = "{s}%s " D_FLOW_RATE "{m}%s " D_UNIT_GALLONS_PER_MIN" {e}"; -const char HTTP_SNS_MOISTURE[] PROGMEM = "{s}%s " D_MOISTURE "{m}%d %%{e}"; -const char HTTP_SNS_RANGE[] PROGMEM = "{s}%s " D_RANGE "{m}%d{e}"; +const char HTTP_SNS_TEMP[] PROGMEM = "{s}%s " D_TEMPERATURE "{m}%s " D_UNIT_DEGREE "%c{e}"; +const char HTTP_SNS_HUM[] PROGMEM = "{s}%s " D_HUMIDITY "{m}%s " D_UNIT_PERCENT "{e}"; +const char HTTP_SNS_DEW[] PROGMEM = "{s}%s " D_DEWPOINT "{m}%s " D_UNIT_DEGREE "%c{e}"; +const char HTTP_SNS_PRESSURE[] PROGMEM = "{s}%s " D_PRESSURE "{m}%s " "%s{e}"; +const char HTTP_SNS_SEAPRESSURE[] PROGMEM = "{s}%s " D_PRESSUREATSEALEVEL "{m}%s " "%s{e}"; +const char HTTP_SNS_ANALOG[] PROGMEM = "{s}%s " D_ANALOG_INPUT "%d{m}%d" "{e}"; +const char HTTP_SNS_ILLUMINANCE[] PROGMEM = "{s}%s " D_ILLUMINANCE "{m}%d " D_UNIT_LUX "{e}"; +const char HTTP_SNS_CO2[] PROGMEM = "{s}%s " D_CO2 "{m}%d " D_UNIT_PARTS_PER_MILLION "{e}"; +const char HTTP_SNS_CO2EAVG[] PROGMEM = "{s}%s " D_ECO2 "{m}%d " D_UNIT_PARTS_PER_MILLION "{e}"; +const char HTTP_SNS_GALLONS[] PROGMEM = "{s}%s " D_TOTAL_USAGE "{m}%s " D_UNIT_GALLONS "{e}"; +const char HTTP_SNS_GPM[] PROGMEM = "{s}%s " D_FLOW_RATE "{m}%s " D_UNIT_GALLONS_PER_MIN "{e}"; +const char HTTP_SNS_MOISTURE[] PROGMEM = "{s}%s " D_MOISTURE "{m}%d " D_UNIT_PERCENT "{e}"; +const char HTTP_SNS_RANGE[] PROGMEM = "{s}%s " D_RANGE "{m}%d" "{e}"; +const char HTTP_SNS_VOLTAGE[] PROGMEM = "{s}" D_VOLTAGE "{m}%s " D_UNIT_VOLT "{e}"; +const char HTTP_SNS_CURRENT[] PROGMEM = "{s}" D_CURRENT "{m}%s " D_UNIT_AMPERE "{e}"; +const char HTTP_SNS_POWER[] PROGMEM = "{s}" D_POWERUSAGE "{m}%s " D_UNIT_WATT "{e}"; +const char HTTP_SNS_ENERGY_TOTAL[] PROGMEM = "{s}" D_ENERGY_TOTAL "{m}%s " D_UNIT_KILOWATTHOUR "{e}"; -const char HTTP_SNS_VOLTAGE[] PROGMEM = "{s}" D_VOLTAGE "{m}%s " D_UNIT_VOLT "{e}"; -const char HTTP_SNS_CURRENT[] PROGMEM = "{s}" D_CURRENT "{m}%s " D_UNIT_AMPERE "{e}"; -const char HTTP_SNS_POWER[] PROGMEM = "{s}" D_POWERUSAGE "{m}%s " D_UNIT_WATT "{e}"; -const char HTTP_SNS_ENERGY_TOTAL[] PROGMEM = "{s}" D_ENERGY_TOTAL "{m}%s " D_UNIT_KILOWATTHOUR "{e}"; - -const char S_MAIN_MENU[] PROGMEM = D_MAIN_MENU; -const char S_CONFIGURATION[] PROGMEM = D_CONFIGURATION; -const char S_CONFIGURE_TEMPLATE[] PROGMEM = D_CONFIGURE_TEMPLATE; -const char S_CONFIGURE_MODULE[] PROGMEM = D_CONFIGURE_MODULE; -const char S_CONFIGURE_WIFI[] PROGMEM = D_CONFIGURE_WIFI; -const char S_NO_NETWORKS_FOUND[] PROGMEM = D_NO_NETWORKS_FOUND; -const char S_CONFIGURE_LOGGING[] PROGMEM = D_CONFIGURE_LOGGING; -const char S_CONFIGURE_OTHER[] PROGMEM = D_CONFIGURE_OTHER; -const char S_SAVE_CONFIGURATION[] PROGMEM = D_SAVE_CONFIGURATION; -const char S_RESET_CONFIGURATION[] PROGMEM = D_RESET_CONFIGURATION; -const char S_RESTORE_CONFIGURATION[] PROGMEM = D_RESTORE_CONFIGURATION; -const char S_FIRMWARE_UPGRADE[] PROGMEM = D_FIRMWARE_UPGRADE; -const char S_CONSOLE[] PROGMEM = D_CONSOLE; -const char S_INFORMATION[] PROGMEM = D_INFORMATION; -const char S_RESTART[] PROGMEM = D_RESTART; +const char S_MAIN_MENU[] PROGMEM = D_MAIN_MENU; +const char S_CONFIGURATION[] PROGMEM = D_CONFIGURATION; +const char S_CONFIGURE_TEMPLATE[] PROGMEM = D_CONFIGURE_TEMPLATE; +const char S_CONFIGURE_MODULE[] PROGMEM = D_CONFIGURE_MODULE; +const char S_CONFIGURE_WIFI[] PROGMEM = D_CONFIGURE_WIFI; +const char S_NO_NETWORKS_FOUND[] PROGMEM = D_NO_NETWORKS_FOUND; +const char S_CONFIGURE_LOGGING[] PROGMEM = D_CONFIGURE_LOGGING; +const char S_CONFIGURE_OTHER[] PROGMEM = D_CONFIGURE_OTHER; +const char S_SAVE_CONFIGURATION[] PROGMEM = D_SAVE_CONFIGURATION; +const char S_RESET_CONFIGURATION[] PROGMEM = D_RESET_CONFIGURATION; +const char S_RESTORE_CONFIGURATION[] PROGMEM = D_RESTORE_CONFIGURATION; +const char S_FIRMWARE_UPGRADE[] PROGMEM = D_FIRMWARE_UPGRADE; +const char S_CONSOLE[] PROGMEM = D_CONSOLE; +const char S_INFORMATION[] PROGMEM = D_INFORMATION; +const char S_RESTART[] PROGMEM = D_RESTART; #endif // USE_WEBSERVER const uint32_t MARKER_START = 0x5AA55AA5; diff --git a/tasmota/language/bg-BG.h b/tasmota/language/bg_BG.h similarity index 86% rename from tasmota/language/bg-BG.h rename to tasmota/language/bg_BG.h index d4cb21b90..8f2c626c4 100644 --- a/tasmota/language/bg-BG.h +++ b/tasmota/language/bg_BG.h @@ -28,7 +28,7 @@ * Use online command StateText to translate ON, OFF, HOLD and TOGGLE. * Use online command Prefix to translate cmnd, stat and tele. * - * Updated until v7.1.2.4 + * Updated until v8.2.0.6 \*********************************************************************/ //#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English) @@ -56,6 +56,7 @@ #define D_AP "Точка за достъп" // Access Point #define D_AS "като" #define D_AUTO "АВТОМАТИЧНО" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "Мигане вкл." #define D_BLINKOFF "Мигане изкл." #define D_BOOT_COUNT "Брой на стартиранията" @@ -98,6 +99,8 @@ #define D_FILE "Файл" #define D_FLOW_RATE "Дебит" #define D_FREE_MEMORY "Свободна памет" +#define D_PSR_MAX_MEMORY "PS-RAM Memory" +#define D_PSR_FREE_MEMORY "PS-RAM free Memory" #define D_FREQUENCY "Честота" #define D_GAS "Газ" #define D_GATEWAY "Шлюз" @@ -114,8 +117,9 @@ #define D_IP_ADDRESS "IP адрес" #define D_LIGHT "Светлина" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "Модул" -#define D_MOISTURE "Moisture" +#define D_MOISTURE "Влага" #define D_MQTT "MQTT" #define D_MULTI_PRESS "неколкократно натискане" #define D_NOISE "Шум" @@ -138,7 +142,7 @@ #define D_PROGRAM_SIZE "Размер на програмата" #define D_PROJECT "Проект" #define D_RAIN "Дъжд" -#define D_RANGE "Range" +#define D_RANGE "Обхват" #define D_RECEIVED "Получено" #define D_RESTART "Рестарт" #define D_RESTARTING "Рестартиране" @@ -300,6 +304,7 @@ #define D_OTHER_PARAMETERS "Други параметри" #define D_TEMPLATE "Модел" #define D_ACTIVATE "Активирай" +#define D_DEVICE_NAME "Device Name" #define D_WEB_ADMIN_PASSWORD "Парола на уеб администратора" #define D_MQTT_ENABLE "Активиране на MQTT" #define D_FRIENDLY_NAME "Приятелско име" @@ -357,7 +362,7 @@ #define D_UPLOAD_ERR_11 "Грешка при изтриване на RF чипа" #define D_UPLOAD_ERR_12 "Грешка при записване в RF чипа" #define D_UPLOAD_ERR_13 "Грешка при декодиране на RF фърмуера" -#define D_UPLOAD_ERR_14 "Not compatible" +#define D_UPLOAD_ERR_14 "Несъвместим" #define D_UPLOAD_ERROR_CODE "Код на грешка при зареждането" #define D_ENTER_COMMAND "Въвеждане на команда" @@ -442,6 +447,8 @@ #define D_KNX_ENHANCEMENT "Подобрена комуникация" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Използвана енергия днес" @@ -482,6 +489,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #define D_PARTICALS_BEYOND "Частици" +// xsns_27_apds9960.ino +#define D_GESTURE "Жест" +#define D_COLOR_RED "Червен" +#define D_COLOR_GREEN "Зелен" +#define D_COLOR_BLUE "Син" +#define D_CCT "CCT" +#define D_PROXIMITY "Близост" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Ускорение - ос X" #define D_AY_AXIS "Ускорение - ос Y" @@ -506,7 +521,7 @@ //xsns_35_tx20.ino #define D_TX20_WIND_DIRECTION "Посока на вятъра" #define D_TX20_WIND_SPEED "Скорост на вятъра" -#define D_TX20_WIND_SPEED_MIN "Мини. скорост на вятъра" +#define D_TX20_WIND_SPEED_MIN "Мин. скорост на вятъра" #define D_TX20_WIND_SPEED_MAX "Макс. скорост на вятъра" #define D_TX20_NORTH "С" #define D_TX20_EAST "И" @@ -514,24 +529,24 @@ #define D_TX20_WEST "З" // xsns_53_sml.ino -#define D_TPWRIN "Energy Total-In" -#define D_TPWROUT "Energy Total-Out" -#define D_TPWRCURR "Active Power-In/Out" -#define D_TPWRCURR1 "Active Power-In p1" -#define D_TPWRCURR2 "Active Power-In p2" -#define D_TPWRCURR3 "Active Power-In p3" -#define D_Strom_L1 "Current L1" -#define D_Strom_L2 "Current L2" -#define D_Strom_L3 "Current L3" -#define D_Spannung_L1 "Voltage L1" -#define D_Spannung_L2 "Voltage L2" -#define D_Spannung_L3 "Voltage L3" -#define D_METERNR "Meter_number" -#define D_METERSID "Service ID" -#define D_GasIN "Counter" -#define D_H2oIN "Counter" -#define D_StL1L2L3 "Current L1+L2+L3" -#define D_SpL1L2L3 "Voltage L1+L2+L3/3" +#define D_TPWRIN "Общо енергия - IN" +#define D_TPWROUT "Общо енергия - OUT" +#define D_TPWRCURR "Активна мощност - In/Out" +#define D_TPWRCURR1 "Активна мощност - In p1" +#define D_TPWRCURR2 "Активна мощност - In p2" +#define D_TPWRCURR3 "Активна мощност - In p3" +#define D_Strom_L1 "Ток L1" +#define D_Strom_L2 "Ток L2" +#define D_Strom_L3 "Ток L3" +#define D_Spannung_L1 "Напрежение L1" +#define D_Spannung_L2 "Напрежение L2" +#define D_Spannung_L3 "Напрежение L3" +#define D_METERNR "Номер_електромер" +#define D_METERSID "ID на услугата" +#define D_GasIN "Брояч" +#define D_H2oIN "Брояч" +#define D_StL1L2L3 "Ток L1+L2+L3" +#define D_SpL1L2L3 "Напрежение L1+L2+L3/3" // tasmota_template.h - keep them as short as possible to be able to fit them in GUI drop down box #define D_SENSOR_NONE "Няма" @@ -567,7 +582,8 @@ #define D_SENSOR_SPI_MOSI "SPI MOSI" #define D_SENSOR_SPI_CLK "SPI CLK" #define D_SENSOR_BACKLIGHT "Подсветка" -#define D_SENSOR_PMS5003 "PMS5003" +#define D_SENSOR_PMS5003_TX "PMS5003 Tx" +#define D_SENSOR_PMS5003_RX "PMS5003 Rx" #define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" #define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" #define D_SENSOR_HPMA_RX "HPMA Rx" @@ -627,8 +643,8 @@ #define D_SENSOR_HRE_CLOCK "HRE Clock" #define D_SENSOR_HRE_DATA "HRE Data" #define D_SENSOR_ADE7953_IRQ "ADE7953 IRQ" -#define D_SENSOR_BUZZER "Buzzer" -#define D_SENSOR_OLED_RESET "OLED Reset" +#define D_SENSOR_BUZZER "Зумер" +#define D_SENSOR_OLED_RESET "Нулиране OLED" #define D_SENSOR_ZIGBEE_TXD "Zigbee Tx" #define D_SENSOR_ZIGBEE_RXD "Zigbee Rx" #define D_SENSOR_SOLAXX1_TX "SolaxX1 Tx" @@ -651,29 +667,57 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" +#define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" +#define D_GPIO_WEBCAM_PWDN "CAM_PWDN" +#define D_GPIO_WEBCAM_RESET "CAM_RESET" +#define D_GPIO_WEBCAM_XCLK "CAM_XCLK" +#define D_GPIO_WEBCAM_SIOD "CAM_SIOD" +#define D_GPIO_WEBCAM_SIOC "CAM_SIOC" +#define D_GPIO_WEBCAM_DATA "CAM_DATA" +#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC" +#define D_GPIO_WEBCAM_HREF "CAM_HREF" +#define D_GPIO_WEBCAM_PCLK "CAM_PCLK" +#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" +#define D_GPIO_WEBCAM_HSD "CAM_HSD" +#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "A" +#define D_UNIT_CELSIUS "C" #define D_UNIT_CENTIMETER "cm" +#define D_UNIT_DEGREE "°" +#define D_UNIT_FAHRENHEIT "F" #define D_UNIT_HERTZ "Hz" #define D_UNIT_HOUR "h" #define D_UNIT_GALLONS "gal" #define D_UNIT_GALLONS_PER_MIN "gal/min" #define D_UNIT_KILOGRAM "kg" #define D_UNIT_INCREMENTS "inc" +#define D_UNIT_KELVIN "K" +#define D_UNIT_KILOMETER "km" #define D_UNIT_KILOMETER_PER_HOUR "km/h" #define D_UNIT_KILOOHM "kΩ" #define D_UNIT_KILOWATTHOUR "kWh" @@ -689,6 +733,7 @@ #define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_MILLION "ppm" +#define D_UNIT_PERCENT "%%" #define D_UNIT_PRESSURE "hPa" #define D_UNIT_SECOND "s" #define D_UNIT_SECTORS "сектори" @@ -708,7 +753,7 @@ #define D_TOTAL_REACTIVE "Общо реактивна мощност" #define D_UNIT_KWARH "kVArh" #define D_UNIT_ANGLE "°" -#define D_TOTAL_ACTIVE "Total Active" +#define D_TOTAL_ACTIVE "Общо активна мощност" //SOLAXX1 #define D_PV1_VOLTAGE "Напрежение на PV1" @@ -735,16 +780,43 @@ #define D_SOLAX_ERROR_8 "Грешка - друго оборудване" //xdrv_10_scripter.ino -#define D_CONFIGURE_SCRIPT "Edit script" -#define D_SCRIPT "edit script" -#define D_SDCARD_UPLOAD "file upload" -#define D_SDCARD_DIR "sd card directory" -#define D_UPL_DONE "Done" -#define D_SCRIPT_CHARS_LEFT "chars left" -#define D_SCRIPT_CHARS_NO_MORE "no more chars" -#define D_SCRIPT_DOWNLOAD "Download" -#define D_SCRIPT_ENABLE "script enable" -#define D_SCRIPT_UPLOAD "Upload" -#define D_SCRIPT_UPLOAD_FILES "Upload files" +#define D_CONFIGURE_SCRIPT "Редакция на скрипт" +#define D_SCRIPT "редактирай скрипт" +#define D_SDCARD_UPLOAD "изпрати файл" +#define D_SDCARD_DIR "директория на SD картата" +#define D_UPL_DONE "Готово" +#define D_SCRIPT_CHARS_LEFT "оставащи символи" +#define D_SCRIPT_CHARS_NO_MORE "няма повече символи" +#define D_SCRIPT_DOWNLOAD "Изтегляне" +#define D_SCRIPT_ENABLE "активирай скрипт" +#define D_SCRIPT_UPLOAD "Изпращане" +#define D_SCRIPT_UPLOAD_FILES "Изпращане на файлове" + +//xsns_67_as3935.ino +#define D_AS3935_GAIN "усилване:" +#define D_AS3935_ENERGY "енергия:" +#define D_AS3935_DISTANCE "разстояние:" +#define D_AS3935_DISTURBER "смущение:" +#define D_AS3935_VRMS "µVrms:" +#define D_AS3935_APRX "прибл.:" +#define D_AS3935_AWAY "далече" +#define D_AS3935_LIGHT "осветление" +#define D_AS3935_OUT "осветление извън обхват" +#define D_AS3935_NOT "неопределено разстояние" +#define D_AS3935_ABOVE "околно осветление" +#define D_AS3935_NOISE "открит шум" +#define D_AS3935_DISTDET "открито смущение" +#define D_AS3935_INTNOEV "Прекъсване без Събитие!" +#define D_AS3935_NOMESS "слушане..." +#define D_AS3935_ON "Вкл." +#define D_AS3935_OFF "Изкл." +#define D_AS3935_INDOORS "На закрито" +#define D_AS3935_OUTDOORS "На открито" +#define D_AS3935_CAL_FAIL "калибрирането е неуспешно" +#define D_AS3935_CAL_OK "калибрирането е зададено на:" + +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" #endif // _LANGUAGE_BG_BG_H_ diff --git a/tasmota/language/cs-CZ.h b/tasmota/language/cs_CZ.h similarity index 90% rename from tasmota/language/cs-CZ.h rename to tasmota/language/cs_CZ.h index fb625af7b..e857b8e69 100644 --- a/tasmota/language/cs-CZ.h +++ b/tasmota/language/cs_CZ.h @@ -56,6 +56,7 @@ #define D_AP "AP" // Access Point #define D_AS "jako" #define D_AUTO "AUTO" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "Blikání" #define D_BLINKOFF "BlikáníVyp" #define D_BOOT_COUNT "Počítadlo spuštění" @@ -98,6 +99,8 @@ #define D_FILE "Soubor" #define D_FLOW_RATE "Flow rate" #define D_FREE_MEMORY "Volná paměť" +#define D_PSR_MAX_MEMORY "PS-RAM Memory" +#define D_PSR_FREE_MEMORY "PS-RAM free Memory" #define D_FREQUENCY "Kmitočet" #define D_GAS "Plyn" #define D_GATEWAY "Výchozí brána" @@ -114,6 +117,7 @@ #define D_IP_ADDRESS "Adresa IP" #define D_LIGHT "Světlo" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "Modul" #define D_MOISTURE "Moisture" #define D_MQTT "MQTT" @@ -300,6 +304,7 @@ #define D_OTHER_PARAMETERS "Další nastavení" #define D_TEMPLATE "Šablona" #define D_ACTIVATE "Aktivovat" +#define D_DEVICE_NAME "Device Name" #define D_WEB_ADMIN_PASSWORD "Heslo Web administrátora" #define D_MQTT_ENABLE "MQTT aktivní" #define D_FRIENDLY_NAME "Friendly Name" @@ -442,6 +447,8 @@ #define D_KNX_ENHANCEMENT "Communication Enhancement" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Spotřeba Dnes" @@ -482,6 +489,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #define D_PARTICALS_BEYOND "částic" +// xsns_27_apds9960.ino +#define D_GESTURE "Gesto" +#define D_COLOR_RED "Červená" +#define D_COLOR_GREEN "Zelená" +#define D_COLOR_BLUE "Modrá" +#define D_CCT "CCT" +#define D_PROXIMITY "Blízkost" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Accel. osa-X" #define D_AY_AXIS "Accel. osa-Y" @@ -567,7 +582,8 @@ #define D_SENSOR_SPI_MOSI "SPI MOSI" #define D_SENSOR_SPI_CLK "SPI CLK" #define D_SENSOR_BACKLIGHT "Backlight" -#define D_SENSOR_PMS5003 "PMS5003" +#define D_SENSOR_PMS5003_TX "PMS5003 Tx" +#define D_SENSOR_PMS5003_RX "PMS5003 Rx" #define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" #define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" #define D_SENSOR_HPMA_RX "HPMA Rx" @@ -651,29 +667,57 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" +#define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" +#define D_GPIO_WEBCAM_PWDN "CAM_PWDN" +#define D_GPIO_WEBCAM_RESET "CAM_RESET" +#define D_GPIO_WEBCAM_XCLK "CAM_XCLK" +#define D_GPIO_WEBCAM_SIOD "CAM_SIOD" +#define D_GPIO_WEBCAM_SIOC "CAM_SIOC" +#define D_GPIO_WEBCAM_DATA "CAM_DATA" +#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC" +#define D_GPIO_WEBCAM_HREF "CAM_HREF" +#define D_GPIO_WEBCAM_PCLK "CAM_PCLK" +#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" +#define D_GPIO_WEBCAM_HSD "CAM_HSD" +#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "A" +#define D_UNIT_CELSIUS "C" #define D_UNIT_CENTIMETER "cm" +#define D_UNIT_DEGREE "°" +#define D_UNIT_FAHRENHEIT "F" #define D_UNIT_HERTZ "Hz" #define D_UNIT_HOUR "hod" #define D_UNIT_GALLONS "gal" #define D_UNIT_GALLONS_PER_MIN "g/m" #define D_UNIT_KILOGRAM "kg" #define D_UNIT_INCREMENTS "inc" +#define D_UNIT_KELVIN "K" +#define D_UNIT_KILOMETER "km" #define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" #define D_UNIT_KILOOHM "kΩ" #define D_UNIT_KILOWATTHOUR "kWh" @@ -689,6 +733,7 @@ #define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_MILLION "ppm" +#define D_UNIT_PERCENT "%%" #define D_UNIT_PRESSURE "hPa" #define D_UNIT_SECOND "sec" #define D_UNIT_SECTORS "sektory" @@ -747,4 +792,31 @@ #define D_SCRIPT_UPLOAD "Upload" #define D_SCRIPT_UPLOAD_FILES "Upload files" +//xsns_67_as3935.ino +#define D_AS3935_GAIN "gain:" +#define D_AS3935_ENERGY "energy:" +#define D_AS3935_DISTANCE "distance:" +#define D_AS3935_DISTURBER "disturber:" +#define D_AS3935_VRMS "µVrms:" +#define D_AS3935_APRX "aprx.:" +#define D_AS3935_AWAY "away" +#define D_AS3935_LIGHT "lightning" +#define D_AS3935_OUT "lightning out of range" +#define D_AS3935_NOT "distance not determined" +#define D_AS3935_ABOVE "lightning overhead" +#define D_AS3935_NOISE "noise detected" +#define D_AS3935_DISTDET "disturber detected" +#define D_AS3935_INTNOEV "Interrupt with no Event!" +#define D_AS3935_NOMESS "listening..." +#define D_AS3935_ON "On" +#define D_AS3935_OFF "Off" +#define D_AS3935_INDOORS "Indoors" +#define D_AS3935_OUTDOORS "Outdoors" +#define D_AS3935_CAL_FAIL "calibration failed" +#define D_AS3935_CAL_OK "calibration set to:" + +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_CS_CZ_H_ diff --git a/tasmota/language/de-DE.h b/tasmota/language/de_DE.h similarity index 90% rename from tasmota/language/de-DE.h rename to tasmota/language/de_DE.h index a698297de..b31e07901 100644 --- a/tasmota/language/de-DE.h +++ b/tasmota/language/de_DE.h @@ -56,6 +56,7 @@ #define D_AP "AP" // Access Point #define D_AS "als" #define D_AUTO "AUTO" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "Blinken" #define D_BLINKOFF "BlinkenAus" #define D_BOOT_COUNT "Anzahl Startvorgänge" @@ -98,6 +99,8 @@ #define D_FILE "Datei" #define D_FLOW_RATE "Durchflussmenge" #define D_FREE_MEMORY "Freier Arbeitsspeicher" +#define D_PSR_MAX_MEMORY "PS-RAM Speicher" +#define D_PSR_FREE_MEMORY "PS-RAM freier Speicher" #define D_FREQUENCY "Frequenz" #define D_GAS "Gas" #define D_GATEWAY "Gateway" @@ -105,7 +108,7 @@ #define D_HOST "Host" #define D_HOSTNAME "Hostname" #define D_HUMIDITY "Feuchtigkeit" -#define D_ILLUMINANCE "Beleuchtungsintensität" +#define D_ILLUMINANCE "Beleuchtungsstärke" #define D_IMMEDIATE "direkt" // Button immediate #define D_INDEX "Index" #define D_INFO "Info" @@ -114,6 +117,7 @@ #define D_IP_ADDRESS "IP-Adresse" #define D_LIGHT "Licht" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "Modul" #define D_MOISTURE "Moisture" #define D_MQTT "MQTT" @@ -300,6 +304,7 @@ #define D_OTHER_PARAMETERS "Sonstige Einstellungen" #define D_TEMPLATE "Vorlage" #define D_ACTIVATE "Aktivieren" +#define D_DEVICE_NAME "Device Name" #define D_WEB_ADMIN_PASSWORD "Passwort für Web Oberfläche" #define D_MQTT_ENABLE "MQTT aktivieren" #define D_FRIENDLY_NAME "Name [friendly name]" @@ -442,6 +447,8 @@ #define D_KNX_ENHANCEMENT "Erweiterte Kommunikation" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Energie heute" @@ -482,6 +489,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #define D_PARTICALS_BEYOND "Partikel" +// xsns_27_apds9960.ino +#define D_GESTURE "Geste" +#define D_COLOR_RED "Rot" +#define D_COLOR_GREEN "Grün" +#define D_COLOR_BLUE "Blau" +#define D_CCT "CCT" +#define D_PROXIMITY "Nähe" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Beschl. X-Achse" #define D_AY_AXIS "Beschl. Y-Achse" @@ -567,7 +582,8 @@ #define D_SENSOR_SPI_MOSI "SPI MOSI" #define D_SENSOR_SPI_CLK "SPI CLK" #define D_SENSOR_BACKLIGHT "Backlight" -#define D_SENSOR_PMS5003 "PMS5003" +#define D_SENSOR_PMS5003_TX "PMS5003 Tx" +#define D_SENSOR_PMS5003_RX "PMS5003 Rx" #define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" #define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" #define D_SENSOR_HPMA_RX "HPMA Rx" @@ -651,28 +667,56 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" +#define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" +#define D_GPIO_WEBCAM_PWDN "CAM_PWDN" +#define D_GPIO_WEBCAM_RESET "CAM_RESET" +#define D_GPIO_WEBCAM_XCLK "CAM_XCLK" +#define D_GPIO_WEBCAM_SIOD "CAM_SIOD" +#define D_GPIO_WEBCAM_SIOC "CAM_SIOC" +#define D_GPIO_WEBCAM_DATA "CAM_DATA" +#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC" +#define D_GPIO_WEBCAM_HREF "CAM_HREF" +#define D_GPIO_WEBCAM_PCLK "CAM_PCLK" +#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" +#define D_GPIO_WEBCAM_HSD "CAM_HSD" +#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "A" +#define D_UNIT_CELSIUS "C" #define D_UNIT_CENTIMETER "cm" +#define D_UNIT_DEGREE "°" +#define D_UNIT_FAHRENHEIT "F" #define D_UNIT_HERTZ "Hz" #define D_UNIT_HOUR "h" #define D_UNIT_GALLONS "gal" #define D_UNIT_GALLONS_PER_MIN "g/m" #define D_UNIT_INCREMENTS "inc" +#define D_UNIT_KELVIN "K" +#define D_UNIT_KILOMETER "km" #define D_UNIT_KILOGRAM "kg" #define D_UNIT_KILOMETER_PER_HOUR "km/h" #define D_UNIT_KILOOHM "kΩ" @@ -689,6 +733,7 @@ #define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_MILLION "ppm" +#define D_UNIT_PERCENT "%%" #define D_UNIT_PRESSURE "hPa" #define D_UNIT_SECOND "s" #define D_UNIT_SECTORS "Sektoren" @@ -747,4 +792,31 @@ #define D_SCRIPT_UPLOAD "Upload" #define D_SCRIPT_UPLOAD_FILES "Upload Dateien" +//xsns_67_as3935.ino +#define D_AS3935_GAIN "Rauschpegel:" +#define D_AS3935_ENERGY "Energie:" +#define D_AS3935_DISTANCE "Entfernung:" +#define D_AS3935_DISTURBER "Störsingal:" +#define D_AS3935_VRMS "µVrms:" +#define D_AS3935_APRX "ca.:" +#define D_AS3935_AWAY "entfernt" +#define D_AS3935_LIGHT "Blitz" +#define D_AS3935_OUT "ausserhalb der Reichweite" +#define D_AS3935_NOT "Entfernung nicht ermittelbar" +#define D_AS3935_ABOVE "Blitz überhalb" +#define D_AS3935_NOISE "Rauschen entdeckt" +#define D_AS3935_DISTDET "Störer entdeckt" +#define D_AS3935_INTNOEV "Interrupt ohne Grund!" +#define D_AS3935_NOMESS "lausche..." +#define D_AS3935_ON "On" +#define D_AS3935_OFF "Off" +#define D_AS3935_INDOORS "Indoors" +#define D_AS3935_OUTDOORS "Outdoors" +#define D_AS3935_CAL_FAIL "Kalibrierung fehlerhaft" +#define D_AS3935_CAL_OK "Cap gesetzt auf:" + +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_DE_DE_H_ diff --git a/tasmota/language/el-GR.h b/tasmota/language/el_GR.h similarity index 91% rename from tasmota/language/el-GR.h rename to tasmota/language/el_GR.h index 6e65f2dce..709c8f6c3 100644 --- a/tasmota/language/el-GR.h +++ b/tasmota/language/el_GR.h @@ -56,6 +56,7 @@ #define D_AP "AP" // Access Point #define D_AS "ως" #define D_AUTO "ΑΥΤΟΜΑΤΟ" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "Blink" #define D_BLINKOFF "BlinkOff" #define D_BOOT_COUNT "Καταμέτρηση εκκινήσεων" @@ -98,6 +99,8 @@ #define D_FILE "Αρχείο" #define D_FLOW_RATE "Flow rate" #define D_FREE_MEMORY "Ελεύθερη μνήμη" +#define D_PSR_MAX_MEMORY "PS-RAM Memory" +#define D_PSR_FREE_MEMORY "PS-RAM free Memory" #define D_FREQUENCY "Συχνότητα" #define D_GAS "Αέριο" #define D_GATEWAY "Πύλη" @@ -114,6 +117,7 @@ #define D_IP_ADDRESS "Διεύθυνση IP" #define D_LIGHT "Φως" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "Μονάδα" #define D_MOISTURE "Moisture" #define D_MQTT "MQTT" @@ -300,6 +304,7 @@ #define D_OTHER_PARAMETERS "Άλλες παράμετροι" #define D_TEMPLATE "Πρότυπο" #define D_ACTIVATE "Ενεργοποίηση" +#define D_DEVICE_NAME "Device Name" #define D_WEB_ADMIN_PASSWORD "Κωδικός διαχειριστή" #define D_MQTT_ENABLE "Ενεργοποίηση MQTT" #define D_FRIENDLY_NAME "Φιλική ονομασία" @@ -442,6 +447,8 @@ #define D_KNX_ENHANCEMENT "Βελτίωση επικοινωνίας" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Ενέργεια σήμερα" @@ -482,6 +489,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #define D_PARTICALS_BEYOND "Particals" +// xsns_27_apds9960.ino +#define D_GESTURE "Χειρονομία" +#define D_COLOR_RED "Κόκκινο" +#define D_COLOR_GREEN "Πράσινο" +#define D_COLOR_BLUE "Μπλε" +#define D_CCT "CCT" +#define D_PROXIMITY "Εγγύτητα" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Accel. X-Axis" #define D_AY_AXIS "Accel. Y-Axis" @@ -567,7 +582,8 @@ #define D_SENSOR_SPI_MOSI "SPI MOSI" #define D_SENSOR_SPI_CLK "SPI CLK" #define D_SENSOR_BACKLIGHT "Backlight" -#define D_SENSOR_PMS5003 "PMS5003" +#define D_SENSOR_PMS5003_TX "PMS5003 Tx" +#define D_SENSOR_PMS5003_RX "PMS5003 Rx" #define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" #define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" #define D_SENSOR_HPMA_RX "HPMA Rx" @@ -651,28 +667,56 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" +#define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" +#define D_GPIO_WEBCAM_PWDN "CAM_PWDN" +#define D_GPIO_WEBCAM_RESET "CAM_RESET" +#define D_GPIO_WEBCAM_XCLK "CAM_XCLK" +#define D_GPIO_WEBCAM_SIOD "CAM_SIOD" +#define D_GPIO_WEBCAM_SIOC "CAM_SIOC" +#define D_GPIO_WEBCAM_DATA "CAM_DATA" +#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC" +#define D_GPIO_WEBCAM_HREF "CAM_HREF" +#define D_GPIO_WEBCAM_PCLK "CAM_PCLK" +#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" +#define D_GPIO_WEBCAM_HSD "CAM_HSD" +#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "A" +#define D_UNIT_CELSIUS "C" #define D_UNIT_CENTIMETER "cm" +#define D_UNIT_DEGREE "°" +#define D_UNIT_FAHRENHEIT "F" #define D_UNIT_HERTZ "Hz" #define D_UNIT_HOUR "h" #define D_UNIT_GALLONS "gal" #define D_UNIT_GALLONS_PER_MIN "g/m" #define D_UNIT_INCREMENTS "inc" +#define D_UNIT_KELVIN "K" +#define D_UNIT_KILOMETER "km" #define D_UNIT_KILOGRAM "kg" #define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" #define D_UNIT_KILOOHM "kΩ" @@ -689,6 +733,7 @@ #define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_MILLION "ppm" +#define D_UNIT_PERCENT "%%" #define D_UNIT_PRESSURE "hPa" #define D_UNIT_SECOND "sec" #define D_UNIT_SECTORS "sectors" @@ -747,4 +792,31 @@ #define D_SCRIPT_UPLOAD "Upload" #define D_SCRIPT_UPLOAD_FILES "Upload files" +//xsns_67_as3935.ino +#define D_AS3935_GAIN "gain:" +#define D_AS3935_ENERGY "energy:" +#define D_AS3935_DISTANCE "distance:" +#define D_AS3935_DISTURBER "disturber:" +#define D_AS3935_VRMS "µVrms:" +#define D_AS3935_APRX "aprx.:" +#define D_AS3935_AWAY "away" +#define D_AS3935_LIGHT "lightning" +#define D_AS3935_OUT "lightning out of range" +#define D_AS3935_NOT "distance not determined" +#define D_AS3935_ABOVE "lightning overhead" +#define D_AS3935_NOISE "noise detected" +#define D_AS3935_DISTDET "disturber detected" +#define D_AS3935_INTNOEV "Interrupt with no Event!" +#define D_AS3935_NOMESS "listening..." +#define D_AS3935_ON "On" +#define D_AS3935_OFF "Off" +#define D_AS3935_INDOORS "Indoors" +#define D_AS3935_OUTDOORS "Outdoors" +#define D_AS3935_CAL_FAIL "calibration failed" +#define D_AS3935_CAL_OK "calibration set to:" + +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_EL_GR_H_ diff --git a/tasmota/language/en-GB.h b/tasmota/language/en_GB.h similarity index 90% rename from tasmota/language/en-GB.h rename to tasmota/language/en_GB.h index 322757d17..1586a0f92 100644 --- a/tasmota/language/en-GB.h +++ b/tasmota/language/en_GB.h @@ -56,6 +56,7 @@ #define D_AP "AP" // Access Point #define D_AS "as" #define D_AUTO "AUTO" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "Blink" #define D_BLINKOFF "BlinkOff" #define D_BOOT_COUNT "Boot Count" @@ -98,6 +99,8 @@ #define D_FILE "File" #define D_FLOW_RATE "Flow rate" #define D_FREE_MEMORY "Free Memory" +#define D_PSR_MAX_MEMORY "PS-RAM Memory" +#define D_PSR_FREE_MEMORY "PS-RAM free Memory" #define D_FREQUENCY "Frequency" #define D_GAS "Gas" #define D_GATEWAY "Gateway" @@ -114,6 +117,7 @@ #define D_IP_ADDRESS "IP Address" #define D_LIGHT "Light" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "Module" #define D_MOISTURE "Moisture" #define D_MQTT "MQTT" @@ -300,6 +304,7 @@ #define D_OTHER_PARAMETERS "Other parameters" #define D_TEMPLATE "Template" #define D_ACTIVATE "Activate" +#define D_DEVICE_NAME "Device Name" #define D_WEB_ADMIN_PASSWORD "Web Admin Password" #define D_MQTT_ENABLE "MQTT enable" #define D_FRIENDLY_NAME "Friendly Name" @@ -442,6 +447,8 @@ #define D_KNX_ENHANCEMENT "Communication Enhancement" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Energy Today" @@ -482,6 +489,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #define D_PARTICALS_BEYOND "Particles" +// xsns_27_apds9960.ino +#define D_GESTURE "Gesture" +#define D_COLOR_RED "Red" +#define D_COLOR_GREEN "Green" +#define D_COLOR_BLUE "Blue" +#define D_CCT "CCT" +#define D_PROXIMITY "Proximity" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Accel. X-Axis" #define D_AY_AXIS "Accel. Y-Axis" @@ -567,7 +582,8 @@ #define D_SENSOR_SPI_MOSI "SPI MOSI" #define D_SENSOR_SPI_CLK "SPI CLK" #define D_SENSOR_BACKLIGHT "Backlight" -#define D_SENSOR_PMS5003 "PMS5003" +#define D_SENSOR_PMS5003_TX "PMS5003 Tx" +#define D_SENSOR_PMS5003_RX "PMS5003 Rx" #define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" #define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" #define D_SENSOR_HPMA_RX "HPMA Rx" @@ -651,28 +667,56 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" +#define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" +#define D_GPIO_WEBCAM_PWDN "CAM_PWDN" +#define D_GPIO_WEBCAM_RESET "CAM_RESET" +#define D_GPIO_WEBCAM_XCLK "CAM_XCLK" +#define D_GPIO_WEBCAM_SIOD "CAM_SIOD" +#define D_GPIO_WEBCAM_SIOC "CAM_SIOC" +#define D_GPIO_WEBCAM_DATA "CAM_DATA" +#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC" +#define D_GPIO_WEBCAM_HREF "CAM_HREF" +#define D_GPIO_WEBCAM_PCLK "CAM_PCLK" +#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" +#define D_GPIO_WEBCAM_HSD "CAM_HSD" +#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "A" +#define D_UNIT_CELSIUS "C" #define D_UNIT_CENTIMETER "cm" +#define D_UNIT_DEGREE "°" +#define D_UNIT_FAHRENHEIT "F" #define D_UNIT_HERTZ "Hz" #define D_UNIT_HOUR "h" #define D_UNIT_GALLONS "gal" #define D_UNIT_GALLONS_PER_MIN "g/m" #define D_UNIT_INCREMENTS "inc" +#define D_UNIT_KELVIN "K" +#define D_UNIT_KILOMETER "km" #define D_UNIT_KILOGRAM "kg" #define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" #define D_UNIT_KILOOHM "kΩ" @@ -689,6 +733,7 @@ #define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_MILLION "ppm" +#define D_UNIT_PERCENT "%%" #define D_UNIT_PRESSURE "hPa" #define D_UNIT_SECOND "sec" #define D_UNIT_SECTORS "sectors" @@ -747,4 +792,31 @@ #define D_SCRIPT_UPLOAD "Upload" #define D_SCRIPT_UPLOAD_FILES "Upload files" +//xsns_67_as3935.ino +#define D_AS3935_GAIN "gain:" +#define D_AS3935_ENERGY "energy:" +#define D_AS3935_DISTANCE "distance:" +#define D_AS3935_DISTURBER "disturber:" +#define D_AS3935_VRMS "µVrms:" +#define D_AS3935_APRX "aprx.:" +#define D_AS3935_AWAY "away" +#define D_AS3935_LIGHT "lightning" +#define D_AS3935_OUT "lightning out of range" +#define D_AS3935_NOT "distance not determined" +#define D_AS3935_ABOVE "lightning overhead" +#define D_AS3935_NOISE "noise detected" +#define D_AS3935_DISTDET "disturber detected" +#define D_AS3935_INTNOEV "Interrupt with no Event!" +#define D_AS3935_NOMESS "listening..." +#define D_AS3935_ON "On" +#define D_AS3935_OFF "Off" +#define D_AS3935_INDOORS "Indoors" +#define D_AS3935_OUTDOORS "Outdoors" +#define D_AS3935_CAL_FAIL "calibration failed" +#define D_AS3935_CAL_OK "calibration set to:" + +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_EN_GB_H_ diff --git a/tasmota/language/es-ES.h b/tasmota/language/es_ES.h similarity index 90% rename from tasmota/language/es-ES.h rename to tasmota/language/es_ES.h index 39f18f29d..b23f71915 100644 --- a/tasmota/language/es-ES.h +++ b/tasmota/language/es_ES.h @@ -28,7 +28,7 @@ * Use online command StateText to translate ON, OFF, HOLD and TOGGLE. * Use online command Prefix to translate cmnd, stat and tele. * - * Updated until v8.1.0.1 + * Updated until v8.3.0.2 \*********************************************************************/ #define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English) @@ -56,6 +56,7 @@ #define D_AP "AP" // Access Point #define D_AS "como" #define D_AUTO "AUTO" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "Blink" #define D_BLINKOFF "BlinkOff" #define D_BOOT_COUNT "Conteo Reinicios" @@ -79,7 +80,7 @@ #define D_DATA "Datos" #define D_DARKLIGHT "Oscuro" #define D_DEBUG "Debug" -#define D_DEWPOINT "Dew point" +#define D_DEWPOINT "Punto de Rocío" #define D_DISABLED "Deshabilitado" #define D_DISTANCE "Distancia" #define D_DNS_SERVER "Servidor DNS" @@ -98,6 +99,8 @@ #define D_FILE "Archivo" #define D_FLOW_RATE "Caudal" #define D_FREE_MEMORY "Memoria Libre" +#define D_PSR_MAX_MEMORY "Memoria PS-RAM" +#define D_PSR_FREE_MEMORY "Memoria PS-RAM libre" #define D_FREQUENCY "Frecuencia" #define D_GAS "Gas" #define D_GATEWAY "Gateway" @@ -114,6 +117,7 @@ #define D_IP_ADDRESS "Dirección IP" #define D_LIGHT "Luz" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "Módulo" #define D_MOISTURE "Humedad del Suelo" #define D_MQTT "MQTT" @@ -138,7 +142,7 @@ #define D_PROGRAM_SIZE "Tamaño Programa" #define D_PROJECT "Proyecto" #define D_RAIN "Lluvia" -#define D_RANGE "Range" +#define D_RANGE "Rango" #define D_RECEIVED "Recibido" #define D_RESTART "Reiniciar" #define D_RESTARTING "Reiniciando" @@ -300,6 +304,7 @@ #define D_OTHER_PARAMETERS "Otros parámetros" #define D_TEMPLATE "Plantilla" #define D_ACTIVATE "Activar" +#define D_DEVICE_NAME "Nombre de Dispositivo" #define D_WEB_ADMIN_PASSWORD "Clave Administrador Web" #define D_MQTT_ENABLE "Habilitar MQTT" #define D_FRIENDLY_NAME "Nombre Amigable" @@ -442,6 +447,8 @@ #define D_KNX_ENHANCEMENT "Mejora de Comunicación" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX ESCENA TX" +#define D_KNX_RX_SCENE "KNX ESCENA RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Energía Hoy" @@ -482,6 +489,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #define D_PARTICALS_BEYOND "Partículas" +// xsns_27_apds9960.ino +#define D_GESTURE "Gesto" +#define D_COLOR_RED "Rojo" +#define D_COLOR_GREEN "Verde" +#define D_COLOR_BLUE "Azul" +#define D_CCT "CCT" +#define D_PROXIMITY "Proximidad" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Accel. X-Axis" #define D_AY_AXIS "Accel. Y-Axis" @@ -567,7 +582,8 @@ #define D_SENSOR_SPI_MOSI "SPI MOSI" #define D_SENSOR_SPI_CLK "SPI CLK" #define D_SENSOR_BACKLIGHT "Backlight" -#define D_SENSOR_PMS5003 "PMS5003" +#define D_SENSOR_PMS5003_TX "PMS5003 Tx" +#define D_SENSOR_PMS5003_RX "PMS5003 Rx" #define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" #define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" #define D_SENSOR_HPMA_RX "HPMA Rx" @@ -651,28 +667,56 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" +#define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" +#define D_GPIO_WEBCAM_PWDN "CAM_PWDN" +#define D_GPIO_WEBCAM_RESET "CAM_RESET" +#define D_GPIO_WEBCAM_XCLK "CAM_XCLK" +#define D_GPIO_WEBCAM_SIOD "CAM_SIOD" +#define D_GPIO_WEBCAM_SIOC "CAM_SIOC" +#define D_GPIO_WEBCAM_DATA "CAM_DATA" +#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC" +#define D_GPIO_WEBCAM_HREF "CAM_HREF" +#define D_GPIO_WEBCAM_PCLK "CAM_PCLK" +#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" +#define D_GPIO_WEBCAM_HSD "CAM_HSD" +#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "A" +#define D_UNIT_CELSIUS "C" #define D_UNIT_CENTIMETER "cm" +#define D_UNIT_DEGREE "°" +#define D_UNIT_FAHRENHEIT "F" #define D_UNIT_HERTZ "Hz" #define D_UNIT_HOUR "h" #define D_UNIT_GALLONS "gal" #define D_UNIT_GALLONS_PER_MIN "g/m" #define D_UNIT_INCREMENTS "inc" +#define D_UNIT_KELVIN "K" +#define D_UNIT_KILOMETER "km" #define D_UNIT_KILOGRAM "kg" #define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" #define D_UNIT_KILOOHM "kΩ" @@ -689,6 +733,7 @@ #define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_MILLION "ppm" +#define D_UNIT_PERCENT "%%" #define D_UNIT_PRESSURE "hPa" #define D_UNIT_SECOND "seg" #define D_UNIT_SECTORS "sectores" @@ -747,4 +792,31 @@ #define D_SCRIPT_UPLOAD "Cargar" #define D_SCRIPT_UPLOAD_FILES "Cargar Archivos" +//xsns_67_as3935.ino +#define D_AS3935_GAIN "Ganancia:" +#define D_AS3935_ENERGY "Energía:" +#define D_AS3935_DISTANCE "Distancia:" +#define D_AS3935_DISTURBER "Perturbancia:" +#define D_AS3935_VRMS "µVrms:" +#define D_AS3935_APRX "aprox.:" +#define D_AS3935_AWAY "lejos" +#define D_AS3935_LIGHT "Relámpagos" +#define D_AS3935_OUT "Relámpagos fuera de rango" +#define D_AS3935_NOT "Distancia no determinada" +#define D_AS3935_ABOVE "Relámpagos cercanos" +#define D_AS3935_NOISE "Ruido detectado" +#define D_AS3935_DISTDET "Perturbancia detectada" +#define D_AS3935_INTNOEV "Interrupción sin evento!" +#define D_AS3935_NOMESS "Escuchando..." +#define D_AS3935_ON "Encendido" +#define D_AS3935_OFF "Apagado" +#define D_AS3935_INDOORS "Dentro de casa" +#define D_AS3935_OUTDOORS "Al aire libre" +#define D_AS3935_CAL_FAIL "Falló calibración" +#define D_AS3935_CAL_OK "Calibración a:" + +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_ES_ES_H_ diff --git a/tasmota/language/fr-FR.h b/tasmota/language/fr_FR.h similarity index 89% rename from tasmota/language/fr-FR.h rename to tasmota/language/fr_FR.h index beb6e6b38..a1ceba0a2 100644 --- a/tasmota/language/fr-FR.h +++ b/tasmota/language/fr_FR.h @@ -56,6 +56,7 @@ #define D_AP "AP" // Access Point #define D_AS "comme" #define D_AUTO "AUTO" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "Blink" #define D_BLINKOFF "BlinkOff" #define D_BOOT_COUNT "Nombre de boot" @@ -79,7 +80,7 @@ #define D_DATA "Donnée" #define D_DARKLIGHT "Sombre" #define D_DEBUG "Debug" -#define D_DEWPOINT "Dew point" +#define D_DEWPOINT "Point de rosée" #define D_DISABLED "Désactivé" #define D_DISTANCE "Distance" #define D_DNS_SERVER "Serveur DNS" @@ -98,6 +99,8 @@ #define D_FILE "Fichier" #define D_FLOW_RATE "Débit" #define D_FREE_MEMORY "Mémoire libre" +#define D_PSR_MAX_MEMORY "PS-RAM Memory" +#define D_PSR_FREE_MEMORY "PS-RAM free Memory" #define D_FREQUENCY "Fréquence" #define D_GAS "Gaz" #define D_GATEWAY "Passerelle" @@ -114,6 +117,7 @@ #define D_IP_ADDRESS "Adresse IP" #define D_LIGHT "Lumière" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "Module" #define D_MOISTURE "Humidité" #define D_MQTT "MQTT" @@ -138,7 +142,7 @@ #define D_PROGRAM_SIZE "Taille programme" #define D_PROJECT "Projet" #define D_RAIN "Pluie" -#define D_RANGE "Range" +#define D_RANGE "Intervalle" #define D_RECEIVED "Reçu" #define D_RESTART "Redémarrage" #define D_RESTARTING "Redémarre" @@ -189,8 +193,8 @@ // tasmota.ino #define D_WARNING_MINIMAL_VERSION "ATTENTION Cette version ne supporte pas les réglages persistants" -#define D_LEVEL_10 "level 1-0" -#define D_LEVEL_01 "level 0-1" +#define D_LEVEL_10 "niveau 1-0" +#define D_LEVEL_01 "niveau 0-1" #define D_SERIAL_LOGGING_DISABLED "Journalisation série désactivée" #define D_SYSLOG_LOGGING_REENABLED "Jounalisation SysLog réactivée" @@ -300,6 +304,7 @@ #define D_OTHER_PARAMETERS "Autres paramètres" #define D_TEMPLATE "Modèle" #define D_ACTIVATE "Activer" +#define D_DEVICE_NAME "Device Name" #define D_WEB_ADMIN_PASSWORD "Mot de passe Web Admin" #define D_MQTT_ENABLE "MQTT activé" #define D_FRIENDLY_NAME "Surnom" @@ -402,7 +407,7 @@ #define D_DOMOTICZ_TEMP_HUM "Temp,Hum" #define D_DOMOTICZ_TEMP_HUM_BARO "Temp,Hum,Baro" #define D_DOMOTICZ_POWER_ENERGY "Puissance,Énergie" - #define D_DOMOTICZ_ILLUMINANCE "Illuminance" + #define D_DOMOTICZ_ILLUMINANCE "Éclairement" #define D_DOMOTICZ_COUNT "Compteur/PM1" #define D_DOMOTICZ_VOLTAGE "Tension/PM2,5" #define D_DOMOTICZ_CURRENT "Courant/PM10" @@ -442,6 +447,8 @@ #define D_KNX_ENHANCEMENT "Amélioration de la communication" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX Scène TX" +#define D_KNX_RX_SCENE "KNX Scène RX" // xsns_03_energy.ino #define D_ENERGY_TODAY "Énergie aujourd'hui" @@ -482,6 +489,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #define D_PARTICALS_BEYOND "Particules" +// xsns_27_apds9960.ino +#define D_GESTURE "Geste" +#define D_COLOR_RED "Rouge" +#define D_COLOR_GREEN "Vert" +#define D_COLOR_BLUE "Bleu" +#define D_CCT "CCT" +#define D_PROXIMITY "Proximité" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Accél. Axe-X" #define D_AY_AXIS "Accél. Axe-Y" @@ -503,7 +518,7 @@ #define D_CALIBRATE "Étalonner" #define D_CALIBRATION "Étalonnage" -//xsns_35_TX20.ino +// xsns_35_TX20.ino #define D_TX20_WIND_DIRECTION "Direction du vent" #define D_TX20_WIND_SPEED "Vitesse du vent" #define D_TX20_WIND_SPEED_MIN "Vitesse Min" @@ -528,8 +543,8 @@ #define D_Spannung_L3 "Voltage L3" #define D_METERNR "Meter_number" #define D_METERSID "Service ID" -#define D_GasIN "Counter" -#define D_H2oIN "Counter" +#define D_GasIN "Compteur" +#define D_H2oIN "Compteur" #define D_StL1L2L3 "Current L1+L2+L3" #define D_SpL1L2L3 "Voltage L1+L2+L3/3" @@ -567,7 +582,8 @@ #define D_SENSOR_SPI_MOSI "SPI MOSI" #define D_SENSOR_SPI_CLK "SPI CLK" #define D_SENSOR_BACKLIGHT "RétroÉcl" -#define D_SENSOR_PMS5003 "PMS5003" +#define D_SENSOR_PMS5003_TX "PMS5003 Tx" +#define D_SENSOR_PMS5003_RX "PMS5003 Rx" #define D_SENSOR_SDS0X1_RX "SDS0X1 RX" #define D_SENSOR_SDS0X1_TX "SDS0X1 TX" #define D_SENSOR_HPMA_RX "HPMA RX" @@ -651,28 +667,56 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "Hibernation" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Esclave TX" -#define D_SENSOR_SLAVE_RX "Esclave RX" -#define D_SENSOR_SLAVE_RESET "Esclave Rst" -#define D_SENSOR_GPS_TX "GPS TX" +#define D_SENSOR_CLIENT_TX "Esclave TX" +#define D_SENSOR_CLIENT_RX "Esclave RX" +#define D_SENSOR_CLIENT_RESET "Esclave Rst" #define D_SENSOR_GPS_RX "GPS RX" +#define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" +#define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" +#define D_GPIO_WEBCAM_PWDN "CAM_PWDN" +#define D_GPIO_WEBCAM_RESET "CAM_RESET" +#define D_GPIO_WEBCAM_XCLK "CAM_XCLK" +#define D_GPIO_WEBCAM_SIOD "CAM_SIOD" +#define D_GPIO_WEBCAM_SIOC "CAM_SIOC" +#define D_GPIO_WEBCAM_DATA "CAM_DATA" +#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC" +#define D_GPIO_WEBCAM_HREF "CAM_HREF" +#define D_GPIO_WEBCAM_PCLK "CAM_PCLK" +#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" +#define D_GPIO_WEBCAM_HSD "CAM_HSD" +#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "A" +#define D_UNIT_CELSIUS "C" #define D_UNIT_CENTIMETER "cm" +#define D_UNIT_DEGREE "°" +#define D_UNIT_FAHRENHEIT "F" #define D_UNIT_HERTZ "Hz" #define D_UNIT_HOUR "h" #define D_UNIT_GALLONS "gal" #define D_UNIT_GALLONS_PER_MIN "gal/mn" #define D_UNIT_INCREMENTS "inc" +#define D_UNIT_KELVIN "K" +#define D_UNIT_KILOMETER "km" #define D_UNIT_KILOGRAM "kg" #define D_UNIT_KILOMETER_PER_HOUR "km/h" #define D_UNIT_KILOOHM "kΩ" @@ -685,10 +729,11 @@ #define D_UNIT_MILLIMETER "mm" #define D_UNIT_MILLIMETER_MERCURY "mmHg" #define D_UNIT_MILLISECOND "ms" -#define D_UNIT_MINUTE "mn" +#define D_UNIT_MINUTE "min" // https://fr.wikipedia.org/wiki/Minute_(temps)#Symbole%20et%20d%C3%A9finition #define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_MILLION "ppm" +#define D_UNIT_PERCENT "%%" #define D_UNIT_PRESSURE "hPa" #define D_UNIT_SECOND "s" #define D_UNIT_SECTORS "secteurs" @@ -747,4 +792,31 @@ #define D_SCRIPT_UPLOAD "Upload" #define D_SCRIPT_UPLOAD_FILES "Upload files" +//xsns_67_as3935.ino +#define D_AS3935_GAIN "gain:" +#define D_AS3935_ENERGY "energy:" +#define D_AS3935_DISTANCE "distance:" +#define D_AS3935_DISTURBER "disturber:" +#define D_AS3935_VRMS "µVrms:" +#define D_AS3935_APRX "aprx.:" +#define D_AS3935_AWAY "away" +#define D_AS3935_LIGHT "lightning" +#define D_AS3935_OUT "lightning out of range" +#define D_AS3935_NOT "distance not determined" +#define D_AS3935_ABOVE "lightning overhead" +#define D_AS3935_NOISE "noise detected" +#define D_AS3935_DISTDET "disturber detected" +#define D_AS3935_INTNOEV "Interrupt with no Event!" +#define D_AS3935_NOMESS "listening..." +#define D_AS3935_ON "On" +#define D_AS3935_OFF "Off" +#define D_AS3935_INDOORS "Indoors" +#define D_AS3935_OUTDOORS "Outdoors" +#define D_AS3935_CAL_FAIL "calibration failed" +#define D_AS3935_CAL_OK "calibration set to:" + +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_FR_FR_H_ diff --git a/tasmota/language/he-HE.h b/tasmota/language/he_HE.h similarity index 91% rename from tasmota/language/he-HE.h rename to tasmota/language/he_HE.h index 99e15b7fd..d9cf1e435 100644 --- a/tasmota/language/he-HE.h +++ b/tasmota/language/he_HE.h @@ -56,6 +56,7 @@ #define D_AP "AP" // Access Point #define D_AS "-כ" #define D_AUTO "אוטומטי" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "מהבהב" #define D_BLINKOFF "כיבוי היבהוב" #define D_BOOT_COUNT "מונה הפעלה מחדש" @@ -98,6 +99,8 @@ #define D_FILE "קובץ" #define D_FLOW_RATE "Flow rate" #define D_FREE_MEMORY "זכרון פנוי" +#define D_PSR_MAX_MEMORY "PS-RAM Memory" +#define D_PSR_FREE_MEMORY "PS-RAM free Memory" #define D_FREQUENCY "תדר" #define D_GAS "גז" #define D_GATEWAY "שער" @@ -114,6 +117,7 @@ #define D_IP_ADDRESS "IP כתובת" #define D_LIGHT "אור" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "מודול" #define D_MOISTURE "Moisture" #define D_MQTT "MQTT" @@ -300,6 +304,7 @@ #define D_OTHER_PARAMETERS "פרמטרים שונים" #define D_TEMPLATE "תבנית" #define D_ACTIVATE "הפעל" +#define D_DEVICE_NAME "Device Name" #define D_WEB_ADMIN_PASSWORD "סיסמת מנהל" #define D_MQTT_ENABLE "MQTT אפשר" #define D_FRIENDLY_NAME "שם ידידותי" @@ -442,6 +447,8 @@ #define D_KNX_ENHANCEMENT "שיפור התקשורת" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "צריכה יומית" @@ -482,6 +489,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #define D_PARTICALS_BEYOND "חלקיקים" +// xsns_27_apds9960.ino +#define D_GESTURE "Gesture" +#define D_COLOR_RED "Red" +#define D_COLOR_GREEN "Green" +#define D_COLOR_BLUE "Blue" +#define D_CCT "CCT" +#define D_PROXIMITY "Proximity" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Accel. X-Axis" #define D_AY_AXIS "Accel. Y-Axis" @@ -567,7 +582,8 @@ #define D_SENSOR_SPI_MOSI "SPI MOSI" #define D_SENSOR_SPI_CLK "SPI CLK" #define D_SENSOR_BACKLIGHT "Backlight" -#define D_SENSOR_PMS5003 "PMS5003" +#define D_SENSOR_PMS5003_TX "PMS5003 Tx" +#define D_SENSOR_PMS5003_RX "PMS5003 Rx" #define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" #define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" #define D_SENSOR_HPMA_RX "HPMA Rx" @@ -651,28 +667,56 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" +#define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" +#define D_GPIO_WEBCAM_PWDN "CAM_PWDN" +#define D_GPIO_WEBCAM_RESET "CAM_RESET" +#define D_GPIO_WEBCAM_XCLK "CAM_XCLK" +#define D_GPIO_WEBCAM_SIOD "CAM_SIOD" +#define D_GPIO_WEBCAM_SIOC "CAM_SIOC" +#define D_GPIO_WEBCAM_DATA "CAM_DATA" +#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC" +#define D_GPIO_WEBCAM_HREF "CAM_HREF" +#define D_GPIO_WEBCAM_PCLK "CAM_PCLK" +#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" +#define D_GPIO_WEBCAM_HSD "CAM_HSD" +#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "A" +#define D_UNIT_CELSIUS "C" #define D_UNIT_CENTIMETER "cm" +#define D_UNIT_DEGREE "°" +#define D_UNIT_FAHRENHEIT "F" #define D_UNIT_HERTZ "Hz" #define D_UNIT_HOUR "h" #define D_UNIT_GALLONS "gal" #define D_UNIT_GALLONS_PER_MIN "g/m" #define D_UNIT_INCREMENTS "inc" +#define D_UNIT_KELVIN "K" +#define D_UNIT_KILOMETER "km" #define D_UNIT_KILOGRAM "kg" #define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" #define D_UNIT_KILOOHM "kΩ" @@ -689,6 +733,7 @@ #define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_MILLION "ppm" +#define D_UNIT_PERCENT "%%" #define D_UNIT_PRESSURE "hPa" #define D_UNIT_SECOND "sec" #define D_UNIT_SECTORS "sectors" @@ -747,4 +792,31 @@ #define D_SCRIPT_UPLOAD "Upload" #define D_SCRIPT_UPLOAD_FILES "Upload files" +//xsns_67_as3935.ino +#define D_AS3935_GAIN "gain:" +#define D_AS3935_ENERGY "energy:" +#define D_AS3935_DISTANCE "distance:" +#define D_AS3935_DISTURBER "disturber:" +#define D_AS3935_VRMS "µVrms:" +#define D_AS3935_APRX "aprx.:" +#define D_AS3935_AWAY "away" +#define D_AS3935_LIGHT "lightning" +#define D_AS3935_OUT "lightning out of range" +#define D_AS3935_NOT "distance not determined" +#define D_AS3935_ABOVE "lightning overhead" +#define D_AS3935_NOISE "noise detected" +#define D_AS3935_DISTDET "disturber detected" +#define D_AS3935_INTNOEV "Interrupt with no Event!" +#define D_AS3935_NOMESS "listening..." +#define D_AS3935_ON "On" +#define D_AS3935_OFF "Off" +#define D_AS3935_INDOORS "Indoors" +#define D_AS3935_OUTDOORS "Outdoors" +#define D_AS3935_CAL_FAIL "calibration failed" +#define D_AS3935_CAL_OK "calibration set to:" + +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_HE_HE_H_ diff --git a/tasmota/language/hu-HU.h b/tasmota/language/hu_HU.h similarity index 91% rename from tasmota/language/hu-HU.h rename to tasmota/language/hu_HU.h index 34ea7e8a6..1df3e0a4e 100644 --- a/tasmota/language/hu-HU.h +++ b/tasmota/language/hu_HU.h @@ -56,6 +56,7 @@ #define D_AP "AP" // Access Point #define D_AS "mint" #define D_AUTO "AUTO" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "Villogás" #define D_BLINKOFF "Villogás ki" #define D_BOOT_COUNT "Újraindulások száma" @@ -98,6 +99,8 @@ #define D_FILE "Fájl" #define D_FLOW_RATE "Flow rate" #define D_FREE_MEMORY "Szabad memória" +#define D_PSR_MAX_MEMORY "PS-RAM Memory" +#define D_PSR_FREE_MEMORY "PS-RAM free Memory" #define D_FREQUENCY "Frekvencia" #define D_GAS "Gáz" #define D_GATEWAY "Átjáró" @@ -114,6 +117,7 @@ #define D_IP_ADDRESS "IP cím" #define D_LIGHT "Fény" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "Modul" #define D_MOISTURE "Moisture" #define D_MQTT "MQTT" @@ -300,6 +304,7 @@ #define D_OTHER_PARAMETERS "Egyéb beállítások" #define D_TEMPLATE "Template" #define D_ACTIVATE "Activate" +#define D_DEVICE_NAME "Device Name" #define D_WEB_ADMIN_PASSWORD "Web admin jelszó" #define D_MQTT_ENABLE "MQTT engedélyezése" #define D_FRIENDLY_NAME "Név" @@ -442,6 +447,8 @@ #define D_KNX_ENHANCEMENT "Communication Enhancement" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Mai energia" @@ -482,6 +489,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #define D_PARTICALS_BEYOND "Részecskék" +// xsns_27_apds9960.ino +#define D_GESTURE "Gesztus" +#define D_COLOR_RED "Red" +#define D_COLOR_GREEN "Green" +#define D_COLOR_BLUE "Blue" +#define D_CCT "CCT" +#define D_PROXIMITY "közelség" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Gyorsulásm. X-tengely" #define D_AY_AXIS "Gyorsulásm. Y-tengely" @@ -567,7 +582,8 @@ #define D_SENSOR_SPI_MOSI "SPI MOSI" #define D_SENSOR_SPI_CLK "SPI CLK" #define D_SENSOR_BACKLIGHT "Háttérfény" -#define D_SENSOR_PMS5003 "PMS5003" +#define D_SENSOR_PMS5003_TX "PMS5003 Tx" +#define D_SENSOR_PMS5003_RX "PMS5003 Rx" #define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" #define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" #define D_SENSOR_HPMA_RX "HPMA Rx" @@ -651,28 +667,56 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" +#define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" +#define D_GPIO_WEBCAM_PWDN "CAM_PWDN" +#define D_GPIO_WEBCAM_RESET "CAM_RESET" +#define D_GPIO_WEBCAM_XCLK "CAM_XCLK" +#define D_GPIO_WEBCAM_SIOD "CAM_SIOD" +#define D_GPIO_WEBCAM_SIOC "CAM_SIOC" +#define D_GPIO_WEBCAM_DATA "CAM_DATA" +#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC" +#define D_GPIO_WEBCAM_HREF "CAM_HREF" +#define D_GPIO_WEBCAM_PCLK "CAM_PCLK" +#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" +#define D_GPIO_WEBCAM_HSD "CAM_HSD" +#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "A" +#define D_UNIT_CELSIUS "C" #define D_UNIT_CENTIMETER "cm" +#define D_UNIT_DEGREE "°" +#define D_UNIT_FAHRENHEIT "F" #define D_UNIT_HERTZ "Hz" #define D_UNIT_HOUR "h" #define D_UNIT_GALLONS "gal" #define D_UNIT_GALLONS_PER_MIN "g/m" #define D_UNIT_INCREMENTS "inc" +#define D_UNIT_KELVIN "K" +#define D_UNIT_KILOMETER "km" #define D_UNIT_KILOGRAM "kg" #define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" #define D_UNIT_KILOOHM "kΩ" @@ -689,6 +733,7 @@ #define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_MILLION "ppm" +#define D_UNIT_PERCENT "%%" #define D_UNIT_PRESSURE "hPa" #define D_UNIT_SECOND "s" #define D_UNIT_SECTORS "szektorok" @@ -747,4 +792,31 @@ #define D_SCRIPT_UPLOAD "Upload" #define D_SCRIPT_UPLOAD_FILES "Upload files" +//xsns_67_as3935.ino +#define D_AS3935_GAIN "gain:" +#define D_AS3935_ENERGY "energy:" +#define D_AS3935_DISTANCE "distance:" +#define D_AS3935_DISTURBER "disturber:" +#define D_AS3935_VRMS "µVrms:" +#define D_AS3935_APRX "aprx.:" +#define D_AS3935_AWAY "away" +#define D_AS3935_LIGHT "lightning" +#define D_AS3935_OUT "lightning out of range" +#define D_AS3935_NOT "distance not determined" +#define D_AS3935_ABOVE "lightning overhead" +#define D_AS3935_NOISE "noise detected" +#define D_AS3935_DISTDET "disturber detected" +#define D_AS3935_INTNOEV "Interrupt with no Event!" +#define D_AS3935_NOMESS "listening..." +#define D_AS3935_ON "On" +#define D_AS3935_OFF "Off" +#define D_AS3935_INDOORS "Indoors" +#define D_AS3935_OUTDOORS "Outdoors" +#define D_AS3935_CAL_FAIL "calibration failed" +#define D_AS3935_CAL_OK "calibration set to:" + +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_HU_HU_H_ diff --git a/tasmota/language/it-IT.h b/tasmota/language/it_IT.h similarity index 85% rename from tasmota/language/it-IT.h rename to tasmota/language/it_IT.h index 151bda319..3623f861b 100644 --- a/tasmota/language/it-IT.h +++ b/tasmota/language/it_IT.h @@ -56,13 +56,14 @@ #define D_AP "AP" // Access Point #define D_AS "come" #define D_AUTO "AUTO" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "Lampeggia" #define D_BLINKOFF "Lampeggia OFF" -#define D_BOOT_COUNT "Numero di boot" +#define D_BOOT_COUNT "Numero boot" #define D_BRIGHTLIGHT "Luminoso" #define D_BSSID "BSSId" #define D_BUTTON "Pulsante" -#define D_BY "da" // Written by me +#define D_BY "di" // Written by me #define D_BYTES "Byte" #define D_CELSIUS "Celsius" #define D_CHANNEL "Canale" @@ -80,13 +81,13 @@ #define D_DARKLIGHT "Scuro" #define D_DEBUG "Debug" #define D_DEWPOINT "Punto rugiada" // -#define D_DISABLED "Disabilitato" +#define D_DISABLED "Disabilitato/a" #define D_DISTANCE "Distanza" #define D_DNS_SERVER "Server DNS" #define D_DONE "Completato" #define D_DST_TIME "DST" #define D_ECO2 "eCO₂" -#define D_EMULATION "Emulazione" +#define D_EMULATION "Tipo emulazione" #define D_ENABLED "Abilitato" #define D_ERASE "Cancella" #define D_ERROR "Errore" @@ -97,7 +98,9 @@ #define D_FALSE "Falso" #define D_FILE "File" #define D_FLOW_RATE "Flusso dati" -#define D_FREE_MEMORY "Memoria Libera" +#define D_FREE_MEMORY "Memoria libera" +#define D_PSR_MAX_MEMORY "PS-RAM - Memoria" +#define D_PSR_FREE_MEMORY "PS-RAM - Memoria libera" #define D_FREQUENCY "Frequenza" #define D_GAS "Gas" #define D_GATEWAY "Gateway" @@ -114,6 +117,7 @@ #define D_IP_ADDRESS "Indirizzo IP" #define D_LIGHT "Luce" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "Modulo" #define D_MOISTURE "Umidità" #define D_MQTT "MQTT" @@ -134,13 +138,13 @@ #define D_POWERUSAGE_REACTIVE "Potenza reattiva" #define D_PRESSURE "Pressione" #define D_PRESSUREATSEALEVEL "Pressione al livello del mare" -#define D_PROGRAM_FLASH_SIZE "Dimensione flash programma" +#define D_PROGRAM_FLASH_SIZE "Dimensione flash" #define D_PROGRAM_SIZE "Dimensione programma" #define D_PROJECT "Progetto" #define D_RAIN "Pioggia" #define D_RANGE "Intervallo" #define D_RECEIVED "Ricevuto" -#define D_RESTART "Riavvio" +#define D_RESTART "Riavvia" #define D_RESTARTING "Riavvio" #define D_RESTART_REASON "Causa riavvio" #define D_RESTORE "ripristino" @@ -149,7 +153,7 @@ #define D_SAVE "Salva" #define D_SENSOR "Sensore" #define D_SSID "SSID" -#define D_START "Avvia" +#define D_START "Esegui" #define D_STD_TIME "STD" #define D_STOP "Stop" #define D_SUBNET_MASK "Maschera sottorete" @@ -166,8 +170,8 @@ #define D_TRANSMIT "Trasmesso" #define D_TRUE "Vero" #define D_TVOC "TVOC" -#define D_UPGRADE "Aggiorna" -#define D_UPLOAD "Invio" +#define D_UPGRADE "aggiornamento" +#define D_UPLOAD "Caricamento" #define D_UPTIME "Tempo accensione" #define D_USER "Utente" #define D_UTC_TIME "UTC" @@ -233,8 +237,8 @@ #define D_WEBSERVER_STOPPED "Server web arrestato" #define D_FILE_NOT_FOUND "File non trovato" #define D_REDIRECTED "Redirezione al captive portal" -#define D_WIFIMANAGER_SET_ACCESSPOINT_AND_STATION "Impostazione Wifimanager come AccessPoint e Station" -#define D_WIFIMANAGER_SET_ACCESSPOINT "Impostazione Wifimanager come AccessPoint" +#define D_WIFIMANAGER_SET_ACCESSPOINT_AND_STATION "Impostazione Wifimanager come Access Point e Station" +#define D_WIFIMANAGER_SET_ACCESSPOINT "Impostazione Wifimanager come Access Point" #define D_TRYING_TO_CONNECT "Tentativo connessione dispositivo alla rete" #define D_RESTART_IN "Riavvio tra" @@ -243,7 +247,7 @@ #define D_BUTTON_TOGGLE "ON/OFF" #define D_CONFIGURATION "Configurazione" #define D_INFORMATION "Informazioni" -#define D_FIRMWARE_UPGRADE "Aggiornamento firmware" +#define D_FIRMWARE_UPGRADE "Aggiorna firmware" #define D_CONSOLE "Console" #define D_CONFIRM_RESTART "Conferma riavvio" @@ -251,8 +255,8 @@ #define D_CONFIGURE_WIFI "Configura WiFi" #define D_CONFIGURE_MQTT "Configura MQTT" #define D_CONFIGURE_DOMOTICZ "Configura Domoticz" -#define D_CONFIGURE_LOGGING "Configura registrazione" -#define D_CONFIGURE_OTHER "Configura extra" +#define D_CONFIGURE_LOGGING "Livello registro" +#define D_CONFIGURE_OTHER "Altre impostazioni" #define D_CONFIRM_RESET_CONFIGURATION "Conferma ripristino configurazione" #define D_RESET_CONFIGURATION "Ripristino configurazione" #define D_BACKUP_CONFIGURATION "Backup configurazione" @@ -272,7 +276,7 @@ #define D_SCAN_DONE "Scansione completata" #define D_NO_NETWORKS_FOUND "Nessuna rete trovata" #define D_REFRESH_TO_SCAN_AGAIN "Aggiorna per nuova scansione" -#define D_DUPLICATE_ACCESSPOINT "AccessPoint duplicato" +#define D_DUPLICATE_ACCESSPOINT "Access Point duplicato" #define D_SKIPPING_LOW_QUALITY "Ignorato a causa di bassa qualità" #define D_RSSI "RSSI" #define D_WEP "WEP" @@ -285,21 +289,22 @@ #define D_MQTT_PARAMETERS "Parametri MQTT" #define D_CLIENT "Client" -#define D_FULL_TOPIC "Full Topic" +#define D_FULL_TOPIC "Full topic" -#define D_LOGGING_PARAMETERS "Parametri registrazione" -#define D_SERIAL_LOG_LEVEL "Livello registrazione seriale" -#define D_MQTT_LOG_LEVEL "Livello registrazione MQTT" -#define D_WEB_LOG_LEVEL "Livello registrazione web" -#define D_SYS_LOG_LEVEL "Livello registrazione Sys" +#define D_LOGGING_PARAMETERS "Livelli registro eventi" +#define D_SERIAL_LOG_LEVEL "Livello registro seriale" +#define D_MQTT_LOG_LEVEL "Livello registro MQTT" +#define D_WEB_LOG_LEVEL "Livello registro web" +#define D_SYS_LOG_LEVEL "Livello registro Sys" #define D_MORE_DEBUG "Debug aggiuntivo" #define D_SYSLOG_HOST "Host Syslog" #define D_SYSLOG_PORT "Porta Syslog" -#define D_TELEMETRY_PERIOD "Periodo Telemetria" +#define D_TELEMETRY_PERIOD "Periodo telemetria" #define D_OTHER_PARAMETERS "Altri parametri" #define D_TEMPLATE "Modello" #define D_ACTIVATE "Attiva" +#define D_DEVICE_NAME "Nome dispositivo" #define D_WEB_ADMIN_PASSWORD "Password amministratore web" #define D_MQTT_ENABLE "Abilita MQTT" #define D_FRIENDLY_NAME "Nome amichevole" @@ -319,9 +324,9 @@ #define D_CONFIGURATION_RESET "Configurazione ripristinata" #define D_PROGRAM_VERSION "Versione programma" -#define D_BUILD_DATE_AND_TIME "Data e ora compilazione" +#define D_BUILD_DATE_AND_TIME "Data/ora compilazione" #define D_CORE_AND_SDK_VERSION "Versione core/SDK" -#define D_FLASH_WRITE_COUNT "Contatore scritture flash" +#define D_FLASH_WRITE_COUNT "Numero scritture flash" #define D_MAC_ADDRESS "Indirizzo MAC" #define D_MQTT_HOST "Host MQTT" #define D_MQTT_PORT "Porta MQTT" @@ -335,15 +340,15 @@ #define D_ESP_CHIP_ID "ID chip ESP" #define D_FLASH_CHIP_ID "ID chip flash" #define D_FLASH_CHIP_SIZE "Dimensione flash" -#define D_FREE_PROGRAM_SPACE "Spazio libero memoria programma" +#define D_FREE_PROGRAM_SPACE "Memoria libera programma" #define D_UPGRADE_BY_WEBSERVER "Aggiornamento via server web" -#define D_OTA_URL "OTA URL" -#define D_START_UPGRADE "Avvio aggiornamento" -#define D_UPGRADE_BY_FILE_UPLOAD "Aggiornamento tramite upload file" -#define D_UPLOAD_STARTED "Upload iniziato" -#define D_UPGRADE_STARTED "Aggiornamento avviato" -#define D_UPLOAD_DONE "Upload completato" +#define D_OTA_URL "URL OTA" +#define D_START_UPGRADE "Esegui aggiornamento" +#define D_UPGRADE_BY_FILE_UPLOAD "Aggiornamento tramite file locale" +#define D_UPLOAD_STARTED "Caricamento..." +#define D_UPGRADE_STARTED "Aggiornamento..." +#define D_UPLOAD_DONE "Caricamento completato" #define D_UPLOAD_ERR_1 "Nessun file selezionato" #define D_UPLOAD_ERR_2 "Spazio insufficiente" #define D_UPLOAD_ERR_3 "Magic byte non corrispondente a 0xE9" @@ -395,9 +400,9 @@ // xdrv_07_domoticz.ino #define D_DOMOTICZ_PARAMETERS "Parametri Domoticz" #define D_DOMOTICZ_IDX "Idx" -#define D_DOMOTICZ_KEY_IDX "Idx chiave" -#define D_DOMOTICZ_SWITCH_IDX "Idx switch" -#define D_DOMOTICZ_SENSOR_IDX "Idx sensore" +#define D_DOMOTICZ_KEY_IDX "Idx - chiave" +#define D_DOMOTICZ_SWITCH_IDX "Idx - switch" +#define D_DOMOTICZ_SENSOR_IDX "Idx - sensore" #define D_DOMOTICZ_TEMP "Temp" #define D_DOMOTICZ_TEMP_HUM "Temp,Umd" #define D_DOMOTICZ_TEMP_HUM_BARO "Temp,Umd,Baro" @@ -406,7 +411,7 @@ #define D_DOMOTICZ_COUNT "Cont/PM1" #define D_DOMOTICZ_VOLTAGE "Tensione/PM2.5" #define D_DOMOTICZ_CURRENT "Corrente/PM10" - #define D_DOMOTICZ_AIRQUALITY "QualitàAria" + #define D_DOMOTICZ_AIRQUALITY "Qualità aria" #define D_DOMOTICZ_P1_SMART_METER "P1SmartMeter" #define D_DOMOTICZ_UPDATE_TIMER "Intervallo aggiornamento" @@ -442,6 +447,8 @@ #define D_KNX_ENHANCEMENT "Miglioramento comunicazione" #define D_KNX_TX_SLOT "KNX - TX" #define D_KNX_RX_SLOT "KNX - RX" +#define D_KNX_TX_SCENE "Scena - TX" +#define D_KNX_RX_SCENE "Scena - RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Energia - oggi" @@ -482,6 +489,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #define D_PARTICALS_BEYOND "Particelle" +// xsns_27_apds9960.ino +#define D_GESTURE "Gesto" +#define D_COLOR_RED "Rosso" +#define D_COLOR_GREEN "Verde" +#define D_COLOR_BLUE "Blu" +#define D_CCT "CCT" +#define D_PROXIMITY "Vicinanza" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Accelerazione asse X" #define D_AY_AXIS "Accelerazione asse Y" @@ -567,7 +582,8 @@ #define D_SENSOR_SPI_MOSI "SPI - MOSI" #define D_SENSOR_SPI_CLK "SPI - CLK" #define D_SENSOR_BACKLIGHT "Retroilluminazione" -#define D_SENSOR_PMS5003 "PMS5003" +#define D_SENSOR_PMS5003_TX "PMS5003 - TX" +#define D_SENSOR_PMS5003_RX "PMS5003 - RX" #define D_SENSOR_SDS0X1_RX "SDS0X1 - RX" #define D_SENSOR_SDS0X1_TX "SDS0X1 - TX" #define D_SENSOR_HPMA_RX "HPMA - RX" @@ -651,28 +667,56 @@ #define D_SENSOR_SM2135_DAT "SM2135 - DATI" #define D_SENSOR_DEEPSLEEP "Deep sleep" #define D_SENSOR_EXS_ENABLE "EXS - Abilita" -#define D_SENSOR_SLAVE_TX "Slave - TX" -#define D_SENSOR_SLAVE_RX "Slave - RX" -#define D_SENSOR_SLAVE_RESET "Slave - RST" +#define D_SENSOR_CLIENT_TX "Client - TX" +#define D_SENSOR_CLIENT_RX "Client - RX" +#define D_SENSOR_CLIENT_RESET "Client - RST" #define D_SENSOR_GPS_RX "GPS - RX" #define D_SENSOR_GPS_TX "GPS - TX" #define D_SENSOR_HM10_RX "HM10 - RX" #define D_SENSOR_HM10_TX "HM10 - TX" #define D_SENSOR_LE01MR_RX "LE-01MR - RX" #define D_SENSOR_LE01MR_TX "LE-01MR - TX" +#define D_SENSOR_BL0940_RX "BL0940 - RX" #define D_SENSOR_CC1101_GDO0 "CC1101 - GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 - GDO2" #define D_SENSOR_HRXL_RX "HRXL - RX" #define D_SENSOR_ELECTRIQ_MOODL "MOODL - TX" +#define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "Velocità vento" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" +#define D_GPIO_WEBCAM_PWDN "CAM_PWDN" +#define D_GPIO_WEBCAM_RESET "CAM_RESET" +#define D_GPIO_WEBCAM_XCLK "CAM_XCLK" +#define D_GPIO_WEBCAM_SIOD "CAM_SIOD" +#define D_GPIO_WEBCAM_SIOC "CAM_SIOC" +#define D_GPIO_WEBCAM_DATA "CAM_DATA" +#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC" +#define D_GPIO_WEBCAM_HREF "CAM_HREF" +#define D_GPIO_WEBCAM_PCLK "CAM_PCLK" +#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" +#define D_GPIO_WEBCAM_HSD "CAM_HSD" +#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" +#define D_SENSOR_TCP_TXD "TCP - TX" +#define D_SENSOR_TCP_RXD "TCP - RX" // Units #define D_UNIT_AMPERE "A" +#define D_UNIT_CELSIUS "C" #define D_UNIT_CENTIMETER "cm" +#define D_UNIT_DEGREE "°" +#define D_UNIT_FAHRENHEIT "F" #define D_UNIT_HERTZ "Hz" #define D_UNIT_HOUR "o" #define D_UNIT_GALLONS "gal" #define D_UNIT_GALLONS_PER_MIN "g/m" #define D_UNIT_INCREMENTS "inc" +#define D_UNIT_KELVIN "K" +#define D_UNIT_KILOMETER "km" #define D_UNIT_KILOGRAM "kg" #define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" #define D_UNIT_KILOOHM "kΩ" @@ -689,6 +733,7 @@ #define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_MILLION "ppm" +#define D_UNIT_PERCENT "%%" #define D_UNIT_PRESSURE "hPa" #define D_UNIT_SECOND "sec" #define D_UNIT_SECTORS "settori" @@ -744,7 +789,34 @@ #define D_SCRIPT_CHARS_NO_MORE "nessun altro carattere" #define D_SCRIPT_DOWNLOAD "Download" #define D_SCRIPT_ENABLE "abilita script" -#define D_SCRIPT_UPLOAD "Upload" -#define D_SCRIPT_UPLOAD_FILES "Upload file" +#define D_SCRIPT_UPLOAD "Carica" +#define D_SCRIPT_UPLOAD_FILES "Carica file" + +//xsns_67_as3935.ino +#define D_AS3935_GAIN "guadagno:" +#define D_AS3935_ENERGY "energia:" +#define D_AS3935_DISTANCE "distanza:" +#define D_AS3935_DISTURBER "disturbatore:" +#define D_AS3935_VRMS "µVrms:" +#define D_AS3935_APRX "apross.:" +#define D_AS3935_AWAY "lontano" +#define D_AS3935_LIGHT "illuminazione" +#define D_AS3935_OUT "illuminazione fuori intervallo" +#define D_AS3935_NOT "distanza non determinata" +#define D_AS3935_ABOVE "illuminazione ambientale" +#define D_AS3935_NOISE "rilevato rumore" +#define D_AS3935_DISTDET "rilevato disturbatore" +#define D_AS3935_INTNOEV "Interrupt senza evento!" +#define D_AS3935_NOMESS "in ascolto..." +#define D_AS3935_ON "ON" +#define D_AS3935_OFF "OFF" +#define D_AS3935_INDOORS "Interno" +#define D_AS3935_OUTDOORS "Esterno" +#define D_AS3935_CAL_FAIL "calibrazione fallita" +#define D_AS3935_CAL_OK "calibrazione impostata a:" + +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm - RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm - TX" #endif // _LANGUAGE_IT_IT_H_ diff --git a/tasmota/language/ko-KO.h b/tasmota/language/ko_KO.h similarity index 91% rename from tasmota/language/ko-KO.h rename to tasmota/language/ko_KO.h index 434ae07e5..a26dba20e 100644 --- a/tasmota/language/ko-KO.h +++ b/tasmota/language/ko_KO.h @@ -56,6 +56,7 @@ #define D_AP "AP" // Access Point #define D_AS "as" #define D_AUTO "자동" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "깜박임" #define D_BLINKOFF "깜박임 끄기" #define D_BOOT_COUNT "부팅 횟수" @@ -98,6 +99,8 @@ #define D_FILE "파일" #define D_FLOW_RATE "Flow rate" #define D_FREE_MEMORY "남은 메모리" +#define D_PSR_MAX_MEMORY "PS-RAM Memory" +#define D_PSR_FREE_MEMORY "PS-RAM free Memory" #define D_FREQUENCY "Frequency" #define D_GAS "가스" #define D_GATEWAY "게이트웨이" @@ -114,6 +117,7 @@ #define D_IP_ADDRESS "IP 주소" #define D_LIGHT "밝게" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "모듈" #define D_MOISTURE "Moisture" #define D_MQTT "MQTT" @@ -300,6 +304,7 @@ #define D_OTHER_PARAMETERS "기타 설정" #define D_TEMPLATE "템플릿" #define D_ACTIVATE "활성화" +#define D_DEVICE_NAME "Device Name" #define D_WEB_ADMIN_PASSWORD "Web Admin 비밀번호" #define D_MQTT_ENABLE "MQTT 사용" #define D_FRIENDLY_NAME "Friendly Name" @@ -442,6 +447,8 @@ #define D_KNX_ENHANCEMENT "커뮤니케이션 강화" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "금일 전력 사용량" @@ -482,6 +489,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #define D_PARTICALS_BEYOND "입자" +// xsns_27_apds9960.ino +#define D_GESTURE "Gesture" +#define D_COLOR_RED "Red" +#define D_COLOR_GREEN "Green" +#define D_COLOR_BLUE "Blue" +#define D_CCT "CCT" +#define D_PROXIMITY "Proximity" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Accel. X-Axis" #define D_AY_AXIS "Accel. Y-Axis" @@ -567,7 +582,8 @@ #define D_SENSOR_SPI_MOSI "SPI MOSI" #define D_SENSOR_SPI_CLK "SPI CLK" #define D_SENSOR_BACKLIGHT "Backlight" -#define D_SENSOR_PMS5003 "PMS5003" +#define D_SENSOR_PMS5003_TX "PMS5003 Tx" +#define D_SENSOR_PMS5003_RX "PMS5003 Rx" #define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" #define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" #define D_SENSOR_HPMA_RX "HPMA Rx" @@ -651,28 +667,56 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" +#define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" +#define D_GPIO_WEBCAM_PWDN "CAM_PWDN" +#define D_GPIO_WEBCAM_RESET "CAM_RESET" +#define D_GPIO_WEBCAM_XCLK "CAM_XCLK" +#define D_GPIO_WEBCAM_SIOD "CAM_SIOD" +#define D_GPIO_WEBCAM_SIOC "CAM_SIOC" +#define D_GPIO_WEBCAM_DATA "CAM_DATA" +#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC" +#define D_GPIO_WEBCAM_HREF "CAM_HREF" +#define D_GPIO_WEBCAM_PCLK "CAM_PCLK" +#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" +#define D_GPIO_WEBCAM_HSD "CAM_HSD" +#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "A" +#define D_UNIT_CELSIUS "C" #define D_UNIT_CENTIMETER "cm" +#define D_UNIT_DEGREE "°" +#define D_UNIT_FAHRENHEIT "F" #define D_UNIT_HERTZ "Hz" #define D_UNIT_HOUR "시" #define D_UNIT_GALLONS "gal" #define D_UNIT_GALLONS_PER_MIN "g/m" #define D_UNIT_INCREMENTS "inc" +#define D_UNIT_KELVIN "K" +#define D_UNIT_KILOMETER "km" #define D_UNIT_KILOGRAM "kg" #define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" #define D_UNIT_KILOOHM "kΩ" @@ -689,6 +733,7 @@ #define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_MILLION "ppm" +#define D_UNIT_PERCENT "%%" #define D_UNIT_PRESSURE "hPa" #define D_UNIT_SECOND "초" #define D_UNIT_SECTORS "섹터" @@ -747,4 +792,31 @@ #define D_SCRIPT_UPLOAD "Upload" #define D_SCRIPT_UPLOAD_FILES "Upload files" +//xsns_67_as3935.ino +#define D_AS3935_GAIN "gain:" +#define D_AS3935_ENERGY "energy:" +#define D_AS3935_DISTANCE "distance:" +#define D_AS3935_DISTURBER "disturber:" +#define D_AS3935_VRMS "µVrms:" +#define D_AS3935_APRX "aprx.:" +#define D_AS3935_AWAY "away" +#define D_AS3935_LIGHT "lightning" +#define D_AS3935_OUT "lightning out of range" +#define D_AS3935_NOT "distance not determined" +#define D_AS3935_ABOVE "lightning overhead" +#define D_AS3935_NOISE "noise detected" +#define D_AS3935_DISTDET "disturber detected" +#define D_AS3935_INTNOEV "Interrupt with no Event!" +#define D_AS3935_NOMESS "listening..." +#define D_AS3935_ON "On" +#define D_AS3935_OFF "Off" +#define D_AS3935_INDOORS "Indoors" +#define D_AS3935_OUTDOORS "Outdoors" +#define D_AS3935_CAL_FAIL "calibration failed" +#define D_AS3935_CAL_OK "calibration set to:" + +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_KO_KO_H_ diff --git a/tasmota/language/nl-NL.h b/tasmota/language/nl_NL.h similarity index 90% rename from tasmota/language/nl-NL.h rename to tasmota/language/nl_NL.h index a129c764e..15d5c715b 100644 --- a/tasmota/language/nl-NL.h +++ b/tasmota/language/nl_NL.h @@ -56,6 +56,7 @@ #define D_AP "AP" // Access Point #define D_AS "als" #define D_AUTO "AUTO" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "Knipper" #define D_BLINKOFF "KnipperUit" #define D_BOOT_COUNT "Herstarts" @@ -98,6 +99,8 @@ #define D_FILE "Bestand" #define D_FLOW_RATE "Debiet" #define D_FREE_MEMORY "Vrij geheugen" +#define D_PSR_MAX_MEMORY "PS-RAM Memory" +#define D_PSR_FREE_MEMORY "PS-RAM free Memory" #define D_FREQUENCY "Frequentie" #define D_GAS "Gas" #define D_GATEWAY "Gateway" @@ -114,6 +117,7 @@ #define D_IP_ADDRESS "IP Adres" #define D_LIGHT "Licht" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "Module" #define D_MOISTURE "Moisture" #define D_MQTT "MQTT" @@ -300,6 +304,7 @@ #define D_OTHER_PARAMETERS "Overige parameters" #define D_TEMPLATE "Sjabloon" #define D_ACTIVATE "Activeer" +#define D_DEVICE_NAME "Apparaatnaam" #define D_WEB_ADMIN_PASSWORD "Web Admin Wachtwoord" #define D_MQTT_ENABLE "MQTT ingeschakeld" #define D_FRIENDLY_NAME "Beschrijvende naam" @@ -442,6 +447,8 @@ #define D_KNX_ENHANCEMENT "Verbeter verbinding" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Verbruik vandaag" @@ -482,6 +489,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #define D_PARTICALS_BEYOND "Stofdeeltjes" +// xsns_27_apds9960.ino +#define D_GESTURE "Gesture" +#define D_COLOR_RED "Red" +#define D_COLOR_GREEN "Green" +#define D_COLOR_BLUE "Blue" +#define D_CCT "CCT" +#define D_PROXIMITY "Proximity" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Versn. X-as" #define D_AY_AXIS "Versn. Y-as" @@ -567,7 +582,8 @@ #define D_SENSOR_SPI_MOSI "SPI MOSI" #define D_SENSOR_SPI_CLK "SPI CLK" #define D_SENSOR_BACKLIGHT "Backlight" -#define D_SENSOR_PMS5003 "PMS5003" +#define D_SENSOR_PMS5003_TX "PMS5003 Tx" +#define D_SENSOR_PMS5003_RX "PMS5003 Rx" #define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" #define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" #define D_SENSOR_HPMA_RX "HPMA Rx" @@ -651,28 +667,56 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" +#define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" +#define D_GPIO_WEBCAM_PWDN "CAM_PWDN" +#define D_GPIO_WEBCAM_RESET "CAM_RESET" +#define D_GPIO_WEBCAM_XCLK "CAM_XCLK" +#define D_GPIO_WEBCAM_SIOD "CAM_SIOD" +#define D_GPIO_WEBCAM_SIOC "CAM_SIOC" +#define D_GPIO_WEBCAM_DATA "CAM_DATA" +#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC" +#define D_GPIO_WEBCAM_HREF "CAM_HREF" +#define D_GPIO_WEBCAM_PCLK "CAM_PCLK" +#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" +#define D_GPIO_WEBCAM_HSD "CAM_HSD" +#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "A" +#define D_UNIT_CELSIUS "C" #define D_UNIT_CENTIMETER "cm" +#define D_UNIT_DEGREE "°" +#define D_UNIT_FAHRENHEIT "F" #define D_UNIT_HERTZ "Hz" #define D_UNIT_HOUR "h" #define D_UNIT_GALLONS "gal" #define D_UNIT_GALLONS_PER_MIN "g/m" #define D_UNIT_INCREMENTS "inc" +#define D_UNIT_KELVIN "K" +#define D_UNIT_KILOMETER "km" #define D_UNIT_KILOGRAM "kg" #define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" #define D_UNIT_KILOOHM "kΩ" @@ -689,6 +733,7 @@ #define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_MILLION "ppm" +#define D_UNIT_PERCENT "%%" #define D_UNIT_PRESSURE "hPa" #define D_UNIT_SECOND "sec" #define D_UNIT_SECTORS "sectoren" @@ -747,4 +792,31 @@ #define D_SCRIPT_UPLOAD "Upload" #define D_SCRIPT_UPLOAD_FILES "Upload files" +//xsns_67_as3935.ino +#define D_AS3935_GAIN "gain:" +#define D_AS3935_ENERGY "energy:" +#define D_AS3935_DISTANCE "distance:" +#define D_AS3935_DISTURBER "disturber:" +#define D_AS3935_VRMS "µVrms:" +#define D_AS3935_APRX "aprx.:" +#define D_AS3935_AWAY "away" +#define D_AS3935_LIGHT "lightning" +#define D_AS3935_OUT "lightning out of range" +#define D_AS3935_NOT "distance not determined" +#define D_AS3935_ABOVE "lightning overhead" +#define D_AS3935_NOISE "noise detected" +#define D_AS3935_DISTDET "disturber detected" +#define D_AS3935_INTNOEV "Interrupt with no Event!" +#define D_AS3935_NOMESS "listening..." +#define D_AS3935_ON "On" +#define D_AS3935_OFF "Off" +#define D_AS3935_INDOORS "Indoors" +#define D_AS3935_OUTDOORS "Outdoors" +#define D_AS3935_CAL_FAIL "calibration failed" +#define D_AS3935_CAL_OK "calibration set to:" + +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_NL_NL_H_ diff --git a/tasmota/language/pl-PL.h b/tasmota/language/pl_PL.h similarity index 91% rename from tasmota/language/pl-PL.h rename to tasmota/language/pl_PL.h index 4c9da5559..446660469 100644 --- a/tasmota/language/pl-PL.h +++ b/tasmota/language/pl_PL.h @@ -56,6 +56,7 @@ #define D_AP "AP" // Access Point #define D_AS "jak" #define D_AUTO "AUTO" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "Miganie" #define D_BLINKOFF "Miganie - Wył." #define D_BOOT_COUNT "Licznik restartów" @@ -98,6 +99,8 @@ #define D_FILE "Plik" #define D_FLOW_RATE "Przepływ" #define D_FREE_MEMORY "Wolna pamięć" +#define D_PSR_MAX_MEMORY "PS-RAM Memory" +#define D_PSR_FREE_MEMORY "PS-RAM free Memory" #define D_FREQUENCY "Częstotliwość" #define D_GAS "Gas" #define D_GATEWAY "Brama" @@ -114,6 +117,7 @@ #define D_IP_ADDRESS "Adres IP" #define D_LIGHT "Światło" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "Moduł" #define D_MOISTURE "Wilgotność" #define D_MQTT "MQTT" @@ -300,6 +304,7 @@ #define D_OTHER_PARAMETERS "Inne parametry" #define D_TEMPLATE "Szablon" #define D_ACTIVATE "Aktywuj" +#define D_DEVICE_NAME "Device Name" #define D_WEB_ADMIN_PASSWORD "Hasło administratora" #define D_MQTT_ENABLE "Załącz MQTT" #define D_FRIENDLY_NAME "Nazwa" @@ -442,6 +447,8 @@ #define D_KNX_ENHANCEMENT "Rozszerzenia" #define D_KNX_TX_SLOT "Gniazdo TX" #define D_KNX_RX_SLOT "Gniazdo RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Energia dzisiaj" @@ -482,6 +489,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #define D_PARTICALS_BEYOND "Cząstki" +// xsns_27_apds9960.ino +#define D_GESTURE "Gesture" +#define D_COLOR_RED "Red" +#define D_COLOR_GREEN "Green" +#define D_COLOR_BLUE "Blue" +#define D_CCT "CCT" +#define D_PROXIMITY "Proximity" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Accel. X-Axis" #define D_AY_AXIS "Accel. Y-Axis" @@ -567,7 +582,8 @@ #define D_SENSOR_SPI_MOSI "SPI MOSI" #define D_SENSOR_SPI_CLK "SPI CLK" #define D_SENSOR_BACKLIGHT "Podświetlanie" -#define D_SENSOR_PMS5003 "PMS5003" +#define D_SENSOR_PMS5003_TX "PMS5003 Tx" +#define D_SENSOR_PMS5003_RX "PMS5003 Rx" #define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" #define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" #define D_SENSOR_HPMA_RX "HPMA Rx" @@ -651,28 +667,56 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "Głęboko uśpiony" #define D_SENSOR_EXS_ENABLE "Załącz EXS" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" +#define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" +#define D_GPIO_WEBCAM_PWDN "CAM_PWDN" +#define D_GPIO_WEBCAM_RESET "CAM_RESET" +#define D_GPIO_WEBCAM_XCLK "CAM_XCLK" +#define D_GPIO_WEBCAM_SIOD "CAM_SIOD" +#define D_GPIO_WEBCAM_SIOC "CAM_SIOC" +#define D_GPIO_WEBCAM_DATA "CAM_DATA" +#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC" +#define D_GPIO_WEBCAM_HREF "CAM_HREF" +#define D_GPIO_WEBCAM_PCLK "CAM_PCLK" +#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" +#define D_GPIO_WEBCAM_HSD "CAM_HSD" +#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "A" +#define D_UNIT_CELSIUS "C" #define D_UNIT_CENTIMETER "cm" +#define D_UNIT_DEGREE "°" +#define D_UNIT_FAHRENHEIT "F" #define D_UNIT_HERTZ "Hz" #define D_UNIT_HOUR "Godz" #define D_UNIT_GALLONS "gal" #define D_UNIT_GALLONS_PER_MIN "g/m" #define D_UNIT_INCREMENTS "inc" +#define D_UNIT_KELVIN "K" +#define D_UNIT_KILOMETER "km" #define D_UNIT_KILOGRAM "kg" #define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" #define D_UNIT_KILOOHM "kΩ" @@ -689,6 +733,7 @@ #define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_MILLION "ppm" +#define D_UNIT_PERCENT "%%" #define D_UNIT_PRESSURE "hPa" #define D_UNIT_SECOND "sec" #define D_UNIT_SECTORS "sektory" @@ -747,4 +792,31 @@ #define D_SCRIPT_UPLOAD "Upload" #define D_SCRIPT_UPLOAD_FILES "Upload files" +//xsns_67_as3935.ino +#define D_AS3935_GAIN "gain:" +#define D_AS3935_ENERGY "energy:" +#define D_AS3935_DISTANCE "distance:" +#define D_AS3935_DISTURBER "disturber:" +#define D_AS3935_VRMS "µVrms:" +#define D_AS3935_APRX "aprx.:" +#define D_AS3935_AWAY "away" +#define D_AS3935_LIGHT "lightning" +#define D_AS3935_OUT "lightning out of range" +#define D_AS3935_NOT "distance not determined" +#define D_AS3935_ABOVE "lightning overhead" +#define D_AS3935_NOISE "noise detected" +#define D_AS3935_DISTDET "disturber detected" +#define D_AS3935_INTNOEV "Interrupt with no Event!" +#define D_AS3935_NOMESS "listening..." +#define D_AS3935_ON "On" +#define D_AS3935_OFF "Off" +#define D_AS3935_INDOORS "Indoors" +#define D_AS3935_OUTDOORS "Outdoors" +#define D_AS3935_CAL_FAIL "calibration failed" +#define D_AS3935_CAL_OK "calibration set to:" + +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_PL_PL_D_H_ diff --git a/tasmota/language/pt-BR.h b/tasmota/language/pt_BR.h similarity index 91% rename from tasmota/language/pt-BR.h rename to tasmota/language/pt_BR.h index 6ce132cb1..56c5811e6 100644 --- a/tasmota/language/pt-BR.h +++ b/tasmota/language/pt_BR.h @@ -56,6 +56,7 @@ #define D_AP "Ponto de acesso" // Ponto de Acesso #define D_AS "como" #define D_AUTO "Auto" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "Pulsar" #define D_BLINKOFF "Pulsar desligado" #define D_BOOT_COUNT "Contagem de inicialização" @@ -98,6 +99,8 @@ #define D_FILE "Arquivo" #define D_FLOW_RATE "Quociente de vazão" #define D_FREE_MEMORY "Memória livre" +#define D_PSR_MAX_MEMORY "PS-RAM Memory" +#define D_PSR_FREE_MEMORY "PS-RAM free Memory" #define D_FREQUENCY "Frequência" #define D_GAS "Gás" #define D_GATEWAY "Gateway" @@ -114,6 +117,7 @@ #define D_IP_ADDRESS "Endereço IP" #define D_LIGHT "Luz" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "Módulo" #define D_MOISTURE "Umidade" #define D_MQTT "MQTT" @@ -300,6 +304,7 @@ #define D_OTHER_PARAMETERS "Outros parâmetros" #define D_TEMPLATE "Modelo" #define D_ACTIVATE "Activate" +#define D_DEVICE_NAME "Device Name" #define D_WEB_ADMIN_PASSWORD "Senha de WEB Admin" #define D_MQTT_ENABLE "MQTT habilitado" #define D_FRIENDLY_NAME "Nome amigável" @@ -442,6 +447,8 @@ #define D_KNX_ENHANCEMENT "Melhoria da comunicação" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Consumo energético de hoje" @@ -482,6 +489,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #define D_PARTICALS_BEYOND "Partículas" +// xsns_27_apds9960.ino +#define D_GESTURE "Gesture" +#define D_COLOR_RED "Red" +#define D_COLOR_GREEN "Green" +#define D_COLOR_BLUE "Blue" +#define D_CCT "CCT" +#define D_PROXIMITY "Proximity" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Accel. X-Axis" #define D_AY_AXIS "Accel. Y-Axis" @@ -567,7 +582,8 @@ #define D_SENSOR_SPI_MOSI "SPI MOSI" #define D_SENSOR_SPI_CLK "SPI CLK" #define D_SENSOR_BACKLIGHT "Luz de fundo" -#define D_SENSOR_PMS5003 "PMS5003" +#define D_SENSOR_PMS5003_TX "PMS5003 Tx" +#define D_SENSOR_PMS5003_RX "PMS5003 Rx" #define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" #define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" #define D_SENSOR_HPMA_RX "HPMA Rx" @@ -651,28 +667,56 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" +#define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" +#define D_GPIO_WEBCAM_PWDN "CAM_PWDN" +#define D_GPIO_WEBCAM_RESET "CAM_RESET" +#define D_GPIO_WEBCAM_XCLK "CAM_XCLK" +#define D_GPIO_WEBCAM_SIOD "CAM_SIOD" +#define D_GPIO_WEBCAM_SIOC "CAM_SIOC" +#define D_GPIO_WEBCAM_DATA "CAM_DATA" +#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC" +#define D_GPIO_WEBCAM_HREF "CAM_HREF" +#define D_GPIO_WEBCAM_PCLK "CAM_PCLK" +#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" +#define D_GPIO_WEBCAM_HSD "CAM_HSD" +#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "A" +#define D_UNIT_CELSIUS "C" #define D_UNIT_CENTIMETER "cm" +#define D_UNIT_DEGREE "°" +#define D_UNIT_FAHRENHEIT "F" #define D_UNIT_HERTZ "Hz" #define D_UNIT_HOUR "H" #define D_UNIT_GALLONS "gal" #define D_UNIT_GALLONS_PER_MIN "g/m" #define D_UNIT_INCREMENTS "inc" +#define D_UNIT_KELVIN "K" +#define D_UNIT_KILOMETER "km" #define D_UNIT_KILOGRAM "kg" #define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" #define D_UNIT_KILOOHM "kΩ" @@ -689,6 +733,7 @@ #define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_MILLION "ppm" +#define D_UNIT_PERCENT "%%" #define D_UNIT_PRESSURE "hPa" #define D_UNIT_SECOND "s" #define D_UNIT_SECTORS "setores" @@ -747,4 +792,31 @@ #define D_SCRIPT_UPLOAD "Upload" #define D_SCRIPT_UPLOAD_FILES "Upload files" +//xsns_67_as3935.ino +#define D_AS3935_GAIN "gain:" +#define D_AS3935_ENERGY "energy:" +#define D_AS3935_DISTANCE "distance:" +#define D_AS3935_DISTURBER "disturber:" +#define D_AS3935_VRMS "µVrms:" +#define D_AS3935_APRX "aprx.:" +#define D_AS3935_AWAY "away" +#define D_AS3935_LIGHT "lightning" +#define D_AS3935_OUT "lightning out of range" +#define D_AS3935_NOT "distance not determined" +#define D_AS3935_ABOVE "lightning overhead" +#define D_AS3935_NOISE "noise detected" +#define D_AS3935_DISTDET "disturber detected" +#define D_AS3935_INTNOEV "Interrupt with no Event!" +#define D_AS3935_NOMESS "listening..." +#define D_AS3935_ON "On" +#define D_AS3935_OFF "Off" +#define D_AS3935_INDOORS "Indoors" +#define D_AS3935_OUTDOORS "Outdoors" +#define D_AS3935_CAL_FAIL "calibration failed" +#define D_AS3935_CAL_OK "calibration set to:" + +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_PT_BR_H_ diff --git a/tasmota/language/pt-PT.h b/tasmota/language/pt_PT.h similarity index 91% rename from tasmota/language/pt-PT.h rename to tasmota/language/pt_PT.h index f87c0db4c..930ac2b1b 100644 --- a/tasmota/language/pt-PT.h +++ b/tasmota/language/pt_PT.h @@ -56,6 +56,7 @@ #define D_AP "AP" // Ponto de Acesso #define D_AS "como" #define D_AUTO "AUTO" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "Piscar" #define D_BLINKOFF "Piscar Desligado" #define D_BOOT_COUNT "Contagem de Inicialização" @@ -98,6 +99,8 @@ #define D_FILE "Ficheiro" #define D_FLOW_RATE "Taxa de Fluxo" #define D_FREE_MEMORY "Memoria Livre" +#define D_PSR_MAX_MEMORY "PS-RAM Memory" +#define D_PSR_FREE_MEMORY "PS-RAM free Memory" #define D_FREQUENCY "Frequência" #define D_GAS "Gás" #define D_GATEWAY "Gateway" @@ -114,6 +117,7 @@ #define D_IP_ADDRESS "Endereço IP" #define D_LIGHT "Luz" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "Módulo" #define D_MOISTURE "Moisture" #define D_MQTT "MQTT" @@ -300,6 +304,7 @@ #define D_OTHER_PARAMETERS "Outros parametros" #define D_TEMPLATE "Modelo" #define D_ACTIVATE "Ativar" +#define D_DEVICE_NAME "Device Name" #define D_WEB_ADMIN_PASSWORD "Palavra Chave do Admin WEB" #define D_MQTT_ENABLE "MQTT habilitado" #define D_FRIENDLY_NAME "Nome amigável" @@ -442,6 +447,8 @@ #define D_KNX_ENHANCEMENT "Melhoria de Comunicação" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Consumo energético de hoje" @@ -482,6 +489,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #define D_PARTICALS_BEYOND "Partículas" +// xsns_27_apds9960.ino +#define D_GESTURE "Gesture" +#define D_COLOR_RED "Red" +#define D_COLOR_GREEN "Green" +#define D_COLOR_BLUE "Blue" +#define D_CCT "CCT" +#define D_PROXIMITY "Proximity" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Accel. X-Axis" #define D_AY_AXIS "Accel. Y-Axis" @@ -567,7 +582,8 @@ #define D_SENSOR_SPI_MOSI "SPI MOSI" #define D_SENSOR_SPI_CLK "SPI CLK" #define D_SENSOR_BACKLIGHT "Luz fundo" -#define D_SENSOR_PMS5003 "PMS5003" +#define D_SENSOR_PMS5003_TX "PMS5003 Tx" +#define D_SENSOR_PMS5003_RX "PMS5003 Rx" #define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" #define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" #define D_SENSOR_HPMA_RX "HPMA Rx" @@ -651,28 +667,56 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" +#define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" +#define D_GPIO_WEBCAM_PWDN "CAM_PWDN" +#define D_GPIO_WEBCAM_RESET "CAM_RESET" +#define D_GPIO_WEBCAM_XCLK "CAM_XCLK" +#define D_GPIO_WEBCAM_SIOD "CAM_SIOD" +#define D_GPIO_WEBCAM_SIOC "CAM_SIOC" +#define D_GPIO_WEBCAM_DATA "CAM_DATA" +#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC" +#define D_GPIO_WEBCAM_HREF "CAM_HREF" +#define D_GPIO_WEBCAM_PCLK "CAM_PCLK" +#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" +#define D_GPIO_WEBCAM_HSD "CAM_HSD" +#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "A" +#define D_UNIT_CELSIUS "C" #define D_UNIT_CENTIMETER "cm" +#define D_UNIT_DEGREE "°" +#define D_UNIT_FAHRENHEIT "F" #define D_UNIT_HERTZ "Hz" #define D_UNIT_HOUR "h" #define D_UNIT_GALLONS "gal" #define D_UNIT_GALLONS_PER_MIN "g/m" #define D_UNIT_INCREMENTS "inc" +#define D_UNIT_KELVIN "K" +#define D_UNIT_KILOMETER "km" #define D_UNIT_KILOGRAM "kg" #define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" #define D_UNIT_KILOOHM "kΩ" @@ -689,6 +733,7 @@ #define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_MILLION "ppm" +#define D_UNIT_PERCENT "%%" #define D_UNIT_PRESSURE "hPa" #define D_UNIT_SECOND "sec" #define D_UNIT_SECTORS "setores" @@ -747,4 +792,31 @@ #define D_SCRIPT_UPLOAD "Upload" #define D_SCRIPT_UPLOAD_FILES "Upload files" +//xsns_67_as3935.ino +#define D_AS3935_GAIN "gain:" +#define D_AS3935_ENERGY "energy:" +#define D_AS3935_DISTANCE "distance:" +#define D_AS3935_DISTURBER "disturber:" +#define D_AS3935_VRMS "µVrms:" +#define D_AS3935_APRX "aprx.:" +#define D_AS3935_AWAY "away" +#define D_AS3935_LIGHT "lightning" +#define D_AS3935_OUT "lightning out of range" +#define D_AS3935_NOT "distance not determined" +#define D_AS3935_ABOVE "lightning overhead" +#define D_AS3935_NOISE "noise detected" +#define D_AS3935_DISTDET "disturber detected" +#define D_AS3935_INTNOEV "Interrupt with no Event!" +#define D_AS3935_NOMESS "listening..." +#define D_AS3935_ON "On" +#define D_AS3935_OFF "Off" +#define D_AS3935_INDOORS "Indoors" +#define D_AS3935_OUTDOORS "Outdoors" +#define D_AS3935_CAL_FAIL "calibration failed" +#define D_AS3935_CAL_OK "calibration set to:" + +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_PT_PT_H_ diff --git a/tasmota/language/ro-RO.h b/tasmota/language/ro_RO.h similarity index 90% rename from tasmota/language/ro-RO.h rename to tasmota/language/ro_RO.h index ce9a152e9..6f38bffe7 100644 --- a/tasmota/language/ro-RO.h +++ b/tasmota/language/ro_RO.h @@ -56,6 +56,7 @@ #define D_AP "AP" // Access Point #define D_AS "as" #define D_AUTO "AUTO" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "Blink" #define D_BLINKOFF "BlinkOff" #define D_BOOT_COUNT "Boot Count" @@ -98,6 +99,8 @@ #define D_FILE "Fișier" #define D_FLOW_RATE "Debit" #define D_FREE_MEMORY "Memorie Liberă" +#define D_PSR_MAX_MEMORY "PS-RAM Memory" +#define D_PSR_FREE_MEMORY "PS-RAM free Memory" #define D_FREQUENCY "Frecvență" #define D_GAS "Gaz" #define D_GATEWAY "Gateway" @@ -114,6 +117,7 @@ #define D_IP_ADDRESS "Adresă IP" #define D_LIGHT "Lumină" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "Modul" #define D_MOISTURE "Umezeală" #define D_MQTT "MQTT" @@ -300,6 +304,7 @@ #define D_OTHER_PARAMETERS "Alți paramatri" #define D_TEMPLATE "Template" #define D_ACTIVATE "Activare" +#define D_DEVICE_NAME "Device Name" #define D_WEB_ADMIN_PASSWORD "Parolă Web Admin" #define D_MQTT_ENABLE "Activare MQTT" #define D_FRIENDLY_NAME "Friendly Name" @@ -442,6 +447,8 @@ #define D_KNX_ENHANCEMENT "Îmbunătățire Communicație" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Energia de Azi" @@ -482,6 +489,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #define D_PARTICALS_BEYOND "Particule" +// xsns_27_apds9960.ino +#define D_GESTURE "Gesture" +#define D_COLOR_RED "Red" +#define D_COLOR_GREEN "Green" +#define D_COLOR_BLUE "Blue" +#define D_CCT "CCT" +#define D_PROXIMITY "Proximity" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Accel.Axa-X" #define D_AY_AXIS "Accel.Axa-Y" @@ -567,7 +582,8 @@ #define D_SENSOR_SPI_MOSI "SPI MOSI" #define D_SENSOR_SPI_CLK "SPI CLK" #define D_SENSOR_BACKLIGHT "Backlight" -#define D_SENSOR_PMS5003 "PMS5003" +#define D_SENSOR_PMS5003_TX "PMS5003 Tx" +#define D_SENSOR_PMS5003_RX "PMS5003 Rx" #define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" #define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" #define D_SENSOR_HPMA_RX "HPMA Rx" @@ -651,28 +667,56 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" +#define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" +#define D_GPIO_WEBCAM_PWDN "CAM_PWDN" +#define D_GPIO_WEBCAM_RESET "CAM_RESET" +#define D_GPIO_WEBCAM_XCLK "CAM_XCLK" +#define D_GPIO_WEBCAM_SIOD "CAM_SIOD" +#define D_GPIO_WEBCAM_SIOC "CAM_SIOC" +#define D_GPIO_WEBCAM_DATA "CAM_DATA" +#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC" +#define D_GPIO_WEBCAM_HREF "CAM_HREF" +#define D_GPIO_WEBCAM_PCLK "CAM_PCLK" +#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" +#define D_GPIO_WEBCAM_HSD "CAM_HSD" +#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "A" +#define D_UNIT_CELSIUS "C" #define D_UNIT_CENTIMETER "cm" +#define D_UNIT_DEGREE "°" +#define D_UNIT_FAHRENHEIT "F" #define D_UNIT_HERTZ "Hz" #define D_UNIT_HOUR "h" #define D_UNIT_GALLONS "gal" #define D_UNIT_GALLONS_PER_MIN "g/m" #define D_UNIT_INCREMENTS "inc" +#define D_UNIT_KELVIN "K" +#define D_UNIT_KILOMETER "km" #define D_UNIT_KILOGRAM "kg" #define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" #define D_UNIT_KILOOHM "kΩ" @@ -689,6 +733,7 @@ #define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_MILLION "ppm" +#define D_UNIT_PERCENT "%%" #define D_UNIT_PRESSURE "hPa" #define D_UNIT_SECOND "sec" #define D_UNIT_SECTORS "sectors" @@ -747,4 +792,31 @@ #define D_SCRIPT_UPLOAD "Încarcă" #define D_SCRIPT_UPLOAD_FILES "Încarcă fișiere" +//xsns_67_as3935.ino +#define D_AS3935_GAIN "gain:" +#define D_AS3935_ENERGY "energy:" +#define D_AS3935_DISTANCE "distance:" +#define D_AS3935_DISTURBER "disturber:" +#define D_AS3935_VRMS "µVrms:" +#define D_AS3935_APRX "aprx.:" +#define D_AS3935_AWAY "away" +#define D_AS3935_LIGHT "lightning" +#define D_AS3935_OUT "lightning out of range" +#define D_AS3935_NOT "distance not determined" +#define D_AS3935_ABOVE "lightning overhead" +#define D_AS3935_NOISE "noise detected" +#define D_AS3935_DISTDET "disturber detected" +#define D_AS3935_INTNOEV "Interrupt with no Event!" +#define D_AS3935_NOMESS "listening..." +#define D_AS3935_ON "On" +#define D_AS3935_OFF "Off" +#define D_AS3935_INDOORS "Indoors" +#define D_AS3935_OUTDOORS "Outdoors" +#define D_AS3935_CAL_FAIL "calibration failed" +#define D_AS3935_CAL_OK "calibration set to:" + +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_RO_RO_H_ diff --git a/tasmota/language/ru-RU.h b/tasmota/language/ru_RU.h similarity index 91% rename from tasmota/language/ru-RU.h rename to tasmota/language/ru_RU.h index d2d0c153f..051395ed7 100644 --- a/tasmota/language/ru-RU.h +++ b/tasmota/language/ru_RU.h @@ -56,6 +56,7 @@ #define D_AP "AP" // Access Point #define D_AS "как" #define D_AUTO "АВТО" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "Мигать" #define D_BLINKOFF "Не Мигать" #define D_BOOT_COUNT "Количество загрузок" @@ -98,6 +99,8 @@ #define D_FILE "Файл" #define D_FLOW_RATE "Flow rate" #define D_FREE_MEMORY "Свободная память" +#define D_PSR_MAX_MEMORY "PS-RAM Memory" +#define D_PSR_FREE_MEMORY "PS-RAM free Memory" #define D_FREQUENCY "Frequency" #define D_GAS "Газ" #define D_GATEWAY "Шлюз" @@ -114,6 +117,7 @@ #define D_IP_ADDRESS "IP Адрес" #define D_LIGHT "Свет" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "Модуль" #define D_MOISTURE "Moisture" #define D_MQTT "MQTT" @@ -300,6 +304,7 @@ #define D_OTHER_PARAMETERS "Параметры Прочие" #define D_TEMPLATE "Template" #define D_ACTIVATE "Activate" +#define D_DEVICE_NAME "Device Name" #define D_WEB_ADMIN_PASSWORD "Пароль Web администратора" #define D_MQTT_ENABLE "MQTT активен" #define D_FRIENDLY_NAME "Дружественное Имя" @@ -442,6 +447,8 @@ #define D_KNX_ENHANCEMENT "Communication Enhancement" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Энергия Сегодня" @@ -482,6 +489,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #define D_PARTICALS_BEYOND "Particals" +// xsns_27_apds9960.ino +#define D_GESTURE "Gesture" +#define D_COLOR_RED "Red" +#define D_COLOR_GREEN "Green" +#define D_COLOR_BLUE "Blue" +#define D_CCT "CCT" +#define D_PROXIMITY "Proximity" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Accel. X-Axis" #define D_AY_AXIS "Accel. Y-Axis" @@ -567,7 +582,8 @@ #define D_SENSOR_SPI_MOSI "SPI MOSI" #define D_SENSOR_SPI_CLK "SPI CLK" #define D_SENSOR_BACKLIGHT "Backlight" -#define D_SENSOR_PMS5003 "PMS5003" +#define D_SENSOR_PMS5003_TX "PMS5003 Tx" +#define D_SENSOR_PMS5003_RX "PMS5003 Rx" #define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" #define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" #define D_SENSOR_HPMA_RX "HPMA Rx" @@ -651,28 +667,56 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" +#define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" +#define D_GPIO_WEBCAM_PWDN "CAM_PWDN" +#define D_GPIO_WEBCAM_RESET "CAM_RESET" +#define D_GPIO_WEBCAM_XCLK "CAM_XCLK" +#define D_GPIO_WEBCAM_SIOD "CAM_SIOD" +#define D_GPIO_WEBCAM_SIOC "CAM_SIOC" +#define D_GPIO_WEBCAM_DATA "CAM_DATA" +#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC" +#define D_GPIO_WEBCAM_HREF "CAM_HREF" +#define D_GPIO_WEBCAM_PCLK "CAM_PCLK" +#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" +#define D_GPIO_WEBCAM_HSD "CAM_HSD" +#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "А" +#define D_UNIT_CELSIUS "C" #define D_UNIT_CENTIMETER "cm" +#define D_UNIT_DEGREE "°" +#define D_UNIT_FAHRENHEIT "F" #define D_UNIT_HERTZ "Hz" #define D_UNIT_HOUR "Ч" #define D_UNIT_GALLONS "gal" #define D_UNIT_GALLONS_PER_MIN "g/m" #define D_UNIT_INCREMENTS "inc" +#define D_UNIT_KELVIN "K" +#define D_UNIT_KILOMETER "km" #define D_UNIT_KILOGRAM "kg" #define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" #define D_UNIT_KILOOHM "кОм" @@ -689,6 +733,7 @@ #define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_MILLION "ppm" +#define D_UNIT_PERCENT "%%" #define D_UNIT_PRESSURE "гПа" #define D_UNIT_SECOND "сек" #define D_UNIT_SECTORS "секторов" @@ -747,4 +792,31 @@ #define D_SCRIPT_UPLOAD "Upload" #define D_SCRIPT_UPLOAD_FILES "Upload files" +//xsns_67_as3935.ino +#define D_AS3935_GAIN "gain:" +#define D_AS3935_ENERGY "energy:" +#define D_AS3935_DISTANCE "distance:" +#define D_AS3935_DISTURBER "disturber:" +#define D_AS3935_VRMS "µVrms:" +#define D_AS3935_APRX "aprx.:" +#define D_AS3935_AWAY "away" +#define D_AS3935_LIGHT "lightning" +#define D_AS3935_OUT "lightning out of range" +#define D_AS3935_NOT "distance not determined" +#define D_AS3935_ABOVE "lightning overhead" +#define D_AS3935_NOISE "noise detected" +#define D_AS3935_DISTDET "disturber detected" +#define D_AS3935_INTNOEV "Interrupt with no Event!" +#define D_AS3935_NOMESS "listening..." +#define D_AS3935_ON "On" +#define D_AS3935_OFF "Off" +#define D_AS3935_INDOORS "Indoors" +#define D_AS3935_OUTDOORS "Outdoors" +#define D_AS3935_CAL_FAIL "calibration failed" +#define D_AS3935_CAL_OK "calibration set to:" + +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_RU_RU_H_ diff --git a/tasmota/language/sk-SK.h b/tasmota/language/sk_SK.h similarity index 91% rename from tasmota/language/sk-SK.h rename to tasmota/language/sk_SK.h index d925da9c6..d0109c930 100644 --- a/tasmota/language/sk-SK.h +++ b/tasmota/language/sk_SK.h @@ -56,6 +56,7 @@ #define D_AP "AP" // Access Point #define D_AS "ako" #define D_AUTO "AUTO" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "Blikanie" #define D_BLINKOFF "BlikanieVyp" #define D_BOOT_COUNT "Počítadlo spustení" @@ -98,6 +99,8 @@ #define D_FALSE "Nepravda" #define D_FILE "Súbor" #define D_FREE_MEMORY "Voľná pamäť" +#define D_PSR_MAX_MEMORY "PS-RAM Memory" +#define D_PSR_FREE_MEMORY "PS-RAM free Memory" #define D_FREQUENCY "Frekvencia" #define D_GAS "Plyn" #define D_GATEWAY "Predvolená brána" @@ -114,6 +117,7 @@ #define D_IP_ADDRESS "Adresa IP" #define D_LIGHT "Svetlo" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "Modul" #define D_MOISTURE "Moisture" #define D_MQTT "MQTT" @@ -300,6 +304,7 @@ #define D_OTHER_PARAMETERS "Ostatné nastavenia" #define D_TEMPLATE "Template" #define D_ACTIVATE "Activate" +#define D_DEVICE_NAME "Device Name" #define D_WEB_ADMIN_PASSWORD "Heslo Web administrátora" #define D_MQTT_ENABLE "MQTT aktívne" #define D_FRIENDLY_NAME "Friendly Name" @@ -442,6 +447,8 @@ #define D_KNX_ENHANCEMENT "Communication Enhancement" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Spotreba dnes" @@ -482,6 +489,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #define D_PARTICALS_BEYOND "častíc" +// xsns_27_apds9960.ino +#define D_GESTURE "Gesture" +#define D_COLOR_RED "Red" +#define D_COLOR_GREEN "Green" +#define D_COLOR_BLUE "Blue" +#define D_CCT "CCT" +#define D_PROXIMITY "Proximity" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Accel. os-X" #define D_AY_AXIS "Accel. os-Y" @@ -567,7 +582,8 @@ #define D_SENSOR_SPI_MOSI "SPI MOSI" #define D_SENSOR_SPI_CLK "SPI CLK" #define D_SENSOR_BACKLIGHT "Backlight" -#define D_SENSOR_PMS5003 "PMS5003" +#define D_SENSOR_PMS5003_TX "PMS5003 Tx" +#define D_SENSOR_PMS5003_RX "PMS5003 Rx" #define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" #define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" #define D_SENSOR_HPMA_RX "HPMA Rx" @@ -651,29 +667,57 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" +#define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" +#define D_GPIO_WEBCAM_PWDN "CAM_PWDN" +#define D_GPIO_WEBCAM_RESET "CAM_RESET" +#define D_GPIO_WEBCAM_XCLK "CAM_XCLK" +#define D_GPIO_WEBCAM_SIOD "CAM_SIOD" +#define D_GPIO_WEBCAM_SIOC "CAM_SIOC" +#define D_GPIO_WEBCAM_DATA "CAM_DATA" +#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC" +#define D_GPIO_WEBCAM_HREF "CAM_HREF" +#define D_GPIO_WEBCAM_PCLK "CAM_PCLK" +#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" +#define D_GPIO_WEBCAM_HSD "CAM_HSD" +#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "A" +#define D_UNIT_CELSIUS "C" #define D_UNIT_CENTIMETER "cm" +#define D_UNIT_DEGREE "°" +#define D_UNIT_FAHRENHEIT "F" #define D_UNIT_HERTZ "Hz" #define D_UNIT_HOUR "hod" #define D_UNIT_GALLONS "gal" #define D_UNIT_GALLONS_PER_MIN "g/m" #define D_UNIT_KILOGRAM "kg" #define D_UNIT_INCREMENTS "inc" +#define D_UNIT_KELVIN "K" +#define D_UNIT_KILOMETER "km" #define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" #define D_UNIT_KILOOHM "kΩ" #define D_UNIT_KILOWATTHOUR "kWh" @@ -689,6 +733,7 @@ #define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_MILLION "ppm" +#define D_UNIT_PERCENT "%%" #define D_UNIT_PRESSURE "hPa" #define D_UNIT_SECOND "sek" #define D_UNIT_SECTORS "sektory" @@ -747,4 +792,31 @@ #define D_SCRIPT_UPLOAD "Upload" #define D_SCRIPT_UPLOAD_FILES "Upload files" +//xsns_67_as3935.ino +#define D_AS3935_GAIN "gain:" +#define D_AS3935_ENERGY "energy:" +#define D_AS3935_DISTANCE "distance:" +#define D_AS3935_DISTURBER "disturber:" +#define D_AS3935_VRMS "µVrms:" +#define D_AS3935_APRX "aprx.:" +#define D_AS3935_AWAY "away" +#define D_AS3935_LIGHT "lightning" +#define D_AS3935_OUT "lightning out of range" +#define D_AS3935_NOT "distance not determined" +#define D_AS3935_ABOVE "lightning overhead" +#define D_AS3935_NOISE "noise detected" +#define D_AS3935_DISTDET "disturber detected" +#define D_AS3935_INTNOEV "Interrupt with no Event!" +#define D_AS3935_NOMESS "listening..." +#define D_AS3935_ON "On" +#define D_AS3935_OFF "Off" +#define D_AS3935_INDOORS "Indoors" +#define D_AS3935_OUTDOORS "Outdoors" +#define D_AS3935_CAL_FAIL "calibration failed" +#define D_AS3935_CAL_OK "calibration set to:" + +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_SK_SK_H_ diff --git a/tasmota/language/sv-SE.h b/tasmota/language/sv_SE.h similarity index 90% rename from tasmota/language/sv-SE.h rename to tasmota/language/sv_SE.h index d6be6cf9b..76385a4f6 100644 --- a/tasmota/language/sv-SE.h +++ b/tasmota/language/sv_SE.h @@ -56,6 +56,7 @@ #define D_AP "AP" // Access Point #define D_AS "som" #define D_AUTO "AUTO" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "Blinka" #define D_BLINKOFF "BlinkaAv" #define D_BOOT_COUNT "Uppstartsräknare" @@ -98,6 +99,8 @@ #define D_FILE "Fil" #define D_FLOW_RATE "Flow rate" #define D_FREE_MEMORY "Ledigt minne" +#define D_PSR_MAX_MEMORY "PS-RAM Memory" +#define D_PSR_FREE_MEMORY "PS-RAM free Memory" #define D_FREQUENCY "Frekvens" #define D_GAS "Gas" #define D_GATEWAY "Gateway" @@ -114,6 +117,7 @@ #define D_IP_ADDRESS "IP-adress" #define D_LIGHT "Ljus" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "Modul" #define D_MOISTURE "Moisture" #define D_MQTT "MQTT" @@ -300,6 +304,7 @@ #define D_OTHER_PARAMETERS "Andra parametrar" #define D_TEMPLATE "Template" #define D_ACTIVATE "Activate" +#define D_DEVICE_NAME "Device Name" #define D_WEB_ADMIN_PASSWORD "Webbadmin-lösenord" #define D_MQTT_ENABLE "MQTT aktivera" #define D_FRIENDLY_NAME "Läsbart namn" @@ -442,6 +447,8 @@ #define D_KNX_ENHANCEMENT "Kommuniceringsförbättring" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Energi idag" @@ -482,6 +489,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #define D_PARTICALS_BEYOND "Partiklar" +// xsns_27_apds9960.ino +#define D_GESTURE "Gesture" +#define D_COLOR_RED "Red" +#define D_COLOR_GREEN "Green" +#define D_COLOR_BLUE "Blue" +#define D_CCT "CCT" +#define D_PROXIMITY "Proximity" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Accel. X-Axel" #define D_AY_AXIS "Accel. Y-Axel" @@ -567,7 +582,8 @@ #define D_SENSOR_SPI_MOSI "SPI MOSI" #define D_SENSOR_SPI_CLK "SPI CLK" #define D_SENSOR_BACKLIGHT "Backlight" -#define D_SENSOR_PMS5003 "PMS5003" +#define D_SENSOR_PMS5003_TX "PMS5003 Tx" +#define D_SENSOR_PMS5003_RX "PMS5003 Rx" #define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" #define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" #define D_SENSOR_HPMA_RX "HPMA Rx" @@ -651,28 +667,56 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" +#define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" +#define D_GPIO_WEBCAM_PWDN "CAM_PWDN" +#define D_GPIO_WEBCAM_RESET "CAM_RESET" +#define D_GPIO_WEBCAM_XCLK "CAM_XCLK" +#define D_GPIO_WEBCAM_SIOD "CAM_SIOD" +#define D_GPIO_WEBCAM_SIOC "CAM_SIOC" +#define D_GPIO_WEBCAM_DATA "CAM_DATA" +#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC" +#define D_GPIO_WEBCAM_HREF "CAM_HREF" +#define D_GPIO_WEBCAM_PCLK "CAM_PCLK" +#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" +#define D_GPIO_WEBCAM_HSD "CAM_HSD" +#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "A" +#define D_UNIT_CELSIUS "C" #define D_UNIT_CENTIMETER "cm" +#define D_UNIT_DEGREE "°" +#define D_UNIT_FAHRENHEIT "F" #define D_UNIT_HERTZ "Hz" #define D_UNIT_HOUR "Tim" #define D_UNIT_GALLONS "gal" #define D_UNIT_GALLONS_PER_MIN "g/m" #define D_UNIT_INCREMENTS "ink" +#define D_UNIT_KELVIN "K" +#define D_UNIT_KILOMETER "km" #define D_UNIT_KILOGRAM "kg" #define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" #define D_UNIT_KILOOHM "kΩ" @@ -689,6 +733,7 @@ #define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_MILLION "ppm" +#define D_UNIT_PERCENT "%%" #define D_UNIT_PRESSURE "hPa" #define D_UNIT_SECOND "sek" #define D_UNIT_SECTORS "sektorer" @@ -747,4 +792,31 @@ #define D_SCRIPT_UPLOAD "Upload" #define D_SCRIPT_UPLOAD_FILES "Upload files" +//xsns_67_as3935.ino +#define D_AS3935_GAIN "gain:" +#define D_AS3935_ENERGY "energy:" +#define D_AS3935_DISTANCE "distance:" +#define D_AS3935_DISTURBER "disturber:" +#define D_AS3935_VRMS "µVrms:" +#define D_AS3935_APRX "aprx.:" +#define D_AS3935_AWAY "away" +#define D_AS3935_LIGHT "lightning" +#define D_AS3935_OUT "lightning out of range" +#define D_AS3935_NOT "distance not determined" +#define D_AS3935_ABOVE "lightning overhead" +#define D_AS3935_NOISE "noise detected" +#define D_AS3935_DISTDET "disturber detected" +#define D_AS3935_INTNOEV "Interrupt with no Event!" +#define D_AS3935_NOMESS "listening..." +#define D_AS3935_ON "On" +#define D_AS3935_OFF "Off" +#define D_AS3935_INDOORS "Indoors" +#define D_AS3935_OUTDOORS "Outdoors" +#define D_AS3935_CAL_FAIL "calibration failed" +#define D_AS3935_CAL_OK "calibration set to:" + +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_SV_SE_H_ diff --git a/tasmota/language/tr-TR.h b/tasmota/language/tr_TR.h similarity index 90% rename from tasmota/language/tr-TR.h rename to tasmota/language/tr_TR.h index 09ca53017..8e7d34d2f 100644 --- a/tasmota/language/tr-TR.h +++ b/tasmota/language/tr_TR.h @@ -56,6 +56,7 @@ #define D_AP "AP" // Access Point #define D_AS "as" #define D_AUTO "OTOMATIK" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "Blink" #define D_BLINKOFF "BlinkOff" #define D_BOOT_COUNT "Yeniden başlama sayısı" @@ -98,6 +99,8 @@ #define D_FILE "Dosya" #define D_FLOW_RATE "Flow rate" #define D_FREE_MEMORY "Boş Hafıza" +#define D_PSR_MAX_MEMORY "PS-RAM Memory" +#define D_PSR_FREE_MEMORY "PS-RAM free Memory" #define D_FREQUENCY "Frekans" #define D_GAS "Gas" #define D_GATEWAY "Geçit" @@ -114,6 +117,7 @@ #define D_IP_ADDRESS "IP Adresi" #define D_LIGHT "Işık" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "Modül" #define D_MOISTURE "Moisture" #define D_MQTT "MQTT" @@ -300,6 +304,7 @@ #define D_OTHER_PARAMETERS "Diğer parametreler" #define D_TEMPLATE "Template" #define D_ACTIVATE "Activate" +#define D_DEVICE_NAME "Device Name" #define D_WEB_ADMIN_PASSWORD "Web Yönetici Şifresi" #define D_MQTT_ENABLE "MQTT aktif" #define D_FRIENDLY_NAME "Kullanıcı Dostu İsim" @@ -442,6 +447,8 @@ #define D_KNX_ENHANCEMENT "Communication Enhancement" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Energy Today" @@ -482,6 +489,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #define D_PARTICALS_BEYOND "Particals" +// xsns_27_apds9960.ino +#define D_GESTURE "Gesture" +#define D_COLOR_RED "Red" +#define D_COLOR_GREEN "Green" +#define D_COLOR_BLUE "Blue" +#define D_CCT "CCT" +#define D_PROXIMITY "Proximity" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Accel. X-Axis" #define D_AY_AXIS "Accel. Y-Axis" @@ -567,7 +582,8 @@ #define D_SENSOR_SPI_MOSI "SPI MOSI" #define D_SENSOR_SPI_CLK "SPI CLK" #define D_SENSOR_BACKLIGHT "Backlight" -#define D_SENSOR_PMS5003 "PMS5003" +#define D_SENSOR_PMS5003_TX "PMS5003 Tx" +#define D_SENSOR_PMS5003_RX "PMS5003 Rx" #define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" #define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" #define D_SENSOR_HPMA_RX "HPMA Rx" @@ -651,28 +667,56 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" +#define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" +#define D_GPIO_WEBCAM_PWDN "CAM_PWDN" +#define D_GPIO_WEBCAM_RESET "CAM_RESET" +#define D_GPIO_WEBCAM_XCLK "CAM_XCLK" +#define D_GPIO_WEBCAM_SIOD "CAM_SIOD" +#define D_GPIO_WEBCAM_SIOC "CAM_SIOC" +#define D_GPIO_WEBCAM_DATA "CAM_DATA" +#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC" +#define D_GPIO_WEBCAM_HREF "CAM_HREF" +#define D_GPIO_WEBCAM_PCLK "CAM_PCLK" +#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" +#define D_GPIO_WEBCAM_HSD "CAM_HSD" +#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "A" +#define D_UNIT_CELSIUS "C" #define D_UNIT_CENTIMETER "cm" +#define D_UNIT_DEGREE "°" +#define D_UNIT_FAHRENHEIT "F" #define D_UNIT_HERTZ "Hz" #define D_UNIT_HOUR "h" #define D_UNIT_GALLONS "gal" #define D_UNIT_GALLONS_PER_MIN "g/m" #define D_UNIT_INCREMENTS "inc" +#define D_UNIT_KELVIN "K" +#define D_UNIT_KILOMETER "km" #define D_UNIT_KILOGRAM "kg" #define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" #define D_UNIT_KILOOHM "kΩ" @@ -689,6 +733,7 @@ #define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_MILLION "ppm" +#define D_UNIT_PERCENT "%%" #define D_UNIT_PRESSURE "hPa" #define D_UNIT_SECOND "sec" #define D_UNIT_SECTORS "sectors" @@ -747,4 +792,31 @@ #define D_SCRIPT_UPLOAD "Upload" #define D_SCRIPT_UPLOAD_FILES "Upload files" +//xsns_67_as3935.ino +#define D_AS3935_GAIN "gain:" +#define D_AS3935_ENERGY "energy:" +#define D_AS3935_DISTANCE "distance:" +#define D_AS3935_DISTURBER "disturber:" +#define D_AS3935_VRMS "µVrms:" +#define D_AS3935_APRX "aprx.:" +#define D_AS3935_AWAY "away" +#define D_AS3935_LIGHT "lightning" +#define D_AS3935_OUT "lightning out of range" +#define D_AS3935_NOT "distance not determined" +#define D_AS3935_ABOVE "lightning overhead" +#define D_AS3935_NOISE "noise detected" +#define D_AS3935_DISTDET "disturber detected" +#define D_AS3935_INTNOEV "Interrupt with no Event!" +#define D_AS3935_NOMESS "listening..." +#define D_AS3935_ON "On" +#define D_AS3935_OFF "Off" +#define D_AS3935_INDOORS "Indoors" +#define D_AS3935_OUTDOORS "Outdoors" +#define D_AS3935_CAL_FAIL "calibration failed" +#define D_AS3935_CAL_OK "calibration set to:" + +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_TR_TR_H_ diff --git a/tasmota/language/uk-UA.h b/tasmota/language/uk_UA.h similarity index 92% rename from tasmota/language/uk-UA.h rename to tasmota/language/uk_UA.h index 4a62825e8..d4763bcfa 100644 --- a/tasmota/language/uk-UA.h +++ b/tasmota/language/uk_UA.h @@ -56,6 +56,7 @@ #define D_AP "Точка доступу" // Access Point #define D_AS "як" #define D_AUTO "АВТО" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "Блимати" #define D_BLINKOFF "Не блимати" #define D_BOOT_COUNT "К-сть завант." @@ -98,6 +99,8 @@ #define D_FILE "Файл" #define D_FLOW_RATE "Потік" #define D_FREE_MEMORY "Вільна память" +#define D_PSR_MAX_MEMORY "PS-RAM Memory" +#define D_PSR_FREE_MEMORY "PS-RAM free Memory" #define D_FREQUENCY "Частота" #define D_GAS "Газ" #define D_GATEWAY "Шлюз" @@ -114,6 +117,7 @@ #define D_IP_ADDRESS "IP адреса" #define D_LIGHT "Світло" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "Модуль" #define D_MOISTURE "Волога" #define D_MQTT "MQTT" @@ -300,6 +304,7 @@ #define D_OTHER_PARAMETERS "Параметри Інше" #define D_TEMPLATE "Шаблони" #define D_ACTIVATE "Активований" +#define D_DEVICE_NAME "Device Name" #define D_WEB_ADMIN_PASSWORD "Гасло адміністратора Web" #define D_MQTT_ENABLE "MQTT активний" #define D_FRIENDLY_NAME "Дружня назва" @@ -442,6 +447,8 @@ #define D_KNX_ENHANCEMENT "Підвищення зв'язку" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "Енергія Сьогодні" @@ -482,6 +489,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #define D_PARTICALS_BEYOND "Частинки понад" +// xsns_27_apds9960.ino +#define D_GESTURE "Gesture" +#define D_COLOR_RED "Red" +#define D_COLOR_GREEN "Green" +#define D_COLOR_BLUE "Blue" +#define D_CCT "CCT" +#define D_PROXIMITY "Proximity" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Приск. Вісь-X" #define D_AY_AXIS "Приск. Вісь-Y" @@ -567,7 +582,8 @@ #define D_SENSOR_SPI_MOSI "SPI MOSI" #define D_SENSOR_SPI_CLK "SPI CLK" #define D_SENSOR_BACKLIGHT "OLED Light" -#define D_SENSOR_PMS5003 "PMS5003" +#define D_SENSOR_PMS5003_TX "PMS5003 Tx" +#define D_SENSOR_PMS5003_RX "PMS5003 Rx" #define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" #define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" #define D_SENSOR_HPMA_RX "HPMA Rx" @@ -651,28 +667,56 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" +#define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" +#define D_GPIO_WEBCAM_PWDN "CAM_PWDN" +#define D_GPIO_WEBCAM_RESET "CAM_RESET" +#define D_GPIO_WEBCAM_XCLK "CAM_XCLK" +#define D_GPIO_WEBCAM_SIOD "CAM_SIOD" +#define D_GPIO_WEBCAM_SIOC "CAM_SIOC" +#define D_GPIO_WEBCAM_DATA "CAM_DATA" +#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC" +#define D_GPIO_WEBCAM_HREF "CAM_HREF" +#define D_GPIO_WEBCAM_PCLK "CAM_PCLK" +#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" +#define D_GPIO_WEBCAM_HSD "CAM_HSD" +#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "А" +#define D_UNIT_CELSIUS "C" #define D_UNIT_CENTIMETER "cм" +#define D_UNIT_DEGREE "°" +#define D_UNIT_FAHRENHEIT "F" #define D_UNIT_HERTZ "Гц" #define D_UNIT_HOUR "г" #define D_UNIT_GALLONS "гал" #define D_UNIT_GALLONS_PER_MIN "гал/хв" #define D_UNIT_INCREMENTS "інк" +#define D_UNIT_KELVIN "K" +#define D_UNIT_KILOMETER "km" #define D_UNIT_KILOGRAM "кг" #define D_UNIT_KILOMETER_PER_HOUR "км/г" // or "km/h" #define D_UNIT_KILOOHM "㏀" @@ -689,6 +733,7 @@ #define D_UNIT_PARTS_PER_BILLION "млрд⁻¹" #define D_UNIT_PARTS_PER_DECILITER "децилітр⁻¹" #define D_UNIT_PARTS_PER_MILLION "млн⁻¹" +#define D_UNIT_PERCENT "%%" #define D_UNIT_PRESSURE "гПа" #define D_UNIT_SECOND "сек" #define D_UNIT_SECTORS "секторів" @@ -747,4 +792,31 @@ #define D_SCRIPT_UPLOAD "Завантажити" #define D_SCRIPT_UPLOAD_FILES "Завантажити файли" +//xsns_67_as3935.ino +#define D_AS3935_GAIN "gain:" +#define D_AS3935_ENERGY "energy:" +#define D_AS3935_DISTANCE "distance:" +#define D_AS3935_DISTURBER "disturber:" +#define D_AS3935_VRMS "µVrms:" +#define D_AS3935_APRX "aprx.:" +#define D_AS3935_AWAY "away" +#define D_AS3935_LIGHT "lightning" +#define D_AS3935_OUT "lightning out of range" +#define D_AS3935_NOT "distance not determined" +#define D_AS3935_ABOVE "lightning overhead" +#define D_AS3935_NOISE "noise detected" +#define D_AS3935_DISTDET "disturber detected" +#define D_AS3935_INTNOEV "Interrupt with no Event!" +#define D_AS3935_NOMESS "listening..." +#define D_AS3935_ON "On" +#define D_AS3935_OFF "Off" +#define D_AS3935_INDOORS "Indoors" +#define D_AS3935_OUTDOORS "Outdoors" +#define D_AS3935_CAL_FAIL "calibration failed" +#define D_AS3935_CAL_OK "calibration set to:" + +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_UK_UA_H_ diff --git a/tasmota/language/zh-CN.h b/tasmota/language/zh_CN.h similarity index 90% rename from tasmota/language/zh-CN.h rename to tasmota/language/zh_CN.h index cb4221e75..84ce0991f 100644 --- a/tasmota/language/zh-CN.h +++ b/tasmota/language/zh_CN.h @@ -56,6 +56,7 @@ #define D_AP "AP" // Access Point #define D_AS "名称:" #define D_AUTO "自动" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "闪烁" #define D_BLINKOFF "闪烁关" #define D_BOOT_COUNT "启动次数" @@ -98,6 +99,8 @@ #define D_FILE "文件:" #define D_FLOW_RATE "Flow rate" #define D_FREE_MEMORY "空闲内存" +#define D_PSR_MAX_MEMORY "PS-RAM Memory" +#define D_PSR_FREE_MEMORY "PS-RAM free Memory" #define D_FREQUENCY "频率" #define D_GAS "气体" #define D_GATEWAY "网关" @@ -114,6 +117,7 @@ #define D_IP_ADDRESS "IP地址" #define D_LIGHT "灯" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "模块" #define D_MOISTURE "Moisture" #define D_MQTT "MQTT" @@ -300,6 +304,7 @@ #define D_OTHER_PARAMETERS "其他设置" #define D_TEMPLATE "模板" #define D_ACTIVATE "启用" +#define D_DEVICE_NAME "Device Name" #define D_WEB_ADMIN_PASSWORD "WEB 管理密码" #define D_MQTT_ENABLE "启用MQTT" #define D_FRIENDLY_NAME "昵称" @@ -442,6 +447,8 @@ #define D_KNX_ENHANCEMENT "通讯增强" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "今日用电量" @@ -482,6 +489,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #define D_PARTICALS_BEYOND "颗粒物直径大于" +// xsns_27_apds9960.ino +#define D_GESTURE "Gesture" +#define D_COLOR_RED "Red" +#define D_COLOR_GREEN "Green" +#define D_COLOR_BLUE "Blue" +#define D_CCT "CCT" +#define D_PROXIMITY "Proximity" + // xsns_32_mpu6050.ino #define D_AX_AXIS "加速度计X轴分量" #define D_AY_AXIS "加速度计Y轴分量" @@ -567,7 +582,8 @@ #define D_SENSOR_SPI_MOSI "SPI MOSI" #define D_SENSOR_SPI_CLK "SPI CLK" #define D_SENSOR_BACKLIGHT "Backlight" -#define D_SENSOR_PMS5003 "PMS5003" +#define D_SENSOR_PMS5003_TX "PMS5003 Tx" +#define D_SENSOR_PMS5003_RX "PMS5003 Rx" #define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" #define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" #define D_SENSOR_HPMA_RX "HPMA Rx" @@ -651,28 +667,56 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" +#define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" +#define D_GPIO_WEBCAM_PWDN "CAM_PWDN" +#define D_GPIO_WEBCAM_RESET "CAM_RESET" +#define D_GPIO_WEBCAM_XCLK "CAM_XCLK" +#define D_GPIO_WEBCAM_SIOD "CAM_SIOD" +#define D_GPIO_WEBCAM_SIOC "CAM_SIOC" +#define D_GPIO_WEBCAM_DATA "CAM_DATA" +#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC" +#define D_GPIO_WEBCAM_HREF "CAM_HREF" +#define D_GPIO_WEBCAM_PCLK "CAM_PCLK" +#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" +#define D_GPIO_WEBCAM_HSD "CAM_HSD" +#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "安" +#define D_UNIT_CELSIUS "C" #define D_UNIT_CENTIMETER "厘米" +#define D_UNIT_DEGREE "°" +#define D_UNIT_FAHRENHEIT "F" #define D_UNIT_HERTZ "赫兹" #define D_UNIT_HOUR "时" #define D_UNIT_GALLONS "gal" #define D_UNIT_GALLONS_PER_MIN "g/m" #define D_UNIT_INCREMENTS "inc" +#define D_UNIT_KELVIN "K" +#define D_UNIT_KILOMETER "km" #define D_UNIT_KILOGRAM "千克" #define D_UNIT_KILOMETER_PER_HOUR "公里/时" // or "km/h" #define D_UNIT_KILOOHM "千欧" @@ -689,6 +733,7 @@ #define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_DECILITER "每分升" #define D_UNIT_PARTS_PER_MILLION "ppm" +#define D_UNIT_PERCENT "%%" #define D_UNIT_PRESSURE "百帕" #define D_UNIT_SECOND "秒" #define D_UNIT_SECTORS "扇区" @@ -747,4 +792,31 @@ #define D_SCRIPT_UPLOAD "Upload" #define D_SCRIPT_UPLOAD_FILES "Upload files" +//xsns_67_as3935.ino +#define D_AS3935_GAIN "gain:" +#define D_AS3935_ENERGY "energy:" +#define D_AS3935_DISTANCE "distance:" +#define D_AS3935_DISTURBER "disturber:" +#define D_AS3935_VRMS "µVrms:" +#define D_AS3935_APRX "aprx.:" +#define D_AS3935_AWAY "away" +#define D_AS3935_LIGHT "lightning" +#define D_AS3935_OUT "lightning out of range" +#define D_AS3935_NOT "distance not determined" +#define D_AS3935_ABOVE "lightning overhead" +#define D_AS3935_NOISE "noise detected" +#define D_AS3935_DISTDET "disturber detected" +#define D_AS3935_INTNOEV "Interrupt with no Event!" +#define D_AS3935_NOMESS "listening..." +#define D_AS3935_ON "On" +#define D_AS3935_OFF "Off" +#define D_AS3935_INDOORS "Indoors" +#define D_AS3935_OUTDOORS "Outdoors" +#define D_AS3935_CAL_FAIL "calibration failed" +#define D_AS3935_CAL_OK "calibration set to:" + +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_ZH_CN_H_ diff --git a/tasmota/language/zh-TW.h b/tasmota/language/zh_TW.h similarity index 90% rename from tasmota/language/zh-TW.h rename to tasmota/language/zh_TW.h index 6738d4208..4762b9c16 100644 --- a/tasmota/language/zh-TW.h +++ b/tasmota/language/zh_TW.h @@ -56,6 +56,7 @@ #define D_AP "AP" // Access Point #define D_AS "名稱:" #define D_AUTO "自動" +#define D_BATT "Batt" // Short for Battery #define D_BLINK "閃爍" #define D_BLINKOFF "閃爍關" #define D_BOOT_COUNT "啟動次數" @@ -98,6 +99,8 @@ #define D_FILE "文件:" #define D_FLOW_RATE "Flow rate" #define D_FREE_MEMORY "可用記憶體" +#define D_PSR_MAX_MEMORY "PS-RAM Memory" +#define D_PSR_FREE_MEMORY "PS-RAM free Memory" #define D_FREQUENCY "Frequency" #define D_GAS "氣體" #define D_GATEWAY "網關" @@ -114,6 +117,7 @@ #define D_IP_ADDRESS "IP地址" #define D_LIGHT "燈" #define D_LWT "LWT" +#define D_LQI "LQI" // Zigbee Link Quality Index #define D_MODULE "模組" #define D_MOISTURE "Moisture" #define D_MQTT "MQTT" @@ -300,6 +304,7 @@ #define D_OTHER_PARAMETERS "其他設置" #define D_TEMPLATE "Template" #define D_ACTIVATE "Activate" +#define D_DEVICE_NAME "Device Name" #define D_WEB_ADMIN_PASSWORD "WEB管理密碼" #define D_MQTT_ENABLE "啟用MQTT" #define D_FRIENDLY_NAME "昵稱" @@ -442,6 +447,8 @@ #define D_KNX_ENHANCEMENT "Communication Enhancement" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" // xdrv_03_energy.ino #define D_ENERGY_TODAY "今日用電量" @@ -482,6 +489,14 @@ #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #define D_PARTICALS_BEYOND "顆粒物直徑大於" +// xsns_27_apds9960.ino +#define D_GESTURE "Gesture" +#define D_COLOR_RED "Red" +#define D_COLOR_GREEN "Green" +#define D_COLOR_BLUE "Blue" +#define D_CCT "CCT" +#define D_PROXIMITY "Proximity" + // xsns_32_mpu6050.ino #define D_AX_AXIS "Accel. X-Axis" #define D_AY_AXIS "Accel. Y-Axis" @@ -567,7 +582,8 @@ #define D_SENSOR_SPI_MOSI "SPI MOSI" #define D_SENSOR_SPI_CLK "SPI CLK" #define D_SENSOR_BACKLIGHT "Backlight" -#define D_SENSOR_PMS5003 "PMS5003" +#define D_SENSOR_PMS5003_TX "PMS5003 Tx" +#define D_SENSOR_PMS5003_RX "PMS5003 Rx" #define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" #define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" #define D_SENSOR_HPMA_RX "HPMA Rx" @@ -651,28 +667,56 @@ #define D_SENSOR_SM2135_DAT "SM2135 Dat" #define D_SENSOR_DEEPSLEEP "DeepSleep" #define D_SENSOR_EXS_ENABLE "EXS Enable" -#define D_SENSOR_SLAVE_TX "Slave TX" -#define D_SENSOR_SLAVE_RX "Slave RX" -#define D_SENSOR_SLAVE_RESET "Slave RST" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" #define D_SENSOR_GPS_RX "GPS RX" #define D_SENSOR_GPS_TX "GPS TX" #define D_SENSOR_HM10_RX "HM10 RX" #define D_SENSOR_HM10_TX "HM10 TX" #define D_SENSOR_LE01MR_RX "LE-01MR Rx" #define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" #define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" #define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" #define D_SENSOR_HRXL_RX "HRXL Rx" #define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" +#define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" +#define D_GPIO_WEBCAM_PWDN "CAM_PWDN" +#define D_GPIO_WEBCAM_RESET "CAM_RESET" +#define D_GPIO_WEBCAM_XCLK "CAM_XCLK" +#define D_GPIO_WEBCAM_SIOD "CAM_SIOD" +#define D_GPIO_WEBCAM_SIOC "CAM_SIOC" +#define D_GPIO_WEBCAM_DATA "CAM_DATA" +#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC" +#define D_GPIO_WEBCAM_HREF "CAM_HREF" +#define D_GPIO_WEBCAM_PCLK "CAM_PCLK" +#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" +#define D_GPIO_WEBCAM_HSD "CAM_HSD" +#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_RXD "TCP Rx" // Units #define D_UNIT_AMPERE "安" +#define D_UNIT_CELSIUS "C" #define D_UNIT_CENTIMETER "cm" +#define D_UNIT_DEGREE "°" +#define D_UNIT_FAHRENHEIT "F" #define D_UNIT_HERTZ "Hz" #define D_UNIT_HOUR "時" #define D_UNIT_GALLONS "gal" #define D_UNIT_GALLONS_PER_MIN "g/m" #define D_UNIT_INCREMENTS "inc" +#define D_UNIT_KELVIN "K" +#define D_UNIT_KILOMETER "km" #define D_UNIT_KILOGRAM "kg" #define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" #define D_UNIT_KILOOHM "千歐" @@ -689,6 +733,7 @@ #define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_DECILITER "每分升" #define D_UNIT_PARTS_PER_MILLION "ppm" +#define D_UNIT_PERCENT "%%" #define D_UNIT_PRESSURE "百帕" #define D_UNIT_SECOND "秒" #define D_UNIT_SECTORS "扇區" @@ -747,4 +792,31 @@ #define D_SCRIPT_UPLOAD "Upload" #define D_SCRIPT_UPLOAD_FILES "Upload files" +//xsns_67_as3935.ino +#define D_AS3935_GAIN "gain:" +#define D_AS3935_ENERGY "energy:" +#define D_AS3935_DISTANCE "distance:" +#define D_AS3935_DISTURBER "disturber:" +#define D_AS3935_VRMS "µVrms:" +#define D_AS3935_APRX "aprx.:" +#define D_AS3935_AWAY "away" +#define D_AS3935_LIGHT "lightning" +#define D_AS3935_OUT "lightning out of range" +#define D_AS3935_NOT "distance not determined" +#define D_AS3935_ABOVE "lightning overhead" +#define D_AS3935_NOISE "noise detected" +#define D_AS3935_DISTDET "disturber detected" +#define D_AS3935_INTNOEV "Interrupt with no Event!" +#define D_AS3935_NOMESS "listening..." +#define D_AS3935_ON "On" +#define D_AS3935_OFF "Off" +#define D_AS3935_INDOORS "Indoors" +#define D_AS3935_OUTDOORS "Outdoors" +#define D_AS3935_CAL_FAIL "calibration failed" +#define D_AS3935_CAL_OK "calibration set to:" + +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + #endif // _LANGUAGE_ZH_TW_H_ diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index a28a52067..0ab09d224 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -50,7 +50,14 @@ #define PROJECT "tasmota" // PROJECT is used as the default topic delimiter // If not selected the default will be SONOFF_BASIC -//#define MODULE SONOFF_BASIC // [Module] Select default model from tasmota_template.h +//#define MODULE SONOFF_BASIC // [Module] Select default module from tasmota_template.h +#ifdef ESP8266 +#define FALLBACK_MODULE SONOFF_BASIC // [Module2] Select default module on fast reboot where USER_MODULE is user template +//#define USER_TEMPLATE "{\"NAME\":\"Generic\",\"GPIO\":[255,255,255,255,255,255,255,255,255,255,255,255,255],\"FLAG\":15,\"BASE\":18}" // [Template] Set JSON template +#else // ESP32 +#define FALLBACK_MODULE WEMOS // [Module2] Select default module on fast reboot where USER_MODULE is user template +//#define USER_TEMPLATE "{\"NAME\":\"ESP32-DevKit\",\"GPIO\":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,0,0,0,0,1,1,1,1,1,0,0,1],\"FLAG\":0,\"BASE\":1}" // [Template] Set JSON template +#endif #define SAVE_DATA 1 // [SaveData] Save changed parameters to Flash (0 = disable, 1 - 3600 seconds) #define SAVE_STATE true // [SetOption0] Save changed power state to Flash (false = disable, true = enable) @@ -70,6 +77,7 @@ #define WIFI_CONFIG_TOOL WIFI_RETRY // [WifiConfig] Default tool if wifi fails to connect (default option: 4 - WIFI_RETRY) // (WIFI_RESTART, WIFI_MANAGER, WIFI_RETRY, WIFI_WAIT, WIFI_SERIAL, WIFI_MANAGER_RESET_ONLY) // The configuration can be changed after first setup using WifiConfig 0, 2, 4, 5, 6 and 7. +#define WIFI_ARP_INTERVAL 0 // [SetOption41] Send gratuitous ARP interval #define WIFI_SCAN_AT_RESTART false // [SetOption56] Scan wifi network at restart for configured AP's #define WIFI_SCAN_REGULARLY false // [SetOption57] Scan wifi network every 44 minutes for configured AP's @@ -89,8 +97,8 @@ #define MQTT_USE true // [SetOption3] Select default MQTT use (false = Off, true = On) #define MQTT_HOST "" // [MqttHost] -#define MQTT_FINGERPRINT1 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" // [MqttFingerprint1] -#define MQTT_FINGERPRINT2 "A5 02 FF 13 99 9F 8B 39 8E F1 83 4F 11 23 65 0B 32 36 FC 07" // [MqttFingerprint2] +#define MQTT_FINGERPRINT1 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" // [MqttFingerprint1] (auto-learn) +#define MQTT_FINGERPRINT2 "DA 39 A3 EE 5E 6B 4B 0D 32 55 BF EF 95 60 18 90 AF D8 07 09" // [MqttFingerprint2] (invalid) #define MQTT_PORT 1883 // [MqttPort] MQTT port (10123 on CloudMQTT) #define MQTT_USER "DVES_USER" // [MqttUser] MQTT user #define MQTT_PASS "DVES_PASS" // [MqttPassword] MQTT password @@ -100,7 +108,7 @@ #define MQTT_SWITCH_RETAIN false // [SwitchRetain] Switch may send retain flag (false = off, true = on) #define MQTT_SENSOR_RETAIN false // [SensorRetain] Sensor may send retain flag (false = off, true = on) #define MQTT_NO_HOLD_RETAIN false // [SetOption62] Disable retain flag on HOLD messages -//#define MQTT_NO_RETAIN // Disable all retain flags (including LWT!) if unsupported by broker (eg Losant) +//#define MQTT_NO_RETAIN // Disable all retain flags (This don't include LWT!) if unsupported by broker (eg Losant) #define MQTT_STATUS_OFF "OFF" // [StateText1] Command or Status result when turned off (needs to be a string like "0" or "Off") #define MQTT_STATUS_ON "ON" // [StateText2] Command or Status result when turned on (needs to be a string like "1" or "On") @@ -117,12 +125,12 @@ #define PUB_PREFIX2 "tele" // [Prefix3] Tasmota devices publish telemetry data to %prefix%/%topic% being PUB_PREFIX2/MQTT_TOPIC/UPTIME, POWER and TIME // May be named the same as PUB_PREFIX // %topic% token options (also ButtonTopic and SwitchTopic) -#define MQTT_TOPIC PROJECT "_%06X" // [Topic] unique MQTT device topic including device MAC address +#define MQTT_TOPIC PROJECT "_%06X" // [Topic] unique MQTT device topic including (part of) device MAC address #define MQTT_GRPTOPIC "tasmotas" // [GroupTopic] MQTT Group topic #define MQTT_GROUPTOPIC_FORMAT false // [SetOption75] GroupTopic replaces %topic% (false) or fixed topic cmnd/grouptopic (true) #define MQTT_BUTTON_TOPIC "0" // [ButtonTopic] MQTT button topic, "0" = same as MQTT_TOPIC, set to 'PROJECT "_BTN_%06X"' for unique topic including device MAC address #define MQTT_SWITCH_TOPIC "0" // [SwitchTopic] MQTT button topic, "0" = same as MQTT_TOPIC, set to 'PROJECT "_SW_%06X"' for unique topic including device MAC address -#define MQTT_CLIENT_ID "DVES_%06X" // [MqttClient] Also fall back topic using Chip Id = last 6 characters of MAC address +#define MQTT_CLIENT_ID "DVES_%06X" // [MqttClient] Also fall back topic using last 6 characters of MAC address or use "DVES_%12X" for complete MAC address // -- MQTT - Telemetry ---------------------------- #define TELE_PERIOD 300 // [TelePeriod] Telemetry (0 = disable, 10 - 3600 seconds) @@ -134,6 +142,8 @@ // -- MQTT - Home Assistant Discovery ------------- #define HOME_ASSISTANT_DISCOVERY_ENABLE false // [SetOption19] Home Assistant Discovery (false = Disable, true = Enable) #define HASS_AS_LIGHT false // [SetOption30] Enforce HAss autodiscovery as light +//#define DEEPSLEEP_LWT_HA_DISCOVERY // Enable LWT topic and its payloads for read-only sensors (Status sensor not included) and binary_sensors on HAss Discovery (Commented out: all read-only sensors and binary_sensors + // won't be shown as OFFLINE on Home Assistant when the device is DeepSleeping - NOTE: This is only for read-only sensors and binary_sensors, relays will be shown as OFFLINE) // -- MQTT - Options ------------------------------ #define MQTT_RESULT_COMMAND false // [SetOption4] Switch between MQTT RESULT or COMMAND @@ -272,6 +282,12 @@ #define APP_DISABLE_POWERCYCLE false // [SetOption65] Disable fast power cycle detection for device reset #define DEEPSLEEP_BOOTCOUNT false // [SetOption76] Enable incrementing bootcount when deepsleep is enabled +#define APP_INTERLOCK_MODE false // [Interlock] Relay interlock mode +#define APP_INTERLOCK_GROUP_1 0xFF // [Interlock] Relay bitmask for interlock group 1 (0xFF if undef) +//#define APP_INTERLOCK_GROUP_2 0x00 // [Interlock] Relay bitmask for interlock group 2 (0x00 if undef) +//#define APP_INTERLOCK_GROUP_3 0x00 // [Interlock] Relay bitmask for interlock group 3 (0x00 if undef) +//#define APP_INTERLOCK_GROUP_4 0x00 // [Interlock] Relay bitmask for interlock group 4 (0x00 if undef) + // -- Lights -------------------------------------- #define WS2812_LEDS 30 // [Pixels] Number of WS2812 LEDs to start with (max is 512) #define LIGHT_MODE true // [SetOption15] Switch between commands PWM or COLOR/DIMMER/CT/CHANNEL @@ -282,6 +298,7 @@ #define LIGHT_CHANNEL_MODE false // [SetOption68] Enable multi-channels PWM instead of Color PWM #define LIGHT_SLIDER_POWER false // [SetOption77] Do not power off if slider moved to far left #define LIGHT_ALEXA_CT_RANGE false // [SetOption82] Reduced CT range for Alexa +#define LIGHT_PWM_CT_MODE false // [SetOption92] Set PWM Mode from regular PWM to ColorTemp control (Xiaomi Philips ...) a.k.a. module 48 mode // -- Energy -------------------------------------- #define ENERGY_VOLTAGE_ALWAYS false // [SetOption21] Enable show voltage even if powered off @@ -311,29 +328,29 @@ // -- Localization -------------------------------- // If non selected the default en-GB will be used -//#define MY_LANGUAGE bg-BG // Bulgarian in Bulgaria -//#define MY_LANGUAGE cs-CZ // Czech in Czech -//#define MY_LANGUAGE de-DE // German in Germany -//#define MY_LANGUAGE el-GR // Greek in Greece -//#define MY_LANGUAGE en-GB // English in Great Britain. Enabled by Default -//#define MY_LANGUAGE es-ES // Spanish in Spain -//#define MY_LANGUAGE fr-FR // French in France -//#define MY_LANGUAGE he-HE // Hebrew in Israel -//#define MY_LANGUAGE hu-HU // Hungarian in Hungary -//#define MY_LANGUAGE it-IT // Italian in Italy -//#define MY_LANGUAGE ko-KO // Korean in Korea -//#define MY_LANGUAGE nl-NL // Dutch in the Netherlands -//#define MY_LANGUAGE pl-PL // Polish in Poland -//#define MY_LANGUAGE pt-BR // Portuguese in Brazil -//#define MY_LANGUAGE pt-PT // Portuguese in Portugal -//#define MY_LANGUAGE ro-RO // Romanian in Romania -//#define MY_LANGUAGE ru-RU // Russian in Russia -//#define MY_LANGUAGE sk-SK // Slovak in Slovakia -//#define MY_LANGUAGE sv-SE // Swedish in Sweden -//#define MY_LANGUAGE tr-TR // Turkish in Turkey -//#define MY_LANGUAGE uk-UA // Ukrainian in Ukraine -//#define MY_LANGUAGE zh-CN // Chinese (Simplified) in China -//#define MY_LANGUAGE zh-TW // Chinese (Traditional) in Taiwan +//#define MY_LANGUAGE bg_BG // Bulgarian in Bulgaria +//#define MY_LANGUAGE cs_CZ // Czech in Czech +//#define MY_LANGUAGE de_DE // German in Germany +//#define MY_LANGUAGE el_GR // Greek in Greece +//#define MY_LANGUAGE en_GB // English in Great Britain. Enabled by Default +//#define MY_LANGUAGE es_ES // Spanish in Spain +//#define MY_LANGUAGE fr_FR // French in France +//#define MY_LANGUAGE he_HE // Hebrew in Israel +//#define MY_LANGUAGE hu_HU // Hungarian in Hungary +//#define MY_LANGUAGE it_IT // Italian in Italy +//#define MY_LANGUAGE ko_KO // Korean in Korea +//#define MY_LANGUAGE nl_NL // Dutch in the Netherlands +//#define MY_LANGUAGE pl_PL // Polish in Poland +//#define MY_LANGUAGE pt_BR // Portuguese in Brazil +//#define MY_LANGUAGE pt_PT // Portuguese in Portugal +//#define MY_LANGUAGE ro_RO // Romanian in Romania +//#define MY_LANGUAGE ru_RU // Russian in Russia +//#define MY_LANGUAGE sk_SK // Slovak in Slovakia +//#define MY_LANGUAGE sv_SE // Swedish in Sweden +//#define MY_LANGUAGE tr_TR // Turkish in Turkey +//#define MY_LANGUAGE uk_UA // Ukrainian in Ukraine +//#define MY_LANGUAGE zh_CN // Chinese (Simplified) in China +//#define MY_LANGUAGE zh_TW // Chinese (Traditional) in Taiwan // -- Wifi Config tools --------------------------- #define WIFI_SOFT_AP_CHANNEL 1 // Soft Access Point Channel number between 1 and 13 as used by Wifi Manager web GUI @@ -365,6 +382,11 @@ // Full documentation here: https://github.com/arendst/Tasmota/wiki/AWS-IoT // #define USE_4K_RSA // Support 4096 bits certificates, instead of 2048 +// -- Telegram Protocol --------------------------- +//#define USE_TELEGRAM // Support for Telegram protocol (+49k code, +7.0k mem and +4.8k additional during connection handshake) + #define USE_TELEGRAM_FINGERPRINT "\xB2\x72\x47\xA6\x69\x8C\x3C\x69\xF9\x58\x6C\xF3\x60\x02\xFB\x83\xFA\x8B\x1F\x23" // Telegram api.telegram.org TLS public key fingerpring +// #define USE_MQTT_TLS_CA_CERT // Use certificate instead of fingerprint + // -- KNX IP Protocol ----------------------------- //#define USE_KNX // Enable KNX IP Protocol Support (+9.4k code, +3k7 mem) #define USE_KNX_WEB_MENU // Enable KNX WEB MENU (+8.3k code, +144 mem) @@ -389,23 +411,32 @@ #define USE_SUNRISE // Add support for Sunrise and sunset tools (+16k) #define SUNRISE_DAWN_ANGLE DAWN_NORMAL // Select desired Dawn Angle from (DAWN_NORMAL, DAWN_CIVIL, DAWN_NAUTIC, DAWN_ASTRONOMIC) +// -- Ping ---------------------------------------- +// #define USE_PING // Enable Ping command (+2k code) + +// -- Compression --------------------------------- +#define USE_UNISHOX_COMPRESSION // Add support for string compression in Rules or Scripts + // -- Rules or Script ---------------------------- -// Select none or only one of the below defines +// Select none or only one of the below defines USE_RULES or USE_SCRIPT #define USE_RULES // Add support for rules (+8k code) +// #define USE_EXPRESSION // Add support for expression evaluation in rules (+3k2 code, +64 bytes mem) +// #define SUPPORT_IF_STATEMENT // Add support for IF statement in rules (+4k2 code, -332 bytes mem) + //#define USE_SCRIPT // Add support for script (+17k code) //#define USE_SCRIPT_FATFS 4 // Script: Add FAT FileSystem Support -// #define USE_EXPRESSION // Add support for expression evaluation in rules (+3k2 code, +64 bytes mem) -// #define SUPPORT_IF_STATEMENT // Add support for IF statement in rules (+4k2 code, -332 bytes mem) // #define SUPPORT_MQTT_EVENT // Support trigger event with MQTT subscriptions (+3k5 code) // -- Optional modules ---------------------------- -//#define ROTARY_V1 // Add support for MI Desk Lamp +#define ROTARY_V1 // Add support for Rotary Encoder as used in MI Desk Lamp (+0k8 code) + #define ROTARY_MAX_STEPS 10 // Rotary step boundary #define USE_SONOFF_RF // Add support for Sonoff Rf Bridge (+3k2 code) #define USE_RF_FLASH // Add support for flashing the EFM8BB1 chip on the Sonoff RF Bridge. C2CK must be connected to GPIO4, C2D to GPIO5 on the PCB (+2k7 code) #define USE_SONOFF_SC // Add support for Sonoff Sc (+1k1 code) #define USE_TUYA_MCU // Add support for Tuya Serial MCU #define TUYA_DIMMER_ID 0 // Default dimmer Id +// #define USE_TUYA_TIME // Add support for Set Time in Tuya MCU #define USE_ARMTRONIX_DIMMERS // Add support for Armtronix Dimmers (+1k4 code) #define USE_PS_16_DZ // Add support for PS-16-DZ Dimmer (+2k code) #define USE_SONOFF_IFAN // Add support for Sonoff iFan02 and iFan03 (+2k code) @@ -416,10 +447,12 @@ #define USE_EXS_DIMMER // Add support for ES-Store WiFi Dimmer (+1k5 code) // #define EXS_MCU_CMNDS // Add command to send MCU commands (+0k8 code) //#define USE_HOTPLUG // Add support for sensor HotPlug -#define USE_DEVICE_GROUPS // Add support for device groups (+5k code) +#define USE_DEVICE_GROUPS // Add support for device groups (+5k5 code) + #define DEVICE_GROUPS_ADDRESS 239,255,250,250 // Device groups multicast address + #define DEVICE_GROUPS_PORT 4447 // Device groups multicast port #define USE_DEVICE_GROUPS_SEND // Add support for the DevGroupSend command (+0k6 code) -#define USE_PWM_DIMMER // Add support for MJ-SD01/acenx/NTONPOWER PWM dimmers (+2k5 code) - #define USE_PWM_DIMMER_REMOTE // Add support for remote switches to PWM Dimmer, also adds device groups support (+1k code plus device groups size) +#define USE_PWM_DIMMER // Add support for MJ-SD01/acenx/NTONPOWER PWM dimmers (+2k2 code, DGR=0k4) + #define USE_PWM_DIMMER_REMOTE // Add support for remote switches to PWM Dimmer (requires USE_DEVICE_GROUPS) (+0k9 code) //#define USE_KEELOQ // Add support for Jarolift rollers by Keeloq algorithm (+4k5 code) #define USE_SONOFF_D1 // Add support for Sonoff D1 Dimmer (+0k7 code) @@ -433,6 +466,8 @@ #define USE_SM2135 // Add support for SM2135 RGBCW led control as used in Action LSC (+0k6 code) #define USE_SONOFF_L1 // Add support for Sonoff L1 led control #define USE_ELECTRIQ_MOODL // Add support for ElectriQ iQ-wifiMOODL RGBW LED controller (+0k3 code) +#define USE_LIGHT_PALETTE // Add support for color palette (+0k7 code) +#define USE_DGR_LIGHT_SEQUENCE // Add support for device group light sequencing (requires USE_DEVICE_GROUPS) (+0k2 code) // -- Counter input ------------------------------- #define USE_COUNTER // Enable inputs as counter (+0k8 code) @@ -468,6 +503,10 @@ // #define USE_SI1145 // [I2cDriver19] Enable SI1145/46/47 sensor (I2C address 0x60) (+1k code) // #define USE_LM75AD // [I2cDriver20] Enable LM75AD sensor (I2C addresses 0x48 - 0x4F) (+0k5 code) // #define USE_APDS9960 // [I2cDriver21] Enable APDS9960 Proximity Sensor (I2C address 0x39). Disables SHT and VEML6070 (+4k7 code) + #define USE_APDS9960_GESTURE // Enable APDS9960 Gesture feature (+2k code) + #define USE_APDS9960_PROXIMITY // Enable APDS9960 Proximity feature (>50 code) + #define USE_APDS9960_COLOR // Enable APDS9960 Color feature (+0.8k code) + #define USE_APDS9960_STARTMODE 0 // Default to enable Gesture mode // #define USE_MCP230xx // [I2cDriver22] Enable MCP23008/MCP23017 - Must define I2C Address in #define USE_MCP230xx_ADDR below - range 0x20 - 0x27 (+4k7 code) // #define USE_MCP230xx_ADDR 0x20 // Enable MCP23008/MCP23017 I2C Address to use (Must be within range 0x20 through 0x26 - set according to your wired setup) // #define USE_MCP230xx_OUTPUT // Enable MCP23008/MCP23017 OUTPUT support through sensor29 commands (+1k5 code) @@ -500,6 +539,11 @@ // #define WEMOS_MOTOR_V1_FREQ 1000 // Default frequency // #define USE_HDC1080 // [I2cDriver45] Enable HDC1080 temperature/humidity sensor (I2C address 0x40) (+1k5 code) // #define USE_IAQ // [I2cDriver46] Enable iAQ-core air quality sensor (I2C address 0x5a) (+0k6 code) +// #define USE_AS3935 // [I2cDriver48] Enable AS3935 Franklin Lightning Sensor (I2C address 0x03) (+5k4 code) +// #define USE_VEML6075 // [I2cDriver49] Enable VEML6075 UVA/UVB/UVINDEX Sensor (I2C address 0x10) (+2k1 code) +// #define USE_VEML7700 // [I2cDriver50] Enable VEML7700 Ambient Light sensor (I2C addresses 0x10) (+4k5 code) +// #define USE_MCP9808 // [I2cDriver51] Enable MCP9808 temperature sensor (I2C addresses 0x18 - 0x1F) (+0k9 code) +// #define USE_HP303B // [I2cDriver52] Enable HP303B temperature and pressure sensor (I2C address 0x76 or 0x77) (+6k2 code) // #define USE_DISPLAY // Add I2C Display Support (+2k code) #define USE_DISPLAY_MODES1TO5 // Enable display mode 1 to 5 in addition to mode 0 @@ -549,6 +593,7 @@ #define STARTING_OFFSET 30 // Turn on NovaSDS XX-seconds before tele_period is reached //#define USE_HPMA // Add support for Honeywell HPMA115S0 particle concentration sensor (+1k4) #define USE_SERIAL_BRIDGE // Add support for software Serial Bridge (+0k8 code) +//#define USE_TCP_BRIDGE // Add support for Serial to TCP bridge (+1.3k code) //#define USE_MP3_PLAYER // Use of the DFPlayer Mini MP3 Player RB-DFR-562 commands: play, volume and stop #define MP3_VOLUME 10 // Set the startup volume on init, the range can be 0..30(max) //#define USE_AZ7798 // Add support for AZ-Instrument 7798 CO2 datalogger (+1k6 code) @@ -560,8 +605,12 @@ //#define USE_IBEACON // Add support for bluetooth LE passive scan of ibeacon devices (uses HM17 module) //#define USE_GPS // Add support for GPS and NTP Server for becoming Stratus 1 Time Source (+3k1 code, +132 bytes RAM) // #define USE_FLOG // Add support for GPS logging in OTA's Flash (Experimental) (+2k9 code, +8 bytes RAM) -//#define USE_HM10 // Add support for HM-10 as a BLE-bridge for the LYWSD03 (+5k1 code) +//#define USE_HM10 // (ESP8266 only) Add support for HM-10 as a BLE-bridge (+9k3 code) //#define USE_HRXL // Add support for MaxBotix HRXL-MaxSonar ultrasonic range finders (+0k7) +//#define USE_TASMOTA_CLIENT // Add support for Arduino Uno/Pro Mini via serial interface including flashing (+2k6 code, 64 mem) + #define USE_TASMOTA_CLIENT_FLASH_SPEED 57600 // Usually 57600 for 3.3V variants and 115200 for 5V variants + #define USE_TASMOTA_CLIENT_SERIAL_SPEED 57600 // Depends on the sketch that is running on the Uno/Pro Mini +//#define USE_OPENTHERM // Add support for OpenTherm (+15k code) // -- Power monitoring sensors -------------------- #define USE_ENERGY_MARGIN_DETECTION // Add support for Energy Margin detection (+1k6 code) @@ -584,16 +633,20 @@ //#define USE_LE01MR // Add support for F&F LE-01MR Modbus energy monitor (+1k code) #define LE01MR_SPEED 9600 // LE-01MR modbus baudrate (default: 9600) #define LE01MR_ADDR 1 // LE-01MR modbus address (default: 0x01) +#define USE_BL0940 // Add support for BL0940 Energy monitor as used in Blitzwolf SHP-10 (+1k6 code) +//#define USE_TELEINFO // Add support for Teleinfo via serial RX interface (+5k2 code, +168 RAM + SmartMeter LinkedList Values RAM) +// #define USE_TELEINFO_STANDARD // Use standard mode (9600 bps) else it's historical mode (1200 bps) // -- Low level interface devices ----------------- #define USE_DHT // Add support for DHT11, AM2301 (DHT21, DHT22, AM2302, AM2321) and SI7021 Temperature and Humidity sensor (1k6 code) -//#define USE_MAX31855 // Add support for MAX31855 K-Type thermocouple sensor using softSPI +//#define USE_MAX31855 // Add support for MAX31855/MAX6675 K-Type thermocouple sensor using softSPI //#define USE_MAX31865 // Add support for MAX31865 RTD sensors using softSPI - #define MAX31865_PTD_WIRES 2 // PTDs come in several flavors. Pick yours - #define MAX31865_PTD_RES 100 // Nominal PTD resistance at 0°C (100Ω for a PT100, 1000Ω for a PT1000, YMMV!) - #define MAX31865_REF_RES 430 // Reference resistor (Usually 430Ω for a PT100, 4300Ω for a PT1000) - #define MAX31865_PTD_BIAS 0 // To calibrate your not-so-good PTD + #define MAX31865_PTD_WIRES 2 // PTDs come in several flavors. Pick yours + #define MAX31865_PTD_RES 100 // Nominal PTD resistance at 0°C (100Ω for a PT100, 1000Ω for a PT1000, YMMV!) + #define MAX31865_REF_RES 430 // Reference resistor (Usually 430Ω for a PT100, 4300Ω for a PT1000) + #define MAX31865_PTD_BIAS 0 // To calibrate your not-so-good PTD +//#define USE_LMT01 // Add support for TI LMT01 temperature sensor, count pulses on single GPIO (+0k5 code) // -- IR Remote features - all protocols from IRremoteESP8266 -------------------------- // IR Full Protocols mode is activated through platform.io only. @@ -618,13 +671,21 @@ // -- Zigbee interface ---------------------------- //#define USE_ZIGBEE // Enable serial communication with Zigbee CC2530 flashed with ZNP (+49k code, +3k mem) + #define USE_ZIGBEE_ZNP // Enable ZNP protocol, needed for CC2530 based devices + // #define USE_ZIGBEE_EZSP // [EXPERIMENTAL - DO NOT USE] Enable EZSP protocol, needed for EFR32 EmberZNet based devices, like Sonoff Zigbee bridge + // Note: USE_ZIGBEE_ZNP and USE_ZIGBEE_EZSP are mutually incompatible, you must select exactly one #define USE_ZIGBEE_PANID 0x1A63 // arbitrary PAN ID for Zigbee network, must be unique in the home + // if PANID == 0xFFFF, then the device will act as a Zigbee router, the parameters below are ignored + // if PANID == 0xFFFE, then the device will act as a Zigbee end-device (non-router), the parameters below are ignored #define USE_ZIGBEE_EXTPANID 0xCCCCCCCCCCCCCCCCL // arbitrary extended PAN ID #define USE_ZIGBEE_CHANNEL 11 // Zigbee Channel (11-26) + #define USE_ZIGBEE_TXRADIO_DBM 20 // Tx Radio power in dBm (only for EZSP, EFR32 can go up to 20 dBm) #define USE_ZIGBEE_PRECFGKEY_L 0x0F0D0B0907050301L // note: changing requires to re-pair all devices #define USE_ZIGBEE_PRECFGKEY_H 0x0D0C0A0806040200L // note: changing requires to re-pair all devices - #define USE_ZIGBEE_PERMIT_JOIN false // don't allow joining by default + #define USE_ZIGBEE_COALESCE_ATTR_TIMER 350 // timer to coalesce attribute values (in ms) + #define USE_ZIGBEE_MODELID "Tasmota Z2T" // reported "ModelId" (cluster 0000 / attribute 0005) + #define USE_ZIGBEE_MANUFACTURER "Tasmota" // reported "Manufacturer" (cluster 0000 / attribute 0004) // -- Other sensors/drivers ----------------------- @@ -638,6 +699,8 @@ //#define USE_TX20_WIND_SENSOR // Add support for La Crosse TX20 anemometer (+2k6/0k8 code) //#define USE_TX23_WIND_SENSOR // Add support for La Crosse TX23 anemometer (+2k7/1k code) +//#define USE_WINDMETER // Add support for analog anemometer (+2k2 code) + //#define USE_RC_SWITCH // Add support for RF transceiver using library RcSwitch (+2k7 code, 460 iram) //#define USE_RF_SENSOR // Add support for RF sensor receiver (434MHz or 868MHz) (+0k8 code) @@ -647,12 +710,66 @@ //#define USE_HRE // Add support for Badger HR-E Water Meter (+1k4 code) //#define USE_A4988_STEPPER // Add support for A4988/DRV8825 stepper-motor-driver-circuit (+10k5 code) -//#define USE_TASMOTA_SLAVE // Add support for Arduino Uno/Pro Mini via serial interface including flashing (+2k6 code, 64 mem) - #define USE_TASMOTA_SLAVE_FLASH_SPEED 57600 // Usually 57600 for 3.3V variants and 115200 for 5V variants - #define USE_TASMOTA_SLAVE_SERIAL_SPEED 57600 // Depends on the sketch that is running on the Uno/Pro Mini +// -- Thermostat control ---------------------------- +//#define USE_THERMOSTAT // Add support for Thermostat + #define THERMOSTAT_CONTROLLER_OUTPUTS 1 // Number of outputs to be controlled independently + #define THERMOSTAT_SENSOR_NAME "DS18B20" // Name of the local sensor to be used + #define THERMOSTAT_RELAY_NUMBER 1 // Default output relay number for the first controller (+i for following ones) + #define THERMOSTAT_SWITCH_NUMBER 1 // Default input switch number for the first controller (+i for following ones) + #define THERMOSTAT_TIME_ALLOW_RAMPUP 300 // Default time after last target update to allow ramp-up controller phase in minutes + #define THERMOSTAT_TIME_RAMPUP_MAX 960 // Default time maximum ramp-up controller duration in minutes + #define THERMOSTAT_TIME_RAMPUP_CYCLE 30 // Default time ramp-up cycle in minutes + #define THERMOSTAT_TIME_SENS_LOST 30 // Maximum time w/o sensor update to set it as lost in minutes + #define THERMOSTAT_TEMP_SENS_NUMBER 1 // Default temperature sensor number + #define THERMOSTAT_TIME_MANUAL_TO_AUTO 60 // Default time without input switch active to change from manual to automatic in minutes + #define THERMOSTAT_TIME_RESET 12000 // Default reset time of the PI controller in seconds + #define THERMOSTAT_TIME_PI_CYCLE 30 // Default cycle time for the thermostat controller in minutes + #define THERMOSTAT_TIME_MAX_ACTION 20 // Default maximum thermostat time per cycle in minutes + #define THERMOSTAT_TIME_MIN_ACTION 4 // Default minimum thermostat time per cycle in minutes + #define THERMOSTAT_TIME_MIN_TURNOFF_ACTION 3 // Default minimum turnoff time in minutes, below it the thermostat will be held on + #define THERMOSTAT_PROP_BAND 4 // Default proportional band of the PI controller in degrees celsius + #define THERMOSTAT_TEMP_RESET_ANTI_WINDUP 8 // Default range where reset antiwindup is disabled, in tenths of degrees celsius + #define THERMOSTAT_TEMP_HYSTERESIS 1 // Default range hysteresis for temperature PI controller, in tenths of degrees celsius + #define THERMOSTAT_TEMP_FROST_PROTECT 40 // Default minimum temperature for frost protection, in tenths of degrees celsius + #define THERMOSTAT_TEMP_RAMPUP_DELTA_IN 4 // Default minimum delta temperature to target to get into rampup mode, in tenths of degrees celsius + #define THERMOSTAT_TEMP_RAMPUP_DELTA_OUT 2 // Default minimum delta temperature to target to get out of the rampup mode, in tenths of degrees celsius + #define THERMOSTAT_TEMP_PI_RAMPUP_ACC_E 200 // Default accumulated error when switching from ramp-up controller to PI in hundreths of degrees celsius + #define THERMOSTAT_TIME_OUTPUT_DELAY 180 // Default output delay between state change and real actuation event (f.i. valve open/closed) + #define THERMOSTAT_TEMP_INIT 180 // Default init target temperature for the thermostat controller + #define THERMOSTAT_TIME_MAX_OUTPUT_INCONSIST 3 // Default maximum time where the input and the outpus shall differ (for diagnostic) in minutes + #define THERMOSTAT_TIME_MAX_AUTOTUNE 21600 // Maximum time for the PI autotune function to complete in seconds + #define THERMOSTAT_DUTYCYCLE_AUTOTUNE 35 // Default duty cycle (in % over PI cycle time) for the step response of the autotune PI function + #define THERMOSTAT_PEAKNUMBER_AUTOTUNE 8 // Default number of peak temperatures (max or min) to be used for the autotune PI function + #define THERMOSTAT_TEMP_BAND_NO_PEAK_DET 1 // Default temperature band in thenths of degrees celsius within no peak will be detected + #define THERMOSTAT_TIME_STD_DEV_PEAK_DET_OK 10 // Default standard deviation in minutes of the oscillation periods within the peak detection is successful + +// -- Prometheus exporter --------------------------- +//#define USE_PROMETHEUS // Add support for https://prometheus.io/ metrics exporting over HTTP /metrics endpoint // -- End of general directives ------------------- +/*********************************************************************************************\ + * ESP32 only features +\*********************************************************************************************/ + +#ifdef ESP32 + +//#define USE_ETHERNET // Add support for ethernet (Currently fixed for Olimex ESP32-PoE) + // Olimex ESP32-PoE + #define ETH_TYPE 0 // [EthType] 0 = ETH_PHY_LAN8720, 1 = ETH_PHY_TLK110, 2 = ETH_PHY_IP101 + #define ETH_ADDR 0 // [EthAddress] 0 = PHY0 .. 31 = PHY31 + #define ETH_CLKMODE 3 // [EthClockMode] 0 = ETH_CLOCK_GPIO0_IN, 1 = ETH_CLOCK_GPIO0_OUT, 2 = ETH_CLOCK_GPIO16_OUT, 3 = ETH_CLOCK_GPIO17_OUT + // wESP32-PoE +// #define ETH_TYPE 0 // [EthType] 0 = ETH_PHY_LAN8720, 1 = ETH_PHY_TLK110, 2 = ETH_PHY_IP101 +// #define ETH_ADDR 0 // [EthAddress] 0 = PHY0 .. 31 = PHY31 +// #define ETH_CLKMODE 0 // [EthClockMode] 0 = ETH_CLOCK_GPIO0_IN, 1 = ETH_CLOCK_GPIO0_OUT, 2 = ETH_CLOCK_GPIO16_OUT, 3 = ETH_CLOCK_GPIO17_OUT + +//#define USE_SPI // Add support for hardware SPI +//#define USE_MI_ESP32 // Add support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) +//#define USE_WEBCAM // Add support for webcam + +#endif + /*********************************************************************************************\ * Debug features \*********************************************************************************************/ @@ -692,4 +809,16 @@ #error "Select either USE_RULES or USE_SCRIPT. They can't both be used at the same time" #endif +/*********************************************************************************************\ + * Post-process compile options for TLS +\*********************************************************************************************/ + +#if defined(USE_MQTT_TLS) || defined(USE_SENDMAIL) || defined(USE_TELEGRAM) + #define USE_TLS // flag indicates we need to include TLS code + + #if defined(USE_MQTT_AWS_IOT) || defined(USE_TELEGRAM) + #define USE_MQTT_TLS_FORCE_EC_CIPHER // AWS IoT and TELEGRAM require EC Cipher + #endif +#endif + #endif // _MY_USER_CONFIG_H_ diff --git a/tasmota/sendemail.h b/tasmota/sendemail.h index 2422ad91f..d95ba9311 100644 --- a/tasmota/sendemail.h +++ b/tasmota/sendemail.h @@ -8,7 +8,11 @@ #include //#include +#ifdef ESP8266 #include "WiFiClientSecureLightBearSSL.h" +#else +#include +#endif class SendEmail { @@ -20,18 +24,24 @@ class SendEmail const int timeout; const bool ssl; const int auth_used; +#ifdef ESP8266 #if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_2) WiFiClient* client; #else // use bear ssl BearSSL::WiFiClientSecure_light *client; #endif +#else + WiFiClient *client; +#endif + String readClient(); void a3_to_a4(unsigned char * a4, unsigned char * a3); int base64_encode(char *output, const char *input, int inputLen); public: SendEmail(const String& host, const int port, const String& user, const String& passwd, const int timeout, const int auth_used); bool send(const String& from, const String& to, const String& subject, const char *msg); + void send_message_txt(char *msg); ~SendEmail() {client->stop(); delete client;} }; diff --git a/tasmota/sendemail.ino b/tasmota/sendemail.ino index 70571b5d2..0a4c4de0e 100644 --- a/tasmota/sendemail.ino +++ b/tasmota/sendemail.ino @@ -1,5 +1,7 @@ #ifdef USE_SENDMAIL +#ifndef USE_ESP32MAIL + #include "sendemail.h" // enable serial debugging @@ -26,6 +28,8 @@ #define SEND_MAIL_MINRAM 12*1024 #endif +void script_send_email_body(void(*func)(char *)); + #define xPSTR(a) a uint16_t SendMail(char *buffer) { @@ -174,12 +178,19 @@ exit: return status; } -void script_send_email_body(BearSSL::WiFiClientSecure_light *client); +#ifdef ESP8266 +WiFiClient *g_client; SendEmail::SendEmail(const String& host, const int port, const String& user, const String& passwd, const int timeout, const int auth_used) : host(host), port(port), user(user), passwd(passwd), timeout(timeout), ssl(ssl), auth_used(auth_used), client(new BearSSL::WiFiClientSecure_light(1024,1024)) { } +#else +WiFiClient *g_client; +SendEmail::SendEmail(const String& host, const int port, const String& user, const String& passwd, const int timeout, const int auth_used) : + host(host), port(port), user(user), passwd(passwd), timeout(timeout), ssl(ssl), auth_used(auth_used), client(new WiFiClientSecure()) { +} +#endif String SendEmail::readClient() { delay(0); @@ -341,7 +352,8 @@ String buffer; #ifdef USE_SCRIPT if (*msg=='*' && *(msg+1)==0) { - script_send_email_body(client); + g_client=client; + script_send_email_body(xsend_message_txt); } else { client->println(msg); } @@ -365,5 +377,289 @@ exit: return status; } +void xsend_message_txt(char *msg) { + g_client->println(msg); +} +#else + +/* + * Created by K. Suwatchai (Mobizt) + * + * Email: k_suwatchai@hotmail.com + * + * Github: https://github.com/mobizt + * + * Copyright (c) 2019 mobizt + * +*/ + + +//To use send Email for Gmail to port 465 (SSL), less secure app option should be enabled. https://myaccount.google.com/lesssecureapps?pli=1 + +//To receive Email for Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + +#include "ESP32_MailClient.h" +#include "SD.h" + +//For demo only +//#include "image.h" + +#ifndef SEND_MAIL32_MINRAM +#define SEND_MAIL32_MINRAM 30*1024 +#endif + +void script_send_email_body(void(*func)(char *)); + +#define xPSTR(a) a +//The Email Sending data object contains config and data to send +SMTPData smtpData; + +//Callback function to get the Email sending status +//void sendCallback(SendStatus info); +//#define DEBUG_EMAIL_PORT + +uint16_t SendMail(char *buffer) { + char *params,*oparams; + const char *mserv; + uint16_t port; + const char *user; + const char *pstr; + const char *passwd; + const char *from; + const char *to; + const char *subject; + const char *cmd; + uint16_t status=1; + uint16_t blen; + char *endcmd; + + // return if not enough memory + uint32_t mem=ESP.getFreeHeap(); + AddLog_P2(LOG_LEVEL_INFO, PSTR("heap: %d"),mem); + if (mem"); + + //Set the storage types to read the attach files (SD is default) + //smtpData.setFileStorageType(MailClientStorageType::SPIFFS); +#if defined (USE_SCRIPT) && defined(USE_SCRIPT_FATFS) + smtpData.setFileStorageType(MailClientStorageType::SD); +#endif + //smtpData.setSendCallback(sendCallback); + + //Start sending Email, can be set callback function to track the status + if (!MailClient.sendMail(smtpData)) { + //Serial.println("Error sending Email, " + MailClient.smtpErrorReason()); + AddLog_P2(LOG_LEVEL_INFO, PSTR("Error sending Email, %s"), MailClient.smtpErrorReason()); + + } else { + status=0; + } + //Clear all data from Email object to free memory + smtpData.empty(); + + exit: + if (oparams) free(oparams); + return status; +} + + +void send_message_txt(char *txt) { + if (*txt=='&') { + txt++; + smtpData.addAttachFile(txt); + } else if (*txt=='$') { + txt++; +#if defined(ESP32) && defined(USE_WEBCAM) + uint32_t cnt; + uint8_t *buff; + uint32_t len,picmax; + picmax=WcGetPicstore(-1,0); + cnt=*txt&7; + if (cnt<1 || cnt>picmax) cnt=1; + len=WcGetPicstore(cnt-1,&buff); + if (len) { + char str[12]; + sprintf(str,"img_%1d.jpg",cnt+1); + smtpData.addAttachData(str, "image/jpg",buff,len); + } +#endif + } else { + smtpData.addMessage(txt); + } +} + +/* +//Callback function to get the Email sending status +void sendCallback(SendStatus msg) +{ + //Print the current status + Serial.println(msg.info()); + + //Do something when complete + if (msg.success()) + { + Serial.println("----------------"); + } +} +*/ +#endif + #endif // USE_SENDMAIL diff --git a/tasmota/settings.h b/tasmota/settings.h index 23a1889c0..cc0fd9bf3 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -86,7 +86,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu uint32_t energy_weekend : 1; // bit 20 (v6.6.0.8) - CMND_TARIFF uint32_t dds2382_model : 1; // bit 21 (v6.6.0.14) - SetOption71 - Select different Modbus registers for Active Energy (#6531) uint32_t hardware_energy_total : 1; // bit 22 (v6.6.0.15) - SetOption72 - Enable hardware energy total counter as reference (#6561) - uint32_t ex_cors_enabled : 1; // bit 23 (v7.0.0.1) - SetOption73 - Enable HTTP CORS + uint32_t mqtt_buttons : 1; // bit 23 (v8.2.0.3) - SetOption73 - Detach buttons from relays and enable MQTT action state for multipress uint32_t ds18x20_internal_pullup : 1; // bit 24 (v7.0.0.1) - SetOption74 - Enable internal pullup for single DS18x20 sensor uint32_t grouptopic_mode : 1; // bit 25 (v7.0.0.1) - SetOption75 - GroupTopic replaces %topic% (0) or fixed topic cmnd/grouptopic (1) uint32_t bootcount_update : 1; // bit 26 (v7.0.0.4) - SetOption76 - Enable incrementing bootcount when deepsleep is enabled @@ -107,18 +107,18 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu uint32_t device_groups_enabled : 1; // bit 3 (v8.1.0.9) - SetOption85 - Enable Device Groups uint32_t led_timeout : 1; // bit 4 (v8.1.0.9) - SetOption86 - PWM Dimmer Turn brightness LED's off 5 seconds after last change uint32_t powered_off_led : 1; // bit 5 (v8.1.0.9) - SetOption87 - PWM Dimmer Turn red LED on when powered off - uint32_t remote_device_mode : 1; // bit 6 (v8.1.0.9) - SetOption88 - PWM Dimmer Buttons control remote devices + uint32_t remote_device_mode : 1; // bit 6 (v8.1.0.9) - SetOption88 - Enable relays in separate device groups/PWM Dimmer Buttons control remote devices uint32_t zigbee_distinct_topics : 1; // bit 7 (v8.1.0.10) - SetOption89 - Distinct MQTT topics per device for Zigbee (#7835) uint32_t only_json_message : 1; // bit 8 (v8.2.0.3) - SetOption90 - Disable non-json MQTT response uint32_t fade_at_startup : 1; // bit 9 (v8.2.0.3) - SetOption91 - Enable light fading at start/power on - uint32_t spare10 : 1; - uint32_t spare11 : 1; - uint32_t spare12 : 1; - uint32_t spare13 : 1; - uint32_t spare14 : 1; - uint32_t spare15 : 1; - uint32_t spare16 : 1; - uint32_t spare17 : 1; + uint32_t pwm_ct_mode : 1; // bit 10 (v8.2.0.4) - SetOption92 - Set PWM Mode from regular PWM to ColorTemp control (Xiaomi Philips ...) + uint32_t compress_rules_cpu : 1; // bit 11 (v8.2.0.6) - SetOption93 - Keep uncompressed rules in memory to avoid CPU load of uncompressing at each tick + uint32_t max6675 : 1; // bit 12 (v8.3.1.2) - SetOption94 - Implement simpler MAX6675 protocol instead of MAX31855 + uint32_t network_wifi : 1; // bit 13 (v8.3.1.3) - CMND_WIFI + uint32_t network_ethernet : 1; // bit 14 (v8.3.1.3) - CMND_ETHERNET + uint32_t tuyamcu_baudrate : 1; // bit 15 (v8.3.1.6) - SetOption97 - Set Baud rate for TuyaMCU serial communication (0 = 9600 or 1 = 115200) + uint32_t rotary_uses_rules : 1; // bit 16 (v8.3.1.6) - SetOption98 - Use rules instead of light control + uint32_t zerocross_dimmer : 1; // bit 17 (v8.3.1.4) = SetOption99 - Enable zerocross dimmer on PWM DIMMER uint32_t spare18 : 1; uint32_t spare19 : 1; uint32_t spare20 : 1; @@ -182,6 +182,35 @@ typedef union { }; } Timer; +typedef union { // Restricted by MISRA-C Rule 18.4 but so useful... + uint32_t data; + struct { + uint32_t stream : 1; + uint32_t mirror : 1; + uint32_t flip : 1; + uint32_t spare3 : 1; + uint32_t spare4 : 1; + uint32_t spare5 : 1; + uint32_t spare6 : 1; + uint32_t spare7 : 1; + uint32_t spare8 : 1; + uint32_t spare9 : 1; + uint32_t spare10 : 1; + uint32_t spare11 : 1; + uint32_t spare12 : 1; + uint32_t spare13 : 1; + uint32_t spare14 : 1; + uint32_t spare15 : 1; + uint32_t spare16 : 1; + uint32_t spare17 : 1; + uint32_t spare18 : 1; + uint32_t contrast : 3; + uint32_t brightness : 3; + uint32_t saturation : 3; + uint32_t resolution : 4; + }; +} WebCamCfg; + typedef union { uint16_t data; struct { @@ -203,14 +232,37 @@ typedef union { struct { uint8_t spare0 : 1; uint8_t spare1 : 1; - uint8_t spare2 : 1; - uint8_t spare3 : 1; - uint8_t bh1750_resolution : 2; // Sensor10 1,2,3 + uint8_t bh1750_2_resolution : 2; + uint8_t bh1750_1_resolution : 2; // Sensor10 1,2,3 uint8_t hx711_json_weight_change : 1; // Sensor34 8,x - Enable JSON message on weight change uint8_t mhz19b_abc_disable : 1; // Disable ABC (Automatic Baseline Correction for MHZ19(B) (0 = Enabled (default), 1 = Disabled with Sensor15 command) }; } SensorCfg1; +typedef union { + uint8_t data; + struct { + uint8_t nf_autotune : 1; // Autotune the NF Noise Level + uint8_t dist_autotune : 1; // Autotune Disturber on/off + uint8_t nf_autotune_both : 1; // Autotune over both Areas: INDOORS/OUDOORS + uint8_t mqtt_only_Light_Event : 1; // mqtt only if lightning Irq + uint8_t spare4 : 1; + uint8_t spare5 : 1; + uint8_t spare6 : 1; + uint8_t spare7 : 1; + }; +} As3935IntCfg; + +typedef union { + uint16_t data; + struct { + uint16_t nf_autotune_time : 4; // NF Noise Autotune Time + uint16_t dist_autotune_time : 4; // Disturber Autotune Time + uint16_t nf_autotune_min : 4; // Min Stages + uint16_t spare3 : 4; + }; +} As3935Param; + typedef struct { uint32_t usage1_kWhtotal; uint32_t usage2_kWhtotal; @@ -229,7 +281,7 @@ typedef struct { const uint32_t settings_text_size = 699; // Settings.text_pool[size] = Settings.display_model (2D2) - Settings.text_pool (017) const uint8_t MAX_TUYA_FUNCTIONS = 16; -struct SYSCFG { +struct { uint16_t cfg_holder; // 000 v6 header uint16_t cfg_size; // 002 unsigned long save_flag; // 004 @@ -334,8 +386,20 @@ struct SYSCFG { SysBitfield3 flag3; // 3A0 uint8_t switchmode[MAX_SWITCHES]; // 3A4 (6.0.0b - moved from 0x4CA) +#ifdef ESP8266 char ex_friendlyname[4][33]; // 3AC char ex_switch_topic[33]; // 430 +#else // ESP32 + myio my_gp; // 3AC - 2 x 40 bytes (ESP32) + mytmplt user_template; // 3FC - 2 x 37 bytes (ESP32) + uint8_t eth_type; // 446 + uint8_t eth_clk_mode; // 447 + + uint8_t free_esp32_448[4]; // 448 + + WebCamCfg webcam_config; // 44C + uint8_t eth_address; // 450 +#endif // ESP8266 - ESP32 char serial_delimiter; // 451 uint8_t seriallog_level; // 452 @@ -345,7 +409,13 @@ struct SYSCFG { uint8_t module; // 474 uint8_t ws_color[4][3]; // 475 uint8_t ws_width[3]; // 481 - myio my_gp; // 484 + +#ifdef ESP8266 + myio my_gp; // 484 - 17 bytes (ESP8266) +#else // ESP32 + uint8_t free_esp32_484[17]; // 484 +#endif // ESP8266 - ESP32 + uint8_t my_adc0; // 495 uint16_t light_pixels; // 496 uint8_t light_color[5]; // 498 @@ -399,7 +469,12 @@ struct SYSCFG { char user_template_name[15]; // 720 15 bytes - Backward compatibility since v8.2.0.3 - mytmplt user_template; // 72F 14 bytes +#ifdef ESP8266 + mytmplt user_template; // 72F 14 bytes (ESP8266) +#else // ESP32 + uint8_t free_esp32_72f[14]; // 72F +#endif // ESP8266 - ESP32 + uint8_t novasds_startingoffset; // 73D uint8_t web_color[18][3]; // 73E uint16_t display_width; // 774 @@ -437,6 +512,10 @@ struct SYSCFG { uint8_t shutter_position[MAX_SHUTTERS]; // E80 uint8_t shutter_startrelay[MAX_SHUTTERS]; // E84 uint8_t pcf8574_config[MAX_PCF8574]; // E88 + uint8_t ot_hot_water_setpoint; // E8C + uint8_t ot_boiler_setpoint; // E8D + uint8_t ot_flags; // E8E + uint8_t ledpwm_mask; // E8F uint16_t dimmer_hw_min; // E90 uint16_t dimmer_hw_max; // E92 uint32_t deepsleep; // E94 @@ -472,9 +551,30 @@ struct SYSCFG { int8_t hum_comp; // F08 uint8_t wifi_channel; // F09 uint8_t wifi_bssid[6]; // F0A + uint8_t as3935_sensor_cfg[5]; // F10 + As3935IntCfg as3935_functions; // F15 + As3935Param as3935_parameter; // F16 + uint64_t zb_ext_panid; // F18 + uint64_t zb_precfgkey_l; // F20 + uint64_t zb_precfgkey_h; // F28 + uint16_t zb_pan_id; // F30 + uint8_t zb_channel; // F32 + uint8_t zb_txradio_dbm; // F33 + uint16_t pms_wake_interval; // F34 + uint8_t config_version; // F36 + uint8_t windmeter_pulses_x_rot; // F37 + uint16_t windmeter_radius; // F38 + uint16_t windmeter_pulse_debounce; // F3A + int16_t windmeter_speed_factor; // F3C + uint8_t windmeter_tele_pchange; // F3E + uint8_t ledpwm_on; // F3F + uint8_t ledpwm_off; // F40 + uint8_t tcp_baudrate; // F41 + uint8_t fallback_module; // F42 - uint8_t free_f10[168]; // F10 + uint8_t free_f43[117]; // F43 - Decrement if adding new Setting variables just above and below + // Only 32 bit boundary variables below uint16_t pulse_counter_debounce_low; // FB8 uint16_t pulse_counter_debounce_high; // FBA uint32_t keeloq_master_msb; // FBC @@ -491,13 +591,17 @@ struct SYSCFG { uint32_t cfg_crc32; // FFC } Settings; -struct RTCRBT { +typedef struct { uint16_t valid; // 280 (RTC memory offset 100 - sizeof(RTCRBT)) uint8_t fast_reboot_count; // 282 uint8_t free_003[1]; // 283 -} RtcReboot; +} TRtcReboot; +TRtcReboot RtcReboot; +#ifdef ESP32 +RTC_NOINIT_ATTR TRtcReboot RtcDataReboot; +#endif -struct RTCMEM { +typedef struct { uint16_t valid; // 290 (RTC memory offset 100) uint8_t oswatch_blocked_loop; // 292 uint8_t ota_loader; // 293 @@ -513,7 +617,11 @@ struct RTCMEM { uint8_t free_022[22]; // 2D6 // 2EC - 2FF free locations -} RtcSettings; +} TRtcSettings; +TRtcSettings RtcSettings; +#ifdef ESP32 +RTC_NOINIT_ATTR TRtcSettings RtcDataSettings; +#endif struct TIME_T { uint8_t second; @@ -542,13 +650,14 @@ struct XDRVMAILBOX { } XdrvMailbox; #ifdef USE_SHUTTER -const uint8_t MAX_RULES_FLAG = 10; // Number of bits used in RulesBitfield (tricky I know...) +const uint8_t MAX_RULES_FLAG = 11; // Number of bits used in RulesBitfield (tricky I know...) #else -const uint8_t MAX_RULES_FLAG = 8; // Number of bits used in RulesBitfield (tricky I know...) +const uint8_t MAX_RULES_FLAG = 9; // Number of bits used in RulesBitfield (tricky I know...) #endif // USE_SHUTTER typedef union { // Restricted by MISRA-C Rule 18.4 but so useful... uint16_t data; // Allow bit manipulation struct { + uint16_t system_init : 1; // Changing layout here needs adjustments in xdrv_10_rules.ino too uint16_t system_boot : 1; uint16_t time_init : 1; uint16_t time_set : 1; @@ -559,7 +668,6 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu uint16_t http_init : 1; uint16_t shutter_moved : 1; uint16_t shutter_moving : 1; - uint16_t spare10 : 1; uint16_t spare11 : 1; uint16_t spare12 : 1; uint16_t spare13 : 1; @@ -571,10 +679,10 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu typedef union { uint8_t data; struct { - uint8_t wifi_down : 1; + uint8_t network_down : 1; uint8_t mqtt_down : 1; - uint8_t spare02 : 1; - uint8_t spare03 : 1; + uint8_t wifi_down : 1; + uint8_t eth_down : 1; uint8_t spare04 : 1; uint8_t spare05 : 1; uint8_t spare06 : 1; diff --git a/tasmota/settings.ino b/tasmota/settings.ino index 2a7e8ce31..1d7ab6d04 100644 --- a/tasmota/settings.ino +++ b/tasmota/settings.ino @@ -30,7 +30,7 @@ uint32_t GetRtcSettingsCrc(void) uint32_t crc = 0; uint8_t *bytes = (uint8_t*)&RtcSettings; - for (uint32_t i = 0; i < sizeof(RTCMEM); i++) { + for (uint32_t i = 0; i < sizeof(RtcSettings); i++) { crc += bytes[i]*(i+1); } return crc; @@ -40,16 +40,24 @@ void RtcSettingsSave(void) { if (GetRtcSettingsCrc() != rtc_settings_crc) { RtcSettings.valid = RTC_MEM_VALID; - ESP.rtcUserMemoryWrite(100, (uint32_t*)&RtcSettings, sizeof(RTCMEM)); +#ifdef ESP8266 + ESP.rtcUserMemoryWrite(100, (uint32_t*)&RtcSettings, sizeof(RtcSettings)); +#else + RtcDataSettings = RtcSettings; +#endif rtc_settings_crc = GetRtcSettingsCrc(); } } void RtcSettingsLoad(void) { - ESP.rtcUserMemoryRead(100, (uint32_t*)&RtcSettings, sizeof(RTCMEM)); // 0x290 +#ifdef ESP8266 + ESP.rtcUserMemoryRead(100, (uint32_t*)&RtcSettings, sizeof(RtcSettings)); // 0x290 +#else + RtcSettings = RtcDataSettings; +#endif if (RtcSettings.valid != RTC_MEM_VALID) { - memset(&RtcSettings, 0, sizeof(RTCMEM)); + memset(&RtcSettings, 0, sizeof(RtcSettings)); RtcSettings.valid = RTC_MEM_VALID; RtcSettings.energy_kWhtoday = Settings.energy_kWhtoday; RtcSettings.energy_kWhtotal = Settings.energy_kWhtotal; @@ -77,7 +85,7 @@ uint32_t GetRtcRebootCrc(void) uint32_t crc = 0; uint8_t *bytes = (uint8_t*)&RtcReboot; - for (uint32_t i = 0; i < sizeof(RTCRBT); i++) { + for (uint32_t i = 0; i < sizeof(RtcReboot); i++) { crc += bytes[i]*(i+1); } return crc; @@ -87,7 +95,11 @@ void RtcRebootSave(void) { if (GetRtcRebootCrc() != rtc_reboot_crc) { RtcReboot.valid = RTC_MEM_VALID; - ESP.rtcUserMemoryWrite(100 - sizeof(RTCRBT), (uint32_t*)&RtcReboot, sizeof(RTCRBT)); +#ifdef ESP8266 + ESP.rtcUserMemoryWrite(100 - sizeof(RtcReboot), (uint32_t*)&RtcReboot, sizeof(RtcReboot)); +#else + RtcDataReboot = RtcReboot; +#endif rtc_reboot_crc = GetRtcRebootCrc(); } } @@ -100,9 +112,13 @@ void RtcRebootReset(void) void RtcRebootLoad(void) { - ESP.rtcUserMemoryRead(100 - sizeof(RTCRBT), (uint32_t*)&RtcReboot, sizeof(RTCRBT)); // 0x280 +#ifdef ESP8266 + ESP.rtcUserMemoryRead(100 - sizeof(RtcReboot), (uint32_t*)&RtcReboot, sizeof(RtcReboot)); // 0x280 +#else + RtcReboot = RtcDataReboot; +#endif if (RtcReboot.valid != RTC_MEM_VALID) { - memset(&RtcReboot, 0, sizeof(RTCRBT)); + memset(&RtcReboot, 0, sizeof(RtcReboot)); RtcReboot.valid = RTC_MEM_VALID; // RtcReboot.fast_reboot_count = 0; // Explicit by memset RtcRebootSave(); @@ -141,6 +157,8 @@ extern "C" { } #include "eboot_command.h" +#ifdef ESP8266 + #if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_1) || defined(ARDUINO_ESP8266_RELEASE_2_4_2) || defined(ARDUINO_ESP8266_RELEASE_2_5_0) || defined(ARDUINO_ESP8266_RELEASE_2_5_1) || defined(ARDUINO_ESP8266_RELEASE_2_5_2) extern "C" uint32_t _SPIFFS_end; @@ -168,6 +186,9 @@ const uint32_t SPIFFS_END = ((uint32_t)&_FS_end - 0x40200000) / SPI_FLASH_SEC_SI // Version 4.2 config = eeprom area const uint32_t SETTINGS_LOCATION = SPIFFS_END; // No need for SPIFFS as it uses EEPROM area + +#endif // ESP8266 + // Version 5.2 allow for more flash space const uint8_t CFG_ROTATES = 8; // Number of flash sectors used (handles uploads) @@ -181,6 +202,7 @@ uint8_t *settings_buffer = nullptr; */ void SetFlashModeDout(void) { +#ifdef ESP8266 uint8_t *_buffer; uint32_t address; @@ -198,10 +220,13 @@ void SetFlashModeDout(void) } } delete[] _buffer; +#endif // ESP8266 } bool VersionCompatible(void) { +#ifdef ESP8266 + if (Settings.flag3.compatibility_check) { return true; } @@ -244,6 +269,8 @@ bool VersionCompatible(void) return false; } +#endif // ESP8266 + return true; } @@ -278,7 +305,7 @@ uint16_t GetCfgCrc16(uint8_t *bytes, uint32_t size) uint16_t GetSettingsCrc(void) { // Fix miscalculation if previous Settings was 3584 and current Settings is 4096 between 0x06060007 and 0x0606000A - uint32_t size = ((Settings.version < 0x06060007) || (Settings.version > 0x0606000A)) ? 3584 : sizeof(SYSCFG); + uint32_t size = ((Settings.version < 0x06060007) || (Settings.version > 0x0606000A)) ? 3584 : sizeof(Settings); return GetCfgCrc16((uint8_t*)&Settings, size); } @@ -298,7 +325,7 @@ uint32_t GetCfgCrc32(uint8_t *bytes, uint32_t size) uint32_t GetSettingsCrc32(void) { - return GetCfgCrc32((uint8_t*)&Settings, sizeof(SYSCFG) -4); // Skip crc32 + return GetCfgCrc32((uint8_t*)&Settings, sizeof(Settings) -4); // Skip crc32 } void SettingsSaveAll(void) @@ -319,39 +346,52 @@ void SettingsSaveAll(void) void UpdateQuickPowerCycle(bool update) { +#ifndef FIRMWARE_MINIMAL if (Settings.flag3.fast_power_cycle_disable) { return; } // SetOption65 - Disable fast power cycle detection for device reset uint32_t pc_register; uint32_t pc_location = SETTINGS_LOCATION - CFG_ROTATES; +#ifdef ESP8266 ESP.flashRead(pc_location * SPI_FLASH_SEC_SIZE, (uint32*)&pc_register, sizeof(pc_register)); - if (update && ((pc_register & 0xFFFFFFF0) == 0xFFA55AB0)) { - uint32_t counter = ((pc_register & 0xF) << 1) & 0xF; - if (0 == counter) { // 4 power cycles in a row +#else // ESP32 + QPCRead(&pc_register, sizeof(pc_register)); +#endif // ESP8266 - ESP32 + if (update && ((pc_register & 0xFFFFFF80) == 0xFFA55A80)) { + uint32_t counter = ((pc_register & 0x7F) << 1) & 0x7F; + if (0 == counter) { // 7 power cycles in a row SettingsErase(3); // Quickly reset all settings including QuickPowerCycle flag EspRestart(); // And restart } else { pc_register = 0xFFA55AB0 | counter; +#ifdef ESP8266 ESP.flashWrite(pc_location * SPI_FLASH_SEC_SIZE, (uint32*)&pc_register, sizeof(pc_register)); +#else // ESP32 + QPCWrite(&pc_register, sizeof(pc_register)); +#endif // ESP8266 - ESP32 AddLog_P2(LOG_LEVEL_DEBUG, PSTR("QPC: Flag %02X"), counter); } } - else if (pc_register != 0xFFA55ABF) { - pc_register = 0xFFA55ABF; + else if (pc_register != 0xFFA55AFF) { + pc_register = 0xFFA55AFF; +#ifdef ESP8266 // Assume flash is default all ones and setting a bit to zero does not need an erase if (ESP.flashEraseSector(pc_location)) { ESP.flashWrite(pc_location * SPI_FLASH_SEC_SIZE, (uint32*)&pc_register, sizeof(pc_register)); } +#else // ESP32 + QPCWrite(&pc_register, sizeof(pc_register)); +#endif // ESP8266 - ESP32 AddLog_P2(LOG_LEVEL_DEBUG, PSTR("QPC: Reset")); } +#endif // FIRMWARE_MINIMAL } /*********************************************************************************************\ * Config Settings.text char array support \*********************************************************************************************/ -uint32_t GetSettingsTextLen(void) -{ +uint32_t GetSettingsTextLen(void) { char* position = Settings.text_pool; for (uint32_t size = 0; size < SET_MAX; size++) { while (*position++ != '\0') { } @@ -359,16 +399,28 @@ uint32_t GetSettingsTextLen(void) return position - Settings.text_pool; } -bool SettingsUpdateText(uint32_t index, const char* replace_me) -{ +bool settings_text_mutex = false; +uint32_t settings_text_busy_count = 0; + +bool SettingsUpdateFinished(void) { + uint32_t wait_loop = 10; + while (settings_text_mutex && wait_loop) { // Wait for any update to finish + yield(); + delayMicroseconds(1); + wait_loop--; + } + return (wait_loop > 0); // true if finished +} + +bool SettingsUpdateText(uint32_t index, const char* replace_me) { if (index >= SET_MAX) { return false; // Setting not supported - internal error } // Make a copy first in case we use source from Settings.text - uint32_t replace_len = strlen(replace_me); + uint32_t replace_len = strlen_P(replace_me); char replace[replace_len +1]; - memcpy(replace, replace_me, sizeof(replace)); + memcpy_P(replace, replace_me, sizeof(replace)); uint32_t start_pos = 0; uint32_t end_pos = 0; @@ -397,16 +449,24 @@ bool SettingsUpdateText(uint32_t index, const char* replace_me) return false; // Replace text too long } - if (diff != 0) { - // Shift Settings.text up or down - memmove_P(Settings.text_pool + start_pos + replace_len, Settings.text_pool + end_pos, char_len - end_pos); - } - // Replace text - memmove_P(Settings.text_pool + start_pos, replace, replace_len); - // Fill for future use - memset(Settings.text_pool + char_len + diff, 0x00, settings_text_size - char_len - diff); + if (settings_text_mutex && !SettingsUpdateFinished()) { + settings_text_busy_count++; + } else { + settings_text_mutex = true; - AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_CONFIG "CR %d/%d"), GetSettingsTextLen(), settings_text_size); + if (diff != 0) { + // Shift Settings.text up or down + memmove_P(Settings.text_pool + start_pos + replace_len, Settings.text_pool + end_pos, char_len - end_pos); + } + // Replace text + memmove_P(Settings.text_pool + start_pos, replace, replace_len); + // Fill for future use + memset(Settings.text_pool + char_len + diff, 0x00, settings_text_size - char_len - diff); + + settings_text_mutex = false; + } + + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_CONFIG "CR %d/%d, Busy %d"), GetSettingsTextLen(), settings_text_size, settings_text_busy_count); return true; } @@ -418,6 +478,7 @@ char* SettingsText(uint32_t index) if (index >= SET_MAX) { position += settings_text_size -1; // Setting not supported - internal error - return empty string } else { + SettingsUpdateFinished(); for (;index > 0; index--) { while (*position++ != '\0') { } } @@ -474,12 +535,13 @@ void SettingsSave(uint8_t rotate) } else { Settings.cfg_timestamp++; } - Settings.cfg_size = sizeof(SYSCFG); + Settings.cfg_size = sizeof(Settings); Settings.cfg_crc = GetSettingsCrc(); // Keep for backward compatibility in case of fall-back just after upgrade Settings.cfg_crc32 = GetSettingsCrc32(); +#ifdef ESP8266 if (ESP.flashEraseSector(settings_location)) { - ESP.flashWrite(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG)); + ESP.flashWrite(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(Settings)); } if (!stop_flash_rotate && rotate) { @@ -488,8 +550,11 @@ void SettingsSave(uint8_t rotate) delay(1); } } - - AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_CONFIG D_SAVED_TO_FLASH_AT " %X, " D_COUNT " %d, " D_BYTES " %d"), settings_location, Settings.save_flag, sizeof(SYSCFG)); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_CONFIG D_SAVED_TO_FLASH_AT " %X, " D_COUNT " %d, " D_BYTES " %d"), settings_location, Settings.save_flag, sizeof(Settings)); +#else // ESP32 + SettingsWrite(&Settings, sizeof(Settings)); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_CONFIG "Saved, " D_COUNT " %d, " D_BYTES " %d"), Settings.save_flag, sizeof(Settings)); +#endif // ESP8266 settings_crc32 = Settings.cfg_crc32; } @@ -499,8 +564,9 @@ void SettingsSave(uint8_t rotate) void SettingsLoad(void) { +#ifdef ESP8266 // Load configuration from eeprom or one of 7 slots below if first valid load does not stop_flash_rotate - struct SYSCFGH { + struct { uint16_t cfg_holder; // 000 uint16_t cfg_size; // 002 unsigned long save_flag; // 004 @@ -512,8 +578,7 @@ void SettingsLoad(void) uint16_t cfg_holder = 0; for (uint32_t i = 0; i < CFG_ROTATES; i++) { flash_location--; - ESP.flashRead(flash_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG)); - + ESP.flashRead(flash_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(Settings)); bool valid = false; if (Settings.version > 0x06000000) { bool almost_valid = (Settings.cfg_crc32 == GetSettingsCrc32()); @@ -524,7 +589,7 @@ void SettingsLoad(void) if (almost_valid && (0 == cfg_holder)) { cfg_holder = Settings.cfg_holder; } // At FB always active cfg_holder valid = (cfg_holder == Settings.cfg_holder); } else { - ESP.flashRead((flash_location -1) * SPI_FLASH_SEC_SIZE, (uint32*)&_SettingsH, sizeof(SYSCFGH)); + ESP.flashRead((flash_location -1) * SPI_FLASH_SEC_SIZE, (uint32*)&_SettingsH, sizeof(_SettingsH)); valid = (Settings.cfg_holder == _SettingsH.cfg_holder); } if (valid) { @@ -536,13 +601,16 @@ void SettingsLoad(void) } } } - delay(1); } if (settings_location > 0) { - ESP.flashRead(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG)); + ESP.flashRead(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(Settings)); AddLog_P2(LOG_LEVEL_NONE, PSTR(D_LOG_CONFIG D_LOADED_FROM_FLASH_AT " %X, " D_COUNT " %lu"), settings_location, Settings.save_flag); } +#else // ESP32 + SettingsRead(&Settings, sizeof(Settings)); + AddLog_P2(LOG_LEVEL_NONE, PSTR(D_LOG_CONFIG "Loaded, " D_COUNT " %lu"), Settings.save_flag); +#endif // ESP8266 - ESP32 #ifndef FIRMWARE_MINIMAL if (!settings_location || (Settings.cfg_holder != (uint16_t)CFG_HOLDER)) { // Init defaults if cfg_holder differs from user settings in my_user_config.h @@ -577,6 +645,7 @@ void EspErase(uint32_t start_sector, uint32_t end_sector) } } +#ifdef ESP8266 void SettingsErase(uint8_t type) { /* @@ -631,6 +700,7 @@ void SettingsErase(uint8_t type) EsptoolErase(_sectorStart, _sectorEnd); // Esptool - erases flash completely #endif // FIRMWARE_MINIMAL } +#endif // ESP8266 void SettingsSdkErase(void) { @@ -651,10 +721,10 @@ void SettingsDefault(void) void SettingsDefaultSet1(void) { - memset(&Settings, 0x00, sizeof(SYSCFG)); + memset(&Settings, 0x00, sizeof(Settings)); Settings.cfg_holder = (uint16_t)CFG_HOLDER; - Settings.cfg_size = sizeof(SYSCFG); + Settings.cfg_size = sizeof(Settings); // Settings.save_flag = 0; Settings.version = VERSION; // Settings.bootcount = 0; @@ -663,15 +733,28 @@ void SettingsDefaultSet1(void) void SettingsDefaultSet2(void) { - memset((char*)&Settings +16, 0x00, sizeof(SYSCFG) -16); + memset((char*)&Settings +16, 0x00, sizeof(Settings) -16); - Settings.flag.stop_flash_rotate = APP_FLASH_CYCLE; - Settings.flag.global_state = APP_ENABLE_LEDLINK; - Settings.flag3.sleep_normal = APP_NORMAL_SLEEP; - Settings.flag3.no_power_feedback = APP_NO_RELAY_SCAN; - Settings.flag3.fast_power_cycle_disable = APP_DISABLE_POWERCYCLE; - Settings.flag3.bootcount_update = DEEPSLEEP_BOOTCOUNT; - Settings.flag3.compatibility_check = OTA_COMPATIBILITY; + // this little trick allows GCC to optimize the assignment by grouping values and doing only ORs + SysBitfield flag = { 0 }; + SysBitfield2 flag2 = { 0 }; + SysBitfield3 flag3 = { 0 }; + SysBitfield4 flag4 = { 0 }; + +#ifdef ESP8266 +// Settings.config_version = 0; // ESP8266 (Has been 0 for long time) +#endif // ESP8266 +#ifdef ESP32 + Settings.config_version = 1; // ESP32 +#endif // ESP32 + + flag.stop_flash_rotate |= APP_FLASH_CYCLE; + flag.global_state |= APP_ENABLE_LEDLINK; + flag3.sleep_normal |= APP_NORMAL_SLEEP; + flag3.no_power_feedback |= APP_NO_RELAY_SCAN; + flag3.fast_power_cycle_disable |= APP_DISABLE_POWERCYCLE; + flag3.bootcount_update |= DEEPSLEEP_BOOTCOUNT; + flag3.compatibility_check |= OTA_COMPATIBILITY; Settings.save_data = SAVE_DATA; Settings.param[P_BACKLOG_DELAY] = MIN_BACKLOG_DELAY; Settings.param[P_BOOT_LOOP_OFFSET] = BOOT_LOOP_OFFSET; // SetOption36 @@ -682,25 +765,33 @@ void SettingsDefaultSet2(void) } // Module -// Settings.flag.interlock = 0; - Settings.interlock[0] = 0xFF; // Legacy support using all relays in one interlock group + flag.interlock |= APP_INTERLOCK_MODE; + Settings.interlock[0] = APP_INTERLOCK_GROUP_1; + Settings.interlock[1] = APP_INTERLOCK_GROUP_2; + Settings.interlock[2] = APP_INTERLOCK_GROUP_3; + Settings.interlock[3] = APP_INTERLOCK_GROUP_4; Settings.module = MODULE; + Settings.fallback_module = FALLBACK_MODULE; ModuleDefault(WEMOS); -// for (uint32_t i = 0; i < sizeof(Settings.my_gp); i++) { Settings.my_gp.io[i] = GPIO_NONE; } - SettingsUpdateText(SET_FRIENDLYNAME1, FRIENDLY_NAME); - SettingsUpdateText(SET_FRIENDLYNAME2, FRIENDLY_NAME"2"); - SettingsUpdateText(SET_FRIENDLYNAME3, FRIENDLY_NAME"3"); - SettingsUpdateText(SET_FRIENDLYNAME4, FRIENDLY_NAME"4"); - SettingsUpdateText(SET_OTAURL, OTA_URL); +// for (uint32_t i = 0; i < ARRAY_SIZE(Settings.my_gp.io); i++) { Settings.my_gp.io[i] = GPIO_NONE; } + SettingsUpdateText(SET_FRIENDLYNAME1, PSTR(FRIENDLY_NAME)); + SettingsUpdateText(SET_FRIENDLYNAME2, PSTR(FRIENDLY_NAME"2")); + SettingsUpdateText(SET_FRIENDLYNAME3, PSTR(FRIENDLY_NAME"3")); + SettingsUpdateText(SET_FRIENDLYNAME4, PSTR(FRIENDLY_NAME"4")); + SettingsUpdateText(SET_DEVICENAME, SettingsText(SET_FRIENDLYNAME1)); + SettingsUpdateText(SET_OTAURL, PSTR(OTA_URL)); // Power - Settings.flag.save_state = SAVE_STATE; + flag.save_state |= SAVE_STATE; Settings.power = APP_POWER; Settings.poweronstate = APP_POWERON_STATE; Settings.blinktime = APP_BLINKTIME; Settings.blinkcount = APP_BLINKCOUNT; Settings.ledstate = APP_LEDSTATE; Settings.ledmask = APP_LEDMASK; +// Settings.ledpwm_off = 0; + Settings.ledpwm_on = 255; +// Settings.ledpwm_mask = 0; Settings.pulse_timer[0] = APP_PULSETIME; // for (uint32_t i = 1; i < MAX_PULSETIMERS; i++) { Settings.pulse_timer[i] = 0; } @@ -711,60 +802,70 @@ void SettingsDefaultSet2(void) Settings.serial_delimiter = 0xff; Settings.seriallog_level = SERIAL_LOG_LEVEL; + // Ethernet + flag4.network_ethernet |= 1; +#ifdef ESP32 + Settings.eth_type = ETH_TYPE; + Settings.eth_clk_mode = ETH_CLKMODE; + Settings.eth_address = ETH_ADDR; +#endif + // Wifi - Settings.flag3.use_wifi_scan = WIFI_SCAN_AT_RESTART; - Settings.flag3.use_wifi_rescan = WIFI_SCAN_REGULARLY; + flag4.network_wifi |= 1; + flag3.use_wifi_scan |= WIFI_SCAN_AT_RESTART; + flag3.use_wifi_rescan |= WIFI_SCAN_REGULARLY; Settings.wifi_output_power = 170; + Settings.param[P_ARP_GRATUITOUS] = WIFI_ARP_INTERVAL; ParseIp(&Settings.ip_address[0], WIFI_IP_ADDRESS); ParseIp(&Settings.ip_address[1], WIFI_GATEWAY); ParseIp(&Settings.ip_address[2], WIFI_SUBNETMASK); ParseIp(&Settings.ip_address[3], WIFI_DNS); Settings.sta_config = WIFI_CONFIG_TOOL; // Settings.sta_active = 0; - SettingsUpdateText(SET_STASSID1, STA_SSID1); - SettingsUpdateText(SET_STASSID2, STA_SSID2); - SettingsUpdateText(SET_STAPWD1, STA_PASS1); - SettingsUpdateText(SET_STAPWD2, STA_PASS2); + SettingsUpdateText(SET_STASSID1, PSTR(STA_SSID1)); + SettingsUpdateText(SET_STASSID2, PSTR(STA_SSID2)); + SettingsUpdateText(SET_STAPWD1, PSTR(STA_PASS1)); + SettingsUpdateText(SET_STAPWD2, PSTR(STA_PASS2)); SettingsUpdateText(SET_HOSTNAME, WIFI_HOSTNAME); // Syslog - SettingsUpdateText(SET_SYSLOG_HOST, SYS_LOG_HOST); + SettingsUpdateText(SET_SYSLOG_HOST, PSTR(SYS_LOG_HOST)); Settings.syslog_port = SYS_LOG_PORT; Settings.syslog_level = SYS_LOG_LEVEL; // Webserver - Settings.flag2.emulation = EMULATION; - Settings.flag3.gui_hostname_ip = GUI_SHOW_HOSTNAME; - Settings.flag3.mdns_enabled = MDNS_ENABLED; + flag2.emulation |= EMULATION; + flag3.gui_hostname_ip |= GUI_SHOW_HOSTNAME; + flag3.mdns_enabled |= MDNS_ENABLED; Settings.webserver = WEB_SERVER; Settings.weblog_level = WEB_LOG_LEVEL; - SettingsUpdateText(SET_WEBPWD, WEB_PASSWORD); - SettingsUpdateText(SET_CORS, CORS_DOMAIN); + SettingsUpdateText(SET_WEBPWD, PSTR(WEB_PASSWORD)); + SettingsUpdateText(SET_CORS, PSTR(CORS_DOMAIN)); // Button - Settings.flag.button_restrict = KEY_DISABLE_MULTIPRESS; - Settings.flag.button_swap = KEY_SWAP_DOUBLE_PRESS; - Settings.flag.button_single = KEY_ONLY_SINGLE_PRESS; + flag.button_restrict |= KEY_DISABLE_MULTIPRESS; + flag.button_swap |= KEY_SWAP_DOUBLE_PRESS; + flag.button_single |= KEY_ONLY_SINGLE_PRESS; Settings.param[P_HOLD_TIME] = KEY_HOLD_TIME; // Default 4 seconds hold time // Switch for (uint32_t i = 0; i < MAX_SWITCHES; i++) { Settings.switchmode[i] = SWITCH_MODE; } // MQTT - Settings.flag.mqtt_enabled = MQTT_USE; - Settings.flag.mqtt_response = MQTT_RESULT_COMMAND; - Settings.flag.mqtt_offline = MQTT_LWT_MESSAGE; - Settings.flag.mqtt_power_retain = MQTT_POWER_RETAIN; - Settings.flag.mqtt_button_retain = MQTT_BUTTON_RETAIN; - Settings.flag.mqtt_switch_retain = MQTT_SWITCH_RETAIN; - Settings.flag.mqtt_sensor_retain = MQTT_SENSOR_RETAIN; -// Settings.flag.mqtt_serial = 0; - Settings.flag.device_index_enable = MQTT_POWER_FORMAT; - Settings.flag3.time_append_timezone = MQTT_APPEND_TIMEZONE; - Settings.flag3.button_switch_force_local = MQTT_BUTTON_SWITCH_FORCE_LOCAL; - Settings.flag3.no_hold_retain = MQTT_NO_HOLD_RETAIN; - Settings.flag3.use_underscore = MQTT_INDEX_SEPARATOR; - Settings.flag3.grouptopic_mode = MQTT_GROUPTOPIC_FORMAT; + flag.mqtt_enabled |= MQTT_USE; + flag.mqtt_response |= MQTT_RESULT_COMMAND; + flag.mqtt_offline |= MQTT_LWT_MESSAGE; + flag.mqtt_power_retain |= MQTT_POWER_RETAIN; + flag.mqtt_button_retain |= MQTT_BUTTON_RETAIN; + flag.mqtt_switch_retain |= MQTT_SWITCH_RETAIN; + flag.mqtt_sensor_retain |= MQTT_SENSOR_RETAIN; +// flag.mqtt_serial |= 0; + flag.device_index_enable |= MQTT_POWER_FORMAT; + flag3.time_append_timezone |= MQTT_APPEND_TIMEZONE; + flag3.button_switch_force_local |= MQTT_BUTTON_SWITCH_FORCE_LOCAL; + flag3.no_hold_retain |= MQTT_NO_HOLD_RETAIN; + flag3.use_underscore |= MQTT_INDEX_SEPARATOR; + flag3.grouptopic_mode |= MQTT_GROUPTOPIC_FORMAT; SettingsUpdateText(SET_MQTT_HOST, MQTT_HOST); Settings.mqtt_port = MQTT_PORT; SettingsUpdateText(SET_MQTT_CLIENT, MQTT_CLIENT_ID); @@ -783,13 +884,13 @@ void SettingsDefaultSet2(void) SettingsUpdateText(SET_STATE_TXT2, MQTT_STATUS_ON); SettingsUpdateText(SET_STATE_TXT3, MQTT_CMND_TOGGLE); SettingsUpdateText(SET_STATE_TXT4, MQTT_CMND_HOLD); - char fingerprint[60]; - strlcpy(fingerprint, MQTT_FINGERPRINT1, sizeof(fingerprint)); + char fingerprint[64]; + strncpy_P(fingerprint, PSTR(MQTT_FINGERPRINT1), sizeof(fingerprint)); char *p = fingerprint; for (uint32_t i = 0; i < 20; i++) { Settings.mqtt_fingerprint[0][i] = strtol(p, &p, 16); } - strlcpy(fingerprint, MQTT_FINGERPRINT2, sizeof(fingerprint)); + strncpy_P(fingerprint, PSTR(MQTT_FINGERPRINT2), sizeof(fingerprint)); p = fingerprint; for (uint32_t i = 0; i < 20; i++) { Settings.mqtt_fingerprint[1][i] = strtol(p, &p, 16); @@ -798,13 +899,13 @@ void SettingsDefaultSet2(void) Settings.mqttlog_level = MQTT_LOG_LEVEL; // Energy - Settings.flag.no_power_on_check = ENERGY_VOLTAGE_ALWAYS; - Settings.flag2.current_resolution = 3; -// Settings.flag2.voltage_resolution = 0; -// Settings.flag2.wattage_resolution = 0; - Settings.flag2.energy_resolution = ENERGY_RESOLUTION; - Settings.flag3.dds2382_model = ENERGY_DDS2382_MODE; - Settings.flag3.hardware_energy_total = ENERGY_HARDWARE_TOTALS; + flag.no_power_on_check |= ENERGY_VOLTAGE_ALWAYS; + flag2.current_resolution |= 3; +// flag2.voltage_resolution |= 0; +// flag2.wattage_resolution |= 0; + flag2.energy_resolution |= ENERGY_RESOLUTION; + flag3.dds2382_model |= ENERGY_DDS2382_MODE; + flag3.hardware_energy_total |= ENERGY_HARDWARE_TOTALS; Settings.param[P_MAX_POWER_RETRY] = MAX_POWER_RETRY; // Settings.energy_power_delta = 0; Settings.energy_power_calibration = HLW_PREF_PULSE; @@ -834,12 +935,12 @@ void SettingsDefaultSet2(void) Settings.param[P_OVER_TEMP] = ENERGY_OVERTEMP; // IRRemote - Settings.flag.ir_receive_decimal = IR_DATA_RADIX; - Settings.flag3.receive_raw = IR_ADD_RAW_DATA; + flag.ir_receive_decimal |= IR_DATA_RADIX; + flag3.receive_raw |= IR_ADD_RAW_DATA; Settings.param[P_IR_UNKNOW_THRESHOLD] = IR_RCV_MIN_UNKNOWN_SIZE; // RF Bridge - Settings.flag.rf_receive_decimal = RF_DATA_RADIX; + flag.rf_receive_decimal |= RF_DATA_RADIX; // for (uint32_t i = 0; i < 17; i++) { Settings.rf_code[i][0] = 0; } memcpy_P(Settings.rf_code[0], kDefaultRfCode, 9); @@ -855,42 +956,43 @@ void SettingsDefaultSet2(void) // } // Sensor - Settings.flag.temperature_conversion = TEMP_CONVERSION; - Settings.flag.pressure_conversion = PRESSURE_CONVERSION; - Settings.flag2.pressure_resolution = PRESSURE_RESOLUTION; - Settings.flag2.humidity_resolution = HUMIDITY_RESOLUTION; - Settings.flag2.temperature_resolution = TEMP_RESOLUTION; - Settings.flag3.ds18x20_internal_pullup = DS18X20_PULL_UP; - Settings.flag3.counter_reset_on_tele = COUNTER_RESET; + flag.temperature_conversion |= TEMP_CONVERSION; + flag.pressure_conversion |= PRESSURE_CONVERSION; + flag2.pressure_resolution |= PRESSURE_RESOLUTION; + flag2.humidity_resolution |= HUMIDITY_RESOLUTION; + flag2.temperature_resolution |= TEMP_RESOLUTION; + flag3.ds18x20_internal_pullup |= DS18X20_PULL_UP; + flag3.counter_reset_on_tele |= COUNTER_RESET; // Settings.altitude = 0; // Rules // Settings.rule_enabled = 0; // Settings.rule_once = 0; // for (uint32_t i = 1; i < MAX_RULE_SETS; i++) { Settings.rules[i][0] = '\0'; } - Settings.flag2.calc_resolution = CALC_RESOLUTION; + flag2.calc_resolution |= CALC_RESOLUTION; // Timer - Settings.flag3.timers_enable = TIMERS_ENABLED; + flag3.timers_enable |= TIMERS_ENABLED; // Home Assistant - Settings.flag.hass_light = HASS_AS_LIGHT; - Settings.flag.hass_discovery = HOME_ASSISTANT_DISCOVERY_ENABLE; - Settings.flag3.hass_tele_on_power = TELE_ON_POWER; + flag.hass_light |= HASS_AS_LIGHT; + flag.hass_discovery |= HOME_ASSISTANT_DISCOVERY_ENABLE; + flag3.hass_tele_on_power |= TELE_ON_POWER; // Knx - Settings.flag.knx_enabled = KNX_ENABLED; - Settings.flag.knx_enable_enhancement = KNX_ENHANCED; + flag.knx_enabled |= KNX_ENABLED; + flag.knx_enable_enhancement |= KNX_ENHANCED; // Light - Settings.flag.pwm_control = LIGHT_MODE; - Settings.flag.ws_clock_reverse = LIGHT_CLOCK_DIRECTION; - Settings.flag.light_signal = LIGHT_PAIRS_CO2; - Settings.flag.not_power_linked = LIGHT_POWER_CONTROL; - Settings.flag.decimal_text = LIGHT_COLOR_RADIX; - Settings.flag3.pwm_multi_channels = LIGHT_CHANNEL_MODE; - Settings.flag3.slider_dimmer_stay_on = LIGHT_SLIDER_POWER; - Settings.flag4.alexa_ct_range = LIGHT_ALEXA_CT_RANGE; + flag.pwm_control |= LIGHT_MODE; + flag.ws_clock_reverse |= LIGHT_CLOCK_DIRECTION; + flag.light_signal |= LIGHT_PAIRS_CO2; + flag.not_power_linked |= LIGHT_POWER_CONTROL; + flag.decimal_text |= LIGHT_COLOR_RADIX; + flag3.pwm_multi_channels |= LIGHT_CHANNEL_MODE; + flag3.slider_dimmer_stay_on |= LIGHT_SLIDER_POWER; + flag4.alexa_ct_range |= LIGHT_ALEXA_CT_RANGE; + flag4.pwm_ct_mode |= LIGHT_PWM_CT_MODE; Settings.pwm_frequency = PWM_FREQ; Settings.pwm_range = PWM_RANGE; @@ -951,9 +1053,9 @@ void SettingsDefaultSet2(void) Settings.timezone = APP_TIMEZONE / 60; Settings.timezone_minutes = abs(APP_TIMEZONE % 60); } - SettingsUpdateText(SET_NTPSERVER1, NTP_SERVER1); - SettingsUpdateText(SET_NTPSERVER2, NTP_SERVER2); - SettingsUpdateText(SET_NTPSERVER3, NTP_SERVER3); + SettingsUpdateText(SET_NTPSERVER1, PSTR(NTP_SERVER1)); + SettingsUpdateText(SET_NTPSERVER2, PSTR(NTP_SERVER2)); + SettingsUpdateText(SET_NTPSERVER3, PSTR(NTP_SERVER3)); for (uint32_t i = 0; i < MAX_NTP_SERVERS; i++) { SettingsUpdateText(SET_NTPSERVER1 +i, ReplaceCommaWithDot(SettingsText(SET_NTPSERVER1 +i))); } @@ -977,13 +1079,22 @@ void SettingsDefaultSet2(void) SettingsEnableAllI2cDrivers(); // Tuya - Settings.flag3.tuya_apply_o20 = TUYA_SETOPTION_20; - Settings.flag3.tuya_serial_mqtt_publish = MQTT_TUYA_RECEIVED; + flag3.tuya_apply_o20 |= TUYA_SETOPTION_20; + flag3.tuya_serial_mqtt_publish |= MQTT_TUYA_RECEIVED; - Settings.flag3.buzzer_enable = BUZZER_ENABLE; - Settings.flag3.shutter_mode = SHUTTER_SUPPORT; - Settings.flag3.pcf8574_ports_inverted = PCF8574_INVERT_PORTS; - Settings.flag4.zigbee_use_names = ZIGBEE_FRIENDLY_NAMES; + flag3.buzzer_enable |= BUZZER_ENABLE; + flag3.shutter_mode |= SHUTTER_SUPPORT; + flag3.pcf8574_ports_inverted |= PCF8574_INVERT_PORTS; + flag4.zigbee_use_names |= ZIGBEE_FRIENDLY_NAMES; + +#ifdef USER_TEMPLATE + JsonTemplate(USER_TEMPLATE); +#endif + + Settings.flag = flag; + Settings.flag2 = flag2; + Settings.flag3 = flag3; + Settings.flag4 = flag4; } /********************************************************************************************/ @@ -1028,8 +1139,10 @@ void SettingsEnableAllI2cDrivers(void) void SettingsDelta(void) { if (Settings.version != VERSION) { // Fix version dependent changes + +#ifdef ESP8266 if (Settings.version < 0x06000000) { - Settings.cfg_size = sizeof(SYSCFG); + Settings.cfg_size = sizeof(Settings); Settings.cfg_crc = GetSettingsCrc(); } if (Settings.version < 0x06000002) { @@ -1040,7 +1153,7 @@ void SettingsDelta(void) Settings.switchmode[i] = SWITCH_MODE; } } - for (uint32_t i = 0; i < sizeof(Settings.my_gp); i++) { + for (uint32_t i = 0; i < ARRAY_SIZE(Settings.my_gp.io); i++) { if (Settings.my_gp.io[i] >= GPIO_SWT5) { // Move up from GPIO_SWT5 to GPIO_KEY1 Settings.my_gp.io[i] += 4; } @@ -1082,8 +1195,11 @@ void SettingsDelta(void) Settings.param[P_MDNS_DELAYED_START] = 0; } if (Settings.version < 0x0604010B) { - Settings.interlock[0] = 0xFF; // Legacy support using all relays in one interlock group - for (uint32_t i = 1; i < MAX_INTERLOCKS; i++) { Settings.interlock[i] = 0; } + Settings.flag.interlock = APP_INTERLOCK_MODE; + Settings.interlock[0] = APP_INTERLOCK_GROUP_1; + Settings.interlock[1] = APP_INTERLOCK_GROUP_2; + Settings.interlock[2] = APP_INTERLOCK_GROUP_3; + Settings.interlock[3] = APP_INTERLOCK_GROUP_4; } if (Settings.version < 0x0604010D) { Settings.param[P_BOOT_LOOP_OFFSET] = BOOT_LOOP_OFFSET; // SetOption36 @@ -1113,7 +1229,7 @@ void SettingsDelta(void) Settings.param[P_OVER_TEMP] = ENERGY_OVERTEMP; } if (Settings.version < 0x06060007) { - memset((char*)&Settings +0xE00, 0x00, sizeof(SYSCFG) -0xE00); + memset((char*)&Settings +0xE00, 0x00, sizeof(Settings) -0xE00); } if (Settings.version < 0x06060008) { // Move current tuya dimmer range to the new param. @@ -1224,7 +1340,7 @@ void SettingsDelta(void) Settings.ex_serial_config = TS_SERIAL_8N1; } if (Settings.version < 0x07010204) { - if (Settings.flag3.ex_cors_enabled == 1) { + if (Settings.flag3.mqtt_buttons == 1) { strlcpy(Settings.ex_cors_domain, CORS_ENABLED_ALL, sizeof(Settings.ex_cors_domain)); } else { Settings.ex_cors_domain[0] = 0; @@ -1314,9 +1430,52 @@ void SettingsDelta(void) } if (Settings.version < 0x08020003) { SettingsUpdateText(SET_TEMPLATE_NAME, Settings.user_template_name); + Settings.zb_channel = 0; // set channel to zero to force reinit of zigbee parameters + } +#endif // ESP8266 + + if (Settings.version < 0x08020004) { + Settings.flag3.mqtt_buttons = 0; // SetOption73 (0) - Decouple button from relay and send just mqtt topic +#ifdef ESP8266 + Settings.config_version = 0; // ESP8266 (Has been 0 for long time) +#endif // ESP8266 +#ifdef ESP32 + Settings.config_version = 1; // ESP32 +#endif // ESP32 + } + if (Settings.version < 0x08020006) { +#ifdef ESP32 + Settings.module = WEMOS; + ModuleDefault(WEMOS); +#endif // ESP32 + // make sure the empty rules have two consecutive NULLs, to be compatible with compressed rules + if (Settings.rules[0][0] == 0) { Settings.rules[0][1] = 0; } + if (Settings.rules[1][0] == 0) { Settings.rules[1][1] = 0; } + if (Settings.rules[2][0] == 0) { Settings.rules[2][1] = 0; } + } + if (Settings.version < 0x08030002) { + SettingsUpdateText(SET_DEVICENAME, SettingsText(SET_FRIENDLYNAME1)); + Settings.ledpwm_off = 0; + Settings.ledpwm_on = 255; + Settings.ledpwm_mask = 0; + } + if (Settings.version < 0x08030104) { + Settings.flag4.network_wifi = 1; + Settings.flag4.network_ethernet = 1; + } +#ifdef ESP32 + if (Settings.version < 0x08030105) { + Settings.eth_type = ETH_TYPE; + Settings.eth_clk_mode = ETH_CLKMODE; + Settings.eth_address = ETH_ADDR; + } +#endif + if (Settings.version < 0x08030106) { + Settings.fallback_module = FALLBACK_MODULE; } Settings.version = VERSION; SettingsSave(1); } + } diff --git a/tasmota/support.ino b/tasmota/support.ino index 453eb4875..1d05ae2d1 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -52,7 +52,7 @@ void OsWatchTicker(void) #ifdef DEBUG_THEO int32_t rssi = WiFi.RSSI(); - AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION D_OSWATCH " FreeRam %d, rssi %d %% (%d dBm), last_run %d"), ESP.getFreeHeap(), WifiGetRssiAsQuality(rssi), rssi, last_run); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION D_OSWATCH " FreeRam %d, rssi %d %% (%d dBm), last_run %d"), ESP_getFreeHeap(), WifiGetRssiAsQuality(rssi), rssi, last_run); #endif // DEBUG_THEO if (last_run >= (OSWATCH_RESET_TIME * 1000)) { // AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION D_OSWATCH " " D_BLOCKED_LOOP ". " D_RESTARTING)); // Save iram space @@ -99,7 +99,7 @@ uint32_t ResetReason(void) REASON_DEEP_SLEEP_AWAKE = 5, // "Deep-Sleep Wake" wake up from deep-sleep REASON_EXT_SYS_RST = 6 // "External System" external system reset */ - return resetInfo.reason; + return ESP_ResetInfoReason(); } String GetResetReason(void) @@ -109,7 +109,7 @@ String GetResetReason(void) strncpy_P(buff, PSTR(D_JSON_BLOCKED_LOOP), sizeof(buff)); return String(buff); } else { - return ESP.getResetReason(); + return ESP_getResetReason(); } } @@ -156,7 +156,7 @@ float CharToFloat(const char *str) signed char sign = 1; if (*pt == '-') { sign = -1; } - if (*pt == '-' || *pt=='+') { pt++; } // Skip any sign + if (*pt == '-' || *pt == '+') { pt++; } // Skip any sign float left = 0; if (*pt != '.') { @@ -167,6 +167,9 @@ float CharToFloat(const char *str) float right = 0; if (*pt == '.') { pt++; + uint32_t max_decimals = 0; + while ((max_decimals < 8) && isdigit(pt[max_decimals])) { max_decimals++; } + pt[max_decimals] = '\0'; // Limit decimals to float max of 8 right = atoi(pt); // Decimal part while (isdigit(*pt)) { pt++; @@ -562,6 +565,7 @@ char* GetPowerDevice(char* dest, uint32_t idx, size_t size) void GetEspHardwareType(void) { +#ifdef ESP8266 // esptool.py get_efuses uint32_t efuse1 = *(uint32_t*)(0x3FF00050); uint32_t efuse2 = *(uint32_t*)(0x3FF00054); @@ -572,16 +576,23 @@ void GetEspHardwareType(void) if (is_8285 && (ESP.getFlashChipRealSize() > 1048576)) { is_8285 = false; // ESP8285 can only have 1M flash } +#else + is_8285 = false; // ESP8285 can only have 1M flash +#endif } String GetDeviceHardware(void) { char buff[10]; +#ifdef ESP8266 if (is_8285) { strcpy_P(buff, PSTR("ESP8285")); } else { strcpy_P(buff, PSTR("ESP8266EX")); } +#else + strcpy_P(buff, PSTR("ESP32")); +#endif return String(buff); } @@ -590,7 +601,7 @@ float ConvertTemp(float c) float result = c; global_update = uptime; - global_temperature = c; + global_temperature_celsius = c; if (!isnan(c) && Settings.flag.temperature_conversion) { // SetOption8 - Switch between Celsius or Fahrenheit result = c * 1.8 + 32; // Fahrenheit @@ -612,7 +623,8 @@ float ConvertTempToCelsius(float c) char TempUnit(void) { - return (Settings.flag.temperature_conversion) ? 'F' : 'C'; // SetOption8 - Switch between Celsius or Fahrenheit + // SetOption8 - Switch between Celsius or Fahrenheit + return (Settings.flag.temperature_conversion) ? D_UNIT_FAHRENHEIT[0] : D_UNIT_CELSIUS[0]; } float ConvertHumidity(float h) @@ -629,7 +641,7 @@ float ConvertHumidity(float h) float CalcTempHumToDew(float t, float h) { - if (isnan(h) || isnan(t)) { return 0.0; } + if (isnan(h) || isnan(t)) { return NAN; } if (Settings.flag.temperature_conversion) { // SetOption8 - Switch between Celsius or Fahrenheit t = (t - 32) / 1.8; // Celsius @@ -649,7 +661,7 @@ float ConvertPressure(float p) float result = p; global_update = uptime; - global_pressure = p; + global_pressure_hpa = p; if (!isnan(p) && Settings.flag.pressure_conversion) { // SetOption24 - Switch between hPa or mmHg pressure unit result = p * 0.75006375541921; // mmHg @@ -678,9 +690,9 @@ void ResetGlobalValues(void) { if ((uptime - global_update) > GLOBAL_VALUES_VALID) { // Reset after 5 minutes global_update = 0; - global_temperature = 9999; - global_humidity = 0; - global_pressure = 0; + global_temperature_celsius = NAN; + global_humidity = 0.0f; + global_pressure_hpa = 0.0f; } } @@ -987,6 +999,9 @@ char* ResponseGetTime(uint32_t format, char* time_str) case 2: snprintf_P(time_str, TIMESZ, PSTR("{\"" D_JSON_TIME "\":%u"), UtcTime()); break; + case 3: + snprintf_P(time_str, TIMESZ, PSTR("{\"" D_JSON_TIME "\":\"%s\""), GetDateAndTime(DT_LOCAL_MILLIS).c_str()); + break; default: snprintf_P(time_str, TIMESZ, PSTR("{\"" D_JSON_TIME "\":\"%s\""), GetDateAndTime(DT_LOCAL).c_str()); } @@ -1065,10 +1080,46 @@ int ResponseJsonEndEnd(void) * GPIO Module and Template management \*********************************************************************************************/ -void DigitalWrite(uint32_t gpio_pin, uint32_t state) +#ifndef ARDUINO_ESP8266_RELEASE_2_3_0 // Fix core 2.5.x ISR not in IRAM Exception +uint32_t Pin(uint32_t gpio, uint32_t index) ICACHE_RAM_ATTR; +#endif + +uint32_t Pin(uint32_t gpio, uint32_t index = 0); +uint32_t Pin(uint32_t gpio, uint32_t index) { +#ifdef ESP8266 + uint16_t real_gpio = gpio + index; +#else // ESP32 + uint16_t real_gpio = (gpio << 5) + index; +#endif // ESP8266 - ESP32 + for (uint32_t i = 0; i < ARRAY_SIZE(gpio_pin); i++) { + if (gpio_pin[i] == real_gpio) { + return i; // Pin number configured for gpio + } + } + return 99; // No pin used for gpio +} + +bool PinUsed(uint32_t gpio, uint32_t index = 0); +bool PinUsed(uint32_t gpio, uint32_t index) { + return (Pin(gpio, index) < 99); +} + +uint32_t GetPin(uint32_t lpin) { + if (lpin < ARRAY_SIZE(gpio_pin)) { + return gpio_pin[lpin]; + } else { + return GPIO_NONE; + } +} + +void SetPin(uint32_t lpin, uint32_t gpio) { + gpio_pin[lpin] = gpio; +} + +void DigitalWrite(uint32_t gpio_pin, uint32_t index, uint32_t state) { - if (pin[gpio_pin] < 99) { - digitalWrite(pin[gpio_pin], state &1); + if (PinUsed(gpio_pin, index)) { + digitalWrite(Pin(gpio_pin, index), state &1); } } @@ -1095,6 +1146,16 @@ bool ValidModule(uint32_t index) return ValidTemplateModule(index); } +bool ValidTemplate(const char *search) { + char template_name[strlen(SettingsText(SET_TEMPLATE_NAME)) +1]; + char search_name[strlen(search) +1]; + + LowerCase(template_name, SettingsText(SET_TEMPLATE_NAME)); + LowerCase(search_name, search); + + return (strstr(template_name, search_name) != nullptr); +} + String AnyModuleName(uint32_t index) { if (USER_MODULE == index) { @@ -1112,21 +1173,30 @@ String ModuleName(void) void ModuleGpios(myio *gp) { +#ifdef ESP8266 uint8_t *dest = (uint8_t *)gp; - memset(dest, GPIO_NONE, sizeof(myio)); + uint8_t src[ARRAY_SIZE(Settings.user_template.gp.io)]; +#else // ESP32 + uint16_t *dest = (uint16_t *)gp; + uint16_t src[ARRAY_SIZE(Settings.user_template.gp.io)]; +#endif // ESP8266 - ESP32 - uint8_t src[sizeof(mycfgio)]; + memset(dest, GPIO_NONE, sizeof(myio)); if (USER_MODULE == Settings.module) { memcpy(&src, &Settings.user_template.gp, sizeof(mycfgio)); } else { +#ifdef ESP8266 memcpy_P(&src, &kModules[Settings.module].gp, sizeof(mycfgio)); +#else // ESP32 + memcpy_P(&src, &kModules.gp, sizeof(mycfgio)); +#endif // ESP8266 - ESP32 } // 11 85 00 85 85 00 00 00 15 38 85 00 00 81 // AddLogBuffer(LOG_LEVEL_DEBUG, (uint8_t *)&src, sizeof(mycfgio)); uint32_t j = 0; - for (uint32_t i = 0; i < sizeof(mycfgio); i++) { + for (uint32_t i = 0; i < ARRAY_SIZE(Settings.user_template.gp.io); i++) { if (6 == i) { j = 9; } if (8 == i) { j = 12; } dest[j] = src[i]; @@ -1144,7 +1214,11 @@ gpio_flag ModuleFlag(void) if (USER_MODULE == Settings.module) { flag = Settings.user_template.flag; } else { +#ifdef ESP8266 memcpy_P(&flag, &kModules[Settings.module].flag, sizeof(gpio_flag)); +#else // ESP32 + memcpy_P(&flag, &kModules.flag, sizeof(gpio_flag)); +#endif // ESP8266 - ESP32 } return flag; @@ -1156,7 +1230,11 @@ void ModuleDefault(uint32_t module) Settings.user_template_base = module; char name[TOPSZ]; SettingsUpdateText(SET_TEMPLATE_NAME, GetTextIndexed(name, sizeof(name), module, kModuleNames)); +#ifdef ESP8266 memcpy_P(&Settings.user_template, &kModules[module], sizeof(mytmplt)); +#else // ESP32 + memcpy_P(&Settings.user_template, &kModules, sizeof(mytmplt)); +#endif // ESP8266 - ESP32 } void SetModuleType(void) @@ -1169,7 +1247,7 @@ bool FlashPin(uint32_t pin) return (((pin > 5) && (pin < 9)) || (11 == pin)); } -uint8_t ValidPin(uint32_t pin, uint32_t gpio) +uint32_t ValidPin(uint32_t pin, uint32_t gpio) { if (FlashPin(pin)) { return GPIO_NONE; // Disable flash pins GPIO6, GPIO7, GPIO8 and GPIO11 @@ -1187,17 +1265,23 @@ uint8_t ValidPin(uint32_t pin, uint32_t gpio) bool ValidGPIO(uint32_t pin, uint32_t gpio) { - return (GPIO_USER == ValidPin(pin, gpio)); // Only allow GPIO_USER pins + return (GPIO_USER == ValidPin(pin, BGPIO(gpio))); // Only allow GPIO_USER pins } +#ifdef ESP8266 bool ValidAdc(void) { gpio_flag flag = ModuleFlag(); uint32_t template_adc0 = flag.data &15; return (ADC0_USER == template_adc0); } +#endif // ESP8266 +#ifdef ESP8266 bool GetUsedInModule(uint32_t val, uint8_t *arr) +#else // ESP32 +bool GetUsedInModule(uint32_t val, uint16_t *arr) +#endif // ESP8266 - ESP32 { int offset = 0; @@ -1264,7 +1348,11 @@ bool JsonTemplate(const char* dataBuf) if (strlen(dataBuf) < 9) { return false; } // Workaround exception if empty JSON like {} - Needs checks +#ifdef ESP8266 StaticJsonBuffer<400> jb; // 331 from https://arduinojson.org/v5/assistant/ +#else + StaticJsonBuffer<999> jb; // 654 from https://arduinojson.org/v5/assistant/ +#endif JsonObject& obj = jb.parseObject(dataBuf); if (!obj.success()) { return false; } @@ -1274,16 +1362,24 @@ bool JsonTemplate(const char* dataBuf) SettingsUpdateText(SET_TEMPLATE_NAME, name); } if (obj[D_JSON_GPIO].success()) { - for (uint32_t i = 0; i < sizeof(mycfgio); i++) { + for (uint32_t i = 0; i < ARRAY_SIZE(Settings.user_template.gp.io); i++) { +#ifdef ESP8266 Settings.user_template.gp.io[i] = obj[D_JSON_GPIO][i] | 0; +#else // ESP32 + uint16_t gpio = obj[D_JSON_GPIO][i] | 0; + if (gpio == (AGPIO(GPIO_NONE) +1)) { + gpio = AGPIO(GPIO_USER); + } + Settings.user_template.gp.io[i] = gpio; +#endif } } if (obj[D_JSON_FLAG].success()) { - uint8_t flag = obj[D_JSON_FLAG] | 0; + uint32_t flag = obj[D_JSON_FLAG] | 0; memcpy(&Settings.user_template.flag, &flag, sizeof(gpio_flag)); } if (obj[D_JSON_BASE].success()) { - uint8_t base = obj[D_JSON_BASE]; + uint32_t base = obj[D_JSON_BASE]; if ((0 == base) || !ValidTemplateModule(base -1)) { base = 18; } Settings.user_template_base = base -1; // Default WEMOS } @@ -1293,8 +1389,16 @@ bool JsonTemplate(const char* dataBuf) void TemplateJson(void) { Response_P(PSTR("{\"" D_JSON_NAME "\":\"%s\",\"" D_JSON_GPIO "\":["), SettingsText(SET_TEMPLATE_NAME)); - for (uint32_t i = 0; i < sizeof(Settings.user_template.gp); i++) { + for (uint32_t i = 0; i < ARRAY_SIZE(Settings.user_template.gp.io); i++) { +#ifdef ESP8266 ResponseAppend_P(PSTR("%s%d"), (i>0)?",":"", Settings.user_template.gp.io[i]); +#else // ESP32 + uint16_t gpio = Settings.user_template.gp.io[i]; + if (gpio == AGPIO(GPIO_USER)) { + gpio = AGPIO(GPIO_NONE) +1; + } + ResponseAppend_P(PSTR("%s%d"), (i>0)?",":"", gpio); +#endif } ResponseAppend_P(PSTR("],\"" D_JSON_FLAG "\":%d,\"" D_JSON_BASE "\":%d}"), Settings.user_template.flag, Settings.user_template_base +1); } @@ -1378,6 +1482,7 @@ bool I2cValidRead(uint8_t addr, uint8_t reg, uint8_t size) } retry--; } + if (!retry) Wire.endTransmission(); return status; } @@ -1519,8 +1624,8 @@ void I2cScan(char *devs, unsigned int devs_len) // Return error codes defined in twi.h and core_esp8266_si2c.c // I2C_OK 0 // I2C_SCL_HELD_LOW 1 = SCL held low by another device, no procedure available to recover - // I2C_SCL_HELD_LOW_AFTER_READ 2 = I2C bus error. SCL held low beyond slave clock stretch time - // I2C_SDA_HELD_LOW 3 = I2C bus error. SDA line held low by slave/another_master after n bits + // I2C_SCL_HELD_LOW_AFTER_READ 2 = I2C bus error. SCL held low beyond client clock stretch time + // I2C_SDA_HELD_LOW 3 = I2C bus error. SDA line held low by client/another_master after n bits // I2C_SDA_HELD_LOW_AFTER_INIT 4 = line busy. SDA again held low by another device. 2nd master? uint8_t error = 0; @@ -1656,11 +1761,11 @@ void Syslog(void) } if (PortUdp.beginPacket(syslog_host_addr, Settings.syslog_port)) { char syslog_preamble[64]; // Hostname + Id - snprintf_P(syslog_preamble, sizeof(syslog_preamble), PSTR("%s ESP-"), my_hostname); + snprintf_P(syslog_preamble, sizeof(syslog_preamble), PSTR("%s ESP-"), NetworkHostname()); memmove(log_data + strlen(syslog_preamble), log_data, sizeof(log_data) - strlen(syslog_preamble)); log_data[sizeof(log_data) -1] = '\0'; memcpy(log_data, syslog_preamble, strlen(syslog_preamble)); - PortUdp.write(log_data, strlen(log_data)); + PortUdp_write(log_data, strlen(log_data)); PortUdp.endPacket(); delay(1); // Add time for UDP handling (#5512) } else { @@ -1703,7 +1808,7 @@ void AddLog(uint32_t loglevel) !global_state.mqtt_down && (loglevel <= Settings.mqttlog_level)) { MqttPublishLogging(mxtime); } - if (!global_state.wifi_down && + if (!global_state.network_down && (loglevel <= syslog_level)) { Syslog(); } prepped_loglevel = 0; @@ -1778,7 +1883,52 @@ void AddLogSerial(uint32_t loglevel) AddLogBuffer(loglevel, (uint8_t*)serial_in_buffer, serial_in_byte_counter); } -void AddLogMissed(char *sensor, uint32_t misses) +void AddLogMissed(const char *sensor, uint32_t misses) { AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SNS: %s missed %d"), sensor, SENSOR_MAX_MISS - misses); } + +void AddLogBufferSize(uint32_t loglevel, uint8_t *buffer, uint32_t count, uint32_t size) { + snprintf_P(log_data, sizeof(log_data), PSTR("DMP:")); + for (uint32_t i = 0; i < count; i++) { + if (1 == size) { // uint8_t + snprintf_P(log_data, sizeof(log_data), PSTR("%s %02X"), log_data, *(buffer)); + } else { // uint16_t + snprintf_P(log_data, sizeof(log_data), PSTR("%s %02X%02X"), log_data, *(buffer +1), *(buffer)); + } + buffer += size; + } + AddLog(loglevel); +} + +/*********************************************************************************************\ + * Uncompress static PROGMEM strings +\*********************************************************************************************/ + +#ifdef USE_UNISHOX_COMPRESSION + +#include + +Unishox compressor; + +String Decompress(const char * compressed, size_t uncompressed_size) { + String content(""); + + uncompressed_size += 2; // take a security margin + + // We use a nasty trick here. To avoid allocating twice the buffer, + // we first extend the buffer of the String object to the target size (maybe overshooting by 7 bytes) + // then we decompress in this buffer, + // and finally assign the raw string to the String, which happens to work: String uses memmove(), so overlapping works + content.reserve(uncompressed_size); + char * buffer = content.begin(); + + int32_t len = compressor.unishox_decompress(compressed, strlen_P(compressed), buffer, uncompressed_size); + if (len > 0) { + buffer[len] = 0; // terminate string with NULL + content = buffer; // copy in place + } + return content; +} + +#endif // USE_UNISHOX_COMPRESSION \ No newline at end of file diff --git a/tasmota/support_button.ino b/tasmota/support_button.ino index f30f3a287..2d7c6a415 100644 --- a/tasmota/support_button.ino +++ b/tasmota/support_button.ino @@ -1,7 +1,7 @@ /* support_button.ino - button support for Tasmota - Copyright (C) 2020 Theo Arends + Copyright (C) 2020 Federico Leoni and Theo Arends This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,15 +17,20 @@ along with this program. If not, see . */ -#define BUTTON_V1 -#ifdef BUTTON_V1 +#define BUTTON_V2 +#ifdef BUTTON_V2 /*********************************************************************************************\ * Button support \*********************************************************************************************/ -#define MAX_BUTTON_COMMANDS 5 // Max number of button commands supported -const char kCommands[] PROGMEM = - D_CMND_WIFICONFIG " 2|" D_CMND_WIFICONFIG " 2|" D_CMND_WIFICONFIG " 2|" D_CMND_RESTART " 1|" D_CMND_UPGRADE " 1"; +#define MAX_RELAY_BUTTON1 5 // Max number of relay controlled by BUTTON1 +#ifdef ESP32 +#define TOUCH_PIN_THRESHOLD 12 // Smaller value will treated as button press +#define TOUCH_HIT_THRESHOLD 3 // successful hits to filter out noise +#endif // ESP32 + +const char kMultiPress[] PROGMEM = + "|SINGLE|DOUBLE|TRIPLE|QUAD|PENTA|"; struct BUTTON { unsigned long debounce = 0; // Button debounce timer @@ -39,10 +44,22 @@ struct BUTTON { uint8_t dual_receive_count = 0; // Sonoff dual input flag uint8_t no_pullup_mask = 0; // key no pullup flag (1 = no pullup) uint8_t inverted_mask = 0; // Key inverted flag (1 = inverted) +#ifdef ESP32 + uint8_t touch_mask = 0; // Touch flag (1 = inverted) + uint8_t touch_hits[MAX_KEYS] = { 0 }; // Hits in a row to filter out noise +#endif // ESP32 uint8_t present = 0; // Number of buttons found flag uint8_t adc = 99; // ADC0 button number } Button; +#ifdef ESP32 +struct TOUCH_BUTTON { + uint8_t pin_threshold = TOUCH_PIN_THRESHOLD; + uint8_t hit_threshold = TOUCH_HIT_THRESHOLD; + uint8_t calibration = 0; // Bitfield +} TOUCH_BUTTON; +#endif // ESP32 + /********************************************************************************************/ void ButtonPullupFlag(uint8 button_bit) @@ -54,14 +71,24 @@ void ButtonInvertFlag(uint8 button_bit) { bitSet(Button.inverted_mask, button_bit); } - +#ifdef ESP32 +void ButtonTouchFlag(uint8 button_bit) +{ + bitSet(Button.touch_mask, button_bit); +} +#endif // ESP32 void ButtonInit(void) { Button.present = 0; +#ifdef ESP8266 + if ((SONOFF_DUAL == my_module_type) || (CH4 == my_module_type)) { + Button.present++; + } +#endif // ESP8266 for (uint32_t i = 0; i < MAX_KEYS; i++) { - if (pin[GPIO_KEY1 +i] < 99) { + if (PinUsed(GPIO_KEY1, i)) { Button.present++; - pinMode(pin[GPIO_KEY1 +i], bitRead(Button.no_pullup_mask, i) ? INPUT : ((16 == pin[GPIO_KEY1 +i]) ? INPUT_PULLDOWN_16 : INPUT_PULLUP)); + pinMode(Pin(GPIO_KEY1, i), bitRead(Button.no_pullup_mask, i) ? INPUT : ((16 == Pin(GPIO_KEY1, i)) ? INPUT_PULLDOWN_16 : INPUT_PULLUP)); } #ifndef USE_ADC_VCC else if ((99 == Button.adc) && ((ADC0_BUTTON == my_adc0) || (ADC0_BUTTON_INV == my_adc0))) { @@ -98,11 +125,10 @@ uint8_t ButtonSerial(uint8_t serial_in_byte) * Button handler with single press only or multi-press and hold on all buttons * * ButtonDebounce (50) - Debounce time in mSec - * SetOption1 (0) - If set do not execute config commands - * SetOption11 (0) - If set perform single press action on double press and reverse + * SetOption1 (0) - If set do not execute commands WifiConfig and Reset + * SetOption11 (0) - If set perform single press action on double press and reverse (on two relay devices only) * SetOption13 (0) - If set act on single press only - * SetOption32 (40) - Max button hold time in Seconds - * SetOption40 (0) - Number of 0.1 seconds until hold is discarded if SetOption1 1 and SetOption13 0 + * SetOption73 (0) - Decouple button from relay and send just mqtt topic \*********************************************************************************************/ void ButtonHandler(void) @@ -113,12 +139,11 @@ void ButtonHandler(void) uint16_t loops_per_second = 1000 / Settings.button_debounce; // ButtonDebounce (50) char scmnd[20]; -// uint8_t maxdev = (devices_present > MAX_KEYS) ? MAX_KEYS : devices_present; -// for (uint32_t button_index = 0; button_index < maxdev; button_index++) { for (uint32_t button_index = 0; button_index < MAX_KEYS; button_index++) { uint8_t button = NOT_PRESSED; uint8_t button_present = 0; +#ifdef ESP8266 if (!button_index && ((SONOFF_DUAL == my_module_type) || (CH4 == my_module_type))) { button_present = 1; if (Button.dual_code) { @@ -131,10 +156,39 @@ void ButtonHandler(void) Button.dual_code = 0; } } - else if (pin[GPIO_KEY1 +button_index] < 99) { - button_present = 1; - button = (digitalRead(pin[GPIO_KEY1 +button_index]) != bitRead(Button.inverted_mask, button_index)); + else { + if (PinUsed(GPIO_KEY1, button_index)) { + button_present = 1; + button = (digitalRead(Pin(GPIO_KEY1, button_index)) != bitRead(Button.inverted_mask, button_index)); + } } +#else + if (PinUsed(GPIO_KEY1, button_index)) { + button_present = 1; + if (bitRead(Button.touch_mask, button_index)) { // Touch + uint32_t _value = touchRead(Pin(GPIO_KEY1, button_index)); + button = NOT_PRESSED; + if (_value != 0) { // Probably read-error + if (_value < TOUCH_BUTTON.pin_threshold) { + if (++Button.touch_hits[button_index] > TOUCH_BUTTON.hit_threshold) { + if (!bitRead(TOUCH_BUTTON.calibration, button_index+1)) { + button = PRESSED; + } + } + } else { + Button.touch_hits[button_index] = 0; + } + } else { + Button.touch_hits[button_index] = 0; + } + if (bitRead(TOUCH_BUTTON.calibration, button_index+1)) { + AddLog_P2(LOG_LEVEL_INFO, PSTR("PLOT: %u, %u, %u,"), button_index+1, _value, Button.touch_hits[button_index]); // Button number (1..4), value, continuous hits under threshold + } + } else { // Normal button + button = (digitalRead(Pin(GPIO_KEY1, button_index)) != bitRead(Button.inverted_mask, button_index)); + } + } +#endif // ESP8266 #ifndef USE_ADC_VCC if (Button.adc == button_index) { button_present = 1; @@ -146,13 +200,13 @@ void ButtonHandler(void) } } #endif // USE_ADC_VCC - if (button_present) { XdrvMailbox.index = button_index; XdrvMailbox.payload = button; if (XdrvCall(FUNC_BUTTON_PRESSED)) { // Serviced } +#ifdef ESP8266 else if (SONOFF_4CHPRO == my_module_type) { if (Button.hold_timer[button_index]) { Button.hold_timer[button_index]--; } @@ -167,17 +221,27 @@ void ButtonHandler(void) if (!Button.hold_timer[button_index]) { button_pressed = true; } // Do not allow within 1 second } if (button_pressed) { - if (!SendKey(KEY_BUTTON, button_index +1, POWER_TOGGLE)) { // Execute Toggle command via MQTT if ButtonTopic is set - ExecuteCommandPower(button_index +1, POWER_TOGGLE, SRC_BUTTON); // Execute Toggle command internally + if (!Settings.flag3.mqtt_buttons) { // SetOption73 (0) - Decouple button from relay and send just mqtt topic + if (!SendKey(KEY_BUTTON, button_index +1, POWER_TOGGLE)) { // Execute Toggle command via MQTT if ButtonTopic is set + ExecuteCommandPower(button_index +1, POWER_TOGGLE, SRC_BUTTON); // Execute Toggle command internally + } + } else { + MqttButtonTopic(button_index +1, 1, 0); // SetOption73 (0) - Decouple button from relay and send just mqtt topic } } } +#endif // ESP8266 else { if ((PRESSED == button) && (NOT_PRESSED == Button.last_state[button_index])) { - if (Settings.flag.button_single) { // SetOption13 (0) - Allow only single button press for immediate action - AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION D_BUTTON "%d " D_IMMEDIATE), button_index +1); - if (!SendKey(KEY_BUTTON, button_index +1, POWER_TOGGLE)) { // Execute Toggle command via MQTT if ButtonTopic is set - ExecuteCommandPower(button_index +1, POWER_TOGGLE, SRC_BUTTON); // Execute Toggle command internally + + if (Settings.flag.button_single) { // SetOption13 (0) - Allow only single button press for immediate action, + if (!Settings.flag3.mqtt_buttons) { // SetOption73 (0) - Decouple button from relay and send just mqtt topic + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION D_BUTTON "%d " D_IMMEDIATE), button_index +1); + if (!SendKey(KEY_BUTTON, button_index +1, POWER_TOGGLE)) { // Execute Toggle command via MQTT if ButtonTopic is set + ExecuteCommandPower(button_index +1, POWER_TOGGLE, SRC_BUTTON); // Execute Toggle command internally + } + } else { + MqttButtonTopic(button_index +1, 1, 0); // SetOption73 1 - Decouple button from relay and send just mqtt topic } } else { Button.press_counter[button_index] = (Button.window_timer[button_index]) ? Button.press_counter[button_index] +1 : 1; @@ -191,87 +255,126 @@ void ButtonHandler(void) Button.hold_timer[button_index] = 0; } else { Button.hold_timer[button_index]++; - if (Settings.flag.button_single) { // SetOption13 (0) - Allow only single button press for immediate action + if (Settings.flag.button_single) { // SetOption13 (0) - Allow only single button press for immediate action if (Button.hold_timer[button_index] == loops_per_second * hold_time_extent * Settings.param[P_HOLD_TIME] / 10) { // SetOption32 (40) - Button held for factor times longer -// Settings.flag.button_single = 0; snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_SETOPTION "13 0")); // Disable single press only ExecuteCommand(scmnd, SRC_BUTTON); } } else { - if (Settings.flag.button_restrict) { // SetOption1 (0) - Button restriction - if (Settings.param[P_HOLD_IGNORE] > 0) { // SetOption40 (0) - Do not ignore button hold - if (Button.hold_timer[button_index] > loops_per_second * Settings.param[P_HOLD_IGNORE] / 10) { - Button.hold_timer[button_index] = 0; // Reset button hold counter to stay below hold trigger - Button.press_counter[button_index] = 0; // Discard button press to disable functionality - DEBUG_CORE_LOG(PSTR("BTN: " D_BUTTON "%d cancel by " D_CMND_SETOPTION "40 %d"), button_index +1, Settings.param[P_HOLD_IGNORE]); - } - } - if (Button.hold_timer[button_index] == loops_per_second * Settings.param[P_HOLD_TIME] / 10) { // SetOption32 (40) - Button hold - Button.press_counter[button_index] = 0; + if (Button.hold_timer[button_index] == loops_per_second * Settings.param[P_HOLD_TIME] / 10) { // SetOption32 (40) - Button hold + Button.press_counter[button_index] = 0; + if (Settings.flag3.mqtt_buttons) { // SetOption73 (0) - Decouple button from relay and send just mqtt topic + MqttButtonTopic(button_index +1, 3, 1); + } else { SendKey(KEY_BUTTON, button_index +1, POWER_HOLD); // Execute Hold command via MQTT if ButtonTopic is set } } else { - if (Button.hold_timer[button_index] == loops_per_second * hold_time_extent * Settings.param[P_HOLD_TIME] / 10) { // SetOption32 (40) - Button held for factor times longer - Button.press_counter[button_index] = 0; - snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_RESET " 1")); - ExecuteCommand(scmnd, SRC_BUTTON); + if (!Settings.flag.button_restrict) { // SetOption1 - Control button multipress + if ((Button.hold_timer[button_index] == loops_per_second * hold_time_extent * Settings.param[P_HOLD_TIME] / 10)) { // SetOption32 (40) - Button held for factor times longer + Button.press_counter[button_index] = 0; + snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_RESET " 1")); + ExecuteCommand(scmnd, SRC_BUTTON); + } } } } } - if (!Settings.flag.button_single) { // SetOption13 (0) - Allow multi-press + if (!Settings.flag.button_single) { // SetOption13 (0) - Allow multi-press if (Button.window_timer[button_index]) { Button.window_timer[button_index]--; } else { - if (!restart_flag && !Button.hold_timer[button_index] && (Button.press_counter[button_index] > 0) && (Button.press_counter[button_index] < MAX_BUTTON_COMMANDS +3)) { + if (!restart_flag && !Button.hold_timer[button_index] && (Button.press_counter[button_index] > 0) && (Button.press_counter[button_index] < 7)) { + bool single_press = false; - if (Button.press_counter[button_index] < 3) { // Single or Double press + if (Button.press_counter[button_index] < 3) { // Single or Double press +#ifdef ESP8266 if ((SONOFF_DUAL_R2 == my_module_type) || (SONOFF_DUAL == my_module_type) || (CH4 == my_module_type)) { single_press = true; - } else { + } else +#endif // ESP8266 + { single_press = (Settings.flag.button_swap +1 == Button.press_counter[button_index]); // SetOption11 (0) if ((1 == Button.present) && (2 == devices_present)) { // Single Button with two devices only if (Settings.flag.button_swap) { // SetOption11 (0) Button.press_counter[button_index] = (single_press) ? 1 : 2; } - } else { - Button.press_counter[button_index] = 1; } } } -#if defined(USE_LIGHT) && defined(ROTARY_V1) +#ifdef ROTARY_V1 if (!((0 == button_index) && RotaryButtonPressed())) { #endif - if (single_press && SendKey(KEY_BUTTON, button_index + Button.press_counter[button_index], POWER_TOGGLE)) { // Execute Toggle command via MQTT if ButtonTopic is set + if (!Settings.flag3.mqtt_buttons && single_press && SendKey(KEY_BUTTON, button_index + Button.press_counter[button_index], POWER_TOGGLE)) { // Execute Toggle command via MQTT if ButtonTopic is set // Success } else { - if (Button.press_counter[button_index] < 3) { // Single or Double press - if (WifiState() > WIFI_RESTART) { // Wifimanager active + if (Button.press_counter[button_index] < 6) { // Single to Penta press + if (WifiState() > WIFI_RESTART) { // Wifimanager active restart_flag = 1; - } else { - ExecuteCommandPower(button_index + Button.press_counter[button_index], POWER_TOGGLE, SRC_BUTTON); // Execute Toggle command internally } - } else { // 3 - 7 press - if (!Settings.flag.button_restrict) { // SetOption1 (0) - GetTextIndexed(scmnd, sizeof(scmnd), Button.press_counter[button_index] -3, kCommands); + if (!Settings.flag3.mqtt_buttons) { // SetOption73 - Detach buttons from relays and enable MQTT action state for multipress + if (Button.press_counter[button_index] == 1) { // By default first press always send a TOGGLE (2) + ExecuteCommandPower(button_index + Button.press_counter[button_index], POWER_TOGGLE, SRC_BUTTON); + } else { + SendKey(KEY_BUTTON, button_index +1, Button.press_counter[button_index] +9); // 2,3,4 and 5 press send just the key value (11,12,13 and 14) for rules + if (0 == button_index) { // BUTTON1 can toggle up to 5 relays if present. If a relay is not present will send out the key value (2,11,12,13 and 14) for rules + bool valid_relay = PinUsed(GPIO_REL1, Button.press_counter[button_index]-1); +#ifdef ESP8266 + if ((SONOFF_DUAL == my_module_type) || (CH4 == my_module_type)) { + valid_relay = (Button.press_counter[button_index] <= devices_present); + } +#endif // ESP8266 + if ((Button.press_counter[button_index] > 1) && valid_relay && (Button.press_counter[button_index] <= MAX_RELAY_BUTTON1)) { + ExecuteCommandPower(button_index + Button.press_counter[button_index], POWER_TOGGLE, SRC_BUTTON); // Execute Toggle command internally +// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DBG: Relay%d found on GPIO%d"), Button.press_counter[button_index], Pin(GPIO_REL1, Button.press_counter[button_index]-1)); + } + } + } + } + + } else { // 6 press start wificonfig 2 + if (!Settings.flag.button_restrict) { + snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_WIFICONFIG " 2")); ExecuteCommand(scmnd, SRC_BUTTON); } } + if (Settings.flag3.mqtt_buttons) { // SetOption73 (0) - Decouple button from relay and send just mqtt topic + if (Button.press_counter[button_index] >= 1 && Button.press_counter[button_index] <= 5) { + MqttButtonTopic(button_index +1, Button.press_counter[button_index], 0); + } + } } -#if defined(USE_LIGHT) && defined(ROTARY_V1) +#ifdef ROTARY_V1 } #endif Button.press_counter[button_index] = 0; } } } + } } Button.last_state[button_index] = button; } } +void MqttButtonTopic(uint8_t button_id, uint8_t action, uint8_t hold) +{ + char scommand[CMDSZ]; + char stopic[TOPSZ]; + char mqttstate[7]; + + SendKey(KEY_BUTTON, button_id, (hold) ? 3 : action +9); + + if (!Settings.flag.hass_discovery) { + GetTextIndexed(mqttstate, sizeof(mqttstate), action, kMultiPress); + snprintf_P(scommand, sizeof(scommand), PSTR("BUTTON%d"), button_id); + GetTopic_P(stopic, STAT, mqtt_topic, scommand); + Response_P(S_JSON_COMMAND_SVALUE, "ACTION", (hold) ? SettingsText(SET_STATE_TXT4) : mqttstate); + MqttPublish(stopic); + } +} + void ButtonLoop(void) { if (Button.present) { @@ -282,4 +385,4 @@ void ButtonLoop(void) } } -#endif // BUTTON_V1 +#endif // BUTTON_V2 \ No newline at end of file diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index 366bc403c..a54b50e89 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -20,14 +20,14 @@ const char kTasmotaCommands[] PROGMEM = "|" // No prefix D_CMND_BACKLOG "|" D_CMND_DELAY "|" D_CMND_POWER "|" D_CMND_STATUS "|" D_CMND_STATE "|" D_CMND_SLEEP "|" D_CMND_UPGRADE "|" D_CMND_UPLOAD "|" D_CMND_OTAURL "|" D_CMND_SERIALLOG "|" D_CMND_RESTART "|" D_CMND_POWERONSTATE "|" D_CMND_PULSETIME "|" D_CMND_BLINKTIME "|" D_CMND_BLINKCOUNT "|" D_CMND_SAVEDATA "|" - D_CMND_SETOPTION "|" D_CMND_TEMPERATURE_RESOLUTION "|" D_CMND_HUMIDITY_RESOLUTION "|" D_CMND_PRESSURE_RESOLUTION "|" D_CMND_POWER_RESOLUTION "|" + D_CMND_SO "|" D_CMND_SETOPTION "|" D_CMND_TEMPERATURE_RESOLUTION "|" D_CMND_HUMIDITY_RESOLUTION "|" D_CMND_PRESSURE_RESOLUTION "|" D_CMND_POWER_RESOLUTION "|" D_CMND_VOLTAGE_RESOLUTION "|" D_CMND_FREQUENCY_RESOLUTION "|" D_CMND_CURRENT_RESOLUTION "|" D_CMND_ENERGY_RESOLUTION "|" D_CMND_WEIGHT_RESOLUTION "|" D_CMND_MODULE "|" D_CMND_MODULES "|" D_CMND_GPIO "|" D_CMND_GPIOS "|" D_CMND_TEMPLATE "|" D_CMND_PWM "|" D_CMND_PWMFREQUENCY "|" D_CMND_PWMRANGE "|" D_CMND_BUTTONDEBOUNCE "|" D_CMND_SWITCHDEBOUNCE "|" D_CMND_SYSLOG "|" D_CMND_LOGHOST "|" D_CMND_LOGPORT "|" D_CMND_SERIALSEND "|" D_CMND_BAUDRATE "|" D_CMND_SERIALCONFIG "|" D_CMND_SERIALDELIMITER "|" D_CMND_IPADDRESS "|" D_CMND_NTPSERVER "|" D_CMND_AP "|" D_CMND_SSID "|" D_CMND_PASSWORD "|" D_CMND_HOSTNAME "|" D_CMND_WIFICONFIG "|" - D_CMND_FRIENDLYNAME "|" D_CMND_SWITCHMODE "|" D_CMND_INTERLOCK "|" D_CMND_TELEPERIOD "|" D_CMND_RESET "|" D_CMND_TIME "|" D_CMND_TIMEZONE "|" D_CMND_TIMESTD "|" - D_CMND_TIMEDST "|" D_CMND_ALTITUDE "|" D_CMND_LEDPOWER "|" D_CMND_LEDSTATE "|" D_CMND_LEDMASK "|" D_CMND_WIFIPOWER "|" D_CMND_TEMPOFFSET "|" D_CMND_HUMOFFSET "|" - D_CMND_SPEEDUNIT "|" + D_CMND_DEVICENAME "|" D_CMND_FRIENDLYNAME "|" D_CMND_SWITCHMODE "|" D_CMND_INTERLOCK "|" D_CMND_TELEPERIOD "|" D_CMND_RESET "|" D_CMND_TIME "|" D_CMND_TIMEZONE "|" D_CMND_TIMESTD "|" + D_CMND_TIMEDST "|" D_CMND_ALTITUDE "|" D_CMND_LEDPOWER "|" D_CMND_LEDSTATE "|" D_CMND_LEDMASK "|" D_CMND_LEDPWM_ON "|" D_CMND_LEDPWM_OFF "|" D_CMND_LEDPWM_MODE "|" + D_CMND_WIFIPOWER "|" D_CMND_TEMPOFFSET "|" D_CMND_HUMOFFSET "|" D_CMND_SPEEDUNIT "|" D_CMND_GLOBAL_TEMP "|" D_CMND_GLOBAL_HUM "|" D_CMND_WIFI "|" #ifdef USE_I2C D_CMND_I2CSCAN "|" D_CMND_I2CDRIVER "|" #endif @@ -36,21 +36,25 @@ const char kTasmotaCommands[] PROGMEM = "|" // No prefix #ifdef USE_DEVICE_GROUPS_SEND D_CMND_DEVGROUP_SEND "|" #endif // USE_DEVICE_GROUPS_SEND - D_CMND_DEVGROUP_SHARE "|" + D_CMND_DEVGROUP_SHARE "|" D_CMND_DEVGROUPSTATUS "|" #endif // USE_DEVICE_GROUPS - D_CMND_SENSOR "|" D_CMND_DRIVER; + D_CMND_SENSOR "|" D_CMND_DRIVER +#ifdef ESP32 + "|" D_CMND_TOUCH_CAL "|" D_CMND_TOUCH_THRES "|" D_CMND_TOUCH_NUM "|" D_CMND_CPU_FREQUENCY +#endif //ESP32 + ; void (* const TasmotaCommand[])(void) PROGMEM = { &CmndBacklog, &CmndDelay, &CmndPower, &CmndStatus, &CmndState, &CmndSleep, &CmndUpgrade, &CmndUpgrade, &CmndOtaUrl, &CmndSeriallog, &CmndRestart, &CmndPowerOnState, &CmndPulsetime, &CmndBlinktime, &CmndBlinkcount, &CmndSavedata, - &CmndSetoption, &CmndTemperatureResolution, &CmndHumidityResolution, &CmndPressureResolution, &CmndPowerResolution, + &CmndSetoption, &CmndSetoption, &CmndTemperatureResolution, &CmndHumidityResolution, &CmndPressureResolution, &CmndPowerResolution, &CmndVoltageResolution, &CmndFrequencyResolution, &CmndCurrentResolution, &CmndEnergyResolution, &CmndWeightResolution, &CmndModule, &CmndModules, &CmndGpio, &CmndGpios, &CmndTemplate, &CmndPwm, &CmndPwmfrequency, &CmndPwmrange, &CmndButtonDebounce, &CmndSwitchDebounce, &CmndSyslog, &CmndLoghost, &CmndLogport, &CmndSerialSend, &CmndBaudrate, &CmndSerialConfig, &CmndSerialDelimiter, &CmndIpAddress, &CmndNtpServer, &CmndAp, &CmndSsid, &CmndPassword, &CmndHostname, &CmndWifiConfig, - &CmndFriendlyname, &CmndSwitchMode, &CmndInterlock, &CmndTeleperiod, &CmndReset, &CmndTime, &CmndTimezone, &CmndTimeStd, - &CmndTimeDst, &CmndAltitude, &CmndLedPower, &CmndLedState, &CmndLedMask, &CmndWifiPower, &CmndTempOffset, &CmndHumOffset, - &CmndSpeedUnit, + &CmndDevicename, &CmndFriendlyname, &CmndSwitchMode, &CmndInterlock, &CmndTeleperiod, &CmndReset, &CmndTime, &CmndTimezone, &CmndTimeStd, + &CmndTimeDst, &CmndAltitude, &CmndLedPower, &CmndLedState, &CmndLedMask, &CmndLedPwmOn, &CmndLedPwmOff, &CmndLedPwmMode, + &CmndWifiPower, &CmndTempOffset, &CmndHumOffset, &CmndSpeedUnit, &CmndGlobalTemp, &CmndGlobalHum, &CmndWifi, #ifdef USE_I2C &CmndI2cScan, CmndI2cDriver, #endif @@ -59,9 +63,13 @@ void (* const TasmotaCommand[])(void) PROGMEM = { #ifdef USE_DEVICE_GROUPS_SEND &CmndDevGroupSend, #endif // USE_DEVICE_GROUPS_SEND - &CmndDevGroupShare, + &CmndDevGroupShare, &CmndDevGroupStatus, #endif // USE_DEVICE_GROUPS - &CmndSensor, &CmndDriver }; + &CmndSensor, &CmndDriver +#ifdef ESP32 + ,&CmndTouchCal, &CmndTouchThres, &CmndTouchNum, &CmndCpuFrequency +#endif //ESP32 + }; const char kWifiConfig[] PROGMEM = D_WCFG_0_RESTART "||" D_WCFG_2_WIFIMANAGER "||" D_WCFG_4_RETRY "|" D_WCFG_5_WAIT "|" D_WCFG_6_SERIAL "|" D_WCFG_7_WIFIMANAGER_RESET_ONLY; @@ -87,15 +95,12 @@ void ResponseCmndIdxNumber(int value) void ResponseCmndChar_P(const char* value) { - size_t buf_size = strlen_P(value); - char buf[buf_size + 1]; - strcpy_P(buf, value); - Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, buf); + Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, value); } void ResponseCmndChar(const char* value) { - Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, value); + Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, EscapeJSONString(value).c_str()); } void ResponseCmndStateText(uint32_t value) @@ -110,7 +115,7 @@ void ResponseCmndDone(void) void ResponseCmndIdxChar(const char* value) { - Response_P(S_JSON_COMMAND_INDEX_SVALUE, XdrvMailbox.command, XdrvMailbox.index, value); + Response_P(S_JSON_COMMAND_INDEX_SVALUE, XdrvMailbox.command, XdrvMailbox.index, EscapeJSONString(value).c_str()); } void ResponseCmndAll(uint32_t text_index, uint32_t count) @@ -119,7 +124,7 @@ void ResponseCmndAll(uint32_t text_index, uint32_t count) mqtt_data[0] = '\0'; for (uint32_t i = 0; i < count; i++) { if ((SET_MQTT_GRP_TOPIC == text_index) && (1 == i)) { real_index = SET_MQTT_GRP_TOPIC2 -1; } - ResponseAppend_P(PSTR("%c\"%s%d\":\"%s\""), (i) ? ',' : '{', XdrvMailbox.command, i +1, SettingsText(real_index +i)); + ResponseAppend_P(PSTR("%c\"%s%d\":\"%s\""), (i) ? ',' : '{', XdrvMailbox.command, i +1, EscapeJSONString(SettingsText(real_index +i)).c_str()); } ResponseJsonEnd(); } @@ -204,14 +209,19 @@ void CommandHandler(char* topicBuf, char* dataBuf, uint32_t data_len) if (type != nullptr) { type++; uint32_t i; - for (i = 0; i < strlen(type); i++) { - type[i] = toupper(type[i]); + int nLen; // strlen(type) + char *s = type; + for (nLen = 0; *s; s++, nLen++) { + *s=toupper(*s); } - while (isdigit(type[i-1])) { - i--; + i = nLen; + if (i > 0) { // may be 0 + while (isdigit(type[i-1])) { + i--; + } } - if (i < strlen(type)) { - index = atoi(type +i); + if (i < nLen) { + index = atoi(type + i); user_index = true; } type[i] = '\0'; @@ -387,17 +397,17 @@ void CmndStatus(void) #endif // USE_SONOFF_IFAN stemp[0] = '\0'; for (uint32_t i = 0; i < maxfn; i++) { - snprintf_P(stemp, sizeof(stemp), PSTR("%s%s\"%s\"" ), stemp, (i > 0 ? "," : ""), SettingsText(SET_FRIENDLYNAME1 +i)); + snprintf_P(stemp, sizeof(stemp), PSTR("%s%s\"%s\"" ), stemp, (i > 0 ? "," : ""), EscapeJSONString(SettingsText(SET_FRIENDLYNAME1 +i)).c_str()); } stemp2[0] = '\0'; for (uint32_t i = 0; i < MAX_SWITCHES; i++) { snprintf_P(stemp2, sizeof(stemp2), PSTR("%s%s%d" ), stemp2, (i > 0 ? "," : ""), Settings.switchmode[i]); } - Response_P(PSTR("{\"" D_CMND_STATUS "\":{\"" D_CMND_MODULE "\":%d,\"" D_CMND_FRIENDLYNAME "\":[%s],\"" D_CMND_TOPIC "\":\"%s\",\"" + Response_P(PSTR("{\"" D_CMND_STATUS "\":{\"" D_CMND_MODULE "\":%d,\"" D_CMND_DEVICENAME "\":\"%s\",\"" D_CMND_FRIENDLYNAME "\":[%s],\"" D_CMND_TOPIC "\":\"%s\",\"" D_CMND_BUTTONTOPIC "\":\"%s\",\"" D_CMND_POWER "\":%d,\"" D_CMND_POWERONSTATE "\":%d,\"" D_CMND_LEDSTATE "\":%d,\"" D_CMND_LEDMASK "\":\"%04X\",\"" D_CMND_SAVEDATA "\":%d,\"" D_JSON_SAVESTATE "\":%d,\"" D_CMND_SWITCHTOPIC "\":\"%s\",\"" D_CMND_SWITCHMODE "\":[%s],\"" D_CMND_BUTTONRETAIN "\":%d,\"" D_CMND_SWITCHRETAIN "\":%d,\"" D_CMND_SENSORRETAIN "\":%d,\"" D_CMND_POWERRETAIN "\":%d}}"), - ModuleNr(), stemp, mqtt_topic, + ModuleNr(), EscapeJSONString(SettingsText(SET_DEVICENAME)).c_str(), stemp, mqtt_topic, SettingsText(SET_MQTT_BUTTON_TOPIC), power, Settings.poweronstate, Settings.ledstate, Settings.ledmask, Settings.save_data, Settings.flag.save_state, // SetOption0 - Save power state and use after restart @@ -413,21 +423,35 @@ void CmndStatus(void) if ((0 == payload) || (1 == payload)) { Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS1_PARAMETER "\":{\"" D_JSON_BAUDRATE "\":%d,\"" D_CMND_SERIALCONFIG "\":\"%s\",\"" D_CMND_GROUPTOPIC "\":\"%s\",\"" D_CMND_OTAURL "\":\"%s\",\"" D_JSON_RESTARTREASON "\":\"%s\",\"" D_JSON_UPTIME "\":\"%s\",\"" D_JSON_STARTUPUTC "\":\"%s\",\"" D_CMND_SLEEP "\":%d,\"" - D_JSON_CONFIG_HOLDER "\":%d,\"" D_JSON_BOOTCOUNT "\":%d,\"BCResetTime\":\"%s\",\"" D_JSON_SAVECOUNT "\":%d,\"" D_JSON_SAVEADDRESS "\":\"%X\"}}"), + D_JSON_CONFIG_HOLDER "\":%d,\"" D_JSON_BOOTCOUNT "\":%d,\"BCResetTime\":\"%s\",\"" D_JSON_SAVECOUNT "\":%d" +#ifdef ESP8266 + ",\"" D_JSON_SAVEADDRESS "\":\"%X\"" +#endif + "}}"), Settings.baudrate * 300, GetSerialConfig().c_str(), SettingsText(SET_MQTT_GRP_TOPIC), SettingsText(SET_OTAURL), GetResetReason().c_str(), GetUptime().c_str(), GetDateAndTime(DT_RESTART).c_str(), Settings.sleep, - Settings.cfg_holder, Settings.bootcount, GetDateAndTime(DT_BOOTCOUNT).c_str(), Settings.save_flag, GetSettingsAddress()); + Settings.cfg_holder, Settings.bootcount, GetDateAndTime(DT_BOOTCOUNT).c_str(), Settings.save_flag +#ifdef ESP8266 + , GetSettingsAddress() +#endif + ); MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "1")); } if ((0 == payload) || (2 == payload)) { - Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS2_FIRMWARE "\":{\"" D_JSON_VERSION "\":\"%s%s\",\"" D_JSON_BUILDDATETIME "\":\"%s\",\"" - D_JSON_BOOTVERSION "\":%d,\"" D_JSON_COREVERSION "\":\"" ARDUINO_ESP8266_RELEASE "\",\"" D_JSON_SDKVERSION "\":\"%s\"," - "\"Hardware\":\"%s\"" + Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS2_FIRMWARE "\":{\"" D_JSON_VERSION "\":\"%s%s\",\"" D_JSON_BUILDDATETIME "\":\"%s\"" +#ifdef ESP8266 + ",\"" D_JSON_BOOTVERSION "\":%d" +#endif + ",\"" D_JSON_COREVERSION "\":\"" ARDUINO_CORE_RELEASE "\",\"" D_JSON_SDKVERSION "\":\"%s\"," + "\"CpuFrequency\":%d,\"Hardware\":\"%s\"" "%s}}"), - my_version, my_image, GetBuildDateAndTime().c_str(), - ESP.getBootVersion(), ESP.getSdkVersion(), - GetDeviceHardware().c_str(), + my_version, my_image, GetBuildDateAndTime().c_str() +#ifdef ESP8266 + , ESP.getBootVersion() +#endif + , ESP.getSdkVersion(), + ESP.getCpuFreqMHz(), GetDeviceHardware().c_str(), GetStatistics().c_str()); MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "2")); } @@ -437,7 +461,7 @@ void CmndStatus(void) D_CMND_LOGHOST "\":\"%s\",\"" D_CMND_LOGPORT "\":%d,\"" D_CMND_SSID "\":[\"%s\",\"%s\"],\"" D_CMND_TELEPERIOD "\":%d,\"" D_JSON_RESOLUTION "\":\"%08X\",\"" D_CMND_SETOPTION "\":[\"%08X\",\"%s\",\"%08X\",\"%08X\"]}}"), Settings.seriallog_level, Settings.weblog_level, Settings.mqttlog_level, Settings.syslog_level, - SettingsText(SET_SYSLOG_HOST), Settings.syslog_port, SettingsText(SET_STASSID1), SettingsText(SET_STASSID2), Settings.tele_period, + SettingsText(SET_SYSLOG_HOST), Settings.syslog_port, EscapeJSONString(SettingsText(SET_STASSID1)).c_str(), EscapeJSONString(SettingsText(SET_STASSID2)).c_str(), Settings.tele_period, Settings.flag2.data, Settings.flag.data, ToHex_P((unsigned char*)Settings.param, PARAM8_SIZE, stemp2, sizeof(stemp2)), Settings.flag3.data, Settings.flag4.data); MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "3")); @@ -445,10 +469,24 @@ void CmndStatus(void) if ((0 == payload) || (4 == payload)) { Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS4_MEMORY "\":{\"" D_JSON_PROGRAMSIZE "\":%d,\"" D_JSON_FREEMEMORY "\":%d,\"" D_JSON_HEAPSIZE "\":%d,\"" - D_JSON_PROGRAMFLASHSIZE "\":%d,\"" D_JSON_FLASHSIZE "\":%d,\"" D_JSON_FLASHCHIPID "\":\"%06X\",\"" D_JSON_FLASHMODE "\":%d,\"" +#ifdef ESP32 + D_JSON_PSRMAXMEMORY "\":%d,\"" D_JSON_PSRFREEMEMORY "\":%d," +#endif + D_JSON_PROGRAMFLASHSIZE "\":%d,\"" D_JSON_FLASHSIZE "\":%d" +#ifdef ESP8266 + ",\"" D_JSON_FLASHCHIPID "\":\"%06X\"" +#endif + ",\"FlashFrequency\":%d,\"" D_JSON_FLASHMODE "\":%d,\"" D_JSON_FEATURES "\":[\"%08X\",\"%08X\",\"%08X\",\"%08X\",\"%08X\",\"%08X\",\"%08X\"]"), - ESP.getSketchSize()/1024, ESP.getFreeSketchSpace()/1024, ESP.getFreeHeap()/1024, - ESP.getFlashChipSize()/1024, ESP.getFlashChipRealSize()/1024, ESP.getFlashChipId(), ESP.getFlashChipMode(), + ESP_getSketchSize()/1024, ESP.getFreeSketchSpace()/1024, ESP_getFreeHeap()/1024, +#ifdef ESP32 + ESP.getPsramSize()/1024, ESP.getFreePsram()/1024, +#endif + ESP.getFlashChipSize()/1024, ESP.getFlashChipRealSize()/1024 +#ifdef ESP8266 + , ESP.getFlashChipId() +#endif + , ESP.getFlashChipSpeed()/1000000, ESP.getFlashChipMode(), LANGUAGE_LCID, feature_drv1, feature_drv2, feature_sns1, feature_sns2, feature5, feature6); XsnsDriverState(); ResponseAppend_P(PSTR(",\"Sensors\":")); @@ -461,8 +499,8 @@ void CmndStatus(void) Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS5_NETWORK "\":{\"" D_CMND_HOSTNAME "\":\"%s\",\"" D_CMND_IPADDRESS "\":\"%s\",\"" D_JSON_GATEWAY "\":\"%s\",\"" D_JSON_SUBNETMASK "\":\"%s\",\"" D_JSON_DNSSERVER "\":\"%s\",\"" D_JSON_MAC "\":\"%s\",\"" D_CMND_WEBSERVER "\":%d,\"" D_CMND_WIFICONFIG "\":%d,\"" D_CMND_WIFIPOWER "\":%s}}"), - my_hostname, WiFi.localIP().toString().c_str(), IPAddress(Settings.ip_address[1]).toString().c_str(), - IPAddress(Settings.ip_address[2]).toString().c_str(), IPAddress(Settings.ip_address[3]).toString().c_str(), WiFi.macAddress().c_str(), + NetworkHostname(), NetworkAddress().toString().c_str(), IPAddress(Settings.ip_address[1]).toString().c_str(), + IPAddress(Settings.ip_address[2]).toString().c_str(), IPAddress(Settings.ip_address[3]).toString().c_str(), NetworkMacAddress().c_str(), Settings.webserver, Settings.sta_config, WifiGetOutputPower().c_str()); MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "5")); } @@ -470,8 +508,8 @@ void CmndStatus(void) if (((0 == payload) || (6 == payload)) && Settings.flag.mqtt_enabled) { // SetOption3 - Enable MQTT Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS6_MQTT "\":{\"" D_CMND_MQTTHOST "\":\"%s\",\"" D_CMND_MQTTPORT "\":%d,\"" D_CMND_MQTTCLIENT D_JSON_MASK "\":\"%s\",\"" D_CMND_MQTTCLIENT "\":\"%s\",\"" D_CMND_MQTTUSER "\":\"%s\",\"" D_JSON_MQTT_COUNT "\":%d,\"MAX_PACKET_SIZE\":%d,\"KEEPALIVE\":%d}}"), - SettingsText(SET_MQTT_HOST), Settings.mqtt_port, SettingsText(SET_MQTT_CLIENT), - mqtt_client, SettingsText(SET_MQTT_USER), MqttConnectCount(), MQTT_MAX_PACKET_SIZE, MQTT_KEEPALIVE); + SettingsText(SET_MQTT_HOST), Settings.mqtt_port, EscapeJSONString(SettingsText(SET_MQTT_CLIENT)).c_str(), + mqtt_client, EscapeJSONString(SettingsText(SET_MQTT_USER)).c_str(), MqttConnectCount(), MQTT_MAX_PACKET_SIZE, MQTT_KEEPALIVE); MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "6")); } @@ -537,6 +575,11 @@ void CmndStatus(void) #ifdef USE_SCRIPT_STATUS if (bitRead(Settings.rule_enabled, 0)) Run_Scripter(">U",2,mqtt_data); #endif + + if (payload) { + XdrvRulesProcess(); // Allow rule processing on single Status command only + } + mqtt_data[0] = '\0'; } @@ -576,14 +619,41 @@ void CmndHumOffset(void) ResponseCmndFloat((float)(Settings.hum_comp) / 10, 1); } +void CmndGlobalTemp(void) +{ + if (XdrvMailbox.data_len > 0) { + float temperature = CharToFloat(XdrvMailbox.data); + if (!isnan(temperature) && Settings.flag.temperature_conversion) { // SetOption8 - Switch between Celsius or Fahrenheit + temperature = (temperature - 32) / 1.8; // Celsius + } + if ((temperature >= -50.0f) && (temperature <= 100.0f)) { + ConvertTemp(temperature); + global_update = 1; // Keep global values just entered valid + } + } + ResponseCmndFloat(global_temperature_celsius, 1); +} + +void CmndGlobalHum(void) +{ + if (XdrvMailbox.data_len > 0) { + float humidity = CharToFloat(XdrvMailbox.data); + if ((humidity >= 0.0) && (humidity <= 100.0)) { + ConvertHumidity(humidity); + global_update = 1; // Keep global values just entered valid + } + } + ResponseCmndFloat(global_humidity, 1); +} + void CmndSleep(void) { if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 251)) { Settings.sleep = XdrvMailbox.payload; - sleep = XdrvMailbox.payload; + ssleep = XdrvMailbox.payload; WiFiSetSleepMode(); } - Response_P(S_JSON_COMMAND_NVALUE_ACTIVE_NVALUE, XdrvMailbox.command, Settings.sleep, sleep); + Response_P(S_JSON_COMMAND_NVALUE_ACTIVE_NVALUE, XdrvMailbox.command, Settings.sleep, ssleep); } @@ -605,7 +675,7 @@ void CmndUpgrade(void) void CmndOtaUrl(void) { if (XdrvMailbox.data_len > 0) { - SettingsUpdateText(SET_OTAURL, (SC_DEFAULT == Shortcut()) ? OTA_URL : XdrvMailbox.data); + SettingsUpdateText(SET_OTAURL, (SC_DEFAULT == Shortcut()) ? PSTR(OTA_URL) : XdrvMailbox.data); } ResponseCmndChar(SettingsText(SET_OTAURL)); } @@ -646,7 +716,10 @@ void CmndRestart(void) void CmndPowerOnState(void) { - if (my_module_type != MOTOR) { +#ifdef ESP8266 + if (my_module_type != MOTOR) +#endif // ESP8266 + { /* 0 = Keep relays off after power on * 1 = Turn relays on after power on, if PulseTime set wait for PulseTime seconds, and turn relays off * 2 = Toggle relays after power on @@ -724,6 +797,8 @@ void CmndSavedata(void) void CmndSetoption(void) { + snprintf_P(XdrvMailbox.command, CMDSZ, PSTR(D_CMND_SETOPTION)); // Rename result shortcut command SO to SetOption + if (XdrvMailbox.index < 114) { uint32_t ptype; uint32_t pindex; @@ -822,7 +897,9 @@ void CmndSetoption(void) else if (4 == ptype) { // SetOption82 .. 113 bitWrite(Settings.flag4.data, pindex, XdrvMailbox.payload); switch (pindex) { + case 3: // SetOption85 - Enable Device Groups case 6: // SetOption88 - PWM Dimmer Buttons control remote devices + case 15: // SetOption97 - Set Baud rate for TuyaMCU serial communication (0 = 9600 or 1 = 115200) restart_flag = 2; break; } @@ -942,18 +1019,29 @@ void CmndModule(void) present = ValidTemplateModule(XdrvMailbox.payload); } if (present) { - Settings.last_module = Settings.module; - Settings.module = XdrvMailbox.payload; - SetModuleType(); - if (Settings.last_module != XdrvMailbox.payload) { - for (uint32_t i = 0; i < sizeof(Settings.my_gp); i++) { - Settings.my_gp.io[i] = GPIO_NONE; + if (XdrvMailbox.index == 2) { + Settings.fallback_module = XdrvMailbox.payload; + } else { + Settings.last_module = Settings.module; + Settings.module = XdrvMailbox.payload; + SetModuleType(); + if (Settings.last_module != XdrvMailbox.payload) { + for (uint32_t i = 0; i < ARRAY_SIZE(Settings.my_gp.io); i++) { + Settings.my_gp.io[i] = GPIO_NONE; + } } + restart_flag = 2; } - restart_flag = 2; } } - Response_P(S_JSON_COMMAND_NVALUE_SVALUE, XdrvMailbox.command, ModuleNr(), ModuleName().c_str()); + uint8_t module_real = Settings.module; + uint8_t module_number = ModuleNr(); + if (XdrvMailbox.index == 2) { + module_real = Settings.fallback_module; + module_number = (USER_MODULE == Settings.fallback_module) ? 0 : Settings.fallback_module +1; + strcat(XdrvMailbox.command, "2"); + } + Response_P(S_JSON_COMMAND_NVALUE_SVALUE, XdrvMailbox.command, module_number, AnyModuleName(module_real).c_str()); } void CmndModules(void) @@ -972,7 +1060,7 @@ void CmndModules(void) uint32_t j = i ? midx +1 : 0; if ((ResponseAppend_P(PSTR("\"%d\":\"%s\""), j, AnyModuleName(midx).c_str()) > (LOGSZ - TOPSZ)) || (i == sizeof(kModuleNiceList))) { ResponseJsonEndEnd(); - MqttPublishPrefixTopic_P(RESULT_OR_STAT, UpperCase(XdrvMailbox.command, XdrvMailbox.command)); + MqttPublishPrefixTopic_P(RESULT_OR_STAT, XdrvMailbox.command); jsflg = false; lines++; } @@ -982,17 +1070,28 @@ void CmndModules(void) void CmndGpio(void) { - if (XdrvMailbox.index < sizeof(Settings.my_gp)) { + if (XdrvMailbox.index < ARRAY_SIZE(Settings.my_gp.io)) { myio cmodule; ModuleGpios(&cmodule); - if (ValidGPIO(XdrvMailbox.index, cmodule.io[XdrvMailbox.index]) && (XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < GPIO_SENSOR_END)) { + if (ValidGPIO(XdrvMailbox.index, cmodule.io[XdrvMailbox.index]) && (XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < AGPIO(GPIO_SENSOR_END))) { bool present = false; - for (uint32_t i = 0; i < sizeof(kGpioNiceList); i++) { + for (uint32_t i = 0; i < ARRAY_SIZE(kGpioNiceList); i++) { +#ifdef ESP8266 uint32_t midx = pgm_read_byte(kGpioNiceList + i); - if (midx == XdrvMailbox.payload) { present = true; } + if (midx == XdrvMailbox.payload) { + present = true; + break; + } +#else // ESP32 + uint32_t midx = pgm_read_word(kGpioNiceList + i); + if ((XdrvMailbox.payload >= (midx & 0xFFE0)) && (XdrvMailbox.payload < midx)) { + present = true; + break; + } +#endif // ESP8266 - ESP32 } if (present) { - for (uint32_t i = 0; i < sizeof(Settings.my_gp); i++) { + for (uint32_t i = 0; i < ARRAY_SIZE(Settings.my_gp.io); i++) { if (ValidGPIO(i, cmodule.io[i]) && (Settings.my_gp.io[i] == XdrvMailbox.payload)) { Settings.my_gp.io[i] = GPIO_NONE; } @@ -1003,26 +1102,37 @@ void CmndGpio(void) } Response_P(PSTR("{")); bool jsflg = false; - for (uint32_t i = 0; i < sizeof(Settings.my_gp); i++) { - if (ValidGPIO(i, cmodule.io[i]) || ((GPIO_USER == XdrvMailbox.payload) && !FlashPin(i))) { + for (uint32_t i = 0; i < ARRAY_SIZE(Settings.my_gp.io); i++) { + if (ValidGPIO(i, cmodule.io[i]) || ((AGPIO(GPIO_USER) == XdrvMailbox.payload) && !FlashPin(i))) { if (jsflg) { ResponseAppend_P(PSTR(",")); } jsflg = true; - uint8_t sensor_type = Settings.my_gp.io[i]; + uint32_t sensor_type = Settings.my_gp.io[i]; if (!ValidGPIO(i, cmodule.io[i])) { sensor_type = cmodule.io[i]; - if (GPIO_USER == sensor_type) { // A user GPIO equals a not connected (=GPIO_NONE) GPIO here + if (AGPIO(GPIO_USER) == sensor_type) { // A user GPIO equals a not connected (=GPIO_NONE) GPIO here sensor_type = GPIO_NONE; } } - uint8_t sensor_name_idx = sensor_type; + char sindex[4] = { 0 }; + uint32_t sensor_name_idx = BGPIO(sensor_type); +#ifdef ESP32 + uint32_t nice_list_search = sensor_type & 0xFFE0; + for (uint32_t j = 0; j < ARRAY_SIZE(kGpioNiceList); j++) { + uint32_t nls_idx = pgm_read_word(kGpioNiceList + j); + if (((nls_idx & 0xFFE0) == nice_list_search) && ((nls_idx & 0x001F) > 0)) { + snprintf_P(sindex, sizeof(sindex), PSTR("%d"), (sensor_type & 0x001F) +1); + break; + } + } +#endif // ESP32 const char *sensor_names = kSensorNames; - if (sensor_type > GPIO_FIX_START) { - sensor_name_idx = sensor_type - GPIO_FIX_START -1; + if (sensor_name_idx > GPIO_FIX_START) { + sensor_name_idx = sensor_name_idx - GPIO_FIX_START -1; sensor_names = kSensorNamesFixed; } char stemp1[TOPSZ]; - ResponseAppend_P(PSTR("\"" D_CMND_GPIO "%d\":{\"%d\":\"%s\"}"), - i, sensor_type, GetTextIndexed(stemp1, sizeof(stemp1), sensor_name_idx, sensor_names)); + ResponseAppend_P(PSTR("\"" D_CMND_GPIO "%d\":{\"%d\":\"%s%s\"}"), + i, sensor_type, GetTextIndexed(stemp1, sizeof(stemp1), sensor_name_idx, sensor_names), sindex); } } if (jsflg) { @@ -1039,8 +1149,14 @@ void CmndGpios(void) ModuleGpios(&cmodule); uint32_t lines = 1; bool jsflg = false; - for (uint32_t i = 0; i < sizeof(kGpioNiceList); i++) { + for (uint32_t i = 0; i < ARRAY_SIZE(kGpioNiceList); i++) { +#ifdef ESP8266 uint32_t midx = pgm_read_byte(kGpioNiceList + i); + uint32_t ridx = midx; +#else // ESP32 + uint32_t ridx = pgm_read_word(kGpioNiceList + i) & 0xFFE0; + uint32_t midx = BGPIO(ridx); +#endif // ESP8266 - ESP32 if ((XdrvMailbox.payload != 255) && GetUsedInModule(midx, cmodule.io)) { continue; } if (!jsflg) { Response_P(PSTR("{\"" D_CMND_GPIOS "%d\":{"), lines); @@ -1049,9 +1165,9 @@ void CmndGpios(void) } jsflg = true; char stemp1[TOPSZ]; - if ((ResponseAppend_P(PSTR("\"%d\":\"%s\""), midx, GetTextIndexed(stemp1, sizeof(stemp1), midx, kSensorNames)) > (LOGSZ - TOPSZ)) || (i == sizeof(kGpioNiceList) -1)) { + if ((ResponseAppend_P(PSTR("\"%d\":\"%s\""), ridx, GetTextIndexed(stemp1, sizeof(stemp1), midx, kSensorNames)) > (LOGSZ - TOPSZ)) || (i == ARRAY_SIZE(kGpioNiceList) -1)) { ResponseJsonEndEnd(); - MqttPublishPrefixTopic_P(RESULT_OR_STAT, UpperCase(XdrvMailbox.command, XdrvMailbox.command)); + MqttPublishPrefixTopic_P(RESULT_OR_STAT, XdrvMailbox.command); jsflg = false; lines++; } @@ -1083,7 +1199,7 @@ void CmndTemplate(void) } SettingsUpdateText(SET_TEMPLATE_NAME, "Merged"); uint32_t j = 0; - for (uint32_t i = 0; i < sizeof(mycfgio); i++) { + for (uint32_t i = 0; i < ARRAY_SIZE(Settings.user_template.gp.io); i++) { if (6 == i) { j = 9; } if (8 == i) { j = 12; } if (my_module.io[j] > GPIO_NONE) { @@ -1107,9 +1223,9 @@ void CmndTemplate(void) void CmndPwm(void) { if (pwm_present && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_PWMS)) { - if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= Settings.pwm_range) && (pin[GPIO_PWM1 + XdrvMailbox.index -1] < 99)) { + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= Settings.pwm_range) && PinUsed(GPIO_PWM1, XdrvMailbox.index -1)) { Settings.pwm_value[XdrvMailbox.index -1] = XdrvMailbox.payload; - analogWrite(pin[GPIO_PWM1 + XdrvMailbox.index -1], bitRead(pwm_inverted, XdrvMailbox.index -1) ? Settings.pwm_range - XdrvMailbox.payload : XdrvMailbox.payload); + analogWrite(Pin(GPIO_PWM1, XdrvMailbox.index -1), bitRead(pwm_inverted, XdrvMailbox.index -1) ? Settings.pwm_range - XdrvMailbox.payload : XdrvMailbox.payload); } Response_P(PSTR("{")); MqttShowPWMState(); // Render the PWM status to MQTT @@ -1121,7 +1237,11 @@ void CmndPwmfrequency(void) { if ((1 == XdrvMailbox.payload) || ((XdrvMailbox.payload >= PWM_MIN) && (XdrvMailbox.payload <= PWM_MAX))) { Settings.pwm_frequency = (1 == XdrvMailbox.payload) ? PWM_FREQ : XdrvMailbox.payload; +#ifdef ESP8266 analogWriteFreq(Settings.pwm_frequency); // Default is 1000 (core_esp8266_wiring_pwm.c) +#else + analogWriteFreqRange(0,Settings.pwm_frequency,Settings.pwm_range); +#endif } ResponseCmndNumber(Settings.pwm_frequency); } @@ -1135,7 +1255,11 @@ void CmndPwmrange(void) Settings.pwm_value[i] = Settings.pwm_range; } } +#ifdef ESP8266 analogWriteRange(Settings.pwm_range); // Default is 1023 (Arduino.h) +#else + analogWriteFreqRange(0,Settings.pwm_frequency,Settings.pwm_range); +#endif } ResponseCmndNumber(Settings.pwm_range); } @@ -1150,7 +1274,7 @@ void CmndButtonDebounce(void) void CmndSwitchDebounce(void) { - if ((XdrvMailbox.payload > 39) && (XdrvMailbox.payload < 1001)) { + if ((XdrvMailbox.payload > 39) && (XdrvMailbox.payload < 1010)) { Settings.switch_debounce = XdrvMailbox.payload; } ResponseCmndNumber(Settings.switch_debounce); @@ -1296,7 +1420,7 @@ void CmndNtpServer(void) uint32_t ntp_server = SET_NTPSERVER1 + XdrvMailbox.index -1; if (XdrvMailbox.data_len > 0) { SettingsUpdateText(ntp_server, - (SC_CLEAR == Shortcut()) ? "" : (SC_DEFAULT == Shortcut()) ? (1 == XdrvMailbox.index) ? NTP_SERVER1 : (2 == XdrvMailbox.index) ? NTP_SERVER2 : NTP_SERVER3 : XdrvMailbox.data); + (SC_CLEAR == Shortcut()) ? "" : (SC_DEFAULT == Shortcut()) ? (1 == XdrvMailbox.index) ? PSTR(NTP_SERVER1) : (2 == XdrvMailbox.index) ? PSTR(NTP_SERVER2) : PSTR(NTP_SERVER3) : XdrvMailbox.data); SettingsUpdateText(ntp_server, ReplaceCommaWithDot(SettingsText(ntp_server))); // restart_flag = 2; // Issue #3890 ntp_force_sync = true; @@ -1317,9 +1441,10 @@ void CmndAp(void) case 2: // AP2 Settings.sta_active = XdrvMailbox.payload -1; } + Settings.wifi_channel = 0; // Disable stored AP restart_flag = 2; } - Response_P(S_JSON_COMMAND_NVALUE_SVALUE, XdrvMailbox.command, Settings.sta_active +1, SettingsText(SET_STASSID1 + Settings.sta_active)); + Response_P(S_JSON_COMMAND_NVALUE_SVALUE, XdrvMailbox.command, Settings.sta_active +1, EscapeJSONString(SettingsText(SET_STASSID1 + Settings.sta_active)).c_str()); } void CmndSsid(void) @@ -1382,6 +1507,23 @@ void CmndWifiConfig(void) Response_P(S_JSON_COMMAND_NVALUE_SVALUE, XdrvMailbox.command, Settings.sta_config, GetTextIndexed(stemp1, sizeof(stemp1), Settings.sta_config, kWifiConfig)); } +void CmndWifi(void) +{ + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) { + Settings.flag4.network_wifi = XdrvMailbox.payload; + restart_flag = 2; + } + ResponseCmndStateText(Settings.flag4.network_wifi); +} + +void CmndDevicename(void) +{ + if (!XdrvMailbox.grpflg && (XdrvMailbox.data_len > 0)) { + SettingsUpdateText(SET_DEVICENAME, ('"' == XdrvMailbox.data[0]) ? "" : (SC_DEFAULT == Shortcut()) ? SettingsText(SET_FRIENDLYNAME1) : XdrvMailbox.data); + } + ResponseCmndChar(SettingsText(SET_DEVICENAME)); +} + void CmndFriendlyname(void) { if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_FRIENDLYNAMES)) { @@ -1484,7 +1626,8 @@ void CmndInterlock(void) } ResponseAppend_P(PSTR("\"}")); } else { - Settings.flag.interlock = 0; // CMND_INTERLOCK - Enable/disable interlock + // never ever reset interlock mode inadvertently if we forced it upon compilation + Settings.flag.interlock = APP_INTERLOCK_MODE; // CMND_INTERLOCK - Enable/disable interlock ResponseCmndStateText(Settings.flag.interlock); } } @@ -1494,8 +1637,9 @@ void CmndTeleperiod(void) if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 3601)) { Settings.tele_period = (1 == XdrvMailbox.payload) ? TELE_PERIOD : XdrvMailbox.payload; if ((Settings.tele_period > 0) && (Settings.tele_period < 10)) Settings.tele_period = 10; // Do not allow periods < 10 seconds - tele_period = Settings.tele_period; +// tele_period = Settings.tele_period; } + tele_period = Settings.tele_period; // Show teleperiod data also on empty command ResponseCmndNumber(Settings.tele_period); } @@ -1504,7 +1648,7 @@ void CmndReset(void) switch (XdrvMailbox.payload) { case 1: restart_flag = 211; - ResponseCmndChar(D_JSON_RESET_AND_RESTARTING); + ResponseCmndChar(PSTR(D_JSON_RESET_AND_RESTARTING)); break; case 2 ... 6: restart_flag = 210 + XdrvMailbox.payload; @@ -1516,7 +1660,7 @@ void CmndReset(void) ResponseCmndDone(); break; default: - ResponseCmndChar(D_JSON_ONE_TO_RESET); + ResponseCmndChar(PSTR(D_JSON_ONE_TO_RESET)); } } @@ -1526,12 +1670,12 @@ void CmndTime(void) // payload 1 = Time format {"Time":"2019-09-04T14:31:29"} // payload 2 = Time format {"Time":"2019-09-04T14:31:29","Epoch":1567600289} // payload 3 = Time format {"Time":1567600289} -// payload 4 = reserved +// payload 4 = Time format {"Time":"2019-09-04T14:31:29.123"} // payload 1451602800 - disable NTP and set time to epoch uint32_t format = Settings.flag2.time_format; if (XdrvMailbox.data_len > 0) { - if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload < 4)) { + if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload < 5)) { Settings.flag2.time_format = XdrvMailbox.payload -1; format = Settings.flag2.time_format; } else { @@ -1631,10 +1775,11 @@ void CmndAltitude(void) ResponseCmndNumber(Settings.altitude); } -void CmndLedPower(void) -{ +void CmndLedPower(void) { + // If GPIO_LEDLINK (used for network status) then allow up to 4 GPIO_LEDx control using led_power + // If no GPIO_LEDLINK then allow legacy single led GPIO_LED1 control using Settings.ledstate if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_LEDS)) { - if (99 == pin[GPIO_LEDLNK]) { XdrvMailbox.index = 1; } + if (!PinUsed(GPIO_LEDLNK)) { XdrvMailbox.index = 1; } if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 2)) { Settings.ledstate &= 8; // Disable power control uint32_t mask = 1 << (XdrvMailbox.index -1); // Led to control @@ -1653,22 +1798,21 @@ void CmndLedPower(void) break; } blinks = 0; - if (99 == pin[GPIO_LEDLNK]) { + if (!PinUsed(GPIO_LEDLNK)) { SetLedPower(Settings.ledstate &8); } else { SetLedPowerIdx(XdrvMailbox.index -1, (led_power & mask)); } } bool state = bitRead(led_power, XdrvMailbox.index -1); - if (99 == pin[GPIO_LEDLNK]) { + if (!PinUsed(GPIO_LEDLNK)) { state = bitRead(Settings.ledstate, 3); } ResponseCmndIdxChar(GetStateText(state)); } } -void CmndLedState(void) -{ +void CmndLedState(void) { if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < MAX_LED_OPTION)) { Settings.ledstate = XdrvMailbox.payload; if (!Settings.ledstate) { @@ -1679,8 +1823,7 @@ void CmndLedState(void) ResponseCmndNumber(Settings.ledstate); } -void CmndLedMask(void) -{ +void CmndLedMask(void) { if (XdrvMailbox.data_len > 0) { Settings.ledmask = XdrvMailbox.payload; } @@ -1689,6 +1832,59 @@ void CmndLedMask(void) ResponseCmndChar(stemp1); } +void CmndLedPwmOff(void) { + if (XdrvMailbox.data_len > 0) { + if (XdrvMailbox.payload < 0) { + Settings.ledpwm_off = 0; + } + else if (XdrvMailbox.payload > 255) { + Settings.ledpwm_off = 255; + } else { + Settings.ledpwm_off = XdrvMailbox.payload; + } + UpdateLedPowerAll(); + } + ResponseCmndNumber(Settings.ledpwm_off); +} + +void CmndLedPwmOn(void) { + if (XdrvMailbox.data_len > 0) { + if (XdrvMailbox.payload < 0) { + Settings.ledpwm_on = 0; + } + else if (XdrvMailbox.payload > 255) { + Settings.ledpwm_on = 255; + } else { + Settings.ledpwm_on = XdrvMailbox.payload; + } + UpdateLedPowerAll(); + } + ResponseCmndNumber(Settings.ledpwm_on); +} + +void CmndLedPwmMode(void) { + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_LEDS)) { + if (!PinUsed(GPIO_LEDLNK)) { XdrvMailbox.index = 1; } + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 2)) { + uint32_t mask = 1 << (XdrvMailbox.index -1); // Led to configure + switch (XdrvMailbox.payload) { + case 0: // digital + Settings.ledpwm_mask &= (0xFF ^ mask); + break; + case 1: // pwm + Settings.ledpwm_mask |= mask; + break; + case 2: // toggle + Settings.ledpwm_mask ^= mask; + break; + } + UpdateLedPowerAll(); + } + bool state = bitRead(Settings.ledpwm_mask, XdrvMailbox.index -1); + ResponseCmndIdxChar(GetStateText(state)); + } +} + void CmndWifiPower(void) { if (XdrvMailbox.data_len > 0) { @@ -1744,8 +1940,9 @@ void CmndDevGroupSend(void) { uint8_t device_group_index = (XdrvMailbox.usridx ? XdrvMailbox.index - 1 : 0); if (device_group_index < device_group_count) { - _SendDeviceGroupMessage(device_group_index, DGR_MSGTYPE_UPDATE_COMMAND); - ResponseCmndChar(XdrvMailbox.data); + if (!_SendDeviceGroupMessage(device_group_index, DGR_MSGTYPE_UPDATE_COMMAND)) { + ResponseCmndChar(XdrvMailbox.data); + } } } #endif // USE_DEVICE_GROUPS_SEND @@ -1758,6 +1955,11 @@ void CmndDevGroupShare(void) Settings.device_group_share_out = parm[1]; Response_P(PSTR("{\"" D_CMND_DEVGROUP_SHARE "\":{\"In\":\"%X\",\"Out\":\"%X\"}}"), Settings.device_group_share_in, Settings.device_group_share_out); } + +void CmndDevGroupStatus(void) +{ + DeviceGroupStatus((XdrvMailbox.usridx ? XdrvMailbox.index - 1 : 0)); +} #endif // USE_DEVICE_GROUPS void CmndSensor(void) @@ -1769,3 +1971,49 @@ void CmndDriver(void) { XdrvCall(FUNC_COMMAND_DRIVER); } + +#ifdef ESP32 + +void CmndCpuFrequency(void) { + if ((80 == XdrvMailbox.payload) || (160 == XdrvMailbox.payload) || (240 == XdrvMailbox.payload)) { + setCpuFrequencyMhz(XdrvMailbox.payload); + } + ResponseCmndNumber(getCpuFrequencyMhz()); +} + +void CmndTouchCal(void) +{ + if (XdrvMailbox.payload >= 0) { + if (XdrvMailbox.payload < MAX_KEYS + 1) TOUCH_BUTTON.calibration = bitSet(TOUCH_BUTTON.calibration, XdrvMailbox.payload); + if (XdrvMailbox.payload == 0) TOUCH_BUTTON.calibration = 0; + if (XdrvMailbox.payload == 255) TOUCH_BUTTON.calibration = 255; // all pinss + } + Response_P(PSTR("{\"" D_CMND_TOUCH_CAL "\": %u"), TOUCH_BUTTON.calibration); + ResponseJsonEnd(); + AddLog_P2(LOG_LEVEL_INFO, PSTR("Button Touchvalue Hits,")); +} + +void CmndTouchThres(void) +{ + if (XdrvMailbox.payload >= 0) { + if (XdrvMailbox.payload<256){ + TOUCH_BUTTON.pin_threshold = XdrvMailbox.payload; + } + } + Response_P(PSTR("{\"" D_CMND_TOUCH_THRES "\": %u"), TOUCH_BUTTON.pin_threshold); + ResponseJsonEnd(); +} + +void CmndTouchNum(void) +{ + if (XdrvMailbox.payload >= 0) { + if (XdrvMailbox.payload<32){ + TOUCH_BUTTON.hit_threshold = XdrvMailbox.payload; + } + } + Response_P(PSTR("{\"" D_CMND_TOUCH_NUM "\": %u"), TOUCH_BUTTON.hit_threshold); + ResponseJsonEnd(); + +} + +#endif //ESP32 \ No newline at end of file diff --git a/tasmota/support_crash_recorder.ino b/tasmota/support_crash_recorder.ino index cc9721cb4..dd0834550 100644 --- a/tasmota/support_crash_recorder.ino +++ b/tasmota/support_crash_recorder.ino @@ -17,6 +17,8 @@ along with this program. If not, see . */ +#ifdef ESP8266 + const uint32_t crash_magic = 0x53415400; // Stack trace magic number (TASx) const uint32_t crash_rtc_offset = 32; // Offset in RTC memory skipping OTA used block const uint32_t crash_dump_max_len = 31; // Dump only 31 call addresses to satisfy max JSON length of about 600 characters @@ -109,3 +111,5 @@ void CrashDump(void) ResponseJsonEnd(); } + +#endif // ESP8266 \ No newline at end of file diff --git a/tasmota/support_device_groups.ino b/tasmota/support_device_groups.ino index d350575c1..3e40f189f 100644 --- a/tasmota/support_device_groups.ino +++ b/tasmota/support_device_groups.ino @@ -20,25 +20,29 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ + #ifdef USE_DEVICE_GROUPS //#define DEVICE_GROUPS_DEBUG #define DGR_MEMBER_TIMEOUT 45000 #define DGR_ANNOUNCEMENT_INTERVAL 60000 +#define DEVICE_GROUP_MESSAGE "TASMOTA_DGR" -extern bool udp_connected; +const char kDeviceGroupMessage[] PROGMEM = DEVICE_GROUP_MESSAGE; struct device_group_member { struct device_group_member * flink; IPAddress ip_address; uint16_t received_sequence; uint16_t acked_sequence; + uint32_t unicast_count; }; struct device_group { uint32_t next_announcement_time; uint32_t next_ack_check_time; uint32_t member_timeout_time; + uint16_t outgoing_sequence; uint16_t last_full_status_sequence; uint16_t message_length; uint16_t ack_check_interval; @@ -46,8 +50,7 @@ struct device_group { uint8_t initial_status_requests_remaining; bool local; char group_name[TOPSZ]; - char message[128]; - uint8_t group_member_count; + uint8_t message[128]; struct device_group_member * device_group_members; #ifdef USE_DEVICE_GROUPS_SEND uint8_t values_8bit[DGR_ITEM_LAST_8BIT]; @@ -56,17 +59,74 @@ struct device_group { #endif // USE_DEVICE_GROUPS_SEND }; +WiFiUDP device_groups_udp; struct device_group * device_groups; -uint32_t next_check_time = 0; -uint16_t outgoing_sequence = 0; +uint32_t next_check_time; bool device_groups_initialized = false; -bool device_groups_initialization_failed = false; +bool device_groups_up = false; bool building_status_message = false; -bool processing_remote_device_message = false; -bool udp_was_connected = false; +bool ignore_dgr_sends = false; + +char * IPAddressToString(const IPAddress& ip_address) +{ + static char buffer[16]; + sprintf_P(buffer, PSTR("%u.%u.%u.%u"), ip_address[0], ip_address[1], ip_address[2], ip_address[3]); + return buffer; +} + +uint8_t * BeginDeviceGroupMessage(struct device_group * device_group, uint16_t flags, bool hold_sequence = false) +{ + uint8_t * message_ptr = &device_group->message[device_group->message_header_length]; + if (!hold_sequence && !++device_group->outgoing_sequence) device_group->outgoing_sequence = 1; + *message_ptr++ = device_group->outgoing_sequence & 0xff; + *message_ptr++ = device_group->outgoing_sequence >> 8; + *message_ptr++ = flags & 0xff; + *message_ptr++ = flags >> 8; + return message_ptr; +} + +// Return true if we're configured to share the specified item. +bool DeviceGroupItemShared(bool incoming, uint8_t item) +{ + uint32_t mask; + if (item == DGR_ITEM_LIGHT_BRI || item == DGR_ITEM_BRI_POWER_ON) + mask = DGR_SHARE_LIGHT_BRI; + else if (item == DGR_ITEM_POWER) + mask = DGR_SHARE_POWER; + else if (item == DGR_ITEM_LIGHT_SCHEME) + mask = DGR_SHARE_LIGHT_SCHEME; + else if (item == DGR_ITEM_LIGHT_FIXED_COLOR || DGR_ITEM_LIGHT_CHANNELS) + mask = DGR_SHARE_LIGHT_COLOR; + else if (item == DGR_ITEM_LIGHT_FADE || item == DGR_ITEM_LIGHT_SPEED) + mask = DGR_SHARE_LIGHT_FADE; + else if (item == DGR_ITEM_BRI_PRESET_LOW || item == DGR_ITEM_BRI_PRESET_HIGH) + mask = DGR_SHARE_DIMMER_SETTINGS; + else if (item == DGR_ITEM_EVENT) + mask = DGR_SHARE_EVENT; + else + return true; + return mask & (incoming ? Settings.device_group_share_in : Settings.device_group_share_out); +} void DeviceGroupsInit(void) { + // If no module set the device group count, ... + if (!device_group_count) { + + // If relays in sepaate device groups is enabled, set the device group count to highest numbered + // relay. + if (Settings.flag4.remote_device_mode) { // SetOption88 - Enable relays in separate device groups + for (uint32_t relay_index = 0; relay_index < MAX_RELAYS; relay_index++) { + if (PinUsed(GPIO_REL1, relay_index)) device_group_count = relay_index + 1; + } + } + + // Otherwise, set the device group count to 1. + else { + device_group_count = 1; + } + } + // If there are more device group names set than the number of device groups needed by the // mdoule, use the device group name count as the device group count. for (; device_group_count < MAX_DEV_GROUP_NAMES; device_group_count++) { @@ -75,14 +135,13 @@ void DeviceGroupsInit(void) // Initialize the device information for each device group. device_groups = (struct device_group *)calloc(device_group_count, sizeof(struct device_group)); - if (device_groups == nullptr) { - AddLog_P2(LOG_LEVEL_ERROR, PSTR("DGR: error allocating %u-element device group array"), device_group_count); - device_groups_initialization_failed = true; + if (!device_groups) { + AddLog_P2(LOG_LEVEL_ERROR, PSTR("DGR: Error allocating %u-element array"), device_group_count); return; } - for (uint32_t device_group_index = 0; device_group_index < device_group_count; device_group_index++) { - struct device_group * device_group = &device_groups[device_group_index]; + struct device_group * device_group = device_groups; + for (uint32_t device_group_index = 0; device_group_index < device_group_count; device_group_index++, device_group++) { strcpy(device_group->group_name, SettingsText(SET_DEV_GROUP_NAME1 + device_group_index)); // If the device group name is not set, use the MQTT group topic (with the device group index + @@ -90,12 +149,10 @@ void DeviceGroupsInit(void) if (!device_group->group_name[0]) { strcpy(device_group->group_name, SettingsText(SET_MQTT_GRP_TOPIC)); if (device_group_index) { - char str[10]; - sprintf_P(str, PSTR("%u"), device_group_index + 1); - strcat(device_group->group_name, str); + snprintf_P(device_group->group_name, sizeof(device_group->group_name), PSTR("%s%u"), device_group->group_name, device_group_index + 1); } } - device_group->message_header_length = sprintf_P(device_group->message, PSTR("%s%s HTTP/1.1\n\n"), kDeviceGroupMessage, device_group->group_name); + device_group->message_header_length = sprintf_P((char *)device_group->message, PSTR("%s%s"), kDeviceGroupMessage, device_group->group_name) + 1; device_group->last_full_status_sequence = -1; } @@ -109,599 +166,147 @@ void DeviceGroupsInit(void) device_groups_initialized = true; } -char * IPAddressToString(const IPAddress& ip_address) +void DeviceGroupsStart() { - static char buffer[16]; - sprintf_P(buffer, PSTR("%u.%u.%u.%u"), ip_address[0], ip_address[1], ip_address[2], ip_address[3]); - return buffer; -} + if (Settings.flag4.device_groups_enabled && !device_groups_up && !restart_flag) { -char * BeginDeviceGroupMessage(struct device_group * device_group, uint16_t flags, bool hold_sequence = false) -{ - char * message_ptr = &device_group->message[device_group->message_header_length]; - if (!hold_sequence && !++outgoing_sequence) outgoing_sequence = 1; - *message_ptr++ = outgoing_sequence & 0xff; - *message_ptr++ = outgoing_sequence >> 8; - *message_ptr++ = flags & 0xff; - *message_ptr++ = flags >> 8; - return message_ptr; -} - -// Return true if we're configured to share the specified item. -bool DeviceGroupItemShared(bool incoming, uint8_t item) -{ - uint8_t mask = 0; - switch (item) { - case DGR_ITEM_LIGHT_BRI: - case DGR_ITEM_BRI_POWER_ON: - mask = DGR_SHARE_LIGHT_BRI; - break; - case DGR_ITEM_POWER: - mask = DGR_SHARE_POWER; - break; - case DGR_ITEM_LIGHT_SCHEME: - mask = DGR_SHARE_LIGHT_SCHEME; - break; - case DGR_ITEM_LIGHT_FIXED_COLOR: - case DGR_ITEM_LIGHT_CHANNELS: - mask = DGR_SHARE_LIGHT_COLOR; - break; - case DGR_ITEM_LIGHT_FADE: - case DGR_ITEM_LIGHT_SPEED: - mask = DGR_SHARE_LIGHT_FADE; - break; - case DGR_ITEM_BRI_PRESET_LOW: - case DGR_ITEM_BRI_PRESET_HIGH: - mask = DGR_SHARE_DIMMER_SETTINGS; - break; - } - return (!mask || ((incoming ? Settings.device_group_share_in : Settings.device_group_share_out) & mask)); -} - -void SendDeviceGroupPacket(IPAddress ip, char * packet, int len, const char * label) -{ - if (!ip) ip = IPAddress(239,255,255,250); - for (int attempt = 1; attempt <= 5; attempt++) { - if (PortUdp.beginPacket(ip, 1900)) { - PortUdp.write(packet, len); - if (PortUdp.endPacket()) return; + // If we haven't successfuly initialized device groups yet, attempt to do it now. + if (!device_groups_initialized) { + DeviceGroupsInit(); + if (!device_groups_initialized) return; } - delay(10); - } - AddLog_P2(LOG_LEVEL_ERROR, PSTR("DGR: error sending %s packet"), label); -} -void _SendDeviceGroupMessage(uint8_t device_group_index, DevGroupMessageType message_type, ...) -{ - // If device groups are not enabled, ignore this request. - if (!Settings.flag4.device_groups_enabled) return; - - // If UDP is not set up, ignore this request. - if (!udp_connected) return; - - // If we're currently processing a remote device message, ignore this request. - if (processing_remote_device_message && message_type != DGR_MSGTYPE_UPDATE_COMMAND) return; - - // Get a pointer to the device information for this device. - device_group * device_group = &device_groups[device_group_index]; - - // If we're still sending initial status requests, ignore this request. - if (device_group->initial_status_requests_remaining) return; - - // A full status request is a request from a remote device for the status of every item we - // control. As long as we're building it, we may as well multicast the status update to all - // device group members. - char * message_ptr = &device_group->message[device_group->message_header_length]; - if (message_type == DGR_MSGTYP_FULL_STATUS) { - - // Set the flag indicating we're currently building a status message. SendDeviceGroupMessage - // will build but not send messages while this flag is set. - building_status_message = true; - - // Call the drivers to build the status update. - if (!++outgoing_sequence) outgoing_sequence = 1; -#ifdef DEVICE_GROUPS_DEBUG - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Building device group %s full status packet"), device_group->group_name); -#endif // DEVICE_GROUPS_DEBUG - device_group->message_length = 0; - SendDeviceGroupMessage(device_group_index, DGR_MSGTYP_PARTIAL_UPDATE, DGR_ITEM_POWER, power); - XdrvMailbox.index = device_group_index << 16; - XdrvMailbox.command_code = DGR_ITEM_STATUS; - XdrvMailbox.topic = (char *)&device_group_index; - XdrvCall(FUNC_DEVICE_GROUP_ITEM); - building_status_message = false; - - // If we have nothing to share with the other members, restore the message sequence and return. - if (!device_group->message_length) { - if (!--outgoing_sequence) outgoing_sequence = -1; + // Subscribe to device groups multicasts. + if (!device_groups_udp.beginMulticast(WiFi.localIP(), IPAddress(DEVICE_GROUPS_ADDRESS), DEVICE_GROUPS_PORT)) { + AddLog_P2(LOG_LEVEL_ERROR, PSTR("DGR: Error subscribing")); return; } - device_group->last_full_status_sequence = outgoing_sequence; + device_groups_up = true; - // Set the status update flag in the outgoing message. - *(message_ptr + 2) |= DGR_FLAG_FULL_STATUS; - } - - else { -#ifdef USE_DEVICE_GROUPS_SEND - bool use_command; - char oper; - uint32_t old_value; - char * delim_ptr; -#endif // USE_DEVICE_GROUPS_SEND - bool shared; - uint8_t item; - uint32_t value; - char * value_ptr; - va_list ap; - -#ifdef DEVICE_GROUPS_DEBUG - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Building device group %s packet"), device_group->group_name); -#endif // DEVICE_GROUPS_DEBUG - -#ifdef USE_DEVICE_GROUPS_SEND - use_command = (message_type == DGR_MSGTYPE_UPDATE_COMMAND); -#endif // USE_DEVICE_GROUPS_SEND - value = 0; - if (message_type == DGR_MSGTYP_UPDATE_MORE_TO_COME) - value |= DGR_FLAG_MORE_TO_COME; - else if (message_type == DGR_MSGTYP_UPDATE_DIRECT) - value |= DGR_FLAG_DIRECT; -#ifdef DEVICE_GROUPS_DEBUG - AddLog_P2(LOG_LEVEL_DEBUG, PSTR(">sequence=%u, flags=%u"), outgoing_sequence, value); -#endif // DEVICE_GROUPS_DEBUG - message_ptr = BeginDeviceGroupMessage(device_group, value, building_status_message || message_type == DGR_MSGTYP_PARTIAL_UPDATE); - - // If we're still building this update or all group members haven't acknowledged the previous - // update yet, update the message to include these new updates. First we need to rebuild the - // previous update message to remove any items and their values that are included in this new - // update. - if (device_group->message_length) { - uint8_t item_array[32]; - int item_index = 0; - int kept_item_count = 0; - - // Build an array of all the items in this new update. -#ifdef USE_DEVICE_GROUPS_SEND - if (use_command) - value_ptr = XdrvMailbox.data; - else -#endif // USE_DEVICE_GROUPS_SEND - va_start(ap, message_type); -#ifdef USE_DEVICE_GROUPS_SEND - while (use_command ? (item = strtoul(value_ptr, &delim_ptr, 0)) : (item = va_arg(ap, int))) { -#else // USE_DEVICE_GROUPS_SEND - while ((item = va_arg(ap, int))) { -#endif // !USE_DEVICE_GROUPS_SEND - item_array[item_index++] = item; -#ifdef USE_DEVICE_GROUPS_SEND - if (use_command) { - if (!*delim_ptr) break; - if (*delim_ptr == '=') { - delim_ptr = strchr(delim_ptr, ' '); - if (!delim_ptr) break; - } - value_ptr = delim_ptr + 1; - } - else { -#endif // USE_DEVICE_GROUPS_SEND - if (item <= DGR_ITEM_MAX_32BIT) - va_arg(ap, int); - else if (item <= DGR_ITEM_MAX_STRING) - va_arg(ap, char *); - else { - switch (item) { - case DGR_ITEM_LIGHT_CHANNELS: - va_arg(ap, uint8_t *); - break; - } - } -#ifdef USE_DEVICE_GROUPS_SEND - } -#endif // USE_DEVICE_GROUPS_SEND - } -#ifdef USE_DEVICE_GROUPS_SEND - if (!use_command) va_end(ap); -#else // USE_DEVICE_GROUPS_SEND - va_end(ap); -#endif // !USE_DEVICE_GROUPS_SEND - item_array[item_index] = 0; - - // Rebuild the previous update message, removing any items whose values are included in this - // new update. - char * previous_message_ptr = message_ptr; - while (item = *previous_message_ptr++) { - - // Search for this item in the new update. - for (item_index = 0; item_array[item_index]; item_index++) { - if (item_array[item_index] == item) break; - } - - // If this item was found in the new update skip over it and it's value. - if (item_array[item_index]) { - if (item <= DGR_ITEM_MAX_32BIT) { - previous_message_ptr++; - if (item > DGR_ITEM_MAX_8BIT) { - previous_message_ptr++; - if (item > DGR_ITEM_MAX_16BIT) { - previous_message_ptr++; - previous_message_ptr++; - } - } - } - else if (item <= DGR_ITEM_MAX_STRING) - previous_message_ptr += *previous_message_ptr++; - else { - switch (item) { - case DGR_ITEM_LIGHT_CHANNELS: - previous_message_ptr += 5; - break; - } - } - } - - // If this item was not found in the new udpate, copy it to the new update message. - else { - *message_ptr++ = item; - if (item <= DGR_ITEM_MAX_32BIT) { - *message_ptr++ = *previous_message_ptr++; - if (item > DGR_ITEM_MAX_8BIT) { - *message_ptr++ = *previous_message_ptr++; - if (item > DGR_ITEM_MAX_16BIT) { - *message_ptr++ = *previous_message_ptr++; - *message_ptr++ = *previous_message_ptr++; - } - } - } - else if (item <= DGR_ITEM_MAX_STRING) { - *message_ptr++ = value = *previous_message_ptr++; - memmove(message_ptr, previous_message_ptr, value); - previous_message_ptr += value; - message_ptr += value; - } - else { - switch (item) { - case DGR_ITEM_LIGHT_CHANNELS: - memmove(message_ptr, previous_message_ptr, 5); - previous_message_ptr += 5; - message_ptr += 5; - break; - } - } - kept_item_count++; - } - } -#ifdef DEVICE_GROUPS_DEBUG - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%u items carried over from previous update"), kept_item_count); -#endif // DEVICE_GROUPS_DEBUG + // The WiFi was down but now it's up and device groups is initialized. (Re-)discover devices in + // our device group(s). Load the status request message for all device groups. This message will + // be multicast 10 times at 200ms intervals. + next_check_time = millis() + 2000; + struct device_group * device_group = device_groups; + for (uint32_t device_group_index = 0; device_group_index < device_group_count; device_group_index++, device_group++) { + device_group->next_announcement_time = -1; + device_group->message_length = BeginDeviceGroupMessage(device_group, DGR_FLAG_RESET | DGR_FLAG_STATUS_REQUEST) - device_group->message; + device_group->initial_status_requests_remaining = 10; + device_group->next_ack_check_time = next_check_time; } - - // Itertate through the passed items adding them and their values to the message. -#ifdef USE_DEVICE_GROUPS_SEND - if (use_command) - value_ptr = XdrvMailbox.data; - else -#endif // USE_DEVICE_GROUPS_SEND - va_start(ap, message_type); -#ifdef USE_DEVICE_GROUPS_SEND - while (use_command ? (item = strtoul(value_ptr, &delim_ptr, 0)) : (item = va_arg(ap, int))) { -#else // !USE_DEVICE_GROUPS_SEND - while ((item = va_arg(ap, int))) { -#endif // !USE_DEVICE_GROUPS_SEND - - // Find out if this item is shared with the group and add the item code to the message if yes. - shared = true; - if (!device_group_index) shared = DeviceGroupItemShared(false, item); - if (shared) *message_ptr++ = item; - -#ifdef USE_DEVICE_GROUPS_SEND - // If we're processing a command, get a pointer to the value if one was specified. - if (use_command) value_ptr = (*delim_ptr == '=' ? delim_ptr + 1 : nullptr); -#endif // USE_DEVICE_GROUPS_SEND - - // For numeric items, get the specified value. - if (item <= DGR_ITEM_MAX_32BIT) { - -#ifdef USE_DEVICE_GROUPS_SEND - // If we're processing a command, get the final value after processing any specified - // operators. - if (use_command) { - value = 0; - if (value_ptr) { - oper = 0; - if (*value_ptr == '@') { - oper = value_ptr[1]; - value_ptr += 2; - } - value = strtoul(value_ptr, nullptr, 0); - if (oper) { - old_value = (item <= DGR_ITEM_MAX_8BIT ? device_group->values_8bit[item] : (item <= DGR_ITEM_MAX_16BIT ? device_group->values_16bit[item - DGR_ITEM_MAX_8BIT - 1] : device_group->values_32bit[item - DGR_ITEM_MAX_16BIT - 1])); - value = (oper == '+' ? old_value + value : (oper == '-' ? old_value - value : (oper == '^' ? old_value ^ (value ? value : 0xffffffff) : old_value))); - } - } - } - else -#endif // USE_DEVICE_GROUPS_SEND - value = va_arg(ap, int); - - // If the item is shared, add it to the message. - if (shared) { -#ifdef DEVICE_GROUPS_DEBUG - AddLog_P2(LOG_LEVEL_DEBUG, PSTR(">item=%u, value=%u"), item, value); -#endif // DEVICE_GROUPS_DEBUG - *message_ptr++ = value & 0xff; - if (item > DGR_ITEM_MAX_8BIT) { -#ifdef USE_DEVICE_GROUPS_SEND - old_value = value; -#endif // USE_DEVICE_GROUPS_SEND - value >>= 8; - *message_ptr++ = value & 0xff; - if (item > DGR_ITEM_MAX_16BIT) { - value >>= 8; - *message_ptr++ = value & 0xff; - value >>= 8; - - // For the power item, the device count is overlayed onto the highest 8 bits. - if (item == DGR_ITEM_POWER) { - if (!value) - value = (device_group_index == 0 ? devices_present : 1); -#ifdef USE_DEVICE_GROUPS_SEND - else - old_value = old_value & 0xffffff; -#endif // USE_DEVICE_GROUPS_SEND - } - - *message_ptr++ = value; -#ifdef USE_DEVICE_GROUPS_SEND - device_group->values_32bit[item - DGR_ITEM_MAX_16BIT - 1] = old_value; -#endif // USE_DEVICE_GROUPS_SEND - } -#ifdef USE_DEVICE_GROUPS_SEND - else { - device_group->values_16bit[item - DGR_ITEM_MAX_8BIT - 1] = old_value; - } -#endif // USE_DEVICE_GROUPS_SEND - } -#ifdef USE_DEVICE_GROUPS_SEND - else { - device_group->values_8bit[item] = value; - } -#endif // USE_DEVICE_GROUPS_SEND - } - } - - // For string items, add the string to the message prefixed by the length. - else if (item <= DGR_ITEM_MAX_STRING) { -#ifdef USE_DEVICE_GROUPS_SEND - if (!use_command) -#endif // USE_DEVICE_GROUPS_SEND - value_ptr = va_arg(ap, char *); - if (shared) { - value = (value_ptr ? strlen((const char *)value_ptr) : 0); -#ifdef DEVICE_GROUPS_DEBUG - AddLog_P2(LOG_LEVEL_DEBUG, PSTR(">item=%u, value=%s"), item, value_ptr); -#endif // DEVICE_GROUPS_DEBUG - *message_ptr++ = value; - memcpy(message_ptr, value_ptr, value); - message_ptr += value; - } - } - - // For special items, handle them individually. - else { - switch (item) { - case DGR_ITEM_LIGHT_CHANNELS: -#ifdef USE_DEVICE_GROUPS_SEND - if (use_command) { - if (shared) { - for (int i = 0; i < 5; i++) { - value = 0; - if (value_ptr) { - value = strtoul(value_ptr, &value_ptr, 0); - value_ptr = (*value_ptr == ',' ? value_ptr + 1 : nullptr); - } - *message_ptr++ = value; - } - } - } - else { -#endif // USE_DEVICE_GROUPS_SEND - value_ptr = va_arg(ap, char *); - if (shared) { - memmove(message_ptr, value_ptr, 5); - message_ptr += 5; - } -#ifdef USE_DEVICE_GROUPS_SEND - } -#endif // USE_DEVICE_GROUPS_SEND -#ifdef DEVICE_GROUPS_DEBUG - if (shared) AddLog_P2(LOG_LEVEL_DEBUG, PSTR(">item=%u, value=%u,%u,%u,%u,%u"), item, *(message_ptr - 5), *(message_ptr - 4), *(message_ptr - 3), *(message_ptr - 2), *(message_ptr - 1)); -#endif // DEVICE_GROUPS_DEBUG - break; - } - } - -#ifdef USE_DEVICE_GROUPS_SEND - // If we're processing a command, advance to the next item. If there are no more, break out of - // the loop. - if (use_command) { - if (!*delim_ptr) break; - if (*delim_ptr == '=') { - delim_ptr = strchr(delim_ptr, ' '); - if (!delim_ptr) break; - } - value_ptr = delim_ptr + 1; - } -#endif // USE_DEVICE_GROUPS_SEND - } -#ifdef USE_DEVICE_GROUPS_SEND - if (!use_command) va_end(ap); -#else // USE_DEVICE_GROUPS_SEND - va_end(ap); -#endif // !USE_DEVICE_GROUPS_SEND - - // Add the EOL item code and calculate the message length. - *message_ptr++ = 0; - device_group->message_length = message_ptr - device_group->message; - - // If there's going to be more items added to this message, return. - if (building_status_message || message_type == DGR_MSGTYP_PARTIAL_UPDATE) return; + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: (Re)discovering members")); } - - // Multicast the packet. -#ifdef DEVICE_GROUPS_DEBUG - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: sending %u-byte device group %s packet via multicast, sequence=%u"), device_group->message_length, device_group->group_name, device_group->message[device_group->message_header_length] | device_group->message[device_group->message_header_length + 1] << 8); -#endif // DEVICE_GROUPS_DEBUG - SendDeviceGroupPacket(0, device_group->message, device_group->message_length, PSTR("Multicast")); - - uint32_t now = millis(); - if (message_type == DGR_MSGTYP_UPDATE_MORE_TO_COME) { - device_group->message_length = 0; - device_group->next_ack_check_time = 0; - } - else { - device_group->ack_check_interval = 100; - device_group->next_ack_check_time = now + device_group->ack_check_interval; - if (device_group->next_ack_check_time < next_check_time) next_check_time = device_group->next_ack_check_time; - device_group->member_timeout_time = now + DGR_MEMBER_TIMEOUT; - } - - device_group->next_announcement_time = now + DGR_ANNOUNCEMENT_INTERVAL; - if (device_group->next_announcement_time < next_check_time) next_check_time = device_group->next_announcement_time; } -void ProcessDeviceGroupMessage(char * packet, int packet_length) +void DeviceGroupsStop() { - // Make the group name a null-terminated string. - char * message_group_name = packet + sizeof(DEVICE_GROUP_MESSAGE) - 1; - char * message_ptr = strchr(message_group_name, ' '); - if (message_ptr == nullptr) return; - *message_ptr = 0; + device_groups_udp.flush(); + device_groups_up = false; +} - // Search for a device group with the target group name. If one isn't found, return. - struct device_group * device_group; - uint8_t device_group_index = 0; - for (;;) { - device_group = &device_groups[device_group_index]; - if (!strcmp(message_group_name, device_group->group_name)) break; - if (++device_group_index >= device_group_count) return; - } - *message_ptr++ = ' '; - - // Find the group member. If this is a new group member, add it. - IPAddress remote_ip = PortUdp.remoteIP(); - struct device_group_member * * flink = &device_group->device_group_members; - struct device_group_member * device_group_member; - for (;;) { - device_group_member = *flink; - if (!device_group_member) { - device_group_member = (struct device_group_member *)calloc(1, sizeof(struct device_group_member)); - if (device_group_member == nullptr) { - AddLog_P2(LOG_LEVEL_ERROR, PSTR("DGR: error allocating device group member block")); - return; - } -#ifdef DEVICE_GROUPS_DEBUG - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: adding member %s (%p)"), IPAddressToString(remote_ip), device_group_member); -#endif // DEVICE_GROUPS_DEBUG - device_group_member->ip_address = remote_ip; - *flink = device_group_member; - break; - } - else if (device_group_member->ip_address == remote_ip) { - break; - } - flink = &device_group_member->flink; - } - - // Find the start of the actual message (after the http header). - message_ptr = strstr_P(message_ptr, PSTR("\n\n")); - if (message_ptr == nullptr) return; - message_ptr += 2; - - bool light_fade; - uint16_t flags; - uint16_t item; +void SendReceiveDeviceGroupMessage(struct device_group * device_group, struct device_group_member * device_group_member, uint8_t * message, int message_length, bool received) +{ + char log_buffer[512]; + bool item_processed = false; uint16_t message_sequence; - int32_t value; + uint16_t flags; + int device_group_index = device_group - device_groups; + int log_length; + int log_remaining; + char * log_ptr; + + // Find the end and start of the actual message (after the header). + uint8_t * message_end_ptr = message + message_length; + uint8_t * message_ptr = message + strlen((char *)message) + 1; // Get the message sequence and flags. - if (packet_length - (message_ptr - packet) < 4) goto badmsg; // Malformed message - must be at least 16-bit sequence, 16-bit flags left + if (message_ptr + 4 > message_end_ptr) goto badmsg; // Malformed message - must be at least 16-bit sequence, 16-bit flags left message_sequence = *message_ptr++; message_sequence |= *message_ptr++ << 8; flags = *message_ptr++; flags |= *message_ptr++ << 8; -#ifdef DEVICE_GROUPS_DEBUG - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Received device group %s packet from %s: sequence=%u, flags=%u"), device_group->group_name, IPAddressToString(remote_ip), message_sequence, flags); -#endif // DEVICE_GROUPS_DEBUG - // If this is an announcement, simply return. - if (flags == DGR_FLAG_ANNOUNCEMENT) return; + // Initialize the log buffer. + log_length = sprintf(log_buffer, PSTR("DGR: %s %s message %s %s: seq=%u, flags=%u"), (received ? PSTR("Received") : PSTR("Sending")), device_group->group_name, (received ? PSTR("from") : PSTR("to")), (device_group_member ? IPAddressToString(device_group_member->ip_address) : received ? PSTR("local") : PSTR("network")), message_sequence, flags); + log_ptr = log_buffer + log_length; + log_remaining = sizeof(log_buffer) - log_length; - // If this is an ack message, save the message sequence if it's newwer than the last ack we + // If this is an announcement, just log it. + if (flags == DGR_FLAG_ANNOUNCEMENT) goto write_log; + + // If this is a received ack message, save the message sequence if it's newer than the last ack we // received from this member. if (flags == DGR_FLAG_ACK) { - if (message_sequence > device_group_member->acked_sequence || device_group_member->acked_sequence - message_sequence < 64536) { + if (received && device_group_member && (message_sequence > device_group_member->acked_sequence || device_group_member->acked_sequence - message_sequence < 64536)) { device_group_member->acked_sequence = message_sequence; } -#ifdef DEVICE_GROUPS_DEBUG - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("acked_sequence != device_group->last_full_status_sequence) { - _SendDeviceGroupMessage(device_group_index, DGR_MSGTYP_FULL_STATUS); + // If this is a received message, send an ack message to the sender. + if (device_group_member) { + if (received) { + if (!(flags & DGR_FLAG_MORE_TO_COME)) { + *(message_ptr - 2) = DGR_FLAG_ACK; + *(message_ptr - 1) = 0; + SendReceiveDeviceGroupMessage(device_group, device_group_member, message, message_ptr - message, false); + } } -#ifdef DEVICE_GROUPS_DEBUG - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("received_sequence) { - if (message_sequence == device_group_member->received_sequence || device_group_member->received_sequence - message_sequence > 64536) { -#ifdef DEVICE_GROUPS_DEBUG - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("acked_sequence); + log_ptr += log_length; + log_remaining -= log_length; + goto write_log; } } - device_group_member->received_sequence = message_sequence; - // Set the flag indicating we're currently processing a remote device message. - // SendDeviceGroupMessage will not send messages while this flag is set. - processing_remote_device_message = true; + // If this is a status request message, skip item processing. + if ((flags & DGR_FLAG_STATUS_REQUEST)) goto write_log; - /* - XdrvMailbox - bool grpflg - bool usridx - uint16_t command_code Item code - uint32_t index 0:15 Flags, 16:31 Message sequence - uint32_t data_len String item value length - int32_t payload Integer item value - char *topic Pointer to device group index - char *data Pointer to non-integer item value - char *command nullptr - */ - XdrvMailbox.command = nullptr; // Indicates the source is a device group update - XdrvMailbox.index = flags | message_sequence << 16; - XdrvMailbox.topic = (char *)&device_group_index; - if (flags & (DGR_FLAG_MORE_TO_COME | DGR_FLAG_DIRECT)) skip_light_fade = true; + // If this is a received message, ... + if (received) { + // If we already processed this or a later message from this group member, ignore this message. + if (device_group_member) { + if (message_sequence <= device_group_member->received_sequence) { + if (message_sequence == device_group_member->received_sequence || device_group_member->received_sequence - message_sequence > 64536) { + log_length = snprintf(log_ptr, log_remaining, PSTR(" (old)")); + log_ptr += log_length; + log_remaining -= log_length; + goto write_log; + } + } + device_group_member->received_sequence = message_sequence; + } + + /* + XdrvMailbox + bool grpflg + bool usridx + uint16_t command_code Item code + uint32_t index 0:15 Flags, 16:31 Message sequence + uint32_t data_len String item value length + int32_t payload Integer item value + char *topic Pointer to device group index + char *data Pointer to non-integer item value + char *command nullptr + */ + XdrvMailbox.command = nullptr; // Indicates the source is a device group update + XdrvMailbox.index = flags | message_sequence << 16; + XdrvMailbox.topic = (char *)&device_group_index; + if (flags & (DGR_FLAG_MORE_TO_COME | DGR_FLAG_DIRECT)) skip_light_fade = true; + + // Set the flag to ignore device group send message request so callbacks from the drivers do not + // send updates. + ignore_dgr_sends = true; + } + + uint8_t item; + int32_t value; for (;;) { - if (packet_length - (message_ptr - packet) < 1) goto badmsg; // Malformed message + if (message_ptr >= message_end_ptr) goto badmsg; // Malformed message item = *message_ptr++; if (!item) break; // Done @@ -716,14 +321,18 @@ void ProcessDeviceGroupMessage(char * packet, int packet_length) case DGR_ITEM_BRI_PRESET_HIGH: case DGR_ITEM_BRI_POWER_ON: case DGR_ITEM_POWER: + case DGR_ITEM_EVENT: case DGR_ITEM_LIGHT_CHANNELS: break; default: - AddLog_P2(LOG_LEVEL_ERROR, PSTR("DGR: ********** invalid item=%u received from device group %s member %s"), item, device_group->group_name, IPAddressToString(remote_ip)); + AddLog_P2(LOG_LEVEL_ERROR, PSTR("DGR: *** Invalid item=%u"), item); } #endif // DEVICE_GROUPS_DEBUG - XdrvMailbox.command_code = item; + log_length = snprintf(log_ptr, log_remaining, PSTR(", %u="), item); + log_ptr += log_length; + log_remaining -= log_length; + log_length = 0; if (item <= DGR_ITEM_LAST_32BIT) { value = *message_ptr++; if (item > DGR_ITEM_MAX_8BIT) { @@ -746,210 +355,563 @@ void ProcessDeviceGroupMessage(char * packet, int packet_length) device_group->values_8bit[item] = value; } #endif // USE_DEVICE_GROUPS_SEND - -#ifdef DEVICE_GROUPS_DEBUG - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("= packet_length - (message_ptr - packet)) goto badmsg; // Malformed message -#ifdef DEVICE_GROUPS_DEBUG - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("= message_end_ptr) goto badmsg; // Malformed message + if (item <= DGR_ITEM_MAX_STRING) { + log_length = snprintf(log_ptr, log_remaining, PSTR("'%s'"), message_ptr); } - } - - if (DeviceGroupItemShared(true, item)) { - if (item == DGR_ITEM_POWER) { - if (device_group->local) { - uint8_t mask_devices = value >> 24; - if (mask_devices > devices_present) mask_devices = devices_present; - for (uint32_t i = 0; i < devices_present; i++) { - uint32_t mask = 1 << i; - bool on = (value & mask); - if (on != (power & mask)) ExecuteCommandPower(i + 1, (on ? POWER_ON : POWER_OFF), SRC_REMOTE); - } + else { + switch (item) { + case DGR_ITEM_LIGHT_CHANNELS: + log_length = snprintf(log_ptr, log_remaining, PSTR("%u,%u,%u,%u,%u,%u"), *message_ptr, *(message_ptr + 1), *(message_ptr + 2), *(message_ptr + 3), *(message_ptr + 4), *(message_ptr + 5)); + break; } } + message_ptr += value; + } + log_ptr += log_length; + log_remaining -= log_length; + + if (received && DeviceGroupItemShared(true, item)) { + item_processed = true; + XdrvMailbox.command_code = item; + XdrvMailbox.payload = value; + XdrvMailbox.data_len = value; + *log_ptr++ = '*'; + log_remaining--; + switch (item) { + case DGR_ITEM_POWER: + if (Settings.flag4.remote_device_mode) { // SetOption88 - Enable relays in separate device groups + bool on = (value & 1); + if (on != (power & (1 << device_group_index))) ExecuteCommandPower(device_group_index + 1, (on ? POWER_ON : POWER_OFF), SRC_REMOTE); + } + else if (device_group->local) { + uint8_t mask_devices = value >> 24; + if (mask_devices > devices_present) mask_devices = devices_present; + for (uint32_t i = 0; i < mask_devices; i++) { + uint32_t mask = 1 << i; + bool on = (value & mask); + if (on != (power & mask)) ExecuteCommandPower(i + 1, (on ? POWER_ON : POWER_OFF), SRC_REMOTE); + } + } + break; +#ifdef USE_RULES + case DGR_ITEM_EVENT: + CmndEvent(); + break; +#endif + case DGR_ITEM_COMMAND: + ExecuteCommand(XdrvMailbox.data, SRC_REMOTE); + break; + } XdrvCall(FUNC_DEVICE_GROUP_ITEM); } } - XdrvMailbox.command_code = DGR_ITEM_EOL; - XdrvCall(FUNC_DEVICE_GROUP_ITEM); - skip_light_fade = false; + if (received) { + if (item_processed) { + XdrvMailbox.command_code = DGR_ITEM_EOL; + XdrvCall(FUNC_DEVICE_GROUP_ITEM); + } + } - processing_remote_device_message = false; -#ifdef DEVICE_GROUPS_DEBUG - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("acked_sequence != device_group->last_full_status_sequence) { + _SendDeviceGroupMessage(device_group_index, DGR_MSGTYP_FULL_STATUS); + } + } + } + + // If this is a message being sent, send it. + else { + int attempt; + IPAddress ip_address = (device_group_member ? device_group_member->ip_address : IPAddress(DEVICE_GROUPS_ADDRESS)); + for (attempt = 1; attempt <= 5; attempt++) { + if (device_groups_udp.beginPacket(ip_address, DEVICE_GROUPS_PORT)) { + device_groups_udp.write(message, message_length); + if (device_groups_udp.endPacket()) break; + } + delay(10); + } + if (attempt > 5) AddLog_P2(LOG_LEVEL_ERROR, PSTR("DGR: Error sending message")); + } + goto cleanup; badmsg: - AddLog_P2(LOG_LEVEL_ERROR, PSTR("DGR: malformed message received from %s"), IPAddressToString(remote_ip)); + AddLog_P(LOG_LEVEL_ERROR, PSTR("%s ** incorrect length"), log_buffer); + +cleanup: + if (received) { + skip_light_fade = false; + ignore_dgr_sends = false; + } +} + +bool _SendDeviceGroupMessage(uint8_t device_group_index, DevGroupMessageType message_type, ...) +{ + // If device groups is not up, ignore this request. + if (!device_groups_up) return 1; + + // If we're currently processing a remote device message, ignore this request. + if (ignore_dgr_sends && message_type != DGR_MSGTYPE_UPDATE_COMMAND) return 0; + + // Get a pointer to the device information for this device. + struct device_group * device_group = &device_groups[device_group_index]; + + // If we're still sending initial status requests, ignore this request. + if (device_group->initial_status_requests_remaining) return 1; + + // Load the message header, sequence and flags. #ifdef DEVICE_GROUPS_DEBUG - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("packet_length=%u, offset=%u"), packet_length, message_ptr - packet); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: Building %s %spacket"), device_group->group_name, (message_type == DGR_MSGTYP_FULL_STATUS ? PSTR("full status ") : PSTR(""))); #endif // DEVICE_GROUPS_DEBUG - processing_remote_device_message = false; + uint16_t original_sequence = device_group->outgoing_sequence; + uint16_t flags = 0; + if (message_type == DGR_MSGTYP_UPDATE_MORE_TO_COME) + flags = DGR_FLAG_MORE_TO_COME; + else if (message_type == DGR_MSGTYP_UPDATE_DIRECT) + flags = DGR_FLAG_DIRECT; + uint8_t * message_ptr = BeginDeviceGroupMessage(device_group, flags, building_status_message || message_type == DGR_MSGTYP_PARTIAL_UPDATE); + + // A full status request is a request from a remote device for the status of every item we + // control. As long as we're building it, we may as well multicast the status update to all + // device group members. + if (message_type == DGR_MSGTYP_FULL_STATUS) { + device_group->last_full_status_sequence = device_group->outgoing_sequence; + device_group->message_length = 0; + + // Set the flag indicating we're currently building a status message. SendDeviceGroupMessage + // will build but not send messages while this flag is set. + building_status_message = true; + + // Call the drivers to build the status update. + if (device_group->local || Settings.flag4.remote_device_mode) { // SetOption88 - Enable relays in separate device groups + SendDeviceGroupMessage(device_group_index, DGR_MSGTYP_PARTIAL_UPDATE, DGR_ITEM_POWER, power); + } + XdrvMailbox.index = device_group_index << 16; + XdrvMailbox.command_code = DGR_ITEM_STATUS; + XdrvMailbox.topic = (char *)&device_group_index; + XdrvCall(FUNC_DEVICE_GROUP_ITEM); + building_status_message = false; + + // Set the status update flag in the outgoing message. + *(message_ptr - 2) |= DGR_FLAG_FULL_STATUS; + + // If we have nothing to share with the other members, just send the EOL item. + if (!device_group->message_length) { + *message_ptr++ = 0; + device_group->message_length = message_ptr - device_group->message; + } + } + + else { +#ifdef USE_DEVICE_GROUPS_SEND + uint8_t out_buffer[128]; + bool escaped; + char chr; + char oper; + uint32_t old_value; + uint8_t * out_ptr = out_buffer; +#endif // USE_DEVICE_GROUPS_SEND + struct item { + uint8_t item; + uint32_t value; + void * value_ptr; + } item_array[32]; + bool shared; + uint8_t item; + uint32_t value; + uint8_t * value_ptr; + uint8_t * first_item_ptr = message_ptr; + struct item * item_ptr; + va_list ap; + + // Build an array of all the items and values in this update. + item_ptr = item_array; +#ifdef USE_DEVICE_GROUPS_SEND + if (message_type == DGR_MSGTYPE_UPDATE_COMMAND) { + value_ptr = (uint8_t *)XdrvMailbox.data; + while ((item = strtoul((char *)value_ptr, (char **)&value_ptr, 0))) { + item_ptr->item = item; + if (*value_ptr != '=') return 1; + value_ptr++; + if (item <= DGR_ITEM_MAX_32BIT) { + oper = 0; + if (*value_ptr == '@') { + oper = value_ptr[1]; + value_ptr += 2; + } + value = (isdigit(*value_ptr) ? strtoul((char *)value_ptr, (char **)&value_ptr, 0) : 1); + if (oper) { + old_value = (item <= DGR_ITEM_MAX_8BIT ? device_group->values_8bit[item] : (item <= DGR_ITEM_MAX_16BIT ? device_group->values_16bit[item - DGR_ITEM_MAX_8BIT - 1] : device_group->values_32bit[item - DGR_ITEM_MAX_16BIT - 1])); + value = (oper == '+' ? old_value + value : (oper == '-' ? old_value - value : (oper == '^' ? old_value ^ (value ? value : 0xffffffff) : old_value))); + } + item_ptr->value = value; + } + else { + item_ptr->value_ptr = out_ptr; + if (item <= DGR_ITEM_MAX_STRING) { + escaped = false; + while ((chr = *value_ptr++)) { + if (chr == ' ' && !escaped) break; + if (!(escaped = (chr == '\\' && !escaped))) *out_ptr++ = chr; + } + *out_ptr = 0; + } + else { + switch (item) { + case DGR_ITEM_LIGHT_CHANNELS: + for (int i = 0; i < 6; i++) { + *out_ptr++ = strtoul((char *)value_ptr, (char **)&value_ptr, 0); + if (*value_ptr == ',') value_ptr++; + } + break; + } + } + } + item_ptr++; + } + } + else { +#endif // USE_DEVICE_GROUPS_SEND + va_start(ap, message_type); + while ((item = va_arg(ap, int))) { + item_ptr->item = item; + if (item <= DGR_ITEM_MAX_32BIT) + item_ptr->value = va_arg(ap, int); + else if (item <= DGR_ITEM_MAX_STRING) + item_ptr->value_ptr = va_arg(ap, char *); + else { + item_ptr->value_ptr = va_arg(ap, uint8_t *); + } + item_ptr++; + } + va_end(ap); +#ifdef USE_DEVICE_GROUPS_SEND + } +#endif // USE_DEVICE_GROUPS_SEND + item_ptr->item = 0; + + // If we're still building this update or all group members haven't acknowledged the previous + // update yet, update the message to include these new updates. First we need to rebuild the + // previous update message to remove any items and their values that are included in this new + // update. + if (device_group->message_length) { + int kept_item_count = 0; + + // Rebuild the previous update message, removing any items whose values are included in this + // new update. + uint8_t * previous_message_ptr = message_ptr; + while (item = *previous_message_ptr++) { + + // Determine the length of this item's value. + if (item <= DGR_ITEM_MAX_32BIT) { + value = 1; + if (item > DGR_ITEM_MAX_8BIT) { + value = 2; + if (item > DGR_ITEM_MAX_16BIT) { + value = 4; + } + } + } + else { + value = *previous_message_ptr + 1; + } + + // Search for this item in the new update. + for (item_ptr = item_array; item_ptr->item; item_ptr++) { + if (item_ptr->item == item) break; + } + + // If this item was not found in the new update, copy it to the new update message. + if (!item_ptr->item) { + kept_item_count++; + *message_ptr++ = item; + memmove(message_ptr, previous_message_ptr, value); + message_ptr += value; + } + + // Advance past the item value. + previous_message_ptr += value; + } +#ifdef DEVICE_GROUPS_DEBUG + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: %u items carried over"), kept_item_count); +#endif // DEVICE_GROUPS_DEBUG + } + + // Itertate through the passed items adding them and their values to the message. + for (item_ptr = item_array; (item = item_ptr->item); item_ptr++) { + + // If this item is shared with the group add it to the message. + shared = true; + if (!device_group_index && message_type != DGR_MSGTYPE_UPDATE_COMMAND) shared = DeviceGroupItemShared(false, item); + if (shared) { + *message_ptr++ = item; + + // For integer items, add the value to the message. + if (item <= DGR_ITEM_MAX_32BIT) { + value = item_ptr->value; + *message_ptr++ = value & 0xff; + if (item > DGR_ITEM_MAX_8BIT) { + value >>= 8; + *message_ptr++ = value & 0xff; + if (item > DGR_ITEM_MAX_16BIT) { + value >>= 8; + *message_ptr++ = value & 0xff; + value >>= 8; + // For the power item, the device count is overlayed onto the highest 8 bits. + if (item == DGR_ITEM_POWER && !value) value = (device_group_index == 0 ? devices_present : 1); + *message_ptr++ = value; + } + } + } + + // For string items and special items, get the value length. + else { + if (item <= DGR_ITEM_MAX_STRING) { + value = strlen((const char *)item_ptr->value_ptr) + 1; + } + else { + switch (item) { + case DGR_ITEM_LIGHT_CHANNELS: + value = 6; + break; + } + } + + // Load the length and copy the value. + *message_ptr++ = value; + memcpy(message_ptr, item_ptr->value_ptr, value); + message_ptr += value; + } + } + } + + // If we added any items, add the EOL item code and calculate the message length. + if (message_ptr != first_item_ptr) { + *message_ptr++ = 0; + device_group->message_length = message_ptr - device_group->message; + } + + // If there's going to be more items added to this message, return. + if (building_status_message || message_type == DGR_MSGTYP_PARTIAL_UPDATE) return 0; + } + + // If there is no message, restore the sequence number and return. + if (!device_group->message_length) { + device_group->outgoing_sequence = original_sequence; + return 0; + } + + // Multicast the packet. + SendReceiveDeviceGroupMessage(device_group, nullptr, device_group->message, device_group->message_length, false); + +#ifdef USE_DEVICE_GROUPS_SEND + // If this is the DevGroupSend command, also handle the update locally. + if (message_type == DGR_MSGTYPE_UPDATE_COMMAND) { + struct XDRVMAILBOX save_XdrvMailbox = XdrvMailbox; + SendReceiveDeviceGroupMessage(device_group, nullptr, device_group->message, device_group->message_length, true); + XdrvMailbox = save_XdrvMailbox; + } +#endif // USE_DEVICE_GROUPS_SEND + + uint32_t now = millis(); + if (message_type == DGR_MSGTYP_UPDATE_MORE_TO_COME) { + device_group->message_length = 0; + device_group->next_ack_check_time = 0; + } + else { + device_group->ack_check_interval = 200; + device_group->next_ack_check_time = now + device_group->ack_check_interval; + if (device_group->next_ack_check_time < next_check_time) next_check_time = device_group->next_ack_check_time; + device_group->member_timeout_time = now + DGR_MEMBER_TIMEOUT; + } + + device_group->next_announcement_time = now + DGR_ANNOUNCEMENT_INTERVAL; + if (device_group->next_announcement_time < next_check_time) next_check_time = device_group->next_announcement_time; + return 0; +} + +void ProcessDeviceGroupMessage(uint8_t * message, int message_length) +{ + // Search for a device group with the target group name. If one isn't found, return. + uint8_t device_group_index = 0; + struct device_group * device_group = device_groups; + char * message_group_name = (char *)message + sizeof(DEVICE_GROUP_MESSAGE) - 1; + for (;;) { + if (!strcmp(message_group_name, device_group->group_name)) break; + if (++device_group_index >= device_group_count) return; + device_group++; + } + + // Find the group member. If this is a new group member, add it. + struct device_group_member * device_group_member; + IPAddress remote_ip = device_groups_udp.remoteIP(); + struct device_group_member * * flink = &device_group->device_group_members; + for (;;) { + device_group_member = *flink; + if (!device_group_member) { + device_group_member = (struct device_group_member *)calloc(1, sizeof(struct device_group_member)); + if (device_group_member == nullptr) { + AddLog_P2(LOG_LEVEL_ERROR, PSTR("DGR: Error allocating member block")); + return; + } + device_group_member->ip_address = remote_ip; + *flink = device_group_member; + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: Member %s added"), IPAddressToString(remote_ip)); + break; + } + else if (device_group_member->ip_address == remote_ip) { + break; + } + flink = &device_group_member->flink; + } + + SendReceiveDeviceGroupMessage(device_group, device_group_member, message, message_length, true); +} + +void DeviceGroupStatus(uint8_t device_group_index) +{ + if (Settings.flag4.device_groups_enabled && device_group_index < device_group_count) { + char buffer[1024]; + int member_count = 0; + struct device_group * device_group = &device_groups[device_group_index]; + buffer[0] = buffer[1] = 0; + for (struct device_group_member * device_group_member = device_group->device_group_members; device_group_member; device_group_member = device_group_member->flink) { + snprintf_P(buffer, sizeof(buffer), PSTR("%s,{\"IPAddress\":\"%s\",\"ResendCount\":%u,\"LastRcvdSeq\":%u,\"LastAckedSeq\":%u}"), buffer, IPAddressToString(device_group_member->ip_address), device_group_member->unicast_count, device_group_member->received_sequence, device_group_member->acked_sequence); + member_count++; + } + Response_P(PSTR("{\"" D_CMND_DEVGROUPSTATUS "\":{\"Index\":%u,\"GroupName\":\"%s\",\"MessageSeq\":%u,\"MemberCount\":%d,\"Members\":[%s]}"), device_group_index, device_group->group_name, device_group->outgoing_sequence, member_count, &buffer[1]); + } } void DeviceGroupsLoop(void) { - if (!Settings.flag4.device_groups_enabled) return; - if (udp_connected) { - uint32_t now = millis(); + if (!device_groups_up || restart_flag) return; - // If UDP was not connected before, (re)initialize. - if (!udp_was_connected) { - udp_was_connected = true; - - if (!device_groups_initialized) DeviceGroupsInit(); - if (device_groups_initialization_failed) return; - - // Load the status request message for all device groups. This message will be multicast 5 - // times. - next_check_time = now + 3000; - for (uint32_t device_group_index = 0; device_group_index < device_group_count; device_group_index++) { - device_group * device_group = &device_groups[device_group_index]; - device_group->message_length = BeginDeviceGroupMessage(device_group, DGR_FLAG_RESET | DGR_FLAG_STATUS_REQUEST) - device_group->message; - device_group->initial_status_requests_remaining = 5; - device_group->next_ack_check_time = next_check_time; - } - - } - - if (device_groups_initialization_failed) return; - - // If it's time to check on things, iterate through the device groups. - if (next_check_time <= now) { -#ifdef DEVICE_GROUPS_DEBUG -AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: Ckecking next_check_time=%u, now=%u"), next_check_time, now); -#endif // DEVICE_GROUPS_DEBUG - next_check_time = now + DGR_ANNOUNCEMENT_INTERVAL * 2; - - for (uint32_t device_group_index = 0; device_group_index < device_group_count; device_group_index++) { - device_group * device_group = &device_groups[device_group_index]; - - // If we're still waiting for acks to the last update from this device group, ... - if (device_group->next_ack_check_time) { - - // If it's time to check for acks, ... - if (device_group->next_ack_check_time <= now) { - - // If we're still sending the initial status request message, send it. - if (device_group->initial_status_requests_remaining) { - if (--device_group->initial_status_requests_remaining) { -#ifdef DEVICE_GROUPS_DEBUG - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: sending initial status request for group %s"), device_group->group_name); -#endif // DEVICE_GROUPS_DEBUG - SendDeviceGroupPacket(0, device_group->message, device_group->message_length, PSTR("Initial")); - device_group->message[device_group->message_header_length + 2] = DGR_FLAG_STATUS_REQUEST; // The reset flag is on only for the first packet - turn it off now - device_group->next_ack_check_time = now + 200; - } - - // If we've sent the initial status request message 5 times, send our status to all - // the members. - else { - device_group->next_ack_check_time = 0; - _SendDeviceGroupMessage(device_group_index, DGR_MSGTYP_FULL_STATUS); - } - } - - // If we're done initializing, iterate through the group memebers, ... - else { -#ifdef DEVICE_GROUPS_DEBUG - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: checking for ack's")); -#endif // DEVICE_GROUPS_DEBUG - bool acked = true; - struct device_group_member ** flink = &device_group->device_group_members; - struct device_group_member * device_group_member; - while ((device_group_member = *flink)) { - - // If we have not received an ack to our last message from this member, ... - if (device_group_member->acked_sequence != outgoing_sequence) { - - // If we haven't receive an ack from this member in DGR_MEMBER_TIMEOUT ms, assume - // they're offline and remove them from the group. - if (device_group->member_timeout_time < now) { -#ifdef DEVICE_GROUPS_DEBUG - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: removing member %s (%p)"), IPAddressToString(device_group_member->ip_address), device_group_member); -#endif // DEVICE_GROUPS_DEBUG - *flink = device_group_member->flink; - free(device_group_member); - } - - // Otherwise, unicast the last message directly to this member. - else { -#ifdef DEVICE_GROUPS_DEBUG - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: sending %u-byte device group %s packet via unicast to %s, sequence %u, last message acked=%u"), device_group->message_length, device_group->group_name, IPAddressToString(device_group_member->ip_address), outgoing_sequence, device_group_member->acked_sequence); -#endif // DEVICE_GROUPS_DEBUG - SendDeviceGroupPacket(device_group_member->ip_address, device_group->message, device_group->message_length, PSTR("Unicast")); - acked = false; - flink = &device_group_member->flink; - } - } - else { - flink = &device_group_member->flink; - } - } - - // If we've received an ack to the last message from all members, clear the ack check - // time and zero-out the message length. - if (acked) { - device_group->next_ack_check_time = 0; - device_group->message_length = 0; // Let _SendDeviceGroupMessage know we're done with this update - } - - // If there are still members we haven't received an ack from, set the next ack check - // time. We start at 200ms and double the interval each pass with a maximum interval of - // 5 seconds. - else { - device_group->ack_check_interval *= 2; - if (device_group->ack_check_interval > 5000) device_group->ack_check_interval = 5000; - device_group->next_ack_check_time = now + device_group->ack_check_interval; - } - } - } - - if (device_group->next_ack_check_time < next_check_time) next_check_time = device_group->next_ack_check_time; - } - - // If it's time to send a multicast announcement for this group, send it. This is to - // announcement ourself to any members that have somehow not heard about us. We send it at - // the announcement interval plus a random number of milliseconds so that even if all the - // devices booted at the same time, they don't all multicast their announcements at the same - // time. -#ifdef DEVICE_GROUPS_DEBUG - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: next_announcement_time=%u, now=%u"), device_group->next_announcement_time, now); -#endif // DEVICE_GROUPS_DEBUG - if (device_group->next_announcement_time <= now) { -#ifdef DEVICE_GROUPS_DEBUG - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: sending device group %s announcement"), device_group->group_name); -#endif // DEVICE_GROUPS_DEBUG - SendDeviceGroupPacket(0, device_group->message, BeginDeviceGroupMessage(device_group, DGR_FLAG_ANNOUNCEMENT, true) - device_group->message, PSTR("Announcement")); - device_group->next_announcement_time = now + DGR_ANNOUNCEMENT_INTERVAL + random(10000); - } - if (device_group->next_announcement_time < next_check_time) next_check_time = device_group->next_announcement_time; + while (device_groups_udp.parsePacket()) { + uint8_t packet_buffer[512]; + int length = device_groups_udp.read(packet_buffer, sizeof(packet_buffer) - 1); + if (length > 0) { + packet_buffer[length] = 0; + if (!strncmp_P((char *)packet_buffer, kDeviceGroupMessage, sizeof(DEVICE_GROUP_MESSAGE) - 1)) { + ProcessDeviceGroupMessage(packet_buffer, length); } } } - else { - udp_was_connected = false; + + uint32_t now = millis(); + + // If it's time to check on things, iterate through the device groups. + if ((long)(now - next_check_time) >= 0) { +#ifdef DEVICE_GROUPS_DEBUG +AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: Checking next_check_time=%u, now=%u"), next_check_time, now); +#endif // DEVICE_GROUPS_DEBUG + next_check_time = now + DGR_ANNOUNCEMENT_INTERVAL * 2; + + struct device_group * device_group = device_groups; + for (uint32_t device_group_index = 0; device_group_index < device_group_count; device_group_index++, device_group++) { + + // If we're still waiting for acks to the last update from this device group, ... + if (device_group->next_ack_check_time) { + + // If it's time to check for acks, ... + if ((long)(now - device_group->next_ack_check_time) >= 0) { + + // If we're still sending the initial status request message, send it. + if (device_group->initial_status_requests_remaining) { + if (--device_group->initial_status_requests_remaining) { +#ifdef DEVICE_GROUPS_DEBUG + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: Sending initial status request for group %s"), device_group->group_name); +#endif // DEVICE_GROUPS_DEBUG + SendReceiveDeviceGroupMessage(device_group, nullptr, device_group->message, device_group->message_length, false); + device_group->message[device_group->message_header_length + 2] = DGR_FLAG_STATUS_REQUEST; // The reset flag is on only for the first packet - turn it off now + next_check_time = device_group->next_ack_check_time = now + 200; + continue; + } + + // If we've sent the initial status request message the set number of times, send our + // status to all the members. + else { + _SendDeviceGroupMessage(device_group_index, DGR_MSGTYP_FULL_STATUS); + } + } + + // If we're done initializing, iterate through the group memebers, ... + else { +#ifdef DEVICE_GROUPS_DEBUG + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: Checking for ack's")); +#endif // DEVICE_GROUPS_DEBUG + bool acked = true; + struct device_group_member ** flink = &device_group->device_group_members; + struct device_group_member * device_group_member; + while ((device_group_member = *flink)) { + + // If we have not received an ack to our last message from this member, ... + if (device_group_member->acked_sequence != device_group->outgoing_sequence) { + + // If we haven't receive an ack from this member in DGR_MEMBER_TIMEOUT ms, assume + // they're offline and remove them from the group. + if ((long)(now - device_group->member_timeout_time) >= 0) { + *flink = device_group_member->flink; + free(device_group_member); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: Member %s removed"), IPAddressToString(device_group_member->ip_address)); + continue; + } + + // Otherwise, unicast the last message directly to this member. + SendReceiveDeviceGroupMessage(device_group, device_group_member, device_group->message, device_group->message_length, false); + device_group_member->unicast_count++; + acked = false; + } + flink = &device_group_member->flink; + } + + // If we've received an ack to the last message from all members, clear the ack check + // time and zero-out the message length. + if (acked) { + device_group->next_ack_check_time = 0; + device_group->message_length = 0; // Let _SendDeviceGroupMessage know we're done with this update + } + + // If there are still members we haven't received an ack from, set the next ack check + // time. We start at 200ms and double the interval each pass with a maximum interval of + // 5 seconds. + else { + device_group->ack_check_interval *= 2; + if (device_group->ack_check_interval > 5000) device_group->ack_check_interval = 5000; + device_group->next_ack_check_time = now + device_group->ack_check_interval; + } + } + } + + if (device_group->next_ack_check_time < next_check_time) next_check_time = device_group->next_ack_check_time; + } + + // If it's time to send a multicast announcement for this group, send it. This is to + // announcement ourself to any members that have somehow not heard about us. We send it at the + // announcement interval plus a random number of milliseconds so that even if all the devices + // booted at the same time, they don't all multicast their announcements at the same time. +#ifdef DEVICE_GROUPS_DEBUG + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: next_announcement_time=%u, now=%u"), device_group->next_announcement_time, now); +#endif // DEVICE_GROUPS_DEBUG + if ((long)(now - device_group->next_announcement_time) >= 0) { + SendReceiveDeviceGroupMessage(device_group, nullptr, device_group->message, BeginDeviceGroupMessage(device_group, DGR_FLAG_ANNOUNCEMENT, true) - device_group->message, false); + device_group->next_announcement_time = now + DGR_ANNOUNCEMENT_INTERVAL + random(10000); + } + if (device_group->next_announcement_time < next_check_time) next_check_time = device_group->next_announcement_time; + } } } diff --git a/tasmota/support_eeprom.ino b/tasmota/support_eeprom.ino new file mode 100644 index 000000000..b990aa242 --- /dev/null +++ b/tasmota/support_eeprom.ino @@ -0,0 +1,89 @@ +/* + support_eeprom.ino - eeprom support for Sonoff-Tasmota + + Copyright (C) 2020 Theo Arends & Gerhard Mutz + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + + supports hardware i2c eeprom 24c256 and flash eeprom simulation on ESP8266 and ESP32 + all ESP8266 linker files contain 4k eeprom partition + ESP32 requires esp32_partition_app1984k_spiffs60k.csv for 4k eeprom +*/ + + +#ifdef USE_EEPROM + +#ifdef USE_24C256 + // i2c eeprom +#include +#define EEPROM_ADDRESS 0x50 +static Eeprom24C128_256 m_eeprom(EEPROM_ADDRESS); + +void eeprom_writeBytes(uint32_t addr, uint32_t len, uint8_t *buff) { + m_eeprom.writeBytes(addr,len,(uint8_t*)buff); +} +void eeprom_readBytes(uint32_t addr, uint32_t len, uint8_t *buff) { + m_eeprom.readBytes(addr,len,(uint8_t*)buff); +} + +uint32_t eeprom_init(uint32_t size) { + if (i2c_flg) { + if (I2cActive(EEPROM_ADDRESS) || I2cSetDevice(EEPROM_ADDRESS)) { + // eeprom is present + I2cSetActiveFound(EEPROM_ADDRESS, "24C256"); + return 1; + } + } + return 0; +} + +#else // USE_24C256 + +#ifdef ESP32 + +// esp32 uses eeprom section +uint32_t eeprom_init(uint32_t size) { + return EEPROM.begin(size); +} +void eeprom_writeBytes(uint32_t addr, uint32_t len, uint8_t *buff) { + EEPROM.writeBytes(addr, buff, len); + EEPROM.commit(); +} +void eeprom_readBytes(uint32_t addr, uint32_t len, uint8_t *buff) { + EEPROM.readBytes(addr, buff, len); +} + +#else +// esp8266 uses eeprom section +uint32_t eeprom_init(uint32_t size) { + EEPROM.begin(size); + return 1; +} +void eeprom_writeBytes(uint32_t adr, uint32_t len, uint8_t *buf) { + for (uint32_t cnt=0; cnt. +*/ + +/*********************************************************************************************\ + * ESP8266 Support +\*********************************************************************************************/ + +#ifdef ESP8266 + +extern "C" { +extern struct rst_info resetInfo; +} + +uint32_t ESP_ResetInfoReason(void) { + return resetInfo.reason; +} + +String ESP_getResetReason(void) { + return ESP.getResetReason(); +} + +uint32_t ESP_getChipId(void) { + return ESP.getChipId(); +} + +uint32_t ESP_getSketchSize(void) { + return ESP.getSketchSize(); +} + +uint32_t ESP_getFreeHeap(void) { + return ESP.getFreeHeap(); +} + +void ESP_Restart(void) { +// ESP.restart(); // This results in exception 3 on restarts on core 2.3.0 + ESP.reset(); +} + +#endif + +/*********************************************************************************************\ + * ESP32 Support +\*********************************************************************************************/ + +#ifdef ESP32 + +// Handle 20k of NVM + +#include +#include + +void NvmLoad(const char *sNvsName, const char *sName, void *pSettings, unsigned nSettingsLen) { + nvs_handle handle; + noInterrupts(); + nvs_open(sNvsName, NVS_READONLY, &handle); + size_t size = nSettingsLen; + nvs_get_blob(handle, sName, pSettings, &size); + nvs_close(handle); + interrupts(); +} + +void NvmSave(const char *sNvsName, const char *sName, const void *pSettings, unsigned nSettingsLen) { + nvs_handle handle; + noInterrupts(); + nvs_open(sNvsName, NVS_READWRITE, &handle); + nvs_set_blob(handle, sName, pSettings, nSettingsLen); + nvs_commit(handle); + nvs_close(handle); + interrupts(); +} + +void NvmErase(const char *sNvsName) { + nvs_handle handle; + noInterrupts(); + nvs_open(sNvsName, NVS_READWRITE, &handle); + nvs_erase_all(handle); + nvs_commit(handle); + nvs_close(handle); + interrupts(); +} + +void SettingsErase(uint8_t type) { + if (1 == type) { // SDK parameter area + } else if (2 == type) { // Tasmota parameter area (0x0F3xxx - 0x0FBFFF) + } else if (3 == type) { // Tasmota and SDK parameter area (0x0F3xxx - 0x0FFFFF) + } + + NvmErase("main"); + + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION D_ERASE " t=%d"), type); +} + +void SettingsRead(void *data, size_t size) { + NvmLoad("main", "Settings", data, size); +} + +void SettingsWrite(const void *pSettings, unsigned nSettingsLen) { + NvmSave("main", "Settings", pSettings, nSettingsLen); +} + +void QPCRead(void *pSettings, unsigned nSettingsLen) { + NvmLoad("qpc", "pcreg", pSettings, nSettingsLen); +} + +void QPCWrite(const void *pSettings, unsigned nSettingsLen) { + NvmSave("qpc", "pcreg", pSettings, nSettingsLen); +} + +void ZigbeeErase(void) { + NvmErase("zb"); +} + +void ZigbeeRead(void *pSettings, unsigned nSettingsLen) { + NvmLoad("zb", "zigbee", pSettings, nSettingsLen); +} + +void ZigbeeWrite(const void *pSettings, unsigned nSettingsLen) { + NvmSave("zb", "zigbee", pSettings, nSettingsLen); +} + +// +// sntp emulation +// +static bool bNetIsTimeSync = false; +// +void SntpInit() { + bNetIsTimeSync = true; +} + +uint32_t SntpGetCurrentTimestamp(void) { + time_t now = 0; + if (bNetIsTimeSync || ntp_force_sync) + { + //Serial_DebugX(("timesync configTime %d\n", ntp_force_sync, bNetIsTimeSync)); + // init to UTC Time + configTime(0, 0, SettingsText(SET_NTPSERVER1), SettingsText(SET_NTPSERVER2), SettingsText(SET_NTPSERVER3)); + bNetIsTimeSync = false; + ntp_force_sync = false; + } + time(&now); + return now; +} + +// +// Crash stuff +// + +void CrashDump(void) { +} + +bool CrashFlag(void) { + return false; +} + +void CrashDumpClear(void) { +} + +void CmndCrash(void) { + /* + volatile uint32_t dummy; + dummy = *((uint32_t*) 0x00000000); +*/ +} + +// Do an infinite loop to trigger WDT watchdog +void CmndWDT(void) { + /* + volatile uint32_t dummy = 0; + while (1) { + dummy++; + } +*/ +} +// This will trigger the os watch after OSWATCH_RESET_TIME (=120) seconds +void CmndBlockedLoop(void) { + /* + while (1) { + delay(1000); + } +*/ +} + +// +// ESP32 specific +// + +#include "soc/soc.h" +#include "soc/rtc_cntl_reg.h" + +void DisableBrownout(void) { + // https://github.com/espressif/arduino-esp32/issues/863#issuecomment-347179737 + WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); // Disable brownout detector +} + +// +// ESP32 Alternatives +// + +String ESP32GetResetReason(uint32_t cpu_no) { + // tools\sdk\include\esp32\rom\rtc.h + switch (rtc_get_reset_reason( (RESET_REASON) cpu_no)) { + case POWERON_RESET : return F("Vbat power on reset"); // 1 + case SW_RESET : return F("Software reset digital core"); // 3 + case OWDT_RESET : return F("Legacy watch dog reset digital core"); // 4 + case DEEPSLEEP_RESET : return F("Deep Sleep reset digital core"); // 5 + case SDIO_RESET : return F("Reset by SLC module, reset digital core"); // 6 + case TG0WDT_SYS_RESET : return F("Timer Group0 Watch dog reset digital core"); // 7 + case TG1WDT_SYS_RESET : return F("Timer Group1 Watch dog reset digital core"); // 8 + case RTCWDT_SYS_RESET : return F("RTC Watch dog Reset digital core"); // 9 + case INTRUSION_RESET : return F("Instrusion tested to reset CPU"); // 10 + case TGWDT_CPU_RESET : return F("Time Group reset CPU"); // 11 + case SW_CPU_RESET : return F("Software reset CPU"); // 12 + case RTCWDT_CPU_RESET : return F("RTC Watch dog Reset CPU"); // 13 + case EXT_CPU_RESET : return F("or APP CPU, reseted by PRO CPU"); // 14 + case RTCWDT_BROWN_OUT_RESET : return F("Reset when the vdd voltage is not stable"); // 15 + case RTCWDT_RTC_RESET : return F("RTC Watch dog reset digital core and rtc module"); // 16 + default : return F("NO_MEAN"); // 0 + } +} + +String ESP_getResetReason(void) { + return ESP32GetResetReason(0); // CPU 0 +} + +uint32_t ESP_ResetInfoReason(void) { + RESET_REASON reason = rtc_get_reset_reason(0); + if (POWERON_RESET == reason) { return REASON_DEFAULT_RST; } + if (SW_CPU_RESET == reason) { return REASON_SOFT_RESTART; } + if (DEEPSLEEP_RESET == reason) { return REASON_DEEP_SLEEP_AWAKE; } + if (SW_RESET == reason) { return REASON_EXT_SYS_RST; } +} + +uint32_t ESP_getChipId(void) { + uint32_t id = 0; + for (uint32_t i = 0; i < 17; i = i +8) { + id |= ((ESP.getEfuseMac() >> (40 - i)) & 0xff) << i; + } + return id; +} + +uint32_t ESP_getSketchSize(void) { + static uint32_t sketchsize = 0; + + if (!sketchsize) { + sketchsize = ESP.getSketchSize(); // This takes almost 2 seconds on an ESP32 + } + return sketchsize; +} + +uint32_t ESP_getFreeHeap(void) { +// return ESP.getFreeHeap(); + return ESP.getMaxAllocHeap(); +} + +void ESP_Restart(void) { + ESP.restart(); +} + +#endif // ESP32 diff --git a/tasmota/support_esptool.ino b/tasmota/support_esptool.ino index 5bb82f999..efde513fc 100644 --- a/tasmota/support_esptool.ino +++ b/tasmota/support_esptool.ino @@ -17,7 +17,10 @@ along with this program. If not, see . */ +#ifdef ESP8266 #define USE_ESPTOOL +#endif // ESP8266 + #ifdef USE_ESPTOOL /*********************************************************************************************\ * EspTool Erase function based on Version 2.8 diff --git a/tasmota/support_features.ino b/tasmota/support_features.ino index 7b094d534..6dfb5ee0e 100644 --- a/tasmota/support_features.ino +++ b/tasmota/support_features.ino @@ -25,7 +25,7 @@ void GetFeatures(void) { feature_drv1 = 0x00000000; -#ifdef USE_ENERGY_MARGIN_DETECTION +#if defined(USE_ENERGY_SENSOR) && defined(USE_ENERGY_MARGIN_DETECTION) feature_drv1 |= 0x00000001; // xdrv_03_energy.ino #endif #ifdef USE_LIGHT @@ -49,31 +49,31 @@ void GetFeatures(void) #ifdef USE_WEBSERVER feature_drv1 |= 0x00000080; // xdrv_01_webserver.ino #endif -#ifdef WEBSERVER_ADVERTISE +#if defined(USE_WEBSERVER) && defined(WEBSERVER_ADVERTISE) feature_drv1 |= 0x00000100; // xdrv_01_webserver.ino #endif -#ifdef USE_EMULATION_HUE +#if defined(USE_WEBSERVER) && defined(USE_EMULATION_HUE) feature_drv1 |= 0x00000200; // xdrv_20_hue.ino #endif -#if (MQTT_LIBRARY_TYPE == MQTT_PUBSUBCLIENT) +//#if (MQTT_LIBRARY_TYPE == MQTT_PUBSUBCLIENT) feature_drv1 |= 0x00000400; // xdrv_02_mqtt.ino -#endif -#if (MQTT_LIBRARY_TYPE == MQTT_TASMOTAMQTT) +//#endif +//#if (MQTT_LIBRARY_TYPE == MQTT_TASMOTAMQTT) // feature_drv1 |= 0x00000800; // xdrv_02_mqtt.ino -#endif -#if (MQTT_LIBRARY_TYPE == MQTT_ESPMQTTARDUINO) // Obsolete since 6.2.1.11 +//#endif +//#if (MQTT_LIBRARY_TYPE == MQTT_ESPMQTTARDUINO) // Obsolete since 6.2.1.11 // feature_drv1 |= 0x00001000; // xdrv_02_mqtt.ino -#endif -#ifdef MQTT_HOST_DISCOVERY +//#endif +#if defined(USE_DISCOVERY) && defined(MQTT_HOST_DISCOVERY) feature_drv1 |= 0x00002000; // xdrv_02_mqtt.ino #endif -#ifdef USE_ARILUX_RF +#if defined(USE_LIGHT) && defined(USE_ARILUX_RF) feature_drv1 |= 0x00004000; // xdrv_04_light.ino #endif #if defined(USE_LIGHT) && defined(USE_WS2812) feature_drv1 |= 0x00008000; // xdrv_04_light.ino #endif -#ifdef USE_WS2812_DMA +#if defined(USE_LIGHT) && defined(USE_WS2812) && defined(USE_WS2812_DMA) feature_drv1 |= 0x00010000; // xdrv_04_light.ino #endif #if defined(USE_IR_REMOTE) || defined(USE_IR_REMOTE_FULL) @@ -82,7 +82,7 @@ void GetFeatures(void) #ifdef USE_IR_HVAC feature_drv1 |= 0x00040000; // xdrv_05_irremote.ino #endif -#ifdef USE_IR_RECEIVE +#if defined(USE_IR_REMOTE) && defined(USE_IR_RECEIVE) feature_drv1 |= 0x00080000; // xdrv_05_irremote.ino #endif #ifdef USE_DOMOTICZ @@ -100,10 +100,10 @@ void GetFeatures(void) #ifdef USE_TIMERS feature_drv1 |= 0x01000000; // xdrv_09_timers.ino #endif -#ifdef USE_SUNRISE +#if defined(USE_TIMERS) && defined(USE_SUNRISE) feature_drv1 |= 0x02000000; // xdrv_09_timers.ino #endif -#ifdef USE_TIMERS_WEB +#if defined(USE_TIMERS) && defined(USE_TIMERS_WEB) feature_drv1 |= 0x04000000; // xdrv_09_timers.ino #endif #ifdef USE_RULES @@ -118,7 +118,7 @@ void GetFeatures(void) #ifdef USE_SMARTCONFIG feature_drv1 |= 0x40000000; // support.ino - removed with version 6.6.0.21 #endif -#ifdef USE_ENERGY_POWER_LIMIT +#if defined(USE_ENERGY_SENSOR) && defined(USE_ENERGY_POWER_LIMIT) feature_drv1 |= 0x80000000; // xdrv_03_energy.ino #endif @@ -141,34 +141,34 @@ void GetFeatures(void) #ifdef FIRMWARE_KNX_NO_EMULATION feature_drv2 |= 0x00000010; // user_config(_override).h #endif -#ifdef USE_DISPLAY_MODES1TO5 +#if defined(USE_DISPLAY) && defined(USE_DISPLAY_MODES1TO5) feature_drv2 |= 0x00000020; // xdrv_13_display.ino #endif -#ifdef USE_DISPLAY_GRAPH +#if defined(USE_DISPLAY) && defined(USE_DISPLAY_GRAPH) feature_drv2 |= 0x00000040; // xdrv_13_display.ino #endif -#ifdef USE_DISPLAY_LCD +#if defined(USE_I2C) && defined(USE_DISPLAY) && defined(USE_DISPLAY_LCD) feature_drv2 |= 0x00000080; // xdsp_01_lcd.ino #endif -#ifdef USE_DISPLAY_SSD1306 +#if defined(USE_I2C) && defined(USE_DISPLAY) && defined(USE_DISPLAY_SSD1306) feature_drv2 |= 0x00000100; // xdsp_02_ssd1306.ino #endif -#ifdef USE_DISPLAY_MATRIX +#if defined(USE_I2C) && defined(USE_DISPLAY) && defined(USE_DISPLAY_MATRIX) feature_drv2 |= 0x00000200; // xdsp_03_matrix.ino #endif -#ifdef USE_DISPLAY_ILI9341 +#if defined(USE_SPI) && defined(USE_DISPLAY) && defined(USE_DISPLAY_ILI9341) feature_drv2 |= 0x00000400; // xdsp_04_ili9341.ino #endif -#ifdef USE_DISPLAY_EPAPER_29 +#if defined(USE_SPI) && defined(USE_DISPLAY) && defined(USE_DISPLAY_EPAPER_29) feature_drv2 |= 0x00000800; // xdsp_05_epaper.ino #endif -#ifdef USE_DISPLAY_SH1106 +#if defined(USE_I2C) && defined(USE_DISPLAY) && defined(USE_DISPLAY_SH1106) feature_drv2 |= 0x00001000; // xdsp_06_sh1106.ino #endif #ifdef USE_MP3_PLAYER feature_drv2 |= 0x00002000; // xdrv_14_mp3.ino #endif -#ifdef USE_PCA9685 +#if defined(USE_I2C) && defined(USE_PCA9685) feature_drv2 |= 0x00004000; // xdrv_15_pca9685.ino #endif #if defined(USE_LIGHT) && defined(USE_TUYA_MCU) @@ -186,7 +186,7 @@ void GetFeatures(void) #ifdef USE_SCRIPT feature_drv2 |= 0x00080000; // xdrv_10_scripter.ino #endif -#ifdef USE_EMULATION_WEMO +#if defined(USE_WEBSERVER) && defined(USE_EMULATION_WEMO) feature_drv2 |= 0x00100000; // xdrv_21_wemo.ino #endif #ifdef USE_SONOFF_IFAN @@ -236,7 +236,7 @@ void GetFeatures(void) #ifdef USE_ENERGY_SENSOR feature_sns1 |= 0x00000004; // xdrv_03_energy.ino #endif -#ifdef USE_PZEM004T +#if defined(USE_ENERGY_SENSOR) && defined(USE_PZEM004T) feature_sns1 |= 0x00000008; // xnrg_03_pzem004t.ino #endif #ifdef USE_DS18B20 @@ -251,40 +251,40 @@ void GetFeatures(void) #ifdef USE_DHT feature_sns1 |= 0x00000080; // xsns_06_dht.ino #endif -#ifdef USE_SHT +#if defined(USE_I2C) && defined(USE_SHT) feature_sns1 |= 0x00000100; // xsns_07_sht1x.ino #endif -#ifdef USE_HTU +#if defined(USE_I2C) && defined(USE_HTU) feature_sns1 |= 0x00000200; // xsns_08_htu21.ino #endif -#ifdef USE_BMP +#if defined(USE_I2C) && defined(USE_BMP) feature_sns1 |= 0x00000400; // xsns_09_bmp.ino #endif -#ifdef USE_BME680 +#if defined(USE_I2C) && defined(USE_BMP) && defined(USE_BME680) feature_sns1 |= 0x00000800; // xsns_09_bmp.ino - BME680 #endif -#ifdef USE_BH1750 +#if defined(USE_I2C) && defined(USE_BH1750) feature_sns1 |= 0x00001000; // xsns_10_bh1750.ino #endif -#ifdef USE_VEML6070 +#if defined(USE_I2C) && defined(USE_VEML6070) feature_sns1 |= 0x00002000; // xsns_11_veml6070.ino #endif -#ifdef USE_ADS1115_I2CDEV +#if defined(USE_I2C) && defined(USE_ADS1115_I2CDEV) feature_sns1 |= 0x00004000; // xsns_12_ads1115_i2cdev.ino #endif -#ifdef USE_ADS1115 +#if defined(USE_I2C) && defined(USE_ADS1115) feature_sns1 |= 0x00008000; // xsns_12_ads1115.ino #endif -#ifdef USE_INA219 +#if defined(USE_I2C) && defined(USE_INA219) feature_sns1 |= 0x00010000; // xsns_13_ina219.ino #endif -#ifdef USE_SHT3X +#if defined(USE_I2C) && defined(USE_SHT3X) feature_sns1 |= 0x00020000; // xsns_14_sht3x.ino #endif #ifdef USE_MHZ19 feature_sns1 |= 0x00040000; // xsns_15_mhz19.ino #endif -#ifdef USE_TSL2561 +#if defined(USE_I2C) && defined(USE_TSL2561) feature_sns1 |= 0x00080000; // xsns_16_tsl2561.ino #endif #ifdef USE_SENSEAIR @@ -293,31 +293,31 @@ void GetFeatures(void) #ifdef USE_PMS5003 feature_sns1 |= 0x00200000; // xsns_18_pms5003.ino #endif -#ifdef USE_MGS +#if defined(USE_I2C) && defined(USE_MGS) feature_sns1 |= 0x00400000; // xsns_19_mgs.ino #endif #ifdef USE_NOVA_SDS feature_sns1 |= 0x00800000; // xsns_20_novasds.ino #endif -#ifdef USE_SGP30 +#if defined(USE_I2C) && defined(USE_SGP30) feature_sns1 |= 0x01000000; // xsns_21_sgp30.ino #endif #ifdef USE_SR04 feature_sns1 |= 0x02000000; // xsns_22_sr04.ino #endif -#ifdef USE_SDM120 +#if defined(USE_ENERGY_SENSOR) && defined(USE_SDM120) feature_sns1 |= 0x04000000; // xnrg_08_sdm120.ino #endif -#ifdef USE_SI1145 +#if defined(USE_I2C) && defined(USE_SI1145) feature_sns1 |= 0x08000000; // xsns_24_si1145.ino #endif -#ifdef USE_SDM630 +#if defined(USE_ENERGY_SENSOR) && defined(USE_SDM630) feature_sns1 |= 0x10000000; // xnrg_10_sdm630.ino #endif -#ifdef USE_LM75AD +#if defined(USE_I2C) && defined(USE_LM75AD) feature_sns1 |= 0x20000000; // xsns_26_lm75ad.ino #endif -#ifdef USE_APDS9960 +#if defined(USE_I2C) && defined(USE_APDS9960) feature_sns1 |= 0x40000000; // xsns_27_apds9960.ino #endif #ifdef USE_TM1638 @@ -328,58 +328,58 @@ void GetFeatures(void) feature_sns2 = 0x00000000; -#ifdef USE_MCP230xx +#if defined(USE_I2C) && defined(USE_MCP230xx) feature_sns2 |= 0x00000001; // xsns_29_mcp230xx.ino #endif -#ifdef USE_MPR121 +#if defined(USE_I2C) && defined(USE_MPR121) feature_sns2 |= 0x00000002; // xsns_30_mpr121.ino #endif -#ifdef USE_CCS811 +#if defined(USE_I2C) && defined(USE_CCS811) feature_sns2 |= 0x00000004; // xsns_31_ccs811.ino #endif -#ifdef USE_MPU6050 +#if defined(USE_I2C) && defined(USE_MPU6050) feature_sns2 |= 0x00000008; // xsns_32_mpu6050.ino #endif -#ifdef USE_MCP230xx_OUTPUT +#if defined(USE_I2C) && defined(USE_MCP230xx) && defined(USE_MCP230xx_OUTPUT) feature_sns2 |= 0x00000010; // xsns_29_mcp230xx.ino #endif -#ifdef USE_MCP230xx_DISPLAYOUTPUT +#if defined(USE_I2C) && defined(USE_MCP230xx) && defined(USE_MCP230xx_DISPLAYOUTPUT) feature_sns2 |= 0x00000020; // xsns_29_mcp230xx.ino #endif -#ifdef USE_HLW8012 +#if defined(USE_ENERGY_SENSOR) && defined(USE_HLW8012) feature_sns2 |= 0x00000040; // xnrg_01_hlw8012.ino #endif -#ifdef USE_CSE7766 +#if defined(USE_ENERGY_SENSOR) && defined(USE_CSE7766) feature_sns2 |= 0x00000080; // xnrg_02_cse7766.ino #endif -#ifdef USE_MCP39F501 +#if defined(USE_ENERGY_SENSOR) && defined(USE_MCP39F501) feature_sns2 |= 0x00000100; // xnrg_04_mcp39f501.ino #endif -#ifdef USE_PZEM_AC +#if defined(USE_ENERGY_SENSOR) && defined(USE_PZEM_AC) feature_sns2 |= 0x00000200; // xnrg_05_pzem_ac.ino #endif -#ifdef USE_DS3231 +#if defined(USE_I2C) && defined(USE_DS3231) feature_sns2 |= 0x00000400; // xsns_33_ds3231.ino #endif #ifdef USE_HX711 feature_sns2 |= 0x00000800; // xsns_34_hx711.ino #endif -#ifdef USE_PZEM_DC +#if defined(USE_ENERGY_SENSOR) && defined(USE_PZEM_DC) feature_sns2 |= 0x00001000; // xnrg_06_pzem_dc.ino #endif #if defined(USE_TX20_WIND_SENSOR) || defined(USE_TX23_WIND_SENSOR) feature_sns2 |= 0x00002000; // xsns_35_tx20.ino #endif -#ifdef USE_MGC3130 +#if defined(USE_I2C) && defined(USE_MGC3130) feature_sns2 |= 0x00004000; // xsns_36_mgc3130.ino #endif #ifdef USE_RF_SENSOR feature_sns2 |= 0x00008000; // xsns_37_rfsensor.ino #endif -#ifdef USE_THEO_V2 +#if defined(USE_RF_SENSOR) && defined(USE_THEO_V2) feature_sns2 |= 0x00010000; // xsns_37_rfsensor.ino #endif -#ifdef USE_ALECTO_V2 +#if defined(USE_RF_SENSOR) && defined(USE_ALECTO_V2) feature_sns2 |= 0x00020000; // xsns_37_rfsensor.ino #endif #ifdef USE_AZ7798 @@ -391,37 +391,37 @@ void GetFeatures(void) #ifdef USE_PN532_HSU feature_sns2 |= 0x00100000; // xsns_40_pn532.ino #endif -#ifdef USE_MAX44009 +#if defined(USE_I2C) && defined(USE_MAX44009) feature_sns2 |= 0x00200000; // xsns_41_max44009.ino #endif -#ifdef USE_SCD30 +#if defined(USE_I2C) && defined(USE_SCD30) feature_sns2 |= 0x00400000; // xsns_42_scd30.ino #endif #ifdef USE_HRE feature_sns2 |= 0x00800000; // xsns_43_hre.ino #endif -#ifdef USE_ADE7953 +#if defined(USE_ENERGY_SENSOR) && defined(USE_ADE7953) feature_sns2 |= 0x01000000; // xnrg_07_ade7953.ino #endif -#ifdef USE_SPS30 +#if defined(USE_I2C) && defined(USE_SPS30) feature_sns2 |= 0x02000000; // xsns_44_sps30.ino #endif -#ifdef USE_VL53L0X +#if defined(USE_I2C) && defined(USE_VL53L0X) feature_sns2 |= 0x04000000; // xsns_45_vl53l0x.ino #endif -#ifdef USE_MLX90614 +#if defined(USE_I2C) && defined(USE_MLX90614) feature_sns2 |= 0x08000000; // xsns_46_MLX90614.ino #endif #ifdef USE_MAX31865 feature_sns2 |= 0x10000000; // xsns_47-max31865.ino #endif -#ifdef USE_CHIRP +#if defined(USE_I2C) && defined(USE_CHIRP) feature_sns2 |= 0x20000000; // xsns_48_chirp.ino #endif -#ifdef USE_SOLAX_X1 +#if defined(USE_ENERGY_SENSOR) && defined(USE_SOLAX_X1) feature_sns2 |= 0x40000000; // xnrg_12_solaxX1.ino #endif -#ifdef USE_PAJ7620 +#if defined(USE_I2C) && defined(USE_PAJ7620) feature_sns2 |= 0x80000000; // xsns_50_paj7620.ino #endif @@ -441,25 +441,25 @@ void GetFeatures(void) #ifdef USE_SML_M feature5 |= 0x00000008; // xsns_53_sml.ino #endif -#ifdef USE_INA226 +#if defined(USE_I2C) && defined(USE_INA226) feature5 |= 0x00000010; // xsns_54_ina226.ino #endif #ifdef USE_A4988_STEPPER feature5 |= 0x00000020; // xdrv_25_A4988.ino #endif -#ifdef USE_DDS2382 +#if defined(USE_ENERGY_SENSOR) && defined(USE_DDS2382) feature5 |= 0x00000040; // xnrg_09_dds2382.ino #endif -#ifdef USE_SM2135 +#if defined(USE_LIGHT) && defined(USE_SM2135) feature5 |= 0x00000080; // xdrv_026_sm2135.ino #endif #ifdef USE_SHUTTER feature5 |= 0x00000100; // xdrv_027_shutter.ino #endif -#ifdef USE_PCF8574 +#if defined(USE_I2C) && defined(USE_PCF8574) feature5 |= 0x00000200; // xdrv_028_pcf8574.ino #endif -#ifdef USE_DDSU666 +#if defined(USE_ENERGY_SENSOR) && defined(USE_DDSU666) feature5 |= 0x00000400; // xnrg_11_ddsu666.ino #endif #ifdef USE_DEEPSLEEP @@ -471,34 +471,34 @@ void GetFeatures(void) #ifdef USE_SONOFF_RF feature5 |= 0x00002000; // xdrv_06_snfbridge.ino #endif -#ifdef USE_SONOFF_L1 +#if defined(USE_LIGHT) && defined(USE_SONOFF_L1) feature5 |= 0x00004000; // xlgt_05_sonoff_l1.ino #endif -#ifdef USE_EXS_DIMMER +#if defined(USE_LIGHT) && defined(USE_EXS_DIMMER) feature5 |= 0x00008000; // xdrv_30_exs_dimmer.ino #endif -#ifdef USE_ARDUINO_SLAVE - feature5 |= 0x00010000; // xdrv_31_arduino_slave.ino +#ifdef USE_TASMOTA_CLIENT + feature5 |= 0x00010000; // xdrv_31_tasmota_client.ino #endif -#ifdef USE_HIH6 +#if defined(USE_I2C) && defined(USE_HIH6) feature5 |= 0x00020000; // xsns_55_hih_series.ino #endif #ifdef USE_HPMA feature5 |= 0x00040000; // xsns_56_hpma.ino #endif -#ifdef USE_TSL2591 +#if defined(USE_I2C) && defined(USE_TSL2591) feature5 |= 0x00080000; // xsns_57_tsl2591.ino #endif -#ifdef USE_DHT12 +#if defined(USE_I2C) && defined(USE_DHT12) feature5 |= 0x00100000; // xsns_58_dht12.ino #endif -#ifdef USE_DS1624 +#if defined(USE_I2C) && defined(USE_DS1624) feature5 |= 0x00200000; // xsns_59_ds1624.ino #endif #ifdef USE_GPS feature5 |= 0x00400000; // xsns_60_GPS.ino #endif -#ifdef USE_HOTPLUG +#if defined(USE_I2C) && defined(USE_HOTPLUG) feature5 |= 0x00800000; // xdrv_32_hotplug.ino #endif #ifdef USE_NRF24 @@ -510,13 +510,13 @@ void GetFeatures(void) #ifdef USE_HM10 feature5 |= 0x04000000; // xsns_62_MI_HM10.ino #endif -#ifdef USE_LE01MR +#if defined(USE_ENERGY_SENSOR) && defined(USE_LE01MR) feature5 |= 0x08000000; // xnrg_13_fif_le01mr.ino #endif -#ifdef USE_AHT1x +#if defined(USE_I2C) && defined(USE_AHT1x) feature5 |= 0x10000000; // xsns_63_aht1x.ino #endif -#ifdef USE_WEMOS_MOTOR_V1 +#if defined(USE_I2C) && defined(USE_WEMOS_MOTOR_V1) feature5 |= 0x20000000; // xdrv_34_wemos_motor_v1.ino #endif #ifdef USE_DEVICE_GROUPS @@ -539,33 +539,60 @@ void GetFeatures(void) #ifdef USE_SONOFF_D1 feature6 |= 0x00000004; // xdrv_37_sonoff_d1.ino #endif -#ifdef USE_HDC1080 +#if defined(USE_I2C) && defined(USE_HDC1080) feature6 |= 0x00000008; // xsns_65_hdc1080.ino #endif -#ifdef USE_IAQ +#if defined(USE_I2C) && defined(USE_IAQ) feature6 |= 0x00000010; // xsns_66_iAQ.ino #endif - -// feature6 |= 0x00000020; -// feature6 |= 0x00000040; -// feature6 |= 0x00000080; - -// feature6 |= 0x00000100; -// feature6 |= 0x00000200; -// feature6 |= 0x00000400; -// feature6 |= 0x00000800; - -// feature6 |= 0x00001000; -// feature6 |= 0x00002000; -// feature6 |= 0x00004000; -// feature6 |= 0x00008000; - -// feature6 |= 0x00010000; -// feature6 |= 0x00020000; -// feature6 |= 0x00040000; -// feature6 |= 0x00080000; - -// feature6 |= 0x00100000; +#if defined(USE_DISPLAY) && defined(USE_DISPLAY_SEVENSEG) + feature6 |= 0x00000020; // xdsp_11_sevenseg.ino +#endif +#if defined(USE_I2C) && defined(USE_AS3935) + feature6 |= 0x00000040; // xsns_67_as3935.ino +#endif +#ifdef USE_PING + feature6 |= 0x00000080; // xdrv_38_ping.ino +#endif +#ifdef USE_WINDMETER + feature6 |= 0x00000100; // xsns_68_windmeter.ino +#endif +#ifdef USE_OPENTHERM + feature6 |= 0x00000200; // xsns_69_opentherm.ino +#endif +#ifdef USE_THERMOSTAT + feature6 |= 0x00000400; // xdrv_39_heating.ino +#endif +#if defined(USE_I2C) && defined(USE_VEML6075) + feature6 |= 0x00000800; // xsns_70_veml6075.ino +#endif +#if defined(USE_I2C) && defined(USE_VEML7700) + feature6 |= 0x00001000; // xsns_71_veml7700.ino +#endif +#if defined(USE_I2C) && defined(USE_MCP9808) + feature6 |= 0x00002000; // xsns_72_mcp9808.ino +#endif +#if defined(USE_ENERGY_SENSOR) && defined(USE_BL0940) + feature6 |= 0x00004000; // xnrg_14_bl0940.ino +#endif +#ifdef USE_TELEGRAM + feature6 |= 0x00008000; // xdrv_40_telegram.ino +#endif +#if defined(USE_I2C) && defined(USE_HP303B) + feature6 |= 0x00010000; // xsns_73_hp303b.ino +#endif +#ifdef USE_TCP_BRIDGE + feature6 |= 0x00020000; // xdrv_41_tcp_bridge.ino +#endif +#if defined(USE_ENERGY_SENSOR) && defined(USE_TELEINFO) + feature6 |= 0x00040000; // xnrg_15_teleinfo.ino +#endif +#ifdef USE_LMT01 + feature6 |= 0x00080000; // xsns_74_lmt01.ino +#endif +#ifdef USE_PROMETHEUS + feature6 |= 0x00100000; // xsns_75_prometheus.ino +#endif // feature6 |= 0x00200000; // feature6 |= 0x00400000; // feature6 |= 0x00800000; @@ -577,7 +604,10 @@ void GetFeatures(void) // feature6 |= 0x10000000; // feature6 |= 0x20000000; -// feature6 |= 0x40000000; -// feature6 |= 0x80000000; - +#if defined(ESP32) && defined(USE_ETHERNET) + feature6 |= 0x40000000; // xdrv_82_ethernet.ino +#endif +#if defined(ESP32) && defined(USE_WEBCAM) + feature6 |= 0x80000000; // xdrv_81_webcam.ino +#endif } diff --git a/tasmota/support_flash_log.ino b/tasmota/support_flash_log.ino index 162ea1f0b..5f73c4078 100644 --- a/tasmota/support_flash_log.ino +++ b/tasmota/support_flash_log.ino @@ -37,6 +37,7 @@ \*********************************************************************************************/ #ifdef USE_FLOG +#ifdef ESP8266 class FLOG @@ -370,13 +371,13 @@ void FLOG::stopRecording(void){ * * @param size: size of the data entry/record in bytes, i.e. sizeof(myStruct) * @param sendHeader: should implement at least something like: - * @example WebServer->setContentLength(CONTENT_LENGTH_UNKNOWN); // This is very likely unknown!! - * WebServer->sendHeader(F("Content-Disposition"), F("attachment; filename=myfile.txt")); + * @example Webserver->setContentLength(CONTENT_LENGTH_UNKNOWN); // This is very likely unknown!! + * Webserver->sendHeader(F("Content-Disposition"), F("attachment; filename=myfile.txt")); * @param sendRecord: will receive the memory address as "uint8_t* addr" and should consume the current entry/record * @example myStruct_t *entry = (myStruct_t*)addr; - * Then make useful Strings and send it, i.e.: WebServer->sendContent_P(myString); + * Then make useful Strings and send it, i.e.: Webserver->sendContent_P(myString); * @param sendFooter: finish the download, should implement at least: - * @example WebServer->sendContent(""); + * @example Webserver->sendContent(""); */ void FLOG::startDownload(size_t size, CallbackNoArgs sendHeader, CallbackWithArgs sendRecord, CallbackNoArgs sendFooter){ @@ -400,7 +401,7 @@ void FLOG::stopRecording(void){ if(k%128 == 0){ // give control to the system every x iteration, TODO: This will fail, when record/entry-size is not 8 // DEBUG_SENSOR_LOG(PSTR("FLOG: now loop(), %u bytes left"), Flog->bytes_left); OsWatchLoop(); - delay(sleep); + delay(ssleep); } k+=size; if(bytes_left>7){ @@ -419,7 +420,7 @@ void FLOG::stopRecording(void){ _readSector(next_sector); bytes_left = sector.header.buf_pointer - sizeof(sector.header); OsWatchLoop(); - delay(sleep); + delay(ssleep); } running_download = false; // Callback 3: create a footer or simply finish the download with an empty payload @@ -429,4 +430,5 @@ void FLOG::stopRecording(void){ _initBuffer(); } + #endif // ESP8266 #endif // USE_FLOG \ No newline at end of file diff --git a/tasmota/support_float.ino b/tasmota/support_float.ino index 29613453a..98553d183 100644 --- a/tasmota/support_float.ino +++ b/tasmota/support_float.ino @@ -422,3 +422,26 @@ uint16_t changeUIntScale(uint16_t inum, uint16_t ifrom_min, uint16_t ifrom_max, } return (uint32_t) (result > to_max ? to_max : (result < to_min ? to_min : result)); } + +// Force a float value between two ranges, and adds or substract the range until we fit +float ModulusRangef(float f, float a, float b) { + if (b <= a) { return a; } // inconsistent, do what we can + float range = b - a; + float x = f - a; // now range of x should be 0..range + x = fmodf(x, range); // actual range is now -range..range + if (x < 0.0f) { x += range; } // actual range is now 0..range + return x + a; // returns range a..b +} + +// Compute a n-degree polynomial for value x and an array of coefficient (by increasing order) +// Ex: +// For factors = { f0, f1, f2, f3 } +// Returns : f0 + f1 x + f2 x^2, + f3 x^3 +// Internally computed as : f0 + x (f1 + x (f2 + x f3)) +float Polynomialf(const float *factors, uint32_t degree, float x) { + float r = 0.0f; + for (uint32_t i = degree - 1; i >= 0; i--) { + r = r * x + factors[i]; + } + return r; +} diff --git a/tasmota/support_jpeg.ino b/tasmota/support_jpeg.ino new file mode 100644 index 000000000..7e811cd76 --- /dev/null +++ b/tasmota/support_jpeg.ino @@ -0,0 +1,157 @@ +/* + jpeg_utils.c - Version header file for Tasmota + + Copyright (C) 2020 Theo Arends + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + + +#ifdef ESP32 +#ifdef JPEG_PICTS + +#include "img_converters.h" +#include "esp_jpg_decode.h" + +void rgb888_to_565(uint8_t *in, uint16_t *out, uint32_t len) { +uint8_t red, grn, blu; +uint16_t b , g, r; + + for (uint32_t cnt=0; cnt> 3) & 0x1f; + g = ((grn >> 2) & 0x3f) << 5; + r = ((red >> 3) & 0x1f) << 11; + *out++ = (r | g | b); + } +} + +typedef struct { + uint16_t width; + uint16_t height; + uint16_t data_offset; + const uint8_t *input; + uint8_t *output; +} rgb_jpg_decoder; + +//input buffer +static uint32_t _jpg_read(void * arg, size_t index, uint8_t *buf, size_t len) +{ + rgb_jpg_decoder * jpeg = (rgb_jpg_decoder *)arg; + if(buf) { + memcpy(buf, jpeg->input + index, len); + } + return len; +} + +//output buffer and image width +static bool _rgb_write(void * arg, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint8_t *data) +{ + rgb_jpg_decoder * jpeg = (rgb_jpg_decoder *)arg; + if(!data){ + if(x == 0 && y == 0){ + //write start + jpeg->width = w; + jpeg->height = h; + //if output is null, this is BMP + if(!jpeg->output){ + jpeg->output = (uint8_t *)malloc((w*h*3)+jpeg->data_offset); + if(!jpeg->output){ + return false; + } + } + } else { + //write end + } + return true; + } + + size_t jw = jpeg->width*3; + size_t t = y * jw; + size_t b = t + (h * jw); + size_t l = x * 3; + uint8_t *out = jpeg->output+jpeg->data_offset; + uint8_t *o = out; + size_t iy, ix; + + w = w * 3; + + for(iy=t; iy= data_size) return false; //Check to protect against segmentation faults + if(data[i] != 0xFF) return false; //Check that we are truly at the start of another block + if(data[i+1] == 0xC0) { //0xFFC0 is the "Start of frame" marker which contains the file size + //The structure of the 0xFFC0 block is quite simple [0xFFC0][ushort length][uchar precision][ushort x][ushort y] + *height = data[i+5]*256 + data[i+6]; + *width = data[i+7]*256 + data[i+8]; + return true; + } + else + { + i+=2; //Skip the block marker + block_length = data[i] * 256 + data[i+1]; //Go to the next block + } + } + return false; //If this point is reached then no size was found + }else{ return false; } //Not a valid JFIF string + + }else{ return false; } //Not a valid SOI header +} + +#endif // JPEG_PICTS +#endif //ESP32 diff --git a/tasmota/support_json.ino b/tasmota/support_json.ino new file mode 100644 index 000000000..b78c68eab --- /dev/null +++ b/tasmota/support_json.ino @@ -0,0 +1,115 @@ +/* + support_json.ino - JSON support functions + + Copyright (C) 2020 Theo Arends and Stephan Hadinger + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/*********************************************************************************************\ + * JSON parsing +\*********************************************************************************************/ + +// does the character needs to be escaped, and if so with which character +char EscapeJSONChar(char c) { + if ((c == '\"') || (c == '\\')) { + return c; + } + if (c == '\n') { return 'n'; } + if (c == '\t') { return 't'; } + if (c == '\r') { return 'r'; } + if (c == '\f') { return 'f'; } + if (c == '\b') { return 'b'; } + return 0; +} + +String EscapeJSONString(const char *str) { + // As this function is used in ResponseCmndChar() and ResponseCmndIdxChar() + // it needs to be PROGMEM safe! + String r(""); + if (nullptr == str) { return r; } + + bool needs_escape = false; + size_t len_out = 1; + const char* c = str; + char ch = '.'; + while (ch != '\0') { + ch = pgm_read_byte(c++); + if (EscapeJSONChar(ch)) { + len_out++; + needs_escape = true; + } + len_out++; + } + + if (needs_escape) { + // we need to escape some chars + // allocate target buffer + r.reserve(len_out); + c = str; + char *d = r.begin(); + char ch = '.'; + while (ch != '\0') { + ch = pgm_read_byte(c++); + char c2 = EscapeJSONChar(ch); + if (c2) { + *d++ = '\\'; + *d++ = c2; + } else { + *d++ = ch; + } + } + *d = 0; // add NULL terminator + r = (char*) r.begin(); // assign the buffer to the string + } else { + r = FPSTR(str); + } + + return r; +} + +/*********************************************************************************************\ + * Find key - case insensitive +\*********************************************************************************************/ + +// Given a JsonObject, finds the value as JsonVariant for the key needle. +// The search is case-insensitive, and will find the first match in the order of keys in JSON +// +// If the key is not found, returns a nullptr +// Input: needle cannot be NULL but may be PROGMEM +const JsonVariant &GetCaseInsensitive(const JsonObject &json, const char *needle) { + // key can be in PROGMEM + // if needle == "?" then we return the first valid key + bool wildcard = strcmp_P("?", needle) == 0; + if ((nullptr == &json) || (nullptr == needle) || (0 == pgm_read_byte(needle)) || (!json.success())) { + return *(JsonVariant*)nullptr; + } + + for (JsonObject::const_iterator it=json.begin(); it!=json.end(); ++it) { + const char *key = it->key; + const JsonVariant &value = it->value; + + if (wildcard || (0 == strcasecmp_P(key, needle))) { + return value; + } + } + // if not found + return *(JsonVariant*)nullptr; +} + +// This function returns true if the JsonObject contains the specified key +// It's just a wrapper to the previous function but it can be tricky to test nullptr on an object ref +bool HasKeyCaseInsensitive(const JsonObject &json, const char *needle) { + return &GetCaseInsensitive(json, needle) != nullptr; +} diff --git a/tasmota/support_network.ino b/tasmota/support_network.ino new file mode 100644 index 000000000..4f6da4d88 --- /dev/null +++ b/tasmota/support_network.ino @@ -0,0 +1,128 @@ +/* + support_network.ino - Network support for Tasmota + + Copyright (C) 2020 Theo Arends + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/*********************************************************************************************\ + * MDNS +\*********************************************************************************************/ + +struct { + uint8_t begun = 0; // mDNS active +} Mdns; + +#ifdef USE_DISCOVERY +void StartMdns(void) { + if (Settings.flag3.mdns_enabled) { // SetOption55 - Control mDNS service + if (!Mdns.begun) { +// if (mdns_delayed_start) { +// AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS D_ATTEMPTING_CONNECTION)); +// mdns_delayed_start--; +// } else { +// mdns_delayed_start = Settings.param[P_MDNS_DELAYED_START]; + Mdns.begun = (uint8_t)MDNS.begin(my_hostname); + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS "%s"), (Mdns.begun) ? D_INITIALIZED : D_FAILED); +// } + } + } +} + +#ifdef MQTT_HOST_DISCOVERY +void MqttDiscoverServer(void) +{ + if (!Mdns.begun) { return; } + + int n = MDNS.queryService("mqtt", "tcp"); // Search for mqtt service + + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS D_QUERY_DONE " %d"), n); + + if (n > 0) { + uint32_t i = 0; // If the hostname isn't set, use the first record found. +#ifdef MDNS_HOSTNAME + for (i = n; i > 0; i--) { // Search from last to first and use first if not found + if (!strcmp(MDNS.hostname(i).c_str(), MDNS_HOSTNAME)) { + break; // Stop at matching record + } + } +#endif // MDNS_HOSTNAME + SettingsUpdateText(SET_MQTT_HOST, MDNS.IP(i).toString().c_str()); + Settings.mqtt_port = MDNS.port(i); + + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS D_MQTT_SERVICE_FOUND " %s, " D_IP_ADDRESS " %s, " D_PORT " %d"), MDNS.hostname(i).c_str(), SettingsText(SET_MQTT_HOST), Settings.mqtt_port); + } +} +#endif // MQTT_HOST_DISCOVERY + +#ifdef WEBSERVER_ADVERTISE +void MdnsAddServiceHttp(void) { + if (1 == Mdns.begun) { + Mdns.begun = 2; + MDNS.addService("http", "tcp", WEB_PORT); + } +} + +void MdnsUpdate(void) { + if (2 == Mdns.begun) { + MDNS.update(); + AddLog_P(LOG_LEVEL_DEBUG_MORE, D_LOG_MDNS, "MDNS.update"); + } +} +#endif // WEBSERVER_ADVERTISE +#endif // USE_DISCOVERY + +/*********************************************************************************************\ + * Global network parameters +\*********************************************************************************************/ + +char* NetworkHostname(void) { + if (global_state.eth_down) { + return my_hostname; + } +#ifdef ESP32 +#ifdef USE_ETHERNET + else { + return EthernetHostname(); + } +#endif +#endif +} + +IPAddress NetworkAddress(void) { + if (global_state.eth_down) { + return WiFi.localIP(); + } +#ifdef ESP32 +#ifdef USE_ETHERNET + else { + return EthernetLocalIP(); + } +#endif +#endif +} + +String NetworkMacAddress(void) { + if (global_state.eth_down) { + return WiFi.macAddress(); + } +#ifdef ESP32 +#ifdef USE_ETHERNET + else { + return EthernetMacAddress(); + } +#endif +#endif +} diff --git a/tasmota/support_rotary.ino b/tasmota/support_rotary.ino index 071b15b92..cfe549a5f 100644 --- a/tasmota/support_rotary.ino +++ b/tasmota/support_rotary.ino @@ -17,85 +17,229 @@ along with this program. If not, see . */ -#ifdef USE_LIGHT -//#define ROTARY_V1 #ifdef ROTARY_V1 /*********************************************************************************************\ * Rotary support + * + * Supports full range in 10 steps of the Rotary Encoder: + * - Light Dimmer + * - Light Color for RGB lights when Button1 pressed + * - Light Color Temperature for CW lights when Button1 pressed + * + * _______ _______ + * GPIO_ROT1A ______| |_______| |______ GPIO_ROT1A + * negative <-- _______ _______ __ --> positive + * GPIO_ROT1B __| |_______| |_______| GPIO_ROT1B + * \*********************************************************************************************/ +#ifndef ROTARY_MAX_STEPS +#define ROTARY_MAX_STEPS 10 // Rotary step boundary +#endif + +//#define ROTARY_OPTION1 // Up to 4 interrupts and pulses per step +//#define ROTARY_OPTION2 // Up to 4 interrupts but 1 pulse per step +#define ROTARY_OPTION3 // 1 interrupt and pulse per step + +#ifdef ROTARY_OPTION1 +// up to 4 pulses per step +const uint8_t rotary_dimmer_increment = 100 / (ROTARY_MAX_STEPS * 3); // Dimmer 1..100 = 100 +const uint8_t rotary_ct_increment = 350 / (ROTARY_MAX_STEPS * 3); // Ct 153..500 = 347 +const uint8_t rotary_color_increment = 360 / (ROTARY_MAX_STEPS * 3); // Hue 0..359 = 360 +#endif // ROTARY_OPTION1 + +#ifdef ROTARY_OPTION2 +// 1 pulse per step +const uint8_t rotary_dimmer_increment = 100 / ROTARY_MAX_STEPS; // Dimmer 1..100 = 100 +const uint8_t rotary_ct_increment = 350 / ROTARY_MAX_STEPS; // Ct 153..500 = 347 +const uint8_t rotary_color_increment = 360 / ROTARY_MAX_STEPS; // Hue 0..359 = 360 +#endif // ROTARY_OPTION2 + +#ifdef ROTARY_OPTION3 +// 1 pulse per step +const uint8_t rotary_dimmer_increment = 100 / ROTARY_MAX_STEPS; // Dimmer 1..100 = 100 +const uint8_t rotary_ct_increment = 350 / ROTARY_MAX_STEPS; // Ct 153..500 = 347 +const uint8_t rotary_color_increment = 360 / ROTARY_MAX_STEPS; // Hue 0..359 = 360 +#endif // ROTARY_OPTION3 + +const uint8_t ROTARY_TIMEOUT = 10; // 10 * RotaryHandler() call which is usually 10 * 0.05 seconds + struct ROTARY { - unsigned long debounce = 0; // Rotary debounce timer - uint8_t present = 0; +#ifdef ROTARY_OPTION1 uint8_t state = 0; +#endif // ROTARY_OPTION1 +#ifdef ROTARY_OPTION2 + uint16_t store; + uint8_t prev_next_code; +#endif // ROTARY_OPTION2 +#ifdef ROTARY_OPTION3 + uint32_t debounce = 0; +#endif // ROTARY_OPTION3 + int8_t abs_position1 = 0; + int8_t abs_position2 = 0; + int8_t direction = 0; // Control consistent direction + uint8_t present = 0; uint8_t position = 128; uint8_t last_position = 128; - uint8_t interrupts_in_use_count = 0; - uint8_t changed = 0; + uint8_t timeout = 0; // Disallow direction change within 0.5 second + bool changed = false; + bool busy = false; } Rotary; /********************************************************************************************/ -#ifndef ARDUINO_ESP8266_RELEASE_2_3_0 // Fix core 2.5.x ISR not in IRAM Exception void update_rotary(void) ICACHE_RAM_ATTR; -#endif // ARDUINO_ESP8266_RELEASE_2_3_0 +void update_rotary(void) { + if (Rotary.busy) { return; } + bool powered_on = (power); +#ifdef USE_LIGHT + if (!Settings.flag4.rotary_uses_rules) { // SetOption98 - Use rules instead of light control + powered_on = (LightPowerIRAM()); + } +#endif // USE_LIGHT + if (!powered_on) { return; } -void update_rotary(void) -{ - if (MI_DESK_LAMP == my_module_type) { - if (LightPowerIRAM()) { - /* - * https://github.com/PaulStoffregen/Encoder/blob/master/Encoder.h - */ +#ifdef ROTARY_OPTION1 + // https://github.com/PaulStoffregen/Encoder/blob/master/Encoder.h +/* + uint8_t p1val = digitalRead(Pin(GPIO_ROT1A)); + uint8_t p2val = digitalRead(Pin(GPIO_ROT1B)); + uint8_t state = Rotary.state & 3; + if (p1val) { state |= 4; } + if (p2val) { state |= 8; } + Rotary.state = (state >> 2); + switch (state) { + case 1: case 7: case 8: case 14: + Rotary.position++; + return; + case 2: case 4: case 11: case 13: + Rotary.position--; + return; + case 3: case 12: + Rotary.position += 2; + return; + case 6: case 9: + Rotary.position -= 2; + return; + } +*/ + uint8_t p1val = digitalRead(Pin(GPIO_ROT1A)); + uint8_t p2val = digitalRead(Pin(GPIO_ROT1B)); + uint8_t state = Rotary.state & 3; + if (p1val) { state |= 4; } + if (p2val) { state |= 8; } + Rotary.state = (state >> 2); + int direction = 0; + int multiply = 1; + switch (state) { + case 3: case 12: + multiply = 2; + case 1: case 7: case 8: case 14: + direction = 1; + break; + case 6: case 9: + multiply = 2; + case 2: case 4: case 11: case 13: + direction = -1; + break; + } + if ((0 == Rotary.direction) || (direction == Rotary.direction)) { + Rotary.position += (direction * multiply); + Rotary.direction = direction; + } +#endif // ROTARY_OPTION1 - uint8_t s = Rotary.state & 3; - if (digitalRead(pin[GPIO_ROT1A])) { s |= 4; } - if (digitalRead(pin[GPIO_ROT1B])) { s |= 8; } - switch (s) { - case 0: case 5: case 10: case 15: - break; - case 1: case 7: case 8: case 14: - Rotary.position++; break; - case 2: case 4: case 11: case 13: - Rotary.position--; break; - case 3: case 12: - Rotary.position = Rotary.position + 2; break; - default: - Rotary.position = Rotary.position - 2; break; - } - Rotary.state = (s >> 2); +#ifdef ROTARY_OPTION2 + // https://github.com/FrankBoesing/EncoderBounce/blob/master/EncoderBounce.h +/* + const uint16_t rot_enc = 0b0110100110010110; + + uint8_t p1val = digitalRead(Pin(GPIO_ROT1B)); + uint8_t p2val = digitalRead(Pin(GPIO_ROT1A)); + uint8_t t = Rotary.prev_next_code; + t <<= 2; + if (p1val) { t |= 0x02; } + if (p2val) { t |= 0x01; } + t &= 0x0f; + Rotary.prev_next_code = t; + + // If valid then store as 16 bit data. + if (rot_enc & (1 << t)) { + Rotary.store = (Rotary.store << 4) | Rotary.prev_next_code; + if (Rotary.store == 0xd42b) { Rotary.position++; } + else if (Rotary.store == 0xe817) { Rotary.position--; } + else if ((Rotary.store & 0xff) == 0x2b) { Rotary.position--; } + else if ((Rotary.store & 0xff) == 0x17) { Rotary.position++; } + } +*/ + const uint16_t rot_enc = 0b0110100110010110; + + uint8_t p1val = digitalRead(Pin(GPIO_ROT1B)); + uint8_t p2val = digitalRead(Pin(GPIO_ROT1A)); + uint8_t t = Rotary.prev_next_code; + t <<= 2; + if (p1val) { t |= 0x02; } + if (p2val) { t |= 0x01; } + t &= 0x0f; + Rotary.prev_next_code = t; + + // If valid then store as 16 bit data. + if (rot_enc & (1 << t)) { + Rotary.store = (Rotary.store << 4) | Rotary.prev_next_code; + int direction = 0; + if (Rotary.store == 0xd42b) { direction = 1; } + else if (Rotary.store == 0xe817) { direction = -1; } + else if ((Rotary.store & 0xff) == 0x2b) { direction = -1; } + else if ((Rotary.store & 0xff) == 0x17) { direction = 1; } + if ((0 == Rotary.direction) || (direction == Rotary.direction)) { + Rotary.position += direction; + Rotary.direction = direction; } } +#endif // ROTARY_OPTION2 + +#ifdef ROTARY_OPTION3 + // Theo Arends + uint32_t time = micros(); + if (Rotary.debounce < time) { + int direction = (digitalRead(Pin(GPIO_ROT1B))) ? 1 : -1; + if ((0 == Rotary.direction) || (direction == Rotary.direction)) { + Rotary.position += direction; + Rotary.direction = direction; + } + Rotary.debounce = time +20; // Experimental debounce + } +#endif // ROTARY_OPTION3 } -bool RotaryButtonPressed(void) -{ - if ((MI_DESK_LAMP == my_module_type) && (Rotary.changed) && LightPower()) { - Rotary.changed = 0; // Color temp changed, no need to turn of the light +bool RotaryButtonPressed(void) { + if (!Rotary.present) { return false; } + + bool powered_on = (power); +#ifdef USE_LIGHT + if (!Settings.flag4.rotary_uses_rules) { // SetOption98 - Use rules instead of light control + powered_on = LightPower(); + } +#endif // USE_LIGHT + if (Rotary.changed && powered_on) { + Rotary.changed = false; // Color (temp) changed, no need to turn of the light return true; } return false; } -void RotaryInit(void) -{ +void RotaryInit(void) { Rotary.present = 0; - if ((pin[GPIO_ROT1A] < 99) && (pin[GPIO_ROT1B] < 99)) { + if (PinUsed(GPIO_ROT1A) && PinUsed(GPIO_ROT1B)) { Rotary.present++; - pinMode(pin[GPIO_ROT1A], INPUT_PULLUP); - pinMode(pin[GPIO_ROT1B], INPUT_PULLUP); - - // GPIO6-GPIO11 are typically used to interface with the flash memory IC on - // most esp8266 modules, so we should avoid adding interrupts to these pins. - - if ((pin[GPIO_ROT1A] < 6) || (pin[GPIO_ROT1A] > 11)) { - attachInterrupt(digitalPinToInterrupt(pin[GPIO_ROT1A]), update_rotary, CHANGE); - Rotary.interrupts_in_use_count++; - } - if ((pin[GPIO_ROT1B] < 6) || (pin[GPIO_ROT1B] > 11)) { - attachInterrupt(digitalPinToInterrupt(pin[GPIO_ROT1B]), update_rotary, CHANGE); - Rotary.interrupts_in_use_count++; - } + pinMode(Pin(GPIO_ROT1A), INPUT_PULLUP); + pinMode(Pin(GPIO_ROT1B), INPUT_PULLUP); +#ifdef ROTARY_OPTION3 + attachInterrupt(Pin(GPIO_ROT1A), update_rotary, RISING); +#else + attachInterrupt(Pin(GPIO_ROT1A), update_rotary, CHANGE); + attachInterrupt(Pin(GPIO_ROT1B), update_rotary, CHANGE); +#endif } } @@ -103,59 +247,59 @@ void RotaryInit(void) * Rotary handler \*********************************************************************************************/ -void RotaryHandler(void) -{ - if (Rotary.interrupts_in_use_count < 2) { - noInterrupts(); - update_rotary(); - } else { - noInterrupts(); - } - if (Rotary.last_position != Rotary.position) { - if (MI_DESK_LAMP == my_module_type) { // Mi Desk lamp - if (Button.hold_timer[0]) { - Rotary.changed = 1; - // button1 is pressed: set color temperature - int16_t t = LightGetColorTemp(); - t = t + (Rotary.position - Rotary.last_position); - if (t < 153) { - t = 153; - } - if (t > 500) { - t = 500; - } - DEBUG_CORE_LOG(PSTR("ROT: " D_CMND_COLORTEMPERATURE " %d"), Rotary.position - Rotary.last_position); - LightSetColorTemp((uint16_t)t); - } else { - int8_t d = Settings.light_dimmer; - d = d + (Rotary.position - Rotary.last_position); - if (d < 1) { - d = 1; - } - if (d > 100) { - d = 100; - } - DEBUG_CORE_LOG(PSTR("ROT: " D_CMND_DIMMER " %d"), Rotary.position - Rotary.last_position); +void RotaryHandler(void) { + if (!Rotary.present) { return; } - LightSetDimmer((uint8_t)d); - Settings.light_dimmer = d; + if (Rotary.timeout) { + Rotary.timeout--; + if (!Rotary.timeout) { + Rotary.direction = 0; + } + } + if (Rotary.last_position == Rotary.position) { return; } + Rotary.busy = true; + + Rotary.timeout = ROTARY_TIMEOUT; // Prevent fast direction changes within 0.5 second + + int rotary_position = Rotary.position - Rotary.last_position; + + if (Settings.save_data && (save_data_counter < 2)) { + save_data_counter = 2; // Postpone flash writes while rotary is turned + } + + bool button_pressed = (Button.hold_timer[0]); // Button1 is pressed: set color temperature + if (button_pressed) { Rotary.changed = true; } +// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ROT: Button1 %d, Position %d"), button_pressed, rotary_position); + +#ifdef USE_LIGHT + if (!Settings.flag4.rotary_uses_rules) { // SetOption98 - Use rules instead of light control + if (button_pressed) { + if (!LightColorTempOffset(rotary_position * rotary_ct_increment)) { + LightColorOffset(rotary_position * rotary_color_increment); } + } else { + LightDimmerOffset(rotary_position * rotary_dimmer_increment); } - Rotary.last_position = 128; - Rotary.position = 128; + } else { +#endif // USE_LIGHT + if (button_pressed) { + Rotary.abs_position2 += rotary_position; + if (Rotary.abs_position2 < 0) { Rotary.abs_position2 = 0; } + if (Rotary.abs_position2 > ROTARY_MAX_STEPS) { Rotary.abs_position2 = ROTARY_MAX_STEPS; } + } else { + Rotary.abs_position1 += rotary_position; + if (Rotary.abs_position1 < 0) { Rotary.abs_position1 = 0; } + if (Rotary.abs_position1 > ROTARY_MAX_STEPS) { Rotary.abs_position1 = ROTARY_MAX_STEPS; } + } + Response_P(PSTR("{\"Rotary1\":{\"Pos1\":%d,\"Pos2\":%d}}"), Rotary.abs_position1, Rotary.abs_position2); + XdrvRulesProcess(); +#ifdef USE_LIGHT } - interrupts(); -} +#endif // USE_LIGHT -void RotaryLoop(void) -{ - if (Rotary.present) { - if (TimeReached(Rotary.debounce)) { - SetNextTimeInterval(Rotary.debounce, Settings.button_debounce); // Using button_debounce setting for this as well - RotaryHandler(); - } - } + Rotary.last_position = 128; + Rotary.position = 128; + Rotary.busy = false; } #endif // ROTARY_V1 -#endif // USE_LIGHT diff --git a/tasmota/support_rtc.ino b/tasmota/support_rtc.ino index 3b7da8e37..25ad82435 100644 --- a/tasmota/support_rtc.ino +++ b/tasmota/support_rtc.ino @@ -47,6 +47,8 @@ struct RTC { uint32_t ntp_time = 0; uint32_t midnight = 0; uint32_t restart_time = 0; + uint32_t millis = 0; + uint32_t last_sync = 0; int32_t time_timezone = 0; uint8_t ntp_sync_minute = 0; bool midnight_now = false; @@ -204,6 +206,14 @@ String GetDateAndTime(uint8_t time_type) break; } String dt = GetDT(time); // 2017-03-07T11:08:02 + + if (DT_LOCAL_MILLIS == time_type) { + char ms[10]; + snprintf_P(ms, sizeof(ms), PSTR(".%03d"), RtcMillis()); + dt += ms; + time_type = DT_LOCAL; + } + if (Settings.flag3.time_append_timezone && (DT_LOCAL == time_type)) { // SetOption52 - Append timezone to JSON time dt += GetTimeZone(); // 2017-03-07T11:08:02-07:00 } @@ -239,6 +249,10 @@ uint32_t MinutesPastMidnight(void) return minutes; } +uint32_t RtcMillis(void) { + return (millis() - Rtc.millis) % 1000; +} + void BreakTime(uint32_t time_input, TIME_T &tm) { // break the given time_input into time components @@ -362,40 +376,50 @@ void RtcSecond(void) { TIME_T tmpTime; - if (!Rtc.user_time_entry && !global_state.wifi_down) { - uint8_t uptime_minute = (uptime / 60) % 60; // 0 .. 59 - if ((Rtc.ntp_sync_minute > 59) && (uptime_minute > 2)) { - Rtc.ntp_sync_minute = 1; // If sync prepare for a new cycle - } - uint8_t offset = (uptime < 30) ? RtcTime.second : (((ESP.getChipId() & 0xF) * 3) + 3) ; // First try ASAP to sync. If fails try once every 60 seconds based on chip id - if ( (((offset == RtcTime.second) && ( (RtcTime.year < 2016) || // Never synced - (Rtc.ntp_sync_minute == uptime_minute))) || // Re-sync every hour - ntp_force_sync ) ) { // Forced sync - Rtc.ntp_time = sntp_get_current_timestamp(); - if (Rtc.ntp_time > START_VALID_TIME) { // Fix NTP bug in core 2.4.1/SDK 2.2.1 (returns Thu Jan 01 08:00:10 1970 after power on) - ntp_force_sync = false; - Rtc.utc_time = Rtc.ntp_time; - Rtc.ntp_sync_minute = 60; // Sync so block further requests - if (Rtc.restart_time == 0) { - Rtc.restart_time = Rtc.utc_time - uptime; // save first ntp time as restart time - } - BreakTime(Rtc.utc_time, tmpTime); - RtcTime.year = tmpTime.year + 1970; - Rtc.daylight_saving_time = RuleToTime(Settings.tflag[1], RtcTime.year); - Rtc.standard_time = RuleToTime(Settings.tflag[0], RtcTime.year); + Rtc.millis = millis(); - // Do not use AddLog_P2 here (interrupt routine) if syslog or mqttlog is enabled. UDP/TCP will force exception 9 - PrepLog_P2(LOG_LEVEL_DEBUG, PSTR("NTP: " D_UTC_TIME " %s, " D_DST_TIME " %s, " D_STD_TIME " %s"), - GetDateAndTime(DT_UTC).c_str(), GetDateAndTime(DT_DST).c_str(), GetDateAndTime(DT_STD).c_str()); - - if (Rtc.local_time < START_VALID_TIME) { // 2016-01-01 - rules_flag.time_init = 1; - } else { - rules_flag.time_set = 1; - } - } else { - Rtc.ntp_sync_minute++; // Try again in next minute + if (!Rtc.user_time_entry) { + if (!global_state.network_down) { + uint8_t uptime_minute = (uptime / 60) % 60; // 0 .. 59 + if ((Rtc.ntp_sync_minute > 59) && (uptime_minute > 2)) { + Rtc.ntp_sync_minute = 1; // If sync prepare for a new cycle } + uint8_t offset = (uptime < 30) ? RtcTime.second : (((ESP_getChipId() & 0xF) * 3) + 3) ; // First try ASAP to sync. If fails try once every 60 seconds based on chip id + if ( (((offset == RtcTime.second) && ( (RtcTime.year < 2016) || // Never synced + (Rtc.ntp_sync_minute == uptime_minute))) || // Re-sync every hour + ntp_force_sync ) ) { // Forced sync + Rtc.ntp_time = sntp_get_current_timestamp(); + if (Rtc.ntp_time > START_VALID_TIME) { // Fix NTP bug in core 2.4.1/SDK 2.2.1 (returns Thu Jan 01 08:00:10 1970 after power on) + ntp_force_sync = false; + Rtc.utc_time = Rtc.ntp_time; + Rtc.last_sync = Rtc.ntp_time; + Rtc.ntp_sync_minute = 60; // Sync so block further requests + if (Rtc.restart_time == 0) { + Rtc.restart_time = Rtc.utc_time - uptime; // save first ntp time as restart time + } + BreakTime(Rtc.utc_time, tmpTime); + RtcTime.year = tmpTime.year + 1970; + Rtc.daylight_saving_time = RuleToTime(Settings.tflag[1], RtcTime.year); + Rtc.standard_time = RuleToTime(Settings.tflag[0], RtcTime.year); + + // Do not use AddLog_P2 here (interrupt routine) if syslog or mqttlog is enabled. UDP/TCP will force exception 9 + PrepLog_P2(LOG_LEVEL_DEBUG, PSTR("NTP: " D_UTC_TIME " %s, " D_DST_TIME " %s, " D_STD_TIME " %s"), + GetDateAndTime(DT_UTC).c_str(), GetDateAndTime(DT_DST).c_str(), GetDateAndTime(DT_STD).c_str()); + + if (Rtc.local_time < START_VALID_TIME) { // 2016-01-01 + rules_flag.time_init = 1; + } else { + rules_flag.time_set = 1; + } + } else { + Rtc.ntp_sync_minute++; // Try again in next minute + } + } + } + if ((Rtc.utc_time > (2 * 60 * 60)) && (Rtc.last_sync < Rtc.utc_time - (2 * 60 * 60))) { // Every two hours a warning + // Do not use AddLog_P2 here (interrupt routine) if syslog or mqttlog is enabled. UDP/TCP will force exception 9 + PrepLog_P2(LOG_LEVEL_DEBUG, PSTR("NTP: Not synced")); + Rtc.last_sync = Rtc.utc_time; } } @@ -459,7 +483,6 @@ void RtcSetTime(uint32_t epoch) Rtc.user_time_entry = true; Rtc.utc_time = epoch -1; // Will be corrected by RtcSecond } - RtcSecond(); } void RtcInit(void) diff --git a/tasmota/support_switch.ino b/tasmota/support_switch.ino index f1d5c7ea2..9fc3b57c3 100644 --- a/tasmota/support_switch.ino +++ b/tasmota/support_switch.ino @@ -26,6 +26,8 @@ \*********************************************************************************************/ const uint8_t SWITCH_PROBE_INTERVAL = 10; // Time in milliseconds between switch input probe +const uint8_t SWITCH_FAST_PROBE_INTERVAL =2;// Time in milliseconds between switch input probe for AC detection +const uint8_t AC_PERIOD = (20 + SWITCH_FAST_PROBE_INTERVAL - 1) / SWITCH_FAST_PROBE_INTERVAL; // Duration of an AC wave in probe intervals #include @@ -38,6 +40,7 @@ struct SWITCH { uint8_t last_state[MAX_SWITCHES]; // Last wall switch states uint8_t hold_timer[MAX_SWITCHES] = { 0 }; // Timer for wallswitch push button hold uint8_t virtual_state[MAX_SWITCHES]; // Virtual switch states + uint8_t first_change = 0; uint8_t present = 0; } Switch; @@ -81,60 +84,136 @@ void SwitchProbe(void) { if (uptime < 4) { return; } // Block GPIO for 4 seconds after poweron to workaround Wemos D1 / Obi RTS circuit - uint8_t state_filter = Settings.switch_debounce / SWITCH_PROBE_INTERVAL; // 5, 10, 15 - uint8_t force_high = (Settings.switch_debounce % 50) &1; // 51, 101, 151 etc - uint8_t force_low = (Settings.switch_debounce % 50) &2; // 52, 102, 152 etc + uint8_t state_filter; + uint8_t debounce_flags = Settings.switch_debounce % 10; + uint8_t force_high = debounce_flags &1; // 51, 101, 151 etc + uint8_t force_low = debounce_flags &2; // 52, 102, 152 etc + uint8_t ac_detect = debounce_flags == 9; + uint8_t switch_probe_interval; + uint8_t first_change = Switch.first_change; + + if (ac_detect) { + switch_probe_interval = SWITCH_FAST_PROBE_INTERVAL; + if (Settings.switch_debounce < 2 * AC_PERIOD * SWITCH_FAST_PROBE_INTERVAL + 9) { + state_filter = 2 * AC_PERIOD; + } else if (Settings.switch_debounce > (0x7f - 2 * AC_PERIOD) * SWITCH_FAST_PROBE_INTERVAL) { + state_filter = 0x7f; + } else { + state_filter = (Settings.switch_debounce - 9) / SWITCH_FAST_PROBE_INTERVAL; + } + } else { + switch_probe_interval = SWITCH_PROBE_INTERVAL; + state_filter = Settings.switch_debounce / SWITCH_PROBE_INTERVAL; // 5, 10, 15 + } for (uint32_t i = 0; i < MAX_SWITCHES; i++) { - if (pin[GPIO_SWT1 +i] < 99) { + if (PinUsed(GPIO_SWT1, i)) { // Olimex user_switch2.c code to fix 50Hz induced pulses - if (1 == digitalRead(pin[GPIO_SWT1 +i])) { + if (1 == digitalRead(Pin(GPIO_SWT1, i))) { - if (force_high) { // Enabled with SwitchDebounce x1 - if (1 == Switch.virtual_state[i]) { - Switch.state[i] = state_filter; // With noisy input keep current state 1 unless constant 0 + if (ac_detect) { // Enabled with SwitchDebounce x9 + Switch.state[i] |= 0x80; + if (Switch.state[i] > 0x80) { + Switch.state[i]--; + if (0x80 == Switch.state[i]) { + Switch.virtual_state[i] = 0; + Switch.first_change = false; + } } - } + } else { - if (Switch.state[i] < state_filter) { - Switch.state[i]++; - if (state_filter == Switch.state[i]) { - Switch.virtual_state[i] = 1; + if (force_high) { // Enabled with SwitchDebounce x1 + if (1 == Switch.virtual_state[i]) { + Switch.state[i] = state_filter; // With noisy input keep current state 1 unless constant 0 + } + } + + if (Switch.state[i] < state_filter) { + Switch.state[i]++; + if (state_filter == Switch.state[i]) { + Switch.virtual_state[i] = 1; + } } } } else { - if (force_low) { // Enabled with SwitchDebounce x2 - if (0 == Switch.virtual_state[i]) { - Switch.state[i] = 0; // With noisy input keep current state 0 unless constant 1 + if (ac_detect) { // Enabled with SwitchDebounce x9 + /* + * Moes MS-104B and similar devices using an AC detection circuitry + * on their switch inputs generating an ~4 ms long low pulse every + * AC wave. We start the time measurement on the falling edge. + * + * state: bit7: previous state, bit6..0: counter + */ + if (Switch.state[i] & 0x80) { + Switch.state[i] &= 0x7f; + if (Switch.state[i] < state_filter - 2 * AC_PERIOD) { + Switch.state[i] += 2 * AC_PERIOD; + } else { + Switch.state[i] = state_filter; + Switch.virtual_state[i] = 1; + if (first_change) { + Switch.last_state[i] = 1; + Switch.first_change = false; + } + } + } else { + if (Switch.state[i] > 0x00) { + Switch.state[i]--; + if (0x00 == Switch.state[i]) { + Switch.virtual_state[i] = 0; + Switch.first_change = false; + } + } } - } + } else { - if (Switch.state[i] > 0) { - Switch.state[i]--; - if (0 == Switch.state[i]) { - Switch.virtual_state[i] = 0; + if (force_low) { // Enabled with SwitchDebounce x2 + if (0 == Switch.virtual_state[i]) { + Switch.state[i] = 0; // With noisy input keep current state 0 unless constant 1 + } + } + + if (Switch.state[i] > 0) { + Switch.state[i]--; + if (0 == Switch.state[i]) { + Switch.virtual_state[i] = 0; + } } } } } } - TickerSwitch.attach_ms(SWITCH_PROBE_INTERVAL, SwitchProbe); // Re-arm as core 2.3.0 does only support ONCE mode + TickerSwitch.attach_ms(switch_probe_interval, SwitchProbe); // Re-arm as core 2.3.0 does only support ONCE mode } void SwitchInit(void) { + uint8_t ac_detect = Settings.switch_debounce % 10 == 9; + Switch.present = 0; for (uint32_t i = 0; i < MAX_SWITCHES; i++) { Switch.last_state[i] = 1; // Init global to virtual switch state; - if (pin[GPIO_SWT1 +i] < 99) { + if (PinUsed(GPIO_SWT1, i)) { Switch.present++; - pinMode(pin[GPIO_SWT1 +i], bitRead(Switch.no_pullup_mask, i) ? INPUT : ((16 == pin[GPIO_SWT1 +i]) ? INPUT_PULLDOWN_16 : INPUT_PULLUP)); - Switch.last_state[i] = digitalRead(pin[GPIO_SWT1 +i]); // Set global now so doesn't change the saved power state on first switch check + pinMode(Pin(GPIO_SWT1, i), bitRead(Switch.no_pullup_mask, i) ? INPUT : ((16 == Pin(GPIO_SWT1, i)) ? INPUT_PULLDOWN_16 : INPUT_PULLUP)); + if (ac_detect) { + Switch.state[i] = 0x80 + 2 * AC_PERIOD; + Switch.last_state[i] = 0; // Will set later in the debouncing code + } else { + Switch.last_state[i] = digitalRead(Pin(GPIO_SWT1, i)); // Set global now so doesn't change the saved power state on first switch check + } } Switch.virtual_state[i] = Switch.last_state[i]; } - if (Switch.present) { TickerSwitch.attach_ms(SWITCH_PROBE_INTERVAL, SwitchProbe); } + if (Switch.present) { + if (ac_detect) { + TickerSwitch.attach_ms(SWITCH_FAST_PROBE_INTERVAL, SwitchProbe); + Switch.first_change = true; + } else { + TickerSwitch.attach_ms(SWITCH_PROBE_INTERVAL, SwitchProbe); + } + } } /*********************************************************************************************\ @@ -148,14 +227,21 @@ void SwitchHandler(uint8_t mode) uint16_t loops_per_second = 1000 / Settings.switch_debounce; for (uint32_t i = 0; i < MAX_SWITCHES; i++) { - if ((pin[GPIO_SWT1 +i] < 99) || (mode)) { + if (PinUsed(GPIO_SWT1, i) || (mode)) { uint8_t button = Switch.virtual_state[i]; uint8_t switchflag = POWER_TOGGLE +1; if (Switch.hold_timer[i]) { Switch.hold_timer[i]--; + if (Switch.hold_timer[i] == loops_per_second * Settings.param[P_HOLD_TIME] / 25) { + if ((Settings.switchmode[i] == PUSHHOLDMULTI) & (NOT_PRESSED == Switch.last_state[i])) { + SendKey(KEY_SWITCH, i +1, POWER_INCREMENT); // Execute command via MQTT + } + if ((Settings.switchmode[i] == PUSHHOLDMULTI_INV) & (PRESSED == Switch.last_state[i])) { + SendKey(KEY_SWITCH, i +1, POWER_INCREMENT); // Execute command via MQTT + } + } if (0 == Switch.hold_timer[i]) { - switch (Settings.switchmode[i]) { case TOGGLEMULTI: switchflag = POWER_TOGGLE; // Toggle after hold @@ -202,51 +288,33 @@ void SwitchHandler(uint8_t mode) switchflag = ~button &1; // Follow inverted wall switch state break; case PUSHBUTTON: -// if ((PRESSED == button) && (NOT_PRESSED == Switch.last_state[i])) { if (PRESSED == button) { switchflag = POWER_TOGGLE; // Toggle with pushbutton to Gnd } break; case PUSHBUTTON_INV: -// if ((NOT_PRESSED == button) && (PRESSED == Switch.last_state[i])) { if (NOT_PRESSED == button) { switchflag = POWER_TOGGLE; // Toggle with releasing pushbutton from Gnd } break; case PUSHBUTTONHOLD: -// if ((PRESSED == button) && (NOT_PRESSED == Switch.last_state[i])) { if (PRESSED == button) { Switch.hold_timer[i] = loops_per_second * Settings.param[P_HOLD_TIME] / 10; // Start timer on button press } -// if ((NOT_PRESSED == button) && (PRESSED == Switch.last_state[i]) && (Switch.hold_timer[i])) { if ((NOT_PRESSED == button) && (Switch.hold_timer[i])) { Switch.hold_timer[i] = 0; // Button released and hold timer not expired : stop timer... switchflag = POWER_TOGGLE; // ...and Toggle } break; case PUSHBUTTONHOLD_INV: -// if ((NOT_PRESSED == button) && (PRESSED == Switch.last_state[i])) { if (NOT_PRESSED == button) { Switch.hold_timer[i] = loops_per_second * Settings.param[P_HOLD_TIME] / 10; // Start timer on button press... } -// if ((PRESSED == button) && (NOT_PRESSED == Switch.last_state[i]) && (Switch.hold_timer[i])) { if ((PRESSED == button) && (Switch.hold_timer[i])) { Switch.hold_timer[i] = 0; // Button released and hold timer not expired : stop timer. switchflag = POWER_TOGGLE; // ...and Toggle } break; -/* - // Reverted Fix switchmode 6 according to issue 7778 (#7831) - case PUSHBUTTONHOLD_INV: - if ((PRESSED == button) && (NOT_PRESSED == Switch.last_state[i])) { - Switch.hold_timer[i] = loops_per_second * Settings.param[P_HOLD_TIME] / 10; // Start timer on button press... - switchflag = POWER_TOGGLE; // ...and Toggle - } - if ((NOT_PRESSED == button) && (PRESSED == Switch.last_state[i])) { - Switch.hold_timer[i] = 0; // Button released : stop timer. - } - break; -*/ case TOGGLEMULTI: case FOLLOWMULTI: case FOLLOWMULTI_INV: @@ -258,36 +326,32 @@ void SwitchHandler(uint8_t mode) } break; case PUSHHOLDMULTI: -// if ((NOT_PRESSED == button) && (PRESSED == Switch.last_state[i])) { if (NOT_PRESSED == button) { if (Switch.hold_timer[i] != 0) { SendKey(KEY_SWITCH, i +1, POWER_INV); // Execute command via MQTT } - Switch.hold_timer[i] = loops_per_second * Settings.param[P_HOLD_TIME] / 10; - } -// if ((PRESSED == button) && (NOT_PRESSED == Switch.last_state[i])) { - if (PRESSED == button) { + } else { if (Switch.hold_timer[i] > loops_per_second * Settings.param[P_HOLD_TIME] / 25) { switchflag = POWER_TOGGLE; // Toggle with pushbutton + } else { + SendKey(KEY_SWITCH, i +1, POWER_RELEASE); // Execute command via MQTT } - Switch.hold_timer[i] = loops_per_second * Settings.param[P_HOLD_TIME] / 10; } + Switch.hold_timer[i] = loops_per_second * Settings.param[P_HOLD_TIME] / 10; break; case PUSHHOLDMULTI_INV: -// if ((PRESSED == button) && (NOT_PRESSED == Switch.last_state[i])) { if (PRESSED == button) { if (Switch.hold_timer[i] != 0) { SendKey(KEY_SWITCH, i +1, POWER_INV); // Execute command via MQTT } - Switch.hold_timer[i] = loops_per_second * Settings.param[P_HOLD_TIME] / 10; - } -// if ((NOT_PRESSED == button) && (PRESSED == Switch.last_state[i])) { - if (NOT_PRESSED == button) { + } else { if (Switch.hold_timer[i] > loops_per_second * Settings.param[P_HOLD_TIME] / 25) { switchflag = POWER_TOGGLE; // Toggle with pushbutton + } else { + SendKey(KEY_SWITCH, i +1, POWER_RELEASE); // Execute command via MQTT } - Switch.hold_timer[i] = loops_per_second * Settings.param[P_HOLD_TIME] / 10; } + Switch.hold_timer[i] = loops_per_second * Settings.param[P_HOLD_TIME] / 10; break; case PUSHON: if (PRESSED == button) { diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index 8144ea351..68edd6a7a 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -39,14 +39,17 @@ char* Format(char* output, const char* input, int size) char tmp[size]; if (strchr(token, 'd')) { snprintf_P(tmp, size, PSTR("%s%c0%dd"), output, '%', digits); - snprintf_P(output, size, tmp, ESP.getChipId() & 0x1fff); // %04d - short chip ID in dec, like in hostname + snprintf_P(output, size, tmp, ESP_getChipId() & 0x1fff); // %04d - short chip ID in dec, like in hostname } else { - snprintf_P(tmp, size, PSTR("%s%c0%dX"), output, '%', digits); - snprintf_P(output, size, tmp, ESP.getChipId()); // %06X - full chip ID in hex + String mac_address = WiFi.macAddress(); + mac_address.replace(":", ""); + if (digits > 12) { digits = 12; } + String mac_part = mac_address.substring(12 - digits); + snprintf_P(output, size, PSTR("%s%s"), output, mac_part.c_str()); // %01X .. %12X - mac address in hex } } else { if (strchr(token, 'd')) { - snprintf_P(output, size, PSTR("%s%d"), output, ESP.getChipId()); // %d - full chip ID in dec + snprintf_P(output, size, PSTR("%s%d"), output, ESP_getChipId()); // %d - full chip ID in dec digits = 8; } } @@ -61,10 +64,10 @@ char* Format(char* output, const char* input, int size) char* GetOtaUrl(char *otaurl, size_t otaurl_size) { if (strstr(SettingsText(SET_OTAURL), "%04d") != nullptr) { // OTA url contains placeholder for chip ID - snprintf(otaurl, otaurl_size, SettingsText(SET_OTAURL), ESP.getChipId() & 0x1fff); + snprintf(otaurl, otaurl_size, SettingsText(SET_OTAURL), ESP_getChipId() & 0x1fff); } else if (strstr(SettingsText(SET_OTAURL), "%d") != nullptr) { // OTA url contains placeholder for chip ID - snprintf_P(otaurl, otaurl_size, SettingsText(SET_OTAURL), ESP.getChipId()); + snprintf_P(otaurl, otaurl_size, SettingsText(SET_OTAURL), ESP_getChipId()); } else { strlcpy(otaurl, SettingsText(SET_OTAURL), otaurl_size); @@ -166,7 +169,7 @@ void SetLatchingRelay(power_t lpower, uint32_t state) for (uint32_t i = 0; i < devices_present; i++) { uint32_t port = (i << 1) + ((latching_power >> i) &1); - DigitalWrite(GPIO_REL1 +port, bitRead(rel_inverted, port) ? !state : state); + DigitalWrite(GPIO_REL1, port, bitRead(rel_inverted, port) ? !state : state); } } @@ -210,6 +213,7 @@ void SetDevicePower(power_t rpower, uint32_t source) if (XdrvCall(FUNC_SET_DEVICE_POWER)) { // Set power state and stop if serviced // Serviced } +#ifdef ESP8266 else if ((SONOFF_DUAL == my_module_type) || (CH4 == my_module_type)) { Serial.write(0xA0); Serial.write(0x04); @@ -221,11 +225,13 @@ void SetDevicePower(power_t rpower, uint32_t source) else if (EXS_RELAY == my_module_type) { SetLatchingRelay(rpower, 1); } - else { +#endif // ESP8266 + else + { for (uint32_t i = 0; i < devices_present; i++) { power_t state = rpower &1; if (i < MAX_RELAYS) { - DigitalWrite(GPIO_REL1 +i, bitRead(rel_inverted, i) ? !state : state); + DigitalWrite(GPIO_REL1, i, bitRead(rel_inverted, i) ? !state : state); } rpower >>= 1; } @@ -279,9 +285,11 @@ void SetAllPower(uint32_t state, uint32_t source) void SetPowerOnState(void) { +#ifdef ESP8266 if (MOTOR == my_module_type) { Settings.poweronstate = POWER_ALL_ON; // Needs always on else in limbo! } +#endif // ESP8266 if (POWER_ALL_ALWAYS_ON == Settings.poweronstate) { SetDevicePower(1, SRC_RESTART); } else { @@ -320,8 +328,8 @@ void SetPowerOnState(void) // Issue #526 and #909 for (uint32_t i = 0; i < devices_present; i++) { if (!Settings.flag3.no_power_feedback) { // SetOption63 - Don't scan relay power state at restart - #5594 and #5663 - if ((i < MAX_RELAYS) && (pin[GPIO_REL1 +i] < 99)) { - bitWrite(power, i, digitalRead(pin[GPIO_REL1 +i]) ^ bitRead(rel_inverted, i)); + if ((i < MAX_RELAYS) && PinUsed(GPIO_REL1, i)) { + bitWrite(power, i, digitalRead(Pin(GPIO_REL1, i)) ^ bitRead(rel_inverted, i)); } } if ((i < MAX_PULSETIMERS) && (bitRead(power, i) || (POWER_ALL_OFF_PULSETIME_ON == Settings.poweronstate))) { @@ -331,14 +339,21 @@ void SetPowerOnState(void) blink_powersave = power; } +void UpdateLedPowerAll() +{ + for (uint32_t i = 0; i < leds_present; i++) { + SetLedPowerIdx(i, bitRead(led_power, i)); + } +} + void SetLedPowerIdx(uint32_t led, uint32_t state) { - if ((99 == pin[GPIO_LEDLNK]) && (0 == led)) { // Legacy - LED1 is link led only if LED2 is present - if (pin[GPIO_LED2] < 99) { + if (!PinUsed(GPIO_LEDLNK) && (0 == led)) { // Legacy - LED1 is link led only if LED2 is present + if (PinUsed(GPIO_LED1, 1)) { led = 1; } } - if (pin[GPIO_LED1 + led] < 99) { + if (PinUsed(GPIO_LED1, led)) { uint32_t mask = 1 << led; if (state) { state = 1; @@ -346,7 +361,17 @@ void SetLedPowerIdx(uint32_t led, uint32_t state) } else { led_power &= (0xFF ^ mask); } - DigitalWrite(GPIO_LED1 + led, bitRead(led_inverted, led) ? !state : state); + uint16_t pwm = 0; + if (bitRead(Settings.ledpwm_mask, led)) { +#ifdef USE_LIGHT + pwm = changeUIntScale(ledGamma10(state ? Settings.ledpwm_on : Settings.ledpwm_off), 0, 1023, 0, Settings.pwm_range); // gamma corrected +#else //USE_LIGHT + pwm = changeUIntScale((uint16_t)(state ? Settings.ledpwm_on : Settings.ledpwm_off), 0, 255, 0, Settings.pwm_range); // linear +#endif //USE_LIGHT + analogWrite(Pin(GPIO_LED1, led), bitRead(led_inverted, led) ? Settings.pwm_range - pwm : pwm); + } else { + DigitalWrite(GPIO_LED1, led, bitRead(led_inverted, led) ? !state : state); + } } #ifdef USE_BUZZER if (led == 0) { @@ -357,7 +382,7 @@ void SetLedPowerIdx(uint32_t led, uint32_t state) void SetLedPower(uint32_t state) { - if (99 == pin[GPIO_LEDLNK]) { // Legacy - Only use LED1 and/or LED2 + if (!PinUsed(GPIO_LEDLNK)) { // Legacy - Only use LED1 and/or LED2 SetLedPowerIdx(0, state); } else { power_t mask = 1; @@ -378,13 +403,12 @@ void SetLedPowerAll(uint32_t state) void SetLedLink(uint32_t state) { - uint32_t led_pin = pin[GPIO_LEDLNK]; + uint32_t led_pin = Pin(GPIO_LEDLNK); uint32_t led_inv = ledlnk_inverted; if (99 == led_pin) { // Legacy - LED1 is status - led_pin = pin[GPIO_LED1]; - led_inv = bitRead(led_inverted, 0); + SetLedPowerIdx(0, state); } - if (led_pin < 99) { + else if (led_pin < 99) { if (state) { state = 1; } digitalWrite(led_pin, (led_inv) ? !state : state); } @@ -418,6 +442,10 @@ bool SendKey(uint32_t key, uint32_t device, uint32_t state) // state 1 = POWER_ON = on // state 2 = POWER_TOGGLE = toggle // state 3 = POWER_HOLD = hold +// state 4 = POWER_INCREMENT = button still pressed +// state 5 = POWER_INV = button released +// state 6 = POWER_CLEAR = button released +// state 7 = POWER_RELEASE = button released // state 9 = CLEAR_RETAIN = clear retain flag char stopic[TOPSZ]; @@ -543,7 +571,12 @@ void ExecuteCommandPower(uint32_t device, uint32_t state, uint32_t source) power ^= mask; } #ifdef USE_DEVICE_GROUPS - if (SRC_REMOTE != source && SRC_RETRY != source) SendLocalDeviceGroupMessage(DGR_MSGTYP_UPDATE, DGR_ITEM_POWER, power); + if (SRC_REMOTE != source && SRC_RETRY != source) { + if (Settings.flag4.remote_device_mode) // SetOption88 - Enable relays in separate device groups + SendDeviceGroupMessage(device - 1, DGR_MSGTYP_UPDATE, DGR_ITEM_POWER, (power >> (device - 1)) & 1 | 0x01000000); // Explicitly set number of relays to one + else + SendLocalDeviceGroupMessage(DGR_MSGTYP_UPDATE, DGR_ITEM_POWER, power); + } #endif // USE_DEVICE_GROUPS SetDevicePower(power, source); #ifdef USE_DOMOTICZ @@ -603,7 +636,7 @@ void MqttShowPWMState(void) ResponseAppend_P(PSTR("\"" D_CMND_PWM "\":{")); bool first = true; for (uint32_t i = 0; i < MAX_PWMS; i++) { - if (pin[GPIO_PWM1 + i] < 99) { + if (PinUsed(GPIO_PWM1, i)) { ResponseAppend_P(PSTR("%s\"" D_CMND_PWM "%d\":%d"), first ? "" : ",", i+1, Settings.pwm_value[i]); first = false; } @@ -624,8 +657,8 @@ void MqttShowState(void) #endif ResponseAppend_P(PSTR(",\"" D_JSON_HEAPSIZE "\":%d,\"SleepMode\":\"%s\",\"Sleep\":%u,\"LoadAvg\":%u,\"MqttCount\":%u"), - ESP.getFreeHeap()/1024, GetTextIndexed(stemp1, sizeof(stemp1), Settings.flag3.sleep_normal, kSleepMode), // SetOption60 - Enable normal sleep instead of dynamic sleep - sleep, loop_load_avg, MqttConnectCount()); + ESP_getFreeHeap()/1024, GetTextIndexed(stemp1, sizeof(stemp1), Settings.flag3.sleep_normal, kSleepMode), // SetOption60 - Enable normal sleep instead of dynamic sleep + ssleep, loop_load_avg, MqttConnectCount()); for (uint32_t i = 1; i <= devices_present; i++) { #ifdef USE_LIGHT @@ -651,10 +684,14 @@ void MqttShowState(void) MqttShowPWMState(); } - int32_t rssi = WiFi.RSSI(); - ResponseAppend_P(PSTR(",\"" D_JSON_WIFI "\":{\"" D_JSON_AP "\":%d,\"" D_JSON_SSID "\":\"%s\",\"" D_JSON_BSSID "\":\"%s\",\"" D_JSON_CHANNEL "\":%d,\"" D_JSON_RSSI "\":%d,\"" D_JSON_SIGNAL "\":%d,\"" D_JSON_LINK_COUNT "\":%d,\"" D_JSON_DOWNTIME "\":\"%s\"}}"), - Settings.sta_active +1, SettingsText(SET_STASSID1 + Settings.sta_active), WiFi.BSSIDstr().c_str(), WiFi.channel(), - WifiGetRssiAsQuality(rssi), rssi, WifiLinkCount(), WifiDowntime().c_str()); + if (!global_state.wifi_down) { + int32_t rssi = WiFi.RSSI(); + ResponseAppend_P(PSTR(",\"" D_JSON_WIFI "\":{\"" D_JSON_AP "\":%d,\"" D_JSON_SSID "\":\"%s\",\"" D_JSON_BSSID "\":\"%s\",\"" D_JSON_CHANNEL "\":%d,\"" D_JSON_RSSI "\":%d,\"" D_JSON_SIGNAL "\":%d,\"" D_JSON_LINK_COUNT "\":%d,\"" D_JSON_DOWNTIME "\":\"%s\"}"), + Settings.sta_active +1, EscapeJSONString(SettingsText(SET_STASSID1 + Settings.sta_active)).c_str(), WiFi.BSSIDstr().c_str(), WiFi.channel(), + WifiGetRssiAsQuality(rssi), rssi, WifiLinkCount(), WifiDowntime().c_str()); + } + + ResponseJsonEnd(); } void MqttPublishTeleState(void) @@ -698,9 +735,9 @@ bool MqttShowSensor(void) int json_data_start = strlen(mqtt_data); for (uint32_t i = 0; i < MAX_SWITCHES; i++) { #ifdef USE_TM1638 - if ((pin[GPIO_SWT1 +i] < 99) || ((pin[GPIO_TM16CLK] < 99) && (pin[GPIO_TM16DIO] < 99) && (pin[GPIO_TM16STB] < 99))) { + if (PinUsed(GPIO_SWT1, i) || (PinUsed(GPIO_TM16CLK) && PinUsed(GPIO_TM16DIO) && PinUsed(GPIO_TM16STB))) { #else - if (pin[GPIO_SWT1 +i] < 99) { + if (PinUsed(GPIO_SWT1, i)) { #endif // USE_TM1638 ResponseAppend_P(PSTR(",\"" D_JSON_SWITCH "%d\":\"%s\""), i +1, GetStateText(SwitchState(i))); } @@ -791,7 +828,7 @@ void PerformEverySecond(void) if (Settings.tele_period) { if (tele_period >= 9999) { - if (!global_state.wifi_down) { + if (!global_state.network_down) { tele_period = 0; // Allow teleperiod once wifi is connected } } else { @@ -819,6 +856,13 @@ void PerformEverySecond(void) // Wifi keep alive to send Gratuitous ARP wifiKeepAlive(); #endif // ARDUINO_ESP8266_RELEASE_2_3_0 + + +#ifdef ESP32 + if (11 == uptime) { // Perform one-time ESP32 houskeeping + ESP_getSketchSize(); // Init sketchsize as it can take up to 2 seconds + } +#endif } /*-------------------------------------------------------------------------------------------*\ @@ -876,10 +920,12 @@ void Every250mSeconds(void) state_250mS++; state_250mS &= 0x3; - if (!Settings.flag.global_state) { // Problem blinkyblinky enabled - SetOption31 - Control link led blinking - if (global_state.data) { // Any problem + global_state.network_down = (global_state.wifi_down && global_state.eth_down); + + if (!Settings.flag.global_state && !global_state.network_down) { // SetOption31 - Control link led blinking + if (global_state.data &0x03) { // Any problem if (global_state.mqtt_down) { blinkinterval = 7; } // MQTT problem so blink every 2 seconds (slowest) - if (global_state.wifi_down) { blinkinterval = 3; } // Wifi problem so blink every second (slow) + if (global_state.network_down) { blinkinterval = 3; } // Network problem so blink every second (slow) blinks = 201; // Allow only a single blink in case the problem is solved } } @@ -901,11 +947,13 @@ void Every250mSeconds(void) if (200 == blinks) blinks = 0; // Disable blink } } - if (Settings.ledstate &1 && (pin[GPIO_LEDLNK] < 99 || !(blinks || restart_flag || ota_state_flag)) ) { + if (Settings.ledstate &1 && (PinUsed(GPIO_LEDLNK) || !(blinks || restart_flag || ota_state_flag)) ) { bool tstate = power & Settings.ledmask; +#ifdef ESP8266 if ((SONOFF_TOUCH == my_module_type) || (SONOFF_T11 == my_module_type) || (SONOFF_T12 == my_module_type) || (SONOFF_T13 == my_module_type)) { tstate = (!power) ? 1 : 0; // As requested invert signal for Touch devices to find them in the dark } +#endif // ESP8266 SetLedPower(tstate); } @@ -1109,11 +1157,75 @@ void Every250mSeconds(void) } break; case 2: // Every x.5 second - WifiCheck(wifi_state_flag); - wifi_state_flag = WIFI_RESTART; + if (Settings.flag4.network_wifi) { + WifiCheck(wifi_state_flag); + wifi_state_flag = WIFI_RESTART; + } break; case 3: // Every x.75 second - if (!global_state.wifi_down) { MqttCheck(); } + if (!global_state.network_down) { +#ifdef FIRMWARE_MINIMAL + if (1 == RtcSettings.ota_loader) { + RtcSettings.ota_loader = 0; + ota_state_flag = 3; + } +#endif // FIRMWARE_MINIMAL + +#ifdef USE_DISCOVERY + StartMdns(); +#endif // USE_DISCOVERY + +#ifdef USE_WEBSERVER + if (Settings.webserver) { + +#ifdef ESP8266 + StartWebserver(Settings.webserver, WiFi.localIP()); +#else // ESP32 +#ifdef USE_ETHERNET + StartWebserver(Settings.webserver, (EthernetLocalIP()) ? EthernetLocalIP() : WiFi.localIP()); +#else + StartWebserver(Settings.webserver, WiFi.localIP()); +#endif +#endif + +#ifdef USE_DISCOVERY +#ifdef WEBSERVER_ADVERTISE + MdnsAddServiceHttp(); +#endif // WEBSERVER_ADVERTISE +#endif // USE_DISCOVERY + } else { + StopWebserver(); + } +#ifdef USE_EMULATION + if (Settings.flag2.emulation) { UdpConnect(); } +#endif // USE_EMULATION +#endif // USE_WEBSERVER + +#ifdef USE_DEVICE_GROUPS + DeviceGroupsStart(); +#endif // USE_DEVICE_GROUPS + +#ifdef USE_KNX + if (!knx_started && Settings.flag.knx_enabled) { // CMND_KNX_ENABLED + KNXStart(); + knx_started = true; + } +#endif // USE_KNX + + MqttCheck(); + } else { +#ifdef USE_EMULATION + UdpDisconnect(); +#endif // USE_EMULATION + +#ifdef USE_DEVICE_GROUPS + DeviceGroupsStop(); +#endif // USE_DEVICE_GROUPS + +#ifdef USE_KNX + knx_started = false; +#endif // USE_KNX + } break; } } @@ -1132,7 +1244,7 @@ uint16_t arduino_ota_progress_dot_count = 0; void ArduinoOTAInit(void) { ArduinoOTA.setPort(8266); - ArduinoOTA.setHostname(my_hostname); + ArduinoOTA.setHostname(NetworkHostname()); if (strlen(SettingsText(SET_WEBPWD))) { ArduinoOTA.setPassword(SettingsText(SET_WEBPWD)); } @@ -1213,13 +1325,25 @@ void SerialInput(void) delay(0); serial_in_byte = Serial.read(); + if (0 == serial_in_byte_counter) { + serial_buffer_overrun = false; + } + else if ((serial_in_byte_counter == INPUT_BUFFER_SIZE) +#ifdef ESP8266 + || Serial.hasOverrun() +#endif + ) { + serial_buffer_overrun = true; + } + +#ifdef ESP8266 /*-------------------------------------------------------------------------------------------*\ * Sonoff dual and ch4 19200 baud serial interface \*-------------------------------------------------------------------------------------------*/ if ((SONOFF_DUAL == my_module_type) || (CH4 == my_module_type)) { serial_in_byte = ButtonSerial(serial_in_byte); } - +#endif // ESP8266 /*-------------------------------------------------------------------------------------------*/ if (XdrvCall(FUNC_SERIAL)) { @@ -1240,21 +1364,28 @@ void SerialInput(void) if (serial_in_byte_counter < INPUT_BUFFER_SIZE -1) { // Add char to string if it still fits serial_in_buffer[serial_in_byte_counter++] = serial_in_byte; } else { - serial_in_byte_counter = 0; + serial_buffer_overrun = true; // Signal overrun but continue reading input to flush until '\n' (EOL) } } } else { if (serial_in_byte || Settings.flag.mqtt_serial_raw) { // Any char between 1 and 127 or any char (0 - 255) - CMND_SERIALSEND3 + bool in_byte_is_delimiter = // Char is delimiter when... + (((Settings.serial_delimiter < 128) && (serial_in_byte == Settings.serial_delimiter)) || // Any char between 1 and 127 and being delimiter + ((Settings.serial_delimiter == 128) && !isprint(serial_in_byte))) && // Any char not between 32 and 127 + !Settings.flag.mqtt_serial_raw; // In raw mode (CMND_SERIALSEND3) there is never a delimiter + if ((serial_in_byte_counter < INPUT_BUFFER_SIZE -1) && // Add char to string if it still fits and ... - ((isprint(serial_in_byte) && (128 == Settings.serial_delimiter)) || // Any char between 32 and 127 - ((serial_in_byte != Settings.serial_delimiter) && (128 != Settings.serial_delimiter)) || // Any char between 1 and 127 and not being delimiter - Settings.flag.mqtt_serial_raw)) { // Any char between 0 and 255 - CMND_SERIALSEND3 + !in_byte_is_delimiter) { // Char is not a delimiter serial_in_buffer[serial_in_byte_counter++] = serial_in_byte; - serial_polling_window = millis(); - } else { + } + + if ((serial_in_byte_counter >= INPUT_BUFFER_SIZE -1) || // Send message when buffer is full or ... + in_byte_is_delimiter) { // Char is delimiter serial_polling_window = 0; // Reception done - send mqtt break; } + + serial_polling_window = millis(); // Wait for next char } } @@ -1277,8 +1408,12 @@ void SerialInput(void) if (!Settings.flag.mqtt_serial && (serial_in_byte == '\n')) { // CMND_SERIALSEND and CMND_SERIALLOG serial_in_buffer[serial_in_byte_counter] = 0; // Serial data completed seriallog_level = (Settings.seriallog_level < LOG_LEVEL_INFO) ? (uint8_t)LOG_LEVEL_INFO : Settings.seriallog_level; - AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_COMMAND "%s"), serial_in_buffer); - ExecuteCommand(serial_in_buffer, SRC_SERIAL); + if (serial_buffer_overrun) { + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_COMMAND "Serial buffer overrun")); + } else { + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_COMMAND "%s"), serial_in_buffer); + ExecuteCommand(serial_in_buffer, SRC_SERIAL); + } serial_in_byte_counter = 0; serial_polling_window = 0; Serial.flush(); @@ -1288,12 +1423,23 @@ void SerialInput(void) if (Settings.flag.mqtt_serial && serial_in_byte_counter && (millis() > (serial_polling_window + SERIAL_POLLING))) { // CMND_SERIALSEND and CMND_SERIALLOG serial_in_buffer[serial_in_byte_counter] = 0; // Serial data completed - char hex_char[(serial_in_byte_counter * 2) + 2]; bool assume_json = (!Settings.flag.mqtt_serial_raw && (serial_in_buffer[0] == '{')); - Response_P(PSTR("{\"" D_JSON_SERIALRECEIVED "\":%s%s%s}"), - (assume_json) ? "" : "\"", - (Settings.flag.mqtt_serial_raw) ? ToHex_P((unsigned char*)serial_in_buffer, serial_in_byte_counter, hex_char, sizeof(hex_char)) : serial_in_buffer, - (assume_json) ? "" : "\""); + + Response_P(PSTR("{\"" D_JSON_SERIALRECEIVED "\":")); + if (assume_json) { + ResponseAppend_P(serial_in_buffer); + } else { + ResponseAppend_P(PSTR("\"")); + if (Settings.flag.mqtt_serial_raw) { + char hex_char[(serial_in_byte_counter * 2) + 2]; + ResponseAppend_P(ToHex_P((unsigned char*)serial_in_buffer, serial_in_byte_counter, hex_char, sizeof(hex_char))); + } else { + ResponseAppend_P(EscapeJSONString(serial_in_buffer).c_str()); + } + ResponseAppend_P(PSTR("\"")); + } + ResponseJsonEnd(); + MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_SERIALRECEIVED)); XdrvRulesProcess(); serial_in_byte_counter = 0; @@ -1305,9 +1451,9 @@ void SerialInput(void) void ResetPwm(void) { for (uint32_t i = 0; i < MAX_PWMS; i++) { // Basic PWM control only - if (pin[GPIO_PWM1 +i] < 99) { - analogWrite(pin[GPIO_PWM1 +i], bitRead(pwm_inverted, i) ? Settings.pwm_range : 0); -// analogWrite(pin[GPIO_PWM1 +i], bitRead(pwm_inverted, i) ? Settings.pwm_range - Settings.pwm_value[i] : Settings.pwm_value[i]); + if (PinUsed(GPIO_PWM1, i)) { + analogWrite(Pin(GPIO_PWM1, i), bitRead(pwm_inverted, i) ? Settings.pwm_range : 0); +// analogWrite(Pin(GPIO_PWM1, i), bitRead(pwm_inverted, i) ? Settings.pwm_range - Settings.pwm_value[i] : Settings.pwm_value[i]); } } } @@ -1316,11 +1462,17 @@ void ResetPwm(void) void GpioInit(void) { - uint32_t mpin; - if (!ValidModule(Settings.module)) { uint32_t module = MODULE; - if (!ValidModule(MODULE)) { module = SONOFF_BASIC; } + if (!ValidModule(MODULE)) { +#ifdef ESP8266 + module = SONOFF_BASIC; +#endif // ESP8266 +#ifdef ESP32 + module = WEMOS; +#endif // ESP32 + } + Settings.module = module; Settings.last_module = module; } @@ -1331,25 +1483,26 @@ void GpioInit(void) Settings.serial_config = TS_SERIAL_8N1; } - for (uint32_t i = 0; i < sizeof(Settings.user_template.gp); i++) { - if ((Settings.user_template.gp.io[i] >= GPIO_SENSOR_END) && (Settings.user_template.gp.io[i] < GPIO_USER)) { - Settings.user_template.gp.io[i] = GPIO_USER; // Fix not supported sensor ids in template + for (uint32_t i = 0; i < ARRAY_SIZE(Settings.user_template.gp.io); i++) { + if ((Settings.user_template.gp.io[i] >= AGPIO(GPIO_SENSOR_END)) && (Settings.user_template.gp.io[i] < AGPIO(GPIO_USER))) { + Settings.user_template.gp.io[i] = AGPIO(GPIO_USER); // Fix not supported sensor ids in template } } myio def_gp; ModuleGpios(&def_gp); - for (uint32_t i = 0; i < sizeof(Settings.my_gp); i++) { - if ((Settings.my_gp.io[i] >= GPIO_SENSOR_END) && (Settings.my_gp.io[i] < GPIO_USER)) { + for (uint32_t i = 0; i < ARRAY_SIZE(Settings.my_gp.io); i++) { + if ((Settings.my_gp.io[i] >= AGPIO(GPIO_SENSOR_END)) && (Settings.my_gp.io[i] < AGPIO(GPIO_USER))) { Settings.my_gp.io[i] = GPIO_NONE; // Fix not supported sensor ids in module } else if (Settings.my_gp.io[i] > GPIO_NONE) { my_module.io[i] = Settings.my_gp.io[i]; // Set User selected Module sensors } - if ((def_gp.io[i] > GPIO_NONE) && (def_gp.io[i] < GPIO_USER)) { + if ((def_gp.io[i] > GPIO_NONE) && (def_gp.io[i] < AGPIO(GPIO_USER))) { my_module.io[i] = def_gp.io[i]; // Force Template override } } +#ifdef ESP8266 if ((Settings.my_adc0 >= ADC0_END) && (Settings.my_adc0 < ADC0_USER)) { Settings.my_adc0 = ADC0_NONE; // Fix not supported sensor ids in module } @@ -1361,51 +1514,55 @@ void GpioInit(void) if ((template_adc0 > ADC0_NONE) && (template_adc0 < ADC0_USER)) { my_adc0 = template_adc0; // Force Template override } +#endif - for (uint32_t i = 0; i < GPIO_MAX; i++) { - pin[i] = 99; - } - for (uint32_t i = 0; i < sizeof(my_module.io); i++) { - mpin = ValidPin(i, my_module.io[i]); + for (uint32_t i = 0; i < ARRAY_SIZE(my_module.io); i++) { + uint32_t mpin = ValidPin(i, my_module.io[i]); DEBUG_CORE_LOG(PSTR("INI: gpio pin %d, mpin %d"), i, mpin); - if (mpin) { + if (mpin) { // Above GPIO_NONE XdrvMailbox.index = mpin; XdrvMailbox.payload = i; - if ((mpin >= GPIO_SWT1_NP) && (mpin < (GPIO_SWT1_NP + MAX_SWITCHES))) { - SwitchPullupFlag(mpin - GPIO_SWT1_NP); - mpin -= (GPIO_SWT1_NP - GPIO_SWT1); + if ((mpin >= AGPIO(GPIO_SWT1_NP)) && (mpin < (AGPIO(GPIO_SWT1_NP) + MAX_SWITCHES))) { + SwitchPullupFlag(mpin - AGPIO(GPIO_SWT1_NP)); + mpin -= (AGPIO(GPIO_SWT1_NP) - AGPIO(GPIO_SWT1)); } - else if ((mpin >= GPIO_KEY1_NP) && (mpin < (GPIO_KEY1_NP + MAX_KEYS))) { - ButtonPullupFlag(mpin - GPIO_KEY1_NP); // 0 .. 3 - mpin -= (GPIO_KEY1_NP - GPIO_KEY1); + else if ((mpin >= AGPIO(GPIO_KEY1_NP)) && (mpin < (AGPIO(GPIO_KEY1_NP) + MAX_KEYS))) { + ButtonPullupFlag(mpin - AGPIO(GPIO_KEY1_NP)); // 0 .. 3 + mpin -= (AGPIO(GPIO_KEY1_NP) - AGPIO(GPIO_KEY1)); } - else if ((mpin >= GPIO_KEY1_INV) && (mpin < (GPIO_KEY1_INV + MAX_KEYS))) { - ButtonInvertFlag(mpin - GPIO_KEY1_INV); // 0 .. 3 - mpin -= (GPIO_KEY1_INV - GPIO_KEY1); + else if ((mpin >= AGPIO(GPIO_KEY1_INV)) && (mpin < (AGPIO(GPIO_KEY1_INV) + MAX_KEYS))) { + ButtonInvertFlag(mpin - AGPIO(GPIO_KEY1_INV)); // 0 .. 3 + mpin -= (AGPIO(GPIO_KEY1_INV) - AGPIO(GPIO_KEY1)); } - else if ((mpin >= GPIO_KEY1_INV_NP) && (mpin < (GPIO_KEY1_INV_NP + MAX_KEYS))) { - ButtonPullupFlag(mpin - GPIO_KEY1_INV_NP); // 0 .. 3 - ButtonInvertFlag(mpin - GPIO_KEY1_INV_NP); // 0 .. 3 - mpin -= (GPIO_KEY1_INV_NP - GPIO_KEY1); + else if ((mpin >= AGPIO(GPIO_KEY1_INV_NP)) && (mpin < (AGPIO(GPIO_KEY1_INV_NP) + MAX_KEYS))) { + ButtonPullupFlag(mpin - AGPIO(GPIO_KEY1_INV_NP)); // 0 .. 3 + ButtonInvertFlag(mpin - AGPIO(GPIO_KEY1_INV_NP)); // 0 .. 3 + mpin -= (AGPIO(GPIO_KEY1_INV_NP) - AGPIO(GPIO_KEY1)); } - else if ((mpin >= GPIO_REL1_INV) && (mpin < (GPIO_REL1_INV + MAX_RELAYS))) { - bitSet(rel_inverted, mpin - GPIO_REL1_INV); - mpin -= (GPIO_REL1_INV - GPIO_REL1); +#ifdef ESP32 + else if ((mpin >= AGPIO(GPIO_KEY1_TC)) && (mpin < (AGPIO(GPIO_KEY1_TC) + MAX_KEYS))) { + ButtonTouchFlag(mpin - AGPIO(GPIO_KEY1_TC)); // 0 .. 3 + mpin -= (AGPIO(GPIO_KEY1_TC) - AGPIO(GPIO_KEY1)); } - else if ((mpin >= GPIO_LED1_INV) && (mpin < (GPIO_LED1_INV + MAX_LEDS))) { - bitSet(led_inverted, mpin - GPIO_LED1_INV); - mpin -= (GPIO_LED1_INV - GPIO_LED1); +#endif //ESP32 + else if ((mpin >= AGPIO(GPIO_REL1_INV)) && (mpin < (AGPIO(GPIO_REL1_INV) + MAX_RELAYS))) { + bitSet(rel_inverted, mpin - AGPIO(GPIO_REL1_INV)); + mpin -= (AGPIO(GPIO_REL1_INV) - AGPIO(GPIO_REL1)); } - else if (mpin == GPIO_LEDLNK_INV) { + else if ((mpin >= AGPIO(GPIO_LED1_INV)) && (mpin < (AGPIO(GPIO_LED1_INV) + MAX_LEDS))) { + bitSet(led_inverted, mpin - AGPIO(GPIO_LED1_INV)); + mpin -= (AGPIO(GPIO_LED1_INV) - AGPIO(GPIO_LED1)); + } + else if (mpin == AGPIO(GPIO_LEDLNK_INV)) { ledlnk_inverted = 1; - mpin -= (GPIO_LEDLNK_INV - GPIO_LEDLNK); + mpin -= (AGPIO(GPIO_LEDLNK_INV) - AGPIO(GPIO_LEDLNK)); } - else if ((mpin >= GPIO_PWM1_INV) && (mpin < (GPIO_PWM1_INV + MAX_PWMS))) { - bitSet(pwm_inverted, mpin - GPIO_PWM1_INV); - mpin -= (GPIO_PWM1_INV - GPIO_PWM1); + else if ((mpin >= AGPIO(GPIO_PWM1_INV)) && (mpin < (AGPIO(GPIO_PWM1_INV) + MAX_PWMS))) { + bitSet(pwm_inverted, mpin - AGPIO(GPIO_PWM1_INV)); + mpin -= (AGPIO(GPIO_PWM1_INV) - AGPIO(GPIO_PWM1)); } else if (XdrvCall(FUNC_PIN_STATE)) { mpin = XdrvMailbox.index; @@ -1414,34 +1571,91 @@ void GpioInit(void) mpin = XdrvMailbox.index; }; } - if (mpin) pin[mpin] = i; + if (mpin) { SetPin(i, mpin); } // Anything above GPIO_NONE and below GPIO_SENSOR_END } - if ((2 == pin[GPIO_TXD]) || (H801 == my_module_type)) { Serial.set_tx(2); } +// AddLogBufferSize(LOG_LEVEL_DEBUG, (uint8_t*)gpio_pin, ARRAY_SIZE(gpio_pin), sizeof(gpio_pin[0])); + +#ifdef ESP8266 + if ((2 == Pin(GPIO_TXD)) || (H801 == my_module_type)) { Serial.set_tx(2); } analogWriteRange(Settings.pwm_range); // Default is 1023 (Arduino.h) analogWriteFreq(Settings.pwm_frequency); // Default is 1000 (core_esp8266_wiring_pwm.c) #ifdef USE_SPI - spi_flg = ((((pin[GPIO_SPI_CS] < 99) && (pin[GPIO_SPI_CS] > 14)) || (pin[GPIO_SPI_CS] < 12)) || (((pin[GPIO_SPI_DC] < 99) && (pin[GPIO_SPI_DC] > 14)) || (pin[GPIO_SPI_DC] < 12))); + spi_flg = (((PinUsed(GPIO_SPI_CS) && (Pin(GPIO_SPI_CS) > 14)) || (Pin(GPIO_SPI_CS) < 12)) || ((PinUsed(GPIO_SPI_DC) && (Pin(GPIO_SPI_DC) > 14)) || (Pin(GPIO_SPI_DC) < 12))); if (spi_flg) { - for (uint32_t i = 0; i < GPIO_MAX; i++) { - if ((pin[i] >= 12) && (pin[i] <=14)) pin[i] = 99; - } my_module.io[12] = GPIO_SPI_MISO; - pin[GPIO_SPI_MISO] = 12; + SetPin(12, GPIO_SPI_MISO); my_module.io[13] = GPIO_SPI_MOSI; - pin[GPIO_SPI_MOSI] = 13; + SetPin(13, GPIO_SPI_MOSI); my_module.io[14] = GPIO_SPI_CLK; - pin[GPIO_SPI_CLK] = 14; + SetPin(14, GPIO_SPI_CLK); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SPI: Using GPIO12(MISO), GPIO13(MOSI) and GPIO14(CLK)")); } - soft_spi_flg = ((pin[GPIO_SSPI_CS] < 99) && (pin[GPIO_SSPI_SCLK] < 99) && ((pin[GPIO_SSPI_MOSI] < 99) || (pin[GPIO_SSPI_MOSI] < 99))); + soft_spi_flg = (PinUsed(GPIO_SSPI_CS) && PinUsed(GPIO_SSPI_SCLK) && (PinUsed(GPIO_SSPI_MOSI) || PinUsed(GPIO_SSPI_MISO))); #endif // USE_SPI +#else // ESP32 + analogWriteFreqRange(0, Settings.pwm_frequency, Settings.pwm_range); + +#ifdef USE_SPI + if (PinUsed(GPIO_SPI_CS) || PinUsed(GPIO_SPI_DC)) { + if ((15 == Pin(GPIO_SPI_CS)) && (!GetPin(12) && !GetPin(13) && !GetPin(14))) { // HSPI + my_module.io[12] = AGPIO(GPIO_SPI_MISO); + SetPin(12, AGPIO(GPIO_SPI_MISO)); + my_module.io[13] = AGPIO(GPIO_SPI_MOSI); + SetPin(13, AGPIO(GPIO_SPI_MOSI)); + my_module.io[14] = AGPIO(GPIO_SPI_CLK); + SetPin(14, AGPIO(GPIO_SPI_CLK)); + } + else if ((5 == Pin(GPIO_SPI_CS)) && (!GetPin(19) && !GetPin(23) && !GetPin(18))) { // VSPI + my_module.io[19] = AGPIO(GPIO_SPI_MISO); + SetPin(19, AGPIO(GPIO_SPI_MISO)); + my_module.io[23] = AGPIO(GPIO_SPI_MOSI); + SetPin(23, AGPIO(GPIO_SPI_MOSI)); + my_module.io[18] = AGPIO(GPIO_SPI_CLK); + SetPin(18, AGPIO(GPIO_SPI_CLK)); + } + else if ((12 == Pin(GPIO_SPI_MISO)) || (13 == Pin(GPIO_SPI_MOSI)) || (14 == Pin(GPIO_SPI_CLK))) { // HSPI + my_module.io[12] = AGPIO(GPIO_SPI_MISO); + SetPin(12, AGPIO(GPIO_SPI_MISO)); + my_module.io[13] = AGPIO(GPIO_SPI_MOSI); + SetPin(13, AGPIO(GPIO_SPI_MOSI)); + my_module.io[14] = AGPIO(GPIO_SPI_CLK); + SetPin(14, AGPIO(GPIO_SPI_CLK)); + } + else if ((19 == Pin(GPIO_SPI_MISO)) || (23 == Pin(GPIO_SPI_MOSI)) || (18 == Pin(GPIO_SPI_CLK))) { // VSPI + my_module.io[19] = AGPIO(GPIO_SPI_MISO); + SetPin(19, AGPIO(GPIO_SPI_MISO)); + my_module.io[23] = AGPIO(GPIO_SPI_MOSI); + SetPin(23, AGPIO(GPIO_SPI_MOSI)); + my_module.io[18] = AGPIO(GPIO_SPI_CLK); + SetPin(18, AGPIO(GPIO_SPI_CLK)); + } + spi_flg = (PinUsed(GPIO_SPI_CLK) && (PinUsed(GPIO_SPI_MOSI) || PinUsed(GPIO_SPI_MISO))); + if (spi_flg) { + if (PinUsed(GPIO_SPI_MOSI) && PinUsed(GPIO_SPI_MISO)) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SPI: Using GPIO%02d(MISO), GPIO%02d(MOSI) and GPIO%02d(CLK)"), + Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_MOSI), Pin(GPIO_SPI_CLK)); + } + else if (PinUsed(GPIO_SPI_MOSI)) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SPI: Using GPIO%02d(MOSI) and GPIO%02d(CLK)"), + Pin(GPIO_SPI_MOSI), Pin(GPIO_SPI_CLK)); + } + else if (PinUsed(GPIO_SPI_MISO)) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SPI: Using GPIO%02d(MISO) and GPIO%02d(CLK)"), + Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_CLK)); + } + } + } + soft_spi_flg = (PinUsed(GPIO_SSPI_SCLK) && (PinUsed(GPIO_SSPI_MOSI) || PinUsed(GPIO_SSPI_MISO))); +#endif // USE_SPI +#endif // ESP8266 - ESP32 // Set any non-used GPIO to INPUT - Related to resetPins() in support_legacy_cores.ino // Doing it here solves relay toggles at restart. - for (uint32_t i = 0; i < sizeof(my_module.io); i++) { - mpin = ValidPin(i, my_module.io[i]); + for (uint32_t i = 0; i < ARRAY_SIZE(my_module.io); i++) { + uint32_t mpin = ValidPin(i, my_module.io[i]); // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("INI: gpio pin %d, mpin %d"), i, mpin); if (((i < 6) || (i > 11)) && (0 == mpin)) { // Skip SPI flash interface if (!((1 == i) || (3 == i))) { // Skip serial @@ -1451,9 +1665,9 @@ void GpioInit(void) } #ifdef USE_I2C - i2c_flg = ((pin[GPIO_I2C_SCL] < 99) && (pin[GPIO_I2C_SDA] < 99)); + i2c_flg = (PinUsed(GPIO_I2C_SCL) && PinUsed(GPIO_I2C_SDA)); if (i2c_flg) { - Wire.begin(pin[GPIO_I2C_SDA], pin[GPIO_I2C_SCL]); + Wire.begin(Pin(GPIO_I2C_SDA), Pin(GPIO_I2C_SCL)); } #endif // USE_I2C @@ -1462,6 +1676,7 @@ void GpioInit(void) if (XdrvCall(FUNC_MODULE_INIT)) { // Serviced } +#ifdef ESP8266 else if (YTF_IR_BRIDGE == my_module_type) { ClaimSerial(); // Stop serial loopback mode // devices_present = 1; @@ -1479,54 +1694,61 @@ void GpioInit(void) SetSerial(19200, TS_SERIAL_8N1); } #endif // USE_SONOFF_SC +#endif // ESP8266 for (uint32_t i = 0; i < MAX_PWMS; i++) { // Basic PWM control only - if (pin[GPIO_PWM1 +i] < 99) { - pinMode(pin[GPIO_PWM1 +i], OUTPUT); + if (PinUsed(GPIO_PWM1, i)) { + pinMode(Pin(GPIO_PWM1, i), OUTPUT); +#ifdef ESP32 + analogAttach(Pin(GPIO_PWM1, i),i); + analogWriteFreqRange(i,Settings.pwm_frequency,Settings.pwm_range); +#endif + if (light_type) { // force PWM GPIOs to low or high mode, see #7165 - analogWrite(pin[GPIO_PWM1 +i], bitRead(pwm_inverted, i) ? Settings.pwm_range : 0); + analogWrite(Pin(GPIO_PWM1, i), bitRead(pwm_inverted, i) ? Settings.pwm_range : 0); } else { pwm_present = true; - analogWrite(pin[GPIO_PWM1 +i], bitRead(pwm_inverted, i) ? Settings.pwm_range - Settings.pwm_value[i] : Settings.pwm_value[i]); + analogWrite(Pin(GPIO_PWM1, i), bitRead(pwm_inverted, i) ? Settings.pwm_range - Settings.pwm_value[i] : Settings.pwm_value[i]); } } } for (uint32_t i = 0; i < MAX_RELAYS; i++) { - if (pin[GPIO_REL1 +i] < 99) { - pinMode(pin[GPIO_REL1 +i], OUTPUT); + if (PinUsed(GPIO_REL1, i)) { + pinMode(Pin(GPIO_REL1, i), OUTPUT); devices_present++; +#ifdef ESP8266 if (EXS_RELAY == my_module_type) { - digitalWrite(pin[GPIO_REL1 +i], bitRead(rel_inverted, i) ? 1 : 0); + digitalWrite(Pin(GPIO_REL1, i), bitRead(rel_inverted, i) ? 1 : 0); if (i &1) { devices_present--; } } +#endif // ESP8266 } } for (uint32_t i = 0; i < MAX_LEDS; i++) { - if (pin[GPIO_LED1 +i] < 99) { + if (PinUsed(GPIO_LED1, i)) { #ifdef USE_ARILUX_RF - if ((3 == i) && (leds_present < 2) && (99 == pin[GPIO_ARIRFSEL])) { - pin[GPIO_ARIRFSEL] = pin[GPIO_LED4]; // Legacy support where LED4 was Arilux RF enable - pin[GPIO_LED4] = 99; + if ((3 == i) && (leds_present < 2) && !PinUsed(GPIO_ARIRFSEL)) { + SetPin(Pin(GPIO_LED1, i), AGPIO(GPIO_ARIRFSEL)); // Legacy support where LED4 was Arilux RF enable } else { #endif - pinMode(pin[GPIO_LED1 +i], OUTPUT); + pinMode(Pin(GPIO_LED1, i), OUTPUT); leds_present++; - digitalWrite(pin[GPIO_LED1 +i], bitRead(led_inverted, i)); + digitalWrite(Pin(GPIO_LED1, i), bitRead(led_inverted, i)); #ifdef USE_ARILUX_RF } #endif } } - if (pin[GPIO_LEDLNK] < 99) { - pinMode(pin[GPIO_LEDLNK], OUTPUT); - digitalWrite(pin[GPIO_LEDLNK], ledlnk_inverted); + if (PinUsed(GPIO_LEDLNK)) { + pinMode(Pin(GPIO_LEDLNK), OUTPUT); + digitalWrite(Pin(GPIO_LEDLNK), ledlnk_inverted); } #ifdef USE_PWM_DIMMER - if (PWM_DIMMER == my_module_type && pin[GPIO_REL1] < 99) devices_present--; + if (PWM_DIMMER == my_module_type && PinUsed(GPIO_REL1)) { devices_present--; } #endif // USE_PWM_DIMMER ButtonInit(); diff --git a/tasmota/support_udp.ino b/tasmota/support_udp.ino index 701abee66..cccb64b4e 100644 --- a/tasmota/support_udp.ino +++ b/tasmota/support_udp.ino @@ -19,7 +19,9 @@ #ifdef USE_EMULATION -#define UDP_BUFFER_SIZE 200 // Max UDP buffer size needed for M-SEARCH message +#ifndef UDP_BUFFER_SIZE +#define UDP_BUFFER_SIZE 120 // Max UDP buffer size needed for M-SEARCH message +#endif #define UDP_MSEARCH_SEND_DELAY 1500 // Delay in ms before M-Search response is send #include @@ -31,6 +33,15 @@ uint16_t udp_remote_port; // M-Search remote port bool udp_connected = false; bool udp_response_mutex = false; // M-Search response mutex to control re-entry +#ifdef ESP8266 +#ifndef UDP_MAX_PACKETS +#define UDP_MAX_PACKETS 3 // we support x more packets than the current one +#endif + +#include "UdpListener.h" +UdpListener UdpCtx(UDP_MAX_PACKETS); +#endif + /*********************************************************************************************\ * UPNP/SSDP search targets \*********************************************************************************************/ @@ -48,8 +59,18 @@ const char SSDP_ALL[] PROGMEM = "ssdp:all"; bool UdpDisconnect(void) { if (udp_connected) { + // flush any outgoing packet PortUdp.flush(); +#ifdef ESP8266 + UdpCtx.disconnect(); +#endif +#ifdef USE_DEVICE_GROUPS + // stop + PortUdp.stop(); +#else // USE_DEVICE_GROUPS + // stop all WiFiUDP::stopAll(); +#endif // !USE_DEVICE_GROUPS AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_UPNP D_MULTICAST_DISABLED)); udp_connected = false; } @@ -60,13 +81,25 @@ bool UdpConnect(void) { if (!udp_connected && !restart_flag) { // Simple Service Discovery Protocol (SSDP) +#ifdef ESP8266 + UdpCtx.reset(); + if (igmp_joingroup(WiFi.localIP(), IPAddress(239,255,255,250)) == ERR_OK) { // addr 239.255.255.250 + ip_addr_t addr = IPADDR4_INIT(INADDR_ANY); + if (UdpCtx.listen(&addr, 1900)) { // port 1900 + // OK + AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_UPNP D_MULTICAST_REJOINED)); + udp_response_mutex = false; + udp_connected = true; + } +#else // ESP32 if (PortUdp.beginMulticast(WiFi.localIP(), IPAddress(239,255,255,250), 1900)) { AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_UPNP D_MULTICAST_REJOINED)); udp_response_mutex = false; udp_connected = true; - } else { +#endif + } + if (!udp_connected) { // if connection failed AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_UPNP D_MULTICAST_JOIN_FAILED)); - udp_connected = false; } } return udp_connected; @@ -75,14 +108,25 @@ bool UdpConnect(void) void PollUdp(void) { if (udp_connected) { +#ifdef ESP8266 + while (UdpCtx.next()) { + UdpPacket *packet; + packet = UdpCtx.read(); + if (packet->len >= UDP_BUFFER_SIZE) { + packet->len--; // leave space for NULL terminator + } + packet->buf[packet->len] = 0; // add NULL at the end of the packer + char * packet_buffer = (char*) &packet->buf; + int32_t len = packet->len; +#else // ESP32 while (PortUdp.parsePacket()) { char packet_buffer[UDP_BUFFER_SIZE]; // buffer to hold incoming UDP/SSDP packet - int len = PortUdp.read(packet_buffer, UDP_BUFFER_SIZE -1); + int32_t len = PortUdp.read(packet_buffer, UDP_BUFFER_SIZE -1); packet_buffer[len] = 0; - +#endif AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("UDP: Packet (%d)"), len); -// AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("\n%s"), packet_buffer); + // AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("\n%s"), packet_buffer); // Simple Service Discovery Protocol (SSDP) if (Settings.flag2.emulation) { @@ -93,11 +137,16 @@ void PollUdp(void) #endif udp_response_mutex = true; +#ifdef ESP8266 + udp_remote_ip = packet->srcaddr; + udp_remote_port = packet->srcport; +#else udp_remote_ip = PortUdp.remoteIP(); udp_remote_port = PortUdp.remotePort(); +#endif -// AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("UDP: M-SEARCH Packet from %s:%d\n%s"), -// udp_remote_ip.toString().c_str(), udp_remote_port, packet_buffer); + // AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("UDP: M-SEARCH Packet from %s:%d\n%s"), + // udp_remote_ip.toString().c_str(), udp_remote_port, packet_buffer); uint32_t response_delay = UDP_MSEARCH_SEND_DELAY + ((millis() &0x7) * 100); // 1500 - 2200 msec @@ -135,12 +184,6 @@ void PollUdp(void) continue; } } - -#ifdef USE_DEVICE_GROUPS - if (Settings.flag4.device_groups_enabled && !strncmp_P(packet_buffer, kDeviceGroupMessage, sizeof(DEVICE_GROUP_MESSAGE) - 1)) { - ProcessDeviceGroupMessage(packet_buffer, len); - } -#endif // USE_DEVICE_GROUPS } optimistic_yield(100); } diff --git a/tasmota/support_wifi.ino b/tasmota/support_wifi.ino index 8f022057d..75de2523f 100644 --- a/tasmota/support_wifi.ino +++ b/tasmota/support_wifi.ino @@ -52,7 +52,6 @@ struct WIFI { uint8_t status; uint8_t config_type = 0; uint8_t config_counter = 0; - uint8_t mdns_begun = 0; // mDNS active uint8_t scan_state; uint8_t bssid[6]; int8_t best_network_db; @@ -156,10 +155,10 @@ void WiFiSetSleepMode(void) // Sleep explanation: https://github.com/esp8266/Arduino/blob/3f0c601cfe81439ce17e9bd5d28994a7ed144482/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp#L255 #if defined(ARDUINO_ESP8266_RELEASE_2_4_1) || defined(ARDUINO_ESP8266_RELEASE_2_4_2) #else // Enabled in 2.3.0, 2.4.0 and stage - if (sleep && Settings.flag3.sleep_normal) { // SetOption60 - Enable normal sleep instead of dynamic sleep - WiFi.setSleepMode(WIFI_LIGHT_SLEEP); // Allow light sleep during idle times + if (ssleep && Settings.flag3.sleep_normal) { // SetOption60 - Enable normal sleep instead of dynamic sleep + WiFi.setSleepMode(WIFI_LIGHT_SLEEP); // Allow light sleep during idle times } else { - WiFi.setSleepMode(WIFI_MODEM_SLEEP); // Disable sleep (Esp8288/Arduino core and sdk default) + WiFi.setSleepMode(WIFI_MODEM_SLEEP); // Disable sleep (Esp8288/Arduino core and sdk default) } #endif WifiSetOutputPower(); @@ -352,6 +351,9 @@ void WifiSetState(uint8_t state) } } global_state.wifi_down = state ^1; + if (!global_state.wifi_down) { + global_state.network_down = 0; + } } #if LWIP_IPV6 @@ -410,10 +412,7 @@ void WifiCheckIp(void) Wifi.status = WL_CONNECTED; #ifdef USE_DISCOVERY #ifdef WEBSERVER_ADVERTISE - if (2 == Wifi.mdns_begun) { - MDNS.update(); - AddLog_P(LOG_LEVEL_DEBUG_MORE, D_LOG_MDNS, "MDNS.update"); - } + MdnsUpdate(); #endif // USE_DISCOVERY #endif // WEBSERVER_ADVERTISE } else { @@ -529,74 +528,14 @@ void WifiCheck(uint8_t param) if ((WL_CONNECTED == WiFi.status()) && (static_cast(WiFi.localIP()) != 0) && !Wifi.config_type) { #endif // LWIP_IPV6=1 WifiSetState(1); - if (Settings.flag3.use_wifi_rescan) { // SetOption57 - Scan wifi network every 44 minutes for configured AP's if (!(uptime % (60 * WIFI_RESCAN_MINUTES))) { Wifi.scan_state = 2; } } - -#ifdef FIRMWARE_MINIMAL - if (1 == RtcSettings.ota_loader) { - RtcSettings.ota_loader = 0; - ota_state_flag = 3; - } -#endif // FIRMWARE_MINIMAL - -#ifdef USE_DISCOVERY - if (Settings.flag3.mdns_enabled) { // SetOption55 - Control mDNS service - if (!Wifi.mdns_begun) { -// if (mdns_delayed_start) { -// AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS D_ATTEMPTING_CONNECTION)); -// mdns_delayed_start--; -// } else { -// mdns_delayed_start = Settings.param[P_MDNS_DELAYED_START]; - Wifi.mdns_begun = (uint8_t)MDNS.begin(my_hostname); - AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS "%s"), (Wifi.mdns_begun) ? D_INITIALIZED : D_FAILED); -// } - } - } -#endif // USE_DISCOVERY - -#ifdef USE_WEBSERVER - if (Settings.webserver) { - StartWebserver(Settings.webserver, WiFi.localIP()); -#ifdef USE_DISCOVERY -#ifdef WEBSERVER_ADVERTISE - if (1 == Wifi.mdns_begun) { - Wifi.mdns_begun = 2; - MDNS.addService("http", "tcp", WEB_PORT); - } -#endif // WEBSERVER_ADVERTISE -#endif // USE_DISCOVERY - } else { - StopWebserver(); - } -#ifdef USE_EMULATION -#ifdef USE_DEVICE_GROUPS - if (Settings.flag2.emulation || Settings.flag4.device_groups_enabled) { UdpConnect(); } -#else // USE_DEVICE_GROUPS - if (Settings.flag2.emulation) { UdpConnect(); } -#endif // USE_DEVICE_GROUPS -#endif // USE_EMULATION -#endif // USE_WEBSERVER - -#ifdef USE_KNX - if (!knx_started && Settings.flag.knx_enabled) { // CMND_KNX_ENABLED - KNXStart(); - knx_started = true; - } -#endif // USE_KNX - } else { WifiSetState(0); -#ifdef USE_EMULATION - UdpDisconnect(); -#endif // USE_EMULATION - Wifi.mdns_begun = 0; -#ifdef USE_KNX - knx_started = false; -#endif // USE_KNX + Mdns.begun = 0; } } } @@ -651,11 +590,13 @@ RF_PRE_INIT() void WifiConnect(void) { + if (!Settings.flag4.network_wifi) { return; } + WifiSetState(0); WifiSetOutputPower(); WiFi.persistent(false); // Solve possible wifi init errors Wifi.status = 0; - Wifi.retry_init = WIFI_RETRY_OFFSET_SEC + (ESP.getChipId() & 0xF); // Add extra delay to stop overrun by simultanous re-connects + Wifi.retry_init = WIFI_RETRY_OFFSET_SEC + (ESP_getChipId() & 0xF); // Add extra delay to stop overrun by simultanous re-connects Wifi.retry = Wifi.retry_init; Wifi.counter = 1; @@ -708,8 +649,7 @@ void EspRestart(void) ResetPwm(); WifiShutdown(true); CrashDumpClear(); // Clear the stack dump in RTC -// ESP.restart(); // This results in exception 3 on restarts on core 2.3.0 - ESP.reset(); + ESP_Restart(); } #ifndef ARDUINO_ESP8266_RELEASE_2_3_0 @@ -760,4 +700,4 @@ void wifiKeepAlive(void) { SetNextTimeInterval(wifiTimer, wifiTimerSec * 1000); } } -#endif // ARDUINO_ESP8266_RELEASE_2_3_0 \ No newline at end of file +#endif // ARDUINO_ESP8266_RELEASE_2_3_0 diff --git a/tasmota/tasmota.h b/tasmota/tasmota.h index 57fdc60ff..4eceddb5c 100644 --- a/tasmota/tasmota.h +++ b/tasmota/tasmota.h @@ -68,7 +68,7 @@ const uint8_t MAX_XDRV_DRIVERS = 96; // Max number of allowed driver driv const uint8_t MAX_XSNS_DRIVERS = 96; // Max number of allowed sensor drivers const uint8_t MAX_I2C_DRIVERS = 96; // Max number of allowed i2c drivers const uint8_t MAX_SHUTTERS = 4; // Max number of shutters -const uint8_t MAX_PCF8574 = 8; // Max number of PCF8574 devices +const uint8_t MAX_PCF8574 = 4; // Max number of PCF8574 devices const uint8_t MAX_RULE_SETS = 3; // Max number of rule sets of size 512 characters const uint16_t MAX_RULE_SIZE = 512; // Max number of characters in rules @@ -104,9 +104,9 @@ const uint16_t WS2812_MAX_LEDS = 512; // Max number of LEDs const uint32_t PWM_RANGE = 1023; // 255..1023 needs to be devisible by 256 //const uint16_t PWM_FREQ = 1000; // 100..1000 Hz led refresh //const uint16_t PWM_FREQ = 910; // 100..1000 Hz led refresh (iTead value) -const uint16_t PWM_FREQ = 880; // 100..1000 Hz led refresh (BN-SZ01 value) +const uint16_t PWM_FREQ = 977; // 100..4000 Hz led refresh const uint16_t PWM_MAX = 4000; // [PWM_MAX] Maximum frequency - Default: 4000 -const uint16_t PWM_MIN = 100; // [PWM_MIN] Minimum frequency - Default: 100 +const uint16_t PWM_MIN = 40; // [PWM_MIN] Minimum frequency - Default: 40 // For Dimmers use double of your mains AC frequecy (100 for 50Hz and 120 for 60Hz) // For Controlling Servos use 50 and also set PWM_FREQ as 50 (DO NOT USE THESE VALUES FOR DIMMERS) @@ -124,12 +124,12 @@ const uint16_t SYSLOG_TIMER = 600; // Seconds to restore syslog_level const uint16_t SERIALLOG_TIMER = 600; // Seconds to disable SerialLog const uint8_t OTA_ATTEMPTS = 5; // Number of times to try fetching the new firmware -const uint16_t INPUT_BUFFER_SIZE = 520; // Max number of characters in (serial and http) command buffer +const uint16_t INPUT_BUFFER_SIZE = 520; // Max number of characters in serial command buffer const uint16_t FLOATSZ = 16; // Max number of characters in float result from dtostrfd (max 32) const uint16_t CMDSZ = 24; // Max number of characters in command const uint16_t TOPSZ = 151; // Max number of characters in topic string const uint16_t LOGSZ = 700; // Max number of characters in log -const uint16_t MIN_MESSZ = 1040; // Min number of characters in MQTT message (1000 - TOPSZ - 9 header bytes) +const uint16_t MIN_MESSZ = 1040; // Min number of characters in MQTT message (1200 - TOPSZ - 9 header bytes) const uint8_t SENSOR_MAX_MISS = 5; // Max number of missed sensor reads before deciding it's offline @@ -203,7 +203,8 @@ const uint32_t LOOP_SLEEP_DELAY = 50; // Lowest number of milliseconds to #define KNX_SLOT3 28 #define KNX_SLOT4 29 #define KNX_SLOT5 30 -#define KNX_MAX_device_param 30 +#define KNX_SCENE 31 +#define KNX_MAX_device_param 31 #define MAX_KNXTX_CMNDS 5 /*********************************************************************************************\ @@ -214,7 +215,7 @@ enum WeekInMonthOptions {Last, First, Second, Third, Fourth}; enum DayOfTheWeekOptions {Sun=1, Mon, Tue, Wed, Thu, Fri, Sat}; enum MonthNamesOptions {Jan=1, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec}; enum HemisphereOptions {North, South}; -enum GetDateAndTimeOptions { DT_LOCAL, DT_UTC, DT_LOCALNOTZ, DT_DST, DT_STD, DT_RESTART, DT_ENERGY, DT_BOOTCOUNT }; +enum GetDateAndTimeOptions { DT_LOCAL, DT_UTC, DT_LOCALNOTZ, DT_DST, DT_STD, DT_RESTART, DT_ENERGY, DT_BOOTCOUNT, DT_LOCAL_MILLIS }; enum LoggingLevels {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE}; @@ -232,8 +233,9 @@ enum TopicOptions { CMND, STAT, TELE, nu1, RESULT_OR_CMND, RESULT_OR_STAT, RESUL enum ExecuteCommandPowerOptions { POWER_OFF, POWER_ON, POWER_TOGGLE, POWER_BLINK, POWER_BLINK_STOP, POWER_OFF_NO_STATE = 8, POWER_ON_NO_STATE, POWER_TOGGLE_NO_STATE, POWER_SHOW_STATE = 16 }; -enum SendKeyPowerOptions { POWER_HOLD = 3, POWER_INCREMENT = 4, POWER_INV = 5, POWER_CLEAR = 6, CLEAR_RETAIN = 9 }; +enum SendKeyPowerOptions { POWER_HOLD = 3, POWER_INCREMENT = 4, POWER_INV = 5, POWER_CLEAR = 6, POWER_RELEASE = 7, CLEAR_RETAIN = 9 }; enum SendKeyOptions { KEY_BUTTON, KEY_SWITCH }; +enum SendKeyMultiClick { SINGLE = 10, DOUBLE = 11, TRIPLE = 12, QUAD = 13, PENTA = 14}; enum PowerOnStateOptions { POWER_ALL_OFF, POWER_ALL_ON, POWER_ALL_SAVED_TOGGLE, POWER_ALL_SAVED, POWER_ALL_ALWAYS_ON, POWER_ALL_OFF_PULSETIME_ON }; @@ -291,13 +293,15 @@ enum SettingsTextIndex { SET_OTAURL, SET_MQTT_GRP_TOPIC2, SET_MQTT_GRP_TOPIC3, SET_MQTT_GRP_TOPIC4, SET_TEMPLATE_NAME, SET_DEV_GROUP_NAME1, SET_DEV_GROUP_NAME2, SET_DEV_GROUP_NAME3, SET_DEV_GROUP_NAME4, + SET_DEVICENAME, + SET_TELEGRAM_TOKEN, SET_TELEGRAM_CHATID, SET_MAX }; enum DevGroupMessageType { DGR_MSGTYP_FULL_STATUS, DGR_MSGTYP_PARTIAL_UPDATE, DGR_MSGTYP_UPDATE, DGR_MSGTYP_UPDATE_MORE_TO_COME, DGR_MSGTYP_UPDATE_DIRECT, DGR_MSGTYPE_UPDATE_COMMAND }; enum DevGroupMessageFlag { DGR_FLAG_RESET = 1, DGR_FLAG_STATUS_REQUEST = 2, DGR_FLAG_FULL_STATUS = 4, DGR_FLAG_ACK = 8, DGR_FLAG_MORE_TO_COME = 16, DGR_FLAG_DIRECT = 32, DGR_FLAG_ANNOUNCEMENT = 64 }; -enum DevGroupItem { DGR_ITEM_EOL, DGR_ITEM_STATUS, +enum DevGroupItem { DGR_ITEM_EOL, DGR_ITEM_STATUS, DGR_ITEM_FLAGS, DGR_ITEM_LIGHT_FADE, DGR_ITEM_LIGHT_SPEED, DGR_ITEM_LIGHT_BRI, DGR_ITEM_LIGHT_SCHEME, DGR_ITEM_LIGHT_FIXED_COLOR, DGR_ITEM_BRI_PRESET_LOW, DGR_ITEM_BRI_PRESET_HIGH, DGR_ITEM_BRI_POWER_ON, // Add new 8-bit items before this line @@ -305,21 +309,23 @@ enum DevGroupItem { DGR_ITEM_EOL, DGR_ITEM_STATUS, //DGR_ITEM_ANALOG1, DGR_ITEM_ANALOG2, DGR_ITEM_ANALOG3, DGR_ITEM_ANALOG4, DGR_ITEM_ANALOG5, // Add new 16-bit items before this line DGR_ITEM_LAST_16BIT, DGR_ITEM_MAX_16BIT = 127, - DGR_ITEM_POWER, DGR_ITEM_DIMMER_RANGE, + DGR_ITEM_POWER, // Add new 32-bit items before this line DGR_ITEM_LAST_32BIT, DGR_ITEM_MAX_32BIT = 191, + DGR_ITEM_EVENT, DGR_ITEM_COMMAND, // Add new string items before this line DGR_ITEM_LAST_STRING, DGR_ITEM_MAX_STRING = 223, DGR_ITEM_LIGHT_CHANNELS }; enum DevGroupShareItem { DGR_SHARE_POWER = 1, DGR_SHARE_LIGHT_BRI = 2, DGR_SHARE_LIGHT_FADE = 4, DGR_SHARE_LIGHT_SCHEME = 8, - DGR_SHARE_LIGHT_COLOR = 16, DGR_SHARE_DIMMER_SETTINGS = 32 }; + DGR_SHARE_LIGHT_COLOR = 16, DGR_SHARE_DIMMER_SETTINGS = 32, DGR_SHARE_EVENT = 64 }; enum CommandSource { SRC_IGNORE, SRC_MQTT, SRC_RESTART, SRC_BUTTON, SRC_SWITCH, SRC_BACKLOG, SRC_SERIAL, SRC_WEBGUI, SRC_WEBCOMMAND, SRC_WEBCONSOLE, SRC_PULSETIMER, SRC_TIMER, SRC_RULE, SRC_MAXPOWER, SRC_MAXENERGY, SRC_OVERTEMP, SRC_LIGHT, SRC_KNX, SRC_DISPLAY, SRC_WEMO, SRC_HUE, SRC_RETRY, SRC_REMOTE, SRC_SHUTTER, - SRC_MAX }; + SRC_THERMOSTAT, SRC_CHAT, SRC_MAX }; const char kCommandSource[] PROGMEM = "I|MQTT|Restart|Button|Switch|Backlog|Serial|WebGui|WebCommand|WebConsole|PulseTimer|" - "Timer|Rule|MaxPower|MaxEnergy|Overtemp|Light|Knx|Display|Wemo|Hue|Retry|Remote|Shutter"; + "Timer|Rule|MaxPower|MaxEnergy|Overtemp|Light|Knx|Display|Wemo|Hue|Retry|Remote|Shutter|" + "Thermostat|Chat"; const uint8_t kDefaultRfCode[9] PROGMEM = { 0x21, 0x16, 0x01, 0x0E, 0x03, 0x48, 0x2E, 0x1A, 0x00 }; @@ -331,7 +337,7 @@ enum TasmotaSerialConfig { TS_SERIAL_5O1, TS_SERIAL_6O1, TS_SERIAL_7O1, TS_SERIAL_8O1, TS_SERIAL_5O2, TS_SERIAL_6O2, TS_SERIAL_7O2, TS_SERIAL_8O2 }; -const uint8_t kTasmotaSerialConfig[] PROGMEM = { +const SerConfu8 kTasmotaSerialConfig[] PROGMEM = { SERIAL_5N1, SERIAL_6N1, SERIAL_7N1, SERIAL_8N1, SERIAL_5N2, SERIAL_6N2, SERIAL_7N2, SERIAL_8N2, SERIAL_5E1, SERIAL_6E1, SERIAL_7E1, SERIAL_8E1, @@ -340,4 +346,12 @@ const uint8_t kTasmotaSerialConfig[] PROGMEM = { SERIAL_5O2, SERIAL_6O2, SERIAL_7O2, SERIAL_8O2 }; +enum TuyaSupportedFunctions { TUYA_MCU_FUNC_NONE, TUYA_MCU_FUNC_SWT1 = 1, TUYA_MCU_FUNC_SWT2, TUYA_MCU_FUNC_SWT3, TUYA_MCU_FUNC_SWT4, + TUYA_MCU_FUNC_REL1 = 11, TUYA_MCU_FUNC_REL2, TUYA_MCU_FUNC_REL3, TUYA_MCU_FUNC_REL4, TUYA_MCU_FUNC_REL5, + TUYA_MCU_FUNC_REL6, TUYA_MCU_FUNC_REL7, TUYA_MCU_FUNC_REL8, TUYA_MCU_FUNC_DIMMER = 21, TUYA_MCU_FUNC_POWER = 31, + TUYA_MCU_FUNC_CURRENT, TUYA_MCU_FUNC_VOLTAGE, TUYA_MCU_FUNC_BATTERY_STATE, TUYA_MCU_FUNC_BATTERY_PERCENTAGE, + TUYA_MCU_FUNC_REL1_INV = 41, TUYA_MCU_FUNC_REL2_INV, TUYA_MCU_FUNC_REL3_INV, TUYA_MCU_FUNC_REL4_INV, TUYA_MCU_FUNC_REL5_INV, + TUYA_MCU_FUNC_REL6_INV, TUYA_MCU_FUNC_REL7_INV, TUYA_MCU_FUNC_REL8_INV, TUYA_MCU_FUNC_LOWPOWER_MODE = 51, TUYA_MCU_FUNC_LAST = 255 +}; + #endif // _TASMOTA_H_ diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index ec06f11a0..6dfcb2548 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -32,12 +32,13 @@ // Location specific includes #include // Arduino_Esp8266 version information (ARDUINO_ESP8266_RELEASE and ARDUINO_ESP8266_RELEASE_2_3_0) +#include "tasmota_compat.h" #include "tasmota_version.h" // Tasmota version information #include "tasmota.h" // Enumeration used in my_user_config.h #include "my_user_config.h" // Fixed user configurable options -#ifdef USE_MQTT_TLS +#ifdef USE_TLS #include // We need to include before "tasmota_globals.h" to take precedence over the BearSSL version in Arduino -#endif // USE_MQTT_TLS +#endif // USE_TLS #include "tasmota_globals.h" // Function prototypes and global configuration #include "i18n.h" // Language support configured by my_user_config.h #include "tasmota_template.h" // Hardware configuration @@ -110,22 +111,31 @@ uint32_t uptime = 0; // Counting every second until 42949 uint32_t loop_load_avg = 0; // Indicative loop load average uint32_t global_update = 0; // Timestamp of last global temperature and humidity update uint32_t web_log_index = 1; // Index in Web log buffer (should never be 0) -float global_temperature = 9999; // Provide a global temperature to be used by some sensors -float global_humidity = 0; // Provide a global humidity to be used by some sensors -float global_pressure = 0; // Provide a global pressure to be used by some sensors +float global_temperature_celsius = NAN; // Provide a global temperature to be used by some sensors +float global_humidity = 0.0f; // Provide a global humidity to be used by some sensors +float global_pressure_hpa = 0.0f; // Provide a global pressure to be used by some sensors uint16_t tele_period = 9999; // Tele period timer uint16_t blink_counter = 0; // Number of blink cycles uint16_t seriallog_timer = 0; // Timer to disable Seriallog uint16_t syslog_timer = 0; // Timer to re-enable syslog_level + +#ifdef ESP32 +uint16_t gpio_pin[MAX_GPIO_PIN] = { 0 }; // GPIO functions indexed by pin number +#endif // ESP32 + int16_t save_data_counter; // Counter and flag for config save to Flash RulesBitfield rules_flag; // Rule state flags (16 bits) uint8_t mqtt_cmnd_blocked = 0; // Ignore flag for publish command uint8_t mqtt_cmnd_blocked_reset = 0; // Count down to reset if needed uint8_t state_250mS = 0; // State 250msecond per second flag uint8_t latching_relay_pulse = 0; // Latching relay pulse timer -uint8_t sleep; // Current copy of Settings.sleep +uint8_t ssleep; // Current copy of Settings.sleep uint8_t blinkspeed = 1; // LED blink rate -uint8_t pin[GPIO_MAX]; // Possible pin configurations + +#ifdef ESP8266 +uint8_t gpio_pin[MAX_GPIO_PIN] = { 0 }; // GPIO functions indexed by pin number +#endif // ESP8266 - ESP32 + uint8_t active_device = 1; // Active device in ExecuteCommandPower uint8_t leds_present = 0; // Max number of LED supported uint8_t led_inverted = 0; // LED inverted flag (1 = (0 = On, 1 = Off)) @@ -141,12 +151,13 @@ uint8_t devices_present = 0; // Max number of devices supported uint8_t seriallog_level; // Current copy of Settings.seriallog_level uint8_t syslog_level; // Current copy of Settings.syslog_level uint8_t my_module_type; // Current copy of Settings.module or user template type -uint8_t my_adc0; // Active copy of Module ADC0 +uint8_t my_adc0 = 0; // Active copy of Module ADC0 uint8_t last_source = 0; // Last command source uint8_t shutters_present = 0; // Number of actual define shutters uint8_t prepped_loglevel = 0; // Delayed log level message //uint8_t mdns_delayed_start = 0; // mDNS delayed start -bool serial_local = false; // Handle serial locally; +bool serial_local = false; // Handle serial locally +bool serial_buffer_overrun = false; // Serial buffer overrun bool fallback_topic_flag = false; // Use Topic or FallbackTopic bool backlog_mutex = false; // Command backlog pending bool interlock_mutex = false; // Interlock power command pending @@ -187,9 +198,14 @@ char web_log[WEB_LOG_SIZE] = {'\0'}; // Web log buffer * Main \*********************************************************************************************/ -void setup(void) -{ - global_state.data = 3; // Init global state (wifi_down, mqtt_down) to solve possible network issues +void setup(void) { +#ifdef ESP32 +#ifdef DISABLE_ESP32_BROWNOUT + DisableBrownout(); // Workaround possible weak LDO resulting in brownout detection during Wifi connection +#endif +#endif + + global_state.data = 0xF; // Init global state (wifi_down, mqtt_down) to solve possible network issues RtcRebootLoad(); if (!RtcRebootValid()) { @@ -199,6 +215,7 @@ void setup(void) RtcRebootSave(); Serial.begin(APP_BAUDRATE); +// Serial.setRxBufferSize(INPUT_BUFFER_SIZE); // Default is 256 chars seriallog_level = LOG_LEVEL_INFO; // Allow specific serial messages until config loaded snprintf_P(my_version, sizeof(my_version), PSTR("%d.%d.%d"), VERSION >> 24 & 0xff, VERSION >> 16 & 0xff, VERSION >> 8 & 0xff); // Release version 6.3.0 @@ -226,7 +243,7 @@ void setup(void) syslog_level = Settings.syslog_level; stop_flash_rotate = Settings.flag.stop_flash_rotate; // SetOption12 - Switch between dynamic or fixed slot flash save location save_data_counter = Settings.save_data; - sleep = Settings.sleep; + ssleep = Settings.sleep; #ifndef USE_EMULATION Settings.flag2.emulation = 0; #else @@ -253,14 +270,16 @@ void setup(void) Settings.rule_enabled = 0; // Disable all rules } if (RtcReboot.fast_reboot_count > Settings.param[P_BOOT_LOOP_OFFSET] +3) { // Restarted 5 times - for (uint32_t i = 0; i < sizeof(Settings.my_gp); i++) { + for (uint32_t i = 0; i < ARRAY_SIZE(Settings.my_gp.io); i++) { Settings.my_gp.io[i] = GPIO_NONE; // Reset user defined GPIO disabling sensors } +#ifdef ESP8266 Settings.my_adc0 = ADC0_NONE; // Reset user defined ADC0 disabling sensors +#endif } if (RtcReboot.fast_reboot_count > Settings.param[P_BOOT_LOOP_OFFSET] +4) { // Restarted 6 times - Settings.module = SONOFF_BASIC; // Reset module to Sonoff Basic - // Settings.last_module = SONOFF_BASIC; + Settings.module = Settings.fallback_module; // Reset module to fallback module +// Settings.last_module = Settings.fallback_module; } AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION D_LOG_SOME_SETTINGS_RESET " (%d)"), RtcReboot.fast_reboot_count); } @@ -270,7 +289,7 @@ void setup(void) Format(mqtt_topic, SettingsText(SET_MQTT_TOPIC), sizeof(mqtt_topic)); if (strstr(SettingsText(SET_HOSTNAME), "%") != nullptr) { SettingsUpdateText(SET_HOSTNAME, WIFI_HOSTNAME); - snprintf_P(my_hostname, sizeof(my_hostname)-1, SettingsText(SET_HOSTNAME), mqtt_topic, ESP.getChipId() & 0x1FFF); + snprintf_P(my_hostname, sizeof(my_hostname)-1, SettingsText(SET_HOSTNAME), mqtt_topic, ESP_getChipId() & 0x1FFF); } else { snprintf_P(my_hostname, sizeof(my_hostname)-1, SettingsText(SET_HOSTNAME)); } @@ -284,7 +303,7 @@ void setup(void) SetPowerOnState(); - AddLog_P2(LOG_LEVEL_INFO, PSTR(D_PROJECT " %s %s " D_VERSION " %s%s-" ARDUINO_ESP8266_RELEASE), PROJECT, SettingsText(SET_FRIENDLYNAME1), my_version, my_image); + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_PROJECT " %s %s " D_VERSION " %s%s-" ARDUINO_CORE_RELEASE), PROJECT, SettingsText(SET_DEVICENAME), my_version, my_image); #ifdef FIRMWARE_MINIMAL AddLog_P2(LOG_LEVEL_INFO, PSTR(D_WARNING_MINIMAL_VERSION)); #endif // FIRMWARE_MINIMAL @@ -299,10 +318,14 @@ void setup(void) XdrvCall(FUNC_INIT); XsnsCall(FUNC_INIT); +#ifdef USE_SCRIPT + if (bitRead(Settings.rule_enabled, 0)) Run_Scripter(">BS",3,0); +#endif + + rules_flag.system_init = 1; } -void BacklogLoop(void) -{ +void BacklogLoop(void) { if (TimeReached(backlog_delay)) { if (!BACKLOG_EMPTY && !backlog_mutex) { #ifdef SUPPORT_IF_STATEMENT @@ -321,8 +344,18 @@ void BacklogLoop(void) } } -void loop(void) -{ +void SleepDelay(uint32_t mseconds) { + if (mseconds) { + for (uint32_t wait = 0; wait < mseconds; wait++) { + delay(1); + if (Serial.available()) { break; } // We need to service serial buffer ASAP as otherwise we get uart buffer overrun + } + } else { + delay(0); + } +} + +void loop(void) { uint32_t my_sleep = millis(); XdrvCall(FUNC_LOOP); @@ -332,9 +365,6 @@ void loop(void) ButtonLoop(); SwitchLoop(); -#ifdef ROTARY_V1 - RotaryLoop(); -#endif #ifdef USE_DEVICE_GROUPS DeviceGroupsLoop(); #endif // USE_DEVICE_GROUPS @@ -342,6 +372,9 @@ void loop(void) if (TimeReached(state_50msecond)) { SetNextTimeInterval(state_50msecond, 50); +#ifdef ROTARY_V1 + RotaryHandler(); +#endif // ROTARY_V1 XdrvCall(FUNC_EVERY_50_MSECOND); XsnsCall(FUNC_EVERY_50_MSECOND); } @@ -372,23 +405,23 @@ void loop(void) uint32_t my_activity = millis() - my_sleep; - if (Settings.flag3.sleep_normal) { // SetOption60 - Enable normal sleep instead of dynamic sleep - // yield(); // yield == delay(0), delay contains yield, auto yield in loop - delay(sleep); // https://github.com/esp8266/Arduino/issues/2021 + if (Settings.flag3.sleep_normal) { // SetOption60 - Enable normal sleep instead of dynamic sleep + // yield(); // yield == delay(0), delay contains yield, auto yield in loop + SleepDelay(ssleep); // https://github.com/esp8266/Arduino/issues/2021 } else { - if (my_activity < (uint32_t)sleep) { - delay((uint32_t)sleep - my_activity); // Provide time for background tasks like wifi + if (my_activity < (uint32_t)ssleep) { + SleepDelay((uint32_t)ssleep - my_activity); // Provide time for background tasks like wifi } else { - if (global_state.wifi_down) { - delay(my_activity /2); // If wifi down and my_activity > setoption36 then force loop delay to 1/3 of my_activity period + if (global_state.network_down) { + SleepDelay(my_activity /2); // If wifi down and my_activity > setoption36 then force loop delay to 1/3 of my_activity period } } } - if (!my_activity) { my_activity++; } // We cannot divide by 0 - uint32_t loop_delay = sleep; - if (!loop_delay) { loop_delay++; } // We cannot divide by 0 - uint32_t loops_per_second = 1000 / loop_delay; // We need to keep track of this many loops per second + if (!my_activity) { my_activity++; } // We cannot divide by 0 + uint32_t loop_delay = ssleep; + if (!loop_delay) { loop_delay++; } // We cannot divide by 0 + uint32_t loops_per_second = 1000 / loop_delay; // We need to keep track of this many loops per second uint32_t this_cycle_ratio = 100 * my_activity / loop_delay; loop_load_avg = loop_load_avg - (loop_load_avg / loops_per_second) + (this_cycle_ratio / loops_per_second); // Take away one loop average away and add the new one } diff --git a/tasmota/tasmota_ca.ino b/tasmota/tasmota_ca.ino index 8e75f891e..1db0a8c63 100644 --- a/tasmota/tasmota_ca.ino +++ b/tasmota/tasmota_ca.ino @@ -21,9 +21,8 @@ // Please use fingerprint validation instead // However, the CA are available below for future use if it appears to be useful -#ifdef USE_MQTT_TLS_CA_CERT +#if defined(USE_TLS) && defined(USE_MQTT_TLS_CA_CERT) -#ifndef USE_MQTT_AWS_IOT /*********************************************************************************************\ * LetsEncrypt IdenTrust DST Root CA X3 certificate, RSA 2048 bits SHA 256, valid until 20210417 * @@ -35,7 +34,7 @@ * remove "static" and add "PROGMEM" \*********************************************************************************************/ -static const unsigned char PROGMEM TA0_DN[] = { +static const unsigned char PROGMEM LetsEncrypt_DN[] = { 0x30, 0x4A, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x0D, 0x4C, 0x65, 0x74, 0x27, 0x73, 0x20, 0x45, 0x6E, 0x63, 0x72, @@ -45,7 +44,7 @@ static const unsigned char PROGMEM TA0_DN[] = { 0x79, 0x20, 0x58, 0x33 }; -static const unsigned char PROGMEM TA0_RSA_N[] = { +static const unsigned char PROGMEM LetsEncrypt_RSA_N[] = { 0x9C, 0xD3, 0x0C, 0xF0, 0x5A, 0xE5, 0x2E, 0x47, 0xB7, 0x72, 0x5D, 0x37, 0x83, 0xB3, 0x68, 0x63, 0x30, 0xEA, 0xD7, 0x35, 0x26, 0x19, 0x25, 0xE1, 0xBD, 0xBE, 0x35, 0xF1, 0x70, 0x92, 0x2F, 0xB7, 0xB8, 0x4B, 0x41, 0x05, @@ -70,27 +69,22 @@ static const unsigned char PROGMEM TA0_RSA_N[] = { 0xD8, 0x7D, 0xC3, 0x93 }; -static const unsigned char TA0_RSA_E[] = { +static const unsigned char LetsEncrypt_RSA_E[] = { 0x01, 0x00, 0x01 }; static const br_x509_trust_anchor PROGMEM LetsEncryptX3CrossSigned_TA = { - { (unsigned char *)TA0_DN, sizeof TA0_DN }, + { (unsigned char *)LetsEncrypt_DN, sizeof LetsEncrypt_DN }, BR_X509_TA_CA, { BR_KEYTYPE_RSA, { .rsa = { - (unsigned char *)TA0_RSA_N, sizeof TA0_RSA_N, - (unsigned char *)TA0_RSA_E, sizeof TA0_RSA_E, + (unsigned char *)LetsEncrypt_RSA_N, sizeof LetsEncrypt_RSA_N, + (unsigned char *)LetsEncrypt_RSA_E, sizeof LetsEncrypt_RSA_E, } } } }; -#define TAs_NUM 1 - -#endif // not USE_MQTT_AWS_IOT - -#ifdef USE_MQTT_AWS_IOT /*********************************************************************************************\ * Amazon Root CA, RSA 2048 bits SHA 256, valid until 20380117 * @@ -103,7 +97,7 @@ static const br_x509_trust_anchor PROGMEM LetsEncryptX3CrossSigned_TA = { \*********************************************************************************************/ -const unsigned char PROGMEM TA0_DN[] = { +const unsigned char PROGMEM AmazonRootCA1_DN[] = { 0x30, 0x39, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0F, 0x30, 0x0D, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x06, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x31, 0x19, 0x30, 0x17, @@ -111,7 +105,7 @@ const unsigned char PROGMEM TA0_DN[] = { 0x6E, 0x20, 0x52, 0x6F, 0x6F, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31 }; -const unsigned char PROGMEM TA0_RSA_N[] = { +const unsigned char PROGMEM AmazonRootCA1_RSA_N[] = { 0xB2, 0x78, 0x80, 0x71, 0xCA, 0x78, 0xD5, 0xE3, 0x71, 0xAF, 0x47, 0x80, 0x50, 0x74, 0x7D, 0x6E, 0xD8, 0xD7, 0x88, 0x76, 0xF4, 0x99, 0x68, 0xF7, 0x58, 0x21, 0x60, 0xF9, 0x74, 0x84, 0x01, 0x2F, 0xAC, 0x02, 0x2D, 0x86, @@ -136,24 +130,79 @@ const unsigned char PROGMEM TA0_RSA_N[] = { 0x9A, 0xC8, 0xAA, 0x0D }; -static const unsigned char PROGMEM TA0_RSA_E[] = { +static const unsigned char PROGMEM AmazonRootCA1_RSA_E[] = { 0x01, 0x00, 0x01 }; const br_x509_trust_anchor PROGMEM AmazonRootCA1_TA = { - { (unsigned char *)TA0_DN, sizeof TA0_DN }, + { (unsigned char *)AmazonRootCA1_DN, sizeof AmazonRootCA1_DN }, BR_X509_TA_CA, { BR_KEYTYPE_RSA, { .rsa = { - (unsigned char *)TA0_RSA_N, sizeof TA0_RSA_N, - (unsigned char *)TA0_RSA_E, sizeof TA0_RSA_E, + (unsigned char *)AmazonRootCA1_RSA_N, sizeof AmazonRootCA1_RSA_N, + (unsigned char *)AmazonRootCA1_RSA_E, sizeof AmazonRootCA1_RSA_E, } } } }; -#define TAs_NUM 1 +// we add a separate CA for telegram +/*********************************************************************************************\ + * GoDaddy Daddy Secure Certificate Authority - G2, RSA 2048 bits SHA 256, valid until 20220523 + * + * to convert do: "brssl ta GoDaddyCA.pem" + * then copy and paste below, chain the generic names to the same as below + * remove "static" and add "PROGMEM" +\*********************************************************************************************/ -#endif // USE_MQTT_AWS_IOT +const unsigned char GoDaddyCAG2_DN[] PROGMEM = { + 0x30, 0x3E, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, + 0x18, 0x44, 0x6F, 0x6D, 0x61, 0x69, 0x6E, 0x20, 0x43, 0x6F, 0x6E, 0x74, + 0x72, 0x6F, 0x6C, 0x20, 0x56, 0x61, 0x6C, 0x69, 0x64, 0x61, 0x74, 0x65, + 0x64, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, + 0x61, 0x70, 0x69, 0x2E, 0x74, 0x65, 0x6C, 0x65, 0x67, 0x72, 0x61, 0x6D, + 0x2E, 0x6F, 0x72, 0x67 +}; -#endif // USE_MQTT_TLS_CA_CERT +const unsigned char GoDaddyCAG2_RSA_N[] PROGMEM = { + 0xB4, 0xA3, 0x16, 0x9E, 0x5C, 0x57, 0xC9, 0x89, 0x65, 0xED, 0xEA, 0x78, + 0x0B, 0xAE, 0x8A, 0x58, 0x2F, 0xAE, 0x5A, 0xC8, 0x6E, 0x49, 0x8D, 0xFC, + 0x57, 0xA5, 0x98, 0x88, 0x78, 0x2E, 0x0B, 0x3C, 0x40, 0x3C, 0x21, 0x2E, + 0x9A, 0x94, 0x98, 0x33, 0xA7, 0xE3, 0x42, 0xA7, 0x85, 0xFA, 0xD0, 0x73, + 0x84, 0x01, 0x1C, 0x72, 0x39, 0x37, 0x23, 0xB5, 0x56, 0x1D, 0x43, 0xA5, + 0x71, 0x14, 0x08, 0x24, 0xA5, 0x39, 0xCC, 0xDE, 0x58, 0x53, 0x94, 0x8E, + 0x2A, 0x42, 0xA7, 0x4E, 0x2D, 0x07, 0x32, 0x9E, 0xBA, 0x8B, 0xD3, 0x2A, + 0xA9, 0x9E, 0xC0, 0xE3, 0xCE, 0x9A, 0x10, 0x96, 0x45, 0x58, 0x7A, 0xC7, + 0x1E, 0x45, 0x14, 0x23, 0x92, 0xBB, 0x54, 0x82, 0x88, 0x94, 0x49, 0xB6, + 0xBE, 0x81, 0x21, 0x00, 0x29, 0x6D, 0xC9, 0xCE, 0x8B, 0x39, 0x3A, 0xDC, + 0x35, 0x15, 0xD9, 0xEB, 0x47, 0x9C, 0xEF, 0xBA, 0x09, 0x0E, 0x16, 0xE4, + 0xD9, 0xEB, 0x72, 0x30, 0xFA, 0x49, 0xAB, 0x98, 0x31, 0x7C, 0xB3, 0xAC, + 0x2B, 0x29, 0x91, 0x87, 0x08, 0x41, 0x72, 0x5E, 0x35, 0xC7, 0x87, 0x04, + 0x22, 0xF5, 0x48, 0x76, 0x30, 0x6D, 0x88, 0xDF, 0xF2, 0xA5, 0x29, 0x13, + 0x70, 0xB3, 0x87, 0x02, 0xD5, 0x6B, 0x58, 0xB1, 0xE8, 0x73, 0xC7, 0xE4, + 0xEF, 0x79, 0x86, 0xA4, 0x07, 0x5F, 0x67, 0xB4, 0x79, 0x8D, 0xA4, 0x25, + 0x01, 0x82, 0x8C, 0xE0, 0x30, 0x17, 0xCB, 0x4B, 0x5C, 0xFB, 0xEB, 0x4C, + 0x12, 0x51, 0xB9, 0xC9, 0x04, 0x1F, 0x7E, 0xD2, 0xF8, 0xBA, 0xF5, 0x35, + 0x8D, 0x8A, 0x1C, 0x37, 0x82, 0xF0, 0x15, 0x73, 0x00, 0x6E, 0x3D, 0x1C, + 0x76, 0x8B, 0x01, 0x74, 0x81, 0x3D, 0xE4, 0x2C, 0xA7, 0xCC, 0x2F, 0x66, + 0xDC, 0x44, 0xA8, 0x27, 0x3F, 0xEA, 0xD0, 0xA7, 0xA8, 0xF1, 0xCB, 0xEA, + 0xDA, 0x07, 0x38, 0xBD +}; + +const unsigned char GoDaddyCAG2_RSA_E[] PROGMEM = { + 0x01, 0x00, 0x01 +}; + +const br_x509_trust_anchor GoDaddyCAG2_TA PROGMEM = { + { (unsigned char *)GoDaddyCAG2_DN, sizeof GoDaddyCAG2_DN }, + 0, + { + BR_KEYTYPE_RSA, + { .rsa = { + (unsigned char *)GoDaddyCAG2_RSA_N, sizeof GoDaddyCAG2_RSA_N, + (unsigned char *)GoDaddyCAG2_RSA_E, sizeof GoDaddyCAG2_RSA_E, + } } + } +}; + +#endif // defined(USE_TLS) && defined(USE_MQTT_TLS_CA_CERT) diff --git a/tasmota/tasmota_compat.h b/tasmota/tasmota_compat.h new file mode 100644 index 000000000..598ca5619 --- /dev/null +++ b/tasmota/tasmota_compat.h @@ -0,0 +1,18 @@ +#pragma once + +#ifdef ESP32 +#include +// Modul +#undef MODULE +#define MODULE WEMOS // [Module] Select default model +#endif // ESP32 + +#ifdef ESP8266 +// ESP8266 +// +// UDP +#define PortUdp_write(p,n) PortUdp.write(p, n) +// +// Serial minimal type to hold the config +#define SerConfu8 uint8_t +#endif // ESP8266 diff --git a/tasmota/tasmota_configurations.h b/tasmota/tasmota_configurations.h index d8d2bfde0..58d08d543 100644 --- a/tasmota/tasmota_configurations.h +++ b/tasmota/tasmota_configurations.h @@ -33,7 +33,7 @@ #undef USE_DISCOVERY // Disable mDNS (+8k code or +23.5k code with core 2_5_x, +0.3k mem) // -- Optional modules ---------------------------- -//#define ROTARY_V1 // Add support for MI Desk Lamp +#define ROTARY_V1 // Add support for Rotary Encoder as used in MI Desk Lamp #define USE_SONOFF_RF // Add support for Sonoff Rf Bridge (+3k2 code) #define USE_RF_FLASH // Add support for flashing the EFM8BB1 chip on the Sonoff RF Bridge. C2CK must be connected to GPIO4, C2D to GPIO5 on the PCB (+2k7 code) #define USE_SONOFF_SC // Add support for Sonoff Sc (+1k1 code) @@ -50,7 +50,7 @@ #define USE_DEEPSLEEP // Add support for deepsleep (+1k code) #undef USE_EXS_DIMMER // Disable support for EX-Store WiFi Dimmer //#define USE_HOTPLUG // Add support for sensor HotPlug -#undef USE_DEVICE_GROUPS // Disable support for device groups (+5k6 code) +//#undef USE_DEVICE_GROUPS // Disable support for device groups (+5k6 code) #undef USE_PWM_DIMMER // Disable support for MJ-SD01/acenx/NTONPOWER PWM dimmers (+4k5 code) #undef USE_KEELOQ // Disable support for Jarolift rollers by Keeloq algorithm (+4k5 code) #undef USE_SONOFF_D1 // DIsable support for Sonoff D1 Dimmer (+0k7 code) @@ -70,6 +70,7 @@ #define USE_SM2135 // Add support for SM2135 RGBCW led control as used in Action LSC (+0k6 code) #define USE_SONOFF_L1 // Add support for Sonoff L1 led control #define USE_ELECTRIQ_MOODL // Add support for ElectriQ iQ-wifiMOODL RGBW LED controller +#define USE_LIGHT_PALETTE // Add support for color palette (+0k9 code) #define USE_COUNTER // Enable counters #undef USE_ADC_VCC // Add Analog input on selected devices @@ -82,6 +83,8 @@ #define USE_BME680 // Add additional support for BME680 sensor using Bosch BME680 library (+4k code) #define USE_BH1750 // Add I2C code for BH1750 sensor (+0k5 code) #define USE_VEML6070 // Add I2C code for VEML6070 sensor (+0k5 code) +// #define USE_VEML6075 // Add I2C code for VEML6075 UVA/UVB/UVINDEX Sensor (+2k1 code) +// #define USE_VEML7700 // Add I2C code for VEML7700 Ambient Light sensor (+4k5 code) #define USE_ADS1115 // Add I2C code for ADS1115 16 bit A/D converter based on Adafruit ADS1x15 library (no library needed) (+0k7 code) #define USE_INA219 // Add I2C code for INA219 Low voltage and current sensor (+1k code) //#define USE_INA226 // Enable INA226 (I2C address 0x40, 0x41 0x44 or 0x45) Low voltage and current sensor (+2k3 code) @@ -123,6 +126,7 @@ #define WEMOS_MOTOR_V1_FREQ 1000 // Default frequency //#define USE_HDC1080 // Enable HDC1080 temperature/humidity sensor #define USE_IAQ // [I2cDriver46] Enable iAQ-core air quality sensor (I2C address 0x5a) (+0k6 code) +#define USE_AS3935 // [I2cDriver48] Enable AS3935 Franklin Lightning Sensor (I2C address 0x03) (+5k4 code) #define USE_MHZ19 // Add support for MH-Z19 CO2 sensor (+2k code) #define USE_SENSEAIR // Add support for SenseAir K30, K70 and S8 CO2 sensor (+2k3 code) @@ -141,11 +145,17 @@ #define MP3_VOLUME 10 // Set the startup volume on init, the range can be 0..30(max) //#define USE_AZ7798 // Add support for AZ-Instrument 7798 CO2 datalogger #define USE_PN532_HSU // Add support for PN532 using HSU (Serial) interface (+1k8 code, 140 bytes mem) +//#define USE_ZIGBEE // Enable serial communication with Zigbee CC2530 flashed with ZNP #define USE_RDM6300 // Add support for RDM6300 125kHz RFID Reader (+0k8) #define USE_IBEACON // Add support for bluetooth LE passive scan of ibeacon devices (uses HM17 module) //#define USE_GPS // Add support for GPS and NTP Server for becoming Stratus 1 Time Source (+ 3.1kb flash, +132 bytes RAM) -#define USE_HM10 // Add support for HM-10 as a BLE-bridge for the LYWSD03 (+5k1 code) +#define USE_HM10 // (ESP8266 only) Add support for HM-10 as a BLE-bridge for the LYWSD03 (+5k1 code) +//#define USE_MI_ESP32 // (ESP32 only) Add support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) #define USE_HRXL // Add support for MaxBotix HRXL-MaxSonar ultrasonic range finders (+0k7) +//#define USE_TASMOTA_CLIENT // Add support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) +//#define USE_OPENTHERM // Add support for OpenTherm (+15k code) +//#define USE_MCP9808 // Add support for MCP9808 temperature sensor (+0k9 code) +//#define USE_HP303B // Add support for HP303B temperature and pressure sensor (I2C address 0x76 or 0x77) (+6k2 code) #define USE_ENERGY_SENSOR // Add energy sensors (-14k code) #define USE_PZEM004T // Add support for PZEM004T Energy monitor (+2k code) @@ -158,6 +168,7 @@ #define USE_DDSU666 // Add support for Chint DDSU666 Modbus energy monitor (+0k6 code) //#define USE_SOLAX_X1 // Add support for Solax X1 series Modbus log info (+3k1 code) //#define USE_LE01MR // Add support for F&F LE-01MR modbus energy meter (+2k code) +//#define USE_TELEINFO // Add support for French Energy Provider metering telemetry (+5k2 code, +168 RAM + SmartMeter LinkedList Values RAM) #define USE_DHT // Add support for DHT11, AM2301 (DHT21, DHT22, AM2302, AM2321) and SI7021 Temperature and Humidity sensor #define USE_MAX31855 // Add support for MAX31855 K-Type thermocouple sensor using softSPI @@ -165,21 +176,21 @@ #define USE_IR_REMOTE // Send IR remote commands using library IRremoteESP8266 and ArduinoJson (+4k code, 0k3 mem, 48 iram) #define USE_IR_RECEIVE // Support for IR receiver (+5k5 code, 264 iram) -//#define USE_ZIGBEE // Enable serial communication with Zigbee CC2530 flashed with ZNP - +#define USE_LMT01 // Add support for TI LMT01 temperature sensor, count pulses on single GPIO (+0k5 code) #define USE_SR04 // Add support for HC-SR04 ultrasonic devices (+1k code) #define USE_TM1638 // Add support for TM1638 switches copying Switch1 .. Switch8 (+1k code) #define USE_HX711 // Add support for HX711 load cell (+1k5 code) //#define USE_HX711_GUI // Add optional web GUI to HX711 as scale (+1k8 code) //#define USE_TX20_WIND_SENSOR // Add support for La Crosse TX20 anemometer (+2k6/0k8 code) //#define USE_TX23_WIND_SENSOR // Add support for La Crosse TX23 anemometer (+2k7/1k code) +//#define USE_WINDMETER // Add support for analog anemometer (+2k2 code) #define USE_RC_SWITCH // Add support for RF transceiver using library RcSwitch (+2k7 code, 460 iram) #define USE_RF_SENSOR // Add support for RF sensor receiver (434MHz or 868MHz) (+0k8 code) // #define USE_THEO_V2 // Add support for decoding Theo V2 sensors as documented on https://sidweb.nl using 434MHz RF sensor receiver (+1k4 code) #define USE_ALECTO_V2 // Add support for decoding Alecto V2 sensors like ACH2010, WS3000 and DKW2012 using 868MHz RF sensor receiver (+1k7 code) #define USE_HRE // Add support for Badger HR-E Water Meter (+1k4 code) //#define USE_A4988_STEPPER // Add support for A4988/DRV8825 stepper-motor-driver-circuit (+10k5 code) -//#define USE_ARDUINO_SLAVE // Add support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) +//#define USE_THERMOSTAT // Add support for Thermostat #undef DEBUG_THEO // Disable debug code #undef USE_DEBUG_DRIVER // Disable debug code #endif // FIRMWARE_SENSORS @@ -255,6 +266,8 @@ #undef USE_DDSU666 // Disable support for Chint DDSU666 Modbus energy monitor (+0k6 code) #undef USE_SOLAX_X1 // Disable support for Solax X1 series Modbus log info (+3k1 code) #undef USE_LE01MR // Disable support for F&F LE-01MR Modbus energy meter (+2k code) + #undef USE_TELEINFO // Disable support for French Energy Provider metering telemetry + #define USE_I2C // I2C using library wire (+10k code, 0k2 mem, 124 iram) #define USE_DISPLAY // Add I2C Display Support (+2k code) @@ -262,6 +275,7 @@ #define USE_DISPLAY_LCD // [DisplayModel 1] Enable Lcd display (I2C addresses 0x27 and 0x3F) (+6k code) #define USE_DISPLAY_SSD1306 // [DisplayModel 2] Enable SSD1306 Oled 128x64 display (I2C addresses 0x3C and 0x3D) (+16k code) #define USE_DISPLAY_MATRIX // [DisplayModel 3] Enable 8x8 Matrix display (I2C adresseses see below) (+11k code) + #define USE_DISPLAY_SEVENSEG // [DisplayModel 11] [I2cDriver47] Enable sevenseg display (I2C addresses 0x70 - 0x77) (<+11k code) #define USE_DISPLAY_SH1106 // [DisplayModel 7] Enable SH1106 Oled 128x64 display (I2C addresses 0x3C and 0x3D) #define USE_SPI // Hardware SPI using GPIO12(MISO), GPIO13(MOSI) and GPIO14(CLK) in addition to two user selectable GPIOs(CS and DC) @@ -330,7 +344,12 @@ #undef USE_SM16716 // Disable support for SM16716 RGB LED controller (+0k7 code) #undef USE_SM2135 // Disable support for SM2135 RGBCW led control as used in Action LSC (+0k6 code) #undef USE_SONOFF_L1 // Disable support for Sonoff L1 led control -#undef USE_ELECTRIQ_MOODL // Add support for ElectriQ iQ-wifiMOODL RGBW LED controller +#undef USE_ELECTRIQ_MOODL // Disable support for ElectriQ iQ-wifiMOODL RGBW LED controller +#undef USE_LIGHT_PALETTE // Disable support for color palette (+0k9 code) + +#undef USE_COUNTER // Disable counters +#define USE_ADC_VCC // Display Vcc in Power status. Disable for use as Analog input on selected devices +#undef USE_DS18x20 // Disable DS18x20 sensor #undef USE_ENERGY_SENSOR // Disable energy sensors (-14k code) #undef USE_PZEM004T // Disable PZEM004T energy sensor @@ -343,6 +362,7 @@ #undef USE_DDSU666 // Disable support for Chint DDSU666 Modbus energy monitor (+0k6 code) #undef USE_SOLAX_X1 // Disable support for Solax X1 series Modbus log info (+3k1 code) #undef USE_LE01MR // Disable support for F&F LE-01MR Modbus energy meter (+2k code) + #undef USE_TELEINFO // Disable support for French Energy Provider metering telemetry //#undef USE_DS18x20 // Disable support for DS18x20 sensors with id sort, single scan and read retry (+1k3 code) @@ -360,13 +380,17 @@ #undef USE_MP3_PLAYER // Disable DFPlayer Mini MP3 Player RB-DFR-562 commands: play, volume and stop #undef USE_AZ7798 // Disable support for AZ-Instrument 7798 CO2 datalogger #undef USE_PN532_HSU // Disable support for PN532 using HSU (Serial) interface (+1k8 code, 140 bytes mem) +#undef USE_ZIGBEE // Disable serial communication with Zigbee CC2530 flashed with ZNP #undef USE_RDM6300 // Disable support for RDM6300 125kHz RFID Reader (+0k8) #undef USE_IBEACON // Disable support for bluetooth LE passive scan of ibeacon devices (uses HM17 module) #undef USE_GPS // Disable support for GPS and NTP Server for becoming Stratus 1 Time Source (+ 3.1kb flash, +132 bytes RAM) -#undef USE_HM10 // Disable support for HM-10 as a BLE-bridge for the LYWSD03 (+5k1 code) +#undef USE_HM10 // (ESP8266 only) Disable support for HM-10 as a BLE-bridge for the LYWSD03 (+5k1 code) +#undef USE_MI_ESP32 // (ESP32 only) Disable support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) #undef USE_HRXL // Disable support for MaxBotix HRXL-MaxSonar ultrasonic range finders (+0k7) +#undef USE_TASMOTA_CLIENT // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) +#undef USE_OPENTHERM // Disable support for OpenTherm (+15k code) -//#define USE_DHT // Add support for DHT11, AM2301 (DHT21, DHT22, AM2302, AM2321) and SI7021 Temperature and Humidity sensor +#undef USE_DHT // Disable support for DHT11, AM2301 (DHT21, DHT22, AM2302, AM2321) and SI7021 Temperature and Humidity sensor #undef USE_MAX31855 // Disable MAX31855 K-Type thermocouple sensor using softSPI #undef USE_MAX31865 // Disable support for MAX31865 RTD sensors using softSPI #undef USE_SR04 // Disable support for for HC-SR04 ultrasonic devices @@ -374,11 +398,12 @@ #undef USE_HX711 // Disable support for HX711 load cell #undef USE_TX20_WIND_SENSOR // Disable support for La Crosse TX20 anemometer #undef USE_TX23_WIND_SENSOR // Disable support for La Crosse TX23 anemometer +#undef USE_WINDMETER // Disable support for analog anemometer (+2k2 code) #undef USE_RC_SWITCH // Disable support for RF transceiver using library RcSwitch #undef USE_RF_SENSOR // Disable support for RF sensor receiver (434MHz or 868MHz) (+0k8 code) #undef USE_HRE // Disable support for Badger HR-E Water Meter (+1k4 code) #undef USE_A4988_STEPPER // Disable support for A4988_Stepper -#undef USE_ARDUINO_SLAVE // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) +#undef USE_THERMOSTAT // Disable support for Thermostat #undef DEBUG_THEO // Disable debug code #undef USE_DEBUG_DRIVER // Disable debug code #endif // FIRMWARE_IR @@ -442,7 +467,8 @@ #undef USE_SM16716 // Disable support for SM16716 RGB LED controller (+0k7 code) #undef USE_SM2135 // Disable support for SM2135 RGBCW led control as used in Action LSC (+0k6 code) #undef USE_SONOFF_L1 // Disable support for Sonoff L1 led control -#undef USE_ELECTRIQ_MOODL // Add support for ElectriQ iQ-wifiMOODL RGBW LED controller +#undef USE_ELECTRIQ_MOODL // Disable support for ElectriQ iQ-wifiMOODL RGBW LED controller +#undef USE_LIGHT_PALETTE // Disable support for color palette (+0k9 code) #undef USE_COUNTER // Disable counters #define USE_ADC_VCC // Display Vcc in Power status. Disable for use as Analog input on selected devices @@ -459,11 +485,15 @@ #undef USE_MP3_PLAYER // Disable DFPlayer Mini MP3 Player RB-DFR-562 commands: play, volume and stop #undef USE_AZ7798 // Disable support for AZ-Instrument 7798 CO2 datalogger #undef USE_PN532_HSU // Disable support for PN532 using HSU (Serial) interface (+1k8 code, 140 bytes mem) +#undef USE_ZIGBEE // Disable serial communication with Zigbee CC2530 flashed with ZNP #undef USE_RDM6300 // Disable support for RDM6300 125kHz RFID Reader (+0k8) #undef USE_IBEACON // Disable support for bluetooth LE passive scan of ibeacon devices (uses HM17 module) #undef USE_GPS // Disable support for GPS and NTP Server for becoming Stratus 1 Time Source (+ 3.1kb flash, +132 bytes RAM) -#undef USE_HM10 // Disable support for HM-10 as a BLE-bridge for the LYWSD03 (+5k1 code) +#undef USE_HM10 // (ESP8266 only) Disable support for HM-10 as a BLE-bridge for the LYWSD03 (+5k1 code) +#undef USE_MI_ESP32 // (ESP32 only) Disable support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) #undef USE_HRXL // Disable support for MaxBotix HRXL-MaxSonar ultrasonic range finders (+0k7) +#undef USE_TASMOTA_CLIENT // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) +#undef USE_OPENTHERM // Disable support for OpenTherm (+15k code) //#undef USE_ENERGY_SENSOR // Disable energy sensors #undef USE_PZEM004T // Disable PZEM004T energy sensor @@ -476,27 +506,28 @@ #undef USE_DDSU666 // Disable support for Chint DDSU666 Modbus energy monitor (+0k6 code) #undef USE_SOLAX_X1 // Disable support for Solax X1 series Modbus log info (+3k1 code) #undef USE_LE01MR // Disable support for F&F LE-01MR Modbus energy meter (+2k code) +#undef USE_TELEINFO // Disable support for French Energy Provider metering telemetry + #undef USE_DHT // Disable support for DHT11, AM2301 (DHT21, DHT22, AM2302, AM2321) and SI7021 Temperature and Humidity sensor #undef USE_MAX31855 // Disable MAX31855 K-Type thermocouple sensor using softSPI #undef USE_MAX31865 // Disable support for MAX31865 RTD sensors using softSPI #undef USE_IR_REMOTE // Disable IR driver -#undef USE_ZIGBEE // Disable serial communication with Zigbee CC2530 flashed with ZNP - #undef USE_SR04 // Disable support for for HC-SR04 ultrasonic devices #undef USE_TM1638 // Disable support for TM1638 switches copying Switch1 .. Switch8 #undef USE_HX711 // Disable support for HX711 load cell #undef USE_TX20_WIND_SENSOR // Disable support for La Crosse TX20 anemometer #undef USE_TX23_WIND_SENSOR // Disable support for La Crosse TX23 anemometer +#undef USE_WINDMETER // Disable support for analog anemometer (+2k2 code) #undef USE_RC_SWITCH // Disable support for RF transceiver using library RcSwitch #undef USE_RF_SENSOR // Disable support for RF sensor receiver (434MHz or 868MHz) (+0k8 code) #undef USE_HRE // Disable support for Badger HR-E Water Meter (+1k4 code) #undef USE_A4988_STEPPER // Disable support for A4988_Stepper -#undef USE_ARDUINO_SLAVE // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) +#undef USE_THERMOSTAT // Disable support for Thermostat #undef DEBUG_THEO // Disable debug code #undef USE_DEBUG_DRIVER // Disable debug code -#endif // FIRMWARE_BASIC +#endif // FIRMWARE_LITE /*********************************************************************************************\ * [tasmota-minimal.bin] @@ -561,7 +592,8 @@ #undef USE_SM16716 // Disable support for SM16716 RGB LED controller (+0k7 code) #undef USE_SM2135 // Disable support for SM2135 RGBCW led control as used in Action LSC (+0k6 code) #undef USE_SONOFF_L1 // Disable support for Sonoff L1 led control -#undef USE_ELECTRIQ_MOODL // Add support for ElectriQ iQ-wifiMOODL RGBW LED controller +#undef USE_ELECTRIQ_MOODL // Disable support for ElectriQ iQ-wifiMOODL RGBW LED controller +#undef USE_LIGHT_PALETTE // Disable support for color palette (+0k9 code) #undef USE_COUNTER // Disable counters #define USE_ADC_VCC // Display Vcc in Power status. Disable for use as Analog input on selected devices @@ -580,11 +612,15 @@ #undef USE_MP3_PLAYER // Disable DFPlayer Mini MP3 Player RB-DFR-562 commands: play, volume and stop #undef USE_AZ7798 // Disable support for AZ-Instrument 7798 CO2 datalogger #undef USE_PN532_HSU // Disable support for PN532 using HSU (Serial) interface (+1k8 code, 140 bytes mem) +#undef USE_ZIGBEE // Disable serial communication with Zigbee CC2530 flashed with ZNP #undef USE_RDM6300 // Disable support for RDM6300 125kHz RFID Reader (+0k8) #undef USE_IBEACON // Disable support for bluetooth LE passive scan of ibeacon devices (uses HM17 module) #undef USE_GPS // Disable support for GPS and NTP Server for becoming Stratus 1 Time Source (+ 3.1kb flash, +132 bytes RAM) -#undef USE_HM10 // Disable support for HM-10 as a BLE-bridge for the LYWSD03 (+5k1 code) +#undef USE_HM10 // (ESP8266 only) Disable support for HM-10 as a BLE-bridge for the LYWSD03 (+5k1 code) +#undef USE_MI_ESP32 // (ESP32 only) Disable support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash) #undef USE_HRXL // Disable support for MaxBotix HRXL-MaxSonar ultrasonic range finders (+0k7) +#undef USE_TASMOTA_CLIENT // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) +#undef USE_OPENTHERM // Disable support for OpenTherm (+15k code) #undef USE_ENERGY_SENSOR // Disable energy sensors #undef USE_PZEM004T // Disable PZEM004T energy sensor @@ -597,6 +633,7 @@ #undef USE_DDSU666 // Disable support for Chint DDSU666 Modbus energy monitor (+0k6 code) #undef USE_SOLAX_X1 // Disable support for Solax X1 series Modbus log info (+3k1 code) #undef USE_LE01MR // Disable support for F&F LE-01MR Modbus energy meter (+2k code) +#undef USE_TELEINFO // Disable support for French Energy Provider metering telemetry #undef USE_DHT // Disable support for DHT11, AM2301 (DHT21, DHT22, AM2302, AM2321) and SI7021 Temperature and Humidity sensor #undef USE_MAX31855 // Disable MAX31855 K-Type thermocouple sensor using softSPI @@ -607,13 +644,18 @@ #undef USE_HX711 // Disable support for HX711 load cell #undef USE_TX20_WIND_SENSOR // Disable support for La Crosse TX20 anemometer #undef USE_TX23_WIND_SENSOR // Disable support for La Crosse TX23 anemometer +#undef USE_WINDMETER // Disable support for analog anemometer (+2k2 code) #undef USE_RC_SWITCH // Disable support for RF transceiver using library RcSwitch #undef USE_RF_SENSOR // Disable support for RF sensor receiver (434MHz or 868MHz) (+0k8 code) #undef USE_HRE // Disable support for Badger HR-E Water Meter (+1k4 code) #undef USE_A4988_STEPPER // Disable support for A4988_Stepper -#undef USE_ARDUINO_SLAVE // Disable support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) +#undef USE_THERMOSTAT // Disable support for Thermostat #undef DEBUG_THEO // Disable debug code #undef USE_DEBUG_DRIVER // Disable debug code #endif // FIRMWARE_MINIMAL +#ifdef ESP32 +#include "tasmota_configurations_ESP32.h" +#endif // ESP32 + #endif // _TASMOTA_CONFIGURATIONS_H_ diff --git a/tasmota/tasmota_configurations_ESP32.h b/tasmota/tasmota_configurations_ESP32.h new file mode 100644 index 000000000..b551c78ef --- /dev/null +++ b/tasmota/tasmota_configurations_ESP32.h @@ -0,0 +1,40 @@ +/* + tasmota_configurations_ESP32.h - ESP32 only Configurations for Tasmota + + Copyright (C) 2020 Theo Arends + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef _TASMOTA_CONFIGURATIONS_ESP32_H_ +#define _TASMOTA_CONFIGURATIONS_ESP32_H_ + +#ifdef ESP32 + +/*********************************************************************************************\ + * [tasmota32-webcam.bin] + * Provide an image with useful supported sensors enabled +\*********************************************************************************************/ + +#ifdef FIRMWARE_WEBCAM + +#undef CODE_IMAGE_STR +#define CODE_IMAGE_STR "webcam" + +#define USE_WEBCAM +#endif // FIRMWARE_WEBCAM + +#endif // ESP32 + +#endif // _TASMOTA_CONFIGURATIONS_ESP32_H_ diff --git a/tasmota/tasmota_globals.h b/tasmota/tasmota_globals.h index d05db0efd..42e63f206 100644 --- a/tasmota/tasmota_globals.h +++ b/tasmota/tasmota_globals.h @@ -42,6 +42,18 @@ void DomoticzTempHumPressureSensor(float temp, float hum, float baro = -1); char* ToHex_P(const unsigned char * in, size_t insz, char * out, size_t outsz, char inbetween = '\0'); extern "C" void custom_crash_callback(struct rst_info * rst_info, uint32_t stack, uint32_t stack_end); extern "C" void resetPins(); +extern "C" int startWaveformClockCycles(uint8_t pin, uint32_t highCcys, uint32_t lowCcys, + uint32_t runTimeCcys, int8_t alignPhase, uint32_t phaseOffsetCcys, bool autoPwm); + +#ifdef ESP32 + +#ifdef USE_ETHERNET +IPAddress EthernetLocalIP(void); +char* EthernetHostname(void); +String EthernetMacAddress(void); +#endif + +#endif // ESP32 /*********************************************************************************************\ * Preconfigured configurations @@ -53,19 +65,24 @@ extern "C" void resetPins(); * Mandatory defines satisfying disabled defines \*********************************************************************************************/ -#ifndef MODULE -#define MODULE SONOFF_BASIC // [Module] Select default model -#endif - #ifdef USE_EMULATION_HUE #define USE_EMULATION #endif #ifdef USE_EMULATION_WEMO #define USE_EMULATION #endif -#ifdef USE_DEVICE_GROUPS -#define USE_EMULATION + +// Convert legacy slave to client +#ifdef USE_TASMOTA_SLAVE +#define USE_TASMOTA_CLIENT #endif +#ifdef USE_TASMOTA_SLAVE_FLASH_SPEED +#define USE_TASMOTA_CLIENT_FLASH_SPEED USE_TASMOTA_SLAVE_FLASH_SPEED +#endif +#ifdef USE_TASMOTA_SLAVE_SERIAL_SPEED +#define USE_TASMOTA_CLIENT_SERIAL_SPEED USE_TASMOTA_SLAVE_SERIAL_SPEED +#endif + // See https://github.com/esp8266/Arduino/pull/4889 #undef NO_EXTRA_4K_HEAP // Allocate 4k heap for WPS in ESP8166/Arduino core v2.4.2 (was always allocated in previous versions) @@ -73,6 +90,22 @@ extern "C" void resetPins(); #undef USE_RF_FLASH // Disable RF firmware flash when Sonoff Rf is disabled #endif +#ifndef APP_INTERLOCK_MODE +#define APP_INTERLOCK_MODE false // [Interlock] Relay interlock mode +#endif +#ifndef APP_INTERLOCK_GROUP_1 +#define APP_INTERLOCK_GROUP_1 0xFF // [Interlock] Relay bitmask for interlock group 1 - Legacy support using all relays in one interlock group +#endif +#ifndef APP_INTERLOCK_GROUP_2 +#define APP_INTERLOCK_GROUP_2 0x00 // [Interlock] Relay bitmask for interlock group 2 +#endif +#ifndef APP_INTERLOCK_GROUP_3 +#define APP_INTERLOCK_GROUP_3 0x00 // [Interlock] Relay bitmask for interlock group 3 +#endif +#ifndef APP_INTERLOCK_GROUP_4 +#define APP_INTERLOCK_GROUP_4 0x00 // [Interlock] Relay bitmask for interlock group 4 +#endif + #ifndef SWITCH_MODE #define SWITCH_MODE TOGGLE // TOGGLE, FOLLOW or FOLLOW_INV (the wall switch state) #endif @@ -81,8 +114,8 @@ extern "C" void resetPins(); // Set an all-zeros default fingerprint to activate auto-learning on first connection (AWS IoT) #define MQTT_FINGERPRINT1 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" #endif -#ifndef MQTT_FINGERPRINT2 -#define MQTT_FINGERPRINT2 "A5 02 FF 13 99 9F 8B 39 8E F1 83 4F 11 23 65 0B 32 36 FC 07" +#ifndef MQTT_FINGERPRINT2 // SHA1('') +#define MQTT_FINGERPRINT2 "DA 39 A3 EE 5E 6B 4B 0D 32 55 BF EF 95 60 18 90 AF D8 07 09" #endif #ifndef WS2812_LEDS @@ -95,7 +128,7 @@ extern "C" void resetPins(); const uint16_t WEB_LOG_SIZE = 4000; // Max number of characters in weblog #endif -#if defined(USE_MQTT_TLS) && defined(ARDUINO_ESP8266_RELEASE_2_3_0) +#if defined(USE_TLS) && defined(ARDUINO_ESP8266_RELEASE_2_3_0) #error "TLS is no more supported on Core 2.3.0, use 2.4.2 or higher." #endif @@ -117,19 +150,10 @@ extern "C" void resetPins(); #define MESSZ (MQTT_MAX_PACKET_SIZE -TOPSZ -7) // Max number of characters in JSON message string #endif -#ifndef ARDUINO_ESP8266_RELEASE -#define ARDUINO_ESP8266_RELEASE "STAGE" -#endif - -#ifdef USE_PWM_DIMMER_REMOTE -#ifdef USE_PWM_DIMMER #ifndef USE_DEVICE_GROUPS -#define USE_DEVICE_GROUPS -#endif // USE_DEVICE_GROUPS -#else // USE_PWM_DIMMER #undef USE_PWM_DIMMER_REMOTE -#endif // USE_PWM_DIMMER -#endif // USE_PWM_DIMMER_REMOTE +#undef USE_DGR_LIGHT_SEQUENCE +#endif // USE_DEVICE_GROUPS #ifndef DOMOTICZ_UPDATE_TIMER #define DOMOTICZ_UPDATE_TIMER 0 // [DomoticzUpdateTimer] Send relay status (0 = disable, 1 - 3600 seconds) (Optional) @@ -284,6 +308,49 @@ const char kWebColors[] PROGMEM = COLOR_BUTTON_TEXT "|" COLOR_BUTTON "|" COLOR_BUTTON_HOVER "|" COLOR_BUTTON_RESET "|" COLOR_BUTTON_RESET_HOVER "|" COLOR_BUTTON_SAVE "|" COLOR_BUTTON_SAVE_HOVER "|" COLOR_TIMER_TAB_TEXT "|" COLOR_TIMER_TAB_BACKGROUND "|" COLOR_TITLE_TEXT; +/*********************************************************************************************\ + * ESP8266 vs ESP32 related parameters +\*********************************************************************************************/ + +#ifdef ESP8266 + +#ifndef MODULE +#define MODULE SONOFF_BASIC // [Module] Select default model +#endif +#ifndef FALLBACK_MODULE +#define FALLBACK_MODULE SONOFF_BASIC // [Module2] Select default module on fast reboot where USER_MODULE is user template +#endif + +#ifndef ARDUINO_ESP8266_RELEASE +#define ARDUINO_CORE_RELEASE "STAGE" +#else +#define ARDUINO_CORE_RELEASE ARDUINO_ESP8266_RELEASE +#endif // ARDUINO_ESP8266_RELEASE + +#endif // ESP8266 + +#ifdef ESP32 + +#ifndef MODULE +#define MODULE WEMOS // [Module] Select default model +#endif +#ifndef FALLBACK_MODULE +#define FALLBACK_MODULE WEMOS // [Module2] Select default module on fast reboot where USER_MODULE is user template +#endif + +#ifndef ARDUINO_ESP32_RELEASE +#define ARDUINO_CORE_RELEASE "STAGE" +#else +#define ARDUINO_CORE_RELEASE ARDUINO_ESP32_RELEASE +#endif // ARDUINO_ESP32_RELEASE + +#undef USE_HM10 // Disable support for HM-10 as a BLE-bridge as an alternative is using the internal ESP32 BLE +#undef USE_KEELOQ // Disable support for Jarolift rollers by Keeloq algorithm as it's library cc1101 is not compatible with ESP32 +//#undef USE_DISPLAY_ILI9488 // Disable as it's library JaretBurkett_ILI9488-gemu-1.0 is not compatible with ESP32 +//#undef USE_DISPLAY_SSD1351 // Disable as it's library Adafruit_SSD1351_gemu-1.0 is not compatible with ESP32 + +#endif // ESP32 + /*********************************************************************************************\ * Macros \*********************************************************************************************/ @@ -301,11 +368,21 @@ const char kWebColors[] PROGMEM = #define STR(x) STR_HELPER(x) #endif +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#endif + +#ifdef ESP8266 +#define AGPIO(x) (x) +#define BGPIO(x) (x) +#else // ESP32 +#define AGPIO(x) (x<<5) +#define BGPIO(x) (x>>5) +#endif // ESP8266 - ESP32 + #ifdef USE_DEVICE_GROUPS #define SendDeviceGroupMessage(DEVICE_INDEX, REQUEST_TYPE, ...) _SendDeviceGroupMessage(DEVICE_INDEX, REQUEST_TYPE, __VA_ARGS__, 0) #define SendLocalDeviceGroupMessage(REQUEST_TYPE, ...) _SendDeviceGroupMessage(0, REQUEST_TYPE, __VA_ARGS__, 0) -#define DEVICE_GROUP_MESSAGE "M-TASMOTA_DGR/" -const char kDeviceGroupMessage[] PROGMEM = DEVICE_GROUP_MESSAGE; uint8_t device_group_count = 1; #endif // USE_DEVICE_GROUPS diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index e21260741..bd1c009de 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -20,6 +20,8 @@ #ifndef _TASMOTA_TEMPLATE_H_ #define _TASMOTA_TEMPLATE_H_ +#ifdef ESP8266 + // User selectable GPIO functionality // ATTENTION: Only add at the end of this list just before GPIO_SENSOR_END // Then add the same name(s) in a nice location in array kGpioNiceList @@ -93,7 +95,7 @@ enum UserSelectablePins { GPIO_SPI_CS, // SPI Chip Select GPIO_SPI_DC, // SPI Data Direction GPIO_BACKLIGHT, // Display backlight control - GPIO_PMS5003, // Plantower PMS5003 Serial interface + GPIO_PMS5003_RX, // Plantower PMS5003 Serial interface GPIO_SDS0X1_RX, // Nova Fitness SDS011 Serial interface GPIO_SBR_TX, // Serial Bridge Serial interface GPIO_SBR_RX, // Serial Bridge Serial interface @@ -135,8 +137,8 @@ enum UserSelectablePins { GPIO_TUYA_RX, // Tuya Serial interface GPIO_MGC3130_XFER, // MGC3130 Transfer GPIO_MGC3130_RESET, // MGC3130 Reset - GPIO_SSPI_MISO, // Software SPI Master Input Slave Output - GPIO_SSPI_MOSI, // Software SPI Master Output Slave Input + GPIO_SSPI_MISO, // Software SPI Master Input Client Output + GPIO_SSPI_MOSI, // Software SPI Master Output Client Input GPIO_SSPI_SCLK, // Software SPI Serial Clock GPIO_SSPI_CS, // Software SPI Chip Select GPIO_SSPI_DC, // Software SPI Data or Command @@ -208,10 +210,10 @@ enum UserSelectablePins { GPIO_SM2135_DAT, // SM2135 Dat GPIO_DEEPSLEEP, // Kill switch for deepsleep GPIO_EXS_ENABLE, // EXS MCU Enable - GPIO_TASMOTASLAVE_TXD, // Slave TX - GPIO_TASMOTASLAVE_RXD, // Slave RX - GPIO_TASMOTASLAVE_RST, // Slave Reset Pin - GPIO_TASMOTASLAVE_RST_INV, // Slave Reset Inverted + GPIO_TASMOTACLIENT_TXD, // Client TX + GPIO_TASMOTACLIENT_RXD, // Client RX + GPIO_TASMOTACLIENT_RST, // Client Reset Pin + GPIO_TASMOTACLIENT_RST_INV, // Client Reset Inverted GPIO_HPMA_RX, // Honeywell HPMA115S0 Serial interface GPIO_HPMA_TX, // Honeywell HPMA115S0 Serial interface GPIO_GPS_RX, // GPS serial interface @@ -226,6 +228,17 @@ enum UserSelectablePins { GPIO_CC1101_GDO2, // CC1101 pin for RX GPIO_HRXL_RX, // Data from MaxBotix HRXL sonar range sensor GPIO_ELECTRIQ_MOODL_TX, // ElectriQ iQ-wifiMOODL Serial TX + GPIO_AS3935, + GPIO_PMS5003_TX, // Plantower PMS5003 Serial interface + GPIO_BOILER_OT_RX, // OpenTherm Boiler RX pin + GPIO_BOILER_OT_TX, // OpenTherm Boiler TX pin + GPIO_WINDMETER_SPEED, // WindMeter speed counter pin + GPIO_BL0940_RX, // BL0940 serial interface + GPIO_TCP_TX, // TCP Serial bridge + GPIO_TCP_RX, // TCP Serial bridge + GPIO_TELEINFO_RX, // TELEINFO serial interface + GPIO_TELEINFO_ENABLE,// TELEINFO Enable PIN + GPIO_LMT01, // LMT01 input counting pin GPIO_SENSOR_END }; // Programmer selectable GPIO functionality @@ -259,7 +272,7 @@ const char kSensorNames[] PROGMEM = D_SENSOR_PZEM0XX_TX "|" D_SENSOR_PZEM004_RX "|" D_SENSOR_SAIR_TX "|" D_SENSOR_SAIR_RX "|" D_SENSOR_SPI_CS "|" D_SENSOR_SPI_DC "|" D_SENSOR_BACKLIGHT "|" - D_SENSOR_PMS5003 "|" D_SENSOR_SDS0X1_RX "|" + D_SENSOR_PMS5003_RX "|" D_SENSOR_SDS0X1_RX "|" D_SENSOR_SBR_TX "|" D_SENSOR_SBR_RX "|" D_SENSOR_SR04_TRIG "|" D_SENSOR_SR04_ECHO "|" D_SENSOR_SDM120_TX "|" D_SENSOR_SDM120_RX "|" @@ -304,7 +317,7 @@ const char kSensorNames[] PROGMEM = D_SENSOR_DDSU666_TX "|" D_SENSOR_DDSU666_RX "|" D_SENSOR_SM2135_CLK "|" D_SENSOR_SM2135_DAT "|" D_SENSOR_DEEPSLEEP "|" D_SENSOR_EXS_ENABLE "|" - D_SENSOR_SLAVE_TX "|" D_SENSOR_SLAVE_RX "|" D_SENSOR_SLAVE_RESET "|" D_SENSOR_SLAVE_RESET "i|" + D_SENSOR_CLIENT_TX "|" D_SENSOR_CLIENT_RX "|" D_SENSOR_CLIENT_RESET "|" D_SENSOR_CLIENT_RESET "i|" D_SENSOR_HPMA_RX "|" D_SENSOR_HPMA_TX "|" D_SENSOR_GPS_RX "|" D_SENSOR_GPS_TX "|" D_SENSOR_DS18X20 "o|" D_SENSOR_DHT11 "o|" @@ -312,7 +325,14 @@ const char kSensorNames[] PROGMEM = D_SENSOR_LE01MR_RX "|" D_SENSOR_LE01MR_TX "|" D_SENSOR_CC1101_GDO0 "|" D_SENSOR_CC1101_GDO2 "|" D_SENSOR_HRXL_RX "|" - D_SENSOR_ELECTRIQ_MOODL + D_SENSOR_ELECTRIQ_MOODL "|" + D_SENSOR_AS3935 "|" D_SENSOR_PMS5003_TX "|" + D_SENSOR_BOILER_OT_RX "|" D_SENSOR_BOILER_OT_TX "|" + D_SENSOR_WINDMETER_SPEED "|" + D_SENSOR_BL0940_RX "|" + D_SENSOR_TCP_TXD "|" D_SENSOR_TCP_RXD "|" + D_SENSOR_TELEINFO_RX "|" D_SENSOR_TELEINFO_ENABLE "|" + D_SENSOR_LMT01_PULSE ; const char kSensorNamesFixed[] PROGMEM = @@ -412,8 +432,8 @@ const uint8_t kGpioNiceList[] PROGMEM = { #ifdef USE_SPI GPIO_SPI_CS, // SPI Chip Select GPIO_SPI_DC, // SPI Data Direction - GPIO_SSPI_MISO, // Software SPI Master Input Slave Output - GPIO_SSPI_MOSI, // Software SPI Master Output Slave Input + GPIO_SSPI_MISO, // Software SPI Master Input Client Output + GPIO_SSPI_MOSI, // Software SPI Master Output Client Input GPIO_SSPI_SCLK, // Software SPI Serial Clock GPIO_SSPI_CS, // Software SPI Chip Select GPIO_SSPI_DC, // Software SPI Data or Command @@ -432,6 +452,9 @@ const uint8_t kGpioNiceList[] PROGMEM = { GPIO_DSB, // Single wire DS18B20 or DS18S20 GPIO_DSB_OUT, // Pseudo Single wire DS18B20 or DS18S20 #endif +#ifdef USE_LMT01 // LMT01, count pulses on GPIO + GPIO_LMT01, +#endif // Light #ifdef USE_LIGHT @@ -543,15 +566,18 @@ const uint8_t kGpioNiceList[] PROGMEM = { #ifdef USE_DDSU666 GPIO_DDSU666_TX, // DDSU666 Serial interface GPIO_DDSU666_RX, // DDSU666 Serial interface -#endif // USE_DDSU666 +#endif #ifdef USE_SOLAX_X1 GPIO_SOLAXX1_TX, // Solax Inverter tx pin GPIO_SOLAXX1_RX, // Solax Inverter rx pin -#endif // USE_SOLAX_X1 +#endif #ifdef USE_LE01MR GPIO_LE01MR_RX, // F7F LE-01MR energy meter rx pin GPIO_LE01MR_TX, // F7F LE-01MR energy meter tx pin -#endif // IFDEF:USE_LE01MR +#endif +#ifdef USE_BL0940 + GPIO_BL0940_RX, // BL0940 Serial interface +#endif #endif // USE_ENERGY_SENSOR // Serial @@ -559,6 +585,10 @@ const uint8_t kGpioNiceList[] PROGMEM = { GPIO_SBR_TX, // Serial Bridge Serial interface GPIO_SBR_RX, // Serial Bridge Serial interface #endif +#ifdef USE_TCP_BRIDGE + GPIO_TCP_TX, // TCP Serial bridge + GPIO_TCP_RX, // TCP Serial bridge +#endif #ifdef USE_ZIGBEE GPIO_ZIGBEE_TX, // Zigbee Serial interface GPIO_ZIGBEE_RX, // Zigbee Serial interface @@ -576,15 +606,19 @@ const uint8_t kGpioNiceList[] PROGMEM = { GPIO_SDS0X1_RX, // Nova Fitness SDS011 Serial interface #endif #ifdef USE_HPMA - GPIO_HPMA_TX, // Honeywell HPMA115S0 Serial interface - GPIO_HPMA_RX, // Honeywell HPMA115S0 Serial interface + GPIO_HPMA_TX, // Honeywell HPMA115S0 Serial interface + GPIO_HPMA_RX, // Honeywell HPMA115S0 Serial interface #endif #ifdef USE_PMS5003 - GPIO_PMS5003, // Plantower PMS5003 Serial interface + GPIO_PMS5003_TX, // Plantower PMS5003 Serial interface + GPIO_PMS5003_RX, // Plantower PMS5003 Serial interface #endif #if defined(USE_TX20_WIND_SENSOR) || defined(USE_TX23_WIND_SENSOR) GPIO_TX2X_TXD_BLACK, // TX20/TX23 Transmission Pin #endif +#ifdef USE_WINDMETER + GPIO_WINDMETER_SPEED, +#endif #ifdef USE_MP3_PLAYER GPIO_MP3_DFR562, // RB-DFR-562, DFPlayer Mini MP3 Player Serial interface #endif @@ -596,26 +630,30 @@ const uint8_t kGpioNiceList[] PROGMEM = { GPIO_PN532_TXD, // PN532 HSU Tx GPIO_PN532_RXD, // PN532 HSU Rx #endif -#ifdef USE_TASMOTA_SLAVE - GPIO_TASMOTASLAVE_TXD, // Tasmota Slave TX - GPIO_TASMOTASLAVE_RXD, // Tasmota Slave RX - GPIO_TASMOTASLAVE_RST, // Tasmota Slave Reset - GPIO_TASMOTASLAVE_RST_INV, // Tasmota Slave Reset Inverted +#ifdef USE_TASMOTA_CLIENT + GPIO_TASMOTACLIENT_TXD, // Tasmota Client TX + GPIO_TASMOTACLIENT_RXD, // Tasmota Client RX + GPIO_TASMOTACLIENT_RST, // Tasmota Client Reset + GPIO_TASMOTACLIENT_RST_INV, // Tasmota Client Reset Inverted #endif #ifdef USE_RDM6300 GPIO_RDM6300_RX, #endif #ifdef USE_IBEACON - GPIO_IBEACON_RX, GPIO_IBEACON_TX, + GPIO_IBEACON_RX, #endif #ifdef USE_GPS - GPIO_GPS_RX, // GPS serial interface GPIO_GPS_TX, // GPS serial interface + GPIO_GPS_RX, // GPS serial interface #endif #ifdef USE_HM10 - GPIO_HM10_RX, // GPS serial interface GPIO_HM10_TX, // GPS serial interface + GPIO_HM10_RX, // GPS serial interface +#endif +#ifdef USE_OPENTHERM + GPIO_BOILER_OT_TX, + GPIO_BOILER_OT_RX, #endif #ifdef USE_MGC3130 @@ -656,6 +694,13 @@ const uint8_t kGpioNiceList[] PROGMEM = { #ifdef USE_HRXL GPIO_HRXL_RX, #endif +#ifdef USE_AS3935 + GPIO_AS3935, +#endif +#ifdef USE_TELEINFO + GPIO_TELEINFO_RX, + GPIO_TELEINFO_ENABLE, +#endif }; /********************************************************************************************/ @@ -694,9 +739,14 @@ const char kAdc0Names[] PROGMEM = #define MAX_GPIO_PIN 17 // Number of supported GPIO #define MIN_FLASH_PINS 4 // Number of flash chip pins unusable for configuration (GPIO6, 7, 8 and 11) +#define MAX_USER_PINS 13 // MAX_GPIO_PIN - MIN_FLASH_PINS +#define ADC0_PIN 17 // Pin number of ADC0 +#define WEMOS_MODULE 17 // Wemos module const char PINS_WEMOS[] PROGMEM = "D3TXD4RXD2D1flashcFLFLolD6D7D5D8D0A0"; +/********************************************************************************************/ + typedef struct MYIO { uint8_t io[MAX_GPIO_PIN]; } myio; @@ -729,8 +779,8 @@ typedef struct MYTMPLT { } mytmplt; /********************************************************************************************/ - // Supported hardware modules + enum SupportedModules { SONOFF_BASIC, SONOFF_RF, SONOFF_SV, SONOFF_TH, SONOFF_DUAL, SONOFF_POW, SONOFF_4CH, SONOFF_S2X, SLAMPHER, SONOFF_TOUCH, SONOFF_LED, CH1, CH4, MOTOR, ELECTRODRAGON, EXS_RELAY, WION, WEMOS, SONOFF_DEV, H801, @@ -2221,4 +2271,10 @@ const mytmplt kModules[MAXMODULE] PROGMEM = { } }; +#endif // ESP8266 + +#ifdef ESP32 +#include "tasmota_template_ESP32.h" +#endif // ESP32 + #endif // _TASMOTA_TEMPLATE_H_ diff --git a/tasmota/tasmota_template_ESP32.h b/tasmota/tasmota_template_ESP32.h new file mode 100644 index 000000000..e5b30a5b1 --- /dev/null +++ b/tasmota/tasmota_template_ESP32.h @@ -0,0 +1,695 @@ +/* + tasmota_template_ESP32.h - ESP32 template settings for Tasmota + + Copyright (C) 2020 Theo Arends + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef _TASMOTA_TEMPLATE_ESP32_H_ +#define _TASMOTA_TEMPLATE_ESP32_H_ + +#ifdef ESP32 + +// Hardware has no ESP32 +#undef USE_TUYA_DIMMER +#undef USE_PWM_DIMMER +#undef USE_EXS_DIMMER +#undef USE_ARMTRONIX_DIMMERS +#undef USE_SONOFF_RF +#undef USE_SONOFF_SC +#undef USE_SONOFF_IFAN +#undef USE_SONOFF_L1 +#undef USE_SONOFF_D1 +#undef USE_RF_FLASH + +// Not ported (yet) +#undef USE_DISCOVERY +#undef USE_ADC_VCC // Needs to be ported +#undef USE_DEEPSLEEP +#undef USE_MY92X1 +#undef USE_TUYA_MCU +#undef USE_PS_16_DZ + +enum UserSelectablePins { + GPIO_NONE, // Not used + GPIO_KEY1, GPIO_KEY1_NP, GPIO_KEY1_INV, GPIO_KEY1_INV_NP, // 4 x Button + GPIO_SWT1, GPIO_SWT1_NP, // 8 x User connected external switches + GPIO_REL1, GPIO_REL1_INV, // 8 x Relays + GPIO_LED1, GPIO_LED1_INV, // 4 x Leds + GPIO_CNTR1, GPIO_CNTR1_NP, // 4 x Counter + GPIO_PWM1, GPIO_PWM1_INV, // 5 x PWM + GPIO_BUZZER, GPIO_BUZZER_INV, // Buzzer + GPIO_LEDLNK, GPIO_LEDLNK_INV, // Link led + GPIO_I2C_SCL, GPIO_I2C_SDA, // Software I2C + GPIO_SPI_MISO, GPIO_SPI_MOSI, GPIO_SPI_CLK, GPIO_SPI_CS, GPIO_SPI_DC, // Hardware SPI + GPIO_SSPI_MISO, GPIO_SSPI_MOSI, GPIO_SSPI_SCLK, GPIO_SSPI_CS, GPIO_SSPI_DC, // Software SPI + GPIO_BACKLIGHT, // Display backlight control + GPIO_OLED_RESET, // OLED Display Reset + GPIO_IRSEND, GPIO_IRRECV, // IR interface + GPIO_RFSEND, GPIO_RFRECV, // RF interface + GPIO_DHT11, GPIO_DHT22, GPIO_SI7021, GPIO_DHT11_OUT, // DHT11, DHT21, DHT22, AM2301, AM2302, AM2321 + GPIO_DSB, GPIO_DSB_OUT, // DS18B20 or DS18S20 + GPIO_WS2812, // WS2812 Led string + GPIO_MHZ_TXD, GPIO_MHZ_RXD, // MH-Z19 Serial interface + GPIO_PZEM0XX_TX, GPIO_PZEM004_RX, GPIO_PZEM016_RX, GPIO_PZEM017_RX, // PZEM Serial Modbus interface + GPIO_SAIR_TX, GPIO_SAIR_RX, // SenseAir Serial interface + GPIO_PMS5003_TX, GPIO_PMS5003_RX, // Plantower PMS5003 Serial interface + GPIO_SDS0X1_TX, GPIO_SDS0X1_RX, // Nova Fitness SDS011 Serial interface + GPIO_SBR_TX, GPIO_SBR_RX, // Serial Bridge Serial interface + GPIO_SR04_TRIG, GPIO_SR04_ECHO, // SR04 interface + GPIO_SDM120_TX, GPIO_SDM120_RX, // SDM120 Serial interface + GPIO_SDM630_TX, GPIO_SDM630_RX, // SDM630 Serial interface + GPIO_TM16CLK, GPIO_TM16DIO, GPIO_TM16STB, // TM1638 interface + GPIO_MP3_DFR562, // RB-DFR-562, DFPlayer Mini MP3 Player + GPIO_HX711_SCK, GPIO_HX711_DAT, // HX711 Load Cell interface + GPIO_TX2X_TXD_BLACK, // TX20/TX23 Transmission Pin + GPIO_TUYA_TX, GPIO_TUYA_RX, // Tuya Serial interface + GPIO_MGC3130_XFER, GPIO_MGC3130_RESET, // MGC3130 interface + GPIO_RF_SENSOR, // Rf receiver with sensor decoding + GPIO_AZ_TXD, GPIO_AZ_RXD, // AZ-Instrument 7798 Serial interface + GPIO_MAX31855CS, GPIO_MAX31855CLK, GPIO_MAX31855DO, // MAX31855 Serial interface + GPIO_NRG_SEL, GPIO_NRG_SEL_INV, GPIO_NRG_CF1, GPIO_HLW_CF, GPIO_HJL_CF, // HLW8012/HJL-01/BL0937 energy monitoring + GPIO_MCP39F5_TX, GPIO_MCP39F5_RX, GPIO_MCP39F5_RST, // MCP39F501 Energy monitoring (Shelly2) + GPIO_PN532_TXD, GPIO_PN532_RXD, // PN532 NFC Serial interface + GPIO_SM16716_CLK, GPIO_SM16716_DAT, GPIO_SM16716_SEL, // SM16716 SELECT + GPIO_DI, GPIO_DCKI, // my92x1 PWM controller + GPIO_CSE7766_TX, GPIO_CSE7766_RX, // CSE7766 Serial interface (S31 and Pow R2) + GPIO_ARIRFRCV, GPIO_ARIRFSEL, // Arilux RF Receive input + GPIO_TXD, GPIO_RXD, // Serial interface + GPIO_ROT1A, GPIO_ROT1B, GPIO_ROT2A, GPIO_ROT2B, // Rotary switch + GPIO_HRE_CLOCK, GPIO_HRE_DATA, // HR-E Water Meter + GPIO_ADE7953_IRQ, // ADE7953 IRQ + GPIO_SOLAXX1_TX, GPIO_SOLAXX1_RX, // Solax Inverter Serial interface + GPIO_ZIGBEE_TX, GPIO_ZIGBEE_RX, // Zigbee Serial interface + GPIO_RDM6300_RX, // RDM6300 RX + GPIO_IBEACON_TX, GPIO_IBEACON_RX, // HM17 IBEACON Serial interface + GPIO_A4988_DIR, GPIO_A4988_STP, GPIO_A4988_ENA, // A4988 interface + GPIO_A4988_MS1, GPIO_A4988_MS2, GPIO_A4988_MS3, // A4988 microstep + GPIO_DDS2382_TX, GPIO_DDS2382_RX, // DDS2382 Serial interface + GPIO_DDSU666_TX, GPIO_DDSU666_RX, // DDSU666 Serial interface + GPIO_SM2135_CLK, GPIO_SM2135_DAT, // SM2135 PWM controller + GPIO_DEEPSLEEP, // Kill switch for deepsleep + GPIO_EXS_ENABLE, // EXS MCU Enable + GPIO_TASMOTACLIENT_TXD, GPIO_TASMOTACLIENT_RXD, // Client Serial interface + GPIO_TASMOTACLIENT_RST, GPIO_TASMOTACLIENT_RST_INV, // Client Reset + GPIO_HPMA_RX, GPIO_HPMA_TX, // Honeywell HPMA115S0 Serial interface + GPIO_GPS_RX, GPIO_GPS_TX, // GPS Serial interface + GPIO_HM10_RX, GPIO_HM10_TX, // HM10-BLE-Mijia-bridge Serial interface + GPIO_LE01MR_RX, GPIO_LE01MR_TX, // F&F LE-01MR energy meter + GPIO_CC1101_GDO0, GPIO_CC1101_GDO2, // CC1101 Serial interface + GPIO_HRXL_RX, // Data from MaxBotix HRXL sonar range sensor + GPIO_ELECTRIQ_MOODL_TX, // ElectriQ iQ-wifiMOODL Serial TX + GPIO_AS3935, + ADC0_INPUT, // Analog input + ADC0_TEMP, // Analog Thermistor + ADC0_LIGHT, // Analog Light sensor + ADC0_BUTTON, ADC0_BUTTON_INV, // Analog Button + ADC0_RANGE, // Analog Range + ADC0_CT_POWER, // ANalog Current + GPIO_WEBCAM_PWDN, GPIO_WEBCAM_RESET, GPIO_WEBCAM_XCLK, // Webcam + GPIO_WEBCAM_SIOD, GPIO_WEBCAM_SIOC, // Webcam I2C + GPIO_WEBCAM_DATA, + GPIO_WEBCAM_VSYNC, GPIO_WEBCAM_HREF, GPIO_WEBCAM_PCLK, + GPIO_WEBCAM_PSCLK, + GPIO_WEBCAM_HSD, + GPIO_WEBCAM_PSRCS, + GPIO_BOILER_OT_RX, GPIO_BOILER_OT_TX, // OpenTherm Boiler TX pin + GPIO_WINDMETER_SPEED, // WindMeter speed counter pin + GPIO_KEY1_TC, // Touch pin as button + GPIO_BL0940_RX, // BL0940 serial interface + GPIO_TCP_TX, GPIO_TCP_RX, // TCP to serial bridge + GPIO_ETH_PHY_POWER, GPIO_ETH_PHY_MDC, GPIO_ETH_PHY_MDIO, // Ethernet + GPIO_TELEINFO_RX, // Teleinfo telemetry data receive pin + GPIO_TELEINFO_ENABLE, // Teleinfo Enable Receive Pin + GPIO_LMT01, // LMT01 input counting pin + GPIO_SENSOR_END }; + +enum ProgramSelectablePins { +// GPIO_FIX_START = 254, + GPIO_FIX_START = 2046, + GPIO_USER, // User configurable needs to be 2047 + GPIO_MAX }; + +// Text in webpage Module Parameters and commands GPIOS and GPIO +const char kSensorNames[] PROGMEM = + D_SENSOR_NONE "|" + D_SENSOR_BUTTON "|" D_SENSOR_BUTTON "_n|" D_SENSOR_BUTTON "_i|" D_SENSOR_BUTTON "_in|" + D_SENSOR_SWITCH "|" D_SENSOR_SWITCH "_n|" + D_SENSOR_RELAY "|" D_SENSOR_RELAY "_i|" + D_SENSOR_LED "|" D_SENSOR_LED "_i|" + D_SENSOR_COUNTER "|" D_SENSOR_COUNTER "_n|" + D_SENSOR_PWM "|" D_SENSOR_PWM "_i|" + D_SENSOR_BUZZER "|" D_SENSOR_BUZZER "_i|" + D_SENSOR_LED_LINK "|" D_SENSOR_LED_LINK "_i|" + D_SENSOR_I2C_SCL "|" D_SENSOR_I2C_SDA "|" + D_SENSOR_SPI_MISO "|" D_SENSOR_SPI_MOSI "|" D_SENSOR_SPI_CLK "|" D_SENSOR_SPI_CS "|" D_SENSOR_SPI_DC "|" + D_SENSOR_SSPI_MISO "|" D_SENSOR_SSPI_MOSI "|" D_SENSOR_SSPI_SCLK "|" D_SENSOR_SSPI_CS "|" D_SENSOR_SSPI_DC "|" + D_SENSOR_BACKLIGHT "|" D_SENSOR_OLED_RESET "|" + D_SENSOR_IRSEND "|" D_SENSOR_IRRECV "|" + D_SENSOR_RFSEND "|" D_SENSOR_RFRECV "|" + D_SENSOR_DHT11 "|" D_SENSOR_AM2301 "|" D_SENSOR_SI7021 "|" D_SENSOR_DHT11 "_o|" + D_SENSOR_DS18X20 "|" D_SENSOR_DS18X20 "_o|" + D_SENSOR_WS2812 "|" + D_SENSOR_MHZ_TX "|" D_SENSOR_MHZ_RX "|" + D_SENSOR_PZEM0XX_TX "|" D_SENSOR_PZEM004_RX "|" D_SENSOR_PZEM016_RX "|" D_SENSOR_PZEM017_RX "|" + D_SENSOR_SAIR_TX "|" D_SENSOR_SAIR_RX "|" + D_SENSOR_PMS5003_TX "|" D_SENSOR_PMS5003_RX "|" + D_SENSOR_SDS0X1_TX "|" D_SENSOR_SDS0X1_RX "|" + D_SENSOR_SBR_TX "|" D_SENSOR_SBR_RX "|" + D_SENSOR_SR04_TRIG "|" D_SENSOR_SR04_ECHO "|" + D_SENSOR_SDM120_TX "|" D_SENSOR_SDM120_RX "|" + D_SENSOR_SDM630_TX "|" D_SENSOR_SDM630_RX "|" + D_SENSOR_TM1638_CLK "|" D_SENSOR_TM1638_DIO "|" D_SENSOR_TM1638_STB "|" + D_SENSOR_DFR562 "|" + D_SENSOR_HX711_SCK "|" D_SENSOR_HX711_DAT "|" + D_SENSOR_TX2X_TX "|" + D_SENSOR_TUYA_TX "|" D_SENSOR_TUYA_RX "|" + D_SENSOR_MGC3130_XFER "|" D_SENSOR_MGC3130_RESET "|" + D_SENSOR_RF_SENSOR "|" + D_SENSOR_AZ_TX "|" D_SENSOR_AZ_RX "|" + D_SENSOR_MAX31855_CS "|" D_SENSOR_MAX31855_CLK "|" D_SENSOR_MAX31855_DO "|" + D_SENSOR_NRG_SEL "|" D_SENSOR_NRG_SEL "_i|" D_SENSOR_NRG_CF1 "|" D_SENSOR_HLW_CF "|" D_SENSOR_HJL_CF "|" + D_SENSOR_MCP39F5_TX "|" D_SENSOR_MCP39F5_RX "|" D_SENSOR_MCP39F5_RST "|" + D_SENSOR_PN532_TX "|" D_SENSOR_PN532_RX "|" + D_SENSOR_SM16716_CLK "|" D_SENSOR_SM16716_DAT "|" D_SENSOR_SM16716_POWER "|" + D_SENSOR_MY92X1_DI "|" D_SENSOR_MY92X1_DCKI "|" + D_SENSOR_CSE7766_TX "|" D_SENSOR_CSE7766_RX "|" + D_SENSOR_ARIRFRCV "|" D_SENSOR_ARIRFSEL "|" + D_SENSOR_TXD "|" D_SENSOR_RXD "|" + D_SENSOR_ROTARY "_1a|" D_SENSOR_ROTARY "_1b|" D_SENSOR_ROTARY "_2a|" D_SENSOR_ROTARY "_2b|" + D_SENSOR_HRE_CLOCK "|" D_SENSOR_HRE_DATA "|" + D_SENSOR_ADE7953_IRQ "|" + D_SENSOR_SOLAXX1_TX "|" D_SENSOR_SOLAXX1_RX "|" + D_SENSOR_ZIGBEE_TXD "|" D_SENSOR_ZIGBEE_RXD "|" + D_SENSOR_RDM6300_RX "|" + D_SENSOR_IBEACON_TX "|" D_SENSOR_IBEACON_RX "|" + D_SENSOR_A4988_DIR "|" D_SENSOR_A4988_STP "|" D_SENSOR_A4988_ENA "|" D_SENSOR_A4988_MS1 "|" D_SENSOR_A4988_MS2 "|" D_SENSOR_A4988_MS3 "|" + D_SENSOR_DDS2382_TX "|" D_SENSOR_DDS2382_RX "|" + D_SENSOR_DDSU666_TX "|" D_SENSOR_DDSU666_RX "|" + D_SENSOR_SM2135_CLK "|" D_SENSOR_SM2135_DAT "|" + D_SENSOR_DEEPSLEEP "|" D_SENSOR_EXS_ENABLE "|" + D_SENSOR_CLIENT_TX "|" D_SENSOR_CLIENT_RX "|" D_SENSOR_CLIENT_RESET "|" D_SENSOR_CLIENT_RESET "_i|" + D_SENSOR_HPMA_RX "|" D_SENSOR_HPMA_TX "|" + D_SENSOR_GPS_RX "|" D_SENSOR_GPS_TX "|" + D_SENSOR_HM10_RX "|" D_SENSOR_HM10_TX "|" + D_SENSOR_LE01MR_RX "|" D_SENSOR_LE01MR_TX "|" + D_SENSOR_CC1101_GDO0 "|" D_SENSOR_CC1101_GDO2 "|" + D_SENSOR_HRXL_RX "|" + D_SENSOR_ELECTRIQ_MOODL "|" + D_SENSOR_AS3935 "|" + D_ANALOG_INPUT "|" + D_TEMPERATURE "|" D_LIGHT "|" + D_SENSOR_BUTTON "|" D_SENSOR_BUTTON "_i|" + D_RANGE "|" + D_CT_POWER "|" + D_GPIO_WEBCAM_PWDN "|" D_GPIO_WEBCAM_RESET "|" D_GPIO_WEBCAM_XCLK "|" + D_GPIO_WEBCAM_SIOD "|" D_GPIO_WEBCAM_SIOC "|" + D_GPIO_WEBCAM_DATA "|" + D_GPIO_WEBCAM_VSYNC "|" D_GPIO_WEBCAM_HREF "|" D_GPIO_WEBCAM_PCLK "|" + D_GPIO_WEBCAM_PSCLK "|" + D_GPIO_WEBCAM_HSD "|" + D_GPIO_WEBCAM_PSRCS "|" + D_SENSOR_BOILER_OT_RX "|" D_SENSOR_BOILER_OT_TX "|" + D_SENSOR_WINDMETER_SPEED "|" D_SENSOR_BUTTON "_tc|" + D_SENSOR_BL0940_RX "|" + D_SENSOR_TCP_TXD "|" D_SENSOR_TCP_RXD "|" + D_SENSOR_ETH_PHY_POWER "|" D_SENSOR_ETH_PHY_MDC "|" D_SENSOR_ETH_PHY_MDIO "|" + D_SENSOR_TELEINFO_RX "|" D_SENSOR_TELEINFO_ENABLE "|" + D_SENSOR_LMT01_PULSE + ; + +const char kSensorNamesFixed[] PROGMEM = + D_SENSOR_USER; + +#define MAX_WEBCAM_DATA 8 +#define MAX_WEBCAM_HSD 3 + +const uint16_t kGpioNiceList[] PROGMEM = { + GPIO_NONE, // Not used + AGPIO(GPIO_KEY1) + MAX_KEYS, // Buttons + AGPIO(GPIO_KEY1_NP) + MAX_KEYS, + AGPIO(GPIO_KEY1_INV) + MAX_KEYS, + AGPIO(GPIO_KEY1_INV_NP) + MAX_KEYS, + AGPIO(GPIO_KEY1_TC) + MAX_KEYS, // Touch button + AGPIO(GPIO_SWT1) + MAX_SWITCHES, // User connected external switches + AGPIO(GPIO_SWT1_NP) + MAX_SWITCHES, + AGPIO(GPIO_REL1) + MAX_RELAYS, // Relays + AGPIO(GPIO_REL1_INV) + MAX_RELAYS, + AGPIO(GPIO_LED1) + MAX_LEDS, // Leds + AGPIO(GPIO_LED1_INV) + MAX_LEDS, +#ifdef USE_COUNTER + AGPIO(GPIO_CNTR1) + MAX_COUNTERS, // Counters + AGPIO(GPIO_CNTR1_NP) + MAX_COUNTERS, +#endif + AGPIO(GPIO_PWM1) + MAX_PWMS, // RGB Red or C Cold White + AGPIO(GPIO_PWM1_INV) + MAX_PWMS, +#ifdef USE_BUZZER + AGPIO(GPIO_BUZZER), // Buzzer + AGPIO(GPIO_BUZZER_INV), // Inverted buzzer +#endif + AGPIO(GPIO_LEDLNK), // Link led + AGPIO(GPIO_LEDLNK_INV), // Inverted link led +#ifdef USE_I2C + AGPIO(GPIO_I2C_SCL), // I2C SCL + AGPIO(GPIO_I2C_SDA), // I2C SDA +#endif +#ifdef USE_SPI + AGPIO(GPIO_SPI_MISO), // SPI MISO + AGPIO(GPIO_SPI_MOSI), // SPI MOSI + AGPIO(GPIO_SPI_CLK), // SPI Clk + AGPIO(GPIO_SPI_CS), // SPI Chip Select + AGPIO(GPIO_SPI_DC), // SPI Data Direction + AGPIO(GPIO_SSPI_MISO), // Software SPI Master Input Client Output + AGPIO(GPIO_SSPI_MOSI), // Software SPI Master Output Client Input + AGPIO(GPIO_SSPI_SCLK), // Software SPI Serial Clock + AGPIO(GPIO_SSPI_CS), // Software SPI Chip Select + AGPIO(GPIO_SSPI_DC), // Software SPI Data or Command +#endif +#ifdef USE_DISPLAY + AGPIO(GPIO_BACKLIGHT), // Display backlight control + AGPIO(GPIO_OLED_RESET), // OLED Display Reset +#endif + + AGPIO(GPIO_TXD), // Serial interface + AGPIO(GPIO_RXD), // Serial interface + +#ifdef USE_DHT + AGPIO(GPIO_DHT11), // DHT11 + AGPIO(GPIO_DHT22), // DHT21, DHT22, AM2301, AM2302, AM2321 + AGPIO(GPIO_SI7021), // iTead SI7021 + AGPIO(GPIO_DHT11_OUT), // Pseudo Single wire DHT11, DHT21, DHT22, AM2301, AM2302, AM2321 +#endif +#ifdef USE_DS18x20 + AGPIO(GPIO_DSB), // Single wire DS18B20 or DS18S20 + AGPIO(GPIO_DSB_OUT), // Pseudo Single wire DS18B20 or DS18S20 +#endif +#ifdef USE_LMT01 + AGPIO(GPIO_LMT01), // LMT01, count pulses on GPIO +#endif + +// Light +#ifdef USE_LIGHT +#ifdef USE_WS2812 + AGPIO(GPIO_WS2812), // WS2812 Led string +#endif +#ifdef USE_ARILUX_RF + AGPIO(GPIO_ARIRFRCV), // AriLux RF Receive input + AGPIO(GPIO_ARIRFSEL), // Arilux RF Receive input selected +#endif +#ifdef USE_MY92X1 + AGPIO(GPIO_DI), // my92x1 PWM input + AGPIO(GPIO_DCKI), // my92x1 CLK input +#endif // USE_MY92X1 +#ifdef USE_SM16716 + AGPIO(GPIO_SM16716_CLK), // SM16716 CLOCK + AGPIO(GPIO_SM16716_DAT), // SM16716 DATA + AGPIO(GPIO_SM16716_SEL), // SM16716 SELECT +#endif // USE_SM16716 +#ifdef USE_SM2135 + AGPIO(GPIO_SM2135_CLK), // SM2135 CLOCK + AGPIO(GPIO_SM2135_DAT), // SM2135 DATA +#endif // USE_SM2135 +#ifdef USE_TUYA_MCU + AGPIO(GPIO_TUYA_TX), // Tuya Serial interface + AGPIO(GPIO_TUYA_RX), // Tuya Serial interface +#endif +#ifdef USE_EXS_DIMMER + AGPIO(GPIO_EXS_ENABLE), // EXS MCU Enable +#endif +#ifdef USE_ELECTRIQ_MOODL + AGPIO(GPIO_ELECTRIQ_MOODL_TX), +#endif +#endif // USE_LIGHT + +#if defined(USE_IR_REMOTE) || defined(USE_IR_REMOTE_FULL) + AGPIO(GPIO_IRSEND), // IR remote +#if defined(USE_IR_RECEIVE) || defined(USE_IR_REMOTE_FULL) + AGPIO(GPIO_IRRECV), // IR receiver +#endif +#endif + +#ifdef USE_RC_SWITCH + AGPIO(GPIO_RFSEND), // RF transmitter + AGPIO(GPIO_RFRECV), // RF receiver +#endif +#ifdef USE_RF_SENSOR + AGPIO(GPIO_RF_SENSOR), // Rf receiver with sensor decoding +#endif +#ifdef USE_SR04 + AGPIO(GPIO_SR04_TRIG), // SR04 Tri/TXgger pin + AGPIO(GPIO_SR04_ECHO), // SR04 Ech/RXo pin +#endif +#ifdef USE_TM1638 + AGPIO(GPIO_TM16CLK), // TM1638 Clock + AGPIO(GPIO_TM16DIO), // TM1638 Data I/O + AGPIO(GPIO_TM16STB), // TM1638 Strobe +#endif +#ifdef USE_HX711 + AGPIO(GPIO_HX711_SCK), // HX711 Load Cell clock + AGPIO(GPIO_HX711_DAT), // HX711 Load Cell data +#endif + +// Energy sensors +#ifdef USE_ENERGY_SENSOR +#ifdef USE_HLW8012 + AGPIO(GPIO_NRG_SEL), // HLW8012/HLJ-01 Sel output (1 = Voltage) + AGPIO(GPIO_NRG_SEL_INV), // HLW8012/HLJ-01 Sel output (0 = Voltage) + AGPIO(GPIO_NRG_CF1), // HLW8012/HLJ-01 CF1 voltage / current + AGPIO(GPIO_HLW_CF), // HLW8012 CF power + AGPIO(GPIO_HJL_CF), // HJL-01/BL0937 CF power +#endif +#if defined(USE_I2C) && defined(USE_ADE7953) + AGPIO(GPIO_ADE7953_IRQ), // ADE7953 IRQ +#endif +#ifdef USE_CSE7766 + AGPIO(GPIO_CSE7766_TX), // CSE7766 Serial interface (S31 and Pow R2) + AGPIO(GPIO_CSE7766_RX), // CSE7766 Serial interface (S31 and Pow R2) +#endif +#ifdef USE_MCP39F501 + AGPIO(GPIO_MCP39F5_TX), // MCP39F501 Serial interface (Shelly2) + AGPIO(GPIO_MCP39F5_RX), // MCP39F501 Serial interface (Shelly2) + AGPIO(GPIO_MCP39F5_RST), // MCP39F501 Reset (Shelly2) +#endif +#if defined(USE_PZEM004T) || defined(USE_PZEM_AC) || defined(USE_PZEM_DC) + AGPIO(GPIO_PZEM0XX_TX), // PZEM0XX Serial interface +#endif +#ifdef USE_PZEM004T + AGPIO(GPIO_PZEM004_RX), // PZEM004T Serial interface +#endif +#ifdef USE_PZEM_AC + AGPIO(GPIO_PZEM016_RX), // PZEM-014,016 Serial Modbus interface +#endif +#ifdef USE_PZEM_DC + AGPIO(GPIO_PZEM017_RX), // PZEM-003,017 Serial Modbus interface +#endif +#ifdef USE_SDM120 + AGPIO(GPIO_SDM120_TX), // SDM120 Serial interface + AGPIO(GPIO_SDM120_RX), // SDM120 Serial interface +#endif +#ifdef USE_SDM630 + AGPIO(GPIO_SDM630_TX), // SDM630 Serial interface + AGPIO(GPIO_SDM630_RX), // SDM630 Serial interface +#endif +#ifdef USE_DDS2382 + AGPIO(GPIO_DDS2382_TX), // DDS2382 Serial interface + AGPIO(GPIO_DDS2382_RX), // DDS2382 Serial interface +#endif +#ifdef USE_DDSU666 + AGPIO(GPIO_DDSU666_TX), // DDSU666 Serial interface + AGPIO(GPIO_DDSU666_RX), // DDSU666 Serial interface +#endif // USE_DDSU666 +#ifdef USE_SOLAX_X1 + AGPIO(GPIO_SOLAXX1_TX), // Solax Inverter tx pin + AGPIO(GPIO_SOLAXX1_RX), // Solax Inverter rx pin +#endif // USE_SOLAX_X1 +#ifdef USE_LE01MR + AGPIO(GPIO_LE01MR_TX), // F7F LE-01MR energy meter tx pin + AGPIO(GPIO_LE01MR_RX), // F7F LE-01MR energy meter rx pin +#endif // IFDEF:USE_LE01MR +#ifdef USE_BL0940 + AGPIO(GPIO_BL0940_RX), // BL0940 Serial interface +#endif +#endif // USE_ENERGY_SENSOR + +// Serial +#ifdef USE_SERIAL_BRIDGE + AGPIO(GPIO_SBR_TX), // Serial Bridge Serial interface + AGPIO(GPIO_SBR_RX), // Serial Bridge Serial interface +#endif +#ifdef USE_TCP_BRIDGE + AGPIO(GPIO_TCP_TX), // TCP Serial bridge + AGPIO(GPIO_TCP_RX), // TCP Serial bridge +#endif +#ifdef USE_ZIGBEE + AGPIO(GPIO_ZIGBEE_TX), // Zigbee Serial interface + AGPIO(GPIO_ZIGBEE_RX), // Zigbee Serial interface +#endif +#ifdef USE_MHZ19 + AGPIO(GPIO_MHZ_TXD), // MH-Z19 Serial interface + AGPIO(GPIO_MHZ_RXD), // MH-Z19 Serial interface +#endif +#ifdef USE_SENSEAIR + AGPIO(GPIO_SAIR_TX), // SenseAir Serial interface + AGPIO(GPIO_SAIR_RX), // SenseAir Serial interface +#endif +#ifdef USE_NOVA_SDS + AGPIO(GPIO_SDS0X1_TX), // Nova Fitness SDS011 Serial interface + AGPIO(GPIO_SDS0X1_RX), // Nova Fitness SDS011 Serial interface +#endif +#ifdef USE_HPMA + AGPIO(GPIO_HPMA_TX), // Honeywell HPMA115S0 Serial interface + AGPIO(GPIO_HPMA_RX), // Honeywell HPMA115S0 Serial interface +#endif +#ifdef USE_PMS5003 + AGPIO(GPIO_PMS5003_TX), // Plantower PMS5003 Serial interface + AGPIO(GPIO_PMS5003_RX), // Plantower PMS5003 Serial interface +#endif +#if defined(USE_TX20_WIND_SENSOR) || defined(USE_TX23_WIND_SENSOR) + AGPIO(GPIO_TX2X_TXD_BLACK), // TX20/TX23 Transmission Pin +#endif +#ifdef USE_WINDMETER + GPIO_WINDMETER_SPEED, +#endif +#ifdef USE_MP3_PLAYER + AGPIO(GPIO_MP3_DFR562), // RB-DFR-562, DFPlayer Mini MP3 Player Serial interface +#endif +#ifdef USE_AZ7798 + AGPIO(GPIO_AZ_TXD), // AZ-Instrument 7798 CO2 datalogger Serial interface + AGPIO(GPIO_AZ_RXD), // AZ-Instrument 7798 CO2 datalogger Serial interface +#endif +#ifdef USE_PN532_HSU + AGPIO(GPIO_PN532_TXD), // PN532 HSU Tx + AGPIO(GPIO_PN532_RXD), // PN532 HSU Rx +#endif +#ifdef USE_TASMOTA_CLIENT + AGPIO(GPIO_TASMOTACLIENT_TXD), // Tasmota Client TX + AGPIO(GPIO_TASMOTACLIENT_RXD), // Tasmota Client RX + AGPIO(GPIO_TASMOTACLIENT_RST), // Tasmota Client Reset + AGPIO(GPIO_TASMOTACLIENT_RST_INV), // Tasmota Client Reset Inverted +#endif +#ifdef USE_RDM6300 + AGPIO(GPIO_RDM6300_RX), +#endif +#ifdef USE_IBEACON + AGPIO(GPIO_IBEACON_TX), + AGPIO(GPIO_IBEACON_RX), +#endif +#ifdef USE_GPS + AGPIO(GPIO_GPS_TX), // GPS serial interface + AGPIO(GPIO_GPS_RX), // GPS serial interface +#endif +#ifdef USE_HM10 + AGPIO(GPIO_HM10_TX), // GPS serial interface + AGPIO(GPIO_HM10_RX), // GPS serial interface +#endif +#ifdef USE_OPENTHERM + GPIO_BOILER_OT_TX, + GPIO_BOILER_OT_RX, +#endif + +#ifdef USE_MGC3130 + AGPIO(GPIO_MGC3130_XFER), + AGPIO(GPIO_MGC3130_RESET), +#endif +#ifdef USE_MAX31855 + AGPIO(GPIO_MAX31855CS), // MAX31855 Serial interface + AGPIO(GPIO_MAX31855CLK), // MAX31855 Serial interface + AGPIO(GPIO_MAX31855DO), // MAX31855 Serial interface +#endif +#ifdef ROTARY_V1 + AGPIO(GPIO_ROT1A), // Rotary switch1 A Pin + AGPIO(GPIO_ROT1B), // Rotary switch1 B Pin + AGPIO(GPIO_ROT2A), // Rotary switch2 A Pin + AGPIO(GPIO_ROT2B), // Rotary switch2 B Pin +#endif +#ifdef USE_HRE + AGPIO(GPIO_HRE_CLOCK), + AGPIO(GPIO_HRE_DATA), +#endif +#ifdef USE_A4988_STEPPER + AGPIO(GPIO_A4988_DIR), // A4988 direction pin + AGPIO(GPIO_A4988_STP), // A4988 step pin + // folowing are not mandatory + AGPIO(GPIO_A4988_ENA), // A4988 enabled pin + AGPIO(GPIO_A4988_MS1), // A4988 microstep pin1 + AGPIO(GPIO_A4988_MS2), // A4988 microstep pin2 + AGPIO(GPIO_A4988_MS3), // A4988 microstep pin3 +#endif +#ifdef USE_DEEPSLEEP + AGPIO(GPIO_DEEPSLEEP), +#endif +#ifdef USE_KEELOQ + AGPIO(GPIO_CC1101_GDO0), // CC1101 pin for RX + AGPIO(GPIO_CC1101_GDO2), // CC1101 pin for RX +#endif +#ifdef USE_HRXL + AGPIO(GPIO_HRXL_RX), +#endif +#ifdef USE_AS3935 + AGPIO(GPIO_AS3935), +#endif +#ifdef USE_TELEINFO + AGPIO(GPIO_TELEINFO_RX), + AGPIO(GPIO_TELEINFO_ENABLE), +#endif +/* +#ifndef USE_ADC_VCC + AGPIO(ADC0_INPUT), // Analog input + AGPIO(ADC0_TEMP), // Thermistor + AGPIO(ADC0_LIGHT), // Light sensor + AGPIO(ADC0_BUTTON), // Button + AGPIO(ADC0_BUTTON_INV), + AGPIO(ADC0_RANGE), // Range + AGPIO(ADC0_CT_POWER), // Current +#endif +*/ +#ifdef USE_WEBCAM + AGPIO(GPIO_WEBCAM_PWDN), + AGPIO(GPIO_WEBCAM_RESET), + AGPIO(GPIO_WEBCAM_XCLK), + AGPIO(GPIO_WEBCAM_SIOD), + AGPIO(GPIO_WEBCAM_SIOC), + AGPIO(GPIO_WEBCAM_DATA) + MAX_WEBCAM_DATA, + AGPIO(GPIO_WEBCAM_VSYNC), + AGPIO(GPIO_WEBCAM_HREF), + AGPIO(GPIO_WEBCAM_PCLK), + AGPIO(GPIO_WEBCAM_PSCLK), + AGPIO(GPIO_WEBCAM_HSD) + MAX_WEBCAM_HSD, + AGPIO(GPIO_WEBCAM_PSRCS), +#endif +#ifdef USE_ETHERNET + AGPIO(GPIO_ETH_PHY_POWER), + AGPIO(GPIO_ETH_PHY_MDC), + AGPIO(GPIO_ETH_PHY_MDIO), // Ethernet +#endif +}; + +//******************************************************************************************** + +#define MAX_GPIO_PIN 40 // Number of supported GPIO +#define MIN_FLASH_PINS 4 // Number of flash chip pins unusable for configuration (GPIO6, 7, 8 and 11) +#define MAX_USER_PINS 36 // MAX_GPIO_PIN - MIN_FLASH_PINS +#define WEMOS_MODULE 0 // Wemos module + +// 0 1 2 3 4 5 6 7 8 9101112131415161718192021222324252627282930313233343536373839 +const char PINS_WEMOS[] PROGMEM = "IOTXIORXIOIOflashcFLFLolIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOA6A7A0IoIoA3"; + +//******************************************************************************************** + +typedef struct MYIO { + uint16_t io[MAX_GPIO_PIN]; +} myio; // 40 * 2 = 80 bytes + +typedef struct MYCFGIO { + uint16_t io[MAX_USER_PINS]; +} mycfgio; // 36 * 2 = 72 bytes + +#define GPIO_FLAG_USED 0 // Currently no flags used + +typedef union { + uint16_t data; + struct { + uint16_t spare00 : 1; + uint16_t spare01 : 1; + uint16_t spare02 : 1; + uint16_t spare03 : 1; + uint16_t spare04 : 1; + uint16_t spare05 : 1; + uint16_t spare06 : 1; + uint16_t spare07 : 1; + uint16_t spare08 : 1; + uint16_t spare09 : 1; + uint16_t spare10 : 1; + uint16_t spare11 : 1; + uint16_t spare12 : 1; + uint16_t spare13 : 1; + uint16_t spare14 : 1; + uint16_t spare15 : 1; + }; +} gpio_flag; // 2 bytes + +typedef struct MYTMPLT { + mycfgio gp; // 72 bytes + gpio_flag flag; // 2 bytes +} mytmplt; // 74 bytes + +/********************************************************************************************/ +// Supported hardware modules +enum SupportedModules { WEMOS, ESP32_CAM_AITHINKER, MAXMODULE }; + +#define USER_MODULE 255 + +const char kModuleNames[] PROGMEM = "ESP32-DevKit|ESP32 Cam AiThinker"; + +// Default module settings +const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = { WEMOS, ESP32_CAM_AITHINKER }; + +const mytmplt kModules PROGMEM = +{ // WEMOS - Espressif ESP32-DevKitC - Any ESP32 device like WeMos and NodeMCU hardware (ESP32) + AGPIO(GPIO_USER), // 0 (I)O GPIO0, ADC2_CH1, TOUCH1, RTC_GPIO11, CLK_OUT1, EMAC_TX_CLK + AGPIO(GPIO_USER), // 1 IO TXD0 GPIO1, U0TXD, CLK_OUT3, EMAC_RXD2 + AGPIO(GPIO_USER), // 2 IO GPIO2, ADC2_CH2, TOUCH2, RTC_GPIO12, HSPIWP, HS2_DATA0, SD_DATA0 + AGPIO(GPIO_USER), // 3 IO RXD0 GPIO3, U0RXD, CLK_OUT2 + AGPIO(GPIO_USER), // 4 IO GPIO4, ADC2_CH0, TOUCH0, RTC_GPIO10, HSPIHD, HS2_DATA1, SD_DATA1, EMAC_TX_ER + AGPIO(GPIO_USER), // 5 IO GPIO5, VSPICS0, HS1_DATA6, EMAC_RX_CLK + // 6 IO GPIO6, Flash CLK + // 7 IO GPIO7, Flash D0 + // 8 IO GPIO8, Flash D1 + AGPIO(GPIO_USER), // 9 IO GPIO9, Flash D2, U1RXD + AGPIO(GPIO_USER), // 10 IO GPIO10, Flash D3, U1TXD + // 11 IO GPIO11, Flash CMD + AGPIO(GPIO_USER), // 12 (I)O GPIO12, ADC2_CH5, TOUCH5, RTC_GPIO15, MTDI, HSPIQ, HS2_DATA2, SD_DATA2, EMAC_TXD3 (If driven High, flash voltage (VDD_SDIO) is 1.8V not default 3.3V. Has internal pull-down, so unconnected = Low = 3.3V. May prevent flashing and/or booting if 3.3V flash is connected and pulled high. See ESP32 datasheet for more details.) + AGPIO(GPIO_USER), // 13 IO GPIO13, ADC2_CH4, TOUCH4, RTC_GPIO14, MTCK, HSPID, HS2_DATA3, SD_DATA3, EMAC_RX_ER + AGPIO(GPIO_USER), // 14 IO GPIO14, ADC2_CH6, TOUCH6, RTC_GPIO16, MTMS, HSPICLK, HS2_CLK, SD_CLK, EMAC_TXD2 + AGPIO(GPIO_USER), // 15 (I)O GPIO15, ADC2_CH3, TOUCH3, MTDO, HSPICS0, RTC_GPIO13, HS2_CMD, SD_CMD, EMAC_RXD3 (If driven Low, silences boot messages from normal boot. Has internal pull-up, so unconnected = High = normal output.) + AGPIO(GPIO_USER), // 16 IO GPIO16, HS1_DATA4, U2RXD, EMAC_CLK_OUT + AGPIO(GPIO_USER), // 17 IO GPIO17, HS1_DATA5, U2TXD, EMAC_CLK_OUT_180 + AGPIO(GPIO_USER), // 18 IO GPIO18, VSPICLK, HS1_DATA7 + AGPIO(GPIO_USER), // 19 IO GPIO19, VSPIQ, U0CTS, EMAC_TXD0 + 0, // 20 + AGPIO(GPIO_USER), // 21 IO GPIO21, VSPIHD, EMAC_TX_EN + AGPIO(GPIO_USER), // 22 IO LED GPIO22, VSPIWP, U0RTS, EMAC_TXD1 + AGPIO(GPIO_USER), // 23 IO GPIO23, VSPID, HS1_STROBE + 0, // 24 + AGPIO(GPIO_USER), // 25 IO GPIO25, DAC_1, ADC2_CH8, RTC_GPIO6, EMAC_RXD0 + AGPIO(GPIO_USER), // 26 IO GPIO26, DAC_2, ADC2_CH9, RTC_GPIO7, EMAC_RXD1 + AGPIO(GPIO_USER), // 27 IO GPIO27, ADC2_CH7, TOUCH7, RTC_GPIO17, EMAC_RX_DV + 0, // 28 + 0, // 29 + 0, // 30 + 0, // 31 + AGPIO(GPIO_USER), // 32 IO GPIO32, XTAL_32K_P (32.768 kHz crystal oscillator input), ADC1_CH4, TOUCH9, RTC_GPIO9 + AGPIO(GPIO_USER), // 33 IO GPIO33, XTAL_32K_N (32.768 kHz crystal oscillator output), ADC1_CH5, TOUCH8, RTC_GPIO8 + AGPIO(GPIO_USER), // 34 I NO PULLUP GPIO34, ADC1_CH6, RTC_GPIO4 + AGPIO(GPIO_USER), // 35 I NO PULLUP GPIO35, ADC1_CH7, RTC_GPIO5 + AGPIO(GPIO_USER), // 36 I NO PULLUP GPIO36, SENSOR_VP, ADC_H, ADC1_CH0, RTC_GPIO0 + 0, // 37 NO PULLUP + 0, // 38 NO PULLUP + AGPIO(GPIO_USER), // 39 I NO PULLUP GPIO39, SENSOR_VN, ADC1_CH3, ADC_H, RTC_GPIO3 + 0 // Flag +}; + +/*********************************************************************************************\ + Known templates + +{"NAME":"AITHINKER CAM","GPIO":[4992,1,1,1,1,5088,1,1,1,1,1,1,1,1,5089,5090,0,5091,5184,5152,0,5120,5024,5056,0,0,0,0,4928,1,5094,5095,5092,0,0,5093],"FLAG":0,"BASE":1} +{"NAME":"Olimex ESP32-PoE","GPIO":[1,1,1,1,1,1,0,0,5536,1,1,1,1,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1} +{"NAME":"wESP32","GPIO":[0,0,1,0,1,1,0,0,1,1,1,1,5568,5600,1,0,0,0,0,1,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1} + +\*********************************************************************************************/ + +#endif // ESP32 + +#endif // _TASMOTA_TEMPLATE_ESP32_H_ diff --git a/tasmota/tasmota_version.h b/tasmota/tasmota_version.h index 3b8314f65..d1601408a 100644 --- a/tasmota/tasmota_version.h +++ b/tasmota/tasmota_version.h @@ -20,7 +20,7 @@ #ifndef _TASMOTA_VERSION_H_ #define _TASMOTA_VERSION_H_ -const uint32_t VERSION = 0x08020003; +const uint32_t VERSION = 0x08040000; // Lowest compatible version const uint32_t VERSION_COMPATIBLE = 0x07010006; diff --git a/tasmota/user_config_override_sample.h b/tasmota/user_config_override_sample.h index 5bd99175a..227006776 100644 --- a/tasmota/user_config_override_sample.h +++ b/tasmota/user_config_override_sample.h @@ -29,8 +29,7 @@ * (1) copy this file to "user_config_override.h" (It will be ignored by Git) * (2) define your own settings below * (3) for platformio: - * define USE_CONFIG_OVERRIDE as a build flags. - * ie1 : export PLATFORMIO_BUILD_FLAGS='-DUSE_CONFIG_OVERRIDE' + * All done. * for Arduino IDE: * enable define USE_CONFIG_OVERRIDE in my_user_config.h ****************************************************************************************************** diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index 1a45434a3..8ba98f91e 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -34,8 +34,8 @@ const uint16_t CHUNKED_BUFFER_SIZE = (MESSZ / 2) - 100; // Chunk buffer size (should be smaller than half mqtt_data size = MESSZ) const uint16_t HTTP_REFRESH_TIME = 2345; // milliseconds -#define HTTP_RESTART_RECONNECT_TIME 9000 // milliseconds -#define HTTP_OTA_RESTART_RECONNECT_TIME 20000 // milliseconds +const uint16_t HTTP_RESTART_RECONNECT_TIME = 9000; // milliseconds - Allow time for restart and wifi reconnect +const uint16_t HTTP_OTA_RESTART_RECONNECT_TIME = 28000; // milliseconds - Allow time for uploading binary, unzip/write to final destination and wifi reconnect #include #include @@ -44,11 +44,52 @@ const uint16_t HTTP_REFRESH_TIME = 2345; // milliseconds uint8_t *efm8bb1_update = nullptr; #endif // USE_RF_FLASH -enum UploadTypes { UPL_TASMOTA, UPL_SETTINGS, UPL_EFM8BB1, UPL_TASMOTASLAVE }; +enum UploadTypes { UPL_TASMOTA, UPL_SETTINGS, UPL_EFM8BB1, UPL_TASMOTACLIENT }; static const char * HEADER_KEYS[] = { "User-Agent", }; -const char HTTP_HEADER[] PROGMEM = +#ifdef USE_UNISHOX_COMPRESSION +#ifdef USE_JAVASCRIPT_ES6 +// insert D_HTML_LANGUAGE later +const size_t HTTP_HEADER1_SIZE = 377; +const char HTTP_HEADER1_COMPRESSED[] PROGMEM = "\x3D\x0F\xE1\x10\x98\x1D\x19\x0C\x64\x85\x50\xD0\x8F\xC3\xD0\x55\x0D\x09\x05\x7C" + "\x3C\x7C\x3F\xB2\xEC\xD7\xE6\x86\x7D\x78\xFE\xCB\xB3\x5F\x9A\x1A\x0C\x2B\xF7\x8F" + "\x87\xB0\xF6\x1F\x87\xA0\xA7\x62\x1F\x87\xA0\xD7\x56\x83\x15\x7F\xF3\xA3\xE1\xF6" + "\x2E\x8C\x1D\x67\x3E\x7D\x90\x21\x52\xEB\x1A\xCF\x87\xB0\xCF\x58\xF8\xCC\xFD\x1E" + "\xC4\x1E\x75\x3E\xA3\xE1\xEC\x1F\xD1\x28\x51\xF0\x46\x67\xA1\xB3\xAC\x7F\x44\xA1" + "\x47\x56\xF6\xD6\xD8\x47\x5F\x83\xB0\x99\xF0\xE4\x3A\x88\x5F\x9F\xCE\xBF\x07\x61" + "\x58\xE0\x99\xF3\xB0\xF6\x1D\x87\xE1\xE9\x5B\x41\x33\xF0\xFA\xF2\x3A\xD1\xF5\xE3" + "\xD0\xEC\x04\x19\x67\xA7\x83\xFE\x8C\xA3\xF0\xCE\xFE\x8D\x87\xCE\x16\x10\x47\x50" + "\x54\x75\x56\x1D\x54\x30\xEA\x18\x19\xF0\xFB\x3E\xCF\x0C\x71\xF3\xC7\xC3\xF0\x4C" + "\x0C\x58\xD7\xD4\x74\x1E\x74\x4C\x26\x35\xF5\x10\xE3\x22\xD1\x0E\xEF\x8E\xF1\xE0" + "\xD5\xE0\x48\xBA\x6A\x16\xFE\x64\x5E\x61\x30\xEB\x3E\x77\x7C\x77\x8F\x1E\x18\x7C" + "\xD3\xE1\xF8\xC7\x1D\xDD\x3B\xC7\x4A\x32\x18\xCF\x87\x74\x11\xA4\x1F\x0F\x87\xDD" + "\x33\x65\x1F\x67\x68\xFB\x19\x7E\xF0\xFE\x7C\x43\xEC\xF3\x04\x19\xC7\x78\xF0\x3E" + "\x11\xF0\xC1\xF0\xFC\x1F\xDE\x13\x07\xCE\x96\x20\x84\xCC\xDF\x51\x05\xBE\xA7\xCF" + "\xE7\x74\xFB\x0B\x2C\x43\xEC\xEA\x30\x77\x8F\x06"; +#define HTTP_HEADER1 Decompress(HTTP_HEADER1_COMPRESSED,HTTP_HEADER1_SIZE).c_str() +#else +const size_t HTTP_HEADER1_SIZE = 431; +const char HTTP_HEADER1_COMPRESSED[] PROGMEM = "\x3D\x0F\xE1\x10\x98\x1D\x19\x0C\x64\x85\x50\xD0\x8F\xC3\xD0\x55\x0D\x09\x05\x7C" + "\x3C\x7C\x3F\xB2\xEC\xD7\xE6\x86\x7D\x78\xFE\xCB\xB3\x5F\x9A\x1A\x0C\x2B\xF7\x8F" + "\x87\xB0\xF6\x1F\x87\xA0\xA7\x62\x1F\x87\xA0\xD7\x56\x83\x15\x7F\xF3\xA3\xE1\xF6" + "\x2E\x8C\x1D\x67\x3E\x7D\x90\x21\x52\xEB\x1A\xCF\x87\xB0\xCF\x58\xF8\xCC\xFD\x1E" + "\xC4\x1E\x75\x3E\xA3\xE1\xEC\x1F\xD1\x28\x51\xF0\x46\x67\xA1\xB3\xAC\x7F\x44\xA1" + "\x47\x56\xF6\xD6\xD8\x47\x5F\x83\xB0\x99\xF0\xE4\x3A\x88\x5F\x9F\xCE\xBF\x07\x61" + "\x58\xE0\x99\xF3\xB0\xF6\x1D\x87\xE1\xE9\x5B\x41\x33\xF0\xFA\xF2\x3A\xD1\xF5\xE3" + "\xD0\xEC\x04\x19\x67\xA7\x83\xFE\x8C\xA3\xF0\xCE\xFE\x8D\x87\xCE\x16\x10\x47\x50" + "\x54\x75\x56\x1D\x54\x30\xEA\x18\x19\xF0\xFB\x3E\xCF\x06\x05\xF0\x75\xB9\xC9\x8E" + "\x3B\xBE\x3B\xC7\xB7\xEE\x85\xFF\x90\x98\x18\xB1\xAF\xA8\xE8\x3C\xE8\x98\x4C\x6B" + "\xEA\x21\xC6\x45\xA2\x1D\xDF\x1D\xE3\xC1\xEE\x04\x4C\x38\xD5\xE0\x4F\xC3\x8D\x42" + "\xDF\xCC\x8B\xCC\x26\x1D\x67\xC1\x27\x0D\xF0\xC3\xBB\xA7\x78\xF6\xB1\xC7\x77\x4E" + "\xF1\xD2\x8C\x86\x33\xE1\xDD\x04\x69\x07\xC3\xE1\xF7\x4C\xD9\x47\xD9\xDA\x3E\xC6" + "\x5F\xBC\x3F\x9F\x10\xFB\x3C\xC1\x06\x70\x23\xE3\xE3\xE1\x1D\xD3\x07\x78\xF6\x8F" + "\xEF\x09\x83\xE7\x4B\x10\x42\x66\x6F\xA8\x82\xDF\x53\xE7\xF3\xBA\x7D\x85\x96\x21" + "\xF6\x75\x18\x3B\xC7\x83\xDC"; +#define HTTP_HEADER1 Decompress(HTTP_HEADER1_COMPRESSED,HTTP_HEADER1_SIZE).c_str() +#endif // USE_JAVASCRIPT_ES6 +#else +const char HTTP_HEADER1[] PROGMEM = "" "" "" @@ -78,7 +119,8 @@ const char HTTP_HEADER[] PROGMEM = "function wl(f){" // Execute multiple window.onload "window.addEventListener('load',f);" "}"; -#endif +#endif // USE_JAVASCRIPT_ES6 +#endif //USE_UNISHOX_COMPRESSION const char HTTP_SCRIPT_COUNTER[] PROGMEM = "var cn=180;" // seconds @@ -91,6 +133,58 @@ const char HTTP_SCRIPT_COUNTER[] PROGMEM = "}" "wl(u);"; +#ifdef USE_UNISHOX_COMPRESSION +#ifdef USE_SCRIPT_WEB_DISPLAY +const size_t HTTP_SCRIPT_ROOT_SIZE = 706; +const char HTTP_SCRIPT_ROOT_COMPRESSED[] PROGMEM = "\x33\xBF\xAF\x98\xF0\xA3\xE1\xC8\x78\x23\x02\xF8\x3A\xDC\xE4\x15\x9D\xD1\x87\x78" + "\xF6\x99\xDF\xD5\x9F\x0F\xB3\xEC\xF1\xA6\x0E\xE8\x56\x74\xBF\x8F\x0B\x1A\xFA\xBC" + "\x74\x09\xF0\xF5\x0A\x3E\x1F\x0E\x43\xBC\x7B\x4A\xCF\x83\x0F\x01\x84\xEF\xE5\x5A" + "\x35\xE0\xBA\x3B\xA1\x51\xDE\x3C\x1E\xED\x30\x77\x4D\x87\xF0\xF9\xC2\xC2\x08\xEF" + "\x1E\xD3\x61\xD2\xC7\x67\xE8\xEE\x9D\xE3\xC1\xEE\x36\x1F\x39\x8F\xA2\x36\x10\xD2" + "\x08\x85\x55\x0C\x2F\xB3\x50\xB7\xEA\x3B\xA7\x78\xF0\x6C\x3A\x67\x7D\xD8\x86\x5E" + "\xAB\xA6\x18\xAB\xE1\xE6\x7C\x04\x3D\xA0\xEE\x9D\xE3\xDB\xA6\x0E\xE9\xB0\xE9\xF7" + "\x62\x19\x17\xAA\xE9\x9F\x0F\x87\x30\xFD\x1F\xA2\x36\x1D\x3D\x57\x42\xFC\x7C\x3E" + "\x1C\xA6\xC8\x10\x78\x07\xF1\xF0\xD8\x74\xFB\xF0\xCC\xEF\x32\xA6\x6C\xA3\xA7\xD8" + "\xC0\xAC\x36\x77\x4E\xC3\xDB\x47\xB8\xEC\x1E\x3A\x8F\x61\xE9\x56\x38\x26\xBD\x46" + "\x41\x33\xE1\xF6\x3F\xA2\x50\xA3\xCC\xE4\x6C\xFA\x3E\x8F\xB3\xF0\xF6\x1D\xE2\x04" + "\x6C\x2B\xC0\x85\x85\x7C\xFC\x3D\x28\x50\x24\xD7\x1A\x08\x35\xCE\xCA\x14\x7E\x1E" + "\x94\x20\x24\xD8\x60\x87\x60\x43\xF0\xF4\x3B\x2B\xE0\x93\x64\x33\xDC\x76\x0F\x1D" + "\x47\xB0\xFA\x3E\x8F\xB3\xF0\xF4\x13\x4C\xC1\x0F\x60\xA6\x6C\xA3\xAE\xC2\xD1\xEE" + "\x3C\xC3\x7D\x4F\xE7\x83\x19\xD4\x75\x8F\xBD\x1E\x15\x47\x99\xEC\x3B\xC7\x86\x38" + "\xEE\x9F\x61\x1C\x87\xD9\xDE\x3A\x16\xF7\x3F\x90\xA2\xA2\x1A\x41\x1F\x3C\x78\x3D" + "\xC7\xB8\xF1\xA6\x11\xDD\xF9\x8F\x0A\x3B\xC8\xF6\x9B\x0E\x98\x31\xF1\xDD\x3E\xC8" + "\x78\x99\x51\xF6\x75\x1F\x67\x43\xB4\x34\xF8\x72\x1F\x67\x6C\xAC\xEA\xAF\x8B\x67" + "\x78\xF0\x6C\x3A\x79\xF0\x87\x74\xEF\x1E\x02\xA3\xE7\x9D\x02\x27\x20\x36\x75\x1F" + "\x42\x1D\xE3\xC1\xEE\x3D\xC0\x89\xCA\x77\x99\x9D\x9D\xD1\x97\xF3\xAB\x4C\xEF\xE7" + "\x78\xF6\x85\x67\x74\xFB\x3F\x5E\x33\x3E\x1F\x67\x6F\x4C\xEF\xE7\x6C\xFB\x3F\x67" + "\xD9\xDB\x19\x7F\x3B\xC7\x80\x46\xC3\x74\x12\x30\xD0\x42\xE6\x78\x14\xF1\x4F\x98" + "\xF0\xA3\xE1\xC6\x40\x8D\x8D\x8C\xF9\xDD\x30\x77\x8F\x6E\x98\x47\x74\xC1\xDE\x47" + "\xB4\x14\x37\xA0\x42\xCB\xCF\x72\x61\x79\xA3\xDA\x09\x9C\xE1\x02\x1E\x60\x7B\x8D"; +#define HTTP_SCRIPT_ROOT Decompress(HTTP_SCRIPT_ROOT_COMPRESSED,HTTP_SCRIPT_ROOT_SIZE).c_str() +#else +const size_t HTTP_SCRIPT_ROOT_SIZE = 486; +const char HTTP_SCRIPT_ROOT_COMPRESSED[] PROGMEM = "\x30\x2F\x83\xAD\xCE\x41\x59\xDD\x18\x77\x8F\x69\x9D\xFD\x59\xF0\xFB\x3E\xCF\x1A" + "\x60\xEE\x85\x67\x4B\xF8\xF0\xB1\xAF\xAB\xC7\x40\x9F\x0F\x50\xA3\xE1\xF0\xE4\x3B" + "\xC7\xB4\xAC\xF8\x30\xF0\x18\x4E\xFE\x55\xA3\x5E\x0B\xA3\xBA\x15\x1D\xE3\xC1\xEE" + "\xD3\x07\x74\xD8\x7F\x0F\x9C\x2C\x20\x8E\xF1\xED\x36\x1D\x2C\x76\x7E\x8E\xE9\xDE" + "\x3C\x1E\xE3\x61\xF3\x98\xFA\x23\x61\x0D\x20\x88\x55\x50\xC2\xFB\x35\x0B\x7E\xA3" + "\xBA\x77\x8F\x06\xC3\xA6\x77\xDD\x88\x65\xEA\xBA\x61\x8A\xBE\x1E\x67\xC0\x43\xDA" + "\x0E\xE9\xDE\x3D\xBA\x60\xEE\x9B\x0E\x9F\x76\x21\x91\x7A\xAE\x99\xF0\xF8\x73\x0F" + "\xD1\xFA\x23\x61\xD3\xD5\x74\x2F\xC7\xC3\xE1\xCA\x6C\x81\x07\x80\x7F\x1F\x0D\x87" + "\x4F\xBF\x0C\xCE\xF3\x2A\x2B\x66\xCA\x3A\x7D\x8C\x0A\xC3\x67\x74\xEC\x3D\xB4\x7B" + "\x8E\xC1\xE3\xA8\xF6\x1E\x95\x63\x82\x6B\xD4\x64\x13\x3E\x1F\x63\xFA\x25\x0A\x3C" + "\xCE\x46\xCF\xA3\xE8\xFB\x3F\x0F\x61\xDE\x20\x46\xC2\xBC\x08\x58\x57\xCF\xC3\xD2" + "\x85\x02\x4D\x71\xA0\x83\x5C\xEC\xA1\x47\xE1\xE9\x42\x02\x4D\x86\x08\x76\x04\x3F" + "\x0F\x43\xB2\xBE\x09\x36\x43\x3D\xC7\x60\xF1\xD4\x7B\x0F\xA3\xE8\xFB\x3F\x0F\x41" + "\x34\xCC\x10\xF6\x0A\x66\xCA\x3A\xEC\x2D\x1E\xE3\xCC\x37\xD4\xFE\x78\x31\x9D\x47" + "\x58\xFB\xD1\xE1\x54\x79\x9E\xC3\xBC\x78\x63\x8E\xE9\xF6\x11\xC8\x7D\x9D\xE3\xA1" + "\x6F\x73\xF9\x0A\x2A\x2B\x21\xA4\x11\xF3\xC7\x83\xDC\x7B\x8F\x06\xC3\xA6\x0C\x7C" + "\x77\x4F\xB2\x1E\x26\x54\x7D\x9D\x47\xD9\xD0\xED\x0D\x3E\x1C\x87\xD9\xDB\x2B\x3A" + "\xAB\xE2\xD9\xDE\x3C\x1B\x0E\x9E\x7C\x21\xDD\x3B\xC7\x80\xA8\xF9\xE7\x40\x89\xC7" + "\xB5\x9D\x47\xD0\x87\x78\xF0\x7B\x8D"; +#define HTTP_SCRIPT_ROOT Decompress(HTTP_SCRIPT_ROOT_COMPRESSED,HTTP_SCRIPT_ROOT_SIZE).c_str() +#endif // USE_SCRIPT_WEB_DISPLAY +#else const char HTTP_SCRIPT_ROOT[] PROGMEM = #ifdef USE_SCRIPT_WEB_DISPLAY "var rfsh=1;" @@ -109,7 +203,7 @@ const char HTTP_SCRIPT_ROOT[] PROGMEM = "}" "};" "if (rfsh) {" - "x.open('GET','.?m=1'+a,true);" // ?m related to WebServer->hasArg("m") + "x.open('GET','.?m=1'+a,true);" // ?m related to Webserver->hasArg("m") "x.send();" "lt=setTimeout(la,%d);" // Settings.web_refresh "}" @@ -146,12 +240,27 @@ const char HTTP_SCRIPT_ROOT[] PROGMEM = "eb('l1').innerHTML=s;" "}" "};" - "x.open('GET','.?m=1'+a,true);" // ?m related to WebServer->hasArg("m") + "x.open('GET','.?m=1'+a,true);" // ?m related to Webserver->hasArg("m") "x.send();" "lt=setTimeout(la,%d);" // Settings.web_refresh "}"; #endif // USE_SCRIPT_WEB_DISPLAY +#endif //USE_UNISHOX_COMPRESSION +#ifdef USE_UNISHOX_COMPRESSION +const size_t HTTP_SCRIPT_ROOT_PART2_SIZE = 222; +const char HTTP_SCRIPT_ROOT_PART2_COMPRESSED[] PROGMEM = "\x30\x2F\x83\xAD\xCE\x41\x06\x77\x4C\xCE\xAD\x3A\x86\x1D\xE3\xDB\xA6\x0E\xEB\x1C" + "\x77\x4F\xBF\x1F\x67\x78\xEF\x1E\xDD\x30\x77\x4C\xCF\x87\xC3\xEC\x51\xF6\x7F\x8F" + "\xF1\x99\xF0\xF8\x7D\x88\x7D\x9D\xE3\xDA\x67\x7F\x5E\x08\xF8\xC7\x1D\xD3\xEF\xC1" + "\x1C\xC3\xEC\xEF\x1D\x08\xCE\xC2\x16\xCF\x2A\x01\x85\x87\x9D\x3D\x46\x41\x33\xA0" + "\xEB\x0C\xD0\x7B\xF8\x2F\x84\x3E\x1F\x61\x6F\x3B\xF9\xD6\x3D\xFB\x13\x5F\x51\xDD" + "\xAC\x5F\xD1\xE1\x54\x75\x7C\x78\x71\xDD\x3E\xCE\xDF\x82\x3B\x67\xD9\xF4\x7D\x1D" + "\x40\x89\x14\x10\xE2\x9D\xE3\xA8\x57\x82\x3B\xA7\xD9\xDB\x04\x1D\x14\xE5\x10\x21" + "\xE8\xA7\x6C\xFB\x3A\x8E\x46\xCF\xA3\xE8\xEA\xD6\x7D\x1F\x47\x78\xEF\x1F\x67\x83" + "\xDC\x7B\x88\x2B\x3B\xA7\xD9\xFA\x3E\xCE\xD9\x99\xDB\xD3\xB6\x7D\x9F\x0F\xB3\xB6" + "\x30\xEF\x1E\x0F\x70\xF8\x47\x74\x2B\x3B\xC7\x83"; +#define HTTP_SCRIPT_ROOT_PART2 Decompress(HTTP_SCRIPT_ROOT_PART2_COMPRESSED,HTTP_SCRIPT_ROOT_PART2_SIZE).c_str() +#else const char HTTP_SCRIPT_ROOT_PART2[] PROGMEM = "function lc(v,i,p){" "if(eb('s')){" // Check if Saturation is in DOM otherwise javascript fails on la() @@ -163,6 +272,7 @@ const char HTTP_SCRIPT_ROOT_PART2[] PROGMEM = "la('&'+v+i+'='+p);" "}" "wl(la);"; +#endif //USE_UNISHOX_COMPRESSION const char HTTP_SCRIPT_WIFI[] PROGMEM = "function c(l){" @@ -170,13 +280,45 @@ const char HTTP_SCRIPT_WIFI[] PROGMEM = "eb('p1').focus();" "}"; -const char HTTP_SCRIPT_RELOAD[] PROGMEM = - "setTimeout(function(){location.href='.';}," STR(HTTP_RESTART_RECONNECT_TIME) ");"; - -// Local OTA upgrade requires more time to complete cp: before web ui should be reloaded -const char HTTP_SCRIPT_RELOAD_OTA[] PROGMEM = - "setTimeout(function(){location.href='.';}," STR(HTTP_OTA_RESTART_RECONNECT_TIME) ");"; +const char HTTP_SCRIPT_RELOAD_TIME[] PROGMEM = + "setTimeout(function(){location.href='.';},%d);"; +#ifdef USE_UNISHOX_COMPRESSION +const size_t HTTP_SCRIPT_CONSOL_SIZE = 853; +const char HTTP_SCRIPT_CONSOL_COMPRESSED[] PROGMEM = "\x33\xBF\xAF\x71\xF0\xE3\x3A\x8B\x44\x3E\x1C\x67\x82\x30\x2F\x83\xAD\xCE\x41\x1D" + "\xD1\x87\x78\xF6\x99\xDF\xD0\x67\x56\x1F\x0F\xB3\xEC\xEA\xA3\xC0\x61\x3B\xF9\x56" + "\x8D\x78\x2E\x8E\xE8\x54\x77\x8F\x14\x7C\x63\x8E\xE9\xF7\x47\x21\xF6\x77\x8F\x05" + "\xA6\x0E\xE8\xC3\xE1\xF0\xE4\x3B\xC7\xB4\x83\x3E\x31\xC7\x74\xFB\x0C\xE4\x3E\xCE" + "\xF1\xE0\xB0\xF8\x7D\x9F\xA0\xCE\x43\xE1\xF6\x76\xC9\xF0\x78\x23\x21\x65\xF2\xD2" + "\x0F\x06\x8C\xCE\x7D\x47\x74\x33\xA1\x9D\x84\x2D\x9D\xE3\xC0\x21\x45\x3E\x1F\x67" + "\xD9\xE2\x8E\x9E\x0F\xF8\x10\x45\x58\x30\xF8\x71\x11\xBD\x2A\x01\xF1\xEE\x3E\x02" + "\x35\x13\xC1\xEE\xD3\x07\x74\x11\xA6\x1F\x87\xCF\x71\xDE\x3D\xBA\x60\xEE\x9B\x0F" + "\xE1\xF3\x85\x84\x11\xDE\x3D\xA6\xC3\xA5\x8E\xCF\xD1\xDD\x3B\xC7\x83\xDC\x6C\x3E" + "\x73\x1F\x44\x6C\x21\xA4\x11\x0A\xAA\x18\x5F\x66\xA1\x6F\xD4\x77\x4E\xF1\xE0\xD8" + "\x74\xCE\xFB\xB1\x0C\xBD\x57\x4C\x31\x57\xC3\xCC\xF8\x08\x7C\x28\x1D\xD0\x41\xCA" + "\x8E\x9F\x76\x21\x91\x7A\xAE\x99\xF0\xF8\x73\x0F\xD1\xFA\x23\x61\xD3\xD5\x74\x2F" + "\xC7\xC3\xE1\xCA\x6C\x81\x07\x87\x03\x69\xD4\x21\xE0\x43\xE1\xB0\xE9\xF7\xE1\x99" + "\xDE\x65\x4C\xD9\x47\x4F\x0C\x0B\x68\xEE\x9D\x87\xB8\xE4\x3B\x0E\xF1\xE0\xB4\x43" + "\xE0\x87\x4F\x0A\xD3\x14\x77\x4E\xF1\xE3\x4C\x1D\xD0\x44\x92\x7C\x3E\x1C\x67\x78" + "\xF6\x95\x02\x2F\x0A\x27\xB8\xDA\x09\x38\x29\xB4\xE8\x13\xE1\xEA\x14\x7E\x02\x2E" + "\x06\x76\xCF\x86\xD3\xC1\xEE\x05\xDE\x1E\x4F\x71\xE0\xD8\x74\xC1\x8F\x8E\xE9\xF6" + "\x43\xC4\xCA\x8F\xB3\xA8\xFB\x0F\xC7\x68\x33\x94\x7C\x3E\xCE\xD9\x68\x87\x6F\x0E" + "\xAA\xF8\xB6\x77\x8F\x06\xC3\xA7\x9F\x08\x77\x4E\xF1\xE0\xF7\x05\x47\xCF\x3A\x04" + "\x4E\x4A\x4E\xA3\xE8\x43\xBC\x78\xFB\xA1\x7F\xE4\x62\xC2\xF3\x3C\x1E\xE1\xF0\x8E" + "\xE8\x47\x78\xF0\x67\x7F\x42\x83\x3E\x1E\xF1\xEF\x9D\x41\xF0\x23\xF2\xF4\x28\xEE" + "\x9D\xE3\xDA\x08\x7C\xA2\x9D\x2C\x41\x09\x99\xBE\xA2\x0B\x7D\x4F\x9F\xCE\xE9\xF6" + "\x68\xCC\x84\xC1\xFE\x3E\xCE\xA0\x44\xE2\xDD\x82\x0F\x12\xA3\x81\x13\x97\xB3\xA8" + "\x33\xE3\x3A\x1A\x33\x22\x0F\x04\x67\x8D\x30\x77\x4E\x5F\xCF\x87\xC2\x0C\xFF\x1F" + "\xE3\x98\xCF\x87\xC2\x0C\xEF\x1E\xD1\xC7\x4B\x17\x58\x1E\x0D\x18\x13\xA6\x7C\x3E" + "\xF0\xC1\x83\xEC\xF0\x7B\x8E\x5F\xCF\x87\xC2\x0C\xED\x1D\xD3\xB6\x76\xC3\xE3\xF0" + "\x50\x60\x85\xC4\x31\xFA\x3F\x47\x74\x3E\x3E\x02\x24\xB3\xBC\x75\x0E\x04\x2E\x2E" + "\x85\x06\x7B\xC1\xF1\xD6\x72\x1E\xF9\xFE\x3F\xC7\xD9\xF6\x77\x8F\x3C\x67\xC3\xE1" + "\x06\x76\x8E\xE9\xC6\x7E\x1D\x67\x59\x07\xC0\x83\x88\x1C\x64\x0A\x78\x41\xC9\x67" + "\xC3\xE1\x06\x7E\x8F\xD1\xDD\x04\x4C\xC4\xFC\x39\x11\xFA\x3F\x44\x28\x33\xA0\xCC" + "\x18\x77\x4E\xF1\xD4\x28\x33\xA0\xBE\x04\x1E\x44\x01\x0B\x1C\x3B\xC7\x50\x7C\x7C" + "\x38\xCE\xF1\xEE\x3B\xC7\x83\xDC\x43\xE1\x1D\xD1\x47\x78\xF0"; +#define HTTP_SCRIPT_CONSOL Decompress(HTTP_SCRIPT_CONSOL_COMPRESSED,HTTP_SCRIPT_CONSOL_SIZE).c_str() +#else const char HTTP_SCRIPT_CONSOL[] PROGMEM = "var sn=0,id=0;" // Scroll position, Get most of weblog initially "function l(p){" // Console log and command service @@ -205,7 +347,7 @@ const char HTTP_SCRIPT_CONSOL[] PROGMEM = "sn=t.scrollTop;" "}" "};" - "x.open('GET','cs?c2='+id+o,true);" // Related to WebServer->hasArg("c2") and WebGetArg("c2", stmp, sizeof(stmp)) + "x.open('GET','cs?c2='+id+o,true);" // Related to Webserver->hasArg("c2") and WebGetArg("c2", stmp, sizeof(stmp)) "x.send();" "}" "lt=setTimeout(l,%d);" @@ -226,17 +368,97 @@ const char HTTP_SCRIPT_CONSOL[] PROGMEM = "});" "}" "wl(h);"; // Add console command key eventlistener after name has been synced with id (= wl(jd)) +#endif //USE_UNISHOX_COMPRESSION const char HTTP_MODULE_TEMPLATE_REPLACE[] PROGMEM = "}2%d'>%s (%d}3"; // }2 and }3 are used in below os.replace +const char HTTP_MODULE_TEMPLATE_REPLACE_INDEX[] PROGMEM = + "}2%d'>%s (%d)}3"; // }2 and }3 are used in below os.replace +const char HTTP_MODULE_TEMPLATE_REPLACE_NO_INDEX[] PROGMEM = + "}2%d'>%s}3"; // }2 and }3 are used in below os.replace + +#if defined(USE_UNISHOX_COMPRESSION) && defined(ESP32) +// no compression on ESP8266, we would lose 16 bytes +const size_t HTTP_SCRIPT_MODULE_TEMPLATE_SIZE = 602; +const char HTTP_SCRIPT_MODULE_TEMPLATE_COMPRESSED[] PROGMEM = "\x33\xBF\xAC\xF1\xD4\x2B\xC7\x83\x02\xF8\x3A\xDC\xE4\x1B\x3B\xBA\x75\x1A\x8E\xF1" + "\xED\x33\xBF\xAC\x3E\x09\x81\x8B\x1A\xFA\x8E\x81\xFD\xDD\x32\x61\x31\xAF\xA8\xEE" + "\x9F\x78\x32\xB7\x38\xFB\x3B\xC7\x8C\x3A\x53\x36\x51\x07\x9D\x4F\xA8\xF9\xA7\x83" + "\x51\xD2\xC6\x0C\x7C\x21\x06\x2B\x42\x10\xEE\xE1\xDE\x3C\x1E\xE0\x44\xCD\xB2\x8E" + "\xE8\xF1\xD5\xE0\x41\xCD\xAC\xF9\xE3\xF4\x71\x91\xB0\xC1\x86\x71\x9D\x44\x38\xF8" + "\x71\x9D\x44\x19\xD4\x30\xEA\x08\xEA\xA3\xE1\xAB\xC7\x74\xFB\x3C\x85\x1F\x67\x6C" + "\x78\xEF\x1D\x42\xCF\x9E\x3F\x47\x19\x1B\x0E\x37\x08\xC1\xE0\x23\xE5\x1D\x01\x07" + "\x4D\xF1\xD0\x27\xC3\xD4\x28\xF0\x63\x3E\x77\x74\xF8\x11\xE3\x4F\x1A\x75\x9D\x67" + "\x78\xF6\x8C\x04\x5B\xC7\xBD\xA7\x59\xC8\x7B\xE7\x42\x19\x7F\x7D\x45\xD8\x23\x3C" + "\x0C\x3A\x7D\x8D\xC3\x36\x08\x3B\x70\x24\xE0\x87\x78\xF0\x7B\x82\x3E\x0A\x04\xAC" + "\xC8\xE3\x3C\x16\x9E\x81\x1E\x34\xED\x9D\xB3\xBC\x7B\x43\x3E\x0A\xF1\xEF\x69\xEF" + "\x82\x17\x2A\x01\xE7\x8D\x30\x77\x6C\xF8\x7C\x0C\xEF\x1E\xD1\xC0\x89\x50\xE3\x70" + "\x8C\x1E\x07\x7D\xD9\xA1\xE0\xF7\x1E\xEF\x1F\x87\xE1\xF0\xE6\x90\x21\x64\x47\x21" + "\xE0\xB4\xF4\x3E\x0E\x04\x2C\x8D\x9D\xD3\xBB\xA7\xA1\xC8\xCE\xF1\xDA\x3B\xA7\xD9" + "\xDC\x3E\xCE\xD9\x69\xDE\x3C\xF4\xEA\xA3\xBC\x78\x3D\xCC\x71\xDD\x3E\xC5\x1F\x67" + "\x6C\x78\xEF\x1D\x0C\xEC\x21\x6C\xF8\x2C\xED\x9C\x87\x82\xA3\xA7\xA8\xC8\x26\x74" + "\x33\xDF\x68\xED\x0B\x68\xC8\xF8\x77\x47\x1F\x87\x19\xDE\x3B\x47\xD9\xF6\x79\x9F" + "\x64\x2B\x44\x11\xF1\xF6\x08\xDC\x58\xF8\xD0\xEE\xF8\xEA\x1E\x04\x3E\x42\xF3\xC7" + "\x4F\xB1\x81\x58\x6C\xEE\x9D\x87\xB8\xE5\x1D\x84\x3C\x75\x1E\xC3\xD0\x10\x78\x4B" + "\x40\x83\x9E\x9F\x67\xB0\xEF\x02\x35\xD3\x96\x76\x10\xF1\xD4\x7B\x0F\x43\xB0\x10" + "\x6F\x1F\x87\xB0\xEF\x1E\x18\xE3\xBA\x7D\x8F\x1F\x67\x6C\x78\xEF\x1D\x37\xB9\xFC" + "\x85\x15\x10\xD2\x08\xF9\x80\x8D\x48\x10\x72\x13\xBA\x3C\x7A\x1C\x48\xEF\x1D\xA2" + "\x04\x3E\x47\x4F\x3F\x1E\x34\xC0\x20\xD0\x3D\xA0\x85\xC9\xF9\xE0\xF7\x1E\xE3"; +#define HTTP_SCRIPT_MODULE_TEMPLATE Decompress(HTTP_SCRIPT_MODULE_TEMPLATE_COMPRESSED,HTTP_SCRIPT_MODULE_TEMPLATE_SIZE).c_str() +#else const char HTTP_SCRIPT_MODULE_TEMPLATE[] PROGMEM = +#ifdef ESP8266 "var os;" "function sk(s,g){" // s = value, g = id and name "var o=os.replace(/}2/g,\"
    Protocol" + + "
    " D_STR_PROTOCOL "" + htmlSelectClimateProtocol(KEY_PROTOCOL, climate[chan]->next.protocol) + "
    Model" + + "
    " D_STR_MODEL "" + htmlSelectModel(KEY_MODEL, climate[chan]->next.model) + "
    Power" + + "
    " D_STR_POWER "" + htmlSelectBool(KEY_POWER, climate[chan]->next.power) + "
    Mode" + + "
    " D_STR_MODE "" + htmlSelectMode(KEY_MODE, climate[chan]->next.mode) + "
    Temp" + "
    " D_STR_TEMP "" "" "
    Fan Speed" + + "
    " D_STR_FAN "" + htmlSelectFanspeed(KEY_FANSPEED, climate[chan]->next.fanspeed) + "
    Swing (V)" + + "
    " D_STR_SWINGV "" + htmlSelectSwingv(KEY_SWINGV, climate[chan]->next.swingv) + "
    Swing (H)" + + "
    " D_STR_SWINGH "" + htmlSelectSwingh(KEY_SWINGH, climate[chan]->next.swingh) + "
    Quiet" + + "
    " D_STR_QUIET "" + htmlSelectBool(KEY_QUIET, climate[chan]->next.quiet) + "
    Turbo" + + "
    " D_STR_TURBO "" + htmlSelectBool(KEY_TURBO, climate[chan]->next.turbo) + "
    Econo" + + "
    " D_STR_ECONO "" + htmlSelectBool(KEY_ECONO, climate[chan]->next.econo) + "
    Light" + + "
    " D_STR_LIGHT "" + htmlSelectBool(KEY_LIGHT, climate[chan]->next.light) + "
    Filter" + + "
    " D_STR_FILTER "" + htmlSelectBool(KEY_FILTER, climate[chan]->next.filter) + "
    Clean" + + "
    " D_STR_CLEAN "" + htmlSelectBool(KEY_CLEAN, climate[chan]->next.clean) + "
    Beep" + + "
    " D_STR_BEEP "" + htmlSelectBool(KEY_BEEP, climate[chan]->next.beep) + "
    Force resend" + @@ -1260,9 +1276,9 @@ void handleInfo(void) { "Last IR Received: " + lastIrReceived + " (" + timeSince(lastIrReceivedTime) + ")
    " #endif // IR_RX - "Duplicate Wifi networks: " + + "Duplicate " D_STR_WIFI " networks: " + String(HIDE_DUPLICATE_NETWORKS ? "Hide" : "Show") + "
    " - "Min Wifi signal required: " + "Min " D_STR_WIFI " signal required: " #ifdef MIN_SIGNAL_STRENGTH + String(static_cast(MIN_SIGNAL_STRENGTH)) + #else // MIN_SIGNAL_STRENGTH @@ -1271,9 +1287,9 @@ void handleInfo(void) { "%
    " "Serial debugging: " #if DEBUG - + String(isSerialGpioUsedByIr() ? "Off" : "On") + + + String(isSerialGpioUsedByIr() ? D_STR_OFF : D_STR_ON) + #else // DEBUG - "Off" + D_STR_OFF #endif // DEBUG "
    " #if REPORT_VCC @@ -1289,6 +1305,7 @@ void handleInfo(void) { : "Disconnected " + timeSince(lastConnectedTime)) + ")
    " "Disconnections: " + String(mqttDisconnectCounter - 1) + "
    " + "Max Packet Size: " + MQTT_MAX_PACKET_SIZE + " bytes
    " "Client id: " + MqttClientId + "
    " "Command topic(s): " + listOfCommandTopics() + "
    " "Acknowledgements topic: " + MqttAck + "
    " @@ -1330,6 +1347,7 @@ void handleInfo(void) { timeElapsed(lastDiscovery.elapsed()) : String("Never"))) + "
    " + "Discovery topic: " + MqttDiscovery + "
    " + #endif // MQTT_DISCOVERY_ENABLE "Command topics: " + MqttClimate + channel_re + '/' + MQTT_CLIMATE_CMND + '/' + kClimateTopics + @@ -1339,7 +1357,7 @@ void handleInfo(void) { "

    " // Page footer "

    " - "(Note: Page will refresh every 60 seconds.)" + "(Note: Page will refresh every 60 " D_STR_SECONDS ".)" "

    "; html += addJsReloadUrl(kUrlInfo, 60, false); html += htmlEnd(); @@ -1401,7 +1419,7 @@ void handleClearMqtt(void) { htmlHeader(F("Clearing saved info from MQTT"), F("Removing all saved settings for this device from " "MQTT.")) + - "

    Device restarting. Try connecting in a few seconds.

    " + + "

    Device restarting. Try connecting in a few " D_STR_SECONDS ".

    " + addJsReloadUrl(kUrlRoot, 10, true) + htmlEnd()); // Do the clearing. @@ -1423,7 +1441,7 @@ void handleReset(void) { server.send(200, "text/html", htmlHeader(F("Reset WiFi Config"), F("Resetting the WiFiManager config back to defaults.")) + - "

    Device restarting. Try connecting in a few seconds.

    " + + "

    Device restarting. Try connecting in a few " D_STR_SECONDS ".

    " + addJsReloadUrl(kUrlRoot, 10, true) + htmlEnd()); // Do the reset. @@ -1456,7 +1474,7 @@ void handleReboot() { #endif server.send(200, "text/html", htmlHeader(F("Device restarting.")) + - "

    Try connecting in a few seconds.

    " + + "

    Try connecting in a few " D_STR_SECONDS ".

    " + addJsReloadUrl(kUrlRoot, kRebootTime, true) + htmlEnd()); doRestart("Reboot requested"); @@ -2012,7 +2030,8 @@ void setup_wifi(void) { if (!wifiManager.autoConnect()) // Reboot. A.k.a. "Have you tried turning it Off and On again?" - doRestart("Wifi failed to connect and hit timeout. Rebooting...", true); + doRestart(D_STR_WIFI " failed to connect and hit timeout. Rebooting...", + true); #if MQTT_ENABLE strncpy(MqttServer, custom_mqtt_server.getValue(), kHostnameLength); @@ -2184,7 +2203,8 @@ void setup(void) { server.send(200, "text/html", htmlHeader(F("Updating firmware")) + "
    " - "

    Warning! Don't power off the device for 60 seconds!

    " + "

    Warning! Don't " D_STR_POWER " " D_STR_OFF " the device for " + "60 " D_STR_SECONDS "!

    " "

    The firmware is uploading and will try to flash itself. " "It is important to not interrupt the process.

    " "

    The firmware upload seems to have " + @@ -2768,12 +2788,12 @@ bool sendIRCode(IRsend *irsend, decode_type_t const ir_type, } else { debug("Failed to send IR Message:"); } - debug("Type:"); + debug(D_STR_PROTOCOL ": "); debug(String(ir_type).c_str()); // For "long" codes we basically repeat what we got. if (hasACState(ir_type) || ir_type == PRONTO || ir_type == RAW || ir_type == GLOBALCACHE) { - debug("Code: "); + debug(D_STR_CODE ": "); debug(code_str); // Confirm what we were asked to send was sent. #if MQTT_ENABLE @@ -2792,9 +2812,9 @@ bool sendIRCode(IRsend *irsend, decode_type_t const ir_type, } #endif // MQTT_ENABLE } else { // For "short" codes, we break it down a bit more before we report. - debug(("Code: 0x" + uint64ToString(code, 16)).c_str()); - debug(("Bits: " + String(bits)).c_str()); - debug(("Repeats: " + String(repeat)).c_str()); + debug((D_STR_CODE ": 0x" + uint64ToString(code, 16)).c_str()); + debug((D_STR_BITS ": " + String(bits)).c_str()); + debug((D_STR_REPEAT ": " + String(repeat)).c_str()); #if MQTT_ENABLE if (success) { mqtt_client.publish(MqttAck.c_str(), (String(ir_type) + @@ -2944,40 +2964,47 @@ void updateClimate(stdAc::state_t *state, const String str, *state = jsonToState(*state, payload.c_str()); else #endif // MQTT_CLIMATE_JSON - if (str.equals(prefix + KEY_PROTOCOL)) + if (str.equals(prefix + KEY_PROTOCOL)) { state->protocol = strToDecodeType(payload.c_str()); - else if (str.equals(prefix + KEY_MODEL)) + } else if (str.equals(prefix + KEY_MODEL)) { state->model = IRac::strToModel(payload.c_str()); - else if (str.equals(prefix + KEY_POWER)) + } else if (str.equals(prefix + KEY_POWER)) { state->power = IRac::strToBool(payload.c_str()); - else if (str.equals(prefix + KEY_MODE)) +#if MQTT_CLIMATE_HA_MODE + if (!state->power) state->mode = stdAc::opmode_t::kOff; +#endif // MQTT_CLIMATE_HA_MODE + } else if (str.equals(prefix + KEY_MODE)) { state->mode = IRac::strToOpmode(payload.c_str()); - else if (str.equals(prefix + KEY_TEMP)) +#if MQTT_CLIMATE_HA_MODE + state->power = (state->mode != stdAc::opmode_t::kOff); +#endif // MQTT_CLIMATE_HA_MODE + } else if (str.equals(prefix + KEY_TEMP)) { state->degrees = payload.toFloat(); - else if (str.equals(prefix + KEY_FANSPEED)) + } else if (str.equals(prefix + KEY_FANSPEED)) { state->fanspeed = IRac::strToFanspeed(payload.c_str()); - else if (str.equals(prefix + KEY_SWINGV)) + } else if (str.equals(prefix + KEY_SWINGV)) { state->swingv = IRac::strToSwingV(payload.c_str()); - else if (str.equals(prefix + KEY_SWINGH)) + } else if (str.equals(prefix + KEY_SWINGH)) { state->swingh = IRac::strToSwingH(payload.c_str()); - else if (str.equals(prefix + KEY_QUIET)) + } else if (str.equals(prefix + KEY_QUIET)) { state->quiet = IRac::strToBool(payload.c_str()); - else if (str.equals(prefix + KEY_TURBO)) + } else if (str.equals(prefix + KEY_TURBO)) { state->turbo = IRac::strToBool(payload.c_str()); - else if (str.equals(prefix + KEY_ECONO)) + } else if (str.equals(prefix + KEY_ECONO)) { state->econo = IRac::strToBool(payload.c_str()); - else if (str.equals(prefix + KEY_LIGHT)) + } else if (str.equals(prefix + KEY_LIGHT)) { state->light = IRac::strToBool(payload.c_str()); - else if (str.equals(prefix + KEY_BEEP)) + } else if (str.equals(prefix + KEY_BEEP)) { state->beep = IRac::strToBool(payload.c_str()); - else if (str.equals(prefix + KEY_FILTER)) + } else if (str.equals(prefix + KEY_FILTER)) { state->filter = IRac::strToBool(payload.c_str()); - else if (str.equals(prefix + KEY_CLEAN)) + } else if (str.equals(prefix + KEY_CLEAN)) { state->clean = IRac::strToBool(payload.c_str()); - else if (str.equals(prefix + KEY_CELSIUS)) + } else if (str.equals(prefix + KEY_CELSIUS)) { state->celsius = IRac::strToBool(payload.c_str()); - else if (str.equals(prefix + KEY_SLEEP)) + } else if (str.equals(prefix + KEY_SLEEP)) { state->sleep = payload.toInt(); + } } bool sendClimate(const String topic_prefix, const bool retain, diff --git a/lib/IRremoteESP8266-2.7.5/examples/IRMQTTServer/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/IRMQTTServer/platformio.ini similarity index 97% rename from lib/IRremoteESP8266-2.7.5/examples/IRMQTTServer/platformio.ini rename to lib/IRremoteESP8266-2.7.8/examples/IRMQTTServer/platformio.ini index 1a22b09af..7920c930e 100644 --- a/lib/IRremoteESP8266-2.7.5/examples/IRMQTTServer/platformio.ini +++ b/lib/IRremoteESP8266-2.7.8/examples/IRMQTTServer/platformio.ini @@ -8,6 +8,7 @@ lib_ignore = examples build_flags = -DMQTT_MAX_PACKET_SIZE=768 ; -D_IR_LOCALE_=en-AU framework = arduino platform = espressif8266 +monitor_speed = 115200 [common] lib_deps_builtin = diff --git a/lib/IRremoteESP8266-2.7.5/examples/IRServer/IRServer.ino b/lib/IRremoteESP8266-2.7.8/examples/IRServer/IRServer.ino similarity index 95% rename from lib/IRremoteESP8266-2.7.5/examples/IRServer/IRServer.ino rename to lib/IRremoteESP8266-2.7.8/examples/IRServer/IRServer.ino index 96fad95d2..92bcd0302 100644 --- a/lib/IRremoteESP8266-2.7.5/examples/IRServer/IRServer.ino +++ b/lib/IRremoteESP8266-2.7.8/examples/IRServer/IRServer.ino @@ -65,7 +65,10 @@ IRsend irsend(kIrLed); // Set the GPIO to be used to sending the message. void handleRoot() { server.send(200, "text/html", "" \ - "" HOSTNAME " Demo" \ + "" HOSTNAME " Demo " \ + "" \ + "" \ "" \ "

    Hello from " HOSTNAME ", you can send NEC encoded IR" \ "signals from here!

    " \ diff --git a/lib/IRremoteESP8266-2.7.8/examples/IRServer/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/IRServer/platformio.ini new file mode 100644 index 000000000..6bda1bb71 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/IRServer/platformio.ini @@ -0,0 +1,18 @@ +[platformio] +src_dir = . + +[env] +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +framework = arduino +monitor_speed = 115200 +build_flags = ; -D_IR_LOCALE_=en-AU + +[env:nodemcuv2] +platform = espressif8266 +board = nodemcuv2 + +[env:esp32dev] +platform = espressif32 +board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.5/examples/IRrecvDemo/IRrecvDemo.ino b/lib/IRremoteESP8266-2.7.8/examples/IRrecvDemo/IRrecvDemo.ino similarity index 95% rename from lib/IRremoteESP8266-2.7.5/examples/IRrecvDemo/IRrecvDemo.ino rename to lib/IRremoteESP8266-2.7.8/examples/IRrecvDemo/IRrecvDemo.ino index 945f94055..2ae2e1410 100644 --- a/lib/IRremoteESP8266-2.7.5/examples/IRrecvDemo/IRrecvDemo.ino +++ b/lib/IRremoteESP8266-2.7.8/examples/IRrecvDemo/IRrecvDemo.ino @@ -2,7 +2,7 @@ * IRremoteESP8266: IRrecvDemo - demonstrates receiving IR codes with IRrecv * This is very simple teaching code to show you how to use the library. * If you are trying to decode your Infra-Red remote(s) for later replay, - * use the IRrecvDumpV2.ino example code instead of this. + * use the IRrecvDumpV2.ino (or later) example code instead of this. * An IR detector/demodulator must be connected to the input kRecvPin. * Copyright 2009 Ken Shirriff, http://arcfn.com * Example circuit diagram: diff --git a/lib/IRremoteESP8266-2.7.8/examples/IRrecvDemo/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/IRrecvDemo/platformio.ini new file mode 100644 index 000000000..7130e886a --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/IRrecvDemo/platformio.ini @@ -0,0 +1,18 @@ +[platformio] +src_dir = . + +[env] +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +framework = arduino +build_flags = ; -D_IR_LOCALE_=en-AU +monitor_speed = 115200 + +[env:nodemcuv2] +platform = espressif8266 +board = nodemcuv2 + +[env:esp32dev] +platform = espressif32 +board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.5/examples/IRrecvDump/IRrecvDump.ino b/lib/IRremoteESP8266-2.7.8/examples/IRrecvDump/IRrecvDump.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.5/examples/IRrecvDump/IRrecvDump.ino rename to lib/IRremoteESP8266-2.7.8/examples/IRrecvDump/IRrecvDump.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/IRrecvDump/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/IRrecvDump/platformio.ini new file mode 100644 index 000000000..6bda1bb71 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/IRrecvDump/platformio.ini @@ -0,0 +1,18 @@ +[platformio] +src_dir = . + +[env] +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +framework = arduino +monitor_speed = 115200 +build_flags = ; -D_IR_LOCALE_=en-AU + +[env:nodemcuv2] +platform = espressif8266 +board = nodemcuv2 + +[env:esp32dev] +platform = espressif32 +board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.5/examples/IRrecvDumpV2/IRrecvDumpV2.ino b/lib/IRremoteESP8266-2.7.8/examples/IRrecvDumpV2/IRrecvDumpV2.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.5/examples/IRrecvDumpV2/IRrecvDumpV2.ino rename to lib/IRremoteESP8266-2.7.8/examples/IRrecvDumpV2/IRrecvDumpV2.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/IRrecvDumpV2/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/IRrecvDumpV2/platformio.ini new file mode 100644 index 000000000..fb04eb4b1 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/IRrecvDumpV2/platformio.ini @@ -0,0 +1,58 @@ +[platformio] +src_dir = . + +[env] +; Default platform +platform = espressif8266 +; Default board +board = nodemcuv2 +framework = arduino +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +monitor_speed = 115200 +build_flags = ; -D_IR_LOCALE_=en-AU + +[env:nodemcuv2] +board = nodemcuv2 +; build_flags = -D_IR_LOCALE_=en-AU + +[env:esp32dev] +platform = espressif32 +board = esp32dev +; build_flags = -D_IR_LOCALE_=en-AU + +[env:de-CH] +build_flags = -D_IR_LOCALE_=de-CH ; German (Swiss) + +[env:de-DE] +build_flags = -D_IR_LOCALE_=de-DE ; German + +[env:en-AU] +build_flags = -D_IR_LOCALE_=en-AU ; English (Australian) (Default) + +[env:en-IE] +build_flags = -D_IR_LOCALE_=en-IE ; English (Irish) + +[env:en-UK] +build_flags = -D_IR_LOCALE_=en-UK ; English (UK) + +[env:en-US] +build_flags = -D_IR_LOCALE_=en-US ; English (Simplified) (USA) + +[env:es-ES] +build_flags = -D_IR_LOCALE_=es-ES ; Spanish + +[env:fr-FR] +build_flags = -D_IR_LOCALE_=fr-FR ; French + +[env:it-IT] +build_flags = -D_IR_LOCALE_=it-IT ; Italian + +[env:zh-CN] +build_flags = -D_IR_LOCALE_=zh-CN ; Chinese (Simplified) + +; Build the library with all protocols disabled to flush out #if/#ifdef issues & +; any compiler warnings, by turning them into errors. +[env:shakedown_no_protocols] +build_flags = -D_IR_ENABLE_DEFAULT_=false -Werror diff --git a/lib/IRremoteESP8266-2.7.8/examples/IRrecvDumpV3/BaseOTA.h b/lib/IRremoteESP8266-2.7.8/examples/IRrecvDumpV3/BaseOTA.h new file mode 100644 index 000000000..5dd8db541 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/IRrecvDumpV3/BaseOTA.h @@ -0,0 +1,71 @@ +// Copyright 2020 Christian Nilsson (@nikize) +// Based on public Arduino BasicOTA example + +#ifndef EXAMPLES_IRRECVDUMPV3_BASEOTA_H_ +#define EXAMPLES_IRRECVDUMPV3_BASEOTA_H_ + +#ifndef OTA_ENABLE +#define OTA_ENABLE false +#endif // OTA_ENABLE + +#if OTA_ENABLE + +#include +#include +#include +#include + +void OTAwifi() { + // start default wifi (previously saved on the ESP) for OTA + WiFi.mode(WIFI_STA); + WiFi.begin(); +} + +void OTAinit() { + // See BasicOTA ESP example for source and settings + + ArduinoOTA + .onStart([]() { + String type; + if (ArduinoOTA.getCommand() == U_FLASH) + type = "sketch"; + else + type = "filesystem"; + + Serial.println("Start updating " + type); + }) + .onEnd([]() { + Serial.println("\nEnd"); + }) + .onProgress([](unsigned int progress, unsigned int total) { + Serial.printf("Progress: %u%%\r", (progress / (total / 100))); + }) + .onError([](ota_error_t error) { + Serial.printf("Error[%u]: ", error); + if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed"); + else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed"); + else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed"); + else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed"); + else if (error == OTA_END_ERROR) Serial.println("End Failed"); + }); + + ArduinoOTA.begin(); + Serial.println(); + if (WiFi.waitForConnectResult() == WL_CONNECTED) { + Serial.print("IP address: "); + Serial.println(WiFi.localIP()); + } else { + Serial.println("Wifi Connection Failed."); + } +} + +void OTAloopHandler() { + ArduinoOTA.handle(); +} + +#else // OTA_ENABLE +void OTAwifi() {} +void OTAinit() {} +void OTAloopHandler() {} +#endif // OTA_ENABLE +#endif // EXAMPLES_IRRECVDUMPV3_BASEOTA_H_ diff --git a/lib/IRremoteESP8266-2.7.8/examples/IRrecvDumpV3/IRrecvDumpV3.ino b/lib/IRremoteESP8266-2.7.8/examples/IRrecvDumpV3/IRrecvDumpV3.ino new file mode 100644 index 000000000..419ca9b4c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/IRrecvDumpV3/IRrecvDumpV3.ino @@ -0,0 +1,166 @@ +/* + * IRremoteESP8266: IRrecvDumpV3 - dump details of IR codes with IRrecv + * An IR detector/demodulator must be connected to the input kRecvPin. + * + * Copyright 2009 Ken Shirriff, http://arcfn.com + * Copyright 2017-2019 David Conran + * + * Example circuit diagram: + * https://github.com/crankyoldgit/IRremoteESP8266/wiki#ir-receiving + * + * Changes: + * Version 1.1 May, 2020 + * - Create DumpV3 from DumpV2 + * - Add OTA Base + * Version 1.0 October, 2019 + * - Internationalisation (i18n) support. + * - Stop displaying the legacy raw timing info. + * Version 0.5 June, 2019 + * - Move A/C description to IRac.cpp. + * Version 0.4 July, 2018 + * - Minor improvements and more A/C unit support. + * Version 0.3 November, 2017 + * - Support for A/C decoding for some protocols. + * Version 0.2 April, 2017 + * - Decode from a copy of the data so we can start capturing faster thus + * reduce the likelihood of miscaptures. + * Based on Ken Shirriff's IrsendDemo Version 0.1 July, 2009, + */ + +// Allow over air update +// #define OTA_ENABLE true +#include "BaseOTA.h" + +#include +#include +#include +#include +#include +#include + +// ==================== start of TUNEABLE PARAMETERS ==================== +// An IR detector/demodulator is connected to GPIO pin 14 +// e.g. D5 on a NodeMCU board. +// Note: GPIO 16 won't work on the ESP8266 as it does not have interrupts. +const uint16_t kRecvPin = 14; + +// The Serial connection baud rate. +// i.e. Status message will be sent to the PC at this baud rate. +// Try to avoid slow speeds like 9600, as you will miss messages and +// cause other problems. 115200 (or faster) is recommended. +// NOTE: Make sure you set your Serial Monitor to the same speed. +const uint32_t kBaudRate = 115200; + +// As this program is a special purpose capture/decoder, let us use a larger +// than normal buffer so we can handle Air Conditioner remote codes. +const uint16_t kCaptureBufferSize = 1024; + +// kTimeout is the Nr. of milli-Seconds of no-more-data before we consider a +// message ended. +// This parameter is an interesting trade-off. The longer the timeout, the more +// complex a message it can capture. e.g. Some device protocols will send +// multiple message packets in quick succession, like Air Conditioner remotes. +// Air Coniditioner protocols often have a considerable gap (20-40+ms) between +// packets. +// The downside of a large timeout value is a lot of less complex protocols +// send multiple messages when the remote's button is held down. The gap between +// them is often also around 20+ms. This can result in the raw data be 2-3+ +// times larger than needed as it has captured 2-3+ messages in a single +// capture. Setting a low timeout value can resolve this. +// So, choosing the best kTimeout value for your use particular case is +// quite nuanced. Good luck and happy hunting. +// NOTE: Don't exceed kMaxTimeoutMs. Typically 130ms. +#if DECODE_AC +// Some A/C units have gaps in their protocols of ~40ms. e.g. Kelvinator +// A value this large may swallow repeats of some protocols +const uint8_t kTimeout = 50; +#else // DECODE_AC +// Suits most messages, while not swallowing many repeats. +const uint8_t kTimeout = 15; +#endif // DECODE_AC +// Alternatives: +// const uint8_t kTimeout = 90; +// Suits messages with big gaps like XMP-1 & some aircon units, but can +// accidentally swallow repeated messages in the rawData[] output. +// +// const uint8_t kTimeout = kMaxTimeoutMs; +// This will set it to our currently allowed maximum. +// Values this high are problematic because it is roughly the typical boundary +// where most messages repeat. +// e.g. It will stop decoding a message and start sending it to serial at +// precisely the time when the next message is likely to be transmitted, +// and may miss it. + +// Set the smallest sized "UNKNOWN" message packets we actually care about. +// This value helps reduce the false-positive detection rate of IR background +// noise as real messages. The chances of background IR noise getting detected +// as a message increases with the length of the kTimeout value. (See above) +// The downside of setting this message too large is you can miss some valid +// short messages for protocols that this library doesn't yet decode. +// +// Set higher if you get lots of random short UNKNOWN messages when nothing +// should be sending a message. +// Set lower if you are sure your setup is working, but it doesn't see messages +// from your device. (e.g. Other IR remotes work.) +// NOTE: Set this value very high to effectively turn off UNKNOWN detection. +const uint16_t kMinUnknownSize = 12; + +// Legacy (No longer supported!) +// +// Change to `true` if you miss/need the old "Raw Timing[]" display. +#define LEGACY_TIMING_INFO false +// ==================== end of TUNEABLE PARAMETERS ==================== + +// Use turn on the save buffer feature for more complete capture coverage. +IRrecv irrecv(kRecvPin, kCaptureBufferSize, kTimeout, true); +decode_results results; // Somewhere to store the results + +// This section of code runs only once at start-up. +void setup() { + OTAwifi(); // start default wifi (previously saved on the ESP) for OTA +#if defined(ESP8266) + Serial.begin(kBaudRate, SERIAL_8N1, SERIAL_TX_ONLY); +#else // ESP8266 + Serial.begin(kBaudRate, SERIAL_8N1); +#endif // ESP8266 + while (!Serial) // Wait for the serial connection to be establised. + delay(50); + Serial.printf("\n" D_STR_IRRECVDUMP_STARTUP "\n", kRecvPin); + OTAinit(); // setup OTA handlers and show IP +#if DECODE_HASH + // Ignore messages with less than minimum on or off pulses. + irrecv.setUnknownThreshold(kMinUnknownSize); +#endif // DECODE_HASH + irrecv.enableIRIn(); // Start the receiver +} + +// The repeating section of the code +void loop() { + // Check if the IR code has been received. + if (irrecv.decode(&results)) { + // Display a crude timestamp. + uint32_t now = millis(); + Serial.printf(D_STR_TIMESTAMP " : %06u.%03u\n", now / 1000, now % 1000); + // Check if we got an IR message that was to big for our capture buffer. + if (results.overflow) + Serial.printf(D_WARN_BUFFERFULL "\n", kCaptureBufferSize); + // Display the library version the message was captured with. + Serial.println(D_STR_LIBRARY " : v" _IRREMOTEESP8266_VERSION_ "\n"); + // Display the basic output of what we found. + Serial.print(resultToHumanReadableBasic(&results)); + // Display any extra A/C info if we have it. + String description = IRAcUtils::resultAcToString(&results); + if (description.length()) Serial.println(D_STR_MESGDESC ": " + description); + yield(); // Feed the WDT as the text output can take a while to print. +#if LEGACY_TIMING_INFO + // Output legacy RAW timing info of the result. + Serial.println(resultToTimingInfo(&results)); + yield(); // Feed the WDT (again) +#endif // LEGACY_TIMING_INFO + // Output the results as source code + Serial.println(resultToSourceCode(&results)); + Serial.println(); // Blank line between entries + yield(); // Feed the WDT (again) + } + OTAloopHandler(); +} diff --git a/lib/IRremoteESP8266-2.7.8/examples/IRrecvDumpV3/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/IRrecvDumpV3/platformio.ini new file mode 100644 index 000000000..95a90ac86 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/IRrecvDumpV3/platformio.ini @@ -0,0 +1,53 @@ +[platformio] +src_dir = . + +[env] +; Default platform +platform = espressif8266 +; Default board +board = nodemcuv2 +framework = arduino +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +monitor_speed = 115200 +build_flags = ; -D_IR_LOCALE_=en-AU + +[env:nodemcuv2] +board = nodemcuv2 +; build_flags = -D_IR_LOCALE_=en-AU + +[env:esp32dev] +platform = espressif32 +board = esp32dev +; build_flags = -D_IR_LOCALE_=en-AU + +[env:de-CH] +build_flags = -D_IR_LOCALE_=de-CH ; German (Swiss) + +[env:de-DE] +build_flags = -D_IR_LOCALE_=de-DE ; German + +[env:en-AU] +build_flags = -D_IR_LOCALE_=en-AU ; English (Australian) (Default) + +[env:en-IE] +build_flags = -D_IR_LOCALE_=en-IE ; English (Irish) + +[env:en-UK] +build_flags = -D_IR_LOCALE_=en-UK ; English (UK) + +[env:en-US] +build_flags = -D_IR_LOCALE_=en-US ; English (Simplified) (USA) + +[env:es-ES] +build_flags = -D_IR_LOCALE_=es-ES ; Spanish + +[env:fr-FR] +build_flags = -D_IR_LOCALE_=fr-FR ; French + +[env:it-IT] +build_flags = -D_IR_LOCALE_=it-IT ; Italian + +[env:zh-CN] +build_flags = -D_IR_LOCALE_=zh-CN ; Chinese (Simplified) diff --git a/lib/IRremoteESP8266-2.7.5/examples/IRsendDemo/IRsendDemo.ino b/lib/IRremoteESP8266-2.7.8/examples/IRsendDemo/IRsendDemo.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.5/examples/IRsendDemo/IRsendDemo.ino rename to lib/IRremoteESP8266-2.7.8/examples/IRsendDemo/IRsendDemo.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/IRsendDemo/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/IRsendDemo/platformio.ini new file mode 100644 index 000000000..6bda1bb71 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/IRsendDemo/platformio.ini @@ -0,0 +1,18 @@ +[platformio] +src_dir = . + +[env] +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +framework = arduino +monitor_speed = 115200 +build_flags = ; -D_IR_LOCALE_=en-AU + +[env:nodemcuv2] +platform = espressif8266 +board = nodemcuv2 + +[env:esp32dev] +platform = espressif32 +board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.5/examples/IRsendProntoDemo/IRsendProntoDemo.ino b/lib/IRremoteESP8266-2.7.8/examples/IRsendProntoDemo/IRsendProntoDemo.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.5/examples/IRsendProntoDemo/IRsendProntoDemo.ino rename to lib/IRremoteESP8266-2.7.8/examples/IRsendProntoDemo/IRsendProntoDemo.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/IRsendProntoDemo/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/IRsendProntoDemo/platformio.ini new file mode 100644 index 000000000..6bda1bb71 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/IRsendProntoDemo/platformio.ini @@ -0,0 +1,18 @@ +[platformio] +src_dir = . + +[env] +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +framework = arduino +monitor_speed = 115200 +build_flags = ; -D_IR_LOCALE_=en-AU + +[env:nodemcuv2] +platform = espressif8266 +board = nodemcuv2 + +[env:esp32dev] +platform = espressif32 +board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.5/examples/JVCPanasonicSendDemo/JVCPanasonicSendDemo.ino b/lib/IRremoteESP8266-2.7.8/examples/JVCPanasonicSendDemo/JVCPanasonicSendDemo.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.5/examples/JVCPanasonicSendDemo/JVCPanasonicSendDemo.ino rename to lib/IRremoteESP8266-2.7.8/examples/JVCPanasonicSendDemo/JVCPanasonicSendDemo.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/JVCPanasonicSendDemo/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/JVCPanasonicSendDemo/platformio.ini new file mode 100644 index 000000000..6bda1bb71 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/JVCPanasonicSendDemo/platformio.ini @@ -0,0 +1,18 @@ +[platformio] +src_dir = . + +[env] +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +framework = arduino +monitor_speed = 115200 +build_flags = ; -D_IR_LOCALE_=en-AU + +[env:nodemcuv2] +platform = espressif8266 +board = nodemcuv2 + +[env:esp32dev] +platform = espressif32 +board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.5/examples/LGACSend/LGACSend.ino b/lib/IRremoteESP8266-2.7.8/examples/LGACSend/LGACSend.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.5/examples/LGACSend/LGACSend.ino rename to lib/IRremoteESP8266-2.7.8/examples/LGACSend/LGACSend.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/LGACSend/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/LGACSend/platformio.ini new file mode 100644 index 000000000..6bda1bb71 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/LGACSend/platformio.ini @@ -0,0 +1,18 @@ +[platformio] +src_dir = . + +[env] +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +framework = arduino +monitor_speed = 115200 +build_flags = ; -D_IR_LOCALE_=en-AU + +[env:nodemcuv2] +platform = espressif8266 +board = nodemcuv2 + +[env:esp32dev] +platform = espressif32 +board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.5/examples/SmartIRRepeater/SmartIRRepeater.ino b/lib/IRremoteESP8266-2.7.8/examples/SmartIRRepeater/SmartIRRepeater.ino similarity index 99% rename from lib/IRremoteESP8266-2.7.5/examples/SmartIRRepeater/SmartIRRepeater.ino rename to lib/IRremoteESP8266-2.7.8/examples/SmartIRRepeater/SmartIRRepeater.ino index 576abb516..d35c4cef6 100644 --- a/lib/IRremoteESP8266-2.7.5/examples/SmartIRRepeater/SmartIRRepeater.ino +++ b/lib/IRremoteESP8266-2.7.8/examples/SmartIRRepeater/SmartIRRepeater.ino @@ -121,8 +121,10 @@ void loop() { uint16_t *raw_array = resultToRawArray(&results); // Find out how many elements are in the array. size = getCorrectedRawLength(&results); +#if SEND_RAW // Send it out via the IR LED circuit. irsend.sendRaw(raw_array, size, kFrequency); +#endif // SEND_RAW // Deallocate the memory allocated by resultToRawArray(). delete [] raw_array; } else if (hasACState(protocol)) { // Does the message require a state[]? diff --git a/lib/IRremoteESP8266-2.7.8/examples/SmartIRRepeater/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/SmartIRRepeater/platformio.ini new file mode 100644 index 000000000..0e8f173f7 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/SmartIRRepeater/platformio.ini @@ -0,0 +1,36 @@ +[platformio] +src_dir = . + +[env] +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +framework = arduino +monitor_speed = 115200 +build_flags = ; -D_IR_LOCALE_=en-AU + +[env:nodemcuv2] +platform = espressif8266 +board = nodemcuv2 + +[env:esp32dev] +platform = espressif32 +board = esp32dev + +; Build the program forcing the compiler to treat all warnings as errors. +[env:shakedown_all_protocols] +platform = espressif8266 +board = nodemcuv2 +build_flags = + ${env.build_flags} + -Werror + +; Disable all protocols to see if we can force any errors. +; Build the program forcing the compiler to treat all warnings as errors. +[env:shakedown_no_protocols] +platform = espressif8266 +board = nodemcuv2 +build_flags = + ${env.build_flags} + -Werror + -D_IR_ENABLE_DEFAULT_=false diff --git a/lib/IRremoteESP8266-2.7.5/examples/TurnOnArgoAC/TurnOnArgoAC.ino b/lib/IRremoteESP8266-2.7.8/examples/TurnOnArgoAC/TurnOnArgoAC.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.5/examples/TurnOnArgoAC/TurnOnArgoAC.ino rename to lib/IRremoteESP8266-2.7.8/examples/TurnOnArgoAC/TurnOnArgoAC.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/TurnOnArgoAC/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/TurnOnArgoAC/platformio.ini new file mode 100644 index 000000000..6bda1bb71 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/TurnOnArgoAC/platformio.ini @@ -0,0 +1,18 @@ +[platformio] +src_dir = . + +[env] +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +framework = arduino +monitor_speed = 115200 +build_flags = ; -D_IR_LOCALE_=en-AU + +[env:nodemcuv2] +platform = espressif8266 +board = nodemcuv2 + +[env:esp32dev] +platform = espressif32 +board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.5/examples/TurnOnDaikinAC/TurnOnDaikinAC.ino b/lib/IRremoteESP8266-2.7.8/examples/TurnOnDaikinAC/TurnOnDaikinAC.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.5/examples/TurnOnDaikinAC/TurnOnDaikinAC.ino rename to lib/IRremoteESP8266-2.7.8/examples/TurnOnDaikinAC/TurnOnDaikinAC.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/TurnOnDaikinAC/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/TurnOnDaikinAC/platformio.ini new file mode 100644 index 000000000..6bda1bb71 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/TurnOnDaikinAC/platformio.ini @@ -0,0 +1,18 @@ +[platformio] +src_dir = . + +[env] +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +framework = arduino +monitor_speed = 115200 +build_flags = ; -D_IR_LOCALE_=en-AU + +[env:nodemcuv2] +platform = espressif8266 +board = nodemcuv2 + +[env:esp32dev] +platform = espressif32 +board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.5/examples/TurnOnFujitsuAC/TurnOnFujitsuAC.ino b/lib/IRremoteESP8266-2.7.8/examples/TurnOnFujitsuAC/TurnOnFujitsuAC.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.5/examples/TurnOnFujitsuAC/TurnOnFujitsuAC.ino rename to lib/IRremoteESP8266-2.7.8/examples/TurnOnFujitsuAC/TurnOnFujitsuAC.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/TurnOnFujitsuAC/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/TurnOnFujitsuAC/platformio.ini new file mode 100644 index 000000000..6bda1bb71 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/TurnOnFujitsuAC/platformio.ini @@ -0,0 +1,18 @@ +[platformio] +src_dir = . + +[env] +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +framework = arduino +monitor_speed = 115200 +build_flags = ; -D_IR_LOCALE_=en-AU + +[env:nodemcuv2] +platform = espressif8266 +board = nodemcuv2 + +[env:esp32dev] +platform = espressif32 +board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.5/examples/TurnOnGreeAC/TurnOnGreeAC.ino b/lib/IRremoteESP8266-2.7.8/examples/TurnOnGreeAC/TurnOnGreeAC.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.5/examples/TurnOnGreeAC/TurnOnGreeAC.ino rename to lib/IRremoteESP8266-2.7.8/examples/TurnOnGreeAC/TurnOnGreeAC.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/TurnOnGreeAC/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/TurnOnGreeAC/platformio.ini new file mode 100644 index 000000000..6bda1bb71 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/TurnOnGreeAC/platformio.ini @@ -0,0 +1,18 @@ +[platformio] +src_dir = . + +[env] +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +framework = arduino +monitor_speed = 115200 +build_flags = ; -D_IR_LOCALE_=en-AU + +[env:nodemcuv2] +platform = espressif8266 +board = nodemcuv2 + +[env:esp32dev] +platform = espressif32 +board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.5/examples/TurnOnKelvinatorAC/TurnOnKelvinatorAC.ino b/lib/IRremoteESP8266-2.7.8/examples/TurnOnKelvinatorAC/TurnOnKelvinatorAC.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.5/examples/TurnOnKelvinatorAC/TurnOnKelvinatorAC.ino rename to lib/IRremoteESP8266-2.7.8/examples/TurnOnKelvinatorAC/TurnOnKelvinatorAC.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/TurnOnKelvinatorAC/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/TurnOnKelvinatorAC/platformio.ini new file mode 100644 index 000000000..6bda1bb71 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/TurnOnKelvinatorAC/platformio.ini @@ -0,0 +1,18 @@ +[platformio] +src_dir = . + +[env] +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +framework = arduino +monitor_speed = 115200 +build_flags = ; -D_IR_LOCALE_=en-AU + +[env:nodemcuv2] +platform = espressif8266 +board = nodemcuv2 + +[env:esp32dev] +platform = espressif32 +board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.5/examples/TurnOnMitsubishiAC/TurnOnMitsubishiAC.ino b/lib/IRremoteESP8266-2.7.8/examples/TurnOnMitsubishiAC/TurnOnMitsubishiAC.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.5/examples/TurnOnMitsubishiAC/TurnOnMitsubishiAC.ino rename to lib/IRremoteESP8266-2.7.8/examples/TurnOnMitsubishiAC/TurnOnMitsubishiAC.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/TurnOnMitsubishiAC/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/TurnOnMitsubishiAC/platformio.ini new file mode 100644 index 000000000..6bda1bb71 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/TurnOnMitsubishiAC/platformio.ini @@ -0,0 +1,18 @@ +[platformio] +src_dir = . + +[env] +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +framework = arduino +monitor_speed = 115200 +build_flags = ; -D_IR_LOCALE_=en-AU + +[env:nodemcuv2] +platform = espressif8266 +board = nodemcuv2 + +[env:esp32dev] +platform = espressif32 +board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.5/examples/TurnOnMitsubishiHeavyAc/TurnOnMitsubishiHeavyAc.ino b/lib/IRremoteESP8266-2.7.8/examples/TurnOnMitsubishiHeavyAc/TurnOnMitsubishiHeavyAc.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.5/examples/TurnOnMitsubishiHeavyAc/TurnOnMitsubishiHeavyAc.ino rename to lib/IRremoteESP8266-2.7.8/examples/TurnOnMitsubishiHeavyAc/TurnOnMitsubishiHeavyAc.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/TurnOnMitsubishiHeavyAc/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/TurnOnMitsubishiHeavyAc/platformio.ini new file mode 100644 index 000000000..6bda1bb71 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/TurnOnMitsubishiHeavyAc/platformio.ini @@ -0,0 +1,18 @@ +[platformio] +src_dir = . + +[env] +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +framework = arduino +monitor_speed = 115200 +build_flags = ; -D_IR_LOCALE_=en-AU + +[env:nodemcuv2] +platform = espressif8266 +board = nodemcuv2 + +[env:esp32dev] +platform = espressif32 +board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.5/examples/TurnOnPanasonicAC/TurnOnPanasonicAC.ino b/lib/IRremoteESP8266-2.7.8/examples/TurnOnPanasonicAC/TurnOnPanasonicAC.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.5/examples/TurnOnPanasonicAC/TurnOnPanasonicAC.ino rename to lib/IRremoteESP8266-2.7.8/examples/TurnOnPanasonicAC/TurnOnPanasonicAC.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/TurnOnPanasonicAC/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/TurnOnPanasonicAC/platformio.ini new file mode 100644 index 000000000..6bda1bb71 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/TurnOnPanasonicAC/platformio.ini @@ -0,0 +1,18 @@ +[platformio] +src_dir = . + +[env] +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +framework = arduino +monitor_speed = 115200 +build_flags = ; -D_IR_LOCALE_=en-AU + +[env:nodemcuv2] +platform = espressif8266 +board = nodemcuv2 + +[env:esp32dev] +platform = espressif32 +board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.5/examples/TurnOnToshibaAC/TurnOnToshibaAC.ino b/lib/IRremoteESP8266-2.7.8/examples/TurnOnToshibaAC/TurnOnToshibaAC.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.5/examples/TurnOnToshibaAC/TurnOnToshibaAC.ino rename to lib/IRremoteESP8266-2.7.8/examples/TurnOnToshibaAC/TurnOnToshibaAC.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/TurnOnToshibaAC/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/TurnOnToshibaAC/platformio.ini new file mode 100644 index 000000000..6bda1bb71 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/TurnOnToshibaAC/platformio.ini @@ -0,0 +1,18 @@ +[platformio] +src_dir = . + +[env] +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +framework = arduino +monitor_speed = 115200 +build_flags = ; -D_IR_LOCALE_=en-AU + +[env:nodemcuv2] +platform = espressif8266 +board = nodemcuv2 + +[env:esp32dev] +platform = espressif32 +board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.5/examples/TurnOnTrotecAC/TurnOnTrotecAC.ino b/lib/IRremoteESP8266-2.7.8/examples/TurnOnTrotecAC/TurnOnTrotecAC.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.5/examples/TurnOnTrotecAC/TurnOnTrotecAC.ino rename to lib/IRremoteESP8266-2.7.8/examples/TurnOnTrotecAC/TurnOnTrotecAC.ino diff --git a/lib/IRremoteESP8266-2.7.8/examples/TurnOnTrotecAC/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/TurnOnTrotecAC/platformio.ini new file mode 100644 index 000000000..6bda1bb71 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/examples/TurnOnTrotecAC/platformio.ini @@ -0,0 +1,18 @@ +[platformio] +src_dir = . + +[env] +lib_extra_dirs = ../../ +lib_ldf_mode = deep+ +lib_ignore = examples +framework = arduino +monitor_speed = 115200 +build_flags = ; -D_IR_LOCALE_=en-AU + +[env:nodemcuv2] +platform = espressif8266 +board = nodemcuv2 + +[env:esp32dev] +platform = espressif32 +board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/README.md b/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/README.md similarity index 100% rename from lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/README.md rename to lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/README.md diff --git a/lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/Web-AC-control.ino b/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/Web-AC-control.ino similarity index 100% rename from lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/Web-AC-control.ino rename to lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/Web-AC-control.ino diff --git a/lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/platformio.ini b/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/platformio.ini similarity index 96% rename from lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/platformio.ini rename to lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/platformio.ini index 731442831..19ff9c277 100644 --- a/lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/platformio.ini +++ b/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/platformio.ini @@ -6,6 +6,7 @@ lib_extra_dirs = ../../ lib_ldf_mode = deep+ lib_ignore = examples framework = arduino +monitor_speed = 115200 build_flags = ; -D_IR_LOCALE_=en-AU [common] diff --git a/lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/printscreen.png b/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/printscreen.png similarity index 100% rename from lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/printscreen.png rename to lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/printscreen.png diff --git a/lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/favicon.ico b/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/favicon.ico similarity index 100% rename from lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/favicon.ico rename to lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/favicon.ico diff --git a/lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/level_1_off.svg b/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_1_off.svg similarity index 100% rename from lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/level_1_off.svg rename to lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_1_off.svg diff --git a/lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/level_1_on.svg b/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_1_on.svg similarity index 100% rename from lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/level_1_on.svg rename to lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_1_on.svg diff --git a/lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/level_2_off.svg b/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_2_off.svg similarity index 100% rename from lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/level_2_off.svg rename to lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_2_off.svg diff --git a/lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/level_2_on.svg b/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_2_on.svg similarity index 100% rename from lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/level_2_on.svg rename to lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_2_on.svg diff --git a/lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/level_3_off.svg b/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_3_off.svg similarity index 100% rename from lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/level_3_off.svg rename to lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_3_off.svg diff --git a/lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/level_3_on.svg b/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_3_on.svg similarity index 100% rename from lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/level_3_on.svg rename to lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_3_on.svg diff --git a/lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/level_4_off.svg b/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_4_off.svg similarity index 100% rename from lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/level_4_off.svg rename to lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_4_off.svg diff --git a/lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/level_4_on.svg b/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_4_on.svg similarity index 100% rename from lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/level_4_on.svg rename to lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/level_4_on.svg diff --git a/lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/ui.html b/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/ui.html similarity index 100% rename from lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/ui.html rename to lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/ui.html diff --git a/lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/ui.js b/lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/ui.js similarity index 100% rename from lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/ui.js rename to lib/IRremoteESP8266-2.7.8/examples/Web-AC-control/upload/ui.js diff --git a/lib/IRremoteESP8266-2.7.5/keywords.txt b/lib/IRremoteESP8266-2.7.8/keywords.txt similarity index 89% rename from lib/IRremoteESP8266-2.7.5/keywords.txt rename to lib/IRremoteESP8266-2.7.8/keywords.txt index 2d0ea9255..c05482770 100644 --- a/lib/IRremoteESP8266-2.7.5/keywords.txt +++ b/lib/IRremoteESP8266-2.7.8/keywords.txt @@ -22,7 +22,9 @@ IRAmcorAc KEYWORD1 IRArgoAC KEYWORD1 +IRCarrierAc64 KEYWORD1 IRCoolixAC KEYWORD1 +IRCoronaAc KEYWORD1 IRDaikin128 KEYWORD1 IRDaikin152 KEYWORD1 IRDaikin160 KEYWORD1 @@ -31,6 +33,7 @@ IRDaikin2 KEYWORD1 IRDaikin216 KEYWORD1 IRDaikin64 KEYWORD1 IRDaikinESP KEYWORD1 +IRDelonghiAc KEYWORD1 IRElectraAc KEYWORD1 IRFujitsuAC KEYWORD1 IRGoodweatherAc KEYWORD1 @@ -40,6 +43,7 @@ IRHaierACYRW02 KEYWORD1 IRHitachiAc KEYWORD1 IRHitachiAc1 KEYWORD1 IRHitachiAc3 KEYWORD1 +IRHitachiAc344: KEYWORD1 IRHitachiAc424 KEYWORD1 IRKelvinatorAC KEYWORD1 IRLgAc KEYWORD1 @@ -84,15 +88,19 @@ whirlpool_ac_remote_model_t KEYWORD1 # Methods and Functions (KEYWORD2) ####################################### +_cancelOffTimer KEYWORD2 +_cancelOnTimer KEYWORD2 _delayMicroseconds KEYWORD2 _getTime KEYWORD2 _getTimer KEYWORD2 _matchGeneric KEYWORD2 _sendSony KEYWORD2 _setMode KEYWORD2 +_setPower KEYWORD2 _setTemp KEYWORD2 _setTime KEYWORD2 _setTimer KEYWORD2 +_toString KEYWORD2 _validTolerance KEYWORD2 add KEYWORD2 addBoolToString KEYWORD2 @@ -113,7 +121,6 @@ buildState KEYWORD2 calcBlockChecksum KEYWORD2 calcChecksum KEYWORD2 calcFirstChecksum KEYWORD2 -calcLGChecksum KEYWORD2 calcSecondChecksum KEYWORD2 calcUSecPeriod KEYWORD2 calculateChecksum KEYWORD2 @@ -121,11 +128,13 @@ calibrate KEYWORD2 cancelOffTimer KEYWORD2 cancelOnTimer KEYWORD2 cancelTimers KEYWORD2 +carrier64 KEYWORD2 celsiusToFahrenheit KEYWORD2 checkZjsSig KEYWORD2 checkZmsSig KEYWORD2 checksum KEYWORD2 clearOnTimerFlag KEYWORD2 +clearPowerSpecial KEYWORD2 clearSensorTemp KEYWORD2 clearSleepTimerFlag KEYWORD2 cmpStates KEYWORD2 @@ -136,6 +145,7 @@ convertSwingH KEYWORD2 convertSwingV KEYWORD2 coolix KEYWORD2 copyIrParams KEYWORD2 +corona KEYWORD2 countBits KEYWORD2 crudeNoiseFilter KEYWORD2 daikin KEYWORD2 @@ -153,6 +163,9 @@ decodeAmcor KEYWORD2 decodeArgo KEYWORD2 decodeCOOLIX KEYWORD2 decodeCarrierAC KEYWORD2 +decodeCarrierAC40 KEYWORD2 +decodeCarrierAC64 KEYWORD2 +decodeCoronaAc KEYWORD2 decodeDISH KEYWORD2 decodeDaikin KEYWORD2 decodeDaikin128 KEYWORD2 @@ -162,7 +175,9 @@ decodeDaikin176 KEYWORD2 decodeDaikin2 KEYWORD2 decodeDaikin216 KEYWORD2 decodeDaikin64 KEYWORD2 +decodeDelonghiAc KEYWORD2 decodeDenon KEYWORD2 +decodeDoshisha KEYWORD2 decodeElectraAC KEYWORD2 decodeEpson KEYWORD2 decodeFujitsuAC KEYWORD2 @@ -185,12 +200,14 @@ decodeLutron KEYWORD2 decodeMWM KEYWORD2 decodeMagiQuest KEYWORD2 decodeMidea KEYWORD2 +decodeMidea24 KEYWORD2 decodeMitsubishi KEYWORD2 decodeMitsubishi112 KEYWORD2 decodeMitsubishi136 KEYWORD2 decodeMitsubishi2 KEYWORD2 decodeMitsubishiAC KEYWORD2 decodeMitsubishiHeavy KEYWORD2 +decodeMultibrackets KEYWORD2 decodeNEC KEYWORD2 decodeNeoclima KEYWORD2 decodeNikai KEYWORD2 @@ -216,7 +233,9 @@ decodeTrotec KEYWORD2 decodeVestelAc KEYWORD2 decodeWhirlpoolAC KEYWORD2 decodeWhynter KEYWORD2 +decodeZepeal KEYWORD2 defaultBits KEYWORD2 +delonghiac KEYWORD2 disableIRIn KEYWORD2 disableOffTimer KEYWORD2 disableOnTimer KEYWORD2 @@ -229,6 +248,7 @@ enableOffTimer KEYWORD2 enableOnTimer KEYWORD2 enableSleepTimer KEYWORD2 enableTimer KEYWORD2 +encodeDoshisha KEYWORD2 encodeJVC KEYWORD2 encodeLG KEYWORD2 encodeMagiQuest KEYWORD2 @@ -252,6 +272,7 @@ get3D KEYWORD2 get8CHeat KEYWORD2 getBeep KEYWORD2 getBit KEYWORD2 +getBoost KEYWORD2 getBreeze KEYWORD2 getBufSize KEYWORD2 getButton KEYWORD2 @@ -265,7 +286,9 @@ getCurrTime KEYWORD2 getCurrentDay KEYWORD2 getCurrentTime KEYWORD2 getDisplay KEYWORD2 +getDisplayTempSource KEYWORD2 getEcono KEYWORD2 +getEconoToggle KEYWORD2 getEye KEYWORD2 getEyeAuto KEYWORD2 getFan KEYWORD2 @@ -299,21 +322,24 @@ getOnTimer KEYWORD2 getOnTimerEnabled KEYWORD2 getOutsideQuiet KEYWORD2 getPower KEYWORD2 +getPowerButton KEYWORD2 +getPowerSpecial KEYWORD2 getPowerToggle KEYWORD2 getPowerful KEYWORD2 -getPreviousPower KEYWORD2 getPurify KEYWORD2 getQuiet KEYWORD2 getRClevel KEYWORD2 getRaw KEYWORD2 getRoomTemp KEYWORD2 getSave KEYWORD2 +getSectionByte KEYWORD2 getSensor KEYWORD2 getSensorTemp KEYWORD2 getSilent KEYWORD2 getSleep KEYWORD2 getSleepTime KEYWORD2 getSleepTimerEnabled KEYWORD2 +getSpecial KEYWORD2 getSpeed KEYWORD2 getStartClock KEYWORD2 getStateLength KEYWORD2 @@ -331,12 +357,16 @@ getSwingVerticalPosition KEYWORD2 getTemp KEYWORD2 getTempOffset KEYWORD2 getTempRaw KEYWORD2 +getTempUnit KEYWORD2 getTime KEYWORD2 getTimer KEYWORD2 getTimerEnabled KEYWORD2 +getTimerTime KEYWORD2 +getTimerType KEYWORD2 getTolerance KEYWORD2 getTurbo KEYWORD2 getUseCelsius KEYWORD2 +getUseFahrenheit KEYWORD2 getVane KEYWORD2 getWeeklyTimerEnable KEYWORD2 getWiFi KEYWORD2 @@ -354,6 +384,7 @@ hasInvertedStates KEYWORD2 hasStateChanged KEYWORD2 hitachi KEYWORD2 hitachi1 KEYWORD2 +hitachi344 KEYWORD2 hitachi424 KEYWORD2 htmlEscape KEYWORD2 initState KEYWORD2 @@ -362,6 +393,7 @@ isOffTimerActive KEYWORD2 isOffTimerEnabled KEYWORD2 isOnTimerActive KEYWORD2 isOnTimerEnabled KEYWORD2 +isPowerSpecial KEYWORD2 isProtocolSupported KEYWORD2 isSpecialState KEYWORD2 isSwingVToggle KEYWORD2 @@ -380,7 +412,9 @@ matchAtLeast KEYWORD2 matchBytes KEYWORD2 matchData KEYWORD2 matchGeneric KEYWORD2 +matchGenericConstBitTime KEYWORD2 matchManchester KEYWORD2 +matchManchesterData KEYWORD2 matchMark KEYWORD2 matchSpace KEYWORD2 midea KEYWORD2 @@ -417,6 +451,9 @@ sendAmcor KEYWORD2 sendArgo KEYWORD2 sendCOOLIX KEYWORD2 sendCarrierAC KEYWORD2 +sendCarrierAC40 KEYWORD2 +sendCarrierAC64 KEYWORD2 +sendCoronaAc KEYWORD2 sendDISH KEYWORD2 sendDaikin KEYWORD2 sendDaikin128 KEYWORD2 @@ -427,7 +464,9 @@ sendDaikin2 KEYWORD2 sendDaikin216 KEYWORD2 sendDaikin64 KEYWORD2 sendData KEYWORD2 +sendDelonghiAc KEYWORD2 sendDenon KEYWORD2 +sendDoshisha KEYWORD2 sendElectraAC KEYWORD2 sendEpson KEYWORD2 sendExtended KEYWORD2 @@ -443,6 +482,7 @@ sendHitachiAC KEYWORD2 sendHitachiAC1 KEYWORD2 sendHitachiAC2 KEYWORD2 sendHitachiAc3 KEYWORD2 +sendHitachiAc344 KEYWORD2 sendHitachiAc424 KEYWORD2 sendInax KEYWORD2 sendJVC KEYWORD2 @@ -457,6 +497,7 @@ sendMagiQuest KEYWORD2 sendManchester KEYWORD2 sendManchesterData KEYWORD2 sendMidea KEYWORD2 +sendMidea24 KEYWORD2 sendMitsubishi KEYWORD2 sendMitsubishi112 KEYWORD2 sendMitsubishi136 KEYWORD2 @@ -464,6 +505,7 @@ sendMitsubishi2 KEYWORD2 sendMitsubishiAC KEYWORD2 sendMitsubishiHeavy152 KEYWORD2 sendMitsubishiHeavy88 KEYWORD2 +sendMultibrackets KEYWORD2 sendNEC KEYWORD2 sendNeoclima KEYWORD2 sendNikai KEYWORD2 @@ -496,6 +538,7 @@ sendTrotec KEYWORD2 sendVestelAc KEYWORD2 sendWhirlpoolAC KEYWORD2 sendWhynter KEYWORD2 +sendZepeal KEYWORD2 serialPrintUint64 KEYWORD2 set3D KEYWORD2 set8CHeat KEYWORD2 @@ -503,6 +546,7 @@ setAuto KEYWORD2 setBeep KEYWORD2 setBit KEYWORD2 setBits KEYWORD2 +setBoost KEYWORD2 setBreeze KEYWORD2 setButton KEYWORD2 setClean KEYWORD2 @@ -514,7 +558,9 @@ setCurrTime KEYWORD2 setCurrentDay KEYWORD2 setCurrentTime KEYWORD2 setDisplay KEYWORD2 +setDisplayTempSource KEYWORD2 setEcono KEYWORD2 +setEconoToggle KEYWORD2 setEye KEYWORD2 setEyeAuto KEYWORD2 setFan KEYWORD2 @@ -552,9 +598,10 @@ setOnTimerActive KEYWORD2 setOnTimerEnabled KEYWORD2 setOutsideQuiet KEYWORD2 setPower KEYWORD2 +setPowerButton KEYWORD2 +setPowerSpecial KEYWORD2 setPowerToggle KEYWORD2 setPowerful KEYWORD2 -setPreviousPower KEYWORD2 setPurify KEYWORD2 setQuiet KEYWORD2 setRaw KEYWORD2 @@ -565,6 +612,7 @@ setSensorTemp KEYWORD2 setSensorTempRaw KEYWORD2 setSilent KEYWORD2 setSleep KEYWORD2 +setSpecial KEYWORD2 setSpeed KEYWORD2 setStartClock KEYWORD2 setStopClock KEYWORD2 @@ -578,6 +626,7 @@ setSwingVToggle KEYWORD2 setSwingVertical KEYWORD2 setTemp KEYWORD2 setTempRaw KEYWORD2 +setTempUnit KEYWORD2 setTime KEYWORD2 setTimer KEYWORD2 setTimerActive KEYWORD2 @@ -586,6 +635,7 @@ setTolerance KEYWORD2 setTurbo KEYWORD2 setUnknownThreshold KEYWORD2 setUseCelsius KEYWORD2 +setUseFahrenheit KEYWORD2 setVane KEYWORD2 setWeeklyTimerEnable KEYWORD2 setWiFi KEYWORD2 @@ -621,6 +671,7 @@ uint64ToString KEYWORD2 uint8ToBcd KEYWORD2 updateSavedState KEYWORD2 validChecksum KEYWORD2 +validSection KEYWORD2 vestel KEYWORD2 whirlpool KEYWORD2 xorBytes KEYWORD2 @@ -629,6 +680,7 @@ xorBytes KEYWORD2 # Constants (LITERAL1) ####################################### +*kAllProtocolNamesStr LITERAL1 // LITERAL1 AIRWELL LITERAL1 AIWA_RC_T501 LITERAL1 @@ -665,9 +717,12 @@ ARRAH2E LITERAL1 ARREB1E LITERAL1 ARRY4 LITERAL1 CARRIER_AC LITERAL1 +CARRIER_AC40 LITERAL1 +CARRIER_AC64 LITERAL1 CARRIER_AC_BITS LITERAL1 COOLIX LITERAL1 COOLIX_BITS LITERAL1 +CORONA_AC LITERAL1 DAIKIN LITERAL1 DAIKIN128 LITERAL1 DAIKIN152 LITERAL1 @@ -694,7 +749,10 @@ DECODE_AIWA_RC_T501 LITERAL1 DECODE_AMCOR LITERAL1 DECODE_ARGO LITERAL1 DECODE_CARRIER_AC LITERAL1 +DECODE_CARRIER_AC40 LITERAL1 +DECODE_CARRIER_AC64 LITERAL1 DECODE_COOLIX LITERAL1 +DECODE_CORONA_AC LITERAL1 DECODE_DAIKIN LITERAL1 DECODE_DAIKIN128 LITERAL1 DECODE_DAIKIN152 LITERAL1 @@ -703,8 +761,10 @@ DECODE_DAIKIN176 LITERAL1 DECODE_DAIKIN2 LITERAL1 DECODE_DAIKIN216 LITERAL1 DECODE_DAIKIN64 LITERAL1 +DECODE_DELONGHI_AC LITERAL1 DECODE_DENON LITERAL1 DECODE_DISH LITERAL1 +DECODE_DOSHISHA LITERAL1 DECODE_ELECTRA_AC LITERAL1 DECODE_EPSON LITERAL1 DECODE_FUJITSU_AC LITERAL1 @@ -719,6 +779,7 @@ DECODE_HITACHI_AC LITERAL1 DECODE_HITACHI_AC1 LITERAL1 DECODE_HITACHI_AC2 LITERAL1 DECODE_HITACHI_AC3 LITERAL1 +DECODE_HITACHI_AC344 LITERAL1 DECODE_HITACHI_AC424 LITERAL1 DECODE_INAX LITERAL1 DECODE_JVC LITERAL1 @@ -729,12 +790,14 @@ DECODE_LG LITERAL1 DECODE_LUTRON LITERAL1 DECODE_MAGIQUEST LITERAL1 DECODE_MIDEA LITERAL1 +DECODE_MIDEA24 LITERAL1 DECODE_MITSUBISHI LITERAL1 DECODE_MITSUBISHI112 LITERAL1 DECODE_MITSUBISHI136 LITERAL1 DECODE_MITSUBISHI2 LITERAL1 DECODE_MITSUBISHIHEAVY LITERAL1 DECODE_MITSUBISHI_AC LITERAL1 +DECODE_MULTIBRACKETS LITERAL1 DECODE_MWM LITERAL1 DECODE_NEC LITERAL1 DECODE_NEOCLIMA LITERAL1 @@ -762,6 +825,8 @@ DECODE_TROTEC LITERAL1 DECODE_VESTEL_AC LITERAL1 DECODE_WHIRLPOOL_AC LITERAL1 DECODE_WHYNTER LITERAL1 +DECODE_ZEPEAL LITERAL1 +DELONGHI_AC LITERAL1 DENON LITERAL1 DENON_48_BITS LITERAL1 DENON_BITS LITERAL1 @@ -770,6 +835,7 @@ DG11J13A LITERAL1 DG11J191 LITERAL1 DISH LITERAL1 DISH_BITS LITERAL1 +DOSHISHA LITERAL1 ELECTRA_AC LITERAL1 ENABLE_NOISE_FILTER_OPTION LITERAL1 EPSON LITERAL1 @@ -892,6 +958,7 @@ HITACHI_AC2 LITERAL1 HITACHI_AC2_BITS LITERAL1 HITACHI_AC2_STATE_LENGTH LITERAL1 HITACHI_AC3 LITERAL1 +HITACHI_AC344 LITERAL1 HITACHI_AC424 LITERAL1 HITACHI_AC_BITS LITERAL1 HITACHI_AC_STATE_LENGTH LITERAL1 @@ -924,6 +991,7 @@ LUTRON LITERAL1 MAGIQUEST LITERAL1 MAGIQUEST_BITS LITERAL1 MIDEA LITERAL1 +MIDEA24 LITERAL1 MIDEA_AC_AUTO LITERAL1 MIDEA_AC_COOL LITERAL1 MIDEA_AC_DRY LITERAL1 @@ -962,6 +1030,7 @@ MITSUBISHI_AC_VANE_AUTO_MOVE LITERAL1 MITSUBISHI_BITS LITERAL1 MITSUBISHI_HEAVY_152 LITERAL1 MITSUBISHI_HEAVY_88 LITERAL1 +MULTIBRACKETS LITERAL1 MWM LITERAL1 NEC LITERAL1 NEC_BITS LITERAL1 @@ -1002,7 +1071,10 @@ SEND_AIWA_RC_T501 LITERAL1 SEND_AMCOR LITERAL1 SEND_ARGO LITERAL1 SEND_CARRIER_AC LITERAL1 +SEND_CARRIER_AC40 LITERAL1 +SEND_CARRIER_AC64 LITERAL1 SEND_COOLIX LITERAL1 +SEND_CORONA_AC LITERAL1 SEND_DAIKIN LITERAL1 SEND_DAIKIN128 LITERAL1 SEND_DAIKIN152 LITERAL1 @@ -1011,8 +1083,10 @@ SEND_DAIKIN176 LITERAL1 SEND_DAIKIN2 LITERAL1 SEND_DAIKIN216 LITERAL1 SEND_DAIKIN64 LITERAL1 +SEND_DELONGHI_AC LITERAL1 SEND_DENON LITERAL1 SEND_DISH LITERAL1 +SEND_DOSHISHA LITERAL1 SEND_ELECTRA_AC LITERAL1 SEND_EPSON LITERAL1 SEND_FUJITSU_AC LITERAL1 @@ -1026,6 +1100,7 @@ SEND_HITACHI_AC LITERAL1 SEND_HITACHI_AC1 LITERAL1 SEND_HITACHI_AC2 LITERAL1 SEND_HITACHI_AC3 LITERAL1 +SEND_HITACHI_AC344 LITERAL1 SEND_HITACHI_AC424 LITERAL1 SEND_INAX LITERAL1 SEND_JVC LITERAL1 @@ -1036,12 +1111,14 @@ SEND_LG LITERAL1 SEND_LUTRON LITERAL1 SEND_MAGIQUEST LITERAL1 SEND_MIDEA LITERAL1 +SEND_MIDEA24 LITERAL1 SEND_MITSUBISHI LITERAL1 SEND_MITSUBISHI112 LITERAL1 SEND_MITSUBISHI136 LITERAL1 SEND_MITSUBISHI2 LITERAL1 SEND_MITSUBISHIHEAVY LITERAL1 SEND_MITSUBISHI_AC LITERAL1 +SEND_MULTIBRACKETS LITERAL1 SEND_MWM LITERAL1 SEND_NEC LITERAL1 SEND_NEOCLIMA LITERAL1 @@ -1070,6 +1147,7 @@ SEND_TROTEC LITERAL1 SEND_VESTEL_AC LITERAL1 SEND_WHIRLPOOL_AC LITERAL1 SEND_WHYNTER LITERAL1 +SEND_ZEPEAL LITERAL1 SHARP LITERAL1 SHARP_AC LITERAL1 SHARP_BITS LITERAL1 @@ -1116,6 +1194,7 @@ WHYNTER LITERAL1 WHYNTER_BITS LITERAL1 YAW1F LITERAL1 YBOFB LITERAL1 +ZEPEAL LITERAL1 k3DStr LITERAL1 k6thSenseStr LITERAL1 k8CHeatStr LITERAL1 @@ -1251,8 +1330,52 @@ kBottomStr LITERAL1 kBreezeStr LITERAL1 kButtonStr LITERAL1 kCancelStr LITERAL1 +kCarrierAc40BitMark LITERAL1 +kCarrierAc40Bits LITERAL1 +kCarrierAc40Gap LITERAL1 +kCarrierAc40HdrMark LITERAL1 +kCarrierAc40HdrSpace LITERAL1 +kCarrierAc40MinRepeat LITERAL1 +kCarrierAc40OneSpace LITERAL1 +kCarrierAc40ZeroSpace LITERAL1 +kCarrierAc64BitMark LITERAL1 +kCarrierAc64Bits LITERAL1 +kCarrierAc64ChecksumOffset LITERAL1 +kCarrierAc64ChecksumSize LITERAL1 +kCarrierAc64Cool LITERAL1 +kCarrierAc64Fan LITERAL1 +kCarrierAc64FanAuto LITERAL1 +kCarrierAc64FanHigh LITERAL1 +kCarrierAc64FanLow LITERAL1 +kCarrierAc64FanMedium LITERAL1 +kCarrierAc64FanOffset LITERAL1 +kCarrierAc64FanSize LITERAL1 +kCarrierAc64Gap LITERAL1 +kCarrierAc64HdrMark LITERAL1 +kCarrierAc64HdrSpace LITERAL1 +kCarrierAc64Heat LITERAL1 +kCarrierAc64MaxTemp LITERAL1 +kCarrierAc64MinRepeat LITERAL1 +kCarrierAc64MinTemp LITERAL1 +kCarrierAc64ModeOffset LITERAL1 +kCarrierAc64ModeSize LITERAL1 +kCarrierAc64OffTimerEnableOffset LITERAL1 +kCarrierAc64OffTimerOffset LITERAL1 +kCarrierAc64OnTimerEnableOffset LITERAL1 +kCarrierAc64OnTimerOffset LITERAL1 +kCarrierAc64OneSpace LITERAL1 +kCarrierAc64PowerOffset LITERAL1 +kCarrierAc64SleepOffset LITERAL1 +kCarrierAc64SwingVOffset LITERAL1 +kCarrierAc64TempOffset LITERAL1 +kCarrierAc64TempSize LITERAL1 +kCarrierAc64TimerMax LITERAL1 +kCarrierAc64TimerMin LITERAL1 +kCarrierAc64TimerSize LITERAL1 +kCarrierAc64ZeroSpace LITERAL1 kCarrierAcBitMark LITERAL1 kCarrierAcBits LITERAL1 +kCarrierAcFreq LITERAL1 kCarrierAcGap LITERAL1 kCarrierAcHdrMark LITERAL1 kCarrierAcHdrSpace LITERAL1 @@ -1329,6 +1452,61 @@ kCoolixUnknown LITERAL1 kCoolixZeroSpace LITERAL1 kCoolixZeroSpaceTicks LITERAL1 kCoolixZoneFollowMaskOffset LITERAL1 +kCoronaAcAutoD0 LITERAL1 +kCoronaAcAutoD1 LITERAL1 +kCoronaAcBitMark LITERAL1 +kCoronaAcBits LITERAL1 +kCoronaAcBitsShort LITERAL1 +kCoronaAcFanAuto LITERAL1 +kCoronaAcFanHigh LITERAL1 +kCoronaAcFanLow LITERAL1 +kCoronaAcFanMedium LITERAL1 +kCoronaAcFanOffset LITERAL1 +kCoronaAcFanSize LITERAL1 +kCoronaAcFreq LITERAL1 +kCoronaAcHdrMark LITERAL1 +kCoronaAcHdrSpace LITERAL1 +kCoronaAcMaxTemp LITERAL1 +kCoronaAcMinTemp LITERAL1 +kCoronaAcModeCool LITERAL1 +kCoronaAcModeDry LITERAL1 +kCoronaAcModeFan LITERAL1 +kCoronaAcModeHeat LITERAL1 +kCoronaAcModeOffset LITERAL1 +kCoronaAcModeSize LITERAL1 +kCoronaAcOffTimerSection LITERAL1 +kCoronaAcOnTimerSection LITERAL1 +kCoronaAcOneSpace LITERAL1 +kCoronaAcOverhead LITERAL1 +kCoronaAcOverheadShort LITERAL1 +kCoronaAcPowerButtonOffset LITERAL1 +kCoronaAcPowerOffset LITERAL1 +kCoronaAcPowerSaveOffset LITERAL1 +kCoronaAcSectionBytes LITERAL1 +kCoronaAcSectionData0Base LITERAL1 +kCoronaAcSectionData0InvPos LITERAL1 +kCoronaAcSectionData0Pos LITERAL1 +kCoronaAcSectionData1InvPos LITERAL1 +kCoronaAcSectionData1Pos LITERAL1 +kCoronaAcSectionHeader0 LITERAL1 +kCoronaAcSectionHeader0Pos LITERAL1 +kCoronaAcSectionHeader1 LITERAL1 +kCoronaAcSectionHeader1Pos LITERAL1 +kCoronaAcSectionLabelBase LITERAL1 +kCoronaAcSectionLabelPos LITERAL1 +kCoronaAcSections LITERAL1 +kCoronaAcSettingsSection LITERAL1 +kCoronaAcSpaceGap LITERAL1 +kCoronaAcStateLength LITERAL1 +kCoronaAcStateLengthShort LITERAL1 +kCoronaAcSwingVToggleOffset LITERAL1 +kCoronaAcTempOffset LITERAL1 +kCoronaAcTempSize LITERAL1 +kCoronaAcTimerMax LITERAL1 +kCoronaAcTimerOff LITERAL1 +kCoronaAcTimerUnitsPerMin LITERAL1 +kCoronaAcZeroSpace LITERAL1 +kCoronaTolerance LITERAL1 kDaikin128Auto LITERAL1 kDaikin128BitCeiling LITERAL1 kDaikin128BitEcono LITERAL1 @@ -1595,6 +1773,7 @@ kDaikin64SleepBit LITERAL1 kDaikin64SwingVBit LITERAL1 kDaikin64TempOffset LITERAL1 kDaikin64TempSize LITERAL1 +kDaikin64ToleranceDelta LITERAL1 kDaikin64ZeroSpace LITERAL1 kDaikinAuto LITERAL1 kDaikinBeepLoud LITERAL1 @@ -1700,6 +1879,51 @@ kDayStr LITERAL1 kDaysStr LITERAL1 kDefaultESP32Timer LITERAL1 kDefaultMessageGap LITERAL1 +kDelonghiAcAuto LITERAL1 +kDelonghiAcBitMark LITERAL1 +kDelonghiAcBits LITERAL1 +kDelonghiAcBoostBit LITERAL1 +kDelonghiAcChecksumOffset LITERAL1 +kDelonghiAcChecksumSize LITERAL1 +kDelonghiAcCool LITERAL1 +kDelonghiAcDefaultRepeat LITERAL1 +kDelonghiAcDry LITERAL1 +kDelonghiAcFan LITERAL1 +kDelonghiAcFanAuto LITERAL1 +kDelonghiAcFanHigh LITERAL1 +kDelonghiAcFanLow LITERAL1 +kDelonghiAcFanMedium LITERAL1 +kDelonghiAcFanOffset LITERAL1 +kDelonghiAcFanSize LITERAL1 +kDelonghiAcFreq LITERAL1 +kDelonghiAcGap LITERAL1 +kDelonghiAcHdrMark LITERAL1 +kDelonghiAcHdrSpace LITERAL1 +kDelonghiAcHoursSize LITERAL1 +kDelonghiAcMinsSize LITERAL1 +kDelonghiAcModeOffset LITERAL1 +kDelonghiAcModeSize LITERAL1 +kDelonghiAcOffTimerEnableBit LITERAL1 +kDelonghiAcOffTimerHoursOffset LITERAL1 +kDelonghiAcOffTimerMinsOffset LITERAL1 +kDelonghiAcOnTimerEnableBit LITERAL1 +kDelonghiAcOnTimerHoursOffset LITERAL1 +kDelonghiAcOnTimerMinsOffset LITERAL1 +kDelonghiAcOneSpace LITERAL1 +kDelonghiAcOverhead LITERAL1 +kDelonghiAcPowerBit LITERAL1 +kDelonghiAcSleepBit LITERAL1 +kDelonghiAcTempAutoDryMode LITERAL1 +kDelonghiAcTempFanMode LITERAL1 +kDelonghiAcTempMaxC LITERAL1 +kDelonghiAcTempMaxF LITERAL1 +kDelonghiAcTempMinC LITERAL1 +kDelonghiAcTempMinF LITERAL1 +kDelonghiAcTempOffset LITERAL1 +kDelonghiAcTempSize LITERAL1 +kDelonghiAcTempUnitBit LITERAL1 +kDelonghiAcTimerMax LITERAL1 +kDelonghiAcZeroSpace LITERAL1 kDenon48Bits LITERAL1 kDenonBitMark LITERAL1 kDenonBitMarkTicks LITERAL1 @@ -1733,6 +1957,13 @@ kDishRptSpaceTicks LITERAL1 kDishTick LITERAL1 kDishZeroSpace LITERAL1 kDishZeroSpaceTicks LITERAL1 +kDisplayTempStr LITERAL1 +kDoshishaBitMark LITERAL1 +kDoshishaBits LITERAL1 +kDoshishaHdrMark LITERAL1 +kDoshishaHdrSpace LITERAL1 +kDoshishaOneSpace LITERAL1 +kDoshishaZeroSpace LITERAL1 kDownStr LITERAL1 kDry LITERAL1 kDryStr LITERAL1 @@ -1908,6 +2139,12 @@ kGreeBlockFooter LITERAL1 kGreeBlockFooterBits LITERAL1 kGreeCool LITERAL1 kGreeDefaultRepeat LITERAL1 +kGreeDisplayTempInside LITERAL1 +kGreeDisplayTempOff LITERAL1 +kGreeDisplayTempOffset LITERAL1 +kGreeDisplayTempOutside LITERAL1 +kGreeDisplayTempSet LITERAL1 +kGreeDisplayTempSize LITERAL1 kGreeDry LITERAL1 kGreeFan LITERAL1 kGreeFanAuto LITERAL1 @@ -1921,8 +2158,10 @@ kGreeHdrSpace LITERAL1 kGreeHeat LITERAL1 kGreeIFeelOffset LITERAL1 kGreeLightOffset LITERAL1 -kGreeMaxTemp LITERAL1 -kGreeMinTemp LITERAL1 +kGreeMaxTempC LITERAL1 +kGreeMaxTempF LITERAL1 +kGreeMinTempC LITERAL1 +kGreeMinTempF LITERAL1 kGreeMsgSpace LITERAL1 kGreeOneSpace LITERAL1 kGreePower1Offset LITERAL1 @@ -1941,6 +2180,8 @@ kGreeSwingMiddleUp LITERAL1 kGreeSwingSize LITERAL1 kGreeSwingUp LITERAL1 kGreeSwingUpAuto LITERAL1 +kGreeTempExtraDegreeFOffset LITERAL1 +kGreeTempOffset LITERAL1 kGreeTempSize LITERAL1 kGreeTimerEnabledOffset LITERAL1 kGreeTimerHalfHrOffset LITERAL1 @@ -1950,6 +2191,7 @@ kGreeTimerMax LITERAL1 kGreeTimerTensHrOffset LITERAL1 kGreeTimerTensHrSize LITERAL1 kGreeTurboOffset LITERAL1 +kGreeUseFahrenheitOffset LITERAL1 kGreeWiFiOffset LITERAL1 kGreeXfanOffset LITERAL1 kGreeZeroSpace LITERAL1 @@ -2105,6 +2347,37 @@ kHitachiAc1TempSize LITERAL1 kHitachiAc1TimerSize LITERAL1 kHitachiAc2Bits LITERAL1 kHitachiAc2StateLength LITERAL1 +kHitachiAc344Bits LITERAL1 +kHitachiAc344ButtonFan LITERAL1 +kHitachiAc344ButtonPowerMode LITERAL1 +kHitachiAc344ButtonSwingH LITERAL1 +kHitachiAc344ButtonSwingV LITERAL1 +kHitachiAc344ButtonTempDown LITERAL1 +kHitachiAc344ButtonTempUp LITERAL1 +kHitachiAc344Cool LITERAL1 +kHitachiAc344Dry LITERAL1 +kHitachiAc344Fan LITERAL1 +kHitachiAc344FanAuto LITERAL1 +kHitachiAc344FanHigh LITERAL1 +kHitachiAc344FanLow LITERAL1 +kHitachiAc344FanMax LITERAL1 +kHitachiAc344FanMedium LITERAL1 +kHitachiAc344FanMin LITERAL1 +kHitachiAc344Heat LITERAL1 +kHitachiAc344MaxTemp LITERAL1 +kHitachiAc344MinTemp LITERAL1 +kHitachiAc344StateLength LITERAL1 +kHitachiAc344SwingHAuto LITERAL1 +kHitachiAc344SwingHByte LITERAL1 +kHitachiAc344SwingHLeft LITERAL1 +kHitachiAc344SwingHLeftMax LITERAL1 +kHitachiAc344SwingHMiddle LITERAL1 +kHitachiAc344SwingHOffset LITERAL1 +kHitachiAc344SwingHRight LITERAL1 +kHitachiAc344SwingHRightMax LITERAL1 +kHitachiAc344SwingHSize LITERAL1 +kHitachiAc344SwingVByte LITERAL1 +kHitachiAc344SwingVOffset LITERAL1 kHitachiAc3BitMark LITERAL1 kHitachiAc3Bits LITERAL1 kHitachiAc3HdrMark LITERAL1 @@ -2119,6 +2392,7 @@ kHitachiAc424Bits LITERAL1 kHitachiAc424ButtonByte LITERAL1 kHitachiAc424ButtonFan LITERAL1 kHitachiAc424ButtonPowerMode LITERAL1 +kHitachiAc424ButtonSwingH LITERAL1 kHitachiAc424ButtonSwingV LITERAL1 kHitachiAc424ButtonTempDown LITERAL1 kHitachiAc424ButtonTempUp LITERAL1 @@ -2190,6 +2464,7 @@ kInaxMinRepeat LITERAL1 kInaxOneSpace LITERAL1 kInaxTick LITERAL1 kInaxZeroSpace LITERAL1 +kInsideStr LITERAL1 kIonStr LITERAL1 kJvcBitMark LITERAL1 kJvcBitMarkTicks LITERAL1 @@ -2383,6 +2658,9 @@ kMediumStr LITERAL1 kMidStr LITERAL1 kMiddle LITERAL1 kMiddleStr LITERAL1 +kMidea24Bits LITERAL1 +kMidea24MinGap LITERAL1 +kMidea24MinRepeat LITERAL1 kMideaACAuto LITERAL1 kMideaACCelsiusOffset LITERAL1 kMideaACCool LITERAL1 @@ -2660,6 +2938,13 @@ kModeStr LITERAL1 kModelStr LITERAL1 kMouldStr LITERAL1 kMoveStr LITERAL1 +kMultibracketsBits LITERAL1 +kMultibracketsDefaultRepeat LITERAL1 +kMultibracketsFooterSpace LITERAL1 +kMultibracketsFreq LITERAL1 +kMultibracketsHdrMark LITERAL1 +kMultibracketsTick LITERAL1 +kMultibracketsTolerance LITERAL1 kNAStr LITERAL1 kNECBits LITERAL1 kNecBitMark LITERAL1 @@ -2859,6 +3144,7 @@ kPioneerOneSpaceTicks LITERAL1 kPioneerTick LITERAL1 kPioneerZeroSpace LITERAL1 kPioneerZeroSpaceTicks LITERAL1 +kPowerButtonStr LITERAL1 kPowerStr LITERAL1 kPowerToggleStr LITERAL1 kPowerfulStr LITERAL1 @@ -2916,6 +3202,22 @@ kRcmmRptLength LITERAL1 kRcmmRptLengthTicks LITERAL1 kRcmmTick LITERAL1 kRcmmTolerance LITERAL1 +kRcz01ChannelMask LITERAL1 +kRcz01CommandLevel1 LITERAL1 +kRcz01CommandLevel2 LITERAL1 +kRcz01CommandLevel3 LITERAL1 +kRcz01CommandLevel4 LITERAL1 +kRcz01CommandLevelDown LITERAL1 +kRcz01CommandLevelUp LITERAL1 +kRcz01CommandMask LITERAL1 +kRcz01CommandNightLight LITERAL1 +kRcz01CommandOff LITERAL1 +kRcz01CommandOn LITERAL1 +kRcz01CommandSwitchChannel LITERAL1 +kRcz01CommandTimmer30 LITERAL1 +kRcz01CommandTimmer60 LITERAL1 +kRcz01Signature LITERAL1 +kRcz01SignatureMask LITERAL1 kRepeat LITERAL1 kRepeatStr LITERAL1 kRight LITERAL1 @@ -3022,20 +3324,21 @@ kSensorStr LITERAL1 kSensorTempStr LITERAL1 kSetStr LITERAL1 kSharpAcAuto LITERAL1 +kSharpAcBitCleanOffset LITERAL1 +kSharpAcBitIonOffset LITERAL1 kSharpAcBitMark LITERAL1 -kSharpAcBitPowerOffset LITERAL1 -kSharpAcBitPreviousPowerOffset LITERAL1 +kSharpAcBitTimerEnabled LITERAL1 +kSharpAcBitTimerType LITERAL1 kSharpAcBits LITERAL1 -kSharpAcButtonFan LITERAL1 -kSharpAcButtonOffset LITERAL1 -kSharpAcButtonPowerMode LITERAL1 -kSharpAcButtonSize LITERAL1 -kSharpAcButtonTemp LITERAL1 -kSharpAcByteButton LITERAL1 +kSharpAcByteClean LITERAL1 kSharpAcByteFan LITERAL1 +kSharpAcByteIon LITERAL1 kSharpAcByteMode LITERAL1 -kSharpAcBytePower LITERAL1 +kSharpAcBytePowerSpecial LITERAL1 +kSharpAcByteSpecial LITERAL1 +kSharpAcByteSwing LITERAL1 kSharpAcByteTemp LITERAL1 +kSharpAcByteTimer LITERAL1 kSharpAcCool LITERAL1 kSharpAcDefaultRepeat LITERAL1 kSharpAcDry LITERAL1 @@ -3053,8 +3356,35 @@ kSharpAcHeat LITERAL1 kSharpAcMaxTemp LITERAL1 kSharpAcMinTemp LITERAL1 kSharpAcModeSize LITERAL1 +kSharpAcOffTimerType LITERAL1 +kSharpAcOnTimerType LITERAL1 kSharpAcOneSpace LITERAL1 +kSharpAcPowerOff LITERAL1 +kSharpAcPowerOn LITERAL1 +kSharpAcPowerOnFromOff LITERAL1 +kSharpAcPowerSetSpecialOff LITERAL1 +kSharpAcPowerSetSpecialOffset LITERAL1 +kSharpAcPowerSetSpecialOn LITERAL1 +kSharpAcPowerSpecialSize LITERAL1 +kSharpAcPowerTimerSetting LITERAL1 +kSharpAcPowerUnknown LITERAL1 +kSharpAcSpecialFan LITERAL1 +kSharpAcSpecialPower LITERAL1 +kSharpAcSpecialSwing LITERAL1 +kSharpAcSpecialTempEcono LITERAL1 +kSharpAcSpecialTimer LITERAL1 +kSharpAcSpecialTimerHalfHour LITERAL1 +kSharpAcSpecialTurbo LITERAL1 kSharpAcStateLength LITERAL1 +kSharpAcSwingNoToggle LITERAL1 +kSharpAcSwingOffset LITERAL1 +kSharpAcSwingSize LITERAL1 +kSharpAcSwingToggle LITERAL1 +kSharpAcTimerHoursMax LITERAL1 +kSharpAcTimerHoursOff LITERAL1 +kSharpAcTimerHoursOffset LITERAL1 +kSharpAcTimerHoursSize LITERAL1 +kSharpAcTimerIncrement LITERAL1 kSharpAcZeroSpace LITERAL1 kSharpAddressBits LITERAL1 kSharpAddressMask LITERAL1 @@ -3116,7 +3446,6 @@ kSwingVToggleStr LITERAL1 kSymphonyBits LITERAL1 kSymphonyDefaultRepeat LITERAL1 kSymphonyFooterGap LITERAL1 -kSymphonyFooterMark LITERAL1 kSymphonyOneMark LITERAL1 kSymphonyOneSpace LITERAL1 kSymphonyZeroMark LITERAL1 @@ -3404,4 +3733,21 @@ kWideStr LITERAL1 kWifiStr LITERAL1 kXFanStr LITERAL1 kYesStr LITERAL1 +kZepealBits LITERAL1 +kZepealCommandOffOn LITERAL1 +kZepealCommandOffTimer LITERAL1 +kZepealCommandOnTimer LITERAL1 +kZepealCommandRhythm LITERAL1 +kZepealCommandSpeed LITERAL1 +kZepealFooterMark LITERAL1 +kZepealGap LITERAL1 +kZepealHdrMark LITERAL1 +kZepealHdrSpace LITERAL1 +kZepealMinRepeat LITERAL1 +kZepealOneMark LITERAL1 +kZepealOneSpace LITERAL1 +kZepealSignature LITERAL1 +kZepealTolerance LITERAL1 +kZepealZeroMark LITERAL1 +kZepealZeroSpace LITERAL1 kZoneFollowStr LITERAL1 diff --git a/lib/IRremoteESP8266-2.7.5/library.json b/lib/IRremoteESP8266-2.7.8/library.json similarity index 88% rename from lib/IRremoteESP8266-2.7.5/library.json rename to lib/IRremoteESP8266-2.7.8/library.json index 3220f9bd2..c92323c46 100644 --- a/lib/IRremoteESP8266-2.7.5/library.json +++ b/lib/IRremoteESP8266-2.7.8/library.json @@ -1,6 +1,6 @@ { "name": "IRremoteESP8266", - "version": "2.7.5", + "version": "2.7.8", "keywords": "infrared, ir, remote, esp8266, esp32", "description": "Send and receive infrared signals with multiple protocols (ESP8266/ESP32)", "repository": @@ -37,6 +37,11 @@ "name": "Massimiliano Pinto", "url": "https://github.com/pintomax/", "maintainer": true + }, + { + "name": "Christian Nilsson", + "url": "https://github.com/NiKiZe", + "maintainer": true } ], "frameworks": "arduino", diff --git a/lib/IRremoteESP8266-2.7.5/library.properties b/lib/IRremoteESP8266-2.7.8/library.properties similarity index 89% rename from lib/IRremoteESP8266-2.7.5/library.properties rename to lib/IRremoteESP8266-2.7.8/library.properties index 16d4c2d20..785252195 100644 --- a/lib/IRremoteESP8266-2.7.5/library.properties +++ b/lib/IRremoteESP8266-2.7.8/library.properties @@ -1,7 +1,7 @@ name=IRremoteESP8266 -version=2.7.5 +version=2.7.8 author=David Conran, Sebastien Warin, Mark Szabo, Ken Shirriff -maintainer=David Conran, Mark Szabo, Sebastien Warin, Roi Dayan, Massimiliano Pinto +maintainer=David Conran, Mark Szabo, Sebastien Warin, Roi Dayan, Massimiliano Pinto, Christian Nilsson sentence=Send and receive infrared signals with multiple protocols (ESP8266/ESP32) paragraph=This library enables you to send and receive infra-red signals on an ESP8266 or an ESP32. category=Device Control diff --git a/lib/IRremoteESP8266-2.7.8/platformio.ini b/lib/IRremoteESP8266-2.7.8/platformio.ini new file mode 100644 index 000000000..76c2f3b40 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/platformio.ini @@ -0,0 +1,22 @@ +[platformio] +# Default to building IRrecvDumpV2 if not in a specific example directory. +src_dir = examples/IRrecvDumpV2 + +[env] +lib_extra_dirs = . +lib_ldf_mode = deep+ +lib_ignore = examples +framework = arduino +platform = espressif8266 +build_flags = ; -D_IR_LOCALE_=en-AU +monitor_speed = 115200 + +[env:nodemcuv2] +board = nodemcuv2 + +[env:d1_mini] +board = d1_mini + +[env:esp32dev] +platform = espressif32 +board = esp32dev diff --git a/lib/IRremoteESP8266-2.7.5/pylintrc b/lib/IRremoteESP8266-2.7.8/pylintrc similarity index 100% rename from lib/IRremoteESP8266-2.7.5/pylintrc rename to lib/IRremoteESP8266-2.7.8/pylintrc diff --git a/lib/IRremoteESP8266-2.7.5/src/CPPLINT.cfg b/lib/IRremoteESP8266-2.7.8/src/CPPLINT.cfg similarity index 100% rename from lib/IRremoteESP8266-2.7.5/src/CPPLINT.cfg rename to lib/IRremoteESP8266-2.7.8/src/CPPLINT.cfg diff --git a/lib/IRremoteESP8266-2.7.5/src/IRac.cpp b/lib/IRremoteESP8266-2.7.8/src/IRac.cpp similarity index 66% rename from lib/IRremoteESP8266-2.7.5/src/IRac.cpp rename to lib/IRremoteESP8266-2.7.8/src/IRac.cpp index abf450df9..fda16aba5 100644 --- a/lib/IRremoteESP8266-2.7.5/src/IRac.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/IRac.cpp @@ -2,7 +2,7 @@ // Provide a universal/standard interface for sending A/C nessages. // It does not provide complete and maximum granular control but tries -// to off most common functionallity across all supported devices. +// to offer most common functionality across all supported devices. #include "IRac.h" #ifndef UNIT_TEST @@ -18,7 +18,9 @@ #include "IRutils.h" #include "ir_Amcor.h" #include "ir_Argo.h" +#include "ir_Carrier.h" #include "ir_Coolix.h" +#include "ir_Corona.h" #include "ir_Daikin.h" #include "ir_Electra.h" #include "ir_Fujitsu.h" @@ -40,6 +42,10 @@ #include "ir_Vestel.h" #include "ir_Whirlpool.h" +/// 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. +/// @param[in] use_modulation true means use frequency modulation. false, don't. IRac::IRac(const uint16_t pin, const bool inverted, const bool use_modulation) { _pin = pin; _inverted = inverted; @@ -48,6 +54,29 @@ IRac::IRac(const uint16_t pin, const bool inverted, const bool use_modulation) { this->markAsSent(); } +/// Initialse the given state with the supplied settings. +/// @param[out] state A Ptr to where the settings will be stored. +/// @param[in] vendor The vendor/protocol type. +/// @param[in] model The A/C model if applicable. +/// @param[in] power The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] celsius Temperature units. True is Celsius, False is Fahrenheit. +/// @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] quiet Run the device in quiet/silent mode. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] econo Run the device in economical mode. +/// @param[in] light Turn on the LED/Display mode. +/// @param[in] filter Turn on the (ion/pollen/etc) filter mode. +/// @param[in] clean Turn on the self-cleaning mode. e.g. Mould, dry filters etc +/// @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. Some devices it is the nr. of mins to run for. +/// Others it may be the time to enter/exit sleep mode. +/// i.e. Time in Nr. of mins since midnight. +/// @param[in] clock The time in Nr. of mins since midnight. < 0 is ignore. void IRac::initState(stdAc::state_t *state, const decode_type_t vendor, const int16_t model, const bool power, const stdAc::opmode_t mode, @@ -78,6 +107,9 @@ void IRac::initState(stdAc::state_t *state, state->clock = clock; } +/// Initialse the given state with the supplied settings. +/// @param[out] state A Ptr to where the settings will be stored. +/// @note Sets all the parameters to reasonable base/automatic defaults. void IRac::initState(stdAc::state_t *state) { initState(state, decode_type_t::UNKNOWN, -1, false, stdAc::opmode_t::kOff, 25, true, // 25 degrees Celsius @@ -86,11 +118,18 @@ void IRac::initState(stdAc::state_t *state) { false, -1, -1); } +/// Get the current internal A/C climate state. +/// @return A Ptr to a state containing the current (to be sent) settings. stdAc::state_t IRac::getState(void) { return next; } +/// Get the previous internal A/C climate state that should have already been +/// sent to the device. i.e. What the A/C unit should already be set to. +/// @return A Ptr to a state containing the previously sent settings. stdAc::state_t IRac::getStatePrev(void) { return _prev; } -// Is the given protocol supported by the IRac class? +/// Is the given protocol supported by the IRac class? +/// @param[in] protocol The vendor/protocol type. +/// @return true if the protocol is supported by this class, otherwise false. bool IRac::isProtocolSupported(const decode_type_t protocol) { switch (protocol) { #if SEND_AMCOR @@ -99,9 +138,15 @@ bool IRac::isProtocolSupported(const decode_type_t protocol) { #if SEND_ARGO case decode_type_t::ARGO: #endif +#if SEND_CARRIER_AC64 + case decode_type_t::CARRIER_AC64: +#endif // SEND_CARRIER_AC64 #if SEND_COOLIX case decode_type_t::COOLIX: #endif +#if SEND_CORONA_AC + case decode_type_t::CORONA_AC: +#endif #if SEND_DAIKIN case decode_type_t::DAIKIN: #endif @@ -126,6 +171,9 @@ bool IRac::isProtocolSupported(const decode_type_t protocol) { #if SEND_DAIKIN64 case decode_type_t::DAIKIN64: #endif +#if SEND_DELONGHI_AC + case decode_type_t::DELONGHI_AC: +#endif #if SEND_ELECTRA_AC case decode_type_t::ELECTRA_AC: #endif @@ -150,6 +198,9 @@ bool IRac::isProtocolSupported(const decode_type_t protocol) { #if SEND_HITACHI_AC1 case decode_type_t::HITACHI_AC1: #endif +#if SEND_HITACHI_AC344 + case decode_type_t::HITACHI_AC344: +#endif #if SEND_HITACHI_AC424 case decode_type_t::HITACHI_AC424: #endif @@ -206,13 +257,25 @@ bool IRac::isProtocolSupported(const decode_type_t protocol) { #if SEND_WHIRLPOOL_AC case decode_type_t::WHIRLPOOL_AC: #endif +// Note: Compiler Warning is disabled because someone could disable all +// the protocols before this and it is then unreachable. +// "-Wswitch-unreachable" not used as it appears to be an unknown option. +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wall" return true; +#pragma GCC diagnostic pop default: return false; } } #if SEND_AMCOR +/// Send an Amcor A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRAmcorAc object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. void IRac::amcor(IRAmcorAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan) { @@ -235,6 +298,16 @@ void IRac::amcor(IRAmcorAc *ac, #endif // SEND_AMCOR #if SEND_ARGO +/// Send an Argo A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRArgoAC object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @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, @@ -257,7 +330,53 @@ void IRac::argo(IRArgoAC *ac, } #endif // SEND_ARGO +#if SEND_CARRIER_AC64 +/// Send a Carrier 64-bit A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRCarrierAc64 object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] sleep Nr. of minutes for sleep mode. +/// @note -1 is Off, >= 0 is on. +void IRac::carrier64(IRCarrierAc64 *ac, + const bool on, const stdAc::opmode_t mode, + const float degrees, const stdAc::fanspeed_t fan, + const stdAc::swingv_t swingv, const int16_t sleep) { + ac->begin(); + ac->setPower(on); + ac->setMode(ac->convertMode(mode)); + ac->setTemp(degrees); + ac->setFan(ac->convertFan(fan)); + ac->setSwingV((int8_t)swingv >= 0); + // No Quiet setting available. + // No Light setting available. + // No Filter setting available. + // No Turbo setting available. + // No Economy setting available. + // No Clean setting available. + // No Beep setting available. + ac->setSleep(sleep >= 0); // Convert to a boolean. + ac->send(); +} +#endif // SEND_CARRIER_AC64 + #if SEND_COOLIX +/// Send a Coolix A/C message with the supplied settings. +/// @note May result in multiple messages being sent. +/// @param[in, out] ac A Ptr to an IRCoolixAC object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] swingh The horizontal swing setting. +/// @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 +/// @param[in] sleep Nr. of minutes for sleep mode. +/// @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, @@ -309,7 +428,51 @@ void IRac::coolix(IRCoolixAC *ac, } #endif // SEND_COOLIX +#if SEND_CORONA_AC +/// Send a Corona A/C message with the supplied settings. +/// @note May result in multiple messages being sent. +/// @param[in, out] ac A Ptr to an IRCoronaAc object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] econo Run the device in economical mode. +void IRac::corona(IRCoronaAc *ac, + const bool on, const stdAc::opmode_t mode, + const float degrees, const stdAc::fanspeed_t fan, + const stdAc::swingv_t swingv, const bool econo) { + ac->begin(); + ac->setPower(on); + ac->setMode(ac->convertMode(mode)); + ac->setTemp(degrees); + ac->setFan(ac->convertFan(fan)); + ac->setSwingVToggle(swingv != stdAc::swingv_t::kOff); + // No Quiet setting available. + // No Light setting available. + // No Filter setting available. + // No Turbo setting available. + ac->setEcono(econo); + // No Clean setting available. + // No Beep setting available. + // No Sleep setting available. + ac->send(); +} +#endif // SEND_CARRIER_AC64 + #if SEND_DAIKIN +/// Send a Daikin A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRDaikinESP object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] swingh The horizontal swing setting. +/// @param[in] quiet Run the device in quiet/silent mode. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] econo Run the device in economical mode. +/// @param[in] clean Turn on the self-cleaning mode. e.g. Mould, dry filters etc void IRac::daikin(IRDaikinESP *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, @@ -337,6 +500,19 @@ void IRac::daikin(IRDaikinESP *ac, #endif // SEND_DAIKIN #if SEND_DAIKIN128 +/// Send a Daikin 128-bit A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRDaikin128 object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] quiet Run the device in quiet/silent mode. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] light Turn on the LED/Display mode. +/// @param[in] econo Run the device in economical mode. +/// @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::daikin128(IRDaikin128 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, @@ -364,6 +540,16 @@ void IRac::daikin128(IRDaikin128 *ac, #endif // SEND_DAIKIN128 #if SEND_DAIKIN152 +/// Send a Daikin 152-bit A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRDaikin152 object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] quiet Run the device in quiet/silent mode. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] econo Run the device in economical mode. void IRac::daikin152(IRDaikin152 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, @@ -390,6 +576,13 @@ void IRac::daikin152(IRDaikin152 *ac, #endif // SEND_DAIKIN152 #if SEND_DAIKIN160 +/// Send a Daikin 160-bit A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRDaikin160 object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. void IRac::daikin160(IRDaikin160 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, @@ -405,6 +598,13 @@ void IRac::daikin160(IRDaikin160 *ac, #endif // SEND_DAIKIN160 #if SEND_DAIKIN176 +/// Send a Daikin 176-bit A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRDaikin176 object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingh The horizontal swing setting. void IRac::daikin176(IRDaikin176 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, @@ -420,6 +620,23 @@ void IRac::daikin176(IRDaikin176 *ac, #endif // SEND_DAIKIN176 #if SEND_DAIKIN2 +/// Send a Daikin2 A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRDaikin2 object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] swingh The horizontal swing setting. +/// @param[in] quiet Run the device in quiet/silent mode. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] light Turn on the LED/Display mode. +/// @param[in] econo Run the device in economical mode. +/// @param[in] filter Turn on the (ion/pollen/etc) filter mode. +/// @param[in] clean Turn on the self-cleaning mode. e.g. Mould, dry filters etc +/// @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. +/// @param[in] clock The time in Nr. of mins since midnight. < 0 is ignore. void IRac::daikin2(IRDaikin2 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, @@ -449,6 +666,16 @@ void IRac::daikin2(IRDaikin2 *ac, #endif // SEND_DAIKIN2 #if SEND_DAIKIN216 +/// Send a Daikin 216-bit A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRDaikin216 object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] swingh The horizontal swing setting. +/// @param[in] quiet Run the device in quiet/silent mode. +/// @param[in] turbo Run the device in turbo/powerful mode. void IRac::daikin216(IRDaikin216 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, @@ -468,6 +695,17 @@ void IRac::daikin216(IRDaikin216 *ac, #endif // SEND_DAIKIN216 #if SEND_DAIKIN64 +/// Send a Daikin 64-bit A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRDaikin64 object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] quiet Run the device in quiet/silent mode. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @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::daikin64(IRDaikin64 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, @@ -488,7 +726,43 @@ void IRac::daikin64(IRDaikin64 *ac, } #endif // SEND_DAIKIN64 +#if SEND_DELONGHI_AC +/// Send a Delonghi A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRDelonghiAc object to use. +/// @param[in] on The power setting. +/// @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] fan The speed setting for the fan. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, >= 0 is on. +void IRac::delonghiac(IRDelonghiAc *ac, + const bool on, const stdAc::opmode_t mode, const bool celsius, + const float degrees, const stdAc::fanspeed_t fan, + const bool turbo, const int16_t sleep) { + ac->begin(); + ac->setPower(on); + ac->setMode(ac->convertMode(mode)); + ac->setTemp(degrees, !celsius); + ac->setFan(ac->convertFan(fan)); + ac->setBoost(turbo); + ac->setSleep(sleep >= 0); + ac->send(); +} +#endif // SEND_DELONGHI_AC + #if SEND_ELECTRA_AC +/// Send an Electra A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRElectraAc object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] swingh The horizontal swing setting. +/// @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, @@ -517,6 +791,20 @@ void IRac::electra(IRElectraAc *ac, #endif // SEND_ELECTRA_AC #if SEND_FUJITSU_AC +/// Send a Fujitsu A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRFujitsuAC object to use. +/// @param[in] model The A/C model to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] swingh The horizontal swing setting. +/// @param[in] quiet Run the device in quiet/silent mode. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] econo Run the device in economical mode. +/// @param[in] filter Turn on the (ion/pollen/etc) filter mode. +/// @param[in] clean Turn on the self-cleaning mode. e.g. Mould, dry filters etc void IRac::fujitsu(IRFujitsuAC *ac, const fujitsu_ac_remote_model_t model, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, @@ -570,6 +858,16 @@ void IRac::fujitsu(IRFujitsuAC *ac, const fujitsu_ac_remote_model_t model, #endif // SEND_FUJITSU_AC #if SEND_GOODWEATHER +/// Send a Goodweather A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRGoodweatherAc object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] light Turn on the LED/Display mode. +/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, >= 0 is on. void IRac::goodweather(IRGoodweatherAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, @@ -599,16 +897,29 @@ void IRac::goodweather(IRGoodweatherAc *ac, #endif // SEND_GOODWEATHER #if SEND_GREE +/// Send a Gree A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRGreeAC object to use. +/// @param[in] model The A/C model to use. +/// @param[in] on The power setting. +/// @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] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @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 +/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, >= 0 is on. void IRac::gree(IRGreeAC *ac, const gree_ac_remote_model_t model, - const bool on, const stdAc::opmode_t mode, const float degrees, - const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, - const bool turbo, const bool light, const bool clean, - const int16_t sleep) { + 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 turbo, + const bool light, const bool clean, const int16_t sleep) { ac->begin(); ac->setModel(model); ac->setPower(on); ac->setMode(ac->convertMode(mode)); - ac->setTemp(degrees); + ac->setTemp(degrees, !celsius); ac->setFan(ac->convertFan(fan)); ac->setSwingVertical(swingv == stdAc::swingv_t::kAuto, // Set auto flag. ac->convertSwingV(swingv)); @@ -627,6 +938,16 @@ void IRac::gree(IRGreeAC *ac, const gree_ac_remote_model_t model, #endif // SEND_GREE #if SEND_HAIER_AC +/// Send a Haier A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRGreeAC object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] filter Turn on the (ion/pollen/etc) filter mode. +/// @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::haier(IRHaierAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, @@ -654,6 +975,16 @@ void IRac::haier(IRHaierAC *ac, #endif // SEND_HAIER_AC #if SEND_HAIER_AC_YRW02 +/// Send a Haier YRWO2 A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRHaierACYRW02 object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] filter Turn on the (ion/pollen/etc) filter mode. +/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, >= 0 is on. void IRac::haierYrwo2(IRHaierACYRW02 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, @@ -678,6 +1009,14 @@ void IRac::haierYrwo2(IRHaierACYRW02 *ac, #endif // SEND_HAIER_AC_YRW02 #if SEND_HITACHI_AC +/// Send a Hitachi A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRHitachiAc object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] swingh The horizontal swing setting. void IRac::hitachi(IRHitachiAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, @@ -702,6 +1041,19 @@ void IRac::hitachi(IRHitachiAc *ac, #endif // SEND_HITACHI_AC #if SEND_HITACHI_AC1 +/// Send a Hitachi1 A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRHitachiAc1 object to use. +/// @param[in] model The A/C model to use. +/// @param[in] on The power setting. +/// @param[in] power_toggle The power toggle setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] swingh The horizontal swing setting. +/// @param[in] swing_toggle The swing_toggle setting. +/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, >= 0 is on. +/// @note The sleep mode used is the "Sleep 2" setting. void IRac::hitachi1(IRHitachiAc1 *ac, const hitachi_ac1_remote_model_t model, const bool on, const bool power_toggle, const stdAc::opmode_t mode, @@ -732,7 +1084,49 @@ void IRac::hitachi1(IRHitachiAc1 *ac, const hitachi_ac1_remote_model_t model, } #endif // SEND_HITACHI_AC1 +#if SEND_HITACHI_AC344 +/// Send a Hitachi 344-bit A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRHitachiAc344 object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] swingh The horizontal swing setting. +void IRac::hitachi344(IRHitachiAc344 *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) { + ac->begin(); + ac->setMode(ac->convertMode(mode)); + ac->setTemp(degrees); + ac->setFan(ac->convertFan(fan)); + ac->setSwingH(ac->convertSwingH(swingh)); + ac->setPower(on); + // No Quiet setting available. + // No Turbo setting available. + // No Light setting available. + // No Filter setting available. + // No Clean setting available. + // No Beep setting available. + // No Sleep setting available. + // No Clock setting available. + + // SwingVToggle is special. Needs to be last method called. + ac->setSwingVToggle(swingv != stdAc::swingv_t::kOff); + ac->send(); +} +#endif // SEND_HITACHI_AC344 + #if SEND_HITACHI_AC424 +/// Send a Hitachi 424-bit A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRHitachiAc424 object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. void IRac::hitachi424(IRHitachiAc424 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, @@ -758,6 +1152,19 @@ void IRac::hitachi424(IRHitachiAc424 *ac, #endif // SEND_HITACHI_AC424 #if SEND_KELVINATOR +/// Send a Kelvinator A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRKelvinatorAC object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] swingh The horizontal swing setting. +/// @param[in] quiet Run the device in quiet/silent mode. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] light Turn on the LED/Display mode. +/// @param[in] filter Turn on the (ion/pollen/etc) filter mode. +/// @param[in] clean Turn on the self-cleaning mode. e.g. XFan, dry filters etc void IRac::kelvinator(IRKelvinatorAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, @@ -785,6 +1192,13 @@ void IRac::kelvinator(IRKelvinatorAC *ac, #endif // SEND_KELVINATOR #if SEND_LG +/// Send a LG A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRLgAc object to use. +/// @param[in] model The A/C model to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. void IRac::lg(IRLgAc *ac, const lg_ac_remote_model_t model, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan) { @@ -809,6 +1223,15 @@ void IRac::lg(IRLgAc *ac, const lg_ac_remote_model_t model, #endif // SEND_LG #if SEND_MIDEA +/// Send a Midea A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRMideaAC object to use. +/// @param[in] on The power setting. +/// @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] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, >= 0 is on. void IRac::midea(IRMideaAC *ac, const bool on, const stdAc::opmode_t mode, const bool celsius, const float degrees, const stdAc::fanspeed_t fan, @@ -834,6 +1257,17 @@ void IRac::midea(IRMideaAC *ac, #endif // SEND_MIDEA #if SEND_MITSUBISHI_AC +/// Send a Mitsubishi A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRMitsubishiAC object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] swingh The horizontal swing setting. +/// @param[in] quiet Run the device in quiet/silent mode. +/// @param[in] clock The time in Nr. of mins since midnight. < 0 is ignore. +/// @note Clock can only be set in 10 minute increments. i.e. % 10. void IRac::mitsubishi(IRMitsubishiAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, @@ -860,6 +1294,15 @@ void IRac::mitsubishi(IRMitsubishiAC *ac, #endif // SEND_MITSUBISHI_AC #if SEND_MITSUBISHI112 +/// Send a Mitsubishi 112-bit A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRMitsubishi112 object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] swingh The horizontal swing setting. +/// @param[in] quiet Run the device in quiet/silent mode. void IRac::mitsubishi112(IRMitsubishi112 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, @@ -888,6 +1331,14 @@ void IRac::mitsubishi112(IRMitsubishi112 *ac, #endif // SEND_MITSUBISHI112 #if SEND_MITSUBISHI136 +/// Send a Mitsubishi 136-bit A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRMitsubishi136 object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] quiet Run the device in quiet/silent mode. void IRac::mitsubishi136(IRMitsubishi136 *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, @@ -912,6 +1363,17 @@ void IRac::mitsubishi136(IRMitsubishi136 *ac, #endif // SEND_MITSUBISHI136 #if SEND_MITSUBISHIHEAVY +/// Send a Mitsubishi Heavy 88-bit A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRMitsubishiHeavy88Ac object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] swingh The horizontal swing setting. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] econo Run the device in economical mode. +/// @param[in] clean Turn on the self-cleaning mode. e.g. Mould, dry filters etc void IRac::mitsubishiHeavy88(IRMitsubishiHeavy88Ac *ac, const bool on, const stdAc::opmode_t mode, const float degrees, @@ -939,6 +1401,20 @@ void IRac::mitsubishiHeavy88(IRMitsubishiHeavy88Ac *ac, ac->send(); } +/// Send a Mitsubishi Heavy 152-bit A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRMitsubishiHeavy152Ac object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] swingh The horizontal swing setting. +/// @param[in] quiet Run the device in quiet/silent mode. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] econo Run the device in economical mode. +/// @param[in] filter Turn on the (ion/pollen/etc) filter mode. +/// @param[in] clean Turn on the self-cleaning mode. e.g. Mould, dry filters etc +/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, > 0 is on. void IRac::mitsubishiHeavy152(IRMitsubishiHeavy152Ac *ac, const bool on, const stdAc::opmode_t mode, const float degrees, @@ -969,6 +1445,18 @@ void IRac::mitsubishiHeavy152(IRMitsubishiHeavy152Ac *ac, #endif // SEND_MITSUBISHIHEAVY #if SEND_NEOCLIMA +/// Send a Neoclima A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRNeoclimaAc object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] swingh The horizontal swing setting. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] light Turn on the LED/Display mode. +/// @param[in] filter Turn on the (ion/pollen/etc) filter mode. +/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, > 0 is on. void IRac::neoclima(IRNeoclimaAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, @@ -996,6 +1484,19 @@ void IRac::neoclima(IRNeoclimaAc *ac, #endif // SEND_NEOCLIMA #if SEND_PANASONIC_AC +/// Send a Panasonic A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRPanasonicAc object to use. +/// @param[in] model The A/C model to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] swingh The horizontal swing setting. +/// @param[in] quiet Run the device in quiet/silent mode. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] filter Turn on the (ion/pollen/etc) filter mode. +/// @param[in] clock The time in Nr. of mins since midnight. < 0 is ignore. void IRac::panasonic(IRPanasonicAc *ac, const panasonic_ac_remote_model_t model, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, @@ -1024,6 +1525,22 @@ void IRac::panasonic(IRPanasonicAc *ac, const panasonic_ac_remote_model_t model, #endif // SEND_PANASONIC_AC #if SEND_SAMSUNG_AC +/// Send a Samsung A/C message with the supplied settings. +/// @note Multiple IR messages may be generated & sent. +/// @param[in, out] ac A Ptr to an IRSamsungAc object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] quiet Run the device in quiet/silent mode. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] light Turn on the LED/Display mode. +/// @param[in] filter Turn on the (ion/pollen/etc) filter mode. +/// @param[in] clean Turn on the self-cleaning mode. e.g. Mould, dry filters etc +/// @param[in] beep Enable/Disable beeps when receiving IR messages. +/// @param[in] prevpower The power setting from the previous A/C state. +/// @param[in] forcepower Do we force send the special power message? void IRac::samsung(IRSamsungAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, @@ -1056,33 +1573,70 @@ void IRac::samsung(IRSamsungAc *ac, #endif // SEND_SAMSUNG_AC #if SEND_SHARP_AC +/// Send a Sharp A/C message with the supplied settings. +/// @note Multiple IR messages may be generated & sent. +/// @param[in, out] ac A Ptr to an IRSharpAc object to use. +/// @param[in] on The power setting. +/// @param[in] prev_power The power setting from the previous A/C state. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] filter Turn on the (ion/pollen/etc) filter mode. +/// @param[in] clean Turn on the self-cleaning mode. e.g. Mould, dry filters etc void IRac::sharp(IRSharpAc *ac, const bool on, const bool prev_power, const stdAc::opmode_t mode, - const float degrees, const stdAc::fanspeed_t fan) { + const float degrees, const stdAc::fanspeed_t fan, + const stdAc::swingv_t swingv, const bool turbo, + const bool filter, const bool clean) { ac->begin(); ac->setPower(on, prev_power); ac->setMode(ac->convertMode(mode)); ac->setTemp(degrees); ac->setFan(ac->convertFan(fan)); - // No Vertical swing setting available. + ac->setSwingToggle(swingv != stdAc::swingv_t::kOff); + // Econo deliberately not used as it cycles through 3 modes uncontrolably. + // ac->setEconoToggle(econo); + ac->setIon(filter); // No Horizontal swing setting available. // No Quiet setting available. - // No Turbo setting available. // No Light setting available. - // No Econo setting available. - // No Filter setting available. - // No Clean setting available. // No Beep setting available. // No Sleep setting available. // No Clock setting available. // Do setMode() again as it can affect fan speed and temp. ac->setMode(ac->convertMode(mode)); + // Clean after mode, as it can affect the mode, temp & fan speed. + if (clean) { + // A/C needs to be off before we can enter clean mode. + ac->setPower(false, prev_power); + ac->send(); + } + ac->setClean(clean); + if (turbo) { + ac->send(); // Send the current state. + // Set up turbo mode as it needs to be sent after everything else. + ac->setTurbo(true); + } ac->send(); } #endif // SEND_SHARP_AC #if SEND_TCL112AC +/// Send a TCL 112-bit A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRTcl112Ac object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] swingh The horizontal swing setting. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] light Turn on the LED/Display mode. +/// @param[in] econo Run the device in economical mode. +/// @param[in] filter Turn on the (ion/pollen/etc) filter mode. void IRac::tcl112(IRTcl112Ac *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, @@ -1110,6 +1664,15 @@ void IRac::tcl112(IRTcl112Ac *ac, #endif // SEND_TCL112AC #if SEND_TECO +/// Send a Teco A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRTecoAc object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] light Turn on the LED/Display mode. +/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, > 0 is on. void IRac::teco(IRTecoAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, @@ -1134,6 +1697,12 @@ void IRac::teco(IRTecoAc *ac, #endif // SEND_TECO #if SEND_TOSHIBA_AC +/// Send a Toshiba A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRToshibaAC object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. void IRac::toshiba(IRToshibaAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan) { @@ -1157,6 +1726,13 @@ void IRac::toshiba(IRToshibaAC *ac, #endif // SEND_TOSHIBA_AC #if SEND_TROTEC +/// Send a Trotec A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRTrotecESP object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, > 0 is on. void IRac::trotec(IRTrotecESP *ac, const bool on, const stdAc::opmode_t mode, const float degrees, const stdAc::fanspeed_t fan, @@ -1181,6 +1757,19 @@ void IRac::trotec(IRTrotecESP *ac, #endif // SEND_TROTEC #if SEND_VESTEL_AC +/// Send a Vestel A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRVestelAc object to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] filter Turn on the (ion/pollen/etc) filter mode. +/// @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. +/// @param[in] sendNormal Do we send a Normal settings message at all? +/// i.e In addition to the clock/time/timer message void IRac::vestel(IRVestelAc *ac, const bool on, const stdAc::opmode_t mode, const float degrees, @@ -1210,6 +1799,18 @@ void IRac::vestel(IRVestelAc *ac, #endif // SEND_VESTEL_AC #if SEND_WHIRLPOOL_AC +/// Send a Whirlpool A/C message with the supplied settings. +/// @param[in, out] ac A Ptr to an IRWhirlpoolAc object to use. +/// @param[in] model The A/C model to use. +/// @param[in] on The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] fan The speed setting for the fan. +/// @param[in] swingv The vertical swing setting. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] light Turn on the LED/Display mode. +/// @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::whirlpool(IRWhirlpoolAc *ac, const whirlpool_ac_remote_model_t model, const bool on, const stdAc::opmode_t mode, const float degrees, @@ -1236,12 +1837,11 @@ void IRac::whirlpool(IRWhirlpoolAc *ac, const whirlpool_ac_remote_model_t model, } #endif // SEND_WHIRLPOOL_AC -// Create a new state base on the provided state that has been suitably fixed. -// Args: -// state: The state_t structure describing the desired a/c state. -// -// Returns: -// A stdAc::state_t with the needed settings. +/// Create a new state base on the provided state that has been suitably fixed. +/// @note This is for use with Home Assistant, which requires mode to be off if +/// the power is off. +/// @param[in] state The state_t structure describing the desired a/c state. +/// @return A stdAc::state_t with the needed settings. stdAc::state_t IRac::cleanState(const stdAc::state_t state) { stdAc::state_t result = state; // A hack for Home Assistant, it appears to need/want an Off opmode. @@ -1250,14 +1850,11 @@ stdAc::state_t IRac::cleanState(const stdAc::state_t state) { return result; } -// Create a new state base on desired & previous states but handle -// any state changes for options that need to be toggled. -// Args: -// desired: The state_t structure describing the desired a/c state. -// prev: Ptr to the previous state_t structure. -// -// Returns: -// A stdAc::state_t with the needed settings. +/// Create a new state base on desired & previous states but handle +/// any state changes for options that need to be toggled. +/// @param[in] desired The state_t structure describing the desired a/c state. +/// @param[in] prev A Ptr to the previous state_t structure. +/// @return A stdAc::state_t with the needed settings. stdAc::state_t IRac::handleToggles(const stdAc::state_t desired, const stdAc::state_t *prev) { stdAc::state_t result = desired; @@ -1284,8 +1881,11 @@ stdAc::state_t IRac::handleToggles(const stdAc::state_t desired, case decode_type_t::ELECTRA_AC: result.light = desired.light ^ prev->light; break; - case decode_type_t::MIDEA: + case decode_type_t::CORONA_AC: + case decode_type_t::HITACHI_AC344: case decode_type_t::HITACHI_AC424: + case decode_type_t::MIDEA: + case decode_type_t::SHARP_AC: if ((desired.swingv == stdAc::swingv_t::kOff) ^ (prev->swingv == stdAc::swingv_t::kOff)) // It changed, so toggle. result.swingv = stdAc::swingv_t::kAuto; @@ -1308,29 +1908,30 @@ stdAc::state_t IRac::handleToggles(const stdAc::state_t desired, return result; } -// Send A/C message for a given device using common A/C settings. -// Args: -// vendor: The type of A/C protocol to use. -// model: The specific model of A/C if supported/applicable. -// on: Should the unit be powered on? (or in some cases, toggled) -// mode: What operating mode should the unit perform? e.g. Cool, Heat etc. -// degrees: What temperature should the unit be set to? -// celsius: Use degrees Celsius, otherwise Fahrenheit. -// fan: Fan speed. -// The following args are all "if supported" by the underlying A/C classes. -// swingv: Control the vertical swing of the vanes. -// swingh: Control the horizontal swing of the vanes. -// quiet: Set the unit to quiet (fan) operation mode. -// turbo: Set the unit to turbo operating mode. e.g. Max fan & cooling etc. -// econo: Set the unit to economical operating mode. -// light: Turn on the display/LEDs etc. -// filter: Turn on any particle/ion/allergy filter etc. -// clean: Turn on any settings to reduce mold etc. (Not self-clean mode.) -// beep: Control if the unit beeps upon receiving commands. -// sleep: Nr. of mins of sleep mode, or use sleep mode. (< 0 means off.) -// clock: Nr. of mins past midnight to set the clock to. (< 0 means off.) -// Returns: -// boolean: True, if accepted/converted/attempted. False, if unsupported. +/// Send A/C message for a given device using common A/C settings. +/// @param[in] vendor The vendor/protocol type. +/// @param[in] model The A/C model if applicable. +/// @param[in] power The power setting. +/// @param[in] mode The operation mode setting. +/// @param[in] degrees The temperature setting in degrees. +/// @param[in] celsius Temperature units. True is Celsius, False is Fahrenheit. +/// @param[in] fan The speed setting for the fan. +/// @note The following are all "if supported" by the underlying A/C classes. +/// @param[in] swingv The vertical swing setting. +/// @param[in] swingh The horizontal swing setting. +/// @param[in] quiet Run the device in quiet/silent mode. +/// @param[in] turbo Run the device in turbo/powerful mode. +/// @param[in] econo Run the device in economical mode. +/// @param[in] light Turn on the LED/Display mode. +/// @param[in] filter Turn on the (ion/pollen/etc) filter mode. +/// @param[in] clean Turn on the self-cleaning mode. e.g. Mould, dry filters etc +/// @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. Some devices it is the nr. of mins to run for. +/// Others it may be the time to enter/exit sleep mode. +/// i.e. Time in Nr. of mins since midnight. +/// @param[in] clock The time in Nr. of mins since midnight. < 0 is ignore. +/// @return True, if accepted/converted/attempted etc. False, if unsupported. bool IRac::sendAc(const decode_type_t vendor, const int16_t model, const bool power, const stdAc::opmode_t mode, const float degrees, const bool celsius, @@ -1346,17 +1947,14 @@ bool IRac::sendAc(const decode_type_t vendor, const int16_t model, return this->sendAc(to_send, &to_send); } -// Send A/C message for a given device using state_t structures. -// Args: -// desired: The state_t structure describing the desired new a/c state. -// prev: Ptr to the previous state_t structure. -// -// Returns: -// boolean: True, if accepted/converted/attempted. False, if unsupported. +/// Send A/C message for a given device using state_t structures. +/// @param[in] desired The state_t structure describing the desired new ac state +/// @param[in] prev A Ptr to the state_t structure containing the previous state +/// @return True, if accepted/converted/attempted etc. False, if unsupported. 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 = desired.celsius ? desired.degrees - : fahrenheitToCelsius(desired.degrees); + float degC __attribute__((unused)) = + desired.celsius ? desired.degrees : fahrenheitToCelsius(desired.degrees); // special `state_t` that is required to be sent based on that. stdAc::state_t send = this->handleToggles(this->cleanState(desired), prev); // Per vendor settings & setup. @@ -1378,6 +1976,15 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) { break; } #endif // SEND_ARGO +#if SEND_CARRIER_AC64 + case CARRIER_AC64: + { + IRCarrierAc64 ac(_pin, _inverted, _modulation); + carrier64(&ac, send.power, send.mode, degC, send.fanspeed, send.swingv, + send.sleep); + break; + } +#endif // SEND_CARRIER_AC64 #if SEND_COOLIX case COOLIX: { @@ -1387,6 +1994,15 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) { break; } #endif // SEND_COOLIX +#if SEND_CORONA_AC + case CORONA_AC: + { + IRCoronaAc ac(_pin, _inverted, _modulation); + corona(&ac, send.power, send.mode, degC, send.fanspeed, send.swingv, + send.econo); + break; + } +#endif // SEND_CORONA_AC #if SEND_DAIKIN case DAIKIN: { @@ -1459,6 +2075,15 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) { break; } #endif // SEND_DAIKIN64 +#if SEND_DELONGHI_AC + case DELONGHI_AC: + { + IRDelonghiAc ac(_pin, _inverted, _modulation); + delonghiac(&ac, send.power, send.mode, send.celsius, degC, send.fanspeed, + send.turbo, send.sleep); + break; + } +#endif // SEND_DELONGHI_AC #if SEND_ELECTRA_AC case ELECTRA_AC: { @@ -1493,9 +2118,9 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) { { IRGreeAC ac(_pin, (gree_ac_remote_model_t)send.model, _inverted, _modulation); - gree(&ac, (gree_ac_remote_model_t)send.model, send.power, send.mode, degC, - send.fanspeed, send.swingv, send.turbo, send.light, send.clean, - send.sleep); + gree(&ac, (gree_ac_remote_model_t)send.model, send.power, send.mode, + send.celsius, send.degrees, send.fanspeed, send.swingv, send.turbo, + send.light, send.clean, send.sleep); break; } #endif // SEND_GREE @@ -1543,6 +2168,15 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) { break; } #endif // SEND_HITACHI_AC1 +#if SEND_HITACHI_AC344 + case HITACHI_AC344: + { + IRHitachiAc344 ac(_pin, _inverted, _modulation); + hitachi344(&ac, send.power, send.mode, degC, send.fanspeed, + send.swingv, send.swingh); + break; + } +#endif // SEND_HITACHI_AC344 #if SEND_HITACHI_AC424 case HITACHI_AC424: { @@ -1660,7 +2294,8 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) { IRSharpAc ac(_pin, _inverted, _modulation); bool prev_power = !send.power; if (prev != NULL) prev_power = prev->power; - sharp(&ac, send.power, prev_power, send.mode, degC, send.fanspeed); + sharp(&ac, send.power, prev_power, send.mode, degC, send.fanspeed, + send.swingv, send.turbo, send.filter, send.clean); break; } #endif // SEND_SHARP_AC @@ -1723,24 +2358,24 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) { return true; // Success. } -// Update the previous state to the current one. +/// Update the previous state to the current one. void IRac::markAsSent(void) { _prev = next; } -// Send an A/C message based soley on our internal state. -// -// Returns: -// boolean: True, if accepted/converted/attempted. False, if unsupported. +/// Send an A/C message based soley on our internal state. +/// @return True, if accepted/converted/attempted. False, if unsupported. bool IRac::sendAc(void) { bool success = this->sendAc(next, &_prev); if (success) this->markAsSent(); return success; } -// Compare two AirCon states. -// Returns: True if they differ, False if they don't. -// Note: Excludes clock. +/// Compare two AirCon states. +/// @note The comparison excludes the clock. +/// @param a A state_t to be compared. +/// @param b A state_t to be compared. +/// @return True if they differ, False if they don't. bool IRac::cmpStates(const stdAc::state_t a, const stdAc::state_t b) { return a.protocol != b.protocol || a.model != b.model || a.power != b.power || a.mode != b.mode || a.degrees != b.degrees || a.celsius != b.celsius || @@ -1750,10 +2385,17 @@ bool IRac::cmpStates(const stdAc::state_t a, const stdAc::state_t b) { a.clean != b.clean || a.beep != b.beep || a.sleep != b.sleep; } +/// Check if the internal state has changed from what was previously sent. +/// @note The comparison excludes the clock. +/// @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 equivilent enum. stdAc::opmode_t IRac::strToOpmode(const char *str, - const stdAc::opmode_t def) { + const stdAc::opmode_t def) { if (!strcasecmp(str, kAutoStr) || !strcasecmp(str, kAutomaticStr)) return stdAc::opmode_t::kAuto; @@ -1778,6 +2420,10 @@ stdAc::opmode_t IRac::strToOpmode(const char *str, 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. +/// @return The equivilent enum. stdAc::fanspeed_t IRac::strToFanspeed(const char *str, const stdAc::fanspeed_t def) { if (!strcasecmp(str, kAutoStr) || @@ -1805,6 +2451,10 @@ stdAc::fanspeed_t IRac::strToFanspeed(const char *str, 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. +/// @return The equivilent enum. stdAc::swingv_t IRac::strToSwingV(const char *str, const stdAc::swingv_t def) { if (!strcasecmp(str, kAutoStr) || @@ -1842,6 +2492,10 @@ stdAc::swingv_t IRac::strToSwingV(const char *str, 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. +/// @return The equivilent enum. stdAc::swingh_t IRac::strToSwingH(const char *str, const stdAc::swingh_t def) { if (!strcasecmp(str, kAutoStr) || @@ -1877,7 +2531,11 @@ stdAc::swingh_t IRac::strToSwingH(const char *str, return def; } -// Assumes str is the model code or an integer >= 1. +/// Convert the supplied str into the appropriate enum. +/// @note Assumes str is the model code or an integer >= 1. +/// @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 equivilent enum. int16_t IRac::strToModel(const char *str, const int16_t def) { // Gree if (!strcasecmp(str, "YAW1F")) { @@ -1929,6 +2587,10 @@ int16_t IRac::strToModel(const char *str, const int16_t def) { } } +/// Convert the supplied str into the appropriate boolean value. +/// @param[in] str A Ptr to a C-style string to be converted. +/// @param[in] def The boolean value to return if no conversion was possible. +/// @return The equivilent boolean value. bool IRac::strToBool(const char *str, const bool def) { if (!strcasecmp(str, kOnStr) || !strcasecmp(str, "1") || @@ -1944,10 +2606,16 @@ bool IRac::strToBool(const char *str, const bool def) { return def; } +/// Convert the supplied boolean into the appropriate String. +/// @param[in] value The boolean value to be converted. +/// @return The equivilent String for the locale. String IRac::boolToString(const bool value) { return value ? kOnStr : kOffStr; } +/// Convert the supplied operation mode into the appropriate String. +/// @param[in] mode The enum to be converted. +/// @return The equivilent String for the locale. String IRac::opmodeToString(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kOff: @@ -1967,6 +2635,9 @@ String IRac::opmodeToString(const stdAc::opmode_t mode) { } } +/// Convert the supplied fan speed enum into the appropriate String. +/// @param[in] speed The enum to be converted. +/// @return The equivilent String for the locale. String IRac::fanspeedToString(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kAuto: @@ -1986,6 +2657,9 @@ String IRac::fanspeedToString(const stdAc::fanspeed_t speed) { } } +/// Convert the supplied enum into the appropriate String. +/// @param[in] swingv The enum to be converted. +/// @return The equivilent String for the locale. String IRac::swingvToString(const stdAc::swingv_t swingv) { switch (swingv) { case stdAc::swingv_t::kOff: @@ -2007,6 +2681,9 @@ String IRac::swingvToString(const stdAc::swingv_t swingv) { } } +/// Convert the supplied enum into the appropriate String. +/// @param[in] swingh The enum to be converted. +/// @return The equivilent String for the locale. String IRac::swinghToString(const stdAc::swingh_t swingh) { switch (swingh) { case stdAc::swingh_t::kOff: @@ -2031,11 +2708,11 @@ String IRac::swinghToString(const stdAc::swingh_t swingh) { } namespace IRAcUtils { - // Display the human readable state of an A/C message if we can. - // Args: - // result: A Ptr to the captured `decode_results` that contains an A/C mesg. - // Returns: - // A string with the human description of the A/C message. "" if we can't. + /// Display the human readable state of an A/C message if we can. + /// @param[in] result A Ptr to the captured `decode_results` that contains an + /// A/C mesg. + /// @return A string with the human description of the A/C message. + /// An empty string if we can't. String resultAcToString(const decode_results * const result) { switch (result->decode_type) { #if DECODE_AMCOR @@ -2052,6 +2729,13 @@ namespace IRAcUtils { return ac.toString(); } #endif // DECODE_ARGO +#if DECODE_CARRIER_AC64 + case decode_type_t::CARRIER_AC64: { + IRCarrierAc64 ac(kGpioUnused); + ac.setRaw(result->value); // CARRIER_AC64 uses value instead of state. + return ac.toString(); + } +#endif // DECODE_CARRIER_AC64 #if DECODE_DAIKIN case decode_type_t::DAIKIN: { IRDaikinESP ac(0); @@ -2107,7 +2791,14 @@ namespace IRAcUtils { ac.setRaw(result->value); // Daikin64 uses value instead of state. return ac.toString(); } -#endif // DECODE_DAIKIN216 +#endif // DECODE_DAIKIN64 +#if DECODE_DELONGHI_AC + case decode_type_t::DELONGHI_AC: { + IRDelonghiAc ac(kGpioUnused); + ac.setRaw(result->value); // DelonghiAc uses value instead of state. + return ac.toString(); + } +#endif // DECODE_DELONGHI_AC #if DECODE_ELECTRA_AC case decode_type_t::ELECTRA_AC: { IRElectraAc ac(0); @@ -2240,6 +2931,13 @@ namespace IRAcUtils { return ac.toString(); } #endif // DECODE_COOLIX +#if DECODE_CORONA_AC + case decode_type_t::CORONA_AC: { + IRCoronaAc ac(kGpioUnused); + ac.setRaw(result->state, result->bits / 8); + return ac.toString(); + } +#endif // DECODE_CORONA_AC #if DECODE_PANASONIC_AC case decode_type_t::PANASONIC_AC: { if (result->bits > kPanasonicAcShortBits) { @@ -2264,6 +2962,13 @@ namespace IRAcUtils { return ac.toString(); } #endif // DECODE_HITACHI_AC1 +#if DECODE_HITACHI_AC344 + case decode_type_t::HITACHI_AC344: { + IRHitachiAc344 ac(kGpioUnused); + ac.setRaw(result->state); + return ac.toString(); + } +#endif // DECODE_HITACHI_AC344 #if DECODE_HITACHI_AC424 case decode_type_t::HITACHI_AC424: { IRHitachiAc424 ac(0); @@ -2319,17 +3024,20 @@ namespace IRAcUtils { } } - // Convert a valid IR A/C remote message that we understand enough into a - // Common A/C state. - // - // Args: - // decode: A PTR to a successful raw IR decode object. - // result: A PTR to a state structure to store the result in. - // prev: A PTR to a state structure which has the prev. state. (optional) - // Returns: - // A boolean indicating success or failure. + /// Convert a valid IR A/C remote message that we understand enough into a + /// Common A/C state. + /// @param[in] decode A PTR to a successful raw IR decode object. + /// @param[in] result A PTR to a state structure to store the result in. + /// @param[in] prev A PTR to a state structure which has the prev. state. + /// @return A boolean indicating success or failure. bool decodeToState(const decode_results *decode, stdAc::state_t *result, - const stdAc::state_t *prev) { + const stdAc::state_t *prev +/// @cond IGNORE +// *prev flagged as "unused" due to potential compiler warning when some +// protocols that use it are disabled. It really is used. + __attribute__((unused)) +/// @endcond + ) { if (decode == NULL || result == NULL) return false; // Safety check. switch (decode->decode_type) { #if DECODE_AMCOR @@ -2356,6 +3064,22 @@ namespace IRAcUtils { break; } #endif // DECODE_COOLIX +#if DECODE_CORONA_AC + case decode_type_t::CORONA_AC: { + IRCoronaAc ac(kGpioUnused); + ac.setRaw(decode->state, decode->bits / 8); + *result = ac.toCommon(); + break; + } +#endif // DECODE_CARRIER_AC64 +#if DECODE_CARRIER_AC64 + case decode_type_t::CARRIER_AC64: { + IRCarrierAc64 ac(kGpioUnused); + ac.setRaw(decode->value); // Uses value instead of state. + *result = ac.toCommon(); + break; + } +#endif // DECODE_CARRIER_AC64 #if DECODE_DAIKIN case decode_type_t::DAIKIN: { IRDaikinESP ac(kGpioUnused); @@ -2420,6 +3144,14 @@ namespace IRAcUtils { break; } #endif // DECODE_DAIKIN64 +#if DECODE_DELONGHI_AC + case decode_type_t::DELONGHI_AC: { + IRDelonghiAc ac(kGpioUnused); + ac.setRaw(decode->value); // Uses value instead of state. + *result = ac.toCommon(); + break; + } +#endif // DECODE_DELONGHI_AC #if DECODE_ELECTRA_AC case decode_type_t::ELECTRA_AC: { IRElectraAc ac(kGpioUnused); @@ -2484,6 +3216,14 @@ namespace IRAcUtils { break; } #endif // DECODE_HITACHI_AC1 +#if DECODE_HITACHI_AC344 + case decode_type_t::HITACHI_AC344: { + IRHitachiAc344 ac(kGpioUnused); + ac.setRaw(decode->state); + *result = ac.toCommon(); + break; + } +#endif // DECODE_HITACHI_AC344 #if DECODE_HITACHI_AC424 case decode_type_t::HITACHI_AC424: { IRHitachiAc424 ac(kGpioUnused); diff --git a/lib/IRremoteESP8266-2.7.5/src/IRac.h b/lib/IRremoteESP8266-2.7.8/src/IRac.h similarity index 90% rename from lib/IRremoteESP8266-2.7.5/src/IRac.h rename to lib/IRremoteESP8266-2.7.8/src/IRac.h index 02faba36a..01365a180 100644 --- a/lib/IRremoteESP8266-2.7.5/src/IRac.h +++ b/lib/IRremoteESP8266-2.7.8/src/IRac.h @@ -9,8 +9,11 @@ #include "IRremoteESP8266.h" #include "ir_Amcor.h" #include "ir_Argo.h" +#include "ir_Carrier.h" #include "ir_Coolix.h" +#include "ir_Corona.h" #include "ir_Daikin.h" +#include "ir_Delonghi.h" #include "ir_Fujitsu.h" #include "ir_Electra.h" #include "ir_Goodweather.h" @@ -85,7 +88,7 @@ class IRac { stdAc::state_t getState(void); stdAc::state_t getStatePrev(void); bool hasStateChanged(void); - stdAc::state_t next; // The state we want the device to be in after we send. + stdAc::state_t next; ///< The state we want the device to be in after we send #ifndef UNIT_TEST private: @@ -105,6 +108,12 @@ class IRac { const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool turbo, const int16_t sleep = -1); #endif // SEND_ARGO +#if SEND_CARRIER_AC64 +void carrier64(IRCarrierAc64 *ac, + const bool on, const stdAc::opmode_t mode, + const float degrees, const stdAc::fanspeed_t fan, + const stdAc::swingv_t swingv, const int16_t sleep = -1); +#endif // SEND_CARRIER_AC64 #if SEND_COOLIX void coolix(IRCoolixAC *ac, const bool on, const stdAc::opmode_t mode, const float degrees, @@ -113,6 +122,12 @@ class IRac { 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, + const bool on, const stdAc::opmode_t mode, + const float degrees, const stdAc::fanspeed_t fan, + const stdAc::swingv_t swingv, const bool econo); +#endif // SEND_CORONA_AC #if SEND_DAIKIN void daikin(IRDaikinESP *ac, const bool on, const stdAc::opmode_t mode, const float degrees, @@ -174,6 +189,12 @@ void daikin216(IRDaikin216 *ac, const bool quiet, const bool turbo, const int16_t sleep = -1, const int16_t clock = -1); #endif // SEND_DAIKIN64 +#if SEND_DELONGHI_AC + void delonghiac(IRDelonghiAc *ac, + const bool on, const stdAc::opmode_t mode, const bool celsius, + const float degrees, const stdAc::fanspeed_t fan, + const bool turbo, const int16_t sleep = -1); +#endif // SEND_DELONGHI_AC #if SEND_ELECTRA_AC void electra(IRElectraAc *ac, const bool on, const stdAc::opmode_t mode, @@ -201,10 +222,10 @@ void electra(IRElectraAc *ac, #endif // SEND_GOODWEATHER #if SEND_GREE void gree(IRGreeAC *ac, const gree_ac_remote_model_t model, - const bool on, const stdAc::opmode_t mode, const float degrees, - const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, - const bool turbo, const bool light, const bool clean, - const int16_t sleep = -1); + const bool on, const stdAc::opmode_t mode, const bool celsius, + const float degrees, const stdAc::fanspeed_t fan, + const stdAc::swingv_t swingv, const bool turbo, const bool light, + const bool clean, const int16_t sleep = -1); #endif // SEND_GREE #if SEND_HAIER_AC void haier(IRHaierAC *ac, @@ -235,6 +256,13 @@ void electra(IRElectraAc *ac, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const bool swing_toggle, const int16_t sleep = -1); #endif // SEND_HITACHI_AC1 +#if SEND_HITACHI_AC344 + void hitachi344(IRHitachiAc344 *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); +#endif // SEND_HITACHI_AC344 #if SEND_HITACHI_AC424 void hitachi424(IRHitachiAc424 *ac, const bool on, const stdAc::opmode_t mode, @@ -325,7 +353,9 @@ void electra(IRElectraAc *ac, #if SEND_SHARP_AC void sharp(IRSharpAc *ac, const bool on, const bool prev_power, const stdAc::opmode_t mode, - const float degrees, const stdAc::fanspeed_t fan); + const float degrees, const stdAc::fanspeed_t fan, + const stdAc::swingv_t swingv, const bool turbo, const bool filter, + const bool clean); #endif // SEND_SHARP_AC #if SEND_TCL112AC void tcl112(IRTcl112Ac *ac, diff --git a/lib/IRremoteESP8266-2.7.5/src/IRrecv.cpp b/lib/IRremoteESP8266-2.7.8/src/IRrecv.cpp similarity index 56% rename from lib/IRremoteESP8266-2.7.5/src/IRrecv.cpp rename to lib/IRremoteESP8266-2.7.8/src/IRrecv.cpp index f59c1248c..efddcc17c 100644 --- a/lib/IRremoteESP8266-2.7.5/src/IRrecv.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/IRrecv.cpp @@ -62,11 +62,19 @@ irparams_t *irparams_save; // A copy of the interrupt state while decoding. #ifndef UNIT_TEST #if defined(ESP8266) +/// Interrupt handler for when the timer runs out. +/// It signals to the library that capturing of IR data has stopped. +/// @param[in] arg Unused. (ESP8266 Only) static void USE_IRAM_ATTR read_timeout(void *arg __attribute__((unused))) { os_intr_lock(); #endif // ESP8266 +/// @cond IGNORE #if defined(ESP32) +/// Interrupt handler for when the timer runs out. +/// It signals to the library that capturing of IR data has stopped. +/// @note ESP32 version static void USE_IRAM_ATTR read_timeout(void) { +/// @endcond portENTER_CRITICAL(&irremote_mux); #endif // ESP32 if (irparams.rawlen) irparams.rcvstate = kStopState; @@ -78,6 +86,7 @@ static void USE_IRAM_ATTR read_timeout(void) { #endif // ESP32 } +/// Interrupt handler for changes on the GPIO pin handling incoming IR messages. static void USE_IRAM_ATTR gpio_intr() { uint32_t now = micros(); static uint32_t start = 0; @@ -128,17 +137,17 @@ static void USE_IRAM_ATTR gpio_intr() { // Start of IRrecv class ------------------- -// Class constructor -// Args: -// recvpin: GPIO pin the IR receiver module's data pin is connected to. -// bufsize: Nr. of entries to have in the capture buffer. (Default: kRawBuf) -// timeout: Nr. of milli-Seconds of no signal before we stop capturing data. -// (Default: kTimeoutMs) -// save_buffer: Use a second (save) buffer to decode from. (Default: false) -// timer_num: Which ESP32 timer number to use? ESP32 only, otherwise unused. -// (Range: 0-3. Default: kDefaultESP32Timer) -// Returns: -// An IRrecv class object. +/// Class constructor +/// Args: +/// @param[in] recvpin The GPIO pin the IR receiver module's data pin is +/// connected to. +/// @param[in] bufsize Nr. of entries to have in the capture buffer. +/// (Default: kRawBuf) +/// @param[in] timeout Nr. of milli-Seconds of no signal before we stop +/// capturing data. (Default: kTimeoutMs) +/// @param[in] save_buffer Use a second (save) buffer to decode from. +/// (Default: false) +/// @param[in] timer_num Nr. of the ESP32 timer to use (0 to 3) (ESP32 Only) #if defined(ESP32) IRrecv::IRrecv(const uint16_t recvpin, const uint16_t bufsize, const uint8_t timeout, const bool save_buffer, @@ -146,8 +155,20 @@ IRrecv::IRrecv(const uint16_t recvpin, const uint16_t bufsize, // There are only 4 timers. 0 to 3. _timer_num = std::min(timer_num, (uint8_t)3); #else // ESP32 +/// @cond IGNORE +/// Class constructor +/// Args: +/// @param[in] recvpin The GPIO pin the IR receiver module's data pin is +/// connected to. +/// @param[in] bufsize Nr. of entries to have in the capture buffer. +/// (Default: kRawBuf) +/// @param[in] timeout Nr. of milli-Seconds of no signal before we stop +/// capturing data. (Default: kTimeoutMs) +/// @param[in] save_buffer Use a second (save) buffer to decode from. +/// (Default: false) IRrecv::IRrecv(const uint16_t recvpin, const uint16_t bufsize, const uint8_t timeout, const bool save_buffer) { +/// @endcond #endif // ESP32 irparams.recvpin = recvpin; irparams.bufsize = bufsize; @@ -185,24 +206,25 @@ IRrecv::IRrecv(const uint16_t recvpin, const uint16_t bufsize, _tolerance = kTolerance; } -// Class destructor +/// Class destructor +/// Cleans up after the object is no longer needed. +/// e.g. Frees up all memory used by the various buffers, and disables any +/// timers or interrupts used. IRrecv::~IRrecv(void) { + disableIRIn(); +#if defined(ESP32) + if (timer != NULL) timerEnd(timer); // Cleanup the ESP32 timeout timer. +#endif // ESP32 delete[] irparams.rawbuf; if (irparams_save != NULL) { delete[] irparams_save->rawbuf; delete irparams_save; } - disableIRIn(); -#if defined(ESP32) - if (timer != NULL) timerEnd(timer); // Cleanup the ESP32 timeout timer. -#endif // ESP32 } -// Set up and (re)start the IR capture mechanism. -// -// Args: -// pullup: A flag indicating should the GPIO use the internal pullup resistor. -// (Default: `false`. i.e. No.) +/// Set up and (re)start the IR capture mechanism. +/// @param[in] pullup A flag indicating should the GPIO use the internal pullup +/// resistor. (Default: `false`. i.e. No.) void IRrecv::enableIRIn(const bool pullup) { // ESP32's seem to require explicitly setting the GPIO to INPUT etc. // This wasn't required on the ESP8266s, but it shouldn't hurt to make sure. @@ -237,6 +259,8 @@ void IRrecv::enableIRIn(const bool pullup) { #endif // UNIT_TEST } +/// Stop collection of any received IR data. +/// Disable any timers and interrupts. void IRrecv::disableIRIn(void) { #ifndef UNIT_TEST #if defined(ESP8266) @@ -249,6 +273,10 @@ void IRrecv::disableIRIn(void) { #endif // UNIT_TEST } +/// Resume collection of received IR data. +/// @note This is required if `decode()` is successful and `save_buffer` was +/// not set when the class was instanciated. +/// @see IRrecv class constructor void IRrecv::resume(void) { irparams.rcvstate = kIdleState; irparams.rawlen = 0; @@ -258,14 +286,12 @@ void IRrecv::resume(void) { #endif // ESP32 } -// Make a copy of the interrupt state & buffer data. -// Needed because irparams is marked as volatile, thus memcpy() isn't allowed. -// Only call this when you know the interrupt handlers won't modify anything. -// i.e. In kStopState. -// -// Args: -// src: Pointer to an irparams_t structure to copy from. -// dst: Pointer to an irparams_t structure to copy to. +/// Make a copy of the interrupt state & buffer data. +/// Needed because irparams is marked as volatile, thus memcpy() isn't allowed. +/// Only call this when you know the interrupt handlers won't modify anything. +/// i.e. In kStopState. +/// @param[in] src Pointer to an irparams_t structure to copy from. +/// @param[out] dst Pointer to an irparams_t structure to copy to. void IRrecv::copyIrParams(volatile irparams_t *src, irparams_t *dst) { // Typecast src and dst addresses to (char *) char *csrc = (char *)src; // NOLINT(readability/casting) @@ -287,31 +313,35 @@ void IRrecv::copyIrParams(volatile irparams_t *src, irparams_t *dst) { for (uint16_t i = 0; i < dst->bufsize; i++) dst->rawbuf[i] = src->rawbuf[i]; } -// Obtain the maximum number of entries possible in the capture buffer. -// i.e. It's size. +/// Obtain the maximum number of entries possible in the capture buffer. +/// i.e. It's size. +/// @return The size of the buffer that is in use by the object. uint16_t IRrecv::getBufSize(void) { return irparams.bufsize; } #if DECODE_HASH -// Set the minimum length we will consider for reporting UNKNOWN message types. +/// Set the minimum length we will consider for reporting UNKNOWN message types. +/// @param[in] length Min nr. of mark/space pulses required to be considered. void IRrecv::setUnknownThreshold(const uint16_t length) { _unknown_threshold = length; } #endif // DECODE_HASH -// Set the base tolerance percentage for matching incoming IR messages. +/// Set the base tolerance percentage for matching incoming IR messages. +/// @param[in] percent An integer percentage. (0-100) void IRrecv::setTolerance(const uint8_t percent) { _tolerance = std::min(percent, (uint8_t)100); } -// Get the base tolerance percentage for matching incoming IR messages. +/// Get the base tolerance percentage for matching incoming IR messages. +/// @return A integer percentage. uint8_t IRrecv::getTolerance(void) { return _tolerance; } #if ENABLE_NOISE_FILTER_OPTION -// Remove or merge pulses in the capture buffer that are too short. -// Args: -// results: Ptr to the decode_results we are going to filter/modify. -// floor: Only allow values in the buffer large than this. (in micro seconds) +/// Remove or merge pulses in the capture buffer that are too short. +/// @param[in,out] results Ptr to the decode_results we are going to filter. +/// @param[in] floor Only allow values in the buffer large than this. +/// (in microSeconds) void IRrecv::crudeNoiseFilter(decode_results *results, const uint16_t floor) { if (floor == 0) return; // Nothing to do. const uint16_t kTickFloor = floor / kRawTick; @@ -338,49 +368,44 @@ void IRrecv::crudeNoiseFilter(decode_results *results, const uint16_t floor) { } #endif // ENABLE_NOISE_FILTER_OPTION -// Decodes the received IR message. -// If the interrupt state is saved, we will immediately resume waiting -// for the next IR message to avoid missing messages. -// Note: There is a trade-off here. Saving the state means less time lost until -// we can receiving the next message vs. using more RAM. Choose appropriately. -// -// Args: -// results: A pointer to where the decoded IR message will be stored. -// save: A pointer to an irparams_t instance in which to save -// the interrupt's memory/state. NULL means don't save it. -// max_skip: Maximum Nr. of pulses at the begining of a capture we can skip -// when attempting to find a protocol we can successfully decode. -// This parameter can dramatically improve detection of protocols -// when there is light IR interference just before an incoming IR -// message, however, it comes at a steep performace price. -// CAUTION: Increasing this value will dramatically (linnearly) -// increase the cpu time & usage to decode protocols. -// e.g. 0 -> 1 will be a 2x increase in cpu usage/time. -// 0 -> 2 will be a 3x increase etc. -// If you are going to do this, consider disabling -// protocol decoding for protocols you are not expecting. -// (Default is 0. No skipping.) -// noise_floor: Pulses below this size (in usecs) will be removed or merged -// prior to any decoding. This is to try to remove noise/poor -// readings & slighly increase the chances of a successful -// decode but at the cost of data fidelity & integrity. -// (Defaults to 0 usecs. i.e. Don't filter; which is safe!) -// DANGER: **Here Be Dragons!** -// If you set the `filter_floor` value too high, it **WILL** -// break decoding of some protocols. You have been warned! -// **Any** non-zero value has the potential to **cook** the -// captured raw data. i.e. The data is going to lie to you. -// It may obscure hardware, circuit, & environment issues thus -// making it impossible to support you accurately or -// confidently. -// Values of <= 50 usecs will probably be safe. -// 51 - 100 usecs **might** be okay. -// 100 - 150 usecs is "Danger, Will Robinson!". -// 150 - 200 usecs expect broken protocols. -// At 200+ usecs, you **have** protocols you can't decode!! -// -// Returns: -// A boolean indicating if an IR message is ready or not. +/// Decodes the received IR message. +/// If the interrupt state is saved, we will immediately resume waiting +/// for the next IR message to avoid missing messages. +/// @note There is a trade-off here. Saving the state means less time lost until +/// we can receiving the next message vs. using more RAM. Choose appropriately. +/// @param[out] results A PTR to where the decoded IR message will be stored. +/// @param[out] save A PTR to an irparams_t instance in which to save +/// the interrupt's memory/state. NULL means don't save it. +/// @param[in] max_skip Maximum Nr. of pulses at the begining of a capture we +/// can skip when attempting to find a protocol we can successfully decode. +/// This parameter can dramatically improve detection of protocols +/// when there is light IR interference just before an incoming IR +/// message, however, it comes at a steep performace price. +/// (Default is 0. No skipping.) +/// @warning Increasing the `max_skip` value will dramatically (linearly) +/// increase the cpu time & usage to decode protocols. +/// e.g. 0 -> 1 will be a 2x increase in cpu usage/time. +/// 0 -> 2 will be a 3x increase etc. +/// If you are going to do this, consider disabling protocol decoding for +/// protocols you are not expecting. +/// @param[in] noise_floor Pulses below this size (in usecs) will be removed or +/// merged prior to any decoding. This is to try to remove noise/poor +/// readings & slighly increase the chances of a successful decode but at the +/// cost of data fidelity & integrity. +/// (Defaults to 0 usecs. i.e. Don't filter; which is safe!) +/// @warning DANGER: **Here Be Dragons!** +/// If you set the `noise_floor` value too high, it **WILL** break decoding +/// of some protocols. You have been warned! +/// **Any** non-zero value has the potential to **cook** the captured raw data +/// i.e. The raw data is going to lie to you. +/// It may obscure hardware, circuit, & environment issues thus making it +/// impossible to support you accurately or confidently. +/// Values of <= 50 usecs will probably be safe. +/// 51 - 100 usecs **might** be okay. +/// 100 - 150 usecs is "Danger, Will Robinson!". +/// 150 - 200 usecs expect broken protocols. +/// At 200+ usecs, you **have** protocols you can't decode!! +/// @return A boolean indicating if an IR message is ready or not. bool IRrecv::decode(decode_results *results, irparams_t *save, uint8_t max_skip, uint16_t noise_floor) { // Proceed only if an IR message been received. @@ -663,6 +688,12 @@ bool IRrecv::decode(decode_results *results, irparams_t *save, decodeHitachiAc3(results, offset, kHitachiAc3MinBits)) return true; #endif // DECODE_HITACHI_AC3 +#if DECODE_HITACHI_AC344 + // HitachiAC344 should be checked before HitachiAC + DPRINTLN("Attempting Hitachi AC344 decode"); + if (decodeHitachiAC(results, offset, kHitachiAc344Bits, true, false)) + return true; +#endif // DECODE_HITACHI_AC344 #if DECODE_HITACHI_AC2 // HitachiAC2 should be checked before HitachiAC DPRINTLN("Attempting Hitachi AC2 decode"); @@ -789,6 +820,38 @@ bool IRrecv::decode(decode_results *results, irparams_t *save, DPRINTLN("Attempting Airwell decode"); if (decodeAirwell(results, offset)) return true; #endif // DECODE_AIRWELL +#if DECODE_DELONGHI_AC + DPRINTLN("Attempting Delonghi AC decode"); + if (decodeDelonghiAc(results, offset)) return true; +#endif // DECODE_DELONGHI_AC +#if DECODE_DOSHISHA + DPRINTLN("Attempting Doshisha decode"); + if (decodeDoshisha(results, offset)) return true; +#endif // DECODE_DOSHISHA +#if DECODE_MULTIBRACKETS + DPRINTLN("Attempting Multibrackets decode"); + if (decodeMultibrackets(results, offset)) return true; +#endif // DECODE_MULTIBRACKETS +#if DECODE_CARRIER_AC40 + DPRINTLN("Attempting Carrier 40bit decode"); + if (decodeCarrierAC40(results, offset)) return true; +#endif // DECODE_CARRIER_AC40 +#if DECODE_CARRIER_AC64 + DPRINTLN("Attempting Carrier 64bit decode"); + if (decodeCarrierAC64(results, offset)) return true; +#endif // DECODE_CARRIER_AC64 +#if DECODE_CORONA_AC + DPRINTLN("Attempting CoronaAc decode"); + if (decodeCoronaAc(results, offset)) return true; +#endif // DECODE_CORONA_AC +#if DECODE_MIDEA24 + DPRINTLN("Attempting Midea-Nec decode"); + if (decodeMidea24(results, offset)) return true; +#endif // DECODE_MIDEA24 +#if DECODE_ZEPEAL + DPRINTLN("Attempting Zepeal decode"); + if (decodeZepeal(results, offset)) return true; +#endif // DECODE_ZEPEAL // Typically new protocols are added above this line. } #if DECODE_HASH @@ -805,19 +868,17 @@ bool IRrecv::decode(decode_results *results, irparams_t *save, return false; } -// Convert the tolerance percentage into something valid. +/// Convert the tolerance percentage into something valid. +/// @param[in] percentage An integer percentage. uint8_t IRrecv::_validTolerance(const uint8_t percentage) { return (percentage > 100) ? _tolerance : percentage; } -// Calculate the lower bound of the nr. of ticks. -// -// Args: -// usecs: Nr. of uSeconds. -// tolerance: Percent as an integer. e.g. 10 is 10% -// delta: A non-scaling amount to reduce usecs by. -// Returns: -// Nr. of ticks. +/// Calculate the lower bound of the nr. of ticks. +/// @param[in] usecs Nr. of uSeconds. +/// @param[in] tolerance Percent as an integer. e.g. 10 is 10% +/// @param[in] delta A non-scaling amount to reduce usecs by. +/// @return Nr. of ticks. uint32_t IRrecv::ticksLow(const uint32_t usecs, const uint8_t tolerance, const uint16_t delta) { // max() used to ensure the result can't drop below 0 before the cast. @@ -826,31 +887,24 @@ uint32_t IRrecv::ticksLow(const uint32_t usecs, const uint8_t tolerance, 0)); } -// Calculate the upper bound of the nr. of ticks. -// -// Args: -// usecs: Nr. of uSeconds. -// tolerance: Percent as an integer. e.g. 10 is 10% -// delta: A non-scaling amount to increase usecs by. -// Returns: -// Nr. of ticks. +/// Calculate the upper bound of the nr. of ticks. +/// @param[in] usecs Nr. of uSeconds. +/// @param[in] tolerance Percent as an integer. e.g. 10 is 10% +/// @param[in] delta A non-scaling amount to increase usecs by. +/// @return Nr. of ticks. uint32_t IRrecv::ticksHigh(const uint32_t usecs, const uint8_t tolerance, const uint16_t delta) { return ((uint32_t)(usecs * (1.0 + _validTolerance(tolerance) / 100.0)) + 1 + delta); } -// Check if we match a pulse(measured) with the desired within -// +/-tolerance percent and/or +/- a fixed delta range. -// -// Args: -// measured: The recorded period of the signal pulse. -// desired: The expected period (in useconds) we are matching against. -// tolerance: A percentage expressed as an integer. e.g. 10 is 10%. -// delta: A non-scaling (+/-) error margin (in useconds). -// -// Returns: -// Boolean: true if it matches, false if it doesn't. +/// Check if we match a pulse(measured) with the desired within +/// +/-tolerance percent and/or +/- a fixed delta range. +/// @param[in] measured The recorded period of the signal pulse. +/// @param[in] desired The expected period (in usecs) we are matching against. +/// @param[in] tolerance A percentage expressed as an integer. e.g. 10 is 10%. +/// @param[in] delta A non-scaling (+/-) error margin (in useconds). +/// @return A Boolean. true if it matches, false if it doesn't. bool IRrecv::match(uint32_t measured, uint32_t desired, uint8_t tolerance, uint16_t delta) { measured *= kRawTick; // Convert to uSecs. @@ -875,18 +929,13 @@ bool IRrecv::match(uint32_t measured, uint32_t desired, uint8_t tolerance, measured <= ticksHigh(desired, tolerance, delta)); } -// Check if we match a pulse(measured) of at least desired within -// tolerance percent and/or a fixed delta margin. -// -// Args: -// measured: The recorded period of the signal pulse. -// desired: The expected period (in useconds) we are matching against. -// tolerance: A percentage expressed as an integer. e.g. 10 is 10%. -// delta: A non-scaling amount to reduce usecs by. - -// -// Returns: -// Boolean: true if it matches, false if it doesn't. +/// Check if we match a pulse(measured) of at least desired within +/// tolerance percent and/or a fixed delta margin. +/// @param[in] measured The recorded period of the signal pulse. +/// @param[in] desired The expected period (in usecs) we are matching against. +/// @param[in] tolerance A percentage expressed as an integer. e.g. 10 is 10%. +/// @param[in] delta A non-scaling amount to reduce usecs by. +/// @return A Boolean. true if it matches, false if it doesn't. bool IRrecv::matchAtLeast(uint32_t measured, uint32_t desired, uint8_t tolerance, uint16_t delta) { measured *= kRawTick; // Convert to uSecs. @@ -922,17 +971,13 @@ bool IRrecv::matchAtLeast(uint32_t measured, uint32_t desired, tolerance, delta); } -// Check if we match a mark signal(measured) with the desired within -// +/-tolerance percent, after an expected is excess is added. -// -// Args: -// measured: The recorded period of the signal pulse. -// desired: The expected period (in useconds) we are matching against. -// tolerance: A percentage expressed as an integer. e.g. 10 is 10%. -// excess: Nr. of useconds. -// -// Returns: -// Boolean: true if it matches, false if it doesn't. +/// Check if we match a mark signal(measured) with the desired within +/// +/-tolerance percent, after an expected is excess is added. +/// @param[in] measured The recorded period of the signal pulse. +/// @param[in] desired The expected period (in usecs) we are matching against. +/// @param[in] tolerance A percentage expressed as an integer. e.g. 10 is 10%. +/// @param[in] excess A non-scaling amount to reduce usecs by. +/// @return A Boolean. true if it matches, false if it doesn't. bool IRrecv::matchMark(uint32_t measured, uint32_t desired, uint8_t tolerance, int16_t excess) { DPRINT("Matching MARK "); @@ -945,17 +990,13 @@ bool IRrecv::matchMark(uint32_t measured, uint32_t desired, uint8_t tolerance, return match(measured, desired + excess, tolerance); } -// Check if we match a space signal(measured) with the desired within -// +/-tolerance percent, after an expected is excess is removed. -// -// Args: -// measured: The recorded period of the signal pulse. -// desired: The expected period (in useconds) we are matching against. -// tolerance: A percentage expressed as an integer. e.g. 10 is 10%. -// excess: Nr. of useconds. -// -// Returns: -// Boolean: true if it matches, false if it doesn't. +/// Check if we match a space signal(measured) with the desired within +/// +/-tolerance percent, after an expected is excess is removed. +/// @param[in] measured The recorded period of the signal pulse. +/// @param[in] desired The expected period (in usecs) we are matching against. +/// @param[in] tolerance A percentage expressed as an integer. e.g. 10 is 10%. +/// @param[in] excess A non-scaling amount to reduce usecs by. +/// @return A Boolean. true if it matches, false if it doesn't. bool IRrecv::matchSpace(uint32_t measured, uint32_t desired, uint8_t tolerance, int16_t excess) { DPRINT("Matching SPACE "); @@ -968,23 +1009,12 @@ bool IRrecv::matchSpace(uint32_t measured, uint32_t desired, uint8_t tolerance, return match(measured, desired - excess, tolerance); } -/* ----------------------------------------------------------------------- - * hashdecode - decode an arbitrary IR code. - * Instead of decoding using a standard encoding scheme - * (e.g. Sony, NEC, RC5), the code is hashed to a 32-bit value. - * - * The algorithm: look at the sequence of MARK signals, and see if each one - * is shorter (0), the same length (1), or longer (2) than the previous. - * Do the same with the SPACE signals. Hash the resulting sequence of 0's, - * 1's, and 2's to a 32-bit value. This will give a unique value for each - * different code (probably), for most code systems. - * - * http://arcfn.com/2010/01/using-arbitrary-remotes-with-arduino.html - */ - -// Compare two tick values, returning 0 if newval is shorter, -// 1 if newval is equal, and 2 if newval is longer -// Use a tolerance of 20% +#if DECODE_HASH +/// Compare two tick values. +/// @param[in] oldval Nr. of ticks. +/// @param[in] newval Nr. of ticks. +/// @return 0 if newval is shorter, 1 if it is equal, & 2 if it is longer. +/// @note Use a tolerance of 20% uint16_t IRrecv::compare(const uint16_t oldval, const uint16_t newval) { if (newval < oldval * 0.8) return 0; @@ -994,11 +1024,18 @@ uint16_t IRrecv::compare(const uint16_t oldval, const uint16_t newval) { return 1; } -#if DECODE_HASH -/* Converts the raw code values into a 32-bit hash code. - * Hopefully this code is unique for each button. - * This isn't a "real" decoding, just an arbitrary value. - */ +/// Decode any arbitrary IR message into a 32-bit code value. +/// Instead of decoding using a standard encoding scheme +/// (e.g. Sony, NEC, RC5), the code is hashed to a 32-bit value. +/// +/// The algorithm: look at the sequence of MARK signals, and see if each one +/// is shorter (0), the same length (1), or longer (2) than the previous. +/// Do the same with the SPACE signals. Hash the resulting sequence of 0's, +/// 1's, and 2's to a 32-bit value. This will give a unique value for each +/// different code (probably), for most code systems. +/// @see http://arcfn.com/2010/01/using-arbitrary-remotes-with-arduino.html +/// @note This isn't a "real" decoding, just an arbitrary value. +/// Hopefully this code is unique for each button. bool IRrecv::decodeHash(decode_results *results) { // Require at least some samples to prevent triggering on noise if (results->rawlen < _unknown_threshold) return false; @@ -1021,23 +1058,21 @@ bool IRrecv::decodeHash(decode_results *results) { } #endif // DECODE_HASH -// Match & decode the typical data section of an IR message. -// The data value is stored in the least significant bits reguardless of the -// bit ordering requested. -// -// Args: -// data_ptr: A pointer to where we are at in the capture buffer. -// nbits: Nr. of data bits we expect. -// onemark: Nr. of uSeconds in an expected mark signal for a '1' bit. -// onespace: Nr. of uSeconds in an expected space signal for a '1' bit. -// zeromark: Nr. of uSeconds in an expected mark signal for a '0' bit. -// zerospace: Nr. of uSeconds in an expected space signal for a '0' bit. -// tolerance: Percentage error margin to allow. (Def: kUseDefTol) -// excess: Nr. of useconds. (Def: kMarkExcess) -// MSBfirst: Bit order to save the data in. (Def: true) -// Returns: -// A match_result_t structure containing the success (or not), the data value, -// and how many buffer entries were used. +/// Match & decode the typical data section of an IR message. +/// The data value is stored in the least significant bits reguardless of the +/// bit ordering requested. +/// @param[in] data_ptr A pointer to where we are at in the capture buffer. +/// @param[in] nbits Nr. of data bits we expect. +/// @param[in] onemark Nr. of uSeconds in an expected mark signal for a '1' bit. +/// @param[in] onespace Nr. of uSecs in an expected space signal for a '1' bit. +/// @param[in] zeromark Nr. of uSecs in an expected mark signal for a '0' bit. +/// @param[in] zerospace Nr. of uSecs in an expected space signal for a '0' bit. +/// @param[in] tolerance Percentage error margin to allow. (Default: kUseDefTol) +/// @param[in] excess Nr. of uSeconds. (Def: kMarkExcess) +/// @param[in] MSBfirst Bit order to save the data in. (Def: true) +/// true is Most Significant Bit First Order, false is Least Significant First +/// @return A match_result_t structure containing the success (or not), the +/// data value, and how many buffer entries were used. match_result_t IRrecv::matchData( volatile uint16_t *data_ptr, const uint16_t nbits, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, @@ -1064,24 +1099,22 @@ match_result_t IRrecv::matchData( return result; } -// Match & decode the typical data section of an IR message. -// The bytes are stored at result_ptr. The first byte in the result equates to -// the first byte encountered, and so on. -// -// Args: -// data_ptr: A pointer to where we are at in the capture buffer. -// result_ptr: A pointer to where to start storing the bytes we decoded. -// remaining: The size of the capture buffer are remaining. -// nbytes: Nr. of data bytes we expect. -// onemark: Nr. of uSeconds in an expected mark signal for a '1' bit. -// onespace: Nr. of uSeconds in an expected space signal for a '1' bit. -// zeromark: Nr. of uSeconds in an expected mark signal for a '0' bit. -// zerospace: Nr. of uSeconds in an expected space signal for a '0' bit. -// tolerance: Percentage error margin to allow. (Def: kUseDefTol) -// excess: Nr. of useconds. (Def: kMarkExcess) -// MSBfirst: Bit order to save the data in. (Def: true) -// Returns: -// A uint16_t: If successful, how many buffer entries were used. Otherwise 0. +/// Match & decode the typical data section of an IR message. +/// The bytes are stored at result_ptr. The first byte in the result equates to +/// the first byte encountered, and so on. +/// @param[in] data_ptr A pointer to where we are at in the capture buffer. +/// @param[out] result_ptr A ptr to where to start storing the bytes we decoded. +/// @param[in] remaining The size of the capture buffer remaining. +/// @param[in] nbytes Nr. of data bytes we expect. +/// @param[in] onemark Nr. of uSeconds in an expected mark signal for a '1' bit. +/// @param[in] onespace Nr. of uSecs in an expected space signal for a '1' bit. +/// @param[in] zeromark Nr. of uSecs in an expected mark signal for a '0' bit. +/// @param[in] zerospace Nr. of uSecs in an expected space signal for a '0' bit. +/// @param[in] tolerance Percentage error margin to allow. (Default: kUseDefTol) +/// @param[in] excess Nr. of uSeconds. (Def: kMarkExcess) +/// @param[in] MSBfirst Bit order to save the data in. (Def: true) +/// true is Most Significant Bit First Order, false is Least Significant First +/// @return If successful, how many buffer entries were used. Otherwise 0. uint16_t IRrecv::matchBytes(volatile uint16_t *data_ptr, uint8_t *result_ptr, const uint16_t remaining, const uint16_t nbytes, const uint16_t onemark, const uint32_t onespace, @@ -1102,33 +1135,36 @@ uint16_t IRrecv::matchBytes(volatile uint16_t *data_ptr, uint8_t *result_ptr, return offset; } -// Match & decode a generic/typical IR message. -// The data is stored in result_bits_ptr or result_bytes_ptr depending on flag -// `use_bits`. -// Values of 0 for hdrmark, hdrspace, footermark, or footerspace mean skip -// that requirement. -// -// Args: -// data_ptr: A pointer to where we are at in the capture buffer. -// result_bits_ptr: A pointer to where to start storing the bits we decoded. -// result_bytes_ptr: A pointer to where to start storing the bytes we decoded. -// use_bits: A flag indicating if we are to decode bits or bytes. -// remaining: The size of the capture buffer are remaining. -// nbits: Nr. of data bits we expect. -// hdrmark: Nr. of uSeconds for the expected header mark signal. -// hdrspace: Nr. of uSeconds for the expected header space signal. -// onemark: Nr. of uSeconds in an expected mark signal for a '1' bit. -// onespace: Nr. of uSeconds in an expected space signal for a '1' bit. -// zeromark: Nr. of uSeconds in an expected mark signal for a '0' bit. -// zerospace: Nr. of uSeconds in an expected space signal for a '0' bit. -// footermark: Nr. of uSeconds for the expected footer mark signal. -// footerspace: Nr. of uSeconds for the expected footer space/gap signal. -// atleast: Is the match on the footerspace a matchAtLeast or matchSpace? -// tolerance: Percentage error margin to allow. (Def: kUseDefTol) -// excess: Nr. of useconds. (Def: kMarkExcess) -// MSBfirst: Bit order to save the data in. (Def: true) -// Returns: -// A uint16_t: If successful, how many buffer entries were used. Otherwise 0. +/// Match & decode a generic/typical IR message. +/// The data is stored in result_bits_ptr or result_bytes_ptr depending on flag +/// `use_bits`. +/// @note Values of 0 for hdrmark, hdrspace, footermark, or footerspace mean +/// skip that requirement. +/// +/// @param[in] data_ptr A pointer to where we are at in the capture buffer. +/// @param[out] result_bits_ptr A pointer to where to start storing the bits we +/// decoded. +/// @param[out] result_bytes_ptr A pointer to where to start storing the bytes +/// we decoded. +/// @param[in] use_bits A flag indicating if we are to decode bits or bytes. +/// @param[in] remaining The size of the capture buffer remaining. +/// @param[in] nbits Nr. of data bits we expect. +/// @param[in] hdrmark Nr. of uSeconds for the expected header mark signal. +/// @param[in] hdrspace Nr. of uSeconds for the expected header space signal. +/// @param[in] onemark Nr. of uSeconds in an expected mark signal for a '1' bit. +/// @param[in] onespace Nr. of uSecs in an expected space signal for a '1' bit. +/// @param[in] zeromark Nr. of uSecs in an expected mark signal for a '0' bit. +/// @param[in] zerospace Nr. of uSecs in an expected space signal for a '0' bit. +/// @param[in] footermark Nr. of uSeconds for the expected footer mark signal. +/// @param[in] footerspace Nr. of uSeconds for the expected footer space/gap +/// signal. +/// @param[in] atleast Is the match on the footerspace a matchAtLeast or +/// matchSpace? +/// @param[in] tolerance Percentage error margin to allow. (Default: kUseDefTol) +/// @param[in] excess Nr. of uSeconds. (Def: kMarkExcess) +/// @param[in] MSBfirst Bit order to save the data in. (Def: true) +/// true is Most Significant Bit First Order, false is Least Significant First +/// @return If successful, how many buffer entries were used. Otherwise 0. uint16_t IRrecv::_matchGeneric(volatile uint16_t *data_ptr, uint64_t *result_bits_ptr, uint8_t *result_bytes_ptr, @@ -1204,30 +1240,31 @@ uint16_t IRrecv::_matchGeneric(volatile uint16_t *data_ptr, return offset; } -// Match & decode a generic/typical <= 64bit IR message. -// The data is stored at result_ptr. -// Values of 0 for hdrmark, hdrspace, footermark, or footerspace mean skip -// that requirement. -// -// Args: -// data_ptr: A pointer to where we are at in the capture buffer. -// result_ptr: A pointer to where to start storing the bits we decoded. -// remaining: The size of the capture buffer are remaining. -// nbits: Nr. of data bits we expect. -// hdrmark: Nr. of uSeconds for the expected header mark signal. -// hdrspace: Nr. of uSeconds for the expected header space signal. -// onemark: Nr. of uSeconds in an expected mark signal for a '1' bit. -// onespace: Nr. of uSeconds in an expected space signal for a '1' bit. -// zeromark: Nr. of uSeconds in an expected mark signal for a '0' bit. -// zerospace: Nr. of uSeconds in an expected space signal for a '0' bit. -// footermark: Nr. of uSeconds for the expected footer mark signal. -// footerspace: Nr. of uSeconds for the expected footer space/gap signal. -// atleast: Is the match on the footerspace a matchAtLeast or matchSpace? -// tolerance: Percentage error margin to allow. (Def: kUseDefTol) -// excess: Nr. of useconds. (Def: kMarkExcess) -// MSBfirst: Bit order to save the data in. (Def: true) -// Returns: -// A uint16_t: If successful, how many buffer entries were used. Otherwise 0. +/// Match & decode a generic/typical <= 64bit IR message. +/// The data is stored at result_ptr. +/// @note Values of 0 for hdrmark, hdrspace, footermark, or footerspace mean +/// skip that requirement. +/// +/// @param[in] data_ptr: A pointer to where we are at in the capture buffer. +/// @param[out] result_ptr A ptr to where to start storing the bits we decoded. +/// @param[in] remaining The size of the capture buffer remaining. +/// @param[in] nbits Nr. of data bits we expect. +/// @param[in] hdrmark Nr. of uSeconds for the expected header mark signal. +/// @param[in] hdrspace Nr. of uSeconds for the expected header space signal. +/// @param[in] onemark Nr. of uSeconds in an expected mark signal for a '1' bit. +/// @param[in] onespace Nr. of uSecs in an expected space signal for a '1' bit. +/// @param[in] zeromark Nr. of uSecs in an expected mark signal for a '0' bit. +/// @param[in] zerospace Nr. of uSecs in an expected space signal for a '0' bit. +/// @param[in] footermark Nr. of uSeconds for the expected footer mark signal. +/// @param[in] footerspace Nr. of uSeconds for the expected footer space/gap +/// signal. +/// @param[in] atleast Is the match on the footerspace a matchAtLeast or +/// matchSpace? +/// @param[in] tolerance Percentage error margin to allow. (Default: kUseDefTol) +/// @param[in] excess Nr. of uSeconds. (Def: kMarkExcess) +/// @param[in] MSBfirst Bit order to save the data in. (Def: true) +/// true is Most Significant Bit First Order, false is Least Significant First +/// @return If successful, how many buffer entries were used. Otherwise 0. uint16_t IRrecv::matchGeneric(volatile uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, @@ -1250,31 +1287,31 @@ uint16_t IRrecv::matchGeneric(volatile uint16_t *data_ptr, tolerance, excess, MSBfirst); } -// Match & decode a generic/typical > 64bit IR message. -// The bytes are stored at result_ptr. The first byte in the result equates to -// the first byte encountered, and so on. -// Values of 0 for hdrmark, hdrspace, footermark, or footerspace mean skip -// that requirement. -// -// Args: -// data_ptr: A pointer to where we are at in the capture buffer. -// result_ptr: A pointer to where to start storing the bytes we decoded. -// remaining: The size of the capture buffer are remaining. -// nbits: Nr. of data bits we expect. -// hdrmark: Nr. of uSeconds for the expected header mark signal. -// hdrspace: Nr. of uSeconds for the expected header space signal. -// onemark: Nr. of uSeconds in an expected mark signal for a '1' bit. -// onespace: Nr. of uSeconds in an expected space signal for a '1' bit. -// zeromark: Nr. of uSeconds in an expected mark signal for a '0' bit. -// zerospace: Nr. of uSeconds in an expected space signal for a '0' bit. -// footermark: Nr. of uSeconds for the expected footer mark signal. -// footerspace: Nr. of uSeconds for the expected footer space/gap signal. -// atleast: Is the match on the footerspace a matchAtLeast or matchSpace? -// tolerance: Percentage error margin to allow. (Def: kUseDefTol) -// excess: Nr. of useconds. (Def: kMarkExcess) -// MSBfirst: Bit order to save the data in. (Def: true) -// Returns: -// A uint16_t: If successful, how many buffer entries were used. Otherwise 0. +/// Match & decode a generic/typical > 64bit IR message. +/// The bytes are stored at result_ptr. The first byte in the result equates to +/// the first byte encountered, and so on. +/// @note Values of 0 for hdrmark, hdrspace, footermark, or footerspace mean +/// skip that requirement. +/// @param[in] data_ptr: A pointer to where we are at in the capture buffer. +/// @param[out] result_ptr A ptr to where to start storing the bytes we decoded. +/// @param[in] remaining The size of the capture buffer remaining. +/// @param[in] nbits Nr. of data bits we expect. +/// @param[in] hdrmark Nr. of uSeconds for the expected header mark signal. +/// @param[in] hdrspace Nr. of uSeconds for the expected header space signal. +/// @param[in] onemark Nr. of uSeconds in an expected mark signal for a '1' bit. +/// @param[in] onespace Nr. of uSecs in an expected space signal for a '1' bit. +/// @param[in] zeromark Nr. of uSecs in an expected mark signal for a '0' bit. +/// @param[in] zerospace Nr. of uSecs in an expected space signal for a '0' bit. +/// @param[in] footermark Nr. of uSeconds for the expected footer mark signal. +/// @param[in] footerspace Nr. of uSeconds for the expected footer space/gap +/// signal. +/// @param[in] atleast Is the match on the footerspace a matchAtLeast or +/// matchSpace? +/// @param[in] tolerance Percentage error margin to allow. (Default: kUseDefTol) +/// @param[in] excess Nr. of uSeconds. (Def: kMarkExcess) +/// @param[in] MSBfirst Bit order to save the data in. (Def: true) +/// true is Most Significant Bit First Order, false is Least Significant First +/// @return If successful, how many buffer entries were used. Otherwise 0. uint16_t IRrecv::matchGeneric(volatile uint16_t *data_ptr, uint8_t *result_ptr, const uint16_t remaining, @@ -1297,33 +1334,118 @@ uint16_t IRrecv::matchGeneric(volatile uint16_t *data_ptr, tolerance, excess, MSBfirst); } -// Match & decode a Manchester Code <= 64bit IR message. -// The data is stored at result_ptr. -// Values of 0 for hdrmark, hdrspace, footermark, or footerspace mean skip -// that requirement. -// -// Args: -// data_ptr: A pointer to where we are at in the capture buffer. -// NOTE: It is assumed to be pointing to a "Mark", not a "Space". -// result_ptr: A pointer to where to start storing the bits we decoded. -// remaining: The size of the capture buffer are remaining. -// nbits: Nr. of data bits we expect. -// hdrmark: Nr. of uSeconds for the expected header mark signal. -// hdrspace: Nr. of uSeconds for the expected header space signal. -// half_period: Nr. of uSeconds for half the clock's period. (1/2 wavelength) -// footermark: Nr. of uSeconds for the expected footer mark signal. -// footerspace: Nr. of uSeconds for the expected footer space/gap signal. -// atleast: Is the match on the footerspace a matchAtLeast or matchSpace? -// tolerance: Percentage error margin to allow. (Def: kUseDefTol) -// excess: Nr. of useconds. (Def: kMarkExcess) -// MSBfirst: Bit order to save the data in. (Def: true) -// GEThomas: Use G.E. Thomas (true/default) or IEEE 802.3 (false) convention? -// Returns: -// A uint16_t: If successful, how many buffer entries were used. Otherwise 0. -// -// Ref: -// https://en.wikipedia.org/wiki/Manchester_code -// http://ww1.microchip.com/downloads/en/AppNotes/Atmel-9164-Manchester-Coding-Basics_Application-Note.pdf +/// Match & decode a generic/typical constant bit time <= 64bit IR message. +/// The data is stored at result_ptr. +/// @note Values of 0 for hdrmark, hdrspace, footermark, or footerspace mean +/// skip that requirement. +/// @param[in] data_ptr A pointer to where we are at in the capture buffer. +/// @note `data_ptr` is assumed to be pointing to a "Mark", not a "Space". +/// @param[out] result_ptr A ptr to where to start storing the bits we decoded. +/// @param[in] remaining The size of the capture buffer remaining. +/// @param[in] nbits Nr. of data bits we expect. +/// @param[in] hdrmark Nr. of uSeconds for the expected header mark signal. +/// @param[in] hdrspace Nr. of uSeconds for the expected header space signal. +/// @param[in] one Nr. of uSeconds in an expected mark signal for a '1' bit. +/// @param[in] zero Nr. of uSeconds in an expected mark signal for a '0' bit. +/// @param[in] footermark Nr. of uSeconds for the expected footer mark signal. +/// @param[in] footerspace Nr. of uSeconds for the expected footer space/gap +/// signal. +/// @param[in] atleast Is the match on the footerspace a matchAtLeast or +/// matchSpace? +/// @param[in] tolerance Percentage error margin to allow. (Default: kUseDefTol) +/// @param[in] excess Nr. of uSeconds. (Def: kMarkExcess) +/// @param[in] MSBfirst Bit order to save the data in. (Def: true) +/// true is Most Significant Bit First Order, false is Least Significant First +/// @return If successful, how many buffer entries were used. Otherwise 0. +/// @note Parameters one + zero add up to the total time for a bit. +/// e.g. mark(one) + space(zero) is a `1`, mark(zero) + space(one) is a `0`. +uint16_t IRrecv::matchGenericConstBitTime(volatile uint16_t *data_ptr, + uint64_t *result_ptr, + const uint16_t remaining, + const uint16_t nbits, + const uint16_t hdrmark, + const uint32_t hdrspace, + const uint16_t one, + const uint32_t zero, + const uint16_t footermark, + const uint32_t footerspace, + const bool atleast, + const uint8_t tolerance, + const int16_t excess, + const bool MSBfirst) { + uint16_t offset = 0; + uint64_t result = 0; + // If we expect a footermark, then this can be processed like normal. + if (footermark) + return _matchGeneric(data_ptr, result_ptr, NULL, true, remaining, nbits, + hdrmark, hdrspace, one, zero, zero, one, + footermark, footerspace, atleast, + tolerance, excess, MSBfirst); + // Overwise handle like normal, except for the last bit. and no footer. + uint16_t bits = (nbits > 0) ? nbits - 1 : 0; // Make sure we don't underflow. + offset = _matchGeneric(data_ptr, &result, NULL, true, remaining, bits, + hdrmark, hdrspace, one, zero, zero, one, 0, 0, false, + tolerance, excess, true); + if (!offset) return 0; // Didn't match. + // Now for the last bit. + if (remaining <= offset) return 0; // Not enough buffer. + result <<= 1; + bool last_bit = 0; + // Is the mark a '1' or a `0`? + if (matchMark(*(data_ptr + offset), one, tolerance, excess)) { // 1 + last_bit = 1; + result |= 1; + } else if (matchMark(*(data_ptr + offset), zero, tolerance, excess)) { // 0 + last_bit = 0; + } else { + return 0; // It's neither, so fail. + } + offset++; + uint32_t expected_space = (last_bit ? zero : one) + footerspace; + // If we are not at the end of the buffer, check for at least the expected + // space value. + if (remaining > offset) { + if (atleast) { + if (!matchAtLeast(*(data_ptr + offset), expected_space, tolerance, + excess)) + return false; + } else { + if (!matchSpace(*(data_ptr + offset), expected_space, tolerance)) + return false; + } + offset++; + } + if (!MSBfirst) result = reverseBits(result, nbits); + *result_ptr = result; + return offset; +} + +/// Match & decode a Manchester Code <= 64bit IR message. +/// The data is stored at result_ptr. +/// @note Values of 0 for hdrmark, hdrspace, footermark, or footerspace mean +/// skip that requirement. +/// @param[in] data_ptr A pointer to where we are at in the capture buffer. +/// @note `data_ptr` is assumed to be pointing to a "Mark", not a "Space". +/// @param[out] result_ptr A ptr to where to start storing the bits we decoded. +/// @param[in] remaining The size of the capture buffer remaining. +/// @param[in] nbits Nr. of data bits we expect. +/// @param[in] hdrmark Nr. of uSeconds for the expected header mark signal. +/// @param[in] hdrspace Nr. of uSeconds for the expected header space signal. +/// @param[in] half_period Nr. of uSeconds for half the clock's period. +/// i.e. 1/2 wavelength +/// @param[in] footermark Nr. of uSeconds for the expected footer mark signal. +/// @param[in] footerspace Nr. of uSeconds for the expected footer space/gap +/// signal. +/// @param[in] atleast Is the match on the footerspace a matchAtLeast or +/// matchSpace? +/// @param[in] tolerance Percentage error margin to allow. (Default: kUseDefTol) +/// @param[in] excess Nr. of uSeconds. (Def: kMarkExcess) +/// @param[in] MSBfirst Bit order to save the data in. (Def: true) +/// true is Most Significant Bit First Order, false is Least Significant First +/// @param[in] GEThomas Use G.E. Thomas (true) or IEEE 802.3 (false) convention? +/// @return If successful, how many buffer entries were used. Otherwise 0. +/// @see https://en.wikipedia.org/wiki/Manchester_code +/// @see http://ww1.microchip.com/downloads/en/AppNotes/Atmel-9164-Manchester-Coding-Basics_Application-Note.pdf uint16_t IRrecv::matchManchester(volatile const uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, @@ -1339,15 +1461,12 @@ uint16_t IRrecv::matchManchester(volatile const uint16_t *data_ptr, const bool MSBfirst, const bool GEThomas) { uint16_t offset = 0; - uint64_t data = 0; - uint16_t nr_of_half_periods = GEThomas; - // 2 per bit, and 4 extra for the timing sync. - uint16_t expected_half_periods = 2 * nbits + 4; - bool currentBit = false; + uint16_t bank = 0; + uint16_t entry = 0; // Calculate how much remaining buffer is required. - // Shortest case. Longest case is 2 * nbits. - uint16_t min_remaining = nbits + 2; + // Shortest case is nbits. Longest case is 2 * nbits. + uint16_t min_remaining = nbits; if (hdrmark) min_remaining++; if (hdrspace) min_remaining++; @@ -1358,86 +1477,45 @@ uint16_t IRrecv::matchManchester(volatile const uint16_t *data_ptr, if (remaining < min_remaining) return 0; // Nope, so abort. // Header - if (hdrmark && !matchMark(*(data_ptr + offset++), hdrmark, tolerance, excess)) - return 0; - // Manchester Code always has a guaranteed 2x half_period (T2) at the start - // of the data section. e.g. a sync header. If it is a GEThomas-style, then - // it is space(T);mark(2xT);space(T), thus we need to check for that space - // plus any requested "header" space. - if ((hdrspace || GEThomas) && - !matchSpace(*(data_ptr + offset++), - hdrspace + ((GEThomas) ? half_period : 0), tolerance, excess)) - return 0; - - // Data - // Loop until we find a 'long' pulse. This is the timing sync per protocol. - while ((offset < remaining) && (nr_of_half_periods < expected_half_periods) && - !match(*(data_ptr + offset), half_period * 2, tolerance, excess)) { - // Was it not a short pulse? - if (!match(*(data_ptr + offset), half_period, tolerance, excess)) - return 0; - nr_of_half_periods++; - offset++; - } - - // Data (cont.) - - // We are now pointing to the first 'long' pulse. - // Loop through the buffer till we run out of buffer, or nr of half periods. - while (offset < remaining && nr_of_half_periods < expected_half_periods) { - // Only if there is enough half_periods left for a long pulse & - // Is it a 'long' pulse? - if (nr_of_half_periods < expected_half_periods - 1 && - match(*(data_ptr + offset), half_period * 2, tolerance, excess)) { - // Yes, so invert the value we will append. - currentBit = !currentBit; - nr_of_half_periods += 2; // A 'long' pulse is two half periods. - offset++; - // Append the bit value. - data <<= 1; - data |= currentBit; - } else if (match(*(data_ptr + offset), half_period, tolerance, excess)) { - // or is it part of a 'short' pulse pair? - nr_of_half_periods++; - offset++; - // Look for the second half of the 'short' pulse pair. - // Do we have enough buffer or nr of half periods? - if (offset < remaining && nr_of_half_periods < expected_half_periods) { - // We do, so look for it. - if (match(*(data_ptr + offset), half_period, tolerance, excess)) { - // Found it! - nr_of_half_periods++; - // No change of the polarity of the bit we will append. - // Append the bit value. - data <<= 1; - data |= currentBit; - offset++; - } else { - // It's not what we expected. - return 0; - } + if (hdrmark) { + entry = *(data_ptr + offset++); + if (!hdrspace) { // If we have no Header Space ... + // Do we have a data 'mark' half period merged with the header mark? + if (matchMark(entry, hdrmark + half_period, + tolerance, excess)) { + // Looks like we do. + bank = entry * kRawTick - hdrmark; + } else if (!matchMark(entry, hdrmark, tolerance, excess)) { + return 0; // It's not a normal header mark, so fail. } - } else if (nr_of_half_periods == expected_half_periods - 1 && - matchAtLeast(*(data_ptr + offset), half_period, tolerance, - excess)) { - // Special case when we are at the end of the expected nr of periods. - // i.e. The pulse could be merged with the footer. - nr_of_half_periods++; - break; - } else { - // It's neither, so abort. - return 0; + } else if (!matchMark(entry, hdrmark, tolerance, excess)) { + return 0; // It's not a normal header mark, so fail. + } + } + if (hdrspace) { + entry = *(data_ptr + offset++); + // Check to see if the header space has merged with a data space half period + if (matchSpace(entry, hdrspace + half_period, tolerance, excess)) { + // Looks like we do. + bank = entry * kRawTick - hdrspace; + } else if (!matchSpace(entry, hdrspace, tolerance, excess)) { + return 0; // It's not a normal header space, so fail. } } - // Did we collect the expected amount of data? - if (nr_of_half_periods < expected_half_periods) return 0; + if (!match(bank / kRawTick, half_period, tolerance, excess)) bank = 0; + // Data + uint16_t used = matchManchesterData(data_ptr + offset, result_ptr, + remaining - offset, nbits, half_period, + bank, tolerance, excess, MSBfirst, + GEThomas); + if (!used) return 0; // Data did match. + offset += used; // Footer if (footermark && !(matchMark(*(data_ptr + offset), footermark + half_period, tolerance, excess) || - matchMark(*(data_ptr + offset), footermark, - tolerance, excess))) + matchMark(*(data_ptr + offset), footermark, tolerance, excess))) return 0; offset++; // If we have something still to match & haven't reached the end of the buffer @@ -1446,15 +1524,127 @@ uint16_t IRrecv::matchManchester(volatile const uint16_t *data_ptr, if (!matchAtLeast(*(data_ptr + offset), footerspace, tolerance, excess)) return 0; } else { - if (!matchSpace(*(data_ptr + offset), footerspace, tolerance, excess)) + if (!matchSpace(*(data_ptr + offset), footerspace, tolerance, excess) && + !matchSpace(*(data_ptr + offset), footerspace + half_period, + tolerance, excess)) return 0; } offset++; } + return offset; +} + +/// Match & decode a Manchester Code data (<= 64bits. +/// @param[in] data_ptr A pointer to where we are at in the capture buffer. +/// @note `data_ptr` is assumed to be pointing to a "Mark", not a "Space". +/// @param[out] result_ptr A ptr to where to start storing the bits we decoded. +/// @param[in] remaining The size of the capture buffer remaining. +/// @param[in] nbits Nr. of data bits we expect. +/// @param[in] half_period Nr. of uSeconds for half the clock's period. +/// i.e. 1/2 wavelength +/// @param[in] tolerance Percentage error margin to allow. (Default: kUseDefTol) +/// @param[in] starting_balance Amount of uSeconds to assume exists prior to +/// the current value pointed too. +/// @param[in] excess Nr. of uSeconds. (Def: kMarkExcess) +/// @param[in] MSBfirst Bit order to save the data in. (Def: true) +/// true is Most Significant Bit First Order, false is Least Significant First +/// @param[in] GEThomas Use G.E. Thomas (true) or IEEE 802.3 (false) convention? +/// @return If successful, how many buffer entries were used. Otherwise 0. +/// @see https://en.wikipedia.org/wiki/Manchester_code +/// @see http://ww1.microchip.com/downloads/en/AppNotes/Atmel-9164-Manchester-Coding-Basics_Application-Note.pdf +/// @todo Clean up and optimise this. It is just "get it working code" atm. +uint16_t IRrecv::matchManchesterData(volatile const uint16_t *data_ptr, + uint64_t *result_ptr, + const uint16_t remaining, + const uint16_t nbits, + const uint16_t half_period, + const uint16_t starting_balance, + const uint8_t tolerance, + const int16_t excess, + const bool MSBfirst, + const bool GEThomas) { + uint16_t offset = 0; + uint64_t data = 0; + uint16_t nr_half_periods = 0; + const uint16_t expected_half_periods = nbits * 2; + // Flip the bit if we have a starting balance. ie. Carry over from the header. + bool currentBit = starting_balance ? !GEThomas : GEThomas; + const uint16_t raw_half_period = half_period / kRawTick; + + // Calculate how much remaining buffer is required. + // Shortest case is nbits. Longest case is 2 * nbits. + uint16_t min_remaining = nbits; + + // Check if there is enough capture buffer to possibly have the message. + if (remaining < min_remaining) return 0; // Nope, so abort. + + // Convert to ticks. Optimisation: Saves on math/extra instructions later. + uint16_t bank = starting_balance / kRawTick; + + // Data + // Loop through the buffer till we run out of buffer, or nr of half periods. + // Possible patterns are: + // short + short = 1 bit (Add the value of the previous bit again) + // short + long + short = 2 bits (Add the previous bit again, then flip & add) + // short + long + long + short = 3 bits (add prev, flip & add, flip & add) + // We can't start with a long. + // + // The general approach is thus: + // Check we have a short interval, next or in the bank. + // If the next timing value is long, act according and reset the bank to + // a short balance. + // or + // If it is short, act accordingly and declare the bank empty. + // Repeat. + while ((offset < remaining || bank) && + nr_half_periods < expected_half_periods) { + // Get the next entry if we haven't anything existing to process. + if (!bank) bank = *(data_ptr + offset++); + // Check if we don't have a short interval. + if (!match(bank, half_period, tolerance, excess)) return 0; // Not valid. + // We've succeeded in matching half a period, so count it. + nr_half_periods++; + // We've now used up our bank, so refill it with the next item, unless we + // are at the end of the capture buffer. + // If we are assume a single half period of "space". + if (offset < remaining) + bank = *(data_ptr + offset++); + else if (offset == remaining) + bank = raw_half_period; + else + return 0; // We are out of buffer, so abort! + + // Shift the data along and add our new bit. + data <<= 1; + data |= currentBit; + + // Check if we have a long interval. + if (match(bank, half_period * 2, tolerance, excess)) { + // It is, so flip the bit we need to append, and remove a half_period of + // time from the bank. + currentBit = !currentBit; + bank -= raw_half_period; + } else if (match(bank, half_period, tolerance, excess)) { + // It is a short interval, so eat up all the time and move on. + bank = 0; + } else if (nr_half_periods == expected_half_periods - 1 && + matchAtLeast(bank, half_period, tolerance, excess)) { + // We are at the end of the data & it is a short interval, so eat up all + // the time and move on. + bank = 0; + // Reduce the offset as we are at the end of the data doing a + // matchAtLeast() because we could be processing part of a footer. + offset--; + } else { + // The length isn't what we expected (neither long or short), so bail. + return 0; + } + nr_half_periods++; + } // Clean up and process the data. if (!MSBfirst) data = reverseBits(data, nbits); - // Trim the data to size to remove timing sync. + // Trim the data to size. *result_ptr = GETBITS64(data, 0, nbits); return offset; } diff --git a/lib/IRremoteESP8266-2.7.5/src/IRrecv.h b/lib/IRremoteESP8266-2.7.8/src/IRrecv.h similarity index 86% rename from lib/IRremoteESP8266-2.7.5/src/IRrecv.h rename to lib/IRremoteESP8266-2.7.8/src/IRrecv.h index aeea5b32d..36da8df1b 100644 --- a/lib/IRremoteESP8266-2.7.5/src/IRrecv.h +++ b/lib/IRremoteESP8266-2.7.8/src/IRrecv.h @@ -64,7 +64,8 @@ const uint16_t kStateSizeMax = 0; #endif // Types -// information for the interrupt handler + +/// Information for the interrupt handler typedef struct { uint8_t recvpin; // pin for IR data from detector uint8_t rcvstate; // state machine @@ -78,7 +79,7 @@ typedef struct { uint8_t timeout; // Nr. of milliSeconds before we give up. } irparams_t; -// results from a data match +/// Results from a data match typedef struct { bool success; // Was the match successful? uint64_t data; // The data found. @@ -87,7 +88,7 @@ typedef struct { // Classes -// Results returned from the decoder +/// Results returned from the decoder class decode_results { public: decode_type_t decode_type; // NEC, SONY, RC5, UNKNOWN @@ -109,7 +110,7 @@ class decode_results { bool repeat; // Is the result a repeat code? }; -// main class for receiving IR +/// Class for receiving IR messages. class IRrecv { public: #if defined(ESP32) @@ -221,6 +222,30 @@ class IRrecv { const uint8_t tolerance = kUseDefTol, const int16_t excess = kMarkExcess, const bool MSBfirst = true); + uint16_t matchGenericConstBitTime(volatile uint16_t *data_ptr, + uint64_t *result_ptr, + const uint16_t remaining, + const uint16_t nbits, + const uint16_t hdrmark, + const uint32_t hdrspace, + const uint16_t one, + const uint32_t zero, + const uint16_t footermark, + const uint32_t footerspace, + const bool atleast = false, + const uint8_t tolerance = kUseDefTol, + const int16_t excess = kMarkExcess, + const bool MSBfirst = true); + uint16_t matchManchesterData(volatile const uint16_t *data_ptr, + uint64_t *result_ptr, + const uint16_t remaining, + const uint16_t nbits, + const uint16_t half_period, + const uint16_t starting_balance = 0, + const uint8_t tolerance = kUseDefTol, + const int16_t excess = kMarkExcess, + const bool MSBfirst = true, + const bool GEThomas = true); uint16_t matchManchester(volatile const uint16_t *data_ptr, uint64_t *result_ptr, const uint16_t remaining, @@ -237,7 +262,7 @@ class IRrecv { const bool GEThomas = true); void crudeNoiseFilter(decode_results *results, const uint16_t floor = 0); bool decodeHash(decode_results *results); -#if (DECODE_NEC || DECODE_SHERWOOD || DECODE_AIWA_RC_T501 || SEND_SANYO) +#if (DECODE_NEC || DECODE_SHERWOOD || DECODE_AIWA_RC_T501 || DECODE_SANYO) bool decodeNEC(decode_results *results, uint16_t offset = kStartOffset, const uint16_t nbits = kNECBits, const bool strict = true); #endif @@ -297,9 +322,9 @@ class IRrecv { #endif #if (DECODE_RC5 || DECODE_R6 || DECODE_LASERTAG || DECODE_MWM) int16_t getRClevel(decode_results *results, uint16_t *offset, uint16_t *used, - uint16_t bitTime, uint8_t tolerance = kUseDefTol, - int16_t excess = kMarkExcess, uint16_t delta = 0, - uint8_t maxwidth = 3); + uint16_t bitTime, const uint8_t tolerance = kUseDefTol, + const int16_t excess = kMarkExcess, + const uint16_t delta = 0, const uint8_t maxwidth = 3); #endif #if DECODE_RC5 bool decodeRC5(decode_results *results, uint16_t offset = kStartOffset, @@ -456,7 +481,12 @@ class IRrecv { bool decodeMidea(decode_results *results, uint16_t offset = kStartOffset, const uint16_t nbits = kMideaBits, const bool strict = true); -#endif +#endif // DECODE_MIDEA +#if DECODE_MIDEA24 + bool decodeMidea24(decode_results *results, uint16_t offset = kStartOffset, + const uint16_t nbits = kMidea24Bits, + const bool strict = true); +#endif // DECODE_MIDEA24 #if DECODE_FUJITSU_AC bool decodeFujitsuAC(decode_results *results, uint16_t offset = kStartOffset, const uint16_t nbits = kFujitsuAcBits, @@ -471,7 +501,19 @@ class IRrecv { bool decodeCarrierAC(decode_results *results, uint16_t offset = kStartOffset, const uint16_t nbits = kCarrierAcBits, const bool strict = true); -#endif +#endif // DECODE_CARRIER_AC +#if DECODE_CARRIER_AC40 + bool decodeCarrierAC40(decode_results *results, + uint16_t offset = kStartOffset, + const uint16_t nbits = kCarrierAc40Bits, + const bool strict = true); +#endif // DECODE_CARRIER_AC40 +#if DECODE_CARRIER_AC64 + bool decodeCarrierAC64(decode_results *results, + uint16_t offset = kStartOffset, + const uint16_t nbits = kCarrierAc64Bits, + const bool strict = true); +#endif // DECODE_CARRIER_AC64 #if DECODE_GOODWEATHER bool decodeGoodweather(decode_results *results, uint16_t offset = kStartOffset, @@ -494,10 +536,10 @@ class IRrecv { const uint16_t nbits = kHaierACYRW02Bits, const bool strict = true); #endif -#if (DECODE_HITACHI_AC || DECODE_HITACHI_AC2) +#if (DECODE_HITACHI_AC || DECODE_HITACHI_AC2 || DECODE_HITACHI_AC344) bool decodeHitachiAC(decode_results *results, uint16_t offset = kStartOffset, const uint16_t nbits = kHitachiAcBits, - const bool strict = true); + const bool strict = true, const bool MSBfirst = true); #endif #if DECODE_HITACHI_AC1 bool decodeHitachiAC1(decode_results *results, uint16_t offset = kStartOffset, @@ -593,6 +635,32 @@ class IRrecv { const uint16_t nbits = kAirwellBits, const bool strict = true); #endif // DECODE_AIRWELL +#if DECODE_DELONGHI_AC + bool decodeDelonghiAc(decode_results *results, uint16_t offset = kStartOffset, + const uint16_t nbits = kDelonghiAcBits, + const bool strict = true); +#endif // DECODE_DELONGHI_AC +#if DECODE_DOSHISHA + bool decodeDoshisha(decode_results *results, uint16_t offset = kStartOffset, + const uint16_t nbits = kDoshishaBits, + const bool strict = true); +#endif // DECODE_DOSHISHA +#if DECODE_MULTIBRACKETS + bool decodeMultibrackets(decode_results *results, + uint16_t offset = kStartOffset, + const uint16_t nbits = kMultibracketsBits, + const bool strict = true); +#endif // DECODE_MULTIBRACKETS +#if DECODE_CORONA_AC + bool decodeCoronaAc(decode_results *results, uint16_t offset = kStartOffset, + const uint16_t nbits = kCoronaAcBitsShort, + const bool strict = true); +#endif // DECODE_CORONA_AC +#if DECODE_ZEPEAL +bool decodeZepeal(decode_results *results, uint16_t offset = kStartOffset, + const uint16_t nbits = kZepealBits, + const bool strict = true); +#endif // DECODE_ZEPEAL }; #endif // IRRECV_H_ diff --git a/lib/IRremoteESP8266-2.7.5/src/IRremoteESP8266.h b/lib/IRremoteESP8266-2.7.8/src/IRremoteESP8266.h similarity index 89% rename from lib/IRremoteESP8266-2.7.5/src/IRremoteESP8266.h rename to lib/IRremoteESP8266-2.7.8/src/IRremoteESP8266.h index dd8008bc0..4490baa3b 100644 --- a/lib/IRremoteESP8266-2.7.5/src/IRremoteESP8266.h +++ b/lib/IRremoteESP8266-2.7.8/src/IRremoteESP8266.h @@ -52,7 +52,7 @@ #endif // UNIT_TEST // Library Version -#define _IRREMOTEESP8266_VERSION_ "2.7.5" +#define _IRREMOTEESP8266_VERSION_ "2.7.8" // Set the language & locale for the library. See the `locale` dir for options. #ifndef _IR_LOCALE_ @@ -369,6 +369,13 @@ #define SEND_MIDEA _IR_ENABLE_DEFAULT_ #endif // SEND_MIDEA +#ifndef DECODE_MIDEA24 +#define DECODE_MIDEA24 _IR_ENABLE_DEFAULT_ +#endif // DECODE_MIDEA24 +#ifndef SEND_MIDEA24 +#define SEND_MIDEA24 _IR_ENABLE_DEFAULT_ +#endif // SEND_MIDEA24 + #ifndef DECODE_LASERTAG #define DECODE_LASERTAG _IR_ENABLE_DEFAULT_ #endif // DECODE_LASERTAG @@ -383,6 +390,20 @@ #define SEND_CARRIER_AC _IR_ENABLE_DEFAULT_ #endif // SEND_CARRIER_AC +#ifndef DECODE_CARRIER_AC40 +#define DECODE_CARRIER_AC40 _IR_ENABLE_DEFAULT_ +#endif // DECODE_CARRIER_AC40 +#ifndef SEND_CARRIER_AC40 +#define SEND_CARRIER_AC40 _IR_ENABLE_DEFAULT_ +#endif // SEND_CARRIER_AC40 + +#ifndef DECODE_CARRIER_AC64 +#define DECODE_CARRIER_AC64 _IR_ENABLE_DEFAULT_ +#endif // DECODE_CARRIER_AC64 +#ifndef SEND_CARRIER_AC64 +#define SEND_CARRIER_AC64 _IR_ENABLE_DEFAULT_ +#endif // SEND_CARRIER_AC64 + #ifndef DECODE_HAIER_AC #define DECODE_HAIER_AC _IR_ENABLE_DEFAULT_ #endif // DECODE_HAIER_AC @@ -412,12 +433,19 @@ #endif // SEND_HITACHI_AC2 #ifndef DECODE_HITACHI_AC3 -#define DECODE_HITACHI_AC3 _IR_ENABLE_DEFAULT_ +#define DECODE_HITACHI_AC3 _IR_ENABLE_DEFAULT_ #endif // DECODE_HITACHI_AC3 #ifndef SEND_HITACHI_AC3 -#define SEND_HITACHI_AC3 _IR_ENABLE_DEFAULT_ +#define SEND_HITACHI_AC3 _IR_ENABLE_DEFAULT_ #endif // SEND_HITACHI_AC3 +#ifndef DECODE_HITACHI_AC344 +#define DECODE_HITACHI_AC344 _IR_ENABLE_DEFAULT_ +#endif // DECODE_HITACHI_AC344 +#ifndef SEND_HITACHI_AC344 +#define SEND_HITACHI_AC344 _IR_ENABLE_DEFAULT_ +#endif // SEND_HITACHI_AC344 + #ifndef DECODE_HITACHI_AC424 #define DECODE_HITACHI_AC424 _IR_ENABLE_DEFAULT_ #endif // DECODE_HITACHI_AC424 @@ -573,33 +601,68 @@ #endif // SEND_DAIKIN152 #ifndef DECODE_EPSON -#define DECODE_EPSON _IR_ENABLE_DEFAULT_ +#define DECODE_EPSON _IR_ENABLE_DEFAULT_ #endif // DECODE_EPSON #ifndef SEND_EPSON -#define SEND_EPSON _IR_ENABLE_DEFAULT_ +#define SEND_EPSON _IR_ENABLE_DEFAULT_ #endif // SEND_EPSON #ifndef DECODE_SYMPHONY -#define DECODE_SYMPHONY _IR_ENABLE_DEFAULT_ +#define DECODE_SYMPHONY _IR_ENABLE_DEFAULT_ #endif // DECODE_SYMPHONY #ifndef SEND_SYMPHONY -#define SEND_SYMPHONY _IR_ENABLE_DEFAULT_ +#define SEND_SYMPHONY _IR_ENABLE_DEFAULT_ #endif // SEND_SYMPHONY #ifndef DECODE_DAIKIN64 -#define DECODE_DAIKIN64 _IR_ENABLE_DEFAULT_ +#define DECODE_DAIKIN64 _IR_ENABLE_DEFAULT_ #endif // DECODE_DAIKIN64 #ifndef SEND_DAIKIN64 -#define SEND_DAIKIN64 _IR_ENABLE_DEFAULT_ +#define SEND_DAIKIN64 _IR_ENABLE_DEFAULT_ #endif // SEND_DAIKIN64 #ifndef DECODE_AIRWELL -#define DECODE_AIRWELL _IR_ENABLE_DEFAULT_ +#define DECODE_AIRWELL _IR_ENABLE_DEFAULT_ #endif // DECODE_AIRWELL #ifndef SEND_AIRWELL -#define SEND_AIRWELL _IR_ENABLE_DEFAULT_ +#define SEND_AIRWELL _IR_ENABLE_DEFAULT_ #endif // SEND_AIRWELL +#ifndef DECODE_DELONGHI_AC +#define DECODE_DELONGHI_AC _IR_ENABLE_DEFAULT_ +#endif // DECODE_DELONGHI_AC +#ifndef SEND_DELONGHI_AC +#define SEND_DELONGHI_AC _IR_ENABLE_DEFAULT_ +#endif // SEND_DELONGHI_AC + +#ifndef DECODE_DOSHISHA +#define DECODE_DOSHISHA _IR_ENABLE_DEFAULT_ +#endif // DECODE_DOSHISHA +#ifndef SEND_DOSHISHA +#define SEND_DOSHISHA _IR_ENABLE_DEFAULT_ +#endif // SEND_DOSHISHA + +#ifndef DECODE_MULTIBRACKETS +#define DECODE_MULTIBRACKETS _IR_ENABLE_DEFAULT_ +#endif // DECODE_MULTIBRACKETS +#ifndef SEND_MULTIBRACKETS +#define SEND_MULTIBRACKETS _IR_ENABLE_DEFAULT_ +#endif // SEND_MULTIBRACKETS + +#ifndef DECODE_CORONA_AC +#define DECODE_CORONA_AC _IR_ENABLE_DEFAULT_ +#endif // DECODE_CORONA_AC +#ifndef SEND_CORONA_AC +#define SEND_CORONA_AC _IR_ENABLE_DEFAULT_ +#endif // SEND_CORONA_AC + +#ifndef DECODE_ZEPEAL +#define DECODE_ZEPEAL _IR_ENABLE_DEFAULT_ +#endif // DECODE_ZEPEAL +#ifndef SEND_ZEPEAL +#define SEND_ZEPEAL _IR_ENABLE_DEFAULT_ +#endif // SEND_ZEPEAL + #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 || \ @@ -610,7 +673,10 @@ DECODE_DAIKIN216 || DECODE_SHARP_AC || DECODE_DAIKIN160 || \ DECODE_NEOCLIMA || DECODE_DAIKIN176 || DECODE_DAIKIN128 || \ DECODE_AMCOR || DECODE_DAIKIN152 || DECODE_MITSUBISHI136 || \ - DECODE_MITSUBISHI112 || DECODE_HITACHI_AC424 || DECODE_HITACHI_AC3) + DECODE_MITSUBISHI112 || DECODE_HITACHI_AC424 || DECODE_HITACHI_AC3 || \ + DECODE_HITACHI_AC344 || DECODE_CORONA_AC) + // Add any DECODE to the above if it uses result->state (see kStateSizeMax) + // you might also want to add the protocol to hasACState function #define DECODE_AC true // We need some common infrastructure for decoding A/Cs. #else #define DECODE_AC false // We don't need that infrastructure. @@ -640,11 +706,11 @@ #ifndef ENABLE_NOISE_FILTER_OPTION #define ENABLE_NOISE_FILTER_OPTION true #endif // ENABLE_NOISE_FILTER_OPTION -/* - * Always add to the end of the list and should never remove entries - * or change order. Projects may save the type number for later usage - * so numbering should always stay the same. - */ + +/// Enumerator for defining and numbering of supported IR protocol. +/// @note Always add to the end of the list and should never remove entries +/// or change order. Projects may save the type number for later usage +/// so numbering should always stay the same. enum decode_type_t { UNKNOWN = -1, UNUSED = 0, @@ -727,15 +793,24 @@ enum decode_type_t { HITACHI_AC3, DAIKIN64, AIRWELL, + DELONGHI_AC, // 80 + DOSHISHA, + MULTIBRACKETS, + CARRIER_AC40, + CARRIER_AC64, + HITACHI_AC344, // 85 + CORONA_AC, + MIDEA24, + ZEPEAL, // Add new entries before this one, and update it to point to the last entry. - kLastDecodeType = AIRWELL, + kLastDecodeType = ZEPEAL, }; // Message lengths & required repeat values const uint16_t kNoRepeat = 0; const uint16_t kSingleRepeat = 1; -const uint16_t kAirwellBits = 32; +const uint16_t kAirwellBits = 34; const uint16_t kAirwellMinRepeats = 2; const uint16_t kAiwaRcT501Bits = 15; const uint16_t kAiwaRcT501MinRepeats = kSingleRepeat; @@ -750,6 +825,14 @@ const uint16_t kCoolixBits = 24; const uint16_t kCoolixDefaultRepeat = kSingleRepeat; const uint16_t kCarrierAcBits = 32; const uint16_t kCarrierAcMinRepeat = kNoRepeat; +const uint16_t kCarrierAc40Bits = 40; +const uint16_t kCarrierAc40MinRepeat = 2; +const uint16_t kCarrierAc64Bits = 64; +const uint16_t kCarrierAc64MinRepeat = kNoRepeat; +const uint16_t kCoronaAcStateLengthShort = 7; +const uint16_t kCoronaAcStateLength = kCoronaAcStateLengthShort * 3; +const uint16_t kCoronaAcBitsShort = kCoronaAcStateLengthShort * 8; +const uint16_t kCoronaAcBits = kCoronaAcStateLength * 8; const uint16_t kDaikinStateLength = 35; const uint16_t kDaikinBits = kDaikinStateLength * 8; const uint16_t kDaikinStateLengthShort = kDaikinStateLength - 8; @@ -775,11 +858,14 @@ const uint16_t kDaikin176DefaultRepeat = kNoRepeat; const uint16_t kDaikin216StateLength = 27; const uint16_t kDaikin216Bits = kDaikin216StateLength * 8; const uint16_t kDaikin216DefaultRepeat = kNoRepeat; +const uint16_t kDelonghiAcBits = 64; +const uint16_t kDelonghiAcDefaultRepeat = kNoRepeat; const uint16_t kDenonBits = 15; const uint16_t kDenon48Bits = 48; const uint16_t kDenonLegacyBits = 14; const uint16_t kDishBits = 16; const uint16_t kDishMinRepeat = 3; +const uint16_t kDoshishaBits = 40; const uint16_t kEpsonBits = 32; const uint16_t kEpsonMinRepeat = 2; const uint16_t kElectraAcStateLength = 13; @@ -814,6 +900,8 @@ const uint16_t kHitachiAc3StateLength = 27; const uint16_t kHitachiAc3Bits = kHitachiAc3StateLength * 8; const uint16_t kHitachiAc3MinStateLength = 15; const uint16_t kHitachiAc3MinBits = kHitachiAc3MinStateLength * 8; +const uint16_t kHitachiAc344StateLength = 43; +const uint16_t kHitachiAc344Bits = kHitachiAc344StateLength * 8; const uint16_t kHitachiAc424StateLength = 53; const uint16_t kHitachiAc424Bits = kHitachiAc424StateLength * 8; const uint16_t kInaxBits = 24; @@ -833,6 +921,8 @@ const uint16_t kLutronBits = 35; const uint16_t kMagiquestBits = 56; const uint16_t kMideaBits = 48; const uint16_t kMideaMinRepeat = kNoRepeat; +const uint16_t kMidea24Bits = 24; +const uint16_t kMidea24MinRepeat = kSingleRepeat; const uint16_t kMitsubishiBits = 16; // TODO(anyone): Verify that the Mitsubishi repeat is really needed. // Based on marcosamarinho's code. @@ -852,6 +942,8 @@ const uint16_t kMitsubishiHeavy88MinRepeat = kNoRepeat; const uint16_t kMitsubishiHeavy152StateLength = 19; const uint16_t kMitsubishiHeavy152Bits = kMitsubishiHeavy152StateLength * 8; const uint16_t kMitsubishiHeavy152MinRepeat = kNoRepeat; +const uint16_t kMultibracketsBits = 8; +const uint16_t kMultibracketsDefaultRepeat = kSingleRepeat; const uint16_t kNikaiBits = 24; const uint16_t kNECBits = 32; const uint16_t kNeoclimaStateLength = 12; @@ -897,8 +989,8 @@ const uint16_t kSony15Bits = 15; const uint16_t kSony20Bits = 20; const uint16_t kSonyMinBits = 12; const uint16_t kSonyMinRepeat = 2; -const uint16_t kSymphonyBits = 11; -const uint16_t kSymphonyDefaultRepeat = kSingleRepeat; +const uint16_t kSymphonyBits = 12; +const uint16_t kSymphonyDefaultRepeat = 3; const uint16_t kTcl112AcStateLength = 14; const uint16_t kTcl112AcBits = kTcl112AcStateLength * 8; const uint16_t kTcl112AcDefaultRepeat = kNoRepeat; @@ -915,6 +1007,8 @@ const uint16_t kWhirlpoolAcBits = kWhirlpoolAcStateLength * 8; const uint16_t kWhirlpoolAcDefaultRepeat = kNoRepeat; const uint16_t kWhynterBits = 32; const uint8_t kVestelAcBits = 56; +const uint16_t kZepealBits = 16; +const uint16_t kZepealMinRepeat = 4; // Legacy defines. (Deprecated) diff --git a/lib/IRremoteESP8266-2.7.5/src/IRsend.cpp b/lib/IRremoteESP8266-2.7.8/src/IRsend.cpp similarity index 62% rename from lib/IRremoteESP8266-2.7.5/src/IRsend.cpp rename to lib/IRremoteESP8266-2.7.8/src/IRsend.cpp index bb5f55407..d3e097839 100644 --- a/lib/IRremoteESP8266-2.7.5/src/IRsend.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/IRsend.cpp @@ -15,25 +15,16 @@ #endif #include "IRtimer.h" -// Originally from https://github.com/shirriff/Arduino-IRremote/ -// Updated by markszabo (https://github.com/crankyoldgit/IRremoteESP8266) for -// sending IR code on ESP8266 - -// IRsend ---------------------------------------------------------------------- -// Create an IRsend object. -// -// Args: -// IRsendPin: Which GPIO pin to use when sending an IR command. -// inverted: *DANGER* Optional flag to invert the output. (default = false) -// e.g. LED is illuminated when GPIO is LOW rather than HIGH. -// Setting this to something other than the default could -// easily destroy your IR LED if you are overdriving it. -// Unless you *REALLY* know what you are doing, don't change this. -// use_modulation: Do we do frequency modulation during transmission? -// i.e. If not, assume a 100% duty cycle. Ignore attempts -// to change the duty cycle etc. -// Returns: -// An IRsend object. +/// Constructor for an IRsend object. +/// @param[in] IRsendPin Which GPIO pin to use when sending an IR command. +/// @param[in] inverted Optional flag to invert the output. (default = false) +/// e.g. LED is illuminated when GPIO is LOW rather than HIGH. +/// @warning Setting `inverted` to something other than the default could +/// easily destroy your IR LED if you are overdriving it. +/// Unless you *REALLY* know what you are doing, don't change this. +/// @param[in] use_modulation Do we do frequency modulation during transmission? +/// i.e. If not, assume a 100% duty cycle. Ignore attempts to change the +/// duty cycle etc. IRsend::IRsend(uint16_t IRsendPin, bool inverted, bool use_modulation) : IRpin(IRsendPin), periodOffset(kPeriodOffset) { if (inverted) { @@ -50,7 +41,7 @@ IRsend::IRsend(uint16_t IRsendPin, bool inverted, bool use_modulation) _dutycycle = kDutyMax; } -// Enable the pin for output. +/// Enable the pin for output. void IRsend::begin() { #ifndef UNIT_TEST pinMode(IRpin, OUTPUT); @@ -58,27 +49,25 @@ void IRsend::begin() { ledOff(); // Ensure the LED is in a known safe state when we start. } -// Turn off the IR LED. +/// Turn off the IR LED. void IRsend::ledOff() { #ifndef UNIT_TEST digitalWrite(IRpin, outputOff); #endif } -// Turn on the IR LED. +/// Turn on the IR LED. void IRsend::ledOn() { #ifndef UNIT_TEST digitalWrite(IRpin, outputOn); #endif } -// Calculate the period for a given frequency. (T = 1/f) -// -// Args: -// freq: Frequency in Hz. -// use_offset: Should we use the calculated offset or not? -// Returns: -// nr. of uSeconds. +/// Calculate the period for a given frequency. +/// @param[in] hz Frequency in Hz. +/// @param[in] use_offset Should we use the calculated offset or not? +/// @return nr. of uSeconds. +/// @note (T = 1/f) uint32_t IRsend::calcUSecPeriod(uint32_t hz, bool use_offset) { if (hz == 0) hz = 1; // Avoid Zero hz. Divide by Zero is nasty. uint32_t period = @@ -90,17 +79,16 @@ uint32_t IRsend::calcUSecPeriod(uint32_t hz, bool use_offset) { return std::max((uint32_t)1, period); } -// Set the output frequency modulation and duty cycle. -// -// Args: -// freq: The freq we want to modulate at. Assumes < 1000 means kHz else Hz. -// duty: Percentage duty cycle of the LED. e.g. 25 = 25% = 1/4 on, 3/4 off. -// This is ignored if modulation is disabled at object instantiation. -// -// Note: -// Integer timing functions & math mean we can't do fractions of -// microseconds timing. Thus minor changes to the freq & duty values may have -// limited effect. You've been warned. +/// Set the output frequency modulation and duty cycle. +/// @param[in] freq The freq we want to modulate at. +/// Assumes < 1000 means kHz else Hz. +/// @param[in] duty Percentage duty cycle of the LED. +/// e.g. 25 = 25% = 1/4 on, 3/4 off. +/// If you are not sure, try 50 percent. +/// This is ignored if modulation is disabled at object instantiation. +/// @note Integer timing functions & math mean we can't do fractions of +/// microseconds timing. Thus minor changes to the freq & duty values may have +/// limited effect. You've been warned. void IRsend::enableIROut(uint32_t freq, uint8_t duty) { // Set the duty cycle to use if we want freq. modulation. if (modulation) { @@ -121,9 +109,8 @@ void IRsend::enableIROut(uint32_t freq, uint8_t duty) { } #if ALLOW_DELAY_CALLS -// An ESP8266 RTOS watch-dog timer friendly version of delayMicroseconds(). -// Args: -// usec: Nr. of uSeconds to delay for. +/// An ESP8266 RTOS watch-dog timer friendly version of delayMicroseconds(). +/// @param[in] usec Nr. of uSeconds to delay for. void IRsend::_delayMicroseconds(uint32_t usec) { // delayMicroseconds() is only accurate to 16383us. // Ref: https://www.arduino.cc/en/Reference/delayMicroseconds @@ -141,13 +128,10 @@ void IRsend::_delayMicroseconds(uint32_t usec) { } } #else // ALLOW_DELAY_CALLS -// A version of delayMicroseconds() that handles large values and does NOT use -// the watch-dog friendly delay() calls where appropriate. -// Args: -// usec: Nr. of uSeconds to delay for. -// -// NOTE: Use this only if you know what you are doing as it may cause the WDT -// to reset the ESP8266. +/// A version of delayMicroseconds() that handles large values and does NOT use +/// the watch-dog friendly delay() calls where appropriate. +/// @note Use this only if you know what you are doing as it may cause the WDT +/// to reset the ESP8266. void IRsend::_delayMicroseconds(uint32_t usec) { for (; usec > kMaxAccurateUsecDelay; usec -= kMaxAccurateUsecDelay) #ifndef UNIT_TEST @@ -157,22 +141,19 @@ void IRsend::_delayMicroseconds(uint32_t usec) { } #endif // ALLOW_DELAY_CALLS -// Modulate the IR LED for the given period (usec) and at the duty cycle set. -// -// Args: -// usec: The period of time to modulate the IR LED for, in microseconds. -// Returns: -// Nr. of pulses actually sent. -// -// Note: -// The ESP8266 has no good way to do hardware PWM, so we have to do it all -// in software. There is a horrible kludge/brilliant hack to use the second -// serial TX line to do fairly accurate hardware PWM, but it is only -// available on a single specific GPIO and only available on some modules. -// e.g. It's not available on the ESP-01 module. -// Hence, for greater compatibility & choice, we don't use that method. -// Ref: -// https://www.analysir.com/blog/2017/01/29/updated-esp8266-nodemcu-backdoor-upwm-hack-for-ir-signals/ +/// Modulate the IR LED for the given period (usec) and at the duty cycle set. +/// @param[in] usec The period of time to modulate the IR LED for, in +/// microseconds. +/// @return Nr. of pulses actually sent. +/// @note +/// The ESP8266 has no good way to do hardware PWM, so we have to do it all +/// in software. There is a horrible kludge/brilliant hack to use the second +/// serial TX line to do fairly accurate hardware PWM, but it is only +/// available on a single specific GPIO and only available on some modules. +/// e.g. It's not available on the ESP-01 module. +/// Hence, for greater compatibility & choice, we don't use that method. +/// Ref: +/// https://www.analysir.com/blog/2017/01/29/updated-esp8266-nodemcu-backdoor-upwm-hack-for-ir-signals/ uint16_t IRsend::mark(uint16_t usec) { // Handle the simple case of no required frequency modulation. if (!modulation || _dutycycle >= 100) { @@ -206,31 +187,23 @@ uint16_t IRsend::mark(uint16_t usec) { return counter; } -// Turn the pin (LED) off for a given time. -// Sends an IR space for the specified number of microseconds. -// A space is no output, so the PWM output is disabled. -// -// Args: -// time: Time in microseconds (us). +/// Turn the pin (LED) off for a given time. +/// Sends an IR space for the specified number of microseconds. +/// A space is no output, so the PWM output is disabled. +/// @param[in] time Time in microseconds (us). void IRsend::space(uint32_t time) { ledOff(); if (time == 0) return; _delayMicroseconds(time); } -// Calculate & set any offsets to account for execution times. -// -// Args: -// hz: The frequency to calibrate at >= 1000Hz. Default is 38000Hz. -// -// Returns: -// The calculated period offset (in uSeconds) which is now in use. e.g. -5. -// -// Status: Stable / Working. -// -// NOTE: -// This will generate an 65535us mark() IR LED signal. -// This only needs to be called once, if at all. +/// Calculate & set any offsets to account for execution times during sending. +/// +/// @param[in] hz The frequency to calibrate at >= 1000Hz. Default is 38000Hz. +/// @return The calculated period offset (in uSeconds) which is now in use. +/// e.g. -5. +/// @note This will generate an 65535us mark() IR LED signal. +/// This only needs to be called once, if at all. int8_t IRsend::calibrate(uint16_t hz) { if (hz < 1000) // Were we given kHz? Supports the old call usage. hz *= 1000; @@ -259,18 +232,17 @@ int8_t IRsend::calibrate(uint16_t hz) { return periodOffset; } -// Generic method for sending data that is common to most protocols. -// Will send leading or trailing 0's if the nbits is larger than the number -// of bits in data. -// -// Args: -// onemark: Nr. of usecs for the led to be pulsed for a '1' bit. -// onespace: Nr. of usecs for the led to be fully off for a '1' bit. -// zeromark: Nr. of usecs for the led to be pulsed for a '0' bit. -// zerospace: Nr. of usecs for the led to be fully off for a '0' bit. -// data: The data to be transmitted. -// nbits: Nr. of bits of data to be sent. -// MSBfirst: Flag for bit transmission order. Defaults to MSB->LSB order. +/// Generic method for sending data that is common to most protocols. +/// Will send leading or trailing 0's if the nbits is larger than the number +/// of bits in data. +/// @param[in] onemark Nr. of usecs for the led to be pulsed for a '1' bit. +/// @param[in] onespace Nr. of usecs for the led to be fully off for a '1' bit. +/// @param[in] zeromark Nr. of usecs for the led to be pulsed for a '0' bit. +/// @param[in] zerospace Nr. of usecs for the led to be fully off for a '0' bit. +/// @param[in] data The data to be transmitted. +/// @param[in] nbits Nr. of bits of data to be sent. +/// @param[in] MSBfirst Flag for bit transmission order. +/// Defaults to MSB->LSB order. void IRsend::sendData(uint16_t onemark, uint32_t onespace, uint16_t zeromark, uint32_t zerospace, uint64_t data, uint16_t nbits, bool MSBfirst) { @@ -304,35 +276,34 @@ void IRsend::sendData(uint16_t onemark, uint32_t onespace, uint16_t zeromark, } } -// Generic method for sending simple protocol messages. -// Will send leading or trailing 0's if the nbits is larger than the number -// of bits in data. -// -// Args: -// headermark: Nr. of usecs for the led to be pulsed for the header mark. -// A value of 0 means no header mark. -// headerspace: Nr. of usecs for the led to be off after the header mark. -// A value of 0 means no header space. -// onemark: Nr. of usecs for the led to be pulsed for a '1' bit. -// onespace: Nr. of usecs for the led to be fully off for a '1' bit. -// zeromark: Nr. of usecs for the led to be pulsed for a '0' bit. -// zerospace: Nr. of usecs for the led to be fully off for a '0' bit. -// footermark: Nr. of usecs for the led to be pulsed for the footer mark. -// A value of 0 means no footer mark. -// gap: Nr. of usecs for the led to be off after the footer mark. -// This is effectively the gap between messages. -// A value of 0 means no gap space. -// data: The data to be transmitted. -// nbits: Nr. of bits of data to be sent. -// frequency: The frequency we want to modulate at. -// Assumes < 1000 means kHz otherwise it is in Hz. -// Most common value is 38000 or 38, for 38kHz. -// MSBfirst: Flag for bit transmission order. Defaults to MSB->LSB order. -// repeat: Nr. of extra times the message will be sent. -// e.g. 0 = 1 message sent, 1 = 1 initial + 1 repeat = 2 messages -// dutycycle: Percentage duty cycle of the LED. -// e.g. 25 = 25% = 1/4 on, 3/4 off. -// If you are not sure, try 50 percent. +/// Generic method for sending simple protocol messages. +/// Will send leading or trailing 0's if the nbits is larger than the number +/// of bits in data. +/// @param[in] headermark Nr. of usecs for the led to be pulsed for the header +/// mark. A value of 0 means no header mark. +/// @param[in] headerspace Nr. of usecs for the led to be off after the header +/// mark. A value of 0 means no header space. +/// @param[in] onemark Nr. of usecs for the led to be pulsed for a '1' bit. +/// @param[in] onespace Nr. of usecs for the led to be fully off for a '1' bit. +/// @param[in] zeromark Nr. of usecs for the led to be pulsed for a '0' bit. +/// @param[in] zerospace Nr. of usecs for the led to be fully off for a '0' bit. +/// @param[in] footermark Nr. of usecs for the led to be pulsed for the footer +/// mark. A value of 0 means no footer mark. +/// @param[in] gap Nr. of usecs for the led to be off after the footer mark. +/// This is effectively the gap between messages. +/// A value of 0 means no gap space. +/// @param[in] data The data to be transmitted. +/// @param[in] nbits Nr. of bits of data to be sent. +/// @param[in] frequency The frequency we want to modulate at. (Hz/kHz) +/// @param[in] MSBfirst Flag for bit transmission order. +/// Defaults to MSB->LSB order. +/// @param[in] repeat Nr. of extra times the message will be sent. +/// e.g. 0 = 1 message sent, 1 = 1 initial + 1 repeat = 2 messages +/// @param[in] dutycycle Percentage duty cycle of the LED. +/// e.g. 25 = 25% = 1/4 on, 3/4 off. +/// If you are not sure, try 50 percent. +/// @note Assumes a frequency < 1000 means kHz otherwise it is in Hz. +/// Most common value is 38000 or 38, for 38kHz. void IRsend::sendGeneric(const uint16_t headermark, const uint32_t headerspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, @@ -345,36 +316,36 @@ void IRsend::sendGeneric(const uint16_t headermark, const uint32_t headerspace, dutycycle); } -// Generic method for sending simple protocol messages. -// Will send leading or trailing 0's if the nbits is larger than the number -// of bits in data. -// -// Args: -// headermark: Nr. of usecs for the led to be pulsed for the header mark. -// A value of 0 means no header mark. -// headerspace: Nr. of usecs for the led to be off after the header mark. -// A value of 0 means no header space. -// onemark: Nr. of usecs for the led to be pulsed for a '1' bit. -// onespace: Nr. of usecs for the led to be fully off for a '1' bit. -// zeromark: Nr. of usecs for the led to be pulsed for a '0' bit. -// zerospace: Nr. of usecs for the led to be fully off for a '0' bit. -// footermark: Nr. of usecs for the led to be pulsed for the footer mark. -// A value of 0 means no footer mark. -// gap: Min. nr. of usecs for the led to be off after the footer mark. -// This is effectively the absolute minimum gap between messages. -// mesgtime: Min. nr. of usecs a single message needs to be. -// This is effectively the min. total length of a single message. -// data: The data to be transmitted. -// nbits: Nr. of bits of data to be sent. -// frequency: The frequency we want to modulate at. -// Assumes < 1000 means kHz otherwise it is in Hz. -// Most common value is 38000 or 38, for 38kHz. -// MSBfirst: Flag for bit transmission order. Defaults to MSB->LSB order. -// repeat: Nr. of extra times the message will be sent. -// e.g. 0 = 1 message sent, 1 = 1 initial + 1 repeat = 2 messages -// dutycycle: Percentage duty cycle of the LED. -// e.g. 25 = 25% = 1/4 on, 3/4 off. -// If you are not sure, try 50 percent. +/// Generic method for sending simple protocol messages. +/// Will send leading or trailing 0's if the nbits is larger than the number +/// of bits in data. +/// @param[in] headermark Nr. of usecs for the led to be pulsed for the header +/// mark. A value of 0 means no header mark. +/// @param[in] headerspace Nr. of usecs for the led to be off after the header +/// mark. A value of 0 means no header space. +/// @param[in] onemark Nr. of usecs for the led to be pulsed for a '1' bit. +/// @param[in] onespace Nr. of usecs for the led to be fully off for a '1' bit. +/// @param[in] zeromark Nr. of usecs for the led to be pulsed for a '0' bit. +/// @param[in] zerospace Nr. of usecs for the led to be fully off for a '0' bit. +/// @param[in] footermark Nr. of usecs for the led to be pulsed for the footer +/// mark. A value of 0 means no footer mark. +/// @param[in] gap Nr. of usecs for the led to be off after the footer mark. +/// This is effectively the gap between messages. +/// A value of 0 means no gap space. +/// @param[in] mesgtime Min. nr. of usecs a single message needs to be. +/// This is effectively the min. total length of a single message. +/// @param[in] data The data to be transmitted. +/// @param[in] nbits Nr. of bits of data to be sent. +/// @param[in] frequency The frequency we want to modulate at. (Hz/kHz) +/// @param[in] MSBfirst Flag for bit transmission order. +/// Defaults to MSB->LSB order. +/// @param[in] repeat Nr. of extra times the message will be sent. +/// e.g. 0 = 1 message sent, 1 = 1 initial + 1 repeat = 2 messages +/// @param[in] dutycycle Percentage duty cycle of the LED. +/// e.g. 25 = 25% = 1/4 on, 3/4 off. +/// If you are not sure, try 50 percent. +/// @note Assumes a frequency < 1000 means kHz otherwise it is in Hz. +/// Most common value is 38000 or 38, for 38kHz. void IRsend::sendGeneric(const uint16_t headermark, const uint32_t headerspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, @@ -409,33 +380,32 @@ void IRsend::sendGeneric(const uint16_t headermark, const uint32_t headerspace, } } -// Generic method for sending simple protocol messages. -// -// Args: -// headermark: Nr. of usecs for the led to be pulsed for the header mark. -// A value of 0 means no header mark. -// headerspace: Nr. of usecs for the led to be off after the header mark. -// A value of 0 means no header space. -// onemark: Nr. of usecs for the led to be pulsed for a '1' bit. -// onespace: Nr. of usecs for the led to be fully off for a '1' bit. -// zeromark: Nr. of usecs for the led to be pulsed for a '0' bit. -// zerospace: Nr. of usecs for the led to be fully off for a '0' bit. -// footermark: Nr. of usecs for the led to be pulsed for the footer mark. -// A value of 0 means no footer mark. -// gap: Nr. of usecs for the led to be off after the footer mark. -// This is effectively the gap between messages. -// A value of 0 means no gap space. -// dataptr: Pointer to the data to be transmitted. -// nbytes: Nr. of bytes of data to be sent. -// frequency: The frequency we want to modulate at. -// Assumes < 1000 means kHz otherwise it is in Hz. -// Most common value is 38000 or 38, for 38kHz. -// MSBfirst: Flag for bit transmission order. Defaults to MSB->LSB order. -// repeat: Nr. of extra times the message will be sent. -// e.g. 0 = 1 message sent, 1 = 1 initial + 1 repeat = 2 messages -// dutycycle: Percentage duty cycle of the LED. -// e.g. 25 = 25% = 1/4 on, 3/4 off. -// If you are not sure, try 50 percent. +/// Generic method for sending simple protocol messages. +/// @param[in] headermark Nr. of usecs for the led to be pulsed for the header +/// mark. A value of 0 means no header mark. +/// @param[in] headerspace Nr. of usecs for the led to be off after the header +/// mark. A value of 0 means no header space. +/// @param[in] onemark Nr. of usecs for the led to be pulsed for a '1' bit. +/// @param[in] onespace Nr. of usecs for the led to be fully off for a '1' bit. +/// @param[in] zeromark Nr. of usecs for the led to be pulsed for a '0' bit. +/// @param[in] zerospace Nr. of usecs for the led to be fully off for a '0' bit. +/// @param[in] footermark Nr. of usecs for the led to be pulsed for the footer +/// mark. A value of 0 means no footer mark. +/// @param[in] gap Nr. of usecs for the led to be off after the footer mark. +/// This is effectively the gap between messages. +/// A value of 0 means no gap space. +/// @param[in] dataptr Pointer to the data to be transmitted. +/// @param[in] nbytes Nr. of bytes of data to be sent. +/// @param[in] frequency The frequency we want to modulate at. (Hz/kHz) +/// @param[in] MSBfirst Flag for bit transmission order. +/// Defaults to MSB->LSB order. +/// @param[in] repeat Nr. of extra times the message will be sent. +/// e.g. 0 = 1 message sent, 1 = 1 initial + 1 repeat = 2 messages +/// @param[in] dutycycle Percentage duty cycle of the LED. +/// e.g. 25 = 25% = 1/4 on, 3/4 off. +/// If you are not sure, try 50 percent. +/// @note Assumes a frequency < 1000 means kHz otherwise it is in Hz. +/// Most common value is 38000 or 38, for 38kHz. void IRsend::sendGeneric(const uint16_t headermark, const uint32_t headerspace, const uint16_t onemark, const uint32_t onespace, const uint16_t zeromark, const uint32_t zerospace, @@ -462,16 +432,16 @@ void IRsend::sendGeneric(const uint16_t headermark, const uint32_t headerspace, } } -// Generic method for sending Manchester code data. -// Will send leading or trailing 0's if the nbits is larger than the number -// of bits in data. -// -// Args: -// half_period: Nr. of uSeconds for half the clock's period. (1/2 wavelength) -// data: The data to be transmitted. -// nbits: Nr. of bits of data to be sent. -// MSBfirst: Flag for bit transmission order. Defaults to MSB->LSB order. -// GEThomas: Use G.E. Thomas (true/default) or IEEE 802.3 (false). +/// Generic method for sending Manchester code data. +/// Will send leading or trailing 0's if the nbits is larger than the number +/// of bits in data. +/// @param[in] half_period Nr. of uSeconds for half the clock's period. +/// (1/2 wavelength) +/// @param[in] data The data to be transmitted. +/// @param[in] nbits Nr. of bits of data to be sent. +/// @param[in] MSBfirst Flag for bit transmission order. +/// Defaults to MSB->LSB order. +/// @param[in] GEThomas Use G.E. Thomas (true/default) or IEEE 802.3 (false). void IRsend::sendManchesterData(const uint16_t half_period, const uint64_t data, const uint16_t nbits, const bool MSBfirst, @@ -508,32 +478,31 @@ void IRsend::sendManchesterData(const uint16_t half_period, } } -// Generic method for sending Manchester code messages. -// Will send leading or trailing 0's if the nbits is larger than the number -// of bits in data. -// -// Args: -// headermark: Nr. of usecs for the led to be pulsed for the header mark. -// A value of 0 means no header mark. -// headerspace: Nr. of usecs for the led to be off after the header mark. -// A value of 0 means no header space. -// half_period: Nr. of uSeconds for half the clock's period. (1/2 wavelength) -// footermark: Nr. of usecs for the led to be pulsed for the footer mark. -// A value of 0 means no footer mark. -// gap: Min. nr. of usecs for the led to be off after the footer mark. -// This is effectively the absolute minimum gap between messages. -// data: The data to be transmitted. -// nbits: Nr. of bits of data to be sent. -// frequency: The frequency we want to modulate at. -// Assumes < 1000 means kHz otherwise it is in Hz. -// Most common value is 38000 or 38, for 38kHz. -// MSBfirst: Flag for bit transmission order. Defaults to MSB->LSB order. -// repeat: Nr. of extra times the message will be sent. -// e.g. 0 = 1 message sent, 1 = 1 initial + 1 repeat = 2 messages -// dutycycle: Percentage duty cycle of the LED. -// e.g. 25 = 25% = 1/4 on, 3/4 off. -// If you are not sure, try 50 percent. -// GEThomas: Use G.E. Thomas (true/default) or IEEE 802.3 (false). +/// Generic method for sending Manchester code messages. +/// Will send leading or trailing 0's if the nbits is larger than the number +/// @param[in] headermark Nr. of usecs for the led to be pulsed for the header +/// mark. A value of 0 means no header mark. +/// @param[in] headerspace Nr. of usecs for the led to be off after the header +/// mark. A value of 0 means no header space. +/// @param[in] half_period Nr. of uSeconds for half the clock's period. +/// (1/2 wavelength) +/// @param[in] footermark Nr. of usecs for the led to be pulsed for the footer +/// mark. A value of 0 means no footer mark. +/// @param[in] gap Min. nr. of usecs for the led to be off after the footer +/// mark. This is effectively the absolute minimum gap between messages. +/// @param[in] data The data to be transmitted. +/// @param[in] nbits Nr. of bits of data to be sent. +/// @param[in] frequency The frequency we want to modulate at. (Hz/kHz) +/// @param[in] MSBfirst Flag for bit transmission order. +/// Defaults to MSB->LSB order. +/// @param[in] repeat Nr. of extra times the message will be sent. +/// e.g. 0 = 1 message sent, 1 = 1 initial + 1 repeat = 2 messages +/// @param[in] dutycycle Percentage duty cycle of the LED. +/// e.g. 25 = 25% = 1/4 on, 3/4 off. +/// If you are not sure, try 50 percent. +/// @param[in] GEThomas Use G.E. Thomas (true/default) or IEEE 802.3 (false). +/// @note Assumes a frequency < 1000 means kHz otherwise it is in Hz. +/// Most common value is 38000 or 38, for 38kHz. void IRsend::sendManchester(const uint16_t headermark, const uint32_t headerspace, const uint16_t half_period, @@ -550,9 +519,6 @@ void IRsend::sendManchester(const uint16_t headermark, // Header if (headermark) mark(headermark); if (headerspace) space(headerspace); - // Data Marker/sync - // This guarantees a double width half_period. i.e. a Period or T2. - sendManchesterData(half_period, 0b01, 2, true, GEThomas); // Data sendManchesterData(half_period, data, nbits, MSBfirst, GEThomas); // Footer @@ -562,20 +528,14 @@ void IRsend::sendManchester(const uint16_t headermark, } #if SEND_RAW -// Send a raw IRremote message. -// -// Args: -// buf: An array of uint16_t's that has microseconds elements. -// len: Nr. of elements in the buf[] array. -// hz: Frequency to send the message at. (kHz < 1000; Hz >= 1000) -// -// Status: STABLE / Known working. -// -// Notes: -// Even elements are Mark times (On), Odd elements are Space times (Off). -// -// Ref: -// examples/IRrecvDumpV2/IRrecvDumpV2.ino +/// Send a raw IRremote message. +/// +/// @param[in] buf An array of uint16_t's that has microseconds elements. +/// @param[in] len Nr. of elements in the buf[] array. +/// @param[in] hz Frequency to send the message at. (kHz < 1000; Hz >= 1000) +/// @note Even elements are Mark times (On), Odd elements are Space times (Off). +/// Ref: +/// examples/IRrecvDumpV2/IRrecvDumpV2.ino (or later) void IRsend::sendRaw(const uint16_t buf[], const uint16_t len, const uint16_t hz) { // Set IR carrier frequency @@ -591,11 +551,9 @@ void IRsend::sendRaw(const uint16_t buf[], const uint16_t len, } #endif // SEND_RAW -// Get the minimum number of repeats for a given protocol. -// Args: -// protocol: Protocol number/type of the message you want to send. -// Returns: -// int16_t: The number of repeats required. +/// Get the minimum number of repeats for a given protocol. +/// @param[in] protocol Protocol number/type of the message you want to send. +/// @return The number of repeats required. uint16_t IRsend::minRepeats(const decode_type_t protocol) { switch (protocol) { // Single repeats @@ -604,16 +562,19 @@ uint16_t IRsend::minRepeats(const decode_type_t protocol) { case COOLIX: case GICABLE: case INAX: + case MIDEA24: case MITSUBISHI: case MITSUBISHI2: case MITSUBISHI_AC: + case MULTIBRACKETS: case SHERWOOD: - case SYMPHONY: case TOSHIBA_AC: return kSingleRepeat; // Special case AIRWELL: return kAirwellMinRepeats; + case CARRIER_AC40: + return kCarrierAc40MinRepeat; case DISH: return kDishMinRepeat; case EPSON: @@ -622,21 +583,24 @@ uint16_t IRsend::minRepeats(const decode_type_t protocol) { return kSonyMinRepeat; case SONY_38K: return kSonyMinRepeat + 1; + case SYMPHONY: + return kSymphonyDefaultRepeat; + case ZEPEAL: + return kZepealMinRepeat; default: return kNoRepeat; } } -// Get the default number of bits for a given protocol. -// Args: -// protocol: Protocol number/type you want the default nr. of bits for. -// Returns: -// int16_t: The number of bits. +/// Get the default number of bits for a given protocol. +/// @param[in] protocol Protocol number/type you want the default bit size for. +/// @return The number of bits. uint16_t IRsend::defaultBits(const decode_type_t protocol) { switch (protocol) { - case SYMPHONY: - return 11; + case MULTIBRACKETS: + return 8; case RC5: + case SYMPHONY: return 12; case LASERTAG: case RC5X: @@ -651,6 +615,7 @@ uint16_t IRsend::defaultBits(const decode_type_t protocol) { case LEGOPF: case MITSUBISHI: case MITSUBISHI2: + case ZEPEAL: return 16; case RC6: case SONY: @@ -658,13 +623,13 @@ uint16_t IRsend::defaultBits(const decode_type_t protocol) { return 20; case COOLIX: case INAX: + case MIDEA24: case NIKAI: case RCMM: return 24; case LG: case LG2: return 28; - case AIRWELL: case CARRIER_AC: case EPSON: case NEC: @@ -673,11 +638,17 @@ uint16_t IRsend::defaultBits(const decode_type_t protocol) { case SHERWOOD: case WHYNTER: return 32; + case AIRWELL: + return 34; case LUTRON: case TECO: return 35; case SAMSUNG36: return 36; + case CARRIER_AC40: + return kCarrierAc40Bits; // 40 + case DOSHISHA: + return kDoshishaBits; // 40 case SANYO_LC7461: return kSanyoLC7461Bits; // 42 case GOODWEATHER: @@ -688,10 +659,14 @@ uint16_t IRsend::defaultBits(const decode_type_t protocol) { case VESTEL_AC: return 56; case AMCOR: + case CARRIER_AC64: + case DELONGHI_AC: case PIONEER: return 64; case ARGO: return kArgoBits; + case CORONA_AC: + return kCoronaAcBits; case DAIKIN: return kDaikinBits; case DAIKIN128: @@ -722,8 +697,10 @@ uint16_t IRsend::defaultBits(const decode_type_t protocol) { return kHitachiAc1Bits; case HITACHI_AC2: return kHitachiAc2Bits; - case HITACHI_AC3: - return kHitachiAc3Bits; + case HITACHI_AC3: + return kHitachiAc3Bits; + case HITACHI_AC344: + return kHitachiAc344Bits; case HITACHI_AC424: return kHitachiAc424Bits; case KELVINATOR: @@ -762,18 +739,17 @@ uint16_t IRsend::defaultBits(const decode_type_t protocol) { } } -// Send a simple (up to 64 bits) IR message of a given type. -// An unknown/unsupported type will do nothing. -// Args: -// type: Protocol number/type of the message you want to send. -// data: The data you want to send (up to 64 bits). -// nbits: How many bits long the message is to be. -// repeat: How many repeats to do? -// Returns: -// bool: True if it is a type we can attempt to send, false if not. +/// Send a simple (up to 64 bits) IR message of a given type. +/// An unknown/unsupported type will send nothing. +/// @param[in] type Protocol number/type of the message you want to send. +/// @param[in] data The data you want to send (up to 64 bits). +/// @param[in] nbits How many bits long the message is to be. +/// @param[in] repeat How many repeats to do? +/// @return True if it is a type we can attempt to send, false if not. bool IRsend::send(const decode_type_t type, const uint64_t data, const uint16_t nbits, const uint16_t repeat) { - uint16_t min_repeat = std::max(IRsend::minRepeats(type), repeat); + uint16_t min_repeat __attribute__((unused)) = + std::max(IRsend::minRepeats(type), repeat); switch (type) { #if SEND_AIRWELL case AIRWELL: @@ -790,6 +766,16 @@ bool IRsend::send(const decode_type_t type, const uint64_t data, sendCarrierAC(data, nbits, min_repeat); break; #endif +#if SEND_CARRIER_AC40 + case CARRIER_AC40: + sendCarrierAC40(data, nbits, min_repeat); + break; +#endif // SEND_CARRIER_AC40 +#if SEND_CARRIER_AC64 + case CARRIER_AC64: + sendCarrierAC64(data, nbits, min_repeat); + break; +#endif // SEND_CARRIER_AC64 #if SEND_COOLIX case COOLIX: sendCOOLIX(data, nbits, min_repeat); @@ -800,6 +786,11 @@ bool IRsend::send(const decode_type_t type, const uint64_t data, sendDaikin64(data, nbits, min_repeat); break; #endif +#if SEND_DELONGHI_AC + case DELONGHI_AC: + sendDelonghiAc(data, nbits, min_repeat); + break; +#endif #if SEND_DENON case DENON: sendDenon(data, nbits, min_repeat); @@ -810,6 +801,11 @@ bool IRsend::send(const decode_type_t type, const uint64_t data, sendDISH(data, nbits, min_repeat); break; #endif +#if SEND_DOSHISHA + case DOSHISHA: + sendDoshisha(data, nbits, min_repeat); + break; +#endif #if SEND_EPSON case EPSON: sendEpson(data, nbits, min_repeat); @@ -872,7 +868,12 @@ bool IRsend::send(const decode_type_t type, const uint64_t data, case MIDEA: sendMidea(data, nbits, min_repeat); break; -#endif +#endif // SEND_MIDEA +#if SEND_MIDEA24 + case MIDEA24: + sendMidea24(data, nbits, min_repeat); + break; +#endif // SEND_MIDEA24 #if SEND_MITSUBISHI case MITSUBISHI: sendMitsubishi(data, nbits, min_repeat); @@ -883,6 +884,11 @@ bool IRsend::send(const decode_type_t type, const uint64_t data, sendMitsubishi2(data, nbits, min_repeat); break; #endif +#if SEND_MULTIBRACKETS + case MULTIBRACKETS: + sendMultibrackets(data, nbits, min_repeat); + break; +#endif #if SEND_NIKAI case NIKAI: sendNikai(data, nbits, min_repeat); @@ -972,6 +978,11 @@ bool IRsend::send(const decode_type_t type, const uint64_t data, case WHYNTER: sendWhynter(data, nbits, min_repeat); break; +#endif +#if SEND_ZEPEAL + case ZEPEAL: + sendZepeal(data, nbits, min_repeat); + break; #endif default: return false; @@ -979,15 +990,13 @@ bool IRsend::send(const decode_type_t type, const uint64_t data, return true; } -// Send a complex (>= 64 bits) IR message of a given type. -// An unknown/unsupported type will do nothing. -// Args: -// type: Protocol number/type of the message you want to send. -// state: A pointer to the array of bytes that make up the state[]. -// nbytes: How many bytes are in the state. -// Returns: -// bool: True if it is a type we can attempt to send, false if not. -bool IRsend::send(const decode_type_t type, const unsigned char *state, +/// Send a complex (>= 64 bits) IR message of a given type. +/// An unknown/unsupported type will send nothing. +/// @param[in] type Protocol number/type of the message you want to send. +/// @param[in] state A pointer to the array of bytes that make up the state[]. +/// @param[in] nbytes How many bytes are in the state. +/// @return True if it is a type we can attempt to send, false if not. +bool IRsend::send(const decode_type_t type, const uint8_t *state, const uint16_t nbytes) { switch (type) { #if SEND_AMCOR @@ -1000,6 +1009,11 @@ bool IRsend::send(const decode_type_t type, const unsigned char *state, sendArgo(state, nbytes); break; #endif // SEND_ARGO +#if SEND_CORONA_AC + case CORONA_AC: + sendCoronaAc(state, nbytes); + break; +#endif // SEND_ARGO #if SEND_DAIKIN case DAIKIN: sendDaikin(state, nbytes); @@ -1080,6 +1094,11 @@ bool IRsend::send(const decode_type_t type, const unsigned char *state, sendHitachiAc3(state, nbytes); break; #endif // SEND_HITACHI_AC3 +#if SEND_HITACHI_AC344 + case HITACHI_AC344: + sendHitachiAc344(state, nbytes); + break; +#endif // SEND_HITACHI_AC344 #if SEND_HITACHI_AC424 case HITACHI_AC424: sendHitachiAc424(state, nbytes); diff --git a/lib/IRremoteESP8266-2.7.5/src/IRsend.h b/lib/IRremoteESP8266-2.7.8/src/IRsend.h similarity index 83% rename from lib/IRremoteESP8266-2.7.5/src/IRsend.h rename to lib/IRremoteESP8266-2.7.8/src/IRsend.h index 8d5e6a862..fe206583f 100644 --- a/lib/IRremoteESP8266-2.7.5/src/IRsend.h +++ b/lib/IRremoteESP8266-2.7.8/src/IRsend.h @@ -40,8 +40,9 @@ const uint16_t kMaxAccurateUsecDelay = 16383; // Usecs to wait between messages we don't know the proper gap time. const uint32_t kDefaultMessageGap = 100000; - +/// Enumerators and Structures for the Common A/C API. namespace stdAc { + /// Common A/C settings for A/C operating modes. enum class opmode_t { kOff = -1, kAuto = 0, @@ -53,6 +54,7 @@ namespace stdAc { kLastOpmodeEnum = kFan, }; + /// Common A/C settings for Fan Speeds. enum class fanspeed_t { kAuto = 0, kMin = 1, @@ -64,6 +66,7 @@ namespace stdAc { kLastFanspeedEnum = kMax, }; + /// Common A/C settings for Vertical Swing. enum class swingv_t { kOff = -1, kAuto = 0, @@ -76,6 +79,7 @@ namespace stdAc { kLastSwingvEnum = kLowest, }; + /// Common A/C settings for Horizontal Swing. enum class swingh_t { kOff = -1, kAuto = 0, // a.k.a. On. @@ -89,7 +93,7 @@ namespace stdAc { kLastSwinghEnum = kWide, }; - // Structure to hold a common A/C state. + /// Structure to hold a common A/C state. typedef struct { decode_type_t protocol; int16_t model; @@ -112,7 +116,7 @@ namespace stdAc { } state_t; }; // namespace stdAc - +/// Fujitsu A/C model numbers enum fujitsu_ac_remote_model_t { ARRAH2E = 1, // (1) AR-RAH2E, AR-RAC1E, AR-RAE1E (Default) ARDB1, // (2) AR-DB1, AR-DL10 (AR-DL10 swing doesn't work) @@ -121,16 +125,19 @@ enum fujitsu_ac_remote_model_t { ARRY4, // (5) AR-RY4 (Same as AR-RAH2E but with clean & filter) }; +/// Gree A/C model numbers enum gree_ac_remote_model_t { YAW1F = 1, // (1) Ultimate, EKOKAI, RusClimate (Default) YBOFB, // (2) Green, YBOFB2, YAPOF3 }; +/// HITACHI_AC1 A/C model numbers enum hitachi_ac1_remote_model_t { R_LT0541_HTA_A = 1, // (1) R-LT0541-HTA Remote in "A" setting. (Default) R_LT0541_HTA_B, // (2) R-LT0541-HTA Remote in "B" setting. }; +/// Panasonic A/C model numbers enum panasonic_ac_remote_model_t { kPanasonicUnknown = 0, kPanasonicLke = 1, @@ -141,11 +148,13 @@ enum panasonic_ac_remote_model_t { kPanasonicRkr = 6, }; +/// Whirlpool A/C model numbers enum whirlpool_ac_remote_model_t { DG11J13A = 1, // DG11J1-04 too DG11J191, }; +/// LG A/C model numbers enum lg_ac_remote_model_t { GE6711AR2853M = 1, // (1) LG 28-bit Protocol (default) AKB75215403, // (2) LG2 28-bit Protocol @@ -153,6 +162,11 @@ enum lg_ac_remote_model_t { // Classes + +/// Class for sending all basic IR protocols. +/// @note Originally from https://github.com/shirriff/Arduino-IRremote/ +/// Updated by markszabo (https://github.com/crankyoldgit/IRremoteESP8266) for +/// sending IR code on ESP8266 class IRsend { public: explicit IRsend(uint16_t IRsendPin, bool inverted = false, @@ -204,9 +218,10 @@ class IRsend { static uint16_t defaultBits(const decode_type_t protocol); bool send(const decode_type_t type, const uint64_t data, const uint16_t nbits, const uint16_t repeat = kNoRepeat); - bool send(const decode_type_t type, const uint8_t state[], + bool send(const decode_type_t type, const uint8_t *state, const uint16_t nbytes); -#if (SEND_NEC || SEND_SHERWOOD || SEND_AIWA_RC_T501 || SEND_SANYO) +#if (SEND_NEC || SEND_SHERWOOD || SEND_AIWA_RC_T501 || SEND_SANYO || \ + SEND_MIDEA24) void sendNEC(uint64_t data, uint16_t nbits = kNECBits, uint16_t repeat = kNoRepeat); uint32_t encodeNEC(uint16_t address, uint16_t command); @@ -217,13 +232,13 @@ class IRsend { // Legacy use of this procedure was to only send a single code so call it with // repeat=0 for backward compatibility. As of v2.0 it defaults to sending // a Sony command that will be accepted be a device. - void sendSony(uint64_t data, uint16_t nbits = kSony20Bits, - uint16_t repeat = kSonyMinRepeat); - void sendSony38(uint64_t data, uint16_t nbits = kSony20Bits, - uint16_t repeat = kSonyMinRepeat + 1); - uint32_t encodeSony(uint16_t nbits, uint16_t command, uint16_t address, - uint16_t extended = 0); -#endif + void sendSony(const uint64_t data, const uint16_t nbits = kSony20Bits, + const uint16_t repeat = kSonyMinRepeat); + void sendSony38(const uint64_t data, const uint16_t nbits = kSony20Bits, + const uint16_t repeat = kSonyMinRepeat + 1); + uint32_t encodeSony(const uint16_t nbits, const uint16_t command, + const uint16_t address, const uint16_t extended = 0); +#endif // SEND_SONY #if SEND_SHERWOOD void sendSherwood(uint64_t data, uint16_t nbits = kSherwoodBits, uint16_t repeat = kSherwoodMinRepeat); @@ -275,8 +290,9 @@ class IRsend { #endif #if SEND_SANYO uint64_t encodeSanyoLC7461(uint16_t address, uint8_t command); - void sendSanyoLC7461(uint64_t data, uint16_t nbits = kSanyoLC7461Bits, - uint16_t repeat = kNoRepeat); + void sendSanyoLC7461(const uint64_t data, + const uint16_t nbits = kSanyoLC7461Bits, + const uint16_t repeat = kNoRepeat); #endif #if SEND_DISH // sendDISH() should typically be called with repeat=3 as DISH devices @@ -297,20 +313,20 @@ class IRsend { const uint8_t subdevice, const uint8_t function); #endif #if SEND_RC5 - void sendRC5(uint64_t data, uint16_t nbits = kRC5XBits, - uint16_t repeat = kNoRepeat); - uint16_t encodeRC5(uint8_t address, uint8_t command, - bool key_released = false); - uint16_t encodeRC5X(uint8_t address, uint8_t command, - bool key_released = false); - uint64_t toggleRC5(uint64_t data); + void sendRC5(const uint64_t data, uint16_t nbits = kRC5XBits, + const uint16_t repeat = kNoRepeat); + uint16_t encodeRC5(const uint8_t address, const uint8_t command, + const bool key_released = false); + uint16_t encodeRC5X(const uint8_t address, const uint8_t command, + const bool key_released = false); + uint64_t toggleRC5(const uint64_t data); #endif #if SEND_RC6 - void sendRC6(uint64_t data, uint16_t nbits = kRC6Mode0Bits, - uint16_t repeat = kNoRepeat); - uint64_t encodeRC6(uint32_t address, uint8_t command, - uint16_t mode = kRC6Mode0Bits); - uint64_t toggleRC6(uint64_t data, uint16_t nbits = kRC6Mode0Bits); + void sendRC6(const uint64_t data, const uint16_t nbits = kRC6Mode0Bits, + const uint16_t repeat = kNoRepeat); + uint64_t encodeRC6(const uint32_t address, const uint8_t command, + const uint16_t mode = kRC6Mode0Bits); + uint64_t toggleRC6(const uint64_t data, const uint16_t nbits = kRC6Mode0Bits); #endif #if SEND_RCMM void sendRCMM(uint64_t data, uint16_t nbits = kRCMMBits, @@ -321,8 +337,8 @@ class IRsend { uint16_t repeat = kCoolixDefaultRepeat); #endif #if SEND_WHYNTER - void sendWhynter(uint64_t data, uint16_t nbits = kWhynterBits, - uint16_t repeat = kNoRepeat); + void sendWhynter(const uint64_t data, const uint16_t nbits = kWhynterBits, + const uint16_t repeat = kNoRepeat); #endif #if SEND_MITSUBISHI void sendMitsubishi(uint64_t data, uint16_t nbits = kMitsubishiBits, @@ -452,11 +468,15 @@ class IRsend { #if SEND_MIDEA void sendMidea(uint64_t data, uint16_t nbits = kMideaBits, uint16_t repeat = kMideaMinRepeat); -#endif +#endif // SEND_MIDEA +#if SEND_MIDEA24 + void sendMidea24(const uint64_t data, const uint16_t nbits = kMidea24Bits, + const uint16_t repeat = kMidea24MinRepeat); +#endif // SEND_MIDEA24 #if SEND_MAGIQUEST - void sendMagiQuest(uint64_t data, uint16_t nbits = kMagiquestBits, - uint16_t repeat = kNoRepeat); - uint64_t encodeMagiQuest(uint32_t wand_id, uint16_t magnitude); + void sendMagiQuest(const uint64_t data, const uint16_t nbits = kMagiquestBits, + const uint16_t repeat = kNoRepeat); + uint64_t encodeMagiQuest(const uint32_t wand_id, const uint16_t magnitude); #endif #if SEND_LASERTAG void sendLasertag(uint64_t data, uint16_t nbits = kLasertagBits, @@ -466,6 +486,14 @@ class IRsend { void sendCarrierAC(uint64_t data, uint16_t nbits = kCarrierAcBits, uint16_t repeat = kCarrierAcMinRepeat); #endif +#if SEND_CARRIER_AC40 + void sendCarrierAC40(uint64_t data, uint16_t nbits = kCarrierAc40Bits, + uint16_t repeat = kCarrierAc40MinRepeat); +#endif +#if SEND_CARRIER_AC64 + void sendCarrierAC64(uint64_t data, uint16_t nbits = kCarrierAc64Bits, + uint16_t repeat = kCarrierAc64MinRepeat); +#endif #if (SEND_HAIER_AC || SEND_HAIER_AC_YRW02) void sendHaierAC(const unsigned char data[], const uint16_t nbytes = kHaierACStateLength, @@ -497,6 +525,11 @@ class IRsend { // different sizes const uint16_t repeat = kHitachiAcDefaultRepeat); #endif // SEND_HITACHI_AC3 +#if SEND_HITACHI_AC344 + void sendHitachiAc344(const unsigned char data[], + const uint16_t nbytes = kHitachiAc344StateLength, + const uint16_t repeat = kHitachiAcDefaultRepeat); +#endif // SEND_HITACHI_AC344 #if SEND_HITACHI_AC424 void sendHitachiAc424(const unsigned char data[], const uint16_t nbytes = kHitachiAc424StateLength, @@ -573,6 +606,30 @@ class IRsend { void sendAirwell(uint64_t data, uint16_t nbits = kAirwellBits, uint16_t repeat = kAirwellMinRepeats); #endif +#if SEND_DELONGHI_AC + void sendDelonghiAc(uint64_t data, uint16_t nbits = kDelonghiAcBits, + uint16_t repeat = kDelonghiAcDefaultRepeat); +#endif +#if SEND_DOSHISHA + void sendDoshisha(const uint64_t data, uint16_t nbits = kDoshishaBits, + const uint16_t repeat = kNoRepeat); + uint64_t encodeDoshisha(const uint8_t command, const uint8_t channel = 0); +#endif // SEND_DOSHISHA +#if SEND_MULTIBRACKETS + void sendMultibrackets(const uint64_t data, + const uint16_t nbits = kMultibracketsBits, + const uint16_t repeat = kMultibracketsDefaultRepeat); +#endif +#if SEND_CORONA_AC + void sendCoronaAc(const uint8_t data[], + const uint16_t nbytes = kCoronaAcStateLength, + const uint16_t repeat = kNoRepeat); +#endif // SEND_CORONA_AC +#if SEND_ZEPEAL + void sendZepeal(const uint64_t data, + const uint16_t nbits = kZepealBits, + const uint16_t repeat = kZepealMinRepeat); +#endif protected: #ifdef UNIT_TEST @@ -601,9 +658,9 @@ class IRsend { bool modulation; uint32_t calcUSecPeriod(uint32_t hz, bool use_offset = true); #if SEND_SONY - void _sendSony(uint64_t data, uint16_t nbits, - uint16_t repeat, uint16_t freq); -#endif + void _sendSony(const uint64_t data, const uint16_t nbits, + const uint16_t repeat, const uint16_t freq); +#endif // SEND_SONY }; #endif // IRSEND_H_ diff --git a/lib/IRremoteESP8266-2.7.8/src/IRtext.cpp b/lib/IRremoteESP8266-2.7.8/src/IRtext.cpp new file mode 100644 index 000000000..7af2ffd0b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/src/IRtext.cpp @@ -0,0 +1,268 @@ +// Copyright 2019-2020 - David Conran (@crankyoldgit) + +/// @file IRtext.cpp +/// @warning If you add or remove an entry in this file, you should run: +/// '../tools/generate_irtext_h.sh' to rebuild the `IRtext.h` file. + +#ifndef UNIT_TEST +#include +#endif // UNIT_TEST +#include "IRremoteESP8266.h" +#include "i18n.h" + +#ifndef PROGMEM +#define PROGMEM // Pretend we have the PROGMEM macro even if we really don't. +#endif + +// Common +const PROGMEM char* kUnknownStr = D_STR_UNKNOWN; ///< "Unknown" +const PROGMEM char* kProtocolStr = D_STR_PROTOCOL; ///< "Protocol" +const PROGMEM char* kPowerStr = D_STR_POWER; ///< "Power" +const PROGMEM char* kOnStr = D_STR_ON; ///< "On" +const PROGMEM char* kOffStr = D_STR_OFF; ///< "Off" +const PROGMEM char* kModeStr = D_STR_MODE; ///< "Mode" +const PROGMEM char* kToggleStr = D_STR_TOGGLE; ///< "Toggle" +const PROGMEM char* kTurboStr = D_STR_TURBO; ///< "Turbo" +const PROGMEM char* kSuperStr = D_STR_SUPER; ///< "Super" +const PROGMEM char* kSleepStr = D_STR_SLEEP; ///< "Sleep" +const PROGMEM char* kLightStr = D_STR_LIGHT; ///< "Light" +const PROGMEM char* kPowerfulStr = D_STR_POWERFUL; ///< "Powerful" +const PROGMEM char* kQuietStr = D_STR_QUIET; ///< "Quiet" +const PROGMEM char* kEconoStr = D_STR_ECONO; ///< "Econo" +const PROGMEM char* kSwingStr = D_STR_SWING; ///< "Swing" +const PROGMEM char* kSwingHStr = D_STR_SWINGH; ///< "SwingH" +const PROGMEM char* kSwingVStr = D_STR_SWINGV; ///< "SwingV" +const PROGMEM char* kBeepStr = D_STR_BEEP; ///< "Beep" +const PROGMEM char* kZoneFollowStr = D_STR_ZONEFOLLOW; ///< "Zone Follow" +const PROGMEM char* kFixedStr = D_STR_FIXED; ///< "Fixed" +const PROGMEM char* kMouldStr = D_STR_MOULD; ///< "Mould" +const PROGMEM char* kCleanStr = D_STR_CLEAN; ///< "Clean" +const PROGMEM char* kPurifyStr = D_STR_PURIFY; ///< "Purify" +const PROGMEM char* kTimerStr = D_STR_TIMER; ///< "Timer" +const PROGMEM char* kOnTimerStr = D_STR_ONTIMER; ///< "OnTimer" +const PROGMEM char* kOffTimerStr = D_STR_OFFTIMER; ///< "OffTimer" +const PROGMEM char* kClockStr = D_STR_CLOCK; ///< "Clock" +const PROGMEM char* kCommandStr = D_STR_COMMAND; ///< "Command" +const PROGMEM char* kXFanStr = D_STR_XFAN; ///< "XFan" +const PROGMEM char* kHealthStr = D_STR_HEALTH; ///< "Health" +const PROGMEM char* kModelStr = D_STR_MODEL; ///< "Model" +const PROGMEM char* kTempStr = D_STR_TEMP; ///< "Temp" +const PROGMEM char* kIFeelStr = D_STR_IFEEL; ///< "IFeel" +const PROGMEM char* kHumidStr = D_STR_HUMID; ///< "Humid" +const PROGMEM char* kSaveStr = D_STR_SAVE; ///< "Save" +const PROGMEM char* kEyeStr = D_STR_EYE; ///< "Eye" +const PROGMEM char* kFollowStr = D_STR_FOLLOW; ///< "Follow" +const PROGMEM char* kIonStr = D_STR_ION; ///< "Ion" +const PROGMEM char* kFreshStr = D_STR_FRESH; ///< "Fresh" +const PROGMEM char* kHoldStr = D_STR_HOLD; ///< "Hold" +const PROGMEM char* kButtonStr = D_STR_BUTTON; ///< "Button" +const PROGMEM char* k8CHeatStr = D_STR_8C_HEAT; ///< "8CHeat" +const PROGMEM char* kNightStr = D_STR_NIGHT; ///< "Night" +const PROGMEM char* kSilentStr = D_STR_SILENT; ///< "Silent" +const PROGMEM char* kFilterStr = D_STR_FILTER; ///< "Filter" +const PROGMEM char* k3DStr = D_STR_3D; ///< "3D" +const PROGMEM char* kCelsiusStr = D_STR_CELSIUS; ///< "Celsius" +const PROGMEM char* kTempUpStr = D_STR_TEMPUP; ///< "Temp Up" +const PROGMEM char* kTempDownStr = D_STR_TEMPDOWN; ///< "Temp Down" +const PROGMEM char* kStartStr = D_STR_START; ///< "Start" +const PROGMEM char* kStopStr = D_STR_STOP; ///< "Stop" +const PROGMEM char* kMoveStr = D_STR_MOVE; ///< "Move" +const PROGMEM char* kSetStr = D_STR_SET; ///< "Set" +const PROGMEM char* kCancelStr = D_STR_CANCEL; ///< "Cancel" +const PROGMEM char* kUpStr = D_STR_UP; ///< "Up" +const PROGMEM char* kDownStr = D_STR_DOWN; ///< "Down" +const PROGMEM char* kChangeStr = D_STR_CHANGE; ///< "Change" +const PROGMEM char* kComfortStr = D_STR_COMFORT; ///< "Comfort" +const PROGMEM char* kSensorStr = D_STR_SENSOR; ///< "Sensor" +const PROGMEM char* kWeeklyTimerStr = D_STR_WEEKLYTIMER; ///< "WeeklyTimer" +const PROGMEM char* kWifiStr = D_STR_WIFI; ///< "Wifi" +const PROGMEM char* kLastStr = D_STR_LAST; ///< "Last" +const PROGMEM char* kFastStr = D_STR_FAST; ///< "Fast" +const PROGMEM char* kSlowStr = D_STR_SLOW; ///< "Slow" +const PROGMEM char* kAirFlowStr = D_STR_AIRFLOW; ///< "Air Flow" +const PROGMEM char* kStepStr = D_STR_STEP; ///< "Step" +const PROGMEM char* kNAStr = D_STR_NA; ///< "N/A" +const PROGMEM char* kInsideStr = D_STR_INSIDE; ///< "Inside" +const PROGMEM char* kOutsideStr = D_STR_OUTSIDE; ///< "Outside" +const PROGMEM char* kLoudStr = D_STR_LOUD; ///< "Loud" +const PROGMEM char* kLowerStr = D_STR_LOWER; ///< "Lower" +const PROGMEM char* kUpperStr = D_STR_UPPER; ///< "Upper" +const PROGMEM char* kBreezeStr = D_STR_BREEZE; ///< "Breeze" +const PROGMEM char* kCirculateStr = D_STR_CIRCULATE; ///< "Circulate" +const PROGMEM char* kCeilingStr = D_STR_CEILING; ///< "Ceiling" +const PROGMEM char* kWallStr = D_STR_WALL; ///< "Wall" +const PROGMEM char* kRoomStr = D_STR_ROOM; ///< "Room" +const PROGMEM char* k6thSenseStr = D_STR_6THSENSE; ///< "6th Sense" + +const PROGMEM char* kAutoStr = D_STR_AUTO; ///< "Auto" +const PROGMEM char* kAutomaticStr = D_STR_AUTOMATIC; ///< "Automatic" +const PROGMEM char* kManualStr = D_STR_MANUAL; ///< "Manual" +const PROGMEM char* kCoolStr = D_STR_COOL; ///< "Cool" +const PROGMEM char* kHeatStr = D_STR_HEAT; ///< "Heat" +const PROGMEM char* kFanStr = D_STR_FAN; ///< "Fan" +const PROGMEM char* kDryStr = D_STR_DRY; ///< "Dry" +const PROGMEM char* kFanOnlyStr = D_STR_FANONLY; ///< "fan_only" + +const PROGMEM char* kMaxStr = D_STR_MAX; ///< "Max" +const PROGMEM char* kMaximumStr = D_STR_MAXIMUM; ///< "Maximum" +const PROGMEM char* kMinStr = D_STR_MIN; ///< "Min" +const PROGMEM char* kMinimumStr = D_STR_MINIMUM; ///< "Minimum" +const PROGMEM char* kMedStr = D_STR_MED; ///< "Med" +const PROGMEM char* kMediumStr = D_STR_MEDIUM; ///< "Medium" + +const PROGMEM char* kHighestStr = D_STR_HIGHEST; ///< "Highest" +const PROGMEM char* kHighStr = D_STR_HIGH; ///< "High" +const PROGMEM char* kHiStr = D_STR_HI; ///< "Hi" +const PROGMEM char* kMidStr = D_STR_MID; ///< "Mid" +const PROGMEM char* kMiddleStr = D_STR_MIDDLE; ///< "Middle" +const PROGMEM char* kLowStr = D_STR_LOW; ///< "Low" +const PROGMEM char* kLoStr = D_STR_LO; ///< "Lo" +const PROGMEM char* kLowestStr = D_STR_LOWEST; ///< "Lowest" +const PROGMEM char* kMaxRightStr = D_STR_MAXRIGHT; ///< "Max Right" +const PROGMEM char* kRightMaxStr = D_STR_RIGHTMAX_NOSPACE; ///< "RightMax" +const PROGMEM char* kRightStr = D_STR_RIGHT; ///< "Right" +const PROGMEM char* kLeftStr = D_STR_LEFT; ///< "Left" +const PROGMEM char* kMaxLeftStr = D_STR_MAXLEFT; ///< "Max Left" +const PROGMEM char* kLeftMaxStr = D_STR_LEFTMAX_NOSPACE; ///< "LeftMax" +const PROGMEM char* kWideStr = D_STR_WIDE; ///< "Wide" +const PROGMEM char* kCentreStr = D_STR_CENTRE; ///< "Centre" +const PROGMEM char* kTopStr = D_STR_TOP; ///< "Top" +const PROGMEM char* kBottomStr = D_STR_BOTTOM; ///< "Bottom" + +// Compound words/phrases/descriptions from pre-defined words. +const PROGMEM char* kEyeAutoStr = D_STR_EYEAUTO; ///< "Eye Auto" +const PROGMEM char* kLightToggleStr = D_STR_LIGHTTOGGLE; ///< "Light Toggle" +const PROGMEM char* kOutsideQuietStr = D_STR_OUTSIDEQUIET; ///< "Outside Quiet" +const PROGMEM char* kPowerToggleStr = D_STR_POWERTOGGLE; ///< "Power Toggle" +const PROGMEM char* kPowerButtonStr = D_STR_POWERBUTTON; ///< "Power Button" +const PROGMEM char* kPreviousPowerStr = D_STR_PREVIOUSPOWER; ///< +///< "Previous Power" +const PROGMEM char* kDisplayTempStr = D_STR_DISPLAYTEMP; ///< "Display Temp" +const PROGMEM char* kSensorTempStr = D_STR_SENSORTEMP; ///< "Sensor Temp" +const PROGMEM char* kSleepTimerStr = D_STR_SLEEP_TIMER; ///< "Sleep Timer" +const PROGMEM char* kSwingVModeStr = D_STR_SWINGVMODE; ///< "Swing(V) Mode" +const PROGMEM char* kSwingVToggleStr = D_STR_SWINGVTOGGLE; ///< +///< "Swing(V) Toggle" + +// Separators +char kTimeSep = D_CHR_TIME_SEP; ///< ':' +const PROGMEM char* kSpaceLBraceStr = D_STR_SPACELBRACE; ///< " (" +const PROGMEM char* kCommaSpaceStr = D_STR_COMMASPACE; ///< ", " +const PROGMEM char* kColonSpaceStr = D_STR_COLONSPACE; ///< ": " + +// IRutils +// - Time +const PROGMEM char* kDayStr = D_STR_DAY; ///< "Day" +const PROGMEM char* kDaysStr = D_STR_DAYS; ///< "Days" +const PROGMEM char* kHourStr = D_STR_HOUR; ///< "Hour" +const PROGMEM char* kHoursStr = D_STR_HOURS; ///< "Hours" +const PROGMEM char* kMinuteStr = D_STR_MINUTE; ///< "Minute" +const PROGMEM char* kMinutesStr = D_STR_MINUTES; ///< "Minutes" +const PROGMEM char* kSecondStr = D_STR_SECOND; ///< "Second" +const PROGMEM char* kSecondsStr = D_STR_SECONDS; ///< "Seconds" +const PROGMEM char* kNowStr = D_STR_NOW; ///< "Now" +const PROGMEM char* kThreeLetterDayOfWeekStr = D_STR_THREELETTERDAYS; ///< +///< "SunMonTueWedThuFriSat" +const PROGMEM char* kYesStr = D_STR_YES; ///< "Yes" +const PROGMEM char* kNoStr = D_STR_NO; ///< "No" +const PROGMEM char* kTrueStr = D_STR_TRUE; ///< "True" +const PROGMEM char* kFalseStr = D_STR_FALSE; ///< "False" + +const PROGMEM char* kRepeatStr = D_STR_REPEAT; ///< "Repeat" +const PROGMEM char* kCodeStr = D_STR_CODE; ///< "Code" +const PROGMEM char* kBitsStr = D_STR_BITS; ///< "Bits" + +// Protocol Names +// Needs to be in decode_type_t order. +const PROGMEM char *kAllProtocolNamesStr = + D_STR_UNUSED "\x0" + D_STR_RC5 "\x0" + D_STR_RC6 "\x0" + D_STR_NEC "\x0" + D_STR_SONY "\x0" + D_STR_PANASONIC "\x0" + D_STR_JVC "\x0" + D_STR_SAMSUNG "\x0" + D_STR_WHYNTER "\x0" + D_STR_AIWA_RC_T501 "\x0" + D_STR_LG "\x0" + D_STR_SANYO "\x0" + D_STR_MITSUBISHI "\x0" + D_STR_DISH "\x0" + D_STR_SHARP "\x0" + D_STR_COOLIX "\x0" + D_STR_DAIKIN "\x0" + D_STR_DENON "\x0" + D_STR_KELVINATOR "\x0" + D_STR_SHERWOOD "\x0" + D_STR_MITSUBISHI_AC "\x0" + D_STR_RCMM "\x0" + D_STR_SANYO_LC7461 "\x0" + D_STR_RC5X "\x0" + D_STR_GREE "\x0" + D_STR_PRONTO "\x0" + D_STR_NEC_LIKE "\x0" + D_STR_ARGO "\x0" + D_STR_TROTEC "\x0" + D_STR_NIKAI "\x0" + D_STR_RAW "\x0" + D_STR_GLOBALCACHE "\x0" + D_STR_TOSHIBA_AC "\x0" + D_STR_FUJITSU_AC "\x0" + D_STR_MIDEA "\x0" + D_STR_MAGIQUEST "\x0" + D_STR_LASERTAG "\x0" + D_STR_CARRIER_AC "\x0" + D_STR_HAIER_AC "\x0" + D_STR_MITSUBISHI2 "\x0" + D_STR_HITACHI_AC "\x0" + D_STR_HITACHI_AC1 "\x0" + D_STR_HITACHI_AC2 "\x0" + D_STR_GICABLE "\x0" + D_STR_HAIER_AC_YRW02 "\x0" + D_STR_WHIRLPOOL_AC "\x0" + D_STR_SAMSUNG_AC "\x0" + D_STR_LUTRON "\x0" + D_STR_ELECTRA_AC "\x0" + D_STR_PANASONIC_AC "\x0" + D_STR_PIONEER "\x0" + D_STR_LG2 "\x0" + D_STR_MWM "\x0" + D_STR_DAIKIN2 "\x0" + D_STR_VESTEL_AC "\x0" + D_STR_TECO "\x0" + D_STR_SAMSUNG36 "\x0" + D_STR_TCL112AC "\x0" + D_STR_LEGOPF "\x0" + D_STR_MITSUBISHI_HEAVY_88 "\x0" + D_STR_MITSUBISHI_HEAVY_152 "\x0" + D_STR_DAIKIN216 "\x0" + D_STR_SHARP_AC "\x0" + D_STR_GOODWEATHER "\x0" + D_STR_INAX "\x0" + D_STR_DAIKIN160 "\x0" + D_STR_NEOCLIMA "\x0" + D_STR_DAIKIN176 "\x0" + D_STR_DAIKIN128 "\x0" + D_STR_AMCOR "\x0" + D_STR_DAIKIN152 "\x0" + D_STR_MITSUBISHI136 "\x0" + D_STR_MITSUBISHI112 "\x0" + D_STR_HITACHI_AC424 "\x0" + D_STR_SONY_38K "\x0" + D_STR_EPSON "\x0" + D_STR_SYMPHONY "\x0" + D_STR_HITACHI_AC3 "\x0" + D_STR_DAIKIN64 "\x0" + D_STR_AIRWELL "\x0" + D_STR_DELONGHI_AC "\x0" + D_STR_DOSHISHA "\x0" + D_STR_MULTIBRACKETS "\x0" + D_STR_CARRIER_AC40 "\x0" + D_STR_CARRIER_AC64 "\x0" + D_STR_HITACHI_AC344 "\x0" + D_STR_CORONA_AC "\x0" + D_STR_MIDEA24 "\x0" + D_STR_ZEPEAL "\x0" + ///< New protocol strings should be added just above this line. + "\x0"; ///< This string requires double null termination. diff --git a/lib/IRremoteESP8266-2.7.5/src/IRtext.h b/lib/IRremoteESP8266-2.7.8/src/IRtext.h similarity index 97% rename from lib/IRremoteESP8266-2.7.5/src/IRtext.h rename to lib/IRremoteESP8266-2.7.8/src/IRtext.h index 13d2d400c..57ba2858b 100644 --- a/lib/IRremoteESP8266-2.7.5/src/IRtext.h +++ b/lib/IRremoteESP8266-2.7.8/src/IRtext.h @@ -17,6 +17,7 @@ extern const char* k3DStr; extern const char* k6thSenseStr; extern const char* k8CHeatStr; extern const char* kAirFlowStr; +extern const char *kAllProtocolNamesStr; extern const char* kAutomaticStr; extern const char* kAutoStr; extern const char* kBeepStr; @@ -40,6 +41,7 @@ extern const char* kCommaSpaceStr; extern const char* kCoolStr; extern const char* kDaysStr; extern const char* kDayStr; +extern const char* kDisplayTempStr; extern const char* kDownStr; extern const char* kDryStr; extern const char* kEconoStr; @@ -63,6 +65,7 @@ extern const char* kHoursStr; extern const char* kHourStr; extern const char* kHumidStr; extern const char* kIFeelStr; +extern const char* kInsideStr; extern const char* kIonStr; extern const char* kLastStr; extern const char* kLeftMaxStr; @@ -104,6 +107,7 @@ extern const char* kOutsideStr; extern const char* kPowerfulStr; extern const char* kPowerStr; extern const char* kPowerToggleStr; +extern const char* kPowerButtonStr; extern const char* kPreviousPowerStr; extern const char* kProtocolStr; extern const char* kPurifyStr; diff --git a/lib/IRremoteESP8266-2.7.5/src/IRtimer.cpp b/lib/IRremoteESP8266-2.7.8/src/IRtimer.cpp similarity index 69% rename from lib/IRremoteESP8266-2.7.5/src/IRtimer.cpp rename to lib/IRremoteESP8266-2.7.8/src/IRtimer.cpp index 4173d763b..edd98a2d7 100644 --- a/lib/IRremoteESP8266-2.7.5/src/IRtimer.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/IRtimer.cpp @@ -11,10 +11,10 @@ uint32_t _IRtimer_unittest_now = 0; uint32_t _TimerMs_unittest_now = 0; #endif // UNIT_TEST -// This class performs a simple time in useconds since instantiated. -// Handles when the system timer wraps around (once). +/// Class constructor. IRtimer::IRtimer() { reset(); } +/// Resets the IRtimer object. void IRtimer::reset() { #ifndef UNIT_TEST start = micros(); @@ -23,6 +23,8 @@ void IRtimer::reset() { #endif } +/// Calculate how many microseconds have elapsed since the timer was started. +/// @return Nr. of microseconds. uint32_t IRtimer::elapsed() { #ifndef UNIT_TEST uint32_t now = micros(); @@ -35,15 +37,17 @@ uint32_t IRtimer::elapsed() { return UINT32_MAX - start + now; // Has wrapped. } -// Only used in unit testing. +/// Add time to the timer to simulate elapsed time. +/// @param[in] usecs Nr. of uSeconds to be added. +/// @note Only used in unit testing. #ifdef UNIT_TEST void IRtimer::add(uint32_t usecs) { _IRtimer_unittest_now += usecs; } #endif // UNIT_TEST -// This class performs a simple time in milli-seoncds since instantiated. -// Handles when the system timer wraps around (once). +/// Class constructor. TimerMs::TimerMs() { reset(); } +/// Resets the TimerMs object. void TimerMs::reset() { #ifndef UNIT_TEST start = millis(); @@ -52,6 +56,8 @@ void TimerMs::reset() { #endif } +/// Calculate how many milliseconds have elapsed since the timer was started. +/// @return Nr. of milliseconds. uint32_t TimerMs::elapsed() { #ifndef UNIT_TEST uint32_t now = millis(); @@ -64,7 +70,9 @@ uint32_t TimerMs::elapsed() { return UINT32_MAX - start + now; // Has wrapped. } -// Only used in unit testing. +/// Add time to the timer to simulate elapsed time. +/// @param[in] msecs Nr. of mSeconds to be added. +/// @note Only used in unit testing. #ifdef UNIT_TEST void TimerMs::add(uint32_t msecs) { _IRtimer_unittest_now += msecs; } #endif // UNIT_TEST diff --git a/lib/IRremoteESP8266-2.7.5/src/IRtimer.h b/lib/IRremoteESP8266-2.7.8/src/IRtimer.h similarity index 65% rename from lib/IRremoteESP8266-2.7.5/src/IRtimer.h rename to lib/IRremoteESP8266-2.7.8/src/IRtimer.h index d00e1d0fa..1a2215fd5 100644 --- a/lib/IRremoteESP8266-2.7.5/src/IRtimer.h +++ b/lib/IRremoteESP8266-2.7.8/src/IRtimer.h @@ -7,6 +7,9 @@ #include // Classes + +/// This class performs a simple timer in useconds since instantiated. +/// @note Handles when the system timer wraps around (once). class IRtimer { public: IRtimer(); @@ -20,6 +23,8 @@ class IRtimer { uint32_t start; }; +/// This class performs a simple timer in milli-seoncds since instantiated. +/// @note Handles when the system timer wraps around (once). class TimerMs { public: TimerMs(); diff --git a/lib/IRremoteESP8266-2.7.5/src/IRutils.cpp b/lib/IRremoteESP8266-2.7.8/src/IRutils.cpp similarity index 54% rename from lib/IRremoteESP8266-2.7.5/src/IRutils.cpp rename to lib/IRremoteESP8266-2.7.8/src/IRutils.cpp index db9095143..9393fcf2d 100644 --- a/lib/IRremoteESP8266-2.7.5/src/IRutils.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/IRutils.cpp @@ -17,12 +17,10 @@ #include "IRsend.h" #include "IRtext.h" -// Reverse the order of the requested least significant nr. of bits. -// Args: -// input: Bit pattern/integer to reverse. -// nbits: Nr. of bits to reverse. -// Returns: -// The reversed bit pattern. +/// Reverse the order of the requested least significant nr. of bits. +/// @param[in] input Bit pattern/integer to reverse. +/// @param[in] nbits Nr. of bits to reverse. (LSB -> MSB) +/// @return The reversed bit pattern. uint64_t reverseBits(uint64_t input, uint16_t nbits) { if (nbits <= 1) return input; // Reversing <= 1 bits makes no change at all. // Cap the nr. of bits to rotate to the max nr. of bits in the input. @@ -37,15 +35,12 @@ uint64_t reverseBits(uint64_t input, uint16_t nbits) { return (input << nbits) | output; } -// Convert a uint64_t (unsigned long long) to a string. -// Arduino String/toInt/Serial.print() can't handle printing 64 bit values. -// -// Args: -// input: The value to print -// base: The output base. -// Returns: -// A string representation of the integer. -// Note: Based on Arduino's Print::printNumber() +/// Convert a uint64_t (unsigned long long) to a string. +/// Arduino String/toInt/Serial.print() can't handle printing 64 bit values. +/// @param[in] input The value to print +/// @param[in] base The output base. +/// @returns A String representation of the integer. +/// @note Based on Arduino's Print::printNumber() String uint64ToString(uint64_t input, uint8_t base) { String result = ""; // prevent issues if called with base <= 1 @@ -73,187 +68,27 @@ String uint64ToString(uint64_t input, uint8_t base) { } #ifdef ARDUINO -// Print a uint64_t/unsigned long long to the Serial port -// Serial.print() can't handle printing long longs. (uint64_t) -// -// Args: -// input: The value to print -// base: The output base. +/// Print a uint64_t/unsigned long long to the Serial port +/// Serial.print() can't handle printing long longs. (uint64_t) +/// @param[in] input The value to print +/// @param[in] base The output base. void serialPrintUint64(uint64_t input, uint8_t base) { Serial.print(uint64ToString(input, base)); } #endif -// Convert a C-style str to a decode_type_t -// -// Args: -// str: A C-style string containing a protocol name or number. -// Returns: -// A decode_type_t enum. +/// Convert a C-style string to a decode_type_t. +/// @param[in] str A C-style string containing a protocol name or number. +/// @return A decode_type_t enum. (decode_type_t::UNKNOWN if no match.) decode_type_t strToDecodeType(const char * const str) { - if (!strcasecmp(str, kUnknownStr)) - return decode_type_t::UNKNOWN; - else if (!strcasecmp(str, "UNUSED")) - return decode_type_t::UNUSED; - else if (!strcasecmp(str, "AIRWELL")) - return decode_type_t::AIRWELL; - else if (!strcasecmp(str, "AIWA_RC_T501")) - return decode_type_t::AIWA_RC_T501; - else if (!strcasecmp(str, "AMCOR")) - return decode_type_t::AMCOR; - else if (!strcasecmp(str, "ARGO")) - return decode_type_t::ARGO; - else if (!strcasecmp(str, "CARRIER_AC")) - return decode_type_t::CARRIER_AC; - else if (!strcasecmp(str, "COOLIX")) - return decode_type_t::COOLIX; - else if (!strcasecmp(str, "DAIKIN")) - return decode_type_t::DAIKIN; - else if (!strcasecmp(str, "DAIKIN128")) - return decode_type_t::DAIKIN128; - else if (!strcasecmp(str, "DAIKIN152")) - return decode_type_t::DAIKIN152; - else if (!strcasecmp(str, "DAIKIN160")) - return decode_type_t::DAIKIN160; - else if (!strcasecmp(str, "DAIKIN176")) - return decode_type_t::DAIKIN176; - else if (!strcasecmp(str, "DAIKIN2")) - return decode_type_t::DAIKIN2; - else if (!strcasecmp(str, "DAIKIN216")) - return decode_type_t::DAIKIN216; - else if (!strcasecmp(str, "DAIKIN64")) - return decode_type_t::DAIKIN64; - else if (!strcasecmp(str, "DENON")) - return decode_type_t::DENON; - else if (!strcasecmp(str, "DISH")) - return decode_type_t::DISH; - else if (!strcasecmp(str, "ELECTRA_AC")) - return decode_type_t::ELECTRA_AC; - else if (!strcasecmp(str, "EPSON")) - return decode_type_t::EPSON; - else if (!strcasecmp(str, "FUJITSU_AC")) - return decode_type_t::FUJITSU_AC; - else if (!strcasecmp(str, "GICABLE")) - return decode_type_t::GICABLE; - else if (!strcasecmp(str, "GLOBALCACHE")) - return decode_type_t::GLOBALCACHE; - else if (!strcasecmp(str, "GOODWEATHER")) - return decode_type_t::GOODWEATHER; - else if (!strcasecmp(str, "GREE")) - return decode_type_t::GREE; - else if (!strcasecmp(str, "HAIER_AC")) - return decode_type_t::HAIER_AC; - else if (!strcasecmp(str, "HAIER_AC_YRW02")) - return decode_type_t::HAIER_AC_YRW02; - else if (!strcasecmp(str, "HITACHI_AC")) - return decode_type_t::HITACHI_AC; - else if (!strcasecmp(str, "HITACHI_AC1")) - return decode_type_t::HITACHI_AC1; - else if (!strcasecmp(str, "HITACHI_AC2")) - return decode_type_t::HITACHI_AC2; - else if (!strcasecmp(str, "HITACHI_AC3")) - return decode_type_t::HITACHI_AC3; - else if (!strcasecmp(str, "HITACHI_AC424")) - return decode_type_t::HITACHI_AC424; - else if (!strcasecmp(str, "INAX")) - return decode_type_t::INAX; - else if (!strcasecmp(str, "JVC")) - return decode_type_t::JVC; - else if (!strcasecmp(str, "KELVINATOR")) - return decode_type_t::KELVINATOR; - else if (!strcasecmp(str, "LEGOPF")) - return decode_type_t::LEGOPF; - else if (!strcasecmp(str, "LG")) - return decode_type_t::LG; - else if (!strcasecmp(str, "LG2")) - return decode_type_t::LG2; - else if (!strcasecmp(str, "LASERTAG")) - return decode_type_t::LASERTAG; - else if (!strcasecmp(str, "LUTRON")) - return decode_type_t::LUTRON; - else if (!strcasecmp(str, "MAGIQUEST")) - return decode_type_t::MAGIQUEST; - else if (!strcasecmp(str, "MIDEA")) - return decode_type_t::MIDEA; - else if (!strcasecmp(str, "MITSUBISHI")) - return decode_type_t::MITSUBISHI; - else if (!strcasecmp(str, "MITSUBISHI2")) - return decode_type_t::MITSUBISHI2; - else if (!strcasecmp(str, "MITSUBISHI_AC")) - return decode_type_t::MITSUBISHI_AC; - else if (!strcasecmp(str, "MITSUBISHI136")) - return decode_type_t::MITSUBISHI136; - else if (!strcasecmp(str, "MITSUBISHI112")) - return decode_type_t::MITSUBISHI112; - else if (!strcasecmp(str, "MITSUBISHI_HEAVY_88")) - return decode_type_t::MITSUBISHI_HEAVY_88; - else if (!strcasecmp(str, "MITSUBISHI_HEAVY_152")) - return decode_type_t::MITSUBISHI_HEAVY_152; - else if (!strcasecmp(str, "MWM")) - return decode_type_t::MWM; - else if (!strcasecmp(str, "NEOCLIMA")) - return decode_type_t::NEOCLIMA; - else if (!strcasecmp(str, "NEC")) - return decode_type_t::NEC; - else if (!strcasecmp(str, "NEC_LIKE") || - !strcasecmp(str, "NEC (NON-STRICT)")) - return decode_type_t::NEC_LIKE; - else if (!strcasecmp(str, "NIKAI")) - return decode_type_t::NIKAI; - else if (!strcasecmp(str, "PANASONIC")) - return decode_type_t::PANASONIC; - else if (!strcasecmp(str, "PANASONIC_AC")) - return decode_type_t::PANASONIC_AC; - else if (!strcasecmp(str, "PIONEER")) - return decode_type_t::PIONEER; - else if (!strcasecmp(str, "PRONTO")) - return decode_type_t::PRONTO; - else if (!strcasecmp(str, "RAW")) - return decode_type_t::RAW; - else if (!strcasecmp(str, "RC5")) - return decode_type_t::RC5; - else if (!strcasecmp(str, "RC5X")) - return decode_type_t::RC5X; - else if (!strcasecmp(str, "RC6")) - return decode_type_t::RC6; - else if (!strcasecmp(str, "RCMM")) - return decode_type_t::RCMM; - else if (!strcasecmp(str, "SAMSUNG")) - return decode_type_t::SAMSUNG; - else if (!strcasecmp(str, "SAMSUNG36")) - return decode_type_t::SAMSUNG36; - else if (!strcasecmp(str, "SAMSUNG_AC")) - return decode_type_t::SAMSUNG_AC; - else if (!strcasecmp(str, "SANYO")) - return decode_type_t::SANYO; - else if (!strcasecmp(str, "SANYO_LC7461")) - return decode_type_t::SANYO_LC7461; - else if (!strcasecmp(str, "SHARP")) - return decode_type_t::SHARP; - else if (!strcasecmp(str, "SHARP_AC")) - return decode_type_t::SHARP_AC; - else if (!strcasecmp(str, "SHERWOOD")) - return decode_type_t::SHERWOOD; - else if (!strcasecmp(str, "SONY")) - return decode_type_t::SONY; - else if (!strcasecmp(str, "SONY_38K")) - return decode_type_t::SONY_38K; - else if (!strcasecmp(str, "SYMPHONY")) - return decode_type_t::SYMPHONY; - else if (!strcasecmp(str, "TCL112AC")) - return decode_type_t::TCL112AC; - else if (!strcasecmp(str, "TECO")) - return decode_type_t::TECO; - else if (!strcasecmp(str, "TOSHIBA_AC")) - return decode_type_t::TOSHIBA_AC; - else if (!strcasecmp(str, "TROTEC")) - return decode_type_t::TROTEC; - else if (!strcasecmp(str, "VESTEL_AC")) - return decode_type_t::VESTEL_AC; - else if (!strcasecmp(str, "WHIRLPOOL_AC")) - return decode_type_t::WHIRLPOOL_AC; - else if (!strcasecmp(str, "WHYNTER")) - return decode_type_t::WHYNTER; + const char *ptr = kAllProtocolNamesStr; + uint16_t length = strlen(ptr); + for (uint16_t i = 0; length; i++) { + if (!strcasecmp(str, ptr)) return (decode_type_t)i; + ptr += length + 1; + length = strlen(ptr); + } + // Handle integer values of the type by converting to a string and back again. decode_type_t result = strToDecodeType( typeToString((decode_type_t)atoi(str)).c_str()); @@ -263,259 +98,23 @@ decode_type_t strToDecodeType(const char * const str) { return decode_type_t::UNKNOWN; } -// Convert a protocol type (enum etc) to a human readable string. -// Args: -// protocol: Nr. (enum) of the protocol. -// isRepeat: A flag indicating if it is a repeat message of the protocol. -// Returns: -// A string containing the protocol name. +/// Convert a protocol type (enum etc) to a human readable string. +/// @param[in] protocol Nr. (enum) of the protocol. +/// @param[in] isRepeat A flag indicating if it is a repeat message. +/// @return A String containing the protocol name. kUnknownStr if no match. String typeToString(const decode_type_t protocol, const bool isRepeat) { String result = ""; - switch (protocol) { - case UNUSED: - result = F("UNUSED"); - break; - case AIRWELL: - result = F("AIRWELL"); - break; - case AIWA_RC_T501: - result = F("AIWA_RC_T501"); - break; - case AMCOR: - result = F("AMCOR"); - break; - case ARGO: - result = F("ARGO"); - break; - case CARRIER_AC: - result = F("CARRIER_AC"); - break; - case COOLIX: - result = F("COOLIX"); - break; - case DAIKIN: - result = F("DAIKIN"); - break; - case DAIKIN128: - result = F("DAIKIN128"); - break; - case DAIKIN152: - result = F("DAIKIN152"); - break; - case DAIKIN160: - result = F("DAIKIN160"); - break; - case DAIKIN176: - result = F("DAIKIN176"); - break; - case DAIKIN2: - result = F("DAIKIN2"); - break; - case DAIKIN216: - result = F("DAIKIN216"); - break; - case DAIKIN64: - result = F("DAIKIN64"); - break; - case DENON: - result = F("DENON"); - break; - case DISH: - result = F("DISH"); - break; - case ELECTRA_AC: - result = F("ELECTRA_AC"); - break; - case EPSON: - result = F("EPSON"); - break; - case FUJITSU_AC: - result = F("FUJITSU_AC"); - break; - case GICABLE: - result = F("GICABLE"); - break; - case GLOBALCACHE: - result = F("GLOBALCACHE"); - break; - case GOODWEATHER: - result = F("GOODWEATHER"); - break; - case GREE: - result = F("GREE"); - break; - case HAIER_AC: - result = F("HAIER_AC"); - break; - case HAIER_AC_YRW02: - result = F("HAIER_AC_YRW02"); - break; - case HITACHI_AC: - result = F("HITACHI_AC"); - break; - case HITACHI_AC1: - result = F("HITACHI_AC1"); - break; - case HITACHI_AC2: - result = F("HITACHI_AC2"); - break; - case HITACHI_AC3: - result = F("HITACHI_AC3"); - break; - case HITACHI_AC424: - result = F("HITACHI_AC424"); - break; - case INAX: - result = F("INAX"); - break; - case JVC: - result = F("JVC"); - break; - case KELVINATOR: - result = F("KELVINATOR"); - break; - case LEGOPF: - result = F("LEGOPF"); - break; - case LG: - result = F("LG"); - break; - case LG2: - result = F("LG2"); - break; - case LASERTAG: - result = F("LASERTAG"); - break; - case LUTRON: - result = F("LUTRON"); - break; - case MAGIQUEST: - result = F("MAGIQUEST"); - break; - case MIDEA: - result = F("MIDEA"); - break; - case MITSUBISHI: - result = F("MITSUBISHI"); - break; - case MITSUBISHI2: - result = F("MITSUBISHI2"); - break; - case MITSUBISHI_AC: - result = F("MITSUBISHI_AC"); - break; - case MITSUBISHI136: - result = F("MITSUBISHI136"); - break; - case MITSUBISHI112: - result = F("MITSUBISHI112"); - break; - case MITSUBISHI_HEAVY_88: - result = F("MITSUBISHI_HEAVY_88"); - break; - case MITSUBISHI_HEAVY_152: - result = F("MITSUBISHI_HEAVY_152"); - break; - case MWM: - result = F("MWM"); - break; - case NEOCLIMA: - result = F("NEOCLIMA"); - break; - case NEC: - result = F("NEC"); - break; - case NEC_LIKE: - result = F("NEC (non-strict)"); - break; - case NIKAI: - result = F("NIKAI"); - break; - case PANASONIC: - result = F("PANASONIC"); - break; - case PANASONIC_AC: - result = F("PANASONIC_AC"); - break; - case PIONEER: - result = F("PIONEER"); - break; - case PRONTO: - result = F("PRONTO"); - break; - case RAW: - result = F("RAW"); - break; - case RC5: - result = F("RC5"); - break; - case RC5X: - result = F("RC5X"); - break; - case RC6: - result = F("RC6"); - break; - case RCMM: - result = F("RCMM"); - break; - case SAMSUNG: - result = F("SAMSUNG"); - break; - case SAMSUNG36: - result = F("SAMSUNG36"); - break; - case SAMSUNG_AC: - result = F("SAMSUNG_AC"); - break; - case SANYO: - result = F("SANYO"); - break; - case SANYO_LC7461: - result = F("SANYO_LC7461"); - break; - case SHARP: - result = F("SHARP"); - break; - case SHARP_AC: - result = F("SHARP_AC"); - break; - case SHERWOOD: - result = F("SHERWOOD"); - break; - case SONY: - result = F("SONY"); - break; - case SONY_38K: - result = F("SONY_38K"); - break; - case SYMPHONY: - result = F("SYMPHONY"); - break; - case TCL112AC: - result = F("TCL112AC"); - break; - case TECO: - result = F("TECO"); - break; - case TOSHIBA_AC: - result = F("TOSHIBA_AC"); - break; - case TROTEC: - result = F("TROTEC"); - break; - case VESTEL_AC: - result = F("VESTEL_AC"); - break; - case WHIRLPOOL_AC: - result = F("WHIRLPOOL_AC"); - break; - case WHYNTER: - result = F("WHYNTER"); - break; - case UNKNOWN: - default: - result = kUnknownStr; - break; + const char *ptr = kAllProtocolNamesStr; + if (protocol > kLastDecodeType || protocol == decode_type_t::UNKNOWN) { + result = kUnknownStr; + } else { + for (uint16_t i = 0; i <= protocol && strlen(ptr); i++) { + if (i == protocol) { + result = ptr; + break; + } + ptr += strlen(ptr) + 1; + } } if (isRepeat) { result += kSpaceLBraceStr; @@ -525,11 +124,15 @@ String typeToString(const decode_type_t protocol, const bool isRepeat) { return result; } -// Does the given protocol use a complex state as part of the decode? +/// Does the given protocol use a complex state as part of the decode? +/// @param[in] protocol The decode_type_t protocol we are enquiring about. +/// @return True if the protocol uses a state array. False if just an integer. bool hasACState(const decode_type_t protocol) { switch (protocol) { + // This is keept sorted by name case AMCOR: case ARGO: + case CORONA_AC: case DAIKIN: case DAIKIN128: case DAIKIN152: @@ -546,6 +149,7 @@ bool hasACState(const decode_type_t protocol) { case HITACHI_AC1: case HITACHI_AC2: case HITACHI_AC3: + case HITACHI_AC344: case HITACHI_AC424: case KELVINATOR: case MITSUBISHI136: @@ -568,12 +172,10 @@ bool hasACState(const decode_type_t protocol) { } } -// Return the corrected length of a 'raw' format array structure -// after over-large values are converted into multiple entries. -// Args: -// results: A ptr to a decode result. -// Returns: -// A uint16_t containing the length. +/// Return the corrected length of a 'raw' format array structure +/// after over-large values are converted into multiple entries. +/// @param[in] results A ptr to a decode_results structure. +/// @return The corrected length. uint16_t getCorrectedRawLength(const decode_results * const results) { uint16_t extended_length = results->rawlen - 1; for (uint16_t i = 0; i < results->rawlen - 1; i++) { @@ -584,8 +186,10 @@ uint16_t getCorrectedRawLength(const decode_results * const results) { return extended_length; } -// Return a string containing the key values of a decode_results structure -// in a C/C++ code style format. +/// Return a String containing the key values of a decode_results structure +/// in a C/C++ code style format. +/// @param[in] results A ptr to a decode_results structure. +/// @return A String containing the code-ified result. String resultToSourceCode(const decode_results * const results) { String output = ""; // Reserve some space for the string to reduce heap fragmentation. @@ -663,8 +267,10 @@ String resultToSourceCode(const decode_results * const results) { return output; } -// Dump out the decode_results structure. -// +/// Dump out the decode_results structure. +/// @param[in] results A ptr to a decode_results structure. +/// @return A String containing the legacy information format. +/// @deprecated This is only for those that want this legacy format. String resultToTimingInfo(const decode_results * const results) { String output = ""; String value = ""; @@ -692,8 +298,9 @@ String resultToTimingInfo(const decode_results * const results) { return output; } -// Convert the decode_results structure's value/state to simple hexadecimal. -// +/// Convert the decode_results structure's value/state to simple hexadecimal. +/// @param[in] result A ptr to a decode_results structure. +/// @return A String containing the output. String resultToHexidecimal(const decode_results * const result) { String output = F("0x"); // Reserve some space for the string to reduce heap fragmentation. @@ -711,8 +318,9 @@ String resultToHexidecimal(const decode_results * const result) { return output; } -// Dump out the decode_results structure. -// +/// Dump out the decode_results structure into a human readable format. +/// @param[in] results A ptr to a decode_results structure. +/// @return A String containing the output. String resultToHumanReadableBasic(const decode_results * const results) { String output = ""; // Reserve some space for the string to reduce heap fragmentation. @@ -735,13 +343,11 @@ String resultToHumanReadableBasic(const decode_results * const results) { return output; } -// Convert a decode_results into an array suitable for `sendRaw()`. -// Args: -// decode: A pointer to an IR decode_results structure that contains a mesg. -// Returns: -// A pointer to a dynamically allocated uint16_t sendRaw compatible array. -// Note: -// Result needs to be delete[]'ed/free()'ed (deallocated) after use by caller. +/// Convert a decode_results into an array suitable for `sendRaw()`. +/// @param[in] decode A ptr to a decode_results structure that contains a mesg. +/// @return A PTR to a dynamically allocated uint16_t sendRaw compatible array. +/// @note The returned array needs to be delete[]'ed/free()'ed (deallocated) +/// after use by caller. uint16_t* resultToRawArray(const decode_results * const decode) { uint16_t *result = new uint16_t[getCorrectedRawLength(decode)]; if (result != NULL) { // The memory was allocated successfully. @@ -760,6 +366,12 @@ uint16_t* resultToRawArray(const decode_results * const decode) { return result; } +/// Sum all the bytes of an array and return the least significant 8-bits of +/// the result. +/// @param[in] start A ptr to the start of the byte array to calculate over. +/// @param[in] length How many bytes to use in the calculation. +/// @param[in] init Starting value of the calculation to use. (Default is 0) +/// @return The 8-bit calculated result of all the bytes and init value. uint8_t sumBytes(const uint8_t * const start, const uint16_t length, const uint8_t init) { uint8_t checksum = init; @@ -768,6 +380,11 @@ uint8_t sumBytes(const uint8_t * const start, const uint16_t length, return checksum; } +/// Calculate a rolling XOR of all the bytes of an array. +/// @param[in] start A ptr to the start of the byte array to calculate over. +/// @param[in] length How many bytes to use in the calculation. +/// @param[in] init Starting value of the calculation to use. (Default is 0) +/// @return The 8-bit calculated result of all the bytes and init value. uint8_t xorBytes(const uint8_t * const start, const uint16_t length, const uint8_t init) { uint8_t checksum = init; @@ -776,14 +393,12 @@ uint8_t xorBytes(const uint8_t * const start, const uint16_t length, return checksum; } -// Count the number of bits of a certain type. -// Args: -// start: Ptr to the start of data to count bits in. -// length: How many bytes to count. -// ones: Count the binary 1 bits. False for counting the 0 bits. -// init: Start the counting from this value. -// Returns: -// Nr. of bits found. +/// Count the number of bits of a certain type in an array. +/// @param[in] start A ptr to the start of the byte array to calculate over. +/// @param[in] length How many bytes to use in the calculation. +/// @param[in] ones Count the binary nr of `1` bits. False is count the `0`s. +/// @param[in] init Starting value of the calculation to use. (Default is 0) +/// @return The nr. of bits found of the given type found in the array. uint16_t countBits(const uint8_t * const start, const uint16_t length, const bool ones, const uint16_t init) { uint16_t count = init; @@ -798,14 +413,12 @@ uint16_t countBits(const uint8_t * const start, const uint16_t length, return (length * 8) - count; } -// Count the number of bits of a certain type. -// Args: -// data: The value you want bits counted for, starting from the LSB. -// length: How many bits to count. -// ones: Count the binary 1 bits. False for counting the 0 bits. -// init: Start the counting from this value. -// Returns: -// Nr. of bits found. +/// Count the number of bits of a certain type in an Integer. +/// @param[in] data The value you want bits counted for. Starting from the LSB. +/// @param[in] length How many bits to use in the calculation? Starts at the LSB +/// @param[in] ones Count the binary nr of `1` bits. False is count the `0`s. +/// @param[in] init Starting value of the calculation to use. (Default is 0) +/// @return The nr. of bits found of the given type found in the Integer. uint16_t countBits(const uint64_t data, const uint8_t length, const bool ones, const uint16_t init) { uint16_t count = init; @@ -819,6 +432,10 @@ uint16_t countBits(const uint64_t data, const uint8_t length, const bool ones, return length - count; } +/// Invert/Flip the bits in an Integer. +/// @param[in] data The Integer that will be inverted. +/// @param[in] nbits How many bits are to be inverted. Starting from the LSB. +/// @return An Integer with the appropriate bits inverted/flipped. uint64_t invertBits(const uint64_t data, const uint16_t nbits) { // No change if we are asked to invert no bits. if (nbits == 0) return data; @@ -829,11 +446,19 @@ uint64_t invertBits(const uint64_t data, const uint16_t nbits) { return (result & ((1ULL << nbits) - 1)); } +/// Convert degrees Celsius to degrees Fahrenheit. float celsiusToFahrenheit(const float deg) { return (deg * 9.0) / 5.0 + 32.0; } +/// Convert degrees Fahrenheit to degrees Celsius. float fahrenheitToCelsius(const float deg) { return (deg - 32.0) * 5.0 / 9.0; } namespace irutils { + /// Create a String with a colon separated "label: value" pair suitable for + /// Humans. + /// @param[in] value The value to come after the label. + /// @param[in] label The label to precede the value. + /// @param[in] precomma Should the output string start with ", " or not? + /// @return The resulting String. String addLabeledString(const String value, const String label, const bool precomma) { String result = ""; @@ -843,16 +468,33 @@ namespace irutils { return result + value; } + /// Create a String with a colon separated flag suitable for Humans. + /// e.g. "Power: On" + /// @param[in] value The value to come after the label. + /// @param[in] label The label to precede the value. + /// @param[in] precomma Should the output string start with ", " or not? + /// @return The resulting String. String addBoolToString(const bool value, const String label, const bool precomma) { return addLabeledString((value ? kOnStr : kOffStr), label, precomma); } + /// Create a String with a colon separated labeled Integer suitable for + /// Humans. + /// e.g. "Foo: 23" + /// @param[in] value The value to come after the label. + /// @param[in] label The label to precede the value. + /// @param[in] precomma Should the output string start with ", " or not? + /// @return The resulting String. String addIntToString(const uint16_t value, const String label, const bool precomma) { return addLabeledString(uint64ToString(value), label, precomma); } + /// Generate the model string for a given Protocol/Model pair. + /// @param[in] protocol The IR protocol. + /// @param[in] model The model number for that protocol. + /// @return The resulting String. String modelToStr(const decode_type_t protocol, const int16_t model) { switch (protocol) { case decode_type_t::FUJITSU_AC: @@ -911,6 +553,12 @@ namespace irutils { } } + /// Create a String of human output for a given protocol model number. + /// e.g. "Model: JKE" + /// @param[in] protocol The IR protocol. + /// @param[in] model The model number for that protocol. + /// @param[in] precomma Should the output string start with ", " or not? + /// @return The resulting String. String addModelToString(const decode_type_t protocol, const int16_t model, const bool precomma) { String result = addIntToString(model, kModelStr, precomma); @@ -919,6 +567,13 @@ namespace irutils { return result + ')'; } + /// Create a String of human output for a given temperature. + /// e.g. "Temp: 25C" + /// @param[in] degrees The temperature in degrees. + /// @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? + /// @return The resulting String. String addTempToString(const uint16_t degrees, const bool celsius, const bool precomma) { String result = addIntToString(degrees, kTempStr, precomma); @@ -926,6 +581,15 @@ namespace irutils { return result; } + /// Create a String of human output for the given operating mode. + /// e.g. "Mode: 1 (Cool)" + /// @param[in] mode The operating mode to display. + /// @param[in] automatic The numeric value for Auto mode. + /// @param[in] cool The numeric value for Cool mode. + /// @param[in] heat The numeric value for Heat mode. + /// @param[in] dry The numeric value for Dry mode. + /// @param[in] fan The numeric value for Fan mode. + /// @return The resulting String. 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) { @@ -941,6 +605,14 @@ namespace irutils { return result + ')'; } + /// Create a String of the 3-letter day of the week from a numerical day of + /// the week. e.g. "Day: 1 (Mon)" + /// @param[in] day_of_week A numerical version of the sequential day of the + /// week. e.g. Saturday = 7 etc. + /// @param[in] offset Days to offset by. + /// e.g. For different day starting the week. + /// @param[in] precomma Should the output string start with ", " or not? + /// @return The resulting String. String addDayToString(const uint8_t day_of_week, const int8_t offset, const bool precomma) { String result = addIntToString(day_of_week, kDayStr, precomma); @@ -958,6 +630,15 @@ namespace irutils { return result + ')'; } + /// 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] 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. + /// @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) { @@ -973,11 +654,9 @@ namespace irutils { return result + ')'; } - // Escape any special HTML (unsafe) characters in a string. e.g. anti-XSS. - // Args: - // unescaped: A string containing text to make HTML safe. - // Returns: - // A string that is HTML safe. + /// 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. String htmlEscape(const String unescaped) { String result = ""; uint16_t ulen = unescaped.length(); @@ -986,55 +665,30 @@ namespace irutils { char c = unescaped[i]; switch (c) { // ';!-"<>=&#{}() are all unsafe. - case '\'': - result += F("'"); - break; - case ';': - result += F(";"); - break; - case '!': - result += F("!"); - break; - case '-': - result += F("‐"); - break; - case '\"': - result += F("""); - break; - case '<': - result += F("<"); - break; - case '>': - result += F(">"); - break; - case '=': - result += F("&#equals;"); - break; - case '&': - result += F("&"); - break; - case '#': - result += F("#"); - break; - case '{': - result += F("{"); - break; - case '}': - result += F("}"); - break; - case '(': - result += F("("); - break; - case ')': - result += F(")"); - break; - default: - result += c; + case '\'': result += F("'"); break; + case ';': result += F(";"); break; + case '!': result += F("!"); break; + case '-': result += F("‐"); break; + case '\"': result += F("""); break; + case '<': result += F("<"); break; + case '>': result += F(">"); break; + case '=': result += F("&#equals;"); break; + case '&': result += F("&"); break; + case '#': result += F("#"); break; + case '{': result += F("{"); break; + case '}': result += F("}"); break; + case '(': result += F("("); break; + case ')': result += F(")"); break; + default: result += c; } } return result; } + /// Convert a nr. of milliSeconds into a Human-readable string. + /// e.g. "1 Day 6 Hours 34 Minutes 17 Seconds" + /// @param[in] msecs Nr. of milliSeconds (ms). + /// @return A human readable string. String msToString(uint32_t const msecs) { uint32_t totalseconds = msecs / 1000; if (totalseconds == 0) return kNowStr; @@ -1067,6 +721,10 @@ namespace irutils { return result; } + /// Convert a nr. of minutes into a 24h clock format Human-readable string. + /// e.g. "23:59" + /// @param[in] mins Nr. of Minutes. + /// @return A human readable string. String minsToString(const uint16_t mins) { String result = ""; result.reserve(5); // 23:59 is the typical worst case. @@ -1077,13 +735,11 @@ namespace irutils { return result; } - // Sum all the nibbles together in a series of bytes. - // Args: - // start: PTR to the start of the bytes. - // length: Nr of bytes to sum the nibbles of. - // init: Starting value of the sum. - // Returns: - // A uint8_t sum of all the nibbles inc the init. + /// Sum all the nibbles together in a series of bytes. + /// @param[in] start A ptr to the start of the byte array to calculate over. + /// @param[in] length How many bytes to use in the calculation. + /// @param[in] init Starting value of the calculation to use. (Default is 0) + /// @return The 8-bit calculated result of all the bytes and init value. uint8_t sumNibbles(const uint8_t * const start, const uint16_t length, const uint8_t init) { uint8_t sum = init; @@ -1093,41 +749,62 @@ namespace irutils { return sum; } + /// Sum all the nibbles together in an integer. + /// @param[in] data The integer to be summed. + /// @param[in] count The number of nibbles to sum. Starts from LSB. Max of 16. + /// @param[in] init Starting value of the calculation to use. (Default is 0) + /// @param[in] nibbleonly true, the result is 4 bits. false, it's 8 bits. + /// @return The 4/8-bit calculated result of all the nibbles and init value. + uint8_t sumNibbles(const uint64_t data, const uint8_t count, + const uint8_t init, const bool nibbleonly) { + uint8_t sum = init; + uint64_t copy = data; + const uint8_t nrofnibbles = (count < 16) ? count : (64 / 4); + for (uint8_t i = 0; i < nrofnibbles; i++, copy >>= 4) sum += copy & 0xF; + return nibbleonly ? sum & 0xF : sum; + } + + /// Convert a byte of Binary Coded Decimal(BCD) into an Integer. + /// @param[in] bcd The BCD value. + /// @return A normal Integer value. uint8_t bcdToUint8(const uint8_t bcd) { if (bcd > 0x99) return 255; // Too big. return (bcd >> 4) * 10 + (bcd & 0xF); } + /// Convert an Integer into a byte of Binary Coded Decimal(BCD). + /// @param[in] integer The number to convert. + /// @return An 8-bit BCD value. uint8_t uint8ToBcd(const uint8_t integer) { if (integer > 99) return 255; // Too big. return ((integer / 10) << 4) + (integer % 10); } - // Return the value of `position`th bit of `data`. - // Args: - // data: Value to be examined. - // position: Nr. of the nth bit to be examined. `0` is the LSB. - // size: Nr. of bits in data. + /// Return the value of `position`th bit of an Integer. + /// @param[in] data Value to be examined. + /// @param[in] position Nr. of the Nth bit to be examined. `0` is the LSB. + /// @param[in] size Nr. of bits in data. + /// @return The bit's value. bool getBit(const uint64_t data, const uint8_t position, const uint8_t size) { if (position >= size) return false; // Outside of range. return data & (1ULL << position); } - // Return the value of `position`th bit of `data`. - // Args: - // data: Value to be examined. - // position: Nr. of the nth bit to be examined. `0` is the LSB. + /// Return the value of `position`th bit of an Integer. + /// @param[in] data Value to be examined. + /// @param[in] position Nr. of the Nth bit to be examined. `0` is the LSB. + /// @return The bit's value. bool getBit(const uint8_t data, const uint8_t position) { if (position >= 8) return false; // Outside of range. return data & (1 << position); } - // Return the value of `data` with the `position`th bit changed to `on` - // Args: - // data: Value to be changed. - // position: Nr. of the bit to be changed. `0` is the LSB. - // on: Value to set the position'th bit to. - // size: Nr. of bits in data. + /// Return the value of an Integer with the `position`th bit changed. + /// @param[in] data Value to be changed. + /// @param[in] position Nr. of the bit to be changed. `0` is the LSB. + /// @param[in] on Value to set the position'th bit to. + /// @param[in] size Nr. of bits in data. + /// @return A suitably modified integer. uint64_t setBit(const uint64_t data, const uint8_t position, const bool on, const uint8_t size) { if (position >= size) return data; // Outside of range. @@ -1138,11 +815,11 @@ namespace irutils { return data & ~mask; } - // Return the value of `data` with the `position`th bit changed to `on` - // Args: - // data: Value to be changed. - // position: Nr. of the bit to be changed. `0` is the LSB. - // on: Value to set the position'th bit to. + /// Return the value of an Integer with the `position`th bit changed. + /// @param[in] data Value to be changed. + /// @param[in] position Nr. of the bit to be changed. `0` is the LSB. + /// @param[in] on Value to set the position'th bit to. + /// @return A suitably modified integer. uint8_t setBit(const uint8_t data, const uint8_t position, const bool on) { if (position >= 8) return data; // Outside of range. uint8_t mask = 1 << position; @@ -1152,12 +829,10 @@ namespace irutils { return data & ~mask; } - // Change the value at the location `data_ptr` with the `position`th bit - // changed to `on` - // Args: - // data: Ptr to the data to be changed. - // position: Nr. of the bit to be changed. `0` is the LSB. - // on: Value to set the position'th bit to. + /// Alter the value of an Integer with the `position`th bit changed. + /// @param[in,out] data A pointer to the 8-bit integer to be changed. + /// @param[in] position Nr. of the bit to be changed. `0` is the LSB. + /// @param[in] on Value to set the position'th bit to. void setBit(uint8_t * const data, const uint8_t position, const bool on) { uint8_t mask = 1 << position; if (on) @@ -1166,12 +841,10 @@ namespace irutils { *data &= ~mask; } - // Change the value at the location `data_ptr` with the `position`th bit - // changed to `on` - // Args: - // data: Ptr to the data to be changed. - // position: Nr. of the bit to be changed. `0` is the LSB. - // on: Value to set the position'th bit to. + /// Alter the value of an Integer with the `position`th bit changed. + /// @param[in,out] data A pointer to the 32-bit integer to be changed. + /// @param[in] position Nr. of the bit to be changed. `0` is the LSB. + /// @param[in] on Value to set the position'th bit to. void setBit(uint32_t * const data, const uint8_t position, const bool on) { uint32_t mask = (uint32_t)1 << position; if (on) @@ -1180,12 +853,10 @@ namespace irutils { *data &= ~mask; } - // Change the value at the location `data_ptr` with the `position`th bit - // changed to `on` - // Args: - // data: Ptr to the data to be changed. - // position: Nr. of the bit to be changed. `0` is the LSB. - // on: Value to set the position'th bit to. + /// Alter the value of an Integer with the `position`th bit changed. + /// @param[in,out] data A pointer to the 64-bit integer to be changed. + /// @param[in] position Nr. of the bit to be changed. `0` is the LSB. + /// @param[in] on Value to set the position'th bit to. void setBit(uint64_t * const data, const uint8_t position, const bool on) { uint64_t mask = (uint64_t)1 << position; if (on) @@ -1194,13 +865,11 @@ namespace irutils { *data &= ~mask; } - // Change the uint8_t pointed to by `dst` starting at the `offset`th bit - // and for `nbits` bits, with the contents of `data`. - // Args: - // dst: Ptr to the uint8_t to be changed. - // offset: Nr. of bits from the Least Significant Bit to be ignored. - // nbits: Nr of bits of `data` to be placed into the destination uint8_t. - // data: Value to be placed into dst. + /// Alter an uint8_t value by overwriting an arbitary given number of bits. + /// @param[in,out] dst A pointer to the value to be changed. + /// @param[in] offset Nr. of bits from the Least Significant Bit to be ignored + /// @param[in] nbits Nr of bits of data to be placed into the destination. + /// @param[in] data The value to be placed. void setBits(uint8_t * const dst, const uint8_t offset, const uint8_t nbits, const uint8_t data) { if (offset >= 8 || !nbits) return; // Short circuit as it won't change. @@ -1213,13 +882,11 @@ namespace irutils { *dst |= ((data & mask) << offset); } - // Change the uint32_t pointed to by `dst` starting at the `offset`th bit - // and for `nbits` bits, with the contents of `data`. - // Args: - // dst: Ptr to the uint32_t to be changed. - // offset: Nr. of bits from the Least Significant Bit to be ignored. - // nbits: Nr of bits of `data` to be placed into the destination uint32_t. - // data: Value to be placed into dst. + /// Alter an uint32_t value by overwriting an arbitary given number of bits. + /// @param[in,out] dst A pointer to the value to be changed. + /// @param[in] offset Nr. of bits from the Least Significant Bit to be ignored + /// @param[in] nbits Nr of bits of data to be placed into the destination. + /// @param[in] data The value to be placed. void setBits(uint32_t * const dst, const uint8_t offset, const uint8_t nbits, const uint32_t data) { if (offset >= 32 || !nbits) return; // Short circuit as it won't change. @@ -1232,13 +899,11 @@ namespace irutils { *dst |= ((data & mask) << offset); } - // Change the uint64_t pointed to by `dst` starting at the `offset`th bit - // and for `nbits` bits, with the contents of `data`. - // Args: - // dst: Ptr to the uint64_t to be changed. - // offset: Nr. of bits from the Least Significant Bit to be ignored. - // nbits: Nr of bits of `data` to be placed into the destination uint64_t. - // data: Value to be placed into dst. + /// Alter an uint64_t value by overwriting an arbitary given number of bits. + /// @param[in,out] dst A pointer to the value to be changed. + /// @param[in] offset Nr. of bits from the Least Significant Bit to be ignored + /// @param[in] nbits Nr of bits of data to be placed into the destination. + /// @param[in] data The value to be placed. void setBits(uint64_t * const dst, const uint8_t offset, const uint8_t nbits, const uint64_t data) { if (offset >= 64 || !nbits) return; // Short circuit as it won't change. diff --git a/lib/IRremoteESP8266-2.7.5/src/IRutils.h b/lib/IRremoteESP8266-2.7.8/src/IRutils.h similarity index 95% rename from lib/IRremoteESP8266-2.7.5/src/IRutils.h rename to lib/IRremoteESP8266-2.7.8/src/IRutils.h index 34319134a..3c865dfcf 100644 --- a/lib/IRremoteESP8266-2.7.5/src/IRutils.h +++ b/lib/IRremoteESP8266-2.7.8/src/IRutils.h @@ -42,6 +42,8 @@ uint64_t invertBits(const uint64_t data, const uint16_t nbits); decode_type_t strToDecodeType(const char *str); float celsiusToFahrenheit(const float deg); float fahrenheitToCelsius(const float deg); +/// Namespace for covering common functions & procedures for advancd protocol +/// handlers namespace irutils { String addBoolToString(const bool value, const String label, const bool precomma = true); @@ -67,6 +69,8 @@ namespace irutils { String minsToString(const uint16_t mins); uint8_t sumNibbles(const uint8_t * const start, const uint16_t length, const uint8_t init = 0); + uint8_t sumNibbles(const uint64_t data, const uint8_t count = 16, + const uint8_t init = 0, const bool nibbleonly = true); uint8_t bcdToUint8(const uint8_t bcd); uint8_t uint8ToBcd(const uint8_t integer); bool getBit(const uint64_t data, const uint8_t position, diff --git a/lib/IRremoteESP8266-2.7.5/src/i18n.h b/lib/IRremoteESP8266-2.7.8/src/i18n.h similarity index 100% rename from lib/IRremoteESP8266-2.7.5/src/i18n.h rename to lib/IRremoteESP8266-2.7.8/src/i18n.h diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Airwell.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Airwell.cpp similarity index 55% rename from lib/IRremoteESP8266-2.7.5/src/ir_Airwell.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Airwell.cpp index 5eb103b84..2bf0a2db8 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Airwell.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Airwell.cpp @@ -3,35 +3,32 @@ #include "IRrecv.h" #include "IRsend.h" -// Airwell "Manchester code" based protocol. -// Some other Airwell products use the COOLIX protocol. -// +/// @file +/// @brief Airwell "Manchester code" based protocol. +/// Some other Airwell products use the COOLIX protocol. + // Supports: // Brand: Airwell, Model: RC08W remote +// Brand: Airwell, Model: RC04 remote +// Brand: Airwell, Model: DLS 21 DCI R410 AW A/C const uint8_t kAirwellOverhead = 4; const uint16_t kAirwellHalfClockPeriod = 950; // uSeconds const uint16_t kAirwellHdrMark = 3 * kAirwellHalfClockPeriod; // uSeconds -const uint16_t kAirwellHdrSpace = 4 * kAirwellHalfClockPeriod; // uSeconds +const uint16_t kAirwellHdrSpace = 3 * kAirwellHalfClockPeriod; // uSeconds const uint16_t kAirwellFooterMark = 5 * kAirwellHalfClockPeriod; // uSeconds #if SEND_AIRWELL -// Send an Airwell Manchester Code formatted message. -// -// Args: -// data: The message to be sent. -// nbits: The number of bits of the message to be sent. -// Typically kAirwellBits. -// repeat: The number of times the command is to be repeated. -// -// Status: BETA / Appears to be working. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/1069 +/// Send an Airwell Manchester Code formatted message. +/// Status: BETA / Appears to be working. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of the message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1069 void IRsend::sendAirwell(uint64_t data, uint16_t nbits, uint16_t repeat) { // Header + Data sendManchester(kAirwellHdrMark, kAirwellHdrMark, kAirwellHalfClockPeriod, - 0, 0, data, nbits, 38000, true, repeat); + 0, 0, data, nbits, 38000, true, repeat, kDutyDefault, false); // Footer mark(kAirwellHdrMark + kAirwellHalfClockPeriod); space(kDefaultMessageGap); // A guess. @@ -39,21 +36,17 @@ void IRsend::sendAirwell(uint64_t data, uint16_t nbits, uint16_t repeat) { #endif #if DECODE_AIRWELL -// Decode the supplied Airwell "Manchester code" message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kAirwellBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: BETA / Appears to be working. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/1069 +/// Decode the supplied Airwell "Manchester code" message. +/// +/// Status: BETA / Appears to be 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. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1069 bool IRrecv::decodeAirwell(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen < nbits + kAirwellOverhead - offset) @@ -69,7 +62,7 @@ bool IRrecv::decodeAirwell(decode_results *results, uint16_t offset, kAirwellHdrMark, kAirwellHdrMark, kAirwellHalfClockPeriod, kAirwellHdrMark, kAirwellHdrSpace, - true); + true, kUseDefTol, kMarkExcess, true, false); if (used == 0) return false; offset += used; diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Aiwa.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Aiwa.cpp similarity index 63% rename from lib/IRremoteESP8266-2.7.5/src/ir_Aiwa.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Aiwa.cpp index 95dffe1aa..2b989c6ae 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Aiwa.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Aiwa.cpp @@ -3,15 +3,12 @@ #include "IRrecv.h" #include "IRsend.h" -// AAA IIIII W W AAA -// A A I W W A A -// AAAAA I W W W AAAAA -// A A I W W W A A -// A A IIIII WWW A A +/// @file +/// @brief Aiwa based protocol. +/// Based off the RC-T501 RCU +/// Inspired by IRremoteESP8266's implementation +/// @see https://github.com/z3t0/Arduino-IRremote -// Based off the RC-T501 RCU -// Added by David Conran. (Inspired by IRremoteESP8266's implementation: -// https://github.com/z3t0/Arduino-IRremote) // Supports: // Brand: Aiwa, Model: RC-T501 RCU @@ -23,18 +20,13 @@ const uint64_t kAiwaRcT501PreData = 0x1D8113FULL; // 26-bits const uint64_t kAiwaRcT501PostData = 1ULL; #if SEND_AIWA_RC_T501 -// Send an Aiwa RC T501 formatted message. -// -// Args: -// data: The message to be sent. -// nbits: The number of bits of the message to be sent. -// Typically kAiwaRcT501Bits. Max is 37 = (64 - 27) -// repeat: The number of times the command is to be repeated. -// -// Status: BETA / Should work. -// -// Ref: -// http://lirc.sourceforge.net/remotes/aiwa/RC-T501 +/// Send an Aiwa RC T501 formatted message. +/// Status: BETA / Should work. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of the message to be sent. +/// Typically kAiwaRcT501Bits. Max is 37 = (64 - 27) +/// @param[in] repeat The number of times the command is to be repeated. +/// @see http://lirc.sourceforge.net/remotes/aiwa/RC-T501 void IRsend::sendAiwaRCT501(uint64_t data, uint16_t nbits, uint16_t repeat) { // Appears to be an extended NEC1 protocol. i.e. 42 bits instead of 32 bits. // So use sendNEC instead, however the twist is it has a fixed 26 bit @@ -49,28 +41,23 @@ void IRsend::sendAiwaRCT501(uint64_t data, uint16_t nbits, uint16_t repeat) { #endif #if DECODE_AIWA_RC_T501 -// Decode the supplied Aiwa RC T501 message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kAiwaRcT501Bits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: BETA / Should work. -// -// Notes: -// Aiwa RC T501 appears to be a 42 bit variant of the NEC1 protocol. -// However, we historically (original Arduino IRremote project) treats it as -// a 15 bit (data) protocol. So, we expect nbits to typically be 15, and we -// will remove the prefix and postfix from the raw data, and use that as -// the result. -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/nec.php +/// Decode the supplied Aiwa RC T501 message. +/// Status: BETA / Should work. +/// @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. +/// @note +/// Aiwa RC T501 appears to be a 42 bit variant of the NEC1 protocol. +/// However, we historically (original Arduino IRremote project) treats it as +/// a 15 bit (data) protocol. So, we expect nbits to typically be 15, and we +/// will remove the prefix and postfix from the raw data, and use that as +/// the result. +/// @see http://www.sbprojects.com/knowledge/ir/nec.php +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1069 bool IRrecv::decodeAiwaRCT501(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { // Compliance diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Amcor.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Amcor.cpp similarity index 68% rename from lib/IRremoteESP8266-2.7.5/src/ir_Amcor.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Amcor.cpp index b29933906..668280133 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Amcor.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Amcor.cpp @@ -1,9 +1,9 @@ // Copyright 2019 David Conran -// Supports: -// Brand: Amcor, Model: ADR-853H A/C -// Brand: Amcor, Model: TAC-495 remote -// Brand: Amcor, Model: TAC-444 remote +/// @file +/// @brief Amcor A/C protocol. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/385 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/834 #include "ir_Amcor.h" #include @@ -14,8 +14,6 @@ #include "IRutils.h" // Constants -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/385 const uint16_t kAmcorHdrMark = 8200; const uint16_t kAmcorHdrSpace = 4200; const uint16_t kAmcorOneMark = 1500; @@ -33,15 +31,11 @@ using irutils::addTempToString; using irutils::setBits; #if SEND_AMCOR -// Send a Amcor HVAC formatted message. -// -// Args: -// data: The message to be sent. -// nbytes: The byte size of the array being sent. typically kAmcorStateLength. -// repeat: The number of times the message is to be repeated. -// -// Status: STABLE / Reported as working. -// +/// Send a Amcor HVAC formatted message. +/// Status: STABLE / Reported as working. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendAmcor(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { // Check if we have enough bytes to send a proper message. @@ -53,19 +47,15 @@ void IRsend::sendAmcor(const unsigned char data[], const uint16_t nbytes, #endif #if DECODE_AMCOR -// Decode the supplied Amcor HVAC message. -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits to expect in the data portion. -// Typically kAmcorBits. -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Reported as working. -// +/// Decode the supplied Amcor HVAC message. +/// Status: STABLE / Reported as 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::decodeAmcor(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen <= 2 * nbits + kHeader - 1 + offset) @@ -99,31 +89,48 @@ bool IRrecv::decodeAmcor(decode_results *results, uint16_t offset, } #endif +/// 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? IRAmcorAc::IRAmcorAc(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { this->stateReset(); } +/// Set up hardware to be able to send a message. void IRAmcorAc::begin(void) { _irsend.begin(); } #if SEND_AMCOR +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRAmcorAc::send(const uint16_t repeat) { _irsend.sendAmcor(getRaw(), kAmcorStateLength, repeat); } #endif // SEND_AMCOR +/// Calculate the checksum for the supplied state. +/// @param[in] state The source state to generate the checksum from. +/// @param[in] length Length of the supplied state to checksum. +/// @return The checksum value. uint8_t IRAmcorAc::calcChecksum(const uint8_t state[], const uint16_t length) { return irutils::sumNibbles(state, length - 1); } +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The size of the state. +/// @return A boolean indicating if it's checksum is valid. bool IRAmcorAc::validChecksum(const uint8_t state[], const uint16_t length) { return (state[length - 1] == IRAmcorAc::calcChecksum(state, length)); } +/// Update the checksum value for the internal state. void IRAmcorAc::checksum(void) { remote_state[kAmcorChecksumByte] = IRAmcorAc::calcChecksum(remote_state, kAmcorStateLength); } +/// Reset the internals of the object to a known good state. void IRAmcorAc::stateReset(void) { for (uint8_t i = 1; i < kAmcorStateLength; i++) remote_state[i] = 0x0; remote_state[0] = 0x01; @@ -132,30 +139,42 @@ void IRAmcorAc::stateReset(void) { setTemp(25); // 25C } +/// Get the raw state of the object, suitable to be sent with the appropriate +/// IRsend object method. +/// @return A PTR to the internal state. uint8_t* IRAmcorAc::getRaw(void) { this->checksum(); // Ensure correct bit array before returning return remote_state; } +/// Set the raw state of the object. +/// @param[in] state The raw state from the native IR message. void IRAmcorAc::setRaw(const uint8_t state[]) { memcpy(remote_state, state, kAmcorStateLength); } +/// Set the internal state to have the power on. void IRAmcorAc::on(void) { setPower(true); } +/// Set the internal state to have the power off. void IRAmcorAc::off(void) { setPower(false); } +/// Set the internal state to have the desired power. +/// @param[in] on The desired power state. void IRAmcorAc::setPower(const bool on) { setBits(&remote_state[kAmcorPowerByte], kAmcorPowerOffset, kAmcorPowerSize, on ? kAmcorPowerOn : kAmcorPowerOff); } +/// Get the power setting from the internal state. +/// @return A boolean indicating the power setting. bool IRAmcorAc::getPower(void) { return GETBITS8(remote_state[kAmcorPowerByte], kAmcorPowerOffset, kAmcorPowerSize) == kAmcorPowerOn; } -// Set the temp in deg C +/// Set the temperature. +/// @param[in] degrees The temperature in degrees celsius. void IRAmcorAc::setTemp(const uint8_t degrees) { uint8_t temp = std::max(kAmcorMinTemp, degrees); temp = std::min(kAmcorMaxTemp, temp); @@ -163,12 +182,16 @@ void IRAmcorAc::setTemp(const uint8_t degrees) { temp); } +/// Get the current temperature setting. +/// @return Get current setting for temp. in degrees celsius. uint8_t IRAmcorAc::getTemp(void) { return GETBITS8(remote_state[kAmcorTempByte], kAmcorTempOffset, kAmcorTempSize); } -// Maximum Cooling or Hearing +/// Control the current Maximum Cooling or Heating setting. (i.e. Turbo) +/// @note Only allowed in Cool or Heat mode. +/// @param[in] on The desired setting. void IRAmcorAc::setMax(const bool on) { if (on) { switch (getMode()) { @@ -182,12 +205,15 @@ void IRAmcorAc::setMax(const bool on) { on ? kAmcorMax : 0); } +/// Is the Maximum Cooling or Heating setting (i.e. Turbo) setting on? +/// @return The current value. bool IRAmcorAc::getMax(void) { return GETBITS8(remote_state[kAmcorSpecialByte], kAmcorMaxOffset, kAmcorMaxSize) == kAmcorMax; } -// Set the speed of the fan +/// Set the speed of the fan. +/// @param[in] speed The desired setting. void IRAmcorAc::setFan(const uint8_t speed) { switch (speed) { case kAmcorFanAuto: @@ -202,16 +228,22 @@ void IRAmcorAc::setFan(const uint8_t speed) { } } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRAmcorAc::getFan(void) { return GETBITS8(remote_state[kAmcorModeFanByte], kAmcorFanOffset, kAmcorFanSize); } +/// Get the current operation mode setting. +/// @return The current operation mode. uint8_t IRAmcorAc::getMode(void) { return GETBITS8(remote_state[kAmcorModeFanByte], kAmcorModeOffset, kAmcorModeSize); } +/// Set the desired operation mode. +/// @param[in] mode The desired operation mode. void IRAmcorAc::setMode(const uint8_t mode) { switch (mode) { case kAmcorFan: @@ -229,7 +261,9 @@ void IRAmcorAc::setMode(const uint8_t mode) { } } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRAmcorAc::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: @@ -245,7 +279,9 @@ uint8_t IRAmcorAc::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRAmcorAc::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: @@ -261,7 +297,9 @@ uint8_t IRAmcorAc::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRAmcorAc::toCommonMode(const uint8_t mode) { switch (mode) { case kAmcorCool: return stdAc::opmode_t::kCool; @@ -272,7 +310,9 @@ stdAc::opmode_t IRAmcorAc::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRAmcorAc::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kAmcorFanMax: return stdAc::fanspeed_t::kMax; @@ -282,7 +322,8 @@ stdAc::fanspeed_t IRAmcorAc::toCommonFanSpeed(const uint8_t speed) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRAmcorAc::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::AMCOR; @@ -307,7 +348,8 @@ stdAc::state_t IRAmcorAc::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRAmcorAc::toString(void) { String result = ""; result.reserve(70); // Reserve some heap for the string to reduce fragging. diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Amcor.h b/lib/IRremoteESP8266-2.7.8/src/ir_Amcor.h similarity index 84% rename from lib/IRremoteESP8266-2.7.5/src/ir_Amcor.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Amcor.h index fa8aa1edd..f3ac1bad6 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Amcor.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Amcor.h @@ -1,7 +1,14 @@ -// Amcor A/C -// // Copyright 2019 David Conran +/// @file +/// @brief Amcor A/C protocol. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/834 +/// @remark Kudos to ldellus; For the breakdown and mapping of the bit values. +// Supports: +// Brand: Amcor, Model: ADR-853H A/C +// Brand: Amcor, Model: TAC-495 remote +// Brand: Amcor, Model: TAC-444 remote + #ifndef IR_AMCOR_H_ #define IR_AMCOR_H_ @@ -16,18 +23,9 @@ #include "IRsend_test.h" #endif -// Supports: -// Brand: Amcor, Model: ADR-853H A/C -// Brand: Amcor, Model: TAC-495 remote -// Brand: Amcor, Model: TAC-444 remote -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/834 -// Kudos: -// ldellus: For the breakdown and mapping of the bit values. // Constants - // state[1] const uint8_t kAmcorModeFanByte = 1; // Fan Control @@ -78,6 +76,8 @@ const uint8_t kAmcorVentSize = 2; const uint8_t kAmcorChecksumByte = kAmcorStateLength - 1; // Classes + +/// Class for handling detailed Amcor A/C messages. class IRAmcorAc { public: explicit IRAmcorAc(const uint16_t pin, const bool inverted = false, @@ -86,7 +86,11 @@ class IRAmcorAc { void stateReset(); #if SEND_AMCOR void send(const uint16_t repeat = kAmcorDefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + /// 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_AMCOR void begin(); static uint8_t calcChecksum(const uint8_t state[], @@ -118,7 +122,9 @@ class IRAmcorAc { private: IRsend _irsend; #else + /// @cond IGNORE IRsendTest _irsend; + /// @endcond #endif uint8_t remote_state[kAmcorStateLength]; // The state of the IR remote. void checksum(void); diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Argo.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Argo.cpp similarity index 69% rename from lib/IRremoteESP8266-2.7.5/src/ir_Argo.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Argo.cpp index 0c4656cb5..cbe32487e 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Argo.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Argo.cpp @@ -1,9 +1,8 @@ -/* -Node MCU/ESP8266 Sketch to emulate Argo Ulisse 13 DCI remote -Controls Argo Ulisse 13 DCI A/C -Copyright 2017 Schmolders -Copyright 2019 crankyoldgit -*/ +// Copyright 2017 Schmolders +// Copyright 2019 crankyoldgit +/// @file +/// @brief Argo A/C protocol. +/// Controls an Argo Ulisse 13 DCI A/C #include "ir_Argo.h" #include @@ -33,13 +32,11 @@ using irutils::setBit; using irutils::setBits; #if SEND_ARGO -// Send an Argo A/C message. -// -// Args: -// data: An array of kArgoStateLength bytes containing the IR command. -// -// Status: BETA / Probably works. - +/// Send a Argo A/C formatted message. +/// Status: BETA / Probably works. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendArgo(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { // Check if we have enough bytes to send a proper message. @@ -51,18 +48,29 @@ void IRsend::sendArgo(const unsigned char data[], const uint16_t nbytes, } #endif // SEND_ARGO +/// 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? IRArgoAC::IRArgoAC(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { this->stateReset(); } +/// Set up hardware to be able to send a message. void IRArgoAC::begin(void) { _irsend.begin(); } #if SEND_ARGO +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRArgoAC::send(const uint16_t repeat) { _irsend.sendArgo(getRaw(), kArgoStateLength, repeat); } #endif // SEND_ARGO +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The size of the state. +/// @return A boolean indicating if it's checksum is valid. uint8_t IRArgoAC::calcChecksum(const uint8_t state[], const uint16_t length) { // Corresponds to byte 11 being constant 0b01 // Only add up bytes to 9. byte 10 is 0b01 constant anyway. @@ -70,11 +78,16 @@ uint8_t IRArgoAC::calcChecksum(const uint8_t state[], const uint16_t length) { return sumBytes(state, length - 2, 2); } +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The size of the state. +/// @return A boolean indicating if it's checksum is valid. bool IRArgoAC::validChecksum(const uint8_t state[], const uint16_t length) { return ((state[length - 2] >> 2) + (state[length - 1] << 6)) == IRArgoAC::calcChecksum(state, length); } +/// Update the checksum for the internal state. void IRArgoAC::checksum(void) { uint8_t sum = IRArgoAC::calcChecksum(argo, kArgoStateLength); // Append sum to end of array @@ -84,6 +97,7 @@ void IRArgoAC::checksum(void) { argo[11] = sum >> 6; // Shift down 6 bits and add in two LSBs of bit 11 } +/// Reset the internals of the object to a known good state. void IRArgoAC::stateReset(void) { for (uint8_t i = 0; i < kArgoStateLength; i++) argo[i] = 0x0; @@ -102,33 +116,49 @@ void IRArgoAC::stateReset(void) { this->setFan(kArgoFanAuto); } +/// Get the raw state of the object, suitable to be sent with the appropriate +/// IRsend object method. +/// @return A PTR to the internal state. uint8_t* IRArgoAC::getRaw(void) { this->checksum(); // Ensure correct bit array before returning return argo; } +/// Set the raw state of the object. +/// @param[in] state The raw state from the native IR message. void IRArgoAC::setRaw(const uint8_t state[]) { memcpy(argo, state, kArgoStateLength); } +/// Set the internal state to have the power on. void IRArgoAC::on(void) { setPower(true); } +/// Set the internal state to have the power off. void IRArgoAC::off(void) { setPower(false); } +/// Set the internal state to have the desired power. +/// @param[in] on The desired power state. void IRArgoAC::setPower(const bool on) { setBit(&argo[9], kArgoPowerBitOffset, on); } +/// Get the power setting from the internal state. +/// @return A boolean indicating the power setting. bool IRArgoAC::getPower(void) { return GETBIT8(argo[9], kArgoPowerBitOffset); } +/// Control the current Max setting. (i.e. Turbo) +/// @param[in] on The desired setting. void IRArgoAC::setMax(const bool on) { setBit(&argo[9], kArgoMaxBitOffset, on); } +/// Is the Max (i.e. Turbo) setting on? +/// @return The current value. bool IRArgoAC::getMax(void) { return GETBIT8(argo[9], kArgoMaxBitOffset); } -// Set the temp in deg C -// Sending 0 equals +4 +/// Set the temperature. +/// @param[in] degrees The temperature in degrees celsius. +/// @note Sending 0 equals +4 void IRArgoAC::setTemp(const uint8_t degrees) { uint8_t temp = std::max(kArgoMinTemp, degrees); // delta 4 degrees. "If I want 12 degrees, I need to send 8" @@ -141,6 +171,8 @@ void IRArgoAC::setTemp(const uint8_t degrees) { temp >> kArgoTempLowSize); } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRArgoAC::getTemp(void) { return ((GETBITS8(argo[3], kArgoTempHighOffset, kArgoTempHighSize) << kArgoTempLowSize) | @@ -148,26 +180,39 @@ uint8_t IRArgoAC::getTemp(void) { kArgoTempDelta; } -// Set the speed of the fan +/// Set the speed of the fan. +/// @param[in] fan The desired setting. void IRArgoAC::setFan(const uint8_t fan) { setBits(&argo[3], kArgoFanOffset, kArgoFanSize, std::min(fan, kArgoFan3)); } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRArgoAC::getFan(void) { return GETBITS8(argo[3], kArgoFanOffset, kArgoFanSize); } +/// Set the flap position. i.e. Swing. +/// @warning Not yet working! +/// @param[in] flap The desired setting. void IRArgoAC::setFlap(const uint8_t flap) { flap_mode = flap; // TODO(kaschmo): set correct bits for flap mode } +/// Get the flap position. i.e. Swing. +/// @warning Not yet working! +/// @return The current flap setting. uint8_t IRArgoAC::getFlap(void) { return flap_mode; } +/// Get the current operation mode setting. +/// @return The current operation mode. uint8_t IRArgoAC::getMode(void) { return GETBITS8(argo[2], kArgoModeOffset, kArgoModeSize); } +/// Set the desired operation mode. +/// @param[in] mode The desired operation mode. void IRArgoAC::setMode(const uint8_t mode) { switch (mode) { case kArgoCool: @@ -183,22 +228,34 @@ void IRArgoAC::setMode(const uint8_t mode) { } } +/// Turn on/off the Night mode. i.e. Sleep. +/// @param[in] on The desired setting. void IRArgoAC::setNight(const bool on) { setBit(&argo[9], kArgoNightBitOffset, on); } +/// Get the status of Night mode. i.e. Sleep. +/// @return true if on, false if off. bool IRArgoAC::getNight(void) { return GETBIT8(argo[9], kArgoNightBitOffset); } +/// Turn on/off the iFeel mode. +/// @param[in] on The desired setting. void IRArgoAC::setiFeel(const bool on) { setBit(&argo[9], kArgoIFeelBitOffset, on); } +/// Get the status of iFeel mode. +/// @return true if on, false if off. bool IRArgoAC::getiFeel(void) { return GETBIT8(argo[9], kArgoIFeelBitOffset); } +/// Set the time for the A/C +/// @warning Not yet working! void IRArgoAC::setTime(void) { // TODO(kaschmo): use function call from checksum to set time first } +/// Set the value for the current room temperature. +/// @param[in] degrees The temperature in degrees celsius. void IRArgoAC::setRoomTemp(const uint8_t degrees) { uint8_t temp = std::min(degrees, kArgoMaxRoomTemp); temp = std::max(temp, kArgoTempDelta) - kArgoTempDelta; @@ -207,6 +264,8 @@ void IRArgoAC::setRoomTemp(const uint8_t degrees) { temp >> kArgoRoomTempLowSize); } +/// Get the currently stored value for the room temperature setting. +/// @return The current setting for the room temp. in degrees celsius. uint8_t IRArgoAC::getRoomTemp(void) { return ((GETBITS8(argo[4], kArgoRoomTempHighOffset, kArgoRoomTempHighSize) << kArgoRoomTempLowSize) | @@ -214,7 +273,9 @@ uint8_t IRArgoAC::getRoomTemp(void) { kArgoTempDelta; } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRArgoAC::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: @@ -231,7 +292,9 @@ uint8_t IRArgoAC::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRArgoAC::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: @@ -247,7 +310,9 @@ uint8_t IRArgoAC::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::swingv_t enum into it's native setting. +/// @param[in] position The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRArgoAC::convertSwingV(const stdAc::swingv_t position) { switch (position) { case stdAc::swingv_t::kHighest: @@ -265,7 +330,9 @@ uint8_t IRArgoAC::convertSwingV(const stdAc::swingv_t position) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRArgoAC::toCommonMode(const uint8_t mode) { switch (mode) { case kArgoCool: return stdAc::opmode_t::kCool; @@ -276,7 +343,9 @@ stdAc::opmode_t IRArgoAC::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRArgoAC::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kArgoFan3: return stdAc::fanspeed_t::kMax; @@ -286,7 +355,8 @@ stdAc::fanspeed_t IRArgoAC::toCommonFanSpeed(const uint8_t speed) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRArgoAC::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::ARGO; @@ -311,7 +381,8 @@ stdAc::state_t IRArgoAC::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRArgoAC::toString(void) { String result = ""; result.reserve(100); // Reserve some heap for the string to reduce fragging. @@ -374,22 +445,17 @@ String IRArgoAC::toString(void) { } #if DECODE_ARGO -// Decode the supplied Argo message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kArgoBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: BETA / Probably works. -// -// Note: -// This decoder is based soley off sendArgo(). We have no actual captures -// to test this against. If you have one of these units, please let us know. +/// Decode the supplied Argo message. +/// Status: BETA / Probably works. +/// @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. +/// @note This decoder is based soley off sendArgo(). We have no actual captures +/// to test this against. If you have one of these units, please let us know. bool IRrecv::decodeArgo(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Argo.h b/lib/IRremoteESP8266-2.7.8/src/ir_Argo.h similarity index 90% rename from lib/IRremoteESP8266-2.7.5/src/ir_Argo.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Argo.h index 3c1281ea3..9104a051b 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Argo.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Argo.h @@ -1,5 +1,6 @@ // Copyright 2017 Schmolders -// Adds support for Argo Ulisse 13 DCI Mobile Split ACs. +/// @file +/// @brief Support for Argo Ulisse 13 DCI Mobile Split ACs. // Supports: // Brand: Argo, Model: Ulisse 13 DCI Mobile Split A/C @@ -124,6 +125,7 @@ const uint8_t kArgoFlapFull = 7; #define ARGO_FLAP_FULL kArgoFlapFull +/// Class for handling detailed Argo A/C messages. class IRArgoAC { public: explicit IRArgoAC(const uint16_t pin, const bool inverted = false, @@ -131,7 +133,11 @@ class IRArgoAC { #if SEND_ARGO void send(const uint16_t repeat = kArgoDefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + /// 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); @@ -181,9 +187,11 @@ class IRArgoAC { #ifndef UNIT_TEST private: - IRsend _irsend; // instance of the IR send class + IRsend _irsend; ///< instance of the IR send class #else - IRsendTest _irsend; // instance of the testing IR send class + /// @cond IGNORE + IRsendTest _irsend; ///< instance of the testing IR send class + /// @endcond #endif // # of bytes per command uint8_t argo[kArgoStateLength]; // Defined in IRremoteESP8266.h diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Carrier.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Carrier.cpp new file mode 100644 index 000000000..ab6b8176b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Carrier.cpp @@ -0,0 +1,545 @@ +// Copyright 2018, 2020 David Conran +/// @file +/// @brief Carrier protocols. +/// @see CarrierAc https://github.com/crankyoldgit/IRremoteESP8266/issues/385 +/// @see CarrierAc64 https://github.com/crankyoldgit/IRremoteESP8266/issues/1127 + +#include "ir_Carrier.h" +#include +#include "IRac.h" +#include "IRrecv.h" +#include "IRsend.h" +#include "IRtext.h" +#include "IRutils.h" + +using irutils::addBoolToString; +using irutils::addIntToString; +using irutils::addLabeledString; +using irutils::addModeToString; +using irutils::addTempToString; +using irutils::addFanToString; +using irutils::minsToString; +using irutils::setBit; +using irutils::setBits; +using irutils::sumNibbles; + +// Constants +const uint16_t kCarrierAcHdrMark = 8532; +const uint16_t kCarrierAcHdrSpace = 4228; +const uint16_t kCarrierAcBitMark = 628; +const uint16_t kCarrierAcOneSpace = 1320; +const uint16_t kCarrierAcZeroSpace = 532; +const uint16_t kCarrierAcGap = 20000; +const uint16_t kCarrierAcFreq = 38; // kHz. (An educated guess) + +const uint16_t kCarrierAc40HdrMark = 8402; +const uint16_t kCarrierAc40HdrSpace = 4166; +const uint16_t kCarrierAc40BitMark = 547; +const uint16_t kCarrierAc40OneSpace = 1540; +const uint16_t kCarrierAc40ZeroSpace = 497; +const uint32_t kCarrierAc40Gap = 150000; ///< +///< @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1190#issuecomment-643380155 + +const uint16_t kCarrierAc64HdrMark = 8940; +const uint16_t kCarrierAc64HdrSpace = 4556; +const uint16_t kCarrierAc64BitMark = 503; +const uint16_t kCarrierAc64OneSpace = 1736; +const uint16_t kCarrierAc64ZeroSpace = 615; +const uint32_t kCarrierAc64Gap = kDefaultMessageGap; // A guess. + + +#if SEND_CARRIER_AC +/// Send a Carrier HVAC formatted message. +/// Status: STABLE / Works on real devices. +/// @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::sendCarrierAC(uint64_t data, uint16_t nbits, uint16_t repeat) { + for (uint16_t r = 0; r <= repeat; r++) { + uint64_t temp_data = data; + // Carrier sends the data block three times. normal + inverted + normal. + for (uint16_t i = 0; i < 3; i++) { + sendGeneric(kCarrierAcHdrMark, kCarrierAcHdrSpace, kCarrierAcBitMark, + kCarrierAcOneSpace, kCarrierAcBitMark, kCarrierAcZeroSpace, + kCarrierAcBitMark, kCarrierAcGap, temp_data, nbits, 38, true, + 0, kDutyDefault); + temp_data = invertBits(temp_data, nbits); + } + } +} +#endif + +#if DECODE_CARRIER_AC +/// Decode the supplied Carrier HVAC message. +/// @note Carrier HVAC messages contain only 32 bits, but it is sent three(3) +/// times. i.e. normal + inverted + normal +/// Status: BETA / Probably works. +/// @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::decodeCarrierAC(decode_results *results, uint16_t offset, + const uint16_t nbits, const bool strict) { + if (results->rawlen < ((2 * nbits + kHeader + kFooter) * 3) - 1 + offset) + return false; // Can't possibly be a valid Carrier message. + if (strict && nbits != kCarrierAcBits) + return false; // We expect Carrier to be 32 bits of message. + + uint64_t data = 0; + uint64_t prev_data = 0; + + for (uint8_t i = 0; i < 3; i++) { + prev_data = data; + // Match Header + Data + Footer + uint16_t used; + used = matchGeneric(results->rawbuf + offset, &data, + results->rawlen - offset, nbits, + kCarrierAcHdrMark, kCarrierAcHdrSpace, + kCarrierAcBitMark, kCarrierAcOneSpace, + kCarrierAcBitMark, kCarrierAcZeroSpace, + kCarrierAcBitMark, kCarrierAcGap, true); + if (!used) return false; + offset += used; + // Compliance. + if (strict) { + // Check if the data is an inverted copy of the previous data. + if (i > 0 && prev_data != invertBits(data, nbits)) return false; + } + } + + // Success + results->bits = nbits; + results->value = data; + results->decode_type = CARRIER_AC; + results->address = data >> 16; + results->command = data & 0xFFFF; + return true; +} +#endif // DECODE_CARRIER_AC + +#if SEND_CARRIER_AC40 +/// Send a Carrier 40bit HVAC formatted message. +/// Status: STABLE / Tested against a real device. +/// @param[in] data The message to be sent. +/// @param[in] nbits The bit size of the message being sent. +/// @param[in] repeat The number of times the message is to be repeated. +void IRsend::sendCarrierAC40(const uint64_t data, const uint16_t nbits, + const uint16_t repeat) { + sendGeneric(kCarrierAc40HdrMark, kCarrierAc40HdrSpace, kCarrierAc40BitMark, + kCarrierAc40OneSpace, kCarrierAc40BitMark, kCarrierAc40ZeroSpace, + kCarrierAc40BitMark, kCarrierAc40Gap, + data, nbits, kCarrierAcFreq, true, repeat, kDutyDefault); +} +#endif // SEND_CARRIER_AC40 + +#if DECODE_CARRIER_AC40 +/// Decode the supplied Carrier 40-bit HVAC message. +/// Carrier HVAC messages contain only 40 bits, but it is sent three(3) times. +/// Status: STABLE / Tested against a real device. +/// @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::decodeCarrierAC40(decode_results *results, uint16_t offset, + const uint16_t nbits, const bool strict) { + if (results->rawlen < 2 * nbits + kHeader + kFooter - 1 + offset) + return false; // Can't possibly be a valid Carrier message. + if (strict && nbits != kCarrierAc40Bits) + return false; // We expect Carrier to be 40 bits of message. + + if (!matchGeneric(results->rawbuf + offset, &(results->value), + results->rawlen - offset, nbits, + kCarrierAc40HdrMark, kCarrierAc40HdrSpace, + kCarrierAc40BitMark, kCarrierAc40OneSpace, + kCarrierAc40BitMark, kCarrierAc40ZeroSpace, + kCarrierAc40BitMark, kCarrierAc40Gap, true)) return false; + + // Success + results->bits = nbits; + results->decode_type = CARRIER_AC40; + results->address = 0; + results->command = 0; + return true; +} +#endif // DECODE_CARRIER_AC40 + +#if SEND_CARRIER_AC64 +/// Send a Carrier 64bit HVAC formatted message. +/// Status: STABLE / Known to be working. +/// @param[in] data The message to be sent. +/// @param[in] nbits The bit size of the message being sent. +/// @param[in] repeat The number of times the message is to be repeated. +void IRsend::sendCarrierAC64(const uint64_t data, const uint16_t nbits, + const uint16_t repeat) { + sendGeneric(kCarrierAc64HdrMark, kCarrierAc64HdrSpace, kCarrierAc64BitMark, + kCarrierAc64OneSpace, kCarrierAc64BitMark, kCarrierAc64ZeroSpace, + kCarrierAc64BitMark, kCarrierAc64Gap, + data, nbits, kCarrierAcFreq, false, repeat, kDutyDefault); +} +#endif // SEND_CARRIER_AC64 + +#if DECODE_CARRIER_AC64 +/// Decode the supplied Carrier 64-bit HVAC message. +/// Status: STABLE / Known to be 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::decodeCarrierAC64(decode_results *results, uint16_t offset, + const uint16_t nbits, const bool strict) { + if (results->rawlen < 2 * nbits + kHeader + kFooter - 1 + offset) + return false; // Can't possibly be a valid Carrier message. + if (strict && nbits != kCarrierAc64Bits) + return false; // We expect Carrier to be 64 bits of message. + + if (!matchGeneric(results->rawbuf + offset, &(results->value), + results->rawlen - offset, nbits, + kCarrierAc64HdrMark, kCarrierAc64HdrSpace, + kCarrierAc64BitMark, kCarrierAc64OneSpace, + kCarrierAc64BitMark, kCarrierAc64ZeroSpace, + kCarrierAc64BitMark, kCarrierAc64Gap, true, + kUseDefTol, kMarkExcess, false)) return false; + + // Compliance + if (strict && !IRCarrierAc64::validChecksum(results->value)) return false; + + // Success + results->bits = nbits; + results->decode_type = CARRIER_AC64; + results->address = 0; + results->command = 0; + return true; +} +#endif // DECODE_CARRIER_AC64 + +/// 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? +IRCarrierAc64::IRCarrierAc64(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. +/// @note The state is powered off. +void IRCarrierAc64::stateReset(void) { remote_state = 0x109000002C2A5584; } + +/// Calculate the checksum for a given state. +/// @param[in] state The value to calc the checksum of. +/// @return The 4-bit checksum stored in a uint_8. +uint8_t IRCarrierAc64::calcChecksum(const uint64_t state) { + uint64_t data = GETBITS64(state, + kCarrierAc64ChecksumOffset + kCarrierAc64ChecksumSize, kCarrierAc64Bits - + (kCarrierAc64ChecksumOffset + kCarrierAc64ChecksumSize)); + uint8_t result = 0; + for (; data; data >>= 4) // Add each nibble together. + result += GETBITS64(data, 0, 4); + return result & 0xF; +} + +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @return true, if the state has a valid checksum. Otherwise, false. +bool IRCarrierAc64::validChecksum(const uint64_t state) { + // Validate the checksum of the given state. + return (GETBITS64(state, kCarrierAc64ChecksumOffset, + kCarrierAc64ChecksumSize) == calcChecksum(state)); +} + +/// Calculate and set the checksum values for the internal state. +void IRCarrierAc64::checksum(void) { + setBits(&remote_state, kCarrierAc64ChecksumOffset, kCarrierAc64ChecksumSize, + calcChecksum(remote_state)); +} + +/// Set up hardware to be able to send a message. +void IRCarrierAc64::begin(void) { _irsend.begin(); } + +#if SEND_CARRIER_AC64 +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. +void IRCarrierAc64::send(const uint16_t repeat) { + _irsend.sendCarrierAC64(getRaw(), kCarrierAc64Bits, repeat); +} +#endif // SEND_CARRIER_AC64 + +/// Get a copy of the internal state as a valid code for this protocol. +/// @return A valid code for this protocol based on the current internal state. +uint64_t IRCarrierAc64::getRaw(void) { + checksum(); // Ensure correct settings before sending. + return remote_state; +} + +/// Set the internal state from a valid code for this protocol. +/// @param[in] state A valid code for this protocol. +void IRCarrierAc64::setRaw(const uint64_t state) { remote_state = state; } + +/// Set the temp in deg C. +/// @param[in] temp The desired temperature in Celsius. +void IRCarrierAc64::setTemp(const uint8_t temp) { + uint8_t degrees = std::max(temp, kCarrierAc64MinTemp); + degrees = std::min(degrees, kCarrierAc64MaxTemp); + setBits(&remote_state, kCarrierAc64TempOffset, kCarrierAc64TempSize, + degrees - kCarrierAc64MinTemp); +} + +/// Get the current temperature from the internal state. +/// @return The current temperature in Celsius. +uint8_t IRCarrierAc64::getTemp(void) { + return GETBITS64(remote_state, kCarrierAc64TempOffset, kCarrierAc64TempSize) + + kCarrierAc64MinTemp; +} + +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. +void IRCarrierAc64::setPower(const bool on) { + setBit(&remote_state, kCarrierAc64PowerOffset, on); +} + +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. +bool IRCarrierAc64::getPower(void) { + return GETBIT64(remote_state, kCarrierAc64PowerOffset); +} + +/// Change the power setting to On. +void IRCarrierAc64::on(void) { setPower(true); } + +/// Change the power setting to Off. +void IRCarrierAc64::off(void) { setPower(false); } + +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. +uint8_t IRCarrierAc64::getMode(void) { + return GETBITS64(remote_state, kCarrierAc64ModeOffset, kCarrierAc64ModeSize); +} + +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. +void IRCarrierAc64::setMode(const uint8_t mode) { + switch (mode) { + case kCarrierAc64Heat: + case kCarrierAc64Cool: + case kCarrierAc64Fan: + setBits(&remote_state, kCarrierAc64ModeOffset, kCarrierAc64ModeSize, + mode); + return; + default: + this->setMode(kCarrierAc64Cool); + } +} + +/// Convert a standard A/C mode into its native mode. +/// @param[in] mode A stdAc::opmode_t to be converted to it's native equivalent. +/// @return The corresponding native mode. +uint8_t IRCarrierAc64::convertMode(const stdAc::opmode_t mode) { + switch (mode) { + case stdAc::opmode_t::kHeat: return kCarrierAc64Heat; + case stdAc::opmode_t::kFan: return kCarrierAc64Fan; + default: return kCarrierAc64Cool; + } +} + +/// Convert a native mode to it's common stdAc::opmode_t equivalent. +/// @param[in] mode A native operation mode to be converted. +/// @return The corresponding common stdAc::opmode_t mode. +stdAc::opmode_t IRCarrierAc64::toCommonMode(const uint8_t mode) { + switch (mode) { + case kCarrierAc64Heat: return stdAc::opmode_t::kHeat; + case kCarrierAc64Fan: return stdAc::opmode_t::kFan; + default: return stdAc::opmode_t::kCool; + } +} + +/// Get the current fan speed setting. +/// @return The current fan speed. +uint8_t IRCarrierAc64::getFan(void) { + return GETBITS64(remote_state, kCarrierAc64FanOffset, kCarrierAc64FanSize); +} + +/// Set the speed of the fan. +/// @param[in] speed The desired setting. +void IRCarrierAc64::setFan(const uint8_t speed) { + if (speed > kCarrierAc64FanHigh) + setFan(kCarrierAc64FanAuto); + else + setBits(&remote_state, kCarrierAc64FanOffset, kCarrierAc64FanSize, speed); +} + +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. +uint8_t IRCarrierAc64::convertFan(const stdAc::fanspeed_t speed) { + switch (speed) { + case stdAc::fanspeed_t::kMin: + case stdAc::fanspeed_t::kLow: return kCarrierAc64FanLow; + case stdAc::fanspeed_t::kMedium: return kCarrierAc64FanMedium; + case stdAc::fanspeed_t::kHigh: + case stdAc::fanspeed_t::kMax: return kCarrierAc64FanHigh; + default: return kCarrierAc64FanAuto; + } +} + +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. +stdAc::fanspeed_t IRCarrierAc64::toCommonFanSpeed(const uint8_t speed) { + switch (speed) { + case kCarrierAc64FanHigh: return stdAc::fanspeed_t::kHigh; + case kCarrierAc64FanMedium: return stdAc::fanspeed_t::kMedium; + case kCarrierAc64FanLow: return stdAc::fanspeed_t::kLow; + default: return stdAc::fanspeed_t::kAuto; + } +} + +/// Set the Vertical Swing mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. +void IRCarrierAc64::setSwingV(const bool on) { + setBit(&remote_state, kCarrierAc64SwingVOffset, on); +} + +/// Get the Vertical Swing mode of the A/C. +/// @return true, the setting is on. false, the setting is off. +bool IRCarrierAc64::getSwingV(void) { + return GETBIT64(remote_state, kCarrierAc64SwingVOffset); +} + +/// Set the Sleep mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. +void IRCarrierAc64::setSleep(const bool on) { + if (on) { + // Sleep sets a default value in the Off timer, and disables both timers. + setOffTimer(2 * 60); + // Clear the enable bits for each timer. + _cancelOnTimer(); + _cancelOffTimer(); + } + setBit(&remote_state, kCarrierAc64SleepOffset, on); +} + +/// Get the Sleep mode of the A/C. +/// @return true, the setting is on. false, the setting is off. +bool IRCarrierAc64::getSleep(void) { + return GETBIT64(remote_state, kCarrierAc64SleepOffset); +} + +/// Clear the On Timer enable bit. +void IRCarrierAc64::_cancelOnTimer(void) { + setBit(&remote_state, kCarrierAc64OnTimerEnableOffset, false); +} + +/// Get the current On Timer time. +/// @return The number of minutes it is set for. 0 means it's off. +/// @note The A/C protocol only supports one hour increments. +uint16_t IRCarrierAc64::getOnTimer(void) { + if (GETBIT64(remote_state, kCarrierAc64OnTimerEnableOffset)) + return GETBITS64(remote_state, kCarrierAc64OnTimerOffset, + kCarrierAc64TimerSize) * 60; + else + return 0; +} + +/// Set the On Timer time. +/// @param[in] nr_of_mins Number of minutes to set the timer to. +/// (< 60 is disable). +/// @note The A/C protocol only supports one hour increments. +void IRCarrierAc64::setOnTimer(const uint16_t nr_of_mins) { + uint8_t hours = std::min((uint8_t)(nr_of_mins / 60), kCarrierAc64TimerMax); + setBit(&remote_state, kCarrierAc64OnTimerEnableOffset, hours); // Enable + setBits(&remote_state, kCarrierAc64OnTimerOffset, kCarrierAc64TimerSize, + std::max(kCarrierAc64TimerMin, hours)); // Hours + if (hours) { // If enabled, disable the Off Timer & Sleep mode. + _cancelOffTimer(); + setSleep(false); + } +} + +/// Clear the Off Timer enable bit. +void IRCarrierAc64::_cancelOffTimer(void) { + setBit(&remote_state, kCarrierAc64OffTimerEnableOffset, false); +} + +/// Get the current Off Timer time. +/// @return The number of minutes it is set for. 0 means it's off. +/// @note The A/C protocol only supports one hour increments. +uint16_t IRCarrierAc64::getOffTimer(void) { + if (GETBIT64(remote_state, kCarrierAc64OffTimerEnableOffset)) + return GETBITS64(remote_state, kCarrierAc64OffTimerOffset, + kCarrierAc64TimerSize) * 60; + else + return 0; +} + +/// Set the Off Timer time. +/// @param[in] nr_of_mins Number of minutes to set the timer to. +/// (< 60 is disable). +/// @note The A/C protocol only supports one hour increments. +void IRCarrierAc64::setOffTimer(const uint16_t nr_of_mins) { + uint8_t hours = std::min((uint8_t)(nr_of_mins / 60), kCarrierAc64TimerMax); + // The time can be changed in sleep mode, but doesn't set the flag. + setBit(&remote_state, kCarrierAc64OffTimerEnableOffset, hours && !getSleep()); + setBits(&remote_state, kCarrierAc64OffTimerOffset, kCarrierAc64TimerSize, + std::max(kCarrierAc64TimerMin, hours)); // Hours + if (hours) { // If enabled, disable the On Timer & Sleep mode. + _cancelOnTimer(); + setSleep(false); + } +} + +/// Convert the internal state into a human readable string. +/// @return The current internal state expressed as a human readable String. +String IRCarrierAc64::toString(void) { + String result = ""; + result.reserve(120); // Reserve some heap for the string to reduce fragging. + result += addBoolToString(getPower(), kPowerStr, false); + result += addModeToString(getMode(), 0xFF, kCarrierAc64Cool, + kCarrierAc64Heat, 0xFF, kCarrierAc64Fan); + result += addTempToString(getTemp()); + result += addFanToString(getFan(), kCarrierAc64FanHigh, kCarrierAc64FanLow, + kCarrierAc64FanAuto, kCarrierAc64FanAuto, + kCarrierAc64FanMedium); + result += addBoolToString(getSwingV(), kSwingVStr); + result += addBoolToString(getSleep(), kSleepStr); + result += addLabeledString(getOnTimer() + ? minsToString(getOnTimer()) : kOffStr, + kOnTimerStr); + result += addLabeledString(getOffTimer() + ? minsToString(getOffTimer()) : kOffStr, + kOffTimerStr); + return result; +} + +/// Convert the A/C state to it's common stdAc::state_t equivalent. +/// @return A stdAc::state_t state. +stdAc::state_t IRCarrierAc64::toCommon(void) { + stdAc::state_t result; + result.protocol = decode_type_t::CARRIER_AC64; + result.model = -1; // No models used. + result.power = getPower(); + result.mode = toCommonMode(getMode()); + result.celsius = true; + result.degrees = getTemp(); + result.fanspeed = toCommonFanSpeed(getFan()); + result.swingv = getSwingV() ? stdAc::swingv_t::kAuto : stdAc::swingv_t::kOff; + result.sleep = getSleep() ? 0 : -1; + // Not supported. + result.swingh = stdAc::swingh_t::kOff; + result.turbo = false; + result.quiet = false; + result.clean = false; + result.filter = false; + result.beep = false; + result.econo = false; + result.light = false; + result.clock = -1; + return result; +} diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Carrier.h b/lib/IRremoteESP8266-2.7.8/src/ir_Carrier.h new file mode 100644 index 000000000..e2f4b7895 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Carrier.h @@ -0,0 +1,131 @@ +// Copyright 2020 David Conran +/// @file +/// @brief Carrier A/C +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1127 +/// @see https://docs.google.com/spreadsheets/d/1EZy78L0cn1KDIX1aKq2biptejFqCjD5HO3tLiRvXf48/edit#gid=0 + +// Supports: +// Brand: Carrier/Surrey, Model: 42QG5A55970 remote +// Brand: Carrier/Surrey, Model: 619EGX0090E0 A/C +// Brand: Carrier/Surrey, Model: 619EGX0120E0 A/C +// Brand: Carrier/Surrey, Model: 619EGX0180E0 A/C +// Brand: Carrier/Surrey, Model: 619EGX0220E0 A/C +// Brand: Carrier/Surrey, Model: 53NGK009/012 Inverter + +#ifndef IR_CARRIER_H_ +#define IR_CARRIER_H_ + +#define __STDC_LIMIT_MACROS +#include +#ifndef UNIT_TEST +#include +#endif +#include "IRremoteESP8266.h" +#include "IRsend.h" +#ifdef UNIT_TEST +#include "IRsend_test.h" +#endif + + +// Constants + +// CARRIER_AC64 +const uint8_t kCarrierAc64ChecksumOffset = 16; +const uint8_t kCarrierAc64ChecksumSize = 4; +const uint8_t kCarrierAc64ModeOffset = kCarrierAc64ChecksumOffset + + kCarrierAc64ChecksumSize; // 20 +const uint8_t kCarrierAc64ModeSize = 2; +const uint8_t kCarrierAc64Heat = 0b01; // 1 +const uint8_t kCarrierAc64Cool = 0b10; // 2 +const uint8_t kCarrierAc64Fan = 0b11; // 3 +const uint8_t kCarrierAc64FanOffset = kCarrierAc64ModeOffset + + kCarrierAc64ModeSize; // 22 +const uint8_t kCarrierAc64FanSize = 2; +const uint8_t kCarrierAc64FanAuto = 0b00; // 0 +const uint8_t kCarrierAc64FanLow = 0b01; // 1 +const uint8_t kCarrierAc64FanMedium = 0b10; // 2 +const uint8_t kCarrierAc64FanHigh = 0b11; // 3 +const uint8_t kCarrierAc64TempOffset = kCarrierAc64FanOffset + + kCarrierAc64FanSize; // 24 +const uint8_t kCarrierAc64TempSize = 4; +const uint8_t kCarrierAc64MinTemp = 16; // Celsius +const uint8_t kCarrierAc64MaxTemp = 30; // Celsius +const uint8_t kCarrierAc64SwingVOffset = kCarrierAc64TempOffset + + kCarrierAc64TempSize + 1; // 29 +const uint8_t kCarrierAc64PowerOffset = kCarrierAc64SwingVOffset + 6 + 1; // 36 +const uint8_t kCarrierAc64OffTimerEnableOffset = + kCarrierAc64PowerOffset + 1; // 37 +const uint8_t kCarrierAc64OnTimerEnableOffset = + kCarrierAc64OffTimerEnableOffset + 1; // 38 +const uint8_t kCarrierAc64SleepOffset = + kCarrierAc64OnTimerEnableOffset + 1; // 39 +const uint8_t kCarrierAc64TimerSize = 4; +const uint8_t kCarrierAc64TimerMax = 9; // Hours. +const uint8_t kCarrierAc64TimerMin = 1; // Hours. +const uint8_t kCarrierAc64OnTimerOffset = + kCarrierAc64SleepOffset + 12 + 1; // 52 +const uint8_t kCarrierAc64OffTimerOffset = kCarrierAc64OnTimerOffset + + kCarrierAc64TimerSize + 4; // 60 + + +// Classes + +/// Class for handling detailed Carrier 64 bit A/C messages. +class IRCarrierAc64 { + public: + explicit IRCarrierAc64(const uint16_t pin, const bool inverted = false, + const bool use_modulation = true); + + void stateReset(); +#if SEND_CARRIER_AC64 + void send(const uint16_t repeat = kCarrierAc64MinRepeat); + /// 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_CARRIER_AC64 + void begin(); + static uint8_t calcChecksum(const uint64_t state); + static bool validChecksum(const uint64_t state); + void setPower(const bool on); + bool getPower(); + void on(); + void off(); + void setTemp(const uint8_t temp); + uint8_t getTemp(); + void setSwingV(const bool on); + bool getSwingV(void); + void setSleep(const bool on); + bool getSleep(void); + void setFan(const uint8_t speed); + uint8_t getFan(); + void setMode(const uint8_t mode); + uint8_t getMode(); + void setOnTimer(const uint16_t nr_of_mins); + uint16_t getOnTimer(void); + void setOffTimer(const uint16_t nr_of_mins); + uint16_t getOffTimer(void); + uint64_t getRaw(); + void setRaw(const uint64_t state); + uint8_t convertMode(const stdAc::opmode_t mode); + uint8_t convertFan(const stdAc::fanspeed_t speed); + static stdAc::opmode_t toCommonMode(const uint8_t mode); + static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed); + stdAc::state_t toCommon(void); + String toString(); +#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 + uint64_t remote_state; ///< The state of the IR remote. + void checksum(void); + void _cancelOnTimer(void); + void _cancelOffTimer(void); +}; +#endif // IR_CARRIER_H_ diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Coolix.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Coolix.cpp similarity index 75% rename from lib/IRremoteESP8266-2.7.5/src/ir_Coolix.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Coolix.cpp index 65535442a..b33a3cf43 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Coolix.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Coolix.cpp @@ -1,5 +1,9 @@ // Copyright bakrus // Copyright 2017,2019 David Conran +// added by (send) bakrus & (decode) crankyoldgit +/// @file +/// @brief Coolix A/C / heatpump +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/484 #include "ir_Coolix.h" #include @@ -11,18 +15,6 @@ #include "IRtext.h" #include "IRutils.h" -// Coolix A/C / heatpump added by (send) bakrus & (decode) crankyoldgit -// -// Supports: -// Brand: Beko, Model: RG57K7(B)/BGEF Remote -// Brand: Beko, Model: BINR 070/071 split-type A/C -// Brand: Midea, Model: RG52D/BGE Remote -// Brand: Midea, Model: MS12FU-10HRDN1-QRD0GW(B) A/C -// Brand: Midea, Model: MSABAU-07HRFN1-QRD0GW A/C (circa 2016) -// Brand: Tokio, Model: AATOEMF17-12CHR1SW split-type RG51|50/BGE Remote -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/484 - // Constants // Pulse parms are *50-100 for the Mark and *50+100 for the space // First MARK is the one after the long gap @@ -50,17 +42,12 @@ using irutils::setBit; using irutils::setBits; #if SEND_COOLIX -// Send a Coolix message -// -// Args: -// data: Contents of the message to be sent. -// nbits: Nr. of bits of data to be sent. Typically kCoolixBits. -// repeat: Nr. of additional times the message is to be sent. -// -// Status: STABLE / Confirmed Working. -// -// Ref: -// https://github.com/z3t0/Arduino-IRremote/blob/master/ir_COOLIX.cpp +/// Send a Coolix message +/// Status: STABLE / Confirmed Working. +/// @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. +/// @see https://github.com/z3t0/Arduino-IRremote/blob/master/ir_COOLIX.cpp void IRsend::sendCOOLIX(uint64_t data, uint16_t nbits, uint16_t repeat) { if (nbits % 8 != 0) return; // nbits is required to be a multiple of 8. @@ -94,15 +81,15 @@ void IRsend::sendCOOLIX(uint64_t data, uint16_t nbits, uint16_t repeat) { } #endif -// IRCoolixAC class -// Supports: -// RG57K7(B)/BGEF remote control for Beko BINR 070/071 split-type aircon. -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/484 +/// 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? IRCoolixAC::IRCoolixAC(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 IRCoolixAC::stateReset() { setRaw(kCoolixDefaultState); clearSensorTemp(); @@ -116,9 +103,12 @@ void IRCoolixAC::stateReset() { swingVFlag = false; } +/// Set up hardware to be able to send a message. void IRCoolixAC::begin() { _irsend.begin(); } #if SEND_COOLIX +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRCoolixAC::send(const uint16_t repeat) { _irsend.sendCOOLIX(remote_state, kCoolixBits, repeat); // make sure to remove special state from remote_state @@ -127,8 +117,12 @@ void IRCoolixAC::send(const uint16_t repeat) { } #endif // SEND_COOLIX +/// Get a copy of the internal state as a valid code for this protocol. +/// @return A valid code for this protocol based on the current internal state. uint32_t IRCoolixAC::getRaw() { return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. void IRCoolixAC::setRaw(const uint32_t new_code) { powerFlag = true; // Everything that is not the special power off mesg is On. if (!handleSpecialState(new_code)) { @@ -143,7 +137,8 @@ void IRCoolixAC::setRaw(const uint32_t new_code) { remote_state = new_code; } -// Return true if the current state is a special state. +/// Is the current state is a special state? +/// @return true, if it is. false if it isn't. bool IRCoolixAC::isSpecialState(void) { switch (remote_state) { case kCoolixClean: @@ -156,8 +151,12 @@ bool IRCoolixAC::isSpecialState(void) { } } -// Special state means commands that are not -// affecting Temperature/Mode/Fan +/// Adjust any internal settings based on the type of special state we are +/// supplied. Does nothing if it isn't a special state. +/// @param[in] data The state we need to act upon. +/// @note Special state means commands that are not affecting +/// Temperature/Mode/Fan +/// @return true, if it is a special state. false if it isn't. bool IRCoolixAC::handleSpecialState(const uint32_t data) { switch (data) { case kCoolixClean: @@ -184,12 +183,15 @@ bool IRCoolixAC::handleSpecialState(const uint32_t data) { return true; } -// must be called before every special state -// to make sure the remote_state is safe +/// Backup the current internal state as long as it isn't a special state. +/// @note: Must be called before every special state to make sure the +/// remote_state is safe void IRCoolixAC::updateSavedState(void) { if (!isSpecialState()) saved_state = remote_state; } +/// Restore the current internal state from backup as long as it isn't a +/// special state. void IRCoolixAC::recoverSavedState(void) { // If the current state is a special one, last known normal one. if (isSpecialState()) remote_state = saved_state; @@ -198,14 +200,21 @@ void IRCoolixAC::recoverSavedState(void) { if (isSpecialState()) stateReset(); } +/// Set the raw (native) temperature value. +/// @note Bypasses any checks. +/// @param[in] code The desired native temperature. void IRCoolixAC::setTempRaw(const uint8_t code) { setBits(&remote_state, kCoolixTempOffset, kCoolixTempSize, code); } +/// Get the raw (native) temperature value. +/// @return The native temperature value. uint8_t IRCoolixAC::getTempRaw() { return GETBITS32(remote_state, kCoolixTempOffset, kCoolixTempSize); } +/// Set the temperature. +/// @param[in] desired The temperature in degrees celsius. void IRCoolixAC::setTemp(const uint8_t desired) { // Range check. uint8_t temp = std::min(desired, kCoolixTempMax); @@ -213,6 +222,8 @@ void IRCoolixAC::setTemp(const uint8_t desired) { setTempRaw(kCoolixTempMap[temp - kCoolixTempMin]); } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRCoolixAC::getTemp() { const uint8_t code = getTempRaw(); for (uint8_t i = 0; i < kCoolixTempRange; i++) @@ -220,10 +231,15 @@ uint8_t IRCoolixAC::getTemp() { return kCoolixTempMax; // Not a temp we expected. } +/// Set the raw (native) sensor temperature value. +/// @note Bypasses any checks or additional actions. +/// @param[in] code The desired native sensor temperature. void IRCoolixAC::setSensorTempRaw(const uint8_t code) { setBits(&remote_state, kCoolixSensorTempOffset, kCoolixSensorTempSize, code); } +/// Set the sensor temperature. +/// @param[in] desired The temperature in degrees celsius. void IRCoolixAC::setSensorTemp(const uint8_t desired) { uint8_t temp = desired; temp = std::min(temp, kCoolixSensorTempMax); @@ -232,16 +248,22 @@ void IRCoolixAC::setSensorTemp(const uint8_t desired) { setZoneFollow(true); // Setting a Sensor temp means you want to Zone Follow. } +/// Get the sensor temperature setting. +/// @return The current setting for sensor temp. in degrees celsius. uint8_t IRCoolixAC::getSensorTemp() { return GETBITS32(remote_state, kCoolixSensorTempOffset, kCoolixSensorTempSize) + kCoolixSensorTempMin; } +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRCoolixAC::getPower() { // There is only an off state. Everything else is "on". return powerFlag; } +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRCoolixAC::setPower(const bool on) { if (!on) { updateSavedState(); @@ -254,12 +276,17 @@ void IRCoolixAC::setPower(const bool on) { powerFlag = on; } +/// Change the power setting to On. void IRCoolixAC::on(void) { this->setPower(true); } +/// Change the power setting to Off. void IRCoolixAC::off(void) { this->setPower(false); } +/// Get the Swing setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRCoolixAC::getSwing() { return swingFlag; } +/// Toggle the Swing mode of the A/C. void IRCoolixAC::setSwing() { // Assumes that repeated sending "swing" toggles the action on the device. updateSavedState(); @@ -267,16 +294,22 @@ void IRCoolixAC::setSwing() { swingFlag = !swingFlag; } +/// Get the Sleep setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRCoolixAC::getSleep() { return sleepFlag; } +/// Toggle the Sleep mode of the A/C. void IRCoolixAC::setSleep() { updateSavedState(); remote_state = kCoolixSleep; sleepFlag = !sleepFlag; } +/// Get the Turbo setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRCoolixAC::getTurbo() { return turboFlag; } +/// Toggle the Turbo mode of the A/C. void IRCoolixAC::setTurbo() { // Assumes that repeated sending "turbo" toggles the action on the device. updateSavedState(); @@ -284,8 +317,11 @@ void IRCoolixAC::setTurbo() { turboFlag = !turboFlag; } +/// Get the Led (light) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRCoolixAC::getLed() { return ledFlag; } +/// Toggle the Led (light) mode of the A/C. void IRCoolixAC::setLed() { // Assumes that repeated sending "Led" toggles the action on the device. updateSavedState(); @@ -293,29 +329,39 @@ void IRCoolixAC::setLed() { ledFlag = !ledFlag; } +/// Get the Clean setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRCoolixAC::getClean() { return cleanFlag; } +/// Toggle the Clean mode of the A/C. void IRCoolixAC::setClean() { updateSavedState(); remote_state = kCoolixClean; cleanFlag = !cleanFlag; } +/// Get the Zone Follow setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRCoolixAC::getZoneFollow() { return zoneFollowFlag; } -// Internal use only. +/// Change the Zone Follow setting. +/// @note Internal use only. +/// @param[in] on true, the setting is on. false, the setting is off. void IRCoolixAC::setZoneFollow(bool on) { zoneFollowFlag = on; setBit(&remote_state, kCoolixZoneFollowMaskOffset, on); } +/// Clear the Sensor Temperature setting.. void IRCoolixAC::clearSensorTemp() { setZoneFollow(false); setSensorTempRaw(kCoolixSensorTempIgnoreCode); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRCoolixAC::setMode(const uint8_t mode) { uint32_t actualmode = mode; switch (actualmode) { @@ -342,6 +388,8 @@ void IRCoolixAC::setMode(const uint8_t mode) { setBits(&remote_state, kCoolixModeOffset, kCoolixModeSize, actualmode); } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRCoolixAC::getMode() { uint8_t mode = GETBITS32(remote_state, kCoolixModeOffset, kCoolixModeSize); @@ -350,10 +398,15 @@ uint8_t IRCoolixAC::getMode() { return mode; } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRCoolixAC::getFan() { return GETBITS32(remote_state, kCoolixFanOffset, kCoolixFanSize); } +/// Set the speed of the fan. +/// @param[in] speed The desired setting. +/// @param[in] modecheck Do we enforce any mode limitations before setting? void IRCoolixAC::setFan(const uint8_t speed, const bool modecheck) { uint8_t newspeed = speed; switch (speed) { @@ -389,7 +442,9 @@ void IRCoolixAC::setFan(const uint8_t speed, const bool modecheck) { setBits(&remote_state, kCoolixFanOffset, kCoolixFanSize, newspeed); } -// Convert a standard A/C mode into its native mode. +/// Convert a standard A/C mode into its native mode. +/// @param[in] mode A stdAc::opmode_t to be converted to it's native equivalent. +/// @return The corresponding native mode. uint8_t IRCoolixAC::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kCoolixCool; @@ -400,7 +455,9 @@ uint8_t IRCoolixAC::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRCoolixAC::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: @@ -412,7 +469,9 @@ uint8_t IRCoolixAC::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode to it's common stdAc::opmode_t equivalent. +/// @param[in] mode A native operation mode to be converted. +/// @return The corresponding common stdAc::opmode_t mode. stdAc::opmode_t IRCoolixAC::toCommonMode(const uint8_t mode) { switch (mode) { case kCoolixCool: return stdAc::opmode_t::kCool; @@ -423,7 +482,9 @@ stdAc::opmode_t IRCoolixAC::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRCoolixAC::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kCoolixFanMax: return stdAc::fanspeed_t::kMax; @@ -433,8 +494,9 @@ stdAc::fanspeed_t IRCoolixAC::toCommonFanSpeed(const uint8_t speed) { } } -// Convert the A/C state to it's common equivalent. Utilise the previous -// state if supplied. +/// Convert the A/C state to it's common stdAc::state_t equivalent. +/// @param[in] prev Ptr to the previous state if required. +/// @return A stdAc::state_t state. stdAc::state_t IRCoolixAC::toCommon(const stdAc::state_t *prev) { stdAc::state_t result; // Start with the previous state if given it. @@ -492,7 +554,8 @@ stdAc::state_t IRCoolixAC::toCommon(const stdAc::state_t *prev) { return result; } -// Convert the internal state into a human readable string. +/// Convert the internal state into a human readable string. +/// @return The current internal state expressed as a human readable String. String IRCoolixAC::toString(void) { String result = ""; result.reserve(100); // Reserve some heap for the string to reduce fragging. @@ -575,18 +638,15 @@ String IRCoolixAC::toString(void) { } #if DECODE_COOLIX -// Decode the supplied Coolix message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kCoolixBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Known Working. +/// Decode the supplied Coolix A/C message. +/// Status: STABLE / Known 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::decodeCOOLIX(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { // The protocol sends the data normal + inverted, alternating on diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Coolix.h b/lib/IRremoteESP8266-2.7.8/src/ir_Coolix.h similarity index 87% rename from lib/IRremoteESP8266-2.7.5/src/ir_Coolix.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Coolix.h index 6f7778416..3b95aa2e4 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Coolix.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Coolix.h @@ -2,6 +2,15 @@ // // Copyright 2018 David Conran +// Supports: +// Brand: Beko, Model: RG57K7(B)/BGEF Remote +// Brand: Beko, Model: BINR 070/071 split-type A/C +// Brand: Midea, Model: RG52D/BGE Remote +// Brand: Midea, Model: MS12FU-10HRDN1-QRD0GW(B) A/C +// Brand: Midea, Model: MSABAU-07HRFN1-QRD0GW A/C (circa 2016) +// Brand: Tokio, Model: AATOEMF17-12CHR1SW split-type RG51|50/BGE Remote +// Brand: Airwell, Model: RC08B remote + #ifndef IR_COOLIX_H_ #define IR_COOLIX_H_ @@ -16,14 +25,6 @@ #include "IRsend_test.h" #endif -// Supports: -// Brand: Beko, Model: RG57K7(B)/BGEF Remote -// Brand: Beko, Model: BINR 070/071 split-type A/C -// Brand: Midea, Model: RG52D/BGE Remote -// Brand: Midea, Model: MS12FU-10HRDN1-QRD0GW(B) A/C -// Brand: Midea, Model: MSABAU-07HRFN1-QRD0GW A/C (circa 2016) -// Brand: Tokio, Model: AATOEMF17-12CHR1SW split-type RG51|50/BGE Remote -// Brand: Airwell, Model: RC08B remote // Ref: // https://github.com/crankyoldgit/IRremoteESP8266/issues/484 // Kudos: @@ -98,15 +99,21 @@ const uint32_t kCoolixCmdFan = 0b101100101011111111100100; // 0xB2BFE4 const uint32_t kCoolixDefaultState = 0b101100100001111111001000; // 0xB21FC8 // Classes + +/// Class for handling detailed Coolix A/C messages. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/484 class IRCoolixAC { public: explicit IRCoolixAC(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - void stateReset(); #if SEND_COOLIX void send(const uint16_t repeat = kCoolixDefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + /// 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_COOLIX void begin(); void on(); @@ -144,9 +151,11 @@ class IRCoolixAC { #ifndef UNIT_TEST private: - IRsend _irsend; + IRsend _irsend; ///< Instance of the IR send class #else - IRsendTest _irsend; + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond #endif // internal state bool powerFlag; @@ -159,8 +168,8 @@ class IRCoolixAC { bool swingHFlag; bool swingVFlag; - uint32_t remote_state; // The state of the IR remote in IR code form. - uint32_t saved_state; // Copy of the state if we required a special mode. + uint32_t remote_state; ///< The state of the IR remote in IR code form. + uint32_t saved_state; ///< Copy of the state if we required a special mode. void setTempRaw(const uint8_t code); uint8_t getTempRaw(); void setSensorTempRaw(const uint8_t code); diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Corona.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Corona.cpp new file mode 100644 index 000000000..2ba6044bf --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Corona.cpp @@ -0,0 +1,598 @@ +// Copyright 2020 Christian Nilsson +// +/// @file +/// @brief Corona A/C protocol +/// @note Unsupported: +/// - Auto/Max button press (special format) + +#include "ir_Corona.h" +#include +#include +#include "IRac.h" +#include "IRrecv.h" +#include "IRsend.h" +#include "IRtext.h" +#include "IRutils.h" + +using irutils::addBoolToString; +using irutils::addLabeledString; +using irutils::addModeToString; +using irutils::addTempToString; +using irutils::addFanToString; +using irutils::minsToString; +using irutils::setBit; +using irutils::setBits; + +// Constants +const uint16_t kCoronaAcHdrMark = 3500; +const uint16_t kCoronaAcHdrSpace = 1680; +const uint16_t kCoronaAcBitMark = 450; +const uint16_t kCoronaAcOneSpace = 1270; +const uint16_t kCoronaAcZeroSpace = 420; +const uint16_t kCoronaAcSpaceGap = 10800; +const uint16_t kCoronaAcFreq = 38000; // Hz. +const uint16_t kCoronaAcOverheadShort = 3; +const uint16_t kCoronaAcOverhead = 11; // full message +const uint8_t kCoronaTolerance = 5; // +5% + +#if SEND_CORONA_AC +/// Send a CoronaAc formatted message. +/// Status: STABLE / Working on real device. +/// @param[in] data An array of bytes containing the IR command. +/// @param[in] nbytes Nr. of bytes of data in the array. +/// e.g. +/// @code +/// uint8_t data[kCoronaAcStateLength] = { +/// 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x37, 0xC8, +/// 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, +/// 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; +/// @endcode +/// @param[in] repeat Nr. of times the message is to be repeated. +void IRsend::sendCoronaAc(const uint8_t data[], + const uint16_t nbytes, const uint16_t repeat) { + if (nbytes < kCoronaAcSectionBytes) return; + if (kCoronaAcSectionBytes < nbytes && + nbytes < kCoronaAcStateLength) return; + for (uint16_t r = 0; r <= repeat; r++) { + uint16_t pos = 0; + // Data Section #1 - 3 loop + // e.g. + // bits = 56; bytes = 7; + // #1 *(data + pos) = {0x28, 0x61, 0x3D, 0x19, 0xE6, 0x37, 0xC8}; + // #2 *(data + pos) = {0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00}; + // #3 *(data + pos) = {0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + for (uint8_t section = 0; section < kCoronaAcSections; section++) { + sendGeneric(kCoronaAcHdrMark, kCoronaAcHdrSpace, + kCoronaAcBitMark, kCoronaAcOneSpace, + kCoronaAcBitMark, kCoronaAcZeroSpace, + kCoronaAcBitMark, kCoronaAcSpaceGap, + data + pos, kCoronaAcSectionBytes, + kCoronaAcFreq, false, kNoRepeat, kDutyDefault); + pos += kCoronaAcSectionBytes; // Adjust by how many bytes was sent + // don't send more data then what we have + if (nbytes <= pos) + break; + } + } +} +#endif // SEND_CORONA_AC + +#if DECODE_CORONA_AC +/// Decode the supplied CoronaAc message. +/// Status: STABLE / Appears to be working. +/// @param[in,out] results Ptr to the data to decode & where to store it +/// @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::decodeCoronaAc(decode_results *results, uint16_t offset, + const uint16_t nbits, const bool strict) { + bool isLong = results->rawlen >= kCoronaAcBits * 2; + if (results->rawlen < 2 * nbits + + (isLong ? kCoronaAcOverhead : kCoronaAcOverheadShort) + - offset) + return false; // Too short a message to match. + if (strict && nbits != kCoronaAcBits && nbits != kCoronaAcBitsShort) + return false; + + uint16_t pos = 0; + uint16_t used = 0; + + // Data Section #1 - 3 loop + // e.g. + // bits = 56; bytes = 7; + // #1 *(results->state + pos) = {0x28, 0x61, 0x3D, 0x19, 0xE6, 0x37, 0xC8}; + // #2 *(results->state + pos) = {0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00}; + // #3 *(results->state + pos) = {0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + for (uint8_t section = 0; section < kCoronaAcSections; section++) { + DPRINT(uint64ToString(section)); + used = matchGeneric(results->rawbuf + offset, results->state + pos, + results->rawlen - offset, kCoronaAcBitsShort, + kCoronaAcHdrMark, kCoronaAcHdrSpace, + kCoronaAcBitMark, kCoronaAcOneSpace, + kCoronaAcBitMark, kCoronaAcZeroSpace, + kCoronaAcBitMark, kCoronaAcSpaceGap, true, + _tolerance + kCoronaTolerance, kMarkExcess, false); + if (used == 0) return false; // We failed to find any data. + // short versions section 0 is special + if (strict && !IRCoronaAc::validSection(results->state, pos, + isLong ? section : 3)) + return false; + offset += used; // Adjust for how much of the message we read. + pos += kCoronaAcSectionBytes; // Adjust by how many bytes of data was read + // don't read more data then what we have + if (results->rawlen <= offset) + break; + } + + // Re-check we got the correct size/length due to the way we read the data. + if (strict && pos * 8 != kCoronaAcBits && pos * 8 != kCoronaAcBitsShort) { + DPRINTLN("strict bit match fail"); + return false; + } + + // Success + results->decode_type = decode_type_t::CORONA_AC; + results->bits = pos * 8; + // No need to record the state as we stored it as we decoded it. + // As we use result->state, we don't record value, address, or command as it + // is a union data type. + return true; +} +#endif // DECODE_CORONA_AC + +/// Class constructor for handling detailed Corona A/C messages. +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? +IRCoronaAc::IRCoronaAc(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. +/// @note The state is powered off. +void IRCoronaAc::stateReset(void) { + // known good state + remote_state[kCoronaAcSectionData0Pos] = kCoronaAcSectionData0Base; + remote_state[kCoronaAcSectionData1Pos] = 0x00; // ensure no unset mem + setPowerButton(true); // we default to this on, any timer removes it + setTemp(kCoronaAcMinTemp); + setMode(kCoronaAcModeCool); + setFan(kCoronaAcFanAuto); + setOnTimer(kCoronaAcTimerOff); + setOffTimer(kCoronaAcTimerOff); + // headers and checks are fixed in getRaw by checksum(remote_state) +} + +/// Get the byte that identifies the section +/// @param[in] section Index of the section 0-2, +/// 3 and above is used as the special case for short message +/// @return The byte used for the section +uint8_t IRCoronaAc::getSectionByte(const uint8_t section) { + // base byte + uint8_t b = kCoronaAcSectionLabelBase; + // 2 enabled bits shifted 0-2 bits depending on section + if (section >= 3) + return 0b10010000 | b; + setBits(&b, kHighNibble, kNibbleSize, 0b11 << section); + return b; +} + +/// Check that a CoronaAc Section part is valid with section byte and inverted +/// @param[in] state An array of bytes containing the section +/// @param[in] pos Where to start in the state array +/// @param[in] section Which section to work with +/// Used to get the section byte, and is validated against pos +/// @return true if section is valid, otherwise false +bool IRCoronaAc::validSection(const uint8_t state[], const uint16_t pos, + const uint8_t section) { + // sanity check, pos must match section, section 4 is at pos 0 + if ((section % kCoronaAcSections) * kCoronaAcSectionBytes != pos) + return false; + // all individual sections has the same prefix + if (state[pos + kCoronaAcSectionHeader0Pos] != kCoronaAcSectionHeader0) { + DPRINT("State "); + DPRINT(pos + kCoronaAcSectionHeader0Pos); + DPRINT(" expected 0x28 was "); + DPRINTLN(uint64ToString(state[pos + kCoronaAcSectionHeader0Pos], 16)); + return false; + } + if (state[pos + kCoronaAcSectionHeader1Pos] != kCoronaAcSectionHeader1) { + DPRINT("State "); + DPRINT(pos + kCoronaAcSectionHeader1Pos); + DPRINT(" expected 0x61 was "); + DPRINTLN(uint64ToString(state[pos + kCoronaAcSectionHeader1Pos], 16)); + return false; + } + + // checking section byte + if (state[pos + kCoronaAcSectionLabelPos] != getSectionByte(section)) { + DPRINT("check 2 not matching, got "); + DPRINT(uint64ToString(state[pos + kCoronaAcSectionLabelPos], 16)); + DPRINT(" expected "); + DPRINTLN(uint64ToString(getSectionByte(section), 16)); + return false; + } + + // checking inverts + uint8_t d0invinv = ~state[pos + kCoronaAcSectionData0InvPos]; + if (state[pos + kCoronaAcSectionData0Pos] != d0invinv) { + DPRINT("inverted 3 - 4 not matching, got "); + DPRINT(uint64ToString(state[pos + kCoronaAcSectionData0Pos], 16)); + DPRINT(" vs "); + DPRINTLN(uint64ToString(state[pos + kCoronaAcSectionData0InvPos], 16)); + return false; + } + uint8_t d1invinv = ~state[pos + kCoronaAcSectionData1InvPos]; + if (state[pos + kCoronaAcSectionData1Pos] != d1invinv) { + DPRINT("inverted 5 - 6 not matching, got "); + DPRINT(uint64ToString(state[pos + kCoronaAcSectionData1Pos], 16)); + DPRINT(" vs "); + DPRINTLN(uint64ToString(state[pos + kCoronaAcSectionData1InvPos], 16)); + return false; + } + return true; +} + +/// Calculate and set the check values for the internal state. +/// @param[in,out] data The array to be modified +void IRCoronaAc::checksum(uint8_t* data) { + uint8_t pos; + for (uint8_t section = 0; section < kCoronaAcSections; section++) { + pos = section * kCoronaAcSectionBytes; + data[pos + kCoronaAcSectionHeader0Pos] = kCoronaAcSectionHeader0; + data[pos + kCoronaAcSectionHeader1Pos] = kCoronaAcSectionHeader1; + data[pos + kCoronaAcSectionLabelPos] = getSectionByte(section); + data[pos + kCoronaAcSectionData0InvPos] = + ~data[pos + kCoronaAcSectionData0Pos]; + data[pos + kCoronaAcSectionData1InvPos] = + ~data[pos + kCoronaAcSectionData1Pos]; + } +} + +/// Set up hardware to be able to send a message. +void IRCoronaAc::begin(void) { _irsend.begin(); } + +#if SEND_CORONA_AC +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. +void IRCoronaAc::send(const uint16_t repeat) { + // if no timer, always send once without power press + if (!getOnTimer() && !getOffTimer()) { + setPowerButton(false); + _irsend.sendCoronaAc(getRaw(), kCoronaAcStateLength, repeat); + // and then with power press + setPowerButton(true); + } + _irsend.sendCoronaAc(getRaw(), kCoronaAcStateLength, repeat); +} +#endif // SEND_CORONA_AC + +/// Get a copy of the internal state as a valid code for this protocol. +/// @return A Ptr to a valid code for this protocol based on the current +/// internal state. +/// @note To get stable AC state, if no timers, send once +/// without PowerButton set, and once with +uint8_t* IRCoronaAc::getRaw(void) { + checksum(remote_state); // Ensure correct check bits before sending. + return remote_state; +} + +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid state for this protocol. +/// @param[in] length of the new_code array. +void IRCoronaAc::setRaw(const uint8_t new_code[], const uint16_t length) { + memcpy(remote_state, new_code, std::min(length, kCoronaAcStateLength)); +} + +/// Set the temp in deg C. +/// @param[in] temp The desired temperature in Celsius. +void IRCoronaAc::setTemp(const uint8_t temp) { + uint8_t degrees = std::max(temp, kCoronaAcMinTemp); + degrees = std::min(degrees, kCoronaAcMaxTemp); + setBits(&remote_state[kCoronaAcSectionData1Pos], kCoronaAcTempOffset, + kCoronaAcTempSize, degrees - kCoronaAcMinTemp + 1); +} + +/// Get the current temperature from the internal state. +/// @return The current temperature in Celsius. +uint8_t IRCoronaAc::getTemp(void) { + return GETBITS8(remote_state[kCoronaAcSectionData1Pos], kCoronaAcTempOffset, + kCoronaAcTempSize) + kCoronaAcMinTemp - 1; +} + +/// Change the power setting. (in practice Standby, remote power) +/// @param[in] on true, the setting is on. false, the setting is off. +void IRCoronaAc::_setPower(const bool on) { + setBit(&remote_state[kCoronaAcSectionData1Pos], kCoronaAcPowerOffset, on); +} + +/// Change the power setting. (in practice Standby, remote power) +/// @param[in] on true, the setting is on. false, the setting is off. +/// @note If changed, setPowerButton is also needed, +/// unless timer is or was active +void IRCoronaAc::setPower(const bool on) { + _setPower(on); + // setting power state resets timers that would cause the state + if (on) + setOnTimer(kCoronaAcTimerOff); + else + setOffTimer(kCoronaAcTimerOff); +} + +/// Get the current power setting. (in practice Standby, remote power) +/// @return true, the setting is on. false, the setting is off. +bool IRCoronaAc::getPower(void) { + return GETBIT8(remote_state[kCoronaAcSectionData1Pos], kCoronaAcPowerOffset); +} + +/// Change the power button setting. +/// @param[in] on true, the setting is on. false, the setting is off. +/// @note this sets that the AC should set power, +/// use setPower to define if the AC should end up as on or off +/// When no timer is active, the below is a truth table +/// With AC On, a command with setPower and setPowerButton gives nothing +/// With AC On, a command with setPower but not setPowerButton is ok +/// With AC Off, a command with setPower but not setPowerButton gives nothing +/// With AC Off, a command with setPower and setPowerButton is ok +void IRCoronaAc::setPowerButton(const bool on) { + setBit(&remote_state[kCoronaAcSectionData1Pos], + kCoronaAcPowerButtonOffset, on); +} + +/// Get the value of the current power button setting. +/// @return true, the setting is on. false, the setting is off. +bool IRCoronaAc::getPowerButton(void) { + return GETBIT8(remote_state[kCoronaAcSectionData1Pos], + kCoronaAcPowerButtonOffset); +} + +/// Change the power setting to On. +void IRCoronaAc::on(void) { setPower(true); } + +/// Change the power setting to Off. +void IRCoronaAc::off(void) { setPower(false); } + +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. +uint8_t IRCoronaAc::getMode(void) { + return GETBITS8(remote_state[kCoronaAcSectionData1Pos], + kCoronaAcModeOffset, kCoronaAcModeSize); +} + +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. +void IRCoronaAc::setMode(const uint8_t mode) { + switch (mode) { + case kCoronaAcModeCool: + case kCoronaAcModeDry: + case kCoronaAcModeFan: + case kCoronaAcModeHeat: + setBits(&remote_state[kCoronaAcSectionData1Pos], + kCoronaAcModeOffset, kCoronaAcModeSize, + mode); + return; + default: + this->setMode(kCoronaAcModeCool); + } +} + +/// Convert a standard A/C mode into its native mode. +/// @param[in] mode A stdAc::opmode_t mode to be +/// converted to it's native equivalent +/// @return The corresponding native mode. +uint8_t IRCoronaAc::convertMode(const stdAc::opmode_t mode) { + switch (mode) { + case stdAc::opmode_t::kFan: return kCoronaAcModeFan; + case stdAc::opmode_t::kDry: return kCoronaAcModeDry; + case stdAc::opmode_t::kHeat: return kCoronaAcModeHeat; + default: return kCoronaAcModeCool; + } +} + +/// Convert a native mode to it's common stdAc::opmode_t equivalent. +/// @param[in] mode A native operation mode to be converted. +/// @return The corresponding common stdAc::opmode_t mode. +stdAc::opmode_t IRCoronaAc::toCommonMode(const uint8_t mode) { + switch (mode) { + case kCoronaAcModeFan: return stdAc::opmode_t::kFan; + case kCoronaAcModeDry: return stdAc::opmode_t::kDry; + case kCoronaAcModeHeat: return stdAc::opmode_t::kHeat; + default: return stdAc::opmode_t::kCool; + } +} + +/// Get the operating speed of the A/C Fan +/// @return The current operating fan speed setting +uint8_t IRCoronaAc::getFan(void) { + return GETBITS8(remote_state[kCoronaAcSectionData0Pos], + kCoronaAcFanOffset, kCoronaAcFanSize); +} + +/// Set the operating speed of the A/C Fan +/// @param[in] speed The desired fan speed +void IRCoronaAc::setFan(const uint8_t speed) { + if (speed > kCoronaAcFanHigh) + setFan(kCoronaAcFanAuto); + else + setBits(&remote_state[kCoronaAcSectionData0Pos], + kCoronaAcFanOffset, kCoronaAcFanSize, speed); +} + +/// Change the powersave setting. +/// @param[in] on true, the setting is on. false, the setting is off. +void IRCoronaAc::setEcono(const bool on) { + setBit(&remote_state[kCoronaAcSectionData0Pos], kCoronaAcPowerSaveOffset, on); +} + +/// Get the value of the current powersave setting. +/// @return true, the setting is on. false, the setting is off. +bool IRCoronaAc::getEcono(void) { + return GETBIT8(remote_state[kCoronaAcSectionData0Pos], + kCoronaAcPowerSaveOffset); +} + +/// Convert a standard A/C Fan speed into its native fan speed. +/// @param[in] speed The desired stdAc::fanspeed_t fan speed +/// @return The given fan speed in native format +uint8_t IRCoronaAc::convertFan(const stdAc::fanspeed_t speed) { + switch (speed) { + case stdAc::fanspeed_t::kMin: + case stdAc::fanspeed_t::kLow: return kCoronaAcFanLow; + case stdAc::fanspeed_t::kMedium: return kCoronaAcFanMedium; + case stdAc::fanspeed_t::kHigh: + case stdAc::fanspeed_t::kMax: return kCoronaAcFanHigh; + default: return kCoronaAcFanAuto; + } +} + +/// Convert a native fan speed to it's common equivalent. +/// @param[in] speed The desired native fan speed +/// @return The given fan speed in stdAc::fanspeed_t format +stdAc::fanspeed_t IRCoronaAc::toCommonFanSpeed(const uint8_t speed) { + switch (speed) { + case kCoronaAcFanHigh: return stdAc::fanspeed_t::kHigh; + case kCoronaAcFanMedium: return stdAc::fanspeed_t::kMedium; + case kCoronaAcFanLow: return stdAc::fanspeed_t::kLow; + default: return stdAc::fanspeed_t::kAuto; + } +} + +/// Set the Vertical Swing toggle setting +/// @param[in] on true, the setting is on. false, the setting is off. +/// @note This is a button press, and not a state +/// after sending it once you should turn it off +void IRCoronaAc::setSwingVToggle(const bool on) { + setBit(&remote_state[kCoronaAcSectionData0Pos], + kCoronaAcSwingVToggleOffset, on); +} + +/// Get the Vertical Swing toggle setting +/// @return true, the setting is on. false, the setting is off. +bool IRCoronaAc::getSwingVToggle(void) { + return GETBIT64(remote_state[kCoronaAcSectionData0Pos], + kCoronaAcSwingVToggleOffset); +} + +/// Set the Timer time +/// @param[in] section index of section, used for offset. +/// @param[in] nr_of_mins Number of minutes to set the timer to. +/// (non in range value is disable). +/// Valid is from 1 minute to 12 hours +void IRCoronaAc::_setTimer(const uint8_t section, const uint16_t nr_of_mins) { + // default to off + uint16_t hsecs = kCoronaAcTimerOff; + if (1 <= nr_of_mins && nr_of_mins <= kCoronaAcTimerMax) + hsecs = nr_of_mins * kCoronaAcTimerUnitsPerMin; + + uint8_t pos = section * kCoronaAcSectionBytes; + // convert 16 bit value to separate 8 bit parts + remote_state[pos + kCoronaAcSectionData1Pos] = hsecs >> 8; + remote_state[pos + kCoronaAcSectionData0Pos] = hsecs; + + // if any timer is enabled, then (remote) ac must be on (Standby) + if (hsecs != kCoronaAcTimerOff) { + _setPower(true); + setPowerButton(false); + } +} + +/// Get the current Timer time +/// @return The number of minutes it is set for. 0 means it's off. +/// @note The A/C protocol supports 2 second increments +uint16_t IRCoronaAc::_getTimer(const uint8_t section) { + uint8_t pos = section * kCoronaAcSectionBytes; + // combine separate 8 bit parts to 16 bit value + uint16_t hsecs = remote_state[pos + kCoronaAcSectionData1Pos] << 8 | + remote_state[pos + kCoronaAcSectionData0Pos]; + + if (hsecs == kCoronaAcTimerOff) + return 0; + + return hsecs / kCoronaAcTimerUnitsPerMin; +} + +/// Get the current On Timer time +/// @return The number of minutes it is set for. 0 means it's off. +uint16_t IRCoronaAc::getOnTimer(void) { + return _getTimer(kCoronaAcOnTimerSection); +} + +/// Set the On Timer time +/// @param[in] nr_of_mins Number of minutes to set the timer to. +/// (0 or kCoronaAcTimerOff is disable). +void IRCoronaAc::setOnTimer(const uint16_t nr_of_mins) { + _setTimer(kCoronaAcOnTimerSection, nr_of_mins); + // if we set a timer value, clear the other timer + if (getOnTimer()) + setOffTimer(kCoronaAcTimerOff); +} + +/// Get the current Off Timer time +/// @return The number of minutes it is set for. 0 means it's off. +uint16_t IRCoronaAc::getOffTimer(void) { + return _getTimer(kCoronaAcOffTimerSection); +} + +/// Set the Off Timer time +/// @param[in] nr_of_mins Number of minutes to set the timer to. +/// (0 or kCoronaAcTimerOff is disable). +void IRCoronaAc::setOffTimer(const uint16_t nr_of_mins) { + _setTimer(kCoronaAcOffTimerSection, nr_of_mins); + // if we set a timer value, clear the other timer + if (getOffTimer()) + setOnTimer(kCoronaAcTimerOff); +} + +/// Convert the internal state into a human readable string. +/// @return The current internal state expressed as a human readable String. +String IRCoronaAc::toString(void) { + String result = ""; + result.reserve(140); // Reserve some heap for the string to reduce fragging. + result += addBoolToString(getPower(), kPowerStr, false); + result += addBoolToString(getPowerButton(), kPowerButtonStr); + result += addModeToString(getMode(), 0xFF, kCoronaAcModeCool, + kCoronaAcModeHeat, kCoronaAcModeDry, + kCoronaAcModeFan); + result += addTempToString(getTemp()); + result += addFanToString(getFan(), kCoronaAcFanHigh, kCoronaAcFanLow, + kCoronaAcFanAuto, kCoronaAcFanAuto, + kCoronaAcFanMedium); + result += addBoolToString(getSwingVToggle(), kSwingVToggleStr); + result += addBoolToString(getEcono(), kEconoStr); + result += addLabeledString(getOnTimer() + ? minsToString(getOnTimer()) : kOffStr, + kOnTimerStr); + result += addLabeledString(getOffTimer() + ? minsToString(getOffTimer()) : kOffStr, + kOffTimerStr); + return result; +} + +/// Convert the A/C state to it's common stdAc::state_t equivalent. +/// @return A stdAc::state_t state. +stdAc::state_t IRCoronaAc::toCommon() { + stdAc::state_t result; + result.protocol = decode_type_t::CORONA_AC; + result.model = -1; // No models used. + result.power = getPower(); + result.mode = toCommonMode(getMode()); + result.celsius = true; + result.degrees = getTemp(); + result.fanspeed = toCommonFanSpeed(getFan()); + result.swingv = getSwingVToggle() ? + stdAc::swingv_t::kAuto : stdAc::swingv_t::kOff; + result.econo = getEcono(); + // Not supported. + result.sleep = -1; + result.swingh = stdAc::swingh_t::kOff; + result.turbo = false; + result.quiet = false; + result.clean = false; + result.filter = false; + result.beep = false; + result.light = false; + result.clock = -1; + return result; +} diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Corona.h b/lib/IRremoteESP8266-2.7.8/src/ir_Corona.h new file mode 100644 index 000000000..871fc4c87 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Corona.h @@ -0,0 +1,155 @@ +// Corona A/C +// +// Copyright 2020 Christian Nilsson + +// Supports: +// Brand: Corona, Model: CSH-N2211 A/C +// Brand: Corona, Model: CSH-N2511 A/C +// Brand: Corona, Model: CSH-N2811 A/C +// Brand: Corona, Model: CSH-N4011 A/C +// Brand: Corona, Model: AR-01 remote +// +// Ref: https://docs.google.com/spreadsheets/d/1zzDEUQ52y7MZ7_xCU3pdjdqbRXOwZLsbTGvKWcicqCI/ +// Ref: https://www.corona.co.jp/box/download.php?id=145060636229 + +#ifndef IR_CORONA_H_ +#define IR_CORONA_H_ + +#define __STDC_LIMIT_MACROS +#include +#ifndef UNIT_TEST +#include +#endif +#include "IRremoteESP8266.h" +#include "IRsend.h" +#ifdef UNIT_TEST +#include "IRsend_test.h" +#endif + +// Constants + +// CORONA_AC +const uint8_t kCoronaAcSectionBytes = 7; // kCoronaAcStateLengthShort +const uint8_t kCoronaAcSections = 3; +const uint8_t kCoronaAcSectionHeader0Pos = 0; +const uint8_t kCoronaAcSectionHeader0 = 0x28; +const uint8_t kCoronaAcSectionHeader1Pos = 1; +const uint8_t kCoronaAcSectionHeader1 = 0x61; +const uint8_t kCoronaAcSectionLabelPos = 2; +const uint8_t kCoronaAcSectionLabelBase = 0x0D; // 0b1101 +const uint8_t kCoronaAcSectionData0Pos = 3; +const uint8_t kCoronaAcSectionData0InvPos = 4; +const uint8_t kCoronaAcSectionData1Pos = 5; +const uint8_t kCoronaAcSectionData1InvPos = 6; +const uint8_t kCoronaAcSectionData0Base = 0x10; // D0 Pos 4 always on + +const uint8_t kCoronaAcSettingsSection = 0; +// D0 +const uint8_t kCoronaAcFanOffset = 0; // D0 LSB Pos 0-1 +const uint8_t kCoronaAcFanSize = 2; +const uint8_t kCoronaAcFanAuto = 0b00; // 0 +const uint8_t kCoronaAcFanLow = 0b01; // 1 +const uint8_t kCoronaAcFanMedium = 0b10; // 2 +const uint8_t kCoronaAcFanHigh = 0b11; // 3 + +// One bit unknown // D0 Pos 2 +const uint8_t kCoronaAcPowerSaveOffset = 3; // D0 Pos 3 +// One bit unknown always on // D0 Pos 4 +// One bit unknown // D0 Pos 5 +const uint8_t kCoronaAcSwingVToggleOffset = 6; // D0 Pos 6 +// One bit unknown // D0 MSB Pos 7 + +// D1 +/* full auto mode not supported by this code yet +const uint8_t kCoronaAcAutoD0 = 0b00010100; // only combined with power save +const uint8_t kCoronaAcAutoD1 = 0b10000011; // only combined with power +*/ +const uint8_t kCoronaAcTempOffset = 0; // D1 LSB Pos 0 +const uint8_t kCoronaAcTempSize = 4; +const uint8_t kCoronaAcMinTemp = 17; // Celsius = 0b0001 +const uint8_t kCoronaAcMaxTemp = 30; // Celsius = 0b1110 +const uint8_t kCoronaAcPowerOffset = + kCoronaAcTempOffset + kCoronaAcTempSize; // D1 Pos 4 +const uint8_t kCoronaAcPowerButtonOffset = + kCoronaAcPowerOffset + 1; // D1 Pos 5 +const uint8_t kCoronaAcModeOffset = + kCoronaAcPowerButtonOffset + 1; // D1 MSB Pos 6-7 +const uint8_t kCoronaAcModeSize = 2; +const uint8_t kCoronaAcModeHeat = 0b00; // 0 +const uint8_t kCoronaAcModeDry = 0b01; // 1 +const uint8_t kCoronaAcModeCool = 0b10; // 2 +const uint8_t kCoronaAcModeFan = 0b11; // 3 + +const uint8_t kCoronaAcOnTimerSection = 1; +const uint8_t kCoronaAcOffTimerSection = 2; +const uint16_t kCoronaAcTimerMax = 12 * 60; // 12H in Minutes +// Min value on remote is 1 hour, actual sent value can be 2 secs +const uint16_t kCoronaAcTimerOff = 0xffff; +const uint16_t kCoronaAcTimerUnitsPerMin = 30; // 30 units = 1 minute + +// Classes + +/// Class for handling detailed Corona A/C messages. +class IRCoronaAc { + public: + explicit IRCoronaAc(const uint16_t pin, const bool inverted = false, + const bool use_modulation = true); + + void stateReset(); +#if SEND_CORONA_AC + 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_CORONA_AC + void begin(); + static bool validSection(const uint8_t state[], const uint16_t pos, + const uint8_t section); + void setPower(const bool on); + bool getPower(); + bool getPowerButton(); + void on(); + void off(); + void setTemp(const uint8_t temp); + uint8_t getTemp(); + void setSwingVToggle(const bool on); + bool getSwingVToggle(void); + void setFan(const uint8_t speed); + uint8_t getFan(); + void setMode(const uint8_t mode); + uint8_t getMode(); + void setEcono(const bool on); + bool getEcono(void); + void setOnTimer(const uint16_t nr_of_mins); + uint16_t getOnTimer(void); + void setOffTimer(const uint16_t nr_of_mins); + uint16_t getOffTimer(void); + uint8_t* getRaw(); + void setRaw(const uint8_t new_code[], + const uint16_t length = kCoronaAcStateLength); + uint8_t convertMode(const stdAc::opmode_t mode); + uint8_t convertFan(const stdAc::fanspeed_t speed); + static stdAc::opmode_t toCommonMode(const uint8_t mode); + static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed); + stdAc::state_t toCommon(); + String toString(); +#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 + uint8_t remote_state[kCoronaAcStateLength]; ///< The state of the IR remote. + static uint8_t getSectionByte(const uint8_t section); + static void checksum(uint8_t* data); + void setPowerButton(const bool on); + void _setPower(const bool on); + void _setTimer(const uint8_t section, const uint16_t nr_of_mins); + uint16_t _getTimer(const uint8_t section); +}; +#endif // IR_CORONA_H_ diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Daikin.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Daikin.cpp similarity index 70% rename from lib/IRremoteESP8266-2.7.5/src/ir_Daikin.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Daikin.cpp index c18e77569..8aa6a73a2 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Daikin.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Daikin.cpp @@ -1,13 +1,25 @@ -/* -An Arduino sketch to emulate IR Daikin ARC433** & ARC477A1 remote control unit -Read more at: -http://harizanov.com/2012/02/control-daikin-air-conditioner-over-the-internet/ +// Copyright 2016 sillyfrog +// Copyright 2017 sillyfrog, crankyoldgit +// Copyright 2018-2020 crankyoldgit +// Copyright 2019 pasna (IRDaikin160 class / Daikin176 class) -Copyright 2016 sillyfrog -Copyright 2017 sillyfrog, crankyoldgit -Copyright 2018-2019 crankyoldgit -Copyright 2019 pasna (IRDaikin160 class / Daikin176 class) -*/ +/// @file +/// @brief Support for Daikin A/C protocols. +/// @see Daikin http://harizanov.com/2012/02/control-daikin-air-conditioner-over-the-internet/ +/// @see Daikin https://github.com/mharizanov/Daikin-AC-remote-control-over-the-Internet/tree/master/IRremote +/// @see Daikin http://rdlab.cdmt.vn/project-2013/daikin-ir-protocol +/// @see Daikin https://github.com/blafois/Daikin-IR-Reverse +/// @see Daikin128 https://github.com/crankyoldgit/IRremoteESP8266/issues/827 +/// @see Daikin152 https://github.com/crankyoldgit/IRremoteESP8266/issues/873 +/// @see Daikin152 https://github.com/ToniA/arduino-heatpumpir/blob/master/DaikinHeatpumpARC480A14IR.cpp +/// @see Daikin152 https://github.com/ToniA/arduino-heatpumpir/blob/master/DaikinHeatpumpARC480A14IR.h +/// @see Daikin160 https://github.com/crankyoldgit/IRremoteESP8266/issues/731 +/// @see Daikin2 https://docs.google.com/spreadsheets/d/1f8EGfIbBUo2B-CzUFdrgKQprWakoYNKM80IKZN4KXQE/edit#gid=236366525&range=B25:D32 +/// @see Daikin2 https://github.com/crankyoldgit/IRremoteESP8266/issues/582 +/// @see Daikin2 https://www.daikin.co.nz/sites/default/files/daikin-split-system-US7-FTXZ25-50NV1B.pdf +/// @see Daikin216 https://github.com/crankyoldgit/IRremoteESP8266/issues/689 +/// @see Daikin216 https://github.com/danny-source/Arduino_DY_IRDaikin +/// @see Daikin64 https://github.com/crankyoldgit/IRremoteESP8266/issues/1064 #include "ir_Daikin.h" #include @@ -24,12 +36,6 @@ Copyright 2019 pasna (IRDaikin160 class / Daikin176 class) #include "IRtext.h" #include "IRutils.h" -// Constants -// Ref: -// https://github.com/mharizanov/Daikin-AC-remote-control-over-the-Internet/tree/master/IRremote -// http://rdlab.cdmt.vn/project-2013/daikin-ir-protocol -// https://github.com/crankyoldgit/IRremoteESP8266/issues/582 - using irutils::addBoolToString; using irutils::addDayToString; using irutils::addIntToString; @@ -44,19 +50,14 @@ using irutils::setBits; using irutils::sumNibbles; using irutils::uint8ToBcd; - #if SEND_DAIKIN -// Send a Daikin A/C message. -// -// Args: -// data: An array of kDaikinStateLength bytes containing the IR command. -// -// Status: STABLE -// -// Ref: -// IRDaikinESP.cpp -// https://github.com/mharizanov/Daikin-AC-remote-control-over-the-Internet/tree/master/IRremote -// https://github.com/blafois/Daikin-IR-Reverse +/// Send a Daikin 280-bit A/C formatted message. +/// Status: STABLE +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @see https://github.com/mharizanov/Daikin-AC-remote-control-over-the-Internet/tree/master/IRremote +/// @see https://github.com/blafois/Daikin-IR-Reverse void IRsend::sendDaikin(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { if (nbytes < kDaikinStateLengthShort) @@ -98,24 +99,29 @@ void IRsend::sendDaikin(const unsigned char data[], const uint16_t nbytes, } #endif // SEND_DAIKIN +/// 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? IRDaikinESP::IRDaikinESP(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { stateReset(); } +/// Set up hardware to be able to send a message. void IRDaikinESP::begin(void) { _irsend.begin(); } #if SEND_DAIKIN +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRDaikinESP::send(const uint16_t repeat) { _irsend.sendDaikin(getRaw(), kDaikinStateLength, repeat); } #endif // SEND_DAIKIN -// Verify the checksums are valid for a given state. -// Args: -// state: The array to verify the checksums of. -// length: The size of the state. -// Returns: -// A boolean. +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length of the state array. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRDaikinESP::validChecksum(uint8_t state[], const uint16_t length) { // Data #1 if (length < kDaikinSection1Length || @@ -136,7 +142,7 @@ bool IRDaikinESP::validChecksum(uint8_t state[], const uint16_t length) { return true; } -// Calculate and set the checksum values for the internal state. +/// Calculate and set the checksum values for the internal state. void IRDaikinESP::checksum(void) { remote[kDaikinByteChecksum1] = sumBytes(remote, kDaikinSection1Length - 1); remote[kDaikinByteChecksum2] = sumBytes(remote + kDaikinSection1Length, @@ -146,6 +152,7 @@ void IRDaikinESP::checksum(void) { kDaikinSection3Length - 1); } +/// Reset the internal state to a fixed known good state. void IRDaikinESP::stateReset(void) { for (uint8_t i = 0; i < kDaikinStateLength; i++) remote[i] = 0x0; @@ -173,11 +180,16 @@ void IRDaikinESP::stateReset(void) { this->checksum(); } +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t *IRDaikinESP::getRaw(void) { this->checksum(); // Ensure correct settings before sending. return remote; } +/// 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 IRDaikinESP::setRaw(const uint8_t new_code[], const uint16_t length) { uint8_t offset = 0; if (length == kDaikinStateLengthShort) { // Handle the "short" length case. @@ -188,28 +200,39 @@ void IRDaikinESP::setRaw(const uint8_t new_code[], const uint16_t length) { remote[i + offset] = new_code[i]; } +/// Change the power setting to On. void IRDaikinESP::on(void) { setPower(true); } +/// Change the power setting to Off. void IRDaikinESP::off(void) { setPower(false); } +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikinESP::setPower(const bool on) { setBit(&remote[kDaikinBytePower], kDaikinBitPowerOffset, on); } +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRDaikinESP::getPower(void) { return GETBIT8(remote[kDaikinBytePower], kDaikinBitPowerOffset); } -// Set the temp in deg C +/// Set the temperature. +/// @param[in] temp The temperature in degrees celsius. void IRDaikinESP::setTemp(const uint8_t temp) { uint8_t degrees = std::max(temp, kDaikinMinTemp); degrees = std::min(degrees, kDaikinMaxTemp); remote[kDaikinByteTemp] = degrees << 1; } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRDaikinESP::getTemp(void) { return remote[kDaikinByteTemp] >> 1; } -// Set the speed of the fan, 1-5 or kDaikinFanAuto or kDaikinFanQuiet +/// Set the speed of the fan. +/// @param[in] fan The desired setting. +/// @note 1-5 or kDaikinFanAuto or kDaikinFanQuiet void IRDaikinESP::setFan(const uint8_t fan) { // Set the fan speed bits, leave low 4 bits alone uint8_t fanset; @@ -222,6 +245,8 @@ void IRDaikinESP::setFan(const uint8_t fan) { setBits(&remote[kDaikinByteFan], kDaikinFanOffset, kDaikinFanSize, fanset); } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRDaikinESP::getFan(void) { uint8_t fan = GETBITS8(remote[kDaikinByteFan], kDaikinFanOffset, kDaikinFanSize); @@ -229,10 +254,14 @@ uint8_t IRDaikinESP::getFan(void) { return fan; } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRDaikinESP::getMode(void) { return GETBITS8(remote[kDaikinBytePower], kDaikinModeOffset, kDaikinModeSize); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRDaikinESP::setMode(const uint8_t mode) { switch (mode) { case kDaikinAuto: @@ -248,35 +277,49 @@ void IRDaikinESP::setMode(const uint8_t mode) { } } +/// Set the Vertical Swing mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikinESP::setSwingVertical(const bool on) { setBits(&remote[kDaikinByteFan], kDaikinSwingOffset, kDaikinSwingSize, on ? kDaikinSwingOn : kDaikinSwingOff); } +/// Get the Vertical Swing mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikinESP::getSwingVertical(void) { return GETBITS8(remote[kDaikinByteFan], kDaikinSwingOffset, kDaikinSwingSize); } +/// Set the Horizontal Swing mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikinESP::setSwingHorizontal(const bool on) { setBits(&remote[kDaikinByteSwingH], kDaikinSwingOffset, kDaikinSwingSize, on ? kDaikinSwingOn : kDaikinSwingOff); } +/// Get the Horizontal Swing mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikinESP::getSwingHorizontal(void) { return GETBITS8(remote[kDaikinByteSwingH], kDaikinSwingOffset, kDaikinSwingSize); } +/// Set the Quiet mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikinESP::setQuiet(const bool on) { setBit(&remote[kDaikinByteSilent], kDaikinBitSilentOffset, on); // Powerful & Quiet mode being on are mutually exclusive. if (on) this->setPowerful(false); } +/// Get the Quiet mode status of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikinESP::getQuiet(void) { return GETBIT8(remote[kDaikinByteSilent], kDaikinBitSilentOffset); } +/// Set the Powerful (Turbo) mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikinESP::setPowerful(const bool on) { setBit(&remote[kDaikinBytePowerful], kDaikinBitPowerfulOffset, on); if (on) { @@ -286,45 +329,64 @@ void IRDaikinESP::setPowerful(const bool on) { } } +/// Get the Powerful (Turbo) mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikinESP::getPowerful(void) { return GETBIT8(remote[kDaikinBytePowerful], kDaikinBitPowerfulOffset); } +/// Set the Sensor mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikinESP::setSensor(const bool on) { setBit(&remote[kDaikinByteSensor], kDaikinBitSensorOffset, on); } +/// Get the Sensor mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikinESP::getSensor(void) { return GETBIT8(remote[kDaikinByteSensor], kDaikinBitSensorOffset); } +/// Set the Economy mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikinESP::setEcono(const bool on) { setBit(&remote[kDaikinByteEcono], kDaikinBitEconoOffset, on); // Powerful & Econo mode being on are mutually exclusive. if (on) this->setPowerful(false); } +/// Get the Economical mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikinESP::getEcono(void) { return GETBIT8(remote[kDaikinByteEcono], kDaikinBitEconoOffset); } +/// Set the Mould mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikinESP::setMold(const bool on) { setBit(&remote[kDaikinByteMold], kDaikinBitMoldOffset, on); } +/// Get the Mould mode status of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikinESP::getMold(void) { return GETBIT8(remote[kDaikinByteMold], kDaikinBitMoldOffset); } +/// Set the Comfort mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikinESP::setComfort(const bool on) { setBit(&remote[kDaikinByteComfort], kDaikinBitComfortOffset, on); } +/// Get the Comfort mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikinESP::getComfort(void) { return GETBIT8(remote[kDaikinByteComfort], kDaikinBitComfortOffset); } -// starttime: Number of minutes after midnight. +/// Set the enable status & time of the On Timer. +/// @param[in] starttime The number of minutes past midnight. void IRDaikinESP::enableOnTimer(const uint16_t starttime) { setBit(&remote[kDaikinByteOnTimer], kDaikinBitOnTimerOffset); remote[kDaikinByteOnTimerMinsLow] = starttime; @@ -333,11 +395,14 @@ void IRDaikinESP::enableOnTimer(const uint16_t starttime) { kDaikinOnTimerMinsHighSize, starttime >> 8); } +/// Clear and disable the On timer. void IRDaikinESP::disableOnTimer(void) { this->enableOnTimer(kDaikinUnusedTime); setBit(&remote[kDaikinByteOnTimer], kDaikinBitOnTimerOffset, false); } +/// Get the On Timer time to be sent to the A/C unit. +/// @return The number of minutes past midnight. uint16_t IRDaikinESP::getOnTime(void) { return (GETBITS8(remote[kDaikinByteOnTimerMinsHigh], kDaikinOnTimerMinsHighOffset, @@ -345,11 +410,14 @@ uint16_t IRDaikinESP::getOnTime(void) { remote[kDaikinByteOnTimerMinsLow]; } +/// Get the enable status of the On Timer. +/// @return true, the setting is on. false, the setting is off. bool IRDaikinESP::getOnTimerEnabled(void) { return GETBIT8(remote[kDaikinByteOnTimer], kDaikinBitOnTimerOffset); } -// endtime: Number of minutes after midnight. +/// Set the enable status & time of the Off Timer. +/// @param[in] endtime The number of minutes past midnight. void IRDaikinESP::enableOffTimer(const uint16_t endtime) { setBit(&remote[kDaikinByteOffTimer], kDaikinBitOffTimerOffset); remote[kDaikinByteOffTimerMinsHigh] = endtime >> kNibbleSize; @@ -357,20 +425,27 @@ void IRDaikinESP::enableOffTimer(const uint16_t endtime) { endtime); } +/// Clear and disable the Off timer. void IRDaikinESP::disableOffTimer(void) { this->enableOffTimer(kDaikinUnusedTime); setBit(&remote[kDaikinByteOffTimer], kDaikinBitOffTimerOffset, false); } +/// Get the Off Timer time to be sent to the A/C unit. +/// @return The number of minutes past midnight. uint16_t IRDaikinESP::getOffTime(void) { return (remote[kDaikinByteOffTimerMinsHigh] << kNibbleSize) + GETBITS8(remote[kDaikinByteOffTimerMinsLow], kHighNibble, kNibbleSize); } +/// Get the enable status of the Off Timer. +/// @return true, the setting is on. false, the setting is off. bool IRDaikinESP::getOffTimerEnabled(void) { return GETBIT8(remote[kDaikinByteOffTimer], kDaikinBitOffTimerOffset); } +/// Set the clock on the A/C unit. +/// @param[in] mins_since_midnight Nr. of minutes past midnight. void IRDaikinESP::setCurrentTime(const uint16_t mins_since_midnight) { uint16_t mins = mins_since_midnight; if (mins > 24 * 60) mins = 0; // If > 23:59, set to 00:00 @@ -380,33 +455,46 @@ void IRDaikinESP::setCurrentTime(const uint16_t mins_since_midnight) { kDaikinClockMinsHighSize, mins >> 8); } +/// Get the clock time to be sent to the A/C unit. +/// @return The number of minutes past midnight. uint16_t IRDaikinESP::getCurrentTime(void) { return (GETBITS8(remote[kDaikinByteClockMinsHigh], kDaikinClockMinsHighOffset, kDaikinClockMinsHighSize) << 8) + remote[kDaikinByteClockMinsLow]; } +/// Set the current day of the week to be sent to the A/C unit. +/// @param[in] day_of_week The numerical representation of the day of the week. +/// @note 1 is SUN, 2 is MON, ..., 7 is SAT void IRDaikinESP::setCurrentDay(const uint8_t day_of_week) { - // 1 is SUN, 2 is MON, ..., 7 is SAT setBits(&remote[kDaikinByteClockMinsHigh], kDaikinDoWOffset, kDaikinDoWSize, day_of_week); } +/// Get the current day of the week to be sent to the A/C unit. +/// @return The numerical representation of the day of the week. +/// @note 1 is SUN, 2 is MON, ..., 7 is SAT uint8_t IRDaikinESP::getCurrentDay(void) { return GETBITS8(remote[kDaikinByteClockMinsHigh], kDaikinDoWOffset, kDaikinDoWSize); } +/// Set the enable status of the Weekly Timer. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikinESP::setWeeklyTimerEnable(const bool on) { // Bit is cleared for `on`. setBit(&remote[kDaikinByteWeeklyTimer], kDaikinBitWeeklyTimerOffset, !on); } +/// Get the enable status of the Weekly Timer. +/// @return true, the setting is on. false, the setting is off. bool IRDaikinESP::getWeeklyTimerEnable(void) { return !GETBIT8(remote[kDaikinByteWeeklyTimer], kDaikinBitWeeklyTimerOffset); } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRDaikinESP::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kDaikinCool; @@ -417,7 +505,9 @@ uint8_t IRDaikinESP::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRDaikinESP::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: return kDaikinFanQuiet; @@ -429,7 +519,9 @@ uint8_t IRDaikinESP::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRDaikinESP::toCommonMode(const uint8_t mode) { switch (mode) { case kDaikinCool: return stdAc::opmode_t::kCool; @@ -440,7 +532,9 @@ stdAc::opmode_t IRDaikinESP::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRDaikinESP::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kDaikinFanMax: return stdAc::fanspeed_t::kMax; @@ -453,7 +547,8 @@ stdAc::fanspeed_t IRDaikinESP::toCommonFanSpeed(const uint8_t speed) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRDaikinESP::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::DAIKIN; @@ -480,7 +575,8 @@ stdAc::state_t IRDaikinESP::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRDaikinESP::toString(void) { String result = ""; result.reserve(230); // Reserve some heap for the string to reduce fragging. @@ -510,20 +606,16 @@ String IRDaikinESP::toString(void) { } #if DECODE_DAIKIN -// Decode the supplied Daikin A/C message. -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits to expect in the data portion. (kDaikinBits) -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Reported as working. -// -// Ref: -// https://github.com/mharizanov/Daikin-AC-remote-control-over-the-Internet/tree/master/IRremote +/// Decode the supplied Daikin 280-bit message. (DAIKIN) +/// Status: STABLE / Reported as 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. +/// @see https://github.com/mharizanov/Daikin-AC-remote-control-over-the-Internet/tree/master/IRremote bool IRrecv::decodeDaikin(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { // Is there enough data to match successfully? @@ -588,15 +680,12 @@ bool IRrecv::decodeDaikin(decode_results *results, uint16_t offset, #endif // DECODE_DAIKIN #if SEND_DAIKIN2 -// Send a Daikin2 A/C message. -// -// Args: -// data: An array of kDaikin2StateLength bytes containing the IR command. -// -// Status: STABLE / Expected to work. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/582 +/// Send a Daikin2 (312-bit) A/C formatted message. +/// Status: STABLE / Expected to work. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/582 void IRsend::sendDaikin2(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { if (nbytes < kDaikin2Section1Length) @@ -622,34 +711,29 @@ void IRsend::sendDaikin2(const unsigned char data[], const uint16_t nbytes, } #endif // SEND_DAIKIN2 -// Class for handling Daikin2 A/C messages. -// -// Code by crankyoldgit, Reverse engineering analysis by sheppy99 -// -// Supported Remotes: Daikin ARC477A1 remote -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/582 -// https://docs.google.com/spreadsheets/d/1f8EGfIbBUo2B-CzUFdrgKQprWakoYNKM80IKZN4KXQE/edit?usp=sharing -// https://www.daikin.co.nz/sites/default/files/daikin-split-system-US7-FTXZ25-50NV1B.pdf +/// 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? IRDaikin2::IRDaikin2(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { stateReset(); } +/// Set up hardware to be able to send a message. void IRDaikin2::begin(void) { _irsend.begin(); } #if SEND_DAIKIN2 +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRDaikin2::send(const uint16_t repeat) { _irsend.sendDaikin2(getRaw(), kDaikin2StateLength, repeat); } #endif // SEND_DAIKIN2 -// Verify the checksum is valid for a given state. -// Args: -// state: The array to verify the checksum of. -// length: The size of the state. -// Returns: -// A boolean. +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length of the state array. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRDaikin2::validChecksum(uint8_t state[], const uint16_t length) { // Validate the checksum of section #1. if (length <= kDaikin2Section1Length - 1 || @@ -664,7 +748,7 @@ bool IRDaikin2::validChecksum(uint8_t state[], const uint16_t length) { return true; } -// Calculate and set the checksum values for the internal state. +/// Calculate and set the checksum values for the internal state. void IRDaikin2::checksum(void) { remote_state[kDaikin2Section1Length - 1] = sumBytes( remote_state, kDaikin2Section1Length - 1); @@ -672,6 +756,7 @@ void IRDaikin2::checksum(void) { remote_state + kDaikin2Section1Length, kDaikin2Section2Length - 1); } +/// Reset the internal state to a fixed known good state. void IRDaikin2::stateReset(void) { for (uint8_t i = 0; i < kDaikin2StateLength; i++) remote_state[i] = 0x0; @@ -706,33 +791,47 @@ void IRDaikin2::stateReset(void) { checksum(); } +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t *IRDaikin2::getRaw(void) { checksum(); // Ensure correct settings before sending. return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. void IRDaikin2::setRaw(const uint8_t new_code[]) { memcpy(remote_state, new_code, kDaikin2StateLength); } +/// Change the power setting to On. void IRDaikin2::on(void) { setPower(true); } +/// Change the power setting to Off. void IRDaikin2::off(void) { setPower(false); } +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin2::setPower(const bool on) { setBit(&remote_state[25], kDaikinBitPowerOffset, on); setBit(&remote_state[6], kDaikin2BitPowerOffset, !on); } +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin2::getPower(void) { return GETBIT8(remote_state[25], kDaikinBitPowerOffset) && !GETBIT8(remote_state[6], kDaikin2BitPowerOffset); } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRDaikin2::getMode(void) { return GETBITS8(remote_state[25], kHighNibble, kModeBitsSize); } +/// Set the operating mode of the A/C. +/// @param[in] desired_mode The desired operating mode. void IRDaikin2::setMode(const uint8_t desired_mode) { uint8_t mode = desired_mode; switch (mode) { @@ -747,7 +846,8 @@ void IRDaikin2::setMode(const uint8_t desired_mode) { if (mode == kDaikinCool) this->setTemp(this->getTemp()); } -// Set the temp in deg C +/// Set the temperature. +/// @param[in] desired The temperature in degrees celsius. void IRDaikin2::setTemp(const uint8_t desired) { // The A/C has a different min temp if in cool mode. uint8_t temp = std::max( @@ -756,7 +856,9 @@ void IRDaikin2::setTemp(const uint8_t desired) { remote_state[26] = std::min(kDaikinMaxTemp, temp) << 1; } -// Set the speed of the fan, 1-5 or kDaikinFanAuto or kDaikinFanQuiet +/// Set the speed of the fan. +/// @param[in] fan The desired setting. +/// @note 1-5 or kDaikinFanAuto or kDaikinFanQuiet void IRDaikin2::setFan(const uint8_t fan) { // Set the fan speed bits, leave low 4 bits alone uint8_t fanset; @@ -769,6 +871,8 @@ void IRDaikin2::setFan(const uint8_t fan) { setBits(&remote_state[kDaikin2FanByte], kHighNibble, kNibbleSize, fanset); } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRDaikin2::getFan(void) { const uint8_t fan = GETBITS8(remote_state[kDaikin2FanByte], kHighNibble, kNibbleSize); @@ -779,8 +883,12 @@ uint8_t IRDaikin2::getFan(void) { } } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRDaikin2::getTemp(void) { return remote_state[26] >> 1; } +/// Set the Vertical Swing mode of the A/C. +/// @param[in] position The position/mode to set the swing to. void IRDaikin2::setSwingVertical(const uint8_t position) { switch (position) { case kDaikin2SwingVHigh: @@ -797,11 +905,15 @@ void IRDaikin2::setSwingVertical(const uint8_t position) { } } +/// Get the Vertical Swing mode of the A/C. +/// @return The native position/mode setting. uint8_t IRDaikin2::getSwingVertical(void) { return GETBITS8(remote_state[18], kLowNibble, kNibbleSize); } -// Convert a standard A/C vertical swing into its native version. +/// Convert a stdAc::swingv_t enum into it's native setting. +/// @param[in] position The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRDaikin2::convertSwingV(const stdAc::swingv_t position) { switch (position) { case stdAc::swingv_t::kHighest: @@ -815,7 +927,9 @@ uint8_t IRDaikin2::convertSwingV(const stdAc::swingv_t position) { } } -// Convert a native vertical swing to it's common equivalent. +/// Convert a native vertical swing postion to it's common equivalent. +/// @param[in] setting A native position to convert. +/// @return The common vertical swing position. stdAc::swingv_t IRDaikin2::toCommonSwingV(const uint8_t setting) { switch (setting) { case kDaikin2SwingVHigh: return stdAc::swingv_t::kHighest; @@ -829,12 +943,18 @@ stdAc::swingv_t IRDaikin2::toCommonSwingV(const uint8_t setting) { } } +/// Set the Horizontal Swing mode of the A/C. +/// @param[in] position The position/mode to set the swing to. void IRDaikin2::setSwingHorizontal(const uint8_t position) { remote_state[17] = position; } +/// Get the Horizontal Swing mode of the A/C. +/// @return The native position/mode setting. uint8_t IRDaikin2::getSwingHorizontal(void) { return remote_state[17]; } +/// Set the clock on the A/C unit. +/// @param[in] numMins Nr. of minutes past midnight. void IRDaikin2::setCurrentTime(const uint16_t numMins) { uint16_t mins = numMins; if (numMins > 24 * 60) mins = 0; // If > 23:59, set to 00:00 @@ -842,13 +962,16 @@ void IRDaikin2::setCurrentTime(const uint16_t numMins) { setBits(&remote_state[6], kLowNibble, kNibbleSize, mins >> 8); } +/// Get the clock time to be sent to the A/C unit. +/// @return The number of minutes past midnight. uint16_t IRDaikin2::getCurrentTime(void) { return (GETBITS8(remote_state[6], kLowNibble, kNibbleSize) << 8) | remote_state[5]; } -// starttime: Number of minutes after midnight. -// Note: Timer location is shared with sleep timer. +/// Set the enable status & time of the On Timer. +/// @param[in] starttime The number of minutes past midnight. +/// @note Timer location is shared with sleep timer. void IRDaikin2::enableOnTimer(const uint16_t starttime) { clearSleepTimerFlag(); setBit(&remote_state[25], kDaikinBitOnTimerOffset); // Set the On Timer flag. @@ -856,26 +979,33 @@ void IRDaikin2::enableOnTimer(const uint16_t starttime) { setBits(&remote_state[31], kLowNibble, kNibbleSize, starttime >> 8); } +/// Clear the On Timer flag. void IRDaikin2::clearOnTimerFlag(void) { setBit(&remote_state[25], kDaikinBitOnTimerOffset, false); } +/// Disable the On timer. void IRDaikin2::disableOnTimer(void) { enableOnTimer(kDaikinUnusedTime); clearOnTimerFlag(); clearSleepTimerFlag(); } +/// Get the On Timer time to be sent to the A/C unit. +/// @return The number of minutes past midnight. uint16_t IRDaikin2::getOnTime(void) { return (GETBITS8(remote_state[31], kLowNibble, kNibbleSize) << 8) + remote_state[30]; } +/// Get the enable status of the On Timer. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin2::getOnTimerEnabled(void) { return GETBIT8(remote_state[25], kDaikinBitOnTimerOffset); } -// endtime: Number of minutes after midnight. +/// Set the enable status & time of the Off Timer. +/// @param[in] endtime The number of minutes past midnight. void IRDaikin2::enableOffTimer(const uint16_t endtime) { // Set the Off Timer flag. setBit(&remote_state[25], kDaikinBitOffTimerOffset); @@ -883,97 +1013,137 @@ void IRDaikin2::enableOffTimer(const uint16_t endtime) { setBits(&remote_state[31], kHighNibble, kNibbleSize, endtime); } +/// Disable the Off timer. void IRDaikin2::disableOffTimer(void) { enableOffTimer(kDaikinUnusedTime); // Clear the Off Timer flag. setBit(&remote_state[25], kDaikinBitOffTimerOffset, false); } +/// Get the Off Timer time to be sent to the A/C unit. +/// @return The number of minutes past midnight. uint16_t IRDaikin2::getOffTime(void) { return (remote_state[32] << 4) + GETBITS8(remote_state[31], kHighNibble, kNibbleSize); } +/// Get the enable status of the Off Timer. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin2::getOffTimerEnabled(void) { return GETBIT8(remote_state[25], kDaikinBitOffTimerOffset); } +/// Get the Beep status of the A/C. +/// @return true, the setting is on. false, the setting is off. uint8_t IRDaikin2::getBeep(void) { return GETBITS8(remote_state[7], kDaikin2BeepOffset, kDaikin2BeepSize); } +/// Set the Beep mode of the A/C. +/// @param[in] beep true, the setting is on. false, the setting is off. void IRDaikin2::setBeep(const uint8_t beep) { setBits(&remote_state[7], kDaikin2BeepOffset, kDaikin2BeepSize, beep); } +/// Get the Light status of the A/C. +/// @return true, the setting is on. false, the setting is off. uint8_t IRDaikin2::getLight(void) { return GETBITS8(remote_state[7], kDaikin2LightOffset, kDaikin2LightSize); } +/// Set the Light (LED) mode of the A/C. +/// @param[in] light true, the setting is on. false, the setting is off. void IRDaikin2::setLight(const uint8_t light) { setBits(&remote_state[7], kDaikin2LightOffset, kDaikin2LightSize, light); } +/// Set the Mould (filter) mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin2::setMold(const bool on) { setBit(&remote_state[8], kDaikin2BitMoldOffset, on); } +/// Get the Mould (filter) mode status of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin2::getMold(void) { return GETBIT8(remote_state[8], kDaikin2BitMoldOffset); } -// Auto clean setting. +/// Set the Auto clean mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin2::setClean(const bool on) { setBit(&remote_state[8], kDaikin2BitCleanOffset, on); } +/// Get the Auto Clean mode status of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin2::getClean(void) { return GETBIT8(remote_state[8], kDaikin2BitCleanOffset); } -// Fresh Air settings. +/// Set the Fresh Air mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin2::setFreshAir(const bool on) { setBit(&remote_state[8], kDaikin2BitFreshAirOffset, on); } +/// Get the Fresh Air mode status of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin2::getFreshAir(void) { return GETBIT8(remote_state[8], kDaikin2BitFreshAirOffset); } +/// Set the (High) Fresh Air mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin2::setFreshAirHigh(const bool on) { setBit(&remote_state[8], kDaikin2BitFreshAirHighOffset, on); } +/// Get the (High) Fresh Air mode status of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin2::getFreshAirHigh(void) { return GETBIT8(remote_state[8], kDaikin2BitFreshAirHighOffset); } +/// Set the Automatic Eye (Sensor) mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin2::setEyeAuto(bool on) { setBit(&remote_state[13], kDaikin2BitEyeAutoOffset, on); } +/// Get the Automaitc Eye (Sensor) mode status of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin2::getEyeAuto(void) { return GETBIT8(remote_state[13], kDaikin2BitEyeAutoOffset); } +/// Set the Eye (Sensor) mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin2::setEye(bool on) { setBit(&remote_state[36], kDaikin2BitEyeOffset, on); } +/// Get the Eye (Sensor) mode status of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin2::getEye(void) { return GETBIT8(remote_state[36], kDaikin2BitEyeOffset); } +/// Set the Economy mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin2::setEcono(bool on) { setBit(&remote_state[36], kDaikinBitEconoOffset, on); } +/// Get the Economical mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin2::getEcono(void) { return GETBIT8(remote_state[36], kDaikinBitEconoOffset); } -// sleeptime: Number of minutes. -// Note: Timer location is shared with On Timer. +/// Set the enable status & time of the Sleep Timer. +/// @param[in] sleeptime The number of minutes past midnight. +/// @note The Timer location is shared with On Timer. void IRDaikin2::enableSleepTimer(const uint16_t sleeptime) { enableOnTimer(sleeptime); clearOnTimerFlag(); @@ -981,61 +1151,85 @@ void IRDaikin2::enableSleepTimer(const uint16_t sleeptime) { setBit(&remote_state[36], kDaikin2BitSleepTimerOffset); } +/// Clear the sleep timer flag. void IRDaikin2::clearSleepTimerFlag(void) { setBit(&remote_state[36], kDaikin2BitSleepTimerOffset, false); } +/// Disable the sleep timer. void IRDaikin2::disableSleepTimer(void) { disableOnTimer(); } +/// Get the Sleep Timer time to be sent to the A/C unit. +/// @return The number of minutes past midnight. uint16_t IRDaikin2::getSleepTime(void) { return getOnTime(); } +/// Get the Sleep timer enabled status of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin2::getSleepTimerEnabled(void) { return GETBIT8(remote_state[36], kDaikin2BitSleepTimerOffset); } +/// Set the Quiet mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin2::setQuiet(const bool on) { setBit(&remote_state[33], kDaikinBitSilentOffset, on); // Powerful & Quiet mode being on are mutually exclusive. if (on) setPowerful(false); } +/// Get the Quiet mode status of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin2::getQuiet(void) { return GETBIT8(remote_state[33], kDaikinBitSilentOffset); } +/// Set the Powerful (Turbo) mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin2::setPowerful(const bool on) { setBit(&remote_state[33], kDaikinBitPowerfulOffset, on); // Powerful & Quiet mode being on are mutually exclusive. if (on) setQuiet(false); } +/// Get the Powerful (Turbo) mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin2::getPowerful(void) { return GETBIT8(remote_state[33], kDaikinBitPowerfulOffset); } +/// Set the Purify (Filter) mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin2::setPurify(const bool on) { setBit(&remote_state[36], kDaikin2BitPurifyOffset, on); } +/// Get the Purify (Filter) mode status of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin2::getPurify(void) { return GETBIT8(remote_state[36], kDaikin2BitPurifyOffset); } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRDaikin2::convertMode(const stdAc::opmode_t mode) { return IRDaikinESP::convertMode(mode); } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRDaikin2::convertFan(const stdAc::fanspeed_t speed) { return IRDaikinESP::convertFan(speed); } -// Convert a standard A/C horizontal swing into its native version. +/// Convert a stdAc::swingh_t enum into it's native setting. +/// @param[in] position The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRDaikin2::convertSwingH(const stdAc::swingh_t position) { switch (position) { case stdAc::swingh_t::kAuto: return kDaikin2SwingHSwing; @@ -1049,7 +1243,9 @@ uint8_t IRDaikin2::convertSwingH(const stdAc::swingh_t position) { } } -// Convert a native horizontal swing to it's common equivalent. +/// Convert a native horizontal swing postion to it's common equivalent. +/// @param[in] setting A native position to convert. +/// @return The common horizontal swing position. stdAc::swingh_t IRDaikin2::toCommonSwingH(const uint8_t setting) { switch (setting) { case kDaikin2SwingHSwing: return stdAc::swingh_t::kAuto; @@ -1063,7 +1259,8 @@ stdAc::swingh_t IRDaikin2::toCommonSwingH(const uint8_t setting) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRDaikin2::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::DAIKIN2; @@ -1088,7 +1285,8 @@ stdAc::state_t IRDaikin2::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRDaikin2::toString(void) { String result = ""; result.reserve(310); // Reserve some heap for the string to reduce fragging. @@ -1205,24 +1403,15 @@ String IRDaikin2::toString(void) { } #if DECODE_DAIKIN2 -// Decode the supplied Daikin2 A/C message. -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits to expect in the data portion. (kDaikin2Bits) -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Supported devices: -// - Daikin FTXZ25NV1B, FTXZ35NV1B, FTXZ50NV1B Aircon -// - Daikin ARC477A1 remote -// -// Status: STABLE / Works as expected. -// -// Ref: -// https://github.com/mharizanov/Daikin-AC-remote-control-over-the-Internet/tree/master/IRremote +/// Decode the supplied Daikin 312-bit message. (DAIKIN2) +/// Status: STABLE / Works as expected. +/// @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::decodeDaikin2(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen < 2 * (nbits + kHeader + kFooter) + kHeader - 1 + offset) @@ -1277,19 +1466,13 @@ bool IRrecv::decodeDaikin2(decode_results *results, uint16_t offset, #endif // DECODE_DAIKIN2 #if SEND_DAIKIN216 -// Send a Daikin 216 bit A/C message. -// -// Args: -// data: An array of kDaikin216StateLength bytes containing the IR command. -// -// Status: Alpha/Untested on a real device. -// -// Supported devices: -// - Daikin ARC433B69 remote. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/689 -// https://github.com/danny-source/Arduino_DY_IRDaikin +/// Send a Daikin216 (216-bit) A/C formatted message. +/// Status: Alpha / Untested on a real device. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/689 +/// @see https://github.com/danny-source/Arduino_DY_IRDaikin void IRsend::sendDaikin216(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { if (nbytes < kDaikin216Section1Length) @@ -1313,33 +1496,29 @@ void IRsend::sendDaikin216(const unsigned char data[], const uint16_t nbytes, } #endif // SEND_DAIKIN216 -// Class for handling Daikin 216 bit / 27 byte A/C messages. -// -// Code by crankyoldgit. -// -// Supported Remotes: Daikin ARC433B69 remote -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/689 -// https://github.com/danny-source/Arduino_DY_IRDaikin +/// 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? IRDaikin216::IRDaikin216(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { stateReset(); } +/// Set up hardware to be able to send a message. void IRDaikin216::begin(void) { _irsend.begin(); } #if SEND_DAIKIN216 +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRDaikin216::send(const uint16_t repeat) { _irsend.sendDaikin216(getRaw(), kDaikin216StateLength, repeat); } #endif // SEND_DAIKIN216 -// Verify the checksum is valid for a given state. -// Args: -// state: The array to verify the checksum of. -// length: The size of the state. -// Returns: -// A boolean. +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length of the state array. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRDaikin216::validChecksum(uint8_t state[], const uint16_t length) { // Validate the checksum of section #1. if (length <= kDaikin216Section1Length - 1 || @@ -1354,7 +1533,7 @@ bool IRDaikin216::validChecksum(uint8_t state[], const uint16_t length) { return true; } -// Calculate and set the checksum values for the internal state. +/// Calculate and set the checksum values for the internal state. void IRDaikin216::checksum(void) { remote_state[kDaikin216Section1Length - 1] = sumBytes( remote_state, kDaikin216Section1Length - 1); @@ -1362,6 +1541,7 @@ void IRDaikin216::checksum(void) { remote_state + kDaikin216Section1Length, kDaikin216Section2Length - 1); } +/// Reset the internal state to a fixed known good state. void IRDaikin216::stateReset(void) { for (uint8_t i = 0; i < kDaikin216StateLength; i++) remote_state[i] = 0x00; remote_state[0] = 0x11; @@ -1376,31 +1556,45 @@ void IRDaikin216::stateReset(void) { // remote_state[26] is a checksum byte, it will be set by checksum(). } +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t *IRDaikin216::getRaw(void) { checksum(); // Ensure correct settings before sending. return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. void IRDaikin216::setRaw(const uint8_t new_code[]) { memcpy(remote_state, new_code, kDaikin216StateLength); } +/// Change the power setting to On. void IRDaikin216::on(void) { setPower(true); } +/// Change the power setting to Off. void IRDaikin216::off(void) { setPower(false); } +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin216::setPower(const bool on) { setBit(&remote_state[kDaikin216BytePower], kDaikinBitPowerOffset, on); } +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin216::getPower(void) { return GETBIT8(remote_state[kDaikin216BytePower], kDaikinBitPowerOffset); } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRDaikin216::getMode(void) { return GETBITS8(remote_state[kDaikin216ByteMode], kHighNibble, kModeBitsSize); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRDaikin216::setMode(const uint8_t mode) { switch (mode) { case kDaikinAuto: @@ -1416,12 +1610,15 @@ void IRDaikin216::setMode(const uint8_t mode) { } } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRDaikin216::convertMode(const stdAc::opmode_t mode) { return IRDaikinESP::convertMode(mode); } -// Set the temp in deg C +/// Set the temperature. +/// @param[in] temp The temperature in degrees celsius. void IRDaikin216::setTemp(const uint8_t temp) { uint8_t degrees = std::max(temp, kDaikinMinTemp); degrees = std::min(degrees, kDaikinMaxTemp); @@ -1429,12 +1626,16 @@ void IRDaikin216::setTemp(const uint8_t temp) { kDaikin216TempSize, degrees); } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRDaikin216::getTemp(void) { return GETBITS8(remote_state[kDaikin216ByteTemp], kDaikin216TempOffset, kDaikin216TempSize); } -// Set the speed of the fan, 1-5 or kDaikinFanAuto or kDaikinFanQuiet +/// Set the speed of the fan. +/// @param[in] fan The desired setting. +/// @note 1-5 or kDaikinFanAuto or kDaikinFanQuiet void IRDaikin216::setFan(const uint8_t fan) { // Set the fan speed bits, leave low 4 bits alone uint8_t fanset; @@ -1448,6 +1649,8 @@ void IRDaikin216::setFan(const uint8_t fan) { fanset); } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRDaikin216::getFan(void) { uint8_t fan = GETBITS8(remote_state[kDaikin216ByteFan], kHighNibble, kDaikinFanSize); @@ -1455,32 +1658,44 @@ uint8_t IRDaikin216::getFan(void) { return fan; } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRDaikin216::convertFan(const stdAc::fanspeed_t speed) { return IRDaikinESP::convertFan(speed); } +/// Set the Vertical Swing mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin216::setSwingVertical(const bool on) { setBits(&remote_state[kDaikin216ByteSwingV], kLowNibble, kDaikin216SwingSize, on ? kDaikin216SwingOn : kDaikin216SwingOff); } +/// Get the Vertical Swing mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin216::getSwingVertical(void) { return GETBITS8(remote_state[kDaikin216ByteSwingV], kLowNibble, kDaikin216SwingSize); } +/// Set the Horizontal Swing mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin216::setSwingHorizontal(const bool on) { setBits(&remote_state[kDaikin216ByteSwingH], kLowNibble, kDaikin216SwingSize, on ? kDaikin216SwingOn : kDaikin216SwingOff); } +/// Get the Horizontal Swing mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin216::getSwingHorizontal(void) { return GETBITS8(remote_state[kDaikin216ByteSwingH], kLowNibble, kDaikin216SwingSize); } -// This is a horrible hack till someone works out the quiet mode bit. +/// Set the Quiet mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. +/// @note This is a horrible hack till someone works out the quiet mode bit. void IRDaikin216::setQuiet(const bool on) { if (on) { this->setFan(kDaikinFanQuiet); @@ -1491,23 +1706,30 @@ void IRDaikin216::setQuiet(const bool on) { } } -// This is a horrible hack till someone works out the quiet mode bit. +/// Get the Quiet mode status of the A/C. +/// @return true, the setting is on. false, the setting is off. +/// @note This is a horrible hack till someone works out the quiet mode bit. bool IRDaikin216::getQuiet(void) { return this->getFan() == kDaikinFanQuiet; } +/// Set the Powerful (Turbo) mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin216::setPowerful(const bool on) { setBit(&remote_state[kDaikin216BytePowerful], kDaikinBitPowerfulOffset, on); // Powerful & Quiet mode being on are mutually exclusive. if (on) this->setQuiet(false); } +/// Get the Powerful (Turbo) mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin216::getPowerful(void) { return GETBIT8(remote_state[kDaikin216BytePowerful], kDaikinBitPowerfulOffset); } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRDaikin216::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::DAIKIN216; @@ -1534,7 +1756,8 @@ stdAc::state_t IRDaikin216::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRDaikin216::toString(void) { String result = ""; result.reserve(120); // Reserve some heap for the string to reduce fragging. @@ -1552,24 +1775,17 @@ String IRDaikin216::toString(void) { } #if DECODE_DAIKIN216 -// Decode the supplied Daikin 216 bit A/C message. -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits to expect in the data portion. (kDaikin216Bits) -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Supported devices: -// - Daikin ARC433B69 remote. -// -// Status: STABLE / Should be working. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/689 -// https://github.com/danny-source/Arduino_DY_IRDaikin +/// Decode the supplied Daikin 216-bit message. (DAIKIN216) +/// Status: STABLE / Should be 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. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/689 +/// @see https://github.com/danny-source/Arduino_DY_IRDaikin bool IRrecv::decodeDaikin216(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen < 2 * (nbits + kHeader + kFooter) - 1 + offset) @@ -1615,18 +1831,12 @@ bool IRrecv::decodeDaikin216(decode_results *results, uint16_t offset, #endif // DECODE_DAIKIN216 #if SEND_DAIKIN160 -// Send a Daikin 160 bit A/C message. -// -// Args: -// data: An array of kDaikin160StateLength bytes containing the IR command. -// -// Status: STABLE / Confirmed working. -// -// Supported devices: -// - Daikin ARC423A5 remote. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/731 +/// Send a Daikin160 (160-bit) A/C formatted message. +/// Status: STABLE / Confirmed working. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/731 void IRsend::sendDaikin160(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { if (nbytes < kDaikin160Section1Length) @@ -1650,26 +1860,21 @@ void IRsend::sendDaikin160(const unsigned char data[], const uint16_t nbytes, } #endif // SEND_DAIKIN160 -// Class for handling Daikin 160 bit / 20 byte A/C messages. -// -// Code by crankyoldgit. -// -// Supported Remotes: Daikin ARC423A5 remote -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/731 +/// 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? IRDaikin160::IRDaikin160(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { stateReset(); } +/// Set up hardware to be able to send a message. void IRDaikin160::begin(void) { _irsend.begin(); } -// Verify the checksum is valid for a given state. -// Args: -// state: The array to verify the checksum of. -// length: The size of the state. -// Returns: -// A boolean. +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length of the state array. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRDaikin160::validChecksum(uint8_t state[], const uint16_t length) { // Validate the checksum of section #1. if (length <= kDaikin160Section1Length - 1 || @@ -1684,7 +1889,7 @@ bool IRDaikin160::validChecksum(uint8_t state[], const uint16_t length) { return true; } -// Calculate and set the checksum values for the internal state. +/// Calculate and set the checksum values for the internal state. void IRDaikin160::checksum(void) { remote_state[kDaikin160Section1Length - 1] = sumBytes( remote_state, kDaikin160Section1Length - 1); @@ -1692,6 +1897,7 @@ void IRDaikin160::checksum(void) { remote_state + kDaikin160Section1Length, kDaikin160Section2Length - 1); } +/// Reset the internal state to a fixed known good state. void IRDaikin160::stateReset(void) { for (uint8_t i = 0; i < kDaikin160StateLength; i++) remote_state[i] = 0x00; remote_state[0] = 0x11; @@ -1712,37 +1918,53 @@ void IRDaikin160::stateReset(void) { // remote_state[19] is a checksum byte, it will be set by checksum(). } +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t *IRDaikin160::getRaw(void) { checksum(); // Ensure correct settings before sending. return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. void IRDaikin160::setRaw(const uint8_t new_code[]) { memcpy(remote_state, new_code, kDaikin160StateLength); } #if SEND_DAIKIN160 +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRDaikin160::send(const uint16_t repeat) { _irsend.sendDaikin160(getRaw(), kDaikin160StateLength, repeat); } #endif // SEND_DAIKIN160 +/// Change the power setting to On. void IRDaikin160::on(void) { setPower(true); } +/// Change the power setting to Off. void IRDaikin160::off(void) { setPower(false); } +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin160::setPower(const bool on) { setBit(&remote_state[kDaikin160BytePower], kDaikinBitPowerOffset, on); } +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin160::getPower(void) { return GETBIT8(remote_state[kDaikin160BytePower], kDaikinBitPowerOffset); } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRDaikin160::getMode(void) { return GETBITS8(remote_state[kDaikin160ByteMode], kHighNibble, kModeBitsSize); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRDaikin160::setMode(const uint8_t mode) { switch (mode) { case kDaikinAuto: @@ -1757,12 +1979,15 @@ void IRDaikin160::setMode(const uint8_t mode) { } } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRDaikin160::convertMode(const stdAc::opmode_t mode) { return IRDaikinESP::convertMode(mode); } -// Set the temp in deg C +/// Set the temperature. +/// @param[in] temp The temperature in degrees celsius. void IRDaikin160::setTemp(const uint8_t temp) { uint8_t degrees = std::max(temp, kDaikinMinTemp); degrees = std::min(degrees, kDaikinMaxTemp) - 10; @@ -1770,12 +1995,16 @@ void IRDaikin160::setTemp(const uint8_t temp) { kDaikin160TempSize, degrees); } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRDaikin160::getTemp(void) { return GETBITS8(remote_state[kDaikin160ByteTemp], kDaikin160TempOffset, kDaikin160TempSize) + 10; } -// Set the speed of the fan, 1-5 or kDaikinFanAuto or kDaikinFanQuiet +/// Set the speed of the fan. +/// @param[in] fan The desired setting. +/// @note 1-5 or kDaikinFanAuto or kDaikinFanQuiet void IRDaikin160::setFan(const uint8_t fan) { uint8_t fanset; if (fan == kDaikinFanQuiet || fan == kDaikinFanAuto) @@ -1788,6 +2017,8 @@ void IRDaikin160::setFan(const uint8_t fan) { setBits(&remote_state[kDaikin160ByteFan], kLowNibble, kDaikinFanSize, fanset); } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRDaikin160::getFan(void) { uint8_t fan = GETBITS8(remote_state[kDaikin160ByteFan], kLowNibble, kDaikinFanSize); @@ -1795,7 +2026,9 @@ uint8_t IRDaikin160::getFan(void) { return fan; } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRDaikin160::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: return kDaikinFanMin; @@ -1808,6 +2041,8 @@ uint8_t IRDaikin160::convertFan(const stdAc::fanspeed_t speed) { } } +/// Set the Vertical Swing mode of the A/C. +/// @param[in] position The position/mode to set the swing to. void IRDaikin160::setSwingVertical(const uint8_t position) { switch (position) { case kDaikin160SwingVLowest: @@ -1823,12 +2058,16 @@ void IRDaikin160::setSwingVertical(const uint8_t position) { } } +/// Get the Vertical Swing mode of the A/C. +/// @return The native position/mode setting. uint8_t IRDaikin160::getSwingVertical(void) { return GETBITS8(remote_state[kDaikin160ByteSwingV], kHighNibble, kDaikinSwingSize); } -// Convert a standard A/C vertical swing into its native version. +/// Convert a stdAc::swingv_t enum into it's native setting. +/// @param[in] position The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRDaikin160::convertSwingV(const stdAc::swingv_t position) { switch (position) { case stdAc::swingv_t::kHighest: @@ -1842,7 +2081,9 @@ uint8_t IRDaikin160::convertSwingV(const stdAc::swingv_t position) { } } -// Convert a native vertical swing to it's common equivalent. +/// Convert a native vertical swing postion to it's common equivalent. +/// @param[in] setting A native position to convert. +/// @return The common vertical swing position. stdAc::swingv_t IRDaikin160::toCommonSwingV(const uint8_t setting) { switch (setting) { case kDaikin160SwingVHighest: return stdAc::swingv_t::kHighest; @@ -1855,7 +2096,8 @@ stdAc::swingv_t IRDaikin160::toCommonSwingV(const uint8_t setting) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRDaikin160::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::DAIKIN160; @@ -1880,7 +2122,8 @@ stdAc::state_t IRDaikin160::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRDaikin160::toString(void) { String result = ""; result.reserve(150); // Reserve some heap for the string to reduce fragging. @@ -1906,23 +2149,16 @@ String IRDaikin160::toString(void) { } #if DECODE_DAIKIN160 -// Decode the supplied Daikin 160 bit A/C message. -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits to expect in the data portion. (kDaikin160Bits) -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Supported devices: -// - Daikin ARC423A5 remote. -// -// Status: STABLE / Confirmed working. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/731 +/// Decode the supplied Daikin 160-bit message. (DAIKIN160) +/// 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. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/731 bool IRrecv::decodeDaikin160(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen < 2 * (nbits + kHeader + kFooter) - 1 + offset) @@ -1968,16 +2204,11 @@ bool IRrecv::decodeDaikin160(decode_results *results, uint16_t offset, #endif // DECODE_DAIKIN160 #if SEND_DAIKIN176 -// Send a Daikin 176 bit A/C message. -// -// Args: -// data: An array of kDaikin176StateLength bytes containing the IR command. -// -// Status: Alpha/Untested on a real device. -// -// Supported devices: -// - Daikin BRC4C153 remote. -// +/// Send a Daikin176 (176-bit) A/C formatted message. +/// Status: Alpha / Untested on a real device. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendDaikin176(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { if (nbytes < kDaikin176Section1Length) @@ -2001,24 +2232,21 @@ void IRsend::sendDaikin176(const unsigned char data[], const uint16_t nbytes, } #endif // SEND_DAIKIN176 -// Class for handling Daikin 176 bit / 22 byte A/C messages. -// -// Code by crankyoldgit. -// -// Supported Remotes: Daikin BRC4C153 remote -// +/// 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? IRDaikin176::IRDaikin176(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { stateReset(); } +/// Set up hardware to be able to send a message. void IRDaikin176::begin(void) { _irsend.begin(); } -// Verify the checksum is valid for a given state. -// Args: -// state: The array to verify the checksum of. -// length: The size of the state. -// Returns: -// A boolean. +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length of the state array. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRDaikin176::validChecksum(uint8_t state[], const uint16_t length) { // Validate the checksum of section #1. if (length <= kDaikin176Section1Length - 1 || @@ -2033,7 +2261,7 @@ bool IRDaikin176::validChecksum(uint8_t state[], const uint16_t length) { return true; } -// Calculate and set the checksum values for the internal state. +/// Calculate and set the checksum values for the internal state. void IRDaikin176::checksum(void) { remote_state[kDaikin176Section1Length - 1] = sumBytes( remote_state, kDaikin176Section1Length - 1); @@ -2041,6 +2269,7 @@ void IRDaikin176::checksum(void) { remote_state + kDaikin176Section1Length, kDaikin176Section2Length - 1); } +/// Reset the internal state to a fixed known good state. void IRDaikin176::stateReset(void) { for (uint8_t i = 0; i < kDaikin176StateLength; i++) remote_state[i] = 0x00; remote_state[0] = 0x11; @@ -2061,39 +2290,55 @@ void IRDaikin176::stateReset(void) { _saved_temp = getTemp(); } +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t *IRDaikin176::getRaw(void) { checksum(); // Ensure correct settings before sending. return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. void IRDaikin176::setRaw(const uint8_t new_code[]) { memcpy(remote_state, new_code, kDaikin176StateLength); _saved_temp = getTemp(); } #if SEND_DAIKIN176 +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRDaikin176::send(const uint16_t repeat) { _irsend.sendDaikin176(getRaw(), kDaikin176StateLength, repeat); } #endif // SEND_DAIKIN176 +/// Change the power setting to On. void IRDaikin176::on(void) { setPower(true); } +/// Change the power setting to Off.. void IRDaikin176::off(void) { setPower(false); } +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin176::setPower(const bool on) { remote_state[kDaikin176ByteModeButton] = 0; setBit(&remote_state[kDaikin176BytePower], kDaikinBitPowerOffset, on); } +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin176::getPower(void) { return GETBIT8(remote_state[kDaikin176BytePower], kDaikinBitPowerOffset); } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRDaikin176::getMode(void) { return GETBITS8(remote_state[kDaikin176ByteMode], kHighNibble, kModeBitsSize); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRDaikin176::setMode(const uint8_t mode) { uint8_t altmode = 0; switch (mode) { @@ -2111,7 +2356,9 @@ void IRDaikin176::setMode(const uint8_t mode) { remote_state[kDaikin176ByteModeButton] = kDaikin176ModeButton; } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRDaikin176::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kDry: return kDaikinDry; @@ -2121,7 +2368,9 @@ uint8_t IRDaikin176::convertMode(const stdAc::opmode_t mode) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRDaikin176::toCommonMode(const uint8_t mode) { switch (mode) { case kDaikinDry: return stdAc::opmode_t::kDry; @@ -2131,7 +2380,8 @@ stdAc::opmode_t IRDaikin176::toCommonMode(const uint8_t mode) { } } -// Set the temp in deg C +/// Set the temperature. +/// @param[in] temp The temperature in degrees celsius. void IRDaikin176::setTemp(const uint8_t temp) { uint8_t degrees = std::min(kDaikinMaxTemp, std::max(temp, kDaikinMinTemp)); _saved_temp = degrees; @@ -2145,12 +2395,16 @@ void IRDaikin176::setTemp(const uint8_t temp) { remote_state[kDaikin176ByteModeButton] = 0; } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRDaikin176::getTemp(void) { return GETBITS8(remote_state[kDaikin176ByteTemp], kDaikin176TempOffset, kDaikin176TempSize) + 9; } -// Set the speed of the fan, 1 for Min or 3 for Max +/// Set the speed of the fan. +/// @param[in] fan The desired setting. +/// @note 1 for Min or 3 for Max void IRDaikin176::setFan(const uint8_t fan) { switch (fan) { case kDaikinFanMin: @@ -2164,11 +2418,15 @@ void IRDaikin176::setFan(const uint8_t fan) { } } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRDaikin176::getFan(void) { return GETBITS8(remote_state[kDaikin176ByteFan], kHighNibble, kDaikinFanSize); } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRDaikin176::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: @@ -2177,6 +2435,8 @@ uint8_t IRDaikin176::convertFan(const stdAc::fanspeed_t speed) { } } +/// Set the Horizontal Swing mode of the A/C. +/// @param[in] position The position/mode to set the swing to. void IRDaikin176::setSwingHorizontal(const uint8_t position) { switch (position) { case kDaikin176SwingHOff: @@ -2188,12 +2448,16 @@ void IRDaikin176::setSwingHorizontal(const uint8_t position) { } } +/// Get the Horizontal Swing mode of the A/C. +/// @return The native position/mode setting. uint8_t IRDaikin176::getSwingHorizontal(void) { return GETBITS8(remote_state[kDaikin176ByteSwingH], kLowNibble, kDaikinSwingSize); } -// Convert a standard A/C horizontal swing into its native version. +/// Convert a stdAc::swingh_t enum into it's native setting. +/// @param[in] position The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRDaikin176::convertSwingH(const stdAc::swingh_t position) { switch (position) { case stdAc::swingh_t::kOff: return kDaikin176SwingHOff; @@ -2201,7 +2465,10 @@ uint8_t IRDaikin176::convertSwingH(const stdAc::swingh_t position) { default: return kDaikin176SwingHAuto; } } -// Convert a native horizontal swing to it's common equivalent. + +/// Convert a native horizontal swing postion to it's common equivalent. +/// @param[in] setting A native position to convert. +/// @return The common horizontal swing position. stdAc::swingh_t IRDaikin176::toCommonSwingH(const uint8_t setting) { switch (setting) { case kDaikin176SwingHOff: return stdAc::swingh_t::kOff; @@ -2211,13 +2478,16 @@ stdAc::swingh_t IRDaikin176::toCommonSwingH(const uint8_t setting) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRDaikin176::toCommonFanSpeed(const uint8_t speed) { return (speed == kDaikinFanMin) ? stdAc::fanspeed_t::kMin : stdAc::fanspeed_t::kMax; } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRDaikin176::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::DAIKIN176; @@ -2243,7 +2513,8 @@ stdAc::state_t IRDaikin176::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRDaikin176::toString(void) { String result = ""; result.reserve(80); // Reserve some heap for the string to reduce fragging. @@ -2270,22 +2541,15 @@ String IRDaikin176::toString(void) { } #if DECODE_DAIKIN176 -// Decode the supplied Daikin 176 bit A/C message. -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits to expect in the data portion. (kDaikin176Bits) -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Supported devices: -// - Daikin BRC4C153 remote. -// -// Status: STABLE / Expected to work. -// - +/// Decode the supplied Daikin 176-bit message. (DAIKIN176) +/// Status: STABLE / Expected to work. +/// @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::decodeDaikin176(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { @@ -2332,17 +2596,12 @@ bool IRrecv::decodeDaikin176(decode_results *results, uint16_t offset, #endif // DECODE_DAIKIN176 #if SEND_DAIKIN128 -// Send a Daikin 128 bit A/C message. -// -// Args: -// data: An array of kDaikin128StateLength bytes containing the IR command. -// -// Status: STABLE / Known Working. -// -// Supported devices: -// - Daikin BRC52B63 remote. -// -// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/827 +/// Send a Daikin128 (128-bit) A/C formatted message. +/// Status: STABLE / Known Working. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/827 void IRsend::sendDaikin128(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { if (nbytes < kDaikin128SectionLength) @@ -2372,19 +2631,15 @@ void IRsend::sendDaikin128(const unsigned char data[], const uint16_t nbytes, } #endif // SEND_DAIKIN128 -// Class for handling Daikin 128 bit / 16 byte A/C messages. -// -// Code by crankyoldgit. -// Analysis by Daniel Vena -// -// Status: STABLE / Known Working. -// -// Supported Remotes: Daikin BRC52B63 remote -// +/// 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? IRDaikin128::IRDaikin128(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { stateReset(); } +/// Set up hardware to be able to send a message. void IRDaikin128::begin(void) { _irsend.begin(); } uint8_t IRDaikin128::calcFirstChecksum(const uint8_t state[]) { @@ -2397,11 +2652,9 @@ uint8_t IRDaikin128::calcSecondChecksum(const uint8_t state[]) { kDaikin128SectionLength - 1); } -// Verify the checksum is valid for a given state. -// Args: -// state: The array to verify the checksum of. -// Returns: -// A boolean. +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRDaikin128::validChecksum(uint8_t state[]) { // Validate the checksum of section #1. if (state[kDaikin128SectionLength - 1] >> 4 != calcFirstChecksum(state)) @@ -2412,7 +2665,7 @@ bool IRDaikin128::validChecksum(uint8_t state[]) { return true; } -// Calculate and set the checksum values for the internal state. +/// Calculate and set the checksum values for the internal state. void IRDaikin128::checksum(void) { remote_state[kDaikin128SectionLength - 1] &= 0x0F; // Clear upper half. remote_state[kDaikin128SectionLength - 1] |= @@ -2420,6 +2673,7 @@ void IRDaikin128::checksum(void) { remote_state[kDaikin128StateLength - 1] = calcSecondChecksum(remote_state); } +/// Reset the internal state to a fixed known good state. void IRDaikin128::stateReset(void) { for (uint8_t i = 0; i < kDaikin128StateLength; i++) remote_state[i] = 0x00; remote_state[0] = 0x16; @@ -2428,36 +2682,50 @@ void IRDaikin128::stateReset(void) { // remote_state[15] is a checksum byte, it will be set by checksum(). } +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t *IRDaikin128::getRaw(void) { checksum(); // Ensure correct settings before sending. return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. void IRDaikin128::setRaw(const uint8_t new_code[]) { memcpy(remote_state, new_code, kDaikin128StateLength); } #if SEND_DAIKIN128 +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRDaikin128::send(const uint16_t repeat) { _irsend.sendDaikin128(getRaw(), kDaikin128StateLength, repeat); } #endif // SEND_DAIKIN128 +/// Set the Power toggle setting of the A/C. +/// @param[in] toggle true, the setting is on. false, the setting is off. void IRDaikin128::setPowerToggle(const bool toggle) { setBit(&remote_state[kDaikin128BytePowerSwingSleep], kDaikin128BitPowerToggleOffset, toggle); } +/// Get the Power toggle setting of the A/C. +/// @return The current operating mode setting. bool IRDaikin128::getPowerToggle(void) { return GETBIT8(remote_state[kDaikin128BytePowerSwingSleep], kDaikin128BitPowerToggleOffset); } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRDaikin128::getMode(void) { return GETBITS8(remote_state[kDaikin128ByteModeFan], kLowNibble, kDaikin128ModeSize); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRDaikin128::setMode(const uint8_t mode) { switch (mode) { case kDaikin128Auto: @@ -2477,7 +2745,9 @@ void IRDaikin128::setMode(const uint8_t mode) { setEcono(getEcono()); } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRDaikin128::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kDaikin128Cool; @@ -2488,7 +2758,9 @@ uint8_t IRDaikin128::convertMode(const stdAc::opmode_t mode) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRDaikin128::toCommonMode(const uint8_t mode) { switch (mode) { case kDaikin128Cool: return stdAc::opmode_t::kCool; @@ -2499,21 +2771,28 @@ stdAc::opmode_t IRDaikin128::toCommonMode(const uint8_t mode) { } } -// Set the temp in deg C +/// Set the temperature. +/// @param[in] temp The temperature in degrees celsius. void IRDaikin128::setTemp(const uint8_t temp) { remote_state[kDaikin128ByteTemp] = uint8ToBcd( std::min(kDaikin128MaxTemp, std::max(temp, kDaikin128MinTemp))); } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRDaikin128::getTemp(void) { return bcdToUint8(remote_state[kDaikin128ByteTemp]); } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRDaikin128::getFan(void) { return GETBITS8(remote_state[kDaikin128ByteModeFan], kHighNibble, kDaikinFanSize); } +/// Set the speed of the fan. +/// @param[in] speed The desired setting. void IRDaikin128::setFan(const uint8_t speed) { uint8_t new_speed = speed; uint8_t mode = getMode(); @@ -2534,7 +2813,9 @@ void IRDaikin128::setFan(const uint8_t speed) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRDaikin128::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: return kDaikinFanQuiet; @@ -2546,7 +2827,9 @@ uint8_t IRDaikin128::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRDaikin128::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kDaikin128FanPowerful: return stdAc::fanspeed_t::kMax; @@ -2558,37 +2841,51 @@ stdAc::fanspeed_t IRDaikin128::toCommonFanSpeed(const uint8_t speed) { } } +/// Set the Vertical Swing mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin128::setSwingVertical(const bool on) { setBit(&remote_state[kDaikin128BytePowerSwingSleep], kDaikin128BitSwingOffset, on); } +/// Get the Vertical Swing mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin128::getSwingVertical(void) { return GETBIT8(remote_state[kDaikin128BytePowerSwingSleep], kDaikin128BitSwingOffset); } +/// Set the Sleep mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin128::setSleep(const bool on) { setBit(&remote_state[kDaikin128BytePowerSwingSleep], kDaikin128BitSleepOffset, on); } +/// Get the Sleep mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin128::getSleep(void) { return GETBIT8(remote_state[kDaikin128BytePowerSwingSleep], kDaikin128BitSleepOffset); } +/// Set the Economy mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin128::setEcono(const bool on) { uint8_t mode = getMode(); setBit(&remote_state[kDaikin128ByteEconoLight], kDaikin128BitEconoOffset, on && (mode == kDaikin128Cool || mode == kDaikin128Heat)); } +/// Get the Economical mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin128::getEcono(void) { return GETBIT8(remote_state[kDaikin128ByteEconoLight], kDaikin128BitEconoOffset); } +/// Set the Quiet mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin128::setQuiet(const bool on) { uint8_t mode = getMode(); if (on && (mode == kDaikin128Cool || mode == kDaikin128Heat)) @@ -2597,10 +2894,14 @@ void IRDaikin128::setQuiet(const bool on) { setFan(kDaikin128FanAuto); } +/// Get the Quiet mode status of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin128::getQuiet(void) { return getFan() == kDaikin128FanQuiet; } +/// Set the Powerful (Turbo) mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin128::setPowerful(const bool on) { uint8_t mode = getMode(); if (on && (mode == kDaikin128Cool || mode == kDaikin128Heat)) @@ -2609,11 +2910,14 @@ void IRDaikin128::setPowerful(const bool on) { setFan(kDaikin128FanAuto); } +/// Get the Powerful (Turbo) mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin128::getPowerful(void) { return getFan() == kDaikin128FanPowerful; } -// Set the clock in mins since midnight +/// Set the clock on the A/C unit. +/// @param[in] mins_since_midnight Nr. of minutes past midnight. void IRDaikin128::setClock(const uint16_t mins_since_midnight) { uint16_t mins = mins_since_midnight; if (mins_since_midnight >= 24 * 60) mins = 0; // Bounds check. @@ -2623,25 +2927,32 @@ void IRDaikin128::setClock(const uint16_t mins_since_midnight) { remote_state[kDaikin128ByteClockMins] = uint8ToBcd(mins % 60); } +/// Get the clock time to be sent to the A/C unit. +/// @return The number of minutes past midnight. uint16_t IRDaikin128::getClock(void) { return bcdToUint8(remote_state[kDaikin128ByteClockHours]) * 60 + bcdToUint8(remote_state[kDaikin128ByteClockMins]); } +/// Set the enable status of the On Timer. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin128::setOnTimerEnabled(const bool on) { setBit(&remote_state[kDaikin128ByteOnTimer], kDaikin128BitTimerEnabledOffset, on); } +/// Get the enable status of the On Timer. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin128::getOnTimerEnabled(void) { return GETBIT8(remote_state[kDaikin128ByteOnTimer], kDaikin128BitTimerEnabledOffset); } -// Timer is rounds down to the nearest half hour. -// Args: -// ptr: A PTR to the byte containing the Timer value to be updated. -// mins_since_midnight: The number of minutes the new timer should be set to. +/// Set the time for a timer at the given location. +/// @param[in,out] ptr Ptr to the byte containing the Timer value to be updated. +/// @param[in] mins_since_midnight The number of minutes the new timer should +/// be set to. +/// @note Timer is rounds down to the nearest half hour. void IRDaikin128::setTimer(uint8_t *ptr, const uint16_t mins_since_midnight) { uint16_t mins = mins_since_midnight; if (mins_since_midnight >= 24 * 60) mins = 0; // Bounds check. @@ -2652,43 +2963,57 @@ void IRDaikin128::setTimer(uint8_t *ptr, const uint16_t mins_since_midnight) { uint8ToBcd(mins / 60)); } -// Timer is stored in nr of half hours internally. -// Args: -// ptr: A PTR to the byte containing the Timer value. -// Returns: -// A uint16_t containing the number of minutes since midnight. +/// Get the time for a timer at the given location. +/// @param[in] ptr A Ptr to the byte containing the Timer value. +/// @return The number of minutes since midnight that the timer is set to. +/// @note Timer is stored in nr. of half hours internally. uint16_t IRDaikin128::getTimer(const uint8_t *ptr) { return bcdToUint8(GETBITS8(*ptr, kDaikin128HoursOffset, kDaikin128HoursSize)) * 60 + (GETBIT8(*ptr, kDaikin128HalfHourOffset) ? 30 : 0); } +/// Set the On Timer time for the A/C unit. +/// @param[in] mins_since_midnight Nr. of minutes past midnight. void IRDaikin128::setOnTimer(const uint16_t mins_since_midnight) { setTimer(remote_state + kDaikin128ByteOnTimer, mins_since_midnight); } +/// Get the On Timer time to be sent to the A/C unit. +/// @return The number of minutes past midnight. uint16_t IRDaikin128::getOnTimer(void) { return getTimer(remote_state + kDaikin128ByteOnTimer); } +/// Set the enable status of the Off Timer. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin128::setOffTimerEnabled(const bool on) { setBit(&remote_state[kDaikin128ByteOffTimer], kDaikin128BitTimerEnabledOffset, on); } +/// Get the enable status of the Off Timer. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin128::getOffTimerEnabled(void) { return GETBIT8(remote_state[kDaikin128ByteOffTimer], kDaikin128BitTimerEnabledOffset); } +/// Set the Off Timer time for the A/C unit. +/// @param[in] mins_since_midnight Nr. of minutes past midnight. void IRDaikin128::setOffTimer(const uint16_t mins_since_midnight) { setTimer(remote_state + kDaikin128ByteOffTimer, mins_since_midnight); } +/// Get the Off Timer time to be sent to the A/C unit. +/// @return The number of minutes past midnight. uint16_t IRDaikin128::getOffTimer(void) { return getTimer(remote_state + kDaikin128ByteOffTimer); } +/// Set the Light toggle setting of the A/C. +/// @param[in] unit Device to show the LED (Light) Display info about. +/// @note 0 is off. void IRDaikin128::setLightToggle(const uint8_t unit) { switch (unit) { case 0: @@ -2701,11 +3026,14 @@ void IRDaikin128::setLightToggle(const uint8_t unit) { } } +/// Get the Light toggle setting of the A/C. +/// @return The current operating mode setting. uint8_t IRDaikin128::getLightToggle(void) { return remote_state[kDaikin128ByteEconoLight] & kDaikin128MaskLight; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRDaikin128::toString(void) { String result = ""; result.reserve(240); // Reserve some heap for the string to reduce fragging. @@ -2738,7 +3066,9 @@ String IRDaikin128::toString(void) { return result; } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @param[in] prev Ptr to a previous state. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRDaikin128::toCommon(const stdAc::state_t *prev) { stdAc::state_t result; if (prev != NULL) result = *prev; @@ -2766,22 +3096,16 @@ stdAc::state_t IRDaikin128::toCommon(const stdAc::state_t *prev) { } #if DECODE_DAIKIN128 -// Decode the supplied Daikin 128 bit A/C message. -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits to expect in the data portion. (kDaikin128Bits) -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Supported devices: -// - Daikin BRC52B63 remote. -// -// Status: STABLE / Known Working. -// -// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/827 +/// Decode the supplied Daikin 128-bit message. (DAIKIN128) +/// Status: STABLE / Known 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. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/827 bool IRrecv::decodeDaikin128(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen < 2 * (nbits + kHeader) + kFooter - 1 + offset) @@ -2836,17 +3160,12 @@ bool IRrecv::decodeDaikin128(decode_results *results, uint16_t offset, #endif // DECODE_DAIKIN128 #if SEND_DAIKIN152 -// Send a Daikin 152 bit A/C message. -// -// Args: -// data: An array of kDaikin152StateLength bytes containing the IR command. -// -// Supported devices: -// - Daikin ARC480A5 remote. -// -// Status: STABLE / Known working. -// -// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/873 +/// Send a Daikin152 (152-bit) A/C formatted message. +/// Status: STABLE / Known Working. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/873 void IRsend::sendDaikin152(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { for (uint16_t r = 0; r <= repeat; r++) { @@ -2866,22 +3185,16 @@ void IRsend::sendDaikin152(const unsigned char data[], const uint16_t nbytes, #endif // SEND_DAIKIN152 #if DECODE_DAIKIN152 -// Decode the supplied Daikin 152 bit A/C message. -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits to expect in the data portion. (kDaikin152Bits) -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Supported devices: -// - Daikin ARC480A5 remote. -// -// Status: STABLE / Known working. -// -// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/873 +/// Decode the supplied Daikin 152-bit message. (DAIKIN152) +/// Status: STABLE / Known 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. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/873 bool IRrecv::decodeDaikin152(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen < 2 * (5 + nbits + kFooter) + kHeader - 1 + offset) @@ -2930,34 +3243,29 @@ bool IRrecv::decodeDaikin152(decode_results *results, uint16_t offset, } #endif // DECODE_DAIKIN152 -// Class for handling Daikin 152 bit / 19 byte A/C messages. -// -// Code by crankyoldgit. -// -// Supported Remotes: Daikin ARC480A5 remote -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/873 -// https://github.com/ToniA/arduino-heatpumpir/blob/master/DaikinHeatpumpARC480A14IR.cpp -// https://github.com/ToniA/arduino-heatpumpir/blob/master/DaikinHeatpumpARC480A14IR.h +/// 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? IRDaikin152::IRDaikin152(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { stateReset(); } +/// Set up hardware to be able to send a message. void IRDaikin152::begin(void) { _irsend.begin(); } #if SEND_DAIKIN152 +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRDaikin152::send(const uint16_t repeat) { _irsend.sendDaikin152(getRaw(), kDaikin152StateLength, repeat); } #endif // SEND_DAIKIN152 -// Verify the checksum is valid for a given state. -// Args: -// state: The array to verify the checksum of. -// length: The size of the state. -// Returns: -// A boolean. +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length of the state array. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRDaikin152::validChecksum(uint8_t state[], const uint16_t length) { // Validate the checksum of the given state. if (length <= 1 || state[length - 1] != sumBytes(state, length - 1)) @@ -2966,12 +3274,13 @@ bool IRDaikin152::validChecksum(uint8_t state[], const uint16_t length) { return true; } -// Calculate and set the checksum values for the internal state. +/// Calculate and set the checksum values for the internal state. void IRDaikin152::checksum(void) { remote_state[kDaikin152StateLength - 1] = sumBytes( remote_state, kDaikin152StateLength - 1); } +/// Reset the internal state to a fixed known good state. void IRDaikin152::stateReset(void) { for (uint8_t i = 3; i < kDaikin152StateLength; i++) remote_state[i] = 0x00; remote_state[0] = 0x11; @@ -2981,32 +3290,46 @@ void IRDaikin152::stateReset(void) { // remote_state[19] is a checksum byte, it will be set by checksum(). } +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t *IRDaikin152::getRaw(void) { checksum(); // Ensure correct settings before sending. return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. void IRDaikin152::setRaw(const uint8_t new_code[]) { memcpy(remote_state, new_code, kDaikin152StateLength); } +/// Change the power setting to On. void IRDaikin152::on(void) { setPower(true); } +/// Change the power setting to Off. void IRDaikin152::off(void) { setPower(false); } +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin152::setPower(const bool on) { setBit(&remote_state[kDaikin152PowerByte], kDaikinBitPowerOffset, on); } +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin152::getPower(void) { return GETBIT8(remote_state[kDaikin152PowerByte], kDaikinBitPowerOffset); } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRDaikin152::getMode(void) { return GETBITS8(remote_state[kDaikin152ModeByte], kDaikinModeOffset, kDaikinModeSize); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRDaikin152::setMode(const uint8_t mode) { switch (mode) { case kDaikinFan: @@ -3027,12 +3350,15 @@ void IRDaikin152::setMode(const uint8_t mode) { kDaikinModeSize, mode); } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRDaikin152::convertMode(const stdAc::opmode_t mode) { return IRDaikinESP::convertMode(mode); } -// Set the temp in deg C +/// Set the temperature. +/// @param[in] temp The temperature in degrees celsius. void IRDaikin152::setTemp(const uint8_t temp) { uint8_t degrees = std::max( temp, (getMode() == kDaikinHeat) ? kDaikinMinTemp : kDaikin2MinCoolTemp); @@ -3042,12 +3368,16 @@ void IRDaikin152::setTemp(const uint8_t temp) { kDaikin152TempSize, degrees); } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRDaikin152::getTemp(void) { return GETBITS8(remote_state[kDaikin152TempByte], kDaikinTempOffset, kDaikin152TempSize); } -// Set the speed of the fan, 1-5 or kDaikinFanAuto or kDaikinFanQuiet +/// Set the speed of the fan. +/// @param[in] fan The desired setting. +/// @note 1-5 or kDaikinFanAuto or kDaikinFanQuiet void IRDaikin152::setFan(const uint8_t fan) { // Set the fan speed bits, leave low 4 bits alone uint8_t fanset; @@ -3060,6 +3390,8 @@ void IRDaikin152::setFan(const uint8_t fan) { setBits(&remote_state[kDaikin152FanByte], kHighNibble, kNibbleSize, fanset); } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRDaikin152::getFan(void) { const uint8_t fan = GETBITS8(remote_state[kDaikin152FanByte], kHighNibble, kNibbleSize); @@ -3070,31 +3402,43 @@ uint8_t IRDaikin152::getFan(void) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRDaikin152::convertFan(const stdAc::fanspeed_t speed) { return IRDaikinESP::convertFan(speed); } +/// Set the Vertical Swing mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin152::setSwingV(const bool on) { setBits(&remote_state[kDaikin152SwingVByte], kDaikinSwingOffset, kDaikinSwingSize, on ? kDaikinSwingOn : kDaikinSwingOff); } +/// Get the Vertical Swing mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin152::getSwingV(void) { return GETBITS8(remote_state[kDaikin152SwingVByte], kDaikinSwingOffset, kDaikinSwingSize); } +/// Set the Quiet mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin152::setQuiet(const bool on) { setBit(&remote_state[kDaikin152QuietByte], kDaikinBitSilentOffset, on); // Powerful & Quiet mode being on are mutually exclusive. if (on) this->setPowerful(false); } +/// Get the Quiet mode status of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin152::getQuiet(void) { return GETBIT8(remote_state[kDaikin152QuietByte], kDaikinBitSilentOffset); } +/// Set the Powerful (Turbo) mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin152::setPowerful(const bool on) { setBit(&remote_state[kDaikin152PowerfulByte], kDaikinBitPowerfulOffset, on); if (on) { @@ -3105,29 +3449,41 @@ void IRDaikin152::setPowerful(const bool on) { } } +/// Get the Powerful (Turbo) mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin152::getPowerful(void) { return GETBIT8(remote_state[kDaikin152PowerfulByte], kDaikinBitPowerfulOffset); } +/// Set the Economy mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin152::setEcono(const bool on) { setBit(&remote_state[kDaikin152EconoByte], kDaikinBitEconoOffset, on); // Powerful & Econo mode being on are mutually exclusive. if (on) this->setPowerful(false); } +/// Get the Economical mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin152::getEcono(void) { return GETBIT8(remote_state[kDaikin152EconoByte], kDaikinBitEconoOffset); } +/// Set the Sensor mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin152::setSensor(const bool on) { setBit(&remote_state[kDaikin152SensorByte], kDaikin152SensorOffset, on); } +/// Get the Sensor mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin152::getSensor(void) { return GETBIT8(remote_state[kDaikin152SensorByte], kDaikin152SensorOffset); } +/// Set the Comfort mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin152::setComfort(const bool on) { setBit(&remote_state[kDaikin152ComfortByte], kDaikin152ComfortOffset, on); if (on) { @@ -3139,11 +3495,14 @@ void IRDaikin152::setComfort(const bool on) { } } +/// Get the Comfort mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin152::getComfort(void) { return GETBIT8(remote_state[kDaikin152ComfortByte], kDaikin152ComfortOffset); } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRDaikin152::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::DAIKIN152; @@ -3169,7 +3528,8 @@ stdAc::state_t IRDaikin152::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRDaikin152::toString(void) { String result = ""; result.reserve(180); // Reserve some heap for the string to reduce fragging. @@ -3189,17 +3549,12 @@ String IRDaikin152::toString(void) { } #if SEND_DAIKIN64 -// Send a Daikin 64 bit A/C message. -// -// Args: -// data: A uint64_t containing the IR command/code. -// -// Supported devices: -// - Daikin FFN-C. -// -// Status: Beta / Probably Working. -// -// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1064 +/// Send a Daikin64 (64-bit) A/C formatted message. +/// Status: Beta / Probably Working. +/// @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. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1064 void IRsend::sendDaikin64(const uint64_t data, const uint16_t nbits, const uint16_t repeat) { enableIROut(kDaikin64Freq); @@ -3223,22 +3578,16 @@ void IRsend::sendDaikin64(const uint64_t data, const uint16_t nbits, #endif // SEND_DAIKIN64 #if DECODE_DAIKIN64 -// Decode the supplied Daikin 64 bit A/C message. -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits to expect in the data portion. (kDaikin64Bits) -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Supported devices: -// - Daikin FFN-C. -// -// Status: Beta / Probably Working. -// -// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1064 +/// Decode the supplied Daikin 64-bit message. (DAIKIN64) +/// Status: Beta / Probably 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. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1064 bool IRrecv::decodeDaikin64(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen < 2 * nbits + kDaikin64Overhead - offset) @@ -3261,7 +3610,8 @@ bool IRrecv::decodeDaikin64(decode_results *results, uint16_t offset, kDaikin64BitMark, kDaikin64OneSpace, kDaikin64BitMark, kDaikin64ZeroSpace, kDaikin64BitMark, kDaikin64Gap, - false, _tolerance, kMarkExcess, false); + false, _tolerance + kDaikin64ToleranceDelta, + kMarkExcess, false); if (used == 0) return false; offset += used; // Footer #2 @@ -3279,33 +3629,28 @@ bool IRrecv::decodeDaikin64(decode_results *results, uint16_t offset, } #endif // DAIKIN64 -// Class for handling Daikin 64 bit / 19 byte A/C messages. -// -// Code by crankyoldgit. -// -// Supported Remotes: Daikin ARC480A5 remote -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/873 -// https://github.com/ToniA/arduino-heatpumpir/blob/master/DaikinHeatpumpARC480A14IR.cpp -// https://github.com/ToniA/arduino-heatpumpir/blob/master/DaikinHeatpumpARC480A14IR.h +/// 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? IRDaikin64::IRDaikin64(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { stateReset(); } +/// Set up hardware to be able to send a message. void IRDaikin64::begin(void) { _irsend.begin(); } #if SEND_DAIKIN64 +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRDaikin64::send(const uint16_t repeat) { _irsend.sendDaikin64(getRaw(), kDaikin64Bits, repeat); } #endif // SEND_DAIKIN64 -// Calc the checksum for a given state. -// Args: -// state: The value to calc the checksum of. -// Returns: -// A 4-bit checksum stored in a uint_8. +/// Calculate the checksum for a given state. +/// @param[in] state The value to calc the checksum of. +/// @return The 4-bit checksum stored in a uint_8. uint8_t IRDaikin64::calcChecksum(const uint64_t state) { uint64_t data = GETBITS64(state, 0, kDaikin64ChecksumOffset); uint8_t result = 0; @@ -3314,44 +3659,51 @@ uint8_t IRDaikin64::calcChecksum(const uint64_t state) { return result & 0xF; } -// Verify the checksum is valid for a given state. -// Args: -// state: The array to verify the checksum of. -// length: The size of the state. -// Returns: -// A boolean. +/// Verify the checksum is valid for a given state. +/// @param[in] state The state to verify the checksum of. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRDaikin64::validChecksum(const uint64_t state) { // Validate the checksum of the given state. return (GETBITS64(state, kDaikin64ChecksumOffset, kDaikin64ChecksumSize) == calcChecksum(state)); } -// Calculate and set the checksum values for the internal state. +/// Calculate and set the checksum values for the internal state. void IRDaikin64::checksum(void) { setBits(&remote_state, kDaikin64ChecksumOffset, kDaikin64ChecksumSize, calcChecksum(remote_state)); } +/// Reset the internal state to a fixed known good state. void IRDaikin64::stateReset(void) { remote_state = kDaikin64KnownGoodState; } +/// Get a copy of the internal state as a valid code for this protocol. +/// @return A valid code for this protocol based on the current internal state. uint64_t IRDaikin64::getRaw(void) { checksum(); // Ensure correct settings before sending. return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_state A valid code for this protocol. void IRDaikin64::setRaw(const uint64_t new_state) { remote_state = new_state; } +/// Set the Power toggle setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin64::setPowerToggle(const bool on) { setBit(&remote_state, kDaikin64PowerToggleBit, on); } +/// Get the Power toggle setting of the A/C. +/// @return The current operating mode setting. bool IRDaikin64::getPowerToggle(void) { return GETBIT64(remote_state, kDaikin64PowerToggleBit); } -// Set the temp in deg C +/// Set the temperature. +/// @param[in] temp The temperature in degrees celsius. void IRDaikin64::setTemp(const uint8_t temp) { uint8_t degrees = std::max(temp, kDaikin64MinTemp); degrees = std::min(degrees, kDaikin64MaxTemp); @@ -3359,15 +3711,21 @@ void IRDaikin64::setTemp(const uint8_t temp) { kDaikin64TempSize, uint8ToBcd(degrees)); } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRDaikin64::getTemp(void) { return bcdToUint8(GETBITS64(remote_state, kDaikin64TempOffset, kDaikin64TempSize)); } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRDaikin64::getMode(void) { return GETBITS64(remote_state, kDaikin64ModeOffset, kDaikin64ModeSize); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRDaikin64::setMode(const uint8_t mode) { switch (mode) { case kDaikin64Fan: @@ -3381,7 +3739,9 @@ void IRDaikin64::setMode(const uint8_t mode) { setBits(&remote_state, kDaikin64ModeOffset, kDaikin64ModeSize, mode); } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRDaikin64::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kDry: return kDaikin64Dry; @@ -3390,7 +3750,9 @@ uint8_t IRDaikin64::convertMode(const stdAc::opmode_t mode) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRDaikin64::toCommonMode(const uint8_t mode) { switch (mode) { case kDaikin64Cool: return stdAc::opmode_t::kCool; @@ -3400,10 +3762,14 @@ stdAc::opmode_t IRDaikin64::toCommonMode(const uint8_t mode) { } } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRDaikin64::getFan(void) { return GETBITS64(remote_state, kDaikin64FanOffset, kDaikin64FanSize); } +/// Set the speed of the fan. +/// @param[in] speed The desired setting. void IRDaikin64::setFan(const uint8_t speed) { switch (speed) { case kDaikin64FanQuiet: @@ -3419,7 +3785,9 @@ void IRDaikin64::setFan(const uint8_t speed) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRDaikin64::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: return kDaikin64FanQuiet; @@ -3431,7 +3799,9 @@ uint8_t IRDaikin64::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRDaikin64::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kDaikin64FanTurbo: return stdAc::fanspeed_t::kMax; @@ -3443,10 +3813,14 @@ stdAc::fanspeed_t IRDaikin64::toCommonFanSpeed(const uint8_t speed) { } } +/// Get the Turbo (Powerful) mode status of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin64::getTurbo(void) { return getFan() == kDaikin64FanTurbo; } +/// Set the Turbo (Powerful) mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin64::setTurbo(const bool on) { if (on) { setFan(kDaikin64FanTurbo); @@ -3455,10 +3829,14 @@ void IRDaikin64::setTurbo(const bool on) { } } +/// Get the Quiet mode status of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin64::getQuiet(void) { return getFan() == kDaikin64FanQuiet; } +/// Set the Quiet mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin64::setQuiet(const bool on) { if (on) { setFan(kDaikin64FanQuiet); @@ -3467,22 +3845,32 @@ void IRDaikin64::setQuiet(const bool on) { } } +/// Set the Vertical Swing mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin64::setSwingVertical(const bool on) { setBit(&remote_state, kDaikin64SwingVBit, on); } +/// Get the Vertical Swing mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin64::getSwingVertical(void) { return GETBIT64(remote_state, kDaikin64SwingVBit); } +/// Set the Sleep mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin64::setSleep(const bool on) { setBit(&remote_state, kDaikin64SleepBit, on); } +/// Get the Sleep mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin64::getSleep(void) { return GETBIT64(remote_state, kDaikin64SleepBit); } +/// Set the clock on the A/C unit. +/// @param[in] mins_since_midnight Nr. of minutes past midnight. void IRDaikin64::setClock(const uint16_t mins_since_midnight) { uint16_t mins = mins_since_midnight; if (mins_since_midnight >= 24 * 60) mins = 0; // Bounds check. @@ -3492,6 +3880,8 @@ void IRDaikin64::setClock(const uint16_t mins_since_midnight) { kDaikin64ClockHoursSize, uint8ToBcd(mins / 60)); // Hours } +/// Get the clock time to be sent to the A/C unit. +/// @return The number of minutes past midnight. uint16_t IRDaikin64::getClock(void) { return bcdToUint8(GETBITS64(remote_state, kDaikin64ClockOffset + kDaikin64ClockMinsSize, @@ -3500,20 +3890,28 @@ uint16_t IRDaikin64::getClock(void) { kDaikin64ClockMinsSize)); } +/// Set the enable status of the On Timer. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin64::setOnTimeEnabled(const bool on) { setBit(&remote_state, kDaikin64OnTimeEnableBit, on); } +/// Get the enable status of the On Timer. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin64::getOnTimeEnabled(void) { return GETBIT64(remote_state, kDaikin64OnTimeEnableBit); } +/// Get the On Timer time to be sent to the A/C unit. +/// @return The number of minutes past midnight. uint16_t IRDaikin64::getOnTime(void) { return bcdToUint8(GETBITS64(remote_state, kDaikin64OnTimeOffset, kDaikin64OnTimeSize)) * 60 + (GETBIT64(remote_state, kDaikin64OnTimeHalfHourBit) ? 30 : 0); } +/// Set the On Timer time for the A/C unit. +/// @param[in] mins_since_midnight Nr. of minutes past midnight. void IRDaikin64::setOnTime(const uint16_t mins_since_midnight) { uint16_t halfhours = mins_since_midnight / 30; if (mins_since_midnight >= 24 * 60) halfhours = 0; // Bounds check. @@ -3523,20 +3921,28 @@ void IRDaikin64::setOnTime(const uint16_t mins_since_midnight) { setBit(&remote_state, kDaikin64OnTimeHalfHourBit, halfhours % 2); } +/// Set the enable status of the Off Timer. +/// @param[in] on true, the setting is on. false, the setting is off. void IRDaikin64::setOffTimeEnabled(const bool on) { setBit(&remote_state, kDaikin64OffTimeEnableBit, on); } +/// Get the enable status of the Off Timer. +/// @return true, the setting is on. false, the setting is off. bool IRDaikin64::getOffTimeEnabled(void) { return GETBIT64(remote_state, kDaikin64OffTimeEnableBit); } +/// Get the Off Timer time to be sent to the A/C unit. +/// @return The number of minutes past midnight. uint16_t IRDaikin64::getOffTime(void) { return bcdToUint8(GETBITS64(remote_state, kDaikin64OffTimeOffset, kDaikin64OffTimeSize)) * 60 + (GETBIT64(remote_state, kDaikin64OffTimeHalfHourBit) ? 30 : 0); } +/// Set the Off Timer time for the A/C unit. +/// @param[in] mins_since_midnight Nr. of minutes past midnight. void IRDaikin64::setOffTime(const uint16_t mins_since_midnight) { uint16_t halfhours = mins_since_midnight / 30; if (mins_since_midnight >= 24 * 60) halfhours = 0; // Bounds check. @@ -3546,7 +3952,8 @@ void IRDaikin64::setOffTime(const uint16_t mins_since_midnight) { setBit(&remote_state, kDaikin64OffTimeHalfHourBit, halfhours % 2); } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRDaikin64::toString(void) { String result = ""; result.reserve(120); // Reserve some heap for the string to reduce fragging. @@ -3578,7 +3985,9 @@ String IRDaikin64::toString(void) { return result; } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @param[in] prev Ptr to a previous state. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRDaikin64::toCommon(const stdAc::state_t *prev) { stdAc::state_t result; if (prev != NULL) result = *prev; diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Daikin.h b/lib/IRremoteESP8266-2.7.8/src/ir_Daikin.h similarity index 82% rename from lib/IRremoteESP8266-2.7.5/src/ir_Daikin.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Daikin.h index 3630aa77b..8c11dfb9f 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Daikin.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Daikin.h @@ -1,17 +1,36 @@ // Copyright 2016 sillyfrog // Copyright 2017 sillyfrog, crankyoldgit -// Copyright 2018-2019 crankyoldgit +// Copyright 2018-2020 crankyoldgit +// Copyright 2019 pasna (IRDaikin160 class / Daikin176 class) + +/// @file +/// @brief Support for Daikin A/C protocols. +/// @see Daikin http://harizanov.com/2012/02/control-daikin-air-conditioner-over-the-internet/ +/// @see Daikin https://github.com/mharizanov/Daikin-AC-remote-control-over-the-Internet/tree/master/IRremote +/// @see Daikin http://rdlab.cdmt.vn/project-2013/daikin-ir-protocol +/// @see Daikin https://github.com/blafois/Daikin-IR-Reverse +/// @see Daikin128 https://github.com/crankyoldgit/IRremoteESP8266/issues/827 +/// @see Daikin152 https://github.com/crankyoldgit/IRremoteESP8266/issues/873 +/// @see Daikin152 https://github.com/ToniA/arduino-heatpumpir/blob/master/DaikinHeatpumpARC480A14IR.cpp +/// @see Daikin152 https://github.com/ToniA/arduino-heatpumpir/blob/master/DaikinHeatpumpARC480A14IR.h +/// @see Daikin160 https://github.com/crankyoldgit/IRremoteESP8266/issues/731 +/// @see Daikin2 https://docs.google.com/spreadsheets/d/1f8EGfIbBUo2B-CzUFdrgKQprWakoYNKM80IKZN4KXQE/edit#gid=236366525&range=B25:D32 +/// @see Daikin2 https://github.com/crankyoldgit/IRremoteESP8266/issues/582 +/// @see Daikin2 https://www.daikin.co.nz/sites/default/files/daikin-split-system-US7-FTXZ25-50NV1B.pdf +/// @see Daikin216 https://github.com/crankyoldgit/IRremoteESP8266/issues/689 +/// @see Daikin216 https://github.com/danny-source/Arduino_DY_IRDaikin +/// @see Daikin64 https://github.com/crankyoldgit/IRremoteESP8266/issues/1064 // Supports: -// Brand: Daikin, Model: ARC433** remote -// Brand: Daikin, Model: ARC477A1 remote -// Brand: Daikin, Model: FTXZ25NV1B A/C -// Brand: Daikin, Model: FTXZ35NV1B A/C -// Brand: Daikin, Model: FTXZ50NV1B A/C -// Brand: Daikin, Model: ARC433B69 remote -// Brand: Daikin, Model: ARC423A5 remote +// Brand: Daikin, Model: ARC433** remote (DAIKIN) +// Brand: Daikin, Model: ARC477A1 remote (DAIKIN2) +// Brand: Daikin, Model: FTXZ25NV1B A/C (DAIKIN2) +// Brand: Daikin, Model: FTXZ35NV1B A/C (DAIKIN2) +// Brand: Daikin, Model: FTXZ50NV1B A/C (DAIKIN2) +// Brand: Daikin, Model: ARC433B69 remote (DAIKIN216) +// Brand: Daikin, Model: ARC423A5 remote (DAIKIN160) // Brand: Daikin, Model: FTE12HV2S A/C -// Brand: Daikin, Model: BRC4C153 remote +// Brand: Daikin, Model: BRC4C153 remote (DAIKIN176) // Brand: Daikin, Model: 17 Series A/C (DAIKIN128) // Brand: Daikin, Model: FTXB12AXVJU A/C (DAIKIN128) // Brand: Daikin, Model: FTXB09AXVJU A/C (DAIKIN128) @@ -19,6 +38,9 @@ // Brand: Daikin, Model: ARC480A5 remote (DAIKIN152) // Brand: Daikin, Model: FFN-C/FCN-F Series A/C (DAIKIN64) // Brand: Daikin, Model: DGS01 remote (DAIKIN64) +// Brand: Daikin, Model: M Series A/C (DAIKIN) +// Brand: Daikin, Model: FTXM-M A/C (DAIKIN) +// Brand: Daikin, Model: ARC466A33 remote (DAIKIN) #ifndef IR_DAIKIN_H_ #define IR_DAIKIN_H_ @@ -191,7 +213,7 @@ const uint16_t kDaikinGap = 29000; const uint64_t kDaikinFirstHeader64 = 0b1101011100000000000000001100010100000000001001111101101000010001; -// Another variant of the protocol for the Daikin ARC477A1 remote. + const uint16_t kDaikin2Freq = 36700; // Modulation Frequency in Hz. const uint16_t kDaikin2LeaderMark = 10024; const uint16_t kDaikin2LeaderSpace = 25180; @@ -237,8 +259,6 @@ const uint8_t kDaikin2SwingVBreeze = 0xC; const uint8_t kDaikin2SwingVCirculate = 0xD; const uint8_t kDaikin2FanByte = 28; -// Ref: -// https://docs.google.com/spreadsheets/d/1f8EGfIbBUo2B-CzUFdrgKQprWakoYNKM80IKZN4KXQE/edit#gid=236366525&range=B25:D32 const uint8_t kDaikin2SwingHWide = 0xA3; const uint8_t kDaikin2SwingHLeftMax = 0xA8; const uint8_t kDaikin2SwingHLeft = 0xA9; @@ -250,7 +270,7 @@ const uint8_t kDaikin2SwingHSwing = 0xBF; const uint8_t kDaikin2MinCoolTemp = 18; // Min temp (in C) when in Cool mode. -// Another variant of the protocol for the Daikin ARC433B69 remote. + const uint16_t kDaikin216Freq = 38000; // Modulation Frequency in Hz. const uint16_t kDaikin216HdrMark = 3440; const uint16_t kDaikin216HdrSpace = 1750; @@ -280,7 +300,7 @@ const uint8_t kDaikin216SwingOff = 0b0000; const uint8_t kDaikin216ByteSwingH = 17; const uint8_t kDaikin216BytePowerful = 21; -// Another variant of the protocol for the Daikin ARC423A5 remote. + const uint16_t kDaikin160Freq = 38000; // Modulation Frequency in Hz. const uint16_t kDaikin160HdrMark = 5000; const uint16_t kDaikin160HdrSpace = 2145; @@ -310,7 +330,7 @@ const uint8_t kDaikin160SwingVHigh = 0x4; const uint8_t kDaikin160SwingVHighest = 0x5; const uint8_t kDaikin160SwingVAuto = 0xF; -// Another variant of the protocol for the Daikin BRC4C153 remote. + const uint16_t kDaikin176Freq = 38000; // Modulation Frequency in Hz. const uint16_t kDaikin176HdrMark = 5070; const uint16_t kDaikin176HdrSpace = 2140; @@ -341,8 +361,7 @@ const uint8_t kDaikin176ByteSwingH = 18; const uint8_t kDaikin176SwingHAuto = 0x5; const uint8_t kDaikin176SwingHOff = 0x6; -// Another variant of the protocol for the Daikin BRC52B63 remote. -// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/827 + const uint16_t kDaikin128Freq = 38000; // Modulation Frequency in Hz. const uint16_t kDaikin128LeaderMark = 9800; const uint16_t kDaikin128LeaderSpace = 9800; @@ -400,8 +419,7 @@ const uint8_t kDaikin128BitWall = 0b00001000; const uint8_t kDaikin128BitCeiling = 0b00000001; const uint8_t kDaikin128MaskLight = kDaikin128BitWall | kDaikin128BitCeiling; -// Another variant of the protocol for the Daikin ARC480A5 remote. -// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/873 + const uint16_t kDaikin152Freq = 38000; // Modulation Frequency in Hz. const uint8_t kDaikin152LeaderBits = 5; const uint16_t kDaikin152HdrMark = 3492; @@ -432,6 +450,7 @@ const uint8_t kDaikin152ComfortOffset = 1; // Mask 0b00000010 const uint8_t kDaikin152SensorByte = kDaikin152EconoByte; // Mask 0b00001000 const uint8_t kDaikin152SensorOffset = 3; // Mask 0b00001000 + const uint16_t kDaikin64HdrMark = kDaikin128HdrMark; const uint16_t kDaikin64BitMark = kDaikin128BitMark; const uint16_t kDaikin64HdrSpace = kDaikin128HdrSpace; @@ -441,7 +460,8 @@ const uint16_t kDaikin64LdrMark = kDaikin128LeaderMark; const uint16_t kDaikin64Gap = kDaikin128Gap; const uint16_t kDaikin64LdrSpace = kDaikin128LeaderSpace; const uint16_t kDaikin64Freq = kDaikin128Freq; // Hz. -const uint16_t kDaikin64Overhead = 9; +const uint8_t kDaikin64Overhead = 9; +const int8_t kDaikin64ToleranceDelta = 5; // +5% const uint64_t kDaikin64KnownGoodState = 0x7C16161607204216; const uint8_t kDaikin64ModeOffset = 8; @@ -496,6 +516,7 @@ const uint8_t kDaikin64ChecksumSize = 4; // Mask 0b1111 << 59 #define DAIKIN_FAN_AUTO kDaikinFanAuto #define DAIKIN_FAN_QUIET kDaikinFanQuiet +/// Class for handling detailed Daikin 280-bit A/C messages. class IRDaikinESP { public: explicit IRDaikinESP(const uint16_t pin, const bool inverted = false, @@ -503,7 +524,11 @@ class IRDaikinESP { #if SEND_DAIKIN void send(const uint16_t repeat = kDaikinDefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + /// 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 void begin(void); void on(void); @@ -560,17 +585,20 @@ class IRDaikinESP { #ifndef UNIT_TEST private: - IRsend _irsend; + IRsend _irsend; ///< instance of the IR send class #else - IRsendTest _irsend; + /// @cond IGNORE + IRsendTest _irsend; ///< instance of the testing IR send class + /// @endcond #endif // # of bytes per command - uint8_t remote[kDaikinStateLength]; + uint8_t remote[kDaikinStateLength]; ///< The state of the IR remote. void stateReset(void); void checksum(void); }; -// Class to emulate a Daikin ARC477A1 remote. +/// Class for handling detailed Daikin 312-bit A/C messages. +/// Code by crankyoldgit, Reverse engineering analysis by sheppy99 class IRDaikin2 { public: explicit IRDaikin2(const uint16_t pin, const bool inverted = false, @@ -578,7 +606,11 @@ class IRDaikin2 { #if SEND_DAIKIN2 void send(const uint16_t repeat = kDaikin2DefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + /// 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 void begin(); void on(); @@ -599,8 +631,6 @@ class IRDaikin2 { void setQuiet(const bool on); bool getPowerful(); void setPowerful(const bool on); - void setSensor(const bool on); - bool getSensor(); void setEcono(const bool on); bool getEcono(); void setEye(const bool on); @@ -637,8 +667,6 @@ class IRDaikin2 { bool getFreshAirHigh(); uint8_t* getRaw(); void setRaw(const uint8_t new_code[]); - uint32_t getCommand(); - void setCommand(uint32_t value); static bool validChecksum(uint8_t state[], const uint16_t length = kDaikin2StateLength); static uint8_t convertMode(const stdAc::opmode_t mode); @@ -652,19 +680,21 @@ class IRDaikin2 { #ifndef UNIT_TEST private: - IRsend _irsend; + IRsend _irsend; ///< instance of the IR send class #else - IRsendTest _irsend; + /// @cond IGNORE + IRsendTest _irsend; ///< instance of the testing IR send class + /// @endcond #endif // # of bytes per command - uint8_t remote_state[kDaikin2StateLength]; + uint8_t remote_state[kDaikin2StateLength]; ///< The state of the IR remote. void stateReset(); void checksum(); void clearOnTimerFlag(); void clearSleepTimerFlag(); }; -// Class to emulate a Daikin ARC433B69 remote. +/// Class for handling detailed Daikin 216-bit A/C messages. class IRDaikin216 { public: explicit IRDaikin216(const uint16_t pin, const bool inverted = false, @@ -672,7 +702,11 @@ class IRDaikin216 { #if SEND_DAIKIN216 void send(const uint16_t repeat = kDaikin216DefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + /// 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 void begin(); uint8_t* getRaw(); @@ -704,17 +738,19 @@ class IRDaikin216 { #ifndef UNIT_TEST private: - IRsend _irsend; + IRsend _irsend; ///< instance of the IR send class #else - IRsendTest _irsend; + /// @cond IGNORE + IRsendTest _irsend; ///< instance of the testing IR send class + /// @endcond #endif // # of bytes per command - uint8_t remote_state[kDaikin216StateLength]; + uint8_t remote_state[kDaikin216StateLength]; ///< The state of the IR remote. void stateReset(); void checksum(); }; -// Class to emulate a Daikin ARC423A5 remote. +/// Class for handling detailed Daikin 160-bit A/C messages. class IRDaikin160 { public: explicit IRDaikin160(const uint16_t pin, const bool inverted = false, @@ -722,7 +758,11 @@ class IRDaikin160 { #if SEND_DAIKIN160 void send(const uint16_t repeat = kDaikin160DefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + /// 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 void begin(); uint8_t* getRaw(); @@ -750,17 +790,19 @@ class IRDaikin160 { #ifndef UNIT_TEST private: - IRsend _irsend; + IRsend _irsend; ///< instance of the IR send class #else - IRsendTest _irsend; + /// @cond IGNORE + IRsendTest _irsend; ///< instance of the testing IR send class + /// @endcond #endif // # of bytes per command - uint8_t remote_state[kDaikin160StateLength]; + uint8_t remote_state[kDaikin160StateLength]; ///< The state of the IR remote. void stateReset(); void checksum(); }; -// Class to emulate a Daikin BRC4C153 remote. +/// Class for handling detailed Daikin 176-bit A/C messages. class IRDaikin176 { public: explicit IRDaikin176(const uint16_t pin, const bool inverted = false, @@ -768,7 +810,11 @@ class IRDaikin176 { #if SEND_DAIKIN176 void send(const uint16_t repeat = kDaikin176DefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + /// 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 void begin(); uint8_t* getRaw(); @@ -799,25 +845,33 @@ class IRDaikin176 { #ifndef UNIT_TEST private: - IRsend _irsend; + IRsend _irsend; ///< instance of the IR send class #else - IRsendTest _irsend; + /// @cond IGNORE + IRsendTest _irsend; ///< instance of the testing IR send class + /// @endcond #endif // # of bytes per command - uint8_t remote_state[kDaikin176StateLength]; + uint8_t remote_state[kDaikin176StateLength]; ///< The state of the IR remote. uint8_t _saved_temp; void stateReset(); void checksum(); }; -// Class to emulate a Daikin BRC52B63 remote / Daikin 17 series A/C. +/// Class for handling detailed Daikin 128-bit A/C messages. +/// Code by crankyoldgit. +/// Analysis by Daniel Vena class IRDaikin128 { public: explicit IRDaikin128(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); #if SEND_DAIKIN128 void send(const uint16_t repeat = kDaikin128DefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + /// 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_DAIKIN128 void begin(); void setPowerToggle(const bool toggle); @@ -862,12 +916,14 @@ class IRDaikin128 { #ifndef UNIT_TEST private: - IRsend _irsend; + IRsend _irsend; ///< instance of the IR send class #else - IRsendTest _irsend; + /// @cond IGNORE + IRsendTest _irsend; ///< instance of the testing IR send class + /// @endcond #endif // # of bytes per command - uint8_t remote_state[kDaikin128StateLength]; + uint8_t remote_state[kDaikin128StateLength]; ///< The state of the IR remote. void stateReset(void); static uint8_t calcFirstChecksum(const uint8_t state[]); static uint8_t calcSecondChecksum(const uint8_t state[]); @@ -878,7 +934,7 @@ class IRDaikin128 { void clearSleepTimerFlag(void); }; -// Class to emulate a Daikin ARC480A5 remote. +/// Class for handling detailed Daikin 152-bit A/C messages. class IRDaikin152 { public: explicit IRDaikin152(const uint16_t pin, const bool inverted = false, @@ -886,7 +942,11 @@ class IRDaikin152 { #if SEND_DAIKIN152 void send(const uint16_t repeat = kDaikin152DefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + /// 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 void begin(); uint8_t* getRaw(); @@ -917,24 +977,24 @@ class IRDaikin152 { bool getComfort(void); static uint8_t convertMode(const stdAc::opmode_t mode); static uint8_t convertFan(const stdAc::fanspeed_t speed); - static stdAc::opmode_t toCommonMode(const uint8_t mode); - static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed); stdAc::state_t toCommon(void); String toString(void); #ifndef UNIT_TEST private: - IRsend _irsend; + IRsend _irsend; ///< instance of the IR send class #else - IRsendTest _irsend; + /// @cond IGNORE + IRsendTest _irsend; ///< instance of the testing IR send class + /// @endcond #endif // # of bytes per command - uint8_t remote_state[kDaikin152StateLength]; + uint8_t remote_state[kDaikin152StateLength]; ///< The state of the IR remote. void stateReset(); void checksum(); }; -// Class to emulate a Daikin DGS01 remote. +/// Class for handling detailed Daikin 64-bit A/C messages. class IRDaikin64 { public: explicit IRDaikin64(const uint16_t pin, const bool inverted = false, @@ -942,7 +1002,11 @@ class IRDaikin64 { #if SEND_DAIKIN64 void send(const uint16_t repeat = kDaikin64DefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + /// 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_DAIKIN64 void begin(); uint64_t getRaw(); @@ -984,11 +1048,13 @@ class IRDaikin64 { #ifndef UNIT_TEST private: - IRsend _irsend; + IRsend _irsend; ///< instance of the IR send class #else - IRsendTest _irsend; + /// @cond IGNORE + IRsendTest _irsend; ///< instance of the testing IR send class + /// @endcond #endif - uint64_t remote_state; + uint64_t remote_state; ///< The state of the IR remote. void stateReset(); void checksum(); }; diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Delonghi.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Delonghi.cpp new file mode 100644 index 000000000..df915ca35 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Delonghi.cpp @@ -0,0 +1,483 @@ +// Copyright 2020 David Conran +/// @file +/// @brief Delonghi based protocol. + +#include "ir_Delonghi.h" +#include "IRrecv.h" +#include "IRsend.h" +#include "IRtext.h" +#include "IRutils.h" +#include + +using irutils::addBoolToString; +using irutils::addModeToString; +using irutils::addFanToString; +using irutils::addLabeledString; +using irutils::addTempToString; +using irutils::minsToString; +using irutils::setBit; +using irutils::setBits; + +const uint16_t kDelonghiAcHdrMark = 8984; +const uint16_t kDelonghiAcBitMark = 572; +const uint16_t kDelonghiAcHdrSpace = 4200; +const uint16_t kDelonghiAcOneSpace = 1558; +const uint16_t kDelonghiAcZeroSpace = 510; +const uint32_t kDelonghiAcGap = kDefaultMessageGap; // A totally made-up guess. +const uint16_t kDelonghiAcFreq = 38000; // Hz. (Guess: most common frequency.) +const uint16_t kDelonghiAcOverhead = 3; + + +#if SEND_DELONGHI_AC +/// Send a Delonghi A/C formatted message. +/// Status: STABLE / Reported as working on 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. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1096 +void IRsend::sendDelonghiAc(const uint64_t data, const uint16_t nbits, + const uint16_t repeat) { + sendGeneric(kDelonghiAcHdrMark, kDelonghiAcHdrSpace, + kDelonghiAcBitMark, kDelonghiAcOneSpace, + kDelonghiAcBitMark, kDelonghiAcZeroSpace, + kDelonghiAcBitMark, kDelonghiAcGap, + data, nbits, kDelonghiAcFreq, false, // LSB First. + repeat, kDutyDefault); +} +#endif // SEND_DELONGHI_AC + +#if DECODE_DELONGHI_AC +/// Decode the supplied Delonghi A/C message. +/// Status: STABLE / Expected to be 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. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1096 +bool IRrecv::decodeDelonghiAc(decode_results *results, uint16_t offset, + const uint16_t nbits, const bool strict) { + if (results->rawlen < 2 * nbits + kDelonghiAcOverhead - offset) + return false; // Too short a message to match. + if (strict && nbits != kDelonghiAcBits) + return false; + + uint64_t data = 0; + + // Header + Data + Footer + if (!matchGeneric(results->rawbuf + offset, &data, + results->rawlen - offset, nbits, + kDelonghiAcHdrMark, kDelonghiAcHdrSpace, + kDelonghiAcBitMark, kDelonghiAcOneSpace, + kDelonghiAcBitMark, kDelonghiAcZeroSpace, + kDelonghiAcBitMark, kDelonghiAcGap, true, + _tolerance, kMarkExcess, false)) return false; + + // Compliance + if (strict && !IRDelonghiAc::validChecksum(data)) return false; + + // Success + results->decode_type = decode_type_t::DELONGHI_AC; + results->bits = nbits; + results->value = data; + results->command = 0; + results->address = 0; + return true; +} +#endif // DECODE_DELONGHI_AC + +/// 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? +IRDelonghiAc::IRDelonghiAc(const uint16_t pin, const bool inverted, + const bool use_modulation) + : _irsend(pin, inverted, use_modulation) { this->stateReset(); } + +/// Set up hardware to be able to send a message. +void IRDelonghiAc::begin(void) { _irsend.begin(); } + +#if SEND_DELONGHI_AC +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. +void IRDelonghiAc::send(const uint16_t repeat) { + _irsend.sendDelonghiAc(getRaw(), kDelonghiAcBits, repeat); +} +#endif // SEND_DELONGHI_AC + +/// Calculate the checksum for a given state. +/// @param[in] state The value to calc the checksum of. +/// @return A valid checksum value. +uint8_t IRDelonghiAc::calcChecksum(const uint64_t state) { + uint8_t sum = 0; + // Add up all the 8 bit chunks except for Most-significant 8 bits. + for (uint8_t offset = 0; offset < kDelonghiAcChecksumOffset; offset += 8) { + sum += GETBITS64(state, offset, 8); + } + return sum; +} + +/// Verify the checksum is valid for a given state. +/// @param[in] state The state to verify the checksum of. +/// @return true, if the state has a valid checksum. Otherwise, false. +bool IRDelonghiAc::validChecksum(const uint64_t state) { + return (GETBITS64(state, kDelonghiAcChecksumOffset, + kDelonghiAcChecksumSize) == + IRDelonghiAc::calcChecksum(state)); +} + +/// Calculate and set the checksum values for the internal state. +void IRDelonghiAc::checksum(void) { + setBits(&remote_state, kDelonghiAcChecksumOffset, kDelonghiAcChecksumSize, + calcChecksum(remote_state)); +} + +/// Reset the internal state to a fixed known good state. +void IRDelonghiAc::stateReset(void) { + remote_state = 0x5400000000000153; + _saved_temp = 23; // DegC (Random reasonable default value) + _saved_temp_units = 0; // Celsius +} + +/// Get a copy of the internal state as a valid code for this protocol. +/// @return A valid code for this protocol based on the current internal state. +uint64_t IRDelonghiAc::getRaw(void) { + checksum(); // Ensure correct bit array before returning + return remote_state; +} + +/// Set the internal state from a valid code for this protocol. +/// @param[in] state A valid code for this protocol. +void IRDelonghiAc::setRaw(const uint64_t state) { remote_state = state; } + +/// Change the power setting to On. +void IRDelonghiAc::on(void) { setPower(true); } + +/// Change the power setting to Off. +void IRDelonghiAc::off(void) { setPower(false); } + +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. +void IRDelonghiAc::setPower(const bool on) { + setBit(&remote_state, kDelonghiAcPowerBit, on); +} + +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. +bool IRDelonghiAc::getPower(void) { + return GETBIT64(remote_state, kDelonghiAcPowerBit); +} + +/// Change the temperature scale units. +/// @param[in] fahrenheit true, use Fahrenheit. false, use Celsius. +void IRDelonghiAc::setTempUnit(const bool fahrenheit) { + setBit(&remote_state, kDelonghiAcTempUnitBit, fahrenheit); +} + +/// Get the temperature scale unit of measure currently in use. +/// @return true, is Fahrenheit. false, is Celsius. +bool IRDelonghiAc::getTempUnit(void) { + return GETBIT64(remote_state, kDelonghiAcTempUnitBit); +} + +/// Set the temperature. +/// @param[in] degrees The temperature in degrees. +/// @param[in] fahrenheit Use Fahrenheit as the temperature scale. +/// @param[in] force Do we ignore any sanity checks? +void IRDelonghiAc::setTemp(const uint8_t degrees, const bool fahrenheit, + const bool force) { + uint8_t temp; + if (force) { + temp = degrees; // We've been asked to force set this value. + } else { + uint8_t temp_min = kDelonghiAcTempMinC; + uint8_t temp_max = kDelonghiAcTempMaxC; + setTempUnit(fahrenheit); + if (fahrenheit) { + temp_min = kDelonghiAcTempMinF; + temp_max = kDelonghiAcTempMaxF; + } + temp = std::max(temp_min, degrees); + temp = std::min(temp_max, temp); + _saved_temp = temp; + _saved_temp_units = fahrenheit; + temp = temp - temp_min + 1; + } + setBits(&remote_state, kDelonghiAcTempOffset, kDelonghiAcTempSize, + temp); +} + +/// Get the current temperature setting. +/// @return The current setting for temp. in currently configured units/scale. +uint8_t IRDelonghiAc::getTemp(void) { + return GETBITS64(remote_state, kDelonghiAcTempOffset, kDelonghiAcTempSize) + + (getTempUnit() ? kDelonghiAcTempMinF : kDelonghiAcTempMinC) - 1; +} + +/// Set the speed of the fan. +/// @param[in] speed The desired native setting. +void IRDelonghiAc::setFan(const uint8_t speed) { + // Mode fan speed rules. + switch (getMode()) { + case kDelonghiAcFan: + // Fan mode can't have auto fan speed. + if (speed == kDelonghiAcFanAuto) { + if (getFan() == kDelonghiAcFanAuto) setFan(kDelonghiAcFanHigh); + return; + } + break; + case kDelonghiAcAuto: + case kDelonghiAcDry: + // Auto & Dry modes only allows auto fan speed. + if (speed != kDelonghiAcFanAuto) { + setFan(kDelonghiAcFanAuto); + return; + } + break; + } + // Bounds check enforcement + if (speed > kDelonghiAcFanLow) + setFan(kDelonghiAcFanAuto); + else + setBits(&remote_state, kDelonghiAcFanOffset, kDelonghiAcFanSize, speed); +} + +/// Get the current native fan speed setting. +/// @return The current fan speed. +uint8_t IRDelonghiAc::getFan(void) { + return GETBITS64(remote_state, kDelonghiAcFanOffset, kDelonghiAcFanSize); +} + +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. +uint8_t IRDelonghiAc::convertFan(const stdAc::fanspeed_t speed) { + switch (speed) { + case stdAc::fanspeed_t::kMin: + case stdAc::fanspeed_t::kLow: + return kDelonghiAcFanLow; + case stdAc::fanspeed_t::kMedium: + return kDelonghiAcFanMedium; + case stdAc::fanspeed_t::kHigh: + case stdAc::fanspeed_t::kMax: + return kDelonghiAcFanHigh; + default: + return kDelonghiAcFanAuto; + } +} + +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. +stdAc::fanspeed_t IRDelonghiAc::toCommonFanSpeed(const uint8_t speed) { + switch (speed) { + case kDelonghiAcFanHigh: return stdAc::fanspeed_t::kMax; + case kDelonghiAcFanMedium: return stdAc::fanspeed_t::kMedium; + case kDelonghiAcFanLow: return stdAc::fanspeed_t::kMin; + default: return stdAc::fanspeed_t::kAuto; + } +} + +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. +uint8_t IRDelonghiAc::getMode(void) { + return GETBITS64(remote_state, kDelonghiAcModeOffset, kDelonghiAcModeSize); +} + +/// Set the operating mode of the A/C. +/// @param[in] mode The desired native operating mode. +void IRDelonghiAc::setMode(const uint8_t mode) { + switch (mode) { + case kDelonghiAcAuto: + case kDelonghiAcDry: + // Set special temp for these modes. + setTemp(kDelonghiAcTempAutoDryMode, getTempUnit(), true); + break; + case kDelonghiAcFan: + // Set special temp for this mode. + setTemp(kDelonghiAcTempFanMode, getTempUnit(), true); + break; + case kDelonghiAcCool: + break; + default: + this->setMode(kDelonghiAcAuto); + return; + } + setBits(&remote_state, kDelonghiAcModeOffset, kDelonghiAcModeSize, mode); + setFan(getFan()); // Re-force any fan speed constraints. + // Restore previous temp settings for cool mode. + if (mode == kDelonghiAcCool) setTemp(_saved_temp, _saved_temp_units); +} + +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. +uint8_t IRDelonghiAc::convertMode(const stdAc::opmode_t mode) { + switch (mode) { + case stdAc::opmode_t::kCool: + return kDelonghiAcCool; + case stdAc::opmode_t::kDry: + return kDelonghiAcDry; + case stdAc::opmode_t::kFan: + return kDelonghiAcFan; + default: + return kDelonghiAcAuto; + } +} + +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. +stdAc::opmode_t IRDelonghiAc::toCommonMode(const uint8_t mode) { + switch (mode) { + case kDelonghiAcCool: return stdAc::opmode_t::kCool; + case kDelonghiAcDry: return stdAc::opmode_t::kDry; + case kDelonghiAcFan: return stdAc::opmode_t::kFan; + default: return stdAc::opmode_t::kAuto; + } +} + +/// Set the Boost (Turbo) mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. +void IRDelonghiAc::setBoost(const bool on) { + setBit(&remote_state, kDelonghiAcBoostBit, on); +} + +/// Get the Boost (Turbo) mode of the A/C. +/// @return true, the setting is on. false, the setting is off. +bool IRDelonghiAc::getBoost(void) { + return GETBIT64(remote_state, kDelonghiAcBoostBit); +} + +/// Set the Sleep mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. +void IRDelonghiAc::setSleep(const bool on) { + setBit(&remote_state, kDelonghiAcSleepBit, on); +} + +/// Get the Sleep mode status of the A/C. +/// @return true, the setting is on. false, the setting is off. +bool IRDelonghiAc::getSleep(void) { + return GETBIT64(remote_state, kDelonghiAcSleepBit); +} + +/// Set the enable status of the On Timer. +/// @param[in] on true, the setting is on. false, the setting is off. +void IRDelonghiAc::setOnTimerEnabled(const bool on) { + setBit(&remote_state, kDelonghiAcOnTimerEnableBit, on); +} + +/// Get the enable status of the On Timer. +/// @return true, the setting is on. false, the setting is off. +bool IRDelonghiAc::getOnTimerEnabled(void) { + return GETBIT64(remote_state, kDelonghiAcOnTimerEnableBit); +} + +/// Set the On timer to activate in nr of minutes. +/// @param[in] nr_of_mins Total nr of mins to wait before waking the device. +/// @note Max 23 hrs and 59 minutes. i.e. 1439 mins. +void IRDelonghiAc::setOnTimer(const uint16_t nr_of_mins) { + uint16_t value = std::min(kDelonghiAcTimerMax, nr_of_mins); + setBits(&remote_state, kDelonghiAcOnTimerMinsOffset, kDelonghiAcMinsSize, + value % 60); // Minutes. + setBits(&remote_state, kDelonghiAcOnTimerHoursOffset, kDelonghiAcHoursSize, + value / 60); // Hours. + // Enable or not? + setOnTimerEnabled(value > 0); +} + +/// Get the On timer time. +/// @return Total nr of mins before the device turns on. +uint16_t IRDelonghiAc::getOnTimer(void) { + return GETBITS64(remote_state, kDelonghiAcOnTimerHoursOffset, + kDelonghiAcHoursSize) * 60 + + GETBITS64(remote_state, kDelonghiAcOnTimerMinsOffset, + kDelonghiAcMinsSize); +} + +/// Set the enable status of the Off Timer. +/// @param[in] on true, the setting is on. false, the setting is off. +void IRDelonghiAc::setOffTimerEnabled(const bool on) { + setBit(&remote_state, kDelonghiAcOffTimerEnableBit, on); +} + +/// Get the enable status of the Off Timer. +/// @return true, the setting is on. false, the setting is off. +bool IRDelonghiAc::getOffTimerEnabled(void) { + return GETBIT64(remote_state, kDelonghiAcOffTimerEnableBit); +} + +/// Set the Off timer to activate in nr of minutes. +/// @param[in] nr_of_mins Total nr of mins to wait before turning off the device +/// @note Max 23 hrs and 59 minutes. i.e. 1439 mins. +void IRDelonghiAc::setOffTimer(const uint16_t nr_of_mins) { + uint16_t value = std::min(kDelonghiAcTimerMax, nr_of_mins); + setBits(&remote_state, kDelonghiAcOffTimerMinsOffset, kDelonghiAcMinsSize, + value % 60); // Minutes. + setBits(&remote_state, kDelonghiAcOffTimerHoursOffset, kDelonghiAcHoursSize, + value / 60); // Hours. + // Enable or not? + setOffTimerEnabled(value > 0); +} + +/// Get the Off timer time. +/// @return Total nr of mins before the device turns off. +uint16_t IRDelonghiAc::getOffTimer(void) { + return GETBITS64(remote_state, kDelonghiAcOffTimerHoursOffset, + kDelonghiAcHoursSize) * 60 + + GETBITS64(remote_state, kDelonghiAcOffTimerMinsOffset, + kDelonghiAcMinsSize); +} + +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. +stdAc::state_t IRDelonghiAc::toCommon(void) { + stdAc::state_t result; + result.protocol = decode_type_t::DELONGHI_AC; + result.power = getPower(); + // result.mode = this->toCommonMode(this->getMode()); + result.celsius = getTempUnit(); + result.degrees = getTemp(); + result.fanspeed = toCommonFanSpeed(this->getFan()); + result.turbo = getBoost(); + result.sleep = getSleep() ? 0 : -1; + // Not supported. + result.model = -1; + result.swingv = stdAc::swingv_t::kOff; + 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 IRDelonghiAc::toString(void) { + String result = ""; + result.reserve(80); // Reserve some heap for the string to reduce fragging. + result += addBoolToString(getPower(), kPowerStr, false); + result += addModeToString(getMode(), kDelonghiAcAuto, kDelonghiAcCool, + kDelonghiAcAuto, kDelonghiAcDry, kDelonghiAcFan); + result += addFanToString(getFan(), kDelonghiAcFanHigh, kDelonghiAcFanLow, + kDelonghiAcFanAuto, kDelonghiAcFanAuto, + kDelonghiAcFanMedium); + result += addTempToString(getTemp(), !getTempUnit()); + result += addBoolToString(getBoost(), kTurboStr); + result += addBoolToString(getSleep(), kSleepStr); + uint16_t mins = getOnTimer(); + result += addLabeledString((mins && getOnTimerEnabled()) ? minsToString(mins) + : kOffStr, + kOnTimerStr); + mins = getOffTimer(); + result += addLabeledString((mins && getOffTimerEnabled()) ? minsToString(mins) + : kOffStr, + kOffTimerStr); + return result; +} diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Delonghi.h b/lib/IRremoteESP8266-2.7.8/src/ir_Delonghi.h new file mode 100644 index 000000000..da3a6f618 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Delonghi.h @@ -0,0 +1,165 @@ +// Copyright 2020 David Conran + +/// @file +/// @brief Delonghi A/C +/// @note Kudos to TheMaxxz For the breakdown and mapping of the bit values. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1096 + +// Supports: +// Brand: Delonghi, Model: PAC A95 + +#ifndef IR_DELONGHI_H_ +#define IR_DELONGHI_H_ + +#define __STDC_LIMIT_MACROS +#include +#ifndef UNIT_TEST +#include +#endif +#include "IRremoteESP8266.h" +#include "IRsend.h" +#ifdef UNIT_TEST +#include "IRsend_test.h" +#endif + +/* State bit map: + ++--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+------+ +| FIXED HEADER | TEMPERATURE | FAN |F or C| ++--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+------+ + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + ++--+--+--+--+-----+-----+ +|ON| MODE |Boost|Sleep| ++--+--+--+--+-----+-----+ +16 17 18 19 20 21 + ++--+--+------------+--+--+--+--+--+--+--+--+--+--+--+--+--+ +| 0| 0|Timer Enable| ON TIME HOUR | 0 0| ON TIME MIN | ++--+--+------------+--+--+--+--+--+--+--+--+--+--+--+--+--+ + 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 + ++--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +| 0 0| OFF TIMER | CHECKSUM | ++--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 + +*/ + +// Constants +const uint8_t kDelonghiAcTempOffset = 8; +const uint8_t kDelonghiAcTempSize = 5; +const uint8_t kDelonghiAcTempMinC = 18; // Deg C +const uint8_t kDelonghiAcTempMaxC = 32; // Deg C +const uint8_t kDelonghiAcTempMinF = 64; // Deg F +const uint8_t kDelonghiAcTempMaxF = 90; // Deg F +const uint8_t kDelonghiAcTempAutoDryMode = 0; +const uint8_t kDelonghiAcTempFanMode = 0b00110; +const uint8_t kDelonghiAcFanOffset = kDelonghiAcTempOffset + + kDelonghiAcTempSize; // 13 +const uint8_t kDelonghiAcFanSize = 2; +const uint8_t kDelonghiAcFanAuto = 0b00; +const uint8_t kDelonghiAcFanHigh = 0b01; +const uint8_t kDelonghiAcFanMedium = 0b10; +const uint8_t kDelonghiAcFanLow = 0b11; +const uint8_t kDelonghiAcTempUnitBit = kDelonghiAcFanOffset + + kDelonghiAcFanSize; // 15 (1 = Celsius, 0 = Fahrenheit) +const uint8_t kDelonghiAcPowerBit = kDelonghiAcTempUnitBit + 1; // 16 +const uint8_t kDelonghiAcModeOffset = kDelonghiAcPowerBit + 1; // 17 +const uint8_t kDelonghiAcModeSize = 3; +const uint8_t kDelonghiAcCool = 0b000; +const uint8_t kDelonghiAcDry = 0b001; +const uint8_t kDelonghiAcFan = 0b010; +const uint8_t kDelonghiAcAuto = 0b100; +const uint8_t kDelonghiAcBoostBit = kDelonghiAcModeOffset + + kDelonghiAcModeSize; // 20 (Aka Turbo) +const uint8_t kDelonghiAcSleepBit = kDelonghiAcBoostBit + 1; // 21 +// Two zero bits +const uint8_t kDelonghiAcOnTimerEnableBit = kDelonghiAcSleepBit + 3; // 24 +const uint8_t kDelonghiAcHoursSize = 5; // Max 23 hrs +const uint8_t kDelonghiAcMinsSize = 6; // Max 59 mins +const uint16_t kDelonghiAcTimerMax = 23 * 60 + 59; +const uint8_t kDelonghiAcOnTimerHoursOffset = kDelonghiAcOnTimerEnableBit + + 1; // 25 +const uint8_t kDelonghiAcOnTimerMinsOffset = kDelonghiAcOnTimerHoursOffset + + kDelonghiAcHoursSize + 2; // 32 (inc another two zero bits) +// Two zero bits +const uint8_t kDelonghiAcOffTimerEnableBit = kDelonghiAcOnTimerMinsOffset + + kDelonghiAcMinsSize + 2; // 40 +const uint8_t kDelonghiAcOffTimerHoursOffset = kDelonghiAcOffTimerEnableBit + + 1; // 41 +const uint8_t kDelonghiAcOffTimerMinsOffset = kDelonghiAcOffTimerHoursOffset + + kDelonghiAcHoursSize + 2; // 48 (inc another two zero bits) +// Two zero bits +const uint8_t kDelonghiAcChecksumOffset = kDelonghiAcOffTimerMinsOffset + + kDelonghiAcMinsSize + 2; // 56 +const uint8_t kDelonghiAcChecksumSize = 8; + + +// Classes + +/// Class for handling detailed Delonghi A/C messages. +class IRDelonghiAc { + public: + explicit IRDelonghiAc(const uint16_t pin, const bool inverted = false, + const bool use_modulation = true); + void stateReset(); +#if SEND_DELONGHI_AC + void send(const uint16_t repeat = kDelonghiAcDefaultRepeat); + /// 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_DELONGHI_AC + void begin(); + static uint8_t calcChecksum(const uint64_t state); + static bool validChecksum(const uint64_t state); + void setPower(const bool on); + bool getPower(); + void on(); + void off(); + void setTempUnit(const bool celsius); + bool getTempUnit(void); + void setTemp(const uint8_t temp, const bool fahrenheit = false, + const bool force = false); + uint8_t getTemp(); + void setFan(const uint8_t speed); + uint8_t getFan(); + void setMode(const uint8_t mode); + uint8_t getMode(); + void setBoost(const bool on); // Aka Turbo + bool getBoost(); // Aka Turbo + void setSleep(const bool on); + bool getSleep(); + void setOnTimerEnabled(const bool on); + bool getOnTimerEnabled(void); + void setOnTimer(const uint16_t nr_of_mins); + uint16_t getOnTimer(void); + void setOffTimerEnabled(const bool on); + bool getOffTimerEnabled(void); + void setOffTimer(const uint16_t nr_of_mins); + uint16_t getOffTimer(void); + uint64_t getRaw(); + void setRaw(const uint64_t state); + uint8_t convertMode(const stdAc::opmode_t mode); + uint8_t convertFan(const stdAc::fanspeed_t speed); + static stdAc::opmode_t toCommonMode(const uint8_t mode); + static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed); + stdAc::state_t toCommon(void); + String toString(); +#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 + uint64_t remote_state; ///< The state of the IR remote. + uint8_t _saved_temp; ///< The previously user requested temp value. + uint8_t _saved_temp_units; ///< The previously user requested temp units. + void checksum(void); +}; +#endif // IR_DELONGHI_H_ diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Denon.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Denon.cpp similarity index 71% rename from lib/IRremoteESP8266-2.7.5/src/ir_Denon.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Denon.cpp index 6dd4cd839..700fd31cb 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Denon.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Denon.cpp @@ -1,17 +1,22 @@ // Copyright 2016 Massimiliano Pinto // Copyright 2017 David Conran +/// @file +/// @brief Denon support +/// Original Denon support added by https://github.com/csBlueChip +/// Ported over by Massimiliano Pinto +/// @see https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Denon.cpp +/// @see http://assets.denon.com/documentmaster/us/denon%20master%20ir%20hex.xls + +// Supports: +// Brand: Denon, Model: AVR-3801 A/V Receiver (probably) #include #include "IRrecv.h" #include "IRsend.h" #include "IRutils.h" -// Original Denon support added by https://github.com/csBlueChip -// Ported over by Massimiliano Pinto // Constants -// Ref: -// https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Denon.cpp const uint16_t kDenonTick = 263; const uint16_t kDenonHdrMarkTicks = 1; const uint16_t kDenonHdrMark = kDenonHdrMarkTicks * kDenonTick; @@ -33,21 +38,13 @@ const uint32_t kDenonMinGap = kDenonMinGapTicks * kDenonTick; const uint64_t kDenonManufacturer = 0x2A4CULL; #if SEND_DENON -// Send a Denon message -// -// Args: -// data: Contents of the message to be sent. -// nbits: Nr. of bits of data to be sent. Typically kDenonBits. -// repeat: Nr. of additional times the message is to be sent. -// -// Status: STABLE / Should be working. -// -// Notes: -// Some Denon devices use a Kaseikyo/Panasonic 48-bit format -// Others use the Sharp protocol. -// Ref: -// https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Denon.cpp -// http://assets.denon.com/documentmaster/us/denon%20master%20ir%20hex.xls +/// Send a Denon formatted message. +/// Status: STABLE / Should be working. +/// @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. +/// @note Some Denon devices use a Kaseikyo/Panasonic 48-bit format +/// Others use the Sharp protocol. void IRsend::sendDenon(uint64_t data, uint16_t nbits, uint16_t repeat) { if (nbits >= kPanasonicBits) // Is this really Panasonic? sendPanasonic64(data, nbits, repeat); @@ -60,21 +57,16 @@ void IRsend::sendDenon(uint64_t data, uint16_t nbits, uint16_t repeat) { #endif #if DECODE_DENON -// Decode a Denon message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Expected nr. of data bits. (Typically kDenonBits) -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Should work fine. -// -// Ref: -// https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Denon.cpp +/// Decode the supplied Delonghi A/C message. +/// Status: STABLE / Should work fine. +/// @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. +/// @see https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Denon.cpp bool IRrecv::decodeDenon(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { // Compliance diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Dish.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Dish.cpp similarity index 56% rename from lib/IRremoteESP8266-2.7.5/src/ir_Dish.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Dish.cpp index 291201ed6..94f5450b8 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Dish.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Dish.cpp @@ -1,20 +1,21 @@ // Copyright Todd Treece // Copyright 2017 David Conran +/// @file +/// @brief DISH Network protocol support +/// DISH support originally by Todd Treece +/// @see http://unionbridge.org/design/ircommand +/// @see https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Dish.cpp +/// @see http://www.hifi-remote.com/wiki/index.php?title=Dish + +// Supports: +// Brand: DISH NETWORK, Model: echostar 301 #include "IRrecv.h" #include "IRsend.h" #include "IRutils.h" -// DISH support originally by Todd Treece -// http://unionbridge.org/design/ircommand - -// Supports: -// Brand: DISH NETWORK, Model: echostar 301 // Constants -// Ref: -// https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Dish.cpp -// http://www.hifi-remote.com/wiki/index.php?title=Dish const uint16_t kDishTick = 100; const uint16_t kDishHdrMarkTicks = 4; const uint16_t kDishHdrMark = kDishHdrMarkTicks * kDishTick; @@ -30,27 +31,20 @@ const uint16_t kDishRptSpaceTicks = kDishHdrSpaceTicks; const uint16_t kDishRptSpace = kDishRptSpaceTicks * kDishTick; #if SEND_DISH -// Send an IR command to a DISH NETWORK device. -// -// Args: -// data: The contents of the command you want to send. -// nbits: The bit size of the command being sent. -// repeat: The number of times you want the command to be repeated. -// -// Status: STABLE / Working. -// -// Note: -// Dishplayer is a different protocol. -// Typically a DISH device needs to get a command a total of at least 4 -// times to accept it. e.g. repeat=3 -// -// Here is the LIRC file I found that seems to match the remote codes from the -// oscilloscope: -// DISH NETWORK (echostar 301): -// http://lirc.sourceforge.net/remotes/echostar/301_501_3100_5100_58xx_59xx -// -// Ref: -// http://www.hifi-remote.com/wiki/index.php?title=Dish +/// Send a DISH NETWORK formatted message. +/// Status: STABLE / Working. +/// @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. +/// @note Dishplayer is a different protocol. +/// Typically a DISH device needs to get a command a total of at least 4 +/// times to accept it. e.g. repeat=3 +/// +/// Here is the LIRC file I found that seems to match the remote codes from the +/// oscilloscope: +/// DISH NETWORK (echostar 301): +/// @see http://lirc.sourceforge.net/remotes/echostar/301_501_3100_5100_58xx_59xx +/// @see http://www.hifi-remote.com/wiki/index.php?title=Dish void IRsend::sendDISH(uint64_t data, uint16_t nbits, uint16_t repeat) { enableIROut(57600); // Set modulation freq. to 57.6kHz. // Header is only ever sent once. @@ -65,27 +59,21 @@ void IRsend::sendDISH(uint64_t data, uint16_t nbits, uint16_t repeat) { #endif #if DECODE_DISH -// Decode the supplied DISH NETWORK message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits to expect in the data portion. Typically kDishBits. -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: ALPHA (untested and unconfirmed.) -// -// Note: -// Dishplayer is a different protocol. -// Typically a DISH device needs to get a command a total of at least 4 -// times to accept it. -// Ref: -// http://www.hifi-remote.com/wiki/index.php?title=Dish -// http://lirc.sourceforge.net/remotes/echostar/301_501_3100_5100_58xx_59xx -// https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Dish.cpp +/// Decode the supplied DISH NETWORK message. +/// Status: ALPHA (untested and unconfirmed.) +/// @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. +/// @note Dishplayer is a different protocol. +/// Typically a DISH device needs to get a command a total of at least 4 +/// times to accept it. +/// @see http://www.hifi-remote.com/wiki/index.php?title=Dish +/// @see http://lirc.sourceforge.net/remotes/echostar/301_501_3100_5100_58xx_59xx +/// @see https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Dish.cpp bool IRrecv::decodeDISH(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (strict && nbits != kDishBits) return false; // Not strictly compliant. diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Doshisha.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Doshisha.cpp new file mode 100644 index 000000000..0a5fadedb --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Doshisha.cpp @@ -0,0 +1,124 @@ +// Copyright 2020 Christian (nikize) +/// @file +/// @brief Doshisha protocol support +/// @see https://www.doshisha-led.com/ + +// Supports: +// Brand: Doshisha, Model: CZ-S32D LED Light +// Brand: Doshisha, Model: CZ-S38D LED Light +// Brand: Doshisha, Model: CZ-S50D LED Light +// Brand: Doshisha, Model: RCZ01 remote + +#include "IRrecv.h" +#include "IRsend.h" +#include "IRutils.h" + + +const uint16_t kDoshishaHdrMark = 3412; +const uint16_t kDoshishaHdrSpace = 1722; +const uint16_t kDoshishaBitMark = 420; +const uint16_t kDoshishaOneSpace = 1310; +const uint16_t kDoshishaZeroSpace = 452; + +// basic structure of bits, and mask +const uint64_t kRcz01SignatureMask = 0xffffffff00; +const uint64_t kRcz01Signature = 0x800B304800; +const uint8_t kRcz01CommandMask = 0xFE; +const uint8_t kRcz01ChannelMask = 0x01; + +// Known commands - Here for documentation rather than actual usage +const uint8_t kRcz01CommandSwitchChannel = 0xD2; +const uint8_t kRcz01CommandTimmer60 = 0x52; +const uint8_t kRcz01CommandTimmer30 = 0x92; +const uint8_t kRcz01CommandOff = 0xA0; + +const uint8_t kRcz01CommandLevelDown = 0x2C; +const uint8_t kRcz01CommandLevelUp = 0xCC; +// below are the only ones that turns it on +const uint8_t kRcz01CommandLevel1 = 0xA4; +const uint8_t kRcz01CommandLevel2 = 0x24; +const uint8_t kRcz01CommandLevel3 = 0xC4; +const uint8_t kRcz01CommandLevel4 = 0xD0; + +const uint8_t kRcz01CommandOn = 0xC0; +const uint8_t kRcz01CommandNightLight = 0xC8; +// end Known commands + +#if SEND_DOSHISHA +/// Send a Doshisha formatted message. +/// Status: STABLE / Works on 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::sendDoshisha(const uint64_t data, const uint16_t nbits, + const uint16_t repeat) { + sendGeneric(kDoshishaHdrMark, kDoshishaHdrSpace, + kDoshishaBitMark, kDoshishaOneSpace, + kDoshishaBitMark, kDoshishaZeroSpace, + kDoshishaBitMark, kDefaultMessageGap, + data, nbits, 38, true, repeat, kDutyDefault); +} + +/// Encode Doshisha combining constant values with command and channel. +/// Status: STABLE / Working. +/// @param[in] command The command code to be sent. +/// @param[in] channel The one bit channel 0 for CH1 and 1 for CH2 +/// @return The corresponding Doshisha code. +uint64_t IRsend::encodeDoshisha(const uint8_t command, const uint8_t channel) { + uint64_t data = kRcz01Signature | + (command & kRcz01CommandMask) | + (channel & kRcz01ChannelMask); + return data; +} +#endif // SEND_DOSHISHA + +#if DECODE_DOSHISHA +/// Decode the supplied Doshisha message. +/// Status: STABLE / Works on real device. +/// @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::decodeDoshisha(decode_results *results, uint16_t offset, + const uint16_t nbits, const bool strict) { + if (results->rawlen < 2 * nbits + kHeader + kFooter - 1 + offset) + return false; // Can't possibly be a valid message. + if (strict && nbits != kDoshishaBits) + return false; + + uint64_t data = 0; + // Match Header + Data + if (!matchGeneric(results->rawbuf + offset, &data, + results->rawlen - offset, nbits, + kDoshishaHdrMark, kDoshishaHdrSpace, + kDoshishaBitMark, kDoshishaOneSpace, + kDoshishaBitMark, kDoshishaZeroSpace, + kDoshishaBitMark, 0, + true, kTolerance, kMarkExcess, true)) return false; + + // e.g. data = 0x800B3048C0, nbits = 40 + + // RCZ01 remote commands starts with a lead bit set + if ((data & kRcz01SignatureMask) != kRcz01Signature) { + DPRINT(" decodeDoshisha data "); + DPRINT(uint64ToString(data, 16)); + DPRINT(" masked "); + DPRINT(uint64ToString(data & kRcz01SignatureMask, 16)); + DPRINT(" not matching "); + DPRINT(uint64ToString(kRcz01Signature, 16)); + DPRINTLN(" ."); + return false; // expected lead bits not matching + } + + // Success + results->decode_type = decode_type_t::DOSHISHA; + results->bits = nbits; + results->value = data; + results->command = data & kRcz01CommandMask; + results->address = data & kRcz01ChannelMask; + return true; +} +#endif // DECODE_DOSHISHA diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Electra.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Electra.cpp similarity index 65% rename from lib/IRremoteESP8266-2.7.5/src/ir_Electra.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Electra.cpp index 16c753f35..0008a79a4 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Electra.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Electra.cpp @@ -1,4 +1,10 @@ // Copyright 2018, 2019 David Conran +/// @file +/// @brief Support for Electra A/C protocols. +/// @see https://github.com/ToniA/arduino-heatpumpir/blob/master/AUXHeatpumpIR.cpp +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/527 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/642 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/778 #include "ir_Electra.h" #include @@ -8,15 +14,6 @@ #include "IRtext.h" #include "IRutils.h" -// Electra A/C added by crankyoldgit -// - -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/527 -// https://github.com/crankyoldgit/IRremoteESP8266/issues/642 -// https://github.com/crankyoldgit/IRremoteESP8266/issues/778 -// https://github.com/ToniA/arduino-heatpumpir/blob/master/AUXHeatpumpIR.cpp - // Constants const uint16_t kElectraAcHdrMark = 9166; const uint16_t kElectraAcBitMark = 646; @@ -35,15 +32,12 @@ using irutils::setBit; using irutils::setBits; #if SEND_ELECTRA_AC -// Send a Electra message -// -// Args: -// data: Contents of the message to be sent. (Guessing MSBF order) -// nbits: Nr. of bits of data to be sent. Typically kElectraAcBits. -// repeat: Nr. of additional times the message is to be sent. -// -// Status: Alpha / Needs testing against a real device. -// +/// Send a Electra A/C formatted message. +/// Status: Alpha / Needs testing against a real device. +/// @param[in] data The message to be sent. +/// @note Guessing MSBF order. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendElectraAC(const uint8_t data[], const uint16_t nbytes, const uint16_t repeat) { for (uint16_t r = 0; r <= repeat; r++) @@ -56,13 +50,17 @@ void IRsend::sendElectraAC(const uint8_t data[], const uint16_t nbytes, } #endif - +/// 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? IRElectraAc::IRElectraAc(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { this->stateReset(); } +/// Reset the internal state to a fixed known good state. void IRElectraAc::stateReset(void) { for (uint8_t i = 1; i < kElectraAcStateLength - 2; i++) remote_state[i] = 0; remote_state[0] = 0xC3; @@ -70,54 +68,78 @@ void IRElectraAc::stateReset(void) { // [12] is the checksum. } +/// Set up hardware to be able to send a message. void IRElectraAc::begin(void) { _irsend.begin(); } +/// Calculate the checksum for a given state. +/// @param[in] state The value to calc the checksum of. +/// @param[in] length The length of the state array. +/// @return The calculated checksum stored in a uint_8. uint8_t IRElectraAc::calcChecksum(const uint8_t state[], - const uint16_t length) { + const uint16_t length) { if (length == 0) return state[0]; return sumBytes(state, length - 1); } +/// Verify the checksum is valid for a given state. +/// @param[in] state The state to verify the checksum of. +/// @param[in] length The length of the state array. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRElectraAc::validChecksum(const uint8_t state[], const uint16_t length) { if (length < 2) return true; // No checksum to compare with. Assume okay. return (state[length - 1] == calcChecksum(state, length)); } -// Update the checksum for the internal state. +/// Calculate and set the checksum values for the internal state. +/// @param[in] length The length of the state array. void IRElectraAc::checksum(uint16_t length) { if (length < 2) return; remote_state[length - 1] = calcChecksum(remote_state, length); } #if SEND_ELECTRA_AC +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRElectraAc::send(const uint16_t repeat) { - this->checksum(); - _irsend.sendElectraAC(remote_state, kElectraAcStateLength, repeat); + _irsend.sendElectraAC(getRaw(), kElectraAcStateLength, repeat); } #endif // SEND_ELECTRA_AC +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t *IRElectraAc::getRaw(void) { this->checksum(); return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. +/// @param[in] length The length of the code array. void IRElectraAc::setRaw(const uint8_t new_code[], const uint16_t length) { memcpy(remote_state, new_code, std::min(length, kElectraAcStateLength)); } +/// Change the power setting to On. void IRElectraAc::on(void) { this->setPower(true); } +/// Change the power setting to Off. void IRElectraAc::off(void) { this->setPower(false); } +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRElectraAc::setPower(const bool on) { setBit(&remote_state[9], kElectraAcPowerOffset, on); } +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRElectraAc::getPower(void) { return GETBIT8(remote_state[9], kElectraAcPowerOffset); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRElectraAc::setMode(const uint8_t mode) { switch (mode) { case kElectraAcAuto: @@ -133,11 +155,15 @@ void IRElectraAc::setMode(const uint8_t mode) { } } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRElectraAc::getMode(void) { return GETBITS8(remote_state[6], kElectraAcModeOffset, kModeBitsSize); } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRElectraAc::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kElectraAcCool; @@ -148,7 +174,9 @@ uint8_t IRElectraAc::convertMode(const stdAc::opmode_t mode) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRElectraAc::toCommonMode(const uint8_t mode) { switch (mode) { case kElectraAcCool: return stdAc::opmode_t::kCool; @@ -159,20 +187,24 @@ stdAc::opmode_t IRElectraAc::toCommonMode(const uint8_t mode) { } } -// Set the temp. in deg C +/// Set the temperature. +/// @param[in] temp The temperature in degrees celsius. void IRElectraAc::setTemp(const uint8_t temp) { uint8_t newtemp = std::max(kElectraAcMinTemp, temp); newtemp = std::min(kElectraAcMaxTemp, newtemp) - kElectraAcTempDelta; setBits(&remote_state[1], kElectraAcTempOffset, kElectraAcTempSize, newtemp); } -// Return the set temp. in deg C +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRElectraAc::getTemp(void) { return GETBITS8(remote_state[1], kElectraAcTempOffset, kElectraAcTempSize) + kElectraAcTempDelta; } -// Set the speed of the fan, 0-3, 0 is auto, 1-3 is the speed +/// Set the speed of the fan. +/// @param[in] speed The desired setting. +/// @note 0 is auto, 1-3 is the speed void IRElectraAc::setFan(const uint8_t speed) { switch (speed) { case kElectraAcFanAuto: @@ -187,11 +219,15 @@ void IRElectraAc::setFan(const uint8_t speed) { } } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRElectraAc::getFan(void) { return GETBITS8(remote_state[4], kElectraAcFanOffset, kElectraAcFanSize); } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRElectraAc::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: @@ -203,7 +239,9 @@ uint8_t IRElectraAc::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRElectraAc::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kElectraAcFanHigh: return stdAc::fanspeed_t::kMax; @@ -213,51 +251,73 @@ stdAc::fanspeed_t IRElectraAc::toCommonFanSpeed(const uint8_t speed) { } } +/// Set the Vertical Swing mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRElectraAc::setSwingV(const bool on) { setBits(&remote_state[1], kElectraAcSwingVOffset, kElectraAcSwingSize, on ? kElectraAcSwingOn : kElectraAcSwingOff); } +/// Get the Vertical Swing mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRElectraAc::getSwingV(void) { return !GETBITS8(remote_state[1], kElectraAcSwingVOffset, kElectraAcSwingSize); } +/// Set the Horizontal Swing mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRElectraAc::setSwingH(const bool on) { setBits(&remote_state[2], kElectraAcSwingHOffset, kElectraAcSwingSize, on ? kElectraAcSwingOn : kElectraAcSwingOff); } +/// Get the Horizontal Swing mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRElectraAc::getSwingH(void) { return !GETBITS8(remote_state[2], kElectraAcSwingHOffset, kElectraAcSwingSize); } +/// Set the Light (LED) Toggle mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRElectraAc::setLightToggle(const bool on) { remote_state[11] = on ? kElectraAcLightToggleOn : kElectraAcLightToggleOff; } +/// Get the Light (LED) Toggle mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRElectraAc::getLightToggle(void) { return (remote_state[11] & kElectraAcLightToggleMask) == kElectraAcLightToggleMask; } +/// Set the Clean mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRElectraAc::setClean(const bool on) { setBit(&remote_state[9], kElectraAcCleanOffset, on); } +/// Get the Clean mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRElectraAc::getClean(void) { return GETBIT8(remote_state[9], kElectraAcCleanOffset); } +/// Set the Turbo mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRElectraAc::setTurbo(const bool on) { setBit(&remote_state[5], kElectraAcTurboOffset, on); } +/// Get the Turbo mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRElectraAc::getTurbo(void) { return GETBIT8(remote_state[5], kElectraAcTurboOffset); } -// Convert the A/C state to it's common equivalent. + +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRElectraAc::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::ELECTRA_AC; @@ -284,7 +344,8 @@ stdAc::state_t IRElectraAc::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRElectraAc::toString(void) { String result = ""; result.reserve(130); // Reserve some heap for the string to reduce fragging. @@ -304,19 +365,15 @@ String IRElectraAc::toString(void) { } #if DECODE_ELECTRA_AC -// Decode the supplied Electra A/C message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kElectraAcBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Known working. -// +/// Decode the supplied Electra A/C message. +/// Status: STABLE / Known 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::decodeElectraAC(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Electra.h b/lib/IRremoteESP8266-2.7.8/src/ir_Electra.h similarity index 83% rename from lib/IRremoteESP8266-2.7.5/src/ir_Electra.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Electra.h index 2d5fe09f5..86f082a76 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Electra.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Electra.h @@ -1,6 +1,13 @@ -// Electra A/C -// // Copyright 2019 David Conran +/// @file +/// @brief Support for Electra A/C protocols. +/// @see https://github.com/ToniA/arduino-heatpumpir/blob/master/AUXHeatpumpIR.cpp + +// Supports: +// Brand: AUX, Model: KFR-35GW/BpNFW=3 A/C +// Brand: AUX, Model: YKR-T/011 remote +// Brand: Electra, Model: Classic INV 17 / AXW12DCS A/C +// Brand: Electra, Model: YKR-M/003E remote #ifndef IR_ELECTRA_H_ #define IR_ELECTRA_H_ @@ -16,15 +23,6 @@ #include "IRsend_test.h" #endif -// Supports: -// Brand: AUX, Model: KFR-35GW/BpNFW=3 A/C -// Brand: AUX, Model: YKR-T/011 remote -// Brand: Electra, Model: Classic INV 17 / AXW12DCS A/C -// Brand: Electra, Model: YKR-M/003E remote - -// Ref: -// https://github.com/ToniA/arduino-heatpumpir/blob/master/AUXHeatpumpIR.cpp - // Constants // state[1] // Temp 0b11111000 @@ -78,15 +76,19 @@ const uint8_t kElectraAcLightToggleOff = 0x08; // Classes +/// Class for handling detailed Electra A/C messages. class IRElectraAc { public: explicit IRElectraAc(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - void stateReset(void); #if SEND_ELECTRA_AC void send(const uint16_t repeat = kElectraAcMinRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + /// 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_ELECTRA_AC void begin(void); void on(void); @@ -125,12 +127,13 @@ class IRElectraAc { #ifndef UNIT_TEST private: - IRsend _irsend; + IRsend _irsend; ///< instance of the IR send class #else - IRsendTest _irsend; + /// @cond IGNORE + IRsendTest _irsend; ///< instance of the testing IR send class + /// @endcond #endif - // The state of the IR remote in IR code form. - uint8_t remote_state[kElectraAcStateLength]; + uint8_t remote_state[kElectraAcStateLength]; ///< The state of the IR remote void checksum(const uint16_t length = kElectraAcStateLength); }; #endif // IR_ELECTRA_H_ diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Epson.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Epson.cpp similarity index 70% rename from lib/IRremoteESP8266-2.7.5/src/ir_Epson.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Epson.cpp index 40973a947..4f92704bc 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Epson.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Epson.cpp @@ -1,6 +1,11 @@ // Copyright 2020 David Conran +/// @file +/// @brief Support for Epson protocols. +/// Epson is an NEC-like protocol, except it doesn't use the NEC style repeat. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1034 -// Epson is an NEC-like protocol, except it doesn't use the NEC style repeat. +// Supports: +// Brand: Epson, Model: EN-TW9100W Projector #define __STDC_LIMIT_MACROS #include @@ -11,17 +16,11 @@ #include "ir_NEC.h" #if SEND_EPSON -// Send an Epson formatted message. -// -// Args: -// data: The message to be sent. -// nbits: The number of bits of the message to be sent. Typically kEpsonBits. -// repeat: The number of times the command is to be repeated. -// -// Status: Beta / Probably works. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/1034 +/// Send an Epson formatted message. +/// Status: Beta / Probably works. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of nbits of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendEpson(uint64_t data, uint16_t nbits, uint16_t repeat) { sendGeneric(kNecHdrMark, kNecHdrSpace, kNecBitMark, kNecOneSpace, kNecBitMark, kNecZeroSpace, kNecBitMark, kNecMinGap, kNecMinCommandLength, @@ -31,27 +30,18 @@ void IRsend::sendEpson(uint64_t data, uint16_t nbits, uint16_t repeat) { #endif // SEND_EPSON #if DECODE_EPSON -// Decode the supplied Epson message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kNECBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: Beta / Probably works. -// -// Notes: -// Experimental data indicates there are at least three -// messages (first + 2 repeats). We only require the first + a single repeat -// to match. This helps us distinguish it from NEC messages which are near -// identical. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/1034 +/// Decode the supplied Epson message. +/// Status: Beta / Probably works. +/// @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. +/// @note Experimental data indicates there are at least three messages +/// (first + 2 repeats). We only require the first + a single repeat to match. +/// This helps us distinguish it from NEC messages which are near identical. bool IRrecv::decodeEpson(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { const uint8_t kEpsonMinMesgsForDecode = 2; diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Fujitsu.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Fujitsu.cpp similarity index 79% rename from lib/IRremoteESP8266-2.7.5/src/ir_Fujitsu.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Fujitsu.cpp index 583a441ba..a4bd90fa8 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Fujitsu.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Fujitsu.cpp @@ -1,5 +1,10 @@ // Copyright 2017 Jonny Graham // Copyright 2017-2019 David Conran + +/// @file +/// @brief Support for Fujitsu A/C protocols. +/// Fujitsu A/C support added by Jonny Graham & David Conran + #include "ir_Fujitsu.h" #include #ifndef ARDUINO @@ -9,16 +14,6 @@ #include "IRtext.h" #include "IRutils.h" -// Fujitsu A/C support added by Jonny Graham & David Conran - -// Equipment it seems compatible with: -// * Fujitsu ASYG30LFCA with remote AR-RAH2E -// * Fujitsu AST9RSGCW with remote AR-DB1 -// * Fujitsu ASYG7LMCA with remote AR-REB1E -// * Fujitsu AR-RAE1E remote. -// * Fujitsu General with remote AR-JW2 -// * - // Ref: // These values are based on averages of measurements const uint16_t kFujitsuAcHdrMark = 3324; @@ -39,20 +34,16 @@ using irutils::setBit; using irutils::setBits; #if SEND_FUJITSU_AC -// Send a Fujitsu A/C message. -// -// Args: -// data: An array of bytes containing the IR command. -// nbytes: Nr. of bytes of data in the array. Typically one of: -// kFujitsuAcStateLength -// kFujitsuAcStateLength - 1 -// kFujitsuAcStateLengthShort -// kFujitsuAcStateLengthShort - 1 -// repeat: Nr. of times the message is to be repeated. -// (Default = kFujitsuAcMinRepeat). -// -// Status: STABLE / Known Good. -// +/// Send a Fujitsu A/C formatted message. +/// Status: STABLE / Known Good. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// Typically one of: +/// kFujitsuAcStateLength, +/// kFujitsuAcStateLength - 1, +/// kFujitsuAcStateLengthShort, +/// kFujitsuAcStateLengthShort - 1 +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendFujitsuAC(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { sendGeneric(kFujitsuAcHdrMark, kFujitsuAcHdrSpace, kFujitsuAcBitMark, @@ -64,7 +55,11 @@ void IRsend::sendFujitsuAC(const unsigned char data[], const uint16_t nbytes, // Code to emulate Fujitsu A/C IR remote control unit. -// Initialise the object. +/// Class Constructor +/// @param[in] pin GPIO to be used when sending. +/// @param[in] model The enum for the model of A/C to be emulated. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? IRFujitsuAC::IRFujitsuAC(const uint16_t pin, const fujitsu_ac_remote_model_t model, const bool inverted, const bool use_modulation) @@ -73,6 +68,8 @@ IRFujitsuAC::IRFujitsuAC(const uint16_t pin, this->stateReset(); } +/// Set the currently emulated model of the A/C. +/// @param[in] model An enum representing the model to support/emulate. void IRFujitsuAC::setModel(const fujitsu_ac_remote_model_t model) { _model = model; switch (model) { @@ -90,9 +87,11 @@ void IRFujitsuAC::setModel(const fujitsu_ac_remote_model_t model) { } } +/// Get the currently emulated/detected model of the A/C. +/// @return The enum representing the model of A/C. fujitsu_ac_remote_model_t IRFujitsuAC::getModel(void) { return _model; } -// Reset the state of the remote to a known good state/sequence. +/// Reset the state of the remote to a known good state/sequence. void IRFujitsuAC::stateReset(void) { _temp = 24; _fanSpeed = kFujitsuAcFanHigh; @@ -104,17 +103,19 @@ void IRFujitsuAC::stateReset(void) { this->buildState(); } -// Configure the pin for output. +/// Set up hardware to be able to send a message. void IRFujitsuAC::begin(void) { _irsend.begin(); } #if SEND_FUJITSU_AC -// Send the current desired state to the IR LED. +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRFujitsuAC::send(const uint16_t repeat) { this->buildState(); _irsend.sendFujitsuAC(remote_state, getStateLength(), repeat); } #endif // SEND_FUJITSU_AC +/// (Re)Build the state from the currently configured settings. void IRFujitsuAC::buildState(void) { remote_state[0] = 0x14; remote_state[1] = 0x63; @@ -208,6 +209,8 @@ void IRFujitsuAC::buildState(void) { } } +/// Get the length (size) of the state code for the current configuration. +/// @return The length of the state array required for this config. uint8_t IRFujitsuAC::getStateLength(void) { this->buildState(); // Force an update of the internal state. if (((_model == fujitsu_ac_remote_model_t::ARRAH2E || @@ -221,12 +224,15 @@ uint8_t IRFujitsuAC::getStateLength(void) { return _state_length; } -// Return a pointer to the internal state date of the remote. +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t* IRFujitsuAC::getRaw(void) { this->buildState(); return remote_state; } +/// Build the internal state/config from the current (raw) A/C message. +/// @param[in] length Size of the current/used (raw) A/C message array. void IRFujitsuAC::buildFromState(const uint16_t length) { switch (length) { case kFujitsuAcStateLength - 1: @@ -285,6 +291,10 @@ void IRFujitsuAC::buildFromState(const uint16_t length) { _outsideQuiet = this->getOutsideQuiet(true); } +/// Set the internal state from a valid code for this protocol. +/// @param[in] newState A valid code for this protocol. +/// @param[in] length Size of the newState array. +/// @return true, if successful; Otherwise false. (i.e. size check) bool IRFujitsuAC::setRaw(const uint8_t newState[], const uint16_t length) { if (length > kFujitsuAcStateLength) return false; for (uint16_t i = 0; i < kFujitsuAcStateLength; i++) { @@ -297,8 +307,11 @@ bool IRFujitsuAC::setRaw(const uint8_t newState[], const uint16_t length) { return true; } +/// Request the A/C to step the Horizontal Swing. void IRFujitsuAC::stepHoriz(void) { this->setCmd(kFujitsuAcCmdStepHoriz); } +/// Request the A/C to toggle the Horizontal Swing mode. +/// @param[in] update Do we need to update the general swing config? void IRFujitsuAC::toggleSwingHoriz(const bool update) { // Toggle the current setting. if (update) this->setSwing(this->getSwing() ^ kFujitsuAcSwingHoriz); @@ -306,8 +319,11 @@ void IRFujitsuAC::toggleSwingHoriz(const bool update) { this->setCmd(kFujitsuAcCmdToggleSwingHoriz); } +/// Request the A/C to step the Vertical Swing. void IRFujitsuAC::stepVert(void) { this->setCmd(kFujitsuAcCmdStepVert); } +/// Request the A/C to toggle the Vertical Swing mode. +/// @param[in] update Do we need to update the general swing config? void IRFujitsuAC::toggleSwingVert(const bool update) { // Toggle the current setting. if (update) this->setSwing(this->getSwing() ^ kFujitsuAcSwingVert); @@ -315,7 +331,8 @@ void IRFujitsuAC::toggleSwingVert(const bool update) { this->setCmd(kFujitsuAcCmdToggleSwingVert); } -// Set the requested command of the A/C. +/// Set the requested (special) command part for the A/C message. +/// @param[in] cmd The special command code. void IRFujitsuAC::setCmd(const uint8_t cmd) { switch (cmd) { case kFujitsuAcCmdTurnOff: @@ -353,39 +370,40 @@ void IRFujitsuAC::setCmd(const uint8_t cmd) { } } -// Get the special command part of the message. -// Args: -// raw: Do we need to get it from first principles from the raw data? -// Returns: -// A uint8_t containing the contents of the special command byte. +/// Set the requested (special) command part for the A/C message. +/// @param[in] raw Do we need to get it from first principles from the raw data? +/// @return The special command code. uint8_t IRFujitsuAC::getCmd(const bool raw) { if (raw) return remote_state[5]; return _cmd; } -// Set the requested power state of the A/C. +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRFujitsuAC::setPower(const bool on) { this->setCmd(on ? kFujitsuAcCmdTurnOn : kFujitsuAcCmdTurnOff); } -// Set the requested power state of the A/C to off. +/// Set the requested power state of the A/C to off. void IRFujitsuAC::off(void) { this->setPower(false); } -// Set the requested power state of the A/C to on. +/// Set the requested power state of the A/C to on. void IRFujitsuAC::on(void) { this->setPower(true); } +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRFujitsuAC::getPower(void) { return _cmd != kFujitsuAcCmdTurnOff; } +/// Set the Outside Quiet mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRFujitsuAC::setOutsideQuiet(const bool on) { _outsideQuiet = on; this->setCmd(kFujitsuAcCmdStayOn); // No special command involved. } -// Get the status of the Outside Quiet setting. -// Args: -// raw: Do we get the result from base data? -// Returns: -// A boolean for if it is set or not. +/// Get the Outside Quiet mode status of the A/C. +/// @param[in] raw Do we get the result from base data? +/// @return true, the setting is on. false, the setting is off. bool IRFujitsuAC::getOutsideQuiet(const bool raw) { if (_state_length == kFujitsuAcStateLength && raw) { _outsideQuiet = GETBIT8(remote_state[14], kFujitsuAcOutsideQuietOffset); @@ -395,16 +413,20 @@ bool IRFujitsuAC::getOutsideQuiet(const bool raw) { return _outsideQuiet; } -// Set the temp. in deg C +/// Set the temperature. +/// @param[in] temp The temperature in degrees celsius. void IRFujitsuAC::setTemp(const uint8_t temp) { _temp = std::max((uint8_t)kFujitsuAcMinTemp, temp); _temp = std::min((uint8_t)kFujitsuAcMaxTemp, _temp); this->setCmd(kFujitsuAcCmdStayOn); // No special command involved. } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRFujitsuAC::getTemp(void) { return _temp; } -// Set the speed of the fan +/// Set the speed of the fan. +/// @param[in] fanSpeed The desired setting. void IRFujitsuAC::setFanSpeed(const uint8_t fanSpeed) { if (fanSpeed > kFujitsuAcFanQuiet) _fanSpeed = kFujitsuAcFanHigh; // Set the fan to maximum if out of range. @@ -412,9 +434,13 @@ void IRFujitsuAC::setFanSpeed(const uint8_t fanSpeed) { _fanSpeed = fanSpeed; this->setCmd(kFujitsuAcCmdStayOn); // No special command involved. } + +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRFujitsuAC::getFanSpeed(void) { return _fanSpeed; } -// Set the requested climate operation mode of the a/c unit. +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRFujitsuAC::setMode(const uint8_t mode) { if (mode > kFujitsuAcModeHeat) _mode = kFujitsuAcModeHeat; // Set the mode to maximum if out of range. @@ -423,9 +449,14 @@ void IRFujitsuAC::setMode(const uint8_t mode) { this->setCmd(kFujitsuAcCmdStayOn); // No special command involved. } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRFujitsuAC::getMode(void) { return _mode; } -// Set the requested swing operation mode of the a/c unit. +/// Set the requested swing operation mode of the A/C unit. +/// @param[in] swingMode The swingMode code for the A/C. +/// Vertical, Horizon, or Both. See constants for details. +/// @note Not all models support all possible swing modes. void IRFujitsuAC::setSwing(const uint8_t swingMode) { _swingMode = swingMode; switch (_model) { @@ -446,22 +477,25 @@ void IRFujitsuAC::setSwing(const uint8_t swingMode) { this->setCmd(kFujitsuAcCmdStayOn); // No special command involved. } -// Get what the swing part of the message should be. -// Args: -// raw: Do we need to get it from first principles from the raw data? -// Returns: -// A uint8_t containing the contents of the swing state. +/// Get the requested swing operation mode of the A/C unit. +/// @param[in] raw Do we need to get it from first principles from the raw data? +/// @return The contents of the swing state/mode. uint8_t IRFujitsuAC::getSwing(const bool raw) { if (raw) _swingMode = GETBITS8(remote_state[10], kHighNibble, kFujitsuAcSwingSize); return _swingMode; } +/// Set the Clean mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRFujitsuAC::setClean(const bool on) { _clean = on; this->setCmd(kFujitsuAcCmdStayOn); // No special command involved. } +/// Get the Clean mode status of the A/C. +/// @param[in] raw Do we get the result from base data? +/// @return true, the setting is on. false, the setting is off. bool IRFujitsuAC::getClean(const bool raw) { if (raw) { return GETBIT8(remote_state[9], kFujitsuAcCleanOffset); @@ -473,11 +507,16 @@ bool IRFujitsuAC::getClean(const bool raw) { } } +/// Set the Filter mode status of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRFujitsuAC::setFilter(const bool on) { _filter = on; this->setCmd(kFujitsuAcCmdStayOn); // No special command involved. } +/// Get the Filter mode status of the A/C. +/// @param[in] raw Do we get the result from base data? +/// @return true, the setting is on. false, the setting is off. bool IRFujitsuAC::getFilter(const bool raw) { if (raw) { return GETBIT8(remote_state[14], kFujitsuAcFilterOffset); @@ -489,6 +528,10 @@ bool IRFujitsuAC::getFilter(const bool raw) { } } +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length of the state array. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRFujitsuAC::validChecksum(uint8_t state[], const uint16_t length) { uint8_t sum = 0; uint8_t sum_complement = 0; @@ -510,7 +553,9 @@ bool IRFujitsuAC::validChecksum(uint8_t state[], const uint16_t length) { return checksum == (uint8_t)(sum_complement - sum); // Does it match? } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRFujitsuAC::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kFujitsuAcModeCool; @@ -521,7 +566,9 @@ uint8_t IRFujitsuAC::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRFujitsuAC::convertFan(stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: return kFujitsuAcFanQuiet; @@ -533,7 +580,9 @@ uint8_t IRFujitsuAC::convertFan(stdAc::fanspeed_t speed) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRFujitsuAC::toCommonMode(const uint8_t mode) { switch (mode) { case kFujitsuAcModeCool: return stdAc::opmode_t::kCool; @@ -544,7 +593,9 @@ stdAc::opmode_t IRFujitsuAC::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRFujitsuAC::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kFujitsuAcFanHigh: return stdAc::fanspeed_t::kMax; @@ -555,7 +606,8 @@ stdAc::fanspeed_t IRFujitsuAC::toCommonFanSpeed(const uint8_t speed) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRFujitsuAC::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::FUJITSU_AC; @@ -597,7 +649,8 @@ stdAc::state_t IRFujitsuAC::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRFujitsuAC::toString(void) { String result = ""; result.reserve(100); // Reserve some heap for the string to reduce fragging. @@ -680,21 +733,15 @@ String IRFujitsuAC::toString(void) { } #if DECODE_FUJITSU_AC -// Decode a Fujitsu AC IR message if possible. -// Places successful decode information in the results pointer. -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kFujitsuAcBits. -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Working. -// -// Ref: -// +/// Decode the supplied Fujitsu AC IR message if possible. +/// Status: STABLE / 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::decodeFujitsuAC(decode_results* results, uint16_t offset, const uint16_t nbits, const bool strict) { diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Fujitsu.h b/lib/IRremoteESP8266-2.7.8/src/ir_Fujitsu.h similarity index 86% rename from lib/IRremoteESP8266-2.7.5/src/ir_Fujitsu.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Fujitsu.h index eae0edb8f..0c1069566 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Fujitsu.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Fujitsu.h @@ -1,13 +1,17 @@ // Copyright 2017 Jonny Graham // Copyright 2018-2019 David Conran +/// @file +/// @brief Support for Fujitsu A/C protocols. +/// Fujitsu A/C support added by Jonny Graham + // Supports: // Brand: Fujitsu, Model: AR-RAH2E remote -// Brand: Fujitsu, Model: ASYG30LFCA A/C +// Brand: Fujitsu, Model: ASYG30LFCA A/C (ARRAH2E) // Brand: Fujitsu, Model: AR-DB1 remote -// Brand: Fujitsu, Model: AST9RSGCW A/C +// Brand: Fujitsu, Model: AST9RSGCW A/C (ARDB1) // Brand: Fujitsu, Model: AR-REB1E remote -// Brand: Fujitsu, Model: ASYG7LMCA A/C +// Brand: Fujitsu, Model: ASYG7LMCA A/C (ARREB1E) // Brand: Fujitsu, Model: AR-RAE1E remote // Brand: Fujitsu, Model: AGTV14LAC A/C // Brand: Fujitsu, Model: AR-RAC1E remote @@ -32,7 +36,6 @@ #include "IRsend_test.h" #endif -// FUJITSU A/C support added by Jonny Graham // Constants const uint8_t kFujitsuAcModeAuto = 0x00; @@ -94,20 +97,23 @@ const uint8_t kFujitsuAcFilterOffset = 3; #define FUJITSU_AC_SWING_HORIZ kFujitsuAcSwingHoriz #define FUJITSU_AC_SWING_BOTH kFujitsuAcSwingBoth - +/// Class for handling detailed Fujitsu A/C messages. class IRFujitsuAC { public: explicit IRFujitsuAC(const uint16_t pin, const fujitsu_ac_remote_model_t model = ARRAH2E, const bool inverted = false, const bool use_modulation = true); - void setModel(const fujitsu_ac_remote_model_t model); fujitsu_ac_remote_model_t getModel(void); void stateReset(void); #if SEND_FUJITSU_AC void send(const uint16_t repeat = kFujitsuAcMinRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + /// 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_FUJITSU_AC void begin(void); void stepHoriz(void); @@ -149,11 +155,13 @@ class IRFujitsuAC { #ifndef UNIT_TEST private: - IRsend _irsend; + IRsend _irsend; ///< Instance of the IR send class #else - IRsendTest _irsend; + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond #endif - uint8_t remote_state[kFujitsuAcStateLength]; + uint8_t remote_state[kFujitsuAcStateLength]; ///< The state of the IR remote. uint8_t _temp; uint8_t _fanSpeed; uint8_t _mode; diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_GICable.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_GICable.cpp similarity index 71% rename from lib/IRremoteESP8266-2.7.5/src/ir_GICable.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_GICable.cpp index ef68199cb..7b29d71db 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_GICable.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_GICable.cpp @@ -1,5 +1,12 @@ // Copyright 2018 David Conran -// G.I. Cable + +/// @file +/// @brief G.I. Cable +/// @see https://github.com/cyborg5/IRLib2/blob/master/IRLibProtocols/IRLib_P09_GICable.h +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/447 + +// Supports: +// Brand: G.I. Cable, Model: XRC-200 remote #define __STDC_LIMIT_MACROS #include @@ -8,10 +15,6 @@ #include "IRsend.h" #include "IRutils.h" -// Ref: -// https://github.com/cyborg5/IRLib2/blob/master/IRLibProtocols/IRLib_P09_GICable.h -// https://github.com/crankyoldgit/IRremoteESP8266/issues/447 - // Constants const uint16_t kGicableHdrMark = 9000; const uint16_t kGicableHdrSpace = 4400; @@ -26,17 +29,11 @@ const uint32_t kGicableMinGap = kGicableBits * (kGicableBitMark + kGicableOneSpace) + kGicableBitMark); #if SEND_GICABLE -// Send a raw G.I. Cable formatted message. -// -// Args: -// data: The message to be sent. -// nbits: The number of bits of the message to be sent. -// Typically kGicableBits. -// repeat: The number of times the command is to be repeated. -// -// Status: Alpha / Untested. -// -// Ref: +/// Send a raw G.I. Cable formatted message. +/// Status: Alpha / Untested. +/// @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::sendGICable(uint64_t data, uint16_t nbits, uint16_t repeat) { sendGeneric(kGicableHdrMark, kGicableHdrSpace, kGicableBitMark, kGicableOneSpace, kGicableBitMark, kGicableZeroSpace, @@ -54,18 +51,15 @@ void IRsend::sendGICable(uint64_t data, uint16_t nbits, uint16_t repeat) { #endif // SEND_GICABLE #if DECODE_GICABLE -// Decode the supplied G.I. Cable message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kGicableBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: Alpha / Not tested against a real device. +/// Decode the supplied G.I. Cable message. +/// Status: Alpha / Not tested against a real device. +/// @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::decodeGICable(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (strict && nbits != kGicableBits) diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_GlobalCache.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_GlobalCache.cpp similarity index 65% rename from lib/IRremoteESP8266-2.7.5/src/ir_GlobalCache.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_GlobalCache.cpp index 8c9646970..e8ebac4af 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_GlobalCache.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_GlobalCache.cpp @@ -1,8 +1,13 @@ // Copyright 2016 Hisham Khalifa // Copyright 2017 David Conran -// Global Cache IR format sender originally added by Hisham Khalifa -// (http://www.hishamkhalifa.com) +/// @file +/// @brief Global Cache IR format sender +/// Originally added by Hisham Khalifa (http://www.hishamkhalifa.com) +/// @see https://irdb.globalcache.com/Home/Database + +// Supports: +// Brand: Global Cache, Model: Control Tower IR DB #include #include "IRsend.h" @@ -16,23 +21,17 @@ const uint8_t kGlobalCacheRptStartIndex = kGlobalCacheRptIndex + 1; const uint8_t kGlobalCacheStartIndex = kGlobalCacheRptStartIndex + 1; #if SEND_GLOBALCACHE -// Send a shortened GlobalCache (GC) IRdb/control tower formatted message. -// -// Args: -// buf: An array of uint16_t containing the shortened GlobalCache data. -// len: Nr. of entries in the buf[] array. -// -// Status: STABLE / Known working. -// -// Note: -// Global Cache format without the emitter ID or request ID. -// Starts at the frequency (Hertz), followed by nr. of times to emit (count), -// then the offset for repeats (where a repeat will start from), -// then the rest of entries are the actual IR message as units of periodic -// time. -// e.g. sendir,1:1,1,38000,1,1,9,70,9,30,9,... -> 38000,1,1,9,70,9,30,9,... -// Ref: -// https://irdb.globalcache.com/Home/Database +/// Send a shortened GlobalCache (GC) IRdb/control tower formatted message. +/// Status: STABLE / Known working. +/// @param[in] buf Array of uint16_t containing the shortened GlobalCache data. +/// @param[in] len Nr. of entries in the buf[] array. +/// @note Global Cache format without the emitter ID or request ID. +/// Starts at the frequency (Hertz), followed by nr. of times to emit (count), +/// then the offset for repeats (where a repeat will start from), +/// then the rest of entries are the actual IR message as units of periodic +/// time. +/// e.g. sendir,1:1,1,38000,1,1,9,70,9,30,9,... -> 38000,1,1,9,70,9,30,9,... +/// @see https://irdb.globalcache.com/Home/Database void IRsend::sendGC(uint16_t buf[], uint16_t len) { uint16_t hz = buf[kGlobalCacheFreqIndex]; // GC frequency is in Hz. enableIROut(hz); diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Goodweather.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Goodweather.cpp similarity index 74% rename from lib/IRremoteESP8266-2.7.5/src/ir_Goodweather.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Goodweather.cpp index 97a4a9277..290f90ad8 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Goodweather.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Goodweather.cpp @@ -1,10 +1,8 @@ // Copyright 2019 ribeirodanielf // Copyright 2019 David Conran -// -// Code to emulate Goodweather protocol compatible HVAC devices. -// Should be compatible with: -// * ZH/JT-03 remote control -// +/// @file +/// @brief Support for Goodweather compatible HVAC protocols. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/697 #include "ir_Goodweather.h" #include @@ -27,17 +25,11 @@ using irutils::setBit; using irutils::setBits; #if SEND_GOODWEATHER -// Send a Goodweather message. -// -// Args: -// data: The raw message to be sent. -// nbits: Nr. of bits of data in the message. (Default is kGoodweatherBits) -// repeat: Nr. of times the message is to be repeated. (Default = 0). -// -// Status: BETA / Needs testing on real device. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/697 +/// Send a Goodweather HVAC formatted message. +/// Status: BETA / Needs testing on 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::sendGoodweather(const uint64_t data, const uint16_t nbits, const uint16_t repeat) { if (nbits != kGoodweatherBits) @@ -67,38 +59,57 @@ void IRsend::sendGoodweather(const uint64_t data, const uint16_t nbits, } #endif // SEND_GOODWEATHER +/// 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? IRGoodweatherAc::IRGoodweatherAc(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 IRGoodweatherAc::stateReset(void) { remote = kGoodweatherStateInit; } +/// Set up hardware to be able to send a message. void IRGoodweatherAc::begin(void) { _irsend.begin(); } #if SEND_GOODWEATHER +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRGoodweatherAc::send(const uint16_t repeat) { _irsend.sendGoodweather(remote, kGoodweatherBits, repeat); } #endif // SEND_GOODWEATHER +/// Get a copy of the internal state as a valid code for this protocol. +/// @return A valid code for this protocol based on the current internal state. uint64_t IRGoodweatherAc::getRaw(void) { return remote; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] state A valid code for this protocol. void IRGoodweatherAc::setRaw(const uint64_t state) { remote = state; } +/// Change the power setting to On. void IRGoodweatherAc::on(void) { this->setPower(true); } +/// Change the power setting to Off. void IRGoodweatherAc::off(void) { this->setPower(false); } +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRGoodweatherAc::setPower(const bool on) { this->setCommand(kGoodweatherCmdPower); setBit(&remote, kGoodweatherBitPower, on); } +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRGoodweatherAc::getPower(void) { return GETBIT64(remote, kGoodweatherBitPower); } -// Set the temp. in deg C +/// Set the temperature. +/// @param[in] temp The temperature in degrees celsius. void IRGoodweatherAc::setTemp(const uint8_t temp) { uint8_t new_temp = std::max(kGoodweatherTempMin, temp); new_temp = std::min(kGoodweatherTempMax, new_temp); @@ -108,13 +119,15 @@ void IRGoodweatherAc::setTemp(const uint8_t temp) { new_temp - kGoodweatherTempMin); } -// Return the set temp. in deg C +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRGoodweatherAc::getTemp(void) { return GETBITS64(remote, kGoodweatherBitTemp, kGoodweatherTempSize) + kGoodweatherTempMin; } -// Set the speed of the fan +/// Set the speed of the fan. +/// @param[in] speed The desired setting. void IRGoodweatherAc::setFan(const uint8_t speed) { switch (speed) { case kGoodweatherFanAuto: @@ -129,10 +142,14 @@ void IRGoodweatherAc::setFan(const uint8_t speed) { } } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRGoodweatherAc::getFan() { return GETBITS64(remote, kGoodweatherBitFan, kGoodweatherFanSize); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRGoodweatherAc::setMode(const uint8_t mode) { switch (mode) { case kGoodweatherAuto: @@ -149,37 +166,53 @@ void IRGoodweatherAc::setMode(const uint8_t mode) { } } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRGoodweatherAc::getMode() { return GETBITS64(remote, kGoodweatherBitMode, kModeBitsSize); } +/// Set the Light (LED) Toggle setting of the A/C. +/// @param[in] toggle true, the setting is on. false, the setting is off. void IRGoodweatherAc::setLight(const bool toggle) { this->setCommand(kGoodweatherCmdLight); setBit(&remote, kGoodweatherBitLight, toggle); } -bool IRGoodweatherAc::getLight() { +/// Get the Light (LED) Toggle setting of the A/C. +/// @return true, the setting is on. false, the setting is off. +bool IRGoodweatherAc::getLight(void) { return GETBIT64(remote, kGoodweatherBitLight); } +/// Set the Sleep Toggle setting of the A/C. +/// @param[in] toggle true, the setting is on. false, the setting is off. void IRGoodweatherAc::setSleep(const bool toggle) { this->setCommand(kGoodweatherCmdSleep); setBit(&remote, kGoodweatherBitSleep, toggle); } -bool IRGoodweatherAc::getSleep() { +/// Get the Sleep Toggle setting of the A/C. +/// @return true, the setting is on. false, the setting is off. +bool IRGoodweatherAc::getSleep(void) { return GETBIT64(remote, kGoodweatherBitSleep); } +/// Set the Turbo Toggle setting of the A/C. +/// @param[in] toggle true, the setting is on. false, the setting is off. void IRGoodweatherAc::setTurbo(const bool toggle) { this->setCommand(kGoodweatherCmdTurbo); setBit(&remote, kGoodweatherBitTurbo, toggle); } -bool IRGoodweatherAc::getTurbo() { +/// Get the Turbo Toggle setting of the A/C. +/// @return true, the setting is on. false, the setting is off. +bool IRGoodweatherAc::getTurbo(void) { return GETBIT64(remote, kGoodweatherBitTurbo); } +/// Set the Vertical Swing speed of the A/C. +/// @param[in] speed The speed to set the swing to. void IRGoodweatherAc::setSwing(const uint8_t speed) { switch (speed) { case kGoodweatherSwingOff: @@ -193,20 +226,28 @@ void IRGoodweatherAc::setSwing(const uint8_t speed) { } } +/// Get the Vertical Swing speed of the A/C. +/// @return The native swing speed setting. uint8_t IRGoodweatherAc::getSwing() { return GETBITS64(remote, kGoodweatherBitSwing, kGoodweatherSwingSize); } +/// Set the remote Command type/button pressed. +/// @param[in] cmd The command/button that was issued/pressed. void IRGoodweatherAc::setCommand(const uint8_t cmd) { if (cmd <= kGoodweatherCmdLight) setBits(&remote, kGoodweatherBitCommand, kGoodweatherCommandSize, cmd); } +/// Get the Command type/button pressed from the current settings +/// @return The command/button that was issued/pressed. uint8_t IRGoodweatherAc::getCommand() { return GETBITS64(remote, kGoodweatherBitCommand, kGoodweatherCommandSize); } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRGoodweatherAc::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kGoodweatherCool; @@ -217,7 +258,9 @@ uint8_t IRGoodweatherAc::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRGoodweatherAc::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: @@ -229,7 +272,9 @@ uint8_t IRGoodweatherAc::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a standard A/C Vertical Swing into its native version. +/// Convert a stdAc::swingv_t enum into it's native setting. +/// @param[in] swingv The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRGoodweatherAc::convertSwingV(const stdAc::swingv_t swingv) { switch (swingv) { case stdAc::swingv_t::kHighest: @@ -242,7 +287,9 @@ uint8_t IRGoodweatherAc::convertSwingV(const stdAc::swingv_t swingv) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRGoodweatherAc::toCommonMode(const uint8_t mode) { switch (mode) { case kGoodweatherCool: return stdAc::opmode_t::kCool; @@ -253,7 +300,9 @@ stdAc::opmode_t IRGoodweatherAc::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRGoodweatherAc::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kGoodweatherFanHigh: return stdAc::fanspeed_t::kMax; @@ -263,7 +312,8 @@ stdAc::fanspeed_t IRGoodweatherAc::toCommonFanSpeed(const uint8_t speed) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRGoodweatherAc::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::GOODWEATHER; @@ -289,7 +339,8 @@ stdAc::state_t IRGoodweatherAc::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRGoodweatherAc::toString(void) { String result = ""; result.reserve(150); // Reserve some heap for the string to reduce fragging. @@ -366,18 +417,15 @@ String IRGoodweatherAc::toString(void) { } #if DECODE_GOODWEATHER -// Decode the supplied Goodweather message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kGoodweatherBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: BETA / Probably works. +/// Decode the supplied Goodweather message. +/// Status: BETA / Probably works. +/// @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::decodeGoodweather(decode_results* results, uint16_t offset, const uint16_t nbits, const bool strict) { diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Goodweather.h b/lib/IRremoteESP8266-2.7.8/src/ir_Goodweather.h similarity index 84% rename from lib/IRremoteESP8266-2.7.5/src/ir_Goodweather.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Goodweather.h index 8f1953581..1fd5579cf 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Goodweather.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Goodweather.h @@ -1,8 +1,10 @@ -// Goodweather A/C -// // Copyright 2019 ribeirodanielf // Copyright 2019 David Conran +/// @file +/// @brief Support for Goodweather compatible HVAC protocols. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/697 + // Supports: // Brand: Goodweather, Model: ZH/JT-03 remote @@ -20,11 +22,8 @@ #include "IRsend_test.h" #endif -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/697 // Constants - // Timing const uint16_t kGoodweatherBitMark = 580; const uint16_t kGoodweatherOneSpace = 580; @@ -87,15 +86,19 @@ const uint64_t kGoodweatherStateInit = 0xD50000000000; // Classes +/// Class for handling detailed Goodweather A/C messages. class IRGoodweatherAc { public: explicit IRGoodweatherAc(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - void stateReset(void); #if SEND_GOODWEATHER void send(const uint16_t repeat = kGoodweatherMinRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + /// 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_GOODWEATHER void begin(void); void on(void); @@ -130,10 +133,12 @@ class IRGoodweatherAc { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - uint64_t remote; // The state of the IR remote in IR code form. + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint64_t remote; ///< The state of the IR remote in IR code form. }; #endif // IR_GOODWEATHER_H_ diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Gree.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Gree.cpp similarity index 59% rename from lib/IRremoteESP8266-2.7.5/src/ir_Gree.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Gree.cpp index 81062d650..d9ff269d5 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Gree.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Gree.cpp @@ -1,11 +1,9 @@ // Copyright 2017 Ville Skyttä (scop) // Copyright 2017, 2018 David Conran -// -// Code to emulate Gree protocol compatible HVAC devices. -// Should be compatible with: -// * Heat pumps carrying the "Ultimate" brand name. -// * EKOKAI air conditioners. -// + +/// @file +/// @brief Support for Gree A/C protocols. +/// @see https://github.com/ToniA/arduino-heatpumpir/blob/master/GreeHeatpumpIR.h #include "ir_Gree.h" #include @@ -21,9 +19,8 @@ #include "ir_Kelvinator.h" // Constants -// Ref: https://github.com/ToniA/arduino-heatpumpir/blob/master/GreeHeatpumpIR.h const uint16_t kGreeHdrMark = 9000; -const uint16_t kGreeHdrSpace = 4500; // See #684 and real example in unit tests +const uint16_t kGreeHdrSpace = 4500; ///< See #684 & real example in unit tests const uint16_t kGreeBitMark = 620; const uint16_t kGreeOneSpace = 1600; const uint16_t kGreeZeroSpace = 540; @@ -43,18 +40,12 @@ using irutils::setBit; using irutils::setBits; #if SEND_GREE -// Send a Gree Heat Pump message. -// -// Args: -// data: An array of bytes containing the IR command. -// nbytes: Nr. of bytes of data in the array. (>=kGreeStateLength) -// repeat: Nr. of times the message is to be repeated. (Default = 0). -// -// Status: STABLE / Working. -// -// Ref: -// https://github.com/ToniA/arduino-heatpumpir/blob/master/GreeHeatpumpIR.cpp -void IRsend::sendGree(const unsigned char data[], const uint16_t nbytes, +/// Send a Gree Heat Pump formatted message. +/// Status: STABLE / Working. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +void IRsend::sendGree(const uint8_t data[], const uint16_t nbytes, const uint16_t repeat) { if (nbytes < kGreeStateLength) return; // Not enough bytes to send a proper message. @@ -77,17 +68,11 @@ void IRsend::sendGree(const unsigned char data[], const uint16_t nbytes, } } -// Send a Gree Heat Pump message. -// -// Args: -// data: The raw message to be sent. -// nbits: Nr. of bits of data in the message. (Default is kGreeBits) -// repeat: Nr. of times the message is to be repeated. (Default = 0). -// -// Status: STABLE / Working. -// -// Ref: -// https://github.com/ToniA/arduino-heatpumpir/blob/master/GreeHeatpumpIR.cpp +/// Send a Gree Heat Pump formatted message. +/// Status: STABLE / Working. +/// @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::sendGree(const uint64_t data, const uint16_t nbits, const uint16_t repeat) { if (nbits != kGreeBits) @@ -119,6 +104,11 @@ void IRsend::sendGree(const uint64_t data, const uint16_t nbits, } #endif // SEND_GREE +/// Class constructor +/// @param[in] pin GPIO to be used when sending. +/// @param[in] model The enum of the model to be emulated. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? IRGreeAC::IRGreeAC(const uint16_t pin, const gree_ac_remote_model_t model, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { @@ -126,6 +116,7 @@ IRGreeAC::IRGreeAC(const uint16_t pin, const gree_ac_remote_model_t model, setModel(model); } +/// Reset the internal state to a fixed known good state. void IRGreeAC::stateReset(void) { // This resets to a known-good state to Power Off, Fan Auto, Mode Auto, 25C. for (uint8_t i = 0; i < kGreeStateLength; i++) remote_state[i] = 0x0; @@ -136,25 +127,34 @@ void IRGreeAC::stateReset(void) { remote_state[7] = 0x50; } +/// Fix up the internal state so it is correct. +/// @note Internal use only. void IRGreeAC::fixup(void) { setPower(getPower()); // Redo the power bits as they differ between models. checksum(); // Calculate the checksums } +/// Set up hardware to be able to send a message. void IRGreeAC::begin(void) { _irsend.begin(); } #if SEND_GREE +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRGreeAC::send(const uint16_t repeat) { fixup(); // Ensure correct settings before sending. _irsend.sendGree(remote_state, kGreeStateLength, repeat); } #endif // SEND_GREE +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t* IRGreeAC::getRaw(void) { fixup(); // Ensure correct settings before sending. return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. void IRGreeAC::setRaw(const uint8_t new_code[]) { memcpy(remote_state, new_code, kGreeStateLength); // We can only detect the difference between models when the power is on. @@ -166,24 +166,26 @@ void IRGreeAC::setRaw(const uint8_t new_code[]) { } } +/// Calculate and set the checksum values for the internal state. +/// @param[in] length The size/length of the state array to fix the checksum of. void IRGreeAC::checksum(const uint16_t length) { // Gree uses the same checksum alg. as Kelvinator's block checksum. setBits(&remote_state[length - 1], kHighNibble, kNibbleSize, IRKelvinatorAC::calcBlockChecksum(remote_state, length)); } -// Verify the checksum is valid for a given state. -// Args: -// state: The array to verify the checksum of. -// length: The size of the state. -// Returns: -// A boolean. +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length of the state array. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRGreeAC::validChecksum(const uint8_t state[], const uint16_t length) { // Top 4 bits of the last byte in the state is the state's checksum. return GETBITS8(state[length - 1], kHighNibble, kNibbleSize) == IRKelvinatorAC::calcBlockChecksum(state, length); } +/// Set the model of the A/C to emulate. +/// @param[in] model The enum of the appropriate model. void IRGreeAC::setModel(const gree_ac_remote_model_t model) { switch (model) { case gree_ac_remote_model_t::YAW1F: @@ -192,12 +194,19 @@ void IRGreeAC::setModel(const gree_ac_remote_model_t model) { } } +/// Get/Detect the model of the A/C. +/// @return The enum of the compatible model. gree_ac_remote_model_t IRGreeAC::getModel(void) { return _model; } +/// Change the power setting to On. void IRGreeAC::on(void) { setPower(true); } +/// Change the power setting to Off. void IRGreeAC::off(void) { setPower(false); } +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/814 void IRGreeAC::setPower(const bool on) { setBit(&remote_state[0], kGreePower1Offset, on); // May not be needed. See #814 @@ -205,25 +214,72 @@ void IRGreeAC::setPower(const bool on) { on && _model != gree_ac_remote_model_t::YBOFB); } +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/814 bool IRGreeAC::getPower(void) { // See #814. Not checking/requiring: (remote_state[2] & kGreePower2Mask) return GETBIT8(remote_state[0], kGreePower1Offset); } -// Set the temp. in deg C -void IRGreeAC::setTemp(const uint8_t temp) { - uint8_t new_temp = std::max((uint8_t)kGreeMinTemp, temp); - new_temp = std::min((uint8_t)kGreeMaxTemp, new_temp); - if (getMode() == kGreeAuto) new_temp = 25; - setBits(&remote_state[1], kLowNibble, kGreeTempSize, new_temp - kGreeMinTemp); +/// Set the default temperature units to use. +/// @param[in] on Use Fahrenheit as the units. +/// true is Fahrenheit, false is Celsius. +void IRGreeAC::setUseFahrenheit(const bool on) { + setBit(&remote_state[3], kGreeUseFahrenheitOffset, on); } -// Return the set temp. in deg C +/// Get the default temperature units in use. +/// @return true is Fahrenheit, false is Celsius. +bool IRGreeAC::getUseFahrenheit(void) { + return GETBIT8(remote_state[3], kGreeUseFahrenheitOffset); +} + +/// Set the temp. in degrees +/// @param[in] temp Desired temperature in Degrees. +/// @param[in] fahrenheit Use units of Fahrenheit and set that as units used. +/// false is Celsius (Default), true is Fahrenheit. +/// @note The unit actually works in Celsius with a special optional +/// "extra degree" when sending Fahrenheit. +void IRGreeAC::setTemp(const uint8_t temp, const bool fahrenheit) { + float safecelsius = temp; + if (fahrenheit) + // Covert to F, and add a fudge factor to round to the expected degree. + // Why 0.6 you ask?! Because it works. Ya'd thing 0.5 would be good for + // rounding, but Noooooo! + safecelsius = fahrenheitToCelsius(temp + 0.6); + setUseFahrenheit(fahrenheit); // Set the correct Temp units. + + // Make sure we have desired temp in the correct range. + safecelsius = std::max(static_cast(kGreeMinTempC), safecelsius); + safecelsius = std::min(static_cast(kGreeMaxTempC), safecelsius); + // An operating mode of Auto locks the temp to a specific value. Do so. + if (getMode() == kGreeAuto) safecelsius = 25; + + // Set the "main" Celsius degrees. + setBits(&remote_state[1], kGreeTempOffset, kGreeTempSize, + safecelsius - kGreeMinTempC); + // Deal with the extra degree fahrenheit difference. + setBit(&remote_state[3], kGreeTempExtraDegreeFOffset, + (uint8_t)(safecelsius * 2) & 1); +} + +/// Get the set temperature +/// @return The temperature in degrees in the current units (C/F) set. uint8_t IRGreeAC::getTemp(void) { - return GETBITS8(remote_state[1], kLowNibble, kGreeTempSize) + kGreeMinTemp; + uint8_t deg = kGreeMinTempC + GETBITS8(remote_state[1], kGreeTempOffset, + kGreeTempSize); + if (getUseFahrenheit()) { + deg = celsiusToFahrenheit(deg); + // Retrieve the "extra" fahrenheit from elsewhere in the code. + if (GETBIT8(remote_state[3], kGreeTempExtraDegreeFOffset)) deg++; + deg = std::max(deg, kGreeMinTempF); // Cover the fact that 61F is < 16C + } + return deg; } -// Set the speed of the fan, 0-3, 0 is auto, 1-3 is the speed +/// Set the speed of the fan. +/// @param[in] speed The desired setting. 0 is auto, 1-3 is the speed. void IRGreeAC::setFan(const uint8_t speed) { uint8_t fan = std::min((uint8_t)kGreeFanMax, speed); // Bounds check if (getMode() == kGreeDry) fan = 1; // DRY mode is always locked to fan 1. @@ -231,10 +287,14 @@ void IRGreeAC::setFan(const uint8_t speed) { setBits(&remote_state[0], kGreeFanOffset, kGreeFanSize, fan); } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRGreeAC::getFan(void) { return GETBITS8(remote_state[0], kGreeFanOffset, kGreeFanSize); } +/// Set the operating mode of the A/C. +/// @param[in] new_mode The desired operating mode. void IRGreeAC::setMode(const uint8_t new_mode) { uint8_t mode = new_mode; switch (mode) { @@ -251,58 +311,87 @@ void IRGreeAC::setMode(const uint8_t new_mode) { setBits(&remote_state[0], kLowNibble, kModeBitsSize, mode); } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRGreeAC::getMode(void) { return GETBITS8(remote_state[0], kLowNibble, kModeBitsSize); } +/// Set the Light (LED) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRGreeAC::setLight(const bool on) { setBit(&remote_state[2], kGreeLightOffset, on); } +/// Get the Light (LED) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRGreeAC::getLight(void) { return GETBIT8(remote_state[2], kGreeLightOffset); } +/// Set the IFeel setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRGreeAC::setIFeel(const bool on) { setBit(&remote_state[5], kGreeIFeelOffset, on); } +/// Get the IFeel setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRGreeAC::getIFeel(void) { return GETBIT8(remote_state[5], kGreeIFeelOffset); } +/// Set the Wifi (enabled) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRGreeAC::setWiFi(const bool on) { setBit(&remote_state[5], kGreeWiFiOffset, on); } +/// Get the Wifi (enabled) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRGreeAC::getWiFi(void) { return GETBIT8(remote_state[5], kGreeWiFiOffset); } +/// Set the XFan (Mould) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRGreeAC::setXFan(const bool on) { setBit(&remote_state[2], kGreeXfanOffset, on); } +/// Get the XFan (Mould) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRGreeAC::getXFan(void) { return GETBIT8(remote_state[2], kGreeXfanOffset); } +/// Set the Sleep setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRGreeAC::setSleep(const bool on) { setBit(&remote_state[0], kGreeSleepOffset, on); } +/// Get the Sleep setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRGreeAC::getSleep(void) { return GETBIT8(remote_state[0], kGreeSleepOffset); } +/// Set the Turbo setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRGreeAC::setTurbo(const bool on) { setBit(&remote_state[2], kGreeTurboOffset, on); } +/// Get the Turbo setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRGreeAC::getTurbo(void) { return GETBIT8(remote_state[2], kGreeTurboOffset); } +/// Set the Vertical Swing mode of the A/C. +/// @param[in] automatic Do we use the automatic setting? +/// @param[in] position The position/mode to set the vanes to. void IRGreeAC::setSwingVertical(const bool automatic, const uint8_t position) { setBit(&remote_state[0], kGreeSwingAutoOffset, automatic); uint8_t new_position = position; @@ -331,23 +420,32 @@ void IRGreeAC::setSwingVertical(const bool automatic, const uint8_t position) { setBits(&remote_state[4], kLowNibble, kGreeSwingSize, new_position); } +/// Get the Vertical Swing Automatic mode setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRGreeAC::getSwingVerticalAuto(void) { return GETBIT8(remote_state[0], kGreeSwingAutoOffset); } +/// Get the Vertical Swing position setting of the A/C. +/// @return The native position/mode. uint8_t IRGreeAC::getSwingVerticalPosition(void) { return GETBITS8(remote_state[4], kLowNibble, kGreeSwingSize); } +/// Set the timer enable setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRGreeAC::setTimerEnabled(const bool on) { setBit(&remote_state[1], kGreeTimerEnabledOffset, on); } +/// Get the timer enabled setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRGreeAC::getTimerEnabled(void) { return GETBIT8(remote_state[1], kGreeTimerEnabledOffset); } -// Returns the number of minutes the timer is set for. +/// Get the timer time value from the A/C. +/// @return The number of minutes the timer is set for. uint16_t IRGreeAC::getTimer(void) { uint16_t hrs = irutils::bcdToUint8( (GETBITS8(remote_state[1], kGreeTimerTensHrOffset, @@ -356,12 +454,10 @@ uint16_t IRGreeAC::getTimer(void) { return hrs * 60 + (GETBIT8(remote_state[1], kGreeTimerHalfHrOffset) ? 30 : 0); } -// Set the A/C's timer to turn off in X many minutes. -// Stores time internally in 30 min units. -// e.g. 5 mins means 0 (& Off), 95 mins is 90 mins (& On). Max is 24 hours. -// -// Args: -// minutes: The number of minutes the timer should be set for. +/// Set the A/C's timer to turn off in X many minutes. +/// @param[in] minutes The number of minutes the timer should be set for. +/// @note Stores time internally in 30 min units. +/// e.g. 5 mins means 0 (& Off), 95 mins is 90 mins (& On). Max is 24 hours. void IRGreeAC::setTimer(const uint16_t minutes) { uint16_t mins = std::min(kGreeTimerMax, minutes); // Bounds check. setTimerEnabled(mins >= 30); // Timer is enabled when >= 30 mins. @@ -376,7 +472,32 @@ void IRGreeAC::setTimer(const uint16_t minutes) { hours % 10); } -// Convert a standard A/C mode into its native mode. +/// Set temperature display mode. +/// i.e. Internal, External temperature sensing. +/// @param[in] mode The desired temp source to display. +/// @note In order for the A/C unit properly accept these settings. You must +/// cycle (send) in the following order: +/// kGreeDisplayTempOff(0) -> kGreeDisplayTempSet(1) -> +/// kGreeDisplayTempInside(2) ->kGreeDisplayTempOutside(3) -> +/// kGreeDisplayTempOff(0). +/// The unit will no behave correctly if the changes of this setting are sent +/// out of order. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1118#issuecomment-628242152 +void IRGreeAC::setDisplayTempSource(const uint8_t mode) { + setBits(&remote_state[5], kGreeDisplayTempOffset, kGreeDisplayTempSize, mode); +} + +/// Get the temperature display mode. +/// i.e. Internal, External temperature sensing. +/// @return The current temp source being displayed. +uint8_t IRGreeAC::getDisplayTempSource(void) { + return GETBITS8(remote_state[5], kGreeDisplayTempOffset, + kGreeDisplayTempSize); +} + +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRGreeAC::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kGreeCool; @@ -387,7 +508,9 @@ uint8_t IRGreeAC::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRGreeAC::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: return kGreeFanMin; @@ -399,7 +522,9 @@ uint8_t IRGreeAC::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a standard A/C Vertical Swing into its native version. +/// Convert a stdAc::swingv_t enum into it's native setting. +/// @param[in] swingv The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRGreeAC::convertSwingV(const stdAc::swingv_t swingv) { switch (swingv) { case stdAc::swingv_t::kHighest: return kGreeSwingUp; @@ -411,7 +536,9 @@ uint8_t IRGreeAC::convertSwingV(const stdAc::swingv_t swingv) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRGreeAC::toCommonMode(const uint8_t mode) { switch (mode) { case kGreeCool: return stdAc::opmode_t::kCool; @@ -422,7 +549,9 @@ stdAc::opmode_t IRGreeAC::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRGreeAC::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kGreeFanMax: return stdAc::fanspeed_t::kMax; @@ -432,7 +561,9 @@ stdAc::fanspeed_t IRGreeAC::toCommonFanSpeed(const uint8_t speed) { } } -// Convert a native vertical swing to it's common equivalent. +/// Convert a stdAc::swingv_t enum into it's native setting. +/// @param[in] pos The enum to be converted. +/// @return The native equivilant of the enum. stdAc::swingv_t IRGreeAC::toCommonSwingV(const uint8_t pos) { switch (pos) { case kGreeSwingUp: return stdAc::swingv_t::kHighest; @@ -444,14 +575,15 @@ stdAc::swingv_t IRGreeAC::toCommonSwingV(const uint8_t pos) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRGreeAC::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::GREE; result.model = this->getModel(); result.power = this->getPower(); result.mode = this->toCommonMode(this->getMode()); - result.celsius = true; + result.celsius = !this->getUseFahrenheit(); result.degrees = this->getTemp(); result.fanspeed = this->toCommonFanSpeed(this->getFan()); if (this->getSwingVerticalAuto()) @@ -472,15 +604,16 @@ stdAc::state_t IRGreeAC::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRGreeAC::toString(void) { String result = ""; - result.reserve(150); // Reserve some heap for the string to reduce fragging. + result.reserve(220); // Reserve some heap for the string to reduce fragging. result += addModelToString(decode_type_t::GREE, getModel(), false); result += addBoolToString(getPower(), kPowerStr); result += addModeToString(getMode(), kGreeAuto, kGreeCool, kGreeHeat, kGreeDry, kGreeFan); - result += addTempToString(getTemp()); + result += addTempToString(getTemp(), !getUseFahrenheit()); result += addFanToString(getFan(), kGreeFanMax, kGreeFanMin, kGreeFanAuto, kGreeFanAuto, kGreeFanMed); result += addBoolToString(getTurbo(), kTurboStr); @@ -505,22 +638,38 @@ String IRGreeAC::toString(void) { result += ')'; result += addLabeledString( getTimerEnabled() ? minsToString(getTimer()) : kOffStr, kTimerStr); + uint8_t src = getDisplayTempSource(); + result += addIntToString(src, kDisplayTempStr); + result += kSpaceLBraceStr; + switch (src) { + case kGreeDisplayTempOff: + result += kOffStr; + break; + case kGreeDisplayTempSet: + result += kSetStr; + break; + case kGreeDisplayTempInside: + result += kInsideStr; + break; + case kGreeDisplayTempOutside: + result += kOutsideStr; + break; + default: result += kUnknownStr; + } + result += ')'; return result; } #if DECODE_GREE -// Decode the supplied Gree message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kGreeBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Working. +/// Decode the supplied Gree HVAC message. +/// Status: STABLE / 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::decodeGree(decode_results* results, uint16_t offset, const uint16_t nbits, bool const strict) { if (results->rawlen <= diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Gree.h b/lib/IRremoteESP8266-2.7.8/src/ir_Gree.h similarity index 66% rename from lib/IRremoteESP8266-2.7.5/src/ir_Gree.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Gree.h index 14cd7b84a..8fb74aa7f 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Gree.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Gree.h @@ -1,6 +1,9 @@ // Copyright 2016 David Conran -// Gree A/C -// + +/// @file +/// @brief Support for Gree A/C protocols. +/// @see https://github.com/ToniA/arduino-heatpumpir/blob/master/GreeHeatpumpIR.h + // Supports: // Brand: Ultimate, Model: Heat Pump // Brand: EKOKAI, Model: A/C @@ -8,6 +11,8 @@ // Brand: RusClimate, Model: YAW1F remote // Brand: Green, Model: YBOFB remote // Brand: Green, Model: YBOFB2 remote +// Brand: Gree, Model: YAA1FBF remote +// Brand: Gree, Model: YB1F2F remote #ifndef IR_GREE_H_ #define IR_GREE_H_ @@ -31,7 +36,7 @@ const uint8_t kGreeDry = 2; const uint8_t kGreeFan = 3; const uint8_t kGreeHeat = 4; -// Byte 0 +// Byte[0] const uint8_t kGreePower1Offset = 3; const uint8_t kGreeFanOffset = 4; const uint8_t kGreeFanSize = 2; // Bits @@ -41,17 +46,19 @@ const uint8_t kGreeFanMed = 2; const uint8_t kGreeFanMax = 3; const uint8_t kGreeSwingAutoOffset = 6; const uint8_t kGreeSleepOffset = 7; -// Byte 1 -const uint8_t kGreeTempSize = 4; -const uint8_t kGreeMinTemp = 16; // Celsius -const uint8_t kGreeMaxTemp = 30; // Celsius -const uint8_t kGreeTimerHalfHrOffset = 4; +// Byte[1] +const uint8_t kGreeTempOffset = 0; +const uint8_t kGreeTempSize = 4; // Mask 0b0000xxxx +const uint8_t kGreeMinTempC = 16; // Celsius +const uint8_t kGreeMaxTempC = 30; // Celsius +const uint8_t kGreeMinTempF = 61; // Fahrenheit +const uint8_t kGreeMaxTempF = 86; // Fahrenheit +const uint8_t kGreeTimerHalfHrOffset = 4; // Mask 0b000x0000 const uint8_t kGreeTimerTensHrOffset = 5; -const uint8_t kGreeTimerTensHrSize = 2; // Bits +const uint8_t kGreeTimerTensHrSize = 2; // Mask 0b0xx00000 const uint16_t kGreeTimerMax = 24 * 60; -const uint8_t kGreeTimerEnabledOffset = 7; - -// Byte 2 +const uint8_t kGreeTimerEnabledOffset = 7; // Mask 0bx0000000 +// Byte[2] const uint8_t kGreeTimerHoursOffset = 0; const uint8_t kGreeTimerHoursSize = 4; // Bits const uint8_t kGreeTurboOffset = 4; @@ -59,7 +66,10 @@ const uint8_t kGreeLightOffset = 5; // This might not be used. See #814 const uint8_t kGreePower2Offset = 6; const uint8_t kGreeXfanOffset = 7; -// Byte 4 +// Byte[3] +const uint8_t kGreeTempExtraDegreeFOffset = 2; // Mask 0b00000x00 +const uint8_t kGreeUseFahrenheitOffset = 3; // Mask 0b0000x000 +// Byte[4] const uint8_t kGreeSwingSize = 4; // Bits const uint8_t kGreeSwingLastPos = 0b0000; const uint8_t kGreeSwingAuto = 0b0001; @@ -71,9 +81,16 @@ const uint8_t kGreeSwingDown = 0b0110; const uint8_t kGreeSwingDownAuto = 0b0111; const uint8_t kGreeSwingMiddleAuto = 0b1001; const uint8_t kGreeSwingUpAuto = 0b1011; -// byte 5 -const uint8_t kGreeIFeelOffset = 2; -const uint8_t kGreeWiFiOffset = 6; +// Byte[5] +const uint8_t kGreeWiFiOffset = 6; // Mask 0b0x000000 +const uint8_t kGreeIFeelOffset = 2; // Mask 0b00000x00 +const uint8_t kGreeDisplayTempOffset = 0; +const uint8_t kGreeDisplayTempSize = 2; // Mask 0b000000xx +const uint8_t kGreeDisplayTempOff = 0b00; // 0 +const uint8_t kGreeDisplayTempSet = 0b01; // 1 +const uint8_t kGreeDisplayTempInside = 0b10; // 2 +const uint8_t kGreeDisplayTempOutside = 0b11; // 3 + // Legacy defines. #define GREE_AUTO kGreeAuto @@ -81,8 +98,8 @@ const uint8_t kGreeWiFiOffset = 6; #define GREE_DRY kGreeDry #define GREE_FAN kGreeFan #define GREE_HEAT kGreeHeat -#define GREE_MIN_TEMP kGreeMinTemp -#define GREE_MAX_TEMP kGreeMaxTemp +#define GREE_MIN_TEMP kGreeMinTempC +#define GREE_MAX_TEMP kGreeMaxTempC #define GREE_FAN_MAX kGreeFanMax #define GREE_SWING_LAST_POS kGreeSwingLastPos #define GREE_SWING_AUTO kGreeSwingAuto @@ -96,17 +113,21 @@ const uint8_t kGreeWiFiOffset = 6; #define GREE_SWING_UP_AUTO kGreeSwingUpAuto // Classes +/// Class for handling detailed Gree A/C messages. class IRGreeAC { public: explicit IRGreeAC( const uint16_t pin, const gree_ac_remote_model_t model = gree_ac_remote_model_t::YAW1F, const bool inverted = false, const bool use_modulation = true); - void stateReset(void); #if SEND_GREE void send(const uint16_t repeat = kGreeDefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + /// 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_GREE void begin(void); void on(void); @@ -115,8 +136,10 @@ class IRGreeAC { gree_ac_remote_model_t getModel(void); void setPower(const bool on); bool getPower(void); - void setTemp(const uint8_t temp); + void setTemp(const uint8_t temp, const bool fahrenheit = false); uint8_t getTemp(void); + void setUseFahrenheit(const bool on); + bool getUseFahrenheit(void); void setFan(const uint8_t speed); uint8_t getFan(void); void setMode(const uint8_t new_mode); @@ -138,6 +161,8 @@ class IRGreeAC { uint8_t getSwingVerticalPosition(void); uint16_t getTimer(void); void setTimer(const uint16_t minutes); + void setDisplayTempSource(const uint8_t mode); + uint8_t getDisplayTempSource(void); uint8_t convertMode(const stdAc::opmode_t mode); uint8_t convertFan(const stdAc::fanspeed_t speed); uint8_t convertSwingV(const stdAc::swingv_t swingv); @@ -153,12 +178,13 @@ class IRGreeAC { #ifndef UNIT_TEST private: - IRsend _irsend; + IRsend _irsend; ///< Instance of the IR send class #else // UNIT_TEST - IRsendTest _irsend; + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond #endif // UNIT_TEST - // The state of the IR remote in IR code form. - uint8_t remote_state[kGreeStateLength]; + uint8_t remote_state[kGreeStateLength]; ///< The state in native IR code form gree_ac_remote_model_t _model; void checksum(const uint16_t length = kGreeStateLength); void fixup(void); diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Haier.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Haier.cpp similarity index 71% rename from lib/IRremoteESP8266-2.7.5/src/ir_Haier.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Haier.cpp index cac4320cf..5f2172696 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Haier.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Haier.cpp @@ -1,8 +1,13 @@ // Copyright 2018 crankyoldgit -// Code to emulate Haier protocol compatible devices. -// The specifics of reverse engineering the protocols details: -// * HSU07-HEA03 by kuzin2006. -// * YR-W02/HSU-09HMC203 by non7top. +/// @file +/// @brief Support for Haier A/C protocols. +/// The specifics of reverse engineering the protocols details: +/// * HSU07-HEA03 by kuzin2006. +/// * YR-W02/HSU-09HMC203 by non7top. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/404 +/// @see https://www.dropbox.com/s/mecyib3lhdxc8c6/IR%20data%20reverse%20engineering.xlsx?dl=0 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/485 +/// @see https://www.dropbox.com/sh/w0bt7egp0fjger5/AADRFV6Wg4wZskJVdFvzb8Z0a?dl=0&preview=haer2.ods #include "ir_Haier.h" #include @@ -13,17 +18,6 @@ #include "IRtext.h" #include "IRutils.h" -// Supported devices: -// * Haier HSU07-HEA03 Remote control. -// * Haier YR-W02 Remote control -// * Haier HSU-09HMC203 A/C unit. - -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/404 -// https://www.dropbox.com/s/mecyib3lhdxc8c6/IR%20data%20reverse%20engineering.xlsx?dl=0 -// https://github.com/crankyoldgit/IRremoteESP8266/issues/485 -// https://www.dropbox.com/sh/w0bt7egp0fjger5/AADRFV6Wg4wZskJVdFvzb8Z0a?dl=0&preview=haer2.ods - // Constants const uint16_t kHaierAcHdr = 3000; const uint16_t kHaierAcHdrGap = 4300; @@ -43,15 +37,11 @@ using irutils::setBit; using irutils::setBits; #if (SEND_HAIER_AC || SEND_HAIER_AC_YRW02) -// Send a Haier A/C message. (HSU07-HEA03 remote) -// -// Args: -// data: An array of bytes containing the IR command. -// nbytes: Nr. of bytes of data in the array. (>=kHaierACStateLength) -// repeat: Nr. of times the message is to be repeated. (Default = 0). -// -// Status: STABLE / Known to be working. -// +/// Send a Haier A/C formatted message. (HSU07-HEA03 remote) +/// Status: STABLE / Known to be working. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendHaierAC(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { if (nbytes < kHaierACStateLength) return; @@ -70,43 +60,51 @@ void IRsend::sendHaierAC(const unsigned char data[], const uint16_t nbytes, #endif // (SEND_HAIER_AC || SEND_HAIER_AC_YRW02) #if SEND_HAIER_AC_YRW02 -// Send a Haier YR-W02 remote A/C message. -// -// Args: -// data: An array of bytes containing the IR command. -// nbytes: Nr. of bytes of data in the array. (>=kHaierACYRW02StateLength) -// repeat: Nr. of times the message is to be repeated. (Default = 0). -// -// Status: Alpha / Untested on a real device. -// +/// Send a Haier YR-W02 remote A/C formatted message. +/// Status: Alpha / Untested on a real device. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendHaierACYRW02(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { if (nbytes >= kHaierACYRW02StateLength) sendHaierAC(data, nbytes, repeat); } #endif // SEND_HAIER_AC_YRW02 -// Class for emulating a Haier HSU07-HEA03 remote +/// 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? IRHaierAC::IRHaierAC(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { stateReset(); } +/// Set up hardware to be able to send a message. void IRHaierAC::begin(void) { _irsend.begin(); } #if SEND_HAIER_AC +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRHaierAC::send(const uint16_t repeat) { _irsend.sendHaierAC(getRaw(), kHaierACStateLength, repeat); } #endif // SEND_HAIER_AC +/// Calculate and set the checksum values for the internal state. void IRHaierAC::checksum(void) { remote_state[8] = sumBytes(remote_state, kHaierACStateLength - 1); } +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length of the state array. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRHaierAC::validChecksum(uint8_t state[], const uint16_t length) { if (length < 2) return false; // 1 byte of data can't have a checksum. return (state[length - 1] == sumBytes(state, length - 1)); } +/// Reset the internal state to a fixed known good state. void IRHaierAC::stateReset(void) { for (uint8_t i = 1; i < kHaierACStateLength; i++) remote_state[i] = 0x0; remote_state[0] = kHaierAcPrefix; @@ -120,15 +118,21 @@ void IRHaierAC::stateReset(void) { setCommand(kHaierAcCmdOn); } +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t* IRHaierAC::getRaw(void) { checksum(); return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. void IRHaierAC::setRaw(const uint8_t new_code[]) { memcpy(remote_state, new_code, kHaierACStateLength); } +/// Set the Command/Button setting of the A/C. +/// @param[in] command The value of the command/button that was pressed. void IRHaierAC::setCommand(const uint8_t command) { switch (command) { case kHaierAcCmdOff: @@ -146,10 +150,14 @@ void IRHaierAC::setCommand(const uint8_t command) { } } +/// Get the Command/Button setting of the A/C. +/// @return The value of the command/button that was pressed. uint8_t IRHaierAC::getCommand(void) { return GETBITS8(remote_state[1], kLowNibble, kNibbleSize); } +/// Set the speed of the fan. +/// @param[in] speed The desired setting. void IRHaierAC::setFan(const uint8_t speed) { uint8_t new_speed = kHaierAcFanAuto; switch (speed) { @@ -164,6 +172,8 @@ void IRHaierAC::setFan(const uint8_t speed) { setBits(&remote_state[5], kLowNibble, kHaierAcSwingSize, new_speed); } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRHaierAC::getFan(void) { switch (GETBITS8(remote_state[5], kLowNibble, kHaierAcSwingSize)) { case 1: return kHaierAcFanMed; @@ -173,6 +183,8 @@ uint8_t IRHaierAC::getFan(void) { } } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRHaierAC::setMode(uint8_t mode) { uint8_t new_mode = mode; setCommand(kHaierAcCmdMode); @@ -181,10 +193,14 @@ void IRHaierAC::setMode(uint8_t mode) { setBits(&remote_state[6], kHaierAcModeOffset, kModeBitsSize, new_mode); } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRHaierAC::getMode(void) { return GETBITS8(remote_state[6], kHaierAcModeOffset, kModeBitsSize); } +/// Set the temperature. +/// @param[in] degrees The temperature in degrees celsius. void IRHaierAC::setTemp(const uint8_t degrees) { uint8_t temp = degrees; if (temp < kHaierAcMinTemp) @@ -201,33 +217,47 @@ void IRHaierAC::setTemp(const uint8_t degrees) { setBits(&remote_state[1], kHighNibble, kNibbleSize, temp - kHaierAcMinTemp); } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRHaierAC::getTemp(void) { return GETBITS8(remote_state[1], kHighNibble, kNibbleSize) + kHaierAcMinTemp; } +/// Set the Health (filter) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRHaierAC::setHealth(const bool on) { setCommand(kHaierAcCmdHealth); setBit(&remote_state[4], kHaierAcHealthBitOffset, on); } +/// Get the Health (filter) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRHaierAC::getHealth(void) { return GETBIT8(remote_state[4], kHaierAcHealthBitOffset); } +/// Set the Sleep setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRHaierAC::setSleep(const bool on) { setCommand(kHaierAcCmdSleep); setBit(&remote_state[7], kHaierAcSleepBitOffset, on); } +/// Get the Sleep setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRHaierAC::getSleep(void) { return GETBIT8(remote_state[7], kHaierAcSleepBitOffset); } +/// Get the Time value at the given pointer. +/// @param[in] ptr A Ptr to a location in the internal state to get the time. uint16_t IRHaierAC::getTime(const uint8_t ptr[]) { return GETBITS8(ptr[0], kHaierAcTimeOffset, kHaierAcHoursSize) * 60 + GETBITS8(ptr[1], kHaierAcTimeOffset, kHaierAcMinsSize); } +/// Get the On Timer value/setting of the A/C. +/// @return Nr of minutes the timer is set to. -1 is Off/not set etc. int16_t IRHaierAC::getOnTimer(void) { // Check if the timer is turned on. if (GETBIT8(remote_state[3], kHaierAcOnTimerOffset)) @@ -236,6 +266,8 @@ int16_t IRHaierAC::getOnTimer(void) { return -1; } +/// Get the Off Timer value/setting of the A/C. +/// @return Nr of minutes the timer is set to. -1 is Off/not set etc. int16_t IRHaierAC::getOffTimer(void) { // Check if the timer is turned on. if (GETBIT8(remote_state[3], kHaierAcOffTimerOffset)) @@ -244,8 +276,13 @@ int16_t IRHaierAC::getOffTimer(void) { return -1; } +/// Get the clock value of the A/C. +/// @return The clock time, in Nr of minutes past midnight. uint16_t IRHaierAC::getCurrTime(void) { return getTime(remote_state + 2); } +/// Set the Time value at the given pointer. +/// @param[out] ptr A Ptr to a location in the internal state to set the time. +/// @param[in] nr_mins The time expressed in total number of minutes. void IRHaierAC::setTime(uint8_t ptr[], const uint16_t nr_mins) { uint16_t mins = nr_mins; if (nr_mins > kHaierAcMaxTime) mins = kHaierAcMaxTime; @@ -253,31 +290,42 @@ void IRHaierAC::setTime(uint8_t ptr[], const uint16_t nr_mins) { setBits(ptr + 1, kHaierAcTimeOffset, kHaierAcMinsSize, mins % 60); // Minutes } +/// Set & enable the On Timer. +/// @param[in] nr_mins The time expressed in total number of minutes. void IRHaierAC::setOnTimer(const uint16_t nr_mins) { setCommand(kHaierAcCmdTimerSet); setBit(&remote_state[3], kHaierAcOnTimerOffset); setTime(remote_state + 6, nr_mins); } +/// Set & enable the Off Timer. +/// @param[in] nr_mins The time expressed in total number of minutes. void IRHaierAC::setOffTimer(const uint16_t nr_mins) { setCommand(kHaierAcCmdTimerSet); setBit(&remote_state[3], kHaierAcOffTimerOffset); setTime(remote_state + 4, nr_mins); } +/// Cancel/disable the On & Off timers. void IRHaierAC::cancelTimers(void) { setCommand(kHaierAcCmdTimerCancel); setBits(&remote_state[3], kHaierAcOffTimerOffset, 2, 0); } +/// Set the clock value for the A/C. +/// @param[in] nr_mins The clock time, in Nr of minutes past midnight. void IRHaierAC::setCurrTime(const uint16_t nr_mins) { setTime(remote_state + 2, nr_mins); } +/// Get the Vertical Swing position setting of the A/C. +/// @return The native swing mode. uint8_t IRHaierAC::getSwing(void) { return GETBITS8(remote_state[2], kHaierAcSwingOffset, kHaierAcSwingSize); } +/// Set the Vertical Swing mode of the A/C. +/// @param[in] cmd The mode to set the vanes to. void IRHaierAC::setSwing(const uint8_t cmd) { if (cmd == getSwing()) return; // Nothing to do. switch (cmd) { @@ -291,7 +339,9 @@ void IRHaierAC::setSwing(const uint8_t cmd) { } } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRHaierAC::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kHaierAcCool; @@ -302,7 +352,9 @@ uint8_t IRHaierAC::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRHaierAC::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: @@ -314,7 +366,9 @@ uint8_t IRHaierAC::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a standard A/C vertical swing into its native setting. +/// Convert a stdAc::swingv_t enum into it's native setting. +/// @param[in] position The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRHaierAC::convertSwingV(const stdAc::swingv_t position) { switch (position) { case stdAc::swingv_t::kHighest: @@ -327,7 +381,9 @@ uint8_t IRHaierAC::convertSwingV(const stdAc::swingv_t position) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRHaierAC::toCommonMode(const uint8_t mode) { switch (mode) { case kHaierAcCool: return stdAc::opmode_t::kCool; @@ -338,7 +394,9 @@ stdAc::opmode_t IRHaierAC::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRHaierAC::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kHaierAcFanHigh: return stdAc::fanspeed_t::kMax; @@ -348,7 +406,9 @@ stdAc::fanspeed_t IRHaierAC::toCommonFanSpeed(const uint8_t speed) { } } -// Convert a native vertical swing to it's common equivalent. +/// Convert a stdAc::swingv_t enum into it's native setting. +/// @param[in] pos The enum to be converted. +/// @return The native equivilant of the enum. stdAc::swingv_t IRHaierAC::toCommonSwingV(const uint8_t pos) { switch (pos) { case kHaierAcSwingUp: return stdAc::swingv_t::kHighest; @@ -358,7 +418,8 @@ stdAc::swingv_t IRHaierAC::toCommonSwingV(const uint8_t pos) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRHaierAC::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::HAIER_AC; @@ -384,7 +445,8 @@ stdAc::state_t IRHaierAC::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRHaierAC::toString(void) { String result = ""; result.reserve(150); // Reserve some heap for the string to reduce fragging. @@ -469,29 +531,41 @@ String IRHaierAC::toString(void) { } // End of IRHaierAC class. -// Class for emulating a Haier YRW02 remote +/// 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? IRHaierACYRW02::IRHaierACYRW02(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { stateReset(); } +/// Set up hardware to be able to send a message. void IRHaierACYRW02::begin(void) { _irsend.begin(); } #if SEND_HAIER_AC_YRW02 +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRHaierACYRW02::send(const uint16_t repeat) { _irsend.sendHaierACYRW02(getRaw(), kHaierACYRW02StateLength, repeat); } #endif // SEND_HAIER_AC_YRW02 +/// Calculate and set the checksum values for the internal state. void IRHaierACYRW02::checksum(void) { remote_state[kHaierACYRW02StateLength - 1] = sumBytes(remote_state, kHaierACYRW02StateLength - 1); } +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length of the state array. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRHaierACYRW02::validChecksum(uint8_t state[], const uint16_t length) { if (length < 2) return false; // 1 byte of data can't have a checksum. return (state[length - 1] == sumBytes(state, length - 1)); } +/// Reset the internal state to a fixed known good state. void IRHaierACYRW02::stateReset(void) { for (uint8_t i = 1; i < kHaierACYRW02StateLength; i++) remote_state[i] = 0x0; remote_state[0] = kHaierAcYrw02Prefix; @@ -506,15 +580,21 @@ void IRHaierACYRW02::stateReset(void) { setPower(true); } +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t* IRHaierACYRW02::getRaw(void) { checksum(); return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. void IRHaierACYRW02::setRaw(const uint8_t new_code[]) { memcpy(remote_state, new_code, kHaierACYRW02StateLength); } +/// Set the Button/Command setting of the A/C. +/// @param[in] button The value of the button/command that was pressed. void IRHaierACYRW02::setButton(uint8_t button) { switch (button) { case kHaierAcYrw02ButtonTempUp: @@ -530,10 +610,14 @@ void IRHaierACYRW02::setButton(uint8_t button) { } } +/// Get the Button/Command setting of the A/C. +/// @return The value of the button/command that was pressed. uint8_t IRHaierACYRW02::getButton(void) { return GETBITS8(remote_state[12], kLowNibble, kNibbleSize); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRHaierACYRW02::setMode(uint8_t mode) { uint8_t new_mode = mode; setButton(kHaierAcYrw02ButtonMode); @@ -548,10 +632,14 @@ void IRHaierACYRW02::setMode(uint8_t mode) { setBits(&remote_state[7], kHaierAcYrw02ModeOffset, kModeBitsSize, new_mode); } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRHaierACYRW02::getMode(void) { return GETBITS8(remote_state[7], kHaierAcYrw02ModeOffset, kModeBitsSize); } +/// Set the temperature. +/// @param[in] celsius The temperature in degrees celsius. void IRHaierACYRW02::setTemp(const uint8_t celsius) { uint8_t temp = celsius; if (temp < kHaierAcMinTemp) @@ -568,46 +656,68 @@ void IRHaierACYRW02::setTemp(const uint8_t celsius) { setBits(&remote_state[1], kHighNibble, kNibbleSize, temp - kHaierAcMinTemp); } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRHaierACYRW02::getTemp(void) { return GETBITS8(remote_state[1], kHighNibble, kNibbleSize) + kHaierAcMinTemp; } +/// Set the Health (filter) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRHaierACYRW02::setHealth(const bool on) { setButton(kHaierAcYrw02ButtonHealth); setBit(&remote_state[3], kHaierAcYrw02HealthOffset, on); } +/// Get the Health (filter) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRHaierACYRW02::getHealth(void) { return GETBIT8(remote_state[3], kHaierAcYrw02HealthOffset); } +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRHaierACYRW02::getPower(void) { return GETBIT8(remote_state[4], kHaierAcYrw02PowerOffset); } +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRHaierACYRW02::setPower(const bool on) { setButton(kHaierAcYrw02ButtonPower); setBit(&remote_state[4], kHaierAcYrw02PowerOffset, on); } +/// Change the power setting to On. void IRHaierACYRW02::on(void) { setPower(true); } +/// Change the power setting to Off. void IRHaierACYRW02::off(void) { setPower(false); } +/// Get the Sleep setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRHaierACYRW02::getSleep(void) { return GETBIT8(remote_state[8], kHaierAcYrw02SleepOffset); } +/// Set the Sleep setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRHaierACYRW02::setSleep(const bool on) { setButton(kHaierAcYrw02ButtonSleep); setBit(&remote_state[8], kHaierAcYrw02SleepOffset, on); } +/// Get the Turbo setting of the A/C. +/// @return The current turbo speed setting. uint8_t IRHaierACYRW02::getTurbo(void) { return GETBITS8(remote_state[6], kHaierAcYrw02TurboOffset, kHaierAcYrw02TurboSize); } +/// Set the Turbo setting of the A/C. +/// @param[in] speed The desired turbo speed setting. +/// @note Valid speeds are kHaierAcYrw02TurboOff, kHaierAcYrw02TurboLow, & +/// kHaierAcYrw02TurboHigh. void IRHaierACYRW02::setTurbo(uint8_t speed) { switch (speed) { case kHaierAcYrw02TurboOff: @@ -619,11 +729,15 @@ void IRHaierACYRW02::setTurbo(uint8_t speed) { } } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRHaierACYRW02::getFan(void) { return GETBITS8(remote_state[5], kHaierAcYrw02FanOffset, kHaierAcYrw02FanSize); } +/// Set the speed of the fan. +/// @param[in] speed The desired setting. void IRHaierACYRW02::setFan(uint8_t speed) { switch (speed) { case kHaierAcYrw02FanLow: @@ -636,10 +750,14 @@ void IRHaierACYRW02::setFan(uint8_t speed) { } } +/// Get the Vertical Swing position setting of the A/C. +/// @return The native position/mode. uint8_t IRHaierACYRW02::getSwing(void) { return GETBITS8(remote_state[1], kLowNibble, kNibbleSize); } +/// Set the Vertical Swing mode of the A/C. +/// @param[in] pos The position/mode to set the vanes to. void IRHaierACYRW02::setSwing(uint8_t pos) { uint8_t newpos = pos; switch (pos) { @@ -660,7 +778,9 @@ void IRHaierACYRW02::setSwing(uint8_t pos) { setBits(&remote_state[1], kLowNibble, kNibbleSize, newpos); } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRHaierACYRW02::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kHaierAcYrw02Cool; @@ -671,7 +791,9 @@ uint8_t IRHaierACYRW02::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRHaierACYRW02::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: @@ -683,7 +805,9 @@ uint8_t IRHaierACYRW02::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a standard A/C vertical swing into its native setting. +/// Convert a stdAc::swingv_t enum into it's native setting. +/// @param[in] position The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRHaierACYRW02::convertSwingV(const stdAc::swingv_t position) { switch (position) { case stdAc::swingv_t::kHighest: @@ -696,7 +820,9 @@ uint8_t IRHaierACYRW02::convertSwingV(const stdAc::swingv_t position) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRHaierACYRW02::toCommonMode(const uint8_t mode) { switch (mode) { case kHaierAcYrw02Cool: return stdAc::opmode_t::kCool; @@ -707,7 +833,9 @@ stdAc::opmode_t IRHaierACYRW02::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRHaierACYRW02::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kHaierAcYrw02FanHigh: return stdAc::fanspeed_t::kMax; @@ -717,7 +845,9 @@ stdAc::fanspeed_t IRHaierACYRW02::toCommonFanSpeed(const uint8_t speed) { } } -// Convert a native vertical swing to it's common equivalent. +/// Convert a stdAc::swingv_t enum into it's native setting. +/// @param[in] pos The enum to be converted. +/// @return The native equivilant of the enum. stdAc::swingv_t IRHaierACYRW02::toCommonSwingV(const uint8_t pos) { switch (pos) { case kHaierAcYrw02SwingTop: return stdAc::swingv_t::kHighest; @@ -729,7 +859,8 @@ stdAc::swingv_t IRHaierACYRW02::toCommonSwingV(const uint8_t pos) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRHaierACYRW02::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::HAIER_AC_YRW02; @@ -754,7 +885,8 @@ stdAc::state_t IRHaierACYRW02::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRHaierACYRW02::toString(void) { String result = ""; result.reserve(130); // Reserve some heap for the string to reduce fragging. @@ -849,19 +981,15 @@ String IRHaierACYRW02::toString(void) { // End of IRHaierACYRW02 class. #if (DECODE_HAIER_AC || DECODE_HAIER_AC_YRW02) -// Decode the supplied Haier HSU07-HEA03 remote message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kHaierACBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Known to be working. -// +/// Decode the supplied Haier HSU07-HEA03 remote message. +/// Status: STABLE / Known to be 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::decodeHaierAC(decode_results* results, uint16_t offset, const uint16_t nbits, const bool strict) { if (strict) { @@ -899,19 +1027,15 @@ bool IRrecv::decodeHaierAC(decode_results* results, uint16_t offset, #endif // (DECODE_HAIER_AC || DECODE_HAIER_AC_YRW02) #if DECODE_HAIER_AC_YRW02 -// Decode the supplied Haier YR-W02 remote A/C message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kHaierACYRW02Bits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: BETA / Appears to be working. -// +/// Decode the supplied Haier YR-W02 remote A/C message. +/// Status: BETA / Appears to be 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::decodeHaierACYRW02(decode_results* results, uint16_t offset, const uint16_t nbits, const bool strict) { if (strict) { diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Haier.h b/lib/IRremoteESP8266-2.7.8/src/ir_Haier.h similarity index 83% rename from lib/IRremoteESP8266-2.7.5/src/ir_Haier.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Haier.h index 587c4c560..e1dd84e15 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Haier.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Haier.h @@ -1,10 +1,18 @@ // Copyright 2018 crankyoldgit -// The specifics of reverse engineering the protocol details by kuzin2006 +/// @file +/// @brief Support for Haier A/C protocols. +/// The specifics of reverse engineering the protocols details: +/// * HSU07-HEA03 by kuzin2006. +/// * YR-W02/HSU-09HMC203 by non7top. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/404 +/// @see https://www.dropbox.com/s/mecyib3lhdxc8c6/IR%20data%20reverse%20engineering.xlsx?dl=0 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/485 +/// @see https://www.dropbox.com/sh/w0bt7egp0fjger5/AADRFV6Wg4wZskJVdFvzb8Z0a?dl=0&preview=haer2.ods // Supports: -// Brand: Haier, Model: HSU07-HEA03 remote -// Brand: Haier, Model: YR-W02 remote -// Brand: Haier, Model: HSU-09HMC203 A/C +// Brand: Haier, Model: HSU07-HEA03 remote (HAIER_AC) +// Brand: Haier, Model: YR-W02 remote (HAIER_AC_YRW02) +// Brand: Haier, Model: HSU-09HMC203 A/C (HAIER_AC_YRW02) #ifndef IR_HAIER_H_ #define IR_HAIER_H_ @@ -18,12 +26,6 @@ #include "IRsend_test.h" #endif -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/404 -// https://www.dropbox.com/s/mecyib3lhdxc8c6/IR%20data%20reverse%20engineering.xlsx?dl=0 -// https://github.com/crankyoldgit/IRremoteESP8266/issues/485 -// https://www.dropbox.com/sh/w0bt7egp0fjger5/AADRFV6Wg4wZskJVdFvzb8Z0a?dl=0&preview=haer2.ods - // Constants // Haier HSU07-HEA03 remote @@ -210,14 +212,19 @@ const uint8_t kHaierAcYrw02ButtonSleep = 0xB; #define HAIER_AC_YRW02_BUTTON_TURBO kHaierAcYrw02ButtonTurbo #define HAIER_AC_YRW02_BUTTON_SLEEP kHaierAcYrw02ButtonSleep +// Classes +/// Class for handling detailed Haier A/C messages. class IRHaierAC { public: explicit IRHaierAC(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - #if SEND_HAIER_AC void send(const uint16_t repeat = kHaierAcDefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + /// 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_HAIER_AC void begin(void); @@ -265,24 +272,31 @@ class IRHaierAC { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond #endif - uint8_t remote_state[kHaierACStateLength]; + uint8_t remote_state[kHaierACStateLength]; ///< The state in native code form void stateReset(void); void checksum(void); static uint16_t getTime(const uint8_t ptr[]); static void setTime(uint8_t ptr[], const uint16_t nr_mins); }; +/// Class for handling detailed Haier ACYRW02 A/C messages. class IRHaierACYRW02 { public: explicit IRHaierACYRW02(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - #if SEND_HAIER_AC_YRW02 void send(const uint16_t repeat = kHaierAcYrw02DefaultRepeat); + /// 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_HAIER_AC_YRW02 void begin(void); @@ -312,7 +326,7 @@ class IRHaierACYRW02 { void setTurbo(const uint8_t speed); uint8_t getSwing(void); - void setSwing(const uint8_t state); + void setSwing(const uint8_t pos); uint8_t* getRaw(void); void setRaw(const uint8_t new_code[]); @@ -329,13 +343,14 @@ class IRHaierACYRW02 { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - uint8_t remote_state[kHaierACYRW02StateLength]; + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint8_t remote_state[kHaierACYRW02StateLength]; ///< The state in native form void stateReset(void); void checksum(void); }; - #endif // IR_HAIER_H_ diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Hitachi.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Hitachi.cpp similarity index 60% rename from lib/IRremoteESP8266-2.7.5/src/ir_Hitachi.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Hitachi.cpp index 01cc49d28..368f9995a 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Hitachi.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Hitachi.cpp @@ -1,9 +1,12 @@ // Copyright 2018-2019 David Conran -// -// Code to emulate Hitachi protocol compatible devices. -// Should be compatible with: -// * Hitachi RAS-35THA6 remote -// +/// @file +/// @brief Support for Hitachi A/C protocols. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/417 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/453 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/973 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1056 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1060 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1134 #include "ir_Hitachi.h" #include @@ -18,7 +21,6 @@ #include "IRutils.h" // Constants -// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/417 const uint16_t kHitachiAcHdrMark = 3300; const uint16_t kHitachiAcHdrSpace = 1700; const uint16_t kHitachiAc1HdrMark = 3400; @@ -28,7 +30,6 @@ const uint16_t kHitachiAcOneSpace = 1250; const uint16_t kHitachiAcZeroSpace = 500; const uint32_t kHitachiAcMinGap = kDefaultMessageGap; // Just a guess. // Support for HitachiAc424 protocol -// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/973 const uint16_t kHitachiAc424LdrMark = 29784; // Leader const uint16_t kHitachiAc424LdrSpace = 49290; // Leader const uint16_t kHitachiAc424HdrMark = 3416; // Header @@ -38,7 +39,6 @@ const uint16_t kHitachiAc424OneSpace = 1208; const uint16_t kHitachiAc424ZeroSpace = 372; // Support for HitachiAc3 protocol -// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1060 const uint16_t kHitachiAc3HdrMark = 3400; // Header const uint16_t kHitachiAc3HdrSpace = 1660; // Header const uint16_t kHitachiAc3BitMark = 460; @@ -56,45 +56,34 @@ using irutils::minsToString; using irutils::setBit; using irutils::setBits; -#if (SEND_HITACHI_AC || SEND_HITACHI_AC2) -// Send a Hitachi A/C message. -// -// Args: -// data: An array of bytes containing the IR command. -// nbytes: Nr. of bytes of data in the array. (>=kHitachiAcStateLength) -// repeat: Nr. of times the message is to be repeated. (Default = 0). -// -// Status: STABLE / Working. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/417 +#if (SEND_HITACHI_AC || SEND_HITACHI_AC2 || SEND_HITACHI_AC344) +/// Send a Hitachi 28-byte/224-bit A/C formatted message. (HITACHI_AC) +/// Status: STABLE / Working. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/417 void IRsend::sendHitachiAC(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { if (nbytes < kHitachiAcStateLength) return; // Not enough bytes to send a proper message. + + const bool MSBfirst = (nbytes == kHitachiAc344StateLength) ? false : true; sendGeneric(kHitachiAcHdrMark, kHitachiAcHdrSpace, kHitachiAcBitMark, kHitachiAcOneSpace, kHitachiAcBitMark, kHitachiAcZeroSpace, - kHitachiAcBitMark, kHitachiAcMinGap, data, nbytes, 38, true, + kHitachiAcBitMark, kHitachiAcMinGap, data, nbytes, 38, MSBfirst, repeat, 50); } -#endif // (SEND_HITACHI_AC || SEND_HITACHI_AC2) +#endif // (SEND_HITACHI_AC || SEND_HITACHI_AC2 || SEND_HITACHI_AC344) #if SEND_HITACHI_AC1 -// Send a Hitachi A/C 13-byte message. -// -// For devices: -// Hitachi A/C Series VI (Circa 2007) / Remote: LT0541-HTA -// -// Args: -// data: An array of bytes containing the IR command. -// nbytes: Nr. of bytes of data in the array. (>=kHitachiAc1StateLength) -// repeat: Nr. of times the message is to be repeated. (Default = 0). -// -// Status: STABLE / Confirmed Working. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/453 -// Basically the same as sendHitatchiAC() except different size and header. +/// Send a Hitachi 13 byte/224-bit A/C formatted message. (HITACHI_AC1) +/// Status: STABLE / Confirmed Working. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @note Basically the same as sendHitatchiAC() except different size & header. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/453 void IRsend::sendHitachiAC1(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { if (nbytes < kHitachiAc1StateLength) @@ -107,21 +96,12 @@ void IRsend::sendHitachiAC1(const unsigned char data[], const uint16_t nbytes, #endif // SEND_HITACHI_AC1 #if SEND_HITACHI_AC2 -// Send a Hitachi A/C 53-byte message. -// -// For devices: -// Hitachi A/C Series VI (Circa 2007) / Remote: LT0541-HTA -// -// Args: -// data: An array of bytes containing the IR command. -// nbytes: Nr. of bytes of data in the array. (>=kHitachiAc2StateLength) -// repeat: Nr. of times the message is to be repeated. (Default = 0). -// -// Status: STABLE / Expected to work. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/417 -// Basically the same as sendHitatchiAC() except different size. +/// Send a Hitachi 53 byte/424-bit A/C formatted message. (HITACHI_AC2) +/// Basically the same as sendHitatchiAC() except different size. +/// Status: STABLE / Expected to work. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendHitachiAC2(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { if (nbytes < kHitachiAc2StateLength) @@ -130,14 +110,31 @@ void IRsend::sendHitachiAC2(const unsigned char data[], const uint16_t nbytes, } #endif // SEND_HITACHI_AC2 -// Class for handling the remote control on a Hitachi 28 byte A/C message. -// Inspired by: -// https://github.com/ToniA/arduino-heatpumpir/blob/master/HitachiHeatpumpIR.cpp +#if SEND_HITACHI_AC344 +/// Send a Hitachi A/C 43-byte/344-bit message. (HITACHI_AC344) +/// Basically the same as sendHitatchiAC() except different size. +/// Status: Beta / Probably works. +/// @param[in] data An array of bytes containing the IR command. +/// @param[in] nbytes Nr. of bytes of data in the array. +/// @param[in] repeat Nr. of times the message is to be repeated. (Default = 0). +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1134 +void IRsend::sendHitachiAc344(const unsigned char data[], const uint16_t nbytes, + const uint16_t repeat) { + if (nbytes < kHitachiAc344StateLength) + return; // Not enough bytes to send a proper message. + sendHitachiAC(data, nbytes, repeat); +} +#endif // SEND_HITACHI_AC344 +/// 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? IRHitachiAc::IRHitachiAc(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 IRHitachiAc::stateReset(void) { remote_state[0] = 0x80; remote_state[1] = 0x08; @@ -156,8 +153,13 @@ void IRHitachiAc::stateReset(void) { setTemp(23); } +/// Set up hardware to be able to send a message. void IRHitachiAc::begin(void) { _irsend.begin(); } +/// Calculate the checksum for a given state. +/// @param[in] state The value to calc the checksum of. +/// @param[in] length The size/length of the state. +/// @return The calculated checksum value. uint8_t IRHitachiAc::calcChecksum(const uint8_t state[], const uint16_t length) { uint8_t sum = 62; @@ -165,44 +167,67 @@ uint8_t IRHitachiAc::calcChecksum(const uint8_t state[], return reverseBits(sum, 8); } +/// Calculate and set the checksum values for the internal state. +/// @param[in] length The size/length of the state. void IRHitachiAc::checksum(const uint16_t length) { remote_state[length - 1] = calcChecksum(remote_state, length); } +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length of the state array. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRHitachiAc::validChecksum(const uint8_t state[], const uint16_t length) { if (length < 2) return true; // Assume true for lengths that are too short. return (state[length - 1] == calcChecksum(state, length)); } +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t *IRHitachiAc::getRaw(void) { checksum(); return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. +/// @param[in] length The length of the new_code array. void IRHitachiAc::setRaw(const uint8_t new_code[], const uint16_t length) { memcpy(remote_state, new_code, std::min(length, kHitachiAcStateLength)); } #if SEND_HITACHI_AC +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRHitachiAc::send(const uint16_t repeat) { _irsend.sendHitachiAC(getRaw(), kHitachiAcStateLength, repeat); } #endif // SEND_HITACHI_AC +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRHitachiAc::getPower(void) { return GETBIT8(remote_state[17], kHitachiAcPowerOffset); } +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRHitachiAc::setPower(const bool on) { setBit(&remote_state[17], kHitachiAcPowerOffset, on); } +/// Change the power setting to On. void IRHitachiAc::on(void) { setPower(true); } +/// Change the power setting to Off. void IRHitachiAc::off(void) { setPower(false); } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRHitachiAc::getMode(void) { return reverseBits(remote_state[10], 8); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRHitachiAc::setMode(const uint8_t mode) { uint8_t newmode = mode; switch (mode) { @@ -219,10 +244,14 @@ void IRHitachiAc::setMode(const uint8_t mode) { setFan(getFan()); // Reset the fan speed after the mode change. } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRHitachiAc::getTemp(void) { return reverseBits(remote_state[11], 8) >> 1; } +/// Set the temperature. +/// @param[in] celsius The temperature in degrees celsius. void IRHitachiAc::setTemp(const uint8_t celsius) { uint8_t temp; if (celsius != 64) _previoustemp = celsius; @@ -241,8 +270,12 @@ void IRHitachiAc::setTemp(const uint8_t celsius) { remote_state[9] = 0x10; } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRHitachiAc::getFan(void) { return reverseBits(remote_state[13], 8); } +/// Set the speed of the fan. +/// @param[in] speed The desired setting. void IRHitachiAc::setFan(const uint8_t speed) { uint8_t fanmin = kHitachiAcFanAuto; uint8_t fanmax = kHitachiAcFanHigh; @@ -260,23 +293,33 @@ void IRHitachiAc::setFan(const uint8_t speed) { remote_state[13] = reverseBits(newspeed, 8); } +/// Get the Vertical Swing setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRHitachiAc::getSwingVertical(void) { return GETBIT8(remote_state[14], kHitachiAcSwingOffset); } +/// Set the Vertical Swing setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRHitachiAc::setSwingVertical(const bool on) { setBit(&remote_state[14], kHitachiAcSwingOffset, on); } +/// Get the Horizontal Swing setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRHitachiAc::getSwingHorizontal(void) { return GETBIT8(remote_state[15], kHitachiAcSwingOffset); } +/// Set the Horizontal Swing setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRHitachiAc::setSwingHorizontal(const bool on) { setBit(&remote_state[15], kHitachiAcSwingOffset, on); } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRHitachiAc::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kHitachiAcCool; @@ -287,7 +330,9 @@ uint8_t IRHitachiAc::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRHitachiAc::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: @@ -299,7 +344,9 @@ uint8_t IRHitachiAc::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRHitachiAc::toCommonMode(const uint8_t mode) { switch (mode) { case kHitachiAcCool: return stdAc::opmode_t::kCool; @@ -310,7 +357,9 @@ stdAc::opmode_t IRHitachiAc::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRHitachiAc::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kHitachiAcFanHigh: return stdAc::fanspeed_t::kMax; @@ -321,7 +370,8 @@ stdAc::fanspeed_t IRHitachiAc::toCommonFanSpeed(const uint8_t speed) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRHitachiAc::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::HITACHI_AC; @@ -348,7 +398,8 @@ stdAc::state_t IRHitachiAc::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRHitachiAc::toString(void) { String result = ""; result.reserve(110); // Reserve some heap for the string to reduce fragging. @@ -364,14 +415,15 @@ String IRHitachiAc::toString(void) { return result; } -// Class for handling the remote control on a Hitachi 13 byte A/C message. -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/1056 - +/// 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? IRHitachiAc1::IRHitachiAc1(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 IRHitachiAc1::stateReset(void) { for (uint8_t i = 0; i < kHitachiAc1StateLength; i++) remote_state[i] = 0x00; // Copy in a known good state. @@ -386,8 +438,13 @@ void IRHitachiAc1::stateReset(void) { remote_state[12] = 0x24; } +/// Set up hardware to be able to send a message. void IRHitachiAc1::begin(void) { _irsend.begin(); } +/// Calculate the checksum for a given state. +/// @param[in] state The value to calc the checksum of. +/// @param[in] length The size/length of the state. +/// @return The calculated checksum value. uint8_t IRHitachiAc1::calcChecksum(const uint8_t state[], const uint16_t length) { uint8_t sum = 0; @@ -400,25 +457,38 @@ uint8_t IRHitachiAc1::calcChecksum(const uint8_t state[], return reverseBits(sum, 8); } +/// Calculate and set the checksum values for the internal state. +/// @param[in] length The size/length of the state. void IRHitachiAc1::checksum(const uint16_t length) { remote_state[length - 1] = calcChecksum(remote_state, length); } +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length of the state array. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRHitachiAc1::validChecksum(const uint8_t state[], const uint16_t length) { if (length < 2) return true; // Assume true for lengths that are too short. return (state[length - 1] == calcChecksum(state, length)); } +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t *IRHitachiAc1::getRaw(void) { checksum(); return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. +/// @param[in] length The length of the new_code array. void IRHitachiAc1::setRaw(const uint8_t new_code[], const uint16_t length) { memcpy(remote_state, new_code, std::min(length, kHitachiAc1StateLength)); } #if SEND_HITACHI_AC +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRHitachiAc1::send(const uint16_t repeat) { _irsend.sendHitachiAC1(getRaw(), kHitachiAc1StateLength, repeat); // Clear the toggle bits as we have actioned them by sending them. @@ -427,6 +497,8 @@ void IRHitachiAc1::send(const uint16_t repeat) { } #endif // SEND_HITACHI_AC +/// Get/Detect the model of the A/C. +/// @return The enum of the compatible model. hitachi_ac1_remote_model_t IRHitachiAc1::getModel(void) { switch (GETBITS8(remote_state[kHitachiAc1ModelByte], kHitachiAc1ModelOffset, kHitachiAc1ModelSize)) { @@ -435,6 +507,8 @@ hitachi_ac1_remote_model_t IRHitachiAc1::getModel(void) { } } +/// Set the model of the A/C to emulate. +/// @param[in] model The enum of the appropriate model. void IRHitachiAc1::setModel(const hitachi_ac1_remote_model_t model) { uint8_t value = 0; switch (model) { @@ -448,34 +522,48 @@ void IRHitachiAc1::setModel(const hitachi_ac1_remote_model_t model) { kHitachiAc1ModelSize, value); } +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRHitachiAc1::getPower(void) { return GETBIT8(remote_state[kHitachiAc1PowerByte], kHitachiAc1PowerOffset); } +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRHitachiAc1::setPower(const bool on) { // If the power changes, set the power toggle bit. if (on != getPower()) setPowerToggle(true); setBit(&remote_state[kHitachiAc1PowerByte], kHitachiAc1PowerOffset, on); } +/// Get the value of the current power toggle setting. +/// @return true, the setting is on. false, the setting is off. bool IRHitachiAc1::getPowerToggle(void) { return GETBIT8(remote_state[kHitachiAc1PowerByte], kHitachiAc1PowerToggleOffset); } +/// Change the power toggle setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRHitachiAc1::setPowerToggle(const bool on) { setBit(&remote_state[kHitachiAc1PowerByte], kHitachiAc1PowerToggleOffset, on); } +/// Change the power setting to On. void IRHitachiAc1::on(void) { setPower(true); } +/// Change the power setting to Off. void IRHitachiAc1::off(void) { setPower(false); } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRHitachiAc1::getMode(void) { return GETBITS8(remote_state[kHitachiAc1ModeByte], kHitachiAc1ModeOffset, kHitachiAc1ModeSize); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRHitachiAc1::setMode(const uint8_t mode) { switch (mode) { case kHitachiAc1Auto: @@ -500,12 +588,16 @@ void IRHitachiAc1::setMode(const uint8_t mode) { } } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRHitachiAc1::getTemp(void) { return reverseBits(GETBITS8(remote_state[kHitachiAc1TempByte], kHitachiAc1TempOffset, kHitachiAc1TempSize), kHitachiAc1TempSize) + kHitachiAc1TempDelta; } +/// Set the temperature. +/// @param[in] celsius The temperature in degrees celsius. void IRHitachiAc1::setTemp(const uint8_t celsius) { if (getMode() == kHitachiAc1Auto) return; // Can't change temp in Auto mode. uint8_t temp = std::min(celsius, kHitachiAcMaxTemp); @@ -516,11 +608,16 @@ void IRHitachiAc1::setTemp(const uint8_t celsius) { kHitachiAc1TempSize, temp); } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRHitachiAc1::getFan(void) { return GETBITS8(remote_state[kHitachiAc1FanByte], kHitachiAc1FanOffset, kHitachiAc1FanSize); } +/// Set the speed of the fan. +/// @param[in] speed The desired setting. +/// @param[in] force Do we allow setting the speed regardless of restrictions? void IRHitachiAc1::setFan(const uint8_t speed, const bool force) { if (!force) { switch (getMode()) { @@ -549,39 +646,56 @@ void IRHitachiAc1::setFan(const uint8_t speed, const bool force) { } } +/// Get the Swing Toggle setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRHitachiAc1::getSwingToggle(void) { return GETBIT8(remote_state[kHitachiAc1SwingByte], kHitachiAc1SwingToggleOffset); } +/// Set the Swing toggle setting of the A/C. +/// @param[in] toggle true, the setting is on. false, the setting is off. void IRHitachiAc1::setSwingToggle(const bool toggle) { setBit(&remote_state[kHitachiAc1SwingByte], kHitachiAc1SwingToggleOffset, toggle); } +/// Get the Vertical Swing setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRHitachiAc1::getSwingV(void) { return GETBIT8(remote_state[kHitachiAc1SwingByte], kHitachiAc1SwingVOffset); } +/// Set the Vertical Swing setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRHitachiAc1::setSwingV(const bool on) { setBit(&remote_state[kHitachiAc1SwingByte], kHitachiAc1SwingVOffset, on); } +/// Get the Horizontal Swing setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRHitachiAc1::getSwingH(void) { return GETBIT8(remote_state[kHitachiAc1SwingByte], kHitachiAc1SwingHOffset); } +/// Set the Horizontal Swing setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRHitachiAc1::setSwingH(const bool on) { setBit(&remote_state[kHitachiAc1SwingByte], kHitachiAc1SwingHOffset, on); } +/// Get the Sleep setting of the A/C. +/// @return The currently configured sleep mode. +/// @note Sleep modes only available in Auto & Cool modes, otherwise it's off. uint8_t IRHitachiAc1::getSleep(void) { return GETBITS8(remote_state[kHitachiAc1SleepByte], kHitachiAc1SleepOffset, kHitachiAc1SleepSize); } +/// Set the Sleep setting of the A/C. +/// @param[in] mode The mode of sleep to set the A/C to. +/// @note Sleep modes only available in Auto & Cool modes, otherwise it's off. void IRHitachiAc1::setSleep(const uint8_t mode) { - // Sleep modes only available in Auto & Cool modes, otherwise it's off. switch (getMode()) { case kHitachiAc1Auto: case kHitachiAc1Cool: @@ -594,31 +708,41 @@ void IRHitachiAc1::setSleep(const uint8_t mode) { } } +/// Set the On Timer time. +/// @param[in] mins The time expressed in total number of minutes. void IRHitachiAc1::setOnTimer(const uint16_t mins) { const uint16_t mins_lsb = reverseBits(mins, kHitachiAc1TimerSize); remote_state[kHitachiAc1OnTimerLowByte] = GETBITS16(mins_lsb, 8, 8); remote_state[kHitachiAc1OnTimerHighByte] = GETBITS16(mins_lsb, 0, 8); } +/// Get the On Timer vtime of the A/C. +/// @return Nr of minutes the timer is set to. uint16_t IRHitachiAc1::getOnTimer(void) { return reverseBits( (remote_state[kHitachiAc1OnTimerLowByte] << 8) | remote_state[kHitachiAc1OnTimerHighByte], kHitachiAc1TimerSize); } +/// Set the Off Timer time. +/// @param[in] mins The time expressed in total number of minutes. void IRHitachiAc1::setOffTimer(const uint16_t mins) { const uint16_t mins_lsb = reverseBits(mins, kHitachiAc1TimerSize); remote_state[kHitachiAc1OffTimerLowByte] = GETBITS16(mins_lsb, 8, 8); remote_state[kHitachiAc1OffTimerHighByte] = GETBITS16(mins_lsb, 0, 8); } +/// Get the Off Timer vtime of the A/C. +/// @return Nr of minutes the timer is set to. uint16_t IRHitachiAc1::getOffTimer(void) { return reverseBits( (remote_state[kHitachiAc1OffTimerLowByte] << 8) | remote_state[kHitachiAc1OffTimerHighByte], kHitachiAc1TimerSize); } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRHitachiAc1::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kHitachiAc1Cool; @@ -629,7 +753,9 @@ uint8_t IRHitachiAc1::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRHitachiAc1::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: @@ -641,7 +767,9 @@ uint8_t IRHitachiAc1::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRHitachiAc1::toCommonMode(const uint8_t mode) { switch (mode) { case kHitachiAc1Cool: return stdAc::opmode_t::kCool; @@ -652,7 +780,9 @@ stdAc::opmode_t IRHitachiAc1::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRHitachiAc1::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kHitachiAc1FanHigh: return stdAc::fanspeed_t::kMax; @@ -662,7 +792,8 @@ stdAc::fanspeed_t IRHitachiAc1::toCommonFanSpeed(const uint8_t speed) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRHitachiAc1::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::HITACHI_AC1; @@ -689,7 +820,8 @@ stdAc::state_t IRHitachiAc1::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRHitachiAc1::toString(void) { String result = ""; result.reserve(170); // Reserve some heap for the string to reduce fragging. @@ -716,29 +848,26 @@ String IRHitachiAc1::toString(void) { return result; } -#if (DECODE_HITACHI_AC || DECODE_HITACHI_AC1 || DECODE_HITACHI_AC2) -// Decode the supplied Hitachi A/C message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. -// Typically kHitachiAcBits, kHitachiAc1Bits, kHitachiAc2Bits -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Expected to work. -// -// Supported devices: -// Hitachi A/C Series VI (Circa 2007) / Remote: LT0541-HTA -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/417 -// https://github.com/crankyoldgit/IRremoteESP8266/issues/453 +#if (DECODE_HITACHI_AC || DECODE_HITACHI_AC1 || DECODE_HITACHI_AC2 || \ + DECODE_HITACHI_AC344) +/// Decode the supplied Hitachi A/C message. +/// Status: STABLE / Expected to work. +/// @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. +/// Typically kHitachiAcBits, kHitachiAc1Bits, kHitachiAc2Bits, +/// kHitachiAc344Bits +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @param[in] MSBfirst Is the data per byte stored in MSB First (true) or +/// LSB First order(false)? +/// @return True if it can decode it, false if it can't. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/417 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/453 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1134 bool IRrecv::decodeHitachiAC(decode_results *results, uint16_t offset, - const uint16_t nbits, const bool strict) { + const uint16_t nbits, const bool strict, + const bool MSBfirst) { const uint8_t k_tolerance = _tolerance + 5; if (strict) { @@ -746,6 +875,7 @@ bool IRrecv::decodeHitachiAC(decode_results *results, uint16_t offset, case kHitachiAcBits: case kHitachiAc1Bits: case kHitachiAc2Bits: + case kHitachiAc344Bits: break; // Okay to continue. default: return false; // Not strictly a Hitachi message. @@ -767,7 +897,7 @@ bool IRrecv::decodeHitachiAC(decode_results *results, uint16_t offset, kHitachiAcBitMark, kHitachiAcOneSpace, kHitachiAcBitMark, kHitachiAcZeroSpace, kHitachiAcBitMark, kHitachiAcMinGap, true, - k_tolerance)) return false; + k_tolerance, kMarkExcess, MSBfirst)) return false; // Compliance if (strict) { @@ -777,19 +907,26 @@ bool IRrecv::decodeHitachiAC(decode_results *results, uint16_t offset, if (nbits / 8 == kHitachiAc1StateLength && !IRHitachiAc1::validChecksum(results->state, kHitachiAc1StateLength)) return false; + if (nbits / 8 == kHitachiAc344StateLength && + !IRHitachiAc3::hasInvertedStates(results->state, + kHitachiAc344StateLength)) + return false; } // Success switch (nbits) { case kHitachiAc1Bits: - results->decode_type = HITACHI_AC1; + results->decode_type = decode_type_t::HITACHI_AC1; break; case kHitachiAc2Bits: - results->decode_type = HITACHI_AC2; + results->decode_type = decode_type_t::HITACHI_AC2; + break; + case kHitachiAc344Bits: + results->decode_type = decode_type_t::HITACHI_AC344; break; case kHitachiAcBits: default: - results->decode_type = HITACHI_AC; + results->decode_type = decode_type_t::HITACHI_AC; } results->bits = nbits; // No need to record the state as we stored it as we decoded it. @@ -797,22 +934,18 @@ bool IRrecv::decodeHitachiAC(decode_results *results, uint16_t offset, // is a union data type. return true; } -#endif // (DECODE_HITACHI_AC || DECODE_HITACHI_AC1 || DECODE_HITACHI_AC2) +#endif // (DECODE_HITACHI_AC || DECODE_HITACHI_AC1 || DECODE_HITACHI_AC2 || + // DECODE_HITACHI_AC344) #if SEND_HITACHI_AC424 -// Send HITACHI_AC424 messages -// -// Note: This protocol is almost exactly the same as HitachiAC2 except this -// variant has a leader section as well, and subtle timing differences. -// It is also in LSBF order (per byte), rather than MSBF order. -// -// Args: -// data: An array of bytes containing the IR command. -// It is assumed to be in LSBF order for this code. -// nbytes: Nr. of bytes of data in the array. (>=kHitachiAc424StateLength) -// repeat: Nr. of times the message is to be repeated. -// -// Status: STABLE / Reported as working. +/// Send a Hitachi 53-byte/424-bit A/C formatted message. (HITACHI_AC424) +/// Status: STABLE / Reported as working. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @note This protocol is almost exactly the same as HitachiAC2 except this +/// variant has a leader section as well, and subtle timing differences. +/// It is also in LSBF order (per byte), rather than MSBF order. void IRsend::sendHitachiAc424(const uint8_t data[], const uint16_t nbytes, const uint16_t repeat) { enableIROut(kHitachiAcFreq); @@ -832,30 +965,19 @@ void IRsend::sendHitachiAc424(const uint8_t data[], const uint16_t nbytes, #endif // SEND_HITACHI_AC424 #if DECODE_HITACHI_AC424 -// Decode the supplied Hitachi 424 bit A/C message. -// -// Note: This protocol is almost exactly the same as HitachiAC2 except this -// variant has a leader section as well, and subtle timing differences. -// It is also in LSBF order (per byte), rather than MSBF order. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kHitachiAc424Bits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Reported as working. -// -// Supported devices: -// Hitachi Shirokumakun / AC Model: RAS-AJ25H / AC Remote Model: RAR-8P2 -// Manual (Japanese): -// https://kadenfan.hitachi.co.jp/support/raj/item/docs/ras_aj22h_a_tori.pdf -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/973 +/// Decode the supplied Hitachi 53-byte/424-bit A/C message. +/// Status: STABLE / Reported as working. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @note This protocol is almost exactly the same as HitachiAC2 except this +/// variant has a leader section as well, and subtle timing differences. +/// It is also in LSBF order (per byte), rather than MSBF order. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/973 +/// @see (Japanese Manual) https://kadenfan.hitachi.co.jp/support/raj/item/docs/ras_aj22h_a_tori.pdf bool IRrecv::decodeHitachiAc424(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { @@ -889,12 +1011,16 @@ bool IRrecv::decodeHitachiAc424(decode_results *results, uint16_t offset, } #endif // DECODE_HITACHI_AC424 -// Class for handling the remote control on a Hitachi_AC424 53 byte A/C message +/// 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? IRHitachiAc424::IRHitachiAc424(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { stateReset(); } -// Reset to auto fan, cooling, 23° Celcius +/// Reset the internal state to a fixed known good state. +/// @note Reset to auto fan, cooling, 23° Celsius void IRHitachiAc424::stateReset(void) { for (uint8_t i = 0; i < kHitachiAc424StateLength; i++) remote_state[i] = 0x00; @@ -919,46 +1045,65 @@ void IRHitachiAc424::stateReset(void) { setFan(kHitachiAc424FanAuto); } +/// Update the internal consistency check for the protocol. void IRHitachiAc424::setInvertedStates(void) { for (uint8_t i = 3; i < kHitachiAc424StateLength - 1; i += 2) remote_state[i + 1] = ~remote_state[i]; } +/// Set up hardware to be able to send a message. void IRHitachiAc424::begin(void) { _irsend.begin(); } +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t *IRHitachiAc424::getRaw(void) { setInvertedStates(); return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. +/// @param[in] length The length of the new_code array. void IRHitachiAc424::setRaw(const uint8_t new_code[], const uint16_t length) { memcpy(remote_state, new_code, std::min(length, kHitachiAc424StateLength)); } #if SEND_HITACHI_AC424 +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRHitachiAc424::send(const uint16_t repeat) { _irsend.sendHitachiAc424(getRaw(), kHitachiAc424StateLength, repeat); } #endif // SEND_HITACHI_AC424 +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRHitachiAc424::getPower(void) { return remote_state[kHitachiAc424PowerByte] == kHitachiAc424PowerOn; } +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRHitachiAc424::setPower(const bool on) { setButton(kHitachiAc424ButtonPowerMode); remote_state[kHitachiAc424PowerByte] = on ? kHitachiAc424PowerOn : kHitachiAc424PowerOff; } +/// Change the power setting to On. void IRHitachiAc424::on(void) { setPower(true); } +/// Change the power setting to Off. void IRHitachiAc424::off(void) { setPower(false); } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRHitachiAc424::getMode(void) { return GETBITS8(remote_state[kHitachiAc424ModeByte], kLowNibble, kNibbleSize); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRHitachiAc424::setMode(const uint8_t mode) { uint8_t newMode = mode; switch (mode) { @@ -976,11 +1121,16 @@ void IRHitachiAc424::setMode(const uint8_t mode) { setButton(kHitachiAc424ButtonPowerMode); } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRHitachiAc424::getTemp(void) { return GETBITS8(remote_state[kHitachiAc424TempByte], kHitachiAc424TempOffset, kHitachiAc424TempSize); } +/// Set the temperature. +/// @param[in] celsius The temperature in degrees celsius. +/// @param[in] setPrevious true, remember this if we change mode. false, don't. void IRHitachiAc424::setTemp(const uint8_t celsius, bool setPrevious) { uint8_t temp; temp = std::min(celsius, kHitachiAc424MaxTemp); @@ -994,10 +1144,14 @@ void IRHitachiAc424::setTemp(const uint8_t celsius, bool setPrevious) { if (setPrevious) _previoustemp = temp; } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRHitachiAc424::getFan(void) { return GETBITS8(remote_state[kHitachiAc424FanByte], kHighNibble, kNibbleSize); } +/// Set the speed of the fan. +/// @param[in] speed The desired setting. void IRHitachiAc424::setFan(const uint8_t speed) { uint8_t newSpeed = std::max(speed, kHitachiAc424FanMin); uint8_t fanMax = kHitachiAc424FanMax; @@ -1029,17 +1183,22 @@ void IRHitachiAc424::setFan(const uint8_t speed) { } } +/// Get the Button/Command setting of the A/C. +/// @return The value of the button/command that was pressed. uint8_t IRHitachiAc424::getButton(void) { return remote_state[kHitachiAc424ButtonByte]; } -// The remote sends the type of button pressed on send +/// Set the Button/Command pressed setting of the A/C. +/// @param[in] button The value of the button/command that was pressed. void IRHitachiAc424::setButton(const uint8_t button) { remote_state[kHitachiAc424ButtonByte] = button; } -// The remote does not keep state of the vertical swing. -// A byte is sent indicating the swing button is pressed on the remote +/// Set the Vertical Swing toggle setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. +/// @note The remote does not keep state of the vertical swing. +/// A byte is sent indicating the swing button is pressed on the remote void IRHitachiAc424::setSwingVToggle(const bool on) { uint8_t button = getButton(); // Get the current button value. if (on) @@ -1050,11 +1209,15 @@ void IRHitachiAc424::setSwingVToggle(const bool on) { setButton(button); } +/// Get the Vertical Swing toggle setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRHitachiAc424::getSwingVToggle(void) { return getButton() == kHitachiAc424ButtonSwingV; } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRHitachiAc424::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kHitachiAc424Cool; @@ -1065,7 +1228,9 @@ uint8_t IRHitachiAc424::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRHitachiAc424::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: return kHitachiAc424FanMin; @@ -1077,7 +1242,9 @@ uint8_t IRHitachiAc424::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRHitachiAc424::toCommonMode(const uint8_t mode) { switch (mode) { case kHitachiAc424Cool: return stdAc::opmode_t::kCool; @@ -1088,7 +1255,9 @@ stdAc::opmode_t IRHitachiAc424::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRHitachiAc424::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kHitachiAc424FanMax: return stdAc::fanspeed_t::kMax; @@ -1100,7 +1269,8 @@ stdAc::fanspeed_t IRHitachiAc424::toCommonFanSpeed(const uint8_t speed) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRHitachiAc424::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::HITACHI_AC424; @@ -1126,8 +1296,10 @@ stdAc::state_t IRHitachiAc424::toCommon(void) { return result; } -// Convert the internal state into a human readable string. -String IRHitachiAc424::toString(void) { +/// Convert the internal state into a human readable string for the settings +/// that are common to protocols of this nature. +/// @return A string containing the common settings in human-readable form. +String IRHitachiAc424::_toString(void) { String result = ""; result.reserve(100); // Reserve some heap for the string to reduce fragging. result += addBoolToString(getPower(), kPowerStr, false); @@ -1147,7 +1319,6 @@ String IRHitachiAc424::toString(void) { default: result += kUnknownStr; } result += ')'; - result += addBoolToString(getSwingVToggle(), kSwingVToggleStr); result += addIntToString(getButton(), kButtonStr); result += kSpaceLBraceStr; switch (getButton()) { @@ -1158,6 +1329,7 @@ String IRHitachiAc424::toString(void) { break; case kHitachiAc424ButtonFan: result += kFanStr; break; case kHitachiAc424ButtonSwingV: result += kSwingVStr; break; + case kHitachiAc344ButtonSwingH: result += kSwingHStr; break; case kHitachiAc424ButtonTempDown: result += kTempDownStr; break; case kHitachiAc424ButtonTempUp: result += kTempUpStr; break; default: result += kUnknownStr; @@ -1166,26 +1338,26 @@ String IRHitachiAc424::toString(void) { return result; } +/// Convert the internal state into a human readable string. +/// @return A string containing the settings in human-readable form. +String IRHitachiAc424::toString(void) { + return _toString() + addBoolToString(getSwingVToggle(), kSwingVToggleStr); +} + #if SEND_HITACHI_AC3 -// Send HITACHI_AC3 messages -// -// Note: This protocol is almost exactly the same as HitachiAC424 except this -// variant has subtle timing differences. -// There are five(5) typical sizes: -// * kHitachiAc3MinStateLength (Cancel Timer) -// * kHitachiAc3MinStateLength + 2 (Change Temp) -// * kHitachiAc3StateLength - 6 (Change Mode) -// * kHitachiAc3StateLength- 4 (Normal) -// * kHitachiAc3StateLength (Set Timer) -// -// Args: -// data: An array of bytes containing the IR command. -// It is assumed to be in LSBF order for this code. -// nbytes: Nr. of bytes of data in the array. -// repeat: Nr. of times the message is to be repeated. -// -// Status: STABLE / Working fine. +/// Send a Hitachi(3) A/C formatted message. (HITACHI_AC3) +/// Status: STABLE / Working fine. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @note This protocol is almost exactly the same as HitachiAC424 except this +/// variant has subtle timing differences. There are five(5) typical sizes: +/// kHitachiAc3MinStateLength (Cancel Timer), +/// kHitachiAc3MinStateLength + 2 (Change Temp), +/// kHitachiAc3StateLength - 6 (Change Mode), +/// kHitachiAc3StateLength - 4 (Normal), & +/// kHitachiAc3StateLength (Set Timer) void IRsend::sendHitachiAc3(const uint8_t data[], const uint16_t nbytes, const uint16_t repeat) { // Header + Data + Footer @@ -1199,12 +1371,16 @@ void IRsend::sendHitachiAc3(const uint8_t data[], const uint16_t nbytes, #endif // SEND_HITACHI_AC3 -// Class for handling the remote control on a Hitachi_AC3 53 A/C message +/// 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? IRHitachiAc3::IRHitachiAc3(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { stateReset(); } -// Reset to auto fan, cooling, 23° Celcius +/// Reset the internal state to a fixed known good state. +/// @note Reset to auto fan, cooling, 23° Celsius void IRHitachiAc3::stateReset(void) { for (uint8_t i = 0; i < kHitachiAc3StateLength; i++) remote_state[i] = 0x00; @@ -1222,11 +1398,19 @@ void IRHitachiAc3::stateReset(void) { setInvertedStates(); } +/// Invert every second byte of the internal state, after the fixed header. +/// @param[in] length The size of the state array. +/// @note This is this protocols integrity check. void IRHitachiAc3::setInvertedStates(const uint16_t length) { for (uint8_t i = 3; i < length - 1; i += 2) remote_state[i + 1] = ~remote_state[i]; } +/// Check if every second byte of the state, after the fixed header +/// is inverted to the previous byte. +/// @param[in] state The state array to be checked. +/// @param[in] length The size of the state array. +/// @note This is this protocols integrity check. bool IRHitachiAc3::hasInvertedStates(const uint8_t state[], const uint16_t length) { for (uint8_t i = 3; i < length - 1; i += 2) @@ -1234,39 +1418,41 @@ bool IRHitachiAc3::hasInvertedStates(const uint8_t state[], return true; } +/// Set up hardware to be able to send a message. void IRHitachiAc3::begin(void) { _irsend.begin(); } +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t *IRHitachiAc3::getRaw(void) { setInvertedStates(); return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. +/// @param[in] length The length of the new_code array. void IRHitachiAc3::setRaw(const uint8_t new_code[], const uint16_t length) { memcpy(remote_state, new_code, std::min(length, kHitachiAc3StateLength)); } #if DECODE_HITACHI_AC3 -// Decode the supplied HitachiAc3 A/C message. -// -// Note: This protocol is almost exactly the same as HitachiAC424 except this -// variant has subtle timing differences and multiple lengths. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kHitachiAc3Bits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Works fine. -// -// Supported devices: -// Hitachi PC-LH3B -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/1060 +/// Decode the supplied Hitachi 15to27-byte/120to216-bit A/C message. +/// Status: STABLE / Works fine. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @note This protocol is almost exactly the same as HitachiAC424 except this +/// variant has subtle timing differences and multiple lengths. +/// There are five(5) typical lengths: +/// kHitachiAc3MinStateLength (Cancel Timer), +/// kHitachiAc3MinStateLength + 2 (Change Temp), +/// kHitachiAc3StateLength - 6 (Change Mode), +/// kHitachiAc3StateLength - 4 (Normal), & +/// kHitachiAc3StateLength (Set Timer) +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1060 bool IRrecv::decodeHitachiAc3(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { @@ -1304,3 +1490,124 @@ bool IRrecv::decodeHitachiAc3(decode_results *results, uint16_t offset, return true; } #endif // DECODE_HITACHI_AC3 + +/// Class constructor for handling detailed Hitachi_AC344 43 byte A/C messages. +/// @param[in] pin GPIO to be used when sending. +/// @param[in] inverted Is the output signal to be inverted? +/// @param[in] use_modulation Is frequency modulation to be used? +IRHitachiAc344::IRHitachiAc344(const uint16_t pin, const bool inverted, + const bool use_modulation) + : IRHitachiAc424(pin, inverted, use_modulation) { stateReset(); } + +/// Reset the internal state to auto fan, cooling, 23° Celsius +void IRHitachiAc344::stateReset(void) { + IRHitachiAc424::stateReset(); + remote_state[37] = 0x00; + remote_state[39] = 0x00; +} + +#if SEND_HITACHI_AC344 +/// Create and send the IR message to the A/C. +/// @param[in] repeat Nr. of times to repeat the message. +void IRHitachiAc344::send(const uint16_t repeat) { + _irsend.sendHitachiAc344(getRaw(), kHitachiAc344StateLength, repeat); +} +#endif // SEND_HITACHI_AC344 + +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. +/// @param[in] length Size (in bytes) of the code for this protocol. +void IRHitachiAc344::setRaw(const uint8_t new_code[], const uint16_t length) { + memcpy(remote_state, new_code, std::min(length, kHitachiAc344StateLength)); +} + +/// Control the vertical swing setting. +/// @param[in] on True, turns on the feature. False, turns off the feature. +void IRHitachiAc344::setSwingV(const bool on) { + setSwingVToggle(on); // Set the button value. + setBit(&remote_state[kHitachiAc344SwingVByte], kHitachiAc344SwingVOffset, on); +} + +/// Get the current vertical swing setting. +/// @return True, if the setting is on. False, it is off. +bool IRHitachiAc344::getSwingV(void) { + return GETBIT8(remote_state[kHitachiAc344SwingVByte], + kHitachiAc344SwingVOffset); +} + +/// Control the horizontal swing setting. +/// @param[in] position The position to set the horizontal swing to. +void IRHitachiAc344::setSwingH(const uint8_t position) { + if (position > kHitachiAc344SwingHLeftMax) + return setSwingH(kHitachiAc344SwingHMiddle); + setBits(&remote_state[kHitachiAc344SwingHByte], kHitachiAc344SwingHOffset, + kHitachiAc344SwingHSize, position); + setButton(kHitachiAc344ButtonSwingH); +} + +/// Get the current horizontal swing setting. +/// @return The current position horizontal swing is set to. +uint8_t IRHitachiAc344::getSwingH(void) { + return GETBITS8(remote_state[kHitachiAc344SwingHByte], + kHitachiAc344SwingHOffset, kHitachiAc344SwingHSize); +} + +/// Convert a standard A/C horizontal swing into its native setting. +/// @param[in] position A stdAc::swingh_t position to convert. +/// @return The equivilent native horizontal swing position. +uint8_t IRHitachiAc344::convertSwingH(const stdAc::swingh_t position) { + switch (position) { + case stdAc::swingh_t::kAuto: return kHitachiAc344SwingHAuto; + case stdAc::swingh_t::kLeftMax: return kHitachiAc344SwingHLeftMax; + case stdAc::swingh_t::kLeft: return kHitachiAc344SwingHLeft; + case stdAc::swingh_t::kRight: return kHitachiAc344SwingHRight; + case stdAc::swingh_t::kRightMax: return kHitachiAc344SwingHRightMax; + default: return kHitachiAc344SwingHMiddle; + } +} + +/// Convert a native horizontal swing postion to it's common equivalent. +/// @param[in] pos A native position to convert. +/// @return The common horizontal swing position. +stdAc::swingh_t IRHitachiAc344::toCommonSwingH(const uint8_t pos) { + switch (pos) { + case kHitachiAc344SwingHLeftMax: return stdAc::swingh_t::kLeftMax; + case kHitachiAc344SwingHLeft: return stdAc::swingh_t::kLeft; + case kHitachiAc344SwingHRight: return stdAc::swingh_t::kRight; + case kHitachiAc344SwingHRightMax: return stdAc::swingh_t::kRightMax; + case kHitachiAc344SwingHAuto: return stdAc::swingh_t::kAuto; + default: return stdAc::swingh_t::kOff; + } +} + +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. +stdAc::state_t IRHitachiAc344::toCommon(void) { + stdAc::state_t result = IRHitachiAc424::toCommon(); + result.protocol = decode_type_t::HITACHI_AC344; + result.swingv = getSwingV() ? stdAc::swingv_t::kAuto : stdAc::swingv_t::kOff; + result.swingh = toCommonSwingH(getSwingH()); + return result; +} + +/// Convert the internal state into a human readable string. +/// @return A string containing the settings in human-readable form. +String IRHitachiAc344::toString(void) { + String result; + result.reserve(120); // Reserve some heap for the string to reduce fragging. + result += _toString(); + result += addBoolToString(getSwingV(), kSwingVStr); + result += addIntToString(getSwingH(), kSwingHStr); + result += kSpaceLBraceStr; + switch (getSwingH()) { + case kHitachiAc344SwingHLeftMax: result += kLeftMaxStr; break; + case kHitachiAc344SwingHLeft: result += kLeftStr; break; + case kHitachiAc344SwingHMiddle: result += kMiddleStr; break; + case kHitachiAc344SwingHRight: result += kRightStr; break; + case kHitachiAc344SwingHRightMax: result += kRightMaxStr; break; + case kHitachiAc344SwingHAuto: result += kAutoStr; break; + default: result += kUnknownStr; + } + result += ')'; + return result; +} diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Hitachi.h b/lib/IRremoteESP8266-2.7.8/src/ir_Hitachi.h similarity index 61% rename from lib/IRremoteESP8266-2.7.5/src/ir_Hitachi.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Hitachi.h index 0db3552ff..408d4784f 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Hitachi.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Hitachi.h @@ -1,16 +1,24 @@ -// Hitachi A/C -// // Copyright 2018-2020 David Conran +/// @file +/// @brief Support for Hitachi A/C protocols. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/417 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/453 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/973 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1056 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1060 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1134 // Supports: // Brand: Hitachi, Model: RAS-35THA6 remote -// Brand: Hitachi, Model: LT0541-HTA remote -// Brand: Hitachi, Model: Series VI A/C (Circa 2007) -// Brand: Hitachi, Model: RAR-8P2 remote -// Brand: Hitachi, Model: RAS-AJ25H A/C +// Brand: Hitachi, Model: LT0541-HTA remote (HITACHI_AC1) +// Brand: Hitachi, Model: Series VI A/C (Circa 2007) (HITACHI_AC1) +// Brand: Hitachi, Model: RAR-8P2 remote (HITACHI_AC424) +// Brand: Hitachi, Model: RAS-AJ25H A/C (HITACHI_AC424) // Brand: Hitachi, Model: PC-LH3B (HITACHI_AC3) // Brand: Hitachi, Model: KAZE-312KSDP A/C (HITACHI_AC1) // Brand: Hitachi, Model: R-LT0541-HTA/Y.K.1.1-1 V2.3 remote (HITACHI_AC1) +// Brand: Hitachi, Model: RAS-22NK A/C (HITACHI_AC344) +// Brand: Hitachi, Model: RF11T1 remote (HITACHI_AC344) #ifndef IR_HITACHI_H_ #define IR_HITACHI_H_ @@ -43,7 +51,7 @@ const uint8_t kHitachiAcAutoTemp = 23; // 23C const uint8_t kHitachiAcPowerOffset = 0; const uint8_t kHitachiAcSwingOffset = 7; -// HitachiAc424 +// HitachiAc424 & HitachiAc344 // Byte[11] const uint8_t kHitachiAc424ButtonByte = 11; const uint8_t kHitachiAc424ButtonPowerMode = 0x13; @@ -51,6 +59,13 @@ const uint8_t kHitachiAc424ButtonFan = 0x42; const uint8_t kHitachiAc424ButtonTempDown = 0x43; const uint8_t kHitachiAc424ButtonTempUp = 0x44; const uint8_t kHitachiAc424ButtonSwingV = 0x81; +const uint8_t kHitachiAc424ButtonSwingH = 0x8C; +const uint8_t kHitachiAc344ButtonPowerMode = kHitachiAc424ButtonPowerMode; +const uint8_t kHitachiAc344ButtonFan = kHitachiAc424ButtonFan; +const uint8_t kHitachiAc344ButtonTempDown = kHitachiAc424ButtonTempDown; +const uint8_t kHitachiAc344ButtonTempUp = kHitachiAc424ButtonTempUp; +const uint8_t kHitachiAc344ButtonSwingV = kHitachiAc424ButtonSwingV; +const uint8_t kHitachiAc344ButtonSwingH = kHitachiAc424ButtonSwingH; // Byte[13] const uint8_t kHitachiAc424TempByte = 13; @@ -58,6 +73,8 @@ const uint8_t kHitachiAc424TempOffset = 2; const uint8_t kHitachiAc424TempSize = 6; const uint8_t kHitachiAc424MinTemp = 16; // 16C const uint8_t kHitachiAc424MaxTemp = 32; // 32C +const uint8_t kHitachiAc344MinTemp = kHitachiAc424MinTemp; +const uint8_t kHitachiAc344MaxTemp = kHitachiAc424MaxTemp; const uint8_t kHitachiAc424FanTemp = 27; // 27C // Byte[25] @@ -66,6 +83,11 @@ const uint8_t kHitachiAc424Fan = 1; const uint8_t kHitachiAc424Cool = 3; const uint8_t kHitachiAc424Dry = 5; const uint8_t kHitachiAc424Heat = 6; +const uint8_t kHitachiAc344Fan = kHitachiAc424Fan; +const uint8_t kHitachiAc344Cool = kHitachiAc424Cool; +const uint8_t kHitachiAc344Dry = kHitachiAc424Dry; +const uint8_t kHitachiAc344Heat = kHitachiAc424Heat; + const uint8_t kHitachiAc424FanByte = kHitachiAc424ModeByte; const uint8_t kHitachiAc424FanMin = 1; const uint8_t kHitachiAc424FanLow = 2; @@ -74,11 +96,33 @@ const uint8_t kHitachiAc424FanHigh = 4; const uint8_t kHitachiAc424FanAuto = 5; const uint8_t kHitachiAc424FanMax = 6; const uint8_t kHitachiAc424FanMaxDry = 2; +const uint8_t kHitachiAc344FanMin = kHitachiAc424FanMin; +const uint8_t kHitachiAc344FanLow = kHitachiAc424FanLow; +const uint8_t kHitachiAc344FanMedium = kHitachiAc424FanMedium; +const uint8_t kHitachiAc344FanHigh = kHitachiAc424FanHigh; +const uint8_t kHitachiAc344FanAuto = kHitachiAc424FanAuto; +const uint8_t kHitachiAc344FanMax = kHitachiAc424FanMax; + // Byte[27] const uint8_t kHitachiAc424PowerByte = 27; const uint8_t kHitachiAc424PowerOn = 0xF1; const uint8_t kHitachiAc424PowerOff = 0xE1; +// Byte[35] +const uint8_t kHitachiAc344SwingHByte = 35; +const uint8_t kHitachiAc344SwingHOffset = 0; // Mask 0b00000xxx +const uint8_t kHitachiAc344SwingHSize = 3; // Mask 0b00000xxx +const uint8_t kHitachiAc344SwingHAuto = 0; // 0b000 +const uint8_t kHitachiAc344SwingHRightMax = 1; // 0b001 +const uint8_t kHitachiAc344SwingHRight = 2; // 0b010 +const uint8_t kHitachiAc344SwingHMiddle = 3; // 0b011 +const uint8_t kHitachiAc344SwingHLeft = 4; // 0b100 +const uint8_t kHitachiAc344SwingHLeftMax = 5; // 0b101 + +// Byte[37] +const uint8_t kHitachiAc344SwingVByte = 37; +const uint8_t kHitachiAc344SwingVOffset = 5; // Mask 0b00x00000 + // HitachiAc1 // Byte[3] (Model) const uint8_t kHitachiAc1ModelByte = 3; @@ -139,15 +183,20 @@ const uint8_t kHitachiAc1ChecksumStartByte = 5; // Classes +/// Class for handling detailed Hitachi 224-bit A/C messages. +/// @see https://github.com/ToniA/arduino-heatpumpir/blob/master/HitachiHeatpumpIR.cpp class IRHitachiAc { public: explicit IRHitachiAc(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - void stateReset(void); #if SEND_HITACHI_AC void send(const uint16_t repeat = kHitachiAcDefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + /// 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_HITACHI_AC void begin(void); void on(void); @@ -180,16 +229,19 @@ class IRHitachiAc { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - // The state of the IR remote in IR code form. - uint8_t remote_state[kHitachiAcStateLength]; + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint8_t remote_state[kHitachiAcStateLength]; ///< The state in native code. void checksum(const uint16_t length = kHitachiAcStateLength); uint8_t _previoustemp; }; +/// Class for handling detailed Hitachi 104-bit A/C messages. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1056 class IRHitachiAc1 { public: explicit IRHitachiAc1(const uint16_t pin, const bool inverted = false, @@ -198,7 +250,11 @@ class IRHitachiAc1 { void stateReset(void); #if SEND_HITACHI_AC1 void send(const uint16_t repeat = kHitachiAcDefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + /// 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_HITACHI_AC1 void begin(void); void on(void); @@ -243,24 +299,30 @@ class IRHitachiAc1 { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - // The state of the IR remote in IR code form. - uint8_t remote_state[kHitachiAc1StateLength]; + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint8_t remote_state[kHitachiAc1StateLength]; ///< The state in native code. void checksum(const uint16_t length = kHitachiAc1StateLength); }; +/// Class for handling detailed Hitachi 53-byte/424-bit A/C messages. class IRHitachiAc424 { + friend class IRHitachiAc344; public: explicit IRHitachiAc424(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - - void stateReset(void); + virtual void stateReset(void); #if SEND_HITACHI_AC424 - void send(const uint16_t repeat = kHitachiAcDefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + virtual void send(const uint16_t repeat = kHitachiAcDefaultRepeat); + /// 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_HITACHI_AC424 void begin(void); void on(void); @@ -278,36 +340,43 @@ class IRHitachiAc424 { void setMode(const uint8_t mode); uint8_t getMode(void); uint8_t* getRaw(void); - void setRaw(const uint8_t new_code[], - const uint16_t length = kHitachiAc424StateLength); + virtual void setRaw(const uint8_t new_code[], + const uint16_t length = kHitachiAc424StateLength); uint8_t convertMode(const stdAc::opmode_t mode); uint8_t convertFan(const stdAc::fanspeed_t speed); static stdAc::opmode_t toCommonMode(const uint8_t mode); static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed); - stdAc::state_t toCommon(void); + virtual stdAc::state_t toCommon(void); String toString(void); #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - // The state of the IR remote in IR code form. - uint8_t remote_state[kHitachiAc424StateLength]; + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint8_t remote_state[kHitachiAc424StateLength]; ///< The state in native code void setInvertedStates(void); + String _toString(void); uint8_t _previoustemp; }; +/// Class for handling detailed Hitachi 15to27-byte/120to216-bit A/C messages. class IRHitachiAc3 { public: explicit IRHitachiAc3(const uint16_t pin, const bool inverted = false, - const bool use_modulation = true); + const bool use_modulation = true); void stateReset(void); #if SEND_HITACHI_AC3 void send(const uint16_t repeat = kHitachiAcDefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + /// 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_HITACHI_AC3 void begin(void); uint8_t getMode(void); @@ -318,13 +387,34 @@ class IRHitachiAc3 { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - // The state of the IR remote in IR code form. - uint8_t remote_state[kHitachiAc3StateLength]; + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint8_t remote_state[kHitachiAc3StateLength]; ///< The state in native code. void setInvertedStates(const uint16_t length = kHitachiAc3StateLength); }; +/// Class for handling detailed Hitachi 344-bit A/C messages. +class IRHitachiAc344: public IRHitachiAc424 { + public: + explicit IRHitachiAc344(const uint16_t pin, const bool inverted = false, + const bool use_modulation = true); + void stateReset(void); + void setRaw(const uint8_t new_code[], + const uint16_t length = kHitachiAc344StateLength); + stdAc::state_t toCommon(void); +#if SEND_HITACHI_AC344 + void send(const uint16_t repeat = kHitachiAcDefaultRepeat); +#endif // SEND_HITACHI_AC344 + void setSwingV(const bool on); + bool getSwingV(void); + void setSwingH(const uint8_t position); + uint8_t getSwingH(void); + static uint8_t convertSwingH(const stdAc::swingh_t position); + static stdAc::swingh_t toCommonSwingH(const uint8_t pos); + String toString(void); +}; #endif // IR_HITACHI_H_ diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Inax.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Inax.cpp similarity index 57% rename from lib/IRremoteESP8266-2.7.5/src/ir_Inax.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Inax.cpp index b57742a12..bb68ff30d 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Inax.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Inax.cpp @@ -1,20 +1,18 @@ // Copyright 2019 David Conran (crankyoldgit) -// Support for an IR controlled Robot Toilet +/// @file +/// @brief Support for the Inax Robot Toilet IR protocols. +/// @see https://www.lixil-manual.com/GCW-1365-16050/GCW-1365-16050.pdf +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/706 + +// Supports: +// Brand: Lixil, Model: Inax DT-BA283 Toilet #include #include "IRrecv.h" #include "IRsend.h" #include "IRutils.h" -// Supports: -// Brand: Lixil, Model: Inax DT-BA283 Toilet - -// Documentation: -// https://www.lixil-manual.com/GCW-1365-16050/GCW-1365-16050.pdf - // Constants -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/706 const uint16_t kInaxTick = 500; const uint16_t kInaxHdrMark = 9000; const uint16_t kInaxHdrSpace = 4500; @@ -24,16 +22,12 @@ const uint16_t kInaxZeroSpace = kInaxBitMark; const uint16_t kInaxMinGap = 40000; #if SEND_INAX -// Send a Inax Toilet formatted message. -// -// Args: -// data: The message to be sent. -// nbits: The bit size of the message being sent. typically kInaxBits. -// repeat: The number of times the message is to be repeated. -// -// Status: STABLE / Working. -// -// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/706 +/// Send a Inax Toilet formatted message. +/// Status: STABLE / Working. +/// @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. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/706 void IRsend::sendInax(const uint64_t data, const uint16_t nbits, const uint16_t repeat) { sendGeneric(kInaxHdrMark, kInaxHdrSpace, @@ -42,23 +36,18 @@ void IRsend::sendInax(const uint64_t data, const uint16_t nbits, kInaxBitMark, kInaxMinGap, data, nbits, 38, true, repeat, kDutyDefault); } -#endif +#endif // SEND_INAX #if DECODE_INAX -// Decode the supplied Inax Toilet message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits to expect in the data portion. -// Typically kInaxBits. -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: Stable / Known working. -// +/// Decode the supplied Inax Toilet message. +/// Status: Stable / Known working. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/706 bool IRrecv::decodeInax(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (strict && nbits != kInaxBits) @@ -76,9 +65,9 @@ bool IRrecv::decodeInax(decode_results *results, uint16_t offset, // Success results->bits = nbits; results->value = data; - results->decode_type = INAX; + results->decode_type = decode_type_t::INAX; results->command = 0; results->address = 0; return true; } -#endif +#endif // DECODE_INAX diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_JVC.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_JVC.cpp similarity index 70% rename from lib/IRremoteESP8266-2.7.5/src/ir_JVC.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_JVC.cpp index 7e1e5de27..cdd302a77 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_JVC.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_JVC.cpp @@ -1,18 +1,22 @@ // Copyright 2015 Kristian Lauszus // Copyright 2017 David Conran +/// @file +/// @brief Support for JVC protocols. +/// Originally added by Kristian Lauszus +/// Thanks to zenwheel and other people at the original blog post. +/// @see http://www.sbprojects.com/knowledge/ir/jvc.php + +// Supports: +// Brand: JVC, Model: PTU94023B remote + #include #include "IRrecv.h" #include "IRsend.h" #include "IRtimer.h" #include "IRutils.h" -// JVC originally added by Kristian Lauszus -// (Thanks to zenwheel and other people at the original blog post) - // Constants -// Ref: -// http://www.sbprojects.com/knowledge/ir/jvc.php const uint16_t kJvcTick = 75; const uint16_t kJvcHdrMarkTicks = 112; const uint16_t kJvcHdrMark = kJvcHdrMarkTicks * kJvcTick; @@ -33,17 +37,12 @@ const uint16_t kJvcMinGapTicks = const uint16_t kJvcMinGap = kJvcMinGapTicks * kJvcTick; #if SEND_JVC -// Send a JVC message. -// -// Args: -// data: The contents of the command you want to send. -// nbits: The bit size of the command being sent. (kJvcBits) -// repeat: The number of times you want the command to be repeated. -// -// Status: STABLE. -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/jvc.php +/// Send a JVC formatted message. +/// Status: STABLE / Working. +/// @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. +/// @see http://www.sbprojects.com/knowledge/ir/jvc.php void IRsend::sendJVC(uint64_t data, uint16_t nbits, uint16_t repeat) { // Set 38kHz IR carrier frequency & a 1/3 (33%) duty cycle. enableIROut(38, 33); @@ -70,41 +69,28 @@ void IRsend::sendJVC(uint64_t data, uint16_t nbits, uint16_t repeat) { } } -// Calculate the raw JVC data based on address and command. -// -// Args: -// address: An 8-bit address value. -// command: An 8-bit command value. -// Returns: -// A raw JVC message. -// -// Status: STABLE / Works fine. -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/jvc.php +/// Calculate the raw JVC data based on address and command. +/// Status: STABLE / Works fine. +/// @param[in] address An 8-bit address value. +/// @param[in] command An 8-bit command value. +/// @return A raw JVC message code, suitable for sendJVC().. +/// @see http://www.sbprojects.com/knowledge/ir/jvc.php uint16_t IRsend::encodeJVC(uint8_t address, uint8_t command) { return reverseBits((command << 8) | address, 16); } -#endif +#endif // SEND_JVC #if DECODE_JVC -// Decode the supplied JVC message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits of data to expect. Typically kJvcBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE -// -// Note: -// JVC repeat codes don't have a header. -// Ref: -// http://www.sbprojects.com/knowledge/ir/jvc.php +/// Decode the supplied JVC message. +/// Status: Stable / Known working. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @note JVC repeat codes don't have a header. +/// @see http://www.sbprojects.com/knowledge/ir/jvc.php bool IRrecv::decodeJVC(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (strict && nbits != kJvcBits) @@ -142,4 +128,4 @@ bool IRrecv::decodeJVC(decode_results *results, uint16_t offset, results->repeat = isRepeat; return true; } -#endif +#endif // DECODE_JVC diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Kelvinator.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Kelvinator.cpp similarity index 75% rename from lib/IRremoteESP8266-2.7.5/src/ir_Kelvinator.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Kelvinator.cpp index 4a4fac276..18702dad8 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Kelvinator.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Kelvinator.cpp @@ -1,18 +1,18 @@ // Copyright 2016 David Conran -// -// Code to emulate IR Kelvinator YALIF remote control unit, which should control -// at least the following Kelvinator A/C units: -// KSV26CRC, KSV26HRC, KSV35CRC, KSV35HRC, KSV53HRC, KSV62HRC, KSV70CRC, -// KSV70HRC, KSV80HRC. -// -// Note: -// * Unsupported: -// - All Sleep modes. -// - All Timer modes. -// - "I Feel" button & mode. -// - Energy Saving mode. -// - Low Heat mode. -// - Fahrenheit. +/// @file +/// @brief Support for Kelvinator A/C protocols. +/// Code to emulate IR Kelvinator YALIF remote control unit, which should +/// control at least the following Kelvinator A/C units: +/// KSV26CRC, KSV26HRC, KSV35CRC, KSV35HRC, KSV53HRC, KSV62HRC, KSV70CRC, +/// KSV70HRC, KSV80HRC. +/// +/// @note Unsupported: +/// - All Sleep modes. +/// - All Timer modes. +/// - "I Feel" button & mode. +/// - Energy Saving mode. +/// - Low Heat mode. +/// - Fahrenheit. #include "ir_Kelvinator.h" #include @@ -27,7 +27,6 @@ #include "IRutils.h" // Constants - const uint16_t kKelvinatorTick = 85; const uint16_t kKelvinatorHdrMarkTicks = 106; const uint16_t kKelvinatorHdrMark = kKelvinatorHdrMarkTicks * kKelvinatorTick; @@ -71,15 +70,11 @@ using irutils::setBit; using irutils::setBits; #if SEND_KELVINATOR -// Send a Kelvinator A/C message. -// -// Args: -// data: An array of bytes containing the IR command. -// nbytes: Nr. of bytes of data in the array. (>=kKelvinatorStateLength) -// repeat: Nr. of times the message is to be repeated. (Default = 0). -// -// Status: STABLE / Known working. -// +/// Send a Kelvinator A/C message. +/// Status: STABLE / Known working. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendKelvinator(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { if (nbytes < kKelvinatorStateLength) @@ -122,18 +117,25 @@ void IRsend::sendKelvinator(const unsigned char data[], const uint16_t nbytes, } #endif // SEND_KELVINATOR +/// 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? IRKelvinatorAC::IRKelvinatorAC(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { this->stateReset(); } +/// Reset the internals of the object to a known good state. void IRKelvinatorAC::stateReset(void) { for (uint8_t i = 0; i < kKelvinatorStateLength; i++) remote_state[i] = 0x0; remote_state[3] = 0x50; remote_state[11] = 0x70; } +/// Set up hardware to be able to send a message. void IRKelvinatorAC::begin(void) { _irsend.begin(); } +/// Fix up any odd conditions for the current state. void IRKelvinatorAC::fixup(void) { // X-Fan mode is only valid in COOL or DRY modes. if (this->getMode() != kKelvinatorCool && this->getMode() != kKelvinatorDry) @@ -142,21 +144,33 @@ void IRKelvinatorAC::fixup(void) { } #if SEND_KELVINATOR +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRKelvinatorAC::send(const uint16_t repeat) { this->fixup(); // Ensure correct settings before sending. _irsend.sendKelvinator(remote_state, kKelvinatorStateLength, repeat); } #endif // SEND_KELVINATOR +/// Get the raw state of the object, suitable to be sent with the appropriate +/// IRsend object method. +/// @return A PTR to the internal state. uint8_t *IRKelvinatorAC::getRaw(void) { this->fixup(); // Ensure correct settings before sending. return remote_state; } +/// Set the raw state of the object. +/// @param[in] new_code The raw state from the native IR message. void IRKelvinatorAC::setRaw(const uint8_t new_code[]) { memcpy(remote_state, new_code, kKelvinatorStateLength); } +/// Calculate the checksum for a given block of state. +/// @param[in] block A pointer to a block to calc the checksum of. +/// @param[in] length Length of the block array to checksum. +/// @return The calculated checksum value. +/// @note Many Bothans died to bring us this information. uint8_t IRKelvinatorAC::calcBlockChecksum(const uint8_t *block, const uint16_t length) { uint8_t sum = kKelvinatorChecksumStart; @@ -169,7 +183,8 @@ uint8_t IRKelvinatorAC::calcBlockChecksum(const uint8_t *block, return sum & 0b1111; } -// Many Bothans died to bring us this information. +/// Calculate the checksum for the internal state. +/// @param[in] length Length of the internal state to checksum. void IRKelvinatorAC::checksum(const uint16_t length) { // For each command + options block. for (uint16_t offset = 0; offset + 7 < length; offset += 8) { @@ -178,12 +193,10 @@ void IRKelvinatorAC::checksum(const uint16_t length) { } } -// Verify the checksum is valid for a given state. -// Args: -// state: The array to verify the checksum of. -// length: The size of the state. -// Returns: -// A boolean. +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The size of the state. +/// @return A boolean indicating if it is valid. bool IRKelvinatorAC::validChecksum(const uint8_t state[], const uint16_t length) { for (uint16_t offset = 0; offset + 7 < length; offset += 8) { @@ -195,20 +208,27 @@ bool IRKelvinatorAC::validChecksum(const uint8_t state[], return true; } +/// Set the internal state to have the power on. void IRKelvinatorAC::on(void) { setPower(true); } +/// Set the internal state to have the power off. void IRKelvinatorAC::off(void) {setPower(false); } +/// Set the internal state to have the desired power. +/// @param[in] on The desired power state. void IRKelvinatorAC::setPower(const bool on) { setBit(&remote_state[0], kKelvinatorPowerOffset, on); remote_state[8] = remote_state[0]; // Duplicate to the 2nd command chunk. } +/// Get the power setting from the internal state. +/// @return A boolean indicating if the power setting. bool IRKelvinatorAC::getPower(void) { return GETBIT8(remote_state[0], kKelvinatorPowerOffset); } -// Set the temp. in deg C +/// Set the temperature setting. +/// @param[in] degrees The temperature in degrees celsius. void IRKelvinatorAC::setTemp(const uint8_t degrees) { uint8_t temp = std::max(kKelvinatorMinTemp, degrees); temp = std::min(kKelvinatorMaxTemp, temp); @@ -216,13 +236,15 @@ void IRKelvinatorAC::setTemp(const uint8_t degrees) { remote_state[9] = remote_state[1]; // Duplicate to the 2nd command chunk. } -// Return the set temp. in deg C +/// Get the current temperature setting. +/// @return Get current setting for temp. in degrees celsius. uint8_t IRKelvinatorAC::getTemp(void) { return GETBITS8(remote_state[1], kLowNibble, kNibbleSize) + kKelvinatorMinTemp; } -// Set the speed of the fan, 0-5, 0 is auto, 1-5 is the speed +/// Set the speed of the fan. +/// @param[in] speed 0 is auto, 1-5 is the speed void IRKelvinatorAC::setFan(const uint8_t speed) { uint8_t fan = std::min(kKelvinatorFanMax, speed); // Bounds check @@ -239,14 +261,20 @@ void IRKelvinatorAC::setFan(const uint8_t speed) { } } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRKelvinatorAC::getFan(void) { return GETBITS8(remote_state[14], kKelvinatorFanOffset, kKelvinatorFanSize); } +/// Get the current operation mode setting. +/// @return The current operation mode. uint8_t IRKelvinatorAC::getMode(void) { return GETBITS8(remote_state[0], kKelvinatorModeOffset, kModeBitsSize); } +/// Set the desired operation mode. +/// @param[in] mode The desired operation mode. void IRKelvinatorAC::setMode(const uint8_t mode) { switch (mode) { case kKelvinatorAuto: @@ -266,6 +294,8 @@ void IRKelvinatorAC::setMode(const uint8_t mode) { } } +/// Control the current vertical swing setting. +/// @param[in] on The desired setting. void IRKelvinatorAC::setSwingVertical(const bool on) { setBit(&remote_state[4], kKelvinatorVentSwingVOffset, on); setBit(&remote_state[0], kKelvinatorVentSwingOffset, @@ -273,10 +303,14 @@ void IRKelvinatorAC::setSwingVertical(const bool on) { remote_state[8] = remote_state[0]; // Duplicate to the 2nd command chunk. } +/// Is the vertical swing setting on? +/// @return The current value. bool IRKelvinatorAC::getSwingVertical(void) { return GETBIT8(remote_state[4], kKelvinatorVentSwingVOffset); } +/// Control the current horizontal swing setting. +/// @param[in] on The desired setting. void IRKelvinatorAC::setSwingHorizontal(const bool on) { setBit(&remote_state[4], kKelvinatorVentSwingHOffset, on); setBit(&remote_state[0], kKelvinatorVentSwingOffset, @@ -284,57 +318,84 @@ void IRKelvinatorAC::setSwingHorizontal(const bool on) { remote_state[8] = remote_state[0]; // Duplicate to the 2nd command chunk. } +/// Is the horizontal swing setting on? +/// @return The current value. bool IRKelvinatorAC::getSwingHorizontal(void) { return GETBIT8(remote_state[4], kKelvinatorVentSwingHOffset); } +/// Control the current Quiet setting. +/// @param[in] on The desired setting. void IRKelvinatorAC::setQuiet(const bool on) { setBit(&remote_state[12], kKelvinatorQuietOffset, on); } +/// Is the Quiet setting on? +/// @return The current value. bool IRKelvinatorAC::getQuiet(void) { return GETBIT8(remote_state[12], kKelvinatorQuietOffset); } +/// Control the current Ion Filter setting. +/// @param[in] on The desired setting. void IRKelvinatorAC::setIonFilter(const bool on) { setBit(&remote_state[2], kKelvinatorIonFilterOffset, on); remote_state[10] = remote_state[2]; // Duplicate to the 2nd command chunk. } +/// Is the Ion Filter setting on? +/// @return The current value. bool IRKelvinatorAC::getIonFilter(void) { return GETBIT8(remote_state[2], kKelvinatorIonFilterOffset); } +/// Control the current Light setting. +/// i.e. The LED display on the A/C unit that shows the basic settings. +/// @param[in] on The desired setting. void IRKelvinatorAC::setLight(const bool on) { setBit(&remote_state[2], kKelvinatorLightOffset, on); remote_state[10] = remote_state[2]; // Duplicate to the 2nd command chunk. } +/// Is the Light (Display) setting on? +/// @return The current value. bool IRKelvinatorAC::getLight(void) { return GETBIT8(remote_state[2], kKelvinatorLightOffset); } -// Note: XFan mode is only valid in Cool or Dry mode. +/// Control the current XFan setting. +/// This setting will cause the unit blow air after power off to dry out the +/// A/C device. +/// @note XFan mode is only valid in Cool or Dry mode. +/// @param[in] on The desired setting. void IRKelvinatorAC::setXFan(const bool on) { setBit(&remote_state[2], kKelvinatorXfanOffset, on); remote_state[10] = remote_state[2]; // Duplicate to the 2nd command chunk. } +/// Is the XFan setting on? +/// @return The current value. bool IRKelvinatorAC::getXFan(void) { return GETBIT8(remote_state[2], kKelvinatorXfanOffset); } -// Note: Turbo mode is turned off if the fan speed is changed. +/// Control the current Turbo setting. +/// @note Turbo mode is turned off if the fan speed is changed. +/// @param[in] on The desired setting. void IRKelvinatorAC::setTurbo(const bool on) { setBit(&remote_state[2], kKelvinatorTurboOffset, on); remote_state[10] = remote_state[2]; // Duplicate to the 2nd command chunk. } +/// Is the Turbo setting on? +/// @return The current value. bool IRKelvinatorAC::getTurbo(void) { return GETBIT8(remote_state[2], kKelvinatorTurboOffset); } -// Convert a standard A/C mode into its native mode. +/// Convert a standard A/C mode (stdAc::opmode_t) into it a native mode. +/// @param[in] mode A stdAc::opmode_t operation mode. +/// @return The native mode equivilant. uint8_t IRKelvinatorAC::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kKelvinatorCool; @@ -345,7 +406,9 @@ uint8_t IRKelvinatorAC::convertMode(const stdAc::opmode_t mode) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode to it's stdAc::opmode_t equivalent. +/// @param[in] mode A native operating mode value. +/// @return The stdAc::opmode_t equivilant. stdAc::opmode_t IRKelvinatorAC::toCommonMode(const uint8_t mode) { switch (mode) { case kKelvinatorCool: return stdAc::opmode_t::kCool; @@ -356,12 +419,15 @@ stdAc::opmode_t IRKelvinatorAC::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed to it's stdAc::fanspeed_t equivalent. +/// @param[in] speed A native fan speed value. +/// @return The stdAc::fanspeed_t equivilant. stdAc::fanspeed_t IRKelvinatorAC::toCommonFanSpeed(const uint8_t speed) { return (stdAc::fanspeed_t)speed; } -// Convert the A/C state to it's common equivalent. +/// Convert the internal A/C object state to it's stdAc::state_t equivalent. +/// @return A stdAc::state_t containing the current settings. stdAc::state_t IRKelvinatorAC::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::KELVINATOR; @@ -388,7 +454,8 @@ stdAc::state_t IRKelvinatorAC::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the internal settings into a human readable string. +/// @return A String. String IRKelvinatorAC::toString(void) { String result = ""; result.reserve(160); // Reserve some heap for the string to reduce fragging. @@ -410,18 +477,15 @@ String IRKelvinatorAC::toString(void) { } #if DECODE_KELVINATOR -// Decode the supplied Kelvinator message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kKelvinatorBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Known working. +/// Decode the supplied Kelvinator message. +/// Status: STABLE / Known 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::decodeKelvinator(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen <= diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Kelvinator.h b/lib/IRremoteESP8266-2.7.8/src/ir_Kelvinator.h similarity index 88% rename from lib/IRremoteESP8266-2.7.5/src/ir_Kelvinator.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Kelvinator.h index fac26bf2e..a75f6b534 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Kelvinator.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Kelvinator.h @@ -1,6 +1,6 @@ -// Kelvinator A/C -// // Copyright 2016 David Conran +/// @file +/// @brief Support for Kelvinator A/C protocols. // Supports: // Brand: Kelvinator, Model: YALIF Remote @@ -133,15 +133,19 @@ const uint8_t kKelvinatorAutoTemp = 25; // 25C */ // Classes +/// Class for handling detailed Kelvinator A/C messages. class IRKelvinatorAC { public: explicit IRKelvinatorAC(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - void stateReset(void); #if SEND_KELVINATOR void send(const uint16_t repeat = kKelvinatorDefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + /// 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_KELVINATOR void begin(void); void on(void); @@ -182,12 +186,13 @@ class IRKelvinatorAC { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - // The state of the IR remote in IR code form. - uint8_t remote_state[kKelvinatorStateLength]; + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint8_t remote_state[kKelvinatorStateLength]; ///< The state in IR code form. void checksum(const uint16_t length = kKelvinatorStateLength); void fixup(void); }; diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_LG.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_LG.cpp similarity index 70% rename from lib/IRremoteESP8266-2.7.5/src/ir_LG.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_LG.cpp index 1024548ca..65fe91883 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_LG.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_LG.cpp @@ -2,9 +2,11 @@ // Copyright 2015 cheaplin // Copyright 2017, 2018 David Conran -// Supports: -// Brand: LG, Model: 6711A20083V remote -// Brand: LG, Model: AKB74395308 remote +/// @file +/// @brief Support for LG protocols. +/// LG decode originally added by Darryl Smith (based on the JVC protocol) +/// LG send originally added by https://github.com/chaeplin +/// @see https://github.com/arendst/Tasmota/blob/54c2eb283a02e4287640a4595e506bc6eadbd7f2/sonoff/xdrv_05_irremote.ino#L327-438 #include "ir_LG.h" #include @@ -22,8 +24,6 @@ using irutils::addTempToString; using irutils::setBit; using irutils::setBits; -// LG decode originally added by Darryl Smith (based on the JVC protocol) -// LG send originally added by https://github.com/chaeplin // Constants const uint16_t kLgTick = 50; @@ -58,34 +58,14 @@ const uint16_t kLg2HdrSpace = kLg2HdrSpaceTicks * kLgTick; // 9850 const uint16_t kLg2BitMarkTicks = 10; const uint16_t kLg2BitMark = kLg2BitMarkTicks * kLgTick; // 500 -#if (SEND_LG || DECODE_LG) -// Calculate the rolling 4-bit wide checksum over all of the data. -// Args: -// data: The value to be checksum'ed. -// Returns: -// A 4-bit checksum. -uint8_t calcLGChecksum(uint16_t data) { - return (((data >> 12) + ((data >> 8) & 0xF) + ((data >> 4) & 0xF) + - (data & 0xF)) & - 0xF); -} -#endif - #if SEND_LG -// Send an LG formatted message. -// -// Args: -// data: The contents of the message you want to send. -// nbits: The bit size of the message being sent. -// Typically kLgBits or kLg32Bits. -// repeat: The number of times you want the message to be repeated. -// -// Status: Beta / Should be working. -// -// Notes: -// LG has a separate message to indicate a repeat, like NEC does. -// Supports: -// IR Remote models: 6711A20083V +/// Send an LG formatted message. (LG) +/// Status: Beta / Should be working. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// Typically kLgBits or kLg32Bits. +/// @param[in] repeat The number of times the command is to be repeated. +/// @note LG has a separate message to indicate a repeat, like NEC does. void IRsend::sendLG(uint64_t data, uint16_t nbits, uint16_t repeat) { uint16_t repeatHeaderMark = 0; uint8_t duty = kDutyDefault; @@ -113,20 +93,13 @@ void IRsend::sendLG(uint64_t data, uint16_t nbits, uint16_t repeat) { 38, true, repeat - 1, duty); } -// Send an LG Variant-2 formatted message. -// -// Args: -// data: The contents of the message you want to send. -// nbits: The bit size of the message being sent. -// Typically kLgBits or kLg32Bits. -// repeat: The number of times you want the message to be repeated. -// -// Status: Beta / Should be working. -// -// Notes: -// LG has a separate message to indicate a repeat, like NEC does. -// Supports: -// IR Remote models: AKB74395308 +/// Send an LG Variant-2 formatted message. (LG2) +/// Status: Beta / Should be working. +/// @param[in] data The message to be sent. +/// @param[in] nbits The number of bits of message to be sent. +/// Typically kLgBits or kLg32Bits. +/// @param[in] repeat The number of times the command is to be repeated. +/// @note LG has a separate message to indicate a repeat, like NEC does. void IRsend::sendLG2(uint64_t data, uint16_t nbits, uint16_t repeat) { if (nbits >= kLg32Bits) { // Let the original routine handle it. @@ -149,52 +122,35 @@ void IRsend::sendLG2(uint64_t data, uint16_t nbits, uint16_t repeat) { 38, true, repeat - 1, 50); } -// Construct a raw 28-bit LG message code from the supplied address & command. -// -// Args: -// address: The address code. -// command: The command code. -// Returns: -// A raw 28-bit LG message code suitable for sendLG() etc. -// -// Status: STABLE / Works. -// -// Notes: -// e.g. Sequence of bits = address + command + checksum. +/// Construct a raw 28-bit LG message code from the supplied address & command. +/// Status: STABLE / Works. +/// @param[in] address The address code. +/// @param[in] command The command code. +/// @return A raw 28-bit LG message code suitable for sendLG() etc. +/// @note Sequence of bits = address + command + checksum. uint32_t IRsend::encodeLG(uint16_t address, uint16_t command) { - return ((address << 20) | (command << 4) | calcLGChecksum(command)); + return ((address << 20) | (command << 4) | irutils::sumNibbles(command, 4)); } -#endif +#endif // SEND_LG #if DECODE_LG -// Decode the supplied LG message. -// LG protocol has a repeat code which is 4 items long. -// Even though the protocol has 28/32 bits of data, only 24/28 bits are -// distinct. -// In transmission order, the 28/32 bits are constructed as follows: -// 8/12 bits of address + 16 bits of command + 4 bits of checksum. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits to expect in the data portion. -// Typically kLgBits or kLg32Bits. -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Working. -// -// Note: -// LG 32bit protocol appears near identical to the Samsung protocol. -// They possibly differ on how they repeat and initial HDR mark. -// -// Supports: -// IR Remote models: 6711A20083V, AKB74395308 - -// Ref: -// https://funembedded.wordpress.com/2014/11/08/ir-remote-control-for-lg-conditioner-using-stm32f302-mcu-on-mbed-platform/ +/// Decode the supplied LG message. +/// Status: STABLE / Working. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// Typically kLgBits or kLg32Bits. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @note LG protocol has a repeat code which is 4 items long. +/// Even though the protocol has 28/32 bits of data, only 24/28 bits are +/// distinct. +/// In transmission order, the 28/32 bits are constructed as follows: +/// 8/12 bits of address + 16 bits of command + 4 bits of checksum. +/// @note LG 32bit protocol appears near identical to the Samsung protocol. +/// They possibly differ on how they repeat and initial HDR mark. +/// @see https://funembedded.wordpress.com/2014/11/08/ir-remote-control-for-lg-conditioner-using-stm32f302-mcu-on-mbed-platform/ bool IRrecv::decodeLG(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (nbits >= kLg32Bits) { @@ -279,7 +235,7 @@ bool IRrecv::decodeLG(decode_results *results, uint16_t offset, // Compliance uint16_t command = (data >> 4) & 0xFFFF; // The 16 bits before the checksum. - if (strict && (data & 0xF) != calcLGChecksum(command)) + if (strict && (data & 0xF) != irutils::sumNibbles(command, 4)) return false; // The last 4 bits sent are the expected checksum. // Success if (isLg2) @@ -295,21 +251,27 @@ bool IRrecv::decodeLG(decode_results *results, uint16_t offset, #endif // LG A/C Class -// Support for LG-type A/C units. -// Ref: -// https://github.com/arendst/Tasmota/blob/54c2eb283a02e4287640a4595e506bc6eadbd7f2/sonoff/xdrv_05_irremote.ino#L327-438 + +/// 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? IRLgAc::IRLgAc(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { this->stateReset(); } +/// Reset the internals of the object to a known good state. void IRLgAc::stateReset(void) { setRaw(kLgAcOffCommand); setModel(lg_ac_remote_model_t::GE6711AR2853M); } +/// Set up hardware to be able to send a message. void IRLgAc::begin(void) { _irsend.begin(); } #if SEND_LG +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRLgAc::send(const uint16_t repeat) { if (this->getPower()) _irsend.send(this->_protocol, this->getRaw(), kLgBits, repeat); @@ -320,6 +282,8 @@ void IRLgAc::send(const uint16_t repeat) { } #endif // SEND_LG +/// Set the model of the A/C to emulate. +/// @param[in] model The enum of the appropriate model. void IRLgAc::setModel(const lg_ac_remote_model_t model) { switch (model) { case lg_ac_remote_model_t::AKB75215403: @@ -332,6 +296,8 @@ void IRLgAc::setModel(const lg_ac_remote_model_t model) { } } +/// Get the model of the A/C. +/// @return The enum of the compatible model. lg_ac_remote_model_t IRLgAc::getModel(void) { switch (_protocol) { case LG2: @@ -343,45 +309,50 @@ lg_ac_remote_model_t IRLgAc::getModel(void) { } } +/// Get a copy of the internal state/code for this protocol. +/// @return The code for this protocol based on the current internal state. uint32_t IRLgAc::getRaw(void) { checksum(); return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. void IRLgAc::setRaw(const uint32_t new_code) { remote_state = new_code; _temp = 15; // Ensure there is a "sane" previous temp. _temp = getTemp(); } -// Calculate the checksum for a given state. -// Args: -// state: The value to calculate the checksum of. -// Returns: -// A uint8_t of the checksum. +/// Calculate the checksum for a given state. +/// @param[in] state The value to calc the checksum of. +/// @return The calculated checksum value. uint8_t IRLgAc::calcChecksum(const uint32_t state) { - return calcLGChecksum(state >> 4); + return irutils::sumNibbles(state >> 4, 4); } -// Verify the checksum is valid for a given state. -// Args: -// state: The value to verify the checksum of. -// Returns: -// A boolean. +/// Verify the checksum is valid for a given state. +/// @param[in] state The value to verify the checksum of. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRLgAc::validChecksum(const uint32_t state) { return calcChecksum(state) == GETBITS32(state, kLgAcChecksumOffset, kLgAcChecksumSize); } +/// Calculate and set the checksum values for the internal state. void IRLgAc::checksum(void) { setBits(&remote_state, kLgAcChecksumOffset, kLgAcChecksumSize, calcChecksum(remote_state)); } +/// Change the power setting to On. void IRLgAc::on(void) { setPower(true); } +/// Change the power setting to Off. void IRLgAc::off(void) { setPower(false); } +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRLgAc::setPower(const bool on) { setBits(&remote_state, kLgAcPowerOffset, kLgAcPowerSize, on ? kLgAcPowerOn : kLgAcPowerOff); @@ -391,17 +362,22 @@ void IRLgAc::setPower(const bool on) { _setTemp(0); // Off clears the temp. } +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRLgAc::getPower(void) { return GETBITS32(remote_state, kLgAcPowerOffset, kLgAcPowerSize) == kLgAcPowerOn; } -// Set the temp. (Internal use only) +/// Set the temperature. +/// @param[in] value The native temperature. +/// @note Internal use only. void IRLgAc::_setTemp(const uint8_t value) { setBits(&remote_state, kLgAcTempOffset, kLgAcTempSize, value); } -// Set the temp. in deg C +/// Set the temperature. +/// @param[in] degrees The temperature in degrees celsius. void IRLgAc::setTemp(const uint8_t degrees) { uint8_t temp = std::max(kLgAcMinTemp, degrees); temp = std::min(kLgAcMaxTemp, temp); @@ -409,7 +385,8 @@ void IRLgAc::setTemp(const uint8_t degrees) { _setTemp(temp - kLgAcTempAdjust); } -// Return the set temp. in deg C +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRLgAc::getTemp(void) { if (getPower()) return GETBITS32(remote_state, kLgAcTempOffset, kLgAcTempSize) + @@ -418,7 +395,8 @@ uint8_t IRLgAc::getTemp(void) { return _temp; } -// Set the speed of the fan. +/// Set the speed of the fan. +/// @param[in] speed The desired setting. void IRLgAc::setFan(const uint8_t speed) { switch (speed) { case kLgAcFanAuto: @@ -432,14 +410,20 @@ void IRLgAc::setFan(const uint8_t speed) { } } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRLgAc::getFan(void) { return GETBITS32(remote_state, kLgAcFanOffset, kLgAcFanSize); } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRLgAc::getMode(void) { return GETBITS32(remote_state, kLgAcModeOffset, kLgAcModeSize); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRLgAc::setMode(const uint8_t mode) { switch (mode) { case kLgAcAuto: @@ -454,7 +438,9 @@ void IRLgAc::setMode(const uint8_t mode) { } } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRLgAc::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kLgAcCool; @@ -465,7 +451,9 @@ uint8_t IRLgAc::convertMode(const stdAc::opmode_t mode) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRLgAc::toCommonMode(const uint8_t mode) { switch (mode) { case kLgAcCool: return stdAc::opmode_t::kCool; @@ -476,7 +464,9 @@ stdAc::opmode_t IRLgAc::toCommonMode(const uint8_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRLgAc::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: @@ -488,7 +478,9 @@ uint8_t IRLgAc::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRLgAc::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kLgAcFanHigh: return stdAc::fanspeed_t::kMax; @@ -498,7 +490,8 @@ stdAc::fanspeed_t IRLgAc::toCommonFanSpeed(const uint8_t speed) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRLgAc::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::LG; @@ -523,7 +516,8 @@ stdAc::state_t IRLgAc::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRLgAc::toString(void) { String result = ""; result.reserve(80); // Reserve some heap for the string to reduce fragging. @@ -539,6 +533,8 @@ String IRLgAc::toString(void) { return result; } +/// Check if the internal state looks like a valud LG A/C message. +/// @return true, the internal state is a valid LG A/C mesg. Otherwise, false. bool IRLgAc::isValidLgAc(void) { return validChecksum(remote_state) && (GETBITS32(remote_state, kLgAcSignatureOffset, kLgAcSignatureSize) == diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_LG.h b/lib/IRremoteESP8266-2.7.8/src/ir_LG.h similarity index 76% rename from lib/IRremoteESP8266-2.7.5/src/ir_LG.h rename to lib/IRremoteESP8266-2.7.8/src/ir_LG.h index 1147b30b7..bf0cdd0b6 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_LG.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_LG.h @@ -1,8 +1,13 @@ // Copyright 2017, 2019 David Conran +/// @file +/// @brief Support for LG protocols. +/// @see https://github.com/arendst/Tasmota/blob/54c2eb283a02e4287640a4595e506bc6eadbd7f2/sonoff/xdrv_05_irremote.ino#L327-438 + + // Supports: -// Brand: LG, Model: 6711A20083V remote -// Brand: LG, Model: AKB74395308 remote +// Brand: LG, Model: 6711A20083V remote (LG) +// Brand: LG, Model: AKB74395308 remote (LG2) // Brand: LG, Model: S4-W12JA3AA A/C (LG2) // Brand: LG, Model: AKB75215403 remote (LG2) // Brand: General Electric, Model: AG1BH09AW101 Split A/C @@ -53,21 +58,23 @@ const uint8_t kLgAcSignature = 0x88; const uint32_t kLgAcOffCommand = 0x88C0051; -uint8_t calcLGChecksum(uint16_t data); - // Classes +/// Class for handling detailed LG A/C messages. class IRLgAc { public: explicit IRLgAc(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - void stateReset(void); static uint8_t calcChecksum(const uint32_t state); static bool validChecksum(const uint32_t state); bool isValidLgAc(void); #if SEND_LG void send(const uint16_t repeat = kLgDefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + /// 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_LG void begin(void); void on(void); @@ -93,12 +100,13 @@ class IRLgAc { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - // The state of the IR remote in IR code form. - uint32_t remote_state; + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint32_t remote_state; ///< The state of the IR remote in IR code form. uint8_t _temp; decode_type_t _protocol; void checksum(void); diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Lasertag.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Lasertag.cpp similarity index 67% rename from lib/IRremoteESP8266-2.7.5/src/ir_Lasertag.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Lasertag.cpp index 14a059084..5285acd4a 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Lasertag.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Lasertag.cpp @@ -1,5 +1,11 @@ // Copyright 2017 David Conran -// Lasertag + +/// @file +/// @brief Support for Lasertag protocols. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/366 + +// Supports: +// Brand: Lasertag, Model: Phaser emitters #include #include "IRrecv.h" @@ -17,16 +23,13 @@ const int16_t kSpace = 1; const int16_t kMark = 0; #if SEND_LASERTAG -// Send a Lasertag packet. -// This protocol is pretty much just raw Manchester encoding. -// -// Args: -// data: The message you wish to send. -// nbits: Bit size of the protocol you want to send. -// repeat: Nr. of extra times the data will be sent. -// -// Status: STABLE / Working. -// +/// Send a Lasertag packet/message. +/// Status: STABLE / Working. +/// @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. +/// @note This protocol is pretty much just raw Manchester encoding. +/// @todo Convert this to use `sendManchester()` if we can.` void IRsend::sendLasertag(uint64_t data, uint16_t nbits, uint16_t repeat) { if (nbits > sizeof(data) * 8) return; // We can't send something that big. @@ -51,24 +54,19 @@ void IRsend::sendLasertag(uint64_t data, uint16_t nbits, uint16_t repeat) { #endif // SEND_LASERTAG #if DECODE_LASERTAG -// Decode the supplied Lasertag message. -// This protocol is pretty much just raw Manchester encoding. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: BETA / Appears to be working 90% of the time. -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/rc5.php -// https://en.wikipedia.org/wiki/RC-5 -// https://en.wikipedia.org/wiki/Manchester_code +/// Decode the supplied Lasertag message. +/// Status: BETA / Appears to be working 90% of the time. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @note This protocol is pretty much just raw Manchester encoding. +/// @see http://www.sbprojects.com/knowledge/ir/rc5.php +/// @see https://en.wikipedia.org/wiki/RC-5 +/// @see https://en.wikipedia.org/wiki/Manchester_code +/// @todo Convert to using `matchManchester()` if we can. bool IRrecv::decodeLasertag(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen <= kLasertagMinSamples + offset) return false; diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Lego.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Lego.cpp similarity index 72% rename from lib/IRremoteESP8266-2.7.5/src/ir_Lego.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Lego.cpp index b2d2f2d0e..3b7144768 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Lego.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Lego.cpp @@ -1,19 +1,19 @@ // Copyright 2019 David Conran +/// @file +/// @brief Support for LEGO protocols. +/// @note LEGO is a Registrated Trademark of the Lego Group. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/641 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/files/2974525/LEGO_Power_Functions_RC_v120.pdf + +// Supports: +// Brand: LEGO Power Functions, Model: IR Receiver + #include #include "IRrecv.h" #include "IRsend.h" #include "IRutils.h" -// LEGO -// (LEGO is a Registrated Trademark of the Lego Group.) -// -// Supports: -// Brand: LEGO Power Functions, Model: IR Receiver -// -// Ref: -// - https://github.com/crankyoldgit/IRremoteESP8266/issues/641 -// - https://github.com/crankyoldgit/IRremoteESP8266/files/2974525/LEGO_Power_Functions_RC_v120.pdf // Constants const uint16_t kLegoPfBitMark = 158; @@ -24,15 +24,12 @@ const uint32_t kLegoPfMinCommandLength = 16000; // 16ms #if SEND_LEGOPF -// Send a LEGO Power Functions message. -// -// Args: -// data: Contents of the message to be sent. -// nbits: Nr. of bits of data to be sent. Typically kLegoPfBits. -// repeat: Nr. of additional times the message is to be sent. -// Note: Non-zero repeats results in at least 5 messages per spec. -// -// Status: Beta / Should work. +/// Send a LEGO Power Functions message. +/// Status: Beta / Should work. +/// @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. +/// @note Non-zero repeats results in at least 5 messages per spec. void IRsend::sendLegoPf(const uint64_t data, const uint16_t nbits, const uint16_t repeat) { uint8_t channelid = ((data >> (nbits - 4)) & 0b11) + 1; @@ -63,18 +60,14 @@ void IRsend::sendLegoPf(const uint64_t data, const uint16_t nbits, #endif // SEND_LEGO #if DECODE_LEGOPF -// Decode the supplied LEGO Power Functions message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kLegoPfBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Appears to work. +/// Decode the supplied LEGO Power Functions message. +/// Status: STABLE / Appears to work. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. bool IRrecv::decodeLegoPf(decode_results* results, uint16_t offset, const uint16_t nbits, const bool strict) { // Check if can possibly be a valid LEGO message. diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Lutron.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Lutron.cpp similarity index 69% rename from lib/IRremoteESP8266-2.7.5/src/ir_Lutron.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Lutron.cpp index 8ea4f0b3a..5d0424784 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Lutron.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Lutron.cpp @@ -1,5 +1,20 @@ // Copyright 2018 David Conran -// Lutron + +/// @file +/// @brief Support for Lutron protocols. +/// @note The Lutron protocol uses a sort of Run Length encoding to encode +/// its data. There is no header or footer per-se. +/// As a mark is the first data we will notice, we always assume the First +/// bit of the technically 36-bit protocol is '1'. So it is assumed, and thus +/// we only care about the 35 bits of data. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/515 +/// @see http://www.lutron.com/TechnicalDocumentLibrary/048158.doc + +// Supports: +// Brand: Lutron, Model: SP-HT remote +// Brand: Lutron, Model: MIR-ITFS remote +// Brand: Lutron, Model: MIR-ITFS-LF remote +// Brand: Lutron, Model: MIR-ITFS-F remote #define __STDC_LIMIT_MACROS #include @@ -8,36 +23,21 @@ #include "IRsend.h" #include "IRutils.h" -// Notes: -// The Lutron protocol uses a sort of Run Length encoding to encode -// its data. There is no header or footer per-se. -// As a mark is the first data we will notice, we always assume the First -// bit of the technically 36-bit protocol is '1'. So it is assumed, and thus -// we only care about the 35 bits of data. // Constants -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/515 const uint16_t kLutronTick = 2288; const uint32_t kLutronGap = 150000; // Completely made up value. const uint16_t kLutronDelta = 400; // +/- 300 usecs. #if SEND_LUTRON -// Send a Lutron formatted message. -// -// Args: -// data: The message to be sent. -// nbits: The number of bits of the message to be sent. Typically kLutronBits -// repeat: The number of times the command is to be repeated. -// -// Status: Stable / Appears to be working for real devices. - -// Notes: -// Protocol is really 36 bits long, but the first bit is always a 1. -// So, assume the 1 and only have a normal payload of 35 bits. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/515 +/// Send a Lutron formatted message. +/// Status: Stable / Appears to be working for real devices. +/// @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. +/// @note The protocol is really 36 bits long, but the first bit is always a 1. +/// So, assume the 1 and only have a normal payload of 35 bits. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/515 void IRsend::sendLutron(uint64_t data, uint16_t nbits, uint16_t repeat) { enableIROut(40000, 40); // 40Khz & 40% dutycycle. for (uint16_t r = 0; r <= repeat; r++) { @@ -54,23 +54,14 @@ void IRsend::sendLutron(uint64_t data, uint16_t nbits, uint16_t repeat) { #endif // SEND_LUTRON #if DECODE_LUTRON -// Decode the supplied Lutron message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kLutronBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Working. -// -// Notes: -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/515 +/// Decode the supplied Lutron message. +/// Status: STABLE / Working. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. bool IRrecv::decodeLutron(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { // Technically the smallest number of entries for the smallest message is '1'. diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_MWM.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_MWM.cpp similarity index 80% rename from lib/IRremoteESP8266-2.7.5/src/ir_MWM.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_MWM.cpp index eefc4a57e..8aca4a4fd 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_MWM.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_MWM.cpp @@ -1,8 +1,12 @@ // Copyright 2018 Brett T. Warden -// MWM +/// @file +/// @brief Disney Made With Magic (MWM) Support +/// derived from ir_Lasertag.cpp +/// @see https://github.com/crankyoldgit/IRremoteESP8266/pull/557 -// derived from ir_Lasertag.cpp, Copyright 2017 David Conran +// Supports: +// Brand: Disney, Model: Made With Magic (Glow With The Show) wand #include #include "IRrecv.h" @@ -23,17 +27,13 @@ const int16_t kSpace = 1; const int16_t kMark = 0; #if SEND_MWM -// Send a MWM packet. -// This protocol is 2400 bps serial, 1 start bit (mark), 1 stop bit (space), no -// parity -// -// Args: -// data: The message you wish to send. -// nbits: Bit size of the protocol you want to send. -// repeat: Nr. of extra times the data will be sent. -// -// Status: Implemented. -// +/// Send a MWM packet/message. +/// Status: Implemented. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @note This protocol is 2400 bps serial, 1 start bit (mark), +/// 1 stop bit (space), no parity void IRsend::sendMWM(const uint8_t data[], const uint16_t nbytes, const uint16_t repeat) { if (nbytes < 3) return; // Shortest possible message is 3 bytes @@ -68,21 +68,16 @@ void IRsend::sendMWM(const uint8_t data[], const uint16_t nbytes, #endif // SEND_MWM #if DECODE_MWM -// Decode the supplied MWM message. -// This protocol is 2400 bps serial, 1 start bit (mark), 1 stop bit (space), no -// parity -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: Implemented. -// +/// Decode the supplied MWM message. +/// Status: Implemented. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @note This protocol is 2400 bps serial, 1 start bit (mark), +/// 1 stop bit (space), no parity bool IRrecv::decodeMWM(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { DPRINTLN("DEBUG: decodeMWM"); diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Magiquest.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Magiquest.cpp similarity index 63% rename from lib/IRremoteESP8266-2.7.5/src/ir_Magiquest.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Magiquest.cpp index 2c15612f4..3f79a18f6 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Magiquest.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Magiquest.cpp @@ -2,6 +2,11 @@ // Copyright 2015 kitlaan // Copyright 2017 Jason kendall, David Conran +/// @file +/// @brief Support for MagiQuest protocols. +/// @see https://github.com/kitlaan/Arduino-IRremote/blob/master/ir_Magiquest.cpp +/// @see https://github.com/mpflaga/Arduino-IRremote + #include "ir_Magiquest.h" #include #include "IRrecv.h" @@ -11,25 +16,14 @@ #define IS_ZERO(m, s) (((m)*100 / ((m) + (s))) <= kMagiQuestZeroRatio) #define IS_ONE(m, s) (((m)*100 / ((m) + (s))) >= kMagiQuestOneRatio) -// Strips taken from: -// https://github.com/kitlaan/Arduino-IRremote/blob/master/ir_Magiquest.cpp -// and -// https://github.com/mpflaga/Arduino-IRremote - -// Source: https://github.com/mpflaga/Arduino-IRremote - #if SEND_MAGIQUEST -// Send a MagiQuest formatted message. -// -// Args: -// data: The contents of the message you want to send. -// nbits: The bit size of the message being sent. -// Typically kMagiquestBits. -// repeat: The number of times you want the message to be repeated. -// -// Status: Alpha / Should be working. -// -void IRsend::sendMagiQuest(uint64_t data, uint16_t nbits, uint16_t repeat) { +/// Send a MagiQuest formatted message. +/// Status: Beta / Should be working. +/// @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::sendMagiQuest(const uint64_t data, const uint16_t nbits, + const uint16_t repeat) { sendGeneric(0, 0, // No Headers - Technically it's included in the data. // i.e. 8 zeros. kMagiQuestMarkOne, kMagiQuestSpaceOne, kMagiQuestMarkZero, @@ -38,11 +32,15 @@ void IRsend::sendMagiQuest(uint64_t data, uint16_t nbits, uint16_t repeat) { kMagiQuestGap, data, nbits, 36, true, repeat, 50); } -// Encode a MagiQuest wand_id, and a magnitude into a single 64bit value. -// (Only 48 bits of real data + 8 leading zero bits) -// This is suitable for calling sendMagiQuest() with. -// e.g. sendMagiQuest(encodeMagiQuest(wand_id, magnitude)); -uint64_t IRsend::encodeMagiQuest(uint32_t wand_id, uint16_t magnitude) { +/// Encode a MagiQuest wand_id, and a magnitude into a single 64bit value. +/// (Only 48 bits of real data + 8 leading zero bits) +/// This is suitable for calling sendMagiQuest() with. +/// e.g. sendMagiQuest(encodeMagiQuest(wand_id, magnitude)) +/// @param[in] wand_id The value for the wand ID. +/// @param[in] magnitude The value for the magnitude +/// @return A code suitable for calling sendMagiQuest() with. +uint64_t IRsend::encodeMagiQuest(const uint32_t wand_id, + const uint16_t magnitude) { uint64_t result = 0; result = wand_id; result <<= 16; @@ -51,34 +49,23 @@ uint64_t IRsend::encodeMagiQuest(uint32_t wand_id, uint16_t magnitude) { result &= 0xFFFFFFFFFFFFULL; return result; } -#endif - -// Source: -// https://github.com/kitlaan/Arduino-IRremote/blob/master/ir_Magiquest.cpp +#endif // SEND_MAGIQUEST #if DECODE_MAGIQUEST -// Decode the supplied MagiQuest message. -// MagiQuest protocol appears to be a header of 8 'zero' bits, followed -// by 32 bits of "wand ID" and finally 16 bits of "magnitude". -// Even though we describe this protocol as 56 bits, it really only has -// 48 bits of data that matter. -// -// In transmission order, 8 zeros + 32 wand_id + 16 magnitude. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits to expect in the data portion, inc. the 8 bit header. -// Typically kMagiquestBits. -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: Alpha / Should work. -// -// Ref: -// https://github.com/kitlaan/Arduino-IRremote/blob/master/ir_Magiquest.cpp +/// Decode the supplied MagiQuest message. +/// Status: Beta / Should work. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @note MagiQuest protocol appears to be a header of 8 'zero' bits, followed +/// by 32 bits of "wand ID" and finally 16 bits of "magnitude". +/// Even though we describe this protocol as 56 bits, it really only has +/// 48 bits of data that matter. +/// In transmission order, 8 zeros + 32 wand_id + 16 magnitude. +/// @see https://github.com/kitlaan/Arduino-IRremote/blob/master/ir_Magiquest.cpp bool IRrecv::decodeMagiQuest(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { uint16_t bits = 0; @@ -164,4 +151,4 @@ bool IRrecv::decodeMagiQuest(decode_results *results, uint16_t offset, results->command = data & 0xFFFF; // Magnitude return true; } -#endif +#endif // DECODE_MAGIQUEST diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Magiquest.h b/lib/IRremoteESP8266-2.7.8/src/ir_Magiquest.h similarity index 73% rename from lib/IRremoteESP8266-2.7.5/src/ir_Magiquest.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Magiquest.h index 81fff53ad..399904375 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Magiquest.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Magiquest.h @@ -2,6 +2,14 @@ // Copyright 2015 kitlaan // Copyright 2017 Jason kendall, David Conran +/// @file +/// @brief Support for MagiQuest protocols. +/// @see https://github.com/kitlaan/Arduino-IRremote/blob/master/ir_Magiquest.cpp +/// @see https://github.com/mpflaga/Arduino-IRremote + +// Supports: +// Brand: MagiQuest, Model: Wand + #ifndef IR_MAGIQUEST_H_ #define IR_MAGIQUEST_H_ @@ -10,7 +18,7 @@ #include "IRremoteESP8266.h" #include "IRsend.h" -// MagiQuest packet is both Wand ID and magnitude of swish and flick +/// MagiQuest packet is both Wand ID and magnitude of swish and flick union magiquest { uint64_t llword; uint8_t byte[8]; diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Midea.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Midea.cpp similarity index 58% rename from lib/IRremoteESP8266-2.7.5/src/ir_Midea.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Midea.cpp index bbf9bedfa..5d270d3d4 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Midea.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Midea.cpp @@ -1,7 +1,12 @@ // Copyright 2017 bwze, crankyoldgit -// Midea +/// @file +/// @brief Support for Midea protocols. +/// Midea added by crankyoldgit & bwze. +/// send: bwze/crankyoldgit, decode: crankyoldgit +/// @see https://docs.google.com/spreadsheets/d/1TZh4jWrx4h9zzpYUI9aYXMl1fYOiqu-xVuOOMqagxrs/edit?usp=sharing #include "ir_Midea.h" +#include "ir_NEC.h" #include #ifndef ARDUINO #include @@ -11,16 +16,6 @@ #include "IRtext.h" #include "IRutils.h" -// Midea A/C added by (send) bwze/crankyoldgit & (decode) crankyoldgit -// -// Equipment it seems compatible with: -// * Pioneer System Model RYBO12GMFILCAD (12K BTU) -// * Pioneer System Model RUBO18GMFILCAD (18K BTU) -// * - -// Ref: -// https://docs.google.com/spreadsheets/d/1TZh4jWrx4h9zzpYUI9aYXMl1fYOiqu-xVuOOMqagxrs/edit?usp=sharing - // Constants const uint16_t kMideaTick = 80; const uint16_t kMideaBitMarkTicks = 7; @@ -37,6 +32,7 @@ const uint16_t kMideaMinGapTicks = kMideaHdrMarkTicks + kMideaZeroSpaceTicks + kMideaBitMarkTicks; const uint16_t kMideaMinGap = kMideaMinGapTicks * kMideaTick; const uint8_t kMideaTolerance = 30; // Percent +const uint16_t kMidea24MinGap = 13000; ///< uSecs using irutils::addBoolToString; using irutils::addFanToString; @@ -48,15 +44,11 @@ using irutils::setBit; using irutils::setBits; #if SEND_MIDEA -// Send a Midea message -// -// Args: -// data: Contents of the message to be sent. -// nbits: Nr. of bits of data to be sent. Typically kMideaBits. -// repeat: Nr. of additional times the message is to be sent. -// -// Status: Alpha / Needs testing against a real device. -// +/// Send a Midea message +/// Status: Alpha / Needs testing 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. void IRsend::sendMidea(uint64_t data, uint16_t nbits, uint16_t repeat) { if (nbits % 8 != 0) return; // nbits is required to be a multiple of 8. @@ -90,28 +82,31 @@ void IRsend::sendMidea(uint64_t data, uint16_t nbits, uint16_t repeat) { } } } -#endif +#endif // SEND_MIDEA // Code to emulate Midea A/C IR remote control unit. -// Warning: Consider this very alpha code. -// Initialise the object. +/// 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? IRMideaAC::IRMideaAC(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { this->stateReset(); } -// Reset the state of the remote to a known good state/sequence. +/// Reset the state of the remote to a known good state/sequence. void IRMideaAC::stateReset(void) { // Power On, Mode Auto, Fan Auto, Temp = 25C/77F remote_state = 0xA1826FFFFF62; _SwingVToggle = false; } -// Configure the pin for output. +/// Set up hardware to be able to send a message. void IRMideaAC::begin(void) { _irsend.begin(); } #if SEND_MIDEA -// Send the current desired state to the IR LED. +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRMideaAC::send(const uint16_t repeat) { this->checksum(); // Ensure correct checksum before sending. _irsend.sendMidea(remote_state, kMideaBits, repeat); @@ -123,37 +118,43 @@ void IRMideaAC::send(const uint16_t repeat) { } #endif // SEND_MIDEA -// Return a pointer to the internal state date of the remote. +/// Get a copy of the internal state/code for this protocol. +/// @return The code for this protocol based on the current internal state. uint64_t IRMideaAC::getRaw(void) { this->checksum(); return GETBITS64(remote_state, 0, kMideaBits); } -// Override the internal state with the new state. +/// Set the internal state from a valid code for this protocol. +/// @param[in] newState A valid code for this protocol. void IRMideaAC::setRaw(const uint64_t newState) { remote_state = newState; } -// Set the requested power state of the A/C to on. +/// Set the requested power state of the A/C to on. void IRMideaAC::on(void) { setPower(true); } -// Set the requested power state of the A/C to off. +/// Set the requested power state of the A/C to off. void IRMideaAC::off(void) { setPower(false); } -// Set the requested power state of the A/C. +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRMideaAC::setPower(const bool on) { setBit(&remote_state, kMideaACPowerOffset, on); } -// Return the requested power state of the A/C. +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRMideaAC::getPower(void) { return GETBIT64(remote_state, kMideaACPowerOffset); } -// Returns true if we want the A/C unit to work natively in Celsius. +/// Is the device currently using Celsius or the Fahrenheit temp scale? +/// @return true, the A/C unit uses Celsius natively, false, is Fahrenheit. bool IRMideaAC::getUseCelsius(void) { return !GETBIT64(remote_state, kMideaACCelsiusOffset); } -// Set the A/C unit to use Celsius natively. +/// Set the A/C unit to use Celsius natively. +/// @param[in] on true, the setting is on. false, the setting is off. void IRMideaAC::setUseCelsius(const bool on) { if (on != getUseCelsius()) { // We need to change. uint8_t native_temp = getTemp(!on); // Get the old native temp. @@ -162,10 +163,9 @@ void IRMideaAC::setUseCelsius(const bool on) { } } -// Set the temperature. -// Args: -// temp: Temp. in degrees. -// useCelsius: Degree type to use. Celsius (true) or Fahrenheit (false) +/// Set the temperature. +/// @param[in] temp The temperature in degrees celsius. +/// @param[in] useCelsius true, use the Celsius temp scale. false, is Fahrenheit void IRMideaAC::setTemp(const uint8_t temp, const bool useCelsius) { uint8_t max_temp = kMideaACMaxTempF; uint8_t min_temp = kMideaACMinTempF; @@ -184,11 +184,9 @@ void IRMideaAC::setTemp(const uint8_t temp, const bool useCelsius) { setBits(&remote_state, kMideaACTempOffset, kMideaACTempSize, new_temp); } -// Return the set temp. -// Args: -// celsius: Flag indicating if the results are in Celsius or Fahrenheit. -// Returns: -// A uint8_t containing the temperature. +/// Get the current temperature setting. +/// @param[in] celsius true, the results are in Celsius. false, in Fahrenheit. +/// @return The current setting for temp. in the requested units/scale. uint8_t IRMideaAC::getTemp(const bool celsius) { uint8_t temp = GETBITS64(remote_state, kMideaACTempOffset, kMideaACTempSize); if (getUseCelsius()) @@ -200,26 +198,27 @@ uint8_t IRMideaAC::getTemp(const bool celsius) { return temp; } -// Set the speed of the fan, -// 1-3 set the speed, 0 or anything else set it to auto. +/// Set the speed of the fan. +/// @param[in] fan The desired setting. 1-3 set the speed, 0 for auto. void IRMideaAC::setFan(const uint8_t fan) { setBits(&remote_state, kMideaACFanOffset, kMideaACFanSize, (fan > kMideaACFanHigh) ? kMideaACFanAuto : fan); } -// Return the requested state of the unit's fan. +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRMideaAC::getFan(void) { return GETBITS64(remote_state, kMideaACFanOffset, kMideaACFanSize); } -// Get the requested climate operation mode of the a/c unit. -// Returns: -// A uint8_t containing the A/C mode. +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRMideaAC::getMode(void) { return GETBITS64(remote_state, kMideaACModeOffset, kModeBitsSize); } -// Set the requested climate operation mode of the a/c unit. +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRMideaAC::setMode(const uint8_t mode) { switch (mode) { case kMideaACAuto: @@ -234,35 +233,38 @@ void IRMideaAC::setMode(const uint8_t mode) { } } -// Set the Sleep state of the A/C. +/// Set the Sleep setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRMideaAC::setSleep(const bool on) { setBit(&remote_state, kMideaACSleepOffset, on); } -// Return the Sleep state of the A/C. +/// Get the Sleep setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRMideaAC::getSleep(void) { return GETBIT64(remote_state, kMideaACSleepOffset); } -// Set the A/C to toggle the vertical swing toggle for the next send. +/// Set the A/C to toggle the vertical swing toggle for the next send. +/// @param[in] on true, the setting is on. false, the setting is off. void IRMideaAC::setSwingVToggle(const bool on) { _SwingVToggle = on; } -// Return if the message/state is just a Swing V toggle message/command. +/// Is the current state a vertical swing toggle message? +/// @return true, it is. false, it isn't. bool IRMideaAC::isSwingVToggle(void) { return remote_state == kMideaACToggleSwingV; } -// Return the Swing V toggle state of the A/C. +// Get the vertical swing toggle state of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRMideaAC::getSwingVToggle(void) { _SwingVToggle |= isSwingVToggle(); return _SwingVToggle; } -// Calculate the checksum for a given array. -// Args: -// state: The state to calculate the checksum over. -// Returns: -// The 8 bit checksum value. +/// Calculate the checksum for a given state. +/// @param[in] state The value to calc the checksum of. +/// @return The calculated checksum value. uint8_t IRMideaAC::calcChecksum(const uint64_t state) { uint8_t sum = 0; uint64_t temp_state = state; @@ -275,23 +277,22 @@ uint8_t IRMideaAC::calcChecksum(const uint64_t state) { return reverseBits(sum, 8); } -// Verify the checksum is valid for a given state. -// Args: -// state: The state to verify the checksum of. -// Returns: -// A boolean. +/// Verify the checksum is valid for a given state. +/// @param[in] state The state to verify the checksum of. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRMideaAC::validChecksum(const uint64_t state) { return GETBITS64(state, 0, 8) == calcChecksum(state); } -// Calculate & set the checksum for the current internal state of the remote. +/// Calculate & set the checksum for the current internal state of the remote. void IRMideaAC::checksum(void) { // Stored the checksum value in the last byte. setBits(&remote_state, 0, 8, calcChecksum(remote_state)); } - -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRMideaAC::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kMideaACCool; @@ -302,7 +303,9 @@ uint8_t IRMideaAC::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRMideaAC::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: @@ -314,7 +317,9 @@ uint8_t IRMideaAC::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRMideaAC::toCommonMode(const uint8_t mode) { switch (mode) { case kMideaACCool: return stdAc::opmode_t::kCool; @@ -325,7 +330,9 @@ stdAc::opmode_t IRMideaAC::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRMideaAC::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kMideaACFanHigh: return stdAc::fanspeed_t::kMax; @@ -335,26 +342,28 @@ stdAc::fanspeed_t IRMideaAC::toCommonFanSpeed(const uint8_t speed) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @param[in] prev A Ptr to the previous state. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRMideaAC::toCommon(const stdAc::state_t *prev) { stdAc::state_t result; if (prev != NULL) { result = *prev; } else { - // Fixed/Not supported/Non-zero defaults. - result.protocol = decode_type_t::MIDEA; - result.model = -1; // No models used. - result.swingh = stdAc::swingh_t::kOff; - result.swingv = stdAc::swingv_t::kOff; - result.quiet = false; - result.turbo = false; - result.clean = false; - result.econo = false; - result.filter = false; - result.light = false; - result.beep = false; - result.sleep = -1; - result.clock = -1; + // Fixed/Not supported/Non-zero defaults. + result.protocol = decode_type_t::MIDEA; + result.model = -1; // No models used. + result.swingh = stdAc::swingh_t::kOff; + result.swingv = stdAc::swingv_t::kOff; + result.quiet = false; + result.turbo = false; + result.clean = false; + result.econo = false; + result.filter = false; + result.light = false; + result.beep = false; + result.sleep = -1; + result.clock = -1; } if (this->isSwingVToggle()) { result.swingv = result.swingv != stdAc::swingv_t::kOff ? @@ -370,7 +379,8 @@ stdAc::state_t IRMideaAC::toCommon(const stdAc::state_t *prev) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRMideaAC::toString(void) { String result = ""; result.reserve(100); // Reserve some heap for the string to reduce fragging. @@ -393,19 +403,15 @@ String IRMideaAC::toString(void) { } #if DECODE_MIDEA -// Decode the supplied Midea message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kMideaBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: Alpha / Needs testing against a real device. -// +/// Decode the supplied Midea message. +/// Status: Alpha / Needs testing 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. +/// @param[in] nbits The number of data bits to expect. +/// Typically kHitachiAcBits, kHitachiAc1Bits, kHitachiAc2Bits, +/// kHitachiAc344Bits +/// @param[in] strict Flag indicating if we should perform strict matching. bool IRrecv::decodeMidea(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { uint8_t min_nr_of_messages = 1; @@ -458,3 +464,80 @@ bool IRrecv::decodeMidea(decode_results *results, uint16_t offset, return true; } #endif // DECODE_MIDEA + +#if SEND_MIDEA24 +/// Send a Midea24 formatted message. +/// Status: STABLE / Confirmed working on 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. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1170 +/// @note This protocol is basically a 48-bit version of the NEC protocol with +/// alternate bytes inverted, thus only 24 bits of real data, and with at +/// least a single repeat. +/// @warning Can't be used beyond 32 bits. +void IRsend::sendMidea24(const uint64_t data, const uint16_t nbits, + const uint16_t repeat) { + uint64_t newdata = 0; + // Construct the data into bye & inverted byte pairs. + for (int16_t i = nbits - 8; i >= 0; i -= 8) { + // Shuffle the data to be sent so far. + newdata <<= 16; + uint8_t next = GETBITS64(data, i, 8); + newdata |= ((next << 8) | (next ^ 0xFF)); + } + sendNEC(newdata, nbits * 2, repeat); +} +#endif // SEND_MIDEA24 + +#if DECODE_MIDEA24 +/// Decode the supplied Midea24 message. +/// Status: STABLE / Confirmed working on a real device. +/// @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. +/// @note This protocol is basically a 48-bit version of the NEC protocol with +/// alternate bytes inverted, thus only 24 bits of real data. +/// @warning Can't be used beyond 32 bits. +bool IRrecv::decodeMidea24(decode_results *results, uint16_t offset, + const uint16_t nbits, const bool strict) { + // Not strictly a MIDEA24 message. + if (strict && nbits != kMidea24Bits) return false; + if (nbits > 32) return false; // Can't successfully match something that big. + + uint64_t longdata = 0; + if (!matchGeneric(results->rawbuf + offset, &longdata, + results->rawlen - offset, nbits * 2, + kNecHdrMark, kNecHdrSpace, + kNecBitMark, kNecOneSpace, + kNecBitMark, kNecZeroSpace, + kNecBitMark, kMidea24MinGap, true)) return false; + + // Build the result by checking every second byte is a complement(inversion) + // of the previous one. + uint32_t data = 0; + for (uint8_t i = nbits * 2; i >= 16;) { + // Shuffle the data collected so far. + data <<= 8; + i -= 8; + uint8_t current = GETBITS64(longdata, i, 8); + i -= 8; + uint8_t next = GETBITS64(longdata, i, 8); + // Check they are an inverted pair. + if (current != (next ^ 0xFF)) return false; // They are not, so abort. + data |= current; + } + + // Success + results->decode_type = decode_type_t::MIDEA24; + results->bits = nbits; + results->value = data; + results->address = 0; + results->command = 0; + return true; +} +#endif // DECODE_MIDEA24 diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Midea.h b/lib/IRremoteESP8266-2.7.8/src/ir_Midea.h similarity index 75% rename from lib/IRremoteESP8266-2.7.5/src/ir_Midea.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Midea.h index af005d729..b7825f569 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Midea.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Midea.h @@ -1,11 +1,16 @@ // Copyright 2017 David Conran -// Midea + +/// @file +/// @brief Support for Midea protocols. +/// Midea added by crankyoldgit & bwze +/// @see https://docs.google.com/spreadsheets/d/1TZh4jWrx4h9zzpYUI9aYXMl1fYOiqu-xVuOOMqagxrs/edit?usp=sharing // Supports: -// Brand: Pioneer System, Model: RYBO12GMFILCAD A/C (12K BTU) -// Brand: Pioneer System, Model: RUBO18GMFILCAD A/C (18K BTU) -// Brand: Comfee, Model: MPD1-12CRN7 A/C -// Brand: Keystone, Model: RG57H4(B)BGEF remote +// Brand: Pioneer System, Model: RYBO12GMFILCAD A/C (12K BTU) (MIDEA) +// Brand: Pioneer System, Model: RUBO18GMFILCAD A/C (18K BTU) (MIDEA) +// Brand: Comfee, Model: MPD1-12CRN7 A/C (MIDEA) +// Brand: Keystone, Model: RG57H4(B)BGEF remote (MIDEA) +// Brand: Midea, Model: FS40-7AR Stand Fan (MIDEA24) #ifndef IR_MIDEA_H_ #define IR_MIDEA_H_ @@ -21,10 +26,6 @@ #include "IRsend_test.h" #endif -// Midea added by crankyoldgit & bwze -// Ref: -// https://docs.google.com/spreadsheets/d/1TZh4jWrx4h9zzpYUI9aYXMl1fYOiqu-xVuOOMqagxrs/edit?usp=sharing - // Constants const uint8_t kMideaACTempOffset = 24; const uint8_t kMideaACTempSize = 5; // Bits @@ -66,15 +67,21 @@ const uint64_t kMideaACToggleSwingV = 0x0000A201FFFFFF7C; #define MIDEA_AC_MIN_TEMP_C kMideaACMinTempC #define MIDEA_AC_MAX_TEMP_C kMideaACMaxTempC +// Classes +/// Class for handling detailed Midea A/C messages. +/// @warning Consider this very alpha code. class IRMideaAC { public: explicit IRMideaAC(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - void stateReset(void); #if SEND_MIDEA void send(const uint16_t repeat = kMideaMinRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + /// 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_MIDEA void begin(void); void on(void); @@ -106,11 +113,13 @@ class IRMideaAC { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - uint64_t remote_state; + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint64_t remote_state; ///< The state of the IR remote in IR code form. bool _SwingVToggle; void checksum(void); static uint8_t calcChecksum(const uint64_t state); diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Mitsubishi.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Mitsubishi.cpp similarity index 71% rename from lib/IRremoteESP8266-2.7.5/src/ir_Mitsubishi.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Mitsubishi.cpp index b8d62e109..1f9f25c1e 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Mitsubishi.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Mitsubishi.cpp @@ -3,7 +3,18 @@ // Copyright 2019 Mark Kuchel // Copyright 2018 Denes Varga -// Mitsubishi +/// @file +/// @brief Support for Mitsubishi protocols. +/// Mitsubishi (TV) decoding added from https://github.com/z3t0/Arduino-IRremote +/// Mitsubishi (TV) sending & Mitsubishi A/C support added by David Conran +/// @see GlobalCache's Control Tower's Mitsubishi TV data. +/// @see https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Mitsubishi.cpp +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/441 +/// @see https://github.com/r45635/HVAC-IR-Control/blob/master/HVAC_ESP8266/HVAC_ESP8266.ino#L84 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/619 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/888 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/947 +/// @see https://github.com/kuchel77 #include "ir_Mitsubishi.h" #include @@ -17,15 +28,9 @@ #include "IRutils.h" #include "ir_Tcl.h" -// Mitsubishi (TV) decoding added from https://github.com/z3t0/Arduino-IRremote -// Mitsubishi (TV) sending & Mitsubishi A/C support added by David Conran - // Constants // Mitsubishi TV // period time is 1/33000Hz = 30.303 uSeconds (T) -// Ref: -// GlobalCache's Control Tower's Mitsubishi TV data. -// https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Mitsubishi.cpp const uint16_t kMitsubishiTick = 30; const uint16_t kMitsubishiBitMarkTicks = 10; const uint16_t kMitsubishiBitMark = kMitsubishiBitMarkTicks * kMitsubishiTick; @@ -41,9 +46,6 @@ const uint16_t kMitsubishiMinGapTicks = 936; const uint16_t kMitsubishiMinGap = kMitsubishiMinGapTicks * kMitsubishiTick; // Mitsubishi Projector (HC3000) -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/441 - const uint16_t kMitsubishi2HdrMark = 8400; const uint16_t kMitsubishi2HdrSpace = kMitsubishi2HdrMark / 2; const uint16_t kMitsubishi2BitMark = 560; @@ -52,9 +54,6 @@ const uint16_t kMitsubishi2OneSpace = kMitsubishi2ZeroSpace * 3; const uint16_t kMitsubishi2MinGap = 28500; // Mitsubishi A/C -// Ref: -// https://github.com/r45635/HVAC-IR-Control/blob/master/HVAC_ESP8266/HVAC_ESP8266.ino#L84 - const uint16_t kMitsubishiAcHdrMark = 3400; const uint16_t kMitsubishiAcHdrSpace = 1750; const uint16_t kMitsubishiAcBitMark = 450; @@ -65,9 +64,6 @@ const uint16_t kMitsubishiAcRptSpace = 17100; const uint8_t kMitsubishiAcExtraTolerance = 5; // Mitsubishi 136 bit A/C -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/888 - const uint16_t kMitsubishi136HdrMark = 3324; const uint16_t kMitsubishi136HdrSpace = 1474; const uint16_t kMitsubishi136BitMark = 467; @@ -76,9 +72,6 @@ const uint16_t kMitsubishi136ZeroSpace = 351; const uint32_t kMitsubishi136Gap = kDefaultMessageGap; // Mitsubishi 112 bit A/C -// Ref: -// https://github.com/kuchel77 - const uint16_t kMitsubishi112HdrMark = 3450; const uint16_t kMitsubishi112HdrSpace = 1696; const uint16_t kMitsubishi112BitMark = 450; @@ -100,20 +93,14 @@ using irutils::setBit; using irutils::setBits; #if SEND_MITSUBISHI -// Send a Mitsubishi message -// -// Args: -// data: Contents of the message to be sent. -// nbits: Nr. of bits of data to be sent. Typically kMitsubishiBits. -// repeat: Nr. of additional times the message is to be sent. -// -// Status: STABLE / Working. -// -// Notes: -// This protocol appears to have no header. -// Ref: -// https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Mitsubishi.cpp -// GlobalCache's Control Tower's Mitsubishi TV data. +/// Send the supplied Mitsubishi 16-bit message. +/// Status: STABLE / Working. +/// @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. +/// @note This protocol appears to have no header. +/// @see https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Mitsubishi.cpp +/// @see GlobalCache's Control Tower's Mitsubishi TV data. void IRsend::sendMitsubishi(uint64_t data, uint16_t nbits, uint16_t repeat) { sendGeneric(0, 0, // No Header kMitsubishiBitMark, kMitsubishiOneSpace, kMitsubishiBitMark, @@ -123,24 +110,16 @@ void IRsend::sendMitsubishi(uint64_t data, uint16_t nbits, uint16_t repeat) { #endif // SEND_MITSUBISHI #if DECODE_MITSUBISHI -// Decode the supplied Mitsubishi message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of data bits to expect. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Working. -// -// Notes: -// This protocol appears to have no header. -// -// Ref: -// GlobalCache's Control Tower's Mitsubishi TV data. +/// Decode the supplied Mitsubishi 16-bit message. +/// Status: STABLE / Working. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @note This protocol appears to have no header. +/// @see GlobalCache's Control Tower's Mitsubishi TV data. bool IRrecv::decodeMitsubishi(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (strict && nbits != kMitsubishiBits) @@ -167,24 +146,18 @@ bool IRrecv::decodeMitsubishi(decode_results *results, uint16_t offset, #endif // DECODE_MITSUBISHI #if SEND_MITSUBISHI2 -// Send a Mitsubishi2 message -// -// Args: -// data: Contents of the message to be sent. -// nbits: Nr. of bits of data to be sent. Typically kMitsubishiBits. -// repeat: Nr. of additional times the message is to be sent. -// -// Status: BETA / Probably works. -// -// Notes: -// Based on a Mitsubishi HC3000 projector's remote. -// This protocol appears to have a manditory in-protocol repeat. -// That is in *addition* to the entire message needing to be sent twice -// for the device to accept the command. That is separate from the repeat. -// i.e. Allegedly, the real remote requires the "Off" button pressed twice. -// You will need to add a suitable gap yourself. -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/441 +/// Send a supplied second variant Mitsubishi 16-bit message. +/// Status: BETA / Probably works. +/// @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. +/// @note Based on a Mitsubishi HC3000 projector's remote. +/// This protocol appears to have a manditory in-protocol repeat. +/// That is in *addition* to the entire message needing to be sent twice +/// for the device to accept the command. That is separate from the repeat. +/// i.e. Allegedly, the real remote requires the "Off" button pressed twice. +/// You will need to add a suitable gap yourself. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/441 void IRsend::sendMitsubishi2(uint64_t data, uint16_t nbits, uint16_t repeat) { for (uint16_t i = 0; i <= repeat; i++) { // First half of the data. @@ -203,25 +176,15 @@ void IRsend::sendMitsubishi2(uint64_t data, uint16_t nbits, uint16_t repeat) { #endif // SEND_MITSUBISHI2 #if DECODE_MITSUBISHI2 -// Decode the supplied Mitsubishi2 message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of data bits to expect. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Works. -// -// Notes: -// Hardware supported: -// * Mitsubishi HC3000 projector's remote. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/441 +/// Decode the supplied second variation of a Mitsubishi 16-bit message. +/// Status: STABLE / Working. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/441 bool IRrecv::decodeMitsubishi2(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen <= 2 * nbits + kHeader + (kFooter * 2) - 1 + offset) @@ -262,16 +225,11 @@ bool IRrecv::decodeMitsubishi2(decode_results *results, uint16_t offset, #endif // DECODE_MITSUBISHI2 #if SEND_MITSUBISHI_AC -// Send a Mitsubishi A/C message. -// -// Args: -// data: An array of bytes containing the IR command. -// nbytes: Nr. of bytes of data in the array. (>=kMitsubishiACStateLength) -// repeat: Nr. of times the message is to be repeated. -// (Default = kMitsubishiACMinRepeat). -// -// Status: STABLE / Working. -// +/// Send a Mitsubishi 144-bit A/C formatted message. (MITSUBISHI_AC) +/// Status: STABLE / Working. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendMitsubishiAC(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { if (nbytes < kMitsubishiACStateLength) @@ -285,21 +243,14 @@ void IRsend::sendMitsubishiAC(const unsigned char data[], const uint16_t nbytes, #endif // SEND_MITSUBISHI_AC #if DECODE_MITSUBISHI_AC -// Decode the supplied Mitsubishi message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of data bits to expect. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: BETA / Probably works -// -// Ref: -// https://www.analysir.com/blog/2015/01/06/reverse-engineering-mitsubishi-ac-infrared-protocol/ +/// Decode the supplied Mitsubish 144-bit A/C message. +/// Status: BETA / Probably works +/// @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. +/// @see https://www.analysir.com/blog/2015/01/06/reverse-engineering-mitsubishi-ac-infrared-protocol/ bool IRrecv::decodeMitsubishiAC(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { @@ -423,17 +374,17 @@ bool IRrecv::decodeMitsubishiAC(decode_results *results, uint16_t offset, // Code to emulate Mitsubishi A/C IR remote control unit. // Inspired and derived from the work done at: // https://github.com/r45635/HVAC-IR-Control -// -// Warning: Consider this very alpha code. Seems to work, but not validated. -// -// Equipment it seems compatible with: -// * -// Initialise the object. + +/// 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? +/// @warning Consider this very alpha code. Seems to work, but not validated. IRMitsubishiAC::IRMitsubishiAC(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { this->stateReset(); } -// Reset the state of the remote to a known good state/sequence. +/// Reset the state of the remote to a known good state/sequence. void IRMitsubishiAC::stateReset(void) { // The state of the IR remote in IR code form. // Known good state obtained from: @@ -443,69 +394,83 @@ void IRMitsubishiAC::stateReset(void) { setRaw(kReset); } -// Configure the pin for output. +/// Set up hardware to be able to send a message. void IRMitsubishiAC::begin(void) { _irsend.begin(); } #if SEND_MITSUBISHI_AC -// Send the current desired state to the IR LED. +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRMitsubishiAC::send(const uint16_t repeat) { _irsend.sendMitsubishiAC(getRaw(), kMitsubishiACStateLength, repeat); } #endif // SEND_MITSUBISHI_AC -// Return a pointer to the internal state date of the remote. +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t *IRMitsubishiAC::getRaw(void) { this->checksum(); return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] data A valid code for this protocol. void IRMitsubishiAC::setRaw(const uint8_t *data) { memcpy(remote_state, data, kMitsubishiACStateLength); } -// Calculate the checksum for the current internal state of the remote. +/// Calculate and set the checksum values for the internal state. void IRMitsubishiAC::checksum(void) { remote_state[kMitsubishiACStateLength - 1] = calculateChecksum(remote_state); } +/// Verify the checksum is valid for a given state. +/// @param[in] data The array to verify the checksum of. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRMitsubishiAC::validChecksum(const uint8_t *data) { return calculateChecksum(data) == data[kMitsubishiACStateLength - 1]; } +/// Calculate the checksum for a given state. +/// @param[in] data The value to calc the checksum of. +/// @return The calculated checksum value. uint8_t IRMitsubishiAC::calculateChecksum(const uint8_t *data) { return sumBytes(data, kMitsubishiACStateLength - 1); } -// Set the requested power state of the A/C to on. +/// Set the requested power state of the A/C to on. void IRMitsubishiAC::on(void) { setPower(true); } -// Set the requested power state of the A/C to off. +/// Set the requested power state of the A/C to off. void IRMitsubishiAC::off(void) { setPower(false); } -// Set the requested power state of the A/C. +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRMitsubishiAC::setPower(bool on) { setBit(&remote_state[5], kMitsubishiAcPowerOffset, on); } -// Return the requested power state of the A/C. +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRMitsubishiAC::getPower(void) { return GETBIT8(remote_state[5], kMitsubishiAcPowerOffset); } -// Set the temp. in deg C +/// Set the temperature. +/// @param[in] degrees The temperature in degrees celsius. void IRMitsubishiAC::setTemp(const uint8_t degrees) { uint8_t temp = std::max((uint8_t)kMitsubishiAcMinTemp, degrees); temp = std::min((uint8_t)kMitsubishiAcMaxTemp, temp); remote_state[7] = temp - kMitsubishiAcMinTemp; } -// Return the set temp. in deg C +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRMitsubishiAC::getTemp(void) { return (remote_state[7] + kMitsubishiAcMinTemp); } -// Set the speed of the fan, 0-6. -// 0 is auto, 1-5 is the speed, 6 is silent. +/// Set the speed of the fan. +/// @param[in] speed The desired setting. 0 is auto, 1-5 is speed, 6 is silent. void IRMitsubishiAC::setFan(const uint8_t speed) { uint8_t fan = speed; // Bounds check @@ -519,7 +484,8 @@ void IRMitsubishiAC::setFan(const uint8_t speed) { setBits(&remote_state[9], kMitsubishiAcFanOffset, kMitsubishiAcFanSize, fan); } -// Return the requested state of the unit's fan. +/// Get the current fan speed setting. +/// @return The current fan speed/mode. uint8_t IRMitsubishiAC::getFan(void) { uint8_t fan = GETBITS8(remote_state[9], kMitsubishiAcFanOffset, kMitsubishiAcFanSize); @@ -527,12 +493,14 @@ uint8_t IRMitsubishiAC::getFan(void) { return fan; } -// Return the requested climate operation mode of the a/c unit. +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRMitsubishiAC::getMode(void) { return GETBITS8(remote_state[6], kMitsubishiAcModeOffset, kModeBitsSize); } -// Set the requested climate operation mode of the a/c unit. +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRMitsubishiAC::setMode(const uint8_t mode) { // If we get an unexpected mode, default to AUTO. switch (mode) { @@ -547,7 +515,8 @@ void IRMitsubishiAC::setMode(const uint8_t mode) { setBits(&remote_state[6], kMitsubishiAcModeOffset, kModeBitsSize, mode); } -// Set the requested vane operation mode of the a/c unit. +/// Set the requested vane (Vertical Swing) operation mode of the a/c unit. +/// @param[in] position The position/mode to set the vane to. void IRMitsubishiAC::setVane(const uint8_t position) { uint8_t pos = std::min(position, kMitsubishiAcVaneAutoMove); // bounds check setBit(&remote_state[9], kMitsubishiAcVaneBitOffset); @@ -555,62 +524,83 @@ void IRMitsubishiAC::setVane(const uint8_t position) { pos); } -// Set the requested wide-vane operation mode of the a/c unit. +/// Set the requested wide-vane (Horizontal Swing) operation mode of the a/c. +/// @param[in] position The position/mode to set the wide vane to. void IRMitsubishiAC::setWideVane(const uint8_t position) { setBits(&remote_state[8], kHighNibble, kNibbleSize, std::min(position, kMitsubishiAcWideVaneAuto)); } -// Return the requested vane operation mode of the a/c unit. +/// Get the Vane (Vertical Swing) mode of the A/C. +/// @return The native position/mode setting. uint8_t IRMitsubishiAC::getVane(void) { return GETBITS8(remote_state[9], kMitsubishiAcVaneOffset, kMitsubishiAcVaneSize); } -// Return the requested wide vane operation mode of the a/c unit. +/// Get the Wide Vane (Horizontal Swing) mode of the A/C. +/// @return The native position/mode setting. uint8_t IRMitsubishiAC::getWideVane(void) { return GETBITS8(remote_state[8], kHighNibble, kNibbleSize); } -// Return the clock setting of the message. 1=1/6 hour. e.g. 4pm = 48 +/// Get the clock time of the A/C unit. +/// @return Nr. of 10 minute increments past midnight. +/// @note 1 = 1/6 hour (10 minutes). e.g. 4pm = 48. uint8_t IRMitsubishiAC::getClock(void) { return remote_state[10]; } -// Set the current time. 1 = 1/6 hour. e.g. 6am = 36. +/// Set the clock time on the A/C unit. +/// @param[in] clock Nr. of 10 minute increments past midnight. +/// @note 1 = 1/6 hour (10 minutes). e.g. 6am = 36. void IRMitsubishiAC::setClock(const uint8_t clock) { remote_state[10] = clock; } -// Return the desired start time. 1 = 1/6 hour. e.g. 1am = 6 +/// Get the desired start time of the A/C unit. +/// @return Nr. of 10 minute increments past midnight. +/// @note 1 = 1/6 hour (10 minutes). e.g. 4pm = 48. uint8_t IRMitsubishiAC::getStartClock(void) { return remote_state[12]; } -// Set the desired start time of the AC. 1 = 1/6 hour. e.g. 8pm = 120 +/// Set the desired start time of the A/C unit. +/// @param[in] clock Nr. of 10 minute increments past midnight. +/// @note 1 = 1/6 hour (10 minutes). e.g. 8pm = 120. void IRMitsubishiAC::setStartClock(const uint8_t clock) { remote_state[12] = clock; } -// Return the desired stop time of the AC. 1 = 1/6 hour. e.g 10pm = 132 +/// Get the desired stop time of the A/C unit. +/// @return Nr. of 10 minute increments past midnight. +/// @note 1 = 1/6 hour (10 minutes). e.g. 10pm = 132. uint8_t IRMitsubishiAC::getStopClock(void) { return remote_state[11]; } -// Set the desired stop time of the AC. 1 = 1/6 hour. e.g 10pm = 132 +/// Set the desired stop time of the A/C unit. +/// @param[in] clock Nr. of 10 minute increments past midnight. +/// @note 1 = 1/6 hour (10 minutes). e.g. 10pm = 132. void IRMitsubishiAC::setStopClock(const uint8_t clock) { remote_state[11] = clock; } -// Return the timer setting. Possible values: kMitsubishiAcNoTimer, -// kMitsubishiAcStartTimer, kMitsubishiAcStopTimer, -// kMitsubishiAcStartStopTimer +/// Get the timers active setting of the A/C. +/// @return The current timers enabled. +/// @note Possible values: kMitsubishiAcNoTimer, +/// kMitsubishiAcStartTimer, kMitsubishiAcStopTimer, +/// kMitsubishiAcStartStopTimer uint8_t IRMitsubishiAC::getTimer(void) { return GETBITS8(remote_state[13], 0, 3); } -// Set the timer setting. Possible values: kMitsubishiAcNoTimer, -// kMitsubishiAcStartTimer, kMitsubishiAcStopTimer, -// kMitsubishiAcStartStopTimer +/// Set the timers active setting of the A/C. +/// @param[in] timer The timer code indicating which ones are active. +/// @note Possible values: kMitsubishiAcNoTimer, +/// kMitsubishiAcStartTimer, kMitsubishiAcStopTimer, +/// kMitsubishiAcStartStopTimer void IRMitsubishiAC::setTimer(uint8_t timer) { setBits(&remote_state[13], 0, 3, timer); } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRMitsubishiAC::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kMitsubishiAcCool; @@ -620,7 +610,9 @@ uint8_t IRMitsubishiAC::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRMitsubishiAC::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: return kMitsubishiAcFanSilent; @@ -632,7 +624,10 @@ uint8_t IRMitsubishiAC::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a standard A/C vertical swing into its native setting. + +/// Convert a stdAc::swingv_t enum into it's native setting. +/// @param[in] position The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRMitsubishiAC::convertSwingV(const stdAc::swingv_t position) { switch (position) { case stdAc::swingv_t::kHighest: return kMitsubishiAcVaneAutoMove - 6; @@ -645,7 +640,9 @@ uint8_t IRMitsubishiAC::convertSwingV(const stdAc::swingv_t position) { } } -// Convert a standard A/C wide wane swing into its native setting. +/// Convert a stdAc::swingh_t enum into it's native setting. +/// @param[in] position The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRMitsubishiAC::convertSwingH(const stdAc::swingh_t position) { switch (position) { case stdAc::swingh_t::kLeftMax: return kMitsubishiAcWideVaneAuto - 7; @@ -659,7 +656,9 @@ uint8_t IRMitsubishiAC::convertSwingH(const stdAc::swingh_t position) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRMitsubishiAC::toCommonMode(const uint8_t mode) { switch (mode) { case kMitsubishiAcCool: return stdAc::opmode_t::kCool; @@ -669,7 +668,9 @@ stdAc::opmode_t IRMitsubishiAC::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRMitsubishiAC::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kMitsubishiAcFanRealMax: return stdAc::fanspeed_t::kMax; @@ -681,7 +682,9 @@ stdAc::fanspeed_t IRMitsubishiAC::toCommonFanSpeed(const uint8_t speed) { } } -// Convert a native vertical swing to it's common equivalent. +/// Convert a native vertical swing postion to it's common equivalent. +/// @param[in] pos A native position to convert. +/// @return The common vertical swing position. stdAc::swingv_t IRMitsubishiAC::toCommonSwingV(const uint8_t pos) { switch (pos) { case 1: return stdAc::swingv_t::kHighest; @@ -693,7 +696,9 @@ stdAc::swingv_t IRMitsubishiAC::toCommonSwingV(const uint8_t pos) { } } -// Convert a native horizontal swing to it's common equivalent. +/// Convert a native horizontal swing postion to it's common equivalent. +/// @param[in] pos A native position to convert. +/// @return The common horizontal swing position. stdAc::swingh_t IRMitsubishiAC::toCommonSwingH(const uint8_t pos) { switch (pos) { case 1: return stdAc::swingh_t::kLeftMax; @@ -706,7 +711,8 @@ stdAc::swingh_t IRMitsubishiAC::toCommonSwingH(const uint8_t pos) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRMitsubishiAC::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::MITSUBISHI_AC; @@ -731,7 +737,8 @@ stdAc::state_t IRMitsubishiAC::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the internal state into a human readable string. +/// @return A string containing the settings in human-readable form. String IRMitsubishiAC::toString(void) { String result = ""; result.reserve(110); // Reserve some heap for the string to reduce fragging. @@ -796,18 +803,12 @@ String IRMitsubishiAC::toString(void) { } #if SEND_MITSUBISHI136 -// Send a Mitsubishi136 A/C message. -// -// Args: -// data: An array of bytes containing the IR command. -// nbytes: Nr. of bytes of data in the array. (>=kMitsubishi136StateLength) -// repeat: Nr. of times the message is to be repeated. -// (Default = kMitsubishi136MinRepeat). -// -// Status: BETA / Probably working. Needs to be tested against a real device. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/888 +/// Send a Mitsubishi 136-bit A/C message. (MITSUBISHI136) +/// Status: BETA / Probably working. Needs to be tested against a real device. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/888 void IRsend::sendMitsubishi136(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { @@ -823,21 +824,14 @@ void IRsend::sendMitsubishi136(const unsigned char data[], #endif // SEND_MITSUBISHI136 #if DECODE_MITSUBISHI136 -// Decode the supplied Mitsubishi136 message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of data bits to expect. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Reported as working. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/888 +/// Decode the supplied Mitsubishi 136-bit A/C message. (MITSUBISHI136) +/// Status: STABLE / Reported as working. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/888 bool IRrecv::decodeMitsubishi136(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { @@ -867,17 +861,16 @@ bool IRrecv::decodeMitsubishi136(decode_results *results, uint16_t offset, #endif // DECODE_MITSUBISHI136 // Code to emulate Mitsubishi 136bit A/C IR remote control unit. -// -// Equipment it seems compatible with: -// Brand: Mitsubishi Electric, Model: PEAD-RP71JAA Ducted A/C -// Brand: Mitsubishi Electric, Model: 001CP T7WE10714 remote -// Initialise the object. +/// 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? IRMitsubishi136::IRMitsubishi136(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { this->stateReset(); } -// Reset the state of the remote to a known good state/sequence. +/// Reset the state of the remote to a known good state/sequence. void IRMitsubishi136::stateReset(void) { // The state of the IR remote in IR code form. // Known good state obtained from: @@ -887,13 +880,17 @@ void IRMitsubishi136::stateReset(void) { memcpy(remote_state, kReset, kMitsubishi136StateLength); } -// Calculate the checksum for the current internal state of the remote. +/// Calculate the checksum for the current internal state of the remote. void IRMitsubishi136::checksum(void) { for (uint8_t i = 0; i < 6; i++) remote_state[kMitsubishi136PowerByte + 6 + i] = ~remote_state[kMitsubishi136PowerByte + i]; } +/// Verify the checksum is valid for a given state. +/// @param[in] data The array to verify the checksum of. +/// @param[in] len The length of the data array. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRMitsubishi136::validChecksum(const uint8_t *data, const uint16_t len) { if (len < kMitsubishi136StateLength) return false; const uint16_t half = (len - kMitsubishi136PowerByte) / 2; @@ -906,44 +903,51 @@ bool IRMitsubishi136::validChecksum(const uint8_t *data, const uint16_t len) { return true; } -// Configure the pin for output. +/// Set up hardware to be able to send a message. void IRMitsubishi136::begin(void) { _irsend.begin(); } #if SEND_MITSUBISHI136 -// Send the current desired state to the IR LED. +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRMitsubishi136::send(const uint16_t repeat) { _irsend.sendMitsubishi136(getRaw(), kMitsubishi136StateLength, repeat); } #endif // SEND_MITSUBISHI136 -// Return a pointer to the internal state date of the remote. +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t *IRMitsubishi136::getRaw(void) { checksum(); return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] data A valid code for this protocol. void IRMitsubishi136::setRaw(const uint8_t *data) { memcpy(remote_state, data, kMitsubishi136StateLength); } -// Set the requested power state of the A/C to off. +/// Set the requested power state of the A/C to on. void IRMitsubishi136::on(void) { setPower(true); } -// Set the requested power state of the A/C to off. +/// Set the requested power state of the A/C to off. void IRMitsubishi136::off(void) { setPower(false); } -// Set the requested power state of the A/C. +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRMitsubishi136::setPower(bool on) { setBit(&remote_state[kMitsubishi136PowerByte], kMitsubishi136PowerOffset, on); } -// Return the requested power state of the A/C. +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRMitsubishi136::getPower(void) { return GETBIT8(remote_state[kMitsubishi136PowerByte], kMitsubishi136PowerOffset); } -// Set the temp. in deg C +/// Set the temperature. +/// @param[in] degrees The temperature in degrees celsius. void IRMitsubishi136::setTemp(const uint8_t degrees) { uint8_t temp = std::max((uint8_t)kMitsubishi136MinTemp, degrees); temp = std::min((uint8_t)kMitsubishi136MaxTemp, temp); @@ -951,30 +955,36 @@ void IRMitsubishi136::setTemp(const uint8_t degrees) { temp - kMitsubishiAcMinTemp); } -// Return the set temp. in deg C +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRMitsubishi136::getTemp(void) { return GETBITS8(remote_state[kMitsubishi136TempByte], kHighNibble, kNibbleSize) + kMitsubishiAcMinTemp; } +/// Set the speed of the fan. +/// @param[in] speed The desired setting. void IRMitsubishi136::setFan(const uint8_t speed) { setBits(&remote_state[kMitsubishi136FanByte], kMitsubishi136FanOffset, kMitsubishi136FanSize, std::min(speed, kMitsubishi136FanMax)); } -// Return the requested state of the unit's fan. +/// Get the current fan speed setting. +/// @return The current fan speed/mode. uint8_t IRMitsubishi136::getFan(void) { return GETBITS8(remote_state[kMitsubishi136FanByte], kMitsubishi136FanOffset, kMitsubishi136FanSize); } -// Return the requested climate operation mode of the a/c unit. +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRMitsubishi136::getMode(void) { return GETBITS8(remote_state[kMitsubishi136ModeByte], kMitsubishi136ModeOffset, kModeBitsSize); } -// Set the requested climate operation mode of the a/c unit. +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRMitsubishi136::setMode(const uint8_t mode) { // If we get an unexpected mode, default to AUTO. switch (mode) { @@ -991,7 +1001,8 @@ void IRMitsubishi136::setMode(const uint8_t mode) { } } -// Set the requested vane operation mode of the a/c unit. +/// Set the Vertical Swing mode of the A/C. +/// @param[in] position The position/mode to set the swing to. void IRMitsubishi136::setSwingV(const uint8_t position) { // If we get an unexpected mode, default to auto. switch (position) { @@ -1008,24 +1019,30 @@ void IRMitsubishi136::setSwingV(const uint8_t position) { } } -// Return the requested vane operation mode of the a/c unit. +/// Get the Vertical Swing mode of the A/C. +/// @return The native position/mode setting. uint8_t IRMitsubishi136::getSwingV(void) { return GETBITS8(remote_state[kMitsubishi136SwingVByte], kHighNibble, kNibbleSize); } -// Emulate a quiet setting. There is no true quiet setting on this a/c +/// Set the Quiet mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRMitsubishi136::setQuiet(bool on) { if (on) setFan(kMitsubishi136FanQuiet); else if (getQuiet()) setFan(kMitsubishi136FanLow); } -// Return the requested power state of the A/C. + +/// Get the Quiet mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRMitsubishi136::getQuiet(void) { return getFan() == kMitsubishi136FanQuiet; } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRMitsubishi136::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kMitsubishi136Cool; @@ -1036,7 +1053,9 @@ uint8_t IRMitsubishi136::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRMitsubishi136::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: return kMitsubishi136FanMin; @@ -1047,7 +1066,9 @@ uint8_t IRMitsubishi136::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a standard A/C vertical swing into its native setting. +/// Convert a stdAc::swingv_t enum into it's native setting. +/// @param[in] position The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRMitsubishi136::convertSwingV(const stdAc::swingv_t position) { switch (position) { case stdAc::swingv_t::kHighest: return kMitsubishi136SwingVHighest; @@ -1059,7 +1080,9 @@ uint8_t IRMitsubishi136::convertSwingV(const stdAc::swingv_t position) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRMitsubishi136::toCommonMode(const uint8_t mode) { switch (mode) { case kMitsubishi136Cool: return stdAc::opmode_t::kCool; @@ -1070,7 +1093,9 @@ stdAc::opmode_t IRMitsubishi136::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRMitsubishi136::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kMitsubishi136FanMax: return stdAc::fanspeed_t::kMax; @@ -1081,7 +1106,9 @@ stdAc::fanspeed_t IRMitsubishi136::toCommonFanSpeed(const uint8_t speed) { } } -// Convert a native vertical swing to it's common equivalent. +/// Convert a native vertical swing postion to it's common equivalent. +/// @param[in] pos A native position to convert. +/// @return The common vertical swing position. stdAc::swingv_t IRMitsubishi136::toCommonSwingV(const uint8_t pos) { switch (pos) { case kMitsubishi136SwingVHighest: return stdAc::swingv_t::kHighest; @@ -1092,7 +1119,8 @@ stdAc::swingv_t IRMitsubishi136::toCommonSwingV(const uint8_t pos) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRMitsubishi136::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::MITSUBISHI136; @@ -1117,7 +1145,8 @@ stdAc::state_t IRMitsubishi136::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the internal state into a human readable string. +/// @return A string containing the settings in human-readable form. String IRMitsubishi136::toString(void) { String result = ""; result.reserve(80); // Reserve some heap for the string to reduce fragging. @@ -1146,18 +1175,12 @@ String IRMitsubishi136::toString(void) { #if SEND_MITSUBISHI112 -// Send a Mitsubishi112 A/C message. -// -// Args: -// data: An array of bytes containing the IR command. -// nbytes: Nr. of bytes of data in the array. (>=kMitsubishi112StateLength) -// repeat: Nr. of times the message is to be repeated. -// (Default = kMitsubishi112MinRepeat). -// -// Status: Stable / Reported as working. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/947 +/// Send a Mitsubishi 112-bit A/C formatted message. (MITSUBISHI112) +/// Status: Stable / Reported as working. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/947 void IRsend::sendMitsubishi112(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { @@ -1173,29 +1196,23 @@ void IRsend::sendMitsubishi112(const unsigned char data[], #endif // SEND_MITSUBISHI112 #if DECODE_MITSUBISHI112 || DECODE_TCL112AC -// Decode the supplied Mitsubishi112 / Tcl112Ac message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of data bits to expect. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Reported as working. -// -// Note: Mitsubishi112 & Tcl112Ac are basically the same protocol. -// The only significant difference I can see is Mitsubishi112 has a -// slightly longer header mark. We will use that to determine which -// varient it should be. The other differences require full decoding and -// only only with certain settings. -// There are some other timing differences too, but the tolerances will -// overlap. -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/619 -// https://github.com/crankyoldgit/IRremoteESP8266/issues/947 +/// Decode the supplied Mitsubishi/TCL 112-bit A/C message. +/// (MITSUBISHI112, TCL112AC) +/// Status: STABLE / Reported as working. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @note Note Mitsubishi112 & Tcl112Ac are basically the same protocol. +/// The only significant difference I can see is Mitsubishi112 has a +/// slightly longer header mark. We will use that to determine which +/// variant it should be. The other differences require full decoding and +/// only only with certain settings. +/// There are some other timing differences too, but the tolerances will +/// overlap. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/619 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/947 bool IRrecv::decodeMitsubishi112(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen < (2 * nbits) + kHeader + kFooter - 1 + offset) @@ -1265,17 +1282,16 @@ bool IRrecv::decodeMitsubishi112(decode_results *results, uint16_t offset, #endif // DECODE_MITSUBISHI112 || DECODE_TCL112AC // Code to emulate Mitsubishi 112bit A/C IR remote control unit. -// -// Equipment it seems compatible with: -// Brand: Mitsubishi Electric, Model: MSH-A24WV / MUH-A24WV A/C -// Brand: Mitsubishi Electric, Model: KPOA remote -// Initialise the object. +/// 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? IRMitsubishi112::IRMitsubishi112(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { this->stateReset(); } -// Reset the state of the remote to a known good state/sequence. +/// Reset the state of the remote to a known good state/sequence. void IRMitsubishi112::stateReset(void) { const uint8_t kReset[kMitsubishi112StateLength] = { 0x23, 0xCB, 0x26, 0x01, 0x00, 0x24, 0x03, 0x0B, 0x10, @@ -1283,50 +1299,57 @@ void IRMitsubishi112::stateReset(void) { setRaw(kReset); } -// Calculate the checksum for the current internal state of the remote. +/// Calculate the checksum for the current internal state of the remote. void IRMitsubishi112::checksum(void) { remote_state[kMitsubishi112StateLength - 1] = IRTcl112Ac::calcChecksum( remote_state, kMitsubishi112StateLength); } -// Configure the pin for output. +/// Set up hardware to be able to send a message. void IRMitsubishi112::begin(void) { _irsend.begin(); } #if SEND_MITSUBISHI112 -// Send the current desired state to the IR LED. +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRMitsubishi112::send(const uint16_t repeat) { _irsend.sendMitsubishi112(getRaw(), kMitsubishi112StateLength, repeat); } #endif // SEND_MITSUBISHI112 -// Return a pointer to the internal state date of the remote. +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t *IRMitsubishi112::getRaw(void) { checksum(); return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] data A valid code for this protocol. void IRMitsubishi112::setRaw(const uint8_t *data) { memcpy(remote_state, data, kMitsubishi112StateLength); } -// Set the requested power state of the A/C to off. +/// Set the requested power state of the A/C to off. void IRMitsubishi112::on(void) { setPower(true); } -// Set the requested power state of the A/C to off. +/// Set the requested power state of the A/C to off. void IRMitsubishi112::off(void) { setPower(false); } -// Set the requested power state of the A/C. +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRMitsubishi112::setPower(bool on) { setBit(&remote_state[kMitsubishi112PowerByte], kMitsubishi112PowerOffset, on); } -// Return the requested power state of the A/C. +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRMitsubishi112::getPower(void) { return GETBIT8(remote_state[kMitsubishi112PowerByte], kMitsubishi112PowerOffset); } -// Set the temp. in deg C +/// Set the temperature. +/// @param[in] degrees The temperature in degrees celsius. void IRMitsubishi112::setTemp(const uint8_t degrees) { uint8_t temp = std::max((uint8_t)kMitsubishi112MinTemp, degrees); temp = std::min((uint8_t)kMitsubishi112MaxTemp, temp); @@ -1334,12 +1357,15 @@ void IRMitsubishi112::setTemp(const uint8_t degrees) { kMitsubishi112TempSize, kMitsubishiAcMaxTemp - temp); } -// Return the set temp. in deg C +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRMitsubishi112::getTemp(void) { return kMitsubishiAcMaxTemp - GETBITS8(remote_state[kMitsubishi112TempByte], kLowNibble, kMitsubishi112TempSize); } +/// Set the speed of the fan. +/// @param[in] speed The desired setting. void IRMitsubishi112::setFan(const uint8_t speed) { switch (speed) { case kMitsubishi112FanMin: @@ -1354,19 +1380,22 @@ void IRMitsubishi112::setFan(const uint8_t speed) { } } -// Return the requested state of the unit's fan. +/// Get the current fan speed setting. +/// @return The current fan speed/mode. uint8_t IRMitsubishi112::getFan(void) { return GETBITS8(remote_state[kMitsubishi112FanByte], kMitsubishi112FanOffset, kMitsubishi112FanSize); } -// Return the requested climate operation mode of the a/c unit. +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRMitsubishi112::getMode(void) { return GETBITS8(remote_state[kMitsubishi112ModeByte], kMitsubishi112ModeOffset, kModeBitsSize); } -// Set the requested climate operation mode of the a/c unit. +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRMitsubishi112::setMode(const uint8_t mode) { // If we get an unexpected mode, default to AUTO. switch (mode) { @@ -1383,7 +1412,8 @@ void IRMitsubishi112::setMode(const uint8_t mode) { } } -// Set the requested vane operation mode of the a/c unit. +/// Set the Vertical Swing mode of the A/C. +/// @param[in] position The position/mode to set the swing to. void IRMitsubishi112::setSwingV(const uint8_t position) { // If we get an unexpected mode, default to auto. switch (position) { @@ -1401,13 +1431,15 @@ void IRMitsubishi112::setSwingV(const uint8_t position) { } } -// Return the requested vane operation mode of the a/c unit. +/// Get the Vertical Swing mode of the A/C. +/// @return The native position/mode setting. uint8_t IRMitsubishi112::getSwingV(void) { return GETBITS8(remote_state[kMitsubishi112SwingVByte], kMitsubishi112SwingVOffset, kMitsubishi112SwingVSize); } -// Set the requested vane operation mode of the a/c unit. +/// Set the Horizontal Swing mode of the A/C. +/// @param[in] position The position/mode to set the swing to. void IRMitsubishi112::setSwingH(const uint8_t position) { // If we get an unexpected mode, default to auto. switch (position) { @@ -1426,26 +1458,34 @@ void IRMitsubishi112::setSwingH(const uint8_t position) { } } -// Return the requested vane operation mode of the a/c unit. + +/// Get the Horizontal Swing mode of the A/C. +/// @return The native position/mode setting. uint8_t IRMitsubishi112::getSwingH(void) { return GETBITS8(remote_state[kMitsubishi112SwingHByte], kMitsubishi112SwingHOffset, kMitsubishi112SwingHSize); } -// Emulate a quiet setting. There is no true quiet setting on this a/c +/// Set the Quiet mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. +/// @note There is no true quiet setting on this A/C. void IRMitsubishi112::setQuiet(bool on) { if (on) setFan(kMitsubishi112FanQuiet); else if (getQuiet()) setFan(kMitsubishi112FanLow); } -// Return the requested power state of the A/C. + +/// Get the Quiet mode of the A/C. +/// @return true, the setting is on. false, the setting is off. +/// @note There is no true quiet setting on this A/C. bool IRMitsubishi112::getQuiet(void) { return getFan() == kMitsubishi112FanQuiet; } - -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRMitsubishi112::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kMitsubishi112Cool; @@ -1456,7 +1496,9 @@ uint8_t IRMitsubishi112::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRMitsubishi112::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: return kMitsubishi112FanMin; @@ -1468,7 +1510,9 @@ uint8_t IRMitsubishi112::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a standard A/C vertical swing into its native setting. +/// Convert a stdAc::swingv_t enum into it's native setting. +/// @param[in] position The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRMitsubishi112::convertSwingV(const stdAc::swingv_t position) { switch (position) { case stdAc::swingv_t::kHighest: return kMitsubishi112SwingVHighest; @@ -1480,7 +1524,9 @@ uint8_t IRMitsubishi112::convertSwingV(const stdAc::swingv_t position) { } } -// Convert a standard A/C vertical swing into its native setting. +/// Convert a stdAc::swingh_t enum into it's native setting. +/// @param[in] position The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRMitsubishi112::convertSwingH(const stdAc::swingh_t position) { switch (position) { case stdAc::swingh_t::kLeftMax: return kMitsubishi112SwingHLeftMax; @@ -1494,7 +1540,9 @@ uint8_t IRMitsubishi112::convertSwingH(const stdAc::swingh_t position) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRMitsubishi112::toCommonMode(const uint8_t mode) { switch (mode) { case kMitsubishi112Cool: return stdAc::opmode_t::kCool; @@ -1504,7 +1552,9 @@ stdAc::opmode_t IRMitsubishi112::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRMitsubishi112::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kMitsubishi112FanMax: return stdAc::fanspeed_t::kMax; @@ -1515,7 +1565,9 @@ stdAc::fanspeed_t IRMitsubishi112::toCommonFanSpeed(const uint8_t speed) { } } -// Convert a native vertical swing to it's common equivalent. +/// Convert a native vertical swing postion to it's common equivalent. +/// @param[in] pos A native position to convert. +/// @return The common vertical swing position. stdAc::swingv_t IRMitsubishi112::toCommonSwingV(const uint8_t pos) { switch (pos) { case kMitsubishi112SwingVHighest: return stdAc::swingv_t::kHighest; @@ -1527,7 +1579,9 @@ stdAc::swingv_t IRMitsubishi112::toCommonSwingV(const uint8_t pos) { } } -// Convert a native vertical swing to it's common equivalent. +/// Convert a native horizontal swing postion to it's common equivalent. +/// @param[in] pos A native position to convert. +/// @return The common horizontal swing position. stdAc::swingh_t IRMitsubishi112::toCommonSwingH(const uint8_t pos) { switch (pos) { case kMitsubishi112SwingHLeftMax: return stdAc::swingh_t::kLeftMax; @@ -1540,8 +1594,8 @@ stdAc::swingh_t IRMitsubishi112::toCommonSwingH(const uint8_t pos) { } } - -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRMitsubishi112::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::MITSUBISHI112; @@ -1568,7 +1622,8 @@ stdAc::state_t IRMitsubishi112::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the internal state into a human readable string. +/// @return A string containing the settings in human-readable form. String IRMitsubishi112::toString(void) { String result = ""; result.reserve(80); // Reserve some heap for the string to reduce fragging. diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Mitsubishi.h b/lib/IRremoteESP8266-2.7.8/src/ir_Mitsubishi.h similarity index 76% rename from lib/IRremoteESP8266-2.7.5/src/ir_Mitsubishi.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Mitsubishi.h index 31021514f..04c7bf57d 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Mitsubishi.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Mitsubishi.h @@ -2,17 +2,29 @@ // Copyright 2017-2019 David Conran // Copyright 2019 Mark Kuchel -// Mitsubishi +/// @file +/// @brief Support for Mitsubishi protocols. +/// Mitsubishi (TV) decoding added from https://github.com/z3t0/Arduino-IRremote +/// Mitsubishi (TV) sending & Mitsubishi A/C support added by David Conran +/// @see GlobalCache's Control Tower's Mitsubishi TV data. +/// @see https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Mitsubishi.cpp +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/441 +/// @see https://github.com/r45635/HVAC-IR-Control/blob/master/HVAC_ESP8266/HVAC_ESP8266.ino#L84 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/619 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/888 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/947 +/// @see https://github.com/kuchel77 // Supports: -// Brand: Mitsubishi, Model: TV -// Brand: Mitsubishi, Model: HC3000 Projector +// Brand: Mitsubishi, Model: TV (MITSUBISHI) +// Brand: Mitsubishi, Model: HC3000 Projector (MITSUBISHI2) // Brand: Mitsubishi, Model: MS-GK24VA A/C // Brand: Mitsubishi, Model: KM14A 0179213 remote -// Brand: Mitsubishi Electric, Model: PEAD-RP71JAA Ducted A/C -// Brand: Mitsubishi Electric, Model: 001CP T7WE10714 remote -// Brand: Mitsubishi Electric, Model: MSH-A24WV / MUH-A24WV A/C -// Brand: Mitsubishi Electric, Model: KPOA remote +// Brand: Mitsubishi Electric, Model: PEAD-RP71JAA Ducted A/C (MITSUBISHI136) +// Brand: Mitsubishi Electric, Model: 001CP T7WE10714 remote (MITSUBISHI136) +// Brand: Mitsubishi Electric, Model: MSH-A24WV A/C (MITSUBISHI112) +// Brand: Mitsubishi Electric, Model: MUH-A24WV A/C (MITSUBISHI112) +// Brand: Mitsubishi Electric, Model: KPOA remote (MITSUBISHI112) #ifndef IR_MITSUBISHI_H_ #define IR_MITSUBISHI_H_ @@ -28,8 +40,6 @@ #include "IRsend_test.h" #endif -// Mitsubishi (TV) decoding added from https://github.com/z3t0/Arduino-IRremote -// Mitsubishi (TV) sending & Mitsubishi A/C support added by David Conran // Constants const uint8_t kMitsubishiAcModeOffset = 3; @@ -151,6 +161,10 @@ const uint8_t kMitsubishi112SwingHAuto = 0b1100; #define MITSUBISHI_AC_COOL kMitsubishiAcCool #define MITSUBISHI_AC_AUTO kMitsubishiAcAuto + +/// Class for handling detailed Mitsubishi 144-bit A/C messages. +/// Inspired and derived from the work done at: https://github.com/r45635/HVAC-IR-Control +/// @warning Consider this very alpha code. Seems to work, but not validated. class IRMitsubishiAC { public: explicit IRMitsubishiAC(const uint16_t pin, const bool inverted = false, @@ -159,7 +173,11 @@ class IRMitsubishiAC { static bool validChecksum(const uint8_t* data); #if SEND_MITSUBISHI_AC void send(const uint16_t repeat = kMitsubishiACMinRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + /// 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_MITSUBISHI_AC void begin(void); void on(void); @@ -199,25 +217,30 @@ class IRMitsubishiAC { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - uint8_t remote_state[kMitsubishiACStateLength]; + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint8_t remote_state[kMitsubishiACStateLength]; ///< The state in code form. void checksum(void); static uint8_t calculateChecksum(const uint8_t* data); }; +/// Class for handling detailed Mitsubishi 136-bit A/C messages. class IRMitsubishi136 { public: explicit IRMitsubishi136(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - - void stateReset(void); #if SEND_MITSUBISHI136 void send(const uint16_t repeat = kMitsubishi136MinRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + /// 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_MITSUBISHI136 void begin(void); static bool validChecksum(const uint8_t* data, @@ -249,11 +272,13 @@ class IRMitsubishi136 { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - uint8_t remote_state[kMitsubishi136StateLength]; + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint8_t remote_state[kMitsubishi136StateLength]; ///< The state in code form. void checksum(void); }; @@ -262,12 +287,14 @@ class IRMitsubishi112 { public: explicit IRMitsubishi112(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - - void stateReset(void); #if SEND_MITSUBISHI112 void send(const uint16_t repeat = kMitsubishi112MinRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + /// 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_MITSUBISHI112 void begin(void); void on(void); @@ -301,11 +328,13 @@ class IRMitsubishi112 { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - uint8_t remote_state[kMitsubishi112StateLength]; + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint8_t remote_state[kMitsubishi112StateLength]; ///< The state in code form. void checksum(void); }; diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_MitsubishiHeavy.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_MitsubishiHeavy.cpp similarity index 73% rename from lib/IRremoteESP8266-2.7.5/src/ir_MitsubishiHeavy.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_MitsubishiHeavy.cpp index 39bd3d8d6..7747ded6d 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_MitsubishiHeavy.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_MitsubishiHeavy.cpp @@ -1,17 +1,14 @@ // Copyright 2019 David Conran -// Mitsubishi Heavy Industries A/C remote emulation. -// Code to emulate Mitsubishi Heavy Industries A/C IR remote control units, -// which should control at least the following A/C units: -// Remote Control RLA502A700B: -// Model SRKxxZM-S -// Model SRKxxZMXA-S -// Remote Control RKX502A001C: -// Model SRKxxZJ-S - -// Note: This code was *heavily* influenced by @ToniA's great work & code, -// but it has been written from scratch. -// Nothing was copied other than constants and message analysis. +/// @file +/// @brief Support for Mitsubishi Heavy Industry protocols. +/// Code to emulate Mitsubishi Heavy Industries A/C IR remote control units. +/// @note This code was *heavily* influenced by ToniA's great work & code, +/// but it has been written from scratch. +/// Nothing was copied other than constants and message analysis. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/660 +/// @see https://github.com/ToniA/Raw-IR-decoder-for-Arduino/blob/master/MitsubishiHeavy.cpp +/// @see https://github.com/ToniA/arduino-heatpumpir/blob/master/MitsubishiHeavyHeatpumpIR.cpp #include "ir_MitsubishiHeavy.h" #include @@ -23,11 +20,6 @@ #include #endif -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/660 -// https://github.com/ToniA/Raw-IR-decoder-for-Arduino/blob/master/MitsubishiHeavy.cpp -// https://github.com/ToniA/arduino-heatpumpir/blob/master/MitsubishiHeavyHeatpumpIR.cpp - // Constants const uint16_t kMitsubishiHeavyHdrMark = 3140; const uint16_t kMitsubishiHeavyHdrSpace = 1630; @@ -45,14 +37,11 @@ using irutils::setBit; using irutils::setBits; #if SEND_MITSUBISHIHEAVY -// Send a MitsubishiHeavy 88 bit A/C message. -// -// Args: -// data: Contents of the message to be sent. -// nbits: Nr. of bits of data to be sent. Typically kMitsubishiHeavy88Bits. -// repeat: Nr. of additional times the message is to be sent. -// -// Status: BETA / Appears to be working. Needs testing against a real device. +/// Send a MitsubishiHeavy 88-bit A/C message. +/// Status: BETA / Appears to be working. Needs testing against a real device. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendMitsubishiHeavy88(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { @@ -65,14 +54,11 @@ void IRsend::sendMitsubishiHeavy88(const unsigned char data[], data, nbytes, 38000, false, repeat, kDutyDefault); } -// Send a MitsubishiHeavy 152 bit A/C message. -// -// Args: -// data: Contents of the message to be sent. -// nbits: Nr. of bits of data to be sent. Typically kMitsubishiHeavy152Bits. -// repeat: Nr. of additional times the message is to be sent. -// -// Status: BETA / Appears to be working. Needs testing against a real device. +/// Send a MitsubishiHeavy 152-bit A/C message. +/// Status: BETA / Appears to be working. Needs testing against a real device. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendMitsubishiHeavy152(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { @@ -83,20 +69,29 @@ void IRsend::sendMitsubishiHeavy152(const unsigned char data[], #endif // SEND_MITSUBISHIHEAVY // Class for decoding and constructing MitsubishiHeavy152 AC messages. + +/// 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? IRMitsubishiHeavy152Ac::IRMitsubishiHeavy152Ac(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { stateReset(); } +/// Set up hardware to be able to send a message. void IRMitsubishiHeavy152Ac::begin(void) { _irsend.begin(); } #if SEND_MITSUBISHIHEAVY +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRMitsubishiHeavy152Ac::send(const uint16_t repeat) { _irsend.sendMitsubishiHeavy152(this->getRaw(), kMitsubishiHeavy152StateLength, repeat); } #endif // SEND_MITSUBISHIHEAVY +/// Reset the state of the remote to a known good state/sequence. void IRMitsubishiHeavy152Ac::stateReset(void) { memcpy(remote_state, kMitsubishiHeavyZmsSig, kMitsubishiHeavySigLength); for (uint8_t i = kMitsubishiHeavySigLength; @@ -104,27 +99,39 @@ void IRMitsubishiHeavy152Ac::stateReset(void) { remote_state[17] = 0x80; } +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t *IRMitsubishiHeavy152Ac::getRaw(void) { checksum(); return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] data A valid code for this protocol. void IRMitsubishiHeavy152Ac::setRaw(const uint8_t *data) { memcpy(remote_state, data, kMitsubishiHeavy152StateLength); } +/// Set the requested power state of the A/C to on. void IRMitsubishiHeavy152Ac::on(void) { setPower(true); } +/// Set the requested power state of the A/C to off. void IRMitsubishiHeavy152Ac::off(void) { setPower(false); } +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRMitsubishiHeavy152Ac::setPower(const bool on) { setBit(&remote_state[5], kMitsubishiHeavyPowerOffset, on); } +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRMitsubishiHeavy152Ac::getPower(void) { return GETBIT8(remote_state[5], kMitsubishiHeavyPowerOffset); } +/// Set the temperature. +/// @param[in] temp The temperature in degrees celsius. void IRMitsubishiHeavy152Ac::setTemp(const uint8_t temp) { uint8_t newtemp = temp; newtemp = std::min(newtemp, kMitsubishiHeavyMaxTemp); @@ -133,12 +140,15 @@ void IRMitsubishiHeavy152Ac::setTemp(const uint8_t temp) { newtemp - kMitsubishiHeavyMinTemp); } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRMitsubishiHeavy152Ac::getTemp(void) { return GETBITS8(remote_state[7], kLowNibble, kNibbleSize) + kMitsubishiHeavyMinTemp; } -// Set the speed of the fan +/// Set the speed of the fan. +/// @param[in] speed The desired setting. void IRMitsubishiHeavy152Ac::setFan(const uint8_t speed) { uint8_t newspeed = speed; switch (speed) { @@ -153,10 +163,14 @@ void IRMitsubishiHeavy152Ac::setFan(const uint8_t speed) { setBits(&remote_state[9], kLowNibble, kNibbleSize, newspeed); } +/// Get the current fan speed setting. +/// @return The current fan speed/mode. uint8_t IRMitsubishiHeavy152Ac::getFan(void) { return GETBITS8(remote_state[9], kLowNibble, kNibbleSize); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRMitsubishiHeavy152Ac::setMode(const uint8_t mode) { uint8_t newmode = mode; switch (mode) { @@ -171,38 +185,54 @@ void IRMitsubishiHeavy152Ac::setMode(const uint8_t mode) { setBits(&remote_state[5], kMitsubishiHeavyModeOffset, kModeBitsSize, newmode); } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRMitsubishiHeavy152Ac::getMode(void) { return GETBITS8(remote_state[5], kMitsubishiHeavyModeOffset, kModeBitsSize); } +/// Set the Vertical Swing mode of the A/C. +/// @param[in] pos The position/mode to set the swing to. void IRMitsubishiHeavy152Ac::setSwingVertical(const uint8_t pos) { setBits(&remote_state[11], kMitsubishiHeavy152SwingVOffset, kMitsubishiHeavy152SwingVSize, std::min(pos, kMitsubishiHeavy152SwingVOff)); } +/// Get the Vertical Swing mode of the A/C. +/// @return The native position/mode setting. uint8_t IRMitsubishiHeavy152Ac::getSwingVertical(void) { return GETBITS8(remote_state[11], kMitsubishiHeavy152SwingVOffset, kMitsubishiHeavy152SwingVSize); } +/// Set the Horizontal Swing mode of the A/C. +/// @param[in] pos The position/mode to set the swing to. void IRMitsubishiHeavy152Ac::setSwingHorizontal(const uint8_t pos) { setBits(&remote_state[13], kLowNibble, kNibbleSize, std::min(pos, kMitsubishiHeavy152SwingHOff)); } +/// Get the Horizontal Swing mode of the A/C. +/// @return The native position/mode setting. uint8_t IRMitsubishiHeavy152Ac::getSwingHorizontal(void) { return GETBITS8(remote_state[13], kLowNibble, kNibbleSize); } +/// Set the Night (Sleep) mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRMitsubishiHeavy152Ac::setNight(const bool on) { setBit(&remote_state[15], kMitsubishiHeavyNightOffset, on); } +/// Get the Night (Sleep) mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRMitsubishiHeavy152Ac::getNight(void) { return GETBIT8(remote_state[15], kMitsubishiHeavyNightOffset); } +/// Set the 3D mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRMitsubishiHeavy152Ac::set3D(const bool on) { if (on) remote_state[11] |= kMitsubishiHeavy3DMask; @@ -210,63 +240,88 @@ void IRMitsubishiHeavy152Ac::set3D(const bool on) { remote_state[11] &= ~kMitsubishiHeavy3DMask; } +/// Get the 3D mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRMitsubishiHeavy152Ac::get3D(void) { return (remote_state[11] & kMitsubishiHeavy3DMask) == kMitsubishiHeavy3DMask; } +/// Set the Silent (Quiet) mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRMitsubishiHeavy152Ac::setSilent(const bool on) { setBit(&remote_state[15], kMitsubishiHeavySilentOffset, on); } +/// Get the Silent (Quiet) mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRMitsubishiHeavy152Ac::getSilent(void) { return GETBIT8(remote_state[15], kMitsubishiHeavySilentOffset); } +/// Set the Filter mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRMitsubishiHeavy152Ac::setFilter(const bool on) { setBit(&remote_state[5], kMitsubishiHeavyFilterOffset, on); } +/// Get the Filter mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRMitsubishiHeavy152Ac::getFilter(void) { return GETBIT8(remote_state[5], kMitsubishiHeavyFilterOffset); } +/// Set the Clean mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRMitsubishiHeavy152Ac::setClean(const bool on) { this->setFilter(on); setBit(&remote_state[5], kMitsubishiHeavyCleanOffset, on); } +/// Get the Clean mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRMitsubishiHeavy152Ac::getClean(void) { return GETBIT8(remote_state[5], kMitsubishiHeavyCleanOffset) && getFilter(); } +/// Set the Turbo mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRMitsubishiHeavy152Ac::setTurbo(const bool on) { if (on) this->setFan(kMitsubishiHeavy152FanTurbo); else if (this->getTurbo()) this->setFan(kMitsubishiHeavy152FanAuto); } +/// Get the Turbo mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRMitsubishiHeavy152Ac::getTurbo(void) { return this->getFan() == kMitsubishiHeavy152FanTurbo; } +/// Set the Economical mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRMitsubishiHeavy152Ac::setEcono(const bool on) { if (on) this->setFan(kMitsubishiHeavy152FanEcono); else if (this->getEcono()) this->setFan(kMitsubishiHeavy152FanAuto); } +/// Get the Economical mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRMitsubishiHeavy152Ac::getEcono(void) { return this->getFan() == kMitsubishiHeavy152FanEcono; } -// Verify the given state has a ZM-S signature. +/// Verify the given state has a ZM-S signature. +/// @param[in] state A ptr to a state to be checked. +/// @return true, the check passed. Otherwise, false. bool IRMitsubishiHeavy152Ac::checkZmsSig(const uint8_t *state) { for (uint8_t i = 0; i < kMitsubishiHeavySigLength; i++) if (state[i] != kMitsubishiHeavyZmsSig[i]) return false; return true; } -// Protocol technically has no checksum, but does has inverted byte pairs. +/// Calculate the checksum for the current internal state of the remote. +/// Note: Technically it has no checksum, but does has inverted byte pairs. void IRMitsubishiHeavy152Ac::checksum(void) { for (uint8_t i = kMitsubishiHeavySigLength - 2; i < kMitsubishiHeavy152StateLength; @@ -275,7 +330,11 @@ void IRMitsubishiHeavy152Ac::checksum(void) { } } -// Protocol technically has no checksum, but does has inverted byte pairs. +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length/size of the state array. +/// @return true, if the state has a valid checksum. Otherwise, false. +/// Note: Technically it has no checksum, but does has inverted byte pairs. bool IRMitsubishiHeavy152Ac::validChecksum(const uint8_t *state, const uint16_t length) { // Assume anything too short is fine. @@ -290,7 +349,9 @@ bool IRMitsubishiHeavy152Ac::validChecksum(const uint8_t *state, return true; } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRMitsubishiHeavy152Ac::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kMitsubishiHeavyCool; @@ -301,7 +362,9 @@ uint8_t IRMitsubishiHeavy152Ac::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRMitsubishiHeavy152Ac::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { // Assumes Econo is slower than Low. @@ -314,7 +377,9 @@ uint8_t IRMitsubishiHeavy152Ac::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a standard A/C vertical swing into its native setting. +/// Convert a stdAc::swingv_t enum into it's native setting. +/// @param[in] position The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRMitsubishiHeavy152Ac::convertSwingV(const stdAc::swingv_t position) { switch (position) { case stdAc::swingv_t::kAuto: return kMitsubishiHeavy152SwingVAuto; @@ -327,7 +392,9 @@ uint8_t IRMitsubishiHeavy152Ac::convertSwingV(const stdAc::swingv_t position) { } } -// Convert a standard A/C horizontal swing into its native setting. +/// Convert a stdAc::swingh_t enum into it's native setting. +/// @param[in] position The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRMitsubishiHeavy152Ac::convertSwingH(const stdAc::swingh_t position) { switch (position) { case stdAc::swingh_t::kAuto: return kMitsubishiHeavy152SwingHAuto; @@ -340,7 +407,9 @@ uint8_t IRMitsubishiHeavy152Ac::convertSwingH(const stdAc::swingh_t position) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRMitsubishiHeavy152Ac::toCommonMode(const uint8_t mode) { switch (mode) { case kMitsubishiHeavyCool: return stdAc::opmode_t::kCool; @@ -351,7 +420,9 @@ stdAc::opmode_t IRMitsubishiHeavy152Ac::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] spd The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRMitsubishiHeavy152Ac::toCommonFanSpeed(const uint8_t spd) { switch (spd) { case kMitsubishiHeavy152FanMax: return stdAc::fanspeed_t::kMax; @@ -363,7 +434,9 @@ stdAc::fanspeed_t IRMitsubishiHeavy152Ac::toCommonFanSpeed(const uint8_t spd) { } } -// Convert a native vertical swing to it's common equivalent. +/// Convert a native horizontal swing postion to it's common equivalent. +/// @param[in] pos A native position to convert. +/// @return The common horizontal swing position. stdAc::swingh_t IRMitsubishiHeavy152Ac::toCommonSwingH(const uint8_t pos) { switch (pos) { case kMitsubishiHeavy152SwingHLeftMax: return stdAc::swingh_t::kLeftMax; @@ -376,7 +449,9 @@ stdAc::swingh_t IRMitsubishiHeavy152Ac::toCommonSwingH(const uint8_t pos) { } } -// Convert a native vertical swing to it's common equivalent. +/// Convert a native vertical swing postion to it's common equivalent. +/// @param[in] pos A native position to convert. +/// @return The common vertical swing position. stdAc::swingv_t IRMitsubishiHeavy152Ac::toCommonSwingV(const uint8_t pos) { switch (pos) { case kMitsubishiHeavy152SwingVHighest: return stdAc::swingv_t::kHighest; @@ -389,7 +464,8 @@ stdAc::swingv_t IRMitsubishiHeavy152Ac::toCommonSwingV(const uint8_t pos) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRMitsubishiHeavy152Ac::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::MITSUBISHI_HEAVY_152; @@ -414,7 +490,8 @@ stdAc::state_t IRMitsubishiHeavy152Ac::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the internal state into a human readable string. +/// @return A string containing the settings in human-readable form. String IRMitsubishiHeavy152Ac::toString(void) { String result = ""; result.reserve(180); // Reserve some heap for the string to reduce fragging. @@ -529,47 +606,68 @@ String IRMitsubishiHeavy152Ac::toString(void) { // Class for decoding and constructing MitsubishiHeavy88 AC messages. + +/// 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? IRMitsubishiHeavy88Ac::IRMitsubishiHeavy88Ac(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { stateReset(); } +/// Set up hardware to be able to send a message. void IRMitsubishiHeavy88Ac::begin(void) { _irsend.begin(); } #if SEND_MITSUBISHIHEAVY +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRMitsubishiHeavy88Ac::send(const uint16_t repeat) { _irsend.sendMitsubishiHeavy88(this->getRaw(), kMitsubishiHeavy88StateLength, repeat); } #endif // SEND_MITSUBISHIHEAVY +/// Reset the state of the remote to a known good state/sequence. void IRMitsubishiHeavy88Ac::stateReset(void) { memcpy(remote_state, kMitsubishiHeavyZjsSig, kMitsubishiHeavySigLength); for (uint8_t i = kMitsubishiHeavySigLength; i < kMitsubishiHeavy88StateLength; i++) remote_state[i] = 0; } +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t *IRMitsubishiHeavy88Ac::getRaw(void) { checksum(); return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] data A valid code for this protocol. void IRMitsubishiHeavy88Ac::setRaw(const uint8_t *data) { memcpy(remote_state, data, kMitsubishiHeavy88StateLength); } +/// Set the requested power state of the A/C to on. void IRMitsubishiHeavy88Ac::on(void) { setPower(true); } +/// Set the requested power state of the A/C to off. void IRMitsubishiHeavy88Ac::off(void) { setPower(false); } +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRMitsubishiHeavy88Ac::setPower(const bool on) { setBit(&remote_state[9], kMitsubishiHeavyPowerOffset, on); } +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRMitsubishiHeavy88Ac::getPower(void) { return GETBIT8(remote_state[9], kMitsubishiHeavyPowerOffset); } +/// Set the temperature. +/// @param[in] temp The temperature in degrees celsius. void IRMitsubishiHeavy88Ac::setTemp(const uint8_t temp) { uint8_t newtemp = temp; newtemp = std::min(newtemp, kMitsubishiHeavyMaxTemp); @@ -578,12 +676,15 @@ void IRMitsubishiHeavy88Ac::setTemp(const uint8_t temp) { newtemp - kMitsubishiHeavyMinTemp); } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRMitsubishiHeavy88Ac::getTemp(void) { return GETBITS8(remote_state[9], kHighNibble, kNibbleSize) + kMitsubishiHeavyMinTemp; } -// Set the speed of the fan +/// Set the speed of the fan. +/// @param[in] speed The desired setting. void IRMitsubishiHeavy88Ac::setFan(const uint8_t speed) { uint8_t newspeed = speed; switch (speed) { @@ -598,11 +699,15 @@ void IRMitsubishiHeavy88Ac::setFan(const uint8_t speed) { kMitsubishiHeavy88FanSize, newspeed); } +/// Get the current fan speed setting. +/// @return The current fan speed/mode. uint8_t IRMitsubishiHeavy88Ac::getFan(void) { return GETBITS8(remote_state[7], kMitsubishiHeavy88FanOffset, kMitsubishiHeavy88FanSize); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRMitsubishiHeavy88Ac::setMode(const uint8_t mode) { uint8_t newmode = mode; switch (mode) { @@ -617,10 +722,14 @@ void IRMitsubishiHeavy88Ac::setMode(const uint8_t mode) { setBits(&remote_state[9], kMitsubishiHeavyModeOffset, kModeBitsSize, newmode); } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRMitsubishiHeavy88Ac::getMode(void) { return GETBITS8(remote_state[9], kMitsubishiHeavyModeOffset, kModeBitsSize); } +/// Set the Vertical Swing mode of the A/C. +/// @param[in] pos The position/mode to set the swing to. void IRMitsubishiHeavy88Ac::setSwingVertical(const uint8_t pos) { uint8_t newpos; switch (pos) { @@ -639,6 +748,8 @@ void IRMitsubishiHeavy88Ac::setSwingVertical(const uint8_t pos) { newpos >> kMitsubishiHeavy88SwingVByte5Size); } +/// Get the Vertical Swing mode of the A/C. +/// @return The native position/mode setting. uint8_t IRMitsubishiHeavy88Ac::getSwingVertical(void) { return GETBITS8(remote_state[5], kMitsubishiHeavy88SwingVByte5Offset, kMitsubishiHeavy88SwingVByte5Size) | @@ -647,6 +758,8 @@ uint8_t IRMitsubishiHeavy88Ac::getSwingVertical(void) { kMitsubishiHeavy88SwingVByte5Size); } +/// Set the Horizontal Swing mode of the A/C. +/// @param[in] pos The position/mode to set the swing to. void IRMitsubishiHeavy88Ac::setSwingHorizontal(const uint8_t pos) { uint8_t newpos; switch (pos) { @@ -668,6 +781,8 @@ void IRMitsubishiHeavy88Ac::setSwingHorizontal(const uint8_t pos) { newpos >> kMitsubishiHeavy88SwingHSize); } +/// Get the Horizontal Swing mode of the A/C. +/// @return The native position/mode setting. uint8_t IRMitsubishiHeavy88Ac::getSwingHorizontal(void) { return GETBITS8(remote_state[5], kMitsubishiHeavy88SwingHOffset1, kMitsubishiHeavy88SwingHSize) | @@ -676,26 +791,36 @@ uint8_t IRMitsubishiHeavy88Ac::getSwingHorizontal(void) { kMitsubishiHeavy88SwingHSize); } +/// Set the Turbo mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRMitsubishiHeavy88Ac::setTurbo(const bool on) { if (on) this->setFan(kMitsubishiHeavy88FanTurbo); else if (this->getTurbo()) this->setFan(kMitsubishiHeavy88FanAuto); } +/// Get the Turbo mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRMitsubishiHeavy88Ac::getTurbo(void) { return this->getFan() == kMitsubishiHeavy88FanTurbo; } +/// Set the Economical mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRMitsubishiHeavy88Ac::setEcono(const bool on) { if (on) this->setFan(kMitsubishiHeavy88FanEcono); else if (this->getEcono()) this->setFan(kMitsubishiHeavy88FanAuto); } +/// Get the Economical mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRMitsubishiHeavy88Ac::getEcono(void) { return this->getFan() == kMitsubishiHeavy88FanEcono; } +/// Set the 3D mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRMitsubishiHeavy88Ac::set3D(const bool on) { if (on) this->setSwingHorizontal(kMitsubishiHeavy88SwingH3D); @@ -703,26 +828,35 @@ void IRMitsubishiHeavy88Ac::set3D(const bool on) { this->setSwingHorizontal(kMitsubishiHeavy88SwingHOff); } +/// Get the 3D mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRMitsubishiHeavy88Ac::get3D(void) { return this->getSwingHorizontal() == kMitsubishiHeavy88SwingH3D; } +/// Set the Clean mode of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRMitsubishiHeavy88Ac::setClean(const bool on) { setBit(&remote_state[5], kMitsubishiHeavy88CleanOffset, on); } +/// Get the Clean mode of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRMitsubishiHeavy88Ac::getClean(void) { return GETBIT8(remote_state[5], kMitsubishiHeavy88CleanOffset); } -// Verify the given state has a ZJ-S signature. +/// Verify the given state has a ZJ-S signature. +/// @param[in] state A ptr to a state to be checked. +/// @return true, the check passed. Otherwise, false. bool IRMitsubishiHeavy88Ac::checkZjsSig(const uint8_t *state) { for (uint8_t i = 0; i < kMitsubishiHeavySigLength; i++) if (state[i] != kMitsubishiHeavyZjsSig[i]) return false; return true; } -// Protocol technically has no checksum, but does has inverted byte pairs. +/// Calculate the checksum for the current internal state of the remote. +/// Note: Technically it has no checksum, but does has inverted byte pairs. void IRMitsubishiHeavy88Ac::checksum(void) { for (uint8_t i = kMitsubishiHeavySigLength - 2; i < kMitsubishiHeavy88StateLength; @@ -731,18 +865,26 @@ void IRMitsubishiHeavy88Ac::checksum(void) { } } -// Protocol technically has no checksum, but does has inverted byte pairs. +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length/size of the state array. +/// @return true, if the state has a valid checksum. Otherwise, false. +/// Note: Technically it has no checksum, but does has inverted byte pairs. bool IRMitsubishiHeavy88Ac::validChecksum(const uint8_t *state, const uint16_t length) { return IRMitsubishiHeavy152Ac::validChecksum(state, length); } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRMitsubishiHeavy88Ac::convertMode(const stdAc::opmode_t mode) { return IRMitsubishiHeavy152Ac::convertMode(mode); } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRMitsubishiHeavy88Ac::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { // Assumes Econo is slower than Low. @@ -755,7 +897,9 @@ uint8_t IRMitsubishiHeavy88Ac::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a standard A/C vertical swing into its native setting. +/// Convert a stdAc::swingv_t enum into it's native setting. +/// @param[in] position The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRMitsubishiHeavy88Ac::convertSwingV(const stdAc::swingv_t position) { switch (position) { case stdAc::swingv_t::kAuto: return kMitsubishiHeavy88SwingVAuto; @@ -768,7 +912,9 @@ uint8_t IRMitsubishiHeavy88Ac::convertSwingV(const stdAc::swingv_t position) { } } -// Convert a standard A/C horizontal swing into its native setting. +/// Convert a stdAc::swingh_t enum into it's native setting. +/// @param[in] position The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRMitsubishiHeavy88Ac::convertSwingH(const stdAc::swingh_t position) { switch (position) { case stdAc::swingh_t::kAuto: return kMitsubishiHeavy88SwingHAuto; @@ -781,7 +927,9 @@ uint8_t IRMitsubishiHeavy88Ac::convertSwingH(const stdAc::swingh_t position) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRMitsubishiHeavy88Ac::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kMitsubishiHeavy88FanTurbo: return stdAc::fanspeed_t::kMax; @@ -793,7 +941,9 @@ stdAc::fanspeed_t IRMitsubishiHeavy88Ac::toCommonFanSpeed(const uint8_t speed) { } } -// Convert a native vertical swing to it's common equivalent. +/// Convert a native horizontal swing postion to it's common equivalent. +/// @param[in] pos A native position to convert. +/// @return The common horizontal swing position. stdAc::swingh_t IRMitsubishiHeavy88Ac::toCommonSwingH(const uint8_t pos) { switch (pos) { case kMitsubishiHeavy88SwingHLeftMax: return stdAc::swingh_t::kLeftMax; @@ -806,7 +956,9 @@ stdAc::swingh_t IRMitsubishiHeavy88Ac::toCommonSwingH(const uint8_t pos) { } } -// Convert a native vertical swing to it's common equivalent. +/// Convert a native vertical swing postion to it's common equivalent. +/// @param[in] pos A native position to convert. +/// @return The common vertical swing position. stdAc::swingv_t IRMitsubishiHeavy88Ac::toCommonSwingV(const uint8_t pos) { switch (pos) { case kMitsubishiHeavy88SwingVHighest: return stdAc::swingv_t::kHighest; @@ -819,7 +971,8 @@ stdAc::swingv_t IRMitsubishiHeavy88Ac::toCommonSwingV(const uint8_t pos) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRMitsubishiHeavy88Ac::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::MITSUBISHI_HEAVY_88; @@ -844,7 +997,8 @@ stdAc::state_t IRMitsubishiHeavy88Ac::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the internal state into a human readable string. +/// @return A string containing the settings in human-readable form. String IRMitsubishiHeavy88Ac::toString(void) { String result = ""; result.reserve(140); // Reserve some heap for the string to reduce fragging. @@ -955,19 +1109,15 @@ String IRMitsubishiHeavy88Ac::toString(void) { } #if DECODE_MITSUBISHIHEAVY -// Decode the supplied MitsubishiHeavy message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. -// Typically kMitsubishiHeavy88Bits or kMitsubishiHeavy152Bits (def). -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: BETA / Appears to be working. Needs testing against a real device. +/// Decode the supplied Mitsubishi Heavy Industries A/C message. +/// Status: BETA / Appears to be working. Needs testing 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. +/// @param[in] nbits The number of data bits to expect. +/// Typically kMitsubishiHeavy88Bits or kMitsubishiHeavy152Bits (def). +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. bool IRrecv::decodeMitsubishiHeavy(decode_results* results, uint16_t offset, const uint16_t nbits, const bool strict) { if (strict) { diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_MitsubishiHeavy.h b/lib/IRremoteESP8266-2.7.8/src/ir_MitsubishiHeavy.h similarity index 81% rename from lib/IRremoteESP8266-2.7.5/src/ir_MitsubishiHeavy.h rename to lib/IRremoteESP8266-2.7.8/src/ir_MitsubishiHeavy.h index 2c2097d03..2d9d4ff73 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_MitsubishiHeavy.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_MitsubishiHeavy.h @@ -1,11 +1,21 @@ // Copyright 2019 David Conran +/// @file +/// @brief Support for Mitsubishi Heavy Industry protocols. +/// Code to emulate Mitsubishi Heavy Industries A/C IR remote control units. +/// @note This code was *heavily* influenced by ToniA's great work & code, +/// but it has been written from scratch. +/// Nothing was copied other than constants and message analysis. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/660 +/// @see https://github.com/ToniA/Raw-IR-decoder-for-Arduino/blob/master/MitsubishiHeavy.cpp +/// @see https://github.com/ToniA/arduino-heatpumpir/blob/master/MitsubishiHeavyHeatpumpIR.cpp + // Supports: -// Brand: Mitsubishi Heavy Industries, Model: RLA502A700B remote -// Brand: Mitsubishi Heavy Industries, Model: SRKxxZM-S A/C -// Brand: Mitsubishi Heavy Industries, Model: SRKxxZMXA-S A/C -// Brand: Mitsubishi Heavy Industries, Model: RKX502A001C remote -// Brand: Mitsubishi Heavy Industries, Model: SRKxxZJ-S A/C +// Brand: Mitsubishi Heavy Industries, Model: RLA502A700B remote (152 bit) +// Brand: Mitsubishi Heavy Industries, Model: SRKxxZM-S A/C (152 bit) +// Brand: Mitsubishi Heavy Industries, Model: SRKxxZMXA-S A/C (152 bit) +// Brand: Mitsubishi Heavy Industries, Model: RKX502A001C remote (88 bit) +// Brand: Mitsubishi Heavy Industries, Model: SRKxxZJ-S A/C (88 bit) #ifndef IR_MITSUBISHIHEAVY_H_ #define IR_MITSUBISHIHEAVY_H_ @@ -19,15 +29,9 @@ #include "IRsend_test.h" #endif -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/660 -// https://github.com/ToniA/Raw-IR-decoder-for-Arduino/blob/master/MitsubishiHeavy.cpp -// https://github.com/ToniA/arduino-heatpumpir/blob/master/MitsubishiHeavyHeatpumpIR.cpp - // Constants. const uint8_t kMitsubishiHeavySigLength = 5; - // ZMS (152 bit) const uint8_t kMitsubishiHeavyZmsSig[kMitsubishiHeavySigLength] = { 0xAD, 0x51, 0x3C, 0xE5, 0x1A}; @@ -124,16 +128,21 @@ const uint8_t kMitsubishiHeavy88SwingVLowest = 0b111; // 7 // Classes + +/// Class for handling detailed Mitsubishi Heavy 152-bit A/C messages. class IRMitsubishiHeavy152Ac { public: explicit IRMitsubishiHeavy152Ac(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - void stateReset(void); #if SEND_MITSUBISHIHEAVY void send(const uint16_t repeat = kMitsubishiHeavy152MinRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + /// 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_MITSUBISHIHEAVY void begin(void); void on(void); @@ -197,24 +206,30 @@ class IRMitsubishiHeavy152Ac { #ifndef UNIT_TEST private: - IRsend _irsend; + IRsend _irsend; ///< Instance of the IR send class #else // UNIT_TEST - IRsendTest _irsend; + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond #endif // UNIT_TEST - // The state of the IR remote in IR code form. - uint8_t remote_state[kMitsubishiHeavy152StateLength]; + uint8_t remote_state[kMitsubishiHeavy152StateLength]; ///< State in code form void checksum(void); }; +/// Class for handling detailed Mitsubishi Heavy 88-bit A/C messages. class IRMitsubishiHeavy88Ac { public: explicit IRMitsubishiHeavy88Ac(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - void stateReset(void); #if SEND_MITSUBISHIHEAVY void send(const uint16_t repeat = kMitsubishiHeavy88MinRepeat); + /// 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_MITSUBISHIHEAVY void begin(void); void on(void); @@ -268,12 +283,13 @@ class IRMitsubishiHeavy88Ac { #ifndef UNIT_TEST private: - IRsend _irsend; + IRsend _irsend; ///< Instance of the IR send class #else // UNIT_TEST - IRsendTest _irsend; + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond #endif // UNIT_TEST - // The state of the IR remote in IR code form. - uint8_t remote_state[kMitsubishiHeavy152StateLength]; + uint8_t remote_state[kMitsubishiHeavy88StateLength]; ///< State in code form void checksum(void); }; #endif // IR_MITSUBISHIHEAVY_H_ diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Multibrackets.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Multibrackets.cpp new file mode 100644 index 000000000..2367b49bc --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Multibrackets.cpp @@ -0,0 +1,115 @@ +// Copyright 2020 David Conran + +/// @file +/// @brief Support for Multibrackets protocols. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1103 +/// @see http://info.multibrackets.com/data/common/manuals/4500_code.pdf + +// Supports: +// Brand: Multibrackets, Model: Motorized Swing mount large - 4500 + +#include "IRrecv.h" +#include "IRsend.h" + +const uint16_t kMultibracketsTick = 5000; // uSeconds +const uint16_t kMultibracketsHdrMark = 3 * kMultibracketsTick; // uSeconds +const uint16_t kMultibracketsFooterSpace = 6 * kMultibracketsTick; // uSeconds +const uint8_t kMultibracketsTolerance = 5; // Percent +const uint16_t kMultibracketsFreq = 38000; // Hertz + +#if SEND_MULTIBRACKETS +/// Send a Multibrackets formatted message. +/// Status: BETA / Appears to be working. +/// @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::sendMultibrackets(uint64_t data, uint16_t nbits, uint16_t repeat) { + enableIROut(kMultibracketsFreq); + for (uint16_t r = 0; r <= repeat; r++) { + uint16_t bits = nbits; + // Header + mark(kMultibracketsHdrMark); + // Data + // Send 0's until we get down to a bit size we can actually manage. + while (bits > sizeof(data) * 8) { + space(kMultibracketsTick); + bits--; + } + // Send the supplied data. + for (uint64_t mask = 1ULL << (bits - 1); mask; mask >>= 1) + if (data & mask) // Send a 1 + mark(kMultibracketsTick); + else // Send a 0 + space(kMultibracketsTick); + // Footer + space(kMultibracketsFooterSpace); + } +} +#endif // SEND_MULTIBRACKETS + +#if DECODE_MULTIBRACKETS +/// Decode the Multibrackets message. +/// Status: BETA / Appears to be working. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +bool IRrecv::decodeMultibrackets(decode_results *results, uint16_t offset, + const uint16_t nbits, const bool strict) { + // Compliance + if (strict && nbits != kMultibracketsBits) + return false; // Doesn't match our protocol defn. + + // Check there is enough unprocessed buffer left. + if (results->rawlen < offset) return false; + + // Header + int32_t remaining = *(results->rawbuf + offset); + if (!matchAtLeast(remaining, kMultibracketsHdrMark, kMultibracketsTolerance)) + return false; + remaining -= (kMultibracketsHdrMark / kRawTick); // Remove the header. + + // We are done with the header. Onto the data. + bool bit = true; + uint16_t bitsSoFar = 0; + uint64_t data = 0; + // Keep going till we run out of message or expected bits. + while (offset <= results->rawlen && bitsSoFar < nbits) { + // Have we finished processing this rawbuf value yet? + if (remaining <= 0) { // No more possible "bits" left in this value. + // Invert the bit for next time, and move along the rawbuf. + bit = !bit; + offset++; + // Load the next data point if there is one. + if (offset <= results->rawlen) remaining = *(results->rawbuf + offset); + } else { // Look for more bits in this entry. + if (matchAtLeast(remaining, kMultibracketsTick, + kMultibracketsTolerance)) { // There is! + data <<= 1; + data += bit; + bitsSoFar++; + } + remaining -= (kMultibracketsTick / kRawTick); // Remove the "bit". + } + } + + // Compliance + if (bitsSoFar != nbits) return false; + + // Footer + if (results->rawlen <= offset && !matchAtLeast(*(results->rawbuf + offset), + kMultibracketsFooterSpace, + kMultibracketsTolerance)) + return false; + + // Success + results->decode_type = decode_type_t::MULTIBRACKETS; + results->value = data; + results->bits = nbits; + results->address = 0; + results->command = 0; + return true; +} +#endif // DECODE_MULTIBRACKETS diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_NEC.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_NEC.cpp similarity index 65% rename from lib/IRremoteESP8266-2.7.5/src/ir_NEC.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_NEC.cpp index 9145f5c24..ac816f2ed 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_NEC.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_NEC.cpp @@ -1,7 +1,10 @@ // Copyright 2009 Ken Shirriff // Copyright 2017 David Conran -// NEC originally added from https://github.com/shirriff/Arduino-IRremote/ +/// @file +/// @brief Support for NEC (Renesas) protocols. +/// NEC originally added from https://github.com/shirriff/Arduino-IRremote/ +/// @see http://www.sbprojects.com/knowledge/ir/nec.php #define __STDC_LIMIT_MACROS #include "ir_NEC.h" @@ -11,18 +14,17 @@ #include "IRsend.h" #include "IRutils.h" -#if (SEND_NEC || SEND_SHERWOOD || SEND_AIWA_RC_T501 || SEND_SANYO) -// Send a raw NEC(Renesas) formatted message. -// -// Args: -// data: The message to be sent. -// nbits: The number of bits of the message to be sent. Typically kNECBits. -// repeat: The number of times the command is to be repeated. -// -// Status: STABLE / Known working. -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/nec.php +// This protocol is used by a lot of other protocols, hence the long list. +#if (SEND_NEC || SEND_SHERWOOD || SEND_AIWA_RC_T501 || SEND_SANYO || \ + SEND_MIDEA24) + +/// Send a raw NEC(Renesas) formatted message. +/// Status: STABLE / Known working. +/// @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. +/// @note This protocol appears to have no header. +/// @see http://www.sbprojects.com/knowledge/ir/nec.php void IRsend::sendNEC(uint64_t data, uint16_t nbits, uint16_t repeat) { sendGeneric(kNecHdrMark, kNecHdrSpace, kNecBitMark, kNecOneSpace, kNecBitMark, kNecZeroSpace, kNecBitMark, kNecMinGap, kNecMinCommandLength, @@ -37,17 +39,12 @@ void IRsend::sendNEC(uint64_t data, uint16_t nbits, uint16_t repeat) { 33); } -// Calculate the raw NEC data based on address and command. -// Args: -// address: An address value. -// command: An 8-bit command value. -// Returns: -// A raw 32-bit NEC message. -// -// Status: STABLE / Expected to work. -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/nec.php +/// Calculate the raw NEC data based on address and command. +/// Status: STABLE / Expected to work. +/// @param[in] address An address value. +/// @param[in] command An 8-bit command value. +/// @return A raw 32-bit NEC message suitable for use with `sendNEC()`. +/// @see http://www.sbprojects.com/knowledge/ir/nec.php uint32_t IRsend::encodeNEC(uint16_t address, uint16_t command) { command &= 0xFF; // We only want the least significant byte of command. // sendNEC() sends MSB first, but protocol says this is LSB first. @@ -61,32 +58,26 @@ uint32_t IRsend::encodeNEC(uint16_t address, uint16_t command) { return (address << 24) + ((address ^ 0xFF) << 16) + command; // Normal. } } -#endif // (SEND_NEC || SEND_SHERWOOD || SEND_AIWA_RC_T501 || SEND_SANYO ) +#endif // (SEND_NEC || SEND_SHERWOOD || SEND_AIWA_RC_T501 || SEND_SANYO || + // SEND_MIDEA24) +// This protocol is used by a lot of other protocols, hence the long list. #if (DECODE_NEC || DECODE_SHERWOOD || DECODE_AIWA_RC_T501 || DECODE_SANYO) -// Decode the supplied NEC message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kNECBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Known good. -// -// Notes: -// NEC protocol has three varients/forms. -// Normal: an 8 bit address & an 8 bit command in 32 bit data form. -// i.e. address + inverted(address) + command + inverted(command) -// Extended: a 16 bit address & an 8 bit command in 32 bit data form. -// i.e. address + command + inverted(command) -// Repeat: a 0-bit code. i.e. No data bits. Just the header + footer. -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/nec.php +/// Decode the supplied NEC (Renesas) message. +/// Status: STABLE / Known good. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @note NEC protocol has three variants/forms. +/// Normal: an 8 bit address & an 8 bit command in 32 bit data form. +/// i.e. address + inverted(address) + command + inverted(command) +/// Extended: a 16 bit address & an 8 bit command in 32 bit data form. +/// i.e. address + command + inverted(command) +/// Repeat: a 0-bit code. i.e. No data bits. Just the header + footer. +/// @see http://www.sbprojects.com/knowledge/ir/nec.php bool IRrecv::decodeNEC(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen < kNecRptLength + offset - 1) @@ -145,4 +136,5 @@ bool IRrecv::decodeNEC(decode_results *results, uint16_t offset, results->address = reverseBits((data >> 16) & UINT16_MAX, 16); return true; } -#endif // DECODE_NEC || DECODE_SHERWOOD || DECODE_AIWA_RC_T501 || DECODE_SANYO +#endif // (DECODE_NEC || DECODE_SHERWOOD || DECODE_AIWA_RC_T501 || + // DECODE_SANYO) diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_NEC.h b/lib/IRremoteESP8266-2.7.8/src/ir_NEC.h similarity index 88% rename from lib/IRremoteESP8266-2.7.5/src/ir_NEC.h rename to lib/IRremoteESP8266-2.7.8/src/ir_NEC.h index cf6191100..48b1c09a2 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_NEC.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_NEC.h @@ -1,7 +1,19 @@ // Copyright 2009 Ken Shirriff // Copyright 2017, 2018 David Conran -// NEC originally added from https://github.com/shirriff/Arduino-IRremote/ +/// @file +/// @brief Support for NEC (Renesas) protocols. +/// NEC originally added from https://github.com/shirriff/Arduino-IRremote/ +/// @see http://www.sbprojects.com/knowledge/ir/nec.php + +// Supports: +// Brand: Yamaha, Model: RAV561 remote +// Brand: Yamaha, Model: RXV585B A/V Receiver +// Brand: Aloka, Model: SleepyLights LED Lamp +// Brand: Toshiba, Model: 42TL838 LCD TV +// Brand: Duux, Model: Blizzard Smart 10K / DXMA04 A/C +// Brand: Duux, Model: YJ-A081 TR Remote +// Brand: Silan Microelectronics, Model: SC6121-001 IC #ifndef IR_NEC_H_ #define IR_NEC_H_ @@ -9,15 +21,7 @@ #include #include "IRremoteESP8266.h" -// Supports: -// Brand: Yamaha, Model: RAV561 remote -// Brand: Yamaha, Model: RXV585B A/V Receiver -// Brand: Aloka, Model: SleepyLights LED Lamp -// Brand: Toshiba, Model: 42TL838 LCD TV - // Constants -// Ref: -// http://www.sbprojects.com/knowledge/ir/nec.php const uint16_t kNecTick = 560; const uint16_t kNecHdrMarkTicks = 16; const uint16_t kNecHdrMark = kNecHdrMarkTicks * kNecTick; diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Neoclima.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Neoclima.cpp similarity index 68% rename from lib/IRremoteESP8266-2.7.5/src/ir_Neoclima.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Neoclima.cpp index 8c93ef26f..c81a69e02 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Neoclima.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Neoclima.cpp @@ -1,17 +1,11 @@ // Copyright 2019 David Conran -// Neoclima A/C support - -// Analysis by crankyoldgit & AndreyShpilevoy -// Code by crankyoldgit -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/764 -// https://drive.google.com/file/d/1kjYk4zS9NQcMQhFkak-L4mp4UuaAIesW/view - - -// Supports: -// Brand: Neoclima, Model: NS-09AHTI A/C -// Brand: Neoclima, Model: ZH/TY-01 remote +/// @file +/// @brief Support for Neoclima protocols. +/// Analysis by crankyoldgit & AndreyShpilevoy +/// Code by crankyoldgit +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/764 +/// @see https://drive.google.com/file/d/1kjYk4zS9NQcMQhFkak-L4mp4UuaAIesW/view #include "ir_Neoclima.h" #include @@ -22,7 +16,6 @@ #include "IRutils.h" // Constants - const uint16_t kNeoclimaHdrMark = 6112; const uint16_t kNeoclimaHdrSpace = 7391; const uint16_t kNeoclimaBitMark = 537; @@ -40,17 +33,11 @@ using irutils::setBit; using irutils::setBits; #if SEND_NEOCLIMA -// Send a Neoclima message. -// -// Args: -// data: message to be sent. -// nbytes: Nr. of bytes of the message to be sent. -// repeat: Nr. of additional times the message is to be sent. -// -// Status: Beta / Known to be working. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/764 +/// Send a Neoclima message. +/// Status: STABLE / Known to be working. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendNeoclima(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { // Set IR carrier frequency @@ -70,54 +57,77 @@ void IRsend::sendNeoclima(const unsigned char data[], const uint16_t nbytes, } #endif // SEND_NEOCLIMA +/// 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? IRNeoclimaAc::IRNeoclimaAc(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { this->stateReset(); } +/// Reset the state of the remote to a known good state/sequence. void IRNeoclimaAc::stateReset(void) { static const uint8_t kReset[kNeoclimaStateLength] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6A, 0x00, 0x2A, 0xA5}; setRaw(kReset); } +/// Set up hardware to be able to send a message. void IRNeoclimaAc::begin(void) { _irsend.begin(); } +/// Calculate the checksum for a given state. +/// @param[in] state The array to calc the checksum of. +/// @param[in] length The length/size of the array. +/// @return The calculated checksum value. uint8_t IRNeoclimaAc::calcChecksum(const uint8_t state[], const uint16_t length) { if (length == 0) return state[0]; return sumBytes(state, length - 1); } +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length/size of the array. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRNeoclimaAc::validChecksum(const uint8_t state[], const uint16_t length) { if (length < 2) return true; // No checksum to compare with. Assume okay. return (state[length - 1] == calcChecksum(state, length)); } -// Update the checksum for the internal state. +/// Calculate & update the checksum for the internal state. +/// @param[in] length The length/size of the internal state. void IRNeoclimaAc::checksum(uint16_t length) { if (length < 2) return; remote_state[length - 1] = calcChecksum(remote_state, length); } #if SEND_NEOCLIMA +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRNeoclimaAc::send(const uint16_t repeat) { _irsend.sendNeoclima(getRaw(), kNeoclimaStateLength, repeat); } #endif // SEND_NEOCLIMA +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t *IRNeoclimaAc::getRaw(void) { this->checksum(); return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. +/// @param[in] length The length/size of the new_code array. void IRNeoclimaAc::setRaw(const uint8_t new_code[], const uint16_t length) { memcpy(remote_state, new_code, std::min(length, kNeoclimaStateLength)); } - +/// Set the Button/Command pressed setting of the A/C. +/// @param[in] button The value of the button/command that was pressed. void IRNeoclimaAc::setButton(const uint8_t button) { switch (button) { case kNeoclimaButtonPower: @@ -144,23 +154,33 @@ void IRNeoclimaAc::setButton(const uint8_t button) { } } +/// Get the Button/Command setting of the A/C. +/// @return The value of the button/command that was pressed. uint8_t IRNeoclimaAc::getButton(void) { return GETBITS8(remote_state[5], kNeoclimaButtonOffset, kNeoclimaButtonSize); } +/// Set the requested power state of the A/C to on. void IRNeoclimaAc::on(void) { this->setPower(true); } +/// Set the requested power state of the A/C to off. void IRNeoclimaAc::off(void) { this->setPower(false); } +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRNeoclimaAc::setPower(const bool on) { this->setButton(kNeoclimaButtonPower); setBit(&remote_state[7], kNeoclimaPowerOffset, on); } +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRNeoclimaAc::getPower(void) { return GETBIT8(remote_state[7], kNeoclimaPowerOffset); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRNeoclimaAc::setMode(const uint8_t mode) { switch (mode) { case kNeoclimaDry: @@ -180,11 +200,15 @@ void IRNeoclimaAc::setMode(const uint8_t mode) { } } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRNeoclimaAc::getMode(void) { return GETBITS8(remote_state[9], kNeoclimaModeOffset, kModeBitsSize); } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRNeoclimaAc::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kNeoclimaCool; @@ -195,7 +219,9 @@ uint8_t IRNeoclimaAc::convertMode(const stdAc::opmode_t mode) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRNeoclimaAc::toCommonMode(const uint8_t mode) { switch (mode) { case kNeoclimaCool: return stdAc::opmode_t::kCool; @@ -206,7 +232,8 @@ stdAc::opmode_t IRNeoclimaAc::toCommonMode(const uint8_t mode) { } } -// Set the temp. in deg C +/// Set the temperature. +/// @param[in] temp The temperature in degrees celsius. void IRNeoclimaAc::setTemp(const uint8_t temp) { uint8_t oldtemp = this->getTemp(); uint8_t newtemp = std::max(kNeoclimaMinTemp, temp); @@ -219,13 +246,15 @@ void IRNeoclimaAc::setTemp(const uint8_t temp) { newtemp - kNeoclimaMinTemp); } -// Return the set temp. in deg C +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRNeoclimaAc::getTemp(void) { return GETBITS8(remote_state[9], kNeoclimaTempOffset, kNeoclimaTempSize) + kNeoclimaMinTemp; } -// Set the speed of the fan, 0-3, 0 is auto, 1-3 is the speed +/// Set the speed of the fan. +/// @param[in] speed The desired setting. 0-3, 0 is auto, 1-3 is the speed void IRNeoclimaAc::setFan(const uint8_t speed) { switch (speed) { case kNeoclimaFanAuto: @@ -246,11 +275,15 @@ void IRNeoclimaAc::setFan(const uint8_t speed) { } } +/// Get the current fan speed setting. +/// @return The current fan speed/mode. uint8_t IRNeoclimaAc::getFan(void) { return GETBITS8(remote_state[7], kNeoclimaFanOffest, kNeoclimaFanSize); } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRNeoclimaAc::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: @@ -262,7 +295,9 @@ uint8_t IRNeoclimaAc::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRNeoclimaAc::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kNeoclimaFanHigh: return stdAc::fanspeed_t::kMax; @@ -272,99 +307,138 @@ stdAc::fanspeed_t IRNeoclimaAc::toCommonFanSpeed(const uint8_t speed) { } } +/// Set the Sleep setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRNeoclimaAc::setSleep(const bool on) { this->setButton(kNeoclimaButtonSleep); setBit(&remote_state[7], kNeoclimaSleepOffset, on); } +/// Get the Sleep setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRNeoclimaAc::getSleep(void) { return GETBIT8(remote_state[7], kNeoclimaSleepOffset); } -// A.k.a. Swing +/// Set the vertical swing setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRNeoclimaAc::setSwingV(const bool on) { this->setButton(kNeoclimaButtonSwing); setBits(&remote_state[7], kNeoclimaSwingVOffset, kNeoclimaSwingVSize, on ? kNeoclimaSwingVOn : kNeoclimaSwingVOff); } +/// Get the vertical swing setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRNeoclimaAc::getSwingV(void) { return GETBITS8(remote_state[7], kNeoclimaSwingVOffset, kNeoclimaSwingVSize) == kNeoclimaSwingVOn; } -// A.k.a. Air Flow +/// Set the horizontal swing setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRNeoclimaAc::setSwingH(const bool on) { this->setButton(kNeoclimaButtonAirFlow); setBit(&remote_state[7], kNeoclimaSwingHOffset, !on); // Cleared when `on` } +/// Get the horizontal swing (Air Flow) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRNeoclimaAc::getSwingH(void) { return !GETBIT8(remote_state[7], kNeoclimaSwingHOffset); } +/// Set the Turbo setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRNeoclimaAc::setTurbo(const bool on) { this->setButton(kNeoclimaButtonTurbo); setBit(&remote_state[3], kNeoclimaTurboOffset, on); } +/// Get the Turbo setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRNeoclimaAc::getTurbo(void) { return GETBIT8(remote_state[3], kNeoclimaTurboOffset); } +/// Set the Fresh (air) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRNeoclimaAc::setFresh(const bool on) { this->setButton(kNeoclimaButtonFresh); setBit(&remote_state[5], kNeoclimaFreshOffset, on); } +/// Get the Frsh (air) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRNeoclimaAc::getFresh(void) { return GETBIT8(remote_state[5], kNeoclimaFreshOffset); } +/// Set the Hold setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRNeoclimaAc::setHold(const bool on) { this->setButton(kNeoclimaButtonHold); setBit(&remote_state[3], kNeoclimaHoldOffset, on); } +/// Get the Hold setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRNeoclimaAc::getHold(void) { return GETBIT8(remote_state[3], kNeoclimaHoldOffset); } +/// Set the Ion (filter) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRNeoclimaAc::setIon(const bool on) { this->setButton(kNeoclimaButtonIon); setBit(&remote_state[1], kNeoclimaIonOffset, on); } +/// Get the Ion (filter) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRNeoclimaAc::getIon(void) { return GETBIT8(remote_state[1], kNeoclimaIonOffset); } +/// Set the Light(LED display) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRNeoclimaAc::setLight(const bool on) { this->setButton(kNeoclimaButtonLight); setBit(&remote_state[3], kNeoclimaLightOffset, on); } +/// Get the Light (LED display) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRNeoclimaAc::getLight(void) { return GETBIT8(remote_state[3], kNeoclimaLightOffset); } -// This feature maintains the room temperature steadily at 8°C and prevents the -// room from freezing by activating the heating operation automatically when -// nobody is at home over a longer period during severe winter. +/// Set the 8°C Heat setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. +/// @note This feature maintains the room temperature steadily at 8°C and +/// prevents the room from freezing by activating the heating operation +/// automatically when nobody is at home over a longer period during severe +/// winter. void IRNeoclimaAc::set8CHeat(const bool on) { this->setButton(kNeoclimaButton8CHeat); setBit(&remote_state[1], kNeoclima8CHeatOffset, on); } +/// Get the 8°C Heat setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRNeoclimaAc::get8CHeat(void) { return GETBIT8(remote_state[1], kNeoclima8CHeatOffset); } +/// Set the Eye (Sensor) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRNeoclimaAc::setEye(const bool on) { this->setButton(kNeoclimaButtonEye); setBit(&remote_state[3], kNeoclimaEyeOffset, on); } +/// Get the Eye (Sensor) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRNeoclimaAc::getEye(void) { return GETBIT8(remote_state[3], kNeoclimaEyeOffset); } @@ -380,11 +454,14 @@ void IRNeoclimaAc::setFollow(const bool on) { } */ +/// Get the Follow Me setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRNeoclimaAc::getFollow(void) { return (remote_state[8] & kNeoclimaFollowMe) == kNeoclimaFollowMe; } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRNeoclimaAc::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::NEOCLIMA; @@ -411,7 +488,8 @@ stdAc::state_t IRNeoclimaAc::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRNeoclimaAc::toString(void) { String result = ""; result.reserve(100); // Reserve some heap for the string to reduce fragging. @@ -459,21 +537,14 @@ String IRNeoclimaAc::toString(void) { } #if DECODE_NEOCLIMA -// Decode the supplied Neoclima message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of data bits to expect. Typically kNeoclimaBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Known working -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/764 +/// Decode the supplied Neoclima message. +/// Status: STABLE / Known working +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. bool IRrecv::decodeNeoclima(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { // Compliance diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Neoclima.h b/lib/IRremoteESP8266-2.7.8/src/ir_Neoclima.h similarity index 83% rename from lib/IRremoteESP8266-2.7.5/src/ir_Neoclima.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Neoclima.h index 360c665d6..cdec89fce 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Neoclima.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Neoclima.h @@ -1,8 +1,14 @@ -// Neoclima A/C -// // Copyright 2019 David Conran -// Analysis by crankyoldgit & AndreyShpilevoy +/// @file +/// @brief Support for Neoclima protocols. +/// Analysis by crankyoldgit & AndreyShpilevoy +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/764 +/// @see https://drive.google.com/file/d/1kjYk4zS9NQcMQhFkak-L4mp4UuaAIesW/view + +// Supports: +// Brand: Neoclima, Model: NS-09AHTI A/C +// Brand: Neoclima, Model: ZH/TY-01 remote #ifndef IR_NEOCLIMA_H_ #define IR_NEOCLIMA_H_ @@ -18,14 +24,6 @@ #include "IRsend_test.h" #endif -// Supports: -// Brand: Neoclima, Model: NS-09AHTI A/C -// Brand: Neoclima, Model: ZH/TY-01 remote - -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/764 -// https://drive.google.com/file/d/1kjYk4zS9NQcMQhFkak-L4mp4UuaAIesW/view - // Constants // state[1] const uint8_t kNeoclima8CHeatOffset = 1; @@ -84,15 +82,19 @@ const uint8_t kNeoclimaFan = 0b011; const uint8_t kNeoclimaHeat = 0b100; // Classes +/// Class for handling detailed Neoclima A/C messages. class IRNeoclimaAc { public: explicit IRNeoclimaAc(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - void stateReset(void); #if SEND_NEOCLIMA void send(const uint16_t repeat = kNeoclimaMinRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + /// 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_NEOCLIMA void begin(void); void setButton(const uint8_t button); @@ -146,12 +148,13 @@ class IRNeoclimaAc { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - // The state of the IR remote in IR code form. - uint8_t remote_state[kNeoclimaStateLength]; + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint8_t remote_state[kNeoclimaStateLength]; ///< State of the remote in code. void checksum(const uint16_t length = kNeoclimaStateLength); }; diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Nikai.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Nikai.cpp similarity index 66% rename from lib/IRremoteESP8266-2.7.5/src/ir_Nikai.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Nikai.cpp index 5e6f9fbe5..01c789d70 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Nikai.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Nikai.cpp @@ -1,7 +1,12 @@ // Copyright 2009 Ken Shirriff // Copyright 2017 David Conran -// Nikai +/// @file +/// @brief Nikai +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/309 + +// Supports: +// Brand: Nikai, Model: Unknown LCD TV #include #include "IRrecv.h" @@ -9,8 +14,6 @@ #include "IRutils.h" // Constants -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/309 const uint16_t kNikaiTick = 500; const uint16_t kNikaiHdrMarkTicks = 8; const uint16_t kNikaiHdrMark = kNikaiHdrMarkTicks * kNikaiTick; @@ -26,38 +29,26 @@ const uint16_t kNikaiMinGapTicks = 17; const uint16_t kNikaiMinGap = kNikaiMinGapTicks * kNikaiTick; #if SEND_NIKAI -// Send a Nikai TV formatted message. -// -// Args: -// data: The message to be sent. -// nbits: The bit size of the message being sent. typically kNikaiBits. -// repeat: The number of times the message is to be repeated. -// -// Status: STABLE / Working. -// -// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/309 +/// Send a Nikai formatted message. +/// Status: STABLE / Working. +/// @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::sendNikai(uint64_t data, uint16_t nbits, uint16_t repeat) { sendGeneric(kNikaiHdrMark, kNikaiHdrSpace, kNikaiBitMark, kNikaiOneSpace, kNikaiBitMark, kNikaiZeroSpace, kNikaiBitMark, kNikaiMinGap, data, nbits, 38, true, repeat, 33); } -#endif +#endif // SEND_NIKAI #if DECODE_NIKAI -// Decode the supplied Nikai message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits to expect in the data portion. -// Typically kNikaiBits. -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Working. -// +/// Decode the supplied Nikai message. +/// Status: STABLE / Working. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. bool IRrecv::decodeNikai(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (strict && nbits != kNikaiBits) @@ -80,4 +71,4 @@ bool IRrecv::decodeNikai(decode_results *results, uint16_t offset, results->address = 0; return true; } -#endif +#endif // DECODE_NIKAI diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Panasonic.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Panasonic.cpp similarity index 69% rename from lib/IRremoteESP8266-2.7.5/src/ir_Panasonic.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Panasonic.cpp index d8b627c9f..b1702824f 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Panasonic.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Panasonic.cpp @@ -1,7 +1,16 @@ // Copyright 2015 Kristian Lauszus // Copyright 2017, 2018 David Conran -// Panasonic devices +/// @file +/// @brief Support for Panasonic protocols. +/// Panasonic protocol originally added by Kristian Lauszus +/// (Thanks to zenwheel and other people at the original blog post) +/// @see Panasonic https://github.com/z3t0/Arduino-IRremote +/// @see http://www.remotecentral.com/cgi-bin/mboard/rc-pronto/thread.cgi?2615 +/// @see Panasonic A/C support heavily influenced by https://github.com/ToniA/ESPEasy/blob/HeatpumpIR/lib/HeatpumpIR/PanasonicHeatpumpIR.cpp +/// Panasonic A/C Clock & Timer support: +/// Reverse Engineering by MikkelTb +/// Code by crankyoldgit #include "ir_Panasonic.h" #include @@ -14,29 +23,8 @@ #include "IRtext.h" #include "IRutils.h" -// Panasonic protocol originally added by Kristian Lauszus from: -// https://github.com/z3t0/Arduino-IRremote -// (Thanks to zenwheel and other people at the original blog post) -// -// Panasonic A/C support add by crankyoldgit but heavily influenced by: -// https://github.com/ToniA/ESPEasy/blob/HeatpumpIR/lib/HeatpumpIR/PanasonicHeatpumpIR.cpp -// Panasonic A/C Clock & Timer support: -// Reverse Engineering by MikkelTb -// Code by crankyoldgit -// Panasonic A/C models supported: -// A/C Series/models: -// JKE, LKE, DKE, CKP, PKR, RKR, & NKE series. (In theory) -// CS-YW9MKD, CS-Z9RKR, CS-E7PKR (confirmed) -// CS-ME14CKPG / CS-ME12CKPG / CS-ME10CKPG -// A/C Remotes: -// A75C3747 (confirmed) -// A75C3704 -// A75C2311 (CKP) - // Constants -// Ref: -// http://www.remotecentral.com/cgi-bin/mboard/rc-pronto/thread.cgi?26152 - +/// @see http://www.remotecentral.com/cgi-bin/mboard/rc-pronto/thread.cgi?26152 const uint16_t kPanasonicTick = 432; const uint16_t kPanasonicHdrMarkTicks = 8; const uint16_t kPanasonicHdrMark = kPanasonicHdrMarkTicks * kPanasonicTick; @@ -74,18 +62,15 @@ using irutils::minsToString; using irutils::setBit; using irutils::setBits; +// Used by Denon as well. #if (SEND_PANASONIC || SEND_DENON) -// Send a Panasonic formatted message. -// -// Args: -// data: The message to be sent. -// nbits: The number of bits of the message to be sent. (kPanasonicBits). -// repeat: The number of times the command is to be repeated. -// -// Status: STABLE / Should be working. -// -// Note: -// This protocol is a modified version of Kaseikyo. +/// Send a Panasonic formatted message. +/// Status: STABLE / Should be working. +/// @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. +/// @note This protocol is a modified version of Kaseikyo. +/// @note Use this method if you want to send the results of `decodePanasonic`. void IRsend::sendPanasonic64(const uint64_t data, const uint16_t nbits, const uint16_t repeat) { sendGeneric(kPanasonicHdrMark, kPanasonicHdrSpace, kPanasonicBitMark, @@ -94,39 +79,29 @@ void IRsend::sendPanasonic64(const uint64_t data, const uint16_t nbits, data, nbits, kPanasonicFreq, true, repeat, 50); } -// Send a Panasonic formatted message. -// -// Args: -// address: The manufacturer code. -// data: The data portion to be sent. -// nbits: The number of bits of the message to be sent. (kPanasonicBits). -// repeat: The number of times the command is to be repeated. -// -// Status: STABLE. -// -// Note: -// This protocol is a modified version of Kaseikyo. +/// Send a Panasonic formatted message. +/// Status: STABLE, but DEPRECATED +/// @deprecated This is only for legacy use only, please use `sendPanasonic64()` +/// instead. +/// @param[in] address The 16-bit manufacturer code. +/// @param[in] data The 32-bit data portion of 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. +/// @note This protocol is a modified version of Kaseikyo. void IRsend::sendPanasonic(const uint16_t address, const uint32_t data, const uint16_t nbits, const uint16_t repeat) { sendPanasonic64(((uint64_t)address << 32) | (uint64_t)data, nbits, repeat); } -// Calculate the raw Panasonic data based on device, subdevice, & function. -// -// Args: -// manufacturer: A 16-bit manufacturer code. e.g. 0x4004 is Panasonic. -// device: An 8-bit code. -// subdevice: An 8-bit code. -// function: An 8-bit code. -// Returns: -// A raw uint64_t Panasonic message. -// -// Status: STABLE / Should be working.. -// -// Note: -// Panasonic 48-bit protocol is a modified version of Kaseikyo. -// Ref: -// http://www.remotecentral.com/cgi-bin/mboard/rc-pronto/thread.cgi?2615 +/// Calculate the raw Panasonic data based on device, subdevice, & function. +/// Status: STABLE / Should be working. +/// @param[in] manufacturer A 16-bit manufacturer code. e.g. 0x4004 is Panasonic +/// @param[in] device An 8-bit code. +/// @param[in] subdevice An 8-bit code. +/// @param[in] function An 8-bit code. +/// @return A value suitable for use with `sendPanasonic64()`. +/// @note Panasonic 48-bit protocol is a modified version of Kaseikyo. +/// @see http://www.remotecentral.com/cgi-bin/mboard/rc-pronto/thread.cgi?2615 uint64_t IRsend::encodePanasonic(const uint16_t manufacturer, const uint8_t device, const uint8_t subdevice, @@ -137,24 +112,21 @@ uint64_t IRsend::encodePanasonic(const uint16_t manufacturer, } #endif // (SEND_PANASONIC || SEND_DENON) +// Used by Denon as well. #if (DECODE_PANASONIC || DECODE_DENON) -// Decode the supplied Panasonic message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of data bits to expect. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Should be working. -// Note: -// Panasonic 48-bit protocol is a modified version of Kaseikyo. -// Ref: -// http://www.remotecentral.com/cgi-bin/mboard/rc-pronto/thread.cgi?26152 -// http://www.hifi-remote.com/wiki/index.php?title=Panasonic +/// Decode the supplied Panasonic message. +/// Status: STABLE / Should be working. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] manufacturer A 16-bit manufacturer code. e.g. 0x4004 is Panasonic +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @warning Results to be used with `sendPanasonic64()`, not `sendPanasonic()`. +/// @note Panasonic 48-bit protocol is a modified version of Kaseikyo. +/// @see http://www.remotecentral.com/cgi-bin/mboard/rc-pronto/thread.cgi?2615 +/// @see http://www.hifi-remote.com/wiki/index.php?title=Panasonic bool IRrecv::decodePanasonic(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict, const uint32_t manufacturer) { @@ -193,24 +165,11 @@ bool IRrecv::decodePanasonic(decode_results *results, uint16_t offset, #endif // (DECODE_PANASONIC || DECODE_DENON) #if SEND_PANASONIC_AC -// Send a Panasonic A/C message. -// -// Args: -// data: Contents of the message to be sent. (Guessing MSBF order) -// nbits: Nr. of bits of data to be sent. Typically kPanasonicAcBits. -// repeat: Nr. of additional times the message is to be sent. -// -// Status: Beta / Appears to work with real device(s). -//: -// Panasonic A/C models supported: -// A/C Series/models: -// JKE, LKE, DKE, CKP, PKR, RKR, & NKE series. -// CS-YW9MKD -// CS-E7PKR -// A/C Remotes: -// A75C3747 -// A75C3704 -// +/// Send a Panasonic A/C message. +/// Status: STABLE / Work with real device(s). +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendPanasonicAC(const uint8_t data[], const uint16_t nbytes, const uint16_t repeat) { if (nbytes < kPanasonicAcSection1Length) return; @@ -231,44 +190,59 @@ void IRsend::sendPanasonicAC(const uint8_t data[], const uint16_t nbytes, } #endif // SEND_PANASONIC_AC +/// 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? IRPanasonicAc::IRPanasonicAc(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { this->stateReset(); } +/// Reset the state of the remote to a known good state/sequence. void IRPanasonicAc::stateReset(void) { memcpy(remote_state, kPanasonicKnownGoodState, kPanasonicAcStateLength); _temp = 25; // An initial saved desired temp. Completely made up. _swingh = kPanasonicAcSwingHMiddle; // A similar made up value for H Swing. } +/// Set up hardware to be able to send a message. void IRPanasonicAc::begin(void) { _irsend.begin(); } -// Verify the checksum is valid for a given state. -// Args: -// state: The array to verify the checksum of. -// length: The size of the state. -// Returns: -// A boolean. -bool IRPanasonicAc::validChecksum(uint8_t state[], const uint16_t length) { +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length of the state array. +/// @return true, if the state has a valid checksum. Otherwise, false. +bool IRPanasonicAc::validChecksum(const uint8_t *state, const uint16_t length) { if (length < 2) return false; // 1 byte of data can't have a checksum. return (state[length - 1] == sumBytes(state, length - 1, kPanasonicAcChecksumInit)); } -uint8_t IRPanasonicAc::calcChecksum(uint8_t state[], const uint16_t length) { +/// Calculate the checksum for a given state. +/// @param[in] state The value to calc the checksum of. +/// @param[in] length The size/length of the state. +/// @return The calculated checksum value. +uint8_t IRPanasonicAc::calcChecksum(const uint8_t *state, + const uint16_t length) { return sumBytes(state, length - 1, kPanasonicAcChecksumInit); } +/// Calculate and set the checksum values for the internal state. +/// @param[in] length The size/length of the state. void IRPanasonicAc::fixChecksum(const uint16_t length) { remote_state[length - 1] = this->calcChecksum(remote_state, length); } #if SEND_PANASONIC_AC +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRPanasonicAc::send(const uint16_t repeat) { _irsend.sendPanasonicAC(getRaw(), kPanasonicAcStateLength, repeat); } #endif // SEND_PANASONIC_AC +/// Set the model of the A/C to emulate. +/// @param[in] model The enum of the appropriate model. void IRPanasonicAc::setModel(const panasonic_ac_remote_model_t model) { switch (model) { case panasonic_ac_remote_model_t::kPanasonicDke: @@ -317,6 +291,8 @@ void IRPanasonicAc::setModel(const panasonic_ac_remote_model_t model) { setIon(getIon()); } +/// Get/Detect the model of the A/C. +/// @return The enum of the compatible model. panasonic_ac_remote_model_t IRPanasonicAc::getModel(void) { if (remote_state[23] == 0x89) return kPanasonicRkr; if (remote_state[17] == 0x00) { @@ -334,45 +310,55 @@ panasonic_ac_remote_model_t IRPanasonicAc::getModel(void) { return panasonic_ac_remote_model_t::kPanasonicUnknown; // Default } +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t *IRPanasonicAc::getRaw(void) { this->fixChecksum(); return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] state A valid code for this protocol. void IRPanasonicAc::setRaw(const uint8_t state[]) { memcpy(remote_state, state, kPanasonicAcStateLength); } -// Control the power state of the A/C unit. -// -// For CKP models, the remote has no memory of the power state the A/C unit -// should be in. For those models setting this on/true will toggle the power -// state of the Panasonic A/C unit with the next meessage. -// e.g. If the A/C unit is already on, setPower(true) will turn it off. -// If the A/C unit is already off, setPower(true) will turn it on. -// setPower(false) will leave the A/C power state as it was. -// -// For all other models, setPower(true) should set the internal state to -// turn it on, and setPower(false) should turn it off. +/// Control the power state of the A/C unit. +/// @param[in] on true, the setting is on. false, the setting is off. +/// @warning For CKP models, the remote has no memory of the power state the A/C +/// unit should be in. For those models setting this on/true will toggle the +/// power state of the Panasonic A/C unit with the next meessage. +/// e.g. If the A/C unit is already on, setPower(true) will turn it off. +/// If the A/C unit is already off, setPower(true) will turn it on. +/// `setPower(false)` will leave the A/C power state as it was. +/// For all other models, setPower(true) should set the internal state to +/// turn it on, and setPower(false) should turn it off. void IRPanasonicAc::setPower(const bool on) { setBit(&remote_state[13], kPanasonicAcPowerOffset, on); } -// Return the A/C power state of the remote. -// Except for CKP models, where it returns if the power state will be toggled -// on the A/C unit when the next message is sent. +/// Get the A/C power state of the remote. +/// @return true, the setting is on. false, the setting is off. +/// @warning Except for CKP models, where it returns if the power state will be +/// toggled on the A/C unit when the next message is sent. bool IRPanasonicAc::getPower(void) { return GETBIT8(remote_state[13], kPanasonicAcPowerOffset); } +/// Change the power setting to On. void IRPanasonicAc::on(void) { setPower(true); } +/// Change the power setting to Off. void IRPanasonicAc::off(void) { setPower(false); } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRPanasonicAc::getMode(void) { return GETBITS8(remote_state[13], kHighNibble, kModeBitsSize); } +/// Set the operating mode of the A/C. +/// @param[in] desired The desired operating mode. void IRPanasonicAc::setMode(const uint8_t desired) { uint8_t mode = kPanasonicAcAuto; // Default to Auto mode. switch (desired) { @@ -394,17 +380,17 @@ void IRPanasonicAc::setMode(const uint8_t desired) { setBits(&remote_state[13], kHighNibble, kModeBitsSize, mode); } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRPanasonicAc::getTemp(void) { return GETBITS8(remote_state[14], kPanasonicAcTempOffset, kPanasonicAcTempSize); } -// Set the desitred temperature in Celsius. -// Args: -// celsius: The temperature to set the A/C unit to. -// remember: A boolean flag for the class to remember the temperature. -// -// Automatically safely limits the temp to the operating range supported. +/// Set the temperature. +/// @param[in] celsius The temperature in degrees celsius. +/// @param[in] remember: A flag for the class to remember the temperature. +/// @note Automatically safely limits the temp to the operating range supported. void IRPanasonicAc::setTemp(const uint8_t celsius, const bool remember) { uint8_t temperature; temperature = std::max(celsius, kPanasonicAcMinTemp); @@ -414,10 +400,14 @@ void IRPanasonicAc::setTemp(const uint8_t celsius, const bool remember) { temperature); } +/// Get the current vertical swing setting. +/// @return The current position it is set to. uint8_t IRPanasonicAc::getSwingVertical(void) { return GETBITS8(remote_state[16], kLowNibble, kNibbleSize); } +/// Control the vertical swing setting. +/// @param[in] desired_elevation The position to set the vertical swing to. void IRPanasonicAc::setSwingVertical(const uint8_t desired_elevation) { uint8_t elevation = desired_elevation; if (elevation != kPanasonicAcSwingVAuto) { @@ -427,10 +417,14 @@ void IRPanasonicAc::setSwingVertical(const uint8_t desired_elevation) { setBits(&remote_state[16], kLowNibble, kNibbleSize, elevation); } +/// Get the current horizontal swing setting. +/// @return The current position it is set to. uint8_t IRPanasonicAc::getSwingHorizontal(void) { return GETBITS8(remote_state[17], kLowNibble, kNibbleSize); } +/// Control the horizontal swing setting. +/// @param[in] desired_direction The position to set the horizontal swing to. void IRPanasonicAc::setSwingHorizontal(const uint8_t desired_direction) { switch (desired_direction) { case kPanasonicAcSwingHAuto: @@ -458,6 +452,8 @@ void IRPanasonicAc::setSwingHorizontal(const uint8_t desired_direction) { setBits(&remote_state[17], kLowNibble, kNibbleSize, direction); } +/// Set the speed of the fan. +/// @param[in] speed The desired setting. void IRPanasonicAc::setFan(const uint8_t speed) { switch (speed) { case kPanasonicAcFanMin: @@ -471,11 +467,15 @@ void IRPanasonicAc::setFan(const uint8_t speed) { } } +/// Get the current fan speed setting. +/// @return The current fan speed. uint8_t IRPanasonicAc::getFan(void) { return GETBITS8(remote_state[16], kHighNibble, kNibbleSize) - kPanasonicAcFanDelta; } +/// Get the Quiet setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRPanasonicAc::getQuiet(void) { switch (this->getModel()) { case kPanasonicRkr: @@ -486,6 +486,8 @@ bool IRPanasonicAc::getQuiet(void) { } } +/// Set the Quiet setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRPanasonicAc::setQuiet(const bool on) { uint8_t offset; switch (this->getModel()) { @@ -497,6 +499,8 @@ void IRPanasonicAc::setQuiet(const bool on) { setBit(&remote_state[21], offset, on); } +/// Get the Powerful (Turbo) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRPanasonicAc::getPowerful(void) { switch (this->getModel()) { case kPanasonicRkr: @@ -507,6 +511,8 @@ bool IRPanasonicAc::getPowerful(void) { } } +/// Set the Powerful (Turbo) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRPanasonicAc::setPowerful(const bool on) { uint8_t offset; switch (this->getModel()) { @@ -519,11 +525,18 @@ void IRPanasonicAc::setPowerful(const bool on) { setBit(&remote_state[21], offset, on); } -// Convert standard (military/24hr) time to nr. of minutes since midnight. +/// Convert standard (military/24hr) time to nr. of minutes since midnight. +/// @param[in] hours The hours component of the time. +/// @param[in] mins The minutes component of the time. +/// @return The nr of minutes since midnight. uint16_t IRPanasonicAc::encodeTime(const uint8_t hours, const uint8_t mins) { return std::min(hours, (uint8_t)23) * 60 + std::min(mins, (uint8_t)59); } +/// Get the time from a given pointer location. +/// @param[in] ptr A pointer to a time location in a state. +/// @return The time expressed as nr. of minutes past midnight. +/// @note Internal use only. uint16_t IRPanasonicAc::_getTime(const uint8_t ptr[]) { uint16_t result = (GETBITS8( ptr[1], kLowNibble, kPanasonicAcTimeOverflowSize) << @@ -532,8 +545,15 @@ uint16_t IRPanasonicAc::_getTime(const uint8_t ptr[]) { return result; } +/// Get the current clock time value. +/// @return The time expressed as nr. of minutes past midnight. uint16_t IRPanasonicAc::getClock(void) { return _getTime(&remote_state[24]); } +/// Set the time at a given pointer location. +/// @param[in, out] ptr A pointer to a time location in a state. +/// @param[in] mins_since_midnight The time as nr. of minutes past midnight. +/// @param[in] round_down Do we round to the nearest 10 minute mark? +/// @note Internal use only. void IRPanasonicAc::_setTime(uint8_t * const ptr, const uint16_t mins_since_midnight, const bool round_down) { @@ -546,12 +566,19 @@ void IRPanasonicAc::_setTime(uint8_t * const ptr, corrected >> (kPanasonicAcTimeSize - kPanasonicAcTimeOverflowSize)); } +/// Set the current clock time value. +/// @param[in] mins_since_midnight The time as nr. of minutes past midnight. void IRPanasonicAc::setClock(const uint16_t mins_since_midnight) { _setTime(&remote_state[24], mins_since_midnight, false); } +/// Get the On Timer time value. +/// @return The time expressed as nr. of minutes past midnight. uint16_t IRPanasonicAc::getOnTimer(void) { return _getTime(&remote_state[18]); } +/// Set/Enable the On Timer. +/// @param[in] mins_since_midnight The time as nr. of minutes past midnight. +/// @param[in] enable Do we enable the timer or not? void IRPanasonicAc::setOnTimer(const uint16_t mins_since_midnight, const bool enable) { // Set the timer flag. @@ -560,12 +587,17 @@ void IRPanasonicAc::setOnTimer(const uint16_t mins_since_midnight, _setTime(&remote_state[18], mins_since_midnight, true); } +/// Cancel the On Timer. void IRPanasonicAc::cancelOnTimer(void) { this->setOnTimer(0, false); } +/// Check if the On Timer is Enabled. +/// @return true, the setting is on. false, the setting is off. bool IRPanasonicAc::isOnTimerEnabled(void) { return GETBIT8(remote_state[13], kPanasonicAcOnTimerOffset); } +/// Get the Off Timer time value. +/// @return The time expressed as nr. of minutes past midnight. uint16_t IRPanasonicAc::getOffTimer(void) { uint16_t result = (GETBITS8(remote_state[20], 0, 7) << kNibbleSize) | GETBITS8(remote_state[19], kHighNibble, kNibbleSize); @@ -573,6 +605,9 @@ uint16_t IRPanasonicAc::getOffTimer(void) { return result; } +/// Set/Enable the Off Timer. +/// @param[in] mins_since_midnight The time as nr. of minutes past midnight. +/// @param[in] enable Do we enable the timer or not? void IRPanasonicAc::setOffTimer(const uint16_t mins_since_midnight, const bool enable) { // Ensure its on a 10 minute boundary and no overflow. @@ -587,12 +622,17 @@ void IRPanasonicAc::setOffTimer(const uint16_t mins_since_midnight, setBits(&remote_state[20], 0, 7, corrected >> kNibbleSize); } +/// Cancel the Off Timer. void IRPanasonicAc::cancelOffTimer(void) { this->setOffTimer(0, false); } +/// Check if the Off Timer is Enabled. +/// @return true, the setting is on. false, the setting is off. bool IRPanasonicAc::isOffTimerEnabled(void) { return GETBIT8(remote_state[13], kPanasonicAcOffTimerOffset); } +/// Get the Ion (filter) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRPanasonicAc::getIon(void) { switch (this->getModel()) { case kPanasonicDke: @@ -603,13 +643,17 @@ bool IRPanasonicAc::getIon(void) { } } +/// Set the Ion (filter) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRPanasonicAc::setIon(const bool on) { if (this->getModel() == kPanasonicDke) setBit(&remote_state[kPanasonicAcIonFilterByte], kPanasonicAcIonFilterOffset, on); } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRPanasonicAc::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kPanasonicAcCool; @@ -620,7 +664,9 @@ uint8_t IRPanasonicAc::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRPanasonicAc::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: return kPanasonicAcFanMin; @@ -632,7 +678,9 @@ uint8_t IRPanasonicAc::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a standard A/C vertical swing into its native setting. +/// Convert a standard A/C vertical swing into its native setting. +/// @param[in] position A stdAc::swingv_t position to convert. +/// @return The equivilent native horizontal swing position. uint8_t IRPanasonicAc::convertSwingV(const stdAc::swingv_t position) { switch (position) { case stdAc::swingv_t::kHighest: @@ -644,7 +692,9 @@ uint8_t IRPanasonicAc::convertSwingV(const stdAc::swingv_t position) { } } -// Convert a standard A/C horizontal swing into its native setting. +/// Convert a standard A/C horizontal swing into its native setting. +/// @param[in] position A stdAc::swingh_t position to convert. +/// @return The equivilent native horizontal swing position. uint8_t IRPanasonicAc::convertSwingH(const stdAc::swingh_t position) { switch (position) { case stdAc::swingh_t::kLeftMax: return kPanasonicAcSwingHFullLeft; @@ -656,7 +706,9 @@ uint8_t IRPanasonicAc::convertSwingH(const stdAc::swingh_t position) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRPanasonicAc::toCommonMode(const uint8_t mode) { switch (mode) { case kPanasonicAcCool: return stdAc::opmode_t::kCool; @@ -667,7 +719,9 @@ stdAc::opmode_t IRPanasonicAc::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] spd The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRPanasonicAc::toCommonFanSpeed(const uint8_t spd) { switch (spd) { case kPanasonicAcFanMax: return stdAc::fanspeed_t::kMax; @@ -679,7 +733,9 @@ stdAc::fanspeed_t IRPanasonicAc::toCommonFanSpeed(const uint8_t spd) { } } -// Convert a native vertical swing to it's common equivalent. +/// Convert a native horizontal swing postion to it's common equivalent. +/// @param[in] pos A native position to convert. +/// @return The common horizontal swing position. stdAc::swingh_t IRPanasonicAc::toCommonSwingH(const uint8_t pos) { switch (pos) { case kPanasonicAcSwingHFullLeft: return stdAc::swingh_t::kLeftMax; @@ -691,7 +747,9 @@ stdAc::swingh_t IRPanasonicAc::toCommonSwingH(const uint8_t pos) { } } -// Convert a native vertical swing to it's common equivalent. +/// Convert a native vertical swing postion to it's common equivalent. +/// @param[in] pos A native position to convert. +/// @return The common vertical swing position. stdAc::swingv_t IRPanasonicAc::toCommonSwingV(const uint8_t pos) { if (pos >= kPanasonicAcSwingVHighest && pos <= kPanasonicAcSwingVLowest) return (stdAc::swingv_t)pos; @@ -699,7 +757,8 @@ stdAc::swingv_t IRPanasonicAc::toCommonSwingV(const uint8_t pos) { return stdAc::swingv_t::kAuto; } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRPanasonicAc::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::PANASONIC_AC; @@ -724,7 +783,8 @@ stdAc::state_t IRPanasonicAc::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the internal state into a human readable string. +/// @return A string containing the settings in human-readable form. String IRPanasonicAc::toString(void) { String result = ""; result.reserve(180); // Reserve some heap for the string to reduce fragging. @@ -808,27 +868,14 @@ String IRPanasonicAc::toString(void) { } #if DECODE_PANASONIC_AC -// Decode the supplied Panasonic AC message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kPanasonicAcBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: Beta / Appears to work with real device(s). -// -// Panasonic A/C models supported: -// A/C Series/models: -// JKE, LKE, DKE, PKR, & NKE series. -// CS-YW9MKD -// CS-E7PKR -// A/C Remotes: -// A75C3747 (Confirmed) -// A75C3704 +/// Decode the supplied Panasonic AC message. +/// Status: STABLE / Works with real device(s). +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. bool IRrecv::decodePanasonicAC(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { uint8_t min_nr_of_messages = 1; diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Panasonic.h b/lib/IRremoteESP8266-2.7.8/src/ir_Panasonic.h similarity index 72% rename from lib/IRremoteESP8266-2.7.5/src/ir_Panasonic.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Panasonic.h index 42e771fb3..4098993f9 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Panasonic.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Panasonic.h @@ -1,24 +1,28 @@ // Copyright 2018 David Conran +/// @file +/// @brief Support for Panasonic protocols. +/// @see Panasonic A/C support heavily influenced by https://github.com/ToniA/ESPEasy/blob/HeatpumpIR/lib/HeatpumpIR/PanasonicHeatpumpIR.cpp + // Supports: -// Brand: Panasonic, Model: TV -// Brand: Panasonic, Model: JKE series A/C -// Brand: Panasonic, Model: DKE series A/C -// Brand: Panasonic, Model: DKW series A/C (DKE) -// Brand: Panasonic, Model: PKR series A/C (DKE) -// Brand: Panasonic, Model: CKP series A/C -// Brand: Panasonic, Model: NKE series A/C -// Brand: Panasonic, Model: RKR series A/C -// Brand: Panasonic, Model: CS-ME10CKPG A/C -// Brand: Panasonic, Model: CS-ME12CKPG A/C -// Brand: Panasonic, Model: CS-ME14CKPG A/C -// Brand: Panasonic, Model: CS-E7PKR A/C (DKE) -// Brand: Panasonic, Model: CS-Z9RKR A/C -// Brand: Panasonic, Model: CS-YW9MKD A/C -// Brand: Panasonic, Model: A75C2311 remote (CKP) -// Brand: Panasonic, Model: A75C2616-1 remote (DKE) -// Brand: Panasonic, Model: A75C3704 remote -// Brand: Panasonic, Model: A75C3747 remote +// Brand: Panasonic, Model: TV (PANASONIC) +// Brand: Panasonic, Model: NKE series A/C (PANASONIC_AC NKE/2) +// Brand: Panasonic, Model: DKE series A/C (PANASONIC_AC DKE/3) +// Brand: Panasonic, Model: DKW series A/C (PANASONIC_AC DKE/3) +// Brand: Panasonic, Model: PKR series A/C (PANASONIC_AC DKE/3) +// Brand: Panasonic, Model: JKE series A/C (PANASONIC_AC JKE/4) +// Brand: Panasonic, Model: CKP series A/C (PANASONIC_AC CKP/5) +// Brand: Panasonic, Model: RKR series A/C (PANASONIC_AC RKR/6) +// Brand: Panasonic, Model: CS-ME10CKPG A/C (PANASONIC_AC CKP/5) +// Brand: Panasonic, Model: CS-ME12CKPG A/C (PANASONIC_AC CKP/5) +// Brand: Panasonic, Model: CS-ME14CKPG A/C (PANASONIC_AC CKP/5) +// Brand: Panasonic, Model: CS-E7PKR A/C (PANASONIC_AC DKE/2) +// Brand: Panasonic, Model: CS-Z9RKR A/C (PANASONIC_AC RKR/6) +// Brand: Panasonic, Model: CS-YW9MKD A/C (PANASONIC_AC JKE/4) +// Brand: Panasonic, Model: A75C2311 remote (PANASONIC_AC CKP/5) +// Brand: Panasonic, Model: A75C2616-1 remote (PANASONIC_AC DKE/3) +// Brand: Panasonic, Model: A75C3704 remote (PANASONIC_AC DKE/3) +// Brand: Panasonic, Model: A75C3747 remote (PANASONIC_AC JKE/4) #ifndef IR_PANASONIC_H_ #define IR_PANASONIC_H_ @@ -34,9 +38,6 @@ #include "IRsend_test.h" #endif -// Panasonic A/C support heavily influenced by: -// https://github.com/ToniA/ESPEasy/blob/HeatpumpIR/lib/HeatpumpIR/PanasonicHeatpumpIR.cpp - // Constants const uint16_t kPanasonicFreq = 36700; const uint16_t kPanasonicAcExcess = 0; @@ -93,16 +94,19 @@ const uint8_t kPanasonicKnownGoodState[kPanasonicAcStateLength] = { 0x20, 0xE0, 0x04, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x0E, 0xE0, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00}; - +/// Class for handling detailed Panasonic A/C messages. class IRPanasonicAc { public: explicit IRPanasonicAc(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - void stateReset(void); #if SEND_PANASONIC void send(const uint16_t repeat = kPanasonicAcDefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + /// 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_PANASONIC void begin(void); void on(void); @@ -117,9 +121,9 @@ class IRPanasonicAc { uint8_t getMode(void); void setRaw(const uint8_t state[]); uint8_t *getRaw(void); - static bool validChecksum(uint8_t *state, + static bool validChecksum(const uint8_t *state, const uint16_t length = kPanasonicAcStateLength); - static uint8_t calcChecksum(uint8_t *state, + static uint8_t calcChecksum(const uint8_t *state, const uint16_t length = kPanasonicAcStateLength); void setQuiet(const bool on); bool getQuiet(void); @@ -158,16 +162,16 @@ class IRPanasonicAc { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - uint8_t remote_state[kPanasonicAcStateLength]; + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint8_t remote_state[kPanasonicAcStateLength]; ///< The state in code form. uint8_t _swingh; uint8_t _temp; void fixChecksum(const uint16_t length = kPanasonicAcStateLength); - static uint8_t calcChecksum(const uint8_t *state, - const uint16_t length = kPanasonicAcStateLength); static uint16_t _getTime(const uint8_t ptr[]); static void _setTime(uint8_t * const ptr, const uint16_t mins_since_midnight, const bool round_down); diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Pioneer.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Pioneer.cpp similarity index 70% rename from lib/IRremoteESP8266-2.7.5/src/ir_Pioneer.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Pioneer.cpp index 08bbf3c06..d5ac89765 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Pioneer.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Pioneer.cpp @@ -3,7 +3,14 @@ // Copyright 2018 Kamil Palczewski // Copyright 2019 s-hadinger -// Pioneer remote emulation +/// @file +/// @brief Pioneer remote emulation +/// @see http://www.adrian-kingston.com/IRFormatPioneer.htm +/// @see https://github.com/crankyoldgit/IRremoteESP8266/pull/547 +/// @see https://www.pioneerelectronics.com/PUSA/Support/Home-Entertainment-Custom-Install/IR+Codes/A+V+Receivers + +// Supports: +// Brand: Pioneer, Model: AV Receivers #define __STDC_LIMIT_MACROS #include @@ -13,8 +20,6 @@ #include "IRutils.h" // Constants -// Ref: -// http://www.adrian-kingston.com/IRFormatPioneer.htm const uint16_t kPioneerTick = 534; const uint16_t kPioneerHdrMarkTicks = 16; const uint16_t kPioneerHdrMark = kPioneerHdrMarkTicks * kPioneerTick; @@ -33,18 +38,11 @@ const uint16_t kPioneerMinGapTicks = 47; const uint32_t kPioneerMinGap = kPioneerMinGapTicks * kPioneerTick; #if SEND_PIONEER -// Send a raw Pioneer formatted message. -// -// Args: -// data: The message to be sent. -// nbits: The number of bits of the message to be sent. -// Typically kPioneerBits. -// repeat: The number of times the command is to be repeated. -// -// Status: STABLE / Expected to be working. -// -// Ref: -// http://adrian-kingston.com/IRFormatPioneer.htm +/// Send a raw Pioneer formatted message. +/// Status: STABLE / Expected to be working. +/// @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::sendPioneer(const uint64_t data, const uint16_t nbits, const uint16_t repeat) { // If nbits is to big, abort. @@ -68,23 +66,18 @@ void IRsend::sendPioneer(const uint64_t data, const uint16_t nbits, } } -// Calculate the raw Pioneer data code based on two NEC sub-codes -// Args: -// address A 16-bit "published" NEC value. -// command: A 16-bit "published" NEC value. -// Returns: -// A raw 64-bit Pioneer message code. -// -// Status: STABLE / Expected to work. -// -// Note: -// Address & Command can be take from a decode result OR from the spreadsheets -// located at: -// https://www.pioneerelectronics.com/PUSA/Support/Home-Entertainment-Custom-Install/IR+Codes/A+V+Receivers -// where the first part is considered the address, -// and the second the command. -// e.g. -// "A556+AF20" is an Address of 0xA556 & a Command of 0xAF20. +/// Calculate the raw Pioneer data code based on two NEC sub-codes +/// Status: STABLE / Expected to work. +/// @param[in] address A 16-bit "published" NEC value. +/// @param[in] command A 16-bit "published" NEC value. +/// @return A raw 64-bit Pioneer message code for use with `sendPioneer()`` +/// @note Address & Command can be take from a decode result OR from the +/// spreadsheets located at: +/// https://www.pioneerelectronics.com/PUSA/Support/Home-Entertainment-Custom-Install/IR+Codes/A+V+Receivers +/// where the first part is considered the address, +/// and the second the command. +/// e.g. +/// "A556+AF20" is an Address of 0xA556 & a Command of 0xAF20. uint64_t IRsend::encodePioneer(const uint16_t address, const uint16_t command) { return (((uint64_t)encodeNEC(address >> 8, address & 0xFF)) << 32) | encodeNEC(command >> 8, command & 0xFF); @@ -92,19 +85,14 @@ uint64_t IRsend::encodePioneer(const uint16_t address, const uint16_t command) { #endif // SEND_PIONEER #if DECODE_PIONEER -// Decode the supplied Pioneer message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kPioneerBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Should be working. (Self decodes & real examples) -// +/// Decode the supplied Pioneer message. +/// Status: STABLE / Should be working. (Self decodes & real examples) +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. bool IRrecv::decodePioneer(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen < 2 * (nbits + kHeader + kFooter) - 1 + offset) diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Pronto.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Pronto.cpp new file mode 100644 index 000000000..2d4ffa759 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Pronto.cpp @@ -0,0 +1,107 @@ +// Copyright 2017 David Conran + +/// @file +/// @brief Pronto code message generation +/// @see http://www.etcwiki.org/wiki/Pronto_Infrared_Format +/// @see http://www.remotecentral.com/features/irdisp2.htm +/// @see http://harctoolbox.org/Glossary.html#ProntoSemantics +/// @see https://irdb.globalcache.com/ + +// Supports: +// Brand: Pronto, Model: Pronto Hex + +#include +#include "IRsend.h" + +// Constants +const float kProntoFreqFactor = 0.241246; +const uint16_t kProntoTypeOffset = 0; +const uint16_t kProntoFreqOffset = 1; +const uint16_t kProntoSeq1LenOffset = 2; +const uint16_t kProntoSeq2LenOffset = 3; +const uint16_t kProntoDataOffset = 4; + +#if SEND_PRONTO +/// Send a Pronto Code formatted message. +/// Status: STABLE / Known working. +/// @param[in] data An array of uint16_t containing the pronto codes. +/// @param[in] len Nr. of entries in the data[] array. +/// @param[in] repeat Nr. of times to repeat the message. +/// @note Pronto codes are typically represented in hexadecimal. +/// You will need to convert the code to an array of integers, and calculate +/// it's length. +/// e.g. +/// @code +/// A Sony 20 bit DVD remote command. +/// "0000 0067 0000 0015 0060 0018 0018 0018 0030 0018 0030 0018 0030 0018 +/// 0018 0018 0030 0018 0018 0018 0018 0018 0030 0018 0018 0018 0030 0018 +/// 0030 0018 0030 0018 0018 0018 0018 0018 0030 0018 0018 0018 0018 0018 +/// 0030 0018 0018 03f6" +/// @endcode +/// converts to: +/// @code{.cpp} +/// uint16_t prontoCode[46] = { +/// 0x0000, 0x0067, 0x0000, 0x0015, +/// 0x0060, 0x0018, 0x0018, 0x0018, 0x0030, 0x0018, 0x0030, 0x0018, +/// 0x0030, 0x0018, 0x0018, 0x0018, 0x0030, 0x0018, 0x0018, 0x0018, +/// 0x0018, 0x0018, 0x0030, 0x0018, 0x0018, 0x0018, 0x0030, 0x0018, +/// 0x0030, 0x0018, 0x0030, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, +/// 0x0030, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0030, 0x0018, +/// 0x0018, 0x03f6}; +/// // Send the Pronto(Sony) code. Repeat twice as Sony's require that. +/// sendPronto(prontoCode, 46, kSonyMinRepeat); +/// @endcode +/// @see http://www.etcwiki.org/wiki/Pronto_Infrared_Format +/// @see http://www.remotecentral.com/features/irdisp2.htm +void IRsend::sendPronto(uint16_t data[], uint16_t len, uint16_t repeat) { + // Check we have enough data to work out what to send. + if (len < kProntoMinLength) return; + + // We only know how to deal with 'raw' pronto codes types. Reject all others. + if (data[kProntoTypeOffset] != 0) return; + + // Pronto frequency is in Hz. + uint16_t hz = + (uint16_t)(1000000U / (data[kProntoFreqOffset] * kProntoFreqFactor)); + enableIROut(hz); + + // Grab the length of the two sequences. + uint16_t seq_1_len = data[kProntoSeq1LenOffset] * 2; + uint16_t seq_2_len = data[kProntoSeq2LenOffset] * 2; + // Calculate where each sequence starts in the buffer. + uint16_t seq_1_start = kProntoDataOffset; + uint16_t seq_2_start = kProntoDataOffset + seq_1_len; + + uint32_t periodic_time_x10 = calcUSecPeriod(hz / 10, false); + + // Normal (1st sequence) case. + // Is there a first (normal) sequence to send? + if (seq_1_len > 0) { + // Check we have enough data to send the complete first sequence. + if (seq_1_len + seq_1_start > len) return; + // Send the contents of the 1st sequence. + for (uint16_t i = seq_1_start; i < seq_1_start + seq_1_len; i += 2) { + mark((data[i] * periodic_time_x10) / 10); + space((data[i + 1] * periodic_time_x10) / 10); + } + } else { + // There was no first sequence to send, it is implied that we have to send + // the 2nd/repeat sequence an additional time. i.e. At least once. + repeat++; + } + + // Repeat (2nd sequence) case. + // Is there a second (repeat) sequence to be sent? + if (seq_2_len > 0) { + // Check we have enough data to send the complete second sequence. + if (seq_2_len + seq_2_start > len) return; + + // Send the contents of the 2nd sequence. + for (uint16_t r = 0; r < repeat; r++) + for (uint16_t i = seq_2_start; i < seq_2_start + seq_2_len; i += 2) { + mark((data[i] * periodic_time_x10) / 10); + space((data[i + 1] * periodic_time_x10) / 10); + } + } +} +#endif // SEND_PRONTO diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_RC5_RC6.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_RC5_RC6.cpp similarity index 59% rename from lib/IRremoteESP8266-2.7.5/src/ir_RC5_RC6.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_RC5_RC6.cpp index 370100f9e..cb00c5a67 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_RC5_RC6.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_RC5_RC6.cpp @@ -1,8 +1,22 @@ // Copyright 2009 Ken Shirriff // Copyright 2017 David Conran -// RC-5 & RC-6 support added from https://github.com/z3t0/Arduino-IRremote -// RC-5X support added by David Conran +/// @file +/// @brief RC-5 & RC-6 support +/// RC-5 & RC-6 support added from https://github.com/z3t0/Arduino-IRremote +/// RC-5X support added by David Conran +/// @see https://en.wikipedia.org/wiki/RC-5 +/// @see http://www.sbprojects.com/knowledge/ir/rc5.php +/// @see https://en.wikipedia.org/wiki/Manchester_code +/// @see https://en.wikipedia.org/wiki/RC-6 +/// @see https://www.sbprojects.net/knowledge/ir/rc6.php +/// @see http://www.pcbheaven.com/userpages/The_Philips_RC6_Protocol/ +/// @see http://www.righto.com/2010/12/64-bit-rc6-codes-arduino-and-xbox.html + +// Supports: +// Brand: Philips, Model: Standard RC-5 (RC5) +// Brand: Philips, Model: RC-5X (RC5X) +// Brand: Philips, Model: Standard RC-6 (RC6) #include #include "IRrecv.h" @@ -12,10 +26,6 @@ // Constants // RC-5/RC-5X -// Ref: -// https://en.wikipedia.org/wiki/RC-5 -// http://www.sbprojects.com/knowledge/ir/rc5.php - const uint16_t kRc5T1 = 889; const uint32_t kRc5MinCommandLength = 113778; const uint32_t kRc5MinGap = kRc5MinCommandLength - kRC5RawBits * (2 * kRc5T1); @@ -23,10 +33,6 @@ const uint16_t kRc5ToggleMask = 0x800; // The 12th bit. const uint16_t kRc5SamplesMin = 11; // RC-6 -// Ref: -// https://en.wikipedia.org/wiki/RC-6 -// http://www.pcbheaven.com/userpages/The_Philips_RC6_Protocol/ - const uint16_t kRc6Tick = 444; const uint16_t kRc6HdrMarkTicks = 6; const uint16_t kRc6HdrMark = kRc6HdrMarkTicks * kRc6Tick; @@ -42,27 +48,18 @@ const int16_t kMark = 0; const int16_t kSpace = 1; #if SEND_RC5 -// Send a Philips RC-5/RC-5X packet. -// -// Args: -// data: The message you wish to send. -// nbits: Bit size of the protocol you want to send. -// repeat: Nr. of extra times the data will be sent. -// -// Status: RC-5 (stable), RC-5X (alpha) -// -// Note: -// Caller needs to take care of flipping the toggle bit. -// That bit differentiates between key press & key release. -// For RC-5 it is the MSB of the data. -// For RC-5X it is the 2nd MSB of the data. -// Ref: -// http://www.sbprojects.com/knowledge/ir/rc5.php -// https://en.wikipedia.org/wiki/RC-5 -// https://en.wikipedia.org/wiki/Manchester_code -// TODO(anyone): -// Testing of the RC-5X components. -void IRsend::sendRC5(uint64_t data, uint16_t nbits, uint16_t repeat) { +/// Send a Philips RC-5/RC-5X packet. +/// Status: RC-5 (stable), RC-5X (alpha) +/// @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. +/// @note Caller needs to take care of flipping the toggle bit. +/// That bit differentiates between key press & key release. +/// For RC-5 it is the MSB of the data. +/// For RC-5X it is the 2nd MSB of the data. +/// @todo Testing of the RC-5X components. +void IRsend::sendRC5(const uint64_t data, uint16_t nbits, + const uint16_t repeat) { if (nbits > sizeof(data) * 8) return; // We can't send something that big. bool skipSpace = true; bool field_bit = true; @@ -109,44 +106,26 @@ void IRsend::sendRC5(uint64_t data, uint16_t nbits, uint16_t repeat) { } } -// Encode a Philips RC-5 data message. -// -// Args: -// address: The 5-bit address value for the message. -// command: The 6-bit command value for the message. -// key_released: Boolean flag indicating if the remote key has been released. -// -// Returns: -// A data message suitable for use in sendRC5(). -// -// Status: Beta / Should be working. -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/rc5.php -// https://en.wikipedia.org/wiki/RC-5 -uint16_t IRsend::encodeRC5(uint8_t address, uint8_t command, - bool key_released) { +/// Encode a Philips RC-5 data message. +/// Status: Beta / Should be working. +/// @param[in] address The 5-bit address value for the message. +/// @param[in] command The 6-bit command value for the message. +/// @param[in] key_released Indicate if the remote key has been released. +/// @return A message suitable for use in sendRC5(). +uint16_t IRsend::encodeRC5(const uint8_t address, const uint8_t command, + const bool key_released) { return (key_released << (kRC5Bits - 1)) | ((address & 0x1f) << 6) | (command & 0x3F); } -// Encode a Philips RC-5X data message. -// -// Args: -// address: The 5-bit address value for the message. -// command: The 7-bit command value for the message. -// key_released: Boolean flag indicating if the remote key has been released. -// -// Returns: -// A data message suitable for use in sendRC5(). -// -// Status: Beta / Should be working. -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/rc5.php -// https://en.wikipedia.org/wiki/RC-5 -uint16_t IRsend::encodeRC5X(uint8_t address, uint8_t command, - bool key_released) { +/// Encode a Philips RC-5X data message. +/// Status: Beta / Should be working. +/// @param[in] address The 5-bit address value for the message. +/// @param[in] command The 7-bit command value for the message. +/// @param[in] key_released Indicate if the remote key has been released. +/// @return A message suitable for use in sendRC5(). +uint16_t IRsend::encodeRC5X(const uint8_t address, const uint8_t command, + const bool key_released) { // The 2nd start/field bit (MSB of the return value) is the value of the 7th // command bit. bool s2 = (command >> 6) & 1; @@ -154,64 +133,43 @@ uint16_t IRsend::encodeRC5X(uint8_t address, uint8_t command, encodeRC5(address, command, key_released); } -// Flip the toggle bit of a Philips RC-5/RC-5X data message. -// Used to indicate a change of remote button's state. -// -// Args: -// data: The existing RC-5/RC-5X message. -// -// Returns: -// A data message suitable for use in sendRC5() with the toggle bit flipped. -// -// Status: STABLE. -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/rc5.php -// https://en.wikipedia.org/wiki/RC-5 -uint64_t IRsend::toggleRC5(uint64_t data) { return data ^ kRc5ToggleMask; } +/// Flip the toggle bit of a Philips RC-5/RC-5X data message. +/// Used to indicate a change of remote button's state. +/// Status: STABLE. +/// @param[in] data The existing RC-5/RC-5X message. +/// @return A data message suitable for use in sendRC5() with the toggle bit +/// flipped. +uint64_t IRsend::toggleRC5(const uint64_t data) { + return data ^ kRc5ToggleMask; +} #endif // SEND_RC5 #if SEND_RC6 -// Flip the toggle bit of a Philips RC-6 data message. -// Used to indicate a change of remote button's state. -// For RC-6 (20-bits), it is the 17th least significant bit. -// for RC-6 (36-bits/Xbox-360), it is the 16th least significant bit. -// -// Args: -// data: The existing RC-6 message. -// nbits: Nr. of bits in the RC-6 protocol. -// -// Returns: -// A data message suitable for use in sendRC6() with the toggle bit flipped. -// -// Status: STABLE / Should work fine. -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/rc6.php -// http://www.righto.com/2010/12/64-bit-rc6-codes-arduino-and-xbox.html -uint64_t IRsend::toggleRC6(uint64_t data, uint16_t nbits) { +/// Flip the toggle bit of a Philips RC-6 data message. +/// Used to indicate a change of remote button's state. +/// Status: STABLE / Should work fine. +/// @param[in] data The existing RC-6 message. +/// @param [in] nbits Nr. of bits in the RC-6 protocol. +/// @return A data message suitable for use in sendRC6() with the toggle bit +/// flipped. +/// @note For RC-6 (20-bits), it is the 17th least significant bit. +/// @note For RC-6 (36-bits/Xbox-360), it is the 16th least significant bit. +uint64_t IRsend::toggleRC6(const uint64_t data, const uint16_t nbits) { if (nbits == kRC6_36Bits) return data ^ kRc6_36ToggleMask; return data ^ kRc6ToggleMask; } -// Encode a Philips RC-6 data message. -// -// Args: -// address: The address (aka. control) value for the message. -// Includes the field/mode/toggle bits. -// command: The 8-bit command value for the message. (aka. information) -// mode: Which protocol to use. Defined by nr. of bits in the protocol. -// -// Returns: -// A data message suitable for use in sendRC6(). -// -// Status: Beta / Should be working. -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/rc6.php -// http://www.righto.com/2010/12/64-bit-rc6-codes-arduino-and-xbox.html -// http://www.pcbheaven.com/userpages/The_Philips_RC6_Protocol/ -uint64_t IRsend::encodeRC6(uint32_t address, uint8_t command, uint16_t mode) { +/// Encode a Philips RC-6 data message. +/// Status: Beta / Should be working. +/// @param[in] address The address (aka. control) value for the message. +/// Includes the field/mode/toggle bits. +/// @param[in] command The 8-bit command value for the message. +/// (aka. information) +/// @param[in] mode Which protocol to use. +/// Defined by nr. of bits in the protocol. +/// @return A data message suitable for use in `sendRC6()`. +uint64_t IRsend::encodeRC6(const uint32_t address, const uint8_t command, + const uint16_t mode) { switch (mode) { case kRC6Mode0Bits: return ((address & 0xFFF) << 8) | (command & 0xFF); @@ -222,22 +180,15 @@ uint64_t IRsend::encodeRC6(uint32_t address, uint8_t command, uint16_t mode) { } } -// Send a Philips RC-6 packet. -// Note: Caller needs to take care of flipping the toggle bit (The 4th Most -// Significant Bit). That bit differentiates between key press & key release. -// -// Args: -// data: The message you wish to send. -// nbits: Bit size of the protocol you want to send. -// repeat: Nr. of extra times the data will be sent. -// -// Status: Stable. -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/rc6.php -// http://www.righto.com/2010/12/64-bit-rc6-codes-arduino-and-xbox.html -// https://en.wikipedia.org/wiki/Manchester_code -void IRsend::sendRC6(uint64_t data, uint16_t nbits, uint16_t repeat) { +/// Send a Philips RC-6 packet. +/// Status: Stable. +/// @note Caller needs to take care of flipping the toggle bit (The 4th Most +/// Significant Bit). That bit differentiates between key press & key release. +/// @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::sendRC6(const uint64_t data, const uint16_t nbits, + const uint16_t repeat) { // Check we can send the number of bits requested. if (nbits > sizeof(data) * 8) return; // Set 36kHz IR carrier frequency & a 1/3 (33%) duty cycle. @@ -271,27 +222,28 @@ void IRsend::sendRC6(uint64_t data, uint16_t nbits, uint16_t repeat) { #endif // SEND_RC6 #if (DECODE_RC5 || DECODE_RC6 || DECODE_LASERTAG) -// Gets one undecoded level at a time from the raw buffer. -// The RC5/6 decoding is easier if the data is broken into time intervals. -// E.g. if the buffer has MARK for 2 time intervals and SPACE for 1, -// successive calls to getRClevel will return MARK, MARK, SPACE. -// offset and used are updated to keep track of the current position. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: Ptr to the currect offset to the rawbuf. -// used: Ptr to the current used counter. -// bitTime: Time interval of single bit in microseconds. -// maxwidth: Maximum number of successive levels to find in a single level -// (default 3) -// Returns: -// int: MARK, SPACE, or -1 for error (The measured time interval is not a -// multiple of t1.) -// Ref: -// https://en.wikipedia.org/wiki/Manchester_code +/// Gets one undecoded level at a time from the raw buffer. +/// The RC5/6 decoding is easier if the data is broken into time intervals. +/// E.g. if the buffer has MARK for 2 time intervals and SPACE for 1, +/// successive calls to getRClevel will return MARK, MARK, SPACE. +/// offset and used are updated to keep track of the current position. +/// @param[in,out] results Ptr to the data to decode and where to store the +/// decode result. +/// @param[in,out] offset Ptr to the currect offset to the rawbuf. +/// @param[in,out] used Ptr to the current used counter. +/// @param[in] bitTime Time interval of single bit in microseconds. +/// @param[in] tolerance Percent tolerance to be used in matching. +/// @param[in] excess Extra useconds to add to Marks & removed from Spaces. +/// @param[in] delta A non-scaling (+/-) error margin (in useconds). +/// @param[in] maxwidth Maximum number of successive levels to find in a single +/// level (default is 3) +/// @return MARK, SPACE, or -1 for error. +/// (The measured time interval is not a multiple of t1.) +/// @see https://en.wikipedia.org/wiki/Manchester_code int16_t IRrecv::getRClevel(decode_results *results, uint16_t *offset, - uint16_t *used, uint16_t bitTime, uint8_t tolerance, - int16_t excess, uint16_t delta, uint8_t maxwidth) { + uint16_t *used, const uint16_t bitTime, + const uint8_t tolerance, const int16_t excess, + const uint16_t delta, const uint8_t maxwidth) { DPRINT("DEBUG: getRClevel: offset = "); DPRINTLN(uint64ToString(*offset)); DPRINT("DEBUG: getRClevel: rawlen = "); @@ -343,28 +295,17 @@ int16_t IRrecv::getRClevel(decode_results *results, uint16_t *offset, #endif // (DECODE_RC5 || DECODE_RC6 || DECODE_LASERTAG) #if DECODE_RC5 -// Decode the supplied RC-5/RC5X message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: RC-5 (stable), RC-5X (alpha) -// -// Note: -// The 'toggle' bit is included as the 6th (MSB) address bit, the MSB of data, -// & in the count of bits decoded. -// Ref: -// http://www.sbprojects.com/knowledge/ir/rc5.php -// https://en.wikipedia.org/wiki/RC-5 -// https://en.wikipedia.org/wiki/Manchester_code -// TODO(anyone): -// Serious testing of the RC-5X and strict aspects needs to be done. +/// Decode the supplied RC-5/RC5X message. +/// Status: RC-5 (stable), RC-5X (alpha) +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @note The 'toggle' bit is included as the 6th (MSB) address bit, the MSB of +/// data, & in the count of bits decoded. +/// @todo Serious testing of the RC-5X and strict aspects needs to be done. bool IRrecv::decodeRC5(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen <= kRc5SamplesMin + kHeader - 1 + offset) return false; @@ -430,24 +371,15 @@ bool IRrecv::decodeRC5(decode_results *results, uint16_t offset, #endif // DECODE_RC5 #if DECODE_RC6 -// Decode the supplied RC6 message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: Stable. -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/rc6.php -// https://en.wikipedia.org/wiki/Manchester_code -// TODO(anyone): -// Testing of the strict compliance aspects. +/// Decode the supplied RC6 message. +/// Status: Stable. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @todo Testing of the strict compliance aspects. bool IRrecv::decodeRC6(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen <= kHeader + 2 + 4 + offset) diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_RCMM.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_RCMM.cpp similarity index 80% rename from lib/IRremoteESP8266-2.7.5/src/ir_RCMM.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_RCMM.cpp index ea0e05e9d..023b82517 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_RCMM.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_RCMM.cpp @@ -1,6 +1,8 @@ // Copyright 2017 David Conran -// Send & decode support for Phillips RC-MM added by David Conran +/// @file +/// @brief Support for the Phillips RC-MM protocol. +/// @see http://www.sbprojects.com/knowledge/ir/rcmm.php // Supports: // Brand: Microsoft, Model: XBOX 360 @@ -12,8 +14,6 @@ #include "IRutils.h" // Constants -// Ref: -// http://www.sbprojects.com/knowledge/ir/rcmm.php const uint16_t kRcmmTick = 28; // Technically it would be 27.777* const uint16_t kRcmmHdrMarkTicks = 15; const uint16_t kRcmmHdrMark = 416; @@ -38,17 +38,11 @@ const uint8_t kRcmmTolerance = 10; const uint16_t kRcmmExcess = 50; #if SEND_RCMM -// Send a Philips RC-MM packet. -// -// Args: -// data: The data we want to send. MSB first. -// nbits: The number of bits of data to send. (Typically 12, 24, or 32[Nokia]) -// repeat: The nr. of times the message should be sent. -// -// Status: STABLE / Should be working. -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/rcmm.php +/// Send a Philips RC-MM packet. +/// Status: STABLE / Should be working. +/// @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::sendRCMM(uint64_t data, uint16_t nbits, uint16_t repeat) { // Set 36kHz IR carrier frequency & a 1/3 (33%) duty cycle. enableIROut(36, 33); @@ -88,24 +82,17 @@ void IRsend::sendRCMM(uint64_t data, uint16_t nbits, uint16_t repeat) { space(std::max(kRcmmRptLength - usecs.elapsed(), kRcmmMinGap)); } } -#endif +#endif // SEND_RCMM #if DECODE_RCMM -// Decode a Philips RC-MM packet (between 12 & 32 bits) if possible. -// Places successful decode information in the results pointer. -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits to expect in the data portion. Typically kRCMMBits. -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Should be working. -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/rcmm.php +/// Decode a Philips RC-MM packet (between 12 & 32 bits) if possible. +/// Status: STABLE / Should be working. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. bool IRrecv::decodeRCMM(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { uint64_t data = 0; @@ -174,4 +161,4 @@ bool IRrecv::decodeRCMM(decode_results *results, uint16_t offset, results->command = 0; return true; } -#endif +#endif // DECODE_RCMM diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Samsung.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Samsung.cpp similarity index 70% rename from lib/IRremoteESP8266-2.7.5/src/ir_Samsung.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Samsung.cpp index 78b36e146..02aa4abdd 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Samsung.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Samsung.cpp @@ -1,7 +1,12 @@ // Copyright 2009 Ken Shirriff // Copyright 2017, 2018, 2019 David Conran - -// Samsung remote emulation +/// @file +/// @brief Support for Samsung protocols. +/// Samsung originally added from https://github.com/shirriff/Arduino-IRremote/ +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/505 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/621 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1062 +/// @see http://elektrolab.wz.cz/katalog/samsung_protocol.pdf #include "ir_Samsung.h" #include @@ -14,11 +19,7 @@ #include "IRtext.h" #include "IRutils.h" -// Samsung originally added from https://github.com/shirriff/Arduino-IRremote/ - // Constants -// Ref: -// http://elektrolab.wz.cz/katalog/samsung_protocol.pdf const uint16_t kSamsungTick = 560; const uint16_t kSamsungHdrMarkTicks = 8; const uint16_t kSamsungHdrMark = kSamsungHdrMarkTicks * kSamsungTick; @@ -62,19 +63,15 @@ using irutils::setBit; using irutils::setBits; #if SEND_SAMSUNG -// Send a Samsung formatted message. -// Samsung has a separate message to indicate a repeat, like NEC does. -// TODO(crankyoldgit): Confirm that is actually how Samsung sends a repeat. -// The refdoc doesn't indicate it is true. -// -// Args: -// data: The message to be sent. -// nbits: The bit size of the message being sent. typically kSamsungBits. -// repeat: The number of times the message is to be repeated. -// -// Status: STABLE / Should be working. -// -// Ref: http://elektrolab.wz.cz/katalog/samsung_protocol.pdf +/// Send a 32-bit Samsung formatted message. +/// Status: STABLE / Should be working. +/// @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. +/// @see http://elektrolab.wz.cz/katalog/samsung_protocol.pdf +/// @note Samsung has a separate message to indicate a repeat, like NEC does. +/// @todo Confirm that is actually how Samsung sends a repeat. +/// The refdoc doesn't indicate it is true. void IRsend::sendSAMSUNG(const uint64_t data, const uint16_t nbits, const uint16_t repeat) { sendGeneric(kSamsungHdrMark, kSamsungHdrSpace, kSamsungBitMark, @@ -83,16 +80,12 @@ void IRsend::sendSAMSUNG(const uint64_t data, const uint16_t nbits, nbits, 38, true, repeat, 33); } -// Construct a raw Samsung message from the supplied customer(address) & -// command. -// -// Args: -// customer: The customer code. (aka. Address) -// command: The command code. -// Returns: -// A raw 32-bit Samsung message suitable for sendSAMSUNG(). -// -// Status: STABLE / Should be working. +/// Construct a raw Samsung message from the supplied customer(address) & +/// command. +/// Status: STABLE / Should be working. +/// @param[in] customer The customer code. (aka. Address) +/// @param[in] command The command code. +/// @return A raw 32-bit Samsung message suitable for `sendSAMSUNG()`. uint32_t IRsend::encodeSAMSUNG(const uint8_t customer, const uint8_t command) { uint8_t revcustomer = reverseBits(customer, sizeof(customer) * 8); uint8_t revcommand = reverseBits(command, sizeof(command) * 8); @@ -102,27 +95,20 @@ uint32_t IRsend::encodeSAMSUNG(const uint8_t customer, const uint8_t command) { #endif #if DECODE_SAMSUNG -// Decode the supplied Samsung message. -// Samsung messages whilst 32 bits in size, only contain 16 bits of distinct -// data. e.g. In transmition order: -// customer_byte + customer_byte(same) + address_byte + invert(address_byte) -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits to expect in the data portion. Typically kSamsungBits. -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE -// -// Note: -// LG 32bit protocol appears near identical to the Samsung protocol. -// They differ on their compliance criteria and how they repeat. -// Ref: -// http://elektrolab.wz.cz/katalog/samsung_protocol.pdf +/// Decode the supplied Samsung 32-bit message. +/// Status: STABLE +/// @note Samsung messages whilst 32 bits in size, only contain 16 bits of +/// distinct data. e.g. In transmition order: +/// customer_byte + customer_byte(same) + address_byte + invert(address_byte) +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @note LG 32bit protocol appears near identical to the Samsung protocol. +/// They differ on their compliance criteria and how they repeat. +/// @see http://elektrolab.wz.cz/katalog/samsung_protocol.pdf bool IRrecv::decodeSAMSUNG(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (strict && nbits != kSamsungBits) @@ -159,20 +145,12 @@ bool IRrecv::decodeSAMSUNG(decode_results *results, uint16_t offset, #endif #if SEND_SAMSUNG36 -// Send a Samsung 36-bit formatted message. -// -// Args: -// data: The message to be sent. -// nbits: The bit size of the message being sent. typically kSamsung36Bits. -// repeat: The number of times the message is to be repeated. -// -// Status: Alpha / Experimental. -// -// Note: -// Protocol is used by Samsung Bluray Remote: ak59-00167a -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/621 +/// Send a Samsung 36-bit formatted message. +/// Status: Alpha / Experimental. +/// @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. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/621 void IRsend::sendSamsung36(const uint64_t data, const uint16_t nbits, const uint16_t repeat) { if (nbits < 16) return; // To small to send. @@ -196,25 +174,15 @@ void IRsend::sendSamsung36(const uint64_t data, const uint16_t nbits, #endif // SEND_SAMSUNG36 #if DECODE_SAMSUNG36 -// Decode the supplied Samsung36 message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of bits to expect in the data portion. -// Typically kSamsung36Bits. -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: Alpha / Experimental -// -// Note: -// Protocol is used by Samsung Bluray Remote: ak59-00167a -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/621 +/// Decode the supplied Samsung36 message. +/// Status: Alpha / Experimental +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/621 bool IRrecv::decodeSamsung36(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen < 2 * nbits + kHeader + kFooter * 2 - 1 + offset) @@ -258,17 +226,12 @@ bool IRrecv::decodeSamsung36(decode_results *results, uint16_t offset, #endif // DECODE_SAMSUNG36 #if SEND_SAMSUNG_AC -// Send a Samsung A/C message. -// -// Args: -// data: An array of bytes containing the IR command. -// nbytes: Nr. of bytes of data in the array. (>=kSamsungAcStateLength) -// repeat: Nr. of times the message is to be repeated. (Default = 0). -// -// Status: Stable / Known working. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/505 +/// Send a Samsung A/C message. +/// Status: Stable / Known working. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/505 +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendSamsungAC(const uint8_t data[], const uint16_t nbytes, const uint16_t repeat) { if (nbytes < kSamsungAcStateLength && nbytes % kSamsungAcSectionLength) @@ -294,16 +257,20 @@ void IRsend::sendSamsungAC(const uint8_t data[], const uint16_t nbytes, } #endif // SEND_SAMSUNG_AC +/// 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? IRSamsungAc::IRSamsungAc(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { this->stateReset(); } -// Reset the internal state of the emulation. -// Args: -// forcepower: A flag indicating if force sending a special power message -// with the first `send()` call. Default: true +/// Reset the internal state of the emulation. +/// @param[in] forcepower A flag indicating if force sending a special power +/// message with the first `send()` call. +/// @param[in] initialPower Set the initial power state. True, on. False, off. void IRSamsungAc::stateReset(const bool forcepower, const bool initialPower) { static const uint8_t kReset[kSamsungAcExtendedStateLength] = { 0x02, 0x92, 0x0F, 0x00, 0x00, 0x00, 0xF0, 0x01, 0x02, 0xAE, 0x71, 0x00, @@ -314,8 +281,13 @@ void IRSamsungAc::stateReset(const bool forcepower, const bool initialPower) { setPower(initialPower); } +/// Set up hardware to be able to send a message. void IRSamsungAc::begin(void) { _irsend.begin(); } +/// Calculate the checksum for a given state. +/// @param[in] state The array to calc the checksum of. +/// @param[in] length The length/size of the array. +/// @return The calculated checksum value. uint8_t IRSamsungAc::calcChecksum(const uint8_t state[], const uint16_t length) { uint8_t sum = 0; @@ -331,6 +303,10 @@ uint8_t IRSamsungAc::calcChecksum(const uint8_t state[], return GETBITS8(28 - sum, kLowNibble, kNibbleSize); } +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length/size of the array. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRSamsungAc::validChecksum(const uint8_t state[], const uint16_t length) { if (length < kSamsungAcStateLength) return true; // No checksum to compare with. Assume okay. @@ -342,7 +318,8 @@ bool IRSamsungAc::validChecksum(const uint8_t state[], const uint16_t length) { IRSamsungAc::calcChecksum(state, length - (7 + offset))); } -// Update the checksum for the internal state. +/// Update the checksum for the internal state. +/// @param[in] length The length/size of the internal array to checksum. void IRSamsungAc::checksum(uint16_t length) { if (length < 13) return; setBits(&remote_state[length - 6], kHighNibble, kNibbleSize, @@ -352,8 +329,11 @@ void IRSamsungAc::checksum(uint16_t length) { } #if SEND_SAMSUNG_AC -// Use for most function/mode/settings changes to the unit. -// i.e. When the device is already running. +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. +/// @param[in] calcchecksum Do we update the checksum before sending? +/// @note Use for most function/mode/settings changes to the unit. +/// i.e. When the device is already running. void IRSamsungAc::send(const uint16_t repeat, const bool calcchecksum) { if (calcchecksum) this->checksum(); // Do we need to send a the special power on/off message? @@ -369,9 +349,12 @@ void IRSamsungAc::send(const uint16_t repeat, const bool calcchecksum) { _irsend.sendSamsungAC(remote_state, kSamsungAcStateLength, repeat); } -// Use this for when you need to power on/off the device. -// Samsung A/C requires an extended length message when you want to -// change the power operating mode of the A/C unit. +/// Send the extended current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. +/// @param[in] calcchecksum Do we update the checksum before sending? +/// @note Use this for when you need to power on/off the device. +/// Samsung A/C requires an extended length message when you want to +/// change the power operating mode of the A/C unit. void IRSamsungAc::sendExtended(const uint16_t repeat, const bool calcchecksum) { if (calcchecksum) this->checksum(); uint8_t extended_state[kSamsungAcExtendedStateLength] = { @@ -389,9 +372,10 @@ void IRSamsungAc::sendExtended(const uint16_t repeat, const bool calcchecksum) { _irsend.sendSamsungAC(extended_state, kSamsungAcExtendedStateLength, repeat); } -// Send the special extended "On" message as the library can't seem to reproduce -// this message automatically. -// See: https://github.com/crankyoldgit/IRremoteESP8266/issues/604#issuecomment-475020036 +/// Send the special extended "On" message as the library can't seem to +/// reproduce this message automatically. +/// @param[in] repeat Nr. of times the message will be repeated. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/604#issuecomment-475020036 void IRSamsungAc::sendOn(const uint16_t repeat) { const uint8_t extended_state[21] = { 0x02, 0x92, 0x0F, 0x00, 0x00, 0x00, 0xF0, @@ -401,9 +385,10 @@ void IRSamsungAc::sendOn(const uint16_t repeat) { _lastsentpowerstate = true; // On } -// Send the special extended "Off" message as the library can't seem to -// reproduce this message automatically. -// See: https://github.com/crankyoldgit/IRremoteESP8266/issues/604#issuecomment-475020036 +/// Send the special extended "Off" message as the library can't seem to +/// reproduce this message automatically. +/// @param[in] repeat Nr. of times the message will be repeated. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/604#issuecomment-475020036 void IRSamsungAc::sendOff(const uint16_t repeat) { const uint8_t extended_state[21] = { 0x02, 0xB2, 0x0F, 0x00, 0x00, 0x00, 0xC0, @@ -414,11 +399,16 @@ void IRSamsungAc::sendOff(const uint16_t repeat) { } #endif // SEND_SAMSUNG_AC +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t *IRSamsungAc::getRaw(void) { this->checksum(); return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. +/// @param[in] length The length/size of the new_code array. void IRSamsungAc::setRaw(const uint8_t new_code[], const uint16_t length) { memcpy(remote_state, new_code, std::min(length, kSamsungAcExtendedStateLength)); @@ -429,23 +419,30 @@ void IRSamsungAc::setRaw(const uint8_t new_code[], const uint16_t length) { } } +/// Set the requested power state of the A/C to on. void IRSamsungAc::on(void) { setPower(true); } +/// Set the requested power state of the A/C to off. void IRSamsungAc::off(void) { setPower(false); } +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRSamsungAc::setPower(const bool on) { setBit(&remote_state[1], kSamsungAcPower1Offset, !on); // Cleared when on. setBits(&remote_state[6], kSamsungAcPower6Offset, kSamsungAcPower6Size, on ? 0b11 : 0b00); } +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRSamsungAc::getPower(void) { return (GETBITS8(remote_state[6], kSamsungAcPower6Offset, kSamsungAcPower6Size) == 0b11) && !GETBIT8(remote_state[1], kSamsungAcPower1Offset); } -// Set the temp. in deg C +/// Set the temperature. +/// @param[in] temp The temperature in degrees celsius. void IRSamsungAc::setTemp(const uint8_t temp) { uint8_t newtemp = std::max(kSamsungAcMinTemp, temp); newtemp = std::min(kSamsungAcMaxTemp, newtemp); @@ -453,12 +450,15 @@ void IRSamsungAc::setTemp(const uint8_t temp) { newtemp - kSamsungAcMinTemp); } -// Return the set temp. in deg C +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRSamsungAc::getTemp(void) { return GETBITS8(remote_state[11], kHighNibble, kNibbleSize) + kSamsungAcMinTemp; } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRSamsungAc::setMode(const uint8_t mode) { // If we get an unexpected mode, default to AUTO. uint8_t newmode = mode; @@ -475,10 +475,14 @@ void IRSamsungAc::setMode(const uint8_t mode) { } } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRSamsungAc::getMode(void) { return GETBITS8(remote_state[12], kSamsungAcModeOffset, kModeBitsSize); } +/// Set the speed of the fan. +/// @param[in] speed The desired setting. void IRSamsungAc::setFan(const uint8_t speed) { switch (speed) { case kSamsungAcFanAuto: @@ -497,47 +501,65 @@ void IRSamsungAc::setFan(const uint8_t speed) { setBits(&remote_state[12], kSamsungAcFanOffest, kSamsungAcFanSize, speed); } +/// Get the current fan speed setting. +/// @return The current fan speed/mode. uint8_t IRSamsungAc::getFan(void) { return GETBITS8(remote_state[12], kSamsungAcFanOffest, kSamsungAcFanSize); } +/// Get the vertical swing setting of the A/C. +/// @return true, the setting is on. false, the setting is off. +/// @todo (Hollako) Explain why sometimes the LSB of remote_state[9] is a 1. +/// e.g. 0xAE or 0XAF for swing move. bool IRSamsungAc::getSwing(void) { - // TODO(Hollako): Explain why sometimes the LSB of remote_state[9] is a 1. - // e.g. 0xAE or 0XAF for swing move. return GETBITS8(remote_state[9], kSamsungAcSwingOffset, kSamsungAcSwingSize) == kSamsungAcSwingMove; } +/// Set the vertical swing setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. +/// @todo (Hollako) Explain why sometimes the LSB of remote_state[9] is a 1. +/// e.g. 0xAE or 0XAF for swing move. void IRSamsungAc::setSwing(const bool on) { - // TODO(Hollako): Explain why sometimes the LSB of remote_state[9] is a 1. - // e.g. 0xAE or 0XAF for swing move. setBits(&remote_state[9], kSamsungAcSwingOffset, kSamsungAcSwingSize, on ? kSamsungAcSwingMove : kSamsungAcSwingStop); } +/// Get the Beep setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRSamsungAc::getBeep(void) { return GETBIT8(remote_state[13], kSamsungAcBeepOffset); } +/// Set the Beep setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRSamsungAc::setBeep(const bool on) { setBit(&remote_state[13], kSamsungAcBeepOffset, on); } +/// Get the Clean setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRSamsungAc::getClean(void) { return GETBIT8(remote_state[10], kSamsungAcClean10Offset) && GETBIT8(remote_state[11], kSamsungAcClean11Offset); } +/// Set the Clean setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRSamsungAc::setClean(const bool on) { setBit(&remote_state[10], kSamsungAcClean10Offset, on); setBit(&remote_state[11], kSamsungAcClean11Offset, on); } +/// Get the Quiet setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRSamsungAc::getQuiet(void) { return !GETBIT8(remote_state[1], kSamsungAcQuiet1Offset) && GETBIT8(remote_state[5], kSamsungAcQuiet5Offset); } +/// Set the Quiet setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRSamsungAc::setQuiet(const bool on) { setBit(&remote_state[1], kSamsungAcQuiet1Offset, !on); // Cleared when on. setBit(&remote_state[5], kSamsungAcQuiet5Offset, on); @@ -548,6 +570,8 @@ void IRSamsungAc::setQuiet(const bool on) { } } +/// Get the Powerful (Turbo) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRSamsungAc::getPowerful(void) { return !(remote_state[8] & kSamsungAcPowerfulMask8) && (GETBITS8(remote_state[10], kSamsungAcPowerful10Offset, @@ -555,6 +579,8 @@ bool IRSamsungAc::getPowerful(void) { (this->getFan() == kSamsungAcFanTurbo); } +/// Set the Powerful (Turbo) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRSamsungAc::setPowerful(const bool on) { uint8_t off_value = this->getBreeze() ? kSamsungAcBreezeOn : 0b000; setBits(&remote_state[10], kSamsungAcPowerful10Offset, @@ -571,16 +597,18 @@ void IRSamsungAc::setPowerful(const bool on) { } } -// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1062 -// Are the vanes closed over the fan outlet, to stop direct wind? Aka. WindFree +/// Are the vanes closed over the fan outlet, to stop direct wind? Aka. WindFree +/// @return true, the setting is on. false, the setting is off. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1062 bool IRSamsungAc::getBreeze(void) { return (GETBITS8(remote_state[10], kSamsungAcBreezeOffset, kSamsungAcBreezeSize) == kSamsungAcBreezeOn) && (this->getFan() == kSamsungAcFanAuto && !getSwing()); } -// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1062 -// Closes the vanes over the fan outlet, to stop direct wind. Aka. WindFree +/// Closes the vanes over the fan outlet, to stop direct wind. Aka. WindFree +/// @param[in] on true, the setting is on. false, the setting is off. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1062 void IRSamsungAc::setBreeze(const bool on) { uint8_t off_value = this->getPowerful() ? kSamsungAcPowerful10On : 0b000; setBits(&remote_state[10], kSamsungAcBreezeOffset, @@ -591,23 +619,33 @@ void IRSamsungAc::setBreeze(const bool on) { } } +/// Get the Display (Light/LED) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRSamsungAc::getDisplay(void) { return GETBIT8(remote_state[10], kSamsungAcDisplayOffset); } +/// Set the Display (Light/LED) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRSamsungAc::setDisplay(const bool on) { setBit(&remote_state[10], kSamsungAcDisplayOffset, on); } +/// Get the Ion (Filter) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRSamsungAc::getIon(void) { return GETBIT8(remote_state[11], kSamsungAcIonOffset); } +/// Set the Ion (Filter) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRSamsungAc::setIon(const bool on) { setBit(&remote_state[11], kSamsungAcIonOffset, on); } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRSamsungAc::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kSamsungAcCool; @@ -618,7 +656,9 @@ uint8_t IRSamsungAc::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRSamsungAc::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: @@ -630,7 +670,9 @@ uint8_t IRSamsungAc::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRSamsungAc::toCommonMode(const uint8_t mode) { switch (mode) { case kSamsungAcCool: return stdAc::opmode_t::kCool; @@ -641,7 +683,9 @@ stdAc::opmode_t IRSamsungAc::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] spd The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRSamsungAc::toCommonFanSpeed(const uint8_t spd) { switch (spd) { case kSamsungAcFanTurbo: return stdAc::fanspeed_t::kMax; @@ -652,7 +696,8 @@ stdAc::fanspeed_t IRSamsungAc::toCommonFanSpeed(const uint8_t spd) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRSamsungAc::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::SAMSUNG_AC; @@ -678,7 +723,8 @@ stdAc::state_t IRSamsungAc::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRSamsungAc::toString(void) { String result = ""; result.reserve(115); // Reserve some heap for the string to reduce fragging. @@ -723,21 +769,15 @@ String IRSamsungAc::toString(void) { } #if DECODE_SAMSUNG_AC -// Decode the supplied Samsung A/C message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kSamsungAcBits -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: Stable / Known to be working. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/505 +/// Decode the supplied Samsung A/C message. +/// Status: Stable / Known to be working. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/505 bool IRrecv::decodeSamsungAC(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen < 2 * nbits + kHeader * 3 + kFooter * 2 - 1 + offset) diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Samsung.h b/lib/IRremoteESP8266-2.7.8/src/ir_Samsung.h similarity index 75% rename from lib/IRremoteESP8266-2.7.5/src/ir_Samsung.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Samsung.h index 31b5ea181..fa6f9f2f3 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Samsung.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Samsung.h @@ -1,6 +1,23 @@ -// Samsung A/C -// // Copyright 2018 David Conran +/// @file +/// @brief Support for Samsung protocols. +/// Samsung originally added from https://github.com/shirriff/Arduino-IRremote/ +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/505 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/621 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1062 +/// @see http://elektrolab.wz.cz/katalog/samsung_protocol.pdf + +// Supports: +// Brand: Samsung, Model: UA55H6300 TV (SAMSUNG) +// Brand: Samsung, Model: BN59-01178B TV remote (SAMSUNG) +// Brand: Samsung, Model: DB63-03556X003 remote +// Brand: Samsung, Model: DB93-16761C remote +// Brand: Samsung, Model: IEC-R03 remote +// Brand: Samsung, Model: AK59-00167A Bluray remote (SAMSUNG36) +// Brand: Samsung, Model: AR09FSSDAWKNFA A/C (SAMSUNG_AC) +// Brand: Samsung, Model: AR12KSFPEWQNET A/C (SAMSUNG_AC) +// Brand: Samsung, Model: AR12HSSDBWKNEU A/C (SAMSUNG_AC) +// Brand: Samsung, Model: AR12NXCXAWKXEU A/C (SAMSUNG_AC) #ifndef IR_SAMSUNG_H_ #define IR_SAMSUNG_H_ @@ -16,21 +33,9 @@ #include "IRsend_test.h" #endif -// Supports: -// Brand: Samsung, Model: UA55H6300 TV -// Brand: Samsung, Model: DB63-03556X003 remote -// Brand: Samsung, Model: DB93-16761C remote -// Brand: Samsung, Model: IEC-R03 remote -// Brand: Samsung, Model: AR09FSSDAWKNFA A/C -// Brand: Samsung, Model: AR12KSFPEWQNET A/C -// Brand: Samsung, Model: AR12HSSDBWKNEU A/C -// Brand: Samsung, Model: AR12NXCXAWKXEU A/C - -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/505 -// https://github.com/crankyoldgit/IRremoteESP8266/issues/1062 - // Constants + +// SamsungAc // Byte[1] // Checksum 0b11110000 ??? const uint8_t kSamsungAcPower1Offset = 5; // Mask 0b00100000 @@ -86,11 +91,11 @@ const uint16_t kSamsungAcSectionLength = 7; const uint64_t kSamsungAcPowerSection = 0x1D20F00000000; // Classes +/// Class for handling detailed Samsung A/C messages. class IRSamsungAc { public: explicit IRSamsungAc(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - void stateReset(const bool forcepower = true, const bool initialPower = true); #if SEND_SAMSUNG_AC void send(const uint16_t repeat = kSamsungAcDefaultRepeat, @@ -99,7 +104,11 @@ class IRSamsungAc { const bool calcchecksum = true); void sendOn(const uint16_t repeat = kSamsungAcDefaultRepeat); void sendOff(const uint16_t repeat = kSamsungAcDefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + /// 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_SAMSUNG_AC void begin(void); void on(void); @@ -128,7 +137,6 @@ class IRSamsungAc { bool getDisplay(void); void setIon(const bool on); bool getIon(void); - uint8_t* getRaw(void); void setRaw(const uint8_t new_code[], const uint16_t length = kSamsungAcStateLength); @@ -145,13 +153,14 @@ class IRSamsungAc { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - // The state of the IR remote in IR code form. - uint8_t remote_state[kSamsungAcExtendedStateLength]; - bool _forcepower; // Hack to know when we need to send a special power mesg. + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint8_t remote_state[kSamsungAcExtendedStateLength]; ///< State in code form. + bool _forcepower; ///< Hack to know when we need to send a special power mesg bool _lastsentpowerstate; void checksum(const uint16_t length = kSamsungAcStateLength); }; diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Sanyo.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Sanyo.cpp similarity index 55% rename from lib/IRremoteESP8266-2.7.5/src/ir_Sanyo.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Sanyo.cpp index f797fb678..25baf380b 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Sanyo.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Sanyo.cpp @@ -2,19 +2,27 @@ // Copyright 2016 marcosamarinho // Copyright 2017 David Conran +/// @file +/// @brief Support for Sanyo protocols. +/// Sanyo LC7461 support originally by marcosamarinho +/// Sanyo SA 8650B originally added from +/// https://github.com/shirriff/Arduino-IRremote/ +/// @see https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Sanyo.cpp +/// @see http://pdf.datasheetcatalog.com/datasheet/sanyo/LC7461.pdf +/// @see https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Sanyo.cpp +/// @see http://slydiman.narod.ru/scr/kb/sanyo.htm + +// Supports: +// Brand: Sanyo, Model: SA 8650B - disabled +// Brand: Sanyo, Model: LC7461 transmitter IC (SANYO_LC7461) + #include #include "IRrecv.h" #include "IRsend.h" -// Sanyo SA 8650B originally added from: -// https://github.com/shirriff/Arduino-IRremote/ -// Sanyo LC7461 support originally by marcosamarinho // Constants // Sanyo SA 8650B -// Ref: -// https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Sanyo.cpp - const uint16_t kSanyoSa8650bHdrMark = 3500; // seen range 3500 const uint16_t kSanyoSa8650bHdrSpace = 950; // seen 950 const uint16_t kSanyoSa8650bOneMark = 2400; // seen 2400 @@ -22,12 +30,8 @@ const uint16_t kSanyoSa8650bZeroMark = 700; // seen 700 // usually see 713 - not using ticks as get number wrapround const uint16_t kSanyoSa8650bDoubleSpaceUsecs = 800; const uint16_t kSanyoSa8650bRptLength = 45000; -// Sanyo LC7461 -// Ref: -// https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Sanyo.cpp -// http://slydiman.narod.ru/scr/kb/sanyo.htm -// http://pdf.datasheetcatalog.com/datasheet/sanyo/LC7461.pdf +// Sanyo LC7461 const uint16_t kSanyoLc7461AddressMask = (1 << kSanyoLC7461AddressBits) - 1; const uint16_t kSanyoLc7461CommandMask = (1 << kSanyoLC7461CommandBits) - 1; const uint16_t kSanyoLc7461HdrMark = 9000; @@ -45,18 +49,15 @@ const uint16_t kSanyoLc7461MinGap = kSanyoLc7461BitMark); #if SEND_SANYO -// Construct a Sanyo LC7461 message. -// -// Args: -// address: The 13 bit value of the address(Custom) portion of the protocol. -// command: The 8 bit value of the command(Key) portion of the protocol. -// Returns: -// An uint64_t with the encoded raw 42 bit Sanyo LC7461 data value. -// -// Notes: -// This protocol uses the NEC protocol timings. However, data is -// formatted as : address(13 bits), !address, command(8 bits), !command. -// According with LIRC, this protocol is used on Sanyo, Aiwa and Chinon +/// Construct a Sanyo LC7461 message. +/// @param[in] address The 13 bit value of the address(Custom) portion of the +/// protocol. +/// @param[in] command The 8 bit value of the command(Key) portion of the +/// protocol. +/// @return An uint64_t with the encoded raw 42 bit Sanyo LC7461 data value. +/// @note This protocol uses the NEC protocol timings. However, data is +/// formatted as : address(13 bits), !address, command(8 bits), !command. +/// According with LIRC, this protocol is used on Sanyo, Aiwa and Chinon uint64_t IRsend::encodeSanyoLC7461(uint16_t address, uint8_t command) { // Mask our input values to ensure the correct bit sizes. address &= kSanyoLc7461AddressMask; @@ -75,56 +76,44 @@ uint64_t IRsend::encodeSanyoLC7461(uint16_t address, uint8_t command) { return data; } -// Send a Sanyo LC7461 message. -// -// Args: -// data: The contents of the command you want to send. -// nbits: The bit size of the command being sent. -// repeat: The number of times you want the command to be repeated. -// -// Status: BETA / Probably works. -// -// Notes: -// Based on @marcosamarinho's work. -// This protocol uses the NEC protocol timings. However, data is -// formatted as : address(13 bits), !address, command (8 bits), !command. -// According with LIRC, this protocol is used on Sanyo, Aiwa and Chinon -// Information for this protocol is available at the Sanyo LC7461 datasheet. -// Repeats are performed similar to the NEC method of sending a special -// repeat message, rather than duplicating the entire message. -// Ref: -// https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Sanyo.cpp -// http://pdf.datasheetcatalog.com/datasheet/sanyo/LC7461.pdf -void IRsend::sendSanyoLC7461(uint64_t data, uint16_t nbits, uint16_t repeat) { +/// Send a Sanyo LC7461 message. +/// Status: BETA / Probably works. +/// @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. +/// @note Based on \@marcosamarinho's work. +/// This protocol uses the NEC protocol timings. However, data is +/// formatted as : address(13 bits), !address, command (8 bits), !command. +/// According with LIRC, this protocol is used on Sanyo, Aiwa and Chinon +/// Information for this protocol is available at the Sanyo LC7461 datasheet. +/// Repeats are performed similar to the NEC method of sending a special +/// repeat message, rather than duplicating the entire message. +/// @see https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Sanyo.cpp +/// @see http://pdf.datasheetcatalog.com/datasheet/sanyo/LC7461.pdf +void IRsend::sendSanyoLC7461(const uint64_t data, const uint16_t nbits, + const uint16_t repeat) { // This protocol appears to be another 42-bit variant of the NEC protocol. sendNEC(data, nbits, repeat); } #endif // SEND_SANYO #if DECODE_SANYO -// Decode the supplied SANYO LC7461 message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of data bits to expect. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: BETA / Probably works. -// -// Notes: -// Based on @marcosamarinho's work. -// This protocol uses the NEC protocol. However, data is -// formatted as : address(13 bits), !address, command (8 bits), !command. -// According with LIRC, this protocol is used on Sanyo, Aiwa and Chinon -// Information for this protocol is available at the Sanyo LC7461 datasheet. -// Ref: -// http://slydiman.narod.ru/scr/kb/sanyo.htm -// https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Sanyo.cpp -// http://pdf.datasheetcatalog.com/datasheet/sanyo/LC7461.pdf +/// Decode the supplied SANYO LC7461 message. +/// Status: BETA / Probably works. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @note Based on \@marcosamarinho's work. +/// This protocol uses the NEC protocol. However, data is +/// formatted as : address(13 bits), !address, command (8 bits), !command. +/// According with LIRC, this protocol is used on Sanyo, Aiwa and Chinon +/// Information for this protocol is available at the Sanyo LC7461 datasheet. +/// @see http://slydiman.narod.ru/scr/kb/sanyo.htm +/// @see https://github.com/marcosamarinho/IRremoteESP8266/blob/master/ir_Sanyo.cpp +/// @see http://pdf.datasheetcatalog.com/datasheet/sanyo/LC7461.pdf bool IRrecv::decodeSanyoLC7461(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (strict && nbits != kSanyoLC7461Bits) @@ -162,24 +151,21 @@ bool IRrecv::decodeSanyoLC7461(decode_results *results, uint16_t offset, } /* NOTE: Disabled due to poor quality. -// Decode the supplied Sanyo SA 8650B message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// nbits: Nr. of data bits to expect. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: Depricated. -// -// NOTE: This decoder looks like rubbish. Only keeping it for compatibility -// with the Arduino IRremote library. Seriously, don't trust it. -// If someone has a device that this is supposed to be for, please log an -// Issue on github with a rawData dump please. We should probably remove -// it. We think this is a Sanyo decoder - serial = SA 8650B -// Ref: -// https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Sanyo.cpp +/// Decode the supplied Sanyo SA 8650B message. +/// Status: Depricated. +/// @depricated Disabled due to poor quality. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @warning This decoder looks like rubbish. Only keeping it for compatibility +/// with the Arduino IRremote library. Seriously, don't trust it. +/// If someone has a device that this is supposed to be for, please log an +/// Issue on github with a rawData dump please. We should probably remove it. +/// We think this is a Sanyo decoder - serial = SA 8650B +/// @see https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Sanyo.cpp bool IRrecv::decodeSanyo(decode_results *results, uint16_t nbits, bool strict) { if (results->rawlen < 2 * nbits + kHeader - 1) return false; // Shorter than shortest possible. diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Sharp.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Sharp.cpp new file mode 100644 index 000000000..4ba23ac89 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Sharp.cpp @@ -0,0 +1,752 @@ +// Copyright 2009 Ken Shirriff +// Copyright 2017, 2019 David Conran + +/// @file +/// @brief Support for Sharp protocols. +/// @see http://www.sbprojects.com/knowledge/ir/sharp.htm +/// @see http://lirc.sourceforge.net/remotes/sharp/GA538WJSA +/// @see http://www.mwftr.com/ucF08/LEC14%20PIC%20IR.pdf +/// @see http://www.hifi-remote.com/johnsfine/DecodeIR.html#Sharp +/// @see GlobalCache's IR Control Tower data. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/638 +/// @see https://github.com/ToniA/arduino-heatpumpir/blob/master/SharpHeatpumpIR.cpp + +#include "ir_Sharp.h" +#include +#include +#ifndef ARDUINO +#include +#endif +#include "IRrecv.h" +#include "IRsend.h" +#include "IRtext.h" +#include "IRutils.h" + +// Constants +// period time = 1/38000Hz = 26.316 microseconds. +const uint16_t kSharpTick = 26; +const uint16_t kSharpBitMarkTicks = 10; +const uint16_t kSharpBitMark = kSharpBitMarkTicks * kSharpTick; +const uint16_t kSharpOneSpaceTicks = 70; +const uint16_t kSharpOneSpace = kSharpOneSpaceTicks * kSharpTick; +const uint16_t kSharpZeroSpaceTicks = 30; +const uint16_t kSharpZeroSpace = kSharpZeroSpaceTicks * kSharpTick; +const uint16_t kSharpGapTicks = 1677; +const uint16_t kSharpGap = kSharpGapTicks * kSharpTick; +// Address(5) + Command(8) + Expansion(1) + Check(1) +const uint64_t kSharpToggleMask = + ((uint64_t)1 << (kSharpBits - kSharpAddressBits)) - 1; +const uint64_t kSharpAddressMask = ((uint64_t)1 << kSharpAddressBits) - 1; +const uint64_t kSharpCommandMask = ((uint64_t)1 << kSharpCommandBits) - 1; + +using irutils::addBoolToString; +using irutils::addFanToString; +using irutils::addIntToString; +using irutils::addLabeledString; +using irutils::addModeToString; +using irutils::addTempToString; +using irutils::minsToString; +using irutils::setBit; +using irutils::setBits; + +// Also used by Denon protocol +#if (SEND_SHARP || SEND_DENON) +/// Send a (raw) Sharp message +/// @note Status: STABLE / Working fine. +/// @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. +/// @note his procedure handles the inversion of bits required per protocol. +/// The protocol spec says to send the LSB first, but legacy code & usage +/// has us sending the MSB first. Grrrr. Normal invocation of encodeSharp() +/// handles this for you, assuming you are using the correct/standard values. +/// e.g. sendSharpRaw(encodeSharp(address, command)); +void IRsend::sendSharpRaw(const uint64_t data, const uint16_t nbits, + const uint16_t repeat) { + uint64_t tempdata = data; + for (uint16_t i = 0; i <= repeat; i++) { + // Protocol demands that the data be sent twice; once normally, + // then with all but the address bits inverted. + // Note: Previously this used to be performed 3 times (normal, inverted, + // normal), however all data points to that being incorrect. + for (uint8_t n = 0; n < 2; n++) { + sendGeneric(0, 0, // No Header + kSharpBitMark, kSharpOneSpace, kSharpBitMark, kSharpZeroSpace, + kSharpBitMark, kSharpGap, tempdata, nbits, 38, true, + 0, // Repeats are handled already. + 33); + // Invert the data per protocol. This is always called twice, so it's + // retured to original upon exiting the inner loop. + tempdata ^= kSharpToggleMask; + } + } +} + +/// Encode a (raw) Sharp message from it's components. +/// Status: STABLE / Works okay. +/// @param[in] address The value of the address to be sent. +/// @param[in] command The value of the address to be sent. (8 bits) +/// @param[in] expansion The value of the expansion bit to use. +/// (0 or 1, typically 1) +/// @param[in] check The value of the check bit to use. (0 or 1, typically 0) +/// @param[in] MSBfirst Flag indicating MSB first or LSB first order. +/// @return A uint32_t containing the raw Sharp message for `sendSharpRaw()`. +/// @note Assumes the standard Sharp bit sizes. +/// Historically sendSharp() sends address & command in +/// MSB first order. This is actually incorrect. It should be sent in LSB +/// order. The behaviour of sendSharp() hasn't been changed to maintain +/// backward compatibility. +uint32_t IRsend::encodeSharp(const uint16_t address, const uint16_t command, + const uint16_t expansion, const uint16_t check, + const bool MSBfirst) { + // Mask any unexpected bits. + uint16_t tempaddress = GETBITS16(address, 0, kSharpAddressBits); + uint16_t tempcommand = GETBITS16(command, 0, kSharpCommandBits); + uint16_t tempexpansion = GETBITS16(expansion, 0, 1); + uint16_t tempcheck = GETBITS16(check, 0, 1); + + if (!MSBfirst) { // Correct bit order if needed. + tempaddress = reverseBits(tempaddress, kSharpAddressBits); + tempcommand = reverseBits(tempcommand, kSharpCommandBits); + } + // Concatinate all the bits. + return (tempaddress << (kSharpCommandBits + 2)) | (tempcommand << 2) | + (tempexpansion << 1) | tempcheck; +} + +/// Send a Sharp message +/// Status: DEPRECATED / Previously working fine. +/// @deprecated Only use this if you are using legacy from the original +/// Arduino-IRremote library. 99% of the time, you will want to use +/// `sendSharpRaw()` instead +/// @param[in] address Address value to be sent. +/// @param[in] command Command value 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. +/// @note This procedure has a non-standard invocation style compared to similar +/// sendProtocol() routines. This is due to legacy, compatibility, & historic +/// reasons. Normally the calling syntax version is like sendSharpRaw(). +/// This procedure transmits the address & command in MSB first order, which is +/// incorrect. This behaviour is left as-is to maintain backward +/// compatibility with legacy code. +/// In short, you should use sendSharpRaw(), encodeSharp(), and the correct +/// values of address & command instead of using this, & the wrong values. +void IRsend::sendSharp(const uint16_t address, uint16_t const command, + const uint16_t nbits, const uint16_t repeat) { + sendSharpRaw(encodeSharp(address, command, 1, 0, true), nbits, repeat); +} +#endif // (SEND_SHARP || SEND_DENON) + +// Used by decodeDenon too. +#if (DECODE_SHARP || DECODE_DENON) +/// Decode the supplied Sharp message. +/// Status: STABLE / Working fine. +/// @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. +/// @param[in] expansion Should we expect the expansion bit to be set. +/// Default is true. +/// @return True if it can decode it, false if it can't. +/// @note This procedure returns a value suitable for use in `sendSharpRaw()`. +/// @todo Need to ensure capture of the inverted message as it can +/// be missed due to the interrupt timeout used to detect an end of message. +/// Several compliance checks are disabled until that is resolved. +bool IRrecv::decodeSharp(decode_results *results, uint16_t offset, + const uint16_t nbits, const bool strict, + const bool expansion) { + if (results->rawlen <= 2 * nbits + kFooter - 1 + offset) + return false; // Not enough entries to be a Sharp message. + // Compliance + if (strict) { + if (nbits != kSharpBits) return false; // Request is out of spec. + // DISABLED - See TODO +#ifdef UNIT_TEST + // An in spec message has the data sent normally, then inverted. So we + // expect twice as many entries than to just get the results. + if (results->rawlen <= (2 * (2 * nbits + kFooter)) - 1 + offset) + return false; +#endif + } + + uint64_t data = 0; + + // Match Data + Footer + uint16_t used; + used = matchGeneric(results->rawbuf + offset, &data, + results->rawlen - offset, nbits, + 0, 0, // No Header + kSharpBitMark, kSharpOneSpace, + kSharpBitMark, kSharpZeroSpace, + kSharpBitMark, kSharpGap, true, 35); + if (!used) return false; + offset += used; + // Compliance + if (strict) { + // Check the state of the expansion bit is what we expect. + if ((data & 0b10) >> 1 != expansion) return false; + // The check bit should be cleared in a normal message. + if (data & 0b1) return false; + // DISABLED - See TODO +#ifdef UNIT_TEST + // Grab the second copy of the data (i.e. inverted) + uint64_t second_data = 0; + // Match Data + Footer + if (!matchGeneric(results->rawbuf + offset, &second_data, + results->rawlen - offset, nbits, + 0, 0, + kSharpBitMark, kSharpOneSpace, + kSharpBitMark, kSharpZeroSpace, + kSharpBitMark, kSharpGap, true, 35)) return false; + // Check that second_data has been inverted correctly. + if (data != (second_data ^ kSharpToggleMask)) return false; +#endif // UNIT_TEST + } + + // Success + results->decode_type = SHARP; + results->bits = nbits; + results->value = data; + // Address & command are actually transmitted in LSB first order. + results->address = reverseBits(data, nbits) & kSharpAddressMask; + results->command = + reverseBits((data >> 2) & kSharpCommandMask, kSharpCommandBits); + return true; +} +#endif // (DECODE_SHARP || DECODE_DENON) + +#if SEND_SHARP_AC +/// Send a Sharp A/C message. +/// Status: Alpha / Untested. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/638 +/// @see https://github.com/ToniA/arduino-heatpumpir/blob/master/SharpHeatpumpIR.cpp +void IRsend::sendSharpAc(const unsigned char data[], const uint16_t nbytes, + const uint16_t repeat) { + if (nbytes < kSharpAcStateLength) + return; // Not enough bytes to send a proper message. + + sendGeneric(kSharpAcHdrMark, kSharpAcHdrSpace, + kSharpAcBitMark, kSharpAcOneSpace, + kSharpAcBitMark, kSharpAcZeroSpace, + kSharpAcBitMark, kSharpAcGap, + data, nbytes, 38000, false, repeat, 50); +} +#endif // SEND_SHARP_AC + +/// 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? +IRSharpAc::IRSharpAc(const uint16_t pin, const bool inverted, + const bool use_modulation) + : _irsend(pin, inverted, use_modulation) { this->stateReset(); } + +/// Set up hardware to be able to send a message. +void IRSharpAc::begin(void) { _irsend.begin(); } + +#if SEND_SHARP_AC +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. +void IRSharpAc::send(const uint16_t repeat) { + _irsend.sendSharpAc(getRaw(), kSharpAcStateLength, repeat); +} +#endif // SEND_SHARP_AC + +/// Calculate the checksum for a given state. +/// @param[in] state The array to calc the checksum of. +/// @param[in] length The length/size of the array. +/// @return The calculated 4-bit checksum value. +uint8_t IRSharpAc::calcChecksum(uint8_t state[], const uint16_t length) { + uint8_t xorsum = xorBytes(state, length - 1); + xorsum ^= GETBITS8(state[length - 1], kLowNibble, kNibbleSize); + xorsum ^= GETBITS8(xorsum, kHighNibble, kNibbleSize); + return GETBITS8(xorsum, kLowNibble, kNibbleSize); +} + +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length/size of the array. +/// @return true, if the state has a valid checksum. Otherwise, false. +bool IRSharpAc::validChecksum(uint8_t state[], const uint16_t length) { + return GETBITS8(state[length - 1], kHighNibble, kNibbleSize) == + IRSharpAc::calcChecksum(state, length); +} + +/// Calculate and set the checksum values for the internal state. +void IRSharpAc::checksum(void) { + setBits(&remote[kSharpAcStateLength - 1], kHighNibble, kNibbleSize, + this->calcChecksum(remote)); +} + +/// Reset the state of the remote to a known good state/sequence. +void IRSharpAc::stateReset(void) { + static const uint8_t reset[kSharpAcStateLength] = { + 0xAA, 0x5A, 0xCF, 0x10, 0x00, 0x01, 0x00, 0x00, 0x08, 0x80, 0x00, 0xE0, + 0x01}; + memcpy(remote, reset, kSharpAcStateLength); + _temp = getTemp(); + _mode = getMode(); + _fan = getFan(); +} + +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. +uint8_t *IRSharpAc::getRaw(void) { + this->checksum(); // Ensure correct settings before sending. + return remote; +} + +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. +/// @param[in] length The length/size of the new_code array. +void IRSharpAc::setRaw(const uint8_t new_code[], const uint16_t length) { + memcpy(remote, new_code, std::min(length, kSharpAcStateLength)); +} + +/// Set the value of the Power Special setting without any checks. +/// @param[in] value The value to set Power Special to. +void IRSharpAc::setPowerSpecial(const uint8_t value) { + setBits(&remote[kSharpAcBytePowerSpecial], kSharpAcPowerSetSpecialOffset, + kSharpAcPowerSpecialSize, value); +} + +/// Get the value of the Power Special setting. +/// @return The setting's value. +uint8_t IRSharpAc::getPowerSpecial(void) { + return GETBITS8(remote[kSharpAcBytePowerSpecial], + kSharpAcPowerSetSpecialOffset, kSharpAcPowerSpecialSize); +} + +/// Clear the "special"/non-normal bits in the power section. +/// e.g. for normal/common command modes. +void IRSharpAc::clearPowerSpecial(void) { + setPowerSpecial(getPowerSpecial() & kSharpAcPowerOn); +} + +/// Is one of the special power states in use? +/// @return true, it is. false, it isn't. +bool IRSharpAc::isPowerSpecial(void) { + switch (getPowerSpecial()) { + case kSharpAcPowerSetSpecialOff: + case kSharpAcPowerSetSpecialOn: + case kSharpAcPowerTimerSetting: return true; + default: return false; + } +} + +/// Set the requested power state of the A/C to on. +void IRSharpAc::on(void) { setPower(true); } + +/// Set the requested power state of the A/C to off. +void IRSharpAc::off(void) { setPower(false); } + +/// Change the power setting, including the previous power state. +/// @param[in] on true, the setting is on. false, the setting is off. +/// @param[in] prev_on true, the setting is on. false, the setting is off. +void IRSharpAc::setPower(const bool on, const bool prev_on) { + setPowerSpecial(on ? (prev_on ? kSharpAcPowerOn : kSharpAcPowerOnFromOff) + : kSharpAcPowerOff); + // Power operations are incompatible with clean mode. + if (getClean()) setClean(false); + setSpecial(kSharpAcSpecialPower); +} + +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. +bool IRSharpAc::getPower(void) { + switch (getPowerSpecial()) { + case kSharpAcPowerUnknown: + case kSharpAcPowerOff: return false; + default: return true; // Everything else is "probably" on. + } +} + +/// Set the value of the Special (button/command?) setting. +/// @param[in] mode The value to set Special to. +void IRSharpAc::setSpecial(const uint8_t mode) { + switch (mode) { + case kSharpAcSpecialPower: + case kSharpAcSpecialTurbo: + case kSharpAcSpecialTempEcono: + case kSharpAcSpecialFan: + case kSharpAcSpecialSwing: + case kSharpAcSpecialTimer: + case kSharpAcSpecialTimerHalfHour: + remote[kSharpAcByteSpecial] = mode; + break; + default: + setSpecial(kSharpAcSpecialPower); + } +} + +/// Get the value of the Special (button/command?) setting. +/// @return The setting's value. +uint8_t IRSharpAc::getSpecial(void) { return remote[kSharpAcByteSpecial]; } + +/// Set the temperature. +/// @param[in] temp The temperature in degrees celsius. +/// @param[in] save Do we save this setting as a user set one? +void IRSharpAc::setTemp(const uint8_t temp, const bool save) { + switch (this->getMode()) { + // Auto & Dry don't allow temp changes and have a special temp. + case kSharpAcAuto: + case kSharpAcDry: + remote[kSharpAcByteTemp] = 0; + return; + default: + remote[kSharpAcByteTemp] = 0xC0; + } + uint8_t degrees = std::max(temp, kSharpAcMinTemp); + degrees = std::min(degrees, kSharpAcMaxTemp); + if (save) _temp = degrees; + setBits(&remote[kSharpAcByteTemp], kLowNibble, kNibbleSize, + degrees - kSharpAcMinTemp); + setSpecial(kSharpAcSpecialTempEcono); + clearPowerSpecial(); +} + +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. +uint8_t IRSharpAc::getTemp(void) { + return GETBITS8(remote[kSharpAcByteTemp], kLowNibble, kNibbleSize) + + kSharpAcMinTemp; +} + +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. +uint8_t IRSharpAc::getMode(void) { + return GETBITS8(remote[kSharpAcByteMode], kLowNibble, kSharpAcModeSize); +} + +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. +/// @param[in] save Do we save this setting as a user set one? +void IRSharpAc::setMode(const uint8_t mode, const bool save) { + switch (mode) { + case kSharpAcAuto: + case kSharpAcDry: + // When Dry or Auto, Fan always 2(Auto) + this->setFan(kSharpAcFanAuto, false); + // FALLTHRU + case kSharpAcCool: + case kSharpAcHeat: + setBits(&remote[kSharpAcByteMode], kLowNibble, kSharpAcModeSize, mode); + break; + default: + this->setMode(kSharpAcAuto, save); + return; + } + // Dry/Auto have no temp setting. This step will enforce it. + this->setTemp(_temp, false); + // Save the mode in case we need to revert to it. eg. Clean + if (save) _mode = mode; + + setSpecial(kSharpAcSpecialPower); + clearPowerSpecial(); +} + +/// Set the speed of the fan. +/// @param[in] speed The desired setting. +/// @param[in] save Do we save this setting as a user set one? +void IRSharpAc::setFan(const uint8_t speed, const bool save) { + switch (speed) { + case kSharpAcFanAuto: + case kSharpAcFanMin: + case kSharpAcFanMed: + case kSharpAcFanHigh: + case kSharpAcFanMax: + setBits(&remote[kSharpAcByteFan], kSharpAcFanOffset, kSharpAcFanSize, + speed); + break; + default: + this->setFan(kSharpAcFanAuto); + return; + } + if (save) _fan = speed; + setSpecial(kSharpAcSpecialFan); + clearPowerSpecial(); +} + +/// Get the current fan speed setting. +/// @return The current fan speed/mode. +uint8_t IRSharpAc::getFan(void) { + return GETBITS8(remote[kSharpAcByteFan], kSharpAcFanOffset, kSharpAcFanSize); +} + +/// Get the Turbo setting of the A/C. +/// @return true, the setting is on. false, the setting is off. +bool IRSharpAc::getTurbo(void) { + return (getPowerSpecial() == kSharpAcPowerSetSpecialOn) && + (getSpecial() == kSharpAcSpecialTurbo); +} + +/// Set the Turbo setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. +/// @note If you use this method, you will need to send it before making +/// other changes to the settings, as they may overwrite some of the bits +/// used by this setting. +void IRSharpAc::setTurbo(const bool on) { + if (on) setFan(kSharpAcFanMax); + setPowerSpecial(on ? kSharpAcPowerSetSpecialOn : kSharpAcPowerSetSpecialOff); + setSpecial(kSharpAcSpecialTurbo); +} + +/// Get the (vertical) Swing Toggle setting of the A/C. +/// @return true, the setting is on. false, the setting is off. +bool IRSharpAc::getSwingToggle(void) { + return GETBITS8(remote[kSharpAcByteSwing], kSharpAcSwingOffset, + kSharpAcSwingSize) == kSharpAcSwingToggle; +} + +/// Set the (vertical) Swing Toggle setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. +void IRSharpAc::setSwingToggle(const bool on) { + setBits(&remote[kSharpAcByteSwing], kSharpAcSwingOffset, kSharpAcSwingSize, + on ? kSharpAcSwingToggle : kSharpAcSwingNoToggle); + if (on) setSpecial(kSharpAcSpecialSwing); +} + +/// Get the Ion (Filter) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. +bool IRSharpAc::getIon(void) { + return GETBIT8(remote[kSharpAcByteIon], kSharpAcBitIonOffset); +} + +/// Set the Ion (Filter) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. +void IRSharpAc::setIon(const bool on) { + setBit(&remote[kSharpAcByteIon], kSharpAcBitIonOffset, on); + clearPowerSpecial(); + if (on) setSpecial(kSharpAcSpecialSwing); +} + +/// Get the Economical mode toggle setting of the A/C. +/// @return true, the setting is on. false, the setting is off. +bool IRSharpAc::getEconoToggle(void) { + return (getPowerSpecial() == kSharpAcPowerSetSpecialOn) && + (getSpecial() == kSharpAcSpecialTempEcono); +} + +/// Set the Economical mode toggle setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. +/// @warning Probably incompatible with `setTurbo()` +void IRSharpAc::setEconoToggle(const bool on) { + if (on) setSpecial(kSharpAcSpecialTempEcono); + setPowerSpecial(on ? kSharpAcPowerSetSpecialOn : kSharpAcPowerSetSpecialOff); +} + +/// Get how long the timer is set for, in minutes. +/// @return The time in nr of minutes. +uint16_t IRSharpAc::getTimerTime(void) { + return GETBITS8(remote[kSharpAcByteTimer], kSharpAcTimerHoursOffset, + kSharpAcTimerHoursSize) * kSharpAcTimerIncrement * 2 + + ((getSpecial() == kSharpAcSpecialTimerHalfHour) ? kSharpAcTimerIncrement + : 0); +} + +/// Is the Timer enabled? +/// @return true, the setting is on. false, the setting is off. +bool IRSharpAc::getTimerEnabled(void) { + return GETBIT8(remote[kSharpAcByteTimer], kSharpAcBitTimerEnabled); +} + +/// Get the current timer type. +/// @return true, It's an "On" timer. false, It's an "Off" timer. +bool IRSharpAc::getTimerType(void) { + return GETBIT8(remote[kSharpAcByteTimer], kSharpAcBitTimerType); +} + +/// Set or cancel the timer function. +/// @param[in] enable Is the timer to be enabled (true) or canceled(false)? +/// @param[in] timer_type An On (true) or an Off (false). Ignored if canceled. +/// @param[in] mins Nr. of minutes the timer is to be set to. +/// @note Rounds down to 30 min increments. (max: 720 mins (12h), 0 is Off) +void IRSharpAc::setTimer(bool enable, bool timer_type, uint16_t mins) { + uint8_t half_hours = std::min(mins / kSharpAcTimerIncrement, + kSharpAcTimerHoursMax * 2); + if (half_hours == 0) enable = false; + if (!enable) { + half_hours = 0; + timer_type = kSharpAcOffTimerType; + } + setBit(&remote[kSharpAcByteTimer], kSharpAcBitTimerEnabled, enable); + setBit(&remote[kSharpAcByteTimer], kSharpAcBitTimerType, timer_type); + setBits(&remote[kSharpAcByteTimer], kSharpAcTimerHoursOffset, + kSharpAcTimerHoursSize, half_hours / 2); + // Handle non-round hours. + setSpecial((half_hours % 2) ? kSharpAcSpecialTimerHalfHour + : kSharpAcSpecialTimer); + setPowerSpecial(kSharpAcPowerTimerSetting); +} + +/// Get the Clean setting of the A/C. +/// @return true, the setting is on. false, the setting is off. +bool IRSharpAc::getClean(void) { + return GETBIT8(remote[kSharpAcByteClean], kSharpAcBitCleanOffset); +} + +/// Set the Economical mode toggle setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. +/// @note Officially A/C unit needs to be "Off" before clean mode can be entered +void IRSharpAc::setClean(const bool on) { + // Clean mode appears to be just default dry mode, with an extra bit set. + if (on) { + setMode(kSharpAcDry, false); + setPower(true, false); + } else { + // Restore the previous operation mode & fan speed. + setMode(_mode, false); + setFan(_fan, false); + } + setBit(&remote[kSharpAcByteClean], kSharpAcBitCleanOffset, on); + clearPowerSpecial(); +} + +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. +uint8_t IRSharpAc::convertMode(const stdAc::opmode_t mode) { + switch (mode) { + case stdAc::opmode_t::kCool: return kSharpAcCool; + case stdAc::opmode_t::kHeat: return kSharpAcHeat; + case stdAc::opmode_t::kDry: return kSharpAcDry; + // No Fan mode. + default: return kSharpAcAuto; + } +} + +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. +uint8_t IRSharpAc::convertFan(const stdAc::fanspeed_t speed) { + switch (speed) { + case stdAc::fanspeed_t::kMin: + case stdAc::fanspeed_t::kLow: return kSharpAcFanMin; + case stdAc::fanspeed_t::kMedium: return kSharpAcFanMed; + case stdAc::fanspeed_t::kHigh: return kSharpAcFanHigh; + case stdAc::fanspeed_t::kMax: return kSharpAcFanMax; + default: return kSharpAcFanAuto; + } +} + +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. +stdAc::opmode_t IRSharpAc::toCommonMode(const uint8_t mode) { + switch (mode) { + case kSharpAcCool: return stdAc::opmode_t::kCool; + case kSharpAcHeat: return stdAc::opmode_t::kHeat; + case kSharpAcDry: return stdAc::opmode_t::kDry; + default: return stdAc::opmode_t::kAuto; + } +} + +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. +stdAc::fanspeed_t IRSharpAc::toCommonFanSpeed(const uint8_t speed) { + switch (speed) { + case kSharpAcFanMax: return stdAc::fanspeed_t::kMax; + case kSharpAcFanHigh: return stdAc::fanspeed_t::kHigh; + case kSharpAcFanMed: return stdAc::fanspeed_t::kMedium; + case kSharpAcFanMin: return stdAc::fanspeed_t::kMin; + default: return stdAc::fanspeed_t::kAuto; + } +} + +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. +stdAc::state_t IRSharpAc::toCommon(void) { + stdAc::state_t result; + result.protocol = decode_type_t::SHARP_AC; + result.model = -1; // Not supported. + result.power = this->getPower(); + result.mode = this->toCommonMode(this->getMode()); + result.celsius = true; + result.degrees = this->getTemp(); + result.fanspeed = this->toCommonFanSpeed(this->getFan()); + result.turbo = this->getTurbo(); + result.swingv = this->getSwingToggle() ? stdAc::swingv_t::kAuto + : stdAc::swingv_t::kOff; + result.filter = this->getIon(); + result.econo = this->getEconoToggle(); + result.clean = this->getClean(); + // Not supported. + result.swingh = stdAc::swingh_t::kOff; + result.quiet = false; + result.beep = false; + result.light = false; + result.sleep = -1; + result.clock = -1; + return result; +} + +/// Convert the current internal state into a human readable string. +/// @return A human readable string. +String IRSharpAc::toString(void) { + String result = ""; + result.reserve(135); // Reserve some heap for the string to reduce fragging. + result += addLabeledString(isPowerSpecial() ? "-" + : (getPower() ? kOnStr : kOffStr), + kPowerStr, false); + result += addModeToString(getMode(), kSharpAcAuto, kSharpAcCool, kSharpAcHeat, + kSharpAcDry, kSharpAcAuto); + result += addTempToString(getTemp()); + result += addFanToString(getFan(), kSharpAcFanMax, kSharpAcFanMin, + kSharpAcFanAuto, kSharpAcFanAuto, kSharpAcFanMed); + result += addBoolToString(getTurbo(), kTurboStr); + result += addBoolToString(getSwingToggle(), kSwingVToggleStr); + result += addBoolToString(getIon(), kIonStr); + result += addLabeledString(getEconoToggle() ? kToggleStr : "-", kEconoStr); + result += addBoolToString(getClean(), kCleanStr); + if (getTimerEnabled()) + result += addLabeledString(minsToString(getTimerTime()), + getTimerType() ? kOnTimerStr : kOffTimerStr); + return result; +} + +#if DECODE_SHARP_AC +/// Decode the supplied Sharp A/C message. +/// Status: STABLE / Known working. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/638 +/// @see https://github.com/ToniA/arduino-heatpumpir/blob/master/SharpHeatpumpIR.cpp +bool IRrecv::decodeSharpAc(decode_results *results, uint16_t offset, + const uint16_t nbits, const bool strict) { + // Compliance + if (strict && nbits != kSharpAcBits) return false; + + // Match Header + Data + Footer + uint16_t used; + used = matchGeneric(results->rawbuf + offset, results->state, + results->rawlen - offset, nbits, + kSharpAcHdrMark, kSharpAcHdrSpace, + kSharpAcBitMark, kSharpAcOneSpace, + kSharpAcBitMark, kSharpAcZeroSpace, + kSharpAcBitMark, kSharpAcGap, true, + _tolerance, kMarkExcess, false); + if (used == 0) return false; + offset += used; + // Compliance + if (strict) { + if (!IRSharpAc::validChecksum(results->state)) return false; + } + + // Success + results->decode_type = SHARP_AC; + results->bits = nbits; + // No need to record the state as we stored it as we decoded it. + // As we use result->state, we don't record value, address, or command as it + // is a union data type. + return true; +} +#endif // DECODE_SHARP_AC diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Sharp.h b/lib/IRremoteESP8266-2.7.8/src/ir_Sharp.h new file mode 100644 index 000000000..38d01a0b0 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Sharp.h @@ -0,0 +1,181 @@ +// Copyright 2019 crankyoldgit + +/// @file +/// @brief Support for Sharp protocols. +/// @see http://www.sbprojects.com/knowledge/ir/sharp.htm +/// @see http://lirc.sourceforge.net/remotes/sharp/GA538WJSA +/// @see http://www.mwftr.com/ucF08/LEC14%20PIC%20IR.pdf +/// @see http://www.hifi-remote.com/johnsfine/DecodeIR.html#Sharp +/// @see GlobalCache's IR Control Tower data. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/638 +/// @see https://github.com/ToniA/arduino-heatpumpir/blob/master/SharpHeatpumpIR.cpp + +// Supports: +// Brand: Sharp, Model: LC-52D62U TV +// Brand: Sharp, Model: AY-ZP40KR A/C +// Brand: Sharp, Model: AH-AxSAY A/C +// Brand: Sharp, Model: CRMC-A907 JBEZ remote +// Brand: Sharp, Model: AH-XP10NRY A/C +// Brand: Sharp, Model: CRMC-820JBEZ remote + +#ifndef IR_SHARP_H_ +#define IR_SHARP_H_ + +#ifndef UNIT_TEST +#include +#endif +#include "IRrecv.h" +#include "IRremoteESP8266.h" +#include "IRsend.h" +#ifdef UNIT_TEST +#include "IRsend_test.h" +#endif +#include "IRutils.h" + +// Constants +const uint16_t kSharpAcHdrMark = 3800; +const uint16_t kSharpAcHdrSpace = 1900; +const uint16_t kSharpAcBitMark = 470; +const uint16_t kSharpAcZeroSpace = 500; +const uint16_t kSharpAcOneSpace = 1400; +const uint32_t kSharpAcGap = kDefaultMessageGap; + +// Byte[4] +const uint8_t kSharpAcByteTemp = 4; +const uint8_t kSharpAcMinTemp = 15; // Celsius +const uint8_t kSharpAcMaxTemp = 30; // Celsius +// Byte[5] +const uint8_t kSharpAcBytePowerSpecial = 5; +const uint8_t kSharpAcPowerSetSpecialOffset = kHighNibble; // 0bxxxx0000 +const uint8_t kSharpAcPowerSpecialSize = kNibbleSize; // 0bxxxx0000 +const uint8_t kSharpAcPowerUnknown = 0; // 0b0000 +const uint8_t kSharpAcPowerOnFromOff = 1; // 0b0001 +const uint8_t kSharpAcPowerOff = 2; // 0b0010 +const uint8_t kSharpAcPowerOn = 3; // 0b0011 (Normal) +const uint8_t kSharpAcPowerSetSpecialOn = 6; // 0b0110 +const uint8_t kSharpAcPowerSetSpecialOff = 7; // 0b0111 +const uint8_t kSharpAcPowerTimerSetting = 8; // 0b1000 +// Byte[6] +const uint8_t kSharpAcByteMode = 6; +const uint8_t kSharpAcModeSize = 2; // Mask 0b000000xx; +const uint8_t kSharpAcAuto = 0b00; +const uint8_t kSharpAcDry = 0b11; +const uint8_t kSharpAcCool = 0b10; +const uint8_t kSharpAcHeat = 0b01; +const uint8_t kSharpAcByteClean = kSharpAcByteMode; +const uint8_t kSharpAcBitCleanOffset = 3; // Mask 0b0000x000 +const uint8_t kSharpAcByteFan = kSharpAcByteMode; +const uint8_t kSharpAcFanOffset = 4; // Mask 0b0xxx0000 +const uint8_t kSharpAcFanSize = 3; // Nr. of Bits +const uint8_t kSharpAcFanAuto = 0b010; // 2 +const uint8_t kSharpAcFanMin = 0b100; // 4 (FAN1) +const uint8_t kSharpAcFanMed = 0b011; // 3 (FAN2) +const uint8_t kSharpAcFanHigh = 0b101; // 5 (FAN3) +const uint8_t kSharpAcFanMax = 0b111; // 7 (FAN4) +// Byte[7] +const uint8_t kSharpAcByteTimer = 7; +const uint8_t kSharpAcTimerIncrement = 30; // Mins +const uint8_t kSharpAcTimerHoursOffset = kLowNibble; +const uint8_t kSharpAcTimerHoursSize = kNibbleSize; // Mask 0b0000xxxx +const uint8_t kSharpAcTimerHoursOff = 0b0000; +const uint8_t kSharpAcTimerHoursMax = 0b1100; // 12 +const uint8_t kSharpAcBitTimerType = 6; // Mask 0b0x000000 +const uint8_t kSharpAcOffTimerType = 0b0; +const uint8_t kSharpAcOnTimerType = 0b1; +const uint8_t kSharpAcBitTimerEnabled = 7; // Mask 0bx0000000 +// Byte[8] +const uint8_t kSharpAcByteSwing = 8; +const uint8_t kSharpAcSwingOffset = 0; +const uint8_t kSharpAcSwingSize = 3; // Mask 0b00000xxx +const uint8_t kSharpAcSwingToggle = 0b111; +const uint8_t kSharpAcSwingNoToggle = 0b000; +// Byte[10] +const uint8_t kSharpAcByteSpecial = 10; // Mask 0bxxxxxxxx +const uint8_t kSharpAcSpecialPower = 0x00; +const uint8_t kSharpAcSpecialTurbo = 0x01; +const uint8_t kSharpAcSpecialTempEcono = 0x04; +const uint8_t kSharpAcSpecialFan = 0x05; +const uint8_t kSharpAcSpecialSwing = 0x06; +const uint8_t kSharpAcSpecialTimer = 0xC0; +const uint8_t kSharpAcSpecialTimerHalfHour = 0xDE; +// Byte[11] +const uint8_t kSharpAcByteIon = 11; +const uint8_t kSharpAcBitIonOffset = 2; // Mask 0b00000x00 +// Byte[12] (Checksum) + +// Classes +/// Class for handling detailed Sharp A/C messages. +class IRSharpAc { + public: + explicit IRSharpAc(const uint16_t pin, const bool inverted = false, + const bool use_modulation = true); +#if SEND_SHARP_AC + void send(const uint16_t repeat = kSharpAcDefaultRepeat); + /// 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_SHARP_AC + void begin(void); + void on(void); + void off(void); + void setPower(const bool on, const bool prev_on = true); + bool getPower(void); + bool isPowerSpecial(void); + void setTemp(const uint8_t temp, const bool save = true); + uint8_t getTemp(void); + void setFan(const uint8_t fan, const bool save = true); + uint8_t getFan(void); + void setMode(const uint8_t mode, const bool save = true); + uint8_t getMode(void); + void setSpecial(const uint8_t mode); + uint8_t getSpecial(void); + bool getTurbo(void); + void setTurbo(const bool on); + bool getSwingToggle(void); + void setSwingToggle(const bool on); + bool getIon(void); + void setIon(const bool on); + bool getEconoToggle(void); + void setEconoToggle(const bool on); + uint16_t getTimerTime(void); + bool getTimerEnabled(void); + bool getTimerType(void); + void setTimer(bool enable, bool timer_type, uint16_t mins); + bool getClean(void); + void setClean(const bool on); + uint8_t* getRaw(void); + void setRaw(const uint8_t new_code[], + const uint16_t length = kSharpAcStateLength); + static bool validChecksum(uint8_t state[], + const uint16_t length = kSharpAcStateLength); + static uint8_t convertMode(const stdAc::opmode_t mode); + static uint8_t convertFan(const stdAc::fanspeed_t speed); + static stdAc::opmode_t toCommonMode(const uint8_t mode); + static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed); + stdAc::state_t toCommon(void); + String toString(void); +#ifndef UNIT_TEST + + private: + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint8_t remote[kSharpAcStateLength]; ///< State of the remote in IR code form + uint8_t _temp; ///< Saved copy of the desired temp. + uint8_t _mode; ///< Saved copy of the desired mode. + uint8_t _fan; ///< Saved copy of the desired fan speed. + void stateReset(void); + void checksum(void); + static uint8_t calcChecksum(uint8_t state[], + const uint16_t length = kSharpAcStateLength); + void setPowerSpecial(const uint8_t value); + uint8_t getPowerSpecial(void); + void clearPowerSpecial(void); +}; + +#endif // IR_SHARP_H_ diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Sherwood.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Sherwood.cpp new file mode 100644 index 000000000..475168721 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Sherwood.cpp @@ -0,0 +1,24 @@ +// Copyright 2017 David Conran + +/// @file +/// @brief Support for Sherwood protocols. + +// Supports: +// Brand: Sherwood, Model: RC-138 remote +// Brand: Sherwood, Model: RD6505(B) Receiver + +#include +#include "IRsend.h" + +#if SEND_SHERWOOD +/// Send an IR command to a Sherwood device. +/// Status: STABLE / Known working. +/// @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. +/// @note Sherwood remote codes appear to be NEC codes with a manditory repeat +/// code. i.e. repeat should be >= kSherwoodMinRepeat (1). +void IRsend::sendSherwood(uint64_t data, uint16_t nbits, uint16_t repeat) { + sendNEC(data, nbits, std::max((uint16_t)kSherwoodMinRepeat, repeat)); +} +#endif // SEND_SHERWOOD diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Sony.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Sony.cpp similarity index 57% rename from lib/IRremoteESP8266-2.7.5/src/ir_Sony.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Sony.cpp index 9ff0c50cc..357fde504 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Sony.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Sony.cpp @@ -2,7 +2,12 @@ // Copyright 2016 marcosamarinho // Copyright 2017,2020 David Conran -// Sony Remote Emulation +/// @file +/// @brief Support for Sony SIRC(Serial Infra-Red Control) protocols. +/// Sony originally added from https://github.com/shirriff/Arduino-IRremote/ +/// Updates from marcosamarinho +/// @see http://www.sbprojects.com/knowledge/ir/sirc.php +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1018 // Supports: // Brand: Sony, Model: HT-CT380 Soundbar (Uses 38kHz & 3 repeats) @@ -12,12 +17,8 @@ #include "IRsend.h" #include "IRutils.h" -// Sony originally added from https://github.com/shirriff/Arduino-IRremote/ -// Updates from marcosamarinho // Constants -// Ref: -// http://www.sbprojects.com/knowledge/ir/sirc.php const uint16_t kSonyTick = 200; const uint16_t kSonyHdrMarkTicks = 12; const uint16_t kSonyHdrMark = kSonyHdrMarkTicks * kSonyTick; @@ -35,80 +36,57 @@ const uint16_t kSonyStdFreq = 40000; // kHz const uint16_t kSonyAltFreq = 38000; // kHz #if SEND_SONY -// Send a standard Sony/SIRC(Serial Infra-Red Control) message. (40kHz) -// -// Args: -// data: message to be sent. -// nbits: Nr. of bits of the message to be sent. -// repeat: Nr. of additional times the message is to be sent. (Default: 2) -// -// Status: STABLE / Known working. -// -// Notes: -// sendSony() should typically be called with repeat=2 as Sony devices -// expect the message to be sent at least 3 times. -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/sirc.php -void IRsend::sendSony(uint64_t data, uint16_t nbits, uint16_t repeat) { +/// Send a standard Sony/SIRC(Serial Infra-Red Control) message. (40kHz) +/// Status: STABLE / Known working. +/// @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. +/// @note sendSony() should typically be called with repeat=2 as Sony devices +/// expect the message to be sent at least 3 times. +void IRsend::sendSony(const uint64_t data, const uint16_t nbits, + const uint16_t repeat) { _sendSony(data, nbits, repeat, kSonyStdFreq); } -// Send an alternative 38kHz Sony/SIRC(Serial Infra-Red Control) message. -// -// Args: -// data: message to be sent. -// nbits: Nr. of bits of the message to be sent. -// repeat: Nr. of additional times the message is to be sent. (Default: 3) -// -// Status: STABLE / Known working. -// -// Notes: -// - `sendSony38()`` should typically be called with repeat=3 as these Sony -// devices expect the message to be sent at least 4 times. -// - Messages send via this method will be detected by this library as just -// `SONY`, not `SONY_38K` as the library has no way to determine the -// modulation frequency used. Hence, there is no `decodeSony38()`. -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/sirc.php -// https://github.com/crankyoldgit/IRremoteESP8266/issues/1018 -void IRsend::sendSony38(uint64_t data, uint16_t nbits, uint16_t repeat) { +/// Send an alternative 38kHz Sony/SIRC(Serial Infra-Red Control) message. +/// Status: STABLE / Known working. +/// @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. +/// @note `sendSony38()` should typically be called with repeat=3 as these Sony +/// devices expect the message to be sent at least 4 times. +/// @warning Messages send via this method will be detected by this library as +/// just `SONY`, not `SONY_38K` as the library has no way to determine the +/// modulation frequency used. Hence, there is no `decodeSony38()`. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1018 +void IRsend::sendSony38(const uint64_t data, const uint16_t nbits, + const uint16_t repeat) { _sendSony(data, nbits, repeat, kSonyAltFreq); } -// Internal procedure to generate a Sony/SIRC(Serial Infra-Red Control) message. -// -// Args: -// data: message to be sent. -// nbits: Nr. of bits of the message to be sent. -// repeat: Nr. of additional times the message is to be sent. -// freq: Frequency of the modulation to transmit at. (Hz or kHz) -// -// Status: STABLE / Known working. -// -// Ref: -// http://www.sbprojects.com/knowledge/ir/sirc.php -void IRsend::_sendSony(uint64_t data, uint16_t nbits, uint16_t repeat, - uint16_t freq) { +/// Internal procedure to generate a Sony/SIRC(Serial Infra-Red Control) message +/// Status: STABLE / Known working. +/// @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. +/// @param[in] freq Frequency of the modulation to transmit at. (Hz or kHz) +void IRsend::_sendSony(const uint64_t data, const uint16_t nbits, + const uint16_t repeat, const uint16_t freq) { sendGeneric(kSonyHdrMark, kSonySpace, kSonyOneMark, kSonySpace, kSonyZeroMark, kSonySpace, 0, // No Footer mark. kSonyMinGap, kSonyRptLength, data, nbits, freq, true, repeat, 33); } -// Convert Sony/SIRC command, address, & extended bits into sendSony format. -// Args: -// nbits: Sony protocol bit size. -// command: Sony command bits. -// address: Sony address bits. -// extended: Sony extended bits. -// Returns: -// A sendSony compatible data message. -// -// Status: STABLE / Should be working. -uint32_t IRsend::encodeSony(uint16_t nbits, uint16_t command, uint16_t address, - uint16_t extended) { +/// Convert Sony/SIRC command, address, & extended bits into sendSony format. +/// Status: STABLE / Should be working. +/// @param[in] nbits Sony protocol bit size. +/// @param[in] command Sony command bits. +/// @param[in] address Sony address bits. +/// @param[in] extended Sony extended bits. +/// @return A `sendSony()` etc compatible data message. +uint32_t IRsend::encodeSony(const uint16_t nbits, const uint16_t command, + const uint16_t address, const uint16_t extended) { uint32_t result = 0; switch (nbits) { case 12: // 5 address bits. @@ -127,26 +105,19 @@ uint32_t IRsend::encodeSony(uint16_t nbits, uint16_t command, uint16_t address, result = (result << 7) | (command & 0x7F); // All sizes have 7 command bits. return reverseBits(result, nbits); // sendSony uses reverse ordered bits. } -#endif +#endif // SEND_SONY #if DECODE_SONY -// Decode the supplied Sony/SIRC message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Should be working. strict mode is ALPHA / Untested. -// -// Notes: -// SONY protocol, SIRC (Serial Infra-Red Control) can be 12,15,20 bits long. -// Ref: -// http://www.sbprojects.com/knowledge/ir/sirc.php +/// Decode the supplied Sony/SIRC message. +/// Status: STABLE / Should be working. strict mode is ALPHA / Untested. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @note SONY protocol, SIRC (Serial Infra-Red Control) can be 12, 15, or 20 +/// bits long. bool IRrecv::decodeSony(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen <= 2 * nbits + kHeader - 1 + offset) @@ -217,4 +188,4 @@ bool IRrecv::decodeSony(decode_results *results, uint16_t offset, } return true; } -#endif +#endif // DECODE_SONY diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Symphony.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Symphony.cpp new file mode 100644 index 000000000..d5fedb29b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Symphony.cpp @@ -0,0 +1,86 @@ +// Copyright 2020 David Conran + +/// @file +/// @brief Support for Symphony protocols. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1057 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1105 +/// @see https://www.alldatasheet.com/datasheet-pdf/pdf/124369/ANALOGICTECH/SM5021B.html + +// Supports: +// Brand: Symphony, Model: Air Cooler 3Di +// Brand: SamHop, Model: SM3015 Fan Remote Control +// Brand: SamHop, Model: SM5021 Encoder chip +// Brand: SamHop, Model: SM5032 Decoder chip +// Brand: Blyss, Model: Owen-SW-5 3 Fan +// Brand: Blyss, Model: WP-YK8 090218 remote +// Brand: Westinghouse, Model: Ceiling fan +// Brand: Westinghouse, Model: 78095 Remote +// Brand: Satellite Electronic, Model: ID6 Remote +// Brand: Satellite Electronic, Model: JY199I Fan driver +// Brand: Satellite Electronic, Model: JY199I-L Fan driver + +#include +#include "IRrecv.h" +#include "IRsend.h" +#include "IRtimer.h" +#include "IRutils.h" + +// Constants +const uint16_t kSymphonyZeroMark = 400; +const uint16_t kSymphonyZeroSpace = 1250; +const uint16_t kSymphonyOneMark = kSymphonyZeroSpace; +const uint16_t kSymphonyOneSpace = kSymphonyZeroMark; +const uint32_t kSymphonyFooterGap = 4 * (kSymphonyZeroMark + + kSymphonyZeroSpace); + +#if SEND_SYMPHONY +/// Send a Symphony packet. +/// Status: STABLE / Should be working. +/// @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::sendSymphony(uint64_t data, uint16_t nbits, uint16_t repeat) { + sendGeneric(0, 0, + kSymphonyOneMark, kSymphonyOneSpace, + kSymphonyZeroMark, kSymphonyZeroSpace, + 0, kSymphonyFooterGap, + data, nbits, 38000, true, repeat, kDutyDefault); +} +#endif // SEND_SYMPHONY + +#if DECODE_SYMPHONY +/// Decode the supplied Symphony packet/message. +/// Status: STABLE / Should be working. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +bool IRrecv::decodeSymphony(decode_results *results, uint16_t offset, + const uint16_t nbits, const bool strict) { + uint64_t data = 0; + + if (results->rawlen < 2 * nbits + offset - 1) + return false; // Not enough entries to ever be SYMPHONY. + // Compliance + if (strict && nbits != kSymphonyBits) return false; + + if (!matchGenericConstBitTime(results->rawbuf + offset, &data, + results->rawlen - offset, + nbits, + 0, 0, // No Header + kSymphonyOneMark, kSymphonyZeroMark, + 0, kSymphonyFooterGap, true, + _tolerance, 0)) + return false; + + // Success + results->value = data; + results->decode_type = decode_type_t::SYMPHONY; + results->bits = nbits; + results->address = 0; + results->command = 0; + return true; +} +#endif // DECODE_SYMPHONY diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Tcl.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Tcl.cpp similarity index 64% rename from lib/IRremoteESP8266-2.7.5/src/ir_Tcl.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Tcl.cpp index ff144e9c1..a818377fd 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Tcl.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Tcl.cpp @@ -1,5 +1,8 @@ // Copyright 2019 David Conran +/// @file +/// @brief Support for TCL protocols. + #include "ir_Tcl.h" #include #include @@ -22,6 +25,11 @@ using irutils::setBit; using irutils::setBits; #if SEND_TCL112AC +/// Send a TCL 112-bit A/C message. +/// Status: Beta / Probably working. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendTcl112Ac(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { sendGeneric(kTcl112AcHdrMark, kTcl112AcHdrSpace, @@ -32,24 +40,29 @@ void IRsend::sendTcl112Ac(const unsigned char data[], const uint16_t nbytes, } #endif // SEND_TCL112AC +/// 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? IRTcl112Ac::IRTcl112Ac(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { stateReset(); } +/// Set up hardware to be able to send a message. void IRTcl112Ac::begin(void) { this->_irsend.begin(); } #if SEND_TCL112AC +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRTcl112Ac::send(const uint16_t repeat) { this->_irsend.sendTcl112Ac(getRaw(), kTcl112AcStateLength, repeat); } #endif // SEND_TCL112AC -// Calculate the checksum for a given array. -// Args: -// state: The array to calculate the checksum over. -// length: The size of the array. -// Returns: -// The 8 bit checksum value. +/// Calculate the checksum for a given state. +/// @param[in] state The array to calc the checksum of. +/// @param[in] length The length/size of the array. +/// @return The calculated checksum value. uint8_t IRTcl112Ac::calcChecksum(uint8_t state[], const uint16_t length) { if (length) return sumBytes(state, length - 1); @@ -57,23 +70,23 @@ uint8_t IRTcl112Ac::calcChecksum(uint8_t state[], const uint16_t length) { return 0; } -// Calculate & set the checksum for the current internal state of the remote. +/// Calculate & set the checksum for the current internal state of the remote. +/// @param[in] length The length/size of the internal array to checksum. void IRTcl112Ac::checksum(const uint16_t length) { // Stored the checksum value in the last byte. if (length > 1) remote_state[length - 1] = calcChecksum(remote_state, length); } -// Verify the checksum is valid for a given state. -// Args: -// state: The array to verify the checksum of. -// length: The size of the state. -// Returns: -// A boolean. +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length/size of the array. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRTcl112Ac::validChecksum(uint8_t state[], const uint16_t length) { return (length > 1 && state[length - 1] == calcChecksum(state, length)); } +/// Reset the internal state of the emulation. (On, Cool, 24C) void IRTcl112Ac::stateReset(void) { // A known good state. (On, Cool, 24C) static const uint8_t reset[kTcl112AcStateLength] = { @@ -82,41 +95,48 @@ void IRTcl112Ac::stateReset(void) { memcpy(remote_state, reset, kTcl112AcStateLength); } +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t* IRTcl112Ac::getRaw(void) { this->checksum(); return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. +/// @param[in] length The length/size of the new_code array. void IRTcl112Ac::setRaw(const uint8_t new_code[], const uint16_t length) { memcpy(remote_state, new_code, std::min(length, kTcl112AcStateLength)); } -// Set the requested power state of the A/C to on. +/// Set the requested power state of the A/C to on. void IRTcl112Ac::on(void) { this->setPower(true); } -// Set the requested power state of the A/C to off. +/// Set the requested power state of the A/C to off. void IRTcl112Ac::off(void) { this->setPower(false); } -// Set the requested power state of the A/C. +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRTcl112Ac::setPower(const bool on) { setBit(&remote_state[5], kTcl112AcPowerOffset, on); } -// Return the requested power state of the A/C. +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRTcl112Ac::getPower(void) { return GETBIT8(remote_state[5], kTcl112AcPowerOffset); } -// Get the requested climate operation mode of the a/c unit. -// Returns: -// A uint8_t containing the A/C mode. +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRTcl112Ac::getMode(void) { return remote_state[6] & 0xF; } -// Set the requested climate operation mode of the a/c unit. -// Note: Fan/Ventilation mode sets the fan speed to high. -// Unknown values default to Auto. +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. +/// @note Fan/Ventilation mode sets the fan speed to high. +/// Unknown values default to Auto. void IRTcl112Ac::setMode(const uint8_t mode) { // If we get an unexpected mode, default to AUTO. switch (mode) { @@ -134,6 +154,9 @@ void IRTcl112Ac::setMode(const uint8_t mode) { } } +/// Set the temperature. +/// @param[in] celsius The temperature in degrees celsius. +/// @note The temperature resolution is 0.5 of a degree. void IRTcl112Ac::setTemp(const float celsius) { // Make sure we have desired temp in the correct range. float safecelsius = std::max(celsius, kTcl112AcTempMin); @@ -146,6 +169,9 @@ void IRTcl112Ac::setTemp(const float celsius) { (uint8_t)kTcl112AcTempMax - nrHalfDegrees / 2); } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. +/// @note The temperature resolution is 0.5 of a degree. float IRTcl112Ac::getTemp(void) { float result = kTcl112AcTempMax - GETBITS8(remote_state[7], kLowNibble, kNibbleSize); @@ -153,8 +179,9 @@ float IRTcl112Ac::getTemp(void) { return result; } -// Set the speed of the fan. -// Unknown speeds will default to Auto. +/// Set the speed of the fan. +/// @param[in] speed The desired setting. +/// @note Unknown speeds will default to Auto. void IRTcl112Ac::setFan(const uint8_t speed) { switch (speed) { case kTcl112AcFanAuto: @@ -168,63 +195,75 @@ void IRTcl112Ac::setFan(const uint8_t speed) { } } -// Return the currect fan speed. +/// Get the current fan speed setting. +/// @return The current fan speed/mode. uint8_t IRTcl112Ac::getFan(void) { return GETBITS8(remote_state[8], kLowNibble, kTcl112AcFanSize); } -// Control economy mode. +/// Set the economy setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRTcl112Ac::setEcono(const bool on) { setBit(&remote_state[5], kTcl112AcBitEconoOffset, on); } -// Return the economy state of the A/C. +/// Get the economy setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRTcl112Ac::getEcono(void) { return GETBIT8(remote_state[5], kTcl112AcBitEconoOffset); } -// Control Health mode. +/// Set the Health (Filter) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRTcl112Ac::setHealth(const bool on) { setBit(&remote_state[6], kTcl112AcBitHealthOffset, on); } -// Return the Health mode state of the A/C. +/// Get the Health (Filter) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRTcl112Ac::getHealth(void) { return GETBIT8(remote_state[6], kTcl112AcBitHealthOffset); } -// Control Light/Display mode. +/// Set the Light (LED/Display) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRTcl112Ac::setLight(const bool on) { setBit(&remote_state[5], kTcl112AcBitLightOffset, !on); // Cleared when on. } -// Return the Light/Display mode state of the A/C. +/// Get the Light (LED/Display) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRTcl112Ac::getLight(void) { return !GETBIT8(remote_state[5], kTcl112AcBitLightOffset); } -// Control Horizontal Swing. +/// Set the horizontal swing setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRTcl112Ac::setSwingHorizontal(const bool on) { setBit(&remote_state[12], kTcl112AcBitSwingHOffset, on); } -// Return the Horizontal Swing state of the A/C. +/// Get the horizontal swing setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRTcl112Ac::getSwingHorizontal(void) { return GETBIT8(remote_state[12], kTcl112AcBitSwingHOffset); } -// Control Vertical Swing. +/// Set the vertical swing setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRTcl112Ac::setSwingVertical(const bool on) { setBits(&remote_state[8], kTcl112AcSwingVOffset, kTcl112AcSwingVSize, on ? kTcl112AcSwingVOn : kTcl112AcSwingVOff); } -// Return the Vertical Swing state of the A/C. +/// Get the vertical swing setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRTcl112Ac::getSwingVertical(void) { return GETBITS8(remote_state[8], kTcl112AcSwingVOffset, kTcl112AcSwingVSize); } -// Control the Turbo setting. +/// Set the Turbo setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRTcl112Ac::setTurbo(const bool on) { setBit(&remote_state[6], kTcl112AcBitTurboOffset, on); if (on) { @@ -233,12 +272,15 @@ void IRTcl112Ac::setTurbo(const bool on) { } } -// Return the Turbo setting state of the A/C. +/// Get the Turbo setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRTcl112Ac::getTurbo(void) { return GETBIT8(remote_state[6], kTcl112AcBitTurboOffset); } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRTcl112Ac::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kTcl112AcCool; @@ -249,7 +291,9 @@ uint8_t IRTcl112Ac::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRTcl112Ac::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: @@ -261,7 +305,9 @@ uint8_t IRTcl112Ac::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRTcl112Ac::toCommonMode(const uint8_t mode) { switch (mode) { case kTcl112AcCool: return stdAc::opmode_t::kCool; @@ -272,7 +318,9 @@ stdAc::opmode_t IRTcl112Ac::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] spd The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRTcl112Ac::toCommonFanSpeed(const uint8_t spd) { switch (spd) { case kTcl112AcFanHigh: return stdAc::fanspeed_t::kMax; @@ -282,7 +330,8 @@ stdAc::fanspeed_t IRTcl112Ac::toCommonFanSpeed(const uint8_t spd) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRTcl112Ac::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::TCL112AC; @@ -309,7 +358,8 @@ stdAc::state_t IRTcl112Ac::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRTcl112Ac::toString(void) { String result = ""; result.reserve(140); // Reserve some heap for the string to reduce fragging. @@ -332,7 +382,8 @@ String IRTcl112Ac::toString(void) { } #if DECODE_TCL112AC -// NOTE: There is no `decodedecodeTcl112Ac()`. -// It's the same as `decodeMitsubishi112()`. A shared routine is used. -// You can find it in: ir_Mitsubishi.cpp +/// @file +/// @note There is no `decodedecodeTcl112Ac()`. +/// It's the same as `decodeMitsubishi112()`. A shared routine is used. +/// You can find it in: ir_Mitsubishi.cpp #endif // DECODE_TCL112AC diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Tcl.h b/lib/IRremoteESP8266-2.7.8/src/ir_Tcl.h similarity index 82% rename from lib/IRremoteESP8266-2.7.5/src/ir_Tcl.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Tcl.h index 21e64a55a..940b68113 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Tcl.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Tcl.h @@ -1,5 +1,8 @@ // Copyright 2019 David Conran +/// @file +/// @brief Support for TCL protocols. + // Supports: // Brand: Leberg, Model: LBS-TOR07 A/C @@ -55,17 +58,22 @@ const uint8_t kTcl112AcSwingVOn = 0b111; const uint8_t kTcl112AcSwingVOff = 0b000; const uint8_t kTcl112AcBitTurboOffset = 6; - +// Classes +/// Class for handling detailed TCL A/C messages. class IRTcl112Ac { public: explicit IRTcl112Ac(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - #if SEND_TCL112AC void send(const uint16_t repeat = kTcl112AcDefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + /// 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_TCL void begin(void); + void stateReset(void); uint8_t* getRaw(void); void setRaw(const uint8_t new_code[], const uint16_t length = kTcl112AcStateLength); @@ -104,12 +112,13 @@ class IRTcl112Ac { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - uint8_t remote_state[kTcl112AcStateLength]; - void stateReset(void); + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint8_t remote_state[kTcl112AcStateLength]; ///< The State in IR code form. void checksum(const uint16_t length = kTcl112AcStateLength); }; diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Teco.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Teco.cpp similarity index 65% rename from lib/IRremoteESP8266-2.7.5/src/ir_Teco.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Teco.cpp index 8e33e04ec..733be6247 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Teco.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Teco.cpp @@ -1,7 +1,7 @@ // Copyright 2019 Fabien Valthier -/* -Node MCU/ESP8266 Sketch to emulate Teco -*/ + +/// @file +/// @brief Support for Teco protocols. #include "ir_Teco.h" #include @@ -31,12 +31,11 @@ using irutils::setBit; using irutils::setBits; #if SEND_TECO -// Send a Teco A/C message. -// -// Args: -// data: Contents of the message to be sent. -// nbits: Nr. of bits of data to be sent. Typically kTecoBits. -// repeat: Nr. of additional times the message is to be sent. +/// Send a Teco A/C message. +/// Status: Beta / Probably working. +/// @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::sendTeco(const uint64_t data, const uint16_t nbits, const uint16_t repeat) { sendGeneric(kTecoHdrMark, kTecoHdrSpace, kTecoBitMark, kTecoOneSpace, @@ -45,40 +44,59 @@ void IRsend::sendTeco(const uint64_t data, const uint16_t nbits, } #endif // SEND_TECO -// Class for decoding and constructing Teco AC messages. +/// 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? IRTecoAc::IRTecoAc(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { this->stateReset(); } +/// Set up hardware to be able to send a message. void IRTecoAc::begin(void) { _irsend.begin(); } #if SEND_TECO +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRTecoAc::send(const uint16_t repeat) { _irsend.sendTeco(remote_state, kTecoBits, repeat); } #endif // SEND_TECO +/// Reset the internal state of the emulation. +/// @note Mode:auto, Power:Off, fan:auto, temp:16, swing:off, sleep:off void IRTecoAc::stateReset(void) { - // Mode:auto, Power:Off, fan:auto, temp:16, swing:off, sleep:off remote_state = kTecoReset; } +/// Get a copy of the internal state/code for this protocol. +/// @return A code for this protocol based on the current internal state. uint64_t IRTecoAc::getRaw(void) { return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. void IRTecoAc::setRaw(const uint64_t new_code) { remote_state = new_code; } +/// Set the requested power state of the A/C to on. void IRTecoAc::on(void) { setPower(true); } +/// Set the requested power state of the A/C to off. void IRTecoAc::off(void) { setPower(false); } +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRTecoAc::setPower(const bool on) { setBit(&remote_state, kTecoPowerOffset, on); } +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRTecoAc::getPower(void) { return GETBIT64(remote_state, kTecoPowerOffset); } +/// Set the temperature. +/// @param[in] temp The temperature in degrees celsius. void IRTecoAc::setTemp(const uint8_t temp) { uint8_t newtemp = temp; newtemp = std::min(newtemp, kTecoMaxTemp); @@ -87,11 +105,14 @@ void IRTecoAc::setTemp(const uint8_t temp) { newtemp - kTecoMinTemp); } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRTecoAc::getTemp(void) { return GETBITS64(remote_state, kTecoTempOffset, kTecoTempSize) + kTecoMinTemp; } -// Set the speed of the fan +/// Set the speed of the fan. +/// @param[in] speed The desired setting. void IRTecoAc::setFan(const uint8_t speed) { uint8_t newspeed = speed; switch (speed) { @@ -104,10 +125,14 @@ void IRTecoAc::setFan(const uint8_t speed) { setBits(&remote_state, kTecoFanOffset, kTecoFanSize, newspeed); } +/// Get the current fan speed setting. +/// @return The current fan speed/mode. uint8_t IRTecoAc::getFan(void) { return GETBITS64(remote_state, kTecoFanOffset, kTecoFanSize); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRTecoAc::setMode(const uint8_t mode) { uint8_t newmode = mode; switch (mode) { @@ -121,54 +146,80 @@ void IRTecoAc::setMode(const uint8_t mode) { setBits(&remote_state, kTecoModeOffset, kModeBitsSize, newmode); } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRTecoAc::getMode(void) { return GETBITS64(remote_state, kTecoModeOffset, kModeBitsSize); } +/// Set the (vertical) swing setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRTecoAc::setSwing(const bool on) { setBit(&remote_state, kTecoSwingOffset, on); } +/// Get the (vertical) swing setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRTecoAc::getSwing(void) { return GETBIT64(remote_state, kTecoSwingOffset); } +/// Set the Sleep setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRTecoAc::setSleep(const bool on) { setBit(&remote_state, kTecoSleepOffset, on); } +/// Get the Sleep setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRTecoAc::getSleep(void) { return GETBIT64(remote_state, kTecoSleepOffset); } +/// Set the Light (LED/Display) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRTecoAc::setLight(const bool on) { setBit(&remote_state, kTecoLightOffset, on); } +/// Get the Light (LED/Display) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRTecoAc::getLight(void) { return GETBIT64(remote_state, kTecoLightOffset); } +/// Set the Humid setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRTecoAc::setHumid(const bool on) { setBit(&remote_state, kTecoHumidOffset, on); } +/// Get the Humid setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRTecoAc::getHumid(void) { return GETBIT64(remote_state, kTecoHumidOffset); } +/// Set the Save setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRTecoAc::setSave(const bool on) { setBit(&remote_state, kTecoSaveOffset, on); } +/// Get the Save setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRTecoAc::getSave(void) { return GETBIT64(remote_state, kTecoSaveOffset); } +/// Is the timer function enabled? +/// @return true, the setting is on. false, the setting is off. bool IRTecoAc::getTimerEnabled(void) { return GETBIT64(remote_state, kTecoTimerOnOffset); } +/// Get the timer time for when the A/C unit will switch power state. +/// @return The number of minutes left on the timer. `0` means off. uint16_t IRTecoAc::getTimer(void) { uint16_t mins = 0; if (getTimerEnabled()) { @@ -181,11 +232,10 @@ uint16_t IRTecoAc::getTimer(void) { return mins; } -// Set the timer for when the A/C unit will switch power state. -// Args: -// nr_mins: Number of minutes before power state change. -// `0` will clear the timer. Max is 24 hrs. -// Time is stored internaly in increments of 30 mins. +/// Set the timer for when the A/C unit will switch power state. +/// @param[in] nr_mins Number of minutes before power state change. +/// `0` will clear the timer. Max is 24 hrs. +/// @note Time is stored internaly in increments of 30 mins. void IRTecoAc::setTimer(const uint16_t nr_mins) { uint16_t mins = std::min(nr_mins, (uint16_t)(24 * 60)); // Limit to 24 hrs. uint8_t hours = mins / 60; @@ -200,7 +250,9 @@ void IRTecoAc::setTimer(const uint16_t nr_mins) { hours / 10); } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRTecoAc::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kTecoCool; @@ -211,7 +263,9 @@ uint8_t IRTecoAc::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRTecoAc::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: @@ -223,7 +277,9 @@ uint8_t IRTecoAc::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRTecoAc::toCommonMode(const uint8_t mode) { switch (mode) { case kTecoCool: return stdAc::opmode_t::kCool; @@ -234,7 +290,9 @@ stdAc::opmode_t IRTecoAc::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRTecoAc::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kTecoFanHigh: return stdAc::fanspeed_t::kMax; @@ -244,7 +302,8 @@ stdAc::fanspeed_t IRTecoAc::toCommonFanSpeed(const uint8_t speed) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRTecoAc::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::TECO; @@ -270,7 +329,8 @@ stdAc::state_t IRTecoAc::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRTecoAc::toString(void) { String result = ""; result.reserve(100); // Reserve some heap for the string to reduce fragging. @@ -294,18 +354,14 @@ String IRTecoAc::toString(void) { } #if DECODE_TECO -// Decode the supplied Teco message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kTecoBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Tested. +/// Decode the supplied Teco message. +/// Status: STABLE / Tested. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. bool IRrecv::decodeTeco(decode_results* results, uint16_t offset, const uint16_t nbits, const bool strict) { if (strict && nbits != kTecoBits) return false; // Not what is expected diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Teco.h b/lib/IRremoteESP8266-2.7.8/src/ir_Teco.h similarity index 85% rename from lib/IRremoteESP8266-2.7.5/src/ir_Teco.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Teco.h index 8bee1b72b..770890caa 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Teco.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Teco.h @@ -1,5 +1,12 @@ // Copyright 2019 Fabien Valthier +/// @file +/// @brief Support for Teco protocols. + +// Supports: +// Brand: Alaska, Model: SAC9010QC A/C +// Brand: Alaska, Model: SAC9010QC remote + #ifndef IR_TECO_H_ #define IR_TECO_H_ @@ -12,10 +19,6 @@ #include "IRsend_test.h" #endif -// Supports: -// Brand: Alaska, Model: SAC9010QC A/C -// Brand: Alaska, Model: SAC9010QC remote - // Constants. const uint8_t kTecoAuto = 0; const uint8_t kTecoCool = 1; @@ -100,14 +103,19 @@ const uint64_t kTecoReset = 0b01001010000000000000010000000000000; */ // Classes +/// Class for handling detailed Teco A/C messages. class IRTecoAc { public: explicit IRTecoAc(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - void stateReset(void); #if SEND_TECO void send(const uint16_t repeat = kTecoDefaultRepeat); + /// 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_TECO void begin(void); void on(void); @@ -155,12 +163,13 @@ class IRTecoAc { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - // The state of the IR remote in IR code form. - uint64_t remote_state; + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint64_t remote_state; ///< The state of the IR remote in IR code form. bool getTimerEnabled(void); }; diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Toshiba.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Toshiba.cpp similarity index 68% rename from lib/IRremoteESP8266-2.7.5/src/ir_Toshiba.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Toshiba.cpp index 3113e1b09..c28b700f8 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Toshiba.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Toshiba.cpp @@ -1,7 +1,9 @@ // Copyright 2017 David Conran -// Toshiba A/C support added by David Conran - +/// @file +/// @brief Support for Toshiba protocols. +/// @see https://github.com/r45635/HVAC-IR-Control +/// @see https://github.com/r45635/HVAC-IR-Control/blob/master/HVAC_ESP8266/HVAC_ESP8266T.ino#L77 #include "ir_Toshiba.h" #include @@ -14,18 +16,9 @@ #include "IRtext.h" #include "IRutils.h" -// -// Equipment it seems compatible with: -// * Toshiba RAS-B13N3KV2 / Akita EVO II -// * Toshiba RAS-B13N3KVP-E, RAS 18SKP-ES -// * Toshiba WH-TA04NE, WC-L03SE -// * - // Constants // Toshiba A/C -// Ref: -// https://github.com/r45635/HVAC-IR-Control/blob/master/HVAC_ESP8266/HVAC_ESP8266T.ino#L77 const uint16_t kToshibaAcHdrMark = 4400; const uint16_t kToshibaAcHdrSpace = 4300; const uint16_t kToshibaAcBitMark = 543; @@ -43,16 +36,11 @@ using irutils::setBit; using irutils::setBits; #if SEND_TOSHIBA_AC -// Send a Toshiba A/C message. -// -// Args: -// data: An array of bytes containing the IR command. -// nbytes: Nr. of bytes of data in the array. (>=kToshibaACStateLength) -// repeat: Nr. of times the message is to be repeated. -// (Default = kToshibaACMinRepeat). -// -// Status: StABLE / Working. -// +/// Send a Toshiba A/C message. +/// Status: STABLE / Working. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendToshibaAC(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { if (nbytes < kToshibaACStateLength) @@ -64,56 +52,52 @@ void IRsend::sendToshibaAC(const unsigned char data[], const uint16_t nbytes, } #endif // SEND_TOSHIBA_AC -// Code to emulate Toshiba A/C IR remote control unit. -// Inspired and derived from the work done at: -// https://github.com/r45635/HVAC-IR-Control -// -// Status: STABLE / Working. -// -// Initialise the object. +/// 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? IRToshibaAC::IRToshibaAC(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { this->stateReset(); } -// Reset the state of the remote to a known good state/sequence. +/// Reset the state of the remote to a known good state/sequence. +/// @see https://github.com/r45635/HVAC-IR-Control/blob/master/HVAC_ESP8266/HVAC_ESP8266T.ino#L103 void IRToshibaAC::stateReset(void) { - // The state of the IR remote in IR code form. - // Known good state obtained from: - // https://github.com/r45635/HVAC-IR-Control/blob/master/HVAC_ESP8266/HVAC_ESP8266T.ino#L103 static const uint8_t kReset[kToshibaACStateLength] = { 0xF2, 0x0D, 0x03, 0xFC, 0x01}; memcpy(remote_state, kReset, kToshibaACStateLength); mode_state = getMode(true); } -// Configure the pin for output. +/// Set up hardware to be able to send a message. void IRToshibaAC::begin(void) { _irsend.begin(); } #if SEND_TOSHIBA_AC -// Send the current desired state to the IR LED. +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRToshibaAC::send(const uint16_t repeat) { _irsend.sendToshibaAC(getRaw(), kToshibaACStateLength, repeat); } #endif // SEND_TOSHIBA_AC -// Return a pointer to the internal state date of the remote. +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t* IRToshibaAC::getRaw(void) { this->checksum(); return remote_state; } -// Override the internal state with the new state. +/// Set the internal state from a valid code for this protocol. +/// @param[in] newState A valid code for this protocol. void IRToshibaAC::setRaw(const uint8_t newState[]) { memcpy(remote_state, newState, kToshibaACStateLength); mode_state = this->getMode(true); } -// Calculate the checksum for a given array. -// Args: -// state: The array to calculate the checksum over. -// length: The size of the array. -// Returns: -// The 8 bit checksum value. +/// Calculate the checksum for a given state. +/// @param[in] state The array to calc the checksum of. +/// @param[in] length The length/size of the array. +/// @return The calculated checksum value. uint8_t IRToshibaAC::calcChecksum(const uint8_t state[], const uint16_t length) { uint8_t checksum = 0; @@ -125,31 +109,32 @@ uint8_t IRToshibaAC::calcChecksum(const uint8_t state[], return checksum; } -// Verify the checksum is valid for a given state. -// Args: -// state: The array to verify the checksum of. -// length: The size of the state. -// Returns: -// A boolean. +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length/size of the array. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRToshibaAC::validChecksum(const uint8_t state[], const uint16_t length) { return (length > 1 && state[length - 1] == IRToshibaAC::calcChecksum(state, length)); } -// Calculate & set the checksum for the current internal state of the remote. +/// Calculate & set the checksum for the current internal state of the remote. +/// @param[in] length The length/size of the internal array to checksum. + void IRToshibaAC::checksum(const uint16_t length) { // Stored the checksum value in the last byte. if (length > 1) remote_state[length - 1] = this->calcChecksum(remote_state, length); } -// Set the requested power state of the A/C to on. +/// Set the requested power state of the A/C to on. void IRToshibaAC::on(void) { setPower(true); } -// Set the requested power state of the A/C to off. +/// Set the requested power state of the A/C to off. void IRToshibaAC::off(void) { setPower(false); } -// Set the requested power state of the A/C. +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRToshibaAC::setPower(const bool on) { setBit(&remote_state[6], kToshibaAcPowerOffset, !on); // Cleared when on. if (on) @@ -159,12 +144,15 @@ void IRToshibaAC::setPower(const bool on) { kToshibaAcHeat); } -// Return the requested power state of the A/C. + +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRToshibaAC::getPower(void) { return !GETBIT8(remote_state[6], kToshibaAcPowerOffset); } -// Set the temp. in deg C +/// Set the temperature. +/// @param[in] degrees The temperature in degrees celsius. void IRToshibaAC::setTemp(const uint8_t degrees) { uint8_t temp = std::max((uint8_t)kToshibaAcMinTemp, degrees); temp = std::min((uint8_t)kToshibaAcMaxTemp, temp); @@ -172,14 +160,15 @@ void IRToshibaAC::setTemp(const uint8_t degrees) { temp - kToshibaAcMinTemp); } -// Return the set temp. in deg C +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRToshibaAC::getTemp(void) { return GETBITS8(remote_state[5], kToshibaAcTempOffset, kToshibaAcTempSize) + kToshibaAcMinTemp; } -// Set the speed of the fan, 0-5. -// 0 is auto, 1-5 is the speed, 5 is Max. +/// Set the speed of the fan. +/// @param[in] speed The desired setting (0 is Auto, 1-5 is the speed, 5 is Max) void IRToshibaAC::setFan(const uint8_t speed) { uint8_t fan = speed; // Bounds check @@ -189,7 +178,8 @@ void IRToshibaAC::setFan(const uint8_t speed) { setBits(&remote_state[6], kToshibaAcFanOffset, kToshibaAcFanSize, fan); } -// Return the requested state of the unit's fan. +/// Get the current fan speed setting. +/// @return The current fan speed/mode. uint8_t IRToshibaAC::getFan(void) { uint8_t fan = GETBITS8(remote_state[6], kToshibaAcFanOffset, kToshibaAcFanSize); @@ -197,11 +187,9 @@ uint8_t IRToshibaAC::getFan(void) { return --fan; } -// Get the requested climate operation mode of the a/c unit. -// Args: -// useRaw: Indicate to get the mode from the state array. (Default: false) -// Returns: -// A uint8_t containing the A/C mode. +/// Get the operating mode setting of the A/C. +/// @param[in] useRaw Indicate to get the mode from the internal state array. +/// @return The current operating mode setting. uint8_t IRToshibaAC::getMode(const bool useRaw) { if (useRaw) return GETBITS8(remote_state[6], kToshibaAcModeOffset, kToshibaAcModeSize); @@ -209,9 +197,10 @@ uint8_t IRToshibaAC::getMode(const bool useRaw) { return mode_state; } -// Set the requested climate operation mode of the a/c unit. +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. +/// @note If we get an unexpected mode, default to AUTO. void IRToshibaAC::setMode(const uint8_t mode) { - // If we get an unexpected mode, default to AUTO. switch (mode) { case kToshibaAcAuto: case kToshibaAcCool: @@ -227,7 +216,9 @@ void IRToshibaAC::setMode(const uint8_t mode) { } } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRToshibaAC::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kToshibaAcCool; @@ -238,7 +229,9 @@ uint8_t IRToshibaAC::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRToshibaAC::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: return kToshibaAcFanMax - 4; @@ -250,7 +243,9 @@ uint8_t IRToshibaAC::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRToshibaAC::toCommonMode(const uint8_t mode) { switch (mode) { case kToshibaAcCool: return stdAc::opmode_t::kCool; @@ -260,7 +255,9 @@ stdAc::opmode_t IRToshibaAC::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] spd The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRToshibaAC::toCommonFanSpeed(const uint8_t spd) { switch (spd) { case kToshibaAcFanMax: return stdAc::fanspeed_t::kMax; @@ -272,7 +269,8 @@ stdAc::fanspeed_t IRToshibaAC::toCommonFanSpeed(const uint8_t spd) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRToshibaAC::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::TOSHIBA_AC; @@ -297,7 +295,8 @@ stdAc::state_t IRToshibaAC::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRToshibaAC::toString(void) { String result = ""; result.reserve(40); @@ -312,21 +311,14 @@ String IRToshibaAC::toString(void) { } #if DECODE_TOSHIBA_AC -// Decode a Toshiba AC IR message if possible. -// Places successful decode information in the results pointer. -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kToshibaACBits. -// strict: Flag to indicate if we strictly adhere to the specification. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Working. -// -// Ref: -// +/// Decode the supplied Toshiba A/C message. +/// Status: STABLE / Working. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. bool IRrecv::decodeToshibaAC(decode_results* results, uint16_t offset, const uint16_t nbits, const bool strict) { // Compliance diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Toshiba.h b/lib/IRremoteESP8266-2.7.8/src/ir_Toshiba.h similarity index 77% rename from lib/IRremoteESP8266-2.7.5/src/ir_Toshiba.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Toshiba.h index 7a679ceda..0e5022ae7 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Toshiba.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Toshiba.h @@ -1,6 +1,9 @@ // Copyright 2017 David Conran -// Toshiba A/C support added by David Conran +/// @file +/// @brief Support for Toshiba protocols. +/// @see https://github.com/r45635/HVAC-IR-Control +/// @see https://github.com/r45635/HVAC-IR-Control/blob/master/HVAC_ESP8266/HVAC_ESP8266T.ino#L77 // Supports: // Brand: Toshiba, Model: RAS-B13N3KV2 @@ -54,15 +57,20 @@ const uint8_t kToshibaAcMaxTemp = 30; // 30C #define TOSHIBA_AC_MIN_TEMP kToshibaAcMinTemp #define TOSHIBA_AC_MAX_TEMP kToshibaAcMaxTemp +// Classes +/// Class for handling detailed Toshiba A/C messages. class IRToshibaAC { public: explicit IRToshibaAC(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - void stateReset(void); #if SEND_TOSHIBA_AC void send(const uint16_t repeat = kToshibaACMinRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + /// 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_TOSHIBA_AC void begin(void); void on(void); @@ -88,11 +96,13 @@ class IRToshibaAC { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - uint8_t remote_state[kToshibaACStateLength]; + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint8_t remote_state[kToshibaACStateLength]; ///< The state in IR code form. void checksum(const uint16_t length = kToshibaACStateLength); static uint8_t calcChecksum(const uint8_t state[], const uint16_t length = kToshibaACStateLength); diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Trotec.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Trotec.cpp similarity index 65% rename from lib/IRremoteESP8266-2.7.5/src/ir_Trotec.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Trotec.cpp index d8b87e034..c2e4d5c00 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Trotec.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Trotec.cpp @@ -1,6 +1,11 @@ // Copyright 2017 stufisher // Copyright 2019 crankyoldgit +/// @file +/// @brief Support for Trotec protocols. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/pull/279 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1176 + #include "ir_Trotec.h" #include #include @@ -30,7 +35,11 @@ using irutils::setBit; using irutils::setBits; #if SEND_TROTEC - +/// Send a Trotec message. +/// Status: Beta / Probably Working. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendTrotec(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { if (nbytes < kTrotecStateLength) return; @@ -49,33 +58,49 @@ void IRsend::sendTrotec(const unsigned char data[], const uint16_t nbytes, } #endif // SEND_TROTEC +/// 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? IRTrotecESP::IRTrotecESP(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { this->stateReset(); } +/// Set up hardware to be able to send a message. void IRTrotecESP::begin(void) { _irsend.begin(); } #if SEND_TROTEC +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. void IRTrotecESP::send(const uint16_t repeat) { - this->checksum(); - _irsend.sendTrotec(remote_state, kTrotecStateLength, repeat); + _irsend.sendTrotec(getRaw(), kTrotecStateLength, repeat); } #endif // SEND_TROTEC +/// Calculate the checksum for a given state. +/// @param[in] state The array to calc the checksum of. +/// @param[in] length The length/size of the array. +/// @return The calculated checksum value. uint8_t IRTrotecESP::calcChecksum(const uint8_t state[], const uint16_t length) { return sumBytes(state + 2, length - 3); } +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length/size of the array. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRTrotecESP::validChecksum(const uint8_t state[], const uint16_t length) { return state[length - 1] == calcChecksum(state, length); } +/// Calculate & set the checksum for the current internal state of the remote. void IRTrotecESP::checksum(void) { remote_state[kTrotecStateLength - 1] = sumBytes(remote_state + 2, kTrotecStateLength - 3); } +/// Reset the state of the remote to a known good state/sequence. void IRTrotecESP::stateReset(void) { for (uint8_t i = 2; i < kTrotecStateLength; i++) remote_state[i] = 0x0; @@ -88,41 +113,65 @@ void IRTrotecESP::stateReset(void) { this->setMode(kTrotecAuto); } +/// Get a PTR to the internal state/code for this protocol. +/// @return PTR to a code for this protocol based on the current internal state. uint8_t* IRTrotecESP::getRaw(void) { this->checksum(); return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] state A valid code for this protocol. void IRTrotecESP::setRaw(const uint8_t state[]) { memcpy(remote_state, state, kTrotecStateLength); } +/// Set the requested power state of the A/C to on. +void IRTrotecESP::on(void) { this->setPower(true); } + +/// Set the requested power state of the A/C to off. +void IRTrotecESP::off(void) { this->setPower(false); } + +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRTrotecESP::setPower(const bool on) { setBit(&remote_state[2], kTrotecPowerBitOffset, on); } +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRTrotecESP::getPower(void) { return GETBIT8(remote_state[2], kTrotecPowerBitOffset); } +/// Set the speed of the fan. +/// @param[in] fan The desired setting. void IRTrotecESP::setSpeed(const uint8_t fan) { uint8_t speed = std::min(fan, kTrotecFanHigh); setBits(&remote_state[2], kTrotecFanOffset, kTrotecFanSize, speed); } +/// Get the current fan speed setting. +/// @return The current fan speed/mode. uint8_t IRTrotecESP::getSpeed(void) { return GETBITS8(remote_state[2], kTrotecFanOffset, kTrotecFanSize); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRTrotecESP::setMode(const uint8_t mode) { setBits(&remote_state[2], kTrotecModeOffset, kTrotecModeSize, (mode > kTrotecFan) ? kTrotecAuto : mode); } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRTrotecESP::getMode(void) { return GETBITS8(remote_state[2], kTrotecModeOffset, kTrotecModeSize); } +/// Set the temperature. +/// @param[in] celsius The temperature in degrees celsius. void IRTrotecESP::setTemp(const uint8_t celsius) { uint8_t temp = std::max(celsius, kTrotecMinTemp); temp = std::min(temp, kTrotecMaxTemp); @@ -130,27 +179,39 @@ void IRTrotecESP::setTemp(const uint8_t celsius) { temp - kTrotecMinTemp); } +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRTrotecESP::getTemp(void) { return GETBITS8(remote_state[3], kTrotecTempOffset, kTrotecTempSize) + kTrotecMinTemp; } +/// Set the Sleep setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRTrotecESP::setSleep(const bool on) { setBit(&remote_state[3], kTrotecSleepBitOffset, on); } +/// Get the Sleep setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRTrotecESP::getSleep(void) { return GETBIT8(remote_state[3], kTrotecSleepBitOffset); } +/// Set the timer time in nr. of Hours. +/// @param[in] timer Nr. of Hours. Max is `kTrotecMaxTimer` void IRTrotecESP::setTimer(const uint8_t timer) { setBit(&remote_state[5], kTrotecTimerBitOffset, timer); remote_state[6] = (timer > kTrotecMaxTimer) ? kTrotecMaxTimer : timer; } +/// Get the timer time in nr. of Hours. +/// @return Nr. of Hours. uint8_t IRTrotecESP::getTimer(void) { return remote_state[6]; } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRTrotecESP::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kTrotecCool; @@ -161,7 +222,9 @@ uint8_t IRTrotecESP::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRTrotecESP::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: @@ -173,8 +236,9 @@ uint8_t IRTrotecESP::convertFan(const stdAc::fanspeed_t speed) { } } - -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRTrotecESP::toCommonMode(const uint8_t mode) { switch (mode) { case kTrotecCool: return stdAc::opmode_t::kCool; @@ -184,7 +248,9 @@ stdAc::opmode_t IRTrotecESP::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] spd The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRTrotecESP::toCommonFanSpeed(const uint8_t spd) { switch (spd) { case kTrotecFanHigh: return stdAc::fanspeed_t::kMax; @@ -194,7 +260,8 @@ stdAc::fanspeed_t IRTrotecESP::toCommonFanSpeed(const uint8_t spd) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRTrotecESP::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::TROTEC; @@ -219,7 +286,8 @@ stdAc::state_t IRTrotecESP::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRTrotecESP::toString(void) { String result = ""; result.reserve(100); // Reserve some heap for the string to reduce fragging. @@ -234,24 +302,18 @@ String IRTrotecESP::toString(void) { } #if DECODE_TROTEC -// Decode the supplied Trotec message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kTrotecBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Works. Untested on real devices. -// -// Ref: +/// Decode the supplied Trotec message. +/// Status: STABLE / Works. Untested on real devices. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. bool IRrecv::decodeTrotec(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen <= 2 * nbits + kHeader + 2 * kFooter - 1 + offset) - return false; // Can't possibly be a valid Samsung A/C message. + return false; // Can't possibly be a valid Trotec A/C message. if (strict && nbits != kTrotecBits) return false; uint16_t used; diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Trotec.h b/lib/IRremoteESP8266-2.7.8/src/ir_Trotec.h similarity index 73% rename from lib/IRremoteESP8266-2.7.5/src/ir_Trotec.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Trotec.h index f836b2e5e..951bdf7b2 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Trotec.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Trotec.h @@ -1,6 +1,15 @@ // Copyright 2017 stufisher // Copyright 2019 crankyoldgit +/// @file +/// @brief Support for Trotec protocols. +/// @see https://github.com/crankyoldgit/IRremoteESP8266/pull/279 +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1176 + +// Supports: +// Brand: Trotec, Model: PAC 3200 A/C +// Brand: Duux, Model: Blizzard Smart 10K / DXMA04 A/C + #ifndef IR_TROTEC_H_ #define IR_TROTEC_H_ @@ -62,17 +71,25 @@ const uint8_t kTrotecMaxTimer = 23; #define TROTEC_MAX_TEMP kTrotecMaxTemp #define TROTEC_MAX_TIMER kTrotecMaxTimer +// Class +/// Class for handling detailed Trotec A/C messages. class IRTrotecESP { public: explicit IRTrotecESP(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - #if SEND_TROTEC void send(const uint16_t repeat = kTrotecDefaultRepeat); - uint8_t calibrate(void) { return _irsend.calibrate(); } + /// 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_TROTEC void begin(void); + void stateReset(void); + void on(void); + void off(void); void setPower(const bool state); bool getPower(void); @@ -104,14 +121,15 @@ class IRTrotecESP { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - uint8_t remote_state[kTrotecStateLength]; + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint8_t remote_state[kTrotecStateLength]; ///< Remote state in IR code form. static uint8_t calcChecksum(const uint8_t state[], const uint16_t length = kTrotecStateLength); - void stateReset(void); void checksum(void); }; diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Vestel.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Vestel.cpp similarity index 67% rename from lib/IRremoteESP8266-2.7.5/src/ir_Vestel.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Vestel.cpp index 4378497e0..0a67c4e59 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Vestel.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Vestel.cpp @@ -1,7 +1,9 @@ // Copyright 2018 Erdem U. Altinyurt // Copyright 2019 David Conran -// Vestel added by Erdem U. Altinyurt +/// @file +/// @brief Support for Vestel protocols. +/// Vestel added by Erdem U. Altinyurt #include "ir_Vestel.h" #include @@ -15,10 +17,6 @@ #include "IRutils.h" #include "ir_Haier.h" -// Equipment it seems compatible with: -// * Vestel AC Model BIOX CXP-9 (9K BTU) -// * - // Ref: // None. Totally reverse engineered. @@ -32,14 +30,11 @@ using irutils::setBit; using irutils::setBits; #if SEND_VESTEL_AC -// Send a Vestel message -// -// Args: -// data: Contents of the message to be sent. -// nbits: Nr. of bits of data to be sent. Typically kVestelBits. -// -// Status: STABLE / Working. -// +/// Send a Vestel message +/// Status: STABLE / Working. +/// @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::sendVestelAc(const uint64_t data, const uint16_t nbits, const uint16_t repeat) { if (nbits % 8 != 0) return; // nbits is required to be a multiple of 8. @@ -50,41 +45,45 @@ void IRsend::sendVestelAc(const uint64_t data, const uint16_t nbits, kVestelAcBitMark, 100000, // Footer + repeat gap data, nbits, 38, false, repeat, 50); } -#endif +#endif // SEND_VESTEL_AC -// Code to emulate Vestel A/C IR remote control unit. - -// Initialise the object. +/// 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? IRVestelAc::IRVestelAc(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { this->stateReset(); } -// Reset the state of the remote to a known good state/sequence. +/// Reset the state of the remote to a known good state/sequence. +/// @note Power On, Mode Auto, Fan Auto, Temp = 25C/77F void IRVestelAc::stateReset(void) { - // Power On, Mode Auto, Fan Auto, Temp = 25C/77F remote_state = kVestelAcStateDefault; remote_time_state = kVestelAcTimeStateDefault; use_time_state = false; } -// Configure the pin for output. -void IRVestelAc::begin(void) { - _irsend.begin(); -} +/// Set up hardware to be able to send a message. +void IRVestelAc::begin(void) { _irsend.begin(); } #if SEND_VESTEL_AC -// Send the current desired state to the IR LED. -void IRVestelAc::send(void) { _irsend.sendVestelAc(getRaw()); } +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. +void IRVestelAc::send(const uint16_t repeat) { + _irsend.sendVestelAc(getRaw(), kVestelAcBits, repeat); +} #endif // SEND_VESTEL_AC -// Return the internal state date of the remote. +/// Get a copy of the internal state/code for this protocol. +/// @return A code for this protocol based on the current internal state. uint64_t IRVestelAc::getRaw(void) { this->checksum(); if (use_time_state) return remote_time_state; return remote_state; } -// Override the internal state with the new state. +/// Set the internal state from a valid code for this protocol. +/// @param[in] newState A valid code for this protocol. void IRVestelAc::setRaw(const uint8_t* newState) { uint64_t upState = 0; for (int i = 0; i < 7; i++) @@ -92,6 +91,8 @@ void IRVestelAc::setRaw(const uint8_t* newState) { this->setRaw(upState); } +/// Set the internal state from a valid code for this protocol. +/// @param[in] newState A valid code for this protocol. void IRVestelAc::setRaw(const uint64_t newState) { use_time_state = false; remote_state = newState; @@ -104,25 +105,28 @@ void IRVestelAc::setRaw(const uint64_t newState) { } } -// Set the requested power state of the A/C to on. +/// Set the requested power state of the A/C to on. void IRVestelAc::on(void) { setPower(true); } -// Set the requested power state of the A/C to off. +/// Set the requested power state of the A/C to off. void IRVestelAc::off(void) { setPower(false); } -// Set the requested power state of the A/C. +/// Change the power setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRVestelAc::setPower(const bool on) { setBits(&remote_state, kVestelAcPowerOffset, kVestelAcPowerSize, on ? 0b11 : 0b00); use_time_state = false; } -// Return the requested power state of the A/C. +/// Get the value of the current power setting. +/// @return true, the setting is on. false, the setting is off. bool IRVestelAc::getPower(void) { return GETBITS64(remote_state, kVestelAcPowerOffset, kVestelAcPowerSize); } -// Set the temperature in Celsius degrees. +/// Set the temperature. +/// @param[in] temp The temperature in degrees celsius. void IRVestelAc::setTemp(const uint8_t temp) { uint8_t new_temp = std::max(kVestelAcMinTempC, temp); new_temp = std::min(kVestelAcMaxTemp, new_temp); @@ -131,13 +135,15 @@ void IRVestelAc::setTemp(const uint8_t temp) { use_time_state = false; } -// Return the set temperature. +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRVestelAc::getTemp(void) { return GETBITS64(remote_state, kVestelAcTempOffset, kNibbleSize) + kVestelAcMinTempH; } -// Set the speed of the fan, +/// Set the speed of the fan. +/// @param[in] fan The desired setting. void IRVestelAc::setFan(const uint8_t fan) { switch (fan) { case kVestelAcFanLow: @@ -154,21 +160,22 @@ void IRVestelAc::setFan(const uint8_t fan) { use_time_state = false; } -// Return the requested state of the unit's fan. +/// Get the current fan speed setting. +/// @return The current fan speed/mode. uint8_t IRVestelAc::getFan(void) { return GETBITS64(remote_state, kVestelAcFanOffset, kVestelAcFanSize); } -// Get the requested climate operation mode of the a/c unit. -// Returns: -// A uint8_t containing the A/C mode. +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRVestelAc::getMode(void) { return GETBITS64(remote_state, kVestelAcModeOffset, kModeBitsSize); } -// Set the requested climate operation mode of the a/c unit. +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. +/// @note If we get an unexpected mode, default to AUTO. void IRVestelAc::setMode(const uint8_t mode) { - // If we get an unexpected mode, default to AUTO. switch (mode) { case kVestelAcAuto: case kVestelAcCool: @@ -183,7 +190,8 @@ void IRVestelAc::setMode(const uint8_t mode) { use_time_state = false; } -// Set Auto mode of AC. +/// Set Auto mode/level of the A/C. +/// @param[in] autoLevel The auto mode/level setting. void IRVestelAc::setAuto(const int8_t autoLevel) { if (autoLevel < -2 || autoLevel > 2) return; setMode(kVestelAcAuto); @@ -200,18 +208,23 @@ void IRVestelAc::setAuto(const int8_t autoLevel) { setTemp(17); } +/// Set the timer to be active on the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRVestelAc::setTimerActive(const bool on) { setBit(&remote_time_state, kVestelAcTimerFlagOffset, on); use_time_state = true; } +/// Get if the Timer is active on the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRVestelAc::isTimerActive(void) { return GETBIT64(remote_time_state, kVestelAcTimerFlagOffset); } -// Set Timer option of AC. -// Valid time arguments are 0, 0.5, 1, 2, 3 and 5 hours (in min). 0 disables the -// timer. +/// Set Timer option of A/C. +/// @param[in] minutes Nr of minutes the timer is to be set for. +/// @note Valid arguments are 0, 0.5, 1, 2, 3 and 5 hours (in minutes). +/// 0 disables the timer. void IRVestelAc::setTimer(const uint16_t minutes) { // Clear both On & Off timers. remote_time_state &= ~((uint64_t)0xFFFF << kVestelAcOffTimeOffset); @@ -225,9 +238,12 @@ void IRVestelAc::setTimer(const uint16_t minutes) { use_time_state = true; } +/// Get the Timer time of A/C. +/// @return The number of minutes of time on the timer. uint16_t IRVestelAc::getTimer(void) { return getOffTimer(); } -// Set the AC's internal clock +/// Set the A/C's internal clock. +/// @param[in] minutes The time expressed in nr. of minutes past midnight. void IRVestelAc::setTime(const uint16_t minutes) { setBits(&remote_time_state, kVestelAcHourOffset, kVestelAcHourSize, minutes / 60); @@ -236,22 +252,30 @@ void IRVestelAc::setTime(const uint16_t minutes) { use_time_state = true; } +/// Get the A/C's internal clock's time. +/// @return The time expressed in nr. of minutes past midnight. uint16_t IRVestelAc::getTime(void) { return GETBITS64(remote_time_state, kVestelAcHourOffset, kVestelAcHourSize) * 60 + GETBITS64(remote_time_state, kVestelAcMinuteOffset, kVestelAcMinuteSize); } +/// Set the On timer to be active on the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRVestelAc::setOnTimerActive(const bool on) { setBit(&remote_time_state, kVestelAcOnTimerFlagOffset, on); use_time_state = true; } +/// Get if the On Timer is active on the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRVestelAc::isOnTimerActive(void) { return GETBIT64(remote_time_state, kVestelAcOnTimerFlagOffset); } -// Set a given timer (via offset). Takes time in nr. of minutes. +/// Set a given timer time at a given bit offset. +/// @param[in] minutes Time in nr. of minutes. +/// @param[in] offset Nr. of bits offset from the start of the state. void IRVestelAc::_setTimer(const uint16_t minutes, const uint8_t offset) { setBits(&remote_time_state, offset, kVestelAcTimerSize, ((minutes / 60) << 3) + (minutes % 60) / 10); @@ -259,112 +283,129 @@ void IRVestelAc::_setTimer(const uint16_t minutes, const uint8_t offset) { use_time_state = true; } -// Get the number of mins a timer is set for. +/// Get the number of minutes a timer is set for. +/// @param[in] offset Nr. of bits offset from the start of the state. +/// @return The time expressed in nr. of minutes. uint16_t IRVestelAc::_getTimer(const uint8_t offset) { return GETBITS64(remote_time_state, offset + kVestelAcTimerMinsSize, kVestelAcTimerHourSize) * 60 + // Hrs GETBITS64(remote_time_state, offset, kVestelAcTimerMinsSize) * 10; // Min } -// Set AC's wake up time. Takes time in minute. + +/// Set the On timer time on the A/C. +/// @param[in] minutes Time in nr. of minutes. void IRVestelAc::setOnTimer(const uint16_t minutes) { setOnTimerActive(minutes); _setTimer(minutes, kVestelAcOnTimeOffset); } +/// Get the A/C's On Timer time. +/// @return The time expressed in nr. of minutes. uint16_t IRVestelAc::getOnTimer(void) { return _getTimer(kVestelAcOnTimeOffset); } +/// Set the Off timer to be active on the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRVestelAc::setOffTimerActive(const bool on) { setBit(&remote_time_state, kVestelAcOffTimerFlagOffset, on); use_time_state = true; } +/// Get if the Off Timer is active on the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRVestelAc::isOffTimerActive(void) { return GETBIT64(remote_time_state, kVestelAcOffTimerFlagOffset); } -// Set AC's turn off time. Takes time in minute. +/// Set the Off timer time on the A/C. +/// @param[in] minutes Time in nr. of minutes. void IRVestelAc::setOffTimer(const uint16_t minutes) { setOffTimerActive(minutes); _setTimer(minutes, kVestelAcOffTimeOffset); } +/// Get the A/C's Off Timer time. +/// @return The time expressed in nr. of minutes. uint16_t IRVestelAc::getOffTimer(void) { return _getTimer(kVestelAcOffTimeOffset); } -// Set the Sleep state of the A/C. +/// Set the Sleep setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRVestelAc::setSleep(const bool on) { setBits(&remote_state, kVestelAcTurboSleepOffset, kNibbleSize, on ? kVestelAcSleep : kVestelAcNormal); use_time_state = false; } -// Return the Sleep state of the A/C. +/// Get the Sleep setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRVestelAc::getSleep(void) { return GETBITS64(remote_state, kVestelAcTurboSleepOffset, kNibbleSize) == kVestelAcSleep; } -// Set the Turbo state of the A/C. +/// Set the Turbo setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRVestelAc::setTurbo(const bool on) { setBits(&remote_state, kVestelAcTurboSleepOffset, kNibbleSize, on ? kVestelAcTurbo : kVestelAcNormal); use_time_state = false; } -// Return the Turbo state of the A/C. +/// Get the Turbo setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRVestelAc::getTurbo(void) { return GETBITS64(remote_state, kVestelAcTurboSleepOffset, kNibbleSize) == kVestelAcTurbo; } -// Set the Ion state of the A/C. +/// Set the Ion (Filter) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRVestelAc::setIon(const bool on) { setBit(&remote_state, kVestelAcIonOffset, on); use_time_state = false; } -// Return the Ion state of the A/C. +/// Get the Ion (Filter) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRVestelAc::getIon(void) { return GETBIT64(remote_state, kVestelAcIonOffset); } -// Set the Swing Roaming state of the A/C. +/// Set the Swing Roaming setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRVestelAc::setSwing(const bool on) { setBits(&remote_state, kVestelAcSwingOffset, kNibbleSize, on ? kVestelAcSwing : 0xF); use_time_state = false; } -// Return the Swing Roaming state of the A/C. +/// Get the Swing Roaming setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRVestelAc::getSwing(void) { return GETBITS64(remote_state, kVestelAcSwingOffset, kNibbleSize) == kVestelAcSwing; } -// Calculate the checksum for a given array. -// Args: -// state: The state to calculate the checksum over. -// Returns: -// The 8 bit checksum value. +/// Calculate the checksum for a given state. +/// @param[in] state The state to calc the checksum of. +/// @return The calculated checksum value. uint8_t IRVestelAc::calcChecksum(const uint64_t state) { // Just counts the set bits +1 on stream and take inverse after mask return 0xFF - countBits(GETBITS64(state, 20, 44), 44, true, 2); } -// Verify the checksum is valid for a given state. -// Args: -// state: The state to verify the checksum of. -// Returns: -// A boolean. +/// Verify the checksum is valid for a given state. +/// @param[in] state The state to verify the checksum of. +/// @return true, if the state has a valid checksum. Otherwise, false. bool IRVestelAc::validChecksum(const uint64_t state) { return GETBITS64(state, kVestelAcChecksumOffset, kVestelAcChecksumSize) == IRVestelAc::calcChecksum(state); } -// Calculate & set the checksum for the current internal state of the remote. +/// Calculate & set the checksum for the current internal state of the remote. void IRVestelAc::checksum(void) { // Stored the checksum value in the last byte. setBits(&remote_state, kVestelAcChecksumOffset, kVestelAcChecksumSize, @@ -373,12 +414,16 @@ void IRVestelAc::checksum(void) { this->calcChecksum(remote_time_state)); } +/// Is the current state a time command? +/// @return true, if the state is a time message. Otherwise, false. bool IRVestelAc::isTimeCommand(void) { return !GETBITS64(remote_state, kVestelAcPowerOffset, kNibbleSize) || use_time_state; } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRVestelAc::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kVestelAcCool; @@ -389,7 +434,9 @@ uint8_t IRVestelAc::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRVestelAc::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: @@ -401,7 +448,9 @@ uint8_t IRVestelAc::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRVestelAc::toCommonMode(const uint8_t mode) { switch (mode) { case kVestelAcCool: return stdAc::opmode_t::kCool; @@ -412,7 +461,9 @@ stdAc::opmode_t IRVestelAc::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] spd The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRVestelAc::toCommonFanSpeed(const uint8_t spd) { switch (spd) { case kVestelAcFanHigh: return stdAc::fanspeed_t::kMax; @@ -422,7 +473,8 @@ stdAc::fanspeed_t IRVestelAc::toCommonFanSpeed(const uint8_t spd) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRVestelAc::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::VESTEL_AC; @@ -448,7 +500,8 @@ stdAc::state_t IRVestelAc::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRVestelAc::toString(void) { String result = ""; result.reserve(100); // Reserve some heap for the string to reduce fragging. @@ -508,19 +561,14 @@ String IRVestelAc::toString(void) { } #if DECODE_VESTEL_AC -// Decode the supplied Vestel message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kVestelBits. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: Alpha / Needs testing against a real device. -// +/// Decode the supplied Vestel message. +/// Status: Alpha / Needs testing 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. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. bool IRrecv::decodeVestelAc(decode_results* results, uint16_t offset, const uint16_t nbits, const bool strict) { if (nbits % 8 != 0) // nbits has to be a multiple of nr. of bits in a byte. diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Vestel.h b/lib/IRremoteESP8266-2.7.8/src/ir_Vestel.h similarity index 86% rename from lib/IRremoteESP8266-2.7.5/src/ir_Vestel.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Vestel.h index 38727b805..b545a5a2f 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Vestel.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Vestel.h @@ -1,6 +1,10 @@ // Copyright 2018 Erdem U. Altinyurt // Copyright 2019 David Conran +/// @file +/// @brief Support for Vestel protocols. +/// Vestel added by Erdem U. Altinyurt + // Supports: // Brand: Vestel, Model: BIOX CXP-9 A/C (9K BTU) @@ -18,7 +22,6 @@ #include "IRsend_test.h" #endif -// Vestel added by Erdem U. Altinyurt // Structure of a Command message (56 bits) // Signature: 12 bits. e.g. 0x201 @@ -108,15 +111,20 @@ const uint8_t kVestelAcMinuteSize = 8; // Nr. of bits const uint64_t kVestelAcStateDefault = 0x0F00D9001FEF201ULL; const uint64_t kVestelAcTimeStateDefault = 0x201ULL; +// Classes +/// Class for handling detailed Vestel A/C messages. class IRVestelAc { public: explicit IRVestelAc(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - void stateReset(void); #if SEND_VESTEL_AC - void send(void); - uint8_t calibrate(void) { return _irsend.calibrate(); } + 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_VESTEL_AC void begin(void); void on(void); @@ -167,12 +175,14 @@ class IRVestelAc { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - uint64_t remote_state; - uint64_t remote_time_state; + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint64_t remote_state; ///< The state of the IR remote in IR code form. + uint64_t remote_time_state; ///< The time state of the remote in code form. bool use_time_state; void checksum(void); void _setTimer(const uint16_t minutes, const uint8_t offset); diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Whirlpool.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Whirlpool.cpp similarity index 71% rename from lib/IRremoteESP8266-2.7.5/src/ir_Whirlpool.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Whirlpool.cpp index 3ba781c4c..c04e32300 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Whirlpool.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Whirlpool.cpp @@ -1,18 +1,12 @@ // Copyright 2018 David Conran -// -// Code to emulate Whirlpool protocol compatible devices. -// Should be compatible with: -// * SPIS409L, SPIS412L, SPIW409L, SPIW412L, SPIW418L -// Remotes: -// * DG11J1-3A / DG11J1-04 -// * DG11J1-91 -// -// Note: Smart, iFeel, AroundU, PowerSave, & Silent modes are unsupported. -// Advanced 6thSense, Dehumidify, & Sleep modes are not supported. -// FYI: -// Dim == !Light -// Jet == Super == Turbo -// + +/// @file +/// @brief Support for Whirlpool protocols. +/// Decoding help from: \@redmusicxd, \@josh929800, \@raducostea +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/509 +/// @note Smart, iFeel, AroundU, PowerSave, & Silent modes are unsupported. +/// Advanced 6thSense, Dehumidify, & Sleep modes are not supported. +/// @note Dim == !Light, Jet == Super == Turbo #include "ir_Whirlpool.h" #include @@ -27,7 +21,6 @@ #include "IRutils.h" // Constants -// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/509 const uint16_t kWhirlpoolAcHdrMark = 8950; const uint16_t kWhirlpoolAcHdrSpace = 4484; const uint16_t kWhirlpoolAcBitMark = 597; @@ -49,17 +42,11 @@ using irutils::setBit; using irutils::setBits; #if SEND_WHIRLPOOL_AC -// Send a Whirlpool A/C message. -// -// Args: -// data: An array of bytes containing the IR command. -// nbytes: Nr. of bytes of data in the array. (>=kWhirlpoolAcStateLength) -// repeat: Nr. of times the message is to be repeated. (Default = 0). -// -// Status: BETA / Probably works. -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/509 +/// Send a Whirlpool A/C message. +/// Status: BETA / Probably works. +/// @param[in] data The message to be sent. +/// @param[in] nbytes The number of bytes of message to be sent. +/// @param[in] repeat The number of times the command is to be repeated. void IRsend::sendWhirlpoolAC(const unsigned char data[], const uint16_t nbytes, const uint16_t repeat) { if (nbytes < kWhirlpoolAcStateLength) @@ -89,13 +76,16 @@ void IRsend::sendWhirlpoolAC(const unsigned char data[], const uint16_t nbytes, #endif // SEND_WHIRLPOOL_AC // Class for emulating a Whirlpool A/C remote. -// Decoding help from: -// @redmusicxd, @josh929800, @raducostea +/// 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? IRWhirlpoolAc::IRWhirlpoolAc(const uint16_t pin, const bool inverted, const bool use_modulation) : _irsend(pin, inverted, use_modulation) { this->stateReset(); } +/// Reset the state of the remote to a known good state/sequence. void IRWhirlpoolAc::stateReset(void) { for (uint8_t i = 2; i < kWhirlpoolAcStateLength; i++) remote_state[i] = 0x0; remote_state[0] = 0x83; @@ -104,9 +94,15 @@ void IRWhirlpoolAc::stateReset(void) { this->_setTemp(kWhirlpoolAcAutoTemp); // Default to a sane value. } +/// Set up hardware to be able to send a message. void IRWhirlpoolAc::begin(void) { _irsend.begin(); } -bool IRWhirlpoolAc::validChecksum(uint8_t state[], const uint16_t length) { +/// Verify the checksum is valid for a given state. +/// @param[in] state The array to verify the checksum of. +/// @param[in] length The length/size of the array. +/// @return true, if the state has a valid checksum. Otherwise, false. +bool IRWhirlpoolAc::validChecksum(const uint8_t state[], + const uint16_t length) { if (length > kWhirlpoolAcChecksumByte1 && state[kWhirlpoolAcChecksumByte1] != xorBytes(state + 2, kWhirlpoolAcChecksumByte1 - 1 - 2)) { @@ -124,7 +120,8 @@ bool IRWhirlpoolAc::validChecksum(uint8_t state[], const uint16_t length) { return true; } -// Update the checksum for the internal state. +/// Calculate & set the checksum for the current internal state of the remote. +/// @param[in] length The length/size of the internal state array. void IRWhirlpoolAc::checksum(uint16_t length) { if (length >= kWhirlpoolAcChecksumByte1) remote_state[kWhirlpoolAcChecksumByte1] = @@ -136,21 +133,32 @@ void IRWhirlpoolAc::checksum(uint16_t length) { } #if SEND_WHIRLPOOL_AC +/// Send the current internal state as an IR message. +/// @param[in] repeat Nr. of times the message will be repeated. +/// @param[in] calcchecksum Do we need to calculate the checksum?. void IRWhirlpoolAc::send(const uint16_t repeat, const bool calcchecksum) { if (calcchecksum) this->checksum(); _irsend.sendWhirlpoolAC(remote_state, kWhirlpoolAcStateLength, repeat); } #endif // SEND_WHIRLPOOL_AC +/// Get a copy of the internal state/code for this protocol. +/// @param[in] calcchecksum Do we need to calculate the checksum?. +/// @return A code for this protocol based on the current internal state. uint8_t *IRWhirlpoolAc::getRaw(const bool calcchecksum) { if (calcchecksum) this->checksum(); return remote_state; } +/// Set the internal state from a valid code for this protocol. +/// @param[in] new_code A valid code for this protocol. +/// @param[in] length The length/size of the new_code array. void IRWhirlpoolAc::setRaw(const uint8_t new_code[], const uint16_t length) { memcpy(remote_state, new_code, std::min(length, kWhirlpoolAcStateLength)); } +/// Get/Detect the model of the A/C. +/// @return The enum of the compatible model. whirlpool_ac_remote_model_t IRWhirlpoolAc::getModel(void) { if (GETBIT8(remote_state[kWhirlpoolAcAltTempPos], kWhirlpoolAcAltTempOffset)) return DG11J191; @@ -158,6 +166,8 @@ whirlpool_ac_remote_model_t IRWhirlpoolAc::getModel(void) { return DG11J13A; } +/// Set the model of the A/C to emulate. +/// @param[in] model The enum of the appropriate model. void IRWhirlpoolAc::setModel(const whirlpool_ac_remote_model_t model) { switch (model) { case DG11J191: @@ -172,7 +182,8 @@ void IRWhirlpoolAc::setModel(const whirlpool_ac_remote_model_t model) { this->_setTemp(_desiredtemp); // Different models have different temp values. } -// Return the temp. offset in deg C for the current model. +/// Calculate the temp. offset in deg C for the current model. +/// @return The temperature offset. int8_t IRWhirlpoolAc::getTempOffset(void) { switch (this->getModel()) { case whirlpool_ac_remote_model_t::DG11J191: return -2; @@ -180,7 +191,10 @@ int8_t IRWhirlpoolAc::getTempOffset(void) { } } -// Set the temp. in deg C +/// Set the temperature. +/// @param[in] temp The temperature in degrees celsius. +/// @param[in] remember Do we save this temperature? +/// @note Internal use only. void IRWhirlpoolAc::_setTemp(const uint8_t temp, const bool remember) { if (remember) _desiredtemp = temp; int8_t offset = this->getTempOffset(); // Cache the min temp for the model. @@ -190,19 +204,24 @@ void IRWhirlpoolAc::_setTemp(const uint8_t temp, const bool remember) { newtemp - (kWhirlpoolAcMinTemp + offset)); } -// Set the temp. in deg C +/// Set the temperature. +/// @param[in] temp The temperature in degrees celsius. void IRWhirlpoolAc::setTemp(const uint8_t temp) { this->_setTemp(temp); this->setSuper(false); // Changing temp cancels Super/Jet mode. this->setCommand(kWhirlpoolAcCommandTemp); } -// Return the set temp. in deg C +/// Get the current temperature setting. +/// @return The current setting for temp. in degrees celsius. uint8_t IRWhirlpoolAc::getTemp(void) { return GETBITS8(remote_state[kWhirlpoolAcTempPos], kHighNibble, kNibbleSize) + kWhirlpoolAcMinTemp + this->getTempOffset(); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. +/// @note Internal use only. void IRWhirlpoolAc::_setMode(const uint8_t mode) { switch (mode) { case kWhirlpoolAcAuto: @@ -224,16 +243,22 @@ void IRWhirlpoolAc::_setMode(const uint8_t mode) { if (mode == kWhirlpoolAcAuto) this->setCommand(kWhirlpoolAcCommand6thSense); } +/// Set the operating mode of the A/C. +/// @param[in] mode The desired operating mode. void IRWhirlpoolAc::setMode(const uint8_t mode) { this->setSuper(false); // Changing mode cancels Super/Jet mode. this->_setMode(mode); } +/// Get the operating mode setting of the A/C. +/// @return The current operating mode setting. uint8_t IRWhirlpoolAc::getMode(void) { return GETBITS8(remote_state[kWhirlpoolAcModePos], kWhirlpoolAcModeOffset, kModeBitsSize); } +/// Set the speed of the fan. +/// @param[in] speed The desired setting. void IRWhirlpoolAc::setFan(const uint8_t speed) { switch (speed) { case kWhirlpoolAcFanAuto: @@ -248,32 +273,45 @@ void IRWhirlpoolAc::setFan(const uint8_t speed) { } } +/// Get the current fan speed setting. +/// @return The current fan speed/mode. uint8_t IRWhirlpoolAc::getFan(void) { return GETBITS8(remote_state[kWhirlpoolAcFanPos], kWhirlpoolAcFanOffset, kWhirlpoolAcFanSize); } +/// Set the (vertical) swing setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRWhirlpoolAc::setSwing(const bool on) { setBit(&remote_state[kWhirlpoolAcFanPos], kWhirlpoolAcSwing1Offset, on); setBit(&remote_state[kWhirlpoolAcOffTimerPos], kWhirlpoolAcSwing2Offset, on); setCommand(kWhirlpoolAcCommandSwing); } +/// Get the (vertical) swing setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRWhirlpoolAc::getSwing(void) { return GETBIT8(remote_state[kWhirlpoolAcFanPos], kWhirlpoolAcSwing1Offset) && GETBIT8(remote_state[kWhirlpoolAcOffTimerPos], kWhirlpoolAcSwing2Offset); } +/// Set the Light (Display/LED) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRWhirlpoolAc::setLight(const bool on) { // Cleared when on. setBit(&remote_state[kWhirlpoolAcClockPos], kWhirlpoolAcLightOffset, !on); } +/// Get the Light (Display/LED) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRWhirlpoolAc::getLight(void) { return !GETBIT8(remote_state[kWhirlpoolAcClockPos], kWhirlpoolAcLightOffset); } +/// Set the time in nr. of minutes past midnight. +/// @param[in] pos The byte offset to write to. +/// @param[in] minspastmidnight Nr. of minutes past midnight. void IRWhirlpoolAc::setTime(const uint16_t pos, const uint16_t minspastmidnight) { // Hours @@ -284,6 +322,9 @@ void IRWhirlpoolAc::setTime(const uint16_t pos, kWhirlpoolAcMinuteSize, minspastmidnight % 60); } +/// Get the time in nr. of minutes past midnight. +/// @param[in] pos The byte offset to read from. +/// @return The time in Nr. of minutes past midnight. uint16_t IRWhirlpoolAc::getTime(const uint16_t pos) { return GETBITS8(remote_state[pos], kWhirlpoolAcHourOffset, kWhirlpoolAcHourSize) * 60 + @@ -291,56 +332,84 @@ uint16_t IRWhirlpoolAc::getTime(const uint16_t pos) { kWhirlpoolAcMinuteSize); } +/// Is the timer enabled at the given byte offset? +/// @param[in] pos The byte offset to read from. +/// @return true, the Timer is on. false, the Timer is off. bool IRWhirlpoolAc::isTimerEnabled(const uint16_t pos) { return GETBIT8(remote_state[pos - 1], kWhirlpoolAcTimerEnableOffset); } +/// Enable the timer enabled at the given byte offset. +/// @param[in] pos The byte offset to write to. +/// @param[in] on true, the timer is enabled. false, the timer is disabled. void IRWhirlpoolAc::enableTimer(const uint16_t pos, const bool on) { setBit(&remote_state[pos - 1], kWhirlpoolAcTimerEnableOffset, on); } +/// Set the clock time in nr. of minutes past midnight. +/// @param[in] minspastmidnight The time expressed as minutes past midnight. void IRWhirlpoolAc::setClock(const uint16_t minspastmidnight) { this->setTime(kWhirlpoolAcClockPos, minspastmidnight); } +/// Get the clock time in nr. of minutes past midnight. +/// @return The time expressed as the Nr. of minutes past midnight. uint16_t IRWhirlpoolAc::getClock(void) { return this->getTime(kWhirlpoolAcClockPos); } +/// Set the Off Timer time. +/// @param[in] minspastmidnight The time expressed as minutes past midnight. void IRWhirlpoolAc::setOffTimer(const uint16_t minspastmidnight) { this->setTime(kWhirlpoolAcOffTimerPos, minspastmidnight); } +/// Get the Off Timer time.. +/// @return The time expressed as the Nr. of minutes past midnight. uint16_t IRWhirlpoolAc::getOffTimer(void) { return this->getTime(kWhirlpoolAcOffTimerPos); } +/// Is the Off timer enabled? +/// @return true, the Timer is enabled. false, the Timer is disabled. bool IRWhirlpoolAc::isOffTimerEnabled(void) { return this->isTimerEnabled(kWhirlpoolAcOffTimerPos); } +/// Enable the Off Timer. +/// @param[in] on true, the timer is enabled. false, the timer is disabled. void IRWhirlpoolAc::enableOffTimer(const bool on) { this->enableTimer(kWhirlpoolAcOffTimerPos, on); this->setCommand(kWhirlpoolAcCommandOffTimer); } +/// Set the On Timer time. +/// @param[in] minspastmidnight The time expressed as minutes past midnight. void IRWhirlpoolAc::setOnTimer(const uint16_t minspastmidnight) { this->setTime(kWhirlpoolAcOnTimerPos, minspastmidnight); } +/// Get the On Timer time.. +/// @return The time expressed as the Nr. of minutes past midnight. uint16_t IRWhirlpoolAc::getOnTimer(void) { return this->getTime(kWhirlpoolAcOnTimerPos); } +/// Is the On timer enabled? +/// @return true, the Timer is enabled. false, the Timer is disabled. bool IRWhirlpoolAc::isOnTimerEnabled(void) { return this->isTimerEnabled(kWhirlpoolAcOnTimerPos); } +/// Enable the On Timer. +/// @param[in] on true, the timer is enabled. false, the timer is disabled. void IRWhirlpoolAc::enableOnTimer(const bool on) { this->enableTimer(kWhirlpoolAcOnTimerPos, on); this->setCommand(kWhirlpoolAcCommandOnTimer); } +/// Change the power toggle setting. +/// @param[in] on true, the setting is on. false, the setting is off. void IRWhirlpoolAc::setPowerToggle(const bool on) { setBit(&remote_state[kWhirlpoolAcPowerTogglePos], kWhirlpoolAcPowerToggleOffset, on); @@ -348,15 +417,21 @@ void IRWhirlpoolAc::setPowerToggle(const bool on) { this->setCommand(kWhirlpoolAcCommandPower); } +/// Get the value of the current power toggle setting. +/// @return true, the setting is on. false, the setting is off. bool IRWhirlpoolAc::getPowerToggle(void) { return GETBIT8(remote_state[kWhirlpoolAcPowerTogglePos], kWhirlpoolAcPowerToggleOffset); } +/// Get the Command (Button) setting of the A/C. +/// @return The current Command (Button) of the A/C. uint8_t IRWhirlpoolAc::getCommand(void) { return remote_state[kWhirlpoolAcCommandPos]; } +/// Set the Sleep setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRWhirlpoolAc::setSleep(const bool on) { setBit(&remote_state[kWhirlpoolAcSleepPos], kWhirlpoolAcSleepOffset, on); @@ -364,11 +439,14 @@ void IRWhirlpoolAc::setSleep(const bool on) { this->setCommand(kWhirlpoolAcCommandSleep); } +/// Get the Sleep setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRWhirlpoolAc::getSleep(void) { return GETBIT8(remote_state[kWhirlpoolAcSleepPos], kWhirlpoolAcSleepOffset); } -// AKA Jet/Turbo mode. +/// Set the Super (Turbo/Jet) setting of the A/C. +/// @param[in] on true, the setting is on. false, the setting is off. void IRWhirlpoolAc::setSuper(const bool on) { if (on) { this->setFan(kWhirlpoolAcFanHigh); @@ -389,15 +467,21 @@ void IRWhirlpoolAc::setSuper(const bool on) { this->setCommand(kWhirlpoolAcCommandSuper); } +/// Get the Super (Turbo/Jet) setting of the A/C. +/// @return true, the setting is on. false, the setting is off. bool IRWhirlpoolAc::getSuper(void) { return remote_state[kWhirlpoolAcSuperPos] & kWhirlpoolAcSuperMask; } +/// Set the Command (Button) setting of the A/C. +/// @param[in] code The current Command (Button) of the A/C. void IRWhirlpoolAc::setCommand(const uint8_t code) { remote_state[kWhirlpoolAcCommandPos] = code; } -// Convert a standard A/C mode into its native mode. +/// Convert a stdAc::opmode_t enum into its native mode. +/// @param[in] mode The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRWhirlpoolAc::convertMode(const stdAc::opmode_t mode) { switch (mode) { case stdAc::opmode_t::kCool: return kWhirlpoolAcCool; @@ -408,7 +492,9 @@ uint8_t IRWhirlpoolAc::convertMode(const stdAc::opmode_t mode) { } } -// Convert a standard A/C Fan speed into its native fan speed. +/// Convert a stdAc::fanspeed_t enum into it's native speed. +/// @param[in] speed The enum to be converted. +/// @return The native equivilant of the enum. uint8_t IRWhirlpoolAc::convertFan(const stdAc::fanspeed_t speed) { switch (speed) { case stdAc::fanspeed_t::kMin: @@ -420,7 +506,9 @@ uint8_t IRWhirlpoolAc::convertFan(const stdAc::fanspeed_t speed) { } } -// Convert a native mode to it's common equivalent. +/// Convert a native mode into its stdAc equivilant. +/// @param[in] mode The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::opmode_t IRWhirlpoolAc::toCommonMode(const uint8_t mode) { switch (mode) { case kWhirlpoolAcCool: return stdAc::opmode_t::kCool; @@ -431,7 +519,9 @@ stdAc::opmode_t IRWhirlpoolAc::toCommonMode(const uint8_t mode) { } } -// Convert a native fan speed to it's common equivalent. +/// Convert a native fan speed into its stdAc equivilant. +/// @param[in] speed The native setting to be converted. +/// @return The stdAc equivilant of the native setting. stdAc::fanspeed_t IRWhirlpoolAc::toCommonFanSpeed(const uint8_t speed) { switch (speed) { case kWhirlpoolAcFanHigh: return stdAc::fanspeed_t::kMax; @@ -441,7 +531,8 @@ stdAc::fanspeed_t IRWhirlpoolAc::toCommonFanSpeed(const uint8_t speed) { } } -// Convert the A/C state to it's common equivalent. +/// Convert the current internal state into its stdAc::state_t equivilant. +/// @return The stdAc equivilant of the native settings. stdAc::state_t IRWhirlpoolAc::toCommon(void) { stdAc::state_t result; result.protocol = decode_type_t::WHIRLPOOL_AC; @@ -467,7 +558,8 @@ stdAc::state_t IRWhirlpoolAc::toCommon(void) { return result; } -// Convert the internal state into a human readable string. +/// Convert the current internal state into a human readable string. +/// @return A human readable string. String IRWhirlpoolAc::toString(void) { String result = ""; result.reserve(200); // Reserve some heap for the string to reduce fragging. @@ -538,22 +630,15 @@ String IRWhirlpoolAc::toString(void) { } #if DECODE_WHIRLPOOL_AC -// Decode the supplied Whirlpool A/C message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: The number of data bits to expect. Typically kWhirlpoolAcBits -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Working as intended. -// -// -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/509 + +/// Decode the supplied Whirlpool A/C message. +/// Status: STABLE / Working as intended. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. bool IRrecv::decodeWhirlpoolAC(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen < 2 * nbits + 4 + kHeader + kFooter - 1 + offset) diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Whirlpool.h b/lib/IRremoteESP8266-2.7.8/src/ir_Whirlpool.h similarity index 82% rename from lib/IRremoteESP8266-2.7.5/src/ir_Whirlpool.h rename to lib/IRremoteESP8266-2.7.8/src/ir_Whirlpool.h index 11fd6949e..3fd4e86dd 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Whirlpool.h +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Whirlpool.h @@ -1,7 +1,13 @@ -// Whirlpool A/C -// // Copyright 2018 David Conran +/// @file +/// @brief Support for Whirlpool protocols. +/// Decoding help from: \@redmusicxd, \@josh929800, \@raducostea +/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/509 +/// @note Smart, iFeel, AroundU, PowerSave, & Silent modes are unsupported. +/// Advanced 6thSense, Dehumidify, & Sleep modes are not supported. +/// @note Dim == !Light, Jet == Super == Turbo + // Supports: // Brand: Whirlpool, Model: DG11J1-3A remote // Brand: Whirlpool, Model: DG11J1-04 remote @@ -26,9 +32,6 @@ #include "IRsend_test.h" #endif -// Ref: -// https://github.com/crankyoldgit/IRremoteESP8266/issues/509 - // Constants const uint8_t kWhirlpoolAcChecksumByte1 = 13; const uint8_t kWhirlpoolAcChecksumByte2 = kWhirlpoolAcStateLength - 1; @@ -84,20 +87,22 @@ const uint8_t kWhirlpoolAcAltTempOffset = 3; const uint8_t kWhirlpoolAcAltTempPos = 18; // Classes +/// Class for handling detailed Whirlpool A/C messages. class IRWhirlpoolAc { public: explicit IRWhirlpoolAc(const uint16_t pin, const bool inverted = false, const bool use_modulation = true); - void stateReset(void); #if SEND_WHIRLPOOL_AC void send(const uint16_t repeat = kWhirlpoolAcDefaultRepeat, const bool calcchecksum = true); - uint8_t calibrate(void) { return _irsend.calibrate(); } + /// 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_WHIRLPOOL_AC void begin(void); - void on(void); - void off(void); void setPowerToggle(const bool on); bool getPowerToggle(void); void setSleep(const bool on); @@ -131,7 +136,7 @@ class IRWhirlpoolAc { uint8_t* getRaw(const bool calcchecksum = true); void setRaw(const uint8_t new_code[], const uint16_t length = kWhirlpoolAcStateLength); - static bool validChecksum(uint8_t state[], + static bool validChecksum(const uint8_t state[], const uint16_t length = kWhirlpoolAcStateLength); uint8_t convertMode(const stdAc::opmode_t mode); uint8_t convertFan(const stdAc::fanspeed_t speed); @@ -142,13 +147,14 @@ class IRWhirlpoolAc { #ifndef UNIT_TEST private: - IRsend _irsend; -#else - IRsendTest _irsend; -#endif - // The state of the IR remote in IR code form. - uint8_t remote_state[kWhirlpoolAcStateLength]; - uint8_t _desiredtemp; + IRsend _irsend; ///< Instance of the IR send class +#else // UNIT_TEST + /// @cond IGNORE + IRsendTest _irsend; ///< Instance of the testing IR send class + /// @endcond +#endif // UNIT_TEST + uint8_t remote_state[kWhirlpoolAcStateLength]; ///< The state in IR code form + uint8_t _desiredtemp; ///< The last user explicitly set temperature. void checksum(const uint16_t length = kWhirlpoolAcStateLength); uint16_t getTime(const uint16_t pos); void setTime(const uint16_t pos, const uint16_t minspastmidnight); diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Whynter.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Whynter.cpp similarity index 70% rename from lib/IRremoteESP8266-2.7.5/src/ir_Whynter.cpp rename to lib/IRremoteESP8266-2.7.8/src/ir_Whynter.cpp index 92bad25ce..7b184eb0b 100644 --- a/lib/IRremoteESP8266-2.7.5/src/ir_Whynter.cpp +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Whynter.cpp @@ -1,8 +1,10 @@ // Copyright 2009 Ken Shirriff // Copyright 2017 David Conran -// Whynter A/C ARC-110WD added by Francesco Meschia -// Whynter originally added from https://github.com/shirriff/Arduino-IRremote/ +/// @file +/// @brief Support for Whynter protocols. +/// Whynter A/C ARC-110WD added by Francesco Meschia +/// Whynter originally added from https://github.com/shirriff/Arduino-IRremote/ // Supports: // Brand: Whynter, Model: ARC-110WD A/C @@ -13,7 +15,6 @@ #include "IRutils.h" // Constants - const uint16_t kWhynterTick = 50; const uint16_t kWhynterHdrMarkTicks = 57; const uint16_t kWhynterHdrMark = kWhynterHdrMarkTicks * kWhynterTick; @@ -35,18 +36,14 @@ const uint16_t kWhynterMinGapTicks = const uint16_t kWhynterMinGap = kWhynterMinGapTicks * kWhynterTick; #if SEND_WHYNTER -// Send a Whynter message. -// -// Args: -// data: message to be sent. -// nbits: Nr. of bits of the message to be sent. -// repeat: Nr. of additional times the message is to be sent. -// -// Status: STABLE -// -// Ref: -// https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Whynter.cpp -void IRsend::sendWhynter(uint64_t data, uint16_t nbits, uint16_t repeat) { +/// Send a Whynter message. +/// Status: STABLE +/// @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. +/// @see https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Whynter.cpp +void IRsend::sendWhynter(const uint64_t data, const uint16_t nbits, + const uint16_t repeat) { // Set IR carrier frequency enableIROut(38); @@ -62,24 +59,18 @@ void IRsend::sendWhynter(uint64_t data, uint16_t nbits, uint16_t repeat) { 50); } } -#endif +#endif // SEND_WHYNTER #if DECODE_WHYNTER -// Decode the supplied Whynter message. -// -// Args: -// results: Ptr to the data to decode and where to store the decode result. -// offset: The starting index to use when attempting to decode the raw data. -// Typically/Defaults to kStartOffset. -// nbits: Nr. of data bits to expect. -// strict: Flag indicating if we should perform strict matching. -// Returns: -// boolean: True if it can decode it, false if it can't. -// -// Status: STABLE / Working. Strict mode is ALPHA. -// -// Ref: -// https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Whynter.cpp +/// Decode the supplied Whynter message. +/// Status: STABLE / Working. Strict mode is ALPHA. +/// @param[in,out] results Ptr to the data to decode & where to store the result +/// @param[in] offset The starting index to use when attempting to decode the +/// raw data. Typically/Defaults to kStartOffset. +/// @param[in] nbits The number of data bits to expect. +/// @param[in] strict Flag indicating if we should perform strict matching. +/// @return True if it can decode it, false if it can't. +/// @see https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Whynter.cpp bool IRrecv::decodeWhynter(decode_results *results, uint16_t offset, const uint16_t nbits, const bool strict) { if (results->rawlen <= 2 * nbits + 2 * kHeader + kFooter - 1 + offset) @@ -109,4 +100,4 @@ bool IRrecv::decodeWhynter(decode_results *results, uint16_t offset, results->command = 0; return true; } -#endif +#endif // DECODE_WHYNTER diff --git a/lib/IRremoteESP8266-2.7.8/src/ir_Zepeal.cpp b/lib/IRremoteESP8266-2.7.8/src/ir_Zepeal.cpp new file mode 100644 index 000000000..96017226c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/src/ir_Zepeal.cpp @@ -0,0 +1,94 @@ +// Copyright 2020 Christian Nilsson (nikize) + +/// @file +/// @brief Support for Zepeal protocol. +/// This protocol uses fixed length bit encoding. +/// Most official information about Zepeal seems to be from Denkyosha +/// @see https://www.denkyosha.co.jp/ + +// Supports: +// Brand: Zepeal, Model: DRT-A3311(BG) floor fan +// Brand: Zepeal, Model: DRT-A3311(BG) 5 button remote + +#include "IRrecv.h" +#include "IRsend.h" +#include "IRutils.h" + +// Constants + +const uint16_t kZepealHdrMark = 2330; +const uint16_t kZepealHdrSpace = 3380; +const uint16_t kZepealOneMark = 1300; +const uint16_t kZepealZeroMark = 420; +const uint16_t kZepealOneSpace = kZepealZeroMark; +const uint16_t kZepealZeroSpace = kZepealOneMark; +const uint16_t kZepealFooterMark = 420; +const uint16_t kZepealGap = 6750; + +const uint8_t kZepealTolerance = 40; + +// Signature limits possible false possitvies, +// but might need change (removal) if more devices are detected +const uint8_t kZepealSignature = 0x6C; + +// Known Zepeal DRT-A3311(BG) Buttons - documentation rather than actual usage +const uint16_t kZepealCommandSpeed = 0x6C82; +const uint16_t kZepealCommandOffOn = 0x6C81; +const uint16_t kZepealCommandRhythm = 0x6C84; +const uint16_t kZepealCommandOffTimer = 0x6C88; +const uint16_t kZepealCommandOnTimer = 0x6CC3; + +#if SEND_ZEPEAL +/// Send a Zepeal formatted message. +/// Status: STABLE / Works on real device. +/// @param[in] data The message to be sent. +/// @param[in] nbits The bit size of the message being sent. +/// @param[in] repeat The number of times the message is to be repeated. +void IRsend::sendZepeal(const uint64_t data, const uint16_t nbits, + const uint16_t repeat) { + sendGeneric(kZepealHdrMark, kZepealHdrSpace, + kZepealOneMark, kZepealOneSpace, + kZepealZeroMark, kZepealZeroSpace, + kZepealFooterMark, kZepealGap, + data, nbits, 38, true, repeat, kDutyDefault); +} +#endif // SEND_ZEPEAL + +#if DECODE_ZEPEAL +/// Decode the supplied Zepeal message. +/// Status: STABLE / Works on real device. +/// @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. Typically kZepealBits. +/// @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::decodeZepeal(decode_results *results, uint16_t offset, + const uint16_t nbits, const bool strict) { + if (results->rawlen < 2 * nbits + kHeader + kFooter - 1 + offset) + return false; // Can't possibly be a valid message. + if (strict && nbits != kZepealBits) + return false; // Not strictly a message. + + uint64_t data = 0; + uint16_t used; + used = matchGeneric(results->rawbuf + offset, &data, + results->rawlen - offset, nbits, + kZepealHdrMark, kZepealHdrSpace, + kZepealOneMark, kZepealOneSpace, + kZepealZeroMark, kZepealZeroSpace, + kZepealFooterMark, kZepealGap, true, + kZepealTolerance); + if (!used) return false; + if (strict && (data >> 8) != kZepealSignature) return false; + + // Success + results->value = data; + results->decode_type = decode_type_t::ZEPEAL; + results->bits = nbits; + results->address = 0; + results->command = 0; + return true; +} +#endif // DECODE_ZEPEAL diff --git a/lib/IRremoteESP8266-2.7.5/src/locale/README.md b/lib/IRremoteESP8266-2.7.8/src/locale/README.md similarity index 68% rename from lib/IRremoteESP8266-2.7.5/src/locale/README.md rename to lib/IRremoteESP8266-2.7.8/src/locale/README.md index 6b55571bf..b8689f34a 100644 --- a/lib/IRremoteESP8266-2.7.5/src/locale/README.md +++ b/lib/IRremoteESP8266-2.7.8/src/locale/README.md @@ -10,7 +10,7 @@ There is _no_ runtime option to change locales. ### Change `_IR_LOCALE_` in the `src/IRremoteESP8266.h` file. In the [IRremoteESP8266.h](../IRremoteESP8266.h#L57-L59) file, find and locate the lines that look like: -``` +```c++ #ifndef _IR_LOCALE_ #define _IR_LOCALE_ en-AU #endif // _IR_LOCALE_ @@ -52,19 +52,19 @@ e.g. `en` is English. `de` is German etc. and `YY` is the ISO country code. e.g. Modify the comments and all `LOCALE_EN_AU_H_`s in the file to `LOCALE_XX_YY_H_` for your locale. -### Override any `#define` values that reside in `defaults.h` -Go through the [defaults.h](defaults.h) file, and find any `#define` lines that define a macro starting with `D_` that has text +### Override any `#‍define` values that reside in `defaults.h` +Go through the [defaults.h](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/locale/defaults.h) file, and find any `#‍define` lines that define a macro starting with `D_` that has text that needs to change for your locale. -Copy or create a corresponding `#define D_STR_HELLOWORLD "Hello World"` in your `xx-YY.h` file, and translate the text appropriately -e.g. `#define D_STR_HELLOWORLD "Bonjour le monde"` (French) +Copy or create a corresponding `#‍define D_STR_HELLOWORLD "Hello World"` in your `xx-YY.h` file, and translate the text appropriately +e.g. `#‍define D_STR_HELLOWORLD "Bonjour le monde"` (French) -Any values you `#define` in `xx-YY.h` will override the corresponding value in the [defaults.h](defaults.h) file. +Any values you `#‍define` in `xx-YY.h` will override the corresponding value in the [defaults.h](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/locale/defaults.h) file. -### Supporting a dialect/regional varient of another _existing_ language/locale. +### Supporting a dialect/regional variant of another _existing_ language/locale. Similar to the previous step, if you only need to modify a small subset of the strings used in another locale file, then include the -other locale file and then make sure to `#undef` any strings that need to be (re-)changed. -See the [Swiss-German](de-CH.h) for an example of how to do this. i.e. It `#include "locale/de-DE.h"`s the German locale, and -redefines any strings that are not standard [German](de-DE.h). +other locale file and then make sure to `#‍undef` any strings that need to be (re-)changed. +See the [Swiss-German](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/locale/de-CH.h) for an example of how to do this. i.e. It `#‍include "locale/de-DE.h"`s the German locale, and +redefines any strings that are not standard [German](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/locale/de-DE.h). ## Adding new text strings to the library. If you need to add an entirely new string to the library to support some feature etc. e.g. _"Widget"_. @@ -72,26 +72,26 @@ You should first understand how the library tries to do this such that it is eas 1. Use a constant named `kWidgetStr` in the appropriate statement in the `.cpp` file. 2. Edit [IRtext.cpp](IRtext.cpp), and add the appropriate line for your new constant. e.g. -``` +```c++ String kWidgetStr = D_STR_WIDGET; ``` The `kWidgetStr` variable will house the sole copy of the string for the entire library. This limits any duplication. The `D_STR_WIDGET` macro will be what is targeted by the different language / locales files. -3. Edit [locale/defaults.h](defaults.h), and add the appropriate stanza for your new string. e.g. -``` +3. Edit [locale/defaults.h](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/locale/defaults.h), and add the appropriate stanza for your new string. e.g. +```c++ #ifndef D_STR_WIDGET #define D_STR_WIDGET "Turbo" #endif // D_STR_WIDGET ``` -4. _(Manual)_ Update [IRtext.h](../IRtext.h), and add the appropriate line for your new constant. e.g. -``` +4. _(Manual)_ Update [IRtext.h](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/IRtext.h), and add the appropriate line for your new constant. e.g. +```c++ extern const String kWidgetStr; ``` -For any file that `#include `s this file, it will tell it that the string is stored elsewhere, +For any file that `#‍include `s this file, it will tell it that the string is stored elsewhere, and to look for it elsewhere at the object linking stage of the build. This is what makes the string be referenced from a central location. -4. _(Automatic)_ Run `tools/generate_irtext_h.sh` to update [IRtext.h](../IRtext.h). -In the [src/locale](../locale) directory. Run the `../../tools/generate_irtext_h.sh` command. It will update the file for you automatically. +4. _(Automatic)_ Run `tools/generate_irtext_h.sh` to update [IRtext.h](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/IRtext.h). +In the [src/locale](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/locale/) directory. Run the `../../tools/generate_irtext_h.sh` command. It will update the file for you automatically. diff --git a/lib/IRremoteESP8266-2.7.5/src/locale/de-CH.h b/lib/IRremoteESP8266-2.7.8/src/locale/de-CH.h similarity index 98% rename from lib/IRremoteESP8266-2.7.5/src/locale/de-CH.h rename to lib/IRremoteESP8266-2.7.8/src/locale/de-CH.h index 2c34ca97b..875ffd394 100644 --- a/lib/IRremoteESP8266-2.7.5/src/locale/de-CH.h +++ b/lib/IRremoteESP8266-2.7.8/src/locale/de-CH.h @@ -143,12 +143,12 @@ #undef D_STR_REPEAT #define D_STR_REPEAT "Wiederhole" -// IRrecvDumpV2 +// IRrecvDumpV2+ #undef D_STR_TIMESTAMP #define D_STR_TIMESTAMP "Ziitstämpfel" #undef D_STR_IRRECVDUMP_STARTUP #define D_STR_IRRECVDUMP_STARTUP \ - "IRrecvDumpV2 lauft und wartet uf IR Iigab ufem Pin %d" + "IRrecvDump lauft und wartet uf IR Iigab ufem Pin %d" #undef D_WARN_BUFFERFULL #define D_WARN_BUFFERFULL \ "WARNUNG: IR Code isch zgross für de Buffer (>= %d). " \ diff --git a/lib/IRremoteESP8266-2.7.5/src/locale/de-DE.h b/lib/IRremoteESP8266-2.7.8/src/locale/de-DE.h similarity index 97% rename from lib/IRremoteESP8266-2.7.5/src/locale/de-DE.h rename to lib/IRremoteESP8266-2.7.8/src/locale/de-DE.h index f366936b0..70ebc4854 100644 --- a/lib/IRremoteESP8266-2.7.5/src/locale/de-DE.h +++ b/lib/IRremoteESP8266-2.7.8/src/locale/de-DE.h @@ -112,12 +112,12 @@ #define D_STR_REPEAT "Wiederholen" -// IRrecvDumpV2 +// IRrecvDumpV2+ #define D_STR_TIMESTAMP "Zeitstempel" #define D_STR_LIBRARY "Bibliothek" #define D_STR_MESGDESC "Nachr. Beschr." #define D_STR_IRRECVDUMP_STARTUP \ - "IRrecvDumpV2 läuft und wartet auf IR Eingabe auf Pin %d" + "IRrecvDump läuft und wartet auf IR Eingabe auf Pin %d" #define D_WARN_BUFFERFULL \ "WARNUNG: IR Code ist zu gross für Buffer (>= %d). " \ "Dem Resultat sollte nicht vertraut werden bevor das behoben ist. " \ diff --git a/lib/IRremoteESP8266-2.7.8/src/locale/defaults.h b/lib/IRremoteESP8266-2.7.8/src/locale/defaults.h new file mode 100644 index 000000000..340e2b8fe --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/src/locale/defaults.h @@ -0,0 +1,758 @@ +// Copyright 2019 - David Conran (@crankyoldgit) +// The default text to use throughout the library. +// The library will use this text if no locale (_IR_LOCALE_) is set or if +// the locale doesn't define particular values. +// If they are defined, this file should NOT override them. +// +// This file should contain a #define for every translateable/locale dependant +// string used by the library. Language specific files don't have to include +// everything. +// +// NOTE: ASCII/UTF-8 characters only. Unicode is NOT supported. +// +// The defaults are English (AU) / en-AU. Australia (AU) is pretty much the same +// as English (UK) for this libraries use case. +#ifndef LOCALE_DEFAULTS_H_ +#define LOCALE_DEFAULTS_H_ + +#ifndef D_STR_UNKNOWN +#define D_STR_UNKNOWN "UNKNOWN" +#endif // D_STR_UNKNOWN +#ifndef D_STR_PROTOCOL +#define D_STR_PROTOCOL "Protocol" +#endif // D_STR_PROTOCOL +#ifndef D_STR_POWER +#define D_STR_POWER "Power" +#endif // D_STR_POWER +#ifndef D_STR_PREVIOUS +#define D_STR_PREVIOUS "Previous" +#endif // D_STR_PREVIOUS +#ifndef D_STR_ON +#define D_STR_ON "On" +#endif // D_STR_ON +#ifndef D_STR_OFF +#define D_STR_OFF "Off" +#endif // D_STR_OFF +#ifndef D_STR_MODE +#define D_STR_MODE "Mode" +#endif // D_STR_MODE +#ifndef D_STR_TOGGLE +#define D_STR_TOGGLE "Toggle" +#endif // D_STR_TOGGLE +#ifndef D_STR_TURBO +#define D_STR_TURBO "Turbo" +#endif // D_STR_TURBO +#ifndef D_STR_SUPER +#define D_STR_SUPER "Super" +#endif // D_STR_SUPER +#ifndef D_STR_SLEEP +#define D_STR_SLEEP "Sleep" +#endif // D_STR_SLEEP +#ifndef D_STR_LIGHT +#define D_STR_LIGHT "Light" +#endif // D_STR_LIGHT +#ifndef D_STR_POWERFUL +#define D_STR_POWERFUL "Powerful" +#endif // D_STR_POWERFUL +#ifndef D_STR_QUIET +#define D_STR_QUIET "Quiet" +#endif // D_STR_QUIET +#ifndef D_STR_ECONO +#define D_STR_ECONO "Econo" +#endif // D_STR_ECONO +#ifndef D_STR_SWING +#define D_STR_SWING "Swing" +#endif // D_STR_SWING +#ifndef D_STR_SWINGH +#define D_STR_SWINGH D_STR_SWING"(H)" // Set `D_STR_SWING` first! +#endif // D_STR_SWINGH +#ifndef D_STR_SWINGV +#define D_STR_SWINGV D_STR_SWING"(V)" // Set `D_STR_SWING` first! +#endif // D_STR_SWINGV +#ifndef D_STR_BEEP +#define D_STR_BEEP "Beep" +#endif // D_STR_BEEP +#ifndef D_STR_MOULD +#define D_STR_MOULD "Mould" +#endif // D_STR_MOULD +#ifndef D_STR_CLEAN +#define D_STR_CLEAN "Clean" +#endif // D_STR_CLEAN +#ifndef D_STR_PURIFY +#define D_STR_PURIFY "Purify" +#endif // D_STR_PURIFY +#ifndef D_STR_TIMER +#define D_STR_TIMER "Timer" +#endif // D_STR_TIMER +#ifndef D_STR_ONTIMER +#define D_STR_ONTIMER D_STR_ON " " D_STR_TIMER // Set `D_STR_ON` first! +#endif // D_STR_ONTIMER +#ifndef D_STR_OFFTIMER +#define D_STR_OFFTIMER D_STR_OFF " " D_STR_TIMER // Set `D_STR_OFF` first! +#endif // D_STR_OFFTIMER +#ifndef D_STR_CLOCK +#define D_STR_CLOCK "Clock" +#endif // D_STR_CLOCK +#ifndef D_STR_COMMAND +#define D_STR_COMMAND "Command" +#endif // D_STR_COMMAND +#ifndef D_STR_XFAN +#define D_STR_XFAN "XFan" +#endif // D_STR_XFAN +#ifndef D_STR_HEALTH +#define D_STR_HEALTH "Health" +#endif // D_STR_HEALTH +#ifndef D_STR_MODEL +#define D_STR_MODEL "Model" +#endif // D_STR_MODEL +#ifndef D_STR_TEMP +#define D_STR_TEMP "Temp" +#endif // D_STR_TEMP +#ifndef D_STR_IFEEL +#define D_STR_IFEEL "IFeel" +#endif // D_STR_IFEEL +#ifndef D_STR_HUMID +#define D_STR_HUMID "Humid" +#endif // D_STR_HUMID +#ifndef D_STR_SAVE +#define D_STR_SAVE "Save" +#endif // D_STR_SAVE +#ifndef D_STR_EYE +#define D_STR_EYE "Eye" +#endif // D_STR_EYE +#ifndef D_STR_FOLLOW +#define D_STR_FOLLOW "Follow" +#endif // D_STR_FOLLOW +#ifndef D_STR_ION +#define D_STR_ION "Ion" +#endif // D_STR_ION +#ifndef D_STR_FRESH +#define D_STR_FRESH "Fresh" +#endif // D_STR_FRESH +#ifndef D_STR_HOLD +#define D_STR_HOLD "Hold" +#endif // D_STR_HOLD +#ifndef D_STR_8C_HEAT +#define D_STR_8C_HEAT "8C " D_STR_HEAT // Set `D_STR_HEAT` first! +#endif // D_STR_8C_HEAT +#ifndef D_STR_BUTTON +#define D_STR_BUTTON "Button" +#endif // D_STR_BUTTON +#ifndef D_STR_NIGHT +#define D_STR_NIGHT "Night" +#endif // D_STR_NIGHT +#ifndef D_STR_SILENT +#define D_STR_SILENT "Silent" +#endif // D_STR_SILENT +#ifndef D_STR_FILTER +#define D_STR_FILTER "Filter" +#endif // D_STR_FILTER +#ifndef D_STR_3D +#define D_STR_3D "3D" +#endif // D_STR_3D +#ifndef D_STR_CELSIUS +#define D_STR_CELSIUS "Celsius" +#endif // D_STR_CELSIUS +#ifndef D_STR_UP +#define D_STR_UP "Up" +#endif // D_STR_UP +#ifndef D_STR_TEMPUP +#define D_STR_TEMPUP D_STR_TEMP " " D_STR_UP // Set `D_STR_TEMP` first! +#endif // D_STR_TEMPUP +#ifndef D_STR_DOWN +#define D_STR_DOWN "Down" +#endif // D_STR_DOWN +#ifndef D_STR_TEMPDOWN +#define D_STR_TEMPDOWN D_STR_TEMP " " D_STR_DOWN // Set `D_STR_TEMP` first! +#endif // D_STR_TEMPDOWN +#ifndef D_STR_CHANGE +#define D_STR_CHANGE "Change" +#endif // D_STR_CHANGE +#ifndef D_STR_START +#define D_STR_START "Start" +#endif // D_STR_START +#ifndef D_STR_STOP +#define D_STR_STOP "Stop" +#endif // D_STR_STOP +#ifndef D_STR_MOVE +#define D_STR_MOVE "Move" +#endif // D_STR_MOVE +#ifndef D_STR_SET +#define D_STR_SET "Set" +#endif // D_STR_SET +#ifndef D_STR_CANCEL +#define D_STR_CANCEL "Cancel" +#endif // D_STR_CANCEL +#ifndef D_STR_COMFORT +#define D_STR_COMFORT "Comfort" +#endif // D_STR_COMFORT +#ifndef D_STR_SENSOR +#define D_STR_SENSOR "Sensor" +#endif // D_STR_SENSOR +#ifndef D_STR_DISPLAY +#define D_STR_DISPLAY "Display" +#endif // D_STR_DISPLAY +#ifndef D_STR_WEEKLY +#define D_STR_WEEKLY "Weekly" +#endif // D_STR_WEEKLY +#ifndef D_STR_WEEKLYTIMER +#define D_STR_WEEKLYTIMER D_STR_WEEKLY " " D_STR_TIMER // Needs `D_STR_WEEKLY`! +#endif // D_STR_WEEKLYTIMER +#ifndef D_STR_WIFI +#define D_STR_WIFI "WiFi" +#endif // D_STR_WIFI +#ifndef D_STR_LAST +#define D_STR_LAST "Last" +#endif // D_STR_LAST +#ifndef D_STR_FAST +#define D_STR_FAST "Fast" +#endif // D_STR_FAST +#ifndef D_STR_SLOW +#define D_STR_SLOW "Slow" +#endif // D_STR_SLOW +#ifndef D_STR_AIRFLOW +#define D_STR_AIRFLOW "Air Flow" +#endif // D_STR_AIRFLOW +#ifndef D_STR_STEP +#define D_STR_STEP "Step" +#endif // D_STR_STEP +#ifndef D_STR_NA +#define D_STR_NA "N/A" +#endif // D_STR_NA +#ifndef D_STR_INSIDE +#define D_STR_INSIDE "Inside" +#endif // D_STR_INSIDE +#ifndef D_STR_OUTSIDE +#define D_STR_OUTSIDE "Outside" +#endif // D_STR_OUTSIDE +#ifndef D_STR_LOUD +#define D_STR_LOUD "Loud" +#endif // D_STR_LOUD +#ifndef D_STR_UPPER +#define D_STR_UPPER "Upper" +#endif // D_STR_UPPER +#ifndef D_STR_LOWER +#define D_STR_LOWER "Lower" +#endif // D_STR_LOWER +#ifndef D_STR_BREEZE +#define D_STR_BREEZE "Breeze" +#endif // D_STR_BREEZE +#ifndef D_STR_CIRCULATE +#define D_STR_CIRCULATE "Circulate" +#endif // D_STR_CIRCULATE +#ifndef D_STR_CEILING +#define D_STR_CEILING "Ceiling" +#endif // D_STR_CEILING +#ifndef D_STR_WALL +#define D_STR_WALL "Wall" +#endif // D_STR_WALL +#ifndef D_STR_ROOM +#define D_STR_ROOM "Room" +#endif // D_STR_ROOM +#ifndef D_STR_6THSENSE +#define D_STR_6THSENSE "6th Sense" +#endif // D_STR_6THSENSE +#ifndef D_STR_ZONEFOLLOW +#define D_STR_ZONEFOLLOW "Zone Follow" +#endif // D_STR_ZONEFOLLOW +#ifndef D_STR_FIXED +#define D_STR_FIXED "Fixed" +#endif // D_STR_FIXED + +#ifndef D_STR_AUTO +#define D_STR_AUTO "Auto" +#endif // D_STR_AUTO +#ifndef D_STR_AUTOMATIC +#define D_STR_AUTOMATIC "Automatic" +#endif // D_STR_AUTOMATIC +#ifndef D_STR_MANUAL +#define D_STR_MANUAL "Manual" +#endif // D_STR_MANUAL +#ifndef D_STR_COOL +#define D_STR_COOL "Cool" +#endif // D_STR_COOL +#ifndef D_STR_HEAT +#define D_STR_HEAT "Heat" +#endif // D_STR_HEAT +#ifndef D_STR_FAN +#define D_STR_FAN "Fan" +#endif // D_STR_FAN +#ifndef D_STR_FANONLY +#define D_STR_FANONLY "fan_only" +#endif // D_STR_FANONLY +#ifndef D_STR_DRY +#define D_STR_DRY "Dry" +#endif // D_STR_DRY + +#ifndef D_STR_MAX +#define D_STR_MAX "Max" +#endif // D_STR_MAX +#ifndef D_STR_MAXIMUM +#define D_STR_MAXIMUM "Maximum" +#endif // D_STR_MAXIMUM +#ifndef D_STR_MIN +#define D_STR_MIN "Min" +#endif // D_STR_MIN +#ifndef D_STR_MINIMUM +#define D_STR_MINIMUM "Minimum" +#endif // D_STR_MINIMUM +#ifndef D_STR_MED +#define D_STR_MED "Med" +#endif // D_STR_MED +#ifndef D_STR_MEDIUM +#define D_STR_MEDIUM "Medium" +#endif // D_STR_MEDIUM + +#ifndef D_STR_HIGHEST +#define D_STR_HIGHEST "Highest" +#endif // D_STR_HIGHEST +#ifndef D_STR_HIGH +#define D_STR_HIGH "High" +#endif // D_STR_HIGH +#ifndef D_STR_HI +#define D_STR_HI "Hi" +#endif // D_STR_HI +#ifndef D_STR_MID +#define D_STR_MID "Mid" +#endif // D_STR_MID +#ifndef D_STR_MIDDLE +#define D_STR_MIDDLE "Middle" +#endif // D_STR_MIDDLE +#ifndef D_STR_LOW +#define D_STR_LOW "Low" +#endif // D_STR_LOW +#ifndef D_STR_LO +#define D_STR_LO "Lo" +#endif // D_STR_LO +#ifndef D_STR_LOWEST +#define D_STR_LOWEST "Lowest" +#endif // D_STR_LOWEST +#ifndef D_STR_RIGHT +#define D_STR_RIGHT "Right" +#endif // D_STR_RIGHT +#ifndef D_STR_MAXRIGHT +#define D_STR_MAXRIGHT D_STR_MAX " " D_STR_RIGHT // Set `D_STR_MAX` first! +#endif // D_STR_MAXRIGHT +#ifndef D_STR_RIGHTMAX_NOSPACE +#define D_STR_RIGHTMAX_NOSPACE D_STR_RIGHT D_STR_MAX // Set `D_STR_MAX` first! +#endif // D_STR_RIGHTMAX_NOSPACE +#ifndef D_STR_LEFT +#define D_STR_LEFT "Left" +#endif // D_STR_LEFT +#ifndef D_STR_MAXLEFT +#define D_STR_MAXLEFT D_STR_MAX " " D_STR_LEFT // Set `D_STR_MAX` first! +#endif // D_STR_MAXLEFT +#ifndef D_STR_LEFTMAX_NOSPACE +#define D_STR_LEFTMAX_NOSPACE D_STR_LEFT D_STR_MAX // Set `D_STR_MAX` first! +#endif // D_STR_LEFTMAX_NOSPACE +#ifndef D_STR_WIDE +#define D_STR_WIDE "Wide" +#endif // D_STR_WIDE +#ifndef D_STR_CENTRE +#define D_STR_CENTRE "Centre" +#endif // D_STR_CENTRE +#ifndef D_STR_TOP +#define D_STR_TOP "Top" +#endif // D_STR_TOP +#ifndef D_STR_BOTTOM +#define D_STR_BOTTOM "Bottom" +#endif // D_STR_BOTTOM + +// Compound words/phrases/descriptions from pre-defined words. +// Note: Obviously these need to be defined *after* their component words. +#ifndef D_STR_EYEAUTO +#define D_STR_EYEAUTO D_STR_EYE " " D_STR_AUTO +#endif // D_STR_EYEAUTO +#ifndef D_STR_LIGHTTOGGLE +#define D_STR_LIGHTTOGGLE D_STR_LIGHT " " D_STR_TOGGLE +#endif // D_STR_LIGHTTOGGLE +#ifndef D_STR_OUTSIDEQUIET +#define D_STR_OUTSIDEQUIET D_STR_OUTSIDE " " D_STR_QUIET +#endif // D_STR_OUTSIDEQUIET +#ifndef D_STR_POWERTOGGLE +#define D_STR_POWERTOGGLE D_STR_POWER " " D_STR_TOGGLE +#endif // D_STR_POWERTOGGLE +#ifndef D_STR_POWERBUTTON +#define D_STR_POWERBUTTON D_STR_POWER " " D_STR_BUTTON +#endif // D_STR_POWERBUTTON +#ifndef D_STR_PREVIOUSPOWER +#define D_STR_PREVIOUSPOWER D_STR_PREVIOUS " " D_STR_POWER +#endif // D_STR_PREVIOUSPOWER +#ifndef D_STR_DISPLAYTEMP +#define D_STR_DISPLAYTEMP D_STR_DISPLAY " " D_STR_TEMP +#endif // D_STR_DISPLAYTEMP +#ifndef D_STR_SENSORTEMP +#define D_STR_SENSORTEMP D_STR_SENSOR " " D_STR_TEMP +#endif // D_STR_SENSORTEMP +#ifndef D_STR_SLEEP_TIMER +#define D_STR_SLEEP_TIMER D_STR_SLEEP " " D_STR_TIMER +#endif // D_STR_SLEEP_TIMER +#ifndef D_STR_SWINGVMODE +#define D_STR_SWINGVMODE D_STR_SWINGV " " D_STR_MODE +#endif // D_STR_SWINGVMODE +#ifndef D_STR_SWINGVTOGGLE +#define D_STR_SWINGVTOGGLE D_STR_SWINGV " " D_STR_TOGGLE +#endif // D_STR_SWINGVTOGGLE + +// Separators +#ifndef D_CHR_TIME_SEP +#define D_CHR_TIME_SEP ':' +#endif // D_CHR_TIME_SEP +#ifndef D_STR_SPACELBRACE +#define D_STR_SPACELBRACE " (" +#endif // D_STR_SPACELBRACE +#ifndef D_STR_COMMASPACE +#define D_STR_COMMASPACE ", " +#endif // D_STR_COMMASPACE +#ifndef D_STR_COLONSPACE +#define D_STR_COLONSPACE ": " +#endif // D_STR_COLONSPACE + +#ifndef D_STR_DAY +#define D_STR_DAY "Day" +#endif // D_STR_DAY +#ifndef D_STR_DAYS +#define D_STR_DAYS D_STR_DAY "s" +#endif // D_STR_DAYS +#ifndef D_STR_HOUR +#define D_STR_HOUR "Hour" +#endif // D_STR_HOUR +#ifndef D_STR_HOURS +#define D_STR_HOURS D_STR_HOUR "s" +#endif // D_STR_HOURS +#ifndef D_STR_MINUTE +#define D_STR_MINUTE "Minute" +#endif // D_STR_MINUTE +#ifndef D_STR_MINUTES +#define D_STR_MINUTES D_STR_MINUTE "s" +#endif // D_STR_MINUTES +#ifndef D_STR_SECOND +#define D_STR_SECOND "Second" +#endif // D_STR_SECOND +#ifndef D_STR_SECONDS +#define D_STR_SECONDS D_STR_SECOND "s" +#endif // D_STR_SECONDS +#ifndef D_STR_NOW +#define D_STR_NOW "Now" +#endif // D_STR_NOW +#ifndef D_STR_THREELETTERDAYS +#define D_STR_THREELETTERDAYS "SunMonTueWedThuFriSat" +#endif // D_STR_THREELETTERDAYS + +#ifndef D_STR_YES +#define D_STR_YES "Yes" +#endif // D_STR_YES +#ifndef D_STR_NO +#define D_STR_NO "No" +#endif // D_STR_NO +#ifndef D_STR_TRUE +#define D_STR_TRUE "True" +#endif // D_STR_TRUE +#ifndef D_STR_FALSE +#define D_STR_FALSE "False" +#endif // D_STR_FALSE + +#ifndef D_STR_REPEAT +#define D_STR_REPEAT "Repeat" +#endif // D_STR_REPEAT +#ifndef D_STR_CODE +#define D_STR_CODE "Code" +#endif // D_STR_CODE +#ifndef D_STR_BITS +#define D_STR_BITS "Bits" +#endif // D_STR_BITS + +// Protocols Names +#ifndef D_STR_AIRWELL +#define D_STR_AIRWELL "AIRWELL" +#endif // D_STR_AIRWELL +#ifndef D_STR_AIWA_RC_T501 +#define D_STR_AIWA_RC_T501 "AIWA_RC_T501" +#endif // D_STR_AIWA_RC_T501 +#ifndef D_STR_AMCOR +#define D_STR_AMCOR "AMCOR" +#endif // D_STR_AMCOR +#ifndef D_STR_ARGO +#define D_STR_ARGO "ARGO" +#endif // D_STR_ARGO +#ifndef D_STR_CARRIER_AC +#define D_STR_CARRIER_AC "CARRIER_AC" +#endif // D_STR_CARRIER_AC +#ifndef D_STR_CARRIER_AC40 +#define D_STR_CARRIER_AC40 D_STR_CARRIER_AC "40" +#endif // D_STR_CARRIER_AC40 +#ifndef D_STR_CARRIER_AC64 +#define D_STR_CARRIER_AC64 D_STR_CARRIER_AC "64" +#endif // D_STR_CARRIER_AC64 +#ifndef D_STR_COOLIX +#define D_STR_COOLIX "COOLIX" +#endif // D_STR_COOLIX +#ifndef D_STR_CORONA_AC +#define D_STR_CORONA_AC "CORONA_AC" +#endif // D_STR_CORONA_AC +#ifndef D_STR_DAIKIN +#define D_STR_DAIKIN "DAIKIN" +#endif // D_STR_DAIKIN +#ifndef D_STR_DAIKIN128 +#define D_STR_DAIKIN128 "DAIKIN128" +#endif // D_STR_DAIKIN128 +#ifndef D_STR_DAIKIN152 +#define D_STR_DAIKIN152 "DAIKIN152" +#endif // D_STR_DAIKIN152 +#ifndef D_STR_DAIKIN160 +#define D_STR_DAIKIN160 "DAIKIN160" +#endif // D_STR_DAIKIN160 +#ifndef D_STR_DAIKIN176 +#define D_STR_DAIKIN176 "DAIKIN176" +#endif // D_STR_DAIKIN176 +#ifndef D_STR_DAIKIN2 +#define D_STR_DAIKIN2 "DAIKIN2" +#endif // D_STR_DAIKIN2 +#ifndef D_STR_DAIKIN216 +#define D_STR_DAIKIN216 "DAIKIN216" +#endif // D_STR_DAIKIN216 +#ifndef D_STR_DAIKIN64 +#define D_STR_DAIKIN64 "DAIKIN64" +#endif // D_STR_DAIKIN64 +#ifndef D_STR_DELONGHI_AC +#define D_STR_DELONGHI_AC "DELONGHI_AC" +#endif // D_STR_DELONGHI_AC +#ifndef D_STR_DENON +#define D_STR_DENON "DENON" +#endif // D_STR_DENON +#ifndef D_STR_DISH +#define D_STR_DISH "DISH" +#endif // D_STR_DISH +#ifndef D_STR_DOSHISHA +#define D_STR_DOSHISHA "DOSHISHA" +#endif // D_STR_DOSHISHA +#ifndef D_STR_ELECTRA_AC +#define D_STR_ELECTRA_AC "ELECTRA_AC" +#endif // D_STR_ELECTRA_AC +#ifndef D_STR_EPSON +#define D_STR_EPSON "EPSON" +#endif // D_STR_EPSON +#ifndef D_STR_FUJITSU_AC +#define D_STR_FUJITSU_AC "FUJITSU_AC" +#endif // D_STR_FUJITSU_AC +#ifndef D_STR_GICABLE +#define D_STR_GICABLE "GICABLE" +#endif // D_STR_GICABLE +#ifndef D_STR_GLOBALCACHE +#define D_STR_GLOBALCACHE "GLOBALCACHE" +#endif // D_STR_GLOBALCACHE +#ifndef D_STR_GOODWEATHER +#define D_STR_GOODWEATHER "GOODWEATHER" +#endif // D_STR_GOODWEATHER +#ifndef D_STR_GREE +#define D_STR_GREE "GREE" +#endif // D_STR_GREE +#ifndef D_STR_HAIER_AC +#define D_STR_HAIER_AC "HAIER_AC" +#endif // D_STR_HAIER_AC +#ifndef D_STR_HAIER_AC_YRW02 +#define D_STR_HAIER_AC_YRW02 "HAIER_AC_YRW02" +#endif // D_STR_HAIER_AC_YRW02 +#ifndef D_STR_HITACHI_AC +#define D_STR_HITACHI_AC "HITACHI_AC" +#endif // D_STR_HITACHI_AC +#ifndef D_STR_HITACHI_AC1 +#define D_STR_HITACHI_AC1 "HITACHI_AC1" +#endif // D_STR_HITACHI_AC1 +#ifndef D_STR_HITACHI_AC2 +#define D_STR_HITACHI_AC2 "HITACHI_AC2" +#endif // D_STR_HITACHI_AC2 +#ifndef D_STR_HITACHI_AC3 +#define D_STR_HITACHI_AC3 "HITACHI_AC3" +#endif // D_STR_HITACHI_AC3 +#ifndef D_STR_HITACHI_AC344 +#define D_STR_HITACHI_AC344 "HITACHI_AC344" +#endif // D_STR_HITACHI_AC344 +#ifndef D_STR_HITACHI_AC424 +#define D_STR_HITACHI_AC424 "HITACHI_AC424" +#endif // D_STR_HITACHI_AC424 +#ifndef D_STR_INAX +#define D_STR_INAX "INAX" +#endif // D_STR_INAX +#ifndef D_STR_JVC +#define D_STR_JVC "JVC" +#endif // D_STR_JVC +#ifndef D_STR_KELVINATOR +#define D_STR_KELVINATOR "KELVINATOR" +#endif // D_STR_KELVINATOR +#ifndef D_STR_LASERTAG +#define D_STR_LASERTAG "LASERTAG" +#endif // D_STR_LASERTAG +#ifndef D_STR_LEGOPF +#define D_STR_LEGOPF "LEGOPF" +#endif // D_STR_LEGOPF +#ifndef D_STR_LG +#define D_STR_LG "LG" +#endif // D_STR_LG +#ifndef D_STR_LG2 +#define D_STR_LG2 "LG2" +#endif // D_STR_LG2 +#ifndef D_STR_LUTRON +#define D_STR_LUTRON "LUTRON" +#endif // D_STR_LUTRON +#ifndef D_STR_MAGIQUEST +#define D_STR_MAGIQUEST "MAGIQUEST" +#endif // D_STR_MAGIQUEST +#ifndef D_STR_MIDEA +#define D_STR_MIDEA "MIDEA" +#endif // D_STR_MIDEA +#ifndef D_STR_MIDEA24 +#define D_STR_MIDEA24 "MIDEA24" +#endif // D_STR_MIDEA24 +#ifndef D_STR_MITSUBISHI +#define D_STR_MITSUBISHI "MITSUBISHI" +#endif // D_STR_MITSUBISHI +#ifndef D_STR_MITSUBISHI112 +#define D_STR_MITSUBISHI112 "MITSUBISHI112" +#endif // D_STR_MITSUBISHI112 +#ifndef D_STR_MITSUBISHI136 +#define D_STR_MITSUBISHI136 "MITSUBISHI136" +#endif // D_STR_MITSUBISHI136 +#ifndef D_STR_MITSUBISHI2 +#define D_STR_MITSUBISHI2 "MITSUBISHI2" +#endif // D_STR_MITSUBISHI2 +#ifndef D_STR_MITSUBISHI_AC +#define D_STR_MITSUBISHI_AC "MITSUBISHI_AC" +#endif // D_STR_MITSUBISHI_AC +#ifndef D_STR_MITSUBISHI_HEAVY_152 +#define D_STR_MITSUBISHI_HEAVY_152 "MITSUBISHI_HEAVY_152" +#endif // D_STR_MITSUBISHI_HEAVY_152 +#ifndef D_STR_MITSUBISHI_HEAVY_88 +#define D_STR_MITSUBISHI_HEAVY_88 "MITSUBISHI_HEAVY_88" +#endif // D_STR_MITSUBISHI_HEAVY_88 +#ifndef D_STR_MULTIBRACKETS +#define D_STR_MULTIBRACKETS "MULTIBRACKETS" +#endif // D_STR_MULTIBRACKETS +#ifndef D_STR_MWM +#define D_STR_MWM "MWM" +#endif // D_STR_MWM +#ifndef D_STR_NEC +#define D_STR_NEC "NEC" +#endif // D_STR_NEC +#ifndef D_STR_NEC_LIKE +#define D_STR_NEC_LIKE D_STR_NEC "_LIKE" +#endif // D_STR_NEC_LIKE +#ifndef D_STR_NEC_NON_STRICT +#define D_STR_NEC_NON_STRICT D_STR_NEC " (NON-STRICT)" +#endif // D_STR_NEC_NON_STRICT +#ifndef D_STR_NEOCLIMA +#define D_STR_NEOCLIMA "NEOCLIMA" +#endif // D_STR_NEOCLIMA +#ifndef D_STR_NIKAI +#define D_STR_NIKAI "NIKAI" +#endif // D_STR_NIKAI +#ifndef D_STR_PANASONIC +#define D_STR_PANASONIC "PANASONIC" +#endif // D_STR_PANASONIC +#ifndef D_STR_PANASONIC_AC +#define D_STR_PANASONIC_AC "PANASONIC_AC" +#endif // D_STR_PANASONIC_AC +#ifndef D_STR_PIONEER +#define D_STR_PIONEER "PIONEER" +#endif // D_STR_PIONEER +#ifndef D_STR_PRONTO +#define D_STR_PRONTO "PRONTO" +#endif // D_STR_PRONTO +#ifndef D_STR_RAW +#define D_STR_RAW "RAW" +#endif // D_STR_RAW +#ifndef D_STR_RC5 +#define D_STR_RC5 "RC5" +#endif // D_STR_RC5 +#ifndef D_STR_RC5X +#define D_STR_RC5X "RC5X" +#endif // D_STR_RC5X +#ifndef D_STR_RC6 +#define D_STR_RC6 "RC6" +#endif // D_STR_RC6 +#ifndef D_STR_RCMM +#define D_STR_RCMM "RCMM" +#endif // D_STR_RCMM +#ifndef D_STR_SAMSUNG +#define D_STR_SAMSUNG "SAMSUNG" +#endif // D_STR_SAMSUNG +#ifndef D_STR_SAMSUNG36 +#define D_STR_SAMSUNG36 "SAMSUNG36" +#endif // D_STR_SAMSUNG36 +#ifndef D_STR_SAMSUNG_AC +#define D_STR_SAMSUNG_AC "SAMSUNG_AC" +#endif // D_STR_SAMSUNG_AC +#ifndef D_STR_SANYO +#define D_STR_SANYO "SANYO" +#endif // D_STR_SANYO +#ifndef D_STR_SANYO_LC7461 +#define D_STR_SANYO_LC7461 "SANYO_LC7461" +#endif // D_STR_SANYO_LC7461 +#ifndef D_STR_SHARP +#define D_STR_SHARP "SHARP" +#endif // D_STR_SHARP +#ifndef D_STR_SHARP_AC +#define D_STR_SHARP_AC "SHARP_AC" +#endif // D_STR_SHARP_AC +#ifndef D_STR_SHERWOOD +#define D_STR_SHERWOOD "SHERWOOD" +#endif // D_STR_SHERWOOD +#ifndef D_STR_SONY +#define D_STR_SONY "SONY" +#endif // D_STR_SONY +#ifndef D_STR_SONY_38K +#define D_STR_SONY_38K "SONY_38K" +#endif // D_STR_SONY_38K +#ifndef D_STR_SYMPHONY +#define D_STR_SYMPHONY "SYMPHONY" +#endif // D_STR_SYMPHONY +#ifndef D_STR_TCL112AC +#define D_STR_TCL112AC "TCL112AC" +#endif // D_STR_TCL112AC +#ifndef D_STR_TECO +#define D_STR_TECO "TECO" +#endif // D_STR_TECO +#ifndef D_STR_TOSHIBA_AC +#define D_STR_TOSHIBA_AC "TOSHIBA_AC" +#endif // D_STR_TOSHIBA_AC +#ifndef D_STR_TROTEC +#define D_STR_TROTEC "TROTEC" +#endif // D_STR_TROTEC +#ifndef D_STR_UNUSED +#define D_STR_UNUSED "UNUSED" +#endif // D_STR_UNUSED +#ifndef D_STR_VESTEL_AC +#define D_STR_VESTEL_AC "VESTEL_AC" +#endif // D_STR_VESTEL_AC +#ifndef D_STR_WHIRLPOOL_AC +#define D_STR_WHIRLPOOL_AC "WHIRLPOOL_AC" +#endif // D_STR_WHIRLPOOL_AC +#ifndef D_STR_WHYNTER +#define D_STR_WHYNTER "WHYNTER" +#endif // D_STR_WHYNTER +#ifndef D_STR_ZEPEAL +#define D_STR_ZEPEAL "ZEPEAL" +#endif // D_STR_ZEPEAL + +// IRrecvDumpV2+ +#ifndef D_STR_TIMESTAMP +#define D_STR_TIMESTAMP "Timestamp" +#endif // D_STR_TIMESTAMP +#ifndef D_STR_LIBRARY +#define D_STR_LIBRARY "Library" +#endif // D_STR_LIBRARY +#ifndef D_STR_MESGDESC +#define D_STR_MESGDESC "Mesg Desc." +#endif // D_STR_MESGDESC +#ifndef D_STR_IRRECVDUMP_STARTUP +#define D_STR_IRRECVDUMP_STARTUP \ + "IRrecvDump is now running and waiting for IR input on Pin %d" +#endif // D_STR_IRRECVDUMP_STARTUP +#ifndef D_WARN_BUFFERFULL +#define D_WARN_BUFFERFULL \ + "WARNING: IR code is too big for buffer (>= %d). " \ + "This result shouldn't be trusted until this is resolved. " \ + "Edit & increase `kCaptureBufferSize`." +#endif // D_WARN_BUFFERFULL + +#endif // LOCALE_DEFAULTS_H_ diff --git a/lib/IRremoteESP8266-2.7.5/src/locale/en-AU.h b/lib/IRremoteESP8266-2.7.8/src/locale/en-AU.h similarity index 100% rename from lib/IRremoteESP8266-2.7.5/src/locale/en-AU.h rename to lib/IRremoteESP8266-2.7.8/src/locale/en-AU.h diff --git a/lib/IRremoteESP8266-2.7.5/src/locale/en-IE.h b/lib/IRremoteESP8266-2.7.8/src/locale/en-IE.h similarity index 100% rename from lib/IRremoteESP8266-2.7.5/src/locale/en-IE.h rename to lib/IRremoteESP8266-2.7.8/src/locale/en-IE.h diff --git a/lib/IRremoteESP8266-2.7.5/src/locale/en-UK.h b/lib/IRremoteESP8266-2.7.8/src/locale/en-UK.h similarity index 100% rename from lib/IRremoteESP8266-2.7.5/src/locale/en-UK.h rename to lib/IRremoteESP8266-2.7.8/src/locale/en-UK.h diff --git a/lib/IRremoteESP8266-2.7.5/src/locale/en-US.h b/lib/IRremoteESP8266-2.7.8/src/locale/en-US.h similarity index 100% rename from lib/IRremoteESP8266-2.7.5/src/locale/en-US.h rename to lib/IRremoteESP8266-2.7.8/src/locale/en-US.h diff --git a/lib/IRremoteESP8266-2.7.5/src/locale/es-ES.h b/lib/IRremoteESP8266-2.7.8/src/locale/es-ES.h similarity index 97% rename from lib/IRremoteESP8266-2.7.5/src/locale/es-ES.h rename to lib/IRremoteESP8266-2.7.8/src/locale/es-ES.h index 52f22333d..e8e54e5b2 100644 --- a/lib/IRremoteESP8266-2.7.5/src/locale/es-ES.h +++ b/lib/IRremoteESP8266-2.7.8/src/locale/es-ES.h @@ -121,11 +121,11 @@ #define D_STR_REPEAT "Repetir" #define D_STR_CODE "Codigo" -// IRrecvDumpV2 +// IRrecvDumpV2+ #define D_STR_TIMESTAMP "marca de tiempo" #define D_STR_LIBRARY "Libreria" #define D_STR_IRRECVDUMP_STARTUP \ - "IRrecvDumpV2 esta ahora corriendo y esperando por comando IR en Pin %d" + "IRrecvDump esta ahora corriendo y esperando por comando IR en Pin %d" #ifndef D_WARN_BUFFERFULL #define D_WARN_BUFFERFULL \ "WARNING: Codigo IR es muy grande para el buffer (>= %d). "\ diff --git a/lib/IRremoteESP8266-2.7.5/src/locale/fr-FR.h b/lib/IRremoteESP8266-2.7.8/src/locale/fr-FR.h similarity index 97% rename from lib/IRremoteESP8266-2.7.5/src/locale/fr-FR.h rename to lib/IRremoteESP8266-2.7.8/src/locale/fr-FR.h index 0eae39e2e..f8c2f8235 100644 --- a/lib/IRremoteESP8266-2.7.5/src/locale/fr-FR.h +++ b/lib/IRremoteESP8266-2.7.8/src/locale/fr-FR.h @@ -103,12 +103,12 @@ #define D_STR_REPEAT "Répetition" -// IRrecvDumpV2 +// IRrecvDumpV2+ #define D_STR_TIMESTAMP "Horodatage" #define D_STR_LIBRARY "Bibliothèque" #define D_STR_MESGDESC "Rèférence" #define D_STR_IRRECVDUMP_STARTUP \ - "IRrecvDumpV2 fonctionne et attend l’entrée IR sur la broche %d" + "IRrecvDump fonctionne et attend l’entrée IR sur la broche %d" #define D_WARN_BUFFERFULL \ "ATTENTION: IR Code est trop gros pour le buffer (>= %d). " \ "Le résultat ne doit pas être approuvé avant que cela soit résolu. " \ diff --git a/lib/IRremoteESP8266-2.7.5/src/locale/it-IT.h b/lib/IRremoteESP8266-2.7.8/src/locale/it-IT.h similarity index 98% rename from lib/IRremoteESP8266-2.7.5/src/locale/it-IT.h rename to lib/IRremoteESP8266-2.7.8/src/locale/it-IT.h index b04a129d2..9457b6e40 100644 --- a/lib/IRremoteESP8266-2.7.5/src/locale/it-IT.h +++ b/lib/IRremoteESP8266-2.7.8/src/locale/it-IT.h @@ -141,12 +141,12 @@ #define D_STR_REPEAT "Ripeti" #define D_STR_CODE "Codice" #define D_STR_BITS "Bit" -// IRrecvDumpV2 +// IRrecvDumpV2+ #define D_STR_LIBRARY "Libreria" #define D_STR_MESGDESC "Desc. Mess." #define D_STR_IRRECVDUMP_STARTUP \ - "IRrecvDumpV2 è ora attivo e in attesa di segnali IR dal pin %d" + "IRrecvDump è ora attivo e in attesa di segnali IR dal pin %d" #ifndef D_WARN_BUFFERFULL #define D_WARN_BUFFERFULL \ diff --git a/lib/IRremoteESP8266-2.7.5/src/locale/defaults.h b/lib/IRremoteESP8266-2.7.8/src/locale/zh-CN.h similarity index 67% rename from lib/IRremoteESP8266-2.7.5/src/locale/defaults.h rename to lib/IRremoteESP8266-2.7.8/src/locale/zh-CN.h index 509e35cfe..5330c93e3 100644 --- a/lib/IRremoteESP8266-2.7.5/src/locale/defaults.h +++ b/lib/IRremoteESP8266-2.7.8/src/locale/zh-CN.h @@ -1,67 +1,56 @@ -// Copyright 2019 - David Conran (@crankyoldgit) -// The default text to use throughout the library. -// The library will use this text if no locale (_IR_LOCALE_) is set or if -// the locale doesn't define particular values. -// If they are defined, this file should NOT override them. -// -// This file should contain a #define for every translateable/locale dependant -// string used by the library. Language specific files don't have to include -// everything. -// -// NOTE: ASCII/UTF-8 characters only. Unicode is NOT supported. -// -// The defaults are English (AU) / en-AU. Australia (AU) is pretty much the same -// as English (UK) for this libraries use case. -#ifndef LOCALE_DEFAULTS_H_ -#define LOCALE_DEFAULTS_H_ +// Copyright 2020 - MiaoYi (@Caffreyfans) +// Locale/language file for China / Simplified. +// This file will override the default values located in `defaults.h`. +#ifndef LOCALE_ZH_CN_H_ +#define LOCALE_ZH_CN_H_ #ifndef D_STR_UNKNOWN -#define D_STR_UNKNOWN "UNKNOWN" +#define D_STR_UNKNOWN "未知" #endif // D_STR_UNKNOWN #ifndef D_STR_PROTOCOL -#define D_STR_PROTOCOL "Protocol" +#define D_STR_PROTOCOL "协议" #endif // D_STR_PROTOCOL #ifndef D_STR_POWER -#define D_STR_POWER "Power" +#define D_STR_POWER "电源" #endif // D_STR_POWER #ifndef D_STR_PREVIOUS -#define D_STR_PREVIOUS "Previous" +#define D_STR_PREVIOUS "以前" #endif // D_STR_PREVIOUS #ifndef D_STR_ON -#define D_STR_ON "On" +#define D_STR_ON "开" #endif // D_STR_ON #ifndef D_STR_OFF -#define D_STR_OFF "Off" +#define D_STR_OFF "关" #endif // D_STR_OFF #ifndef D_STR_MODE -#define D_STR_MODE "Mode" +#define D_STR_MODE "模式" #endif // D_STR_MODE #ifndef D_STR_TOGGLE -#define D_STR_TOGGLE "Toggle" +#define D_STR_TOGGLE "切换" #endif // D_STR_TOGGLE #ifndef D_STR_TURBO -#define D_STR_TURBO "Turbo" +#define D_STR_TURBO "强力" #endif // D_STR_TURBO #ifndef D_STR_SUPER -#define D_STR_SUPER "Super" +#define D_STR_SUPER "超级" #endif // D_STR_SUPER #ifndef D_STR_SLEEP -#define D_STR_SLEEP "Sleep" +#define D_STR_SLEEP "睡眠" #endif // D_STR_SLEEP #ifndef D_STR_LIGHT -#define D_STR_LIGHT "Light" +#define D_STR_LIGHT "灯光" #endif // D_STR_LIGHT #ifndef D_STR_POWERFUL -#define D_STR_POWERFUL "Powerful" +#define D_STR_POWERFUL "强劲模式" #endif // D_STR_POWERFUL #ifndef D_STR_QUIET -#define D_STR_QUIET "Quiet" +#define D_STR_QUIET "安静" #endif // D_STR_QUIET #ifndef D_STR_ECONO -#define D_STR_ECONO "Econo" +#define D_STR_ECONO "经济" #endif // D_STR_ECONO #ifndef D_STR_SWING -#define D_STR_SWING "Swing" +#define D_STR_SWING "扫风" #endif // D_STR_SWING #ifndef D_STR_SWINGH #define D_STR_SWINGH D_STR_SWING"(H)" // Set `D_STR_SWING` first! @@ -70,19 +59,19 @@ #define D_STR_SWINGV D_STR_SWING"(V)" // Set `D_STR_SWING` first! #endif // D_STR_SWINGV #ifndef D_STR_BEEP -#define D_STR_BEEP "Beep" +#define D_STR_BEEP "蜂鸣" #endif // D_STR_BEEP #ifndef D_STR_MOULD -#define D_STR_MOULD "Mould" +#define D_STR_MOULD "模子" #endif // D_STR_MOULD #ifndef D_STR_CLEAN -#define D_STR_CLEAN "Clean" +#define D_STR_CLEAN "清洁" #endif // D_STR_CLEAN #ifndef D_STR_PURIFY -#define D_STR_PURIFY "Purify" +#define D_STR_PURIFY "净化" #endif // D_STR_PURIFY #ifndef D_STR_TIMER -#define D_STR_TIMER "Timer" +#define D_STR_TIMER "计时器" #endif // D_STR_TIMER #ifndef D_STR_ONTIMER #define D_STR_ONTIMER D_STR_ON " " D_STR_TIMER // Set `D_STR_ON` first! @@ -91,106 +80,106 @@ #define D_STR_OFFTIMER D_STR_OFF " " D_STR_TIMER // Set `D_STR_OFF` first! #endif // D_STR_OFFTIMER #ifndef D_STR_CLOCK -#define D_STR_CLOCK "Clock" +#define D_STR_CLOCK "时钟" #endif // D_STR_CLOCK #ifndef D_STR_COMMAND -#define D_STR_COMMAND "Command" +#define D_STR_COMMAND "命令" #endif // D_STR_COMMAND #ifndef D_STR_XFAN #define D_STR_XFAN "XFan" #endif // D_STR_XFAN #ifndef D_STR_HEALTH -#define D_STR_HEALTH "Health" +#define D_STR_HEALTH "健康" #endif // D_STR_HEALTH #ifndef D_STR_MODEL -#define D_STR_MODEL "Model" +#define D_STR_MODEL "模式" #endif // D_STR_MODEL #ifndef D_STR_TEMP -#define D_STR_TEMP "Temp" +#define D_STR_TEMP "温度" #endif // D_STR_TEMP #ifndef D_STR_IFEEL #define D_STR_IFEEL "IFeel" #endif // D_STR_IFEEL #ifndef D_STR_HUMID -#define D_STR_HUMID "Humid" +#define D_STR_HUMID "湿度" #endif // D_STR_HUMID #ifndef D_STR_SAVE -#define D_STR_SAVE "Save" +#define D_STR_SAVE "保存" #endif // D_STR_SAVE #ifndef D_STR_EYE -#define D_STR_EYE "Eye" +#define D_STR_EYE "眼" #endif // D_STR_EYE #ifndef D_STR_FOLLOW -#define D_STR_FOLLOW "Follow" +#define D_STR_FOLLOW "跟随" #endif // D_STR_FOLLOW #ifndef D_STR_ION #define D_STR_ION "Ion" #endif // D_STR_ION #ifndef D_STR_FRESH -#define D_STR_FRESH "Fresh" +#define D_STR_FRESH "刷新" #endif // D_STR_FRESH #ifndef D_STR_HOLD -#define D_STR_HOLD "Hold" +#define D_STR_HOLD "保持" #endif // D_STR_HOLD #ifndef D_STR_8C_HEAT #define D_STR_8C_HEAT "8C " D_STR_HEAT // Set `D_STR_HEAT` first! #endif // D_STR_8C_HEAT #ifndef D_STR_BUTTON -#define D_STR_BUTTON "Button" +#define D_STR_BUTTON "按钮" #endif // D_STR_BUTTON #ifndef D_STR_NIGHT -#define D_STR_NIGHT "Night" +#define D_STR_NIGHT "夜间" #endif // D_STR_NIGHT #ifndef D_STR_SILENT -#define D_STR_SILENT "Silent" +#define D_STR_SILENT "安静" #endif // D_STR_SILENT #ifndef D_STR_FILTER -#define D_STR_FILTER "Filter" +#define D_STR_FILTER "过滤" #endif // D_STR_FILTER #ifndef D_STR_3D #define D_STR_3D "3D" #endif // D_STR_3D #ifndef D_STR_CELSIUS -#define D_STR_CELSIUS "Celsius" +#define D_STR_CELSIUS "摄氏度" #endif // D_STR_CELSIUS #ifndef D_STR_UP -#define D_STR_UP "Up" +#define D_STR_UP "上" #endif // D_STR_UP #ifndef D_STR_TEMPUP #define D_STR_TEMPUP D_STR_TEMP " " D_STR_UP // Set `D_STR_TEMP` first! #endif // D_STR_TEMPUP #ifndef D_STR_DOWN -#define D_STR_DOWN "Down" +#define D_STR_DOWN "下" #endif // D_STR_DOWN #ifndef D_STR_TEMPDOWN #define D_STR_TEMPDOWN D_STR_TEMP " " D_STR_DOWN // Set `D_STR_TEMP` first! #endif // D_STR_TEMPDOWN #ifndef D_STR_CHANGE -#define D_STR_CHANGE "Change" +#define D_STR_CHANGE "改变" #endif // D_STR_CHANGE #ifndef D_STR_START -#define D_STR_START "Start" +#define D_STR_START "开始" #endif // D_STR_START #ifndef D_STR_STOP -#define D_STR_STOP "Stop" +#define D_STR_STOP "结束" #endif // D_STR_STOP #ifndef D_STR_MOVE -#define D_STR_MOVE "Move" +#define D_STR_MOVE "移动" #endif // D_STR_MOVE #ifndef D_STR_SET -#define D_STR_SET "Set" +#define D_STR_SET "设置" #endif // D_STR_SET #ifndef D_STR_CANCEL -#define D_STR_CANCEL "Cancel" +#define D_STR_CANCEL "取消" #endif // D_STR_CANCEL #ifndef D_STR_COMFORT -#define D_STR_COMFORT "Comfort" +#define D_STR_COMFORT "舒适" #endif // D_STR_COMFORT #ifndef D_STR_SENSOR -#define D_STR_SENSOR "Sensor" +#define D_STR_SENSOR "传感器" #endif // D_STR_SENSOR #ifndef D_STR_WEEKLY -#define D_STR_WEEKLY "Weekly" +#define D_STR_WEEKLY "每周" #endif // D_STR_WEEKLY #ifndef D_STR_WEEKLYTIMER #define D_STR_WEEKLYTIMER D_STR_WEEKLY " " D_STR_TIMER // Needs `D_STR_WEEKLY`! @@ -199,130 +188,130 @@ #define D_STR_WIFI "WiFi" #endif // D_STR_WIFI #ifndef D_STR_LAST -#define D_STR_LAST "Last" +#define D_STR_LAST "最近" #endif // D_STR_LAST #ifndef D_STR_FAST -#define D_STR_FAST "Fast" +#define D_STR_FAST "快" #endif // D_STR_FAST #ifndef D_STR_SLOW -#define D_STR_SLOW "Slow" +#define D_STR_SLOW "慢" #endif // D_STR_SLOW #ifndef D_STR_AIRFLOW -#define D_STR_AIRFLOW "Air Flow" +#define D_STR_AIRFLOW "空气流动" #endif // D_STR_AIRFLOW #ifndef D_STR_STEP -#define D_STR_STEP "Step" +#define D_STR_STEP "步" #endif // D_STR_STEP #ifndef D_STR_NA -#define D_STR_NA "N/A" +#define D_STR_NA "不适用" #endif // D_STR_NA #ifndef D_STR_OUTSIDE -#define D_STR_OUTSIDE "Outside" +#define D_STR_OUTSIDE "室外" #endif // D_STR_OUTSIDE #ifndef D_STR_LOUD -#define D_STR_LOUD "Loud" +#define D_STR_LOUD "大声" #endif // D_STR_LOUD #ifndef D_STR_UPPER -#define D_STR_UPPER "Upper" +#define D_STR_UPPER "更高" #endif // D_STR_UPPER #ifndef D_STR_LOWER -#define D_STR_LOWER "Lower" +#define D_STR_LOWER "更低" #endif // D_STR_LOWER #ifndef D_STR_BREEZE -#define D_STR_BREEZE "Breeze" +#define D_STR_BREEZE "微风" #endif // D_STR_BREEZE #ifndef D_STR_CIRCULATE -#define D_STR_CIRCULATE "Circulate" +#define D_STR_CIRCULATE "流通" #endif // D_STR_CIRCULATE #ifndef D_STR_CEILING -#define D_STR_CEILING "Ceiling" +#define D_STR_CEILING "天花板" #endif // D_STR_CEILING #ifndef D_STR_WALL -#define D_STR_WALL "Wall" +#define D_STR_WALL "墙" #endif // D_STR_WALL #ifndef D_STR_ROOM -#define D_STR_ROOM "Room" +#define D_STR_ROOM "房间" #endif // D_STR_ROOM #ifndef D_STR_6THSENSE -#define D_STR_6THSENSE "6th Sense" +#define D_STR_6THSENSE "第六感" #endif // D_STR_6THSENSE #ifndef D_STR_ZONEFOLLOW -#define D_STR_ZONEFOLLOW "Zone Follow" +#define D_STR_ZONEFOLLOW "区域跟随" #endif // D_STR_ZONEFOLLOW #ifndef D_STR_FIXED -#define D_STR_FIXED "Fixed" +#define D_STR_FIXED "固定" #endif // D_STR_FIXED #ifndef D_STR_AUTO -#define D_STR_AUTO "Auto" +#define D_STR_AUTO "自动" #endif // D_STR_AUTO #ifndef D_STR_AUTOMATIC -#define D_STR_AUTOMATIC "Automatic" +#define D_STR_AUTOMATIC "自动的" #endif // D_STR_AUTOMATIC #ifndef D_STR_MANUAL -#define D_STR_MANUAL "Manual" +#define D_STR_MANUAL "手动" #endif // D_STR_MANUAL #ifndef D_STR_COOL -#define D_STR_COOL "Cool" +#define D_STR_COOL "制冷" #endif // D_STR_COOL #ifndef D_STR_HEAT -#define D_STR_HEAT "Heat" +#define D_STR_HEAT "加热" #endif // D_STR_HEAT #ifndef D_STR_FAN -#define D_STR_FAN "Fan" +#define D_STR_FAN "风扇" #endif // D_STR_FAN #ifndef D_STR_FANONLY -#define D_STR_FANONLY "fan_only" +#define D_STR_FANONLY "仅风扇" #endif // D_STR_FANONLY #ifndef D_STR_DRY -#define D_STR_DRY "Dry" +#define D_STR_DRY "干燥" #endif // D_STR_DRY #ifndef D_STR_MAX -#define D_STR_MAX "Max" +#define D_STR_MAX "最大" #endif // D_STR_MAX #ifndef D_STR_MAXIMUM -#define D_STR_MAXIMUM "Maximum" +#define D_STR_MAXIMUM "最小" #endif // D_STR_MAXIMUM #ifndef D_STR_MIN -#define D_STR_MIN "Min" +#define D_STR_MIN "最低" #endif // D_STR_MIN #ifndef D_STR_MINIMUM -#define D_STR_MINIMUM "Minimum" +#define D_STR_MINIMUM "最低" #endif // D_STR_MINIMUM #ifndef D_STR_MED -#define D_STR_MED "Med" +#define D_STR_MED "中" #endif // D_STR_MED #ifndef D_STR_MEDIUM -#define D_STR_MEDIUM "Medium" +#define D_STR_MEDIUM "中" #endif // D_STR_MEDIUM #ifndef D_STR_HIGHEST -#define D_STR_HIGHEST "Highest" +#define D_STR_HIGHEST "最高" #endif // D_STR_HIGHEST #ifndef D_STR_HIGH -#define D_STR_HIGH "High" +#define D_STR_HIGH "高" #endif // D_STR_HIGH #ifndef D_STR_HI -#define D_STR_HI "Hi" +#define D_STR_HI "嗨" #endif // D_STR_HI #ifndef D_STR_MID -#define D_STR_MID "Mid" +#define D_STR_MID "中" #endif // D_STR_MID #ifndef D_STR_MIDDLE -#define D_STR_MIDDLE "Middle" +#define D_STR_MIDDLE "居中" #endif // D_STR_MIDDLE #ifndef D_STR_LOW -#define D_STR_LOW "Low" +#define D_STR_LOW "低" #endif // D_STR_LOW #ifndef D_STR_LO -#define D_STR_LO "Lo" +#define D_STR_LO "低" #endif // D_STR_LO #ifndef D_STR_LOWEST -#define D_STR_LOWEST "Lowest" +#define D_STR_LOWEST "最低" #endif // D_STR_LOWEST #ifndef D_STR_RIGHT -#define D_STR_RIGHT "Right" +#define D_STR_RIGHT "右" #endif // D_STR_RIGHT #ifndef D_STR_MAXRIGHT #define D_STR_MAXRIGHT D_STR_MAX " " D_STR_RIGHT // Set `D_STR_MAX` first! @@ -331,7 +320,7 @@ #define D_STR_RIGHTMAX_NOSPACE D_STR_RIGHT D_STR_MAX // Set `D_STR_MAX` first! #endif // D_STR_RIGHTMAX_NOSPACE #ifndef D_STR_LEFT -#define D_STR_LEFT "Left" +#define D_STR_LEFT "左" #endif // D_STR_LEFT #ifndef D_STR_MAXLEFT #define D_STR_MAXLEFT D_STR_MAX " " D_STR_LEFT // Set `D_STR_MAX` first! @@ -340,16 +329,16 @@ #define D_STR_LEFTMAX_NOSPACE D_STR_LEFT D_STR_MAX // Set `D_STR_MAX` first! #endif // D_STR_LEFTMAX_NOSPACE #ifndef D_STR_WIDE -#define D_STR_WIDE "Wide" +#define D_STR_WIDE "扫风" #endif // D_STR_WIDE #ifndef D_STR_CENTRE -#define D_STR_CENTRE "Centre" +#define D_STR_CENTRE "中间" #endif // D_STR_CENTRE #ifndef D_STR_TOP -#define D_STR_TOP "Top" +#define D_STR_TOP "上部" #endif // D_STR_TOP #ifndef D_STR_BOTTOM -#define D_STR_BOTTOM "Bottom" +#define D_STR_BOTTOM "底部" #endif // D_STR_BOTTOM // Compound words/phrases/descriptions from pre-defined words. @@ -397,78 +386,80 @@ #endif // D_STR_COLONSPACE #ifndef D_STR_DAY -#define D_STR_DAY "Day" +#define D_STR_DAY "天" #endif // D_STR_DAY #ifndef D_STR_DAYS #define D_STR_DAYS D_STR_DAY "s" #endif // D_STR_DAYS #ifndef D_STR_HOUR -#define D_STR_HOUR "Hour" +#define D_STR_HOUR "时" #endif // D_STR_HOUR #ifndef D_STR_HOURS #define D_STR_HOURS D_STR_HOUR "s" #endif // D_STR_HOURS #ifndef D_STR_MINUTE -#define D_STR_MINUTE "Minute" +#define D_STR_MINUTE "分" #endif // D_STR_MINUTE #ifndef D_STR_MINUTES #define D_STR_MINUTES D_STR_MINUTE "s" #endif // D_STR_MINUTES #ifndef D_STR_SECOND -#define D_STR_SECOND "Second" +#define D_STR_SECOND "秒" #endif // D_STR_SECOND #ifndef D_STR_SECONDS #define D_STR_SECONDS D_STR_SECOND "s" #endif // D_STR_SECONDS #ifndef D_STR_NOW -#define D_STR_NOW "Now" +#define D_STR_NOW "现在" #endif // D_STR_NOW +/* This is not three letter days. Disabled. #ifndef D_STR_THREELETTERDAYS -#define D_STR_THREELETTERDAYS "SunMonTueWedThuFriSat" +#define D_STR_THREELETTERDAYS "周一至周末" #endif // D_STR_THREELETTERDAYS +*/ #ifndef D_STR_YES -#define D_STR_YES "Yes" +#define D_STR_YES "是" #endif // D_STR_YES #ifndef D_STR_NO -#define D_STR_NO "No" +#define D_STR_NO "否" #endif // D_STR_NO #ifndef D_STR_TRUE -#define D_STR_TRUE "True" +#define D_STR_TRUE "正确" #endif // D_STR_TRUE #ifndef D_STR_FALSE -#define D_STR_FALSE "False" +#define D_STR_FALSE "错误" #endif // D_STR_FALSE #ifndef D_STR_REPEAT -#define D_STR_REPEAT "Repeat" +#define D_STR_REPEAT "重复" #endif // D_STR_REPEAT #ifndef D_STR_CODE -#define D_STR_CODE "Code" +#define D_STR_CODE "代码" #endif // D_STR_CODE #ifndef D_STR_BITS -#define D_STR_BITS "Bits" +#define D_STR_BITS "位" #endif // D_STR_BITS -// IRrecvDumpV2 +// IRrecvDumpV2+ #ifndef D_STR_TIMESTAMP -#define D_STR_TIMESTAMP "Timestamp" +#define D_STR_TIMESTAMP "时间戳记" #endif // D_STR_TIMESTAMP #ifndef D_STR_LIBRARY -#define D_STR_LIBRARY "Library" +#define D_STR_LIBRARY "库文件" #endif // D_STR_LIBRARY #ifndef D_STR_MESGDESC -#define D_STR_MESGDESC "Mesg Desc." +#define D_STR_MESGDESC "等等信息" #endif // D_STR_MESGDESC #ifndef D_STR_IRRECVDUMP_STARTUP #define D_STR_IRRECVDUMP_STARTUP \ - "IRrecvDumpV2 is now running and waiting for IR input on Pin %d" + "IRrecvDump 运行当中,等待红外信息输入位于引脚 %d" #endif // D_STR_IRRECVDUMP_STARTUP #ifndef D_WARN_BUFFERFULL #define D_WARN_BUFFERFULL \ - "WARNING: IR code is too big for buffer (>= %d). " \ - "This result shouldn't be trusted until this is resolved. " \ - "Edit & increase `kCaptureBufferSize`." + "警告: 红外编码数组过大(>= %d). " \ + "在解决此问题之前,不应信任此结果. " \ + "编辑并增加 `kCaptureBufferSize` 变量." #endif // D_WARN_BUFFERFULL -#endif // LOCALE_DEFAULTS_H_ +#endif // LOCALE_ZH_CN_H_ diff --git a/lib/IRremoteESP8266-2.7.5/test/IRac_test.cpp b/lib/IRremoteESP8266-2.7.8/test/IRac_test.cpp similarity index 91% rename from lib/IRremoteESP8266-2.7.5/test/IRac_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/IRac_test.cpp index 8ddf98b59..a0f975666 100644 --- a/lib/IRremoteESP8266-2.7.5/test/IRac_test.cpp +++ b/lib/IRremoteESP8266-2.7.8/test/IRac_test.cpp @@ -3,7 +3,11 @@ #include #include "ir_Amcor.h" #include "ir_Argo.h" +#include "ir_Carrier.h" +#include "ir_Coolix.h" +#include "ir_Corona.h" #include "ir_Daikin.h" +#include "ir_Delonghi.h" #include "ir_Electra.h" #include "ir_Fujitsu.h" #include "ir_Goodweather.h" @@ -79,6 +83,40 @@ TEST(TestIRac, Argo) { EXPECT_FALSE(ac.getNight()); // Sleep } +TEST(TestIRac, Carrier64) { + IRCarrierAc64 ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); + + char expected[] = + "Power: On, Mode: 1 (Heat), Temp: 21C, Fan: 3 (High), Swing(V): On, " + "Sleep: On, On Timer: Off, Off Timer: Off"; + + ac.begin(); + irac.carrier64(&ac, + true, // Power + stdAc::opmode_t::kHeat, // Mode + 21, // Celsius + stdAc::fanspeed_t::kHigh, // Fan speed + stdAc::swingv_t::kAuto, // Veritcal swing + 1); // Sleep + EXPECT_TRUE(ac.getPower()); // Power. + EXPECT_EQ(kCarrierAc64Heat, ac.getMode()); // Operating mode. + EXPECT_EQ(21, ac.getTemp()); // Temperature. + EXPECT_EQ(kCarrierAc64FanHigh, ac.getFan()); // Fan Speed + EXPECT_TRUE(ac.getSwingV()); // SwingV + EXPECT_TRUE(ac.getSleep()); // Sleep + + ASSERT_EQ(expected, ac.toString()); + ac._irsend.makeDecodeResult(); + EXPECT_TRUE(capture.decode(&ac._irsend.capture)); + ASSERT_EQ(CARRIER_AC64, ac._irsend.capture.decode_type); + ASSERT_EQ(kCarrierAc64Bits, ac._irsend.capture.bits); + ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture)); + stdAc::state_t r, p; + ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p)); +} + TEST(TestIRac, Coolix) { IRCoolixAC ac(0); IRac irac(0); @@ -140,6 +178,48 @@ TEST(TestIRac, Coolix) { ac._irsend.outputStr()); } +TEST(TestIRac, Corona) { + IRCoronaAc ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); + + char expectedAfterSent[] = + "Power: On, Power Button: On, Mode: 0 (Heat), Temp: 21C, " + "Fan: 3 (High), Swing(V) Toggle: On, Econo: On, " + "On Timer: Off, Off Timer: Off"; + + char expectedCapture[] = + "Power: On, Power Button: Off, Mode: 0 (Heat), Temp: 21C, " + "Fan: 3 (High), Swing(V) Toggle: On, Econo: On, " + "On Timer: Off, Off Timer: Off"; + + ac.begin(); + // this sends as well + irac.corona(&ac, + true, // Power + stdAc::opmode_t::kHeat, // Mode + 21, // Celsius + stdAc::fanspeed_t::kHigh, // Fan speed + stdAc::swingv_t::kAuto, // Veritcal swing + true); // Econo (PowerSave) + EXPECT_TRUE(ac.getPower()); // Power. + EXPECT_TRUE(ac.getPowerButton()); // Power.button + EXPECT_EQ(kCoronaAcModeHeat, ac.getMode()); // Operating mode. + EXPECT_EQ(21, ac.getTemp()); // Temperature. + EXPECT_EQ(kCoronaAcFanHigh, ac.getFan()); // Fan Speed + EXPECT_TRUE(ac.getSwingVToggle()); // SwingV + EXPECT_TRUE(ac.getEcono()); // Econo (PowerSave) + + ASSERT_EQ(expectedAfterSent, ac.toString()); + ac._irsend.makeDecodeResult(); + EXPECT_TRUE(capture.decode(&ac._irsend.capture)); + ASSERT_EQ(CORONA_AC, ac._irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBits, ac._irsend.capture.bits); + ASSERT_EQ(expectedCapture, IRAcUtils::resultAcToString(&ac._irsend.capture)); + stdAc::state_t r, p; + ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p)); +} + TEST(TestIRac, Daikin) { IRDaikinESP ac(0); IRac irac(0); @@ -377,6 +457,31 @@ TEST(TestIRac, Daikin64) { ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture)); } +TEST(TestIRac, DelonghiAc) { + IRDelonghiAc ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); + char expected[] = + "Power: On, Mode: 0 (Cool), Fan: 2 (Medium), Temp: 77F, " + "Turbo: On, Sleep: On, On Timer: Off, Off Timer: Off"; + + ac.begin(); + irac.delonghiac(&ac, + true, // Power + stdAc::opmode_t::kCool, // Mode + false, // Celsius (i.e. Fahrenheit) + 77, // Degrees (F) + stdAc::fanspeed_t::kMedium, // Fan Speed + true, // Turbo + 360); // Sleep + ASSERT_EQ(expected, ac.toString()); + ac._irsend.makeDecodeResult(); + EXPECT_TRUE(capture.decode(&ac._irsend.capture)); + ASSERT_EQ(decode_type_t::DELONGHI_AC, ac._irsend.capture.decode_type); + ASSERT_EQ(kDelonghiAcBits, ac._irsend.capture.bits); + ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture)); +} + TEST(TestIRac, Electra) { IRElectraAc ac(kGpioUnused); IRac irac(kGpioUnused); @@ -518,17 +623,18 @@ TEST(TestIRac, Gree) { IRac irac(0); IRrecv capture(0); char expected[] = - "Model: 1 (YAW1F), Power: On, Mode: 1 (Cool), Temp: 22C, " + "Model: 1 (YAW1F), Power: On, Mode: 1 (Cool), Temp: 71F, " "Fan: 2 (Medium), Turbo: Off, IFeel: Off, WiFi: Off, XFan: On, " "Light: On, Sleep: On, Swing(V) Mode: Manual, " - "Swing(V): 3 (UNKNOWN), Timer: Off"; + "Swing(V): 3 (UNKNOWN), Timer: Off, Display Temp: 0 (Off)"; ac.begin(); irac.gree(&ac, gree_ac_remote_model_t::YAW1F, // Model true, // Power stdAc::opmode_t::kCool, // Mode - 22, // Celsius + false, // Celsius + 71, // Degrees (F) stdAc::fanspeed_t::kMedium, // Fan speed stdAc::swingv_t::kHigh, // Veritcal swing false, // Turbo @@ -663,16 +769,67 @@ TEST(TestIRac, Hitachi1) { ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p)); } +TEST(TestIRac, Hitachi344) { + IRHitachiAc344 ac(kGpioUnused); + IRac irac(kGpioUnused); + IRrecv capture(kGpioUnused); + char expected_swingon[] = + "Power: On, Mode: 6 (Heat), Temp: 25C, Fan: 6 (Max), " + "Button: 129 (Swing(V)), Swing(V): Off, Swing(H): 2 (Right)"; + + ac.begin(); + irac.hitachi344(&ac, + true, // Power + stdAc::opmode_t::kHeat, // Mode + 25, // Celsius + stdAc::fanspeed_t::kMax, // Fan speed + stdAc::swingv_t::kAuto, // Swing(V) + stdAc::swingh_t::kRight); // Swing(H) + + ASSERT_EQ(expected_swingon, ac.toString()); + ac._irsend.makeDecodeResult(); + EXPECT_TRUE(capture.decode(&ac._irsend.capture)); + ASSERT_EQ(HITACHI_AC344, ac._irsend.capture.decode_type); + ASSERT_EQ(kHitachiAc344Bits, ac._irsend.capture.bits); + ASSERT_EQ(expected_swingon, IRAcUtils::resultAcToString(&ac._irsend.capture)); + stdAc::state_t r, p; + ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p)); + EXPECT_EQ(decode_type_t::HITACHI_AC344, r.protocol); + EXPECT_TRUE(r.power); + EXPECT_EQ(stdAc::opmode_t::kHeat, r.mode); + EXPECT_EQ(25, r.degrees); + + char expected_swingoff[] = + "Power: On, Mode: 6 (Heat), Temp: 25C, Fan: 6 (Max), " + "Button: 19 (Power/Mode), Swing(V): Off, Swing(H): 2 (Right)"; + + ac._irsend.reset(); + irac.hitachi344(&ac, + true, // Power + stdAc::opmode_t::kHeat, // Mode + 25, // Celsius + stdAc::fanspeed_t::kMax, // Fan speed + stdAc::swingv_t::kOff, // Swing(V) + stdAc::swingh_t::kRight); // Swing(H) + ASSERT_EQ(expected_swingoff, ac.toString()); + ac._irsend.makeDecodeResult(); + EXPECT_TRUE(capture.decode(&ac._irsend.capture)); + ASSERT_EQ(HITACHI_AC344, ac._irsend.capture.decode_type); + ASSERT_EQ(kHitachiAc344Bits, ac._irsend.capture.bits); + ASSERT_EQ(expected_swingoff, + IRAcUtils::resultAcToString(&ac._irsend.capture)); +} + TEST(TestIRac, Hitachi424) { IRHitachiAc424 ac(0); IRac irac(0); IRrecv capture(0); char expected[] = "Power: On, Mode: 6 (Heat), Temp: 25C, Fan: 6 (Max), " - "Swing(V) Toggle: Off, Button: 19 (Power/Mode)"; + "Button: 19 (Power/Mode), Swing(V) Toggle: Off"; char expected_swingv[] = "Power: On, Mode: 3 (Cool), Temp: 26C, Fan: 1 (Min), " - "Swing(V) Toggle: On, Button: 129 (Swing(V))"; + "Button: 129 (Swing(V)), Swing(V) Toggle: On"; ac.begin(); irac.hitachi424(&ac, @@ -1071,8 +1228,8 @@ TEST(TestIRac, Sharp) { IRac irac(0); IRrecv capture(0); char expected[] = - "Power: On, Previous Power: On, Mode: 2 (Cool), Temp: 28C, " - "Fan: 3 (Medium)"; + "Power: On, Mode: 2 (Cool), Temp: 28C, Fan: 3 (Medium), " + "Turbo: Off, Swing(V) Toggle: On, Ion: On, Econo: -, Clean: Off"; ac.begin(); irac.sharp(&ac, @@ -1080,7 +1237,11 @@ TEST(TestIRac, Sharp) { true, // Previous Power stdAc::opmode_t::kCool, // Mode 28, // Celsius - stdAc::fanspeed_t::kMedium); // Fan speed + stdAc::fanspeed_t::kMedium, // Fan speed + stdAc::swingv_t::kAuto, // Veritcal swing + false, // Turbo + true, // Filter (Ion) + false); // Clean ASSERT_EQ(expected, ac.toString()); ac._irsend.makeDecodeResult(); EXPECT_TRUE(capture.decode(&ac._irsend.capture)); diff --git a/lib/IRremoteESP8266-2.7.5/test/IRrecv_test.cpp b/lib/IRremoteESP8266-2.7.8/test/IRrecv_test.cpp similarity index 85% rename from lib/IRremoteESP8266-2.7.5/test/IRrecv_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/IRrecv_test.cpp index e66866be1..08649978c 100644 --- a/lib/IRremoteESP8266-2.7.5/test/IRrecv_test.cpp +++ b/lib/IRremoteESP8266-2.7.8/test/IRrecv_test.cpp @@ -1595,11 +1595,37 @@ TEST(TestManchesterCode, matchManchester) { IRrecv irrecv(0); const uint16_t rawData[163] = { + // 0 2860, 3862, + // 11 00 11 00 1 0 11 0 1 0 1 0 1 + // 0 1 0 1 0 0 1 1 1 + // 1 4 + // 1 0 1 0 1 1 0 0 0 + // 2 B 1924, 1952, 1926, 1952, 956, 984, 1924, 1028, 952, 958, 980, 956, 982, + // 00 1 0 11 00 11 0 1 0 1 0 1 0 + // 1 0 0 1 0 1 1 1 1 + // F 2 F + // 0 1 1 0 1 0 0 0 0 + // 0 D 0 1882, 1016, 950, 1958, 1920, 1948, 1004, 954, 956, 984, 956, 952, 984, + // 1 0 1 0 1 00 1 0 11 0 1 0 1 + // 1 1 1 0 0 1 1 + // E + // 0 0 0 1 1 0 0 + // 1 974, 966, 974, 964, 974, 1888, 1010, 960, 1948, 1002, 946, 962, 978, + // 0 1 0 1 0 1 00 1 0 11 00 1 0 + // 1 1 1 1 0 0 1 0 + // 7 E + // 0 0 0 0 1 1 0 1 + // 8 1 962, 976, 960, 948, 992, 978, 1886, 982, 984, 1924, 1954, 952, 986, + // 1 + // 0 + // 4 + // 1 + // B 3892, 3862, 1924, 1954, 1924, 1954, 984, 952, 1956, 996, 954, 990, 948, 958, 980, 1882, 1016, 952, 1958, 1920, 1956, 994, 944, 962, 986, 956, 972, 962, @@ -1616,11 +1642,11 @@ TEST(TestManchesterCode, matchManchester) { uint16_t offset = 1; uint64_t result = 0; - uint16_t nbits = 32; + uint16_t nbits = 34; EXPECT_EQ(56, irrecv.matchManchester(irsend.capture.rawbuf + offset, &result, irsend.capture.rawlen - offset, nbits, - 2860, 3800, 1000, 0, 3800)); - EXPECT_EQ(0x4F2FE7E4, result); + 2860, 2860, 1000, 2860, 2860)); + EXPECT_EQ(0x14F2FE7E4, result); irsend.reset(); irsend.sendRaw(rawData, 55, 38); // Send just the bare minimum. @@ -1628,8 +1654,8 @@ TEST(TestManchesterCode, matchManchester) { EXPECT_EQ(55, irrecv.matchManchester(irsend.capture.rawbuf + offset, &result, irsend.capture.rawlen - offset, nbits, - 2860, 3800, 1000, 0, 3800)); - EXPECT_EQ(0x4F2FE7E4, result); + 2860, 2860, 1000, 2860, 2860)); + EXPECT_EQ(0x14F2FE7E4, result); irsend.reset(); irsend.sendRaw(rawData, 52, 38); // Now, just too short. @@ -1637,7 +1663,7 @@ TEST(TestManchesterCode, matchManchester) { EXPECT_EQ(0, irrecv.matchManchester(irsend.capture.rawbuf + offset, &result, irsend.capture.rawlen - offset, nbits, - 2860, 3800, 1000, 0, 0)); + 2860, 2860, 1000, 2860, 2860)); } TEST(TestManchesterCode, ManchesterLoopBackGEThomasTest) { @@ -1650,7 +1676,7 @@ TEST(TestManchesterCode, ManchesterLoopBackGEThomasTest) { irsend.reset(); irsend.sendManchester(5000, 7000, 1000, 0, 10000, 0x12345678, nbits); irsend.makeDecodeResult(); - EXPECT_EQ(52, irrecv.matchManchester(irsend.capture.rawbuf + offset, &result, + EXPECT_EQ(50, irrecv.matchManchester(irsend.capture.rawbuf + offset, &result, irsend.capture.rawlen - offset, nbits, 5000, 7000, 1000, 0, 10000, true, kUseDefTol, kMarkExcess, true, true)); @@ -1659,7 +1685,7 @@ TEST(TestManchesterCode, ManchesterLoopBackGEThomasTest) { irsend.reset(); irsend.sendManchester(5000, 7000, 1000, 0, 10000, 0x87654321, nbits); irsend.makeDecodeResult(); - EXPECT_EQ(52, irrecv.matchManchester(irsend.capture.rawbuf + offset, &result, + EXPECT_EQ(50, irrecv.matchManchester(irsend.capture.rawbuf + offset, &result, irsend.capture.rawlen - offset, nbits, 5000, 7000, 1000, 0, 10000, true, kUseDefTol, kMarkExcess, true, true)); @@ -1677,7 +1703,7 @@ TEST(TestManchesterCode, ManchesterLoopBackIEEE802_3Test) { irsend.sendManchester(5000, 7000, 1000, 0, 10000, 0x12345678, nbits, 38000, true, kNoRepeat, kDutyDefault, false); irsend.makeDecodeResult(); - EXPECT_EQ(52, irrecv.matchManchester(irsend.capture.rawbuf + offset, &result, + EXPECT_EQ(50, irrecv.matchManchester(irsend.capture.rawbuf + offset, &result, irsend.capture.rawlen - offset, nbits, 5000, 7000, 1000, 0, 10000, true, kUseDefTol, kMarkExcess, true, false)); @@ -1687,9 +1713,198 @@ TEST(TestManchesterCode, ManchesterLoopBackIEEE802_3Test) { irsend.sendManchester(5000, 7000, 1000, 0, 10000, 0x87654321, nbits, 38000, true, kNoRepeat, kDutyDefault, false); irsend.makeDecodeResult(); - EXPECT_EQ(54, irrecv.matchManchester(irsend.capture.rawbuf + offset, &result, + EXPECT_EQ(50, irrecv.matchManchester(irsend.capture.rawbuf + offset, &result, irsend.capture.rawlen - offset, nbits, 5000, 7000, 1000, 0, 10000, true, kUseDefTol, kMarkExcess, true, false)); EXPECT_EQ(0x87654321, result); } + +TEST(TestMatchManchesterData, Normal) { + IRsendTest irsend(0); + IRrecv irrecv(0); + uint16_t offset = 1; + uint64_t result = 0; + irsend.begin(); + + irsend.reset(); + irsend.enableIROut(38); + irsend.sendManchesterData(1000, 0b1111, 4); + irsend.makeDecodeResult(); + EXPECT_EQ(8, irrecv.matchManchesterData(irsend.capture.rawbuf + offset, + &result, + irsend.capture.rawlen - offset, + 4, 1000)); + EXPECT_EQ(0b1111, result); + EXPECT_EQ("f38000d50m1000s1000m1000s1000m1000s1000m1000s1000", + irsend.outputStr()); + + irsend.reset(); + irsend.enableIROut(38); + irsend.sendManchesterData(1000, 0b1011, 4); + irsend.makeDecodeResult(); + EXPECT_EQ(6, irrecv.matchManchesterData(irsend.capture.rawbuf + offset, + &result, + irsend.capture.rawlen - offset, + 4, 1000)); + EXPECT_EQ(0b1011, result); + EXPECT_EQ("f38000d50m1000s2000m2000s1000m1000s1000", + irsend.outputStr()); + + irsend.reset(); + irsend.enableIROut(38); + irsend.sendManchesterData(1000, 0b1010, 4); + irsend.makeDecodeResult(); + EXPECT_EQ(5, irrecv.matchManchesterData(irsend.capture.rawbuf + offset, + &result, + irsend.capture.rawlen - offset, + 4, 1000)); + EXPECT_EQ(0b1010, result); + EXPECT_EQ("f38000d50m1000s2000m2000s2000m1000", + irsend.outputStr()); + + irsend.reset(); + irsend.enableIROut(38); + irsend.sendManchesterData(1000, 0b1000, 4); + irsend.makeDecodeResult(); + EXPECT_EQ(7, irrecv.matchManchesterData(irsend.capture.rawbuf + offset, + &result, + irsend.capture.rawlen - offset, + 4, 1000)); + EXPECT_EQ(0b1000, result); + EXPECT_EQ("f38000d50m1000s2000m1000s1000m1000s1000m1000", + irsend.outputStr()); + + irsend.reset(); + irsend.enableIROut(38); + irsend.sendManchesterData(1000, 0b1001, 4); + irsend.makeDecodeResult(); + EXPECT_EQ(6, irrecv.matchManchesterData(irsend.capture.rawbuf + offset, + &result, + irsend.capture.rawlen - offset, + 4, 1000)); + EXPECT_EQ(0b1001, result); + EXPECT_EQ("f38000d50m1000s2000m1000s1000m2000s1000", + irsend.outputStr()); +} + +TEST(TestMatchManchesterData, SimulateAtEndOfARealMessage) { + IRsendTest irsend(0); + IRrecv irrecv(0); + uint16_t offset = 1; + uint64_t result = 0; + irsend.begin(); + + irsend.reset(); + irsend.enableIROut(38); + irsend.sendManchesterData(1000, 0b1111, 4); + irsend.makeDecodeResult(); + // To simulate an normal (no space at the end) reduce the remaining by 1. + EXPECT_EQ(7, irrecv.matchManchesterData(irsend.capture.rawbuf + offset, + &result, + irsend.capture.rawlen - offset - 1, + 4, 1000)); + EXPECT_EQ(0b1111, result); + EXPECT_EQ("f38000d50m1000s1000m1000s1000m1000s1000m1000s1000", + irsend.outputStr()); + + uint16_t rawData[7] = {1000, 1000, 1000, 1000, 1000, 1000, 1000}; + irsend.reset(); + irsend.enableIROut(38); + irsend.sendRaw(rawData, 7, 38); + irsend.makeDecodeResult(); + EXPECT_EQ(7, irrecv.matchManchesterData(irsend.capture.rawbuf + offset, + &result, + irsend.capture.rawlen - offset, + 4, 1000)); + EXPECT_EQ(0b1111, result); + EXPECT_EQ("f38000d50m1000s1000m1000s1000m1000s1000m1000", + irsend.outputStr()); + + irsend.reset(); + irsend.enableIROut(38); + irsend.sendManchesterData(1000, 0b1011, 4); + irsend.makeDecodeResult(); + // To simulate an normal (no space at the end) reduce the remaining by 1. + EXPECT_EQ(5, irrecv.matchManchesterData(irsend.capture.rawbuf + offset, + &result, + irsend.capture.rawlen - offset - 1, + 4, 1000)); + EXPECT_EQ(0b1011, result); + EXPECT_EQ("f38000d50m1000s2000m2000s1000m1000s1000", + irsend.outputStr()); + + irsend.reset(); + irsend.enableIROut(38); + irsend.sendManchesterData(1000, 0b1010, 4); + irsend.makeDecodeResult(); + // To simulate an normal (no space at the end) reduce the remaining by 1. + EXPECT_EQ(4, irrecv.matchManchesterData(irsend.capture.rawbuf + offset, + &result, + irsend.capture.rawlen - offset - 1, + 4, 1000)); + EXPECT_EQ(0b1010, result); + EXPECT_EQ("f38000d50m1000s2000m2000s2000m1000", + irsend.outputStr()); + + irsend.reset(); + irsend.enableIROut(38); + irsend.sendManchesterData(1000, 0b1000, 4); + irsend.makeDecodeResult(); + // To simulate an normal (no space at the end) reduce the remaining by 1. + EXPECT_EQ(6, irrecv.matchManchesterData(irsend.capture.rawbuf + offset, + &result, + irsend.capture.rawlen - offset - 1, + 4, 1000)); + EXPECT_EQ(0b1000, result); + EXPECT_EQ("f38000d50m1000s2000m1000s1000m1000s1000m1000", + irsend.outputStr()); + + irsend.reset(); + irsend.enableIROut(38); + irsend.sendManchesterData(1000, 0b1001, 4); + irsend.makeDecodeResult(); + // To simulate an normal (no space at the end) reduce the remaining by 1. + EXPECT_EQ(5, irrecv.matchManchesterData(irsend.capture.rawbuf + offset, + &result, + irsend.capture.rawlen - offset - 1, + 4, 1000)); + EXPECT_EQ(0b1001, result); + EXPECT_EQ("f38000d50m1000s2000m1000s1000m2000s1000", + irsend.outputStr()); +} + +TEST(TestMatchManchesterData, SimulateLongFooter) { + IRsendTest irsend(0); + IRrecv irrecv(0); + uint16_t offset = 1; + uint64_t result = 0; + irsend.begin(); + + irsend.reset(); + irsend.enableIROut(38); + irsend.sendManchesterData(1000, 0b1110, 4); + irsend.mark(4000); + irsend.makeDecodeResult(); + EXPECT_EQ(6, irrecv.matchManchesterData(irsend.capture.rawbuf + offset, + &result, + irsend.capture.rawlen - offset, + 4, 1000)); + EXPECT_EQ(0b1110, result); + EXPECT_EQ("f38000d50m1000s1000m1000s1000m1000s2000m5000", + irsend.outputStr()); + + irsend.reset(); + irsend.enableIROut(38); + irsend.sendManchesterData(1000, 0b1001, 4); + irsend.space(4000); + irsend.makeDecodeResult(); + // To simulate an normal (no space at the end) reduce the remaining by 1. + EXPECT_EQ(5, irrecv.matchManchesterData(irsend.capture.rawbuf + offset, + &result, + irsend.capture.rawlen - offset - 1, + 4, 1000)); + EXPECT_EQ(0b1001, result); + EXPECT_EQ("f38000d50m1000s2000m1000s1000m2000s5000", + irsend.outputStr()); +} diff --git a/lib/IRremoteESP8266-2.7.5/test/IRrecv_test.h b/lib/IRremoteESP8266-2.7.8/test/IRrecv_test.h similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/IRrecv_test.h rename to lib/IRremoteESP8266-2.7.8/test/IRrecv_test.h diff --git a/lib/IRremoteESP8266-2.7.5/test/IRsend_test.cpp b/lib/IRremoteESP8266-2.7.8/test/IRsend_test.cpp similarity index 96% rename from lib/IRremoteESP8266-2.7.5/test/IRsend_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/IRsend_test.cpp index 2f39e323d..51fae7499 100644 --- a/lib/IRremoteESP8266-2.7.5/test/IRsend_test.cpp +++ b/lib/IRremoteESP8266-2.7.8/test/IRsend_test.cpp @@ -794,9 +794,9 @@ TEST(TestSendManchester, SendZeroBits) { IRsendTest irsend(0); irsend.begin(); irsend.sendManchester(0, 0, 1, 0, 0, 0b1, 0); - EXPECT_EQ("f36000d25m0f38000d50s1m2s1", irsend.outputStr()); + EXPECT_EQ("", irsend.outputStr()); irsend.sendManchester(1, 2, 100, 3, 4, 0b1, 0); - EXPECT_EQ("f38000d50m1s102m200s100m3s4", irsend.outputStr()); + EXPECT_EQ("f38000d50m1s2m3s4", irsend.outputStr()); } // Test sending zero and one. @@ -804,10 +804,10 @@ TEST(TestSendManchester, SendSingleBit) { IRsendTest irsend(0); irsend.begin(); irsend.sendManchester(1000, 2000, 100, 3000, 4000, 0b0, 1); - EXPECT_EQ("f38000d50m1000s2100m200s200m3100s4000", irsend.outputStr()); + EXPECT_EQ("f38000d50m1000s2100m3100s4000", irsend.outputStr()); irsend.sendManchester(1000, 2000, 100, 3000, 4000, 0b0, 1, 38, true, kNoRepeat, kDutyDefault, false); - EXPECT_EQ("f38000d50m1000s2000m100s200m200s100m3000s4000", + EXPECT_EQ("f38000d50m1000s2000m100s100m3000s4000", irsend.outputStr()); } @@ -816,14 +816,14 @@ TEST(TestSendManchester, TestingBitSendOrder) { IRsendTest irsend(0); irsend.begin(); irsend.sendManchester(1000, 2000, 100, 3000, 0, 0b10, 2); - EXPECT_EQ("f38000d50m1000s2100m200s100m100s200m3100", irsend.outputStr()); + EXPECT_EQ("f38000d50m1000s2000m100s200m3100", irsend.outputStr()); irsend.sendManchester(1000, 2000, 100, 3000, 0, 0b10, 2, 38, false); - EXPECT_EQ("f38000d50m1000s2100m200s200m200s100m3000", irsend.outputStr()); + EXPECT_EQ("f38000d50m1000s2100m200s100m3000", irsend.outputStr()); irsend.sendManchester(1000, 2000, 100, 3000, 0, 0b0001, 4, 38, true); - EXPECT_EQ("f38000d50m1000s2100m200s200m100s100m100s100m200s100m3000", + EXPECT_EQ("f38000d50m1000s2100m100s100m100s100m200s100m3000", irsend.outputStr()); irsend.sendManchester(1000, 2000, 100, 3000, 0, 0b0001, 4, 38, false); - EXPECT_EQ("f38000d50m1000s2100m200s100m100s200m100s100m100s100m3100", + EXPECT_EQ("f38000d50m1000s2000m100s200m100s100m100s100m3100", irsend.outputStr()); } @@ -835,16 +835,16 @@ TEST(TestSendManchester, SendTypicalData) { irsend.sendManchester(0, 0, 100, 0, 0, 0b10100111001, 11, 38, true); EXPECT_EQ( "f38000d50" - "m0s100m200s100" "m100s200m200s200m100s100m200s100m100s100m100s200m100s100m200s100", irsend.outputStr()); irsend.sendManchester(100, 200, 1, 300, 0, 0x1234567890ABCDEF, 64, 38, true); EXPECT_EQ( "f38000d50" "m100s201" - "m2s2m1s1m1s1m2s2m1s1m2s2m1s1m1s1m2s1m1s2m2s2m1s1m1s1m2s2m2s2m2s1m1s2m1s1" - "m2s1m1s1m1s1m1s2m1s1m1s1m2s2m1s1m2s2m1s1m1s1m1s1m2s2m2s2m2s2m2s1m1s1m1s1" - "m1s2m1s1m2s1m1s2m2s1m1s1m1s1m1s2m2s1m1s1m1s1m1s1m300", + "m1s1m1s1m2s2m1s1m2s2m1s1m1s1m2s1m1s2m2s2m1s1m1s1m2s2m2s2m2s1m1s2m1s1m2s1" + "m1s1m1s1m1s2m1s1m1s1m2s2m1s1m2s2m1s1m1s1m1s1m2s2m2s2m2s2m2s1m1s1m1s1m1s2" + "m1s1m2s1m1s2m2s1m1s1m1s1m1s2m2s1m1s1m1s1m1s1" + "m300", irsend.outputStr()); } @@ -856,7 +856,7 @@ TEST(TestSendManchester, SendOverLargeData) { EXPECT_EQ( "f38000d50" "m100s201" - "m2s2m1s1m1s1m1s1m1s1m1s1m2s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1" + "m1s1m1s1m1s1m1s1m1s1m2s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1" "m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1" "m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1" "m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1" diff --git a/lib/IRremoteESP8266-2.7.5/test/IRsend_test.h b/lib/IRremoteESP8266-2.7.8/test/IRsend_test.h similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/IRsend_test.h rename to lib/IRremoteESP8266-2.7.8/test/IRsend_test.h diff --git a/lib/IRremoteESP8266-2.7.5/test/IRutils_test.cpp b/lib/IRremoteESP8266-2.7.8/test/IRutils_test.cpp similarity index 95% rename from lib/IRremoteESP8266-2.7.5/test/IRutils_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/IRutils_test.cpp index b079893cd..ecb23dbbf 100644 --- a/lib/IRremoteESP8266-2.7.5/test/IRutils_test.cpp +++ b/lib/IRremoteESP8266-2.7.8/test/IRutils_test.cpp @@ -518,6 +518,7 @@ TEST(TestUtils, MinsToString) { } TEST(TestUtils, sumNibbles) { + // PTR/Array variant. uint8_t testdata[] = {0x01, 0x23, 0x45}; EXPECT_EQ(0, irutils::sumNibbles(testdata, 0)); EXPECT_EQ(1, irutils::sumNibbles(testdata, 0, 1)); @@ -525,6 +526,30 @@ TEST(TestUtils, sumNibbles) { EXPECT_EQ(2, irutils::sumNibbles(testdata, 1, 1)); EXPECT_EQ(15, irutils::sumNibbles(testdata, 3)); EXPECT_EQ(115, irutils::sumNibbles(testdata, 3, 100)); + + // Integer variant. + EXPECT_EQ(0x0, irutils::sumNibbles(0x0)); + EXPECT_EQ(0x1, irutils::sumNibbles(0x1)); + EXPECT_EQ(0xF, irutils::sumNibbles(0xF)); + EXPECT_EQ(0x4, irutils::sumNibbles(0x1111)); + EXPECT_EQ(0x8, irutils::sumNibbles(0x2222)); + EXPECT_EQ(0x0, irutils::sumNibbles(0x4444)); + EXPECT_EQ(0xA, irutils::sumNibbles(0x1234)); + EXPECT_EQ(0xA, irutils::sumNibbles(0x4321)); + EXPECT_EQ(0xE, irutils::sumNibbles(0xABCD)); + EXPECT_EQ(0x1, irutils::sumNibbles(0x4AE5)); + EXPECT_EQ(0xC, irutils::sumNibbles(0xFFFF)); + EXPECT_EQ(0x1, irutils::sumNibbles(0xC005)); + EXPECT_EQ(0x4, irutils::sumNibbles(0xC035)); + EXPECT_EQ(0x2, irutils::sumNibbles(0x88C0051)); + EXPECT_EQ(0x1, irutils::sumNibbles(0x88C0051, 1)); + EXPECT_EQ(0x2, irutils::sumNibbles(0x88C0051, 1, 1)); + EXPECT_EQ(0x6, irutils::sumNibbles(0x88C0051, 2)); + EXPECT_EQ(0x6, irutils::sumNibbles(0x88C0051, 4)); + EXPECT_EQ(0x2, irutils::sumNibbles(0x88C0051, 5)); + EXPECT_EQ(0x22, irutils::sumNibbles(0x88C0051, 16, 0, false)); + EXPECT_EQ(0x12, irutils::sumNibbles(0x88C0051, 5, 0, false)); + EXPECT_EQ(0x22, irutils::sumNibbles(0x88C0051, 255, 0, false)); } TEST(TestUtils, BCD) { diff --git a/lib/IRremoteESP8266-2.7.8/test/Makefile b/lib/IRremoteESP8266-2.7.8/test/Makefile new file mode 100644 index 000000000..ab64e28ed --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/test/Makefile @@ -0,0 +1,159 @@ +# SYNOPSIS: +# +# make [all] - makes everything. +# make TARGET - makes the given target. +# make run - makes everything and runs all the tests. +# make clean - removes all files generated by make. +# make install-googletest - install the googletest code suite + +# Please tweak the following variable definitions as needed by your +# project, except GTEST_HEADERS, which you can use in your own targets +# but shouldn't modify. + +# 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 + +# Where to find user code. +USER_DIR = ../src +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 + +# Flags passed to the C++ compiler. +CXXFLAGS += -g -Wall -Wextra -Werror -pthread -std=gnu++11 + +# All tests produced by this Makefile. generated from all *_test.cpp files +TESTS = $(patsubst %.cpp,%,$(wildcard *_test.cpp)) + +# All Google Test headers. Usually you shouldn't change this +# definition. +GTEST_HEADERS = $(GTEST_DIR)/include/gtest/*.h \ + $(GTEST_DIR)/include/gtest/internal/*.h + +# House-keeping build targets. + +all : $(TESTS) + +clean : + rm -f $(TESTS) gtest.a gtest_main.a *.o + +# Build and run all the tests. +run : all + failed=""; \ + for unittest in $(TESTS); do \ + ./$${unittest} || failed="$${failed} $${unittest}"; \ + done; \ + if [ -n "$${failed}" ]; then \ + echo "FAIL: :-( :-( Unit test(s)$${failed} failed! :-( :-("; exit 1; \ + else \ + echo "PASS: \o/ \o/ All unit tests passed. \o/ \o/"; \ + fi + +run_tests : run + +install-googletest : + git clone -b v1.8.x https://github.com/google/googletest.git ../lib/googletest + +# Builds gtest.a and gtest_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) + +# All the IR protocol object files. +PROTOCOL_OBJS = $(patsubst %.cpp,%.o,$(wildcard $(USER_DIR)/ir_*.cpp)) +PROTOCOLS = $(patsubst $(USER_DIR)/%,%,$(PROTOCOL_OBJS)) + +# All the IR Protocol header files. +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 +# Common dependencies +COMMON_DEPS = $(USER_DIR)/IRrecv.h $(USER_DIR)/IRsend.h $(USER_DIR)/IRtimer.h \ + $(USER_DIR)/IRutils.h $(USER_DIR)/IRremoteESP8266.h \ + $(USER_DIR)/IRac.h $(USER_DIR)/i18n.h $(USER_DIR)/IRtext.h \ + $(PROTOCOLS_H) + +# Common test dependencies +COMMON_TEST_DEPS = $(COMMON_DEPS) IRrecv_test.h IRsend_test.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. +gtest-all.o : $(GTEST_SRCS_) + $(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c \ + $(GTEST_DIR)/src/gtest-all.cc + +gtest_main.o : $(GTEST_SRCS_) + $(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c \ + $(GTEST_DIR)/src/gtest_main.cc + +gtest.a : gtest-all.o + $(AR) $(ARFLAGS) $@ $^ + +gtest_main.a : gtest-all.o gtest_main.o + $(AR) $(ARFLAGS) $@ $^ + +# Keep all intermediate files. +.SECONDARY: + +# Builds our test. A test should link with either gtest.a or +# gtest_main.a, depending on whether it defines its own main() +# function. + +IRtext.o : $(USER_DIR)/IRtext.cpp $(USER_DIR)/IRtext.h $(USER_DIR)/IRremoteESP8266.h $(USER_DIR)/i18n.h $(USER_DIR)/locale/*.h + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/IRtext.cpp + +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) + $(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 + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ + +IRtimer.o : $(USER_DIR)/IRtimer.cpp $(USER_DIR)/IRtimer.h + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/IRtimer.cpp + +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) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c IRsend_test.cpp + +IRrecv.o : $(USER_DIR)/IRrecv.cpp $(USER_DIR)/IRrecv.h $(USER_DIR)/IRremoteESP8266.h $(GTEST_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) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c IRrecv_test.cpp + +IRac.o : $(USER_DIR)/IRac.cpp $(USER_DIR)/IRac.h $(COMMON_DEPS) $(GTEST_HEADERS) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/IRac.cpp + +IRac_test.o : IRac_test.cpp $(USER_DIR)/IRac.h $(COMMON_DEPS) $(GTEST_HEADERS) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c IRac_test.cpp + +# new specific targets goes above this line + +ir_%.o : $(USER_DIR)/ir_%.h $(USER_DIR)/ir_%.cpp $(COMMON_DEPS) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_$*.cpp + +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) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_$*_test.cpp + +ir_%_test.o : ir_%_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_$*_test.cpp + +%_test : $(COMMON_OBJ) %_test.o + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Airwell_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Airwell_test.cpp similarity index 72% rename from lib/IRremoteESP8266-2.7.5/test/ir_Airwell_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Airwell_test.cpp index b58bceced..09300bac2 100644 --- a/lib/IRremoteESP8266-2.7.5/test/ir_Airwell_test.cpp +++ b/lib/IRremoteESP8266-2.7.8/test/ir_Airwell_test.cpp @@ -41,7 +41,7 @@ TEST(TestDecodeAirwell, RealExample) { ASSERT_TRUE(irrecv.decode(&irsend.capture)); ASSERT_EQ(decode_type_t::AIRWELL, irsend.capture.decode_type); ASSERT_EQ(kAirwellBits, irsend.capture.bits); - EXPECT_EQ(0x4F2FE7E4, irsend.capture.value); + EXPECT_EQ(0x2B0D0181B, irsend.capture.value); EXPECT_EQ(0x0, irsend.capture.address); EXPECT_EQ(0x0, irsend.capture.command); @@ -73,7 +73,7 @@ TEST(TestDecodeAirwell, RealExample) { ASSERT_TRUE(irrecv.decode(&irsend.capture)); ASSERT_EQ(decode_type_t::AIRWELL, irsend.capture.decode_type); ASSERT_EQ(kAirwellBits, irsend.capture.bits); - EXPECT_EQ(0x8F07E7E4, irsend.capture.value); + EXPECT_EQ(0x270F8181B, irsend.capture.value); EXPECT_EQ(0x0, irsend.capture.address); EXPECT_EQ(0x0, irsend.capture.command); } @@ -83,46 +83,16 @@ TEST(TestDecodeAirwell, SyntheticExample) { IRrecv irrecv(kGpioUnused); irsend.begin(); irsend.reset(); - irsend.sendAirwell(0xB0D0181B); + irsend.sendAirwell(0x2B0D0181B); irsend.makeDecodeResult(); ASSERT_TRUE(irrecv.decode(&irsend.capture)); EXPECT_EQ(decode_type_t::AIRWELL, irsend.capture.decode_type); EXPECT_EQ(kAirwellBits, irsend.capture.bits); - EXPECT_EQ(0xB0D0181B, irsend.capture.value); + EXPECT_EQ(0x2B0D0181B, irsend.capture.value); EXPECT_EQ(0x0, irsend.capture.address); EXPECT_EQ(0x0, irsend.capture.command); - EXPECT_EQ( - "f38000d50" - "m2850s3800" - "m1900s950m950s1900m1900s950m950s1900m950s950m950s950m950s950" - "m1900s950m950s1900m1900s1900m950s950m950s950m950s950m950s950" - "m950s950m950s950m1900s950m950s1900m950s950m950s950m950s950" - "m950s950m950s950m1900s950m950s1900m1900s950m950s950" - "m2850s3800" - "m1900s950m950s1900m1900s950m950s1900m950s950m950s950m950s950" - "m1900s950m950s1900m1900s1900m950s950m950s950m950s950m950s950" - "m950s950m950s950m1900s950m950s1900m950s950m950s950m950s950" - "m950s950m950s950m1900s950m950s1900m1900s950m950s950" - "m2850s3800" - "m1900s950m950s1900m1900s950m950s1900m950s950m950s950m950s950" - "m1900s950m950s1900m1900s1900m950s950m950s950m950s950m950s950" - "m950s950m950s950m1900s950m950s1900m950s950m950s950m950s950" - "m950s950m950s950m1900s950m950s1900m1900s950m950s950" - "m3800s100000", - irsend.outputStr()); - - irsend.reset(); - irsend.sendAirwell(0x4F2FE7E4); - irsend.makeDecodeResult(); - - ASSERT_TRUE(irrecv.decode(&irsend.capture)); - EXPECT_EQ(decode_type_t::AIRWELL, irsend.capture.decode_type); - EXPECT_EQ(kAirwellBits, irsend.capture.bits); - EXPECT_EQ(0x4F2FE7E4, irsend.capture.value); - EXPECT_EQ(0x0, irsend.capture.address); - EXPECT_EQ(0x0, irsend.capture.command); EXPECT_EQ( "f38000d50" "m2850s3800" @@ -143,6 +113,36 @@ TEST(TestDecodeAirwell, SyntheticExample) { "m4750s100000", irsend.outputStr()); + irsend.reset(); + irsend.sendAirwell(0x60080002); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(decode_type_t::AIRWELL, irsend.capture.decode_type); + EXPECT_EQ(kAirwellBits, irsend.capture.bits); + EXPECT_EQ(0x60080002, irsend.capture.value); + EXPECT_EQ(0x0, irsend.capture.address); + EXPECT_EQ(0x0, irsend.capture.command); + EXPECT_EQ( + "f38000d50" + "m2850s2850" + "m950s950m950s950m950s1900m950s950m1900s950m950s950m950s950m950s950" + "m950s950m950s950m950s950m950s950m950s1900m1900s950m950s950m950s950" + "m950s950m950s950m950s950m950s950m950s950m950s950m950s950m950s950" + "m950s950m950s950m950s950m950s950m950s950m950s1900m1900s950" + "m2850s2850" + "m950s950m950s950m950s1900m950s950m1900s950m950s950m950s950m950s950" + "m950s950m950s950m950s950m950s950m950s1900m1900s950m950s950m950s950" + "m950s950m950s950m950s950m950s950m950s950m950s950m950s950m950s950" + "m950s950m950s950m950s950m950s950m950s950m950s1900m1900s950" + "m2850s2850" + "m950s950m950s950m950s1900m950s950m1900s950m950s950m950s950m950s950" + "m950s950m950s950m950s950m950s950m950s1900m1900s950m950s950m950s950" + "m950s950m950s950m950s950m950s950m950s950m950s950m950s950m950s950" + "m950s950m950s950m950s950m950s950m950s950m950s1900m1900s950" + "m3800s100000", + irsend.outputStr()); + irsend.reset(); irsend.sendAirwell(0x70F8181B); irsend.makeDecodeResult(); @@ -214,3 +214,40 @@ TEST(TestUtils, Housekeeping) { ASSERT_EQ(kAirwellBits, IRsend::defaultBits(decode_type_t::AIRWELL)); ASSERT_EQ(kAirwellMinRepeats, IRsend::minRepeats(decode_type_t::AIRWELL)); } + +// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1069 +// Data from: +// https://docs.google.com/spreadsheets/d/1MeqVsgXQAMSiAx7zNunG8qbFcIT8tqZtcjLmMa0GEng/edit#gid=1053299474&range=M2:GW2 +TEST(TestDecodeAirwell, RealExample3) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + const uint16_t rawData[193] = { + 3010, 2852, + 904, 1042, 872, 1052, 872, 1932, 904, 956, 1878, 1050, 874, 1046, 872, + 956, 876, 1048, 872, 1044, 876, 1046, 874, 958, 872, 1050, 872, 1966, + 1880, 956, 872, 1048, 874, 1048, 872, 1050, 872, 958, 872, 1050, 872, + 1048, 872, 1050, 872, 958, 872, 1048, 872, 1050, 872, 1048, 872, 958, 872, + 1050, 872, 1048, 872, 1050, 872, 1872, 1880, 1048, + 2978, 2880, + 872, 1048, 872, 1050, 872, 1964, 872, 958, 1880, 1050, 872, 1050, 872, + 958, 872, 1050, 872, 1050, 872, 1050, 872, 958, 872, 1050, 872, 1964, + 1882, 958, 870, 1050, 872, 1048, 872, 1050, 872, 958, 872, 1048, 872, + 1050, 872, 1050, 872, 958, 872, 1050, 872, 1050, 872, 1050, 872, 958, 872, + 1050, 872, 1050, 872, 1050, 872, 1874, 1880, 1050, + 2978, 2880, + 872, 1050, 872, 1050, 872, 1964, 872, 958, 1880, 1050, 872, 1050, 872, + 958, 872, 1050, 872, 1050, 872, 1050, 872, 958, 872, 1050, 872, 1964, + 1880, 958, 872, 1050, 872, 1050, 872, 1050, 872, 958, 872, 1052, 870, + 1050, 872, 1050, 872, 958, 872, 1050, 872, 1050, 872, 1050, 872, 958, 872, + 1050, 872, 1050, 872, 1050, 872, 1874, 1880, 1050, 3894}; + irsend.reset(); + irsend.sendRaw(rawData, 193, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decodeAirwell(&irsend.capture)); + ASSERT_EQ(decode_type_t::AIRWELL, irsend.capture.decode_type); + ASSERT_EQ(kAirwellBits, irsend.capture.bits); + EXPECT_EQ(0x60080002, irsend.capture.value); + EXPECT_EQ(0x0, irsend.capture.address); + EXPECT_EQ(0x0, irsend.capture.command); +} diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Aiwa_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Aiwa_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/ir_Aiwa_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Aiwa_test.cpp diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Amcor_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Amcor_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/ir_Amcor_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Amcor_test.cpp diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Argo_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Argo_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/ir_Argo_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Argo_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Carrier_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Carrier_test.cpp new file mode 100644 index 000000000..fb6fb1b1b --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/test/ir_Carrier_test.cpp @@ -0,0 +1,614 @@ +// Copyright 2018, 2020 David Conran + +#include "ir_Carrier.h" +#include "IRac.h" +#include "IRrecv.h" +#include "IRsend.h" +#include "IRsend_test.h" +#include "gtest/gtest.h" + +// Tests for sendCarrierAC() + +// Test sending typical data only. +TEST(TestSendCarrierAC, SendDataOnly) { + IRsendTest irsend(0); + irsend.begin(); + + irsend.reset(); + irsend.sendCarrierAC(0x0); + EXPECT_EQ( + "f38000d50" + "m8532s4228" + "m628s532m628s532m628s532m628s532m628s532m628s532m628s532m628s532" + "m628s532m628s532m628s532m628s532m628s532m628s532m628s532m628s532" + "m628s532m628s532m628s532m628s532m628s532m628s532m628s532m628s532" + "m628s532m628s532m628s532m628s532m628s532m628s532m628s532m628s532" + "m628s20000" + "m8532s4228" + "m628s1320m628s1320m628s1320m628s1320m628s1320m628s1320m628s1320m628s1320" + "m628s1320m628s1320m628s1320m628s1320m628s1320m628s1320m628s1320m628s1320" + "m628s1320m628s1320m628s1320m628s1320m628s1320m628s1320m628s1320m628s1320" + "m628s1320m628s1320m628s1320m628s1320m628s1320m628s1320m628s1320m628s1320" + "m628s20000" + "m8532s4228" + "m628s532m628s532m628s532m628s532m628s532m628s532m628s532m628s532" + "m628s532m628s532m628s532m628s532m628s532m628s532m628s532m628s532" + "m628s532m628s532m628s532m628s532m628s532m628s532m628s532m628s532" + "m628s532m628s532m628s532m628s532m628s532m628s532m628s532m628s532" + "m628s20000", + irsend.outputStr()); + irsend.reset(); + irsend.sendCarrierAC(0x12345678); + EXPECT_EQ( + "f38000d50" + "m8532s4228" + "m628s532m628s532m628s532m628s1320m628s532m628s532m628s1320m628s532" + "m628s532m628s532m628s1320m628s1320m628s532m628s1320m628s532m628s532" + "m628s532m628s1320m628s532m628s1320m628s532m628s1320m628s1320m628s532" + "m628s532m628s1320m628s1320m628s1320m628s1320m628s532m628s532m628s532" + "m628s20000" + "m8532s4228" + "m628s1320m628s1320m628s1320m628s532m628s1320m628s1320m628s532m628s1320" + "m628s1320m628s1320m628s532m628s532m628s1320m628s532m628s1320m628s1320" + "m628s1320m628s532m628s1320m628s532m628s1320m628s532m628s532m628s1320" + "m628s1320m628s532m628s532m628s532m628s532m628s1320m628s1320m628s1320" + "m628s20000" + "m8532s4228" + "m628s532m628s532m628s532m628s1320m628s532m628s532m628s1320m628s532" + "m628s532m628s532m628s1320m628s1320m628s532m628s1320m628s532m628s532" + "m628s532m628s1320m628s532m628s1320m628s532m628s1320m628s1320m628s532" + "m628s532m628s1320m628s1320m628s1320m628s1320m628s532m628s532m628s532" + "m628s20000", + irsend.outputStr()); + + irsend.reset(); + irsend.sendCarrierAC(0x4CCA541D); + EXPECT_EQ( + "f38000d50" + "m8532s4228" + "m628s532m628s1320m628s532m628s532m628s1320m628s1320m628s532m628s532" + "m628s1320m628s1320m628s532m628s532m628s1320m628s532m628s1320m628s532" + "m628s532m628s1320m628s532m628s1320m628s532m628s1320m628s532m628s532" + "m628s532m628s532m628s532m628s1320m628s1320m628s1320m628s532m628s1320" + "m628s20000" + "m8532s4228" + "m628s1320m628s532m628s1320m628s1320m628s532m628s532m628s1320m628s1320" + "m628s532m628s532m628s1320m628s1320m628s532m628s1320m628s532m628s1320" + "m628s1320m628s532m628s1320m628s532m628s1320m628s532m628s1320m628s1320" + "m628s1320m628s1320m628s1320m628s532m628s532m628s532m628s1320m628s532" + "m628s20000" + "m8532s4228" + "m628s532m628s1320m628s532m628s532m628s1320m628s1320m628s532m628s532" + "m628s1320m628s1320m628s532m628s532m628s1320m628s532m628s1320m628s532" + "m628s532m628s1320m628s532m628s1320m628s532m628s1320m628s532m628s532" + "m628s532m628s532m628s532m628s1320m628s1320m628s1320m628s532m628s1320" + "m628s20000", + irsend.outputStr()); +} + +// Test sending typical data only. +TEST(TestSendCarrierAC, SendWithRepeats) { + IRsendTest irsend(0); + irsend.begin(); + + irsend.reset(); + irsend.sendCarrierAC(0x12345678, kCarrierAcBits, 2); // two repeats. + EXPECT_EQ( + "f38000d50" + "m8532s4228" + "m628s532m628s532m628s532m628s1320m628s532m628s532m628s1320m628s532" + "m628s532m628s532m628s1320m628s1320m628s532m628s1320m628s532m628s532" + "m628s532m628s1320m628s532m628s1320m628s532m628s1320m628s1320m628s532" + "m628s532m628s1320m628s1320m628s1320m628s1320m628s532m628s532m628s532" + "m628s20000" + "m8532s4228" + "m628s1320m628s1320m628s1320m628s532m628s1320m628s1320m628s532m628s1320" + "m628s1320m628s1320m628s532m628s532m628s1320m628s532m628s1320m628s1320" + "m628s1320m628s532m628s1320m628s532m628s1320m628s532m628s532m628s1320" + "m628s1320m628s532m628s532m628s532m628s532m628s1320m628s1320m628s1320" + "m628s20000" + "m8532s4228" + "m628s532m628s532m628s532m628s1320m628s532m628s532m628s1320m628s532" + "m628s532m628s532m628s1320m628s1320m628s532m628s1320m628s532m628s532" + "m628s532m628s1320m628s532m628s1320m628s532m628s1320m628s1320m628s532" + "m628s532m628s1320m628s1320m628s1320m628s1320m628s532m628s532m628s532" + "m628s20000" + "m8532s4228" + "m628s532m628s532m628s532m628s1320m628s532m628s532m628s1320m628s532" + "m628s532m628s532m628s1320m628s1320m628s532m628s1320m628s532m628s532" + "m628s532m628s1320m628s532m628s1320m628s532m628s1320m628s1320m628s532" + "m628s532m628s1320m628s1320m628s1320m628s1320m628s532m628s532m628s532" + "m628s20000" + "m8532s4228" + "m628s1320m628s1320m628s1320m628s532m628s1320m628s1320m628s532m628s1320" + "m628s1320m628s1320m628s532m628s532m628s1320m628s532m628s1320m628s1320" + "m628s1320m628s532m628s1320m628s532m628s1320m628s532m628s532m628s1320" + "m628s1320m628s532m628s532m628s532m628s532m628s1320m628s1320m628s1320" + "m628s20000" + "m8532s4228" + "m628s532m628s532m628s532m628s1320m628s532m628s532m628s1320m628s532" + "m628s532m628s532m628s1320m628s1320m628s532m628s1320m628s532m628s532" + "m628s532m628s1320m628s532m628s1320m628s532m628s1320m628s1320m628s532" + "m628s532m628s1320m628s1320m628s1320m628s1320m628s532m628s532m628s532" + "m628s20000" + "m8532s4228" + "m628s532m628s532m628s532m628s1320m628s532m628s532m628s1320m628s532" + "m628s532m628s532m628s1320m628s1320m628s532m628s1320m628s532m628s532" + "m628s532m628s1320m628s532m628s1320m628s532m628s1320m628s1320m628s532" + "m628s532m628s1320m628s1320m628s1320m628s1320m628s532m628s532m628s532" + "m628s20000" + "m8532s4228" + "m628s1320m628s1320m628s1320m628s532m628s1320m628s1320m628s532m628s1320" + "m628s1320m628s1320m628s532m628s532m628s1320m628s532m628s1320m628s1320" + "m628s1320m628s532m628s1320m628s532m628s1320m628s532m628s532m628s1320" + "m628s1320m628s532m628s532m628s532m628s532m628s1320m628s1320m628s1320" + "m628s20000" + "m8532s4228" + "m628s532m628s532m628s532m628s1320m628s532m628s532m628s1320m628s532" + "m628s532m628s532m628s1320m628s1320m628s532m628s1320m628s532m628s532" + "m628s532m628s1320m628s532m628s1320m628s532m628s1320m628s1320m628s532" + "m628s532m628s1320m628s1320m628s1320m628s1320m628s532m628s532m628s532" + "m628s20000", + irsend.outputStr()); +} + +// Tests for decodeCarrierAC(). + +// Decode normal "synthetic" messages. +TEST(TestDecodeCarrierAC, NormalDecodeWithStrict) { + IRsendTest irsend(0); + IRrecv irrecv(0); + irsend.begin(); + + irsend.reset(); + irsend.sendCarrierAC(0x0); + irsend.makeDecodeResult(); + ASSERT_TRUE(irrecv.decodeCarrierAC(&irsend.capture, kStartOffset, + kCarrierAcBits, true)); + EXPECT_EQ(CARRIER_AC, irsend.capture.decode_type); + EXPECT_EQ(kCarrierAcBits, irsend.capture.bits); + EXPECT_EQ(0x0, irsend.capture.value); + EXPECT_EQ(0x0, irsend.capture.address); + EXPECT_EQ(0x0, irsend.capture.command); + EXPECT_FALSE(irsend.capture.repeat); + + irsend.reset(); + irsend.sendCarrierAC(0xB335ABE2); + irsend.makeDecodeResult(); + ASSERT_TRUE(irrecv.decodeCarrierAC(&irsend.capture, kStartOffset, + kCarrierAcBits, true)); + EXPECT_EQ(CARRIER_AC, irsend.capture.decode_type); + EXPECT_EQ(kCarrierAcBits, irsend.capture.bits); + EXPECT_EQ(0xB335ABE2, irsend.capture.value); + EXPECT_EQ(0xB335, irsend.capture.address); + EXPECT_EQ(0xABE2, irsend.capture.command); + EXPECT_FALSE(irsend.capture.repeat); + + // Do the last one again, & use the full decoder, not just protocol specific. + irsend.reset(); + irsend.sendCarrierAC(0xB335ABE2); + irsend.makeDecodeResult(); + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(CARRIER_AC, irsend.capture.decode_type); + EXPECT_EQ(kCarrierAcBits, irsend.capture.bits); + EXPECT_EQ(0xB335ABE2, irsend.capture.value); +} + +// Decode a "real" example message. +TEST(TestDecodeCarrierAC, RealExamples) { + IRsendTest irsend(0); + IRrecv irrecv(0); + irsend.begin(); + + irsend.reset(); + // Data from Issue #385 captured by gnkarn + uint16_t rawData[203] = { + 8532, 4216, 628, 1312, 628, 528, 628, 1312, 628, 1312, 628, 528, + 628, 524, 628, 1316, 624, 1316, 628, 524, 628, 528, 628, 1312, + 628, 1316, 624, 528, 628, 1312, 628, 528, 628, 1312, 628, 1312, + 628, 528, 628, 1316, 624, 528, 628, 1312, 628, 528, 628, 1312, + 628, 1316, 624, 1316, 628, 1312, 628, 1316, 628, 524, 628, 528, + 628, 528, 624, 1316, 628, 528, 628, 20064, 8504, 4228, 628, 528, + 628, 1312, 628, 528, 628, 528, 628, 1312, 628, 1316, 624, 532, + 624, 528, 628, 1316, 628, 1312, 628, 528, 628, 528, 628, 1312, + 628, 528, 628, 1316, 628, 528, 624, 528, 628, 1316, 628, 528, + 628, 1316, 624, 528, 628, 1316, 628, 528, 624, 532, 624, 528, + 628, 528, 628, 528, 628, 1316, 624, 1316, 628, 1316, 628, 528, + 624, 1316, 628, 20076, 8528, 4212, 624, 1316, 628, 528, 628, 1316, + 628, 1316, 624, 528, 628, 528, 628, 1316, 628, 1316, 628, 528, + 624, 532, 624, 1316, 628, 1316, 628, 528, 628, 1316, 624, 528, + 628, 1316, 628, 1316, 628, 528, 628, 1316, 624, 532, 624, 1316, + 628, 532, 624, 1316, 628, 1316, 624, 1320, 624, 1316, 628, 1316, + 628, 528, 628, 528, 628, 528, 628, 1316, 624, 532, 624}; + + irsend.sendRaw(rawData, 203, 38000); + irsend.makeDecodeResult(); + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(CARRIER_AC, irsend.capture.decode_type); + EXPECT_EQ(kCarrierAcBits, irsend.capture.bits); + EXPECT_EQ(0xB335ABE2, irsend.capture.value); + EXPECT_EQ(0xB335, irsend.capture.address); + EXPECT_EQ(0xABE2, irsend.capture.command); + EXPECT_FALSE(irsend.capture.repeat); +} + +TEST(TestUtils, Housekeeping) { + // CARRIER_AC + ASSERT_EQ("CARRIER_AC", typeToString(decode_type_t::CARRIER_AC)); + ASSERT_EQ(decode_type_t::CARRIER_AC, strToDecodeType("CARRIER_AC")); + ASSERT_FALSE(hasACState(decode_type_t::CARRIER_AC)); + ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::CARRIER_AC)); + ASSERT_EQ(kCarrierAcBits, + IRsend::defaultBits(decode_type_t::CARRIER_AC)); + ASSERT_EQ(kCarrierAcMinRepeat, + IRsend::minRepeats(decode_type_t::CARRIER_AC)); + + // CARRIER_AC40 + ASSERT_EQ("CARRIER_AC40", typeToString(decode_type_t::CARRIER_AC40)); + ASSERT_EQ(decode_type_t::CARRIER_AC40, strToDecodeType("CARRIER_AC40")); + ASSERT_FALSE(hasACState(decode_type_t::CARRIER_AC40)); + ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::CARRIER_AC40)); + ASSERT_EQ(kCarrierAc40Bits, + IRsend::defaultBits(decode_type_t::CARRIER_AC40)); + ASSERT_EQ(kCarrierAc40MinRepeat, + IRsend::minRepeats(decode_type_t::CARRIER_AC40)); + + // CARRIER_AC64 + ASSERT_EQ("CARRIER_AC64", typeToString(decode_type_t::CARRIER_AC64)); + ASSERT_EQ(decode_type_t::CARRIER_AC64, strToDecodeType("CARRIER_AC64")); + ASSERT_FALSE(hasACState(decode_type_t::CARRIER_AC64)); + ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::CARRIER_AC64)); + ASSERT_EQ(kCarrierAc64Bits, + IRsend::defaultBits(decode_type_t::CARRIER_AC64)); + ASSERT_EQ(kCarrierAc64MinRepeat, + IRsend::minRepeats(decode_type_t::CARRIER_AC64)); +} + +/// Decode a "real" example message. +TEST(TestDecodeCarrierAC40, RealExample) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + irsend.begin(); + + irsend.reset(); + // Data from: + // https://github.com/crankyoldgit/IRremoteESP8266/issues/1112#issuecomment-627961192 + const uint16_t rawData[83] = { + 8402, 4166, + 562, 1550, 538, 1526, 562, 1552, 538, 1524, 566, 504, 538, 504, 540, 480, + 564, 506, 538, 506, 538, 506, 538, 1550, 538, 1550, 540, 506, 538, 506, + 538, 1550, 538, 506, 540, 478, 564, 480, 564, 506, 540, 1550, 538, 506, + 540, 506, 538, 1524, 564, 506, 538, 1550, 538, 1550, 538, 482, 562, 482, + 562, 506, 540, 504, 540, 482, 562, 506, 538, 1550, 538, 1550, 540, 1524, + 564, 1526, 564, 480, 564, 1528, 562, 504, 540, 480, + 564}; // UNKNOWN BCF4730D + + irsend.sendRaw(rawData, 83, 38000); + irsend.makeDecodeResult(); + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(CARRIER_AC40, irsend.capture.decode_type); + EXPECT_EQ(kCarrierAc40Bits, irsend.capture.bits); + EXPECT_EQ(0xF03212C0F4, irsend.capture.value); + EXPECT_EQ(0, irsend.capture.address); + EXPECT_EQ(0, irsend.capture.command); +} + +/// Send & Decode a synthetic message. +TEST(TestDecodeCarrierAC40, SyntheticExample) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + irsend.begin(); + + irsend.reset(); + + irsend.sendCarrierAC40(0xF03212C0F4); + irsend.makeDecodeResult(); + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(CARRIER_AC40, irsend.capture.decode_type); + EXPECT_EQ(kCarrierAc40Bits, irsend.capture.bits); + EXPECT_EQ(0xF03212C0F4, irsend.capture.value); + EXPECT_EQ(0, irsend.capture.address); + EXPECT_EQ(0, irsend.capture.command); + // Payload is sent a total of three times. + EXPECT_EQ( + "f38000d50" + // Initial + "m8402s4166" + "m547s1540m547s1540m547s1540m547s1540m547s497m547s497m547s497m547s497" + "m547s497m547s497m547s1540m547s1540m547s497m547s497m547s1540m547s497" + "m547s497m547s497m547s497m547s1540m547s497m547s497m547s1540m547s497" + "m547s1540m547s1540m547s497m547s497m547s497m547s497m547s497m547s497" + "m547s1540m547s1540m547s1540m547s1540m547s497m547s1540m547s497m547s497" + "m547s150000" + // Repeat #1 + "m8402s4166" + "m547s1540m547s1540m547s1540m547s1540m547s497m547s497m547s497m547s497" + "m547s497m547s497m547s1540m547s1540m547s497m547s497m547s1540m547s497" + "m547s497m547s497m547s497m547s1540m547s497m547s497m547s1540m547s497" + "m547s1540m547s1540m547s497m547s497m547s497m547s497m547s497m547s497" + "m547s1540m547s1540m547s1540m547s1540m547s497m547s1540m547s497m547s497" + "m547s150000" + // Repeat #2 + "m8402s4166" + "m547s1540m547s1540m547s1540m547s1540m547s497m547s497m547s497m547s497" + "m547s497m547s497m547s1540m547s1540m547s497m547s497m547s1540m547s497" + "m547s497m547s497m547s497m547s1540m547s497m547s497m547s1540m547s497" + "m547s1540m547s1540m547s497m547s497m547s497m547s497m547s497m547s497" + "m547s1540m547s1540m547s1540m547s1540m547s497m547s1540m547s497m547s497" + "m547s150000", + irsend.outputStr()); +} + +/// Decode a "real" example message. +TEST(TestDecodeCarrierAC64, RealExample) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + irsend.begin(); + + irsend.reset(); + // Data from: + // https://github.com/crankyoldgit/IRremoteESP8266/issues/1127#issuecomment-629713855 + const uint16_t rawData[131] = { + 8940, 4556, + 504, 616, 504, 616, 502, 1736, 504, 616, 504, 616, 504, 616, 502, 616, + 502, 1736, 504, 1736, 502, 616, 504, 1736, 504, 616, 502, 1736, 504, 616, + 502, 1736, 502, 616, 504, 616, 504, 1736, 502, 1736, 504, 1736, 502, 1736, + 504, 616, 502, 1736, 502, 616, 504, 616, 504, 1736, 504, 1736, 504, 1736, + 504, 616, 504, 1736, 502, 616, 502, 616, 504, 616, 504, 616, 502, 616, + 502, 616, 504, 1736, 504, 616, 504, 616, 502, 616, 504, 616, 504, 616, + 502, 616, 502, 616, 504, 616, 504, 616, 504, 616, 502, 616, 504, 616, + 504, 616, 502, 616, 502, 616, 504, 616, 504, 616, 504, 1736, 504, 616, + 504, 616, 504, 616, 504, 616, 504, 616, 504, 616, 504, 616, 502, 1736, + 504, 586, 502}; + + irsend.sendRaw(rawData, 131, 38000); + irsend.makeDecodeResult(); + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(CARRIER_AC64, irsend.capture.decode_type); + EXPECT_EQ(kCarrierAc64Bits, irsend.capture.bits); + EXPECT_EQ(0x404000102E5E5584, irsend.capture.value); + EXPECT_EQ(0, irsend.capture.address); + EXPECT_EQ(0, irsend.capture.command); + EXPECT_EQ( + "Power: On, Mode: 1 (Heat), Temp: 30C, Fan: 1 (Low), Swing(V): On, " + "Sleep: Off, On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); +} + +/// Send & Decode a synthetic message. +TEST(TestDecodeCarrierAC64, SyntheticExample) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + irsend.begin(); + + irsend.reset(); + + irsend.sendCarrierAC64(0x404000102E5E5584); + irsend.makeDecodeResult(); + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(CARRIER_AC64, irsend.capture.decode_type); + EXPECT_EQ(kCarrierAc64Bits, irsend.capture.bits); + EXPECT_EQ(0x404000102E5E5584, irsend.capture.value); + EXPECT_EQ(0, irsend.capture.address); + EXPECT_EQ(0, irsend.capture.command); + EXPECT_EQ( + "f38000d50m" + // Header + "8940s4556" + // Data + "m503s615m503s615m503s1736m503s615m503s615m503s615m503s615m503s1736" + "m503s1736m503s615m503s1736m503s615m503s1736m503s615m503s1736m503s615" + "m503s615m503s1736m503s1736m503s1736m503s1736m503s615m503s1736m503s615" + "m503s615m503s1736m503s1736m503s1736m503s615m503s1736m503s615m503s615" + "m503s615m503s615m503s615m503s615m503s1736m503s615m503s615m503s615" + "m503s615m503s615m503s615m503s615m503s615m503s615m503s615m503s615" + "m503s615m503s615m503s615m503s615m503s615m503s615m503s1736m503s615" + "m503s615m503s615m503s615m503s615m503s615m503s615m503s1736m503s615" + // Footer + "m503s100000", + irsend.outputStr()); +} + +// Tests for IRCarrierAc64 class. + +TEST(TestCarrierAc64Class, Power) { + IRCarrierAc64 ac(kGpioUnused); + ac.begin(); + + ac.on(); + EXPECT_TRUE(ac.getPower()); + + ac.off(); + EXPECT_FALSE(ac.getPower()); + + ac.setPower(true); + EXPECT_TRUE(ac.getPower()); + + ac.setPower(false); + EXPECT_FALSE(ac.getPower()); + + ASSERT_EQ(36, kCarrierAc64PowerOffset); +} + +TEST(TestCarrierAc64Class, Temperature) { + IRCarrierAc64 ac(kGpioUnused); + ac.begin(); + + ac.setTemp(0); + EXPECT_EQ(kCarrierAc64MinTemp, ac.getTemp()); + + ac.setTemp(255); + EXPECT_EQ(kCarrierAc64MaxTemp, ac.getTemp()); + + ac.setTemp(kCarrierAc64MinTemp); + EXPECT_EQ(kCarrierAc64MinTemp, ac.getTemp()); + + ac.setTemp(kCarrierAc64MaxTemp); + EXPECT_EQ(kCarrierAc64MaxTemp, ac.getTemp()); + + ac.setTemp(kCarrierAc64MinTemp - 1); + EXPECT_EQ(kCarrierAc64MinTemp, ac.getTemp()); + + ac.setTemp(kCarrierAc64MaxTemp + 1); + EXPECT_EQ(kCarrierAc64MaxTemp, ac.getTemp()); + + ac.setTemp(17); + EXPECT_EQ(17, ac.getTemp()); + + ac.setTemp(21); + EXPECT_EQ(21, ac.getTemp()); + + ac.setTemp(25); + EXPECT_EQ(25, ac.getTemp()); + + ac.setTemp(29); + EXPECT_EQ(29, ac.getTemp()); +} + +TEST(TestCarrierAc64Class, OperatingMode) { + IRCarrierAc64 ac(kGpioUnused); + ac.begin(); + + ac.setMode(kCarrierAc64Cool); + EXPECT_EQ(kCarrierAc64Cool, ac.getMode()); + + ac.setMode(kCarrierAc64Fan); + EXPECT_EQ(kCarrierAc64Fan, ac.getMode()); + + ac.setMode(kCarrierAc64Heat); + EXPECT_EQ(kCarrierAc64Heat, ac.getMode()); + + ac.setMode(kCarrierAc64Fan + 1); + EXPECT_EQ(kCarrierAc64Cool, ac.getMode()); + + ac.setMode(255); + EXPECT_EQ(kCarrierAc64Cool, ac.getMode()); + ac.setMode(0); + EXPECT_EQ(kCarrierAc64Cool, ac.getMode()); +} + +TEST(TestCarrierAc64Class, Sleep) { + IRCarrierAc64 ac(kGpioUnused); + ac.begin(); + ac.setSleep(true); + EXPECT_TRUE(ac.getSleep()); + ac.setSleep(false); + EXPECT_FALSE(ac.getSleep()); + ac.setSleep(true); + EXPECT_TRUE(ac.getSleep()); +} + +TEST(TestCarrierAc64Class, SwingVertical) { + IRCarrierAc64 ac(kGpioUnused); + ac.begin(); + ac.setSwingV(true); + EXPECT_TRUE(ac.getSwingV()); + ac.setSwingV(false); + EXPECT_FALSE(ac.getSwingV()); + ac.setSwingV(true); + EXPECT_TRUE(ac.getSwingV()); +} + +TEST(TestCarrierAc64Class, FanSpeed) { + IRCarrierAc64 ac(kGpioUnused); + ac.begin(); + + // Unexpected value should default to Auto. + ac.setFan(255); + EXPECT_EQ(kCarrierAc64FanAuto, ac.getFan()); + ac.setFan(5); + EXPECT_EQ(kCarrierAc64FanAuto, ac.getFan()); + + ac.setFan(kCarrierAc64FanHigh); + EXPECT_EQ(kCarrierAc64FanHigh, ac.getFan()); + + // Beyond High should default to Auto. + ac.setFan(kCarrierAc64FanHigh + 1); + EXPECT_EQ(kCarrierAc64FanAuto, ac.getFan()); + + ac.setFan(kCarrierAc64FanMedium); + EXPECT_EQ(kCarrierAc64FanMedium, ac.getFan()); + + ac.setFan(kCarrierAc64FanLow); + EXPECT_EQ(kCarrierAc64FanLow, ac.getFan()); + + ac.setFan(kCarrierAc64FanAuto); + EXPECT_EQ(kCarrierAc64FanAuto, ac.getFan()); +} + +TEST(TestCarrierAc64Class, ChecksumAndSetGetRaw) { + IRCarrierAc64 ac(kGpioUnused); + + const uint64_t valid = 0x90900030205C5584; + const uint64_t invalid = 0x9090003020505584; + ASSERT_NE(valid, invalid); + ASSERT_EQ(0x0C, IRCarrierAc64::calcChecksum(valid)); + ASSERT_TRUE(IRCarrierAc64::validChecksum(valid)); + ASSERT_FALSE(IRCarrierAc64::validChecksum(invalid)); + ac.setRaw(valid); + ASSERT_EQ(valid, ac.getRaw()); + ac.setRaw(invalid); + ASSERT_EQ(valid, ac.getRaw()); + + // Additional known states. + ASSERT_TRUE(IRCarrierAc64::validChecksum(0x109000002C2A5584)); + ASSERT_TRUE(IRCarrierAc64::validChecksum(0x109000102C2B5584)); +} + +// Test human readable output. +TEST(TestCarrierAc64Class, HumanReadable) { + IRCarrierAc64 ac(kGpioUnused); + EXPECT_EQ( + "Power: Off, Mode: 2 (Cool), Temp: 28C, Fan: 0 (Auto), Swing(V): On, " + "Sleep: Off, On Timer: Off, Off Timer: Off", + ac.toString()); + ac.setPower(true); + ac.setMode(kCarrierAc64Fan); + ac.setTemp(30); + ac.setFan(kCarrierAc64FanAuto); + ac.setSwingV(true); + EXPECT_EQ( + "Power: On, Mode: 3 (Fan), Temp: 30C, Fan: 0 (Auto), Swing(V): On, " + "Sleep: Off, On Timer: Off, Off Timer: Off", + ac.toString()); + ac.setOffTimer(8* 60 + 37); + EXPECT_EQ( + "Power: On, Mode: 3 (Fan), Temp: 30C, Fan: 0 (Auto), Swing(V): On, " + "Sleep: Off, On Timer: Off, Off Timer: 08:00", + ac.toString()); + ac.setOnTimer(5 * 60 + 59); + EXPECT_EQ( + "Power: On, Mode: 3 (Fan), Temp: 30C, Fan: 0 (Auto), Swing(V): On, " + "Sleep: Off, On Timer: 05:00, Off Timer: Off", + ac.toString()); + ac.setOnTimer(59); + EXPECT_EQ( + "Power: On, Mode: 3 (Fan), Temp: 30C, Fan: 0 (Auto), Swing(V): On, " + "Sleep: Off, On Timer: Off, Off Timer: Off", + ac.toString()); + ac.setSleep(true); + EXPECT_EQ( + "Power: On, Mode: 3 (Fan), Temp: 30C, Fan: 0 (Auto), Swing(V): On, " + "Sleep: On, On Timer: Off, Off Timer: Off", + ac.toString()); +} + +TEST(TestCarrierAc64Class, ReconstructKnownState) { + IRCarrierAc64 ac(kGpioUnused); + const uint64_t expected = 0x2030009020555584; + ac.begin(); + ac.stateReset(); + ASSERT_NE(expected, ac.getRaw()); + ac.on(); + ac.setMode(kCarrierAc64Heat); + ac.setTemp(16); + ac.setFan(kCarrierAc64FanLow); + ac.setSwingV(true); + ac.setOnTimer(3 * 60); + ac.setSleep(true); + EXPECT_EQ(expected, ac.getRaw()); + EXPECT_EQ( + "Power: On, Mode: 1 (Heat), Temp: 16C, Fan: 1 (Low), Swing(V): On, " + "Sleep: On, On Timer: Off, Off Timer: Off", + ac.toString()); +} diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Coolix_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Coolix_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/ir_Coolix_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Coolix_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Corona_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Corona_test.cpp new file mode 100644 index 000000000..4bada0854 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/test/ir_Corona_test.cpp @@ -0,0 +1,1690 @@ +// Copyright 2020 Christian Nilsson + +#include "ir_Corona.h" +#include "IRac.h" +#include "IRrecv.h" +#include "IRrecv_test.h" +#include "IRsend.h" +#include "IRsend_test.h" +#include "gtest/gtest.h" + +// Tests for decodeCoronaAc(). +TEST(TestDecodeCoronaAc, RealExample) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + + const uint16_t rawData_On[347] = { + 3520, 1686, + 460, 386, 452, 454, 408, 452, 410, 1320, 434, 428, 434, 1296, + 410, 452, 490, 374, 438, 1292, 434, 430, 434, 428, 438, 424, + 438, 426, 438, 1266, 464, 1266, 462, 402, 462, 1266, 464, 400, + 462, 1268, 464, 1266, 462, 1266, 464, 1268, 486, 376, 462, 402, + 472, 1256, 488, 378, 514, 346, 464, 1266, 488, 1240, 462, 404, + 462, 426, 460, 376, 462, 402, 488, 1240, 464, 1266, 462, 402, + 462, 400, 490, 1240, 462, 1266, 486, 1244, 460, 1268, 462, 1266, + 462, 1266, 462, 404, 458, 1270, 458, 1268, 462, 400, 464, 428, + 434, 402, 460, 402, 462, 398, 462, 1268, 462, 404, 460, 402, + 460, 1266, 466, 1264, + 462, 10808, + 3502, 1686, + 462, 400, 462, 400, 462, 400, 464, 1266, 462, 404, 458, 1266, + 464, 402, 460, 402, 462, 1266, 464, 404, 458, 402, 460, 400, + 488, 374, 464, 1266, 462, 1266, 466, 398, 462, 1268, 462, 400, + 518, 1208, 438, 1292, 440, 426, 488, 1242, 466, 1264, 460, 402, + 490, 1238, 490, 1238, 490, 1242, 514, 1212, 464, 1268, 490, 1238, + 464, 1266, 490, 1238, 462, 406, 458, 400, 464, 398, 464, 402, + 488, 374, 486, 376, 460, 402, 488, 372, 464, 1268, 462, 1264, + 464, 1266, 462, 1268, 462, 1266, 466, 1266, 490, 1242, 458, 1264, + 516, 348, 462, 404, 460, 404, 462, 398, 516, 344, 462, 400, + 464, 402, 488, 376, + 460, 10810, + 3526, 1658, + 462, 404, 460, 400, 488, 374, 464, 1264, 462, 402, 464, 1266, + 462, 402, 486, 374, 462, 1266, 546, 318, 462, 400, 464, 400, + 462, 402, 460, 1268, 466, 1262, 492, 374, 516, 1212, 464, 400, + 462, 1266, 516, 1212, 464, 402, 462, 424, 462, 1242, 460, 1268, + 488, 1242, 462, 1268, 490, 1236, 466, 1264, 462, 1268, 464, 1266, + 460, 1268, 464, 1266, 462, 338, 528, 402, 486, 374, 462, 402, + 460, 402, 490, 374, 458, 406, 458, 402, 488, 1240, 490, 1238, + 462, 1268, 464, 1268, 490, 1238, 488, 1242, 462, 1264, 464, 1270, + 462, 398, 436, 426, 460, 406, 458, 404, 434, 424, 464, 400, + 462, 400, 460, 402, + 462}; // UNKNOWN 94D81276 * ON + const uint8_t expectedState_On[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x37, 0xC8, + 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_On, 347, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState_On, irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: On, Power Button: On, Mode: 0 (Heat), Temp: 23C, " + "Fan: 1 (Low), Swing(V) Toggle: Off, Econo: On, " + "On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + + + const uint16_t rawData_Off[347] = { + 3520, 1686, + 462, 400, 460, 402, 462, 382, 482, 1266, 462, 400, 462, 1268, + 462, 404, 488, 372, 462, 1266, 464, 402, 458, 404, 458, 382, + 482, 400, 462, 1266, 438, 1294, 488, 376, 460, 1268, 460, 400, + 470, 1260, 460, 1270, 462, 1268, 460, 1268, 462, 404, 458, 402, + 460, 1266, 462, 402, 462, 400, 462, 1268, 464, 1264, 462, 384, + 480, 400, 460, 404, 448, 414, 460, 1268, 462, 1268, 460, 402, + 490, 372, 462, 1268, 464, 1266, 462, 1268, 460, 1266, 464, 1266, + 464, 1266, 462, 404, 460, 400, 438, 1294, 486, 376, 462, 400, + 462, 402, 462, 400, 460, 402, 462, 1268, 460, 1268, 462, 404, + 486, 1240, 464, 1268, + 460, 10788, + 3524, 1682, + 462, 402, 462, 402, 460, 404, 460, 1266, 490, 374, 460, 1268, + 464, 400, 460, 406, 460, 1268, 464, 400, 458, 402, 462, 404, + 458, 404, 460, 1268, 460, 1268, 464, 400, 466, 1268, 456, 404, + 460, 1268, 460, 1268, 462, 402, 462, 1268, 462, 1266, 462, 402, + 462, 1268, 462, 1266, 488, 1242, 462, 1264, 460, 1270, 462, 1266, + 464, 1264, 462, 1270, 460, 402, 462, 402, 462, 400, 460, 402, + 462, 402, 462, 400, 462, 400, 460, 402, 462, 1266, 462, 1266, + 460, 1270, 462, 1268, 462, 1266, 460, 1268, 462, 1268, 462, 1268, + 462, 400, 458, 404, 466, 396, 436, 428, 460, 402, 460, 404, + 460, 402, 436, 428, + 462, 10794, + 3520, 1682, + 490, 376, 460, 402, 462, 402, 462, 1266, 462, 400, 462, 1268, + 460, 402, 460, 400, 462, 1266, 464, 400, 460, 402, 488, 378, + 456, 384, 482, 1268, 460, 1268, 462, 402, 460, 1268, 460, 404, + 460, 1268, 436, 1276, 480, 404, 456, 404, 460, 1268, 462, 1268, + 460, 1268, 462, 1270, 462, 1268, 462, 1268, 462, 1266, 460, 1268, + 462, 1268, 462, 1268, 462, 400, 462, 384, 478, 404, 460, 384, + 480, 400, 488, 376, 460, 404, 458, 404, 460, 1268, 464, 1264, + 462, 1268, 462, 1268, 462, 1270, 462, 1268, 486, 1244, 460, 1266, + 462, 400, 462, 400, 462, 402, 460, 404, 460, 400, 460, 404, + 486, 374, 462, 400, + 464}; // UNKNOWN A37A38D7 * Off + const uint8_t expectedState_Off[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x27, 0xD8, + 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_Off, 347, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState_Off, irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: Off, Power Button: On, Mode: 0 (Heat), Temp: 23C, " + "Fan: 1 (Low), Swing(V) Toggle: Off, Econo: On, " + "On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + + + const uint16_t rawData_17C[347] = { + 3522, 1686, + 458, 404, 486, 374, 434, 432, 482, 1244, 462, 400, 460, 1268, + 462, 400, 462, 386, 478, 1268, 462, 402, 462, 404, 458, 400, + 464, 400, 462, 1272, 456, 1268, 460, 402, 460, 1270, 434, 428, + 462, 1268, 460, 1268, 464, 1268, 460, 1266, 462, 402, 460, 382, + 482, 1264, 464, 400, 462, 402, 460, 1268, 460, 1270, 462, 404, + 460, 400, 460, 402, 462, 382, 506, 1242, 462, 1268, 464, 398, + 460, 398, 466, 1268, 458, 1268, 462, 1266, 462, 1266, 462, 402, + 458, 406, 460, 402, 460, 1270, 460, 406, 432, 428, 462, 402, + 438, 424, 460, 1268, 462, 1270, 460, 1266, 462, 402, 462, 1266, + 462, 1270, 460, 1268, + 438, 10814, + 3522, 1684, + 462, 402, 464, 402, 460, 400, 462, 1266, 462, 400, 462, 1266, + 466, 398, 462, 402, 460, 1270, 460, 384, 478, 402, 434, 428, + 462, 402, 516, 1212, 436, 1294, 460, 402, 460, 1268, 464, 400, + 460, 1268, 462, 1268, 434, 428, 462, 1266, 462, 1266, 462, 400, + 460, 1270, 462, 1268, 458, 1268, 436, 1274, 480, 1268, 460, 1266, + 490, 1240, 462, 1268, 460, 404, 460, 402, 488, 376, 462, 402, + 460, 402, 492, 370, 462, 400, 464, 402, 458, 1268, 490, 1240, + 460, 1268, 464, 1266, 462, 1266, 460, 1272, 460, 1266, 462, 1266, + 464, 400, 462, 404, 462, 400, 462, 402, 458, 384, 480, 402, + 458, 402, 460, 402, + 464, 10810, + 3528, 1660, + 490, 374, 462, 404, 458, 400, 462, 1268, 460, 404, 460, 1270, + 458, 402, 460, 402, 462, 1266, 486, 378, 460, 382, 506, 376, + 458, 404, 460, 1270, 460, 1270, 460, 402, 460, 1268, 464, 402, + 456, 1268, 462, 1268, 462, 402, 460, 402, 462, 1266, 462, 1266, + 464, 1266, 460, 1272, 460, 1266, 464, 1266, 462, 1266, 462, 1268, + 462, 1266, 462, 1268, 462, 402, 460, 404, 462, 402, 512, 352, + 512, 346, 438, 426, 462, 402, 460, 400, 462, 1268, 462, 1268, + 462, 1268, 460, 1270, 434, 1292, 464, 1266, 462, 1268, 460, 1270, + 514, 350, 432, 430, 460, 402, 460, 404, 460, 384, 480, 400, + 490, 374, 458, 404, + 462}; // UNKNOWN 8CC3C997 * 17C + const uint8_t expectedState_17C[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x11, 0xEE, + 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_17C, 347, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState_17C, irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 0 (Heat), Temp: 17C, " + "Fan: 1 (Low), Swing(V) Toggle: Off, Econo: On, " + "On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + + + const uint16_t rawData_18C[347] = { + 3520, 1686, + 462, 400, 460, 402, 436, 426, 488, 1242, 460, 402, 460, 1270, + 460, 404, 462, 398, 462, 1268, 462, 402, 462, 402, 436, 326, + 536, 430, 458, 1266, 462, 1268, 486, 380, 456, 1270, 462, 400, + 462, 1268, 462, 1266, 490, 1240, 438, 1292, 462, 404, 462, 400, + 462, 1266, 460, 404, 458, 404, 484, 1244, 466, 1264, 460, 402, + 436, 430, 458, 400, 436, 426, 460, 1268, 462, 1268, 438, 426, + 434, 428, 462, 1268, 462, 1266, 464, 1266, 462, 428, 436, 1268, + 436, 406, 480, 402, 462, 1270, 458, 404, 460, 402, 488, 374, + 464, 1246, 480, 400, 436, 1292, 488, 1242, 462, 402, 460, 1268, + 462, 1250, 480, 1268, + 462, 10790, + 3520, 1684, + 464, 402, 460, 404, 462, 398, 462, 1266, 464, 400, 462, 1270, + 460, 402, 458, 406, 456, 1268, 436, 424, 464, 400, 460, 404, + 462, 400, 462, 1268, 462, 1268, 464, 398, 488, 1238, 464, 400, + 462, 1268, 462, 1248, 478, 384, 482, 1264, 436, 1292, 462, 402, + 462, 1266, 464, 1266, 460, 1268, 464, 1268, 462, 1266, 462, 1266, + 464, 1266, 462, 1268, 462, 402, 486, 376, 464, 398, 460, 404, + 462, 402, 436, 426, 462, 428, 408, 428, 460, 1268, 460, 1268, + 436, 1290, 466, 1264, 464, 1266, 460, 1270, 462, 1264, 462, 1268, + 460, 404, 462, 402, 460, 400, 462, 404, 458, 404, 460, 404, + 460, 382, 482, 400, + 460, 10812, + 3480, 1706, + 464, 402, 482, 376, 460, 404, 458, 1270, 462, 402, 462, 1268, + 462, 400, 460, 402, 462, 1268, 462, 400, 462, 400, 464, 400, + 436, 426, 436, 1294, 462, 1268, 462, 402, 516, 1212, 462, 402, + 464, 1266, 460, 1266, 438, 428, 460, 402, 460, 1268, 462, 1268, + 488, 1242, 462, 1264, 460, 1270, 462, 1266, 462, 1266, 462, 1268, + 462, 1268, 460, 1270, 462, 400, 462, 402, 460, 400, 462, 400, + 488, 378, 458, 402, 462, 400, 516, 348, 460, 1268, 436, 1276, + 478, 1268, 436, 1292, 462, 1270, 460, 1268, 462, 1248, 484, 1266, + 460, 400, 464, 402, 460, 404, 432, 426, 436, 430, 462, 400, + 432, 428, 434, 426, + 464}; // UNKNOWN 513BFA3A * 18C + const uint8_t expectedState_18C[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x12, 0xED, + 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_18C, 347, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState_18C, irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 0 (Heat), Temp: 18C, " + "Fan: 1 (Low), Swing(V) Toggle: Off, Econo: On, " + "On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + + + const uint16_t rawData_19C[347] = { + 3508, 1682, + 490, 350, 488, 372, 514, 372, 466, 1262, 468, 398, 464, 1262, + 466, 396, 466, 396, 496, 1234, 442, 400, 488, 396, 470, 396, + 464, 396, 466, 1262, 468, 1260, 466, 396, 468, 1262, 466, 396, + 520, 1210, 474, 1254, 470, 1260, 466, 1266, 464, 396, 494, 368, + 468, 1260, 468, 364, 498, 396, 466, 1264, 470, 1260, 466, 394, + 466, 398, 468, 392, 494, 370, 466, 1262, 524, 1206, 466, 398, + 466, 396, 520, 1210, 492, 1238, 464, 1268, 466, 1260, 492, 1236, + 494, 350, 484, 398, 466, 1262, 468, 1264, 466, 396, 468, 396, + 492, 350, 486, 398, 466, 1262, 494, 1236, 466, 394, 468, 396, + 492, 1236, 494, 1236, + 466, 10804, + 3508, 1680, + 466, 292, 572, 396, 464, 396, 466, 1262, 466, 398, 466, 1264, + 468, 374, 488, 296, 568, 1262, 464, 396, 524, 288, 520, 396, + 468, 396, 492, 1234, 466, 1266, 464, 398, 464, 1262, 468, 398, + 492, 1234, 468, 1262, 466, 396, 442, 1286, 468, 1264, 466, 394, + 468, 1264, 518, 1210, 492, 1238, 466, 1264, 520, 1206, 468, 1262, + 468, 1260, 472, 1260, 466, 394, 468, 396, 494, 348, 488, 376, + 484, 396, 470, 396, 464, 396, 494, 346, 492, 1260, 468, 1262, + 468, 1262, 492, 1236, 494, 1236, 492, 1236, 466, 1262, 468, 1262, + 468, 394, 466, 398, 492, 370, 466, 396, 468, 394, 496, 368, + 492, 370, 466, 398, + 490, 10780, + 3510, 1680, + 468, 374, 486, 396, 494, 348, 486, 1264, 492, 368, 492, 1236, + 468, 398, 466, 394, 468, 1262, 464, 304, 536, 402, 512, 370, + 492, 370, 492, 1236, 468, 1262, 468, 394, 492, 1238, 466, 398, + 466, 1264, 468, 1262, 490, 372, 492, 290, 546, 1262, 522, 1208, + 466, 1264, 466, 1264, 468, 1258, 494, 1236, 468, 1264, 466, 1264, + 520, 1208, 494, 1238, 494, 370, 466, 396, 464, 396, 520, 292, + 518, 394, 468, 398, 464, 376, 490, 394, 468, 1264, 464, 1264, + 466, 1260, 466, 1264, 496, 1232, 466, 1262, 468, 1262, 466, 1264, + 466, 396, 492, 372, 468, 374, 486, 398, 464, 396, 468, 398, + 464, 398, 466, 396, + 464}; // CORONA_AC * On 19C + const uint8_t expectedState_19C[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x33, 0xCC, + 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_19C, 347, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState_19C, irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: On, Power Button: On, Mode: 0 (Heat), Temp: 19C, " + "Fan: 1 (Low), Swing(V) Toggle: Off, Econo: On, " + "On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + + + const uint16_t rawData_20C[347] = { + 3522, 1684, + 466, 398, 462, 402, 462, 382, 480, 1266, 460, 404, 462, 1266, + 464, 400, 464, 398, 462, 1268, 462, 400, 462, 404, 460, 402, + 458, 402, 466, 1266, 434, 1292, 462, 402, 460, 1268, 460, 386, + 478, 1266, 462, 1268, 460, 1268, 460, 1268, 462, 404, 460, 402, + 462, 1266, 462, 384, 480, 404, 460, 1268, 436, 1294, 460, 402, + 462, 400, 464, 402, 456, 406, 460, 1268, 464, 1264, 468, 398, + 460, 402, 460, 1270, 488, 1240, 460, 1270, 434, 430, 458, 402, + 458, 1270, 462, 402, 462, 1268, 462, 400, 462, 400, 462, 402, + 462, 1266, 464, 1264, 462, 404, 432, 1296, 438, 426, 462, 1268, + 458, 1270, 460, 1268, + 464, 10788, + 3518, 1686, + 488, 376, 462, 400, 462, 402, 460, 1268, 436, 426, 438, 1292, + 462, 402, 518, 344, 462, 1266, 462, 400, 460, 402, 436, 428, + 460, 402, 458, 1268, 438, 1292, 438, 424, 464, 1266, 460, 404, + 460, 1266, 462, 1268, 462, 400, 462, 1268, 462, 1266, 462, 400, + 462, 1268, 462, 1268, 464, 1264, 462, 1266, 460, 1270, 486, 1242, + 462, 1268, 436, 1294, 508, 292, 526, 400, 462, 402, 460, 402, + 488, 374, 462, 404, 436, 424, 462, 402, 438, 1292, 460, 1266, + 462, 1268, 460, 1266, 464, 1268, 460, 1268, 436, 1294, 490, 1240, + 434, 428, 438, 424, 460, 404, 436, 426, 462, 404, 484, 374, + 462, 404, 462, 400, + 460, 10792, + 3546, 1658, + 436, 430, 460, 400, 462, 404, 460, 1266, 462, 402, 438, 1292, + 462, 402, 458, 404, 436, 1290, 494, 374, 460, 402, 460, 402, + 462, 398, 436, 1292, 462, 1268, 462, 402, 436, 1290, 464, 400, + 462, 1266, 438, 1292, 462, 402, 490, 374, 434, 1296, 432, 1298, + 432, 1292, 464, 1266, 460, 1268, 462, 1268, 490, 1240, 436, 1292, + 464, 1266, 438, 1290, 462, 402, 436, 426, 462, 400, 460, 402, + 460, 402, 436, 426, 488, 374, 436, 428, 460, 1270, 462, 1268, + 462, 1268, 436, 1292, 462, 1266, 462, 1268, 460, 1266, 462, 1268, + 460, 406, 458, 402, 462, 402, 436, 408, 482, 400, 438, 426, + 434, 428, 460, 404, + 434}; // UNKNOWN 48F17976 * 20C + const uint8_t expectedState_20C[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x14, 0xEB, + 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_20C, 347, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState_20C, irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 0 (Heat), Temp: 20C, " + "Fan: 1 (Low), Swing(V) Toggle: Off, Econo: On, " + "On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + + + const uint16_t rawData_21C[347] = { + 3522, 1684, + 434, 430, 430, 412, 460, 418, 462, 1268, 460, 386, 452, 1296, + 460, 426, 432, 386, 480, 1268, 458, 404, 432, 430, 434, 428, + 434, 428, 460, 1266, 490, 1240, 462, 402, 460, 1268, 460, 386, + 452, 1296, 458, 1272, 460, 1266, 462, 1270, 460, 404, 434, 428, + 458, 1270, 434, 430, 432, 430, 460, 1268, 462, 1270, 458, 430, + 406, 432, 456, 404, 458, 404, 466, 1262, 460, 1270, 458, 406, + 456, 406, 458, 1268, 460, 1270, 488, 1240, 490, 1240, 460, 384, + 478, 1268, 436, 430, 432, 1294, 462, 384, 450, 456, 432, 404, + 436, 430, 458, 1270, 434, 430, 460, 1268, 460, 404, 464, 1264, + 460, 1268, 460, 1270, + 460, 10808, + 3504, 1682, + 462, 402, 460, 430, 430, 406, 460, 1268, 462, 428, 436, 1268, + 434, 432, 458, 404, 458, 1272, 458, 426, 432, 406, 460, 404, + 460, 428, 406, 1296, 462, 1268, 434, 454, 408, 1278, 480, 426, + 408, 1294, 460, 1268, 460, 404, 432, 1294, 462, 1268, 458, 384, + 480, 1272, 460, 1266, 460, 1270, 460, 1268, 462, 1266, 462, 1268, + 460, 1268, 462, 1268, 436, 428, 436, 428, 464, 424, 434, 386, + 478, 428, 434, 406, 432, 410, 478, 386, 476, 1270, 462, 1270, + 462, 1266, 460, 1270, 458, 1272, 458, 1270, 436, 1292, 464, 1266, + 434, 430, 460, 428, 408, 430, 458, 404, 484, 378, 432, 430, + 460, 404, 458, 406, + 458, 10796, + 3542, 1662, + 460, 402, 434, 456, 430, 406, 458, 1270, 458, 408, 432, 1294, + 462, 382, 480, 384, 450, 1296, 488, 374, 458, 406, 432, 430, + 432, 456, 432, 1270, 436, 1292, 462, 402, 434, 1294, 434, 428, + 460, 1268, 460, 1270, 458, 402, 464, 400, 462, 1266, 460, 1270, + 460, 1270, 434, 1294, 464, 1268, 486, 1242, 464, 1266, 460, 1270, + 486, 1244, 458, 1268, 464, 402, 458, 402, 460, 404, 434, 452, + 410, 428, 432, 432, 456, 432, 408, 426, 462, 1268, 462, 1268, + 434, 1296, 462, 1268, 458, 1270, 466, 1262, 464, 1272, 456, 1268, + 460, 406, 458, 402, 460, 404, 460, 404, 460, 402, 458, 430, + 430, 386, 480, 402, + 460}; // UNKNOWN D1869C5B * 21C + const uint8_t expectedState_21C[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x15, 0xEA, + 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_21C, 347, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState_21C, irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 0 (Heat), Temp: 21C, " + "Fan: 1 (Low), Swing(V) Toggle: Off, Econo: On, " + "On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + + + const uint16_t rawData_22C[347] = { + 3524, 1686, + 460, 404, 458, 402, 462, 400, 462, 1248, 482, 400, 460, 1268, + 436, 428, 488, 374, 460, 1268, 460, 404, 460, 402, 462, 402, + 460, 402, 462, 1268, 458, 1270, 458, 404, 460, 1248, 480, 402, + 462, 1268, 436, 1292, 462, 1270, 460, 1268, 462, 400, 460, 402, + 462, 1266, 460, 404, 436, 428, 462, 1266, 462, 1268, 460, 402, + 462, 402, 460, 404, 434, 428, 462, 1266, 438, 1290, 462, 404, + 460, 404, 434, 1292, 466, 1266, 436, 1294, 462, 400, 462, 1268, + 436, 1294, 460, 402, 462, 1268, 436, 426, 492, 374, 458, 400, + 464, 1266, 462, 400, 436, 428, 460, 1266, 492, 372, 462, 1268, + 460, 1268, 462, 1268, + 488, 10762, + 3496, 1710, + 462, 400, 462, 400, 460, 402, 460, 1270, 434, 426, 462, 1268, + 460, 400, 438, 424, 438, 1292, 436, 426, 460, 402, 436, 426, + 438, 426, 460, 1268, 464, 1266, 462, 400, 462, 1268, 464, 400, + 434, 1294, 464, 1268, 488, 372, 462, 1268, 464, 1264, 436, 426, + 490, 1240, 438, 1292, 464, 1264, 460, 1270, 436, 1294, 460, 1268, + 434, 1294, 462, 1266, 438, 426, 460, 402, 462, 400, 462, 402, + 462, 400, 460, 402, 462, 402, 460, 382, 482, 1268, 436, 1294, + 462, 1266, 436, 1294, 460, 1268, 438, 1290, 462, 1268, 462, 1268, + 462, 400, 462, 400, 464, 400, 462, 402, 462, 400, 488, 372, + 492, 372, 460, 402, + 460, 10810, + 3528, 1660, + 462, 404, 434, 426, 464, 400, 434, 1294, 462, 400, 464, 1266, + 462, 400, 464, 398, 466, 1264, 462, 402, 460, 402, 464, 398, + 464, 398, 462, 1268, 462, 1266, 440, 422, 462, 1268, 462, 404, + 462, 1264, 436, 1294, 460, 402, 462, 400, 438, 1292, 464, 1266, + 460, 1268, 462, 1266, 464, 1268, 462, 1266, 462, 1266, 462, 1266, + 438, 1292, 464, 1266, 460, 400, 462, 384, 480, 402, 460, 404, + 434, 428, 462, 402, 434, 428, 460, 402, 458, 1270, 462, 1266, + 464, 1266, 464, 1266, 464, 1264, 464, 1266, 462, 1246, 484, 1266, + 438, 424, 438, 424, 462, 402, 462, 400, 438, 424, 460, 402, + 462, 400, 436, 428, + 434}; // UNKNOWN 21DD90BB * 22C + const uint8_t expectedState_22C[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x16, 0xE9, + 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_22C, 347, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState_22C, irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 0 (Heat), Temp: 22C, " + "Fan: 1 (Low), Swing(V) Toggle: Off, Econo: On, " + "On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + + + const uint16_t rawData_23C[347] = { + 3522, 1684, + 460, 402, 462, 428, 406, 430, 458, 1270, 462, 400, 460, 1268, + 462, 402, 462, 402, 462, 1266, 462, 404, 432, 428, 434, 428, + 462, 402, 458, 1266, 464, 1268, 458, 402, 516, 1216, 460, 404, + 458, 1268, 462, 1268, 462, 1266, 462, 1266, 462, 402, 460, 406, + 456, 1268, 462, 402, 460, 402, 462, 1268, 462, 1266, 462, 402, + 460, 402, 488, 374, 490, 398, 434, 1270, 460, 1268, 460, 404, + 460, 430, 408, 1292, 462, 1268, 462, 1266, 462, 1268, 460, 1250, + 506, 1242, 462, 400, 460, 1268, 462, 400, 460, 408, 456, 404, + 458, 404, 460, 398, 462, 404, 458, 1268, 434, 430, 460, 1268, + 462, 1266, 462, 1268, + 464, 10790, + 3520, 1682, + 464, 402, 460, 428, 406, 430, 458, 1270, 462, 402, 460, 1268, + 462, 406, 488, 374, 430, 1296, 460, 402, 462, 402, 462, 400, + 462, 402, 458, 1268, 490, 1242, 460, 402, 460, 1272, 460, 400, + 460, 1268, 462, 1266, 462, 404, 462, 1264, 462, 1266, 490, 374, + 464, 1268, 458, 1268, 492, 1236, 462, 1266, 464, 1264, 462, 1250, + 478, 1266, 462, 1268, 462, 402, 460, 384, 478, 402, 434, 428, + 460, 404, 460, 402, 462, 400, 460, 430, 430, 1270, 490, 1240, + 460, 1268, 462, 1268, 460, 1272, 460, 1268, 436, 1294, 462, 1264, + 464, 400, 460, 386, 504, 400, 434, 404, 460, 402, 462, 384, + 476, 384, 454, 426, + 462, 10792, + 3548, 1656, + 462, 404, 460, 400, 516, 350, 458, 1268, 462, 400, 434, 1294, + 464, 424, 434, 382, 480, 1270, 462, 406, 454, 406, 458, 402, + 462, 402, 434, 1294, 514, 1216, 462, 400, 434, 1298, 458, 404, + 460, 1268, 460, 1270, 460, 402, 464, 398, 460, 1268, 464, 1266, + 436, 1294, 460, 1268, 460, 1270, 462, 1264, 436, 1292, 462, 1268, + 436, 1294, 460, 1268, 460, 402, 460, 402, 486, 376, 462, 402, + 460, 402, 462, 428, 408, 430, 464, 426, 430, 1272, 460, 1270, + 462, 1268, 434, 1292, 462, 1268, 464, 1266, 464, 1268, 462, 1266, + 464, 402, 458, 432, 434, 402, 434, 430, 488, 398, 410, 428, + 460, 402, 460, 428, + 410}; // UNKNOWN F68FE737 * 23C + const uint8_t expectedState_23C[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x17, 0xE8, + 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_23C, 347, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState_23C, irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 0 (Heat), Temp: 23C, " + "Fan: 1 (Low), Swing(V) Toggle: Off, Econo: On, " + "On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + + + const uint16_t rawData_24C[347] = { + 3522, 1686, + 460, 428, 406, 454, 410, 454, 432, 1272, 458, 432, 432, 1270, + 434, 454, 436, 424, 436, 1270, 458, 388, 474, 432, 406, 458, + 432, 384, 452, 1296, 434, 1294, 458, 428, 436, 1270, 432, 412, + 476, 1270, 456, 1272, 434, 1292, 462, 1296, 434, 428, 410, 454, + 408, 1320, 434, 428, 432, 432, 408, 1296, 434, 1320, 408, 454, + 410, 454, 434, 428, 408, 454, 436, 1268, 436, 1296, 442, 418, + 464, 384, 450, 1298, 458, 1296, 408, 1296, 462, 424, 434, 428, + 434, 430, 406, 1322, 434, 1270, 460, 384, 452, 412, 474, 430, + 434, 1296, 432, 1272, 436, 1320, 434, 428, 434, 430, 434, 1298, + 430, 1294, 464, 1266, + 410, 10816, + 3516, 1716, + 408, 454, 412, 450, 408, 454, 408, 1322, 432, 430, 434, 1296, + 406, 456, 408, 454, 434, 1296, 408, 454, 434, 430, 408, 452, + 408, 454, 410, 1294, 434, 1296, 460, 428, 436, 1270, 458, 430, + 408, 1296, 462, 1292, 434, 430, 408, 1322, 408, 1322, 434, 430, + 432, 1270, 438, 1322, 406, 1322, 432, 1272, 434, 1294, 436, 1318, + 408, 1324, 406, 1296, 450, 394, 480, 428, 432, 388, 450, 456, + 408, 454, 432, 430, 408, 454, 408, 456, 432, 1274, 486, 1240, + 434, 1296, 436, 1292, 458, 1270, 460, 1268, 462, 1270, 458, 1270, + 438, 450, 434, 430, 434, 428, 410, 452, 434, 430, 434, 384, + 476, 430, 432, 406, + 432, 10822, + 3516, 1690, + 456, 386, 480, 430, 428, 430, 434, 1272, 456, 430, 408, 1296, + 458, 426, 410, 454, 408, 1294, 464, 426, 434, 430, 412, 450, + 436, 428, 406, 1324, 434, 1294, 432, 408, 456, 1272, 458, 384, + 506, 1242, 458, 1272, 458, 430, 434, 428, 432, 1296, 408, 1296, + 458, 1272, 456, 1272, 460, 1292, 434, 1270, 462, 1294, 434, 1298, + 430, 1272, 460, 1294, 406, 454, 434, 430, 432, 430, 432, 430, + 410, 454, 406, 456, 408, 456, 432, 428, 436, 1270, 458, 1296, + 434, 1294, 436, 1294, 406, 1322, 410, 1294, 460, 1294, 432, 1298, + 432, 430, 408, 456, 406, 414, 476, 430, 434, 428, 434, 428, + 436, 426, 410, 454, + 434}; // UNKNOWN 914A12BF * 24C + const uint8_t expectedState_24C[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x18, 0xE7, + 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_24C, 347, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState_24C, irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 0 (Heat), Temp: 24C, " + "Fan: 1 (Low), Swing(V) Toggle: Off, Econo: On, " + "On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + + + const uint16_t rawData_25C[347] = { + 3518, 1690, + 458, 426, 436, 384, 478, 432, 432, 1270, 460, 384, 480, 1268, + 458, 386, 452, 430, 432, 1294, 462, 428, 434, 404, 458, 432, + 432, 428, 436, 1268, 458, 1270, 458, 386, 454, 1294, 486, 360, + 480, 1268, 436, 1296, 460, 1270, 434, 1294, 460, 430, 408, 454, + 436, 1268, 434, 454, 406, 456, 408, 1276, 480, 1268, 460, 428, + 410, 426, 460, 430, 430, 406, 462, 1266, 460, 1274, 430, 456, + 434, 384, 450, 1296, 460, 1268, 434, 1298, 460, 1266, 460, 386, + 510, 350, 452, 1296, 434, 1296, 486, 404, 434, 424, 436, 426, + 434, 432, 430, 1298, 408, 1296, 434, 454, 408, 454, 434, 1270, + 434, 1296, 432, 1296, + 434, 10816, + 3516, 1690, + 458, 426, 408, 458, 432, 388, 476, 1296, 434, 428, 458, 1244, + 462, 430, 406, 430, 460, 1270, 458, 386, 476, 384, 476, 386, + 478, 386, 450, 1296, 460, 1270, 460, 382, 478, 1270, 460, 426, + 410, 1294, 462, 1270, 434, 454, 434, 1270, 432, 1296, 458, 386, + 478, 1294, 432, 1272, 436, 1294, 460, 1272, 432, 1298, 434, 1294, + 462, 1250, 452, 1298, 432, 432, 486, 400, 410, 454, 408, 414, + 476, 430, 430, 386, 476, 404, 460, 428, 410, 1296, 456, 1274, + 432, 1294, 460, 1250, 480, 1268, 436, 1292, 462, 1268, 488, 1242, + 458, 406, 482, 380, 458, 428, 408, 456, 414, 448, 410, 428, + 458, 430, 432, 404, + 434, 10822, + 3516, 1688, + 460, 428, 436, 424, 410, 428, 460, 1270, 460, 428, 410, 1276, + 478, 384, 476, 430, 408, 1296, 460, 432, 414, 418, 436, 454, + 434, 406, 456, 1270, 456, 1270, 462, 428, 408, 1298, 458, 430, + 406, 1296, 460, 1296, 408, 428, 460, 430, 432, 1268, 460, 1270, + 434, 1296, 432, 1294, 460, 1272, 432, 1298, 456, 1272, 460, 1268, + 460, 1270, 458, 1270, 460, 430, 432, 430, 434, 388, 476, 404, + 456, 430, 406, 458, 406, 456, 406, 412, 476, 1270, 460, 1270, + 460, 1270, 460, 1270, 434, 1294, 462, 1268, 460, 1296, 436, 1268, + 460, 428, 432, 430, 432, 430, 408, 440, 448, 388, 450, 452, + 410, 428, 460, 428, + 408}; // UNKNOWN 7A72A3B * 25C + const uint8_t expectedState_25C[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x19, 0xE6, + 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_25C, 347, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState_25C, irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 0 (Heat), Temp: 25C, " + "Fan: 1 (Low), Swing(V) Toggle: Off, Econo: On, " + "On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + + + const uint16_t rawData_26C[347] = { + 3516, 1668, + 480, 402, 458, 386, 504, 380, 458, 1266, 462, 402, 462, 1268, + 460, 402, 462, 402, 458, 1270, 460, 402, 462, 400, 486, 376, + 460, 404, 436, 1292, 460, 1268, 460, 404, 462, 1268, 460, 402, + 458, 1270, 460, 1268, 462, 1266, 436, 1294, 458, 404, 488, 358, + 480, 1268, 460, 402, 488, 374, 458, 1270, 462, 1266, 462, 404, + 462, 400, 460, 404, 486, 376, 460, 1268, 460, 1270, 462, 400, + 458, 404, 458, 1270, 460, 1270, 462, 1266, 462, 400, 460, 1270, + 462, 402, 460, 1268, 462, 1268, 460, 402, 462, 402, 460, 402, + 460, 1270, 460, 402, 460, 1268, 460, 402, 482, 380, 460, 1268, + 490, 1244, 462, 1264, + 460, 10792, + 3518, 1686, + 460, 402, 462, 402, 460, 402, 460, 1270, 470, 388, 466, 1268, + 462, 402, 460, 402, 462, 1266, 462, 402, 460, 402, 460, 384, + 480, 400, 488, 1242, 460, 1268, 462, 402, 462, 1266, 462, 402, + 460, 1270, 460, 1268, 462, 384, 482, 1266, 462, 1266, 462, 402, + 460, 1266, 462, 1270, 460, 1266, 462, 1268, 462, 1268, 460, 1270, + 462, 1268, 458, 1268, 462, 402, 460, 402, 458, 402, 464, 400, + 460, 402, 462, 402, 460, 402, 462, 402, 458, 1270, 462, 1268, + 460, 1268, 462, 1266, 462, 1268, 462, 1268, 458, 1270, 460, 1266, + 462, 402, 516, 346, 460, 404, 460, 402, 488, 376, 458, 404, + 460, 402, 460, 400, + 460, 10794, + 3520, 1684, + 464, 400, 462, 402, 460, 400, 462, 1268, 462, 402, 462, 1270, + 458, 402, 462, 402, 460, 1268, 462, 402, 460, 402, 460, 404, + 460, 402, 462, 1268, 462, 1268, 460, 384, 480, 1266, 462, 404, + 458, 1272, 458, 1268, 462, 402, 460, 402, 460, 1270, 460, 1268, + 462, 1268, 462, 1266, 464, 1266, 462, 1266, 462, 1268, 462, 1268, + 488, 1240, 486, 1242, 466, 400, 462, 402, 460, 400, 460, 404, + 462, 398, 486, 380, 458, 406, 458, 404, 458, 1268, 436, 1292, + 462, 1268, 462, 1268, 460, 1272, 460, 1268, 486, 1242, 460, 1270, + 462, 400, 460, 404, 436, 428, 464, 398, 460, 402, 462, 404, + 458, 404, 458, 404, + 458}; // UNKNOWN 881F925B * 26C + const uint8_t expectedState_26C[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x1A, 0xE5, + 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_26C, 347, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState_26C, irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 0 (Heat), Temp: 26C, " + "Fan: 1 (Low), Swing(V) Toggle: Off, Econo: On, " + "On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + + + const uint16_t rawData_30C[347] = { + 3520, 1688, + 462, 400, 460, 404, 460, 404, 456, 1270, 462, 402, 462, 1266, + 490, 374, 464, 398, 462, 1266, 464, 400, 460, 402, 490, 376, + 460, 402, 462, 1248, 478, 1268, 462, 382, 534, 1214, 462, 402, + 458, 1268, 464, 1266, 458, 1270, 462, 1266, 462, 400, 464, 400, + 464, 1264, 462, 406, 456, 402, 460, 1268, 462, 1266, 462, 404, + 460, 402, 462, 400, 462, 404, 458, 1270, 464, 1266, 460, 402, + 462, 402, 434, 1294, 462, 1248, 480, 1270, 490, 372, 462, 1272, + 456, 1268, 464, 1268, 458, 1268, 464, 400, 464, 400, 460, 402, + 462, 1268, 462, 398, 462, 402, 458, 404, 462, 400, 462, 1266, + 438, 1292, 462, 1270, + 460, 10790, + 3520, 1684, + 462, 402, 462, 402, 458, 404, 458, 1272, 462, 400, 460, 1270, + 462, 400, 436, 428, 484, 1244, 462, 380, 482, 402, 486, 376, + 490, 372, 462, 1266, 460, 1270, 462, 402, 460, 1268, 490, 372, + 460, 1270, 460, 1268, 488, 378, 458, 1268, 436, 1296, 488, 374, + 462, 1268, 434, 1292, 462, 1268, 460, 1268, 460, 1270, 436, 1292, + 460, 1268, 462, 1270, 456, 404, 460, 402, 464, 398, 460, 402, + 462, 402, 486, 374, 460, 402, 460, 404, 460, 1270, 460, 1268, + 460, 1268, 462, 1266, 460, 1268, 460, 1268, 462, 1268, 462, 1250, + 504, 376, 462, 400, 436, 428, 458, 404, 460, 400, 462, 406, + 458, 400, 460, 384, + 478, 10796, + 3570, 1632, + 464, 400, 458, 406, 456, 404, 486, 1242, 460, 384, 482, 1264, + 462, 402, 460, 402, 458, 1270, 462, 402, 462, 402, 460, 402, + 462, 400, 490, 1240, 486, 1242, 438, 424, 488, 1242, 462, 402, + 458, 1270, 462, 1266, 464, 400, 460, 404, 462, 1268, 458, 1270, + 462, 1266, 462, 1266, 462, 1270, 460, 1266, 462, 1268, 460, 1268, + 462, 1250, 478, 1268, 464, 400, 462, 404, 458, 400, 488, 378, + 458, 402, 488, 374, 462, 404, 512, 350, 460, 1270, 488, 1242, + 488, 1240, 462, 1266, 464, 1264, 490, 1240, 490, 1240, 462, 1266, + 462, 400, 462, 400, 460, 404, 460, 402, 462, 400, 460, 404, + 458, 382, 480, 402, + 462}; // UNKNOWN B0D0585F * 30C + const uint8_t expectedState_30C[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x1E, 0xE1, + 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_30C, 347, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState_30C, irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 0 (Heat), Temp: 30C, " + "Fan: 1 (Low), Swing(V) Toggle: Off, Econo: On, " + "On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); +} + +TEST(TestDecodeCoronaAc, RealExample2) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + const uint16_t rawData_TOn5[347] = { + 3520, 1684, + 436, 452, 410, 412, 476, 430, 434, 1294, 410, 454, 406, 1296, + 458, 430, 436, 424, 436, 1270, 434, 454, 408, 454, 410, 454, + 434, 428, 434, 1296, 436, 1270, 432, 454, 462, 1268, 434, 386, + 452, 1320, 434, 1270, 434, 1294, 458, 1272, 458, 428, 410, 452, + 436, 1268, 434, 412, 450, 454, 434, 1270, 458, 1274, 456, 388, + 476, 426, 410, 454, 408, 454, 410, 1318, 410, 1296, 458, 430, + 408, 412, 452, 1322, 430, 1298, 434, 1296, 434, 434, 428, 1272, + 458, 1296, 410, 1296, 460, 1294, 432, 430, 408, 452, 434, 430, + 408, 1296, 458, 386, 478, 428, 410, 454, 434, 428, 434, 1272, + 456, 1294, 432, 1272, + 458, 10794, + 3518, 1684, + 464, 426, 410, 454, 488, 374, 434, 1296, 436, 382, 452, 1320, + 436, 428, 406, 454, 410, 1296, 458, 384, 482, 384, 454, 450, + 434, 386, 478, 1268, 460, 1298, 404, 454, 434, 1270, 458, 430, + 410, 1292, 462, 1296, 436, 426, 436, 1270, 434, 1320, 430, 388, + 476, 384, 478, 386, 452, 454, 434, 1294, 412, 452, 432, 1270, + 434, 456, 406, 456, 410, 1292, 460, 1272, 460, 1266, 462, 428, + 434, 1294, 434, 430, 434, 1294, 434, 1272, 460, 1266, 464, 1292, + 438, 426, 434, 428, 408, 432, 460, 1294, 436, 384, 452, 454, + 410, 454, 436, 426, 436, 1270, 458, 1296, 410, 1322, 432, 430, + 434, 1294, 408, 1322, + 436, 10812, + 3478, 1736, + 406, 416, 472, 430, 410, 452, 410, 1322, 408, 454, 436, 1270, + 434, 454, 410, 408, 478, 1268, 460, 430, 434, 428, 408, 454, + 432, 406, 432, 1322, 432, 1296, 434, 430, 408, 1294, 458, 430, + 406, 1322, 434, 1272, 460, 426, 438, 426, 408, 1320, 408, 1296, + 460, 1270, 434, 1296, 434, 1322, 406, 1320, 434, 1252, 476, 1296, + 438, 1268, 432, 1296, 488, 400, 410, 410, 476, 430, 432, 386, + 452, 410, 458, 420, 488, 400, 436, 428, 434, 1294, 408, 1296, + 460, 1294, 410, 1296, 458, 1270, 432, 1298, 432, 1296, 434, 1296, + 460, 428, 408, 452, 462, 402, 432, 430, 406, 430, 438, 450, + 408, 454, 410, 454, + 412}; // UNKNOWN 96CCC404 * On Timer 5H 30C + const uint8_t expectedState_TOn5[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x1E, 0xE1, + 0x28, 0x61, 0x6D, 0x28, 0xD7, 0x23, 0xDC, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_TOn5, 347, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState_TOn5, + irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 0 (Heat), Temp: 30C, " + "Fan: 1 (Low), Swing(V) Toggle: Off, Econo: On, " + "On Timer: 05:00, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + + + const uint16_t rawData_TOn1[347] = { + 3522, 1684, + 462, 428, 434, 426, 434, 428, 408, 1296, 462, 424, 436, 1266, + 464, 402, 488, 400, 440, 1264, 460, 402, 434, 454, 434, 404, + 460, 404, 460, 1264, 464, 1268, 460, 404, 460, 1266, 462, 404, + 434, 1294, 436, 1292, 464, 1268, 460, 1268, 462, 402, 460, 402, + 458, 1268, 462, 404, 434, 452, 436, 1266, 462, 1268, 462, 402, + 462, 400, 462, 428, 436, 400, 460, 1266, 490, 1240, 492, 372, + 488, 376, 458, 1270, 486, 1242, 464, 1266, 460, 402, 462, 1266, + 464, 1268, 462, 1266, 464, 1270, 462, 396, 464, 400, 460, 402, + 436, 1292, 464, 402, 462, 400, 434, 428, 486, 378, 460, 1266, + 462, 1268, 460, 1266, + 464, 10804, + 3506, 1682, + 462, 402, 462, 400, 460, 428, 438, 1268, 460, 428, 462, 1242, + 460, 428, 436, 400, 462, 1268, 460, 428, 436, 400, 460, 430, + 466, 368, 464, 1266, 438, 1292, 462, 400, 462, 1268, 462, 426, + 410, 1296, 460, 1266, 464, 398, 490, 1242, 488, 1238, 462, 428, + 438, 424, 436, 400, 462, 404, 460, 1266, 462, 404, 460, 404, + 460, 402, 460, 402, 464, 1264, 464, 1264, 464, 1266, 488, 376, + 464, 1266, 458, 1268, 464, 1264, 462, 1266, 466, 1264, 488, 1244, + 462, 1262, 468, 422, 434, 402, 464, 402, 462, 400, 462, 424, + 438, 400, 462, 402, 462, 402, 486, 1242, 460, 1268, 464, 1264, + 436, 1292, 462, 1268, + 460, 10810, + 3504, 1684, + 462, 428, 436, 398, 492, 374, 460, 1268, 462, 404, 462, 1264, + 462, 404, 460, 400, 460, 1266, 490, 400, 438, 424, 438, 400, + 462, 428, 410, 1292, 464, 1268, 460, 428, 460, 1242, 464, 402, + 460, 1266, 460, 1270, 462, 426, 462, 402, 412, 1272, 482, 1266, + 436, 1292, 436, 1294, 462, 1268, 462, 1266, 464, 1264, 464, 1270, + 488, 1238, 464, 1266, 464, 396, 464, 426, 438, 402, 458, 402, + 464, 398, 462, 430, 408, 426, 460, 428, 492, 1210, 440, 1292, + 464, 1266, 438, 1292, 460, 1266, 464, 1266, 464, 1268, 460, 1266, + 438, 430, 458, 402, 458, 406, 460, 406, 456, 400, 434, 426, + 464, 400, 460, 402, + 462}; // UNKNOWN 446E2F48 * On Timer 1H 30C + const uint8_t expectedState_TOn1[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x1E, 0xE1, + 0x28, 0x61, 0x6D, 0x08, 0xF7, 0x07, 0xF8, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_TOn1, 347, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState_TOn1, + irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 0 (Heat), Temp: 30C, " + "Fan: 1 (Low), Swing(V) Toggle: Off, Econo: On, " + "On Timer: 01:00, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + + + const uint16_t rawData_TOn2[347] = { + 3516, 1716, + 410, 452, 408, 454, 412, 450, 434, 1270, 460, 430, 432, 1272, + 456, 406, 460, 384, 452, 1298, 458, 428, 406, 456, 436, 428, + 434, 430, 432, 1298, 434, 1298, 408, 428, 458, 1298, 432, 430, + 434, 1294, 434, 1296, 432, 1272, 458, 1296, 408, 454, 436, 428, + 436, 1268, 458, 430, 436, 428, 434, 1272, 432, 1320, 460, 402, + 410, 454, 432, 388, 474, 388, 452, 1296, 460, 1270, 458, 386, + 450, 412, 478, 1296, 430, 1272, 458, 1298, 434, 428, 434, 1254, + 474, 1296, 410, 1320, 434, 1270, 460, 384, 478, 428, 434, 428, + 434, 1272, 460, 384, 478, 428, 432, 430, 434, 428, 410, 1296, + 458, 1274, 454, 1270, + 460, 10810, + 3500, 1716, + 432, 430, 408, 452, 434, 430, 410, 1294, 456, 428, 434, 1298, + 408, 432, 544, 314, 462, 1270, 430, 454, 436, 430, 458, 404, + 432, 386, 478, 1268, 460, 1270, 458, 388, 450, 1322, 430, 434, + 458, 1268, 434, 1294, 410, 454, 434, 1270, 460, 1294, 432, 430, + 410, 454, 434, 428, 406, 456, 432, 430, 408, 1320, 408, 456, + 432, 430, 434, 428, 410, 1294, 434, 1294, 486, 1268, 432, 1272, + 460, 426, 414, 1292, 462, 1294, 432, 1298, 430, 388, 478, 1296, + 408, 1296, 458, 1270, 458, 386, 452, 456, 408, 454, 436, 426, + 434, 1272, 432, 430, 458, 430, 434, 430, 406, 1320, 436, 1294, + 434, 1296, 410, 1320, + 434, 10812, + 3504, 1686, + 432, 452, 434, 430, 436, 428, 406, 1296, 460, 404, 460, 1292, + 436, 428, 436, 428, 436, 1268, 436, 454, 412, 452, 408, 454, + 434, 428, 408, 1296, 462, 1266, 462, 384, 480, 1266, 458, 430, + 410, 1320, 434, 1270, 434, 428, 436, 452, 412, 1294, 432, 1320, + 432, 1274, 458, 1270, 434, 1294, 460, 1270, 460, 1296, 434, 1268, + 436, 1294, 434, 1296, 460, 430, 434, 424, 436, 428, 434, 426, + 410, 410, 478, 430, 432, 408, 456, 428, 408, 1298, 458, 1268, + 436, 1296, 460, 1292, 462, 1268, 436, 1270, 460, 1294, 434, 1294, + 436, 402, 488, 400, 408, 456, 432, 386, 478, 428, 408, 452, + 408, 456, 410, 454, + 406}; // UNKNOWN D49AF170 * On Timer 2H 30C + const uint8_t expectedState_TOn2[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x1E, 0xE1, + 0x28, 0x61, 0x6D, 0x10, 0xEF, 0x0E, 0xF1, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_TOn2, 347, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState_TOn2, + irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 0 (Heat), Temp: 30C, " + "Fan: 1 (Low), Swing(V) Toggle: Off, Econo: On, " + "On Timer: 02:00, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + + + const uint16_t rawData_21C2[347] = { + 3522, 1682, + 438, 426, 460, 402, 462, 402, 434, 1296, 434, 426, 460, 1270, + 436, 430, 460, 400, 436, 1294, 462, 398, 436, 428, 462, 400, + 462, 400, 438, 1292, 460, 1270, 460, 404, 434, 1294, 462, 402, + 462, 1268, 434, 1294, 462, 1268, 490, 1240, 462, 400, 460, 404, + 460, 1268, 436, 426, 462, 402, 462, 1266, 460, 1268, 438, 428, + 458, 404, 460, 402, 462, 398, 462, 1272, 460, 1266, 462, 404, + 458, 402, 436, 1294, 460, 1268, 436, 1292, 464, 1266, 436, 428, + 462, 1268, 462, 400, 438, 1290, 460, 404, 460, 402, 462, 404, + 434, 424, 462, 1268, 436, 426, 462, 1272, 456, 404, 460, 1270, + 434, 1292, 438, 1292, + 462, 10786, + 3498, 1714, + 458, 404, 458, 402, 462, 400, 464, 1264, 466, 398, 462, 1266, + 438, 428, 436, 424, 462, 1266, 490, 374, 436, 424, 436, 428, + 434, 426, 464, 1266, 464, 1268, 434, 428, 462, 1266, 466, 396, + 436, 1294, 462, 1270, 460, 402, 460, 1266, 462, 1268, 460, 404, + 458, 1270, 434, 1294, 460, 1268, 464, 1266, 462, 1266, 464, 1266, + 462, 1268, 462, 1266, 464, 400, 434, 426, 438, 426, 460, 402, + 436, 426, 464, 400, 470, 370, 486, 398, 464, 1264, 440, 1292, + 462, 1266, 464, 1266, 464, 1266, 462, 1266, 462, 1268, 460, 1270, + 462, 398, 462, 400, 438, 426, 462, 400, 462, 402, 434, 430, + 458, 402, 460, 400, + 436, 10820, + 3496, 1708, + 462, 402, 464, 400, 438, 422, 438, 1294, 460, 400, 462, 1266, + 464, 400, 462, 400, 464, 1266, 462, 402, 436, 426, 460, 404, + 436, 426, 462, 1266, 436, 1294, 462, 400, 462, 1266, 462, 400, + 460, 1268, 464, 1266, 462, 402, 436, 426, 436, 1294, 436, 1294, + 438, 1290, 462, 1268, 462, 1266, 436, 1292, 462, 1268, 460, 1248, + 482, 1268, 462, 1270, 458, 404, 434, 426, 464, 400, 460, 406, + 434, 426, 462, 402, 460, 384, 480, 400, 436, 1294, 460, 1268, + 492, 1238, 462, 1268, 460, 1272, 434, 1292, 462, 1266, 438, 1292, + 464, 400, 462, 400, 436, 426, 438, 424, 488, 374, 462, 402, + 462, 400, 464, 400, + 438}; // UNKNOWN D1869C5B * 21C + const uint8_t expectedState_21C2[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x15, 0xEA, + 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_21C2, 347, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState_21C2, + irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 0 (Heat), Temp: 21C, " + "Fan: 1 (Low), Swing(V) Toggle: Off, Econo: On, " + "On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + + + const uint16_t rawData_20C2[347] = { + 3498, 1708, + 436, 430, 434, 426, 464, 398, 460, 1268, 456, 388, 482, 1266, + 436, 426, 436, 426, 438, 1292, 436, 426, 436, 428, 436, 424, + 460, 404, 436, 1290, 438, 1292, 462, 404, 434, 1292, 438, 426, + 462, 1266, 516, 1212, 438, 1292, 436, 1292, 438, 424, 438, 424, + 462, 1268, 438, 424, 436, 426, 438, 1292, 460, 1268, 460, 402, + 436, 428, 436, 426, 438, 426, 434, 1294, 436, 1294, 436, 428, + 436, 426, 464, 1264, 436, 1274, 484, 1264, 440, 424, 460, 402, + 438, 1292, 434, 426, 438, 1292, 436, 428, 436, 426, 464, 398, + 492, 1238, 438, 1292, 436, 428, 460, 1248, 456, 426, 438, 1294, + 434, 1296, 434, 1296, + 434, 10812, + 3498, 1710, + 436, 428, 434, 426, 438, 424, 438, 1294, 438, 424, 438, 1292, + 434, 426, 442, 420, 438, 1290, 438, 426, 466, 396, 462, 400, + 436, 428, 436, 1294, 438, 1290, 466, 398, 436, 1294, 436, 426, + 460, 1268, 462, 1268, 436, 426, 438, 1290, 438, 1294, 462, 402, + 462, 1266, 462, 1266, 462, 1266, 436, 1294, 440, 1290, 464, 1266, + 436, 1292, 436, 1294, 436, 426, 462, 400, 438, 424, 436, 426, + 462, 400, 438, 426, 462, 400, 436, 426, 438, 1292, 438, 1292, + 438, 1292, 462, 1266, 438, 1270, 458, 1292, 438, 1294, 462, 1266, + 438, 428, 434, 426, 464, 398, 436, 426, 436, 428, 436, 426, + 492, 370, 438, 426, + 436, 10818, + 3492, 1712, + 462, 402, 460, 402, 438, 426, 440, 1292, 436, 424, 464, 1266, + 438, 424, 462, 400, 438, 1288, 438, 428, 434, 428, 486, 376, + 462, 402, 434, 1292, 436, 1292, 438, 424, 462, 1268, 436, 426, + 438, 1294, 462, 1266, 436, 428, 436, 424, 438, 1292, 438, 1290, + 440, 1292, 434, 1294, 436, 1294, 436, 1294, 514, 1212, 438, 1292, + 436, 1296, 458, 1268, 438, 424, 460, 404, 460, 400, 462, 400, + 462, 400, 438, 426, 434, 430, 434, 426, 466, 1266, 464, 1262, + 436, 1294, 434, 1294, 464, 1266, 464, 1264, 460, 1268, 464, 1266, + 462, 404, 460, 402, 436, 428, 434, 428, 436, 428, 462, 400, + 462, 400, 462, 400, + 464}; // UNKNOWN 27CBC9D7 * 20C + const uint8_t expectedState_20C2[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x14, 0xEB, + 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_20C2, 347, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState_20C2, + irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 0 (Heat), Temp: 20C, " + "Fan: 1 (Low), Swing(V) Toggle: Off, Econo: On, " + "On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + + + const uint16_t rawData_Off2[347] = { + 3522, 1684, + 436, 428, 460, 404, 436, 424, 464, 1266, 436, 426, 462, 1270, + 452, 390, 480, 404, 462, 1268, 436, 424, 462, 402, 462, 400, + 434, 428, 436, 1292, 462, 1268, 462, 402, 460, 1268, 460, 402, + 436, 1292, 462, 1266, 436, 1294, 438, 1292, 436, 426, 460, 402, + 462, 1268, 438, 424, 462, 400, 462, 1270, 458, 1270, 436, 428, + 458, 404, 460, 400, 436, 426, 464, 1268, 460, 1266, 464, 398, + 464, 398, 462, 1270, 434, 1292, 438, 1292, 460, 404, 436, 1296, + 458, 402, 462, 402, 460, 404, 460, 1268, 460, 402, 436, 426, + 434, 1274, 482, 400, 438, 1292, 490, 1240, 462, 1268, 460, 402, + 436, 1292, 438, 1294, + 460, 10808, + 3474, 1692, + 482, 400, 462, 402, 460, 402, 460, 1268, 464, 400, 488, 1240, + 462, 400, 462, 402, 460, 1270, 434, 426, 462, 402, 462, 402, + 462, 400, 462, 1268, 462, 1266, 462, 400, 436, 1294, 460, 402, + 436, 1292, 438, 1292, 436, 428, 460, 1268, 462, 1268, 436, 428, + 438, 1290, 466, 1266, 462, 1266, 464, 1266, 460, 1268, 462, 1268, + 436, 1292, 462, 1266, 452, 390, 482, 400, 436, 428, 462, 400, + 464, 400, 462, 402, 434, 428, 460, 402, 462, 1266, 462, 1266, + 462, 1270, 436, 1294, 460, 1268, 460, 1268, 438, 1296, 432, 1294, + 464, 398, 462, 402, 434, 430, 460, 400, 462, 400, 460, 402, + 460, 402, 438, 426, + 436, 10816, + 3522, 1686, + 436, 428, 434, 426, 464, 400, 460, 1270, 460, 400, 438, 1294, + 460, 400, 464, 400, 438, 1296, 436, 424, 460, 402, 460, 402, + 464, 400, 462, 1266, 438, 1292, 462, 402, 434, 1296, 432, 428, + 460, 1270, 462, 1266, 436, 428, 436, 428, 458, 1268, 438, 1290, + 438, 1292, 460, 1270, 434, 1294, 460, 1268, 462, 1246, 456, 1294, + 438, 1290, 460, 1268, 446, 388, 490, 400, 436, 426, 462, 400, + 438, 424, 462, 402, 436, 428, 434, 430, 460, 1270, 458, 1266, + 462, 1268, 438, 1292, 438, 1290, 436, 1294, 462, 1268, 462, 1266, + 460, 404, 434, 428, 460, 400, 462, 402, 436, 426, 434, 428, + 434, 426, 438, 430, + 458}; // UNKNOWN FBD27697 * OFF + const uint8_t expectedState_Off2[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x22, 0xDD, + 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_Off2, 347, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState_Off2, + irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: Off, Power Button: On, Mode: 0 (Heat), Temp: 18C, " + "Fan: 1 (Low), Swing(V) Toggle: Off, Econo: On, " + "On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + + + const uint16_t rawData_U[347] = { + 3520, 1686, + 462, 402, 460, 402, 462, 402, 436, 1276, 478, 402, 462, 1266, + 464, 400, 460, 402, 462, 1268, 452, 392, 478, 402, 464, 380, + 480, 404, 432, 1296, 462, 1266, 460, 404, 460, 1270, 460, 402, + 460, 1270, 458, 1270, 460, 1270, 456, 1270, 462, 402, 460, 402, + 460, 1270, 460, 400, 464, 400, 460, 1268, 464, 1264, 462, 404, + 458, 402, 434, 428, 464, 402, 456, 1270, 462, 1270, 460, 404, + 458, 402, 438, 1292, 460, 1268, 464, 1266, 464, 1264, 462, 404, + 458, 1272, 458, 1270, 460, 1268, 464, 402, 458, 402, 462, 400, + 462, 400, 462, 1270, 458, 406, 430, 430, 458, 400, 462, 1270, + 460, 1266, 464, 1266, + 462, 10790, + 3520, 1682, + 462, 404, 434, 428, 464, 400, 460, 1270, 460, 400, 464, 1266, + 462, 404, 460, 402, 464, 1264, 460, 406, 460, 402, 458, 406, + 460, 402, 458, 1270, 464, 1266, 460, 404, 460, 1270, 462, 402, + 488, 1240, 460, 1268, 462, 400, 462, 1268, 462, 1266, 462, 400, + 462, 1268, 460, 1250, 482, 1266, 462, 1270, 462, 1266, 462, 1268, + 458, 1270, 462, 1268, 460, 400, 462, 402, 460, 400, 462, 402, + 462, 398, 462, 404, 486, 374, 460, 404, 458, 1270, 460, 1270, + 486, 1244, 458, 1270, 464, 1266, 460, 1268, 462, 1268, 460, 1270, + 462, 400, 460, 406, 458, 402, 462, 400, 462, 404, 458, 400, + 516, 350, 458, 402, + 462, 10794, + 3520, 1684, + 460, 402, 460, 402, 460, 406, 460, 1268, 458, 406, 458, 1268, + 462, 400, 464, 400, 460, 1268, 462, 402, 460, 402, 464, 426, + 436, 400, 462, 1264, 462, 1270, 460, 402, 460, 1266, 464, 400, + 460, 1268, 464, 1266, 460, 406, 456, 404, 462, 1268, 462, 1268, + 460, 1266, 490, 1240, 464, 1266, 460, 1270, 438, 1294, 460, 1250, + 478, 1266, 462, 1270, 460, 404, 462, 400, 462, 400, 462, 402, + 462, 398, 460, 404, 460, 402, 460, 402, 460, 1268, 460, 1270, + 460, 1272, 458, 1270, 460, 1268, 464, 1268, 434, 1296, 462, 1266, + 464, 398, 462, 402, 434, 426, 462, 404, 460, 402, 462, 404, + 456, 406, 460, 400, + 462}; // UNKNOWN 2D1BA8F7 * unk + const uint8_t expectedState_U[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x1D, 0xE2, + 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_U, 347, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState_U, irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 0 (Heat), Temp: 29C, " + "Fan: 1 (Low), Swing(V) Toggle: Off, Econo: On, " + "On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); +} + +TEST(TestDecodeCoronaAc, RealExampleShort) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + const uint16_t rawData_A1[115] = { + 3548, 1658, + 462, 400, 464, 424, 436, 428, 436, 1272, 460, 400, 462, 1266, + 464, 426, 436, 426, 434, 1270, 432, 454, 436, 402, 460, 384, + 482, 400, 486, 1244, 460, 1268, 462, 404, 484, 1242, 460, 428, + 460, 1250, 430, 1292, 462, 1266, 464, 404, 456, 384, 480, 1266, + 462, 428, 436, 1270, 460, 1268, 462, 428, 434, 1270, 460, 430, + 434, 404, 460, 1294, 460, 1242, 462, 382, 478, 428, 436, 1268, + 458, 406, 460, 1268, 460, 1268, 460, 404, 458, 404, 434, 430, + 462, 426, 434, 430, 432, 1268, 462, 426, 436, 402, 460, 404, + 458, 1268, 464, 1270, 432, 1294, 464, 1266, 458, 404, 462, 1268, + 460, 1268, 464, 1266, + 462}; // UNKNOWN AEDD5409 * Auto1 + const uint8_t expectedState_A1[kCoronaAcStateLengthShort] = { + 0x28, 0x61, 0x9D, 0x96, 0x69, 0x10, 0xEF}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_A1, 115, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBitsShort, irsend.capture.bits); + EXPECT_STATE_EQ(expectedState_A1, irsend.capture.state, irsend.capture.bits); + // this is special, but showing what it might be + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 0 (Heat), Temp: 16C, " + "Fan: 2 (Medium), Swing(V) Toggle: Off, Econo: Off, " + "On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); +} + +TEST(TestDecodeCoronaAc, SyntheticExample1) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + irsend.begin(); + irsend.reset(); + const uint8_t state[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x1D, 0xE2, + 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.sendCoronaAc(state); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + EXPECT_EQ(kCoronaAcBits, irsend.capture.bits); + EXPECT_STATE_EQ(state, irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 0 (Heat), Temp: 29C, " + "Fan: 1 (Low), Swing(V) Toggle: Off, Econo: On, " + "On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + + EXPECT_EQ( + "f38000d50" + "m3500s1680" + "m450s420m450s420m450s420m450s1270m450s420m450s1270m450s420m450s420" + "m450s1270m450s420m450s420m450s420m450s420m450s1270m450s1270m450s420" + "m450s1270m450s420m450s1270m450s1270m450s1270m450s1270m450s420m450s420" + "m450s1270m450s420m450s420m450s1270m450s1270m450s420m450s420m450s420" + "m450s420m450s1270m450s1270m450s420m450s420m450s1270m450s1270m450s1270" + "m450s1270m450s420m450s1270m450s1270m450s1270m450s420m450s420m450s420" + "m450s420m450s1270m450s420m450s420m450s420m450s1270m450s1270m450s1270" + "m450s10800" + "m3500s1680" + "m450s420m450s420m450s420m450s1270m450s420m450s1270m450s420m450s420" + "m450s1270m450s420m450s420m450s420m450s420m450s1270m450s1270m450s420" + "m450s1270m450s420m450s1270m450s1270m450s420m450s1270m450s1270m450s420" + "m450s1270m450s1270m450s1270m450s1270m450s1270m450s1270m450s1270m450s1270" + "m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420" + "m450s1270m450s1270m450s1270m450s1270m450s1270m450s1270m450s1270m450s1270" + "m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420" + "m450s10800" + "m3500s1680" + "m450s420m450s420m450s420m450s1270m450s420m450s1270m450s420m450s420" + "m450s1270m450s420m450s420m450s420m450s420m450s1270m450s1270m450s420" + "m450s1270m450s420m450s1270m450s1270m450s420m450s420m450s1270m450s1270" + "m450s1270m450s1270m450s1270m450s1270m450s1270m450s1270m450s1270m450s1270" + "m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420" + "m450s1270m450s1270m450s1270m450s1270m450s1270m450s1270m450s1270m450s1270" + "m450s420m450s420m450s420m450s420m450s420m450s420m450s420m450s420" + "m450s10800", + irsend.outputStr()); + + irsend.reset(); + const uint8_t stateShort[kCoronaAcStateLengthShort] = { + 0x28, 0x61, 0x9D, 0x96, 0x69, 0x10, 0xEF}; + irsend.sendCoronaAc(stateShort, kCoronaAcStateLengthShort); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + ASSERT_EQ(kCoronaAcBitsShort, irsend.capture.bits); + EXPECT_STATE_EQ(stateShort, irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 0 (Heat), Temp: 16C, " + "Fan: 2 (Medium), Swing(V) Toggle: Off, Econo: Off, " + "On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + + EXPECT_EQ( + "f38000d50" + "m3500s1680" + "m450s420m450s420m450s420m450s1270m450s420m450s1270m450s420m450s420" + "m450s1270m450s420m450s420m450s420m450s420m450s1270m450s1270m450s420" + "m450s1270m450s420m450s1270m450s1270m450s1270m450s420m450s420m450s1270" + "m450s420m450s1270m450s1270m450s420m450s1270m450s420m450s420m450s1270" + "m450s1270m450s420m450s420m450s1270m450s420m450s1270m450s1270m450s420" + "m450s420m450s420m450s420m450s420m450s1270m450s420m450s420m450s420" + "m450s1270m450s1270m450s1270m450s1270m450s420m450s1270m450s1270m450s1270" + "m450s10800", + irsend.outputStr()); +} + +TEST(TestDecodeCoronaAc, SyntheticExampleNonMatch) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + + // Test checksum and prefix + // first base example match + irsend.begin(); + irsend.reset(); + const uint8_t stateOk[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x1D, 0xE2, + 0x28, 0x61, 0x6D, 0xE8, 0x17, 0x17, 0xE8, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.sendCoronaAc(stateOk); + irsend.makeDecodeResult(); + + EXPECT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(decode_type_t::CORONA_AC, irsend.capture.decode_type); + + irsend.begin(); + irsend.reset(); + // non valid Corona header section 1 + const uint8_t stateHeaderFail1[kCoronaAcStateLength] = { + 0x00, 0x61, 0x3D, 0x19, 0xE6, 0x1D, 0xE2, + 0x28, 0x61, 0x6D, 0xE8, 0x17, 0x17, 0xE8, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.sendCoronaAc(stateHeaderFail1); + irsend.makeDecodeResult(); + + EXPECT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_NE(decode_type_t::CORONA_AC, irsend.capture.decode_type); + + irsend.begin(); + irsend.reset(); + // non valid Corona header section 1 b2 + const uint8_t stateHeaderFail12[kCoronaAcStateLength] = { + 0x28, 0x00, 0x3D, 0x19, 0xE6, 0x1D, 0xE2, + 0x28, 0x61, 0x6D, 0xE8, 0x17, 0x17, 0xE8, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.sendCoronaAc(stateHeaderFail12); + irsend.makeDecodeResult(); + + EXPECT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_NE(decode_type_t::CORONA_AC, irsend.capture.decode_type); + + irsend.begin(); + irsend.reset(); + // non valid Corona section number + const uint8_t stateSection1NumFail[kCoronaAcStateLength] = { + 0x28, 0x61, 0x2D, 0x19, 0xE6, 0x1D, 0xE2, + 0x28, 0x61, 0x6D, 0xE8, 0x17, 0x17, 0xE8, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.sendCoronaAc(stateSection1NumFail); + irsend.makeDecodeResult(); + + EXPECT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_NE(decode_type_t::CORONA_AC, irsend.capture.decode_type); + + irsend.begin(); + irsend.reset(); + // non valid Corona invert D0 + const uint8_t stateInvertD0Fail[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0x19, 0x1D, 0xE2, + 0x28, 0x61, 0x6D, 0xE8, 0x17, 0x17, 0xE8, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.sendCoronaAc(stateInvertD0Fail); + irsend.makeDecodeResult(); + + EXPECT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_NE(decode_type_t::CORONA_AC, irsend.capture.decode_type); + + irsend.begin(); + irsend.reset(); + // non valid Corona invert D1 + const uint8_t stateInvertD1Fail[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x19, 0xE6, 0x1D, 0x1D, + 0x28, 0x61, 0x6D, 0xE8, 0x17, 0x17, 0xE8, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + irsend.sendCoronaAc(stateInvertD1Fail); + irsend.makeDecodeResult(); + + EXPECT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_NE(decode_type_t::CORONA_AC, irsend.capture.decode_type); +} + +TEST(TestUtils, Housekeeping) { + ASSERT_EQ("CORONA_AC", typeToString(decode_type_t::CORONA_AC)); + ASSERT_EQ(decode_type_t::CORONA_AC, strToDecodeType("CORONA_AC")); + ASSERT_TRUE(hasACState(decode_type_t::CORONA_AC)); + ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::CORONA_AC)); + ASSERT_EQ(kCoronaAcBits, IRsend::defaultBits(decode_type_t::CORONA_AC)); + ASSERT_EQ(kNoRepeat, IRsend::minRepeats(decode_type_t::CORONA_AC)); + ASSERT_EQ(kCoronaAcStateLength, 7 * 3); + ASSERT_EQ(kCoronaAcStateLengthShort, 7); + ASSERT_EQ(kCoronaAcSectionBytes, 7); + ASSERT_EQ(kCoronaAcSections, 3); +} + +// Tests for IRCoronaAc class. + +TEST(TestCoronaAcClass, Power) { + IRCoronaAc ac(kGpioUnused); + ac.begin(); + + ac.on(); + EXPECT_TRUE(ac.getPower()); + EXPECT_TRUE(ac.getPowerButton()); + + ac.off(); + EXPECT_FALSE(ac.getPower()); + EXPECT_TRUE(ac.getPowerButton()); + + ac.setOnTimer(60); + EXPECT_FALSE(ac.getPowerButton()); + ac.setPower(true); + EXPECT_TRUE(ac.getPower()); + EXPECT_EQ(0, ac.getOnTimer()); + EXPECT_FALSE(ac.getPowerButton()); + + ac.setOffTimer(60); + EXPECT_FALSE(ac.getPowerButton()); + ac.setPower(false); + EXPECT_FALSE(ac.getPower()); + EXPECT_EQ(0, ac.getOffTimer()); + EXPECT_FALSE(ac.getPowerButton()); + + ASSERT_EQ(4, kCoronaAcPowerOffset); + ASSERT_EQ(5, kCoronaAcPowerButtonOffset); +} + +TEST(TestCoronaAcClass, Temperature) { + IRCoronaAc ac(kGpioUnused); + ac.begin(); + + ac.setTemp(0); + EXPECT_EQ(kCoronaAcMinTemp, ac.getTemp()); + + ac.setTemp(255); + EXPECT_EQ(kCoronaAcMaxTemp, ac.getTemp()); + + ac.setTemp(kCoronaAcMinTemp); + EXPECT_EQ(kCoronaAcMinTemp, ac.getTemp()); + + ac.setTemp(kCoronaAcMaxTemp); + EXPECT_EQ(kCoronaAcMaxTemp, ac.getTemp()); + + ac.setTemp(kCoronaAcMinTemp - 1); + EXPECT_EQ(kCoronaAcMinTemp, ac.getTemp()); + + ac.setTemp(kCoronaAcMaxTemp + 1); + EXPECT_EQ(kCoronaAcMaxTemp, ac.getTemp()); + + ac.setTemp(17); + EXPECT_EQ(17, ac.getTemp()); + + ac.setTemp(21); + EXPECT_EQ(21, ac.getTemp()); + + ac.setTemp(25); + EXPECT_EQ(25, ac.getTemp()); + + ac.setTemp(29); + EXPECT_EQ(29, ac.getTemp()); +} + +TEST(TestCoronaAcClass, OperatingMode) { + IRCoronaAc ac(kGpioUnused); + ac.begin(); + + ac.setMode(kCoronaAcModeCool); + EXPECT_EQ(kCoronaAcModeCool, ac.getMode()); + + ac.setMode(kCoronaAcModeFan); + EXPECT_EQ(kCoronaAcModeFan, ac.getMode()); + + ac.setMode(kCoronaAcModeHeat); + EXPECT_EQ(kCoronaAcModeHeat, ac.getMode()); + + ac.setMode(kCoronaAcModeFan + 1); + EXPECT_EQ(kCoronaAcModeCool, ac.getMode()); + + ac.setMode(255); + EXPECT_EQ(kCoronaAcModeCool, ac.getMode()); + ac.setMode(0); + EXPECT_EQ(kCoronaAcModeHeat, ac.getMode()); +} + +TEST(TestCoronaAcClass, EconoPowerSave) { + IRCoronaAc ac(kGpioUnused); + ac.begin(); + ac.setEcono(true); + EXPECT_TRUE(ac.getEcono()); + ac.setEcono(false); + EXPECT_FALSE(ac.getEcono()); + ac.setEcono(true); + EXPECT_TRUE(ac.getEcono()); +} + +TEST(TestCoronaAcClass, SwingVerticalToggle) { + IRCoronaAc ac(kGpioUnused); + ac.begin(); + ac.setSwingVToggle(true); + EXPECT_TRUE(ac.getSwingVToggle()); + ac.setSwingVToggle(false); + EXPECT_FALSE(ac.getSwingVToggle()); + ac.setSwingVToggle(true); + EXPECT_TRUE(ac.getSwingVToggle()); +} + +TEST(TestCoronaAcClass, Timer) { + IRCoronaAc ac(kGpioUnused); + ac.begin(); + ac.setPowerButton(false); + ac.setMode(kCoronaAcModeHeat); + const uint8_t expectedStateNoTimer[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x10, 0xEF, 0x01, 0xFE, + 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + ASSERT_FALSE(ac.getPower()); + ASSERT_FALSE(ac.getPowerButton()); + EXPECT_STATE_EQ(expectedStateNoTimer, ac.getRaw(), kCoronaAcBits); + + ac.setOnTimer(3 * 60); + EXPECT_EQ(3 * 60, ac.getOnTimer()); + const uint8_t expectedStateOnTimer3H[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x10, 0xEF, 0x11, 0xEE, + 0x28, 0x61, 0x6D, 0x18, 0xE7, 0x15, 0xEA, // 5400 + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + ASSERT_TRUE(ac.getPower()); // remote should be on from timer + ASSERT_FALSE(ac.getPowerButton()); + EXPECT_STATE_EQ(expectedStateOnTimer3H, ac.getRaw(), kCoronaAcBits); + + ac.setOnTimer(0); + EXPECT_EQ(0, ac.getOnTimer()); + ASSERT_FALSE(ac.getPowerButton()); + ASSERT_TRUE(ac.getPower()); // remote should still be on + ac.off(); // set it to off + EXPECT_STATE_EQ(expectedStateNoTimer, ac.getRaw(), kCoronaAcBits); + ac.setOnTimer(kCoronaAcTimerOff); + EXPECT_EQ(0, ac.getOnTimer()); + EXPECT_FALSE(ac.getPowerButton()); + EXPECT_STATE_EQ(expectedStateNoTimer, ac.getRaw(), kCoronaAcBits); + + ac.setOffTimer(1); + EXPECT_EQ(1, ac.getOffTimer()); + ASSERT_TRUE(ac.getPower()); // remote should be on from timer + const uint8_t expectedStateOffTimer1m[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x10, 0xEF, 0x11, 0xEE, + 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, + 0x28, 0x61, 0xCD, 0x1E, 0xE1, 0x00, 0xFF}; // 30 + ASSERT_FALSE(ac.getPowerButton()); + EXPECT_STATE_EQ(expectedStateOffTimer1m, ac.getRaw(), kCoronaAcBits); + + ac.setOnTimer(2); + EXPECT_EQ(2, ac.getOnTimer()); + ASSERT_TRUE(ac.getPower()); // remote should be on from timer + // setting any of the timers needs to reset the other one + ASSERT_EQ(0, ac.getOffTimer()); + const uint8_t expectedStateOnTimer2m[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x10, 0xEF, 0x11, 0xEE, + 0x28, 0x61, 0x6D, 0x3C, 0xC3, 0x00, 0xFF, // 60 + 0x28, 0x61, 0xCD, 0xFF, 0x00, 0xFF, 0x00}; + ASSERT_FALSE(ac.getPowerButton()); + EXPECT_STATE_EQ(expectedStateOnTimer2m, ac.getRaw(), kCoronaAcBits); + + // setting a higher value than max should instead disable + ac.setOnTimer(kCoronaAcTimerMax + 1); + ASSERT_EQ(0, ac.getOnTimer()); + ASSERT_FALSE(ac.getPowerButton()); + ASSERT_TRUE(ac.getPower()); // remote should still be on + ac.off(); + ASSERT_FALSE(ac.getPowerButton()); + EXPECT_STATE_EQ(expectedStateNoTimer, ac.getRaw(), kCoronaAcBits); +} + + +TEST(TestCoronaAcClass, FanSpeed) { + IRCoronaAc ac(kGpioUnused); + ac.begin(); + + // Unexpected value should default to Auto. + ac.setFan(255); + EXPECT_EQ(kCoronaAcFanAuto, ac.getFan()); + ac.setFan(5); + EXPECT_EQ(kCoronaAcFanAuto, ac.getFan()); + + ac.setFan(kCoronaAcFanHigh); + EXPECT_EQ(kCoronaAcFanHigh, ac.getFan()); + + // Beyond High should default to Auto. + ac.setFan(kCoronaAcFanHigh + 1); + EXPECT_EQ(kCoronaAcFanAuto, ac.getFan()); + + ac.setFan(kCoronaAcFanMedium); + EXPECT_EQ(kCoronaAcFanMedium, ac.getFan()); + + ac.setFan(kCoronaAcFanLow); + EXPECT_EQ(kCoronaAcFanLow, ac.getFan()); + + ac.setFan(kCoronaAcFanAuto); + EXPECT_EQ(kCoronaAcFanAuto, ac.getFan()); +} + +// Test human readable output. +TEST(TestCoronaAcClass, HumanReadable) { + IRCoronaAc ac(kGpioUnused); + EXPECT_EQ( + "Power: Off, Power Button: On, Mode: 2 (Cool), Temp: 17C, " + "Fan: 0 (Auto), Swing(V) Toggle: Off, Econo: Off, " + "On Timer: Off, Off Timer: Off", + ac.toString()); + ac.setPower(true); + ac.setMode(kCoronaAcModeFan); + ac.setTemp(30); + ac.setFan(kCoronaAcFanAuto); + ac.setSwingVToggle(true); + EXPECT_EQ( + "Power: On, Power Button: On, Mode: 3 (Fan), Temp: 30C, " + "Fan: 0 (Auto), Swing(V) Toggle: On, Econo: Off, " + "On Timer: Off, Off Timer: Off", + ac.toString()); + ac.setOffTimer(8 * 60 + 37); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 3 (Fan), Temp: 30C, " + "Fan: 0 (Auto), Swing(V) Toggle: On, Econo: Off, " + "On Timer: Off, Off Timer: 08:37", + ac.toString()); + ac.setOnTimer(5 * 60 + 59); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 3 (Fan), Temp: 30C, " + "Fan: 0 (Auto), Swing(V) Toggle: On, Econo: Off, " + "On Timer: 05:59, Off Timer: Off", + ac.toString()); + ac.setOnTimer(59); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 3 (Fan), Temp: 30C, " + "Fan: 0 (Auto), Swing(V) Toggle: On, Econo: Off, " + "On Timer: 00:59, Off Timer: Off", + ac.toString()); + ac.setEcono(true); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 3 (Fan), Temp: 30C, " + "Fan: 0 (Auto), Swing(V) Toggle: On, Econo: On, " + "On Timer: 00:59, Off Timer: Off", + ac.toString()); +} + +TEST(TestCoronaAcClass, ReconstructKnownState) { + IRCoronaAc ac(kGpioUnused); + const uint8_t expectedState[kCoronaAcStateLength] = { + 0x28, 0x61, 0x3D, 0x59, 0xA6, 0xD3, 0x2C, + 0x28, 0x61, 0x6D, 0xFF, 0x00, 0xFF, 0x00, + 0x28, 0x61, 0xCD, 0x18, 0xE7, 0x15, 0xEA}; + ASSERT_TRUE(IRCoronaAc::validSection(expectedState, + 0 * kCoronaAcSectionBytes, 0)); + ASSERT_TRUE(IRCoronaAc::validSection(expectedState, + 1 * kCoronaAcSectionBytes, 1)); + ASSERT_TRUE(IRCoronaAc::validSection(expectedState, + 2 * kCoronaAcSectionBytes, 2)); + ac.begin(); + ac.stateReset(); + // ASSERT_STATE_NE(expectedState, ac.getRaw()); + ac.on(); + ac.setMode(kCoronaAcModeFan); + ac.setTemp(19); + ac.setFan(kCoronaAcFanLow); + ac.setSwingVToggle(true); + ac.setOffTimer(3 * 60); + ac.setEcono(true); + EXPECT_STATE_EQ(expectedState, ac.getRaw(), kCoronaAcBits); + EXPECT_EQ( + "Power: On, Power Button: Off, Mode: 3 (Fan), Temp: 19C, " + "Fan: 1 (Low), Swing(V) Toggle: On, Econo: On, " + "On Timer: Off, Off Timer: 03:00", + ac.toString()); +} + +TEST(TestCoronaAcClass, toCommon) { + IRCoronaAc ac(kGpioUnused); + ac.begin(); + ac.stateReset(); + ac.on(); + ac.setMode(kCoronaAcModeFan); + ac.setTemp(20); + ac.setFan(kCoronaAcFanLow); + ac.setSwingVToggle(true); + ac.setOffTimer(3 * 60); + ac.setEcono(true); + // Now test it. + ASSERT_EQ(decode_type_t::CORONA_AC, ac.toCommon().protocol); + ASSERT_EQ(-1, ac.toCommon().model); + ASSERT_TRUE(ac.toCommon().power); + ASSERT_TRUE(ac.toCommon().celsius); + ASSERT_EQ(20, ac.toCommon().degrees); + ASSERT_EQ(stdAc::opmode_t::kFan, ac.toCommon().mode); + ASSERT_EQ(stdAc::fanspeed_t::kLow, ac.toCommon().fanspeed); + ASSERT_EQ(stdAc::swingv_t::kAuto, ac.toCommon().swingv); + ASSERT_TRUE(ac.toCommon().econo); + // Unsupported. + ASSERT_EQ(stdAc::swingh_t::kOff, ac.toCommon().swingh); + ASSERT_FALSE(ac.toCommon().turbo); + ASSERT_FALSE(ac.toCommon().quiet); + ASSERT_FALSE(ac.toCommon().clean); + ASSERT_FALSE(ac.toCommon().light); + ASSERT_FALSE(ac.toCommon().filter); + ASSERT_FALSE(ac.toCommon().beep); + ASSERT_EQ(-1, ac.toCommon().sleep); + ASSERT_EQ(-1, ac.toCommon().clock); +} diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Daikin_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Daikin_test.cpp similarity index 98% rename from lib/IRremoteESP8266-2.7.5/test/ir_Daikin_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Daikin_test.cpp index e37c6b00a..f57888c23 100644 --- a/lib/IRremoteESP8266-2.7.5/test/ir_Daikin_test.cpp +++ b/lib/IRremoteESP8266-2.7.8/test/ir_Daikin_test.cpp @@ -3690,3 +3690,36 @@ TEST(TestDaikin64Class, HumanReadable) { "Clock: 12:31, On Timer: 08:30, Off Timer: Off", ac.toString()); } + +TEST(TestDecodeDaikin64, Issue1092) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + + uint16_t rawData[137] = { + 9792, 9786, 9818, 9860, 4600, 2532, 338, 422, 332, 950, 362, 950, 360, + 378, 354, 954, 386, 378, 334, 376, 356, 382, 360, 380, 364, 946, 354, 410, + 334, 380, 364, 972, 328, 386, 358, 380, 364, 374, 358, 380, 362, 376, 356, + 382, 360, 378, 354, 410, 334, 404, 326, 412, 332, 408, 336, 376, 356, 382, + 362, 378, 354, 384, 360, 378, 354, 384, 358, 380, 354, 384, 358, 382, 362, + 976, 336, 974, 338, 374, 358, 980, 332, 380, 362, 376, 356, 382, 362, 376, + 356, 956, 356, 980, 330, 382, 360, 976, 334, 376, 356, 382, 360, 378, 354, + 384, 358, 952, 360, 950, 360, 378, 354, 384, 360, 952, 360, 378, 354, 384, + 358, 380, 364, 374, 358, 952, 360, 380, 362, 376, 356, 382, 382, 928, 362, + 376, 356, 20348, 4628}; // UNKNOWN C508A32A + + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData, 137, kDaikin64Freq); + irsend.makeDecodeResult(); + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::DAIKIN64, irsend.capture.decode_type); + ASSERT_EQ(kDaikin64Bits, irsend.capture.bits); + EXPECT_EQ(0x4426161600001216, irsend.capture.value); + EXPECT_EQ( + "Power Toggle: Off, Mode: 2 (Cool), Temp: 26C, Fan: 1 (Auto), " + "Turbo: Off, Quiet: Off, Swing(V): Off, Sleep: Off, " + "Clock: 00:00, On Timer: Off, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + stdAc::state_t result, prev; + ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &result, &prev)); +} diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Delonghi_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Delonghi_test.cpp new file mode 100644 index 000000000..9f069e40e --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/test/ir_Delonghi_test.cpp @@ -0,0 +1,362 @@ +// Copyright 2020 David Conran + +#include "IRac.h" +#include "ir_Delonghi.h" +#include "IRrecv.h" +#include "IRrecv_test.h" +#include "IRsend.h" +#include "IRsend_test.h" +#include "IRutils.h" +#include "gtest/gtest.h" + +TEST(TestUtils, Housekeeping) { + ASSERT_EQ("DELONGHI_AC", typeToString(decode_type_t::DELONGHI_AC)); + ASSERT_EQ(decode_type_t::DELONGHI_AC, strToDecodeType("DELONGHI_AC")); + ASSERT_FALSE(hasACState(decode_type_t::DELONGHI_AC)); + ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::DELONGHI_AC)); + ASSERT_EQ(kDelonghiAcBits, IRsend::defaultBits(decode_type_t::DELONGHI_AC)); + ASSERT_EQ(kDelonghiAcDefaultRepeat, + IRsend::minRepeats(decode_type_t::DELONGHI_AC)); +} + +TEST(TestDecodeDelonghiAc, SyntheticSelfDecode) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + + irsend.begin(); + irsend.reset(); + irsend.sendDelonghiAc(0x6900000D0D01FB53); + irsend.makeDecodeResult(); + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(DELONGHI_AC, irsend.capture.decode_type); + EXPECT_EQ(kDelonghiAcBits, irsend.capture.bits); + EXPECT_EQ(0x6900000D0D01FB53, irsend.capture.value); + EXPECT_EQ(0, irsend.capture.command); + EXPECT_EQ(0, irsend.capture.address); +} + +TEST(TestDecodeDelonghiAc, RealExample) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + irsend.begin(); + + // Data from: + // https://github.com/crankyoldgit/IRremoteESP8266/issues/1096#issue-610665633 + uint16_t rawData[131] = { + 8984, 4200, + 608, 1516, 608, 1516, 612, 472, 556, 528, 560, 1564, 556, 528, 560, 1564, + 564, 528, 552, 1572, 556, 1568, 556, 528, 552, 1572, 556, 1568, 560, 1564, + 552, 1572, 556, 1576, 552, 1568, 560, 528, 560, 524, 556, 528, 552, 532, + 560, 528, 552, 532, 556, 532, 560, 1564, 560, 528, 552, 1568, 560, 1564, + 564, 524, 556, 528, 560, 524, 556, 536, 556, 1568, 560, 524, 556, 1568, + 560, 1564, 584, 500, 588, 496, 584, 500, 592, 500, 588, 496, 584, 500, + 592, 496, 584, 500, 588, 496, 584, 500, 592, 492, 584, 508, 584, 500, + 588, 496, 584, 500, 592, 496, 584, 500, 580, 504, 584, 500, 580, 508, + 584, 1544, 584, 500, 588, 496, 584, 1540, 588, 500, 580, 1540, 588, 1536, + 588, 500, + 592}; + + irsend.reset(); + irsend.sendRaw(rawData, 263, 38000); + irsend.makeDecodeResult(); + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(DELONGHI_AC, irsend.capture.decode_type); + EXPECT_EQ(kDelonghiAcBits, irsend.capture.bits); + EXPECT_EQ(0x6900000D0D01FB53, irsend.capture.value); + EXPECT_EQ(0, irsend.capture.command); + EXPECT_EQ(0, irsend.capture.address); + EXPECT_EQ( + "Power: On, Mode: 0 (Cool), Fan: 3 (Low), Temp: 90F, " + "Turbo: Off, Sleep: Off, On Timer: 06:13, Off Timer: Off", + IRAcUtils::resultAcToString(&irsend.capture)); + stdAc::state_t r, p; + ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p)); +} + +// Tests for IRDelonghiAc class. + +TEST(TestIRDelonghiAcClass, Power) { + IRDelonghiAc ac(kGpioUnused); + ac.begin(); + + ac.on(); + EXPECT_TRUE(ac.getPower()); + + ac.off(); + EXPECT_FALSE(ac.getPower()); + + ac.setPower(true); + EXPECT_TRUE(ac.getPower()); + + ac.setPower(false); + EXPECT_FALSE(ac.getPower()); + + // Ref: + // https://github.com/crankyoldgit/IRremoteESP8266/issues/1096#issuecomment-622521726 + ac.setRaw(0x5500000000010153); // Power on + EXPECT_TRUE(ac.getPower()); + ac.setRaw(0x5400000000000153); // Power off + EXPECT_FALSE(ac.getPower()); +} + +TEST(TestIRDelonghiAcClass, Temperature) { + IRDelonghiAc ac(kGpioUnused); + ac.begin(); + + // Celsius + ac.setTemp(0); + EXPECT_EQ(kDelonghiAcTempMinC, ac.getTemp()); + EXPECT_FALSE(ac.getTempUnit()); + + ac.setTemp(255); + EXPECT_EQ(kDelonghiAcTempMaxC, ac.getTemp()); + EXPECT_FALSE(ac.getTempUnit()); + + ac.setTemp(kDelonghiAcTempMinC); + EXPECT_EQ(kDelonghiAcTempMinC, ac.getTemp()); + EXPECT_FALSE(ac.getTempUnit()); + + ac.setTemp(kDelonghiAcTempMaxC); + EXPECT_EQ(kDelonghiAcTempMaxC, ac.getTemp()); + EXPECT_FALSE(ac.getTempUnit()); + + ac.setTemp(kDelonghiAcTempMinC - 1); + EXPECT_EQ(kDelonghiAcTempMinC, ac.getTemp()); + EXPECT_FALSE(ac.getTempUnit()); + + ac.setTemp(kDelonghiAcTempMaxC + 1); + EXPECT_EQ(kDelonghiAcTempMaxC, ac.getTemp()); + EXPECT_FALSE(ac.getTempUnit()); + + ac.setTemp(19); + EXPECT_EQ(19, ac.getTemp()); + EXPECT_FALSE(ac.getTempUnit()); + + ac.setTemp(21); + EXPECT_EQ(21, ac.getTemp()); + EXPECT_FALSE(ac.getTempUnit()); + + ac.setTemp(25); + EXPECT_EQ(25, ac.getTemp()); + EXPECT_FALSE(ac.getTempUnit()); + + ac.setTemp(29, false); + EXPECT_EQ(29, ac.getTemp()); + EXPECT_FALSE(ac.getTempUnit()); + + // Fahrenheit + ac.setTemp(0, true); + EXPECT_EQ(kDelonghiAcTempMinF, ac.getTemp()); + EXPECT_TRUE(ac.getTempUnit()); + + ac.setTemp(255, true); + EXPECT_EQ(kDelonghiAcTempMaxF, ac.getTemp()); + EXPECT_TRUE(ac.getTempUnit()); + + ac.setTemp(kDelonghiAcTempMinF, true); + EXPECT_EQ(kDelonghiAcTempMinF, ac.getTemp()); + EXPECT_TRUE(ac.getTempUnit()); + + ac.setTemp(kDelonghiAcTempMaxF, true); + EXPECT_EQ(kDelonghiAcTempMaxF, ac.getTemp()); + EXPECT_TRUE(ac.getTempUnit()); + + ac.setTemp(kDelonghiAcTempMinF - 1, true); + EXPECT_EQ(kDelonghiAcTempMinF, ac.getTemp()); + EXPECT_TRUE(ac.getTempUnit()); + + ac.setTemp(kDelonghiAcTempMaxF + 1, true); + EXPECT_EQ(kDelonghiAcTempMaxF, ac.getTemp()); + EXPECT_TRUE(ac.getTempUnit()); + + ac.setTemp(66, true); + EXPECT_EQ(66, ac.getTemp()); + EXPECT_TRUE(ac.getTempUnit()); + + ac.setTemp(75, true); + EXPECT_EQ(75, ac.getTemp()); + EXPECT_TRUE(ac.getTempUnit()); + + ac.setTemp(80, true); + EXPECT_EQ(80, ac.getTemp()); + EXPECT_TRUE(ac.getTempUnit()); + + ac.setTemp(88, true); + EXPECT_EQ(88, ac.getTemp()); + EXPECT_TRUE(ac.getTempUnit()); +} + +TEST(TestIRDelonghiAcClass, OperatingMode) { + IRDelonghiAc ac(kGpioUnused); + ac.begin(); + + ac.setMode(kDelonghiAcAuto); + EXPECT_EQ(kDelonghiAcAuto, ac.getMode()); + EXPECT_EQ(17, ac.getTemp()); // Check for special temp + EXPECT_EQ(kDelonghiAcFanAuto, ac.getFan()); // Look for fan speed enforcement + + ac.setMode(kDelonghiAcCool); + EXPECT_EQ(kDelonghiAcCool, ac.getMode()); + // Check changing to another mode that has a fixed temp and back keeps the + // existing temp. Only for Cool mode. + ac.setTemp(22); + EXPECT_EQ(22, ac.getTemp()); + ac.setMode(kDelonghiAcAuto); + EXPECT_NE(22, ac.getTemp()); + ac.setMode(kDelonghiAcCool); + EXPECT_EQ(22, ac.getTemp()); + + ac.setMode(kDelonghiAcDry); + EXPECT_EQ(kDelonghiAcDry, ac.getMode()); + EXPECT_EQ(17, ac.getTemp()); // Check for special temp + EXPECT_EQ(kDelonghiAcFanAuto, ac.getFan()); // Look for fan speed enforcement + + ac.setMode(kDelonghiAcFan); + EXPECT_EQ(kDelonghiAcFan, ac.getMode()); + EXPECT_EQ(23, ac.getTemp()); // Check for special temp + EXPECT_NE(kDelonghiAcFanAuto, ac.getFan()); // Look for fan speed enforcement + + ac.setMode(kDelonghiAcAuto + 1); + EXPECT_EQ(kDelonghiAcAuto, ac.getMode()); + + ac.setMode(255); + EXPECT_EQ(kDelonghiAcAuto, ac.getMode()); +} + +TEST(TestIRDelonghiAcClass, FanSpeed) { + IRDelonghiAc ac(kGpioUnused); + ac.begin(); + ac.setMode(kDelonghiAcCool); // All fan speeds available in this mode. + + ac.setFan(0); + EXPECT_EQ(kDelonghiAcFanAuto, ac.getFan()); + + ac.setFan(255); + EXPECT_EQ(kDelonghiAcFanAuto, ac.getFan()); + + ac.setFan(kDelonghiAcFanHigh); + EXPECT_EQ(kDelonghiAcFanHigh, ac.getFan()); + + ac.setFan(kDelonghiAcFanLow + 1); + EXPECT_EQ(kDelonghiAcFanAuto, ac.getFan()); + + ac.setFan(1); + EXPECT_EQ(1, ac.getFan()); + + ac.setFan(2); + EXPECT_EQ(2, ac.getFan()); + + ac.setFan(3); + EXPECT_EQ(3, ac.getFan()); + + // Confirm changing to fan mode handles speed behaviour correctly. + ac.setFan(kDelonghiAcFanLow); + ac.setMode(kDelonghiAcFan); + EXPECT_EQ(kDelonghiAcFanLow, ac.getFan()); + ac.setMode(kDelonghiAcAuto); + EXPECT_EQ(kDelonghiAcFanAuto, ac.getFan()); + ac.setMode(kDelonghiAcFan); + EXPECT_NE(kDelonghiAcFanAuto, ac.getFan()); +} + +TEST(TestIRDelonghiAcClass, Boost) { + IRDelonghiAc ac(kGpioUnused); + ac.begin(); + + ac.setBoost(false); + EXPECT_FALSE(ac.getBoost()); + ac.setBoost(true); + EXPECT_TRUE(ac.getBoost()); + ac.setBoost(false); + EXPECT_FALSE(ac.getBoost()); +} + +TEST(TestIRDelonghiAcClass, Sleep) { + IRDelonghiAc ac(kGpioUnused); + ac.begin(); + + ac.setSleep(false); + EXPECT_FALSE(ac.getSleep()); + ac.setSleep(true); + EXPECT_TRUE(ac.getSleep()); + ac.setSleep(false); + EXPECT_FALSE(ac.getSleep()); +} + +TEST(TestIRDelonghiAcClass, OnTimer) { + IRDelonghiAc ac(kGpioUnused); + ac.begin(); + + ac.setOnTimerEnabled(false); + EXPECT_FALSE(ac.getOnTimerEnabled()); + ac.setOnTimerEnabled(true); + EXPECT_TRUE(ac.getOnTimerEnabled()); + ac.setOnTimerEnabled(false); + EXPECT_FALSE(ac.getOnTimerEnabled()); + + ac.setOnTimer(0); + EXPECT_FALSE(ac.getOnTimerEnabled()); + EXPECT_EQ(0, ac.getOnTimer()); + + ac.setOnTimer(1); + EXPECT_TRUE(ac.getOnTimerEnabled()); + EXPECT_EQ(1, ac.getOnTimer()); + + ac.setOnTimer(61); + EXPECT_TRUE(ac.getOnTimerEnabled()); + EXPECT_EQ(61, ac.getOnTimer()); + + ac.setOnTimerEnabled(false); + ac.setOnTimer(23 * 60 + 59); + EXPECT_TRUE(ac.getOnTimerEnabled()); + EXPECT_EQ(23 * 60 + 59, ac.getOnTimer()); + + ac.setOnTimerEnabled(false); + ac.setOnTimer(24 * 60); + EXPECT_TRUE(ac.getOnTimerEnabled()); + EXPECT_EQ(23 * 60 + 59, ac.getOnTimer()); +} + +TEST(TestIRDelonghiAcClass, OffTimer) { + IRDelonghiAc ac(kGpioUnused); + ac.begin(); + + ac.setOffTimerEnabled(false); + EXPECT_FALSE(ac.getOffTimerEnabled()); + ac.setOffTimerEnabled(true); + EXPECT_TRUE(ac.getOffTimerEnabled()); + ac.setOffTimerEnabled(false); + EXPECT_FALSE(ac.getOffTimerEnabled()); + + ac.setOffTimer(0); + EXPECT_FALSE(ac.getOffTimerEnabled()); + EXPECT_EQ(0, ac.getOffTimer()); + + ac.setOffTimer(1); + EXPECT_TRUE(ac.getOffTimerEnabled()); + EXPECT_EQ(1, ac.getOffTimer()); + + ac.setOffTimer(61); + EXPECT_TRUE(ac.getOffTimerEnabled()); + EXPECT_EQ(61, ac.getOffTimer()); + + ac.setOffTimerEnabled(false); + ac.setOffTimer(23 * 60 + 59); + EXPECT_TRUE(ac.getOffTimerEnabled()); + EXPECT_EQ(23 * 60 + 59, ac.getOffTimer()); + + ac.setOffTimerEnabled(false); + ac.setOffTimer(24 * 60); + EXPECT_TRUE(ac.getOffTimerEnabled()); + EXPECT_EQ(23 * 60 + 59, ac.getOffTimer()); + + // Real Data + // From: https://github.com/crankyoldgit/IRremoteESP8266/issues/1096#issuecomment-623115619 + // Setting off timer to 8:51 when the time on the remote displayed 16:05. + // (8:51 + 24:00 - 16:05 == 32:51 - 16:05 == 16:46) i.e. Turn off in 16h46m. + ac.setRaw(0xB12E210000000F53); + EXPECT_TRUE(ac.getOffTimerEnabled()); + EXPECT_EQ(16 * 60 + 46, ac.getOffTimer()); + EXPECT_FALSE(ac.getOnTimerEnabled()); + EXPECT_EQ(0, ac.getOnTimer()); +} diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Denon_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Denon_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/ir_Denon_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Denon_test.cpp diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Dish_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Dish_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/ir_Dish_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Dish_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Doshisha_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Doshisha_test.cpp new file mode 100644 index 000000000..8c69bfbb3 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/test/ir_Doshisha_test.cpp @@ -0,0 +1,152 @@ +// Copyright 2020 Christian Nilsson + +#include "IRac.h" +#include "IRrecv.h" +#include "IRrecv_test.h" +#include "IRsend.h" +#include "IRsend_test.h" +#include "gtest/gtest.h" + +// Tests for decodeDoshisha(). + +TEST(TestDecodeDoshisha, RealExample) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + // CH2 Light Level 1 + const uint16_t rawData_1[83] = { + 3404, 1718, + 416, 1306, 416, 460, 438, 432, 412, 460, 464, 396, 488, 394, 488, 394, + 488, 398, 460, 430, 468, 398, 484, 416, 468, 396, 488, 1264, 414, 460, + 436, 1286, 524, 1210, 470, 390, 434, 456, 414, 1288, 458, 1290, 438, 434, + 412, 458, 440, 434, 438, 418, 456, 432, 466, 1270, 438, 442, 438, 430, + 414, 1316, 412, 460, 440, 432, 412, 460, 440, 1264, 458, 434, 436, 1268, + 458, 436, 438, 412, 456, 1290, 438, 442, 436, 1290, + 464}; // DOSHISHA 800B3048A5 + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_1, 83, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::DOSHISHA, irsend.capture.decode_type); + ASSERT_EQ(kDoshishaBits, irsend.capture.bits); + EXPECT_EQ(0x800B3048A5, irsend.capture.value); + EXPECT_EQ(0b1, irsend.capture.address); + EXPECT_EQ(0xA4, irsend.capture.command); + + // CH2 OFF + const uint16_t rawData_2[83] = { + 3434, 1700, + 446, 1284, 442, 440, 442, 428, 444, 432, 440, 430, 442, 432, 472, 438, + 444, 446, 416, 430, 470, 416, 470, 438, 444, 442, 470, 1242, 440, 430, + 442, 1314, 390, 1344, 444, 440, 414, 432, 442, 1310, 412, 1318, 416, 458, + 416, 434, 438, 432, 418, 484, 416, 458, 442, 1298, 416, 466, 420, 428, + 442, 1316, 418, 432, 442, 430, 442, 434, 444, 1286, 440, 430, 444, 1288, + 444, 430, 444, 430, 442, 432, 498, 386, 498, 1242, + 474}; // DOSHISHA 800B3048A1 + + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_2, 175, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::DOSHISHA, irsend.capture.decode_type); + ASSERT_EQ(kDoshishaBits, irsend.capture.bits); + EXPECT_EQ(0x800B3048A1, irsend.capture.value); + EXPECT_EQ(0b1, irsend.capture.address); + EXPECT_EQ(0xA0, irsend.capture.command); + + // CH1 OFF + const uint16_t rawData_4[83] = { + 3470, 1670, + 444, 1294, 470, 408, 442, 430, 444, 412, 464, 440, 498, 386, 498, 388, + 474, 418, 440, 430, 472, 414, 474, 412, 472, 414, 470, 1268, 444, 428, + 448, 1284, 444, 1294, 472, 412, 446, 428, 442, 1284, 444, 1290, 444, 430, + 446, 430, 442, 410, 490, 406, 446, 428, 472, 1270, 472, 414, 442, 410, + 460, 1292, 444, 430, 442, 430, 444, 434, 444, 1286, 442, 432, 442, 1288, + 446, 430, 442, 414, 486, 386, 516, 388, 446, 438, + 446}; // DOSHISHA 800B3048A0 + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_4, 175, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::DOSHISHA, irsend.capture.decode_type); + ASSERT_EQ(kDoshishaBits, irsend.capture.bits); + EXPECT_EQ(0x800B3048A0, irsend.capture.value); + EXPECT_EQ(0b0, irsend.capture.address); + EXPECT_EQ(0xA0, irsend.capture.command); +} + +TEST(TestDecodeDoshisha, SyntheticExample) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + irsend.begin(); + irsend.reset(); + irsend.sendDoshisha(0x800B3048A5); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(decode_type_t::DOSHISHA, irsend.capture.decode_type); + EXPECT_EQ(kDoshishaBits, irsend.capture.bits); + EXPECT_EQ(0x800B3048A5, irsend.capture.value); + EXPECT_EQ(0b1, irsend.capture.address); + EXPECT_EQ(0xA4, irsend.capture.command); + + EXPECT_EQ( + "f38000d50" + "m3412s1722" + "m420s1310m420s452m420s452m420s452m420s452m420s452m420s452" + "m420s452m420s452m420s452m420s452m420s452m420s1310m420s452" + "m420s1310m420s1310m420s452m420s452m420s1310m420s1310m420s452" + "m420s452m420s452m420s452m420s452m420s1310m420s452m420s452" + "m420s1310m420s452m420s452m420s452m420s1310m420s452m420s1310" + "m420s452m420s452m420s1310m420s452m420s1310" + "m420s100000", + irsend.outputStr()); + + irsend.reset(); + irsend.sendDoshisha(0x800B3048D0); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(decode_type_t::DOSHISHA, irsend.capture.decode_type); + EXPECT_EQ(kDoshishaBits, irsend.capture.bits); + EXPECT_EQ(0x800B3048D0, irsend.capture.value); + EXPECT_EQ(irsend.encodeDoshisha(0xD0, 0b0), irsend.capture.value); + EXPECT_EQ(0b0, irsend.capture.address); + EXPECT_EQ(0xD0, irsend.capture.command); + EXPECT_EQ( + "f38000d50" + "m3412s1722" + "m420s1310m420s452m420s452m420s452m420s452m420s452m420s452" + "m420s452m420s452m420s452m420s452m420s452m420s1310m420s452" + "m420s1310m420s1310m420s452m420s452m420s1310m420s1310m420s452" + "m420s452m420s452m420s452m420s452m420s1310m420s452m420s452m420" + "s1310m420s452m420s452m420s452m420s1310m420s1310m420s452m420s1310" + "m420s452m420s452m420s452m420s452" + "m420s100000", + irsend.outputStr()); +} + +TEST(TestEncodeDoshisha, SyntheticExample) { + IRsendTest irsend(kGpioUnused); + // kRcz01CheckExpected + EXPECT_EQ(0x800B304800, irsend.encodeDoshisha(0x00, 0b0)); + // kRcz01CommandTimmer30 + EXPECT_EQ(0x800B304892, irsend.encodeDoshisha(0x92, 0b0)); + // kRcz01CommandLevel1 + EXPECT_EQ(0x800B3048A5, irsend.encodeDoshisha(0xA4, 0b1)); + EXPECT_EQ(0x800B3048A4, irsend.encodeDoshisha(0xA4, 0b0)); +} + +TEST(TestUtils, Housekeeping) { + ASSERT_EQ("DOSHISHA", typeToString(decode_type_t::DOSHISHA)); + ASSERT_EQ(decode_type_t::DOSHISHA, strToDecodeType("DOSHISHA")); + ASSERT_FALSE(hasACState(decode_type_t::DOSHISHA)); + ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::DOSHISHA)); + ASSERT_EQ(kDoshishaBits, IRsend::defaultBits(decode_type_t::DOSHISHA)); + ASSERT_EQ(kNoRepeat, IRsend::minRepeats(decode_type_t::DOSHISHA)); +} diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Electra_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Electra_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/ir_Electra_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Electra_test.cpp diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Epson_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Epson_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/ir_Epson_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Epson_test.cpp diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Fujitsu_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Fujitsu_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/ir_Fujitsu_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Fujitsu_test.cpp diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_GICable_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_GICable_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/ir_GICable_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_GICable_test.cpp diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_GlobalCache_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_GlobalCache_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/ir_GlobalCache_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_GlobalCache_test.cpp diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Goodweather_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Goodweather_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/ir_Goodweather_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Goodweather_test.cpp diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Gree_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Gree_test.cpp similarity index 65% rename from lib/IRremoteESP8266-2.7.5/test/ir_Gree_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Gree_test.cpp index a824cd10a..46b1b17b4 100644 --- a/lib/IRremoteESP8266-2.7.5/test/ir_Gree_test.cpp +++ b/lib/IRremoteESP8266-2.7.8/test/ir_Gree_test.cpp @@ -13,7 +13,7 @@ // Test sending typical data only. TEST(TestSendGreeChars, SendData) { - IRsendTest irsend(4); + IRsendTest irsend(kGpioUnused); irsend.begin(); uint8_t gree_code[kGreeStateLength] = {0x12, 0x34, 0x56, 0x78, @@ -38,7 +38,7 @@ TEST(TestSendGreeChars, SendData) { } TEST(TestSendGreeUint64, SendData) { - IRsendTest irsend(4); + IRsendTest irsend(kGpioUnused); irsend.begin(); irsend.reset(); @@ -62,7 +62,7 @@ TEST(TestSendGreeUint64, SendData) { // Test sending with repeats. TEST(TestSendGreeChars, SendWithRepeats) { - IRsendTest irsend(4); + IRsendTest irsend(kGpioUnused); irsend.begin(); irsend.reset(); @@ -101,7 +101,7 @@ TEST(TestSendGreeChars, SendWithRepeats) { } TEST(TestSendGreeUint64, SendWithRepeats) { - IRsendTest irsend(4); + IRsendTest irsend(kGpioUnused); irsend.begin(); irsend.reset(); @@ -137,7 +137,7 @@ TEST(TestSendGreeUint64, SendWithRepeats) { // Test sending atypical sizes. TEST(TestSendGreeChars, SendUnexpectedSizes) { - IRsendTest irsend(4); + IRsendTest irsend(kGpioUnused); irsend.begin(); uint8_t gree_short_code[kGreeStateLength - 1] = {0x12, 0x34, 0x56, 0x78, @@ -169,7 +169,7 @@ TEST(TestSendGreeChars, SendUnexpectedSizes) { } TEST(TestSendGreeUint64, SendUnexpectedSizes) { - IRsendTest irsend(4); + IRsendTest irsend(kGpioUnused); irsend.begin(); irsend.reset(); @@ -209,138 +209,184 @@ TEST(TestSendGree, CompareUint64ToCharResults) { // Tests for IRGreeAC class. TEST(TestGreeClass, Power) { - IRGreeAC irgree(0); - irgree.begin(); + IRGreeAC ac(kGpioUnused); + ac.begin(); - irgree.on(); - EXPECT_TRUE(irgree.getPower()); + ac.on(); + EXPECT_TRUE(ac.getPower()); - irgree.off(); - EXPECT_FALSE(irgree.getPower()); + ac.off(); + EXPECT_FALSE(ac.getPower()); - irgree.setPower(true); - EXPECT_TRUE(irgree.getPower()); + ac.setPower(true); + EXPECT_TRUE(ac.getPower()); - irgree.setPower(false); - EXPECT_FALSE(irgree.getPower()); + ac.setPower(false); + EXPECT_FALSE(ac.getPower()); } TEST(TestGreeClass, Temperature) { - IRGreeAC irgree(0); - irgree.begin(); + IRGreeAC ac(kGpioUnused); + ac.begin(); - irgree.setMode(kGreeCool); + ac.setMode(kGreeCool); - irgree.setTemp(0); - EXPECT_EQ(kGreeMinTemp, irgree.getTemp()); + ac.setTemp(0); + EXPECT_EQ(kGreeMinTempC, ac.getTemp()); - irgree.setTemp(255); - EXPECT_EQ(kGreeMaxTemp, irgree.getTemp()); + ac.setTemp(255); + EXPECT_EQ(kGreeMaxTempC, ac.getTemp()); - irgree.setTemp(kGreeMinTemp); - EXPECT_EQ(kGreeMinTemp, irgree.getTemp()); + ac.setTemp(kGreeMinTempC); + EXPECT_EQ(kGreeMinTempC, ac.getTemp()); + EXPECT_FALSE(ac.getUseFahrenheit()); - irgree.setTemp(kGreeMaxTemp); - EXPECT_EQ(kGreeMaxTemp, irgree.getTemp()); + ac.setTemp(kGreeMaxTempC); + EXPECT_EQ(kGreeMaxTempC, ac.getTemp()); - irgree.setTemp(kGreeMinTemp - 1); - EXPECT_EQ(kGreeMinTemp, irgree.getTemp()); + ac.setTemp(kGreeMinTempC - 1); + EXPECT_EQ(kGreeMinTempC, ac.getTemp()); - irgree.setTemp(kGreeMaxTemp + 1); - EXPECT_EQ(kGreeMaxTemp, irgree.getTemp()); + ac.setTemp(kGreeMaxTempC + 1); + EXPECT_EQ(kGreeMaxTempC, ac.getTemp()); - irgree.setTemp(17); - EXPECT_EQ(17, irgree.getTemp()); + ac.setTemp(17); + EXPECT_EQ(17, ac.getTemp()); - irgree.setTemp(21); - EXPECT_EQ(21, irgree.getTemp()); + ac.setTemp(21); + EXPECT_EQ(21, ac.getTemp()); - irgree.setTemp(25); - EXPECT_EQ(25, irgree.getTemp()); + ac.setTemp(25); + EXPECT_EQ(25, ac.getTemp()); - irgree.setTemp(29); - EXPECT_EQ(29, irgree.getTemp()); + ac.setTemp(29); + EXPECT_EQ(29, ac.getTemp()); + + // Fahrenheit tests. + ac.setTemp(kGreeMinTempF, true); + ASSERT_TRUE(ac.getUseFahrenheit()); + EXPECT_EQ(kGreeMinTempF, ac.getTemp()); + + ac.setTemp(kGreeMaxTempF, true); + ASSERT_TRUE(ac.getUseFahrenheit()); + EXPECT_EQ(kGreeMaxTempF, ac.getTemp()); + + ac.setTemp(kGreeMaxTempF + 1, true); + ASSERT_TRUE(ac.getUseFahrenheit()); + EXPECT_EQ(kGreeMaxTempF, ac.getTemp()); + + ac.setTemp(kGreeMaxTempF - 1, true); + ASSERT_TRUE(ac.getUseFahrenheit()); + EXPECT_EQ(kGreeMaxTempF - 1, ac.getTemp()); + + ac.setTemp(kGreeMaxTempF - 2, true); + ASSERT_TRUE(ac.getUseFahrenheit()); + EXPECT_EQ(kGreeMaxTempF - 2, ac.getTemp()); + + ac.setTemp(kGreeMinTempF - 1, true); + ASSERT_TRUE(ac.getUseFahrenheit()); + EXPECT_EQ(kGreeMinTempF, ac.getTemp()); + + ac.setTemp(kGreeMinTempF + 1, true); + ASSERT_TRUE(ac.getUseFahrenheit()); + EXPECT_EQ(kGreeMinTempF + 1, ac.getTemp()); + + ac.setTemp(kGreeMinTempF + 2, true); + ASSERT_TRUE(ac.getUseFahrenheit()); + EXPECT_EQ(kGreeMinTempF + 2, ac.getTemp()); + + // Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1121#issuecomment-628946040 + ac.setUseFahrenheit(false); + const uint8_t state[] = {0x09, 0x01, 0x20, 0x5C, 0x00, 0x20, 0x00, 0x20}; + ac.setRaw(state); + EXPECT_TRUE(ac.getUseFahrenheit()); + EXPECT_EQ(63, ac.getTemp()); + EXPECT_EQ( + "Model: 2 (YBOFB), Power: On, Mode: 1 (Cool), Temp: 63F, Fan: 0 (Auto), " + "Turbo: Off, IFeel: Off, WiFi: Off, XFan: Off, Light: On, Sleep: Off, " + "Swing(V) Mode: Manual, Swing(V): 0 (Last), Timer: Off, " + "Display Temp: 0 (Off)", ac.toString()); } TEST(TestGreeClass, OperatingMode) { - IRGreeAC irgree(0); - irgree.begin(); + IRGreeAC ac(kGpioUnused); + ac.begin(); - irgree.setTemp(17); - irgree.setMode(kGreeAuto); // Auto should lock the temp to 25C. - EXPECT_EQ(kGreeAuto, irgree.getMode()); - EXPECT_EQ(25, irgree.getTemp()); - irgree.setTemp(17); - EXPECT_EQ(25, irgree.getTemp()); + ac.setTemp(17); + ac.setMode(kGreeAuto); // Auto should lock the temp to 25C. + EXPECT_EQ(kGreeAuto, ac.getMode()); + EXPECT_EQ(25, ac.getTemp()); + ac.setTemp(17); + EXPECT_EQ(25, ac.getTemp()); - irgree.setMode(kGreeCool); - EXPECT_EQ(kGreeCool, irgree.getMode()); + ac.setMode(kGreeCool); + EXPECT_EQ(kGreeCool, ac.getMode()); - irgree.setMode(kGreeHeat); - EXPECT_EQ(kGreeHeat, irgree.getMode()); + ac.setMode(kGreeHeat); + EXPECT_EQ(kGreeHeat, ac.getMode()); ASSERT_NE(kGreeFanMax, 1); - irgree.setFan(kGreeFanMax); - irgree.setMode(kGreeDry); // Dry should lock the fan to speed 1. - EXPECT_EQ(kGreeDry, irgree.getMode()); - EXPECT_EQ(1, irgree.getFan()); - irgree.setFan(kGreeFanMax); - EXPECT_EQ(1, irgree.getFan()); + ac.setFan(kGreeFanMax); + ac.setMode(kGreeDry); // Dry should lock the fan to speed 1. + EXPECT_EQ(kGreeDry, ac.getMode()); + EXPECT_EQ(1, ac.getFan()); + ac.setFan(kGreeFanMax); + EXPECT_EQ(1, ac.getFan()); - irgree.setMode(kGreeFan); - EXPECT_EQ(kGreeFan, irgree.getMode()); + ac.setMode(kGreeFan); + EXPECT_EQ(kGreeFan, ac.getMode()); - irgree.setMode(kGreeHeat + 1); - EXPECT_EQ(kGreeAuto, irgree.getMode()); + ac.setMode(kGreeHeat + 1); + EXPECT_EQ(kGreeAuto, ac.getMode()); - irgree.setMode(255); - EXPECT_EQ(kGreeAuto, irgree.getMode()); + ac.setMode(255); + EXPECT_EQ(kGreeAuto, ac.getMode()); } TEST(TestGreeClass, Light) { - IRGreeAC irgree(0); - irgree.begin(); + IRGreeAC ac(kGpioUnused); + ac.begin(); - irgree.setLight(true); - EXPECT_TRUE(irgree.getLight()); + ac.setLight(true); + EXPECT_TRUE(ac.getLight()); - irgree.setLight(false); - EXPECT_FALSE(irgree.getLight()); + ac.setLight(false); + EXPECT_FALSE(ac.getLight()); - irgree.setLight(true); - EXPECT_TRUE(irgree.getLight()); + ac.setLight(true); + EXPECT_TRUE(ac.getLight()); } TEST(TestGreeClass, XFan) { - IRGreeAC irgree(0); - irgree.begin(); + IRGreeAC ac(kGpioUnused); + ac.begin(); - irgree.setXFan(true); - EXPECT_TRUE(irgree.getXFan()); + ac.setXFan(true); + EXPECT_TRUE(ac.getXFan()); - irgree.setXFan(false); - EXPECT_FALSE(irgree.getXFan()); + ac.setXFan(false); + EXPECT_FALSE(ac.getXFan()); - irgree.setXFan(true); - EXPECT_TRUE(irgree.getXFan()); + ac.setXFan(true); + EXPECT_TRUE(ac.getXFan()); } TEST(TestGreeClass, Turbo) { - IRGreeAC irgree(0); - irgree.begin(); + IRGreeAC ac(kGpioUnused); + ac.begin(); - irgree.setTurbo(true); - EXPECT_TRUE(irgree.getTurbo()); + ac.setTurbo(true); + EXPECT_TRUE(ac.getTurbo()); - irgree.setTurbo(false); - EXPECT_FALSE(irgree.getTurbo()); + ac.setTurbo(false); + EXPECT_FALSE(ac.getTurbo()); - irgree.setTurbo(true); - EXPECT_TRUE(irgree.getTurbo()); + ac.setTurbo(true); + EXPECT_TRUE(ac.getTurbo()); } TEST(TestGreeClass, IFeel) { - IRGreeAC ac(0); + IRGreeAC ac(kGpioUnused); ac.begin(); ac.setIFeel(true); @@ -362,7 +408,7 @@ TEST(TestGreeClass, IFeel) { } TEST(TestGreeClass, WiFi) { - IRGreeAC ac(0); + IRGreeAC ac(kGpioUnused); ac.begin(); ac.setWiFi(true); @@ -384,148 +430,150 @@ TEST(TestGreeClass, WiFi) { } TEST(TestGreeClass, Sleep) { - IRGreeAC irgree(0); - irgree.begin(); + IRGreeAC ac(kGpioUnused); + ac.begin(); - irgree.setSleep(true); - EXPECT_TRUE(irgree.getSleep()); + ac.setSleep(true); + EXPECT_TRUE(ac.getSleep()); - irgree.setSleep(false); - EXPECT_FALSE(irgree.getSleep()); + ac.setSleep(false); + EXPECT_FALSE(ac.getSleep()); - irgree.setSleep(true); - EXPECT_TRUE(irgree.getSleep()); + ac.setSleep(true); + EXPECT_TRUE(ac.getSleep()); } TEST(TestGreeClass, FanSpeed) { - IRGreeAC irgree(0); - irgree.begin(); + IRGreeAC ac(kGpioUnused); + ac.begin(); - irgree.setFan(0); - EXPECT_EQ(0, irgree.getFan()); + ac.setFan(0); + EXPECT_EQ(0, ac.getFan()); - irgree.setFan(255); - EXPECT_EQ(kGreeFanMax, irgree.getFan()); + ac.setFan(255); + EXPECT_EQ(kGreeFanMax, ac.getFan()); - irgree.setFan(kGreeFanMax); - EXPECT_EQ(kGreeFanMax, irgree.getFan()); + ac.setFan(kGreeFanMax); + EXPECT_EQ(kGreeFanMax, ac.getFan()); - irgree.setFan(kGreeFanMax + 1); - EXPECT_EQ(kGreeFanMax, irgree.getFan()); + ac.setFan(kGreeFanMax + 1); + EXPECT_EQ(kGreeFanMax, ac.getFan()); - irgree.setFan(kGreeFanMax - 1); - EXPECT_EQ(kGreeFanMax - 1, irgree.getFan()); + ac.setFan(kGreeFanMax - 1); + EXPECT_EQ(kGreeFanMax - 1, ac.getFan()); - irgree.setFan(1); - EXPECT_EQ(1, irgree.getFan()); + ac.setFan(1); + EXPECT_EQ(1, ac.getFan()); - irgree.setFan(1); - EXPECT_EQ(1, irgree.getFan()); + ac.setFan(1); + EXPECT_EQ(1, ac.getFan()); - irgree.setFan(3); - EXPECT_EQ(3, irgree.getFan()); + ac.setFan(3); + EXPECT_EQ(3, ac.getFan()); } TEST(TestGreeClass, VerticalSwing) { - IRGreeAC irgree(0); - irgree.begin(); - EXPECT_FALSE(irgree.getSwingVerticalAuto()); - EXPECT_EQ(kGreeSwingLastPos, irgree.getSwingVerticalPosition()); + IRGreeAC ac(kGpioUnused); + ac.begin(); + EXPECT_FALSE(ac.getSwingVerticalAuto()); + EXPECT_EQ(kGreeSwingLastPos, ac.getSwingVerticalPosition()); - irgree.setSwingVertical(true, kGreeSwingAuto); - EXPECT_TRUE(irgree.getSwingVerticalAuto()); - EXPECT_EQ(kGreeSwingAuto, irgree.getSwingVerticalPosition()); + ac.setSwingVertical(true, kGreeSwingAuto); + EXPECT_TRUE(ac.getSwingVerticalAuto()); + EXPECT_EQ(kGreeSwingAuto, ac.getSwingVerticalPosition()); - irgree.setSwingVertical(false, kGreeSwingMiddle); - EXPECT_FALSE(irgree.getSwingVerticalAuto()); - EXPECT_EQ(kGreeSwingMiddle, irgree.getSwingVerticalPosition()); + ac.setSwingVertical(false, kGreeSwingMiddle); + EXPECT_FALSE(ac.getSwingVerticalAuto()); + EXPECT_EQ(kGreeSwingMiddle, ac.getSwingVerticalPosition()); - irgree.setSwingVertical(true, kGreeSwingDownAuto); - EXPECT_TRUE(irgree.getSwingVerticalAuto()); - EXPECT_EQ(kGreeSwingDownAuto, irgree.getSwingVerticalPosition()); + ac.setSwingVertical(true, kGreeSwingDownAuto); + EXPECT_TRUE(ac.getSwingVerticalAuto()); + EXPECT_EQ(kGreeSwingDownAuto, ac.getSwingVerticalPosition()); // Out of bounds. - irgree.setSwingVertical(false, 255); - EXPECT_FALSE(irgree.getSwingVerticalAuto()); - EXPECT_EQ(kGreeSwingLastPos, irgree.getSwingVerticalPosition()); - irgree.setSwingVertical(false, kGreeSwingAuto); - EXPECT_FALSE(irgree.getSwingVerticalAuto()); - EXPECT_EQ(kGreeSwingLastPos, irgree.getSwingVerticalPosition()); + ac.setSwingVertical(false, 255); + EXPECT_FALSE(ac.getSwingVerticalAuto()); + EXPECT_EQ(kGreeSwingLastPos, ac.getSwingVerticalPosition()); + ac.setSwingVertical(false, kGreeSwingAuto); + EXPECT_FALSE(ac.getSwingVerticalAuto()); + EXPECT_EQ(kGreeSwingLastPos, ac.getSwingVerticalPosition()); - irgree.setSwingVertical(true, 255); - EXPECT_TRUE(irgree.getSwingVerticalAuto()); - EXPECT_EQ(kGreeSwingAuto, irgree.getSwingVerticalPosition()); - irgree.setSwingVertical(true, kGreeSwingDown); - EXPECT_TRUE(irgree.getSwingVerticalAuto()); - EXPECT_EQ(kGreeSwingAuto, irgree.getSwingVerticalPosition()); + ac.setSwingVertical(true, 255); + EXPECT_TRUE(ac.getSwingVerticalAuto()); + EXPECT_EQ(kGreeSwingAuto, ac.getSwingVerticalPosition()); + ac.setSwingVertical(true, kGreeSwingDown); + EXPECT_TRUE(ac.getSwingVerticalAuto()); + EXPECT_EQ(kGreeSwingAuto, ac.getSwingVerticalPosition()); } TEST(TestGreeClass, SetAndGetRaw) { - IRGreeAC irgree(0); + IRGreeAC ac(kGpioUnused); uint8_t initialState[kGreeStateLength] = {0x00, 0x09, 0x20, 0x50, 0x00, 0x20, 0x00, 0x50}; uint8_t expectedState[kGreeStateLength] = {0xA9, 0x05, 0xD0, 0x50, 0x00, 0x20, 0x00, 0xA0}; - EXPECT_STATE_EQ(initialState, irgree.getRaw(), kGreeBits); + EXPECT_STATE_EQ(initialState, ac.getRaw(), kGreeBits); // toggle the power state. - irgree.setPower(!irgree.getPower()); - irgree.setMode(kGreeCool); - irgree.setTemp(21); - irgree.setFan(2); - irgree.setLight(false); - irgree.setTurbo(true); - irgree.setSleep(true); - irgree.setXFan(true); + ac.setPower(!ac.getPower()); + ac.setMode(kGreeCool); + ac.setTemp(21); + ac.setFan(2); + ac.setLight(false); + ac.setTurbo(true); + ac.setSleep(true); + ac.setXFan(true); - EXPECT_EQ(kGreeCool, irgree.getMode()); - EXPECT_EQ(21, irgree.getTemp()); - EXPECT_EQ(2, irgree.getFan()); - EXPECT_FALSE(irgree.getLight()); - EXPECT_TRUE(irgree.getTurbo()); - EXPECT_TRUE(irgree.getSleep()); - EXPECT_TRUE(irgree.getXFan()); + EXPECT_EQ(kGreeCool, ac.getMode()); + EXPECT_EQ(21, ac.getTemp()); + EXPECT_EQ(2, ac.getFan()); + EXPECT_FALSE(ac.getLight()); + EXPECT_TRUE(ac.getTurbo()); + EXPECT_TRUE(ac.getSleep()); + EXPECT_TRUE(ac.getXFan()); - EXPECT_STATE_EQ(expectedState, irgree.getRaw(), kGreeBits); - irgree.setRaw(initialState); - EXPECT_STATE_EQ(initialState, irgree.getRaw(), kGreeBits); + EXPECT_STATE_EQ(expectedState, ac.getRaw(), kGreeBits); + ac.setRaw(initialState); + EXPECT_STATE_EQ(initialState, ac.getRaw(), kGreeBits); } TEST(TestGreeClass, HumanReadable) { - IRGreeAC irgree(0); + IRGreeAC ac(kGpioUnused); EXPECT_EQ( "Model: 1 (YAW1F), Power: Off, Mode: 0 (Auto), Temp: 25C, Fan: 0 (Auto), " "Turbo: Off, IFeel: Off, WiFi: Off, XFan: Off, Light: On, Sleep: Off, " "Swing(V) Mode: Manual, Swing(V): 0 (Last), " - "Timer: Off", - irgree.toString()); - irgree.on(); - irgree.setMode(kGreeCool); - irgree.setTemp(kGreeMinTemp); - irgree.setFan(kGreeFanMax); - irgree.setXFan(true); - irgree.setSleep(true); - irgree.setLight(false); - irgree.setTurbo(true); - irgree.setIFeel(true); - irgree.setWiFi(true); - irgree.setSwingVertical(true, kGreeSwingAuto); - irgree.setTimer(12 * 60 + 30); + "Timer: Off, Display Temp: 0 (Off)", + ac.toString()); + ac.on(); + ac.setMode(kGreeCool); + ac.setTemp(kGreeMinTempC); + ac.setFan(kGreeFanMax); + ac.setXFan(true); + ac.setSleep(true); + ac.setLight(false); + ac.setTurbo(true); + ac.setIFeel(true); + ac.setWiFi(true); + ac.setSwingVertical(true, kGreeSwingAuto); + ac.setTimer(12 * 60 + 30); + ac.setDisplayTempSource(3); EXPECT_EQ( "Model: 1 (YAW1F), Power: On, Mode: 1 (Cool), Temp: 16C, Fan: 3 (High), " "Turbo: On, IFeel: On, WiFi: On, XFan: On, Light: Off, Sleep: On, " - "Swing(V) Mode: Auto, Swing(V): 1 (Auto), Timer: 12:30", - irgree.toString()); + "Swing(V) Mode: Auto, Swing(V): 1 (Auto), Timer: 12:30, " + "Display Temp: 3 (Outside)", + ac.toString()); } // Tests for decodeGree(). // Decode a synthetic Gree message. TEST(TestDecodeGree, NormalSynthetic) { - IRsendTest irsend(4); - IRrecv irrecv(4); + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); irsend.begin(); uint8_t gree_code[kGreeStateLength] = {0x00, 0x09, 0x20, 0x50, @@ -542,9 +590,9 @@ TEST(TestDecodeGree, NormalSynthetic) { // Decode a real Gree message. TEST(TestDecodeGree, NormalRealExample) { - IRsendTest irsend(4); - IRrecv irrecv(4); - IRGreeAC irgree(4); + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + IRGreeAC ac(kGpioUnused); irsend.begin(); uint8_t gree_code[kGreeStateLength] = {0x19, 0x0A, 0x60, 0x50, @@ -572,18 +620,19 @@ TEST(TestDecodeGree, NormalRealExample) { EXPECT_EQ(GREE, irsend.capture.decode_type); ASSERT_EQ(kGreeBits, irsend.capture.bits); EXPECT_STATE_EQ(gree_code, irsend.capture.state, kGreeBits); - irgree.setRaw(irsend.capture.state); + ac.setRaw(irsend.capture.state); EXPECT_EQ( "Model: 1 (YAW1F), Power: On, Mode: 1 (Cool), Temp: 26C, Fan: 1 (Low), " "Turbo: Off, IFeel: Off, WiFi: Off, XFan: Off, Light: On, Sleep: Off, " - "Swing(V) Mode: Manual, Swing(V): 2 (UNKNOWN), Timer: Off", + "Swing(V) Mode: Manual, Swing(V): 2 (UNKNOWN), Timer: Off, " + "Display Temp: 3 (Outside)", IRAcUtils::resultAcToString(&irsend.capture)); stdAc::state_t r, p; ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p)); } TEST(TestGreeClass, toCommon) { - IRGreeAC ac(0); + IRGreeAC ac(kGpioUnused); ac.setPower(true); ac.setMode(kGreeCool); ac.setTemp(20); @@ -616,7 +665,7 @@ TEST(TestGreeClass, toCommon) { } TEST(TestGreeClass, Issue814Power) { - IRGreeAC ac(0); + IRGreeAC ac(kGpioUnused); ac.begin(); // https://github.com/crankyoldgit/IRremoteESP8266/issues/814#issuecomment-511263921 @@ -633,7 +682,8 @@ TEST(TestGreeClass, Issue814Power) { EXPECT_EQ( "Model: 2 (YBOFB), Power: On, Mode: 1 (Cool), Temp: 23C, Fan: 1 (Low), " "Turbo: Off, IFeel: Off, WiFi: Off, XFan: Off, Light: On, Sleep: Off, " - "Swing(V) Mode: Auto, Swing(V): 1 (Auto), Timer: Off", + "Swing(V) Mode: Auto, Swing(V): 1 (Auto), Timer: Off, " + "Display Temp: 0 (Off)", ac.toString()); ac.off(); EXPECT_STATE_EQ(off, ac.getRaw(), kGreeBits); @@ -650,7 +700,7 @@ TEST(TestGreeClass, Issue814Power) { } TEST(TestGreeClass, Timer) { - IRGreeAC ac(0); + IRGreeAC ac(kGpioUnused); ac.begin(); ac.setTimer(0); @@ -689,3 +739,25 @@ TEST(TestGreeClass, Timer) { EXPECT_TRUE(ac.getTimerEnabled()); EXPECT_EQ(24 * 60, ac.getTimer()); } + +TEST(TestGreeClass, DisplayTempSource) { + IRGreeAC ac(kGpioUnused); + ac.begin(); + + ac.setDisplayTempSource(1); + EXPECT_EQ(1, ac.getDisplayTempSource()); + + ac.setDisplayTempSource(2); + EXPECT_EQ(2, ac.getDisplayTempSource()); + + ac.setDisplayTempSource(3); + EXPECT_EQ(3, ac.getDisplayTempSource()); + + ac.setDisplayTempSource(1); + EXPECT_EQ(1, ac.getDisplayTempSource()); + + // Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1118#issuecomment-627674014 + const uint8_t state[8] = {0x4C, 0x04, 0x60, 0x50, 0x01, 0x02, 0x00, 0xA0}; + ac.setRaw(state); + EXPECT_EQ(2, ac.getDisplayTempSource()); +} diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Haier_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Haier_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/ir_Haier_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Haier_test.cpp diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Hitachi_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Hitachi_test.cpp similarity index 89% rename from lib/IRremoteESP8266-2.7.5/test/ir_Hitachi_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Hitachi_test.cpp index aef8008ff..2bbbd29e9 100644 --- a/lib/IRremoteESP8266-2.7.5/test/ir_Hitachi_test.cpp +++ b/lib/IRremoteESP8266-2.7.8/test/ir_Hitachi_test.cpp @@ -811,16 +811,28 @@ TEST(TestUtils, Housekeeping) { ASSERT_EQ(decode_type_t::HITACHI_AC, strToDecodeType("HITACHI_AC")); ASSERT_TRUE(hasACState(decode_type_t::HITACHI_AC)); ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::HITACHI_AC)); + ASSERT_EQ(kHitachiAcBits, + IRsend::defaultBits(decode_type_t::HITACHI_AC)); + ASSERT_EQ(kNoRepeat, + IRsend::minRepeats(decode_type_t::HITACHI_AC)); ASSERT_EQ("HITACHI_AC1", typeToString(decode_type_t::HITACHI_AC1)); ASSERT_EQ(decode_type_t::HITACHI_AC1, strToDecodeType("HITACHI_AC1")); ASSERT_TRUE(hasACState(decode_type_t::HITACHI_AC1)); ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::HITACHI_AC1)); + ASSERT_EQ(kHitachiAc1Bits, + IRsend::defaultBits(decode_type_t::HITACHI_AC1)); + ASSERT_EQ(kNoRepeat, + IRsend::minRepeats(decode_type_t::HITACHI_AC1)); ASSERT_EQ("HITACHI_AC2", typeToString(decode_type_t::HITACHI_AC2)); ASSERT_EQ(decode_type_t::HITACHI_AC2, strToDecodeType("HITACHI_AC2")); ASSERT_TRUE(hasACState(decode_type_t::HITACHI_AC2)); ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::HITACHI_AC2)); + ASSERT_EQ(kHitachiAc2Bits, + IRsend::defaultBits(decode_type_t::HITACHI_AC2)); + ASSERT_EQ(kNoRepeat, + IRsend::minRepeats(decode_type_t::HITACHI_AC2)); ASSERT_EQ("HITACHI_AC3", typeToString(decode_type_t::HITACHI_AC3)); ASSERT_EQ(decode_type_t::HITACHI_AC3, strToDecodeType("HITACHI_AC3")); @@ -831,6 +843,19 @@ TEST(TestUtils, Housekeeping) { ASSERT_EQ(decode_type_t::HITACHI_AC424, strToDecodeType("HITACHI_AC424")); ASSERT_TRUE(hasACState(decode_type_t::HITACHI_AC424)); ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::HITACHI_AC424)); + ASSERT_EQ(kHitachiAc424Bits, + IRsend::defaultBits(decode_type_t::HITACHI_AC424)); + ASSERT_EQ(kNoRepeat, + IRsend::minRepeats(decode_type_t::HITACHI_AC424)); + + ASSERT_EQ("HITACHI_AC344", typeToString(decode_type_t::HITACHI_AC344)); + ASSERT_EQ(decode_type_t::HITACHI_AC344, strToDecodeType("HITACHI_AC344")); + ASSERT_TRUE(hasACState(decode_type_t::HITACHI_AC344)); + ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::HITACHI_AC344)); + ASSERT_EQ(kHitachiAc344Bits, + IRsend::defaultBits(decode_type_t::HITACHI_AC344)); + ASSERT_EQ(kNoRepeat, + IRsend::minRepeats(decode_type_t::HITACHI_AC344)); } // Decode a 'real' HitachiAc424 message. @@ -924,7 +949,7 @@ TEST(TestDecodeHitachiAc424, RealExample) { ac.setRaw(irsend.capture.state); EXPECT_EQ( "Power: On, Mode: 3 (Cool), Temp: 23C, Fan: 5 (Auto), " - "Swing(V) Toggle: Off, Button: 19 (Power/Mode)", + "Button: 19 (Power/Mode), Swing(V) Toggle: Off", IRAcUtils::resultAcToString(&irsend.capture)); stdAc::state_t r, p; ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p)); @@ -1099,29 +1124,29 @@ TEST(TestIRHitachiAc424Class, HumanReadable) { ac.setFan(kHitachiAc424FanHigh); EXPECT_EQ( "Power: On, Mode: 6 (Heat), Temp: 32C, Fan: 4 (High), " - "Swing(V) Toggle: Off, Button: 66 (Fan)", + "Button: 66 (Fan), Swing(V) Toggle: Off", ac.toString()); ac.setMode(kHitachiAc424Cool); ac.setFan(kHitachiAc424FanMin); ac.setTemp(kHitachiAc424MinTemp); EXPECT_EQ( "Power: On, Mode: 3 (Cool), Temp: 16C, Fan: 1 (Min), " - "Swing(V) Toggle: Off, Button: 67 (Temp Down)", + "Button: 67 (Temp Down), Swing(V) Toggle: Off", ac.toString()); ac.setSwingVToggle(true); EXPECT_EQ( "Power: On, Mode: 3 (Cool), Temp: 16C, Fan: 1 (Min), " - "Swing(V) Toggle: On, Button: 129 (Swing(V))", + "Button: 129 (Swing(V)), Swing(V) Toggle: On", ac.toString()); ac.setTemp(ac.getTemp() + 1); EXPECT_EQ( "Power: On, Mode: 3 (Cool), Temp: 17C, Fan: 1 (Min), " - "Swing(V) Toggle: Off, Button: 68 (Temp Up)", + "Button: 68 (Temp Up), Swing(V) Toggle: Off", ac.toString()); ac.setTemp(ac.getTemp() - 1); EXPECT_EQ( "Power: On, Mode: 3 (Cool), Temp: 16C, Fan: 1 (Min), " - "Swing(V) Toggle: Off, Button: 67 (Temp Down)", + "Button: 67 (Temp Down), Swing(V) Toggle: Off", ac.toString()); } @@ -1801,3 +1826,161 @@ TEST(TestIRHitachiAc1Class, FanSpeedInDryMode) { "On Timer: Off, Off Timer: Off", ac.toString()); } + +// Decode a 'real' HitachiAc344 message. +TEST(TestDecodeHitachiAc344, RealExample) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + irsend.begin(); + + uint8_t expected[kHitachiAc344StateLength] = { + 0x01, 0x10, 0x00, 0x40, 0xBF, 0xFF, 0x00, 0xCC, 0x33, 0x98, 0x67, 0x13, + 0xEC, 0x68, 0x97, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, + 0xFF, 0x13, 0xEC, 0xF1, 0x0E, 0x00, 0xFF, 0x00, 0xFF, 0x80, 0x7F, 0x03, + 0xFC, 0x20, 0xDF, 0x00, 0xFF, 0x00, 0xFF}; + + // Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1134#issue-622516158 + const uint16_t rawData[691] = {3410, 1624, 482, 1226, 458, 464, 458, 462, 456, + 464, 460, 460, 462, 460, 460, 462, 460, 460, 460, 462, 460, 462, 456, 466, + 458, 462, 456, 1228, 462, 460, 460, 462, 460, 462, 458, 462, 456, 466, + 456, 464, 458, 464, 456, 466, 460, 460, 460, 462, 460, 460, 458, 464, 456, + 464, 458, 464, 456, 464, 460, 462, 454, 466, 458, 1226, 460, 462, 456, + 1226, 456, 1230, 456, 1228, 456, 1230, 458, 1228, 456, 1228, 456, 464, + 456, 1230, 454, 1230, 458, 1228, 458, 1226, 454, 1230, 454, 1230, 454, + 1230, 458, 1228, 458, 1230, 452, 468, 456, 464, 454, 468, 456, 464, 418, + 502, 456, 466, 458, 464, 458, 462, 458, 464, 454, 468, 456, 1230, 454, + 1230, 454, 466, 456, 464, 456, 1228, 456, 1230, 456, 1230, 456, 1230, 456, + 464, 458, 464, 458, 1228, 456, 1230, 456, 464, 454, 466, 456, 466, 456, + 464, 458, 462, 458, 1228, 458, 1228, 458, 464, 454, 468, 456, 1228, 458, + 1228, 458, 1228, 456, 1228, 456, 464, 454, 468, 456, 1228, 458, 1226, 458, + 464, 458, 1226, 456, 1230, 454, 468, 458, 462, 452, 1232, 460, 462, 458, + 460, 460, 462, 456, 466, 458, 462, 456, 1230, 456, 1228, 460, 462, 460, + 1226, 458, 1228, 458, 1226, 460, 460, 456, 468, 458, 464, 456, 1226, 460, + 462, 458, 1228, 456, 1228, 458, 462, 462, 1224, 460, 1226, 458, 1226, 460, + 464, 458, 1228, 456, 462, 460, 462, 460, 1226, 460, 460, 462, 460, 458, + 462, 458, 462, 456, 464, 460, 460, 462, 460, 462, 460, 460, 1224, 462, + 1224, 462, 1224, 458, 1226, 462, 1224, 460, 1224, 400, 1284, 446, 1240, + 446, 476, 458, 462, 464, 458, 462, 460, 460, 460, 458, 462, 462, 462, 456, + 464, 460, 1226, 460, 1226, 460, 1224, 462, 1224, 460, 1224, 460, 1224, + 460, 1224, 462, 1224, 462, 460, 460, 462, 460, 460, 458, 464, 458, 462, + 458, 464, 458, 462, 460, 460, 462, 1224, 460, 1226, 458, 1228, 456, 1226, + 462, 1222, 460, 1228, 458, 1226, 460, 1226, 460, 460, 458, 462, 460, 462, + 460, 460, 460, 462, 460, 462, 458, 464, 460, 458, 460, 1226, 456, 1228, + 462, 1224, 460, 1224, 458, 1228, 458, 1226, 458, 1228, 462, 1224, 460, + 462, 460, 462, 458, 464, 460, 460, 456, 466, 458, 462, 460, 460, 462, + 458, 460, 1224, 460, 1224, 458, 1226, 460, 1224, 460, 1226, 460, 1226, + 458, 1228, 456, 1230, 456, 1228, 462, 1224, 460, 460, 458, 462, 458, + 1228, 456, 466, 458, 462, 454, 468, 458, 462, 458, 462, 460, 1226, 456, + 1228, 458, 464, 420, 1264, 458, 1228, 458, 1228, 456, 1228, 454, 468, 456, + 464, 456, 466, 456, 1228, 460, 1226, 456, 1230, 456, 1228, 456, 464, 456, + 1230, 458, 1226, 458, 1226, 452, 468, 456, 466, 376, 546, 456, 466, 456, + 464, 456, 466, 458, 464, 458, 464, 456, 466, 424, 496, 456, 464, 416, 504, + 454, 1230, 454, 1232, 456, 1228, 456, 1228, 456, 1230, 456, 1230, 454, + 1230, 460, 1226, 426, 496, 424, 496, 456, 466, 374, 546, 454, 468, 374, + 544, 458, 464, 456, 464, 458, 1228, 424, 1262, 454, 1232, 426, 1258, 458, + 1228, 426, 1260, 454, 1230, 456, 1228, 426, 496, 374, 546, 426, 494, 426, + 496, 424, 496, 426, 496, 424, 496, 456, 1230, 456, 1230, 456, 1228, 458, + 1228, 456, 1230, 456, 1230, 456, 1230, 424, 1260, 458, 464, 426, 1258, + 456, 1230, 422, 500, 456, 466, 418, 504, 424, 496, 426, 496, 456, 464, + 420, 500, 454, 468, 456, 1230, 424, 1260, 420, 1264, 422, 1264, 418, + 1266, 420, 1264, 420, 500, 456, 466, 426, 494, 454, 468, 456, 464, 420, + 1266, 452, 470, 454, 466, 374, 1310, 456, 1228, 456, 1230, 452, 1232, 420, + 1266, 424, 498, 456, 1230, 456, 1230, 456, 466, 450, 470, 456, 464, 376, + 546, 456, 466, 422, 498, 426, 496, 458, 464, 424, 1260, 454, 1232, 454, + 1232, 454, 1232, 458, 1228, 422, 1262, 456, 1228, 454, 1230, 456, 468, + 416, 504, 422, 498, 424, 498, 454, 466, 456, 466, 422, 500, 456, 466, 374, + 1310, 418, 1266, 424, 1262, 422, 1262, 376, 1310, 376, 1308, 422, 1264, + 424, 1262, 350}; // UNKNOWN 919B8582 + + irsend.reset(); + irsend.sendRaw(rawData, 691, kHitachiAcFreq); + irsend.makeDecodeResult(); + EXPECT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(HITACHI_AC344, irsend.capture.decode_type); + ASSERT_EQ(kHitachiAc344Bits, irsend.capture.bits); + EXPECT_STATE_EQ(expected, irsend.capture.state, irsend.capture.bits); +} + +// Decode a synthetic HitachiAc344 message. +TEST(TestDecodeHitachiAc344, SyntheticExample) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + irsend.begin(); + + uint8_t expected[kHitachiAc344StateLength] = { + 0x01, 0x10, 0x00, 0x40, 0xBF, 0xFF, 0x00, 0xCC, 0x33, 0x98, 0x67, 0x13, + 0xEC, 0x68, 0x97, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, + 0xFF, 0x13, 0xEC, 0xF1, 0x0E, 0x00, 0xFF, 0x00, 0xFF, 0x80, 0x7F, 0x03, + 0xFC, 0x20, 0xDF, 0x00, 0xFF, 0x00, 0xFF}; + + irsend.reset(); + irsend.sendHitachiAc344(expected); + irsend.makeDecodeResult(); + EXPECT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(HITACHI_AC344, irsend.capture.decode_type); + ASSERT_EQ(kHitachiAc344Bits, irsend.capture.bits); + EXPECT_STATE_EQ(expected, irsend.capture.state, irsend.capture.bits); + EXPECT_EQ( + "Power: On, Mode: 3 (Cool), Temp: 26C, Fan: 1 (Min), " + "Button: 19 (Power/Mode), Swing(V): On, Swing(H): 3 (Middle)", + IRAcUtils::resultAcToString(&irsend.capture)); +} + +TEST(TestDecodeIRHitachiAc344, ExampleMessages) { + IRHitachiAc344 ac(kGpioUnused); + + // On, 17, Hot, Auto + // Ref: https://docs.google.com/spreadsheets/d/1LPd8K9V437oyEMZT6JDv5LlPXh61RPmgeoVcHLWWr7k/edit#gid=1093727366&range=E21 + // but bit order revered. + const uint8_t state[kHitachiAc344StateLength] = { + 0x01, 0x10, 0x00, 0x40, 0xBF, 0xFF, 0x00, 0xCC, 0x33, 0x92, 0x6D, 0x13, + 0xEC, 0x44, 0xBB, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, + 0xFF, 0x56, 0xA9, 0xF1, 0x0E, 0x00, 0xFF, 0x00, 0xFF, 0x80, 0x7F, 0x03, + 0xFC, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF}; + ac.setRaw(state); + EXPECT_EQ( + "Power: On, Mode: 6 (Heat), Temp: 17C, Fan: 5 (Auto), " + "Button: 19 (Power/Mode), Swing(V): Off, Swing(H): 3 (Middle)", + ac.toString()); +} + +TEST(TestIRHitachiAc344Class, ReconstructKnownState) { + IRHitachiAc344 ac(kGpioUnused); + + // On, 17, Hot, Auto + const uint8_t expected[kHitachiAc344StateLength] = { + 0x01, 0x10, 0x00, 0x40, 0xBF, 0xFF, 0x00, 0xCC, 0x33, 0x92, 0x6D, 0x13, + 0xEC, 0x44, 0xBB, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, + 0xFF, 0x56, 0xA9, 0xF1, 0x0E, 0x00, 0xFF, 0x00, 0xFF, 0x80, 0x7F, 0x03, + 0xFC, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF}; + ac.setMode(kHitachiAc344Heat); + ac.setTemp(17); + ac.setFan(kHitachiAc344FanAuto); + ac.setButton(kHitachiAc344ButtonPowerMode); + EXPECT_STATE_EQ(expected, ac.getRaw(), kHitachiAc344Bits); +} + +TEST(TestIRHitachiAc344Class, SwingV) { + IRHitachiAc344 ac(kGpioUnused); + // Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1134#issuecomment-635760537 + + // https://docs.google.com/spreadsheets/d/1LPd8K9V437oyEMZT6JDv5LlPXh61RPmgeoVcHLWWr7k/edit#gid=874235844&range=G4 + // aka. On 17 Cool Auto SwingV off SwingH off + const uint8_t start[43] = { + 0x01, 0x10, 0x00, 0x40, 0xBF, 0xFF, 0x00, 0xCC, 0x33, 0x92, 0x6D, 0x44, + 0xBB, 0x44, 0xBB, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, + 0xFF, 0x53, 0xAC, 0xF1, 0x0E, 0x00, 0xFF, 0x00, 0xFF, 0x80, 0x7F, 0x03, + 0xFC, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF}; + ac.setRaw(start); + EXPECT_FALSE(ac.getSwingV()); + const uint8_t turn_on_swingv[43] = { + 0x01, 0x10, 0x00, 0x40, 0xBF, 0xFF, 0x00, 0xCC, 0x33, 0x92, 0x6D, 0x81, + 0x7E, 0x44, 0xBB, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, + 0xFF, 0x53, 0xAC, 0xF1, 0x0E, 0x00, 0xFF, 0x00, 0xFF, 0x80, 0x7F, 0x03, + 0xFC, 0x20, 0xDF, 0x00, 0xFF, 0x00, 0xFF}; + ac.setSwingV(true); // Turn it on. + EXPECT_TRUE(ac.getSwingV()); + EXPECT_STATE_EQ(turn_on_swingv, ac.getRaw(), kHitachiAc344Bits); + ac.setSwingV(false); + EXPECT_FALSE(ac.getSwingV()); +} diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Inax_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Inax_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/ir_Inax_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Inax_test.cpp diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_JVC_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_JVC_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/ir_JVC_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_JVC_test.cpp diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Kelvinator_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Kelvinator_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/ir_Kelvinator_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Kelvinator_test.cpp diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_LG_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_LG_test.cpp similarity index 97% rename from lib/IRremoteESP8266-2.7.5/test/ir_LG_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_LG_test.cpp index 3c04c902f..d899576b9 100644 --- a/lib/IRremoteESP8266-2.7.5/test/ir_LG_test.cpp +++ b/lib/IRremoteESP8266-2.7.8/test/ir_LG_test.cpp @@ -6,24 +6,6 @@ #include "IRsend_test.h" #include "gtest/gtest.h" -// Tests for calcLGChecksum() -TEST(TestCalcLGChecksum, General) { - EXPECT_EQ(0x0, calcLGChecksum(0x0)); - EXPECT_EQ(0x1, calcLGChecksum(0x1)); - EXPECT_EQ(0xF, calcLGChecksum(0xF)); - EXPECT_EQ(0x4, calcLGChecksum(0x1111)); - EXPECT_EQ(0x8, calcLGChecksum(0x2222)); - EXPECT_EQ(0x0, calcLGChecksum(0x4444)); - EXPECT_EQ(0xA, calcLGChecksum(0x1234)); - EXPECT_EQ(0xA, calcLGChecksum(0x4321)); - EXPECT_EQ(0xE, calcLGChecksum(0xABCD)); - EXPECT_EQ(0x1, calcLGChecksum(0x4AE5)); - EXPECT_EQ(0xC, calcLGChecksum(0xFFFF)); - EXPECT_EQ(0x1, calcLGChecksum(0xC005)); - EXPECT_EQ(0x1, IRLgAc::calcChecksum(0x88C0051)); - EXPECT_EQ(0x4, calcLGChecksum(0xC035)); - EXPECT_EQ(0x4, IRLgAc::calcChecksum(0x88C0354)); -} // Tests for sendLG(). @@ -670,6 +652,11 @@ TEST(TestIRLgAcClass, isValidLgAc) { ASSERT_FALSE(ac.isValidLgAc()); } +TEST(TestIRLgAcClass, calcChecksum) { + EXPECT_EQ(0x1, IRLgAc::calcChecksum(0x88C0051)); + EXPECT_EQ(0x4, IRLgAc::calcChecksum(0x88C0354)); +} + TEST(TestUtils, Housekeeping) { ASSERT_EQ("LG", typeToString(decode_type_t::LG)); ASSERT_EQ(decode_type_t::LG, strToDecodeType("LG")); diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Lasertag_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Lasertag_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/ir_Lasertag_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Lasertag_test.cpp diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Lego_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Lego_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/ir_Lego_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Lego_test.cpp diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Lutron_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Lutron_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/ir_Lutron_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Lutron_test.cpp diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_MWM_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_MWM_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/ir_MWM_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_MWM_test.cpp diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Magiquest_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Magiquest_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/ir_Magiquest_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Magiquest_test.cpp diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Midea_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Midea_test.cpp similarity index 79% rename from lib/IRremoteESP8266-2.7.5/test/ir_Midea_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Midea_test.cpp index 4c437a576..24c2610a4 100644 --- a/lib/IRremoteESP8266-2.7.5/test/ir_Midea_test.cpp +++ b/lib/IRremoteESP8266-2.7.8/test/ir_Midea_test.cpp @@ -790,3 +790,165 @@ TEST(TestDecodeMidea, Issue887) { EXPECT_EQ(kMideaBits, irsend.capture.bits); EXPECT_EQ(hwaddr, irsend.capture.value); } + +// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1170 +TEST(TestDecodeMidea24, RealExample) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + irsend.begin(); + irsend.reset(); + + const uint16_t rawData[103] = { + 8928, 4412, 590, 1630, 588, 538, 538, 544, 610, 516, 592, 516, 590, 538, + 568, 536, 538, 568, 592, 518, 588, 1630, 588, 1630, 560, 1680, 592, 1628, + 594, 1628, 592, 1650, 568, 1630, 558, 1680, 594, 1652, 568, 514, 592, 536, + 538, 568, 594, 516, 588, 538, 566, 518, 560, 566, 588, 514, 594, 1630, + 588, 1630, 590, 1630, 560, 1680, 594, 1630, 588, 1652, 568, 1650, 540, + 1680, 590, 512, 594, 518, 586, 538, 566, 538, 536, 568, 592, 540, 564, + 540, 566, 540, 538, 1680, 590, 1626, 592, 1630, 588, 1628, 538, 1702, 590, + 1630, 590, 13318, 8916, 2166, 638}; // UNKNOWN 774B249A + + irsend.sendRaw(rawData, 103, 38); + irsend.makeDecodeResult(); + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(MIDEA24, irsend.capture.decode_type); + EXPECT_EQ(kMidea24Bits, irsend.capture.bits); + EXPECT_EQ(0x80C0C0, irsend.capture.value); + EXPECT_EQ(0, irsend.capture.address); + EXPECT_EQ(0, irsend.capture.command); +} + +TEST(TestDecodeMidea24, SyntheticExample) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + irsend.begin(); + irsend.reset(); + + irsend.sendMidea24(0x80C0C0); + irsend.makeDecodeResult(); + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(MIDEA24, irsend.capture.decode_type); + EXPECT_EQ(kMidea24Bits, irsend.capture.bits); + EXPECT_EQ(0x80C0C0, irsend.capture.value); + EXPECT_EQ(0, irsend.capture.address); + EXPECT_EQ(0, irsend.capture.command); + EXPECT_EQ( + "f38000d33" + "m8960s4480" + "m560s1680m560s560m560s560m560s560m560s560m560s560m560s560m560s560" + "m560s560m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680" + "m560s1680m560s1680m560s560m560s560m560s560m560s560m560s560m560s560" + "m560s560m560s560m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680" + "m560s1680m560s1680m560s560m560s560m560s560m560s560m560s560m560s560" + "m560s560m560s560m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680" + "m560s22400" + "m8960s2240m560s96320", + irsend.outputStr()); +} + +TEST(TestUtils, Housekeeping) { + ASSERT_EQ("MIDEA", typeToString(decode_type_t::MIDEA)); + ASSERT_EQ(decode_type_t::MIDEA, strToDecodeType("MIDEA")); + ASSERT_FALSE(hasACState(decode_type_t::MIDEA)); + ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::MIDEA)); + ASSERT_EQ(kNoRepeat, IRsend::minRepeats(decode_type_t::MIDEA)); + ASSERT_EQ(kMideaBits, IRsend::defaultBits(decode_type_t::MIDEA)); + + ASSERT_EQ("MIDEA24", typeToString(decode_type_t::MIDEA24)); + ASSERT_EQ(decode_type_t::MIDEA24, strToDecodeType("MIDEA24")); + ASSERT_FALSE(hasACState(decode_type_t::MIDEA24)); + ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::MIDEA24)); + ASSERT_EQ(kSingleRepeat, IRsend::minRepeats(decode_type_t::MIDEA24)); + ASSERT_EQ(kMidea24Bits, IRsend::defaultBits(decode_type_t::MIDEA24)); +} + +TEST(TestDecodeMidea24, RealExample2) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + irsend.begin(); + irsend.reset(); + + // https://github.com/crankyoldgit/IRremoteESP8266/issues/1170#issuecomment-639271003 + const uint16_t rawData[103] = { + 8926, 4412, 590, 1630, 536, 570, 608, 518, 594, 516, 588, 518, 588, 538, + 538, 568, 592, 514, 590, 518, 588, 1630, 536, 1684, 610, 1628, 594, 1630, + 588, 1630, 590, 1630, 560, 1680, 592, 1630, 588, 1650, 568, 538, 538, 568, + 590, 514, 594, 538, 566, 518, 536, 594, 584, 516, 594, 518, 586, 1630, + 588, 1650, 538, 1682, 592, 1630, 588, 1628, 588, 1630, 560, 1680, 590, + 1626, 594, 538, 566, 538, 568, 536, 538, 570, 590, 538, 566, 538, 568, + 538, 538, 568, 590, 1626, 594, 1650, 568, 1628, 558, 1662, 558, 1680, 592, + 1650, 568, 13312, 8924, 2186, 588}; // UNKNOWN 774B249A + + irsend.sendRaw(rawData, 103, 38); + irsend.makeDecodeResult(); + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(MIDEA24, irsend.capture.decode_type); + EXPECT_EQ(kMidea24Bits, irsend.capture.bits); + EXPECT_EQ(0x80C0C0, irsend.capture.value); + EXPECT_EQ(0, irsend.capture.address); + EXPECT_EQ(0, irsend.capture.command); + + // ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1170#issuecomment-639349316 + const uint16_t rawData639349316[105] = { + 8924, 4410, 596, 1628, 590, 538, 538, 568, 588, 520, 592, 516, 588, 518, + 588, 516, 558, 568, 594, 538, 566, 1652, 568, 1650, 540, 1680, 590, 1628, + 592, 1628, 590, 1628, 590, 1650, 540, 1680, 592, 1630, 590, 518, 586, 538, + 538, 568, 590, 514, 616, 494, 588, 516, 588, 516, 560, 566, 590, 1630, + 586, 1634, 564, 1652, 538, 1704, 566, 948, 254, 450, 564, 1654, 566, + 1652, 540, 1682, 610, 518, 588, 516, 590, 514, 590, 514, 582, 526, 614, + 436, 670, 512, 592, 514, 538, 1578, 718, 1602, 614, 1542, 676, 1626, 538, + 1678, 586, 1634, 616, 13308, 8920, 2158, 626}; // UNKNOWN CBEC0079 + irsend.reset(); + irsend.sendRaw(rawData639349316, 105, 38); + irsend.makeDecodeResult(); + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_NE(MIDEA24, irsend.capture.decode_type); + + // Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1170#issuecomment-639358566 + const uint16_t rawData639358566[103] = { + 8920, 4412, 620, 1606, 614, 512, 592, 512, 536, 568, 618, 512, 590, 492, + 614, 514, 514, 590, 594, 510, 620, 1624, 592, 1604, 590, 1632, 608, 1626, + 606, 1616, 618, 1602, 618, 1602, 560, 1682, 622, 1602, 618, 512, 592, 510, + 538, 568, 590, 512, 622, 488, 616, 490, 614, 488, 560, 568, 620, 1624, + 594, 1604, 616, 1602, 536, 1684, 640, 1600, 618, 1598, 618, 1602, 590, + 1630, 612, 512, 622, 510, 594, 514, 592, 512, 534, 568, 620, 512, 594, + 488, 616, 488, 536, 1702, 594, 1622, 622, 1604, 614, 1624, 594, 1602, 610, + 1630, 620, 13294, 8914, 2184, 596}; // UNKNOWN 774B249A + irsend.reset(); + irsend.sendRaw(rawData639358566, 103, 38); + irsend.makeDecodeResult(); + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(MIDEA24, irsend.capture.decode_type); + EXPECT_EQ(kMidea24Bits, irsend.capture.bits); + EXPECT_EQ(0x80C0C0, irsend.capture.value); + EXPECT_EQ(0, irsend.capture.address); + EXPECT_EQ(0, irsend.capture.command); +} + +// See https://github.com/crankyoldgit/IRremoteESP8266/issues/1170#issuecomment-639468620 +// for why this test exists. +TEST(TestDecodeMidea24, LargeTimeout) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused, 1000, 90); // Test with a large timeout value + irsend.begin(); + irsend.reset(); + // Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1170#issuecomment-639358566 + const uint16_t rawData639358566[103] = { + 8920, 4412, 620, 1606, 614, 512, 592, 512, 536, 568, 618, 512, 590, 492, + 614, 514, 514, 590, 594, 510, 620, 1624, 592, 1604, 590, 1632, 608, 1626, + 606, 1616, 618, 1602, 618, 1602, 560, 1682, 622, 1602, 618, 512, 592, 510, + 538, 568, 590, 512, 622, 488, 616, 490, 614, 488, 560, 568, 620, 1624, + 594, 1604, 616, 1602, 536, 1684, 640, 1600, 618, 1598, 618, 1602, 590, + 1630, 612, 512, 622, 510, 594, 514, 592, 512, 534, 568, 620, 512, 594, + 488, 616, 488, 536, 1702, 594, 1622, 622, 1604, 614, 1624, 594, 1602, 610, + 1630, 620, 13294, 8914, 2184, 596}; // UNKNOWN 774B249A + irsend.reset(); + irsend.sendRaw(rawData639358566, 103, 38); + irsend.makeDecodeResult(); + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(MIDEA24, irsend.capture.decode_type); + EXPECT_EQ(kMidea24Bits, irsend.capture.bits); + EXPECT_EQ(0x80C0C0, irsend.capture.value); + EXPECT_EQ(0, irsend.capture.address); + EXPECT_EQ(0, irsend.capture.command); +} diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_MitsubishiHeavy_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_MitsubishiHeavy_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/ir_MitsubishiHeavy_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_MitsubishiHeavy_test.cpp diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Mitsubishi_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Mitsubishi_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/ir_Mitsubishi_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Mitsubishi_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Multibrackets_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Multibrackets_test.cpp new file mode 100644 index 000000000..7b58b3333 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/test/ir_Multibrackets_test.cpp @@ -0,0 +1,98 @@ +// Copyright 2020 David Conran + +#include "IRac.h" +#include "IRrecv.h" +#include "IRrecv_test.h" +#include "IRsend.h" +#include "IRsend_test.h" +#include "gtest/gtest.h" + +// Tests for decodeMultibrackets(). + +// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1103 + +TEST(TestDecodeMultibrackets, RealExample) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + // The 1 + ok keypress: + uint16_t rawData_1[7] = {20100, 20472, 15092, 30704, 20102, 20472, 15086}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_1, 7, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::MULTIBRACKETS, irsend.capture.decode_type); + ASSERT_EQ(kMultibracketsBits, irsend.capture.bits); + EXPECT_EQ(0x87, irsend.capture.value); + EXPECT_EQ(0x0, irsend.capture.address); + EXPECT_EQ(0x0, irsend.capture.command); + + // ok keypress. + const uint16_t rawData_2[11] = { + 25124, 5108, 5038, 5110, 5034, 40940, 25132, 5108, 5036, 5110, 5036}; + + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_2, 11, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::MULTIBRACKETS, irsend.capture.decode_type); + ASSERT_EQ(kMultibracketsBits, irsend.capture.bits); + EXPECT_EQ(0xD4, irsend.capture.value); + EXPECT_EQ(0x0, irsend.capture.address); + EXPECT_EQ(0x0, irsend.capture.command); +} + +TEST(TestDecodeMultibrackets, SyntheticExample) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + irsend.begin(); + irsend.reset(); + irsend.sendMultibrackets(0x87); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(decode_type_t::MULTIBRACKETS, irsend.capture.decode_type); + EXPECT_EQ(kMultibracketsBits, irsend.capture.bits); + EXPECT_EQ(0x87, irsend.capture.value); + EXPECT_EQ(0x0, irsend.capture.address); + EXPECT_EQ(0x0, irsend.capture.command); + + // Real data is: + // uint16_t rawData[7] = {20100, 20472, 15092, 30704, 20102, 20472, 15086}; + + EXPECT_EQ( + "f38000d50m20000s20000m15000s30000m20000s20000m15000s30000", + irsend.outputStr()); +} + +TEST(TestUtils, Housekeeping) { + ASSERT_EQ("MULTIBRACKETS", typeToString(decode_type_t::MULTIBRACKETS)); + ASSERT_EQ(decode_type_t::MULTIBRACKETS, strToDecodeType("MULTIBRACKETS")); + ASSERT_FALSE(hasACState(decode_type_t::MULTIBRACKETS)); + ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::MULTIBRACKETS)); + ASSERT_EQ(kMultibracketsBits, + IRsend::defaultBits(decode_type_t::MULTIBRACKETS)); + ASSERT_EQ(kMultibracketsDefaultRepeat, + IRsend::minRepeats(decode_type_t::MULTIBRACKETS)); +} + +TEST(TestDecodeMultibrackets, ShortNoRepeatExample) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + // The 1 + ok keypress: (edited to be bare minimum) + uint16_t rawData[3] = {20100, 20472, 15092}; + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData, 3, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::MULTIBRACKETS, irsend.capture.decode_type); + ASSERT_EQ(kMultibracketsBits, irsend.capture.bits); + EXPECT_EQ(0x87, irsend.capture.value); + EXPECT_EQ(0x0, irsend.capture.address); + EXPECT_EQ(0x0, irsend.capture.command); +} diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_NEC_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_NEC_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/ir_NEC_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_NEC_test.cpp diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Neoclima_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Neoclima_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/ir_Neoclima_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Neoclima_test.cpp diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Nikai_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Nikai_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/ir_Nikai_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Nikai_test.cpp diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Panasonic_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Panasonic_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/ir_Panasonic_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Panasonic_test.cpp diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Pioneer_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Pioneer_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/ir_Pioneer_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Pioneer_test.cpp diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Pronto_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Pronto_test.cpp similarity index 69% rename from lib/IRremoteESP8266-2.7.5/test/ir_Pronto_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Pronto_test.cpp index b5020987f..8331192bc 100644 --- a/lib/IRremoteESP8266-2.7.5/test/ir_Pronto_test.cpp +++ b/lib/IRremoteESP8266-2.7.8/test/ir_Pronto_test.cpp @@ -58,7 +58,7 @@ TEST(TestSendPronto, MoreDataThanNeededInNormal) { uint16_t pronto_test[8] = {0x0000, 0x0067, 0x0001, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004}; irsend.sendPronto(pronto_test, 8); - EXPECT_EQ("f40244d50m25s50", + EXPECT_EQ("f40244d50m24s49", irsend.outputStr()); // Only send the data required. } @@ -71,7 +71,7 @@ TEST(TestSendPronto, MoreDataThanNeededInRepeat) { uint16_t pronto_test[8] = {0x0000, 0x0067, 0x0000, 0x0001, 0x0001, 0x0002, 0x0003, 0x0004}; irsend.sendPronto(pronto_test, 8); - EXPECT_EQ("f40244d50m25s50", + EXPECT_EQ("f40244d50m24s49", irsend.outputStr()); // Only send the data required. } @@ -84,10 +84,10 @@ TEST(TestSendPronto, MoreDataThanNeededInBoth) { uint16_t pronto_test[10] = {0x0000, 0x0067, 0x0001, 0x0001, 0x0001, 0x0002, 0x0003, 0x0004, 0x5, 0x6}; irsend.sendPronto(pronto_test, 10); - EXPECT_EQ("f40244d50m25s50", + EXPECT_EQ("f40244d50m24s49", irsend.outputStr()); // Only send the data required. irsend.sendPronto(pronto_test, 10, 1); - EXPECT_EQ("f40244d50m25s50m75s100", + EXPECT_EQ("f40244d50m24s49m74s99", irsend.outputStr()); // Only the data required. } @@ -139,18 +139,18 @@ TEST(TestSendPronto, NonRepeatingCode) { EXPECT_EQ(0x0, irsend.capture.command); EXPECT_EQ( "f40244d50" - "m2400s600" - "m600s600m600s600m600s600m600s600m600s600m600s600m600s600m1200s600" - "m600s600m600s600m600s600m600s27650" - "m2400s600" - "m600s600m600s600m600s600m600s600m600s600m600s600m600s600m1200s600" - "m600s600m600s600m600s600m600s27650" - "m2400s600" - "m600s600m600s600m600s600m600s600m600s600m600s600m600s600m1200s600" - "m600s600m600s600m600s600m600s27650" - "m2400s600" - "m600s600m600s600m600s600m600s600m600s600m600s600m600s600m1200s600" - "m600s600m600s600m600s600m600s600", + "m2390s597" + "m597s597m597s597m597s597m597s597m597s597m597s597m597s597m1195s597" + "m597s597m597s597m597s597m597s27539" + "m2390s597" + "m597s597m597s597m597s597m597s597m597s597m597s597m597s597m1195s597" + "m597s597m597s597m597s597m597s27539" + "m2390s597" + "m597s597m597s597m597s597m597s597m597s597m597s597m597s597m1195s597" + "m597s597m597s597m597s597m597s27539" + "m2390s597" + "m597s597m597s597m597s597m597s597m597s597m597s597m597s597m1195s597" + "m597s597m597s597m597s597m597s597", irsend.outputStr()); // Now try repeating it. @@ -166,18 +166,18 @@ TEST(TestSendPronto, NonRepeatingCode) { EXPECT_EQ(0x0, irsend.capture.command); EXPECT_EQ( "f40244d50" - "m2400s600" - "m600s600m600s600m600s600m600s600m600s600m600s600m600s600m1200s600" - "m600s600m600s600m600s600m600s27650" - "m2400s600" - "m600s600m600s600m600s600m600s600m600s600m600s600m600s600m1200s600" - "m600s600m600s600m600s600m600s27650" - "m2400s600" - "m600s600m600s600m600s600m600s600m600s600m600s600m600s600m1200s600" - "m600s600m600s600m600s600m600s27650" - "m2400s600" - "m600s600m600s600m600s600m600s600m600s600m600s600m600s600m1200s600" - "m600s600m600s600m600s600m600s600", + "m2390s597" + "m597s597m597s597m597s597m597s597m597s597m597s597m597s597m1195s597" + "m597s597m597s597m597s597m597s27539" + "m2390s597" + "m597s597m597s597m597s597m597s597m597s597m597s597m597s597m1195s597" + "m597s597m597s597m597s597m597s27539" + "m2390s597" + "m597s597m597s597m597s597m597s597m597s597m597s597m597s597m1195s597" + "m597s597m597s597m597s597m597s27539" + "m2390s597" + "m597s597m597s597m597s597m597s597m597s597m597s597m597s597m1195s597" + "m597s597m597s597m597s597m597s597", irsend.outputStr()); } @@ -208,10 +208,10 @@ TEST(TestSendPronto, RepeatSequenceOnlyForSony) { EXPECT_EQ(0x24AE, irsend.capture.command); EXPECT_EQ( "f40244d50" - "m2400s600" - "m600s600m1200s600m1200s600m1200s600m600s600m1200s600m600s600m600s600" - "m1200s600m600s600m1200s600m1200s600m1200s600m600s600m600s600m1200s600" - "m600s600m600s600m1200s600m600s25350", + "m2390s597" + "m597s597m1195s597m1195s597m1195s597m597s597m1195s597m597s597m597s597" + "m1195s597m597s597m1195s597m1195s597m1195s597m597s597m597s597m1195s597" + "m597s597m597s597m1195s597m597s25248", irsend.outputStr()); // Send the Pronto code with 2 repeats. @@ -226,18 +226,18 @@ TEST(TestSendPronto, RepeatSequenceOnlyForSony) { EXPECT_EQ(0x24AE, irsend.capture.command); EXPECT_EQ( "f40244d50" - "m2400s600" - "m600s600m1200s600m1200s600m1200s600m600s600m1200s600m600s600m600s600" - "m1200s600m600s600m1200s600m1200s600m1200s600m600s600m600s600m1200s600" - "m600s600m600s600m1200s600m600s25350" - "m2400s600" - "m600s600m1200s600m1200s600m1200s600m600s600m1200s600m600s600m600s600" - "m1200s600m600s600m1200s600m1200s600m1200s600m600s600m600s600m1200s600" - "m600s600m600s600m1200s600m600s25350" - "m2400s600" - "m600s600m1200s600m1200s600m1200s600m600s600m1200s600m600s600m600s600" - "m1200s600m600s600m1200s600m1200s600m1200s600m600s600m600s600m1200s600" - "m600s600m600s600m1200s600m600s25350", + "m2390s597" + "m597s597m1195s597m1195s597m1195s597m597s597m1195s597m597s597m597s597" + "m1195s597m597s597m1195s597m1195s597m1195s597m597s597m597s597m1195s597" + "m597s597m597s597m1195s597m597s25248" + "m2390s597" + "m597s597m1195s597m1195s597m1195s597m597s597m1195s597m597s597m597s597" + "m1195s597m597s597m1195s597m1195s597m1195s597m597s597m597s597m1195s597" + "m597s597m597s597m1195s597m597s25248" + "m2390s597" + "m597s597m1195s597m1195s597m1195s597m597s597m1195s597m597s597m597s597" + "m1195s597m597s597m1195s597m1195s597m1195s597m597s597m597s597m1195s597" + "m597s597m597s597m1195s597m597s25248", irsend.outputStr()); } @@ -274,14 +274,14 @@ TEST(TestSendPronto, RepeatSequenceOnlyForPanasonic) { EXPECT_EQ(0x1007C7D, irsend.capture.command); EXPECT_EQ( "f36682d50" - "m3456s1701" - "m432s432m432s1296m432s432m432s432m432s432m432s432m432s432m432s432" - "m432s432m432s432m432s432m432s432m432s432m432s1296m432s432m432s432" - "m432s432m432s432m432s432m432s432m432s432m432s432m432s432m432s1296" - "m432s432m432s432m432s432m432s432m432s432m432s432m432s432m432s432" - "m432s432m432s1296m432s1296m432s1296m432s1296m432s1296m432s432m432s432" - "m432s432m432s1296m432s1296m432s1296m432s1296m432s1296m432s432m432s1296" - "m432s73224", + "m3494s1719" + "m436s436m436s1310m436s436m436s436m436s436m436s436m436s436m436s436" + "m436s436m436s436m436s436m436s436m436s436m436s1310m436s436m436s436" + "m436s436m436s436m436s436m436s436m436s436m436s436m436s436m436s1310" + "m436s436m436s436m436s436m436s436m436s436m436s436m436s436m436s436" + "m436s436m436s1310m436s1310m436s1310m436s1310m436s1310m436s436m436s436" + "m436s436m436s1310m436s1310m436s1310m436s1310m436s1310m436s436m436s1310" + "m436s74037", irsend.outputStr()); } @@ -315,12 +315,12 @@ TEST(TestSendPronto, NormalPlusRepeatSequence) { EXPECT_EQ(0x8, irsend.capture.command); EXPECT_EQ( "f38028d50" - "m8892s4446" - "m546s546m546s546m546s546m546s1664m546s1664m546s546m546s546m546s546" - "m546s1664m546s1664m546s1664m546s546m546s546m546s1664m546s1664m546s1664" - "m546s546m546s546m546s546m546s1664m546s546m546s546m546s546m546s546" - "m546s1664m546s1664m546s1664m546s546m546s1664m546s1664m546s1664m546s1664" - "m546s39858", + "m8994s4497" + "m552s552m552s552m552s552m552s1683m552s1683m552s552m552s552m552s552" + "m552s1683m552s1683m552s1683m552s552m552s552m552s1683m552s1683m552s1683" + "m552s552m552s552m552s552m552s1683m552s552m552s552m552s552m552s552" + "m552s1683m552s1683m552s1683m552s552m552s1683m552s1683m552s1683m552s1683" + "m552s40317", irsend.outputStr()); // Send it again with a single repeat. @@ -335,13 +335,13 @@ TEST(TestSendPronto, NormalPlusRepeatSequence) { EXPECT_EQ(0x8, irsend.capture.command); EXPECT_EQ( "f38028d50" - "m8892s4446" - "m546s546m546s546m546s546m546s1664m546s1664m546s546m546s546m546s546" - "m546s1664m546s1664m546s1664m546s546m546s546m546s1664m546s1664m546s1664" - "m546s546m546s546m546s546m546s1664m546s546m546s546m546s546m546s546" - "m546s1664m546s1664m546s1664m546s546m546s1664m546s1664m546s1664m546s1664" - "m546s39858" - "m8892s2210m546s95212", + "m8994s4497" + "m552s552m552s552m552s552m552s1683m552s1683m552s552m552s552m552s552" + "m552s1683m552s1683m552s1683m552s552m552s552m552s1683m552s1683m552s1683" + "m552s552m552s552m552s552m552s1683m552s552m552s552m552s552m552s552" + "m552s1683m552s1683m552s1683m552s552m552s1683m552s1683m552s1683m552s1683" + "m552s40317" + "m8994s2235m552s96310", irsend.outputStr()); // Send it again with a two repeats. @@ -356,14 +356,14 @@ TEST(TestSendPronto, NormalPlusRepeatSequence) { EXPECT_EQ(0x8, irsend.capture.command); EXPECT_EQ( "f38028d50" - "m8892s4446" - "m546s546m546s546m546s546m546s1664m546s1664m546s546m546s546m546s546" - "m546s1664m546s1664m546s1664m546s546m546s546m546s1664m546s1664m546s1664" - "m546s546m546s546m546s546m546s1664m546s546m546s546m546s546m546s546" - "m546s1664m546s1664m546s1664m546s546m546s1664m546s1664m546s1664m546s1664" - "m546s39858" - "m8892s2210m546s95212" - "m8892s2210m546s95212", + "m8994s4497" + "m552s552m552s552m552s552m552s1683m552s1683m552s552m552s552m552s552" + "m552s1683m552s1683m552s1683m552s552m552s552m552s1683m552s1683m552s1683" + "m552s552m552s552m552s552m552s1683m552s552m552s552m552s552m552s552" + "m552s1683m552s1683m552s1683m552s552m552s1683m552s1683m552s1683m552s1683" + "m552s40317" + "m8994s2235m552s96310" + "m8994s2235m552s96310", irsend.outputStr()); } @@ -391,3 +391,47 @@ TEST(TestSendPronto, Issue1034) { EXPECT_EQ(0xa3, irsend.capture.address); EXPECT_EQ(0x10, irsend.capture.command); } + +// Tests for #1103 +TEST(TestSendPronto, Issue1103) { + IRsendTest irsend(0); + IRrecv irrecv(0); + irsend.begin(); + // Based on raw data: + // uint16_t rawData[7] = {20100, 20472, 15092, 30704, 20102, 20472, 15086}; + // and output from `raw_to_pronto_code.py --hz 38000`: + // Pronto code = '0000 006D 0004 0000 02FB 0309 023D 048E 02FB 0309 023D 0ED8' + uint16_t pronto_test[12] = { + 0x0000, 0x006D, 0x0004, 0x0000, 0x02FB, 0x0309, 0x023D, 0x048E, + 0x02FB, 0x0309, 0x023D, 0x0ED8}; + irsend.reset(); + irsend.sendPronto(pronto_test, 12); + EXPECT_EQ( + "f38028d50m20066s20435m15069s30665m20066s20435m15069s99940", + irsend.outputStr()); + // Which pretty much matches the `rawData` above. + + // Shorter test. + // uint16_t rawData[4] = {20100, 20472, 15092, 30704}; + // and output from `raw_to_pronto_code.py --hz 38000`: + // Pronto code = '0000 006D 0002 0000 02FB 0309 023D 048E' + uint16_t pronto_test2[8] = { + 0x0000, 0x006D, 0x0002, 0x0000, 0x02FB, 0x0309, 0x023D, 0x048E}; + irsend.reset(); + irsend.sendPronto(pronto_test2, 8); + EXPECT_EQ( + "f38028d50m20066s20435m15069s30665", + irsend.outputStr()); + // Which pretty much matches the `rawData` above. + + // Ref: + // https://github.com/crankyoldgit/IRremoteESP8266/issues/1103#issuecomment-628946514 + uint16_t pronto_test_using_repeat[12] = { + 0x0000, 0x006D, 0x0000, 0x0004, 0x02fb, 0x0309, 0x023d, 0x048e, 0x02fb, + 0x0309, 0x023d, 0x0474}; + irsend.reset(); + irsend.sendPronto(pronto_test_using_repeat, 12); + EXPECT_EQ( + "f38028d50m20066s20435m15069s30665m20066s20435m15069s29982", + irsend.outputStr()); +} diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_RC5_RC6_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_RC5_RC6_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/ir_RC5_RC6_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_RC5_RC6_test.cpp diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_RCMM_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_RCMM_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/ir_RCMM_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_RCMM_test.cpp diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Samsung_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Samsung_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/ir_Samsung_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Samsung_test.cpp diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Sanyo_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Sanyo_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/ir_Sanyo_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Sanyo_test.cpp diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Sharp_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Sharp_test.cpp similarity index 69% rename from lib/IRremoteESP8266-2.7.5/test/ir_Sharp_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Sharp_test.cpp index 173c94f2a..c0c8bd5be 100644 --- a/lib/IRremoteESP8266-2.7.5/test/ir_Sharp_test.cpp +++ b/lib/IRremoteESP8266-2.7.8/test/ir_Sharp_test.cpp @@ -408,8 +408,8 @@ TEST(TestDecodeSharpAc, RealExample) { ASSERT_EQ(SHARP_AC, irsend.capture.decode_type); ASSERT_EQ(kSharpAcBits, irsend.capture.bits); EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits); - EXPECT_EQ("Power: On, Previous Power: On, Mode: 2 (Cool), Temp: 27C, " - "Fan: 2 (Auto)", + EXPECT_EQ("Power: On, Mode: 2 (Cool), Temp: 27C, Fan: 2 (Auto), Turbo: Off, " + "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off", IRAcUtils::resultAcToString(&irsend.capture)); stdAc::state_t r, p; ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p)); @@ -448,23 +448,6 @@ TEST(TestIRUtils, SharpAc) { // Tests for IRSharpAc class. -TEST(TestSharpAcClass, Power) { - IRSharpAc ac(0); - ac.begin(); - - ac.on(); - EXPECT_TRUE(ac.getPower()); - - ac.off(); - EXPECT_FALSE(ac.getPower()); - - ac.setPower(true); - EXPECT_TRUE(ac.getPower()); - - ac.setPower(false); - EXPECT_FALSE(ac.getPower()); -} - TEST(TestSharpAcClass, Checksum) { uint8_t state[kSharpAcStateLength] = { 0xAA, 0x5A, 0xCF, 0x10, 0xCC, 0x31, 0x22, 0x00, 0x08, 0x80, 0x04, 0xE0, @@ -477,7 +460,7 @@ TEST(TestSharpAcClass, Checksum) { } TEST(TestSharpAcClass, Temperature) { - IRSharpAc ac(0); + IRSharpAc ac(kGpioUnused); ac.begin(); ac.setMode(kSharpAcCool); // Cool mode doesn't have temp restrictions. @@ -510,10 +493,20 @@ TEST(TestSharpAcClass, Temperature) { ac.setTemp(29); EXPECT_EQ(29, ac.getTemp()); + + // Auto & Dry have special temps. Per request, we should revert to the + // previous temp when we exit those modes. + + ac.setMode(kSharpAcAuto); + EXPECT_EQ(kSharpAcMinTemp, ac.getTemp()); + ac.setMode(kSharpAcDry); + EXPECT_EQ(kSharpAcMinTemp, ac.getTemp()); + ac.setMode(kSharpAcCool); + EXPECT_EQ(29, ac.getTemp()); } TEST(TestSharpAcClass, OperatingMode) { - IRSharpAc ac(0); + IRSharpAc ac(kGpioUnused); ac.begin(); ac.setTemp(25); @@ -547,7 +540,7 @@ TEST(TestSharpAcClass, OperatingMode) { TEST(TestSharpAcClass, FanSpeed) { - IRSharpAc ac(0); + IRSharpAc ac(kGpioUnused); ac.begin(); // Unexpected value should default to Auto. @@ -582,7 +575,7 @@ TEST(TestSharpAcClass, FanSpeed) { } TEST(TestSharpAcClass, ReconstructKnownState) { - IRSharpAc ac(0); + IRSharpAc ac(kGpioUnused); ac.begin(); uint8_t on_auto_auto[kSharpAcStateLength] = { @@ -593,8 +586,8 @@ TEST(TestSharpAcClass, ReconstructKnownState) { ac.setFan(kSharpAcFanAuto); ac.setMode(kSharpAcAuto); EXPECT_STATE_EQ(on_auto_auto, ac.getRaw(), kSharpAcBits); - EXPECT_EQ("Power: On, Previous Power: Off, Mode: 0 (Auto), Temp: 15C, " - "Fan: 2 (Auto)", + EXPECT_EQ("Power: On, Mode: 0 (Auto), Temp: 15C, Fan: 2 (Auto), Turbo: Off, " + "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off", ac.toString()); uint8_t cool_auto_28[kSharpAcStateLength] = { @@ -605,15 +598,15 @@ TEST(TestSharpAcClass, ReconstructKnownState) { ac.setMode(kSharpAcCool); ac.setFan(kSharpAcFanAuto); ac.setTemp(28); - EXPECT_EQ("Power: On, Previous Power: On, Mode: 2 (Cool), Temp: 28C, " - "Fan: 2 (Auto)", + EXPECT_EQ("Power: On, Mode: 2 (Cool), Temp: 28C, Fan: 2 (Auto), Turbo: Off, " + "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off", ac.toString()); EXPECT_STATE_EQ(cool_auto_28, ac.getRaw(), kSharpAcBits); } // https://github.com/crankyoldgit/IRremoteESP8266/issues/638#issue-421064165 TEST(TestSharpAcClass, KnownStates) { - IRSharpAc ac(0); + IRSharpAc ac(kGpioUnused); ac.begin(); uint8_t off_auto_auto[kSharpAcStateLength] = { @@ -621,65 +614,66 @@ TEST(TestSharpAcClass, KnownStates) { 0x31}; ASSERT_TRUE(ac.validChecksum(off_auto_auto)); ac.setRaw(off_auto_auto); - EXPECT_EQ("Power: Off, Previous Power: On, Mode: 0 (Auto), Temp: 15C, " - "Fan: 2 (Auto)", + EXPECT_EQ("Power: Off, Mode: 0 (Auto), Temp: 15C, Fan: 2 (Auto), Turbo: Off, " + "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off", ac.toString()); uint8_t on_auto_auto[kSharpAcStateLength] = { 0xAA, 0x5A, 0xCF, 0x10, 0x00, 0x11, 0x20, 0x00, 0x08, 0x80, 0x00, 0xE0, 0x01}; ASSERT_TRUE(ac.validChecksum(on_auto_auto)); ac.setRaw(on_auto_auto); - EXPECT_EQ("Power: On, Previous Power: Off, Mode: 0 (Auto), Temp: 15C, " - "Fan: 2 (Auto)", + EXPECT_EQ("Power: On, Mode: 0 (Auto), Temp: 15C, Fan: 2 (Auto), Turbo: Off, " + "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off", ac.toString()); uint8_t cool_auto_28[kSharpAcStateLength] = { 0xAA, 0x5A, 0xCF, 0x10, 0xCD, 0x31, 0x22, 0x00, 0x08, 0x80, 0x04, 0xE0, 0x51}; ASSERT_TRUE(ac.validChecksum(cool_auto_28)); ac.setRaw(cool_auto_28); - EXPECT_EQ("Power: On, Previous Power: On, Mode: 2 (Cool), Temp: 28C, " - "Fan: 2 (Auto)", + EXPECT_EQ("Power: On, Mode: 2 (Cool), Temp: 28C, Fan: 2 (Auto), Turbo: Off, " + "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off", ac.toString()); uint8_t cool_fan1_28[kSharpAcStateLength] = { 0xAA, 0x5A, 0xCF, 0x10, 0xCD, 0x31, 0x42, 0x00, 0x08, 0x80, 0x05, 0xE0, 0x21}; ASSERT_TRUE(ac.validChecksum(cool_fan1_28)); ac.setRaw(cool_fan1_28); - EXPECT_EQ("Power: On, Previous Power: On, Mode: 2 (Cool), Temp: 28C, " - "Fan: 4 (Low)", + EXPECT_EQ("Power: On, Mode: 2 (Cool), Temp: 28C, Fan: 4 (Low), Turbo: Off, " + "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off", ac.toString()); uint8_t cool_fan2_28[kSharpAcStateLength] = { 0xAA, 0x5A, 0xCF, 0x10, 0xCD, 0x31, 0x32, 0x00, 0x08, 0x80, 0x05, 0xE0, 0x51}; ASSERT_TRUE(ac.validChecksum(cool_fan2_28)); ac.setRaw(cool_fan2_28); - EXPECT_EQ("Power: On, Previous Power: On, Mode: 2 (Cool), Temp: 28C, " - "Fan: 3 (Medium)", + EXPECT_EQ("Power: On, Mode: 2 (Cool), Temp: 28C, Fan: 3 (Medium), " + "Turbo: Off, Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off", ac.toString()); uint8_t cool_fan3_28[kSharpAcStateLength] = { 0xAA, 0x5A, 0xCF, 0x10, 0xCD, 0x31, 0x52, 0x00, 0x08, 0x80, 0x05, 0xE0, 0x31}; ASSERT_TRUE(ac.validChecksum(cool_fan3_28)); ac.setRaw(cool_fan3_28); - EXPECT_EQ("Power: On, Previous Power: On, Mode: 2 (Cool), Temp: 28C, " - "Fan: 5 (UNKNOWN)", + EXPECT_EQ("Power: On, Mode: 2 (Cool), Temp: 28C, Fan: 5 (UNKNOWN), " + "Turbo: Off, Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off", ac.toString()); uint8_t cool_fan4_28[kSharpAcStateLength] = { 0xAA, 0x5A, 0xCF, 0x10, 0xCD, 0x31, 0x72, 0x00, 0x08, 0x80, 0x05, 0xE0, 0x11}; ASSERT_TRUE(ac.validChecksum(cool_fan4_28)); ac.setRaw(cool_fan4_28); - EXPECT_EQ("Power: On, Previous Power: On, Mode: 2 (Cool), Temp: 28C, " - "Fan: 7 (High)", + EXPECT_EQ("Power: On, Mode: 2 (Cool), Temp: 28C, Fan: 7 (High), Turbo: Off, " + "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off", ac.toString()); - /* Unsupported / Not yet reverse engineered. uint8_t cool_fan4_28_ion_on[kSharpAcStateLength] = { 0xAA, 0x5A, 0xCF, 0x10, 0xCD, 0x61, 0x72, 0x08, 0x08, 0x80, 0x00, 0xE4, 0xD1}; ASSERT_TRUE(ac.validChecksum(cool_fan4_28_ion_on)); ac.setRaw(cool_fan4_28_ion_on); - EXPECT_EQ("Power: On, Mode: 2 (Cool), Temp: 28C, Fan: 7 (Max)", + EXPECT_EQ("Power: -, Mode: 2 (Cool), Temp: 28C, Fan: 7 (High), Turbo: Off, " + "Swing(V) Toggle: Off, Ion: On, Econo: -, Clean: Off", ac.toString()); + /* Unsupported / Not yet reverse engineered. uint8_t cool_fan4_28_eco1[kSharpAcStateLength] = { 0xAA, 0x5A, 0xCF, 0x10, 0xCD, 0x61, 0x72, 0x18, 0x08, 0x80, 0x00, 0xE8, 0x01}; @@ -692,13 +686,13 @@ TEST(TestSharpAcClass, KnownStates) { 0x11}; ASSERT_TRUE(ac.validChecksum(dry_auto)); ac.setRaw(dry_auto); - EXPECT_EQ("Power: On, Previous Power: On, Mode: 3 (Dry), Temp: 15C, " - "Fan: 2 (Auto)", + EXPECT_EQ("Power: On, Mode: 3 (Dry), Temp: 15C, Fan: 2 (Auto), Turbo: Off, " + "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off", ac.toString()); } TEST(TestSharpAcClass, toCommon) { - IRSharpAc ac(0); + IRSharpAc ac(kGpioUnused); ac.setPower(true); ac.setMode(kSharpAcCool); ac.setTemp(20); @@ -725,32 +719,20 @@ TEST(TestSharpAcClass, toCommon) { ASSERT_EQ(-1, ac.toCommon().clock); } -TEST(TestSharpAcClass, PreviousPower) { +TEST(TestSharpAcClass, Power) { IRSharpAc ac(kGpioUnused); ac.setPower(false, false); EXPECT_FALSE(ac.getPower()); - EXPECT_FALSE(ac.getPreviousPower()); ac.setPower(true); EXPECT_TRUE(ac.getPower()); - EXPECT_FALSE(ac.getPreviousPower()); ac.setPower(false); EXPECT_FALSE(ac.getPower()); - EXPECT_TRUE(ac.getPreviousPower()); - ac.setPower(true); + ac.on(); EXPECT_TRUE(ac.getPower()); - EXPECT_FALSE(ac.getPreviousPower()); - ac.setPower(true); - EXPECT_TRUE(ac.getPower()); - EXPECT_TRUE(ac.getPreviousPower()); - ac.setPreviousPower(false); - EXPECT_TRUE(ac.getPower()); - EXPECT_FALSE(ac.getPreviousPower()); - ac.setPreviousPower(true); - EXPECT_TRUE(ac.getPower()); - EXPECT_TRUE(ac.getPreviousPower()); + ac.off(); + EXPECT_FALSE(ac.getPower()); ac.setPower(true, false); EXPECT_TRUE(ac.getPower()); - EXPECT_FALSE(ac.getPreviousPower()); // Data from: https://github.com/crankyoldgit/IRremoteESP8266/pull/1074#discussion_r403407146 // Command ON (previously OFF) -> 0xAA 5A CF 10 CB 11 22 00 08 80 00 E0 51 @@ -759,21 +741,18 @@ TEST(TestSharpAcClass, PreviousPower) { 0x00, 0x08, 0x80, 0x00, 0xE0, 0x51}; ac.setRaw(on_prev_off); EXPECT_TRUE(ac.getPower()); - EXPECT_FALSE(ac.getPreviousPower()); // Command ON (previously ON) -> 0xAA 5A CF 10 CB 31 22 00 08 80 04 E0 31 const uint8_t on_prev_on[] = { 0xAA, 0x5A, 0xCF, 0x10, 0xCB, 0x31, 0x22, 0x00, 0x08, 0x80, 0x04, 0xE0, 0x31}; ac.setRaw(on_prev_on); EXPECT_TRUE(ac.getPower()); - EXPECT_TRUE(ac.getPreviousPower()); // Command OFF (previously ON) -> 0xAA 5A CF 10 CB 21 22 00 08 80 00 E0 61 const uint8_t off_prev_on[] = { 0xAA, 0x5A, 0xCF, 0x10, 0xCB, 0x21, 0x22, 0x00, 0x08, 0x80, 0x00, 0xE0, 0x61}; ac.setRaw(off_prev_on); EXPECT_FALSE(ac.getPower()); - EXPECT_TRUE(ac.getPreviousPower()); /* Extra test data if needed. // Power:OFF Mode:2(Cool) Fan:2(Auto) Temp:22 const uint8_t collect1[13] = { @@ -810,3 +789,279 @@ TEST(TestSharpAcClass, PreviousPower) { 0x00, 0x08, 0x80, 0x00, 0xE0, 0xB1}; */ } + +TEST(TestSharpAcClass, Turbo) { + IRSharpAc ac(kGpioUnused); + ac.begin(); + + ac.setFan(kSharpAcFanMin); + ac.setTurbo(false); + EXPECT_FALSE(ac.getTurbo()); + EXPECT_EQ(kSharpAcFanMin, ac.getFan()); + + ac.setTurbo(true); + EXPECT_TRUE(ac.getTurbo()); + EXPECT_EQ(kSharpAcFanMax, ac.getFan()); + + ac.setTurbo(false); + EXPECT_FALSE(ac.getTurbo()); + + // ref: https://docs.google.com/spreadsheets/d/1otzVFM5_tegrZ4ROCLgQ_jvJaWCDlZs1vC-YuR1FFXM/edit#gid=0&range=D25 + const uint8_t on_state[] = { + 0xAA, 0x5A, 0xCF, 0x10, 0xC6, 0x61, 0x72, + 0x00, 0x08, 0x80, 0x01, 0xF4, 0xE1}; + const uint8_t off_state[] = { + 0xAA, 0x5A, 0xCF, 0x10, 0xC6, 0x71, 0x72, + 0x00, 0x08, 0x80, 0x01, 0xF4, 0xF1}; + ac.setRaw(on_state); + EXPECT_TRUE(ac.getTurbo()); + EXPECT_EQ(kSharpAcFanMax, ac.getFan()); + EXPECT_EQ( + "Power: -, Mode: 2 (Cool), Temp: 21C, Fan: 7 (High), Turbo: On, " + "Swing(V) Toggle: Off, Ion: On, Econo: -, Clean: Off", + ac.toString()); + + ac.setRaw(off_state); + EXPECT_FALSE(ac.getTurbo()); + EXPECT_EQ( + "Power: -, Mode: 2 (Cool), Temp: 21C, Fan: 7 (High), Turbo: Off, " + "Swing(V) Toggle: Off, Ion: On, Econo: -, Clean: Off", + ac.toString()); +} + +TEST(TestSharpAcClass, SwingToggle) { + IRSharpAc ac(kGpioUnused); + ac.begin(); + + ac.setSwingToggle(false); + EXPECT_FALSE(ac.getSwingToggle()); + + ac.setSwingToggle(true); + EXPECT_TRUE(ac.getSwingToggle()); + + ac.setSwingToggle(false); + EXPECT_FALSE(ac.getSwingToggle()); + + // ref: https://docs.google.com/spreadsheets/d/1otzVFM5_tegrZ4ROCLgQ_jvJaWCDlZs1vC-YuR1FFXM/edit#gid=1057982086&range=C13:E14 + const uint8_t on_state[] = { + 0xAA, 0x5A, 0xCF, 0x10, 0xCA, 0x31, 0x22, + 0x00, 0x0F, 0x80, 0x06, 0xF4, 0x21}; + const uint8_t off_state[] = { + 0xAA, 0x5A, 0xCF, 0x10, 0xC9, 0x31, 0x22, + 0x00, 0x08, 0x80, 0x04, 0xF4, 0x41}; + ac.setRaw(on_state); + EXPECT_TRUE(ac.getSwingToggle()); + + ac.setRaw(off_state); + EXPECT_FALSE(ac.getSwingToggle()); +} + +TEST(TestSharpAcClass, Ion) { + IRSharpAc ac(kGpioUnused); + ac.begin(); + + ac.setIon(false); + EXPECT_FALSE(ac.getIon()); + + ac.setIon(true); + EXPECT_TRUE(ac.getIon()); + + ac.setIon(false); + EXPECT_FALSE(ac.getIon()); + + // ref: https://docs.google.com/spreadsheets/d/1otzVFM5_tegrZ4ROCLgQ_jvJaWCDlZs1vC-YuR1FFXM/edit#gid=1057982086&range=B23:E31 + const uint8_t on_state[] = { + 0xAA, 0x5A, 0xCF, 0x10, 0xCA, 0x61, 0x22, + 0x08, 0x08, 0x80, 0x00, 0xF4, 0xE1}; + const uint8_t off_state[] = { + 0xAA, 0x5A, 0xCF, 0x10, 0xCA, 0x71, 0x22, + 0x08, 0x08, 0x80, 0x00, 0xF0, 0xB1}; + ac.setRaw(on_state); + EXPECT_TRUE(ac.getIon()); + ac.setRaw(off_state); + EXPECT_FALSE(ac.getIon()); +} + +TEST(TestSharpAcClass, Timers) { + IRSharpAc ac(kGpioUnused); + ac.begin(); + + // Off cases + ac.setTimer(false, kSharpAcOffTimerType, 0); + EXPECT_FALSE(ac.getTimerEnabled()); + EXPECT_EQ(kSharpAcOffTimerType, ac.getTimerType()); + EXPECT_EQ(0, ac.getTimerTime()); + + ac.setTimer(false, kSharpAcOnTimerType, 0); + EXPECT_FALSE(ac.getTimerEnabled()); + EXPECT_EQ(kSharpAcOffTimerType, ac.getTimerType()); + EXPECT_EQ(0, ac.getTimerTime()); + + ac.setTimer(true, kSharpAcOnTimerType, 0); + EXPECT_FALSE(ac.getTimerEnabled()); + EXPECT_EQ(kSharpAcOffTimerType, ac.getTimerType()); + EXPECT_EQ(0, ac.getTimerTime()); + + ac.setTimer(false, kSharpAcOffTimerType, 12 * 60); + EXPECT_FALSE(ac.getTimerEnabled()); + EXPECT_EQ(kSharpAcOffTimerType, ac.getTimerType()); + EXPECT_EQ(0, ac.getTimerTime()); + + ac.setTimer(true, kSharpAcOnTimerType, kSharpAcTimerIncrement - 1); + EXPECT_FALSE(ac.getTimerEnabled()); + EXPECT_EQ(kSharpAcOffTimerType, ac.getTimerType()); + EXPECT_EQ(0, ac.getTimerTime()); + + // Trivial cases + ac.setTimer(true, kSharpAcOnTimerType, 30); + EXPECT_TRUE(ac.getTimerEnabled()); + EXPECT_EQ(kSharpAcOnTimerType, ac.getTimerType()); + EXPECT_EQ(30, ac.getTimerTime()); + EXPECT_TRUE(ac.isPowerSpecial()); + + ac.setTimer(true, kSharpAcOffTimerType, 60); + EXPECT_TRUE(ac.getTimerEnabled()); + EXPECT_EQ(kSharpAcOffTimerType, ac.getTimerType()); + EXPECT_EQ(60, ac.getTimerTime()); + + ac.setTimer(true, kSharpAcOnTimerType, 91); + EXPECT_TRUE(ac.getTimerEnabled()); + EXPECT_EQ(kSharpAcOnTimerType, ac.getTimerType()); + EXPECT_EQ(90, ac.getTimerTime()); + + // Bounds checks + ac.setTimer(true, kSharpAcOnTimerType, kSharpAcTimerHoursMax * 60); + EXPECT_TRUE(ac.getTimerEnabled()); + EXPECT_EQ(kSharpAcOnTimerType, ac.getTimerType()); + EXPECT_EQ(kSharpAcTimerHoursMax * 60, ac.getTimerTime()); + + ac.setTimer(false, kSharpAcOffTimerType, 0); // Known good. + ac.setTimer(true, kSharpAcOnTimerType, kSharpAcTimerHoursMax * 60 + + kSharpAcTimerIncrement); + EXPECT_TRUE(ac.getTimerEnabled()); + EXPECT_EQ(kSharpAcOnTimerType, ac.getTimerType()); + EXPECT_EQ(kSharpAcTimerHoursMax * 60, ac.getTimerTime()); + + // ref: https://docs.google.com/spreadsheets/d/1otzVFM5_tegrZ4ROCLgQ_jvJaWCDlZs1vC-YuR1FFXM/edit#gid=0&range=E51 + const uint8_t off_timer_8_5_hrs[] = { + 0xAA, 0x5A, 0xCF, 0x10, 0xC6, 0x81, 0x72, + 0x88, 0x08, 0x80, 0xDE, 0xF4, 0x21}; + ac.setRaw(off_timer_8_5_hrs); + EXPECT_TRUE(ac.getTimerEnabled()); + EXPECT_EQ(kSharpAcOffTimerType, ac.getTimerType()); + EXPECT_EQ(8 * 60 + 30, ac.getTimerTime()); + EXPECT_TRUE(ac.isPowerSpecial()); + EXPECT_EQ( + "Power: -, Mode: 2 (Cool), Temp: 21C, Fan: 7 (High), Turbo: Off, " + "Swing(V) Toggle: Off, Ion: On, Econo: -, Clean: Off, Off Timer: 08:30", + ac.toString()); + + // ref: https://docs.google.com/spreadsheets/d/1otzVFM5_tegrZ4ROCLgQ_jvJaWCDlZs1vC-YuR1FFXM/edit#gid=0&range=E80 + const uint8_t on_timer_12_hrs[] = { + 0xAA, 0x5A, 0xCF, 0x10, 0xC6, 0x81, 0x72, + 0xCC, 0x08, 0x80, 0xC0, 0xF4, 0xD1}; + ac.setRaw(on_timer_12_hrs); + EXPECT_TRUE(ac.getTimerEnabled()); + EXPECT_EQ(kSharpAcOnTimerType, ac.getTimerType()); + EXPECT_EQ(12 * 60, ac.getTimerTime()); + EXPECT_TRUE(ac.isPowerSpecial()); + EXPECT_EQ( + "Power: -, Mode: 2 (Cool), Temp: 21C, Fan: 7 (High), Turbo: Off, " + "Swing(V) Toggle: Off, Ion: On, Econo: -, Clean: Off, On Timer: 12:00", + ac.toString()); +} + +TEST(TestSharpAcClass, Clean) { + IRSharpAc ac(kGpioUnused); + ac.begin(); + + ac.setMode(kSharpAcCool); + ac.setTemp(25); + ASSERT_NE(kSharpAcDry, ac.getMode()); + ASSERT_NE(kSharpAcMinTemp, ac.getTemp()); + ASSERT_NE(kSharpAcFanAuto, ac.getFan()); + + ac.setClean(false); + EXPECT_FALSE(ac.getClean()); + + ac.setClean(true); + EXPECT_TRUE(ac.getClean()); + ASSERT_EQ(kSharpAcDry, ac.getMode()); + ASSERT_EQ(kSharpAcMinTemp, ac.getTemp()); + ASSERT_EQ(kSharpAcFanAuto, ac.getFan()); + + ac.setClean(false); + EXPECT_FALSE(ac.getClean()); + + // ref: https://docs.google.com/spreadsheets/d/1otzVFM5_tegrZ4ROCLgQ_jvJaWCDlZs1vC-YuR1FFXM/edit#gid=1057982086&range=B82:D85 + const uint8_t clean_on_state[] = { + 0xAA, 0x5A, 0xCF, 0x10, 0x00, 0x11, 0x2B, + 0x00, 0x08, 0x80, 0x00, 0xF0, 0xA1}; + const uint8_t clean_off_state[] = { + 0xAA, 0x5A, 0xCF, 0x10, 0xCA, 0x11, 0x72, + 0x00, 0x08, 0x80, 0x00, 0xF0, 0x01}; + ac.setRaw(clean_on_state); + EXPECT_TRUE(ac.getClean()); + EXPECT_EQ( + "Power: On, Mode: 3 (Dry), Temp: 15C, Fan: 2 (Auto), Turbo: Off, " + "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: On", + ac.toString()); + ac.setRaw(clean_off_state); + EXPECT_FALSE(ac.getClean()); + EXPECT_EQ( + "Power: On, Mode: 2 (Cool), Temp: 25C, Fan: 7 (High), Turbo: Off, " + "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off", + ac.toString()); + + // Try constructing the clean on state. + ac.setClean(true); + EXPECT_STATE_EQ(clean_on_state, ac.getRaw(), kSharpAcBits); + + // Try to replicate the exact sequence of commands to activate clean mode + // and compare it to captured values from the real remote. + // Ref: + // https://github.com/crankyoldgit/IRremoteESP8266/issues/1091#issuecomment-622378747 + ac.stateReset(); + // AC OFF (Mode Cool, Temp 25, Ion OFF, Fan 7) + ac.setMode(kSharpAcCool); + ac.setIon(false); + ac.setTemp(25); + ac.setFan(7); + ac.setPower(false); + EXPECT_EQ( + "Power: Off, Mode: 2 (Cool), Temp: 25C, Fan: 7 (High), Turbo: Off, " + "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off", + ac.toString()); + // Clean ON + ac.setClean(true); + EXPECT_EQ( + "Power: On, Mode: 3 (Dry), Temp: 15C, Fan: 2 (Auto), Turbo: Off, " + "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: On", + ac.toString()); + // Clean OFF (state is identical to `off_msg`). + // i.e. It just clears the clean settings & turns off the device. + ac.setClean(false); + ac.setPower(false, true); + EXPECT_EQ( + "Power: Off, Mode: 2 (Cool), Temp: 25C, Fan: 7 (High), Turbo: Off, " + "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off", + ac.toString()); + // Clean ON + ac.setClean(true); + EXPECT_EQ( + "Power: On, Mode: 3 (Dry), Temp: 15C, Fan: 2 (Auto), Turbo: Off, " + "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: On", + ac.toString()); + // AC OFF + ac.off(); + EXPECT_EQ( + "Power: Off, Mode: 2 (Cool), Temp: 25C, Fan: 7 (High), Turbo: Off, " + "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off", + ac.toString()); + // AC ON (Mode Cool, Temp 25, Ion OFF, Fan 7) + ac.on(); + EXPECT_EQ( + "Power: On, Mode: 2 (Cool), Temp: 25C, Fan: 7 (High), Turbo: Off, " + "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off", + ac.toString()); +} diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Sherwood_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Sherwood_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/ir_Sherwood_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Sherwood_test.cpp diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Sony_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Sony_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/ir_Sony_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Sony_test.cpp diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Symphony_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Symphony_test.cpp similarity index 70% rename from lib/IRremoteESP8266-2.7.5/test/ir_Symphony_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Symphony_test.cpp index ee4aadfda..e3f818136 100644 --- a/lib/IRremoteESP8266-2.7.5/test/ir_Symphony_test.cpp +++ b/lib/IRremoteESP8266-2.7.8/test/ir_Symphony_test.cpp @@ -13,15 +13,21 @@ TEST(TestSendSymphony, SendDataOnly) { IRsendTest irsend(kGpioUnused); irsend.begin(); - irsend.sendSymphony(0x137); + irsend.sendSymphony(0xD90); EXPECT_EQ( "f38000d50" "m1250s400m1250s400m400s1250m1250s400m1250s400m400s1250m400s1250m1250s400" "m400s1250m400s1250m400s1250" - "m400s8000" + "m400s7850" "m1250s400m1250s400m400s1250m1250s400m1250s400m400s1250m400s1250m1250s400" "m400s1250m400s1250m400s1250" - "m400s8000", + "m400s7850" + "m1250s400m1250s400m400s1250m1250s400m1250s400m400s1250m400s1250m1250s400" + "m400s1250m400s1250m400s1250" + "m400s7850" + "m1250s400m1250s400m400s1250m1250s400m1250s400m400s1250m400s1250m1250s400" + "m400s1250m400s1250m400s1250" + "m400s7850", irsend.outputStr()); } @@ -69,7 +75,7 @@ TEST(TestDecodeSymphony, RealMessageDecode) { EXPECT_TRUE(irrecv.decode(&irsend.capture)); EXPECT_EQ(decode_type_t::SYMPHONY, irsend.capture.decode_type); EXPECT_EQ(kSymphonyBits, irsend.capture.bits); - EXPECT_EQ(0x137, irsend.capture.value); + EXPECT_EQ(0xD90, irsend.capture.value); EXPECT_EQ(0x0, irsend.capture.address); EXPECT_EQ(0x0, irsend.capture.command); EXPECT_FALSE(irsend.capture.repeat); @@ -81,10 +87,10 @@ TEST(TestDecodeSymphony, RealMessageDecode) { 1198, 1284, 396, 444, 1224, 470, 1200, 470, 1198, 472}; irsend.sendRaw(power, 23, 38000); irsend.makeDecodeResult(); - EXPECT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_TRUE(irrecv.decodeSymphony(&irsend.capture)); EXPECT_EQ(decode_type_t::SYMPHONY, irsend.capture.decode_type); EXPECT_EQ(kSymphonyBits, irsend.capture.bits); - EXPECT_EQ(0x137, irsend.capture.value); + EXPECT_EQ(0xD90, irsend.capture.value); EXPECT_EQ(0x0, irsend.capture.address); EXPECT_EQ(0x0, irsend.capture.command); EXPECT_FALSE(irsend.capture.repeat); @@ -98,7 +104,7 @@ TEST(TestDecodeSymphony, RealMessageDecode) { EXPECT_TRUE(irrecv.decode(&irsend.capture)); EXPECT_EQ(decode_type_t::SYMPHONY, irsend.capture.decode_type); EXPECT_EQ(kSymphonyBits, irsend.capture.bits); - EXPECT_EQ(0x13E, irsend.capture.value); + EXPECT_EQ(0xD82, irsend.capture.value); EXPECT_EQ(0x0, irsend.capture.address); EXPECT_EQ(0x0, irsend.capture.command); EXPECT_FALSE(irsend.capture.repeat); @@ -122,7 +128,7 @@ TEST(TestDecodeSymphony, RealMessageSentViaLibrary) { EXPECT_TRUE(irrecv.decode(&irsend.capture)); EXPECT_EQ(decode_type_t::SYMPHONY, irsend.capture.decode_type); EXPECT_EQ(kSymphonyBits, irsend.capture.bits); - EXPECT_EQ(0x137, irsend.capture.value); + EXPECT_EQ(0xD90, irsend.capture.value); EXPECT_EQ(0x0, irsend.capture.address); EXPECT_EQ(0x0, irsend.capture.command); EXPECT_FALSE(irsend.capture.repeat); @@ -139,12 +145,47 @@ TEST(TestDecodeSymphony, RealMessageSentViaLibrary) { EXPECT_TRUE(irrecv.decode(&irsend.capture)); EXPECT_EQ(decode_type_t::SYMPHONY, irsend.capture.decode_type); EXPECT_EQ(kSymphonyBits, irsend.capture.bits); - EXPECT_EQ(0x137, irsend.capture.value); + EXPECT_EQ(0xD90, irsend.capture.value); EXPECT_EQ(0x0, irsend.capture.address); EXPECT_EQ(0x0, irsend.capture.command); EXPECT_FALSE(irsend.capture.repeat); } +// Decode a real SM5021 generated message. +// Note: This used to fail because it had a "long" mark before the gap in mesg. +TEST(TestDecodeSymphony, Issue1105) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + irsend.begin(); + + // Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1105#issuecomment-625327833 + irsend.reset(); + uint16_t rawData[191] = { + 1324, 372, 1322, 398, 448, 1218, 476, 1216, 478, 1216, 478, 1218, 478, + 1218, 476, 1218, 476, 1220, 474, 1220, 474, 1220, 1346, 7128, 1320, 402, + 1290, 404, 440, 1252, 442, 1254, 440, 1254, 440, 1254, 440, 1254, 440, + 1254, 440, 1254, 442, 1254, 440, 1254, 1288, 7186, 1288, 408, 1286, 408, + 438, 1254, 440, 1254, 440, 1254, 440, 1254, 440, 1254, 440, 1256, 440, + 1254, 440, 1254, 440, 1254, 1288, 7186, 1288, 408, 1286, 408, 438, 1254, + 440, 1256, 440, 1254, 440, 1254, 440, 1254, 440, 1254, 438, 1256, 438, + 1256, 440, 1254, 1288, 7188, 1288, 408, 1286, 408, 438, 1256, 438, 1256, + 440, 1254, 438, 1256, 438, 1256, 438, 1256, 438, 1256, 438, 1256, 440, + 1254, 1288, 7188, 1286, 408, 1286, 408, 440, 1254, 438, 1256, 438, 1256, + 438, 1256, 440, 1254, 438, 1254, 440, 1256, 438, 1256, 440, 1256, 438, + 8038, 1284, 408, 1286, 408, 438, 1282, 412, 1282, 414, 1280, 414, 1280, + 414, 1282, 414, 1280, 412, 1276, 412, 1286, 414, 1282, 412, 8062, 1260, + 434, 1262, 432, 414, 1280, 414, 1282, 412, 1282, 412, 1282, 412, 1282, + 414, 1280, 414, 1282, 412, 1282, 412, 1282, 412}; // UNKNOWN 827AA7B + irsend.sendRaw(rawData, 191, 38000); + irsend.makeDecodeResult(); + EXPECT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(decode_type_t::SYMPHONY, irsend.capture.decode_type); + EXPECT_EQ(kSymphonyBits, irsend.capture.bits); + EXPECT_EQ(0xC01, irsend.capture.value); + EXPECT_EQ(0x0, irsend.capture.address); + EXPECT_EQ(0x0, irsend.capture.command); + EXPECT_FALSE(irsend.capture.repeat); +} TEST(TestUtils, Housekeeping) { ASSERT_EQ("SYMPHONY", typeToString(decode_type_t::SYMPHONY)); diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Tcl_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Tcl_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/ir_Tcl_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Tcl_test.cpp diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Teco_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Teco_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/ir_Teco_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Teco_test.cpp diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Toshiba_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Toshiba_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/ir_Toshiba_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Toshiba_test.cpp diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Trotec_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Trotec_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/ir_Trotec_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Trotec_test.cpp diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Vestel_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Vestel_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/ir_Vestel_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Vestel_test.cpp diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Whirlpool_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Whirlpool_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/ir_Whirlpool_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Whirlpool_test.cpp diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Whynter_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Whynter_test.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/test/ir_Whynter_test.cpp rename to lib/IRremoteESP8266-2.7.8/test/ir_Whynter_test.cpp diff --git a/lib/IRremoteESP8266-2.7.8/test/ir_Zepeal_test.cpp b/lib/IRremoteESP8266-2.7.8/test/ir_Zepeal_test.cpp new file mode 100644 index 000000000..12240d2f7 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/test/ir_Zepeal_test.cpp @@ -0,0 +1,312 @@ +// Copyright 2020 Christian Nilsson + +#include "IRac.h" +#include "IRrecv.h" +#include "IRrecv_test.h" +#include "IRsend.h" +#include "IRsend_test.h" +#include "gtest/gtest.h" + +// Tests for decodeZepeal(). + +TEST(TestDecodeZepeal, RealExample) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + // fuuryou (speed) one of 5 repeats + const uint16_t rawData_1[35] = { + 2328, 3412, + 424, 1314, 1302, 436, 1276, 454, 424, 1316, + 1274, 464, 1274, 458, 454, 1278, 450, 1288, + 1302, 432, 424, 1306, 424, 1306, 424, 1306, + 428, 1304, 450, 1290, 1298, 430, 426, 1308, + 426}; // UNKNOWN B5E66F84 + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_1, 35, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::ZEPEAL, irsend.capture.decode_type); + ASSERT_EQ(kZepealBits, irsend.capture.bits); + EXPECT_EQ(0x6C82, irsend.capture.value); + EXPECT_EQ(0x0, irsend.capture.address); + EXPECT_EQ(0x0, irsend.capture.command); + + // kiri/iri (off/on) short press + const uint16_t rawData_2[179] = { + 2338, 3384, + 426, 1314, 1300, 436, 1304, 428, 424, 1314, + 1302, 440, 1300, 428, 424, 1306, 424, 1314, + 1300, 432, 400, 1330, 400, 1332, 418, 1316, + 422, 1308, 424, 1308, 400, 1338, 1300, 432, + 426, 6728, + 2352, 3384, + 426, 1312, 1302, 436, 1276, 438, 442, 1316, + 1300, 434, 1302, 430, 424, 1308, 422, 1298, + 1318, 414, 468, 1280, 426, 1306, 452, 1280, + 450, 1282, 400, 1332, 400, 1338, 1302, 412, + 416, 6760, + 2350, 3384, + 400, 1340, 1300, 438, 1300, 412, 444, 1312, + 1302, 434, 1302, 412, 442, 1308, 426, 1312, + 1302, 430, 422, 1308, 424, 1304, 400, 1332, + 424, 1306, 402, 1332, 422, 1318, 1300, 430, + 398, 6754, + 2354, 3364, + 442, 1316, 1300, 438, 1300, 430, 422, 1316, + 1328, 410, 1302, 430, 400, 1332, 400, 1338, + 1302, 412, 418, 1334, 398, 1314, 444, 1306, + 400, 1330, 424, 1308, 424, 1314, 1300, 430, + 428, 6774, + 2334, 3384, + 400, 1338, 1302, 436, 1304, 430, 396, 1340, + 1300, 436, 1302, 432, 452, 1280, 398, 1338, + 1302, 428, 402, 1330, 426, 1310, 422, 1306, + 426, 1306, 426, 1306, 404, 1336, 1274, 458, + 424}; // UNKNOWN C2DCDDE5 + + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_2, 179, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::ZEPEAL, irsend.capture.decode_type); + ASSERT_EQ(kZepealBits, irsend.capture.bits); + EXPECT_EQ(0x6C81, irsend.capture.value); + EXPECT_EQ(0x0, irsend.capture.address); + EXPECT_EQ(0x0, irsend.capture.command); + + EXPECT_EQ( + "f38000d50" + "m2338s3384" + "m426s1314m1300s436m1304s428m424s1314m1302s440m1300s428m424s1306m424s1314" + "m1300s432m400s1330m400s1332m418s1316m422s1308m424s1308m400s1338m1300s432" + "m426s6728" + "m2352s3384" + "m426s1312m1302s436m1276s438m442s1316m1300s434m1302s430m424s1308m422s1298" + "m1318s414m468s1280m426s1306m452s1280m450s1282m400s1332m400s1338m1302s412" + "m416s6760" + "m2350s3384" + "m400s1340m1300s438m1300s412m444s1312m1302s434m1302s412m442s1308m426s1312" + "m1302s430m422s1308m424s1304m400s1332m424s1306m402s1332m422s1318m1300s430" + "m398s6754" + "m2354s3364" + "m442s1316m1300s438m1300s430m422s1316m1328s410m1302s430m400s1332m400s1338" + "m1302s412m418s1334m398s1314m444s1306m400s1330m424s1308m424s1314m1300s430" + "m428s6774" + "m2334s3384" + "m400s1338m1302s436m1304s430m396s1340m1300s436m1302s432m452s1280m398s1338" + "m1302s428m402s1330m426s1310m422s1306m426s1306m426s1306m404s1336m1274s458" + "m424", + irsend.outputStr()); + + // rizumu/oyasumi (rhythm/sleep - mode) + const uint16_t rawData_3[143] = { + 2354, 3386, + 422, 1312, 1278, 462, 1300, 410, 442, 1316, + 1300, 436, 1302, 412, 448, 1304, 398, 1338, + 1300, 430, 426, 1306, 426, 1304, 400, 1332, + 400, 1340, 1300, 430, 400, 1334, 426, 1304, + 398, 6756, + 2354, 3382, + 424, 1294, 1346, 410, 1302, 410, 418, 1340, + 1300, 434, 1304, 430, 398, 1332, 400, 1338, + 1276, 456, 400, 1334, 400, 1330, 400, 1332, + 398, 1342, 1298, 430, 422, 1308, 400, 1332, + 398, 6754, + 2356, 3382, + 400, 1340, 1274, 464, 1298, 412, 444, 1314, + 1300, 438, 1300, 412, 442, 1308, 400, 1338, + 1300, 414, 418, 1330, 400, 1332, 400, 1330, + 426, 1312, 1332, 380, 446, 1306, 424, 1308, + 424, 6736, + 2352, 3380, + 402, 1338, 1302, 436, 1300, 412, 420, 1338, + 1300, 436, 1300, 412, 418, 1332, 402, 1336, + 1302, 408, 418, 1332, 424, 1308, 424, 1306, + 398, 1340, 1276, 454, 400, 1314, 418, 1332, + 426}; // UNKNOWN 712E7A7F + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_3, 143, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::ZEPEAL, irsend.capture.decode_type); + ASSERT_EQ(kZepealBits, irsend.capture.bits); + EXPECT_EQ(0x6C84, irsend.capture.value); + EXPECT_EQ(0x0, irsend.capture.address); + EXPECT_EQ(0x0, irsend.capture.command); + + // kiri taimaa (off timer) + const uint16_t rawData_4[143] = { + 2308, 3392, + 444, 1314, 1302, 436, 1330, 382, 420, 1338, + 1302, 436, 1302, 408, 444, 1308, 450, 1288, + 1300, 410, 420, 1332, 424, 1308, 400, 1338, + 1302, 430, 428, 1286, 444, 1306, 452, 1282, + 424, 6728, + 2354, 3362, + 444, 1314, 1274, 464, 1302, 410, 420, 1338, + 1300, 438, 1328, 384, 444, 1308, 398, 1338, + 1274, 456, 424, 1306, 402, 1332, 424, 1312, + 1302, 412, 442, 1308, 424, 1308, 398, 1334, + 422, 6752, + 2336, 3382, + 422, 1316, 1302, 434, 1302, 430, 400, 1340, + 1302, 434, 1302, 410, 444, 1310, 422, 1314, + 1302, 410, 444, 1304, 428, 1304, 426, 1312, + 1302, 428, 424, 1308, 424, 1308, 426, 1304, + 426, 6736, + 2354, 3382, + 424, 1314, 1302, 438, 1300, 410, 418, 1338, + 1304, 436, 1304, 406, 418, 1336, 398, 1338, + 1300, 432, 424, 1306, 426, 1306, 450, 1286, + 1302, 412, 418, 1336, 396, 1334, 424, 1306, + 424}; // UNKNOWN AAD01FEF + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_4, 143, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::ZEPEAL, irsend.capture.decode_type); + ASSERT_EQ(kZepealBits, irsend.capture.bits); + EXPECT_EQ(0x6C88, irsend.capture.value); + EXPECT_EQ(0x0, irsend.capture.address); + EXPECT_EQ(0x0, irsend.capture.command); + + // iri taimaa (on timer) + const uint16_t rawData_5[143] = { + 2364, 3358, + 424, 1316, 1298, 438, 1300, 432, 424, 1314, + 1298, 440, 1300, 430, 424, 1310, 424, 1312, + 1300, 436, 1302, 430, 424, 1308, 422, 1308, + 424, 1308, 424, 1314, 1302, 438, 1302, 430, + 422, 6730, + 2354, 3384, + 422, 1314, 1300, 438, 1302, 426, 426, 1312, + 1300, 438, 1302, 412, 418, 1330, 426, 1316, + 1302, 434, 1302, 430, 426, 1306, 424, 1306, + 424, 1308, 426, 1312, 1302, 436, 1302, 430, + 428, 6752, + 2364, 3354, + 428, 1308, 1304, 436, 1302, 428, 426, 1314, + 1330, 408, 1304, 428, 402, 1330, 398, 1338, + 1306, 432, 1280, 454, 426, 1302, 428, 1304, + 430, 1302, 428, 1310, 1306, 434, 1304, 428, + 428, 6788, + 2336, 3382, + 428, 1310, 1302, 434, 1304, 430, 426, 1310, + 1306, 434, 1304, 430, 424, 1306, 402, 1336, + 1302, 438, 1304, 426, 426, 1304, 402, 1330, + 426, 1304, 400, 1336, 1306, 434, 1304, 428, + 424}; // UNKNOWN F8FC587 + irsend.begin(); + irsend.reset(); + irsend.sendRaw(rawData_5, 143, 38); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + ASSERT_EQ(decode_type_t::ZEPEAL, irsend.capture.decode_type); + ASSERT_EQ(kZepealBits, irsend.capture.bits); + EXPECT_EQ(0x6CC3, irsend.capture.value); + EXPECT_EQ(0x0, irsend.capture.address); + EXPECT_EQ(0x0, irsend.capture.command); +} + +TEST(TestDecodeZepeal, SyntheticExample) { + IRsendTest irsend(kGpioUnused); + IRrecv irrecv(kGpioUnused); + irsend.begin(); + irsend.reset(); + // power + irsend.sendZepeal(0x6C81); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(decode_type_t::ZEPEAL, irsend.capture.decode_type); + EXPECT_EQ(kZepealBits, irsend.capture.bits); + EXPECT_EQ(0x6C81, irsend.capture.value); + EXPECT_EQ(0x0, irsend.capture.address); + EXPECT_EQ(0x0, irsend.capture.command); + + EXPECT_EQ( + "f38000d50" + "m2330s3380" + "m420s1300m1300s420m1300s420m420s1300m1300s420m1300s420m420s1300m420s1300" + "m1300s420m420s1300m420s1300m420s1300m420s1300m420s1300m420s1300m1300s420" + "m420s6750" + "m2330s3380" + "m420s1300m1300s420m1300s420m420s1300m1300s420m1300s420m420s1300m420s1300" + "m1300s420m420s1300m420s1300m420s1300m420s1300m420s1300m420s1300m1300s420" + "m420s6750" + "m2330s3380" + "m420s1300m1300s420m1300s420m420s1300m1300s420m1300s420m420s1300m420s1300" + "m1300s420m420s1300m420s1300m420s1300m420s1300m420s1300m420s1300m1300s420" + "m420s6750" + "m2330s3380" + "m420s1300m1300s420m1300s420m420s1300m1300s420m1300s420m420s1300m420s1300" + "m1300s420m420s1300m420s1300m420s1300m420s1300m420s1300m420s1300m1300s420" + "m420s6750" + "m2330s3380" + "m420s1300m1300s420m1300s420m420s1300m1300s420m1300s420m420s1300m420s1300" + "m1300s420m420s1300m420s1300m420s1300m420s1300m420s1300m420s1300m1300s420" + "m420s6750", + irsend.outputStr()); + + irsend.reset(); + irsend.sendZepeal(0x6Cff, kZepealBits, kNoRepeat); + irsend.makeDecodeResult(); + + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(decode_type_t::ZEPEAL, irsend.capture.decode_type); + EXPECT_EQ(kZepealBits, irsend.capture.bits); + EXPECT_EQ(0x6Cff, irsend.capture.value); + EXPECT_EQ(0x0, irsend.capture.address); + EXPECT_EQ(0x0, irsend.capture.command); + EXPECT_EQ( + "f38000d50" + "m2330s3380" + "m420s1300m1300s420m1300s420m420s1300m1300s420m1300s420m420s1300m420s1300" + "m1300s420m1300s420m1300s420m1300s420m1300s420m1300s420m1300s420m1300s420" + "m420s6750", + irsend.outputStr()); + + irsend.reset(); + // testing a non valid value + irsend.sendZepeal(0xffff, kZepealBits, kNoRepeat); + irsend.makeDecodeResult(); + + // strict check should fail + ASSERT_FALSE(irrecv.decodeZepeal(&irsend.capture, kStartOffset, + kZepealBits, true)); + ASSERT_TRUE(irrecv.decode(&irsend.capture)); + EXPECT_EQ(-1, irsend.capture.decode_type); + + // non strict check should be ok + ASSERT_TRUE(irrecv.decodeZepeal(&irsend.capture, kStartOffset, + kZepealBits, false)); + EXPECT_EQ(decode_type_t::ZEPEAL, irsend.capture.decode_type); + EXPECT_EQ(kZepealBits, irsend.capture.bits); + EXPECT_EQ(0xffff, irsend.capture.value); + EXPECT_EQ(0x0, irsend.capture.address); + EXPECT_EQ(0x0, irsend.capture.command); + EXPECT_EQ( + "f38000d50" + "m2330s3380" + "m1300s420m1300s420m1300s420m1300s420m1300s420m1300s420m1300s420m1300s420" + "m1300s420m1300s420m1300s420m1300s420m1300s420m1300s420m1300s420m1300s420" + "m420s6750", + irsend.outputStr()); +} + +TEST(TestUtils, Housekeeping) { + ASSERT_EQ("ZEPEAL", typeToString(decode_type_t::ZEPEAL)); + ASSERT_EQ(decode_type_t::ZEPEAL, strToDecodeType("ZEPEAL")); + ASSERT_FALSE(hasACState(decode_type_t::ZEPEAL)); + ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::ZEPEAL)); + ASSERT_EQ(kZepealBits, IRsend::defaultBits(decode_type_t::ZEPEAL)); + ASSERT_EQ(kZepealMinRepeat, IRsend::minRepeats(decode_type_t::ZEPEAL)); +} diff --git a/lib/IRremoteESP8266-2.7.8/tools/Makefile b/lib/IRremoteESP8266-2.7.8/tools/Makefile new file mode 100644 index 000000000..b30d1207c --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/tools/Makefile @@ -0,0 +1,88 @@ +# SYNOPSIS: +# +# make [all] - makes everything. +# make clean - removes all files generated by make. + +# Please tweak the following variable definitions as needed by your +# project, except GTEST_HEADERS, which you can use in your own targets +# but shouldn't modify. + + +# Where to find user code. +USER_DIR = ../src + +# Where to find test code. +TEST_DIR = ../test + +INCLUDES = -I$(USER_DIR) -I$(TEST_DIR) +# 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 += -DUNIT_TEST -D_IR_LOCALE_=en-AU + +# Flags passed to the C++ compiler. +CXXFLAGS += -g -Wall -Wextra -pthread -std=gnu++11 + +all : gc_decode mode2_decode + +run_tests : all + failed=""; \ + for py_unittest in *_test.py; do \ + echo "RUNNING: $${py_unittest}"; \ + python3 ./$${py_unittest} || failed="$${failed} $${py_unittest}"; \ + done; \ + if [ -n "$${failed}" ]; then \ + echo "FAIL: :-( :-( Unit test(s)$${failed} failed! :-( :-("; exit 1; \ + else \ + echo "PASS: \o/ \o/ All unit tests passed. \o/ \o/"; \ + fi + +clean : + rm -f *.o *.pyc gc_decode mode2_decode + + +# Keep all intermediate files. +.SECONDARY: + +# All the IR protocol object files. +PROTOCOL_OBJS = $(patsubst %.cpp,%.o,$(wildcard $(USER_DIR)/ir_*.cpp)) +PROTOCOLS = $(patsubst $(USER_DIR)/%,%,$(PROTOCOL_OBJS)) + +# Common object files +COMMON_OBJ = IRutils.o IRtimer.o IRsend.o IRrecv.o IRtext.o IRac.o $(PROTOCOLS) + +# Common dependencies +COMMON_DEPS = $(USER_DIR)/IRrecv.h $(USER_DIR)/IRsend.h $(USER_DIR)/IRtimer.h \ + $(USER_DIR)/IRutils.h $(USER_DIR)/IRremoteESP8266.h \ + $(TEST_DIR)/IRsend_test.h $(USER_DIR)/IRtext.h $(USER_DIR)/i18n.h +# Common test dependencies +COMMON_TEST_DEPS = $(COMMON_DEPS) $(TEST_DIR)/IRsend_test.h + +IRtext.o : $(USER_DIR)/IRtext.cpp $(USER_DIR)/IRtext.h $(USER_DIR)/IRremoteESP8266.h $(USER_DIR)/i18n.h $(USER_DIR)/locale/*.h + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/IRtext.cpp + +IRutils.o : $(USER_DIR)/IRutils.cpp $(USER_DIR)/IRutils.h $(USER_DIR)/IRremoteESP8266.h + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/IRutils.cpp + +IRsend.o : $(USER_DIR)/IRsend.cpp $(USER_DIR)/IRsend.h $(USER_DIR)/IRremoteESP8266.h + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/IRsend.cpp + +IRrecv.o : $(USER_DIR)/IRrecv.cpp $(USER_DIR)/IRrecv.h $(USER_DIR)/IRremoteESP8266.h $(GTEST_HEADERS) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/IRrecv.cpp + +# new specific targets goes above this line + +%_decode : $(COMMON_OBJ) %_decode.o + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ + +ir_%.o : $(USER_DIR)/ir_%.h $(USER_DIR)/ir_%.cpp $(COMMON_DEPS) $(GTEST_HEADERS) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_$*.cpp + +ir_%.o : $(USER_DIR)/ir_%.cpp $(GTEST_HEADERS) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_$*.cpp + +%.o : %.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $*.cpp + +%.o : $(USER_DIR)/%.cpp $(USER_DIR)/%.h $(COMMON_DEPS) $(GTEST_HEADERS) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/$*.cpp diff --git a/lib/IRremoteESP8266-2.7.5/tools/RawToGlobalCache.sh b/lib/IRremoteESP8266-2.7.8/tools/RawToGlobalCache.sh old mode 100755 new mode 100644 similarity index 100% rename from lib/IRremoteESP8266-2.7.5/tools/RawToGlobalCache.sh rename to lib/IRremoteESP8266-2.7.8/tools/RawToGlobalCache.sh diff --git a/lib/IRremoteESP8266-2.7.5/tools/auto_analyse_raw_data.py b/lib/IRremoteESP8266-2.7.8/tools/auto_analyse_raw_data.py old mode 100755 new mode 100644 similarity index 87% rename from lib/IRremoteESP8266-2.7.5/tools/auto_analyse_raw_data.py rename to lib/IRremoteESP8266-2.7.8/tools/auto_analyse_raw_data.py index 5bea3926a..3b22ea12d --- a/lib/IRremoteESP8266-2.7.5/tools/auto_analyse_raw_data.py +++ b/lib/IRremoteESP8266-2.7.8/tools/auto_analyse_raw_data.py @@ -7,6 +7,8 @@ import argparse import sys +SAFE64NOTE = "--safe64note--" +CODEGEN = "--codegen--" class RawIRMessage(): """Basic analyse functions & structure for raw IR messages.""" @@ -359,10 +361,14 @@ def parse_and_report(rawdata_str, margin, gen_code=False, name="", """Analyse the rawdata c++ definition of a IR message.""" defines = [] code = {} + code["sendcomhead"] = [] code["send"] = [] code["send64+"] = [] + code["sendcomfoot"] = [] + code["recvcomhead"] = [] code["recv"] = [] code["recv64+"] = [] + code["recvcomfoot"] = [] # Parse the input. rawdata = convert_rawdata(rawdata_str) @@ -401,53 +407,71 @@ def decode_data(message, defines, code, name="", output=sys.stdout): else: def_name = "TBD" - code["send"].extend([ + code["sendcomhead"].extend([ + "", "#if SEND_%s" % def_name.upper(), - "// Function should be safe up to 64 bits.", + SAFE64NOTE, + "/// Send a %s formatted message." % name, + "/// Status: ALPHA / Untested."]) + code["send"].extend([ + "/// @param[in] data containing the IR command.", + "/// @param[in] nbits Nr. of bits to send. usually k%sBits" % name, + "/// @param[in] repeat Nr. of times the message is to be repeated.", "void IRsend::send%s(const uint64_t data, const uint16_t" " nbits, const uint16_t repeat) {" % def_name, " enableIROut(k%sFreq);" % name, " for (uint16_t r = 0; r <= repeat; r++) {", " uint64_t send_data = data;"]) code["send64+"].extend([ - "// Args:", - "// data: An array of bytes containing the IR command.", - "// It is assumed to be in MSB order for this code.\n" - "// nbytes: Nr. of bytes of data in the array." + "/// @param[in] data An array of bytes containing the IR command.", + "/// It is assumed to be in MSB order for this code.", + "/// e.g.", + "/// @code", + CODEGEN, + "/// @endcode", + "/// @param[in] nbytes Nr. of bytes of data in the array." " (>=k%sStateLength)" % name, - "// repeat: Nr. of times the message is to be repeated.", - "//", - "// Status: ALPHA / Untested.", + "/// @param[in] repeat Nr. of times the message is to be repeated.", "void IRsend::send%s(const uint8_t data[], const uint16_t nbytes," " const uint16_t repeat) {" % def_name, " for (uint16_t r = 0; r <= repeat; r++) {", " uint16_t pos = 0;"]) - code["recv"].extend([ + code["sendcomfoot"].extend([ + " }", + "}", + "#endif // SEND_%s" % def_name.upper()]) + code["recvcomhead"].extend([ + "", "#if DECODE_%s" % def_name.upper(), - "// Function should be safe up to 64 bits.", - "bool IRrecv::decode%s(decode_results *results, const uint16_t nbits," - " const bool strict) {" % def_name, - " if (results->rawlen < 2 * nbits + k%sOverhead)" % name, + SAFE64NOTE, + "/// Decode the supplied %s message." % name, + "/// Status: ALPHA / Untested.", + "/// @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::decode%s(decode_results *results, uint16_t offset," + " const uint16_t nbits, const bool strict) {" % def_name, + " if (results->rawlen < 2 * nbits + k%sOverhead - offset)" % name, " return false; // Too short a message to match.", " if (strict && nbits != k%sBits)" % name, " return false;", - "", - " uint16_t offset = kStartOffset;", + ""]) + code["recv"].extend([ " uint64_t data = 0;", " match_result_t data_result;"]) code["recv64+"].extend([ - "#if DECODE_%s" % def_name.upper(), - "// Function should be safe over 64 bits.", - "bool IRrecv::decode%s(decode_results *results, const uint16_t nbits," - " const bool strict) {" % def_name, - " if (results->rawlen < 2 * nbits + k%sOverhead)" % name, - " return false; // Too short a message to match.", - " if (strict && nbits != k%sBits)" % name, - " return false;", - "", - " uint16_t offset = kStartOffset;", " uint16_t pos = 0;", " uint16_t used = 0;"]) + code["recvcomfoot"].extend([ + " return true;", + "}", + "#endif // DECODE_%s" % def_name.upper()]) # states are: # HM: Header/Leader mark @@ -582,14 +606,7 @@ def decode_data(message, defines, code, name="", output=sys.stdout): message.section_count = message.section_count + 1 code["send"].extend([ " space(kDefaultMessageGap); // A 100% made up guess of the gap" - " between messages.", - " }", - "}", - "#endif // SEND_%s" % def_name.upper()]) - code["send64+"].extend([ - " }", - "}", - "#endif // SEND_%s" % def_name.upper()]) + " between messages."]) code["recv"].extend([ "", " // Success", @@ -597,18 +614,12 @@ def decode_data(message, defines, code, name="", output=sys.stdout): " results->bits = nbits;", " results->value = data;", " results->command = 0;", - " results->address = 0;", - " return true;", - "}", - "#endif // DECODE_%s" % def_name.upper()]) + " results->address = 0;"]) code["recv64+"].extend([ "", " // Success", " results->decode_type = decode_type_t::%s;" % def_name.upper(), - " results->bits = nbits;", - " return true;", - "}", - "#endif // DECODE_%s" % def_name.upper()]) + " results->bits = nbits;"]) total_bits = total_bits + binary_value output.write("\nTotal Nr. of suspected bits: %d\n" % len(total_bits)) @@ -625,13 +636,17 @@ def decode_data(message, defines, code, name="", output=sys.stdout): def generate_code(defines, code, bits_str, name="", output=sys.stdout): """Output the estimated C++ code to reproduce & decode the IR message.""" + # pylint: disable=too-many-branches if name: def_name = name else: def_name = "TBD" output.write("\nGenerating a VERY rough code outline:\n\n" - "// Copyright 2019 David Conran (crankyoldgit)\n" - "// Support for %s protocol\n\n" + "// Copyright 2020 David Conran (crankyoldgit)\n" + "/// @file\n" + "/// @brief Support for %s protocol\n\n" + "// Supports:\n" + "// Brand: %s, Model: TODO add device and remote\n\n" '#include "IRrecv.h"\n' '#include "IRsend.h"\n' '#include "IRutils.h"\n\n' @@ -640,7 +655,7 @@ def generate_code(defines, code, bits_str, name="", output=sys.stdout): "// See https://github.com/crankyoldgit/IRremoteESP8266/wiki/" "Adding-support-for-a-new-IR-protocol\n" "// for details of how to include this in the library." - "\n" % def_name) + "\n" % (def_name, def_name)) for line in defines: output.write("%s\n" % line) @@ -649,38 +664,70 @@ def generate_code(defines, code, bits_str, name="", output=sys.stdout): "'data' won't work!\n") # Display the "normal" version's send code incase there are some # oddities in it. - for line in code["send"]: + for line in code["sendcomhead"] + code["send"] + code["sendcomfoot"]: + if line == SAFE64NOTE: + line = "// Function should be safe up to 64 bits." output.write("%s\n" % line) if len(bits_str) > 64: # Will it fit in a uint64_t? - code["send64+"] = [ - "", - "#if SEND_%s" % def_name.upper(), - "// Alternative >64bit function to send %s messages" % def_name.upper(), - "// Where data is:", - "// uint8_t data[k%sStateLength] = {0x%s};" % ( + for line in code["sendcomhead"] + code["send64+"] + code["sendcomfoot"]: + if line == SAFE64NOTE: + line = "// Alternative >64bit function to send %s messages\n" % \ + def_name.upper() + "// Function should be safe over 64 bits." + elif line == CODEGEN: + line = "/// uint8_t data[k%sStateLength] = {0x%s};" % ( name, ", 0x".join("%02X" % int(bits_str[i:i + 8], 2) - for i in range(0, len(bits_str), 8))), - "//"] + code["send64+"] - for line in code["send64+"]: + for i in range(0, len(bits_str), 8))) output.write("%s\n" % line) - output.write("\n") if len(bits_str) > 64: # Will it fit in a uint64_t? - output.write("// DANGER: More than 64 bits detected. A uint64_t for " - "'data' won't work!\n") + output.write("\n// DANGER: More than 64 bits detected. A uint64_t for " + "'data' won't work!") + # Display the "normal" version's decode code incase there are some # oddities in it. - for line in code["recv"]: + for line in code["recvcomhead"] + code["recv"] + code["recvcomfoot"]: + if line == SAFE64NOTE: + line = "// Function should be safe up to 64 bits." output.write("%s\n" % line) + # Display the > 64bit version's decode code if len(bits_str) > 64: # Is it too big for a uint64_t? - output.write("\n// Note: This should be 64+ bit safe.\n") if len(bits_str) % 8: output.write("\n// WARNING: Data is not a multiple of bytes. " "This won't work!\n") - for line in code["recv64+"]: + for line in code["recvcomhead"] + code["recv64+"] + code["recvcomfoot"]: + if line == SAFE64NOTE: + line = "// Function should be safe over 64 bits." output.write("%s\n" % line) +def add_rawdata_args(parser): + """Add the arguments for feeding in the rawdata string(s).""" + arg_group = parser.add_mutually_exclusive_group(required=True) + arg_group.add_argument( + "rawdata", + help="A rawData line from IRrecvDumpV2+. e.g. 'uint16_t rawbuf[37] = {" + "7930, 3952, 494, 1482, 520, 1482, 494, 1508, 494, 520, 494, 1482, 494, " + "520, 494, 1482, 494, 1482, 494, 3978, 494, 520, 494, 520, 494, 520, " + "494, 520, 520, 520, 494, 520, 494, 520, 494, 520, 494};'", + nargs="?") + arg_group.add_argument( + "-f", "--file", help="Read in a rawData line from the file.") + arg_group.add_argument( + "--stdin", + help="Read in a rawData line from STDIN.", + action="store_true", + default=False) + +def get_rawdata(arg_options): + """Return the rawdata string(s) as per the options.""" + if arg_options.stdin: + return sys.stdin.read() + if arg_options.file: + with open(arg_options.file) as input_file: + return input_file.read() + else: + return arg_options.rawdata + def main(): """Parse the commandline arguments and call the method.""" @@ -701,16 +748,6 @@ def main(): help="Name of the protocol/device to use in code generation. E.g. Onkyo", dest="name", default="") - arg_group = arg_parser.add_mutually_exclusive_group(required=True) - arg_group.add_argument( - "rawdata", - help="A rawData line from IRrecvDumpV2. e.g. 'uint16_t rawbuf[37] = {" - "7930, 3952, 494, 1482, 520, 1482, 494, 1508, 494, 520, 494, 1482, 494, " - "520, 494, 1482, 494, 1482, 494, 3978, 494, 520, 494, 520, 494, 520, " - "494, 520, 520, 520, 494, 520, 494, 520, 494, 520, 494};'", - nargs="?") - arg_group.add_argument( - "-f", "--file", help="Read in a rawData line from the file.") arg_parser.add_argument( "-r", "--range", @@ -719,22 +756,17 @@ def main(): " it the same value.", dest="margin", default=200) - arg_group.add_argument( - "--stdin", - help="Read in a rawData line from STDIN.", - action="store_true", - default=False) + add_rawdata_args(arg_parser) arg_options = arg_parser.parse_args() - if arg_options.stdin: - data = sys.stdin.read() - elif arg_options.file: - with open(arg_options.file) as input_file: - data = input_file.read() - else: - data = arg_options.rawdata - parse_and_report(data, arg_options.margin, arg_options.gen_code, - arg_options.name) + raw_data = get_rawdata(arg_options).strip() + if not raw_data: + arg_parser.print_help(sys.stderr) + sys.stderr.write("error: no rawdata content\n") + sys.exit(1) + + parse_and_report(raw_data, arg_options.margin, + arg_options.gen_code, arg_options.name) if __name__ == '__main__': diff --git a/lib/IRremoteESP8266-2.7.5/tools/auto_analyse_raw_data_test.py b/lib/IRremoteESP8266-2.7.8/tools/auto_analyse_raw_data_test.py old mode 100755 new mode 100644 similarity index 86% rename from lib/IRremoteESP8266-2.7.5/tools/auto_analyse_raw_data_test.py rename to lib/IRremoteESP8266-2.7.8/tools/auto_analyse_raw_data_test.py index fa3a87933..1b080c5a8 --- a/lib/IRremoteESP8266-2.7.5/tools/auto_analyse_raw_data_test.py +++ b/lib/IRremoteESP8266-2.7.8/tools/auto_analyse_raw_data_test.py @@ -279,8 +279,12 @@ class TestAutoAnalyseRawData(unittest.TestCase): '\n' 'Generating a VERY rough code outline:\n' '\n' - '// Copyright 2019 David Conran (crankyoldgit)\n' - '// Support for FOO protocol\n' + '// Copyright 2020 David Conran (crankyoldgit)\n' + '/// @file\n' + '/// @brief Support for FOO protocol\n' + '\n' + '// Supports:\n' + '// Brand: FOO, Model: TODO add device and remote\n' '\n' '#include "IRrecv.h"\n' '#include "IRsend.h"\n' @@ -300,8 +304,14 @@ class TestAutoAnalyseRawData(unittest.TestCase): ' frequency.)\n' 'const uint16_t kFOOBits = 16; // Move to IRremoteESP8266.h\n' 'const uint16_t kFOOOverhead = 5;\n' + '\n' '#if SEND_FOO\n' '// Function should be safe up to 64 bits.\n' + '/// Send a FOO formatted message.\n' + '/// Status: ALPHA / Untested.\n' + '/// @param[in] data containing the IR command.\n' + '/// @param[in] nbits Nr. of bits to send. usually kFOOBits\n' + '/// @param[in] repeat Nr. of times the message is to be repeated.\n' 'void IRsend::sendFOO(const uint64_t data, const uint16_t nbits,' ' const uint16_t repeat) {\n' ' enableIROut(kFOOFreq);\n' @@ -333,14 +343,24 @@ class TestAutoAnalyseRawData(unittest.TestCase): '\n' '#if DECODE_FOO\n' '// Function should be safe up to 64 bits.\n' - 'bool IRrecv::decodeFOO(decode_results *results, const uint16_t nbits,' - ' const bool strict) {\n' - ' if (results->rawlen < 2 * nbits + kFOOOverhead)\n' + '/// Decode the supplied FOO message.\n' + '/// Status: ALPHA / Untested.\n' + '/// @param[in,out] results Ptr to the data to decode &' + ' where to store the decode\n' + '/// @param[in] offset The starting index to use when' + ' attempting to decode the\n' + '/// raw data. Typically/Defaults to kStartOffset.\n' + '/// @param[in] nbits The number of data bits to expect.\n' + '/// @param[in] strict Flag indicating if we should perform strict' + ' matching.\n' + "/// @return A boolean. True if it can decode it, false if it can't.\n" + 'bool IRrecv::decodeFOO(decode_results *results, uint16_t offset,' + ' const uint16_t nbits, const bool strict) {\n' + ' if (results->rawlen < 2 * nbits + kFOOOverhead - offset)\n' ' return false; // Too short a message to match.\n' ' if (strict && nbits != kFOOBits)\n' ' return false;\n' '\n' - ' uint16_t offset = kStartOffset;\n' ' uint64_t data = 0;\n' ' match_result_t data_result;\n' '\n' @@ -540,8 +560,12 @@ class TestAutoAnalyseRawData(unittest.TestCase): '\n' 'Generating a VERY rough code outline:\n' '\n' - '// Copyright 2019 David Conran (crankyoldgit)\n' - '// Support for Hitachi protocol\n' + '// Copyright 2020 David Conran (crankyoldgit)\n' + '/// @file\n' + '/// @brief Support for Hitachi protocol\n' + '\n' + '// Supports:\n' + '// Brand: Hitachi, Model: TODO add device and remote\n' '\n' '#include "IRrecv.h"\n' '#include "IRsend.h"\n' @@ -567,8 +591,14 @@ class TestAutoAnalyseRawData(unittest.TestCase): 'const uint16_t kHitachiOverhead = 5;\n' "// DANGER: More than 64 bits detected. A uint64_t for 'data' won't" ' work!\n' + '\n' '#if SEND_HITACHI\n' '// Function should be safe up to 64 bits.\n' + '/// Send a Hitachi formatted message.\n' + '/// Status: ALPHA / Untested.\n' + '/// @param[in] data containing the IR command.\n' + '/// @param[in] nbits Nr. of bits to send. usually kHitachiBits\n' + '/// @param[in] repeat Nr. of times the message is to be repeated.\n' 'void IRsend::sendHitachi(const uint64_t data, const uint16_t nbits,' ' const uint16_t repeat) {\n' ' enableIROut(kHitachiFreq);\n' @@ -598,22 +628,23 @@ class TestAutoAnalyseRawData(unittest.TestCase): '\n' '#if SEND_HITACHI\n' '// Alternative >64bit function to send HITACHI messages\n' - '// Where data is:\n' - '// uint8_t data[kHitachiStateLength] = {0x80, 0x08, 0x00, 0x02,' + '// Function should be safe over 64 bits.\n' + '/// Send a Hitachi formatted message.\n' + '/// Status: ALPHA / Untested.\n' + '/// @param[in] data An array of bytes containing the IR command.\n' + '/// It is assumed to be in MSB order for this code.\n' + '/// e.g.\n' + '/// @code\n' + '/// uint8_t data[kHitachiStateLength] = {0x80, 0x08, 0x00, 0x02,' ' 0xFD, 0xFF, 0x00, 0x33, 0xCC, 0x49, 0xB6, 0xC8, 0x37, 0x3A, 0xC5,' ' 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xCA,' ' 0x35, 0x8F, 0x70, 0x00, 0xFF, 0x00, 0xFF, 0x01, 0xFE, 0xC0, 0x3F,' ' 0x80, 0x7F, 0x11, 0xEE, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF,' ' 0x00, 0xFF, 0x00, 0xFF, 0x00};\n' - '//\n' - '// Args:\n' - '// data: An array of bytes containing the IR command.\n' - '// It is assumed to be in MSB order for this code.\n' - '// nbytes: Nr. of bytes of data in the array.' + '/// @endcode\n' + '/// @param[in] nbytes Nr. of bytes of data in the array.' ' (>=kHitachiStateLength)\n' - '// repeat: Nr. of times the message is to be repeated.\n' - '//\n' - '// Status: ALPHA / Untested.\n' + '/// @param[in] repeat Nr. of times the message is to be repeated.\n' 'void IRsend::sendHitachi(const uint8_t data[], const uint16_t nbytes,' ' const uint16_t repeat) {\n' ' for (uint16_t r = 0; r <= repeat; r++) {\n' @@ -642,14 +673,24 @@ class TestAutoAnalyseRawData(unittest.TestCase): ' work!\n' '#if DECODE_HITACHI\n' '// Function should be safe up to 64 bits.\n' - 'bool IRrecv::decodeHitachi(decode_results *results,' + '/// Decode the supplied Hitachi message.\n' + '/// Status: ALPHA / Untested.\n' + '/// @param[in,out] results Ptr to the data to decode &' + ' where to store the decode\n' + '/// @param[in] offset The starting index to use when' + ' attempting to decode the\n' + '/// raw data. Typically/Defaults to kStartOffset.\n' + '/// @param[in] nbits The number of data bits to expect.\n' + '/// @param[in] strict Flag indicating if we should perform strict' + ' matching.\n' + "/// @return A boolean. True if it can decode it, false if it can't.\n" + 'bool IRrecv::decodeHitachi(decode_results *results, uint16_t offset,' ' const uint16_t nbits, const bool strict) {\n' - ' if (results->rawlen < 2 * nbits + kHitachiOverhead)\n' + ' if (results->rawlen < 2 * nbits + kHitachiOverhead - offset)\n' ' return false; // Too short a message to match.\n' ' if (strict && nbits != kHitachiBits)\n' ' return false;\n' '\n' - ' uint16_t offset = kStartOffset;\n' ' uint64_t data = 0;\n' ' match_result_t data_result;\n' '\n' @@ -693,17 +734,26 @@ class TestAutoAnalyseRawData(unittest.TestCase): '}\n' '#endif // DECODE_HITACHI\n' '\n' - '// Note: This should be 64+ bit safe.\n' '#if DECODE_HITACHI\n' '// Function should be safe over 64 bits.\n' - 'bool IRrecv::decodeHitachi(decode_results *results,' + '/// Decode the supplied Hitachi message.\n' + '/// Status: ALPHA / Untested.\n' + '/// @param[in,out] results Ptr to the data to decode &' + ' where to store the decode\n' + '/// @param[in] offset The starting index to use when' + ' attempting to decode the\n' + '/// raw data. Typically/Defaults to kStartOffset.\n' + '/// @param[in] nbits The number of data bits to expect.\n' + '/// @param[in] strict Flag indicating if we should perform strict' + ' matching.\n' + "/// @return A boolean. True if it can decode it, false if it can't.\n" + 'bool IRrecv::decodeHitachi(decode_results *results, uint16_t offset,' ' const uint16_t nbits, const bool strict) {\n' - ' if (results->rawlen < 2 * nbits + kHitachiOverhead)\n' + ' if (results->rawlen < 2 * nbits + kHitachiOverhead - offset)\n' ' return false; // Too short a message to match.\n' ' if (strict && nbits != kHitachiBits)\n' ' return false;\n' '\n' - ' uint16_t offset = kStartOffset;\n' ' uint16_t pos = 0;\n' ' uint16_t used = 0;\n' '\n' @@ -824,8 +874,12 @@ class TestAutoAnalyseRawData(unittest.TestCase): '\n' 'Generating a VERY rough code outline:\n' '\n' - '// Copyright 2019 David Conran (crankyoldgit)\n' - '// Support for FOO protocol\n' + '// Copyright 2020 David Conran (crankyoldgit)\n' + '/// @file\n' + '/// @brief Support for FOO protocol\n' + '\n' + '// Supports:\n' + '// Brand: FOO, Model: TODO add device and remote\n' '\n' '#include "IRrecv.h"\n' '#include "IRsend.h"\n' @@ -849,8 +903,14 @@ class TestAutoAnalyseRawData(unittest.TestCase): 'const uint16_t kFOOOverhead = 16;\n' "// DANGER: More than 64 bits detected. A uint64_t for 'data' won't" ' work!\n' + '\n' '#if SEND_FOO\n' '// Function should be safe up to 64 bits.\n' + '/// Send a FOO formatted message.\n' + '/// Status: ALPHA / Untested.\n' + '/// @param[in] data containing the IR command.\n' + '/// @param[in] nbits Nr. of bits to send. usually kFOOBits\n' + '/// @param[in] repeat Nr. of times the message is to be repeated.\n' 'void IRsend::sendFOO(const uint64_t data, const uint16_t nbits,' ' const uint16_t repeat) {\n' ' enableIROut(kFOOFreq);\n' @@ -908,17 +968,19 @@ class TestAutoAnalyseRawData(unittest.TestCase): '\n' '#if SEND_FOO\n' '// Alternative >64bit function to send FOO messages\n' - '// Where data is:\n' - '// uint8_t data[kFOOStateLength] = {0x5F, 0x5F, 0x40, 0x40, 0x5F,' + '// Function should be safe over 64 bits.\n' + '/// Send a FOO formatted message.\n' + '/// Status: ALPHA / Untested.\n' + '/// @param[in] data An array of bytes containing the IR command.\n' + '/// It is assumed to be in MSB order for this code.\n' + '/// e.g.\n' + '/// @code\n' + '/// uint8_t data[kFOOStateLength] = {0x5F, 0x5F, 0x40, 0x40, 0x5F,' ' 0x5F, 0x40, 0x40, 0x2F, 0x2F, 0x6C, 0x6C, 0x2F, 0x2F, 0x6C, 0x6C};\n' - '//\n' - '// Args:\n' - '// data: An array of bytes containing the IR command.\n' - '// It is assumed to be in MSB order for this code.\n' - '// nbytes: Nr. of bytes of data in the array. (>=kFOOStateLength)\n' - '// repeat: Nr. of times the message is to be repeated.\n' - '//\n' - '// Status: ALPHA / Untested.\n' + '/// @endcode\n' + '/// @param[in] nbytes Nr. of bytes of data in the array.' + ' (>=kFOOStateLength)\n' + '/// @param[in] repeat Nr. of times the message is to be repeated.\n' 'void IRsend::sendFOO(const uint8_t data[], const uint16_t nbytes,' ' const uint16_t repeat) {\n' ' for (uint16_t r = 0; r <= repeat; r++) {\n' @@ -975,14 +1037,24 @@ class TestAutoAnalyseRawData(unittest.TestCase): 'work!\n' '#if DECODE_FOO\n' '// Function should be safe up to 64 bits.\n' - 'bool IRrecv::decodeFOO(decode_results *results, const uint16_t nbits,' - ' const bool strict) {\n' - ' if (results->rawlen < 2 * nbits + kFOOOverhead)\n' + '/// Decode the supplied FOO message.\n' + '/// Status: ALPHA / Untested.\n' + '/// @param[in,out] results Ptr to the data to decode &' + ' where to store the decode\n' + '/// @param[in] offset The starting index to use when' + ' attempting to decode the\n' + '/// raw data. Typically/Defaults to kStartOffset.\n' + '/// @param[in] nbits The number of data bits to expect.\n' + '/// @param[in] strict Flag indicating if we should perform strict' + ' matching.\n' + "/// @return A boolean. True if it can decode it, false if it can't.\n" + 'bool IRrecv::decodeFOO(decode_results *results, uint16_t offset,' + ' const uint16_t nbits, const bool strict) {\n' + ' if (results->rawlen < 2 * nbits + kFOOOverhead - offset)\n' ' return false; // Too short a message to match.\n' ' if (strict && nbits != kFOOBits)\n' ' return false;\n' '\n' - ' uint16_t offset = kStartOffset;\n' ' uint64_t data = 0;\n' ' match_result_t data_result;\n' '\n' @@ -1084,17 +1156,26 @@ class TestAutoAnalyseRawData(unittest.TestCase): '}\n' '#endif // DECODE_FOO\n' '\n' - '// Note: This should be 64+ bit safe.\n' '#if DECODE_FOO\n' '// Function should be safe over 64 bits.\n' - 'bool IRrecv::decodeFOO(decode_results *results, const uint16_t nbits,' - ' const bool strict) {\n' - ' if (results->rawlen < 2 * nbits + kFOOOverhead)\n' + '/// Decode the supplied FOO message.\n' + '/// Status: ALPHA / Untested.\n' + '/// @param[in,out] results Ptr to the data to decode &' + ' where to store the decode\n' + '/// @param[in] offset The starting index to use when' + ' attempting to decode the\n' + '/// raw data. Typically/Defaults to kStartOffset.\n' + '/// @param[in] nbits The number of data bits to expect.\n' + '/// @param[in] strict Flag indicating if we should perform strict' + ' matching.\n' + "/// @return A boolean. True if it can decode it, false if it can't.\n" + 'bool IRrecv::decodeFOO(decode_results *results, uint16_t offset,' + ' const uint16_t nbits, const bool strict) {\n' + ' if (results->rawlen < 2 * nbits + kFOOOverhead - offset)\n' ' return false; // Too short a message to match.\n' ' if (strict && nbits != kFOOBits)\n' ' return false;\n' '\n' - ' uint16_t offset = kStartOffset;\n' ' uint16_t pos = 0;\n' ' uint16_t used = 0;\n' '\n' @@ -1229,8 +1310,12 @@ class TestAutoAnalyseRawData(unittest.TestCase): '\n' 'Generating a VERY rough code outline:\n' '\n' - '// Copyright 2019 David Conran (crankyoldgit)\n' - '// Support for TBD protocol\n' + '// Copyright 2020 David Conran (crankyoldgit)\n' + '/// @file\n' + '/// @brief Support for TBD protocol\n' + '\n' + '// Supports:\n' + '// Brand: TBD, Model: TODO add device and remote\n' '\n' '#include "IRrecv.h"\n' '#include "IRsend.h"\n' @@ -1253,8 +1338,14 @@ class TestAutoAnalyseRawData(unittest.TestCase): 'const uint16_t kOverhead = 1;\n' "// DANGER: More than 64 bits detected. A uint64_t for 'data' won't" ' work!\n' + '\n' '#if SEND_TBD\n' '// Function should be safe up to 64 bits.\n' + '/// Send a formatted message.\n' + '/// Status: ALPHA / Untested.\n' + '/// @param[in] data containing the IR command.\n' + '/// @param[in] nbits Nr. of bits to send. usually kBits\n' + '/// @param[in] repeat Nr. of times the message is to be repeated.\n' 'void IRsend::sendTBD(const uint64_t data, const uint16_t nbits, const' ' uint16_t repeat) {\n' ' enableIROut(kFreq);\n' @@ -1275,17 +1366,19 @@ class TestAutoAnalyseRawData(unittest.TestCase): '\n' '#if SEND_TBD\n' '// Alternative >64bit function to send TBD messages\n' - '// Where data is:\n' - '// uint8_t data[kStateLength] = {0xA5, 0x5A, 0x00, 0x00, 0x40, 0x00,' - ' 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80};\n' - '//\n' - '// Args:\n' - '// data: An array of bytes containing the IR command.\n' - '// It is assumed to be in MSB order for this code.\n' - '// nbytes: Nr. of bytes of data in the array. (>=kStateLength)\n' - '// repeat: Nr. of times the message is to be repeated.\n' - '//\n' - '// Status: ALPHA / Untested.\n' + '// Function should be safe over 64 bits.\n' + '/// Send a formatted message.\n' + '/// Status: ALPHA / Untested.\n' + '/// @param[in] data An array of bytes containing the IR command.\n' + '/// It is assumed to be in MSB order for this code.\n' + '/// e.g.\n' + '/// @code\n' + '/// uint8_t data[kStateLength] = {0xA5, 0x5A, 0x00, 0x00, 0x40,' + ' 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80};\n' + '/// @endcode\n' + '/// @param[in] nbytes Nr. of bytes of data in the array.' + ' (>=kStateLength)\n' + '/// @param[in] repeat Nr. of times the message is to be repeated.\n' 'void IRsend::sendTBD(const uint8_t data[], const uint16_t nbytes,' ' const uint16_t repeat) {\n' ' for (uint16_t r = 0; r <= repeat; r++) {\n' @@ -1310,14 +1403,24 @@ class TestAutoAnalyseRawData(unittest.TestCase): ' work!\n' '#if DECODE_TBD\n' '// Function should be safe up to 64 bits.\n' - 'bool IRrecv::decodeTBD(decode_results *results, const uint16_t nbits,' - ' const bool strict) {\n' - ' if (results->rawlen < 2 * nbits + kOverhead)\n' + '/// Decode the supplied message.\n' + '/// Status: ALPHA / Untested.\n' + '/// @param[in,out] results Ptr to the data to decode &' + ' where to store the decode\n' + '/// @param[in] offset The starting index to use when' + ' attempting to decode the\n' + '/// raw data. Typically/Defaults to kStartOffset.\n' + '/// @param[in] nbits The number of data bits to expect.\n' + '/// @param[in] strict Flag indicating if we should perform strict' + ' matching.\n' + "/// @return A boolean. True if it can decode it, false if it can't.\n" + 'bool IRrecv::decodeTBD(decode_results *results, uint16_t offset,' + ' const uint16_t nbits, const bool strict) {\n' + ' if (results->rawlen < 2 * nbits + kOverhead - offset)\n' ' return false; // Too short a message to match.\n' ' if (strict && nbits != kBits)\n' ' return false;\n' '\n' - ' uint16_t offset = kStartOffset;\n' ' uint64_t data = 0;\n' ' match_result_t data_result;\n' '\n' @@ -1346,17 +1449,26 @@ class TestAutoAnalyseRawData(unittest.TestCase): '}\n' '#endif // DECODE_TBD\n' '\n' - '// Note: This should be 64+ bit safe.\n' '#if DECODE_TBD\n' '// Function should be safe over 64 bits.\n' - 'bool IRrecv::decodeTBD(decode_results *results, const uint16_t nbits,' - ' const bool strict) {\n' - ' if (results->rawlen < 2 * nbits + kOverhead)\n' + '/// Decode the supplied message.\n' + '/// Status: ALPHA / Untested.\n' + '/// @param[in,out] results Ptr to the data to decode &' + ' where to store the decode\n' + '/// @param[in] offset The starting index to use when' + ' attempting to decode the\n' + '/// raw data. Typically/Defaults to kStartOffset.\n' + '/// @param[in] nbits The number of data bits to expect.\n' + '/// @param[in] strict Flag indicating if we should perform strict' + ' matching.\n' + "/// @return A boolean. True if it can decode it, false if it can't.\n" + 'bool IRrecv::decodeTBD(decode_results *results, uint16_t offset,' + ' const uint16_t nbits, const bool strict) {\n' + ' if (results->rawlen < 2 * nbits + kOverhead - offset)\n' ' return false; // Too short a message to match.\n' ' if (strict && nbits != kBits)\n' ' return false;\n' '\n' - ' uint16_t offset = kStartOffset;\n' ' uint16_t pos = 0;\n' ' uint16_t used = 0;\n' '\n' diff --git a/lib/IRremoteESP8266-2.7.5/tools/gc_decode.cpp b/lib/IRremoteESP8266-2.7.8/tools/gc_decode.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/tools/gc_decode.cpp rename to lib/IRremoteESP8266-2.7.8/tools/gc_decode.cpp diff --git a/lib/IRremoteESP8266-2.7.5/tools/generate_irtext_h.sh b/lib/IRremoteESP8266-2.7.8/tools/generate_irtext_h.sh old mode 100755 new mode 100644 similarity index 100% rename from lib/IRremoteESP8266-2.7.5/tools/generate_irtext_h.sh rename to lib/IRremoteESP8266-2.7.8/tools/generate_irtext_h.sh diff --git a/lib/IRremoteESP8266-2.7.5/tools/mkkeywords b/lib/IRremoteESP8266-2.7.8/tools/mkkeywords old mode 100755 new mode 100644 similarity index 100% rename from lib/IRremoteESP8266-2.7.5/tools/mkkeywords rename to lib/IRremoteESP8266-2.7.8/tools/mkkeywords diff --git a/lib/IRremoteESP8266-2.7.5/tools/mode2_decode.cpp b/lib/IRremoteESP8266-2.7.8/tools/mode2_decode.cpp similarity index 100% rename from lib/IRremoteESP8266-2.7.5/tools/mode2_decode.cpp rename to lib/IRremoteESP8266-2.7.8/tools/mode2_decode.cpp diff --git a/lib/IRremoteESP8266-2.7.8/tools/raw_to_pronto_code.py b/lib/IRremoteESP8266-2.7.8/tools/raw_to_pronto_code.py new file mode 100755 index 000000000..307ae7121 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/tools/raw_to_pronto_code.py @@ -0,0 +1,103 @@ +#!/usr/bin/python +"""Convert IRremoteESP8266's Raw data output into Pronto Code.""" +# +# Copyright 2020 David Conran +import argparse +import sys +from auto_analyse_raw_data import convert_rawdata, add_rawdata_args, get_rawdata + + +# pylint: disable=too-many-arguments +def parse_and_report(rawdata_str, hertz=38000, end_usecs=100000, + use_initial=False, generate_code=False, verbose=False, + output=sys.stdout): + """Analyse the rawdata c++ definition of a IR message.""" + + # Parse the input. + rawdata = convert_rawdata(rawdata_str) + if verbose: + output.write("Found %d timing entries.\n" % len(rawdata)) + + # Do we need to pad out the rawdata to make it even in length? + if end_usecs > 0 and len(rawdata) % 2 == 1: + rawdata.append(end_usecs) + + result = ["0000"] + # Work out the frequency code. + pronto_freq = int(1000000.0 / (hertz * 0.241246)) + if verbose: + output.write("Pronto frequency is %X (%d Hz).\n" % (pronto_freq, hertz)) + result.append("%04X" % pronto_freq) + period = 1000000.0 / max(1, hertz) + if verbose: + output.write("Pronto period is %f uSecs.\n" % period) + # Add the lengths to the code. + if use_initial: + result.append("%04x" % int(len(rawdata) / 2)) # Initial burst code length + result.append("%04x" % 0) # No Repeat code length + else: + result.append("%04x" % 0) # No Initial burst code length + result.append("%04x" % int(len(rawdata) / 2)) # Repeat code length + + # Add the data. + if verbose: + output.write("Raw data: %s " % rawdata) + for i in rawdata: + result.append("%04x" % int(i / period)) + if generate_code: + output.write("uint16_t pronto[%d] = {0x%s};\n" % (len(result), + ", 0x".join(result))) + else: + output.write("Pronto code = '%s'\n" % " ".join(result)) +# pylint: enable=too-many-arguments + + +def main(): + """Parse the commandline arguments and call the method.""" + arg_parser = argparse.ArgumentParser( + description="Read an IRremoteESP8266 rawData declaration and tries to " + "convert it in to a Pronto code.", + formatter_class=argparse.ArgumentDefaultsHelpFormatter) + arg_parser.add_argument( + "--hz", + "--hertz", + type=int, + help="Frequency of the protocol to use in code generation. E.g. 38000Hz", + dest="hertz", + required=True) + arg_parser.add_argument( + "-c", + "--code", + action='store_true', + help="Output C/C++ code instead of human-readable.", + dest="generate_code") + arg_parser.add_argument( + "-g", + "--gap", + "--endgap", + type=int, + help="Nr. of uSeconds of gap to add to the end of the message.", + dest="usecs", + default=100000) + arg_parser.add_argument( + "-i", + "--initial_burst", + action='store_true', + help="Send using only the 'inital burst' section of the pronto code.", + dest="use_initial") + arg_parser.add_argument( + "-v", + "--verbose", + help="Increase output verbosity", + action="store_true", + dest="verbose", + default=False) + add_rawdata_args(arg_parser) + arg_options = arg_parser.parse_args() + parse_and_report(get_rawdata(arg_options), arg_options.hertz, + arg_options.usecs, arg_options.use_initial, + arg_options.generate_code, arg_options.verbose) + + +if __name__ == '__main__': + main() diff --git a/lib/IRremoteESP8266-2.7.8/tools/raw_to_pronto_code_test.py b/lib/IRremoteESP8266-2.7.8/tools/raw_to_pronto_code_test.py new file mode 100755 index 000000000..b7b029b66 --- /dev/null +++ b/lib/IRremoteESP8266-2.7.8/tools/raw_to_pronto_code_test.py @@ -0,0 +1,81 @@ +#!/usr/bin/python3 +"""Unit tests for raw_to_pronto_code.py""" +from io import StringIO +import unittest +import raw_to_pronto_code as pronto + +class TestRawToPronto(unittest.TestCase): + """Unit tests for the methods in raw_to_pronto_code.""" + + def test_parse_and_report_at_38000(self): + """Tests for the parse_and_report() function @ 38kHz.""" + + output = StringIO() + input_str = """ + uint16_t rawData[7] = { + 20100, 20472, 15092, 30704, 20102, 20472, 15086};""" + pronto.parse_and_report(input_str, 38000, 100000, True, False, False, + output) + self.assertEqual( + output.getvalue(), + "Pronto code = " + "'0000 006D 0004 0000 02fb 0309 023d 048e 02fb 0309 023d 0ed8'\n") + + def test_parse_and_report_at_36000(self): + """Tests for the parse_and_report() function @ 36kHz.""" + + output = StringIO() + input_str = """ + uint16_t rawData[7] = { + 20100, 20472, 15092, 30704, 20102, 20472, 15086};""" + pronto.parse_and_report(input_str, 36000, 100000, True, False, False, + output) + self.assertEqual( + output.getvalue(), + "Pronto code = " + "'0000 0073 0004 0000 02d3 02e0 021f 0451 02d3 02e0 021f 0e10'\n") + + def test_parse_and_report_at_57600(self): + """Tests for the parse_and_report() function @ 57.6kHz.""" + + output = StringIO() + input_str = """ + uint16_t rawData[7] = { + 20100, 20472, 15092, 30704, 20102, 20472, 15086};""" + pronto.parse_and_report(input_str, 57600, 100000, True, False, False, + output) + self.assertEqual( + output.getvalue(), + "Pronto code = " + "'0000 0047 0004 0000 0485 049b 0365 06e8 0485 049b 0364 1680'\n") + + def test_using_repeat(self): + """Tests for the parse_and_report() function @38kHz using repeat section.""" + + output = StringIO() + input_str = """ + uint16_t rawData[7] = { + 20100, 20472, 15092, 30704, 20102, 20472, 15086};""" + pronto.parse_and_report(input_str, 38000, 30000, False, False, False, + output) + self.assertEqual( + output.getvalue(), + "Pronto code = " + "'0000 006D 0000 0004 02fb 0309 023d 048e 02fb 0309 023d 0474'\n") + + def test_generate_code_output(self): + """Tests for the parse_and_report() function geneating code output.""" + + output = StringIO() + input_str = """ + uint16_t rawData[7] = { + 20100, 20472, 15092, 30704, 20102, 20472, 15086};""" + pronto.parse_and_report(input_str, 38000, 30000, True, True, False, output) + self.assertEqual( + output.getvalue(), + "uint16_t pronto[12] = {0x0000, 0x006D, 0x0004, 0x0000, 0x02fb, " + "0x0309, 0x023d, 0x048e, 0x02fb, 0x0309, 0x023d, 0x0474};\n") + + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/lib/IRremoteESP8266-2.7.5/tools/scrape_supported_devices.py b/lib/IRremoteESP8266-2.7.8/tools/scrape_supported_devices.py old mode 100755 new mode 100644 similarity index 56% rename from lib/IRremoteESP8266-2.7.5/tools/scrape_supported_devices.py rename to lib/IRremoteESP8266-2.7.8/tools/scrape_supported_devices.py index c859bbf06..a9cd10f0a --- a/lib/IRremoteESP8266-2.7.5/tools/scrape_supported_devices.py +++ b/lib/IRremoteESP8266-2.7.8/tools/scrape_supported_devices.py @@ -2,6 +2,8 @@ """Generate SupportedProtocols.md by scraping source code files""" import pathlib import argparse +import subprocess +from io import StringIO import sys import re import time @@ -21,9 +23,28 @@ ALL_FN = re.compile(r"ir_(.+)\.(h|cpp)") EXCLUDED_PROTOCOLS = ["UNKNOWN", "UNUSED", "kLastDecodeType", "typeguess"] EXCLUDED_ACS = ["Magiquest", "NEC"] -MARKDOWN_HEADER = """""".format(time.asctime()) + Last generated: {} --->""".format( + time.strftime("%a %d %b %Y %H:%M:%S +0000", time.gmtime(srctime))) def getallprotocols(): @@ -42,7 +63,7 @@ def getdecodedprotocols(): for path in ARGS.directory.iterdir(): if path.suffix != ".cpp": continue - matches = DECODED_PROTOCOLS.finditer(path.open().read()) + matches = DECODED_PROTOCOLS.finditer(path.open(encoding="utf-8").read()) for match in matches: protocol = match.group(1) if protocol not in EXCLUDED_PROTOCOLS: @@ -85,37 +106,88 @@ def getallacs(): ret[acprotocol] = models return ret +class FnSets(): + """Container for getalldevices""" + def __init__(self): + self.allcodes = {} + self.fnnomatch = set() + self.allhfileprotos = set() + self.fnhmatch = set() + self.fncppmatch = set() + + def add(self, supports, path): + """add the path to correct set based on supports""" + if path.suffix == ".h": + self.allhfileprotos.add(path.stem) + if supports: + if path.suffix == ".h": + self.fnhmatch.add(path.stem) + elif path.suffix == ".cpp": + self.fncppmatch.add(path.stem) + else: + self.fnnomatch.add(path.stem) + + def printwarnings(self): + """print warnings""" + # all protos with support in .cpp file, when there is a .h file + # meaning that the documentation should probably be moved to .h + # in the future, with doxygen, that might change + protosincppwithh = list(self.fncppmatch & self.allhfileprotos) + if protosincppwithh: + protosincppwithh.sort() + print("The following files has supports section in .cpp, expected in .h") + for path in protosincppwithh: + print("\t{}".format(path)) + + protosincppandh = list(self.fncppmatch & self.fnhmatch) + if protosincppandh: + protosincppandh.sort() + print("The following files has supports section in both .h and .cpp") + for path in protosincppandh: + print("\t{}".format(path)) + + nosupports = self.getnosupports() + if nosupports: + nosupports.sort() + print("The following files had no supports section:") + for path in nosupports: + print("\t{}".format(path)) + + return protosincppwithh or protosincppandh or nosupports + + def getnosupports(self): + """get protos without supports sections""" + return list(self.fnnomatch - self.fnhmatch - self.fncppmatch) + def getalldevices(): """All devices and associated branding and model information (if available) """ - allcodes = {} - fnnomatch = set() - fnmatch = set() + sets = FnSets() for path in ARGS.directory.iterdir(): match = ALL_FN.match(path.name) if not match: continue supports = extractsupports(path) - if supports: - fnmatch.add(path.stem) - else: - fnnomatch.add(path.stem) + sets.add(supports, path) protocol = match.group(1) for brand, model in supports: protocolbrand = (protocol, brand) - allcodes[protocolbrand] = allcodes.get(protocolbrand, list()) + [model] - nosupports = fnnomatch - fnmatch - for fnprotocol in nosupports: - allcodes[(fnprotocol[3:], "Unknown")] = [] - return allcodes, nosupports + pbset = sets.allcodes.get(protocolbrand, list()) + if model in pbset: + print("Model %s is duplicated for %s, %s" % (model, protocol, brand)) + sets.allcodes[protocolbrand] = pbset + [model] + + for fnprotocol in sets.getnosupports(): + sets.allcodes[(fnprotocol[3:], "Unknown")] = [] + return sets def getenums(path): """Returns the keys for the first enum type in path - """ + """ ret = {} - for enums in ENUMS.finditer(path.open().read()): + for enums in ENUMS.finditer(path.open(encoding="utf-8").read()): if enums: enum_name = AC_MODEL_ENUM_RE.search(enums.group(1)) if enum_name: @@ -138,6 +210,12 @@ def initargs(): """Init the command line arguments""" global ARGS # pylint: disable=global-statement parser = argparse.ArgumentParser() + parser.add_argument( + "-n", + "--noout", + help="generate no output data, combine with --alert to only check", + action="store_true", + ) parser.add_argument( "-s", "--stdout", @@ -151,7 +229,8 @@ def initargs(): parser.add_argument( "-a", "--alert", - help="alert if a file does not have a supports section", + help="alert if a file does not have a supports section, " + "non zero exit code if issues where found", action="store_true", ) parser.add_argument( @@ -172,6 +251,10 @@ def initargs(): ARGS.directory = src return ARGS +def getmdfile(): + """Resolves SupportedProtocols.md path""" + foutpath = ARGS.directory / "../SupportedProtocols.md" + return foutpath.resolve() def errorexit(msg): """Print an error and exit on critical error""" @@ -184,7 +267,7 @@ def extractsupports(path): """ supports = [] insupports = False - for line in path.open(): + for line in path.open(encoding="utf-8"): if not line.startswith("//"): continue line = line[2:].strip() @@ -198,6 +281,12 @@ def extractsupports(path): else: insupports = False continue + # search and inform about any legacy formated supports data + elif any(x in line for x in [ \ + "seems compatible with", + "be compatible with", + "it working with here"]): + print("\t%s Legacy supports format found\n\t\t%s" % (path.name, line)) return supports @@ -214,28 +303,18 @@ def outputprotocols(fout, protocols): fout.write("- {}\n".format(protocol)) -def main(): - """Standard boiler plate""" - initargs() - if ARGS.verbose: - print("Looking for files in: {}".format(str(ARGS.directory.resolve()))) - if ARGS.stdout: - fout = sys.stdout - else: - foutpath = ARGS.directory / "../SupportedProtocols.md" - foutpath = foutpath.resolve() - if ARGS.verbose: - print("Output path: {}".format(str(foutpath))) - fout = foutpath.open("w") +def generate(fout): + """Generate data to fout + return True on any issues (when alert is active)""" decodedprotocols = getdecodedprotocols() sendonly = getallprotocols() - decodedprotocols allacs = getallacs() - allcodes, nosupports = getalldevices() + sets = getalldevices() + allcodes = sets.allcodes allbrands = list(allcodes.keys()) allbrands.sort() - fout.write(MARKDOWN_HEADER) fout.write("\n# IR Protocols supported by this library\n\n") fout.write( "| Protocol | Brand | Model | A/C Model | Detailed A/C Support |\n") @@ -268,13 +347,60 @@ def main(): fout.write("\n\n## Send & decodable protocols:\n\n") outputprotocols(fout, decodedprotocols) - if ARGS.alert: - nosupports = list(nosupports) - nosupports.sort() - print("The following files had no supports section:") - for path in nosupports: - print("\t{}".format(path)) + return ARGS.alert and sets.printwarnings() + +def generatenone(): + """No out write + return True on any issues""" + return generate(StringIO()) + +def generatestdout(): + """Standard out write + return True on any issues""" + fout = sys.stdout + fout.write(getmarkdownheader()) + return generate(fout) + +def generatefile(): + """File write, extra detection of changes in existing file + return True on any issues, but only if there is changes""" + # get file path + foutpath = getmdfile() + if ARGS.verbose: + print("Output path: {}".format(str(foutpath))) + # write data to temp memorystream + ftemp = StringIO() + ret = generate(ftemp) + # get old filedata, skipping header + with getmdfile().open("r", encoding="utf-8") as forg: + olddata = forg.readlines()[3:] + # get new data, skip first empty line + ftemp.seek(0) + newdata = ftemp.readlines()[1:] + # if new data is same as old we don't need to write anything + if newdata == olddata: + print("No changes, exit without write") + return False + # write output + with foutpath.open("w", encoding="utf-8") as fout: + fout.write(getmarkdownheader()) + fout.write(ftemp.getvalue()) + + return ret + +def main(): + """Default main function + return True on any issues""" + initargs() + if ARGS.verbose: + print("Looking for files in: {}".format(str(ARGS.directory.resolve()))) + if ARGS.noout: + return generatenone() + if ARGS.stdout: + return generatestdout() + # default file + return generatefile() if __name__ == "__main__": - main() + sys.exit(1 if main() else 0) diff --git a/lib/JaretBurkett_ILI9488-gemu-1.0/ILI9488.cpp b/lib/JaretBurkett_ILI9488-gemu-1.0/ILI9488.cpp index 3e0aca9ee..c7cdeba0a 100644 --- a/lib/JaretBurkett_ILI9488-gemu-1.0/ILI9488.cpp +++ b/lib/JaretBurkett_ILI9488-gemu-1.0/ILI9488.cpp @@ -19,7 +19,7 @@ #include // if using software spi this optimizes the code -#define SWSPI_OPTMODE + #define ILI9488_START start(); #define ILI9488_STOP stop(); @@ -37,9 +37,6 @@ ILI9488::ILI9488(int8_t cs,int8_t mosi,int8_t sclk,int8_t bp) : Renderer(ILI9488 _hwspi = 0; } - -#include "spi_register.h" - /* CPU Clock = 80 Mhz @@ -73,6 +70,13 @@ GPIO15: PERIPHS_IO_MUX_MTDO_U uint8_t ili9488_start; +#ifndef ESP32 +// ESP8266 +#include "spi_register.h" +#define SWSPI_OPTMODE +// this enables the 27 bit packed mode +#define RGB_PACK_MODE + uint32_t ili9488_clock; uint32_t ili9488_usr; uint32_t ili9488_usr1; @@ -192,32 +196,6 @@ void ILI9488::stop(void) { ili9488_start=0; } - -#if 0 -// code from espressif SDK -/****************************************************************************** - * FunctionName : spi_lcd_9bit_write - * Description : SPI 9bits transmission function for driving LCD TM035PDZV36 - * Parameters : uint8 spi_no - SPI module number, Only "SPI" and "HSPI" are valid - * uint8 high_bit - first high bit of the data, 0 is for "0",the other value 1-255 is for "1" - * uint8 low_8bit- the rest 8bits of the data. -*******************************************************************************/ -void spi_lcd_9bit_write(uint8_t high_bit,uint8_t low_8bit) -{ - uint32_t regvalue; - uint8_t bytetemp; - - if(high_bit) bytetemp=(low_8bit>>1)|0x80; - else bytetemp=(low_8bit>>1)&0x7f; - - regvalue= ((8&SPI_USR_COMMAND_BITLEN)<>= 1) { + WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<_sclk); + if(d&bit) WRITE_PERI_REG( PIN_OUT_SET, 1<<_mosi); + else WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<_mosi); + WRITE_PERI_REG( PIN_OUT_SET, 1<<_sclk); } + WRITE_PERI_REG( PIN_OUT_SET, 1<<_cs); } -*/ +#else +// ESP32 section +void ILI9488::writedata(uint8_t d) { + ILI9488_START + fastSPIwrite(d,1); +} + +void ILI9488::writecommand(uint8_t c) { + ILI9488_START + fastSPIwrite(c,0); +} + +#include "soc/spi_reg.h" +#include "soc/spi_struct.h" +#include "esp32-hal-spi.h" +#include "esp32-hal.h" +#include "soc/spi_struct.h" + +#define RGB_PACK_MODE + +// since ardunio transferBits ia completely disfunctional +// we use our own hardware driver for 9 bit spi +void ILI9488::fastSPIwrite(uint8_t d,uint8_t dc) { + digitalWrite( _cs, LOW); + + uint32_t regvalue=d>>1; + if (dc) regvalue|=0x80; + else regvalue&=0x7f; + if (d&1) regvalue|=0x8000; + + REG_SET_BIT(SPI_USER_REG(3), SPI_USR_MOSI); + REG_WRITE(SPI_MOSI_DLEN_REG(3), 9 - 1); + uint32_t *dp=(uint32_t*)SPI_W0_REG(3); + *dp=regvalue; + REG_SET_BIT(SPI_CMD_REG(3), SPI_USR); + while (REG_GET_FIELD(SPI_CMD_REG(3), SPI_USR)); + + digitalWrite( _cs, HIGH); +} + +SPISettings ili9488_spiSettings; + +void ILI9488::start(void) { + if (ili9488_start) return; + SPI.beginTransaction(ili9488_spiSettings); + ili9488_start=1; +} +void ILI9488::stop(void) { + if (!ili9488_start) return; + SPI.endTransaction(); + ili9488_start=0; +} +#endif + uint16_t ILI9488::GetColorFromIndex(uint8_t index) { if (index>=sizeof(ili9488_colors)/2) index=0; @@ -339,14 +351,23 @@ void ILI9488::begin(void) { pinMode(_bp, OUTPUT); digitalWrite(_bp,HIGH); } + +#ifndef ESP32 if ((_sclk==14) && (_mosi==13) && (_cs==15)) { // we use hardware spi + SPI.begin(); _hwspi=1; spi_lcd_mode_init(); } else { // we must use software spi _hwspi=0; } +#else + SPI.begin(_sclk,-1,_mosi, -1); + ili9488_spiSettings = SPISettings(10000000, MSBFIRST, SPI_MODE3); + _hwspi=1; +#endif + ILI9488_START delay(1); @@ -817,8 +838,7 @@ void ILI9488::fillScreen(uint16_t color) { //#define WRITE_SPI_REG -// this enables the 27 bit packed mode -#define RGB_PACK_MODE + // extremely strange => if this code is merged into pack_rgb() the software crashes // swap bytes @@ -844,9 +864,9 @@ uint32_t pack_rgb(uint32_t r, uint32_t g, uint32_t b) { return ulswap(data); } +#ifndef ESP32 // fill a rectangle -void ILI9488::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, - uint16_t color) { +void ILI9488::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) { ILI9488_START // rudimentary clipping (drawChar w/big text requires this) @@ -990,6 +1010,56 @@ void ILI9488::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, #endif } +#else +// ESP32 +void ILI9488::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) { + + // rudimentary clipping (drawChar w/big text requires this) + if((x >= _width) || (y >= _height)) return; + if((x + w - 1) >= _width) w = _width - x; + if((y + h - 1) >= _height) h = _height - y; + + setAddrWindow(x, y, x+w-1, y+h-1); + + uint8_t r = (color & 0xF800) >> 11; + uint8_t g = (color & 0x07E0) >> 5; + uint8_t b = color & 0x001F; + + r = (r * 255) / 31; + g = (g * 255) / 63; + b = (b * 255) / 31; + +#ifdef RGB_PACK_MODE + // init 27 bit mode + uint32_t data=pack_rgb(r,g,b); + REG_SET_BIT(SPI_USER_REG(3), SPI_USR_MOSI); + REG_WRITE(SPI_MOSI_DLEN_REG(3), 27 - 1); + uint32_t *dp=(uint32_t*)SPI_W0_REG(3); + digitalWrite( _cs, LOW); +#endif + + for(y=h; y>0; y--) { + for(x=w; x>0; x--) { + #ifndef RGB_PACK_MODE + writedata(r); + writedata(g); + writedata(b); + #else + while (REG_GET_FIELD(SPI_CMD_REG(3), SPI_USR)); + *dp=data; + REG_SET_BIT(SPI_CMD_REG(3), SPI_USR); + #endif + } + } + +#ifdef RGB_PACK_MODE + while (REG_GET_FIELD(SPI_CMD_REG(3), SPI_USR)); + digitalWrite( _cs, HIGH); +#endif + + ILI9488_STOP +} +#endif // Pass 8-bit (each) R,G,B, get back 16-bit packed color @@ -1040,65 +1110,3 @@ void ILI9488::invertDisplay(boolean i) { writecommand(i ? ILI9488_INVON : ILI9488_INVOFF); ILI9488_STOP } - -void ICACHE_RAM_ATTR ILI9488::fastSPIwrite(uint8_t d,uint8_t dc) { - - WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<_cs); - WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<_sclk); - if(dc) WRITE_PERI_REG( PIN_OUT_SET, 1<<_mosi); - else WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<_mosi); - WRITE_PERI_REG( PIN_OUT_SET, 1<<_sclk); - - for(uint8_t bit = 0x80; bit; bit >>= 1) { - WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<_sclk); - if(d&bit) WRITE_PERI_REG( PIN_OUT_SET, 1<<_mosi); - else WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<_mosi); - WRITE_PERI_REG( PIN_OUT_SET, 1<<_sclk); - } - WRITE_PERI_REG( PIN_OUT_SET, 1<<_cs); -} - -/* - - uint16_t ILI9488::readcommand16(uint8_t c) { - digitalWrite(_dc, LOW); - if (_cs) - digitalWrite(_cs, LOW); - - spiwrite(c); - pinMode(_sid, INPUT); // input! - uint16_t r = spiread(); - r <<= 8; - r |= spiread(); - if (_cs) - digitalWrite(_cs, HIGH); - - pinMode(_sid, OUTPUT); // back to output - return r; - } - - uint32_t ILI9488::readcommand32(uint8_t c) { - digitalWrite(_dc, LOW); - if (_cs) - digitalWrite(_cs, LOW); - spiwrite(c); - pinMode(_sid, INPUT); // input! - - dummyclock(); - dummyclock(); - - uint32_t r = spiread(); - r <<= 8; - r |= spiread(); - r <<= 8; - r |= spiread(); - r <<= 8; - r |= spiread(); - if (_cs) - digitalWrite(_cs, HIGH); - - pinMode(_sid, OUTPUT); // back to output - return r; - } - - */ diff --git a/lib/LOLIN_HP303B/README.md b/lib/LOLIN_HP303B/README.md new file mode 100644 index 000000000..24d6c2d1b --- /dev/null +++ b/lib/LOLIN_HP303B/README.md @@ -0,0 +1,4 @@ +# Arduino library for the HP303B +### Installation +- Clone this repository or download&unzip [zip file](https://github.com/wemos/LOLIN_HP303B_Library/archive/master.zip) into Arduino/libraries + diff --git a/lib/LOLIN_HP303B/examples/i2c_background/i2c_background.ino b/lib/LOLIN_HP303B/examples/i2c_background/i2c_background.ino new file mode 100644 index 000000000..1b9ae6e68 --- /dev/null +++ b/lib/LOLIN_HP303B/examples/i2c_background/i2c_background.ino @@ -0,0 +1,98 @@ +#include + +// HP303B Opject +LOLIN_HP303B HP303BPressureSensor = LOLIN_HP303B(); + +void setup() +{ + Serial.begin(115200); + while (!Serial); + + //Call begin to initialize HP303BPressureSensor + //The parameter 0x76 is the bus address. The default address is 0x77 and does not need to be given. + //HP303BPressureSensor.begin(Wire, 0x76); + //Use the commented line below instead to use the default I2C address. + HP303BPressureSensor.begin(); + + //temperature measure rate (value from 0 to 7) + //2^temp_mr temperature measurement results per second + int16_t temp_mr = 2; + //temperature oversampling rate (value from 0 to 7) + //2^temp_osr internal temperature measurements per result + //A higher value increases precision + int16_t temp_osr = 2; + //pressure measure rate (value from 0 to 7) + //2^prs_mr pressure measurement results per second + int16_t prs_mr = 2; + //pressure oversampling rate (value from 0 to 7) + //2^prs_osr internal pressure measurements per result + //A higher value increases precision + int16_t prs_osr = 2; + //startMeasureBothCont enables background mode + //temperature and pressure ar measured automatically + //High precision and hgh measure rates at the same time are not available. + //Consult Datasheet (or trial and error) for more information + int16_t ret = HP303BPressureSensor.startMeasureBothCont(temp_mr, temp_osr, prs_mr, prs_osr); + //Use one of the commented lines below instead to measure only temperature or pressure + //int16_t ret = HP303BPressureSensor.startMeasureTempCont(temp_mr, temp_osr); + //int16_t ret = HP303BPressureSensor.startMeasurePressureCont(prs_mr, prs_osr); + + + if (ret != 0) + { + Serial.print("Init FAILED! ret = "); + Serial.println(ret); + } + else + { + Serial.println("Init complete!"); + } +} + + + +void loop() +{ + unsigned char pressureCount = 20; + int32_t pressure[pressureCount]; + unsigned char temperatureCount = 20; + int32_t temperature[temperatureCount]; + + //This function writes the results of continuous measurements to the arrays given as parameters + //The parameters temperatureCount and pressureCount should hold the sizes of the arrays temperature and pressure when the function is called + //After the end of the function, temperatureCount and pressureCount hold the numbers of values written to the arrays + //Note: The HP303B cannot save more than 32 results. When its result buffer is full, it won't save any new measurement results + int16_t ret = HP303BPressureSensor.getContResults(temperature, temperatureCount, pressure, pressureCount); + + if (ret != 0) + { + Serial.println(); + Serial.println(); + Serial.print("FAIL! ret = "); + Serial.println(ret); + } + else + { + Serial.println(); + Serial.println(); + Serial.print(temperatureCount); + Serial.println(" temperature values found: "); + for (int16_t i = 0; i < temperatureCount; i++) + { + Serial.print(temperature[i]); + Serial.println(" degrees of Celsius"); + } + + Serial.println(); + Serial.print(pressureCount); + Serial.println(" pressure values found: "); + for (int16_t i = 0; i < pressureCount; i++) + { + Serial.print(pressure[i]); + Serial.println(" Pascal"); + } + } + + //Wait some time, so that the HP303B can refill its buffer + delay(10000); +} diff --git a/lib/LOLIN_HP303B/examples/i2c_command/i2c_command.ino b/lib/LOLIN_HP303B/examples/i2c_command/i2c_command.ino new file mode 100644 index 000000000..e629f7d5f --- /dev/null +++ b/lib/LOLIN_HP303B/examples/i2c_command/i2c_command.ino @@ -0,0 +1,75 @@ +#include + +// HP303B Opject +LOLIN_HP303B HP303BPressureSensor; + + +void setup() +{ + Serial.begin(115200); + while (!Serial); + + + //Call begin to initialize HP303BPressureSensor + //The parameter 0x76 is the bus address. The default address is 0x77 and does not need to be given. + //HP303BPressureSensor.begin(Wire, 0x76); + //Use the commented line below instead of the one above to use the default I2C address. + //if you are using the Pressure 3 click Board, you need 0x76 + HP303BPressureSensor.begin(); + + Serial.println("Init complete!"); +} + + + +void loop() +{ + int32_t temperature; + int32_t pressure; + int16_t oversampling = 7; + int16_t ret; + Serial.println(); + + //lets the HP303B perform a Single temperature measurement with the last (or standard) configuration + //The result will be written to the paramerter temperature + //ret = HP303BPressureSensor.measureTempOnce(temperature); + //the commented line below does exactly the same as the one above, but you can also config the precision + //oversampling can be a value from 0 to 7 + //the HP303B will perform 2^oversampling internal temperature measurements and combine them to one result with higher precision + //measurements with higher precision take more time, consult datasheet for more information + ret = HP303BPressureSensor.measureTempOnce(temperature, oversampling); + + if (ret != 0) + { + //Something went wrong. + //Look at the library code for more information about return codes + Serial.print("FAIL! ret = "); + Serial.println(ret); + } + else + { + Serial.print("Temperature: "); + Serial.print(temperature); + Serial.println(" degrees of Celsius"); + } + + //Pressure measurement behaves like temperature measurement + //ret = HP303BPressureSensor.measurePressureOnce(pressure); + ret = HP303BPressureSensor.measurePressureOnce(pressure, oversampling); + if (ret != 0) + { + //Something went wrong. + //Look at the library code for more information about return codes + Serial.print("FAIL! ret = "); + Serial.println(ret); + } + else + { + Serial.print("Pressure: "); + Serial.print(pressure); + Serial.println(" Pascal"); + } + + //Wait some time + delay(500); +} diff --git a/lib/LOLIN_HP303B/examples/i2c_interrupt/i2c_interrupt.ino b/lib/LOLIN_HP303B/examples/i2c_interrupt/i2c_interrupt.ino new file mode 100644 index 000000000..d1221109b --- /dev/null +++ b/lib/LOLIN_HP303B/examples/i2c_interrupt/i2c_interrupt.ino @@ -0,0 +1,112 @@ +#include + +// HP303B Opject +LOLIN_HP303B HP303BPressureSensor = LOLIN_HP303B(); + +void onFifoFull(); + +const unsigned char pressureLength = 50; +unsigned char pressureCount = 0; +int32_t pressure[pressureLength]; +unsigned char temperatureCount = 0; +const unsigned char temperatureLength = 50; +int32_t temperature[temperatureLength]; + + + +void setup() +{ + Serial.begin(115200); + while (!Serial); + + //Call begin to initialize HP303BPressureSensor + //The parameter 0x76 is the bus address. The default address is 0x77 and does not need to be given. + //HP303BPressureSensor.begin(Wire, 0x76); + //Use the commented line below instead to use the default I2C address. + HP303BPressureSensor.begin(); + + int16_t ret = HP303BPressureSensor.setInterruptPolarity(1); + ret = HP303BPressureSensor.setInterruptSources(1, 0, 0); + //clear interrupt flag by reading + HP303BPressureSensor.getIntStatusFifoFull(); + + //initialization of Interrupt for Controller unit + //SDO pin of HP303B has to be connected with interrupt pin + int16_t interruptPin = 3; + pinMode(interruptPin, INPUT); + attachInterrupt(digitalPinToInterrupt(interruptPin), onFifoFull, RISING); + + //start of a continuous measurement just like before + int16_t temp_mr = 3; + int16_t temp_osr = 2; + int16_t prs_mr = 1; + int16_t prs_osr = 3; + ret = HP303BPressureSensor.startMeasureBothCont(temp_mr, temp_osr, prs_mr, prs_osr); + if (ret != 0) + { + Serial.print("Init FAILED! ret = "); + Serial.println(ret); + } + else + { + Serial.println("Init complete!"); + } +} + + +void loop() +{ + //do other stuff + Serial.println("loop running"); + delay(500); + + + //if result arrays are full + //This could also be in the interrupt handler, but it would take too much time for a proper ISR + if (pressureCount == pressureLength && temperatureCount == temperatureLength) + { + //print results + Serial.println(); + Serial.println(); + Serial.print(temperatureCount); + Serial.println(" temperature values found: "); + for (int16_t i = 0; i < temperatureCount; i++) + { + Serial.print(temperature[i]); + Serial.println(" degrees of Celsius"); + } + Serial.println(); + Serial.print(pressureCount); + Serial.println(" pressure values found: "); + for (int16_t i = 0; i < pressureCount; i++) + { + Serial.print(pressure[i]); + Serial.println(" Pascal"); + } + Serial.println(); + Serial.println(); + //reset result counters + pressureCount = 0; + temperatureCount = 0; + } +} + + +//interrupt handler +void onFifoFull() +{ + //message for debugging + Serial.println("Interrupt handler called"); + + //clear interrupt flag by reading + HP303BPressureSensor.getIntStatusFifoFull(); + + //calculate the number of free indexes in the result arrays + unsigned char prs_freespace = pressureLength - pressureCount; + unsigned char temp_freespace = temperatureLength - temperatureCount; + //read the results from HP303B, new results will be added at the end of the arrays + HP303BPressureSensor.getContResults(&temperature[temperatureCount], temp_freespace, &pressure[pressureCount], prs_freespace); + //after reading the result counters are increased by the amount of new results + pressureCount += prs_freespace; + temperatureCount += temp_freespace; +} diff --git a/lib/LOLIN_HP303B/keywords.txt b/lib/LOLIN_HP303B/keywords.txt new file mode 100644 index 000000000..b283317f5 --- /dev/null +++ b/lib/LOLIN_HP303B/keywords.txt @@ -0,0 +1,26 @@ +####################################### +# Syntax Coloring Map For DHT12 +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +DHT12 KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +get KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### + +cTemp LITERAL1 +fTemp LITERAL1 +humidity LITERAL1 + + + diff --git a/lib/LOLIN_HP303B/library.properties b/lib/LOLIN_HP303B/library.properties new file mode 100644 index 000000000..7f71ad2b2 --- /dev/null +++ b/lib/LOLIN_HP303B/library.properties @@ -0,0 +1,9 @@ +name=LOLIN_HP303B +version=1.0.0 +author=WEMOS.CC +maintainer=WEMOS.CC +sentence=Library for the HP303B.. +paragraph=LOLIN HP303B +category=Device Control +url=https://github.com/wemos/LOLIN_HP303B_Library +architectures=* diff --git a/lib/LOLIN_HP303B/src/LOLIN_HP303B.cpp b/lib/LOLIN_HP303B/src/LOLIN_HP303B.cpp new file mode 100644 index 000000000..c6f8aeb1d --- /dev/null +++ b/lib/LOLIN_HP303B/src/LOLIN_HP303B.cpp @@ -0,0 +1,1685 @@ +#include "LOLIN_HP303B.h" + + + +const int32_t LOLIN_HP303B::scaling_facts[HP303B__NUM_OF_SCAL_FACTS] + = {524288, 1572864, 3670016, 7864320, 253952, 516096, 1040384, 2088960}; + + + +//////// Constructor, Destructor, begin, end //////// + + +/** + * Standard Constructor + */ +LOLIN_HP303B::LOLIN_HP303B(void) +{ + //assume that initialization has failed before it has been done + m_initFail = 1U; +} + +/** + * Standard Destructor + */ +LOLIN_HP303B::~LOLIN_HP303B(void) +{ + end(); +} + + + +/** + * Standard I2C begin function + * + * &bus: I2CBus which connects MC to HP303B + * slaveAddress: Address of the HP303B (0x77 or 0x76) + */ +uint8_t LOLIN_HP303B::begin(TwoWire &bus, uint8_t slaveAddress) +{ + //this flag will show if the initialization was successful + m_initFail = 0U; + + //Set I2C bus connection + m_SpiI2c = 1U; + m_i2cbus = &bus; + m_slaveAddress = slaveAddress; + + // Init bus + m_i2cbus->begin(); + + delay(50); //startup time of HP303B + + return init(); +} + +uint8_t LOLIN_HP303B::begin(uint8_t slaveAddress) +{ + return begin(Wire,slaveAddress); +} + +/** + * SPI begin function for HP303B with 4-wire SPI + */ +uint8_t LOLIN_HP303B::begin(SPIClass &bus, int32_t chipSelect) +{ + return begin(bus, chipSelect, 0U); +} + +/** + * Standard SPI begin function + * + * &bus: SPI bus which connects MC to HP303B + * chipSelect: Number of the CS line for the HP303B + * threeWire: 1 if HP303B is connected with 3-wire SPI + * 0 if HP303B is connected with 4-wire SPI (standard) + */ +uint8_t LOLIN_HP303B::begin(SPIClass &bus, int32_t chipSelect, uint8_t threeWire) +{ + //this flag will show if the initialization was successful + m_initFail = 0U; + + //Set SPI bus connection + m_SpiI2c = 0U; + m_spibus = &bus; + m_chipSelect = chipSelect; + + // Init bus + m_spibus->begin(); + m_spibus->setDataMode(SPI_MODE3); + + pinMode(m_chipSelect, OUTPUT); + digitalWrite(m_chipSelect, HIGH); + + delay(50); //startup time of HP303B + + //switch to 3-wire mode if necessary + //do not use writeByteBitfield or check option to set SPI mode! + //Reading is not possible until SPI-mode is valid + if(threeWire) + { + m_threeWire = 1U; + if(writeByte(HP303B__REG_ADR_SPI3W, HP303B__REG_CONTENT_SPI3W)) + { + m_initFail = 1U; + return 0U; + } + } + + return init(); +} + +/** + * End function for HP303B + * Sets the sensor to idle mode + */ +void LOLIN_HP303B::end(void) +{ + standby(); +} + + +//////// Declaration of other public functions starts here //////// + + +/** + * returns the Product ID of the connected HP303B sensor + */ +uint8_t LOLIN_HP303B::getProductId(void) +{ + return m_productID; +} + +/** + * returns the Revision ID of the connected HP303B sensor + */ +uint8_t LOLIN_HP303B::getRevisionId(void) +{ + return m_revisionID; +} + +/** + * Sets the HP303B to standby mode + * + * returns: 0 on success + * -2 if object initialization failed + * -1 on other fail + */ +int16_t LOLIN_HP303B::standby(void) +{ + //set device to idling mode + int16_t ret = setOpMode(IDLE); + if(ret != HP303B__SUCCEEDED) + { + return ret; + } + //flush the FIFO + ret = writeByteBitfield(1U, HP303B__REG_INFO_FIFO_FL); + if(ret < 0) + { + return ret; + } + //disable the FIFO + ret = writeByteBitfield(0U, HP303B__REG_INFO_FIFO_EN); + return ret; +} + + +/** + * performs one temperature measurement and writes result to the given address + * + * &result: reference to a 32-Bit signed Integer value where the result will be written + * It will not be written if result==NULL + * returns: 0 on success + * -4 if the HP303B is could not finish its measurement in time + * -3 if the HP303B is already busy + * -2 if the object initialization failed + * -1 on other fail + */ +int16_t LOLIN_HP303B::measureTempOnce(float &result) +{ + return measureTempOnce(result, m_slaveAddress, m_tempOsr); +} + +/** + * performs one temperature measurement and writes result to the given address + * + * &result: reference to a 32-Bit signed Integer value where the result will be written + * It will not be written if result==NULL + * returns: 0 on success + * -4 if the HP303B is could not finish its measurement in time + * -3 if the HP303B is already busy + * -2 if the object initialization failed + * -1 on other fail + */ +int16_t LOLIN_HP303B::measureTempOnce(float &result, uint8_t slaveAddress) +{ + return measureTempOnce(result, slaveAddress, m_tempOsr); +} + +/** + * performs one temperature measurement and writes result to the given address + * the desired precision can be set with oversamplingRate + * + * &result: reference to a 32-Bit signed Integer where the result will be written + * It will not be written if result==NULL + * oversamplingRate: a value from 0 to 7 that decides about the precision + * of the measurement + * If this value equals n, the HP303B will perform + * 2^n measurements and combine the results + * returns: 0 on success + * -4 if the HP303B is could not finish its measurement in time + * -3 if the HP303B is already busy + * -2 if the object initialization failed + * -1 on other fail + */ +int16_t LOLIN_HP303B::measureTempOnce(float &result, uint8_t slaveAddress, uint8_t oversamplingRate) +{ + //Set I2C bus connection + m_slaveAddress = slaveAddress; + + //Start measurement + int16_t ret = startMeasureTempOnce(oversamplingRate); + if(ret!=HP303B__SUCCEEDED) + { + return ret; + } + + //wait until measurement is finished + delay(calcBusyTime(0U, m_tempOsr)/HP303B__BUSYTIME_SCALING); + delay(HP303B__BUSYTIME_FAILSAFE); + + ret = getSingleResult(result); + if(ret!=HP303B__SUCCEEDED) + { + standby(); + } + return ret; +} + +/** + * starts a single temperature measurement + * + * returns: 0 on success + * -3 if the HP303B is already busy + * -2 if the object initialization failed + * -1 on other fail + */ +int16_t LOLIN_HP303B::startMeasureTempOnce(void) +{ + return startMeasureTempOnce(m_tempOsr); +} + +/** + * starts a single temperature measurement + * The desired precision can be set with oversamplingRate + * + * oversamplingRate: a value from 0 to 7 that decides about the precision + * of the measurement + * If this value equals n, the HP303B will perform + * 2^n measurements and combine the results + * returns: 0 on success + * -3 if the HP303B is already busy + * -2 if the object initialization failed + * -1 on other fail + */ +int16_t LOLIN_HP303B::startMeasureTempOnce(uint8_t oversamplingRate) +{ + //abort if device is not in idling mode + if(m_opMode!=IDLE) + { + return HP303B__FAIL_TOOBUSY; + } + + if(oversamplingRate!=m_tempOsr) + { + //configuration of oversampling rate + if(configTemp(0U, oversamplingRate) != HP303B__SUCCEEDED) + { + return HP303B__FAIL_UNKNOWN; + } + } + + //set device to temperature measuring mode + return setOpMode(0U, 1U, 0U); +} + +/** + * performs one pressure measurement and writes result to the given address + * + * &result: reference to a 32-Bit signed Integer value where the result will be written + * It will not be written if result==NULL + * returns: 0 on success + * -4 if the HP303B is could not finish its measurement in time + * -3 if the HP303B is already busy + * -2 if the object initialization failed + * -1 on other fail + */ +int16_t LOLIN_HP303B::measurePressureOnce(float &result) +{ + return measurePressureOnce(result, m_slaveAddress, m_prsOsr); +} + +/** + * performs one pressure measurement and writes result to the given address + * + * &result: reference to a 32-Bit signed Integer value where the result will be written + * It will not be written if result==NULL + * returns: 0 on success + * -4 if the HP303B is could not finish its measurement in time + * -3 if the HP303B is already busy + * -2 if the object initialization failed + * -1 on other fail + */ +int16_t LOLIN_HP303B::measurePressureOnce(float &result, uint8_t slaveAddress) +{ + return measurePressureOnce(result, slaveAddress, m_prsOsr); +} + +/** + * performs one pressure measurement and writes result to the given address + * the desired precision can be set with oversamplingRate + * + * &result: reference to a 32-Bit signed Integer where the result will be written + * It will not be written if result==NULL + * oversamplingRate: a value from 0 to 7 that decides about the precision + * of the measurement + * If this value equals n, the HP303B will perform + * 2^n measurements and combine the results + * returns: 0 on success + * -4 if the HP303B is could not finish its measurement in time + * -3 if the HP303B is already busy + * -2 if the object initialization failed + * -1 on other fail + */ +int16_t LOLIN_HP303B::measurePressureOnce(float &result, uint8_t slaveAddress, uint8_t oversamplingRate) +{ + //Set I2C bus connection + m_slaveAddress = slaveAddress; + + //start the measurement + int16_t ret = startMeasurePressureOnce(oversamplingRate); + if(ret != HP303B__SUCCEEDED) + { + return ret; + } + + //wait until measurement is finished + delay(calcBusyTime(0U, m_prsOsr)/HP303B__BUSYTIME_SCALING); + delay(HP303B__BUSYTIME_FAILSAFE); + + ret = getSingleResult(result); + if(ret!=HP303B__SUCCEEDED) + { + standby(); + } + return ret; +} + +/** + * starts a single pressure measurement + * + * returns: 0 on success + * -3 if the HP303B is already busy + * -2 if the object initialization failed + * -1 on other fail + */ +int16_t LOLIN_HP303B::startMeasurePressureOnce(void) +{ + return startMeasurePressureOnce(m_prsOsr); +} + +/** + * starts a single pressure measurement + * The desired precision can be set with oversamplingRate + * + * oversamplingRate: a value from 0 to 7 that decides about the precision + * of the measurement + * If this value equals n, the HP303B will perform + * 2^n measurements and combine the results + * returns: 0 on success + * -3 if the HP303B is already busy + * -2 if the object initialization failed + * -1 on other fail + */ +int16_t LOLIN_HP303B::startMeasurePressureOnce(uint8_t oversamplingRate) +{ + //abort if device is not in idling mode + if(m_opMode != IDLE) + { + return HP303B__FAIL_TOOBUSY; + } + //configuration of oversampling rate, lowest measure rate to avoid conflicts + if(oversamplingRate != m_prsOsr) + { + if(configPressure(0U, oversamplingRate)) + { + return HP303B__FAIL_UNKNOWN; + } + } + //set device to pressure measuring mode + return setOpMode(0U, 0U, 1U); +} + +/** + * gets the result a single temperature or pressure measurement in °C or Pa + * + * &result: reference to a 32-Bit signed Integer value where the result will be written + * returns: 0 on success + * -4 if the HP303B is still busy + * -3 if the HP303B is not in command mode + * -2 if the object initialization failed + * -1 on other fail + */ +int16_t LOLIN_HP303B::getSingleResult(float &result) +{ + //read finished bit for current opMode + int16_t rdy; + switch(m_opMode) + { + case CMD_TEMP: //temperature + rdy = readByteBitfield(HP303B__REG_INFO_TEMP_RDY); + break; + case CMD_PRS: //pressure + rdy = readByteBitfield(HP303B__REG_INFO_PRS_RDY); + break; + default: //HP303B not in command mode + return HP303B__FAIL_TOOBUSY; + } + + //read new measurement result + switch(rdy) + { + case HP303B__FAIL_UNKNOWN: //could not read ready flag + return HP303B__FAIL_UNKNOWN; + case 0: //ready flag not set, measurement still in progress + return HP303B__FAIL_UNFINISHED; + case 1: //measurement ready, expected case + LOLIN_HP303B::Mode oldMode = m_opMode; + m_opMode = IDLE; //opcode was automatically reseted by HP303B + switch(oldMode) + { + case CMD_TEMP: //temperature + return getTemp(&result); //get and calculate the temperature value + case CMD_PRS: //pressure + return getPressure(&result); //get and calculate the pressure value + default: + return HP303B__FAIL_UNKNOWN; //should already be filtered above + } + } + return HP303B__FAIL_UNKNOWN; +} + +/** + * starts a continuous temperature measurement + * The desired precision can be set with oversamplingRate + * The desired number of measurements per second can be set with measureRate + * + * measureRate: a value from 0 to 7 that decides about + * the number of measurements per second + * If this value equals n, the HP303B will perform + * 2^n measurements per second + * oversamplingRate: a value from 0 to 7 that decides about + * the precision of the measurements + * If this value equals m, the HP303B will perform + * 2^m internal measurements and combine the results + * to one more exact measurement + * returns: 0 on success + * -4 if measureRate or oversamplingRate is too high + * -3 if the HP303B is already busy + * -2 if the object initialization failed + * -1 on other fail + * NOTE: If measure rate is n and oversampling rate is m, + * the HP303B performs 2^(n+m) internal measurements per second. + * The HP303B cannot operate with high precision and high speed + * at the same time. + * Consult the datasheet for more information. + */ +int16_t LOLIN_HP303B::startMeasureTempCont(uint8_t measureRate, uint8_t oversamplingRate) +{ + //abort if initialization failed + if(m_initFail) + { + return HP303B__FAIL_INIT_FAILED; + } + //abort if device is not in idling mode + if(m_opMode != IDLE) + { + return HP303B__FAIL_TOOBUSY; + } + //abort if speed and precision are too high + if(calcBusyTime(measureRate, oversamplingRate) >= HP303B__MAX_BUSYTIME) + { + return HP303B__FAIL_UNFINISHED; + } + //update precision and measuring rate + if(configTemp(measureRate, oversamplingRate)) + { + return HP303B__FAIL_UNKNOWN; + } + //enable result FIFO + if(writeByteBitfield(1U, HP303B__REG_INFO_FIFO_EN)) + { + return HP303B__FAIL_UNKNOWN; + } + //Start measuring in background mode + if(setOpMode(1U, 1U, 0U)) + { + return HP303B__FAIL_UNKNOWN; + } + return HP303B__SUCCEEDED; +} + + +/** + * starts a continuous temperature measurement + * The desired precision can be set with oversamplingRate + * The desired number of measurements per second can be set with measureRate + * + * measureRate: a value from 0 to 7 that decides about + * the number of measurements per second + * If this value equals n, the HP303B will perform + * 2^n measurements per second + * oversamplingRate: a value from 0 to 7 that decides about the precision + * of the measurements + * If this value equals m, the HP303B will perform + * 2^m internal measurements + * and combine the results to one more exact measurement + * returns: 0 on success + * -4 if measureRate or oversamplingRate is too high + * -3 if the HP303B is already busy + * -2 if the object initialization failed + * -1 on other fail + * NOTE: If measure rate is n and oversampling rate is m, + * the HP303B performs 2^(n+m) internal measurements per second. + * The HP303B cannot operate with high precision and high speed + * at the same time. + * Consult the datasheet for more information. + */ +int16_t LOLIN_HP303B::startMeasurePressureCont(uint8_t measureRate, uint8_t oversamplingRate) +{ + //abort if initialization failed + if(m_initFail) + { + return HP303B__FAIL_INIT_FAILED; + } + //abort if device is not in idling mode + if(m_opMode != IDLE) + { + return HP303B__FAIL_TOOBUSY; + } + //abort if speed and precision are too high + if(calcBusyTime(measureRate, oversamplingRate) >= HP303B__MAX_BUSYTIME) + { + return HP303B__FAIL_UNFINISHED; + } + //update precision and measuring rate + if(configPressure(measureRate, oversamplingRate)) + return HP303B__FAIL_UNKNOWN; + //enable result FIFO + if(writeByteBitfield(1U, HP303B__REG_INFO_FIFO_EN)) + { + return HP303B__FAIL_UNKNOWN; + } + //Start measuring in background mode + if(setOpMode(1U, 0U, 1U)) + { + return HP303B__FAIL_UNKNOWN; + } + return HP303B__SUCCEEDED; +} + +/** + * starts a continuous temperature and pressure measurement + * The desired precision can be set with tempOsr and prsOsr + * The desired number of measurements per second can be set with tempMr and prsMr + * + * tempMr measure rate for temperature + * tempOsr oversampling rate for temperature + * prsMr measure rate for pressure + * prsOsr oversampling rate for pressure + * returns: 0 on success + * -4 if precision or speed is too high + * -3 if the HP303B is already busy + * -2 if the object initialization failed + * -1 on other fail + * NOTE: High precision and speed for both temperature and pressure + * can not be reached at the same time. + * Estimated time for temperature and pressure measurement + * is the sum of both values. + * This sum must not be more than 1 second. + * Consult the datasheet for more information. + */ +int16_t LOLIN_HP303B::startMeasureBothCont(uint8_t tempMr, + uint8_t tempOsr, + uint8_t prsMr, + uint8_t prsOsr) +{ + //abort if initialization failed + if(m_initFail) + { + return HP303B__FAIL_INIT_FAILED; + } + //abort if device is not in idling mode + if(m_opMode!=IDLE) + { + return HP303B__FAIL_TOOBUSY; + } + //abort if speed and precision are too high + if(calcBusyTime(tempMr, tempOsr) + calcBusyTime(prsMr, prsOsr)>=HP303B__MAX_BUSYTIME) + { + return HP303B__FAIL_UNFINISHED; + } + //update precision and measuring rate + if(configTemp(tempMr, tempOsr)) + { + return HP303B__FAIL_UNKNOWN; + } + //update precision and measuring rate + if(configPressure(prsMr, prsOsr)) + return HP303B__FAIL_UNKNOWN; + //enable result FIFO + if(writeByteBitfield(1U, HP303B__REG_INFO_FIFO_EN)) + { + return HP303B__FAIL_UNKNOWN; + } + //Start measuring in background mode + if(setOpMode(1U, 1U, 1U)) + { + return HP303B__FAIL_UNKNOWN; + } + return HP303B__SUCCEEDED; +} + +/** + * Gets the results from continuous measurements and writes them to given arrays + * + * *tempBuffer: The start address of the buffer where the temperature results + * are written + * If this is NULL, no temperature results will be written out + * &tempCount: This has to be a reference to a number which contains + * the size of the buffer for temperature results. + * When the function ends, it will contain + * the number of bytes written to the buffer + * *prsBuffer: The start address of the buffer where the pressure results + * are written + * If this is NULL, no pressure results will be written out + * &prsCount: This has to be a reference to a number which contains + * the size of the buffer for pressure results. + * When the function ends, it will contain + * the number of bytes written to the buffer + * returns: 0 on success + * -3 if HP303B is not in background mode + * -2 if the object initialization failed + * -1 on other fail + */ +int16_t LOLIN_HP303B::getContResults(float *tempBuffer, + uint8_t &tempCount, + float *prsBuffer, + uint8_t &prsCount) +{ + if(m_initFail) + { + return HP303B__FAIL_INIT_FAILED; + } + //abort if device is not in background mode + if(!(m_opMode & INVAL_OP_CONT_NONE)) + { + return HP303B__FAIL_TOOBUSY; + } + + //prepare parameters for buffer length and count + uint8_t tempLen = tempCount; + uint8_t prsLen = prsCount; + tempCount = 0U; + prsCount = 0U; + + //while FIFO is not empty + while(readByteBitfield(HP303B__REG_INFO_FIFO_EMPTY) == 0) + { + float result; + //read next result from FIFO + int16_t type = getFIFOvalue(&result); + switch(type) + { + case 0: //temperature + //calculate compensated pressure value + result = calcTemp(result); + //if buffer exists and is not full + //write result to buffer and increase temperature result counter + if(tempBuffer != NULL) + { + if(tempCount> HP303B__REG_SHIFT_INT_EN_FIFO; + tempReady &= HP303B__REG_MASK_INT_EN_TEMP >> HP303B__REG_SHIFT_INT_EN_TEMP; + prsReady &= HP303B__REG_MASK_INT_EN_PRS >> HP303B__REG_SHIFT_INT_EN_PRS; + //read old value from register + int16_t regData = readByte(HP303B__REG_ADR_INT_EN_FIFO); + if(regData <0) + { + return HP303B__FAIL_UNKNOWN; + } + uint8_t toWrite = (uint8_t)regData; + //update FIFO enable bit + toWrite &= ~HP303B__REG_MASK_INT_EN_FIFO; //clear bit + toWrite |= fifoFull << HP303B__REG_SHIFT_INT_EN_FIFO; //set new bit + //update TempReady enable bit + toWrite &= ~HP303B__REG_MASK_INT_EN_TEMP; + toWrite |= tempReady << HP303B__REG_SHIFT_INT_EN_TEMP; + //update PrsReady enable bit + toWrite &= ~HP303B__REG_MASK_INT_EN_PRS; + toWrite |= prsReady << HP303B__REG_SHIFT_INT_EN_PRS; + //write updated value to register + return writeByte(HP303B__REG_ADR_INT_EN_FIFO, toWrite); +} + +/** + * Gets the interrupt status flag of the FIFO + * + * Returns: 1 if the FIFO is full and caused an interrupt + * 0 if the FIFO is not full or FIFO interrupt is disabled + * -1 on fail + */ +int16_t LOLIN_HP303B::getIntStatusFifoFull(void) +{ + return readByteBitfield(HP303B__REG_INFO_INT_FLAG_FIFO); +} + +/** + * Gets the interrupt status flag that indicates a finished temperature measurement + * + * Returns: 1 if a finished temperature measurement caused an interrupt + * 0 if there is no finished temperature measurement + * or interrupts are disabled + * -1 on fail + */ +int16_t LOLIN_HP303B::getIntStatusTempReady(void) +{ + return readByteBitfield(HP303B__REG_INFO_INT_FLAG_TEMP); +} + +/** + * Gets the interrupt status flag that indicates a finished pressure measurement + * + * Returns: 1 if a finished pressure measurement caused an interrupt + * 0 if there is no finished pressure measurement + * or interrupts are disabled + * -1 on fail + */ +int16_t LOLIN_HP303B::getIntStatusPrsReady(void) +{ + return readByteBitfield(HP303B__REG_INFO_INT_FLAG_PRS); +} + +/** + * Function to fix a hardware problem on some devices + * You have this problem if you measure a temperature which is too high (e.g. 60°C when temperature is around 20°C) + * Call correctTemp() directly after begin() to fix this issue + */ +int16_t LOLIN_HP303B::correctTemp(void) +{ + if(m_initFail) + { + return HP303B__FAIL_INIT_FAILED; + } + writeByte(0x0E, 0xA5); + writeByte(0x0F, 0x96); + writeByte(0x62, 0x02); + writeByte(0x0E, 0x00); + writeByte(0x0F, 0x00); + + //perform a first temperature measurement (again) + //the most recent temperature will be saved internally + //and used for compensation when calculating pressure + float trash; + measureTempOnce(trash); + + return HP303B__SUCCEEDED; +} + + + +//////// Declaration of private functions starts here //////// + + +/** + * Initializes the sensor. + * This function has to be called from begin() + * and requires a valid bus initialization. + */ +uint8_t LOLIN_HP303B::init(void) +{ + int16_t prodId = readByteBitfield(HP303B__REG_INFO_PROD_ID); + if(prodId != HP303B__PROD_ID) + { + //Connected device is not a HP303B + m_initFail = 1U; + return 0U; + } + m_productID = prodId; + + int16_t revId = readByteBitfield(HP303B__REG_INFO_REV_ID); + if(revId < 0) + { + m_initFail = 1U; + return 0U; + } + m_revisionID = revId; + + //find out which temperature sensor is calibrated with coefficients... + int16_t sensor = readByteBitfield(HP303B__REG_INFO_TEMP_SENSORREC); + if(sensor < 0) + { + m_initFail = 1U; + return 0U; + } + + //...and use this sensor for temperature measurement + m_tempSensor = sensor; + if(writeByteBitfield((uint8_t)sensor, HP303B__REG_INFO_TEMP_SENSOR) < 0) + { + m_initFail = 1U; + return 0U; + } + + //read coefficients + if(readcoeffs() < 0) + { + m_initFail = 1U; + return 0U; + } + + //set to standby for further configuration + standby(); + + //set measurement precision and rate to standard values; + configTemp(HP303B__TEMP_STD_MR, HP303B__TEMP_STD_OSR); + configPressure(HP303B__PRS_STD_MR, HP303B__PRS_STD_OSR); + + //perform a first temperature measurement + //the most recent temperature will be saved internally + //and used for compensation when calculating pressure + float trash; + measureTempOnce(trash); + + //make sure the HP303B is in standby after initialization + standby(); + + // Fix IC with a fuse bit problem, which lead to a wrong temperature + // Should not affect ICs without this problem + correctTemp(); + + return 1U; +} + + +/** + * reads the compensation coefficients from the HP303B + * this is called once from init(), which is called from begin() + * + * returns: 0 on success, -1 on fail + */ +int16_t LOLIN_HP303B::readcoeffs(void) +{ + uint8_t buffer[HP303B__REG_LEN_COEF]; + //read COEF registers to buffer + int16_t ret = readBlock(HP303B__REG_ADR_COEF, + HP303B__REG_LEN_COEF, + buffer); + //abort if less than REG_LEN_COEF bytes were read + if(ret < HP303B__REG_LEN_COEF) + { + return HP303B__FAIL_UNKNOWN; + } + + //compose coefficients from buffer content + m_c0Half = ((uint32_t)buffer[0] << 4) + | (((uint32_t)buffer[1] >> 4) & 0x0F); + //this construction recognizes non-32-bit negative numbers + //and converts them to 32-bit negative numbers with 2's complement + if(m_c0Half & ((uint32_t)1 << 11)) + { + m_c0Half -= (uint32_t)1 << 12; + } + //c0 is only used as c0*0.5, so c0_half is calculated immediately + m_c0Half = m_c0Half / 2U; + + //now do the same thing for all other coefficients + m_c1 = (((uint32_t)buffer[1] & 0x0F) << 8) | (uint32_t)buffer[2]; + if(m_c1 & ((uint32_t)1 << 11)) + { + m_c1 -= (uint32_t)1 << 12; + } + + m_c00 = ((uint32_t)buffer[3] << 12) + | ((uint32_t)buffer[4] << 4) + | (((uint32_t)buffer[5] >> 4) & 0x0F); + if(m_c00 & ((uint32_t)1 << 19)) + { + m_c00 -= (uint32_t)1 << 20; + } + + m_c10 = (((uint32_t)buffer[5] & 0x0F) << 16) + | ((uint32_t)buffer[6] << 8) + | (uint32_t)buffer[7]; + if(m_c10 & ((uint32_t)1<<19)) + { + m_c10 -= (uint32_t)1 << 20; + } + + m_c01 = ((uint32_t)buffer[8] << 8) + | (uint32_t)buffer[9]; + if(m_c01 & ((uint32_t)1 << 15)) + { + m_c01 -= (uint32_t)1 << 16; + } + + m_c11 = ((uint32_t)buffer[10] << 8) + | (uint32_t)buffer[11]; + if(m_c11 & ((uint32_t)1 << 15)) + { + m_c11 -= (uint32_t)1 << 16; + } + + m_c20 = ((uint32_t)buffer[12] << 8) + | (uint32_t)buffer[13]; + if(m_c20 & ((uint32_t)1 << 15)) + { + m_c20 -= (uint32_t)1 << 16; + } + + m_c21 = ((uint32_t)buffer[14] << 8) + | (uint32_t)buffer[15]; + if(m_c21 & ((uint32_t)1 << 15)) + { + m_c21 -= (uint32_t)1 << 16; + } + + m_c30 = ((uint32_t)buffer[16] << 8) + | (uint32_t)buffer[17]; + if(m_c30 & ((uint32_t)1 << 15)) + { + m_c30 -= (uint32_t)1 << 16; + } + + return HP303B__SUCCEEDED; +} + +/** + * Sets the Operation Mode of the HP303B + * + * background: determines the general behavior of the HP303B + * 0 enables command mode (only measure on commands) + * 1 enables background mode (continuous work in background) + * temperature: set 1 to measure temperature + * pressure: set 1 to measure pressure + * return: 0 on success, -1 on fail + * + * NOTE! + * You cannot set background to 1 without setting temperature and pressure + * You cannot set both temperature and pressure when background mode is disabled + */ +int16_t LOLIN_HP303B::setOpMode(uint8_t background, uint8_t temperature, uint8_t pressure) +{ + uint8_t opMode = (background & HP303B__LSB) << 2U + | (temperature & HP303B__LSB) << 1U + | (pressure & HP303B__LSB); + return setOpMode(opMode); +} + + +/** + * Sets the Operation Mode of the HP303B + * + * opMode: the new OpMode that has to be set + * return: 0 on success, -1 on fail + * + * NOTE! + * You cannot set background to 1 without setting temperature and pressure + * You cannot set both temperature and pressure when background mode is disabled + */ +int16_t LOLIN_HP303B::setOpMode(uint8_t opMode) +{ + //Filter irrelevant bits + opMode &= HP303B__REG_MASK_OPMODE >> HP303B__REG_SHIFT_OPMODE; + //Filter invalid OpModes + if(opMode == INVAL_OP_CMD_BOTH || opMode == INVAL_OP_CONT_NONE) + { + return HP303B__FAIL_UNKNOWN; + } + //Set OpMode + if(writeByte(HP303B__REG_ADR_OPMODE, opMode)) + { + return HP303B__FAIL_UNKNOWN; + } + m_opMode = (LOLIN_HP303B::Mode)opMode; + return HP303B__SUCCEEDED; +} + +/** + * Configures temperature measurement + * + * tempMr: the new measure rate for temperature + * This can be a value from 0U to 7U. + * Actual measure rate will be 2^tempMr, + * so this will be a value from 1 to 128. + * tempOsr: the new oversampling rate for temperature + * This can be a value from 0U to 7U. + * Actual measure rate will be 2^tempOsr, + * so this will be a value from 1 to 128. + * returns: 0 normally or -1 on fail + */ +int16_t LOLIN_HP303B::configTemp(uint8_t tempMr, uint8_t tempOsr) +{ + //mask parameters + tempMr &= HP303B__REG_MASK_TEMP_MR >> HP303B__REG_SHIFT_TEMP_MR; + tempOsr &= HP303B__REG_MASK_TEMP_OSR >> HP303B__REG_SHIFT_TEMP_OSR; + + //set config register according to parameters + uint8_t toWrite = tempMr << HP303B__REG_SHIFT_TEMP_MR; + toWrite |= tempOsr << HP303B__REG_SHIFT_TEMP_OSR; + //using recommended temperature sensor + toWrite |= HP303B__REG_MASK_TEMP_SENSOR + & (m_tempSensor << HP303B__REG_SHIFT_TEMP_SENSOR); + int16_t ret = writeByte(HP303B__REG_ADR_TEMP_MR, toWrite); + //abort immediately on fail + if(ret != HP303B__SUCCEEDED) + { + return HP303B__FAIL_UNKNOWN; + } + + //set TEMP SHIFT ENABLE if oversampling rate higher than eight(2^3) + if(tempOsr > HP303B__OSR_SE) + { + ret=writeByteBitfield(1U, HP303B__REG_INFO_TEMP_SE); + } + else + { + ret=writeByteBitfield(0U, HP303B__REG_INFO_TEMP_SE); + } + + if(ret == HP303B__SUCCEEDED) + { //save new settings + m_tempMr = tempMr; + m_tempOsr = tempOsr; + } + else + { + //try to rollback on fail avoiding endless recursion + //this is to make sure that shift enable and oversampling rate + //are always consistent + if(tempMr != m_tempMr || tempOsr != m_tempOsr) + { + configTemp(m_tempMr, m_tempOsr); + } + } + return ret; +} + +/** + * Configures pressure measurement + * + * prsMr: the new measure rate for pressure + * This can be a value from 0U to 7U. + * Actual measure rate will be 2^prs_mr, + * so this will be a value from 1 to 128. + * prsOs: the new oversampling rate for temperature + * This can be a value from 0U to 7U. + * Actual measure rate will be 2^prsOsr, + * so this will be a value from 1 to 128. + * returns: 0 normally or -1 on fail + */ +int16_t LOLIN_HP303B::configPressure(uint8_t prsMr, uint8_t prsOsr) +{ + //mask parameters + prsMr &= HP303B__REG_MASK_PRS_MR >> HP303B__REG_SHIFT_PRS_MR; + prsOsr &= HP303B__REG_MASK_PRS_OSR >> HP303B__REG_SHIFT_PRS_OSR; + + //set config register according to parameters + uint8_t toWrite = prsMr << HP303B__REG_SHIFT_PRS_MR; + toWrite |= prsOsr << HP303B__REG_SHIFT_PRS_OSR; + int16_t ret = writeByte(HP303B__REG_ADR_PRS_MR, toWrite); + //abort immediately on fail + if(ret != HP303B__SUCCEEDED) + { + return HP303B__FAIL_UNKNOWN; + } + + //set PM SHIFT ENABLE if oversampling rate higher than eight(2^3) + if(prsOsr > HP303B__OSR_SE) + { + ret = writeByteBitfield(1U, HP303B__REG_INFO_PRS_SE); + } + else + { + ret = writeByteBitfield(0U, HP303B__REG_INFO_PRS_SE); + } + + if(ret == HP303B__SUCCEEDED) + { //save new settings + m_prsMr = prsMr; + m_prsOsr = prsOsr; + } + else + { //try to rollback on fail avoiding endless recursion + //this is to make sure that shift enable and oversampling rate + //are always consistent + if(prsMr != m_prsMr || prsOsr != m_prsOsr) + { + configPressure(m_prsMr, m_prsOsr); + } + } + return ret; +} + +/** + * calculates the time that the HP303B needs for 2^mr measurements + * with an oversampling rate of 2^osr + * + * mr: Measure rate for temperature or pressure + * osr: Oversampling rate for temperature or pressure + * returns: time that the HP303B needs for this measurement + * a value of 10000 equals 1 second + * NOTE! The measurement time for temperature and pressure + * in sum must not be more than 1 second! + * Timing behavior of pressure and temperature sensors + * can be considered as equal. + */ +uint16_t LOLIN_HP303B::calcBusyTime(uint16_t mr, uint16_t osr) +{ + //mask parameters first + mr &= HP303B__REG_MASK_TEMP_MR >> HP303B__REG_SHIFT_TEMP_MR; + osr &= HP303B__REG_MASK_TEMP_OSR >> HP303B__REG_SHIFT_TEMP_OSR; + //formula from datasheet (optimized) + return ((uint32_t)20U << mr) + ((uint32_t)16U << (osr + mr)); +} + +/** + * Gets the next temperature measurement result in degrees of Celsius + * + * result: address where the result will be written + * returns: 0 on success + * -1 on fail; + */ +int16_t LOLIN_HP303B::getTemp(float *result) +{ + unsigned char buffer[3] = {0}; + //read raw pressure data to buffer + + int16_t i = readBlock(HP303B__REG_ADR_TEMP, + HP303B__REG_LEN_TEMP, + buffer); + if(i != HP303B__REG_LEN_TEMP) + { + //something went wrong + return HP303B__FAIL_UNKNOWN; + } + + //compose raw temperature value from buffer + float temp = buffer[0] << 16 + | buffer[1] << 8 + | buffer[2]; + //recognize non-32-bit negative numbers + //and convert them to 32-bit negative numbers using 2's complement + if(temp > 0x7FFFFF) + { + temp = temp - 0x1000000; + } + + //return temperature + *result = calcTemp(temp); + return HP303B__SUCCEEDED; +} + +/** + * Gets the next pressure measurement result in Pa + * + * result: address where the result will be written + * returns: 0 on success + * -1 on fail; + */ +int16_t LOLIN_HP303B::getPressure(float *result) +{ + unsigned char buffer[3] = {0}; + //read raw pressure data to buffer + int16_t i = readBlock(HP303B__REG_ADR_PRS, + HP303B__REG_LEN_PRS, + buffer); + if(i != HP303B__REG_LEN_PRS) + { + //something went wrong + //negative pressure is not allowed + return HP303B__FAIL_UNKNOWN; + } + + //compose raw pressure value from buffer + float prs = buffer[0] << 16 | buffer[1] << 8 | buffer[2]; + //recognize non-32-bit negative numbers + //and convert them to 32-bit negative numbers using 2's complement + if(prs > 0x7FFFFF) + { + prs = prs - 0x1000000; + } + + *result = calcPressure(prs); + return HP303B__SUCCEEDED; +} + +/** + * reads the next raw value from the HP303B FIFO + * + * value: address where the value will be written + * returns: -1 on fail + * 0 if result is a temperature raw value + * 1 if result is a pressure raw value + */ +int16_t LOLIN_HP303B::getFIFOvalue(float *value) +{ + //abort on invalid argument + if(value == NULL) + { + return HP303B__FAIL_UNKNOWN; + } + + unsigned char buffer[HP303B__REG_LEN_PRS] = {0}; + //always read from pressure raw value register + int16_t i = readBlock(HP303B__REG_ADR_PRS, + HP303B__REG_LEN_PRS, + buffer); + if(i != HP303B__REG_LEN_PRS) + { + //something went wrong + //return error code + return HP303B__FAIL_UNKNOWN; + } + //compose raw pressure value from buffer + *value = buffer[0] << 16 + | buffer[1] << 8 + | buffer[2]; + //recognize non-32-bit negative numbers + //and convert them to 32-bit negative numbers using 2's complement + if(*value > 0x7FFFFF) + { + *value = *value - 0x1000000; + } + + //least significant bit shows measurement type + return buffer[2] & HP303B__LSB; +} + +/** + * Calculates a scaled and compensated pressure value from raw data + * raw: raw temperature value read from HP303B + * returns: temperature value in °C + */ +float LOLIN_HP303B::calcTemp(float raw) +{ + double temp = raw; + + //scale temperature according to scaling table and oversampling + temp /= scaling_facts[m_tempOsr]; + + //update last measured temperature + //it will be used for pressure compensation + m_lastTempScal = temp; + + //Calculate compensated temperature + temp = m_c0Half + m_c1 * temp; + + //return temperature + return (float)temp; +} + +/** + * Calculates a scaled and compensated pressure value from raw data + * raw: raw pressure value read from HP303B + * returns: pressure value in Pa + */ +float LOLIN_HP303B::calcPressure(float raw) +{ + double prs = raw; + + //scale pressure according to scaling table and oversampling + prs /= scaling_facts[m_prsOsr]; + + //Calculate compensated pressure + prs = m_c00 + + prs * (m_c10 + prs * (m_c20 + prs * m_c30)) + + m_lastTempScal * (m_c01 + prs * (m_c11 + prs * m_c21)); + + //return pressure + return (float)prs; +} + +/** + * reads a byte from HP303B + * + * regAdress: Address that has to be read + * returns: register content or -1 on fail + */ +int16_t LOLIN_HP303B::readByte(uint8_t regAddress) +{ + //delegate to specialized function if HP303B is connected via SPI + if(m_SpiI2c==0) + { + return readByteSPI(regAddress); + } + + m_i2cbus->beginTransmission(m_slaveAddress); + m_i2cbus->write(regAddress); + m_i2cbus->endTransmission(0); + //request 1 byte from slave + if(m_i2cbus->requestFrom(m_slaveAddress, 1U, 1U) > 0) + { + return m_i2cbus->read(); //return this byte on success + } + else + { + return HP303B__FAIL_UNKNOWN; //if 0 bytes were read successfully + } +} + +/** + * reads a byte from HP303B via SPI + * this function is automatically called by readByte + * if HP303B is connected via SPI + * + * regAdress: Address that has to be read + * returns: register content or -1 on fail + */ +int16_t LOLIN_HP303B::readByteSPI(uint8_t regAddress) +{ + //this function is only made for communication via SPI + if(m_SpiI2c != 0) + { + return HP303B__FAIL_UNKNOWN; + } + //mask regAddress + regAddress &= ~HP303B__SPI_RW_MASK; + //reserve and initialize bus + m_spibus->beginTransaction(SPISettings(HP303B__SPI_MAX_FREQ, + MSBFIRST, + SPI_MODE3)); + //enable ChipSelect for HP303B + digitalWrite(m_chipSelect, LOW); + //send address with read command to HP303B + m_spibus->transfer(regAddress | HP303B__SPI_READ_CMD); + //receive register content from HP303B + uint8_t ret = m_spibus->transfer(0xFF); //send a dummy byte while receiving + //disable ChipSelect for HP303B + digitalWrite(m_chipSelect, HIGH); + //close current SPI transaction + m_spibus->endTransaction(); + //return received data + return ret; +} + +/** + * reads a block from HP303B + * + * regAdress: Address that has to be read + * length: Length of data block + * buffer: Buffer where data will be stored + * returns: number of bytes that have been read successfully + * NOTE! This is not always equal to length + * due to rx-Buffer overflow etc. + */ +int16_t LOLIN_HP303B::readBlock(uint8_t regAddress, uint8_t length, uint8_t *buffer) +{ + //delegate to specialized function if HP303B is connected via SPI + if(m_SpiI2c == 0) + { + return readBlockSPI(regAddress, length, buffer); + } + //do not read if there is no buffer + if(buffer == NULL) + { + return 0; //0 bytes read successfully + } + + m_i2cbus->beginTransmission(m_slaveAddress); + m_i2cbus->write(regAddress); + m_i2cbus->endTransmission(0); + //request length bytes from slave + int16_t ret = m_i2cbus->requestFrom(m_slaveAddress, length, 1U); + //read all received bytes to buffer + for(int16_t count = 0; count < ret; count++) + { + buffer[count] = m_i2cbus->read(); + } + return ret; +} + +/** + * reads a block from HP303B via SPI + * + * regAdress: Address that has to be read + * length: Length of data block + * readbuffer: Buffer where data will be stored + * returns: number of bytes that have been read successfully + * NOTE! This is not always equal to length + * due to rx-Buffer overflow etc. + */ +int16_t LOLIN_HP303B::readBlockSPI(uint8_t regAddress, uint8_t length, uint8_t *buffer) +{ + //this function is only made for communication via SPI + if(m_SpiI2c != 0) + { + return HP303B__FAIL_UNKNOWN; + } + //do not read if there is no buffer + if(buffer == NULL) + { + return 0; //0 bytes were read successfully + } + //mask regAddress + regAddress &= ~HP303B__SPI_RW_MASK; + //reserve and initialize bus + m_spibus->beginTransaction(SPISettings(HP303B__SPI_MAX_FREQ, + MSBFIRST, + SPI_MODE3)); + //enable ChipSelect for HP303B + digitalWrite(m_chipSelect, LOW); + //send address with read command to HP303B + m_spibus->transfer(regAddress | HP303B__SPI_READ_CMD); + + //receive register contents from HP303B + for(uint8_t count = 0; count < length; count++) + { + buffer[count] = m_spibus->transfer(0xFF);//send a dummy byte while receiving + } + + //disable ChipSelect for HP303B + digitalWrite(m_chipSelect, HIGH); + //close current SPI transaction + m_spibus->endTransaction(); + //return received data + return length; +} + +/** + * writes a given byte to a given register of HP303B without checking + * + * regAdress: Address of the register that has to be updated + * data: Byte that will be written to the register + * return: 0 if byte was written successfully + * or -1 on fail + */ +int16_t LOLIN_HP303B::writeByte(uint8_t regAddress, uint8_t data) +{ + return writeByte(regAddress, data, 0U); +} + +/** + * writes a given byte to a given register of HP303B + * + * regAdress: Address of the register that has to be updated + * data: Byte that will be written to the register + * check: If this is true, register content will be read after writing + * to check if update was successful + * return: 0 if byte was written successfully + * or -1 on fail + */ +int16_t LOLIN_HP303B::writeByte(uint8_t regAddress, uint8_t data, uint8_t check) +{ + //delegate to specialized function if HP303B is connected via SPI + if(m_SpiI2c==0) + { + return writeByteSpi(regAddress, data, check); + } + m_i2cbus->beginTransmission(m_slaveAddress); + m_i2cbus->write(regAddress); //Write Register number to buffer + m_i2cbus->write(data); //Write data to buffer + if(m_i2cbus->endTransmission() != 0) //Send buffer content to slave + { + return HP303B__FAIL_UNKNOWN; + } + else + { + if(check == 0) return 0; //no checking + if(readByte(regAddress) == data) //check if desired by calling function + { + return HP303B__SUCCEEDED; + } + else + { + return HP303B__FAIL_UNKNOWN; + } + } +} + +/** + * writes a given byte to a given register of HP303B via SPI + * + * regAdress: Address of the register that has to be updated + * data: Byte that will be written to the register + * check: If this is true, register content will be read after writing + * to check if update was successful + * return: 0 if byte was written successfully + * or -1 on fail + */ +int16_t LOLIN_HP303B::writeByteSpi(uint8_t regAddress, uint8_t data, uint8_t check) +{ + //this function is only made for communication via SPI + if(m_SpiI2c != 0) + { + return HP303B__FAIL_UNKNOWN; + } + //mask regAddress + regAddress &= ~HP303B__SPI_RW_MASK; + //reserve and initialize bus + m_spibus->beginTransaction(SPISettings(HP303B__SPI_MAX_FREQ, + MSBFIRST, + SPI_MODE3)); + //enable ChipSelect for HP303B + digitalWrite(m_chipSelect, LOW); + //send address with read command to HP303B + m_spibus->transfer(regAddress | HP303B__SPI_WRITE_CMD); + + //write register content from HP303B + m_spibus->transfer(data); + + //disable ChipSelect for HP303B + digitalWrite(m_chipSelect, HIGH); + //close current SPI transaction + m_spibus->endTransaction(); + + //check if necessary + if(check == 0) + { + //no checking necessary + return HP303B__SUCCEEDED; + } + //checking necessary + if(readByte(regAddress) == data) + { + //check passed + return HP303B__SUCCEEDED; + } + else + { + //check failed + return HP303B__FAIL_UNKNOWN; + } +} + +/** + * updates some given bits of a given register of HP303B without checking + * + * regAdress: Address of the register that has to be updated + * data: BitValues that will be written to the register + * shift: Amount of bits the data byte is shifted (left) before being masked + * mask: Masks the bits of the register that have to be updated + * Bits with value 1 are updated + * Bits with value 0 are not changed + * return: 0 if byte was written successfully + * or -1 on fail + */ +int16_t LOLIN_HP303B::writeByteBitfield(uint8_t data, + uint8_t regAddress, + uint8_t mask, + uint8_t shift) +{ + return writeByteBitfield(data, regAddress, mask, shift, 0U); +} + +/** + * updates some given bits of a given register of HP303B + * + * regAdress: Address of the register that has to be updated + * data: BitValues that will be written to the register + * shift: Amount of bits the data byte is shifted (left) before being masked + * mask: Masks the bits of the register that have to be updated + * Bits with value 1 are updated + * Bits with value 0 are not changed + * check: enables/disables check after writing + * 0 disables check + * if check fails, -1 will be returned + * return: 0 if byte was written successfully + * or -1 on fail + */ +int16_t LOLIN_HP303B::writeByteBitfield(uint8_t data, + uint8_t regAddress, + uint8_t mask, + uint8_t shift, + uint8_t check) +{ + int16_t old = readByte(regAddress); + if(old < 0) + { + //fail while reading + return old; + } + return writeByte(regAddress, ((uint8_t)old & ~mask)|((data << shift) & mask), check); +} + +/** + * reads some given bits of a given register of HP303B + * + * regAdress: Address of the register that has to be updated + * mask: Masks the bits of the register that have to be updated + * Bits masked with value 1 are read + * Bits masked with value 0 are set 0 + * shift: Amount of bits the data byte is shifted (right) after being masked + * return: read and processed bits + * or -1 on fail + */ +int16_t LOLIN_HP303B::readByteBitfield(uint8_t regAddress, uint8_t mask, uint8_t shift) +{ + int16_t ret = readByte(regAddress); + if(ret<0) + { + return ret; + } + return (((uint8_t)ret) & mask) >> shift; +} diff --git a/lib/LOLIN_HP303B/src/LOLIN_HP303B.h b/lib/LOLIN_HP303B/src/LOLIN_HP303B.h new file mode 100644 index 000000000..4d04ff6da --- /dev/null +++ b/lib/LOLIN_HP303B/src/LOLIN_HP303B.h @@ -0,0 +1,146 @@ +#ifndef __LOLIN_HP303B_H +#define __LOLIN_HP303B_H + +#if ARDUINO >= 100 +#include "Arduino.h" +#else +#include "WProgram.h" +#endif + +#include +#include +#include "util/hp303b_consts.h" + +class LOLIN_HP303B +{ +public: + //constructor + LOLIN_HP303B(void); + //destructor + ~LOLIN_HP303B(void); + //begin + uint8_t begin(TwoWire &bus, uint8_t slaveAddress); + uint8_t begin(uint8_t slaveAddress=HP303B__STD_SLAVE_ADDRESS); + uint8_t begin(SPIClass &bus, int32_t chipSelect); + uint8_t begin(SPIClass &bus, int32_t chipSelect, uint8_t threeWire); + //end + void end(void); + + //general + uint8_t getProductId(void); + uint8_t getRevisionId(void); + + //Idle Mode + int16_t standby(void); + + //Command Mode + int16_t measureTempOnce(float &result); + int16_t measureTempOnce(float &result, uint8_t slaveAddress); + int16_t measureTempOnce(float &result, uint8_t slaveAddress, uint8_t oversamplingRate); + int16_t startMeasureTempOnce(void); + int16_t startMeasureTempOnce(uint8_t oversamplingRate); + int16_t measurePressureOnce(float &result); + int16_t measurePressureOnce(float &result, uint8_t slaveAddress); + int16_t measurePressureOnce(float &result, uint8_t slaveAddress, uint8_t oversamplingRate); + int16_t startMeasurePressureOnce(void); + int16_t startMeasurePressureOnce(uint8_t oversamplingRate); + int16_t getSingleResult(float &result); + + //Background Mode + int16_t startMeasureTempCont(uint8_t measureRate, uint8_t oversamplingRate); + int16_t startMeasurePressureCont(uint8_t measureRate, uint8_t oversamplingRate); + int16_t startMeasureBothCont(uint8_t tempMr, uint8_t tempOsr, uint8_t prsMr, uint8_t prsOsr); + int16_t getContResults(float *tempBuffer, uint8_t &tempCount, float *prsBuffer, uint8_t &prsCount); + + //Interrupt Control + int16_t setInterruptPolarity(uint8_t polarity); + int16_t setInterruptSources(uint8_t fifoFull, uint8_t tempReady, uint8_t prsReady); + int16_t getIntStatusFifoFull(void); + int16_t getIntStatusTempReady(void); + int16_t getIntStatusPrsReady(void); + + //function to fix a hardware problem on some devices + int16_t correctTemp(void); + +private: + //scaling factor table + static const int32_t scaling_facts[HP303B__NUM_OF_SCAL_FACTS]; + + //enum for operating mode + enum Mode + { + IDLE = 0x00, + CMD_PRS = 0x01, + CMD_TEMP = 0x02, + INVAL_OP_CMD_BOTH = 0x03, //invalid + INVAL_OP_CONT_NONE = 0x04, //invalid + CONT_PRS = 0x05, + CONT_TMP = 0x06, + CONT_BOTH = 0x07 + }; + Mode m_opMode; + + //flags + uint8_t m_initFail; + uint8_t m_productID; + uint8_t m_revisionID; + + //settings + uint8_t m_tempMr; + uint8_t m_tempOsr; + uint8_t m_prsMr; + uint8_t m_prsOsr; + uint8_t m_tempSensor; + + //compensation coefficients + int32_t m_c0Half; + int32_t m_c1; + int32_t m_c00; + int32_t m_c10; + int32_t m_c01; + int32_t m_c11; + int32_t m_c20; + int32_t m_c21; + int32_t m_c30; + //last measured scaled temperature + //(necessary for pressure compensation) + double m_lastTempScal; + + //bus specific + uint8_t m_SpiI2c; //0=SPI, 1=I2C + //used for I2C + TwoWire *m_i2cbus; + uint8_t m_slaveAddress; + //used for SPI + SPIClass *m_spibus; + int32_t m_chipSelect; + uint8_t m_threeWire; + + //measurement + uint8_t init(void); + int16_t readcoeffs(void); + int16_t setOpMode(uint8_t background, uint8_t temperature, uint8_t pressure); + int16_t setOpMode(uint8_t opMode); + int16_t configTemp(uint8_t temp_mr, uint8_t temp_osr); + int16_t configPressure(uint8_t prs_mr, uint8_t prs_osr); + uint16_t calcBusyTime(uint16_t temp_rate, uint16_t temp_osr); + int16_t getTemp(float *result); + int16_t getPressure(float *result); + int16_t getFIFOvalue(float *value); + float calcTemp(float raw); + float calcPressure(float raw); + + //bus specific + int16_t readByte(uint8_t regAddress); + int16_t readByteSPI(uint8_t regAddress); + int16_t readBlock(uint8_t regAddress, uint8_t length, uint8_t *buffer); + int16_t readBlockSPI(uint8_t regAddress, uint8_t length, uint8_t *readbuffer); + int16_t writeByte(uint8_t regAddress, uint8_t data); + int16_t writeByte(uint8_t regAddress, uint8_t data, uint8_t check); + int16_t writeByteSpi(uint8_t regAddress, uint8_t data, uint8_t check); + int16_t writeByteBitfield(uint8_t data, uint8_t regAddress, uint8_t mask, uint8_t shift); + int16_t writeByteBitfield(uint8_t data, uint8_t regAddress, uint8_t mask, uint8_t shift, uint8_t check); + int16_t readByteBitfield(uint8_t regAddress, uint8_t mask, uint8_t shift); +}; + +#endif diff --git a/lib/LOLIN_HP303B/src/util/hp303b_consts.h b/lib/LOLIN_HP303B/src/util/hp303b_consts.h new file mode 100644 index 000000000..f93629e93 --- /dev/null +++ b/lib/LOLIN_HP303B/src/util/hp303b_consts.h @@ -0,0 +1,258 @@ +/** + * + * + */ + +#ifndef __HP303B_CONSTS_H_ +#define __HP303B_CONSTS_H_ + + + //general Constants +#define HP303B__PROD_ID 0U +#define HP303B__STD_SLAVE_ADDRESS 0x77U +#define HP303B__SPI_WRITE_CMD 0x00U +#define HP303B__SPI_READ_CMD 0x80U +#define HP303B__SPI_RW_MASK 0x80U +#define HP303B__SPI_MAX_FREQ 100000U + +#define HP303B__LSB 0x01U + +#define HP303B__TEMP_STD_MR 2U +#define HP303B__TEMP_STD_OSR 3U +#define HP303B__PRS_STD_MR 2U +#define HP303B__PRS_STD_OSR 3U +#define HP303B__OSR_SE 3U +//we use 0.1 mS units for time calculations, so 10 units are one millisecond +#define HP303B__BUSYTIME_SCALING 10U +// DPS310 has 10 milliseconds of spare time for each synchronous measurement / per second for asynchronous measurements +// this is for error prevention on friday-afternoon-products :D +// you can set it to 0 if you dare, but there is no warranty that it will still work +#define HP303B__BUSYTIME_FAILSAFE 10U +#define HP303B__MAX_BUSYTIME ((1000U-HP303B__BUSYTIME_FAILSAFE)*HP303B__BUSYTIME_SCALING) +#define HP303B__NUM_OF_SCAL_FACTS 8 + +#define HP303B__SUCCEEDED 0 +#define HP303B__FAIL_UNKNOWN -1 +#define HP303B__FAIL_INIT_FAILED -2 +#define HP303B__FAIL_TOOBUSY -3 +#define HP303B__FAIL_UNFINISHED -4 + + + //Constants for register manipulation + //SPI mode (3 or 4 wire) +#define HP303B__REG_ADR_SPI3W 0x09U +#define HP303B__REG_CONTENT_SPI3W 0x01U + + + //product id +#define HP303B__REG_INFO_PROD_ID HP303B__REG_ADR_PROD_ID, \ + HP303B__REG_MASK_PROD_ID, \ + HP303B__REG_SHIFT_PROD_ID +#define HP303B__REG_ADR_PROD_ID 0x0DU +#define HP303B__REG_MASK_PROD_ID 0x0FU +#define HP303B__REG_SHIFT_PROD_ID 0U + + //revision id +#define HP303B__REG_INFO_REV_ID HP303B__REG_ADR_REV_ID, \ + HP303B__REG_MASK_REV_ID, \ + HP303B__REG_SHIFT_REV_ID +#define HP303B__REG_ADR_REV_ID 0x0DU +#define HP303B__REG_MASK_REV_ID 0xF0U +#define HP303B__REG_SHIFT_REV_ID 4U + + //operating mode +#define HP303B__REG_INFO_OPMODE HP303B__REG_ADR_OPMODE, \ + HP303B__REG_MASK_OPMODE, \ + HP303B__REG_SHIFT_OPMODE +#define HP303B__REG_ADR_OPMODE 0x08U +#define HP303B__REG_MASK_OPMODE 0x07U +#define HP303B__REG_SHIFT_OPMODE 0U + + + //temperature measure rate +#define HP303B__REG_INFO_TEMP_MR HP303B__REG_ADR_TEMP_MR, \ + HP303B__REG_MASK_TEMP_MR, \ + HP303B__REG_SHIFT_TEMP_MR +#define HP303B__REG_ADR_TEMP_MR 0x07U +#define HP303B__REG_MASK_TEMP_MR 0x70U +#define HP303B__REG_SHIFT_TEMP_MR 4U + + //temperature oversampling rate +#define HP303B__REG_INFO_TEMP_OSR HP303B__REG_ADR_TEMP_OSR, \ + HP303B__REG_MASK_TEMP_OSR, \ + HP303B__REG_SHIFT_TEMP_OSR +#define HP303B__REG_ADR_TEMP_OSR 0x07U +#define HP303B__REG_MASK_TEMP_OSR 0x07U +#define HP303B__REG_SHIFT_TEMP_OSR 0U + + //temperature sensor +#define HP303B__REG_INFO_TEMP_SENSOR HP303B__REG_ADR_TEMP_SENSOR, \ + HP303B__REG_MASK_TEMP_SENSOR, \ + HP303B__REG_SHIFT_TEMP_SENSOR +#define HP303B__REG_ADR_TEMP_SENSOR 0x07U +#define HP303B__REG_MASK_TEMP_SENSOR 0x80U +#define HP303B__REG_SHIFT_TEMP_SENSOR 7U + + //temperature sensor recommendation +#define HP303B__REG_INFO_TEMP_SENSORREC HP303B__REG_ADR_TEMP_SENSORREC, \ + HP303B__REG_MASK_TEMP_SENSORREC, \ + HP303B__REG_SHIFT_TEMP_SENSORREC +#define HP303B__REG_ADR_TEMP_SENSORREC 0x28U +#define HP303B__REG_MASK_TEMP_SENSORREC 0x80U +#define HP303B__REG_SHIFT_TEMP_SENSORREC 7U + + //temperature shift enable (if temp_osr>3) +#define HP303B__REG_INFO_TEMP_SE HP303B__REG_ADR_TEMP_SE, \ + HP303B__REG_MASK_TEMP_SE, \ + HP303B__REG_SHIFT_TEMP_SE +#define HP303B__REG_ADR_TEMP_SE 0x09U +#define HP303B__REG_MASK_TEMP_SE 0x08U +#define HP303B__REG_SHIFT_TEMP_SE 3U + + + //pressure measure rate +#define HP303B__REG_INFO_PRS_MR HP303B__REG_ADR_PRS_MR, \ + HP303B__REG_MASK_PRS_MR, \ + HP303B__REG_SHIFT_PRS_MR +#define HP303B__REG_ADR_PRS_MR 0x06U +#define HP303B__REG_MASK_PRS_MR 0x70U +#define HP303B__REG_SHIFT_PRS_MR 4U + + //pressure oversampling rate +#define HP303B__REG_INFO_PRS_OSR HP303B__REG_ADR_PRS_OSR, \ + HP303B__REG_MASK_PRS_OSR, \ + HP303B__REG_SHIFT_PRS_OSR +#define HP303B__REG_ADR_PRS_OSR 0x06U +#define HP303B__REG_MASK_PRS_OSR 0x07U +#define HP303B__REG_SHIFT_PRS_OSR 0U + + //pressure shift enable (if prs_osr>3) +#define HP303B__REG_INFO_PRS_SE HP303B__REG_ADR_PRS_SE, \ + HP303B__REG_MASK_PRS_SE, \ + HP303B__REG_SHIFT_PRS_SE +#define HP303B__REG_ADR_PRS_SE 0x09U +#define HP303B__REG_MASK_PRS_SE 0x04U +#define HP303B__REG_SHIFT_PRS_SE 2U + + + //temperature ready flag +#define HP303B__REG_INFO_TEMP_RDY HP303B__REG_ADR_TEMP_RDY, \ + HP303B__REG_MASK_TEMP_RDY, \ + HP303B__REG_SHIFT_TEMP_RDY +#define HP303B__REG_ADR_TEMP_RDY 0x08U +#define HP303B__REG_MASK_TEMP_RDY 0x20U +#define HP303B__REG_SHIFT_TEMP_RDY 5U + + //pressure ready flag +#define HP303B__REG_INFO_PRS_RDY HP303B__REG_ADR_PRS_RDY, \ + HP303B__REG_MASK_PRS_RDY, \ + HP303B__REG_SHIFT_PRS_RDY +#define HP303B__REG_ADR_PRS_RDY 0x08U +#define HP303B__REG_MASK_PRS_RDY 0x10U +#define HP303B__REG_SHIFT_PRS_RDY 4U + + //pressure value +#define HP303B__REG_ADR_PRS 0x00U +#define HP303B__REG_LEN_PRS 3U + + //temperature value +#define HP303B__REG_ADR_TEMP 0x03U +#define HP303B__REG_LEN_TEMP 3U + + //compensation coefficients +#define HP303B__REG_ADR_COEF 0x10U +#define HP303B__REG_LEN_COEF 18 + + + //FIFO enable +#define HP303B__REG_INFO_FIFO_EN HP303B__REG_ADR_FIFO_EN, \ + HP303B__REG_MASK_FIFO_EN, \ + HP303B__REG_SHIFT_FIFO_EN +#define HP303B__REG_ADR_FIFO_EN 0x09U +#define HP303B__REG_MASK_FIFO_EN 0x02U +#define HP303B__REG_SHIFT_FIFO_EN 1U + + //FIFO flush +#define HP303B__REG_INFO_FIFO_FL HP303B__REG_ADR_FIFO_EN, \ + HP303B__REG_MASK_FIFO_EN, \ + HP303B__REG_SHIFT_FIFO_EN +#define HP303B__REG_ADR_FIFO_FL 0x0CU +#define HP303B__REG_MASK_FIFO_FL 0x80U +#define HP303B__REG_SHIFT_FIFO_FL 7U + + //FIFO empty +#define HP303B__REG_INFO_FIFO_EMPTY HP303B__REG_ADR_FIFO_EMPTY, \ + HP303B__REG_MASK_FIFO_EMPTY, \ + HP303B__REG_SHIFT_FIFO_EMPTY +#define HP303B__REG_ADR_FIFO_EMPTY 0x0BU +#define HP303B__REG_MASK_FIFO_EMPTY 0x01U +#define HP303B__REG_SHIFT_FIFO_EMPTY 0U + + //FIFO full +#define HP303B__REG_INFO_FIFO_FULL HP303B__REG_ADR_FIFO_FULL, \ + HP303B__REG_MASK_FIFO_FULL, \ + HP303B__REG_SHIFT_FIFO_FULL +#define HP303B__REG_ADR_FIFO_FULL 0x0BU +#define HP303B__REG_MASK_FIFO_FULL 0x02U +#define HP303B__REG_SHIFT_FIFO_FULL 1U + + + //INT HL +#define HP303B__REG_INFO_INT_HL HP303B__REG_ADR_INT_HL, \ + HP303B__REG_MASK_INT_HL, \ + HP303B__REG_SHIFT_INT_HL +#define HP303B__REG_ADR_INT_HL 0x09U +#define HP303B__REG_MASK_INT_HL 0x80U +#define HP303B__REG_SHIFT_INT_HL 7U + + //INT FIFO enable +#define HP303B__REG_INFO_INT_EN_FIFO HP303B__REG_ADR_INT_EN_FIFO, \ + HP303B__REG_MASK_INT_EN_FIFO, \ + HP303B__REG_SHIFT_INT_EN_FIFO +#define HP303B__REG_ADR_INT_EN_FIFO 0x09U +#define HP303B__REG_MASK_INT_EN_FIFO 0x40U +#define HP303B__REG_SHIFT_INT_EN_FIFO 6U + + //INT TEMP enable +#define HP303B__REG_INFO_INT_EN_TEMP HP303B__REG_ADR_INT_EN_TEMP, \ + HP303B__REG_MASK_INT_EN_TEMP, \ + HP303B__REG_SHIFT_INT_EN_TEMP +#define HP303B__REG_ADR_INT_EN_TEMP 0x09U +#define HP303B__REG_MASK_INT_EN_TEMP 0x20U +#define HP303B__REG_SHIFT_INT_EN_TEMP 5U + + //INT PRS enable +#define HP303B__REG_INFO_INT_EN_PRS HP303B__REG_ADR_INT_EN_PRS, \ + HP303B__REG_MASK_INT_EN_PRS, \ + HP303B__REG_SHIFT_INT_EN_PRS +#define HP303B__REG_ADR_INT_EN_PRS 0x09U +#define HP303B__REG_MASK_INT_EN_PRS 0x10U +#define HP303B__REG_SHIFT_INT_EN_PRS 4U + + //INT FIFO flag +#define HP303B__REG_INFO_INT_FLAG_FIFO HP303B__REG_ADR_INT_FLAG_FIFO, \ + HP303B__REG_MASK_INT_FLAG_FIFO, \ + HP303B__REG_SHIFT_INT_FLAG_FIFO +#define HP303B__REG_ADR_INT_FLAG_FIFO 0x0AU +#define HP303B__REG_MASK_INT_FLAG_FIFO 0x04U +#define HP303B__REG_SHIFT_INT_FLAG_FIFO 2U + + //INT TMP flag +#define HP303B__REG_INFO_INT_FLAG_TEMP HP303B__REG_ADR_INT_FLAG_TEMP, \ + HP303B__REG_MASK_INT_FLAG_TEMP, \ + HP303B__REG_SHIFT_INT_FLAG_TEMP +#define HP303B__REG_ADR_INT_FLAG_TEMP 0x0AU +#define HP303B__REG_MASK_INT_FLAG_TEMP 0x02U +#define HP303B__REG_SHIFT_INT_FLAG_TEMP 1U + + //INT PRS flag +#define HP303B__REG_INFO_INT_FLAG_PRS HP303B__REG_ADR_INT_FLAG_PRS, \ + HP303B__REG_MASK_INT_FLAG_PRS, \ + HP303B__REG_SHIFT_INT_FLAG_PRS +#define HP303B__REG_ADR_INT_FLAG_PRS 0x0AU +#define HP303B__REG_MASK_INT_FLAG_PRS 0x01U +#define HP303B__REG_SHIFT_INT_FLAG_PRS 0U + + + +#endif /* DPS310_CONSTS_H_ */ diff --git a/lib/LibTeleinfo/README.md b/lib/LibTeleinfo/README.md new file mode 100755 index 000000000..11a90ac2b --- /dev/null +++ b/lib/LibTeleinfo/README.md @@ -0,0 +1,65 @@ +Teleinfo (Aka TIC) Universal Library +==================================== + +This is a generic Teleinfo French Meter Measure Library, it can be used on Arduino like device and also such as Spark Core, Particle, ESP8266, Raspberry PI or anywhere you can do Cpp code ... + +You can see Teleinformation official french datasheet [there][1] + +Since this is really dedicated to French energy measuring system, I will continue in French + +Installation +============ + +Copier le contenu de ce dossier (download zip) dans le dossier libraries de votre environnement Arduino Vous devriez avoir maintenant quelque chose comme `your_sketchbook_folder/libraries/LibTeleinfo` et ce dossier doit contentir les fichiers .cpp et .h ainsi que le sous dossier `examples`. +
    +Pour trouver votre dossier de sketchbook, dans l'environnement IDE, allez dans File>Preferences. +
    +allez voir ce [tutorial][2] sur les librairies Arduino si beoin. +
    + +Documentation +============= + +J'ai écrit un article [dédié][10] sur cette librairie, vous pouvez aussi voir les [catégories][6] associées à la téléinfo sur mon [blog][7]. +Pour les commentaires et le support vous pouvez allez sur le [forum][8] dédié ou dans la [communauté][9] + +Sketch d'exemples +================= + +- [Arduino_Softserial_Etiquette][3] Affiche des informations de téléinformation reçue étiquette par étiquette +- [Arduino_Softserial_Blink][11] Affiche des informations de téléinformation reçue trame par trame avec clignotement LED court/long si les données ont été modifiés +- [Arduino_Softserial_JSON][4] Retourne les informations de téléinformation au format JSON sur la liaison série. +- [Raspberry_JSON][12] Retourne les informations de téléinformation au format JSON sur stdout. +- [Wifinfo][5] ESP8266, ESP32 Wifi Teleinformation, Web + Rest + bonus, version en cours de développement, à venir mais un article [dédié][13] est déjà présent sur mon blog +- [ESP32][14] ESP32 Basic test pour WifInfo32 nouveau nom Denky :-) + +Pourquoi +======== +- J'utilise la téléinfo dans plusieurs de mes programmes et j'en avais marre de devoir faire des copier/coller de code constament, j'ai donc décidé de faire une librairie commune que j'utilise sans me poser de question + +License +======= +Cette oeuvre est mise à disposition selon les termes de la Licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International. + +Si vous êtes une entreprise et que vous souhaitez participer car vous utilisez cette librairie dans du hardware (box, automate, ...), vous pouvez toujours m'envoyer un exemplaire de votre fabrication, c'est toujours sympa de voir ce qui est fait avec ce code ;-) + +Divers +====== +Vous pouvez aller voir les nouveautés et autres projets sur [blog][7] + +[1]: http://www.erdf.fr/sites/default/files/ERDF-NOI-CPT_02E.pdf +[2]: http://learn.adafruit.com/arduino-tips-tricks-and-techniques/arduino-libraries +[6]: https://hallard.me/category/tinfo/ +[7]: https://hallard.me +[8]: https://community.hallard.me/category/7 +[9]: https://community.hallard.me +[10]: https://hallard.me/libteleinfo + +[3]: https://github.com/hallard/LibTeleinfo/blob/master/examples/Arduino_Softserial/Arduino_Softserial_Etiquette.ino +[4]: https://github.com/hallard/LibTeleinfo/blob/master/examples/Arduino_Softserial_JSON/Arduino_Softserial_JSON.ino +[5]: https://github.com/hallard/LibTeleinfo/tree/master/examples/Wifinfo/Wifinfo.ino +[11]: https://github.com/hallard/LibTeleinfo/blob/master/examples/Arduino_Softserial/Arduino_Softserial_Blink.ino +[12]: https://github.com/hallard/LibTeleinfo/blob/master/examples/Raspberry_JSON/Raspberry_JSON.ino +[13]: https://hallard.me/wifiinfo/ +[14]: https://github.com/hallard/LibTeleinfo/blob/master/examples/ESP32/ESP32.ino + diff --git a/lib/LibTeleinfo/library.json b/lib/LibTeleinfo/library.json new file mode 100755 index 000000000..a93105e61 --- /dev/null +++ b/lib/LibTeleinfo/library.json @@ -0,0 +1,19 @@ +{ + "name": "LibTeleinfo", + "version": "1.1.2", + "keywords": "teleinfo, french, meter, power, erdf, linky, tic", + "description": "Decoder for Teleinfo (aka TIC) from French smart power meters", + "repository": + { + "type": "git", + "url": "https://github.com/hallard/LibTeleinfo.git" + }, + "authors": + { + "name": "Charles-Henri Hallard", + "url": "http://hallard.me" + }, + "frameworks": "arduino", + "platforms": "*" +} + diff --git a/lib/LibTeleinfo/library.properties b/lib/LibTeleinfo/library.properties new file mode 100755 index 000000000..7cfc9a635 --- /dev/null +++ b/lib/LibTeleinfo/library.properties @@ -0,0 +1,9 @@ +name=LibTeleinfo +version=1.1.2 +author=Charles-Henri Hallard +maintainer=Charles-Henri Hallard +sentence=Decoder for Teleinfo (aka TIC) from French smart power meters +paragraph=This is a generic Teleinfo (aka TIC) French Meter Measure Library, it can be used on Arduino, Particle, ESP8266, Raspberry PI or anywhere you can do Cpp coding. +category=Communication +url=https://github.com/hallard/LibTeleinfo +architectures=* \ No newline at end of file diff --git a/lib/LibTeleinfo/src/LibTeleinfo.cpp b/lib/LibTeleinfo/src/LibTeleinfo.cpp new file mode 100644 index 000000000..588555831 --- /dev/null +++ b/lib/LibTeleinfo/src/LibTeleinfo.cpp @@ -0,0 +1,881 @@ +// ********************************************************************************** +// Driver definition for French Teleinfo +// ********************************************************************************** +// Creative Commons Attrib Share-Alike License +// You are free to use/extend this library but please abide with the CC-BY-SA license: +// http://creativecommons.org/licenses/by-sa/4.0/ +// +// For any explanation about teleinfo ou use , see my blog +// http://hallard.me/category/tinfo +// +// Code based on following datasheet +// http://www.erdf.fr/sites/default/files/ERDF-NOI-CPT_02E.pdf +// +// Written by Charles-Henri Hallard (http://hallard.me) +// +// History : V1.00 2015-06-14 - First release +// V2.00 2020-06-11 - Integration into Tasmota +// +// All text above must be included in any redistribution. +// +// Edit : Tab size set to 2 but I converted tab to sapces +// +// ********************************************************************************** + +#include "Arduino.h" +#include "LibTeleinfo.h" + +/* ====================================================================== +Class : TInfo +Purpose : Constructor +Input : - +Output : - +Comments: - +====================================================================== */ +TInfo::TInfo() +{ + // Init of our linked list + _valueslist.name = NULL; + _valueslist.value = NULL; + _valueslist.checksum = '\0'; + _valueslist.flags = TINFO_FLAGS_NONE; + + // callback + _fn_ADPS = NULL; + _fn_data = NULL; + _fn_new_frame = NULL; + _fn_updated_frame = NULL; +} + +/* ====================================================================== +Function: init +Purpose : try to guess +Input : - +Output : - +Comments: - +====================================================================== */ +void TInfo::init() +{ + // free up linked list (in case on recall init()) + listDelete(); + + // clear our receive buffer + clearBuffer(); + + // We're in INIT in term of receive data + _state = TINFO_INIT; +} + +/* ====================================================================== +Function: attachADPS +Purpose : attach a callback when we detected a ADPS on any phase +Input : callback function +Output : - +Comments: - +====================================================================== */ +void TInfo::attachADPS(void (*fn_ADPS)(uint8_t phase)) +{ + // indicate the user callback + _fn_ADPS = fn_ADPS; +} + +/* ====================================================================== +Function: attachNewData +Purpose : attach a callback when we detected a new/changed value +Input : callback function +Output : - +Comments: - +====================================================================== */ +void TInfo::attachData(void (*fn_data)(ValueList * valueslist, uint8_t state)) +{ + // indicate the user callback + _fn_data = fn_data; +} + +/* ====================================================================== +Function: attachNewFrame +Purpose : attach a callback when we received a full frame +Input : callback function +Output : - +Comments: - +====================================================================== */ +void TInfo::attachNewFrame(void (*fn_new_frame)(ValueList * valueslist)) +{ + // indicate the user callback + _fn_new_frame = fn_new_frame; +} + +/* ====================================================================== +Function: attachChangedFrame +Purpose : attach a callback when we received a full frame where data + has changed since the last frame (cool to update data) +Input : callback function +Output : - +Comments: - +====================================================================== */ +void TInfo::attachUpdatedFrame(void (*fn_updated_frame)(ValueList * valueslist)) +{ + // indicate the user callback + _fn_updated_frame = fn_updated_frame; +} + +/* ====================================================================== +Function: clearBuffer +Purpose : clear and init the buffer +Input : - +Output : - +Comments: - +====================================================================== */ +void TInfo::clearBuffer() +{ + // Clear our buffer, set index to 0 + memset(_recv_buff, 0, TINFO_BUFSIZE); + _recv_idx = 0; +} + + +/* ====================================================================== +Function: addCustomValue +Purpose : let user add custom values (mainly for testing) +Input : Pointer to the label name + pointer to the value + pointer on flag state of the label +Output : pointer to the new node (or founded one) +Comments: checksum is calculated before adding, no need to bother with +====================================================================== */ +ValueList * TInfo::addCustomValue(char * name, char * value, uint8_t * flags) +{ + // Little check + if (name && *name && value && *value) { + ValueList * me; + + // Same as if we really received this line + customLabel(name, value, flags); + me = valueAdd(name, value, calcChecksum(name,value), flags); + + if ( me ) { + // something to do with new datas + if (*flags & (TINFO_FLAGS_UPDATED | TINFO_FLAGS_ADDED | TINFO_FLAGS_ALERT) ) { + // this frame will for sure be updated + _frame_updated = true; + } + return (me); + } + } + + // Error or Already Exists + return ( (ValueList *) NULL); +} + +/* ====================================================================== +Function: valueAdd +Purpose : Add element to the Linked List of values +Input : Pointer to the label name + pointer to the value + checksum value + flag state of the label (modified by function) +Output : pointer to the new node (or founded one) +Comments: - state of the label changed by the function +====================================================================== */ +ValueList * TInfo::valueAdd(char * name, char * value, uint8_t checksum, uint8_t * flags) +{ + // Get our linked list + ValueList * me = &_valueslist; + + uint8_t lgname = strlen(name); + uint8_t lgvalue = strlen(value); + uint8_t thischeck = calcChecksum(name,value); + + // just some paranoia + if (thischeck != checksum ) { + TI_Debug(name); + TI_Debug('='); + TI_Debug(value); + TI_Debug(F(" '")); + TI_Debug((char) checksum); + TI_Debug(F("' Not added bad checksum calculated '")); + TI_Debug((char) thischeck); + TI_Debugln(F("'")); + } else { + // Got one and all seems good ? + if (me && lgname && lgvalue && checksum) { + // Create pointer on the new node + ValueList *newNode = NULL; + ValueList *parNode = NULL ; + + // Loop thru the node + while (me->next) { + // save parent node + parNode = me ; + + // go to next node + me = me->next; + + // Check if we already have this LABEL (same name AND same size) + if (lgname==strlen(me->name) && strcmp(me->name, name)==0) { + // Already got also this value return US + if (lgvalue==strlen(me->value) && strcmp(me->value, value) == 0) { + *flags |= TINFO_FLAGS_EXIST; + me->flags = *flags; + return ( me ); + } else { + // We changed the value + *flags |= TINFO_FLAGS_UPDATED; + me->flags = *flags ; + // Do we have enought space to hold new value ? + if (strlen(me->value) >= lgvalue ) { + // Copy it + strlcpy(me->value, value , lgvalue + 1 ); + me->checksum = checksum ; + + // That's all + return (me); + } else { + // indicate our parent node that the next node + // is not us anymore but the next we have + parNode->next = me->next; + + // free up this node + free (me); + + // Return to parent (that will now point on next node and not us) + // and continue loop just in case we have sevral with same name + me = parNode; + } + } + } + } + + // Our linked list structure sizeof(ValueList) + // + Name + '\0' + // + Value + '\0' + size_t size ; + #if defined (ESP8266) || defined (ESP32) + lgname = ESP_allocAlign(lgname+1); // Align name buffer + lgvalue = ESP_allocAlign(lgvalue+1); // Align value buffer + // Align the whole structure + size = ESP_allocAlign( sizeof(ValueList) + lgname + lgvalue ) ; + #else + size = sizeof(ValueList) + lgname + 1 + lgvalue + 1 ; + #endif + + // Create new node with size to store strings + if ((newNode = (ValueList *) malloc(size) ) == NULL) + return ( (ValueList *) NULL ); + + // get our buffer Safe + memset(newNode, 0, size); + + // Put the new node on the list + me->next = newNode; + + // First String located after last struct element + // Second String located after the First + \0 + newNode->checksum = checksum; + newNode->name = (char *) newNode + sizeof(ValueList); + newNode->value = (char *) newNode->name + lgname + 1; + + // Copy the string data + memcpy(newNode->name , name , lgname ); + memcpy(newNode->value, value , lgvalue ); + + // So we just created this node but was it new + // or was matter of text size ? + if ( (*flags & TINFO_FLAGS_UPDATED) == 0) { + // so we added this node ! + *flags |= TINFO_FLAGS_ADDED ; + newNode->flags = *flags; + } + + TI_Debug(F("Added '")); + TI_Debug(name); + TI_Debug('='); + TI_Debug(value); + TI_Debug(F("' '")); + TI_Debug((char) checksum); + TI_Debugln(F("'")); + + // return pointer on the new node + return (newNode); + } + + } // Checksum OK + + + // Error or Already Exists + return ( (ValueList *) NULL); +} + +/* ====================================================================== +Function: valueRemoveFlagged +Purpose : remove element to the Linked List of values where +Input : paramter flags +Output : true if found and removed +Comments: - +====================================================================== */ +boolean TInfo::valueRemoveFlagged(uint8_t flags) +{ + boolean deleted = false; + + // Get our linked list + ValueList * me = &_valueslist; + ValueList *parNode = NULL ; + + // Got one and all seems good ? + if (me) { + // Loop thru the node + while (me->next) { + // save parent node + parNode = me ; + + // go to next node + me = me->next; + + // found the flags? + if (me->flags & flags ) { + // indicate our parent node that the next node + // is not us anymore but the next we have + parNode->next = me->next; + + // free up this node + free (me); + + // Return to parent (that will now point on next node and not us) + // and continue loop just in case we have sevral with same name + me = parNode; + deleted = true; + } + } + } + + return (deleted); +} + +/* ====================================================================== +Function: valueRemove +Purpose : remove element to the Linked List of values +Input : Pointer to the label name +Output : true if found and removed +Comments: - +====================================================================== */ +boolean TInfo::valueRemove(char * name) +{ + boolean deleted = false; + + // Get our linked list + ValueList * me = &_valueslist; + ValueList *parNode = NULL ; + + uint8_t lgname = strlen(name); + + // Got one and all seems good ? + if (me && lgname) { + // Loop thru the node + while (me->next) { + // save parent node + parNode = me ; + + // go to next node + me = me->next; + + // found ? + if (strncmp(me->name, name, lgname) == 0) { + // indicate our parent node that the next node + // is not us anymore but the next we have + parNode->next = me->next; + + // free up this node + free (me); + + // Return to parent (that will now point on next node and not us) + // and continue loop just in case we have sevral with same name + me = parNode; + deleted = true; + } + } + } + + return (deleted); +} + +/* ====================================================================== +Function: valueGet +Purpose : get value of one element +Input : Pointer to the label name + pointer to the value where we fill data +Output : pointer to the value where we filled data NULL is not found +====================================================================== */ +char * TInfo::valueGet(char * name, char * value) +{ + // Get our linked list + ValueList * me = &_valueslist; + uint8_t lgname = strlen(name); + + // Got one and all seems good ? + if (me && lgname) { + + // Loop thru the node + while (me->next) { + + // go to next node + me = me->next; + + // Check if we match this LABEL + if (lgname==strlen(me->name) && strncmp(me->name, name, lgname)==0) { + // this one has a value ? + if (me->value) { + // copy to dest buffer + uint8_t lgvalue = strlen(me->value); + strlcpy(value, me->value , lgvalue + 1 ); + return ( value ); + } + } + } + } + // not found + return ( NULL); +} + +/* ====================================================================== +Function: valueGet_P +Purpose : get value of one element +Input : Pointer to the label name + pointer to the value where we fill data +Output : pointer to the value where we filled data NULL is not found +====================================================================== */ +char * TInfo::valueGet_P(const char * name, char * value) +{ + // Get our linked list + ValueList * me = &_valueslist; + uint8_t lgname = strlen_P(name); + + // Got one and all seems good ? + if (me && lgname) { + + // Loop thru the node + while (me->next) { + + // go to next node + me = me->next; + + // Check if we match this LABEL + if (lgname==strlen(me->name) && strncmp_P(me->name, name, lgname)==0) { + // this one has a value ? + if (me->value) { + // copy to dest buffer + uint8_t lgvalue = strlen(me->value); + strlcpy(value, me->value , lgvalue + 1 ); + return ( value ); + } + } + } + } + // not found + return ( NULL); +} + +/* ====================================================================== +Function: getTopList +Purpose : return a pointer on the top of the linked list +Input : - +Output : Pointer +====================================================================== */ +ValueList * TInfo::getList(void) +{ + // Get our linked list + return &_valueslist; +} + +/* ====================================================================== +Function: valuesDump +Purpose : dump linked list content +Input : - +Output : total number of values +====================================================================== */ +uint8_t TInfo::valuesDump(void) +{ + // Get our linked list + ValueList * me = &_valueslist; + uint8_t index = 0; + + // Got one ? + if (me) { + // Loop thru the node + while (me->next) { + // go to next node + me = me->next; + + index++; + TI_Debug(index) ; + TI_Debug(F(") ")) ; + + if (me->name) { + TI_Debug(me->name) ; + } else { + TI_Debug(F("NULL")) ; + } + + TI_Debug(F("=")) ; + + if (me->value) { + TI_Debug(me->value) ; + } else { + TI_Debug(F("NULL")) ; + } + + TI_Debug(F(" '")) ; + TI_Debug(me->checksum) ; + TI_Debug(F("' ")); + + // Flags management + if ( me->flags) { + TI_Debug(F("Flags:0x")); + TI_Debugf("%02X =>", me->flags); + if ( me->flags & TINFO_FLAGS_EXIST) { + TI_Debug(F("Exist ")) ; + } + if ( me->flags & TINFO_FLAGS_UPDATED) { + TI_Debug(F("Updated ")) ; + } + if ( me->flags & TINFO_FLAGS_ADDED) { + TI_Debug(F("New ")) ; + } + } + + TI_Debugln() ; + } + } + + return index; +} + +/* ====================================================================== +Function: labelCount +Purpose : Count the number of label in the list +Input : - +Output : element numbers +====================================================================== */ +int TInfo::labelCount() +{ + int count = 0; + + // Get our linked list + ValueList * me = &_valueslist; + + if (me) + while ((me = me->next)) + count++; + + return (count); +} + +/* ====================================================================== +Function: listDelete +Purpose : Delete the ENTIRE Linked List, not a value +Input : - +Output : True if Ok False Otherwise +====================================================================== */ +boolean TInfo::listDelete() +{ + // Get our linked list + ValueList * me = &_valueslist; + + // Got a pointer + if (me) { + ValueList *current; + + // For each linked list + while ((current = me->next)) { + // Get the next + me->next = current->next; + + // Free the current + free(current); + } + + // Free the top element + me->next = NULL ; + + // Ok + return (true); + } + + return (false); +} + +/* ====================================================================== +Function: checksum +Purpose : calculate the checksum based on data/value fields +Input : label name + label value +Output : checksum +Comments: return '\0' in case of error +====================================================================== */ +unsigned char TInfo::calcChecksum(char *etiquette, char *valeur) +{ + uint8_t sum = ' '; // Somme des codes ASCII du message + un espace + + // avoid dead loop, always check all is fine + if (etiquette && valeur) { + // this will not hurt and may save our life ;-) + if (strlen(etiquette) && strlen(valeur)) { + while (*etiquette) + sum += *etiquette++ ; + + while(*valeur) + sum += *valeur++ ; + + return ( (sum & 63) + ' ' ) ; + } + } + return 0; +} + +/* ====================================================================== +Function: customLabel +Purpose : do action when received a correct label / value + checksum line +Input : plabel : pointer to string containing the label + pvalue : pointer to string containing the associated value + pflags pointer in flags value if we need to cchange it +Output : +Comments: +====================================================================== */ +void TInfo::customLabel( char * plabel, char * pvalue, uint8_t * pflags) +{ + int8_t phase = -1; + + // Monophasé + if (strcmp(plabel, "ADPS")==0 ) + phase=0; + + // For testing + //if (strcmp(plabel, "IINST")==0 ) { + // *pflags |= TINFO_FLAGS_ALERT; + //} + + // triphasé c'est ADIR + Num Phase + if (plabel[0]=='A' && plabel[1]=='D' && plabel[2]=='I' && plabel[3]=='R' && plabel[4]>='1' && plabel[4]<='3') { + phase = plabel[4]-'0'; + } + + // Nous avons un ADPS ? + if (phase>=0 && phase <=3) { + // ne doit pas être sauvé définitivement + *pflags |= TINFO_FLAGS_ALERT; + + // Traitement de l'ADPS demandé par le sketch + if (_fn_ADPS) + _fn_ADPS(phase); + } +} + +/* ====================================================================== +Function: checkLine +Purpose : check one line of teleinfo received +Input : - +Output : pointer to the data object in the linked list if OK else NULL +Comments: +====================================================================== */ +ValueList * TInfo::checkLine(char * pline) +{ + char * p; + char * ptok; + char * pend; + char * pvalue; + char checksum; + char buff[TINFO_BUFSIZE]; + uint8_t flags = TINFO_FLAGS_NONE; + //boolean err = true ; // Assume error + int len ; // Group len + + if (pline==NULL) + return NULL; + + len = strlen(pline); + + // a line should be at least 7 Char + // 2 Label + Space + 1 etiquette + space + checksum + \r + if ( len < 7 ) + return NULL; + + // Get our own working copy + strlcpy( buff, pline, len+1); + + p = &buff[0]; + ptok = p; // for sure we start with token name + pend = p + len; // max size + + // Init values + pvalue = NULL; + checksum = 0; + + //TI_Debug("Got ["); + //TI_Debug(len); + //TI_Debug("] "); + + + // Loop in buffer + while ( p < pend ) { + // start of token value + if ( *p==' ' && ptok) { + // Isolate token name + *p++ = '\0'; + + // 1st space, it's the label value + if (!pvalue) + pvalue = p; + else + // 2nd space, so it's the checksum + checksum = *p; + } + // new line ? ok we got all we need ? + + if ( *p=='\r' ) { + *p='\0'; + + // Good format ? + if ( ptok && pvalue && checksum ) { + // Always check to avoid bad behavior + if(strlen(ptok) && strlen(pvalue)) { + // Is checksum is OK + if ( calcChecksum(ptok,pvalue) == checksum) { + // In case we need to do things on specific labels + customLabel(ptok, pvalue, &flags); + + // Add value to linked lists of values + ValueList * me = valueAdd(ptok, pvalue, checksum, &flags); + + // value correctly added/changed + if ( me ) { + // something to do with new datas + if (flags & (TINFO_FLAGS_UPDATED | TINFO_FLAGS_ADDED | TINFO_FLAGS_ALERT) ) { + // this frame will for sure be updated + _frame_updated = true; + + // Do we need to advertise user callback + if (_fn_data) + _fn_data(me, flags); + } + } + } + } + } + } + // Next char + p++; + + } // While + + return NULL; +} + +/* ====================================================================== +Function: process +Purpose : teleinfo serial char received processing, should be called + my main loop, this will take care of managing all the other +Input : pointer to the serial used +Output : teleinfo global state +====================================================================== */ +_State_e TInfo::process(char c) +{ + // be sure 7 bits only + c &= 0x7F; + + // What we received ? + switch (c) { + // start of transmission ??? + case TINFO_STX: + // Clear buffer, begin to store in it + clearBuffer(); + + // by default frame is not "updated" + // if data change we'll set this flag + _frame_updated = false; + + // We were waiting fo this one ? + if (_state == TINFO_INIT || _state == TINFO_WAIT_STX ) { + TI_Debugln(F("TINFO_WAIT_ETX")); + _state = TINFO_WAIT_ETX; + } + break; + + // End of transmission ? + case TINFO_ETX: + + // Normal working mode ? + if (_state == TINFO_READY) { + // Get on top of our linked list + ValueList * me = &_valueslist; + + // Call user callback if any + if (_frame_updated && _fn_updated_frame) + _fn_updated_frame(me); + else if (_fn_new_frame) + _fn_new_frame(me); + + #ifdef TI_Debug + valuesDump(); + #endif + + // It's important there since all user job is done + // to remove the alert flags from table (ADPS for example) + // it will be put back again next time if any + valueRemoveFlagged(TINFO_FLAGS_ALERT); + } + + // We were waiting fo this one ? + if (_state == TINFO_WAIT_ETX) { + TI_Debugln(F("TINFO_READY")); + _state = TINFO_READY; + } + else if ( _state == TINFO_INIT) { + TI_Debugln(F("TINFO_WAIT_STX")); + _state = TINFO_WAIT_STX ; + } + + break; + + // Start of group \n ? + case TINFO_SGR: + // Do nothing we'll work at end of group + // we can safely ignore this char + break; + + // End of group \r ? + case TINFO_EGR: + // Are we ready to process ? + if (_state == TINFO_READY) { + // Store data recceived (we'll need it) + if ( _recv_idx < TINFO_BUFSIZE) + _recv_buff[_recv_idx++]=c; + + // clear the end of buffer (paranoia inside) + memset(&_recv_buff[_recv_idx], 0, TINFO_BUFSIZE-_recv_idx); + + // check the group we've just received + checkLine(_recv_buff) ; + + // Whatever error or not, we done + clearBuffer(); + } + break; + + // other char ? + default: + { + // Only in a ready state of course + if (_state == TINFO_READY) { + // If buffer is not full, Store data + if ( _recv_idx < TINFO_BUFSIZE) + _recv_buff[_recv_idx++]=c; + else + clearBuffer(); + } + } + break; + } + + return _state; +} + + diff --git a/lib/LibTeleinfo/src/LibTeleinfo.h b/lib/LibTeleinfo/src/LibTeleinfo.h new file mode 100755 index 000000000..5b43523c7 --- /dev/null +++ b/lib/LibTeleinfo/src/LibTeleinfo.h @@ -0,0 +1,147 @@ +// ********************************************************************************** +// Driver definition for French Teleinfo +// ********************************************************************************** +// Creative Commons Attrib Share-Alike License +// You are free to use/extend this library but please abide with the CC-BY-SA license: +// http://creativecommons.org/licenses/by-sa/4.0/ +// +// For any explanation about teleinfo ou use , see my blog +// http://hallard.me/category/tinfo +// +// Code based on following datasheet +// http://www.erdf.fr/sites/default/files/ERDF-NOI-CPT_02E.pdf +// +// Written by Charles-Henri Hallard (http://hallard.me) +// +// History : V1.00 2015-06-14 - First release +// V2.00 2020-06-11 - Integration into Tasmota +// +// All text above must be included in any redistribution. +// +// Edit : Tab size set to 2 but I converted tab to sapces +// +// ********************************************************************************** + +#ifndef LibTeleinfo_h +#define LibTeleinfo_h + +#include "Arduino.h" + +// Define this if you want library to be verbose +//#define TI_DEBUG + +// I prefix debug macro to be sure to use specific for THIS library +// debugging, this should not interfere with main sketch or other +// libraries +#ifdef TI_DEBUG + #ifdef ESP8266 + #define TI_Debug(x) Serial1.print(x) + #define TI_Debugln(x) Serial1.println(x) + #define TI_Debugf(...) Serial1.printf(__VA_ARGS__) + #define TI_Debugflush Serial1.flush + #else + #define TI_Debug(x) Serial.print(x) + #define TI_Debugln(x) Serial.println(x) + #define TI_Debugf(...) Serial.printf(__VA_ARGS__) + #define TI_Debugflush Serial.flush + #endif +#else + #define TI_Debug(x) {} + #define TI_Debugln(x) {} + #define TI_Debugf(...) {} + #define TI_Debugflush {} +#endif + +// For 4 bytes Aligment boundaries +#define ESP_allocAlign(size) ((size + 3) & ~((size_t) 3)) + +#pragma pack(push) // push current alignment to stack +#pragma pack(1) // set alignment to 1 byte boundary + +// Linked list structure containing all values received +typedef struct _ValueList ValueList; +struct _ValueList +{ + ValueList *next; // next element + uint8_t checksum;// checksum + uint8_t flags; // specific flags + char * name; // LABEL of value name + char * value; // value +}; + +#pragma pack(pop) + + +// Library state machine +enum _State_e { + TINFO_INIT, // We're in init + TINFO_WAIT_STX, // We're waiting for STX + TINFO_WAIT_ETX, // We had STX, We're waiting for ETX + TINFO_READY // We had STX AND ETX, So we're OK +}; + +// what we done with received value (also for callback flags) +#define TINFO_FLAGS_NONE 0x00 +#define TINFO_FLAGS_NOTHING 0x01 +#define TINFO_FLAGS_ADDED 0x02 +#define TINFO_FLAGS_EXIST 0x04 +#define TINFO_FLAGS_UPDATED 0x08 +#define TINFO_FLAGS_ALERT 0x80 /* This will generate an alert */ + +// Local buffer for one line of teleinfo +// maximum size, I think it should be enought +#define TINFO_BUFSIZE 64 + +// Teleinfo start and end of frame characters +#define TINFO_STX 0x02 +#define TINFO_ETX 0x03 +#define TINFO_SGR '\n' // start of group +#define TINFO_EGR '\r' // End of group + +typedef void (*_fn_ADPS) (uint8_t); +typedef void (*_fn_data) (ValueList *, uint8_t); +typedef void (*_fn_new_frame) (ValueList *); +typedef void (*_fn_updated_frame) (ValueList *); + +class TInfo +{ + public: + TInfo(); + void init(); + _State_e process (char c); + void attachADPS(void (*_fn_ADPS)(uint8_t phase)); + void attachData(void (*_fn_data)(ValueList * valueslist, uint8_t state)); + void attachNewFrame(void (*_fn_new_frame)(ValueList * valueslist)); + void attachUpdatedFrame(void (*_fn_updated_frame)(ValueList * valueslist)); + ValueList * addCustomValue(char * name, char * value, uint8_t * flags); + ValueList * getList(void); + uint8_t valuesDump(void); + char * valueGet(char * name, char * value); + char * valueGet_P(const char * name, char * value); + boolean listDelete(); + unsigned char calcChecksum(char *etiquette, char *valeur) ; + + private: + void clearBuffer(); + ValueList * valueAdd (char * name, char * value, uint8_t checksum, uint8_t * flags); + boolean valueRemove (char * name); + boolean valueRemoveFlagged(uint8_t flags); + int labelCount(); + void customLabel( char * plabel, char * pvalue, uint8_t * pflags) ; + ValueList * checkLine(char * pline) ; + + _State_e _state; // Teleinfo machine state + ValueList _valueslist; // Linked list of teleinfo values + char _recv_buff[TINFO_BUFSIZE]; // line receive buffer + uint8_t _recv_idx; // index in receive buffer + boolean _frame_updated; // Data on the frame has been updated + void (*_fn_ADPS)(uint8_t phase); + void (*_fn_data)(ValueList * valueslist, uint8_t state); + void (*_fn_new_frame)(ValueList * valueslist); + void (*_fn_updated_frame)(ValueList * valueslist); + + //volatile uint8_t *dcport; + //uint8_t dcpinmask; +}; + +#endif diff --git a/lib/Mutichannel_Gas_Sensor/src/MutichannelGasSensor.cpp b/lib/Mutichannel_Gas_Sensor/src/MutichannelGasSensor.cpp index 9be9473ef..2d4d4c5dd 100644 --- a/lib/Mutichannel_Gas_Sensor/src/MutichannelGasSensor.cpp +++ b/lib/Mutichannel_Gas_Sensor/src/MutichannelGasSensor.cpp @@ -57,7 +57,7 @@ bool MutichannelGasSensor::isError() unsigned char MutichannelGasSensor::getVersion() { - if(get_addr_dta(CMD_READ_EEPROM, ADDR_IS_SET) == 1126) // get version + if(get_addr_dta(CMD_READ_EEPROM, ADDR_IS_SET) == 1126) // get version { __version = 2; return __version; @@ -105,66 +105,66 @@ START: return 0; } } - + Wire.requestFrom(i2cAddress, (uint8_t)2); - + unsigned int dta = 0; - + unsigned char raw[10]; int cnt = 0; - + while(Wire.available()) { raw[cnt++] = Wire.read(); } - + if(cnt == 0)goto START; dta = raw[0]; dta <<= 8; dta += raw[1]; - + switch(addr_reg) { case CH_VALUE_NH3: - + if(dta > 0) { adcValueR0_NH3_Buf = dta; } - else + else { dta = adcValueR0_NH3_Buf; } - + break; - + case CH_VALUE_CO: - + if(dta > 0) { adcValueR0_CO_Buf = dta; } - else + else { dta = adcValueR0_CO_Buf; } - + break; - + case CH_VALUE_NO2: - + if(dta > 0) { adcValueR0_NO2_Buf = dta; } - else + else { dta = adcValueR0_NO2_Buf; } - + break; - + default:; } return dta; @@ -173,7 +173,7 @@ START: unsigned int MutichannelGasSensor::get_addr_dta(unsigned char addr_reg, unsigned char __dta) { int trys = 0; -START: +START: __send_error = false; Wire.beginTransmission(i2cAddress); Wire.write(addr_reg); @@ -185,25 +185,25 @@ START: return 0; } } - + Wire.requestFrom(i2cAddress, (uint8_t)2); - + unsigned int dta = 0; - + unsigned char raw[10]; int cnt = 0; - + while(Wire.available()) { raw[cnt++] = Wire.read(); } - + if(cnt == 0)goto START; dta = raw[0]; dta <<= 8; dta += raw[1]; - + return dta; } @@ -269,7 +269,7 @@ int16_t MutichannelGasSensor::readR0(void) int16_t rtnData = 0; rtnData = readData(0x11); - + if(rtnData > 0) res0[0] = rtnData; else @@ -338,7 +338,7 @@ float MutichannelGasSensor::calcGas(int gas) if(readR0() >= 0) r0_inited = true; else return -1.0f; } - + if(readR() < 0) return -2.0f; @@ -353,65 +353,65 @@ float MutichannelGasSensor::calcGas(int gas) int A0_0 = get_addr_dta(6, ADDR_USER_ADC_HN3); int A0_1 = get_addr_dta(6, ADDR_USER_ADC_CO); int A0_2 = get_addr_dta(6, ADDR_USER_ADC_NO2); - + int An_0 = get_addr_dta(CH_VALUE_NH3); int An_1 = get_addr_dta(CH_VALUE_CO); int An_2 = get_addr_dta(CH_VALUE_NO2); - - ratio0 = (float)An_0/(float)A0_0*(1023.0-A0_0)/(1023.0-An_0); - ratio1 = (float)An_1/(float)A0_1*(1023.0-A0_1)/(1023.0-An_1); - ratio2 = (float)An_2/(float)A0_2*(1023.0-A0_2)/(1023.0-An_2); - + + ratio0 = (float)An_0/(float)A0_0*(1023.0f-A0_0)/(1023.0f-An_0); + ratio1 = (float)An_1/(float)A0_1*(1023.0f-A0_1)/(1023.0f-An_1); + ratio2 = (float)An_2/(float)A0_2*(1023.0f-A0_2)/(1023.0f-An_2); + } - + float c = 0; switch(gas) { case CO: { - c = pow(ratio1, -1.179)*4.385; //mod by jack + c = pow(ratio1, -1.179f)*4.385f; //mod by jack break; } case NO2: { - c = pow(ratio2, 1.007)/6.855; //mod by jack + c = pow(ratio2, 1.007f)/6.855f; //mod by jack break; } case NH3: { - c = pow(ratio0, -1.67)/1.47; //modi by jack + c = pow(ratio0, -1.67f)/1.47f; //modi by jack break; } case C3H8: //add by jack { - c = pow(ratio0, -2.518)*570.164; + c = pow(ratio0, -2.518f)*570.164f; break; } case C4H10: //add by jack { - c = pow(ratio0, -2.138)*398.107; + c = pow(ratio0, -2.138f)*398.107f; break; } case GAS_CH4: //add by jack { - c = pow(ratio1, -4.363)*630.957; + c = pow(ratio1, -4.363f)*630.957f; break; } case H2: //add by jack { - c = pow(ratio1, -1.8)*0.73; + c = pow(ratio1, -1.8f)*0.73f; break; } case C2H5OH: //add by jack { - c = pow(ratio1, -1.552)*1.622; + c = pow(ratio1, -1.552f)*1.622f; break; } default: break; } - + if(2==__version)ledOff(); return isnan(c)?-3:c; } @@ -474,7 +474,7 @@ void MutichannelGasSensor::doCalibrate(void) a0 = get_addr_dta(CH_VALUE_NH3); a1 = get_addr_dta(CH_VALUE_CO); a2 = get_addr_dta(CH_VALUE_NO2); - + Serial.print(a0); Serial.print('\t'); Serial.print(a1); @@ -482,44 +482,44 @@ void MutichannelGasSensor::doCalibrate(void) Serial.print(a2); Serial.println('\t'); ledOn(); - + int cnt = 0; for(i=0; i<20; i++) { if((a0 - get_addr_dta(CH_VALUE_NH3)) > 2 || (get_addr_dta(CH_VALUE_NH3) - a0) > 2)cnt++; if((a1 - get_addr_dta(CH_VALUE_CO)) > 2 || (get_addr_dta(CH_VALUE_CO) - a1) > 2)cnt++; if((a2 - get_addr_dta(CH_VALUE_NO2)) > 2 || (get_addr_dta(CH_VALUE_NO2) - a2) > 2)cnt++; - + if(cnt>5) { break; } delay(1000); } - + ledOff(); if(cnt <= 5)break; delay(200); } - + Serial.print("write user adc value: "); Serial.print(a0);Serial.print('\t'); Serial.print(a1);Serial.print('\t'); Serial.print(a2);Serial.println('\t'); - + unsigned char tmp[7]; - + tmp[0] = 7; tmp[1] = a0>>8; tmp[2] = a0&0xff; - + tmp[3] = a1>>8; tmp[4] = a1&0xff; tmp[5] = a2>>8; tmp[6] = a2&0xff; - + write_i2c(i2cAddress, tmp, 7); } } @@ -563,7 +563,7 @@ void MutichannelGasSensor::display_eeprom() Serial.println("ERROR: display_eeprom() is NOT support by V1 firmware."); return ; } - + Serial.print("ADDR_IS_SET = "); Serial.println(get_addr_dta(CMD_READ_EEPROM, ADDR_IS_SET)); Serial.print("ADDR_FACTORY_ADC_NH3 = "); Serial.println(get_addr_dta(CMD_READ_EEPROM, ADDR_FACTORY_ADC_NH3)); Serial.print("ADDR_FACTORY_ADC_CO = "); Serial.println(get_addr_dta(CMD_READ_EEPROM, ADDR_FACTORY_ADC_CO)); @@ -581,7 +581,7 @@ float MutichannelGasSensor::getR0(unsigned char ch) // 0:CH3, 1:CO, 2:NO Serial.println("ERROR: getR0() is NOT support by V1 firmware."); return -1; } - + int a = 0; switch(ch) { @@ -590,54 +590,54 @@ float MutichannelGasSensor::getR0(unsigned char ch) // 0:CH3, 1:CO, 2:NO Serial.print("a_ch3 = "); Serial.println(a); break; - + case 1: // CO a = get_addr_dta(CMD_READ_EEPROM, ADDR_USER_ADC_CO); Serial.print("a_co = "); Serial.println(a); break; - + case 2: // NO2 a = get_addr_dta(CMD_READ_EEPROM, ADDR_USER_ADC_NO2); Serial.print("a_no2 = "); Serial.println(a); break; - + default:; } - float r = 56.0*(float)a/(1023.0-(float)a); + float r = 56.0f*(float)a/(1023.0f-(float)a); return r; } float MutichannelGasSensor::getRs(unsigned char ch) // 0:CH3, 1:CO, 2:NO2 { - + if(__version == 1) { Serial.println("ERROR: getRs() is NOT support by V1 firmware."); return -1; } - + int a = 0; switch(ch) { case 0: // NH3 a = get_addr_dta(1); break; - + case 1: // CO a = get_addr_dta(2); break; - + case 2: // NO2 a = get_addr_dta(3); break; - + default:; } - - float r = 56.0*(float)a/(1023.0-(float)a); + + float r = 56.0f*(float)a/(1023.0f-(float)a); return r; } @@ -645,12 +645,12 @@ float MutichannelGasSensor::getRs(unsigned char ch) // 0:CH3, 1:CO, 2:NO // 2. change adc value of R0 to default void MutichannelGasSensor::factory_setting() { - + unsigned char tmp[7]; unsigned char error; unsigned char address = 0; - + for(address = 1; address < 127; address++ ) { // The i2c_scanner uses the return value of @@ -661,11 +661,11 @@ void MutichannelGasSensor::factory_setting() if (error == 0) { // change i2c to 0x04 - + Serial.print("I2C address is: 0x"); Serial.println(address, HEX); Serial.println("Change I2C address to 0x04"); - + dta_test[0] = CMD_CHANGE_I2C; dta_test[1] = 0x04; write_i2c(address, dta_test, 2); @@ -680,15 +680,15 @@ void MutichannelGasSensor::factory_setting() unsigned int a0 = get_addr_dta(CMD_READ_EEPROM, ADDR_FACTORY_ADC_NH3); unsigned int a1 = get_addr_dta(CMD_READ_EEPROM, ADDR_FACTORY_ADC_CO); unsigned int a2 = get_addr_dta(CMD_READ_EEPROM, ADDR_FACTORY_ADC_NO2); - + tmp[0] = 7; tmp[1] = a0>>8; - tmp[2] = a0&0xff; + tmp[2] = a0&0xff; tmp[3] = a1>>8; tmp[4] = a1&0xff; tmp[5] = a2>>8; - tmp[6] = a2&0xff; + tmp[6] = a2&0xff; delay(100); write_i2c(i2cAddress, tmp, 7); delay(100); @@ -699,13 +699,13 @@ void MutichannelGasSensor::change_i2c_address(unsigned char addr) dta_test[0] = CMD_CHANGE_I2C; dta_test[1] = addr; write_i2c(i2cAddress, dta_test, 2); - - + + Serial.print("FUNCTION: CHANGE I2C ADDRESS: 0X"); Serial.print(i2cAddress, HEX); Serial.print(" > 0x"); Serial.println(addr, HEX); - + i2cAddress = addr; } diff --git a/lib/Mutichannel_Gas_Sensor/src/MutichannelGasSensor.h b/lib/Mutichannel_Gas_Sensor/src/MutichannelGasSensor.h index 5f4ce7c7f..87ad10b46 100644 --- a/lib/Mutichannel_Gas_Sensor/src/MutichannelGasSensor.h +++ b/lib/Mutichannel_Gas_Sensor/src/MutichannelGasSensor.h @@ -6,7 +6,7 @@ 2015-3-17 http://www.seeed.cc/ modi by Jack, 2015-8 - + V2 by Loovee 2016-11-11 @@ -38,7 +38,7 @@ #define DEFAULT_I2C_ADDR 0x04 -#define ADDR_IS_SET 0 // if this is the first time to run, if 1126, set +#define ADDR_IS_SET 0 // if this is the first time to run, if 1126, set #define ADDR_FACTORY_ADC_NH3 2 #define ADDR_FACTORY_ADC_CO 4 #define ADDR_FACTORY_ADC_NO2 6 @@ -68,19 +68,23 @@ enum{CO, NO2, NH3, C3H8, C4H10, GAS_CH4, H2, C2H5OH}; +// FastPrecisePowf from tasmota/support_float.ino +extern float FastPrecisePowf(const float x, const float y); + class MutichannelGasSensor{ private: + static inline float pow(float a, float b) { return FastPrecisePowf(a, b); } int __version; int __send_error; unsigned char dta_test[20]; - + unsigned int readChAdcValue(int ch); unsigned int adcValueR0_NH3_Buf; unsigned int adcValueR0_CO_Buf; unsigned int adcValueR0_NO2_Buf; - + public: uint8_t i2cAddress; //I2C address of this MCU @@ -98,7 +102,7 @@ public: int16_t readR0(void); int16_t readR(void); float calcGas(int gas); - + public: void begin(int address); @@ -107,7 +111,7 @@ public: void powerOn(void); void powerOff(void); void doCalibrate(void); - + //get gas concentration, unit: ppm float measure_CO(){return calcGas(CO);} float measure_NO2(){return calcGas(NO2);} @@ -117,7 +121,7 @@ public: float measure_CH4(){return calcGas(GAS_CH4);} float measure_H2(){return calcGas(H2);} float measure_C2H5OH(){return calcGas(C2H5OH);} - + float getR0(unsigned char ch); // 0:CH3, 1:CO, 2:NO2 float getRs(unsigned char ch); // 0:CH3, 1:CO, 2:NO2 diff --git a/lib/OpenTherm-0.9.0/LICENSE b/lib/OpenTherm-0.9.0/LICENSE new file mode 100644 index 000000000..42a9cdf66 --- /dev/null +++ b/lib/OpenTherm-0.9.0/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Ihor Melnyk + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/lib/OpenTherm-0.9.0/README.md b/lib/OpenTherm-0.9.0/README.md new file mode 100644 index 000000000..9482c7403 --- /dev/null +++ b/lib/OpenTherm-0.9.0/README.md @@ -0,0 +1,65 @@ +# OpenTherm Arduino/ESP8266 Library + +This library provides implementation of OpenTherm protocol. + +OpenTherm Library is based on OpenTherm protocol specification v2.2 and works with all OpenTherm compatible boilers. Library can be easily installed into Arduino IDE and compiled for Arduino, ESP8266 and other similar controllers. + +OpenTherm protocol requires simple low voltage twowire connection to boiler, but voltage levels (7..15V) still much higher than Arduino/ESP8266 levels, which requires [OpenTherm Adapter](http://ihormelnyk.com/opentherm_adapter). + +This version of library uses interrupts to achieve better stability and synchronization with boiler. + +## Using OpenTherm Library you will be able: +- control your boiler remotely (get status, switch on/off heating/water heating, set water temperature and much more) +- make custom thermostat + +## Configuration and Usage: +```c +#include +``` +You have to choose 2 controller GPIO pins which will be used for communication and connected to [OpenTherm Adapter](http://ihormelnyk.com/opentherm_adapter). Controller(Arduino/ESP8266) input pin should support interrupts. +Controller output pin should be connected to OpenTherm Adapter input pin and vise versa. +```c +const int inPin = 2; +const int outPin = 3; +``` +Define OpenTherm class instance using constructor which accepts as arguments pin numbers: +```c +OpenTherm ot(inPin, outPin); +``` +Define interrupts handler function for specified above instance: +```c +void handleInterrupt() { + ot.handleInterrupt(); +} +``` +Use begin function to initialize OpenTherm instance, specify interrupts handler function as argument +```c +void setup() +{ + ot.begin(handleInterrupt); +} +``` +According to OpenTherm Protocol specification master (controller) must communicate at least every 1 sec. So lets make some requests in loop function: +```c +void loop() +{ + //Set/Get Boiler Status + ot.setBoilerStatus(enableCentralHeating, enableHotWater, enableCooling); + //Set Boiler Temperature to 64 degrees C + ot.setBoilerTemperature(64); + //Get Boiler Temperature + float temperature = ot.getBoilerTemperature(); + delay(1000); +} +``` + +In details [OpenTherm Library](http://ihormelnyk.com/opentherm_library) described [here](http://ihormelnyk.com/opentherm_library). + +## OpenTherm Adapter Schematic +![opentherm adapter schmetic](http://ihormelnyk.com/Content/Pages/opentherm_adapter/opentherm_adapter_schematic.png) + +## Arduino UNO Connection +![opentherm adapter arduino](http://ihormelnyk.com/Content/Pages/opentherm_adapter/opentherm_adapter_arduino_connection.png) + +## License +Copyright (c) 2018 [Ihor Melnyk](http://ihormelnyk.com). Licensed under the [MIT license](/LICENSE?raw=true). diff --git a/lib/OpenTherm-0.9.0/keywords.txt b/lib/OpenTherm-0.9.0/keywords.txt new file mode 100644 index 000000000..881d1da7d --- /dev/null +++ b/lib/OpenTherm-0.9.0/keywords.txt @@ -0,0 +1,40 @@ +####################################### +# Syntax Coloring Map For OpenTherm +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +OpenTherm KEYWORD1 +OpenThermStatus KEYWORD1 +OpenThermResponseStatus KEYWORD1 +OpenThermRequestType KEYWORD1 +OpenThermMessageID KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +begin KEYWORD2 +isReady KEYWORD2 +sendRequest KEYWORD2 +sendRequestAync KEYWORD2 +buildRequest KEYWORD2 +getLastResponseStatus KEYWORD2 +handleInterrupt KEYWORD2 +process KEYWORD2 +end KEYWORD2 +doSomething KEYWORD2 + +setBoilerStatus KEYWORD2 +setBoilerTemperature KEYWORD2 +getBoilerTemperature KEYWORD2 + +####################################### +# Instances (KEYWORD2) +####################################### + +####################################### +# Constants (LITERAL1) +####################################### \ No newline at end of file diff --git a/lib/OpenTherm-0.9.0/library.properties b/lib/OpenTherm-0.9.0/library.properties new file mode 100644 index 000000000..003b43eef --- /dev/null +++ b/lib/OpenTherm-0.9.0/library.properties @@ -0,0 +1,10 @@ +name=OpenTherm Library +version=0.9.0 +author=Ihor Melnyk +maintainer=Ihor Melnyk +sentence=OpenTherm Library for HVAC system control communication using Arduino and ESP8266 hardware. +paragraph=OpenTherm Library is based on OpenTherm protocol specification v2.2 and works with all OpenTherm compatible boilers. +category=Communication +url=https://github.com/ihormelnyk/opentherm_library +architectures=* +includes=OpenTherm.h diff --git a/lib/OpenTherm-0.9.0/src/OpenTherm.cpp b/lib/OpenTherm-0.9.0/src/OpenTherm.cpp new file mode 100644 index 000000000..a08608649 --- /dev/null +++ b/lib/OpenTherm-0.9.0/src/OpenTherm.cpp @@ -0,0 +1,410 @@ +/* +OpenTherm.cpp - OpenTherm Communication Library For Arduino, ESP8266 +Copyright 2018, Ihor Melnyk +*/ + +#include "OpenTherm.h" + +OpenTherm::OpenTherm(int inPin, int outPin, bool isSlave): + status(OpenThermStatus::NOT_INITIALIZED), + inPin(inPin), + outPin(outPin), + isSlave(isSlave), + response(0), + responseStatus(OpenThermResponseStatus::NONE), + responseTimestamp(0), + handleInterruptCallback(NULL), + processResponseCallback(NULL) +{ +} + +void OpenTherm::begin(void(*handleInterruptCallback)(void), void(*processResponseCallback)(unsigned long, int)) +{ + pinMode(inPin, INPUT); + pinMode(outPin, OUTPUT); + if (handleInterruptCallback != NULL) { + this->handleInterruptCallback = handleInterruptCallback; + attachInterrupt(digitalPinToInterrupt(inPin), handleInterruptCallback, CHANGE); + } + activateBoiler(); + status = OpenThermStatus::READY; + this->processResponseCallback = processResponseCallback; +} + +void OpenTherm::begin(void(*handleInterruptCallback)(void)) +{ + begin(handleInterruptCallback, NULL); +} + +bool ICACHE_RAM_ATTR OpenTherm::isReady() +{ + return status == OpenThermStatus::READY; +} + +int ICACHE_RAM_ATTR OpenTherm::readState() { + return digitalRead(inPin); +} + +void OpenTherm::setActiveState() { + digitalWrite(outPin, LOW); +} + +void OpenTherm::setIdleState() { + digitalWrite(outPin, HIGH); +} + +void OpenTherm::activateBoiler() { + setIdleState(); + delay(1000); +} + +void OpenTherm::sendBit(bool high) { + if (high) setActiveState(); else setIdleState(); + delayMicroseconds(500); + if (high) setIdleState(); else setActiveState(); + delayMicroseconds(500); +} + +bool OpenTherm::sendRequestAync(unsigned long request) +{ + //Serial.println("Request: " + String(request, HEX)); + noInterrupts(); + const bool ready = isReady(); + interrupts(); + + if (!ready) + return false; + + status = OpenThermStatus::REQUEST_SENDING; + response = 0; + responseStatus = OpenThermResponseStatus::NONE; + + sendBit(HIGH); //start bit + for (int i = 31; i >= 0; i--) { + sendBit(bitRead(request, i)); + } + sendBit(HIGH); //stop bit + setIdleState(); + + status = OpenThermStatus::RESPONSE_WAITING; + responseTimestamp = micros(); + return true; +} + +unsigned long OpenTherm::sendRequest(unsigned long request) +{ + if (!sendRequestAync(request)) return 0; + while (!isReady()) { + process(); + yield(); + } + return response; +} + +bool OpenTherm::sendResponse(unsigned long request) +{ + status = OpenThermStatus::REQUEST_SENDING; + response = 0; + responseStatus = OpenThermResponseStatus::NONE; + + sendBit(HIGH); //start bit + for (int i = 31; i >= 0; i--) { + sendBit(bitRead(request, i)); + } + sendBit(HIGH); //stop bit + setIdleState(); + status = OpenThermStatus::READY; + return true; +} + +OpenThermResponseStatus OpenTherm::getLastResponseStatus() +{ + return responseStatus; +} + +void ICACHE_RAM_ATTR OpenTherm::handleInterrupt() +{ + if (isReady()) + { + if (isSlave && readState() == HIGH) { + status = OpenThermStatus::RESPONSE_WAITING; + } + else { + return; + } + } + + unsigned long newTs = micros(); + if (status == OpenThermStatus::RESPONSE_WAITING) { + if (readState() == HIGH) { + status = OpenThermStatus::RESPONSE_START_BIT; + responseTimestamp = newTs; + } + else { + status = OpenThermStatus::RESPONSE_INVALID; + responseTimestamp = newTs; + } + } + else if (status == OpenThermStatus::RESPONSE_START_BIT) { + if ((newTs - responseTimestamp < 750) && readState() == LOW) { + status = OpenThermStatus::RESPONSE_RECEIVING; + responseTimestamp = newTs; + responseBitIndex = 0; + } + else { + status = OpenThermStatus::RESPONSE_INVALID; + responseTimestamp = newTs; + } + } + else if (status == OpenThermStatus::RESPONSE_RECEIVING) { + if ((newTs - responseTimestamp) > 750) { + if (responseBitIndex < 32) { + response = (response << 1) | !readState(); + responseTimestamp = newTs; + responseBitIndex++; + } + else { //stop bit + status = OpenThermStatus::RESPONSE_READY; + responseTimestamp = newTs; + } + } + } +} + +void OpenTherm::process() +{ + noInterrupts(); + OpenThermStatus st = status; + unsigned long ts = responseTimestamp; + interrupts(); + + if (st == OpenThermStatus::READY) return; + unsigned long newTs = micros(); + if (st != OpenThermStatus::NOT_INITIALIZED && (newTs - ts) > 1000000) { + status = OpenThermStatus::READY; + responseStatus = OpenThermResponseStatus::TIMEOUT; + if (processResponseCallback != NULL) { + processResponseCallback(response, responseStatus); + } + } + else if (st == OpenThermStatus::RESPONSE_INVALID) { + status = OpenThermStatus::DELAY; + responseStatus = OpenThermResponseStatus::INVALID; + if (processResponseCallback != NULL) { + processResponseCallback(response, responseStatus); + } + } + else if (st == OpenThermStatus::RESPONSE_READY) { + status = OpenThermStatus::DELAY; + responseStatus = (isSlave ? isValidRequest(response) : isValidResponse(response)) ? OpenThermResponseStatus::SUCCESS : OpenThermResponseStatus::INVALID; + if (processResponseCallback != NULL) { + processResponseCallback(response, responseStatus); + } + } + else if (st == OpenThermStatus::DELAY) { + if ((newTs - ts) > 100000) { + status = OpenThermStatus::READY; + } + } +} + +bool OpenTherm::parity(unsigned long frame) //odd parity +{ + byte p = 0; + while (frame > 0) + { + if (frame & 1) p++; + frame = frame >> 1; + } + return (p & 1); +} + +OpenThermMessageType OpenTherm::getMessageType(unsigned long message) +{ + OpenThermMessageType msg_type = static_cast((message >> 28) & 7); + return msg_type; +} + +OpenThermMessageID OpenTherm::getDataID(unsigned long frame) +{ + return (OpenThermMessageID)((frame >> 16) & 0xFF); +} + +unsigned long OpenTherm::buildRequest(OpenThermMessageType type, OpenThermMessageID id, unsigned int data) +{ + unsigned long request = data; + if (type == OpenThermMessageType::WRITE_DATA) { + request |= 1ul << 28; + } + request |= ((unsigned long)id) << 16; + if (OpenTherm::parity(request)) request |= (1ul << 31); + return request; +} + +unsigned long OpenTherm::buildResponse(OpenThermMessageType type, OpenThermMessageID id, unsigned int data) +{ + unsigned long response = data; + response |= type << 28; + response |= ((unsigned long)id) << 16; + if (OpenTherm::parity(response)) response |= (1ul << 31); + return response; +} + +bool OpenTherm::isValidResponse(unsigned long response) +{ + if (OpenTherm::parity(response)) return false; + byte msgType = (response << 1) >> 29; + return msgType == READ_ACK || msgType == WRITE_ACK; +} + +bool OpenTherm::isValidRequest(unsigned long request) +{ + if (OpenTherm::parity(request)) return false; + byte msgType = (request << 1) >> 29; + return msgType == READ_DATA || msgType == WRITE_DATA; +} + +void OpenTherm::end() { + if (this->handleInterruptCallback != NULL) { + detachInterrupt(digitalPinToInterrupt(inPin)); + } +} + +const char *OpenTherm::statusToString(OpenThermResponseStatus status) +{ + switch (status) { + case NONE: return "NONE"; + case SUCCESS: return "SUCCESS"; + case INVALID: return "INVALID"; + case TIMEOUT: return "TIMEOUT"; + default: return "UNKNOWN"; + } +} + +const char *OpenTherm::messageTypeToString(OpenThermMessageType message_type) +{ + switch (message_type) { + case READ_DATA: return "READ_DATA"; + case WRITE_DATA: return "WRITE_DATA"; + case INVALID_DATA: return "INVALID_DATA"; + case RESERVED: return "RESERVED"; + case READ_ACK: return "READ_ACK"; + case WRITE_ACK: return "WRITE_ACK"; + case DATA_INVALID: return "DATA_INVALID"; + case UNKNOWN_DATA_ID: return "UNKNOWN_DATA_ID"; + default: return "UNKNOWN"; + } +} + +//building requests + +unsigned long OpenTherm::buildSetBoilerStatusRequest(bool enableCentralHeating, bool enableHotWater, bool enableCooling, bool enableOutsideTemperatureCompensation, bool enableCentralHeating2) { + unsigned int data = enableCentralHeating | (enableHotWater << 1) | (enableCooling << 2) | (enableOutsideTemperatureCompensation << 3) | (enableCentralHeating2 << 4); + data <<= 8; + return buildRequest(OpenThermMessageType::READ_DATA, OpenThermMessageID::Status, data); +} + +unsigned long OpenTherm::buildSetBoilerTemperatureRequest(float temperature) { + unsigned int data = temperatureToData(temperature); + return buildRequest(OpenThermMessageType::WRITE_DATA, OpenThermMessageID::TSet, data); +} + +unsigned long OpenTherm::buildSetHotWaterTemperatureRequest(float temperature) { + unsigned int data = temperatureToData(temperature); + return buildRequest(OpenThermMessageType::WRITE_DATA, OpenThermMessageID::TdhwSet, data); +} + +unsigned long OpenTherm::buildGetBoilerTemperatureRequest() { + return buildRequest(OpenThermMessageType::READ_DATA, OpenThermMessageID::Tboiler, 0); +} + +unsigned long OpenTherm::buildSlaveConfigurationRequest() { + return buildRequest(OpenThermMessageType::READ_DATA, OpenThermMessageID::SConfigSMemberIDcode, 0); +} + +//parsing responses +bool OpenTherm::isFault(unsigned long response) { + return response & 0x1; +} + +bool OpenTherm::isCentralHeatingActive(unsigned long response) { + return response & 0x2; +} + +bool OpenTherm::isHotWaterActive(unsigned long response) { + return response & 0x4; +} + +bool OpenTherm::isFlameOn(unsigned long response) { + return response & 0x8; +} + +bool OpenTherm::isCoolingActive(unsigned long response) { + return response & 0x10; +} + +bool OpenTherm::isDiagnostic(unsigned long response) { + return response & 0x40; +} + +uint16_t OpenTherm::getUInt(const unsigned long response) { + const uint16_t u88 = response & 0xffff; + return u88; +} + +float OpenTherm::getFloat(const unsigned long response) { + const uint16_t u88 = getUInt(response); + const float f = (u88 & 0x8000) ? -(0x10000L - u88) / 256.0f : u88 / 256.0f; + return f; +} + +unsigned int OpenTherm::temperatureToData(float temperature) { + if (temperature < 0) temperature = 0; + if (temperature > 100) temperature = 100; + unsigned int data = (unsigned int)(temperature * 256); + return data; +} + +//basic requests + +unsigned long OpenTherm::setBoilerStatus(bool enableCentralHeating, bool enableHotWater, bool enableCooling, bool enableOutsideTemperatureCompensation, bool enableCentralHeating2) { + return sendRequest(buildSetBoilerStatusRequest(enableCentralHeating, enableHotWater, enableCooling, enableOutsideTemperatureCompensation, enableCentralHeating2)); +} + +bool OpenTherm::setBoilerTemperature(float temperature) { + unsigned long response = sendRequest(buildSetBoilerTemperatureRequest(temperature)); + return isValidResponse(response); +} + +bool OpenTherm::setHotWaterTemperature(float temperature) { + unsigned long response = sendRequest(buildSetHotWaterTemperatureRequest(temperature)); + return isValidResponse(response); +} + +float OpenTherm::getBoilerTemperature() { + unsigned long response = sendRequest(buildGetBoilerTemperatureRequest()); + return isValidResponse(response) ? getFloat(response) : 0; +} + +float OpenTherm::getReturnTemperature() { + unsigned long response = sendRequest(buildRequest(OpenThermRequestType::READ, OpenThermMessageID::Tret, 0)); + return isValidResponse(response) ? getFloat(response) : 0; +} + +float OpenTherm::getModulation() { + unsigned long response = sendRequest(buildRequest(OpenThermRequestType::READ, OpenThermMessageID::RelModLevel, 0)); + return isValidResponse(response) ? getFloat(response) : 0; +} + +float OpenTherm::getPressure() { + unsigned long response = sendRequest(buildRequest(OpenThermRequestType::READ, OpenThermMessageID::CHPressure, 0)); + return isValidResponse(response) ? getFloat(response) : 0; +} + +unsigned char OpenTherm::getFault() { + return ((sendRequest(buildRequest(OpenThermRequestType::READ, OpenThermMessageID::ASFflags, 0)) >> 8) & 0xff); +} + +unsigned long OpenTherm::getSlaveConfiguration() { + return sendRequest(buildSlaveConfigurationRequest()); +} \ No newline at end of file diff --git a/lib/OpenTherm-0.9.0/src/OpenTherm.h b/lib/OpenTherm-0.9.0/src/OpenTherm.h new file mode 100644 index 000000000..22bf965ad --- /dev/null +++ b/lib/OpenTherm-0.9.0/src/OpenTherm.h @@ -0,0 +1,193 @@ +/* +OpenTherm.h - OpenTherm Library for the ESP8266/Arduino platform +https://github.com/ihormelnyk/OpenTherm +http://ihormelnyk.com/pages/OpenTherm +Licensed under MIT license +Copyright 2018, Ihor Melnyk + +Frame Structure: +P MGS-TYPE SPARE DATA-ID DATA-VALUE +0 000 0000 00000000 00000000 00000000 +*/ + +#ifndef OpenTherm_h +#define OpenTherm_h + +#include +#include + +enum OpenThermResponseStatus { + NONE, + SUCCESS, + INVALID, + TIMEOUT +}; + + +enum OpenThermMessageType { + /* Master to Slave */ + READ_DATA = B000, + READ = READ_DATA, // for backwared compatibility + WRITE_DATA = B001, + WRITE = WRITE_DATA, // for backwared compatibility + INVALID_DATA = B010, + RESERVED = B011, + /* Slave to Master */ + READ_ACK = B100, + WRITE_ACK = B101, + DATA_INVALID = B110, + UNKNOWN_DATA_ID = B111 +}; + +typedef OpenThermMessageType OpenThermRequestType; // for backwared compatibility + +enum OpenThermMessageID { + Status, // flag8 / flag8 Master and Slave Status flags. + TSet, // f8.8 Control setpoint ie CH water temperature setpoint (°C) + MConfigMMemberIDcode, // flag8 / u8 Master Configuration Flags / Master MemberID Code + SConfigSMemberIDcode, // flag8 / u8 Slave Configuration Flags / Slave MemberID Code + Command, // u8 / u8 Remote Command + ASFflags, // / OEM-fault-code flag8 / u8 Application-specific fault flags and OEM fault code + RBPflags, // flag8 / flag8 Remote boiler parameter transfer-enable & read/write flags + CoolingControl, // f8.8 Cooling control signal (%) + TsetCH2, // f8.8 Control setpoint for 2e CH circuit (°C) + TrOverride, // f8.8 Remote override room setpoint + TSP, // u8 / u8 Number of Transparent-Slave-Parameters supported by slave + TSPindexTSPvalue, // u8 / u8 Index number / Value of referred-to transparent slave parameter. + FHBsize, // u8 / u8 Size of Fault-History-Buffer supported by slave + FHBindexFHBvalue, // u8 / u8 Index number / Value of referred-to fault-history buffer entry. + MaxRelModLevelSetting, // f8.8 Maximum relative modulation level setting (%) + MaxCapacityMinModLevel, // u8 / u8 Maximum boiler capacity (kW) / Minimum boiler modulation level(%) + TrSet, // f8.8 Room Setpoint (°C) + RelModLevel, // f8.8 Relative Modulation Level (%) + CHPressure, // f8.8 Water pressure in CH circuit (bar) + DHWFlowRate, // f8.8 Water flow rate in DHW circuit. (litres/minute) + DayTime, // special / u8 Day of Week and Time of Day + Date, // u8 / u8 Calendar date + Year, // u16 Calendar year + TrSetCH2, // f8.8 Room Setpoint for 2nd CH circuit (°C) + Tr, // f8.8 Room temperature (°C) + Tboiler, // f8.8 Boiler flow water temperature (°C) + Tdhw, // f8.8 DHW temperature (°C) + Toutside, // f8.8 Outside temperature (°C) + Tret, // f8.8 Return water temperature (°C) + Tstorage, // f8.8 Solar storage temperature (°C) + Tcollector, // f8.8 Solar collector temperature (°C) + TflowCH2, // f8.8 Flow water temperature CH2 circuit (°C) + Tdhw2, // f8.8 Domestic hot water temperature 2 (°C) + Texhaust, // s16 Boiler exhaust temperature (°C) + TdhwSetUBTdhwSetLB = 48, // s8 / s8 DHW setpoint upper & lower bounds for adjustment (°C) + MaxTSetUBMaxTSetLB, // s8 / s8 Max CH water setpoint upper & lower bounds for adjustment (°C) + HcratioUBHcratioLB, // s8 / s8 OTC heat curve ratio upper & lower bounds for adjustment + TdhwSet = 56, // f8.8 DHW setpoint (°C) (Remote parameter 1) + MaxTSet, // f8.8 Max CH water setpoint (°C) (Remote parameters 2) + Hcratio, // f8.8 OTC heat curve ratio (°C) (Remote parameter 3) + RemoteOverrideFunction = 100, // flag8 / - Function of manual and program changes in master and remote room setpoint. + OEMDiagnosticCode = 115, // u16 OEM-specific diagnostic/service code + BurnerStarts, // u16 Number of starts burner + CHPumpStarts, // u16 Number of starts CH pump + DHWPumpValveStarts, // u16 Number of starts DHW pump/valve + DHWBurnerStarts, // u16 Number of starts burner during DHW mode + BurnerOperationHours, // u16 Number of hours that burner is in operation (i.e. flame on) + CHPumpOperationHours, // u16 Number of hours that CH pump has been running + DHWPumpValveOperationHours, // u16 Number of hours that DHW pump has been running or DHW valve has been opened + DHWBurnerOperationHours, // u16 Number of hours that burner is in operation during DHW mode + OpenThermVersionMaster, // f8.8 The implemented version of the OpenTherm Protocol Specification in the master. + OpenThermVersionSlave, // f8.8 The implemented version of the OpenTherm Protocol Specification in the slave. + MasterVersion, // u8 / u8 Master product version number and type + SlaveVersion, // u8 / u8 Slave product version number and type +}; + +enum OpenThermStatus { + NOT_INITIALIZED, + READY, + DELAY, + REQUEST_SENDING, + RESPONSE_WAITING, + RESPONSE_START_BIT, + RESPONSE_RECEIVING, + RESPONSE_READY, + RESPONSE_INVALID +}; + +class OpenTherm +{ +public: + OpenTherm(int inPin = 4, int outPin = 5, bool isSlave = false); + volatile OpenThermStatus status; + void begin(void(*handleInterruptCallback)(void)); + void begin(void(*handleInterruptCallback)(void), void(*processResponseCallback)(unsigned long, int)); + bool isReady(); + unsigned long sendRequest(unsigned long request); + bool sendResponse(unsigned long request); + bool sendRequestAync(unsigned long request); + static unsigned long buildRequest(OpenThermMessageType type, OpenThermMessageID id, unsigned int data); + static unsigned long buildResponse(OpenThermMessageType type, OpenThermMessageID id, unsigned int data); + OpenThermResponseStatus getLastResponseStatus(); + const char *statusToString(OpenThermResponseStatus status); + void handleInterrupt(); + void process(); + void end(); + + static bool parity(unsigned long frame); + OpenThermMessageType getMessageType(unsigned long message); + OpenThermMessageID getDataID(unsigned long frame); + const char *messageTypeToString(OpenThermMessageType message_type); + bool isValidRequest(unsigned long request); + bool isValidResponse(unsigned long response); + + //requests + unsigned long buildSetBoilerStatusRequest(bool enableCentralHeating, bool enableHotWater = false, bool enableCooling = false, bool enableOutsideTemperatureCompensation = false, bool enableCentralHeating2 = false); + unsigned long buildSetBoilerTemperatureRequest(float temperature); + unsigned long buildGetBoilerTemperatureRequest(); + unsigned long buildSetHotWaterTemperatureRequest(float temperature); + unsigned long buildSlaveConfigurationRequest(); + + + //responses + static bool isFault(unsigned long response); + static bool isCentralHeatingActive(unsigned long response); + static bool isHotWaterActive(unsigned long response); + static bool isFlameOn(unsigned long response); + static bool isCoolingActive(unsigned long response); + static bool isDiagnostic(unsigned long response); + static uint16_t getUInt(const unsigned long response); + static float getFloat(const unsigned long response); + static unsigned int temperatureToData(float temperature); + + //basic requests + unsigned long setBoilerStatus(bool enableCentralHeating, bool enableHotWater = false, bool enableCooling = false, bool enableOutsideTemperatureCompensation = false, bool enableCentralHeating2 = false); + bool setBoilerTemperature(float temperature); + bool setHotWaterTemperature(float temperature); + float getBoilerTemperature(); + float getReturnTemperature(); + float getModulation(); + float getPressure(); + unsigned char getFault(); + unsigned long getSlaveConfiguration(); + +private: + const int inPin; + const int outPin; + const bool isSlave; + + volatile unsigned long response; + volatile OpenThermResponseStatus responseStatus; + volatile unsigned long responseTimestamp; + volatile byte responseBitIndex; + + int readState(); + void setActiveState(); + void setIdleState(); + void activateBoiler(); + + void sendBit(bool high); + void(*handleInterruptCallback)(); + void(*processResponseCallback)(unsigned long, int); +}; + +#ifndef ICACHE_RAM_ATTR +#define ICACHE_RAM_ATTR +#endif + +#endif // OpenTherm_h \ No newline at end of file diff --git a/lib/TasmotaSerial-2.4.1/README.md b/lib/TasmotaSerial-3.0.0/README.md similarity index 86% rename from lib/TasmotaSerial-2.4.1/README.md rename to lib/TasmotaSerial-3.0.0/README.md index 019aafc07..d2196ed4c 100644 --- a/lib/TasmotaSerial-2.4.1/README.md +++ b/lib/TasmotaSerial-3.0.0/README.md @@ -1,6 +1,7 @@ # TasmotaSerial Implementation of software serial with hardware serial fallback library for the ESP8266 +Implementation of dual UART hardware serial for the ESP32 Allows for several instances to be active at the same time. diff --git a/lib/TasmotaSerial-2.4.1/examples/swsertest/swsertest.ino b/lib/TasmotaSerial-3.0.0/examples/swsertest/swsertest.ino similarity index 100% rename from lib/TasmotaSerial-2.4.1/examples/swsertest/swsertest.ino rename to lib/TasmotaSerial-3.0.0/examples/swsertest/swsertest.ino diff --git a/lib/TasmotaSerial-2.4.1/keywords.txt b/lib/TasmotaSerial-3.0.0/keywords.txt similarity index 96% rename from lib/TasmotaSerial-2.4.1/keywords.txt rename to lib/TasmotaSerial-3.0.0/keywords.txt index 9cf6d825c..f9bde9254 100644 --- a/lib/TasmotaSerial-2.4.1/keywords.txt +++ b/lib/TasmotaSerial-3.0.0/keywords.txt @@ -1,6 +1,6 @@ ####################################### # Syntax Coloring Map for TasmotaSerial -# (esp8266) +# (esp8266 and esp32) ####################################### ####################################### diff --git a/lib/TasmotaSerial-2.4.1/library.json b/lib/TasmotaSerial-3.0.0/library.json similarity index 70% rename from lib/TasmotaSerial-2.4.1/library.json rename to lib/TasmotaSerial-3.0.0/library.json index 64cde09c9..19197cce4 100644 --- a/lib/TasmotaSerial-2.4.1/library.json +++ b/lib/TasmotaSerial-3.0.0/library.json @@ -1,15 +1,17 @@ { "name": "TasmotaSerial", - "version": "2.4.1", + "version": "3.0.0", "keywords": [ "serial", "io", "TasmotaSerial" ], - "description": "Implementation of software serial with hardware serial fallback for ESP8266.", + "description": "Implementation of software serial with hardware serial fallback for ESP8266 and ESP32.", "repository": { "type": "git", "url": "https://github.com/arendst/Tasmota/lib/TasmotaSerial" }, "frameworks": "arduino", - "platforms": "espressif8266" + "platforms": [ + "espressif8266", "espressif32" + ] } diff --git a/lib/TasmotaSerial-2.4.1/library.properties b/lib/TasmotaSerial-3.0.0/library.properties similarity index 71% rename from lib/TasmotaSerial-2.4.1/library.properties rename to lib/TasmotaSerial-3.0.0/library.properties index b326d7404..d1d9e718a 100644 --- a/lib/TasmotaSerial-2.4.1/library.properties +++ b/lib/TasmotaSerial-3.0.0/library.properties @@ -1,9 +1,9 @@ name=TasmotaSerial -version=2.4.1 +version=3.0.0 author=Theo Arends maintainer=Theo Arends -sentence=Implementation of software serial with hardware serial fallback for ESP8266. +sentence=Implementation of software serial with hardware serial fallback for ESP8266 and ESP32. paragraph= category=Signal Input/Output url= -architectures=esp8266 +architectures=esp8266,esp32 diff --git a/lib/TasmotaSerial-2.4.1/src/TasmotaSerial.cpp b/lib/TasmotaSerial-3.0.0/src/TasmotaSerial.cpp similarity index 89% rename from lib/TasmotaSerial-2.4.1/src/TasmotaSerial.cpp rename to lib/TasmotaSerial-3.0.0/src/TasmotaSerial.cpp index 1fad7c0f5..6982779d5 100644 --- a/lib/TasmotaSerial-2.4.1/src/TasmotaSerial.cpp +++ b/lib/TasmotaSerial-3.0.0/src/TasmotaSerial.cpp @@ -1,5 +1,5 @@ /* - TasmotaSerial.cpp - Minimal implementation of software serial for Tasmota + TasmotaSerial.cpp - Implementation of software serial with hardware serial fallback for Tasmota Copyright (C) 2020 Theo Arends @@ -27,6 +27,8 @@ extern "C" { #include +#ifdef ESP8266 + // for STAGE and pre-2.6, we can have a single wrapper using attachInterruptArg() void ICACHE_RAM_ATTR callRxRead(void *self) { ((TasmotaSerial*)self)->rxRead(); }; @@ -79,6 +81,12 @@ static void (*ISRList[16])() = { tms_isr_15 }; +#else // ESP32 + + static int tasmota_serial_index = 2; // Allow UART2 and UART1 only + +#endif // ESP8266 + TasmotaSerial::TasmotaSerial(int receive_pin, int transmit_pin, int hardware_fallback, int nwmode, int buffer_size) { m_valid = false; @@ -87,12 +95,13 @@ TasmotaSerial::TasmotaSerial(int receive_pin, int transmit_pin, int hardware_fal m_stop_bits = 1; m_nwmode = nwmode; serial_buffer_size = buffer_size; - if (!((isValidGPIOpin(receive_pin)) && (isValidGPIOpin(transmit_pin) || transmit_pin == 16))) { - return; - } m_rx_pin = receive_pin; m_tx_pin = transmit_pin; m_in_pos = m_out_pos = 0; +#ifdef ESP8266 + if (!((isValidGPIOpin(receive_pin)) && (isValidGPIOpin(transmit_pin) || transmit_pin == 16))) { + return; + } if (hardware_fallback && (((3 == m_rx_pin) && (1 == m_tx_pin)) || ((3 == m_rx_pin) && (-1 == m_tx_pin)) || ((-1 == m_rx_pin) && (1 == m_tx_pin)))) { m_hardserial = true; } @@ -120,11 +129,16 @@ TasmotaSerial::TasmotaSerial(int receive_pin, int transmit_pin, int hardware_fal digitalWrite(m_tx_pin, HIGH); } } +#else // ESP32 + if (transmit_pin > 33) { return; } // GPIO34 - GPIO39 are Input only + m_hardserial = true; +#endif // ESP8266 - ESP32 m_valid = true; } TasmotaSerial::~TasmotaSerial() { +#ifdef ESP8266 if (!m_hardserial) { if (m_rx_pin > -1) { detachInterrupt(m_rx_pin); @@ -134,6 +148,7 @@ TasmotaSerial::~TasmotaSerial() } } } +#endif // ESP8266 } bool TasmotaSerial::isValidGPIOpin(int pin) @@ -144,6 +159,7 @@ bool TasmotaSerial::isValidGPIOpin(int pin) bool TasmotaSerial::begin(long speed, int stop_bits) { m_stop_bits = ((stop_bits -1) &1) +1; if (m_hardserial) { +#ifdef ESP8266 Serial.flush(); if (2 == m_stop_bits) { Serial.begin(speed, SERIAL_8N2); @@ -153,6 +169,24 @@ bool TasmotaSerial::begin(long speed, int stop_bits) { if (m_hardswap) { Serial.swap(); } +#else // ESP32 + if (tasmota_serial_index > 0) { // We only support UART1 and UART2 and keep UART0 for debugging + m_uart = tasmota_serial_index; + tasmota_serial_index--; + TSerial = new HardwareSerial(m_uart); + if (serial_buffer_size > 256) { + TSerial->setRxBufferSize(serial_buffer_size); + } + if (2 == m_stop_bits) { + TSerial->begin(speed, SERIAL_8N2, m_rx_pin, m_tx_pin); + } else { + TSerial->begin(speed, SERIAL_8N1, m_rx_pin, m_tx_pin); + } + } else { + m_valid = false; + } +// Serial.printf("TSR: Using UART%d\n", m_uart); +#endif // ESP8266 - ESP32 } else { // Use getCycleCount() loop to get as exact timing as possible m_bit_time = ESP.getCpuFreqMHz() * 1000000 / speed; @@ -168,12 +202,20 @@ bool TasmotaSerial::begin() { } bool TasmotaSerial::hardwareSerial() { +#ifdef ESP8266 return m_hardserial; +#else + return false; // On ESP32 do not mess with Serial0 buffers +#endif } void TasmotaSerial::flush() { if (m_hardserial) { +#ifdef ESP8266 Serial.flush(); +#else + TSerial->flush(); +#endif } else { m_in_pos = m_out_pos = 0; } @@ -181,7 +223,11 @@ void TasmotaSerial::flush() { int TasmotaSerial::peek() { if (m_hardserial) { +#ifdef ESP8266 return Serial.peek(); +#else + return TSerial->peek(); +#endif } else { if ((-1 == m_rx_pin) || (m_in_pos == m_out_pos)) return -1; return m_buffer[m_out_pos]; @@ -191,7 +237,11 @@ int TasmotaSerial::peek() { int TasmotaSerial::read() { if (m_hardserial) { +#ifdef ESP8266 return Serial.read(); +#else + return TSerial->read(); +#endif } else { if ((-1 == m_rx_pin) || (m_in_pos == m_out_pos)) return -1; uint32_t ch = m_buffer[m_out_pos]; @@ -203,7 +253,11 @@ int TasmotaSerial::read() int TasmotaSerial::available() { if (m_hardserial) { +#ifdef ESP8266 return Serial.available(); +#else + return TSerial->available(); +#endif } else { int avail = m_in_pos - m_out_pos; if (avail < 0) avail += serial_buffer_size; @@ -248,7 +302,11 @@ void TasmotaSerial::_fast_write(uint8_t b) { size_t TasmotaSerial::write(uint8_t b) { if (m_hardserial) { +#ifdef ESP8266 return Serial.write(b); +#else + return TSerial->write(b); +#endif } else { if (-1 == m_tx_pin) return 0; if (m_high_speed) { diff --git a/lib/TasmotaSerial-2.4.1/src/TasmotaSerial.h b/lib/TasmotaSerial-3.0.0/src/TasmotaSerial.h similarity index 90% rename from lib/TasmotaSerial-2.4.1/src/TasmotaSerial.h rename to lib/TasmotaSerial-3.0.0/src/TasmotaSerial.h index 3ef4ee43b..42a3f120e 100644 --- a/lib/TasmotaSerial-2.4.1/src/TasmotaSerial.h +++ b/lib/TasmotaSerial-3.0.0/src/TasmotaSerial.h @@ -1,5 +1,5 @@ /* - TasmotaSerial.h - Minimal implementation of software serial for Tasmota + TasmotaSerial.h - Implementation of software serial with hardware serial fallback for Tasmota Copyright (C) 2020 Theo Arends @@ -36,6 +36,10 @@ #include #include +#ifdef ESP32 +#include +#endif + class TasmotaSerial : public Stream { public: TasmotaSerial(int receive_pin, int transmit_pin, int hardware_fallback = 0, int nwmode = 0, int buffer_size = TM_SERIAL_BUFFER_SIZE); @@ -55,6 +59,10 @@ class TasmotaSerial : public Stream { uint32_t getLoopReadMetric(void) const { return m_bit_follow_metric; } +#ifdef ESP32 + uint32_t getUart(void) const { return m_uart; } +#endif + using Print::write; private: @@ -83,6 +91,12 @@ class TasmotaSerial : public Stream { uint8_t *m_buffer; void _fast_write(uint8_t b); // IRAM minimized version + +#ifdef ESP32 + HardwareSerial *TSerial; + int m_uart = 0; +#endif + }; #endif // TasmotaSerial_h diff --git a/lib/UdpListener/library.properties b/lib/UdpListener/library.properties new file mode 100644 index 000000000..1d453bc6c --- /dev/null +++ b/lib/UdpListener/library.properties @@ -0,0 +1,7 @@ +name=UdpListener +version=1.0 +author=Ivan Grokhotkov, Stephan Hadinger +maintainer=Stephan +sentence=UdpListener optimized for static and limite memory allocation, to reduce memory footprint of receiving SSDP request, as a replacement for WifiUdp. +paragraph=This class only handles receiving UDP Multicast packets. For sending packets, use WifiUdp. +architectures=esp8266 diff --git a/lib/UdpListener/src/UdpListener.h b/lib/UdpListener/src/UdpListener.h new file mode 100644 index 000000000..a369a5d81 --- /dev/null +++ b/lib/UdpListener/src/UdpListener.h @@ -0,0 +1,209 @@ +/* + UdpListener.h - webserver for Tasmota + + Copyright (C) 2020 Theo Arends & Stephan Hadinger + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see .@ +*/ + +// adapted from: +/* + UdpContext.h - UDP connection handling on top of lwIP + + Copyright (c) 2014 Ivan Grokhotkov. All rights reserved. + This file is part of the esp8266 core for Arduino environment. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +/* + * This is a stripped down version of Udp handler to avoid overflowing + * memory when lots of multicast SSDP packets arrive. + * The pbuf is freed immediately upon arrival of the packet. + * + * Packet data are kept in a statically area in RAM and keeps + * only the first bytes (200 by default) of each packet. + * The number of packets treated is limited (3 by default), any + * new packet arriving is dropped. + * + * This class does only receiving multicast packets for LWIP2 +*/ + +#ifndef UDPMULTICASTLISTENER_H +#define UDPMULTICASTLISTENER_H + +#ifdef ESP8266 +// #include + +extern "C" { +#include +#include +} + +template +struct UdpPacket { + IPAddress srcaddr; + IPAddress dstaddr; + int16_t srcport; + netif* input_netif; + size_t len; + uint8_t buf[PACKET_SIZE]; +}; + +template +class UdpListener +{ +public: + + typedef std::function rxhandler_t; + + UdpListener(size_t packet_number) + : _pcb(0) + , _packet_number(packet_number) + , _buffers(nullptr) + , _udp_packets(0) + , _udp_ready(false) + , _udp_index(0) + { + _packet_number = packet_number; + _buffers = new UdpPacket[_packet_number]; + _pcb = udp_new(); + } + + ~UdpListener() + { + udp_remove(_pcb); + _pcb = 0; + delete[] _buffers; + _buffers = nullptr; + } + + void reset(void) + { + _udp_packets = 0; + _udp_index = 0; + } + + bool listen(const IPAddress& addr, uint16_t port) + { + if (!_buffers) { return false; } + udp_recv(_pcb, &_s_recv, (void *) this); + err_t err = udp_bind(_pcb, addr, port); + return err == ERR_OK; + } + + void disconnect() + { + udp_disconnect(_pcb); + } + + bool next() + { + if (!_buffers) { return false; } + if (_udp_packets > 0) { + if (!_udp_ready) { + // we just consume the first packet + _udp_ready = true; + } else { + _udp_packets--; + _udp_index = (_udp_index + 1) % _packet_number; // advance to next buffer index in ring + if (_udp_packets == 0) { + _udp_ready = false; + } + } + } else { + _udp_ready = false; + } + return _udp_ready; + } + + UdpPacket * read(void) + { + if (!_buffers) { return nullptr; } + if (_udp_ready) { // we have a packet ready to consume + return &_buffers[_udp_index]; + } else { + return nullptr; + } + } + +private: + + void _recv(udp_pcb *upcb, pbuf *pb, + const ip_addr_t *srcaddr, u16_t srcport) + { + if (!_buffers) { pbuf_free(pb); return; } + // Serial.printf(">>> _recv: _udp_packets = %d, _udp_index = %d, tot_len = %d\n", _udp_packets, _udp_index, pb->tot_len); + if (_udp_packets >= _packet_number) { + // we don't have slots anymore, drop packet + pbuf_free(pb); + return; + } + + uint8_t next_slot = (_udp_index + _udp_packets) % _packet_number; + + size_t packet_len = pb->tot_len; + if (packet_len > PACKET_SIZE) { packet_len = PACKET_SIZE; } + + uint8_t * dst = &_buffers[next_slot].buf[0]; + void* buf = pbuf_get_contiguous(pb, dst, PACKET_SIZE, packet_len, 0); + if (buf) { + + if (buf != dst) + memcpy(dst, buf, packet_len); + _buffers[next_slot].len = packet_len; + + _buffers[next_slot].srcaddr = srcaddr; + _buffers[next_slot].dstaddr = ip_current_dest_addr(); + _buffers[next_slot].srcport = srcport; + _buffers[next_slot].input_netif = ip_current_input_netif(); + _udp_packets++; // we have one packet ready + } + pbuf_free(pb); // free memory immediately + } + + static void _s_recv(void *arg, + udp_pcb *upcb, pbuf *p, + CONST ip_addr_t *srcaddr, u16_t srcport) + { + reinterpret_cast(arg)->_recv(upcb, p, srcaddr, srcport); + } + +private: + udp_pcb* _pcb; + uint8_t _packet_number; + + UdpPacket * _buffers; + + // how many packets are ready. + int8_t _udp_packets; // number of udp packets ready to consume + bool _udp_ready; // is a packet currenlty consumed after a call to next() + // ring buffer ranges from 0..(_packet_number-1) + int8_t _udp_index; // current index in the ring buffer +}; + +#endif // ESP8266 +#endif //UDPMULTICASTLISTENER_H \ No newline at end of file diff --git a/lib/Unishox-1.0-shadinger/generator/generator.c b/lib/Unishox-1.0-shadinger/generator/generator.c new file mode 100644 index 000000000..81c46649e --- /dev/null +++ b/lib/Unishox-1.0-shadinger/generator/generator.c @@ -0,0 +1,165 @@ +/* + * Copyright (C) 2019 Siara Logics (cc) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @author Arundale R. + * + */ + +// Pre-compute c_95[] and l_95[] + +#include +#include +#include +#include +#include +#include + +typedef unsigned char byte; + +enum {SHX_SET1 = 0, SHX_SET1A, SHX_SET1B, SHX_SET2, SHX_SET3, SHX_SET4, SHX_SET4A}; +char us_vcodes[] = {0, 2, 3, 4, 10, 11, 12, 13, 14, 30, 31}; +char us_vcode_lens[] = {2, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5}; +char us_sets[][11] = + {{ 0, ' ', 'e', 0, 't', 'a', 'o', 'i', 'n', 's', 'r'}, + { 0, 'l', 'c', 'd', 'h', 'u', 'p', 'm', 'b', 'g', 'w'}, + {'f', 'y', 'v', 'k', 'q', 'j', 'x', 'z', 0, 0, 0}, + { 0, '9', '0', '1', '2', '3', '4', '5', '6', '7', '8'}, + {'.', ',', '-', '/', '?', '+', ' ', '(', ')', '$', '@'}, + {';', '#', ':', '<', '^', '*', '"', '{', '}', '[', ']'}, + {'=', '%', '\'', '>', '&', '_', '!', '\\', '|', '~', '`'}}; + // {{ 0, ' ', 'e', 0, 't', 'a', 'o', 'i', 'n', 's', 'r'}, + // { 0, 'l', 'c', 'd', 'h', 'u', 'p', 'm', 'b', 'g', 'w'}, + // {'f', 'y', 'v', 'k', 'q', 'j', 'x', 'z', 0, 0, 0}, + // { 0, '9', '0', '1', '2', '3', '4', '5', '6', '7', '8'}, + // {'.', ',', '-', '/', '=', '+', ' ', '(', ')', '$', '%'}, + // {'&', ';', ':', '<', '>', '*', '"', '{', '}', '[', ']'}, + // {'@', '?', '\'', '^', '#', '_', '!', '\\', '|', '~', '`'}}; + +unsigned int c_95[95] ; +unsigned char l_95[95] ; + + +void init_coder() { + for (int i = 0; i < 7; i++) { + for (int j = 0; j < 11; j++) { + char c = us_sets[i][j]; + if (c != 0 && c != 32) { + int ascii = c - 32; + //int prev_code = c_95[ascii]; + //int prev_code_len = l_95[ascii]; + switch (i) { + case SHX_SET1: // just us_vcode + c_95[ascii] = (us_vcodes[j] << (16 - us_vcode_lens[j])); + l_95[ascii] = us_vcode_lens[j]; + //checkPreus_vcodes(c, prev_code, prev_code_len, c_95[ascii], l_95[ascii]); + if (c >= 'a' && c <= 'z') { + ascii -= ('a' - 'A'); + //prev_code = c_95[ascii]; + //prev_code_len = l_95[ascii]; + c_95[ascii] = (2 << 12) + (us_vcodes[j] << (12 - us_vcode_lens[j])); + l_95[ascii] = 4 + us_vcode_lens[j]; + } + break; + case SHX_SET1A: // 000 + us_vcode + c_95[ascii] = 0 + (us_vcodes[j] << (13 - us_vcode_lens[j])); + l_95[ascii] = 3 + us_vcode_lens[j]; + //checkPreus_vcodes(c, prev_code, prev_code_len, c_95[ascii], l_95[ascii]); + if (c >= 'a' && c <= 'z') { + ascii -= ('a' - 'A'); + //prev_code = c_95[ascii]; + //prev_code_len = l_95[ascii]; + c_95[ascii] = (2 << 12) + 0 + (us_vcodes[j] << (9 - us_vcode_lens[j])); + l_95[ascii] = 4 + 3 + us_vcode_lens[j]; + } + break; + case SHX_SET1B: // 00110 + us_vcode + c_95[ascii] = (6 << 11) + (us_vcodes[j] << (11 - us_vcode_lens[j])); + l_95[ascii] = 5 + us_vcode_lens[j]; + //checkPreus_vcodes(c, prev_code, prev_code_len, c_95[ascii], l_95[ascii]); + if (c >= 'a' && c <= 'z') { + ascii -= ('a' - 'A'); + //prev_code = c_95[ascii]; + //prev_code_len = l_95[ascii]; + c_95[ascii] = (2 << 12) + (6 << 7) + (us_vcodes[j] << (7 - us_vcode_lens[j])); + l_95[ascii] = 4 + 5 + us_vcode_lens[j]; + } + break; + case SHX_SET2: // 0011100 + us_vcode + c_95[ascii] = (28 << 9) + (us_vcodes[j] << (9 - us_vcode_lens[j])); + l_95[ascii] = 7 + us_vcode_lens[j]; + break; + case SHX_SET3: // 0011101 + us_vcode + c_95[ascii] = (29 << 9) + (us_vcodes[j] << (9 - us_vcode_lens[j])); + l_95[ascii] = 7 + us_vcode_lens[j]; + break; + case SHX_SET4: // 0011110 + us_vcode + c_95[ascii] = (30 << 9) + (us_vcodes[j] << (9 - us_vcode_lens[j])); + l_95[ascii] = 7 + us_vcode_lens[j]; + break; + case SHX_SET4A: // 0011111 + us_vcode + c_95[ascii] = (31 << 9) + (us_vcodes[j] << (9 - us_vcode_lens[j])); + l_95[ascii] = 7 + us_vcode_lens[j]; + } + //checkPreus_vcodes(c, prev_code, prev_code_len, c_95[ascii], l_95[ascii]); + } + } + } + c_95[0] = 16384; + l_95[0] = 3; + +} + +int main(int argv, char *args[]) { + init_coder(); + + printf("uint16_t c_95[95] PROGMEM = {"); + for (uint8_t i = 0; i<95; i++) { + if (i) { printf(", "); } + printf("0x%04X", c_95[i]); + } + printf(" };\n"); + + printf("uint8_t l_95[95] PROGMEM = {"); + for (uint8_t i = 0; i<95; i++) { + if (i) { printf(", "); } + printf("%6d", l_95[i]); + } + printf(" };\n"); + + printf("\n\n"); + + printf("uint16_t c_95[95] PROGMEM = {"); + for (uint8_t i = 0; i<95; i++) { + if (i) { printf(", "); } + printf("%5d", c_95[i]); + } + printf(" };\n"); + + printf("uint8_t l_95[95] PROGMEM = {"); + for (uint8_t i = 0; i<95; i++) { + if (i) { printf(", "); } + printf("%5d", l_95[i]); + } + printf(" };\n"); + + + printf("uint16_t cl_95[95] PROGMEM = {"); + for (uint8_t i = 0; i<95; i++) { + if (i) { printf(", "); } + printf("0x%04X + %2d", c_95[i], l_95[i]); + } + printf(" };\n"); + +} \ No newline at end of file diff --git a/lib/Unishox-1.0-shadinger/generator/remapping.xlsx b/lib/Unishox-1.0-shadinger/generator/remapping.xlsx new file mode 100644 index 000000000..94a82ecde Binary files /dev/null and b/lib/Unishox-1.0-shadinger/generator/remapping.xlsx differ diff --git a/lib/Unishox-1.0-shadinger/library.properties b/lib/Unishox-1.0-shadinger/library.properties new file mode 100644 index 000000000..138b2027c --- /dev/null +++ b/lib/Unishox-1.0-shadinger/library.properties @@ -0,0 +1,8 @@ +name=Unishox Compressor Decompressor highly customized and optimized for ESP8266 and Tasmota +version=1.0 +author=Arundale Ramanathan, Stephan Hadinger +maintainer=Arun , Stephan +sentence=Unishox compression for Tasmota Rules +paragraph=It is based on Unishox hybrid encoding technique. This version has specific Unicode code removed for size. +url=https://github.com/siara-cc/Unishox +architectures=esp8266 diff --git a/lib/Unishox-1.0-shadinger/python/unishox.py b/lib/Unishox-1.0-shadinger/python/unishox.py new file mode 100644 index 000000000..087932daa --- /dev/null +++ b/lib/Unishox-1.0-shadinger/python/unishox.py @@ -0,0 +1,521 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +Python Class for compressing short strings. + +This class contains a highly modified and optimized version of Unishox +for Tasmota converted in C ported to Pyhton3. + +It was basically developed to individually compress and decompress small strings +(see https://github.com/siara-cc/Unishox) +In general compression utilities such as zip, gzip do not compress short strings +well and often expand them. They also use lots of memory which makes them unusable +in constrained environments like Arduino. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" + +class Unishox: + """ + This is a highly modified and optimized version of Unishox + for Tasmota, aimed at compressing `Rules` which are typically + short strings from 50 to 500 bytes. + + @author Stephan Hadinger + @revised Norbert Richter + """ + + # pylint: disable=bad-continuation,bad-whitespace,line-too-long + #cl_95 = [0x4000 + 3, 0x3F80 + 11, 0x3D80 + 11, 0x3C80 + 10, 0x3BE0 + 12, 0x3E80 + 10, 0x3F40 + 11, 0x3EC0 + 10, 0x3BA0 + 11, 0x3BC0 + 11, 0x3D60 + 11, 0x3B60 + 11, 0x3A80 + 10, 0x3AC0 + 10, 0x3A00 + 9, 0x3B00 + 10, 0x38C0 + 10, 0x3900 + 10, 0x3940 + 11, 0x3960 + 11, 0x3980 + 11, 0x39A0 + 11, 0x39C0 + 11, 0x39E0 + 12, 0x39F0 + 12, 0x3880 + 10, 0x3CC0 + 10, 0x3C00 + 9, 0x3D00 + 10, 0x3E00 + 9, 0x3F00 + 10, 0x3B40 + 11, 0x3BF0 + 12, 0x2B00 + 8, 0x21C0 + 11, 0x20C0 + 10, 0x2100 + 10, 0x2600 + 7, 0x2300 + 11, 0x21E0 + 12, 0x2140 + 11, 0x2D00 + 8, 0x2358 + 13, 0x2340 + 12, 0x2080 + 10, 0x21A0 + 11, 0x2E00 + 8, 0x2C00 + 8, 0x2180 + 11, 0x2350 + 13, 0x2F80 + 9, 0x2F00 + 9, 0x2A00 + 8, 0x2160 + 11, 0x2330 + 12, 0x21F0 + 12, 0x2360 + 13, 0x2320 + 12, 0x2368 + 13, 0x3DE0 + 12, 0x3FA0 + 11, 0x3DF0 + 12, 0x3D40 + 11, 0x3F60 + 11, 0x3FF0 + 12, 0xB000 + 4, 0x1C00 + 7, 0x0C00 + 6, 0x1000 + 6, 0x6000 + 3, 0x3000 + 7, 0x1E00 + 8, 0x1400 + 7, 0xD000 + 4, 0x3580 + 9, 0x3400 + 8, 0x0800 + 6, 0x1A00 + 7, 0xE000 + 4, 0xC000 + 4, 0x1800 + 7, 0x3500 + 9, 0xF800 + 5, 0xF000 + 5, 0xA000 + 4, 0x1600 + 7, 0x3300 + 8, 0x1F00 + 8, 0x3600 + 9, 0x3200 + 8, 0x3680 + 9, 0x3DA0 + 11, 0x3FC0 + 11, 0x3DC0 + 11, 0x3FE0 + 12] + cl_95 = [0x4000 + 3, 0x3F80 + 11, 0x3D80 + 11, 0x3C80 + 10, 0x3BE0 + 12, 0x3E80 + 10, 0x3F40 + 11, 0x3EC0 + 10, 0x3BA0 + 11, 0x3BC0 + 11, 0x3D60 + 11, 0x3B60 + 11, 0x3A80 + 10, 0x3AC0 + 10, 0x3A00 + 9, 0x3B00 + 10, 0x38C0 + 10, 0x3900 + 10, 0x3940 + 11, 0x3960 + 11, 0x3980 + 11, 0x39A0 + 11, 0x39C0 + 11, 0x39E0 + 12, 0x39F0 + 12, 0x3880 + 10, 0x3CC0 + 10, 0x3C00 + 9, 0x3D00 + 10, 0x3E00 + 9, 0x3F00 + 10, 0x3B40 + 11, 0x3BF0 + 12, 0x2B00 + 8, 0x21C0 + 11, 0x20C0 + 10, 0x2100 + 10, 0x2600 + 7, 0x2300 + 11, 0x21E0 + 12, 0x2140 + 11, 0x2D00 + 8, 0x46B0 + 13, 0x2340 + 12, 0x2080 + 10, 0x21A0 + 11, 0x2E00 + 8, 0x2C00 + 8, 0x2180 + 11, 0x46A0 + 13, 0x2F80 + 9, 0x2F00 + 9, 0x2A00 + 8, 0x2160 + 11, 0x2330 + 12, 0x21F0 + 12, 0x46C0 + 13, 0x2320 + 12, 0x46D0 + 13, 0x3DE0 + 12, 0x3FA0 + 11, 0x3DF0 + 12, 0x3D40 + 11, 0x3F60 + 11, 0x3FF0 + 12, 0xB000 + 4, 0x1C00 + 7, 0x0C00 + 6, 0x1000 + 6, 0x6000 + 3, 0x3000 + 7, 0x1E00 + 8, 0x1400 + 7, 0xD000 + 4, 0x3580 + 9, 0x3400 + 8, 0x0800 + 6, 0x1A00 + 7, 0xE000 + 4, 0xC000 + 4, 0x1800 + 7, 0x3500 + 9, 0xF800 + 5, 0xF000 + 5, 0xA000 + 4, 0x1600 + 7, 0x3300 + 8, 0x1F00 + 8, 0x3600 + 9, 0x3200 + 8, 0x3680 + 9, 0x3DA0 + 11, 0x3FC0 + 11, 0x3DC0 + 11, 0x3FE0 + 12] + + # enum {SHX_STATE_1 = 1, SHX_STATE_2}; // removed Unicode state + SHX_STATE_1 = 1 + SHX_STATE_2 = 2 + + SHX_SET1 = 0 + SHX_SET1A = 1 + SHX_SET1B = 2 + SHX_SET2 = 3 + + sets = [['\0', ' ', 'e', '\0', 't', 'a', 'o', 'i', 'n', 's', 'r'], + ['\0', 'l', 'c', 'd', 'h', 'u', 'p', 'm', 'b', 'g', 'w'], + ['f', 'y', 'v', 'k', 'q', 'j', 'x', 'z', '\0', '\0', '\0'], + ['\0', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8'], + ['.', ',', '-', '/', '?', '+', ' ', '(', ')', '$', '@'], + [';', '#', ':', '<', '^', '*', '"', '{', '}', '[', ']'], + ['=', '%', '\'', '>', '&', '_', '!', '\\', '|', '~', '`']] + + us_vcode = [2 + (0 << 3), 3 + (3 << 3), 3 + (1 << 3), 4 + (6 << 3), 0, + # 5, 6, 7, 8, 9, 10 + 4 + (4 << 3), 3 + (2 << 3), 4 + (8 << 3), 0, 0, 0, + # 11, 12, 13, 14, 15 + 4 + (7 << 3), 0, 4 + (5 << 3), 0, 5 + (9 << 3), + # 16, 17, 18, 19, 20, 21, 22, 23 + 0, 0, 0, 0, 0, 0, 0, 0, + # 24, 25, 26, 27, 28, 29, 30, 31 + 0, 0, 0, 0, 0, 0, 0, 5 + (10 << 3) ] + # 0, 1, 2, 3, 4, 5, 6, 7, + us_hcode = [1 + (1 << 3), 2 + (0 << 3), 0, 3 + (2 << 3), 0, 0, 0, 5 + (3 << 3), + # 8, 9, 10, 11, 12, 13, 14, 15, + 0, 0, 0, 0, 0, 0, 0, 5 + (5 << 3), + # 16, 17, 18, 19, 20, 21, 22, 23 + 0, 0, 0, 0, 0, 0, 0, 5 + (4 << 3), + # 24, 25, 26, 27, 28, 29, 30, 31 + 0, 0, 0, 0, 0, 0, 0, 5 + (6 << 3) ] + # pylint: enable=bad-continuation,bad-whitespace + + ESCAPE_MARKER = 0x2A + + TERM_CODE = 0x37C0 + # TERM_CODE_LEN = 10 + DICT_CODE = 0x0000 + DICT_CODE_LEN = 5 + #DICT_OTHER_CODE = 0x0000 + #DICT_OTHER_CODE_LEN = 6 + RPT_CODE_TASMOTA = 0x3780 + RPT_CODE_TASMOTA_LEN = 10 + BACK2_STATE1_CODE = 0x2000 + BACK2_STATE1_CODE_LEN = 4 + #BACK_FROM_UNI_CODE = 0xFE00 + #BACK_FROM_UNI_CODE_LEN = 8 + LF_CODE = 0x3700 + LF_CODE_LEN = 9 + TAB_CODE = 0x2400 + TAB_CODE_LEN = 7 + ALL_UPPER_CODE = 0x2200 + ALL_UPPER_CODE_LEN = 8 + SW2_STATE2_CODE = 0x3800 + SW2_STATE2_CODE_LEN = 7 + ST2_SPC_CODE = 0x3B80 + ST2_SPC_CODE_LEN = 11 + BIN_CODE_TASMOTA = 0x8000 + BIN_CODE_TASMOTA_LEN = 3 + + NICE_LEN = 5 + + mask = [0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFF] + + # pylint: disable=missing-function-docstring,invalid-name + + # Input + # out = bytearray + def append_bits(self, out, ol, code, clen, state): + #print("Append bits {ol} {code} {clen} {state}".format(ol=ol, code=code, clen=clen, state=state)) + if state == self.SHX_STATE_2: + # remove change state prefix + if (code >> 9) == 0x1C: + code <<= 7 + clen -= 7 + while clen > 0: + cur_bit = ol % 8 + blen = 8 if (clen > 8) else clen + a_byte = (code >> 8) & self.mask[blen - 1] + #print("append_bits a_byte {ab} blen {blen}".format(ab=a_byte,blen=blen)) + a_byte >>= cur_bit + if blen + cur_bit > 8: + blen = (8 - cur_bit) + if cur_bit == 0: + out[ol // 8] = a_byte + else: + out[ol // 8] |= a_byte + code <<= blen + ol += blen + if 0 == ol % 8: # pylint: disable=misplaced-comparison-constant + # we completed a full byte + last_c = out[(ol // 8) - 1] + if last_c in (0, self.ESCAPE_MARKER): + out[ol // 8] = 1 + last_c # increment to 0x01 or 0x2B + out[(ol // 8) -1] = self.ESCAPE_MARKER # replace old value with marker + ol += 8 # add one full byte + clen -= blen + return ol + + codes = [0x82, 0xC3, 0xE5, 0xED, 0xF5] # pylint: disable=bad-whitespace + bit_len = [ 5, 7, 9, 12, 16] # pylint: disable=bad-whitespace + + def encodeCount(self, out, ol, count): + #print("encodeCount ol = {ol}, count = {count}".format(ol=ol, count=count)) + till = 0 + base = 0 + for i in range(len(self.bit_len)): + bit_len_i = self.bit_len[i] + till += (1 << bit_len_i) + if count < till: + codes_i = self.codes[i] + ol = self.append_bits(out, ol, (codes_i & 0xF8) << 8, codes_i & 0x07, 1) + #print("encodeCount append_bits ol = {ol}, code = {code}, len = {len}".format(ol=ol,code=(codes_i & 0xF8) << 8,len=codes_i & 0x07)) + ol = self.append_bits(out, ol, (count - base) << (16 - bit_len_i), bit_len_i, 1) + #print("encodeCount append_bits ol = {ol}, code = {code}, len = {len}".format(ol=ol,code=(count - base) << (16 - bit_len_i),len=bit_len_i)) + return ol + base = till + return ol + + # Returns (int, ol, state, is_all_upper) + def matchOccurance(self, inn, len_, l_, out, ol, state, is_all_upper): + # int j, k; + longest_dist = 0 + longest_len = 0 + #for (j = l_ - self.NICE_LEN; j >= 0; j--) { + j = l_ - self.NICE_LEN + while j >= 0: + k = l_ + #for (k = l_; k < len && j + k - l_ < l_; k++) { + while k < len_ and j + k - l_ < l_: + if inn[k] != inn[j + k - l_]: + break + k += 1 + if k - l_ > self.NICE_LEN - 1: + match_len = k - l_ - self.NICE_LEN + match_dist = l_ - j - self.NICE_LEN + 1 + if match_len > longest_len: + longest_len = match_len + longest_dist = match_dist + j -= 1 + + if longest_len: + #print("longest_len {ll}".format(ll=longest_len)) + #ol_save = ol + if state == self.SHX_STATE_2 or is_all_upper: + is_all_upper = 0 + state = self.SHX_STATE_1 + ol = self.append_bits(out, ol, self.BACK2_STATE1_CODE, self.BACK2_STATE1_CODE_LEN, state) + + ol = self.append_bits(out, ol, self.DICT_CODE, self.DICT_CODE_LEN, 1) + ol = self.encodeCount(out, ol, longest_len) + ol = self.encodeCount(out, ol, longest_dist) + #print("longest_len {ll} longest_dist {ld} ol {ols}-{ol}".format(ll=longest_len, ld=longest_dist, ol=ol, ols=ol_save)) + l_ += longest_len + self.NICE_LEN + l_ -= 1 + + return l_, ol, state, is_all_upper + return -l_, ol, state, is_all_upper + + + def compress(self, inn, len_, out, len_out): + ol = 0 + state = self.SHX_STATE_1 + is_all_upper = 0 + l = 0 + while l < len_: + # for (l=0; l 0: + #print("matchOccurance l = {l} l_old = {lo}".format(l=l,lo=l_old)) + l += 1 # for loop + continue + + l = -l + + if state == self.SHX_STATE_2: # if Set2 + if ord(' ') <= c_in <= ord('@') or ord('[') <= c_in <= ord('`') or ord('{') <= c_in <= ord('~'): + pass + else: + state = self.SHX_STATE_1 # back to Set1 and lower case + ol = self.append_bits(out, ol, self.BACK2_STATE1_CODE, self.BACK2_STATE1_CODE_LEN, state) + + is_upper = 0 + if ord('A') <= c_in <= ord('Z'): + is_upper = 1 + else: + if is_all_upper: + is_all_upper = 0 + ol = self.append_bits(out, ol, self.BACK2_STATE1_CODE, self.BACK2_STATE1_CODE_LEN, state) + + if 32 <= c_in <= 126: + if is_upper and not is_all_upper: + ll = l+5 + # for (ll=l+5; ll>=l && ll ord('Z'): + break + + ll -= 1 + + if ll == l-1: + ol = self.append_bits(out, ol, self.ALL_UPPER_CODE, self.ALL_UPPER_CODE_LEN, state) # CapsLock + is_all_upper = 1 + + if state == self.SHX_STATE_1 and ord('0') <= c_in <= ord('9'): + ol = self.append_bits(out, ol, self.SW2_STATE2_CODE, self.SW2_STATE2_CODE_LEN, state) # Switch to sticky Set2 + state = self.SHX_STATE_2 + + c_in -= 32 + if is_all_upper and is_upper: + c_in += 32 + if c_in == 0 and state == self.SHX_STATE_2: + ol = self.append_bits(out, ol, self.ST2_SPC_CODE, self.ST2_SPC_CODE_LEN, state) # space from Set2 ionstead of Set1 + else: + # ol = self.append_bits(out, ol, pgm_read_word(&c_95[c_in]), pgm_read_byte(&l_95[c_in]), state); // original version with c/l in split arrays + cl = self.cl_95[c_in] + cl_code = cl & 0xFFF0 + cl_len = cl & 0x000F + if cl_len == 13: + cl_code = cl_code >> 1 + ol = self.append_bits(out, ol, cl_code, cl_len, state) + + elif c_in == 10: + ol = self.append_bits(out, ol, self.LF_CODE, self.LF_CODE_LEN, state) # LF + elif c_in == '\t': + ol = self.append_bits(out, ol, self.TAB_CODE, self.TAB_CODE_LEN, state) # TAB + else: + ol = self.append_bits(out, ol, self.BIN_CODE_TASMOTA, self.BIN_CODE_TASMOTA_LEN, state) # Binary, we reuse the Unicode marker which 3 bits instead of 9 + ol = self.encodeCount(out, ol, (255 - c_in) & 0xFF) + + + # check that we have some headroom in the output buffer + if ol // 8 >= len_out - 4: + return -1 # we risk overflow and crash + + l += 1 + + bits = ol % 8 + if bits: + ol = self.append_bits(out, ol, self.TERM_CODE, 8 - bits, 1) # 0011 0111 1100 0000 TERM = 0011 0111 11 + return (ol + 7) // 8 + # return ol // 8 + 1 if (ol%8) else 0 + + + def getBitVal(self, inn, bit_no, count): + c_in = inn[bit_no >> 3] + if bit_no >> 3 and self.ESCAPE_MARKER == inn[(bit_no >> 3) - 1]: + c_in -= 1 + r = 1 << count if (c_in & (0x80 >> (bit_no % 8))) else 0 + #print("getBitVal r={r}".format(r=r)) + return r + + # Returns: + # 0..11 + # or -1 if end of stream + def getCodeIdx(self, code_type, inn, len_, bit_no_p): + code = 0 + count = 0 + while count < 5: + if bit_no_p >= len_: + return -1, bit_no_p + # detect marker + if self.ESCAPE_MARKER == inn[bit_no_p >> 3]: + bit_no_p += 8 # skip marker + + if bit_no_p >= len_: + return -1, bit_no_p + + code += self.getBitVal(inn, bit_no_p, count) + bit_no_p += 1 + count += 1 + code_type_code = code_type[code] + if code_type_code and (code_type_code & 0x07) == count: + #print("getCodeIdx = {r}".format(r=code_type_code >> 3)) + return code_type_code >> 3, bit_no_p + + #print("getCodeIdx not found = {r}".format(r=1)) + return 1, bit_no_p + + def getNumFromBits(self, inn, bit_no_p, count): + ret = 0 + while count: + count -= 1 + if self.ESCAPE_MARKER == inn[bit_no_p >> 3]: + bit_no_p += 8 # skip marker + ret += self.getBitVal(inn, bit_no_p, count) + bit_no_p += 1 + # print("getNumFromBits = {r}".format(r=ret)) + return ret, bit_no_p + + def readCount(self, inn, bit_no_p, len_): + (idx, bit_no_p) = self.getCodeIdx(self.us_hcode, inn, len_, bit_no_p) + if idx >= 1: + idx -= 1 # we skip v = 1 (code '0') since we no more accept 2 bits encoding + if idx >= 5 or idx < 0: + return 0, bit_no_p # unsupported or end of stream + till = 0 + bit_len_idx = 0 + base = 0 + #for (uint32_t i = 0; i <= idx; i++) { + i = 0 + while i <= idx: + # for i in range(idx): + base = till + bit_len_idx = self.bit_len[i] + till += (1 << bit_len_idx) + i += 1 + + (count, bit_no_p) = self.getNumFromBits(inn, bit_no_p, bit_len_idx) + count = count + base + #print("readCount getNumFromBits = {count} ({bl})".format(count=count,bl=bit_len_idx)) + + return count, bit_no_p + + def decodeRepeat(self, inn, len_, out, ol, bit_no): + #print("decodeRepeat Enter") + (dict_len, bit_no) = self.readCount(inn, bit_no, len_) + dict_len += self.NICE_LEN + (dist, bit_no) = self.readCount(inn, bit_no, len_) + dist += self.NICE_LEN - 1 + #memcpy(out + ol, out + ol - dist, dict_len); + i = 0 + while i < dict_len: + #for i in range(dict_len): + out[ol + i] = out[ol - dist + i] + i += 1 + ol += dict_len + + return ol, bit_no + + def decompress(self, inn, len_, out, len_out): + ol = 0 + bit_no = 0 + dstate = self.SHX_SET1 + is_all_upper = 0 + + len_ <<= 3 # *8, len_ in bits + out[ol] = 0 + while bit_no < len_: + c = 0 + is_upper = is_all_upper + (v, bit_no) = self.getCodeIdx(self.us_vcode, inn, len_, bit_no) # read vCode + #print("bit_no {b}. v = {v}".format(b=bit_no,v=v)) + if v < 0: + break # end of stream + h = dstate # Set1 or Set2 + if v == 0: # Switch which is common to Set1 and Set2, first entry + (h, bit_no) = self.getCodeIdx(self.us_hcode, inn, len_, bit_no) # read hCode + #print("bit_no {b}. h = {h}".format(b=bit_no,h=h)) + if h < 0: + break # end of stream + if h == self.SHX_SET1: # target is Set1 + if dstate == self.SHX_SET1: # Switch from Set1 to Set1 us UpperCase + if is_all_upper: # if CapsLock, then back to LowerCase + is_upper = 0 + is_all_upper = 0 + continue + + (v, bit_no) = self.getCodeIdx(self.us_vcode, inn, len_, bit_no) # read again vCode + if v < 0: + break # end of stream + if v == 0: + (h, bit_no) = self.getCodeIdx(self.us_hcode, inn, len_, bit_no) # read second hCode + if h < 0: + break # end of stream + if h == self.SHX_SET1: # If double Switch Set1, the CapsLock + is_all_upper = 1 + continue + + is_upper = 1 # anyways, still uppercase + else: + dstate = self.SHX_SET1 # if Set was not Set1, switch to Set1 + continue + + elif h == self.SHX_SET2: # If Set2, switch dstate to Set2 + if dstate == self.SHX_SET1: + dstate = self.SHX_SET2 + continue + + if h != self.SHX_SET1: # all other Sets (why not else) + (v, bit_no) = self.getCodeIdx(self.us_vcode, inn, len_, bit_no) # we changed set, now read vCode for char + if v < 0: + break # end of stream + + if v == 0 and h == self.SHX_SET1A: + #print("v = 0, h = self.SHX_SET1A") + if is_upper: + (temp, bit_no) = self.readCount(inn, bit_no, len_) + out[ol] = 255 - temp # binary + ol += 1 + else: + (ol, bit_no) = self.decodeRepeat(inn, len_, out, ol, bit_no) # dist + continue + + if h == self.SHX_SET1 and v == 3: + # was Unicode, will do Binary instead + (temp, bit_no) = self.readCount(inn, bit_no, len_) + out[ol] = 255 - temp # binary + ol += 1 + continue + + if h < 7 and v < 11: + #print("h {h} v {v}".format(h=h,v=v)) + c = ord(self.sets[h][v]) + if ord('a') <= c <= ord('z'): + if is_upper: + c -= 32 # go to UpperCase for letters + else: # handle all other cases + if is_upper and dstate == self.SHX_SET1 and v == 1: + c = ord('\t') # If UpperCase Space, change to TAB + if h == self.SHX_SET1B: + if 8 == v: # was LF or RPT, now only LF # pylint: disable=misplaced-comparison-constant + out[ol] = ord('\n') + ol += 1 + continue + + if 9 == v: # was CRLF, now RPT # pylint: disable=misplaced-comparison-constant + (count, bit_no) = self.readCount(inn, bit_no, len_) + count += 4 + if ol + count >= len_out: + return -1 # overflow + + rpt_c = out[ol - 1] + while count: + count -= 1 + out[ol] = rpt_c + ol += 1 + continue + + if 10 == v: # pylint: disable=misplaced-comparison-constant + break # TERM, stop decoding + + out[ol] = c + ol += 1 + + if ol >= len_out: + return -1 # overflow + + return ol + + # pylint: enable=missing-function-docstring + + +if __name__ == "__main__": + # pylint: disable=line-too-long + UNISHOX = Unishox() + BYTES_ = bytearray(2048) + INN = bytearray(b'ON Switch1#State==1 DO Add1 1 ENDON ON Var1#State==0 DO ShutterStop1 ENDON ON Var1#State==1 DO ShutterClose1 ENDON ON Var1#State>=2 DO Var1 0 ENDON ON Shutter1#Close DO Var1 0 ENDON ON Switch2#State==1 DO Add2 1 ENDON ON Var2#State==0 DO ShutterStop1 ENDON ON Var2#State==1 DO ShutterOpen1 ENDON ON Var2#State>=2 DO Var2 0 ENDON ON Shutter1#Open DO Var2 0 ENDON') + LEN_ = UNISHOX.compress(INN, len(INN), BYTES_, len(BYTES_)) + print("Compressed from {fromm} to {to} ({p}%)".format(fromm=len(INN), to=LEN_, p=(100-LEN_/len(INN)*100))) + + OUT = bytearray(2048) + LEN_ = UNISHOX.decompress(BYTES_, LEN_, OUT, len(OUT)) + print(str(OUT, 'utf-8').split('\x00')[0]) diff --git a/lib/Unishox-1.0-shadinger/src/unishox.cpp b/lib/Unishox-1.0-shadinger/src/unishox.cpp new file mode 100644 index 000000000..51c9d4701 --- /dev/null +++ b/lib/Unishox-1.0-shadinger/src/unishox.cpp @@ -0,0 +1,587 @@ +/* + * Copyright (C) 2019 Siara Logics (cc) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @author Arundale R. + * + */ + +/* + * + * This is a highly modified and optimized version of Unishox + * for Tasmota, aimed at compressing `Rules` which are typically + * short strings from 50 to 500 bytes. + * + * - moved to C++ (but still C-style) + * - c_95[] and l_95[] are pre-computed + * - all arrays in PROGMEM + * - removed all Unicode specific code to get code smaller, Unicode is rare in rules and encoded as pure binary + * - removed prev_lines management to reduce code size, we don't track previous encodings + * - using C++ const instead of #define + * - reusing the Unicode market to encode pure binary, which is 3 bits instead of 9 + * - reverse binary encoding to 255-byte, favoring short encoding for values above 127, typical of Unicode + * - remove 2 bits encoding for Counts, since it could lead to a series of more than 8 consecutive 0-bits and output NULL char. + * Minimum encoding is 5 bits, which means spending 3+1=4 more bits for values in the range 0..3 + * - removed CRLF encoding and reusing entry for RPT, saving 3 bits for repeats. Note: any CR will be binary encded + * - add safeguard to the output size (len_out), note that the compress buffer needs to be 4 bytes larger than actual compressed output. + * This is needed to avoid crash, since output can have ~30 bits + * - combined c_95[] and l_95[] to a single array to save space + * - Changed mapping of some characters in Set3, Set4 and Set4A, favoring frequent characters in rules and javascript + * - Added escape mechanism to ensure we never output NULL char. The marker is 0x2A which looked rare in preliminary tests + * + * @author Stephan Hadinger + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include "unishox.h" + +typedef unsigned char byte; +// we squeeze both c_95[] and l_95[] in a sinle array. +// c_95[] uses only the 3 upper nibbles (or 12 most signifcant bits), while the last nibble encodes length (3..13) +// static uint16_t cl_95[95] PROGMEM = {0x4000 + 3, 0x3F80 + 11, 0x3D80 + 11, 0x3C80 + 10, 0x3BE0 + 12, 0x3E80 + 10, 0x3F40 + 11, 0x3EC0 + 10, 0x3BA0 + 11, 0x3BC0 + 11, 0x3D60 + 11, 0x3B60 + 11, 0x3A80 + 10, 0x3AC0 + 10, 0x3A00 + 9, 0x3B00 + 10, 0x38C0 + 10, 0x3900 + 10, 0x3940 + 11, 0x3960 + 11, 0x3980 + 11, 0x39A0 + 11, 0x39C0 + 11, 0x39E0 + 12, 0x39F0 + 12, 0x3880 + 10, 0x3CC0 + 10, 0x3C00 + 9, 0x3D00 + 10, 0x3E00 + 9, 0x3F00 + 10, 0x3B40 + 11, 0x3BF0 + 12, 0x2B00 + 8, 0x21C0 + 11, 0x20C0 + 10, 0x2100 + 10, 0x2600 + 7, 0x2300 + 11, 0x21E0 + 12, 0x2140 + 11, 0x2D00 + 8, 0x2358 + 13, 0x2340 + 12, 0x2080 + 10, 0x21A0 + 11, 0x2E00 + 8, 0x2C00 + 8, 0x2180 + 11, 0x2350 + 13, 0x2F80 + 9, 0x2F00 + 9, 0x2A00 + 8, 0x2160 + 11, 0x2330 + 12, 0x21F0 + 12, 0x2360 + 13, 0x2320 + 12, 0x2368 + 13, 0x3DE0 + 12, 0x3FA0 + 11, 0x3DF0 + 12, 0x3D40 + 11, 0x3F60 + 11, 0x3FF0 + 12, 0xB000 + 4, 0x1C00 + 7, 0x0C00 + 6, 0x1000 + 6, 0x6000 + 3, 0x3000 + 7, 0x1E00 + 8, 0x1400 + 7, 0xD000 + 4, 0x3580 + 9, 0x3400 + 8, 0x0800 + 6, 0x1A00 + 7, 0xE000 + 4, 0xC000 + 4, 0x1800 + 7, 0x3500 + 9, 0xF800 + 5, 0xF000 + 5, 0xA000 + 4, 0x1600 + 7, 0x3300 + 8, 0x1F00 + 8, 0x3600 + 9, 0x3200 + 8, 0x3680 + 9, 0x3DA0 + 11, 0x3FC0 + 11, 0x3DC0 + 11, 0x3FE0 + 12 }; +// Patched, for len == 13, shift 1 bit right +static uint16_t cl_95[95] PROGMEM = {0x4000 + 3, 0x3F80 + 11, 0x3D80 + 11, 0x3C80 + 10, 0x3BE0 + 12, 0x3E80 + 10, 0x3F40 + 11, 0x3EC0 + 10, 0x3BA0 + 11, 0x3BC0 + 11, 0x3D60 + 11, 0x3B60 + 11, 0x3A80 + 10, 0x3AC0 + 10, 0x3A00 + 9, 0x3B00 + 10, 0x38C0 + 10, 0x3900 + 10, 0x3940 + 11, 0x3960 + 11, 0x3980 + 11, 0x39A0 + 11, 0x39C0 + 11, 0x39E0 + 12, 0x39F0 + 12, 0x3880 + 10, 0x3CC0 + 10, 0x3C00 + 9, 0x3D00 + 10, 0x3E00 + 9, 0x3F00 + 10, 0x3B40 + 11, 0x3BF0 + 12, 0x2B00 + 8, 0x21C0 + 11, 0x20C0 + 10, 0x2100 + 10, 0x2600 + 7, 0x2300 + 11, 0x21E0 + 12, 0x2140 + 11, 0x2D00 + 8, 0x46B0 + 13, 0x2340 + 12, 0x2080 + 10, 0x21A0 + 11, 0x2E00 + 8, 0x2C00 + 8, 0x2180 + 11, 0x46A0 + 13, 0x2F80 + 9, 0x2F00 + 9, 0x2A00 + 8, 0x2160 + 11, 0x2330 + 12, 0x21F0 + 12, 0x46C0 + 13, 0x2320 + 12, 0x46D0 + 13, 0x3DE0 + 12, 0x3FA0 + 11, 0x3DF0 + 12, 0x3D40 + 11, 0x3F60 + 11, 0x3FF0 + 12, 0xB000 + 4, 0x1C00 + 7, 0x0C00 + 6, 0x1000 + 6, 0x6000 + 3, 0x3000 + 7, 0x1E00 + 8, 0x1400 + 7, 0xD000 + 4, 0x3580 + 9, 0x3400 + 8, 0x0800 + 6, 0x1A00 + 7, 0xE000 + 4, 0xC000 + 4, 0x1800 + 7, 0x3500 + 9, 0xF800 + 5, 0xF000 + 5, 0xA000 + 4, 0x1600 + 7, 0x3300 + 8, 0x1F00 + 8, 0x3600 + 9, 0x3200 + 8, 0x3680 + 9, 0x3DA0 + 11, 0x3FC0 + 11, 0x3DC0 + 11, 0x3FE0 + 12 }; +// Original version with c/l separate +// uint16_t c_95[95] PROGMEM = {0x4000, 0x3F80, 0x3D80, 0x3C80, 0x3BE0, 0x3E80, 0x3F40, 0x3EC0, 0x3BA0, 0x3BC0, 0x3D60, 0x3B60, 0x3A80, 0x3AC0, 0x3A00, 0x3B00, 0x38C0, 0x3900, 0x3940, 0x3960, 0x3980, 0x39A0, 0x39C0, 0x39E0, 0x39F0, 0x3880, 0x3CC0, 0x3C00, 0x3D00, 0x3E00, 0x3F00, 0x3B40, 0x3BF0, 0x2B00, 0x21C0, 0x20C0, 0x2100, 0x2600, 0x2300, 0x21E0, 0x2140, 0x2D00, 0x2358, 0x2340, 0x2080, 0x21A0, 0x2E00, 0x2C00, 0x2180, 0x2350, 0x2F80, 0x2F00, 0x2A00, 0x2160, 0x2330, 0x21F0, 0x2360, 0x2320, 0x2368, 0x3DE0, 0x3FA0, 0x3DF0, 0x3D40, 0x3F60, 0x3FF0, 0xB000, 0x1C00, 0x0C00, 0x1000, 0x6000, 0x3000, 0x1E00, 0x1400, 0xD000, 0x3580, 0x3400, 0x0800, 0x1A00, 0xE000, 0xC000, 0x1800, 0x3500, 0xF800, 0xF000, 0xA000, 0x1600, 0x3300, 0x1F00, 0x3600, 0x3200, 0x3680, 0x3DA0, 0x3FC0, 0x3DC0, 0x3FE0 }; +// uint8_t l_95[95] PROGMEM = { 3, 11, 11, 10, 12, 10, 11, 10, 11, 11, 11, 11, 10, 10, 9, 10, 10, 10, 11, 11, 11, 11, 11, 12, 12, 10, 10, 9, 10, 9, 10, 11, 12, 8, 11, 10, 10, 7, 11, 12, 11, 8, 13, 12, 10, 11, 8, 8, 11, 13, 9, 9, 8, 11, 12, 12, 13, 12, 13, 12, 11, 12, 11, 11, 12, 4, 7, 6, 6, 3, 7, 8, 7, 4, 9, 8, 6, 7, 4, 4, 7, 9, 5, 5, 4, 7, 8, 8, 9, 8, 9, 11, 11, 11, 12 }; + +enum {SHX_STATE_1 = 1, SHX_STATE_2}; // removed Unicode state + +enum {SHX_SET1 = 0, SHX_SET1A, SHX_SET1B, SHX_SET2, SHX_SET3, SHX_SET4, SHX_SET4A}; +// changed mapping in Set3, Set4, Set4A to accomodate frequencies in Rules and Javascript +static char sets[][11] PROGMEM = + {{ 0, ' ', 'e', 0, 't', 'a', 'o', 'i', 'n', 's', 'r'}, + { 0, 'l', 'c', 'd', 'h', 'u', 'p', 'm', 'b', 'g', 'w'}, + {'f', 'y', 'v', 'k', 'q', 'j', 'x', 'z', 0, 0, 0}, + { 0, '9', '0', '1', '2', '3', '4', '5', '6', '7', '8'}, + {'.', ',', '-', '/', '?', '+', ' ', '(', ')', '$', '@'}, + {';', '#', ':', '<', '^', '*', '"', '{', '}', '[', ']'}, + {'=', '%', '\'', '>', '&', '_', '!', '\\', '|', '~', '`'}}; + // {{ 0, ' ', 'e', 0, 't', 'a', 'o', 'i', 'n', 's', 'r'}, + // { 0, 'l', 'c', 'd', 'h', 'u', 'p', 'm', 'b', 'g', 'w'}, + // {'f', 'y', 'v', 'k', 'q', 'j', 'x', 'z', 0, 0, 0}, + // { 0, '9', '0', '1', '2', '3', '4', '5', '6', '7', '8'}, + // {'.', ',', '-', '/', '=', '+', ' ', '(', ')', '$', '%'}, + // {'&', ';', ':', '<', '>', '*', '"', '{', '}', '[', ']'}, + // {'@', '?', '\'', '^', '#', '_', '!', '\\', '|', '~', '`'}}; + +// Decoder is designed for using less memory, not speed +// Decode lookup table for code index and length +// First 2 bits 00, Next 3 bits indicate index of code from 0, +// last 3 bits indicate code length in bits +// 0, 1, 2, 3, 4, +static char us_vcode[32] PROGMEM = + {2 + (0 << 3), 3 + (3 << 3), 3 + (1 << 3), 4 + (6 << 3), 0, +// 5, 6, 7, 8, 9, 10 + 4 + (4 << 3), 3 + (2 << 3), 4 + (8 << 3), 0, 0, 0, +// 11, 12, 13, 14, 15 + 4 + (7 << 3), 0, 4 + (5 << 3), 0, 5 + (9 << 3), +// 16, 17, 18, 19, 20, 21, 22, 23 + 0, 0, 0, 0, 0, 0, 0, 0, +// 24, 25, 26, 27, 28, 29, 30, 31 + 0, 0, 0, 0, 0, 0, 0, 5 + (10 << 3)}; +// 0, 1, 2, 3, 4, 5, 6, 7, +static char us_hcode[32] PROGMEM = + {1 + (1 << 3), 2 + (0 << 3), 0, 3 + (2 << 3), 0, 0, 0, 5 + (3 << 3), +// 8, 9, 10, 11, 12, 13, 14, 15, + 0, 0, 0, 0, 0, 0, 0, 5 + (5 << 3), +// 16, 17, 18, 19, 20, 21, 22, 23 + 0, 0, 0, 0, 0, 0, 0, 5 + (4 << 3), +// 24, 25, 26, 27, 28, 29, 30, 31 + 0, 0, 0, 0, 0, 0, 0, 5 + (6 << 3)}; + +static const char ESCAPE_MARKER = 0x2A; // Escape any null char + +static const uint16_t TERM_CODE = 0x37C0; // 0b0011011111000000 +static const uint16_t TERM_CODE_LEN = 10; +static const uint16_t DICT_CODE = 0x0000; +static const uint16_t DICT_CODE_LEN = 5; +static const uint16_t DICT_OTHER_CODE = 0x0000; // not used +static const uint16_t DICT_OTHER_CODE_LEN = 6; +// const uint16_t RPT_CODE = 0x2370; +// const uint16_t RPT_CODE_LEN = 13; +static const uint16_t RPT_CODE_TASMOTA = 0x3780; +static const uint16_t RPT_CODE_TASMOTA_LEN = 10; +static const uint16_t BACK2_STATE1_CODE = 0x2000; // 0010 = back to lower case +static const uint16_t BACK2_STATE1_CODE_LEN = 4; +static const uint16_t BACK_FROM_UNI_CODE = 0xFE00; +static const uint16_t BACK_FROM_UNI_CODE_LEN = 8; +// const uint16_t CRLF_CODE = 0x3780; +// const uint16_t CRLF_CODE_LEN = 10; +static const uint16_t LF_CODE = 0x3700; +static const uint16_t LF_CODE_LEN = 9; +static const uint16_t TAB_CODE = 0x2400; +static const uint16_t TAB_CODE_LEN = 7; +// const uint16_t UNI_CODE = 0x8000; // Unicode disabled +// const uint16_t UNI_CODE_LEN = 3; +// const uint16_t UNI_STATE_SPL_CODE = 0xF800; +// const uint16_t UNI_STATE_SPL_CODE_LEN = 5; +// const uint16_t UNI_STATE_DICT_CODE = 0xFC00; +// const uint16_t UNI_STATE_DICT_CODE_LEN = 7; +// const uint16_t CONT_UNI_CODE = 0x2800; +// const uint16_t CONT_UNI_CODE_LEN = 7; +static const uint16_t ALL_UPPER_CODE = 0x2200; +static const uint16_t ALL_UPPER_CODE_LEN = 8; +static const uint16_t SW2_STATE2_CODE = 0x3800; +static const uint16_t SW2_STATE2_CODE_LEN = 7; +static const uint16_t ST2_SPC_CODE = 0x3B80; +static const uint16_t ST2_SPC_CODE_LEN = 11; +static const uint16_t BIN_CODE_TASMOTA = 0x8000; +static const uint16_t BIN_CODE_TASMOTA_LEN = 3; +// const uint16_t BIN_CODE = 0x2000; +// const uint16_t BIN_CODE_LEN = 9; + +#define NICE_LEN 5 + +// uint16_t mask[] PROGMEM = {0x8000, 0xC000, 0xE000, 0xF000, 0xF800, 0xFC00, 0xFE00, 0xFF00}; +static const uint8_t mask[] PROGMEM = {0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFF}; + + + +void Unishox::append_bits(unsigned int code, int clen) { +// Serial.printf("append_bits code = 0x%08X, clen %d\n", code, clen); + byte cur_bit; + byte blen; + unsigned char a_byte; + + if (state == SHX_STATE_2) { + // remove change state prefix + if ((code >> 9) == 0x1C) { + code <<= 7; + clen -= 7; + } + } + while (clen > 0) { + cur_bit = ol % 8; + blen = (clen > 8 ? 8 : clen); + a_byte = (code >> 8) & pgm_read_word(&mask[blen - 1]); + a_byte >>= cur_bit; + if (blen + cur_bit > 8) + blen = (8 - cur_bit); + if (out) { // if out == nullptr, then we are in dry-run mode + if (cur_bit == 0) + out[ol >> 3] = a_byte; + else + out[ol >> 3] |= a_byte; + } + code <<= blen; + ol += blen; + if ((out) && (0 == ol % 8)) { // if out == nullptr, dry-run mode. We miss the escaping of characters in the length + // we completed a full byte + char last_c = out[(ol / 8) - 1]; + if ((0 == last_c) || (ESCAPE_MARKER == last_c)) { + out[ol >> 3] = 1 + last_c; // increment to 0x01 or 0x2B + out[(ol >>3) -1] = ESCAPE_MARKER; // replace old value with marker + ol += 8; // add one full byte + } + } + clen -= blen; + } +} + +// First five bits are code and Last three bits of codes represent length +// removing last 2 bytes, unused, we will never have values above 600 bytes +// const byte codes[7] = {0x01, 0x82, 0xC3, 0xE5, 0xED, 0xF5, 0xFD}; +// const byte bit_len[7] = {2, 5, 7, 9, 12, 16, 17}; +// const uint16_t adder[7] = {0, 4, 36, 164, 676, 4772, 0}; +byte codes[] PROGMEM = { 0x82, 0xC3, 0xE5, 0xED, 0xF5 }; +byte bit_len[] PROGMEM = { 5, 7, 9, 12, 16 }; +// uint16_t adder[7] PROGMEM = { 0, 32, 160, 672, 4768 }; // no more used + +void Unishox::encodeCount(int32_t count) { + int till = 0; + int base = 0; + for (uint32_t i = 0; i < sizeof(bit_len); i++) { + uint32_t bit_len_i = pgm_read_byte(&bit_len[i]); + till += (1 << bit_len_i); + if (count < till) { + byte codes_i = pgm_read_byte(&codes[i]); + append_bits((codes_i & 0xF8) << 8, codes_i & 0x07); + // ol = append_bits(out, ol, (count - pgm_read_word(&adder[i])) << (16 - bit_len_i), bit_len_i, 1); + append_bits((count - base) << (16 - bit_len_i), bit_len_i); + return; + } + base = till; + } + return; +} + +bool Unishox::matchOccurance(void) { + int32_t j, k; + uint32_t longest_dist = 0; + uint32_t longest_len = 0; + for (j = l - NICE_LEN; j >= 0; j--) { + for (k = l; k < len && j + k - l < l; k++) { + if (in[k] != in[j + k - l]) + break; + } + if (k - l > NICE_LEN - 1) { + uint32_t match_len = k - l - NICE_LEN; + uint32_t match_dist = l - j - NICE_LEN + 1; + if (match_len > longest_len) { + longest_len = match_len; + longest_dist = match_dist; + } + } + } + if (longest_len) { + if (state == SHX_STATE_2 || is_all_upper) { + is_all_upper = 0; + state = SHX_STATE_1; + append_bits(BACK2_STATE1_CODE, BACK2_STATE1_CODE_LEN); + } + append_bits(DICT_CODE, DICT_CODE_LEN); + encodeCount(longest_len); + encodeCount(longest_dist); + l += longest_len + NICE_LEN - 1; + return true; + } + return false; +} + +// Compress a buffer. +// Inputs: +// - in: non-null pointer to a buffer of bytes to be compressed. Progmem is not valid. Null bytes are valid. +// - len: size of the input buffer. 0 is valid for empty buffer +// - out: pointer to output buffer. out is nullptr, the compressor does a dry-run and reports the compressed size without writing bytes +// - len_out: length in bytes of the output buffer. +// Output: +// - if >= 0: size of the compressed buffer. The output buffer does not contain NULL bytes, and it is not NULL terminated +// - if < 0: an error occured, most certainly the output buffer was not large enough +int32_t Unishox::unishox_compress(const char *p_in, size_t p_len, char *p_out, size_t p_len_out) { + in = p_in; + len = p_len; + out = p_out; + len_out = p_len_out; + + char *ptr; + byte bits; + + int ll; + char c_in, c_next; + byte is_upper; + + ol = 0; + state = SHX_STATE_1; + is_all_upper = 0; + for (l=0; l= ' ' && c_in <= '@') || + (c_in >= '[' && c_in <= '`') || + (c_in >= '{' && c_in <= '~')) { + } else { + state = SHX_STATE_1; // back to Set1 and lower case + append_bits(BACK2_STATE1_CODE, BACK2_STATE1_CODE_LEN); + } + } + + is_upper = 0; + if (c_in >= 'A' && c_in <= 'Z') + is_upper = 1; + else { + if (is_all_upper) { + is_all_upper = 0; + append_bits(BACK2_STATE1_CODE, BACK2_STATE1_CODE_LEN); + } + } + + c_next = 0; + if (l+1 < len) + c_next = in[l+1]; + + if (c_in >= 32 && c_in <= 126) { + if (is_upper && !is_all_upper) { + for (ll=l+5; ll>=l && ll 'Z') + break; + } + if (ll == l-1) { + append_bits(ALL_UPPER_CODE, ALL_UPPER_CODE_LEN); // CapsLock + is_all_upper = 1; + } + } + if (state == SHX_STATE_1 && c_in >= '0' && c_in <= '9') { + append_bits(SW2_STATE2_CODE, SW2_STATE2_CODE_LEN); // Switch to sticky Set2 + state = SHX_STATE_2; + } + c_in -= 32; + if (is_all_upper && is_upper) + c_in += 32; + if (c_in == 0 && state == SHX_STATE_2) + append_bits(ST2_SPC_CODE, ST2_SPC_CODE_LEN); // space from Set2 ionstead of Set1 + else { +// Serial.printf("Encode %c %d\n", c_in + 32, c_in); + uint16_t cl = pgm_read_word(&cl_95[c_in]); + uint16_t cl_code = cl & 0xFFF0; + uint8_t cl_len = cl & 0x000F; + if (13 == cl_len) { + cl_code >>= 1; + } + append_bits(cl_code, cl_len); + } + } else if (c_in == 10) { + append_bits(LF_CODE, LF_CODE_LEN); // LF + } else if (c_in == '\t') { + append_bits(TAB_CODE, TAB_CODE_LEN); // TAB + } else { + append_bits(BIN_CODE_TASMOTA, BIN_CODE_TASMOTA_LEN); // Binary, we reuse the Unicode marker which 3 bits instead of 9 + encodeCount((unsigned char) 255 - c_in); + } + + // check that we have some headroom in the output buffer + if (ol / 8 >= len_out - 4) { + return -1; // we risk overflow and crash + } + } + + bits = ol % 8; + if (bits) { + state = SHX_STATE_1; + append_bits(TERM_CODE, 8 - bits); // 0011 0111 1100 0000 TERM = 0011 0111 11 + } + return ol / 8; // we already arrived to a byte boundary + // return ol/8+(ol%8?1:0); +} + +uint32_t Unishox::getNextBit(void) { + if (8 == bit_no) { + if (byte_no >= len) { + in_eof = true; + return 1; // return only 1s, which appends 'r' in worst case + } + byte_in = pgm_read_byte(&in[byte_no++]); + if (ESCAPE_MARKER == byte_in) { + byte_in = pgm_read_byte(&in[byte_no++]) - 1; // we shouldn't need to test if byte_no >= len, because it should not be possible to end with ESCAPE_MARKER + } + bit_no = 0; + } + // Serial.printf("getNextBit %d\n", byte_in & (0x80 >> bit_no) ? 1 : 0); + return byte_in & (0x80 >> bit_no++) ? 1 : 0; +} + +// Returns: +// 0..11 +// or -1 if end of stream +int32_t Unishox::getCodeIdx(const char *code_type) { + int32_t code = 0; + int32_t count = 0; + do { + if (in_eof) return -1; // invalid state + code += getNextBit() << count; + count++; + uint8_t code_type_code = pgm_read_byte(&code_type[code]); + if (code_type_code && (code_type_code & 0x07) == count) { + return code_type_code >> 3; + } + } while (count < 5); + return -1; // skip if code not found +} + +int32_t Unishox::getNumFromBits(uint32_t count) { + int ret = 0; + while (count--) { + ret += getNextBit() << count; + } + if (in_eof) return 0; + return ret; +} + +// const byte bit_len[7] = {5, 2, 7, 9, 12, 16, 17}; +// const uint16_t adder[7] = {4, 0, 36, 164, 676, 4772, 0}; + +// byte bit_len[7] PROGMEM = { 5, 7, 9, 12, 16 }; +// byte bit_len_read[7] PROGMEM = {5, 2, 7, 9, 12, 16 }; +// uint16_t adder_read[7] PROGMEM = {4, 0, 36, 164, 676, 4772, 0}; +// uint16_t adder_read[] PROGMEM = {0, 0, 32, 160, 672, 4768 }; + +// byte bit_len[7] PROGMEM = { 5, 7, 9, 12, 16 }; +// uint16_t adder_read[] PROGMEM = {0, 32, 160, 672, 4768 }; + +// Code size optimized, recalculate adder[] like in encodeCount +uint32_t Unishox::readCount(void) { + int32_t idx = getCodeIdx(us_hcode); + if ((1 == idx) || (idx >= sizeof(bit_len)) || (idx < 0)) return 0; // unsupported or end of stream + if (idx >= 1) idx--; // we skip v = 1 (code '0') since we no more accept 2 bits encoding + + int base; + int till = 0; + byte bit_len_idx; // bit_len[0] + for (uint32_t i = 0; i <= idx; i++) { + base = till; + bit_len_idx = pgm_read_byte(&bit_len[i]); + till += (1 << bit_len_idx); + } + int count = getNumFromBits(bit_len_idx) + base; + + return count; +} + +void Unishox::decodeRepeat(void) { + uint32_t dict_len = readCount() + NICE_LEN; + uint32_t dist = readCount() + NICE_LEN - 1; + if (ol + dict_len <= len_out) { + memcpy(out + ol, out + ol - dist, dict_len); + ol += dict_len; +} +} + +int32_t Unishox::unishox_decompress(const char *p_in, size_t p_len, char *p_out, size_t p_len_out) { + in = p_in; + len = p_len; + out = p_out; + len_out = p_len_out; + + in_eof = false; + ol = 0; + bit_no = 8; // force load of first byte, pretending we expired the last one + byte_no = 0; + dstate = SHX_SET1; + is_all_upper = 0; + + out[ol] = 0; + // while ((byte_no << 3) + bit_no - 8 < len) { + while (!in_eof) { + if (ol >= len_out) { + break; + } + int32_t h, v; + char c = 0; + byte is_upper = is_all_upper; + v = getCodeIdx(us_vcode); // read vCode + if (v < 0) break; // end of stream + h = dstate; // Set1 or Set2 + if (v == 0) { // Switch which is common to Set1 and Set2, first entry + h = getCodeIdx(us_hcode); // read hCode + if (h < 0) break; // end of stream + if (h == SHX_SET1) { // target is Set1 + if (dstate == SHX_SET1) { // Switch from Set1 to Set1 us UpperCase + if (is_all_upper) { // if CapsLock, then back to LowerCase + is_upper = is_all_upper = 0; + continue; + } + v = getCodeIdx(us_vcode); // read again vCode + if (v < 0) break; // end of stream + if (v == 0) { + h = getCodeIdx(us_hcode); // read second hCode + if (h < 0) break; // end of stream + if (h == SHX_SET1) { // If double Switch Set1, the CapsLock + is_all_upper = 1; + continue; + } + } + is_upper = 1; // anyways, still uppercase + } else { + dstate = SHX_SET1; // if Set was not Set1, switch to Set1 + continue; + } + } else + if (h == SHX_SET2) { // If Set2, switch dstate to Set2 + if (dstate == SHX_SET1) // TODO: is this test useful, there are only 2 states possible + dstate = SHX_SET2; + continue; + } + if (h != SHX_SET1) { // all other Sets (why not else) + v = getCodeIdx(us_vcode); // we changed set, now read vCode for char + if (v < 0) break; // end of stream + } + } + + if (v == 0 && h == SHX_SET1A) { + if (is_upper) { + out[ol++] = 255 - readCount(); // binary + } else { + decodeRepeat(); // dist + } + continue; + } + + if (h == SHX_SET1 && v == 3) { + // was Unicode, will do Binary instead + out[ol++] = 255 - readCount(); // binary + continue; + } + if (h < 7 && v < 11) // TODO: are these the actual limits? Not 11x7 ? + c = pgm_read_byte(&sets[h][v]); + if (c >= 'a' && c <= 'z') { + if (is_upper) + c -= 32; // go to UpperCase for letters + } else { // handle all other cases + if (is_upper && dstate == SHX_SET1 && v == 1) + c = '\t'; // If UpperCase Space, change to TAB + if (h == SHX_SET1B) { + if (8 == v) { // was LF or RPT, now only LF + out[ol++] = '\n'; + continue; + } + if (9 == v) { // was CRLF, now RPT + uint32_t count = readCount() + 4; + if (ol + count >= len_out) { + return -1; // overflow + } + char rpt_c = out[ol - 1]; + while (count--) + out[ol++] = rpt_c; + continue; + } + if (10 == v) { + break; // TERM, stop decoding + } + } + } + // Serial.printf(">>>>>>>>>>>>>>>>>>>>>> Out = %c\n", c); + out[ol++] = c; + } + + if (ol > len_out) { + return -1; // overflow + } else { + return ol; + } +} diff --git a/lib/Unishox-1.0-shadinger/src/unishox.h b/lib/Unishox-1.0-shadinger/src/unishox.h new file mode 100644 index 000000000..6388be4cf --- /dev/null +++ b/lib/Unishox-1.0-shadinger/src/unishox.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2019 Siara Logics (cc) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @author Arundale R. + * + */ +#ifndef unishox +#define unishox + +class Unishox { + +public: + Unishox() {}; + + int32_t unishox_decompress(const char *in, size_t len, char *out, size_t len_out); + int32_t unishox_compress(const char *in, size_t len, char *out, size_t len_out); + +private: + + void append_bits(unsigned int code, int clen); + void encodeCount(int32_t count); + bool matchOccurance(void); + + uint32_t getNextBit(void); + int32_t getCodeIdx(const char *code_type); + uint32_t readCount(void); + void decodeRepeat(void); + int32_t getNumFromBits(uint32_t count); + + inline void writeOut(char c) { out[ol++] = c; } + + int32_t l; + uint32_t ol; + int32_t bit_no; + uint32_t byte_no; + bool in_eof; // have we reached end of file for compressed input + const char * in; + char * out; + size_t len; + size_t len_out; + + uint8_t dstate; + unsigned char byte_in; + uint8_t state; + uint8_t is_all_upper; + +}; + +#endif + diff --git a/lib/Xlatb_RA8876-gemu-1.0/RA8876.cpp b/lib/Xlatb_RA8876-gemu-1.0/RA8876.cpp index a3c73f3fb..1d9a893e4 100644 --- a/lib/Xlatb_RA8876-gemu-1.0/RA8876.cpp +++ b/lib/Xlatb_RA8876-gemu-1.0/RA8876.cpp @@ -66,8 +66,13 @@ RA8876::RA8876(int8_t cs,int8_t mosi,int8_t miso,int8_t sclk,int8_t bp) : Render //#define RA8876_CS_LOW digitalWrite(m_csPin, LOW) //#define RA8876_CS_HIGH digitalWrite(m_csPin, HIGH) +#ifndef ESP32 #define RA8876_CS_LOW GPOC=(1<= 0x21) || (c <= 0x7F))) diff --git a/lib/Xlatb_RA8876-gemu-1.0/RA8876.h b/lib/Xlatb_RA8876-gemu-1.0/RA8876.h index b27698027..5bf8b404f 100644 --- a/lib/Xlatb_RA8876-gemu-1.0/RA8876.h +++ b/lib/Xlatb_RA8876-gemu-1.0/RA8876.h @@ -23,6 +23,7 @@ #include #include +#undef SPRINT #define SPRINT(A) {char str[32];sprintf(str,"val: %d ",A);Serial.println((char*)str);} diff --git a/lib/bearssl-esp8266/src/pgmspace_bearssl.h b/lib/bearssl-esp8266/src/pgmspace_bearssl.h index 5a42114f5..e616ffe2e 100644 --- a/lib/bearssl-esp8266/src/pgmspace_bearssl.h +++ b/lib/bearssl-esp8266/src/pgmspace_bearssl.h @@ -50,7 +50,7 @@ extern "C" { // w1, w0 #define pgm_read_with_offset(addr, res) \ - asm("extui %0, %1, 0, 2\n" /* Extract offset within word (in bytes) */ \ + __asm__ ("extui %0, %1, 0, 2\n" /* Extract offset within word (in bytes) */ \ "sub %1, %1, %0\n" /* Subtract offset from addr, yielding an aligned address */ \ "l32i.n %1, %1, 0x0\n" /* Load word from aligned address */ \ "slli %0, %0, 3\n" /* Mulitiply offset by 8, yielding an offset in bits */ \ diff --git a/lib/bearssl-esp8266/src/t_inner.h b/lib/bearssl-esp8266/src/t_inner.h index a7267f0df..8dca0c09b 100644 --- a/lib/bearssl-esp8266/src/t_inner.h +++ b/lib/bearssl-esp8266/src/t_inner.h @@ -2584,6 +2584,9 @@ br_cpuid(uint32_t mask_eax, uint32_t mask_ebx, #define optimistic_yield(ignored) #endif +#ifdef ESP32 +#define memcpy_P memcpy +#endif /* ==================================================================== */ diff --git a/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd2in9.cpp b/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd2in9.cpp index 686b0391e..90e257483 100644 --- a/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd2in9.cpp +++ b/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd2in9.cpp @@ -364,8 +364,12 @@ const unsigned char lut_partial_update[] = #define PIN_OUT_SET 0x60000304 #define PIN_OUT_CLEAR 0x60000308 -#define PWRITE xdigitalWrite - +#ifdef ESP32 +#define SSPI_USEANYPIN 1 +#define PWRITE digitalWrite +#else +#define PWRITE ydigitalWrite +#endif #ifndef SSPI_USEANYPIN // uses about 2.75 usecs, 365 kb /sec @@ -388,6 +392,7 @@ void ICACHE_RAM_ATTR Epd::fastSPIwrite(uint8_t d,uint8_t dc) { } #else +#ifndef ESP32 extern void ICACHE_RAM_ATTR xdigitalWrite(uint8_t pin, uint8_t val) { //stopWaveform(pin); if(pin < 16){ @@ -398,6 +403,7 @@ extern void ICACHE_RAM_ATTR xdigitalWrite(uint8_t pin, uint8_t val) { else GP16O &= ~1; } } +#endif // about 13 us => 76 kb / sec // can use any pin diff --git a/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd2in9.h b/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd2in9.h index 99459b198..3fc8ea190 100644 --- a/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd2in9.h +++ b/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd2in9.h @@ -68,8 +68,8 @@ public: int16_t width; int16_t height; - Epd(); - ~Epd(); +// Epd(); +// ~Epd(); int Init(const unsigned char* lut); void Init(int8_t p); void SendCommand(unsigned char command); diff --git a/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd4in2.cpp b/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd4in2.cpp old mode 100755 new mode 100644 index 8c8d037c5..8450a9647 --- a/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd4in2.cpp +++ b/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd4in2.cpp @@ -1,566 +1,571 @@ -/** - * @filename : epd4in2.cpp - * @brief : Implements for Dual-color e-paper library - * @author : Yehui from Waveshare - * - * Copyright (C) Waveshare August 10 2017 - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documnetation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include -#include - - -//#define SSPI_USEANYPIN - -extern uint8_t *buffer; -uint8_t epd42_mode; - -Epd42::Epd42(int16_t width, int16_t height) : -Paint(width,height) { -} - -void Epd42::DisplayOnff(int8_t on) { -} - - -#define DISPLAY_INIT_MODE 0 -#define DISPLAY_INIT_PARTIAL 1 -#define DISPLAY_INIT_FULL 2 - -void Epd42::Updateframe() { - //SetFrameMemory(buffer, 0, 0, EPD_WIDTH,EPD_HEIGHT); - SetPartialWindow(buffer, 0, 0, width,height,2); - if (epd42_mode==DISPLAY_INIT_PARTIAL) { - DisplayFrameQuick(); - } else { - DisplayFrame(); - } - //Serial.printf("update\n"); -} - -void Epd42::DisplayInit(int8_t p,int8_t size,int8_t rot,int8_t font) { -// ignore update mode - if (p==DISPLAY_INIT_PARTIAL) { - epd42_mode=p; - //Init(lut_partial_update); - //ClearFrameMemory(0xFF); // bit set = white, bit reset = black - DisplayFrameQuick(); - delay(500); - return; - //Serial.printf("partial\n"); - } else if (p==DISPLAY_INIT_FULL) { - epd42_mode=p; - //Init(lut_full_update); - //ClearFrameMemory(0xFF); // bit set = white, bit reset = black - DisplayFrame(); - delay(4500); - return; - //Serial.printf("full\n"); - } else { - epd42_mode=DISPLAY_INIT_FULL; - Updateframe(); - } - - setRotation(rot); - invertDisplay(false); - setTextWrap(false); // Allow text to run off edges - cp437(true); - setTextFont(font); - setTextSize(size); - setTextColor(WHITE,BLACK); - setCursor(0,0); - fillScreen(BLACK); -} - -int16_t Epd42::Begin(int16_t cs,int16_t mosi,int16_t sclk) { - cs_pin=cs; - mosi_pin=mosi; - sclk_pin=sclk; -} - -void Epd42::Init(int8_t p) { - epd42_mode=p; - DisplayFrame(); - delay(4000); -} - -int Epd42::Init(void) { - pinMode(cs_pin, OUTPUT); - pinMode(mosi_pin, OUTPUT); - pinMode(sclk_pin, OUTPUT); - - digitalWrite(cs_pin,HIGH); - digitalWrite(mosi_pin,LOW); - digitalWrite(sclk_pin,LOW); - - width = EPD_WIDTH42; - height = EPD_HEIGHT42; - - Reset(); - SendCommand(POWER_SETTING); - SendData(0x03); // VDS_EN, VDG_EN - SendData(0x00); // VCOM_HV, VGHL_LV[1], VGHL_LV[0] - SendData(0x2b); // VDH - SendData(0x2b); // VDL - SendData(0xff); // VDHR - SendCommand(BOOSTER_SOFT_START); - SendData(0x17); - SendData(0x17); - SendData(0x17); //07 0f 17 1f 27 2F 37 2f - SendCommand(POWER_ON); - WaitUntilIdle(); - SendCommand(PANEL_SETTING); - // SendData(0xbf); // KW-BF KWR-AF BWROTP 0f - // SendData(0x0b); -// SendData(0x0F); //300x400 Red mode, LUT from OTP -// SendData(0x1F); //300x400 B/W mode, LUT from OTP - SendData(0x3F); //300x400 B/W mode, LUT set by register -// SendData(0x2F); //300x400 Red mode, LUT set by register - - SendCommand(PLL_CONTROL); - SendData(0x3C); // 3A 100Hz 29 150Hz 39 200Hz 31 171Hz 3C 50Hz (default) 0B 10Hz - //SendData(0x0B); //0B is 10Hz - /* EPD hardware init end */ - return 0; -} - -/** - * @brief: basic function for sending commands - */ -void Epd42::SendCommand(unsigned char command) { - //DigitalWrite(dc_pin, LOW); - //SpiTransfer(command); - fastSPIwrite(command,0); -} - -/** - * @brief: basic function for sending data - */ -void Epd42::SendData(unsigned char data) { - //DigitalWrite(dc_pin, HIGH); - //SpiTransfer(data); - fastSPIwrite(data,1); -} - -/** - * @brief: Wait until the busy_pin goes HIGH - */ -void Epd42::WaitUntilIdle(void) { - // while(DigitalRead(busy_pin) == 0) { //0: busy, 1: idle - // DelayMs(1); - // } -} - -/** - * @brief: module reset. - * often used to awaken the module in deep sleep, - * see Epd::Sleep(); - */ -void Epd42::Reset(void) { - //DigitalWrite(reset_pin, LOW); - //DelayMs(200); - //DigitalWrite(reset_pin, HIGH); - //DelayMs(200); -} -/** - * @brief: transmit partial data to the SRAM. The final parameter chooses between dtm=1 and dtm=2 - */ -void Epd42::SetPartialWindow(const unsigned char* buffer_black, int x, int y, int w, int l, int dtm) { - SendCommand(PARTIAL_IN); - SendCommand(PARTIAL_WINDOW); - SendData(x >> 8); - SendData(x & 0xf8); // x should be the multiple of 8, the last 3 bit will always be ignored - SendData(((x & 0xf8) + w - 1) >> 8); - SendData(((x & 0xf8) + w - 1) | 0x07); - SendData(y >> 8); - SendData(y & 0xff); - SendData((y + l - 1) >> 8); - SendData((y + l - 1) & 0xff); - SendData(0x01); // Gates scan both inside and outside of the partial window. (default) - // DelayMs(2); - SendCommand((dtm == 1) ? DATA_START_TRANSMISSION_1 : DATA_START_TRANSMISSION_2); - if (buffer_black != NULL) { - for(int i = 0; i < w / 8 * l; i++) { - SendData(buffer_black[i]^0xff); - } - } else { - for(int i = 0; i < w / 8 * l; i++) { - SendData(0x00); - } - } - // DelayMs(2); - SendCommand(PARTIAL_OUT); -} - - - -/** - * @brief: set the look-up table - */ -void Epd42::SetLut(void) { - unsigned int count; - SendCommand(LUT_FOR_VCOM); //vcom - for(count = 0; count < 44; count++) { - SendData(pgm_read_byte(&lut_vcom0[count])); - } - - SendCommand(LUT_WHITE_TO_WHITE); //ww -- - for(count = 0; count < 42; count++) { - SendData(pgm_read_byte(&lut_ww[count])); - } - - SendCommand(LUT_BLACK_TO_WHITE); //bw r - for(count = 0; count < 42; count++) { - SendData(pgm_read_byte(&lut_bw[count])); - } - - SendCommand(LUT_WHITE_TO_BLACK); //wb w - for(count = 0; count < 42; count++) { - SendData(pgm_read_byte(&lut_wb[count])); - } - - SendCommand(LUT_BLACK_TO_BLACK); //bb b - for(count = 0; count < 42; count++) { - SendData(pgm_read_byte(&lut_bb[count])); - } -} - - -/** - * @brief: set the look-up table for quick display (partial refresh) - */ - -void Epd42::SetLutQuick(void) { - unsigned int count; - SendCommand(LUT_FOR_VCOM); //vcom - for(count = 0; count < 44; count++) { - SendData(pgm_read_byte(&lut_vcom0_quick[count])); - } - - SendCommand(LUT_WHITE_TO_WHITE); //ww -- - for(count = 0; count < 42; count++) { - SendData(pgm_read_byte(&lut_ww_quick[count])); - } - - SendCommand(LUT_BLACK_TO_WHITE); //bw r - for(count = 0; count < 42; count++) { - SendData(pgm_read_byte(&lut_bw_quick[count])); - } - - SendCommand(LUT_WHITE_TO_BLACK); //wb w - for(count = 0; count < 42; count++) { - SendData(pgm_read_byte(&lut_wb_quick[count])); - } - - SendCommand(LUT_BLACK_TO_BLACK); //bb b - for(count = 0; count < 42; count++) { - SendData(pgm_read_byte(&lut_bb_quick[count])); - } -} - - -/** - * @brief: refresh and displays the frame - */ -void Epd42::DisplayFrame(const unsigned char* frame_buffer) { - SendCommand(RESOLUTION_SETTING); - SendData(width >> 8); - SendData(width & 0xff); - SendData(height >> 8); - SendData(height & 0xff); - - SendCommand(VCM_DC_SETTING); - SendData(0x12); - - SendCommand(VCOM_AND_DATA_INTERVAL_SETTING); - SendCommand(0x97); //VBDF 17|D7 VBDW 97 VBDB 57 VBDF F7 VBDW 77 VBDB 37 VBDR B7 - - if (frame_buffer != NULL) { - SendCommand(DATA_START_TRANSMISSION_1); - for(int i = 0; i < width / 8 * height; i++) { - SendData(0xFF); // bit set: white, bit reset: black - } - delay(2); - SendCommand(DATA_START_TRANSMISSION_2); - for(int i = 0; i < width / 8 * height; i++) { - SendData(pgm_read_byte(&frame_buffer[i])); - } - delay(2); - } - - SetLut(); - - SendCommand(DISPLAY_REFRESH); - delay(100); - WaitUntilIdle(); -} - - - - -/** - * @brief: clear the frame data from the SRAM, this won't refresh the display - */ -void Epd42::ClearFrame(void) { - SendCommand(RESOLUTION_SETTING); - SendData(width >> 8); - SendData(width & 0xff); - SendData(height >> 8); - SendData(height & 0xff); - - SendCommand(DATA_START_TRANSMISSION_1); - delay(2); - for(int i = 0; i < width / 8 * height; i++) { - SendData(0xFF); - } - delay(2); - SendCommand(DATA_START_TRANSMISSION_2); - delay(2); - for(int i = 0; i < width / 8 * height; i++) { - SendData(0xFF); - } - delay(2); -} - - - -/** - * @brief: This displays the frame data from SRAM - */ -void Epd42::DisplayFrame(void) { - SetLut(); - SendCommand(DISPLAY_REFRESH); - delay(100); - WaitUntilIdle(); -} - -void Epd42::DisplayFrameQuick(void) { - SetLutQuick(); - SendCommand(DISPLAY_REFRESH); - // DelayMs(100); - // WaitUntilIdle(); -} - - -/** - * @brief: After this command is transmitted, the chip would enter the deep-sleep mode to save power. - * The deep sleep mode would return to standby by hardware reset. The only one parameter is a - * check code, the command would be executed if check code = 0xA5. - * You can use Epd::Reset() to awaken and use Epd::Init() to initialize. - */ -void Epd42::Sleep() { - SendCommand(VCOM_AND_DATA_INTERVAL_SETTING); - SendData(0x17); //border floating - SendCommand(VCM_DC_SETTING); //VCOM to 0V - SendCommand(PANEL_SETTING); - delay(100); - - SendCommand(POWER_SETTING); //VG&VS to 0V fast - SendData(0x00); - SendData(0x00); - SendData(0x00); - SendData(0x00); - SendData(0x00); - delay(100); - - SendCommand(POWER_OFF); //power off - WaitUntilIdle(); - SendCommand(DEEP_SLEEP); //deep sleep - SendData(0xA5); -} - -const unsigned char lut_vcom0[] PROGMEM = -{ -0x40, 0x17, 0x00, 0x00, 0x00, 0x02, -0x00, 0x17, 0x17, 0x00, 0x00, 0x02, -0x00, 0x0A, 0x01, 0x00, 0x00, 0x01, -0x00, 0x0E, 0x0E, 0x00, 0x00, 0x02, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -const unsigned char lut_vcom0_quick[] PROGMEM = -{ -0x00, 0x0E, 0x00, 0x00, 0x00, 0x01, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - - - -const unsigned char lut_ww[] PROGMEM = -{ -0x40, 0x17, 0x00, 0x00, 0x00, 0x02, -0x90, 0x17, 0x17, 0x00, 0x00, 0x02, -0x40, 0x0A, 0x01, 0x00, 0x00, 0x01, -0xA0, 0x0E, 0x0E, 0x00, 0x00, 0x02, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -const unsigned char lut_ww_quick[] PROGMEM = -{ -0xA0, 0x0E, 0x00, 0x00, 0x00, 0x01, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - - -const unsigned char lut_bw[] PROGMEM = -{ -0x40, 0x17, 0x00, 0x00, 0x00, 0x02, -0x90, 0x17, 0x17, 0x00, 0x00, 0x02, -0x40, 0x0A, 0x01, 0x00, 0x00, 0x01, -0xA0, 0x0E, 0x0E, 0x00, 0x00, 0x02, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - - -const unsigned char lut_bw_quick[] PROGMEM = -{ -0xA0, 0x0E, 0x00, 0x00, 0x00, 0x01, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -const unsigned char lut_bb[] PROGMEM = -{ -0x80, 0x17, 0x00, 0x00, 0x00, 0x02, -0x90, 0x17, 0x17, 0x00, 0x00, 0x02, -0x80, 0x0A, 0x01, 0x00, 0x00, 0x01, -0x50, 0x0E, 0x0E, 0x00, 0x00, 0x02, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -const unsigned char lut_bb_quick[] PROGMEM = -{ -0x50, 0x0E, 0x00, 0x00, 0x00, 0x01, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - - -const unsigned char lut_wb[] PROGMEM = -{ -0x80, 0x17, 0x00, 0x00, 0x00, 0x02, -0x90, 0x17, 0x17, 0x00, 0x00, 0x02, -0x80, 0x0A, 0x01, 0x00, 0x00, 0x01, -0x50, 0x0E, 0x0E, 0x00, 0x00, 0x02, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -const unsigned char lut_wb_quick[] PROGMEM = -{ -0x50, 0x0E, 0x00, 0x00, 0x00, 0x01, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - - - -#define PIN_OUT_SET 0x60000304 -#define PIN_OUT_CLEAR 0x60000308 - -#define PWRITE ydigitalWrite - -#ifndef SSPI_USEANYPIN -// uses about 2.75 usecs, 365 kb /sec -// however does not work with GPIO 16 !!!! -void ICACHE_RAM_ATTR Epd42::fastSPIwrite(uint8_t d,uint8_t dc) { - - WRITE_PERI_REG( PIN_OUT_CLEAR, 1<>= 1) { - WRITE_PERI_REG( PIN_OUT_CLEAR, 1< 76 kb / sec -// can use any pin -void Epd42::fastSPIwrite(uint8_t d,uint8_t dc) { - - PWRITE(cs_pin, LOW); - - // transfer dc - PWRITE(sclk_pin, LOW); - if(dc) PWRITE(mosi_pin, HIGH); - else PWRITE(mosi_pin, LOW); - PWRITE(sclk_pin, HIGH); - - for(uint8_t bit = 0x80; bit; bit >>= 1) { - PWRITE(sclk_pin, LOW); - if(d & bit) PWRITE(mosi_pin, HIGH); - else PWRITE(mosi_pin, LOW); - PWRITE(sclk_pin, HIGH); - } - - PWRITE(cs_pin, HIGH); -} -#endif - -/* END OF FILE */ +/** + * @filename : epd4in2.cpp + * @brief : Implements for Dual-color e-paper library + * @author : Yehui from Waveshare + * + * Copyright (C) Waveshare August 10 2017 + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documnetation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include + + +//#define SSPI_USEANYPIN + +extern uint8_t *buffer; +uint8_t epd42_mode; + +Epd42::Epd42(int16_t width, int16_t height) : +Paint(width,height) { +} + +void Epd42::DisplayOnff(int8_t on) { +} + + +#define DISPLAY_INIT_MODE 0 +#define DISPLAY_INIT_PARTIAL 1 +#define DISPLAY_INIT_FULL 2 + +void Epd42::Updateframe() { + //SetFrameMemory(buffer, 0, 0, EPD_WIDTH,EPD_HEIGHT); + SetPartialWindow(buffer, 0, 0, width,height,2); + if (epd42_mode==DISPLAY_INIT_PARTIAL) { + DisplayFrameQuick(); + } else { + DisplayFrame(); + } + //Serial.printf("update\n"); +} + +void Epd42::DisplayInit(int8_t p,int8_t size,int8_t rot,int8_t font) { +// ignore update mode + if (p==DISPLAY_INIT_PARTIAL) { + epd42_mode=p; + //Init(lut_partial_update); + //ClearFrameMemory(0xFF); // bit set = white, bit reset = black + DisplayFrameQuick(); + delay(500); + return; + //Serial.printf("partial\n"); + } else if (p==DISPLAY_INIT_FULL) { + epd42_mode=p; + //Init(lut_full_update); + //ClearFrameMemory(0xFF); // bit set = white, bit reset = black + DisplayFrame(); + delay(4500); + return; + //Serial.printf("full\n"); + } else { + epd42_mode=DISPLAY_INIT_FULL; + Updateframe(); + } + + setRotation(rot); + invertDisplay(false); + setTextWrap(false); // Allow text to run off edges + cp437(true); + setTextFont(font); + setTextSize(size); + setTextColor(WHITE,BLACK); + setCursor(0,0); + fillScreen(BLACK); +} + +int16_t Epd42::Begin(int16_t cs,int16_t mosi,int16_t sclk) { + cs_pin=cs; + mosi_pin=mosi; + sclk_pin=sclk; +} + +void Epd42::Init(int8_t p) { + epd42_mode=p; + DisplayFrame(); + delay(4000); +} + +int Epd42::Init(void) { + pinMode(cs_pin, OUTPUT); + pinMode(mosi_pin, OUTPUT); + pinMode(sclk_pin, OUTPUT); + + digitalWrite(cs_pin,HIGH); + digitalWrite(mosi_pin,LOW); + digitalWrite(sclk_pin,LOW); + + width = EPD_WIDTH42; + height = EPD_HEIGHT42; + + Reset(); + SendCommand(POWER_SETTING); + SendData(0x03); // VDS_EN, VDG_EN + SendData(0x00); // VCOM_HV, VGHL_LV[1], VGHL_LV[0] + SendData(0x2b); // VDH + SendData(0x2b); // VDL + SendData(0xff); // VDHR + SendCommand(BOOSTER_SOFT_START); + SendData(0x17); + SendData(0x17); + SendData(0x17); //07 0f 17 1f 27 2F 37 2f + SendCommand(POWER_ON); + WaitUntilIdle(); + SendCommand(PANEL_SETTING); + // SendData(0xbf); // KW-BF KWR-AF BWROTP 0f + // SendData(0x0b); +// SendData(0x0F); //300x400 Red mode, LUT from OTP +// SendData(0x1F); //300x400 B/W mode, LUT from OTP + SendData(0x3F); //300x400 B/W mode, LUT set by register +// SendData(0x2F); //300x400 Red mode, LUT set by register + + SendCommand(PLL_CONTROL); + SendData(0x3C); // 3A 100Hz 29 150Hz 39 200Hz 31 171Hz 3C 50Hz (default) 0B 10Hz + //SendData(0x0B); //0B is 10Hz + /* EPD hardware init end */ + return 0; +} + +/** + * @brief: basic function for sending commands + */ +void Epd42::SendCommand(unsigned char command) { + //DigitalWrite(dc_pin, LOW); + //SpiTransfer(command); + fastSPIwrite(command,0); +} + +/** + * @brief: basic function for sending data + */ +void Epd42::SendData(unsigned char data) { + //DigitalWrite(dc_pin, HIGH); + //SpiTransfer(data); + fastSPIwrite(data,1); +} + +/** + * @brief: Wait until the busy_pin goes HIGH + */ +void Epd42::WaitUntilIdle(void) { + // while(DigitalRead(busy_pin) == 0) { //0: busy, 1: idle + // DelayMs(1); + // } +} + +/** + * @brief: module reset. + * often used to awaken the module in deep sleep, + * see Epd::Sleep(); + */ +void Epd42::Reset(void) { + //DigitalWrite(reset_pin, LOW); + //DelayMs(200); + //DigitalWrite(reset_pin, HIGH); + //DelayMs(200); +} +/** + * @brief: transmit partial data to the SRAM. The final parameter chooses between dtm=1 and dtm=2 + */ +void Epd42::SetPartialWindow(const unsigned char* buffer_black, int x, int y, int w, int l, int dtm) { + SendCommand(PARTIAL_IN); + SendCommand(PARTIAL_WINDOW); + SendData(x >> 8); + SendData(x & 0xf8); // x should be the multiple of 8, the last 3 bit will always be ignored + SendData(((x & 0xf8) + w - 1) >> 8); + SendData(((x & 0xf8) + w - 1) | 0x07); + SendData(y >> 8); + SendData(y & 0xff); + SendData((y + l - 1) >> 8); + SendData((y + l - 1) & 0xff); + SendData(0x01); // Gates scan both inside and outside of the partial window. (default) + // DelayMs(2); + SendCommand((dtm == 1) ? DATA_START_TRANSMISSION_1 : DATA_START_TRANSMISSION_2); + if (buffer_black != NULL) { + for(int i = 0; i < w / 8 * l; i++) { + SendData(buffer_black[i]^0xff); + } + } else { + for(int i = 0; i < w / 8 * l; i++) { + SendData(0x00); + } + } + // DelayMs(2); + SendCommand(PARTIAL_OUT); +} + + + +/** + * @brief: set the look-up table + */ +void Epd42::SetLut(void) { + unsigned int count; + SendCommand(LUT_FOR_VCOM); //vcom + for(count = 0; count < 44; count++) { + SendData(pgm_read_byte(&lut_vcom0[count])); + } + + SendCommand(LUT_WHITE_TO_WHITE); //ww -- + for(count = 0; count < 42; count++) { + SendData(pgm_read_byte(&lut_ww[count])); + } + + SendCommand(LUT_BLACK_TO_WHITE); //bw r + for(count = 0; count < 42; count++) { + SendData(pgm_read_byte(&lut_bw[count])); + } + + SendCommand(LUT_WHITE_TO_BLACK); //wb w + for(count = 0; count < 42; count++) { + SendData(pgm_read_byte(&lut_wb[count])); + } + + SendCommand(LUT_BLACK_TO_BLACK); //bb b + for(count = 0; count < 42; count++) { + SendData(pgm_read_byte(&lut_bb[count])); + } +} + + +/** + * @brief: set the look-up table for quick display (partial refresh) + */ + +void Epd42::SetLutQuick(void) { + unsigned int count; + SendCommand(LUT_FOR_VCOM); //vcom + for(count = 0; count < 44; count++) { + SendData(pgm_read_byte(&lut_vcom0_quick[count])); + } + + SendCommand(LUT_WHITE_TO_WHITE); //ww -- + for(count = 0; count < 42; count++) { + SendData(pgm_read_byte(&lut_ww_quick[count])); + } + + SendCommand(LUT_BLACK_TO_WHITE); //bw r + for(count = 0; count < 42; count++) { + SendData(pgm_read_byte(&lut_bw_quick[count])); + } + + SendCommand(LUT_WHITE_TO_BLACK); //wb w + for(count = 0; count < 42; count++) { + SendData(pgm_read_byte(&lut_wb_quick[count])); + } + + SendCommand(LUT_BLACK_TO_BLACK); //bb b + for(count = 0; count < 42; count++) { + SendData(pgm_read_byte(&lut_bb_quick[count])); + } +} + + +/** + * @brief: refresh and displays the frame + */ +void Epd42::DisplayFrame(const unsigned char* frame_buffer) { + SendCommand(RESOLUTION_SETTING); + SendData(width >> 8); + SendData(width & 0xff); + SendData(height >> 8); + SendData(height & 0xff); + + SendCommand(VCM_DC_SETTING); + SendData(0x12); + + SendCommand(VCOM_AND_DATA_INTERVAL_SETTING); + SendCommand(0x97); //VBDF 17|D7 VBDW 97 VBDB 57 VBDF F7 VBDW 77 VBDB 37 VBDR B7 + + if (frame_buffer != NULL) { + SendCommand(DATA_START_TRANSMISSION_1); + for(int i = 0; i < width / 8 * height; i++) { + SendData(0xFF); // bit set: white, bit reset: black + } + delay(2); + SendCommand(DATA_START_TRANSMISSION_2); + for(int i = 0; i < width / 8 * height; i++) { + SendData(pgm_read_byte(&frame_buffer[i])); + } + delay(2); + } + + SetLut(); + + SendCommand(DISPLAY_REFRESH); + delay(100); + WaitUntilIdle(); +} + + + + +/** + * @brief: clear the frame data from the SRAM, this won't refresh the display + */ +void Epd42::ClearFrame(void) { + SendCommand(RESOLUTION_SETTING); + SendData(width >> 8); + SendData(width & 0xff); + SendData(height >> 8); + SendData(height & 0xff); + + SendCommand(DATA_START_TRANSMISSION_1); + delay(2); + for(int i = 0; i < width / 8 * height; i++) { + SendData(0xFF); + } + delay(2); + SendCommand(DATA_START_TRANSMISSION_2); + delay(2); + for(int i = 0; i < width / 8 * height; i++) { + SendData(0xFF); + } + delay(2); +} + + + +/** + * @brief: This displays the frame data from SRAM + */ +void Epd42::DisplayFrame(void) { + SetLut(); + SendCommand(DISPLAY_REFRESH); + delay(100); + WaitUntilIdle(); +} + +void Epd42::DisplayFrameQuick(void) { + SetLutQuick(); + SendCommand(DISPLAY_REFRESH); + // DelayMs(100); + // WaitUntilIdle(); +} + + +/** + * @brief: After this command is transmitted, the chip would enter the deep-sleep mode to save power. + * The deep sleep mode would return to standby by hardware reset. The only one parameter is a + * check code, the command would be executed if check code = 0xA5. + * You can use Epd::Reset() to awaken and use Epd::Init() to initialize. + */ +void Epd42::Sleep() { + SendCommand(VCOM_AND_DATA_INTERVAL_SETTING); + SendData(0x17); //border floating + SendCommand(VCM_DC_SETTING); //VCOM to 0V + SendCommand(PANEL_SETTING); + delay(100); + + SendCommand(POWER_SETTING); //VG&VS to 0V fast + SendData(0x00); + SendData(0x00); + SendData(0x00); + SendData(0x00); + SendData(0x00); + delay(100); + + SendCommand(POWER_OFF); //power off + WaitUntilIdle(); + SendCommand(DEEP_SLEEP); //deep sleep + SendData(0xA5); +} + +const unsigned char lut_vcom0[] PROGMEM = +{ +0x40, 0x17, 0x00, 0x00, 0x00, 0x02, +0x00, 0x17, 0x17, 0x00, 0x00, 0x02, +0x00, 0x0A, 0x01, 0x00, 0x00, 0x01, +0x00, 0x0E, 0x0E, 0x00, 0x00, 0x02, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const unsigned char lut_vcom0_quick[] PROGMEM = +{ +0x00, 0x0E, 0x00, 0x00, 0x00, 0x01, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + + + +const unsigned char lut_ww[] PROGMEM = +{ +0x40, 0x17, 0x00, 0x00, 0x00, 0x02, +0x90, 0x17, 0x17, 0x00, 0x00, 0x02, +0x40, 0x0A, 0x01, 0x00, 0x00, 0x01, +0xA0, 0x0E, 0x0E, 0x00, 0x00, 0x02, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const unsigned char lut_ww_quick[] PROGMEM = +{ +0xA0, 0x0E, 0x00, 0x00, 0x00, 0x01, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + + +const unsigned char lut_bw[] PROGMEM = +{ +0x40, 0x17, 0x00, 0x00, 0x00, 0x02, +0x90, 0x17, 0x17, 0x00, 0x00, 0x02, +0x40, 0x0A, 0x01, 0x00, 0x00, 0x01, +0xA0, 0x0E, 0x0E, 0x00, 0x00, 0x02, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + + +const unsigned char lut_bw_quick[] PROGMEM = +{ +0xA0, 0x0E, 0x00, 0x00, 0x00, 0x01, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const unsigned char lut_bb[] PROGMEM = +{ +0x80, 0x17, 0x00, 0x00, 0x00, 0x02, +0x90, 0x17, 0x17, 0x00, 0x00, 0x02, +0x80, 0x0A, 0x01, 0x00, 0x00, 0x01, +0x50, 0x0E, 0x0E, 0x00, 0x00, 0x02, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const unsigned char lut_bb_quick[] PROGMEM = +{ +0x50, 0x0E, 0x00, 0x00, 0x00, 0x01, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + + +const unsigned char lut_wb[] PROGMEM = +{ +0x80, 0x17, 0x00, 0x00, 0x00, 0x02, +0x90, 0x17, 0x17, 0x00, 0x00, 0x02, +0x80, 0x0A, 0x01, 0x00, 0x00, 0x01, +0x50, 0x0E, 0x0E, 0x00, 0x00, 0x02, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const unsigned char lut_wb_quick[] PROGMEM = +{ +0x50, 0x0E, 0x00, 0x00, 0x00, 0x01, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +#define PIN_OUT_SET 0x60000304 +#define PIN_OUT_CLEAR 0x60000308 + +#ifdef ESP32 +#define SSPI_USEANYPIN 1 +#define PWRITE digitalWrite +#else +#define PWRITE ydigitalWrite +#endif + +#ifndef SSPI_USEANYPIN +// uses about 2.75 usecs, 365 kb /sec +// however does not work with GPIO 16 !!!! +void ICACHE_RAM_ATTR Epd42::fastSPIwrite(uint8_t d,uint8_t dc) { + + WRITE_PERI_REG( PIN_OUT_CLEAR, 1<>= 1) { + WRITE_PERI_REG( PIN_OUT_CLEAR, 1< 76 kb / sec +// can use any pin +void Epd42::fastSPIwrite(uint8_t d,uint8_t dc) { + + PWRITE(cs_pin, LOW); + + // transfer dc + PWRITE(sclk_pin, LOW); + if(dc) PWRITE(mosi_pin, HIGH); + else PWRITE(mosi_pin, LOW); + PWRITE(sclk_pin, HIGH); + + for(uint8_t bit = 0x80; bit; bit >>= 1) { + PWRITE(sclk_pin, LOW); + if(d & bit) PWRITE(mosi_pin, HIGH); + else PWRITE(mosi_pin, LOW); + PWRITE(sclk_pin, HIGH); + } + + PWRITE(cs_pin, HIGH); +} +#endif + +/* END OF FILE */ diff --git a/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd4in2.h b/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd4in2.h old mode 100755 new mode 100644 index d2f934093..9b140c0d8 --- a/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd4in2.h +++ b/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd4in2.h @@ -1,130 +1,130 @@ -/** - * @filename : epd4in2.h - * @brief : Header file for Dual-color e-paper library epd4in2.cpp - * @author : Yehui from Waveshare - * - * Copyright (C) Waveshare August 10 2017 - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documnetation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef EPD4IN2_H -#define EPD4IN2_H - -#include "epdpaint.h" - -// Display resolution -#define EPD_WIDTH42 400 -#define EPD_HEIGHT42 300 - -// EPD4IN2 commands -#define PANEL_SETTING 0x00 -#define POWER_SETTING 0x01 -#define POWER_OFF 0x02 -#define POWER_OFF_SEQUENCE_SETTING 0x03 -#define POWER_ON 0x04 -#define POWER_ON_MEASURE 0x05 -#define BOOSTER_SOFT_START 0x06 -#define DEEP_SLEEP 0x07 -#define DATA_START_TRANSMISSION_1 0x10 -#define DATA_STOP 0x11 -#define DISPLAY_REFRESH 0x12 -#define DATA_START_TRANSMISSION_2 0x13 -#define LUT_FOR_VCOM 0x20 -#define LUT_WHITE_TO_WHITE 0x21 -#define LUT_BLACK_TO_WHITE 0x22 -#define LUT_WHITE_TO_BLACK 0x23 -#define LUT_BLACK_TO_BLACK 0x24 -#define PLL_CONTROL 0x30 -#define TEMPERATURE_SENSOR_COMMAND 0x40 -#define TEMPERATURE_SENSOR_SELECTION 0x41 -#define TEMPERATURE_SENSOR_WRITE 0x42 -#define TEMPERATURE_SENSOR_READ 0x43 -#define VCOM_AND_DATA_INTERVAL_SETTING 0x50 -#define LOW_POWER_DETECTION 0x51 -#define TCON_SETTING 0x60 -#define RESOLUTION_SETTING 0x61 -#define GSST_SETTING 0x65 -#define GET_STATUS 0x71 -#define AUTO_MEASUREMENT_VCOM 0x80 -#define READ_VCOM_VALUE 0x81 -#define VCM_DC_SETTING 0x82 -#define PARTIAL_WINDOW 0x90 -#define PARTIAL_IN 0x91 -#define PARTIAL_OUT 0x92 -#define PROGRAM_MODE 0xA0 -#define ACTIVE_PROGRAMMING 0xA1 -#define READ_OTP 0xA2 -#define POWER_SAVING 0xE3 - -extern const unsigned char lut_vcom0[]; -extern const unsigned char lut_ww[]; -extern const unsigned char lut_bw[]; -extern const unsigned char lut_bb[]; -extern const unsigned char lut_wb[]; - -extern const unsigned char lut_vcom0_quick[]; -extern const unsigned char lut_ww_quick[]; -extern const unsigned char lut_bw_quick[]; -extern const unsigned char lut_bb_quick[]; -extern const unsigned char lut_wb_quick[]; - - - - -class Epd42 : public Paint { -public: - Epd42(int16_t width, int16_t height); - - int Init(void); - void Init(int8_t p); - void SendCommand(unsigned char command); - void SendData(unsigned char data); - void WaitUntilIdle(void); - void Reset(void); - - void SetPartialWindow(const unsigned char* frame_buffer, int x, int y, int w, int l, int dtm); - - void SetPartialWindowBlack(const unsigned char* buffer_black, int x, int y, int w, int l); - void SetPartialWindowRed(const unsigned char* buffer_red, int x, int y, int w, int l); - void SetLut(void); - void SetLutQuick(void); - void DisplayFrame(const unsigned char* frame_buffer); - void DisplayFrame(void); - void DisplayFrameQuick(void); - void ClearFrame(void); - void Sleep(void); - - void DisplayOnff(int8_t on); - void DisplayInit(int8_t p,int8_t size,int8_t rot,int8_t font); - int16_t Begin(int16_t p1,int16_t p2,int16_t p3); - void Updateframe(); - -private: - void fastSPIwrite(uint8_t d,uint8_t dc); - uint8_t cs_pin; - uint8_t mosi_pin; - uint8_t sclk_pin; - int16_t width; - int16_t height; -}; - -#endif /* EPD4IN2_H */ - -/* END OF FILE */ +/** + * @filename : epd4in2.h + * @brief : Header file for Dual-color e-paper library epd4in2.cpp + * @author : Yehui from Waveshare + * + * Copyright (C) Waveshare August 10 2017 + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documnetation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef EPD4IN2_H +#define EPD4IN2_H + +#include "epdpaint.h" + +// Display resolution +#define EPD_WIDTH42 400 +#define EPD_HEIGHT42 300 + +// EPD4IN2 commands +#define PANEL_SETTING 0x00 +#define POWER_SETTING 0x01 +#define POWER_OFF 0x02 +#define POWER_OFF_SEQUENCE_SETTING 0x03 +#define POWER_ON 0x04 +#define POWER_ON_MEASURE 0x05 +#define BOOSTER_SOFT_START 0x06 +#define DEEP_SLEEP 0x07 +#define DATA_START_TRANSMISSION_1 0x10 +#define DATA_STOP 0x11 +#define DISPLAY_REFRESH 0x12 +#define DATA_START_TRANSMISSION_2 0x13 +#define LUT_FOR_VCOM 0x20 +#define LUT_WHITE_TO_WHITE 0x21 +#define LUT_BLACK_TO_WHITE 0x22 +#define LUT_WHITE_TO_BLACK 0x23 +#define LUT_BLACK_TO_BLACK 0x24 +#define PLL_CONTROL 0x30 +#define TEMPERATURE_SENSOR_COMMAND 0x40 +#define TEMPERATURE_SENSOR_SELECTION 0x41 +#define TEMPERATURE_SENSOR_WRITE 0x42 +#define TEMPERATURE_SENSOR_READ 0x43 +#define VCOM_AND_DATA_INTERVAL_SETTING 0x50 +#define LOW_POWER_DETECTION 0x51 +#define TCON_SETTING 0x60 +#define RESOLUTION_SETTING 0x61 +#define GSST_SETTING 0x65 +#define GET_STATUS 0x71 +#define AUTO_MEASUREMENT_VCOM 0x80 +#define READ_VCOM_VALUE 0x81 +#define VCM_DC_SETTING 0x82 +#define PARTIAL_WINDOW 0x90 +#define PARTIAL_IN 0x91 +#define PARTIAL_OUT 0x92 +#define PROGRAM_MODE 0xA0 +#define ACTIVE_PROGRAMMING 0xA1 +#define READ_OTP 0xA2 +#define POWER_SAVING 0xE3 + +extern const unsigned char lut_vcom0[]; +extern const unsigned char lut_ww[]; +extern const unsigned char lut_bw[]; +extern const unsigned char lut_bb[]; +extern const unsigned char lut_wb[]; + +extern const unsigned char lut_vcom0_quick[]; +extern const unsigned char lut_ww_quick[]; +extern const unsigned char lut_bw_quick[]; +extern const unsigned char lut_bb_quick[]; +extern const unsigned char lut_wb_quick[]; + + + + +class Epd42 : public Paint { +public: + Epd42(int16_t width, int16_t height); + + int Init(void); + void Init(int8_t p); + void SendCommand(unsigned char command); + void SendData(unsigned char data); + void WaitUntilIdle(void); + void Reset(void); + + void SetPartialWindow(const unsigned char* frame_buffer, int x, int y, int w, int l, int dtm); + + void SetPartialWindowBlack(const unsigned char* buffer_black, int x, int y, int w, int l); + void SetPartialWindowRed(const unsigned char* buffer_red, int x, int y, int w, int l); + void SetLut(void); + void SetLutQuick(void); + void DisplayFrame(const unsigned char* frame_buffer); + void DisplayFrame(void); + void DisplayFrameQuick(void); + void ClearFrame(void); + void Sleep(void); + + void DisplayOnff(int8_t on); + void DisplayInit(int8_t p,int8_t size,int8_t rot,int8_t font); + int16_t Begin(int16_t p1,int16_t p2,int16_t p3); + void Updateframe(); + +private: + void fastSPIwrite(uint8_t d,uint8_t dc); + uint8_t cs_pin; + uint8_t mosi_pin; + uint8_t sclk_pin; + int16_t width; + int16_t height; +}; + +#endif /* EPD4IN2_H */ + +/* END OF FILE */ diff --git a/lib/esp-knx-ip-0.5.2/esp-knx-ip.cpp b/lib/esp-knx-ip-0.5.2/esp-knx-ip.cpp index 5917e62f3..96f4e1c73 100644 --- a/lib/esp-knx-ip-0.5.2/esp-knx-ip.cpp +++ b/lib/esp-knx-ip-0.5.2/esp-knx-ip.cpp @@ -536,7 +536,6 @@ void ESPKNXIP::__loop_knx() uint8_t buf[read]; udp.read(buf, read); - udp.flush(); DEBUG_PRINT(F("Got packet:")); diff --git a/lib/esp-knx-ip-0.5.2/esp-knx-ip.h b/lib/esp-knx-ip-0.5.2/esp-knx-ip.h index 7c6377bec..7150706bb 100644 --- a/lib/esp-knx-ip-0.5.2/esp-knx-ip.h +++ b/lib/esp-knx-ip-0.5.2/esp-knx-ip.h @@ -397,6 +397,9 @@ typedef struct __callback_assignment callback_id_t callback_id; } callback_assignment_t; +// FastPrecisePowf from tasmota/support_float.ino +//extern float FastPrecisePowf(const float x, const float y); + class ESPKNXIP { public: ESPKNXIP(); @@ -564,6 +567,8 @@ class ESPKNXIP { callback_assignment_id_t __callback_register_assignment(address_t address, callback_id_t id); void __callback_delete_assignment(callback_assignment_id_t id); + //static inline float pow(float a, float b) { return FastPrecisePowf(a, b); } + ESP8266WebServer *server; address_t physaddr; diff --git a/lib/vl53l0x-arduino-1.02/.travis.yml b/lib/vl53l0x-arduino-1.02/.travis.yml old mode 100755 new mode 100644 diff --git a/lib/vl53l0x-arduino-1.02/LICENSE.txt b/lib/vl53l0x-arduino-1.02/LICENSE.txt old mode 100755 new mode 100644 diff --git a/lib/vl53l0x-arduino-1.02/README.md b/lib/vl53l0x-arduino-1.02/README.md old mode 100755 new mode 100644 diff --git a/lib/vl53l0x-arduino-1.02/VL53L0X.cpp b/lib/vl53l0x-arduino-1.02/VL53L0X.cpp old mode 100755 new mode 100644 diff --git a/lib/vl53l0x-arduino-1.02/VL53L0X.h b/lib/vl53l0x-arduino-1.02/VL53L0X.h old mode 100755 new mode 100644 diff --git a/lib/vl53l0x-arduino-1.02/examples/Continuous/Continuous.ino b/lib/vl53l0x-arduino-1.02/examples/Continuous/Continuous.ino old mode 100755 new mode 100644 diff --git a/lib/vl53l0x-arduino-1.02/examples/Single/Single.ino b/lib/vl53l0x-arduino-1.02/examples/Single/Single.ino old mode 100755 new mode 100644 diff --git a/lib/vl53l0x-arduino-1.02/keywords.txt b/lib/vl53l0x-arduino-1.02/keywords.txt old mode 100755 new mode 100644 diff --git a/lib/vl53l0x-arduino-1.02/library.properties b/lib/vl53l0x-arduino-1.02/library.properties old mode 100755 new mode 100644 diff --git a/libesp32/ESP32-Ethernet/README.md b/libesp32/ESP32-Ethernet/README.md new file mode 100644 index 000000000..ac4d80fa4 --- /dev/null +++ b/libesp32/ESP32-Ethernet/README.md @@ -0,0 +1,4 @@ +# Ethernet Arduino Library for ESP32 + +See https://github.com/espressif/arduino-esp32/issues/3554#issuecomment-596902806 + diff --git a/libesp32/ESP32-Ethernet/examples/EthernetLAN_IP101/EthernetLAN_IP101.ino b/libesp32/ESP32-Ethernet/examples/EthernetLAN_IP101/EthernetLAN_IP101.ino new file mode 100644 index 000000000..3bbe837a1 --- /dev/null +++ b/libesp32/ESP32-Ethernet/examples/EthernetLAN_IP101/EthernetLAN_IP101.ino @@ -0,0 +1,82 @@ +#include + +#define ETH_ADDR 1 +#define ETH_POWER_PIN 5 +#define ETH_MDC_PIN 23 +#define ETH_MDIO_PIN 18 +#define ETH_TYPE ETH_PHY_IP101 + +static bool eth_connected = false; + +void WiFiEvent(WiFiEvent_t event) +{ + switch (event) { + case SYSTEM_EVENT_ETH_START: + Serial.println("ETH Started"); + //set eth hostname here + ETH.setHostname("esp32-ethernet"); + break; + case SYSTEM_EVENT_ETH_CONNECTED: + Serial.println("ETH Connected"); + break; + case SYSTEM_EVENT_ETH_GOT_IP: + Serial.print("ETH MAC: "); + Serial.print(ETH.macAddress()); + Serial.print(", IPv4: "); + Serial.print(ETH.localIP()); + if (ETH.fullDuplex()) { + Serial.print(", FULL_DUPLEX"); + } + Serial.print(", "); + Serial.print(ETH.linkSpeed()); + Serial.println("Mbps"); + eth_connected = true; + break; + case SYSTEM_EVENT_ETH_DISCONNECTED: + Serial.println("ETH Disconnected"); + eth_connected = false; + break; + case SYSTEM_EVENT_ETH_STOP: + Serial.println("ETH Stopped"); + eth_connected = false; + break; + default: + break; + } +} + +void testClient(const char * host, uint16_t port) +{ + Serial.print("\nconnecting to "); + Serial.println(host); + + WiFiClient client; + if (!client.connect(host, port)) { + Serial.println("connection failed"); + return; + } + client.printf("GET / HTTP/1.1\r\nHost: %s\r\n\r\n", host); + while (client.connected() && !client.available()); + while (client.available()) { + Serial.write(client.read()); + } + + Serial.println("closing connection\n"); + client.stop(); +} + +void setup() +{ + Serial.begin(115200); + WiFi.onEvent(WiFiEvent); + ETH.begin(ETH_ADDR, ETH_POWER_PIN, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_TYPE); +} + + +void loop() +{ + if (eth_connected) { + testClient("google.com", 80); + } + delay(10000); +} \ No newline at end of file diff --git a/libesp32/ESP32-Ethernet/library.properties b/libesp32/ESP32-Ethernet/library.properties new file mode 100644 index 000000000..50c7b8ea1 --- /dev/null +++ b/libesp32/ESP32-Ethernet/library.properties @@ -0,0 +1,17 @@ +name=ESP32 Ethernet + +version=1.1.0 + +author=Espressif + +maintainer=Espressif + +sentence=Ethernet Library for ESP32 + +paragraph=This library allows ESP32 to use ethernet hardware + +category=Communication + +url= + +architectures=esp32 diff --git a/libesp32/ESP32-Ethernet/src/ETH.cpp b/libesp32/ESP32-Ethernet/src/ETH.cpp new file mode 100644 index 000000000..2b3dd4390 --- /dev/null +++ b/libesp32/ESP32-Ethernet/src/ETH.cpp @@ -0,0 +1,299 @@ +/* + ETH.h - espre ETH PHY support. + Based on WiFi.h from Arduino WiFi shield library. + Copyright (c) 2011-2014 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "ETH.h" +#include "eth_phy/phy.h" +#include "eth_phy/phy_tlk110.h" +#include "eth_phy/phy_lan8720.h" +#include "eth_phy/phy_ip101.h" +#include "lwip/err.h" +#include "lwip/dns.h" + +extern void tcpipInit(); + +static int _eth_phy_mdc_pin = -1; +static int _eth_phy_mdio_pin = -1; +static int _eth_phy_power_pin = -1; +static eth_phy_power_enable_func _eth_phy_power_enable_orig = NULL; + +static void _eth_phy_config_gpio(void) +{ + if(_eth_phy_mdc_pin < 0 || _eth_phy_mdio_pin < 0){ + log_e("MDC and MDIO pins are not configured!"); + return; + } + phy_rmii_configure_data_interface_pins(); + phy_rmii_smi_configure_pins(_eth_phy_mdc_pin, _eth_phy_mdio_pin); +} + +static void _eth_phy_power_enable(bool enable) +{ + pinMode(_eth_phy_power_pin, OUTPUT); + digitalWrite(_eth_phy_power_pin, enable); + delay(1); +} + +ETHClass::ETHClass():initialized(false),started(false),staticIP(false) +{ +} + +ETHClass::~ETHClass() +{} + +bool ETHClass::begin(uint8_t phy_addr, int power, int mdc, int mdio, eth_phy_type_t type, eth_clock_mode_t clock_mode) +{ + esp_err_t err; + if(initialized){ + err = esp_eth_enable(); + if(err){ + log_e("esp_eth_enable error: %d", err); + return false; + } + started = true; + return true; + } + _eth_phy_mdc_pin = mdc; + _eth_phy_mdio_pin = mdio; + _eth_phy_power_pin = power; + + if(type == ETH_PHY_LAN8720) + { + eth_config_t config = phy_lan8720_default_ethernet_config; + memcpy(ð_config, &config, sizeof(eth_config_t)); + } + else if(type == ETH_PHY_TLK110) + { + eth_config_t config = phy_tlk110_default_ethernet_config; + memcpy(ð_config, &config, sizeof(eth_config_t)); + } + else if(type == ETH_PHY_IP101) + { + eth_config_t config = phy_ip101_default_ethernet_config; + memcpy(ð_config, &config, sizeof(eth_config_t)); + } + else + { + log_e("Bad ETH_PHY type: %u", (uint8_t)type); + return false; + } + + eth_config.phy_addr = (eth_phy_base_t)phy_addr; + eth_config.clock_mode = clock_mode; + eth_config.gpio_config = _eth_phy_config_gpio; + eth_config.tcpip_input = tcpip_adapter_eth_input; + if(_eth_phy_power_pin >= 0){ + _eth_phy_power_enable_orig = eth_config.phy_power_enable; + eth_config.phy_power_enable = _eth_phy_power_enable; + } + + tcpipInit(); + err = esp_eth_init(ð_config); + if(!err){ + initialized = true; + err = esp_eth_enable(); + if(err){ + log_e("esp_eth_enable error: %d", err); + } else { + started = true; + return true; + } + } else { + log_e("esp_eth_init error: %d", err); + } + return false; +} + +bool ETHClass::config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1, IPAddress dns2) +{ + esp_err_t err = ESP_OK; + tcpip_adapter_ip_info_t info; + + if(local_ip != (uint32_t)0x00000000){ + info.ip.addr = static_cast(local_ip); + info.gw.addr = static_cast(gateway); + info.netmask.addr = static_cast(subnet); + } else { + info.ip.addr = 0; + info.gw.addr = 0; + info.netmask.addr = 0; + } + + err = tcpip_adapter_dhcpc_stop(TCPIP_ADAPTER_IF_ETH); + if(err != ESP_OK && err != ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED){ + log_e("DHCP could not be stopped! Error: %d", err); + return false; + } + + err = tcpip_adapter_set_ip_info(TCPIP_ADAPTER_IF_ETH, &info); + if(err != ERR_OK){ + log_e("STA IP could not be configured! Error: %d", err); + return false; +} + if(info.ip.addr){ + staticIP = true; + } else { + err = tcpip_adapter_dhcpc_start(TCPIP_ADAPTER_IF_ETH); + if(err != ESP_OK && err != ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED){ + log_w("DHCP could not be started! Error: %d", err); + return false; + } + staticIP = false; + } + + ip_addr_t d; + d.type = IPADDR_TYPE_V4; + + if(dns1 != (uint32_t)0x00000000) { + // Set DNS1-Server + d.u_addr.ip4.addr = static_cast(dns1); + dns_setserver(0, &d); + } + + if(dns2 != (uint32_t)0x00000000) { + // Set DNS2-Server + d.u_addr.ip4.addr = static_cast(dns2); + dns_setserver(1, &d); + } + + return true; +} + +IPAddress ETHClass::localIP() +{ + tcpip_adapter_ip_info_t ip; + if(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip)){ + return IPAddress(); + } + return IPAddress(ip.ip.addr); +} + +IPAddress ETHClass::subnetMask() +{ + tcpip_adapter_ip_info_t ip; + if(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip)){ + return IPAddress(); + } + return IPAddress(ip.netmask.addr); +} + +IPAddress ETHClass::gatewayIP() +{ + tcpip_adapter_ip_info_t ip; + if(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip)){ + return IPAddress(); + } + return IPAddress(ip.gw.addr); +} + +IPAddress ETHClass::dnsIP(uint8_t dns_no) +{ + ip_addr_t dns_ip = dns_getserver(dns_no); + return IPAddress(dns_ip.u_addr.ip4.addr); +} + +IPAddress ETHClass::broadcastIP() +{ + tcpip_adapter_ip_info_t ip; + if(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip)){ + return IPAddress(); + } + return WiFiGenericClass::calculateBroadcast(IPAddress(ip.gw.addr), IPAddress(ip.netmask.addr)); +} + +IPAddress ETHClass::networkID() +{ + tcpip_adapter_ip_info_t ip; + if(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip)){ + return IPAddress(); + } + return WiFiGenericClass::calculateNetworkID(IPAddress(ip.gw.addr), IPAddress(ip.netmask.addr)); +} + +uint8_t ETHClass::subnetCIDR() +{ + tcpip_adapter_ip_info_t ip; + if(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip)){ + return (uint8_t)0; + } + return WiFiGenericClass::calculateSubnetCIDR(IPAddress(ip.netmask.addr)); +} + +const char * ETHClass::getHostname() +{ + const char * hostname; + if(tcpip_adapter_get_hostname(TCPIP_ADAPTER_IF_ETH, &hostname)){ + return NULL; + } + return hostname; +} + +bool ETHClass::setHostname(const char * hostname) +{ + return tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_ETH, hostname) == 0; +} + +bool ETHClass::fullDuplex() +{ + return eth_config.phy_get_duplex_mode(); +} + +bool ETHClass::linkUp() +{ + return eth_config.phy_check_link(); +} + +uint8_t ETHClass::linkSpeed() +{ + return eth_config.phy_get_speed_mode()?100:10; +} + +bool ETHClass::enableIpV6() +{ + return tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_ETH) == 0; +} + +IPv6Address ETHClass::localIPv6() +{ + static ip6_addr_t addr; + if(tcpip_adapter_get_ip6_linklocal(TCPIP_ADAPTER_IF_ETH, &addr)){ + return IPv6Address(); + } + return IPv6Address(addr.addr); +} + +uint8_t * macAddress(uint8_t* mac) +{ + if(!mac){ + return NULL; + } + esp_eth_get_mac(mac); + return mac; +} + +String ETHClass::macAddress(void) +{ + uint8_t mac[6]; + char macStr[18] = { 0 }; + esp_eth_get_mac(mac); + sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + return String(macStr); +} + +ETHClass ETH; diff --git a/libesp32/ESP32-Ethernet/src/ETH.h b/libesp32/ESP32-Ethernet/src/ETH.h new file mode 100644 index 000000000..7f175e13f --- /dev/null +++ b/libesp32/ESP32-Ethernet/src/ETH.h @@ -0,0 +1,95 @@ +/* + ETH.h - espre ETH PHY support. + Based on WiFi.h from Ardiono WiFi shield library. + Copyright (c) 2011-2014 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _ETH_H_ +#define _ETH_H_ + +#include "WiFi.h" +#include "esp_eth.h" + +#ifndef ETH_PHY_ADDR +#define ETH_PHY_ADDR 0 +#endif + +#ifndef ETH_PHY_TYPE +#define ETH_PHY_TYPE ETH_PHY_LAN8720 +#endif + +#ifndef ETH_PHY_POWER +#define ETH_PHY_POWER -1 +#endif + +#ifndef ETH_PHY_MDC +#define ETH_PHY_MDC 23 +#endif + +#ifndef ETH_PHY_MDIO +#define ETH_PHY_MDIO 18 +#endif + +#ifndef ETH_CLK_MODE +#define ETH_CLK_MODE ETH_CLOCK_GPIO0_IN +#endif + +typedef enum { ETH_PHY_LAN8720, ETH_PHY_TLK110, ETH_PHY_IP101, ETH_PHY_MAX } eth_phy_type_t; + +class ETHClass { + private: + bool initialized; + bool started; + bool staticIP; + eth_config_t eth_config; + public: + ETHClass(); + ~ETHClass(); + + bool begin(uint8_t phy_addr=ETH_PHY_ADDR, int power=ETH_PHY_POWER, int mdc=ETH_PHY_MDC, int mdio=ETH_PHY_MDIO, eth_phy_type_t type=ETH_PHY_TYPE, eth_clock_mode_t clk_mode=ETH_CLK_MODE); + + bool config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1 = (uint32_t)0x00000000, IPAddress dns2 = (uint32_t)0x00000000); + + const char * getHostname(); + bool setHostname(const char * hostname); + + bool fullDuplex(); + bool linkUp(); + uint8_t linkSpeed(); + + bool enableIpV6(); + IPv6Address localIPv6(); + + IPAddress localIP(); + IPAddress subnetMask(); + IPAddress gatewayIP(); + IPAddress dnsIP(uint8_t dns_no = 0); + + IPAddress broadcastIP(); + IPAddress networkID(); + uint8_t subnetCIDR(); + + uint8_t * macAddress(uint8_t* mac); + String macAddress(); + + friend class WiFiClient; + friend class WiFiServer; +}; + +extern ETHClass ETH; + +#endif /* _ETH_H_ */ diff --git a/libesp32/ESP32-Mail-Client/LICENSE b/libesp32/ESP32-Mail-Client/LICENSE new file mode 100755 index 000000000..2b2f9d774 --- /dev/null +++ b/libesp32/ESP32-Mail-Client/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 mobizt + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/libesp32/ESP32-Mail-Client/README.md b/libesp32/ESP32-Mail-Client/README.md new file mode 100755 index 000000000..bd4cb6328 --- /dev/null +++ b/libesp32/ESP32-Mail-Client/README.md @@ -0,0 +1,2138 @@ +# Mail Client Arduino Library for ESP32 v 2.1.4 + +This library allows ESP32 to send Email with/without attachment and receive Email with/without attachment download via SMTP and IMAP servers. + +The library was test and work well with ESP32s based module. + +Copyright (c) 2019 K. Suwatchai (Mobizt). + +![ESP32 Mail](/media/images/esp32-mail.png) + +## Tested Devices + +This following devices were tested and work well. + + * Sparkfun ESP32 Thing + * NodeMCU-32 + * WEMOS LOLIN32 + * TTGO T8 V1.8 + * M5Stack ESP32 + + + +## Features + +* Support Email sending with or without attachment via IMAP server. + +* Support SSL/TLS and STARTTLS protocols. + +* Working with SD card allows large file attachment supported or SPIFFS for small file size attachment. + +* Support Email reading via search and fetch modes (with or without attachment downloads). + +* Support large attachment download via SD card or SPIFFS for small file size attachment. + +* Message text and its header are able to download and save to SD card or SPIFFS. + +* Support Email message fetch and search via IMAP command as in RFC 3501 (depending on IMAP server implementation). + +* Support Ethernet. + +* Built-in Time function. + + + + +## Prerequisites + + +For library version 1.2.0 or newer, STARTTLS was supported and can be enable automatically when port 587 for SMTP was used or can set manually thrugh smtpData.setSTARTTLS(true) and for IMAP through imapData.setSTARTTLS(true). + + + +## Installing + + +Click on **Clone or download** dropdown at the top of repository, select **Download ZIP** and save file on your computer. + +From Arduino IDE, goto menu **Sketch** -> **Include Library** -> **Add .ZIP Library...** and choose **ESP32-Mail-Client-master.zip** that previously downloaded. + +Go to menu **Files** -> **Examples** -> **ESP32-Mail-Client-master** and choose one from examples + + + +## Usages + + +__Declaration and Initialization__ + + + +**The first thing to do to use this library.** + +```C++ + + +//1. Include ESP32 Mail Client library (this library) + +#include "ESP32_MailClient.h" + + +//2. For sending Email, declare Email Sending data object in global scope. +SMTPData smtpData; + +//Or + +//For receiving Email, declare Email receiving data object in global scope. +IMAPData imapData; + + +//3 Setup SMTP server login credential in setup() + +smtpData.setLogin("smtp.gmail.com", 587, "YOUR_EMAIL_ACCOUNT@gmail.com", "YOUR_EMAIL_PASSWORD"); + +//Or + +//Setup IMAP server login credential in setup() + +imapData.setLogin("imap.gmail.com", 993, "YOUR_EMAIL_ACCOUNT@gmail.com", "YOUR_EMAIL_PASSWORD"); + + +//4 For SMTP, set some custom message header (optional) +smtpData.addCustomMessageHeader("Date: Sat, 10 Aug 2019 21:39:56 -0700 (PDT)"); + +smtpData.addCustomMessageHeader("Message-ID: <10000.30000@gmail.com>"); + + +//5 To debug for SMTP + +smtpData.setDebug(true); + +//Or IMAP +imapData.setDebug(true); + + +//6. Send Email +MailClient.sendMail(smtpData)); + +//Or Receive Email + +MailClient.readdMail(imapData)); + + + + + +``` + +___ + + +__Send and Receive Email__ + + +**Compose Email** + +This library allows you to set sender, recipient, importance (priority), CC, BCC and attachment data (binary or from SD card file). + +To set sender, use `smtpData.setSender` e.g. `smtpData.setSender("Jarvis", "SOME_EMAIL_ACCOUNT@SOME_EMAIL.com")`. + +To set priority, use `smtpData.setPriority` e.g. `smtpData.setPriority("High")`. + +To set message subject, use `smtpData.setSubject` e.g. `smtpData.setSubject("ESP32 Send Mail Test")`. + +To set message text, use `smtpData.setMessage` e.g. `smtpData.setMessage("This is plain text message", false);`. + +To set sender, use `smtpData.addRecipient` e.g. `smtpData.addRecipient("SOME_RECIPIENT@SOME_MAIL.com")`. + +To add attachment, use `smtpData.addAttachData` e.g. `smtpData.addAttachData("test.png", "image/png", (uint8_t *)imageData, sizeof imageData);`. + + +When completed all required message data, sending Email `MailClient.sendMail(smtpData)`. + + + +**Get Email** + +To read or receive Email, mailbox folder should be assigned via `imapData.setFolder` e.g. `imapData.setFolder("INBOX")`. + +Then set search criteria to search specified mailbox folder via `imapData.setSearchCriteria` e.g. `imapData.setSearchCriteria("UID SEARCH ALL")`. + +Then set search limit to limut the memory and time usages `imapData.setSearchLimit`. + +From search criteria, UID of message will be available to fetch or read. + +Whit search, body message and attachment can be ignore to reduce the network data usage. + +Begin receive Email `MailClient.readMail(imapData)`. + +From above settings, you will get the following header information + +Messsage UID via `imapData.getUID`. + +Messsage ID via `imapData.getMessageID`. + +Accept Language via `imapData.getAcceptLanguage`. + +Content Language via `imapData.getContentLanguage`. + +Sender via `imapData.getFrom`. + +Sender Charset via `imapData.getFromCharset`. + +Recipient via `imapData.getTo`. + +Recipient Charset via `imapData.getToCharset`. + +CC via `imapData.getCC`. + +CC Charset via `imapData.getCCCharset`. + +Date via `imapData.getDate`. + +Subject via `imapData.getSubject`. + +Subject Charset via `imapData.getSubjectCharset`. + +In addition, by setting search criteria, the following infomation are available. + +Mailbox folder count via `imapData.getFolderCount`. + +Mailbox folder name via `imapData.getFolder`. + +Supported flags count via `imapData.getFlagCount`. + +Supported flags name via `imapData.getFlag`. + +Total message in folder via `imapData.totalMessages`. + +Total message from search result via `imapData.searchCount`. + +Available message from search result (limited by `imapData.setSearchLimit`) via `imapData.availableMessages`. + +When fetch specific message via `imapData.setFetchUID`, availability of attachment file can be determined via +`imapData.getAttachmentCount` for that message which will be automatically download by setting `imapData.setDownloadAttachment(true)` +prior to `MailClient.readMail`. + + + +See [full examples](https://github.com/mobizt/ESP32-Mail-Client/tree/master/examples) for all features usages. + + + + + +## All Supported Functions + + +**These are all functions available from the library and the descriptions.** + + +__Global functions__ + + +**Sending Email via SMTP server.** + +param *`smtpData`* - SMTP Data object to hold data and instances. + +return - *`Boolean`* type status indicates the success of operation. + +```C++ +bool sendMail(SMTPData &smtpData); +``` + + + + +**Reading Email via IMAP server.** + +param *`imapData`* - IMAP Data object to hold data and instances. + +return - *`Boolean`* type status indicates the success of operation. + +```C++ +bool readMail(IMAPData &imapData); +``` + + + + + +**Set the argument to the Flags for message.** + +param *`imapData`* - IMAP Data object to hold data and instances. + +param *`msgUID`* - The UID of message. + +param *`flags`* - The flag list. + +return - *`Boolean`* type status indicates the success of operation. + +```C++ +bool setFlag(IMAPData &imapData, int msgUID, const String &flags); +``` + + + + + +**Add the argument to the Flags for message.** + +param *`imapData`* - IMAP Data object to hold data and instances. + +param *`msgUID`* - The UID of message. + +param *`flags`* - The flag list. + +return - *`Boolean`* type status indicates the success of operation. + +```C++ +bool addFlag(IMAPData &imapData, int msgUID, const String &flags); +``` + + + + + + +**Remove the argument from the Flags for message.** + +param *`imapData`* - IMAP Data object to hold data and instances. + +param *`msgUID`* - The UID of message. + +param *`flags`* - The flag list. + +return - *`Boolean`* type status indicates the success of operation. + +```C++ +bool removeFlag(IMAPData &imapData, int msgUID, const String &flags); +``` + + + + + +**Get the Email sending error details.** + +return - *`Error details string (String object).`* + +```C++ +String smtpErrorReason(); +``` + + + + +**Get the Email reading error details.** + +return - *`Error details string (String object).`* + +```C++ +String imapErrorReason(); +``` + + + + + +**Init SD card with GPIO pins.** + +param *`sck`* -SPI Clock pin. + +param *`miso`* - SPI MISO pin. + +param *`m0si`* - SPI MOSI pin. + +param *`ss`* - SPI Chip/Slave Select pin. + +return *`Boolean`* type status indicates the success of operation. + + +```C++ +bool sdBegin(uint8_t sck, uint8_t miso, uint8_t mosi, uint8_t ss); +``` + + + + + + +**Init SD card with default GPIO pins.** + +return *`Boolean`* type status indicates the success of operation. + + +```C++ +bool sdBegin(void); +``` + + + + + + + +### IMAPData object call for receiving Email. + + +**Set the IMAP server login credentials.** + +param *`host`* - IMAP server e.g. imap.gmail.com. + +param *`port`* - IMAP port e.g. 993 for gmail. + +param *`loginEmail`* - The Email address of account. + +param *`loginPassword`* - The account password. + +param *`rootCA`* - Root CA certificate base64 string + +```C++ +void setLogin(const String &host, uint16_t port, const String &loginEmail, const String &loginPassword); + +void setLogin(const String &host, uint16_t port, const String &loginEmail, const String &loginPassword, const char *rootCA); + +``` + + + + + +**Set STARTTLS mode to enable STARTTLS protocol.** + +param *`starttls`* - bool flag that enables STARTTLS mode + +```C++ +void setSTARTTLS(bool starttls); +``` + + + + + + +**Set debug print to serial.** + +param *`debug`* - bool flag to enable debug + +```C++ +void setDebug(bool debug); +``` + + + + + + +**Set the mailbox folder to search or fetch.** + +param *`folderName`* - Known mailbox folder. Default value is INBOX + +```C++ +void setFolder(const String &folderName); +``` + + + +**Set the maximum message buffer size for text/html result from search or fetch the message.** + +param *`size`* - The message size in byte. + +```C++ +void setMessageBufferSize(size_t size); +``` + + + +**Set the maximum attachment file size to be downloaded.** + +param *`size`* - The attachement file size in byte. + +```C++ +void setAttachmentSizeLimit(size_t size); +``` + + + +**Set the search criteria used in selected mailbox search.** + +In case of message UID was set via setFetchUID function, search operation will not process, + +you need to clear message UID by calling imapData.setFetchUID("") to clear. + +param *`criteria`* - Search criteria String. + +If folder is not set, the INBOX folder will be used + +Example: + +*`SINCE 10-Feb-2019`* will search all messages that received since 10 Feb 2019 + +*`UID SEARCH ALL`* will seach all message which will return the message UID that can be use later for fetch one or more messages. + + +Search criteria can be consisted these keywords + + +*`ALL`* - All messages in the mailbox; the default initial key for ANDing. + +*`ANSWERED`* - Messages with the \Answered flag set. + +*`BCC`* - Messages that contain the specified string in the envelope structure's BCC field. + +*`BEFORE`* - Messages whose internal date (disregarding time and timezone) is earlier than the specified date. + +*`BODY`* - Messages that contain the specified string in the body of the message. + +*`CC`* - Messages that contain the specified string in the envelope structure's CC field. + +*`DELETED`* - Messages with the \Deleted flag set. + +*`DRAFT`* - Messages with the \Draft flag set. + +*`FLAGGED`* - Messages with the \Flagged flag set. + +*`FROM`* - Messages that contain the specified string in the envelope structure's FROM field. + +*`HEADER`* - Messages that have a header with the specified field-name (as defined in [RFC-2822]) + +and that contains the specified string in the text of the header (what comes after the colon). + +If the string to search is zero-length, this matches all messages that have a header line with + +the specified field-name regardless of the contents. + +*`KEYWORD`* - Messages with the specified keyword flag set. + +*`LARGER`* - Messages with an (RFC-2822) size larger than the specified number of octets. + +*`NEW`* - Messages that have the \Recent flag set but not the \Seen flag. + +This is functionally equivalent to `*"(RECENT UNSEEN)"*`. + +*`NOT`* - Messages that do not match the specified search key. + +*`OLD`* - Messages that do not have the \Recent flag set. This is functionally equivalent to + +*`"NOT RECENT"`* (as opposed to *`"NOT NEW"`*). + +*`ON`* - Messages whose internal date (disregarding time and timezone) is within the specified date. + +*`OR`* - Messages that match either search key. + +*`RECENT`* - Messages that have the \Recent flag set. + +*`SEEN`* - Messages that have the \Seen flag set. + +*`SENTBEFORE`* - Messages whose (RFC-2822) Date: header (disregarding time and timezone) is earlier than the specified date. + +*`SENTON`* - Messages whose (RFC-2822) Date: header (disregarding time and timezone) is within the specified date. + +*`SENTSINCE`* - Messages whose (RFC-2822) Date: header (disregarding time and timezone) is within or later than the specified date. + +*`SINCE`* - Messages whose internal date (disregarding time and timezone) is within or later than the specified date. + +*`SMALLER`* - Messages with an (RFC-2822) size smaller than the specified number of octets. + +*`SUBJECT`* - Messages that contain the specified string in the envelope structure's SUBJECT field. + +*`TEXT`* - Messages that contain the specified string in the header or body of the message. + +*`TO`* - Messages that contain the specified string in the envelope structure's TO field. + +*`UID`* - Messages with unique identifiers corresponding to the specified unique identifier set. + +Sequence set ranges are permitted. + +*`UNANSWERED`* - Messages that do not have the \Answered flag set. + +*`UNDELETED`* - Messages that do not have the \Deleted flag set. + +*`UNDRAFT`* - Messages that do not have the \Draft flag set. + +*`UNFLAGGED`* - Messages that do not have the \Flagged flag set. + +*`UNKEYWORD`* - Messages that do not have the specified keyword flag set. + +*`UNSEEN`* - Messages that do not have the \Seen flag set. + +```C++ +void setSearchCriteria(const String &criteria); +``` + + + + + +**Set to search the unseen message.** + +param *`unseenSearch`* - Boolean flag to enable unseen message search. + +This function will be overridden (omitted) by setFetchUID as setSearchCriteria. + +```C++ +void setSearchUnseenMessage(bool unseenSearch); +``` + + + + + + +**Set the download folder.** + +param *`path`* - Path in SD card. + +All text/html message and attachemnts will be saved to message UID folder which created in defined path + +e.g. *`"/{DEFINED_PATH}/{MESSAGE_UID}/{ATTACHMENT_FILE...}"`*. + +```C++ +void setSaveFilePath(const String &path); +``` + + + + +**Specify message UID to fetch or read.** + +param *`fetchUID`* - The message UID. + +Specify the message UID to fetch (read) only specific message instead of search. + +```C++ +void setFetchUID(const String &fetchUID); +``` + + + + + +**Set storage type to save download attached file or messages.** + +param *`storageType`* - The storage type to save file, MailClientStorageType::SD or MailClientStorageType::SPIFFS + +```C++ +void setFileStorageType(uint8_t storageType); +``` + + + + + + +**Enable/disable attachment download.** + +param *`download`* - Boolean flag to enable/disable attachment download. + +```C++ +void setDownloadAttachment(bool download); +``` + + + +**Enable/disable html message result.** + +param *`htmlFormat`* - Boolean flag to enable/disable html message result. + +The default value is false. + +```C++ +void setHTMLMessage(bool htmlFormat); +``` + + + + +**Enable/disable plain text message result.** + +param *`textFormat`* - Boolean flag to enable/disable plain text message result. + +The default value is true. + +```C++ +void setTextMessage(bool textFormat); +``` + + + + + +**Set the maximum message to search.** + +param *`limit`* - Any number from 0 to 65535. + +The default value is 20. + +```C++ +void setSearchLimit(uint16_t limit); +``` + + + +**Enable/disable recent sort result.** + +param *`recentSort`* - Boolean flag to enable/disable recent message sort result. + +The default value is true. + +```C++ +void setRecentSort(bool recentSort); +``` + + + +**Assign callback function that return status of message fetching or reading.** + +param *`readCallback`* - The function that accept readStatusCallback as parameter. + +```C++ +void setReadCallback(readStatusCallback readCallback); +``` + + + +**Enable/disable attachement download progress while fetching or receiving message.** + +param *`report`* - Boolean flag to enable/disable attachement download progress while fetching or receiving message. + +To get the download status, Callback function should be set via setReadCallback. + +```C++ +void setDownloadReport(bool report); +``` + + + +**Determine only message header is return when search.** + +```C++ +bool isHeaderOnly(); +``` + + + +**Get the sender name/Email for selected message from search result.** + +param *`messageIndex`* - The index of message. + +return *`Sender name/Email String.`* + +```C++ +String getFrom(uint16_t messageIndex); +``` + + + +**Get the sender name/Email charactor encoding.** + +param *`messageIndex`* - The index of message. + +return *`Sender name/Email charactor encoding which use for decoding.`* + +```C++ +String getFromCharset(uint16_t messageIndex); +``` + + + +**Get the recipient name/Email for selected message index from search result.** + +param *`messageIndex`* - The index of message. + +return *`Recipient name/Email String.`* + +```C++ +String getTo(uint16_t messageIndex); +``` + + + + +**Get the recipient name/Email charactor encoding.** + +param *`messageIndex`* - The index of message. + +return *`Recipient name/Email charactor encoding which use in decoding to local language.`* + +```C++ +String getToCharset(uint16_t messageIndex); +``` + + + + +**Get the CC name/Email for selected message index of IMAPData result.** + +param *`messageIndex`* - The index of message. + +return *`CC name/Email String.`* + +```C++ +String getCC(uint16_t messageIndex); +``` + + + +**Get the CC name/Email charactor encoding.** + +param *`messageIndex`* - The index of message. + +return *`CC name/Email charactor encoding which use in decoding to local language.`* + +```C++ +String getCCCharset(uint16_t messageIndex); +``` + + + + +**Get the message subject for selected message index from search result.** + +param *`messageIndex`* - The index of message. + +return *`Message subject name/Email String.`* + +```C++ +String getSubject(uint16_t messageIndex); +``` + + + + +**Get the message subject charactor encoding.** + +param *`messageIndex`* - The index of message. + +return *`Message subject charactor encoding which use in decoding to local language.`* + +```C++ +String getSubjectCharset(uint16_t messageIndex); +``` + + + +**Get the html message for selected message index from search result.** + +param *`messageIndex`* - The index of message. + +return *`The html message String or empty String upon the setHTMLMessage was set.`* + +```C++ +String getHTMLMessage(uint16_t messageIndex); +``` + + + +**Get the plain text message for selected message index from search result.** + +param *`messageIndex`* - The index of message. + +return *`The plain text message String or empty String upon the setTextMessage was set.`* + +```C++ +String getTextMessage(uint16_t messageIndex); +``` + + +**Get the html message charactor encoding.** + +param *`messageIndex`* - The index of message. + +return *`Html message charactor encoding which use in decoding to local language.`* + +```C++ +String getHTMLMessgaeCharset(uint16_t messageIndex); +``` + + + + +**Get the text message charactor encoding.** + +param *`messageIndex`* - The index of message. + +return *`The text message charactor encoding which use in decoding to local language.`* + +```C++ +String getTextMessgaeCharset(uint16_t messageIndex); +``` + + + + +**Get the date of received message for selected message index from search result.** + +param *`messageIndex`* - The index of message. + +return *`The date String.`* + +```C++ +String getDate(uint16_t messageIndex); +``` + + + + +**Get the message UID for selected message index from search result.** + +param *`messageIndex`* - The index of message. + +return *`UID String that can be use in setFetchUID.`* + +```C++ +String getUID(uint16_t messageIndex); +``` + + + + +**Get the message number for selected message index from search result.** + +param *`messageIndex`* - The index of message. + +return *`The message number which vary upon search criteria and sorting.`* + +```C++ +String getNumber(uint16_t messageIndex); +``` + + + + +**Get the message ID for selected message index from search result.** + +param *`messageIndex`* - The index of message. + +return *`The message ID String.`* + +```C++ +String getMessageID(uint16_t messageIndex); +``` + + + + +**Get the accept language for selected message index from search result.** + +param *`messageIndex`* - The index of message. + +return *`The accept language String.`* + +```C++ +String getAcceptLanguage(uint16_t messageIndex); +``` + + + +**Get the content language of text or html for selected message index from search result.** + +param *`messageIndex`* - The index of message. + +return *`The content language String.`* + +```C++ +String getContentLanguage(uint16_t messageIndex); +``` + + + + +**Determine fetch error status for selected message index from search result.** + +param *`messageIndex`* - The index of message. + +return *`Fetch error status.`* + +```C++ +bool isFetchMessageFailed(uint16_t messageIndex); +``` + + + +**Get fetch error reason for selected message index from search result.** + +param *`messageIndex`* - The index of message. + +return *`Fetch error reason String for selected message index.`* + +```C++ +String getFetchMessageFailedReason(uint16_t messageIndex); +``` + + + + +**Determine the attachment download error for selected message index from search result.** + +param *`messageIndex`* - The index of message. + +return *`Fetch status.`* + +```C++ +bool isDownloadAttachmentFailed(uint16_t messageIndex, size_t attachmentIndex); +``` + + + + +**Get the attachment download error reason for selected message index from search result.** + +param *`messageIndex`* - The index of message. + +return *`Download error reason String for selected message index.`* + +```C++ +String getDownloadAttachmentFailedReason(uint16_t messageIndex, size_t attachmentIndex); +``` + + + +**Determine the downloaded/saved text message error status for selected message index from search result.** + +param *`messageIndex`* - The index of message. + +return *`Text message download status.`* + +```C++ +bool isDownloadMessageFailed(uint16_t messageIndex); +``` + + + + + +**Get the attachment or message downloadeds error reason for selected message index from search result.** + +param *`messageIndex`* - The index of message. + +return *`Downloaded error reason String for selected message index.`* + +```C++ +String getDownloadMessageFailedReason(uint16_t messageIndex); +``` + + + + +**Assign the download and decode flags for html message download.** + +param *`download`* - Boolean flag to enable/disable message download. + +return *`decoded`* - Boolean flag to enable/disable html message decoding (support utf8 and base64 encoding). + +```C++ +void saveHTMLMessage(bool download, bool decoded); +``` + + + + +**Assign the download and decode flags for plain text message download.** + +param *`download`* - Boolean flag to enable/disable message download. + +return *`decoded`* - Boolean flag to enable/disable plain text message decoding (support utf8 and base64 encoding). + +```C++ +void saveTextMessage(bool download, bool decoded); +``` + + + + +**Determine the mailbox folder count.** + +return *`Folder count number.`* + +```C++ +uint16_t getFolderCount(); +``` + + + + +**Get the mailbox folder name at selected index.** + +param *`folderIndex`* - Index of folder. + +return *`Folder name String.`* + +Use folder name from this function for fetch or search. + +```C++ +String getFolder(uint16_t folderIndex); +``` + + + +**Determin the number of supported flags count.** + +return *`Flag count number.`* + +```C++ +uint16_t getFlagCount(); +``` + + + + +**Get the flag name for selected index.** + +param *`folderIndex`* - Index of folder. + +return *`Flag name String.`* + +Use flags from this function for fetch or search. + +```C++ +String getFlag(uint16_t flagIndex); +``` + + + + +**Get the number of message in selected mailbox folder.** + +return *`Total message number.`* + +```C++ +size_t totalMessages(); +``` + + + + +**Get the number of message from search result.** + +return *`Search result number.`* + +```C++ +size_t searchCount(); +``` + + + + +**Get the number of message available from search result which less than search limit.** + +return *`Available message number.`* + +```C++ +size_t availableMessages(); +``` + + + + + +**Get the number of attachments for selected message index from search result.** + +param *`messageIndex`* - Index of message. + +return *`Number of attachments`* + +```C++ +size_t getAttachmentCount(uint16_t messageIndex); +``` + + + + + +**Get file name of attachment for selected attachment index and message index from search result.** + +param *`messageIndex`* - Index of message. + +param *`attachmentIndex`* - Index of attachment. + +return *`The attachment file name String at the selected index.`* + +```C++ +String getAttachmentFileName(size_t messageIndex, size_t attachmentIndex); +``` + + + + +**Get the name of attachment for selected attachment index and message index from search result.** + +param *`messageIndex`* - Index of message. + +param *`attachmentIndex`* - Index of attachment. + +return *`The attachment name String at the selected index.`* + +```C++ +String getAttachmentName(size_t messageIndex, size_t attachmentIndex); +``` + + + + +**Get attachment file size for selected attachment index and message index from search result.** + +param *`messageIndex`* - Index of message. + +param *`attachmentIndex`* - Index of attachment. + +return *`The attachment file size in byte at the selected index.`* + +```C++ +int getAttachmentFileSize(size_t messageIndex, size_t attachmentIndex); +``` + + + + +**Get creation date of attachment for selected attachment index and message index from search result.** + +param *`messageIndex`* - Index of message. + +param *`attachmentIndex`* - Index of attachment. + +return *`The attachment creation date String at the selected index.`* + +```C++ +String getAttachmentCreationDate(size_t messageIndex, size_t attachmentIndex); +``` + + + + +**Get attachment file type for selected attachment index and message index from search result.** + +param *`messageIndex`* - Index of message. + +param *`attachmentIndex`* - Index of attachment. + +return *`File MIME String at the selected index`* e.g. image/jpeg. + +```C++ +String getAttachmentType(size_t messageIndex, size_t attachmentIndex); +``` + + + + +**Clear IMAPData object data.** + +```C++ +void empty(); +``` + + + + +### SMTPData object call for sending Email. + + +**Set SMTP server login credentials** + +param *`host`* - SMTP server e.g. smtp.gmail.com + +param *`port`* - SMTP port. + +param *`loginEmail`* - The account Email. + +param *`loginPassword`* - The account password. + +param *`rootCA`* - Root CA certificate base64 string + +```C++ +void setLogin(const String &host, uint16_t port, const String &loginEmail, const String &loginPassword); + +void setLogin(const String &host, uint16_t port, const String &loginEmail, const String &loginPassword, const char *rootCA); + +``` + + + + + +**Set STARTTLS mode to enable STARTTLS protocol.** + +param *`starttls`* - bool flag that enables STARTTLS mode + +```C++ +void setSTARTTLS(bool starttls); +``` + + + + + + +**Set debug print to serial.** + +param *`debug`* - bool flag to enable debug + +```C++ +void setDebug(bool debug); +``` + + + + + + +**Set Sender info** + +param *`fromName`* - Sender's name + +param *`senderEmail`* - Sender's Email. + +```C++ +void setSender(const String &fromName, const String &senderEmail); +``` + + + + + +**Get Sender's name** + +return *`Sender's name String.`* + +```C++ +String getFromName(); +``` + + + + + +**Get Sender's Email.** + +return *`Sender's Email String.`* + +```C++ +String getSenderEmail(); +``` + + + + +**Set Email priority or importance** + +param *`priority`* - Number from 1 to 5, 1 for highest, 3 for normal and 5 for lowest priority + +```C++ +void setPriority(int priority); +``` + + + + + +**Set Email priority or importance.** + +param *`priority`* - String (High, Normal or Low) + +```C++ +void setPriority(const String &priority); +``` + + + + +**Get Email priority** + +return *`Number`* represents Email priority (1 for highest, 3 for normal, 5 for low priority). + +```C++ +uint8_t getPriority(); +``` + + + + +**Add one or more recipient** + +param *`email`* - Recipient Email String of one recipient. + +To add multiple recipients, call addRecipient for each recipient. + +```C++ +void addRecipient(const String &email); +``` + + + + +**Remove recipient** + +param *`email`* - Recipient Email String. + +```C++ +void removeRecipient(const String &email); +``` + + + + +**Remove recipient** + +param *`index`* - Index of recipients in Email object that previously added. + +```C++ +void removeRecipient(uint8_t index); +``` + + + + +**Clear all recipients** +```C++ +void clearRecipient(); +``` + + + + +**Get one recipient** + +param *`index`* - Index of recipients. + +return *`Recipient Email`* String at the index. + +```C++ +String getRecipient(uint8_t index); +``` + + + + + +**Get number of recipients** + +return *`Number`* of recipients. + +```C++ +uint8_t recipientCount(); +``` + + + + +**Set the Email subject.** + +param *`subject`* - The subject. + +```C++ +void setSubject(const String &subject); +``` + + + + +**Get the Email subject.** + +return *`Subject String.`* + +```C++ +String getSubject(); +``` + + + + +**Set the Email message** + +param *`message`* - The message can be in normal text or html format. + +param *`htmlFormat`* - The html format flag, True for send the message as html format + +```C++ +void setMessage(const String &message, bool htmlFormat); +``` + + + + +**Get the message** + +return *`Message String.`* + +```C++ +String getMessage(); +``` + + + + +**Determine message is being send in html format.** + +return *`Boolean`* status. + +```C++ +bool htmlFormat(); +``` + + + + + +**Add Carbon Copy (CC) Email.** + +param *`email`* - The CC Email String. + +```C++ +void addCC(const String &email); +``` + + + + + +**Remove specified Carbon Copy (CC) Email** + +param *`email`* - The CC Email String to remove. + +```C++ +void removeCC(const String &email); +``` + + + + + +**Remove specified Carbon Copy (CC) Email** + +param *`index`* - The CC Email index to remove. + +```C++ +void removeCC(uint8_t index); +``` + + + + + +**Clear all Carbon Copy (CC) Emails** + +```C++ +void clearCC(); +``` + + + + + +**Get Carbon Copy (CC) Email at specified index.** + +param *`index`* - The CC Email index to get. +return *`The CC Email string`* at the index. + +```C++ +String getCC(uint8_t index); +``` + + + + + +**Get the number of Carbon Copy (CC) Email.** + +return *`Number`* of CC Emails. + +```C++ +uint8_t ccCount(); +``` + + + + + +**Add Blind Carbon Copy (BCC) Email** + +param *`email`* - The BCC Email String. + +```C++ +void addBCC(const String &email); +``` + + + + + +**Remove specified Blind Carbon Copy (BCC) Email** + +param *`email`* - The BCC Email String to remove. + +```C++ +void removeBCC(const String &email); +``` + + + + + +**Remove specified Blind Carbon Copy (BCC) Email** + +param *`index`* - The BCC Email index to remove. + +```C++ +void removeBCC(uint8_t index); +``` + + + + + + +**Clear all Blind Carbon Copy (BCC) Emails** + +```C++ +void clearBCC(); +``` + + + + + +**Get Blind Carbon Copy (BCC) Email at specified index.** + +param *`index`* - The BCC Email index to get. + +return *`The BCC Email string`* at the index. + +```C++ +String getBCC(uint8_t index); +``` + + + + + +**Get the number of Blind Carbon Copy (BCC) Email** + +return *`Number`* of BCC Emails. + +```C++ +uint8_t bccCount(); +``` + + + + + +**Add attchement data (binary) from internal memory (flash or ram).** + +param *`fileName`* - The file name String that recipient can be saved. + +param *`mimeType`* - The MIME type of file (image/jpeg, image/png, text/plain...). Can be empty String. + +param *`data`* - The byte array of data (uint8_t). + +param *`size`* - The data length in byte. + +```C++ +void addAttachData(const String &fileName, const String &mimeType, uint8_t *data, uint16_t size); +``` + + + + + +**Remove specified attachment data.** + +param *`fileName`* - The file name of the attachment data to remove. + +```C++ +void removeAttachData(const String &fileName); +``` + + + + + +**Remove specified attachment data.** + +param *`index`* - The index of the attachment data (count only data type attachment) to remove. + +```C++ +void removeAttachData(uint8_t index); +``` + + + + +**Get the number of attachment data.** + +return *`Number`* of attach data. + +```C++ +uint8_t attachDataCount(); +``` + + + +**Add attchement file from SD card** + +param *`fileName`* - The file name String that recipient can be saved. + +param *`mimeType`* - The MIME type of file (image/jpeg, image/png, text/plain...). Can be omitted. + +```C++ +void addAttachFile(const String &filePath, const String &mimeType = ""); +``` + + + + +**Remove specified attachment file from Email object.** + +param *`fileName`* - The file name of the attachment file to remove. + +```C++ +void removeAttachFile(const String &filePath); +``` + + + + +**Set storage type for all attach files.** + +param *`storageType`* - The storage type to read attach file, MailClientStorageType::SD or MailClientStorageType::SPIFFS. + +```C++ +void setFileStorageType(uint8_t storageType); +``` + + + + + + +**Remove specified attachment file.** + +param *`index`* - The index of the attachment file (count only file type attachment) to remove. + +```C++ +void removeAttachFile(uint8_t index); +``` + + + + +**Clear all attachment data.** + +```C++ +void clearAttachData(); +``` + + + + +**Clear all attachment file.** + +```C++ +void clearAttachFile(); +``` + + + + +**Clear all attachments (both data and file type attachments).** + +```C++ +void clearAttachment(); +``` + + + + +**Get number of attachments (both data and file type attachments).** + +return *`Number`* of all attachemnts. + +```C++ +uint8_t attachFileCount(); +``` + + + + + +**Add one or more custom message header field.** + +param *`field`* - custom header String inform of FIELD: VALUE + +This header field will add to message header. + +```C++ +void addCustomMessageHeader(const String &field); +``` + + + + + + +**Remove one custom message header field that previously added..** + +param *`field`* - custom custom message header field String to remove. + +```C++ +void removeCustomMessageHeader(const String &field); +``` + + + + + +**Remove one custom message header field that previously added by its index.** + +param *`index`* - custom message header field index (number) to remove. + + +```C++ +void removeCustomMessageHeader(uint8_t index); +``` + + + + + +**Clear all ccustom message header field that previously added.** + +```C++ +void clearCustomMessageHeader(); +``` + + + + + + +**Get the number of custom message header field that previously added.** + +return *`Number`* of custom message header field. + +```C++ +uint8_t CustomMessageHeaderCount(); +``` + + + + + + +**Get custom message header field that previously added by index.** + +param *`index`* - The custom message header field index to get. + +return *`The custom message header field string at the index`*. + +```C++ +String getCustomMessageHeader(uint8_t index); +``` + + + + + +**Clear all data from Email object to free memory.** + +```C++ +void empty(); +``` + + + + + +**Set the Email sending status callback function to Email object.** + +param *`sendCallback`* - The callback function that accept the sendStatusCallback param. + +```C++ +void setSendCallback(sendStatusCallback sendCallback); +``` + + + + +__MailClient.Time functions__ + + +**Get the time from NTP server and set to device.** + +param *`gmtOffset`* - The GMT time offset in hour. + +param *`daylightOffset`* - The Daylight time offset in hour. + +return - *`Boolean`* type status indicates the success of operation. + +This requires internet connectivity. + +```C++ +bool setClock(float gmtOffset, float daylightOffset); +``` + + + + + + +**Get the Unix time.** + +return - *`uint32_t`* value of current Unix time. + +```C++ +uint32_t getUnixTime(); +``` + + + + + + +**Get timestamp from defined year, month, date, hour, minute, and second.** + +param *`year`* - Year. +param *`mon`* - Month (1 to 12). +param *`date`* - Date. +param *`hour`* - Hour. +param *`mins`* - Minute. +param *`sec`* - Second. + +return - *`time_t`* value of timestamp. + +```C++ +time_t getTimestamp(int year, int mon, int date, int hour, int mins, int sec); +``` + + + + + + +**Get current year.** + +return - *`int`* value of current year. + +```C++ +int getYear(); +``` + + + + + + +**Get current month.** + +return - *`int`* value of current month. + +```C++ +int getMonth(); +``` + + + + + +**Get current date.** + +return - *`int`* value of current date. + +```C++ +int getDay(); +``` + + + + + + +**Get current day of week.** + +return - *`int`* value of day of week. + +1 for sunday and 7 for saturday + +```C++ +int getDayOfWeek(); +``` + + + + + +**Get current day of week in String.** + +return - *`String`* value of day of week. + +Returns sunday, monday, tuesday, wednesday, thurseday, friday and saturday. + +```C++ +String getDayOfWeekString(); +``` + + + + + + +**Get current hour.** + +return - *`int`* value of current hour (0 to 23). + +```C++ +int getHour(); +``` + + + + + + +**Get current minute.** + +return - *`int`* value of current minute (0 to 59). + +```C++ +int getMin(); +``` + + + + + + +**Get current second.** + +return - *`int`* value of current second (0 to 59). + +```C++ +int getSecond(); +``` + + + + + + + +**Get the total days of current year.** + +return - *`int`* value of total days of current year. + +```C++ +int getNumberOfDayThisYear(); +``` + + + + + + +**Get the total days of from January 1, 1970 to specific date.** + +param *`year`* - Year from 1970. +param *`mon`* - Month (1 to 12). +param *`date`* - Date. + +return - *`int`* value of total days. + +```C++ +int getTotalDays(int year, int month, int day); +``` + + + + + +**Get the day of week from specific date.** + +param *`year`* - Year. +param *`month`* - Month (1 to 12). +param *`day`* - Date. + +return - *`int`* value of day of week. + +1 for sunday and 7 for saturday + +```C++ +int dayofWeek(int year, int month, int day); +``` + + + + + + +**Get the second of current hour.** + +return - *`int`* value of current second. + +```C++ +int getCurrentSecond(); +``` + + + + + +**Get the current timestamp.** + +return - *`uint64_t`* value of current timestamp. + +```C++ +uint64_t getCurrentTimestamp(); +``` + + + + + + +**Get time (year, month, day, hour, minute, and second) from second counted from January 1, 1970.** + +param *`secCount`* - The seconds from January 1, 1970 00.00. +param *`yrs`* - The return year. +param *`months`* - The return month. +param *`days`* - The return day. +param *`hr`* - The return hour. +param *`min`* - The return minute. +param *`sec`* - The return second. + +```C++ +void getTimeFromSec(int secCount, int &yrs, int &months, int &days, int &hr, int &min, int &sec); +``` + + + + + + +## License + +The MIT License (MIT) + +Copyright (c) 2019 K. Suwatchai (Mobizt) + + +Permission is hereby granted, free of charge, to any person returning a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + + + diff --git a/libesp32/ESP32-Mail-Client/examples/Receive_email/Receive_email.ino b/libesp32/ESP32-Mail-Client/examples/Receive_email/Receive_email.ino new file mode 100755 index 000000000..4c3540898 --- /dev/null +++ b/libesp32/ESP32-Mail-Client/examples/Receive_email/Receive_email.ino @@ -0,0 +1,278 @@ +/* + * Created by K. Suwatchai (Mobizt) + * + * Email: k_suwatchai@hotmail.com + * + * Github: https://github.com/mobizt + * + * Copyright (c) 2019 mobizt + * +*/ + + +//To use send Email for Gmail to port 465 (SSL), less secure app option should be enabled. https://myaccount.google.com/lesssecureapps?pli=1 + +//To receive Email for Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + +/* + =========================================================================================================================== + To prevent stack overrun in case of you want to download email attachments in IMAP readMail, + increase the stack size in app_main() in esp32 main.cpp will help by change the stack size from 8192 to any more value + as following + + xTaskCreatePinnedToCore(loopTask, "loopTask", 8192, NULL, 1, &loopTaskHandle, ARDUINO_RUNNING_CORE); + to + xTaskCreatePinnedToCore(loopTask, "loopTask", 16384, NULL, 1, &loopTaskHandle, ARDUINO_RUNNING_CORE); + + For Arduino, file esp32's main.cpp is at C:\Users\USER_NAME\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.1\cores\esp32\main.cpp + And for platformIO, that file is at C:\Users\USER_NAME\.platformio\packages\framework-arduinoespressif32\cores\esp32\main.cpp + =========================================================================================================================== + +*/ + +#include +#include "ESP32_MailClient.h" +#include "SD.h" + +#define WIFI_SSID "YOUR_WIFI_SSID" +#define WIFI_PASSWORD "YOUR_WIFI_PASSWORD" + + + +//The Email Reading data object contains config and data that received +IMAPData imapData; + +//Callback function to get the Email reading status +void readCallback(ReadStatus info); + +//List all files in SD card +void printDirectory(File &dir, int depth); + +void readEmail(); + +unsigned long lastTime = 0; + +void setup() +{ + + Serial.begin(115200); + Serial.println(); + + Serial.print("Connecting to AP"); + + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(200); + } + + Serial.println(""); + Serial.println("WiFi connected."); + Serial.println("IP address: "); + Serial.println(WiFi.localIP()); + + Serial.println(); + + MailClient.sdBegin(); + //MailClient.sdBegin(14,2,15,13); //SCK, MISO, MOSI,SS for TTGO T8 v1.7 or 1.8 + + File dir = SD.open("/"); + + printDirectory(dir, 0); + + Serial.println(); + + imapData.setLogin("imap.gmail.com", 993, "YOUR_EMAIL_ACCOUNT@gmail.com", "YOUR_EMAIL_PASSWORD"); + imapData.setFolder("INBOX"); + + //Clear fetch UID + //If fetch UID was set, no search is perform. + imapData.setFetchUID(""); + + //imapData.setSearchCriteria("UID SINCE 10-Feb-2019"); + //imapData.setSearchCriteria("UID 700:*"); + //imapData.setSearchCriteria("UID SEARCH NOT SEEN"); + //imapData.setSearchCriteria("UID SEARCH UNSEEN"); + imapData.setSearchCriteria("UID SEARCH ALL"); + + //To fetch or read one message UID = 320 + //imapData.setFechUID("320"); + + //Set SD folder to save download messages and attachments + imapData.setSaveFilePath("/email_data"); + + //Save attachament + imapData.setDownloadAttachment(true); + + //Set fetch/search result to return html message + imapData.setHTMLMessage(true); + + //Set fetch/search result to return text message + imapData.setTextMessage(true); + + //Set to save html message in SD card with decoded content. + imapData.saveHTMLMessage(true, true); + + //Set to save text message in SD card with decoded content. + imapData.saveTextMessage(true, true); + + //Set the maximum result when search criteria was set. + imapData.setSearchLimit(10); + + //Set the sort order of returning message upon most recent received email. + imapData.setRecentSort(true); + + //Set the return tex/html message size in byte. + imapData.setMessageBufferSize(200); + + //Set the maximum attachment size 5 MB (each file) + imapData.setAttachmentSizeLimit(1024 * 1024 * 5); + + //Set the Email receive callback function. + imapData.setReadCallback(readCallback); + + //Set to get attachment downloading progress status. + imapData.setDownloadReport(true); + + //Set the storage types to save download attachments or messages (SD is default) + //imapData.setFileStorageType(MailClientStorageType::SPIFFS) + imapData.setFileStorageType(MailClientStorageType::SD); + + MailClient.readMail(imapData); +} + +void readEmail() +{ + + Serial.println(); + Serial.println("Read Email..."); + + imapData.setFetchUID("10"); + imapData.setSearchCriteria(""); + MailClient.readMail(imapData); + + imapData.setFetchUID("11"); + imapData.setSearchCriteria(""); + MailClient.readMail(imapData); + + imapData.setFetchUID("12"); + imapData.setSearchCriteria(""); + MailClient.readMail(imapData); +} + +void loop() +{ + + if (millis() - lastTime > 1000 * 60 * 3) + { + + lastTime = millis(); + Serial.println(ESP.getFreeHeap()); + + readEmail(); + } +} + +//Callback function to get the Email reading status +void readCallback(ReadStatus msg) +{ + //Print the current status + Serial.println("INFO: " + msg.info()); + + if (msg.status() != "") + Serial.println("STATUS: " + msg.status()); + + //Show the result when reading finished + if (msg.success()) + { + + for (int i = 0; i < imapData.availableMessages(); i++) + { + Serial.println("================="); + + //Search result number which varied upon search crieria + Serial.println("Messsage Number: " + imapData.getNumber(i)); + + //UID only available when assigned UID keyword in setSearchCriteria + //e.g. imapData.setSearchCriteria("UID SEARCH ALL"); + Serial.println("Messsage UID: " + imapData.getUID(i)); + Serial.println("Messsage ID: " + imapData.getMessageID(i)); + Serial.println("Accept Language: " + imapData.getAcceptLanguage(i)); + Serial.println("Content Language: " + imapData.getContentLanguage(i)); + Serial.println("From: " + imapData.getFrom(i)); + Serial.println("From Charset: " + imapData.getFromCharset(i)); + Serial.println("To: " + imapData.getTo(i)); + Serial.println("To Charset: " + imapData.getToCharset(i)); + Serial.println("CC: " + imapData.getCC(i)); + Serial.println("CC Charset: " + imapData.getCCCharset(i)); + Serial.println("Date: " + imapData.getDate(i)); + Serial.println("Subject: " + imapData.getSubject(i)); + Serial.println("Subject Charset: " + imapData.getSubjectCharset(i)); + + //If setHeaderOnly to false; + if (!imapData.isHeaderOnly()) + { + Serial.println("Text Message: " + imapData.getTextMessage(i)); + Serial.println("Text Message Charset: " + imapData.getTextMessgaeCharset(i)); + Serial.println("HTML Message: " + imapData.getHTMLMessage(i)); + Serial.println("HTML Message Charset: " + imapData.getHTMLMessgaeCharset(i)); + if (imapData.isFetchMessageFailed(i)) + Serial.println("Fetch Error: " + imapData.getFetchMessageFailedReason(i)); + + if (imapData.isDownloadMessageFailed(i)) + Serial.println("Save Content Error: " + imapData.getDownloadMessageFailedReason(i)); + + if (imapData.getAttachmentCount(i) > 0) + { + + Serial.println("**************"); + Serial.println("Attachment: " + String(imapData.getAttachmentCount(i)) + " file(s)"); + + for (int j = 0; j < imapData.getAttachmentCount(i); j++) + { + Serial.println("File Index: " + String(j + 1)); + Serial.println("Filename: " + imapData.getAttachmentFileName(i, j)); + Serial.println("Name: " + imapData.getAttachmentName(i, j)); + Serial.println("Size: " + String(imapData.getAttachmentFileSize(i, j))); + Serial.println("Type: " + imapData.getAttachmentType(i, j)); + Serial.println("Creation Date: " + imapData.getAttachmentCreationDate(i, j)); + if (imapData.isDownloadAttachmentFailed(i, j)) + Serial.println("Download Attachment Error: " + imapData.getDownloadAttachmentFailedReason(i, j)); + } + } + } + + Serial.println(); + } + } +} + +//List all files in SD card +void printDirectory(File &dir, int depth) +{ + while (true) + { + File entry = dir.openNextFile(); + if (!entry) + break; + + for (uint8_t i = 0; i < depth; i++) + Serial.print("| "); + + std::string name = entry.name(); + if (entry.isDirectory()) + { + Serial.print("+----" + String(name.substr(name.find_last_of("/\\") + 1).c_str()) + "\r\n"); + printDirectory(entry, depth + 1); + } + else + { + Serial.print("+--" + String(name.substr(name.find_last_of("/\\") + 1).c_str())); + Serial.print("\t\t\t("); + Serial.print(entry.size(), DEC); + Serial.println(")"); + } + entry.close(); + } +} diff --git a/libesp32/ESP32-Mail-Client/examples/Send_email/Send_email.ino b/libesp32/ESP32-Mail-Client/examples/Send_email/Send_email.ino new file mode 100755 index 000000000..4d4a5b1aa --- /dev/null +++ b/libesp32/ESP32-Mail-Client/examples/Send_email/Send_email.ino @@ -0,0 +1,180 @@ + + +/* + * Created by K. Suwatchai (Mobizt) + * + * Email: k_suwatchai@hotmail.com + * + * Github: https://github.com/mobizt + * + * Copyright (c) 2019 mobizt + * +*/ + + +//To use send Email for Gmail to port 465 (SSL), less secure app option should be enabled. https://myaccount.google.com/lesssecureapps?pli=1 + +//To receive Email for Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + + +#include +#include "ESP32_MailClient.h" +#include "SD.h" + +//For demo only +#include "image.h" + +#define WIFI_SSID "YOUR_WIFI_SSID" +#define WIFI_PASSWORD "YOUR_WIFI_PASSWORD" + + +//The Email Sending data object contains config and data to send +SMTPData smtpData; + +//Callback function to get the Email sending status +void sendCallback(SendStatus info); + +void setup() +{ + + Serial.begin(115200); + Serial.println(); + + Serial.print("Connecting to AP"); + + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(200); + } + + Serial.println(""); + Serial.println("WiFi connected."); + Serial.println("IP address: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + + Serial.println("Mounting SD Card..."); + + if (SD.begin()) // MailClient.sdBegin(14,2,15,13) for TTGO T8 v1.7 or 1.8 + { + + Serial.println("Preparing attach file..."); + + File file = SD.open("/text_file.txt", FILE_WRITE); + file.print("Hello World!\r\nHello World!"); + file.close(); + + file = SD.open("/binary_file.dat", FILE_WRITE); + + static uint8_t buf[512]; + + buf[0] = 'H'; + buf[1] = 'E'; + buf[2] = 'A'; + buf[3] = 'D'; + file.write(buf, 4); + + size_t i; + memset(buf, 0xff, 512); + for (i = 0; i < 2048; i++) + { + file.write(buf, 512); + } + + buf[0] = 'T'; + buf[1] = 'A'; + buf[2] = 'I'; + buf[3] = 'L'; + file.write(buf, 4); + + file.close(); + } + else + { + Serial.println("SD Card Monting Failed"); + } + + Serial.println(); + + + Serial.println("Sending email..."); + + //Set the Email host, port, account and password + smtpData.setLogin("outlook.office365.com", 587, "YOUR_EMAIL_ACCOUNT@outlook.com", "YOUR_EMAIL_PASSWORD"); + + //For library version 1.2.0 and later which STARTTLS protocol was supported,the STARTTLS will be + //enabled automatically when port 587 was used, or enable it manually using setSTARTTLS function. + //smtpData.setSTARTTLS(true); + + //Set the sender name and Email + smtpData.setSender("ESP32", "SOME_EMAIL_ACCOUNT@SOME_EMAIL.com"); + + //Set Email priority or importance High, Normal, Low or 1 to 5 (1 is highest) + smtpData.setPriority("High"); + + //Set the subject + smtpData.setSubject("ESP32 SMTP Mail Sending Test"); + + //Set the message - normal text or html format + smtpData.setMessage("
    Hello World! - From ESP32
    ", true); + + //Add recipients, can add more than one recipient + smtpData.addRecipient("SOME_RECIPIENT@SOME_MAIL.com"); + + + + //Add attachments, can add the file or binary data from flash memory, file in SD card + //Data from internal memory + smtpData.addAttachData("firebase_logo.png", "image/png", (uint8_t *)dummyImageData, sizeof dummyImageData); + + //Add attach files from SD card + //Comment these two lines, if no SD card connected + //Two files that previousely created. + smtpData.addAttachFile("/binary_file.dat"); + smtpData.addAttachFile("/text_file.txt"); + + + //Add some custom header to message + //See https://tools.ietf.org/html/rfc822 + //These header fields can be read from raw or source of message when it received) + smtpData.addCustomMessageHeader("Date: Sat, 10 Aug 2019 21:39:56 -0700 (PDT)"); + //Be careful when set Message-ID, it should be unique, otherwise message will not store + //smtpData.addCustomMessageHeader("Message-ID: "); + + //Set the storage types to read the attach files (SD is default) + //smtpData.setFileStorageType(MailClientStorageType::SPIFFS); + smtpData.setFileStorageType(MailClientStorageType::SD); + + + + smtpData.setSendCallback(sendCallback); + + //Start sending Email, can be set callback function to track the status + if (!MailClient.sendMail(smtpData)) + Serial.println("Error sending Email, " + MailClient.smtpErrorReason()); + + //Clear all data from Email object to free memory + smtpData.empty(); + +} + +void loop() +{ +} + +//Callback function to get the Email sending status +void sendCallback(SendStatus msg) +{ + //Print the current status + Serial.println(msg.info()); + + //Do something when complete + if (msg.success()) + { + Serial.println("----------------"); + } +} + diff --git a/libesp32/ESP32-Mail-Client/examples/Send_email/image.h b/libesp32/ESP32-Mail-Client/examples/Send_email/image.h new file mode 100755 index 000000000..4b8b3542d --- /dev/null +++ b/libesp32/ESP32-Mail-Client/examples/Send_email/image.h @@ -0,0 +1,1074 @@ +#include + +static const uint8_t dummyImageData[] PROGMEM = {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x03, 0x20, 0x00, 0x00, 0x02, 0x58, 0x08, 0x06, 0x00, 0x00, 0x00, 0x9A, 0x76, 0x82, +0x70, 0x00, 0x00, 0x00, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6F, 0x66, 0x74, 0x77, 0x61, 0x72, +0x65, 0x00, 0x41, 0x64, 0x6F, 0x62, 0x65, 0x20, 0x49, 0x6D, 0x61, 0x67, 0x65, 0x52, 0x65, 0x61, +0x64, 0x79, 0x71, 0xC9, 0x65, 0x3C, 0x00, 0x00, 0x42, 0x9A, 0x49, 0x44, 0x41, 0x54, 0x78, 0xDA, +0xEC, 0xDD, 0x7F, 0x90, 0x6C, 0xD9, 0x41, 0xD8, 0xF7, 0xD3, 0xF3, 0xE6, 0xFD, 0xD8, 0xDD, 0xA7, +0xDD, 0xD1, 0xB2, 0x20, 0x88, 0x70, 0x5E, 0x63, 0xB0, 0xB4, 0x20, 0xE1, 0x37, 0x26, 0x50, 0x05, +0x68, 0x57, 0xAF, 0x57, 0x3F, 0xA1, 0x70, 0x15, 0x4A, 0x59, 0x80, 0x88, 0xA9, 0xF8, 0x29, 0x02, +0x1B, 0x12, 0x5C, 0xBB, 0x40, 0x28, 0x48, 0x19, 0x67, 0xA5, 0x42, 0xC6, 0x8A, 0xA3, 0x64, 0xE5, +0x18, 0x63, 0x91, 0x22, 0x48, 0xB8, 0xCA, 0x95, 0xC4, 0x71, 0x2C, 0x1C, 0x40, 0x6F, 0x77, 0xE3, +0x18, 0xA5, 0xE2, 0x3F, 0x53, 0x05, 0x55, 0xB6, 0x14, 0x6C, 0x09, 0xF4, 0x0B, 0xAD, 0x24, 0x76, +0xB5, 0xDA, 0xDD, 0x37, 0x3F, 0x7B, 0xBA, 0xEF, 0x49, 0x9F, 0xDB, 0x7D, 0x7B, 0x6E, 0xFF, 0x98, +0x79, 0x3D, 0x33, 0xDD, 0x3D, 0x7D, 0xBB, 0x3F, 0x9F, 0xD2, 0xCC, 0x9B, 0xD7, 0x33, 0xD3, 0xD3, +0x73, 0x67, 0xDE, 0xD5, 0xF9, 0xEE, 0xE9, 0x73, 0x6E, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0F, 0x35, 0x87, 0x00, +0x58, 0x35, 0xF1, 0xFF, 0xFC, 0xBE, 0x46, 0xEF, 0xCD, 0x17, 0x6A, 0x6F, 0x7E, 0xF2, 0x0F, 0x1D, +0x11, 0x00, 0x10, 0x20, 0x00, 0xD3, 0x8E, 0x8E, 0x9B, 0x9D, 0x3F, 0x1E, 0xED, 0xBC, 0x6C, 0x1E, +0xDE, 0x18, 0x8B, 0xB7, 0x3E, 0xDC, 0x79, 0xF9, 0xAD, 0xDA, 0x5B, 0x9E, 0xFA, 0x98, 0x23, 0x05, +0x00, 0x02, 0x04, 0xE0, 0x2C, 0xE1, 0x51, 0xEF, 0xFC, 0xF1, 0x91, 0x81, 0xF0, 0x18, 0x8C, 0x8F, +0xB2, 0x0F, 0x74, 0x22, 0xE4, 0x67, 0x1C, 0x35, 0x00, 0x10, 0x20, 0x00, 0xA7, 0x89, 0x8F, 0x14, +0x1D, 0xBF, 0xDF, 0x79, 0xD9, 0x08, 0xB1, 0x1D, 0x42, 0xF3, 0xAB, 0x9D, 0x97, 0x17, 0x43, 0x68, +0x37, 0x43, 0xC8, 0x3A, 0x2F, 0x17, 0xEE, 0xEA, 0xBC, 0x5C, 0x09, 0xE1, 0xF2, 0xFD, 0x21, 0xAC, +0xDF, 0x53, 0x7C, 0xDA, 0x87, 0x3B, 0x11, 0xF2, 0x4E, 0x47, 0x0F, 0x00, 0x04, 0x08, 0xC0, 0x49, +0x03, 0xE4, 0x0F, 0x42, 0x9A, 0xF9, 0xD8, 0x7F, 0x2E, 0x84, 0xDD, 0x2F, 0x87, 0x3C, 0x42, 0xC6, +0xCF, 0x7C, 0x74, 0x02, 0xE4, 0x6A, 0x08, 0x57, 0xAF, 0x75, 0xCE, 0x8A, 0x17, 0xD2, 0xDF, 0xFE, +0xE3, 0x4E, 0x84, 0xFC, 0xB6, 0x23, 0x08, 0x00, 0x02, 0x04, 0x60, 0xD2, 0xF8, 0xB8, 0xD9, 0xF9, +0xE3, 0x43, 0x61, 0xFB, 0xF3, 0xDD, 0x99, 0x8F, 0xFC, 0xC6, 0x78, 0x87, 0x33, 0x62, 0x27, 0x3E, +0x5E, 0xF6, 0xE7, 0xD3, 0xCC, 0xC8, 0x0B, 0x9D, 0x0F, 0xFE, 0xA6, 0xDA, 0x5B, 0x9E, 0x7E, 0xC1, +0x91, 0x04, 0x80, 0xE9, 0x5A, 0x73, 0x08, 0x80, 0x25, 0xF5, 0x78, 0xD8, 0xFB, 0xF2, 0xE4, 0xF1, +0x91, 0x7F, 0x4C, 0x3B, 0xE4, 0xC1, 0x12, 0x5B, 0x1B, 0x9D, 0xBF, 0x3D, 0xE6, 0x10, 0x02, 0xC0, +0xF4, 0x99, 0x01, 0x01, 0x96, 0x4E, 0xBE, 0xF0, 0x3C, 0x6B, 0x7E, 0x3A, 0xBC, 0xF8, 0x47, 0x93, +0xC7, 0xC7, 0xE1, 0x67, 0x87, 0x70, 0xD7, 0x2B, 0x42, 0xB8, 0xF2, 0x8A, 0x34, 0xFB, 0x61, 0x16, +0x04, 0x00, 0xA6, 0xCC, 0x0C, 0x08, 0xB0, 0x8C, 0xEA, 0x61, 0xEF, 0xB9, 0xD3, 0xC5, 0x47, 0x92, +0x3E, 0x37, 0xB6, 0xCD, 0x82, 0x00, 0x80, 0x00, 0x01, 0x98, 0x48, 0x23, 0xB4, 0xB6, 0x4E, 0x17, +0x1F, 0xF9, 0x9B, 0xED, 0xEE, 0xA2, 0xF5, 0x10, 0x1E, 0x8F, 0x4F, 0xBF, 0xA5, 0xEE, 0x70, 0x02, +0x80, 0x00, 0x01, 0x38, 0xCE, 0xB5, 0xD0, 0xDA, 0x3D, 0x5D, 0x7C, 0x14, 0xD2, 0xCE, 0x59, 0x69, +0xAB, 0xDE, 0xB4, 0x96, 0x04, 0x00, 0x10, 0x20, 0x00, 0x47, 0x3A, 0xD8, 0xAA, 0x9F, 0x29, 0x3E, +0x0A, 0xDD, 0x59, 0x90, 0x9B, 0x66, 0x41, 0x00, 0x40, 0x80, 0x00, 0x1C, 0x2D, 0x6B, 0x6D, 0x9E, +0x39, 0x3E, 0x92, 0xB4, 0x83, 0x56, 0x3B, 0x9F, 0x49, 0xF9, 0x90, 0x83, 0x0A, 0x00, 0x02, 0x04, +0x60, 0x34, 0x29, 0x9E, 0x7E, 0xEB, 0x46, 0xC8, 0xF6, 0x36, 0xCE, 0x1C, 0x1F, 0x85, 0x9D, 0x2F, +0xA6, 0xD7, 0x8D, 0xF8, 0xF4, 0x5B, 0x1A, 0x8E, 0x2E, 0x00, 0x08, 0x10, 0x80, 0x61, 0x9B, 0x77, +0x5E, 0xFF, 0x71, 0x82, 0xC5, 0xE9, 0x69, 0x31, 0x7B, 0x7A, 0x09, 0xD1, 0x5A, 0x10, 0x00, 0x10, +0x20, 0x00, 0x23, 0xEA, 0x21, 0x66, 0xD3, 0x89, 0x8F, 0x42, 0x77, 0x2D, 0x48, 0x23, 0x3E, 0xFD, +0xE6, 0x86, 0xC3, 0x0B, 0x00, 0x02, 0x04, 0x60, 0x30, 0x40, 0xF2, 0x19, 0x8B, 0x29, 0xC5, 0x47, +0xFA, 0x9C, 0x74, 0x7F, 0xDD, 0x2B, 0xAA, 0x5B, 0x0B, 0x02, 0x00, 0x02, 0x04, 0xA0, 0xA4, 0xBD, +0x77, 0x63, 0xAA, 0xF1, 0x51, 0xE8, 0xCE, 0x82, 0xD4, 0xE3, 0xD3, 0x6F, 0xBE, 0xE9, 0x20, 0x03, +0x80, 0x00, 0x01, 0xE8, 0xCA, 0x0E, 0xEA, 0x53, 0x8F, 0x8F, 0xFC, 0x7E, 0x9B, 0xC5, 0x2C, 0x88, +0xB5, 0x20, 0x00, 0x20, 0x40, 0x00, 0x8A, 0x50, 0xD8, 0xAF, 0x4F, 0x3D, 0x3E, 0x0A, 0x69, 0x16, +0x24, 0xB6, 0xD3, 0x2C, 0xC8, 0xBB, 0x1D, 0x68, 0x00, 0x10, 0x20, 0xC0, 0x8A, 0x8B, 0x4F, 0xBF, +0x75, 0x33, 0xB4, 0x9B, 0xB3, 0x89, 0x8F, 0x3C, 0x6E, 0x9A, 0xDD, 0x2B, 0xA4, 0x87, 0xF0, 0x68, +0x27, 0x42, 0x36, 0x1C, 0x71, 0x00, 0x10, 0x20, 0xC0, 0x6A, 0xAB, 0x87, 0xF6, 0xDE, 0x6C, 0xE2, +0xA3, 0xB0, 0xF7, 0x5C, 0x9A, 0x05, 0x49, 0xF1, 0xF1, 0x98, 0xC3, 0x0D, 0x00, 0x02, 0x04, 0x58, +0x6D, 0x9B, 0xDD, 0x2B, 0x97, 0xCF, 0x28, 0x3E, 0xF2, 0x0F, 0x6B, 0x9B, 0x05, 0x01, 0x00, 0x01, +0x02, 0x90, 0xBB, 0x16, 0x62, 0x6B, 0x76, 0xF1, 0x51, 0x48, 0x6B, 0x41, 0xB2, 0x66, 0x8A, 0x8F, +0x27, 0x1C, 0x72, 0x00, 0x10, 0x20, 0xC0, 0xAA, 0x6A, 0xBE, 0x50, 0x9F, 0x79, 0x7C, 0xE4, 0x9F, +0x12, 0x8B, 0x6D, 0x79, 0x6F, 0xC6, 0xA7, 0xDF, 0x5C, 0x77, 0xE0, 0x01, 0x40, 0x80, 0x00, 0x2B, +0x29, 0x6B, 0xCC, 0x25, 0x3E, 0x92, 0xFD, 0xE7, 0xBB, 0x8B, 0xD2, 0x6D, 0xCB, 0x0B, 0x00, 0x02, +0x04, 0x58, 0x3D, 0xF1, 0xE9, 0xB7, 0xD4, 0x7B, 0x41, 0x30, 0xFB, 0xF8, 0x28, 0xEC, 0x3C, 0x93, +0x5E, 0xA7, 0x59, 0x90, 0x86, 0x9F, 0x00, 0x00, 0x08, 0x10, 0x60, 0xB5, 0xD4, 0x43, 0x6B, 0x77, +0x7E, 0xF1, 0x91, 0x34, 0x5F, 0x0C, 0xA1, 0xB5, 0x95, 0xDE, 0x32, 0x0B, 0x02, 0x00, 0x02, 0x04, +0x58, 0x31, 0x9B, 0x21, 0x3B, 0x98, 0x5F, 0x7C, 0x14, 0xBA, 0x6B, 0x41, 0x1A, 0x66, 0x41, 0x00, +0x40, 0x80, 0x00, 0xAB, 0xE5, 0x5A, 0x77, 0x0B, 0xDE, 0x39, 0xC6, 0x47, 0x72, 0xB0, 0x65, 0x16, +0x04, 0x00, 0x04, 0x08, 0xB0, 0x72, 0x5A, 0xDB, 0x9B, 0x73, 0x8F, 0x8F, 0xC2, 0xD6, 0xE7, 0xD3, +0xEB, 0x34, 0x0B, 0x72, 0xD3, 0x0F, 0x02, 0x00, 0x04, 0x08, 0xB0, 0x0A, 0x62, 0x56, 0x3F, 0x97, +0xF8, 0x48, 0xD2, 0xE2, 0xF7, 0xB4, 0x2B, 0x96, 0x59, 0x10, 0x00, 0x10, 0x20, 0xC0, 0x8A, 0x68, +0xEF, 0xD4, 0xCF, 0x25, 0x3E, 0x0A, 0x69, 0x2D, 0x48, 0x8C, 0xF5, 0xF8, 0xD4, 0x9B, 0x6E, 0xFA, +0x61, 0x00, 0x80, 0x00, 0x01, 0x96, 0x58, 0x7C, 0xFA, 0x2D, 0x8D, 0xD0, 0x6E, 0x9E, 0x5F, 0x7C, +0x24, 0xD9, 0x7E, 0x08, 0xFB, 0xCF, 0xA6, 0xB7, 0x9E, 0xE8, 0x44, 0xC8, 0x86, 0x9F, 0x0A, 0x00, +0x08, 0x10, 0x60, 0x79, 0xD5, 0x47, 0x77, 0xC0, 0x9A, 0x63, 0x7C, 0x14, 0x5F, 0x2B, 0x9F, 0x05, +0x69, 0xA7, 0xF8, 0x78, 0xCC, 0x8F, 0x04, 0x00, 0x04, 0x08, 0xB0, 0xCC, 0x01, 0x32, 0xB0, 0x03, +0xD6, 0x39, 0xC4, 0x47, 0xFE, 0x66, 0x3B, 0x84, 0xFD, 0xE7, 0xD2, 0x5B, 0x8F, 0x9A, 0x05, 0x01, +0x00, 0x01, 0x02, 0x2C, 0xAB, 0xAC, 0x75, 0x3D, 0x1F, 0xFC, 0x9F, 0x67, 0x7C, 0x14, 0xF6, 0x9E, +0x2D, 0x66, 0x41, 0x2C, 0x48, 0x07, 0x00, 0x01, 0x02, 0x2C, 0xA5, 0xFE, 0x02, 0xF4, 0x73, 0x8E, +0x8F, 0xFC, 0xE6, 0x4E, 0x08, 0xED, 0x3C, 0x93, 0xDE, 0x7A, 0x2C, 0x3E, 0xF5, 0xA6, 0xBA, 0x1F, +0x0E, 0x00, 0x08, 0x10, 0x60, 0xD9, 0x64, 0xCD, 0xCD, 0x85, 0x88, 0x8F, 0x42, 0xF3, 0xF9, 0xEE, +0xD6, 0xBC, 0x66, 0x41, 0x00, 0x40, 0x80, 0x00, 0xCB, 0x25, 0x3E, 0xFD, 0x96, 0x7A, 0x88, 0xAD, +0xC5, 0x89, 0x8F, 0x42, 0x5A, 0x90, 0x1E, 0xC2, 0x4D, 0xB3, 0x20, 0x00, 0x20, 0x40, 0x80, 0xE5, +0x4A, 0x90, 0x7A, 0x38, 0xD8, 0x5E, 0xAC, 0xF8, 0x48, 0xD2, 0x2C, 0x48, 0x6B, 0x2B, 0xBD, 0xF5, +0x21, 0x3F, 0x23, 0x00, 0x10, 0x20, 0xC0, 0xF2, 0x68, 0xF4, 0x9E, 0xEE, 0xB4, 0x38, 0xF1, 0x51, +0xE8, 0xCE, 0x82, 0x34, 0xE2, 0x53, 0x6F, 0x6C, 0xF8, 0x31, 0x01, 0x80, 0x00, 0x01, 0x96, 0xC3, +0xB5, 0x89, 0x03, 0x64, 0x9E, 0xF1, 0x91, 0xA4, 0x19, 0x90, 0xD6, 0xED, 0xF4, 0x96, 0xB5, 0x20, +0x00, 0x20, 0x40, 0x80, 0xA5, 0xD0, 0xDA, 0xAE, 0x2F, 0x64, 0x7C, 0x14, 0x5F, 0xF3, 0x70, 0x16, +0xE4, 0x6D, 0x7E, 0x58, 0x00, 0x20, 0x40, 0x80, 0xAA, 0xCB, 0x5A, 0x9B, 0x0B, 0x1B, 0x1F, 0xC9, +0xC1, 0x56, 0x08, 0xFB, 0xCF, 0xA7, 0xB7, 0x9E, 0xF0, 0xC3, 0x02, 0x00, 0x01, 0x02, 0x54, 0x58, +0x7C, 0xFA, 0xCD, 0x1B, 0x21, 0xDB, 0xDB, 0x58, 0xD8, 0xF8, 0x28, 0x74, 0x67, 0x41, 0xEA, 0xF1, +0xA9, 0x37, 0xDE, 0xF4, 0x53, 0x03, 0x40, 0x80, 0x00, 0x54, 0xD7, 0x66, 0x68, 0xED, 0x2E, 0x76, +0x7C, 0x24, 0x69, 0x8D, 0x4A, 0x77, 0x16, 0xC4, 0x5A, 0x10, 0x00, 0x04, 0x88, 0x43, 0x00, 0x54, +0x58, 0x3D, 0xC4, 0x6C, 0xB1, 0xE3, 0xA3, 0x90, 0xAE, 0x8E, 0x1E, 0xDB, 0x69, 0x16, 0xE4, 0xDD, +0x7E, 0x6C, 0x00, 0x08, 0x10, 0x80, 0xAA, 0x06, 0x48, 0xF7, 0x5A, 0x1B, 0x8B, 0x1D, 0x1F, 0xF9, +0xFB, 0xDB, 0x21, 0xEC, 0x3D, 0x97, 0xDE, 0x7A, 0xB4, 0x13, 0x21, 0x1B, 0x7E, 0x74, 0x00, 0x08, +0x10, 0x80, 0xAA, 0x69, 0xEF, 0xDD, 0xA8, 0x44, 0x7C, 0x14, 0xF6, 0x9E, 0x4D, 0x21, 0x92, 0xE2, +0xE3, 0x31, 0x3F, 0x3C, 0x00, 0x04, 0x08, 0x40, 0xD5, 0x64, 0xCD, 0x8D, 0xCA, 0xC4, 0x47, 0xFE, +0xB1, 0xED, 0x6E, 0x84, 0x84, 0xF8, 0x68, 0x7C, 0xEA, 0x0D, 0x75, 0x3F, 0x40, 0x00, 0x04, 0x08, +0x40, 0xB5, 0x02, 0x64, 0xB3, 0x32, 0xF1, 0x51, 0xD8, 0xFD, 0x52, 0x11, 0x4E, 0x16, 0xA4, 0x03, +0xB0, 0x92, 0x6A, 0x0E, 0x01, 0x50, 0x45, 0xF1, 0xE9, 0x37, 0x6F, 0x86, 0x9D, 0x67, 0xFE, 0x20, +0xEC, 0x3F, 0x57, 0x9D, 0xF8, 0x28, 0xBE, 0xDE, 0xE5, 0xFB, 0x43, 0xB8, 0xE7, 0xCF, 0xA5, 0xB7, +0xBE, 0xA9, 0xF6, 0xD6, 0x7F, 0xF5, 0x99, 0xCA, 0x1D, 0xFB, 0x27, 0x1B, 0xF5, 0x90, 0xD6, 0xDF, +0x74, 0x7D, 0xA6, 0xF6, 0x7D, 0x1F, 0xFB, 0x8C, 0xDF, 0x48, 0x00, 0x26, 0xB5, 0xEE, 0x10, 0x00, +0x15, 0x55, 0x0F, 0xED, 0xBD, 0xEA, 0xC5, 0x47, 0x92, 0xB6, 0xE4, 0xBD, 0xEB, 0x15, 0x21, 0xAC, +0x5D, 0x4A, 0xB3, 0x20, 0xEF, 0xAC, 0x48, 0x74, 0x14, 0x6B, 0x57, 0xFE, 0x5A, 0x29, 0x3E, 0x8A, +0xF7, 0xA5, 0x00, 0xF9, 0xAD, 0xCE, 0xCB, 0x07, 0x3A, 0x31, 0xF2, 0x82, 0x5F, 0x4D, 0x00, 0x8E, +0xE3, 0x29, 0x58, 0x40, 0x55, 0x6D, 0x86, 0xD6, 0x4E, 0xF5, 0xE2, 0xA3, 0xB0, 0xFD, 0xF9, 0xF4, +0xFA, 0x66, 0x7C, 0xEA, 0x0D, 0x8D, 0x0A, 0xC4, 0xC7, 0xDB, 0x3A, 0x7F, 0x7C, 0x3A, 0x74, 0x9F, +0x36, 0x56, 0x1F, 0x1B, 0x83, 0xDD, 0xF7, 0x7D, 0xBA, 0xF7, 0xB1, 0x00, 0x20, 0x40, 0x80, 0xA5, +0x73, 0x2D, 0x5F, 0xD4, 0x5D, 0xC5, 0xF8, 0x48, 0x0E, 0xB6, 0x42, 0x6F, 0x0B, 0xE1, 0x85, 0x5E, +0x0B, 0xD2, 0x09, 0x8A, 0x9B, 0x9D, 0x3F, 0x3E, 0xD2, 0x79, 0xD9, 0xE8, 0x2F, 0xA2, 0xBF, 0xFD, +0xA9, 0xC1, 0x97, 0xEE, 0xEE, 0x5E, 0xA1, 0xFB, 0x31, 0xF1, 0x23, 0xF1, 0xD6, 0x8D, 0x9B, 0x7E, +0x3D, 0x01, 0x38, 0x8A, 0x35, 0x20, 0x40, 0x25, 0xC5, 0xDF, 0xFD, 0xAE, 0xDF, 0x0F, 0x5B, 0x9F, +0x6D, 0x54, 0x32, 0x3E, 0x0A, 0x17, 0xAF, 0x86, 0xF0, 0xB2, 0x6F, 0x4E, 0x6F, 0x3D, 0x52, 0x7B, +0xEB, 0xBF, 0xFA, 0xD8, 0x02, 0xC6, 0x47, 0xBD, 0xF3, 0xC7, 0x1F, 0xE4, 0x61, 0x91, 0x16, 0xCF, +0x1F, 0x86, 0xC6, 0x98, 0xFF, 0x37, 0xB9, 0x10, 0xC2, 0x95, 0x07, 0x3A, 0x2F, 0x5F, 0x9F, 0xFE, +0x96, 0x9E, 0x86, 0xF5, 0x97, 0x6A, 0xDF, 0xFF, 0x7F, 0x7F, 0xC6, 0x6F, 0x2A, 0x00, 0xC3, 0xCC, +0x80, 0x00, 0x15, 0x2D, 0x90, 0xAC, 0xDA, 0xF1, 0x91, 0x1C, 0xCE, 0x82, 0x3C, 0xB1, 0xA0, 0x47, +0xF9, 0x89, 0x3C, 0x3E, 0xB6, 0x3F, 0xD7, 0xDD, 0xBD, 0xEB, 0xB8, 0x19, 0xA7, 0xD8, 0xEA, 0x7E, +0x4C, 0xFA, 0xD8, 0xF4, 0x39, 0x21, 0x7C, 0xC8, 0x2F, 0x29, 0x00, 0x02, 0x04, 0x58, 0x8E, 0xF6, +0x78, 0xFA, 0xCD, 0x1B, 0x21, 0x3B, 0xA8, 0x76, 0x7C, 0x14, 0xB6, 0xF2, 0xB5, 0x20, 0x9B, 0xF1, +0xA9, 0x37, 0xDC, 0x5C, 0xA8, 0x63, 0xFC, 0x64, 0x23, 0x05, 0xDE, 0xDB, 0xC2, 0xCE, 0x17, 0xBA, +0x8B, 0xE6, 0x27, 0xFD, 0x7E, 0x9B, 0xCF, 0x17, 0x11, 0xD2, 0x88, 0xB7, 0x6E, 0x34, 0xFC, 0xB6, +0x02, 0x20, 0x40, 0x80, 0x65, 0xB0, 0x19, 0xDA, 0xBB, 0xD5, 0x8F, 0x8F, 0x24, 0x6B, 0x16, 0x03, +0xFC, 0x45, 0x5B, 0x0B, 0xF2, 0x78, 0x3E, 0x3B, 0x93, 0x5F, 0x38, 0xF1, 0x84, 0xDF, 0x6F, 0x8A, +0x90, 0x0A, 0xAC, 0x6F, 0x01, 0x40, 0x80, 0x00, 0x9C, 0x20, 0x40, 0x9A, 0xD5, 0x8F, 0x8F, 0xC2, +0xEE, 0x97, 0xD3, 0xEB, 0x7A, 0x7C, 0xF2, 0x91, 0xC7, 0x16, 0xE1, 0xE0, 0xF6, 0x66, 0x3F, 0x1A, +0xF9, 0x53, 0xAA, 0x4E, 0xFB, 0xFD, 0x76, 0x3F, 0xD7, 0x2C, 0x08, 0x00, 0x02, 0x04, 0x58, 0x0A, +0xD7, 0xEE, 0x3C, 0x03, 0x52, 0x91, 0xF8, 0x48, 0xD2, 0x2C, 0x48, 0x77, 0xC0, 0xFE, 0x78, 0x27, +0x42, 0x36, 0x16, 0xE0, 0xF8, 0x76, 0x67, 0x3F, 0x0E, 0xB6, 0x4E, 0xFF, 0xFD, 0xB6, 0xB6, 0xCC, +0x82, 0x00, 0x20, 0x40, 0x80, 0x25, 0xD1, 0xDA, 0xDA, 0x5C, 0x9A, 0xF8, 0x28, 0x3E, 0xBF, 0xBB, +0xC3, 0x54, 0x71, 0xB1, 0xBF, 0x73, 0xD3, 0xBB, 0x8E, 0x47, 0x23, 0x6C, 0x7D, 0xEE, 0xEC, 0xDF, +0xEF, 0xE1, 0x5A, 0x10, 0xD7, 0x06, 0x01, 0x40, 0x80, 0x00, 0x15, 0x16, 0x63, 0x7D, 0xA9, 0xE2, +0x23, 0xFF, 0xA3, 0x1D, 0xC2, 0xFE, 0x73, 0xE9, 0xAD, 0x47, 0xCF, 0x79, 0x16, 0xE4, 0x89, 0x7C, +0x4D, 0x4A, 0xD6, 0x3C, 0xFB, 0xF7, 0x9B, 0xEE, 0xA3, 0xF9, 0x7C, 0xF7, 0x3E, 0x01, 0x40, 0x80, +0x00, 0x95, 0xD5, 0xDA, 0xA9, 0x2F, 0x55, 0x7C, 0x14, 0xD2, 0x2C, 0x48, 0xD6, 0x4C, 0xF1, 0x71, +0x2E, 0x4F, 0x5B, 0xEA, 0x5D, 0x74, 0xB0, 0x7E, 0xF4, 0xDA, 0x8F, 0x53, 0x7C, 0xBF, 0xDD, 0xFB, +0xAA, 0xC7, 0x5B, 0xAF, 0xBF, 0xE9, 0x17, 0x17, 0x00, 0x01, 0x02, 0x54, 0x4E, 0x7C, 0xFA, 0xCD, +0x8D, 0xF1, 0xFF, 0x75, 0xBE, 0xE2, 0xF1, 0x91, 0xDF, 0xD4, 0x2E, 0x16, 0xA4, 0x3F, 0x16, 0x9F, +0x7C, 0xA4, 0x7E, 0x0E, 0x87, 0xF7, 0xF1, 0xA3, 0x67, 0x3F, 0x4E, 0xF9, 0xFD, 0xE6, 0xBB, 0x7C, +0x7D, 0x25, 0x04, 0x6B, 0x41, 0x00, 0x10, 0x20, 0x40, 0x45, 0x6D, 0x8C, 0x0E, 0x90, 0x97, 0x20, +0x3E, 0x0A, 0xCD, 0x7E, 0x00, 0xCC, 0x75, 0xC0, 0x7E, 0xFC, 0xEC, 0xC7, 0x19, 0x8F, 0x6F, 0xF7, +0x22, 0x86, 0x66, 0x41, 0x00, 0x10, 0x20, 0x40, 0x25, 0x6D, 0x86, 0xD6, 0xEE, 0x72, 0xC6, 0x47, +0xA1, 0x3B, 0x0B, 0x72, 0x33, 0x3E, 0xF9, 0xC8, 0xE6, 0x9C, 0xE2, 0xA3, 0xFB, 0xB4, 0xAF, 0x14, +0x0A, 0xB3, 0x88, 0xBB, 0x74, 0x9F, 0xDD, 0xEB, 0x89, 0x3C, 0xD1, 0x89, 0x90, 0x0D, 0xBF, 0xC2, +0x00, 0x02, 0x04, 0xA0, 0x3A, 0xB2, 0xD6, 0xF5, 0xFC, 0xA9, 0x4A, 0xCB, 0x1A, 0x1F, 0xC9, 0xE1, +0x85, 0xFC, 0xE6, 0xB5, 0x78, 0xFB, 0xB1, 0x34, 0x43, 0x31, 0x7A, 0xD1, 0xC1, 0x29, 0x1E, 0xDF, +0x05, 0xD9, 0xE5, 0x0B, 0x00, 0x01, 0x02, 0x70, 0x32, 0xFD, 0x05, 0xE8, 0x4B, 0x1A, 0x1F, 0x85, +0xEE, 0x2C, 0x48, 0x23, 0x3E, 0xF9, 0x48, 0x63, 0x96, 0x87, 0xB3, 0x37, 0xFB, 0xF1, 0x68, 0x2F, +0x10, 0x66, 0x13, 0x1F, 0xF9, 0x6D, 0xED, 0x62, 0x16, 0xE4, 0x51, 0xB3, 0x20, 0x00, 0x02, 0x04, +0xA0, 0x3A, 0xB2, 0xFD, 0xCD, 0xA5, 0x8F, 0x8F, 0xE4, 0xE0, 0xF6, 0xBC, 0x2E, 0xE4, 0xF7, 0x58, +0x3E, 0x33, 0x31, 0x30, 0xFB, 0x31, 0xA3, 0xE3, 0x6B, 0x16, 0x04, 0x00, 0x01, 0x02, 0x54, 0x49, +0x7C, 0xEA, 0x4D, 0xF5, 0xC1, 0xFF, 0x4A, 0xBF, 0xA4, 0xF1, 0x51, 0x3C, 0xCE, 0xED, 0x2F, 0xA4, +0xD7, 0x69, 0x16, 0x64, 0x26, 0x17, 0xF2, 0x1B, 0x3F, 0xFB, 0x31, 0xC3, 0xB8, 0x33, 0x0B, 0x02, +0x80, 0x00, 0x01, 0x2A, 0xA6, 0x1E, 0x0E, 0xB6, 0x56, 0x23, 0x3E, 0x92, 0xF6, 0x6E, 0xC8, 0xB7, +0xC5, 0x9D, 0xDD, 0x5A, 0x90, 0xC7, 0xF3, 0xEB, 0x8E, 0xF4, 0x77, 0xBE, 0x9A, 0xC3, 0xCC, 0x52, +0x77, 0xA1, 0xFB, 0xB9, 0x5D, 0xEB, 0x04, 0x00, 0x01, 0x02, 0x70, 0x12, 0x8D, 0xA3, 0xAF, 0xD0, +0xBD, 0x64, 0xF1, 0x51, 0x1E, 0xB0, 0xA7, 0x0B, 0xF9, 0x3D, 0xF9, 0xC8, 0xCD, 0x69, 0x1E, 0xC8, +0xF8, 0x64, 0xA3, 0x1E, 0xD2, 0x53, 0xA1, 0xE6, 0x19, 0x1F, 0x83, 0xDF, 0xD3, 0x63, 0xF1, 0xD6, +0xEB, 0xEB, 0x7E, 0xA5, 0x01, 0x04, 0x08, 0xC0, 0x22, 0xBB, 0xEF, 0xC4, 0x01, 0x52, 0xE5, 0xF8, +0x48, 0xF2, 0x0B, 0xF9, 0xE5, 0xB3, 0x20, 0x8F, 0x77, 0x22, 0x64, 0x9A, 0x4F, 0x5B, 0x7A, 0xFC, +0xF0, 0xBE, 0xE7, 0xBC, 0xA6, 0x66, 0xFF, 0x7C, 0xAE, 0x75, 0x02, 0x80, 0x00, 0x01, 0x38, 0x99, +0xD6, 0xD6, 0xC9, 0xAE, 0x8B, 0x51, 0xF5, 0xF8, 0x28, 0xEC, 0x7C, 0x21, 0xBF, 0x90, 0x5F, 0x98, +0xD2, 0xE2, 0xED, 0xDE, 0xEC, 0xC7, 0xCD, 0xEE, 0x4C, 0xC4, 0xBC, 0x17, 0xF4, 0xF7, 0x74, 0x67, +0x41, 0x6E, 0x9A, 0x05, 0x01, 0x58, 0x3D, 0xEB, 0x0E, 0x01, 0x50, 0x19, 0x59, 0x6B, 0xF2, 0x00, +0x59, 0x96, 0xF8, 0xC8, 0x3F, 0xA6, 0xB7, 0x78, 0xFB, 0xAE, 0xAF, 0x7F, 0x34, 0x3E, 0xF9, 0xC8, +0x07, 0x6A, 0xDF, 0xF7, 0xFB, 0x2F, 0x9C, 0xF1, 0x81, 0x3E, 0x9E, 0x5F, 0xCC, 0x71, 0xFF, 0x2B, +0xE7, 0x13, 0x1F, 0x49, 0x9A, 0x05, 0xB9, 0xF2, 0xB5, 0x21, 0x5C, 0xB8, 0x92, 0x66, 0x41, 0xDE, +0xE9, 0x97, 0x7B, 0xCC, 0x21, 0xFE, 0xC4, 0x8F, 0xA6, 0x19, 0xAF, 0xB4, 0x01, 0x41, 0x39, 0xD2, +0xFE, 0xB0, 0xF3, 0xF2, 0xB1, 0xDA, 0xB7, 0xFD, 0xCF, 0x2F, 0x38, 0x42, 0x40, 0x55, 0xD5, 0x1C, +0x02, 0xA0, 0x12, 0x83, 0xB1, 0xA7, 0xDE, 0xB4, 0x11, 0xF6, 0xBE, 0xFC, 0xD5, 0xC3, 0x35, 0x0B, +0x2B, 0x12, 0x1F, 0xFD, 0xB3, 0xF5, 0x85, 0x10, 0x36, 0xBE, 0x2D, 0xFD, 0xF9, 0x9E, 0x4E, 0x80, +0xBC, 0xFB, 0xD4, 0x8F, 0xF2, 0xC9, 0x46, 0x8A, 0xB8, 0x3F, 0x08, 0x2F, 0x7D, 0xB2, 0xD8, 0xE6, +0x77, 0xFE, 0xF1, 0x51, 0xB8, 0x78, 0x4F, 0x08, 0x2F, 0xFB, 0x96, 0xF4, 0xD6, 0x23, 0xB5, 0xEF, +0xFF, 0x7F, 0x3E, 0xE6, 0xB7, 0x7C, 0x20, 0x3C, 0xD2, 0xC6, 0x03, 0x37, 0x8F, 0x0C, 0xD2, 0xDA, +0x85, 0x0F, 0x77, 0xDE, 0xFA, 0x19, 0x21, 0x02, 0x54, 0x91, 0xA7, 0x60, 0x01, 0x55, 0xB1, 0x99, +0xFF, 0x57, 0xFB, 0x55, 0x8C, 0x8F, 0x62, 0xD0, 0xD9, 0x8D, 0xAF, 0x47, 0x7B, 0x4F, 0xA1, 0x3A, +0xAD, 0x27, 0x4A, 0xD7, 0x18, 0x39, 0xBF, 0xF8, 0x48, 0xC7, 0x2C, 0xED, 0x68, 0x36, 0x9F, 0x6B, +0x9D, 0x54, 0x29, 0x3E, 0x52, 0x20, 0x7E, 0x7A, 0x20, 0x3E, 0xE2, 0x41, 0x08, 0xD9, 0xCE, 0xE1, +0x56, 0xC9, 0x29, 0x46, 0xBB, 0xEF, 0xFF, 0x74, 0xEF, 0xE3, 0x01, 0x04, 0x08, 0xC0, 0x0C, 0xDC, +0xF9, 0x1A, 0x20, 0xCB, 0x1A, 0x1F, 0x85, 0xF4, 0x34, 0xAC, 0x6C, 0xFF, 0xD4, 0x5B, 0xD8, 0xC6, +0x5B, 0x37, 0x1A, 0x9D, 0xAF, 0xDD, 0x98, 0x68, 0x16, 0x69, 0xD6, 0xF1, 0x51, 0xE8, 0x3E, 0x96, +0x46, 0xBC, 0xF5, 0x70, 0x43, 0x7C, 0xE4, 0x31, 0xF1, 0xFB, 0x9D, 0x97, 0x8D, 0x3C, 0x3A, 0x9A, +0xCF, 0x74, 0x8E, 0xCF, 0xBF, 0xEF, 0xBC, 0x7C, 0xAA, 0xF3, 0xB3, 0xFF, 0xEC, 0xE1, 0xDB, 0xCD, +0x2F, 0x77, 0xA3, 0x24, 0x7D, 0x5C, 0xE7, 0xE3, 0x45, 0x08, 0x20, 0x40, 0x00, 0x66, 0x15, 0x20, +0xC7, 0xFD, 0x57, 0xFB, 0x65, 0x8F, 0x8F, 0xE2, 0xEB, 0x15, 0x8B, 0xB7, 0x4F, 0x37, 0x0B, 0xF2, +0x78, 0x7E, 0x0C, 0x4F, 0x33, 0xFB, 0x31, 0x8B, 0xF8, 0x48, 0xCC, 0x82, 0x8C, 0xC6, 0xC7, 0xC1, +0x73, 0xDD, 0xD0, 0x68, 0xBD, 0x18, 0x46, 0xA2, 0x3B, 0x85, 0x47, 0xEB, 0xF9, 0x4E, 0x90, 0x7C, +0xBA, 0xFB, 0xFE, 0x6E, 0x84, 0x3C, 0xE1, 0xF4, 0x00, 0x08, 0x10, 0x80, 0x69, 0x6B, 0xEF, 0xDD, +0x58, 0xF9, 0xF8, 0x48, 0x0E, 0xB7, 0xB0, 0x3D, 0xD1, 0xA0, 0x33, 0x9F, 0xFD, 0x48, 0xD7, 0x51, +0x39, 0xCD, 0xEC, 0xC7, 0xAC, 0xE2, 0xA3, 0x50, 0x5C, 0xF1, 0x7D, 0x45, 0x67, 0x41, 0x06, 0xE2, +0x23, 0xCD, 0x7A, 0x1C, 0x3C, 0x3B, 0xC1, 0x27, 0xB5, 0xBB, 0x33, 0x24, 0x29, 0x56, 0xD2, 0xB1, +0xFB, 0xC4, 0x8F, 0xBE, 0xCD, 0x49, 0x02, 0x10, 0x20, 0x00, 0xD3, 0xD4, 0xBD, 0x7A, 0xF6, 0x6A, +0xC7, 0x47, 0x61, 0xEB, 0x73, 0xE9, 0xA6, 0xB7, 0xC5, 0x5B, 0x8D, 0x93, 0x0C, 0xD8, 0x9F, 0x08, +0xCD, 0xE7, 0x4F, 0x3E, 0xFB, 0x31, 0xEB, 0xF8, 0xC8, 0xE3, 0x72, 0xE6, 0x57, 0x7C, 0xAF, 0x4E, +0x7C, 0x74, 0x67, 0x35, 0x26, 0x97, 0x62, 0xA5, 0x7D, 0x3B, 0xBD, 0xF5, 0x83, 0x4E, 0x12, 0x80, +0x00, 0x01, 0x98, 0x6A, 0x80, 0xEC, 0x6F, 0x8A, 0x8F, 0xDE, 0x5F, 0x4F, 0xF8, 0xB4, 0xA5, 0x78, +0xEB, 0xC6, 0xCD, 0x90, 0x16, 0xF1, 0x9F, 0x74, 0xF6, 0x63, 0x1E, 0xF1, 0x51, 0xE8, 0x3E, 0xB6, +0xCD, 0x78, 0xEB, 0xE1, 0x9B, 0xE2, 0xE3, 0x84, 0xD2, 0x9A, 0x90, 0x34, 0xBB, 0x05, 0x20, 0x40, +0x00, 0xA6, 0x34, 0x50, 0x7B, 0xEA, 0x4D, 0x9B, 0xA1, 0x7D, 0xB0, 0xBA, 0xF1, 0x11, 0x07, 0xBF, +0x74, 0xFE, 0xD7, 0xCE, 0x80, 0xBD, 0xF3, 0x67, 0x23, 0x9B, 0x6C, 0x16, 0xE4, 0xF1, 0x7C, 0xF6, +0xE3, 0x24, 0x57, 0x91, 0x9F, 0x67, 0x7C, 0xE4, 0x81, 0x79, 0x78, 0xC5, 0x77, 0xF1, 0x71, 0xD2, +0x3B, 0xEB, 0xFC, 0xDB, 0x68, 0xBF, 0x54, 0x77, 0xA6, 0x00, 0x04, 0x08, 0xC0, 0xF4, 0xD4, 0xF3, +0xA7, 0xE9, 0xAC, 0x6A, 0x7C, 0x24, 0xB5, 0xEE, 0xDD, 0xF5, 0xEF, 0xB1, 0xB9, 0xD5, 0x79, 0xC9, +0x07, 0xAD, 0x1F, 0x3A, 0xF6, 0x5E, 0xBA, 0xB3, 0x1F, 0xF5, 0x13, 0xCD, 0x7E, 0xCC, 0x3B, 0x3E, +0x0A, 0xDD, 0xC7, 0x58, 0x5F, 0xF6, 0x59, 0x90, 0xA9, 0xC6, 0x47, 0x71, 0x9C, 0xB3, 0xFD, 0xCE, +0xFD, 0xBE, 0xA3, 0xE1, 0x54, 0x01, 0x08, 0x10, 0x80, 0xE9, 0xD8, 0xEC, 0x07, 0xC8, 0x2A, 0xC6, +0xC7, 0xF0, 0xDD, 0x15, 0x6F, 0xA7, 0xC5, 0xDB, 0x31, 0xD4, 0xB3, 0x8F, 0x36, 0x8E, 0x1B, 0xB0, +0x3F, 0x1E, 0xF6, 0x9F, 0x9D, 0x7C, 0xF6, 0xE3, 0xBC, 0xE2, 0x23, 0x49, 0x8F, 0x71, 0xEF, 0xD9, +0xEE, 0x63, 0x16, 0x1F, 0x27, 0x3B, 0xCE, 0xD9, 0x76, 0x37, 0xD4, 0x01, 0x04, 0x08, 0xC0, 0x54, +0x5C, 0xCB, 0x77, 0xFD, 0x59, 0xC5, 0x35, 0x1F, 0xC5, 0x2D, 0x71, 0xB4, 0x4D, 0x62, 0x67, 0xC0, +0x1E, 0xF7, 0x9F, 0x4F, 0x6F, 0x8F, 0x1D, 0xB0, 0x67, 0xB7, 0x6E, 0xBC, 0xBB, 0x73, 0xDC, 0xEA, +0x61, 0xE7, 0x4B, 0x73, 0x78, 0xDC, 0x53, 0x3A, 0xE6, 0x69, 0x16, 0xA4, 0xF3, 0x98, 0xE3, 0xAD, +0x87, 0xDF, 0x2D, 0x3E, 0x4E, 0x70, 0x9C, 0xB3, 0x03, 0x01, 0x02, 0x08, 0x10, 0x80, 0xA9, 0x69, +0xBE, 0x50, 0x5F, 0xC9, 0xF8, 0xA8, 0x8D, 0xC6, 0x47, 0x2C, 0xBE, 0x44, 0xF1, 0xD2, 0x1B, 0xB0, +0xB7, 0x3F, 0xDA, 0x78, 0x6C, 0x28, 0x3E, 0xD2, 0xAE, 0x61, 0x8F, 0xE6, 0x33, 0x0A, 0x77, 0xBA, +0x80, 0xE3, 0xA2, 0xC4, 0x47, 0xFE, 0xE9, 0xED, 0x62, 0x16, 0xE4, 0xD1, 0x4E, 0x84, 0x6C, 0x88, +0x8F, 0x09, 0x8F, 0x73, 0xF7, 0xC2, 0x84, 0x37, 0x9C, 0x2C, 0x00, 0x01, 0x02, 0x30, 0x95, 0xD1, +0x5B, 0xBB, 0xB1, 0x52, 0xF1, 0xD1, 0x8B, 0x8B, 0x38, 0x66, 0x03, 0xAC, 0xEE, 0xAB, 0x5A, 0xE7, +0x7D, 0xBD, 0x97, 0x56, 0x67, 0xE0, 0xB9, 0x9B, 0x22, 0x23, 0x3C, 0xDE, 0xFE, 0xBD, 0xC6, 0x46, +0xE9, 0x83, 0x1F, 0xEB, 0x1C, 0xB7, 0x8D, 0xB8, 0xF7, 0xEC, 0x8C, 0x1F, 0xF7, 0x34, 0x8F, 0x79, +0xEF, 0xB1, 0xEC, 0xFE, 0x59, 0xFA, 0x99, 0xA7, 0xEF, 0xE5, 0x31, 0xF1, 0x71, 0x82, 0xE3, 0xDC, +0xBE, 0xBD, 0xE1, 0x64, 0x01, 0x08, 0x10, 0x80, 0xB3, 0x0E, 0xB5, 0x9E, 0x7A, 0xE3, 0x46, 0xEF, +0xE9, 0x25, 0xAB, 0x11, 0x1F, 0xC7, 0x7D, 0x44, 0x3E, 0x03, 0x52, 0xEB, 0x7F, 0xA9, 0xD8, 0x8B, +0x94, 0x6C, 0xE7, 0xD9, 0x81, 0x01, 0x7B, 0xFB, 0xA3, 0x37, 0x36, 0x62, 0x9A, 0xFD, 0xD8, 0xED, +0xCE, 0x7E, 0xC4, 0x52, 0xD4, 0x2C, 0x7C, 0x7C, 0x74, 0x83, 0x73, 0x69, 0x66, 0x41, 0xE6, 0x16, +0x1F, 0xF9, 0xBB, 0xB2, 0x4D, 0x67, 0x0C, 0x40, 0x80, 0x00, 0x9C, 0xDD, 0xE6, 0xC0, 0x0E, 0x58, +0xCB, 0x1E, 0x1F, 0xC3, 0xEB, 0xCF, 0xE3, 0x60, 0x7C, 0x14, 0x33, 0x23, 0x87, 0x4F, 0xC3, 0x4A, +0x05, 0xD2, 0x89, 0x8C, 0x4E, 0x6C, 0x74, 0xDE, 0x7C, 0xB4, 0xF5, 0xBB, 0x8D, 0x6E, 0x88, 0xA4, +0x20, 0xB9, 0xD3, 0xEC, 0xC7, 0x22, 0xC6, 0x47, 0x21, 0xCD, 0x82, 0x74, 0x2F, 0x3E, 0x59, 0xD9, +0x59, 0x90, 0xB9, 0xC6, 0x47, 0xFE, 0xEE, 0x83, 0xB4, 0x13, 0x96, 0x08, 0x01, 0x04, 0x08, 0xC0, +0xD9, 0x03, 0x64, 0xD2, 0xEB, 0x57, 0x2C, 0xC7, 0xCC, 0xC7, 0x9D, 0xE2, 0xA3, 0xF8, 0xB2, 0xB1, +0xF3, 0x6A, 0x60, 0x16, 0xA4, 0x9D, 0x0F, 0xD8, 0x3F, 0x12, 0x62, 0xED, 0xD1, 0xB4, 0x43, 0x56, +0xCC, 0x17, 0xEE, 0x8F, 0xDE, 0xE7, 0xC2, 0xC7, 0x47, 0x7E, 0x5B, 0xE7, 0xB1, 0xEF, 0x7C, 0x31, +0xBD, 0xF5, 0x78, 0xBC, 0xF5, 0x70, 0x5D, 0x7C, 0x4C, 0x70, 0x9C, 0xB3, 0xBD, 0xF4, 0xBA, 0xEE, +0x94, 0x01, 0x08, 0x10, 0x80, 0xB3, 0xB9, 0x36, 0xD9, 0x0C, 0xC8, 0x12, 0xC4, 0xC7, 0xD8, 0xA7, +0x48, 0x75, 0xC2, 0x63, 0x4C, 0x7C, 0xA4, 0x57, 0x31, 0x94, 0x66, 0x43, 0xD2, 0x2C, 0xC8, 0xCE, +0x97, 0x42, 0xFB, 0xC5, 0xD8, 0x88, 0xCD, 0xE6, 0x46, 0xDC, 0xFB, 0xEA, 0x40, 0xC0, 0x0C, 0xDC, +0x7D, 0xB6, 0xE0, 0xF1, 0x51, 0xD8, 0xEF, 0x5F, 0x3C, 0xB1, 0x52, 0xDB, 0xF2, 0x9E, 0x4B, 0x7C, +0xE4, 0x1F, 0x76, 0xD0, 0x0D, 0x76, 0x00, 0x01, 0x02, 0x70, 0x06, 0xAD, 0xAD, 0x09, 0x06, 0x54, +0xCB, 0xB3, 0xE6, 0x63, 0x64, 0xF6, 0x23, 0xC4, 0x81, 0x2F, 0x55, 0x9E, 0xF9, 0x08, 0xA5, 0x97, +0x7C, 0x16, 0x64, 0xFB, 0xF9, 0x90, 0x6D, 0x35, 0x43, 0xEB, 0xCB, 0x5F, 0xEC, 0x7D, 0x66, 0x6D, +0xF4, 0x4B, 0xC5, 0x8A, 0xC4, 0x47, 0xA1, 0x3B, 0x0B, 0x72, 0xB3, 0x2A, 0xB3, 0x20, 0xE7, 0x16, +0x1F, 0x79, 0x58, 0xE6, 0x33, 0x20, 0xD7, 0x9D, 0x34, 0x00, 0x01, 0x02, 0x70, 0xB6, 0x41, 0x6A, +0x7D, 0x25, 0xE2, 0x23, 0xDD, 0x5C, 0x1B, 0xBD, 0x2D, 0xF6, 0x6E, 0x8C, 0xF1, 0x30, 0x3E, 0x0E, +0xD7, 0x81, 0xD4, 0xBA, 0x8B, 0xD2, 0x7B, 0x1F, 0x9B, 0xBD, 0xD4, 0x09, 0x93, 0x17, 0x3F, 0x17, +0xB2, 0xE7, 0x9E, 0x0F, 0xB1, 0x15, 0x06, 0x67, 0x3E, 0x4A, 0xB3, 0x26, 0x95, 0x89, 0x8F, 0xA4, +0x42, 0xB3, 0x20, 0xE7, 0x1A, 0x1F, 0xFD, 0x08, 0xD9, 0xAD, 0x3B, 0x69, 0x00, 0x02, 0x04, 0xE0, +0x2C, 0x5A, 0x3B, 0xF5, 0xA5, 0x8F, 0x8F, 0xE1, 0xBB, 0x8E, 0x43, 0x33, 0x21, 0xF1, 0xF0, 0x69, +0x57, 0xFD, 0xA7, 0x62, 0xC5, 0xDA, 0xC0, 0xDB, 0xB1, 0xD5, 0x79, 0xD9, 0xE9, 0xBC, 0xDD, 0xDC, +0xEA, 0x1E, 0xB6, 0xAF, 0xC4, 0x7E, 0xA4, 0x1C, 0x5E, 0x3C, 0x64, 0x1A, 0x87, 0x6E, 0x8E, 0xF1, +0x51, 0xD8, 0xFE, 0xD3, 0xF4, 0x7A, 0xA1, 0x67, 0x41, 0x16, 0x22, 0x3E, 0xF2, 0x4F, 0x6B, 0x79, +0x0A, 0x16, 0x20, 0x40, 0x00, 0x4E, 0x3D, 0x04, 0x7B, 0xEA, 0x8D, 0x8D, 0xDE, 0x7F, 0xFD, 0x5E, +0xEE, 0xF8, 0xB8, 0xC3, 0xEC, 0x47, 0x71, 0xC3, 0xE1, 0x4C, 0x46, 0x6D, 0xE0, 0x82, 0x84, 0xF9, +0xD3, 0xAF, 0x5E, 0x1C, 0xBC, 0xFF, 0xB8, 0xDF, 0x7D, 0x29, 0x1E, 0xF7, 0xD8, 0xB5, 0x20, 0x55, +0x88, 0x8F, 0xA4, 0xD9, 0x19, 0xCC, 0x1F, 0xE4, 0x61, 0xF5, 0x21, 0xF1, 0x71, 0x07, 0xD9, 0x7E, +0xDA, 0x09, 0xAB, 0xEE, 0xEC, 0x01, 0x08, 0x10, 0x80, 0xD3, 0xD9, 0x18, 0x1F, 0x20, 0x4B, 0x78, +0x9D, 0x8F, 0x63, 0x66, 0x3F, 0x8A, 0x99, 0x8F, 0x10, 0x4B, 0x97, 0xF3, 0x28, 0xDF, 0x65, 0x3A, +0x44, 0xCD, 0xD1, 0xAF, 0xD1, 0x4E, 0x51, 0x92, 0xC5, 0xC3, 0x59, 0x90, 0xB2, 0xDA, 0x49, 0x0F, +0xC3, 0x39, 0xC5, 0x47, 0x61, 0x37, 0x5F, 0x0B, 0xD2, 0x88, 0xB7, 0x1E, 0x6E, 0x88, 0x8F, 0xE3, +0x02, 0xC4, 0x4E, 0x58, 0x80, 0x00, 0x01, 0x38, 0x8B, 0xCD, 0xD0, 0xDA, 0x5D, 0xFA, 0xF8, 0x38, +0x6A, 0xF6, 0xA3, 0xBF, 0x08, 0x3D, 0x94, 0x9F, 0x86, 0x55, 0x8A, 0x89, 0x22, 0x4A, 0xB6, 0x8F, +0xD8, 0xCE, 0x77, 0x2F, 0xA6, 0xFF, 0x20, 0x5E, 0xFE, 0xD0, 0xC3, 0x59, 0x90, 0x2A, 0xC5, 0x47, +0x92, 0x66, 0x40, 0xD2, 0x4B, 0x8C, 0x0B, 0xB3, 0x16, 0x64, 0xE1, 0xE2, 0x23, 0xBF, 0x8B, 0x7C, +0x27, 0xAC, 0x86, 0x53, 0x07, 0x20, 0x40, 0x00, 0x4E, 0x23, 0x6B, 0x5D, 0xCF, 0xAF, 0x07, 0xB1, +0xCC, 0xF1, 0x11, 0x8F, 0x9A, 0xFD, 0xE8, 0xBE, 0x23, 0x96, 0xAF, 0x60, 0x1E, 0x6B, 0x83, 0xBB, +0x5F, 0xA5, 0x3F, 0x8E, 0x98, 0xFD, 0x28, 0xEE, 0xB4, 0xFD, 0xD5, 0x38, 0x1A, 0x2E, 0xE5, 0xF0, +0x89, 0x33, 0x38, 0x66, 0xD3, 0x8E, 0x8F, 0xC2, 0xEE, 0x33, 0xF9, 0xE0, 0x3A, 0x7E, 0xF4, 0xA1, +0x73, 0x1F, 0x60, 0x2F, 0x64, 0x7C, 0xE4, 0xFF, 0x66, 0xF2, 0x19, 0x90, 0x6B, 0x4E, 0x1E, 0x80, +0x00, 0x01, 0x38, 0x8D, 0x81, 0x05, 0xE8, 0x4B, 0x18, 0x1F, 0x45, 0x04, 0x0C, 0x07, 0xC9, 0x98, +0x40, 0x89, 0xB1, 0x36, 0x70, 0x7B, 0x7F, 0x46, 0x64, 0x3B, 0x1E, 0xFB, 0xB8, 0xD3, 0x7F, 0x10, +0xCF, 0xB6, 0x0F, 0x1F, 0xD1, 0xC9, 0x66, 0x41, 0x16, 0x28, 0x3E, 0xD2, 0x63, 0x49, 0x33, 0x20, +0xCD, 0x7C, 0xA0, 0x7F, 0xAE, 0xB3, 0x20, 0x0B, 0x1B, 0x1F, 0xFD, 0x08, 0xD9, 0xAF, 0x3B, 0x79, +0x00, 0x02, 0x04, 0xE0, 0x74, 0x03, 0xA9, 0xCD, 0xA5, 0x8E, 0x8F, 0x78, 0xE7, 0x9D, 0xAF, 0x62, +0xB9, 0x1C, 0x86, 0x17, 0x91, 0xEF, 0xA7, 0x41, 0x79, 0xBC, 0xE3, 0xE3, 0xCE, 0xB7, 0xE7, 0x3D, +0x6E, 0x16, 0xA4, 0x0A, 0xF1, 0x51, 0xD8, 0xC9, 0x77, 0xC4, 0x4A, 0xB3, 0x20, 0x37, 0xC5, 0xC7, +0x51, 0xDA, 0x0D, 0x27, 0x0F, 0x40, 0x80, 0x00, 0x9C, 0x74, 0x58, 0xF6, 0xD4, 0x1B, 0xEB, 0xDD, +0xA7, 0x5F, 0x2D, 0x69, 0x7C, 0x1C, 0x15, 0x24, 0x61, 0x30, 0x44, 0x06, 0xD7, 0x83, 0x0C, 0xC5, +0xC8, 0x76, 0x9C, 0xE8, 0x71, 0xA7, 0x6B, 0x82, 0x14, 0xB3, 0x20, 0xFD, 0x47, 0x38, 0x70, 0x55, +0xF5, 0x8A, 0xC4, 0x47, 0x5E, 0x53, 0xCD, 0xEE, 0xB5, 0x41, 0xCE, 0x61, 0x16, 0xA4, 0x1A, 0xF1, +0x91, 0xFA, 0x63, 0xDB, 0x4E, 0x58, 0x80, 0x00, 0x01, 0x38, 0x85, 0x7A, 0x68, 0x6D, 0x2D, 0x67, +0x7C, 0x94, 0x76, 0xB4, 0x1A, 0x78, 0xBB, 0xFC, 0xF7, 0x71, 0xB3, 0x1F, 0xE5, 0x19, 0x93, 0x34, +0xFB, 0xD1, 0x9E, 0xFC, 0x71, 0x17, 0xB3, 0x20, 0xF1, 0x8E, 0xB3, 0x20, 0x0B, 0x1C, 0x1F, 0x85, +0xEE, 0x8E, 0x58, 0xF5, 0x79, 0xCE, 0x82, 0x54, 0x26, 0x3E, 0xF2, 0x3D, 0x99, 0x0F, 0xBA, 0xFF, +0x7E, 0x00, 0x04, 0x08, 0xC0, 0x89, 0x46, 0x52, 0x8D, 0xD0, 0x6E, 0x2E, 0x5F, 0x7C, 0x84, 0xD1, +0xC1, 0x7F, 0xEC, 0x7D, 0xED, 0x71, 0xB3, 0x1C, 0x47, 0x4E, 0x50, 0xEC, 0xC4, 0x13, 0x3D, 0xEE, +0x7C, 0x16, 0xE4, 0xA5, 0xC1, 0xBB, 0x1F, 0x88, 0x9A, 0x58, 0x91, 0xF8, 0xC8, 0x6B, 0x6A, 0xBE, +0xB3, 0x20, 0x95, 0x8A, 0x8F, 0xFC, 0xCF, 0x3C, 0x40, 0x5C, 0x90, 0x10, 0x10, 0x20, 0x00, 0x27, +0x74, 0xDF, 0xD1, 0x17, 0x21, 0xAC, 0x70, 0x7C, 0x0C, 0xAF, 0xE3, 0xE8, 0x0D, 0xFC, 0x63, 0xA8, +0x0D, 0xCC, 0x7C, 0x94, 0x2F, 0x3A, 0x38, 0x32, 0x4B, 0x52, 0x9E, 0xFD, 0x38, 0xC1, 0xE3, 0x6E, +0xDF, 0x8E, 0xBD, 0x67, 0xB5, 0x95, 0x66, 0x41, 0x6A, 0x53, 0x1C, 0x14, 0xCF, 0x23, 0x3E, 0x0A, +0x69, 0x16, 0x24, 0xB6, 0x67, 0x3E, 0x0B, 0x52, 0xB9, 0xF8, 0xC8, 0x7F, 0xD0, 0xF9, 0xF3, 0xED, +0xEC, 0x84, 0x05, 0x08, 0x10, 0x80, 0x13, 0x69, 0x6D, 0x9D, 0xF2, 0xBF, 0xE0, 0x56, 0x2B, 0x3E, +0x62, 0x88, 0x63, 0x9F, 0x92, 0xD5, 0xBF, 0x79, 0x60, 0x1B, 0xDE, 0xCE, 0x4B, 0xD6, 0x79, 0xD9, +0x8A, 0xA7, 0x7B, 0xDC, 0x9D, 0xCF, 0xCD, 0xFA, 0xCF, 0x6A, 0xAB, 0x95, 0xBE, 0x5E, 0x1C, 0xFC, +0xDA, 0x8B, 0x1E, 0x1F, 0xF9, 0xF7, 0xD2, 0x89, 0xD3, 0xBD, 0x67, 0xD3, 0x5B, 0x4F, 0x74, 0x22, +0x64, 0x43, 0x7C, 0x0C, 0x1F, 0x9F, 0x7D, 0x33, 0x20, 0x80, 0x00, 0x01, 0x38, 0xD9, 0x60, 0xB9, +0x75, 0x8A, 0x01, 0x54, 0x85, 0x16, 0x9C, 0x1F, 0x16, 0x48, 0x77, 0xF6, 0x23, 0x0C, 0x46, 0x47, +0x7F, 0xD7, 0xAA, 0xE1, 0x87, 0xB9, 0x5B, 0x2E, 0x93, 0x93, 0x2B, 0x66, 0x41, 0x62, 0x2C, 0x05, +0x50, 0x6D, 0x06, 0x03, 0xE0, 0x79, 0x1C, 0xCF, 0xBD, 0x3F, 0x4B, 0xB3, 0x20, 0x29, 0x3E, 0x1E, +0x13, 0x1F, 0xC3, 0xB7, 0xB7, 0x04, 0x08, 0x20, 0x40, 0x00, 0x26, 0x1E, 0x53, 0x3D, 0xF5, 0x86, +0x8D, 0xD0, 0xDE, 0x3F, 0xE1, 0x7F, 0xD5, 0xAE, 0x46, 0x7C, 0x94, 0x2F, 0x34, 0x38, 0x6E, 0xDB, +0xDD, 0xC3, 0x1B, 0x6B, 0xA3, 0x3B, 0x54, 0x65, 0x45, 0x80, 0x9C, 0xE1, 0x71, 0x77, 0xEE, 0xA3, +0xFD, 0x52, 0x3C, 0x7C, 0x2C, 0xE3, 0xB6, 0xF7, 0x8D, 0xF3, 0x3A, 0x86, 0x67, 0xFD, 0xF9, 0xB5, +0x8B, 0x59, 0x90, 0x47, 0xA7, 0x39, 0x0B, 0x52, 0xF9, 0xF8, 0xC8, 0x7F, 0xCE, 0xFB, 0x1B, 0xF1, +0x13, 0xEF, 0xD8, 0x70, 0x36, 0x01, 0x04, 0x08, 0xC0, 0x64, 0x36, 0x43, 0x7B, 0x77, 0xB9, 0xE2, +0x23, 0x8E, 0xF9, 0xCB, 0xF0, 0x16, 0xBB, 0x21, 0x8C, 0xDD, 0xA9, 0x6A, 0x60, 0xF6, 0x23, 0x3B, +0xFB, 0x60, 0x36, 0xBB, 0x9D, 0xD6, 0x29, 0xC7, 0xC1, 0xF0, 0x38, 0x4D, 0x84, 0x9C, 0x67, 0x7C, +0x14, 0xA6, 0x3C, 0x0B, 0xB2, 0x14, 0xF1, 0x91, 0xBF, 0xBF, 0xD9, 0xFD, 0x77, 0x04, 0x20, 0x40, +0x00, 0x26, 0xD2, 0xBB, 0x06, 0xC8, 0x92, 0xC4, 0xC7, 0xC0, 0x67, 0xC6, 0x23, 0xB7, 0xDD, 0x1D, +0x89, 0x8E, 0x91, 0xD9, 0x8F, 0x6C, 0x6A, 0x03, 0xFE, 0xF6, 0x71, 0xDB, 0xF2, 0xCE, 0xFC, 0x18, +0x4E, 0x71, 0x80, 0x9E, 0x7E, 0x4F, 0xF2, 0x6D, 0x79, 0xE3, 0xA3, 0xF1, 0xA3, 0xAF, 0x3B, 0xD3, +0x7F, 0xF1, 0x5F, 0x9A, 0xF8, 0xC8, 0x7F, 0x5F, 0xF6, 0x05, 0x08, 0x20, 0x40, 0x00, 0x4E, 0x14, +0x20, 0x07, 0x93, 0x5C, 0x03, 0xA4, 0x22, 0xF1, 0x91, 0x3E, 0xAD, 0x36, 0xF4, 0xF9, 0xE5, 0xB5, +0x1F, 0xA5, 0x87, 0x76, 0xE4, 0xEC, 0xC7, 0x56, 0xD6, 0x8D, 0x90, 0x29, 0x0D, 0xF8, 0xD3, 0x85, +0x09, 0xD3, 0xD6, 0xBC, 0xA5, 0x06, 0x1A, 0x9D, 0x05, 0x59, 0xF4, 0xF8, 0x28, 0xA4, 0x59, 0x90, +0xAC, 0x99, 0xE2, 0xE3, 0x09, 0xF1, 0x51, 0x04, 0xC8, 0x5E, 0x7A, 0x6D, 0x27, 0x2C, 0x40, 0x80, +0x00, 0x4C, 0xA4, 0xBD, 0x77, 0x63, 0x69, 0xE2, 0xA3, 0xFF, 0xA5, 0xCB, 0x4F, 0xBB, 0x2A, 0x45, +0x48, 0xF9, 0x42, 0x83, 0xE5, 0x87, 0x59, 0x5E, 0xEA, 0xD1, 0xEE, 0xBC, 0xB1, 0x37, 0x8D, 0x01, +0xED, 0xE0, 0x7D, 0x14, 0x17, 0x27, 0x0C, 0x47, 0xCD, 0x82, 0xC4, 0x0A, 0xC4, 0x47, 0x71, 0x3F, +0x3B, 0x69, 0x5B, 0xDE, 0x70, 0x33, 0xFE, 0xDE, 0xEB, 0xEA, 0x2B, 0x1F, 0x1F, 0xF9, 0xC7, 0xA6, +0x9D, 0x06, 0xDA, 0x66, 0x40, 0x00, 0x01, 0x02, 0x30, 0x59, 0x80, 0x34, 0x37, 0x96, 0x26, 0x3E, +0xF2, 0xD9, 0x8F, 0x38, 0x72, 0x5B, 0x79, 0xED, 0xC7, 0xE1, 0xCE, 0x57, 0xB5, 0xD1, 0x87, 0x99, +0x6E, 0xD8, 0x9E, 0x7E, 0x7C, 0xE4, 0x01, 0x92, 0x66, 0x41, 0xF6, 0x87, 0x3E, 0xE2, 0xB8, 0x59, +0x90, 0x45, 0x8D, 0x8F, 0xF4, 0x47, 0xBA, 0x30, 0x61, 0xF7, 0xBA, 0x31, 0x27, 0xBA, 0x38, 0xE1, +0x52, 0xC6, 0x47, 0xFF, 0x07, 0xBC, 0x5B, 0x77, 0x32, 0x01, 0x04, 0x08, 0xC0, 0x44, 0x03, 0xA7, +0xE3, 0xAE, 0x61, 0x50, 0xBD, 0xAD, 0x76, 0x63, 0x2C, 0x87, 0x47, 0xB9, 0x3A, 0xC6, 0xAC, 0xF5, +0x18, 0x78, 0xC8, 0xB1, 0xFB, 0xB4, 0xAB, 0xBD, 0x29, 0x6C, 0xF7, 0x7B, 0x54, 0xEB, 0xBD, 0xD8, +0x5B, 0x93, 0x32, 0x6E, 0x16, 0xA4, 0x56, 0xFA, 0xD4, 0x45, 0x8E, 0x8F, 0xDE, 0x63, 0x8D, 0xBB, +0x5F, 0x4C, 0x7F, 0xBD, 0x99, 0xFD, 0xEE, 0x64, 0xB3, 0x20, 0x4B, 0x1D, 0x1F, 0xF9, 0xBF, 0xA3, +0xA6, 0x00, 0x01, 0x04, 0x08, 0xC0, 0x1D, 0xC7, 0x5A, 0x4F, 0xBD, 0x61, 0x33, 0x64, 0x07, 0xCB, +0x11, 0x1F, 0x71, 0xCC, 0x35, 0x36, 0x86, 0x77, 0xBE, 0x8A, 0x43, 0xB3, 0x1F, 0xE5, 0x05, 0x19, +0xE9, 0xCF, 0xED, 0xD9, 0xC5, 0x47, 0xFE, 0xDE, 0xFD, 0x62, 0xBD, 0xF2, 0x98, 0xB5, 0x20, 0x55, +0x8A, 0x8F, 0x62, 0x16, 0xE4, 0x60, 0x2B, 0xDD, 0x7C, 0xC7, 0xB5, 0x20, 0x4B, 0x1F, 0x1F, 0xF9, +0xE7, 0x36, 0x3B, 0xDF, 0xE7, 0x3B, 0x1A, 0xCE, 0x2A, 0x80, 0x00, 0x01, 0x38, 0xDE, 0xC6, 0xF8, +0x2D, 0x78, 0x2B, 0x78, 0x91, 0xC1, 0x81, 0x41, 0xFC, 0x11, 0xB3, 0x1F, 0x63, 0x3F, 0xB3, 0xF7, +0x8E, 0xD4, 0x61, 0x7B, 0xB3, 0xFF, 0x1E, 0xD2, 0x2C, 0xC8, 0xD1, 0x6B, 0x41, 0x2A, 0x12, 0x1F, +0xC5, 0x31, 0x4E, 0x3B, 0x62, 0xC5, 0xDA, 0xDB, 0xDA, 0xBF, 0xF3, 0x50, 0x63, 0xA5, 0xE3, 0x23, +0xE9, 0x96, 0x65, 0xDD, 0x29, 0x05, 0x10, 0x20, 0x00, 0xC7, 0x6B, 0x84, 0xD6, 0x6E, 0xF5, 0xE3, +0xA3, 0xBF, 0xF3, 0xD5, 0xF0, 0xCD, 0xC7, 0xCF, 0x7E, 0xE4, 0x8B, 0xD5, 0x8B, 0xA9, 0x88, 0xED, +0xF9, 0x7C, 0x0F, 0xF9, 0x2C, 0xC8, 0xEE, 0x40, 0x1B, 0xF5, 0x5F, 0x4D, 0x67, 0x68, 0x3D, 0xA7, +0xF8, 0x48, 0x7F, 0x36, 0xB7, 0xBB, 0xB3, 0x20, 0x71, 0xFC, 0x5A, 0x90, 0x95, 0x89, 0x8F, 0x3C, +0x40, 0x9A, 0x02, 0x04, 0x10, 0x20, 0x00, 0x13, 0xB8, 0x36, 0x78, 0x0D, 0x90, 0x6A, 0xCE, 0x7C, +0x0C, 0x3C, 0x8C, 0x09, 0x67, 0x3F, 0x06, 0x86, 0xFB, 0x69, 0xF6, 0xE3, 0x20, 0xCE, 0xED, 0x7B, +0xC8, 0x5E, 0x18, 0x9E, 0x05, 0xA9, 0xD8, 0xCC, 0x47, 0xE8, 0x3E, 0xF6, 0xBC, 0xDF, 0xBA, 0x3B, +0x62, 0x35, 0x0E, 0x7E, 0x7B, 0x70, 0x16, 0x64, 0xA5, 0xE2, 0x23, 0xBF, 0x9F, 0xFC, 0xA9, 0x8C, +0x37, 0x9C, 0x52, 0x00, 0x01, 0x02, 0x70, 0x9C, 0xE6, 0x0B, 0xF5, 0x65, 0x88, 0x8F, 0x93, 0xCF, +0x7E, 0x94, 0x66, 0x3E, 0xCE, 0x34, 0xFB, 0x71, 0xBA, 0xCF, 0x4B, 0xD7, 0x04, 0x49, 0xBB, 0x62, +0x95, 0x1A, 0x69, 0xF2, 0xEB, 0x82, 0x2C, 0x52, 0x7C, 0xA4, 0x97, 0xE6, 0x56, 0xC8, 0x9A, 0x69, +0x16, 0xA4, 0xF6, 0xF8, 0xCA, 0xC6, 0x47, 0xA1, 0xBD, 0x55, 0x77, 0x52, 0x01, 0x16, 0xCD, 0xBA, +0x43, 0x00, 0x2C, 0x94, 0x98, 0x35, 0x2A, 0x1F, 0x1F, 0xC3, 0xD7, 0xFA, 0x28, 0x7F, 0xC8, 0xF0, +0xEC, 0x47, 0x2F, 0x3E, 0x06, 0xBE, 0xFA, 0xA9, 0x67, 0x3F, 0xCE, 0xF6, 0x3D, 0xA4, 0xEB, 0x82, +0xAC, 0xDD, 0x53, 0x6A, 0xA7, 0xDA, 0x22, 0x0C, 0xD0, 0x4F, 0x16, 0x1F, 0xC5, 0xF1, 0xCD, 0xB6, +0xBE, 0x10, 0x6A, 0xF7, 0x3D, 0xD8, 0xD8, 0xFF, 0xDF, 0x1F, 0x6E, 0x5C, 0xFA, 0xD6, 0x6F, 0x7C, +0x61, 0x25, 0xE3, 0xA3, 0x5B, 0x96, 0x02, 0x04, 0x58, 0x38, 0x66, 0x40, 0x80, 0xC5, 0x69, 0x8F, +0xA7, 0xDE, 0xB0, 0xD1, 0x7D, 0xDE, 0x7A, 0x85, 0xE3, 0x63, 0xDC, 0xC0, 0x7D, 0xF8, 0xAA, 0xE7, +0xE5, 0xD9, 0x8F, 0xF2, 0x00, 0xBB, 0x78, 0xB9, 0x9D, 0x9D, 0xC3, 0xF7, 0xD0, 0x19, 0xB4, 0x77, +0xA2, 0xA7, 0x7D, 0x7B, 0xE8, 0x1E, 0x4F, 0x35, 0x0B, 0x72, 0xCE, 0xF1, 0x91, 0x75, 0x6E, 0x3B, +0xD8, 0x0D, 0xD9, 0xEE, 0xF3, 0x21, 0x5C, 0xB9, 0xF8, 0xA1, 0x95, 0x8D, 0x8F, 0xFC, 0x7E, 0xD3, +0x4E, 0x58, 0x3F, 0xE2, 0x82, 0x84, 0x80, 0x00, 0x01, 0x38, 0x62, 0x10, 0xB6, 0x39, 0xBA, 0x00, +0xBD, 0x62, 0xF1, 0x11, 0x8F, 0x5E, 0xFB, 0xD1, 0x7F, 0x8A, 0x50, 0x3F, 0x38, 0xE2, 0xE8, 0xB5, +0x40, 0xD2, 0xAE, 0x57, 0xED, 0xF9, 0x0F, 0x8A, 0x8B, 0x2B, 0xB5, 0xE7, 0x3B, 0x62, 0xB5, 0x8F, +0xB8, 0x2E, 0x48, 0x55, 0xE2, 0x23, 0xBD, 0x9D, 0x37, 0xDC, 0x76, 0xB8, 0xF4, 0x1F, 0x7E, 0x6D, +0x7D, 0x65, 0xE3, 0x23, 0x3D, 0xDE, 0xF6, 0x4E, 0x7A, 0xA3, 0xEE, 0xE4, 0x02, 0x08, 0x10, 0x80, +0xF1, 0x36, 0x7B, 0x3B, 0xF7, 0x54, 0x33, 0x3E, 0x8E, 0xF8, 0x90, 0xE1, 0xB5, 0x1F, 0xA1, 0xB4, +0xDC, 0x63, 0xE4, 0xEE, 0x76, 0xE2, 0x9C, 0xBF, 0x87, 0xC3, 0xF8, 0xC8, 0x75, 0x06, 0xEE, 0xC5, +0x2C, 0xC8, 0xC0, 0x5A, 0x90, 0x38, 0xC9, 0x57, 0x5A, 0x9C, 0xF8, 0xA8, 0xDD, 0x73, 0x6F, 0xB8, +0xFC, 0xED, 0xDF, 0x19, 0xC2, 0x85, 0xCE, 0xFF, 0xCD, 0xAD, 0x6A, 0x7C, 0xE4, 0x3F, 0xCF, 0x66, +0xF7, 0xDF, 0x15, 0x80, 0x00, 0x01, 0x18, 0xEB, 0x88, 0x6B, 0x80, 0x54, 0x20, 0x3E, 0xCA, 0x83, +0xF4, 0x81, 0x01, 0x7B, 0x6D, 0x60, 0xED, 0x47, 0x2C, 0x1E, 0x77, 0xF9, 0x62, 0x7F, 0xA7, 0x9E, +0xFD, 0x98, 0x72, 0x7C, 0xF4, 0xB4, 0x6F, 0x77, 0x67, 0x41, 0x06, 0xAE, 0x0B, 0x52, 0x9B, 0xFD, +0x63, 0x99, 0x6A, 0x7C, 0x5C, 0xFF, 0xDE, 0x50, 0x5B, 0xBF, 0xB8, 0xDA, 0xF1, 0x91, 0xBF, 0x99, +0xEF, 0x84, 0x75, 0xDD, 0xA9, 0x05, 0x10, 0x20, 0x00, 0xE3, 0xB4, 0xB6, 0x26, 0xDF, 0x32, 0x74, +0x91, 0x67, 0x3E, 0x6A, 0x83, 0x17, 0x33, 0x2F, 0x07, 0x4A, 0xB1, 0xE0, 0x7C, 0x64, 0xA7, 0xDB, +0x13, 0xCF, 0x7E, 0xCC, 0x26, 0x3E, 0x72, 0xA5, 0x59, 0x90, 0x50, 0xCC, 0xDE, 0x1C, 0x3B, 0x0B, +0x22, 0x3E, 0x16, 0x32, 0x3E, 0xFA, 0x45, 0xB9, 0x53, 0x77, 0x72, 0x01, 0x04, 0x08, 0xC0, 0xF8, +0x41, 0x59, 0x7D, 0xC2, 0x8F, 0x5B, 0xAC, 0xF8, 0x18, 0x5E, 0xA8, 0xDD, 0xFF, 0x7B, 0x6D, 0x60, +0xE6, 0x23, 0xF6, 0x9F, 0x7B, 0x55, 0x1B, 0xDD, 0x0D, 0x6B, 0xE7, 0x24, 0xB3, 0x1F, 0x33, 0x8C, +0x8F, 0x62, 0xCC, 0x9A, 0x66, 0x41, 0x0E, 0x4A, 0x03, 0xFD, 0x5E, 0x10, 0x88, 0x8F, 0x8A, 0xC5, +0x47, 0xF7, 0xA7, 0xE9, 0x29, 0x58, 0x80, 0x00, 0x01, 0x18, 0x3F, 0x4E, 0x9A, 0xE0, 0xBF, 0xD4, +0x56, 0x20, 0x3E, 0x46, 0x66, 0x0C, 0xCA, 0x0B, 0xCE, 0xC3, 0xE1, 0x62, 0xF4, 0xFE, 0x27, 0x66, +0xE1, 0x04, 0xB3, 0x1F, 0xB3, 0x8F, 0x8F, 0x5C, 0x96, 0xC6, 0xEF, 0x71, 0x20, 0xA4, 0x46, 0xBF, +0x57, 0xF1, 0xB1, 0xF8, 0xF1, 0x91, 0x7E, 0x96, 0x7B, 0x76, 0xC2, 0x02, 0x04, 0x08, 0xC0, 0xC8, +0xF0, 0xE9, 0xC9, 0x47, 0x1A, 0xA1, 0xDD, 0xAC, 0x56, 0x7C, 0x1C, 0xF3, 0xA1, 0xFD, 0x6D, 0x77, +0x63, 0x77, 0xE6, 0xE3, 0x70, 0xF0, 0x5C, 0x1B, 0xBD, 0xCB, 0xDD, 0x38, 0xE1, 0xDD, 0xCF, 0x29, +0x3E, 0x8A, 0x71, 0xEB, 0x76, 0xDA, 0x9A, 0x77, 0xA8, 0x0F, 0xE2, 0xD0, 0xFD, 0x9C, 0xF9, 0x21, +0x89, 0x8F, 0x99, 0xC6, 0x47, 0x1E, 0xF6, 0x7B, 0xE9, 0xF5, 0x86, 0xB3, 0x0C, 0x20, 0x40, 0x00, +0x06, 0x6D, 0x1C, 0xBB, 0x03, 0xD6, 0x02, 0xC7, 0xC7, 0x51, 0x17, 0x1D, 0xEC, 0x0E, 0x9A, 0xCB, +0x37, 0xD6, 0x06, 0x67, 0x3F, 0xF2, 0x51, 0x7E, 0x98, 0x70, 0xF6, 0x63, 0xBE, 0xF1, 0xD1, 0x1F, +0xBB, 0xBE, 0x18, 0xFB, 0xD7, 0x2C, 0xE9, 0x3F, 0x04, 0x33, 0x1F, 0xD5, 0x89, 0x8F, 0xFC, 0x43, +0xF2, 0x85, 0xE8, 0x0D, 0xA7, 0x18, 0x40, 0x80, 0x00, 0x0C, 0xDA, 0x3C, 0x72, 0x07, 0xAC, 0x45, +0x8D, 0x8F, 0x38, 0xFE, 0xB6, 0xD8, 0x0B, 0x8D, 0xF2, 0x75, 0x3E, 0x46, 0xAE, 0xAB, 0x71, 0xA2, +0xD9, 0x8F, 0xF3, 0x89, 0x8F, 0xBC, 0x8F, 0xB6, 0xF3, 0x6B, 0xD9, 0xF5, 0x1F, 0x45, 0x39, 0xA8, +0xE2, 0x34, 0x8E, 0xAB, 0xF8, 0x98, 0xFD, 0xE3, 0xCD, 0xF2, 0x19, 0x90, 0x6B, 0x4E, 0x31, 0x80, +0x00, 0x01, 0x18, 0x18, 0x24, 0xB5, 0xAE, 0x77, 0xF7, 0x7E, 0xAD, 0x48, 0x7C, 0x0C, 0x7F, 0xC4, +0xC8, 0x8E, 0x57, 0x71, 0xE4, 0xB3, 0x47, 0x66, 0x3F, 0xD2, 0xB7, 0xBB, 0x1D, 0x67, 0xFC, 0x3D, +0x9C, 0x3E, 0x3E, 0xFA, 0x0F, 0xF3, 0xAB, 0xDD, 0x59, 0x90, 0x7C, 0xB6, 0x26, 0x4E, 0xE3, 0x21, +0x8A, 0x8F, 0xB9, 0xC5, 0x47, 0xFF, 0x87, 0x68, 0x27, 0x2C, 0x40, 0x80, 0x00, 0x0C, 0x6A, 0x6D, +0x6D, 0x54, 0x2A, 0x3E, 0x62, 0x18, 0xDD, 0x15, 0xAA, 0x3F, 0xD3, 0x11, 0x4B, 0x7F, 0x3F, 0x66, +0xF6, 0xA3, 0x02, 0xF1, 0x91, 0xB7, 0xE1, 0x7E, 0xE7, 0x7E, 0xF6, 0xE2, 0xE0, 0xA3, 0x3A, 0xF5, +0x2C, 0x88, 0xF8, 0x98, 0x7B, 0x7C, 0x74, 0x35, 0x9C, 0x64, 0x00, 0x01, 0x02, 0x30, 0x30, 0xA6, +0x3A, 0x68, 0x54, 0x26, 0x3E, 0x86, 0x1F, 0x62, 0x1C, 0xDC, 0x19, 0x6A, 0xDC, 0x43, 0x2F, 0x0F, +0xA8, 0x73, 0x69, 0xF6, 0x63, 0x2F, 0x2E, 0x7C, 0x7C, 0x14, 0x8F, 0x25, 0xAD, 0x05, 0x09, 0xE3, +0x62, 0xAA, 0x17, 0x11, 0x27, 0x5A, 0x44, 0x2F, 0x3E, 0xE6, 0xFF, 0x78, 0xB3, 0xED, 0xB4, 0x13, +0x56, 0xDD, 0x89, 0x06, 0x10, 0x20, 0x00, 0x21, 0xDF, 0x01, 0xAB, 0x9E, 0x8F, 0x2E, 0xAB, 0x12, +0x1F, 0x47, 0xCE, 0x7E, 0x0C, 0xAE, 0xD3, 0x2E, 0x66, 0x3F, 0x46, 0xBE, 0x9D, 0xF4, 0xF7, 0xED, +0xEA, 0xC4, 0x47, 0x3E, 0x7E, 0xDD, 0xEF, 0xBE, 0x14, 0xB7, 0x0C, 0xEE, 0x88, 0x25, 0x3E, 0x16, +0x3A, 0x3E, 0xF2, 0x1F, 0x60, 0xBE, 0x10, 0x5D, 0x80, 0x00, 0x02, 0x04, 0xA0, 0xA7, 0x1E, 0x0E, +0xB6, 0xAA, 0x11, 0x1F, 0xC3, 0x63, 0xCC, 0xFE, 0xE0, 0x39, 0x1E, 0x5E, 0xFB, 0xE3, 0xA8, 0xCB, +0x85, 0x14, 0xB7, 0xB7, 0xC2, 0x31, 0xB3, 0x1F, 0x8B, 0x17, 0x1F, 0x85, 0xD6, 0xF3, 0xF1, 0x70, +0x2B, 0xE1, 0x13, 0xCD, 0x82, 0x88, 0x8F, 0x73, 0x8D, 0x8F, 0xFC, 0xD3, 0xED, 0x84, 0x05, 0x08, +0x10, 0x80, 0xB2, 0x46, 0xBE, 0x05, 0x6F, 0x15, 0xE2, 0x63, 0xEC, 0xEC, 0x47, 0xEC, 0xEE, 0x7C, +0x35, 0x34, 0x0E, 0xED, 0xCF, 0x7E, 0x94, 0x9F, 0x7A, 0x95, 0xFE, 0xDC, 0xAA, 0x5E, 0x7C, 0xE4, +0xB7, 0xB4, 0xBA, 0xBB, 0x62, 0x85, 0x70, 0x92, 0x59, 0x10, 0xF1, 0x71, 0xEE, 0xF1, 0x91, 0xB4, +0xF3, 0x1F, 0x9C, 0x9D, 0xB0, 0x00, 0x01, 0x02, 0xD0, 0x73, 0x5F, 0x68, 0xEF, 0x2F, 0x7E, 0x7C, +0x0C, 0x8F, 0x33, 0xCB, 0xD7, 0xF9, 0xB8, 0xD3, 0xEC, 0x47, 0x21, 0xFD, 0x87, 0xE8, 0x83, 0x38, +0x83, 0xEF, 0x61, 0xB6, 0xF1, 0xD1, 0x1F, 0xC7, 0xBE, 0x74, 0x87, 0x59, 0x10, 0xF1, 0xB1, 0x78, +0xF1, 0x51, 0xC8, 0xF6, 0xEB, 0x4E, 0x35, 0x80, 0x00, 0x01, 0x48, 0x5A, 0x5B, 0x9B, 0x55, 0x89, +0x8F, 0x81, 0x41, 0x76, 0x71, 0x9D, 0x8F, 0x49, 0x66, 0x3F, 0x8A, 0x97, 0xED, 0xEA, 0xC6, 0x47, +0xFE, 0xDE, 0xD2, 0x2C, 0x48, 0xFF, 0xA3, 0xCB, 0xB3, 0x20, 0x51, 0x7C, 0x2C, 0x64, 0x7C, 0x74, +0x7F, 0x78, 0x9B, 0x4E, 0x36, 0x80, 0x00, 0x01, 0x48, 0xB2, 0xD3, 0x0E, 0x8C, 0xE6, 0x1C, 0x1F, +0xE5, 0x19, 0x8E, 0xF2, 0x75, 0x3E, 0xC6, 0xCD, 0x7E, 0xC4, 0x30, 0xB8, 0x3B, 0x56, 0x32, 0x76, +0xF6, 0xA3, 0x3A, 0xF1, 0x51, 0xC8, 0x67, 0x41, 0xDA, 0xC7, 0xEC, 0x88, 0x25, 0x3E, 0x16, 0x2F, +0x3E, 0xF2, 0x7F, 0x67, 0x3B, 0x1B, 0xF1, 0x13, 0x3F, 0xBC, 0xE1, 0x84, 0x03, 0x08, 0x10, 0x80, +0xF6, 0xDE, 0x29, 0x06, 0x45, 0x73, 0x8E, 0x8F, 0xFE, 0xE0, 0x3A, 0x0C, 0x2E, 0x38, 0x1F, 0x7A, +0xDE, 0x51, 0x7F, 0xF6, 0x63, 0x28, 0x44, 0xC6, 0xCF, 0x7E, 0x54, 0x2F, 0x3E, 0xF2, 0x8F, 0x6C, +0x75, 0x7E, 0x64, 0x5B, 0x83, 0xDF, 0xDE, 0x61, 0x84, 0xC5, 0xC1, 0x35, 0x2F, 0xE2, 0x63, 0x71, +0x1E, 0x6F, 0x96, 0x5F, 0xD2, 0xDE, 0x2C, 0x08, 0x20, 0x40, 0x80, 0xD5, 0x16, 0x9F, 0x7C, 0xA4, +0x11, 0xDA, 0xBB, 0x8B, 0x1F, 0x1F, 0xFD, 0x01, 0x73, 0x1C, 0xB9, 0xEA, 0x79, 0x2C, 0x6F, 0xC1, +0x3B, 0xBC, 0x1E, 0xA4, 0xF8, 0xC0, 0xB4, 0xEB, 0xD5, 0x41, 0xAC, 0x7C, 0x7C, 0xF4, 0x9B, 0xF1, +0x76, 0x77, 0x16, 0x64, 0x60, 0x2D, 0x48, 0xCD, 0xCC, 0xC7, 0xC2, 0xC6, 0x47, 0x7E, 0xB0, 0x0F, +0x04, 0x08, 0x20, 0x40, 0x00, 0x42, 0xDA, 0x82, 0x37, 0x1F, 0xC9, 0x2E, 0x70, 0x7C, 0x8C, 0x1B, +0x74, 0x8E, 0x59, 0xFB, 0x31, 0xF6, 0xB6, 0xE2, 0x4B, 0xEE, 0x2C, 0x4F, 0x7C, 0xE4, 0xB2, 0x14, +0x21, 0xE5, 0x7B, 0x89, 0x23, 0x4F, 0x3B, 0x2B, 0xAF, 0x81, 0x11, 0x1F, 0xE7, 0x1C, 0x1F, 0xF9, +0xCF, 0x6C, 0x2F, 0xBD, 0xB6, 0x13, 0x16, 0x20, 0x40, 0x00, 0x01, 0xD2, 0xBF, 0x06, 0xC8, 0x22, +0xC6, 0xC7, 0x98, 0xA7, 0x16, 0x75, 0xEF, 0xA5, 0x36, 0x30, 0xD3, 0x31, 0x30, 0xFB, 0x11, 0xC6, +0xCC, 0x7E, 0xB4, 0x97, 0x28, 0x3E, 0x7A, 0xDA, 0x5B, 0xC5, 0x5A, 0x90, 0x30, 0xB8, 0x06, 0xA6, +0x36, 0xF8, 0xFD, 0x8B, 0x8F, 0x05, 0x88, 0x8F, 0xFC, 0xCD, 0xF4, 0xC3, 0x6A, 0x9B, 0x01, 0x01, +0x04, 0x08, 0xB0, 0xE2, 0xDA, 0x7B, 0x37, 0x16, 0x36, 0x3E, 0x86, 0x07, 0x9D, 0xB5, 0xC3, 0xD0, +0x18, 0x37, 0xCB, 0x31, 0x7C, 0x6D, 0x8C, 0xFE, 0x97, 0xDD, 0x89, 0x4B, 0x17, 0x1F, 0xB9, 0x4E, +0x38, 0xB4, 0xBE, 0x9A, 0xF5, 0x1E, 0x57, 0x6D, 0xE0, 0x70, 0xF5, 0x8F, 0x53, 0x14, 0x1F, 0x0B, +0x11, 0x1F, 0xFD, 0x9F, 0xD9, 0x9E, 0x00, 0x01, 0x04, 0x08, 0xB0, 0xEA, 0x01, 0xB2, 0x3F, 0xC1, +0x02, 0xF4, 0x73, 0x8A, 0x8F, 0xDE, 0x9A, 0x8F, 0xD1, 0x9D, 0x65, 0x6B, 0x47, 0xAC, 0xFD, 0xA8, +0x8D, 0xEE, 0x86, 0xB5, 0x5B, 0xCC, 0x7E, 0x2C, 0x59, 0x7C, 0xF4, 0x06, 0xE4, 0x69, 0x4B, 0xDE, +0xEC, 0x60, 0x68, 0x8C, 0x5E, 0x9A, 0x29, 0xCA, 0x17, 0xE4, 0x67, 0xE2, 0x63, 0x21, 0xE2, 0x23, +0x0F, 0x90, 0x7D, 0xBB, 0x60, 0x01, 0x02, 0x04, 0x58, 0x71, 0x59, 0x73, 0xB3, 0x2A, 0xF1, 0x31, +0xB0, 0xDB, 0xD3, 0xD0, 0xC7, 0xF6, 0xD7, 0xA7, 0x97, 0x27, 0x3B, 0xD2, 0xE4, 0xC0, 0x76, 0x5C, +0xDA, 0xF8, 0xE8, 0x37, 0xE4, 0x8B, 0x71, 0x20, 0x2C, 0xCA, 0xF1, 0xD1, 0x0F, 0xB2, 0x4C, 0x7C, +0x9C, 0x7B, 0x7C, 0xE4, 0xEF, 0x6A, 0x86, 0xF8, 0x89, 0x1F, 0x6E, 0x38, 0xF1, 0x00, 0x02, 0x04, +0x58, 0x49, 0xF1, 0xC9, 0x47, 0x36, 0x7B, 0x5B, 0x83, 0x2E, 0x56, 0x7C, 0x1C, 0x35, 0xE8, 0x2C, +0x6F, 0xBB, 0x5B, 0x9E, 0x01, 0x29, 0x66, 0x3F, 0x86, 0xBF, 0xEC, 0x6E, 0x9C, 0xCA, 0xE0, 0x75, +0x91, 0xE3, 0x23, 0x6F, 0xC8, 0xED, 0xEE, 0xD6, 0xBC, 0xFD, 0x19, 0x8E, 0x70, 0x78, 0x21, 0xC6, +0xF2, 0x8B, 0xF8, 0x38, 0xE7, 0xF8, 0xC8, 0x7F, 0x58, 0xFB, 0xE9, 0x75, 0xDD, 0xD9, 0x07, 0x10, +0x20, 0xC0, 0xAA, 0xDA, 0x38, 0x7A, 0x0B, 0xDE, 0xF3, 0x8F, 0x8F, 0x91, 0xD9, 0x8F, 0x72, 0x78, +0x0C, 0x7C, 0x42, 0x6D, 0x70, 0xF6, 0x23, 0x1F, 0xE8, 0x75, 0x5E, 0x76, 0xB2, 0xA5, 0x8F, 0x8F, +0xE2, 0xA6, 0xD6, 0x73, 0xF1, 0xF0, 0x1A, 0x28, 0x9D, 0xD0, 0x28, 0x66, 0x3C, 0x06, 0xE2, 0x23, +0x13, 0x1F, 0xE7, 0x1A, 0x1F, 0xF9, 0xEF, 0xE5, 0x9E, 0x00, 0x01, 0x04, 0x08, 0xB0, 0xD2, 0x1A, +0xA1, 0xB5, 0xBB, 0x78, 0xF1, 0x11, 0xC7, 0xDF, 0xE5, 0xC0, 0x16, 0xBB, 0xF1, 0xF0, 0xA2, 0x83, +0x61, 0xDC, 0x0E, 0xBB, 0xBB, 0xD9, 0x99, 0xBF, 0x8D, 0xAA, 0xC4, 0x47, 0x3E, 0xAE, 0xDD, 0xEF, +0xBE, 0x94, 0x9F, 0x76, 0x55, 0x04, 0x47, 0x7F, 0xE6, 0x23, 0x8A, 0x8F, 0x73, 0x8D, 0x8F, 0xFC, +0xC3, 0xF2, 0x05, 0x49, 0x37, 0x9C, 0x7A, 0x00, 0x01, 0x02, 0xAC, 0xAA, 0x6B, 0xA3, 0xD7, 0x00, +0x59, 0x8C, 0xA7, 0x5D, 0x1D, 0x35, 0xFB, 0x31, 0x6E, 0x07, 0xAC, 0xD1, 0xD9, 0x8F, 0x38, 0x74, +0xDD, 0x8F, 0xE5, 0x8E, 0x8F, 0xE2, 0xED, 0xF6, 0x0B, 0x45, 0x98, 0xD5, 0x3A, 0xD1, 0xD1, 0x9B, +0xF9, 0x28, 0x3D, 0x15, 0xAB, 0x76, 0xB7, 0xF8, 0x58, 0x88, 0xFB, 0x6D, 0x6F, 0xD5, 0x9D, 0x7A, +0x00, 0x01, 0x02, 0xAC, 0xA6, 0xE6, 0x0B, 0xF5, 0x85, 0x8B, 0x8F, 0xF4, 0x47, 0x6D, 0xF4, 0x6E, +0x63, 0x18, 0x5C, 0xE3, 0x71, 0xF4, 0xEC, 0x47, 0xE7, 0xD5, 0x56, 0x3C, 0xE3, 0x43, 0xA9, 0x5E, +0x7C, 0xA4, 0x83, 0x96, 0x9E, 0xDD, 0x93, 0x9E, 0x51, 0x57, 0xC4, 0x47, 0x2C, 0x3D, 0xED, 0x2A, +0xA4, 0xF8, 0xD8, 0x14, 0x1F, 0x0B, 0x71, 0xBF, 0xB1, 0x25, 0x40, 0x00, 0x01, 0x02, 0xAC, 0xA8, +0x98, 0x35, 0x16, 0x2A, 0x3E, 0x86, 0xFF, 0x3A, 0x66, 0xED, 0xC7, 0xB8, 0x4F, 0x8D, 0xE5, 0x0B, +0x80, 0xA4, 0x09, 0x9D, 0xBD, 0x78, 0x86, 0x87, 0x52, 0xCD, 0xF8, 0x28, 0x8E, 0x4F, 0xBE, 0x23, +0x56, 0x7A, 0xDA, 0x55, 0xBB, 0x37, 0x0B, 0xD2, 0x5B, 0xF3, 0x71, 0x45, 0x7C, 0x2C, 0xCE, 0xFD, +0xC6, 0x03, 0x3B, 0x61, 0x01, 0x02, 0x04, 0x58, 0xC1, 0xF6, 0x78, 0xF2, 0x91, 0x8D, 0xC3, 0x1D, +0xB0, 0x16, 0x24, 0x3E, 0x8E, 0x99, 0xFD, 0x88, 0x43, 0xC1, 0x51, 0xEC, 0xF2, 0x34, 0xF4, 0x81, +0xBD, 0x6D, 0x77, 0x57, 0x33, 0x3E, 0x92, 0x7C, 0x16, 0x64, 0xEB, 0x70, 0xF6, 0x43, 0x7C, 0x2C, +0xE0, 0xFD, 0xB6, 0x77, 0xD2, 0x6B, 0xD7, 0x03, 0x01, 0x04, 0x08, 0xB0, 0x72, 0x36, 0xBB, 0x3B, +0x60, 0x2D, 0xD6, 0x56, 0xBB, 0x47, 0xCD, 0x7E, 0x1C, 0x37, 0x03, 0x72, 0x38, 0xFA, 0x0E, 0xA7, +0x9E, 0xFD, 0x58, 0x86, 0xF8, 0x28, 0xC2, 0x2C, 0x35, 0x46, 0xB1, 0xE0, 0xFC, 0xCA, 0x5F, 0x12, +0x1F, 0x0B, 0x77, 0xBF, 0xDD, 0xF0, 0x77, 0x45, 0x74, 0x40, 0x80, 0x00, 0xAB, 0x18, 0x20, 0xFB, +0x8B, 0x13, 0x1F, 0x13, 0xCC, 0x7E, 0x94, 0x07, 0xD9, 0x87, 0x57, 0xFC, 0x2E, 0xAD, 0x1D, 0xD9, +0x12, 0x1F, 0xF9, 0x9F, 0xAD, 0x74, 0x59, 0x94, 0x97, 0x85, 0xBB, 0xBE, 0x43, 0x7C, 0x2C, 0xE4, +0xFD, 0xC6, 0xFC, 0xD2, 0xF5, 0xD7, 0x9D, 0x82, 0x00, 0x01, 0x02, 0xAC, 0x98, 0x78, 0xCC, 0x35, +0x40, 0xE6, 0x1C, 0x1F, 0xC3, 0x37, 0x4F, 0x32, 0xFB, 0x11, 0x87, 0xC2, 0x21, 0x8D, 0xE9, 0xF6, +0xE3, 0x29, 0x1E, 0xCA, 0x92, 0xC5, 0x47, 0xE7, 0x65, 0x6D, 0xE3, 0xDE, 0x70, 0xF5, 0x75, 0xE2, +0x63, 0xA1, 0xEF, 0xB7, 0x7D, 0xBB, 0xEE, 0x1C, 0x04, 0x08, 0x10, 0x60, 0xB5, 0xB4, 0xB6, 0xCE, +0x70, 0x2D, 0x82, 0xE9, 0x5F, 0xE1, 0xFC, 0xE4, 0xB3, 0x1F, 0xA5, 0x4A, 0x39, 0xE5, 0xDA, 0x8F, +0x65, 0x8D, 0x8F, 0x7B, 0xDF, 0xDA, 0x89, 0x8F, 0x4B, 0xE2, 0x63, 0xA1, 0xEF, 0x37, 0xB6, 0x3D, +0x05, 0x0B, 0x10, 0x20, 0xC0, 0x8A, 0x89, 0x59, 0x7D, 0x21, 0xE2, 0x63, 0xF8, 0x5D, 0x77, 0x9A, +0xFD, 0xE8, 0x8D, 0xB4, 0x07, 0xEE, 0x29, 0xCD, 0x7E, 0x1C, 0xC4, 0x13, 0x3E, 0x14, 0xF1, 0x21, +0x3E, 0xCE, 0xF1, 0x7E, 0xBB, 0x3B, 0x61, 0x89, 0x10, 0x40, 0x80, 0x00, 0x2B, 0xA4, 0xB5, 0x73, +0x8A, 0x00, 0x99, 0x4D, 0x7C, 0x4C, 0x3C, 0xFB, 0x91, 0x95, 0xB6, 0xDC, 0x3D, 0xC3, 0xEC, 0x87, +0xF8, 0x10, 0x1F, 0xE7, 0x7E, 0xBF, 0xED, 0xBD, 0xF4, 0xBA, 0x1E, 0x00, 0x04, 0x08, 0xB0, 0x0A, +0xE2, 0x93, 0x8D, 0xC6, 0xE1, 0x16, 0xBC, 0xE7, 0x1C, 0x1F, 0x71, 0xC2, 0xD9, 0x8F, 0x52, 0x78, +0x0C, 0xDC, 0x5B, 0x33, 0x9E, 0x68, 0xF6, 0x43, 0x7C, 0x88, 0x8F, 0xF3, 0xBF, 0xDF, 0x50, 0x2C, +0x44, 0x37, 0x03, 0x02, 0x08, 0x10, 0x60, 0x65, 0x6C, 0x9C, 0x2C, 0x40, 0x66, 0x14, 0x1F, 0xBD, +0xB1, 0xF5, 0x48, 0x90, 0x0C, 0xDD, 0x58, 0xCC, 0x7C, 0xC4, 0xE1, 0x87, 0x73, 0xC2, 0x9D, 0xAF, +0xC4, 0x87, 0xF8, 0x58, 0x88, 0xF8, 0x48, 0xB2, 0x7C, 0x06, 0xC4, 0x4E, 0x58, 0x80, 0x00, 0x01, +0x56, 0xC6, 0x66, 0x68, 0x4D, 0xBA, 0x03, 0xD6, 0x0C, 0xE3, 0x23, 0x1E, 0x7F, 0xD5, 0xF3, 0xC3, +0xAB, 0x9C, 0xC7, 0xF1, 0xEB, 0x41, 0xF6, 0x7A, 0x57, 0x3E, 0x17, 0x1F, 0xE2, 0xA3, 0x4A, 0xF1, +0x51, 0x68, 0xEF, 0xB8, 0x18, 0x21, 0x20, 0x40, 0x80, 0x15, 0x91, 0xB5, 0xAE, 0x87, 0x38, 0xC9, +0xC8, 0x7D, 0x86, 0xF1, 0x71, 0x54, 0x90, 0x0C, 0xAD, 0xFD, 0xE8, 0x2E, 0x38, 0xAF, 0x8D, 0x3E, +0x92, 0x74, 0xC3, 0x4E, 0x9C, 0xF0, 0xA1, 0x88, 0x0F, 0xF1, 0xB1, 0x60, 0xF1, 0xD1, 0x2D, 0x90, +0x86, 0x93, 0x11, 0x20, 0x40, 0x80, 0xD5, 0xD0, 0xDA, 0x9A, 0xE0, 0xBF, 0xBC, 0xCE, 0x76, 0xE6, +0xA3, 0x3F, 0xE3, 0x31, 0xB0, 0xAE, 0xA3, 0x36, 0x30, 0xD3, 0x11, 0x4B, 0x33, 0x1F, 0x23, 0x77, +0x3B, 0xE1, 0xEC, 0x87, 0xF8, 0x10, 0x1F, 0x8B, 0x19, 0x1F, 0x31, 0x7F, 0x1A, 0x56, 0xFC, 0xC4, +0x0F, 0xD7, 0x9D, 0x90, 0x00, 0x01, 0x02, 0x2C, 0xBF, 0xEC, 0xA0, 0x71, 0x6E, 0xF1, 0x31, 0xAC, +0x76, 0x18, 0x22, 0xC3, 0x33, 0x1F, 0xA1, 0xDC, 0x1F, 0xE5, 0x77, 0x66, 0x61, 0xA2, 0xD9, 0x0F, +0xF1, 0x21, 0x3E, 0x16, 0x36, 0x3E, 0x92, 0xEE, 0x85, 0x40, 0x05, 0x08, 0x20, 0x40, 0x80, 0xE5, +0x16, 0x9F, 0x6C, 0xD4, 0x8F, 0x7F, 0xFA, 0xD5, 0x8C, 0xE3, 0x23, 0x0E, 0x7D, 0x95, 0xFE, 0xDF, +0x6B, 0x03, 0x33, 0x1F, 0x87, 0xB3, 0x23, 0xB5, 0xD1, 0xDD, 0xB0, 0x76, 0xEF, 0x3C, 0xFB, 0x21, +0x3E, 0xC4, 0xC7, 0x42, 0xC7, 0x47, 0xBF, 0xA4, 0x43, 0xC3, 0x59, 0x09, 0x10, 0x20, 0xC0, 0xB2, +0xAB, 0x87, 0xD6, 0xD6, 0xC2, 0xC4, 0xC7, 0xC8, 0xD3, 0xB0, 0xCA, 0x0B, 0xCE, 0x43, 0x69, 0x21, +0x7A, 0xF9, 0x3E, 0xEE, 0x30, 0xFB, 0x21, 0x3E, 0xC4, 0xC7, 0xE2, 0xC7, 0x47, 0x47, 0x7B, 0x3B, +0xBD, 0xBE, 0xE6, 0x94, 0x04, 0x08, 0x10, 0x60, 0xD9, 0x35, 0x42, 0xBB, 0x39, 0xFF, 0xF8, 0x38, +0x66, 0x4C, 0xD6, 0xDF, 0x76, 0xB7, 0x37, 0xF3, 0x71, 0xB8, 0xFB, 0x55, 0x6D, 0xF4, 0x21, 0xEE, +0xC6, 0x63, 0x1F, 0xAA, 0xF8, 0x10, 0x1F, 0x95, 0x88, 0x8F, 0x42, 0xB6, 0x5F, 0x77, 0x4A, 0x02, +0xE6, 0x6D, 0xDD, 0x21, 0x00, 0xE6, 0xEC, 0xBE, 0xD1, 0x6B, 0x80, 0xCC, 0x2F, 0x3E, 0x46, 0x66, +0x3F, 0x8A, 0xF0, 0x88, 0xA5, 0xAB, 0x9C, 0x87, 0xEE, 0xA0, 0xFC, 0xA4, 0xB3, 0x1F, 0xE2, 0x43, +0x7C, 0x54, 0x2A, 0x3E, 0xF2, 0x77, 0xB5, 0x1A, 0x4E, 0x49, 0xC0, 0xBC, 0x99, 0x01, 0x01, 0xE6, +0xAB, 0xB5, 0xB5, 0x79, 0x2E, 0xF1, 0x11, 0xC7, 0xDF, 0x16, 0x87, 0xDE, 0x55, 0x0C, 0xC0, 0xC7, +0x7E, 0xFC, 0xF6, 0xD1, 0xB3, 0x1F, 0x8B, 0x1C, 0x1F, 0x51, 0x7C, 0x88, 0x8F, 0xA3, 0x64, 0x3B, +0x69, 0x27, 0x2C, 0xD7, 0x03, 0x01, 0x04, 0x08, 0xB0, 0xC4, 0xB2, 0xD6, 0xE6, 0xDC, 0xE3, 0x63, +0xF8, 0xAB, 0x0D, 0x5F, 0xD5, 0x7C, 0x64, 0xF6, 0x63, 0xCC, 0xDA, 0x8F, 0xB4, 0xE8, 0x7C, 0x37, +0x56, 0x32, 0x3E, 0x6A, 0xC7, 0xC4, 0xC7, 0xC0, 0x6D, 0xE2, 0x63, 0xB5, 0xE2, 0x23, 0xFF, 0xF7, +0x98, 0xCF, 0x46, 0x6E, 0x3A, 0x31, 0x01, 0x02, 0x04, 0x58, 0x5E, 0xED, 0xBD, 0x8D, 0xB9, 0xC7, +0x47, 0x31, 0x0A, 0x1F, 0xBA, 0x2D, 0x8E, 0xB9, 0xDB, 0x63, 0x67, 0x3F, 0x2A, 0x16, 0x1F, 0xE1, +0xC8, 0xF8, 0x08, 0x03, 0x8B, 0xEC, 0x8B, 0xDD, 0xBE, 0x32, 0xF1, 0xB1, 0x5A, 0xF1, 0x91, 0x7F, +0xD8, 0x81, 0x00, 0x01, 0x04, 0x08, 0xB0, 0xBC, 0xE2, 0x93, 0x8D, 0x46, 0xF7, 0xDA, 0x03, 0xF3, +0x5F, 0x70, 0x3E, 0x3C, 0xF0, 0x2E, 0xDE, 0x38, 0x1C, 0x80, 0x0F, 0x87, 0x48, 0x39, 0x9A, 0x42, +0xF7, 0xC2, 0x83, 0x15, 0x8B, 0x8F, 0x91, 0x9B, 0xFA, 0xC7, 0xA0, 0x76, 0x78, 0x2C, 0x86, 0x9E, +0x76, 0x75, 0x41, 0x7C, 0xAC, 0x4E, 0x7C, 0xE4, 0xBF, 0xDB, 0x76, 0xC2, 0x02, 0x04, 0x08, 0xB0, +0xD4, 0x05, 0x12, 0xEB, 0x21, 0x6B, 0xCD, 0x77, 0xD0, 0x39, 0x76, 0xF6, 0x23, 0xE6, 0x3B, 0x5F, +0x95, 0x2F, 0xED, 0x51, 0x1E, 0x88, 0x8F, 0x7C, 0xFE, 0x76, 0xF5, 0xE3, 0x23, 0xF6, 0xB7, 0x19, +0xAE, 0x1D, 0xBE, 0xAF, 0xF4, 0xB4, 0xAB, 0xAC, 0x17, 0x1F, 0x2F, 0x13, 0x1F, 0xAB, 0x13, 0x1F, +0xFD, 0x4F, 0x69, 0x99, 0x01, 0x01, 0x04, 0x08, 0xB0, 0xB4, 0x8E, 0xB9, 0x06, 0xC8, 0xEC, 0x06, +0x9D, 0x83, 0xB3, 0x1F, 0xA5, 0x8B, 0x81, 0x8C, 0x59, 0xFB, 0x31, 0x32, 0x84, 0x4B, 0xBD, 0x34, +0x34, 0xFB, 0x51, 0x85, 0xF8, 0x18, 0xFF, 0x71, 0x83, 0xF1, 0x31, 0x3C, 0xF3, 0x21, 0x3E, 0x56, +0x30, 0x3E, 0x92, 0x6C, 0x5F, 0x80, 0x00, 0x02, 0x04, 0x58, 0x52, 0xED, 0xBD, 0x1B, 0x73, 0x1D, +0x74, 0x8E, 0xCC, 0x7E, 0xC4, 0xFE, 0x75, 0x3F, 0x06, 0x16, 0xA4, 0x97, 0x67, 0x3F, 0xCA, 0x41, +0x92, 0xFE, 0xDC, 0xAA, 0x66, 0x7C, 0x8C, 0x5D, 0x74, 0x5E, 0xBA, 0xBD, 0x7C, 0xBD, 0x93, 0x35, +0xF1, 0xB1, 0xBA, 0xF1, 0x91, 0x07, 0xC8, 0xDE, 0x86, 0x9D, 0xB0, 0x00, 0x01, 0x02, 0x2C, 0xA7, +0x6C, 0xFF, 0xE4, 0x83, 0x9C, 0x33, 0x0E, 0x3A, 0x63, 0x69, 0x0F, 0xDA, 0xB1, 0x3B, 0x5F, 0x1D, +0x37, 0x8C, 0x4B, 0xEB, 0x73, 0x0F, 0xE2, 0x72, 0xC4, 0x47, 0x2C, 0xCF, 0x7C, 0x1C, 0x06, 0x97, +0xF8, 0x58, 0xF1, 0xF8, 0xC8, 0x3F, 0xDD, 0x42, 0x74, 0x60, 0xBE, 0x5C, 0x88, 0x10, 0x98, 0x63, +0x80, 0x34, 0x4F, 0x36, 0xC8, 0x39, 0xEB, 0xA0, 0xB3, 0x56, 0x8C, 0xCD, 0x0E, 0xFF, 0xB3, 0xFF, +0x89, 0x66, 0x3F, 0xB6, 0x97, 0x34, 0x3E, 0x7A, 0x17, 0x59, 0x5C, 0x7B, 0x79, 0x27, 0x3E, 0xDE, +0x22, 0x3E, 0x56, 0x3A, 0x3E, 0xF2, 0x7F, 0x97, 0x7B, 0xE9, 0x75, 0xDD, 0x09, 0x0A, 0x98, 0x17, +0x33, 0x20, 0xC0, 0x7C, 0x86, 0x49, 0xB7, 0x6E, 0x6C, 0x86, 0x76, 0x73, 0x7E, 0x83, 0xCE, 0xFE, +0x0C, 0x47, 0x3C, 0xFA, 0xBA, 0x1F, 0xC3, 0xB7, 0x95, 0x3F, 0xBF, 0x34, 0xFB, 0x51, 0xF9, 0xF8, +0x18, 0xF8, 0x36, 0x4B, 0x33, 0x1F, 0xE2, 0x43, 0x7C, 0x08, 0x10, 0x40, 0x80, 0x00, 0x4B, 0x6C, +0xA3, 0xBB, 0x05, 0xEF, 0x9C, 0x06, 0x9D, 0xB5, 0xA1, 0x01, 0x5A, 0xEF, 0xBF, 0xFC, 0x0F, 0x07, +0x4A, 0x3E, 0xFB, 0x31, 0x3C, 0x9E, 0xCB, 0xD7, 0x7E, 0x64, 0x95, 0x8D, 0x8F, 0x30, 0x1C, 0x1F, +0xE3, 0x9E, 0x76, 0x25, 0x3E, 0xC4, 0x47, 0xFF, 0xAE, 0xDA, 0x69, 0x27, 0xAC, 0x1B, 0x01, 0x60, +0x4E, 0x3C, 0x05, 0x0B, 0x98, 0x97, 0x46, 0xEF, 0xAA, 0xCB, 0xB3, 0x1F, 0x74, 0x0E, 0xED, 0x76, +0x35, 0xFA, 0x94, 0xAB, 0xD2, 0x33, 0xB3, 0xC6, 0xCD, 0x88, 0xA4, 0x5D, 0xAF, 0x5A, 0xD5, 0x8D, +0x8F, 0x28, 0x3E, 0xC4, 0xC7, 0x49, 0x65, 0x7B, 0x75, 0xA7, 0x28, 0x40, 0x80, 0x00, 0xCB, 0xE6, +0xDA, 0x1D, 0x03, 0x64, 0x56, 0x03, 0xFE, 0x31, 0x6B, 0x3F, 0x46, 0x6E, 0x2B, 0xBF, 0x6F, 0x27, +0x2E, 0xC7, 0xD3, 0xAE, 0xC4, 0x87, 0xF8, 0x98, 0x38, 0x40, 0xF6, 0x05, 0x08, 0x30, 0x37, 0x9E, +0x82, 0x05, 0xCC, 0x47, 0xF3, 0x85, 0xFA, 0xCC, 0x07, 0x9D, 0xBD, 0xBD, 0x65, 0xE3, 0x40, 0x64, +0x1C, 0x0E, 0xCA, 0xC3, 0xB8, 0xD9, 0x8F, 0x30, 0x3A, 0xFB, 0x11, 0x5B, 0xCB, 0xB7, 0xDB, 0x55, +0x58, 0x5F, 0x0F, 0x57, 0x1B, 0xFF, 0x51, 0x2F, 0x3E, 0xBE, 0x2C, 0x3E, 0xC4, 0xC7, 0x70, 0x81, +0x84, 0xF8, 0x89, 0x1F, 0x6E, 0x38, 0x51, 0x01, 0x02, 0x04, 0x58, 0x1E, 0xB1, 0xBD, 0x39, 0xFB, +0x41, 0x67, 0xE9, 0x7E, 0x6A, 0xA5, 0x59, 0x80, 0x81, 0x40, 0x39, 0xBC, 0x2D, 0x0E, 0x8F, 0xE9, +0xD2, 0xED, 0xDB, 0x4B, 0x10, 0x1F, 0x61, 0x34, 0x3E, 0xD2, 0xCC, 0xC7, 0xDA, 0xD5, 0xAB, 0xDD, +0xF0, 0x68, 0x3D, 0x2F, 0x3E, 0xC4, 0xC7, 0xA0, 0xF6, 0x76, 0x7A, 0x5D, 0x77, 0xA2, 0x02, 0x04, +0x08, 0xB0, 0x1C, 0xED, 0x71, 0xEB, 0xC6, 0x46, 0x88, 0x07, 0x1B, 0x33, 0x1D, 0x74, 0xF6, 0xEE, +0x67, 0x78, 0x41, 0x79, 0x2C, 0x0D, 0xCC, 0x07, 0xA2, 0x23, 0x0E, 0x0E, 0xD8, 0xF3, 0xB7, 0x77, +0x3A, 0xAF, 0xDA, 0xD3, 0x78, 0x3C, 0x8B, 0x17, 0x1F, 0x17, 0xEE, 0xBF, 0xAF, 0x1B, 0x1F, 0xE9, +0xA9, 0x57, 0xE2, 0x43, 0x7C, 0x0C, 0xEB, 0x3E, 0x3D, 0x52, 0x80, 0x00, 0x02, 0x04, 0x58, 0x1A, +0x9B, 0xA1, 0xB5, 0x3B, 0xD7, 0xF8, 0x18, 0x79, 0x1A, 0xD6, 0xF0, 0xEC, 0xC7, 0xD0, 0xC2, 0xF3, +0x98, 0x75, 0xFE, 0xB2, 0x9D, 0x89, 0x0F, 0xF1, 0xB1, 0x7A, 0xF1, 0x91, 0x7F, 0x99, 0xFC, 0x62, +0x84, 0x76, 0xC2, 0x02, 0x04, 0x08, 0xB0, 0x44, 0x01, 0x32, 0xBC, 0x00, 0x7D, 0xD6, 0x8B, 0xBC, +0xCB, 0xDB, 0xEE, 0x0E, 0x47, 0x47, 0xAC, 0x0D, 0x3D, 0x94, 0xCE, 0x8D, 0xBB, 0x71, 0x0A, 0x63, +0x3D, 0xF1, 0x21, 0x3E, 0xAA, 0xFA, 0xB5, 0x3A, 0x5A, 0x2F, 0x6D, 0x38, 0x55, 0x01, 0x02, 0x04, +0x58, 0x16, 0x83, 0xD7, 0x00, 0x99, 0x41, 0x7C, 0x8C, 0xCC, 0x7E, 0x14, 0x6F, 0x97, 0x16, 0x65, +0x77, 0xD5, 0x06, 0x66, 0x3F, 0xF2, 0xF8, 0x48, 0x13, 0x1F, 0x3B, 0x71, 0x6A, 0x8F, 0x45, 0x7C, +0x88, 0x8F, 0xCA, 0xC5, 0x47, 0xFE, 0x25, 0x8F, 0x59, 0xA7, 0x05, 0x20, 0x40, 0x80, 0x4A, 0x69, +0xEF, 0xDD, 0x98, 0x59, 0x7C, 0xC4, 0xF1, 0xEF, 0x1A, 0xDE, 0x62, 0xB7, 0x18, 0xA0, 0x0F, 0x7E, +0x7C, 0xEF, 0x2F, 0x67, 0x9E, 0xFD, 0x10, 0x1F, 0xE2, 0xA3, 0xE2, 0xF1, 0x91, 0x7F, 0xD9, 0x83, +0x10, 0x3F, 0xFE, 0x43, 0x22, 0x04, 0x10, 0x20, 0xC0, 0x12, 0xC8, 0x9A, 0xF5, 0x99, 0xC4, 0xC7, +0xF0, 0xDF, 0xC6, 0xEC, 0x78, 0x35, 0x38, 0xFB, 0x51, 0x5E, 0xFB, 0x11, 0xBB, 0x7F, 0xB6, 0xC3, +0x19, 0x67, 0x3F, 0xC4, 0x87, 0xF8, 0x58, 0x82, 0xF8, 0xC8, 0xFF, 0x9D, 0xEE, 0xA4, 0xD7, 0x75, +0x27, 0x2C, 0x40, 0x80, 0x00, 0xD5, 0xD7, 0xDA, 0xA9, 0xCF, 0x24, 0x3E, 0x62, 0x77, 0x3C, 0x3E, +0xFC, 0xEE, 0x18, 0x6A, 0x23, 0xE3, 0xDD, 0xC1, 0xD9, 0x8F, 0x78, 0xF8, 0x70, 0xB6, 0xCF, 0x32, +0xFB, 0x21, 0x3E, 0xC4, 0xC7, 0x92, 0xC4, 0x47, 0xFE, 0xE5, 0x53, 0x8D, 0x07, 0x33, 0x20, 0x80, +0x00, 0x01, 0xAA, 0x2D, 0xDE, 0xBA, 0xB1, 0x19, 0xB2, 0xFD, 0x99, 0x0D, 0xD0, 0x06, 0xB6, 0xD1, +0x2D, 0x47, 0x48, 0x69, 0xD7, 0xAB, 0xC1, 0x10, 0x29, 0xC5, 0x47, 0x1A, 0x6F, 0xED, 0xC5, 0xA9, +0x3D, 0x16, 0xF1, 0x21, 0x3E, 0x2A, 0x1B, 0x1F, 0x49, 0xB6, 0x97, 0x5E, 0x5F, 0x77, 0xD6, 0x02, +0x04, 0x08, 0x50, 0xF5, 0x04, 0xA9, 0x8F, 0xEC, 0x80, 0x35, 0x8D, 0x01, 0xDA, 0x31, 0xB3, 0x1F, +0xA5, 0x26, 0x19, 0x1C, 0xA8, 0x0F, 0xCF, 0x9E, 0x6C, 0x8B, 0x0F, 0xF1, 0x21, 0x3E, 0x06, 0x23, +0x64, 0xA7, 0xEE, 0x9C, 0x05, 0x08, 0x10, 0xA0, 0xEA, 0xC6, 0x5F, 0x03, 0x64, 0x0A, 0x03, 0xB4, +0xA3, 0x66, 0x3F, 0xC6, 0xAD, 0xFD, 0xC8, 0x9F, 0x76, 0x55, 0xBE, 0xAB, 0xB4, 0xF3, 0xD5, 0xA9, +0x66, 0x3F, 0xC4, 0x87, 0xF8, 0x58, 0xD2, 0xF8, 0xC8, 0x1F, 0x8E, 0x9D, 0xB0, 0x00, 0x01, 0x02, +0x54, 0x5D, 0xD6, 0xBA, 0xDE, 0x7B, 0x6E, 0xF9, 0xF4, 0x06, 0x68, 0x13, 0xCC, 0x7E, 0x1C, 0x6E, +0xC1, 0x5B, 0xEB, 0x6E, 0xB5, 0x3B, 0x7C, 0x51, 0xC2, 0x97, 0xC4, 0x87, 0xF8, 0x10, 0x1F, 0xA3, +0xFF, 0x5E, 0xF7, 0xD2, 0x4E, 0x58, 0x75, 0x27, 0x2E, 0x40, 0x80, 0x00, 0xD5, 0xD5, 0xDA, 0x3A, +0xC3, 0xC5, 0xCD, 0xE2, 0x9D, 0xC7, 0xB5, 0x47, 0xCD, 0x7E, 0x0C, 0xDD, 0xC7, 0xC0, 0x4D, 0xE9, +0xA2, 0xCF, 0x07, 0x71, 0x6A, 0x8F, 0x45, 0x7C, 0x88, 0x8F, 0xA5, 0x88, 0x8F, 0x5E, 0x80, 0x04, +0x3B, 0x61, 0x01, 0x02, 0x04, 0xA8, 0xB4, 0x98, 0x35, 0xA6, 0x3E, 0x40, 0x9B, 0x78, 0xF6, 0x63, +0x70, 0x31, 0x7A, 0xFF, 0xED, 0x6D, 0xF1, 0x21, 0x3E, 0xC4, 0xC7, 0xF8, 0x87, 0x96, 0xEA, 0x3C, +0x34, 0x02, 0x80, 0x00, 0x01, 0x2A, 0xD9, 0x1E, 0xB7, 0x5E, 0x7F, 0xCA, 0x05, 0xE8, 0xF1, 0xD8, +0x77, 0x4D, 0x36, 0xFB, 0x31, 0xF4, 0xB4, 0xAB, 0xC2, 0x89, 0x67, 0x3F, 0xC4, 0x87, 0xF8, 0x58, +0x91, 0xF8, 0x48, 0xBA, 0x33, 0x20, 0xD7, 0x9C, 0xBD, 0x00, 0x01, 0x02, 0x54, 0x55, 0x3D, 0xB4, +0xB6, 0xA6, 0x3B, 0x40, 0xBB, 0xD3, 0x75, 0x3F, 0xFA, 0x5B, 0xED, 0xD6, 0xC6, 0x6F, 0xCB, 0xBB, +0x2D, 0x3E, 0xC4, 0x87, 0xF8, 0x38, 0x3E, 0x42, 0xEC, 0x84, 0x05, 0xCC, 0xD6, 0xBA, 0x43, 0x00, +0xCC, 0xD0, 0x66, 0x68, 0x9F, 0x64, 0x06, 0x24, 0xDE, 0xF1, 0xDD, 0x47, 0x5D, 0xF5, 0xBC, 0xFF, +0x94, 0xAB, 0xD2, 0xCC, 0x47, 0xF9, 0xF6, 0x5C, 0x33, 0x9E, 0x60, 0xF6, 0x43, 0x7C, 0x88, 0x8F, +0x15, 0x8C, 0x8F, 0xAE, 0x86, 0x53, 0x17, 0x30, 0x4B, 0x66, 0x40, 0x80, 0x59, 0xBA, 0x36, 0xF9, +0x53, 0xB0, 0x4E, 0x31, 0x40, 0x1B, 0x59, 0xFB, 0x11, 0x47, 0x6F, 0x2B, 0xDF, 0xFD, 0x96, 0xF8, +0x10, 0x1F, 0xE2, 0xE3, 0x8E, 0xDA, 0xDB, 0x76, 0xC2, 0x02, 0x04, 0x08, 0x50, 0x51, 0xAD, 0xAD, +0x09, 0xAF, 0x29, 0x70, 0xE7, 0x99, 0x8F, 0x81, 0x2D, 0x74, 0xFB, 0xB3, 0x1F, 0xB5, 0xD2, 0x4C, +0x47, 0x1C, 0x78, 0xFF, 0xE1, 0x40, 0xBE, 0x77, 0x1F, 0xE9, 0x9A, 0x1F, 0xED, 0x29, 0x3C, 0x16, +0xF1, 0x21, 0x3E, 0x96, 0x39, 0x3E, 0xF2, 0x87, 0x9C, 0x2F, 0x44, 0x17, 0x20, 0x80, 0x00, 0x01, +0x2A, 0x28, 0x6B, 0x4D, 0x10, 0x20, 0x27, 0x1C, 0xA0, 0xD5, 0x0E, 0x43, 0x64, 0x78, 0xE6, 0xA3, +0xFC, 0xEC, 0xAB, 0x81, 0xBB, 0x4D, 0x6F, 0xEF, 0x4C, 0xF2, 0x75, 0xC4, 0x87, 0xF8, 0x58, 0xF1, +0xF8, 0x38, 0x0C, 0x10, 0x17, 0x24, 0x04, 0x04, 0x08, 0x50, 0x41, 0xED, 0xBD, 0x8D, 0x33, 0x0F, +0xD0, 0xE2, 0xD0, 0x47, 0xF6, 0xFF, 0x5E, 0x1B, 0x98, 0xF9, 0x38, 0x9C, 0xFD, 0x38, 0x1C, 0xD4, +0xF7, 0x3F, 0x67, 0xA2, 0xD9, 0x0F, 0xF1, 0x21, 0x3E, 0xC4, 0x47, 0xF7, 0xDF, 0xED, 0x76, 0x7A, +0x6D, 0x27, 0x2C, 0x40, 0x80, 0x00, 0xD5, 0x12, 0x6F, 0xBD, 0xBE, 0x71, 0xFC, 0xFA, 0x8F, 0xD3, +0xC5, 0xC7, 0xE0, 0xD3, 0xB0, 0x86, 0x16, 0x9C, 0x87, 0xA1, 0xA7, 0x5D, 0xA5, 0x3F, 0xB3, 0x30, +0xC1, 0xDA, 0x0F, 0xF1, 0x21, 0x3E, 0xC4, 0xC7, 0x80, 0x6C, 0xDF, 0x0C, 0x08, 0x20, 0x40, 0x80, +0xCA, 0x39, 0xE6, 0x1A, 0x20, 0x67, 0x18, 0xA0, 0xF5, 0xB7, 0xDD, 0x8D, 0xA3, 0xD1, 0x11, 0x6B, +0xA3, 0xE3, 0xE3, 0xDD, 0x78, 0x87, 0x2F, 0x27, 0x3E, 0xC4, 0x87, 0xF8, 0x18, 0xFD, 0x36, 0x5A, +0x02, 0x04, 0x10, 0x20, 0x40, 0x05, 0x03, 0xE4, 0x60, 0xEB, 0xCC, 0x03, 0xB4, 0xF1, 0xDB, 0xEE, +0xC6, 0xC1, 0xAB, 0x9C, 0x87, 0xEE, 0xC0, 0x7E, 0x60, 0xF6, 0x23, 0x49, 0xB3, 0x1F, 0xC7, 0xAE, +0xFD, 0x10, 0x1F, 0xE2, 0x43, 0x7C, 0x8C, 0x95, 0xED, 0x6C, 0xC4, 0x8F, 0xFF, 0xD0, 0x86, 0xD3, +0x18, 0x20, 0x40, 0x80, 0xEA, 0x68, 0xEF, 0x5E, 0x3F, 0xD3, 0x00, 0x2D, 0x8E, 0xBF, 0x2D, 0x0E, +0xBD, 0xAB, 0x18, 0xC4, 0x87, 0x38, 0x66, 0x8C, 0x7C, 0xEC, 0xEC, 0x87, 0xF8, 0x10, 0x1F, 0xE2, +0xE3, 0xE8, 0x6F, 0x27, 0x5F, 0x34, 0x65, 0x16, 0x04, 0x10, 0x20, 0x40, 0x95, 0x02, 0xA4, 0x59, +0x3F, 0xEB, 0x00, 0x6D, 0x74, 0xF6, 0x23, 0x0E, 0x5C, 0x60, 0x70, 0x38, 0x3A, 0x26, 0x9F, 0xFD, +0x10, 0x1F, 0xE2, 0x43, 0x7C, 0x1C, 0xFF, 0x2D, 0xED, 0x0B, 0x10, 0x40, 0x80, 0x00, 0x15, 0x93, +0x35, 0x37, 0x4F, 0x3D, 0x40, 0x8B, 0xDD, 0x31, 0xFB, 0xF0, 0x00, 0x38, 0x0E, 0xDD, 0x78, 0xEC, +0xEC, 0xC7, 0xF6, 0x51, 0xB3, 0x1F, 0xE2, 0x43, 0x7C, 0x88, 0x8F, 0x3B, 0xFF, 0xFB, 0xDD, 0x4B, +0xAF, 0xED, 0x84, 0x05, 0x08, 0x10, 0xA0, 0x1A, 0xE2, 0xAD, 0xD7, 0x6F, 0x1E, 0x2E, 0x40, 0x3F, +0xDD, 0x00, 0xAD, 0xBC, 0x93, 0x55, 0x2C, 0x6D, 0x87, 0x15, 0x4B, 0xBB, 0x5E, 0x0D, 0x86, 0x48, +0xE9, 0x73, 0xD2, 0xB3, 0x47, 0x76, 0xA3, 0xF8, 0x10, 0x1F, 0xE2, 0xE3, 0xD4, 0xDF, 0x5A, 0x3B, +0xBD, 0x98, 0x01, 0x01, 0x04, 0x08, 0x50, 0x19, 0x1B, 0xA1, 0xBD, 0x7B, 0xBA, 0x01, 0xDA, 0xC8, +0xEC, 0x47, 0xEC, 0xEF, 0x7C, 0x55, 0xDE, 0x5D, 0x77, 0x60, 0x30, 0x3F, 0xFC, 0xF9, 0xDB, 0xE2, +0x43, 0x7C, 0x88, 0x8F, 0x33, 0xCB, 0x76, 0xEB, 0x4E, 0x65, 0x80, 0x00, 0x01, 0x2A, 0x22, 0x36, +0x42, 0x7B, 0xFF, 0xEC, 0xE3, 0xDE, 0x18, 0x07, 0x2F, 0x40, 0x38, 0x66, 0xED, 0x47, 0x7F, 0x28, +0x58, 0xDC, 0x96, 0xD6, 0x7E, 0xEC, 0x45, 0xF1, 0x21, 0x3E, 0xC4, 0xC7, 0x99, 0xBF, 0xCD, 0x7D, +0x01, 0x02, 0x08, 0x10, 0xA0, 0x32, 0xAE, 0x1D, 0x7F, 0x11, 0xC2, 0x63, 0xC6, 0x75, 0xB5, 0xA1, +0x41, 0xDE, 0xD0, 0xEC, 0x47, 0xFF, 0x2A, 0xE7, 0xC5, 0x80, 0xBE, 0x74, 0x11, 0xC2, 0xF1, 0xB3, +0x1F, 0xE2, 0x43, 0x7C, 0x88, 0x8F, 0x53, 0xE9, 0xFC, 0x1B, 0x8E, 0x1F, 0x7F, 0x7B, 0xC3, 0xE9, +0x0C, 0x10, 0x20, 0xC0, 0xE2, 0x6B, 0xBE, 0x50, 0x3F, 0xDB, 0xD8, 0x37, 0x0E, 0x5D, 0xF7, 0x23, +0x0C, 0x0C, 0xEA, 0x8F, 0x1C, 0x0E, 0x1E, 0x84, 0xA1, 0xD9, 0x0F, 0xF1, 0x21, 0x3E, 0xC4, 0xC7, +0xA9, 0x7F, 0x0F, 0xB2, 0x7C, 0x16, 0xB3, 0x1E, 0x00, 0x04, 0x08, 0xB0, 0xF8, 0x83, 0x97, 0x53, +0x2C, 0x5E, 0xED, 0xCF, 0x7E, 0xC4, 0x81, 0xDB, 0x26, 0x9A, 0xFD, 0x28, 0xDE, 0xDE, 0x16, 0x1F, +0xE2, 0x43, 0x7C, 0x4C, 0xED, 0xF7, 0xA0, 0x3B, 0x8B, 0x29, 0x40, 0x00, 0x01, 0x02, 0x2C, 0xF8, +0xD8, 0xE5, 0xD6, 0xC3, 0x1B, 0x21, 0x3B, 0x38, 0xD5, 0x15, 0x94, 0x63, 0x2C, 0x3F, 0xED, 0xAA, +0x34, 0xEE, 0x9B, 0x74, 0xF6, 0xE3, 0x20, 0x8A, 0x0F, 0xF1, 0x21, 0x3E, 0xA6, 0xF5, 0x7B, 0x10, +0xD3, 0x3F, 0xAA, 0x70, 0xC3, 0x59, 0x0D, 0x10, 0x20, 0xC0, 0xA2, 0xDB, 0xEC, 0xEE, 0x80, 0x75, +0xC6, 0x41, 0xDE, 0xA9, 0x67, 0x3F, 0xC4, 0x87, 0xF8, 0x10, 0x1F, 0x53, 0xFB, 0x3D, 0x68, 0x6F, +0xD5, 0x9D, 0xD2, 0x00, 0x01, 0x02, 0x54, 0x20, 0x40, 0x4E, 0xB8, 0x00, 0x7D, 0x68, 0xB7, 0xAB, +0x63, 0x67, 0x3F, 0xE2, 0xD0, 0xC7, 0x24, 0xFD, 0xD9, 0x0F, 0xF1, 0x21, 0x3E, 0xC4, 0xC7, 0x54, +0x7F, 0x0F, 0x62, 0x4B, 0x80, 0x00, 0x02, 0x04, 0x58, 0x78, 0x1B, 0x27, 0x9A, 0x01, 0x39, 0xE2, +0xB9, 0x55, 0x03, 0x57, 0x3D, 0x2F, 0xCF, 0x7E, 0x0C, 0xDD, 0x96, 0xDF, 0x70, 0x3B, 0x13, 0x1F, +0xE2, 0x43, 0x7C, 0xCC, 0xE2, 0xF7, 0x20, 0x1E, 0xA4, 0x9D, 0xB0, 0x5C, 0x90, 0x10, 0x10, 0x20, +0xC0, 0x02, 0x6B, 0xEF, 0x4D, 0xFE, 0x9C, 0xF1, 0xDE, 0xC0, 0xA7, 0xBF, 0x85, 0xEE, 0xD0, 0xEC, +0x47, 0xFF, 0x0A, 0xE7, 0xA5, 0xF7, 0x87, 0xE1, 0xAB, 0x9E, 0xA7, 0x5D, 0xAF, 0xDA, 0xE2, 0x43, +0x7C, 0x88, 0x8F, 0x99, 0xFC, 0x1E, 0xB4, 0x77, 0xD2, 0xEB, 0xBA, 0x13, 0x1B, 0x20, 0x40, 0x80, +0xC5, 0x95, 0x35, 0x27, 0x1B, 0xAC, 0x0C, 0x0F, 0x7C, 0x6A, 0xA5, 0xF0, 0x18, 0x5A, 0xFB, 0x31, +0x72, 0x5B, 0xF9, 0x7D, 0x3B, 0x99, 0xF8, 0x10, 0x1F, 0xE2, 0x63, 0x56, 0xBF, 0x07, 0xDD, 0x9D, +0xB0, 0xCC, 0x80, 0x00, 0x53, 0xB5, 0xEE, 0x10, 0x00, 0x53, 0xD5, 0xDA, 0xB9, 0x73, 0x80, 0x94, +0x06, 0x3E, 0xE5, 0xAB, 0x98, 0xC7, 0x70, 0x38, 0xC0, 0x0F, 0xE3, 0x66, 0x3F, 0xC2, 0xF0, 0xEC, +0x47, 0x27, 0x3E, 0xDA, 0xE2, 0x43, 0x7C, 0x88, 0x8F, 0x99, 0xFD, 0x1E, 0x74, 0x77, 0xC2, 0xBA, +0xEE, 0xC4, 0x06, 0x4C, 0x93, 0x19, 0x10, 0x60, 0x7A, 0x63, 0x9A, 0x5B, 0x0F, 0x6F, 0xDE, 0xF1, +0x0A, 0xE8, 0xE3, 0x06, 0x3E, 0xB5, 0xC3, 0xD0, 0x18, 0x9E, 0xF9, 0x28, 0x6E, 0x8B, 0xC3, 0xE3, +0xC3, 0x74, 0x3F, 0x3B, 0x53, 0x18, 0x30, 0x8A, 0x0F, 0xF1, 0x21, 0x3E, 0x8E, 0xD7, 0xBE, 0x5D, +0x0F, 0x00, 0x02, 0x04, 0x58, 0x50, 0xF5, 0x63, 0x03, 0x64, 0x68, 0xE0, 0x13, 0x87, 0xDE, 0x88, +0xA5, 0x41, 0xFE, 0x40, 0x74, 0xC4, 0xC1, 0xDB, 0xF3, 0xD7, 0x29, 0x3E, 0xCE, 0x3A, 0xFB, 0x21, +0x3E, 0xC4, 0x87, 0xF8, 0x98, 0x84, 0xA7, 0x60, 0x01, 0x02, 0x04, 0x58, 0x58, 0x9B, 0xA1, 0xB5, +0x7B, 0xE2, 0xF8, 0x18, 0x59, 0x84, 0x3E, 0x3C, 0xFB, 0x51, 0x7E, 0xDA, 0x55, 0x7A, 0x23, 0x2D, +0xFB, 0x38, 0xEB, 0xEC, 0x87, 0xF8, 0x10, 0x1F, 0xE2, 0x63, 0x32, 0xD9, 0x9E, 0x9D, 0xB0, 0x00, +0x01, 0x02, 0x2C, 0xA8, 0xAC, 0x75, 0x3D, 0xC4, 0xF6, 0xC9, 0x07, 0x3E, 0xE5, 0x6D, 0x77, 0x87, +0xA3, 0x23, 0xD6, 0x4A, 0x77, 0xD3, 0xBB, 0x9F, 0xDD, 0x78, 0xB6, 0x71, 0xA3, 0xF8, 0x10, 0x1F, +0xE2, 0x63, 0x72, 0xED, 0xBD, 0xF4, 0x7A, 0xC3, 0x09, 0x0E, 0x10, 0x20, 0xC0, 0xE2, 0x69, 0x6D, +0x6D, 0x4C, 0x32, 0xF0, 0x39, 0xEA, 0xA2, 0x83, 0xB1, 0x7C, 0x6D, 0x8F, 0xD0, 0x0D, 0x80, 0xC3, +0xD9, 0x8F, 0xDE, 0x8D, 0x67, 0x9D, 0xFD, 0x10, 0x1F, 0xE2, 0x43, 0x7C, 0x9C, 0xF0, 0xF3, 0xF3, +0x85, 0xE8, 0x0D, 0x27, 0x38, 0x40, 0x80, 0x00, 0x0B, 0x38, 0xD0, 0xC9, 0x1A, 0x27, 0x1E, 0xF8, +0x8C, 0xD9, 0x62, 0xB7, 0x18, 0xEC, 0x97, 0xEB, 0xA4, 0x7F, 0x57, 0x67, 0x99, 0xFD, 0x10, 0x1F, +0xE2, 0x43, 0x7C, 0x9C, 0x5C, 0x96, 0xCF, 0x80, 0x5C, 0x73, 0x82, 0x03, 0x04, 0x08, 0xB0, 0x58, +0xE3, 0x9C, 0x5B, 0x0F, 0x0F, 0x2E, 0x40, 0x3F, 0x6A, 0xB0, 0x3F, 0x10, 0x1E, 0xA5, 0x1B, 0x47, +0x66, 0x3F, 0x8A, 0x81, 0x7F, 0xE9, 0x86, 0xF4, 0xEC, 0xAE, 0xED, 0x53, 0x0E, 0xA8, 0xC4, 0x87, +0xF8, 0x10, 0x1F, 0xA7, 0xD7, 0x9E, 0x60, 0x7B, 0x6D, 0x00, 0x01, 0x02, 0xCC, 0x59, 0x3D, 0xB4, +0xB6, 0x4E, 0x36, 0xF0, 0x29, 0xAF, 0xFD, 0x08, 0x83, 0x03, 0xFE, 0xF2, 0xBE, 0xBB, 0xFD, 0xBB, +0x13, 0x1F, 0xE2, 0x43, 0x7C, 0x9C, 0xD3, 0xEF, 0x41, 0xBB, 0xE1, 0x14, 0x07, 0x08, 0x10, 0x60, +0xD1, 0x6C, 0x86, 0x76, 0xF3, 0xD8, 0x81, 0xCF, 0x71, 0x6B, 0x3F, 0xC2, 0xC8, 0xEC, 0x47, 0x1C, +0xDC, 0xFD, 0x2A, 0xCD, 0x7E, 0xEC, 0x9D, 0x62, 0x50, 0x25, 0x3E, 0xC4, 0x87, 0xF8, 0x38, 0xBB, +0xEE, 0x4E, 0x58, 0x75, 0xA7, 0x39, 0x40, 0x80, 0x00, 0x8B, 0xE4, 0x5A, 0x68, 0xEF, 0x9F, 0x68, +0x3C, 0x58, 0x5E, 0xFB, 0x51, 0xDE, 0xF9, 0x2A, 0x0E, 0x0F, 0xA0, 0xD2, 0x5F, 0xB7, 0xC5, 0x87, +0xF8, 0x10, 0x1F, 0xE7, 0xF6, 0x7B, 0x90, 0xE5, 0x0B, 0xD1, 0x05, 0x08, 0x20, 0x40, 0x80, 0x05, +0x72, 0xB0, 0xB5, 0x39, 0xD1, 0x10, 0xF0, 0xB8, 0xB5, 0x1F, 0x43, 0xD7, 0xFF, 0xE8, 0x7F, 0x60, +0xDA, 0xF9, 0xEA, 0xA4, 0xB3, 0x1F, 0xE2, 0x43, 0x7C, 0x88, 0x8F, 0x29, 0xDE, 0xB7, 0x9D, 0xB0, +0x00, 0x01, 0x02, 0x2C, 0xDC, 0xE0, 0xA7, 0x35, 0xF9, 0x85, 0xCA, 0x86, 0x77, 0xBE, 0x2A, 0x6D, +0xC1, 0x3B, 0xF6, 0x02, 0x85, 0x2F, 0x89, 0x0F, 0xF1, 0x21, 0x3E, 0xCE, 0x2D, 0x3E, 0x92, 0xF6, +0x76, 0xFA, 0x37, 0x6E, 0x27, 0x2C, 0x40, 0x80, 0x00, 0x0B, 0xA4, 0xBD, 0xB7, 0x71, 0xC7, 0x61, +0xE0, 0xB1, 0xB3, 0x1F, 0x71, 0xF4, 0x63, 0x92, 0xF4, 0x1F, 0x5E, 0x0F, 0x4E, 0x30, 0xB8, 0x12, +0x1F, 0xE2, 0x43, 0x7C, 0xCC, 0xE8, 0xEB, 0xB4, 0xEB, 0x4E, 0x74, 0x80, 0x00, 0x01, 0x16, 0x63, +0xFC, 0x73, 0xEB, 0xE1, 0xC6, 0xC4, 0xEB, 0x3F, 0xC6, 0xCE, 0x7E, 0xC4, 0xEE, 0xE0, 0x7F, 0xE0, +0xB6, 0x70, 0xF2, 0xB5, 0x1F, 0xE2, 0x43, 0x7C, 0x88, 0x8F, 0x19, 0x7E, 0xAD, 0x13, 0xCC, 0x72, +0x02, 0x08, 0x10, 0x60, 0xC6, 0x06, 0xAF, 0x01, 0x32, 0x6E, 0x28, 0x78, 0xE4, 0xEC, 0x47, 0x1C, +0x8A, 0x93, 0x92, 0x93, 0xCC, 0x7E, 0x88, 0x0F, 0xF1, 0x21, 0x3E, 0x66, 0x2B, 0xDB, 0xD9, 0x88, +0x1F, 0x7F, 0xFB, 0x86, 0xD3, 0x1D, 0x20, 0x40, 0x80, 0xC5, 0x08, 0x90, 0x83, 0xAD, 0x89, 0xC6, +0x86, 0xFD, 0xEB, 0x7E, 0xA4, 0xB1, 0x53, 0x16, 0x07, 0x03, 0x20, 0x84, 0xD3, 0xCD, 0x7E, 0x88, +0x0F, 0xF1, 0x21, 0x3E, 0xE6, 0x10, 0x20, 0xF9, 0x42, 0x74, 0xB3, 0x20, 0x80, 0x00, 0x01, 0x16, +0x40, 0x7B, 0xF7, 0xFA, 0x91, 0xC3, 0xC1, 0xF2, 0xAE, 0x56, 0xA5, 0xC0, 0xC8, 0x9F, 0x76, 0x35, +0x34, 0x66, 0x1C, 0xB8, 0xEE, 0x47, 0xDA, 0xF5, 0x6A, 0x92, 0xD9, 0x0F, 0xF1, 0x21, 0x3E, 0xC4, +0xC7, 0x9C, 0xBE, 0xAE, 0x00, 0x01, 0x04, 0x08, 0xB0, 0x30, 0x01, 0xD2, 0xAC, 0x1F, 0xF9, 0xBE, +0x5A, 0x29, 0x3C, 0x42, 0xED, 0xF0, 0x69, 0x57, 0x31, 0x8C, 0xAE, 0x07, 0x29, 0x8F, 0x25, 0x77, +0xC4, 0x87, 0xF8, 0x10, 0x1F, 0x0B, 0x13, 0x1F, 0xF9, 0xBF, 0xF3, 0xED, 0xF4, 0xDA, 0x4E, 0x58, +0xC0, 0x99, 0xAD, 0x3B, 0x04, 0xC0, 0x99, 0x65, 0xCD, 0xCD, 0xB1, 0x43, 0xC2, 0x58, 0x1E, 0x1E, +0xD6, 0xFA, 0xBB, 0x5D, 0xC5, 0xE1, 0xEB, 0x7C, 0xC4, 0x31, 0xB3, 0x1F, 0x6D, 0xF1, 0x21, 0x3E, +0xC4, 0xC7, 0xC2, 0xC4, 0x47, 0xFF, 0x31, 0xB4, 0xCD, 0x80, 0x00, 0x67, 0x66, 0x06, 0x04, 0x38, +0xDB, 0x78, 0xE4, 0xD6, 0xC3, 0xF5, 0x23, 0x77, 0xC0, 0xAA, 0x1D, 0x86, 0xC6, 0xF0, 0xCC, 0x47, +0xF1, 0xB4, 0xAC, 0x91, 0x31, 0xD5, 0x24, 0xB3, 0x1F, 0xE2, 0x43, 0x7C, 0x88, 0x8F, 0x73, 0xFA, +0x8F, 0x0D, 0x7B, 0x02, 0x04, 0x10, 0x20, 0xC0, 0xB9, 0xEB, 0x04, 0xC8, 0xEE, 0xF8, 0x61, 0x61, +0x79, 0x06, 0xA4, 0x34, 0xF3, 0x71, 0xB8, 0x36, 0xA4, 0x76, 0x18, 0x06, 0xC5, 0xE7, 0xEC, 0xDE, +0x61, 0xF6, 0x43, 0x7C, 0x88, 0x0F, 0xF1, 0x71, 0x8E, 0x01, 0xB2, 0x6F, 0x17, 0x2C, 0x40, 0x80, +0x00, 0xE7, 0xAE, 0x11, 0xDA, 0xCD, 0xB1, 0xF1, 0x31, 0xB2, 0x08, 0x7D, 0x78, 0xF6, 0xA3, 0x3C, +0xB6, 0xCA, 0x77, 0xC5, 0x0A, 0xC7, 0xEF, 0x7C, 0x25, 0x3E, 0xC4, 0x87, 0xF8, 0x38, 0xE7, 0xC7, +0xD3, 0x0C, 0xF1, 0xE3, 0x6F, 0x6F, 0x38, 0xED, 0x01, 0x02, 0x04, 0x38, 0x4F, 0xD7, 0x8E, 0xBA, +0x06, 0xC8, 0xE0, 0x95, 0xCE, 0x0F, 0x83, 0x23, 0x96, 0x66, 0x3F, 0x06, 0xC6, 0x58, 0xBB, 0xF1, +0xE8, 0xB1, 0xA5, 0xF8, 0x10, 0x1F, 0xE2, 0xE3, 0xFC, 0x65, 0x7B, 0xE9, 0x75, 0xDD, 0x69, 0x0F, +0x10, 0x20, 0xC0, 0xF9, 0x69, 0xBE, 0x50, 0x1F, 0x19, 0x1A, 0xC6, 0xC3, 0xA7, 0x5D, 0x0D, 0x2C, +0x30, 0xEF, 0x7F, 0x40, 0x6D, 0x74, 0xFD, 0x47, 0x9A, 0xFD, 0x38, 0x6A, 0xED, 0x87, 0xF8, 0x10, +0x1F, 0xE2, 0x63, 0x11, 0x1E, 0x94, 0x00, 0x01, 0x04, 0x08, 0xB0, 0x00, 0xB2, 0xD6, 0xE6, 0x51, +0x03, 0xA8, 0xE1, 0x2D, 0x76, 0x8B, 0x20, 0x08, 0x71, 0xCC, 0x38, 0xEB, 0xA8, 0xD9, 0x0F, 0xF1, +0x21, 0x3E, 0xC4, 0xC7, 0x62, 0xC4, 0x47, 0xFE, 0x47, 0xBB, 0xF3, 0xD2, 0xBA, 0xE1, 0xC4, 0x07, +0x08, 0x10, 0xE0, 0x7C, 0x86, 0x24, 0xB7, 0x1E, 0xDE, 0xE8, 0x0C, 0x46, 0x36, 0x06, 0x86, 0x87, +0xBD, 0x8B, 0x0C, 0x0E, 0xAC, 0xF7, 0x88, 0x83, 0xE3, 0xC7, 0x89, 0x67, 0x3F, 0xC4, 0x87, 0xF8, +0x10, 0x1F, 0x8B, 0x13, 0x1F, 0xFD, 0x7F, 0xAF, 0x7B, 0x75, 0x67, 0x3F, 0x40, 0x80, 0x00, 0xE7, +0x65, 0x33, 0xB4, 0x76, 0x46, 0x07, 0x50, 0xBD, 0x0B, 0x0C, 0x8E, 0xDC, 0x7C, 0xD4, 0xEC, 0xC7, +0xD6, 0x98, 0xD9, 0x0F, 0xF1, 0x21, 0x3E, 0xC4, 0xC7, 0xE2, 0xC5, 0x47, 0x7E, 0x53, 0x4B, 0x80, +0x00, 0x02, 0x04, 0x38, 0x37, 0xF5, 0xB4, 0x00, 0x3D, 0x96, 0x06, 0x50, 0x83, 0x33, 0x21, 0xA1, +0xB4, 0xEF, 0xEE, 0xE1, 0x70, 0x66, 0xE0, 0xA2, 0x83, 0x69, 0xCB, 0xDD, 0xBD, 0x28, 0x3E, 0xC4, +0x87, 0xF8, 0xA8, 0x42, 0x7C, 0xE4, 0x37, 0x1F, 0xD8, 0x09, 0x0B, 0x10, 0x20, 0xC0, 0xB9, 0x8D, +0x4F, 0xEA, 0xA1, 0xB5, 0x5B, 0x1A, 0xFD, 0x87, 0xFE, 0xEC, 0x47, 0x1C, 0x09, 0x8E, 0xDA, 0xE8, +0x70, 0x26, 0xDD, 0xB0, 0x2D, 0x3E, 0xC4, 0x87, 0xF8, 0xA8, 0x4C, 0x7C, 0xE4, 0xFF, 0xD1, 0x60, +0x3B, 0xBD, 0x76, 0x3D, 0x10, 0x40, 0x80, 0x00, 0xE7, 0xA0, 0xBD, 0x77, 0x63, 0x60, 0xB7, 0xAB, +0xF2, 0xD8, 0x65, 0xCC, 0xDA, 0x8F, 0x81, 0xEB, 0x81, 0x24, 0x69, 0xED, 0xC7, 0x5E, 0x14, 0x1F, +0xE2, 0x43, 0x7C, 0x54, 0x25, 0x3E, 0xF2, 0x7F, 0xB7, 0xF9, 0xB6, 0xDB, 0xAE, 0x88, 0x0E, 0x08, +0x10, 0xE0, 0x1C, 0x64, 0xCD, 0xFA, 0x60, 0x1D, 0x0C, 0xCE, 0x7E, 0x1C, 0x6E, 0xC1, 0x5B, 0x1B, +0x7F, 0x81, 0xC2, 0x2D, 0xF1, 0x21, 0x3E, 0xC4, 0x47, 0xA5, 0xE2, 0x23, 0xFF, 0x90, 0x83, 0xF4, +0xFA, 0xBA, 0x13, 0x20, 0x20, 0x40, 0x80, 0xF9, 0x0F, 0x55, 0x0E, 0xB6, 0xEB, 0x03, 0x51, 0x51, +0x8C, 0x5F, 0xE2, 0x98, 0xB1, 0xD5, 0xF0, 0x3A, 0xF3, 0x34, 0x86, 0xD9, 0x8F, 0xE2, 0x43, 0x7C, +0x88, 0x8F, 0x2A, 0xC5, 0x47, 0xA1, 0x7D, 0xBB, 0xEE, 0x0C, 0x08, 0x08, 0x10, 0x60, 0xBE, 0x43, +0x95, 0x8F, 0x3E, 0xB4, 0x19, 0xB2, 0xFD, 0xA1, 0xC0, 0x98, 0x60, 0xF6, 0xA3, 0x78, 0x5A, 0xD6, +0xB6, 0xF8, 0x10, 0x1F, 0xE2, 0xA3, 0x92, 0xF1, 0x91, 0x7F, 0x78, 0xDB, 0x53, 0xB0, 0x00, 0x01, +0x02, 0xCC, 0x7D, 0x0C, 0x95, 0xEF, 0x80, 0x75, 0xEA, 0xD9, 0x8F, 0x83, 0x28, 0x3E, 0xC4, 0x87, +0xF8, 0xA8, 0x62, 0x7C, 0xE4, 0x9F, 0x92, 0xEF, 0x84, 0x25, 0x42, 0x00, 0x01, 0x02, 0xCC, 0xD5, +0xE6, 0xE1, 0x0E, 0x58, 0x27, 0x9D, 0xFD, 0xC8, 0xC4, 0x87, 0xF8, 0x10, 0x1F, 0x55, 0x8D, 0x8F, +0xA4, 0x9D, 0xFF, 0xDB, 0xAF, 0x3B, 0x0D, 0x02, 0x02, 0x04, 0x98, 0x9F, 0xEC, 0xE0, 0x5A, 0xC8, +0xDA, 0xA7, 0x98, 0xFD, 0xE8, 0xFC, 0xAD, 0x29, 0x3E, 0xC4, 0x87, 0xF8, 0xA8, 0x6C, 0x7C, 0xE4, +0x9F, 0x7A, 0xD0, 0xFD, 0x8F, 0x10, 0x00, 0x02, 0x04, 0x98, 0x9B, 0x56, 0x79, 0x01, 0x7A, 0x6D, +0x30, 0x38, 0xCA, 0xA1, 0x50, 0xBA, 0x2D, 0x1F, 0xEF, 0xBC, 0x94, 0x89, 0x0F, 0xF1, 0x21, 0x3E, +0xAA, 0x1C, 0x1F, 0xF9, 0x7F, 0x80, 0xD8, 0x4B, 0x57, 0x44, 0xB7, 0x13, 0x16, 0x20, 0x40, 0x80, +0x79, 0x8E, 0x5F, 0xB2, 0xC6, 0xE8, 0x53, 0xAE, 0x86, 0xAE, 0xF3, 0x11, 0x86, 0xAE, 0x7A, 0xBE, +0x9B, 0x75, 0xAF, 0x7C, 0x2E, 0x3E, 0xC4, 0x87, 0xF8, 0xA8, 0x6E, 0x7C, 0xF4, 0x23, 0x64, 0xDF, +0xC5, 0x08, 0x01, 0x01, 0x02, 0xCC, 0x47, 0xF6, 0x7B, 0x0F, 0xD5, 0x43, 0xBB, 0x39, 0x76, 0xED, +0xC7, 0xC8, 0x6D, 0xFD, 0x4F, 0xEA, 0xDC, 0xB2, 0x13, 0xC5, 0x87, 0xF8, 0x10, 0x1F, 0xCB, 0x10, +0x1F, 0xDD, 0x7F, 0xD4, 0x0D, 0x67, 0x43, 0x40, 0x80, 0x00, 0xF3, 0x1A, 0xC3, 0xD4, 0x63, 0xEB, +0x76, 0x3F, 0x16, 0xC2, 0xB8, 0xD9, 0x8F, 0xD2, 0xAC, 0x48, 0xFE, 0x2A, 0x5D, 0xF1, 0xBC, 0x2D, +0x3E, 0xC4, 0x87, 0xF8, 0x58, 0x8E, 0xF8, 0x08, 0xF9, 0xD3, 0xB0, 0xE2, 0xC7, 0xDF, 0x5E, 0x77, +0x42, 0x04, 0x04, 0x08, 0x30, 0x8F, 0x61, 0xCC, 0x66, 0x9A, 0x01, 0x19, 0x9E, 0xF9, 0x28, 0x16, +0x9C, 0x0F, 0x8C, 0xBD, 0xD2, 0x5F, 0xD2, 0xB2, 0x8F, 0xA1, 0xD9, 0x0F, 0xF1, 0x21, 0x3E, 0xC4, +0x47, 0xA8, 0xF6, 0xF1, 0xB7, 0x13, 0x16, 0x20, 0x40, 0x80, 0x39, 0xBA, 0x16, 0xDB, 0x07, 0x03, +0x33, 0x1F, 0xFD, 0xD9, 0x8F, 0x58, 0x2B, 0x05, 0x44, 0x6F, 0xD0, 0xB3, 0x3B, 0x38, 0xFB, 0x21, +0x3E, 0xC4, 0x87, 0xF8, 0x08, 0xD5, 0x3F, 0xFE, 0xDD, 0x9D, 0xB0, 0x1A, 0x4E, 0x87, 0x80, 0x00, +0x01, 0x66, 0xEF, 0x60, 0x6B, 0x33, 0x94, 0x9F, 0x72, 0x55, 0x9E, 0xFD, 0x08, 0xA5, 0xA7, 0x5D, +0xA5, 0x3F, 0x87, 0x66, 0x3F, 0xC4, 0x87, 0xF8, 0x10, 0x1F, 0x61, 0x39, 0x8E, 0x7F, 0xDA, 0x09, +0x2B, 0x84, 0x6B, 0x4E, 0x88, 0x80, 0x00, 0x01, 0x66, 0x2F, 0x3B, 0xA8, 0x17, 0x63, 0x9B, 0x7E, +0x6B, 0x14, 0x31, 0xD1, 0x1B, 0x88, 0x1D, 0xEE, 0x7C, 0x75, 0x78, 0x21, 0x10, 0xF1, 0x21, 0x3E, +0xC4, 0x47, 0x58, 0xAE, 0xE3, 0x9F, 0xED, 0xD7, 0x9D, 0x10, 0x01, 0x01, 0x02, 0xCC, 0x5E, 0x7B, +0xBF, 0x1E, 0xCB, 0xD7, 0xF6, 0x08, 0xDD, 0x98, 0x18, 0x78, 0xDA, 0x55, 0x3E, 0x38, 0x09, 0xFD, +0xD9, 0x0F, 0xF1, 0x21, 0x3E, 0xC4, 0x47, 0x58, 0xBE, 0xE3, 0x1F, 0x5B, 0x0D, 0x27, 0x44, 0x40, +0x80, 0x00, 0xB3, 0x6D, 0x8F, 0xDF, 0x79, 0xB8, 0x11, 0xD3, 0x16, 0xBC, 0x61, 0x30, 0x1C, 0x42, +0xE9, 0x69, 0x57, 0xFD, 0xF1, 0xD8, 0x76, 0x1C, 0xB9, 0x3A, 0xBA, 0xF8, 0x10, 0x1F, 0xE2, 0x63, +0x89, 0x8E, 0x7F, 0xB6, 0x93, 0x76, 0xC2, 0x72, 0x3D, 0x10, 0x40, 0x80, 0x00, 0x33, 0x95, 0x5F, +0x03, 0x64, 0x70, 0xF6, 0x23, 0xE6, 0x33, 0x1F, 0x03, 0x63, 0xB1, 0xB4, 0xE8, 0x7C, 0x37, 0x8A, +0x0F, 0xF1, 0x21, 0x3E, 0x96, 0x35, 0x3E, 0xF2, 0x00, 0xC9, 0xFF, 0x63, 0xC4, 0xA6, 0xD3, 0x22, +0x20, 0x40, 0x80, 0x59, 0x8E, 0x6F, 0xEA, 0xF1, 0x60, 0xAB, 0x14, 0x0F, 0x61, 0xE4, 0xCA, 0xE7, +0xB9, 0x6D, 0xF1, 0x21, 0x3E, 0xC4, 0xC7, 0x52, 0xC7, 0x47, 0xFE, 0x25, 0x0F, 0x04, 0x08, 0x20, +0x40, 0x80, 0x19, 0x8F, 0x37, 0xDA, 0xBB, 0xD7, 0x43, 0x39, 0x3A, 0xCA, 0x17, 0x21, 0x2C, 0xB4, +0x3B, 0x7F, 0xDF, 0x8D, 0xE2, 0x43, 0x7C, 0x88, 0x8F, 0x65, 0x3F, 0xFE, 0xED, 0xED, 0xF4, 0xDA, +0x4E, 0x58, 0x80, 0x00, 0x01, 0x66, 0xA8, 0xD5, 0xAC, 0x1F, 0xEE, 0x7C, 0x15, 0x07, 0xC6, 0x3F, +0xFD, 0xB8, 0xD8, 0x16, 0x1F, 0xE2, 0x43, 0x7C, 0xAC, 0xCC, 0xF1, 0xCF, 0xF6, 0xCD, 0x80, 0x00, +0x02, 0x04, 0x98, 0xE1, 0x50, 0x27, 0x6B, 0x6E, 0x1E, 0x5E, 0x00, 0xA4, 0x56, 0xDA, 0x82, 0xB7, +0xF7, 0xFE, 0xF4, 0x8C, 0x8C, 0xDD, 0x28, 0x3E, 0xC4, 0x87, 0xF8, 0x58, 0x95, 0xE3, 0x1F, 0x5B, +0x02, 0x04, 0x10, 0x20, 0xC0, 0x6C, 0xB4, 0xFE, 0xC5, 0xC3, 0xF5, 0xD0, 0xDE, 0x3F, 0x5C, 0x70, +0x1E, 0xC7, 0x8C, 0x83, 0xB6, 0xC4, 0x87, 0xF8, 0x10, 0x1F, 0x2B, 0x75, 0xFC, 0xB3, 0xBD, 0x0D, +0x3B, 0x61, 0x01, 0x02, 0x04, 0x98, 0xD1, 0x70, 0x27, 0xD6, 0xE3, 0xC1, 0xCE, 0xC0, 0xF0, 0x27, +0x96, 0x87, 0x42, 0x69, 0x43, 0x9C, 0x66, 0x14, 0x1F, 0xE2, 0x43, 0x7C, 0xAC, 0xD2, 0xF1, 0xB7, +0x10, 0x1D, 0x10, 0x20, 0xC0, 0x0C, 0xC7, 0x3C, 0x8D, 0x98, 0x15, 0x5B, 0xF0, 0x76, 0x03, 0xA3, +0x56, 0x7E, 0xF7, 0xB6, 0xF8, 0x10, 0x1F, 0xE2, 0x63, 0xE5, 0x8E, 0x7F, 0xB6, 0x97, 0x5E, 0xD7, +0x9D, 0x20, 0x01, 0x01, 0x02, 0xCC, 0x62, 0xD8, 0x73, 0x2D, 0x5D, 0x03, 0x24, 0x14, 0x31, 0x11, +0x4A, 0x5B, 0xF1, 0xA6, 0x9B, 0xF7, 0xA3, 0xF8, 0x10, 0x1F, 0xE2, 0x63, 0xD5, 0x8E, 0xBF, 0x00, +0x01, 0x04, 0x08, 0x30, 0x33, 0xFB, 0x2F, 0xD4, 0x87, 0xAF, 0xED, 0xD1, 0x7F, 0x0A, 0xD6, 0xED, +0x4C, 0x7C, 0x88, 0x0F, 0xF1, 0xB1, 0x8A, 0xC7, 0x3F, 0xA6, 0x7D, 0xB7, 0x5B, 0x37, 0x9C, 0x20, +0x01, 0x01, 0x02, 0x4C, 0x5F, 0x36, 0xBA, 0xDB, 0x4D, 0x2D, 0x8D, 0x89, 0xD2, 0x15, 0xCF, 0x0F, +0xC4, 0x87, 0xF8, 0x10, 0x1F, 0x2B, 0x7B, 0xFC, 0xB3, 0xBD, 0xBA, 0x13, 0x24, 0x20, 0x40, 0x80, +0xA9, 0x6A, 0x7E, 0xE4, 0xA1, 0x8D, 0x4E, 0x80, 0x6C, 0xE4, 0x4F, 0xBF, 0x0A, 0x83, 0x8B, 0xCF, +0xB3, 0xDB, 0x41, 0x7C, 0x88, 0x0F, 0xF1, 0xB1, 0xCA, 0xC7, 0x3F, 0xDB, 0x17, 0x20, 0x80, 0x00, +0x01, 0xA6, 0xAC, 0x16, 0x36, 0x63, 0x6B, 0xA7, 0x5F, 0x1A, 0xB5, 0x62, 0x4C, 0xB4, 0x1B, 0xBA, +0x57, 0x3E, 0x17, 0x1F, 0xE2, 0x43, 0x7C, 0xAC, 0xEE, 0xF1, 0x8F, 0x07, 0x21, 0x7E, 0xFC, 0xED, +0x0D, 0x27, 0x4A, 0x40, 0x80, 0x00, 0xD3, 0x54, 0x4F, 0x0B, 0xD0, 0x63, 0xAF, 0x46, 0x8A, 0x3F, +0xB3, 0xDB, 0x51, 0x7C, 0x88, 0x0F, 0xF1, 0xB1, 0xEA, 0xC7, 0xDF, 0x42, 0x74, 0x40, 0x80, 0x00, +0x33, 0x18, 0x9F, 0xD5, 0x63, 0x6B, 0xB7, 0x3B, 0x01, 0xD2, 0x1B, 0x18, 0xC5, 0xAD, 0xCE, 0x5B, +0x2D, 0xF1, 0x21, 0x3E, 0xC4, 0xC7, 0xCA, 0x1F, 0xFF, 0xAC, 0x29, 0x40, 0x00, 0x01, 0x02, 0x4C, +0x59, 0x7B, 0xAF, 0xBF, 0xCB, 0x4D, 0xAD, 0xB7, 0xDB, 0x55, 0x9A, 0xFD, 0x10, 0x1F, 0xE2, 0x43, +0x7C, 0x38, 0xFE, 0xF9, 0xC5, 0x08, 0xED, 0x84, 0x05, 0x08, 0x10, 0x60, 0xBA, 0x01, 0xD2, 0xAC, +0x97, 0xC7, 0x6C, 0xD9, 0x56, 0xE7, 0xCF, 0xAC, 0x37, 0x56, 0x12, 0x1F, 0xE2, 0x43, 0x7C, 0x38, +0xFE, 0xD9, 0xEE, 0x86, 0x13, 0x25, 0x30, 0x89, 0x75, 0x87, 0x00, 0x98, 0x48, 0x6B, 0xA7, 0x17, +0x20, 0xBD, 0xD9, 0x8F, 0xAD, 0xD8, 0x9F, 0xF9, 0x08, 0xE2, 0x43, 0x7C, 0x88, 0x0F, 0xC7, 0x3F, +0xB6, 0x37, 0x9D, 0x28, 0x81, 0x49, 0x98, 0x01, 0x01, 0xEE, 0xA8, 0xF9, 0xDB, 0x0F, 0x6D, 0x86, +0x6C, 0xBF, 0xD3, 0x1E, 0xB5, 0xFC, 0xEF, 0xF9, 0xEC, 0x47, 0xBB, 0x74, 0x15, 0x74, 0xF1, 0x21, +0x3E, 0xC4, 0x87, 0xE3, 0xDF, 0xDD, 0x09, 0x4B, 0x84, 0x00, 0x02, 0x04, 0x98, 0x8A, 0x7C, 0x07, +0xAC, 0x7C, 0x8C, 0x94, 0xC2, 0xE3, 0x76, 0x31, 0x58, 0xAA, 0x85, 0xDA, 0xC5, 0xF5, 0x70, 0xF5, +0xAD, 0xE2, 0x43, 0x7C, 0x88, 0x8F, 0x95, 0x3F, 0xFE, 0xED, 0xED, 0xF4, 0xBD, 0xD4, 0x9D, 0x2E, +0x01, 0x01, 0x02, 0x4C, 0xC3, 0x66, 0x68, 0xEF, 0x75, 0xC7, 0x18, 0x2F, 0xC5, 0x7C, 0xED, 0x47, +0xFE, 0xD4, 0xAB, 0xF5, 0x4E, 0x7C, 0xA4, 0x99, 0x8F, 0x97, 0x8B, 0x0F, 0xF1, 0x21, 0x3E, 0x56, +0xFE, 0xF8, 0x77, 0x77, 0xC2, 0x32, 0x03, 0x02, 0xDC, 0x91, 0x35, 0x20, 0xC0, 0x1D, 0xD5, 0xB2, +0x83, 0x6B, 0x31, 0x3D, 0xE7, 0xAA, 0xF3, 0xBF, 0x6C, 0xBB, 0x3B, 0x64, 0x4A, 0x33, 0x1F, 0xF7, +0xBC, 0x59, 0x7C, 0x88, 0x0F, 0xF1, 0xE1, 0xF8, 0xF7, 0xBE, 0x97, 0x98, 0x07, 0xC8, 0x75, 0x67, +0x4C, 0x40, 0x80, 0x00, 0x67, 0xD7, 0xDA, 0xAE, 0xA7, 0xB5, 0xE7, 0x69, 0xF6, 0x23, 0x8D, 0x33, +0x52, 0x7C, 0xDC, 0xFD, 0x26, 0xF1, 0x21, 0x3E, 0xC4, 0x87, 0xE3, 0x3F, 0xF4, 0xBD, 0xB4, 0x8B, +0xCD, 0x2A, 0x00, 0x04, 0x08, 0x70, 0x06, 0xB5, 0xD0, 0x6E, 0x84, 0x56, 0xCC, 0x17, 0x9F, 0x87, +0x4B, 0x9D, 0xF8, 0x78, 0xE3, 0xEB, 0xC4, 0x87, 0xF8, 0x10, 0x1F, 0x8E, 0xFF, 0x98, 0xEF, 0xC5, +0x4E, 0x58, 0xC0, 0x9D, 0x59, 0x03, 0x02, 0x1C, 0xAB, 0xFD, 0x3B, 0xAF, 0xAB, 0xA7, 0xA7, 0x56, +0xB4, 0xBE, 0x22, 0x3E, 0xC4, 0x87, 0xF8, 0x70, 0xFC, 0xEF, 0xF0, 0xBD, 0x64, 0x7B, 0x21, 0x7E, +0xFC, 0xAF, 0xD4, 0x9D, 0x39, 0x01, 0x01, 0x02, 0x9C, 0x45, 0x3D, 0xBB, 0x7D, 0x3B, 0xC4, 0xAC, +0x13, 0x1F, 0x6F, 0x10, 0x1F, 0xE2, 0x43, 0x7C, 0x38, 0xFE, 0xC7, 0x7C, 0x2F, 0xED, 0xDD, 0xFC, +0x9C, 0xE1, 0xB4, 0x09, 0x08, 0x10, 0xE0, 0xD4, 0x0E, 0xF6, 0xB3, 0xCD, 0xD6, 0xED, 0x2C, 0xDC, +0xD5, 0x89, 0x8F, 0x35, 0xF1, 0x21, 0x3E, 0xC4, 0x87, 0xE3, 0x7F, 0xCC, 0xF7, 0x12, 0xDB, 0x07, +0x61, 0xFF, 0xF6, 0x41, 0xC3, 0x99, 0x13, 0x38, 0x8E, 0x35, 0x20, 0xC0, 0xB1, 0x6E, 0x7F, 0x39, +0xBB, 0xB6, 0x7E, 0xED, 0x7A, 0xB8, 0x78, 0xE5, 0x6A, 0x58, 0x13, 0x1F, 0xE2, 0x43, 0x7C, 0x88, +0x8F, 0x23, 0xEC, 0xBE, 0x90, 0x85, 0xBD, 0x17, 0xB7, 0x42, 0xBC, 0xBC, 0x77, 0xCD, 0x99, 0x13, +0x10, 0x20, 0xC0, 0xA9, 0xAD, 0x7D, 0xE3, 0xD7, 0xBD, 0x3A, 0x76, 0xCE, 0x14, 0xB7, 0xFF, 0xF4, +0xD9, 0xB0, 0xBE, 0xF6, 0x5C, 0xB8, 0xE7, 0x81, 0x0B, 0x61, 0xED, 0xD4, 0x67, 0x0E, 0xF1, 0x21, +0x3E, 0xC4, 0xC7, 0xB2, 0xC5, 0xC7, 0xFE, 0x56, 0x0C, 0xBB, 0x5F, 0xCD, 0x42, 0xD6, 0xEA, 0xBD, +0x3F, 0xDB, 0xDD, 0x70, 0xE6, 0x04, 0x8E, 0x1D, 0x5B, 0x38, 0x04, 0xC0, 0x71, 0xFE, 0xCD, 0xAD, +0x7B, 0xDF, 0x71, 0xB0, 0xBD, 0xFB, 0xFE, 0xB8, 0xF7, 0xEC, 0x56, 0x6B, 0x2F, 0x86, 0x17, 0xFF, +0xB4, 0x15, 0xB6, 0x9F, 0xCB, 0xF2, 0x8B, 0x11, 0x8A, 0x0F, 0xF1, 0x21, 0x3E, 0x56, 0x37, 0x3E, +0xD2, 0xF9, 0xE0, 0xF6, 0x17, 0xDB, 0x61, 0xFB, 0xD9, 0x76, 0x11, 0x1F, 0x2F, 0x74, 0x5E, 0xDE, +0xF3, 0xE4, 0x2F, 0xFC, 0x7F, 0x3F, 0xE4, 0xCC, 0x09, 0x1C, 0xA7, 0xE6, 0x10, 0x00, 0x93, 0xF8, +0xF8, 0x7B, 0x36, 0x5F, 0xF9, 0x75, 0xAF, 0x6A, 0xBF, 0xFF, 0xC2, 0xC5, 0xF8, 0x8E, 0xFC, 0xE4, +0xB1, 0x16, 0xC2, 0x95, 0x7B, 0xD7, 0xC2, 0x95, 0x8D, 0x49, 0xFE, 0x3B, 0x86, 0xF8, 0x10, 0x1F, +0xE2, 0x63, 0x59, 0xE2, 0x23, 0x6B, 0x85, 0xB0, 0xF3, 0x95, 0x76, 0x68, 0xEE, 0xC4, 0xF2, 0x6D, +0xFF, 0x70, 0x6D, 0x3D, 0xFC, 0xD2, 0xD7, 0xFC, 0xC8, 0xA7, 0x5E, 0x70, 0xB6, 0x04, 0x04, 0x08, +0x30, 0x55, 0x9F, 0xFC, 0x6F, 0xAF, 0x5F, 0x7F, 0xF9, 0x9F, 0x6B, 0x7F, 0xB0, 0x33, 0xD8, 0xF8, +0xEE, 0xF4, 0xF7, 0xB5, 0xF5, 0x5A, 0xB8, 0xAB, 0x13, 0x21, 0x97, 0xAE, 0xD6, 0xC4, 0x87, 0xF8, +0x10, 0x1F, 0x4B, 0x1C, 0x1F, 0x69, 0xD6, 0x33, 0x3D, 0xD5, 0x6A, 0xEF, 0xA5, 0xC3, 0xE9, 0xCF, +0xAC, 0x1D, 0x7E, 0x77, 0xED, 0x42, 0xF8, 0x9B, 0x9D, 0xF0, 0xF8, 0x8C, 0xB3, 0x23, 0x20, 0x40, +0x80, 0x99, 0xFA, 0xDC, 0x07, 0xFF, 0xE2, 0x0F, 0xDE, 0x73, 0x7F, 0xF6, 0xAB, 0xB5, 0xB5, 0xF0, +0x8D, 0xE9, 0xEF, 0xEB, 0x57, 0xBA, 0x21, 0x92, 0xFE, 0x14, 0x1F, 0xE2, 0x43, 0x7C, 0x2C, 0x57, +0x7C, 0x74, 0x17, 0x98, 0x0F, 0x3C, 0xF5, 0xF2, 0x0F, 0x3B, 0x2F, 0x3F, 0xD3, 0x09, 0x8F, 0x8F, +0x39, 0x1B, 0x02, 0x02, 0x04, 0x98, 0x9B, 0xFF, 0xE3, 0xCD, 0xDF, 0xB5, 0xFE, 0x9D, 0x3F, 0xBA, +0xF7, 0x5F, 0x5C, 0xBE, 0x1A, 0xDF, 0xDB, 0x09, 0x91, 0xAB, 0xE9, 0xB6, 0x8B, 0x77, 0xD7, 0xC2, +0xDD, 0xF7, 0xAF, 0x9D, 0x61, 0xA1, 0xBA, 0xF8, 0x30, 0xF8, 0x15, 0x1F, 0x8B, 0xF2, 0xBD, 0x0C, +0x2F, 0x30, 0xEF, 0x04, 0xC8, 0x9F, 0x76, 0xFE, 0xAD, 0xFF, 0xED, 0x4E, 0x78, 0x7C, 0xD8, 0x19, +0x10, 0x10, 0x20, 0xC0, 0xB9, 0xF9, 0xDC, 0x07, 0xFF, 0xE2, 0x03, 0x97, 0xEE, 0x8A, 0x7F, 0xEB, +0xE2, 0x5D, 0xF1, 0xC7, 0xBB, 0x21, 0x12, 0xF3, 0xD9, 0x90, 0xCB, 0xF7, 0xAE, 0xE5, 0x6B, 0x45, +0xC4, 0x87, 0xC1, 0xAF, 0xF8, 0xA8, 0x56, 0x7C, 0xA4, 0x05, 0xE6, 0x29, 0x3C, 0x0E, 0xF6, 0xFA, +0xDF, 0x57, 0x5A, 0xDB, 0xF1, 0xF7, 0x3B, 0x2F, 0x1F, 0xB0, 0xCE, 0x03, 0x10, 0x20, 0xC0, 0x22, +0x85, 0xC8, 0x83, 0x57, 0x5E, 0x96, 0xFD, 0xF2, 0xFA, 0xE5, 0xF8, 0xF6, 0xFC, 0x04, 0xD3, 0x89, +0x8F, 0x22, 0x44, 0xC4, 0x87, 0xC1, 0xAF, 0xF8, 0x58, 0x7C, 0x69, 0xA6, 0x63, 0x78, 0x81, 0x79, +0xC7, 0x87, 0x5F, 0xFC, 0x42, 0xFB, 0xE7, 0xFF, 0xFC, 0xCF, 0x7E, 0xFA, 0x39, 0x67, 0x39, 0x40, +0x80, 0x00, 0x0B, 0xE9, 0x8B, 0xBF, 0xF5, 0xDA, 0xB7, 0xAE, 0x5F, 0x8C, 0xEF, 0xBD, 0x70, 0x29, +0x7C, 0x67, 0xFA, 0x7B, 0x5A, 0xA8, 0x9E, 0x9E, 0x96, 0x95, 0x9E, 0x9E, 0x25, 0x3E, 0x0C, 0x7E, +0xC5, 0xC7, 0x02, 0x7E, 0x17, 0xF9, 0x02, 0xF3, 0xF6, 0xC0, 0x02, 0xF3, 0x8E, 0x8F, 0xED, 0xBD, +0x98, 0xFD, 0xC4, 0x2B, 0xFF, 0xFA, 0x9F, 0x7C, 0xCA, 0x59, 0x0D, 0x10, 0x20, 0xC0, 0xC2, 0xFB, +0x17, 0x6F, 0xFC, 0x8E, 0xF5, 0xEF, 0xFA, 0xB1, 0xE6, 0x8F, 0x5C, 0xBE, 0x27, 0xBE, 0xEF, 0xF8, +0x85, 0xEA, 0xE2, 0x43, 0x7C, 0x88, 0x8F, 0xF3, 0x94, 0xA2, 0x23, 0xC5, 0x47, 0xB1, 0xC0, 0x3C, +0xB6, 0xC3, 0xBF, 0xAD, 0x75, 0x77, 0xB6, 0xFA, 0x98, 0x33, 0x19, 0x20, 0x40, 0x80, 0x2A, 0x86, +0xC8, 0x95, 0xEF, 0x7D, 0xD7, 0xFE, 0xE3, 0x6B, 0xEB, 0xE1, 0xA7, 0x8B, 0x85, 0xEA, 0x97, 0xAE, +0xAE, 0xE5, 0x21, 0x72, 0xC7, 0x85, 0xEA, 0xE2, 0x43, 0x7C, 0x88, 0x8F, 0x99, 0x49, 0x4F, 0xB3, +0x4A, 0x4F, 0xB7, 0xB2, 0xC0, 0x1C, 0x10, 0x20, 0xC0, 0x52, 0xFA, 0xF7, 0x7F, 0xEF, 0xDB, 0xBF, +0xFE, 0xBE, 0xFF, 0x20, 0xFE, 0xF2, 0xC5, 0x2B, 0xF1, 0xC7, 0xF3, 0x93, 0x4F, 0xEF, 0x42, 0x86, +0x47, 0x2E, 0x54, 0x17, 0x1F, 0xE2, 0x43, 0x7C, 0xCC, 0xC4, 0xE0, 0x02, 0xF3, 0xFE, 0x15, 0xCC, +0x2D, 0x30, 0x07, 0x04, 0x08, 0xB0, 0x9C, 0xFE, 0xE4, 0x03, 0xDF, 0xFE, 0x9A, 0xAB, 0x5F, 0x97, +0x7D, 0x60, 0xFD, 0x52, 0x78, 0x53, 0x11, 0x22, 0x77, 0xDF, 0x7F, 0x61, 0xF0, 0x42, 0x86, 0xE2, +0x43, 0x7C, 0x88, 0x8F, 0xA9, 0x4B, 0x57, 0x30, 0x4F, 0xE1, 0xB1, 0xBF, 0x95, 0x95, 0xBF, 0x17, +0x0B, 0xCC, 0x01, 0x01, 0x02, 0xAC, 0x86, 0x2F, 0xFC, 0xC6, 0x6B, 0x7F, 0xE0, 0xF2, 0xD5, 0xF8, +0xFE, 0xB5, 0xF5, 0xF0, 0x60, 0xFA, 0x7B, 0x5A, 0xA8, 0x7E, 0xCF, 0x03, 0x6B, 0x61, 0xFD, 0x72, +0xD5, 0x06, 0x8E, 0xE2, 0x43, 0x7C, 0x2C, 0xF8, 0xA1, 0xCC, 0x8A, 0x75, 0x1E, 0xE5, 0x05, 0xE6, +0xD1, 0x02, 0x73, 0x40, 0x80, 0x00, 0xAB, 0x27, 0x2D, 0x54, 0xFF, 0xEE, 0x77, 0x36, 0xDF, 0x75, +0xE1, 0x62, 0x7C, 0xF7, 0xDA, 0x85, 0xF0, 0xF5, 0xB1, 0x33, 0xE8, 0xBC, 0x78, 0xA5, 0xBB, 0x63, +0xD6, 0x85, 0x4B, 0xD3, 0x3C, 0x3D, 0x89, 0x0F, 0xF1, 0xB1, 0x9A, 0xC7, 0xBF, 0x08, 0x8F, 0xD1, +0x05, 0xE6, 0x9F, 0xFC, 0x98, 0x33, 0x10, 0x20, 0x40, 0x80, 0x95, 0xF5, 0xB9, 0x7F, 0xF4, 0xDA, +0x07, 0x2E, 0x5D, 0x8D, 0xBF, 0xB0, 0x7E, 0x29, 0xFE, 0x64, 0xB1, 0x50, 0xFD, 0xF2, 0xD5, 0xB5, +0x3C, 0x44, 0xCE, 0x7E, 0x21, 0x43, 0xF1, 0x21, 0x3E, 0x56, 0xEF, 0xF8, 0x77, 0x17, 0x98, 0x8F, +0xBB, 0x82, 0xF9, 0x27, 0x3F, 0xEC, 0x8C, 0x03, 0x08, 0x10, 0x80, 0x9E, 0x7F, 0xF3, 0x5F, 0xBF, +0xF6, 0x95, 0xAF, 0x78, 0x30, 0x7B, 0xFF, 0x85, 0x8B, 0xE1, 0x1D, 0xF9, 0x09, 0xAA, 0xB7, 0x50, +0xFD, 0xCA, 0xA9, 0xAF, 0xA8, 0x2E, 0x3E, 0xC4, 0xC7, 0x6A, 0x1D, 0xFF, 0xE3, 0xAF, 0x60, 0xFE, +0x49, 0x0B, 0xCC, 0x01, 0x01, 0x02, 0x30, 0xCE, 0x67, 0x7F, 0xED, 0x35, 0xAF, 0xBB, 0xFB, 0xE5, +0xF9, 0xFA, 0x90, 0xEF, 0x4E, 0x7F, 0x4F, 0xEB, 0x43, 0xF2, 0x2B, 0xAA, 0x5F, 0x3D, 0xC9, 0x29, +0x4B, 0x7C, 0x88, 0x8F, 0xD5, 0x39, 0xFE, 0xA3, 0x0B, 0xCC, 0x73, 0xBD, 0x05, 0xE6, 0x7F, 0x62, +0x81, 0x39, 0x20, 0x40, 0x00, 0x26, 0x0A, 0x91, 0x7F, 0xF4, 0x9A, 0x1F, 0xBC, 0xE7, 0xFE, 0xF8, +0xAB, 0xC5, 0x85, 0x0C, 0xD3, 0xBA, 0x90, 0x7B, 0xEE, 0x9F, 0xE4, 0x42, 0x86, 0xE2, 0x43, 0x7C, +0xAC, 0xC6, 0xF1, 0x1F, 0xBF, 0xC0, 0xBC, 0xB8, 0x82, 0xF9, 0x1F, 0x5B, 0x60, 0x0E, 0x08, 0x10, +0x80, 0x93, 0xFA, 0x48, 0xE3, 0xFA, 0xFA, 0x77, 0xBF, 0xB3, 0xF5, 0x0B, 0x17, 0xAF, 0xC4, 0x5F, +0x2C, 0xD6, 0x87, 0xA4, 0x85, 0xEA, 0xF7, 0x3C, 0x70, 0xE1, 0x88, 0x0B, 0x19, 0x8A, 0x0F, 0xF1, +0xB1, 0x1A, 0xC7, 0xDF, 0x02, 0x73, 0x40, 0x80, 0x00, 0xCC, 0xD0, 0x67, 0x7F, 0xED, 0x35, 0x0F, +0x5C, 0xBC, 0x3B, 0xFC, 0xAD, 0xCB, 0xF7, 0xC4, 0xC7, 0x8A, 0xDB, 0xD2, 0xDA, 0x90, 0xF4, 0xD4, +0xAC, 0xC3, 0xF5, 0x21, 0xE2, 0x43, 0x7C, 0x2C, 0xFF, 0xF1, 0xB7, 0xC0, 0x1C, 0x10, 0x20, 0x00, +0xF3, 0x0D, 0x91, 0x07, 0xAF, 0xDC, 0x1B, 0x7F, 0x79, 0xFD, 0x72, 0x78, 0x7B, 0x7E, 0x12, 0x5B, +0x2B, 0x42, 0x64, 0x56, 0xA7, 0x33, 0xF1, 0x21, 0x3E, 0x16, 0x83, 0x05, 0xE6, 0x80, 0x00, 0x01, +0x38, 0x47, 0xCF, 0x7C, 0xF8, 0x35, 0x6F, 0x5D, 0xBF, 0x18, 0xDF, 0x7B, 0xE1, 0x52, 0xF8, 0xCE, +0x34, 0x70, 0x3C, 0xDD, 0x42, 0x75, 0xF1, 0x21, 0x3E, 0x16, 0xFF, 0xF8, 0x5B, 0x60, 0x0E, 0x08, +0x10, 0x80, 0x05, 0x91, 0xD6, 0x87, 0x7C, 0xCF, 0xBB, 0x0E, 0xDE, 0xB5, 0x7E, 0x29, 0xFE, 0x52, +0xB1, 0x50, 0x3D, 0xAD, 0x0F, 0x49, 0x21, 0x72, 0xE7, 0x85, 0xEA, 0xE2, 0x43, 0x7C, 0x2C, 0xF6, +0xF1, 0x3F, 0x6A, 0x81, 0x79, 0x27, 0x3C, 0x7E, 0xAA, 0x13, 0x1E, 0x7F, 0xE4, 0x0C, 0x00, 0x08, +0x10, 0x80, 0x73, 0xF2, 0xCF, 0x1F, 0x7A, 0xCD, 0x95, 0x87, 0x7E, 0x2A, 0x7B, 0x7C, 0x6D, 0x3D, +0xFC, 0x74, 0xF9, 0x42, 0x86, 0x29, 0x44, 0xC6, 0x2F, 0x54, 0x17, 0x1F, 0xE2, 0x63, 0xB1, 0x8F, +0xFF, 0xB8, 0x05, 0xE6, 0xED, 0x83, 0xF8, 0x33, 0xAF, 0xF8, 0x6B, 0x9F, 0xFA, 0x97, 0xFE, 0xC5, +0x03, 0x02, 0x04, 0x60, 0x41, 0xFC, 0xBB, 0xF7, 0x7D, 0xDB, 0x2B, 0xEE, 0x7B, 0x65, 0x7C, 0xEF, +0xC5, 0x2B, 0xE1, 0xC7, 0x8B, 0xDB, 0x52, 0x84, 0x9C, 0xEC, 0x42, 0x86, 0xE2, 0x43, 0x7C, 0x9C, +0x9F, 0xE1, 0x05, 0xE6, 0x1D, 0x2F, 0x74, 0xC2, 0xE3, 0xE7, 0xBF, 0xEE, 0xC7, 0x3E, 0xF5, 0x1B, +0xFE, 0x85, 0x03, 0x02, 0x04, 0x60, 0x41, 0xFD, 0xF1, 0x7F, 0xFF, 0x6D, 0xAF, 0xB9, 0xF7, 0x1B, +0xE2, 0x6F, 0x14, 0x17, 0x32, 0x4C, 0xF1, 0x51, 0x84, 0x88, 0xF8, 0x10, 0x1F, 0x8B, 0x78, 0xFC, +0x87, 0x17, 0x98, 0xC7, 0x2C, 0x6C, 0x75, 0x7E, 0x6F, 0xFF, 0xBB, 0x60, 0x81, 0x39, 0x20, 0x40, +0x00, 0xAA, 0xE3, 0xF3, 0xFF, 0xE3, 0xB7, 0xFE, 0xC0, 0x95, 0x97, 0x85, 0x74, 0x45, 0xF5, 0x07, +0xD3, 0xDF, 0xD3, 0x42, 0xF5, 0xBB, 0xEF, 0x5F, 0x0B, 0x97, 0xEE, 0xAE, 0x89, 0x0F, 0xF1, 0xB1, +0x10, 0x8E, 0x5A, 0x60, 0xDE, 0x79, 0x79, 0x4F, 0x27, 0x3C, 0x3E, 0xE3, 0x5F, 0x31, 0x20, 0x40, +0x00, 0x2A, 0xE6, 0x9F, 0x3F, 0xF4, 0x9A, 0xF5, 0xEF, 0xFD, 0x1B, 0xD9, 0xBB, 0xD6, 0x2F, 0x85, +0xF7, 0x97, 0x2F, 0x64, 0x98, 0x42, 0x24, 0x5D, 0x59, 0x5D, 0x7C, 0x88, 0x8F, 0x73, 0x79, 0x14, +0x47, 0x2C, 0x30, 0x6F, 0x6E, 0xC7, 0x9F, 0xFF, 0x86, 0xFF, 0xEC, 0x53, 0xFF, 0xAF, 0x7F, 0xB9, +0x80, 0x00, 0x01, 0xA8, 0xB8, 0xCF, 0xFE, 0xDA, 0xB7, 0x3E, 0x70, 0xF9, 0x6A, 0xF8, 0x85, 0xF5, +0xCB, 0xE1, 0x27, 0x0F, 0x17, 0xAA, 0xD7, 0xCE, 0xB0, 0x50, 0x5D, 0x7C, 0x88, 0x8F, 0xD3, 0x19, +0x5E, 0x60, 0xDE, 0xF1, 0x99, 0xD6, 0x5E, 0xFC, 0x09, 0x0B, 0xCC, 0x01, 0x01, 0x02, 0xB0, 0x9C, +0x21, 0xF2, 0xEA, 0xBB, 0x36, 0xC2, 0xBB, 0x2F, 0x5C, 0x0C, 0xEF, 0x48, 0x03, 0xD2, 0xE2, 0x42, +0x86, 0x27, 0x5B, 0xA8, 0x2E, 0x3E, 0xC4, 0xC7, 0xC9, 0x59, 0x60, 0x0E, 0x20, 0x40, 0x80, 0x95, +0x0E, 0x91, 0x07, 0x5F, 0x77, 0xF7, 0xCB, 0xF3, 0xF5, 0x21, 0xFD, 0x85, 0xEA, 0x77, 0xDF, 0x7F, +0x61, 0xCA, 0x17, 0x32, 0x14, 0x1F, 0xE2, 0xC3, 0x02, 0x73, 0x00, 0x01, 0x02, 0x50, 0xF2, 0x85, +0xFF, 0xE9, 0xC1, 0xBF, 0x7A, 0xF9, 0x6A, 0x78, 0x5F, 0x71, 0x21, 0xC3, 0xB4, 0x50, 0xFD, 0xEA, +0x03, 0xD3, 0xB8, 0x90, 0xA1, 0xF8, 0x58, 0xF5, 0xF8, 0xB0, 0xC0, 0x1C, 0x40, 0x80, 0x00, 0x8C, +0xF5, 0xCF, 0xBE, 0xE7, 0xD5, 0xEB, 0xAF, 0xFB, 0xC9, 0xDA, 0x2F, 0x5C, 0xBC, 0x12, 0x7E, 0xB1, +0xBC, 0x50, 0xFD, 0x9E, 0x07, 0x2E, 0x9C, 0x71, 0x7D, 0x88, 0xF8, 0x58, 0xC5, 0xF8, 0xB0, 0xC0, +0x1C, 0x40, 0x80, 0x00, 0x4C, 0xE4, 0xB3, 0xFF, 0xF0, 0xC1, 0x07, 0x2E, 0xDF, 0x1B, 0xFE, 0x6E, +0xF9, 0x42, 0x86, 0xE9, 0x8A, 0xEA, 0x69, 0xC7, 0xAC, 0x93, 0xAF, 0x0F, 0x11, 0x1F, 0xAB, 0x18, +0x1F, 0xFB, 0x5B, 0x69, 0x9D, 0x47, 0xDB, 0x02, 0x73, 0x00, 0x01, 0x02, 0x70, 0xA2, 0x10, 0x79, +0xF5, 0x5D, 0x2F, 0x0F, 0x1F, 0xB8, 0x70, 0x31, 0x7C, 0x5F, 0x7E, 0xA2, 0x3C, 0xF1, 0x42, 0x75, +0xF1, 0xB1, 0x6A, 0xF1, 0x91, 0xD6, 0x79, 0x6C, 0x3D, 0x6B, 0x81, 0x39, 0x80, 0x00, 0x01, 0x38, +0x83, 0x67, 0x3E, 0xF4, 0xE0, 0x5B, 0x2F, 0x5E, 0x09, 0xEF, 0x2E, 0x16, 0xAA, 0xA7, 0xF5, 0x21, +0x69, 0xDB, 0xDE, 0xE3, 0x17, 0xAA, 0x8B, 0x8F, 0x55, 0x8A, 0x8F, 0x76, 0xB3, 0xBB, 0xB3, 0x95, +0x05, 0xE6, 0x00, 0x02, 0x04, 0x60, 0x2A, 0xD2, 0xFA, 0x90, 0x87, 0xFE, 0xF3, 0x5A, 0xBA, 0x90, +0xE1, 0x2F, 0x15, 0x0B, 0xD5, 0xD3, 0xFA, 0x90, 0x14, 0x22, 0xA3, 0x0B, 0xD5, 0xC5, 0xC7, 0xAA, +0xC4, 0x87, 0x05, 0xE6, 0x00, 0x02, 0x04, 0x60, 0xA6, 0xD2, 0xFA, 0x90, 0xBB, 0x36, 0xC2, 0xCF, +0xAD, 0xAD, 0x87, 0x9F, 0x2E, 0x16, 0xAA, 0x5F, 0xBA, 0xBB, 0x96, 0x6F, 0xDD, 0xDB, 0x5D, 0xA8, +0x2E, 0x3E, 0x56, 0x21, 0x3E, 0x8A, 0x05, 0xE6, 0x7B, 0x2F, 0x0E, 0x5C, 0x48, 0xD0, 0x02, 0x73, +0x00, 0x01, 0x02, 0x30, 0x1B, 0x7F, 0xF4, 0x77, 0x1F, 0x7C, 0xC5, 0xFD, 0xD7, 0xF2, 0xF5, 0x21, +0xEF, 0x28, 0x6E, 0xBB, 0xF2, 0xB2, 0x5A, 0xB8, 0xEB, 0xE5, 0xB3, 0xBE, 0x90, 0xA1, 0xF8, 0x38, +0xEF, 0xF8, 0x18, 0xB7, 0xC0, 0xBC, 0x13, 0x22, 0x3F, 0xF5, 0xCA, 0xBF, 0xFE, 0xC7, 0x4F, 0xFA, +0x97, 0x01, 0x20, 0x40, 0x00, 0x66, 0x2A, 0x2D, 0x54, 0xBF, 0xFB, 0xE5, 0xE1, 0xC3, 0x6B, 0xEB, +0xB1, 0x7F, 0x21, 0xC3, 0x2B, 0xF7, 0xAD, 0xE5, 0x4F, 0xCD, 0x12, 0x1F, 0xCB, 0x15, 0x1F, 0xE3, +0x16, 0x98, 0x37, 0x77, 0xE2, 0x7F, 0xF5, 0x0D, 0xEF, 0xFC, 0xD4, 0x07, 0xFD, 0x4B, 0x00, 0x10, +0x20, 0x00, 0x73, 0xF5, 0xF9, 0x5F, 0x7F, 0xF5, 0x0F, 0xDC, 0x75, 0x5F, 0xF8, 0x60, 0xF9, 0x42, +0x86, 0x77, 0x7F, 0xCD, 0x5A, 0xFE, 0xF4, 0x2C, 0xF1, 0x51, 0xED, 0xF8, 0x18, 0xB7, 0xC0, 0xBC, +0xF3, 0xF2, 0xF7, 0xD7, 0xD6, 0xC3, 0xFB, 0x2D, 0x30, 0x07, 0x10, 0x20, 0x00, 0xE7, 0xE6, 0x7F, +0xFB, 0xAE, 0x6F, 0x59, 0x7F, 0xF8, 0x6F, 0x5E, 0x48, 0x0B, 0xD5, 0xDF, 0x5F, 0xBE, 0x90, 0x61, +0x7A, 0x5A, 0xD6, 0xF4, 0xAE, 0xA8, 0x2E, 0x3E, 0xE6, 0x15, 0x1F, 0xE3, 0x16, 0x98, 0x67, 0xED, +0xF0, 0x4F, 0xD6, 0x2E, 0x84, 0x5F, 0xB2, 0xC0, 0x1C, 0x40, 0x80, 0x00, 0x2C, 0x8C, 0xCF, 0xFE, +0xEA, 0xAB, 0x1E, 0xB8, 0xB2, 0x51, 0xFB, 0xB9, 0x4E, 0x88, 0xFC, 0x62, 0x71, 0x5B, 0xBA, 0x90, +0x61, 0x0A, 0x91, 0xB3, 0x5D, 0x51, 0x5D, 0x7C, 0xCC, 0x23, 0x3E, 0x2C, 0x30, 0x07, 0x10, 0x20, +0x00, 0x55, 0x0D, 0x91, 0x57, 0xDF, 0xF5, 0xF2, 0xDA, 0xBB, 0xCB, 0x0B, 0xD5, 0x53, 0x84, 0x4C, +0x7E, 0x21, 0x43, 0xF1, 0x31, 0xEF, 0xF8, 0xB0, 0xC0, 0x1C, 0x40, 0x80, 0x00, 0x54, 0xDE, 0x33, +0xBF, 0xF9, 0xEA, 0x81, 0x0B, 0x19, 0xA6, 0xF8, 0x28, 0x42, 0x44, 0x7C, 0x2C, 0x46, 0x7C, 0x58, +0x60, 0x0E, 0x20, 0x40, 0x00, 0x96, 0xCE, 0x17, 0x7E, 0xE3, 0xD5, 0x7F, 0xF5, 0xF2, 0xD5, 0xF0, +0xBE, 0xF2, 0x42, 0xF5, 0xAB, 0x5F, 0xBB, 0xC0, 0xEB, 0x43, 0x56, 0x20, 0x3E, 0x2C, 0x30, 0x07, +0x10, 0x20, 0x00, 0x4B, 0x2D, 0x2D, 0x54, 0x6F, 0xFC, 0xEC, 0x85, 0xC7, 0x6B, 0xB5, 0xF0, 0x58, +0x79, 0xA1, 0x7A, 0xDA, 0x31, 0xEB, 0xC2, 0xA5, 0x05, 0x3A, 0x15, 0x2F, 0x79, 0x7C, 0x58, 0x60, +0x0E, 0x20, 0x40, 0x00, 0x56, 0x4A, 0x5A, 0xA8, 0x7E, 0xF9, 0xDE, 0xDA, 0xAF, 0x5C, 0xBC, 0x12, +0x7E, 0xA2, 0xB8, 0x6D, 0x61, 0x16, 0xAA, 0x2F, 0x71, 0x7C, 0x1C, 0xB5, 0xC0, 0xBC, 0xF3, 0xF2, +0x9E, 0x4E, 0x78, 0x7C, 0xCC, 0x6F, 0x26, 0x80, 0x00, 0x01, 0x58, 0xF6, 0x10, 0x49, 0x0B, 0xD5, +0xD3, 0x15, 0xD5, 0xBF, 0x2F, 0x3F, 0x19, 0xF7, 0x2E, 0x64, 0x78, 0x6E, 0x0B, 0xD5, 0x97, 0x38, +0x3E, 0xC6, 0x2D, 0x30, 0x6F, 0xED, 0xC7, 0x9F, 0x7F, 0xC5, 0x7F, 0xFA, 0xA9, 0x7F, 0xE6, 0x37, +0x11, 0x40, 0x80, 0x00, 0xAC, 0x94, 0xB4, 0x50, 0xFD, 0xD2, 0xDD, 0xF9, 0xF5, 0x43, 0x5E, 0x9B, +0xFE, 0x9E, 0xD6, 0x87, 0xA4, 0xD9, 0x90, 0xCB, 0x57, 0xE7, 0x78, 0x7A, 0x5E, 0xD2, 0xF8, 0x18, +0xB7, 0xC0, 0xBC, 0x7D, 0x10, 0xFE, 0xCE, 0xD7, 0xFD, 0xD8, 0x27, 0xDF, 0xEF, 0x37, 0x0F, 0x40, +0x80, 0x00, 0xAC, 0xAC, 0x7F, 0xFA, 0x1D, 0xF5, 0xF5, 0xD7, 0x3F, 0x76, 0x39, 0x5D, 0xC8, 0xF0, +0x97, 0x8A, 0x85, 0xEA, 0x69, 0x5D, 0xC8, 0x3D, 0x5F, 0x33, 0x87, 0x85, 0xEA, 0x4B, 0x18, 0x1F, +0xC3, 0x0B, 0xCC, 0x93, 0xAC, 0x15, 0xFE, 0x8E, 0x05, 0xE6, 0x00, 0x02, 0x04, 0x80, 0x92, 0xE2, +0x42, 0x86, 0x17, 0xD6, 0xC3, 0x4F, 0x97, 0x17, 0xAA, 0xDF, 0xF3, 0xB5, 0x17, 0x66, 0xB3, 0x3E, +0x64, 0xC9, 0xE2, 0xC3, 0x02, 0x73, 0x00, 0x01, 0x02, 0xC0, 0x29, 0x3C, 0xF3, 0x9B, 0xAF, 0xFA, +0xE6, 0xF5, 0xCB, 0xB5, 0xF7, 0x96, 0x2F, 0x64, 0x98, 0x16, 0xAA, 0xA7, 0x1D, 0xB3, 0xA6, 0xB6, +0x3E, 0x64, 0x89, 0xE2, 0xC3, 0x02, 0x73, 0x00, 0x01, 0x02, 0xC0, 0x14, 0x7C, 0xE9, 0xB7, 0x5E, +0xF5, 0x9D, 0x17, 0x2E, 0xD6, 0xFE, 0x87, 0xB5, 0xF5, 0xF0, 0x3D, 0xF9, 0x09, 0xBB, 0xB7, 0x50, +0xFD, 0xAE, 0x8D, 0x33, 0x56, 0xC8, 0x12, 0xC5, 0x87, 0x05, 0xE6, 0x00, 0x02, 0x04, 0x80, 0x29, +0xFB, 0xFC, 0xAF, 0xBF, 0xEA, 0x07, 0xEE, 0xBA, 0xAF, 0xF6, 0xC1, 0xF2, 0x85, 0x0C, 0x4F, 0xBD, +0x50, 0x7D, 0x49, 0xE2, 0xC3, 0x02, 0x73, 0x00, 0x01, 0x02, 0xC0, 0x0C, 0xA5, 0x85, 0xEA, 0x8F, +0xFC, 0x97, 0x97, 0x1F, 0xED, 0x44, 0xC8, 0xBB, 0xCB, 0xEB, 0x43, 0x52, 0x88, 0x4C, 0xBC, 0x50, +0x7D, 0x09, 0xE2, 0x63, 0xDC, 0x02, 0xF3, 0x4E, 0x8C, 0xFC, 0x37, 0x9D, 0x63, 0xF0, 0x3E, 0x0B, +0xCC, 0x01, 0x04, 0x08, 0x00, 0x53, 0x56, 0x2C, 0x54, 0x5F, 0xBF, 0x14, 0x7E, 0xB1, 0xB8, 0xED, +0xD2, 0xDD, 0xE9, 0x8A, 0xEA, 0x77, 0x58, 0xA8, 0x5E, 0xF1, 0xF8, 0x48, 0x4F, 0xB1, 0x4A, 0xE1, +0x51, 0x5E, 0x60, 0xDE, 0x6A, 0xC6, 0xFF, 0x75, 0xFD, 0x52, 0xED, 0x17, 0x2D, 0x30, 0x07, 0x10, +0x20, 0x00, 0xCC, 0x3E, 0x44, 0x5E, 0x7D, 0xCF, 0x03, 0xB5, 0x74, 0xFD, 0x90, 0xBF, 0x5C, 0xDC, +0x96, 0x2E, 0x62, 0x98, 0x66, 0x44, 0x46, 0x16, 0xAA, 0x57, 0x38, 0x3E, 0xC6, 0x2D, 0x30, 0xCF, +0xDA, 0xE1, 0x5F, 0xAF, 0x5D, 0x08, 0x7F, 0xDB, 0x02, 0x73, 0x00, 0x01, 0x02, 0xC0, 0x9C, 0x3D, +0xF3, 0x9B, 0xAF, 0x7A, 0xEB, 0xC5, 0x2B, 0xB5, 0xC7, 0xCB, 0x0B, 0xD5, 0x53, 0x84, 0xA4, 0x18, +0xA9, 0x7A, 0x7C, 0xA4, 0x05, 0xE6, 0x69, 0x5B, 0xDD, 0xD2, 0x3A, 0x0F, 0x0B, 0xCC, 0x01, 0x04, +0x08, 0x00, 0x8B, 0xE0, 0x4B, 0xFF, 0xF8, 0xD5, 0x7F, 0xA3, 0x7C, 0x21, 0xC3, 0xF4, 0x74, 0xAC, +0xBB, 0xEF, 0x5F, 0xCB, 0x9F, 0x9E, 0x55, 0xB5, 0xF8, 0x48, 0x0B, 0xCC, 0xB7, 0xBF, 0x92, 0xE5, +0xEB, 0x3D, 0x7A, 0xF2, 0x05, 0xE6, 0xFF, 0xF2, 0x57, 0x6E, 0x7F, 0xE0, 0x3F, 0xF9, 0xC4, 0x97, +0x5A, 0x7E, 0xDA, 0x00, 0x02, 0x04, 0x80, 0x05, 0x90, 0x2F, 0x54, 0xFF, 0xF9, 0xCB, 0x8F, 0xD7, +0x6A, 0xE1, 0xB1, 0xDA, 0x5A, 0x3C, 0x5C, 0xA8, 0xBE, 0x31, 0x87, 0x2B, 0xAA, 0x4F, 0x21, 0x3E, +0xD2, 0x85, 0x04, 0xB7, 0x9F, 0x6D, 0x5B, 0x60, 0x0E, 0x20, 0x40, 0x00, 0xA8, 0x92, 0xCF, 0xFC, +0x83, 0x6F, 0x79, 0xE0, 0xEE, 0xFB, 0xD7, 0xFE, 0xC1, 0xF0, 0x85, 0x0C, 0x53, 0x88, 0xCC, 0xE4, +0x8A, 0xEA, 0x67, 0x8C, 0x0F, 0x0B, 0xCC, 0x01, 0x04, 0x08, 0x00, 0xCB, 0x11, 0x22, 0xAF, 0xBE, +0xFA, 0xB5, 0x6B, 0xBF, 0x51, 0x5B, 0x0B, 0x0F, 0xE5, 0x27, 0xFC, 0xB5, 0xEE, 0x42, 0xF5, 0xF4, +0x32, 0xB5, 0x2B, 0xAA, 0x9F, 0x21, 0x3E, 0x2C, 0x30, 0x07, 0x10, 0x20, 0x00, 0x2C, 0xA1, 0x67, +0x7E, 0xF3, 0x2F, 0xBC, 0xF5, 0xD2, 0xDD, 0xF9, 0x8E, 0x59, 0xAF, 0x2D, 0x42, 0xE4, 0xEE, 0xFB, +0x2F, 0x9C, 0xEE, 0x42, 0x86, 0x53, 0x8A, 0x0F, 0x0B, 0xCC, 0x01, 0x04, 0x08, 0x00, 0x4B, 0xEC, +0x7F, 0xB9, 0xFE, 0x8D, 0xEB, 0x8D, 0x9F, 0xBD, 0xEB, 0x5D, 0x17, 0xEF, 0xAA, 0xBD, 0xAF, 0xF3, +0xD7, 0x8D, 0x74, 0x5B, 0xBA, 0xA2, 0xFA, 0xD5, 0x07, 0x66, 0xB9, 0x3E, 0x64, 0x34, 0x3E, 0x2C, +0x30, 0x07, 0x40, 0x80, 0x00, 0xAC, 0x90, 0xB4, 0x3E, 0xE4, 0xAE, 0x97, 0xD7, 0x7E, 0xEE, 0xC2, +0x7A, 0xED, 0xA7, 0xCB, 0x57, 0x54, 0x4F, 0x3B, 0x66, 0x5D, 0xB8, 0x34, 0xCD, 0xFF, 0x4B, 0x18, +0x8C, 0x0F, 0x0B, 0xCC, 0x01, 0x10, 0x20, 0x00, 0x2B, 0xEC, 0x99, 0xDF, 0xFC, 0x0B, 0xDF, 0xBC, +0x7E, 0xB9, 0xF6, 0xDE, 0xE1, 0x85, 0xEA, 0x57, 0xEE, 0xAD, 0x4D, 0x21, 0x44, 0xE2, 0x40, 0x78, +0xA4, 0xA7, 0x5A, 0x59, 0x60, 0x0E, 0x80, 0x00, 0x01, 0x20, 0x7C, 0xE5, 0x9F, 0xBE, 0xAA, 0xD1, +0x89, 0x84, 0x5F, 0x29, 0x2E, 0x64, 0x98, 0xA4, 0x00, 0x49, 0x0B, 0xD5, 0xD3, 0xCC, 0xC8, 0xC9, +0x77, 0xCD, 0x8A, 0xF9, 0x82, 0xF2, 0xE6, 0x4E, 0x0C, 0xCD, 0xDB, 0xD9, 0xC0, 0x8C, 0x47, 0x6C, +0x87, 0x7F, 0x5D, 0xB3, 0xC0, 0x1C, 0x40, 0x80, 0x38, 0x04, 0x00, 0xFC, 0xD9, 0x3F, 0x79, 0xD5, +0x5F, 0xB9, 0x70, 0x31, 0xBC, 0xBF, 0xF3, 0x66, 0xBD, 0x7C, 0x7B, 0x8A, 0x91, 0x22, 0x44, 0xD6, +0x3B, 0x6F, 0xA7, 0x05, 0xEC, 0xE5, 0x19, 0x92, 0xB4, 0x96, 0x23, 0x05, 0x47, 0xAB, 0xF3, 0x67, +0x5A, 0x50, 0x7E, 0xB0, 0x1B, 0xCB, 0xEB, 0x3B, 0x0A, 0x9F, 0xE9, 0xBC, 0xBC, 0xA7, 0x13, 0x1E, +0x1F, 0x76, 0xA4, 0x01, 0x10, 0x20, 0x00, 0xF4, 0xA5, 0x1D, 0xB3, 0xD6, 0x2F, 0xD7, 0x1E, 0xED, +0xC4, 0xC8, 0xF7, 0x9F, 0xE8, 0x13, 0xE3, 0xD8, 0xDD, 0xAE, 0x7E, 0x7B, 0xEF, 0xA5, 0xF8, 0xEB, +0xAF, 0xFC, 0x89, 0x4F, 0x3D, 0xE9, 0xC8, 0x02, 0x20, 0x40, 0x00, 0x38, 0x52, 0x5A, 0xAC, 0x7E, +0xF9, 0x65, 0xB5, 0x37, 0x5E, 0x58, 0xAF, 0x35, 0x6A, 0x6B, 0xA1, 0xB1, 0xB6, 0x1E, 0x1E, 0xBC, +0x53, 0x7C, 0xC4, 0x2C, 0xFC, 0xDB, 0xCE, 0x9B, 0x7F, 0xB8, 0x76, 0x21, 0xFC, 0x5F, 0x2F, 0x7D, +0xB1, 0xFD, 0xBB, 0xDF, 0xF4, 0xD8, 0x9F, 0x3C, 0xE7, 0x48, 0x02, 0x20, 0x40, 0x00, 0x38, 0xB1, +0xB4, 0x8D, 0xEF, 0x77, 0xFF, 0xF8, 0x95, 0x6F, 0x7E, 0xD9, 0x2B, 0xD6, 0xBE, 0x61, 0xF8, 0x7D, +0x9D, 0xD8, 0xF8, 0xE2, 0x37, 0x3D, 0xFA, 0xC7, 0xFF, 0xCE, 0x51, 0x02, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0xC7, +0xFF, 0x2F, 0xC0, 0x00, 0x23, 0xF2, 0x4C, 0x01, 0x21, 0x26, 0xDF, 0x39, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82}; diff --git a/libesp32/ESP32-Mail-Client/examples/Set_flag/Set_flag.ino b/libesp32/ESP32-Mail-Client/examples/Set_flag/Set_flag.ino new file mode 100755 index 000000000..e9ff771e4 --- /dev/null +++ b/libesp32/ESP32-Mail-Client/examples/Set_flag/Set_flag.ino @@ -0,0 +1,70 @@ +/* + * Created by K. Suwatchai (Mobizt) + * + * Email: k_suwatchai@hotmail.com + * + * Github: https://github.com/mobizt + * + * Copyright (c) 2019 mobizt + * +*/ + + +#include +#include "ESP32_MailClient.h" + +#define WIFI_SSID "YOUR_WIFI_SSID" +#define WIFI_PASSWORD "YOUR_WIFI_PASSWORD" + +//The Email Reading data object contains config and data that received +IMAPData imapData; + +void readEmail(); + +unsigned long lastTime = 0; + +void setup() +{ + + Serial.begin(115200); + Serial.println(); + + Serial.print("Connecting to AP"); + + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(200); + } + + Serial.println(""); + Serial.println("WiFi connected."); + Serial.println("IP address: "); + Serial.println(WiFi.localIP()); + + Serial.println(); + + Serial.println(); + + imapData.setLogin("imap.gmail.com", 993, "YOUR_EMAIL_ACCOUNT@gmail.com", "YOUR_EMAIL_PASSWORD"); + imapData.setFolder("INBOX"); + imapData.setDebug(true); + + //Set \Seen and \Answered to flags for message with UID 100 + MailClient.setFlag(imapData, 100, "\\Seen \\Answered"); + + //Add \Seen and \Answered to flags for message with UID 100 + //MailClient.addFlag(imapData, 100, "\\Seen \\Answered"); + + //Remove \Seen and \Answered from flags for message with UID 100 + //MailClient.removeFlag(imapData, 100, "\\Seen \\Answered"); +} + + + +void loop() +{ + +} + diff --git a/libesp32/ESP32-Mail-Client/examples/Time/Time.ino b/libesp32/ESP32-Mail-Client/examples/Time/Time.ino new file mode 100755 index 000000000..4726064d3 --- /dev/null +++ b/libesp32/ESP32-Mail-Client/examples/Time/Time.ino @@ -0,0 +1,136 @@ +/* + * Created by K. Suwatchai (Mobizt) + * + * Email: k_suwatchai@hotmail.com + * + * Github: https://github.com/mobizt + * + * Copyright (c) 2019 mobizt + * +*/ + + +#include +#include "ESP32_MailClient.h" + +#define WIFI_SSID "YOUR_WIFI_SSID" +#define WIFI_PASSWORD "YOUR_WIFI_PASSWORD" + + +void setup() +{ + + Serial.begin(115200); + Serial.println(); + + Serial.print("Connecting to AP"); + + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(200); + } + + Serial.println(""); + Serial.println("WiFi connected."); + Serial.println("IP address: "); + Serial.println(WiFi.localIP()); + + Serial.println(); + + //Set Clock + //GMT offset (3 Hrs), Daylight offset (0 Hrs) + MailClient.Time.setClock(3, 0); + + Serial.println("Number of Days This Year (since January): " + String(MailClient.Time.getNumberOfDayThisYear())); + Serial.println("Day of Week Number: " + String(MailClient.Time.getDayOfWeek())); + Serial.println("Day of Week String: : " + String(MailClient.Time.getDayOfWeekString())); + Serial.println("Total seconds today: : " + String(MailClient.Time.getCurrentSecond())); + Serial.println(); +} + +void loop() +{ + + if (!MailClient.Time.clockReady) + return; + + //Print out current date and time + int d = MailClient.Time.getDay(); + int m = MailClient.Time.getMonth(); + int y = MailClient.Time.getYear(); + int hr = MailClient.Time.getHour(); + int min = MailClient.Time.getMin(); + int sec = MailClient.Time.getSec(); + Serial.print("Current Time (GMT+3): "); + Serial.print(d); + Serial.print("/"); + Serial.print(m); + Serial.print("/"); + Serial.print(y); + Serial.print(" "); + Serial.print(hr); + Serial.print(":"); + Serial.print(min); + Serial.print(":"); + Serial.println(sec); + + uint32_t todayFromMidnightTimestamp = MailClient.Time.getTimestamp(y, m, d, 0, 0, 0); + uint32_t currentTimestamp = MailClient.Time.getUnixTime(); + uint32_t totalSecondsFromMidnight = currentTimestamp - todayFromMidnightTimestamp; + + //Assumed we countdown until 15:00:00 everyday + uint8_t targetSec = 0; + uint8_t targetMin = 0; + uint8_t targetHr = 15; + uint32_t targetSecondsFromMidnight = targetHr * 60 * 60 + targetMin * 60 + targetSec; + + if (targetSecondsFromMidnight >= totalSecondsFromMidnight) + { + uint32_t diffSeconds = targetSecondsFromMidnight - totalSecondsFromMidnight; + int remainYrs, remainMonths, remainDays, remainHr, remainMin, remainSec; + MailClient.Time.getTimeFromSec(diffSeconds, remainYrs, remainMonths, remainDays, remainHr, remainMin, remainSec); + Serial.print("Everyday countdown until 15:00:00 is "); + Serial.print(remainHr); + Serial.print(" Hr, "); + Serial.print(remainMin); + Serial.print(" Min and "); + Serial.print(remainSec); + Serial.println(" Sec to go."); + } + else + { + Serial.println("Everyday countdown until 15:00:00 was passed."); + } + + //Assumed we countdown until 18/12/2019 8:30:45 + uint32_t targetTimestamp = MailClient.Time.getTimestamp(2019, 12, 18, 8, 30, 45); + if (targetTimestamp >= currentTimestamp) + { + uint32_t diffSeconds = targetTimestamp - currentTimestamp; + int remainYrs, remainMonths, remainDays, remainHr, remainMin, remainSec; + MailClient.Time.getTimeFromSec(diffSeconds, remainYrs, remainMonths, remainDays, remainHr, remainMin, remainSec); + Serial.print("One time countdown until 18/12/2019 8:30:45 is "); + Serial.print(remainYrs); + Serial.print(" Years, "); + Serial.print(remainMonths); + Serial.print(" Months, "); + Serial.print(remainDays); + Serial.print(" Days, "); + Serial.print(remainHr); + Serial.print(" Hr, "); + Serial.print(remainMin); + Serial.print(" Min and "); + Serial.print(remainSec); + Serial.println(" Sec to go."); + } + else + { + Serial.println("One time countdown until 18/12/2019 8:30:45 was finished."); + } + Serial.println(); + + delay(1000); +} + diff --git a/libesp32/ESP32-Mail-Client/keywords.txt b/libesp32/ESP32-Mail-Client/keywords.txt new file mode 100755 index 000000000..81b7ee9b2 --- /dev/null +++ b/libesp32/ESP32-Mail-Client/keywords.txt @@ -0,0 +1,166 @@ +####################################### +# Syntax Coloring Map ESP32-Mail-Client +####################################### + +####################################### +# Classes (KEYWORD1) +####################################### + +IMAPData KEYWORD1 +SMTPData KEYWORD1 +attachmentData KEYWORD1 +SendStatus KEYWORD1 +messageBodyData KEYWORD1 +DownloadProgress KEYWORD1 +MessageData KEYWORD1 + +TIME KEYWORD1 + + +################################## +# Methods and Functions (KEYWORD2) +################################## + +sendMail KEYWORD2 +readMail KEYWORD2 +smtpErrorReason KEYWORD2 +imapErrorReason KEYWORD2 +sdBegin KEYWORD2 +setFlag KEYWORD2 +addFlag KEYWORD2 +removeFlag KEYWORD2 + + +setClock KEYWORD2 +getUnixTime KEYWORD2 +getTimestamp KEYWORD2 +getYear KEYWORD2 +getMonth KEYWORD2 +getDay KEYWORD2 +getDayOfWeek KEYWORD2 +getDayOfWeekString KEYWORD2 +getHour KEYWORD2 +getMin KEYWORD2 +getSec KEYWORD2 +getNumberOfDayThisYear KEYWORD2 +getTotalDays KEYWORD2 +dayofweek KEYWORD2 +getCurrentSecond KEYWORD2 +getCurrentTimestamp KEYWORD2 +getTimeFromSec KEYWORD2 + +######################################### +# Methods for IMAP Data object (KEYWORD2) +######################################### + +setLogin KEYWORD2 +setSTARTTLS KEYWORD2 +setDebug KEYWORD2 +setFolder KEYWORD2 +setMessageBufferSize KEYWORD2 +setAttachmentSizeLimit KEYWORD2 +setSearchCriteria KEYWORD2 +setSaveFilePath KEYWORD2 +setFechUID KEYWORD2 +setDownloadAttachment KEYWORD2 +setHTMLMessage KEYWORD2 +setTextMessage KEYWORD2 +setSearchLimit KEYWORD2 +setRecentSort KEYWORD2 +setReadCallback KEYWORD2 +setDownloadReport KEYWORD2 +isHeaderOnly KEYWORD2 +getFrom KEYWORD2 +getFromCharset KEYWORD2 +getTo KEYWORD2 +getToCharset KEYWORD2 +getCC KEYWORD2 +getCCCharset KEYWORD2 +getSubject KEYWORD2 +getSubjectCharset KEYWORD2 +getHTMLMessage KEYWORD2 +getTextMessage KEYWORD2 +getHTMLMessgaeCharset KEYWORD2 +getTextMessgaeCharset KEYWORD2 +getDate KEYWORD2 +getUID KEYWORD2 +getNumber KEYWORD2 +getMessageID KEYWORD2 +getAcceptLanguage KEYWORD2 +getContentLanguage KEYWORD2 +isFetchMessageFailed KEYWORD2 +getFetchMessageFailedReason KEYWORD2 +isDownloadAttachmentFailed KEYWORD2 +getDownloadAttachmentFailedReason KEYWORD2 +isDownloadMessageFailed KEYWORD2 +getDownloadMessageFailedReason KEYWORD2 +saveHTMLMessage KEYWORD2 +saveTextMessage KEYWORD2 +getFolderCount KEYWORD2 +getFolder KEYWORD2 +getFlagCount KEYWORD2 +getFlag KEYWORD2 +totalMessages KEYWORD2 +searchCount KEYWORD2 +availableMessages KEYWORD2 +getAttachmentCount KEYWORD2 +getAttachmentFileName KEYWORD2 +getAttachmentName KEYWORD2 +getAttachmentFileSize KEYWORD2 +getAttachmentCreationDate KEYWORD2 +getAttachmentType KEYWORD2 +empty KEYWORD2 +clearMessageData KEYWORD2 + +######################################### +# Methods for SMTP Data object (KEYWORD2) +######################################### + +setSender KEYWORD2 +getFromName KEYWORD2 +getSenderEmail KEYWORD2 +setPriority KEYWORD2 +getPriority KEYWORD2 +addRecipient KEYWORD2 +removeRecipient KEYWORD2 +clearRecipient KEYWORD2 +getRecipient KEYWORD2 +recipientCount KEYWORD2 +setSubject KEYWORD2 +getSubject KEYWORD2 +setMessage KEYWORD2 +getMessage KEYWORD2 +htmlFormat KEYWORD2 +addCC KEYWORD2 +removeCC KEYWORD2 +clearCC KEYWORD2 +getCC KEYWORD2 +ccCount KEYWORD2 +addBCC KEYWORD2 +removeBCC KEYWORD2 +clearBCC KEYWORD2 +getBCC KEYWORD2 +bccCount KEYWORD2 +addAttachData KEYWORD2 +removeAttachData KEYWORD2 +attachDataCount KEYWORD2 +addAttachFile KEYWORD2 +removeAttachFile KEYWORD2 +clearAttachData KEYWORD2 +clearAttachFile KEYWORD2 +clearAttachment KEYWORD2 +attachFileCount KEYWORD2 +setSendCallback KEYWORD2 + + +############################################################ +# Functions for ReadStatus and SendStatus classes (KEYWORD2) +############################################################ + +SendStatus KEYWORD2 +info KEYWORD2 +success KEYWORD2 +ReadStatus KEYWORD2 +status KEYWORD2 + +clockReady KEYWORD3 \ No newline at end of file diff --git a/libesp32/ESP32-Mail-Client/library.properties b/libesp32/ESP32-Mail-Client/library.properties new file mode 100755 index 000000000..6ff993e8b --- /dev/null +++ b/libesp32/ESP32-Mail-Client/library.properties @@ -0,0 +1,17 @@ +name=ESP32 Mail Client + +version=2.1.4 + +author=Mobizt + +maintainer=Mobizt + +sentence=Mail Client Arduino Library for ESP32 + +paragraph=This library allows ESP32 to send Email with/without attachment and receive Email with/without attachment download through SMTP and IMAP servers. + +category=Communication + +url=https://github.com/mobizt/ESP32-Mail-Client + +architectures=esp32 diff --git a/libesp32/ESP32-Mail-Client/media/images/esp32-mail.jpg b/libesp32/ESP32-Mail-Client/media/images/esp32-mail.jpg new file mode 100755 index 000000000..d4c62c865 Binary files /dev/null and b/libesp32/ESP32-Mail-Client/media/images/esp32-mail.jpg differ diff --git a/libesp32/ESP32-Mail-Client/media/images/esp32-mail.png b/libesp32/ESP32-Mail-Client/media/images/esp32-mail.png new file mode 100755 index 000000000..459238782 Binary files /dev/null and b/libesp32/ESP32-Mail-Client/media/images/esp32-mail.png differ diff --git a/libesp32/ESP32-Mail-Client/src/ESP32MailHTTPClient.cpp b/libesp32/ESP32-Mail-Client/src/ESP32MailHTTPClient.cpp new file mode 100755 index 000000000..39df83f7e --- /dev/null +++ b/libesp32/ESP32-Mail-Client/src/ESP32MailHTTPClient.cpp @@ -0,0 +1,200 @@ +/* + * Customized version of ESP32 HTTPClient Library. + * Allow custom header and payload with STARTTLS support + * + * v 1.0.0 + * + * The MIT License (MIT) + * Copyright (c) 2019 K. Suwatchai (Mobizt) + * + * HTTPClient Arduino library for ESP32 + * + * Copyright (c) 2015 Markus Sattler. All rights reserved. + * This file is part of the HTTPClient for Arduino. + * Port to ESP32 by Evandro Luis Copercini (2017), + * changed fingerprints to CA verification. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * +*/ + +#ifndef ESP32MailHTTPClient_CPP +#define ESP32MailHTTPClient_CPP + +#ifdef ESP32 + +#include "ESP32MailHTTPClient.h" + +class TransportTraits +{ +public: + virtual ~TransportTraits() {} + + virtual std::unique_ptr create() + { + return std::unique_ptr(new WiFiClient()); + } + + virtual bool + verify(WiFiClient &client, const char *host, bool starttls, DebugMsgCallback cb) + { + return true; + } +}; + +class TLSTraits : public TransportTraits +{ +public: + TLSTraits(const char *CAcert, const char *clicert = nullptr, const char *clikey = nullptr) : _cacert(CAcert), _clicert(clicert), _clikey(clikey) {} + + std::unique_ptr create() override + { + return std::unique_ptr(new WiFiClientSecureESP32()); + } + + bool verify(WiFiClient &client, const char *host, bool starttls, DebugMsgCallback cb) override + { + WiFiClientSecureESP32 &wcs = static_cast(client); + wcs.setCACert(_cacert); + wcs.setCertificate(_clicert); + wcs.setPrivateKey(_clikey); + wcs.setSTARTTLS(starttls); + wcs.setDebugCB(cb); + return true; + } + +protected: + const char *_cacert; + const char *_clicert; + const char *_clikey; +}; + +ESP32MailHTTPClient::ESP32MailHTTPClient() {} + +ESP32MailHTTPClient::~ESP32MailHTTPClient() +{ + if (_client) + _client->stop(); +} + +bool ESP32MailHTTPClient::begin(const char *host, uint16_t port, const char *uri, const char *CAcert) +{ + transportTraits.reset(nullptr); + + _host = host; + _port = port; + _uri = uri; + transportTraits = TransportTraitsPtr(new TLSTraits(CAcert)); + return true; +} + +bool ESP32MailHTTPClient::connected() +{ + if (_client) + return ((_client->available() > 0) || _client->connected()); + return false; +} + +bool ESP32MailHTTPClient::sendHeader(const char *header) +{ + if (!connected()) + return false; + return (_client->write(header, strlen(header)) == strlen(header)); +} + +int ESP32MailHTTPClient::sendRequest(const char *header, const char *payload) +{ + size_t size = strlen(payload); + if (strlen(header) > 0) + { + if (!connect()) + return HTTPC_ERROR_CONNECTION_REFUSED; + if (!sendHeader(header)) + return HTTPC_ERROR_SEND_HEADER_FAILED; + } + if (size > 0) + if (_client->write(&payload[0], size) != size) + return HTTPC_ERROR_SEND_PAYLOAD_FAILED; + + return 0; +} + +WiFiClient *ESP32MailHTTPClient::getStreamPtr(void) +{ + if (connected()) + return _client.get(); + return nullptr; +} + +bool ESP32MailHTTPClient::connect(void) +{ + if (connected()) + { + while (_client->available() > 0) + _client->read(); + return true; + } + + if (!transportTraits) + return false; + + _client = transportTraits->create(); + + if (!transportTraits->verify(*_client, _host.c_str(), false, _debugCallback)) + { + _client->stop(); + return false; + } + + if (!_client->connect(_host.c_str(), _port)) + return false; + + return connected(); +} + +bool ESP32MailHTTPClient::connect(bool starttls) +{ + if (connected()) + { + while (_client->available() > 0) + _client->read(); + return true; + } + + if (!transportTraits) + return false; + + _client = transportTraits->create(); + + if (!transportTraits->verify(*_client, _host.c_str(), starttls, _debugCallback)) + { + _client->stop(); + return false; + } + + if (!_client->connect(_host.c_str(), _port)) + return false; + + return connected(); +} + +void ESP32MailHTTPClient::setDebugCallback(DebugMsgCallback cb) +{ + _debugCallback = std::move(cb); +} + +#endif //ESP32 + +#endif //ESP32MailHTTPClient_CPP diff --git a/libesp32/ESP32-Mail-Client/src/ESP32MailHTTPClient.h b/libesp32/ESP32-Mail-Client/src/ESP32MailHTTPClient.h new file mode 100755 index 000000000..5df2c8d2d --- /dev/null +++ b/libesp32/ESP32-Mail-Client/src/ESP32MailHTTPClient.h @@ -0,0 +1,107 @@ +/* + * Customized version of ESP32 HTTPClient Library. + * Allow custom header and payload with STARTTLS support + * + * v 1.0.0 + * + * The MIT License (MIT) + * Copyright (c) 2019 K. Suwatchai (Mobizt) + * + * HTTPClient Arduino library for ESP32 + * + * Copyright (c) 2015 Markus Sattler. All rights reserved. + * This file is part of the HTTPClient for Arduino. + * Port to ESP32 by Evandro Luis Copercini (2017), + * changed fingerprints to CA verification. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * +*/ + +#ifndef ESP32MailHTTPClient_H +#define ESP32MailHTTPClient_H + +#ifdef ESP32 + +#include +#include + +#include +#include "WiFiClientSecureESP32.h" + +class ESP32MailHTTPClient : public HTTPClient +{ +public: + ESP32MailHTTPClient(); + ~ESP32MailHTTPClient(); + + /** + * Initialization of new http connection. + * \param host - Host name without protocols. + * \param port - Server's port. + * \param uri - The URI of resource. + * \param CAcert - The Base64 encode root certificate string + * \return True as default. + * If no certificate string provided, use (const char*)NULL to CAcert param + */ + bool begin(const char *host, uint16_t port, const char *uri, const char *CAcert); + + /** + * Check the http connection status. + * \return True if connected. + */ + bool connected(); + + /** + * Establish http connection if header provided and send it, send payload if provided. + * \param header - The header string (constant chars array). + * \param payload - The payload string (constant chars array), optional. + * \return http status code, Return zero if new http connection and header and/or payload sent + * with no error or no header and payload provided. If obly payload provided, no new http connection was established. + */ + int sendRequest(const char *header, const char *payload); + + /** + * Send extra header without making new http connection (if sendRequest has been called) + * \param header - The header string (constant chars array). + * \return True if header sending success. + * Need to call sendRequest with header first. + */ + bool sendHeader(const char *header); + + /** + * Get the WiFi client pointer. + * \return WiFi client pointer. + */ + WiFiClient *getStreamPtr(void); + + uint16_t tcpTimeout = HTTPCLIENT_DEFAULT_TCP_TIMEOUT; + bool connect(void); + bool connect(bool starttls); + void setDebugCallback(DebugMsgCallback cb); + +protected: + TransportTraitsPtr transportTraits; + std::unique_ptr _client; + DebugMsgCallback _debugCallback = NULL; + + std::string _host = ""; + std::string _uri = ""; + uint16_t _port = 0; +}; + +#endif //ESP32 + +#endif //ESP32MailHTTPClient_H diff --git a/libesp32/ESP32-Mail-Client/src/ESP32TimeHelper.cpp b/libesp32/ESP32-Mail-Client/src/ESP32TimeHelper.cpp new file mode 100755 index 000000000..8e37b566b --- /dev/null +++ b/libesp32/ESP32-Mail-Client/src/ESP32TimeHelper.cpp @@ -0,0 +1,191 @@ +/* + * ESP32 Internet Time Helper Arduino Library v 1.0.1 + * + * The MIT License (MIT) + * Copyright (c) 2019 K. Suwatchai (Mobizt) + * + * + * Permission is hereby granted, free of charge, to any person returning a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef ESP32TimeHelper_CPP +#define ESP32TimeHelper_CPP + +#ifdef ESP32 + +#include "ESP32TimeHelper.h" + +ESP32TimeHelper::ESP32TimeHelper() +{ +} +uint32_t ESP32TimeHelper::getUnixTime() +{ + uint32_t utime = (msec_time_diff + millis()) / 1000; + return utime; +} + +time_t ESP32TimeHelper::getTimestamp(int year, int mon, int date, int hour, int mins, int sec) +{ + struct tm timeinfo; + timeinfo.tm_year = year - 1900; + timeinfo.tm_mon = mon - 1; + timeinfo.tm_mday = date; + timeinfo.tm_hour = hour; + timeinfo.tm_min = mins; + timeinfo.tm_sec = sec; + time_t ts = mktime(&timeinfo); + return ts; +} + +bool ESP32TimeHelper::setClock(float gmtOffset, float daylightOffset) +{ + TZ = gmtOffset; + DST_MN = daylightOffset; + configTime((TZ)*3600, (DST_MN)*60, "pool.ntp.org", "time.nist.gov", NULL); + + now = time(nullptr); + int cnt = 0; + while (now < 8 * 3600 * 2 && cnt < 20) + { + delay(50); + now = time(nullptr); + cnt++; + } + + uint64_t tmp = now; + tmp = tmp * 1000; + msec_time_diff = tmp - millis(); + + getLocalTime(&timeinfo); + + clockReady = now > 8 * 3600 * 2; + return clockReady; +} + +int ESP32TimeHelper::getYear() +{ + getLocalTime(&timeinfo); + return timeinfo.tm_year + 1900; +} +int ESP32TimeHelper::getMonth() +{ + getLocalTime(&timeinfo); + return timeinfo.tm_mon + 1; +} +int ESP32TimeHelper::getDay() +{ + getLocalTime(&timeinfo); + return timeinfo.tm_mday; +} + +int ESP32TimeHelper::getDayOfWeek() +{ + getLocalTime(&timeinfo); + return timeinfo.tm_wday; +} +String ESP32TimeHelper::getDayOfWeekString() +{ + getLocalTime(&timeinfo); + return dow[timeinfo.tm_wday]; +} + +int ESP32TimeHelper::getHour() +{ + getLocalTime(&timeinfo); + return timeinfo.tm_hour; +} + +int ESP32TimeHelper::getMin() +{ + getLocalTime(&timeinfo); + return timeinfo.tm_min; +} +int ESP32TimeHelper::getSec() +{ + getLocalTime(&timeinfo); + return timeinfo.tm_sec; +} +int ESP32TimeHelper::getNumberOfDayThisYear() +{ + getLocalTime(&timeinfo); + return timeinfo.tm_yday + 1; +} + +int ESP32TimeHelper::totalDays(int y, int m, int d) +{ + static char daytab[2][13] = + { + {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, + {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}}; + int daystotal = d; + for (int year = 1; year <= y; year++) + { + int max_month = (year < y ? 12 : m - 1); + int leap = (year % 4 == 0); + if (year % 100 == 0 && year % 400 != 0) + leap = 0; + for (int month = 1; month <= max_month; month++) + { + daystotal += daytab[leap][month]; + } + } + return daystotal; +} +int ESP32TimeHelper::getTotalDays(int year, int month, int day) +{ + return totalDays(year, month, day) - totalDays(1970, 1, 1); +} + +int ESP32TimeHelper::dayofWeek(int year, int month, int day) /* 1 <= m <= 12, y > 1752 (in the U.K.) */ +{ + static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4}; + year -= month < 3; + return (year + year / 4 - year / 100 + year / 400 + t[month - 1] + day) % 7; +} + +int ESP32TimeHelper::getCurrentSecond() +{ + return (timeinfo.tm_hour * 3600) + (timeinfo.tm_min * 60) + timeinfo.tm_sec; +} +uint64_t ESP32TimeHelper::getCurrentTimestamp() +{ + return now; +} +void ESP32TimeHelper::getTimeFromSec(int secCount, int &yrs, int &months, int &days, int &hr, int &min, int &sec) +{ + int _yrs = secCount / (365 * 24 * 3600); + secCount = secCount - _yrs * (365 * 24 * 3600); + yrs = _yrs; + int _months = secCount / (30* 24 * 3600); + secCount = secCount - _months * (30 * 24 * 3600); + months = _months; + int _days = secCount / (24 * 3600); + secCount = secCount - _days * (24 * 3600); + days = _days; + int _hr = secCount / 3600; + secCount = secCount - _hr * 3600; + hr = _hr; + int _min = secCount / 60; + secCount = secCount - _min * 60; + min = _min; + sec = secCount; +} + +#endif //ESP32 + +#endif //ESP32TimeHelper_CPP \ No newline at end of file diff --git a/libesp32/ESP32-Mail-Client/src/ESP32TimeHelper.h b/libesp32/ESP32-Mail-Client/src/ESP32TimeHelper.h new file mode 100755 index 000000000..e4feff648 --- /dev/null +++ b/libesp32/ESP32-Mail-Client/src/ESP32TimeHelper.h @@ -0,0 +1,73 @@ +/* + * ESP32 Internet Time Helper Arduino Library v 1.0.1 + * + * The MIT License (MIT) + * Copyright (c) 2019 K. Suwatchai (Mobizt) + * + * + * Permission is hereby granted, free of charge, to any person returning a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef ESP32TimeHelper_H +#define ESP32TimeHelper_H + +#ifdef ESP32 + + +#include +#include +#include + +class ESP32TimeHelper +{ +public: + ESP32TimeHelper(); + bool clockReady = false; + bool setClock(float gmtOffset, float daylightOffset); + uint32_t getUnixTime(); + time_t getTimestamp(int year, int mon, int date, int hour, int mins, int sec); + int getYear(); + int getMonth(); + int getDay(); + int getDayOfWeek(); + String getDayOfWeekString(); + int getHour(); + int getMin(); + int getSec(); + int getNumberOfDayThisYear(); + int getTotalDays(int year, int month, int day); + int dayofWeek(int year, int month, int day); + int getCurrentSecond(); + uint64_t getCurrentTimestamp(); + void getTimeFromSec(int secCount, int &yrs, int &months, int &days, int &hr, int &min, int &sec); + +private: + time_t now; + uint64_t msec_time_diff = 0; + struct tm timeinfo; + float TZ = 0.0; + float DST_MN = 0.0; + + bool setClock(); + int totalDays(int y, int m, int d); + const char *dow[20] = {"sunday", "monday", "tuesday", "wednesday", "thurseday", "friday", "saturday"}; +}; + +#endif //ESP32 + +#endif //ESP32TimeHelper_H diff --git a/libesp32/ESP32-Mail-Client/src/ESP32_MailClient.cpp b/libesp32/ESP32-Mail-Client/src/ESP32_MailClient.cpp new file mode 100755 index 000000000..85cb0663e --- /dev/null +++ b/libesp32/ESP32-Mail-Client/src/ESP32_MailClient.cpp @@ -0,0 +1,4875 @@ +/* + *Mail Client Arduino Library for ESP32, version 2.1.4 + * + * April 12, 2020 + * + * This library allows ESP32 to send Email with/without attachment and receive Email with/without attachment download through SMTP and IMAP servers. + * + * The library supports all ESP32 MCU based modules. + * + * The MIT License (MIT) + * Copyright (c) 2019 K. Suwatchai (Mobizt) + * + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef ESP32_MailClient_CPP +#define ESP32_MailClient_CPP + +#ifdef ESP32 + +#include "ESP32_MailClient.h" + +struct ESP32_MailClient::IMAP_COMMAND_TYPE +{ + static const uint8_t LOGIN = 0; + static const uint8_t LIST = 1; + static const uint8_t SELECT = 2; + static const uint8_t EXAMINE = 3; + static const uint8_t STATUS = 4; + static const uint8_t SEARCH = 5; + static const uint8_t FETCH_BODY_HEADER = 6; + static const uint8_t FETCH_BODY_MIME = 7; + static const uint8_t FETCH_BODY_TEXT = 8; + static const uint8_t FETCH_BODY_ATTACHMENT = 9; + static const uint8_t LOGOUT = 10; +}; + +struct ESP32_MailClient::IMAP_HEADER_TYPE +{ + static const uint8_t FROM = 1; + static const uint8_t TO = 2; + static const uint8_t CC = 3; + static const uint8_t SUBJECT = 4; + static const uint8_t DATE = 5; + static const uint8_t MSG_ID = 6; + static const uint8_t CONT_LANG = 7; + static const uint8_t ACCEPT_LANG = 8; +}; + + + +bool ESP32_MailClient::readMail(IMAPData &imapData) +{ + + std::string buf; + std::string command = "$"; + + size_t mailIndex = 0; + int messageDataIndex = 0; + int partID = 1; + int _partID = 1; + bool res = false; + bool _res = false; + bool starttls = imapData._starttls; + bool connected = false; + + int bufSize = 50; + + char *_val = new char[bufSize]; + char *_part = new char[bufSize]; + + unsigned long dataTime = 0; + + int count = 0; + + imapData._net->setDebugCallback(NULL); + + if (imapData._debug) + { + ESP32MailDebugInfo(ESP32_MAIL_STR_225); + ESP32MailDebug(imapData._host.c_str()); + ESP32MailDebug(String(imapData._port).c_str()); + } + + + if (imapData._readCallback) + { + imapData._cbData._info = ESP32_MAIL_STR_50; + imapData._cbData._status = ESP32_MAIL_STR_51; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + } + + if (imapData._debug) + imapData._net->setDebugCallback(ESP32MailDebug); + + if (imapData._rootCA.size() > 0) + imapData._net->begin(imapData._host.c_str(), imapData._port, ESP32_MAIL_STR_202, (const char *)imapData._rootCA.front()); + else + imapData._net->begin(imapData._host.c_str(), imapData._port, ESP32_MAIL_STR_202, (const char *)NULL); + + while (!imapData._net->connected() && count < 10) + { + + count++; + + if (!imapData._net->connect(starttls)) + { + + _imapStatus = IMAP_STATUS_SERVER_CONNECT_FAILED; + + if (imapData._readCallback) + { + imapData._cbData._info = ESP32_MAIL_STR_53 + imapErrorReasonStr(); + imapData._cbData._status = ESP32_MAIL_STR_52; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + } + if (imapData._debug) + { + ESP32MailDebugError(); + ESP32MailDebugLine(imapErrorReasonStr().c_str(), true); + } + } + else + { + break; + } + } + + if (!imapData._net->connect(starttls)) + { + goto out; + } + + connected = true; + + if (imapData._readCallback) + { + imapData._cbData._info = ESP32_MAIL_STR_54; + imapData._cbData._status = ESP32_MAIL_STR_55; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + } + + if (imapData._debug) + ESP32MailDebugInfo(ESP32_MAIL_STR_228); + + //Don't expect handshake from some servers + dataTime = millis(); + + while (imapData._net->connected() && !imapData._net->getStreamPtr()->available() && millis() - 500 < dataTime) + delay(0); + + if (imapData._net->connected() && imapData._net->getStreamPtr()->available()) + while (imapData._net->getStreamPtr()->available()) + imapData._net->getStreamPtr()->read(); + + imapData.clearMessageData(); + + if (imapData._readCallback) + { + imapData._cbData._info = ESP32_MAIL_STR_56; + imapData._cbData._status = ESP32_MAIL_STR_57; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + } + + if (imapData._debug) + ESP32MailDebugInfo(ESP32_MAIL_STR_229); + + imapData._net->getStreamPtr()->print(ESP32_MAIL_STR_130); + imapData._net->getStreamPtr()->print(imapData._loginEmail.c_str()); + imapData._net->getStreamPtr()->print(ESP32_MAIL_STR_131); + imapData._net->getStreamPtr()->println(imapData._loginPassword.c_str()); + + if (!waitIMAPResponse(imapData, IMAP_COMMAND_TYPE::LOGIN)) + { + _imapStatus = IMAP_STATUS_LOGIN_FAILED; + if (imapData._readCallback) + { + imapData._cbData._info = ESP32_MAIL_STR_53 + imapErrorReasonStr(); + imapData._cbData._status = ESP32_MAIL_STR_52; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + } + if (imapData._debug) + { + ESP32MailDebugError(); + ESP32MailDebugLine(imapErrorReasonStr().c_str(), true); + } + goto out; + } + + if (imapData._fetchUID.length() > 0) + imapData._headerOnly = false; + else + imapData._headerOnly = true; + + if (imapData._headerOnly) + { + if (imapData._readCallback) + { + imapData._cbData._info = ESP32_MAIL_STR_58; + imapData._cbData._status = ESP32_MAIL_STR_59; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + } + + if (imapData._debug) + ESP32MailDebugInfo(ESP32_MAIL_STR_230); + + imapData._net->getStreamPtr()->println(ESP32_MAIL_STR_133); + if (!waitIMAPResponse(imapData, IMAP_COMMAND_TYPE::LIST)) + { + _imapStatus = IMAP_STATUS_BAD_COMMAND; + if (imapData._readCallback) + { + imapData._cbData._info = ESP32_MAIL_STR_53 + imapErrorReasonStr(); + imapData._cbData._status = ESP32_MAIL_STR_52; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + } + if (imapData._debug) + { + ESP32MailDebugError(); + ESP32MailDebugLine(imapErrorReasonStr().c_str(), true); + } + imapData._cbData.empty(); + } + + if (imapData._readCallback) + { + + imapData._cbData._info = ESP32_MAIL_STR_60; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + + for (size_t i = 0; i < imapData._folders.size(); i++) + { + imapData._cbData._info = imapData._folders[i]; + imapData._cbData._status = ""; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + } + + imapData._cbData._info = ESP32_MAIL_STR_61 + imapData._currentFolder + ESP32_MAIL_STR_97; + imapData._cbData._status = ""; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + } + } + + if (imapData._debug) + ESP32MailDebugInfo(ESP32_MAIL_STR_231); + + imapData._net->getStreamPtr()->print(ESP32_MAIL_STR_135); + imapData._net->getStreamPtr()->print(imapData._currentFolder.c_str()); + imapData._net->getStreamPtr()->println(ESP32_MAIL_STR_136); + if (!waitIMAPResponse(imapData, IMAP_COMMAND_TYPE::EXAMINE)) + { + _imapStatus = IMAP_STATUS_BAD_COMMAND; + if (imapData._readCallback) + { + imapData._cbData._info = ESP32_MAIL_STR_53 + imapErrorReasonStr(); + imapData._cbData._status = ESP32_MAIL_STR_52; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + } + if (imapData._debug) + { + ESP32MailDebugError(); + ESP32MailDebugLine(imapErrorReasonStr().c_str(), true); + } + goto out; + } + + if (imapData._headerOnly) + { + + if (imapData._readCallback) + { + imapData._cbData._info = ESP32_MAIL_STR_62 + imapData._nextUID; + imapData._cbData._status = ""; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + + imapData._cbData._info = ESP32_MAIL_STR_63; + memset(_val, 0, bufSize); + itoa(imapData._totalMessage, _val, 10); + imapData._cbData._info += _val; + imapData._cbData._status = ""; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + + imapData._cbData._info = ESP32_MAIL_STR_64; + imapData._cbData._status = ""; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + + for (size_t i = 0; i < imapData._flag.size(); i++) + { + imapData._cbData._info = imapData._flag[i]; + imapData._cbData._status = ""; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + } + + imapData._cbData._info = ESP32_MAIL_STR_65; + imapData._cbData._status = ""; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + + imapData._cbData._info = ESP32_MAIL_STR_66; + imapData._cbData._status = ESP32_MAIL_STR_67; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + } + } + + imapData._msgNum.clear(); + imapData._uidSearch = false; + imapData._msgID.clear(); + imapData._contentLanguage.clear(); + imapData._acceptLanguage.clear(); + imapData._attachmentCount.clear(); + imapData._totalAttachFileSize.clear(); + imapData._downloadedByte.clear(); + imapData._error.clear(); + imapData._errorMsg.clear(); + imapData._searchCount = 0; + + if (imapData._headerOnly) + { + + if (imapData._searchCriteria != "") + { + if (imapData._debug) + ESP32MailDebugInfo(ESP32_MAIL_STR_232); + + if (imapData._searchCriteria.find(ESP32_MAIL_STR_137) != std::string::npos) + { + imapData._uidSearch = true; + command += ESP32_MAIL_STR_138; + } + command += ESP32_MAIL_STR_139; + + for (size_t i = 0; i < imapData._searchCriteria.length(); i++) + { + if (imapData._searchCriteria[i] != ' ' && imapData._searchCriteria[i] != '\r' && imapData._searchCriteria[i] != '\n' && imapData._searchCriteria[i] != '$') + buf.append(1, imapData._searchCriteria[i]); + + if (imapData._searchCriteria[i] == ' ') + { + if ((imapData._uidSearch && buf == ESP32_MAIL_STR_140) || (imapData._unseen && buf.find(ESP32_MAIL_STR_224) != std::string::npos)) + buf.clear(); + + if (buf != ESP32_MAIL_STR_141 && buf != "") + { + command += ESP32_MAIL_STR_131; + command += buf; + } + + buf.clear(); + } + } + + if (imapData._unseen && imapData._searchCriteria.find(ESP32_MAIL_STR_223) == std::string::npos) + command += ESP32_MAIL_STR_223; + + if (buf.length() > 0) + { + command += ESP32_MAIL_STR_131; + command += buf; + } + + imapData._net->getStreamPtr()->println(command.c_str()); + + std::string().swap(command); + + if (!waitIMAPResponse(imapData, IMAP_COMMAND_TYPE::SEARCH, 1)) + { + _imapStatus = IMAP_STATUS_BAD_COMMAND; + if (imapData._readCallback) + { + imapData._cbData._info = ESP32_MAIL_STR_53 + imapErrorReasonStr(); + imapData._cbData._status = ESP32_MAIL_STR_52; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + } + if (imapData._debug) + { + ESP32MailDebugError(); + ESP32MailDebugLine(imapErrorReasonStr().c_str(), true); + } + goto out; + } + + if (imapData._readCallback) + { + + imapData._cbData._info = ESP32_MAIL_STR_68; + memset(_val, 0, bufSize); + itoa(imapData._emailNumMax, _val, 10); + imapData._cbData._info += _val; + imapData._cbData._status = ""; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + + if (imapData._msgNum.size() > 0) + { + + imapData._cbData._info = ESP32_MAIL_STR_69; + memset(_val, 0, bufSize); + itoa(imapData._searchCount, _val, 10); + imapData._cbData._info += _val; + imapData._cbData._info += ESP32_MAIL_STR_70; + imapData._cbData._status = ""; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + + imapData._cbData._info = ESP32_MAIL_STR_71; + memset(_val, 0, bufSize); + itoa(imapData._msgNum.size(), _val, 10); + imapData._cbData._info += _val; + imapData._cbData._info += ESP32_MAIL_STR_70; + imapData._cbData._status = ""; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + } + else + { + imapData._cbData._info = ESP32_MAIL_STR_72; + imapData._cbData._status = ""; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + } + } + } + else + { + + imapData._msgNum.push_back(imapData._totalMessage); + if (imapData._readCallback) + { + imapData._cbData._info = ESP32_MAIL_STR_73; + imapData._cbData._status = ""; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + } + } + } + else + { + + imapData._msgNum.push_back(atoi(imapData._fetchUID.c_str())); + } + + for (int i = 0; i < imapData._messageDataInfo.size(); i++) + imapData._messageDataInfo[i].clear(); + + imapData._messageDataInfo.clear(); + + for (int i = 0; i < imapData._msgNum.size(); i++) + { + + if (imapData._debug) + ESP32MailDebugInfo(ESP32_MAIL_STR_233); + + if (imapData._readCallback) + { + + imapData._cbData._info = ESP32_MAIL_STR_74; + memset(_val, 0, bufSize); + itoa(i + 1, _val, 10); + imapData._cbData._info += _val; + + imapData._cbData._status = ""; + if (imapData._uidSearch || imapData._fetchUID.length() > 0) + imapData._cbData._info += ESP32_MAIL_STR_75; + else + imapData._cbData._info += ESP32_MAIL_STR_76; + + memset(_val, 0, bufSize); + itoa(imapData._msgNum[i], _val, 10); + imapData._cbData._info += _val; + imapData._cbData._status = ESP32_MAIL_STR_77; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + } + + imapData._date.push_back(std::string()); + imapData._subject.push_back(std::string()); + imapData._subject_charset.push_back(std::string()); + imapData._from.push_back(std::string()); + imapData._from_charset.push_back(std::string()); + imapData._to.push_back(std::string()); + imapData._to_charset.push_back(std::string()); + imapData._cc.push_back(std::string()); + imapData._attachmentCount.push_back(0); + imapData._totalAttachFileSize.push_back(0); + imapData._downloadedByte.push_back(0); + imapData._messageDataCount.push_back(0); + imapData._error.push_back(false); + imapData._errorMsg.push_back(std::string()); + imapData._cc_charset.push_back(std::string()); + imapData._msgID.push_back(std::string()); + imapData._acceptLanguage.push_back(std::string()); + imapData._contentLanguage.push_back(std::string()); + + std::vector d = std::vector(); + + imapData._messageDataInfo.push_back(d); + + std::vector().swap(d); + + if (imapData._uidSearch || imapData._fetchUID.length() > 0) + imapData._net->getStreamPtr()->print(ESP32_MAIL_STR_142); + else + imapData._net->getStreamPtr()->print(ESP32_MAIL_STR_143); + + imapData._net->getStreamPtr()->print(imapData._msgNum[i]); + imapData._net->getStreamPtr()->println(ESP32_MAIL_STR_144); + + if (!waitIMAPResponse(imapData, IMAP_COMMAND_TYPE::FETCH_BODY_HEADER, 0, mailIndex)) + { + if (imapData._headerOnly) + _imapStatus = IMAP_STATUS_IMAP_RESPONSE_FAILED; + else + _imapStatus = IMAP_STATUS_BAD_COMMAND; + + if (imapData._readCallback) + { + imapData._cbData._info = ESP32_MAIL_STR_53 + imapErrorReasonStr(); + imapData._cbData._status = ESP32_MAIL_STR_52; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + } + if (imapData._debug) + { + ESP32MailDebugError(); + ESP32MailDebugLine(imapErrorReasonStr().c_str(), true); + } + goto out; + } + + if (!imapData._headerOnly) + { + + messageDataIndex = 0; + partID = 1; + _partID = 1; + res = false; + _res = false; + + do + { + + if (imapData._uidSearch || imapData._fetchUID.length() > 0) + imapData._net->getStreamPtr()->print(ESP32_MAIL_STR_142); + else + imapData._net->getStreamPtr()->print(ESP32_MAIL_STR_143); + + imapData._net->getStreamPtr()->print(imapData._msgNum[i]); + imapData._net->getStreamPtr()->print(ESP32_MAIL_STR_147); + imapData._net->getStreamPtr()->print(partID); + imapData._net->getStreamPtr()->println(ESP32_MAIL_STR_148); + + memset(_part, 0, bufSize); + memset(_val, 0, bufSize); + itoa(partID, _val, 10); + strcpy(_part, _val); + res = waitIMAPResponse(imapData, IMAP_COMMAND_TYPE::FETCH_BODY_MIME, 0, mailIndex, messageDataIndex, _part); + if (res) + { + + if (imapData._messageDataInfo[mailIndex].size() < messageDataIndex + 1) + { + messageBodyData b; + imapData._messageDataInfo[mailIndex].push_back(b); + b.empty(); + imapData._messageDataCount[mailIndex] = imapData._messageDataInfo[mailIndex].size(); + } + + if (imapData._messageDataInfo[mailIndex][messageDataIndex]._contentType == "") + continue; + + if (imapData._messageDataInfo[mailIndex][messageDataIndex]._contentType.find(ESP32_MAIL_STR_149) != std::string::npos) + { + do + { + + if (imapData._uidSearch || imapData._fetchUID.length() > 0) + imapData._net->getStreamPtr()->print(ESP32_MAIL_STR_142); + else + imapData._net->getStreamPtr()->print(ESP32_MAIL_STR_143); + + imapData._net->getStreamPtr()->print(imapData._msgNum[i]); + imapData._net->getStreamPtr()->print(ESP32_MAIL_STR_147); + imapData._net->getStreamPtr()->print(partID); + imapData._net->getStreamPtr()->print("."); + imapData._net->getStreamPtr()->print(_partID); + imapData._net->getStreamPtr()->println(ESP32_MAIL_STR_148); + + memset(_part, 0, bufSize); + memset(_val, 0, bufSize); + itoa(partID, _val, 10); + strcpy(_part, _val); + strcat(_part, "."); + memset(_val, 0, bufSize); + itoa(_partID, _val, 10); + strcat(_part, _val); + _res = waitIMAPResponse(imapData, IMAP_COMMAND_TYPE::FETCH_BODY_MIME, 0, mailIndex, messageDataIndex, _part); + + if (_res) + { + messageDataIndex++; + _partID++; + } + + } while (_res); + } + else + { + messageDataIndex++; + } + partID++; + } + + } while (res); + + if (imapData._saveHTMLMsg || imapData._saveTextMsg || imapData._downloadAttachment) + { + + if (!_sdOk) + { + if (imapData._storageType == MailClientStorageType::SD) + { + _sdOk = sdTest(); + if (_sdOk) + if (!SD.exists(imapData._savePath.c_str())) + createDirs(imapData._savePath); + } + else if (imapData._storageType == MailClientStorageType::SPIFFS) + _sdOk = SPIFFS.begin(true); + } + } + + if (imapData._messageDataInfo[mailIndex].size() > 0) + { + if (imapData._attachmentCount[mailIndex] > 0 && imapData._readCallback) + { + imapData._cbData._info = ESP32_MAIL_STR_78; + memset(_val, 0, bufSize); + itoa(imapData._attachmentCount[mailIndex], _val, 10); + imapData._cbData._info += _val; + imapData._cbData._info += ESP32_MAIL_STR_79; + imapData._cbData._status = ""; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + + for (int j = 0; j < imapData._messageDataInfo[mailIndex].size(); j++) + { + if (imapData._messageDataInfo[mailIndex][j]._disposition == ESP32_MAIL_STR_153) + { + imapData._cbData._info = imapData._messageDataInfo[mailIndex][j]._filename; + imapData._cbData._info += ESP32_MAIL_STR_83; + memset(_val, 0, bufSize); + itoa(imapData._messageDataInfo[mailIndex][j]._size, _val, 10); + imapData._cbData._info += _val; + imapData._cbData._info += ESP32_MAIL_STR_82; + imapData._cbData._status = ""; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + } + } + + if (imapData._downloadAttachment && _sdOk) + { + imapData._cbData._info = ESP32_MAIL_STR_80; + imapData._cbData._status = ESP32_MAIL_STR_81; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + } + } + + for (int j = 0; j < imapData._messageDataInfo[mailIndex].size(); j++) + { + + if (imapData._messageDataInfo[mailIndex][j]._disposition == "") + { + + if (!imapData._textFormat && imapData._messageDataInfo[mailIndex][j]._contentType != ESP32_MAIL_STR_154) + continue; + + if (!imapData._htmlFormat && imapData._messageDataInfo[mailIndex][j]._contentType != ESP32_MAIL_STR_155) + continue; + + if (imapData._uidSearch || imapData._fetchUID.length() > 0) + imapData._net->getStreamPtr()->print(ESP32_MAIL_STR_142); + else + imapData._net->getStreamPtr()->print(ESP32_MAIL_STR_143); + + imapData._net->getStreamPtr()->print(imapData._msgNum[i]); + imapData._net->getStreamPtr()->print(ESP32_MAIL_STR_147); + imapData._net->getStreamPtr()->print(imapData._messageDataInfo[mailIndex][j]._part.c_str()); + imapData._net->getStreamPtr()->println(ESP32_MAIL_STR_156); + if (!waitIMAPResponse(imapData, IMAP_COMMAND_TYPE::FETCH_BODY_TEXT, imapData._message_buffer_size, mailIndex, j)) + { + _imapStatus = IMAP_STATUS_IMAP_RESPONSE_FAILED; + if (imapData._readCallback) + { + imapData._cbData._info = ESP32_MAIL_STR_53 + imapErrorReasonStr(); + imapData._cbData._status = ESP32_MAIL_STR_52; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + } + if (imapData._debug) + { + ESP32MailDebugError(); + ESP32MailDebugLine(imapErrorReasonStr().c_str(), true); + } + } + } + else if (imapData._messageDataInfo[mailIndex][j]._disposition == ESP32_MAIL_STR_153 && _sdOk) + { + + if (imapData._downloadAttachment) + { + if (imapData._messageDataInfo[mailIndex][j]._size <= imapData._attacement_max_size) + { + + if (_sdOk) + { + + if (j < imapData._messageDataInfo[mailIndex].size() - 1) + if (imapData._messageDataInfo[mailIndex][j + 1]._size > imapData._attacement_max_size) + imapData._downloadedByte[mailIndex] += imapData._messageDataInfo[mailIndex][j + 1]._size; + + if (imapData._uidSearch || imapData._fetchUID.length() > 0) + imapData._net->getStreamPtr()->print(ESP32_MAIL_STR_142); + else + imapData._net->getStreamPtr()->print(ESP32_MAIL_STR_143); + + imapData._net->getStreamPtr()->print(imapData._msgNum[i]); + imapData._net->getStreamPtr()->print(ESP32_MAIL_STR_147); + imapData._net->getStreamPtr()->print(imapData._messageDataInfo[mailIndex][j]._part.c_str()); + imapData._net->getStreamPtr()->println(ESP32_MAIL_STR_156); + if (!waitIMAPResponse(imapData, IMAP_COMMAND_TYPE::FETCH_BODY_ATTACHMENT, imapData._message_buffer_size, mailIndex, j)) + { + _imapStatus = IMAP_STATUS_IMAP_RESPONSE_FAILED; + if (imapData._readCallback) + { + imapData._cbData._info = ESP32_MAIL_STR_53 + imapErrorReasonStr(); + imapData._cbData._status = ESP32_MAIL_STR_52; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + } + if (imapData._debug) + { + ESP32MailDebugError(); + ESP32MailDebugLine(imapErrorReasonStr().c_str(), true); + } + } + + delay(0); + } + } + else + { + if (j == imapData._messageDataInfo[mailIndex].size() - 1) + imapData._downloadedByte[mailIndex] += imapData._messageDataInfo[mailIndex][j]._size; + } + } + } + } + } + + if (imapData._storageType == MailClientStorageType::SD) + { + if (_sdOk) + SD.end(); + } + else if (imapData._storageType == MailClientStorageType::SPIFFS) + { + if (_sdOk) + SPIFFS.end(); + } + + _sdOk = false; + } + + if (imapData._readCallback) + { + imapData._cbData._info = ESP32_MAIL_STR_84; + memset(_val, 0, bufSize); + itoa(ESP.getFreeHeap(), _val, 10); + imapData._cbData._info += _val; + imapData._cbData._status = ""; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + } + + mailIndex++; + } + + if (imapData._readCallback) + { + imapData._cbData._info = ESP32_MAIL_STR_85; + imapData._cbData._status = ESP32_MAIL_STR_86; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + } + + if (imapData._debug) + ESP32MailDebugInfo(ESP32_MAIL_STR_234); + + if (imapData._net->connected()) + while (imapData._net->getStreamPtr()->available()) + imapData._net->getStreamPtr()->read(); + + imapData._net->getStreamPtr()->println(ESP32_MAIL_STR_146); + + if (!waitIMAPResponse(imapData, 0)) + { + _imapStatus = IMAP_STATUS_BAD_COMMAND; + if (imapData._readCallback) + { + imapData._cbData._info = ESP32_MAIL_STR_53 + imapErrorReasonStr(); + imapData._cbData._status = ESP32_MAIL_STR_52; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + } + if (imapData._debug) + { + ESP32MailDebugError(); + ESP32MailDebugLine(imapErrorReasonStr().c_str(), true); + } + goto out; + } + + if (imapData._readCallback) + { + imapData._cbData._info = ESP32_MAIL_STR_98; + imapData._cbData._status = ESP32_MAIL_STR_96; + imapData._cbData._success = true; + imapData._readCallback(imapData._cbData); + } + + if (imapData._debug) + ESP32MailDebugInfo(ESP32_MAIL_STR_235); + + if (imapData._net->connected()) + { + while (imapData._net->getStreamPtr()->available()) + imapData._net->getStreamPtr()->read(); + + imapData._net->getStreamPtr()->stop(); + } + + imapData._cbData.empty(); + delete[] _val; + delete[] _part; + std::string().swap(command); + std::string().swap(buf); + + return true; + +out: + + if (connected) + { + if (imapData._net->connected()) + { + while (imapData._net->getStreamPtr()->available()) + imapData._net->getStreamPtr()->read(); + imapData._net->getStreamPtr()->stop(); + } + } + + imapData._cbData.empty(); + delete[] _val; + delete[] _part; + std::string().swap(command); + std::string().swap(buf); + + return false; +} + +bool ESP32_MailClient::setFlag(IMAPData &imapData, int msgUID, const String &flag) +{ + return _setFlag(imapData, msgUID, flag, 0); +} + +bool ESP32_MailClient::addFlag(IMAPData &imapData, int msgUID, const String &flag) +{ + return _setFlag(imapData, msgUID, flag, 1); +} + +bool ESP32_MailClient::removeFlag(IMAPData &imapData, int msgUID, const String &flag) +{ + return _setFlag(imapData, msgUID, flag, 2); +} + +bool ESP32_MailClient::_setFlag(IMAPData &imapData, int msgUID, const String &flag, uint8_t action) +{ + + std::string buf; + + bool starttls = imapData._starttls; + bool connected = false; + + int bufSize = 50; + + char *_val = new char[bufSize]; + char *_part = new char[bufSize]; + + unsigned long dataTime = 0; + + int count = 0; + + imapData._net->setDebugCallback(NULL); + + if (imapData._debug) + { + ESP32MailDebugInfo(ESP32_MAIL_STR_225); + ESP32MailDebug(imapData._host.c_str()); + ESP32MailDebug(String(imapData._port).c_str()); + } + + if (imapData._readCallback) + { + imapData._cbData._info = ESP32_MAIL_STR_50; + imapData._cbData._status = ESP32_MAIL_STR_51; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + } + + if (imapData._debug) + imapData._net->setDebugCallback(ESP32MailDebug); + + if (imapData._rootCA.size() > 0) + imapData._net->begin(imapData._host.c_str(), imapData._port, ESP32_MAIL_STR_202, (const char *)imapData._rootCA.front()); + else + imapData._net->begin(imapData._host.c_str(), imapData._port, ESP32_MAIL_STR_202, (const char *)NULL); + + while (!imapData._net->connected() && count < 10) + { + + count++; + + if (!imapData._net->connect(starttls)) + { + + _imapStatus = IMAP_STATUS_SERVER_CONNECT_FAILED; + + if (imapData._readCallback) + { + imapData._cbData._info = ESP32_MAIL_STR_53 + imapErrorReasonStr(); + imapData._cbData._status = ESP32_MAIL_STR_52; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + } + if (imapData._debug) + { + ESP32MailDebugError(); + ESP32MailDebugLine(imapErrorReasonStr().c_str(), true); + } + } + else + { + break; + } + } + + if (!imapData._net->connect(starttls)) + { + goto out; + } + + connected = true; + + if (imapData._readCallback) + { + imapData._cbData._info = ESP32_MAIL_STR_54; + imapData._cbData._status = ESP32_MAIL_STR_55; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + } + + if (imapData._debug) + ESP32MailDebugInfo(ESP32_MAIL_STR_228); + + //Don't expect handshake from some servers + dataTime = millis(); + + while (imapData._net->connected() && !imapData._net->getStreamPtr()->available() && millis() - 500 < dataTime) + delay(0); + + if (imapData._net->connected() && imapData._net->getStreamPtr()->available()) + while (imapData._net->getStreamPtr()->available()) + imapData._net->getStreamPtr()->read(); + + imapData.clearMessageData(); + + if (imapData._readCallback) + { + imapData._cbData._info = ESP32_MAIL_STR_56; + imapData._cbData._status = ESP32_MAIL_STR_57; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + } + + if (imapData._debug) + ESP32MailDebugInfo(ESP32_MAIL_STR_229); + + imapData._net->getStreamPtr()->print(ESP32_MAIL_STR_130); + imapData._net->getStreamPtr()->print(imapData._loginEmail.c_str()); + imapData._net->getStreamPtr()->print(ESP32_MAIL_STR_131); + imapData._net->getStreamPtr()->println(imapData._loginPassword.c_str()); + + if (!waitIMAPResponse(imapData, IMAP_COMMAND_TYPE::LOGIN)) + { + _imapStatus = IMAP_STATUS_LOGIN_FAILED; + if (imapData._readCallback) + { + imapData._cbData._info = ESP32_MAIL_STR_53 + imapErrorReasonStr(); + imapData._cbData._status = ESP32_MAIL_STR_52; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + } + if (imapData._debug) + { + ESP32MailDebugError(); + ESP32MailDebugLine(imapErrorReasonStr().c_str(), true); + } + goto out; + } + + if (imapData._readCallback) + { + imapData._cbData._info = ESP32_MAIL_STR_58; + imapData._cbData._status = ESP32_MAIL_STR_59; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + } + + if (imapData._debug) + ESP32MailDebugInfo(ESP32_MAIL_STR_230); + + imapData._net->getStreamPtr()->println(ESP32_MAIL_STR_133); + if (!waitIMAPResponse(imapData, IMAP_COMMAND_TYPE::LIST)) + { + _imapStatus = IMAP_STATUS_BAD_COMMAND; + if (imapData._readCallback) + { + imapData._cbData._info = ESP32_MAIL_STR_53 + imapErrorReasonStr(); + imapData._cbData._status = ESP32_MAIL_STR_52; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + } + if (imapData._debug) + { + ESP32MailDebugError(); + ESP32MailDebugLine(imapErrorReasonStr().c_str(), true); + } + imapData._cbData.empty(); + } + + if (imapData._readCallback) + { + + imapData._cbData._info = ESP32_MAIL_STR_60; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + + for (size_t i = 0; i < imapData._folders.size(); i++) + { + imapData._cbData._info = imapData._folders[i]; + imapData._cbData._status = ""; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + } + + imapData._cbData._info = ESP32_MAIL_STR_61 + imapData._currentFolder + ESP32_MAIL_STR_97; + imapData._cbData._status = ""; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + } + + if (imapData._debug) + ESP32MailDebugInfo(ESP32_MAIL_STR_248); + + imapData._net->getStreamPtr()->print(ESP32_MAIL_STR_247); + imapData._net->getStreamPtr()->print(imapData._currentFolder.c_str()); + imapData._net->getStreamPtr()->println(ESP32_MAIL_STR_136); + if (!waitIMAPResponse(imapData, IMAP_COMMAND_TYPE::EXAMINE)) + { + _imapStatus = IMAP_STATUS_BAD_COMMAND; + if (imapData._readCallback) + { + imapData._cbData._info = ESP32_MAIL_STR_53 + imapErrorReasonStr(); + imapData._cbData._status = ESP32_MAIL_STR_52; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + } + if (imapData._debug) + { + ESP32MailDebugError(); + ESP32MailDebugLine(imapErrorReasonStr().c_str(), true); + } + goto out; + } + + if (imapData._debug) + { + if (action == 0) + ESP32MailDebugInfo(ESP32_MAIL_STR_253); + else if (action == 1) + ESP32MailDebugInfo(ESP32_MAIL_STR_254); + else + ESP32MailDebugInfo(ESP32_MAIL_STR_255); + } + + imapData._net->getStreamPtr()->print(ESP32_MAIL_STR_249); + imapData._net->getStreamPtr()->print(msgUID); + if (action == 0) + imapData._net->getStreamPtr()->print(ESP32_MAIL_STR_250); + else if (action == 1) + imapData._net->getStreamPtr()->print(ESP32_MAIL_STR_251); + else + imapData._net->getStreamPtr()->print(ESP32_MAIL_STR_252); + imapData._net->getStreamPtr()->print(flag); + imapData._net->getStreamPtr()->println(ESP32_MAIL_STR_192); + + if (!getIMAPResponse(imapData)) + { + _imapStatus = IMAP_STATUS_PARSE_FLAG_FAILED; + if (imapData._readCallback) + { + imapData._cbData._info = ESP32_MAIL_STR_53 + imapErrorReasonStr(); + imapData._cbData._status = ESP32_MAIL_STR_52; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + } + if (imapData._debug) + { + ESP32MailDebugError(); + ESP32MailDebugLine(imapErrorReasonStr().c_str(), true); + } + goto out; + } + + if (imapData._readCallback) + { + imapData._cbData._info = ESP32_MAIL_STR_85; + imapData._cbData._status = ESP32_MAIL_STR_86; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + } + + if (imapData._debug) + ESP32MailDebugInfo(ESP32_MAIL_STR_234); + + if (imapData._net->connected()) + while (imapData._net->getStreamPtr()->available()) + imapData._net->getStreamPtr()->read(); + + imapData._net->getStreamPtr()->println(ESP32_MAIL_STR_146); + + if (!waitIMAPResponse(imapData, 0)) + { + _imapStatus = IMAP_STATUS_BAD_COMMAND; + if (imapData._readCallback) + { + imapData._cbData._info = ESP32_MAIL_STR_53 + imapErrorReasonStr(); + imapData._cbData._status = ESP32_MAIL_STR_52; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + } + if (imapData._debug) + { + ESP32MailDebugError(); + ESP32MailDebugLine(imapErrorReasonStr().c_str(), true); + } + goto out; + } + + if (imapData._readCallback) + { + imapData._cbData._info = ESP32_MAIL_STR_98; + imapData._cbData._status = ESP32_MAIL_STR_96; + imapData._cbData._success = true; + imapData._readCallback(imapData._cbData); + } + + if (imapData._debug) + ESP32MailDebugInfo(ESP32_MAIL_STR_235); + + if (imapData._net->connected()) + { + while (imapData._net->getStreamPtr()->available()) + imapData._net->getStreamPtr()->read(); + + imapData._net->getStreamPtr()->stop(); + } + + imapData._cbData.empty(); + delete[] _val; + delete[] _part; + std::string().swap(buf); + + return true; + +out: + + if (connected) + { + if (imapData._net->connected()) + { + while (imapData._net->getStreamPtr()->available()) + imapData._net->getStreamPtr()->read(); + imapData._net->getStreamPtr()->stop(); + } + } + + imapData._cbData.empty(); + delete[] _val; + delete[] _part; + std::string().swap(buf); + return false; +} + + +bool ESP32_MailClient::smtpClientAvailable(SMTPData &smtpData, bool available) +{ + + if (!smtpData._net->getStreamPtr()) + return false; + + if (available) + return smtpData._net->getStreamPtr()->connected() && smtpData._net->getStreamPtr()->available(); + else + return smtpData._net->getStreamPtr()->connected() && !smtpData._net->getStreamPtr()->available(); +} + +bool ESP32_MailClient::imapClientAvailable(IMAPData &imapData, bool available) +{ + + if (!imapData._net->getStreamPtr()) + return false; + + if (available) + return imapData._net->getStreamPtr()->connected() && imapData._net->getStreamPtr()->available(); + else + return imapData._net->getStreamPtr()->connected() && !imapData._net->getStreamPtr()->available(); +} + +void ESP32_MailClient::createDirs(std::string dirs) +{ + std::string dir = ""; + int count = 0; + for (int i = 0; i < dirs.length(); i++) + { + dir.append(1, dirs[i]); + count++; + if (dirs[i] == '/') + { + if (dir.length() > 0) + SD.mkdir(dir.substr(0, dir.length() - 1).c_str()); + count = 0; + } + } + if (count > 0) + SD.mkdir(dir.c_str()); + std::string().swap(dir); +} + +bool ESP32_MailClient::sdTest() +{ + + if (_sdConfigSet) + sdBegin(_sck, _miso, _mosi, _ss); + else + sdBegin(); + + File file = SD.open(ESP32_MAIL_STR_204, FILE_WRITE); + if (!file) + return false; + + if (!file.write(32)) + return false; + file.close(); + + file = SD.open(ESP32_MAIL_STR_204); + if (!file) + return false; + + while (file.available()) + { + if (file.read() != 32) + return false; + } + file.close(); + + SD.remove(ESP32_MAIL_STR_204); + + return true; +} + +bool ESP32_MailClient::sendMail(SMTPData &smtpData) +{ + + _smtpStatus = 0; + std::string buf; + std::string buf2; + int bufSize = 50; + bool starttls = smtpData._starttls; + bool connected = false; + char *_val = new char[bufSize]; + int res = 0; + + smtpData._net->setDebugCallback(NULL); + + if (smtpData._sendCallback) + { + smtpData._cbData._info = ESP32_MAIL_STR_120; + smtpData._cbData._success = false; + smtpData._sendCallback(smtpData._cbData); + } + + if (smtpData._debug) + { + ESP32MailDebugInfo(ESP32_MAIL_STR_236); + ESP32MailDebug(smtpData._host.c_str()); + ESP32MailDebug(String(smtpData._port).c_str()); + } + + + if (smtpData._debug) + smtpData._net->setDebugCallback(ESP32MailDebug); + + if (smtpData._rootCA.size() > 0) + smtpData._net->begin(smtpData._host.c_str(), smtpData._port, ESP32_MAIL_STR_202, (const char *)smtpData._rootCA.front()); + else + smtpData._net->begin(smtpData._host.c_str(), smtpData._port, ESP32_MAIL_STR_202, (const char *)NULL); + + if (smtpData._port == 587) + starttls = true; + + if (!smtpData._net->connect(starttls)) + { + _smtpStatus = SMTP_STATUS_SERVER_CONNECT_FAILED; + if (smtpData._sendCallback) + { + smtpData._cbData._info = ESP32_MAIL_STR_53 + smtpErrorReasonStr(); + smtpData._cbData._success = false; + smtpData._sendCallback(smtpData._cbData); + } + + if (smtpData._debug) + { + ESP32MailDebugError(); + ESP32MailDebugLine(smtpErrorReasonStr().c_str(), true); + } + goto failed; + } + + if (smtpData._debug) + ESP32MailDebugInfo(ESP32_MAIL_STR_238); + + connected = true; + + if (!starttls) + { + + if (smtpData._sendCallback) + { + smtpData._cbData._info = ESP32_MAIL_STR_121; + smtpData._cbData._success = false; + smtpData._sendCallback(smtpData._cbData); + } + + if (waitSMTPResponse(smtpData) != 220) + { + _smtpStatus = SMTP_STATUS_SMTP_RESPONSE_FAILED; + if (smtpData._sendCallback) + { + smtpData._cbData._info = ESP32_MAIL_STR_53 + smtpErrorReasonStr(); + smtpData._cbData._success = false; + smtpData._sendCallback(smtpData._cbData); + } + if (smtpData._debug) + { + ESP32MailDebugError(); + ESP32MailDebugLine(smtpErrorReasonStr().c_str(), true); + } + goto failed; + } + } + + if (smtpData._sendCallback) + { + smtpData._cbData._info = ESP32_MAIL_STR_122; + smtpData._cbData._success = false; + smtpData._sendCallback(smtpData._cbData); + } + + if (smtpData._debug) + ESP32MailDebugInfo(ESP32_MAIL_STR_239); + + smtpData._net->getStreamPtr()->println(ESP32_MAIL_STR_5); + + if (waitSMTPResponse(smtpData) != 250) + { + _smtpStatus = SMTP_STATUS_IDENTIFICATION_FAILED; + if (smtpData._sendCallback) + { + smtpData._cbData._info = ESP32_MAIL_STR_53 + smtpErrorReasonStr(); + smtpData._cbData._success = false; + smtpData._sendCallback(smtpData._cbData); + } + if (smtpData._debug) + { + ESP32MailDebugError(); + ESP32MailDebugLine(smtpErrorReasonStr().c_str(), true); + } + goto failed; + } + + if (smtpData._sendCallback) + { + smtpData._cbData._info = ESP32_MAIL_STR_123; + smtpData._cbData._success = false; + smtpData._sendCallback(smtpData._cbData); + } + + if (smtpData._debug) + ESP32MailDebugInfo(ESP32_MAIL_STR_240); + + smtpData._net->getStreamPtr()->println(ESP32_MAIL_STR_4); + + if (waitSMTPResponse(smtpData) != 334) + { + _smtpStatus = SMTP_STATUS_AUTHEN_FAILED; + if (smtpData._sendCallback) + { + smtpData._cbData._info = ESP32_MAIL_STR_53 + smtpErrorReasonStr(); + smtpData._cbData._success = false; + smtpData._sendCallback(smtpData._cbData); + } + if (smtpData._debug) + { + ESP32MailDebugError(); + ESP32MailDebugLine(smtpErrorReasonStr().c_str(), true); + } + goto failed; + } + + if (smtpData._sendCallback) + { + smtpData._cbData._info = ESP32_MAIL_STR_124; + smtpData._cbData._success = false; + smtpData._sendCallback(smtpData._cbData); + } + if (smtpData._debug) + ESP32MailDebugInfo(ESP32_MAIL_STR_241); + + smtpData._net->getStreamPtr()->println(base64_encode_string((const unsigned char *)smtpData._loginEmail.c_str(), smtpData._loginEmail.length()).c_str()); + + if (waitSMTPResponse(smtpData) != 334) + { + _smtpStatus = SMTP_STATUS_USER_LOGIN_FAILED; + if (smtpData._sendCallback) + { + smtpData._cbData._info = ESP32_MAIL_STR_53 + smtpErrorReasonStr(); + smtpData._cbData._success = false; + smtpData._sendCallback(smtpData._cbData); + } + if (smtpData._debug) + { + ESP32MailDebugError(); + ESP32MailDebugLine(smtpErrorReasonStr().c_str(), true); + } + goto failed; + } + + smtpData._net->getStreamPtr()->println(base64_encode_string((const unsigned char *)smtpData._loginPassword.c_str(), smtpData._loginPassword.length()).c_str()); + + if (waitSMTPResponse(smtpData) != 235) + { + _smtpStatus = SMTP_STATUS_PASSWORD_LOGIN_FAILED; + if (smtpData._sendCallback) + { + smtpData._cbData._info = ESP32_MAIL_STR_53 + smtpErrorReasonStr(); + smtpData._cbData._success = false; + smtpData._sendCallback(smtpData._cbData); + } + if (smtpData._debug) + { + ESP32MailDebugError(); + ESP32MailDebugLine(smtpErrorReasonStr().c_str(), true); + } + goto failed; + } + + if (smtpData._sendCallback) + { + smtpData._cbData._info = ESP32_MAIL_STR_125; + smtpData._cbData._success = false; + smtpData._sendCallback(smtpData._cbData); + } + + if (smtpData._debug) + ESP32MailDebugInfo(ESP32_MAIL_STR_242); + + if (smtpData._priority > 0 && smtpData._priority <= 5) + { + memset(_val, 0, bufSize); + itoa(smtpData._priority, _val, 10); + + buf2 += ESP32_MAIL_STR_17; + buf2 += _val; + buf2 += ESP32_MAIL_STR_34; + + if (smtpData._priority == 1) + { + buf2 += ESP32_MAIL_STR_18; + buf2 += ESP32_MAIL_STR_21; + } + else if (smtpData._priority == 3) + { + buf2 += ESP32_MAIL_STR_19; + buf2 += ESP32_MAIL_STR_22; + } + else if (smtpData._priority == 5) + { + buf2 += ESP32_MAIL_STR_20; + buf2 += ESP32_MAIL_STR_23; + } + } + + buf2 += ESP32_MAIL_STR_10; + + if (smtpData._fromName.length() > 0) + buf2 += smtpData._fromName; + + buf2 += ESP32_MAIL_STR_14; + buf2 += smtpData._senderEmail; + buf2 += ESP32_MAIL_STR_15; + buf2 += ESP32_MAIL_STR_34; + + buf += ESP32_MAIL_STR_8; + buf += ESP32_MAIL_STR_14; + buf += smtpData._senderEmail; + buf += ESP32_MAIL_STR_15; + smtpData._net->getStreamPtr()->println(buf.c_str()); + + if (waitSMTPResponse(smtpData) != 250) + { + _smtpStatus = SMTP_STATUS_SEND_HEADER_SENDER_FAILED; + if (smtpData._sendCallback) + { + smtpData._cbData._info = ESP32_MAIL_STR_53 + smtpErrorReasonStr(); + smtpData._cbData._success = false; + smtpData._sendCallback(smtpData._cbData); + } + if (smtpData._debug) + { + ESP32MailDebugError(); + ESP32MailDebugLine(smtpErrorReasonStr().c_str(), true); + } + goto failed; + } + + for (uint8_t i = 0; i < smtpData._recipient.size(); i++) + { + if (i == 0) + { + buf2 += ESP32_MAIL_STR_11; + buf2 += ESP32_MAIL_STR_14; + buf2 += smtpData._recipient[i]; + buf2 += ESP32_MAIL_STR_15; + } + else + { + buf2 += ESP32_MAIL_STR_13; + buf2 += smtpData._recipient[i]; + buf2 += ESP32_MAIL_STR_15; + } + + if (i == smtpData._recipient.size() - 1) + buf2 += ESP32_MAIL_STR_34; + + buf.clear(); + + buf += ESP32_MAIL_STR_9; + buf += ESP32_MAIL_STR_14; + buf += smtpData._recipient[i]; + buf += ESP32_MAIL_STR_15; + + smtpData._net->getStreamPtr()->println(buf.c_str()); + + if (waitSMTPResponse(smtpData) != 250) + { + _smtpStatus = SMTP_STATUS_SEND_HEADER_RECIPIENT_FAILED; + if (smtpData._sendCallback) + { + smtpData._cbData._info = ESP32_MAIL_STR_53 + smtpErrorReasonStr(); + smtpData._cbData._success = false; + smtpData._sendCallback(smtpData._cbData); + } + if (smtpData._debug) + { + ESP32MailDebugError(); + ESP32MailDebugLine(smtpErrorReasonStr().c_str(), true); + } + goto failed; + } + } + + for (uint8_t i = 0; i < smtpData._cc.size(); i++) + { + + if (i == 0) + { + buf2 += ESP32_MAIL_STR_12; + buf2 += ESP32_MAIL_STR_14; + buf2 += smtpData._cc[i]; + buf2 += ESP32_MAIL_STR_15; + } + else + { + buf2 += ESP32_MAIL_STR_13; + buf2 += smtpData._cc[i]; + buf2 += ESP32_MAIL_STR_15; + } + + if (i == smtpData.ccCount() - 1) + buf2 += ESP32_MAIL_STR_34; + + buf.clear(); + + buf += ESP32_MAIL_STR_9; + buf += ESP32_MAIL_STR_14; + buf += smtpData._cc[i]; + buf += ESP32_MAIL_STR_15; + smtpData._net->getStreamPtr()->println(buf.c_str()); + + if (waitSMTPResponse(smtpData) != 250) + { + _smtpStatus = SMTP_STATUS_SEND_HEADER_RECIPIENT_FAILED; + if (smtpData._sendCallback) + { + smtpData._cbData._info = ESP32_MAIL_STR_53 + smtpErrorReasonStr(); + smtpData._cbData._success = false; + smtpData._sendCallback(smtpData._cbData); + } + if (smtpData._debug) + { + ESP32MailDebugError(); + ESP32MailDebugLine(smtpErrorReasonStr().c_str(), true); + } + goto failed; + } + } + + for (uint8_t i = 0; i < smtpData._bcc.size(); i++) + { + buf.clear(); + buf += ESP32_MAIL_STR_9; + buf += ESP32_MAIL_STR_14; + buf += smtpData._bcc[i]; + buf += ESP32_MAIL_STR_15; + smtpData._net->getStreamPtr()->println(buf.c_str()); + + if (waitSMTPResponse(smtpData) != 250) + { + _smtpStatus = SMTP_STATUS_SEND_HEADER_RECIPIENT_FAILED; + if (smtpData._sendCallback) + { + smtpData._cbData._info = ESP32_MAIL_STR_53 + smtpErrorReasonStr(); + smtpData._cbData._success = false; + smtpData._sendCallback(smtpData._cbData); + } + if (smtpData._debug) + { + ESP32MailDebugError(); + ESP32MailDebugLine(smtpErrorReasonStr().c_str(), true); + } + goto failed; + } + } + + if (smtpData._sendCallback) + { + smtpData._cbData._info = ESP32_MAIL_STR_126; + smtpData._cbData._success = false; + smtpData._sendCallback(smtpData._cbData); + } + + if (smtpData._debug) + ESP32MailDebugInfo(ESP32_MAIL_STR_243); + + smtpData._net->getStreamPtr()->println(ESP32_MAIL_STR_16); + + if (waitSMTPResponse(smtpData) != 354) + { + _smtpStatus = SMTP_STATUS_SEND_BODY_FAILED; + if (smtpData._sendCallback) + { + smtpData._cbData._info = ESP32_MAIL_STR_53 + smtpErrorReasonStr(); + smtpData._cbData._success = false; + smtpData._sendCallback(smtpData._cbData); + } + if (smtpData._debug) + { + ESP32MailDebugError(); + ESP32MailDebugLine(smtpErrorReasonStr().c_str(), true); + } + goto failed; + } + + smtpData._net->getStreamPtr()->print(buf2.c_str()); + + smtpData._net->getStreamPtr()->print(ESP32_MAIL_STR_24); + smtpData._net->getStreamPtr()->println(smtpData._subject.c_str()); + + if (smtpData._customMessageHeader.size() > 0) + for (uint8_t k = 0; k < smtpData._customMessageHeader.size(); k++) + smtpData._net->getStreamPtr()->println(smtpData._customMessageHeader[k].c_str()); + + smtpData._net->getStreamPtr()->print(ESP32_MAIL_STR_3); + smtpData._net->getStreamPtr()->print(ESP32_MAIL_STR_1); + smtpData._net->getStreamPtr()->print(ESP32_MAIL_STR_2); + smtpData._net->getStreamPtr()->print(ESP32_MAIL_STR_35); + + buf.clear(); + + set_message_header(buf, smtpData._message, smtpData._htmlFormat); + + smtpData._net->getStreamPtr()->print(buf.c_str()); + + if (smtpData._attach._index > 0) + { + smtpData._cbData._info = ESP32_MAIL_STR_127; + smtpData._cbData._success = false; + if (smtpData._sendCallback) + smtpData._sendCallback(smtpData._cbData); + if (smtpData._debug) + ESP32MailDebugInfo(ESP32_MAIL_STR_244); + } + + for (uint8_t i = 0; i < smtpData._attach._index; i++) + { + if (smtpData._attach._type[i] == 0) + { + + smtpData._cbData._info = smtpData._attach._filename[i]; + smtpData._cbData._success = false; + if (smtpData._sendCallback) + smtpData._sendCallback(smtpData._cbData); + if (smtpData._debug) + ESP32MailDebug(smtpData._attach._filename[i].c_str()); + + buf.clear(); + set_attachment_header(i, buf, smtpData._attach); + smtpData._net->getStreamPtr()->print(buf.c_str()); + send_base64_encode_mime_data(smtpData._net->getStreamPtr(), smtpData._attach._buf[i].front(), smtpData._attach._size[i]); + smtpData._net->getStreamPtr()->print(ESP32_MAIL_STR_34); + } + else + { + + if (!_sdOk) + { + if (smtpData._storageType == MailClientStorageType::SD) + _sdOk = sdTest(); + else if (smtpData._storageType == MailClientStorageType::SPIFFS) + _sdOk = SPIFFS.begin(true); + } + + if (!_sdOk) + continue; + + bool file_existed = false; + if (smtpData._storageType == MailClientStorageType::SD) + file_existed = SD.exists(smtpData._attach._filename[i].c_str()); + else if (smtpData._storageType == MailClientStorageType::SPIFFS) + file_existed = SPIFFS.exists(smtpData._attach._filename[i].c_str()); + + if (file_existed) + { + smtpData._cbData._info = smtpData._attach._filename[i]; + smtpData._cbData._success = false; + if (smtpData._sendCallback) + smtpData._sendCallback(smtpData._cbData); + + if (smtpData._debug) + ESP32MailDebug(smtpData._attach._filename[i].c_str()); + + buf.clear(); + set_attachment_header(i, buf, smtpData._attach); + smtpData._net->getStreamPtr()->print(buf.c_str()); + + File file; + if (smtpData._storageType == MailClientStorageType::SD) + file = SD.open(smtpData._attach._filename[i].c_str(), FILE_READ); + else if (smtpData._storageType == MailClientStorageType::SPIFFS) + file = SPIFFS.open(smtpData._attach._filename[i].c_str(), FILE_READ); + + send_base64_encode_mime_file(smtpData._net->getStreamPtr(), file); + smtpData._net->getStreamPtr()->print(ESP32_MAIL_STR_34); + } + } + } + + if (smtpData._debug) + ESP32MailDebugInfo(ESP32_MAIL_STR_245); + + smtpData._net->getStreamPtr()->print(ESP32_MAIL_STR_33); + smtpData._net->getStreamPtr()->print(ESP32_MAIL_STR_2); + smtpData._net->getStreamPtr()->print(ESP32_MAIL_STR_33); + smtpData._net->getStreamPtr()->print(ESP32_MAIL_STR_37); + + if (smtpData._sendCallback) + { + smtpData._cbData._info = ESP32_MAIL_STR_128; + smtpData._cbData._success = false; + smtpData._sendCallback(smtpData._cbData); + } + + res = waitSMTPResponse(smtpData); + + if (res != 250 && res != -1000) + { + _smtpStatus = SMTP_STATUS_SEND_BODY_FAILED; + if (smtpData._sendCallback) + { + smtpData._cbData._info = ESP32_MAIL_STR_53 + smtpErrorReasonStr(); + smtpData._cbData._success = false; + smtpData._sendCallback(smtpData._cbData); + } + if (smtpData._debug) + { + ESP32MailDebugError(); + ESP32MailDebugLine(smtpErrorReasonStr().c_str(), true); + } + goto failed; + } + + if (smtpData._sendCallback) + { + smtpData._cbData._info = ESP32_MAIL_STR_129; + smtpData._cbData._success = true; + smtpData._sendCallback(smtpData._cbData); + } + + if (smtpData._debug) + ESP32MailDebugInfo(ESP32_MAIL_STR_246); + + if (smtpData._net->connected()) + smtpData._net->getStreamPtr()->stop(); + + smtpData._cbData.empty(); + + std::string().swap(buf); + std::string().swap(buf2); + delete[] _val; + + return true; + +failed: + + if (connected) + { + if (smtpData._net->connected()) + smtpData._net->getStreamPtr()->stop(); + } + + smtpData._cbData.empty(); + std::string().swap(buf); + std::string().swap(buf2); + delete[] _val; + return false; +} + +String ESP32_MailClient::smtpErrorReason() +{ + return smtpErrorReasonStr().c_str(); +} + +std::string ESP32_MailClient::smtpErrorReasonStr() +{ + std::string res = ""; + switch (_smtpStatus) + { + case SMTP_STATUS_SERVER_CONNECT_FAILED: + res = ESP32_MAIL_STR_38; + break; + case SMTP_STATUS_SMTP_RESPONSE_FAILED: + res = ESP32_MAIL_STR_39; + break; + case SMTP_STATUS_IDENTIFICATION_FAILED: + res = ESP32_MAIL_STR_41; + break; + case SMTP_STATUS_AUTHEN_NOT_SUPPORT: + res = ESP32_MAIL_STR_42; + break; + case SMTP_STATUS_AUTHEN_FAILED: + res = ESP32_MAIL_STR_43; + break; + case SMTP_STATUS_USER_LOGIN_FAILED: + res = ESP32_MAIL_STR_44; + break; + case SMTP_STATUS_PASSWORD_LOGIN_FAILED: + res = ESP32_MAIL_STR_47; + break; + case SMTP_STATUS_SEND_HEADER_SENDER_FAILED: + res = ESP32_MAIL_STR_48; + break; + case SMTP_STATUS_SEND_HEADER_RECIPIENT_FAILED: + res = ESP32_MAIL_STR_222; + break; + case SMTP_STATUS_SEND_BODY_FAILED: + res = ESP32_MAIL_STR_49; + break; + case MAIL_CLIENT_STATUS_WIFI_CONNECT_FAIL: + res = ESP32_MAIL_STR_221; + break; + default: + res = ""; + } + return res; +} + +String ESP32_MailClient::imapErrorReason() +{ + std::string res = ""; + switch (_imapStatus) + { + case IMAP_STATUS_SERVER_CONNECT_FAILED: + res = ESP32_MAIL_STR_38; + break; + case IMAP_STATUS_IMAP_RESPONSE_FAILED: + res = ESP32_MAIL_STR_40; + break; + case IMAP_STATUS_LOGIN_FAILED: + res = ESP32_MAIL_STR_45; + break; + case IMAP_STATUS_BAD_COMMAND: + res = ESP32_MAIL_STR_46; + break; + case IMAP_STATUS_PARSE_FLAG_FAILED: + res = ESP32_MAIL_STR_256; + break; + case MAIL_CLIENT_STATUS_WIFI_CONNECT_FAIL: + res = ESP32_MAIL_STR_221; + break; + default: + res = ""; + } + return res.c_str(); +} + +std::string ESP32_MailClient::imapErrorReasonStr() +{ + std::string res = ""; + + switch (_imapStatus) + { + case IMAP_STATUS_SERVER_CONNECT_FAILED: + res = ESP32_MAIL_STR_38; + break; + case IMAP_STATUS_IMAP_RESPONSE_FAILED: + res = ESP32_MAIL_STR_40; + break; + case IMAP_STATUS_LOGIN_FAILED: + res = ESP32_MAIL_STR_45; + break; + case IMAP_STATUS_BAD_COMMAND: + res = ESP32_MAIL_STR_46; + break; + case IMAP_STATUS_PARSE_FLAG_FAILED: + res = ESP32_MAIL_STR_256; + break; + case MAIL_CLIENT_STATUS_WIFI_CONNECT_FAIL: + res = ESP32_MAIL_STR_221; + break; + default: + res = ""; + } + return res; +} + +void ESP32_MailClient::ESP32MailDebugError() +{ + size_t dbgInfoLen = strlen_P(ESP32_MAIL_STR_227) + 1; + char *dbgInfo = new char[dbgInfoLen]; + memset(dbgInfo, 0, dbgInfoLen); + strcpy_P(dbgInfo, ESP32_MAIL_STR_227); + ESP32MailDebugLine(dbgInfo, false); + delete[] dbgInfo; +} + +void ESP32_MailClient::ESP32MailDebugInfo(PGM_P info) +{ + size_t dbgInfoLen = strlen_P(info) + 1; + char *dbgInfo = new char[dbgInfoLen]; + memset(dbgInfo, 0, dbgInfoLen); + strcpy_P(dbgInfo, info); + ESP32MailDebug(dbgInfo); + delete[] dbgInfo; +} + +bool ESP32_MailClient::sdBegin(uint8_t sck, uint8_t miso, uint8_t mosi, uint8_t ss) +{ + _sck = sck; + _miso = miso; + _mosi = mosi; + _ss = ss; + _sdConfigSet = true; + SPI.begin(_sck, _miso, _mosi, _ss); + return SD.begin(_ss, SPI); +} + +bool ESP32_MailClient::sdBegin(void) +{ + _sdConfigSet = false; + return SD.begin(); +} + +void ESP32_MailClient::set_message_header(string &header, string &message, bool htmlFormat) +{ + header += ESP32_MAIL_STR_33; + header += ESP32_MAIL_STR_2; + header += ESP32_MAIL_STR_34; + if (!htmlFormat) + header += ESP32_MAIL_STR_27; + else + header += ESP32_MAIL_STR_28; + + header += ESP32_MAIL_STR_29; + header += ESP32_MAIL_STR_34; + + header += message; + header += ESP32_MAIL_STR_34; + header += ESP32_MAIL_STR_34; +} + +void ESP32_MailClient::set_attachment_header(uint8_t index, std::string &header, attachmentData &attach) +{ + + header += ESP32_MAIL_STR_33; + header += ESP32_MAIL_STR_2; + header += ESP32_MAIL_STR_34; + + header += ESP32_MAIL_STR_25; + + if (attach._mime_type[index].length() == 0) + header += ESP32_MAIL_STR_32; + else + header += attach._mime_type[index]; + + header += ESP32_MAIL_STR_26; + + std::string filename(attach._filename[index]); + + size_t found = filename.find_last_of("/\\"); + + if (found != std::string::npos) + { + filename.clear(); + filename += attach._filename[index].substr(found + 1); + } + + header += filename; + header += ESP32_MAIL_STR_36; + + header += ESP32_MAIL_STR_30; + header += filename; + header += ESP32_MAIL_STR_36; + + header += ESP32_MAIL_STR_31; + header += ESP32_MAIL_STR_34; + + std::string().swap(filename); +} + +int ESP32_MailClient::waitSMTPResponse(SMTPData &smtpData) +{ + + long dataTime = millis(); + char c = '\0'; + std::string lineBuf = ""; + int lfCount = 0; + size_t p1 = 0; + int resCode = -1000; + + while (smtpClientAvailable(smtpData, false) && millis() - dataTime < smtpData._net->tcpTimeout) + delay(0); + + dataTime = millis(); + if (smtpClientAvailable(smtpData, true)) + { + while (smtpClientAvailable(smtpData, true)) + { + int r = smtpData._net->getStreamPtr()->read(); + + if (r < 0) + continue; + + c = (char)r; + + lineBuf.append(1, c); + if (c == '\n') + { + dataTime = millis(); + if (lfCount == 0) + { + p1 = lineBuf.find(" "); + if (p1 != std::string::npos) + resCode = atoi(lineBuf.substr(0, p1).c_str()); + } + if (smtpData._debug) + ESP32MailDebug(lineBuf.c_str()); + lineBuf.clear(); + lfCount++; + } + + if (millis() - dataTime > smtpData._net->tcpTimeout + 30000) + break; + } + } + std::string().swap(lineBuf); + return resCode; +} + +bool ESP32_MailClient::getIMAPResponse(IMAPData &imapData) +{ + long dataTime = millis(); + char c = '\0'; + bool success = false; + std::string str = ""; + while (imapClientAvailable(imapData, false) && millis() - dataTime < imapData._net->tcpTimeout) + delay(0); + + dataTime = millis(); + if (imapClientAvailable(imapData, true)) + { + while (imapClientAvailable(imapData, true)) + { + int r = imapData._net->getStreamPtr()->read(); + if (r < 0) + continue; + c = (char)r; + if (c == '\n') + { + if (imapData._debug) + ESP32MailDebug(str.c_str()); + str.clear(); + } + else + str += c; + + if (str.find(ESP32_MAIL_STR_132) != std::string::npos) + success = true; + } + } + + std::string().swap(str); + return success; +} + +bool ESP32_MailClient::waitIMAPResponse(IMAPData &imapData, uint8_t imapCommandType, int maxChar, int mailIndex, int messageDataIndex, std::string part) +{ + + long dataTime = millis(); + + char c = 0; + std::string lineBuf = ""; + std::string msgNumBuf = ""; + std::string filepath = ""; + std::string hpath = ""; + std::string tmp = ""; + std::string msgID = ""; + std::string from = ""; + std::string to = ""; + std::string subject = ""; + std::string date = ""; + std::string cc = ""; + std::string from_charset = ""; + std::string to_charset = ""; + std::string cc_charset = ""; + std::string subject_charset = ""; + std::string acceptLanguage = ""; + std::string contentLanguage = ""; + + int bufSize = 100; + char *dest = new char[bufSize]; + char *buf = new char[bufSize]; + + int readCount = 0; + int lfCount = 0; + int charCount = 0; + size_t p1 = 0; + size_t p2 = 0; + size_t p3 = 0; + size_t payloadLength = 0; + size_t outputLength; + + bool completeResp = false; + bool validResponse = false; + bool downloadReq = false; + size_t currentDownloadByte = 0; + + int max = imapData._emailNumMax; + if (!imapData._recentSort) + max = max - 1; + + uint8_t headerType = 0; + + File file; + int reportState = 0; + int downloadedByte = 0; + + if (imapCommandType == IMAP_COMMAND_TYPE::LIST) + std::vector() + .swap(imapData._folders); + + while (imapClientAvailable(imapData, false) && millis() - dataTime < imapData._net->tcpTimeout) + delay(0); + + dataTime = millis(); + if (imapClientAvailable(imapData, true)) + { + while (imapClientAvailable(imapData, true) || !completeResp) + { + + int r = imapData._net->getStreamPtr()->read(); + + if (r < 0) + continue; + + c = (char)r; + + if (payloadLength > 0 && !completeResp) + charCount++; + + if (imapCommandType == IMAP_COMMAND_TYPE::SEARCH && lfCount == 0) + { + delay(0); + if (c == ' ') + { + p3 = msgNumBuf.find(ESP32_MAIL_STR_257); + if (p3 != std::string::npos) + { + validResponse = false; + break; + } + + if (msgNumBuf != ESP32_MAIL_STR_183 && msgNumBuf != ESP32_MAIL_STR_141 && imapData._msgNum.size() <= max) + { + imapData._msgNum.push_back(atoi(msgNumBuf.c_str())); + + if (imapData._msgNum.size() > imapData._emailNumMax && imapData._recentSort) + imapData._msgNum.erase(imapData._msgNum.begin()); + imapData._searchCount++; + } + + msgNumBuf.clear(); + } + else if (c != '\r' && c != '\n') + { + msgNumBuf.append(1, c); + } + } + + if (c != '\r' && c != '\n' && imapCommandType != IMAP_COMMAND_TYPE::SEARCH) + lineBuf.append(1, c); + + if (validResponse && imapCommandType == IMAP_COMMAND_TYPE::FETCH_BODY_TEXT && lfCount > 0) + { + + if (payloadLength > 0 && charCount < payloadLength - 1) + { + + if (imapData._messageDataInfo[mailIndex][messageDataIndex]._transfer_encoding != ESP32_MAIL_STR_160) + { + if (charCount < maxChar) + imapData._messageDataInfo[mailIndex][messageDataIndex]._text.append(1, c); + + if (imapData._saveHTMLMsg || imapData._saveTextMsg) + { + + if (!imapData._messageDataInfo[mailIndex][messageDataIndex]._sdFileOpenWrite) + { + imapData._messageDataInfo[mailIndex][messageDataIndex]._sdFileOpenWrite = true; + + if (_sdOk) + { + downloadReq = true; + + filepath.clear(); + + filepath = imapData._savePath; + filepath += ESP32_MAIL_STR_202; + + char *midx = new char[50]; + memset(midx, 0, 50); + itoa(imapData._msgNum[mailIndex], midx, 10); + + filepath += midx; + + delete[] midx; + + if (imapData._storageType == MailClientStorageType::SD) + if (!SD.exists(filepath.c_str())) + createDirs(filepath); + + if (!imapData._headerSaved) + hpath = filepath + ESP32_MAIL_STR_203; + + if (imapData._messageDataInfo[mailIndex][messageDataIndex]._contentType == ESP32_MAIL_STR_155) + { + if (imapData._saveDecodedText) + filepath += ESP32_MAIL_STR_161; + else + filepath += ESP32_MAIL_STR_162; + } + else if (imapData._messageDataInfo[mailIndex][messageDataIndex]._contentType == ESP32_MAIL_STR_154) + { + if (imapData._saveDecodedHTML) + filepath += ESP32_MAIL_STR_163; + else + filepath += ESP32_MAIL_STR_164; + } + + if (imapData._storageType == MailClientStorageType::SD) + file = SD.open(filepath.c_str(), FILE_WRITE); + else if (imapData._storageType == MailClientStorageType::SPIFFS) + file = SPIFFS.open(filepath.c_str(), FILE_WRITE); + } + else + { + + if (imapData._messageDataCount[mailIndex] == messageDataIndex + 1) + { + imapData._messageDataInfo[mailIndex][messageDataIndex]._error = true; + imapData._messageDataInfo[mailIndex][messageDataIndex]._downloadError.clear(); + imapData._messageDataInfo[mailIndex][messageDataIndex]._downloadError = ESP32_MAIL_STR_89; + } + } + } + if (_sdOk) + file.write(c); + } + } + } + + if (millis() - dataTime > imapData._net->tcpTimeout + (30 * 1000) || (payloadLength > 0 && charCount == payloadLength && completeResp)) + { + + if (charCount < payloadLength || !completeResp) + clientReadAll(imapData._net->getStreamPtr()); + + break; + } + } + + if (c == '\n') + { + dataTime = millis(); + + if (lfCount == 0) + { + if (imapData._debug) + ESP32MailDebug(lineBuf.c_str()); + + if (imapCommandType == IMAP_COMMAND_TYPE::FETCH_BODY_TEXT || + imapCommandType == IMAP_COMMAND_TYPE::FETCH_BODY_MIME || + imapCommandType == IMAP_COMMAND_TYPE::FETCH_BODY_HEADER || + imapCommandType == IMAP_COMMAND_TYPE::FETCH_BODY_ATTACHMENT) + { + + p1 = lineBuf.find(ESP32_MAIL_STR_165); + if (p1 != std::string::npos) + validResponse = true; + } + + p1 = lineBuf.find(ESP32_MAIL_STR_166); + if (p1 != std::string::npos) + validResponse = true; + } + + p1 = lineBuf.find(ESP32_MAIL_STR_211); + p2 = lineBuf.find(ESP32_MAIL_STR_158); + p3 = lineBuf.find(ESP32_MAIL_STR_159); + + if (p1 != std::string::npos || p2 != std::string::npos || p3 != std::string::npos) + { + + validResponse = true; + + if (p2 != std::string::npos || p3 != std::string::npos) + validResponse = false; + + if (payloadLength == 0) + { + if (imapCommandType == IMAP_COMMAND_TYPE::LOGIN || + imapCommandType == IMAP_COMMAND_TYPE::LIST || + imapCommandType == IMAP_COMMAND_TYPE::EXAMINE || + imapCommandType == IMAP_COMMAND_TYPE::SEARCH || + imapCommandType == IMAP_COMMAND_TYPE::FETCH_BODY_MIME || + imapCommandType == IMAP_COMMAND_TYPE::FETCH_BODY_HEADER) + { + + //Cyrus server 3.0 does not comply to rfc3501 as it resonses the CAPABILITY after received LOGIN command with no CAPABILITY command requested. + if (lineBuf.find(ESP32_MAIL_STR_134) == std::string::npos && lineBuf.find(ESP32_MAIL_STR_145) == std::string::npos) + completeResp = true; + + //Some servers e.g. STRATO E-Mail-Server does not reply any error when fetching none existing MIME header part at defined index. + if (imapCommandType == IMAP_COMMAND_TYPE::FETCH_BODY_MIME) + validResponse = false; + } + } + else + { + + if ((payloadLength > 0 && charCount >= payloadLength) || imapCommandType == IMAP_COMMAND_TYPE::FETCH_BODY_MIME) + { + completeResp = true; + } + } + } + + if (imapCommandType == IMAP_COMMAND_TYPE::SEARCH && lfCount > 0) + { + completeResp = true; + validResponse = true; + } + + tmp = lineBuf; + std::transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower); + + if (imapCommandType == IMAP_COMMAND_TYPE::FETCH_BODY_MIME && lfCount > 0) + { + + if (payloadLength > 0 && validResponse) + { + + if (imapData._messageDataInfo[mailIndex].size() < messageDataIndex + 1) + { + messageBodyData b; + imapData._messageDataInfo[mailIndex].push_back(b); + imapData._messageDataCount[mailIndex] = imapData._messageDataInfo[mailIndex].size(); + } + + p1 = tmp.find(ESP32_MAIL_STR_167); + if (p1 != std::string::npos) + { + + p2 = lineBuf.find(";", p1 + strlen(ESP32_MAIL_STR_167)); + if (p2 != std::string::npos) + { + + imapData._messageDataInfo[mailIndex][messageDataIndex]._contentType = lineBuf.substr(p1 + strlen(ESP32_MAIL_STR_167), p2 - p1 - strlen(ESP32_MAIL_STR_167)); + + p1 = tmp.find(ESP32_MAIL_STR_168, p2); + if (p1 != std::string::npos) + { + p2 = lineBuf.find(ESP32_MAIL_STR_136, p1 + strlen(ESP32_MAIL_STR_168)); + if (p2 != std::string::npos) + imapData._messageDataInfo[mailIndex][messageDataIndex]._charset = lineBuf.substr(p1 + strlen(ESP32_MAIL_STR_168), p2 - p1 - strlen(ESP32_MAIL_STR_168)); + } + else if (tmp.find(ESP32_MAIL_STR_169, p2) != std::string::npos) + { + p1 = tmp.find(ESP32_MAIL_STR_169, p2); + imapData._messageDataInfo[mailIndex][messageDataIndex]._charset = lineBuf.substr(p1 + strlen(ESP32_MAIL_STR_169)); + } + + p1 = tmp.find(ESP32_MAIL_STR_170, p2); + if (p1 != std::string::npos) + { + p2 = lineBuf.find(ESP32_MAIL_STR_136, p1 + strlen(ESP32_MAIL_STR_170)); + if (p2 != std::string::npos) + imapData._messageDataInfo[mailIndex][messageDataIndex]._name = lineBuf.substr(p1 + strlen(ESP32_MAIL_STR_170), p2 - p1 - strlen(ESP32_MAIL_STR_170)); + } + else if (tmp.find(ESP32_MAIL_STR_171, p2) != std::string::npos) + { + p1 = tmp.find(ESP32_MAIL_STR_171, p2); + imapData._messageDataInfo[mailIndex][messageDataIndex]._name = lineBuf.substr(p1 + strlen(ESP32_MAIL_STR_171)); + } + } + } + + p1 = tmp.find(ESP32_MAIL_STR_172); + if (p1 != std::string::npos) + { + + p2 = lineBuf.find(ESP32_MAIL_STR_173, p1 + strlen(ESP32_MAIL_STR_172)); + + if (p2 != std::string::npos) + imapData._messageDataInfo[mailIndex][messageDataIndex]._transfer_encoding = lineBuf.substr(p1 + strlen(ESP32_MAIL_STR_172), p2 - p1 - strlen(ESP32_MAIL_STR_172)); + else + imapData._messageDataInfo[mailIndex][messageDataIndex]._transfer_encoding = lineBuf.substr(p1 + strlen(ESP32_MAIL_STR_172)); + } + + p1 = tmp.find(ESP32_MAIL_STR_174); + if (p1 != std::string::npos) + { + p2 = lineBuf.find(ESP32_MAIL_STR_173, p1 + strlen(ESP32_MAIL_STR_174)); + + if (p2 != std::string::npos) + imapData._messageDataInfo[mailIndex][messageDataIndex]._descr = lineBuf.substr(p1 + strlen(ESP32_MAIL_STR_174), p2 - p1 - strlen(ESP32_MAIL_STR_174)); + else + imapData._messageDataInfo[mailIndex][messageDataIndex]._descr = lineBuf.substr(p1 + strlen(ESP32_MAIL_STR_174)); + } + + p1 = tmp.find(ESP32_MAIL_STR_175); + if (p1 != std::string::npos) + { + + p2 = lineBuf.find(";", p1 + strlen(ESP32_MAIL_STR_175)); + + if (p2 != std::string::npos) + imapData._messageDataInfo[mailIndex][messageDataIndex]._disposition = lineBuf.substr(p1 + strlen(ESP32_MAIL_STR_175), p2 - p1 - strlen(ESP32_MAIL_STR_175)); + else + imapData._messageDataInfo[mailIndex][messageDataIndex]._disposition = lineBuf.substr(p1 + strlen(ESP32_MAIL_STR_175)); + + if (imapData._messageDataInfo[mailIndex][messageDataIndex]._disposition == ESP32_MAIL_STR_153) + imapData._attachmentCount[mailIndex]++; + } + + if (imapData._messageDataInfo[mailIndex][messageDataIndex]._disposition != "") + { + + p1 = tmp.find(ESP32_MAIL_STR_176); + if (p1 != std::string::npos) + { + p2 = lineBuf.find(ESP32_MAIL_STR_136, p1 + strlen(ESP32_MAIL_STR_176)); + + if (p2 != std::string::npos) + imapData._messageDataInfo[mailIndex][messageDataIndex]._filename = lineBuf.substr(p1 + strlen(ESP32_MAIL_STR_176), p2 - p1 - strlen(ESP32_MAIL_STR_176)); + } + else if (tmp.find(ESP32_MAIL_STR_177) != std::string::npos) + { + + p1 = tmp.find(ESP32_MAIL_STR_177); + imapData._messageDataInfo[mailIndex][messageDataIndex]._filename = lineBuf.substr(p1 + strlen(ESP32_MAIL_STR_177)); + } + + p1 = tmp.find(ESP32_MAIL_STR_178); + if (p1 != std::string::npos) + { + p2 = lineBuf.find(";", p1 + strlen(ESP32_MAIL_STR_178) + 1); + if (p2 != std::string::npos) + { + imapData._messageDataInfo[mailIndex][messageDataIndex]._size = atoi(lineBuf.substr(p1 + strlen(ESP32_MAIL_STR_178), p2 - p1 - strlen(ESP32_MAIL_STR_178)).c_str()); + imapData._totalAttachFileSize[mailIndex] += imapData._messageDataInfo[mailIndex][messageDataIndex]._size; + } + else + { + imapData._messageDataInfo[mailIndex][messageDataIndex]._size = atoi(lineBuf.substr(p1 + strlen(ESP32_MAIL_STR_178)).c_str()); + imapData._totalAttachFileSize[mailIndex] += imapData._messageDataInfo[mailIndex][messageDataIndex]._size; + } + } + + p1 = tmp.find(ESP32_MAIL_STR_179); + if (p1 != std::string::npos) + { + p2 = lineBuf.find(ESP32_MAIL_STR_136, p1 + strlen(ESP32_MAIL_STR_179)); + if (p2 != std::string::npos) + imapData._messageDataInfo[mailIndex][messageDataIndex]._creation_date = lineBuf.substr(p1 + strlen(ESP32_MAIL_STR_179), p2 - p1 - strlen(ESP32_MAIL_STR_179)); + } + else if (tmp.find(ESP32_MAIL_STR_180) != std::string::npos) + { + p1 = tmp.find(ESP32_MAIL_STR_180); + imapData._messageDataInfo[mailIndex][messageDataIndex]._creation_date = lineBuf.substr(p1 + strlen(ESP32_MAIL_STR_180)); + } + + p1 = tmp.find(ESP32_MAIL_STR_181); + if (p1 != std::string::npos) + { + p2 = lineBuf.find(ESP32_MAIL_STR_136, p1 + strlen(ESP32_MAIL_STR_181)); + if (p2 != std::string::npos) + imapData._messageDataInfo[mailIndex][messageDataIndex]._modification_date = lineBuf.substr(p1 + strlen(ESP32_MAIL_STR_181), p2 - p1 - strlen(ESP32_MAIL_STR_181)); + } + else if (tmp.find(ESP32_MAIL_STR_182) != std::string::npos) + { + p1 = tmp.find(ESP32_MAIL_STR_182); + imapData._messageDataInfo[mailIndex][messageDataIndex]._modification_date = lineBuf.substr(p1 + strlen(ESP32_MAIL_STR_182)); + } + } + + imapData._messageDataInfo[mailIndex][messageDataIndex]._part = part; + } + } + + if (imapCommandType == IMAP_COMMAND_TYPE::SEARCH && lfCount == 0) + { + + if (msgNumBuf.length() > 0 && msgNumBuf != ESP32_MAIL_STR_183 && msgNumBuf != ESP32_MAIL_STR_141 && imapData._msgNum.size() <= max) + { + imapData._msgNum.push_back(atoi(msgNumBuf.c_str())); + imapData._searchCount++; + + if (imapData._msgNum.size() > imapData._emailNumMax && imapData._recentSort) + imapData._msgNum.erase(imapData._msgNum.begin()); + } + + if (imapData._recentSort) + std::sort(imapData._msgNum.begin(), imapData._msgNum.end(), compFunc); + } + + if (imapCommandType == IMAP_COMMAND_TYPE::FETCH_BODY_HEADER) + { + + uint8_t _headerType = 0; + + p1 = tmp.find(ESP32_MAIL_STR_184); + if (p1 != std::string::npos) + { + headerType = IMAP_HEADER_TYPE::FROM; + _headerType = IMAP_HEADER_TYPE::FROM; + + p2 = lineBuf.find(ESP32_MAIL_STR_173, p1 + strlen(ESP32_MAIL_STR_184)); + if (p2 != std::string::npos) + from = lineBuf.substr(p1 + strlen(ESP32_MAIL_STR_184), p2 - p1 - strlen(ESP32_MAIL_STR_184)); + else + from = lineBuf.substr(p1 + strlen(ESP32_MAIL_STR_184)); + + if (from[0] == '=' && from[1] == '?') + { + p1 = from.find("?", 2); + + if (p1 != std::string::npos) + from_charset = from.substr(2, p1 - 2); + } + + memset(dest, 0, bufSize); + RFC2047Decoder.rfc2047Decode(dest, from.c_str(), bufSize); + from = dest; + } + + p1 = tmp.find(ESP32_MAIL_STR_185); + if (p1 != std::string::npos) + { + headerType = IMAP_HEADER_TYPE::TO; + _headerType = IMAP_HEADER_TYPE::TO; + + p2 = lineBuf.find(ESP32_MAIL_STR_173, p1 + 1); + if (p2 != std::string::npos) + to = lineBuf.substr(p1 + strlen(ESP32_MAIL_STR_185), p2 - p1 - strlen(ESP32_MAIL_STR_185)); + else + to = lineBuf.substr(p1 + strlen(ESP32_MAIL_STR_185)); + + if (to[0] == '=' && to[1] == '?') + { + p1 = to.find("?", 2); + + if (p1 != std::string::npos) + to_charset = to.substr(2, p1 - 2); + } + + memset(dest, 0, bufSize); + RFC2047Decoder.rfc2047Decode(dest, to.c_str(), bufSize); + to = dest; + } + + p1 = tmp.find(ESP32_MAIL_STR_186); + if (p1 != std::string::npos) + { + headerType = IMAP_HEADER_TYPE::CC; + _headerType = IMAP_HEADER_TYPE::CC; + + p2 = lineBuf.find(ESP32_MAIL_STR_173, p1 + 1); + if (p2 != std::string::npos) + cc = lineBuf.substr(p1 + strlen(ESP32_MAIL_STR_186), p2 - p1 - strlen(ESP32_MAIL_STR_186)); + else + cc = lineBuf.substr(p1 + strlen(ESP32_MAIL_STR_186)); + + if (cc[0] == '=' && cc[1] == '?') + { + p1 = cc.find("?", 2); + + if (p1 != std::string::npos) + cc_charset = cc.substr(2, p1 - 2); + } + + memset(dest, 0, bufSize); + RFC2047Decoder.rfc2047Decode(dest, cc.c_str(), bufSize); + cc = dest; + } + + p1 = tmp.find(ESP32_MAIL_STR_187); + if (p1 != std::string::npos) + { + headerType = IMAP_HEADER_TYPE::SUBJECT; + _headerType = IMAP_HEADER_TYPE::SUBJECT; + + p2 = lineBuf.find(ESP32_MAIL_STR_173, p1 + 1); + + memset(dest, 0, bufSize); + if (p2 != std::string::npos) + subject = lineBuf.substr(p1 + strlen(ESP32_MAIL_STR_187), p2 - p1 - strlen(ESP32_MAIL_STR_187)); + else + subject = lineBuf.substr(p1 + strlen(ESP32_MAIL_STR_187)); + + if (subject[0] == '=' && subject[1] == '?') + { + p1 = subject.find("?", 2); + if (p1 != std::string::npos) + subject_charset = subject.substr(2, p1 - 2); + } + + memset(dest, 0, bufSize); + RFC2047Decoder.rfc2047Decode(dest, subject.c_str(), bufSize); + subject = dest; + } + p1 = tmp.find(ESP32_MAIL_STR_188); + if (p1 != std::string::npos) + { + headerType = IMAP_HEADER_TYPE::DATE; + _headerType = IMAP_HEADER_TYPE::DATE; + + p2 = lineBuf.find(ESP32_MAIL_STR_173, p1 + 1); + if (p2 != std::string::npos) + date = lineBuf.substr(p1 + strlen(ESP32_MAIL_STR_188), p2 - p1 - strlen(ESP32_MAIL_STR_188)); + else + date = lineBuf.substr(p1 + strlen(ESP32_MAIL_STR_188)); + } + + p1 = tmp.find(ESP32_MAIL_STR_189); + if (p1 != std::string::npos) + { + headerType = IMAP_HEADER_TYPE::MSG_ID; + _headerType = IMAP_HEADER_TYPE::MSG_ID; + + p2 = lineBuf.find(ESP32_MAIL_STR_173, p1 + 1); + if (p2 != std::string::npos) + msgID = lineBuf.substr(p1 + strlen(ESP32_MAIL_STR_189), p2 - p1 - strlen(ESP32_MAIL_STR_189)); + else + msgID = lineBuf.substr(p1 + strlen(ESP32_MAIL_STR_189)); + } + + p1 = tmp.find(ESP32_MAIL_STR_190); + if (p1 != std::string::npos) + { + headerType = IMAP_HEADER_TYPE::ACCEPT_LANG; + _headerType = IMAP_HEADER_TYPE::ACCEPT_LANG; + + p2 = lineBuf.find(ESP32_MAIL_STR_173, p1 + 1); + if (p2 != std::string::npos) + acceptLanguage = lineBuf.substr(p1 + strlen(ESP32_MAIL_STR_190), p2 - p1 - strlen(ESP32_MAIL_STR_190)); + else + acceptLanguage = lineBuf.substr(p1 + strlen(ESP32_MAIL_STR_190)); + } + + p1 = tmp.find(ESP32_MAIL_STR_191); + if (p1 != std::string::npos) + { + headerType = IMAP_HEADER_TYPE::CONT_LANG; + _headerType = IMAP_HEADER_TYPE::CONT_LANG; + + p2 = lineBuf.find(ESP32_MAIL_STR_173, p1 + 1); + if (p2 != std::string::npos) + contentLanguage = lineBuf.substr(p1 + strlen(ESP32_MAIL_STR_191), p2 - p1 - strlen(ESP32_MAIL_STR_191)); + else + contentLanguage = lineBuf.substr(p1 + strlen(ESP32_MAIL_STR_191)); + } + + if (_headerType == 0 && charCount < payloadLength && payloadLength > 0) + { + if (headerType == IMAP_HEADER_TYPE::FROM) + { + memset(dest, 0, bufSize); + RFC2047Decoder.rfc2047Decode(dest, lineBuf.c_str(), bufSize); + from += dest; + } + else if (headerType == IMAP_HEADER_TYPE::TO) + { + memset(dest, 0, bufSize); + RFC2047Decoder.rfc2047Decode(dest, lineBuf.c_str(), bufSize); + to += dest; + } + else if (headerType == IMAP_HEADER_TYPE::CC) + { + memset(dest, 0, bufSize); + RFC2047Decoder.rfc2047Decode(dest, lineBuf.c_str(), bufSize); + cc += dest; + } + else if (headerType == IMAP_HEADER_TYPE::SUBJECT) + { + memset(dest, 0, bufSize); + RFC2047Decoder.rfc2047Decode(dest, lineBuf.c_str(), bufSize); + subject += dest; + } + } + } + + if (imapCommandType == IMAP_COMMAND_TYPE::LIST) + { + p1 = lineBuf.find(ESP32_MAIL_STR_195); + p2 = lineBuf.find(ESP32_MAIL_STR_196); + + if (p1 != std::string::npos && p2 == std::string::npos) + { + p2 = lineBuf.find_last_of(ESP32_MAIL_STR_136); + if (p2 != std::string::npos) + { + p1 = lineBuf.find_last_of(ESP32_MAIL_STR_136, p2 - 1); + if (p1 != std::string::npos) + imapData._folders.push_back(lineBuf.substr(p1 + 1, p2 - p1 - 1)); + } + } + } + + if (imapCommandType == IMAP_COMMAND_TYPE::SELECT || imapCommandType == IMAP_COMMAND_TYPE::EXAMINE) + { + + p1 = lineBuf.find(ESP32_MAIL_STR_197); + if (p1 != std::string::npos) + { + p1 = lineBuf.find(ESP32_MAIL_STR_198); + if (p1 != std::string::npos) + { + p2 = lineBuf.find(ESP32_MAIL_STR_192); + if (p2 != std::string::npos) + { + string _tmp; + + _tmp = lineBuf.substr(p1 + 1, p2 - p1 - 1).c_str(); + msgNumBuf.clear(); + + for (size_t i = 0; i < _tmp.length(); i++) + { + if (_tmp[i] != '\\' && _tmp[i] != ' ' && _tmp[i] != '\r' && _tmp[i] != '\n') + msgNumBuf.append(1, _tmp[i]); + + if (_tmp[i] == ' ') + { + imapData._flag.push_back(msgNumBuf); + msgNumBuf.clear(); + } + } + if (msgNumBuf.length() > 0) + { + imapData._flag.push_back(msgNumBuf); + } + + std::string().swap(_tmp); + } + } + } + + p2 = lineBuf.find(ESP32_MAIL_STR_199); + if (p2 != std::string::npos) + imapData._totalMessage = atoi(lineBuf.substr(2, p2 - 2).c_str()); + + p1 = lineBuf.find(ESP32_MAIL_STR_200); + if (p1 != std::string::npos) + { + p2 = lineBuf.find(ESP32_MAIL_STR_156, p1 + 10); + if (p2 != std::string::npos) + imapData._nextUID = lineBuf.substr(p1 + 10, p2 - p1 - 10); + } + } + + if (validResponse && imapCommandType == IMAP_COMMAND_TYPE::FETCH_BODY_TEXT && lfCount > 0 && (charCount < maxChar || imapData._saveHTMLMsg || imapData._saveTextMsg)) + { + + if (imapData._messageDataInfo[mailIndex][messageDataIndex]._transfer_encoding == ESP32_MAIL_STR_160) + { + + unsigned char *decoded = base64_decode_char((const unsigned char *)lineBuf.c_str(), lineBuf.length(), &outputLength); + + if (decoded) + { + if (charCount < maxChar) + imapData._messageDataInfo[mailIndex][messageDataIndex]._text.append((char *)decoded, outputLength); + + if (imapData._saveHTMLMsg || imapData._saveTextMsg) + { + + if (!imapData._messageDataInfo[mailIndex][messageDataIndex]._sdFileOpenWrite) + { + + imapData._messageDataInfo[mailIndex][messageDataIndex]._sdFileOpenWrite = true; + + if (_sdOk) + { + + downloadReq = true; + + filepath.clear(); + filepath += imapData._savePath; + filepath += ESP32_MAIL_STR_202; + + char *midx = new char[50]; + memset(midx, 0, 50); + itoa(imapData._msgNum[mailIndex], midx, 10); + + filepath += midx; + + delete[] midx; + + if (imapData._storageType == MailClientStorageType::SD) + if (!SD.exists(filepath.c_str())) + createDirs(filepath); + + if (!imapData._headerSaved) + hpath = filepath + ESP32_MAIL_STR_203; + + if (imapData._messageDataInfo[mailIndex][messageDataIndex]._contentType == ESP32_MAIL_STR_155) + { + if (imapData._saveDecodedText) + filepath += ESP32_MAIL_STR_161; + else + filepath += ESP32_MAIL_STR_162; + } + else if (imapData._messageDataInfo[mailIndex][messageDataIndex]._contentType == ESP32_MAIL_STR_154) + { + if (imapData._saveDecodedHTML) + filepath += ESP32_MAIL_STR_163; + else + filepath += ESP32_MAIL_STR_164; + } + + if (imapData._storageType == MailClientStorageType::SD) + file = SD.open(filepath.c_str(), FILE_WRITE); + else if (imapData._storageType == MailClientStorageType::SPIFFS) + file = SPIFFS.open(filepath.c_str(), FILE_WRITE); + } + else + { + if (imapData._messageDataCount[mailIndex] == messageDataIndex + 1) + { + imapData._messageDataInfo[mailIndex][messageDataIndex]._error = true; + imapData._messageDataInfo[mailIndex][messageDataIndex]._downloadError.clear(); + imapData._messageDataInfo[mailIndex][messageDataIndex]._downloadError = ESP32_MAIL_STR_89; + } + } + } + + if (_sdOk) + { + if ((imapData._messageDataInfo[mailIndex][messageDataIndex]._contentType == ESP32_MAIL_STR_155 && imapData._saveDecodedText) || + (imapData._messageDataInfo[mailIndex][messageDataIndex]._contentType == ESP32_MAIL_STR_154 && imapData._saveDecodedHTML)) + file.write((const uint8_t *)decoded, outputLength); + else + file.write((const uint8_t *)lineBuf.c_str(), lineBuf.length()); + } + } + + delete[] decoded; + } + } + } + + if (validResponse && imapCommandType == IMAP_COMMAND_TYPE::FETCH_BODY_ATTACHMENT && lfCount > 0) + { + + if (imapData._messageDataInfo[mailIndex][messageDataIndex]._transfer_encoding == ESP32_MAIL_STR_160) + { + + if (!imapData._messageDataInfo[mailIndex][messageDataIndex]._sdFileOpenWrite) + { + + imapData._messageDataInfo[mailIndex][messageDataIndex]._sdFileOpenWrite = true; + + if (_sdOk) + { + + downloadReq = true; + + filepath.clear(); + filepath += imapData._savePath; + filepath += ESP32_MAIL_STR_202; + + char *midx = new char[50]; + memset(midx, 0, 50); + itoa(imapData._msgNum[mailIndex], midx, 10); + + filepath += midx; + + delete[] midx; + + if (imapData._storageType == MailClientStorageType::SD) + if (!SD.exists(filepath.c_str())) + createDirs(filepath); + + filepath += ESP32_MAIL_STR_202; + + filepath += imapData._messageDataInfo[mailIndex][messageDataIndex]._filename; + + if (imapData._storageType == MailClientStorageType::SD) + file = SD.open(filepath.c_str(), FILE_WRITE); + else if (imapData._storageType == MailClientStorageType::SPIFFS) + file = SPIFFS.open(filepath.c_str(), FILE_WRITE); + } + else + { + if (imapData._messageDataCount[mailIndex] == messageDataIndex + 1) + { + imapData._messageDataInfo[mailIndex][messageDataIndex]._error = true; + imapData._messageDataInfo[mailIndex][messageDataIndex]._downloadError.clear(); + imapData._messageDataInfo[mailIndex][messageDataIndex]._downloadError = ESP32_MAIL_STR_89; + } + } + } + + if (_sdOk) + { + + unsigned char *decoded = base64_decode_char((const unsigned char *)lineBuf.c_str(), lineBuf.length(), &outputLength); + + downloadedByte += outputLength; + + if (downloadedByte > imapData._messageDataInfo[mailIndex][messageDataIndex]._size) + continue; + + if (decoded) + { + file.write((const uint8_t *)decoded, outputLength); + + if (imapData._storageType == MailClientStorageType::SPIFFS) + delayMicroseconds(1); + else + yield(); + + if (imapData._downloadReport) + { + imapData._downloadedByte[mailIndex] += outputLength; + currentDownloadByte += outputLength; + + if (imapData._messageDataInfo[mailIndex][messageDataIndex]._size == 0) + { + if (payloadLength > 36) + { + imapData._messageDataInfo[mailIndex][messageDataIndex]._size = base64DecodeSize(lineBuf, payloadLength - (payloadLength / 36)); + imapData._totalAttachFileSize[mailIndex] += imapData._messageDataInfo[mailIndex][messageDataIndex]._size; + } + } + + int p = 0; + + if (imapData._totalAttachFileSize[mailIndex] > 0) + p = 100 * imapData._downloadedByte[mailIndex] / imapData._totalAttachFileSize[mailIndex]; + + if ((p % 5 == 0) && (p <= 100)) + { + + if (imapData._readCallback && reportState != -1) + { + memset(buf, 0, bufSize); + itoa(p, buf, 10); + + std::string dl = ESP32_MAIL_STR_90 + imapData._messageDataInfo[mailIndex][messageDataIndex]._filename + ESP32_MAIL_STR_91 + buf + ESP32_MAIL_STR_92; + + if (imapData._readCallback) + { + imapData._cbData._info = dl; + imapData._cbData._status = dl; + imapData._cbData._success = false; + imapData._readCallback(imapData._cbData); + } + + std::string().swap(dl); + } + reportState = -1; + } + else + reportState = 0; + } + + delete[] decoded; + } + + if (millis() - dataTime > imapData._net->tcpTimeout + 1000 * 60 * 5) + break; + } + } + } + + if (lfCount == 0) + { + p1 = lineBuf.find_last_of(ESP32_MAIL_STR_193); + if (p1 != std::string::npos) + { + p2 = lineBuf.find(ESP32_MAIL_STR_194, p1 + 1); + if (p2 != std::string::npos) + payloadLength = atoi(lineBuf.substr(p1 + 1, p2 - p1 - 1).c_str()); + } + } + + lineBuf.clear(); + lfCount++; + std::string().swap(tmp); + } + + readCount++; + } + + if (imapData._error.size() > 0 && mailIndex > -1) + { + if (validResponse && !imapData._error[mailIndex]) + { + imapData._errorMsg[mailIndex].clear(); + imapData._errorMsg[mailIndex] = ""; + } + } + + if (millis() - dataTime > imapData._net->tcpTimeout) + { + + if (downloadReq) + { + if (imapData._messageDataCount[mailIndex] == messageDataIndex + 1) + { + imapData._messageDataInfo[mailIndex][messageDataIndex]._error = true; + imapData._messageDataInfo[mailIndex][messageDataIndex]._downloadError.clear(); + imapData._messageDataInfo[mailIndex][messageDataIndex]._downloadError = ESP32_MAIL_STR_93; + } + } + else + { + + if (imapData._error.size() > 0 && mailIndex > -1) + { + imapData._error[mailIndex] = true; + imapData._errorMsg[mailIndex].clear(); + imapData._errorMsg[mailIndex] = ESP32_MAIL_STR_95; + } + } + } + } + + if (validResponse && (imapCommandType == IMAP_COMMAND_TYPE::FETCH_BODY_ATTACHMENT || imapCommandType == IMAP_COMMAND_TYPE::FETCH_BODY_TEXT) && messageDataIndex != -1) + { + if (imapData._messageDataInfo[mailIndex][messageDataIndex]._sdFileOpenWrite) + file.close(); + } + + if (validResponse && imapCommandType == IMAP_COMMAND_TYPE::FETCH_BODY_ATTACHMENT && imapData._messageDataInfo[mailIndex][messageDataIndex]._size != currentDownloadByte) + { + imapData._messageDataInfo[mailIndex][messageDataIndex]._size = currentDownloadByte; + } + + if (hpath != "") + { + + if (imapData._storageType == MailClientStorageType::SD) + file = SD.open(hpath.c_str(), FILE_WRITE); + else if (imapData._storageType == MailClientStorageType::SPIFFS) + file = SPIFFS.open(hpath.c_str(), FILE_WRITE); + + file.print(ESP32_MAIL_STR_99); + file.println(imapData._date[mailIndex].c_str()); + + file.print(ESP32_MAIL_STR_100); + if (imapData._uidSearch) + file.println(imapData._msgNum[mailIndex]); + else + file.println(); + + file.print(ESP32_MAIL_STR_101); + file.println(imapData._msgNum[mailIndex]); + + file.print(ESP32_MAIL_STR_102); + file.println(imapData._acceptLanguage[mailIndex].c_str()); + + file.print(ESP32_MAIL_STR_103); + file.println(imapData._contentLanguage[mailIndex].c_str()); + + file.print(ESP32_MAIL_STR_104); + file.println(imapData._from[mailIndex].c_str()); + + file.print(ESP32_MAIL_STR_105); + file.println(imapData._from_charset[mailIndex].c_str()); + + file.print(ESP32_MAIL_STR_106); + file.println(imapData._to[mailIndex].c_str()); + + file.print(ESP32_MAIL_STR_107); + file.println(imapData._to_charset[mailIndex].c_str()); + + file.print(ESP32_MAIL_STR_108); + file.println(imapData._cc[mailIndex].c_str()); + + file.print(ESP32_MAIL_STR_109); + file.println(imapData._cc_charset[mailIndex].c_str()); + + file.print(ESP32_MAIL_STR_110); + file.println(imapData._subject[mailIndex].c_str()); + + file.print(ESP32_MAIL_STR_111); + file.println(imapData._subject_charset[mailIndex].c_str()); + + file.print(ESP32_MAIL_STR_112); + file.println(imapData._messageDataInfo[mailIndex][messageDataIndex]._charset.c_str()); + + if (imapData._attachmentCount[mailIndex] > 0) + { + + file.print(ESP32_MAIL_STR_113); + file.println(imapData._attachmentCount[mailIndex]); + + for (int j = 0; j < imapData._attachmentCount[mailIndex]; j++) + { + file.print(ESP32_MAIL_STR_114); + file.println(j + 1); + + file.print(ESP32_MAIL_STR_115); + file.println(imapData.getAttachmentFileName(mailIndex, j)); + + file.print(ESP32_MAIL_STR_116); + file.println(imapData.getAttachmentName(mailIndex, j)); + + file.print(ESP32_MAIL_STR_117); + file.println(imapData.getAttachmentFileSize(mailIndex, j)); + + file.print(ESP32_MAIL_STR_118); + file.println(imapData.getAttachmentType(mailIndex, j)); + + file.print(ESP32_MAIL_STR_119); + file.println(imapData.getAttachmentCreationDate(mailIndex, j)); + } + } + + file.close(); + imapData._headerSaved = true; + } + + if (imapCommandType == IMAP_COMMAND_TYPE::FETCH_BODY_HEADER) + { + if (from != "") + { + imapData._msgID[mailIndex] = msgID; + imapData._from[mailIndex] = from; + imapData._to[mailIndex] = to; + imapData._cc[mailIndex] = cc; + imapData._subject[mailIndex] = subject; + imapData._date[mailIndex] = date; + imapData._from_charset[mailIndex] = from_charset; + imapData._to_charset[mailIndex] = to_charset; + imapData._cc_charset[mailIndex] = cc_charset; + imapData._subject_charset[mailIndex] = subject_charset; + imapData._contentLanguage[mailIndex] = contentLanguage; + imapData._acceptLanguage[mailIndex] = acceptLanguage; + } + } + + delete[] buf; + delete[] dest; + + std::string().swap(lineBuf); + std::string().swap(msgNumBuf); + std::string().swap(filepath); + std::string().swap(hpath); + std::string().swap(tmp); + + std::string().swap(msgID); + std::string().swap(from); + std::string().swap(to); + std::string().swap(subject); + std::string().swap(date); + std::string().swap(cc); + std::string().swap(from_charset); + std::string().swap(to_charset); + std::string().swap(cc_charset); + std::string().swap(subject_charset); + std::string().swap(contentLanguage); + std::string().swap(acceptLanguage); + + return validResponse; +} + +void ESP32_MailClient::clientReadAll(WiFiClient *client) +{ + if (client) + { + if (client->available() > 0) + client->read(); + } +} + +double ESP32_MailClient::base64DecodeSize(std::string lastBase64String, int length) +{ + double result = 0; + int padding = 0; + if (lastBase64String != "") + { + + if (lastBase64String[lastBase64String.length() - 1] == '=' && lastBase64String[lastBase64String.length() - 2] == '=') + padding = 2; + else if (lastBase64String[lastBase64String.length() - 1] == '=') + padding = 1; + } + result = (ceil(length / 4) * 3) - padding; + return result; +} + +unsigned char *ESP32_MailClient::base64_decode_char(const unsigned char *src, size_t len, size_t *out_len) +{ + + unsigned char *out, *pos, block[4], tmp; + size_t i, count, olen; + int pad = 0; + size_t extra_pad; + + unsigned char *dtable = new unsigned char[256]; + + memset(dtable, 0x80, 256); + + for (i = 0; i < sizeof(base64_table) - 1; i++) + dtable[base64_table[i]] = (unsigned char)i; + dtable['='] = 0; + + count = 0; + for (i = 0; i < len; i++) + { + if (dtable[src[i]] != 0x80) + count++; + } + + if (count == 0) + goto exit; + extra_pad = (4 - count % 4) % 4; + + olen = (count + extra_pad) / 4 * 3; + pos = out = (unsigned char *)malloc(olen); + if (out == NULL) + goto exit; + + count = 0; + for (i = 0; i < len + extra_pad; i++) + { + unsigned char val; + + if (i >= len) + val = '='; + else + val = src[i]; + tmp = dtable[val]; + if (tmp == 0x80) + continue; + + if (val == '=') + pad++; + block[count] = tmp; + count++; + if (count == 4) + { + *pos++ = (block[0] << 2) | (block[1] >> 4); + *pos++ = (block[1] << 4) | (block[2] >> 2); + *pos++ = (block[2] << 6) | block[3]; + count = 0; + if (pad) + { + if (pad == 1) + pos--; + else if (pad == 2) + pos -= 2; + else + { + free(out); + goto exit; + } + break; + } + } + } + + *out_len = pos - out; + delete[] dtable; + return out; + +exit: + delete[] dtable; + return NULL; +} + +std::string ESP32_MailClient::base64_encode_string(const unsigned char *src, size_t len) +{ + unsigned char *out, *pos; + const unsigned char *end, *in; + + size_t olen; + + olen = 4 * ((len + 2) / 3); + + if (olen < len) + return std::string(); + + std::string outStr = ""; + outStr.resize(olen); + out = (unsigned char *)&outStr[0]; + + end = src + len; + in = src; + pos = out; + + while (end - in >= 3) + { + *pos++ = base64_table[in[0] >> 2]; + *pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)]; + *pos++ = base64_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)]; + *pos++ = base64_table[in[2] & 0x3f]; + in += 3; + } + + if (end - in) + { + *pos++ = base64_table[in[0] >> 2]; + if (end - in == 1) + { + *pos++ = base64_table[(in[0] & 0x03) << 4]; + *pos++ = '='; + } + else + { + *pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)]; + *pos++ = base64_table[(in[1] & 0x0f) << 2]; + } + *pos++ = '='; + } + + return outStr; +} + +void ESP32_MailClient::send_base64_encode_mime_data(WiFiClient *client, const unsigned char *src, size_t len) +{ + + const unsigned char *end, *in; + + size_t olen; + + olen = 4 * ((len + 2) / 3); + + if (olen < len) + return; + + end = src + len; + in = src; + + size_t chunkSize = 936; + size_t byteAdd = 0; + size_t byteSent = 0; + + int dByte = 0; + unsigned char *buf = new unsigned char[chunkSize]; + memset(buf, 0, chunkSize); + + while (end - in >= 3) + { + buf[byteAdd++] = base64_table[in[0] >> 2]; + buf[byteAdd++] = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)]; + buf[byteAdd++] = base64_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)]; + buf[byteAdd++] = base64_table[in[2] & 0x3f]; + dByte += 4; + if (dByte == 76) + { + if(byteAdd + 1 < chunkSize) + { + buf[byteAdd++] = 0x0d; + buf[byteAdd++] = 0x0a; + } + dByte = 0; + } + if (byteAdd >= chunkSize - 4) + { + byteSent += byteAdd; + client->write(buf, byteAdd); + memset(buf, 0, chunkSize); + byteAdd = 0; + } + in += 3; + } + + if (byteAdd > 0) + client->write(buf, byteAdd); + + if (end - in) + { + memset(buf, 0, chunkSize); + byteAdd = 0; + + buf[byteAdd++] = base64_table[in[0] >> 2]; + if (end - in == 1) + { + buf[byteAdd++] = base64_table[(in[0] & 0x03) << 4]; + buf[byteAdd++] = '='; + } + else + { + buf[byteAdd++] = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)]; + buf[byteAdd++] = base64_table[(in[1] & 0x0f) << 2]; + } + buf[byteAdd++] = '='; + + client->write(buf, byteAdd); + memset(buf, 0, chunkSize); + } + delete[] buf; +} + +void ESP32_MailClient::send_base64_encode_mime_file(WiFiClient *client, File file) +{ + + if (!file) + return; + + size_t chunkSize = 936; + size_t byteAdd = 0; + size_t byteSent = 0; + + unsigned char *buf = new unsigned char[chunkSize]; + memset(buf, 0, chunkSize); + + size_t len = file.size(); + size_t fbufIndex = 0; + unsigned char *fbuf = new unsigned char[3]; + + int dByte = 0; + + while (file.available()) + { + memset(fbuf, 0, 3); + if (len - fbufIndex >= 3) + { + file.read(fbuf, 3); + buf[byteAdd++] = base64_table[fbuf[0] >> 2]; + buf[byteAdd++] = base64_table[((fbuf[0] & 0x03) << 4) | (fbuf[1] >> 4)]; + buf[byteAdd++] = base64_table[((fbuf[1] & 0x0f) << 2) | (fbuf[2] >> 6)]; + buf[byteAdd++] = base64_table[fbuf[2] & 0x3f]; + dByte += 4; + if (dByte == 76) + { + if(byteAdd + 1 < chunkSize) + { + buf[byteAdd++] = 0x0d; + buf[byteAdd++] = 0x0a; + } + dByte = 0; + } + if (byteAdd >= chunkSize - 4) + { + byteSent += byteAdd; + client->write(buf, byteAdd); + memset(buf, 0, chunkSize); + byteAdd = 0; + } + fbufIndex += 3; + } + else + { + if (len - fbufIndex == 1) + { + fbuf[0] = file.read(); + } + else if (len - fbufIndex == 2) + { + fbuf[0] = file.read(); + fbuf[1] = file.read(); + } + break; + } + } + + file.close(); + if (byteAdd > 0) + client->write(buf, byteAdd); + + if (len - fbufIndex > 0) + { + memset(buf, 0, chunkSize); + byteAdd = 0; + buf[byteAdd++] = base64_table[fbuf[0] >> 2]; + if (len - fbufIndex == 1) + { + buf[byteAdd++] = base64_table[(fbuf[0] & 0x03) << 4]; + buf[byteAdd++] = '='; + } + else + { + buf[byteAdd++] = base64_table[((fbuf[0] & 0x03) << 4) | (fbuf[1] >> 4)]; + buf[byteAdd++] = base64_table[(fbuf[1] & 0x0f) << 2]; + } + buf[byteAdd++] = '='; + client->write(buf, byteAdd); + } + delete[] buf; + delete[] fbuf; +} + +IMAPData::IMAPData() {} +IMAPData::~IMAPData() +{ + empty(); + _net.reset(); + _net.release(); +} + +void IMAPData::setLogin(const String &host, uint16_t port, const String &loginEmail, const String &loginPassword, const char *rootCA) +{ + + _host.clear(); + _port = port; + _loginEmail.clear(); + _loginPassword.clear(); + + _host = host.c_str(); + _loginEmail = loginEmail.c_str(); + _loginPassword = loginPassword.c_str(); + + _rootCA.clear(); + if (strlen(rootCA) > 0) + _rootCA.push_back((char *)rootCA); +} + +void IMAPData::setLogin(const String &host, uint16_t port, const String &loginEmail, const String &loginPassword) +{ + _host.clear(); + _port = port; + _loginEmail.clear(); + _loginPassword.clear(); + + _host = host.c_str(); + _loginEmail = loginEmail.c_str(); + _loginPassword = loginPassword.c_str(); +} + +void IMAPData::setSTARTTLS(bool starttls) +{ + _starttls = starttls; +} + +void IMAPData::setDebug(bool debug) +{ + _debug = debug; +} + +void IMAPData::setFolder(const String &folderName) +{ + _currentFolder.clear(); + _currentFolder = folderName.c_str(); +} +void IMAPData::setMessageBufferSize(size_t size) +{ + _message_buffer_size = size; +} + +void IMAPData::setAttachmentSizeLimit(size_t size) +{ + _attacement_max_size = size; +} + +void IMAPData::setSearchCriteria(const String &criteria) +{ + _searchCriteria.clear(); + _searchCriteria = criteria.c_str(); +} + +void IMAPData::setSearchUnseenMessage(bool unseenSearch) +{ + _unseen = unseenSearch; +} + +void IMAPData::setSaveFilePath(const String &path) +{ + _savePath.clear(); + if (path.c_str()[0] != '/') + { + _savePath = "/"; + _savePath += path.c_str(); + } + else + _savePath = path.c_str(); +} + +void IMAPData::setFetchUID(const String &fetchUID) +{ + _fetchUID.clear(); + string tmp = fetchUID.c_str(); + std::transform(tmp.begin(), tmp.end(), tmp.begin(), ::toupper); + if (tmp.find(ESP32_MAIL_STR_140) != std::string::npos || tmp.find(ESP32_MAIL_STR_212) != std::string::npos || + tmp.find(ESP32_MAIL_STR_213) != std::string::npos || tmp.find(ESP32_MAIL_STR_214) != std::string::npos || tmp.find(ESP32_MAIL_STR_215) != std::string::npos || + tmp.find(ESP32_MAIL_STR_216) != std::string::npos || tmp.find(ESP32_MAIL_STR_217) != std::string::npos || tmp.find(ESP32_MAIL_STR_218) != std::string::npos || + tmp.find(ESP32_MAIL_STR_219) != std::string::npos || tmp.find(ESP32_MAIL_STR_220) != std::string::npos) + _fetchUID = ESP32_MAIL_STR_183; + else + _fetchUID = fetchUID.c_str(); + + std::string().swap(tmp); +} + +void IMAPData::setFileStorageType(uint8_t storageType) +{ + _storageType = storageType; +} + +void IMAPData::setDownloadAttachment(bool download) +{ + _downloadAttachment = download; +} +void IMAPData::setRecentSort(bool recentSort) +{ + _recentSort = recentSort; +} + +void IMAPData::setHTMLMessage(bool htmlFormat) +{ + _htmlFormat = htmlFormat; +} +void IMAPData::setTextMessage(bool textFormat) +{ + _textFormat = textFormat; +} + +void IMAPData::setSearchLimit(uint16_t limit) +{ + if (limit <= MAX_EMAIL_SEARCH_LIMIT) + _emailNumMax = limit; +} + +bool IMAPData::isHeaderOnly() +{ + return _headerOnly; +} + +void IMAPData::saveHTMLMessage(bool download, bool decoded) +{ + _saveDecodedHTML = decoded; + _saveHTMLMsg = download; +} +void IMAPData::saveTextMessage(bool download, bool decoded) +{ + _saveDecodedText = decoded; + _saveTextMsg = download; +} + +void IMAPData::setReadCallback(readStatusCallback readCallback) +{ + _readCallback = std::move(readCallback); +} + +void IMAPData::setDownloadReport(bool report) +{ + _downloadReport = report; +} + +uint16_t IMAPData::getFolderCount() +{ + return _folders.size(); +} +String IMAPData::getFolder(uint16_t folderIndex) +{ + if (folderIndex < _folders.size()) + return _folders[folderIndex].c_str(); + return std::string().c_str(); +} + +uint16_t IMAPData::getFlagCount() +{ + return _flag.size(); +} +String IMAPData::getFlag(uint16_t flagIndex) +{ + if (flagIndex < _flag.size()) + return _flag[flagIndex].c_str(); + return std::string().c_str(); +} + +size_t IMAPData::totalMessages() +{ + return _totalMessage; +} + +size_t IMAPData::searchCount() +{ + return _searchCount; +} + +size_t IMAPData::availableMessages() +{ + return _msgNum.size(); +} + +size_t IMAPData::getAttachmentCount(uint16_t messageIndex) +{ + if (messageIndex < _msgNum.size()) + return _attachmentCount[messageIndex]; + return 0; +} + +String IMAPData::getAttachmentFileName(size_t messageIndex, size_t attachmentIndex) +{ + if (messageIndex < _msgNum.size()) + { + int s = _messageDataInfo[messageIndex].size(); + int id = 0; + if (s > 0) + { + for (int i = 0; i < s; i++) + { + if (_messageDataInfo[messageIndex][i]._disposition == ESP32_MAIL_STR_153) + { + if (attachmentIndex == id) + return _messageDataInfo[messageIndex][i]._filename.c_str(); + id++; + } + } + } + else + return std::string().c_str(); + } + else + return std::string().c_str(); + + return std::string().c_str(); +} + +String IMAPData::getAttachmentName(size_t messageIndex, size_t attachmentIndex) +{ + if (messageIndex < _msgNum.size()) + { + int s = _messageDataInfo[messageIndex].size(); + int id = 0; + if (s > 0) + { + for (int i = 0; i < s; i++) + { + if (_messageDataInfo[messageIndex][i]._disposition == ESP32_MAIL_STR_153) + { + if (attachmentIndex == id) + return _messageDataInfo[messageIndex][i]._name.c_str(); + id++; + } + } + } + else + return std::string().c_str(); + } + else + return std::string().c_str(); + + return std::string().c_str(); +} + +int IMAPData::getAttachmentFileSize(size_t messageIndex, size_t attachmentIndex) +{ + if (messageIndex < _msgNum.size()) + { + int s = _messageDataInfo[messageIndex].size(); + int id = 0; + if (s > 0) + { + for (int i = 0; i < s; i++) + { + if (_messageDataInfo[messageIndex][i]._disposition == ESP32_MAIL_STR_153) + { + if (attachmentIndex == id) + return _messageDataInfo[messageIndex][i]._size; + id++; + } + } + } + else + return 0; + } + else + return 0; + + return 0; +} + +String IMAPData::getAttachmentCreationDate(size_t messageIndex, size_t attachmentIndex) +{ + if (messageIndex < _msgNum.size()) + { + int s = _messageDataInfo[messageIndex].size(); + int id = 0; + if (s > 0) + { + for (int i = 0; i < s; i++) + { + if (_messageDataInfo[messageIndex][i]._disposition == ESP32_MAIL_STR_153) + { + if (attachmentIndex == id) + return _messageDataInfo[messageIndex][i]._creation_date.c_str(); + id++; + } + } + } + else + return std::string().c_str(); + } + else + return std::string().c_str(); + + return std::string().c_str(); +} + +String IMAPData::getAttachmentType(size_t messageIndex, size_t attachmentIndex) +{ + if (messageIndex < _msgNum.size()) + { + int s = _messageDataInfo[messageIndex].size(); + int id = 0; + if (s > 0) + { + for (int i = 0; i < s; i++) + { + if (_messageDataInfo[messageIndex][i]._disposition == ESP32_MAIL_STR_153) + { + if (attachmentIndex == id) + return _messageDataInfo[messageIndex][i]._contentType.c_str(); + id++; + } + } + } + else + return std::string().c_str(); + } + else + return std::string().c_str(); + + return std::string().c_str(); +} + +String IMAPData::getFrom(uint16_t messageIndex) +{ + if (messageIndex < _msgNum.size()) + return _from[messageIndex].c_str(); + return std::string().c_str(); +} + +String IMAPData::getFromCharset(uint16_t messageIndex) +{ + if (messageIndex < _msgNum.size()) + return _from_charset[messageIndex].c_str(); + return std::string().c_str(); +} +String IMAPData::getTo(uint16_t messageIndex) +{ + if (messageIndex < _msgNum.size()) + return _to[messageIndex].c_str(); + return std::string().c_str(); +} +String IMAPData::getToCharset(uint16_t messageIndex) +{ + if (messageIndex < _msgNum.size()) + return _to_charset[messageIndex].c_str(); + return std::string().c_str(); +} +String IMAPData::getCC(uint16_t messageIndex) +{ + if (messageIndex < _msgNum.size()) + return _cc[messageIndex].c_str(); + return std::string().c_str(); +} +String IMAPData::getCCCharset(uint16_t messageIndex) +{ + if (messageIndex < _msgNum.size()) + return _cc_charset[messageIndex].c_str(); + return std::string().c_str(); +} + +String IMAPData::getSubject(uint16_t messageIndex) +{ + if (messageIndex < _msgNum.size()) + return _subject[messageIndex].c_str(); + return std::string().c_str(); +} +String IMAPData::getSubjectCharset(uint16_t messageIndex) +{ + if (messageIndex < _msgNum.size()) + return _subject_charset[messageIndex].c_str(); + return std::string().c_str(); +} +String IMAPData::getHTMLMessage(uint16_t messageIndex) +{ + if (messageIndex < _msgNum.size()) + return getMessage(messageIndex, true); + return std::string().c_str(); +} + +String IMAPData::getTextMessage(uint16_t messageIndex) +{ + if (messageIndex < _msgNum.size()) + return getMessage(messageIndex, false); + return std::string().c_str(); +} + +String IMAPData::getMessage(uint16_t messageIndex, bool htmlFormat) +{ + if (messageIndex < _msgNum.size()) + { + int s = _messageDataInfo[messageIndex].size(); + + if (s > 0) + { + for (int i = 0; i < s; i++) + { + if (_messageDataInfo[messageIndex][i]._contentType == ESP32_MAIL_STR_155 && !htmlFormat) + return _messageDataInfo[messageIndex][i]._text.c_str(); + else if (_messageDataInfo[messageIndex][i]._contentType == ESP32_MAIL_STR_154 && htmlFormat) + return _messageDataInfo[messageIndex][i]._text.c_str(); + } + return std::string().c_str(); + } + else + return std::string().c_str(); + } + else + return std::string().c_str(); + + return std::string().c_str(); +} + +String IMAPData::getHTMLMessgaeCharset(uint16_t messageIndex) +{ + if (messageIndex < _msgNum.size()) + { + int s = _messageDataInfo[messageIndex].size(); + + if (s > 0) + { + for (int i = 0; i < s; i++) + { + if (_messageDataInfo[messageIndex][i]._contentType == ESP32_MAIL_STR_154) + return _messageDataInfo[messageIndex][i]._charset.c_str(); + } + return std::string().c_str(); + } + else + return std::string().c_str(); + } + else + return std::string().c_str(); + + return std::string().c_str(); +} + +String IMAPData::getTextMessgaeCharset(uint16_t messageIndex) +{ + if (messageIndex < _msgNum.size()) + { + int s = _messageDataInfo[messageIndex].size(); + + if (s > 0) + { + for (int i = 0; i < s; i++) + { + if (_messageDataInfo[messageIndex][i]._contentType == ESP32_MAIL_STR_155) + return _messageDataInfo[messageIndex][i]._charset.c_str(); + } + return std::string().c_str(); + } + else + return std::string().c_str(); + } + else + return std::string().c_str(); + + return std::string().c_str(); +} + +String IMAPData::getDate(uint16_t messageIndex) +{ + if (messageIndex < _msgNum.size()) + return _date[messageIndex].c_str(); + return std::string().c_str(); +} + +String IMAPData::getUID(uint16_t messageIndex) +{ + char *buf = new char[50]; + memset(buf, 0, 50); + if (_uidSearch) + { + if (messageIndex < _msgNum.size()) + itoa(_msgNum[messageIndex], buf, 10); + } + + String v = buf; + delete[] buf; + return v; +} + +String IMAPData::getNumber(uint16_t messageIndex) +{ + char *buf = new char[50]; + memset(buf, 0, 50); + + if (messageIndex < _msgNum.size()) + { + if (!_uidSearch) + itoa(_msgNum[messageIndex], buf, 10); + else + itoa(_msgNum[messageIndex] + 1, buf, 10); + } + + String v = buf; + delete[] buf; + return v; +} + +String IMAPData::getMessageID(uint16_t messageIndex) +{ + if (messageIndex < _msgNum.size()) + return _msgID[messageIndex].c_str(); + return std::string().c_str(); +} + +String IMAPData::getAcceptLanguage(uint16_t messageIndex) +{ + if (messageIndex < _msgNum.size()) + return _acceptLanguage[messageIndex].c_str(); + return std::string().c_str(); +} +String IMAPData::getContentLanguage(uint16_t messageIndex) +{ + if (messageIndex < _msgNum.size()) + return _contentLanguage[messageIndex].c_str(); + return std::string().c_str(); +} + +bool IMAPData::isFetchMessageFailed(uint16_t messageIndex) +{ + if (messageIndex < _msgNum.size()) + return _error[messageIndex]; + return false; +} +String IMAPData::getFetchMessageFailedReason(uint16_t messageIndex) +{ + if (messageIndex < _msgNum.size()) + return _errorMsg[messageIndex].c_str(); + return std::string().c_str(); +} + +bool IMAPData::isDownloadAttachmentFailed(uint16_t messageIndex, size_t attachmentIndex) +{ + if (messageIndex < _msgNum.size()) + { + int s = _messageDataInfo[messageIndex].size(); + int id = 0; + if (s > 0) + { + for (int i = 0; i < s; i++) + { + if (_messageDataInfo[messageIndex][i]._disposition == ESP32_MAIL_STR_153) + { + if (attachmentIndex == id) + return _messageDataInfo[messageIndex][i]._error; + id++; + } + } + } + else + return false; + } + else + return false; + + return false; +} + +String IMAPData::getDownloadAttachmentFailedReason(uint16_t messageIndex, size_t attachmentIndex) +{ + if (messageIndex < _msgNum.size()) + { + int s = _messageDataInfo[messageIndex].size(); + int id = 0; + if (s > 0) + { + for (int i = 0; i < s; i++) + { + if (_messageDataInfo[messageIndex][i]._disposition == ESP32_MAIL_STR_153) + { + if (attachmentIndex == id) + return _messageDataInfo[messageIndex][i]._downloadError.c_str(); + id++; + } + } + } + else + return std::string().c_str(); + } + else + return std::string().c_str(); + return std::string().c_str(); +} + +bool IMAPData::isDownloadMessageFailed(uint16_t messageIndex) +{ + if (messageIndex < _msgNum.size()) + { + int s = _messageDataInfo[messageIndex].size(); + bool res = false; + if (s > 0) + { + for (int i = 0; i < s; i++) + { + if (_messageDataInfo[messageIndex][i]._disposition == "") + { + res |= _messageDataInfo[messageIndex][i]._error; + } + } + + return res; + } + else + return false; + } + else + return false; + + return false; +} +String IMAPData::getDownloadMessageFailedReason(uint16_t messageIndex) +{ + if (messageIndex < _msgNum.size()) + { + int s = _messageDataInfo[messageIndex].size(); + string res = ""; + if (s > 0) + { + for (int i = 0; i < s; i++) + { + if (_messageDataInfo[messageIndex][i]._disposition == "") + { + if (_messageDataInfo[messageIndex][i]._downloadError != "") + res = _messageDataInfo[messageIndex][i]._downloadError; + } + } + + return res.c_str(); + } + else + return std::string().c_str(); + } + else + return std::string().c_str(); + + return std::string().c_str(); +} + +void IMAPData::empty() +{ + std::string().swap(_host); + std::string().swap(_loginEmail); + std::string().swap(_loginPassword); + std::string().swap(_currentFolder); + std::string().swap(_nextUID); + std::string().swap(_searchCriteria); + std::vector().swap(_date); + std::vector().swap(_subject); + std::vector().swap(_subject_charset); + std::vector().swap(_from); + std::vector().swap(_from_charset); + std::vector().swap(_to); + std::vector().swap(_to_charset); + std::vector().swap(_cc); + std::vector().swap(_cc_charset); + std::vector().swap(_msgNum); + std::vector().swap(_folders); + std::vector().swap(_flag); + std::vector().swap(_msgID); + std::vector().swap(_acceptLanguage); + std::vector().swap(_contentLanguage); + std::vector().swap(_attachmentCount); + std::vector().swap(_totalAttachFileSize); + std::vector().swap(_downloadedByte); + std::vector().swap(_error); + std::vector>().swap(_messageDataInfo); + std::vector().swap(_errorMsg); +} + +void IMAPData::clearMessageData() +{ + std::vector().swap(_date); + std::vector().swap(_subject); + std::vector().swap(_subject_charset); + std::vector().swap(_from); + std::vector().swap(_from_charset); + std::vector().swap(_to); + std::vector().swap(_to_charset); + std::vector().swap(_cc); + std::vector().swap(_cc_charset); + std::vector().swap(_msgNum); + std::vector().swap(_msgID); + std::vector().swap(_contentLanguage); + std::vector().swap(_acceptLanguage); + std::vector().swap(_folders); + std::vector().swap(_flag); + std::vector().swap(_attachmentCount); + std::vector>().swap(_messageDataInfo); + std::vector().swap(_totalAttachFileSize); + std::vector().swap(_downloadedByte); + std::vector().swap(_messageDataCount); + std::vector().swap(_errorMsg); + std::vector().swap(_error); + _searchCount = 0; +} + +messageBodyData::messageBodyData() +{ +} +messageBodyData::~messageBodyData() +{ + empty(); +} + +void messageBodyData::empty() +{ + std::string().swap(_text); + std::string().swap(_filename); + std::string().swap(_savePath); + std::string().swap(_name); + std::string().swap(_disposition); + std::string().swap(_contentType); + std::string().swap(_descr); + std::string().swap(_transfer_encoding); + std::string().swap(_creation_date); + std::string().swap(_modification_date); + std::string().swap(_charset); + std::string().swap(_part); + std::string().swap(_downloadError); +} + +attachmentData::attachmentData() {} +attachmentData::~attachmentData() +{ + + std::vector>().swap(_buf); + std::vector().swap(_filename); + std::vector().swap(_id); + std::vector().swap(_type); + std::vector().swap(_size); + std::vector().swap(_mime_type); +} + +void attachmentData::add(const String &fileName, const String &mimeType, uint8_t *data, size_t size) +{ + _filename.push_back(fileName.c_str()); + _mime_type.push_back(mimeType.c_str()); + + if (size > 0) + { + std::vector d = std::vector(); + d.push_back(data); + _buf.push_back(d); + _size.push_back(size); + _type.push_back(0); + } + else + { + _buf.push_back(std::vector()); + _size.push_back(0); + _type.push_back(1); + } + + _id.push_back(_index); + _index++; +} + +void attachmentData::remove(uint8_t index) +{ + _buf.erase(_buf.begin() + index); + _filename.erase(_filename.begin() + index); + _type.erase(_type.begin() + index); + _size.erase(_size.begin() + index); + _mime_type.erase(_mime_type.begin() + index); + _id.erase(_id.begin() + index); +} + +void attachmentData::free() +{ + std::vector>().swap(_buf); + std::vector().swap(_filename); + std::vector().swap(_id); + std::vector().swap(_type); + std::vector().swap(_size); + std::vector().swap(_mime_type); + _index = 0; +} + +String attachmentData::getFileName(uint8_t index) +{ + return _filename[index].c_str(); +} + +String attachmentData::getMimeType(uint8_t index) +{ + return _mime_type[index].c_str(); +} + +uint8_t *attachmentData::getData(uint8_t index) +{ + uint8_t *ptr = _buf[index].front(); + return ptr; +} + +uint16_t attachmentData::getSize(uint8_t index) +{ + return _size[index]; +} + +uint8_t attachmentData::getCount() +{ + return _index; +} + +uint8_t attachmentData::getType(uint8_t index) +{ + return _type[index]; +} + +SMTPData::SMTPData() {} + +SMTPData::~SMTPData() +{ + empty(); + _net.reset(); + _net.release(); +} + +void SMTPData::setLogin(const String &host, uint16_t port, const String &loginEmail, const String &loginPassword, const char *rootCA) +{ + + _host.clear(); + _port = port; + _loginEmail.clear(); + _loginPassword.clear(); + + _host = host.c_str(); + _loginEmail = loginEmail.c_str(); + _loginPassword = loginPassword.c_str(); + + _rootCA.clear(); + if (strlen(rootCA) > 0) + _rootCA.push_back((char *)rootCA); +} + +void SMTPData::setLogin(const String &host, uint16_t port, const String &loginEmail, const String &loginPassword) +{ + + _host.clear(); + _port = port; + _loginEmail.clear(); + _loginPassword.clear(); + + _host = host.c_str(); + _loginEmail = loginEmail.c_str(); + _loginPassword = loginPassword.c_str(); + + _rootCA.clear(); +} + +void SMTPData::setSTARTTLS(bool starttls) +{ + _starttls = starttls; +} + +void SMTPData::setDebug(bool debug) +{ + _debug = debug; +} + +void SMTPData::setSender(const String &fromName, const String &senderEmail) +{ + + _fromName.clear(); + _senderEmail.clear(); + + _fromName += fromName.c_str(); + _senderEmail += senderEmail.c_str(); +} + +String SMTPData::getFromName() +{ + return _fromName.c_str(); +} + +String SMTPData::getSenderEmail() +{ + return _senderEmail.c_str(); +} + +void SMTPData::setPriority(int priority) +{ + _priority = priority; +} +void SMTPData::setPriority(const String &priority) +{ + if (priority == ESP32_MAIL_STR_205 || priority == ESP32_MAIL_STR_206) + _priority = 1; + else if (priority == ESP32_MAIL_STR_207 || priority == ESP32_MAIL_STR_208) + _priority = 3; + else if (priority == ESP32_MAIL_STR_209 || priority == ESP32_MAIL_STR_210) + _priority = 5; +} + +uint8_t SMTPData::getPriority() +{ + return _priority; +} + +void SMTPData::addRecipient(const String &email) +{ + _recipient.insert(_recipient.end(), email.c_str()); +} + +void SMTPData::removeRecipient(const String &email) +{ + for (uint8_t i = 0; i < _recipient.size(); i++) + if (_recipient[i].c_str() == email.c_str()) + _recipient.erase(_recipient.begin() + i); +} + +void SMTPData::removeRecipient(uint8_t index) +{ + _recipient.erase(_recipient.begin() + index); +} + +void SMTPData::clearRecipient() +{ + std::vector().swap(_recipient); +} + +uint8_t SMTPData::recipientCount() +{ + return _recipient.size(); +} + +String SMTPData::getRecipient(uint8_t index) +{ + if (index >= _recipient.size()) + return std::string().c_str(); + return _recipient[index].c_str(); +} + +void SMTPData::setSubject(const String &subject) +{ + _subject = subject.c_str(); +} + +String SMTPData::getSubject() +{ + return _subject.c_str(); +} + +void SMTPData::setMessage(const String &message, bool htmlFormat) +{ + _message.clear(); + _message += message.c_str(); + _htmlFormat = htmlFormat; +} + +void SMTPData::clrMessage(bool htmlFormat) +{ + _message.clear(); + _htmlFormat = htmlFormat; +} + +void SMTPData::addMessage(const String &message) +{ + _message += message.c_str(); +} + +String SMTPData::getMessage() +{ + return _message.c_str(); +} + +bool SMTPData::htmlFormat() +{ + return _htmlFormat; +} +void SMTPData::addCC(const String &email) +{ + _cc.push_back(email.c_str()); +} + +void SMTPData::removeCC(const String &email) +{ + for (uint8_t i = 0; i < _cc.size(); i++) + if (_cc[i].c_str() == email.c_str()) + _cc.erase(_cc.begin() + i); +} + +void SMTPData::removeCC(uint8_t index) +{ + _cc.erase(_cc.begin() + index); +} +void SMTPData::clearCC() +{ + std::vector().swap(_cc); +} + +uint8_t SMTPData::ccCount() +{ + return _cc.size(); +} + +String SMTPData::getCC(uint8_t index) +{ + if (index >= _cc.size()) + return std::string().c_str(); + return _cc[index].c_str(); +} + +void SMTPData::addBCC(const String &email) +{ + _bcc.push_back(email.c_str()); +} + +void SMTPData::removeBCC(const String &email) +{ + for (uint8_t i = 0; i < _bcc.size(); i++) + if (_bcc[i].c_str() == email.c_str()) + _bcc.erase(_bcc.begin() + i); +} + +void SMTPData::removeBCC(uint8_t index) +{ + _bcc.erase(_bcc.begin() + index); +} + +void SMTPData::clearBCC() +{ + std::vector().swap(_bcc); +} + +uint8_t SMTPData::bccCount() +{ + return _bcc.size(); +} + +String SMTPData::getBCC(uint8_t index) +{ + if (index >= _bcc.size()) + return std::string().c_str(); + return _bcc[index].c_str(); +} + +void SMTPData::addAttachData(const String &fileName, const String &mimeType, uint8_t *data, size_t size) +{ + _attach.add(fileName, mimeType, data, size); +} + +void SMTPData::removeAttachData(const String &fileName) +{ + for (uint8_t i = 0; i < _attach.getCount(); i++) + if (_attach.getFileName(i) == fileName && _attach.getType(i) == 0) + { + _attach.remove(i); + } +} + +void SMTPData::removeAttachData(uint8_t index) +{ + uint8_t id = 0; + for (uint8_t i = 0; i < _attach.getCount(); i++) + if (_attach.getType(i) == 0) + { + if (id == index) + { + _attach.remove(i); + break; + } + id++; + } +} + +uint8_t SMTPData::attachDataCount() +{ + uint8_t count = 0; + for (uint8_t i = 0; i < _attach.getCount(); i++) + if (_attach.getType(i) == 0) + count++; + + return count; +} + +void SMTPData::addAttachFile(const String &filePath, const String &mimeType) +{ + _attach.add(filePath, mimeType, NULL, 0); +} + +void SMTPData::removeAttachFile(const String &filePath) +{ + for (uint8_t i = 0; i < _attach.getCount(); i++) + if (_attach.getFileName(i) == filePath && _attach.getType(i) == 1) + { + _attach.remove(i); + } +} + +void SMTPData::removeAttachFile(uint8_t index) +{ + uint8_t id = 0; + for (uint8_t i = 0; i < _attach.getCount(); i++) + if (_attach.getType(i) == 1) + { + if (id == index) + { + _attach.remove(i); + break; + } + id++; + } +} + +void SMTPData::setFileStorageType(uint8_t storageType) +{ + _storageType = storageType; +} + +void SMTPData::clearAttachData() +{ + for (uint8_t i = 0; i < _attach.getCount(); i++) + if (_attach.getType(i) == 0) + _attach.remove(i); +} + +void SMTPData::clearAttachFile() +{ + for (uint8_t i = 0; i < _attach.getCount(); i++) + if (_attach.getType(i) == 1) + _attach.remove(i); +} + +void SMTPData::clearAttachment() +{ + _attach.free(); +} + +uint8_t SMTPData::attachFileCount() +{ + uint8_t count = 0; + for (uint8_t i = 0; i < _attach.getCount(); i++) + if (_attach.getType(i) == 1) + count++; + + return count; +} + +void SMTPData::addCustomMessageHeader(const String &commmand) +{ + _customMessageHeader.insert(_customMessageHeader.end(), commmand.c_str()); +} + +void SMTPData::removeCustomMessageHeader(const String &commmand) +{ + for (uint8_t i = 0; i < _customMessageHeader.size(); i++) + if (_customMessageHeader[i].c_str() == commmand.c_str()) + _customMessageHeader.erase(_customMessageHeader.begin() + i); +} + +void SMTPData::removeCustomMessageHeader(uint8_t index) +{ + _customMessageHeader.erase(_customMessageHeader.begin() + index); +} + +void SMTPData::clearCustomMessageHeader() +{ + std::vector().swap(_customMessageHeader); +} + +uint8_t SMTPData::CustomMessageHeaderCount() +{ + return _customMessageHeader.size(); +} + +String SMTPData::getCustomMessageHeader(uint8_t index) +{ + if (index >= _customMessageHeader.size()) + return std::string().c_str(); + return _customMessageHeader[index].c_str(); +} + +void SMTPData::empty() +{ + std::string().swap(_host); + std::string().swap(_loginEmail); + std::string().swap(_loginPassword); + std::string().swap(_fromName); + std::string().swap(_senderEmail); + std::string().swap(_subject); + std::string().swap(_message); + clearRecipient(); + clearCustomMessageHeader(); + clearCC(); + clearBCC(); + clearAttachment(); +} + +void SMTPData::setSendCallback(sendStatusCallback sendCallback) +{ + _sendCallback = std::move(sendCallback); +} + +ReadStatus::ReadStatus() +{ +} +ReadStatus::~ReadStatus() +{ + empty(); +} + +String ReadStatus::status() +{ + return _status.c_str(); +} +String ReadStatus::info() +{ + return _info.c_str(); +} + +bool ReadStatus::success() +{ + return _success; +} +void ReadStatus::empty() +{ + std::string().swap(_info); + std::string().swap(_status); +} + +SendStatus::SendStatus() +{ +} + +SendStatus::~SendStatus() +{ + empty(); +} + +String SendStatus::info() +{ + return _info.c_str(); +} +bool SendStatus::success() +{ + return _success; +} +void SendStatus::empty() +{ + std::string().swap(_info); +} + +ESP32_MailClient MailClient = ESP32_MailClient(); + +#endif //ESP32 + +#endif //ESP32_MailClient_CPP diff --git a/libesp32/ESP32-Mail-Client/src/ESP32_MailClient.h b/libesp32/ESP32-Mail-Client/src/ESP32_MailClient.h new file mode 100755 index 000000000..943cd62f7 --- /dev/null +++ b/libesp32/ESP32-Mail-Client/src/ESP32_MailClient.h @@ -0,0 +1,1908 @@ +/* + *Mail Client Arduino Library for ESP32, version 2.1.4 + * + * April 12, 2020 + * + * This library allows ESP32 to send Email with/without attachment and receive Email with/without attachment download through SMTP and IMAP servers. + * + * The library supports all ESP32 MCU based modules. + * + * The MIT License (MIT) + * Copyright (c) 2019 K. Suwatchai (Mobizt) + * + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + + + +#ifndef ESP32_MailClient_H +#define ESP32_MailClient_H + +#ifdef ESP32 + +#include +#include "WiFiClientSecureESP32.h" +#include +#include +#include +#include +#include +#include +#include +#include "RFC2047.h" +#include "ESP32MailHTTPClient.h" +#include "ESP32TimeHelper.h" + +#define FORMAT_SPIFFS_IF_FAILED true + +static RFC2047 RFC2047Decoder; + +using namespace std; + +#define SMTP_STATUS_SERVER_CONNECT_FAILED 1 +#define SMTP_STATUS_SMTP_RESPONSE_FAILED 2 +#define SMTP_STATUS_IDENTIFICATION_FAILED 3 +#define SMTP_STATUS_AUTHEN_NOT_SUPPORT 4 +#define SMTP_STATUS_AUTHEN_FAILED 5 +#define SMTP_STATUS_USER_LOGIN_FAILED 6 +#define SMTP_STATUS_PASSWORD_LOGIN_FAILED 7 +#define SMTP_STATUS_SEND_HEADER_SENDER_FAILED 8 +#define SMTP_STATUS_SEND_HEADER_RECIPIENT_FAILED 9 +#define SMTP_STATUS_SEND_BODY_FAILED 10 + +#define IMAP_STATUS_SERVER_CONNECT_FAILED 1 +#define IMAP_STATUS_IMAP_RESPONSE_FAILED 2 +#define IMAP_STATUS_LOGIN_FAILED 3 +#define IMAP_STATUS_BAD_COMMAND 4 +#define IMAP_STATUS_PARSE_FLAG_FAILED 5 + +#define MAIL_CLIENT_STATUS_WIFI_CONNECT_FAIL 100 + +#define MAX_EMAIL_SEARCH_LIMIT 1000 + +static const unsigned char base64_table[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +class IMAPData; +class SMTPData; +class attachmentData; +class SendStatus; +class messageBodyData; +class DownloadProgress; +class MessageData; + +struct MailClientStorageType +{ + static const uint8_t SPIFFS = 0; + static const uint8_t SD = 1; +}; + +static const char ESP32_MAIL_STR_1[] PROGMEM = "Content-Type: multipart/mixed; boundary=\""; +static const char ESP32_MAIL_STR_2[] PROGMEM = "{BOUNDARY}"; +static const char ESP32_MAIL_STR_3[] PROGMEM = "Mime-Version: 1.0\r\n"; +static const char ESP32_MAIL_STR_4[] PROGMEM = "AUTH LOGIN"; +static const char ESP32_MAIL_STR_5[] PROGMEM = "HELO dude"; +static const char ESP32_MAIL_STR_6[] PROGMEM = "EHLO dude"; +static const char ESP32_MAIL_STR_7[] PROGMEM = "QUIT"; +static const char ESP32_MAIL_STR_8[] PROGMEM = "MAIL FROM:"; +static const char ESP32_MAIL_STR_9[] PROGMEM = "RCPT TO:"; +static const char ESP32_MAIL_STR_10[] PROGMEM = "From: "; +static const char ESP32_MAIL_STR_11[] PROGMEM = "To: "; +static const char ESP32_MAIL_STR_12[] PROGMEM = "Cc: "; +static const char ESP32_MAIL_STR_13[] PROGMEM = ",<"; +static const char ESP32_MAIL_STR_14[] PROGMEM = "<"; +static const char ESP32_MAIL_STR_15[] PROGMEM = ">"; +static const char ESP32_MAIL_STR_16[] PROGMEM = "DATA"; +static const char ESP32_MAIL_STR_17[] PROGMEM = "X-Priority: "; +static const char ESP32_MAIL_STR_18[] PROGMEM = "X-MSMail-Priority: High\r\n"; +static const char ESP32_MAIL_STR_19[] PROGMEM = "X-MSMail-Priority: Normal\r\n"; +static const char ESP32_MAIL_STR_20[] PROGMEM = "X-MSMail-Priority: Low\r\n"; +static const char ESP32_MAIL_STR_21[] PROGMEM = "Importance: High\r\n"; +static const char ESP32_MAIL_STR_22[] PROGMEM = "Importance: Normal\r\n"; +static const char ESP32_MAIL_STR_23[] PROGMEM = "Importance: Low\r\n"; +static const char ESP32_MAIL_STR_24[] PROGMEM = "Subject: "; +static const char ESP32_MAIL_STR_25[] PROGMEM = "Content-Type: "; +static const char ESP32_MAIL_STR_26[] PROGMEM = "; Name=\""; +static const char ESP32_MAIL_STR_27[] PROGMEM = "Content-type: text/plain; charset=us-ascii\r\n"; +static const char ESP32_MAIL_STR_28[] PROGMEM = "Content-type: text/html; charset=\"UTF-8\"\r\n"; +static const char ESP32_MAIL_STR_29[] PROGMEM = "Content-transfer-encoding: 7bit\r\n"; +static const char ESP32_MAIL_STR_30[] PROGMEM = "Content-Disposition: attachment; filename=\""; +static const char ESP32_MAIL_STR_31[] PROGMEM = "Content-transfer-encoding: base64\r\n"; +static const char ESP32_MAIL_STR_32[] PROGMEM = "application/octet-stream"; +static const char ESP32_MAIL_STR_33[] PROGMEM = "--"; +static const char ESP32_MAIL_STR_34[] PROGMEM = "\r\n"; +static const char ESP32_MAIL_STR_35[] PROGMEM = "\"\r\n\r\n"; +static const char ESP32_MAIL_STR_36[] PROGMEM = "\"\r\n"; +static const char ESP32_MAIL_STR_37[] PROGMEM = "\r\n.\r\n"; +static const char ESP32_MAIL_STR_38[] PROGMEM = "could not connect to server"; +static const char ESP32_MAIL_STR_39[] PROGMEM = "could not handle SMTP server response"; +static const char ESP32_MAIL_STR_40[] PROGMEM = "could not handle IMAP server response"; +static const char ESP32_MAIL_STR_41[] PROGMEM = "identification failed"; +static const char ESP32_MAIL_STR_42[] PROGMEM = "authentication is not support"; +static const char ESP32_MAIL_STR_43[] PROGMEM = "authentication failed"; +static const char ESP32_MAIL_STR_44[] PROGMEM = "login account is not valid"; +static const char ESP32_MAIL_STR_45[] PROGMEM = "could not sigin"; +static const char ESP32_MAIL_STR_46[] PROGMEM = "could not parse command"; +static const char ESP32_MAIL_STR_47[] PROGMEM = "login password is not valid"; +static const char ESP32_MAIL_STR_48[] PROGMEM = "send header failed"; +static const char ESP32_MAIL_STR_49[] PROGMEM = "send body failed"; +static const char ESP32_MAIL_STR_50[] PROGMEM = "Connecting to IMAP server..."; +static const char ESP32_MAIL_STR_51[] PROGMEM = "initialize"; +static const char ESP32_MAIL_STR_52[] PROGMEM = "failed"; +static const char ESP32_MAIL_STR_53[] PROGMEM = "Error, "; +static const char ESP32_MAIL_STR_54[] PROGMEM = "IMAP server connected"; +static const char ESP32_MAIL_STR_55[] PROGMEM = "server_connected"; +static const char ESP32_MAIL_STR_56[] PROGMEM = "Sign in..."; +static const char ESP32_MAIL_STR_57[] PROGMEM = "signin"; +static const char ESP32_MAIL_STR_58[] PROGMEM = "Lising folders..."; +static const char ESP32_MAIL_STR_59[] PROGMEM = "listing"; +static const char ESP32_MAIL_STR_60[] PROGMEM = ":::::::Message folders:::::::"; +static const char ESP32_MAIL_STR_61[] PROGMEM = "Reading "; +static const char ESP32_MAIL_STR_62[] PROGMEM = "Predicted next UID: "; +static const char ESP32_MAIL_STR_63[] PROGMEM = "Total Message: "; +static const char ESP32_MAIL_STR_64[] PROGMEM = "::::::::::::Flags::::::::::::"; +static const char ESP32_MAIL_STR_65[] PROGMEM = "::::::::::Messages:::::::::::"; +static const char ESP32_MAIL_STR_66[] PROGMEM = "Searching messages..."; +static const char ESP32_MAIL_STR_67[] PROGMEM = "searching"; +static const char ESP32_MAIL_STR_68[] PROGMEM = "Search limit:"; +static const char ESP32_MAIL_STR_69[] PROGMEM = "Found "; +static const char ESP32_MAIL_STR_70[] PROGMEM = " messages"; +static const char ESP32_MAIL_STR_71[] PROGMEM = "Show "; +static const char ESP32_MAIL_STR_72[] PROGMEM = "Could not found any Email for defined criteria"; +static const char ESP32_MAIL_STR_73[] PROGMEM = "Search criteria is not set, fetch the recent message"; +static const char ESP32_MAIL_STR_74[] PROGMEM = "Feching message "; +static const char ESP32_MAIL_STR_75[] PROGMEM = ", UID: "; +static const char ESP32_MAIL_STR_76[] PROGMEM = ", Number: "; +static const char ESP32_MAIL_STR_77[] PROGMEM = "fetching"; +static const char ESP32_MAIL_STR_78[] PROGMEM = "Attachment ("; +static const char ESP32_MAIL_STR_79[] PROGMEM = ")"; +static const char ESP32_MAIL_STR_80[] PROGMEM = "Downloading attachments..."; +static const char ESP32_MAIL_STR_81[] PROGMEM = "downloading"; +static const char ESP32_MAIL_STR_82[] PROGMEM = " bytes"; +static const char ESP32_MAIL_STR_83[] PROGMEM = " - "; +static const char ESP32_MAIL_STR_84[] PROGMEM = "Free Heap: "; +static const char ESP32_MAIL_STR_85[] PROGMEM = "Sign out..."; +static const char ESP32_MAIL_STR_86[] PROGMEM = "signout"; +static const char ESP32_MAIL_STR_87[] PROGMEM = "Finished"; +static const char ESP32_MAIL_STR_88[] PROGMEM = "finished"; +static const char ESP32_MAIL_STR_89[] PROGMEM = "SD card mount failed"; +static const char ESP32_MAIL_STR_90[] PROGMEM = "download "; +static const char ESP32_MAIL_STR_91[] PROGMEM = ", "; +static const char ESP32_MAIL_STR_92[] PROGMEM = "%"; +static const char ESP32_MAIL_STR_93[] PROGMEM = "connection timeout"; +static const char ESP32_MAIL_STR_94[] PROGMEM = "WiFi connection lost"; +static const char ESP32_MAIL_STR_95[] PROGMEM = "no server response"; +static const char ESP32_MAIL_STR_96[] PROGMEM = "finished"; +static const char ESP32_MAIL_STR_97[] PROGMEM = " folder..."; +static const char ESP32_MAIL_STR_98[] PROGMEM = "Finished"; +static const char ESP32_MAIL_STR_99[] PROGMEM = "Date: "; +static const char ESP32_MAIL_STR_100[] PROGMEM = "Messsage UID: "; +static const char ESP32_MAIL_STR_101[] PROGMEM = "Messsage ID: "; +static const char ESP32_MAIL_STR_102[] PROGMEM = "Accept Language: "; +static const char ESP32_MAIL_STR_103[] PROGMEM = "Content Language: "; +static const char ESP32_MAIL_STR_104[] PROGMEM = "From: "; +static const char ESP32_MAIL_STR_105[] PROGMEM = "From Charset: "; +static const char ESP32_MAIL_STR_106[] PROGMEM = "To: "; +static const char ESP32_MAIL_STR_107[] PROGMEM = "To Charset: "; +static const char ESP32_MAIL_STR_108[] PROGMEM = "CC: "; +static const char ESP32_MAIL_STR_109[] PROGMEM = "CC Charset: "; +static const char ESP32_MAIL_STR_110[] PROGMEM = "Subject: "; +static const char ESP32_MAIL_STR_111[] PROGMEM = "Subject Charset: "; +static const char ESP32_MAIL_STR_112[] PROGMEM = "Message Charset: "; +static const char ESP32_MAIL_STR_113[] PROGMEM = "Attachment: "; +static const char ESP32_MAIL_STR_114[] PROGMEM = "File Index: "; +static const char ESP32_MAIL_STR_115[] PROGMEM = "Filename: "; +static const char ESP32_MAIL_STR_116[] PROGMEM = "Name: "; +static const char ESP32_MAIL_STR_117[] PROGMEM = "Size: "; +static const char ESP32_MAIL_STR_118[] PROGMEM = "Type: "; +static const char ESP32_MAIL_STR_119[] PROGMEM = "Creation Date: "; +static const char ESP32_MAIL_STR_120[] PROGMEM = "Connecting to SMTP server..."; +static const char ESP32_MAIL_STR_121[] PROGMEM = "SMTP server connected, wait for response..."; +static const char ESP32_MAIL_STR_122[] PROGMEM = "Identification..."; +static const char ESP32_MAIL_STR_123[] PROGMEM = "Authentication..."; +static const char ESP32_MAIL_STR_124[] PROGMEM = "Sign in..."; +static const char ESP32_MAIL_STR_125[] PROGMEM = "Sending Email header..."; +static const char ESP32_MAIL_STR_126[] PROGMEM = "Sending Email body..."; +static const char ESP32_MAIL_STR_127[] PROGMEM = "Sending attachments..."; +static const char ESP32_MAIL_STR_128[] PROGMEM = "Finalize..."; +static const char ESP32_MAIL_STR_129[] PROGMEM = "Finished\r\nEmail sent successfully"; +static const char ESP32_MAIL_STR_130[] PROGMEM = "$ LOGIN "; +static const char ESP32_MAIL_STR_131[] PROGMEM = " "; +static const char ESP32_MAIL_STR_132[] PROGMEM = " OK "; +static const char ESP32_MAIL_STR_133[] PROGMEM = "$ LIST \"\" \"*\""; +static const char ESP32_MAIL_STR_134[] PROGMEM = "CAPABILITY"; +static const char ESP32_MAIL_STR_135[] PROGMEM = "$ EXAMINE \""; +static const char ESP32_MAIL_STR_136[] PROGMEM = "\""; +static const char ESP32_MAIL_STR_137[] PROGMEM = "UID "; +static const char ESP32_MAIL_STR_138[] PROGMEM = " UID"; +static const char ESP32_MAIL_STR_139[] PROGMEM = " SEARCH"; +static const char ESP32_MAIL_STR_140[] PROGMEM = "UID"; +static const char ESP32_MAIL_STR_141[] PROGMEM = "SEARCH"; +static const char ESP32_MAIL_STR_142[] PROGMEM = "$ UID FETCH "; +static const char ESP32_MAIL_STR_143[] PROGMEM = "$ FETCH "; +static const char ESP32_MAIL_STR_144[] PROGMEM = " BODY.PEEK[HEADER.FIELDS (SUBJECT FROM TO DATE Message-ID Accept-Language Content-Language)]"; +static const char ESP32_MAIL_STR_145[] PROGMEM = "IMAP"; +static const char ESP32_MAIL_STR_146[] PROGMEM = "$ LOGOUT"; +static const char ESP32_MAIL_STR_147[] PROGMEM = " BODY.PEEK["; +static const char ESP32_MAIL_STR_148[] PROGMEM = ".MIME]"; +static const char ESP32_MAIL_STR_149[] PROGMEM = "multipart/"; +static const char ESP32_MAIL_STR_150[] PROGMEM = "$ UID FETCH "; +static const char ESP32_MAIL_STR_151[] PROGMEM = " BODY.PEEK["; +static const char ESP32_MAIL_STR_152[] PROGMEM = "."; +static const char ESP32_MAIL_STR_153[] PROGMEM = "attachment"; +static const char ESP32_MAIL_STR_154[] PROGMEM = "text/html"; +static const char ESP32_MAIL_STR_155[] PROGMEM = "text/plain"; +static const char ESP32_MAIL_STR_156[] PROGMEM = "]"; +static const char ESP32_MAIL_STR_157[] PROGMEM = "* ESEARCH"; +static const char ESP32_MAIL_STR_158[] PROGMEM = "$ NO "; +static const char ESP32_MAIL_STR_159[] PROGMEM = "$ BAD "; +static const char ESP32_MAIL_STR_160[] PROGMEM = "base64"; +static const char ESP32_MAIL_STR_161[] PROGMEM = "/decoded_msg.txt"; +static const char ESP32_MAIL_STR_162[] PROGMEM = "/raw_msg.txt"; +static const char ESP32_MAIL_STR_163[] PROGMEM = "/decoded_msg.html"; +static const char ESP32_MAIL_STR_164[] PROGMEM = "/raw_msg.html"; +static const char ESP32_MAIL_STR_165[] PROGMEM = " FETCH "; +static const char ESP32_MAIL_STR_166[] PROGMEM = "* OK "; +static const char ESP32_MAIL_STR_167[] PROGMEM = "content-type: "; +static const char ESP32_MAIL_STR_168[] PROGMEM = "charset=\""; +static const char ESP32_MAIL_STR_169[] PROGMEM = "charset="; +static const char ESP32_MAIL_STR_170[] PROGMEM = "name=\""; +static const char ESP32_MAIL_STR_171[] PROGMEM = "name="; +static const char ESP32_MAIL_STR_172[] PROGMEM = "content-transfer-encoding: "; +static const char ESP32_MAIL_STR_173[] PROGMEM = "\r"; +static const char ESP32_MAIL_STR_174[] PROGMEM = "content-description: "; +static const char ESP32_MAIL_STR_175[] PROGMEM = "content-disposition: "; +static const char ESP32_MAIL_STR_176[] PROGMEM = "filename=\""; +static const char ESP32_MAIL_STR_177[] PROGMEM = "filename="; +static const char ESP32_MAIL_STR_178[] PROGMEM = "size="; +static const char ESP32_MAIL_STR_179[] PROGMEM = "creation-date=\""; +static const char ESP32_MAIL_STR_180[] PROGMEM = "creation-date="; +static const char ESP32_MAIL_STR_181[] PROGMEM = "modification-date=\""; +static const char ESP32_MAIL_STR_182[] PROGMEM = "modification-date="; +static const char ESP32_MAIL_STR_183[] PROGMEM = "*"; +static const char ESP32_MAIL_STR_184[] PROGMEM = "from: "; +static const char ESP32_MAIL_STR_185[] PROGMEM = "to: "; +static const char ESP32_MAIL_STR_186[] PROGMEM = "cc: "; +static const char ESP32_MAIL_STR_187[] PROGMEM = "subject: "; +static const char ESP32_MAIL_STR_188[] PROGMEM = "date: "; +static const char ESP32_MAIL_STR_189[] PROGMEM = "message-id: "; +static const char ESP32_MAIL_STR_190[] PROGMEM = "accept-language: "; +static const char ESP32_MAIL_STR_191[] PROGMEM = "content-language: "; +static const char ESP32_MAIL_STR_192[] PROGMEM = ")"; +static const char ESP32_MAIL_STR_193[] PROGMEM = "{"; +static const char ESP32_MAIL_STR_194[] PROGMEM = "}"; +static const char ESP32_MAIL_STR_195[] PROGMEM = " LIST "; +static const char ESP32_MAIL_STR_196[] PROGMEM = "\\Noselect"; +static const char ESP32_MAIL_STR_197[] PROGMEM = " FLAGS "; +static const char ESP32_MAIL_STR_198[] PROGMEM = "("; +static const char ESP32_MAIL_STR_199[] PROGMEM = " EXISTS"; +static const char ESP32_MAIL_STR_200[] PROGMEM = " [UIDNEXT "; +static const char ESP32_MAIL_STR_201[] PROGMEM = "]"; +static const char ESP32_MAIL_STR_202[] PROGMEM = "/"; +static const char ESP32_MAIL_STR_203[] PROGMEM = "/header.txt"; +static const char ESP32_MAIL_STR_204[] PROGMEM = "/esp.32"; +static const char ESP32_MAIL_STR_205[] PROGMEM = "high"; +static const char ESP32_MAIL_STR_206[] PROGMEM = "High"; +static const char ESP32_MAIL_STR_207[] PROGMEM = "normal"; +static const char ESP32_MAIL_STR_208[] PROGMEM = "Normal"; +static const char ESP32_MAIL_STR_209[] PROGMEM = "low"; +static const char ESP32_MAIL_STR_210[] PROGMEM = "Low"; +static const char ESP32_MAIL_STR_211[] PROGMEM = "$ OK "; +static const char ESP32_MAIL_STR_212[] PROGMEM = "FLAGS"; +static const char ESP32_MAIL_STR_213[] PROGMEM = "BODY"; +static const char ESP32_MAIL_STR_214[] PROGMEM = "PEEK"; +static const char ESP32_MAIL_STR_215[] PROGMEM = "TEXT"; +static const char ESP32_MAIL_STR_216[] PROGMEM = "HEADER"; +static const char ESP32_MAIL_STR_217[] PROGMEM = "FIELDS"; +static const char ESP32_MAIL_STR_218[] PROGMEM = "["; +static const char ESP32_MAIL_STR_219[] PROGMEM = "]"; +static const char ESP32_MAIL_STR_220[] PROGMEM = "MIME"; +static const char ESP32_MAIL_STR_221[] PROGMEM = "connection lost"; +static const char ESP32_MAIL_STR_222[] PROGMEM = "set recipient failed"; +static const char ESP32_MAIL_STR_223[] PROGMEM = " NEW"; +static const char ESP32_MAIL_STR_224[] PROGMEM = "ALL"; + +static const char ESP32_MAIL_STR_225[] PROGMEM = "INFO: connecting to IMAP server..."; +static const char ESP32_MAIL_STR_226[] PROGMEM = "ERROR: could not connect to internet"; +static const char ESP32_MAIL_STR_227[] PROGMEM = "ERROR: "; +static const char ESP32_MAIL_STR_228[] PROGMEM = "INFO: server connected"; +static const char ESP32_MAIL_STR_229[] PROGMEM = "INFO: send imap command LOGIN"; +static const char ESP32_MAIL_STR_230[] PROGMEM = "INFO: send imap command LIST"; +static const char ESP32_MAIL_STR_231[] PROGMEM = "INFO: send imap command EXAMINE"; +static const char ESP32_MAIL_STR_232[] PROGMEM = "INFO: search message"; +static const char ESP32_MAIL_STR_233[] PROGMEM = "INFO: fetch message"; +static const char ESP32_MAIL_STR_234[] PROGMEM = "INFO: send imap command LOGOUT"; +static const char ESP32_MAIL_STR_235[] PROGMEM = "INFO: message fetch completed"; +static const char ESP32_MAIL_STR_236[] PROGMEM = "INFO: connecting to SMTP server..."; +static const char ESP32_MAIL_STR_237[] PROGMEM = "ERROR: could not connect to internet"; +static const char ESP32_MAIL_STR_238[] PROGMEM = "INFO: smtp server connected"; +static const char ESP32_MAIL_STR_239[] PROGMEM = "INFO: send smtp HELO command"; +static const char ESP32_MAIL_STR_240[] PROGMEM = "INFO: send smtp AUTH LOGIN command"; +static const char ESP32_MAIL_STR_241[] PROGMEM = "INFO: log in with username and password"; +static const char ESP32_MAIL_STR_242[] PROGMEM = "INFO: send email header"; +static const char ESP32_MAIL_STR_243[] PROGMEM = "INFO: send email body"; +static const char ESP32_MAIL_STR_244[] PROGMEM = "INFO: send attachment..."; +static const char ESP32_MAIL_STR_245[] PROGMEM = "INFO: finalize..."; +static const char ESP32_MAIL_STR_246[] PROGMEM = "INFO: email sent successfully"; +static const char ESP32_MAIL_STR_247[] PROGMEM = "$ SELECT \""; +static const char ESP32_MAIL_STR_248[] PROGMEM = "INFO: send imap command SELECT"; +static const char ESP32_MAIL_STR_249[] PROGMEM = "$ UID STORE "; +static const char ESP32_MAIL_STR_250[] PROGMEM = " FLAGS ("; +static const char ESP32_MAIL_STR_251[] PROGMEM = " +FLAGS ("; +static const char ESP32_MAIL_STR_252[] PROGMEM = " -FLAGS ("; +static const char ESP32_MAIL_STR_253[] PROGMEM = "INFO: set FLAG"; +static const char ESP32_MAIL_STR_254[] PROGMEM = "INFO: add FLAG"; +static const char ESP32_MAIL_STR_255[] PROGMEM = "INFO: remove FLAG"; +static const char ESP32_MAIL_STR_256[] PROGMEM = "could not parse flag"; +static const char ESP32_MAIL_STR_257[] PROGMEM = "BAD"; + +__attribute__((used)) static bool compFunc(uint32_t i, uint32_t j) +{ + return (i > j); +} + +class ReadStatus +{ +public: + ReadStatus(); + ~ReadStatus(); + String status(); + String info(); + bool success(); + void empty(); + friend IMAPData; + + std::string _status = ""; + std::string _info = ""; + bool _success = false; +}; + +class SendStatus +{ +public: + SendStatus(); + ~SendStatus(); + String info(); + bool success(); + void empty(); + friend SMTPData; + + std::string _info = ""; + bool _success = false; +}; + +typedef void (*readStatusCallback)(ReadStatus); +typedef void (*sendStatusCallback)(SendStatus); + + + +class ESP32_MailClient +{ + +public: + /* + + Sending Email through SMTP server + + @param net - HTTPClientESP32 WiFi client. + + @return Boolean type status indicates the success of operation. + + */ + bool sendMail(SMTPData &smtpData); + + /* + + Reading Email through IMAP server. + + @param imapData - IMAP Data object to hold data and instances. + + @return Boolean type status indicates the success of operation. + + */ + bool readMail(IMAPData &imapData); + + /* + + Set the argument to the Flags for message. + + @param imapData - IMAP Data object to hold data and instances. + + @param msgUID - The UID of message. + + @param flags - The flag list. + + + @return Boolean type status indicates the success of operation. + + */ + bool setFlag(IMAPData &imapData, int msgUID, const String &flags); + + + + /* + + Add the argument to the Flags for message. + + @param imapData - IMAP Data object to hold data and instances. + + @param msgUID - The UID of message. + + @param flags - The flag list. + + + @return Boolean type status indicates the success of operation. + + */ + bool addFlag(IMAPData &imapData, int msgUID, const String &flags); + + /* + + Remove the argument from the Flags for message. + + @param imapData - IMAP Data object to hold data and instances. + + @param msgUID - The UID of message. + + @param flags - The flag list. + + + @return Boolean type status indicates the success of operation. + + */ + bool removeFlag(IMAPData &imapData, int msgUID, const String &flags); + + /* + + Get the Email sending error details. + + @return Error details string (String object). + + */ + String smtpErrorReason(); + + /* + + Get the Email reading error details. + + @return Error details string (String object). + + */ + String imapErrorReason(); + + /* + + Init SD card with GPIO pins. + + @param sck - SPI Clock pin. + @param miso - SPI MISO pin. + @param mosi - SPI MOSI pin. + @param ss - SPI Chip/Slave Select pin. + + @return Boolean type status indicates the success of operation. + + */ + bool sdBegin(uint8_t sck, uint8_t miso, uint8_t mosi, uint8_t ss); + + /* + + Init SD card with default GPIO pins. + + @return Boolean type status indicates the success of operation. + + */ + bool sdBegin(void); + + struct IMAP_COMMAND_TYPE; + struct IMAP_HEADER_TYPE; + + +ESP32TimeHelper Time; + +private: + int _smtpStatus = 0; + int _imapStatus = 0; + bool _sdOk = false; + bool _sdConfigSet = false; + uint8_t _sck, _miso, _mosi, _ss; + unsigned long _lastReconnectMillis = 0; + uint16_t _reconnectTimeout = 10000; + + + std::string smtpErrorReasonStr(); + std::string imapErrorReasonStr(); + void ESP32MailDebugError(); + void ESP32MailDebugInfo(PGM_P info); + void set_message_header(string &header, std::string &message, bool htmlFormat); + void set_attachment_header(uint8_t index, std::string &header, attachmentData &attach); + void clientReadAll(WiFiClient *client); + double base64DecodeSize(std::string lastBase64String, int length); + unsigned char *base64_decode_char(const unsigned char *src, size_t len, size_t *out_len); + std::string base64_encode_string(const unsigned char *src, size_t len); + void send_base64_encode_mime_data(WiFiClient *client, const unsigned char *src, size_t len); + void send_base64_encode_mime_file(WiFiClient *client, File file); + int waitSMTPResponse(SMTPData &smtpData); + bool waitIMAPResponse(IMAPData &imapData, uint8_t imapCommandType = 0, int maxChar = 0, int mailIndex = -1, int messageDataIndex = -1, std ::string part = ""); + bool _setFlag(IMAPData &imapData, int msgUID, const String &flags, uint8_t action); + bool getIMAPResponse(IMAPData &imapData); + void createDirs(std::string dirs); + bool smtpClientAvailable(SMTPData &smtpData, bool available); + bool imapClientAvailable(IMAPData &imapData, bool available); + bool sdTest(); +}; + +class messageBodyData +{ +public: + messageBodyData(); + ~messageBodyData(); + void empty(); + + friend ESP32_MailClient; + friend IMAPData; + +protected: + uint8_t _index = 0; + size_t _size = 0; + std::string _text = ""; + std::string _filename = ""; + std::string _savePath = ""; + std::string _name = ""; + std::string _disposition = ""; + std::string _contentType = ""; + std::string _descr = ""; + std::string _transfer_encoding = ""; + std::string _creation_date = ""; + std::string _modification_date = ""; + std::string _charset = ""; + std::string _part = ""; + std::string _downloadError = ""; + bool _sdFileOpenWrite = false; + bool _error = false; +}; + +class attachmentData +{ +public: + attachmentData(); + ~attachmentData(); + + friend ESP32_MailClient; + friend SMTPData; + +protected: + uint8_t _index = 0; + std::vector> _buf = std::vector>(); + std::vector _filename = std::vector(); + std::vector _id = std::vector(); + std::vector _type = std::vector(); + std::vector _size = std::vector(); + std::vector _mime_type = std::vector(); + + void add(const String &fileName, const String &mimeType, uint8_t *data, size_t size); + void remove(uint8_t index); + void free(); + String getFileName(uint8_t index); + String getMimeType(uint8_t index); + uint8_t *getData(uint8_t index); + uint16_t getSize(uint8_t index); + uint8_t getCount(); + uint8_t getType(uint8_t index); +}; + +class IMAPData +{ +public: + IMAPData(); + ~IMAPData(); + + /* + Set the IMAP server login credentials. + + @param host - IMAP server e.g. imap.gmail.com. + @param port - IMAP port e.g. 993 for gmail. + @param loginEmail - The Email address of account. + @param loginPassword - The account password. + @rootCA - Root CA certificate base64 string + + */ + void setLogin(const String &host, uint16_t port, const String &loginEmail, const String &loginPassword, const char *rootCA); + void setLogin(const String &host, uint16_t port, const String &loginEmail, const String &loginPassword); + + /* + + Set STARTTLS mode to enable STARTTLS protocol + + @param starttls - bool flag that enables STARTTLS mode + + */ + void setSTARTTLS(bool starttls); + + /* + + Set debug print to serial + + @param debug - bool flag to enable debug + + */ + void setDebug(bool debug); + + /* + + Set the mailbox folder to search or fetch. + + @param folderName - Known mailbox folder. Ddefault value is INBOX + + */ + void setFolder(const String &folderName); + + /* + + Set the maximum message buffer size for text/html result from search or fetch the message. + + @param size - The message size in byte. + + */ + void setMessageBufferSize(size_t size); + + /* + + Set the maximum attachment file size to be downloaded. + + @param size - The attachement file size in byte. + + */ + void setAttachmentSizeLimit(size_t size); + + /* + Set the search criteria used in selected mailbox search. + + In case of message UID was set through setFetchUID function, search operation will not process, + you need to clear message UID by calling imapData.setFetchUID("") to clear. + + @param criteria - Search criteria String. + + If folder is not set, the INBOX folder will be used + + Example: + + "SINCE 10-Feb-2019" will search all messages that received since 10 Feb 2019 + "UID SEARCH ALL" will seach all message which will return the message UID that can be use later for fetch one or more messages. + + + Search criteria can be consisted these keywords + + ALL - All messages in the mailbox; the default initial key for ANDing. + ANSWERED - Messages with the \Answered flag set. + BCC - Messages that contain the specified string in the envelope structure's BCC field. + BEFORE - Messages whose internal date (disregarding time and timezone) is earlier than the specified date. + BODY - Messages that contain the specified string in the body of the message. + CC - Messages that contain the specified string in the envelope structure's CC field. + DELETED - Messages with the \Deleted flag set. + DRAFT - Messages with the \Draft flag set. + FLAGGED - Messages with the \Flagged flag set. + FROM - Messages that contain the specified string in the envelope structure's FROM field. + HEADER - Messages that have a header with the specified field-name (as defined in [RFC-2822]) + and that contains the specified string in the text of the header (what comes after the colon). + + If the string to search is zero-length, this matches all messages that have a header line with + the specified field-name regardless of the contents. + + KEYWORD - Messages with the specified keyword flag set. + LARGER - Messages with an [RFC-2822] size larger than the specified number of octets. + NEW - Messages that have the \Recent flag set but not the \Seen flag. + This is functionally equivalent to "(RECENT UNSEEN)". + NOT - Messages that do not match the specified search key. + OLD - Messages that do not have the \Recent flag set. This is functionally equivalent to + "NOT RECENT" (as opposed to "NOT NEW"). + ON - Messages whose internal date (disregarding time and timezone) is within the specified date. + OR - Messages that match either search key. + RECENT - Messages that have the \Recent flag set. + SEEN - Messages that have the \Seen flag set. + SENTBEFORE - Messages whose [RFC-2822] Date: header (disregarding time and timezone) is earlier than the specified date. + SENTON - Messages whose [RFC-2822] Date: header (disregarding time and timezone) is within the specified date. + SENTSINCE - Messages whose [RFC-2822] Date: header (disregarding time and timezone) is within or later than the specified date. + SINCE - Messages whose internal date (disregarding time and timezone) is within or later than the specified date. + SMALLER - Messages with an [RFC-2822] size smaller than the specified number of octets. + SUBJECT - Messages that contain the specified string in the envelope structure's SUBJECT field. + TEXT - Messages that contain the specified string in the header or body of the message. + TO - Messages that contain the specified string in the envelope structure's TO field. + UID - Messages with unique identifiers corresponding to the specified unique identifier set. + Sequence set ranges are permitted. + UNANSWERED - Messages that do not have the \Answered flag set. + UNDELETED - Messages that do not have the \Deleted flag set. + UNDRAFT - Messages that do not have the \Draft flag set. + UNFLAGGED - Messages that do not have the \Flagged flag set. + UNKEYWORD - Messages that do not have the specified keyword flag set. + UNSEEN - Messages that do not have the \Seen flag set. + + */ + void setSearchCriteria(const String &criteria); + + /* + Set to search the unseen message. + + @param unseenSearch - Boolean flag to enable unseen message search. + + This function will be overridden (omitted) by setFetchUID as setSearchCriteria. + + */ + void setSearchUnseenMessage(bool unseenSearch); + + /* + Set the download folder. + + @param path - Path in SD card. + + All text/html message and attachemnts will be saved to message UID folder which created in defined path + e.g. "/{DEFINED_PATH}/{MESSAGE_UID}/{ATTACHMENT_FILE...}". + + */ + void setSaveFilePath(const String &path); + + /* + + Specify message UID to fetch or read. + + @param fetchUID - The message UID. + + Specify the message UID to fetch (read) only specific message instead of search. + + */ + void setFetchUID(const String &fetchUID); + + /* + + Set storage type to save download attached file or messages. + + @param storageType - The storage type to save file, MailClientStorageType::SD or MailClientStorageType::SPIFFS + + */ + void setFileStorageType(uint8_t storageType); + + /* + + Enable/disable attachment download. + + @param download - Boolean flag to enable/disable attachment download. + + */ + void setDownloadAttachment(bool download); + + /* + + Enable/disable html message result. + + @param htmlFormat - Boolean flag to enable/disable html message result. + + The default value is false. + + */ + void setHTMLMessage(bool htmlFormat); + + /* + + Enable/disable plain text message result. + + @param textFormat - Boolean flag to enable/disable plain text message result. + + The default value is true. + + */ + void setTextMessage(bool textFormat); + + /* + + Set the maximum message to search. + + @param limit - Any number from 0 to 65535. + + The default value is 20. + + */ + void setSearchLimit(uint16_t limit); + + /* + + Enable/disable recent sort result. + + @param recentSort - Boolean flag to enable/disable recent message sort result. + + The default value is true. + + */ + void setRecentSort(bool recentSort); + + /* + + Assign callback function that return status of message fetching or reading. + + @param readCallback - The function that accept readStatusCallback as parameter. + + */ + void setReadCallback(readStatusCallback readCallback); + + /* + + Enable/disable attachement download progress while fetching or receiving message. + + @param report - Boolean flag to enable/disable attachement download progress while fetching or receiving message. + + To get the download status, Callback function should be set through setReadCallback. + + */ + void setDownloadReport(bool report); + + /* + + Determine only message header is return when search. + + */ + bool isHeaderOnly(); + + /* + + Get the sender name/Email for selected message from search result. + + @param messageIndex - The index of message. + + @return Sender name/Email String. + + */ + String getFrom(uint16_t messageIndex); + + /* + + Get the sender name/Email charactor encoding. + + @param messageIndex - The index of message. + + @return Sender name/Email charactor encoding which use for decoding. + + */ + String getFromCharset(uint16_t messageIndex); + + /* + + Get the recipient name/Email for selected message index from search result. + + @param messageIndex - The index of message. + + @return Recipient name/Email String. + + */ + String getTo(uint16_t messageIndex); + + /* + + Get the recipient name/Email charactor encoding. + + @param messageIndex - The index of message. + + @return Recipient name/Email charactor encoding which use in decoding to local language. + + */ + String getToCharset(uint16_t messageIndex); + + /* + + Get the CC name/Email for selected message index of IMAPData result. + + @param messageIndex - The index of message. + + @return CC name/Email String. + + */ + String getCC(uint16_t messageIndex); + + /* + + Get the CC name/Email charactor encoding. + + @param messageIndex - The index of message. + + @return CC name/Email charactor encoding which use in decoding to local language. + + */ + String getCCCharset(uint16_t messageIndex); + + /* + + Get the message subject for selected message index from search result. + + @param messageIndex - The index of message. + + @return Message subject name/Email String. + + */ + String getSubject(uint16_t messageIndex); + + /* + + Get the message subject charactor encoding. + + @param messageIndex - The index of message. + + @return Message subject charactor encoding which use in decoding to local language. + + */ + String getSubjectCharset(uint16_t messageIndex); + + /* + + Get the html message for selected message index from search result. + + @param messageIndex - The index of message. + + @return The html message String or empty String upon the setHTMLMessage was set. + + */ + String getHTMLMessage(uint16_t messageIndex); + + /* + + Get the plain text message for selected message index from search result. + + @param messageIndex - The index of message. + + @return The plain text message String or empty String upon the setTextMessage was set. + + */ + String getTextMessage(uint16_t messageIndex); + + /* + + Get the html message charactor encoding. + + @param messageIndex - The index of message. + + @return Html message charactor encoding which use in decoding to local language. + + */ + String getHTMLMessgaeCharset(uint16_t messageIndex); + + /* + + Get the text message charactor encoding. + + @param messageIndex - The index of message. + + @return The text message charactor encoding which use in decoding to local language. + + */ + String getTextMessgaeCharset(uint16_t messageIndex); + + /* + + Get the date of received message for selected message index from search result. + + @param messageIndex - The index of message. + + @return The date String. + + */ + String getDate(uint16_t messageIndex); + + /* + + Get the message UID for selected message index from search result. + + @param messageIndex - The index of message. + + @return UID String that can be use in setFetchUID. + + */ + String getUID(uint16_t messageIndex); + + /* + + Get the message number for selected message index from search result. + + @param messageIndex - The index of message. + + @return The message number which vary upon search criteria and sorting. + + */ + String getNumber(uint16_t messageIndex); + + /* + + Get the message ID for selected message index from search result. + + @param messageIndex - The index of message. + + @return The message ID String. + + */ + String getMessageID(uint16_t messageIndex); + + /* + + Get the accept language for selected message index from search result. + + @param messageIndex - The index of message. + + @return The accept language String. + + */ + String getAcceptLanguage(uint16_t messageIndex); + + /* + + Get the content language of text or html for selected message index from search result. + + @param messageIndex - The index of message. + + @return The content language String. + + */ + String getContentLanguage(uint16_t messageIndex); + + /* + + Determine fetch error status for selected message index from search result. + + @param messageIndex - The index of message. + + @return Fetch error status. + + */ + bool isFetchMessageFailed(uint16_t messageIndex); + + /* + Get fetch error reason for selected message index from search result. + + @param messageIndex - The index of message. + + @return Fetch error reason String for selected message index. + + */ + String getFetchMessageFailedReason(uint16_t messageIndex); + + /* + Determine the attachment download error for selected message index from search result. + + @param messageIndex - The index of message. + + @return Fetch status. + + */ + bool isDownloadAttachmentFailed(uint16_t messageIndex, size_t attachmentIndex); + + /* + + Get the attachment download error reason for selected message index from search result. + + @param messageIndex - The index of message. + + @return Download error reason String for selected message index. + + */ + String getDownloadAttachmentFailedReason(uint16_t messageIndex, size_t attachmentIndex); + + /* + + Determine the downloaded/saved text message error status for selected message index from search result. + + @param messageIndex - The index of message. + + @return Text message download status. + + */ + bool isDownloadMessageFailed(uint16_t messageIndex); + + /* + + Get the attachment or message downloadeds error reason for selected message index from search result. + + @param messageIndex - The index of message. + + @return Downloaded error reason String for selected message index. + + */ + String getDownloadMessageFailedReason(uint16_t messageIndex); + + /* + + Assign the download and decode flags for html message download. + + @param download - Boolean flag to enable/disable message download. + + @param decoded - Boolean flag to enable/disable html message decoding (support utf8 and base64 encoding). + + */ + void saveHTMLMessage(bool download, bool decoded); + + /* + + Assign the download and decode flags for plain text message download. + + @param download - Boolean flag to enable/disable message download. + + @param decoded - Boolean flag to enable/disable plain text message decoding (support utf8 and base64 encoding). + + */ + void saveTextMessage(bool download, bool decoded); + + /* + + Determine the mailbox folder count. + + @return Folder count number. + + */ + uint16_t getFolderCount(); + + /* + Get the mailbox folder name at selected index. + + @param folderIndex - Index of folder. + + @return Folder name String. + + Use folder name from this function for fetch or search. + + */ + String getFolder(uint16_t folderIndex); + + /* + + Determin the number of supported flags count. + + @return Flag count number. + + */ + uint16_t getFlagCount(); + + /* + Get the flag name for selected index. + + @param folderIndex - Index of folder. + + @return Flag name String. + + Use flags from this function for fetch or search. + + */ + String getFlag(uint16_t flagIndex); + + /* + + Get the number of message in selected mailbox folder. + + @return Total message number. + + */ + size_t totalMessages(); + + /* + + Get the number of message from search result. + + @return Search result number. + + */ + size_t searchCount(); + + /* + + Get the number of message available from search result which less than search limit. + + @return Available message number. + + */ + size_t availableMessages(); + + /* + + Get the number of attachments for selected message index from search result. + + @param messageIndex - Index of message. + + @return Number of attachments + + */ + size_t getAttachmentCount(uint16_t messageIndex); + + /* + + Get file name of attachment for selected attachment index and message index from search result. + + @param messageIndex - Index of message. + @param attachmentIndex - Index of attachment. + + @return The attachment file name String at the selected index. + + */ + String getAttachmentFileName(size_t messageIndex, size_t attachmentIndex); + + /* + + Get the name of attachment for selected attachment index and message index from search result. + + @param messageIndex - Index of message. + @param attachmentIndex - Index of attachment. + + @return The attachment name String at the selected index. + + */ + String getAttachmentName(size_t messageIndex, size_t attachmentIndex); + + /* + + Get attachment file size for selected attachment index and message index from search result. + + @param messageIndex - Index of message. + @param attachmentIndex - Index of attachment. + + @return The attachment file size in byte at the selected index. + + */ + int getAttachmentFileSize(size_t messageIndex, size_t attachmentIndex); + + /* + + Get creation date of attachment for selected attachment index and message index from search result. + + @param messageIndex - Index of message. + @param attachmentIndex - Index of attachment. + + @return The attachment creation date String at the selected index. + + */ + String getAttachmentCreationDate(size_t messageIndex, size_t attachmentIndex); + + /* + Get attachment file type for selected attachment index and message index from search result. + + @param messageIndex - Index of message. + @param attachmentIndex - Index of attachment. + + @return File MIME String at the selected index e.g. image/jpeg. + + */ + String getAttachmentType(size_t messageIndex, size_t attachmentIndex); + + /* + + Clear all IMAPData object data. + + */ + void empty(); + + /* + + Clear IMAPData object message data. + + */ + void clearMessageData(); + + friend ESP32_MailClient; + +private: + String getMessage(uint16_t messageIndex, bool htmlFormat); + + + size_t _totalMessage = 0; + std::string _host = ""; + uint16_t _port = 993; + uint8_t _storageType = 1; + bool _unseen = false; + std::string _loginEmail = ""; + std::string _loginPassword = ""; + std::string _currentFolder = "INBOX"; + std::string _nextUID = ""; + std::string _searchCriteria = "ALL*"; + std::string _fetchUID = ""; + std::string _savePath = ""; + + bool _downloadAttachment = false; + bool _recentSort = true; + bool _htmlFormat = false; + bool _textFormat = false; + bool _headerOnly = true; + bool _uidSearch = false; + bool _saveHTMLMsg = false; + bool _saveTextMsg = false; + bool _saveDecodedHTML = false; + bool _saveDecodedText = false; + bool _downloadReport = false; + bool _headerSaved = false; + + size_t _message_buffer_size = 200; + size_t _attacement_max_size = 1024 * 1024; + uint16_t _emailNumMax = 20; + int _searchCount; + bool _starttls = false; + bool _debug = false; + readStatusCallback _readCallback = NULL; + + std::vector _date = std::vector(); + std::vector _subject = std::vector(); + std::vector _subject_charset = std::vector(); + std::vector _from = std::vector(); + std::vector _from_charset = std::vector(); + std::vector _to = std::vector(); + std::vector _to_charset = std::vector(); + std::vector _cc = std::vector(); + std::vector _cc_charset = std::vector(); + std::vector _msgNum = std::vector(); + std::vector _msgID = std::vector(); + std::vector _contentLanguage = std::vector(); + std::vector _acceptLanguage = std::vector(); + + std::vector _folders = std::vector(); + std::vector _flag = std::vector(); + std::vector _attachmentCount = std::vector(); + std::vector> _messageDataInfo = std::vector>(); + std::vector _totalAttachFileSize = std::vector(); + std::vector _downloadedByte = std::vector(); + std::vector _messageDataCount = std::vector(); + std::vector _errorMsg = std::vector(); + std::vector _error = std::vector(); + std::vector _rootCA = std::vector(); + + + std::unique_ptr _net = std::unique_ptr(new ESP32MailHTTPClient()); + + ReadStatus _cbData; +}; + +class SMTPData +{ +public: + SMTPData(); + ~SMTPData(); + + /* + + Set SMTP server login credentials + + @param host - SMTP server e.g. smtp.gmail.com + @param port - SMTP port. + @param loginEmail - The account Email. + @param loginPassword - The account password. + @rootCA - Root CA certificate base64 string + + */ + void setLogin(const String &host, uint16_t port, const String &loginEmail, const String &loginPassword, const char *rootCA); + void setLogin(const String &host, uint16_t port, const String &loginEmail, const String &loginPassword); + + /* + + Set STARTTLS mode to enable STARTTLS protocol + + @param starttls - bool flag that enables STARTTLS mode + + */ + void setSTARTTLS(bool starttls); + + /* + + Set debug print to serial + + @param debug - bool flag to enable debug + + */ + void setDebug(bool debug); + /* + + Set Sender info + + @param fromName - Sender's name + @param senderEmail - Sender's Email. + + */ + void setSender(const String &fromName, const String &senderEmail); + + /* + + Get Sender's name + + @return Sender's name String. + + */ + String getFromName(); + + /* + + Get Sender's Email + + @return Sender's Email String. + + */ + String getSenderEmail(); + + /* + + Set Email priority or importance + + @param priority - Number from 1 to 5, 1 for highest, 3 for normal and 5 for lowest priority + + */ + void setPriority(int priority); + + /* + + Set Email priority or importance + + @param priority - String (High, Normal or Low) + + */ + void setPriority(const String &priority); + + /* + + Get Email priority + + @return number represents Email priority (1 for highest, 3 for normal, 5 for low priority). + + */ + uint8_t getPriority(); + + /* + + Add one or more recipient + + @param email - Recipient Email String of one recipient. + + To add multiple recipients, call addRecipient for each recipient. + + */ + void addRecipient(const String &email); + + /* + + Remove recipient + + @param email - Recipient Email String. + + */ + void removeRecipient(const String &email); + + /* + + Remove recipient + + @param index - Index of recipients in Email object that previously added. + + */ + void removeRecipient(uint8_t index); + + /* + Clear all recipients. + */ + void clearRecipient(); + + /* + + Get one recipient + + @param index - Index of recipients. + + @return Recipient Email String at the index. + + */ + String getRecipient(uint8_t index); + + /* + + Get number of recipients + + @return Number of recipients. + + */ + uint8_t recipientCount(); + + /* + + Set the Email subject + + @param subject - The subject. + + */ + void setSubject(const String &subject); + + /* + + Get the Email subject + + @return Subject String. + + */ + String getSubject(); + + /* + + Set the Email message + + @param message - The message can be in normal text or html format. + @param htmlFormat - The html format flag, True for send the message as html format + + */ + void setMessage(const String &message, bool htmlFormat); + + void clrMessage(bool htmlFormat); + + void addMessage(const String &message); + + + /* + + Get the message + + @return Message String. + + */ + String getMessage(); + + /* + + Determine message is being send in html format + + @return Boolean status. + + */ + bool htmlFormat(); + + /* + + Add Carbon Copy (CC) Email + + @param email - The CC Email String. + + */ + void addCC(const String &email); + + /* + + Remove specified Carbon Copy (CC) Email + + @param email - The CC Email String to remove. + + */ + void removeCC(const String &email); + + /* + + Remove specified Carbon Copy (CC) Email + + @param index - The CC Email index to remove. + + */ + void removeCC(uint8_t index); + + /* + + Clear all Carbon Copy (CC) Emails + + */ + void clearCC(); + + /* + + Get Carbon Copy (CC) Email at specified index + + @param index - The CC Email index to get. + @return The CC Email string at the index. + + */ + String getCC(uint8_t index); + + /* + + Get the number of Carbon Copy (CC) Email + + @return Number of CC Emails. + + */ + uint8_t ccCount(); + + /* + Add Blind Carbon Copy (BCC) Email + + @param email - The BCC Email String. + + */ + void addBCC(const String &email); + + /* + + Remove specified Blind Carbon Copy (BCC) Email + + @param email - The BCC Email String to remove. + + */ + void removeBCC(const String &email); + + /* + + Remove specified Blind Carbon Copy (BCC) Email + + @param index - The BCC Email index to remove. + + */ + void removeBCC(uint8_t index); + + /* + + Clear all Blind Carbon Copy (BCC) Emails + + */ + void clearBCC(); + + /* + + Get Blind Carbon Copy (BCC) Email at specified index + + @param index - The BCC Email index to get. + + @return The BCC Email string at the index. + + */ + String getBCC(uint8_t index); + + /* + + Get the number of Blind Carbon Copy (BCC) Email + + @return Number of BCC Emails. + + */ + uint8_t bccCount(); + + /* + + Add attchement data (binary) from internal memory (flash or ram) + + @param fileName - The file name String that recipient can be saved. + @param mimeType - The MIME type of file (image/jpeg, image/png, text/plain...). Can be empty String. + @param data - The byte array of data (uint8_t) + @param size - The data length in byte. + + */ + void addAttachData(const String &fileName, const String &mimeType, uint8_t *data, size_t size); + + /* + + Remove specified attachment data + + @param fileName - The file name of the attachment data to remove. + + */ + void removeAttachData(const String &fileName); + + /* + + Remove specified attachment data + + @param index - The index of the attachment data (count only data type attachment) to remove. + + */ + void removeAttachData(uint8_t index); + + /* + + Get the number of attachment data + + @return Number of attach data. + + */ + uint8_t attachDataCount(); + + /* + + Add attchement file from SD card + + @param fileName - The file name String that recipient can be saved. + @param mimeType - The MIME type of file (image/jpeg, image/png, text/plain...). Can be omitted. + + */ + void addAttachFile(const String &filePath, const String &mimeType = ""); + + /* + + Remove specified attachment file from Email object + + @param fileName - The file name of the attachment file to remove. + + */ + void removeAttachFile(const String &filePath); + + /* + + Remove specified attachment file + + @param index - The index of the attachment file (count only file type attachment) to remove. + + */ + void removeAttachFile(uint8_t index); + + /* + + Set storage type for all attach files. + + @param storageType - The storage type to read attach file, MailClientStorageType::SD or MailClientStorageType::SPIFFS + + */ + void setFileStorageType(uint8_t storageType); + + /* + + Clear all attachment data + + */ + void clearAttachData(); + + /* + + Clear all attachment file. + + */ + void clearAttachFile(); + + /* + + Clear all attachments (both data and file type attachments). + + */ + void clearAttachment(); + + /* + + Get number of attachments (both data and file type attachments). + + @return Number of all attachemnts. + + */ + uint8_t attachFileCount(); + + /* + + Add one or more custom message header field. + + @param field - custom header String inform of FIELD: VALUE + + This header field will add to message header. + + + */ + void addCustomMessageHeader(const String &field); + + /* + + Remove one custom message header field that previously added. + + @param field - custom custom message header field String to remove. + + + */ + void removeCustomMessageHeader(const String &field); + + /* + + Remove one custom message header field that previously added by its index. + + @param index - custom message header field index (number) to remove. + + + */ + void removeCustomMessageHeader(uint8_t index); + + /* + + Clear all ccustom message header field that previously added. + + */ + void clearCustomMessageHeader(); + + /* + + Get the number of custom message header field that previously added. + + @return Number of custom message header field. + + */ + uint8_t CustomMessageHeaderCount(); + + /* + + Get custom message header field that previously added by index + + @param index - The custom message header field index to get. + + @return The custom message header field string at the index. + + */ + String getCustomMessageHeader(uint8_t index); + + + + /* + + Clear all data from Email object to free memory. + + */ + void empty(); + + /* + + Set the Email sending status callback function to Email object. + + @param sendCallback - The callback function that accept the sendStatusCallback param. + + */ + void setSendCallback(sendStatusCallback sendCallback); + + friend ESP32_MailClient; + friend attachmentData; + +protected: + int _priority = -1; + string _loginEmail = ""; + string _loginPassword = ""; + string _host = ""; + uint16_t _port = 0; + uint8_t _storageType = 1; + + string _fromName = ""; + string _senderEmail = ""; + string _subject = ""; + string _message = ""; + bool _htmlFormat = false; + bool _starttls = false; + bool _debug = false; + sendStatusCallback _sendCallback = NULL; + + std::vector _recipient = std::vector(); + std::vector _customMessageHeader = std::vector(); + std::vector _cc = std::vector(); + std::vector _bcc = std::vector(); + attachmentData _attach; + SendStatus _cbData; + std::vector _rootCA = std::vector(); + std::unique_ptr _net = std::unique_ptr(new ESP32MailHTTPClient()); + +}; + + +static void __attribute__((used)) ESP32MailDebug(const char *msg) +{ + + Serial.print(FPSTR("[DEBUG] - ")); + Serial.println(msg); + +} + +static void __attribute__((used)) ESP32MailDebugLine(const char *msg, bool newline) +{ + if (!newline) + Serial.print(FPSTR("[DEBUG] - ")); + + if (newline) + Serial.println(msg); + else + Serial.print(msg); +} + + +extern ESP32_MailClient MailClient; + +#endif //ESP32 + +#endif //ESP32_MailClient_H diff --git a/libesp32/ESP32-Mail-Client/src/RFC2047.cpp b/libesp32/ESP32-Mail-Client/src/RFC2047.cpp new file mode 100755 index 000000000..993c132e3 --- /dev/null +++ b/libesp32/ESP32-Mail-Client/src/RFC2047.cpp @@ -0,0 +1,240 @@ +#ifndef RFC2047_CPP +#define RFC2047_CPP + +#ifdef ESP32 + +#include "RFC2047.h" + +RFC2047::RFC2047(){} + + +void RFC2047::rfc2047Decode(char *d, const char *s, size_t dlen){ + + const char *p, *q; + size_t n; + int found_encoded = 0; + + dlen--; /* save room for the terminal nul */ + + while (*s && dlen > 0) + { + if ((p = strstr (s, "=?")) == NULL || + (q = strchr (p + 2, '?')) == NULL || + (q = strchr (q + 1, '?')) == NULL || + (q = strstr (q + 1, "?=")) == NULL) + { + /* no encoded words */ + if (d != s) + strfcpy (d, s, dlen + 1); + return; + } + + if (p != s) + { + n = (size_t) (p - s); + /* ignore spaces between encoded words */ + if (!found_encoded || strspn (s, " \t\r\n") != n) + { + if (n > dlen) + n = dlen; + if (d != s) + memcpy (d, s, n); + d += n; + dlen -= n; + } + } + + rfc2047DecodeWord (d, p, dlen); + found_encoded = 1; + s = q + 2; + n = strlen (d); + dlen -= n; + d += n; + } + *d = 0; + +} + +void RFC2047::rfc2047DecodeWord(char *d, const char *s, size_t dlen){ + + char *p = safe_strdup (s); + char *pp = p; + char *pd = d; + size_t len = dlen; + int enc = 0, filter = 0, count = 0, c1, c2, c3, c4; + + while ((pp = strtok (pp, "?")) != NULL) + { + count++; + switch (count) + { + case 2: + if (strcasecmp (pp, Charset) != 0) + { + filter = 1; + } + break; + case 3: + if (toupper (*pp) == 'Q') + enc = ENCQUOTEDPRINTABLE; + else if (toupper (*pp) == 'B') + enc = ENCBASE64; + else + return; + break; + case 4: + if (enc == ENCQUOTEDPRINTABLE) + { + while (*pp && len > 0) + { + if (*pp == '_') + { + *pd++ = ' '; + len--; + } + else if (*pp == '=') + { + *pd++ = (hexval(pp[1]) << 4) | hexval(pp[2]); + len--; + pp += 2; + } + else + { + *pd++ = *pp; + len--; + } + pp++; + } + *pd = 0; + } + else if (enc == ENCBASE64) + { + while (*pp && len > 0) + { + c1 = base64val(pp[0]); + c2 = base64val(pp[1]); + *pd++ = (c1 << 2) | ((c2 >> 4) & 0x3); + if (--len == 0) break; + + if (pp[2] == '=') break; + + c3 = base64val(pp[2]); + *pd++ = ((c2 & 0xf) << 4) | ((c3 >> 2) & 0xf); + if (--len == 0) + break; + + if (pp[3] == '=') + break; + + c4 = base64val(pp[3]); + *pd++ = ((c3 & 0x3) << 6) | c4; + if (--len == 0) + break; + + pp += 4; + } + *pd = 0; + } + break; + } + pp = 0; + } + safe_free (&p); + if (filter) + { + + pd = d; + while (*pd) + { + if (!IsPrint (*pd)) + *pd = '?'; + pd++; + } + } + return; +} + + +void *RFC2047::safe_calloc (size_t nmemb, size_t size) +{ + void *p; + + if (!nmemb || !size) + return NULL; + if (!(p = calloc (nmemb, size))) + { + //out of memory + return NULL; + } + return p; +} + +void *RFC2047::safe_malloc (unsigned int siz) +{ + void *p; + + if (siz == 0) + return 0; + if ((p = (void *) malloc (siz)) == 0) + { + //out of memory + return NULL; + } + return (p); +} + +void RFC2047::safe_realloc (void **p, size_t siz) +{ + void *r; + + if (siz == 0) + { + if (*p) + { + free (*p); + *p = NULL; + } + return; + } + + if (*p) + r = (void *) realloc (*p, siz); + else + { + r = (void *) malloc (siz); + } + + if (!r) + { + //out of memory + return; + } + + *p = r; +} + +void RFC2047::safe_free (void *ptr) +{ + void **p = (void **)ptr; + if (*p) + { + free (*p); + *p = 0; + } +} + +char *RFC2047::safe_strdup (const char *s) +{ + char *p; + size_t l; + + if (!s || !*s) return 0; + l = strlen (s) + 1; + p = (char *)safe_malloc (l); + memcpy (p, s, l); + return (p); +} + +#endif //ESP32 + +#endif //RFC2047_CPP \ No newline at end of file diff --git a/libesp32/ESP32-Mail-Client/src/RFC2047.h b/libesp32/ESP32-Mail-Client/src/RFC2047.h new file mode 100755 index 000000000..aeee0e12c --- /dev/null +++ b/libesp32/ESP32-Mail-Client/src/RFC2047.h @@ -0,0 +1,70 @@ + +#ifndef RFC2047_H +#define RFC2047_H + +#ifdef ESP32 + +#include + + +#define strfcpy(A,B,C) strncpy(A,B,C), *(A+(C)-1)=0 + +enum +{ + ENCOTHER, + ENC7BIT, + ENC8BIT, + ENCQUOTEDPRINTABLE, + ENCBASE64, + ENCBINARY +}; + +__attribute__((used)) static const char *Charset = "utf-8"; + +__attribute__((used)) static int Index_hex[128] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, + -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; + +__attribute__((used)) static int Index_64[128] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, + -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1}; + +#define IsPrint(c) (isprint((unsigned char)(c)) || \ + ((unsigned char)(c) >= 0xa0)) + +#define hexval(c) Index_hex[(unsigned int)(c)] +#define base64val(c) Index_64[(unsigned int)(c)] + +class RFC2047{ + + public: + RFC2047(); + void rfc2047Decode(char *d, const char *s, size_t dlen); + + + private: + void rfc2047DecodeWord(char *d, const char *s, size_t dlen); + void *safe_calloc (size_t nmemb, size_t size); + void *safe_malloc (unsigned int siz); + void safe_realloc (void **p, size_t siz); + void safe_free (void *ptr); + char *safe_strdup (const char *s); + + +}; + +#endif //ESP32 + +#endif //RFC2047_H \ No newline at end of file diff --git a/libesp32/ESP32-Mail-Client/src/WiFiClientSecureESP32.cpp b/libesp32/ESP32-Mail-Client/src/WiFiClientSecureESP32.cpp new file mode 100755 index 000000000..26460a604 --- /dev/null +++ b/libesp32/ESP32-Mail-Client/src/WiFiClientSecureESP32.cpp @@ -0,0 +1,397 @@ +/* + *Customized WiFiClientSecure.cpp to support STARTTLS protocol, version 1.0.1 + * + * The MIT License (MIT) + * Copyright (c) 2019 K. Suwatchai (Mobizt) + * + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + WiFiClientSecureESP32.cpp - Client Secure class for ESP32 + Copyright (c) 2016 Hristo Gochkov All right reserved. + Additions Copyright (C) 2017 Evandro Luis Copercini. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef WiFiClientSecureESP32_CPP +#define WiFiClientSecureESP32_CPP + +#ifdef ESP32 + +#include "WiFiClientSecureESP32.h" +#include +#include +#include + +#undef connect +#undef write +#undef read + + +WiFiClientSecureESP32::WiFiClientSecureESP32() +{ + _connected = false; + + sslclient = new sslclient_context32; + ssl_init(sslclient); + sslclient->socket = -1; + sslclient->handshake_timeout = 120000; + _CA_cert = NULL; + _cert = NULL; + _private_key = NULL; + _pskIdent = NULL; + _psKey = NULL; + next = NULL; +} + + +WiFiClientSecureESP32::WiFiClientSecureESP32(int sock) +{ + _connected = false; + _timeout = 0; + + sslclient = new sslclient_context32; + ssl_init(sslclient); + sslclient->socket = sock; + sslclient->handshake_timeout = 120000; + + if (sock >= 0) { + _connected = true; + } + + _CA_cert = NULL; + _cert = NULL; + _private_key = NULL; + _pskIdent = NULL; + _psKey = NULL; + next = NULL; +} + +WiFiClientSecureESP32::WiFiClientSecureESP32(bool starttls) +{ + _connected = false; + + sslclient = new sslclient_context32; + ssl_init(sslclient); + sslclient->socket = -1; + sslclient->handshake_timeout = 120000; + sslclient->starttls = true; + _CA_cert = NULL; + _cert = NULL; + _private_key = NULL; + _pskIdent = NULL; + _psKey = NULL; + next = NULL; +} + +WiFiClientSecureESP32::~WiFiClientSecureESP32() +{ + stop(); + delete sslclient; +} + +WiFiClientSecureESP32 &WiFiClientSecureESP32::operator=(const WiFiClientSecureESP32 &other) +{ + stop(); + sslclient->socket = other.sslclient->socket; + _connected = other._connected; + return *this; +} + +void WiFiClientSecureESP32::stop() +{ + if (sslclient->socket >= 0) { + close(sslclient->socket); + sslclient->socket = -1; + _connected = false; + _peek = -1; + } + stop_ssl_socket(sslclient, _CA_cert, _cert, _private_key); +} + +int WiFiClientSecureESP32::connect(IPAddress ip, uint16_t port) +{ + if (_pskIdent && _psKey) + return connect(ip, port, _pskIdent, _psKey); + return connect(ip, port, _CA_cert, _cert, _private_key); +} + +int WiFiClientSecureESP32::connect(IPAddress ip, uint16_t port, int32_t timeout){ + _timeout = timeout; + return connect(ip, port); +} + +int WiFiClientSecureESP32::connect(const char *host, uint16_t port) +{ + if (_pskIdent && _psKey) + return connect(host, port, _pskIdent, _psKey); + return connect(host, port, _CA_cert, _cert, _private_key); +} + +int WiFiClientSecureESP32::connect(const char *host, uint16_t port, int32_t timeout){ + _timeout = timeout; + return connect(host, port); +} + +int WiFiClientSecureESP32::connect(IPAddress ip, uint16_t port, const char *_CA_cert, const char *_cert, const char *_private_key) +{ + return connect(ip.toString().c_str(), port, _CA_cert, _cert, _private_key); +} + +int WiFiClientSecureESP32::connect(const char *host, uint16_t port, const char *_CA_cert, const char *_cert, const char *_private_key) +{ + if(_timeout > 0){ + sslclient->handshake_timeout = _timeout; + } + int ret = start_ssl_client(sslclient, host, port, _timeout, _CA_cert, _cert, _private_key, NULL, NULL); + _lastError = ret; + if (ret < 0) { + log_e("start_ssl_client: %d", ret); + stop(); + return 0; + } + _connected = true; + return 1; +} + +int WiFiClientSecureESP32::connect(IPAddress ip, uint16_t port, const char *pskIdent, const char *psKey) { + return connect(ip.toString().c_str(), port,_pskIdent, _psKey); +} + +int WiFiClientSecureESP32::connect(const char *host, uint16_t port, const char *pskIdent, const char *psKey) { + log_v("start_ssl_client with PSK"); + if(_timeout > 0){ + sslclient->handshake_timeout = _timeout; + } + int ret = start_ssl_client(sslclient, host, port, _timeout, NULL, NULL, NULL, _pskIdent, _psKey); + _lastError = ret; + if (ret < 0) { + log_e("start_ssl_client: %d", ret); + stop(); + return 0; + } + _connected = true; + return 1; +} + +int WiFiClientSecureESP32::peek(){ + if(_peek >= 0){ + return _peek; + } + _peek = timedRead(); + return _peek; +} + +size_t WiFiClientSecureESP32::write(uint8_t data) +{ + return write(&data, 1); +} + +int WiFiClientSecureESP32::read() +{ + uint8_t data = -1; + int res = read(&data, 1); + if (res < 0) { + return res; + } + return data; +} + +size_t WiFiClientSecureESP32::write(const uint8_t *buf, size_t size) +{ + if (!_connected) { + return 0; + } + int res = send_ssl_data(sslclient, buf, size); + if (res < 0) { + stop(); + res = 0; + } + return res; +} + +int WiFiClientSecureESP32::read(uint8_t *buf, size_t size) +{ + int peeked = 0; + int avail = available(); + if ((!buf && size) || avail <= 0) { + return -1; + } + if(!size){ + return 0; + } + if(_peek >= 0){ + buf[0] = _peek; + _peek = -1; + size--; + avail--; + if(!size || !avail){ + return 1; + } + buf++; + peeked = 1; + } + + int res = get_ssl_receive(sslclient, buf, size); + if (res < 0) { + stop(); + return peeked?peeked:res; + } + return res + peeked; +} + +int WiFiClientSecureESP32::available() +{ + int peeked = (_peek >= 0); + if (!_connected) { + return peeked; + } + int res = data_to_read(sslclient); + if (res < 0) { + stop(); + return peeked?peeked:res; + } + return res+peeked; +} + +uint8_t WiFiClientSecureESP32::connected() +{ + uint8_t dummy = 0; + read(&dummy, 0); + + return _connected; +} + +void WiFiClientSecureESP32::setCACert (const char *rootCA) +{ + _CA_cert = rootCA; +} + +void WiFiClientSecureESP32::setCertificate (const char *client_ca) +{ + _cert = client_ca; +} + +void WiFiClientSecureESP32::setPrivateKey (const char *private_key) +{ + _private_key = private_key; +} + +void WiFiClientSecureESP32::setPreSharedKey(const char *pskIdent, const char *psKey) { + _pskIdent = pskIdent; + _psKey = psKey; +} + +bool WiFiClientSecureESP32::verify(const char* fp, const char* domain_name) +{ + if (!sslclient) + return false; + + return verify_ssl_fingerprint(sslclient, fp, domain_name); +} + +char *WiFiClientSecureESP32::_streamLoad(Stream& stream, size_t size) { + static char *dest = nullptr; + if(dest) { + free(dest); + } + dest = (char*)malloc(size); + if (!dest) { + return nullptr; + } + if (size != stream.readBytes(dest, size)) { + free(dest); + dest = nullptr; + } + return dest; +} + +bool WiFiClientSecureESP32::loadCACert(Stream& stream, size_t size) { + char *dest = _streamLoad(stream, size); + bool ret = false; + if (dest) { + setCACert(dest); + ret = true; + } + return ret; +} + +bool WiFiClientSecureESP32::loadCertificate(Stream& stream, size_t size) { + char *dest = _streamLoad(stream, size); + bool ret = false; + if (dest) { + setCertificate(dest); + ret = true; + } + return ret; +} + +bool WiFiClientSecureESP32::loadPrivateKey(Stream& stream, size_t size) { + char *dest = _streamLoad(stream, size); + bool ret = false; + if (dest) { + setPrivateKey(dest); + ret = true; + } + return ret; +} + +int WiFiClientSecureESP32::lastError(char *buf, const size_t size) +{ + if (!_lastError) { + return 0; + } + char error_buf[100]; + mbedtls_strerror(_lastError, error_buf, 100); + snprintf(buf, size, "%s", error_buf); + return _lastError; +} + +void WiFiClientSecureESP32::setHandshakeTimeout(unsigned long handshake_timeout) +{ + sslclient->handshake_timeout = handshake_timeout * 1000; +} + +void WiFiClientSecureESP32::setSTARTTLS(bool starttls) +{ + sslclient->starttls = starttls; +} + +void WiFiClientSecureESP32::setDebugCB(DebugMsgCallback cb) +{ + sslclient->_debugCallback = std::move(cb); +} + +#endif //ESP32 + +#endif //WiFiClientSecureESP32_CPP \ No newline at end of file diff --git a/libesp32/ESP32-Mail-Client/src/WiFiClientSecureESP32.h b/libesp32/ESP32-Mail-Client/src/WiFiClientSecureESP32.h new file mode 100755 index 000000000..2a940c391 --- /dev/null +++ b/libesp32/ESP32-Mail-Client/src/WiFiClientSecureESP32.h @@ -0,0 +1,145 @@ + +/* + *Customized WiFiClientSecure.h to support STARTTLS protocol, version 1.0.1 + * + * The MIT License (MIT) + * Copyright (c) 2019 K. Suwatchai (Mobizt) + * + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* + WiFiClientSecureESP32.h - Base class that provides Client SSL to ESP32 + Copyright (c) 2011 Adrian McEwen. All right reserved. + Additions Copyright (C) 2017 Evandro Luis Copercini. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef WiFiClientSecureESP32_H +#define WiFiClientSecureESP32_H + +#ifdef ESP32 + +#include "Arduino.h" +#include "IPAddress.h" +#include +#include "ssl_client32.h" + +typedef void (*DebugMsgCallback)(const char* msg); + +class WiFiClientSecureESP32 : public WiFiClient +{ +protected: + sslclient_context32 *sslclient; + + int _lastError = 0; + int _peek = -1; + int _timeout = 0; + const char *_CA_cert; + const char *_cert; + const char *_private_key; + const char *_pskIdent; // identity for PSK cipher suites + const char *_psKey; // key in hex for PSK cipher suites + DebugMsgCallback _debugCallback = NULL; + +public: + WiFiClientSecureESP32 *next; + WiFiClientSecureESP32(); + WiFiClientSecureESP32(int socket); + WiFiClientSecureESP32(bool starttls); + ~WiFiClientSecureESP32(); + int connect(IPAddress ip, uint16_t port); + int connect(IPAddress ip, uint16_t port, int32_t timeout); + int connect(const char *host, uint16_t port); + int connect(const char *host, uint16_t port, int32_t timeout); + int connect(IPAddress ip, uint16_t port, const char *rootCABuff, const char *cli_cert, const char *cli_key); + int connect(const char *host, uint16_t port, const char *rootCABuff, const char *cli_cert, const char *cli_key); + int connect(IPAddress ip, uint16_t port, const char *pskIdent, const char *psKey); + int connect(const char *host, uint16_t port, const char *pskIdent, const char *psKey); + int peek(); + size_t write(uint8_t data); + size_t write(const uint8_t *buf, size_t size); + int available(); + int read(); + int read(uint8_t *buf, size_t size); + void flush() {} + void stop(); + uint8_t connected(); + int lastError(char *buf, const size_t size); + void setPreSharedKey(const char *pskIdent, const char *psKey); // psKey in Hex + void setCACert(const char *rootCA); + void setCertificate(const char *client_ca); + void setPrivateKey (const char *private_key); + bool loadCACert(Stream& stream, size_t size); + bool loadCertificate(Stream& stream, size_t size); + bool loadPrivateKey(Stream& stream, size_t size); + bool verify(const char* fingerprint, const char* domain_name); + void setHandshakeTimeout(unsigned long handshake_timeout); + void setSTARTTLS(bool starttls); + void setDebugCB(DebugMsgCallback cb); + + operator bool() + { + return connected(); + } + WiFiClientSecureESP32 &operator=(const WiFiClientSecureESP32 &other); + bool operator==(const bool value) + { + return bool() == value; + } + bool operator!=(const bool value) + { + return bool() != value; + } + bool operator==(const WiFiClientSecureESP32 &); + bool operator!=(const WiFiClientSecureESP32 &rhs) + { + return !this->operator==(rhs); + }; + + int socket() + { + return sslclient->socket = -1; + } + +private: + char *_streamLoad(Stream& stream, size_t size); + + //friend class WiFiServer; + using Print::write; +}; + +#endif //ESP32 + +#endif //WiFiClientSecureESP32_H + + diff --git a/libesp32/ESP32-Mail-Client/src/ssl_client32.cpp b/libesp32/ESP32-Mail-Client/src/ssl_client32.cpp new file mode 100755 index 000000000..06e3f11b1 --- /dev/null +++ b/libesp32/ESP32-Mail-Client/src/ssl_client32.cpp @@ -0,0 +1,853 @@ +/* + *Customized ssl_client.cpp to support STARTTLS protocol, version 1.0.3 + * + * The MIT License (MIT) + * Copyright (c) 2019 K. Suwatchai (Mobizt) + * + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* Provide SSL/TLS functions to ESP32 with Arduino IDE +* +* Adapted from the ssl_client1 example of mbedtls. +* +* Original Copyright (C) 2006-2015, ARM Limited, All Rights Reserved, Apache 2.0 License. +* Additions Copyright (C) 2017 Evandro Luis Copercini, Apache 2.0 License. +*/ + +#ifndef SSL_CLIENT32_CPP +#define SSL_CLIENT32_CPP + +#ifdef ESP32 + +#include "Arduino.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ssl_client32.h" +#include "WiFi.h" + +const char *pers32 = "esp32-tls"; + +static int handle_error(int err) +{ + if (err == -30848) + { + return err; + } +#ifdef MBEDTLS_ERROR_C + char error_buf[100]; + mbedtls_strerror(err, error_buf, 100); + log_e("%s", error_buf); +#endif + log_e("MbedTLS message code: %d", err); + return err; +} + +void ssl_init(sslclient_context32 *ssl_client) +{ + mbedtls_ssl_init(&ssl_client->ssl_ctx); + mbedtls_ssl_config_init(&ssl_client->ssl_conf); + mbedtls_ctr_drbg_init(&ssl_client->drbg_ctx); + mbedtls_net_init(&ssl_client->server_fd); +} + +int start_ssl_client(sslclient_context32 *ssl_client, const char *host, uint32_t port, int timeout, const char *rootCABuff, const char *cli_cert, const char *cli_key, const char *pskIdent, const char *psKey) +{ + char buf[512]; + int ret, flags; + int enable = 1; + + if (ssl_client->_debugCallback) + ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_2, ssl_client); + + log_v("Free internal heap before TLS %u", ESP.getFreeHeap()); + + log_v("Starting socket"); + ssl_client->socket = -1; + + ssl_client->socket = lwip_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (ssl_client->socket < 0) + { + if (ssl_client->_debugCallback) + ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_3, ssl_client); + log_e("ERROR opening socket"); + return ssl_client->socket; + } + + IPAddress srv((uint32_t)0); + if (!WiFiGenericClass::hostByName(host, srv)) + { + if (ssl_client->_debugCallback) + ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_4, ssl_client); + return -1; + } + + struct sockaddr_in serv_addr; + memset(&serv_addr, 0, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + serv_addr.sin_addr.s_addr = srv; + serv_addr.sin_port = htons(port); + + if (ssl_client->_debugCallback) + ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_5, ssl_client); + + if (lwip_connect(ssl_client->socket, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == 0) + { + if (timeout <= 0) + { + timeout = 30000; + } + lwip_setsockopt(ssl_client->socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); + lwip_setsockopt(ssl_client->socket, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)); + lwip_setsockopt(ssl_client->socket, IPPROTO_TCP, TCP_NODELAY, &enable, sizeof(enable)); + lwip_setsockopt(ssl_client->socket, SOL_SOCKET, SO_KEEPALIVE, &enable, sizeof(enable)); + + if (ssl_client->_debugCallback) + ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_6, ssl_client); + } + else + { + if (ssl_client->_debugCallback) + ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_7, ssl_client); + log_e("Connect to Server failed!"); + return -1; + } + + fcntl(ssl_client->socket, F_SETFL, fcntl(ssl_client->socket, F_GETFL, 0) | O_NONBLOCK); + + if (ssl_client->starttls && (port == 25 || port == 587 || port == 143)) + { + + if (ssl_client->_debugCallback) + ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_8, ssl_client); + + if ((ret = starttlsHandshake(ssl_client, port)) != 0) + { + log_e("STARTTLS failed!"); + return -1; + } + } + + if (ssl_client->_debugCallback) + ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_9, ssl_client); + + log_v("Seeding the random number generator"); + mbedtls_entropy_init(&ssl_client->entropy_ctx); + + ret = mbedtls_ctr_drbg_seed(&ssl_client->drbg_ctx, mbedtls_entropy_func, + &ssl_client->entropy_ctx, (const unsigned char *)pers32, strlen(pers32)); + if (ret < 0) + { + if (ssl_client->_debugCallback) + { + char *error_buf = new char[100]; + memset(buf, 0, 512); + strcpy_P(buf, ESP32_SSL_CLIENT_STR_1); + mbedtls_strerror(ret, error_buf, 100); + strcat(buf, error_buf); + ssl_client->_debugCallback(buf); + delete[] error_buf; + } + + return handle_error(ret); + } + + if (ssl_client->_debugCallback) + ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_10, ssl_client); + + log_v("Setting up the SSL/TLS structure..."); + + if ((ret = mbedtls_ssl_config_defaults(&ssl_client->ssl_conf, + MBEDTLS_SSL_IS_CLIENT, + MBEDTLS_SSL_TRANSPORT_STREAM, + MBEDTLS_SSL_PRESET_DEFAULT)) != 0) + { + if (ssl_client->_debugCallback) + { + char *error_buf = new char[100]; + memset(buf, 0, 512); + strcpy_P(buf, ESP32_SSL_CLIENT_STR_1); + mbedtls_strerror(ret, error_buf, 100); + strcat(buf, error_buf); + ssl_client->_debugCallback(buf); + delete[] error_buf; + } + return handle_error(ret); + } + + // MBEDTLS_SSL_VERIFY_REQUIRED if a CA certificate is defined on Arduino IDE and + // MBEDTLS_SSL_VERIFY_NONE if not. + + if (rootCABuff != NULL) + { + if (ssl_client->_debugCallback) + ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_11, ssl_client); + log_v("Loading CA cert"); + mbedtls_x509_crt_init(&ssl_client->ca_cert); + mbedtls_ssl_conf_authmode(&ssl_client->ssl_conf, MBEDTLS_SSL_VERIFY_REQUIRED); + ret = mbedtls_x509_crt_parse(&ssl_client->ca_cert, (const unsigned char *)rootCABuff, strlen(rootCABuff) + 1); + mbedtls_ssl_conf_ca_chain(&ssl_client->ssl_conf, &ssl_client->ca_cert, NULL); + //mbedtls_ssl_conf_verify(&ssl_client->ssl_ctx, my_verify, NULL ); + if (ret < 0) + { + if (ssl_client->_debugCallback) + { + char *error_buf = new char[100]; + memset(buf, 0, 512); + strcpy_P(buf, ESP32_SSL_CLIENT_STR_1); + mbedtls_strerror(ret, error_buf, 100); + strcat(buf, error_buf); + ssl_client->_debugCallback(buf); + delete[] error_buf; + } + return handle_error(ret); + } + } + else if (pskIdent != NULL && psKey != NULL) + { + if (ssl_client->_debugCallback) + ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_12, ssl_client); + log_v("Setting up PSK"); + // convert PSK from hex to binary + if ((strlen(psKey) & 1) != 0 || strlen(psKey) > 2 * MBEDTLS_PSK_MAX_LEN) + { + if (ssl_client->_debugCallback) + ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_13, ssl_client); + log_e("pre-shared key not valid hex or too long"); + return -1; + } + unsigned char psk[MBEDTLS_PSK_MAX_LEN]; + size_t psk_len = strlen(psKey) / 2; + for (int j = 0; j < strlen(psKey); j += 2) + { + char c = psKey[j]; + if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'A' && c <= 'F') + c -= 'A' - 10; + else if (c >= 'a' && c <= 'f') + c -= 'a' - 10; + else + return -1; + psk[j / 2] = c << 4; + c = psKey[j + 1]; + if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'A' && c <= 'F') + c -= 'A' - 10; + else if (c >= 'a' && c <= 'f') + c -= 'a' - 10; + else + return -1; + psk[j / 2] |= c; + } + // set mbedtls config + if (ssl_client->_debugCallback) + ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_14, ssl_client); + ret = mbedtls_ssl_conf_psk(&ssl_client->ssl_conf, psk, psk_len, + (const unsigned char *)pskIdent, strlen(pskIdent)); + if (ret != 0) + { + if (ssl_client->_debugCallback) + { + char *error_buf = new char[100]; + memset(buf, 0, 512); + strcpy_P(buf, ESP32_SSL_CLIENT_STR_1); + mbedtls_strerror(ret, error_buf, 100); + strcat(buf, error_buf); + ssl_client->_debugCallback(buf); + delete[] error_buf; + } + log_e("mbedtls_ssl_conf_psk returned %d", ret); + return handle_error(ret); + } + } + else + { + + mbedtls_ssl_conf_authmode(&ssl_client->ssl_conf, MBEDTLS_SSL_VERIFY_NONE); + log_i("WARNING: Use certificates for a more secure communication!"); + } + + if (cli_cert != NULL && cli_key != NULL) + { + + mbedtls_x509_crt_init(&ssl_client->client_cert); + mbedtls_pk_init(&ssl_client->client_key); + + if (ssl_client->_debugCallback) + ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_15, ssl_client); + + log_v("Loading CRT cert"); + + ret = mbedtls_x509_crt_parse(&ssl_client->client_cert, (const unsigned char *)cli_cert, strlen(cli_cert) + 1); + if (ret < 0) + { + if (ssl_client->_debugCallback) + { + char *error_buf = new char[100]; + memset(buf, 0, 512); + strcpy_P(buf, ESP32_SSL_CLIENT_STR_1); + mbedtls_strerror(ret, error_buf, 100); + strcat(buf, error_buf); + ssl_client->_debugCallback(buf); + delete[] error_buf; + } + return handle_error(ret); + } + + if (ssl_client->_debugCallback) + ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_16, ssl_client); + + log_v("Loading private key"); + ret = mbedtls_pk_parse_key(&ssl_client->client_key, (const unsigned char *)cli_key, strlen(cli_key) + 1, NULL, 0); + + if (ret != 0) + { + return handle_error(ret); + } + + mbedtls_ssl_conf_own_cert(&ssl_client->ssl_conf, &ssl_client->client_cert, &ssl_client->client_key); + } + + if (ssl_client->_debugCallback) + ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_17, ssl_client); + + log_v("Setting hostname for TLS session..."); + + // Hostname set here should match CN in server certificate + if ((ret = mbedtls_ssl_set_hostname(&ssl_client->ssl_ctx, host)) != 0) + { + if (ssl_client->_debugCallback) + { + char *error_buf = new char[100]; + memset(buf, 0, 512); + strcpy_P(buf, ESP32_SSL_CLIENT_STR_1); + mbedtls_strerror(ret, error_buf, 100); + strcat(buf, error_buf); + ssl_client->_debugCallback(buf); + delete[] error_buf; + } + return handle_error(ret); + } + + mbedtls_ssl_conf_rng(&ssl_client->ssl_conf, mbedtls_ctr_drbg_random, &ssl_client->drbg_ctx); + + if ((ret = mbedtls_ssl_setup(&ssl_client->ssl_ctx, &ssl_client->ssl_conf)) != 0) + { + if (ssl_client->_debugCallback) + { + char *error_buf = new char[100]; + memset(buf, 0, 512); + strcpy_P(buf, ESP32_SSL_CLIENT_STR_1); + mbedtls_strerror(ret, error_buf, 100); + strcat(buf, error_buf); + ssl_client->_debugCallback(buf); + delete[] error_buf; + } + + return handle_error(ret); + } + + mbedtls_ssl_set_bio(&ssl_client->ssl_ctx, &ssl_client->socket, mbedtls_net_send, mbedtls_net_recv, NULL); + + if (ssl_client->_debugCallback) + ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_18, ssl_client); + + log_v("Performing the SSL/TLS handshake..."); + unsigned long handshake_start_time = millis(); + while ((ret = mbedtls_ssl_handshake(&ssl_client->ssl_ctx)) != 0) + { + if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) + { + if (ssl_client->_debugCallback) + { + char *error_buf = new char[100]; + memset(buf, 0, 512); + strcpy_P(buf, ESP32_SSL_CLIENT_STR_1); + mbedtls_strerror(ret, error_buf, 100); + strcat(buf, error_buf); + ssl_client->_debugCallback(buf); + delete[] error_buf; + } + return handle_error(ret); + } + if ((millis() - handshake_start_time) > ssl_client->handshake_timeout) + return -1; + vTaskDelay(10 / portTICK_PERIOD_MS); + } + + if (cli_cert != NULL && cli_key != NULL) + { + log_d("Protocol is %s Ciphersuite is %s", mbedtls_ssl_get_version(&ssl_client->ssl_ctx), mbedtls_ssl_get_ciphersuite(&ssl_client->ssl_ctx)); + if ((ret = mbedtls_ssl_get_record_expansion(&ssl_client->ssl_ctx)) >= 0) + { + + log_d("Record expansion is %d", ret); + } + else + { + log_w("Record expansion is unknown (compression)"); + } + } + + if (ssl_client->_debugCallback) + ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_19, ssl_client); + + log_v("Verifying peer X.509 certificate..."); + + if ((flags = mbedtls_ssl_get_verify_result(&ssl_client->ssl_ctx)) != 0) + { + bzero(buf, sizeof(buf)); + mbedtls_x509_crt_verify_info(buf, sizeof(buf), " ! ", flags); + if (ssl_client->_debugCallback) + ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_20, ssl_client); + log_e("Failed to verify peer certificate! verification info: %s", buf); + stop_ssl_socket(ssl_client, rootCABuff, cli_cert, cli_key); //It's not safe continue. + return handle_error(ret); + } + else + { + if (ssl_client->_debugCallback) + ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_21, ssl_client); + log_v("Certificate verified."); + } + + if (rootCABuff != NULL) + { + mbedtls_x509_crt_free(&ssl_client->ca_cert); + } + + if (cli_cert != NULL) + { + mbedtls_x509_crt_free(&ssl_client->client_cert); + } + + if (cli_key != NULL) + { + mbedtls_pk_free(&ssl_client->client_key); + } + + log_v("Free internal heap after TLS %u", ESP.getFreeHeap()); + + return ssl_client->socket; +} + +void stop_ssl_socket(sslclient_context32 *ssl_client, const char *rootCABuff, const char *cli_cert, const char *cli_key) +{ + if (ssl_client->_debugCallback) + ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_22, ssl_client); + log_v("Cleaning SSL connection."); + + if (ssl_client->socket >= 0) + { + close(ssl_client->socket); + ssl_client->socket = -1; + } + + mbedtls_ssl_free(&ssl_client->ssl_ctx); + mbedtls_ssl_config_free(&ssl_client->ssl_conf); + mbedtls_ctr_drbg_free(&ssl_client->drbg_ctx); + mbedtls_entropy_free(&ssl_client->entropy_ctx); +} + +int data_to_read(sslclient_context32 *ssl_client) +{ + int ret, res; + ret = mbedtls_ssl_read(&ssl_client->ssl_ctx, NULL, 0); + //log_e("RET: %i",ret); //for low level debug + res = mbedtls_ssl_get_bytes_avail(&ssl_client->ssl_ctx); + //log_e("RES: %i",res); //for low level debug + if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE && ret < 0) + { + if (ssl_client->_debugCallback) + { + char *buf = new char[512]; + char *error_buf = new char[100]; + memset(buf, 0, 512); + strcpy_P(buf, ESP32_SSL_CLIENT_STR_1); + mbedtls_strerror(ret, error_buf, 100); + strcat(buf, error_buf); + ssl_client->_debugCallback(buf); + delete[] error_buf; + delete[] buf; + } + return handle_error(ret); + } + + return res; +} + +int send_ssl_data(sslclient_context32 *ssl_client, const uint8_t *data, uint16_t len) +{ + + log_v("Writing HTTP request..."); //for low level debug + int ret = -1; + + while ((ret = mbedtls_ssl_write(&ssl_client->ssl_ctx, data, len)) <= 0) + { + if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) + { + return handle_error(ret); + } + } + + len = ret; + //log_v("%d bytes written", len); //for low level debug + return ret; +} + +int get_ssl_receive(sslclient_context32 *ssl_client, uint8_t *data, int length) +{ + + //log_d( "Reading HTTP response..."); //for low level debug + int ret = -1; + + ret = mbedtls_ssl_read(&ssl_client->ssl_ctx, data, length); + + //log_v( "%d bytes read", ret); //for low level debug + return ret; +} + +static bool parseHexNibble(char pb, uint8_t *res) +{ + if (pb >= '0' && pb <= '9') + { + *res = (uint8_t)(pb - '0'); + return true; + } + else if (pb >= 'a' && pb <= 'f') + { + *res = (uint8_t)(pb - 'a' + 10); + return true; + } + else if (pb >= 'A' && pb <= 'F') + { + *res = (uint8_t)(pb - 'A' + 10); + return true; + } + return false; +} + +// Compare a name from certificate and domain name, return true if they match +static bool matchName(const std::string &name, const std::string &domainName) +{ + size_t wildcardPos = name.find('*'); + if (wildcardPos == std::string::npos) + { + // Not a wildcard, expect an exact match + return name == domainName; + } + + size_t firstDotPos = name.find('.'); + if (wildcardPos > firstDotPos) + { + // Wildcard is not part of leftmost component of domain name + // Do not attempt to match (rfc6125 6.4.3.1) + return false; + } + if (wildcardPos != 0 || firstDotPos != 1) + { + // Matching of wildcards such as baz*.example.com and b*z.example.com + // is optional. Maybe implement this in the future? + return false; + } + size_t domainNameFirstDotPos = domainName.find('.'); + if (domainNameFirstDotPos == std::string::npos) + { + return false; + } + return domainName.substr(domainNameFirstDotPos) == name.substr(firstDotPos); +} + +// Verifies certificate provided by the peer to match specified SHA256 fingerprint +bool verify_ssl_fingerprint(sslclient_context32 *ssl_client, const char *fp, const char *domain_name) +{ + // Convert hex string to byte array + uint8_t fingerprint_local[32]; + int len = strlen(fp); + int pos = 0; + for (size_t i = 0; i < sizeof(fingerprint_local); ++i) + { + while (pos < len && ((fp[pos] == ' ') || (fp[pos] == ':'))) + { + ++pos; + } + if (pos > len - 2) + { + if (ssl_client->_debugCallback) + ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_23, ssl_client); + log_d("pos:%d len:%d fingerprint too short", pos, len); + return false; + } + uint8_t high, low; + if (!parseHexNibble(fp[pos], &high) || !parseHexNibble(fp[pos + 1], &low)) + { + if (ssl_client->_debugCallback) + ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_24, ssl_client); + log_d("pos:%d len:%d invalid hex sequence: %c%c", pos, len, fp[pos], fp[pos + 1]); + return false; + } + pos += 2; + fingerprint_local[i] = low | (high << 4); + } + + // Get certificate provided by the peer + const mbedtls_x509_crt *crt = mbedtls_ssl_get_peer_cert(&ssl_client->ssl_ctx); + + if (!crt) + { + if (ssl_client->_debugCallback) + ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_25, ssl_client); + log_d("could not fetch peer certificate"); + return false; + } + + // Calculate certificate's SHA256 fingerprint + uint8_t fingerprint_remote[32]; + mbedtls_sha256_context sha256_ctx; + mbedtls_sha256_init(&sha256_ctx); + mbedtls_sha256_starts(&sha256_ctx, false); + mbedtls_sha256_update(&sha256_ctx, crt->raw.p, crt->raw.len); + mbedtls_sha256_finish(&sha256_ctx, fingerprint_remote); + + // Check if fingerprints match + if (memcmp(fingerprint_local, fingerprint_remote, 32)) + { + if (ssl_client->_debugCallback) + ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_26, ssl_client); + log_d("fingerprint doesn't match"); + return false; + } + + // Additionally check if certificate has domain name if provided + if (domain_name) + return verify_ssl_dn(ssl_client, domain_name); + else + return true; +} + +// Checks if peer certificate has specified domain in CN or SANs +bool verify_ssl_dn(sslclient_context32 *ssl_client, const char *domain_name) +{ + log_d("domain name: '%s'", (domain_name) ? domain_name : "(null)"); + std::string domain_name_str(domain_name); + std::transform(domain_name_str.begin(), domain_name_str.end(), domain_name_str.begin(), ::tolower); + + // Get certificate provided by the peer + const mbedtls_x509_crt *crt = mbedtls_ssl_get_peer_cert(&ssl_client->ssl_ctx); + + // Check for domain name in SANs + const mbedtls_x509_sequence *san = &crt->subject_alt_names; + while (san != nullptr) + { + std::string san_str((const char *)san->buf.p, san->buf.len); + std::transform(san_str.begin(), san_str.end(), san_str.begin(), ::tolower); + + if (matchName(san_str, domain_name_str)) + return true; + + log_d("SAN '%s': no match", san_str.c_str()); + + // Fetch next SAN + san = san->next; + } + + // Check for domain name in CN + const mbedtls_asn1_named_data *common_name = &crt->subject; + while (common_name != nullptr) + { + // While iterating through DN objects, check for CN object + if (!MBEDTLS_OID_CMP(MBEDTLS_OID_AT_CN, &common_name->oid)) + { + std::string common_name_str((const char *)common_name->val.p, common_name->val.len); + + if (matchName(common_name_str, domain_name_str)) + return true; + + log_d("CN '%s': not match", common_name_str.c_str()); + } + + // Fetch next DN object + common_name = common_name->next; + } + + return false; +} + +int starttlsHandshake(sslclient_context32 *ssl_client, int port) +{ + + int ret = 0; + size_t msgLen = 100; + size_t bufLen = 512; + char *buf = new char[bufLen]; + char *hMsg = new char[msgLen]; + + fd_set readset; + fd_set writeset; + fd_set errset; + + struct timeval tv; + + FD_ZERO(&readset); + FD_SET(ssl_client->socket, &readset); + FD_ZERO(&writeset); + FD_SET(ssl_client->socket, &writeset); + + FD_ZERO(&errset); + FD_SET(ssl_client->socket, &errset); + + tv.tv_sec = 1; + tv.tv_usec = 0; + + ret = lwip_select(ssl_client->socket, &readset, &writeset, &errset, &tv); + if (ret < 0) + { + if (ssl_client->_debugCallback) + ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_27, ssl_client); + + goto starttls_exit; + } + + ret = read(ssl_client->socket, buf, bufLen); + + if (ret < 0) + { + if (ssl_client->_debugCallback) + ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_28, ssl_client); + goto starttls_exit; + } + else + { + if (ssl_client->_debugCallback) + ssl_client->_debugCallback(buf); + } + + if (port == 587 || port == 25) + { + + memset(hMsg, 0, msgLen); + strcpy_P(hMsg, ESP32_SSL_CLIENT_STR_29); + if (ssl_client->_debugCallback) + ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_30, ssl_client); + ret = lwip_write(ssl_client->socket, hMsg, strlen(hMsg)); + + if (ret < 0) + { + if (ssl_client->_debugCallback) + ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_31, ssl_client); + goto starttls_exit; + } + + ret = lwip_select(ssl_client->socket, &readset, &writeset, &errset, &tv); + + if (ret < 0) + { + if (ssl_client->_debugCallback) + ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_32, ssl_client); + goto starttls_exit; + } + + memset(buf, 0, bufLen); + ret = lwip_read(ssl_client->socket, buf, bufLen); + + if (ret < 0) + { + if (ssl_client->_debugCallback) + ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_33, ssl_client); + goto starttls_exit; + } + else + { + if (ssl_client->_debugCallback) + ssl_client->_debugCallback(buf); + } + } + + memset(hMsg, 0, msgLen); + strcpy_P(hMsg, ESP32_SSL_CLIENT_STR_34); + if (ssl_client->_debugCallback) + ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_35, ssl_client); + ret = lwip_write(ssl_client->socket, hMsg, strlen(hMsg)); + + if (ret < 0) + { + if (ssl_client->_debugCallback) + ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_36, ssl_client); + goto starttls_exit; + } + + ret = lwip_select(ssl_client->socket, &readset, &writeset, &errset, &tv); + + if (ret < 0) + { + if (ssl_client->_debugCallback) + ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_37, ssl_client); + goto starttls_exit; + } + + memset(buf, 0, bufLen); + ret = lwip_read(ssl_client->socket, buf, bufLen); + + if (ret < 0) + { + if (ssl_client->_debugCallback) + ESP32SSLClientDebugInfo(ESP32_SSL_CLIENT_STR_38, ssl_client); + goto starttls_exit; + } + else + { + if (ssl_client->_debugCallback) + ssl_client->_debugCallback(buf); + } + + delete[] buf; + delete[] hMsg; + + return 0; + +starttls_exit: + + delete[] buf; + delete[] hMsg; + + return -1; +} + +void ESP32SSLClientDebugInfo(PGM_P info, sslclient_context32 *ssl_client) +{ + size_t dbgInfoLen = strlen_P(info) + 1; + char *dbgInfo = new char[dbgInfoLen]; + memset(dbgInfo, 0, dbgInfoLen); + strcpy_P(dbgInfo, info); + ssl_client->_debugCallback(dbgInfo); + delete[] dbgInfo; +} + +#endif //ESP32 + +#endif //SSL_CLIENT32_CPP \ No newline at end of file diff --git a/libesp32/ESP32-Mail-Client/src/ssl_client32.h b/libesp32/ESP32-Mail-Client/src/ssl_client32.h new file mode 100755 index 000000000..3e2d3b09a --- /dev/null +++ b/libesp32/ESP32-Mail-Client/src/ssl_client32.h @@ -0,0 +1,116 @@ +/* + *Customized ssl_client.h to support STARTTLS protocol, version 1.0.3 + * + * The MIT License (MIT) + * Copyright (c) 2019 K. Suwatchai (Mobizt) + * + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/* Provide SSL/TLS functions to ESP32 with Arduino IDE + * by Evandro Copercini - 2017 - Apache 2.0 License + */ + +#ifndef SSL_CLIENT32_H +#define SSL_CLIENT32_H + +#ifdef ESP32 + +#include "mbedtls/platform.h" +#include "mbedtls/net.h" +#include "mbedtls/debug.h" +#include "mbedtls/ssl.h" +#include "mbedtls/entropy.h" +#include "mbedtls/ctr_drbg.h" +#include "mbedtls/error.h" + +static const char ESP32_SSL_CLIENT_STR_1[] PROGMEM = "ERROR: "; +static const char ESP32_SSL_CLIENT_STR_2[] PROGMEM = "INFO: starting socket"; +static const char ESP32_SSL_CLIENT_STR_3[] PROGMEM = "ERROR: opening socket"; +static const char ESP32_SSL_CLIENT_STR_4[] PROGMEM = "ERROR: could not get ip from host"; +static const char ESP32_SSL_CLIENT_STR_5[] PROGMEM = "INFO: connecting to Server..."; +static const char ESP32_SSL_CLIENT_STR_6[] PROGMEM = "INFO: server connected"; +static const char ESP32_SSL_CLIENT_STR_7[] PROGMEM = "ERROR: connect to Server failed!"; +static const char ESP32_SSL_CLIENT_STR_8[] PROGMEM = "INFO: begin STARTTLS handshake"; +static const char ESP32_SSL_CLIENT_STR_9[] PROGMEM = "INFO: seeding the random number generator"; +static const char ESP32_SSL_CLIENT_STR_10[] PROGMEM = "INFO: setting up the SSL/TLS structure..."; +static const char ESP32_SSL_CLIENT_STR_11[] PROGMEM = "INFO: loading CA cert"; +static const char ESP32_SSL_CLIENT_STR_12[] PROGMEM = "INFO: setting up PSK"; +static const char ESP32_SSL_CLIENT_STR_13[] PROGMEM = "ERROR: pre-shared key not valid hex or too long"; +static const char ESP32_SSL_CLIENT_STR_14[] PROGMEM = "INFO: set mbedtls config"; +static const char ESP32_SSL_CLIENT_STR_15[] PROGMEM = "INFO: loading CRT cert"; +static const char ESP32_SSL_CLIENT_STR_16[] PROGMEM = "INFO: loading private key"; +static const char ESP32_SSL_CLIENT_STR_17[] PROGMEM = "INFO: setting hostname for TLS session..."; +static const char ESP32_SSL_CLIENT_STR_18[] PROGMEM = "INFO: performing the SSL/TLS handshake..."; +static const char ESP32_SSL_CLIENT_STR_19[] PROGMEM = "INFO: verifying peer X.509 certificate..."; +static const char ESP32_SSL_CLIENT_STR_20[] PROGMEM = "ERROR: failed to verify peer certificate!"; +static const char ESP32_SSL_CLIENT_STR_21[] PROGMEM = "INFO: certificate verified"; +static const char ESP32_SSL_CLIENT_STR_22[] PROGMEM = "INFO: cleaning SSL connection"; +static const char ESP32_SSL_CLIENT_STR_23[] PROGMEM = "ERROR: fingerprint too short"; +static const char ESP32_SSL_CLIENT_STR_24[] PROGMEM = "ERROR: invalid hex sequence"; +static const char ESP32_SSL_CLIENT_STR_25[] PROGMEM = "ERROR: could not fetch peer certificate"; +static const char ESP32_SSL_CLIENT_STR_26[] PROGMEM = "ERROR: fingerprint doesn't match"; +static const char ESP32_SSL_CLIENT_STR_27[] PROGMEM = "ERROR: waiting incoming data failed!"; +static const char ESP32_SSL_CLIENT_STR_28[] PROGMEM = "ERROR: reading incoming data failed!"; +static const char ESP32_SSL_CLIENT_STR_29[] PROGMEM = "EHLO DUDE\r\n"; +static const char ESP32_SSL_CLIENT_STR_30[] PROGMEM = "INFO: send SMTP command extended HELO"; +static const char ESP32_SSL_CLIENT_STR_31[] PROGMEM = "ERROR: send SMTP command failed!"; +static const char ESP32_SSL_CLIENT_STR_32[] PROGMEM = "ERROR: waiting incoming data failed!"; +static const char ESP32_SSL_CLIENT_STR_33[] PROGMEM = "ERROR: reading incoming data failed!"; +static const char ESP32_SSL_CLIENT_STR_34[] PROGMEM = "STARTTLS\r\n"; +static const char ESP32_SSL_CLIENT_STR_35[] PROGMEM = "INFO: send STARTTLS protocol command"; +static const char ESP32_SSL_CLIENT_STR_36[] PROGMEM = "ERROR: send STARTTLS protocol command failed!"; +static const char ESP32_SSL_CLIENT_STR_37[] PROGMEM = "ERROR: waiting incoming data failed!"; +static const char ESP32_SSL_CLIENT_STR_38[] PROGMEM = "ERROR: reading incoming data failed!"; + +typedef void (*DebugMsgCallback)(const char *msg); + +typedef struct sslclient_context32 { + int socket; + bool starttls; + mbedtls_ssl_context ssl_ctx; + mbedtls_ssl_config ssl_conf; + mbedtls_net_context server_fd; + + mbedtls_ctr_drbg_context drbg_ctx; + mbedtls_entropy_context entropy_ctx; + + mbedtls_x509_crt ca_cert; + mbedtls_x509_crt client_cert; + mbedtls_pk_context client_key; + DebugMsgCallback _debugCallback; + + unsigned long handshake_timeout; +} sslclient_context32; + + +void ssl_init(sslclient_context32 *ssl_client); +int start_ssl_client(sslclient_context32 *ssl_client, const char *host, uint32_t port, int timeout, const char *rootCABuff, const char *cli_cert, const char *cli_key, const char *pskIdent, const char *psKey); +void stop_ssl_socket(sslclient_context32 *ssl_client, const char *rootCABuff, const char *cli_cert, const char *cli_key); +int data_to_read(sslclient_context32 *ssl_client); +int send_ssl_data(sslclient_context32 *ssl_client, const uint8_t *data, uint16_t len); +int get_ssl_receive(sslclient_context32 *ssl_client, uint8_t *data, int length); +bool verify_ssl_fingerprint(sslclient_context32 *ssl_client, const char* fp, const char* domain_name); +bool verify_ssl_dn(sslclient_context32 *ssl_client, const char* domain_name); +int starttlsHandshake(sslclient_context32 *ssl_client, int port); +void ESP32SSLClientDebugInfo(PGM_P info, sslclient_context32 *ssl_client); + +#endif //ESP32 + +#endif //SSL_CLIENT32_H diff --git a/libesp32/ESP32-to-ESP8266-compat/README.adoc b/libesp32/ESP32-to-ESP8266-compat/README.adoc new file mode 100644 index 000000000..abf17a277 --- /dev/null +++ b/libesp32/ESP32-to-ESP8266-compat/README.adoc @@ -0,0 +1,19 @@ +Library for ESP32 with Tasmota + +This Class is for compatibility with esp8266 code + +== License == + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA diff --git a/libesp32/ESP32-to-ESP8266-compat/keywords.txt b/libesp32/ESP32-to-ESP8266-compat/keywords.txt new file mode 100644 index 000000000..3422d1305 --- /dev/null +++ b/libesp32/ESP32-to-ESP8266-compat/keywords.txt @@ -0,0 +1,24 @@ +####################################### +# Syntax Coloring Map For Test +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +A4988_ESP32Compat KEYWORD1 A4988_ESP32Compat + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +doMove KEYWORD2 +doRotate KEYWORD2 +setRPM KEYWORD2 +setSPR KEYWORD2 +setMIS KEYWORD2 +version KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### diff --git a/libesp32/ESP32-to-ESP8266-compat/library.properties b/libesp32/ESP32-to-ESP8266-compat/library.properties new file mode 100644 index 000000000..5d5e39166 --- /dev/null +++ b/libesp32/ESP32-to-ESP8266-compat/library.properties @@ -0,0 +1,9 @@ +name=ESP32-to-ESP8266-compat +version=0.0.2 +author=Jörg Schüler-Maroldt +maintainer=Jörg Schüler-Maroldt +sentence=Allows Tasmota to compile for esp32 +paragraph=Allows Tasmota to compile for esp32 +category=ESP32 +url= +architectures=* diff --git a/libesp32/ESP32-to-ESP8266-compat/src/AddrList.h b/libesp32/ESP32-to-ESP8266-compat/src/AddrList.h new file mode 100644 index 000000000..cc32ea232 --- /dev/null +++ b/libesp32/ESP32-to-ESP8266-compat/src/AddrList.h @@ -0,0 +1,233 @@ +/* + AddrList.h - cycle through lwIP netif's ip addresses like a c++ list + Copyright (c) 2018 david gauchard. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + This class allows to explore all configured IP addresses + in lwIP netifs, with that kind of c++ loop: + + for (auto a: addrList) + out.printf("IF='%s' index=%d legacy=%d IPv4=%d local=%d hostname='%s' addr= %s\n", + a.iface().c_str(), + a.ifnumber(), + a.addr().isLegacy(), + a.addr().isV4(), + a.addr().isLocal(), + a.hostname().c_str(), + a.addr().toString().c_str()); + + This loop: + + while (WiFi.status() != WL_CONNECTED()) { + Serial.print('.'); + delay(500); + } + + can be replaced by: + + for (bool configured = false; !configured; ) { + for (auto iface: addrList) + if ((configured = !iface.addr().isLocal()) + break; + Serial.print('.'); + delay(500); + } + + waiting for an IPv6 global address: + + for (bool configured = false; !configured; ) { + for (auto iface: addrList) + if ((configured = ( !iface.addr().isV4() + && !iface.addr().isLocal()))) + break; + Serial.print('.'); + delay(500); + } + + waiting for an IPv6 global address, on a specific interface: + + for (bool configured = false; !configured; ) { + for (auto iface: addrList) + if ((configured = ( !iface.addr().isV4() + && !iface.addr().isLocal() + && iface.ifnumber() == STATION_IF))) + break; + Serial.print('.'); + delay(500); + } +*/ + +#ifndef __ADDRLIST_H +#define __ADDRLIST_H + +#include +#include + +#if LWIP_IPV6 +#define IF_NUM_ADDRESSES (1 + LWIP_IPV6_NUM_ADDRESSES) +#else +#define IF_NUM_ADDRESSES (1) +#endif + + +namespace esp8266 +{ + +namespace AddressListImplementation +{ + + +struct netifWrapper +{ + netifWrapper (netif* netif) : _netif(netif), _num(-1) {} + netifWrapper (const netifWrapper& o) : _netif(o._netif), _num(o._num) {} + + netifWrapper& operator= (const netifWrapper& o) + { + _netif = o._netif; + _num = o._num; + return *this; + } + + bool equal(const netifWrapper& o) + { + return _netif == o._netif && (!_netif || _num == o._num); + } + + // address properties + class IPAddress4 : public IPAddress + { + public: + bool isV6() const + { + return false; + } + bool isLocal() const + { + return false; + } + }; + IPAddress4 addr () const { return ipFromNetifNum(); } + bool isLegacy () const { return _num == 0; } + //bool isLocal () const { return addr().isLocal(); } + bool isV4 () const { return addr().isV4(); } + bool isV6 () const { return !addr().isV4(); } + String toString() const { return addr().toString(); } + + // related to legacy address (_num=0, ipv4) + IPAddress ipv4 () const { return _netif->ip_addr; } + IPAddress netmask () const { return _netif->netmask; } + IPAddress gw () const { return _netif->gw; } + + // common to all addresses of this interface + String ifname () const { return String(_netif->name[0]) + _netif->name[1]; } + const char* ifhostname () const { return _netif->hostname?: emptyString.c_str(); } + const char* ifmac () const { return (const char*)_netif->hwaddr; } + int ifnumber () const { return _netif->num; } + bool ifUp () const { return !!(_netif->flags & NETIF_FLAG_UP); } + const netif* interface () const { return _netif; } + + const ip_addr_t* ipFromNetifNum () const + { +#if LWIP_IPV6 + return _num ? &_netif->ip6_addr[_num - 1] : &_netif->ip_addr; +#else + return &_netif->ip_addr; +#endif + } + + // lwIP interface + netif* _netif; + + // address index within interface + // 0: legacy address (IPv4) + // n>0: (_num-1) is IPv6 index for netif->ip6_addr[] + int _num; +}; + + +class AddressListIterator +{ +public: + AddressListIterator (const netifWrapper& o) : netIf(o) {} + AddressListIterator (netif* netif) : netIf(netif) + { + // This constructor is called with lwIP's global netif_list, or + // nullptr. operator++() is designed to loop through _configured_ + // addresses. That's why netIf's _num is initialized to -1 to allow + // returning the first usable address to AddressList::begin(). + (void)operator++(); + } + + const netifWrapper& operator* () const { return netIf; } + const netifWrapper* operator-> () const { return &netIf; } + + bool operator== (AddressListIterator& o) { return netIf.equal(*o); } + bool operator!= (AddressListIterator& o) { return !netIf.equal(*o); } + + AddressListIterator operator++ (int) + { + AddressListIterator ret = *this; + (void)operator++(); + return ret; + } + + AddressListIterator& operator++ () + { + while (netIf._netif) + { + if (++netIf._num == IF_NUM_ADDRESSES) + { + // all addresses from current interface were iterated, + // switching to next interface + netIf = netifWrapper(netIf._netif->next); + continue; + } + if (!ip_addr_isany(netIf.ipFromNetifNum())) + // found an initialized address + break; + } + return *this; + } + + netifWrapper netIf; +}; + + +class AddressList +{ +public: + using const_iterator = const AddressListIterator; + + const_iterator begin () const { return const_iterator(netif_list); } + const_iterator end () const { return const_iterator(nullptr); } + +}; + +inline AddressList::const_iterator begin (const AddressList& a) { return a.begin(); } +inline AddressList::const_iterator end (const AddressList& a) { return a.end(); } + + +} // AddressListImplementation + +} // esp8266 + +extern AddressList addrList; + + +#endif diff --git a/libesp32/ESP32-to-ESP8266-compat/src/ESP32Wifi.cpp b/libesp32/ESP32-to-ESP8266-compat/src/ESP32Wifi.cpp new file mode 100644 index 000000000..9ce191cde --- /dev/null +++ b/libesp32/ESP32-to-ESP8266-compat/src/ESP32Wifi.cpp @@ -0,0 +1,93 @@ +/* + WiFi compat with ESP32 + + Copyright (C) 2020 Theo Arends / Jörg Schüler-Maroldt + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +// +#include "Arduino.h" +#include + +// +// Wifi +// +#ifdef WiFi +#undef WiFi +#endif + +void WiFiClass32::setSleepMode(int iSleepMode) +{ + // WIFI_MODEM_SLEEP + WiFi.setSleep(iSleepMode != WIFI_MODEM_SLEEP); +} + +int WiFiClass32::getPhyMode() +{ + return 0; // " BGN" +} + +void WiFiClass32::wps_disable() +{ +} + +void WiFiClass32::setOutputPower(int n) +{ + wifi_power_t p = WIFI_POWER_2dBm; + if (n > 19) + p = WIFI_POWER_19_5dBm; + else if (n > 18) + p = WIFI_POWER_18_5dBm; + else if (n >= 17) + p = WIFI_POWER_17dBm; + else if (n >= 15) + p = WIFI_POWER_15dBm; + else if (n >= 13) + p = WIFI_POWER_13dBm; + else if (n >= 11) + p = WIFI_POWER_11dBm; + else if (n >= 8) + p = WIFI_POWER_8_5dBm; + else if (n >= 7) + p = WIFI_POWER_7dBm; + else if (n >= 5) + p = WIFI_POWER_5dBm; + WiFi.setTxPower(p); +} + +void WiFiClass32::forceSleepBegin() +{ +} + +void WiFiClass32::forceSleepWake() +{ +} + +bool WiFiClass32::getNetworkInfo(uint8_t i, String &ssid, uint8_t &encType, int32_t &rssi, uint8_t *&bssid, int32_t &channel, bool &hidden_scan) +{ + hidden_scan = false; + return WiFi.getNetworkInfo(i, ssid, encType, rssi, bssid, channel); +} + +void wifi_station_disconnect() +{ + // erase ap: empty ssid, ... + WiFi.disconnect(true, true); +} + +void wifi_station_dhcpc_start() +{ +} + +WiFiClass32 WiFi32; diff --git a/libesp32/ESP32-to-ESP8266-compat/src/ESP8266HTTPClient.h b/libesp32/ESP32-to-ESP8266-compat/src/ESP8266HTTPClient.h new file mode 100644 index 000000000..178911e3c --- /dev/null +++ b/libesp32/ESP32-to-ESP8266-compat/src/ESP8266HTTPClient.h @@ -0,0 +1,5 @@ +// +// Compat with ESP32 +// +#include + diff --git a/libesp32/ESP32-to-ESP8266-compat/src/ESP8266WebServer.h b/libesp32/ESP32-to-ESP8266-compat/src/ESP8266WebServer.h new file mode 100644 index 000000000..f00be7b64 --- /dev/null +++ b/libesp32/ESP32-to-ESP8266-compat/src/ESP8266WebServer.h @@ -0,0 +1,19 @@ +// +// Compat with ESP32 +// +#pragma once +#include + +//#define ESP8266WebServer WebServer + + +class ESP8266WebServer : public WebServer +{ +public: + ESP8266WebServer(int port) + :WebServer(port) + { + } +}; + +//#define ENC_TYPE_AUTO 0 diff --git a/libesp32/ESP32-to-ESP8266-compat/src/ESP8266WiFi.h b/libesp32/ESP32-to-ESP8266-compat/src/ESP8266WiFi.h new file mode 100644 index 000000000..09d404e72 --- /dev/null +++ b/libesp32/ESP32-to-ESP8266-compat/src/ESP8266WiFi.h @@ -0,0 +1,85 @@ +/* + WiFi compat with ESP32 + + Copyright (C) 2020 Theo Arends / Jörg Schüler-Maroldt + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +#pragma once +#include + +// sorry, no +#undef LWIP_IPV6 + +#define ENC_TYPE_NONE WIFI_AUTH_OPEN +#define ENC_TYPE_WEP WIFI_AUTH_WEP +#define ENC_TYPE_CCMP WIFI_AUTH_WPA2_PSK +#define ENC_TYPE_TKIP WIFI_AUTH_WPA_WPA2_PSK +#define ENC_TYPE_AUTO WIFI_AUTH_MAX + 1 + +#define WIFI_LIGHT_SLEEP 1 +#define WIFI_MODEM_SLEEP 2 + +class WiFiClass32 : public WiFiClass +{ +public: + static void hostname(const char* aHostname) + { + WiFi.setHostname(aHostname); + } + static void setSleepMode(int iSleepMode); + static int getPhyMode(); + + static void wps_disable(); + static void setOutputPower(int n); + static void forceSleepBegin(); + static void forceSleepWake(); + static bool getNetworkInfo(uint8_t i, String &ssid, uint8_t &encType, int32_t &rssi, uint8_t* &bssid, int32_t &channel, bool &hidden_scan); +}; + +void wifi_station_disconnect(); +void wifi_station_dhcpc_start(); +extern WiFiClass32 WiFi32; +#define WiFi WiFi32 + +class WiFiUDP32 : public WiFiUDP +{ + public: + size_t write(const char*s) + { + return WiFiUDP::write((const uint8_t *)s, strlen(s)); + } + size_t write(const uint8_t *buf, size_t n) + { + return WiFiUDP::write(buf, n); + } + static void stopAll() + { + + } + static void forceSleepWake() + { + + } + uint8_t beginMulticast(IPAddress interfaceAddr, IPAddress multicast, uint16_t port) + { + return WiFiUDP::beginMulticast(multicast, port); + } + void beginPacketMulticast(IPAddress multicast, uint16_t port, IPAddress interfaceAddr) + { + + } +}; + +#define WiFiUDP WiFiUDP32 diff --git a/libesp32/ESP32-to-ESP8266-compat/src/ESP8266httpUpdate.h b/libesp32/ESP32-to-ESP8266-compat/src/ESP8266httpUpdate.h new file mode 100644 index 000000000..0ef8fbbb0 --- /dev/null +++ b/libesp32/ESP32-to-ESP8266-compat/src/ESP8266httpUpdate.h @@ -0,0 +1,10 @@ +// +// Compat with ESP32 +// +#include +#define ESPhttpUpdate httpUpdate + +inline HTTPUpdateResult ESPhttpUpdate_update(const String& url, const String& currentVersion = "") +{ + return HTTP_UPDATE_OK; +} diff --git a/libesp32/ESP32-to-ESP8266-compat/src/ESP8266mDNS.h b/libesp32/ESP32-to-ESP8266-compat/src/ESP8266mDNS.h new file mode 100644 index 000000000..f679ec5fa --- /dev/null +++ b/libesp32/ESP32-to-ESP8266-compat/src/ESP8266mDNS.h @@ -0,0 +1,4 @@ +// +// Compat with ESP32 +// +#include diff --git a/libesp32/ESP32-to-ESP8266-compat/src/c_types.h b/libesp32/ESP32-to-ESP8266-compat/src/c_types.h new file mode 100644 index 000000000..22f551391 --- /dev/null +++ b/libesp32/ESP32-to-ESP8266-compat/src/c_types.h @@ -0,0 +1,6 @@ +#pragma once +/**/ +#include +#ifndef ICACHE_FLASH_ATTR +#define ICACHE_FLASH_ATTR +#endif diff --git a/libesp32/ESP32-to-ESP8266-compat/src/eboot_command.h b/libesp32/ESP32-to-ESP8266-compat/src/eboot_command.h new file mode 100644 index 000000000..992d014ea --- /dev/null +++ b/libesp32/ESP32-to-ESP8266-compat/src/eboot_command.h @@ -0,0 +1,3 @@ +// +// Compat with ESP32 +// diff --git a/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.cpp b/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.cpp new file mode 100644 index 000000000..e15770022 --- /dev/null +++ b/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.cpp @@ -0,0 +1,24 @@ +/* + This library is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + */ +// +#include "Arduino.h" +#include "lwip/apps/sntp.h" +#include +#include +#include +#include "esp8266toEsp32.h" + +// ESP Stuff diff --git a/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h b/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h new file mode 100644 index 000000000..90e2460b3 --- /dev/null +++ b/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h @@ -0,0 +1,142 @@ +/* + This library is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + */ +#pragma once +#ifdef ESP32 +// my debug Stuff +#define Serial_Debug1(p) Serial.printf p +#define Serial_DebugX(p) + +// +// basics +// +// dummy defines +#define SPIFFS_END (SPI_FLASH_SEC_SIZE * 200) +#define SETTINGS_LOCATION SPIFFS_END + +#include + + +// webcam uses channel 0, so we offset standard PWM +#define PWM_CHANNEL_OFFSET 2 +// Analog + +uint8_t pwm_channel[8]={99,99,99,99,99,99,99,99}; + +inline uint32_t pin2chan(uint32_t pin) { + for (uint32_t cnt=0;cnt<8;cnt++) { + if ((pwm_channel[cnt]<99) && (pwm_channel[cnt]==pin)) { + return cnt; + } + } + return 0; +} + +inline void analogWrite(uint8_t pin, int val) +{ + uint32_t channel=pin2chan(pin); + ledcWrite(channel+PWM_CHANNEL_OFFSET,val); + //Serial.printf("write %d - %d\n",channel,val); +} + +inline void analogWriteFreq(uint32_t freq) +{ +} +inline void analogWriteRange(uint32_t range) +{ +} + +inline void analogAttach(uint32_t pin, uint32_t channel) { + pwm_channel[channel&7]=pin; + ledcAttachPin(pin,channel+PWM_CHANNEL_OFFSET); + //Serial.printf("attach %d - %d\n",channel,pin); +} + +inline uint32_t pow2(uint32_t x) { +uint32_t power = 1,bits=0; + while (power < x) { + power*=2; + bits++; + } + return bits-1; +} +// input range is in full range, ledc needs bits +inline void analogWriteFreqRange(uint32_t channel,uint32_t freq, uint32_t irange) { + uint32_t range=pow2(irange); + for (uint32_t cnt=0;cnt<8;cnt++) { + if (pwm_channel[cnt]<99) { + ledcSetup(cnt+PWM_CHANNEL_OFFSET,freq,range); + } + } + //Serial.printf("freq - range %d - %d\n",freq,range); +} + +#define INPUT_PULLDOWN_16 INPUT_PULLUP + +typedef double real64_t; + +// +// Time and Timer +// +#define ETS_UART_INTR_DISABLE() +#define ETS_UART_INTR_ENABLE() + +#define ESPhttpUpdate httpUpdate +#define getFlashChipRealSize() getFlashChipSize() + +#define os_delay_us ets_delay_us +// Serial minimal type to hold the config +typedef int SerConfu8; +typedef int SerialConfig; +//#define analogWrite(a, b) + +// +// WS2812 +// +#define NeoEsp8266BitBang800KbpsMethod NeoEsp32BitBang800KbpsMethod +// +// UDP +// +//#define PortUdp_writestr(log_data) PortUdp.write((const uint8_t *)(log_data), strlen(log_data)) +#define PortUdp_write(log_data, n) PortUdp.write((const uint8_t *)(log_data), n) + +// +#define wifi_forceSleepBegin() + +#undef LWIP_IPV6 + +#define REASON_DEFAULT_RST 0 // "Power on" normal startup by power on +#define REASON_WDT_RST 1 // "Hardware Watchdog" hardware watch dog reset +#define REASON_EXCEPTION_RST 2 // "Exception" exception reset, GPIO status won’t change +#define REASON_SOFT_WDT_RST 3 // "Software Watchdog" software watch dog reset, GPIO status won’t change +#define REASON_SOFT_RESTART 4 // "Software/System restart" software restart ,system_restart , GPIO status won’t change +#define REASON_DEEP_SLEEP_AWAKE 5 // "Deep-Sleep Wake" wake up from deep-sleep +#define REASON_EXT_SYS_RST 6 // "External System" external system reset + +// memmove ... +#define memcpy_P memcpy +#define memmove_P memmove +#define strncpy_P strncpy +#define strcmp_P strcmp +#define memccpy_P memccpy +#define snprintf_P snprintf +#define sprintf_P sprintf +#define strncmp_P strncmp + +// LWIP STuff + +#define STATION_IF 0 + +#endif diff --git a/libesp32/ESP32-to-ESP8266-compat/src/ets_sys.h b/libesp32/ESP32-to-ESP8266-compat/src/ets_sys.h new file mode 100644 index 000000000..30a7e7733 --- /dev/null +++ b/libesp32/ESP32-to-ESP8266-compat/src/ets_sys.h @@ -0,0 +1,3 @@ +#pragma once +#define timercallback void* +#define ets_printf(...) diff --git a/libesp32/ESP32-to-ESP8266-compat/src/gpio.h b/libesp32/ESP32-to-ESP8266-compat/src/gpio.h new file mode 100644 index 000000000..0ff47d6a2 --- /dev/null +++ b/libesp32/ESP32-to-ESP8266-compat/src/gpio.h @@ -0,0 +1,2 @@ +#pragma once +#define GPIO_STATUS_W1TC_ADDRESS 0x24 diff --git a/libesp32/ESP32-to-ESP8266-compat/src/os_type.h b/libesp32/ESP32-to-ESP8266-compat/src/os_type.h new file mode 100644 index 000000000..a9e1558f5 --- /dev/null +++ b/libesp32/ESP32-to-ESP8266-compat/src/os_type.h @@ -0,0 +1,6 @@ +#pragma once +#include "esp8266-compat.h" +#include +#include +typedef uint16 uint16_t; +typedef double real64_t; diff --git a/libesp32/ESP32-to-ESP8266-compat/src/osapi.h b/libesp32/ESP32-to-ESP8266-compat/src/osapi.h new file mode 100644 index 000000000..947de57cc --- /dev/null +++ b/libesp32/ESP32-to-ESP8266-compat/src/osapi.h @@ -0,0 +1,8 @@ +#pragma once +/**/ +#include +/* +#ifndef ICACHE_FLASH_ATTR +#define ICACHE_FLASH_ATTR +#endif +*/ diff --git a/libesp32/ESP32-to-ESP8266-compat/src/sntp.h b/libesp32/ESP32-to-ESP8266-compat/src/sntp.h new file mode 100644 index 000000000..2d92438d5 --- /dev/null +++ b/libesp32/ESP32-to-ESP8266-compat/src/sntp.h @@ -0,0 +1,7 @@ +#pragma once +#define sntp_get_current_timestamp() SntpGetCurrentTimestamp() +#define sntp_init() SntpInit() +#define sntp_set_timezone(tz) +#define sntp_setservername(idx, name) +#define sntp_stop() + diff --git a/libesp32/ESP32-to-ESP8266-compat/src/spi_flash.h b/libesp32/ESP32-to-ESP8266-compat/src/spi_flash.h new file mode 100644 index 000000000..fffa3c3a0 --- /dev/null +++ b/libesp32/ESP32-to-ESP8266-compat/src/spi_flash.h @@ -0,0 +1,4 @@ +// +// Compat with ESP32 +// +// TODO: Port it to ESP32 diff --git a/libesp32/ESP32-to-ESP8266-compat/src/twi.h b/libesp32/ESP32-to-ESP8266-compat/src/twi.h new file mode 100644 index 000000000..eaf51d122 --- /dev/null +++ b/libesp32/ESP32-to-ESP8266-compat/src/twi.h @@ -0,0 +1,2 @@ +#pragma once +/**/ \ No newline at end of file diff --git a/libesp32/ESP32-to-ESP8266-compat/src/user_interface.h b/libesp32/ESP32-to-ESP8266-compat/src/user_interface.h new file mode 100644 index 000000000..ee38dfb21 --- /dev/null +++ b/libesp32/ESP32-to-ESP8266-compat/src/user_interface.h @@ -0,0 +1,24 @@ +/* + This library is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +#ifndef user_interface_h +#define user_interface_h +enum wps_cb_status { + WPS_CB_ST_SUCCESS = 0, + WPS_CB_ST_FAILED, + WPS_CB_ST_TIMEOUT, + WPS_CB_ST_WEP, + WPS_CB_ST_UNK, +}; +#endif diff --git a/libesp32/ESP32README.md b/libesp32/ESP32README.md new file mode 100644 index 000000000..1cb4e3c42 --- /dev/null +++ b/libesp32/ESP32README.md @@ -0,0 +1,46 @@ +![Tasmota logo](/tools/logo/TASMOTA_FullLogo_Vector.svg) + +## ESP32 port with minimal changes +## Description: +This is my esp32 port, i try to make only minimal changes to the original source code +from Theo Arends, now again for development branch. + +## Checklist: + - [x] The pull request is done against the latest dev branch + - [x] Only relevant files were touched + - [x] Only one feature/fix was added per PR. + - [x] The code change is tested and works on core Tasmota_core_stage + - [ ] The code change pass travis tests. **Your PR cannot be merged unless tests pass** + - [x] I accept the [CLA](https://github.com/arendst/Tasmota/blob/development/CONTRIBUTING.md#contributor-license-agreement-cla). + - [x] i checked binary "tasmota.bin" to be the same in development and development_esp32 branch + +Here are the main things i have done + +- in "lib_extra_dirs" i have libesp32 directory for things missing in ESP32 framework + my "ESP32-to-ESP8266-compat" has all files that are not available in ESP32 + so you dont have to change the source code and i write code to get the informations from ESP32 +- all librarys that are not compatibel i add to lib_ignore +- all code that is not for ESP32 i put in "#ifdef ESP8266" the define is from espessif platform +- all code for ESP32 is in "#ifdef ESP32" +- SerConfu8 type uint8_t for SerialConfig list +- changed "HTTP_HEADER" to "HTTP_HEADER1", in ESP32 its an enum +- for ip adress 0 i used IPAddress(0,0,0,0) +- Special ESP.xxx call i change to ESP_xxx (ESP_rtcUserMemoryWrite, ...) and write macros for ESP8266 +- because ESP32 has only WEMOS 32 modul, i exclude all code like this: + "if (SONOFF_xxx == Settings.module)" in "#ifdef ESP8266" +- variable "sleep" i changed to "ssleep" because of standard library sleep(..) function +- all esp32 stuff is in support_esp32.ino +- in tasmota.ino i include "tasmota_compat.h" +- in tasmota_template.h i use ifdef and tasmota_templESP32.h +- defines for sensors that currently don't work, i undef in tasmota_templESP32.h +- comment fo "no warnig" in "xdrv_20_hue.ino" thats the only warning i had + +Build info + +Copy platformio_override_esp32.ini to platformio_override.ini an select your imagetype. +You can build tasmota and tasmota32 Version with one build. +If you need other versions change platformio_override.ini + +stay at home, have fun and keep good + +Jörg \ No newline at end of file diff --git a/libesp32/NimBLE-Arduino/API_DIFFERENCES.md b/libesp32/NimBLE-Arduino/API_DIFFERENCES.md new file mode 100644 index 000000000..91b0fd78f --- /dev/null +++ b/libesp32/NimBLE-Arduino/API_DIFFERENCES.md @@ -0,0 +1,245 @@ +# Server API differnces: + +### Characteristics: +When creating a characteristic the properties are now set with `NIMBLE_PROPERTY::XXXX` instead of `BLECharacteristic::XXXX`. + +#### Previous: +``` +BLECharacteristic::PROPERTY_READ | +BLECharacteristic::PROPERTY_WRITE +``` + +#### Changed to: +``` +NIMBLE_PROPERTY::READ | +NIMBLE_PROPERTY::WRITE +``` + +#### The full list of properties: +``` +NIMBLE_PROPERTY::READ +NIMBLE_PROPERTY::READ_ENC +NIMBLE_PROPERTY::READ_AUTHEN +NIMBLE_PROPERTY::READ_AUTHOR +NIMBLE_PROPERTY::WRITE +NIMBLE_PROPERTY::WRITE_NR +NIMBLE_PROPERTY::WRITE_ENC +NIMBLE_PROPERTY::WRITE_AUTHEN +NIMBLE_PROPERTY::WRITE_AUTHOR +NIMBLE_PROPERTY::BROADCAST +NIMBLE_PROPERTY::NOTIFY +NIMBLE_PROPERTY::INDICATE +``` + +### Descriptors: +Descriptors are now created using the NimBLEcharacteristic method `createDescriptor()`. + +The previous method `addDescriptor()` is now a private function in the library. + +This was done because the NimBLE host automatically creates a 0x2902 descriptor if a characteristic has notify or indicate properties applied. +Due to this fact, this library also creates one automatically for your application. +The only reason to manually create this descriptor now is to assign callback functions. +If you do not require this functionality you can safely exclude the manual creation of that descriptor. + + +For any other descriptor, (except 0x2904, see below) it should now be created just as characteristics are +by invoking the `NimBLECharacteristic::createDescriptor` methods. +Which are defined as: +``` +NimBLEDescriptor* createDescriptor(const char* uuid, + uint32_t properties = NIMBLE_PROPERTY::READ | + NIMBLE_PROPERTY::WRITE, + uint16_t max_len = 100); + +NimBLEDescriptor* createDescriptor(NimBLEUUID uuid, + uint32_t properties = NIMBLE_PROPERTY::READ | + NIMBLE_PROPERTY::WRITE, + uint16_t max_len = 100); +``` +##### Example: +``` +pDescriptor = pCharacteristic->createDescriptor("ABCD", + NIMBLE_PROPERTY::READ | + NIMBLE_PROPERTY::WRITE | + NIMBLE_PROPERTY::WRITE_ENC, + 25);` +``` +Would create a descriptor with the UUID 0xABCD, publicly readable but only writable if paired/bonded (encrypted) and has a max value length of 25 bytes. + +For the 0x2904 descriptor, there is a special class that is created when you call `createDescriptor("2904")`. + +The pointer returned is of the base class `NimBLEDescriptor` but the call will create the derived class of `NimBLE2904` so you must cast the returned pointer to `NimBLE2904*` to access the specific class methods. + +##### Example: +``` +p2904 = (NimBLE2904*)pCharacteristic->createDescriptor("2904"); +``` + +#### Server Security: +Security is set on the characteristic or descriptor properties by applying one of the following: +``` +NIMBLE_PROPERTY::READ_ENC +NIMBLE_PROPERTY::READ_AUTHEN +NIMBLE_PROPERTY::READ_AUTHOR +NIMBLE_PROPERTY::WRITE_ENC +NIMBLE_PROPERTY::WRITE_AUTHEN +NIMBLE_PROPERTY::WRITE_AUTHOR +``` +When a peer wants to read or write a characteristic or descriptor with any of these properties applied +it will trigger the pairing process. By default the "just-works" pairing will be performed automatically. +This can be changed to use passkey authentication or numeric confirmation. See below for details. + + +# Client API Differences: +The `BLEAdvertisedDeviceCallbacks` class `onResult()` method now receives a pointer to the +`NimBLEAdvertisedDevice` object instead of a copy. + +`NimBLEClient::connect()` now takes an extra parameter to indicate if the client should download the services + database from the peripheral, default value is true. + +Defined as: +``` +bool connect(NimBLEAdvertisedDevice* device, bool refreshServices = true); +bool connect(NimBLEAddress address, uint8_t type = BLE_ADDR_PUBLIC, bool refreshServices = true); +``` +If set to false the client will use the services database it retrieved from the peripheral last time it connected. +This allows for faster connections and power saving if the devices just dropped connection and want to reconnect. + +``` +NimBLERemoteCharacteristic::writeValue(); +NimBLERemoteCharacteristic::registerForNotify(); +``` +Now return true or false to indicate success or failure so you can choose to disconnect or try again. + +``` +NimBLEClient::getServices() +NimBLERemoteService::getCharacteristics() +``` +Now return a pointer to a `std::vector` of the respective object database instead of `std::map`. + +`NimBLERemoteService::getCharacteristicsByHandle()` +Has been removed from the API as it is no longer maintained in the library. + +The last two above changes reduce the heap usage significantly with minimal application code adjustments. + +**UPDATED** on June 21, 2020 +> ``` +> NimBLEClient::getServices(bool refresh = false) +> NimBLERemoteService::getCharacteristics(bool refresh = false) +> NimBLERemoteCharacteristic::getDecriptors(bool refresh = false) +>``` +These methods now take an optional (bool) parameter. +If true it will clear the respective vector and retrieve all the respective attributes from the peripheral. +If false(default) it will return the respective vector empty or otherwise with the currently stored attributes. + +**Removed:** the automatic discovery of all peripheral attributes as they consumed time and resources for data +the user may not be interested in. + +**Added:** `NimBLEClient::discoverAtrributes()` for the user to discover all the peripheral attributes +to replace the the former functionality. + + +> ``` +>getService(NimBLEUUID) +>getCharacteristic(NimBLEUUID) +>getDescriptor(NimBLEUUID) +>``` +These methods will now check the respective vectors for the attribute object and, if not found, will retrieve (only) +the specified attribute from the peripheral. + +These changes allow more control for the user to manage the resources used for the attributes. +*** +#### Client Security: +The client will automatically initiate security when the peripheral responds that it's required. +The default configuration will use "just-works" pairing with no bonding, if you wish to enable bonding see below. + + +# Security: +Security callback functions are now incorporated in the client/server Callbacks class. +However backward compatibility with the `BLESecurity` class is retained to minimize app code changes. + +The relevant server callbacks are defined as: +``` +bool onConfirmPIN(uint32_t pin); // accept or reject the passkey +void onAuthenticationComplete(ble_gap_conn_desc* desc); // auth complete - details in desc +bool onPassKeyNotify(uint32_t pass_key); // receive the passkey sent by the client, accept or reject +``` +The relevant client callbacks are defined as: +``` +bool onConfirmPIN(uint32_t pin); // accept or reject the passkey +void onAuthenticationComplete(ble_gap_conn_desc* desc); // auth complete - details in desc +uint32_t onPassKeyRequest(); // return the passkey to send to the server +``` + +Security settings and IO capabilities are now set by the corresponding method of `NimBLEDevice::`. +``` +static void setSecurityAuth(bool bonding, bool mitm, bool sc); +static void setSecurityAuth(uint8_t auth_req); +static void setSecurityIOCap(uint8_t iocap); +static void setSecurityInitKey(uint8_t init_key); +static void setSecurityRespKey(uint8_t init_key); + + +/** + * @brief Set the authorization mode for this device. + * @param bonding, if true we allow bonding, false no bonding will be performed. + * @param mitm, if true we are capable of man in the middle protection, false if not. + * @param sc, if true we will perform secure connection pairing, false we will use legacy pairing. + */ +void NimBLEDevice::setSecurityAuth(bool bonding, bool mitm, bool sc) + + + +/** + * @brief Set the authorization mode for this device. + * @param A bitmap indicating what modes are supported. + * The bits are defined as follows: + ** 0x01 BLE_SM_PAIR_AUTHREQ_BOND + ** 0x04 BLE_SM_PAIR_AUTHREQ_MITM + ** 0x08 BLE_SM_PAIR_AUTHREQ_SC + ** 0x10 BLE_SM_PAIR_AUTHREQ_KEYPRESS - not yet supported. + ** 0xe2 BLE_SM_PAIR_AUTHREQ_RESERVED - for reference only. + */ +void NimBLEDevice::setSecurityAuth(uint8_t auth_req) + + + +/** + * @brief Set the Input/Output capabilities of this device. + * @param One of the following: + ** 0x00 BLE_HS_IO_DISPLAY_ONLY DisplayOnly IO capability + ** 0x01 BLE_HS_IO_DISPLAY_YESNO DisplayYesNo IO capability + ** 0x02 BLE_HS_IO_KEYBOARD_ONLY KeyboardOnly IO capability + ** 0x03 BLE_HS_IO_NO_INPUT_OUTPUT NoInputNoOutput IO capability + ** 0x04 BLE_HS_IO_KEYBOARD_DISPLAY KeyboardDisplay Only IO capability + */ +void NimBLEDevice::setSecurityIOCap(uint8_t iocap) + + + +/** + * @brief If we are the initiator of the security procedure this sets the keys we will distribute. + * @param A bitmap indicating which keys to distribute during pairing. + * The bits are defined as follows: + ** 0x01: BLE_SM_PAIR_KEY_DIST_ENC - Distribute the encryption key. + ** 0x02: BLE_SM_PAIR_KEY_DIST_ID - Distribute the ID key (IRK). + ** 0x04: BLE_SM_PAIR_KEY_DIST_SIGN + ** 0x08: BLE_SM_PAIR_KEY_DIST_LINK + */ +void NimBLEDevice::setSecurityInitKey(uint8_t init_key) + + +/** + * @brief Set the keys we are willing to accept during pairing. + * @param A bitmap indicating which keys to accept during pairing. + * The bits are defined as follows: + ** 0x01: BLE_SM_PAIR_KEY_DIST_ENC - Accept the encryption key. + ** 0x02: BLE_SM_PAIR_KEY_DIST_ID - Accept the ID key (IRK). + ** 0x04: BLE_SM_PAIR_KEY_DIST_SIGN + ** 0x08: BLE_SM_PAIR_KEY_DIST_LINK + */ +void NimBLEDevice::setSecurityRespKey(uint8_t init_key) +``` + + I'm sure there are more things I have forgotten but this is all the majors. + I will update this document as necessary. diff --git a/libesp32/NimBLE-Arduino/LICENSE b/libesp32/NimBLE-Arduino/LICENSE new file mode 100644 index 000000000..4abe69699 --- /dev/null +++ b/libesp32/NimBLE-Arduino/LICENSE @@ -0,0 +1,219 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {2020} {Ryan Powell} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +This product bundles queue.h 8.5, which is available under the "3-clause BSD" +license. For details, see porting/nimble/include/os/queue.h + +This product partly derives from FreeBSD, which is available under the +"3-clause BSD" license. For details, see: + * porting/nimble/src/os_mbuf.c + +This product bundles Gary S. Brown's CRC32 implementation, which is available +under the following license: + COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or + code or tables extracted from it, as desired without restriction. + +This product bundles tinycrypt, which is available under the "3-clause BSD" +license. For details, and bundled files see: + * ext/tinycrypt/LICENSE + +This product partly derives from esp32-snippets; Copyright 2017 Neil Kolban. \ No newline at end of file diff --git a/libesp32/NimBLE-Arduino/README.md b/libesp32/NimBLE-Arduino/README.md new file mode 100644 index 000000000..04c3a80c5 --- /dev/null +++ b/libesp32/NimBLE-Arduino/README.md @@ -0,0 +1,97 @@ +# *** UPDATES *** +**Breaking changes:** +**NEW** on June 21, 2020 +> ``` +> NimBLEClient::getServices(bool refresh = false) +> NimBLERemoteService::getCharacteristics(bool refresh = false) +> NimBLERemoteCharacteristic::getDecriptors(bool refresh = false) +>``` +These methods now take an optional (bool) parameter. +If true it will clear the respective vector and retrieve all the respective attributes from the peripheral. +If false(default) it will return the respective vector empty or otherwise with the currently stored attributes. + +**NEW** on May 23, 2020 +Client and scan now use `std::vector` instead of `std::map` for storing the remote attribute database. + +This change will affect your application code if you use `NimBLEClient::getServices()` or `NimBLERemoteService::getCharacteristics()` +in your application as they now return a pointer to `std::vector` of the respective attributes. + +In addition `NimBLERemoteService::getCharacteristicsByHandle()` has been removed as it is no longer maintained in the library. + +These changes were necessary due to the amount of resources required to use `std::map`, it was not justifed by any benfit it provided. + +It is expected that there will be minimal impact on most applications, if you need help adjusting your code please create an issue. + +# NimBLE-Arduino +A fork of the NimBLE stack restructured for compilation in the Ardruino IDE with a CPP library for use with ESP32. + +This library **significantly** reduces resource usage and improves performance for ESP32 BLE applications as compared +with the bluedroid based library. The goal is to maintain, as much as reasonable, compatibility with the original +library but refactored to use the NimBLE stack. In addition, this library will be more actively developed and maintained +to provide improved capabilites and stability over the original. + +## Resource use improvement: + +### (Original) BLE_client example comparison (Debug): +#### Arduino BLE Library +Sketch uses **1216377** bytes (58%) of program storage space. +Memory after connection: Free Heap: **171548** + +#### NimBLE-Arduino library +Sketch uses **617256** bytes (29%) of program storage space. +Memory after connection: Free Heap: **270336** +*** +### (Original) BLE_notify example comparison (Debug): +#### Arduino BLE Library +Sketch uses **1208409** bytes (57%) of program storage space. +Memory after connection: Free Heap: **173300** + +#### NimBLE-Arduino library +Sketch uses **603432** bytes (28%) of program storage space. +Memory after connection: Free Heap: **269792** + +**As shown: there is nearly a 50% reduction in flash use and approx. 100kB less ram consumed!** + + +# Installation: + +Download as .zip and extract to Arduino/libraries folder, or in Arduino IDE from Sketch menu -> Include library -> Add .Zip library. + +`#include "NimBLEDevice.h"` at the beginning of your sketch. + +Tested and working with esp32-arduino v1.0.2 and 1.0.4 in Arduino IDE v1.8.12 and platform IO. + + +# Usage: + +This library is intended to be compatible with the original ESP32 BLE functions and types with minor changes. + +Check the Refactored_original_examples in the examples folder for highlights of the differences with the original library. + +More advanced examples highlighting many available features are in examples/ NimBLE_Server, NimBLE_Client. + +Beacon examples provided by @beegee-tokyo are in examples/ BLE_Beacon_Scanner, BLE_EddystoneTLM_Beacon, BLE_EddystoneURL_Beacon. + +Change the settings in the `nimconfig.h` file to customize NimBLE to your project, such as increasing max connections, default is 3. + + +# Continuing development: + +This Library is tracking the esp-nimble repo, nimble-1.2.0-idf master branch, currently [@46c1d9f.](https://github.com/espressif/esp-nimble) + +Also tracking the NimBLE related changes in esp-idf, master branch, currently [@2ef4890.](https://github.com/espressif/esp-idf/tree/master/components/bt/host/nimble) + +# Acknowledgments: + +* @nkolban and @chegewara for the [original esp32 BLE library](https://github.com/nkolban/esp32-snippets) this project was derived from. +* @beegee-tokyo for contributing your time to test/debug and contributing the beacon examples. +* @Jeroen88 for the amazing help debugging and improving the client code. + + +# Todo: + +1. Create documentation. +2. Add BLE Mesh code. +3. Expose more NimBLE features. + + diff --git a/libesp32/NimBLE-Arduino/examples/BLE_Beacon_Scanner/BLE_Beacon_Scanner.ino b/libesp32/NimBLE-Arduino/examples/BLE_Beacon_Scanner/BLE_Beacon_Scanner.ino new file mode 100644 index 000000000..fea6b7d50 --- /dev/null +++ b/libesp32/NimBLE-Arduino/examples/BLE_Beacon_Scanner/BLE_Beacon_Scanner.ino @@ -0,0 +1,164 @@ +/* + Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleScan.cpp + Ported to Arduino ESP32 by Evandro Copercini +*/ + +/** NimBLE differences highlighted in comment blocks **/ + +/*******original******** + #include + #include + #include + #include + #include "BLEEddystoneURL.h" + #include "BLEEddystoneTLM.h" + #include "BLEBeacon.h" +***********************/ + +#include + +#include +#include +#include "NimBLEEddystoneURL.h" +#include "NimBLEEddystoneTLM.h" +#include "NimBLEBeacon.h" + +#define ENDIAN_CHANGE_U16(x) ((((x)&0xFF00) >> 8) + (((x)&0xFF) << 8)) + +int scanTime = 5; //In seconds +BLEScan *pBLEScan; + +class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks +{ + /*** Only a reference to the advertised device is passed now + void onResult(BLEAdvertisedDevice advertisedDevice) { **/ + void onResult(BLEAdvertisedDevice *advertisedDevice) + { + if (advertisedDevice->haveName()) + { + Serial.print("Device name: "); + Serial.println(advertisedDevice->getName().c_str()); + Serial.println(""); + } + + if (advertisedDevice->haveServiceUUID()) + { + BLEUUID devUUID = advertisedDevice->getServiceUUID(); + Serial.print("Found ServiceUUID: "); + Serial.println(devUUID.toString().c_str()); + Serial.println(""); + } + else + { + if (advertisedDevice->haveManufacturerData() == true) + { + std::string strManufacturerData = advertisedDevice->getManufacturerData(); + + uint8_t cManufacturerData[100]; + strManufacturerData.copy((char *)cManufacturerData, strManufacturerData.length(), 0); + + if (strManufacturerData.length() == 25 && cManufacturerData[0] == 0x4C && cManufacturerData[1] == 0x00) + { + Serial.println("Found an iBeacon!"); + BLEBeacon oBeacon = BLEBeacon(); + oBeacon.setData(strManufacturerData); + Serial.printf("iBeacon Frame\n"); + Serial.printf("ID: %04X Major: %d Minor: %d UUID: %s Power: %d\n", oBeacon.getManufacturerId(), ENDIAN_CHANGE_U16(oBeacon.getMajor()), ENDIAN_CHANGE_U16(oBeacon.getMinor()), oBeacon.getProximityUUID().toString().c_str(), oBeacon.getSignalPower()); + } + else + { + Serial.println("Found another manufacturers beacon!"); + Serial.printf("strManufacturerData: %d ", strManufacturerData.length()); + for (int i = 0; i < strManufacturerData.length(); i++) + { + Serial.printf("[%X]", cManufacturerData[i]); + } + Serial.printf("\n"); + } + } + return; + } + + uint8_t *payLoad = advertisedDevice->getPayload(); + + BLEUUID checkUrlUUID = (uint16_t)0xfeaa; + + if (advertisedDevice->getServiceUUID().equals(checkUrlUUID)) + { + if (payLoad[11] == 0x10) + { + Serial.println("Found an EddystoneURL beacon!"); + BLEEddystoneURL foundEddyURL = BLEEddystoneURL(); + std::string eddyContent((char *)&payLoad[11]); // incomplete EddystoneURL struct! + + foundEddyURL.setData(eddyContent); + std::string bareURL = foundEddyURL.getURL(); + if (bareURL[0] == 0x00) + { + size_t payLoadLen = advertisedDevice->getPayloadLength(); + Serial.println("DATA-->"); + for (int idx = 0; idx < payLoadLen; idx++) + { + Serial.printf("0x%08X ", payLoad[idx]); + } + Serial.println("\nInvalid Data"); + return; + } + + Serial.printf("Found URL: %s\n", foundEddyURL.getURL().c_str()); + Serial.printf("Decoded URL: %s\n", foundEddyURL.getDecodedURL().c_str()); + Serial.printf("TX power %d\n", foundEddyURL.getPower()); + Serial.println("\n"); + } + else if (payLoad[11] == 0x20) + { + Serial.println("Found an EddystoneTLM beacon!"); + BLEEddystoneTLM foundEddyURL = BLEEddystoneTLM(); + std::string eddyContent((char *)&payLoad[11]); // incomplete EddystoneURL struct! + + eddyContent = "01234567890123"; + + for (int idx = 0; idx < 14; idx++) + { + eddyContent[idx] = payLoad[idx + 11]; + } + + foundEddyURL.setData(eddyContent); + Serial.printf("Reported battery voltage: %dmV\n", foundEddyURL.getVolt()); + Serial.printf("Reported temperature from TLM class: %.2fC\n", (double)foundEddyURL.getTemp()); + int temp = (int)payLoad[16] + (int)(payLoad[15] << 8); + float calcTemp = temp / 256.0f; + Serial.printf("Reported temperature from data: %.2fC\n", calcTemp); + Serial.printf("Reported advertise count: %d\n", foundEddyURL.getCount()); + Serial.printf("Reported time since last reboot: %ds\n", foundEddyURL.getTime()); + Serial.println("\n"); + Serial.print(foundEddyURL.toString().c_str()); + Serial.println("\n"); + } + } + } +}; + +void setup() +{ + Serial.begin(115200); + Serial.println("Scanning..."); + + BLEDevice::init(""); + pBLEScan = BLEDevice::getScan(); //create new scan + pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks()); + pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster + pBLEScan->setInterval(100); + pBLEScan->setWindow(99); // less or equal setInterval value +} + +void loop() +{ + // put your main code here, to run repeatedly: + BLEScanResults foundDevices = pBLEScan->start(scanTime, false); + Serial.print("Devices found: "); + Serial.println(foundDevices.getCount()); + Serial.println("Scan done!"); + pBLEScan->clearResults(); // delete results fromBLEScan buffer to release memory + delay(2000); +} diff --git a/libesp32/NimBLE-Arduino/examples/BLE_Beacon_Scanner/BLE_Beacon_Scanner.md b/libesp32/NimBLE-Arduino/examples/BLE_Beacon_Scanner/BLE_Beacon_Scanner.md new file mode 100644 index 000000000..558c3e7ae --- /dev/null +++ b/libesp32/NimBLE-Arduino/examples/BLE_Beacon_Scanner/BLE_Beacon_Scanner.md @@ -0,0 +1,9 @@ +## BLE Beacon Scanner + +Initiates a BLE device scan. +Checks if the discovered devices are +- an iBeacon +- an Eddystone TLM beacon +- an Eddystone URL beacon + +and sends the decoded beacon information over Serial log \ No newline at end of file diff --git a/libesp32/NimBLE-Arduino/examples/BLE_EddystoneTLM_Beacon/BLE_EddystoneTLM_Beacon.ino b/libesp32/NimBLE-Arduino/examples/BLE_EddystoneTLM_Beacon/BLE_EddystoneTLM_Beacon.ino new file mode 100644 index 000000000..32e0b1e99 --- /dev/null +++ b/libesp32/NimBLE-Arduino/examples/BLE_EddystoneTLM_Beacon/BLE_EddystoneTLM_Beacon.ino @@ -0,0 +1,113 @@ +/* + EddystoneTLM beacon for NimBLE by BeeGee based on https://github.com/pcbreflux/espressif/blob/master/esp32/arduino/sketchbook/ESP32_Eddystone_TLM_deepsleep/ESP32_Eddystone_TLM_deepsleep.ino + EddystoneTLM frame specification https://github.com/google/eddystone/blob/master/eddystone-tlm/tlm-plain.md +*/ + +/* + Create a BLE server that will send periodic Eddystone URL frames. + The design of creating the BLE server is: + 1. Create a BLE Server + 2. Create advertising data + 3. Start advertising. + 4. wait + 5. Stop advertising. + 6. deep sleep + +*/ + +#include "NimBLEDevice.h" +#include "NimBLEBeacon.h" +#include "NimBLEAdvertising.h" +#include "NimBLEEddystoneURL.h" + +#include "sys/time.h" +#include "esp_sleep.h" + +#define GPIO_DEEP_SLEEP_DURATION 10 // sleep x seconds and then wake up + +// UUID 1 128-Bit (may use linux tool uuidgen or random numbers via https://www.uuidgenerator.net/) +#define BEACON_UUID "8ec76ea3-6668-48da-9866-75be8bc86f4d" + +RTC_DATA_ATTR static time_t last; // remember last boot in RTC Memory +RTC_DATA_ATTR static uint32_t bootcount; // remember number of boots in RTC Memory + +BLEAdvertising *pAdvertising; +struct timeval nowTimeStruct; + +time_t lastTenth; + +// Check +// https://github.com/google/eddystone/blob/master/eddystone-tlm/tlm-plain.md +// and http://www.hugi.scene.org/online/coding/hugi%2015%20-%20cmtadfix.htm +// for the temperature value. It is a 8.8 fixed-point notation +void setBeacon() +{ + char beacon_data[25]; + uint16_t beconUUID = 0xFEAA; + uint16_t volt = random(2800, 3700); // 3300mV = 3.3V + float tempFloat = random(2000, 3100) / 100.0f; + Serial.printf("Random temperature is %.2fC\n", tempFloat); + int temp = (int)(tempFloat * 256); //(uint16_t)((float)23.00); + Serial.printf("Converted to 8.8 format %0X%0X\n", (temp >> 8), (temp & 0xFF)); + + BLEAdvertisementData oAdvertisementData = BLEAdvertisementData(); + BLEAdvertisementData oScanResponseData = BLEAdvertisementData(); + + oScanResponseData.setFlags(0x06); // GENERAL_DISC_MODE 0x02 | BR_EDR_NOT_SUPPORTED 0x04 + oScanResponseData.setCompleteServices(BLEUUID(beconUUID)); + + beacon_data[0] = 0x20; // Eddystone Frame Type (Unencrypted Eddystone-TLM) + beacon_data[1] = 0x00; // TLM version + beacon_data[2] = (volt >> 8); // Battery voltage, 1 mV/bit i.e. 0xCE4 = 3300mV = 3.3V + beacon_data[3] = (volt & 0xFF); // + beacon_data[4] = (temp >> 8); // Beacon temperature + beacon_data[5] = (temp & 0xFF); // + beacon_data[6] = ((bootcount & 0xFF000000) >> 24); // Advertising PDU count + beacon_data[7] = ((bootcount & 0xFF0000) >> 16); // + beacon_data[8] = ((bootcount & 0xFF00) >> 8); // + beacon_data[9] = (bootcount & 0xFF); // + beacon_data[10] = ((lastTenth & 0xFF000000) >> 24); // Time since power-on or reboot as 0.1 second resolution counter + beacon_data[11] = ((lastTenth & 0xFF0000) >> 16); // + beacon_data[12] = ((lastTenth & 0xFF00) >> 8); // + beacon_data[13] = (lastTenth & 0xFF); // + + oScanResponseData.setServiceData(BLEUUID(beconUUID), std::string(beacon_data, 14)); + oAdvertisementData.setName("TLMBeacon"); + pAdvertising->setAdvertisementData(oAdvertisementData); + pAdvertising->setScanResponseData(oScanResponseData); +} + +void setup() +{ + + Serial.begin(115200); + gettimeofday(&nowTimeStruct, NULL); + + Serial.printf("start ESP32 %d\n", bootcount++); + + Serial.printf("deep sleep (%lds since last reset, %lds since last boot)\n", nowTimeStruct.tv_sec, nowTimeStruct.tv_sec - last); + + last = nowTimeStruct.tv_sec; + lastTenth = nowTimeStruct.tv_sec * 10; // Time since last reset as 0.1 second resolution counter + + // Create the BLE Device + BLEDevice::init("TLMBeacon"); + + BLEDevice::setPower(ESP_PWR_LVL_N12); + + pAdvertising = BLEDevice::getAdvertising(); + + setBeacon(); + // Start advertising + pAdvertising->start(); + Serial.println("Advertizing started for 10s ..."); + delay(10000); + pAdvertising->stop(); + Serial.printf("enter deep sleep for 10s\n"); + esp_deep_sleep(1000000LL * GPIO_DEEP_SLEEP_DURATION); + Serial.printf("in deep sleep\n"); +} + +void loop() +{ +} diff --git a/libesp32/NimBLE-Arduino/examples/BLE_EddystoneTLM_Beacon/BLE_EddystoneTLM_Beacon.md b/libesp32/NimBLE-Arduino/examples/BLE_EddystoneTLM_Beacon/BLE_EddystoneTLM_Beacon.md new file mode 100644 index 000000000..2e34029d1 --- /dev/null +++ b/libesp32/NimBLE-Arduino/examples/BLE_EddystoneTLM_Beacon/BLE_EddystoneTLM_Beacon.md @@ -0,0 +1,14 @@ +## Eddystone TLM beacon +EddystoneTLM beacon by BeeGee based on +[pcbreflux ESP32 Eddystone TLM deepsleep](https://github.com/pcbreflux/espressif/blob/master/esp32/arduino/sketchbook/ESP32_Eddystone_TLM_deepsleep/ESP32_Eddystone_TLM_deepsleep.ino) + +[EddystoneTLM frame specification](https://github.com/google/eddystone/blob/master/eddystone-tlm/tlm-plain.md) + + Create a BLE server that will send periodic Eddystone TLM frames. + The design of creating the BLE server is: + 1. Create a BLE Server + 2. Create advertising data + 3. Start advertising. + 4. wait + 5. Stop advertising. + 6. deep sleep diff --git a/libesp32/NimBLE-Arduino/examples/BLE_EddystoneURL_Beacon/BLE_EddystoneURL_Beacon.ino b/libesp32/NimBLE-Arduino/examples/BLE_EddystoneURL_Beacon/BLE_EddystoneURL_Beacon.ino new file mode 100644 index 000000000..07879b257 --- /dev/null +++ b/libesp32/NimBLE-Arduino/examples/BLE_EddystoneURL_Beacon/BLE_EddystoneURL_Beacon.ino @@ -0,0 +1,185 @@ +/* + EddystoneURL beacon for NimBLE by BeeGee + EddystoneURL frame specification https://github.com/google/eddystone/blob/master/eddystone-url/README.md + +*/ + +/* + Create a BLE server that will send periodic Eddystone URL frames. + The design of creating the BLE server is: + 1. Create a BLE Server + 2. Create advertising data + 3. Start advertising. + 4. wait + 5. Stop advertising. + 6. deep sleep + +*/ + +#include "NimBLEDevice.h" +#include "NimBLEBeacon.h" +#include "NimBLEEddystoneURL.h" + +#include "sys/time.h" +#include "esp_sleep.h" + +#define GPIO_DEEP_SLEEP_DURATION 10 // sleep x seconds and then wake up + +// UUID 1 128-Bit (may use linux tool uuidgen or random numbers via https://www.uuidgenerator.net/) +#define BEACON_UUID "8ec76ea3-6668-48da-9866-75be8bc86f4d" + +RTC_DATA_ATTR static time_t last; // remember last boot in RTC Memory +RTC_DATA_ATTR static uint32_t bootcount; // remember number of boots in RTC Memory + +BLEAdvertising *pAdvertising; +struct timeval now; + +static const char *eddystone_url_prefix_subs[] = { + "http://www.", + "https://www.", + "http://", + "https://", + "urn:uuid:", + NULL +}; + +static const char *eddystone_url_suffix_subs[] = { + ".com/", + ".org/", + ".edu/", + ".net/", + ".info/", + ".biz/", + ".gov/", + ".com", + ".org", + ".edu", + ".net", + ".info", + ".biz", + ".gov", + NULL +}; + +static int string_begin_with(const char *str, const char *prefix) +{ + int prefix_len = strlen(prefix); + if (strncmp(prefix, str, prefix_len) == 0) + { + return prefix_len; + } + return 0; +} + +void setBeacon() +{ + BLEAdvertisementData oAdvertisementData = BLEAdvertisementData(); + BLEAdvertisementData oScanResponseData = BLEAdvertisementData(); + + const char url[] = "https://d.giesecke.tk"; + + int scheme_len, ext_len = 1, i, idx, url_idx; + char *ret_data; + int url_len = strlen(url); + + ret_data = (char *)calloc(1, url_len + 13); + + ret_data[0] = 2; // Len + ret_data[1] = 0x01; // Type Flags + ret_data[2] = 0x06; // GENERAL_DISC_MODE 0x02 | BR_EDR_NOT_SUPPORTED 0x04 + ret_data[3] = 3; // Len + ret_data[4] = 0x03; // Type 16-Bit UUID + ret_data[5] = 0xAA; // Eddystone UUID 2 -> 0xFEAA LSB + ret_data[6] = 0xFE; // Eddystone UUID 1 MSB + ret_data[7] = 19; // Length of Beacon Data + ret_data[8] = 0x16; // Type Service Data + ret_data[9] = 0xAA; // Eddystone UUID 2 -> 0xFEAA LSB + ret_data[10] = 0xFE; // Eddystone UUID 1 MSB + ret_data[11] = 0x10; // Eddystone Frame Type + ret_data[12] = 0xF4; // Beacons TX power at 0m + + i = 0, idx = 13, url_idx = 0; + + //replace prefix + scheme_len = 0; + while (eddystone_url_prefix_subs[i] != NULL) + { + if ((scheme_len = string_begin_with(url, eddystone_url_prefix_subs[i])) > 0) + { + ret_data[idx] = i; + idx++; + url_idx += scheme_len; + break; + } + i++; + } + while (url_idx < url_len) + { + i = 0; + ret_data[idx] = url[url_idx]; + ext_len = 1; + while (eddystone_url_suffix_subs[i] != NULL) + { + if ((ext_len = string_begin_with(&url[url_idx], eddystone_url_suffix_subs[i])) > 0) + { + ret_data[idx] = i; + break; + } + else + { + ext_len = 1; //inc 1 + } + i++; + } + url_idx += ext_len; + idx++; + } + ret_data[7] = idx - 8; + + Serial.printf("struct size %d url size %d reported len %d\n", + url_len + 13, + url_len, ret_data[7]); + + Serial.printf("URL in data %s\n", &ret_data[13]); + + std::string eddyStoneData(ret_data); + + oAdvertisementData.addData(eddyStoneData); + oScanResponseData.setName("MeBeacon"); + pAdvertising->setAdvertisementData(oAdvertisementData); + pAdvertising->setScanResponseData(oScanResponseData); +} + +void setup() +{ + + Serial.begin(115200); + gettimeofday(&now, NULL); + + Serial.printf("start ESP32 %d\n", bootcount++); + + Serial.printf("deep sleep (%lds since last reset, %lds since last boot)\n", now.tv_sec, now.tv_sec - last); + + last = now.tv_sec; + + // Create the BLE Device + BLEDevice::init("MeBeacon"); + + BLEDevice::setPower(ESP_PWR_LVL_N12); + + pAdvertising = BLEDevice::getAdvertising(); + + setBeacon(); + // Start advertising + pAdvertising->start(); + Serial.println("Advertizing started..."); + delay(10000); + pAdvertising->stop(); + Serial.printf("enter deep sleep\n"); + esp_deep_sleep(1000000LL * GPIO_DEEP_SLEEP_DURATION); + Serial.printf("in deep sleep\n"); +} + +void loop() +{ +} diff --git a/libesp32/NimBLE-Arduino/examples/BLE_EddystoneURL_Beacon/BLE_EddystoneURL_Beacon.md b/libesp32/NimBLE-Arduino/examples/BLE_EddystoneURL_Beacon/BLE_EddystoneURL_Beacon.md new file mode 100644 index 000000000..2baf1cc52 --- /dev/null +++ b/libesp32/NimBLE-Arduino/examples/BLE_EddystoneURL_Beacon/BLE_EddystoneURL_Beacon.md @@ -0,0 +1,14 @@ +## Eddystone URL beacon +EddystoneURL beacon by BeeGee based on +[pcbreflux ESP32 Eddystone URL deepsleep](https://github.com/pcbreflux/espressif/tree/master/esp32/arduino/sketchbook/ESP32_Eddystone_URL_deepsleep) + +[EddystoneURL frame specification](https://github.com/google/eddystone/blob/master/eddystone-url/README.md) + + Create a BLE server that will send periodic Eddystone URL frames. + The design of creating the BLE server is: + 1. Create a BLE Server + 2. Create advertising data + 3. Start advertising. + 4. wait + 5. Stop advertising. + 6. deep sleep diff --git a/libesp32/NimBLE-Arduino/examples/NimBLE_Client/NimBLE_Client.ino b/libesp32/NimBLE-Arduino/examples/NimBLE_Client/NimBLE_Client.ino new file mode 100644 index 000000000..30eeb9fe3 --- /dev/null +++ b/libesp32/NimBLE-Arduino/examples/NimBLE_Client/NimBLE_Client.ino @@ -0,0 +1,383 @@ + +/** NimBLE_Server Demo: + * + * Demonstrates many of the available features of the NimBLE client library. + * + * Created: on March 24 2020 + * Author: H2zero + * +*/ + +#include + +void scanEndedCB(NimBLEScanResults results); + +static NimBLEAdvertisedDevice* advDevice; + +static bool doConnect = false; +static uint32_t scanTime = 0; /** 0 = scan forever */ + + +/** None of these are required as they will be handled by the library with defaults. ** + ** Remove as you see fit for your needs */ +class ClientCallbacks : public NimBLEClientCallbacks { + void onConnect(NimBLEClient* pClient) { + Serial.println("Connected"); + /** After connection we should change the parameters if we don't need fast response times. + * These settings are 150ms interval, 0 latency, 450ms timout. + * Timeout should be a multiple of the interval, minimum is 100ms. + * I find a multiple of 3-5 * the interval works best for quick response/reconnect. + * Min interval: 120 * 1.25ms = 150, Max interval: 120 * 1.25ms = 150, 0 latency, 60 * 10ms = 600ms timeout + */ + pClient->updateConnParams(120,120,0,60); + }; + + void onDisconnect(NimBLEClient* pClient) { + Serial.print(pClient->getPeerAddress().toString().c_str()); + Serial.println(" Disconnected - Starting scan"); + NimBLEDevice::getScan()->start(scanTime, scanEndedCB); + }; + + /** Called when the peripheral requests a change to the connection parameters. + * Return true to accept and apply them or false to reject and keep + * the currently used parameters. Default will return true. + */ + bool onConnParamsUpdateRequest(NimBLEClient* pClient, const ble_gap_upd_params* params) { + if(params->itvl_min < 24) { /** 1.25ms units */ + return false; + } else if(params->itvl_max > 40) { /** 1.25ms units */ + return false; + } else if(params->latency > 2) { /** Number of intervals allowed to skip */ + return false; + } else if(params->supervision_timeout > 100) { /** 10ms units */ + return false; + } + + return true; + }; + + /********************* Security handled here ********************** + ****** Note: these are the same return values as defaults ********/ + uint32_t onPassKeyRequest(){ + Serial.println("Client Passkey Request"); + /** return the passkey to send to the server */ + return 123456; + }; + + bool onConfirmPIN(uint32_t pass_key){ + Serial.print("The passkey YES/NO number: "); + Serial.println(pass_key); + /** Return false if passkeys don't match. */ + return true; + }; + + /** Pairing process complete, we can check the results in ble_gap_conn_desc */ + void onAuthenticationComplete(ble_gap_conn_desc* desc){ + if(!desc->sec_state.encrypted) { + Serial.println("Encrypt connection failed - disconnecting"); + /** Find the client with the connection handle provided in desc */ + NimBLEDevice::getClientByID(desc->conn_handle)->disconnect(); + return; + } + }; +}; + + +/** Define a class to handle the callbacks when advertisments are received */ +class AdvertisedDeviceCallbacks: public NimBLEAdvertisedDeviceCallbacks { + + void onResult(NimBLEAdvertisedDevice* advertisedDevice) { + Serial.print("Advertised Device found: "); + Serial.println(advertisedDevice->toString().c_str()); + if(advertisedDevice->isAdvertisingService(NimBLEUUID("DEAD"))) + { + Serial.println("Found Our Service"); + /** stop scan before connecting */ + NimBLEDevice::getScan()->stop(); + /** Save the device reference in a global for the client to use*/ + advDevice = advertisedDevice; + /** Ready to connect now */ + doConnect = true; + } + }; +}; + + +/** Notification / Indication receiving handler callback */ +void notifyCB(NimBLERemoteCharacteristic* pRemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify){ + std::string str = (isNotify == true) ? "Notification" : "Indication"; + str += " from "; + str += pRemoteCharacteristic->getRemoteService()->getClient()->getPeerAddress().toString(); + str += ": Service = " + pRemoteCharacteristic->getRemoteService()->getUUID().toString(); + str += ", Characteristic = " + pRemoteCharacteristic->getUUID().toString(); + str += ", Value = " + std::string((char*)pData, length); + Serial.println(str.c_str()); +} + +/** Callback to process the results of the last scan or restart it */ +void scanEndedCB(NimBLEScanResults results){ + Serial.println("Scan Ended"); +} + + +/** Create a single global instance of the callback class to be used by all clients */ +static ClientCallbacks clientCB; + + +/** Handles the provisioning of clients and connects / interfaces with the server */ +bool connectToServer() { + NimBLEClient* pClient = nullptr; + + /** Check if we have a client we should reuse first **/ + if(NimBLEDevice::getClientListSize()) { + /** Special case when we already know this device, we send false as the + * second argument in connect() to prevent refreshing the service database. + * This saves considerable time and power. + */ + pClient = NimBLEDevice::getClientByPeerAddress(advDevice->getAddress()); + if(pClient){ + if(!pClient->connect(advDevice, false)) { + Serial.println("Reconnect failed"); + return false; + } + Serial.println("Reconnected client"); + } + /** We don't already have a client that knows this device, + * we will check for a client that is disconnected that we can use. + */ + else { + pClient = NimBLEDevice::getDisconnectedClient(); + } + } + + /** No client to reuse? Create a new one. */ + if(!pClient) { + if(NimBLEDevice::getClientListSize() >= NIMBLE_MAX_CONNECTIONS) { + Serial.println("Max clients reached - no more connections available"); + return false; + } + + pClient = NimBLEDevice::createClient(); + + Serial.println("New client created"); + + pClient->setClientCallbacks(&clientCB, false); + /** Set initial connection parameters: These settings are 15ms interval, 0 latency, 120ms timout. + * These settings are safe for 3 clients to connect reliably, can go faster if you have less + * connections. Timeout should be a multiple of the interval, minimum is 100ms. + * Min interval: 12 * 1.25ms = 15, Max interval: 12 * 1.25ms = 15, 0 latency, 51 * 10ms = 510ms timeout + */ + pClient->setConnectionParams(12,12,0,51); + /** Set how long we are willing to wait for the connection to complete (seconds), default is 30. */ + pClient->setConnectTimeout(5); + + + if (!pClient->connect(advDevice)) { + /** Created a client but failed to connect, don't need to keep it as it has no data */ + NimBLEDevice::deleteClient(pClient); + Serial.println("Failed to connect, deleted client"); + return false; + } + } + + if(!pClient->isConnected()) { + if (!pClient->connect(advDevice)) { + Serial.println("Failed to connect"); + return false; + } + } + + Serial.print("Connected to: "); + Serial.println(pClient->getPeerAddress().toString().c_str()); + Serial.print("RSSI: "); + Serial.println(pClient->getRssi()); + + /** Now we can read/write/subscribe the charateristics of the services we are interested in */ + NimBLERemoteService* pSvc = nullptr; + NimBLERemoteCharacteristic* pChr = nullptr; + NimBLERemoteDescriptor* pDsc = nullptr; + + pSvc = pClient->getService("DEAD"); + if(pSvc) { /** make sure it's not null */ + pChr = pSvc->getCharacteristic("BEEF"); + } + + if(pChr) { /** make sure it's not null */ + if(pChr->canRead()) { + Serial.print(pChr->getUUID().toString().c_str()); + Serial.print(" Value: "); + Serial.println(pChr->readValue().c_str()); + } + + if(pChr->canWrite()) { + if(pChr->writeValue("Tasty")) { + Serial.print("Wrote new value to: "); + Serial.println(pChr->getUUID().toString().c_str()); + } + else { + /** Disconnect if write failed */ + pClient->disconnect(); + return false; + } + + if(pChr->canRead()) { + Serial.print("The value of: "); + Serial.print(pChr->getUUID().toString().c_str()); + Serial.print(" is now: "); + Serial.println(pChr->readValue().c_str()); + } + } + + if(pChr->canNotify()) { + /** Must send a callback to subscribe, if nullptr it will unsubscribe */ + if(!pChr->registerForNotify(notifyCB)) { + /** Disconnect if subscribe failed */ + pClient->disconnect(); + return false; + } + } + else if(pChr->canIndicate()) { + /** Send false as second argument to subscribe to indications instead of notifications */ + if(!pChr->registerForNotify(notifyCB, false)) { + /** Disconnect if subscribe failed */ + pClient->disconnect(); + return false; + } + } + } + + else{ + Serial.println("DEAD service not found."); + } + + pSvc = pClient->getService("BAAD"); + if(pSvc) { /** make sure it's not null */ + pChr = pSvc->getCharacteristic("F00D"); + } + + if(pChr) { /** make sure it's not null */ + if(pChr->canRead()) { + Serial.print(pChr->getUUID().toString().c_str()); + Serial.print(" Value: "); + Serial.println(pChr->readValue().c_str()); + } + + pDsc = pChr->getDescriptor(NimBLEUUID("C01D")); + if(pDsc) { /** make sure it's not null */ + Serial.print("Descriptor: "); + Serial.print(pDsc->getUUID().toString().c_str()); + Serial.print(" Value: "); + Serial.println(pDsc->readValue().c_str()); + } + + if(pChr->canWrite()) { + if(pChr->writeValue("No tip!")) { + Serial.print("Wrote new value to: "); + Serial.println(pChr->getUUID().toString().c_str()); + } + else { + /** Disconnect if write failed */ + pClient->disconnect(); + return false; + } + + if(pChr->canRead()) { + Serial.print("The value of: "); + Serial.print(pChr->getUUID().toString().c_str()); + Serial.print(" is now: "); + Serial.println(pChr->readValue().c_str()); + } + } + + if(pChr->canNotify()) { + /** Must send a callback to subscribe, if nullptr it will unsubscribe */ + if(!pChr->registerForNotify(notifyCB)) { + /** Disconnect if subscribe failed */ + pClient->disconnect(); + return false; + } + } + else if(pChr->canIndicate()) { + /** Send false as second argument to subscribe to indications instead of notifications */ + if(!pChr->registerForNotify(notifyCB, false)) { + /** Disconnect if subscribe failed */ + pClient->disconnect(); + return false; + } + } + } + + else{ + Serial.println("BAAD service not found."); + } + + Serial.println("Done with this device!"); + return true; +} + +void setup (){ + Serial.begin(115200); + Serial.println("Starting NimBLE Client"); + /** Initialize NimBLE, no device name spcified as we are not advertising */ + NimBLEDevice::init(""); + + /** Set the IO capabilities of the device, each option will trigger a different pairing method. + * BLE_HS_IO_KEYBOARD_ONLY - Passkey pairing + * BLE_HS_IO_DISPLAY_YESNO - Numeric comparison pairing + * BLE_HS_IO_NO_INPUT_OUTPUT - DEFAULT setting - just works pairing + */ + //NimBLEDevice::setSecurityIOCap(BLE_HS_IO_KEYBOARD_ONLY); // use passkey + //NimBLEDevice::setSecurityIOCap(BLE_HS_IO_DISPLAY_YESNO); //use numeric comparison + + /** 2 different ways to set security - both calls achieve the same result. + * no bonding, no man in the middle protection, secure connections. + * + * These are the default values, only shown here for demonstration. + */ + //NimBLEDevice::setSecurityAuth(false, false, true); + NimBLEDevice::setSecurityAuth(/*BLE_SM_PAIR_AUTHREQ_BOND | BLE_SM_PAIR_AUTHREQ_MITM |*/ BLE_SM_PAIR_AUTHREQ_SC); + + /** Optional: set the transmit power, default is 3db */ + NimBLEDevice::setPower(ESP_PWR_LVL_P9); /** +9db */ + + /** Optional: set any devices you don't want to get advertisments from */ + // NimBLEDevice::addIgnored(NimBLEAddress ("aa:bb:cc:dd:ee:ff")); + + /** create new scan */ + NimBLEScan* pScan = NimBLEDevice::getScan(); + + /** create a callback that gets called when advertisers are found */ + pScan->setAdvertisedDeviceCallbacks(new AdvertisedDeviceCallbacks()); + + /** Set scan interval (how often) and window (how long) in milliseconds */ + pScan->setInterval(45); + pScan->setWindow(15); + + /** Active scan will gather scan response data from advertisers + * but will use more energy from both devices + */ + pScan->setActiveScan(true); + /** Start scanning for advertisers for the scan time specified (in seconds) 0 = forever + * Optional callback for when scanning stops. + */ + pScan->start(scanTime, scanEndedCB); +} + + +void loop (){ + /** Loop here until we find a device we want to connect to */ + while(!doConnect){ + delay(1); + } + + doConnect = false; + + /** Found a device we want to connect to, do it now */ + if(connectToServer()) { + Serial.println("Success! we should now be getting notifications, scanning for more!"); + } else { + Serial.println("Failed to connect, starting scan"); + } + + NimBLEDevice::getScan()->start(scanTime,scanEndedCB); +} diff --git a/libesp32/NimBLE-Arduino/examples/NimBLE_Server/NimBLE_Server.ino b/libesp32/NimBLE-Arduino/examples/NimBLE_Server/NimBLE_Server.ino new file mode 100644 index 000000000..e0be793d5 --- /dev/null +++ b/libesp32/NimBLE-Arduino/examples/NimBLE_Server/NimBLE_Server.ino @@ -0,0 +1,250 @@ + +/** NimBLE_Server Demo: + * + * Demonstrates many of the available features of the NimBLE server library. + * + * Created: on March 22 2020 + * Author: H2zero + * +*/ + +#include +#include +#include + +static NimBLEServer* pServer; + +/** None of these are required as they will be handled by the library with defaults. ** + ** Remove as you see fit for your needs */ +class ServerCallbacks: public NimBLEServerCallbacks { + void onConnect(NimBLEServer* pServer) { + Serial.println("Client connected"); + Serial.println("Multi-connect support: start advertising"); + NimBLEDevice::startAdvertising(); + }; + /** Alternative onConnect() method to extract details of the connection. + * See: src/ble_gap.h for the details of the ble_gap_conn_desc struct. + */ + void onConnect(NimBLEServer* pServer, ble_gap_conn_desc* desc) { + Serial.print("Client address: "); + Serial.println(NimBLEAddress(desc->peer_ota_addr).toString().c_str()); + /** We can use the connection handle here to ask for different connection parameters. + * Args: connection handle, min connection interval, max connection interval + * latency, supervision timeout. + * Units; Min/Max Intervals: 1.25 millisecond increments. + * Latency: number of intervals allowed to skip. + * Timeout: 10 millisecond increments, try for 5x interval time for best results. + */ + pServer->updateConnParams(desc->conn_handle, 24, 48, 0, 60); + }; + void onDisconnect(NimBLEServer* pServer) { + Serial.println("Client disconnected - start advertising"); + NimBLEDevice::startAdvertising(); + }; + +/********************* Security handled here ********************** +****** Note: these are the same return values as defaults ********/ + uint32_t onPassKeyRequest(){ + Serial.println("Server Passkey Request"); + /** This should return a random 6 digit number for security + * or make your own static passkey as done here. + */ + return 123456; + }; + + bool onConfirmPIN(uint32_t pass_key){ + Serial.print("The passkey YES/NO number: ");Serial.println(pass_key); + /** Return false if passkeys don't match. */ + return true; + }; + + void onAuthenticationComplete(ble_gap_conn_desc* desc){ + /** Check that encryption was successful, if not we disconnect the client */ + if(!desc->sec_state.encrypted) { + NimBLEDevice::getServer()->disconnect(desc->conn_handle); + Serial.println("Encrypt connection failed - disconnecting client"); + return; + } + Serial.println("Starting BLE work!"); + }; +}; + +/** Handler class for characteristic actions */ +class CharacteristicCallbacks: public NimBLECharacteristicCallbacks { + void onRead(NimBLECharacteristic* pCharacteristic){ + Serial.print(pCharacteristic->getUUID().toString().c_str()); + Serial.print(": onRead(), value: "); + Serial.println(pCharacteristic->getValue().c_str()); + }; + + void onWrite(NimBLECharacteristic* pCharacteristic) { + Serial.print(pCharacteristic->getUUID().toString().c_str()); + Serial.print(": onWrite(), value: "); + Serial.println(pCharacteristic->getValue().c_str()); + }; + /** Called before notification or indication is sent, + * the value can be changed here before sending if desired. + */ + void onNotify(NimBLECharacteristic* pCharacteristic) { + Serial.println("Sending notification to clients"); + }; + + + /** The status returned in status is defined in NimBLECharacteristic.h. + * The value returned in code is the NimBLE host return code. + */ + void onStatus(NimBLECharacteristic* pCharacteristic, Status status, int code) { + String str = ("Notification/Indication status code: "); + str += status; + str += ", return code: "; + str += code; + str += ", "; + str += NimBLEUtils::returnCodeToString(code); + Serial.println(str); + }; +}; + +/** Handler class for descriptor actions */ +class DescriptorCallbacks : public NimBLEDescriptorCallbacks { + void onWrite(NimBLEDescriptor* pDescriptor) { + if(pDescriptor->getUUID().equals(NimBLEUUID("2902"))) { + /** Cast to NimBLE2902 to use the class specific functions. **/ + NimBLE2902* p2902 = (NimBLE2902*)pDescriptor; + if(p2902->getNotifications()) { + Serial.println("Client Subscribed to notfications"); + } else { + Serial.println("Client Unubscribed to notfications"); + } + } else { + std::string dscVal((char*)pDescriptor->getValue(), pDescriptor->getLength()); + Serial.print("Descriptor witten value:"); + Serial.println(dscVal.c_str()); + } + }; + + void onRead(NimBLEDescriptor* pDescriptor) { + Serial.print(pDescriptor->getUUID().toString().c_str()); + Serial.println(" Descriptor read"); + }; +}; + + +/** Define callback instances globally to use for multiple Charateristics \ Descriptors */ +static DescriptorCallbacks dscCallbacks; +static CharacteristicCallbacks chrCallbacks; + + +void setup() { + Serial.begin(115200); + Serial.println("Starting NimBLE Server"); + + /** sets device name */ + NimBLEDevice::init("NimBLE-Arduino"); + + /** Optional: set the transmit power, default is 3db */ + NimBLEDevice::setPower(ESP_PWR_LVL_P9); /** +9db */ + + /** Set the IO capabilities of the device, each option will trigger a different pairing method. + * BLE_HS_IO_DISPLAY_ONLY - Passkey pairing + * BLE_HS_IO_DISPLAY_YESNO - Numeric comparison pairing + * BLE_HS_IO_NO_INPUT_OUTPUT - DEFAULT setting - just works pairing + */ + //NimBLEDevice::setSecurityIOCap(BLE_HS_IO_DISPLAY_ONLY); // use passkey + //NimBLEDevice::setSecurityIOCap(BLE_HS_IO_DISPLAY_YESNO); //use numeric comparison + + /** 2 different ways to set security - both calls achieve the same result. + * no bonding, no man in the middle protection, secure connections. + * + * These are the default values, only shown here for demonstration. + */ + //NimBLEDevice::setSecurityAuth(false, false, true); + NimBLEDevice::setSecurityAuth(/*BLE_SM_PAIR_AUTHREQ_BOND | BLE_SM_PAIR_AUTHREQ_MITM |*/ BLE_SM_PAIR_AUTHREQ_SC); + + pServer = NimBLEDevice::createServer(); + pServer->setCallbacks(new ServerCallbacks()); + + NimBLEService* pDeadService = pServer->createService("DEAD"); + NimBLECharacteristic* pBeefCharacteristic = pDeadService->createCharacteristic( + "BEEF", + NIMBLE_PROPERTY::READ | + NIMBLE_PROPERTY::WRITE | + /** Require a secure connection for read and write access */ + NIMBLE_PROPERTY::READ_ENC | // only allow reading if paired / encrypted + NIMBLE_PROPERTY::WRITE_ENC // only allow writing if paired / encrypted + ); + + pBeefCharacteristic->setValue("Burger"); + pBeefCharacteristic->setCallbacks(&chrCallbacks); + + /** 2902 and 2904 descriptors are a special case, when createDescriptor is called with + * either of those uuid's it will create the associated class with the correct properties + * and sizes. However we must cast the returned reference to the correct type as the method + * only returns a pointer to the base NimBLEDescriptor class. + */ + NimBLE2904* pBeef2904 = (NimBLE2904*)pBeefCharacteristic->createDescriptor("2904"); + pBeef2904->setFormat(NimBLE2904::FORMAT_UTF8); + pBeef2904->setCallbacks(&dscCallbacks); + + + NimBLEService* pBaadService = pServer->createService("BAAD"); + NimBLECharacteristic* pFoodCharacteristic = pBaadService->createCharacteristic( + "F00D", + NIMBLE_PROPERTY::READ | + NIMBLE_PROPERTY::WRITE | + NIMBLE_PROPERTY::NOTIFY + ); + + pFoodCharacteristic->setValue("Fries"); + pFoodCharacteristic->setCallbacks(&chrCallbacks); + + /** Custom descriptor: Arguments are UUID, Properties, max length in bytes of the value */ + NimBLEDescriptor* pC01Ddsc = pFoodCharacteristic->createDescriptor( + "C01D", + NIMBLE_PROPERTY::READ | + NIMBLE_PROPERTY::WRITE| + NIMBLE_PROPERTY::WRITE_ENC, // only allow writing if paired / encrypted + 20 + ); + pC01Ddsc->setValue("Send it back!"); + pC01Ddsc->setCallbacks(&dscCallbacks); + + /** Note a 2902 descriptor does NOT need to be created as any chactateristic with + * notification or indication properties will have one created autmatically. + * Manually creating it is only useful if you wish to handle callback functions + * as shown here. Otherwise this can be removed without loss of functionality. + */ + NimBLE2902* pFood2902 = (NimBLE2902*)pFoodCharacteristic->createDescriptor("2902"); + pFood2902->setCallbacks(&dscCallbacks); + + /** Start the services when finished creating all Characteristics and Descriptors */ + pDeadService->start(); + pBaadService->start(); + + NimBLEAdvertising* pAdvertising = NimBLEDevice::getAdvertising(); + /** Add the services to the advertisment data **/ + pAdvertising->addServiceUUID(pDeadService->getUUID()); + pAdvertising->addServiceUUID(pBaadService->getUUID()); + /** If your device is battery powered you may consider setting scan response + * to false as it will extend battery life at the expense of less data sent. + */ + pAdvertising->setScanResponse(true); + pAdvertising->start(); + + Serial.println("Advertising Started"); +} + + +void loop() { + /** Do your thing here, this just spams notifications to all connected clients */ + if(pServer->getConnectedCount()) { + NimBLEService* pSvc = pServer->getServiceByUUID("BAAD"); + if(pSvc) { + NimBLECharacteristic* pChr = pSvc->getCharacteristic("F00D"); + if(pChr) { + pChr->notify(true); + } + } + } + + delay(2000); +} diff --git a/libesp32/NimBLE-Arduino/examples/Refactored_original_examples/BLE_client/BLE_client.ino b/libesp32/NimBLE-Arduino/examples/Refactored_original_examples/BLE_client/BLE_client.ino new file mode 100644 index 000000000..0d4ab94b4 --- /dev/null +++ b/libesp32/NimBLE-Arduino/examples/Refactored_original_examples/BLE_client/BLE_client.ino @@ -0,0 +1,194 @@ +/** + * A BLE client example that is rich in capabilities. + * There is a lot new capabilities implemented. + * author unknown + * updated by chegewara + * updated for NimBLE by H2zero + */ + +/** NimBLE differences highlighted in comment blocks **/ + +/*******original******** +#include "BLEDevice.h" +***********************/ +#include "NimBLEDevice.h" + +// The remote service we wish to connect to. +static BLEUUID serviceUUID("4fafc201-1fb5-459e-8fcc-c5c9c331914b"); +// The characteristic of the remote service we are interested in. +static BLEUUID charUUID("beb5483e-36e1-4688-b7f5-ea07361b26a8"); + +static boolean doConnect = false; +static boolean connected = false; +static boolean doScan = false; +static BLERemoteCharacteristic* pRemoteCharacteristic; +static BLEAdvertisedDevice* myDevice; + +static void notifyCallback( + BLERemoteCharacteristic* pBLERemoteCharacteristic, + uint8_t* pData, + size_t length, + bool isNotify) { + Serial.print("Notify callback for characteristic "); + Serial.print(pBLERemoteCharacteristic->getUUID().toString().c_str()); + Serial.print(" of data length "); + Serial.println(length); + Serial.print("data: "); + Serial.println((char*)pData); +} + +/** None of these are required as they will be handled by the library with defaults. ** + ** Remove as you see fit for your needs */ +class MyClientCallback : public BLEClientCallbacks { + void onConnect(BLEClient* pclient) { + } + + void onDisconnect(BLEClient* pclient) { + connected = false; + Serial.println("onDisconnect"); + } +/***************** New - Security handled here ******************** +****** Note: these are the same return values as defaults ********/ + uint32_t onPassKeyRequest(){ + Serial.println("Client PassKeyRequest"); + return 123456; + } + bool onConfirmPIN(uint32_t pass_key){ + Serial.print("The passkey YES/NO number: ");Serial.println(pass_key); + return true; + } + + void onAuthenticationComplete(ble_gap_conn_desc desc){ + Serial.println("Starting BLE work!"); + } +/*******************************************************************/ +}; + +bool connectToServer() { + Serial.print("Forming a connection to "); + Serial.println(myDevice->getAddress().toString().c_str()); + + BLEClient* pClient = BLEDevice::createClient(); + Serial.println(" - Created client"); + + pClient->setClientCallbacks(new MyClientCallback()); + + // Connect to the remove BLE Server. + pClient->connect(myDevice); // if you pass BLEAdvertisedDevice instead of address, it will be recognized type of peer device address (public or private) + Serial.println(" - Connected to server"); + + // Obtain a reference to the service we are after in the remote BLE server. + BLERemoteService* pRemoteService = pClient->getService(serviceUUID); + if (pRemoteService == nullptr) { + Serial.print("Failed to find our service UUID: "); + Serial.println(serviceUUID.toString().c_str()); + pClient->disconnect(); + return false; + } + Serial.println(" - Found our service"); + + + // Obtain a reference to the characteristic in the service of the remote BLE server. + pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID); + if (pRemoteCharacteristic == nullptr) { + Serial.print("Failed to find our characteristic UUID: "); + Serial.println(charUUID.toString().c_str()); + pClient->disconnect(); + return false; + } + Serial.println(" - Found our characteristic"); + + // Read the value of the characteristic. + if(pRemoteCharacteristic->canRead()) { + std::string value = pRemoteCharacteristic->readValue(); + Serial.print("The characteristic value was: "); + Serial.println(value.c_str()); + } + + if(pRemoteCharacteristic->canNotify()) + pRemoteCharacteristic->registerForNotify(notifyCallback); + + connected = true; + return true; +} + +/** + * Scan for BLE servers and find the first one that advertises the service we are looking for. + */ +class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks { + /** + * Called for each advertising BLE server. + */ + +/*** Only a reference to the advertised device is passed now + void onResult(BLEAdvertisedDevice advertisedDevice) { **/ + void onResult(BLEAdvertisedDevice* advertisedDevice) { + Serial.print("BLE Advertised Device found: "); + Serial.println(advertisedDevice->toString().c_str()); + + // We have found a device, let us now see if it contains the service we are looking for. +/******************************************************************************** + if (advertisedDevice.haveServiceUUID() && advertisedDevice.isAdvertisingService(serviceUUID)) { +********************************************************************************/ + if (advertisedDevice->haveServiceUUID() && advertisedDevice->isAdvertisingService(serviceUUID)) { + + BLEDevice::getScan()->stop(); +/******************************************************************* + myDevice = new BLEAdvertisedDevice(advertisedDevice); +*******************************************************************/ + myDevice = advertisedDevice; /** Just save the reference now, no need to copy the object */ + doConnect = true; + doScan = true; + + } // Found our server + } // onResult +}; // MyAdvertisedDeviceCallbacks + + +void setup() { + Serial.begin(115200); + Serial.println("Starting Arduino BLE Client application..."); + BLEDevice::init(""); + + // Retrieve a Scanner and set the callback we want to use to be informed when we + // have detected a new device. Specify that we want active scanning and start the + // scan to run for 5 seconds. + BLEScan* pBLEScan = BLEDevice::getScan(); + pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks()); + pBLEScan->setInterval(1349); + pBLEScan->setWindow(449); + pBLEScan->setActiveScan(true); + pBLEScan->start(5, false); +} // End of setup. + + +// This is the Arduino main loop function. +void loop() { + + // If the flag "doConnect" is true then we have scanned for and found the desired + // BLE Server with which we wish to connect. Now we connect to it. Once we are + // connected we set the connected flag to be true. + if (doConnect == true) { + if (connectToServer()) { + Serial.println("We are now connected to the BLE Server."); + } else { + Serial.println("We have failed to connect to the server; there is nothin more we will do."); + } + doConnect = false; + } + + // If we are connected to a peer BLE Server, update the characteristic each time we are reached + // with the current time since boot. + if (connected) { + String newValue = "Time since boot: " + String(millis()/1000); + Serial.println("Setting new characteristic value to \"" + newValue + "\""); + + // Set the characteristic's value to be the array of bytes that is actually a string. + /*** Note: write / read value now returns true if successful, false otherwise - try again or disconnect ***/ + pRemoteCharacteristic->writeValue(newValue.c_str(), newValue.length()); + }else if(doScan){ + BLEDevice::getScan()->start(0); // this is just eample to start scan after disconnect, most likely there is better way to do it in arduino + } + + delay(1000); // Delay a second between loops. +} // End of loop diff --git a/libesp32/NimBLE-Arduino/examples/Refactored_original_examples/BLE_iBeacon/BLE_iBeacon.ino b/libesp32/NimBLE-Arduino/examples/Refactored_original_examples/BLE_iBeacon/BLE_iBeacon.ino new file mode 100644 index 000000000..86b97def3 --- /dev/null +++ b/libesp32/NimBLE-Arduino/examples/Refactored_original_examples/BLE_iBeacon/BLE_iBeacon.ino @@ -0,0 +1,118 @@ +/* + Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleScan.cpp + Ported to Arduino ESP32 by pcbreflux +*/ + + +/* + Create a BLE server that will send periodic iBeacon frames. + The design of creating the BLE server is: + 1. Create a BLE Server + 2. Create advertising data + 3. Start advertising. + 4. wait + 5. Stop advertising. + 6. deep sleep + +*/ + + +/** NimBLE differences highlighted in comment blocks **/ + + +#include "sys/time.h" +/*******original******** +#include "BLEDevice.h" +#include "BLEUtils.h" +#include "BLEBeacon.h" +***********************/ +#include "NimBLEDevice.h" +#include "NimBLEBeacon.h" +#include "esp_sleep.h" + +#define GPIO_DEEP_SLEEP_DURATION 10 // sleep x seconds and then wake up +RTC_DATA_ATTR static time_t last; // remember last boot in RTC Memory +RTC_DATA_ATTR static uint32_t bootcount; // remember number of boots in RTC Memory + +#ifdef __cplusplus +extern "C" { +#endif + +uint8_t temprature_sens_read(); +//uint8_t g_phyFuns; + +#ifdef __cplusplus +} +#endif + +// See the following for generating UUIDs: +// https://www.uuidgenerator.net/ +BLEAdvertising *pAdvertising; +struct timeval now; + +#define BEACON_UUID "8ec76ea3-6668-48da-9866-75be8bc86f4d" // UUID 1 128-Bit (may use linux tool uuidgen or random numbers via https://www.uuidgenerator.net/) + +void setBeacon() { + + BLEBeacon oBeacon = BLEBeacon(); + oBeacon.setManufacturerId(0x4C00); // fake Apple 0x004C LSB (ENDIAN_CHANGE_U16!) + oBeacon.setProximityUUID(BLEUUID(BEACON_UUID)); + oBeacon.setMajor((bootcount & 0xFFFF0000) >> 16); + oBeacon.setMinor(bootcount&0xFFFF); + BLEAdvertisementData oAdvertisementData = BLEAdvertisementData(); + BLEAdvertisementData oScanResponseData = BLEAdvertisementData(); + + oAdvertisementData.setFlags(0x04); // BR_EDR_NOT_SUPPORTED 0x04 + + std::string strServiceData = ""; + + strServiceData += (char)26; // Len + strServiceData += (char)0xFF; // Type + strServiceData += oBeacon.getData(); + oAdvertisementData.addData(strServiceData); + + pAdvertising->setAdvertisementData(oAdvertisementData); + pAdvertising->setScanResponseData(oScanResponseData); + /** pAdvertising->setAdvertisementType(ADV_TYPE_NONCONN_IND); + * Advertising mode. Can be one of following constants: + * - BLE_GAP_CONN_MODE_NON (non-connectable; 3.C.9.3.2). + * - BLE_GAP_CONN_MODE_DIR (directed-connectable; 3.C.9.3.3). + * - BLE_GAP_CONN_MODE_UND (undirected-connectable; 3.C.9.3.4). + */ + pAdvertising->setAdvertisementType(BLE_GAP_CONN_MODE_NON); + +} + +void setup() { + + + Serial.begin(115200); + gettimeofday(&now, NULL); + + Serial.printf("start ESP32 %d\n",bootcount++); + + Serial.printf("deep sleep (%lds since last reset, %lds since last boot)\n",now.tv_sec,now.tv_sec-last); + + last = now.tv_sec; + + // Create the BLE Device + BLEDevice::init(""); + + // Create the BLE Server + // BLEServer *pServer = BLEDevice::createServer(); // <-- no longer required to instantiate BLEServer, less flash and ram usage + + pAdvertising = BLEDevice::getAdvertising(); + + setBeacon(); + // Start advertising + pAdvertising->start(); + Serial.println("Advertizing started..."); + delay(100); + pAdvertising->stop(); + Serial.printf("enter deep sleep\n"); + esp_deep_sleep(1000000LL * GPIO_DEEP_SLEEP_DURATION); + Serial.printf("in deep sleep\n"); +} + +void loop() { +} diff --git a/libesp32/NimBLE-Arduino/examples/Refactored_original_examples/BLE_notify/BLE_notify.ino b/libesp32/NimBLE-Arduino/examples/Refactored_original_examples/BLE_notify/BLE_notify.ino new file mode 100644 index 000000000..f57c52e2b --- /dev/null +++ b/libesp32/NimBLE-Arduino/examples/Refactored_original_examples/BLE_notify/BLE_notify.ino @@ -0,0 +1,147 @@ +/* + Video: https://www.youtube.com/watch?v=oCMOYS71NIU + Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleNotify.cpp + Ported to Arduino ESP32 by Evandro Copercini + updated by chegewara + + Create a BLE server that, once we receive a connection, will send periodic notifications. + The service advertises itself as: 4fafc201-1fb5-459e-8fcc-c5c9c331914b + And has a characteristic of: beb5483e-36e1-4688-b7f5-ea07361b26a8 + + The design of creating the BLE server is: + 1. Create a BLE Server + 2. Create a BLE Service + 3. Create a BLE Characteristic on the Service + 4. Create a BLE Descriptor on the characteristic + 5. Start the service. + 6. Start advertising. + + A connect hander associated with the server starts a background task that performs notification + every couple of seconds. +*/ + +/** NimBLE differences highlighted in comment blocks **/ + +/*******original******** +#include +#include +#include +#include +***********************/ +#include + +BLEServer* pServer = NULL; +BLECharacteristic* pCharacteristic = NULL; +bool deviceConnected = false; +bool oldDeviceConnected = false; +uint32_t value = 0; + +// See the following for generating UUIDs: +// https://www.uuidgenerator.net/ + +#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b" +#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8" + +/** None of these are required as they will be handled by the library with defaults. ** + ** Remove as you see fit for your needs */ +class MyServerCallbacks: public BLEServerCallbacks { + void onConnect(BLEServer* pServer) { + deviceConnected = true; + }; + + void onDisconnect(BLEServer* pServer) { + deviceConnected = false; + } +/***************** New - Security handled here ******************** +****** Note: these are the same return values as defaults ********/ + uint32_t onPassKeyRequest(){ + Serial.println("Server PassKeyRequest"); + return 123456; + } + + bool onConfirmPIN(uint32_t pass_key){ + Serial.print("The passkey YES/NO number: ");Serial.println(pass_key); + return true; + } + + void onAuthenticationComplete(ble_gap_conn_desc desc){ + Serial.println("Starting BLE work!"); + } +/*******************************************************************/ +}; + + +void setup() { + Serial.begin(115200); + + // Create the BLE Device + BLEDevice::init("ESP32"); + + // Create the BLE Server + pServer = BLEDevice::createServer(); + pServer->setCallbacks(new MyServerCallbacks()); + + // Create the BLE Service + BLEService *pService = pServer->createService(SERVICE_UUID); + + // Create a BLE Characteristic + pCharacteristic = pService->createCharacteristic( + CHARACTERISTIC_UUID, + /******* Enum Type NIMBLE_PROPERTY now ******* + BLECharacteristic::PROPERTY_READ | + BLECharacteristic::PROPERTY_WRITE | + BLECharacteristic::PROPERTY_NOTIFY | + BLECharacteristic::PROPERTY_INDICATE + ); + **********************************************/ + NIMBLE_PROPERTY::READ | + NIMBLE_PROPERTY::WRITE | + NIMBLE_PROPERTY::NOTIFY | + NIMBLE_PROPERTY::INDICATE + ); + + // https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml + // Create a BLE Descriptor + /*********** New createDescriptor method ************ + NOTE: There is no need to create the 2902 descriptor + as it will be created automatically if notifications + or indications are enabled on a characteristic. + + pCharacteristic->addDescriptor(new BLE2902()); + ****************************************************/ + /** Add properties the same way as characteristics now **/ + + pCharacteristic->createDescriptor("2902" /** , NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE **/); + // Start the service + pService->start(); + + // Start advertising + BLEAdvertising *pAdvertising = BLEDevice::getAdvertising(); + pAdvertising->addServiceUUID(SERVICE_UUID); + pAdvertising->setScanResponse(false); + pAdvertising->setMinPreferred(0x0); // set value to 0x00 to not advertise this parameter + BLEDevice::startAdvertising(); + Serial.println("Waiting a client connection to notify..."); +} + +void loop() { + // notify changed value + if (deviceConnected) { + pCharacteristic->setValue((uint8_t*)&value, 4); + pCharacteristic->notify(); + value++; + delay(3); // bluetooth stack will go into congestion, if too many packets are sent, in 6 hours test i was able to go as low as 3ms + } + // disconnecting + if (!deviceConnected && oldDeviceConnected) { + delay(500); // give the bluetooth stack the chance to get things ready + pServer->startAdvertising(); // restart advertising + Serial.println("start advertising"); + oldDeviceConnected = deviceConnected; + } + // connecting + if (deviceConnected && !oldDeviceConnected) { + // do stuff here on connecting + oldDeviceConnected = deviceConnected; + } +} \ No newline at end of file diff --git a/libesp32/NimBLE-Arduino/examples/Refactored_original_examples/BLE_scan/BLE_scan.ino b/libesp32/NimBLE-Arduino/examples/Refactored_original_examples/BLE_scan/BLE_scan.ino new file mode 100644 index 000000000..86cdaf46f --- /dev/null +++ b/libesp32/NimBLE-Arduino/examples/Refactored_original_examples/BLE_scan/BLE_scan.ino @@ -0,0 +1,49 @@ +/* + Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleScan.cpp + Ported to Arduino ESP32 by Evandro Copercini +*/ + +/** NimBLE differences highlighted in comment blocks **/ + +/*******original******** +#include +#include +#include +#include +***********************/ + +#include + +int scanTime = 5; //In seconds +BLEScan* pBLEScan; + +class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks { + /*** Only a reference to the advertised device is passed now + void onResult(BLEAdvertisedDevice advertisedDevice) { **/ + void onResult(BLEAdvertisedDevice* advertisedDevice) { + /** Serial.printf("Advertised Device: %s \n", advertisedDevice.toString().c_str()); **/ + Serial.printf("Advertised Device: %s \n", advertisedDevice->toString().c_str()); + } +}; + +void setup() { + Serial.begin(115200); + Serial.println("Scanning..."); + + BLEDevice::init(""); + pBLEScan = BLEDevice::getScan(); //create new scan + pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks()); + pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster + pBLEScan->setInterval(100); + pBLEScan->setWindow(99); // less or equal setInterval value +} + +void loop() { + // put your main code here, to run repeatedly: + BLEScanResults foundDevices = pBLEScan->start(scanTime, false); + Serial.print("Devices found: "); + Serial.println(foundDevices.getCount()); + Serial.println("Scan done!"); + pBLEScan->clearResults(); // delete results fromBLEScan buffer to release memory + delay(2000); +} \ No newline at end of file diff --git a/libesp32/NimBLE-Arduino/examples/Refactored_original_examples/BLE_server/BLE_server.ino b/libesp32/NimBLE-Arduino/examples/Refactored_original_examples/BLE_server/BLE_server.ino new file mode 100644 index 000000000..82aa70aaa --- /dev/null +++ b/libesp32/NimBLE-Arduino/examples/Refactored_original_examples/BLE_server/BLE_server.ino @@ -0,0 +1,56 @@ +/* + Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleServer.cpp + Ported to Arduino ESP32 by Evandro Copercini + updates by chegewara +*/ + +/** NimBLE differences highlighted in comment blocks **/ + +/*******original******** +#include +#include +#include +***********************/ + +#include + +// See the following for generating UUIDs: +// https://www.uuidgenerator.net/ + +#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b" +#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8" + +void setup() { + Serial.begin(115200); + Serial.println("Starting BLE work!"); + + BLEDevice::init("Long name works now"); + BLEServer *pServer = BLEDevice::createServer(); + BLEService *pService = pServer->createService(SERVICE_UUID); + BLECharacteristic *pCharacteristic = pService->createCharacteristic( + CHARACTERISTIC_UUID, + /***** Enum Type NIMBLE_PROPERTY now ***** + BLECharacteristic::PROPERTY_READ | + BLECharacteristic::PROPERTY_WRITE + ); + *****************************************/ + NIMBLE_PROPERTY::READ | + NIMBLE_PROPERTY::WRITE + ); + + pCharacteristic->setValue("Hello World says Neil"); + pService->start(); + // BLEAdvertising *pAdvertising = pServer->getAdvertising(); // this still is working for backward compatibility + BLEAdvertising *pAdvertising = BLEDevice::getAdvertising(); + pAdvertising->addServiceUUID(SERVICE_UUID); + pAdvertising->setScanResponse(true); + pAdvertising->setMinPreferred(0x06); // functions that help with iPhone connections issue + pAdvertising->setMinPreferred(0x12); + BLEDevice::startAdvertising(); + Serial.println("Characteristic defined! Now you can read it in your phone!"); +} + +void loop() { + // put your main code here, to run repeatedly: + delay(2000); +} \ No newline at end of file diff --git a/libesp32/NimBLE-Arduino/examples/Refactored_original_examples/BLE_server_multiconnect/BLE_server_multiconnect.ino b/libesp32/NimBLE-Arduino/examples/Refactored_original_examples/BLE_server_multiconnect/BLE_server_multiconnect.ino new file mode 100644 index 000000000..025266650 --- /dev/null +++ b/libesp32/NimBLE-Arduino/examples/Refactored_original_examples/BLE_server_multiconnect/BLE_server_multiconnect.ino @@ -0,0 +1,151 @@ +/* + Video: https://www.youtube.com/watch?v=oCMOYS71NIU + Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleNotify.cpp + Ported to Arduino ESP32 by Evandro Copercini + updated by chegewara + + Create a BLE server that, once we receive a connection, will send periodic notifications. + The service advertises itself as: 4fafc201-1fb5-459e-8fcc-c5c9c331914b + And has a characteristic of: beb5483e-36e1-4688-b7f5-ea07361b26a8 + + The design of creating the BLE server is: + 1. Create a BLE Server + 2. Create a BLE Service + 3. Create a BLE Characteristic on the Service + 4. Create a BLE Descriptor on the characteristic + 5. Start the service. + 6. Start advertising. + + A connect hander associated with the server starts a background task that performs notification + every couple of seconds. +*/ + +/** NimBLE differences highlighted in comment blocks **/ + +/*******original******** +#include +#include +#include +#include +***********************/ +#include + +BLEServer* pServer = NULL; +BLECharacteristic* pCharacteristic = NULL; +bool deviceConnected = false; +bool oldDeviceConnected = false; +uint32_t value = 0; + +// See the following for generating UUIDs: +// https://www.uuidgenerator.net/ + +#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b" +#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8" + + +/** None of these are required as they will be handled by the library with defaults. ** + ** Remove as you see fit for your needs */ +class MyServerCallbacks: public BLEServerCallbacks { + void onConnect(BLEServer* pServer) { + deviceConnected = true; + BLEDevice::startAdvertising(); + }; + + void onDisconnect(BLEServer* pServer) { + deviceConnected = false; + } + /***************** New - Security handled here ******************** + ****** Note: these are the same return values as defaults ********/ + uint32_t onPassKeyRequest(){ + Serial.println("Server PassKeyRequest"); + return 123456; + } + + bool onConfirmPIN(uint32_t pass_key){ + Serial.print("The passkey YES/NO number: ");Serial.println(pass_key); + return true; + } + + void onAuthenticationComplete(ble_gap_conn_desc desc){ + Serial.println("Starting BLE work!"); + } + /*******************************************************************/ +}; + + + +void setup() { + Serial.begin(115200); + + // Create the BLE Device + BLEDevice::init("ESP32"); + + // Create the BLE Server + pServer = BLEDevice::createServer(); + pServer->setCallbacks(new MyServerCallbacks()); + + // Create the BLE Service + BLEService *pService = pServer->createService(SERVICE_UUID); + + // Create a BLE Characteristic + pCharacteristic = pService->createCharacteristic( + CHARACTERISTIC_UUID, + /******* Enum Type NIMBLE_PROPERTY now ******* + BLECharacteristic::PROPERTY_READ | + BLECharacteristic::PROPERTY_WRITE | + BLECharacteristic::PROPERTY_NOTIFY | + BLECharacteristic::PROPERTY_INDICATE + ); + **********************************************/ + NIMBLE_PROPERTY::READ | + NIMBLE_PROPERTY::WRITE | + NIMBLE_PROPERTY::NOTIFY | + NIMBLE_PROPERTY::INDICATE + ); + + // https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml + // Create a BLE Descriptor + /*********** New createDescriptor method ************ + NOTE: There is no need to create the 2902 descriptor + as it will be created automatically if notifications + or indications are enabled on a characteristic. + + pCharacteristic->addDescriptor(new BLE2902()); + ****************************************************/ + /** Add properties the same way as characteristics now **/ + + pCharacteristic->createDescriptor("2902" /** , NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE **/); + + // Start the service + pService->start(); + + // Start advertising + BLEAdvertising *pAdvertising = BLEDevice::getAdvertising(); + pAdvertising->addServiceUUID(SERVICE_UUID); + pAdvertising->setScanResponse(false); + pAdvertising->setMinPreferred(0x0); // set value to 0x00 to not advertise this parameter + BLEDevice::startAdvertising(); + Serial.println("Waiting a client connection to notify..."); +} + +void loop() { + // notify changed value + if (deviceConnected) { + pCharacteristic->setValue((uint8_t*)&value, 4); + pCharacteristic->notify(); + value++; + delay(10); // bluetooth stack will go into congestion, if too many packets are sent, in 6 hours test i was able to go as low as 3ms + } + // disconnecting + if (!deviceConnected && oldDeviceConnected) { + delay(500); // give the bluetooth stack the chance to get things ready + pServer->startAdvertising(); // restart advertising + Serial.println("start advertising"); + oldDeviceConnected = deviceConnected; + } + // connecting + if (deviceConnected && !oldDeviceConnected) { + // do stuff here on connecting + oldDeviceConnected = deviceConnected; + } +} diff --git a/libesp32/NimBLE-Arduino/examples/Refactored_original_examples/BLE_uart/BLE_uart.ino b/libesp32/NimBLE-Arduino/examples/Refactored_original_examples/BLE_uart/BLE_uart.ino new file mode 100644 index 000000000..b83470cf6 --- /dev/null +++ b/libesp32/NimBLE-Arduino/examples/Refactored_original_examples/BLE_uart/BLE_uart.ino @@ -0,0 +1,165 @@ +/* + Video: https://www.youtube.com/watch?v=oCMOYS71NIU + Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleNotify.cpp + Ported to Arduino ESP32 by Evandro Copercini + + Create a BLE server that, once we receive a connection, will send periodic notifications. + The service advertises itself as: 6E400001-B5A3-F393-E0A9-E50E24DCCA9E + Has a characteristic of: 6E400002-B5A3-F393-E0A9-E50E24DCCA9E - used for receiving data with "WRITE" + Has a characteristic of: 6E400003-B5A3-F393-E0A9-E50E24DCCA9E - used to send data with "NOTIFY" + + The design of creating the BLE server is: + 1. Create a BLE Server + 2. Create a BLE Service + 3. Create a BLE Characteristic on the Service + 4. Create a BLE Descriptor on the characteristic + 5. Start the service. + 6. Start advertising. + + In this example rxValue is the data received (only accessible inside that function). + And txValue is the data to be sent, in this example just a byte incremented every second. +*/ + +/** NimBLE differences highlighted in comment blocks **/ + +/*******original******** +#include +#include +#include +#include +***********************/ +#include + +BLEServer *pServer = NULL; +BLECharacteristic * pTxCharacteristic; +bool deviceConnected = false; +bool oldDeviceConnected = false; +uint8_t txValue = 0; + +// See the following for generating UUIDs: +// https://www.uuidgenerator.net/ + +#define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUID +#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E" +#define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E" + + +/** None of these are required as they will be handled by the library with defaults. ** + ** Remove as you see fit for your needs */ +class MyServerCallbacks: public BLEServerCallbacks { + void onConnect(BLEServer* pServer) { + deviceConnected = true; + }; + + void onDisconnect(BLEServer* pServer) { + deviceConnected = false; + } + /***************** New - Security handled here ******************** + ****** Note: these are the same return values as defaults ********/ + uint32_t onPassKeyRequest(){ + Serial.println("Server PassKeyRequest"); + return 123456; + } + + bool onConfirmPIN(uint32_t pass_key){ + Serial.print("The passkey YES/NO number: ");Serial.println(pass_key); + return true; + } + + void onAuthenticationComplete(ble_gap_conn_desc desc){ + Serial.println("Starting BLE work!"); + } + /*******************************************************************/ +}; + +class MyCallbacks: public BLECharacteristicCallbacks { + void onWrite(BLECharacteristic *pCharacteristic) { + std::string rxValue = pCharacteristic->getValue(); + + if (rxValue.length() > 0) { + Serial.println("*********"); + Serial.print("Received Value: "); + for (int i = 0; i < rxValue.length(); i++) + Serial.print(rxValue[i]); + + Serial.println(); + Serial.println("*********"); + } + } +}; + + +void setup() { + Serial.begin(115200); + + // Create the BLE Device + BLEDevice::init("UART Service"); + + // Create the BLE Server + pServer = BLEDevice::createServer(); + pServer->setCallbacks(new MyServerCallbacks()); + + // Create the BLE Service + BLEService *pService = pServer->createService(SERVICE_UUID); + + // Create a BLE Characteristic + pTxCharacteristic = pService->createCharacteristic( + CHARACTERISTIC_UUID_TX, + /******* Enum Type NIMBLE_PROPERTY now ******* + BLECharacteristic::PROPERTY_NOTIFY + ); + **********************************************/ + NIMBLE_PROPERTY::NOTIFY + ); + + /******* New createDescriptor method ******** + NOTE: There is no need to create the 2902 descriptor + as it will be created automatically if notifications or + indications are enabled on a characteristic. + + pCharacteristic->addDescriptor(new BLE2902()); + ********************************************/ + /** Add properties the same way as characteristics now **/ + pTxCharacteristic->createDescriptor("2902" /** , NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE **/); + + BLECharacteristic * pRxCharacteristic = pService->createCharacteristic( + CHARACTERISTIC_UUID_RX, + /******* Enum Type NIMBLE_PROPERTY now ******* + BLECharacteristic::PROPERTY_WRITE + ); + *********************************************/ + NIMBLE_PROPERTY::WRITE + ); + + pRxCharacteristic->setCallbacks(new MyCallbacks()); + + // Start the service + pService->start(); + + // Start advertising + pServer->getAdvertising()->start(); + Serial.println("Waiting a client connection to notify..."); +} + +void loop() { + + if (deviceConnected) { + pTxCharacteristic->setValue(&txValue, 1); + pTxCharacteristic->notify(); + txValue++; + delay(10); // bluetooth stack will go into congestion, if too many packets are sent + } + + // disconnecting + if (!deviceConnected && oldDeviceConnected) { + delay(500); // give the bluetooth stack the chance to get things ready + pServer->startAdvertising(); // restart advertising + Serial.println("start advertising"); + oldDeviceConnected = deviceConnected; + } + // connecting + if (deviceConnected && !oldDeviceConnected) { + // do stuff here on connecting + oldDeviceConnected = deviceConnected; + } +} diff --git a/libesp32/NimBLE-Arduino/examples/Refactored_original_examples/BLE_write/BLE_write.ino b/libesp32/NimBLE-Arduino/examples/Refactored_original_examples/BLE_write/BLE_write.ino new file mode 100644 index 000000000..b1eb0f83e --- /dev/null +++ b/libesp32/NimBLE-Arduino/examples/Refactored_original_examples/BLE_write/BLE_write.ino @@ -0,0 +1,75 @@ +/* + Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleWrite.cpp + Ported to Arduino ESP32 by Evandro Copercini +*/ + +/** NimBLE differences highlighted in comment blocks **/ + +/*******original******** +#include +#include +#include +***********************/ +#include + +// See the following for generating UUIDs: +// https://www.uuidgenerator.net/ + +#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b" +#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8" + + +class MyCallbacks: public BLECharacteristicCallbacks { + void onWrite(BLECharacteristic *pCharacteristic) { + std::string value = pCharacteristic->getValue(); + + if (value.length() > 0) { + Serial.println("*********"); + Serial.print("New value: "); + for (int i = 0; i < value.length(); i++) + Serial.print(value[i]); + + Serial.println(); + Serial.println("*********"); + } + } +}; + +void setup() { + Serial.begin(115200); + + Serial.println("1- Download and install an BLE scanner app in your phone"); + Serial.println("2- Scan for BLE devices in the app"); + Serial.println("3- Connect to MyESP32"); + Serial.println("4- Go to CUSTOM CHARACTERISTIC in CUSTOM SERVICE and write something"); + Serial.println("5- See the magic =)"); + + BLEDevice::init("MyESP32"); + BLEServer *pServer = BLEDevice::createServer(); + + BLEService *pService = pServer->createService(SERVICE_UUID); + + BLECharacteristic *pCharacteristic = pService->createCharacteristic( + CHARACTERISTIC_UUID, + /***** Enum Type NIMBLE_PROPERTY now ***** + BLECharacteristic::PROPERTY_READ | + BLECharacteristic::PROPERTY_WRITE + ); + *****************************************/ + NIMBLE_PROPERTY::READ | + NIMBLE_PROPERTY::WRITE + ); + + pCharacteristic->setCallbacks(new MyCallbacks()); + + pCharacteristic->setValue("Hello World"); + pService->start(); + + BLEAdvertising *pAdvertising = pServer->getAdvertising(); + pAdvertising->start(); +} + +void loop() { + // put your main code here, to run repeatedly: + delay(2000); +} \ No newline at end of file diff --git a/libesp32/NimBLE-Arduino/library.properties b/libesp32/NimBLE-Arduino/library.properties new file mode 100644 index 000000000..236fcd606 --- /dev/null +++ b/libesp32/NimBLE-Arduino/library.properties @@ -0,0 +1,10 @@ +name=NimBLE-Arduino +version=0.9.0 +author=H2zero +maintainer=h2zero +sentence=NimBLE library for Arduino +paragraph=A lighter-weight alternative to the bluedroid library for esp32. +url=https://github.com/h2zero/NimBLE-Arduino +category=Communication +architectures=esp32 +includes=NimBLEDevice.h \ No newline at end of file diff --git a/libesp32/NimBLE-Arduino/src/CODING_STANDARDS.md b/libesp32/NimBLE-Arduino/src/CODING_STANDARDS.md new file mode 100644 index 000000000..d14b9fdb1 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/CODING_STANDARDS.md @@ -0,0 +1,267 @@ +# Coding Style for Apache NimBLE + +Apache NimBLE project is part of Apache Mynewt projct and follows its coding +style. + +# Coding Style for Apache Mynewt Core + +This document is meant to define the coding style for Apache Mynewt, and +all subprojects of Apache Mynewt. This covers C and Assembly coding +conventions, *only*. Other languages (such as Go), have their own +coding conventions. + +## Headers + +* All files that are newly written, should have the Apache License clause +at the top of them. + +* For files that are copied from another source, but contain an Apache +compatible license, the original license header shall be maintained. + +* For more information on applying the Apache license, the definitive +source is here: http://www.apache.org/dev/apply-license.html + +* The Apache License clause for the top of files is as follows: + +```no-highlight +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +``` + +## Whitespace and Braces + +* Code must be indented to 4 spaces, tabs should not be used. + +* Do not add whitespace at the end of a line. + +* Put space after keywords (for, if, return, switch, while). + +* for, else, if, while statements must have braces around their +code blocks, i.e., do: + +``` + if (x) { + assert(0); + } else { + assert(0); + } +``` + +Not: + +``` + if (x) + assert(0); + else + assert(0); +``` + +* Braces for statements must be on the same line as the statement. Good: + +``` + for (i = 0; i < 10; i++) { + if (i == 5) { + break; + } else { + continue; + } + } +``` + +Not: + +``` + for (i = 0; i < 10; i++) + { <-- brace must be on same line as for + if (i == 5) { + break; + } <-- no new line between else + else { + continue; + } + } +``` + +* After a function declaration, the braces should be on a newline, i.e. do: + +``` + static void * + function(int var1, int var2) + { +``` + +not: + +``` + static void * + function(int var1, int var2) { +``` + +## Line Length and Wrap + +* Line length should never exceed 79 columns. + +* When you have to wrap a long statement, put the operator at the end of the + line. i.e.: + +``` + if (x && + y == 10 && + b) +``` + +Not: + +``` + if (x + && y == 10 + && b) +``` + +## Comments + +* No C++ style comments allowed. + +* When using a single line comment, put it above the line of code that you +intend to comment, i.e., do: + +``` + /* check variable */ + if (a) { +``` + +Not: + +``` + if (a) { /* check variable */ +``` + + +* All public APIs should be commented with Doxygen style comments describing +purpose, parameters and return values. Private APIs need not be documented. + + +## Header files + +* Header files must contain the following structure: + * Apache License (see above) + * ```#ifdef``` aliasing, to prevent multiple includes + * ```#include``` directives for other required header files + * ```#ifdef __cplusplus``` wrappers to maintain C++ friendly APIs + * Contents of the header file + +* ```#ifdef``` aliasing, shall be in the following format, where +the package name is "os" and the file name is "callout.h": + +```no-highlight +#ifndef _OS_CALLOUT_H +#define _OS_CALLOUT_H +``` + +* ```#include``` directives must happen prior to the cplusplus +wrapper. + +* The cplusplus wrapper must have the following format, and precedes +any contents of the header file: + +```no-highlight +#ifdef __cplusplus +#extern "C" { +##endif +``` + +## Naming + +* Names of functions, structures and variables must be in all lowercase. + +* Names should be as short as possible, but no shorter. + +* Globally visible names must be prefixed with the name of the module, +followed by the '_' character, i.e.: + +``` + os_callout_init(&c) +``` + +Not: + +``` + callout_init(c) +``` + +## Functions + +* No spaces after function names when calling a function, i.e, do: + +``` + rc = function(a) +``` + +Not: + +``` + rc = function (a) +``` + + +* Arguments to function calls should have spaces between the comma, i.e. do: + +``` + rc = function(a, b) +``` + +Not: + +``` + rc = function(a,b) +``` + +* The function type must be on a line by itself preceding the function, i.e. do: + +``` + static void * + function(int var1, int var2) + { +``` + +Not: + +``` + static void *function(int var1, int var2) + { +``` + +* In general, for functions that return values that denote success or error, 0 +shall be success, and non-zero shall be the failure code. + +## Variables and Macros + +* Do not use typedefs for structures. This makes it impossible for +applications to use pointers to those structures opaquely. + +* typedef may be used for non-structure types, where it is beneficial to +hide or alias the underlying type used (e.g. ```os_time_t```.) Indicate +typedefs by applying the ```_t``` marker to them. + +* Place all function-local variable definitions at the top of the function body, before any statements. + +## Compiler Directives + +* Code must compile cleanly with -Wall enabled. + diff --git a/libesp32/NimBLE-Arduino/src/FreeRTOS.cpp b/libesp32/NimBLE-Arduino/src/FreeRTOS.cpp new file mode 100644 index 000000000..f6bbe171b --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/FreeRTOS.cpp @@ -0,0 +1,309 @@ +/* + * FreeRTOS.cpp + * + * Created on: Feb 24, 2017 + * Author: kolban + */ +#include "sdkconfig.h" +#include "FreeRTOS.h" +#include "NimBLELog.h" + +#include // Include the base FreeRTOS definitions +#include // Include the task definitions +#include // Include the semaphore definitions +#include + +static const char* LOG_TAG = "FreeRTOS"; + + +/** + * Sleep for the specified number of milliseconds. + * @param[in] ms The period in milliseconds for which to sleep. + */ +void FreeRTOS::sleep(uint32_t ms) { + ::vTaskDelay(ms / portTICK_PERIOD_MS); +} // sleep + + +/** + * Start a new task. + * @param[in] task The function pointer to the function to be run in the task. + * @param[in] taskName A string identifier for the task. + * @param[in] param An optional parameter to be passed to the started task. + * @param[in] stackSize An optional paremeter supplying the size of the stack in which to run the task. + */ +void FreeRTOS::startTask(void task(void*), std::string taskName, void* param, uint32_t stackSize) { + ::xTaskCreate(task, taskName.data(), stackSize, param, 5, NULL); +} // startTask + + +/** + * Delete the task. + * @param[in] pTask An optional handle to the task to be deleted. If not supplied the calling task will be deleted. + */ +void FreeRTOS::deleteTask(TaskHandle_t pTask) { + ::vTaskDelete(pTask); +} // deleteTask + + +/** + * Get the time in milliseconds since the %FreeRTOS scheduler started. + * @return The time in milliseconds since the %FreeRTOS scheduler started. + */ +uint32_t FreeRTOS::getTimeSinceStart() { + return (uint32_t) (xTaskGetTickCount() * portTICK_PERIOD_MS); +} // getTimeSinceStart + + +/** + * @brief Wait for a semaphore to be released by trying to take it and + * then releasing it again. + * @param [in] owner A debug tag. + * @return The value associated with the semaphore. + */ +uint32_t FreeRTOS::Semaphore::wait(std::string owner) { + NIMBLE_LOGD(LOG_TAG, ">> wait: Semaphore waiting: %s for %s", toString().c_str(), owner.c_str()); + + if (m_usePthreads) { + pthread_mutex_lock(&m_pthread_mutex); + } else { + xSemaphoreTake(m_semaphore, portMAX_DELAY); + } + + if (m_usePthreads) { + pthread_mutex_unlock(&m_pthread_mutex); + } else { + xSemaphoreGive(m_semaphore); + } + + NIMBLE_LOGD(LOG_TAG, "<< wait: Semaphore released: %s", toString().c_str()); + return m_value; +} // wait + + +/** + * @brief Wait for a semaphore to be released in a given period of time by trying to take it and + * then releasing it again. The value associated with the semaphore can be taken by value() call after return + * @param [in] owner A debug tag. + * @param [in] timeoutMs timeout to wait in ms. + * @return True if we took the semaphore within timeframe. + */ +bool FreeRTOS::Semaphore::timedWait(std::string owner, uint32_t timeoutMs) { + NIMBLE_LOGD(LOG_TAG, ">> wait: Semaphore waiting: %s for %s", toString().c_str(), owner.c_str()); + + if (m_usePthreads && timeoutMs != portMAX_DELAY) { + assert(false); // We apparently don't have a timed wait for pthreads. + } + + auto ret = pdTRUE; + + if (m_usePthreads) { + pthread_mutex_lock(&m_pthread_mutex); + } else { + ret = xSemaphoreTake(m_semaphore, timeoutMs); + } + + if (m_usePthreads) { + pthread_mutex_unlock(&m_pthread_mutex); + } else { + xSemaphoreGive(m_semaphore); + } + + NIMBLE_LOGD(LOG_TAG, "<< wait: Semaphore %s released: %d", toString().c_str(), ret); + return ret; +} // wait + + +FreeRTOS::Semaphore::Semaphore(std::string name) { + m_usePthreads = false; // Are we using pThreads or FreeRTOS? + if (m_usePthreads) { + pthread_mutex_init(&m_pthread_mutex, nullptr); + } else { + //m_semaphore = xSemaphoreCreateMutex(); + m_semaphore = xSemaphoreCreateBinary(); + xSemaphoreGive(m_semaphore); + } + + m_name = name; + m_owner = std::string(""); + m_value = 0; +} + + +FreeRTOS::Semaphore::~Semaphore() { + if (m_usePthreads) { + pthread_mutex_destroy(&m_pthread_mutex); + } else { + vSemaphoreDelete(m_semaphore); + } +} + + +/** + * @brief Give a semaphore. + * The Semaphore is given. + */ +void FreeRTOS::Semaphore::give() { + NIMBLE_LOGD(LOG_TAG, "Semaphore giving: %s", toString().c_str()); + m_owner = std::string(""); + + if (m_usePthreads) { + pthread_mutex_unlock(&m_pthread_mutex); + } else { + xSemaphoreGive(m_semaphore); + } +// #ifdef ARDUINO_ARCH_ESP32 +// FreeRTOS::sleep(10); +// #endif + +} // Semaphore::give + + +/** + * @brief Give a semaphore. + * The Semaphore is given with an associated value. + * @param [in] value The value to associate with the semaphore. + */ +void FreeRTOS::Semaphore::give(uint32_t value) { + m_value = value; + give(); +} // give + + +/** + * @brief Give a semaphore from an ISR. + */ +void FreeRTOS::Semaphore::giveFromISR() { + BaseType_t higherPriorityTaskWoken; + if (m_usePthreads) { + assert(false); + } else { + xSemaphoreGiveFromISR(m_semaphore, &higherPriorityTaskWoken); + } +} // giveFromISR + + +/** + * @brief Take a semaphore. + * Take a semaphore and wait indefinitely. + * @param [in] owner The new owner (for debugging) + * @return True if we took the semaphore. + */ +bool FreeRTOS::Semaphore::take(std::string owner) { + NIMBLE_LOGD(LOG_TAG, "Semaphore taking: %s for %s", toString().c_str(), owner.c_str()); + bool rc = false; + if (m_usePthreads) { + pthread_mutex_lock(&m_pthread_mutex); + } else { + rc = ::xSemaphoreTake(m_semaphore, portMAX_DELAY) == pdTRUE; + } + m_owner = owner; + if (rc) { + NIMBLE_LOGD(LOG_TAG, "Semaphore taken: %s", toString().c_str()); + } else { + NIMBLE_LOGE(LOG_TAG, "Semaphore NOT taken: %s", toString().c_str()); + } + return rc; +} // Semaphore::take + + +/** + * @brief Take a semaphore. + * Take a semaphore but return if we haven't obtained it in the given period of milliseconds. + * @param [in] timeoutMs Timeout in milliseconds. + * @param [in] owner The new owner (for debugging) + * @return True if we took the semaphore. + */ +bool FreeRTOS::Semaphore::take(uint32_t timeoutMs, std::string owner) { + NIMBLE_LOGD(LOG_TAG, "Semaphore taking: %s for %s", toString().c_str(), owner.c_str()); + bool rc = false; + if (m_usePthreads) { + assert(false); // We apparently don't have a timed wait for pthreads. + } else { + rc = ::xSemaphoreTake(m_semaphore, timeoutMs / portTICK_PERIOD_MS) == pdTRUE; + } + m_owner = owner; + if (rc) { + NIMBLE_LOGD(LOG_TAG, "Semaphore taken: %s", toString().c_str()); + } else { + NIMBLE_LOGE(LOG_TAG, "Semaphore NOT taken: %s", toString().c_str()); + } + return rc; +} // Semaphore::take + + + +/** + * @brief Create a string representation of the semaphore. + * @return A string representation of the semaphore. + */ +std::string FreeRTOS::Semaphore::toString() { + char hex[9]; + std::string res = "name: " + m_name + " (0x"; + snprintf(hex, sizeof(hex), "%08x", (uint32_t)m_semaphore); + res += hex; + res += "), owner: " + m_owner; + return res; +} // toString + + +/** + * @brief Set the name of the semaphore. + * @param [in] name The name of the semaphore. + */ +void FreeRTOS::Semaphore::setName(std::string name) { + m_name = name; +} // setName + + +/** + * @brief Create a ring buffer. + * @param [in] length The amount of storage to allocate for the ring buffer. + * @param [in] type The type of buffer. One of RINGBUF_TYPE_NOSPLIT, RINGBUF_TYPE_ALLOWSPLIT, RINGBUF_TYPE_BYTEBUF. + */ +#ifdef ESP_IDF_VERSION //Quick hack to detect if using IDF version that replaced ringbuf_type_t +Ringbuffer::Ringbuffer(size_t length, RingbufferType_t type) { +#else +Ringbuffer::Ringbuffer(size_t length, ringbuf_type_t type) { +#endif + m_handle = ::xRingbufferCreate(length, type); +} // Ringbuffer + + +Ringbuffer::~Ringbuffer() { + ::vRingbufferDelete(m_handle); +} // ~Ringbuffer + + +/** + * @brief Receive data from the buffer. + * @param [out] size On return, the size of data returned. + * @param [in] wait How long to wait. + * @return A pointer to the storage retrieved. + */ +void* Ringbuffer::receive(size_t* size, TickType_t wait) { + return ::xRingbufferReceive(m_handle, size, wait); +} // receive + + +/** + * @brief Return an item. + * @param [in] item The item to be returned/released. + */ +void Ringbuffer::returnItem(void* item) { + ::vRingbufferReturnItem(m_handle, item); +} // returnItem + + +/** + * @brief Send data to the buffer. + * @param [in] data The data to place into the buffer. + * @param [in] length The length of data to place into the buffer. + * @param [in] wait How long to wait before giving up. The default is to wait indefinitely. + * @return + */ +bool Ringbuffer::send(void* data, size_t length, TickType_t wait) { + return ::xRingbufferSend(m_handle, data, length, wait) == pdTRUE; +} // send + + diff --git a/libesp32/NimBLE-Arduino/src/FreeRTOS.h b/libesp32/NimBLE-Arduino/src/FreeRTOS.h new file mode 100644 index 000000000..a6737b757 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/FreeRTOS.h @@ -0,0 +1,78 @@ +/* + * FreeRTOS.h + * + * Created on: Feb 24, 2017 + * Author: kolban + */ + +#ifndef MAIN_FREERTOS_H_ +#define MAIN_FREERTOS_H_ + +#include // Include the base FreeRTOS definitions. +#include // Include the task definitions. +#include // Include the semaphore definitions. +#include // Include the ringbuffer definitions. + +#include +#include +#include + + +/** + * @brief Interface to %FreeRTOS functions. + */ +class FreeRTOS { +public: + static void sleep(uint32_t ms); + static void startTask(void task(void*), std::string taskName, void* param = nullptr, uint32_t stackSize = 2048); + static void deleteTask(TaskHandle_t pTask = nullptr); + + static uint32_t getTimeSinceStart(); + + class Semaphore { + public: + Semaphore(std::string owner = ""); + ~Semaphore(); + void give(); + void give(uint32_t value); + void giveFromISR(); + void setName(std::string name); + bool take(std::string owner = ""); + bool take(uint32_t timeoutMs, std::string owner = ""); + std::string toString(); + bool timedWait(std::string owner = "", uint32_t timeoutMs = portMAX_DELAY); + uint32_t wait(std::string owner = ""); + uint32_t value(){ return m_value; }; + + private: + SemaphoreHandle_t m_semaphore; + pthread_mutex_t m_pthread_mutex; + std::string m_name; + std::string m_owner; + uint32_t m_value; + bool m_usePthreads; + + }; +}; + + +/** + * @brief Ringbuffer. + */ +class Ringbuffer { +public: +#ifdef ESP_IDF_VERSION //Quick hack to detect if using IDF version that replaced ringbuf_type_t + Ringbuffer(size_t length, RingbufferType_t type = RINGBUF_TYPE_NOSPLIT); +#else + Ringbuffer(size_t length, ringbuf_type_t type = RINGBUF_TYPE_NOSPLIT); +#endif + ~Ringbuffer(); + + void* receive(size_t* size, TickType_t wait = portMAX_DELAY); + void returnItem(void* item); + bool send(void* data, size_t length, TickType_t wait = portMAX_DELAY); +private: + RingbufHandle_t m_handle; +}; + +#endif /* MAIN_FREERTOS_H_ */ diff --git a/libesp32/NimBLE-Arduino/src/HIDKeyboardTypes.h b/libesp32/NimBLE-Arduino/src/HIDKeyboardTypes.h new file mode 100644 index 000000000..531437ee4 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/HIDKeyboardTypes.h @@ -0,0 +1,402 @@ +/* Copyright (c) 2015 mbed.org, MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Note: this file was pulled from different parts of the USBHID library, in mbed SDK + */ + +#ifndef KEYBOARD_DEFS_H +#define KEYBOARD_DEFS_H + +#define REPORT_ID_KEYBOARD 1 +#define REPORT_ID_VOLUME 3 + +/* Modifiers */ +enum MODIFIER_KEY { + KEY_CTRL = 1, + KEY_SHIFT = 2, + KEY_ALT = 4, +}; + + +enum MEDIA_KEY { + KEY_NEXT_TRACK, /*!< next Track Button */ + KEY_PREVIOUS_TRACK, /*!< Previous track Button */ + KEY_STOP, /*!< Stop Button */ + KEY_PLAY_PAUSE, /*!< Play/Pause Button */ + KEY_MUTE, /*!< Mute Button */ + KEY_VOLUME_UP, /*!< Volume Up Button */ + KEY_VOLUME_DOWN, /*!< Volume Down Button */ +}; + +enum FUNCTION_KEY { + KEY_F1 = 128, /* F1 key */ + KEY_F2, /* F2 key */ + KEY_F3, /* F3 key */ + KEY_F4, /* F4 key */ + KEY_F5, /* F5 key */ + KEY_F6, /* F6 key */ + KEY_F7, /* F7 key */ + KEY_F8, /* F8 key */ + KEY_F9, /* F9 key */ + KEY_F10, /* F10 key */ + KEY_F11, /* F11 key */ + KEY_F12, /* F12 key */ + + KEY_PRINT_SCREEN, /* Print Screen key */ + KEY_SCROLL_LOCK, /* Scroll lock */ + KEY_CAPS_LOCK, /* caps lock */ + KEY_NUM_LOCK, /* num lock */ + KEY_INSERT, /* Insert key */ + KEY_HOME, /* Home key */ + KEY_PAGE_UP, /* Page Up key */ + KEY_PAGE_DOWN, /* Page Down key */ + + RIGHT_ARROW, /* Right arrow */ + LEFT_ARROW, /* Left arrow */ + DOWN_ARROW, /* Down arrow */ + UP_ARROW, /* Up arrow */ +}; + +typedef struct { + unsigned char usage; + unsigned char modifier; +} KEYMAP; + +#ifdef US_KEYBOARD +/* US keyboard (as HID standard) */ +#define KEYMAP_SIZE (152) +const KEYMAP keymap[KEYMAP_SIZE] = { + {0, 0}, /* NUL */ + {0, 0}, /* SOH */ + {0, 0}, /* STX */ + {0, 0}, /* ETX */ + {0, 0}, /* EOT */ + {0, 0}, /* ENQ */ + {0, 0}, /* ACK */ + {0, 0}, /* BEL */ + {0x2a, 0}, /* BS */ /* Keyboard Delete (Backspace) */ + {0x2b, 0}, /* TAB */ /* Keyboard Tab */ + {0x28, 0}, /* LF */ /* Keyboard Return (Enter) */ + {0, 0}, /* VT */ + {0, 0}, /* FF */ + {0, 0}, /* CR */ + {0, 0}, /* SO */ + {0, 0}, /* SI */ + {0, 0}, /* DEL */ + {0, 0}, /* DC1 */ + {0, 0}, /* DC2 */ + {0, 0}, /* DC3 */ + {0, 0}, /* DC4 */ + {0, 0}, /* NAK */ + {0, 0}, /* SYN */ + {0, 0}, /* ETB */ + {0, 0}, /* CAN */ + {0, 0}, /* EM */ + {0, 0}, /* SUB */ + {0, 0}, /* ESC */ + {0, 0}, /* FS */ + {0, 0}, /* GS */ + {0, 0}, /* RS */ + {0, 0}, /* US */ + {0x2c, 0}, /* */ + {0x1e, KEY_SHIFT}, /* ! */ + {0x34, KEY_SHIFT}, /* " */ + {0x20, KEY_SHIFT}, /* # */ + {0x21, KEY_SHIFT}, /* $ */ + {0x22, KEY_SHIFT}, /* % */ + {0x24, KEY_SHIFT}, /* & */ + {0x34, 0}, /* ' */ + {0x26, KEY_SHIFT}, /* ( */ + {0x27, KEY_SHIFT}, /* ) */ + {0x25, KEY_SHIFT}, /* * */ + {0x2e, KEY_SHIFT}, /* + */ + {0x36, 0}, /* , */ + {0x2d, 0}, /* - */ + {0x37, 0}, /* . */ + {0x38, 0}, /* / */ + {0x27, 0}, /* 0 */ + {0x1e, 0}, /* 1 */ + {0x1f, 0}, /* 2 */ + {0x20, 0}, /* 3 */ + {0x21, 0}, /* 4 */ + {0x22, 0}, /* 5 */ + {0x23, 0}, /* 6 */ + {0x24, 0}, /* 7 */ + {0x25, 0}, /* 8 */ + {0x26, 0}, /* 9 */ + {0x33, KEY_SHIFT}, /* : */ + {0x33, 0}, /* ; */ + {0x36, KEY_SHIFT}, /* < */ + {0x2e, 0}, /* = */ + {0x37, KEY_SHIFT}, /* > */ + {0x38, KEY_SHIFT}, /* ? */ + {0x1f, KEY_SHIFT}, /* @ */ + {0x04, KEY_SHIFT}, /* A */ + {0x05, KEY_SHIFT}, /* B */ + {0x06, KEY_SHIFT}, /* C */ + {0x07, KEY_SHIFT}, /* D */ + {0x08, KEY_SHIFT}, /* E */ + {0x09, KEY_SHIFT}, /* F */ + {0x0a, KEY_SHIFT}, /* G */ + {0x0b, KEY_SHIFT}, /* H */ + {0x0c, KEY_SHIFT}, /* I */ + {0x0d, KEY_SHIFT}, /* J */ + {0x0e, KEY_SHIFT}, /* K */ + {0x0f, KEY_SHIFT}, /* L */ + {0x10, KEY_SHIFT}, /* M */ + {0x11, KEY_SHIFT}, /* N */ + {0x12, KEY_SHIFT}, /* O */ + {0x13, KEY_SHIFT}, /* P */ + {0x14, KEY_SHIFT}, /* Q */ + {0x15, KEY_SHIFT}, /* R */ + {0x16, KEY_SHIFT}, /* S */ + {0x17, KEY_SHIFT}, /* T */ + {0x18, KEY_SHIFT}, /* U */ + {0x19, KEY_SHIFT}, /* V */ + {0x1a, KEY_SHIFT}, /* W */ + {0x1b, KEY_SHIFT}, /* X */ + {0x1c, KEY_SHIFT}, /* Y */ + {0x1d, KEY_SHIFT}, /* Z */ + {0x2f, 0}, /* [ */ + {0x31, 0}, /* \ */ + {0x30, 0}, /* ] */ + {0x23, KEY_SHIFT}, /* ^ */ + {0x2d, KEY_SHIFT}, /* _ */ + {0x35, 0}, /* ` */ + {0x04, 0}, /* a */ + {0x05, 0}, /* b */ + {0x06, 0}, /* c */ + {0x07, 0}, /* d */ + {0x08, 0}, /* e */ + {0x09, 0}, /* f */ + {0x0a, 0}, /* g */ + {0x0b, 0}, /* h */ + {0x0c, 0}, /* i */ + {0x0d, 0}, /* j */ + {0x0e, 0}, /* k */ + {0x0f, 0}, /* l */ + {0x10, 0}, /* m */ + {0x11, 0}, /* n */ + {0x12, 0}, /* o */ + {0x13, 0}, /* p */ + {0x14, 0}, /* q */ + {0x15, 0}, /* r */ + {0x16, 0}, /* s */ + {0x17, 0}, /* t */ + {0x18, 0}, /* u */ + {0x19, 0}, /* v */ + {0x1a, 0}, /* w */ + {0x1b, 0}, /* x */ + {0x1c, 0}, /* y */ + {0x1d, 0}, /* z */ + {0x2f, KEY_SHIFT}, /* { */ + {0x31, KEY_SHIFT}, /* | */ + {0x30, KEY_SHIFT}, /* } */ + {0x35, KEY_SHIFT}, /* ~ */ + {0,0}, /* DEL */ + + {0x3a, 0}, /* F1 */ + {0x3b, 0}, /* F2 */ + {0x3c, 0}, /* F3 */ + {0x3d, 0}, /* F4 */ + {0x3e, 0}, /* F5 */ + {0x3f, 0}, /* F6 */ + {0x40, 0}, /* F7 */ + {0x41, 0}, /* F8 */ + {0x42, 0}, /* F9 */ + {0x43, 0}, /* F10 */ + {0x44, 0}, /* F11 */ + {0x45, 0}, /* F12 */ + + {0x46, 0}, /* PRINT_SCREEN */ + {0x47, 0}, /* SCROLL_LOCK */ + {0x39, 0}, /* CAPS_LOCK */ + {0x53, 0}, /* NUM_LOCK */ + {0x49, 0}, /* INSERT */ + {0x4a, 0}, /* HOME */ + {0x4b, 0}, /* PAGE_UP */ + {0x4e, 0}, /* PAGE_DOWN */ + + {0x4f, 0}, /* RIGHT_ARROW */ + {0x50, 0}, /* LEFT_ARROW */ + {0x51, 0}, /* DOWN_ARROW */ + {0x52, 0}, /* UP_ARROW */ +}; + +#else +/* UK keyboard */ +#define KEYMAP_SIZE (152) +const KEYMAP keymap[KEYMAP_SIZE] = { + {0, 0}, /* NUL */ + {0, 0}, /* SOH */ + {0, 0}, /* STX */ + {0, 0}, /* ETX */ + {0, 0}, /* EOT */ + {0, 0}, /* ENQ */ + {0, 0}, /* ACK */ + {0, 0}, /* BEL */ + {0x2a, 0}, /* BS */ /* Keyboard Delete (Backspace) */ + {0x2b, 0}, /* TAB */ /* Keyboard Tab */ + {0x28, 0}, /* LF */ /* Keyboard Return (Enter) */ + {0, 0}, /* VT */ + {0, 0}, /* FF */ + {0, 0}, /* CR */ + {0, 0}, /* SO */ + {0, 0}, /* SI */ + {0, 0}, /* DEL */ + {0, 0}, /* DC1 */ + {0, 0}, /* DC2 */ + {0, 0}, /* DC3 */ + {0, 0}, /* DC4 */ + {0, 0}, /* NAK */ + {0, 0}, /* SYN */ + {0, 0}, /* ETB */ + {0, 0}, /* CAN */ + {0, 0}, /* EM */ + {0, 0}, /* SUB */ + {0, 0}, /* ESC */ + {0, 0}, /* FS */ + {0, 0}, /* GS */ + {0, 0}, /* RS */ + {0, 0}, /* US */ + {0x2c, 0}, /* */ + {0x1e, KEY_SHIFT}, /* ! */ + {0x1f, KEY_SHIFT}, /* " */ + {0x32, 0}, /* # */ + {0x21, KEY_SHIFT}, /* $ */ + {0x22, KEY_SHIFT}, /* % */ + {0x24, KEY_SHIFT}, /* & */ + {0x34, 0}, /* ' */ + {0x26, KEY_SHIFT}, /* ( */ + {0x27, KEY_SHIFT}, /* ) */ + {0x25, KEY_SHIFT}, /* * */ + {0x2e, KEY_SHIFT}, /* + */ + {0x36, 0}, /* , */ + {0x2d, 0}, /* - */ + {0x37, 0}, /* . */ + {0x38, 0}, /* / */ + {0x27, 0}, /* 0 */ + {0x1e, 0}, /* 1 */ + {0x1f, 0}, /* 2 */ + {0x20, 0}, /* 3 */ + {0x21, 0}, /* 4 */ + {0x22, 0}, /* 5 */ + {0x23, 0}, /* 6 */ + {0x24, 0}, /* 7 */ + {0x25, 0}, /* 8 */ + {0x26, 0}, /* 9 */ + {0x33, KEY_SHIFT}, /* : */ + {0x33, 0}, /* ; */ + {0x36, KEY_SHIFT}, /* < */ + {0x2e, 0}, /* = */ + {0x37, KEY_SHIFT}, /* > */ + {0x38, KEY_SHIFT}, /* ? */ + {0x34, KEY_SHIFT}, /* @ */ + {0x04, KEY_SHIFT}, /* A */ + {0x05, KEY_SHIFT}, /* B */ + {0x06, KEY_SHIFT}, /* C */ + {0x07, KEY_SHIFT}, /* D */ + {0x08, KEY_SHIFT}, /* E */ + {0x09, KEY_SHIFT}, /* F */ + {0x0a, KEY_SHIFT}, /* G */ + {0x0b, KEY_SHIFT}, /* H */ + {0x0c, KEY_SHIFT}, /* I */ + {0x0d, KEY_SHIFT}, /* J */ + {0x0e, KEY_SHIFT}, /* K */ + {0x0f, KEY_SHIFT}, /* L */ + {0x10, KEY_SHIFT}, /* M */ + {0x11, KEY_SHIFT}, /* N */ + {0x12, KEY_SHIFT}, /* O */ + {0x13, KEY_SHIFT}, /* P */ + {0x14, KEY_SHIFT}, /* Q */ + {0x15, KEY_SHIFT}, /* R */ + {0x16, KEY_SHIFT}, /* S */ + {0x17, KEY_SHIFT}, /* T */ + {0x18, KEY_SHIFT}, /* U */ + {0x19, KEY_SHIFT}, /* V */ + {0x1a, KEY_SHIFT}, /* W */ + {0x1b, KEY_SHIFT}, /* X */ + {0x1c, KEY_SHIFT}, /* Y */ + {0x1d, KEY_SHIFT}, /* Z */ + {0x2f, 0}, /* [ */ + {0x64, 0}, /* \ */ + {0x30, 0}, /* ] */ + {0x23, KEY_SHIFT}, /* ^ */ + {0x2d, KEY_SHIFT}, /* _ */ + {0x35, 0}, /* ` */ + {0x04, 0}, /* a */ + {0x05, 0}, /* b */ + {0x06, 0}, /* c */ + {0x07, 0}, /* d */ + {0x08, 0}, /* e */ + {0x09, 0}, /* f */ + {0x0a, 0}, /* g */ + {0x0b, 0}, /* h */ + {0x0c, 0}, /* i */ + {0x0d, 0}, /* j */ + {0x0e, 0}, /* k */ + {0x0f, 0}, /* l */ + {0x10, 0}, /* m */ + {0x11, 0}, /* n */ + {0x12, 0}, /* o */ + {0x13, 0}, /* p */ + {0x14, 0}, /* q */ + {0x15, 0}, /* r */ + {0x16, 0}, /* s */ + {0x17, 0}, /* t */ + {0x18, 0}, /* u */ + {0x19, 0}, /* v */ + {0x1a, 0}, /* w */ + {0x1b, 0}, /* x */ + {0x1c, 0}, /* y */ + {0x1d, 0}, /* z */ + {0x2f, KEY_SHIFT}, /* { */ + {0x64, KEY_SHIFT}, /* | */ + {0x30, KEY_SHIFT}, /* } */ + {0x32, KEY_SHIFT}, /* ~ */ + {0,0}, /* DEL */ + + {0x3a, 0}, /* F1 */ + {0x3b, 0}, /* F2 */ + {0x3c, 0}, /* F3 */ + {0x3d, 0}, /* F4 */ + {0x3e, 0}, /* F5 */ + {0x3f, 0}, /* F6 */ + {0x40, 0}, /* F7 */ + {0x41, 0}, /* F8 */ + {0x42, 0}, /* F9 */ + {0x43, 0}, /* F10 */ + {0x44, 0}, /* F11 */ + {0x45, 0}, /* F12 */ + + {0x46, 0}, /* PRINT_SCREEN */ + {0x47, 0}, /* SCROLL_LOCK */ + {0x39, 0}, /* CAPS_LOCK */ + {0x53, 0}, /* NUM_LOCK */ + {0x49, 0}, /* INSERT */ + {0x4a, 0}, /* HOME */ + {0x4b, 0}, /* PAGE_UP */ + {0x4e, 0}, /* PAGE_DOWN */ + + {0x4f, 0}, /* RIGHT_ARROW */ + {0x50, 0}, /* LEFT_ARROW */ + {0x51, 0}, /* DOWN_ARROW */ + {0x52, 0}, /* UP_ARROW */ +}; +#endif + +#endif diff --git a/libesp32/NimBLE-Arduino/src/HIDTypes.h b/libesp32/NimBLE-Arduino/src/HIDTypes.h new file mode 100644 index 000000000..726b84be3 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/HIDTypes.h @@ -0,0 +1,96 @@ +/* Copyright (c) 2010-2011 mbed.org, MIT License +* +* Permission is hereby granted, free of charge, to any person obtaining a copy of this software +* and associated documentation files (the "Software"), to deal in the Software without +* restriction, including without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all copies or +* substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING +* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef USBCLASS_HID_TYPES +#define USBCLASS_HID_TYPES + +#include + +/* */ +#define HID_VERSION_1_11 (0x0111) + +/* HID Class */ +#define HID_CLASS (3) +#define HID_SUBCLASS_NONE (0) +#define HID_PROTOCOL_NONE (0) + +/* Descriptors */ +#define HID_DESCRIPTOR (33) +#define HID_DESCRIPTOR_LENGTH (0x09) +#define REPORT_DESCRIPTOR (34) + +/* Class requests */ +#define GET_REPORT (0x1) +#define GET_IDLE (0x2) +#define SET_REPORT (0x9) +#define SET_IDLE (0xa) + +/* HID Class Report Descriptor */ +/* Short items: size is 0, 1, 2 or 3 specifying 0, 1, 2 or 4 (four) bytes */ +/* of data as per HID Class standard */ + +/* Main items */ +#ifdef ARDUINO_ARCH_ESP32 +#define HIDINPUT(size) (0x80 | size) +#define HIDOUTPUT(size) (0x90 | size) +#else +#define INPUT(size) (0x80 | size) +#define OUTPUT(size) (0x90 | size) +#endif +#define FEATURE(size) (0xb0 | size) +#define COLLECTION(size) (0xa0 | size) +#define END_COLLECTION(size) (0xc0 | size) + +/* Global items */ +#define USAGE_PAGE(size) (0x04 | size) +#define LOGICAL_MINIMUM(size) (0x14 | size) +#define LOGICAL_MAXIMUM(size) (0x24 | size) +#define PHYSICAL_MINIMUM(size) (0x34 | size) +#define PHYSICAL_MAXIMUM(size) (0x44 | size) +#define UNIT_EXPONENT(size) (0x54 | size) +#define UNIT(size) (0x64 | size) +#define REPORT_SIZE(size) (0x74 | size) //bits +#define REPORT_ID(size) (0x84 | size) +#define REPORT_COUNT(size) (0x94 | size) //bytes +#define PUSH(size) (0xa4 | size) +#define POP(size) (0xb4 | size) + +/* Local items */ +#define USAGE(size) (0x08 | size) +#define USAGE_MINIMUM(size) (0x18 | size) +#define USAGE_MAXIMUM(size) (0x28 | size) +#define DESIGNATOR_INDEX(size) (0x38 | size) +#define DESIGNATOR_MINIMUM(size) (0x48 | size) +#define DESIGNATOR_MAXIMUM(size) (0x58 | size) +#define STRING_INDEX(size) (0x78 | size) +#define STRING_MINIMUM(size) (0x88 | size) +#define STRING_MAXIMUM(size) (0x98 | size) +#define DELIMITER(size) (0xa8 | size) + +/* HID Report */ +/* Where report IDs are used the first byte of 'data' will be the */ +/* report ID and 'length' will include this report ID byte. */ + +#define MAX_HID_REPORT_SIZE (64) + +typedef struct { + uint32_t length; + uint8_t data[MAX_HID_REPORT_SIZE]; +} HID_REPORT; + +#endif diff --git a/libesp32/NimBLE-Arduino/src/NOTICE b/libesp32/NimBLE-Arduino/src/NOTICE new file mode 100644 index 000000000..fc24c6abc --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NOTICE @@ -0,0 +1,8 @@ +Apache Mynewt NimBLE +Copyright 2015-2018 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + +Portions of this software were developed at +Runtime Inc, copyright 2015. diff --git a/libesp32/NimBLE-Arduino/src/NimBLE2902.cpp b/libesp32/NimBLE-Arduino/src/NimBLE2902.cpp new file mode 100644 index 000000000..04a07b6f9 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLE2902.cpp @@ -0,0 +1,79 @@ +/* + * NimBLE2902.cpp + * + * Created: on March 10, 2020 + * Author H2zero + * + * Originally: + * + * BLE2902.cpp + * + * Created on: Jun 25, 2017 + * Author: kolban + */ + + +/* + * See also: + * https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml + */ +#include "sdkconfig.h" +#if defined(CONFIG_BT_ENABLED) + +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + +#include "NimBLE2902.h" + +NimBLE2902::NimBLE2902(NimBLECharacteristic* pCharacterisitic) +: NimBLEDescriptor(NimBLEUUID((uint16_t) 0x2902), + BLE_GATT_CHR_F_READ | + BLE_GATT_CHR_F_WRITE, + 2, pCharacterisitic) +{ + uint8_t data[2] = { 0, 0 }; + setValue(data, 2); +} // NimBLE2902 + + +/** + * @brief Get the notifications value. + * @return The notifications value. True if notifications are enabled and false if not. + */ +bool NimBLE2902::getNotifications() { + return (getValue()[0] & (1 << 0)) != 0; +} // getNotifications + + +/** + * @brief Get the indications value. + * @return The indications value. True if indications are enabled and false if not. + */ +bool NimBLE2902::getIndications() { + return (getValue()[0] & (1 << 1)) != 0; +} // getIndications + + +/** + * @brief Set the indications flag. + * @param [in] flag The indications flag. + */ +void NimBLE2902::setIndications(bool flag) { + uint8_t *pValue = getValue(); + if (flag) pValue[0] |= 1 << 1; + else pValue[0] &= ~(1 << 1); +} // setIndications + + +/** + * @brief Set the notifications flag. + * @param [in] flag The notifications flag. + */ +void NimBLE2902::setNotifications(bool flag) { + uint8_t *pValue = getValue(); + if (flag) pValue[0] |= 1 << 0; + else pValue[0] &= ~(1 << 0); +} // setNotifications + +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) +#endif diff --git a/libesp32/NimBLE-Arduino/src/NimBLE2902.h b/libesp32/NimBLE-Arduino/src/NimBLE2902.h new file mode 100644 index 000000000..2d84b73dc --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLE2902.h @@ -0,0 +1,59 @@ +/* + * NimBLE2902.h + * + * Created: on March 10, 2020 + * Author H2zero + * + * Originally: + * + * BLE2902.h + * + * Created on: Jun 25, 2017 + * Author: kolban + */ + +#ifndef MAIN_NIMBLE2902_H_ +#define MAIN_NIMBLE2902_H_ +#include "sdkconfig.h" +#if defined(CONFIG_BT_ENABLED) + +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + +#include "NimBLEDescriptor.h" + +#include + +#define NIMBLE_DESC_FLAG_NOTIFY 0x0001 +#define NIMBLE_DESC_FLAG_INDICATE 0x0002 + +typedef struct { + uint16_t conn_id; + uint16_t sub_val; +} chr_sub_status_t; + + +/** + * @brief Descriptor for Client Characteristic Configuration. + * + * This is a convenience descriptor for the Client Characteristic Configuration which has a UUID of 0x2902. + * + * See also: + * https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml + */ +class NimBLE2902: public NimBLEDescriptor { +public: + bool getNotifications(); + bool getIndications(); + void setNotifications(bool flag); + void setIndications(bool flag); +private: + NimBLE2902(NimBLECharacteristic* pCharacterisitic); + friend class NimBLECharacteristic; + std::vector m_subscribedVec; + +}; // NimBLE2902 + +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) +#endif /* CONFIG_BT_ENABLED */ +#endif /* MAIN_NIMBLE2902_H_ */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLE2904.cpp b/libesp32/NimBLE-Arduino/src/NimBLE2904.cpp new file mode 100644 index 000000000..d85cd87e4 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLE2904.cpp @@ -0,0 +1,90 @@ +/* + * NimBLE2904.cpp + * + * Created: on March 13, 2020 + * Author H2zero + * + * Originally: + * + * BLE2904.cpp + * + * Created on: Dec 23, 2017 + * Author: kolban + */ + +/* + * See also: + * https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.characteristic_presentation_format.xml + */ +#include "sdkconfig.h" +#if defined(CONFIG_BT_ENABLED) + +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + +#include "NimBLE2904.h" + + +NimBLE2904::NimBLE2904(NimBLECharacteristic* pCharacterisitic) +: NimBLEDescriptor(NimBLEUUID((uint16_t) 0x2904), + BLE_GATT_CHR_F_READ, + sizeof(BLE2904_Data), + pCharacterisitic) +{ + m_data.m_format = 0; + m_data.m_exponent = 0; + m_data.m_namespace = 1; // 1 = Bluetooth SIG Assigned Numbers + m_data.m_unit = 0; + m_data.m_description = 0; + setValue((uint8_t*) &m_data, sizeof(m_data)); +} // BLE2902 + + +/** + * @brief Set the description. + */ +void NimBLE2904::setDescription(uint16_t description) { + m_data.m_description = description; + setValue((uint8_t*) &m_data, sizeof(m_data)); +} + + +/** + * @brief Set the exponent. + */ +void NimBLE2904::setExponent(int8_t exponent) { + m_data.m_exponent = exponent; + setValue((uint8_t*) &m_data, sizeof(m_data)); +} // setExponent + + +/** + * @brief Set the format. + */ +void NimBLE2904::setFormat(uint8_t format) { + m_data.m_format = format; + setValue((uint8_t*) &m_data, sizeof(m_data)); +} // setFormat + + +/** + * @brief Set the namespace. + */ +void NimBLE2904::setNamespace(uint8_t namespace_value) { + m_data.m_namespace = namespace_value; + setValue((uint8_t*) &m_data, sizeof(m_data)); +} // setNamespace + + +/** + * @brief Set the units for this value. It should be one of the encoded values defined here: + * https://www.bluetooth.com/specifications/assigned-numbers/units + * @param [in] unit The type of units of this characteristic as defined by assigned numbers. + */ +void NimBLE2904::setUnit(uint16_t unit) { + m_data.m_unit = unit; + setValue((uint8_t*) &m_data, sizeof(m_data)); +} // setUnit + +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) +#endif diff --git a/libesp32/NimBLE-Arduino/src/NimBLE2904.h b/libesp32/NimBLE-Arduino/src/NimBLE2904.h new file mode 100644 index 000000000..0a6d036a4 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLE2904.h @@ -0,0 +1,87 @@ +/* + * NimBLE2904.h + * + * Created: on March 13, 2020 + * Author H2zero + * + * Originally: + * + * BLE2904.h + * + * Created on: Dec 23, 2017 + * Author: kolban + */ + +#ifndef MAIN_NIMBLE2904_H_ +#define MAIN_NIMBLE2904_H_ +#include "sdkconfig.h" +#if defined(CONFIG_BT_ENABLED) + +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + +#include "NimBLEDescriptor.h" + +struct BLE2904_Data { + uint8_t m_format; + int8_t m_exponent; + uint16_t m_unit; // See https://www.bluetooth.com/specifications/assigned-numbers/units + uint8_t m_namespace; + uint16_t m_description; + +} __attribute__((packed)); + + +/** + * @brief Descriptor for Characteristic Presentation Format. + * + * This is a convenience descriptor for the Characteristic Presentation Format which has a UUID of 0x2904. + * + * See also: + * https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.characteristic_presentation_format.xml + */ +class NimBLE2904: public NimBLEDescriptor { +public: + static const uint8_t FORMAT_BOOLEAN = 1; + static const uint8_t FORMAT_UINT2 = 2; + static const uint8_t FORMAT_UINT4 = 3; + static const uint8_t FORMAT_UINT8 = 4; + static const uint8_t FORMAT_UINT12 = 5; + static const uint8_t FORMAT_UINT16 = 6; + static const uint8_t FORMAT_UINT24 = 7; + static const uint8_t FORMAT_UINT32 = 8; + static const uint8_t FORMAT_UINT48 = 9; + static const uint8_t FORMAT_UINT64 = 10; + static const uint8_t FORMAT_UINT128 = 11; + static const uint8_t FORMAT_SINT8 = 12; + static const uint8_t FORMAT_SINT12 = 13; + static const uint8_t FORMAT_SINT16 = 14; + static const uint8_t FORMAT_SINT24 = 15; + static const uint8_t FORMAT_SINT32 = 16; + static const uint8_t FORMAT_SINT48 = 17; + static const uint8_t FORMAT_SINT64 = 18; + static const uint8_t FORMAT_SINT128 = 19; + static const uint8_t FORMAT_FLOAT32 = 20; + static const uint8_t FORMAT_FLOAT64 = 21; + static const uint8_t FORMAT_SFLOAT16 = 22; + static const uint8_t FORMAT_SFLOAT32 = 23; + static const uint8_t FORMAT_IEEE20601 = 24; + static const uint8_t FORMAT_UTF8 = 25; + static const uint8_t FORMAT_UTF16 = 26; + static const uint8_t FORMAT_OPAQUE = 27; + + void setDescription(uint16_t); + void setExponent(int8_t exponent); + void setFormat(uint8_t format); + void setNamespace(uint8_t namespace_value); + void setUnit(uint16_t unit); + +private: + NimBLE2904(NimBLECharacteristic* pCharacterisitic); + friend class NimBLECharacteristic; + BLE2904_Data m_data; +}; // BLE2904 + +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) +#endif /* CONFIG_BT_ENABLED */ +#endif /* MAIN_NIMBLE2904_H_ */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLEAddress.cpp b/libesp32/NimBLE-Arduino/src/NimBLEAddress.cpp new file mode 100644 index 000000000..8c2c68f79 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLEAddress.cpp @@ -0,0 +1,151 @@ +/* + * NimBLEAddress.cpp + * + * Created: on Jan 24 2020 + * Author H2zero + * + * Originally: + * + * BLEAddress.cpp + * + * Created on: Jul 2, 2017 + * Author: kolban + */ +#include "sdkconfig.h" +#if defined(CONFIG_BT_ENABLED) + +#include + +#include "NimBLEAddress.h" +#include "NimBLEUtils.h" +#include "NimBLELog.h" + +static const char* LOG_TAG = "NimBLEAddress"; + +/************************************************* +NOTE: NimBLE addresses are in INVERSE ORDER! +We will accomodate that fact in these methods. +*************************************************/ + +/** + * @brief Create an address from the native ESP32 representation. + * @param [in] address The native representation. + */ +NimBLEAddress::NimBLEAddress(ble_addr_t address) { + memcpy(m_address, address.val, 6); +} // BLEAddress + + +/** + * @brief Create an address from a hex string + * + * A hex string is of the format: + * ``` + * 00:00:00:00:00:00 + * ``` + * which is 17 characters in length. + * + * @param [in] stringAddress The hex representation of the address. + */ +NimBLEAddress::NimBLEAddress(const std::string &stringAddress) { + if (stringAddress.length() == 0) { + memset(m_address, 0, 6); + return; + } + + if (stringAddress.length() == 6) { + std::reverse_copy(stringAddress.data(), stringAddress.data() + 6, m_address); + return; + } + + if (stringAddress.length() != 17) { + memset(m_address, 0, sizeof m_address); // "00:00:00:00:00:00" represents an invalid address + NIMBLE_LOGD(LOG_TAG, "Invalid address '%s'", stringAddress.c_str()); + return; + } + + int data[6]; + if(sscanf(stringAddress.c_str(), "%x:%x:%x:%x:%x:%x", &data[5], &data[4], &data[3], &data[2], &data[1], &data[0]) != 6) { + memset(m_address, 0, sizeof m_address); // "00:00:00:00:00:00" represents an invalid address + NIMBLE_LOGD(LOG_TAG, "Invalid address '%s'", stringAddress.c_str()); + } + for(size_t index = 0; index < sizeof m_address; index++) { + m_address[index] = data[index]; + } +} // BLEAddress + + +/** + * @brief Constructor for compatibility with bluedroid esp library. + * @param [in] uint8_t[6] or esp_bd_addr_t struct containing the address. + */ +NimBLEAddress::NimBLEAddress(uint8_t address[6]) { + std::reverse_copy(address, address + sizeof m_address, m_address); +} // NimBLEAddress + + +/** + * @brief Constructor for address using a hex value. Use the same byte order, so use 0xa4c1385def16 for "a4:c1:38:5d:ef:16" + * @param [in] uint64_t containing the address. + */ +NimBLEAddress::NimBLEAddress(const uint64_t &address) { + memcpy(m_address, &address, sizeof m_address); +} // NimBLEAddress + + +/** + * @brief Determine if this address equals another. + * @param [in] otherAddress The other address to compare against. + * @return True if the addresses are equal. + */ +bool NimBLEAddress::equals(const NimBLEAddress &otherAddress) const { + return *this == otherAddress; +} // equals + + +/** + * @brief Return the native representation of the address. + * @return The native representation of the address. + */ +const uint8_t *NimBLEAddress::getNative() const { + return m_address; +} // getNative + + +/** + * @brief Convert a BLE address to a string. + * + * A string representation of an address is in the format: + * + * ``` + * xx:xx:xx:xx:xx:xx + * ``` + * + * @return The string representation of the address. + */ +std::string NimBLEAddress::toString() const { + return std::string(*this); +} // toString + + +bool NimBLEAddress::operator ==(const NimBLEAddress & rhs) const { + return memcmp(rhs.m_address, m_address, sizeof m_address) == 0; +} + +bool NimBLEAddress::operator !=(const NimBLEAddress & rhs) const { + return !this->operator==(rhs); +} + +NimBLEAddress::operator std::string() const { + char buffer[18]; + sprintf(buffer, "%02x:%02x:%02x:%02x:%02x:%02x", m_address[5], m_address[4], m_address[3], m_address[2], m_address[1], m_address[0]); + return std::string(buffer); +} + +NimBLEAddress::operator uint64_t() const { + uint64_t address = 0; + memcpy(&address, m_address, sizeof m_address); + return address; +} + +#endif diff --git a/libesp32/NimBLE-Arduino/src/NimBLEAddress.h b/libesp32/NimBLE-Arduino/src/NimBLEAddress.h new file mode 100644 index 000000000..778ff8644 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLEAddress.h @@ -0,0 +1,54 @@ +/* + * NimBLEAddress.h + * + * Created: on Jan 24 2020 + * Author H2zero + * + * Originally: + * + * BLEAddress.h + * + * Created on: Jul 2, 2017 + * Author: kolban + */ + +#ifndef COMPONENTS_NIMBLEADDRESS_H_ +#define COMPONENTS_NIMBLEADDRESS_H_ +#include "sdkconfig.h" +#if defined(CONFIG_BT_ENABLED) + +#include "nimble/ble.h" +/**** FIX COMPILATION ****/ +#undef min +#undef max +/**************************/ + +#include +#include + +/** + * @brief A %BLE device address. + * + * Every %BLE device has a unique address which can be used to identify it and form connections. + */ +class NimBLEAddress { +public: + NimBLEAddress(ble_addr_t address); + NimBLEAddress(uint8_t address[6]); + NimBLEAddress(const std::string &stringAddress); + NimBLEAddress(const uint64_t &address); + bool equals(const NimBLEAddress &otherAddress) const; + const uint8_t* getNative() const; + std::string toString() const; + + bool operator ==(const NimBLEAddress & rhs) const; + bool operator !=(const NimBLEAddress & rhs) const; + operator std::string() const; + operator uint64_t() const; + +private: + uint8_t m_address[6]; +}; + +#endif /* CONFIG_BT_ENABLED */ +#endif /* COMPONENTS_NIMBLEADDRESS_H_ */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLEAdvertisedDevice.cpp b/libesp32/NimBLE-Arduino/src/NimBLEAdvertisedDevice.cpp new file mode 100644 index 000000000..c53bb688b --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLEAdvertisedDevice.cpp @@ -0,0 +1,574 @@ +/* + * NimBLEAdvertisedDevice.cpp + * + * Created: on Jan 24 2020 + * Author H2zero + * + * Originally: + * + * BLEAdvertisedDevice.cpp + * + * Created on: Jul 3, 2017 + * Author: kolban + */ +#include "sdkconfig.h" +#if defined(CONFIG_BT_ENABLED) + +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) + +#include "NimBLEAdvertisedDevice.h" +#include "NimBLEUtils.h" +#include "NimBLELog.h" + +static const char* LOG_TAG = "NimBLEAdvertisedDevice"; + + +/** + * @brief Constructor + */ +NimBLEAdvertisedDevice::NimBLEAdvertisedDevice() { + m_advType = 0; + m_appearance = 0; + m_deviceType = 0; + m_manufacturerData = ""; + m_name = ""; + m_rssi = -9999; + m_serviceData = ""; + m_txPower = 0; + m_pScan = nullptr; + m_payloadLength = 0; + m_payload = nullptr; + + m_haveAppearance = false; + m_haveManufacturerData = false; + m_haveName = false; + m_haveRSSI = false; + m_haveServiceData = false; + m_haveServiceUUID = false; + m_haveTXPower = false; + m_callbackSent = false; + +} // NimBLEAdvertisedDevice + + +/** + * @brief Get the address. + * + * Every %BLE device exposes an address that is used to identify it and subsequently connect to it. + * Call this function to obtain the address of the advertised device. + * + * @return The address of the advertised device. + */ +NimBLEAddress NimBLEAdvertisedDevice::getAddress() { + return m_address; +} // getAddress + + +/** + * @brief Get the advertised type. + * + * @return The advertised type of the advertised device. + */ +uint8_t NimBLEAdvertisedDevice::getAdvType() { + return m_advType; +} // getAddress + + +/** + * @brief Get the appearance. + * + * A %BLE device can declare its own appearance. The appearance is how it would like to be shown to an end user + * typcially in the form of an icon. + * + * @return The appearance of the advertised device. + */ +uint16_t NimBLEAdvertisedDevice::getAppearance() { + return m_appearance; +} // getAppearance + + +/** + * @brief Get the manufacturer data. + * @return The manufacturer data of the advertised device. + */ +std::string NimBLEAdvertisedDevice::getManufacturerData() { + return m_manufacturerData; +} // getManufacturerData + + +/** + * @brief Get the name. + * @return The name of the advertised device. + */ +std::string NimBLEAdvertisedDevice::getName() { + return m_name; +} // getName + + +/** + * @brief Get the RSSI. + * @return The RSSI of the advertised device. + */ +int NimBLEAdvertisedDevice::getRSSI() { + return m_rssi; +} // getRSSI + + +/** + * @brief Get the scan object that created this advertisement. + * @return The scan object. + */ +NimBLEScan* NimBLEAdvertisedDevice::getScan() { + return m_pScan; +} // getScan + + +/** + * @brief Get the service data. + * @return The ServiceData of the advertised device. + */ +std::string NimBLEAdvertisedDevice::getServiceData() { + return m_serviceData; +} //getServiceData + + +/** + * @brief Get the service data UUID. + * @return The service data UUID. + */ + +NimBLEUUID NimBLEAdvertisedDevice::getServiceDataUUID() { + return m_serviceDataUUID; +} // getServiceDataUUID + + +/** + * @brief Get the Service UUID. + * @return The Service UUID of the advertised device. + */ + +NimBLEUUID NimBLEAdvertisedDevice::getServiceUUID() { //TODO Remove it eventually, is no longer useful + return m_serviceUUIDs[0]; +} // getServiceUUID + + +/** + * @brief Check advertised serviced for existence required UUID + * @return Return true if service is advertised + */ +bool NimBLEAdvertisedDevice::isAdvertisingService(const NimBLEUUID &uuid){ + for (int i = 0; i < m_serviceUUIDs.size(); i++) { + NIMBLE_LOGI(LOG_TAG, "Comparing UUIDS: %s %s", m_serviceUUIDs[i].toString().c_str(), uuid.toString().c_str()); + if (m_serviceUUIDs[i].equals(uuid)) return true; + } + return false; +} + + +/** + * @brief Get the TX Power. + * @return The TX Power of the advertised device. + */ +int8_t NimBLEAdvertisedDevice::getTXPower() { + return m_txPower; +} // getTXPower + + +/** + * @brief Does this advertisement have an appearance value? + * @return True if there is an appearance value present. + */ +bool NimBLEAdvertisedDevice::haveAppearance() { + return m_haveAppearance; +} // haveAppearance + + +/** + * @brief Does this advertisement have manufacturer data? + * @return True if there is manufacturer data present. + */ +bool NimBLEAdvertisedDevice::haveManufacturerData() { + return m_haveManufacturerData; +} // haveManufacturerData + + +/** + * @brief Does this advertisement have a name value? + * @return True if there is a name value present. + */ +bool NimBLEAdvertisedDevice::haveName() { + return m_haveName; +} // haveName + + +/** + * @brief Does this advertisement have a signal strength value? + * @return True if there is a signal strength value present. + */ +bool NimBLEAdvertisedDevice::haveRSSI() { + return m_haveRSSI; +} // haveRSSI + + +/** + * @brief Does this advertisement have a service data value? + * @return True if there is a service data value present. + */ +bool NimBLEAdvertisedDevice::haveServiceData() { + return m_haveServiceData; +} // haveServiceData + + +/** + * @brief Does this advertisement have a service UUID value? + * @return True if there is a service UUID value present. + */ +bool NimBLEAdvertisedDevice::haveServiceUUID() { + return m_haveServiceUUID; +} // haveServiceUUID + + +/** + * @brief Does this advertisement have a transmission power value? + * @return True if there is a transmission power value present. + */ +bool NimBLEAdvertisedDevice::haveTXPower() { + return m_haveTXPower; +} // haveTXPower + + +/** + * @brief Parse the advertising pay load. + * + * The pay load is a buffer of bytes that is either 31 bytes long or terminated by + * a 0 length value. Each entry in the buffer has the format: + * [length][type][data...] + * + * The length does not include itself but does include everything after it until the next record. A record + * with a length value of 0 indicates a terminator. + * + * https://www.bluetooth.com/specifications/assigned-numbers/generic-access-profile + */ + void NimBLEAdvertisedDevice::parseAdvertisement(ble_hs_adv_fields *fields) { + //char s[BLE_HS_ADV_MAX_SZ]; + uint8_t *u8p; + uint8_t length; + int i; + + if (fields->uuids16 != NULL) { + for (i = 0; i < fields->num_uuids16; i++) { + setServiceUUID(NimBLEUUID(fields->uuids16[i].value)); + } + } + + if (fields->uuids32 != NULL) { + for (i = 0; i < fields->num_uuids32; i++) { + setServiceUUID(NimBLEUUID(fields->uuids32[i].value)); + } + } + + if (fields->uuids128 != NULL) { + for (i = 0; i < fields->num_uuids128; i++) { + setServiceUUID(NimBLEUUID(&fields->uuids128[i])); + } + } + + if (fields->name != NULL) { + setName(std::string(reinterpret_cast(fields->name), fields->name_len)); + } + + if (fields->tx_pwr_lvl_is_present) { + setTXPower(fields->tx_pwr_lvl); + } + + if (fields->svc_data_uuid16 != NULL) { + + u8p = fields->svc_data_uuid16; + length = fields->svc_data_uuid16_len; + + if (length < 2) { + NIMBLE_LOGE(LOG_TAG,"Length too small for ESP_BLE_AD_TYPE_SERVICE_DATA"); + } + else{ + uint16_t uuid = *(uint16_t*)u8p; + setServiceDataUUID(NimBLEUUID(uuid)); + if (length > 2) { + setServiceData(std::string(reinterpret_cast(u8p + 2), length - 2)); + } + } + } + + if (fields->svc_data_uuid32 != NULL) { + + u8p = fields->svc_data_uuid16; + length = fields->svc_data_uuid16_len; + + if (length < 4) { + NIMBLE_LOGE(LOG_TAG,"Length too small for ESP_BLE_AD_TYPE_32SERVICE_DATA"); + } + + uint32_t uuid = *(uint32_t*) u8p; + setServiceDataUUID(NimBLEUUID(uuid)); + if (length > 4) { + setServiceData(std::string(reinterpret_cast(u8p + 4), length - 4)); + } + } + + if (fields->svc_data_uuid128 != NULL) { + + u8p = fields->svc_data_uuid16; + length = fields->svc_data_uuid16_len; + + if (length < 16) { + NIMBLE_LOGE(LOG_TAG,"Length too small for ESP_BLE_AD_TYPE_128SERVICE_DATA"); + } + + setServiceDataUUID(NimBLEUUID(u8p, (size_t)16, false)); + if (length > 16) { + setServiceData(std::string(reinterpret_cast(u8p + 16), length - 16)); + } + } + + if (fields->appearance_is_present) { + NIMBLE_LOGD(LOG_TAG, " appearance=0x%04x", fields->appearance); + setAppearance(fields->appearance); + } + +/**** TODO: create storage and fucntions for these parameters + if (fields->public_tgt_addr != NULL) { + NIMBLE_LOGD(LOG_TAG, " public_tgt_addr="); + u8p = fields->public_tgt_addr; + for (i = 0; i < fields->num_public_tgt_addrs; i++) { + NIMBLE_LOGD(LOG_TAG, "public_tgt_addr=%s ", addr_str(u8p)); + u8p += BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN; + } + NIMBLE_LOGD(LOG_TAG, "\n"); + } + + if (fields->slave_itvl_range != NULL) { + NIMBLE_LOGD(LOG_TAG, " slave_itvl_range="); + print_bytes(fields->slave_itvl_range, BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN); + NIMBLE_LOGD(LOG_TAG, "\n"); + } + + if (fields->adv_itvl_is_present) { + NIMBLE_LOGD(LOG_TAG, " adv_itvl=0x%04x\n", fields->adv_itvl); + } + + if (fields->uri != NULL) { + NIMBLE_LOGD(LOG_TAG, " uri="); + print_bytes(fields->uri, fields->uri_len); + NIMBLE_LOGD(LOG_TAG, "\n"); + } +*/ + if (fields->mfg_data != NULL) { + setManufacturerData(std::string(reinterpret_cast(fields->mfg_data), fields->mfg_data_len)); + } + } //parseAdvertisement + + +/** + * @brief Set the address of the advertised device. + * @param [in] address The address of the advertised device. + */ +void NimBLEAdvertisedDevice::setAddress(NimBLEAddress address) { + m_address = address; +} // setAddress + + +/** + * @brief Set the adFlag for this device. + * @param [in] The discovered adFlag. + */ +void NimBLEAdvertisedDevice::setAdvType(uint8_t advType) { + m_advType = advType; +} // setAdvType + + +/** + * @brief Set the appearance for this device. + * @param [in] The discovered appearance. + */ +void NimBLEAdvertisedDevice::setAppearance(uint16_t appearance) { + m_appearance = appearance; + m_haveAppearance = true; + NIMBLE_LOGD(LOG_TAG,"- appearance: %d", m_appearance); +} // setAppearance + + +/** + * @brief Set the manufacturer data for this device. + * @param [in] The discovered manufacturer data. + */ +void NimBLEAdvertisedDevice::setManufacturerData(std::string manufacturerData) { + m_manufacturerData = manufacturerData; + m_haveManufacturerData = true; + + char* pHex = NimBLEUtils::buildHexData(nullptr, (uint8_t*) m_manufacturerData.data(), (uint8_t) m_manufacturerData.length()); + NIMBLE_LOGD(LOG_TAG,"- manufacturer data: %s", pHex); + free(pHex); +} // setManufacturerData + + +/** + * @brief Set the name for this device. + * @param [in] name The discovered name. + */ +void NimBLEAdvertisedDevice::setName(std::string name) { + m_name = name; + m_haveName = true; + NIMBLE_LOGD(LOG_TAG,"- setName(): name: %s", m_name.c_str()); +} // setName + + +/** + * @brief Set the RSSI for this device. + * @param [in] rssi The discovered RSSI. + */ +void NimBLEAdvertisedDevice::setRSSI(int rssi) { + m_rssi = rssi; + m_haveRSSI = true; + NIMBLE_LOGD(LOG_TAG,"- setRSSI(): rssi: %d", m_rssi); +} // setRSSI + + +/** + * @brief Set the Scan that created this advertised device. + * @param pScan The Scan that created this advertised device. + */ +void NimBLEAdvertisedDevice::setScan(NimBLEScan* pScan) { + m_pScan = pScan; +} // setScan + + +/** + * @brief Set the Service UUID for this device. + * @param [in] serviceUUID The discovered serviceUUID + */ + +void NimBLEAdvertisedDevice::setServiceUUID(const char* serviceUUID) { + return setServiceUUID(NimBLEUUID(serviceUUID)); +} // setServiceUUID + + +/** + * @brief Set the Service UUID for this device. + * @param [in] serviceUUID The discovered serviceUUID + */ +void NimBLEAdvertisedDevice::setServiceUUID(NimBLEUUID serviceUUID) { + // Don't add duplicates + for (int i = 0; i < m_serviceUUIDs.size(); i++) { + if (m_serviceUUIDs[i].equals(serviceUUID)) { + return; + } + } + m_serviceUUIDs.push_back(serviceUUID); + m_haveServiceUUID = true; + NIMBLE_LOGD(LOG_TAG,"- addServiceUUID(): serviceUUID: %s", serviceUUID.toString().c_str()); +} // setServiceUUID + + +/** + * @brief Set the ServiceData value. + * @param [in] data ServiceData value. + */ +void NimBLEAdvertisedDevice::setServiceData(std::string serviceData) { + m_haveServiceData = true; // Set the flag that indicates we have service data. + m_serviceData = serviceData; // Save the service data that we received. +} //setServiceData + + +/** + * @brief Set the ServiceDataUUID value. + * @param [in] data ServiceDataUUID value. + */ +void NimBLEAdvertisedDevice::setServiceDataUUID(NimBLEUUID uuid) { + m_haveServiceData = true; // Set the flag that indicates we have service data. + m_serviceDataUUID = uuid; +} // setServiceDataUUID + + +/** + * @brief Set the power level for this device. + * @param [in] txPower The discovered power level. + */ +void NimBLEAdvertisedDevice::setTXPower(int8_t txPower) { + m_txPower = txPower; + m_haveTXPower = true; + NIMBLE_LOGD(LOG_TAG,"- txPower: %d", m_txPower); +} // setTXPower + + +/** + * @brief Create a string representation of this device. + * @return A string representation of this device. + */ +std::string NimBLEAdvertisedDevice::toString() { + std::string res = "Name: " + getName() + ", Address: " + getAddress().toString(); + + if (haveAppearance()) { + char val[6]; + snprintf(val, sizeof(val), "%d", getAppearance()); + res += ", appearance: "; + res += val; + } + + if (haveManufacturerData()) { + char *pHex = NimBLEUtils::buildHexData(nullptr, (uint8_t*)getManufacturerData().data(), getManufacturerData().length()); + res += ", manufacturer data: "; + res += pHex; + free(pHex); + } + + if (haveServiceUUID()) { + res += ", serviceUUID: " + getServiceUUID().toString(); + } + + if (haveTXPower()) { + char val[5]; + snprintf(val, sizeof(val), "%d", getTXPower()); + res += ", txPower: "; + res += val; + } + + res += ", advType: " + std::string(NimBLEUtils::advTypeToString(m_advType)); + + return res; + +} // toString + + +uint8_t* NimBLEAdvertisedDevice::getPayload() { + return m_payload; +} + + +uint8_t NimBLEAdvertisedDevice::getAddressType() { + return m_addressType; +} + + +time_t NimBLEAdvertisedDevice::getTimestamp() { + return m_timestamp; +} + + +void NimBLEAdvertisedDevice::setAddressType(uint8_t type) { + m_addressType = type; +} + + +size_t NimBLEAdvertisedDevice::getPayloadLength() { + return m_payloadLength; +} + + +void NimBLEAdvertisedDevice::setAdvertisementResult(uint8_t* payload, uint8_t length){ + m_payload = payload; + m_payloadLength = length; +} + +#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) +#endif /* CONFIG_BT_ENABLED */ + diff --git a/libesp32/NimBLE-Arduino/src/NimBLEAdvertisedDevice.h b/libesp32/NimBLE-Arduino/src/NimBLEAdvertisedDevice.h new file mode 100644 index 000000000..c38d7001d --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLEAdvertisedDevice.h @@ -0,0 +1,159 @@ +/* + * NimBLEAdvertisedDevice.h + * + * Created: on Jan 24 2020 + * Author H2zero + * + * Originally: + * + * BLEAdvertisedDevice.h + * + * Created on: Jul 3, 2017 + * Author: kolban + */ + +#ifndef COMPONENTS_NIMBLEADVERTISEDDEVICE_H_ +#define COMPONENTS_NIMBLEADVERTISEDDEVICE_H_ +#include "sdkconfig.h" +#if defined(CONFIG_BT_ENABLED) + +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) + +#include "NimBLEAddress.h" +#include "NimBLEScan.h" +#include "NimBLEUUID.h" + +#include "host/ble_hs_adv.h" + +#include +#include + + +class NimBLEScan; +/** + * @brief A representation of a %BLE advertised device found by a scan. + * + * When we perform a %BLE scan, the result will be a set of devices that are advertising. This + * class provides a model of a detected device. + */ +class NimBLEAdvertisedDevice { +public: + NimBLEAdvertisedDevice(); + + NimBLEAddress getAddress(); + uint8_t getAdvType(); + uint16_t getAppearance(); + std::string getManufacturerData(); + + template + T getManufacturerData(bool skipSizeCheck = false) { + std::string data = getManufacturerData(); + if(!skipSizeCheck && data.size() < sizeof(T)) return T(); + const char *pData = data.data(); + return *((T *)pData); + } + + std::string getName(); + int getRSSI(); + NimBLEScan* getScan(); + std::string getServiceData(); + + template + T getServiceData(bool skipSizeCheck = false) { + std::string data = getServiceData(); + if(!skipSizeCheck && data.size() < sizeof(T)) return T(); + const char *pData = data.data(); + return *((T *)pData); + } + + NimBLEUUID getServiceDataUUID(); + NimBLEUUID getServiceUUID(); + int8_t getTXPower(); + uint8_t* getPayload(); + size_t getPayloadLength(); + uint8_t getAddressType(); + time_t getTimestamp(); + void setAddressType(uint8_t type); + + + bool isAdvertisingService(const NimBLEUUID &uuid); + bool haveAppearance(); + bool haveManufacturerData(); + bool haveName(); + bool haveRSSI(); + bool haveServiceData(); + bool haveServiceUUID(); + bool haveTXPower(); + + std::string toString(); + +private: + friend class NimBLEScan; + + void parseAdvertisement(ble_hs_adv_fields *fields); + void setAddress(NimBLEAddress address); + void setAdvType(uint8_t advType); + void setAdvertisementResult(uint8_t* payload, uint8_t length); + void setAppearance(uint16_t appearance); + void setManufacturerData(std::string manufacturerData); + void setName(std::string name); + void setRSSI(int rssi); + void setScan(NimBLEScan* pScan); + void setServiceData(std::string data); + void setServiceDataUUID(NimBLEUUID uuid); + void setServiceUUID(const char* serviceUUID); + void setServiceUUID(NimBLEUUID serviceUUID); + void setTXPower(int8_t txPower); + + bool m_haveAppearance; + bool m_haveManufacturerData; + bool m_haveName; + bool m_haveRSSI; + bool m_haveServiceData; + bool m_haveServiceUUID; + bool m_haveTXPower; + + + NimBLEAddress m_address = NimBLEAddress(""); + uint8_t m_advType; + uint16_t m_appearance; + int m_deviceType; + std::string m_manufacturerData; + std::string m_name; + NimBLEScan* m_pScan; + int m_rssi; + std::vector m_serviceUUIDs; + int8_t m_txPower; + std::string m_serviceData; + NimBLEUUID m_serviceDataUUID; + uint8_t* m_payload; + size_t m_payloadLength; + uint8_t m_addressType; + time_t m_timestamp; + bool m_callbackSent; +}; + +/** + * @brief A callback handler for callbacks associated device scanning. + * + * When we are performing a scan as a %BLE client, we may wish to know when a new device that is advertising + * has been found. This class can be sub-classed and registered such that when a scan is performed and + * a new advertised device has been found, we will be called back to be notified. + */ +class NimBLEAdvertisedDeviceCallbacks { +public: + virtual ~NimBLEAdvertisedDeviceCallbacks() {} + /** + * @brief Called when a new scan result is detected. + * + * As we are scanning, we will find new devices. When found, this call back is invoked with a reference to the + * device that was found. During any individual scan, a device will only be detected one time. + */ + //virtual void onResult(NimBLEAdvertisedDevice advertisedDevice) = 0; + virtual void onResult(NimBLEAdvertisedDevice* advertisedDevice) = 0; +}; + +#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) +#endif /* CONFIG_BT_ENABLED */ +#endif /* COMPONENTS_NIMBLEADVERTISEDDEVICE_H_ */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLEAdvertising.cpp b/libesp32/NimBLE-Arduino/src/NimBLEAdvertising.cpp new file mode 100644 index 000000000..7e1e07ae3 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLEAdvertising.cpp @@ -0,0 +1,617 @@ +/* + * NimBLEAdvertising.cpp + * + * Created: on March 3, 2020 + * Author H2zero + * + * Originally: + * + * BLEAdvertising.cpp + * + * This class encapsulates advertising a BLE Server. + * Created on: Jun 21, 2017 + * Author: kolban + * + */ +#include "sdkconfig.h" +#if defined(CONFIG_BT_ENABLED) + +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) + +#include "services/gap/ble_svc_gap.h" +#include "NimBLEAdvertising.h" +#include "NimBLEDevice.h" +#include "NimBLEServer.h" +#include "NimBLEUtils.h" +#include "NimBLELog.h" + +static const char* LOG_TAG = "NimBLEAdvertising"; + + +/** + * @brief Construct a default advertising object. + * + */ +NimBLEAdvertising::NimBLEAdvertising() { + memset(&m_advData, 0, sizeof m_advData); + memset(&m_scanData, 0, sizeof m_scanData); + memset(&m_advParams, 0, sizeof m_advParams); + const char *name = ble_svc_gap_device_name(); + + m_advData.name = (uint8_t *)name; + m_advData.name_len = strlen(name); + m_advData.name_is_complete = 1; + m_scanData.tx_pwr_lvl_is_present = 1; + m_scanData.tx_pwr_lvl = NimBLEDevice::getPower(); + m_advData.flags = (BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP); + m_advData.appearance = 0; + m_advData.appearance_is_present = 0; + m_advData.mfg_data_len = 0; + m_advData.mfg_data = nullptr; + + m_advParams.conn_mode = BLE_GAP_CONN_MODE_UND; + m_advParams.disc_mode = BLE_GAP_DISC_MODE_GEN; + m_advParams.itvl_min = 0; + m_advParams.itvl_max = 0; + +} // NimBLEAdvertising + + +/** + * @brief Add a service uuid to exposed list of services. + * @param [in] serviceUUID The UUID of the service to expose. + */ +void NimBLEAdvertising::addServiceUUID(const NimBLEUUID &serviceUUID) { + m_serviceUUIDs.push_back(serviceUUID); +} // addServiceUUID + + +/** + * @brief Add a service uuid to exposed list of services. + * @param [in] serviceUUID The string representation of the service to expose. + */ +void NimBLEAdvertising::addServiceUUID(const char* serviceUUID) { + addServiceUUID(NimBLEUUID(serviceUUID)); +} // addServiceUUID + + +/** + * @brief Set the device appearance in the advertising data. + * The appearance attribute is of type 0x19. The codes for distinct appearances can be found here: + * https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.gap.appearance.xml. + * @param [in] appearance The appearance of the device in the advertising data. + * @return N/A. + */ +void NimBLEAdvertising::setAppearance(uint16_t appearance) { + m_advData.appearance = appearance; + m_advData.appearance_is_present = 1; +} // setAppearance + +void NimBLEAdvertising::setAdvertisementType(uint8_t adv_type){ + m_advParams.conn_mode = adv_type; +} // setAdvertisementType + +void NimBLEAdvertising::setMinInterval(uint16_t mininterval) { + m_advParams.itvl_min = mininterval; +} // setMinInterval + +void NimBLEAdvertising::setMaxInterval(uint16_t maxinterval) { + m_advParams.itvl_max = maxinterval; +} // setMaxInterval + + +/* These are dummy functions for now for compatibility */ +void NimBLEAdvertising::setMinPreferred(uint16_t mininterval) { + //m_advData.min_interval = mininterval; +} // + +void NimBLEAdvertising::setMaxPreferred(uint16_t maxinterval) { + //m_advData.max_interval = maxinterval; +} // +/*******************************************************/ + + +void NimBLEAdvertising::setScanResponse(bool set) { + m_scanResp = set; +} + +/** + * @brief Set the filtering for the scan filter. + * @param [in] scanRequestWhitelistOnly If true, only allow scan requests from those on the white list. + * @param [in] connectWhitelistOnly If true, only allow connections from those on the white list. + */ +void NimBLEAdvertising::setScanFilter(bool scanRequestWhitelistOnly, bool connectWhitelistOnly) { + NIMBLE_LOGD(LOG_TAG, ">> setScanFilter: scanRequestWhitelistOnly: %d, connectWhitelistOnly: %d", scanRequestWhitelistOnly, connectWhitelistOnly); + if (!scanRequestWhitelistOnly && !connectWhitelistOnly) { + m_advParams.filter_policy = BLE_HCI_ADV_FILT_NONE; + NIMBLE_LOGD(LOG_TAG, "<< setScanFilter"); + return; + } + if (scanRequestWhitelistOnly && !connectWhitelistOnly) { + m_advParams.filter_policy = BLE_HCI_ADV_FILT_SCAN; + NIMBLE_LOGD(LOG_TAG, "<< setScanFilter"); + return; + } + if (!scanRequestWhitelistOnly && connectWhitelistOnly) { + m_advParams.filter_policy = BLE_HCI_ADV_FILT_CONN; + NIMBLE_LOGD(LOG_TAG, "<< setScanFilter"); + return; + } + if (scanRequestWhitelistOnly && connectWhitelistOnly) { + m_advParams.filter_policy = BLE_HCI_ADV_FILT_BOTH; + NIMBLE_LOGD(LOG_TAG, "<< setScanFilter"); + return; + } +} // setScanFilter + +/** + * @brief Set the advertisement data that is to be published in a regular advertisement. + * @param [in] advertisementData The data to be advertised. + */ + +void NimBLEAdvertising::setAdvertisementData(NimBLEAdvertisementData& advertisementData) { + NIMBLE_LOGD(LOG_TAG, ">> setAdvertisementData"); + int rc = ble_gap_adv_set_data( + (uint8_t*)advertisementData.getPayload().data(), + advertisementData.getPayload().length()); + if (rc != 0) { + NIMBLE_LOGE(LOG_TAG, "ble_gap_adv_set_data: %d %s", rc, NimBLEUtils::returnCodeToString(rc)); + } + m_customAdvData = true; // Set the flag that indicates we are using custom advertising data. + NIMBLE_LOGD(LOG_TAG, "<< setAdvertisementData"); +} // setAdvertisementData + + +/** + * @brief Set the advertisement data that is to be published in a scan response. + * @param [in] advertisementData The data to be advertised. + */ +void NimBLEAdvertising::setScanResponseData(NimBLEAdvertisementData& advertisementData) { + NIMBLE_LOGD(LOG_TAG, ">> setScanResponseData"); + int rc = ble_gap_adv_rsp_set_data( + (uint8_t*)advertisementData.getPayload().data(), + advertisementData.getPayload().length()); + if (rc != 0) { + NIMBLE_LOGE(LOG_TAG, "ble_gap_adv_rsp_set_data: %d %s", rc, NimBLEUtils::returnCodeToString(rc)); + } + m_customScanResponseData = true; // Set the flag that indicates we are using custom scan response data. + NIMBLE_LOGD(LOG_TAG, "<< setScanResponseData"); +} // setScanResponseData + + +/** + * @brief Start advertising. + * Start advertising. + * @return N/A. + */ +void NimBLEAdvertising::start() { + NIMBLE_LOGD(LOG_TAG, ">> Advertising start: customAdvData: %d, customScanResponseData: %d", m_customAdvData, m_customScanResponseData); + + // If Host is not synced we cannot start advertising. + if(!NimBLEDevice::m_synced) { + NIMBLE_LOGE(LOG_TAG, "Host reset, wait for sync."); + return; + } + +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + NimBLEServer* pServer = NimBLEDevice::getServer(); + if(pServer != nullptr) { + if(!pServer->m_gattsStarted){ + pServer->start(); + } else if(pServer->getConnectedCount() >= NIMBLE_MAX_CONNECTIONS) { + NIMBLE_LOGW(LOG_TAG, "Max connections reached - not advertising"); + return; + } + } +#endif + + // If already advertising just return + if(ble_gap_adv_active()) { + return; + } + + int rc = 0; + + if (!m_customAdvData && !m_advDataSet) { + //start with 3 bytes for the flags data + uint8_t payloadLen = 3; + + for(auto &it : m_serviceUUIDs) { + if(it.getNative()->u.type == BLE_UUID_TYPE_16) { + int add = (m_advData.num_uuids16 > 0) ? 2 : 4; + if((payloadLen + add) > 31){ + m_advData.uuids16_is_complete = 0; + continue; + } + payloadLen += add; + + if(nullptr == (m_advData.uuids16 = (ble_uuid16_t*)realloc(m_advData.uuids16, + (m_advData.num_uuids16 + 1) * sizeof(ble_uuid16_t)))) + { + NIMBLE_LOGE(LOG_TAG, "Error, no mem"); + abort(); + } + memcpy(&m_advData.uuids16[m_advData.num_uuids16].value, + &it.getNative()->u16.value, 2); + + m_advData.uuids16[m_advData.num_uuids16].u.type = BLE_UUID_TYPE_16; + m_advData.uuids16_is_complete = 1; + m_advData.num_uuids16++; + } + if(it.getNative()->u.type == BLE_UUID_TYPE_32) { + int add = (m_advData.num_uuids32 > 0) ? 4 : 6; + if((payloadLen + add) > 31){ + m_advData.uuids32_is_complete = 0; + continue; + } + payloadLen += add; + + if(nullptr == (m_advData.uuids32 = (ble_uuid32_t*)realloc(m_advData.uuids32, + (m_advData.num_uuids32 + 1) * sizeof(ble_uuid32_t)))) + { + NIMBLE_LOGE(LOG_TAG, "Error, no mem"); + abort(); + } + memcpy(&m_advData.uuids32[m_advData.num_uuids32].value, + &it.getNative()->u32.value, 4); + + m_advData.uuids32[m_advData.num_uuids32].u.type = BLE_UUID_TYPE_32; + m_advData.uuids32_is_complete = 1; + m_advData.num_uuids32++; + } + if(it.getNative()->u.type == BLE_UUID_TYPE_128){ + int add = (m_advData.num_uuids128 > 0) ? 16 : 18; + if((payloadLen + add) > 31){ + m_advData.uuids128_is_complete = 0; + continue; + } + payloadLen += add; + + if(nullptr == (m_advData.uuids128 = (ble_uuid128_t*)realloc(m_advData.uuids128, + (m_advData.num_uuids128 + 1) * sizeof(ble_uuid128_t)))) + { + NIMBLE_LOGE(LOG_TAG, "Error, no mem"); + abort(); + } + memcpy(&m_advData.uuids128[m_advData.num_uuids128].value, + &it.getNative()->u128.value, 16); + + m_advData.uuids128[m_advData.num_uuids128].u.type = BLE_UUID_TYPE_128; + m_advData.uuids128_is_complete = 1; + m_advData.num_uuids128++; + } + } + + // check if there is room for the name, if not put it in scan data + if((payloadLen + m_advData.name_len) > 29) { + if(m_scanResp){ + m_scanData.name = m_advData.name; + m_scanData.name_len = m_advData.name_len; + m_scanData.name_is_complete = m_advData.name_is_complete; + m_advData.name = nullptr; + m_advData.name_len = 0; + } else { + // if not using scan response just cut the name down + // leaving 2 bytes for the data specifier. + m_advData.name_len = (29 - payloadLen); + } + m_advData.name_is_complete = 0; + } + + if(m_advData.name_len > 0) { + payloadLen += (m_advData.name_len + 2); + } + + if(m_scanResp) { + // name length + type byte + length byte + tx power type + length + data + if((m_scanData.name_len + 5) > 31) { + // prioritize name data over tx power + m_scanData.tx_pwr_lvl_is_present = 0; + m_scanData.tx_pwr_lvl = 0; + // limit name to 29 to leave room for the data specifiers + if(m_scanData.name_len > 29) { + m_scanData.name_len = 29; + m_scanData.name_is_complete = false; + } + } + + rc = ble_gap_adv_rsp_set_fields(&m_scanData); + if (rc != 0) { + NIMBLE_LOGC(LOG_TAG, "error setting scan response data; rc=%d, %s", rc, NimBLEUtils::returnCodeToString(rc)); + abort(); + } + // if not using scan response and there is room, + // put the tx power data into the advertisment + } else if (payloadLen < 29) { + m_advData.tx_pwr_lvl_is_present = 1; + m_advData.tx_pwr_lvl = NimBLEDevice::getPower(); + } + + rc = ble_gap_adv_set_fields(&m_advData); + if (rc != 0) { + NIMBLE_LOGC(LOG_TAG, "error setting advertisement data; rc=%d, %s", rc, NimBLEUtils::returnCodeToString(rc)); + abort(); + } + + if(m_advData.num_uuids128 > 0) { + free(m_advData.uuids128); + m_advData.uuids128 = nullptr; + m_advData.num_uuids128 = 0; + } + + if(m_advData.num_uuids32 > 0) { + free(m_advData.uuids32); + m_advData.uuids32 = nullptr; + m_advData.num_uuids32 = 0; + } + + if(m_advData.num_uuids16 > 0) { + free(m_advData.uuids16); + m_advData.uuids16 = nullptr; + m_advData.num_uuids16 = 0; + } + + m_advDataSet = true; + } + +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + rc = ble_gap_adv_start(0, NULL, BLE_HS_FOREVER, + &m_advParams, + (pServer != nullptr) ? NimBLEServer::handleGapEvent : NULL, + pServer); +#else + rc = ble_gap_adv_start(0, NULL, BLE_HS_FOREVER, + &m_advParams, NULL,NULL); +#endif + if (rc != 0) { + NIMBLE_LOGC(LOG_TAG, "Error enabling advertising; rc=%d, %s", rc, NimBLEUtils::returnCodeToString(rc)); + abort(); + } + + NIMBLE_LOGD(LOG_TAG, "<< Advertising start"); +} // start + + +/** + * @brief Stop advertising. + * Stop advertising. + * @return N/A. + */ +void NimBLEAdvertising::stop() { + NIMBLE_LOGD(LOG_TAG, ">> stop"); + int rc = ble_gap_adv_stop(); + if (rc != 0 && rc != BLE_HS_EALREADY) { + NIMBLE_LOGE(LOG_TAG, "ble_gap_adv_stop rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc)); + return; + } + + NIMBLE_LOGD(LOG_TAG, "<< stop"); +} // stop + + +/** + * Host reset seems to clear advertising data, + * we need clear the flag so it reloads it. + */ +void NimBLEAdvertising::onHostReset() { + m_advDataSet = false; +} + + +/** + * @brief Add data to the payload to be advertised. + * @param [in] data The data to be added to the payload. + */ +void NimBLEAdvertisementData::addData(const std::string &data) { + if ((m_payload.length() + data.length()) > BLE_HS_ADV_MAX_SZ) { + return; + } + m_payload.append(data); +} // addData + + +/** + * @brief Set the appearance. + * @param [in] appearance The appearance code value. + * + * See also: + * https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.gap.appearance.xml + */ +void NimBLEAdvertisementData::setAppearance(uint16_t appearance) { + char cdata[2]; + cdata[0] = 3; + cdata[1] = BLE_HS_ADV_TYPE_APPEARANCE; // 0x19 + addData(std::string(cdata, 2) + std::string((char*) &appearance, 2)); +} // setAppearance + + +/** + * @brief Set the complete services. + * @param [in] uuid The single service to advertise. + */ +void NimBLEAdvertisementData::setCompleteServices(const NimBLEUUID &uuid) { + char cdata[2]; + switch (uuid.bitSize()) { + case 16: { + // [Len] [0x02] [LL] [HH] + cdata[0] = 3; + cdata[1] = BLE_HS_ADV_TYPE_COMP_UUIDS16; // 0x03 + addData(std::string(cdata, 2) + std::string((char*) &uuid.getNative()->u16.value, 2)); + break; + } + + case 32: { + // [Len] [0x04] [LL] [LL] [HH] [HH] + cdata[0] = 5; + cdata[1] = BLE_HS_ADV_TYPE_COMP_UUIDS32; // 0x05 + addData(std::string(cdata, 2) + std::string((char*) &uuid.getNative()->u32.value, 4)); + break; + } + + case 128: { + // [Len] [0x04] [0] [1] ... [15] + cdata[0] = 17; + cdata[1] = BLE_HS_ADV_TYPE_COMP_UUIDS128; // 0x07 + addData(std::string(cdata, 2) + std::string((char*) uuid.getNative()->u128.value, 16)); + break; + } + + default: + return; + } +} // setCompleteServices + + +/** + * @brief Set the advertisement flags. + * @param [in] The flags to be set in the advertisement. + * * ****DO NOT USE THESE**** + * * ESP_BLE_ADV_FLAG_LIMIT_DISC + * * ESP_BLE_ADV_FLAG_GEN_DISC + * * ESP_BLE_ADV_FLAG_BREDR_NOT_SPT + * * ESP_BLE_ADV_FLAG_DMT_CONTROLLER_SPT + * * ESP_BLE_ADV_FLAG_DMT_HOST_SPT + * * ESP_BLE_ADV_FLAG_NON_LIMIT_DISC + * * + * * ****THESE ARE SUPPORTED**** + * * BLE_HS_ADV_F_DISC_LTD + * * BLE_HS_ADV_F_DISC_GEN + * * BLE_HS_ADV_F_BREDR_UNSUP - must always use with NimBLE + */ +void NimBLEAdvertisementData::setFlags(uint8_t flag) { + char cdata[3]; + cdata[0] = 2; + cdata[1] = BLE_HS_ADV_TYPE_FLAGS; // 0x01 + cdata[2] = flag | BLE_HS_ADV_F_BREDR_UNSUP; + addData(std::string(cdata, 3)); +} // setFlag + + +/** + * @brief Set manufacturer specific data. + * @param [in] data Manufacturer data. + */ +void NimBLEAdvertisementData::setManufacturerData(const std::string &data) { + NIMBLE_LOGD("NimBLEAdvertisementData", ">> setManufacturerData"); + char cdata[2]; + cdata[0] = data.length() + 1; + cdata[1] = BLE_HS_ADV_TYPE_MFG_DATA ; // 0xff + addData(std::string(cdata, 2) + data); + NIMBLE_LOGD("NimBLEAdvertisementData", "<< setManufacturerData"); +} // setManufacturerData + + +/** + * @brief Set the name. + * @param [in] The complete name of the device. + */ +void NimBLEAdvertisementData::setName(const std::string &name) { + NIMBLE_LOGD("NimBLEAdvertisementData", ">> setName: %s", name.c_str()); + char cdata[2]; + cdata[0] = name.length() + 1; + cdata[1] = BLE_HS_ADV_TYPE_COMP_NAME; // 0x09 + addData(std::string(cdata, 2) + name); + NIMBLE_LOGD("NimBLEAdvertisementData", "<< setName"); +} // setName + + +/** + * @brief Set the partial services. + * @param [in] uuid The single service to advertise. + */ +void NimBLEAdvertisementData::setPartialServices(const NimBLEUUID &uuid) { + char cdata[2]; + switch (uuid.bitSize()) { + case 16: { + // [Len] [0x02] [LL] [HH] + cdata[0] = 3; + cdata[1] = BLE_HS_ADV_TYPE_INCOMP_UUIDS16; // 0x02 + addData(std::string(cdata, 2) + std::string((char *) &uuid.getNative()->u16.value, 2)); + break; + } + + case 32: { + // [Len] [0x04] [LL] [LL] [HH] [HH] + cdata[0] = 5; + cdata[1] = BLE_HS_ADV_TYPE_INCOMP_UUIDS32; // 0x04 + addData(std::string(cdata, 2) + std::string((char *) &uuid.getNative()->u32.value, 4)); + break; + } + + case 128: { + // [Len] [0x04] [0] [1] ... [15] + cdata[0] = 17; + cdata[1] = BLE_HS_ADV_TYPE_INCOMP_UUIDS128; // 0x06 + addData(std::string(cdata, 2) + std::string((char *) &uuid.getNative()->u128.value, 16)); + break; + } + + default: + return; + } +} // setPartialServices + + +/** + * @brief Set the service data (UUID + data) + * @param [in] uuid The UUID to set with the service data. Size of UUID will be used. + * @param [in] data The data to be associated with the service data advert. + */ +void NimBLEAdvertisementData::setServiceData(const NimBLEUUID &uuid, const std::string &data) { + char cdata[2]; + switch (uuid.bitSize()) { + case 16: { + // [Len] [0x16] [UUID16] data + cdata[0] = data.length() + 3; + cdata[1] = BLE_HS_ADV_TYPE_SVC_DATA_UUID16; // 0x16 + addData(std::string(cdata, 2) + std::string((char*) &uuid.getNative()->u16.value, 2) + data); + break; + } + + case 32: { + // [Len] [0x20] [UUID32] data + cdata[0] = data.length() + 5; + cdata[1] = BLE_HS_ADV_TYPE_SVC_DATA_UUID32; // 0x20 + addData(std::string(cdata, 2) + std::string((char*) &uuid.getNative()->u32.value, 4) + data); + break; + } + + case 128: { + // [Len] [0x21] [UUID128] data + cdata[0] = data.length() + 17; + cdata[1] = BLE_HS_ADV_TYPE_SVC_DATA_UUID128; // 0x21 + addData(std::string(cdata, 2) + std::string((char*) &uuid.getNative()->u128.value, 16) + data); + break; + } + + default: + return; + } +} // setServiceData + + +/** + * @brief Set the short name. + * @param [in] The short name of the device. + */ +void NimBLEAdvertisementData::setShortName(const std::string &name) { + NIMBLE_LOGD("NimBLEAdvertisementData", ">> setShortName: %s", name.c_str()); + char cdata[2]; + cdata[0] = name.length() + 1; + cdata[1] = BLE_HS_ADV_TYPE_INCOMP_NAME; // 0x08 + addData(std::string(cdata, 2) + name); + NIMBLE_LOGD("NimBLEAdvertisementData", "<< setShortName"); +} // setShortName + + +/** + * @brief Retrieve the payload that is to be advertised. + * @return The payload that is to be advertised. + */ +std::string NimBLEAdvertisementData::getPayload() { + return m_payload; +} // getPayload + +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) +#endif /* CONFIG_BT_ENABLED */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLEAdvertising.h b/libesp32/NimBLE-Arduino/src/NimBLEAdvertising.h new file mode 100644 index 000000000..ad76d7eec --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLEAdvertising.h @@ -0,0 +1,111 @@ +/* + * NimBLEAdvertising.h + * + * Created: on March 3, 2020 + * Author H2zero + * + * Originally: + * + * BLEAdvertising.h + * + * Created on: Jun 21, 2017 + * Author: kolban + */ + +#ifndef MAIN_BLEADVERTISING_H_ +#define MAIN_BLEADVERTISING_H_ +#include "sdkconfig.h" +#if defined(CONFIG_BT_ENABLED) + +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) + +#include "host/ble_gap.h" +/**** FIX COMPILATION ****/ +#undef min +#undef max +/**************************/ + +#include "NimBLEUUID.h" + +#include + +/* COMPATIBILITY - DO NOT USE */ +#define ESP_BLE_ADV_FLAG_LIMIT_DISC (0x01 << 0) +#define ESP_BLE_ADV_FLAG_GEN_DISC (0x01 << 1) +#define ESP_BLE_ADV_FLAG_BREDR_NOT_SPT (0x01 << 2) +#define ESP_BLE_ADV_FLAG_DMT_CONTROLLER_SPT (0x01 << 3) +#define ESP_BLE_ADV_FLAG_DMT_HOST_SPT (0x01 << 4) +#define ESP_BLE_ADV_FLAG_NON_LIMIT_DISC (0x00 ) + /* ************************* */ + + +/** + * @brief Advertisement data set by the programmer to be published by the %BLE server. + */ +class NimBLEAdvertisementData { + // Only a subset of the possible BLE architected advertisement fields are currently exposed. Others will + // be exposed on demand/request or as time permits. + // +public: + void setAppearance(uint16_t appearance); + void setCompleteServices(const NimBLEUUID &uuid); + void setFlags(uint8_t); + void setManufacturerData(const std::string &data); + void setName(const std::string &name); + void setPartialServices(const NimBLEUUID &uuid); + void setServiceData(const NimBLEUUID &uuid, const std::string &data); + void setShortName(const std::string &name); + void addData(const std::string &data); // Add data to the payload. + std::string getPayload(); // Retrieve the current advert payload. + +private: + friend class NimBLEAdvertising; + std::string m_payload; // The payload of the advertisement. +}; // NimBLEAdvertisementData + + +/** + * @brief Perform and manage %BLE advertising. + * + * A %BLE server will want to perform advertising in order to make itself known to %BLE clients. + */ +class NimBLEAdvertising { +public: + NimBLEAdvertising(); + void addServiceUUID(const NimBLEUUID &serviceUUID); + void addServiceUUID(const char* serviceUUID); + void start(); + void stop(); + void setAppearance(uint16_t appearance); + void setAdvertisementType(uint8_t adv_type); + void setMaxInterval(uint16_t maxinterval); + void setMinInterval(uint16_t mininterval); + void setAdvertisementData(NimBLEAdvertisementData& advertisementData); + void setScanFilter(bool scanRequertWhitelistOnly, bool connectWhitelistOnly); + void setScanResponseData(NimBLEAdvertisementData& advertisementData); + void setPrivateAddress(uint8_t type = BLE_ADDR_RANDOM); + + void setMinPreferred(uint16_t); + void setMaxPreferred(uint16_t); + void setScanResponse(bool); + +private: + friend class NimBLEDevice; + + void onHostReset(); + + ble_hs_adv_fields m_advData; + ble_hs_adv_fields m_scanData; + ble_gap_adv_params m_advParams; + std::vector m_serviceUUIDs; + bool m_customAdvData = false; // Are we using custom advertising data? + bool m_customScanResponseData = false; // Are we using custom scan response data? + bool m_scanResp = true; + bool m_advDataSet = false; + +}; + +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) +#endif /* CONFIG_BT_ENABLED */ +#endif /* MAIN_BLEADVERTISING_H_ */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLEBeacon.cpp b/libesp32/NimBLE-Arduino/src/NimBLEBeacon.cpp new file mode 100644 index 000000000..718a507f5 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLEBeacon.cpp @@ -0,0 +1,93 @@ +/* + * NimBLEBeacon2.cpp + * + * Created: on March 15 2020 + * Author H2zero + * + * Originally: + * + * BLEBeacon.cpp + * + * Created on: Jan 4, 2018 + * Author: kolban + */ +#include "sdkconfig.h" +#if defined(CONFIG_BT_ENABLED) + +#include +#include "NimBLEBeacon.h" +#include "NimBLELog.h" + +#define ENDIAN_CHANGE_U16(x) ((((x)&0xFF00)>>8) + (((x)&0xFF)<<8)) + +static const char* LOG_TAG = "NimBLEBeacon"; + +NimBLEBeacon::NimBLEBeacon() { + m_beaconData.manufacturerId = 0x4c00; + m_beaconData.subType = 0x02; + m_beaconData.subTypeLength = 0x15; + m_beaconData.major = 0; + m_beaconData.minor = 0; + m_beaconData.signalPower = 0; + memset(m_beaconData.proximityUUID, 0, sizeof(m_beaconData.proximityUUID)); +} // NimBLEBeacon + +std::string NimBLEBeacon::getData() { + return std::string((char*) &m_beaconData, sizeof(m_beaconData)); +} // getData + +uint16_t NimBLEBeacon::getMajor() { + return m_beaconData.major; +} + +uint16_t NimBLEBeacon::getManufacturerId() { + return m_beaconData.manufacturerId; +} + +uint16_t NimBLEBeacon::getMinor() { + return m_beaconData.minor; +} + +NimBLEUUID NimBLEBeacon::getProximityUUID() { + return NimBLEUUID(m_beaconData.proximityUUID, 16, false); +} + +int8_t NimBLEBeacon::getSignalPower() { + return m_beaconData.signalPower; +} + +/** + * Set the raw data for the beacon record. + */ +void NimBLEBeacon::setData(const std::string &data) { + if (data.length() != sizeof(m_beaconData)) { + NIMBLE_LOGE(LOG_TAG, "Unable to set the data ... length passed in was %d and expected %d", + data.length(), sizeof(m_beaconData)); + return; + } + memcpy(&m_beaconData, data.data(), sizeof(m_beaconData)); +} // setData + +void NimBLEBeacon::setMajor(uint16_t major) { + m_beaconData.major = ENDIAN_CHANGE_U16(major); +} // setMajor + +void NimBLEBeacon::setManufacturerId(uint16_t manufacturerId) { + m_beaconData.manufacturerId = ENDIAN_CHANGE_U16(manufacturerId); +} // setManufacturerId + +void NimBLEBeacon::setMinor(uint16_t minor) { + m_beaconData.minor = ENDIAN_CHANGE_U16(minor); +} // setMinior + +void NimBLEBeacon::setProximityUUID(const NimBLEUUID &uuid) { + NimBLEUUID temp_uuid = uuid; + temp_uuid.to128(); + memcpy(m_beaconData.proximityUUID, temp_uuid.getNative()->u128.value, 16); +} // setProximityUUID + +void NimBLEBeacon::setSignalPower(int8_t signalPower) { + m_beaconData.signalPower = signalPower; +} // setSignalPower + +#endif diff --git a/libesp32/NimBLE-Arduino/src/NimBLEBeacon.h b/libesp32/NimBLE-Arduino/src/NimBLEBeacon.h new file mode 100644 index 000000000..82ee61c53 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLEBeacon.h @@ -0,0 +1,51 @@ +/* + * NimBLEBeacon2.h + * + * Created: on March 15 2020 + * Author H2zero + * + * Originally: + * + * BLEBeacon2.h + * + * Created on: Jan 4, 2018 + * Author: kolban + */ + +#ifndef MAIN_NIMBLEBEACON_H_ +#define MAIN_NIMBLEBEACON_H_ + +#include "NimBLEUUID.h" +/** + * @brief Representation of a beacon. + * See: + * * https://en.wikipedia.org/wiki/IBeacon + */ +class NimBLEBeacon { +private: + struct { + uint16_t manufacturerId; + uint8_t subType; + uint8_t subTypeLength; + uint8_t proximityUUID[16]; + uint16_t major; + uint16_t minor; + int8_t signalPower; + } __attribute__((packed)) m_beaconData; +public: + NimBLEBeacon(); + std::string getData(); + uint16_t getMajor(); + uint16_t getMinor(); + uint16_t getManufacturerId(); + NimBLEUUID getProximityUUID(); + int8_t getSignalPower(); + void setData(const std::string &data); + void setMajor(uint16_t major); + void setMinor(uint16_t minor); + void setManufacturerId(uint16_t manufacturerId); + void setProximityUUID(const NimBLEUUID &uuid); + void setSignalPower(int8_t signalPower); +}; // NimBLEBeacon + +#endif /* MAIN_NIMBLEBEACON_H_ */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLECharacteristic.cpp b/libesp32/NimBLE-Arduino/src/NimBLECharacteristic.cpp new file mode 100644 index 000000000..0bd11f6ba --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLECharacteristic.cpp @@ -0,0 +1,548 @@ +/* + * NimBLECharacteristic.cpp + * + * Created: on March 3, 2020 + * Author H2zero + * + * BLECharacteristic.cpp + * + * Created on: Jun 22, 2017 + * Author: kolban + */ +#include "sdkconfig.h" +#if defined(CONFIG_BT_ENABLED) + +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + +#include "NimBLECharacteristic.h" +#include "NimBLE2902.h" +#include "NimBLE2904.h" +#include "NimBLEDevice.h" +#include "NimBLELog.h" + +#define NULL_HANDLE (0xffff) + +static NimBLECharacteristicCallbacks defaultCallback; +static const char* LOG_TAG = "NimBLECharacteristic"; + +/** + * @brief Construct a characteristic + * @param [in] uuid - UUID (const char*) for the characteristic. + * @param [in] properties - Properties for the characteristic. + * @param [in] pService - pointer to the service instance this characteristic belongs to. + */ +NimBLECharacteristic::NimBLECharacteristic(const char* uuid, uint16_t properties, NimBLEService* pService) +: NimBLECharacteristic(NimBLEUUID(uuid), properties, pService) { +} + +/** + * @brief Construct a characteristic + * @param [in] uuid - UUID for the characteristic. + * @param [in] properties - Properties for the characteristic. + * @param [in] pService - pointer to the service instance this characteristic belongs to. + */ +NimBLECharacteristic::NimBLECharacteristic(const NimBLEUUID &uuid, uint16_t properties, NimBLEService* pService) { + m_uuid = uuid; + m_handle = NULL_HANDLE; + m_properties = properties; + m_pCallbacks = &defaultCallback; + m_pService = pService; + m_value = ""; + m_valMux = portMUX_INITIALIZER_UNLOCKED; + m_pTaskData = nullptr; + m_timestamp = 0; +} // NimBLECharacteristic + +/** + * @brief Destructor. + */ +NimBLECharacteristic::~NimBLECharacteristic() { +} // ~NimBLECharacteristic + + +/** + * @brief Create a new BLE Descriptor associated with this characteristic. + * @param [in] uuid - The UUID of the descriptor. + * @param [in] properties - The properties of the descriptor. + * @return The new BLE descriptor. + */ +NimBLEDescriptor* NimBLECharacteristic::createDescriptor(const char* uuid, uint32_t properties, uint16_t max_len) { + return createDescriptor(NimBLEUUID(uuid), properties, max_len); +} + + +/** + * @brief Create a new BLE Descriptor associated with this characteristic. + * @param [in] uuid - The UUID of the descriptor. + * @param [in] properties - The properties of the descriptor. + * @return The new BLE descriptor. + */ +NimBLEDescriptor* NimBLECharacteristic::createDescriptor(const NimBLEUUID &uuid, uint32_t properties, uint16_t max_len) { + NimBLEDescriptor* pDescriptor = nullptr; + if(uuid == NimBLEUUID(uint16_t(0x2902))) { + if(!(m_properties & BLE_GATT_CHR_F_NOTIFY) && !(m_properties & BLE_GATT_CHR_F_INDICATE)) { + assert(0 && "Cannot create 2902 descriptior without characteristic notification or indication property set"); + } + // We cannot have more than one 2902 descriptor, if it's already been created just return a pointer to it. + pDescriptor = getDescriptorByUUID(uuid); + if(pDescriptor == nullptr) { + pDescriptor = new NimBLE2902(this); + } else { + return pDescriptor; + } + + } else if (uuid == NimBLEUUID(uint16_t(0x2904))) { + pDescriptor = new NimBLE2904(this); + + } else { + pDescriptor = new NimBLEDescriptor(uuid, properties, max_len, this); + } + + m_dscVec.push_back(pDescriptor); + return pDescriptor; +} // createCharacteristic + + +/** + * @brief Return the BLE Descriptor for the given UUID if associated with this characteristic. + * @param [in] descriptorUUID The UUID of the descriptor that we wish to retrieve. + * @return The BLE Descriptor. If no such descriptor is associated with the characteristic, nullptr is returned. + */ +NimBLEDescriptor* NimBLECharacteristic::getDescriptorByUUID(const char* uuid) { + return getDescriptorByUUID(NimBLEUUID(uuid)); +} // getDescriptorByUUID + + +/** + * @brief Return the BLE Descriptor for the given UUID if associated with this characteristic. + * @param [in] descriptorUUID The UUID of the descriptor that we wish to retrieve. + * @return The BLE Descriptor. If no such descriptor is associated with the characteristic, nullptr is returned. + */ +NimBLEDescriptor* NimBLECharacteristic::getDescriptorByUUID(const NimBLEUUID &uuid) { + for (auto &it : m_dscVec) { + if (it->getUUID() == uuid) { + return it; + } + } + return nullptr; +} // getDescriptorByUUID + + +/** + * @brief Get the handle of the characteristic. + * @return The handle of the characteristic. + */ +uint16_t NimBLECharacteristic::getHandle() { + return m_handle; +} // getHandle + + +uint16_t NimBLECharacteristic::getProperties() { + return m_properties; +} // getProperties + + +/** + * @brief Get the service associated with this characteristic. + */ +NimBLEService* NimBLECharacteristic::getService() { + return m_pService; +} // getService + + +/** + * @brief Get the UUID of the characteristic. + * @return The UUID of the characteristic. + */ +NimBLEUUID NimBLECharacteristic::getUUID() { + return m_uuid; +} // getUUID + + +/** + * @brief Retrieve the current value of the characteristic. + * @return A pointer to storage containing the current characteristic value. + */ +std::string NimBLECharacteristic::getValue(time_t *timestamp) { + portENTER_CRITICAL(&m_valMux); + std::string retVal = m_value; + if(timestamp != nullptr) { + *timestamp = m_timestamp; + } + portEXIT_CRITICAL(&m_valMux); + + return retVal; +} // getValue + + +/** + * @brief Retrieve the the current data length of the characteristic. + * @return The length of the current characteristic data. + */ +size_t NimBLECharacteristic::getDataLength() { + portENTER_CRITICAL(&m_valMux); + size_t len = m_value.length(); + portEXIT_CRITICAL(&m_valMux); + + return len; +} + + +int NimBLECharacteristic::handleGapEvent(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, + void *arg) +{ + const ble_uuid_t *uuid; + int rc; + NimBLECharacteristic* pCharacteristic = (NimBLECharacteristic*)arg; + + NIMBLE_LOGD(LOG_TAG, "Characteristic %s %s event", pCharacteristic->getUUID().toString().c_str(), + ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR ? "Read" : "Write"); + + uuid = ctxt->chr->uuid; + if(ble_uuid_cmp(uuid, &pCharacteristic->getUUID().getNative()->u) == 0){ + switch(ctxt->op) { + case BLE_GATT_ACCESS_OP_READ_CHR: { + // If the packet header is only 8 bytes this is a follow up of a long read + // so we don't want to call the onRead() callback again. + if(ctxt->om->om_pkthdr_len > 8) { + pCharacteristic->m_pCallbacks->onRead(pCharacteristic); + } + + portENTER_CRITICAL(&pCharacteristic->m_valMux); + rc = os_mbuf_append(ctxt->om, (uint8_t*)pCharacteristic->m_value.data(), + pCharacteristic->m_value.length()); + portEXIT_CRITICAL(&pCharacteristic->m_valMux); + + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + } + + case BLE_GATT_ACCESS_OP_WRITE_CHR: { + if (ctxt->om->om_len > BLE_ATT_ATTR_MAX_LEN) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + + uint8_t buf[BLE_ATT_ATTR_MAX_LEN]; + size_t len = ctxt->om->om_len; + memcpy(buf, ctxt->om->om_data,len); + + os_mbuf *next; + next = SLIST_NEXT(ctxt->om, om_next); + while(next != NULL){ + if((len + next->om_len) > BLE_ATT_ATTR_MAX_LEN) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + memcpy(&buf[len-1], next->om_data, next->om_len); + len += next->om_len; + next = SLIST_NEXT(next, om_next); + } + + pCharacteristic->setValue(buf, len); + pCharacteristic->m_pCallbacks->onWrite(pCharacteristic); + + return 0; + } + default: + break; + } + } + + return BLE_ATT_ERR_UNLIKELY; +} + + +/** + * @brief Set the subscribe status for this characteristic. + * This will maintain a map of subscribed clients and their indicate/notify status. + * @return N/A + */ +void NimBLECharacteristic::setSubscribe(struct ble_gap_event *event) { + uint16_t subVal = 0; + if(event->subscribe.cur_notify) { + subVal |= NIMBLE_DESC_FLAG_NOTIFY; + } + if(event->subscribe.cur_indicate) { + subVal |= NIMBLE_DESC_FLAG_INDICATE; + } + + if(m_pTaskData != nullptr) { + m_pTaskData->rc = (subVal & NIMBLE_DESC_FLAG_INDICATE) ? 0 : + NimBLECharacteristicCallbacks::Status::ERROR_INDICATE_DISABLED; + xTaskNotifyGive(m_pTaskData->task); + } + + NIMBLE_LOGI(LOG_TAG, "New subscribe value for conn: %d val: %d", + event->subscribe.conn_handle, subVal); + + NimBLE2902* p2902 = (NimBLE2902*)getDescriptorByUUID(uint16_t(0x2902)); + if(p2902 == nullptr){ + ESP_LOGE(LOG_TAG, "No 2902 descriptor found for %s", + std::string(getUUID()).c_str()); + return; + } + + p2902->setNotifications(subVal & NIMBLE_DESC_FLAG_NOTIFY); + p2902->setIndications(subVal & NIMBLE_DESC_FLAG_INDICATE); + p2902->m_pCallbacks->onWrite(p2902); + + + auto it = p2902->m_subscribedVec.begin(); + for(;it != p2902->m_subscribedVec.end(); ++it) { + if((*it).conn_id == event->subscribe.conn_handle) { + break; + } + } + + if(subVal > 0) { + if(it == p2902->m_subscribedVec.end()) { + chr_sub_status_t client_sub; + client_sub.conn_id = event->subscribe.conn_handle; + client_sub.sub_val = subVal; + p2902->m_subscribedVec.push_back(client_sub); + return; + } + + (*it).sub_val = subVal; + + } else if(it != p2902->m_subscribedVec.end()) { + p2902->m_subscribedVec.erase(it); + p2902->m_subscribedVec.shrink_to_fit(); + } +} + + +/** + * @brief Send an indication. + * An indication is a transmission of up to the first 20 bytes of the characteristic value. An indication + * will block waiting a positive confirmation from the client. + * @return N/A + */ +void NimBLECharacteristic::indicate() { + NIMBLE_LOGD(LOG_TAG, ">> indicate: length: %d", getDataLength()); + notify(false); + NIMBLE_LOGD(LOG_TAG, "<< indicate"); +} // indicate + +/** + * @brief Send a notify. + * A notification is a transmission of up to the first 20 bytes of the characteristic value. An notification + * will not block; it is a fire and forget. + * @return N/A. + */ +void NimBLECharacteristic::notify(bool is_notification) { + NIMBLE_LOGD(LOG_TAG, ">> notify: length: %d", getDataLength()); + + NimBLE2902* p2902 = (NimBLE2902*)getDescriptorByUUID(uint16_t(0x2902)); + + if(p2902 == nullptr) { + NIMBLE_LOGE(LOG_TAG, + "<< notify-Error; Notify/indicate not enabled for characterisitc: %s", + std::string(getUUID()).c_str()); + } + + if (p2902->m_subscribedVec.size() == 0) { + NIMBLE_LOGD(LOG_TAG, "<< notify: No clients subscribed."); + return; + } + + m_pCallbacks->onNotify(this); + + std::string value = getValue(); + size_t length = value.length(); + bool reqSec = (m_properties & BLE_GATT_CHR_F_READ_AUTHEN) || + (m_properties & BLE_GATT_CHR_F_READ_AUTHOR) || + (m_properties & BLE_GATT_CHR_F_READ_ENC); + int rc = 0; + + for (auto &it : p2902->m_subscribedVec) { + uint16_t _mtu = getService()->getServer()->getPeerMTU(it.conn_id); + + // check if connected and subscribed + if(_mtu == 0 || it.sub_val == 0) { + continue; + } + + // check if security requirements are satisfied + if(reqSec) { + struct ble_gap_conn_desc desc; + rc = ble_gap_conn_find(it.conn_id, &desc); + if(rc != 0 || !desc.sec_state.encrypted) { + continue; + } + } + + if (length > _mtu - 3) { + NIMBLE_LOGW(LOG_TAG, "- Truncating to %d bytes (maximum notify size)", _mtu - 3); + } + + if(is_notification && (!(it.sub_val & NIMBLE_DESC_FLAG_NOTIFY))) { + NIMBLE_LOGW(LOG_TAG, + "Sending notification to client subscribed to indications, sending indication instead"); + is_notification = false; + } + + if(!is_notification && (!(it.sub_val & NIMBLE_DESC_FLAG_INDICATE))) { + NIMBLE_LOGW(LOG_TAG, + "Sending indication to client subscribed to notification, sending notification instead"); + is_notification = true; + } + + // don't create the m_buf until we are sure to send the data or else + // we could be allocating a buffer that doesn't get released. + // We also must create it in each loop iteration because it is consumed with each host call. + os_mbuf *om = ble_hs_mbuf_from_flat((uint8_t*)value.data(), length); + + NimBLECharacteristicCallbacks::Status statusRC; + + if(!is_notification && (m_properties & NIMBLE_PROPERTY::INDICATE)) { + ble_task_data_t taskData = {nullptr, xTaskGetCurrentTaskHandle(),0, nullptr}; + m_pTaskData = &taskData; + + rc = ble_gattc_indicate_custom(it.conn_id, m_handle, om); + if(rc != 0){ + statusRC = NimBLECharacteristicCallbacks::Status::ERROR_GATT; + } else { + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + rc = m_pTaskData->rc; + } + + m_pTaskData = nullptr; + + if(rc == BLE_HS_EDONE) { + rc = 0; + statusRC = NimBLECharacteristicCallbacks::Status::SUCCESS_INDICATE; + } else if(rc == BLE_HS_ETIMEOUT) { + statusRC = NimBLECharacteristicCallbacks::Status::ERROR_INDICATE_TIMEOUT; + } else { + statusRC = NimBLECharacteristicCallbacks::Status::ERROR_INDICATE_FAILURE; + } + } else { + rc = ble_gattc_notify_custom(it.conn_id, m_handle, om); + if(rc == 0) { + statusRC = NimBLECharacteristicCallbacks::Status::SUCCESS_NOTIFY; + } else { + statusRC = NimBLECharacteristicCallbacks::Status::ERROR_GATT; + } + } + + m_pCallbacks->onStatus(this, statusRC, rc); + } + + NIMBLE_LOGD(LOG_TAG, "<< notify"); +} // Notify + + +/** + * @brief Set the callback handlers for this characteristic. + * @param [in] pCallbacks An instance of a callbacks structure used to define any callbacks for the characteristic. + */ +void NimBLECharacteristic::setCallbacks(NimBLECharacteristicCallbacks* pCallbacks) { + if (pCallbacks != nullptr){ + m_pCallbacks = pCallbacks; + } else { + m_pCallbacks = &defaultCallback; + } +} // setCallbacks + + +/** + * @brief Set the value of the characteristic. + * @param [in] data The data to set for the characteristic. + * @param [in] length The length of the data in bytes. + */ +void NimBLECharacteristic::setValue(const uint8_t* data, size_t length) { +#if CONFIG_LOG_DEFAULT_LEVEL > 3 || (ARDUINO_ARCH_ESP32 && CORE_DEBUG_LEVEL >= 4) + char* pHex = NimBLEUtils::buildHexData(nullptr, data, length); + NIMBLE_LOGD(LOG_TAG, ">> setValue: length=%d, data=%s, characteristic UUID=%s", length, pHex, getUUID().toString().c_str()); + free(pHex); +#endif + + if (length > BLE_ATT_ATTR_MAX_LEN) { + NIMBLE_LOGE(LOG_TAG, "Size %d too large, must be no bigger than %d", length, BLE_ATT_ATTR_MAX_LEN); + return; + } + + portENTER_CRITICAL(&m_valMux); + m_value = std::string((char*)data, length); + m_timestamp = time(nullptr); + portEXIT_CRITICAL(&m_valMux); + + NIMBLE_LOGD(LOG_TAG, "<< setValue"); +} // setValue + + +/** + * @brief Set the value of the characteristic from string data. + * We set the value of the characteristic from the bytes contained in the + * string. + * @param [in] Set the value of the characteristic. + * @return N/A. + */ +void NimBLECharacteristic::setValue(const std::string &value) { + setValue((uint8_t*)(value.data()), value.length()); +} // setValue + + +/** + * @brief Return a string representation of the characteristic. + * @return A string representation of the characteristic. + */ +std::string NimBLECharacteristic::toString() { + std::string res = "UUID: " + m_uuid.toString() + ", handle : 0x"; + char hex[5]; + snprintf(hex, sizeof(hex), "%04x", m_handle); + res += hex; + res += " "; + if (m_properties & BLE_GATT_CHR_PROP_READ ) res += "Read "; + if (m_properties & BLE_GATT_CHR_PROP_WRITE) res += "Write "; + if (m_properties & BLE_GATT_CHR_PROP_WRITE_NO_RSP) res += "WriteNoResponse "; + if (m_properties & BLE_GATT_CHR_PROP_BROADCAST) res += "Broadcast "; + if (m_properties & BLE_GATT_CHR_PROP_NOTIFY) res += "Notify "; + if (m_properties & BLE_GATT_CHR_PROP_INDICATE) res += "Indicate "; + return res; +} // toString + + +NimBLECharacteristicCallbacks::~NimBLECharacteristicCallbacks() {} + + +/** + * @brief Callback function to support a read request. + * @param [in] pCharacteristic The characteristic that is the source of the event. + */ +void NimBLECharacteristicCallbacks::onRead(NimBLECharacteristic* pCharacteristic) { + NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onRead: default"); +} // onRead + + +/** + * @brief Callback function to support a write request. + * @param [in] pCharacteristic The characteristic that is the source of the event. + */ +void NimBLECharacteristicCallbacks::onWrite(NimBLECharacteristic* pCharacteristic) { + NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onWrite: default"); +} // onWrite + + +/** + * @brief Callback function to support a Notify request. + * @param [in] pCharacteristic The characteristic that is the source of the event. + */ +void NimBLECharacteristicCallbacks::onNotify(NimBLECharacteristic* pCharacteristic) { + NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onNotify: default"); +} // onNotify + + +/** + * @brief Callback function to support a Notify/Indicate Status report. + * @param [in] pCharacteristic The characteristic that is the source of the event. + * @param [in] s Status of the notification/indication + * @param [in] code Additional code of underlying errors + */ +void NimBLECharacteristicCallbacks::onStatus(NimBLECharacteristic* pCharacteristic, Status s, int code) { + NIMBLE_LOGD("NimBLECharacteristicCallbacks", "onStatus: default"); +} // onStatus + +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) +#endif /* CONFIG_BT_ENABLED */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLECharacteristic.h b/libesp32/NimBLE-Arduino/src/NimBLECharacteristic.h new file mode 100644 index 000000000..4474e5f29 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLECharacteristic.h @@ -0,0 +1,167 @@ +/* + * NimBLECharacteristic.h + * + * Created: on March 3, 2020 + * Author H2zero + * + * Originally: + * BLECharacteristic.h + * + * Created on: Jun 22, 2017 + * Author: kolban + */ + +#ifndef MAIN_NIMBLECHARACTERISTIC_H_ +#define MAIN_NIMBLECHARACTERISTIC_H_ +#include "sdkconfig.h" +#if defined(CONFIG_BT_ENABLED) + +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + +#include "host/ble_hs.h" +/**** FIX COMPILATION ****/ +#undef min +#undef max +/**************************/ + +typedef enum { + READ = BLE_GATT_CHR_F_READ, + READ_ENC = BLE_GATT_CHR_F_READ_ENC, + READ_AUTHEN = BLE_GATT_CHR_F_READ_AUTHEN, + READ_AUTHOR = BLE_GATT_CHR_F_READ_AUTHOR, + WRITE = BLE_GATT_CHR_F_WRITE, + WRITE_NR = BLE_GATT_CHR_F_WRITE_NO_RSP, + WRITE_ENC = BLE_GATT_CHR_F_WRITE_ENC, + WRITE_AUTHEN = BLE_GATT_CHR_F_WRITE_AUTHEN, + WRITE_AUTHOR = BLE_GATT_CHR_F_WRITE_AUTHOR, + BROADCAST = BLE_GATT_CHR_F_BROADCAST, + NOTIFY = BLE_GATT_CHR_F_NOTIFY, + INDICATE = BLE_GATT_CHR_F_INDICATE +} NIMBLE_PROPERTY; + +#include "NimBLEService.h" +#include "NimBLEDescriptor.h" + +#include +#include + +class NimBLEService; +class NimBLEDescriptor; +class NimBLECharacteristicCallbacks; + + +/** + * @brief The model of a %BLE Characteristic. + * + * A BLE Characteristic is an identified value container that manages a value. It is exposed by a BLE server and + * can be read and written to by a %BLE client. + */ +class NimBLECharacteristic { +public: + NimBLEDescriptor* createDescriptor(const char* uuid, + uint32_t properties = + NIMBLE_PROPERTY::READ | + NIMBLE_PROPERTY::WRITE, + uint16_t max_len = 100); + NimBLEDescriptor* createDescriptor(const NimBLEUUID &uuid, + uint32_t properties = + NIMBLE_PROPERTY::READ | + NIMBLE_PROPERTY::WRITE, + uint16_t max_len = 100); + + NimBLEDescriptor* getDescriptorByUUID(const char* uuid); + NimBLEDescriptor* getDescriptorByUUID(const NimBLEUUID &uuid); + NimBLEUUID getUUID(); + std::string getValue(time_t *timestamp = nullptr); + + template + T getValue(time_t *timestamp = nullptr, bool skipSizeCheck = false) { + std::string value = getValue(); + if(!skipSizeCheck && value.size() < sizeof(T)) return T(); + const char *pData = value.data(); + return *((T *)pData); + } + + size_t getDataLength(); + void indicate(); + void notify(bool is_notification = true); + void setCallbacks(NimBLECharacteristicCallbacks* pCallbacks); + void setValue(const uint8_t* data, size_t size); + void setValue(const std::string &value); + + template + void setValue(const T &s) { + setValue((uint8_t*)&s, sizeof(T)); + } + + std::string toString(); + uint16_t getHandle(); + +private: + + friend class NimBLEServer; + friend class NimBLEService; + + NimBLECharacteristic(const char* uuid, + uint16_t properties = + NIMBLE_PROPERTY::READ | + NIMBLE_PROPERTY::WRITE, + NimBLEService* pService = nullptr); + NimBLECharacteristic(const NimBLEUUID &uuid, + uint16_t properties = + NIMBLE_PROPERTY::READ | + NIMBLE_PROPERTY::WRITE, + NimBLEService* pService = nullptr); + + ~NimBLECharacteristic(); + + NimBLEService* getService(); + uint16_t getProperties(); + void setSubscribe(struct ble_gap_event *event); + static int handleGapEvent(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg); + + NimBLEUUID m_uuid; + uint16_t m_handle; + uint16_t m_properties; + NimBLECharacteristicCallbacks* m_pCallbacks; + NimBLEService* m_pService; + std::string m_value; + std::vector m_dscVec; + ble_task_data_t *m_pTaskData; + portMUX_TYPE m_valMux; + time_t m_timestamp; +}; // NimBLECharacteristic + + +/** + * @brief Callbacks that can be associated with a %BLE characteristic to inform of events. + * + * When a server application creates a %BLE characteristic, we may wish to be informed when there is either + * a read or write request to the characteristic's value. An application can register a + * sub-classed instance of this class and will be notified when such an event happens. + */ +class NimBLECharacteristicCallbacks { +public: + typedef enum { + SUCCESS_INDICATE, + SUCCESS_NOTIFY, + ERROR_INDICATE_DISABLED, + ERROR_NOTIFY_DISABLED, + ERROR_GATT, + ERROR_NO_CLIENT, + ERROR_INDICATE_TIMEOUT, + ERROR_INDICATE_FAILURE + }Status; + + virtual ~NimBLECharacteristicCallbacks(); + virtual void onRead(NimBLECharacteristic* pCharacteristic); + virtual void onWrite(NimBLECharacteristic* pCharacteristic); + virtual void onNotify(NimBLECharacteristic* pCharacteristic); + virtual void onStatus(NimBLECharacteristic* pCharacteristic, Status s, int code); +}; + +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) +#endif /* CONFIG_BT_ENABLED */ +#endif /*MAIN_NIMBLECHARACTERISTIC_H_*/ diff --git a/libesp32/NimBLE-Arduino/src/NimBLEClient.cpp b/libesp32/NimBLE-Arduino/src/NimBLEClient.cpp new file mode 100644 index 000000000..71f1c9afc --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLEClient.cpp @@ -0,0 +1,959 @@ +/* + * NimBLEClient.cpp + * + * Created: on Jan 26 2020 + * Author H2zero + * + * Originally: + * BLEClient.cpp + * + * Created on: Mar 22, 2017 + * Author: kolban + */ + +#include "sdkconfig.h" +#if defined(CONFIG_BT_ENABLED) + +#include "nimconfig.h" +#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) + +#include "NimBLEClient.h" +#include "NimBLEDevice.h" +#include "NimBLELog.h" + +#include +#include + +static const char* LOG_TAG = "NimBLEClient"; +static NimBLEClientCallbacks defaultCallbacks; + +/* + * Design + * ------ + * When we perform a getService() request, we are asking the BLE server to return each of the services + * that it exposes. For each service, we receive a callback which contains details + * of the exposed service including its UUID. + * + * The objects we will invent for a NimBLEClient will be as follows: + * * NimBLERemoteService - A model of a remote service. + * * NimBLERemoteCharacteristic - A model of a remote characteristic + * * NimBLERemoteDescriptor - A model of a remote descriptor. + * + * Since there is a hierarchical relationship here, we will have the idea that from a NimBLERemoteService will own + * zero or more remote characteristics and a NimBLERemoteCharacteristic will own zero or more remote NimBLEDescriptors. + * + * We will assume that a NimBLERemoteService contains a vector of owned characteristics + * and that a NimBLECharacteristic contains a vector of owned descriptors. + * + * + */ + +NimBLEClient::NimBLEClient() +{ + m_pClientCallbacks = &defaultCallbacks; + m_conn_id = BLE_HS_CONN_HANDLE_NONE; + m_isConnected = false; + m_waitingToConnect = false; + m_connectTimeout = 30000; + m_deleteCallbacks = false; + m_pTaskData = nullptr; + + m_pConnParams.scan_itvl = 16; // Scan interval in 0.625ms units (NimBLE Default) + m_pConnParams.scan_window = 16; // Scan window in 0.625ms units (NimBLE Default) + m_pConnParams.itvl_min = BLE_GAP_INITIAL_CONN_ITVL_MIN; // min_int = 0x10*1.25ms = 20ms + m_pConnParams.itvl_max = BLE_GAP_INITIAL_CONN_ITVL_MAX; // max_int = 0x20*1.25ms = 40ms + m_pConnParams.latency = BLE_GAP_INITIAL_CONN_LATENCY; // number of packets allowed to skip (extends max interval) + m_pConnParams.supervision_timeout = BLE_GAP_INITIAL_SUPERVISION_TIMEOUT; // timeout = 400*10ms = 4000ms + m_pConnParams.min_ce_len = BLE_GAP_INITIAL_CONN_MIN_CE_LEN; // Minimum length of connection event in 0.625ms units + m_pConnParams.max_ce_len = BLE_GAP_INITIAL_CONN_MAX_CE_LEN; // Maximum length of connection event in 0.625ms units +} // NimBLEClient + + +/** + * @brief Destructor, private - only callable by NimBLEDevice::deleteClient + * to ensure proper disconnect and removal from device list. + */ +NimBLEClient::~NimBLEClient() { + // We may have allocated service references associated with this client. + // Before we are finished with the client, we must release resources. + deleteServices(); + + if(m_deleteCallbacks && m_pClientCallbacks != &defaultCallbacks) { + delete m_pClientCallbacks; + } + +} // ~NimBLEClient + + +/** + * @brief Delete any existing services. + */ +void NimBLEClient::deleteServices() { + NIMBLE_LOGD(LOG_TAG, ">> deleteServices"); + // Delete all the services. + for(auto &it: m_servicesVector) { + delete it; + } + m_servicesVector.clear(); + + NIMBLE_LOGD(LOG_TAG, "<< deleteServices"); +} // deleteServices + + +/** + * @brief Delete service by UUID + * @param [in] uuid The UUID of the service to be deleted from the local database. + * @return Number of services left. + */ +size_t NimBLEClient::deleteService(const NimBLEUUID &uuid) { + NIMBLE_LOGD(LOG_TAG, ">> deleteService"); + // Delete the requested service. + for(auto it = m_servicesVector.begin(); it != m_servicesVector.end(); ++it) { + if((*it)->getUUID() == uuid) { + delete *it; + m_servicesVector.erase(it); + break; + } + } + + NIMBLE_LOGD(LOG_TAG, "<< deleteService"); + + return m_servicesVector.size(); +} // deleteServices + + +/** + * NOT NEEDED + */ + /* +void NimBLEClient::onHostReset() { + +} + */ + +/** + * Add overloaded function to ease connect to peer device with not public address + */ +bool NimBLEClient::connect(NimBLEAdvertisedDevice* device, bool refreshServices) { + NimBLEAddress address(device->getAddress()); + uint8_t type = device->getAddressType(); + return connect(address, type, refreshServices); +} + + +/** + * @brief Connect to the partner (BLE Server). + * @param [in] address The address of the partner. + * @return True on success. + */ +bool NimBLEClient::connect(const NimBLEAddress &address, uint8_t type, bool refreshServices) { + NIMBLE_LOGD(LOG_TAG, ">> connect(%s)", address.toString().c_str()); + + if(!NimBLEDevice::m_synced) { + NIMBLE_LOGC(LOG_TAG, "Host reset, wait for sync."); + return false; + } + + if(ble_gap_conn_active()) { + NIMBLE_LOGE(LOG_TAG, "Connection in progress - must wait."); + return false; + } + + if(!NimBLEDevice::getScan()->stop()) { + return false; + } + + int rc = 0; + m_peerAddress = address; + + ble_addr_t peerAddrt; + memcpy(&peerAddrt.val, address.getNative(),6); + peerAddrt.type = type; + + ble_task_data_t taskData = {this, xTaskGetCurrentTaskHandle(), 0, nullptr}; + m_pTaskData = &taskData; + + /** Try to connect the the advertiser. Allow 30 seconds (30000 ms) for + * timeout (default value of m_connectTimeout). + * Loop on BLE_HS_EBUSY if the scan hasn't stopped yet. + */ + do{ + rc = ble_gap_connect(BLE_OWN_ADDR_PUBLIC, &peerAddrt, m_connectTimeout, &m_pConnParams, + NimBLEClient::handleGapEvent, this); + if(rc == BLE_HS_EBUSY) { + vTaskDelay(1 / portTICK_PERIOD_MS); + } + }while(rc == BLE_HS_EBUSY); + + if (rc != 0 && rc != BLE_HS_EDONE) { + NIMBLE_LOGE(LOG_TAG, "Error: Failed to connect to device; addr_type=%d " + "addr=%s, rc=%d; %s", + type, + m_peerAddress.toString().c_str(), + rc, NimBLEUtils::returnCodeToString(rc)); + m_pTaskData = nullptr; + m_waitingToConnect = false; + return false; + } + + m_waitingToConnect = true; + + // Wait for the connection to complete. + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + + if(taskData.rc != 0){ + return false; + } + + if(refreshServices) { + NIMBLE_LOGD(LOG_TAG, "Refreshing Services for: (%s)", address.toString().c_str()); + deleteServices(); + } + + m_pClientCallbacks->onConnect(this); + + NIMBLE_LOGD(LOG_TAG, "<< connect()"); + return true; +} // connect + + +/** + * @brief Called when a characteristic or descriptor requires encryption or authentication to access it. + * This will pair with the device and bond if enabled. + * @return True on success. + */ +bool NimBLEClient::secureConnection() { + ble_task_data_t taskData = {this, xTaskGetCurrentTaskHandle(), 0, nullptr}; + m_pTaskData = &taskData; + + int rc = NimBLEDevice::startSecurity(m_conn_id); + if(rc != 0){ + m_pTaskData = nullptr; + return false; + } + + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + + if(taskData.rc != 0){ + return false; + } + + return true; +} + + +/** + * @brief Disconnect from the peer. + * @return N/A. + */ +int NimBLEClient::disconnect(uint8_t reason) { + NIMBLE_LOGD(LOG_TAG, ">> disconnect()"); + int rc = 0; + if(m_isConnected){ + rc = ble_gap_terminate(m_conn_id, reason); + if(rc != 0){ + NIMBLE_LOGE(LOG_TAG, "ble_gap_terminate failed: rc=%d %s", rc, + NimBLEUtils::returnCodeToString(rc)); + } + } + + NIMBLE_LOGD(LOG_TAG, "<< disconnect()"); + return rc; +} // disconnect + + +/** + * @brief Set the connection paramaters to use when connecting to a server. + */ +void NimBLEClient::setConnectionParams(uint16_t minInterval, uint16_t maxInterval, + uint16_t latency, uint16_t timeout, + uint16_t scanInterval, uint16_t scanWindow)/*, + uint16_t minConnTime, uint16_t maxConnTime)*/ +{ + + m_pConnParams.scan_itvl = scanInterval; // Scan interval in 0.625ms units + m_pConnParams.scan_window = scanWindow; // Scan window in 0.625ms units + m_pConnParams.itvl_min = minInterval; // min_int = 0x10*1.25ms = 20ms + m_pConnParams.itvl_max = maxInterval; // max_int = 0x20*1.25ms = 40ms + m_pConnParams.latency = latency; // number of packets allowed to skip (extends max interval) + m_pConnParams.supervision_timeout = timeout; // timeout = 400*10ms = 4000ms + + // These are not used by NimBLE at this time - Must leave at defaults + //m_pConnParams->min_ce_len = minConnTime; // Minimum length of connection event in 0.625ms units + //m_pConnParams->max_ce_len = maxConnTime; // Maximum length of connection event in 0.625ms units + + int rc = NimBLEUtils::checkConnParams(&m_pConnParams); + assert(rc == 0 && "Invalid Connection parameters"); +} + + +/** + * Update connection parameters can be called only after connection has been established + */ +void NimBLEClient::updateConnParams(uint16_t minInterval, uint16_t maxInterval, + uint16_t latency, uint16_t timeout) +{ + ble_gap_upd_params params; + + params.latency = latency; + params.itvl_max = maxInterval; + params.itvl_min = minInterval; + params.supervision_timeout = timeout; + // These are not used by NimBLE at this time - Must leave at defaults + params.min_ce_len = BLE_GAP_INITIAL_CONN_MIN_CE_LEN; + params.max_ce_len = BLE_GAP_INITIAL_CONN_MAX_CE_LEN; + + int rc = ble_gap_update_params(m_conn_id, ¶ms); + if(rc != 0) { + NIMBLE_LOGE(LOG_TAG, "Update params error: %d, %s", + rc, NimBLEUtils::returnCodeToString(rc)); + } +} + + +/** + * @brief Set the timeout to wait for connection attempt to complete + * @params[in] Time to wait in seconds. + */ +void NimBLEClient::setConnectTimeout(uint8_t time) { + m_connectTimeout = (uint32_t)(time * 1000); +} + + +/** + * @brief Get the connection id for this client. + * @return The connection id. + */ +uint16_t NimBLEClient::getConnId() { + return m_conn_id; +} // getConnId + + +/** + * @brief Retrieve the address of the peer. + */ +NimBLEAddress NimBLEClient::getPeerAddress() { + return m_peerAddress; +} // getAddress + + +/** + * @brief Ask the BLE server for the RSSI value. + * @return The RSSI value. + */ +int NimBLEClient::getRssi() { + NIMBLE_LOGD(LOG_TAG, ">> getRssi()"); + if (!isConnected()) { + NIMBLE_LOGE(LOG_TAG, "<< getRssi(): Not connected"); + return 0; + } + + int8_t rssiValue = 0; + int rc = ble_gap_conn_rssi(m_conn_id, &rssiValue); + if(rc != 0) { + NIMBLE_LOGE(LOG_TAG, "Failed to read RSSI error code: %d, %s", + rc, NimBLEUtils::returnCodeToString(rc)); + return 0; + } + + return rssiValue; +} // getRssi + + +/** + * @brief Get iterator to the beginning of the vector of remote service pointers. + * @return An iterator to the beginning of the vector of remote service pointers. + */ +std::vector::iterator NimBLEClient::begin() { + return m_servicesVector.begin(); +} + + +/** + * @brief Get iterator to the end of the vector of remote service pointers. + * @return An iterator to the end of the vector of remote service pointers. + */ +std::vector::iterator NimBLEClient::end() { + return m_servicesVector.end(); +} + + +/** + * @brief Get the service BLE Remote Service instance corresponding to the uuid. + * @param [in] uuid The UUID of the service being sought. + * @return A reference to the Service or nullptr if don't know about it. + */ +NimBLERemoteService* NimBLEClient::getService(const char* uuid) { + return getService(NimBLEUUID(uuid)); +} // getService + + +/** + * @brief Get the service object corresponding to the uuid. + * @param [in] uuid The UUID of the service being sought. + * @return A reference to the Service or nullptr if don't know about it. + */ +NimBLERemoteService* NimBLEClient::getService(const NimBLEUUID &uuid) { + NIMBLE_LOGD(LOG_TAG, ">> getService: uuid: %s", uuid.toString().c_str()); + + for(auto &it: m_servicesVector) { + if(it->getUUID() == uuid) { + NIMBLE_LOGD(LOG_TAG, "<< getService: found the service with uuid: %s", uuid.toString().c_str()); + return it; + } + } + + size_t prev_size = m_servicesVector.size(); + if(retrieveServices(&uuid)) { + if(m_servicesVector.size() > prev_size) { + return m_servicesVector.back(); + } + } + + NIMBLE_LOGD(LOG_TAG, "<< getService: not found"); + return nullptr; +} // getService + + +/** + * @Get a pointer to the vector of found services. + * @param [in] bool value to indicate if the current vector should be cleared and + * subsequently all services retrieved from the peripheral. + * If false the vector will be returned with the currently stored services, + * If true it will retrieve all services from the peripheral and return the vector with all services + * @return a pointer to the vector of available services. + */ +std::vector* NimBLEClient::getServices(bool refresh) { + if(refresh) { + deleteServices(); + + if (!retrieveServices()) { + NIMBLE_LOGE(LOG_TAG, "Error: Failed to get services"); + } + else{ + NIMBLE_LOGI(LOG_TAG, "Found %d services", m_servicesVector.size()); + } + } + return &m_servicesVector; +} + + +/** + * @ Retrieves the full database of attributes that the peripheral has available. + */ +void NimBLEClient::discoverAttributes() { + for(auto svc: *getServices(true)) { + for(auto chr: *svc->getCharacteristics(true)) { + chr->getDescriptors(true); + } + } +} + + +/** + * @brief Ask the remote %BLE server for its services. + * A %BLE Server exposes a set of services for its partners. Here we ask the server for its set of + * services and wait until we have received them all. + * We then ask for the characteristics for each service found and their desciptors. + * @return true on success otherwise false if an error occurred + */ +bool NimBLEClient::retrieveServices(const NimBLEUUID *uuid_filter) { +/** + * Design + * ------ + * We invoke ble_gattc_disc_all_svcs. This will request a list of the services exposed by the + * peer BLE partner to be returned in the callback function provided. + */ + + NIMBLE_LOGD(LOG_TAG, ">> retrieveServices"); + + if(!m_isConnected){ + NIMBLE_LOGE(LOG_TAG, "Disconnected, could not retrieve services -aborting"); + return false; + } + + int rc = 0; + ble_task_data_t taskData = {this, xTaskGetCurrentTaskHandle(), 0, nullptr}; + + if(uuid_filter == nullptr) { + rc = ble_gattc_disc_all_svcs(m_conn_id, NimBLEClient::serviceDiscoveredCB, &taskData); + } else { + rc = ble_gattc_disc_svc_by_uuid(m_conn_id, &uuid_filter->getNative()->u, + NimBLEClient::serviceDiscoveredCB, &taskData); + } + + if (rc != 0) { + NIMBLE_LOGE(LOG_TAG, "ble_gattc_disc_all_svcs: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc)); + return false; + } + + // wait until we have all the services + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + + if(taskData.rc == 0){ + NIMBLE_LOGD(LOG_TAG, "<< retrieveServices"); + return true; + } + else { + NIMBLE_LOGE(LOG_TAG, "Could not retrieve services"); + return false; + } +} // getServices + + +/** + * @brief STATIC Callback for the service discovery API function. + * When a service is found or there is none left or there was an error + * the API will call this and report findings. + */ +int NimBLEClient::serviceDiscoveredCB( + uint16_t conn_handle, + const struct ble_gatt_error *error, + const struct ble_gatt_svc *service, void *arg) +{ + NIMBLE_LOGD(LOG_TAG,"Service Discovered >> status: %d handle: %d", + error->status, (error->status == 0) ? service->start_handle : -1); + + ble_task_data_t *pTaskData = (ble_task_data_t*)arg; + NimBLEClient *client = (NimBLEClient*)pTaskData->pATT; + + // Make sure the service discovery is for this device + if(client->getConnId() != conn_handle){ + return 0; + } + + if(error->status == 0) { + // Found a service - add it to the vector + NimBLERemoteService* pRemoteService = new NimBLERemoteService(client, service); + client->m_servicesVector.push_back(pRemoteService); + return 0; + } + + if(error->status == BLE_HS_EDONE) { + pTaskData->rc = 0; + } else { + NIMBLE_LOGE(LOG_TAG, "characteristicDiscCB() rc=%d %s", + error->status, + NimBLEUtils::returnCodeToString(error->status)); + pTaskData->rc = error->status; + } + + xTaskNotifyGive(pTaskData->task); + + NIMBLE_LOGD(LOG_TAG,"<< << Service Discovered"); + return error->status; +} + + +/** + * @brief Get the value of a specific characteristic associated with a specific service. + * @param [in] serviceUUID The service that owns the characteristic. + * @param [in] characteristicUUID The characteristic whose value we wish to read. + * @returns characteristic value or an empty string if not found + */ +std::string NimBLEClient::getValue(const NimBLEUUID &serviceUUID, const NimBLEUUID &characteristicUUID) { + NIMBLE_LOGD(LOG_TAG, ">> getValue: serviceUUID: %s, characteristicUUID: %s", + serviceUUID.toString().c_str(), characteristicUUID.toString().c_str()); + + std::string ret = ""; + NimBLERemoteService* pService = getService(serviceUUID); + + if(pService != nullptr) { + NimBLERemoteCharacteristic* pChar = pService->getCharacteristic(characteristicUUID); + if(pChar != nullptr) { + ret = pChar->readValue(); + } + } + + NIMBLE_LOGD(LOG_TAG, "<> setValue: serviceUUID: %s, characteristicUUID: %s", + serviceUUID.toString().c_str(), characteristicUUID.toString().c_str()); + + bool ret = false; + NimBLERemoteService* pService = getService(serviceUUID); + + if(pService != nullptr) { + NimBLERemoteCharacteristic* pChar = pService->getCharacteristic(characteristicUUID); + if(pChar != nullptr) { + ret = pChar->writeValue(value); + } + } + + NIMBLE_LOGD(LOG_TAG, "<< setValue"); + return ret; +} // setValue + + + +/** + * @brief Get the current mtu of this connection. + */ +uint16_t NimBLEClient::getMTU() { + return ble_att_mtu(m_conn_id); +} + + +/** + * @brief Handle a received GAP event. + * + * @param [in] event + * @param [in] arg = pointer to the client instance + */ + /*STATIC*/ int NimBLEClient::handleGapEvent(struct ble_gap_event *event, void *arg) { + NimBLEClient* client = (NimBLEClient*)arg; + int rc; + + NIMBLE_LOGD(LOG_TAG, "Got Client event %s", NimBLEUtils::gapEventToString(event->type)); + + switch(event->type) { + + case BLE_GAP_EVENT_DISCONNECT: { + if(!client->m_isConnected) + return 0; + + if(client->m_conn_id != event->disconnect.conn.conn_handle) + return 0; + + client->m_isConnected = false; + client->m_waitingToConnect=false; + // Remove the device from ignore list so we will scan it again + NimBLEDevice::removeIgnored(client->m_peerAddress); + + NIMBLE_LOGI(LOG_TAG, "disconnect; reason=%d, %s", event->disconnect.reason, + NimBLEUtils::returnCodeToString(event->disconnect.reason)); + + // If Host reset tell the device now before returning to prevent + // any errors caused by calling host functions before resyncing. + switch(event->disconnect.reason) { + case BLE_HS_ETIMEOUT_HCI: + case BLE_HS_EOS: + case BLE_HS_ECONTROLLER: + case BLE_HS_ENOTSYNCED: + NIMBLE_LOGC(LOG_TAG, "Disconnect - host reset, rc=%d", event->disconnect.reason); + NimBLEDevice::onReset(event->disconnect.reason); + break; + default: + break; + } + + //client->m_conn_id = BLE_HS_CONN_HANDLE_NONE; + client->m_pClientCallbacks->onDisconnect(client); + rc = event->disconnect.reason; + break; + } // BLE_GAP_EVENT_DISCONNECT + + case BLE_GAP_EVENT_CONNECT: { + + if(!client->m_waitingToConnect) + return 0; + + //if(client->m_conn_id != BLE_HS_CONN_HANDLE_NONE) + // return 0; + + client->m_waitingToConnect=false; + + if (event->connect.status == 0) { + client->m_isConnected = true; + + NIMBLE_LOGD(LOG_TAG, "Connection established"); + + client->m_conn_id = event->connect.conn_handle; + + rc = ble_gattc_exchange_mtu(client->m_conn_id, NULL,NULL); + if(rc != 0) { + NIMBLE_LOGE(LOG_TAG, "ble_gattc_exchange_mtu: rc=%d %s",rc, + NimBLEUtils::returnCodeToString(rc)); + break; + } + + // In the case of a multiconnecting device we ignore this device when + // scanning since we are already connected to it + NimBLEDevice::addIgnored(client->m_peerAddress); + } else { + NIMBLE_LOGE(LOG_TAG, "Error: Connection failed; status=%d %s", + event->connect.status, + NimBLEUtils::returnCodeToString(event->connect.status)); + + client->m_isConnected = false; + rc = event->connect.status; + break; + } + return 0; + } // BLE_GAP_EVENT_CONNECT + + case BLE_GAP_EVENT_NOTIFY_RX: { + if(client->m_conn_id != event->notify_rx.conn_handle) + return 0; + + NIMBLE_LOGD(LOG_TAG, "Notify Recieved for handle: %d",event->notify_rx.attr_handle); + + for(auto &it: client->m_servicesVector) { + // Dont waste cycles searching services without this handle in its range + if(it->getEndHandle() < event->notify_rx.attr_handle) { + continue; + } + + auto cVector = &it->m_characteristicVector; + NIMBLE_LOGD(LOG_TAG, "checking service %s for handle: %d", + it->getUUID().toString().c_str(), + event->notify_rx.attr_handle); + + auto characteristic = cVector->cbegin(); + for(; characteristic != cVector->cend(); ++characteristic) { + if((*characteristic)->m_handle == event->notify_rx.attr_handle) + break; + } + + if(characteristic != cVector->cend()) { + NIMBLE_LOGD(LOG_TAG, "Got Notification for characteristic %s", (*characteristic)->toString().c_str()); + + portENTER_CRITICAL(&(*characteristic)->m_valMux); + (*characteristic)->m_value = std::string((char *)event->notify_rx.om->om_data, event->notify_rx.om->om_len); + (*characteristic)->m_timestamp = time(nullptr); + portEXIT_CRITICAL(&(*characteristic)->m_valMux); + + if ((*characteristic)->m_notifyCallback != nullptr) { + NIMBLE_LOGD(LOG_TAG, "Invoking callback for notification on characteristic %s", + (*characteristic)->toString().c_str()); + (*characteristic)->m_notifyCallback(*characteristic, event->notify_rx.om->om_data, + event->notify_rx.om->om_len, + !event->notify_rx.indication); + } + break; + } + } + + return 0; + } // BLE_GAP_EVENT_NOTIFY_RX + + case BLE_GAP_EVENT_CONN_UPDATE_REQ: + case BLE_GAP_EVENT_L2CAP_UPDATE_REQ: { + if(client->m_conn_id != event->conn_update_req.conn_handle){ + return 0; + } + NIMBLE_LOGD(LOG_TAG, "Peer requesting to update connection parameters"); + NIMBLE_LOGD(LOG_TAG, "MinInterval: %d, MaxInterval: %d, Latency: %d, Timeout: %d", + event->conn_update_req.peer_params->itvl_min, + event->conn_update_req.peer_params->itvl_max, + event->conn_update_req.peer_params->latency, + event->conn_update_req.peer_params->supervision_timeout); + + rc = client->m_pClientCallbacks->onConnParamsUpdateRequest(client, + event->conn_update_req.peer_params) ? 0 : BLE_ERR_CONN_PARMS; + + + if(!rc && event->type == BLE_GAP_EVENT_CONN_UPDATE_REQ ) { + event->conn_update_req.self_params->itvl_min = client->m_pConnParams.itvl_min; + event->conn_update_req.self_params->itvl_max = client->m_pConnParams.itvl_max; + event->conn_update_req.self_params->latency = client->m_pConnParams.latency; + event->conn_update_req.self_params->supervision_timeout = client->m_pConnParams.supervision_timeout; + } + + NIMBLE_LOGD(LOG_TAG, "%s peer params", (rc == 0) ? "Accepted" : "Rejected"); + return rc; + } // BLE_GAP_EVENT_CONN_UPDATE_REQ, BLE_GAP_EVENT_L2CAP_UPDATE_REQ + + case BLE_GAP_EVENT_CONN_UPDATE: { + if(client->m_conn_id != event->conn_update.conn_handle){ + return 0; + } + if(event->conn_update.status == 0) { + NIMBLE_LOGI(LOG_TAG, "Connection parameters updated."); + } else { + NIMBLE_LOGE(LOG_TAG, "Update connection parameters failed."); + } + return 0; + } // BLE_GAP_EVENT_CONN_UPDATE + + case BLE_GAP_EVENT_ENC_CHANGE: { + if(client->m_conn_id != event->enc_change.conn_handle){ + return 0; + } + + if(event->enc_change.status == 0) { + struct ble_gap_conn_desc desc; + rc = ble_gap_conn_find(event->conn_update.conn_handle, &desc); + assert(rc == 0); + + if(NimBLEDevice::m_securityCallbacks != nullptr) { + NimBLEDevice::m_securityCallbacks->onAuthenticationComplete(&desc); + } else { + client->m_pClientCallbacks->onAuthenticationComplete(&desc); + } + } + + rc = event->enc_change.status; + break; + } //BLE_GAP_EVENT_ENC_CHANGE + + case BLE_GAP_EVENT_MTU: { + if(client->m_conn_id != event->mtu.conn_handle){ + return 0; + } + NIMBLE_LOGI(LOG_TAG, "mtu update event; conn_handle=%d mtu=%d", + event->mtu.conn_handle, + event->mtu.value); + rc = 0; + break; + } // BLE_GAP_EVENT_MTU + + case BLE_GAP_EVENT_PASSKEY_ACTION: { + struct ble_sm_io pkey = {0,0}; + + if(client->m_conn_id != event->passkey.conn_handle) + return 0; + + if (event->passkey.params.action == BLE_SM_IOACT_DISP) { + pkey.action = event->passkey.params.action; + pkey.passkey = NimBLEDevice::m_passkey; // This is the passkey to be entered on peer + rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey); + NIMBLE_LOGD(LOG_TAG, "ble_sm_inject_io result: %d", rc); + + } else if (event->passkey.params.action == BLE_SM_IOACT_NUMCMP) { + NIMBLE_LOGD(LOG_TAG, "Passkey on device's display: %d", event->passkey.params.numcmp); + pkey.action = event->passkey.params.action; + // Compatibility only - Do not use, should be removed the in future + if(NimBLEDevice::m_securityCallbacks != nullptr) { + pkey.numcmp_accept = NimBLEDevice::m_securityCallbacks->onConfirmPIN(event->passkey.params.numcmp); + //////////////////////////////////////////////////// + } else { + pkey.numcmp_accept = client->m_pClientCallbacks->onConfirmPIN(event->passkey.params.numcmp); + } + + rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey); + NIMBLE_LOGD(LOG_TAG, "ble_sm_inject_io result: %d", rc); + + //TODO: Handle out of band pairing + } else if (event->passkey.params.action == BLE_SM_IOACT_OOB) { + static uint8_t tem_oob[16] = {0}; + pkey.action = event->passkey.params.action; + for (int i = 0; i < 16; i++) { + pkey.oob[i] = tem_oob[i]; + } + rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey); + NIMBLE_LOGD(LOG_TAG, "ble_sm_inject_io result: %d", rc); + //////// + } else if (event->passkey.params.action == BLE_SM_IOACT_INPUT) { + NIMBLE_LOGD(LOG_TAG, "Enter the passkey"); + pkey.action = event->passkey.params.action; + + // Compatibility only - Do not use, should be removed the in future + if(NimBLEDevice::m_securityCallbacks != nullptr) { + pkey.passkey = NimBLEDevice::m_securityCallbacks->onPassKeyRequest(); + ///////////////////////////////////////////// + } else { + client->m_pClientCallbacks->onPassKeyRequest(); + } + + rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey); + NIMBLE_LOGD(LOG_TAG, "ble_sm_inject_io result: %d", rc); + + } else if (event->passkey.params.action == BLE_SM_IOACT_NONE) { + NIMBLE_LOGD(LOG_TAG, "No passkey action required"); + } + + return 0; + } // BLE_GAP_EVENT_PASSKEY_ACTION + + default: { + return 0; + } + } // Switch + + if(client->m_pTaskData != nullptr) { + client->m_pTaskData->rc = rc; + xTaskNotifyGive(client->m_pTaskData->task); + client->m_pTaskData = nullptr; + } + + return 0; +} // handleGapEvent + + +/** + * @brief Are we connected to a server? + * @return True if we are connected and false if we are not connected. + */ +bool NimBLEClient::isConnected() { + return m_isConnected; +} // isConnected + + +/** + * @brief Set the callbacks that will be invoked. + */ +void NimBLEClient::setClientCallbacks(NimBLEClientCallbacks* pClientCallbacks, bool deleteCallbacks) { + if (pClientCallbacks != nullptr){ + m_pClientCallbacks = pClientCallbacks; + } else { + m_pClientCallbacks = &defaultCallbacks; + } + m_deleteCallbacks = deleteCallbacks; +} // setClientCallbacks + + +/** + * @brief Return a string representation of this client. + * @return A string representation of this client. + */ +std::string NimBLEClient::toString() { + std::string res = "peer address: " + m_peerAddress.toString(); + res += "\nServices:\n"; + + for(auto &it: m_servicesVector) { + res += it->toString() + "\n"; + } + + return res; +} // toString + + +void NimBLEClientCallbacks::onConnect(NimBLEClient* pClient) { + NIMBLE_LOGD("NimBLEClientCallbacks", "onConnect: default"); +} + +void NimBLEClientCallbacks::onDisconnect(NimBLEClient* pClient) { + NIMBLE_LOGD("NimBLEClientCallbacks", "onDisconnect: default"); +} + +bool NimBLEClientCallbacks::onConnParamsUpdateRequest(NimBLEClient* pClient, const ble_gap_upd_params* params) { + NIMBLE_LOGD("NimBLEClientCallbacks", "onConnParamsUpdateRequest: default"); + return true; +} + +uint32_t NimBLEClientCallbacks::onPassKeyRequest(){ + NIMBLE_LOGD("NimBLEClientCallbacks", "onPassKeyRequest: default: 123456"); + return 123456; +} + +void NimBLEClientCallbacks::onPassKeyNotify(uint32_t pass_key){ + NIMBLE_LOGD("NimBLEClientCallbacks", "onPassKeyNotify: default: %d", pass_key); +} + +bool NimBLEClientCallbacks::onSecurityRequest(){ + NIMBLE_LOGD("NimBLEClientCallbacks", "onSecurityRequest: default: true"); + return true; +} +void NimBLEClientCallbacks::onAuthenticationComplete(ble_gap_conn_desc* desc){ + NIMBLE_LOGD("NimBLEClientCallbacks", "onAuthenticationComplete: default"); +} +bool NimBLEClientCallbacks::onConfirmPIN(uint32_t pin){ + NIMBLE_LOGD("NimBLEClientCallbacks", "onConfirmPIN: default: true"); + return true; +} + +#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) +#endif // CONFIG_BT_ENABLED diff --git a/libesp32/NimBLE-Arduino/src/NimBLEClient.h b/libesp32/NimBLE-Arduino/src/NimBLEClient.h new file mode 100644 index 000000000..888b42d02 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLEClient.h @@ -0,0 +1,122 @@ +/* + * NimBLEClient.h + * + * Created: on Jan 26 2020 + * Author H2zero + * + * Originally: + * BLEClient.h + * + * Created on: Mar 22, 2017 + * Author: kolban + */ + +#ifndef MAIN_NIMBLECLIENT_H_ +#define MAIN_NIMBLECLIENT_H_ + +#include "sdkconfig.h" +#if defined(CONFIG_BT_ENABLED) + +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) + +#include "NimBLEAddress.h" +#include "NimBLEUUID.h" +#include "NimBLEUtils.h" +#include "NimBLEAdvertisedDevice.h" +#include "NimBLERemoteService.h" + +#include +#include + +class NimBLERemoteService; +class NimBLEClientCallbacks; +class NimBLEAdvertisedDevice; + +/** + * @brief A model of a %BLE client. + */ +class NimBLEClient { +public: + bool connect(NimBLEAdvertisedDevice* device, bool refreshServices = true); + bool connect(const NimBLEAddress &address, uint8_t type = BLE_ADDR_PUBLIC, + bool refreshServices = true); + int disconnect(uint8_t reason = BLE_ERR_REM_USER_CONN_TERM); + NimBLEAddress getPeerAddress(); + int getRssi(); + std::vector* getServices(bool refresh = false); + std::vector::iterator begin(); + std::vector::iterator end(); + NimBLERemoteService* getService(const char* uuid); + NimBLERemoteService* getService(const NimBLEUUID &uuid); + void deleteServices(); + size_t deleteService(const NimBLEUUID &uuid); + std::string getValue(const NimBLEUUID &serviceUUID, const NimBLEUUID &characteristicUUID); + bool setValue(const NimBLEUUID &serviceUUID, const NimBLEUUID &characteristicUUID, + const std::string &value); + bool isConnected(); + void setClientCallbacks(NimBLEClientCallbacks *pClientCallbacks, + bool deleteCallbacks = true); + std::string toString(); + uint16_t getConnId(); + uint16_t getMTU(); + bool secureConnection(); + void setConnectTimeout(uint8_t timeout); + void setConnectionParams(uint16_t minInterval, uint16_t maxInterval, + uint16_t latency, uint16_t timeout, + uint16_t scanInterval=16, uint16_t scanWindow=16); + void updateConnParams(uint16_t minInterval, uint16_t maxInterval, + uint16_t latency, uint16_t timeout); + void discoverAttributes(); + +private: + NimBLEClient(); + ~NimBLEClient(); + + friend class NimBLEDevice; + friend class NimBLERemoteService; + + static int handleGapEvent(struct ble_gap_event *event, void *arg); + static int serviceDiscoveredCB(uint16_t conn_handle, + const struct ble_gatt_error *error, + const struct ble_gatt_svc *service, + void *arg); + bool retrieveServices(const NimBLEUUID *uuid_filter = nullptr); + + NimBLEAddress m_peerAddress = NimBLEAddress(""); + uint16_t m_conn_id; + bool m_isConnected; + bool m_waitingToConnect; + bool m_deleteCallbacks; + int32_t m_connectTimeout; + NimBLEClientCallbacks* m_pClientCallbacks; + ble_task_data_t *m_pTaskData; + + std::vector m_servicesVector; + +private: + friend class NimBLEClientCallbacks; + ble_gap_conn_params m_pConnParams; + +}; // class NimBLEClient + + +/** + * @brief Callbacks associated with a %BLE client. + */ +class NimBLEClientCallbacks { +public: + virtual ~NimBLEClientCallbacks() {}; + virtual void onConnect(NimBLEClient* pClient); + virtual void onDisconnect(NimBLEClient* pClient); + virtual bool onConnParamsUpdateRequest(NimBLEClient* pClient, const ble_gap_upd_params* params); + virtual uint32_t onPassKeyRequest(); + virtual void onPassKeyNotify(uint32_t pass_key); + virtual bool onSecurityRequest(); + virtual void onAuthenticationComplete(ble_gap_conn_desc* desc); + virtual bool onConfirmPIN(uint32_t pin); +}; + +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) +#endif // CONFIG_BT_ENABLED +#endif /* MAIN_NIMBLECLIENT_H_ */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLEDescriptor.cpp b/libesp32/NimBLE-Arduino/src/NimBLEDescriptor.cpp new file mode 100644 index 000000000..e8f7f9f8b --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLEDescriptor.cpp @@ -0,0 +1,267 @@ +/* + * NimBLEDescriptor.cpp + * + * Created: on March 10, 2020 + * Author H2zero + * + * Originally: + * + * BLEDescriptor.cpp + * + * Created on: Jun 22, 2017 + * Author: kolban + */ +#include "sdkconfig.h" +#if defined(CONFIG_BT_ENABLED) + +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + +#include "NimBLEService.h" +#include "NimBLEDescriptor.h" +#include "NimBLELog.h" + +#include + +#define NULL_HANDLE (0xffff) + +static const char* LOG_TAG = "NimBLEDescriptor"; +static NimBLEDescriptorCallbacks defaultCallbacks; + + +/** + * @brief NimBLEDescriptor constructor. + */ +NimBLEDescriptor::NimBLEDescriptor(const char* uuid, uint16_t properties, uint16_t max_len, + NimBLECharacteristic* pCharacteristic) +: NimBLEDescriptor(NimBLEUUID(uuid), max_len, properties, pCharacteristic) { +} + +/** + * @brief NimBLEDescriptor constructor. + */ +NimBLEDescriptor::NimBLEDescriptor(NimBLEUUID uuid, uint16_t properties, uint16_t max_len, + NimBLECharacteristic* pCharacteristic) +{ + m_uuid = uuid; + m_value.attr_len = 0; // Initial length is 0. + m_value.attr_max_len = max_len; // Maximum length of the data. + m_handle = NULL_HANDLE; // Handle is initially unknown. + m_pCharacteristic = nullptr; // No initial characteristic. + m_pCallbacks = &defaultCallbacks; // No initial callback. + m_value.attr_value = (uint8_t*) calloc(max_len,1); // Allocate storage for the value. + m_valMux = portMUX_INITIALIZER_UNLOCKED; + m_properties = 0; + + if (properties & BLE_GATT_CHR_F_READ) { // convert uint16_t properties to uint8_t + m_properties |= BLE_ATT_F_READ; + } + if (properties & (BLE_GATT_CHR_F_WRITE_NO_RSP | BLE_GATT_CHR_F_WRITE)) { + m_properties |= BLE_ATT_F_WRITE; + } + if (properties & BLE_GATT_CHR_F_READ_ENC) { + m_properties |= BLE_ATT_F_READ_ENC; + } + if (properties & BLE_GATT_CHR_F_READ_AUTHEN) { + m_properties |= BLE_ATT_F_READ_AUTHEN; + } + if (properties & BLE_GATT_CHR_F_READ_AUTHOR) { + m_properties |= BLE_ATT_F_READ_AUTHOR; + } + if (properties & BLE_GATT_CHR_F_WRITE_ENC) { + m_properties |= BLE_ATT_F_WRITE_ENC; + } + if (properties & BLE_GATT_CHR_F_WRITE_AUTHEN) { + m_properties |= BLE_ATT_F_WRITE_AUTHEN; + } + if (properties & BLE_GATT_CHR_F_WRITE_AUTHOR) { + m_properties |= BLE_ATT_F_WRITE_AUTHOR; + } + +} // NimBLEDescriptor + + +/** + * @brief NimBLEDescriptor destructor. + */ +NimBLEDescriptor::~NimBLEDescriptor() { + free(m_value.attr_value); // Release the storage we created in the constructor. +} // ~NimBLEDescriptor + +/** + * @brief Get the BLE handle for this descriptor. + * @return The handle for this descriptor. + */ +uint16_t NimBLEDescriptor::getHandle() { + return m_handle; +} // getHandle + + +/** + * @brief Get the length of the value of this descriptor. + * @return The length (in bytes) of the value of this descriptor. + */ +size_t NimBLEDescriptor::getLength() { + return m_value.attr_len; +} // getLength + + +/** + * @brief Get the UUID of the descriptor. + */ +NimBLEUUID NimBLEDescriptor::getUUID() { + return m_uuid; +} // getUUID + + +/** + * @brief Get the value of this descriptor. + * @return A pointer to the value of this descriptor. + */ +uint8_t* NimBLEDescriptor::getValue() { + return m_value.attr_value; +} // getValue + + +int NimBLEDescriptor::handleGapEvent(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, + void *arg) +{ + const ble_uuid_t *uuid; + int rc; + NimBLEDescriptor* pDescriptor = (NimBLEDescriptor*)arg; + + NIMBLE_LOGD(LOG_TAG, "Descriptor %s %s event", pDescriptor->getUUID().toString().c_str(), + ctxt->op == BLE_GATT_ACCESS_OP_READ_DSC ? "Read" : "Write"); + + uuid = ctxt->chr->uuid; + if(ble_uuid_cmp(uuid, &pDescriptor->getUUID().getNative()->u) == 0){ + switch(ctxt->op) { + case BLE_GATT_ACCESS_OP_READ_DSC: { + // If the packet header is only 8 bytes this is a follow up of a long read + // so we don't want to call the onRead() callback again. + if(ctxt->om->om_pkthdr_len > 8) { + pDescriptor->m_pCallbacks->onRead(pDescriptor); + } + portENTER_CRITICAL(&pDescriptor->m_valMux); + rc = os_mbuf_append(ctxt->om, pDescriptor->getValue(), pDescriptor->getLength()); + portEXIT_CRITICAL(&pDescriptor->m_valMux); + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + } + + case BLE_GATT_ACCESS_OP_WRITE_DSC: { + if (ctxt->om->om_len > pDescriptor->m_value.attr_max_len) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + + uint8_t buf[pDescriptor->m_value.attr_max_len]; + size_t len = ctxt->om->om_len; + memcpy(buf, ctxt->om->om_data,len); + os_mbuf *next; + next = SLIST_NEXT(ctxt->om, om_next); + while(next != NULL){ + if((len + next->om_len) > pDescriptor->m_value.attr_max_len) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + memcpy(&buf[len-1], next->om_data, next->om_len); + len += next->om_len; + next = SLIST_NEXT(next, om_next); + } + + pDescriptor->setValue(buf, len); + pDescriptor->m_pCallbacks->onWrite(pDescriptor); + return 0; + } + default: + break; + } + } + + return BLE_ATT_ERR_UNLIKELY; +} + +/** + * @brief Set the callback handlers for this descriptor. + * @param [in] pCallbacks An instance of a callback structure used to define any callbacks for the descriptor. + */ +void NimBLEDescriptor::setCallbacks(NimBLEDescriptorCallbacks* pCallbacks) { + if (pCallbacks != nullptr){ + m_pCallbacks = pCallbacks; + } else { + m_pCallbacks = &defaultCallbacks; + } +} // setCallbacks + + +/** + * @brief Set the handle of this descriptor. + * Set the handle of this descriptor to be the supplied value. + * @param [in] handle The handle to be associated with this descriptor. + * @return N/A. + */ +void NimBLEDescriptor::setHandle(uint16_t handle) { + NIMBLE_LOGD(LOG_TAG, ">> setHandle(0x%.2x): Setting descriptor handle to be 0x%.2x", handle, handle); + m_handle = handle; + NIMBLE_LOGD(LOG_TAG, "<< setHandle()"); +} // setHandle + + +/** + * @brief Set the value of the descriptor. + * @param [in] data The data to set for the descriptor. + * @param [in] length The length of the data in bytes. + */ +void NimBLEDescriptor::setValue(const uint8_t* data, size_t length) { + if (length > m_value.attr_max_len) { + NIMBLE_LOGE(LOG_TAG, "Size %d too large, must be no bigger than %d", length, m_value.attr_max_len); + return; + } + portENTER_CRITICAL(&m_valMux); + m_value.attr_len = length; + memcpy(m_value.attr_value, data, length); + portEXIT_CRITICAL(&m_valMux); +} // setValue + + +/** + * @brief Set the value of the descriptor. + * @param [in] value The value of the descriptor in string form. + */ +void NimBLEDescriptor::setValue(const std::string &value) { + setValue((uint8_t*) value.data(), value.length()); +} // setValue + + +/** + * @brief Return a string representation of the descriptor. + * @return A string representation of the descriptor. + */ +std::string NimBLEDescriptor::toString() { + char hex[5]; + snprintf(hex, sizeof(hex), "%04x", m_handle); + std::string res = "UUID: " + m_uuid.toString() + ", handle: 0x" + hex; + return res; +} // toString + + +NimBLEDescriptorCallbacks::~NimBLEDescriptorCallbacks() {} + +/** + * @brief Callback function to support a read request. + * @param [in] pDescriptor The descriptor that is the source of the event. + */ +void NimBLEDescriptorCallbacks::onRead(NimBLEDescriptor* pDescriptor) { + NIMBLE_LOGD("NimBLEDescriptorCallbacks", "onRead: default"); +} // onRead + + +/** + * @brief Callback function to support a write request. + * @param [in] pDescriptor The descriptor that is the source of the event. + */ +void NimBLEDescriptorCallbacks::onWrite(NimBLEDescriptor* pDescriptor) { + NIMBLE_LOGD("NimBLEDescriptorCallbacks", "onWrite: default"); +} // onWrite + +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) +#endif /* CONFIG_BT_ENABLED */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLEDescriptor.h b/libesp32/NimBLE-Arduino/src/NimBLEDescriptor.h new file mode 100644 index 000000000..f4978f570 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLEDescriptor.h @@ -0,0 +1,106 @@ +/* + * NimBLEDescriptor.h + * + * Created: on March 10, 2020 + * Author H2zero + * + * Originally: + * + * BLEDescriptor.h + * + * Created on: Jun 22, 2017 + * Author: kolban + */ + +#ifndef MAIN_NIMBLEDESCRIPTOR_H_ +#define MAIN_NIMBLEDESCRIPTOR_H_ +#include "sdkconfig.h" +#if defined(CONFIG_BT_ENABLED) + +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + +#include "NimBLECharacteristic.h" +#include "NimBLEUUID.h" + +#include + + +typedef struct +{ + uint16_t attr_max_len; /*!< attribute max value length */ + uint16_t attr_len; /*!< attribute current value length */ + uint8_t *attr_value; /*!< the pointer to attribute value */ +} attr_value_t; + +class NimBLEService; +class NimBLECharacteristic; +class NimBLEDescriptorCallbacks; + + +/** + * @brief A model of a %BLE descriptor. + */ +class NimBLEDescriptor { +public: + uint16_t getHandle(); + size_t getLength(); + NimBLEUUID getUUID(); + uint8_t* getValue(); + void setCallbacks(NimBLEDescriptorCallbacks* pCallbacks); + void setValue(const uint8_t* data, size_t size); + void setValue(const std::string &value); + std::string toString(); + + template + void setValue(const T &s) { + setValue((uint8_t*)&s, sizeof(T)); + } + +private: + friend class NimBLECharacteristic; + friend class NimBLEService; + friend class NimBLE2902; + friend class NimBLE2904; + + NimBLEDescriptor(const char* uuid, uint16_t properties, + uint16_t max_len, + NimBLECharacteristic* pCharacteristic); + + NimBLEDescriptor(NimBLEUUID uuid, uint16_t properties, + uint16_t max_len, + NimBLECharacteristic* pCharacteristic); + + ~NimBLEDescriptor(); + + static int handleGapEvent(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg); + void setHandle(uint16_t handle); + + NimBLEUUID m_uuid; + uint16_t m_handle; + NimBLEDescriptorCallbacks* m_pCallbacks; + NimBLECharacteristic* m_pCharacteristic; + uint8_t m_properties; + attr_value_t m_value; + portMUX_TYPE m_valMux; +}; // NimBLEDescriptor + + +/** + * @brief Callbacks that can be associated with a %BLE descriptors to inform of events. + * + * When a server application creates a %BLE descriptor, we may wish to be informed when there is either + * a read or write request to the descriptors value. An application can register a + * sub-classed instance of this class and will be notified when such an event happens. + */ +class NimBLEDescriptorCallbacks { +public: + virtual ~NimBLEDescriptorCallbacks(); + virtual void onRead(NimBLEDescriptor* pDescriptor); + virtual void onWrite(NimBLEDescriptor* pDescriptor); +}; + +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) +#endif /* CONFIG_BT_ENABLED */ +#endif /* MAIN_NIMBLEDESCRIPTOR_H_ */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLEDevice.cpp b/libesp32/NimBLE-Arduino/src/NimBLEDevice.cpp new file mode 100644 index 000000000..b3d882ba3 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLEDevice.cpp @@ -0,0 +1,695 @@ +/* + * NimBLEDevice.cpp + * + * Created: on Jan 24 2020 + * Author H2zero + * + * Originally: + * + * BLEDevice.cpp + * + * Created on: Mar 16, 2017 + * Author: kolban + */ +#include "sdkconfig.h" +#if defined(CONFIG_BT_ENABLED) + +#include "nimconfig.h" +#include "NimBLEDevice.h" +#include "NimBLEUtils.h" + +#include "esp_err.h" +#include "esp_bt.h" +#include "nvs_flash.h" +#include "esp_nimble_hci.h" +#include "nimble/nimble_port.h" +#include "nimble/nimble_port_freertos.h" +#include "host/ble_hs.h" +#include "host/util/util.h" +#include "services/gap/ble_svc_gap.h" +#include "services/gatt/ble_svc_gatt.h" + +#ifdef ARDUINO_ARCH_ESP32 +#include "esp32-hal-bt.h" +#endif + +#include "NimBLELog.h" + +static const char* LOG_TAG = "NimBLEDevice"; + +/** + * Singletons for the NimBLEDevice. + */ +static bool initialized = false; +#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) +NimBLEScan* NimBLEDevice::m_pScan = nullptr; +#endif +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) +NimBLEServer* NimBLEDevice::m_pServer = nullptr; +#endif +uint32_t NimBLEDevice::m_passkey = 123456; +bool NimBLEDevice::m_synced = false; +#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) +NimBLEAdvertising* NimBLEDevice::m_bleAdvertising = nullptr; +#endif + +gap_event_handler NimBLEDevice::m_customGapHandler = nullptr; +ble_gap_event_listener NimBLEDevice::m_listener; +#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) +std::list NimBLEDevice::m_cList; +#endif +std::list NimBLEDevice::m_ignoreList; +NimBLESecurityCallbacks* NimBLEDevice::m_securityCallbacks = nullptr; + + +/** + * @brief Create a new instance of a server. + * @return A new instance of the server. + */ +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) +/* STATIC */ NimBLEServer* NimBLEDevice::createServer() { + if(NimBLEDevice::m_pServer == nullptr) { + NimBLEDevice::m_pServer = new NimBLEServer(); + ble_gatts_reset(); + ble_svc_gap_init(); + ble_svc_gatt_init(); + } + + return m_pServer; +} // createServer + + +/** + * @brief Get the instance of the server. + * @return A pointer to the server instance. + */ +/* STATIC */ NimBLEServer* NimBLEDevice::getServer() { + return m_pServer; +} // getServer +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + + +#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) +NimBLEAdvertising* NimBLEDevice::getAdvertising() { + if(m_bleAdvertising == nullptr) { + m_bleAdvertising = new NimBLEAdvertising(); + } + return m_bleAdvertising; +} + + +void NimBLEDevice::startAdvertising() { + getAdvertising()->start(); +} // startAdvertising + + +void NimBLEDevice::stopAdvertising() { + getAdvertising()->stop(); +} // stopAdvertising +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) + + +/** + * @brief Retrieve the Scan object that we use for scanning. + * @return The scanning object reference. This is a singleton object. The caller should not + * try and release/delete it. + */ +#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) +/* STATIC */ NimBLEScan* NimBLEDevice::getScan() { + if (m_pScan == nullptr) { + m_pScan = new NimBLEScan(); + } + return m_pScan; +} // getScan +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) + +/** + * @brief Creates a new client object and maintains a list of all client objects + * each client can connect to 1 peripheral device. + * @return A reference to the new client object. + */ +#if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) +/* STATIC */ NimBLEClient* NimBLEDevice::createClient() { + if(m_cList.size() >= NIMBLE_MAX_CONNECTIONS) { + NIMBLE_LOGW("Number of clients exceeds Max connections. Max=(%d)", + NIMBLE_MAX_CONNECTIONS); + } + + NimBLEClient* pClient = new NimBLEClient(); + m_cList.push_back(pClient); + + return pClient; +} // createClient + + +/** + * @brief Delete the client object and remove it from the list. + * Check if it is connected or trying to connect and close/stop it first. + * @param [in] Pointer to the client object. + */ +/* STATIC */ bool NimBLEDevice::deleteClient(NimBLEClient* pClient) { + if(pClient == nullptr) { + return false; + } + + int rc =0; + + if(pClient->m_isConnected) { + rc = pClient->disconnect(); + if (rc != 0 && rc != BLE_HS_EALREADY && rc != BLE_HS_ENOTCONN) { + return false; + } + + while(pClient->m_isConnected) { + vTaskDelay(10); + } + } + + if(pClient->m_waitingToConnect) { + rc = ble_gap_conn_cancel(); + if (rc != 0 && rc != BLE_HS_EALREADY) { + return false; + } + while(pClient->m_waitingToConnect) { + vTaskDelay(10); + } + } + + m_cList.remove(pClient); + delete pClient; + + return true; +} // deleteClient + + +/** + * @brief get the list of clients. + * @return a pointer to the list of clients. + */ +/* STATIC */std::list* NimBLEDevice::getClientList() { + return &m_cList; +} // getClientList + + +/** + * @brief get the size of the list of clients. + * @return a pointer to the list of clients. + */ +/* STATIC */size_t NimBLEDevice::getClientListSize() { + return m_cList.size(); +} // getClientList + + +/** + * @brief Get a reference to a client by connection ID. + * @param [in] The client connection ID to search for. + * @return A reference pointer to the client with the spcified connection ID. + */ +/* STATIC */NimBLEClient* NimBLEDevice::getClientByID(uint16_t conn_id) { + for(auto it = m_cList.cbegin(); it != m_cList.cend(); ++it) { + if((*it)->getConnId() == conn_id) { + return (*it); + } + } + assert(0); + return nullptr; +} // getClientByID + + +/** + * @brief Get a reference to a client by peer address. + * @param [in] a NimBLEAddress of the peer to search for. + * @return A reference pointer to the client with the peer address. + */ +/* STATIC */NimBLEClient* NimBLEDevice::getClientByPeerAddress(const NimBLEAddress &peer_addr) { + for(auto it = m_cList.cbegin(); it != m_cList.cend(); ++it) { + if((*it)->getPeerAddress().equals(peer_addr)) { + return (*it); + } + } + return nullptr; +} // getClientPeerAddress + + +/** + * @brief Finds the first disconnected client in the list. + * @return A reference pointer to the first client that is not connected to a peer. + */ +/* STATIC */NimBLEClient* NimBLEDevice::getDisconnectedClient() { + for(auto it = m_cList.cbegin(); it != m_cList.cend(); ++it) { + if(!(*it)->isConnected()) { + return (*it); + } + } + return nullptr; +} // getDisconnectedClient + +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) + + +/** + * @brief Set the transmission power. + * The power level can be one of: + * * ESP_PWR_LVL_N12 = 0, !< Corresponding to -12dbm + * * ESP_PWR_LVL_N9 = 1, !< Corresponding to -9dbm + * * ESP_PWR_LVL_N6 = 2, !< Corresponding to -6dbm + * * ESP_PWR_LVL_N3 = 3, !< Corresponding to -3dbm + * * ESP_PWR_LVL_N0 = 4, !< Corresponding to 0dbm + * * ESP_PWR_LVL_P3 = 5, !< Corresponding to +3dbm + * * ESP_PWR_LVL_P6 = 6, !< Corresponding to +6dbm + * * ESP_PWR_LVL_P9 = 7, !< Corresponding to +9dbm + * @param [in] powerLevel. + */ +/* STATIC */ void NimBLEDevice::setPower(esp_power_level_t powerLevel, esp_ble_power_type_t powerType) { + NIMBLE_LOGD(LOG_TAG, ">> setPower: %d (type: %d)", powerLevel, powerType); + esp_err_t errRc = esp_ble_tx_power_set(powerType, powerLevel); + if (errRc != ESP_OK) { + NIMBLE_LOGE(LOG_TAG, "esp_ble_tx_power_set: rc=%d", errRc); + } + NIMBLE_LOGD(LOG_TAG, "<< setPower"); +} // setPower + + +/* STATIC */ int NimBLEDevice::getPower(esp_ble_power_type_t powerType) { + + switch(esp_ble_tx_power_get(powerType)) { + case ESP_PWR_LVL_N12: + return -12; + case ESP_PWR_LVL_N9: + return -9; + case ESP_PWR_LVL_N6: + return -6; + case ESP_PWR_LVL_N3: + return -6; + case ESP_PWR_LVL_N0: + return 0; + case ESP_PWR_LVL_P3: + return 3; + case ESP_PWR_LVL_P6: + return 6; + case ESP_PWR_LVL_P9: + return 9; + default: + return BLE_HS_ADV_TX_PWR_LVL_AUTO; + } +} // setPower + + +/** + * @brief Get our device address. + * @return A NimBLEAddress object of our public address if we have one, + * if not then our current random address. + */ +/* STATIC*/ NimBLEAddress NimBLEDevice::getAddress() { + ble_addr_t addr = {BLE_ADDR_PUBLIC, 0}; + //ble_hs_id_copy_addr(BLE_ADDR_PUBLIC, addr.val, NULL) + + if(BLE_HS_ENOADDR == ble_hs_id_copy_addr(BLE_ADDR_PUBLIC, addr.val, NULL)) { + NIMBLE_LOGD(LOG_TAG, "Public address not found, checking random"); + addr.type = BLE_ADDR_RANDOM; + ble_hs_id_copy_addr(BLE_ADDR_RANDOM, addr.val, NULL); + } + + return NimBLEAddress(addr); +} // getAddress + + +/** + * @brief Return a string representation of the address of this device. + * @return A string representation of this device address. + */ +/* STATIC */ std::string NimBLEDevice::toString() { + return getAddress().toString(); +} // toString + + +/** + * @brief Setup local mtu that will be used to negotiate mtu during request from client peer + * @param [in] mtu Value to set local mtu, should be larger than 23 and lower or equal to + * BLE_ATT_MTU_MAX = 527 + */ +/* STATIC */int NimBLEDevice::setMTU(uint16_t mtu) { + NIMBLE_LOGD(LOG_TAG, ">> setLocalMTU: %d", mtu); + + int rc = ble_att_set_preferred_mtu(mtu); + + if (rc != 0) { + NIMBLE_LOGE(LOG_TAG, "Could not set local mtu value to: %d", mtu); + } + + NIMBLE_LOGD(LOG_TAG, "<< setLocalMTU"); + return rc; +} // setMTU + + +/** + * @brief Get local MTU value set. + */ +/* STATIC */uint16_t NimBLEDevice::getMTU() { + return ble_att_preferred_mtu(); +} + + +/** + * @brief Host reset, we pass the message so we don't make calls until resynced. + */ +/* STATIC */ void NimBLEDevice::onReset(int reason) +{ + if(!m_synced) { + return; + } + + m_synced = false; + +#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) + if(m_pScan != nullptr) { + m_pScan->onHostReset(); + } +#endif + +/* Not needed + if(m_pServer != nullptr) { + m_pServer->onHostReset(); + } + + for(auto it = m_cList.cbegin(); it != m_cList.cend(); ++it) { + (*it)->onHostReset(); + } +*/ + +#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) + if(m_bleAdvertising != nullptr) { + m_bleAdvertising->onHostReset(); + } +#endif + + NIMBLE_LOGC(LOG_TAG, "Resetting state; reason=%d, %s", reason, + NimBLEUtils::returnCodeToString(reason)); +} // onReset + + +/** + * @brief Host resynced with controller, all clear to make calls. + */ +/* STATIC */ void NimBLEDevice::onSync(void) +{ + NIMBLE_LOGI(LOG_TAG, "NimBle host synced."); + // This check is needed due to potentially being called multiple times in succession + // If this happens, the call to scan start may get stuck or cause an advertising fault. + if(m_synced) { + return; + } + + /* Make sure we have proper identity address set (public preferred) */ + int rc = ble_hs_util_ensure_addr(0); + assert(rc == 0); + + m_synced = true; + + if(initialized) { +#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) + if(m_pScan != nullptr) { + // Restart scanning with the last values sent, allow to clear results. + m_pScan->start(m_pScan->m_duration, m_pScan->m_scanCompleteCB); + } +#endif + +#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) + if(m_bleAdvertising != nullptr) { + // Restart advertisng, parameters should already be set. + m_bleAdvertising->start(); + } +#endif + } +} // onSync + + +/** + * @brief The main host task. + */ +/* STATIC */ void NimBLEDevice::host_task(void *param) +{ + NIMBLE_LOGI(LOG_TAG, "BLE Host Task Started"); + /* This function will return only when nimble_port_stop() is executed */ + nimble_port_run(); + + nimble_port_freertos_deinit(); +} // host_task + + +/** + * @brief Initialize the %BLE environment. + * @param deviceName The device name of the device. + */ +/* STATIC */ void NimBLEDevice::init(const std::string &deviceName) { + if(!initialized){ + int rc=0; + esp_err_t errRc = ESP_OK; + +#ifdef ARDUINO_ARCH_ESP32 + // make sure the linker includes esp32-hal-bt.c so ardruino init doesn't release BLE memory. + btStarted(); +#endif + + errRc = nvs_flash_init(); + + if (errRc == ESP_ERR_NVS_NO_FREE_PAGES || errRc == ESP_ERR_NVS_NEW_VERSION_FOUND) { + ESP_ERROR_CHECK(nvs_flash_erase()); + errRc = nvs_flash_init(); + } + + ESP_ERROR_CHECK(errRc); + + ESP_ERROR_CHECK(esp_nimble_hci_and_controller_init()); + + nimble_port_init(); + + // Setup callbacks for host events + ble_hs_cfg.reset_cb = NimBLEDevice::onReset; + ble_hs_cfg.sync_cb = NimBLEDevice::onSync; + + // Set initial security capabilities + ble_hs_cfg.sm_io_cap = BLE_HS_IO_NO_INPUT_OUTPUT; + ble_hs_cfg.sm_bonding = 0; + ble_hs_cfg.sm_mitm = 0; + ble_hs_cfg.sm_sc = 1; + ble_hs_cfg.sm_our_key_dist = 1; + ble_hs_cfg.sm_their_key_dist = 3; + + ble_hs_cfg.store_status_cb = ble_store_util_status_rr; /*TODO: Implement handler for this*/ + + // Set the device name. + rc = ble_svc_gap_device_name_set(deviceName.c_str()); + assert(rc == 0); + + ble_store_config_init(); + + nimble_port_freertos_init(NimBLEDevice::host_task); + } + // Wait for host and controller to sync before returning and accepting new tasks + while(!m_synced){ + vTaskDelay(1 / portTICK_PERIOD_MS); + } + + initialized = true; // Set the initialization flag to ensure we are only initialized once. +} // init + + +/** + * @brief Shutdown the NimBLE stack/controller. + */ +/* STATIC */ void NimBLEDevice::deinit() { + int ret = nimble_port_stop(); + if (ret == 0) { + nimble_port_deinit(); + + ret = esp_nimble_hci_and_controller_deinit(); + if (ret != ESP_OK) { + NIMBLE_LOGE(LOG_TAG, "esp_nimble_hci_and_controller_deinit() failed with error: %d", ret); + } + + initialized = false; + m_synced = false; + } +} // deinit + + +/** + * @brief Check if the initialization is complete. + */ +bool NimBLEDevice::getInitialized() { + return initialized; +} // getInitialized + + +/** + * @brief Set the authorization mode for this device. + * @param bonding, if true we allow bonding, false no bonding will be performed. + * @param mitm, if true we are capable of man in the middle protection, false if not. + * @param sc, if true we will perform secure connection pairing, false we will use legacy pairing. + */ +/*STATIC*/ void NimBLEDevice::setSecurityAuth(bool bonding, bool mitm, bool sc) { + NIMBLE_LOGD(LOG_TAG, "Setting bonding: %d, mitm: %d, sc: %d",bonding,mitm,sc); + ble_hs_cfg.sm_bonding = bonding; + ble_hs_cfg.sm_mitm = mitm; + ble_hs_cfg.sm_sc = sc; +} // setSecurityAuth + + +/** + * @brief Set the authorization mode for this device. + * @param A bitmap indicating what modes are supported. + * The bits are defined as follows: + ** 0x01 BLE_SM_PAIR_AUTHREQ_BOND + ** 0x04 BLE_SM_PAIR_AUTHREQ_MITM + ** 0x08 BLE_SM_PAIR_AUTHREQ_SC + ** 0x10 BLE_SM_PAIR_AUTHREQ_KEYPRESS - not yet supported. + ** 0xe2 BLE_SM_PAIR_AUTHREQ_RESERVED - for reference only. + */ +/*STATIC*/void NimBLEDevice::setSecurityAuth(uint8_t auth_req) { + NimBLEDevice::setSecurityAuth((auth_req & BLE_SM_PAIR_AUTHREQ_BOND)>0, + (auth_req & BLE_SM_PAIR_AUTHREQ_MITM)>0, + (auth_req & BLE_SM_PAIR_AUTHREQ_SC)>0); +} // setSecurityAuth + + +/** + * @brief Set the Input/Output capabilities of this device. + * @param One of the following: + ** 0x00 BLE_HS_IO_DISPLAY_ONLY DisplayOnly IO capability + ** 0x01 BLE_HS_IO_DISPLAY_YESNO DisplayYesNo IO capability + ** 0x02 BLE_HS_IO_KEYBOARD_ONLY KeyboardOnly IO capability + ** 0x03 BLE_HS_IO_NO_INPUT_OUTPUT NoInputNoOutput IO capability + ** 0x04 BLE_HS_IO_KEYBOARD_DISPLAY KeyboardDisplay Only IO capability + */ +/*STATIC*/ void NimBLEDevice::setSecurityIOCap(uint8_t iocap) { + ble_hs_cfg.sm_io_cap = iocap; +} // setSecurityIOCap + + +/** + * @brief If we are the initiator of the security procedure this sets the keys we will distribute. + * @param A bitmap indicating which keys to distribute during pairing. + * The bits are defined as follows: + ** 0x01: BLE_SM_PAIR_KEY_DIST_ENC - Distribute the encryption key. + ** 0x02: BLE_SM_PAIR_KEY_DIST_ID - Distribute the ID key (IRK). + ** 0x04: BLE_SM_PAIR_KEY_DIST_SIGN + ** 0x08: BLE_SM_PAIR_KEY_DIST_LINK + */ +/*STATIC*/void NimBLEDevice::setSecurityInitKey(uint8_t init_key) { + ble_hs_cfg.sm_our_key_dist = init_key; +} // setsSecurityInitKey + + +/** + * @brief Set the keys we are willing to accept during pairing. + * @param A bitmap indicating which keys to accept during pairing. + * The bits are defined as follows: + ** 0x01: BLE_SM_PAIR_KEY_DIST_ENC - Accept the encryption key. + ** 0x02: BLE_SM_PAIR_KEY_DIST_ID - Accept the ID key (IRK). + ** 0x04: BLE_SM_PAIR_KEY_DIST_SIGN + ** 0x08: BLE_SM_PAIR_KEY_DIST_LINK + */ +/*STATIC*/void NimBLEDevice::setSecurityRespKey(uint8_t init_key) { + ble_hs_cfg.sm_their_key_dist = init_key; +} // setsSecurityRespKey + + +/** + * @brief Set the passkey for pairing. + */ +/*STATIC*/void NimBLEDevice::setSecurityPasskey(uint32_t pin) { + m_passkey = pin; +} // setSecurityPasskey + + +/** + * @brief Get the passkey for pairing. + */ +/*STATIC*/uint32_t NimBLEDevice::getSecurityPasskey() { + return m_passkey; +} // getSecurityPasskey + + +/** + * @brief Set callbacks that will be used to handle encryption negotiation events and authentication events + * @param [in] cllbacks Pointer to NimBLESecurityCallbacks class + */ +void NimBLEDevice::setSecurityCallbacks(NimBLESecurityCallbacks* callbacks) { + NimBLEDevice::m_securityCallbacks = callbacks; +} // setSecurityCallbacks + + +/** + * @brief Start the connection securing and authorization for this connection. + * @param Connection id of the client. + * @returns host return code 0 if success. + */ +/* STATIC */int NimBLEDevice::startSecurity(uint16_t conn_id) { + /* if(m_securityCallbacks != nullptr) { + m_securityCallbacks->onSecurityRequest(); + } + */ + int rc = ble_gap_security_initiate(conn_id); + if(rc != 0){ + NIMBLE_LOGE(LOG_TAG, "ble_gap_security_initiate: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc)); + } + + return rc; +} // startSecurity + + +/** + * @brief Check if the device address is on our ignore list. + * @return True if ignoring. + */ +/*STATIC*/ bool NimBLEDevice::isIgnored(const NimBLEAddress &address) { + for(auto &it : m_ignoreList) { + if(it.equals(address)){ + return true; + } + } + + return false; +} + + +/** + * @brief Add a device to the ignore list. + * @param Address of the device we want to ignore. + */ +/*STATIC*/ void NimBLEDevice::addIgnored(const NimBLEAddress &address) { + m_ignoreList.push_back(address); +} + + +/** + * @brief Remove a device from the ignore list. + * @param Address of the device we want to remove from the list. + */ +/*STATIC*/void NimBLEDevice::removeIgnored(const NimBLEAddress &address) { + for(auto it = m_ignoreList.begin(); it != m_ignoreList.end(); ++it) { + if((*it).equals(address)){ + m_ignoreList.erase(it); + return; + } + } +} + + +/** + * @brief Set a custom callback for gap events. + */ +void NimBLEDevice::setCustomGapHandler(gap_event_handler handler) { + m_customGapHandler = handler; + int rc = ble_gap_event_listener_register(&m_listener, m_customGapHandler, NULL); + if(rc == BLE_HS_EALREADY){ + NIMBLE_LOGI(LOG_TAG, "Already listening to GAP events."); + } + else{ + assert(rc == 0); + } +} // setCustomGapHandler + + +#endif // CONFIG_BT_ENABLED diff --git a/libesp32/NimBLE-Arduino/src/NimBLEDevice.h b/libesp32/NimBLE-Arduino/src/NimBLEDevice.h new file mode 100644 index 000000000..412647987 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLEDevice.h @@ -0,0 +1,191 @@ +/* + * NimBLEDevice.h + * + * Created: on Jan 24 2020 + * Author H2zero + * + * Originally: + * + * BLEDevice.h + * + * Created on: Mar 16, 2017 + * Author: kolban + */ + +#ifndef MAIN_NIMBLEDEVICE_H_ +#define MAIN_NIMBLEDEVICE_H_ +#include "sdkconfig.h" +#if defined(CONFIG_BT_ENABLED) + +#include "nimconfig.h" + +#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) +#include "NimBLEScan.h" +#endif + +#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) +#include "NimBLEAdvertising.h" +#endif + +#if defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) +#include "NimBLEClient.h" +#endif + +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) +#include "NimBLEServer.h" +#endif + +#include "NimBLEUtils.h" +#include "NimBLESecurity.h" +#include "NimBLEAddress.h" + +#include "esp_bt.h" + +#include +#include +#include + +#define BLEDevice NimBLEDevice +#define BLEClient NimBLEClient +#define BLERemoteService NimBLERemoteService +#define BLERemoteCharacteristic NimBLERemoteCharacteristic +#define BLERemoteDescriptor NimBLERemoteDescriptor +#define BLEAdvertisedDevice NimBLEAdvertisedDevice +#define BLEScan NimBLEScan +#define BLEUUID NimBLEUUID +#define BLESecurity NimBLESecurity +#define BLESecurityCallbacks NimBLESecurityCallbacks +#define BLEAddress NimBLEAddress +#define BLEUtils NimBLEUtils +#define BLEClientCallbacks NimBLEClientCallbacks +#define BLEAdvertisedDeviceCallbacks NimBLEAdvertisedDeviceCallbacks +#define BLEScanResults NimBLEScanResults +#define BLEServer NimBLEServer +#define BLEService NimBLEService +#define BLECharacteristic NimBLECharacteristic +#define BLEAdvertising NimBLEAdvertising +#define BLEServerCallbacks NimBLEServerCallbacks +#define BLECharacteristicCallbacks NimBLECharacteristicCallbacks +#define BLEAdvertisementData NimBLEAdvertisementData +#define BLEDescriptor NimBLEDescriptor +#define BLE2902 NimBLE2902 +#define BLE2904 NimBLE2904 +#define BLEDescriptorCallbacks NimBLEDescriptorCallbacks +#define BLEBeacon NimBLEBeacon +#define BLEEddystoneTLM NimBLEEddystoneTLM +#define BLEEddystoneURL NimBLEEddystoneURL + +#ifdef CONFIG_BT_NIMBLE_MAX_CONNECTIONS +#define NIMBLE_MAX_CONNECTIONS CONFIG_BT_NIMBLE_MAX_CONNECTIONS +#else +#define NIMBLE_MAX_CONNECTIONS CONFIG_NIMBLE_MAX_CONNECTIONS +#endif + +/** + * @brief BLE functions. + */ + typedef int (*gap_event_handler)(ble_gap_event *event, void *arg); + +extern "C" void ble_store_config_init(void); + +class NimBLEDevice { +public: + static void init(const std::string &deviceName); + static void deinit(); + static bool getInitialized(); + static NimBLEAddress getAddress(); + static std::string toString(); + +#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) + static NimBLEScan* getScan(); +#endif + +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + static NimBLEServer* createServer(); + static NimBLEServer* getServer(); +#endif + + static void setPower(esp_power_level_t powerLevel, esp_ble_power_type_t powerType=ESP_BLE_PWR_TYPE_DEFAULT); + static int getPower(esp_ble_power_type_t powerType=ESP_BLE_PWR_TYPE_DEFAULT); + static void setCustomGapHandler(gap_event_handler handler); + static void setSecurityAuth(bool bonding, bool mitm, bool sc); + static void setSecurityAuth(uint8_t auth_req); + static void setSecurityIOCap(uint8_t iocap); + static void setSecurityInitKey(uint8_t init_key); + static void setSecurityRespKey(uint8_t init_key); + static void setSecurityPasskey(uint32_t pin); + static uint32_t getSecurityPasskey(); + static void setSecurityCallbacks(NimBLESecurityCallbacks* pCallbacks); + static int startSecurity(uint16_t conn_id); + static int setMTU(uint16_t mtu); + static uint16_t getMTU(); + static bool isIgnored(const NimBLEAddress &address); + static void addIgnored(const NimBLEAddress &address); + static void removeIgnored(const NimBLEAddress &address); + +#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) + static NimBLEAdvertising* getAdvertising(); + static void startAdvertising(); + static void stopAdvertising(); +#endif + +#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) + static NimBLEClient* createClient(); + static bool deleteClient(NimBLEClient* pClient); + static NimBLEClient* getClientByID(uint16_t conn_id); + static NimBLEClient* getClientByPeerAddress(const NimBLEAddress &peer_addr); + static NimBLEClient* getDisconnectedClient(); + static size_t getClientListSize(); + static std::list* getClientList(); +#endif + +private: +#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) + friend class NimBLEClient; +#endif + +#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) + friend class NimBLEScan; +#endif + +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + friend class NimBLEServer; + friend class NimBLECharacteristic; +#endif + +#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) + friend class NimBLEAdvertising; +#endif + + static void onReset(int reason); + static void onSync(void); + static void host_task(void *param); + static bool m_synced; + +#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) + static NimBLEScan* m_pScan; +#endif + +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + static NimBLEServer* m_pServer; +#endif + +#if defined(CONFIG_BT_NIMBLE_ROLE_BROADCASTER) + static NimBLEAdvertising* m_bleAdvertising; +#endif + +#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) + static std::list m_cList; +#endif + static std::list m_ignoreList; + static NimBLESecurityCallbacks* m_securityCallbacks; + static uint32_t m_passkey; + static ble_gap_event_listener m_listener; + +public: + static gap_event_handler m_customGapHandler; +}; + + +#endif // CONFIG_BT_ENABLED +#endif // MAIN_NIMBLEDEVICE_H_ diff --git a/libesp32/NimBLE-Arduino/src/NimBLEEddystoneTLM.cpp b/libesp32/NimBLE-Arduino/src/NimBLEEddystoneTLM.cpp new file mode 100644 index 000000000..990a36f52 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLEEddystoneTLM.cpp @@ -0,0 +1,152 @@ +/* + * NimBLEEddystoneTLM.cpp + * + * Created: on March 15 2020 + * Author H2zero + * + * Originally: + * + * BLEEddystoneTLM.cpp + * + * Created on: Mar 12, 2018 + * Author: pcbreflux + */ +#include "sdkconfig.h" +#if defined(CONFIG_BT_ENABLED) + +#include "NimBLEEddystoneTLM.h" +#include "NimBLELog.h" + +#include + +#define ENDIAN_CHANGE_U16(x) ((((x)&0xFF00)>>8) + (((x)&0xFF)<<8)) +#define ENDIAN_CHANGE_U32(x) ((((x)&0xFF000000)>>24) + (((x)&0x00FF0000)>>8)) + ((((x)&0xFF00)<<8) + (((x)&0xFF)<<24)) + +static const char LOG_TAG[] = "NimBLEEddystoneTLM"; + + +NimBLEEddystoneTLM::NimBLEEddystoneTLM() { + beaconUUID = 0xFEAA; + m_eddystoneData.frameType = EDDYSTONE_TLM_FRAME_TYPE; + m_eddystoneData.version = 0; + m_eddystoneData.volt = 3300; // 3300mV = 3.3V + m_eddystoneData.temp = (uint16_t) ((float) 23.00 * 256); // 8.8 fixed format + m_eddystoneData.advCount = 0; + m_eddystoneData.tmil = 0; +} // NimBLEEddystoneTLM + +std::string NimBLEEddystoneTLM::getData() { + return std::string((char*) &m_eddystoneData, sizeof(m_eddystoneData)); +} // getData + +NimBLEUUID NimBLEEddystoneTLM::getUUID() { + return NimBLEUUID(beaconUUID); +} // getUUID + +uint8_t NimBLEEddystoneTLM::getVersion() { + return m_eddystoneData.version; +} // getVersion + +uint16_t NimBLEEddystoneTLM::getVolt() { + return ENDIAN_CHANGE_U16(m_eddystoneData.volt); +} // getVolt + +float NimBLEEddystoneTLM::getTemp() { + return ENDIAN_CHANGE_U16(m_eddystoneData.temp) / 256.0f; +} // getTemp + +uint32_t NimBLEEddystoneTLM::getCount() { + return ENDIAN_CHANGE_U32(m_eddystoneData.advCount); +} // getCount + +uint32_t NimBLEEddystoneTLM::getTime() { + return (ENDIAN_CHANGE_U32(m_eddystoneData.tmil)) / 10; +} // getTime + +std::string NimBLEEddystoneTLM::toString() { + std::string out = ""; + uint32_t rawsec = ENDIAN_CHANGE_U32(m_eddystoneData.tmil); + char val[12]; + + out += "Version "; // + std::string(m_eddystoneData.version); + snprintf(val, sizeof(val), "%d", m_eddystoneData.version); + out += val; + out += "\n"; + out += "Battery Voltage "; // + ENDIAN_CHANGE_U16(m_eddystoneData.volt); + snprintf(val, sizeof(val), "%d", ENDIAN_CHANGE_U16(m_eddystoneData.volt)); + out += val; + out += " mV\n"; + + out += "Temperature "; + snprintf(val, sizeof(val), "%.2f", ENDIAN_CHANGE_U16(m_eddystoneData.temp) / 256.0f); + out += val; + out += " C\n"; + + out += "Adv. Count "; + snprintf(val, sizeof(val), "%d", ENDIAN_CHANGE_U32(m_eddystoneData.advCount)); + out += val; + out += "\n"; + + out += "Time in seconds "; + snprintf(val, sizeof(val), "%d", rawsec/10); + out += val; + out += "\n"; + + out += "Time "; + + snprintf(val, sizeof(val), "%04d", rawsec / 864000); + out += val; + out += "."; + + snprintf(val, sizeof(val), "%02d", (rawsec / 36000) % 24); + out += val; + out += ":"; + + snprintf(val, sizeof(val), "%02d", (rawsec / 600) % 60); + out += val; + out += ":"; + + snprintf(val, sizeof(val), "%02d", (rawsec / 10) % 60); + out += val; + out += "\n"; + + return out; +} // toString + +/** + * Set the raw data for the beacon record. + */ +void NimBLEEddystoneTLM::setData(const std::string &data) { + if (data.length() != sizeof(m_eddystoneData)) { + NIMBLE_LOGE(LOG_TAG, "Unable to set the data ... length passed in was %d and expected %d", + data.length(), sizeof(m_eddystoneData)); + return; + } + memcpy(&m_eddystoneData, data.data(), data.length()); +} // setData + +void NimBLEEddystoneTLM::setUUID(const NimBLEUUID &l_uuid) { + beaconUUID = l_uuid.getNative()->u16.value; +} // setUUID + +void NimBLEEddystoneTLM::setVersion(uint8_t version) { + m_eddystoneData.version = version; +} // setVersion + +void NimBLEEddystoneTLM::setVolt(uint16_t volt) { + m_eddystoneData.volt = volt; +} // setVolt + +void NimBLEEddystoneTLM::setTemp(float temp) { + m_eddystoneData.temp = (uint16_t)temp; +} // setTemp + +void NimBLEEddystoneTLM::setCount(uint32_t advCount) { + m_eddystoneData.advCount = advCount; +} // setCount + +void NimBLEEddystoneTLM::setTime(uint32_t tmil) { + m_eddystoneData.tmil = tmil; +} // setTime + +#endif diff --git a/libesp32/NimBLE-Arduino/src/NimBLEEddystoneTLM.h b/libesp32/NimBLE-Arduino/src/NimBLEEddystoneTLM.h new file mode 100644 index 000000000..eb1cb0721 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLEEddystoneTLM.h @@ -0,0 +1,60 @@ +/* + * NimBLEEddystoneTLM.h + * + * Created: on March 15 2020 + * Author H2zero + * + * Originally: + * + * BLEEddystoneTLM.h + * + * Created on: Mar 12, 2018 + * Author: pcbreflux + */ + +#ifndef _NimBLEEddystoneTLM_H_ +#define _NimBLEEddystoneTLM_H_ +#include "NimBLEUUID.h" + +#include + +#define EDDYSTONE_TLM_FRAME_TYPE 0x20 + +/** + * @brief Representation of a beacon. + * See: + * * https://github.com/google/eddystone + */ +class NimBLEEddystoneTLM { +public: + NimBLEEddystoneTLM(); + std::string getData(); + NimBLEUUID getUUID(); + uint8_t getVersion(); + uint16_t getVolt(); + float getTemp(); + uint32_t getCount(); + uint32_t getTime(); + std::string toString(); + void setData(const std::string &data); + void setUUID(const NimBLEUUID &l_uuid); + void setVersion(uint8_t version); + void setVolt(uint16_t volt); + void setTemp(float temp); + void setCount(uint32_t advCount); + void setTime(uint32_t tmil); + +private: + uint16_t beaconUUID; + struct { + uint8_t frameType; + uint8_t version; + uint16_t volt; + uint16_t temp; + uint32_t advCount; + uint32_t tmil; + } __attribute__((packed)) m_eddystoneData; + +}; // NimBLEEddystoneTLM + +#endif /* _NimBLEEddystoneTLM_H_ */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLEEddystoneURL.cpp b/libesp32/NimBLE-Arduino/src/NimBLEEddystoneURL.cpp new file mode 100644 index 000000000..ce7975958 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLEEddystoneURL.cpp @@ -0,0 +1,159 @@ +/* + * NimBLEEddystoneURL.cpp + * + * Created: on March 15 2020 + * Author H2zero + * + * Originally: + * + * BLEEddystoneURL.cpp + * + * Created on: Mar 12, 2018 + * Author: pcbreflux + */ +#include "sdkconfig.h" +#if defined(CONFIG_BT_ENABLED) + +#include "NimBLEEddystoneURL.h" +#include "NimBLELog.h" + +#include + +static const char LOG_TAG[] = "NimBLEEddystoneURL"; + +NimBLEEddystoneURL::NimBLEEddystoneURL() { + beaconUUID = 0xFEAA; + lengthURL = 0; + m_eddystoneData.frameType = EDDYSTONE_URL_FRAME_TYPE; + m_eddystoneData.advertisedTxPower = 0; + memset(m_eddystoneData.url, 0, sizeof(m_eddystoneData.url)); +} // BLEEddystoneURL + +std::string NimBLEEddystoneURL::getData() { + return std::string((char*) &m_eddystoneData, sizeof(m_eddystoneData)); +} // getData + +NimBLEUUID NimBLEEddystoneURL::getUUID() { + return NimBLEUUID(beaconUUID); +} // getUUID + +int8_t NimBLEEddystoneURL::getPower() { + return m_eddystoneData.advertisedTxPower; +} // getPower + +std::string NimBLEEddystoneURL::getURL() { + return std::string((char*) &m_eddystoneData.url, sizeof(m_eddystoneData.url)); +} // getURL + +std::string NimBLEEddystoneURL::getDecodedURL() { + std::string decodedURL = ""; + + switch (m_eddystoneData.url[0]) { + case 0x00: + decodedURL += "http://www."; + break; + case 0x01: + decodedURL += "https://www."; + break; + case 0x02: + decodedURL += "http://"; + break; + case 0x03: + decodedURL += "https://"; + break; + default: + decodedURL += m_eddystoneData.url[0]; + } + + for (int i = 1; i < lengthURL; i++) { + if (m_eddystoneData.url[i] > 33 && m_eddystoneData.url[i] < 127) { + decodedURL += m_eddystoneData.url[i]; + } else { + switch (m_eddystoneData.url[i]) { + case 0x00: + decodedURL += ".com/"; + break; + case 0x01: + decodedURL += ".org/"; + break; + case 0x02: + decodedURL += ".edu/"; + break; + case 0x03: + decodedURL += ".net/"; + break; + case 0x04: + decodedURL += ".info/"; + break; + case 0x05: + decodedURL += ".biz/"; + break; + case 0x06: + decodedURL += ".gov/"; + break; + case 0x07: + decodedURL += ".com"; + break; + case 0x08: + decodedURL += ".org"; + break; + case 0x09: + decodedURL += ".edu"; + break; + case 0x0A: + decodedURL += ".net"; + break; + case 0x0B: + decodedURL += ".info"; + break; + case 0x0C: + decodedURL += ".biz"; + break; + case 0x0D: + decodedURL += ".gov"; + break; + default: + break; + } + } + } + return decodedURL; +} // getDecodedURL + + + +/** + * Set the raw data for the beacon record. + */ +void NimBLEEddystoneURL::setData(const std::string &data) { + if (data.length() > sizeof(m_eddystoneData)) { + NIMBLE_LOGE(LOG_TAG, "Unable to set the data ... length passed in was %d and max expected %d", + data.length(), sizeof(m_eddystoneData)); + return; + } + memset(&m_eddystoneData, 0, sizeof(m_eddystoneData)); + memcpy(&m_eddystoneData, data.data(), data.length()); + lengthURL = data.length() - (sizeof(m_eddystoneData) - sizeof(m_eddystoneData.url)); +} // setData + +void NimBLEEddystoneURL::setUUID(const NimBLEUUID &l_uuid) { + beaconUUID = l_uuid.getNative()->u16.value; +} // setUUID + +void NimBLEEddystoneURL::setPower(int8_t advertisedTxPower) { + m_eddystoneData.advertisedTxPower = advertisedTxPower; +} // setPower + +void NimBLEEddystoneURL::setURL(const std::string &url) { + if (url.length() > sizeof(m_eddystoneData.url)) { + NIMBLE_LOGE(LOG_TAG, "Unable to set the url ... length passed in was %d and max expected %d", + url.length(), sizeof(m_eddystoneData.url)); + return; + } + memset(m_eddystoneData.url, 0, sizeof(m_eddystoneData.url)); + memcpy(m_eddystoneData.url, url.data(), url.length()); + lengthURL = url.length(); +} // setURL + + +#endif diff --git a/libesp32/NimBLE-Arduino/src/NimBLEEddystoneURL.h b/libesp32/NimBLE-Arduino/src/NimBLEEddystoneURL.h new file mode 100644 index 000000000..9c5f37f80 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLEEddystoneURL.h @@ -0,0 +1,52 @@ +/* + * NimBLEEddystoneURL.h + * + * Created: on March 15 2020 + * Author H2zero + * + * Originally: + * + * BLEEddystoneURL.h + * + * Created on: Mar 12, 2018 + * Author: pcbreflux + */ + +#ifndef _NIMBLEEddystoneURL_H_ +#define _NIMBLEEddystoneURL_H_ +#include "NimBLEUUID.h" + +#include + +#define EDDYSTONE_URL_FRAME_TYPE 0x10 + +/** + * @brief Representation of a beacon. + * See: + * * https://github.com/google/eddystone + */ +class NimBLEEddystoneURL { +public: + NimBLEEddystoneURL(); + std::string getData(); + NimBLEUUID getUUID(); + int8_t getPower(); + std::string getURL(); + std::string getDecodedURL(); + void setData(const std::string &data); + void setUUID(const NimBLEUUID &l_uuid); + void setPower(int8_t advertisedTxPower); + void setURL(const std::string &url); + +private: + uint16_t beaconUUID; + uint8_t lengthURL; + struct { + uint8_t frameType; + int8_t advertisedTxPower; + uint8_t url[16]; + } __attribute__((packed)) m_eddystoneData; + +}; // NIMBLEEddystoneURL + +#endif /* _NIMBLEEddystoneURL_H_ */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLELog.h b/libesp32/NimBLE-Arduino/src/NimBLELog.h new file mode 100644 index 000000000..6e9ed97f3 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLELog.h @@ -0,0 +1,60 @@ +/* + * NimBLELog.h + * + * Created: on Feb 24 2020 + * Author H2zero + * + */ +#ifndef MAIN_NIMBLELOG_H_ +#define MAIN_NIMBLELOG_H_ +#include "sdkconfig.h" +#if defined(CONFIG_BT_ENABLED) + +#include "syscfg/syscfg.h" +#include "modlog/modlog.h" + + +// If Arduino is being used, strip out the colors and ignore log printing below ui setting. +// Note: because CONFIG_LOG_DEFAULT_LEVEL is set at ERROR in Arduino we must use MODLOG_DFLT(ERROR +// otherwise no messages will be printed above that level. +#ifdef ARDUINO_ARCH_ESP32 +#ifndef CORE_DEBUG_LEVEL +#define CORE_DEBUG_LEVEL CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL +#endif + +#if CORE_DEBUG_LEVEL >= 4 +#define NIMBLE_LOGD( tag, format, ... ) MODLOG_DFLT(ERROR, "D %s: "#format"\n",tag,##__VA_ARGS__) +#else +#define NIMBLE_LOGD( tag, format, ... ) (void)tag +#endif + +#if CORE_DEBUG_LEVEL >= 3 +#define NIMBLE_LOGI( tag, format, ... ) MODLOG_DFLT(ERROR, "I %s: "#format"\n",tag,##__VA_ARGS__) +#else +#define NIMBLE_LOGI( tag, format, ... ) (void)tag +#endif + +#if CORE_DEBUG_LEVEL >= 2 +#define NIMBLE_LOGW( tag, format, ... ) MODLOG_DFLT(ERROR, "W %s: "#format"\n",tag,##__VA_ARGS__) +#else +#define NIMBLE_LOGW( tag, format, ... ) (void)tag +#endif + +#if CORE_DEBUG_LEVEL >= 1 +#define NIMBLE_LOGE( tag, format, ... ) MODLOG_DFLT(ERROR, "E %s: "#format"\n",tag,##__VA_ARGS__) +#else +#define NIMBLE_LOGE( tag, format, ... ) (void)tag +#endif + +#define NIMBLE_LOGC( tag, format, ... ) MODLOG_DFLT(CRITICAL, "CRIT %s: "#format"\n",tag,##__VA_ARGS__) + +#else +#define NIMBLE_LOGE( tag, format, ... ) MODLOG_DFLT(ERROR, "\033[0;31mE %s: "#format"\033[0m\n",tag,##__VA_ARGS__) +#define NIMBLE_LOGW( tag, format, ... ) MODLOG_DFLT(WARN, "\033[0;33mW %s: "#format"\033[0m\n",tag,##__VA_ARGS__) +#define NIMBLE_LOGI( tag, format, ... ) MODLOG_DFLT(INFO, "\033[0;32mI %s: "#format"\033[0m\n",tag,##__VA_ARGS__) +#define NIMBLE_LOGD( tag, format, ... ) MODLOG_DFLT(DEBUG, "D %s: "#format"\n",tag,##__VA_ARGS__) +#define NIMBLE_LOGC( tag, format, ... ) MODLOG_DFLT(CRITICAL, "\033[1;31mCRIT %s: "#format"\033[0m\n",tag,##__VA_ARGS__) +#endif /*ARDUINO_ARCH_ESP32*/ + +#endif /*CONFIG_BT_ENABLED*/ +#endif /*MAIN_NIMBLELOG_H_*/ \ No newline at end of file diff --git a/libesp32/NimBLE-Arduino/src/NimBLERemoteCharacteristic.cpp b/libesp32/NimBLE-Arduino/src/NimBLERemoteCharacteristic.cpp new file mode 100644 index 000000000..23089ca77 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLERemoteCharacteristic.cpp @@ -0,0 +1,751 @@ +/* + * NimBLERemoteCharacteristic.cpp + * + * Created: on Jan 27 2020 + * Author H2zero + * + * Originally: + * + * BLERemoteCharacteristic.cpp + * + * Created on: Mar 16, 2017 + * Author: kolban + */ + +#include "sdkconfig.h" +#if defined(CONFIG_BT_ENABLED) + +#include "nimconfig.h" +#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) + +#include "NimBLERemoteCharacteristic.h" +#include "NimBLEUtils.h" +#include "NimBLELog.h" + +static const char* LOG_TAG = "NimBLERemoteCharacteristic"; + +/** + * @brief Constructor. + * @param [in] reference to the service this characteristic belongs to. + * @param [in] ble_gatt_chr struct defined as: + * struct ble_gatt_chr { + * uint16_t def_handle; + * uint16_t val_handle; + * uint8_t properties; + * ble_uuid_any_t uuid; + * }; + */ + NimBLERemoteCharacteristic::NimBLERemoteCharacteristic(NimBLERemoteService *pRemoteService, + const struct ble_gatt_chr *chr) +{ + + switch (chr->uuid.u.type) { + case BLE_UUID_TYPE_16: + m_uuid = NimBLEUUID(chr->uuid.u16.value); + break; + case BLE_UUID_TYPE_32: + m_uuid = NimBLEUUID(chr->uuid.u32.value); + break; + case BLE_UUID_TYPE_128: + m_uuid = NimBLEUUID(const_cast(&chr->uuid.u128)); + break; + default: + m_uuid = nullptr; + break; + } + + m_handle = chr->val_handle; + m_defHandle = chr->def_handle; + m_charProp = chr->properties; + m_pRemoteService = pRemoteService; + m_notifyCallback = nullptr; + m_timestamp = 0; + m_valMux = portMUX_INITIALIZER_UNLOCKED; + } // NimBLERemoteCharacteristic + + +/** + *@brief Destructor. + */ +NimBLERemoteCharacteristic::~NimBLERemoteCharacteristic() { + deleteDescriptors(); +} // ~NimBLERemoteCharacteristic + +/* +#define BLE_GATT_CHR_PROP_BROADCAST 0x01 +#define BLE_GATT_CHR_PROP_READ 0x02 +#define BLE_GATT_CHR_PROP_WRITE_NO_RSP 0x04 +#define BLE_GATT_CHR_PROP_WRITE 0x08 +#define BLE_GATT_CHR_PROP_NOTIFY 0x10 +#define BLE_GATT_CHR_PROP_INDICATE 0x20 +#define BLE_GATT_CHR_PROP_AUTH_SIGN_WRITE 0x40 +#define BLE_GATT_CHR_PROP_EXTENDED 0x80 +*/ + +/** + * @brief Does the characteristic support broadcasting? + * @return True if the characteristic supports broadcasting. + */ +bool NimBLERemoteCharacteristic::canBroadcast() { + return (m_charProp & BLE_GATT_CHR_PROP_BROADCAST) != 0; +} // canBroadcast + + +/** + * @brief Does the characteristic support indications? + * @return True if the characteristic supports indications. + */ +bool NimBLERemoteCharacteristic::canIndicate() { + return (m_charProp & BLE_GATT_CHR_PROP_INDICATE) != 0; +} // canIndicate + + +/** + * @brief Does the characteristic support notifications? + * @return True if the characteristic supports notifications. + */ +bool NimBLERemoteCharacteristic::canNotify() { + return (m_charProp & BLE_GATT_CHR_PROP_NOTIFY) != 0; +} // canNotify + + +/** + * @brief Does the characteristic support reading? + * @return True if the characteristic supports reading. + */ +bool NimBLERemoteCharacteristic::canRead() { + return (m_charProp & BLE_GATT_CHR_PROP_READ) != 0; +} // canRead + + +/** + * @brief Does the characteristic support writing? + * @return True if the characteristic supports writing. + */ +bool NimBLERemoteCharacteristic::canWrite() { + return (m_charProp & BLE_GATT_CHR_PROP_WRITE) != 0; +} // canWrite + + +/** + * @brief Does the characteristic support writing with no response? + * @return True if the characteristic supports writing with no response. + */ +bool NimBLERemoteCharacteristic::canWriteNoResponse() { + return (m_charProp & BLE_GATT_CHR_PROP_WRITE_NO_RSP) != 0; +} // canWriteNoResponse + + +/** + * @brief Callback used by the API when a descriptor is discovered or search complete. + */ +int NimBLERemoteCharacteristic::descriptorDiscCB(uint16_t conn_handle, + const struct ble_gatt_error *error, + uint16_t chr_val_handle, + const struct ble_gatt_dsc *dsc, + void *arg) +{ + NIMBLE_LOGD(LOG_TAG,"Descriptor Discovered >> status: %d handle: %d", + error->status, (error->status == 0) ? dsc->handle : -1); + + desc_filter_t *filter = (desc_filter_t*)arg; + const NimBLEUUID *uuid_filter = filter->uuid; + ble_task_data_t *pTaskData = (ble_task_data_t*)filter->task_data; + NimBLERemoteCharacteristic *characteristic = (NimBLERemoteCharacteristic*)pTaskData->pATT; + int rc=0; + + if(characteristic->getRemoteService()->getClient()->getConnId() != conn_handle){ + return 0; + } + + switch (error->status) { + case 0: { + if(dsc->uuid.u.type == BLE_UUID_TYPE_16 && dsc->uuid.u16.value == uint16_t(0x2803)) { + NIMBLE_LOGD(LOG_TAG,"Descriptor NOT found - end of Characteristic definintion"); + rc = BLE_HS_EDONE; + break; + } + if(uuid_filter != nullptr) { + if(ble_uuid_cmp(&uuid_filter->getNative()->u, &dsc->uuid.u) != 0) { + return 0; + } else { + NIMBLE_LOGD(LOG_TAG,"Descriptor Found"); + rc = BLE_HS_EDONE; + } + } + + NimBLERemoteDescriptor* pNewRemoteDescriptor = new NimBLERemoteDescriptor(characteristic, dsc); + characteristic->m_descriptorVector.push_back(pNewRemoteDescriptor); + break; + } + default: + rc = error->status; + break; + } + + /** If rc == BLE_HS_EDONE, resume the task with a success error code and stop the discovery process. + * Else if rc == 0, just return 0 to continue the discovery until we get BLE_HS_EDONE. + * If we get any other error code tell the application to abort by returning non-zero in the rc. + */ + if (rc == BLE_HS_EDONE) { + pTaskData->rc = 0; + xTaskNotifyGive(pTaskData->task); + } else if(rc != 0) { + // Error; abort discovery. + pTaskData->rc = rc; + xTaskNotifyGive(pTaskData->task); + } + + NIMBLE_LOGD(LOG_TAG,"<< Descriptor Discovered. status: %d", pTaskData->rc); + return rc; +} + + +/** + * @brief Populate the descriptors (if any) for this characteristic. + * @param [in] the end handle of the characteristic, or the service, whichever comes first. + */ +bool NimBLERemoteCharacteristic::retrieveDescriptors(const NimBLEUUID *uuid_filter) { + NIMBLE_LOGD(LOG_TAG, ">> retrieveDescriptors() for characteristic: %s", getUUID().toString().c_str()); + + int rc = 0; + ble_task_data_t taskData = {this, xTaskGetCurrentTaskHandle(), 0, nullptr}; + desc_filter_t filter = {uuid_filter, &taskData}; + + rc = ble_gattc_disc_all_dscs(getRemoteService()->getClient()->getConnId(), + m_handle, + getRemoteService()->getEndHandle(), + NimBLERemoteCharacteristic::descriptorDiscCB, + &filter); + if (rc != 0) { + NIMBLE_LOGE(LOG_TAG, "ble_gattc_disc_all_chrs: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc)); + return false; + } + + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + + if(taskData.rc != 0) { + return false; + } + + return true; + NIMBLE_LOGD(LOG_TAG, "<< retrieveDescriptors(): Found %d descriptors.", m_descriptorVector.size()); +} // getDescriptors + + +/** + * @brief Get the descriptor instance with the given UUID that belongs to this characteristic. + * @param [in] uuid The UUID of the descriptor to find. + * @return The Remote descriptor (if present) or null if not present. + */ +NimBLERemoteDescriptor* NimBLERemoteCharacteristic::getDescriptor(const NimBLEUUID &uuid) { + NIMBLE_LOGD(LOG_TAG, ">> getDescriptor: uuid: %s", uuid.toString().c_str()); + + for(auto &it: m_descriptorVector) { + if(it->getUUID() == uuid) { + NIMBLE_LOGD(LOG_TAG, "<< getDescriptor: found"); + return it; + } + } + + size_t prev_size = m_descriptorVector.size(); + if(retrieveDescriptors(&uuid)) { + if(m_descriptorVector.size() > prev_size) { + return m_descriptorVector.back(); + } + } + NIMBLE_LOGD(LOG_TAG, "<< getDescriptor: Not found"); + return nullptr; +} // getDescriptor + + +/** + * @Get a pointer to the vector of found descriptors. + * @param [in] bool value to indicate if the current vector should be cleared and + * subsequently all descriptors for this characteristic retrieved from the peripheral. + * If false the vector will be returned with the currently stored descriptors, + * if the vector is empty it will retrieve all descriptors for this characteristic + * from the peripheral. + * @return a pointer to the vector of descriptors for this characteristic. + */ +std::vector* NimBLERemoteCharacteristic::getDescriptors(bool refresh) { + if(refresh) { + deleteDescriptors(); + + if (!retrieveDescriptors()) { + NIMBLE_LOGE(LOG_TAG, "Error: Failed to get descriptors"); + } + else{ + NIMBLE_LOGI(LOG_TAG, "Found %d descriptor(s)", m_descriptorVector.size()); + } + } + return &m_descriptorVector; +} // getDescriptors + + +/** + * @brief Get iterator to the beginning of the vector of remote descriptor pointers. + * @return An iterator to the beginning of the vector of remote descriptor pointers. + */ +std::vector::iterator NimBLERemoteCharacteristic::begin() { + return m_descriptorVector.begin(); +} + + +/** + * @brief Get iterator to the end of the vector of remote descriptor pointers. + * @return An iterator to the end of the vector of remote descriptor pointers. + */ +std::vector::iterator NimBLERemoteCharacteristic::end() { + return m_descriptorVector.end(); +} + + +/** + * @brief Get the handle for this characteristic. + * @return The handle for this characteristic. + */ +uint16_t NimBLERemoteCharacteristic::getHandle() { + return m_handle; +} // getHandle + +/** + * @brief Get the handle for this characteristics definition. + * @return The handle for this characteristic definition. + */ +uint16_t NimBLERemoteCharacteristic::getDefHandle() { + return m_defHandle; +} // getDefHandle + + +/** + * @brief Get the remote service associated with this characteristic. + * @return The remote service associated with this characteristic. + */ +NimBLERemoteService* NimBLERemoteCharacteristic::getRemoteService() { + return m_pRemoteService; +} // getRemoteService + + +/** + * @brief Get the UUID for this characteristic. + * @return The UUID for this characteristic. + */ +NimBLEUUID NimBLERemoteCharacteristic::getUUID() { + return m_uuid; +} // getUUID + + +/** + * @brief Get the value of the remote characteristic. + * @return The value of the remote characteristic. + */ +std::string NimBLERemoteCharacteristic::getValue(time_t *timestamp) { + portENTER_CRITICAL(&m_valMux); + std::string value = m_value; + if(timestamp != nullptr) { + *timestamp = m_timestamp; + } + portEXIT_CRITICAL(&m_valMux); + + return value; +} + + +/** + * @brief Read an unsigned 16 bit value + * @return The unsigned 16 bit value. + */ +uint16_t NimBLERemoteCharacteristic::readUInt16() { + return readValue(); +} // readUInt16 + + +/** + * @brief Read an unsigned 32 bit value. + * @return the unsigned 32 bit value. + */ +uint32_t NimBLERemoteCharacteristic::readUInt32() { + return readValue(); +} // readUInt32 + + +/** + * @brief Read a byte value + * @return The value as a byte + */ +uint8_t NimBLERemoteCharacteristic::readUInt8() { + return readValue(); +} // readUInt8 + + +/** + * @brief Read a float value. + * @return the float value. + */ +float NimBLERemoteCharacteristic::readFloat() { + return readValue(); +} // readFloat + + +/** + * @brief Read the value of the remote characteristic. + * @return The value of the remote characteristic. + */ +std::string NimBLERemoteCharacteristic::readValue(time_t *timestamp) { + NIMBLE_LOGD(LOG_TAG, ">> readValue(): uuid: %s, handle: %d 0x%.2x", + getUUID().toString().c_str(), getHandle(), getHandle()); + + NimBLEClient* pClient = getRemoteService()->getClient(); + std::string value; + + if (!pClient->isConnected()) { + NIMBLE_LOGE(LOG_TAG, "Disconnected"); + return value; + } + + int rc = 0; + int retryCount = 1; + ble_task_data_t taskData = {this, xTaskGetCurrentTaskHandle(),0, &value}; + + do { + rc = ble_gattc_read_long(pClient->getConnId(), m_handle, 0, + NimBLERemoteCharacteristic::onReadCB, + &taskData); + if (rc != 0) { + NIMBLE_LOGE(LOG_TAG, "Error: Failed to read characteristic; rc=%d, %s", + rc, NimBLEUtils::returnCodeToString(rc)); + return value; + } + + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + rc = taskData.rc; + + switch(rc){ + case 0: + case BLE_HS_EDONE: + rc = 0; + break; + // Characteristic is not long-readable, return with what we have. + case BLE_HS_ATT_ERR(BLE_ATT_ERR_ATTR_NOT_LONG): + NIMBLE_LOGI(LOG_TAG, "Attribute not long"); + rc = 0; + break; + case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHEN): + case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHOR): + case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_ENC): + if (retryCount && pClient->secureConnection()) + break; + /* Else falls through. */ + default: + NIMBLE_LOGE(LOG_TAG, "<< readValue rc=%d", rc); + return value; + } + } while(rc != 0 && retryCount--); + + portENTER_CRITICAL(&m_valMux); + m_value = value; + m_timestamp = time(nullptr); + if(timestamp != nullptr) { + *timestamp = m_timestamp; + } + portEXIT_CRITICAL(&m_valMux); + + NIMBLE_LOGD(LOG_TAG, "<< readValue length: %d rc=%d", value.length(), rc); + return value; +} // readValue + + +/** + * @brief Callback for characteristic read operation. + * @return 0 or error code. + */ +int NimBLERemoteCharacteristic::onReadCB(uint16_t conn_handle, + const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, void *arg) +{ + ble_task_data_t *pTaskData = (ble_task_data_t*)arg; + NimBLERemoteCharacteristic *characteristic = (NimBLERemoteCharacteristic*)pTaskData->pATT; + uint16_t conn_id = characteristic->getRemoteService()->getClient()->getConnId(); + + if(conn_id != conn_handle) { + return 0; + } + + NIMBLE_LOGI(LOG_TAG, "Read complete; status=%d conn_handle=%d", error->status, conn_handle); + + std::string *strBuf = (std::string*)pTaskData->buf; + int rc = error->status; + + if(rc == 0) { + if(attr) { + if(((*strBuf).length() + attr->om->om_len) > BLE_ATT_ATTR_MAX_LEN) { + rc = BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } else { + NIMBLE_LOGD(LOG_TAG, "Got %d bytes", attr->om->om_len); + (*strBuf) += std::string((char*) attr->om->om_data, attr->om->om_len); + return 0; + } + } + } + + pTaskData->rc = rc; + xTaskNotifyGive(pTaskData->task); + + return rc; +} + + +/** + * @brief Subscribe or unsubscribe for notifications or indications. + * @param [in] uint16_t val 0x00 to unsubscribe, 0x01 for notifications, 0x02 for indications. + * @param [in] notifyCallback A callback to be invoked for a notification. If NULL is provided then no callback + * is performed for notifications. + * @return true if successful. + */ +bool NimBLERemoteCharacteristic::setNotify(uint16_t val, bool response, notify_callback notifyCallback) { + NIMBLE_LOGD(LOG_TAG, ">> setNotify(): %s, %02x", toString().c_str(), val); + + NimBLERemoteDescriptor* desc = getDescriptor(NimBLEUUID((uint16_t)0x2902)); + if(desc == nullptr) { + NIMBLE_LOGE(LOG_TAG, "<< setNotify(): Could not get descriptor"); + return false; + } + + m_notifyCallback = notifyCallback; + + NIMBLE_LOGD(LOG_TAG, "<< setNotify()"); + + return desc->writeValue((uint8_t *)&val, 2, response); +} // setNotify + + +/** + * @brief Subscribe for notifications or indications. + * @param [in] bool if true, subscribe for notifications, false subscribe for indications. + * @param [in] bool if true, require a write response from the descriptor write operation. + * @param [in] notifyCallback A callback to be invoked for a notification. If NULL is provided then no callback + * is performed for notifications. + * @return true if successful. + */ +bool NimBLERemoteCharacteristic::subscribe(bool notifications, bool response, notify_callback notifyCallback) { + if(notifications) { + return setNotify(0x01, response, notifyCallback); + } else { + return setNotify(0x02, response, notifyCallback); + } +} // subscribe + + +/** + * @brief Unsubscribe for notifications or indications. + * @param [in] bool if true, require a write response from the descriptor write operation. + * @return true if successful. + */ +bool NimBLERemoteCharacteristic::unsubscribe(bool response) { + return setNotify(0x00, response); +} // unsubscribe + + + /** + * @brief backward-compatibility method for subscribe/unsubscribe notifications/indications + * @param [in] notifyCallback A callback to be invoked for a notification. If NULL is provided then we are + * unregistering for notifications. + * @param [in] bool if true, register for notifications, false register for indications. + * @param [in] bool if true, require a write response from the descriptor write operation. + * @return true if successful. + */ +bool NimBLERemoteCharacteristic::registerForNotify(notify_callback notifyCallback, bool notifications, bool response) { + bool success; + if(notifyCallback != nullptr) { + success = subscribe(notifications, response, notifyCallback); + } else { + success = unsubscribe(response); + } + return success; +} // registerForNotify + + +/** + * @brief Delete the descriptors in the descriptor vector. + * We maintain a vector called m_descriptorVector that contains pointers to BLERemoteDescriptors + * object references. Since we allocated these in this class, we are also responsible for deleting + * them. This method does just that. + * @return N/A. + */ +void NimBLERemoteCharacteristic::deleteDescriptors() { + NIMBLE_LOGD(LOG_TAG, ">> deleteDescriptors"); + + for(auto &it: m_descriptorVector) { + delete it; + } + m_descriptorVector.clear(); + NIMBLE_LOGD(LOG_TAG, "<< deleteDescriptors"); +} // deleteDescriptors + + +/** + * @brief Delete descriptor by UUID + * @param [in] uuid The UUID of the descriptor to be deleted. + * @return Number of services left. + */ +size_t NimBLERemoteCharacteristic::deleteDescriptor(const NimBLEUUID &uuid) { + NIMBLE_LOGD(LOG_TAG, ">> deleteDescriptor"); + + for(auto it = m_descriptorVector.begin(); it != m_descriptorVector.end(); ++it) { + if((*it)->getUUID() == uuid) { + delete *it; + m_descriptorVector.erase(it); + break; + } + } + + NIMBLE_LOGD(LOG_TAG, "<< deleteDescriptor"); + + return m_descriptorVector.size(); +} // deleteDescriptor + + +/** + * @brief Convert a BLERemoteCharacteristic to a string representation; + * @return a String representation. + */ +std::string NimBLERemoteCharacteristic::toString() { + std::string res = "Characteristic: uuid: " + m_uuid.toString(); + char val[6]; + res += ", handle: "; + snprintf(val, sizeof(val), "%d", getHandle()); + res += val; + res += " 0x"; + snprintf(val, sizeof(val), "%04x", getHandle()); + res += val; + res += ", props: "; + res += " 0x"; + snprintf(val, sizeof(val), "%02x", m_charProp); + res += val; + + for(auto &it: m_descriptorVector) { + res += "\n" + it->toString(); + } + + return res; +} // toString + + +/** + * @brief Write the new value for the characteristic. + * @param [in] newValue The new value to write. + * @param [in] response Do we expect a response? + * @return false if not connected or cant perform write for some reason. + */ +bool NimBLERemoteCharacteristic::writeValue(const std::string &newValue, bool response) { + return writeValue((uint8_t*)newValue.c_str(), strlen(newValue.c_str()), response); +} // writeValue + + +/** + * @brief Write the new value for the characteristic from a data buffer. + * @param [in] data A pointer to a data buffer. + * @param [in] length The length of the data in the data buffer. + * @param [in] response Whether we require a response from the write. + * @return false if not connected or cant perform write for some reason. + */ +bool NimBLERemoteCharacteristic::writeValue(const uint8_t* data, size_t length, bool response) { + + NIMBLE_LOGD(LOG_TAG, ">> writeValue(), length: %d", length); + + NimBLEClient* pClient = getRemoteService()->getClient(); + + if (!pClient->isConnected()) { + NIMBLE_LOGE(LOG_TAG, "Disconnected"); + return false; + } + + int rc = 0; + int retryCount = 1; + uint16_t mtu = ble_att_mtu(pClient->getConnId()) - 3; + + // Check if the data length is longer than we can write in one connection event. + // If so we must do a long write which requires a response. + if(length <= mtu && !response) { + rc = ble_gattc_write_no_rsp_flat(pClient->getConnId(), m_handle, data, length); + return (rc==0); + } + + ble_task_data_t taskData = {this, xTaskGetCurrentTaskHandle(), 0, nullptr}; + + do { + if(length > mtu) { + NIMBLE_LOGI(LOG_TAG,"long write %d bytes", length); + os_mbuf *om = ble_hs_mbuf_from_flat(data, length); + rc = ble_gattc_write_long(pClient->getConnId(), m_handle, 0, om, + NimBLERemoteCharacteristic::onWriteCB, + &taskData); + } else { + rc = ble_gattc_write_flat(pClient->getConnId(), m_handle, + data, length, + NimBLERemoteCharacteristic::onWriteCB, + &taskData); + } + if (rc != 0) { + NIMBLE_LOGE(LOG_TAG, "Error: Failed to write characteristic; rc=%d", rc); + return false; + } + + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + rc = taskData.rc; + + switch(rc){ + case 0: + case BLE_HS_EDONE: + rc = 0; + break; + case BLE_HS_ATT_ERR(BLE_ATT_ERR_ATTR_NOT_LONG): + NIMBLE_LOGE(LOG_TAG, "Long write not supported by peer; Truncating length to %d", mtu); + retryCount++; + length = mtu; + break; + + case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHEN): + case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHOR): + case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_ENC): + if (retryCount && pClient->secureConnection()) + break; + /* Else falls through. */ + default: + NIMBLE_LOGE(LOG_TAG, "<< writeValue, rc: %d", rc); + return false; + } + } while(rc != 0 && retryCount--); + + NIMBLE_LOGD(LOG_TAG, "<< writeValue, rc: %d", rc); + return (rc == 0); +} // writeValue + + +/** + * @brief Callback for characteristic write operation. + * @return 0 or error code. + */ +int NimBLERemoteCharacteristic::onWriteCB(uint16_t conn_handle, + const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, void *arg) +{ + ble_task_data_t *pTaskData = (ble_task_data_t*)arg; + NimBLERemoteCharacteristic *characteristic = (NimBLERemoteCharacteristic*)pTaskData->pATT; + + if(characteristic->getRemoteService()->getClient()->getConnId() != conn_handle){ + return 0; + } + + NIMBLE_LOGI(LOG_TAG, "Write complete; status=%d conn_handle=%d", error->status, conn_handle); + + pTaskData->rc = error->status; + xTaskNotifyGive(pTaskData->task); + + return 0; +} + + +#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) +#endif /* CONFIG_BT_ENABLED */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLERemoteCharacteristic.h b/libesp32/NimBLE-Arduino/src/NimBLERemoteCharacteristic.h new file mode 100644 index 000000000..364efb59d --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLERemoteCharacteristic.h @@ -0,0 +1,145 @@ +/* + * NimBLERemoteCharacteristic.h + * + * Created: on Jan 27 2020 + * Author H2zero + * + * Originally: + * + * BLERemoteCharacteristic.h + * + * Created on: Jul 8, 2017 + * Author: kolban + */ + +#ifndef COMPONENTS_NIMBLEREMOTECHARACTERISTIC_H_ +#define COMPONENTS_NIMBLEREMOTECHARACTERISTIC_H_ +#include "sdkconfig.h" +#if defined(CONFIG_BT_ENABLED) + +#include "nimconfig.h" +#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) + +#include "NimBLERemoteService.h" +#include "NimBLERemoteDescriptor.h" + +#include + +class NimBLERemoteService; +class NimBLERemoteDescriptor; + + +typedef void (*notify_callback)(NimBLERemoteCharacteristic* pBLERemoteCharacteristic, + uint8_t* pData, size_t length, bool isNotify); + +typedef struct { + const NimBLEUUID *uuid; + void *task_data; +} desc_filter_t; + + +/** + * @brief A model of a remote %BLE characteristic. + */ +class NimBLERemoteCharacteristic { +public: + ~NimBLERemoteCharacteristic(); + + // Public member functions + bool canBroadcast(); + bool canIndicate(); + bool canNotify(); + bool canRead(); + bool canWrite(); + bool canWriteNoResponse(); + std::vector::iterator begin(); + std::vector::iterator end(); + NimBLERemoteDescriptor* getDescriptor(const NimBLEUUID &uuid); + std::vector* getDescriptors(bool refresh = false); + void deleteDescriptors(); + size_t deleteDescriptor(const NimBLEUUID &uuid); + uint16_t getHandle(); + uint16_t getDefHandle(); + NimBLEUUID getUUID(); + std::string readValue(time_t *timestamp = nullptr); + + template + T readValue(time_t *timestamp = nullptr, bool skipSizeCheck = false) { + std::string value = readValue(timestamp); + if(!skipSizeCheck && value.size() < sizeof(T)) return T(); + const char *pData = value.data(); + return *((T *)pData); + } + + uint8_t readUInt8() __attribute__ ((deprecated("Use template readValue()"))); + uint16_t readUInt16() __attribute__ ((deprecated("Use template readValue()"))); + uint32_t readUInt32() __attribute__ ((deprecated("Use template readValue()"))); + float readFloat() __attribute__ ((deprecated("Use template readValue()"))); + std::string getValue(time_t *timestamp = nullptr); + + template + T getValue(time_t *timestamp = nullptr, bool skipSizeCheck = false) { + std::string value = getValue(timestamp); + if(!skipSizeCheck && value.size() < sizeof(T)) return T(); + const char *pData = value.data(); + return *((T *)pData); + } + + bool subscribe(bool notifications = true, + bool response = true, + notify_callback notifyCallback = nullptr); + bool unsubscribe(bool response = true); + bool registerForNotify(notify_callback notifyCallback, + bool notifications = true, + bool response = true) + __attribute__ ((deprecated("Use subscribe()/unsubscribe()"))); + bool writeValue(const uint8_t* data, + size_t length, + bool response = false); + bool writeValue(const std::string &newValue, + bool response = false); + template + bool writeValue(const T &s, bool response = false) { + return writeValue((uint8_t*)&s, sizeof(T), response); + } + + std::string toString(); + NimBLERemoteService* getRemoteService(); + +private: + + NimBLERemoteCharacteristic(NimBLERemoteService *pRemoteservice, const struct ble_gatt_chr *chr); + + friend class NimBLEClient; + friend class NimBLERemoteService; + friend class NimBLERemoteDescriptor; + + // Private member functions + bool setNotify(uint16_t val, bool response = true, notify_callback notifyCallback = nullptr); + bool retrieveDescriptors(const NimBLEUUID *uuid_filter = nullptr); + static int onReadCB(uint16_t conn_handle, const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, void *arg); + static int onWriteCB(uint16_t conn_handle, const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, void *arg); + static int descriptorDiscCB(uint16_t conn_handle, const struct ble_gatt_error *error, + uint16_t chr_val_handle, const struct ble_gatt_dsc *dsc, + void *arg); + + // Private properties + NimBLEUUID m_uuid; + uint8_t m_charProp; + uint16_t m_handle; + uint16_t m_defHandle; + NimBLERemoteService* m_pRemoteService; + std::string m_value; + notify_callback m_notifyCallback; + time_t m_timestamp; + portMUX_TYPE m_valMux; + + // We maintain a vector of descriptors owned by this characteristic. + std::vector m_descriptorVector; +}; // NimBLERemoteCharacteristic + +#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) +#endif /* CONFIG_BT_ENABLED */ +#endif /* COMPONENTS_NIMBLEREMOTECHARACTERISTIC_H_ */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLERemoteDescriptor.cpp b/libesp32/NimBLE-Arduino/src/NimBLERemoteDescriptor.cpp new file mode 100644 index 000000000..d17ae6a0e --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLERemoteDescriptor.cpp @@ -0,0 +1,332 @@ +/* + * NimBLERemoteDescriptor.cpp + * + * Created: on Jan 27 2020 + * Author H2zero + * + * Originally: + * + * BLERemoteDescriptor.cpp + * + * Created on: Jul 8, 2017 + * Author: kolban + */ +#include "sdkconfig.h" +#if defined(CONFIG_BT_ENABLED) + +#include "nimconfig.h" +#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) + +#include "NimBLERemoteDescriptor.h" +#include "NimBLEUtils.h" +#include "NimBLELog.h" + +static const char* LOG_TAG = "NimBLERemoteDescriptor"; + +/** + * @brief Remote descriptor constructor. + * @param [in] Reference to the Characteristic that this belongs to. + * @param [in] Reference to the struct that contains the descriptor information. + */ +NimBLERemoteDescriptor::NimBLERemoteDescriptor(NimBLERemoteCharacteristic* pRemoteCharacteristic, + const struct ble_gatt_dsc *dsc) +{ + switch (dsc->uuid.u.type) { + case BLE_UUID_TYPE_16: + m_uuid = NimBLEUUID(dsc->uuid.u16.value); + break; + case BLE_UUID_TYPE_32: + m_uuid = NimBLEUUID(dsc->uuid.u32.value); + break; + case BLE_UUID_TYPE_128: + m_uuid = NimBLEUUID(const_cast(&dsc->uuid.u128)); + break; + default: + m_uuid = nullptr; + break; + } + + m_handle = dsc->handle; + m_pRemoteCharacteristic = pRemoteCharacteristic; +} + + +/** + * @brief Retrieve the handle associated with this remote descriptor. + * @return The handle associated with this remote descriptor. + */ +uint16_t NimBLERemoteDescriptor::getHandle() { + return m_handle; +} // getHandle + + +/** + * @brief Get the characteristic that owns this descriptor. + * @return The characteristic that owns this descriptor. + */ +NimBLERemoteCharacteristic* NimBLERemoteDescriptor::getRemoteCharacteristic() { + return m_pRemoteCharacteristic; +} // getRemoteCharacteristic + + +/** + * @brief Retrieve the UUID associated this remote descriptor. + * @return The UUID associated this remote descriptor. + */ +NimBLEUUID NimBLERemoteDescriptor::getUUID() { + return m_uuid; +} // getUUID + + +uint8_t NimBLERemoteDescriptor::readUInt8() { + std::string value = readValue(); + if (value.length() >= 1) { + return (uint8_t) value[0]; + } + return 0; +} // readUInt8 + + +uint16_t NimBLERemoteDescriptor::readUInt16() { + std::string value = readValue(); + if (value.length() >= 2) { + return *(uint16_t*) value.data(); + } + return 0; +} // readUInt16 + + +uint32_t NimBLERemoteDescriptor::readUInt32() { + std::string value = readValue(); + if (value.length() >= 4) { + return *(uint32_t*) value.data(); + } + return 0; +} // readUInt32 + + +std::string NimBLERemoteDescriptor::readValue() { + NIMBLE_LOGD(LOG_TAG, ">> Descriptor readValue: %s", toString().c_str()); + + NimBLEClient* pClient = getRemoteCharacteristic()->getRemoteService()->getClient(); + std::string value; + + if (!pClient->isConnected()) { + NIMBLE_LOGE(LOG_TAG, "Disconnected"); + return value; + } + + int rc = 0; + int retryCount = 1; + ble_task_data_t taskData = {this, xTaskGetCurrentTaskHandle(),0, &value}; + + do { + rc = ble_gattc_read_long(pClient->getConnId(), m_handle, 0, + NimBLERemoteDescriptor::onReadCB, + &taskData); + if (rc != 0) { + NIMBLE_LOGE(LOG_TAG, "Error: Failed to read descriptor; rc=%d, %s", + rc, NimBLEUtils::returnCodeToString(rc)); + return value; + } + + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + rc = taskData.rc; + + switch(rc){ + case 0: + case BLE_HS_EDONE: + rc = 0; + break; + // Descriptor is not long-readable, return with what we have. + case BLE_HS_ATT_ERR(BLE_ATT_ERR_ATTR_NOT_LONG): + NIMBLE_LOGI(LOG_TAG, "Attribute not long"); + rc = 0; + break; + case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHEN): + case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHOR): + case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_ENC): + if (retryCount && pClient->secureConnection()) + break; + /* Else falls through. */ + default: + return value; + } + } while(rc != 0 && retryCount--); + + NIMBLE_LOGD(LOG_TAG, "<< Descriptor readValue(): length: %d rc=%d", value.length(), rc); + return value; +} // readValue + + +/** + * @brief Callback for Descriptor read operation. + * @return 0 or error code. + */ +int NimBLERemoteDescriptor::onReadCB(uint16_t conn_handle, + const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, void *arg) +{ + ble_task_data_t *pTaskData = (ble_task_data_t*)arg; + NimBLERemoteDescriptor* desc = (NimBLERemoteDescriptor*)pTaskData->pATT; + uint16_t conn_id = desc->getRemoteCharacteristic()->getRemoteService()->getClient()->getConnId(); + + if(conn_id != conn_handle){ + return 0; + } + + NIMBLE_LOGD(LOG_TAG, "Read complete; status=%d conn_handle=%d", error->status, conn_handle); + + std::string *strBuf = (std::string*)pTaskData->buf; + int rc = error->status; + + if(rc == 0) { + if(attr) { + if(((*strBuf).length() + attr->om->om_len) > BLE_ATT_ATTR_MAX_LEN) { + rc = BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } else { + NIMBLE_LOGD(LOG_TAG, "Got %d bytes", attr->om->om_len); + (*strBuf) += std::string((char*) attr->om->om_data, attr->om->om_len); + return 0; + } + } + } + + pTaskData->rc = rc; + xTaskNotifyGive(pTaskData->task); + + return rc; +} + + +/** + * @brief Return a string representation of this BLE Remote Descriptor. + * @retun A string representation of this BLE Remote Descriptor. + */ +std::string NimBLERemoteDescriptor::toString() { + std::string res = "Descriptor: uuid: " + getUUID().toString(); + char val[6]; + res += ", handle: "; + snprintf(val, sizeof(val), "%d", getHandle()); + res += val; + + return res; +} // toString + + +/** + * @brief Callback for descriptor write operation. + * @return 0 or error code. + */ +int NimBLERemoteDescriptor::onWriteCB(uint16_t conn_handle, + const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, void *arg) +{ + ble_task_data_t *pTaskData = (ble_task_data_t*)arg; + NimBLERemoteDescriptor* descriptor = (NimBLERemoteDescriptor*)pTaskData->pATT; + + if(descriptor->getRemoteCharacteristic()->getRemoteService()->getClient()->getConnId() != conn_handle){ + return 0; + } + + NIMBLE_LOGI(LOG_TAG, "Write complete; status=%d conn_handle=%d", error->status, conn_handle); + + pTaskData->rc = error->status; + xTaskNotifyGive(pTaskData->task); + + return 0; +} + + +/** + * @brief Write data to the BLE Remote Descriptor. + * @param [in] data The data to send to the remote descriptor. + * @param [in] length The length of the data to send. + * @param [in] response True if we expect a response. + */ +bool NimBLERemoteDescriptor::writeValue(const uint8_t* data, size_t length, bool response) { + + NIMBLE_LOGD(LOG_TAG, ">> Descriptor writeValue: %s", toString().c_str()); + + NimBLEClient* pClient = getRemoteCharacteristic()->getRemoteService()->getClient(); + + // Check to see that we are connected. + if (!pClient->isConnected()) { + NIMBLE_LOGE(LOG_TAG, "Disconnected"); + return false; + } + + int rc = 0; + int retryCount = 1; + uint16_t mtu = ble_att_mtu(pClient->getConnId()) - 3; + + // Check if the data length is longer than we can write in 1 connection event. + // If so we must do a long write which requires a response. + if(length <= mtu && !response) { + rc = ble_gattc_write_no_rsp_flat(pClient->getConnId(), m_handle, data, length); + return (rc == 0); + } + + ble_task_data_t taskData = {this, xTaskGetCurrentTaskHandle(), 0, nullptr}; + + do { + if(length > mtu) { + NIMBLE_LOGI(LOG_TAG,"long write %d bytes", length); + os_mbuf *om = ble_hs_mbuf_from_flat(data, length); + rc = ble_gattc_write_long(pClient->getConnId(), m_handle, 0, om, + NimBLERemoteDescriptor::onWriteCB, + &taskData); + } else { + rc = ble_gattc_write_flat(pClient->getConnId(), m_handle, + data, length, + NimBLERemoteDescriptor::onWriteCB, + &taskData); + } + + if (rc != 0) { + NIMBLE_LOGE(LOG_TAG, "Error: Failed to write descriptor; rc=%d", rc); + return false; + } + + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + rc = taskData.rc; + + switch(rc) { + case 0: + case BLE_HS_EDONE: + rc = 0; + break; + case BLE_HS_ATT_ERR(BLE_ATT_ERR_ATTR_NOT_LONG): + NIMBLE_LOGE(LOG_TAG, "Long write not supported by peer; Truncating length to %d", mtu); + retryCount++; + length = mtu; + break; + + case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHEN): + case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHOR): + case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_ENC): + if (retryCount && pClient->secureConnection()) + break; + /* Else falls through. */ + default: + return false; + } + } while(rc != 0 && retryCount--); + + NIMBLE_LOGD(LOG_TAG, "<< Descriptor writeValue, rc: %d",rc); + return (rc == 0); +} // writeValue + + +/** + * @brief Write data represented as a string to the BLE Remote Descriptor. + * @param [in] newValue The data to send to the remote descriptor. + * @param [in] response True if we expect a response. + */ +bool NimBLERemoteDescriptor::writeValue(const std::string &newValue, bool response) { + return writeValue((uint8_t*) newValue.data(), newValue.length(), response); +} // writeValue + + +#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) +#endif /* CONFIG_BT_ENABLED */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLERemoteDescriptor.h b/libesp32/NimBLE-Arduino/src/NimBLERemoteDescriptor.h new file mode 100644 index 000000000..554e9dc16 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLERemoteDescriptor.h @@ -0,0 +1,72 @@ +/* + * NimBLERemoteDescriptor.h + * + * Created: on Jan 27 2020 + * Author H2zero + * + * Originally: + * + * BLERemoteDescriptor.h + * + * Created on: Jul 8, 2017 + * Author: kolban + */ + +#ifndef COMPONENTS_NIMBLEREMOTEDESCRIPTOR_H_ +#define COMPONENTS_NIMBLEREMOTEDESCRIPTOR_H_ +#include "sdkconfig.h" +#if defined(CONFIG_BT_ENABLED) + +#include "nimconfig.h" +#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) + +#include "NimBLERemoteCharacteristic.h" + +class NimBLERemoteCharacteristic; +/** + * @brief A model of remote %BLE descriptor. + */ +class NimBLERemoteDescriptor { +public: + uint16_t getHandle(); + NimBLERemoteCharacteristic* getRemoteCharacteristic(); + NimBLEUUID getUUID(); + std::string readValue(); + + template + T readValue(bool skipSizeCheck = false) { + std::string value = readValue(); + if(!skipSizeCheck && value.size() < sizeof(T)) return T(); + const char *pData = value.data(); + return *((T *)pData); + } + + uint8_t readUInt8() __attribute__ ((deprecated)); + uint16_t readUInt16() __attribute__ ((deprecated)); + uint32_t readUInt32() __attribute__ ((deprecated)); + std::string toString(void); + bool writeValue(const uint8_t* data, size_t length, bool response = false); + bool writeValue(const std::string &newValue, bool response = false); + template + bool writeValue(const T &s, bool response = false) { + return writeValue((uint8_t*)&s, sizeof(T), response); + } + +private: + friend class NimBLERemoteCharacteristic; + + NimBLERemoteDescriptor (NimBLERemoteCharacteristic* pRemoteCharacteristic, + const struct ble_gatt_dsc *dsc); + static int onWriteCB(uint16_t conn_handle, const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, void *arg); + static int onReadCB(uint16_t conn_handle, const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, void *arg); + + uint16_t m_handle; + NimBLEUUID m_uuid; + NimBLERemoteCharacteristic* m_pRemoteCharacteristic; +}; + +#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) +#endif /* CONFIG_BT_ENABLED */ +#endif /* COMPONENTS_NIMBLEREMOTEDESCRIPTOR_H_ */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLERemoteService.cpp b/libesp32/NimBLE-Arduino/src/NimBLERemoteService.cpp new file mode 100644 index 000000000..db9eabca1 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLERemoteService.cpp @@ -0,0 +1,368 @@ +/* + * NimBLERemoteService.cpp + * + * Created: on Jan 27 2020 + * Author H2zero + * + * Originally: + * + * BLERemoteService.cpp + * + * Created on: Jul 8, 2017 + * Author: kolban + */ +#include "sdkconfig.h" +#if defined(CONFIG_BT_ENABLED) + +#include "nimconfig.h" +#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) + +#include "NimBLERemoteService.h" +#include "NimBLEUtils.h" +#include "NimBLEDevice.h" +#include "NimBLELog.h" + +static const char* LOG_TAG = "NimBLERemoteService"; + +/** + * @brief Remote Service constructor. + * @param [in] Reference to the client this belongs to. + * @param [in] Refernce to the structure with the services' information. + */ +NimBLERemoteService::NimBLERemoteService(NimBLEClient* pClient, const struct ble_gatt_svc* service) { + + NIMBLE_LOGD(LOG_TAG, ">> NimBLERemoteService()"); + m_pClient = pClient; + switch (service->uuid.u.type) { + case BLE_UUID_TYPE_16: + m_uuid = NimBLEUUID(service->uuid.u16.value); + break; + case BLE_UUID_TYPE_32: + m_uuid = NimBLEUUID(service->uuid.u32.value); + break; + case BLE_UUID_TYPE_128: + m_uuid = NimBLEUUID(const_cast(&service->uuid.u128)); + break; + default: + m_uuid = nullptr; + break; + } + m_startHandle = service->start_handle; + m_endHandle = service->end_handle; + NIMBLE_LOGD(LOG_TAG, "<< NimBLERemoteService()"); +} + + +/** + * @brief When deleting the service make sure we delete all characteristics and descriptors. + * Also release any semaphores they may be holding. + */ +NimBLERemoteService::~NimBLERemoteService() { + deleteCharacteristics(); +} + + +/** + * @brief Get iterator to the beginning of the vector of remote characteristic pointers. + * @return An iterator to the beginning of the vector of remote characteristic pointers. + */ +std::vector::iterator NimBLERemoteService::begin() { + return m_characteristicVector.begin(); +} + + +/** + * @brief Get iterator to the end of the vector of remote characteristic pointers. + * @return An iterator to the end of the vector of remote characteristic pointers. + */ +std::vector::iterator NimBLERemoteService::end() { + return m_characteristicVector.end(); +} + + +/** + * @brief Get the remote characteristic object for the characteristic UUID. + * @param [in] uuid Remote characteristic uuid. + * @return Reference to the remote characteristic object. + */ +NimBLERemoteCharacteristic* NimBLERemoteService::getCharacteristic(const char* uuid) { + return getCharacteristic(NimBLEUUID(uuid)); +} // getCharacteristic + + +/** + * @brief Get the characteristic object for the UUID. + * @param [in] uuid Characteristic uuid. + * @return Reference to the characteristic object, or nullptr if not found. + */ +NimBLERemoteCharacteristic* NimBLERemoteService::getCharacteristic(const NimBLEUUID &uuid) { + for(auto &it: m_characteristicVector) { + if(it->getUUID() == uuid) { + return it; + } + } + + size_t prev_size = m_characteristicVector.size(); + if(retrieveCharacteristics(&uuid)) { + if(m_characteristicVector.size() > prev_size) { + return m_characteristicVector.back(); + } + } + + return nullptr; +} // getCharacteristic + + +/** + * @Get a pointer to the vector of found characteristics. + * @param [in] bool value to indicate if the current vector should be cleared and + * subsequently all characteristics for this service retrieved from the peripheral. + * If false the vector will be returned with the currently stored characteristics, + * If true it will retrieve all characteristics of this service from the peripheral + * and return the vector with all characteristics for this service. + * @return a pointer to the vector of descriptors for this characteristic. + */ + +std::vector* NimBLERemoteService::getCharacteristics(bool refresh) { + if(refresh) { + deleteCharacteristics(); + + if (!retrieveCharacteristics()) { + NIMBLE_LOGE(LOG_TAG, "Error: Failed to get characteristics"); + } + else{ + NIMBLE_LOGI(LOG_TAG, "Found %d characteristics", m_characteristicVector.size()); + } + } + return &m_characteristicVector; +} // getCharacteristics + + +/** + * @brief Callback for Characterisic discovery. + */ +int NimBLERemoteService::characteristicDiscCB(uint16_t conn_handle, + const struct ble_gatt_error *error, + const struct ble_gatt_chr *chr, void *arg) +{ + NIMBLE_LOGD(LOG_TAG,"Characteristic Discovered >> status: %d handle: %d", + error->status, (error->status == 0) ? chr->val_handle : -1); + + ble_task_data_t *pTaskData = (ble_task_data_t*)arg; + NimBLERemoteService *service = (NimBLERemoteService*)pTaskData->pATT; + + // Make sure the discovery is for this device + if(service->getClient()->getConnId() != conn_handle){ + return 0; + } + + if(error->status == 0) { + // Found a service - add it to the vector + NimBLERemoteCharacteristic* pRemoteCharacteristic = new NimBLERemoteCharacteristic(service, chr); + service->m_characteristicVector.push_back(pRemoteCharacteristic); + return 0; + } + + if(error->status == BLE_HS_EDONE) { + pTaskData->rc = 0; + } else { + NIMBLE_LOGE(LOG_TAG, "characteristicDiscCB() rc=%d %s", + error->status, + NimBLEUtils::returnCodeToString(error->status)); + pTaskData->rc = error->status; + } + + xTaskNotifyGive(pTaskData->task); + + NIMBLE_LOGD(LOG_TAG,"<< Characteristic Discovered"); + return error->status; +} + + +/** + * @brief Retrieve all the characteristics for this service. + * This function will not return until we have all the characteristics. + * @return N/A + */ +bool NimBLERemoteService::retrieveCharacteristics(const NimBLEUUID *uuid_filter) { + NIMBLE_LOGD(LOG_TAG, ">> retrieveCharacteristics() for service: %s", getUUID().toString().c_str()); + + int rc = 0; + ble_task_data_t taskData = {this, xTaskGetCurrentTaskHandle(), 0, nullptr}; + + if(uuid_filter == nullptr) { + rc = ble_gattc_disc_all_chrs(m_pClient->getConnId(), + m_startHandle, + m_endHandle, + NimBLERemoteService::characteristicDiscCB, + &taskData); + } else { + rc = ble_gattc_disc_chrs_by_uuid(m_pClient->getConnId(), + m_startHandle, + m_endHandle, + &uuid_filter->getNative()->u, + NimBLERemoteService::characteristicDiscCB, + &taskData); + } + + if (rc != 0) { + NIMBLE_LOGE(LOG_TAG, "ble_gattc_disc_all_chrs: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc)); + return false; + } + + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + + if(taskData.rc == 0){ + NIMBLE_LOGD(LOG_TAG, "<< retrieveCharacteristics()"); + return true; + } + + NIMBLE_LOGE(LOG_TAG, "Could not retrieve characteristics"); + return false; + +} // retrieveCharacteristics + + +/** + * @brief Get the client associated with this service. + * @return A reference to the client associated with this service. + */ +NimBLEClient* NimBLERemoteService::getClient() { + return m_pClient; +} // getClient + + +/** + * @brief Get the service end handle. + */ +uint16_t NimBLERemoteService::getEndHandle() { + return m_endHandle; +} // getEndHandle + + +/** + * @brief Get the service start handle. + */ +uint16_t NimBLERemoteService::getStartHandle() { + return m_startHandle; +} // getStartHandle + + +/** + * @brief Get the service UUID. + */ +NimBLEUUID NimBLERemoteService::getUUID() { + return m_uuid; +} + + +/** + * @brief Read the value of a characteristic associated with this service. + * @param [in] characteristicUuid The characteristic to read. + * @returns a string containing the value or an empty string if not found or error. + */ +std::string NimBLERemoteService::getValue(const NimBLEUUID &characteristicUuid) { + NIMBLE_LOGD(LOG_TAG, ">> readValue: uuid: %s", characteristicUuid.toString().c_str()); + + std::string ret = ""; + NimBLERemoteCharacteristic* pChar = getCharacteristic(characteristicUuid); + + if(pChar != nullptr) { + ret = pChar->readValue(); + } + + NIMBLE_LOGD(LOG_TAG, "<< readValue"); + return ret; +} // readValue + + +/** + * @brief Set the value of a characteristic. + * @param [in] characteristicUuid The characteristic to set. + * @param [in] value The value to set. + * @returns true on success, false if not found or error + */ +bool NimBLERemoteService::setValue(const NimBLEUUID &characteristicUuid, const std::string &value) { + NIMBLE_LOGD(LOG_TAG, ">> setValue: uuid: %s", characteristicUuid.toString().c_str()); + + bool ret = false; + NimBLERemoteCharacteristic* pChar = getCharacteristic(characteristicUuid); + + if(pChar != nullptr) { + ret = pChar->writeValue(value); + } + + NIMBLE_LOGD(LOG_TAG, "<< setValue"); + return ret; +} // setValue + + +/** + * @brief Delete the characteristics in the characteristics vector. + * We maintain a vector called m_characteristicsVector that contains pointers to BLERemoteCharacteristic + * object references. Since we allocated these in this class, we are also responsible for deleting + * them. This method does just that. + * @return N/A. + */ +void NimBLERemoteService::deleteCharacteristics() { + NIMBLE_LOGD(LOG_TAG, ">> deleteCharacteristics"); + for(auto &it: m_characteristicVector) { + delete it; + } + m_characteristicVector.clear(); + NIMBLE_LOGD(LOG_TAG, "<< deleteCharacteristics"); +} // deleteCharacteristics + + +/** + * @brief Delete characteristic by UUID + * @param [in] uuid The UUID of the characteristic to be cleared. + * @return Number of characteristics left. + */ +size_t NimBLERemoteService::deleteCharacteristic(const NimBLEUUID &uuid) { + NIMBLE_LOGD(LOG_TAG, ">> deleteCharacteristic"); + + for(auto it = m_characteristicVector.begin(); it != m_characteristicVector.end(); ++it) { + if((*it)->getUUID() == uuid) { + delete *it; + m_characteristicVector.erase(it); + break; + } + } + + NIMBLE_LOGD(LOG_TAG, "<< deleteCharacteristic"); + + return m_characteristicVector.size(); +} // deleteCharacteristic + + +/** + * @brief Create a string representation of this remote service. + * @return A string representation of this remote service. + */ +std::string NimBLERemoteService::toString() { + std::string res = "Service: uuid: " + m_uuid.toString(); + char val[6]; + res += ", start_handle: "; + snprintf(val, sizeof(val), "%d", m_startHandle); + res += val; + snprintf(val, sizeof(val), "%04x", m_startHandle); + res += " 0x"; + res += val; + res += ", end_handle: "; + snprintf(val, sizeof(val), "%d", m_endHandle); + res += val; + snprintf(val, sizeof(val), "%04x", m_endHandle); + res += " 0x"; + res += val; + + for (auto &it: m_characteristicVector) { + res += "\n" + it->toString(); + } + + return res; +} // toString + + +#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) +#endif /* CONFIG_BT_ENABLED */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLERemoteService.h b/libesp32/NimBLE-Arduino/src/NimBLERemoteService.h new file mode 100644 index 000000000..2d63c5d70 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLERemoteService.h @@ -0,0 +1,88 @@ +/* + * NimBLERemoteService.h + * + * Created: on Jan 27 2020 + * Author H2zero + * + * Originally: + * + * BLERemoteService.h + * + * Created on: Jul 8, 2017 + * Author: kolban + */ + +#ifndef COMPONENTS_NIMBLEREMOTESERVICE_H_ +#define COMPONENTS_NIMBLEREMOTESERVICE_H_ +#include "sdkconfig.h" +#if defined(CONFIG_BT_ENABLED) + +#include "nimconfig.h" +#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) + +#include "NimBLEClient.h" +#include "NimBLEUUID.h" +#include "NimBLERemoteCharacteristic.h" + +#include + +class NimBLEClient; +class NimBLERemoteCharacteristic; + + +/** + * @brief A model of a remote %BLE service. + */ +class NimBLERemoteService { +public: + virtual ~NimBLERemoteService(); + + // Public methods + std::vector::iterator begin(); + std::vector::iterator end(); + NimBLERemoteCharacteristic* getCharacteristic(const char* uuid); + NimBLERemoteCharacteristic* getCharacteristic(const NimBLEUUID &uuid); + void deleteCharacteristics(); + size_t deleteCharacteristic(const NimBLEUUID &uuid); + NimBLEClient* getClient(void); + uint16_t getHandle(); + NimBLEUUID getUUID(void); + std::string getValue(const NimBLEUUID &characteristicUuid); + bool setValue(const NimBLEUUID &characteristicUuid, + const std::string &value); + std::string toString(void); + std::vector* getCharacteristics(bool refresh = false); + +private: + // Private constructor ... never meant to be created by a user application. + NimBLERemoteService(NimBLEClient* pClient, const struct ble_gatt_svc *service); + + // Friends + friend class NimBLEClient; + friend class NimBLERemoteCharacteristic; + + // Private methods + bool retrieveCharacteristics(const NimBLEUUID *uuid_filter = nullptr); + static int characteristicDiscCB(uint16_t conn_handle, + const struct ble_gatt_error *error, + const struct ble_gatt_chr *chr, + void *arg); + + uint16_t getStartHandle(); + uint16_t getEndHandle(); + void releaseSemaphores(); + + // Properties + + // We maintain a vector of characteristics owned by this service. + std::vector m_characteristicVector; + + NimBLEClient* m_pClient; + NimBLEUUID m_uuid; + uint16_t m_startHandle; + uint16_t m_endHandle; +}; // NimBLERemoteService + +#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) +#endif /* CONFIG_BT_ENABLED */ +#endif /* COMPONENTS_NIMBLEREMOTESERVICE_H_ */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLEScan.cpp b/libesp32/NimBLE-Arduino/src/NimBLEScan.cpp new file mode 100644 index 000000000..dbf88741d --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLEScan.cpp @@ -0,0 +1,468 @@ +/* + * NimBLEScan.cpp + * + * Created: on Jan 24 2020 + * Author H2zero + * + * Originally: + * + * BLEScan.cpp + * + * Created on: Jul 1, 2017 + * Author: kolban + */ +#include "sdkconfig.h" +#if defined(CONFIG_BT_ENABLED) + +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) + +#include "NimBLEScan.h" +#include "NimBLEDevice.h" +#include "NimBLELog.h" + +#include + +static const char* LOG_TAG = "NimBLEScan"; + + +/** + * @brief Scan constuctor. + */ +NimBLEScan::NimBLEScan() { + m_own_addr_type = 0; + m_scan_params.filter_policy = BLE_HCI_SCAN_FILT_NO_WL; + m_scan_params.passive = 1; // If set, don’t send scan requests to advertisers (i.e., don’t request additional advertising data). + m_scan_params.itvl = 0; // This is defined as the time interval from when the Controller started its last LE scan until it begins the subsequent LE scan. (units=0.625 msec) + m_scan_params.window = 0; // The duration of the LE scan. LE_Scan_Window shall be less than or equal to LE_Scan_Interval (units=0.625 msec) + m_scan_params.limited = 0; // If set, only discover devices in limited discoverable mode. + m_scan_params.filter_duplicates = 0; // If set, the controller ignores all but the first advertisement from each device. + m_pAdvertisedDeviceCallbacks = nullptr; + m_stopped = true; + m_wantDuplicates = false; + m_pTaskData = nullptr; +} + + +/** + * @brief Handle GAP events related to scans. + * @param [in] event The event type for this event. + * @param [in] param Parameter data for this event. + */ +/*STATIC*/int NimBLEScan::handleGapEvent(ble_gap_event* event, void* arg) { + + NimBLEScan* pScan = (NimBLEScan*)arg; + struct ble_hs_adv_fields fields; + int rc = 0; + + switch(event->type) { + + case BLE_GAP_EVENT_DISC: { + if(pScan->m_stopped) { + NIMBLE_LOGE(LOG_TAG, "Scan stop called, ignoring results."); + return 0; + } + + rc = ble_hs_adv_parse_fields(&fields, event->disc.data, + event->disc.length_data); + if (rc != 0) { + NIMBLE_LOGE(LOG_TAG, "Gap Event Parse ERROR."); + return 0; + } + + NimBLEAddress advertisedAddress(event->disc.addr); + + // Examine our list of ignored addresses and stop processing if we don't want to see it or are already connected + if(NimBLEDevice::isIgnored(advertisedAddress)) { + NIMBLE_LOGI(LOG_TAG, "Ignoring device: address: %s", advertisedAddress.toString().c_str()); + return 0; + } + + NimBLEAdvertisedDevice* advertisedDevice = nullptr; + + // If we've seen this device before get a pointer to it from the vector + for(auto &it: pScan->m_scanResults.m_advertisedDevicesVector) { + if(it->getAddress() == advertisedAddress) { + advertisedDevice = it; + break; + } + } + + // If we haven't seen this device before; create a new instance and insert it in the vector. + // Otherwise just update the relevant parameters of the already known device. + if(advertisedDevice == nullptr){ + advertisedDevice = new NimBLEAdvertisedDevice(); + advertisedDevice->setAddressType(event->disc.addr.type); + advertisedDevice->setAddress(advertisedAddress); + advertisedDevice->setAdvType(event->disc.event_type); + pScan->m_scanResults.m_advertisedDevicesVector.push_back(advertisedDevice); + NIMBLE_LOGI(LOG_TAG, "NEW DEVICE FOUND: %s", advertisedAddress.toString().c_str()); + } + else{ + NIMBLE_LOGI(LOG_TAG, "UPDATING PREVIOUSLY FOUND DEVICE: %s", advertisedAddress.toString().c_str()); + } + advertisedDevice->setRSSI(event->disc.rssi); + advertisedDevice->parseAdvertisement(&fields); + advertisedDevice->setScan(pScan); + advertisedDevice->setAdvertisementResult(event->disc.data, event->disc.length_data); + advertisedDevice->m_timestamp = time(nullptr); + + if (pScan->m_pAdvertisedDeviceCallbacks) { + if(pScan->m_wantDuplicates || !advertisedDevice->m_callbackSent) { + // If not active scanning report the result to the listener. + if(pScan->m_scan_params.passive || event->disc.event_type == BLE_HCI_ADV_TYPE_ADV_NONCONN_IND) { + advertisedDevice->m_callbackSent = true; + pScan->m_pAdvertisedDeviceCallbacks->onResult(advertisedDevice); + + // Otherwise wait for the scan response so we can report all of the data at once. + } else if (event->disc.event_type == BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP) { + advertisedDevice->m_callbackSent = true; + pScan->m_pAdvertisedDeviceCallbacks->onResult(advertisedDevice); + } + } + } + + return 0; + } + case BLE_GAP_EVENT_DISC_COMPLETE: { + NIMBLE_LOGD(LOG_TAG, "discovery complete; reason=%d", + event->disc_complete.reason); + + if (pScan->m_scanCompleteCB != nullptr) { + pScan->m_scanCompleteCB(pScan->m_scanResults); + } + + pScan->m_stopped = true; + if(pScan->m_pTaskData != nullptr) { + pScan->m_pTaskData->rc = event->disc_complete.reason; + xTaskNotifyGive(pScan->m_pTaskData->task); + } + + return 0; + } + + default: + return 0; + } +} // gapEventHandler + + +/** + * @brief Should we perform an active or passive scan? + * The default is a passive scan. An active scan means that we will wish a scan response. + * @param [in] active If true, we perform an active scan otherwise a passive scan. + * @return N/A. + */ +void NimBLEScan::setActiveScan(bool active) { + if (active) { + m_scan_params.passive = 0; + } else { + m_scan_params.passive = 1; + } +} // setActiveScan + + +/** + * @brief Set whether or not the BLE controller should only report results + * from devices it has not already seen. + * @param [in] active If true, scanned devices will only be reported once. + * @details The controller has a limited buffer and will start reporting + * dupicate devices once the limit is reached. + */ +void NimBLEScan::setDuplicateFilter(bool active) { + m_scan_params.filter_duplicates = active; +} // setDuplicateFilter + + +/** + * @brief Set whether or not the BLE controller only report scan results + * from devices advertising in limited discovery mode, i.e. directed advertising. + * @param [in] active If true, only limited discovery devices will be in scan results. + */ +void NimBLEScan::setLimitedOnly(bool active) { + m_scan_params.limited = active; +} // setLimited + + +/** + * @brief Sets the scan filter policy. + * @param [in] filter Can be one of: + * BLE_HCI_SCAN_FILT_NO_WL (0) + * Scanner processes all advertising packets (white list not used) except + * directed, connectable advertising packets not sent to the scanner. + * BLE_HCI_SCAN_FILT_USE_WL (1) + * Scanner processes advertisements from white list only. A connectable, + * directed advertisment is ignored unless it contains scanners address. + * BLE_HCI_SCAN_FILT_NO_WL_INITA (2) + * Scanner process all advertising packets (white list not used). A + * connectable, directed advertisement shall not be ignored if the InitA + * is a resolvable private address. + * BLE_HCI_SCAN_FILT_USE_WL_INITA (3) + * Scanner process advertisements from white list only. A connectable, + * directed advertisement shall not be ignored if the InitA is a + * resolvable private address. + */ +void NimBLEScan::setFilterPolicy(uint8_t filter) { + m_scan_params.filter_policy = filter; +} // setFilterPolicy + + +/** + * @brief Set the call backs to be invoked. + * @param [in] pAdvertisedDeviceCallbacks Call backs to be invoked. + * @param [in] wantDuplicates True if we wish to be called back with duplicates. Default is false. + */ +void NimBLEScan::setAdvertisedDeviceCallbacks(NimBLEAdvertisedDeviceCallbacks* pAdvertisedDeviceCallbacks, + bool wantDuplicates) { + m_wantDuplicates = wantDuplicates; + m_pAdvertisedDeviceCallbacks = pAdvertisedDeviceCallbacks; +} // setAdvertisedDeviceCallbacks + + +/** + * @brief Set the interval to scan. + * @param [in] The interval in msecs. + */ +void NimBLEScan::setInterval(uint16_t intervalMSecs) { + m_scan_params.itvl = intervalMSecs / 0.625; +} // setInterval + + +/** + * @brief Set the window to actively scan. + * @param [in] windowMSecs How long to actively scan. + */ +void NimBLEScan::setWindow(uint16_t windowMSecs) { + m_scan_params.window = windowMSecs / 0.625; +} // setWindow + + +/** + * @brief Start scanning. + * @param [in] duration The duration in seconds for which to scan. + * @param [in] scanCompleteCB A function to be called when scanning has completed. + * @param [in] are we continue scan (true) or we want to clear stored devices (false) + * @return True if scan started or false if there was an error. + */ +bool NimBLEScan::start(uint32_t duration, void (*scanCompleteCB)(NimBLEScanResults), bool is_continue) { + NIMBLE_LOGD(LOG_TAG, ">> start(duration=%d)", duration); + + // If Host is not synced we cannot start scanning. + if(!NimBLEDevice::m_synced) { + NIMBLE_LOGC(LOG_TAG, "Host reset, wait for sync."); + return false; + } + + if(ble_gap_conn_active()) { + NIMBLE_LOGE(LOG_TAG, "Connection in progress - must wait."); + return false; + } + + // If we are already scanning don't start again or we will get stuck on the semaphore. + if(!m_stopped || ble_gap_disc_active()) { // double check - can cause host reset. + NIMBLE_LOGE(LOG_TAG, "Scan already in progress"); + return false; + } + + m_stopped = false; + + // Save the callback to be invoked when the scan completes. + m_scanCompleteCB = scanCompleteCB; + // Save the duration in the case that the host is reset so we can reuse it. + m_duration = duration; + + // If 0 duration specified then we assume a continuous scan is desired. + if(duration == 0){ + duration = BLE_HS_FOREVER; + } + else{ + duration = duration*1000; // convert duration to milliseconds + } + + // if we are connecting to devices that are advertising even after being connected, multiconnecting peripherals + // then we should not clear vector or we will connect the same device few times + if(!is_continue) { + clearResults(); + } + + int rc = 0; + do{ + rc = ble_gap_disc(m_own_addr_type, duration, &m_scan_params, + NimBLEScan::handleGapEvent, this); + if(rc == BLE_HS_EBUSY) { + vTaskDelay(1 / portTICK_PERIOD_MS); + } + } while(rc == BLE_HS_EBUSY); + + if (rc != 0 && rc != BLE_HS_EDONE) { + NIMBLE_LOGE(LOG_TAG, "Error initiating GAP discovery procedure; rc=%d, %s", + rc, NimBLEUtils::returnCodeToString(rc)); + m_stopped = true; + return false; + } + + NIMBLE_LOGD(LOG_TAG, "<< start()"); + return true; +} // start + + +/** + * @brief Start scanning and block until scanning has been completed. + * @param [in] duration The duration in seconds for which to scan. + * @return The BLEScanResults. + */ +NimBLEScanResults NimBLEScan::start(uint32_t duration, bool is_continue) { + if(duration == 0) { + NIMBLE_LOGW(LOG_TAG, "Blocking scan called with duration = forever"); + } + + ble_task_data_t taskData = {nullptr, xTaskGetCurrentTaskHandle(),0, nullptr}; + m_pTaskData = &taskData; + + if(start(duration, nullptr, is_continue)) { + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + } + + m_pTaskData = nullptr; + return m_scanResults; +} // start + + +/** + * @brief Stop an in progress scan. + * @return N/A. + */ +bool NimBLEScan::stop() { + NIMBLE_LOGD(LOG_TAG, ">> stop()"); + + int rc = ble_gap_disc_cancel(); + if (rc != 0 && rc != BLE_HS_EALREADY) { + NIMBLE_LOGE(LOG_TAG, "Failed to cancel scan; rc=%d\n", rc); + return false; + } + + m_stopped = true; + + if (m_scanCompleteCB != nullptr) { + m_scanCompleteCB(m_scanResults); + } + + if(m_pTaskData != nullptr) { + xTaskNotifyGive(m_pTaskData->task); + } + + NIMBLE_LOGD(LOG_TAG, "<< stop()"); + return true; +} // stop + + +// delete peer device from cache after disconnecting, it is required in case we are connecting to devices with not public address +void NimBLEScan::erase(const NimBLEAddress &address) { + NIMBLE_LOGI(LOG_TAG, "erase device: %s", address.toString().c_str()); + + for(auto it = m_scanResults.m_advertisedDevicesVector.begin(); it != m_scanResults.m_advertisedDevicesVector.end(); ++it) { + if((*it)->getAddress() == address) { + delete *it; + m_scanResults.m_advertisedDevicesVector.erase(it); + break; + } + } +} + + +/** + * @brief If the host reset the scan will have stopped so we should flag it and release the semaphore. + * @return N/A. + */ +void NimBLEScan::onHostReset() { + m_stopped = true; +} + + +/** + * @brief Get the results of the scan. + * @return NimBLEScanResults object. + */ +NimBLEScanResults NimBLEScan::getResults() { + return m_scanResults; +} + + +/** + * @brief Clear the results of the scan. + */ +void NimBLEScan::clearResults() { + for(auto &it: m_scanResults.m_advertisedDevicesVector) { + delete it; + } + m_scanResults.m_advertisedDevicesVector.clear(); +} + + +/** + * @brief Dump the scan results to the log. + */ +void NimBLEScanResults::dump() { + NIMBLE_LOGD(LOG_TAG, ">> Dump scan results:"); + for (int i=0; i::iterator NimBLEScanResults::begin() { + return m_advertisedDevicesVector.begin(); +} + + +/** + * @brief Get iterator to the end of the vector of advertised device pointers. + * @return An iterator to the end of the vector of advertised device pointers. + */ +std::vector::iterator NimBLEScanResults::end() { + return m_advertisedDevicesVector.end(); +} + + +/** + * @brief Return a pointer to the specified device at the given address. + * If the address is not found a nullptr is returned. + * @param [in] address The address of the device. + * @return A pointer to the device at the specified address. + */ +NimBLEAdvertisedDevice *NimBLEScanResults::getDevice(const NimBLEAddress &address) { + for(size_t index = 0; index < m_advertisedDevicesVector.size(); index++) { + if(m_advertisedDevicesVector[index]->getAddress() == address) { + return m_advertisedDevicesVector[index]; + } + } + + return nullptr; +} + +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) +#endif /* CONFIG_BT_ENABLED */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLEScan.h b/libesp32/NimBLE-Arduino/src/NimBLEScan.h new file mode 100644 index 000000000..5bc7bcf35 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLEScan.h @@ -0,0 +1,97 @@ +/* + * NimBLEScan.h + * + * Created: on Jan 24 2020 + * Author H2zero + * + * Originally: + * + * BLEScan.h + * + * Created on: Jul 1, 2017 + * Author: kolban + */ +#ifndef COMPONENTS_NIMBLE_SCAN_H_ +#define COMPONENTS_NIMBLE_SCAN_H_ +#include "sdkconfig.h" +#if defined(CONFIG_BT_ENABLED) + +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) + +#include "NimBLEAdvertisedDevice.h" +#include "NimBLEUtils.h" + +#include "host/ble_gap.h" + +#include + +class NimBLEDevice; +class NimBLEScan; +class NimBLEAdvertisedDevice; +class NimBLEAdvertisedDeviceCallbacks; +class NimBLEAddress; + +/** + * @brief The result of having performed a scan. + * When a scan completes, we have a set of found devices. Each device is described + * by a BLEAdvertisedDevice object. The number of items in the set is given by + * getCount(). We can retrieve a device by calling getDevice() passing in the + * index (starting at 0) of the desired device. + */ +class NimBLEScanResults { +public: + void dump(); + int getCount(); + NimBLEAdvertisedDevice getDevice(uint32_t i); + std::vector::iterator begin(); + std::vector::iterator end(); + NimBLEAdvertisedDevice *getDevice(const NimBLEAddress &address); + +private: + friend NimBLEScan; + std::vector m_advertisedDevicesVector; +}; + +/** + * @brief Perform and manage %BLE scans. + * + * Scanning is associated with a %BLE client that is attempting to locate BLE servers. + */ +class NimBLEScan { +public: + bool start(uint32_t duration, void (*scanCompleteCB)(NimBLEScanResults), bool is_continue = false); + NimBLEScanResults start(uint32_t duration, bool is_continue = false); + void setAdvertisedDeviceCallbacks(NimBLEAdvertisedDeviceCallbacks* pAdvertisedDeviceCallbacks, bool wantDuplicates = false); + void setActiveScan(bool active); + void setInterval(uint16_t intervalMSecs); + void setWindow(uint16_t windowMSecs); + void setDuplicateFilter(bool active); + void setLimitedOnly(bool active); + void setFilterPolicy(uint8_t filter); + bool stop(); + void clearResults(); + NimBLEScanResults getResults(); + void erase(const NimBLEAddress &address); + + +private: + NimBLEScan(); + friend class NimBLEDevice; + static int handleGapEvent(ble_gap_event* event, void* arg); + void onHostReset(); + + NimBLEAdvertisedDeviceCallbacks* m_pAdvertisedDeviceCallbacks = nullptr; + void (*m_scanCompleteCB)(NimBLEScanResults scanResults); + ble_gap_disc_params m_scan_params; + uint8_t m_own_addr_type; + bool m_stopped; + bool m_wantDuplicates; + NimBLEScanResults m_scanResults; + uint32_t m_duration; + ble_task_data_t *m_pTaskData; +}; + +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER) +#endif /* CONFIG_BT_ENABLED */ +#endif /* COMPONENTS_NIMBLE_SCAN_H_ */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLESecurity.cpp b/libesp32/NimBLE-Arduino/src/NimBLESecurity.cpp new file mode 100644 index 000000000..8a0dbd952 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLESecurity.cpp @@ -0,0 +1,138 @@ +/* + * NimBLESecurity.cpp + * + * Created: on Feb 22 2020 + * Author H2zero + * + * Originally: + * + * BLESecurity.cpp + * + * Created on: Dec 17, 2017 + * Author: chegewara + */ + +#include "sdkconfig.h" +#if defined(CONFIG_BT_ENABLED) + +#include "NimBLESecurity.h" +#include "NimBLEDevice.h" + +/** + * @brief This class is for backward compatibility with the bluedroid based library. + * Use the new security functions in NimBLEDevice instead. + * New callback functions in NimBLEServer and NimBLEClient. + */ + +NimBLESecurity::NimBLESecurity() { +} + +NimBLESecurity::~NimBLESecurity() { +} + + +/** + * @brief Set requested authentication mode + */ +void NimBLESecurity::setAuthenticationMode(esp_ble_auth_req_t auth_req) { + NimBLEDevice::setSecurityAuth((auth_req & BLE_SM_PAIR_AUTHREQ_BOND)>0, + (auth_req & BLE_SM_PAIR_AUTHREQ_MITM)>0, + (auth_req & BLE_SM_PAIR_AUTHREQ_SC)>0); +} + + +/** + * @brief Set our device IO capability to let end user perform authorization + * either by displaying or entering generated 6-digits pin code + */ +void NimBLESecurity::setCapability(esp_ble_io_cap_t iocap) { + NimBLEDevice::setSecurityIOCap(iocap); +} // setCapability + + +/** + * @brief Init encryption key by server + * @param key_size is value between 7 and 16 + */ +void NimBLESecurity::setInitEncryptionKey(uint8_t init_key) { + NimBLEDevice::setSecurityInitKey(init_key); +} // setInitEncryptionKey + + +/** + * @brief Init encryption key by client + * @param key_size is value between 7 and 16 + */ +void NimBLESecurity::setRespEncryptionKey(uint8_t resp_key) { + NimBLEDevice::setSecurityRespKey(resp_key); +} // setRespEncryptionKey + + +/** + *@todo Requires implementation + * + */ +void NimBLESecurity::setKeySize(uint8_t key_size) { + + //m_keySize = key_size; + //esp_ble_gap_set_security_param(ESP_BLE_SM_MAX_KEY_SIZE, &m_keySize, sizeof(uint8_t)); +} //setKeySize + + +/** + * Setup for static PIN connection. + */ +void NimBLESecurity::setStaticPIN(uint32_t pin){ + //uint32_t passkey = pin; + //esp_ble_gap_set_security_param(ESP_BLE_SM_SET_STATIC_PASSKEY, &passkey, sizeof(uint32_t)); + NimBLEDevice::setSecurityPasskey(pin); + setCapability(ESP_IO_CAP_OUT); + setKeySize(); + setAuthenticationMode(ESP_LE_AUTH_REQ_SC_ONLY); + setInitEncryptionKey(ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK); +} + + +/** + * @brief Debug function to display what keys are exchanged by peers + */ + /* +char* BLESecurity::esp_key_type_to_str(esp_ble_key_type_t key_type) { + char* key_str = nullptr; + switch (key_type) { + case ESP_LE_KEY_NONE: + key_str = (char*) "ESP_LE_KEY_NONE"; + break; + case ESP_LE_KEY_PENC: + key_str = (char*) "ESP_LE_KEY_PENC"; + break; + case ESP_LE_KEY_PID: + key_str = (char*) "ESP_LE_KEY_PID"; + break; + case ESP_LE_KEY_PCSRK: + key_str = (char*) "ESP_LE_KEY_PCSRK"; + break; + case ESP_LE_KEY_PLK: + key_str = (char*) "ESP_LE_KEY_PLK"; + break; + case ESP_LE_KEY_LLK: + key_str = (char*) "ESP_LE_KEY_LLK"; + break; + case ESP_LE_KEY_LENC: + key_str = (char*) "ESP_LE_KEY_LENC"; + break; + case ESP_LE_KEY_LID: + key_str = (char*) "ESP_LE_KEY_LID"; + break; + case ESP_LE_KEY_LCSRK: + key_str = (char*) "ESP_LE_KEY_LCSRK"; + break; + default: + key_str = (char*) "INVALID BLE KEY TYPE"; + break; + } + return key_str; + +} // esp_key_type_to_str +*/ +#endif // CONFIG_BT_ENABLED diff --git a/libesp32/NimBLE-Arduino/src/NimBLESecurity.h b/libesp32/NimBLE-Arduino/src/NimBLESecurity.h new file mode 100644 index 000000000..50c732c9b --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLESecurity.h @@ -0,0 +1,117 @@ +/* + * NimBLESecurity.h + * + * Created: on Feb 22 2020 + * Author H2zero + * + * Originally: + * + * BLESecurity.h + * + * Created on: Dec 17, 2017 + * Author: chegewara + */ + +/** This class exists for backward compatibility - Should not be used in new code + * See the security functions in NimBLEDevice and callbacks in NimBLEServer / NimBLEClient + */ + +#ifndef COMPONENTS_NIMBLESECURITY_H_ +#define COMPONENTS_NIMBLESECURITY_H_ +#include "sdkconfig.h" +#if defined(CONFIG_BT_ENABLED) + +#include "host/ble_gap.h" +/**** FIX COMPILATION ****/ +#undef min +#undef max +/**************************/ + +#include + +#define ESP_LE_AUTH_NO_BOND 0x00 /*!< 0*/ /* relate to BTM_LE_AUTH_NO_BOND in stack/btm_api.h */ +#define ESP_LE_AUTH_BOND 0x01 /*!< 1 << 0 */ /* relate to BTM_LE_AUTH_BOND in stack/btm_api.h */ +#define ESP_LE_AUTH_REQ_MITM (1 << 2) /*!< 1 << 2 */ /* relate to BTM_LE_AUTH_REQ_MITM in stack/btm_api.h */ +#define ESP_LE_AUTH_REQ_BOND_MITM (ESP_LE_AUTH_BOND | ESP_LE_AUTH_REQ_MITM)/*!< 0101*/ +#define ESP_LE_AUTH_REQ_SC_ONLY (1 << 3) /*!< 1 << 3 */ /* relate to BTM_LE_AUTH_REQ_SC_ONLY in stack/btm_api.h */ +#define ESP_LE_AUTH_REQ_SC_BOND (ESP_LE_AUTH_BOND | ESP_LE_AUTH_REQ_SC_ONLY) /*!< 1001 */ /* relate to BTM_LE_AUTH_REQ_SC_BOND in stack/btm_api.h */ +#define ESP_LE_AUTH_REQ_SC_MITM (ESP_LE_AUTH_REQ_MITM | ESP_LE_AUTH_REQ_SC_ONLY) /*!< 1100 */ /* relate to BTM_LE_AUTH_REQ_SC_MITM in stack/btm_api.h */ +#define ESP_LE_AUTH_REQ_SC_MITM_BOND (ESP_LE_AUTH_REQ_MITM | ESP_LE_AUTH_REQ_SC_ONLY | ESP_LE_AUTH_BOND) /*!< 1101 */ /* relate to BTM_LE_AUTH_REQ_SC_MITM_BOND in stack/btm_api.h */ + +#define ESP_IO_CAP_OUT 0 /*!< DisplayOnly */ /* relate to BTM_IO_CAP_OUT in stack/btm_api.h */ +#define ESP_IO_CAP_IO 1 /*!< DisplayYesNo */ /* relate to BTM_IO_CAP_IO in stack/btm_api.h */ +#define ESP_IO_CAP_IN 2 /*!< KeyboardOnly */ /* relate to BTM_IO_CAP_IN in stack/btm_api.h */ +#define ESP_IO_CAP_NONE 3 /*!< NoInputNoOutput */ /* relate to BTM_IO_CAP_NONE in stack/btm_api.h */ +#define ESP_IO_CAP_KBDISP 4 /*!< Keyboard display */ /* relate to BTM_IO_CAP_KBDISP in stack/btm_api.h */ + +/// Used to exchange the encryption key in the init key & response key +#define ESP_BLE_ENC_KEY_MASK (1 << 0) /* relate to BTM_BLE_ENC_KEY_MASK in stack/btm_api.h */ +/// Used to exchange the IRK key in the init key & response key +#define ESP_BLE_ID_KEY_MASK (1 << 1) /* relate to BTM_BLE_ID_KEY_MASK in stack/btm_api.h */ +/// Used to exchange the CSRK key in the init key & response key +#define ESP_BLE_CSR_KEY_MASK (1 << 2) /* relate to BTM_BLE_CSR_KEY_MASK in stack/btm_api.h */ +/// Used to exchange the link key(this key just used in the BLE & BR/EDR coexist mode) in the init key & response key +#define ESP_BLE_LINK_KEY_MASK (1 << 3) /* relate to BTM_BLE_LINK_KEY_MASK in stack/btm_api.h */ + +typedef uint8_t esp_ble_auth_req_t; /*!< combination of the above bit pattern */ +typedef uint8_t esp_ble_io_cap_t; /*!< combination of the io capability */ + +class NimBLESecurity { +public: + NimBLESecurity(); + virtual ~NimBLESecurity(); + void setAuthenticationMode(esp_ble_auth_req_t auth_req); + void setCapability(esp_ble_io_cap_t iocap); + void setInitEncryptionKey(uint8_t init_key); + void setRespEncryptionKey(uint8_t resp_key); + void setKeySize(uint8_t key_size = 16); + void setStaticPIN(uint32_t pin); + //static char* esp_key_type_to_str(esp_ble_key_type_t key_type); +/* +private: + esp_ble_auth_req_t m_authReq; + esp_ble_io_cap_t m_iocap; + uint8_t m_initKey; + uint8_t m_respKey; + uint8_t m_keySize; +*/ +}; // BLESecurity + + +/* + * @brief Callbacks to handle GAP events related to authorization + */ +class NimBLESecurityCallbacks { +public: + virtual ~NimBLESecurityCallbacks() {}; + + /** + * @brief Its request from peer device to input authentication pin code displayed on peer device. + * It requires that our device is capable to input 6-digits code by end user + * @return Return 6-digits integer value from input device + */ + virtual uint32_t onPassKeyRequest() = 0; + + /** + * @brief Provide us 6-digits code to perform authentication. + * It requires that our device is capable to display this code to end user + * @param + */ + virtual void onPassKeyNotify(uint32_t pass_key) = 0; + + /** + * @brief Here we can make decision if we want to let negotiate authorization with peer device or not + * return Return true if we accept this peer device request + */ + + virtual bool onSecurityRequest() = 0 ; + /** + * Provide us information when authentication process is completed + */ + virtual void onAuthenticationComplete(ble_gap_conn_desc*) = 0; + + virtual bool onConfirmPIN(uint32_t pin) = 0; +}; // BLESecurityCallbacks + +#endif // CONFIG_BT_ENABLED +#endif // COMPONENTS_NIMBLESECURITY_H_ diff --git a/libesp32/NimBLE-Arduino/src/NimBLEServer.cpp b/libesp32/NimBLE-Arduino/src/NimBLEServer.cpp new file mode 100644 index 000000000..376b02144 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLEServer.cpp @@ -0,0 +1,538 @@ +/* + * NimBLEServer.cpp + * + * Created: on March 2, 2020 + * Author H2zero + * + * Originally: + * + * BLEServer.cpp + * + * Created on: Apr 16, 2017 + * Author: kolban + */ + +#include "sdkconfig.h" +#if defined(CONFIG_BT_ENABLED) + +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + +#include "NimBLEServer.h" +#include "NimBLEDevice.h" +#include "NimBLELog.h" + +static const char* LOG_TAG = "NimBLEServer"; +static NimBLEServerCallbacks defaultCallbacks; + + +/** + * @brief Construct a %BLE Server + * + * This class is not designed to be individually instantiated. Instead one should create a server by asking + * the NimBLEDevice class. + */ +NimBLEServer::NimBLEServer() { +// m_svcChgChrHdl = 0xffff; // Future Use + m_pServerCallbacks = &defaultCallbacks; + m_gattsStarted = false; + m_advertiseOnDisconnect = true; +} // NimBLEServer + + +/** + * @brief Create a %BLE Service. + * @param [in] uuid The UUID of the new service. + * @return A reference to the new service object. + */ +NimBLEService* NimBLEServer::createService(const char* uuid) { + return createService(NimBLEUUID(uuid)); +} // createService + + +/** + * @brief Create a %BLE Service. + * @param [in] uuid The UUID of the new service. + * @param [in] numHandles The maximum number of handles associated with this service. + * @param [in] inst_id if we have multiple services with the same UUID we need + * to provide inst_id value different for each service. + * @return A reference to the new service object. + */ +NimBLEService* NimBLEServer::createService(const NimBLEUUID &uuid, uint32_t numHandles, uint8_t inst_id) { + NIMBLE_LOGD(LOG_TAG, ">> createService - %s", uuid.toString().c_str()); + // TODO: add functionality to use inst_id for multiple services with same uuid + (void)inst_id; + // Check that a service with the supplied UUID does not already exist. + if(getServiceByUUID(uuid) != nullptr) { + NIMBLE_LOGW(LOG_TAG, "Warning creating a duplicate service UUID: %s", + std::string(uuid).c_str()); + } + + NimBLEService* pService = new NimBLEService(uuid, numHandles, this); + m_svcVec.push_back(pService); // Save a reference to this service being on this server. + + NIMBLE_LOGD(LOG_TAG, "<< createService"); + return pService; +} // createService + + +/** + * @brief Get a %BLE Service by its UUID + * @param [in] uuid The UUID of the new service. + * @return A reference to the service object. + */ +NimBLEService* NimBLEServer::getServiceByUUID(const char* uuid) { + return getServiceByUUID(NimBLEUUID(uuid)); +} // getServiceByUUID + + +/** + * @brief Get a %BLE Service by its UUID + * @param [in] uuid The UUID of the new service. + * @return A reference to the service object. + */ +NimBLEService* NimBLEServer::getServiceByUUID(const NimBLEUUID &uuid) { + for (auto &it : m_svcVec) { + if (it->getUUID() == uuid) { + return it; + } + } + return nullptr; +} // getServiceByUUID + + +/** + * @brief Retrieve the advertising object that can be used to advertise the existence of the server. + * + * @return An advertising object. + */ +NimBLEAdvertising* NimBLEServer::getAdvertising() { + return NimBLEDevice::getAdvertising(); +} // getAdvertising + + +/** + * @brief Start the GATT server. Required to be called after setup of all + * services and characteristics / descriptors for the NimBLE host to register them. + */ +void NimBLEServer::start() { + if(m_gattsStarted) { + NIMBLE_LOGW(LOG_TAG, "Gatt server already started"); + return; + } + + int rc = ble_gatts_start(); + if (rc != 0) { + NIMBLE_LOGE(LOG_TAG, "ble_gatts_start; rc=%d, %s", rc, + NimBLEUtils::returnCodeToString(rc)); + abort(); + } + +#if CONFIG_LOG_DEFAULT_LEVEL > 3 || (ARDUINO_ARCH_ESP32 && CORE_DEBUG_LEVEL >= 4) + ble_gatts_show_local(); +#endif +/*** Future use *** + * TODO: implement service changed handling + + ble_uuid16_t svc = {BLE_UUID_TYPE_16, 0x1801}; + ble_uuid16_t chr = {BLE_UUID_TYPE_16, 0x2a05}; + + rc = ble_gatts_find_chr(&svc.u, &chr.u, NULL, &m_svcChgChrHdl); + if(rc != 0) { + NIMBLE_LOGE(LOG_TAG, "ble_gatts_find_chr: rc=%d, %s", rc, + NimBLEUtils::returnCodeToString(rc)); + abort(); + } + + NIMBLE_LOGI(LOG_TAG, "Service changed characterisic handle: %d", m_svcChgChrHdl); +*/ + // Build a vector of characteristics with Notify / Indicate capabilities for event handling + for(auto &svc : m_svcVec) { + for(auto &chr : svc->m_chrVec) { + // if Notify / Indicate is enabled but we didn't create the descriptor + // we do it now. + if((chr->m_properties & BLE_GATT_CHR_F_INDICATE) || + (chr->m_properties & BLE_GATT_CHR_F_NOTIFY)) { + + if(nullptr == chr->getDescriptorByUUID(uint16_t(0x2902))) { + chr->createDescriptor(uint16_t(0x2902)); + } + m_notifyChrVec.push_back(chr); + } + } + } + + m_gattsStarted = true; +} // start + + +/** + * @brief Disconnect the specified client with optional reason. + * @param [in] Connection Id of the client to disconnect. + * @param [in] Reason code for disconnecting. + * @return NimBLE host return code. + */ +int NimBLEServer::disconnect(uint16_t connId, uint8_t reason) { + NIMBLE_LOGD(LOG_TAG, ">> disconnect()"); + + int rc = ble_gap_terminate(connId, reason); + if(rc != 0){ + NIMBLE_LOGE(LOG_TAG, "ble_gap_terminate failed: rc=%d %s", rc, + NimBLEUtils::returnCodeToString(rc)); + } + + NIMBLE_LOGD(LOG_TAG, "<< disconnect()"); + return rc; +} // disconnect + + +/** + * @brief Set the server to automatically start advertising when a client disconnects. + * @param [in] bool true == advertise, false == don't advertise. + */ +void NimBLEServer::advertiseOnDisconnect(bool aod) { + m_advertiseOnDisconnect = aod; +} // advertiseOnDisconnect + + +/** + * @brief Return the number of connected clients. + * @return The number of connected clients. + */ +size_t NimBLEServer::getConnectedCount() { + return m_connectedPeersVec.size(); +} // getConnectedCount + + +/** + * @brief Handle a GATT Server Event. + * + * @param [in] event + * @param [in] gatts_if + * @param [in] param + * + */ +/*STATIC*/int NimBLEServer::handleGapEvent(struct ble_gap_event *event, void *arg) { + NimBLEServer* server = (NimBLEServer*)arg; + NIMBLE_LOGD(LOG_TAG, ">> handleGapEvent: %s", + NimBLEUtils::gapEventToString(event->type)); + int rc = 0; + struct ble_gap_conn_desc desc; + + switch(event->type) { + + case BLE_GAP_EVENT_CONNECT: { + if (event->connect.status != 0) { + /* Connection failed; resume advertising */ + NIMBLE_LOGE(LOG_TAG, "Connection failed"); + NimBLEDevice::startAdvertising(); + } + else { + server->m_connectedPeersVec.push_back(event->connect.conn_handle); + + rc = ble_gap_conn_find(event->connect.conn_handle, &desc); + assert(rc == 0); + + server->m_pServerCallbacks->onConnect(server); + server->m_pServerCallbacks->onConnect(server, &desc); + } + + return 0; + } // BLE_GAP_EVENT_CONNECT + + + case BLE_GAP_EVENT_DISCONNECT: { + // If Host reset tell the device now before returning to prevent + // any errors caused by calling host functions before resyncing. + switch(event->disconnect.reason) { + case BLE_HS_ETIMEOUT_HCI: + case BLE_HS_EOS: + case BLE_HS_ECONTROLLER: + case BLE_HS_ENOTSYNCED: + NIMBLE_LOGC(LOG_TAG, "Disconnect - host reset, rc=%d", event->disconnect.reason); + NimBLEDevice::onReset(event->disconnect.reason); + break; + default: + break; + } + + server->m_connectedPeersVec.erase(std::remove(server->m_connectedPeersVec.begin(), + server->m_connectedPeersVec.end(), + event->disconnect.conn.conn_handle), + server->m_connectedPeersVec.end()); + server->m_pServerCallbacks->onDisconnect(server); + + if(server->m_advertiseOnDisconnect) { + server->startAdvertising(); + } + return 0; + } // BLE_GAP_EVENT_DISCONNECT + + case BLE_GAP_EVENT_SUBSCRIBE: { + NIMBLE_LOGI(LOG_TAG, "subscribe event; cur_notify=%d\n value handle; " + "val_handle=%d\n", + event->subscribe.cur_notify, event->subscribe.attr_handle); + + for(auto &it : server->m_notifyChrVec) { + if(it->getHandle() == event->subscribe.attr_handle) { + if((it->getProperties() & BLE_GATT_CHR_F_READ_AUTHEN) || + (it->getProperties() & BLE_GATT_CHR_F_READ_AUTHOR) || + (it->getProperties() & BLE_GATT_CHR_F_READ_ENC)) + { + rc = ble_gap_conn_find(event->subscribe.conn_handle, &desc); + assert(rc == 0); + + if(!desc.sec_state.encrypted) { + NimBLEDevice::startSecurity(event->subscribe.conn_handle); + } + } + + it->setSubscribe(event); + break; + } + } + + return 0; + } // BLE_GAP_EVENT_SUBSCRIBE + + case BLE_GAP_EVENT_MTU: { + NIMBLE_LOGI(LOG_TAG, "mtu update event; conn_handle=%d mtu=%d", + event->mtu.conn_handle, + event->mtu.value); + return 0; + } // BLE_GAP_EVENT_MTU + + case BLE_GAP_EVENT_NOTIFY_TX: { + if(event->notify_tx.indication && event->notify_tx.status != 0) { + for(auto &it : server->m_notifyChrVec) { + if(it->getHandle() == event->notify_tx.attr_handle) { + if(it->m_pTaskData != nullptr) { + it->m_pTaskData->rc = event->notify_tx.status; + xTaskNotifyGive(it->m_pTaskData->task); + } + break; + } + } + } + + return 0; + } // BLE_GAP_EVENT_NOTIFY_TX + + case BLE_GAP_EVENT_CONN_UPDATE: { + NIMBLE_LOGD(LOG_TAG, "Connection parameters updated."); + return 0; + } // BLE_GAP_EVENT_CONN_UPDATE + + case BLE_GAP_EVENT_REPEAT_PAIRING: { + /* We already have a bond with the peer, but it is attempting to + * establish a new secure link. This app sacrifices security for + * convenience: just throw away the old bond and accept the new link. + */ + + /* Delete the old bond. */ + rc = ble_gap_conn_find(event->repeat_pairing.conn_handle, &desc); + assert(rc == 0); + ble_store_util_delete_peer(&desc.peer_id_addr); + + /* Return BLE_GAP_REPEAT_PAIRING_RETRY to indicate that the host should + * continue with the pairing operation. + */ + return BLE_GAP_REPEAT_PAIRING_RETRY; + } // BLE_GAP_EVENT_REPEAT_PAIRING + + case BLE_GAP_EVENT_ENC_CHANGE: { + rc = ble_gap_conn_find(event->enc_change.conn_handle, &desc); + if(rc != 0) { + return BLE_ATT_ERR_INVALID_HANDLE; + } + // Compatibility only - Do not use, should be removed the in future + if(NimBLEDevice::m_securityCallbacks != nullptr) { + NimBLEDevice::m_securityCallbacks->onAuthenticationComplete(&desc); + ///////////////////////////////////////////// + } else { + server->m_pServerCallbacks->onAuthenticationComplete(&desc); + } + + return 0; + } // BLE_GAP_EVENT_ENC_CHANGE + + case BLE_GAP_EVENT_PASSKEY_ACTION: { + struct ble_sm_io pkey = {0,0}; + + if (event->passkey.params.action == BLE_SM_IOACT_DISP) { + pkey.action = event->passkey.params.action; + // backward compatibility + pkey.passkey = NimBLEDevice::getSecurityPasskey(); // This is the passkey to be entered on peer + // if the (static)passkey is the default, check the callback for custom value + // both values default to the same. + if(pkey.passkey == 123456) { + pkey.passkey = server->m_pServerCallbacks->onPassKeyRequest(); + } + rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey); + NIMBLE_LOGD(LOG_TAG, "BLE_SM_IOACT_DISP; ble_sm_inject_io result: %d", rc); + + } else if (event->passkey.params.action == BLE_SM_IOACT_NUMCMP) { + NIMBLE_LOGD(LOG_TAG, "Passkey on device's display: %d", event->passkey.params.numcmp); + pkey.action = event->passkey.params.action; + // Compatibility only - Do not use, should be removed the in future + if(NimBLEDevice::m_securityCallbacks != nullptr) { + pkey.numcmp_accept = NimBLEDevice::m_securityCallbacks->onConfirmPIN(event->passkey.params.numcmp); + ///////////////////////////////////////////// + } else { + pkey.numcmp_accept = server->m_pServerCallbacks->onConfirmPIN(event->passkey.params.numcmp); + } + + rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey); + NIMBLE_LOGD(LOG_TAG, "BLE_SM_IOACT_NUMCMP; ble_sm_inject_io result: %d", rc); + + //TODO: Handle out of band pairing + } else if (event->passkey.params.action == BLE_SM_IOACT_OOB) { + static uint8_t tem_oob[16] = {0}; + pkey.action = event->passkey.params.action; + for (int i = 0; i < 16; i++) { + pkey.oob[i] = tem_oob[i]; + } + rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey); + NIMBLE_LOGD(LOG_TAG, "BLE_SM_IOACT_OOB; ble_sm_inject_io result: %d", rc); + ////////////////////////////////// + } else if (event->passkey.params.action == BLE_SM_IOACT_INPUT) { + NIMBLE_LOGD(LOG_TAG, "Enter the passkey"); + pkey.action = event->passkey.params.action; + + // Compatibility only - Do not use, should be removed the in future + if(NimBLEDevice::m_securityCallbacks != nullptr) { + pkey.passkey = NimBLEDevice::m_securityCallbacks->onPassKeyRequest(); + ///////////////////////////////////////////// + } else { + pkey.passkey = server->m_pServerCallbacks->onPassKeyRequest(); + } + + rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey); + NIMBLE_LOGD(LOG_TAG, "BLE_SM_IOACT_INPUT; ble_sm_inject_io result: %d", rc); + + } else if (event->passkey.params.action == BLE_SM_IOACT_NONE) { + NIMBLE_LOGD(LOG_TAG, "No passkey action required"); + } + + NIMBLE_LOGD(LOG_TAG, "<< handleGATTServerEvent"); + return 0; + } // BLE_GAP_EVENT_PASSKEY_ACTION + + default: + break; + } + + NIMBLE_LOGD(LOG_TAG, "<< handleGATTServerEvent"); + return 0; +} // handleGapEvent + + +/** + * @brief Set the server callbacks. + * + * As a %BLE server operates, it will generate server level events such as a new client connecting or a previous client + * disconnecting. This function can be called to register a callback handler that will be invoked when these + * events are detected. + * + * @param [in] pCallbacks The callbacks to be invoked. + */ +void NimBLEServer::setCallbacks(NimBLEServerCallbacks* pCallbacks) { + if (pCallbacks != nullptr){ + m_pServerCallbacks = pCallbacks; + } else { + m_pServerCallbacks = &defaultCallbacks; + } +} // setCallbacks + + +/** + * @brief Start advertising. + * + * Start the server advertising its existence. This is a convenience function and is equivalent to + * retrieving the advertising object and invoking start upon it. + */ +void NimBLEServer::startAdvertising() { + NimBLEDevice::startAdvertising(); +} // startAdvertising + + +/** + * @brief Stop advertising. + */ +void NimBLEServer::stopAdvertising() { + NimBLEDevice::stopAdvertising(); +} // startAdvertising + + +/** + * @brief Get the MTU of the client. + * @returns The client MTU or 0 if not found/connected. + */ +uint16_t NimBLEServer::getPeerMTU(uint16_t conn_id) { + return ble_att_mtu(conn_id); +} //getPeerMTU + + +/** + * Update connection parameters can be called only after connection has been established + */ +void NimBLEServer::updateConnParams(uint16_t conn_handle, + uint16_t minInterval, uint16_t maxInterval, + uint16_t latency, uint16_t timeout) +{ + ble_gap_upd_params params; + + params.latency = latency; + params.itvl_max = maxInterval; // max_int = 0x20*1.25ms = 40ms + params.itvl_min = minInterval; // min_int = 0x10*1.25ms = 20ms + params.supervision_timeout = timeout; // timeout = 400*10ms = 4000ms + params.min_ce_len = BLE_GAP_INITIAL_CONN_MIN_CE_LEN; // Minimum length of connection event in 0.625ms units + params.max_ce_len = BLE_GAP_INITIAL_CONN_MAX_CE_LEN; // Maximum length of connection event in 0.625ms units + + int rc = ble_gap_update_params(conn_handle, ¶ms); + if(rc != 0) { + NIMBLE_LOGE(LOG_TAG, "Update params error: %d, %s", rc, NimBLEUtils::returnCodeToString(rc)); + } +} // updateConnParams + + +/** Default callback handlers */ + +void NimBLEServerCallbacks::onConnect(NimBLEServer* pServer) { + NIMBLE_LOGD("NimBLEServerCallbacks", "onConnect(): Default"); +} // onConnect + + +void NimBLEServerCallbacks::onConnect(NimBLEServer* pServer, ble_gap_conn_desc* desc) { + NIMBLE_LOGD("NimBLEServerCallbacks", "onConnect(): Default"); +} // onConnect + + +void NimBLEServerCallbacks::onDisconnect(NimBLEServer* pServer) { + NIMBLE_LOGD("NimBLEServerCallbacks", "onDisconnect(): Default"); +} // onDisconnect + +uint32_t NimBLEServerCallbacks::onPassKeyRequest(){ + NIMBLE_LOGD("NimBLEServerCallbacks", "onPassKeyRequest: default: 123456"); + return 123456; +} + +void NimBLEServerCallbacks::onPassKeyNotify(uint32_t pass_key){ + NIMBLE_LOGD("NimBLEServerCallbacks", "onPassKeyNotify: default: %d", pass_key); +} + +bool NimBLEServerCallbacks::onSecurityRequest(){ + NIMBLE_LOGD("NimBLEServerCallbacks", "onSecurityRequest: default: true"); + return true; +} +void NimBLEServerCallbacks::onAuthenticationComplete(ble_gap_conn_desc*){ + NIMBLE_LOGD("NimBLEServerCallbacks", "onAuthenticationComplete: default"); +} +bool NimBLEServerCallbacks::onConfirmPIN(uint32_t pin){ + NIMBLE_LOGD("NimBLEServerCallbacks", "onConfirmPIN: default: true"); + return true; +} + + +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) +#endif // CONFIG_BT_ENABLED diff --git a/libesp32/NimBLE-Arduino/src/NimBLEServer.h b/libesp32/NimBLE-Arduino/src/NimBLEServer.h new file mode 100644 index 000000000..cfaa8acc7 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLEServer.h @@ -0,0 +1,114 @@ +/* + * NimBLEServer.h + * + * Created: on March 2, 2020 + * Author H2zero + * + * Originally: + * + * BLEServer.h + * + * Created on: Apr 16, 2017 + * Author: kolban + */ + +#ifndef MAIN_NIMBLESERVER_H_ +#define MAIN_NIMBLESERVER_H_ +#include "sdkconfig.h" +#if defined(CONFIG_BT_ENABLED) + +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + +#include "NimBLEUtils.h" +#include "NimBLEAddress.h" +#include "NimBLEAdvertising.h" +#include "NimBLEService.h" +#include "NimBLESecurity.h" + + +class NimBLEService; +class NimBLECharacteristic; +class NimBLEServerCallbacks; + + +/** + * @brief The model of a %BLE server. + */ +class NimBLEServer { +public: + size_t getConnectedCount(); + NimBLEService* createService(const char* uuid); + NimBLEService* createService(const NimBLEUUID &uuid, uint32_t numHandles=15, + uint8_t inst_id=0); + NimBLEAdvertising* getAdvertising(); + void setCallbacks(NimBLEServerCallbacks* pCallbacks); + void startAdvertising(); + void stopAdvertising(); + void start(); + NimBLEService* getServiceByUUID(const char* uuid); + NimBLEService* getServiceByUUID(const NimBLEUUID &uuid); + int disconnect(uint16_t connID, + uint8_t reason = BLE_ERR_REM_USER_CONN_TERM); + void updateConnParams(uint16_t conn_handle, + uint16_t minInterval, uint16_t maxInterval, + uint16_t latency, uint16_t timeout); + uint16_t getPeerMTU(uint16_t conn_id); + std::vector getPeerDevices(); + void advertiseOnDisconnect(bool); + +private: + NimBLEServer(); + friend class NimBLECharacteristic; + friend class NimBLEDevice; + friend class NimBLEAdvertising; + + bool m_gattsStarted; + bool m_advertiseOnDisconnect; + NimBLEServerCallbacks* m_pServerCallbacks; + std::vector m_connectedPeersVec; + +// uint16_t m_svcChgChrHdl; // Future use + + std::vector m_svcVec; + std::vector m_notifyChrVec; + + static int handleGapEvent(struct ble_gap_event *event, void *arg); +}; // NimBLEServer + + +/** + * @brief Callbacks associated with the operation of a %BLE server. + */ +class NimBLEServerCallbacks { +public: + virtual ~NimBLEServerCallbacks() {}; + /** + * @brief Handle a new client connection. + * + * When a new client connects, we are invoked. + * + * @param [in] pServer A reference to the %BLE server that received the client connection. + */ + virtual void onConnect(NimBLEServer* pServer); + virtual void onConnect(NimBLEServer* pServer, ble_gap_conn_desc* desc); + /** + * @brief Handle an existing client disconnection. + * + * When an existing client disconnects, we are invoked. + * + * @param [in] pServer A reference to the %BLE server that received the existing client disconnection. + */ + virtual void onDisconnect(NimBLEServer* pServer); + + virtual uint32_t onPassKeyRequest(); //{return 0;} + virtual void onPassKeyNotify(uint32_t pass_key); //{} + virtual bool onSecurityRequest(); //{return true;} + virtual void onAuthenticationComplete(ble_gap_conn_desc* desc);//{}; + virtual bool onConfirmPIN(uint32_t pin);//{return true;} +}; // NimBLEServerCallbacks + + +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) +#endif /* CONFIG_BT_ENABLED */ +#endif /* MAIN_NIMBLESERVER_H_ */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLEService.cpp b/libesp32/NimBLE-Arduino/src/NimBLEService.cpp new file mode 100644 index 000000000..c2631ab36 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLEService.cpp @@ -0,0 +1,283 @@ +/* + * NimBLEService.cpp + * + * Created: on March 2, 2020 + * Author H2zero + * + * Originally: + * + * BLEService.cpp + * + * Created on: Mar 25, 2017 + * Author: kolban + */ + +// A service is identified by a UUID. A service is also the container for one or more characteristics. + +#include "sdkconfig.h" +#if defined(CONFIG_BT_ENABLED) + +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + +#include "NimBLEService.h" +#include "NimBLEUtils.h" +#include "NimBLELog.h" + +#include + +static const char* LOG_TAG = "NimBLEService"; // Tag for logging. + +#define NULL_HANDLE (0xffff) + + +/** + * @brief Construct an instance of the NimBLEService + * @param [in] uuid The UUID of the service. + * @param [in] numHandles The maximum number of handles associated with the service. + * @param [in] a pointer to the server instance that this service belongs to. + */ +NimBLEService::NimBLEService(const char* uuid, uint16_t numHandles, NimBLEServer* pServer) +: NimBLEService(NimBLEUUID(uuid), numHandles, pServer) { +} + + +/** + * @brief Construct an instance of the BLEService + * @param [in] uuid The UUID of the service. + * @param [in] numHandles The maximum number of handles associated with the service. + * @param [in] a pointer to the server instance that this service belongs to. + */ +NimBLEService::NimBLEService(const NimBLEUUID &uuid, uint16_t numHandles, NimBLEServer* pServer) { + m_uuid = uuid; + m_handle = NULL_HANDLE; + m_pServer = pServer; + m_numHandles = numHandles; +} // NimBLEService + + +/** + * @brief Dump details of this BLE GATT service. + * @return N/A. + */ +void NimBLEService::dump() { + NIMBLE_LOGD(LOG_TAG, "Service: uuid:%s, handle: 0x%2x", + m_uuid.toString().c_str(), + m_handle); + + std::string res; + int count = 0; + char hex[5]; + for (auto &it: m_chrVec) { + if (count > 0) {res += "\n";} + snprintf(hex, sizeof(hex), "%04x", it->getHandle()); + count++; + res += "handle: 0x"; + res += hex; + res += ", uuid: " + std::string(it->getUUID()); + } + NIMBLE_LOGD(LOG_TAG, "Characteristics:\n%s", res.c_str()); +} // dump + + +/** + * @brief Get the UUID of the service. + * @return the UUID of the service. + */ +NimBLEUUID NimBLEService::getUUID() { + return m_uuid; +} // getUUID + + +/** + * @brief Builds the database of characteristics/descriptors for the service + * and registers it with the NimBLE stack. + * @return bool success/failure . + */ + +bool NimBLEService::start() { + NIMBLE_LOGD(LOG_TAG, ">> start(): Starting service: %s", toString().c_str()); + int rc = 0; + // Nimble requires an array of services to be sent to the api + // Since we are adding 1 at a time we create an array of 2 and set the type + // of the second service to 0 to indicate the end of the array. + ble_gatt_svc_def* svc = new ble_gatt_svc_def[2]; + ble_gatt_chr_def* pChr_a = nullptr; + ble_gatt_dsc_def* pDsc_a = nullptr; + + svc[0].type = BLE_GATT_SVC_TYPE_PRIMARY; + svc[0].uuid = &m_uuid.getNative()->u; + svc[0].includes = NULL; + + size_t numChrs = m_chrVec.size(); + + NIMBLE_LOGD(LOG_TAG,"Adding %d characteristics for service %s", numChrs, toString().c_str()); + + if(!numChrs){ + svc[0].characteristics = NULL; + }else{ + // Nimble requires the last characteristic to have it's uuid = 0 to indicate the end + // of the characteristics for the service. We create 1 extra and set it to null + // for this purpose. + pChr_a = new ble_gatt_chr_def[numChrs+1]; + NimBLECharacteristic* pCharacteristic = *m_chrVec.begin(); + + for(uint8_t i=0; i < numChrs;) { + uint8_t numDscs = pCharacteristic->m_dscVec.size(); + if(numDscs) { + // skip 2902 as it's automatically created by NimBLE + // if Indicate or Notify flags are set + if(((pCharacteristic->m_properties & BLE_GATT_CHR_F_INDICATE) || + (pCharacteristic->m_properties & BLE_GATT_CHR_F_NOTIFY)) && + pCharacteristic->getDescriptorByUUID("2902") != nullptr) + { + numDscs--; + } + } + + if(!numDscs){ + pChr_a[i].descriptors = NULL; + } else { + // Must have last descriptor uuid = 0 so we have to create 1 extra + //NIMBLE_LOGD(LOG_TAG, "Adding %d descriptors", numDscs); + pDsc_a = new ble_gatt_dsc_def[numDscs+1]; + NimBLEDescriptor* pDescriptor = *pCharacteristic->m_dscVec.begin(); + for(uint8_t d=0; d < numDscs;) { + // skip 2902 + if(pDescriptor->m_uuid == NimBLEUUID(uint16_t(0x2902))) { + //NIMBLE_LOGD(LOG_TAG, "Skipped 0x2902"); + pDescriptor = *(pCharacteristic->m_dscVec.begin()+d+1); + continue; + } + pDsc_a[d].uuid = &pDescriptor->m_uuid.getNative()->u; + pDsc_a[d].att_flags = pDescriptor->m_properties; + pDsc_a[d].min_key_size = 0; + pDsc_a[d].access_cb = NimBLEDescriptor::handleGapEvent; + pDsc_a[d].arg = pDescriptor; + d++; + pDescriptor = *(pCharacteristic->m_dscVec.begin() + d); + } + + pDsc_a[numDscs].uuid = NULL; + pChr_a[i].descriptors = pDsc_a; + } + + pChr_a[i].uuid = &pCharacteristic->m_uuid.getNative()->u; + pChr_a[i].access_cb = NimBLECharacteristic::handleGapEvent; + pChr_a[i].arg = pCharacteristic; + pChr_a[i].flags = pCharacteristic->m_properties; + pChr_a[i].min_key_size = 0; + pChr_a[i].val_handle = &pCharacteristic->m_handle; + i++; + pCharacteristic = *(m_chrVec.begin() + i); + } + + pChr_a[numChrs].uuid = NULL; + svc[0].characteristics = pChr_a; + } + + // end of services must indicate to api with type = 0 + svc[1].type = 0; + + rc = ble_gatts_count_cfg((const ble_gatt_svc_def*)svc); + if (rc != 0) { + NIMBLE_LOGE(LOG_TAG, "ble_gatts_count_cfg failed, rc= %d, %s", rc, NimBLEUtils::returnCodeToString(rc)); + return false; + } + + rc = ble_gatts_add_svcs((const ble_gatt_svc_def*)svc); + if (rc != 0) { + NIMBLE_LOGE(LOG_TAG, "ble_gatts_add_svcs, rc= %d, %s", rc, NimBLEUtils::returnCodeToString(rc)); + return false; + + } + + NIMBLE_LOGD(LOG_TAG, "<< start()"); + return true; +} // start + + +/** + * @brief Get the handle associated with this service. + * @return The handle associated with this service. + */ +uint16_t NimBLEService::getHandle() { + return m_handle; +} // getHandle + + +/** + * @brief Create a new BLE Characteristic associated with this service. + * @param [in] uuid - The UUID of the characteristic. + * @param [in] properties - The properties of the characteristic. + * @return The new BLE characteristic. + */ +NimBLECharacteristic* NimBLEService::createCharacteristic(const char* uuid, uint32_t properties) { + return createCharacteristic(NimBLEUUID(uuid), properties); +} + + +/** + * @brief Create a new BLE Characteristic associated with this service. + * @param [in] uuid - The UUID of the characteristic. + * @param [in] properties - The properties of the characteristic. + * @return The new BLE characteristic. + */ +NimBLECharacteristic* NimBLEService::createCharacteristic(const NimBLEUUID &uuid, uint32_t properties) { + NimBLECharacteristic* pCharacteristic = new NimBLECharacteristic(uuid, properties, this); + // Check that we don't add the same characteristic twice. + if (getCharacteristic(uuid) != nullptr) { + NIMBLE_LOGW(LOG_TAG, "<< Adding a duplicate characteristic with UUID: %s", + std::string(uuid).c_str()); + } + + // Remember this characteristic in our vector of characteristics. + m_chrVec.push_back(pCharacteristic); + + return pCharacteristic; +} // createCharacteristic + + +NimBLECharacteristic* NimBLEService::getCharacteristic(const char* uuid) { + return getCharacteristic(NimBLEUUID(uuid)); +} + + +NimBLECharacteristic* NimBLEService::getCharacteristic(const NimBLEUUID &uuid) { + for (auto &it : m_chrVec) { + if (it->getUUID() == uuid) { + return it; + } + } + + return nullptr; +} + + +/** + * @brief Return a string representation of this service. + * A service is defined by: + * * Its UUID + * * Its handle + * @return A string representation of this service. + */ +std::string NimBLEService::toString() { + std::string res = "UUID: " + getUUID().toString(); + char hex[5]; + snprintf(hex, sizeof(hex), "%04x", getHandle()); + res += ", handle: 0x"; + res += hex; + return res; +} // toString + + +/** + * @brief Get the BLE server associated with this service. + * @return The BLEServer associated with this service. + */ +NimBLEServer* NimBLEService::getServer() { + return m_pServer; +} // getServer + +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) +#endif // CONFIG_BT_ENABLED diff --git a/libesp32/NimBLE-Arduino/src/NimBLEService.h b/libesp32/NimBLE-Arduino/src/NimBLEService.h new file mode 100644 index 000000000..4c1fa2adf --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLEService.h @@ -0,0 +1,76 @@ +/* + * NimBLEService.h + * + * Created: on March 2, 2020 + * Author H2zero + * + * Originally: + * + * BLEService.h + * + * Created on: Mar 25, 2017 + * Author: kolban + */ + +#ifndef MAIN_NIMBLESERVICE_H_ +#define MAIN_NIMBLESERVICE_H_ +#include "sdkconfig.h" +#if defined(CONFIG_BT_ENABLED) + +#include "nimconfig.h" +#if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) + +#include "NimBLEServer.h" +#include "NimBLECharacteristic.h" +#include "NimBLEUUID.h" + + +class NimBLEServer; +class NimBLECharacteristic; + + +/** + * @brief The model of a %BLE service. + * + */ +class NimBLEService { +public: + NimBLECharacteristic* createCharacteristic(const char* uuid, + uint32_t properties = + NIMBLE_PROPERTY::READ | + NIMBLE_PROPERTY::WRITE); + + NimBLECharacteristic* createCharacteristic(const NimBLEUUID &uuid, + uint32_t properties = + NIMBLE_PROPERTY::READ | + NIMBLE_PROPERTY::WRITE); + + void dump(); + NimBLECharacteristic* getCharacteristic(const char* uuid); + NimBLECharacteristic* getCharacteristic(const NimBLEUUID &uuid); + NimBLEUUID getUUID(); + NimBLEServer* getServer(); + bool start(); + std::string toString(); + uint16_t getHandle(); + +private: + NimBLEService(const char* uuid, uint16_t numHandles, NimBLEServer* pServer); + NimBLEService(const NimBLEUUID &uuid, uint16_t numHandles, NimBLEServer* pServer); + + friend class NimBLEServer; + friend class NimBLEDevice; + + uint16_t m_handle; + NimBLEServer* m_pServer; + NimBLEUUID m_uuid; + uint16_t m_numHandles; + + std::vector m_chrVec; + +}; // NimBLEService + + +#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_PERIPHERAL) +#endif // CONFIG_BT_ENABLED +#endif /* MAIN_NIMBLESERVICE_H_ */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLEUUID.cpp b/libesp32/NimBLE-Arduino/src/NimBLEUUID.cpp new file mode 100644 index 000000000..4a9d7e876 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLEUUID.cpp @@ -0,0 +1,287 @@ +/* + * NimBLEUUID.cpp + * + * Created: on Jan 24 2020 + * Author H2zero + * + * Originally: + * + * BLEUUID.cpp + * + * Created on: Jun 21, 2017 + * Author: kolban + */ +#include "sdkconfig.h" +#if defined(CONFIG_BT_ENABLED) + +#include "NimBLEUtils.h" +#include "NimBLEUUID.h" +#include "NimBLELog.h" + +#include + +static const char* LOG_TAG = "NimBLEUUID"; + + +/** + * @brief Create a UUID from a string. + * + * Create a UUID from a string. There will be two possible stories here. Either the string represents + * a binary data field or the string represents a hex encoding of a UUID. + * For the hex encoding, here is an example: + * + * ``` + * "beb5483e-36e1-4688-b7f5-ea07361b26a8" + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + * 12345678-90ab-cdef-1234-567890abcdef + * ``` + * + * This has a length of 36 characters. We need to parse this into 16 bytes. + * + * @param [in] value The string to build a UUID from. + */ + NimBLEUUID::NimBLEUUID(const std::string &value) { + m_valueSet = true; + if (value.length() == 4) { + m_uuid.u.type = BLE_UUID_TYPE_16; + m_uuid.u16.value = strtoul(value.c_str(), NULL, 16); + } + else if (value.length() == 8) { + m_uuid.u.type = BLE_UUID_TYPE_32; + m_uuid.u32.value = strtoul(value.c_str(), NULL, 16); + } + else if (value.length() == 16) { + *this = NimBLEUUID((uint8_t*)value.data(), 16, true); + } + else if (value.length() == 36) { + // If the length of the string is 36 bytes then we will assume it is a long hex string in + // UUID format. + char * position = const_cast(value.c_str()); + uint32_t first = strtoul(position, &position, 16); + uint16_t second = strtoul(position + 1, &position, 16); + uint16_t third = strtoul(position + 1, &position, 16); + uint16_t fourth = strtoul(position + 1, &position, 16); + uint64_t fifth = strtoull(position + 1, NULL, 16); + *this = NimBLEUUID(first, second, third, (uint64_t(fourth) << 48) + fifth); + } + else { + NIMBLE_LOGE(LOG_TAG,"ERROR: UUID value not 2, 4, 16 or 36 bytes"); + m_valueSet = false; + } +} // NimBLEUUID(std::string) + + +/** + * @brief Create a UUID from 16 bytes of memory. + * + * @param [in] pData The pointer to the start of the UUID. + * @param [in] size The size of the data. + * @param [in] msbFirst Is the MSB first in pData memory? + */ +NimBLEUUID::NimBLEUUID(const uint8_t* pData, size_t size, bool msbFirst) { +/*** TODO: change this to use the Nimble function for various lenght UUIDs: + int ble_uuid_init_from_buf(ble_uuid_any_t *uuid, const void *buf, size_t len); +***/ + if (size != 16) { + NIMBLE_LOGE(LOG_TAG,"ERROR: UUID length not 16 bytes"); + return; + } + m_uuid.u.type = BLE_UUID_TYPE_128; + + if (msbFirst) { + std::reverse_copy(pData, pData + 16, m_uuid.u128.value); + } else { + memcpy(m_uuid.u128.value, pData, 16); + } + m_valueSet = true; +} // NimBLEUUID + + +/** + * @brief Create a UUID from the 16bit value. + * + * @param [in] uuid The 16bit short form UUID. + */ +NimBLEUUID::NimBLEUUID(uint16_t uuid) { + m_uuid.u.type = BLE_UUID_TYPE_16; + m_uuid.u16.value = uuid; + m_valueSet = true; +} // NimBLEUUID + + +/** + * @brief Create a UUID from the 32bit value. + * + * @param [in] uuid The 32bit short form UUID. + */ +NimBLEUUID::NimBLEUUID(uint32_t uuid) { + m_uuid.u.type = BLE_UUID_TYPE_32; + m_uuid.u32.value = uuid; + m_valueSet = true; +} // NimBLEUUID + + +/** + * @brief Create a UUID from the native UUID. + * + * @param [in] uuid The native UUID. + */ +NimBLEUUID::NimBLEUUID(const ble_uuid128_t* uuid) { + m_uuid.u.type = BLE_UUID_TYPE_128; + memcpy(m_uuid.u128.value, uuid->value, 16); + m_valueSet = true; +} // NimBLEUUID + + +/** + * @brief Create a UUID from the 128bit value using hex parts instead of string, + * instead of BLEUUID("ebe0ccb0-7a0a-4b0c-8a1a-6ff2997da3a6"), it becomes + * BLEUUID(0xebe0ccb0, 0x7a0a, 0x4b0c, 0x8a1a6ff2997da3a6) + * + * @param [in] first The first 32bit of the UUID. + * @param [in] second The next 16bit of the UUID. + * @param [in] third The next 16bit of the UUID. + * @param [in] fourth The last 64bit of the UUID, combining the last 2 parts of the string equivalent + */ +NimBLEUUID::NimBLEUUID(uint32_t first, uint16_t second, uint16_t third, uint64_t fourth) { + m_uuid.u.type = BLE_UUID_TYPE_128; + memcpy(m_uuid.u128.value + 12, &first, 4); + memcpy(m_uuid.u128.value + 10, &second, 2); + memcpy(m_uuid.u128.value + 8, &third, 2); + memcpy(m_uuid.u128.value, &fourth, 8); + m_valueSet = true; +} + + +NimBLEUUID::NimBLEUUID() { + m_valueSet = false; +} // NimBLEUUID + + +/** + * @brief Get the number of bits in this uuid. + * @return The number of bits in the UUID. One of 16, 32 or 128. + */ +uint8_t NimBLEUUID::bitSize() const { + if (!m_valueSet) return 0; + return m_uuid.u.type; +} // bitSize + + +/** + * @brief Compare a UUID against this UUID. + * + * @param [in] uuid The UUID to compare against. + * @return True if the UUIDs are equal and false otherwise. + */ +bool NimBLEUUID::equals(const NimBLEUUID &uuid) const { + return *this == uuid; +} + + +/** + * Create a BLEUUID from a string of the form: + * 0xNNNN + * 0xNNNNNNNN + * 0x + * NNNN + * NNNNNNNN + * + */ +NimBLEUUID NimBLEUUID::fromString(const std::string &_uuid) { + uint8_t start = 0; + if (strstr(_uuid.c_str(), "0x") != nullptr) { // If the string starts with 0x, skip those characters. + start = 2; + } + uint8_t len = _uuid.length() - start; // Calculate the length of the string we are going to use. + + if(len == 4) { + uint16_t x = strtoul(_uuid.substr(start, len).c_str(), NULL, 16); + return NimBLEUUID(x); + } else if (len == 8) { + uint32_t x = strtoul(_uuid.substr(start, len).c_str(), NULL, 16); + return NimBLEUUID(x); + } else if (len == 36) { + return NimBLEUUID(_uuid); + } + return NimBLEUUID(); +} // fromString + + +/** + * @brief Get the native UUID value. + * + * @return The native UUID value or NULL if not set. + */ +const ble_uuid_any_t* NimBLEUUID::getNative() const { + if (m_valueSet == false) { + NIMBLE_LOGD(LOG_TAG,"<< Return of un-initialized UUID!"); + return nullptr; + } + return &m_uuid; +} // getNative + + +/** + * @brief Convert a UUID to its 128 bit representation. + * + * A UUID can be internally represented as 16bit, 32bit or the full 128bit. This method + * will convert 16 or 32 bit representations to the full 128bit. + */ +const NimBLEUUID &NimBLEUUID::to128() { + // If we either don't have a value or are already a 128 bit UUID, nothing further to do. + if (!m_valueSet || m_uuid.u.type == BLE_UUID_TYPE_128) { + return *this; + } + + // If we are 16 bit or 32 bit, then set the other bytes of the UUID. + if (m_uuid.u.type == BLE_UUID_TYPE_16) { + *this = NimBLEUUID(m_uuid.u16.value, 0x0000, 0x1000, 0x800000805f9b34fb); + } + else if (m_uuid.u.type == BLE_UUID_TYPE_32) { + *this = NimBLEUUID(m_uuid.u32.value, 0x0000, 0x1000, 0x800000805f9b34fb); + } + + return *this; +} // to128 + + +/** + * @brief Get a string representation of the UUID. + * + * The format of a string is: + * 01234567 8901 2345 6789 012345678901 + * 0000180d-0000-1000-8000-00805f9b34fb + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + * + * @return A string representation of the UUID. + */ +std::string NimBLEUUID::toString() const { + return std::string(*this); +} // toString + + +bool NimBLEUUID::operator ==(const NimBLEUUID & rhs) const { + if(m_valueSet && rhs.m_valueSet) { + return ble_uuid_cmp(&m_uuid.u, &rhs.m_uuid.u) == 0; + } + + return m_valueSet == rhs.m_valueSet; +} + + +bool NimBLEUUID::operator !=(const NimBLEUUID & rhs) const { + return !this->operator==(rhs); +} + + +NimBLEUUID::operator std::string() const { + if (!m_valueSet) return std::string(); // If we have no value, nothing to format. + + char buf[BLE_UUID_STR_LEN]; + + return ble_uuid_to_str(&m_uuid.u, buf); +} + + +#endif /* CONFIG_BT_ENABLED */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLEUUID.h b/libesp32/NimBLE-Arduino/src/NimBLEUUID.h new file mode 100644 index 000000000..f07bb3df5 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLEUUID.h @@ -0,0 +1,56 @@ +/* + * NimBLEUUID.h + * + * Created: on Jan 24 2020 + * Author H2zero + * + * Originally: + * + * BLEUUID.h + * + * Created on: Jun 21, 2017 + * Author: kolban + */ + +#ifndef COMPONENTS_NIMBLEUUID_H_ +#define COMPONENTS_NIMBLEUUID_H_ +#include "sdkconfig.h" +#if defined(CONFIG_BT_ENABLED) + +#include "host/ble_uuid.h" +/**** FIX COMPILATION ****/ +#undef min +#undef max +/**************************/ + +#include + +/** + * @brief A model of a %BLE UUID. + */ +class NimBLEUUID { +public: + NimBLEUUID(const std::string &uuid); + NimBLEUUID(uint16_t uuid); + NimBLEUUID(uint32_t uuid); + NimBLEUUID(const ble_uuid128_t* uuid); + NimBLEUUID(const uint8_t* pData, size_t size, bool msbFirst); + NimBLEUUID(uint32_t first, uint16_t second, uint16_t third, uint64_t fourth); + NimBLEUUID(); + uint8_t bitSize() const; // Get the number of bits in this uuid. + bool equals(const NimBLEUUID &uuid) const; + const ble_uuid_any_t* getNative() const; + const NimBLEUUID & to128(); + std::string toString() const; + static NimBLEUUID fromString(const std::string &uuid); // Create a NimBLEUUID from a string + + bool operator ==(const NimBLEUUID & rhs) const; + bool operator !=(const NimBLEUUID & rhs) const; + operator std::string() const; + +private: + ble_uuid_any_t m_uuid; // The underlying UUID structure that this class wraps. + bool m_valueSet = false; // Is there a value set for this instance. +}; // NimBLEUUID +#endif /* CONFIG_BT_ENABLED */ +#endif /* COMPONENTS_NIMBLEUUID_H_ */ diff --git a/libesp32/NimBLE-Arduino/src/NimBLEUtils.cpp b/libesp32/NimBLE-Arduino/src/NimBLEUtils.cpp new file mode 100644 index 000000000..1f1f22c25 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLEUtils.cpp @@ -0,0 +1,690 @@ +/* + * NimBLEUtils.cpp + * + * Created: on Jan 25 2020 + * Author H2zero + * + */ + +#include "sdkconfig.h" +#if defined(CONFIG_BT_ENABLED) + +#include "NimBLEUtils.h" +#include "NimBLELog.h" +#include "nimconfig.h" + +static const char* LOG_TAG = "NimBLEUtils"; + + +int NimBLEUtils::checkConnParams(ble_gap_conn_params* params) { + /* Check connection interval min */ + if ((params->itvl_min < BLE_HCI_CONN_ITVL_MIN) || + (params->itvl_min > BLE_HCI_CONN_ITVL_MAX)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + /* Check connection interval max */ + if ((params->itvl_max < BLE_HCI_CONN_ITVL_MIN) || + (params->itvl_max > BLE_HCI_CONN_ITVL_MAX) || + (params->itvl_max < params->itvl_min)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + /* Check connection latency */ + if (params->latency > BLE_HCI_CONN_LATENCY_MAX) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + /* Check supervision timeout */ + if ((params->supervision_timeout < BLE_HCI_CONN_SPVN_TIMEOUT_MIN) || + (params->supervision_timeout > BLE_HCI_CONN_SPVN_TIMEOUT_MAX)) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + /* Check connection event length */ + if (params->min_ce_len > params->max_ce_len) { + return BLE_ERR_INV_HCI_CMD_PARMS; + } + + return 0; +} + + +const char* NimBLEUtils::returnCodeToString(int rc) { +#if defined(CONFIG_NIMBLE_CPP_ENABLE_RETURN_CODE_TEXT) + switch(rc) { + case 0: + return "SUCCESS"; + case BLE_HS_EAGAIN: + return "Temporary failure; try again."; + case BLE_HS_EALREADY: + return "Operation already in progress or completed."; + case BLE_HS_EINVAL: + return "One or more arguments are invalid."; + case BLE_HS_EMSGSIZE: + return "The provided buffer is too small."; + case BLE_HS_ENOENT: + return "No entry matching the specified criteria."; + case BLE_HS_ENOMEM: + return "Operation failed due to resource exhaustion."; + case BLE_HS_ENOTCONN: + return "No open connection with the specified handle."; + case BLE_HS_ENOTSUP: + return "Operation disabled at compile time."; + case BLE_HS_EAPP: + return "Application callback behaved unexpectedly."; + case BLE_HS_EBADDATA: + return "Command from peer is invalid."; + case BLE_HS_EOS: + return "Mynewt OS error."; + case BLE_HS_ECONTROLLER: + return "Event from controller is invalid."; + case BLE_HS_ETIMEOUT: + return "Operation timed out."; + case BLE_HS_EDONE: + return "Operation completed successfully."; + case BLE_HS_EBUSY: + return "Operation cannot be performed until procedure completes."; + case BLE_HS_EREJECT: + return "Peer rejected a connection parameter update request."; + case BLE_HS_EUNKNOWN: + return "Unexpected failure; catch all."; + case BLE_HS_EROLE: + return "Operation requires different role (e.g., central vs. peripheral)."; + case BLE_HS_ETIMEOUT_HCI: + return "HCI request timed out; controller unresponsive."; + case BLE_HS_ENOMEM_EVT: + return "Controller failed to send event due to memory exhaustion (combined host-controller only)."; + case BLE_HS_ENOADDR: + return "Operation requires an identity address but none configured."; + case BLE_HS_ENOTSYNCED: + return "Attempt to use the host before it is synced with controller."; + case BLE_HS_EAUTHEN: + return "Insufficient authentication."; + case BLE_HS_EAUTHOR: + return "Insufficient authorization."; + case BLE_HS_EENCRYPT: + return "Insufficient encryption level."; + case BLE_HS_EENCRYPT_KEY_SZ: + return "Insufficient key size."; + case BLE_HS_ESTORE_CAP: + return "Storage at capacity."; + case BLE_HS_ESTORE_FAIL: + return "Storage IO error."; + case (0x0100+BLE_ATT_ERR_INVALID_HANDLE ): + return "The attribute handle given was not valid on this server."; + case (0x0100+BLE_ATT_ERR_READ_NOT_PERMITTED ): + return "The attribute cannot be read."; + case (0x0100+BLE_ATT_ERR_WRITE_NOT_PERMITTED ): + return "The attribute cannot be written."; + case (0x0100+BLE_ATT_ERR_INVALID_PDU ): + return "The attribute PDU was invalid."; + case (0x0100+BLE_ATT_ERR_INSUFFICIENT_AUTHEN ): + return "The attribute requires authentication before it can be read or written."; + case (0x0100+BLE_ATT_ERR_REQ_NOT_SUPPORTED ): + return "Attribute server does not support the request received from the client."; + case (0x0100+BLE_ATT_ERR_INVALID_OFFSET ): + return "Offset specified was past the end of the attribute."; + case (0x0100+BLE_ATT_ERR_INSUFFICIENT_AUTHOR ): + return "The attribute requires authorization before it can be read or written."; + case (0x0100+BLE_ATT_ERR_PREPARE_QUEUE_FULL ): + return "Too many prepare writes have been queued."; + case (0x0100+BLE_ATT_ERR_ATTR_NOT_FOUND ): + return "No attribute found within the given attribute handle range."; + case (0x0100+BLE_ATT_ERR_ATTR_NOT_LONG ): + return "The attribute cannot be read or written using the Read Blob Request."; + case (0x0100+BLE_ATT_ERR_INSUFFICIENT_KEY_SZ ): + return "The Encryption Key Size used for encrypting this link is insufficient."; + case (0x0100+BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN ): + return "The attribute value length is invalid for the operation."; + case (0x0100+BLE_ATT_ERR_UNLIKELY ): + return "The attribute request has encountered an error that was unlikely, could not be completed as requested."; + case (0x0100+BLE_ATT_ERR_INSUFFICIENT_ENC ): + return "The attribute requires encryption before it can be read or written."; + case (0x0100+BLE_ATT_ERR_UNSUPPORTED_GROUP ): + return "The attribute type is not a supported grouping attribute as defined by a higher layer specification."; + case (0x0100+BLE_ATT_ERR_INSUFFICIENT_RES ): + return "Insufficient Resources to complete the request."; + case (0x0200+BLE_ERR_UNKNOWN_HCI_CMD ): + return "Unknown HCI Command"; + case (0x0200+BLE_ERR_UNK_CONN_ID ): + return "Unknown Connection Identifier"; + case (0x0200+BLE_ERR_HW_FAIL ): + return "Hardware Failure"; + case (0x0200+BLE_ERR_PAGE_TMO ): + return "Page Timeout"; + case (0x0200+BLE_ERR_AUTH_FAIL ): + return "Authentication Failure"; + case (0x0200+BLE_ERR_PINKEY_MISSING ): + return "PIN or Key Missing"; + case (0x0200+BLE_ERR_MEM_CAPACITY ): + return "Memory Capacity Exceeded"; + case (0x0200+BLE_ERR_CONN_SPVN_TMO ): + return "Connection Timeout"; + case (0x0200+BLE_ERR_CONN_LIMIT ): + return "Connection Limit Exceeded"; + case (0x0200+BLE_ERR_SYNCH_CONN_LIMIT ): + return "Synchronous Connection Limit To A Device Exceeded"; + case (0x0200+BLE_ERR_ACL_CONN_EXISTS ): + return "ACL Connection Already Exists"; + case (0x0200+BLE_ERR_CMD_DISALLOWED ): + return "Command Disallowed"; + case (0x0200+BLE_ERR_CONN_REJ_RESOURCES ): + return "Connection Rejected due to Limited Resources"; + case (0x0200+BLE_ERR_CONN_REJ_SECURITY ): + return "Connection Rejected Due To Security Reasons"; + case (0x0200+BLE_ERR_CONN_REJ_BD_ADDR ): + return "Connection Rejected due to Unacceptable BD_ADDR"; + case (0x0200+BLE_ERR_CONN_ACCEPT_TMO ): + return "Connection Accept Timeout Exceeded"; + case (0x0200+BLE_ERR_UNSUPPORTED ): + return "Unsupported Feature or Parameter Value"; + case (0x0200+BLE_ERR_INV_HCI_CMD_PARMS ): + return "Invalid HCI Command Parameters"; + case (0x0200+BLE_ERR_REM_USER_CONN_TERM ): + return "Remote User Terminated Connection"; + case (0x0200+BLE_ERR_RD_CONN_TERM_RESRCS ): + return "Remote Device Terminated Connection due to Low Resources"; + case (0x0200+BLE_ERR_RD_CONN_TERM_PWROFF ): + return "Remote Device Terminated Connection due to Power Off"; + case (0x0200+BLE_ERR_CONN_TERM_LOCAL ): + return "Connection Terminated By Local Host"; + case (0x0200+BLE_ERR_REPEATED_ATTEMPTS ): + return "Repeated Attempts"; + case (0x0200+BLE_ERR_NO_PAIRING ): + return "Pairing Not Allowed"; + case (0x0200+BLE_ERR_UNK_LMP ): + return "Unknown LMP PDU"; + case (0x0200+BLE_ERR_UNSUPP_REM_FEATURE ): + return "Unsupported Remote Feature / Unsupported LMP Feature"; + case (0x0200+BLE_ERR_SCO_OFFSET ): + return "SCO Offset Rejected"; + case (0x0200+BLE_ERR_SCO_ITVL ): + return "SCO Interval Rejected"; + case (0x0200+BLE_ERR_SCO_AIR_MODE ): + return "SCO Air Mode Rejected"; + case (0x0200+BLE_ERR_INV_LMP_LL_PARM ): + return "Invalid LMP Parameters / Invalid LL Parameters"; + case (0x0200+BLE_ERR_UNSPECIFIED ): + return "Unspecified Error"; + case (0x0200+BLE_ERR_UNSUPP_LMP_LL_PARM ): + return "Unsupported LMP Parameter Value / Unsupported LL Parameter Value"; + case (0x0200+BLE_ERR_NO_ROLE_CHANGE ): + return "Role Change Not Allowed"; + case (0x0200+BLE_ERR_LMP_LL_RSP_TMO ): + return "LMP Response Timeout / LL Response Timeout"; + case (0x0200+BLE_ERR_LMP_COLLISION ): + return "LMP Error Transaction Collision"; + case (0x0200+BLE_ERR_LMP_PDU ): + return "LMP PDU Not Allowed"; + case (0x0200+BLE_ERR_ENCRYPTION_MODE ): + return "Encryption Mode Not Acceptable"; + case (0x0200+BLE_ERR_LINK_KEY_CHANGE ): + return "Link Key cannot be Changed"; + case (0x0200+BLE_ERR_UNSUPP_QOS ): + return "Requested QoS Not Supported"; + case (0x0200+BLE_ERR_INSTANT_PASSED ): + return "Instant Passed"; + case (0x0200+BLE_ERR_UNIT_KEY_PAIRING ): + return "Pairing With Unit Key Not Supported"; + case (0x0200+BLE_ERR_DIFF_TRANS_COLL ): + return "Different Transaction Collision"; + case (0x0200+BLE_ERR_QOS_PARM ): + return "QoS Unacceptable Parameter"; + case (0x0200+BLE_ERR_QOS_REJECTED ): + return "QoS Rejected"; + case (0x0200+BLE_ERR_CHAN_CLASS ): + return "Channel Classification Not Supported"; + case (0x0200+BLE_ERR_INSUFFICIENT_SEC ): + return "Insufficient Security"; + case (0x0200+BLE_ERR_PARM_OUT_OF_RANGE ): + return "Parameter Out Of Mandatory Range"; + case (0x0200+BLE_ERR_PENDING_ROLE_SW ): + return "Role Switch Pending"; + case (0x0200+BLE_ERR_RESERVED_SLOT ): + return "Reserved Slot Violation"; + case (0x0200+BLE_ERR_ROLE_SW_FAIL ): + return "Role Switch Failed"; + case (0x0200+BLE_ERR_INQ_RSP_TOO_BIG ): + return "Extended Inquiry Response Too Large"; + case (0x0200+BLE_ERR_SEC_SIMPLE_PAIR ): + return "Secure Simple Pairing Not Supported By Host"; + case (0x0200+BLE_ERR_HOST_BUSY_PAIR ): + return "Host Busy - Pairing"; + case (0x0200+BLE_ERR_CONN_REJ_CHANNEL ): + return "Connection Rejected, No Suitable Channel Found"; + case (0x0200+BLE_ERR_CTLR_BUSY ): + return "Controller Busy"; + case (0x0200+BLE_ERR_CONN_PARMS ): + return "Unacceptable Connection Parameters"; + case (0x0200+BLE_ERR_DIR_ADV_TMO ): + return "Directed Advertising Timeout"; + case (0x0200+BLE_ERR_CONN_TERM_MIC ): + return "Connection Terminated due to MIC Failure"; + case (0x0200+BLE_ERR_CONN_ESTABLISHMENT ): + return "Connection Failed to be Established"; + case (0x0200+BLE_ERR_MAC_CONN_FAIL ): + return "MAC Connection Failed"; + case (0x0200+BLE_ERR_COARSE_CLK_ADJ ): + return "Coarse Clock Adjustment Rejected"; + case (0x0300+BLE_L2CAP_SIG_ERR_CMD_NOT_UNDERSTOOD ): + return "Invalid or unsupported incoming L2CAP sig command."; + case (0x0300+BLE_L2CAP_SIG_ERR_MTU_EXCEEDED ): + return "Incoming packet too large."; + case (0x0300+BLE_L2CAP_SIG_ERR_INVALID_CID ): + return "No channel with specified ID."; + case (0x0400+BLE_SM_ERR_PASSKEY ): + return "The user input of passkey failed, for example, the user cancelled the operation."; + case (0x0400+BLE_SM_ERR_OOB ): + return "The OOB data is not available."; + case (0x0400+BLE_SM_ERR_AUTHREQ ): + return "The pairing procedure cannot be performed as authentication requirements cannot be met due to IO capabilities of one or both devices."; + case (0x0400+BLE_SM_ERR_CONFIRM_MISMATCH ): + return "The confirm value does not match the calculated compare value."; + case (0x0400+BLE_SM_ERR_PAIR_NOT_SUPP ): + return "Pairing is not supported by the device."; + case (0x0400+BLE_SM_ERR_ENC_KEY_SZ ): + return "The resultant encryption key size is insufficient for the security requirements of this device."; + case (0x0400+BLE_SM_ERR_CMD_NOT_SUPP ): + return "The SMP command received is not supported on this device."; + case (0x0400+BLE_SM_ERR_UNSPECIFIED ): + return "Pairing failed due to an unspecified reason."; + case (0x0400+BLE_SM_ERR_REPEATED ): + return "Pairing or authentication procedure disallowed, too little time has elapsed since last pairing request or security request."; + case (0x0400+BLE_SM_ERR_INVAL ): + return "Command length is invalid or that a parameter is outside of the specified range."; + case (0x0400+BLE_SM_ERR_DHKEY ): + return "DHKey Check value received doesn't match the one calculated by the local device."; + case (0x0400+BLE_SM_ERR_NUMCMP ): + return "Confirm values in the numeric comparison protocol do not match."; + case (0x0400+BLE_SM_ERR_ALREADY ): + return "Pairing over the LE transport failed - Pairing Request sent over the BR/EDR transport in process."; + case (0x0400+BLE_SM_ERR_CROSS_TRANS ): + return "BR/EDR Link Key generated on the BR/EDR transport cannot be used to derive and distribute keys for the LE transport."; + case (0x0500+BLE_SM_ERR_PASSKEY ): + return "The user input of passkey failed or the user cancelled the operation."; + case (0x0500+BLE_SM_ERR_OOB ): + return "The OOB data is not available."; + case (0x0500+BLE_SM_ERR_AUTHREQ ): + return "The pairing procedure cannot be performed as authentication requirements cannot be met due to IO capabilities of one or both devices."; + case (0x0500+BLE_SM_ERR_CONFIRM_MISMATCH ): + return "The confirm value does not match the calculated compare value."; + case (0x0500+BLE_SM_ERR_PAIR_NOT_SUPP ): + return "Pairing is not supported by the device."; + case (0x0500+BLE_SM_ERR_ENC_KEY_SZ ): + return "The resultant encryption key size is insufficient for the security requirements of this device."; + case (0x0500+BLE_SM_ERR_CMD_NOT_SUPP ): + return "The SMP command received is not supported on this device."; + case (0x0500+BLE_SM_ERR_UNSPECIFIED ): + return "Pairing failed due to an unspecified reason."; + case (0x0500+BLE_SM_ERR_REPEATED ): + return "Pairing or authentication procedure is disallowed because too little time has elapsed since last pairing request or security request."; + case (0x0500+BLE_SM_ERR_INVAL ): + return "Command length is invalid or a parameter is outside of the specified range."; + case (0x0500+BLE_SM_ERR_DHKEY ): + return "Indicates to the remote device that the DHKey Check value received doesn’t match the one calculated by the local device."; + case (0x0500+BLE_SM_ERR_NUMCMP ): + return "Confirm values in the numeric comparison protocol do not match."; + case (0x0500+BLE_SM_ERR_ALREADY ): + return "Pairing over the LE transport failed - Pairing Request sent over the BR/EDR transport in process."; + case (0x0500+BLE_SM_ERR_CROSS_TRANS ): + return "BR/EDR Link Key generated on the BR/EDR transport cannot be used to derive and distribute keys for the LE transport."; + default: + return "Unknown"; + } +#else // #if defined(CONFIG_NIMBLE_CPP_ENABLE_RETURN_CODE_TEXT) + return ""; +#endif // #if defined(CONFIG_NIMBLE_CPP_ENABLE_RETURN_CODE_TEXT) +} + + +/** + * @brief Convert the BLE Advertising Data flags to a string. + * @param adFlags The flags to convert + * @return std::string A string representation of the advertising flags. + */ +const char* NimBLEUtils::advTypeToString(uint8_t advType) { +#if defined(CONFIG_NIMBLE_CPP_ENABLE_ADVERTISMENT_TYPE_TEXT) + switch(advType) { + case BLE_HCI_ADV_TYPE_ADV_IND : //0 + return "Undirected - Connectable / Scannable"; + case BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD: //1 + return "Directed High Duty - Connectable"; + case BLE_HCI_ADV_TYPE_ADV_SCAN_IND: //2 + return "Non-Connectable - Scan Response Available"; + case BLE_HCI_ADV_TYPE_ADV_NONCONN_IND: //3 + return "Non-Connectable - No Scan Response"; + case BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_LD: //4 + return "Directed Low Duty - Connectable"; + default: + return "Unknown flag"; + } +#else // #if defined(CONFIG_NIMBLE_CPP_ENABLE_ADVERTISMENT_TYPE_TEXT) + return ""; +#endif // #if defined(CONFIG_NIMBLE_CPP_ENABLE_ADVERTISMENT_TYPE_TEXT) +} // adFlagsToString + + +/** + * @brief Create a hex representation of data. + * + * @param [in] target Where to write the hex string. If this is null, we malloc storage. + * @param [in] source The start of the binary data. + * @param [in] length The length of the data to convert. + * @return A pointer to the formatted buffer. + */ +char* NimBLEUtils::buildHexData(uint8_t* target, const uint8_t* source, uint8_t length) { + // Guard against too much data. + if (length > 100) length = 100; + + if (target == nullptr) { + target = (uint8_t*) malloc(length * 2 + 1); + if (target == nullptr) { + NIMBLE_LOGE(LOG_TAG, "buildHexData: malloc failed"); + return nullptr; + } + } + char* startOfData = (char*) target; + + for (int i = 0; i < length; i++) { + sprintf((char*) target, "%.2x", (char) *source); + source++; + target += 2; + } + + // Handle the special case where there was no data. + if (length == 0) { + *startOfData = 0; + } + + return startOfData; +} // buildHexData + + +void NimBLEUtils::dumpGapEvent(ble_gap_event *event, void *arg){ +#if defined(CONFIG_NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT) + NIMBLE_LOGD(LOG_TAG, "Received a GAP event: %s", gapEventToString(event->type)); +#endif +} + + +/** + * @brief Convert a BT GAP event type to a string representation. + * @param [in] eventType The type of event. + * @return A string representation of the event type. + */ +const char* NimBLEUtils::gapEventToString(uint8_t eventType) { +#if defined(CONFIG_NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT) + switch (eventType) { + case BLE_GAP_EVENT_CONNECT : //0 + return "BLE_GAP_EVENT_CONNECT "; + + case BLE_GAP_EVENT_DISCONNECT: //1 + return "BLE_GAP_EVENT_DISCONNECT"; + + case BLE_GAP_EVENT_CONN_UPDATE: //3 + return "BLE_GAP_EVENT_CONN_UPDATE"; + + case BLE_GAP_EVENT_CONN_UPDATE_REQ: //4 + return "BLE_GAP_EVENT_CONN_UPDATE_REQ"; + + case BLE_GAP_EVENT_L2CAP_UPDATE_REQ: //5 + return "BLE_GAP_EVENT_L2CAP_UPDATE_REQ"; + + case BLE_GAP_EVENT_TERM_FAILURE: //6 + return "BLE_GAP_EVENT_TERM_FAILURE"; + + case BLE_GAP_EVENT_DISC: //7 + return "BLE_GAP_EVENT_DISC"; + + case BLE_GAP_EVENT_DISC_COMPLETE: //8 + return "BLE_GAP_EVENT_DISC_COMPLETE"; + + case BLE_GAP_EVENT_ADV_COMPLETE: //9 + return "BLE_GAP_EVENT_ADV_COMPLETE"; + + case BLE_GAP_EVENT_ENC_CHANGE: //10 + return "BLE_GAP_EVENT_ENC_CHANGE"; + + case BLE_GAP_EVENT_PASSKEY_ACTION : //11 + return "BLE_GAP_EVENT_PASSKEY_ACTION"; + + case BLE_GAP_EVENT_NOTIFY_RX: //12 + return "BLE_GAP_EVENT_NOTIFY_RX"; + + case BLE_GAP_EVENT_NOTIFY_TX : //13 + return "BLE_GAP_EVENT_NOTIFY_TX"; + + case BLE_GAP_EVENT_SUBSCRIBE : //14 + return "BLE_GAP_EVENT_SUBSCRIBE"; + + case BLE_GAP_EVENT_MTU: //15 + return "BLE_GAP_EVENT_MTU"; + + case BLE_GAP_EVENT_IDENTITY_RESOLVED: //16 + return "BLE_GAP_EVENT_IDENTITY_RESOLVED"; + + case BLE_GAP_EVENT_REPEAT_PAIRING: //17 + return "BLE_GAP_EVENT_REPEAT_PAIRING"; + + case BLE_GAP_EVENT_PHY_UPDATE_COMPLETE: //18 + return "BLE_GAP_EVENT_PHY_UPDATE_COMPLETE"; + + case BLE_GAP_EVENT_EXT_DISC: //19 + return "BLE_GAP_EVENT_EXT_DISC"; +#ifdef BLE_GAP_EVENT_PERIODIC_SYNC // IDF 4.0 does not support these + case BLE_GAP_EVENT_PERIODIC_SYNC: //20 + return "BLE_GAP_EVENT_PERIODIC_SYNC"; + + case BLE_GAP_EVENT_PERIODIC_REPORT: //21 + return "BLE_GAP_EVENT_PERIODIC_REPORT"; + + case BLE_GAP_EVENT_PERIODIC_SYNC_LOST: //22 + return "BLE_GAP_EVENT_PERIODIC_SYNC_LOST"; + + case BLE_GAP_EVENT_SCAN_REQ_RCVD: //23 + return "BLE_GAP_EVENT_SCAN_REQ_RCVD"; +#endif + default: + NIMBLE_LOGD(LOG_TAG, "gapEventToString: Unknown event type %d 0x%.2x", eventType, eventType); + return "Unknown event type"; + } +#else // #if defined(CONFIG_NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT) + return ""; +#endif // #if defined(CONFIG_NIMBLE_CPP_ENABLE_GAP_EVENT_CODE_TEXT) +} // gapEventToString + + +/** + * Utility function to log an array of bytes. + */ +void print_bytes(const uint8_t *bytes, int len) +{ + int i; + + for (i = 0; i < len; i++) { + MODLOG_DFLT(ERROR, "%s0x%02x", i != 0 ? ":" : "", bytes[i]); + if(i % 30 == 0){ + MODLOG_DFLT(ERROR, "\n"); + } + } + + MODLOG_DFLT(ERROR, "\n"); +} + +void print_mbuf(const struct os_mbuf *om) +{ + int colon; + + colon = 0; + while (om != NULL) { + if (colon) { + MODLOG_DFLT(DEBUG, ":"); + } else { + colon = 1; + } + print_bytes(om->om_data, om->om_len); + om = SLIST_NEXT(om, om_next); + } +} + +char *addr_str(const void *addr) +{ + static char buf[6 * 2 + 5 + 1]; + const uint8_t *u8p; + + u8p = (const uint8_t*)addr; + sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", + u8p[5], u8p[4], u8p[3], u8p[2], u8p[1], u8p[0]); + + return buf; +} + +void print_uuid(const ble_uuid_t *uuid) +{ + char buf[BLE_UUID_STR_LEN]; + + MODLOG_DFLT(DEBUG, "%s", ble_uuid_to_str(uuid, buf)); +} + +void print_adv_fields(const struct ble_hs_adv_fields *fields) +{ + char s[BLE_HS_ADV_MAX_SZ]; + const uint8_t *u8p; + int i; + + if (fields->flags != 0) { + MODLOG_DFLT(DEBUG, " flags=0x%02x\n", fields->flags); + } + + if (fields->uuids16 != NULL) { + MODLOG_DFLT(DEBUG, " uuids16(%scomplete)=", + fields->uuids16_is_complete ? "" : "in"); + for (i = 0; i < fields->num_uuids16; i++) { + print_uuid(&fields->uuids16[i].u); + MODLOG_DFLT(DEBUG, " "); + } + MODLOG_DFLT(DEBUG, "\n"); + } + + if (fields->uuids32 != NULL) { + MODLOG_DFLT(DEBUG, " uuids32(%scomplete)=", + fields->uuids32_is_complete ? "" : "in"); + for (i = 0; i < fields->num_uuids32; i++) { + print_uuid(&fields->uuids32[i].u); + MODLOG_DFLT(DEBUG, " "); + } + MODLOG_DFLT(DEBUG, "\n"); + } + + if (fields->uuids128 != NULL) { + MODLOG_DFLT(DEBUG, " uuids128(%scomplete)=", + fields->uuids128_is_complete ? "" : "in"); + for (i = 0; i < fields->num_uuids128; i++) { + print_uuid(&fields->uuids128[i].u); + MODLOG_DFLT(DEBUG, " "); + } + MODLOG_DFLT(DEBUG, "\n"); + } + + if (fields->name != NULL) { + assert(fields->name_len < sizeof s - 1); + memcpy(s, fields->name, fields->name_len); + s[fields->name_len] = '\0'; + MODLOG_DFLT(DEBUG, " name(%scomplete)=%s\n", + fields->name_is_complete ? "" : "in", s); + } + + if (fields->tx_pwr_lvl_is_present) { + MODLOG_DFLT(DEBUG, " tx_pwr_lvl=%d\n", fields->tx_pwr_lvl); + } + + if (fields->slave_itvl_range != NULL) { + MODLOG_DFLT(DEBUG, " slave_itvl_range="); + print_bytes(fields->slave_itvl_range, BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN); + MODLOG_DFLT(DEBUG, "\n"); + } + + if (fields->svc_data_uuid16 != NULL) { + MODLOG_DFLT(DEBUG, " svc_data_uuid16="); + print_bytes(fields->svc_data_uuid16, fields->svc_data_uuid16_len); + MODLOG_DFLT(DEBUG, "\n"); + } + + if (fields->public_tgt_addr != NULL) { + MODLOG_DFLT(DEBUG, " public_tgt_addr="); + u8p = fields->public_tgt_addr; + for (i = 0; i < fields->num_public_tgt_addrs; i++) { + MODLOG_DFLT(DEBUG, "public_tgt_addr=%s ", addr_str(u8p)); + u8p += BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN; + } + MODLOG_DFLT(DEBUG, "\n"); + } + + if (fields->appearance_is_present) { + MODLOG_DFLT(DEBUG, " appearance=0x%04x\n", fields->appearance); + } + + if (fields->adv_itvl_is_present) { + MODLOG_DFLT(DEBUG, " adv_itvl=0x%04x\n", fields->adv_itvl); + } + + if (fields->svc_data_uuid32 != NULL) { + MODLOG_DFLT(DEBUG, " svc_data_uuid32="); + print_bytes(fields->svc_data_uuid32, fields->svc_data_uuid32_len); + MODLOG_DFLT(DEBUG, "\n"); + } + + if (fields->svc_data_uuid128 != NULL) { + MODLOG_DFLT(DEBUG, " svc_data_uuid128="); + print_bytes(fields->svc_data_uuid128, fields->svc_data_uuid128_len); + MODLOG_DFLT(DEBUG, "\n"); + } + + if (fields->uri != NULL) { + MODLOG_DFLT(DEBUG, " uri="); + print_bytes(fields->uri, fields->uri_len); + MODLOG_DFLT(DEBUG, "\n"); + } + + if (fields->mfg_data != NULL) { + MODLOG_DFLT(DEBUG, " mfg_data="); + print_bytes(fields->mfg_data, fields->mfg_data_len); + MODLOG_DFLT(DEBUG, "\n"); + } +} + + + /** + * Logs information about a connection to the console. + */ +void print_conn_desc(const struct ble_gap_conn_desc *desc) +{ + MODLOG_DFLT(DEBUG, "handle=%d our_ota_addr_type=%d our_ota_addr=%s ", + desc->conn_handle, desc->our_ota_addr.type, + addr_str(desc->our_ota_addr.val)); + MODLOG_DFLT(DEBUG, "our_id_addr_type=%d our_id_addr=%s ", + desc->our_id_addr.type, addr_str(desc->our_id_addr.val)); + MODLOG_DFLT(DEBUG, "peer_ota_addr_type=%d peer_ota_addr=%s ", + desc->peer_ota_addr.type, addr_str(desc->peer_ota_addr.val)); + MODLOG_DFLT(DEBUG, "peer_id_addr_type=%d peer_id_addr=%s ", + desc->peer_id_addr.type, addr_str(desc->peer_id_addr.val)); + MODLOG_DFLT(DEBUG, "conn_itvl=%d conn_latency=%d supervision_timeout=%d " + "encrypted=%d authenticated=%d bonded=%d", + desc->conn_itvl, desc->conn_latency, + desc->supervision_timeout, + desc->sec_state.encrypted, + desc->sec_state.authenticated, + desc->sec_state.bonded); +} + + +void print_addr(const void *addr) +{ + const uint8_t *u8p; + + u8p = (uint8_t*)addr; + MODLOG_DFLT(INFO, "%02x:%02x:%02x:%02x:%02x:%02x", + u8p[5], u8p[4], u8p[3], u8p[2], u8p[1], u8p[0]); +} + +#endif //CONFIG_BT_ENABLED diff --git a/libesp32/NimBLE-Arduino/src/NimBLEUtils.h b/libesp32/NimBLE-Arduino/src/NimBLEUtils.h new file mode 100644 index 000000000..891f83596 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/NimBLEUtils.h @@ -0,0 +1,50 @@ +/* + * NimBLEUtils.h + * + * Created: on Jan 25 2020 + * Author H2zero + * + */ + +#ifndef COMPONENTS_NIMBLEUTILS_H_ +#define COMPONENTS_NIMBLEUTILS_H_ +#include "sdkconfig.h" +#if defined(CONFIG_BT_ENABLED) + +#include "host/ble_gap.h" + +/**** FIX COMPILATION ****/ +#undef min +#undef max +/**************************/ + +#include + +typedef struct { + void *pATT; + TaskHandle_t task; + int rc; + std::string *buf; +} ble_task_data_t; + +extern "C"{ +char *addr_str(const void *addr); +void print_conn_desc(const struct ble_gap_conn_desc *desc); +void print_adv_fields(const struct ble_hs_adv_fields *fields); +void print_addr(const void *addr); +void print_bytes(const uint8_t *bytes, int len); +} + +class NimBLEUtils { +public: + static void dumpGapEvent(ble_gap_event *event, void *arg); + static const char* gapEventToString(uint8_t eventType); + static char* buildHexData(uint8_t* target, const uint8_t* source, uint8_t length); + static const char* advTypeToString(uint8_t advType); + static const char* returnCodeToString(int rc); + static int checkConnParams(ble_gap_conn_params* params); +}; + + +#endif // CONFIG_BT_ENABLED +#endif // COMPONENTS_NIMBLEUTILS_H_ diff --git a/libesp32/NimBLE-Arduino/src/README.md b/libesp32/NimBLE-Arduino/src/README.md new file mode 100644 index 000000000..bbd17fc85 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/README.md @@ -0,0 +1,173 @@ + + +Apache Mynewt + +## Overview + +Apache NimBLE is an open-source Bluetooth 5.0 stack (both Host & Controller) +that completely replaces the proprietary SoftDevice on Nordic chipsets. It is +part of [Apache Mynewt project](https://github.com/apache/mynewt-core). + +Features highlight: + - Support for 251 byte packet size + - Support for all 4 roles concurrently - Broadcaster, Observer, Peripheral and Central + - Support for up to 32 simultaneous connections. + - Legacy and SC (secure connections) SMP support (pairing and bonding). + - Advertising Extensions. + - Periodic Advertising. + - Coded (aka Long Range) and 2M PHYs. + - Bluetooth Mesh. + +## Supported hardware + +Controller supports Nordic nRF51 and nRF52 chipsets. Host runs on any board +and architecture [supported](https://github.com/apache/mynewt-core#overview) +by Apache Mynewt OS. + + +## Browsing + +If you are browsing around the source tree, and want to see some of the +major functional chunks, here are a few pointers: + +- nimble/controller: Contains code for controller including Link Layer and HCI implementation +([controller](https://github.com/apache/mynewt-nimble/tree/master/nimble/controller)) + +- nimble/drivers: Contains drivers for supported radio transceivers (Nordic nRF51 and nRF52) +([drivers](https://github.com/apache/mynewt-nimble/tree/master/nimble/drivers)) + +- nimble/host: Contains code for host subsystem. This includes protocols like +L2CAP and ATT, support for HCI commands and events, Generic Access Profile (GAP), +Generic Attribute Profile (GATT) and Security Manager (SM). +([host](https://github.com/apache/mynewt-nimble/tree/master/nimble/host)) + +- nimble/host/mesh: Contains code for Bluetooth Mesh subsystem. +([mesh](https://github.com/apache/mynewt-nimble/tree/master/nimble/host/mesh)) + +- nimble/transport: Contains code for supported transport protocols between host +and controller. This includes UART, emSPI and RAM (used in combined build when +host and controller run on same CPU) +([transport](https://github.com/apache/mynewt-nimble/tree/master/nimble/transport)) + +- porting: Contains implementation of NimBLE Porting Layer (NPL) for supported +operating systems +([porting](https://github.com/apache/mynewt-nimble/tree/master/porting)) + +- ext: Contains external libraries used by NimBLE. Those are used if not +provided by OS +([ext](https://github.com/apache/mynewt-nimble/tree/master/ext)) + +- kernel: Contains the core of the RTOS ([kernel/os](https://github.com/apache/mynewt-core/tree/master/kernel/os)) + +## Sample Applications + +There are also some sample applications that show how to Apache Mynewt NimBLE +stack. These sample applications are located in the `apps/` directory of +Apache Mynewt [repo](https://github.com/apache/mynewt-core). Some examples: + +* [blecent](https://github.com/apache/mynewt-core/tree/master/apps/blecent): +A basic central device with no user interface. This application scans for +a peripheral that supports the alert notification service (ANS). Upon +discovering such a peripheral, blecent connects and performs a characteristic +read, characteristic write, and notification subscription. +* [blehci](https://github.com/apache/mynewt-core/tree/master/apps/blehci): +Implements a BLE controller-only application. A separate host-only +implementation, such as Linux's BlueZ, can interface with this application via +HCI over UART. +* [bleprph](https://github.com/apache/mynewt-core/tree/master/apps/bleprph): An + implementation of a minimal BLE peripheral. +* [btshell](https://github.com/apache/mynewt-core/tree/master/apps/btshell): A + shell-like application allowing to configure and use most of NimBLE + functionality from command line. +* [bleuart](https://github.com/apache/mynewt-core/tree/master/apps/bleuart): +Implements a simple BLE peripheral that supports the Nordic +UART / Serial Port Emulation service +(https://developer.nordicsemi.com/nRF5_SDK/nRF51_SDK_v8.x.x/doc/8.0.0/s110/html/a00072.html). +* [test](https://github.com/apache/mynewt-core/tree/master/apps/test): Test + project which can be compiled either with the simulator, or on a per-architecture basis. + Test will run all the package's unit tests. + +# Getting Help + +If you are having trouble using or contributing to Apache Mynewt NimBLE, or just +want to talk to a human about what you're working on, you can contact us via the +[developers mailing list](mailto:dev@mynewt.apache.org). + +Although not a formal channel, you can also find a number of core developers +on the #mynewt channel on Freenode IRC or #general channel on [Mynewt Slack](https://join.slack.com/mynewt/shared_invite/MTkwMTg1ODM1NTg5LTE0OTYxNzQ4NzQtZTU1YmNhYjhkMg) + +Also, be sure to checkout the [Frequently Asked Questions](https://mynewt.apache.org/faq/answers) +for some help troubleshooting first. + +# Contributing + +Anybody who works with Apache Mynewt can be a contributing member of the +community that develops and deploys it. The process of releasing an operating +system for microcontrollers is never done: and we welcome your contributions +to that effort. + +More information can be found at the Community section of the Apache Mynewt +website, located [here](https://mynewt.apache.org/community). + +## Pull Requests + +Apache Mynewt welcomes pull request via Github. Discussions are done on Github, +but depending on the topic, can also be relayed to the official Apache Mynewt +developer mailing list dev@mynewt.apache.org. + +If you are suggesting a new feature, please email the developer list directly, +with a description of the feature you are planning to work on. + +## Filing Bugs + +Bugs can be filed on the +[Apache Mynewt NimBLE Issues](https://github.com/apache/mynewt-nimble/issues). +Please label the issue as a "Bug". + +Where possible, please include a self-contained reproduction case! + +## Feature Requests + +Feature requests should also be filed on the +[Apache Mynewt NimBLE Bug Tracker](https://github.com/apache/mynewt-nimble/issues). +Please label the issue as a "Feature" or "Enhancement" depending on the scope. + +## Writing Tests + +We love getting newt tests! Apache Mynewt is a huge undertaking, and improving +code coverage is a win for every Apache Mynewt user. + + + +# License + +The code in this repository is all under either the Apache 2 license, or a +license compatible with the Apache 2 license. See the LICENSE file for more +information. diff --git a/libesp32/NimBLE-Arduino/src/RELEASE_NOTES.md b/libesp32/NimBLE-Arduino/src/RELEASE_NOTES.md new file mode 100644 index 000000000..cda8fe2e4 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/RELEASE_NOTES.md @@ -0,0 +1,27 @@ +# RELEASE NOTES + +16 July 2019 - Apache NimBLE v1.2.0 + +For full release notes, please visit the +[Apache Mynewt Wiki](https://cwiki.apache.org/confluence/display/MYNEWT/Release+Notes). + +Apache NimBLE is an open-source Bluetooth 5.0 stack (both Host & Controller) that completely +replaces the proprietary SoftDevice on Nordic chipsets. + +New features in this version of NimBLE include: + +* Perdiodic Advertising support with up to 1650 bytes of data (scanner and advertiser) +* Support for scan request notification in GAP API +* Updated host qualification ID +* Qualification related bugfixes +* GAP API doxygen documentation update +* BLE Mesh improvements - fixes and resync with latest Zephyr code +* RIOT OS port fixes and improvements +* btshell sample application improvements +* improvements for bttester application +* Controller duplicates filtering improvements +* Memory and CPU usage optimizations in controller + +If working on next-generation RTOS and Bluetooth protocol stack +sounds exciting to you, get in touch, by sending a mail to the Apache Mynewt +Developer's list, dev@mynewt.apache.org. diff --git a/libesp32/NimBLE-Arduino/src/console/console.h b/libesp32/NimBLE-Arduino/src/console/console.h new file mode 100644 index 000000000..96f965159 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/console/console.h @@ -0,0 +1,21 @@ +// Copyright 2019 Espressif Systems (Shanghai) PTE LTD +// +//Licensed under the Apache License, Version 2.0 (the "License"); +//you may not use this file except in compliance with the License. +//You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, software +//distributed under the License is distributed on an "AS IS" BASIS, +//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//See the License for the specific language governing permissions and +//limitations under the License. +#ifndef _CONSOLE_H +#define _CONSOLE_H + +#include + +#define console_printf printf + +#endif diff --git a/libesp32/NimBLE-Arduino/src/esp-hci/src/esp_nimble_hci.c b/libesp32/NimBLE-Arduino/src/esp-hci/src/esp_nimble_hci.c new file mode 100644 index 000000000..e4ab99932 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/esp-hci/src/esp_nimble_hci.c @@ -0,0 +1,522 @@ +/* + * Copyright 2019 Espressif Systems (Shanghai) PTE LTD + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include "sysinit/sysinit.h" +#include "nimble/hci_common.h" +#include "host/ble_hs.h" +#include "nimble/nimble_port.h" +#include "nimble/nimble_port_freertos.h" +#include "esp_nimble_hci.h" +#include "esp_nimble_mem.h" +#include "esp_bt.h" +#include "freertos/semphr.h" +#include "esp_compiler.h" + +#define NIMBLE_VHCI_TIMEOUT_MS 2000 + +static ble_hci_trans_rx_cmd_fn *ble_hci_rx_cmd_hs_cb; +static void *ble_hci_rx_cmd_hs_arg; + +static ble_hci_trans_rx_acl_fn *ble_hci_rx_acl_hs_cb; +static void *ble_hci_rx_acl_hs_arg; + +static struct os_mbuf_pool ble_hci_acl_mbuf_pool; +static struct os_mempool_ext ble_hci_acl_pool; +/* + * The MBUF payload size must accommodate the HCI data header size plus the + * maximum ACL data packet length. The ACL block size is the size of the + * mbufs we will allocate. + */ +#define ACL_BLOCK_SIZE OS_ALIGN(MYNEWT_VAL(BLE_ACL_BUF_SIZE) \ + + BLE_MBUF_MEMBLOCK_OVERHEAD \ + + BLE_HCI_DATA_HDR_SZ, OS_ALIGNMENT) + +static os_membuf_t *ble_hci_acl_buf; + +static struct os_mempool ble_hci_cmd_pool; +static os_membuf_t *ble_hci_cmd_buf; + +static struct os_mempool ble_hci_evt_hi_pool; +static os_membuf_t *ble_hci_evt_hi_buf; + +static struct os_mempool ble_hci_evt_lo_pool; +static os_membuf_t *ble_hci_evt_lo_buf; + +static SemaphoreHandle_t vhci_send_sem; +const static char *TAG = "NimBLE"; + +int os_msys_buf_alloc(void); +void os_msys_buf_free(void); + +void ble_hci_trans_cfg_hs(ble_hci_trans_rx_cmd_fn *cmd_cb, + void *cmd_arg, + ble_hci_trans_rx_acl_fn *acl_cb, + void *acl_arg) +{ + ble_hci_rx_cmd_hs_cb = cmd_cb; + ble_hci_rx_cmd_hs_arg = cmd_arg; + ble_hci_rx_acl_hs_cb = acl_cb; + ble_hci_rx_acl_hs_arg = acl_arg; +} + + +int ble_hci_trans_hs_cmd_tx(uint8_t *cmd) +{ + uint16_t len; + uint8_t rc = 0; + + assert(cmd != NULL); + *cmd = BLE_HCI_UART_H4_CMD; + len = BLE_HCI_CMD_HDR_LEN + cmd[3] + 1; + if (!esp_vhci_host_check_send_available()) { + ESP_LOGD(TAG, "Controller not ready to receive packets"); + } + + if (xSemaphoreTake(vhci_send_sem, NIMBLE_VHCI_TIMEOUT_MS / portTICK_PERIOD_MS) == pdTRUE) { + esp_vhci_host_send_packet(cmd, len); + } else { + rc = BLE_HS_ETIMEOUT_HCI; + } + + ble_hci_trans_buf_free(cmd); + return rc; +} + +int ble_hci_trans_ll_evt_tx(uint8_t *hci_ev) +{ + int rc = ESP_FAIL; + + if (ble_hci_rx_cmd_hs_cb) { + rc = ble_hci_rx_cmd_hs_cb(hci_ev, ble_hci_rx_cmd_hs_arg); + } + return rc; +} + +int ble_hci_trans_hs_acl_tx(struct os_mbuf *om) +{ + uint16_t len = 0; + uint8_t data[MYNEWT_VAL(BLE_ACL_BUF_SIZE) + 1], rc = 0; + /* If this packet is zero length, just free it */ + if (OS_MBUF_PKTLEN(om) == 0) { + os_mbuf_free_chain(om); + return 0; + } + data[0] = BLE_HCI_UART_H4_ACL; + len++; + + if (!esp_vhci_host_check_send_available()) { + ESP_LOGD(TAG, "Controller not ready to receive packets"); + } + + os_mbuf_copydata(om, 0, OS_MBUF_PKTLEN(om), &data[1]); + len += OS_MBUF_PKTLEN(om); + + if (xSemaphoreTake(vhci_send_sem, NIMBLE_VHCI_TIMEOUT_MS / portTICK_PERIOD_MS) == pdTRUE) { + esp_vhci_host_send_packet(data, len); + } else { + rc = BLE_HS_ETIMEOUT_HCI; + } + + os_mbuf_free_chain(om); + + return rc; +} + +int ble_hci_trans_ll_acl_tx(struct os_mbuf *om) +{ + int rc = ESP_FAIL; + + if (ble_hci_rx_acl_hs_cb) { + rc = ble_hci_rx_acl_hs_cb(om, ble_hci_rx_acl_hs_arg); + } + return rc; +} + +uint8_t *ble_hci_trans_buf_alloc(int type) +{ + uint8_t *buf; + + switch (type) { + case BLE_HCI_TRANS_BUF_CMD: + buf = os_memblock_get(&ble_hci_cmd_pool); + break; + + case BLE_HCI_TRANS_BUF_EVT_HI: + buf = os_memblock_get(&ble_hci_evt_hi_pool); + if (buf == NULL) { + /* If no high-priority event buffers remain, try to grab a + * low-priority one. + */ + buf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_LO); + } + break; + + case BLE_HCI_TRANS_BUF_EVT_LO: + buf = os_memblock_get(&ble_hci_evt_lo_pool); + break; + + default: + assert(0); + buf = NULL; + } + + return buf; +} + +void ble_hci_trans_buf_free(uint8_t *buf) +{ + int rc; + /* XXX: this may look a bit odd, but the controller uses the command + * buffer to send back the command complete/status as an immediate + * response to the command. This was done to insure that the controller + * could always send back one of these events when a command was received. + * Thus, we check to see which pool the buffer came from so we can free + * it to the appropriate pool + */ + if (os_memblock_from(&ble_hci_evt_hi_pool, buf)) { + rc = os_memblock_put(&ble_hci_evt_hi_pool, buf); + assert(rc == 0); + } else if (os_memblock_from(&ble_hci_evt_lo_pool, buf)) { + rc = os_memblock_put(&ble_hci_evt_lo_pool, buf); + assert(rc == 0); + } else { + assert(os_memblock_from(&ble_hci_cmd_pool, buf)); + rc = os_memblock_put(&ble_hci_cmd_pool, buf); + assert(rc == 0); + } +} + +/** + * Unsupported; the RAM transport does not have a dedicated ACL data packet + * pool. + */ +int ble_hci_trans_set_acl_free_cb(os_mempool_put_fn *cb, void *arg) +{ + return BLE_ERR_UNSUPPORTED; +} + +int ble_hci_trans_reset(void) +{ + /* No work to do. All allocated buffers are owned by the host or + * controller, and they will get freed by their owners. + */ + return 0; +} + +/** + * Allocates a buffer (mbuf) for ACL operation. + * + * @return The allocated buffer on success; + * NULL on buffer exhaustion. + */ +static struct os_mbuf *ble_hci_trans_acl_buf_alloc(void) +{ + struct os_mbuf *m; + uint8_t usrhdr_len; + +#if MYNEWT_VAL(BLE_DEVICE) + usrhdr_len = sizeof(struct ble_mbuf_hdr); +#elif MYNEWT_VAL(BLE_HS_FLOW_CTRL) + usrhdr_len = BLE_MBUF_HS_HDR_LEN; +#else + usrhdr_len = 0; +#endif + + m = os_mbuf_get_pkthdr(&ble_hci_acl_mbuf_pool, usrhdr_len); + return m; +} + +static void ble_hci_rx_acl(uint8_t *data, uint16_t len) +{ + struct os_mbuf *m; + int sr; + if (len < BLE_HCI_DATA_HDR_SZ || len > MYNEWT_VAL(BLE_ACL_BUF_SIZE)) { + return; + } + + m = ble_hci_trans_acl_buf_alloc(); + + if (!m) { + return; + } + if (os_mbuf_append(m, data, len)) { + os_mbuf_free_chain(m); + return; + } + OS_ENTER_CRITICAL(sr); + if (ble_hci_rx_acl_hs_cb) { + ble_hci_rx_acl_hs_cb(m, NULL); + } + OS_EXIT_CRITICAL(sr); +} + +static void ble_hci_transport_init(void) +{ + int rc; + + /* Ensure this function only gets called by sysinit. */ + SYSINIT_ASSERT_ACTIVE(); + + rc = os_mempool_ext_init(&ble_hci_acl_pool, + MYNEWT_VAL(BLE_ACL_BUF_COUNT), + ACL_BLOCK_SIZE, + ble_hci_acl_buf, + "ble_hci_acl_pool"); + SYSINIT_PANIC_ASSERT(rc == 0); + + rc = os_mbuf_pool_init(&ble_hci_acl_mbuf_pool, + &ble_hci_acl_pool.mpe_mp, + ACL_BLOCK_SIZE, + MYNEWT_VAL(BLE_ACL_BUF_COUNT)); + SYSINIT_PANIC_ASSERT(rc == 0); + + /* + * Create memory pool of HCI command buffers. NOTE: we currently dont + * allow this to be configured. The controller will only allow one + * outstanding command. We decided to keep this a pool in case we allow + * allow the controller to handle more than one outstanding command. + */ + rc = os_mempool_init(&ble_hci_cmd_pool, + 1, + BLE_HCI_TRANS_CMD_SZ, + ble_hci_cmd_buf, + "ble_hci_cmd_pool"); + SYSINIT_PANIC_ASSERT(rc == 0); + + rc = os_mempool_init(&ble_hci_evt_hi_pool, + MYNEWT_VAL(BLE_HCI_EVT_HI_BUF_COUNT), + MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE), + ble_hci_evt_hi_buf, + "ble_hci_evt_hi_pool"); + SYSINIT_PANIC_ASSERT(rc == 0); + + rc = os_mempool_init(&ble_hci_evt_lo_pool, + MYNEWT_VAL(BLE_HCI_EVT_LO_BUF_COUNT), + MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE), + ble_hci_evt_lo_buf, + "ble_hci_evt_lo_pool"); + SYSINIT_PANIC_ASSERT(rc == 0); +} + +/* + * @brief: BT controller callback function, used to notify the upper layer that + * controller is ready to receive command + */ +static void controller_rcv_pkt_ready(void) +{ + if (vhci_send_sem) { + xSemaphoreGive(vhci_send_sem); + } +} + +/* + * @brief: BT controller callback function, to transfer data packet to the host + */ +static int host_rcv_pkt(uint8_t *data, uint16_t len) +{ + + if (data[0] == BLE_HCI_UART_H4_EVT) { + uint8_t *evbuf; + int totlen; + int rc; + + totlen = BLE_HCI_EVENT_HDR_LEN + data[2]; + assert(totlen <= UINT8_MAX + BLE_HCI_EVENT_HDR_LEN); + + if (data[1] == BLE_HCI_EVCODE_HW_ERROR) { + assert(0); + } + + /* Allocate LE Advertising Report Event from lo pool only */ + if ((data[1] == BLE_HCI_EVCODE_LE_META) && (data[3] == BLE_HCI_LE_SUBEV_ADV_RPT)) { + evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_LO); + /* Skip advertising report if we're out of memory */ + if (!evbuf) { + return 0; + } + } else { + evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); + assert(evbuf != NULL); + } + + memcpy(evbuf, &data[1], totlen); + + rc = ble_hci_trans_ll_evt_tx(evbuf); + assert(rc == 0); + } else if (data[0] == BLE_HCI_UART_H4_ACL) { + ble_hci_rx_acl(data + 1, len - 1); + } + return 0; +} + +static const esp_vhci_host_callback_t vhci_host_cb = { + .notify_host_send_available = controller_rcv_pkt_ready, + .notify_host_recv = host_rcv_pkt, +}; + +static void ble_buf_free(void) +{ + os_msys_buf_free(); + + nimble_platform_mem_free(ble_hci_evt_hi_buf); + ble_hci_evt_hi_buf = NULL; + nimble_platform_mem_free(ble_hci_evt_lo_buf); + ble_hci_evt_lo_buf = NULL; + nimble_platform_mem_free(ble_hci_cmd_buf); + ble_hci_cmd_buf = NULL; + nimble_platform_mem_free(ble_hci_acl_buf); + ble_hci_acl_buf = NULL; +} + +static esp_err_t ble_buf_alloc(void) +{ + if (os_msys_buf_alloc()) { + return ESP_ERR_NO_MEM; + } + + ble_hci_evt_hi_buf = (os_membuf_t *) nimble_platform_mem_calloc(1, + (sizeof(os_membuf_t) * OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_HCI_EVT_HI_BUF_COUNT), + MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE)))); + + ble_hci_evt_lo_buf = (os_membuf_t *) nimble_platform_mem_calloc(1, + (sizeof(os_membuf_t) * OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_HCI_EVT_LO_BUF_COUNT), + MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE)))); + + ble_hci_cmd_buf = (os_membuf_t *) nimble_platform_mem_calloc(1, + (sizeof(os_membuf_t) * OS_MEMPOOL_SIZE(1, BLE_HCI_TRANS_CMD_SZ))); + + ble_hci_acl_buf = (os_membuf_t *) nimble_platform_mem_calloc(1, + (sizeof(os_membuf_t) * OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_ACL_BUF_COUNT), + ACL_BLOCK_SIZE))); + + if (!ble_hci_evt_hi_buf || !ble_hci_evt_lo_buf || !ble_hci_cmd_buf || !ble_hci_acl_buf) { + ble_buf_free(); + return ESP_ERR_NO_MEM; + } + return ESP_OK; +} + +esp_err_t esp_nimble_hci_init(void) +{ + esp_err_t ret; + + ret = ble_buf_alloc(); + if (ret != ESP_OK) { + goto err; + } + if ((ret = esp_vhci_host_register_callback(&vhci_host_cb)) != ESP_OK) { + goto err; + } + + ble_hci_transport_init(); + + vhci_send_sem = xSemaphoreCreateBinary(); + if (vhci_send_sem == NULL) { + ret = ESP_ERR_NO_MEM; + goto err; + } + + xSemaphoreGive(vhci_send_sem); + + return ret; +err: + ble_buf_free(); + return ret; + +} + +esp_err_t esp_nimble_hci_and_controller_init(void) +{ + esp_err_t ret; + + esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT); + + esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); + + if ((ret = esp_bt_controller_init(&bt_cfg)) != ESP_OK) { + return ret; + } + + if ((ret = esp_bt_controller_enable(ESP_BT_MODE_BLE)) != ESP_OK) { + return ret; + } + return esp_nimble_hci_init(); +} + +static esp_err_t ble_hci_transport_deinit(void) +{ + int ret = 0; + + ret += os_mempool_clear(&ble_hci_evt_lo_pool); + + ret += os_mempool_clear(&ble_hci_evt_hi_pool); + + ret += os_mempool_clear(&ble_hci_cmd_pool); + + ret += os_mempool_ext_clear(&ble_hci_acl_pool); + + if (ret) { + return ESP_FAIL; + } else { + return ESP_OK; + } +} + +esp_err_t esp_nimble_hci_deinit(void) +{ + if (vhci_send_sem) { + /* Dummy take & give semaphore before deleting */ + xSemaphoreTake(vhci_send_sem, portMAX_DELAY); + xSemaphoreGive(vhci_send_sem); + vSemaphoreDelete(vhci_send_sem); + vhci_send_sem = NULL; + } + esp_err_t ret = ble_hci_transport_deinit(); + if (ret != ESP_OK) { + return ret; + } + + ble_buf_free(); + + return ESP_OK; +} + +esp_err_t esp_nimble_hci_and_controller_deinit(void) +{ + int ret; + ret = esp_nimble_hci_deinit(); + if (ret != ESP_OK) { + return ret; + } + + ret = esp_bt_controller_disable(); + if (ret != ESP_OK) { + return ret; + } + + ret = esp_bt_controller_deinit(); + if (ret != ESP_OK) { + return ret; + } + + return ESP_OK; +} diff --git a/libesp32/NimBLE-Arduino/src/esp_compiler.h b/libesp32/NimBLE-Arduino/src/esp_compiler.h new file mode 100644 index 000000000..94ec29c23 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/esp_compiler.h @@ -0,0 +1,33 @@ +// Copyright 2016-2019 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#ifndef __ESP_COMPILER_H +#define __ESP_COMPILER_H + +/* + * The likely and unlikely macro pairs: + * These macros are useful to place when application + * knows the majority ocurrence of a decision paths, + * placing one of these macros can hint the compiler + * to reorder instructions producing more optimized + * code. + */ +#if (CONFIG_COMPILER_OPTIMIZATION_PERF) +#define likely(x) __builtin_expect(!!(x), 1) +#define unlikely(x) __builtin_expect(!!(x), 0) +#else +#define likely(x) (x) +#define unlikely(x) (x) +#endif + +#endif \ No newline at end of file diff --git a/libesp32/NimBLE-Arduino/src/esp_nimble_cfg.h b/libesp32/NimBLE-Arduino/src/esp_nimble_cfg.h new file mode 100644 index 000000000..384ec4a56 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/esp_nimble_cfg.h @@ -0,0 +1,1101 @@ + +#ifndef __ESP_NIMBLE_CFG__ +#define __ESP_NIMBLE_CFG__ +#include "nimconfig.h" + +/** + * This macro exists to ensure code includes this header when needed. If code + * checks the existence of a setting directly via ifdef without including this + * header, the setting macro will silently evaluate to 0. In contrast, an + * attempt to use these macros without including this header will result in a + * compiler error. + */ +#define MYNEWT_VAL(x) MYNEWT_VAL_ ## x + +/*** kernel/os */ +#ifndef MYNEWT_VAL_MSYS_1_BLOCK_COUNT +#ifdef CONFIG_BT_NIMBLE_MESH +#define MYNEWT_VAL_MSYS_1_BLOCK_COUNT (CONFIG_BT_NIMBLE_MSYS1_BLOCK_COUNT + 8) +#else +#define MYNEWT_VAL_MSYS_1_BLOCK_COUNT CONFIG_BT_NIMBLE_MSYS1_BLOCK_COUNT +#endif +#endif + +#ifndef MYNEWT_VAL_MSYS_1_BLOCK_SIZE +#define MYNEWT_VAL_MSYS_1_BLOCK_SIZE (292) +#endif + +#ifndef MYNEWT_VAL_MSYS_2_BLOCK_COUNT +#define MYNEWT_VAL_MSYS_2_BLOCK_COUNT (0) +#endif + +#ifndef MYNEWT_VAL_MSYS_2_BLOCK_SIZE +#define MYNEWT_VAL_MSYS_2_BLOCK_SIZE (0) +#endif + +#ifndef MYNEWT_VAL_OS_CPUTIME_FREQ +#define MYNEWT_VAL_OS_CPUTIME_FREQ (1000000) +#endif + +#ifndef MYNEWT_VAL_OS_CPUTIME_TIMER_NUM +#define MYNEWT_VAL_OS_CPUTIME_TIMER_NUM (0) +#endif + +/*** nimble */ +#ifndef MYNEWT_VAL_BLE_EXT_ADV +#define MYNEWT_VAL_BLE_EXT_ADV (0) +#endif + +#ifndef MYNEWT_VAL_BLE_EXT_ADV_MAX_SIZE +#define MYNEWT_VAL_BLE_EXT_ADV_MAX_SIZE (31) +#endif + +#ifndef MYNEWT_VAL_BLE_MAX_CONNECTIONS +#define MYNEWT_VAL_BLE_MAX_CONNECTIONS CONFIG_BT_NIMBLE_MAX_CONNECTIONS +#endif + +#ifndef MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES +#define MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MAX_PERIODIC_SYNCS +#define MYNEWT_VAL_BLE_MAX_PERIODIC_SYNCS (0) +#endif + +#ifndef MYNEWT_VAL_BLE_ROLE_BROADCASTER +#ifdef CONFIG_BT_NIMBLE_ROLE_BROADCASTER +#define MYNEWT_VAL_BLE_ROLE_BROADCASTER (1) +#else +#define MYNEWT_VAL_BLE_ROLE_BROADCASTER (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_ROLE_CENTRAL +#ifdef CONFIG_BT_NIMBLE_ROLE_CENTRAL +#define MYNEWT_VAL_BLE_ROLE_CENTRAL (1) +#else +#define MYNEWT_VAL_BLE_ROLE_CENTRAL (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_ROLE_OBSERVER +#ifdef CONFIG_BT_NIMBLE_ROLE_OBSERVER +#define MYNEWT_VAL_BLE_ROLE_OBSERVER (1) +#else +#define MYNEWT_VAL_BLE_ROLE_OBSERVER (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_ROLE_PERIPHERAL +#ifdef CONFIG_BT_NIMBLE_ROLE_PERIPHERAL +#define MYNEWT_VAL_BLE_ROLE_PERIPHERAL (1) +#else +#define MYNEWT_VAL_BLE_ROLE_PERIPHERAL (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_WHITELIST +#define MYNEWT_VAL_BLE_WHITELIST (1) +#endif + +/*** @apache-mynewt-nimble/nimble/controller */ +#ifndef MYNEWT_VAL_BLE_DEVICE +#define MYNEWT_VAL_BLE_DEVICE (0) +#endif + +/* Overridden by @apache-mynewt-nimble/nimble/controller (defined by @apache-mynewt-nimble/nimble/controller) */ +#ifndef MYNEWT_VAL_BLE_HW_WHITELIST_ENABLE +#define MYNEWT_VAL_BLE_HW_WHITELIST_ENABLE (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_ADD_STRICT_SCHED_PERIODS +#define MYNEWT_VAL_BLE_LL_ADD_STRICT_SCHED_PERIODS (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_CONN_PARAM_REQ +#define MYNEWT_VAL_BLE_LL_CFG_FEAT_CONN_PARAM_REQ (1) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_DATA_LEN_EXT +#define MYNEWT_VAL_BLE_LL_CFG_FEAT_DATA_LEN_EXT (1) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_EXT_SCAN_FILT +#define MYNEWT_VAL_BLE_LL_CFG_FEAT_EXT_SCAN_FILT (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_2M_PHY +#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_2M_PHY (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_CODED_PHY +#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_CODED_PHY (0) +#endif + +/* Overridden by @apache-mynewt-nimble/nimble/controller (defined by @apache-mynewt-nimble/nimble/controller) */ +#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_CSA2 +#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_CSA2 (1) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_ENCRYPTION +#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_ENCRYPTION (1) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_PING +#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_PING (MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_ENCRYPTION) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_EXT_ADV +#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_EXT_ADV (MYNEWT_VAL_BLE_EXT_ADV) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PRIVACY +#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PRIVACY (1) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_SLAVE_INIT_FEAT_XCHG +#define MYNEWT_VAL_BLE_LL_CFG_FEAT_SLAVE_INIT_FEAT_XCHG (1) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_CONN_INIT_MAX_TX_BYTES +#define MYNEWT_VAL_BLE_LL_CONN_INIT_MAX_TX_BYTES (27) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_CONN_INIT_MIN_WIN_OFFSET +#define MYNEWT_VAL_BLE_LL_CONN_INIT_MIN_WIN_OFFSET (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_CONN_INIT_SLOTS +#define MYNEWT_VAL_BLE_LL_CONN_INIT_SLOTS (4) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_DIRECT_TEST_MODE +#define MYNEWT_VAL_BLE_LL_DIRECT_TEST_MODE (0) +#endif + +/* Overridden by @apache-mynewt-nimble/nimble/controller (defined by @apache-mynewt-nimble/nimble/controller) */ +#ifndef MYNEWT_VAL_BLE_LL_EXT_ADV_AUX_PTR_CNT +#define MYNEWT_VAL_BLE_LL_EXT_ADV_AUX_PTR_CNT (5) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_MASTER_SCA +#define MYNEWT_VAL_BLE_LL_MASTER_SCA (4) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_MAX_PKT_SIZE +#define MYNEWT_VAL_BLE_LL_MAX_PKT_SIZE (251) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_MFRG_ID +#define MYNEWT_VAL_BLE_LL_MFRG_ID (0xFFFF) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_NUM_SCAN_DUP_ADVS +#define MYNEWT_VAL_BLE_LL_NUM_SCAN_DUP_ADVS (8) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_NUM_SCAN_RSP_ADVS +#define MYNEWT_VAL_BLE_LL_NUM_SCAN_RSP_ADVS (8) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_OUR_SCA +#define MYNEWT_VAL_BLE_LL_OUR_SCA (60) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_PRIO +#define MYNEWT_VAL_BLE_LL_PRIO (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_RESOLV_LIST_SIZE +#define MYNEWT_VAL_BLE_LL_RESOLV_LIST_SIZE (4) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_RNG_BUFSIZE +#define MYNEWT_VAL_BLE_LL_RNG_BUFSIZE (32) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_STRICT_CONN_SCHEDULING +#define MYNEWT_VAL_BLE_LL_STRICT_CONN_SCHEDULING (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_SUPP_MAX_RX_BYTES +#define MYNEWT_VAL_BLE_LL_SUPP_MAX_RX_BYTES (MYNEWT_VAL_BLE_LL_MAX_PKT_SIZE) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_SUPP_MAX_TX_BYTES +#define MYNEWT_VAL_BLE_LL_SUPP_MAX_TX_BYTES (MYNEWT_VAL_BLE_LL_MAX_PKT_SIZE) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_SYSVIEW +#define MYNEWT_VAL_BLE_LL_SYSVIEW (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_TX_PWR_DBM +#define MYNEWT_VAL_BLE_LL_TX_PWR_DBM (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_USECS_PER_PERIOD +#define MYNEWT_VAL_BLE_LL_USECS_PER_PERIOD (3250) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_VND_EVENT_ON_ASSERT +#define MYNEWT_VAL_BLE_LL_VND_EVENT_ON_ASSERT (0) +#endif + +#ifndef MYNEWT_VAL_BLE_LL_WHITELIST_SIZE +#define MYNEWT_VAL_BLE_LL_WHITELIST_SIZE (8) +#endif + +#ifndef MYNEWT_VAL_BLE_LP_CLOCK +#define MYNEWT_VAL_BLE_LP_CLOCK (1) +#endif + +#ifndef MYNEWT_VAL_BLE_NUM_COMP_PKT_RATE +#define MYNEWT_VAL_BLE_NUM_COMP_PKT_RATE ((2 * OS_TICKS_PER_SEC)) +#endif + +#ifndef MYNEWT_VAL_BLE_PUBLIC_DEV_ADDR +#define MYNEWT_VAL_BLE_PUBLIC_DEV_ADDR ((uint8_t[6]){0x00, 0x00, 0x00, 0x00, 0x00, 0x00}) +#endif + +#ifndef MYNEWT_VAL_BLE_XTAL_SETTLE_TIME +#define MYNEWT_VAL_BLE_XTAL_SETTLE_TIME (0) +#endif + +/*** @apache-mynewt-nimble/nimble/host */ +#ifndef MYNEWT_VAL_BLE_ATT_PREFERRED_MTU +#define MYNEWT_VAL_BLE_ATT_PREFERRED_MTU CONFIG_BT_NIMBLE_ATT_PREFERRED_MTU +#endif + +#ifndef MYNEWT_VAL_BLE_PERIODIC_ADV +#define MYNEWT_VAL_BLE_PERIODIC_ADV (0) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_FIND_INFO +#define MYNEWT_VAL_BLE_ATT_SVR_FIND_INFO (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_FIND_TYPE +#define MYNEWT_VAL_BLE_ATT_SVR_FIND_TYPE (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_INDICATE +#define MYNEWT_VAL_BLE_ATT_SVR_INDICATE (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_MAX_PREP_ENTRIES +#define MYNEWT_VAL_BLE_ATT_SVR_MAX_PREP_ENTRIES (64) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_NOTIFY +#define MYNEWT_VAL_BLE_ATT_SVR_NOTIFY (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE +#define MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE_TMO +#define MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE_TMO (30000) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_READ +#define MYNEWT_VAL_BLE_ATT_SVR_READ (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_READ_BLOB +#define MYNEWT_VAL_BLE_ATT_SVR_READ_BLOB (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_READ_GROUP_TYPE +#define MYNEWT_VAL_BLE_ATT_SVR_READ_GROUP_TYPE (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_READ_MULT +#define MYNEWT_VAL_BLE_ATT_SVR_READ_MULT (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_READ_TYPE +#define MYNEWT_VAL_BLE_ATT_SVR_READ_TYPE (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_SIGNED_WRITE +#define MYNEWT_VAL_BLE_ATT_SVR_SIGNED_WRITE (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_WRITE +#define MYNEWT_VAL_BLE_ATT_SVR_WRITE (1) +#endif + +#ifndef MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP +#define MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP (1) +#endif + +#ifndef MYNEWT_VAL_BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE +#define MYNEWT_VAL_BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE (1) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_DISC_ALL_CHRS +#define MYNEWT_VAL_BLE_GATT_DISC_ALL_CHRS (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_DISC_ALL_DSCS +#define MYNEWT_VAL_BLE_GATT_DISC_ALL_DSCS (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_DISC_ALL_SVCS +#define MYNEWT_VAL_BLE_GATT_DISC_ALL_SVCS (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_DISC_CHR_UUID +#define MYNEWT_VAL_BLE_GATT_DISC_CHR_UUID (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_DISC_SVC_UUID +#define MYNEWT_VAL_BLE_GATT_DISC_SVC_UUID (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_FIND_INC_SVCS +#define MYNEWT_VAL_BLE_GATT_FIND_INC_SVCS (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_INDICATE +#define MYNEWT_VAL_BLE_GATT_INDICATE (1) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_MAX_PROCS +#define MYNEWT_VAL_BLE_GATT_MAX_PROCS (4) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_NOTIFY +#define MYNEWT_VAL_BLE_GATT_NOTIFY (1) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_READ +#define MYNEWT_VAL_BLE_GATT_READ (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_READ_LONG +#define MYNEWT_VAL_BLE_GATT_READ_LONG (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_READ_MAX_ATTRS +#define MYNEWT_VAL_BLE_GATT_READ_MAX_ATTRS (8) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_READ_MULT +#define MYNEWT_VAL_BLE_GATT_READ_MULT (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_READ_UUID +#define MYNEWT_VAL_BLE_GATT_READ_UUID (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_RESUME_RATE +#define MYNEWT_VAL_BLE_GATT_RESUME_RATE (1000) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_SIGNED_WRITE +#define MYNEWT_VAL_BLE_GATT_SIGNED_WRITE (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_WRITE +#define MYNEWT_VAL_BLE_GATT_WRITE (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_WRITE_LONG +#define MYNEWT_VAL_BLE_GATT_WRITE_LONG (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_WRITE_MAX_ATTRS +#define MYNEWT_VAL_BLE_GATT_WRITE_MAX_ATTRS (4) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_WRITE_NO_RSP +#define MYNEWT_VAL_BLE_GATT_WRITE_NO_RSP (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_GATT_WRITE_RELIABLE +#define MYNEWT_VAL_BLE_GATT_WRITE_RELIABLE (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + +#ifndef MYNEWT_VAL_BLE_HOST +#define MYNEWT_VAL_BLE_HOST (1) +#endif + +#ifndef MYNEWT_VAL_ESP_BLE_MESH +#ifdef CONFIG_BLE_MESH_HCI_5_0 +#define MYNEWT_VAL_ESP_BLE_MESH (1) +#else +#define MYNEWT_VAL_ESP_BLE_MESH (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_HS_DEBUG +#ifdef CONFIG_BT_NIMBLE_DEBUG +#define MYNEWT_VAL_BLE_HS_DEBUG (1) +#else +#define MYNEWT_VAL_BLE_HS_DEBUG (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS +#ifdef CONFIG_BT_NIMBLE_SM_SC_DEBUG_KEYS +#define MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS (1) +#else +#define MYNEWT_VAL_BLE_SM_SC_DEBUG_KEYS (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_HS_AUTO_START +#define MYNEWT_VAL_BLE_HS_AUTO_START (1) +#endif + +#ifndef MYNEWT_VAL_BLE_HS_FLOW_CTRL +#ifdef CONFIG_BT_NIMBLE_HS_FLOW_CTRL +#define MYNEWT_VAL_BLE_HS_FLOW_CTRL (1) +#else +#define MYNEWT_VAL_BLE_HS_FLOW_CTRL (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_HS_FLOW_CTRL_ITVL +#define MYNEWT_VAL_BLE_HS_FLOW_CTRL_ITVL CONFIG_BT_NIMBLE_HS_FLOW_CTRL_ITVL +#endif + +#ifndef MYNEWT_VAL_BLE_HS_FLOW_CTRL_THRESH +#define MYNEWT_VAL_BLE_HS_FLOW_CTRL_THRESH CONFIG_BT_NIMBLE_HS_FLOW_CTRL_THRESH +#endif + +#ifndef MYNEWT_VAL_BLE_HS_FLOW_CTRL_TX_ON_DISCONNECT +#define MYNEWT_VAL_BLE_HS_FLOW_CTRL_TX_ON_DISCONNECT CONFIG_BT_NIMBLE_HS_FLOW_CTRL_TX_ON_DISCONNECT +#endif + +#ifndef MYNEWT_VAL_BLE_HS_PHONY_HCI_ACKS +#define MYNEWT_VAL_BLE_HS_PHONY_HCI_ACKS (0) +#endif + +#ifndef MYNEWT_VAL_BLE_HS_REQUIRE_OS +#define MYNEWT_VAL_BLE_HS_REQUIRE_OS (1) +#endif + +#ifndef MYNEWT_VAL_BLE_L2CAP_COC_MAX_NUM +#define MYNEWT_VAL_BLE_L2CAP_COC_MAX_NUM CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM +#endif + +#ifndef MYNEWT_VAL_BLE_L2CAP_JOIN_RX_FRAGS +#define MYNEWT_VAL_BLE_L2CAP_JOIN_RX_FRAGS (1) +#endif + +#ifndef MYNEWT_VAL_BLE_L2CAP_MAX_CHANS +#define MYNEWT_VAL_BLE_L2CAP_MAX_CHANS (3*MYNEWT_VAL_BLE_MAX_CONNECTIONS) +#endif + +#ifndef MYNEWT_VAL_BLE_L2CAP_RX_FRAG_TIMEOUT +#define MYNEWT_VAL_BLE_L2CAP_RX_FRAG_TIMEOUT (30000) +#endif + +#ifndef MYNEWT_VAL_BLE_L2CAP_SIG_MAX_PROCS +#define MYNEWT_VAL_BLE_L2CAP_SIG_MAX_PROCS (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH +#ifdef CONFIG_BT_NIMBLE_MESH +#define MYNEWT_VAL_BLE_MESH (1) +#else +#define MYNEWT_VAL_BLE_MESH (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_CONSOLE_BUFFER_SIZE +#define MYNEWT_VAL_BLE_MONITOR_CONSOLE_BUFFER_SIZE (128) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_RTT +#define MYNEWT_VAL_BLE_MONITOR_RTT (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFERED +#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFERED (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_NAME +#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_NAME ("monitor") +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_SIZE +#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_SIZE (256) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_UART +#define MYNEWT_VAL_BLE_MONITOR_UART (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_UART_BAUDRATE +#define MYNEWT_VAL_BLE_MONITOR_UART_BAUDRATE (1000000) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_UART_BUFFER_SIZE +#define MYNEWT_VAL_BLE_MONITOR_UART_BUFFER_SIZE (64) +#endif + +#ifndef MYNEWT_VAL_BLE_MONITOR_UART_DEV +#define MYNEWT_VAL_BLE_MONITOR_UART_DEV ("uart0") +#endif + +#ifndef MYNEWT_VAL_BLE_HOST_BASED_PRIVACY +#define MYNEWT_VAL_BLE_HOST_BASED_PRIVACY (1) +#endif + +#ifndef MYNEWT_VAL_BLE_RPA_TIMEOUT +#define MYNEWT_VAL_BLE_RPA_TIMEOUT (CONFIG_BT_NIMBLE_RPA_TIMEOUT) +#endif + +#ifndef MYNEWT_VAL_BLE_SM_BONDING +#define MYNEWT_VAL_BLE_SM_BONDING (1) +#endif + +#ifndef MYNEWT_VAL_BLE_SM_IO_CAP +#define MYNEWT_VAL_BLE_SM_IO_CAP (BLE_HS_IO_NO_INPUT_OUTPUT) +#endif + +#ifndef MYNEWT_VAL_BLE_SM_KEYPRESS +#define MYNEWT_VAL_BLE_SM_KEYPRESS (0) +#endif + +#ifndef MYNEWT_VAL_BLE_SM_LEGACY +#ifdef CONFIG_BT_NIMBLE_SM_LEGACY +#define MYNEWT_VAL_BLE_SM_LEGACY (1) +#else +#define MYNEWT_VAL_BLE_SM_LEGACY (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_SM_MAX_PROCS +#define MYNEWT_VAL_BLE_SM_MAX_PROCS (1) +#endif + +#ifndef MYNEWT_VAL_BLE_SM_MITM +#define MYNEWT_VAL_BLE_SM_MITM (0) +#endif + +#ifndef MYNEWT_VAL_BLE_SM_OOB_DATA_FLAG +#define MYNEWT_VAL_BLE_SM_OOB_DATA_FLAG (0) +#endif + +#ifndef MYNEWT_VAL_BLE_SM_OUR_KEY_DIST +#define MYNEWT_VAL_BLE_SM_OUR_KEY_DIST (0) +#endif + +#ifndef MYNEWT_VAL_BLE_SM_SC +#ifdef CONFIG_BT_NIMBLE_SM_SC +#define MYNEWT_VAL_BLE_SM_SC (1) +#else +#define MYNEWT_VAL_BLE_SM_SC (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_SM_THEIR_KEY_DIST +#define MYNEWT_VAL_BLE_SM_THEIR_KEY_DIST (0) +#endif + +#ifndef MYNEWT_VAL_BLE_CRYPTO_STACK_MBEDTLS +#define MYNEWT_VAL_BLE_CRYPTO_STACK_MBEDTLS (CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS) +#endif + +#ifndef MYNEWT_VAL_BLE_STORE_MAX_BONDS +#define MYNEWT_VAL_BLE_STORE_MAX_BONDS CONFIG_BT_NIMBLE_MAX_BONDS +#endif + +#ifndef MYNEWT_VAL_BLE_STORE_MAX_CCCDS +#define MYNEWT_VAL_BLE_STORE_MAX_CCCDS CONFIG_BT_NIMBLE_MAX_CCCDS +#endif + +#ifndef MYNEWT_VAL_BLE_STORE_CONFIG_PERSIST +#ifdef CONFIG_BT_NIMBLE_NVS_PERSIST +#define MYNEWT_VAL_BLE_STORE_CONFIG_PERSIST (1) +#else +#define MYNEWT_VAL_BLE_STORE_CONFIG_PERSIST (0) +#endif +#endif + +/*** nimble/host/services/ans */ +#ifndef MYNEWT_VAL_BLE_SVC_ANS_NEW_ALERT_CAT +#define MYNEWT_VAL_BLE_SVC_ANS_NEW_ALERT_CAT (0) +#endif + + +#ifndef MYNEWT_VAL_BLE_SVC_ANS_UNR_ALERT_CAT +#define MYNEWT_VAL_BLE_SVC_ANS_UNR_ALERT_CAT (0) +#endif + +/*** nimble/host/services/bas */ +#ifndef MYNEWT_VAL_BLE_SVC_BAS_BATTERY_LEVEL_NOTIFY_ENABLE +#define MYNEWT_VAL_BLE_SVC_BAS_BATTERY_LEVEL_NOTIFY_ENABLE (1) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_BAS_BATTERY_LEVEL_READ_PERM +#define MYNEWT_VAL_BLE_SVC_BAS_BATTERY_LEVEL_READ_PERM (0) +#endif +#ifndef MYNEWT_VAL_BLE_MESH_ADV_TASK_PRIO +#define MYNEWT_VAL_BLE_MESH_ADV_TASK_PRIO (9) +#endif + + +/*** @apache-mynewt-nimble/nimble/host/mesh */ +/* Overridden by apps/blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_ADV_BUF_COUNT +#define MYNEWT_VAL_BLE_MESH_ADV_BUF_COUNT (20) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_APP_KEY_COUNT +#define MYNEWT_VAL_BLE_MESH_APP_KEY_COUNT (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_CFG_CLI +#define MYNEWT_VAL_BLE_MESH_CFG_CLI (0) +#endif +#ifndef MYNEWT_VAL_BLE_MESH_CRPL +#define MYNEWT_VAL_BLE_MESH_CRPL (10) +#endif + +/* Overridden by apps/blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_DEBUG +#define MYNEWT_VAL_BLE_MESH_DEBUG (1) +#endif + +/* Overridden by apps/blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_DEBUG_ACCESS +#define MYNEWT_VAL_BLE_MESH_DEBUG_ACCESS (1) +#endif + +/* Overridden by apps/blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_DEBUG_ADV +#define MYNEWT_VAL_BLE_MESH_DEBUG_ADV (1) +#endif + +/* Overridden by apps/blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_DEBUG +#define MYNEWT_VAL_BLE_MESH_DEBUG (1) +#endif + +/* Overridden by apps/blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_DEBUG_ACCESS +#define MYNEWT_VAL_BLE_MESH_DEBUG_ACCESS (1) +#endif + +/* Overridden by apps/blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_DEBUG_ADV +#define MYNEWT_VAL_BLE_MESH_DEBUG_ADV (1) +#endif + +/* Overridden by apps/blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_DEBUG_BEACON +#define MYNEWT_VAL_BLE_MESH_DEBUG_BEACON (1) +#endif + +/* Overridden by apps/blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_DEBUG_CRYPTO +#define MYNEWT_VAL_BLE_MESH_DEBUG_CRYPTO (1) +#endif + +/* Overridden by apps/blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_DEBUG_FRIEND +#define MYNEWT_VAL_BLE_MESH_DEBUG_FRIEND (1) +#endif + +/* Overridden by apps/blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_DEBUG_LOW_POWER +#define MYNEWT_VAL_BLE_MESH_DEBUG_LOW_POWER (1) +#endif + +/* Overridden by apps/blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_DEBUG_MODEL +#define MYNEWT_VAL_BLE_MESH_DEBUG_MODEL (1) +#endif + +/* Overridden by apps/blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_DEBUG_NET +#define MYNEWT_VAL_BLE_MESH_DEBUG_NET (1) +#endif + +/* Overridden by apps/blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_DEBUG_PROV +#define MYNEWT_VAL_BLE_MESH_DEBUG_PROV (1) +#endif + +/* Overridden by apps/blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_DEBUG_PROXY +#define MYNEWT_VAL_BLE_MESH_DEBUG_PROXY (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_DEBUG_SETTINGS +#define MYNEWT_VAL_BLE_MESH_DEBUG_SETTINGS (1) +#endif + +/* Overridden by apps/blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_DEBUG_TRANS +#define MYNEWT_VAL_BLE_MESH_DEBUG_TRANS (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_DEVICE_NAME +#define MYNEWT_VAL_BLE_MESH_DEVICE_NAME CONFIG_BT_NIMBLE_MESH_DEVICE_NAME +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_DEV_UUID +#define MYNEWT_VAL_BLE_MESH_DEV_UUID (((uint8_t[16]){0x11, 0x22, 0})) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_FRIEND +#ifdef CONFIG_BT_NIMBLE_MESH_FRIEND +#define MYNEWT_VAL_BLE_MESH_FRIEND (1) +#else +#define MYNEWT_VAL_BLE_MESH_FRIEND (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_FRIEND_LPN_COUNT +#define MYNEWT_VAL_BLE_MESH_FRIEND_LPN_COUNT (2) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_FRIEND_QUEUE_SIZE +#define MYNEWT_VAL_BLE_MESH_FRIEND_QUEUE_SIZE (16) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_FRIEND_RECV_WIN +#define MYNEWT_VAL_BLE_MESH_FRIEND_RECV_WIN (255) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_FRIEND_SEG_RX +#define MYNEWT_VAL_BLE_MESH_FRIEND_SEG_RX (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_FRIEND_SUB_LIST_SIZE +#define MYNEWT_VAL_BLE_MESH_FRIEND_SUB_LIST_SIZE (3) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_GATT_PROXY +#ifdef CONFIG_BT_NIMBLE_MESH_GATT_PROXY +#define MYNEWT_VAL_BLE_MESH_GATT_PROXY (1) +#else +#define MYNEWT_VAL_BLE_MESH_GATT_PROXY (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_HEALTH_CLI +#define MYNEWT_VAL_BLE_MESH_HEALTH_CLI (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_IVU_DIVIDER +#define MYNEWT_VAL_BLE_MESH_IVU_DIVIDER (4) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_IV_UPDATE_TEST +#define MYNEWT_VAL_BLE_MESH_IV_UPDATE_TEST (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_LABEL_COUNT +#define MYNEWT_VAL_BLE_MESH_LABEL_COUNT (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_LOW_POWER +#ifdef CONFIG_BT_NIMBLE_MESH_LOW_POWER +#define MYNEWT_VAL_BLE_MESH_LOW_POWER (1) +#else +#define MYNEWT_VAL_BLE_MESH_LOW_POWER (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_LPN_AUTO +#define MYNEWT_VAL_BLE_MESH_LPN_AUTO (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_LPN_AUTO_TIMEOUT +#define MYNEWT_VAL_BLE_MESH_LPN_AUTO_TIMEOUT (15) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_LPN_ESTABLISHMENT +#define MYNEWT_VAL_BLE_MESH_LPN_ESTABLISHMENT (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_LPN_GROUPS +#define MYNEWT_VAL_BLE_MESH_LPN_GROUPS (10) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_LPN_INIT_POLL_TIMEOUT +#define MYNEWT_VAL_BLE_MESH_LPN_INIT_POLL_TIMEOUT (MYNEWT_VAL_BLE_MESH_LPN_POLL_TIMEOUT) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_LPN_MIN_QUEUE_SIZE +#define MYNEWT_VAL_BLE_MESH_LPN_MIN_QUEUE_SIZE (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_LPN_POLL_TIMEOUT +#define MYNEWT_VAL_BLE_MESH_LPN_POLL_TIMEOUT (300) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_LPN_RECV_DELAY +#define MYNEWT_VAL_BLE_MESH_LPN_RECV_DELAY (100) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_LPN_RECV_WIN_FACTOR +#define MYNEWT_VAL_BLE_MESH_LPN_RECV_WIN_FACTOR (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_LPN_RETRY_TIMEOUT +#define MYNEWT_VAL_BLE_MESH_LPN_RETRY_TIMEOUT (8) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_LPN_RSSI_FACTOR +#define MYNEWT_VAL_BLE_MESH_LPN_RSSI_FACTOR (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_LPN_SCAN_LATENCY +#define MYNEWT_VAL_BLE_MESH_LPN_SCAN_LATENCY (10) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_MODEL_GROUP_COUNT +#define MYNEWT_VAL_BLE_MESH_MODEL_GROUP_COUNT (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_MODEL_KEY_COUNT +#define MYNEWT_VAL_BLE_MESH_MODEL_KEY_COUNT (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_MSG_CACHE_SIZE +#define MYNEWT_VAL_BLE_MESH_MSG_CACHE_SIZE (10) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_NODE_ID_TIMEOUT +#define MYNEWT_VAL_BLE_MESH_NODE_ID_TIMEOUT (60) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_OOB_INPUT_ACTIONS +#define MYNEWT_VAL_BLE_MESH_OOB_INPUT_ACTIONS (((BT_MESH_NO_INPUT))) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_OOB_INPUT_SIZE +#define MYNEWT_VAL_BLE_MESH_OOB_INPUT_SIZE (4) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_OOB_OUTPUT_ACTIONS +#define MYNEWT_VAL_BLE_MESH_OOB_OUTPUT_ACTIONS (((BT_MESH_DISPLAY_NUMBER))) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_OOB_OUTPUT_SIZE +#define MYNEWT_VAL_BLE_MESH_OOB_OUTPUT_SIZE (4) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_PB_ADV +#ifdef CONFIG_BT_NIMBLE_MESH_PB_ADV +#define MYNEWT_VAL_BLE_MESH_PB_ADV (1) +#else +#define MYNEWT_VAL_BLE_MESH_PB_ADV (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_PB_GATT +#ifdef CONFIG_BT_NIMBLE_MESH_PB_GATT +#define MYNEWT_VAL_BLE_MESH_PB_GATT (1) +#else +#define MYNEWT_VAL_BLE_MESH_PB_GATT (0) +#endif +#endif + +/* Overridden by @apache-mynewt-nimble/nimble/host/mesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_PROV +#ifdef CONFIG_BT_NIMBLE_MESH_PROV +#define MYNEWT_VAL_BLE_MESH_PROV (1) +#else +#define MYNEWT_VAL_BLE_MESH_PROV (0) +#endif +#endif + +/* Overridden by @apache-mynewt-nimble/nimble/host/mesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_PROXY +#ifdef CONFIG_BT_NIMBLE_MESH_PROXY +#define MYNEWT_VAL_BLE_MESH_PROXY (1) +#else +#define MYNEWT_VAL_BLE_MESH_PROXY (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_PROXY_FILTER_SIZE +#define MYNEWT_VAL_BLE_MESH_PROXY_FILTER_SIZE (1) +#endif + + +#ifndef MYNEWT_VAL_BLE_MESH_RELAY +#ifdef CONFIG_BT_NIMBLE_MESH_RELAY +#define MYNEWT_VAL_BLE_MESH_RELAY (1) +#else +#define MYNEWT_VAL_BLE_MESH_RELAY (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_RPL_STORE_TIMEOUT +#define MYNEWT_VAL_BLE_MESH_RPL_STORE_TIMEOUT (5) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_RX_SDU_MAX +#define MYNEWT_VAL_BLE_MESH_RX_SDU_MAX (72) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_RX_SEG_MSG_COUNT +#define MYNEWT_VAL_BLE_MESH_RX_SEG_MSG_COUNT (2) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_SEQ_STORE_RATE +#define MYNEWT_VAL_BLE_MESH_SEQ_STORE_RATE (128) +#endif + +/* Overridden by apps/blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_SETTINGS +#define MYNEWT_VAL_BLE_MESH_SETTINGS (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_SHELL +#define MYNEWT_VAL_BLE_MESH_SHELL (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_SHELL_MODELS +#define MYNEWT_VAL_BLE_MESH_SHELL_MODELS (0) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_STORE_TIMEOUT +#define MYNEWT_VAL_BLE_MESH_STORE_TIMEOUT (2) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_SUBNET_COUNT +#define MYNEWT_VAL_BLE_MESH_SUBNET_COUNT (1) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_TESTING +#define MYNEWT_VAL_BLE_MESH_TESTING (0) +#endif + +/* Overridden by apps/blemesh (defined by @apache-mynewt-nimble/nimble/host/mesh) */ +#ifndef MYNEWT_VAL_BLE_MESH_TX_SEG_MAX +#define MYNEWT_VAL_BLE_MESH_TX_SEG_MAX (6) +#endif + +#ifndef MYNEWT_VAL_BLE_MESH_TX_SEG_MSG_COUNT +#define MYNEWT_VAL_BLE_MESH_TX_SEG_MSG_COUNT (4) +#endif + +/*** @apache-mynewt-nimble/nimble/host/services/gap */ +#ifndef MYNEWT_VAL_BLE_SVC_GAP_APPEARANCE +#define MYNEWT_VAL_BLE_SVC_GAP_APPEARANCE CONFIG_BT_NIMBLE_SVC_GAP_APPEARANCE +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_GAP_APPEARANCE_WRITE_PERM +#define MYNEWT_VAL_BLE_SVC_GAP_APPEARANCE_WRITE_PERM (-1) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_GAP_CENTRAL_ADDRESS_RESOLUTION +#define MYNEWT_VAL_BLE_SVC_GAP_CENTRAL_ADDRESS_RESOLUTION (-1) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME +#define MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME CONFIG_BT_NIMBLE_SVC_GAP_DEVICE_NAME +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME_MAX_LENGTH +#define MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME_MAX_LENGTH CONFIG_BT_NIMBLE_GAP_DEVICE_NAME_MAX_LEN +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME_WRITE_PERM +#define MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME_WRITE_PERM (-1) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL +#define MYNEWT_VAL_BLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL (0) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL +#define MYNEWT_VAL_BLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL (0) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_GAP_PPCP_SLAVE_LATENCY +#define MYNEWT_VAL_BLE_SVC_GAP_PPCP_SLAVE_LATENCY (0) +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_GAP_PPCP_SUPERVISION_TMO +#define MYNEWT_VAL_BLE_SVC_GAP_PPCP_SUPERVISION_TMO (0) +#endif + +/*** nimble/transport */ +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_EMSPI +#define MYNEWT_VAL_BLE_HCI_TRANSPORT_EMSPI (0) +#endif + +/* Overridden by targets/porting-nimble (defined by nimble/transport) */ +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_NIMBLE_BUILTIN +#define MYNEWT_VAL_BLE_HCI_TRANSPORT_NIMBLE_BUILTIN (0) +#endif + +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_RAM +#define MYNEWT_VAL_BLE_HCI_TRANSPORT_RAM (0) +#endif + +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_SOCKET +#define MYNEWT_VAL_BLE_HCI_TRANSPORT_SOCKET (0) +#endif + +/* Overridden by targets/porting-nimble (defined by nimble/transport) */ +#ifndef MYNEWT_VAL_BLE_HCI_TRANSPORT_UART +#define MYNEWT_VAL_BLE_HCI_TRANSPORT_UART (1) +#endif + +/*** nimble/transport/uart */ +#ifndef MYNEWT_VAL_BLE_ACL_BUF_COUNT +#define MYNEWT_VAL_BLE_ACL_BUF_COUNT CONFIG_BT_NIMBLE_ACL_BUF_COUNT +#endif + +#ifndef MYNEWT_VAL_BLE_ACL_BUF_SIZE +#define MYNEWT_VAL_BLE_ACL_BUF_SIZE CONFIG_BT_NIMBLE_ACL_BUF_SIZE +#endif + +#ifndef MYNEWT_VAL_BLE_HCI_ACL_OUT_COUNT +#define MYNEWT_VAL_BLE_HCI_ACL_OUT_COUNT (12) +#endif + +#ifndef MYNEWT_VAL_BLE_HCI_EVT_BUF_SIZE +#define MYNEWT_VAL_BLE_HCI_EVT_BUF_SIZE CONFIG_BT_NIMBLE_HCI_EVT_BUF_SIZE +#endif + +#ifndef MYNEWT_VAL_BLE_HCI_EVT_HI_BUF_COUNT +#define MYNEWT_VAL_BLE_HCI_EVT_HI_BUF_COUNT CONFIG_BT_NIMBLE_HCI_EVT_HI_BUF_COUNT +#endif + +#ifndef MYNEWT_VAL_BLE_HCI_EVT_LO_BUF_COUNT +#define MYNEWT_VAL_BLE_HCI_EVT_LO_BUF_COUNT CONFIG_BT_NIMBLE_HCI_EVT_LO_BUF_COUNT +#endif + +/* Overridden by targets/porting-nimble (defined by nimble/transport/uart) */ +#ifndef MYNEWT_VAL_BLE_HCI_UART_BAUD +#define MYNEWT_VAL_BLE_HCI_UART_BAUD (115200) +#endif + +#ifndef MYNEWT_VAL_BLE_HCI_UART_DATA_BITS +#define MYNEWT_VAL_BLE_HCI_UART_DATA_BITS (8) +#endif + +/* Overridden by targets/porting-nimble (defined by nimble/transport/uart) */ +#ifndef MYNEWT_VAL_BLE_HCI_UART_FLOW_CTRL +#define MYNEWT_VAL_BLE_HCI_UART_FLOW_CTRL (0) +#endif + +#ifndef MYNEWT_VAL_BLE_HCI_UART_PARITY +#define MYNEWT_VAL_BLE_HCI_UART_PARITY (HAL_UART_PARITY_NONE) +#endif + +#ifndef MYNEWT_VAL_BLE_HCI_UART_PORT +#define MYNEWT_VAL_BLE_HCI_UART_PORT (0) +#endif + +#ifndef MYNEWT_VAL_BLE_HCI_UART_STOP_BITS +#define MYNEWT_VAL_BLE_HCI_UART_STOP_BITS (1) +#endif + +#endif diff --git a/libesp32/NimBLE-Arduino/src/esp_nimble_hci.h b/libesp32/NimBLE-Arduino/src/esp_nimble_hci.h new file mode 100644 index 000000000..e10436f3c --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/esp_nimble_hci.h @@ -0,0 +1,138 @@ +/* + * Copyright 2019 Espressif Systems (Shanghai) PTE LTD + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef __ESP_NIMBLE_HCI_H__ +#define __ESP_NIMBLE_HCI_H__ + +#include "nimble/ble_hci_trans.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define BLE_HCI_UART_H4_NONE 0x00 +#define BLE_HCI_UART_H4_CMD 0x01 +#define BLE_HCI_UART_H4_ACL 0x02 +#define BLE_HCI_UART_H4_SCO 0x03 +#define BLE_HCI_UART_H4_EVT 0x04 + +/** + * @brief Initialize VHCI transport layer between NimBLE Host and + * ESP Bluetooth controller + * + * This function initializes the transport buffers to be exchanged + * between NimBLE host and ESP controller. It also registers required + * host callbacks with the controller. + * + * @return + * - ESP_OK if the initialization is successful + * - Appropriate error code from esp_err_t in case of an error + */ +esp_err_t esp_nimble_hci_init(void); + +/** + * @brief Initialize ESP Bluetooth controller(link layer) and VHCI transport + * layer between NimBLE Host and ESP Bluetooth controller + * + * This function initializes ESP controller in BLE only mode and the + * transport buffers to be exchanged between NimBLE host and ESP controller. + * It also registers required host callbacks with the controller. + * + * Below is the sequence of APIs to be called to init/enable NimBLE host and ESP controller: + * + * @code{c} + * void ble_host_task(void *param) + * { + * nimble_port_run(); //This function will return only when nimble_port_stop() is executed. + * nimble_port_freertos_deinit(); + * } + * + * int ret = esp_nimble_hci_and_controller_init(); + * if (ret != ESP_OK) { + ESP_LOGE(TAG, "esp_nimble_hci_and_controller_init() failed with error: %d", ret); + * return; + * } + * + * nimble_port_init(); + * + * //Initialize the NimBLE Host configuration + * + * nimble_port_freertos_init(ble_host_task); + * @endcode + * + * nimble_port_freertos_init() is an optional call that creates a new task in which the NimBLE + * host will run. The task function should have a call to nimble_port_run(). If a separate task + * is not required, calling nimble_port_run() will run the NimBLE host in the current task. + * + * @return + * - ESP_OK if the initialization is successful + * - Appropriate error code from esp_err_t in case of an error + */ +esp_err_t esp_nimble_hci_and_controller_init(void); + +/** + * @brief Deinitialize VHCI transport layer between NimBLE Host and + * ESP Bluetooth controller + * + * @note This function should be called after the NimBLE host is deinitialized. + * + * @return + * - ESP_OK if the deinitialization is successful + * - Appropriate error codes from esp_err_t in case of an error + */ +esp_err_t esp_nimble_hci_deinit(void); + +/** + * @brief Deinitialize VHCI transport layer between NimBLE Host and + * ESP Bluetooth controller and disable and deinitialize the controller + * + * @note This function should not be executed in the context of Bluetooth host task. + * + * @note This function should be called after the NimBLE host is deinitialized. + * + * Below is the sequence of APIs to be called to disable/deinit NimBLE host and ESP controller: + * + * @code{c} + * int ret = nimble_port_stop(); + * if (ret == 0) { + * nimble_port_deinit(); + * + * ret = esp_nimble_hci_and_controller_deinit(); + * if (ret != ESP_OK) { + ESP_LOGE(TAG, "esp_nimble_hci_and_controller_deinit() failed with error: %d", ret); + * } + * } + * @endcode + * + * If nimble_port_freertos_init() is used during initialization, then + * nimble_port_freertos_deinit() should be called in the host task after nimble_port_run(). + * + * @return + * - ESP_OK if the deinitialization is successful + * - Appropriate error codes from esp_err_t in case of an error + */ +esp_err_t esp_nimble_hci_and_controller_deinit(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __ESP_NIMBLE_HCI_H__ */ diff --git a/libesp32/NimBLE-Arduino/src/esp_nimble_mem.h b/libesp32/NimBLE-Arduino/src/esp_nimble_mem.h new file mode 100644 index 000000000..90e52a20d --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/esp_nimble_mem.h @@ -0,0 +1,39 @@ +/* + * Copyright 2020 Espressif Systems (Shanghai) PTE LTD + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef __ESP_NIMBLE_MEM_H__ +#define __ESP_NIMBLE_MEM_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void *nimble_platform_mem_malloc(size_t size); +void *nimble_platform_mem_calloc(size_t n, size_t size); +void nimble_platform_mem_free(void *ptr); + +#ifdef __cplusplus +} +#endif + +#endif /* __ESP_NIMBLE_MEM_H__ */ diff --git a/libesp32/NimBLE-Arduino/src/ext/tinycrypt/AUTHORS b/libesp32/NimBLE-Arduino/src/ext/tinycrypt/AUTHORS new file mode 100644 index 000000000..0a8e9f806 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/ext/tinycrypt/AUTHORS @@ -0,0 +1,15 @@ +Architect: +Rafael Misoczki + +Open Source Maintainer: +Constanza Heath +Rafael Misoczki + +Contributors: +Constanza Heath +Rafael Misoczki +Flavio Santes +Jarkko Sakkinen +Chris Morrison +Marti Bolivar +Colin Ian King diff --git a/libesp32/NimBLE-Arduino/src/ext/tinycrypt/LICENSE b/libesp32/NimBLE-Arduino/src/ext/tinycrypt/LICENSE new file mode 100644 index 000000000..2e1db516a --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/ext/tinycrypt/LICENSE @@ -0,0 +1,61 @@ + +================================================================================ + + TinyCrypt Cryptographic Library + +================================================================================ + + Copyright (c) 2017, Intel Corporation. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + - Neither the name of the Intel Corporation nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +================================================================================ +Copyright (c) 2014, Kenneth MacKay +All rights reserved. + +https://github.com/kmackay/micro-ecc + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +================================================================================ diff --git a/libesp32/NimBLE-Arduino/src/ext/tinycrypt/README b/libesp32/NimBLE-Arduino/src/ext/tinycrypt/README new file mode 100644 index 000000000..fb52c196a --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/ext/tinycrypt/README @@ -0,0 +1,71 @@ + +================================================================================ + + TinyCrypt Cryptographic Library + +================================================================================ + + Copyright (c) 2017, Intel Corporation. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + - Neither the name of the Intel Corporation nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +================================================================================ + +Overview: + +The TinyCrypt Library provides an implementation for constrained devices of a +minimal set of standard cryptography primitives. + +Please, ***SEE THE DOCUMENTATION*** folder for more information on the supported +cryptographic primitives and the limitations of TinyCrypt library. For usage, +security and technicalities, please see the corresponding header file of each +cryptographic primitive. + +================================================================================ + +Organization: + +/lib: C source code of the cryptographic primitives. +/lib/include/tinycrypt: C header files of the cryptographic primitives. +/tests: Test vectors of the cryptographic primitives. +/doc: Documentation of TinyCrypt. + +================================================================================ + +Building: + +1) In Makefile.conf set: + - CFLAGS for compiler flags. + - CC for compiler. + - ENABLE_TESTS for enabling (true) or disabling (false) tests compilation. +2) In lib/Makefile select the primitives required by your project. +3) In tests/Makefile select the corresponding tests of the selected primitives. +4) make +5) run tests in tests/ + +================================================================================ + diff --git a/libesp32/NimBLE-Arduino/src/ext/tinycrypt/VERSION b/libesp32/NimBLE-Arduino/src/ext/tinycrypt/VERSION new file mode 100644 index 000000000..a45be4627 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/ext/tinycrypt/VERSION @@ -0,0 +1 @@ +0.2.8 diff --git a/libesp32/NimBLE-Arduino/src/ext/tinycrypt/documentation/tinycrypt.rst b/libesp32/NimBLE-Arduino/src/ext/tinycrypt/documentation/tinycrypt.rst new file mode 100644 index 000000000..356c099a0 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/ext/tinycrypt/documentation/tinycrypt.rst @@ -0,0 +1,352 @@ + +TinyCrypt Cryptographic Library +############################### +Copyright (C) 2017 by Intel Corporation, All Rights Reserved. + +Overview +******** +The TinyCrypt Library provides an implementation for targeting constrained devices +with a minimal set of standard cryptography primitives, as listed below. To better +serve applications targeting constrained devices, TinyCrypt implementations differ +from the standard specifications (see the Important Remarks section for some +important differences). Certain cryptographic primitives depend on other +primitives, as mentioned in the list below. + +Aside from the Important Remarks section below, valuable information on the usage, +security and technicalities of each cryptographic primitive are found in the +corresponding header file. + +* SHA-256: + + * Type of primitive: Hash function. + * Standard Specification: NIST FIPS PUB 180-4. + * Requires: -- + +* HMAC-SHA256: + + * Type of primitive: Message authentication code. + * Standard Specification: RFC 2104. + * Requires: SHA-256 + +* HMAC-PRNG: + + * Type of primitive: Pseudo-random number generator (256-bit strength). + * Standard Specification: NIST SP 800-90A. + * Requires: SHA-256 and HMAC-SHA256. + +* AES-128: + + * Type of primitive: Block cipher. + * Standard Specification: NIST FIPS PUB 197. + * Requires: -- + +* AES-CBC mode: + + * Type of primitive: Encryption mode of operation. + * Standard Specification: NIST SP 800-38A. + * Requires: AES-128. + +* AES-CTR mode: + + * Type of primitive: Encryption mode of operation. + * Standard Specification: NIST SP 800-38A. + * Requires: AES-128. + +* AES-CMAC mode: + + * Type of primitive: Message authentication code. + * Standard Specification: NIST SP 800-38B. + * Requires: AES-128. + +* AES-CCM mode: + + * Type of primitive: Authenticated encryption. + * Standard Specification: NIST SP 800-38C. + * Requires: AES-128. + +* CTR-PRNG: + + * Type of primitive: Pseudo-random number generator (128-bit strength). + * Standard Specification: NIST SP 800-90A. + * Requires: AES-128. + +* ECC-DH: + + * Type of primitive: Key exchange based on curve NIST p-256. + * Standard Specification: RFC 6090. + * Requires: ECC auxiliary functions (ecc.h/c). + +* ECC-DSA: + + * Type of primitive: Digital signature based on curve NIST p-256. + * Standard Specification: RFC 6090. + * Requires: ECC auxiliary functions (ecc.h/c). + +Design Goals +************ + +* Minimize the code size of each cryptographic primitive. This means minimize + the size of a platform-independent implementation, as presented in TinyCrypt. + Note that various applications may require further features, optimizations with + respect to other metrics and countermeasures for particular threats. These + peculiarities would increase the code size and thus are not considered here. + +* Minimize the dependencies among the cryptographic primitives. This means + that it is unnecessary to build and allocate object code for more primitives + than the ones strictly required by the intended application. In other words, + one can select and compile only the primitives required by the application. + + +Important Remarks +***************** + +The cryptographic implementations in TinyCrypt library have some limitations. +Some of these limitations are inherent to the cryptographic primitives +themselves, while others are specific to TinyCrypt. These limitations were accepted +in order to meet its design goals (in special, minimal code size) and to better +serve applications targeting constrained devices in general. Some of these +limitations are discussed in-depth below. + +General Remarks +*************** + +* TinyCrypt does **not** intend to be fully side-channel resistant. Due to the + variety of side-channel attacks, many of them only relevant to certain + platforms. In this sense, instead of penalizing all library users with + side-channel countermeasures such as increasing the overall code size, + TinyCrypt only implements certain generic timing-attack countermeasures. + +Specific Remarks +**************** + +* SHA-256: + + * The number of bits_hashed in the state is not checked for overflow. Note + however that this will only be a problem if you intend to hash more than + 2^64 bits, which is an extremely large window. + +* HMAC: + + * The HMAC verification process is assumed to be performed by the application. + This compares the computed tag with some given tag. + Note that conventional memory-comparison methods (such as memcmp function) + might be vulnerable to timing attacks; thus be sure to use a constant-time + memory comparison function (such as compare_constant_time + function provided in lib/utils.c). + + * The tc_hmac_final function, responsible for computing the message tag, + cleans the state context before exiting. Thus, applications do not need to + clean the TCHmacState_t ctx after calling tc_hmac_final. This should not + be changed in future versions of the library as there are applications + currently relying on this good-practice/feature of TinyCrypt. + +* HMAC-PRNG: + + * Before using HMAC-PRNG, you *must* find an entropy source to produce a seed. + PRNGs only stretch the seed into a seemingly random output of arbitrary + length. The security of the output is exactly equal to the + unpredictability of the seed. + + * NIST SP 800-90A requires three items as seed material in the initialization + step: entropy seed, personalization and a nonce (which is not implemented). + TinyCrypt requires the personalization byte array and automatically creates + the entropy seed using a mandatory call to the re-seed function. + +* AES-128: + + * The current implementation does not support other key-lengths (such as 256 + bits). Note that if you need AES-256, it doesn't sound as though your + application is running in a constrained environment. AES-256 requires keys + twice the size as for AES-128, and the key schedule is 40% larger. + +* CTR mode: + + * The AES-CTR mode limits the size of a data message they encrypt to 2^32 + blocks. If you need to encrypt larger data sets, your application would + need to replace the key after 2^32 block encryptions. + +* CTR-PRNG: + + * Before using CTR-PRNG, you *must* find an entropy source to produce a seed. + PRNGs only stretch the seed into a seemingly random output of arbitrary + length. The security of the output is exactly equal to the + unpredictability of the seed. + +* CBC mode: + + * TinyCrypt CBC decryption assumes that the iv and the ciphertext are + contiguous (as produced by TinyCrypt CBC encryption). This allows for a + very efficient decryption algorithm that would not otherwise be possible. + +* CMAC mode: + + * AES128-CMAC mode of operation offers 64 bits of security against collision + attacks. Note however that an external attacker cannot generate the tags + him/herself without knowing the MAC key. In this sense, to attack the + collision property of AES128-CMAC, an external attacker would need the + cooperation of the legal user to produce an exponentially high number of + tags (e.g. 2^64) to finally be able to look for collisions and benefit + from them. As an extra precaution, the current implementation allows to at + most 2^48 calls to tc_cmac_update function before re-calling tc_cmac_setup + (allowing a new key to be set), as suggested in Appendix B of SP 800-38B. + +* CCM mode: + + * There are a few tradeoffs for the selection of the parameters of CCM mode. + In special, there is a tradeoff between the maximum number of invocations + of CCM under a given key and the maximum payload length for those + invocations. Both things are related to the parameter 'q' of CCM mode. The + maximum number of invocations of CCM under a given key is determined by + the nonce size, which is: 15-q bytes. The maximum payload length for those + invocations is defined as 2^(8q) bytes. + + To achieve minimal code size, TinyCrypt CCM implementation fixes q = 2, + which is a quite reasonable choice for constrained applications. The + implications of this choice are: + + The nonce size is: 13 bytes. + + The maximum payload length is: 2^16 bytes = 65 KB. + + The mac size parameter is an important parameter to estimate the security + against collision attacks (that aim at finding different messages that + produce the same authentication tag). TinyCrypt CCM implementation + accepts any even integer between 4 and 16, as suggested in SP 800-38C. + + * TinyCrypt CCM implementation accepts associated data of any length between + 0 and (2^16 - 2^8) = 65280 bytes. + + * TinyCrypt CCM implementation accepts: + + * Both non-empty payload and associated data (it encrypts and + authenticates the payload and only authenticates the associated data); + + * Non-empty payload and empty associated data (it encrypts and + authenticates the payload); + + * Non-empty associated data and empty payload (it degenerates to an + authentication-only mode on the associated data). + + * RFC-3610, which also specifies CCM, presents a few relevant security + suggestions, such as: it is recommended for most applications to use a + mac size greater than 8. Besides, it is emphasized that the usage of the + same nonce for two different messages which are encrypted with the same + key obviously destroys the security properties of CCM mode. + +* ECC-DH and ECC-DSA: + + * TinyCrypt ECC implementation is based on micro-ecc (see + https://github.com/kmackay/micro-ecc). In the original micro-ecc + documentation, there is an important remark about the way integers are + represented: + + "Integer representation: To reduce code size, all large integers are + represented using little-endian words - so the least significant word is + first. You can use the 'ecc_bytes2native()' and 'ecc_native2bytes()' + functions to convert between the native integer representation and the + standardized octet representation." + + Note that the assumed bit layout is: {31, 30, ..., 0}, {63, 62, ..., 32}, + {95, 94, ..., 64}, {127, 126, ..., 96} for a very-long-integer (vli) + consisting of 4 unsigned integers (as an example). + + * A cryptographically-secure PRNG function must be set (using uECC_set_rng()) + before calling uECC_make_key() or uECC_sign(). + +Examples of Applications +************************ +It is possible to do useful cryptography with only the given small set of +primitives. With this list of primitives it becomes feasible to support a range +of cryptography usages: + + * Measurement of code, data structures, and other digital artifacts (SHA256); + + * Generate commitments (SHA256); + + * Construct keys (HMAC-SHA256); + + * Extract entropy from strings containing some randomness (HMAC-SHA256); + + * Construct random mappings (HMAC-SHA256); + + * Construct nonces and challenges (HMAC-PRNG, CTR-PRNG); + + * Authenticate using a shared secret (HMAC-SHA256); + + * Create an authenticated, replay-protected session (HMAC-SHA256 + HMAC-PRNG); + + * Authenticated encryption (AES-128 + AES-CCM); + + * Key-exchange (EC-DH); + + * Digital signature (EC-DSA); + +Test Vectors +************ + +The library provides a test program for each cryptographic primitive (see 'test' +folder). Besides illustrating how to use the primitives, these tests evaluate +the correctness of the implementations by checking the results against +well-known publicly validated test vectors. + +For the case of the HMAC-PRNG, due to the necessity of performing an extensive +battery test to produce meaningful conclusions, we suggest the user to evaluate +the unpredictability of the implementation by using the NIST Statistical Test +Suite (see References). + +For the case of the EC-DH and EC-DSA implementations, most of the test vectors +were obtained from the site of the NIST Cryptographic Algorithm Validation +Program (CAVP), see References. + +References +********** + +* `NIST FIPS PUB 180-4 (SHA-256)`_ + +.. _NIST FIPS PUB 180-4 (SHA-256): + http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf + +* `NIST FIPS PUB 197 (AES-128)`_ + +.. _NIST FIPS PUB 197 (AES-128): + http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf + +* `NIST SP800-90A (HMAC-PRNG)`_ + +.. _NIST SP800-90A (HMAC-PRNG): + http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf + +* `NIST SP 800-38A (AES-CBC and AES-CTR)`_ + +.. _NIST SP 800-38A (AES-CBC and AES-CTR): + http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf + +* `NIST SP 800-38B (AES-CMAC)`_ + +.. _NIST SP 800-38B (AES-CMAC): + http://csrc.nist.gov/publications/nistpubs/800-38B/SP_800-38B.pdf + +* `NIST SP 800-38C (AES-CCM)`_ + +.. _NIST SP 800-38C (AES-CCM): + http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf + +* `NIST Statistical Test Suite (useful for testing HMAC-PRNG)`_ + +.. _NIST Statistical Test Suite (useful for testing HMAC-PRNG): + http://csrc.nist.gov/groups/ST/toolkit/rng/documentation_software.html + +* `NIST Cryptographic Algorithm Validation Program (CAVP) site`_ + +.. _NIST Cryptographic Algorithm Validation Program (CAVP) site: + http://csrc.nist.gov/groups/STM/cavp/ + +* `RFC 2104 (HMAC-SHA256)`_ + +.. _RFC 2104 (HMAC-SHA256): + https://www.ietf.org/rfc/rfc2104.txt + +* `RFC 6090 (ECC-DH and ECC-DSA)`_ + +.. _RFC 6090 (ECC-DH and ECC-DSA): + https://www.ietf.org/rfc/rfc6090.txt diff --git a/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/aes_decrypt.c b/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/aes_decrypt.c new file mode 100644 index 000000000..993a6180c --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/aes_decrypt.c @@ -0,0 +1,164 @@ +/* aes_decrypt.c - TinyCrypt implementation of AES decryption procedure */ + +/* + * Copyright (C) 2017 by Intel Corporation, All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +static const uint8_t inv_sbox[256] = { + 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, + 0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, + 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32, + 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, + 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, + 0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, + 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, + 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, + 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, + 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, + 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91, 0x11, 0x41, + 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, + 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, + 0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, + 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b, + 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, + 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, + 0x27, 0x80, 0xec, 0x5f, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, + 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d, + 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, + 0x55, 0x21, 0x0c, 0x7d +}; + +int tc_aes128_set_decrypt_key(TCAesKeySched_t s, const uint8_t *k) +{ + return tc_aes128_set_encrypt_key(s, k); +} + +#define mult8(a)(_double_byte(_double_byte(_double_byte(a)))) +#define mult9(a)(mult8(a)^(a)) +#define multb(a)(mult8(a)^_double_byte(a)^(a)) +#define multd(a)(mult8(a)^_double_byte(_double_byte(a))^(a)) +#define multe(a)(mult8(a)^_double_byte(_double_byte(a))^_double_byte(a)) + +static inline void mult_row_column(uint8_t *out, const uint8_t *in) +{ + out[0] = multe(in[0]) ^ multb(in[1]) ^ multd(in[2]) ^ mult9(in[3]); + out[1] = mult9(in[0]) ^ multe(in[1]) ^ multb(in[2]) ^ multd(in[3]); + out[2] = multd(in[0]) ^ mult9(in[1]) ^ multe(in[2]) ^ multb(in[3]); + out[3] = multb(in[0]) ^ multd(in[1]) ^ mult9(in[2]) ^ multe(in[3]); +} + +static inline void inv_mix_columns(uint8_t *s) +{ + uint8_t t[Nb*Nk]; + + mult_row_column(t, s); + mult_row_column(&t[Nb], s+Nb); + mult_row_column(&t[2*Nb], s+(2*Nb)); + mult_row_column(&t[3*Nb], s+(3*Nb)); + (void)_copy(s, sizeof(t), t, sizeof(t)); +} + +static inline void add_round_key(uint8_t *s, const unsigned int *k) +{ + s[0] ^= (uint8_t)(k[0] >> 24); s[1] ^= (uint8_t)(k[0] >> 16); + s[2] ^= (uint8_t)(k[0] >> 8); s[3] ^= (uint8_t)(k[0]); + s[4] ^= (uint8_t)(k[1] >> 24); s[5] ^= (uint8_t)(k[1] >> 16); + s[6] ^= (uint8_t)(k[1] >> 8); s[7] ^= (uint8_t)(k[1]); + s[8] ^= (uint8_t)(k[2] >> 24); s[9] ^= (uint8_t)(k[2] >> 16); + s[10] ^= (uint8_t)(k[2] >> 8); s[11] ^= (uint8_t)(k[2]); + s[12] ^= (uint8_t)(k[3] >> 24); s[13] ^= (uint8_t)(k[3] >> 16); + s[14] ^= (uint8_t)(k[3] >> 8); s[15] ^= (uint8_t)(k[3]); +} + +static inline void inv_sub_bytes(uint8_t *s) +{ + unsigned int i; + + for (i = 0; i < (Nb*Nk); ++i) { + s[i] = inv_sbox[s[i]]; + } +} + +/* + * This inv_shift_rows also implements the matrix flip required for + * inv_mix_columns, but performs it here to reduce the number of memory + * operations. + */ +static inline void inv_shift_rows(uint8_t *s) +{ + uint8_t t[Nb*Nk]; + + t[0] = s[0]; t[1] = s[13]; t[2] = s[10]; t[3] = s[7]; + t[4] = s[4]; t[5] = s[1]; t[6] = s[14]; t[7] = s[11]; + t[8] = s[8]; t[9] = s[5]; t[10] = s[2]; t[11] = s[15]; + t[12] = s[12]; t[13] = s[9]; t[14] = s[6]; t[15] = s[3]; + (void)_copy(s, sizeof(t), t, sizeof(t)); +} + +int tc_aes_decrypt(uint8_t *out, const uint8_t *in, const TCAesKeySched_t s) +{ + uint8_t state[Nk*Nb]; + unsigned int i; + + if (out == (uint8_t *) 0) { + return TC_CRYPTO_FAIL; + } else if (in == (const uint8_t *) 0) { + return TC_CRYPTO_FAIL; + } else if (s == (TCAesKeySched_t) 0) { + return TC_CRYPTO_FAIL; + } + + (void)_copy(state, sizeof(state), in, sizeof(state)); + + add_round_key(state, s->words + Nb*Nr); + + for (i = Nr - 1; i > 0; --i) { + inv_shift_rows(state); + inv_sub_bytes(state); + add_round_key(state, s->words + Nb*i); + inv_mix_columns(state); + } + + inv_shift_rows(state); + inv_sub_bytes(state); + add_round_key(state, s->words); + + (void)_copy(out, sizeof(state), state, sizeof(state)); + + /*zeroing out the state buffer */ + _set(state, TC_ZERO_BYTE, sizeof(state)); + + + return TC_CRYPTO_SUCCESS; +} diff --git a/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/aes_encrypt.c b/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/aes_encrypt.c new file mode 100644 index 000000000..8991aee52 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/aes_encrypt.c @@ -0,0 +1,191 @@ +/* aes_encrypt.c - TinyCrypt implementation of AES encryption procedure */ + +/* + * Copyright (C) 2017 by Intel Corporation, All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +static const uint8_t sbox[256] = { + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, + 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, + 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, + 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, + 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, + 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, + 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, + 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, + 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec, + 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, + 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, + 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, + 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, + 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, + 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, + 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, + 0xb0, 0x54, 0xbb, 0x16 +}; + +static inline unsigned int rotword(unsigned int a) +{ + return (((a) >> 24)|((a) << 8)); +} + +#define subbyte(a, o)(sbox[((a) >> (o))&0xff] << (o)) +#define subword(a)(subbyte(a, 24)|subbyte(a, 16)|subbyte(a, 8)|subbyte(a, 0)) + +int tc_aes128_set_encrypt_key(TCAesKeySched_t s, const uint8_t *k) +{ + const unsigned int rconst[11] = { + 0x00000000, 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, + 0x20000000, 0x40000000, 0x80000000, 0x1b000000, 0x36000000 + }; + unsigned int i; + unsigned int t; + + if (s == (TCAesKeySched_t) 0) { + return TC_CRYPTO_FAIL; + } else if (k == (const uint8_t *) 0) { + return TC_CRYPTO_FAIL; + } + + for (i = 0; i < Nk; ++i) { + s->words[i] = (k[Nb*i]<<24) | (k[Nb*i+1]<<16) | + (k[Nb*i+2]<<8) | (k[Nb*i+3]); + } + + for (; i < (Nb * (Nr + 1)); ++i) { + t = s->words[i-1]; + if ((i % Nk) == 0) { + t = subword(rotword(t)) ^ rconst[i/Nk]; + } + s->words[i] = s->words[i-Nk] ^ t; + } + + return TC_CRYPTO_SUCCESS; +} + +static inline void add_round_key(uint8_t *s, const unsigned int *k) +{ + s[0] ^= (uint8_t)(k[0] >> 24); s[1] ^= (uint8_t)(k[0] >> 16); + s[2] ^= (uint8_t)(k[0] >> 8); s[3] ^= (uint8_t)(k[0]); + s[4] ^= (uint8_t)(k[1] >> 24); s[5] ^= (uint8_t)(k[1] >> 16); + s[6] ^= (uint8_t)(k[1] >> 8); s[7] ^= (uint8_t)(k[1]); + s[8] ^= (uint8_t)(k[2] >> 24); s[9] ^= (uint8_t)(k[2] >> 16); + s[10] ^= (uint8_t)(k[2] >> 8); s[11] ^= (uint8_t)(k[2]); + s[12] ^= (uint8_t)(k[3] >> 24); s[13] ^= (uint8_t)(k[3] >> 16); + s[14] ^= (uint8_t)(k[3] >> 8); s[15] ^= (uint8_t)(k[3]); +} + +static inline void sub_bytes(uint8_t *s) +{ + unsigned int i; + + for (i = 0; i < (Nb * Nk); ++i) { + s[i] = sbox[s[i]]; + } +} + +#define triple(a)(_double_byte(a)^(a)) + +static inline void mult_row_column(uint8_t *out, const uint8_t *in) +{ + out[0] = _double_byte(in[0]) ^ triple(in[1]) ^ in[2] ^ in[3]; + out[1] = in[0] ^ _double_byte(in[1]) ^ triple(in[2]) ^ in[3]; + out[2] = in[0] ^ in[1] ^ _double_byte(in[2]) ^ triple(in[3]); + out[3] = triple(in[0]) ^ in[1] ^ in[2] ^ _double_byte(in[3]); +} + +static inline void mix_columns(uint8_t *s) +{ + uint8_t t[Nb*Nk]; + + mult_row_column(t, s); + mult_row_column(&t[Nb], s+Nb); + mult_row_column(&t[2 * Nb], s + (2 * Nb)); + mult_row_column(&t[3 * Nb], s + (3 * Nb)); + (void) _copy(s, sizeof(t), t, sizeof(t)); +} + +/* + * This shift_rows also implements the matrix flip required for mix_columns, but + * performs it here to reduce the number of memory operations. + */ +static inline void shift_rows(uint8_t *s) +{ + uint8_t t[Nb * Nk]; + + t[0] = s[0]; t[1] = s[5]; t[2] = s[10]; t[3] = s[15]; + t[4] = s[4]; t[5] = s[9]; t[6] = s[14]; t[7] = s[3]; + t[8] = s[8]; t[9] = s[13]; t[10] = s[2]; t[11] = s[7]; + t[12] = s[12]; t[13] = s[1]; t[14] = s[6]; t[15] = s[11]; + (void) _copy(s, sizeof(t), t, sizeof(t)); +} + +int tc_aes_encrypt(uint8_t *out, const uint8_t *in, const TCAesKeySched_t s) +{ + uint8_t state[Nk*Nb]; + unsigned int i; + + if (out == (uint8_t *) 0) { + return TC_CRYPTO_FAIL; + } else if (in == (const uint8_t *) 0) { + return TC_CRYPTO_FAIL; + } else if (s == (TCAesKeySched_t) 0) { + return TC_CRYPTO_FAIL; + } + + (void)_copy(state, sizeof(state), in, sizeof(state)); + add_round_key(state, s->words); + + for (i = 0; i < (Nr - 1); ++i) { + sub_bytes(state); + shift_rows(state); + mix_columns(state); + add_round_key(state, s->words + Nb*(i+1)); + } + + sub_bytes(state); + shift_rows(state); + add_round_key(state, s->words + Nb*(i+1)); + + (void)_copy(out, sizeof(state), state, sizeof(state)); + + /* zeroing out the state buffer */ + _set(state, TC_ZERO_BYTE, sizeof(state)); + + return TC_CRYPTO_SUCCESS; +} diff --git a/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/cbc_mode.c b/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/cbc_mode.c new file mode 100644 index 000000000..62d7879eb --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/cbc_mode.c @@ -0,0 +1,114 @@ +/* cbc_mode.c - TinyCrypt implementation of CBC mode encryption & decryption */ + +/* + * Copyright (C) 2017 by Intel Corporation, All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +int tc_cbc_mode_encrypt(uint8_t *out, unsigned int outlen, const uint8_t *in, + unsigned int inlen, const uint8_t *iv, + const TCAesKeySched_t sched) +{ + + uint8_t buffer[TC_AES_BLOCK_SIZE]; + unsigned int n, m; + + /* input sanity check: */ + if (out == (uint8_t *) 0 || + in == (const uint8_t *) 0 || + sched == (TCAesKeySched_t) 0 || + inlen == 0 || + outlen == 0 || + (inlen % TC_AES_BLOCK_SIZE) != 0 || + (outlen % TC_AES_BLOCK_SIZE) != 0 || + outlen != inlen + TC_AES_BLOCK_SIZE) { + return TC_CRYPTO_FAIL; + } + + /* copy iv to the buffer */ + (void)_copy(buffer, TC_AES_BLOCK_SIZE, iv, TC_AES_BLOCK_SIZE); + /* copy iv to the output buffer */ + (void)_copy(out, TC_AES_BLOCK_SIZE, iv, TC_AES_BLOCK_SIZE); + out += TC_AES_BLOCK_SIZE; + + for (n = m = 0; n < inlen; ++n) { + buffer[m++] ^= *in++; + if (m == TC_AES_BLOCK_SIZE) { + (void)tc_aes_encrypt(buffer, buffer, sched); + (void)_copy(out, TC_AES_BLOCK_SIZE, + buffer, TC_AES_BLOCK_SIZE); + out += TC_AES_BLOCK_SIZE; + m = 0; + } + } + + return TC_CRYPTO_SUCCESS; +} + +int tc_cbc_mode_decrypt(uint8_t *out, unsigned int outlen, const uint8_t *in, + unsigned int inlen, const uint8_t *iv, + const TCAesKeySched_t sched) +{ + + uint8_t buffer[TC_AES_BLOCK_SIZE]; + const uint8_t *p; + unsigned int n, m; + + /* sanity check the inputs */ + if (out == (uint8_t *) 0 || + in == (const uint8_t *) 0 || + sched == (TCAesKeySched_t) 0 || + inlen == 0 || + outlen == 0 || + (inlen % TC_AES_BLOCK_SIZE) != 0 || + (outlen % TC_AES_BLOCK_SIZE) != 0 || + outlen != inlen - TC_AES_BLOCK_SIZE) { + return TC_CRYPTO_FAIL; + } + + /* + * Note that in == iv + ciphertext, i.e. the iv and the ciphertext are + * contiguous. This allows for a very efficient decryption algorithm + * that would not otherwise be possible. + */ + p = iv; + for (n = m = 0; n < inlen; ++n) { + if ((n % TC_AES_BLOCK_SIZE) == 0) { + (void)tc_aes_decrypt(buffer, in, sched); + in += TC_AES_BLOCK_SIZE; + m = 0; + } + *out++ = buffer[m++] ^ *p++; + } + + return TC_CRYPTO_SUCCESS; +} diff --git a/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/ccm_mode.c b/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/ccm_mode.c new file mode 100644 index 000000000..929adac63 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/ccm_mode.c @@ -0,0 +1,266 @@ +/* ccm_mode.c - TinyCrypt implementation of CCM mode */ + +/* + * Copyright (C) 2017 by Intel Corporation, All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +#include + +int tc_ccm_config(TCCcmMode_t c, TCAesKeySched_t sched, uint8_t *nonce, + unsigned int nlen, unsigned int mlen) +{ + + /* input sanity check: */ + if (c == (TCCcmMode_t) 0 || + sched == (TCAesKeySched_t) 0 || + nonce == (uint8_t *) 0) { + return TC_CRYPTO_FAIL; + } else if (nlen != 13) { + return TC_CRYPTO_FAIL; /* The allowed nonce size is: 13. See documentation.*/ + } else if ((mlen < 4) || (mlen > 16) || (mlen & 1)) { + return TC_CRYPTO_FAIL; /* The allowed mac sizes are: 4, 6, 8, 10, 12, 14, 16.*/ + } + + c->mlen = mlen; + c->sched = sched; + c->nonce = nonce; + + return TC_CRYPTO_SUCCESS; +} + +/** + * Variation of CBC-MAC mode used in CCM. + */ +static void ccm_cbc_mac(uint8_t *T, const uint8_t *data, unsigned int dlen, + unsigned int flag, TCAesKeySched_t sched) +{ + + unsigned int i; + + if (flag > 0) { + T[0] ^= (uint8_t)(dlen >> 8); + T[1] ^= (uint8_t)(dlen); + dlen += 2; i = 2; + } else { + i = 0; + } + + while (i < dlen) { + T[i++ % (Nb * Nk)] ^= *data++; + if (((i % (Nb * Nk)) == 0) || dlen == i) { + (void) tc_aes_encrypt(T, T, sched); + } + } +} + +/** + * Variation of CTR mode used in CCM. + * The CTR mode used by CCM is slightly different than the conventional CTR + * mode (the counter is increased before encryption, instead of after + * encryption). Besides, it is assumed that the counter is stored in the last + * 2 bytes of the nonce. + */ +static int ccm_ctr_mode(uint8_t *out, unsigned int outlen, const uint8_t *in, + unsigned int inlen, uint8_t *ctr, const TCAesKeySched_t sched) +{ + + uint8_t buffer[TC_AES_BLOCK_SIZE]; + uint8_t nonce[TC_AES_BLOCK_SIZE]; + uint16_t block_num; + unsigned int i; + + /* input sanity check: */ + if (out == (uint8_t *) 0 || + in == (uint8_t *) 0 || + ctr == (uint8_t *) 0 || + sched == (TCAesKeySched_t) 0 || + inlen == 0 || + outlen == 0 || + outlen != inlen) { + return TC_CRYPTO_FAIL; + } + + /* copy the counter to the nonce */ + (void) _copy(nonce, sizeof(nonce), ctr, sizeof(nonce)); + + /* select the last 2 bytes of the nonce to be incremented */ + block_num = (uint16_t) ((nonce[14] << 8)|(nonce[15])); + for (i = 0; i < inlen; ++i) { + if ((i % (TC_AES_BLOCK_SIZE)) == 0) { + block_num++; + nonce[14] = (uint8_t)(block_num >> 8); + nonce[15] = (uint8_t)(block_num); + if (!tc_aes_encrypt(buffer, nonce, sched)) { + return TC_CRYPTO_FAIL; + } + } + /* update the output */ + *out++ = buffer[i % (TC_AES_BLOCK_SIZE)] ^ *in++; + } + + /* update the counter */ + ctr[14] = nonce[14]; ctr[15] = nonce[15]; + + return TC_CRYPTO_SUCCESS; +} + +int tc_ccm_generation_encryption(uint8_t *out, unsigned int olen, + const uint8_t *associated_data, + unsigned int alen, const uint8_t *payload, + unsigned int plen, TCCcmMode_t c) +{ + + /* input sanity check: */ + if ((out == (uint8_t *) 0) || + (c == (TCCcmMode_t) 0) || + ((plen > 0) && (payload == (uint8_t *) 0)) || + ((alen > 0) && (associated_data == (uint8_t *) 0)) || + (alen >= TC_CCM_AAD_MAX_BYTES) || /* associated data size unsupported */ + (plen >= TC_CCM_PAYLOAD_MAX_BYTES) || /* payload size unsupported */ + (olen < (plen + c->mlen))) { /* invalid output buffer size */ + return TC_CRYPTO_FAIL; + } + + uint8_t b[Nb * Nk]; + uint8_t tag[Nb * Nk]; + unsigned int i; + + /* GENERATING THE AUTHENTICATION TAG: */ + + /* formatting the sequence b for authentication: */ + b[0] = ((alen > 0) ? 0x40:0) | (((c->mlen - 2) / 2 << 3)) | (1); + for (i = 1; i <= 13; ++i) { + b[i] = c->nonce[i - 1]; + } + b[14] = (uint8_t)(plen >> 8); + b[15] = (uint8_t)(plen); + + /* computing the authentication tag using cbc-mac: */ + (void) tc_aes_encrypt(tag, b, c->sched); + if (alen > 0) { + ccm_cbc_mac(tag, associated_data, alen, 1, c->sched); + } + if (plen > 0) { + ccm_cbc_mac(tag, payload, plen, 0, c->sched); + } + + /* ENCRYPTION: */ + + /* formatting the sequence b for encryption: */ + b[0] = 1; /* q - 1 = 2 - 1 = 1 */ + b[14] = b[15] = TC_ZERO_BYTE; + + /* encrypting payload using ctr mode: */ + ccm_ctr_mode(out, plen, payload, plen, b, c->sched); + + b[14] = b[15] = TC_ZERO_BYTE; /* restoring initial counter for ctr_mode (0):*/ + + /* encrypting b and adding the tag to the output: */ + (void) tc_aes_encrypt(b, b, c->sched); + out += plen; + for (i = 0; i < c->mlen; ++i) { + *out++ = tag[i] ^ b[i]; + } + + return TC_CRYPTO_SUCCESS; +} + +int tc_ccm_decryption_verification(uint8_t *out, unsigned int olen, + const uint8_t *associated_data, + unsigned int alen, const uint8_t *payload, + unsigned int plen, TCCcmMode_t c) +{ + + /* input sanity check: */ + if ((out == (uint8_t *) 0) || + (c == (TCCcmMode_t) 0) || + ((plen > 0) && (payload == (uint8_t *) 0)) || + ((alen > 0) && (associated_data == (uint8_t *) 0)) || + (alen >= TC_CCM_AAD_MAX_BYTES) || /* associated data size unsupported */ + (plen >= TC_CCM_PAYLOAD_MAX_BYTES) || /* payload size unsupported */ + (olen < plen - c->mlen)) { /* invalid output buffer size */ + return TC_CRYPTO_FAIL; + } + + uint8_t b[Nb * Nk]; + uint8_t tag[Nb * Nk]; + unsigned int i; + + /* DECRYPTION: */ + + /* formatting the sequence b for decryption: */ + b[0] = 1; /* q - 1 = 2 - 1 = 1 */ + for (i = 1; i < 14; ++i) { + b[i] = c->nonce[i - 1]; + } + b[14] = b[15] = TC_ZERO_BYTE; /* initial counter value is 0 */ + + /* decrypting payload using ctr mode: */ + ccm_ctr_mode(out, plen - c->mlen, payload, plen - c->mlen, b, c->sched); + + b[14] = b[15] = TC_ZERO_BYTE; /* restoring initial counter value (0) */ + + /* encrypting b and restoring the tag from input: */ + (void) tc_aes_encrypt(b, b, c->sched); + for (i = 0; i < c->mlen; ++i) { + tag[i] = *(payload + plen - c->mlen + i) ^ b[i]; + } + + /* VERIFYING THE AUTHENTICATION TAG: */ + + /* formatting the sequence b for authentication: */ + b[0] = ((alen > 0) ? 0x40:0)|(((c->mlen - 2) / 2 << 3)) | (1); + for (i = 1; i < 14; ++i) { + b[i] = c->nonce[i - 1]; + } + b[14] = (uint8_t)((plen - c->mlen) >> 8); + b[15] = (uint8_t)(plen - c->mlen); + + /* computing the authentication tag using cbc-mac: */ + (void) tc_aes_encrypt(b, b, c->sched); + if (alen > 0) { + ccm_cbc_mac(b, associated_data, alen, 1, c->sched); + } + if (plen > 0) { + ccm_cbc_mac(b, out, plen - c->mlen, 0, c->sched); + } + + /* comparing the received tag and the computed one: */ + if (_compare(b, tag, c->mlen) == 0) { + return TC_CRYPTO_SUCCESS; + } else { + /* erase the decrypted buffer in case of mac validation failure: */ + _set(out, 0, plen - c->mlen); + return TC_CRYPTO_FAIL; + } +} diff --git a/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/cmac_mode.c b/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/cmac_mode.c new file mode 100644 index 000000000..96d147e80 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/cmac_mode.c @@ -0,0 +1,254 @@ +/* cmac_mode.c - TinyCrypt CMAC mode implementation */ + +/* + * Copyright (C) 2017 by Intel Corporation, All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +/* max number of calls until change the key (2^48).*/ +const static uint64_t MAX_CALLS = ((uint64_t)1 << 48); + +/* + * gf_wrap -- In our implementation, GF(2^128) is represented as a 16 byte + * array with byte 0 the most significant and byte 15 the least significant. + * High bit carry reduction is based on the primitive polynomial + * + * X^128 + X^7 + X^2 + X + 1, + * + * which leads to the reduction formula X^128 = X^7 + X^2 + X + 1. Indeed, + * since 0 = (X^128 + X^7 + X^2 + 1) mod (X^128 + X^7 + X^2 + X + 1) and since + * addition of polynomials with coefficients in Z/Z(2) is just XOR, we can + * add X^128 to both sides to get + * + * X^128 = (X^7 + X^2 + X + 1) mod (X^128 + X^7 + X^2 + X + 1) + * + * and the coefficients of the polynomial on the right hand side form the + * string 1000 0111 = 0x87, which is the value of gf_wrap. + * + * This gets used in the following way. Doubling in GF(2^128) is just a left + * shift by 1 bit, except when the most significant bit is 1. In the latter + * case, the relation X^128 = X^7 + X^2 + X + 1 says that the high order bit + * that overflows beyond 128 bits can be replaced by addition of + * X^7 + X^2 + X + 1 <--> 0x87 to the low order 128 bits. Since addition + * in GF(2^128) is represented by XOR, we therefore only have to XOR 0x87 + * into the low order byte after a left shift when the starting high order + * bit is 1. + */ +const unsigned char gf_wrap = 0x87; + +/* + * assumes: out != NULL and points to a GF(2^n) value to receive the + * doubled value; + * in != NULL and points to a 16 byte GF(2^n) value + * to double; + * the in and out buffers do not overlap. + * effects: doubles the GF(2^n) value pointed to by "in" and places + * the result in the GF(2^n) value pointed to by "out." + */ +void gf_double(uint8_t *out, uint8_t *in) +{ + + /* start with low order byte */ + uint8_t *x = in + (TC_AES_BLOCK_SIZE - 1); + + /* if msb == 1, we need to add the gf_wrap value, otherwise add 0 */ + uint8_t carry = (in[0] >> 7) ? gf_wrap : 0; + + out += (TC_AES_BLOCK_SIZE - 1); + for (;;) { + *out-- = (*x << 1) ^ carry; + if (x == in) { + break; + } + carry = *x-- >> 7; + } +} + +int tc_cmac_setup(TCCmacState_t s, const uint8_t *key, TCAesKeySched_t sched) +{ + + /* input sanity check: */ + if (s == (TCCmacState_t) 0 || + key == (const uint8_t *) 0) { + return TC_CRYPTO_FAIL; + } + + /* put s into a known state */ + _set(s, 0, sizeof(*s)); + s->sched = sched; + + /* configure the encryption key used by the underlying block cipher */ + tc_aes128_set_encrypt_key(s->sched, key); + + /* compute s->K1 and s->K2 from s->iv using s->keyid */ + _set(s->iv, 0, TC_AES_BLOCK_SIZE); + tc_aes_encrypt(s->iv, s->iv, s->sched); + gf_double (s->K1, s->iv); + gf_double (s->K2, s->K1); + + /* reset s->iv to 0 in case someone wants to compute now */ + tc_cmac_init(s); + + return TC_CRYPTO_SUCCESS; +} + +int tc_cmac_erase(TCCmacState_t s) +{ + if (s == (TCCmacState_t) 0) { + return TC_CRYPTO_FAIL; + } + + /* destroy the current state */ + _set(s, 0, sizeof(*s)); + + return TC_CRYPTO_SUCCESS; +} + +int tc_cmac_init(TCCmacState_t s) +{ + /* input sanity check: */ + if (s == (TCCmacState_t) 0) { + return TC_CRYPTO_FAIL; + } + + /* CMAC starts with an all zero initialization vector */ + _set(s->iv, 0, TC_AES_BLOCK_SIZE); + + /* and the leftover buffer is empty */ + _set(s->leftover, 0, TC_AES_BLOCK_SIZE); + s->leftover_offset = 0; + + /* Set countdown to max number of calls allowed before re-keying: */ + s->countdown = MAX_CALLS; + + return TC_CRYPTO_SUCCESS; +} + +int tc_cmac_update(TCCmacState_t s, const uint8_t *data, size_t data_length) +{ + unsigned int i; + + /* input sanity check: */ + if (s == (TCCmacState_t) 0) { + return TC_CRYPTO_FAIL; + } + if (data_length == 0) { + return TC_CRYPTO_SUCCESS; + } + if (data == (const uint8_t *) 0) { + return TC_CRYPTO_FAIL; + } + + if (s->countdown == 0) { + return TC_CRYPTO_FAIL; + } + + s->countdown--; + + if (s->leftover_offset > 0) { + /* last data added to s didn't end on a TC_AES_BLOCK_SIZE byte boundary */ + size_t remaining_space = TC_AES_BLOCK_SIZE - s->leftover_offset; + + if (data_length < remaining_space) { + /* still not enough data to encrypt this time either */ + _copy(&s->leftover[s->leftover_offset], data_length, data, data_length); + s->leftover_offset += data_length; + return TC_CRYPTO_SUCCESS; + } + /* leftover block is now full; encrypt it first */ + _copy(&s->leftover[s->leftover_offset], + remaining_space, + data, + remaining_space); + data_length -= remaining_space; + data += remaining_space; + s->leftover_offset = 0; + + for (i = 0; i < TC_AES_BLOCK_SIZE; ++i) { + s->iv[i] ^= s->leftover[i]; + } + tc_aes_encrypt(s->iv, s->iv, s->sched); + } + + /* CBC encrypt each (except the last) of the data blocks */ + while (data_length > TC_AES_BLOCK_SIZE) { + for (i = 0; i < TC_AES_BLOCK_SIZE; ++i) { + s->iv[i] ^= data[i]; + } + tc_aes_encrypt(s->iv, s->iv, s->sched); + data += TC_AES_BLOCK_SIZE; + data_length -= TC_AES_BLOCK_SIZE; + } + + if (data_length > 0) { + /* save leftover data for next time */ + _copy(s->leftover, data_length, data, data_length); + s->leftover_offset = data_length; + } + + return TC_CRYPTO_SUCCESS; +} + +int tc_cmac_final(uint8_t *tag, TCCmacState_t s) +{ + uint8_t *k; + unsigned int i; + + /* input sanity check: */ + if (tag == (uint8_t *) 0 || + s == (TCCmacState_t) 0) { + return TC_CRYPTO_FAIL; + } + + if (s->leftover_offset == TC_AES_BLOCK_SIZE) { + /* the last message block is a full-sized block */ + k = (uint8_t *) s->K1; + } else { + /* the final message block is not a full-sized block */ + size_t remaining = TC_AES_BLOCK_SIZE - s->leftover_offset; + + _set(&s->leftover[s->leftover_offset], 0, remaining); + s->leftover[s->leftover_offset] = TC_CMAC_PADDING; + k = (uint8_t *) s->K2; + } + for (i = 0; i < TC_AES_BLOCK_SIZE; ++i) { + s->iv[i] ^= s->leftover[i] ^ k[i]; + } + + tc_aes_encrypt(tag, s->iv, s->sched); + + /* erasing state: */ + tc_cmac_erase(s); + + return TC_CRYPTO_SUCCESS; +} diff --git a/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/ctr_mode.c b/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/ctr_mode.c new file mode 100644 index 000000000..1dfb92dfe --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/ctr_mode.c @@ -0,0 +1,85 @@ +/* ctr_mode.c - TinyCrypt CTR mode implementation */ + +/* + * Copyright (C) 2017 by Intel Corporation, All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +int tc_ctr_mode(uint8_t *out, unsigned int outlen, const uint8_t *in, + unsigned int inlen, uint8_t *ctr, const TCAesKeySched_t sched) +{ + + uint8_t buffer[TC_AES_BLOCK_SIZE]; + uint8_t nonce[TC_AES_BLOCK_SIZE]; + unsigned int block_num; + unsigned int i; + + /* input sanity check: */ + if (out == (uint8_t *) 0 || + in == (uint8_t *) 0 || + ctr == (uint8_t *) 0 || + sched == (TCAesKeySched_t) 0 || + inlen == 0 || + outlen == 0 || + outlen != inlen) { + return TC_CRYPTO_FAIL; + } + + /* copy the ctr to the nonce */ + (void)_copy(nonce, sizeof(nonce), ctr, sizeof(nonce)); + + /* select the last 4 bytes of the nonce to be incremented */ + block_num = (nonce[12] << 24) | (nonce[13] << 16) | + (nonce[14] << 8) | (nonce[15]); + for (i = 0; i < inlen; ++i) { + if ((i % (TC_AES_BLOCK_SIZE)) == 0) { + /* encrypt data using the current nonce */ + if (tc_aes_encrypt(buffer, nonce, sched)) { + block_num++; + nonce[12] = (uint8_t)(block_num >> 24); + nonce[13] = (uint8_t)(block_num >> 16); + nonce[14] = (uint8_t)(block_num >> 8); + nonce[15] = (uint8_t)(block_num); + } else { + return TC_CRYPTO_FAIL; + } + } + /* update the output */ + *out++ = buffer[i%(TC_AES_BLOCK_SIZE)] ^ *in++; + } + + /* update the counter */ + ctr[12] = nonce[12]; ctr[13] = nonce[13]; + ctr[14] = nonce[14]; ctr[15] = nonce[15]; + + return TC_CRYPTO_SUCCESS; +} diff --git a/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/ctr_prng.c b/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/ctr_prng.c new file mode 100644 index 000000000..cac2cc41d --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/ctr_prng.c @@ -0,0 +1,283 @@ +/* ctr_prng.c - TinyCrypt implementation of CTR-PRNG */ + +/* + * Copyright (c) 2016, Chris Morrison + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +/* + * This PRNG is based on the CTR_DRBG described in Recommendation for Random + * Number Generation Using Deterministic Random Bit Generators, + * NIST SP 800-90A Rev. 1. + * + * Annotations to particular steps (e.g. 10.2.1.2 Step 1) refer to the steps + * described in that document. + * + */ + +/** + * @brief Array incrementer + * Treats the supplied array as one contiguous number (MSB in arr[0]), and + * increments it by one + * @return none + * @param arr IN/OUT -- array to be incremented + * @param len IN -- size of arr in bytes + */ +static void arrInc(uint8_t arr[], unsigned int len) +{ + unsigned int i; + if (0 != arr) { + for (i = len; i > 0U; i--) { + if (++arr[i-1] != 0U) { + break; + } + } + } +} + +/** + * @brief CTR PRNG update + * Updates the internal state of supplied the CTR PRNG context + * increments it by one + * @return none + * @note Assumes: providedData is (TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE) bytes long + * @param ctx IN/OUT -- CTR PRNG state + * @param providedData IN -- data used when updating the internal state + */ +static void tc_ctr_prng_update(TCCtrPrng_t * const ctx, uint8_t const * const providedData) +{ + if (0 != ctx) { + /* 10.2.1.2 step 1 */ + uint8_t temp[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE]; + unsigned int len = 0U; + + /* 10.2.1.2 step 2 */ + while (len < sizeof temp) { + unsigned int blocklen = sizeof(temp) - len; + uint8_t output_block[TC_AES_BLOCK_SIZE]; + + /* 10.2.1.2 step 2.1 */ + arrInc(ctx->V, sizeof ctx->V); + + /* 10.2.1.2 step 2.2 */ + if (blocklen > TC_AES_BLOCK_SIZE) { + blocklen = TC_AES_BLOCK_SIZE; + } + (void)tc_aes_encrypt(output_block, ctx->V, &ctx->key); + + /* 10.2.1.2 step 2.3/step 3 */ + memcpy(&(temp[len]), output_block, blocklen); + + len += blocklen; + } + + /* 10.2.1.2 step 4 */ + if (0 != providedData) { + unsigned int i; + for (i = 0U; i < sizeof temp; i++) { + temp[i] ^= providedData[i]; + } + } + + /* 10.2.1.2 step 5 */ + (void)tc_aes128_set_encrypt_key(&ctx->key, temp); + + /* 10.2.1.2 step 6 */ + memcpy(ctx->V, &(temp[TC_AES_KEY_SIZE]), TC_AES_BLOCK_SIZE); + } +} + +int tc_ctr_prng_init(TCCtrPrng_t * const ctx, + uint8_t const * const entropy, + unsigned int entropyLen, + uint8_t const * const personalization, + unsigned int pLen) +{ + int result = TC_CRYPTO_FAIL; + unsigned int i; + uint8_t personalization_buf[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE] = {0U}; + uint8_t seed_material[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE]; + uint8_t zeroArr[TC_AES_BLOCK_SIZE] = {0U}; + + if (0 != personalization) { + /* 10.2.1.3.1 step 1 */ + unsigned int len = pLen; + if (len > sizeof personalization_buf) { + len = sizeof personalization_buf; + } + + /* 10.2.1.3.1 step 2 */ + memcpy(personalization_buf, personalization, len); + } + + if ((0 != ctx) && (0 != entropy) && (entropyLen >= sizeof seed_material)) { + /* 10.2.1.3.1 step 3 */ + memcpy(seed_material, entropy, sizeof seed_material); + for (i = 0U; i < sizeof seed_material; i++) { + seed_material[i] ^= personalization_buf[i]; + } + + /* 10.2.1.3.1 step 4 */ + (void)tc_aes128_set_encrypt_key(&ctx->key, zeroArr); + + /* 10.2.1.3.1 step 5 */ + memset(ctx->V, 0x00, sizeof ctx->V); + + /* 10.2.1.3.1 step 6 */ + tc_ctr_prng_update(ctx, seed_material); + + /* 10.2.1.3.1 step 7 */ + ctx->reseedCount = 1U; + + result = TC_CRYPTO_SUCCESS; + } + return result; +} + +int tc_ctr_prng_reseed(TCCtrPrng_t * const ctx, + uint8_t const * const entropy, + unsigned int entropyLen, + uint8_t const * const additional_input, + unsigned int additionallen) +{ + unsigned int i; + int result = TC_CRYPTO_FAIL; + uint8_t additional_input_buf[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE] = {0U}; + uint8_t seed_material[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE]; + + if (0 != additional_input) { + /* 10.2.1.4.1 step 1 */ + unsigned int len = additionallen; + if (len > sizeof additional_input_buf) { + len = sizeof additional_input_buf; + } + + /* 10.2.1.4.1 step 2 */ + memcpy(additional_input_buf, additional_input, len); + } + + unsigned int seedlen = (unsigned int)TC_AES_KEY_SIZE + (unsigned int)TC_AES_BLOCK_SIZE; + if ((0 != ctx) && (entropyLen >= seedlen)) { + /* 10.2.1.4.1 step 3 */ + memcpy(seed_material, entropy, sizeof seed_material); + for (i = 0U; i < sizeof seed_material; i++) { + seed_material[i] ^= additional_input_buf[i]; + } + + /* 10.2.1.4.1 step 4 */ + tc_ctr_prng_update(ctx, seed_material); + + /* 10.2.1.4.1 step 5 */ + ctx->reseedCount = 1U; + + result = TC_CRYPTO_SUCCESS; + } + return result; +} + +int tc_ctr_prng_generate(TCCtrPrng_t * const ctx, + uint8_t const * const additional_input, + unsigned int additionallen, + uint8_t * const out, + unsigned int outlen) +{ + /* 2^48 - see section 10.2.1 */ + static const uint64_t MAX_REQS_BEFORE_RESEED = 0x1000000000000ULL; + + /* 2^19 bits - see section 10.2.1 */ + static const unsigned int MAX_BYTES_PER_REQ = 65536U; + + unsigned int result = TC_CRYPTO_FAIL; + + if ((0 != ctx) && (0 != out) && (outlen < MAX_BYTES_PER_REQ)) { + /* 10.2.1.5.1 step 1 */ + if (ctx->reseedCount > MAX_REQS_BEFORE_RESEED) { + result = TC_CTR_PRNG_RESEED_REQ; + } else { + uint8_t additional_input_buf[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE] = {0U}; + if (0 != additional_input) { + /* 10.2.1.5.1 step 2 */ + unsigned int len = additionallen; + if (len > sizeof additional_input_buf) { + len = sizeof additional_input_buf; + } + memcpy(additional_input_buf, additional_input, len); + tc_ctr_prng_update(ctx, additional_input_buf); + } + + /* 10.2.1.5.1 step 3 - implicit */ + + /* 10.2.1.5.1 step 4 */ + unsigned int len = 0U; + while (len < outlen) { + unsigned int blocklen = outlen - len; + uint8_t output_block[TC_AES_BLOCK_SIZE]; + + /* 10.2.1.5.1 step 4.1 */ + arrInc(ctx->V, sizeof ctx->V); + + /* 10.2.1.5.1 step 4.2 */ + (void)tc_aes_encrypt(output_block, ctx->V, &ctx->key); + + /* 10.2.1.5.1 step 4.3/step 5 */ + if (blocklen > TC_AES_BLOCK_SIZE) { + blocklen = TC_AES_BLOCK_SIZE; + } + memcpy(&(out[len]), output_block, blocklen); + + len += blocklen; + } + + /* 10.2.1.5.1 step 6 */ + tc_ctr_prng_update(ctx, additional_input_buf); + + /* 10.2.1.5.1 step 7 */ + ctx->reseedCount++; + + /* 10.2.1.5.1 step 8 */ + result = TC_CRYPTO_SUCCESS; + } + } + + return result; +} + +void tc_ctr_prng_uninstantiate(TCCtrPrng_t * const ctx) +{ + if (0 != ctx) { + memset(ctx->key.words, 0x00, sizeof ctx->key.words); + memset(ctx->V, 0x00, sizeof ctx->V); + ctx->reseedCount = 0U; + } +} + + + + diff --git a/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/ecc.c b/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/ecc.c new file mode 100644 index 000000000..46080bf61 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/ecc.c @@ -0,0 +1,942 @@ +/* ecc.c - TinyCrypt implementation of common ECC functions */ + +/* + * Copyright (c) 2014, Kenneth MacKay + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Copyright (C) 2017 by Intel Corporation, All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +/* IMPORTANT: Make sure a cryptographically-secure PRNG is set and the platform + * has access to enough entropy in order to feed the PRNG regularly. */ +#if default_RNG_defined +static uECC_RNG_Function g_rng_function = &default_CSPRNG; +#else +static uECC_RNG_Function g_rng_function = 0; +#endif + +void uECC_set_rng(uECC_RNG_Function rng_function) +{ + g_rng_function = rng_function; +} + +uECC_RNG_Function uECC_get_rng(void) +{ + return g_rng_function; +} + +int uECC_curve_private_key_size(uECC_Curve curve) +{ + return BITS_TO_BYTES(curve->num_n_bits); +} + +int uECC_curve_public_key_size(uECC_Curve curve) +{ + return 2 * curve->num_bytes; +} + +void uECC_vli_clear(uECC_word_t *vli, wordcount_t num_words) +{ + wordcount_t i; + for (i = 0; i < num_words; ++i) { + vli[i] = 0; + } +} + +uECC_word_t uECC_vli_isZero(const uECC_word_t *vli, wordcount_t num_words) +{ + uECC_word_t bits = 0; + wordcount_t i; + for (i = 0; i < num_words; ++i) { + bits |= vli[i]; + } + return (bits == 0); +} + +uECC_word_t uECC_vli_testBit(const uECC_word_t *vli, bitcount_t bit) +{ + return (vli[bit >> uECC_WORD_BITS_SHIFT] & + ((uECC_word_t)1 << (bit & uECC_WORD_BITS_MASK))); +} + +/* Counts the number of words in vli. */ +static wordcount_t vli_numDigits(const uECC_word_t *vli, + const wordcount_t max_words) +{ + + wordcount_t i; + /* Search from the end until we find a non-zero digit. We do it in reverse + * because we expect that most digits will be nonzero. */ + for (i = max_words - 1; i >= 0 && vli[i] == 0; --i) { + } + + return (i + 1); +} + +bitcount_t uECC_vli_numBits(const uECC_word_t *vli, + const wordcount_t max_words) +{ + + uECC_word_t i; + uECC_word_t digit; + + wordcount_t num_digits = vli_numDigits(vli, max_words); + if (num_digits == 0) { + return 0; + } + + digit = vli[num_digits - 1]; + for (i = 0; digit; ++i) { + digit >>= 1; + } + + return (((bitcount_t)(num_digits - 1) << uECC_WORD_BITS_SHIFT) + i); +} + +void uECC_vli_set(uECC_word_t *dest, const uECC_word_t *src, + wordcount_t num_words) +{ + wordcount_t i; + + for (i = 0; i < num_words; ++i) { + dest[i] = src[i]; + } +} + +cmpresult_t uECC_vli_cmp_unsafe(const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) +{ + wordcount_t i; + + for (i = num_words - 1; i >= 0; --i) { + if (left[i] > right[i]) { + return 1; + } else if (left[i] < right[i]) { + return -1; + } + } + return 0; +} + +uECC_word_t uECC_vli_equal(const uECC_word_t *left, const uECC_word_t *right, + wordcount_t num_words) +{ + + uECC_word_t diff = 0; + wordcount_t i; + + for (i = num_words - 1; i >= 0; --i) { + diff |= (left[i] ^ right[i]); + } + return !(diff == 0); +} + +uECC_word_t cond_set(uECC_word_t p_true, uECC_word_t p_false, unsigned int cond) +{ + return (p_true*(cond)) | (p_false*(!cond)); +} + +/* Computes result = left - right, returning borrow, in constant time. + * Can modify in place. */ +uECC_word_t uECC_vli_sub(uECC_word_t *result, const uECC_word_t *left, + const uECC_word_t *right, wordcount_t num_words) +{ + uECC_word_t borrow = 0; + wordcount_t i; + for (i = 0; i < num_words; ++i) { + uECC_word_t diff = left[i] - right[i] - borrow; + uECC_word_t val = (diff > left[i]); + borrow = cond_set(val, borrow, (diff != left[i])); + + result[i] = diff; + } + return borrow; +} + +/* Computes result = left + right, returning carry, in constant time. + * Can modify in place. */ +static uECC_word_t uECC_vli_add(uECC_word_t *result, const uECC_word_t *left, + const uECC_word_t *right, wordcount_t num_words) +{ + uECC_word_t carry = 0; + wordcount_t i; + for (i = 0; i < num_words; ++i) { + uECC_word_t sum = left[i] + right[i] + carry; + uECC_word_t val = (sum < left[i]); + carry = cond_set(val, carry, (sum != left[i])); + result[i] = sum; + } + return carry; +} + +cmpresult_t uECC_vli_cmp(const uECC_word_t *left, const uECC_word_t *right, + wordcount_t num_words) +{ + uECC_word_t tmp[NUM_ECC_WORDS]; + uECC_word_t neg = !!uECC_vli_sub(tmp, left, right, num_words); + uECC_word_t equal = uECC_vli_isZero(tmp, num_words); + return (!equal - 2 * neg); +} + +/* Computes vli = vli >> 1. */ +static void uECC_vli_rshift1(uECC_word_t *vli, wordcount_t num_words) +{ + uECC_word_t *end = vli; + uECC_word_t carry = 0; + + vli += num_words; + while (vli-- > end) { + uECC_word_t temp = *vli; + *vli = (temp >> 1) | carry; + carry = temp << (uECC_WORD_BITS - 1); + } +} + +static void muladd(uECC_word_t a, uECC_word_t b, uECC_word_t *r0, + uECC_word_t *r1, uECC_word_t *r2) +{ + + uECC_dword_t p = (uECC_dword_t)a * b; + uECC_dword_t r01 = ((uECC_dword_t)(*r1) << uECC_WORD_BITS) | *r0; + r01 += p; + *r2 += (r01 < p); + *r1 = r01 >> uECC_WORD_BITS; + *r0 = (uECC_word_t)r01; + +} + +/* Computes result = left * right. Result must be 2 * num_words long. */ +static void uECC_vli_mult(uECC_word_t *result, const uECC_word_t *left, + const uECC_word_t *right, wordcount_t num_words) +{ + + uECC_word_t r0 = 0; + uECC_word_t r1 = 0; + uECC_word_t r2 = 0; + wordcount_t i, k; + + /* Compute each digit of result in sequence, maintaining the carries. */ + for (k = 0; k < num_words; ++k) { + + for (i = 0; i <= k; ++i) { + muladd(left[i], right[k - i], &r0, &r1, &r2); + } + + result[k] = r0; + r0 = r1; + r1 = r2; + r2 = 0; + } + + for (k = num_words; k < num_words * 2 - 1; ++k) { + + for (i = (k + 1) - num_words; i < num_words; ++i) { + muladd(left[i], right[k - i], &r0, &r1, &r2); + } + result[k] = r0; + r0 = r1; + r1 = r2; + r2 = 0; + } + result[num_words * 2 - 1] = r0; +} + +void uECC_vli_modAdd(uECC_word_t *result, const uECC_word_t *left, + const uECC_word_t *right, const uECC_word_t *mod, + wordcount_t num_words) +{ + uECC_word_t carry = uECC_vli_add(result, left, right, num_words); + if (carry || uECC_vli_cmp_unsafe(mod, result, num_words) != 1) { + /* result > mod (result = mod + remainder), so subtract mod to get + * remainder. */ + uECC_vli_sub(result, result, mod, num_words); + } +} + +void uECC_vli_modSub(uECC_word_t *result, const uECC_word_t *left, + const uECC_word_t *right, const uECC_word_t *mod, + wordcount_t num_words) +{ + uECC_word_t l_borrow = uECC_vli_sub(result, left, right, num_words); + if (l_borrow) { + /* In this case, result == -diff == (max int) - diff. Since -x % d == d - x, + * we can get the correct result from result + mod (with overflow). */ + uECC_vli_add(result, result, mod, num_words); + } +} + +/* Computes result = product % mod, where product is 2N words long. */ +/* Currently only designed to work for curve_p or curve_n. */ +void uECC_vli_mmod(uECC_word_t *result, uECC_word_t *product, + const uECC_word_t *mod, wordcount_t num_words) +{ + uECC_word_t mod_multiple[2 * NUM_ECC_WORDS]; + uECC_word_t tmp[2 * NUM_ECC_WORDS]; + uECC_word_t *v[2] = {tmp, product}; + uECC_word_t index; + + /* Shift mod so its highest set bit is at the maximum position. */ + bitcount_t shift = (num_words * 2 * uECC_WORD_BITS) - + uECC_vli_numBits(mod, num_words); + wordcount_t word_shift = shift / uECC_WORD_BITS; + wordcount_t bit_shift = shift % uECC_WORD_BITS; + uECC_word_t carry = 0; + uECC_vli_clear(mod_multiple, word_shift); + if (bit_shift > 0) { + for(index = 0; index < (uECC_word_t)num_words; ++index) { + mod_multiple[word_shift + index] = (mod[index] << bit_shift) | carry; + carry = mod[index] >> (uECC_WORD_BITS - bit_shift); + } + } else { + uECC_vli_set(mod_multiple + word_shift, mod, num_words); + } + + for (index = 1; shift >= 0; --shift) { + uECC_word_t borrow = 0; + wordcount_t i; + for (i = 0; i < num_words * 2; ++i) { + uECC_word_t diff = v[index][i] - mod_multiple[i] - borrow; + if (diff != v[index][i]) { + borrow = (diff > v[index][i]); + } + v[1 - index][i] = diff; + } + /* Swap the index if there was no borrow */ + index = !(index ^ borrow); + uECC_vli_rshift1(mod_multiple, num_words); + mod_multiple[num_words - 1] |= mod_multiple[num_words] << + (uECC_WORD_BITS - 1); + uECC_vli_rshift1(mod_multiple + num_words, num_words); + } + uECC_vli_set(result, v[index], num_words); +} + +void uECC_vli_modMult(uECC_word_t *result, const uECC_word_t *left, + const uECC_word_t *right, const uECC_word_t *mod, + wordcount_t num_words) +{ + uECC_word_t product[2 * NUM_ECC_WORDS]; + uECC_vli_mult(product, left, right, num_words); + uECC_vli_mmod(result, product, mod, num_words); +} + +void uECC_vli_modMult_fast(uECC_word_t *result, const uECC_word_t *left, + const uECC_word_t *right, uECC_Curve curve) +{ + uECC_word_t product[2 * NUM_ECC_WORDS]; + uECC_vli_mult(product, left, right, curve->num_words); + + curve->mmod_fast(result, product); +} + +static void uECC_vli_modSquare_fast(uECC_word_t *result, + const uECC_word_t *left, + uECC_Curve curve) +{ + uECC_vli_modMult_fast(result, left, left, curve); +} + + +#define EVEN(vli) (!(vli[0] & 1)) + +static void vli_modInv_update(uECC_word_t *uv, + const uECC_word_t *mod, + wordcount_t num_words) +{ + + uECC_word_t carry = 0; + + if (!EVEN(uv)) { + carry = uECC_vli_add(uv, uv, mod, num_words); + } + uECC_vli_rshift1(uv, num_words); + if (carry) { + uv[num_words - 1] |= HIGH_BIT_SET; + } +} + +void uECC_vli_modInv(uECC_word_t *result, const uECC_word_t *input, + const uECC_word_t *mod, wordcount_t num_words) +{ + uECC_word_t a[NUM_ECC_WORDS], b[NUM_ECC_WORDS]; + uECC_word_t u[NUM_ECC_WORDS], v[NUM_ECC_WORDS]; + cmpresult_t cmpResult; + + if (uECC_vli_isZero(input, num_words)) { + uECC_vli_clear(result, num_words); + return; + } + + uECC_vli_set(a, input, num_words); + uECC_vli_set(b, mod, num_words); + uECC_vli_clear(u, num_words); + u[0] = 1; + uECC_vli_clear(v, num_words); + while ((cmpResult = uECC_vli_cmp_unsafe(a, b, num_words)) != 0) { + if (EVEN(a)) { + uECC_vli_rshift1(a, num_words); + vli_modInv_update(u, mod, num_words); + } else if (EVEN(b)) { + uECC_vli_rshift1(b, num_words); + vli_modInv_update(v, mod, num_words); + } else if (cmpResult > 0) { + uECC_vli_sub(a, a, b, num_words); + uECC_vli_rshift1(a, num_words); + if (uECC_vli_cmp_unsafe(u, v, num_words) < 0) { + uECC_vli_add(u, u, mod, num_words); + } + uECC_vli_sub(u, u, v, num_words); + vli_modInv_update(u, mod, num_words); + } else { + uECC_vli_sub(b, b, a, num_words); + uECC_vli_rshift1(b, num_words); + if (uECC_vli_cmp_unsafe(v, u, num_words) < 0) { + uECC_vli_add(v, v, mod, num_words); + } + uECC_vli_sub(v, v, u, num_words); + vli_modInv_update(v, mod, num_words); + } + } + uECC_vli_set(result, u, num_words); +} + +/* ------ Point operations ------ */ + +void double_jacobian_default(uECC_word_t * X1, uECC_word_t * Y1, + uECC_word_t * Z1, uECC_Curve curve) +{ + /* t1 = X, t2 = Y, t3 = Z */ + uECC_word_t t4[NUM_ECC_WORDS]; + uECC_word_t t5[NUM_ECC_WORDS]; + wordcount_t num_words = curve->num_words; + + if (uECC_vli_isZero(Z1, num_words)) { + return; + } + + uECC_vli_modSquare_fast(t4, Y1, curve); /* t4 = y1^2 */ + uECC_vli_modMult_fast(t5, X1, t4, curve); /* t5 = x1*y1^2 = A */ + uECC_vli_modSquare_fast(t4, t4, curve); /* t4 = y1^4 */ + uECC_vli_modMult_fast(Y1, Y1, Z1, curve); /* t2 = y1*z1 = z3 */ + uECC_vli_modSquare_fast(Z1, Z1, curve); /* t3 = z1^2 */ + + uECC_vli_modAdd(X1, X1, Z1, curve->p, num_words); /* t1 = x1 + z1^2 */ + uECC_vli_modAdd(Z1, Z1, Z1, curve->p, num_words); /* t3 = 2*z1^2 */ + uECC_vli_modSub(Z1, X1, Z1, curve->p, num_words); /* t3 = x1 - z1^2 */ + uECC_vli_modMult_fast(X1, X1, Z1, curve); /* t1 = x1^2 - z1^4 */ + + uECC_vli_modAdd(Z1, X1, X1, curve->p, num_words); /* t3 = 2*(x1^2 - z1^4) */ + uECC_vli_modAdd(X1, X1, Z1, curve->p, num_words); /* t1 = 3*(x1^2 - z1^4) */ + if (uECC_vli_testBit(X1, 0)) { + uECC_word_t l_carry = uECC_vli_add(X1, X1, curve->p, num_words); + uECC_vli_rshift1(X1, num_words); + X1[num_words - 1] |= l_carry << (uECC_WORD_BITS - 1); + } else { + uECC_vli_rshift1(X1, num_words); + } + + /* t1 = 3/2*(x1^2 - z1^4) = B */ + uECC_vli_modSquare_fast(Z1, X1, curve); /* t3 = B^2 */ + uECC_vli_modSub(Z1, Z1, t5, curve->p, num_words); /* t3 = B^2 - A */ + uECC_vli_modSub(Z1, Z1, t5, curve->p, num_words); /* t3 = B^2 - 2A = x3 */ + uECC_vli_modSub(t5, t5, Z1, curve->p, num_words); /* t5 = A - x3 */ + uECC_vli_modMult_fast(X1, X1, t5, curve); /* t1 = B * (A - x3) */ + /* t4 = B * (A - x3) - y1^4 = y3: */ + uECC_vli_modSub(t4, X1, t4, curve->p, num_words); + + uECC_vli_set(X1, Z1, num_words); + uECC_vli_set(Z1, Y1, num_words); + uECC_vli_set(Y1, t4, num_words); +} + +void x_side_default(uECC_word_t *result, + const uECC_word_t *x, + uECC_Curve curve) +{ + uECC_word_t _3[NUM_ECC_WORDS] = {3}; /* -a = 3 */ + wordcount_t num_words = curve->num_words; + + uECC_vli_modSquare_fast(result, x, curve); /* r = x^2 */ + uECC_vli_modSub(result, result, _3, curve->p, num_words); /* r = x^2 - 3 */ + uECC_vli_modMult_fast(result, result, x, curve); /* r = x^3 - 3x */ + /* r = x^3 - 3x + b: */ + uECC_vli_modAdd(result, result, curve->b, curve->p, num_words); +} + +uECC_Curve uECC_secp256r1(void) +{ + return &curve_secp256r1; +} + +void vli_mmod_fast_secp256r1(unsigned int *result, unsigned int*product) +{ + unsigned int tmp[NUM_ECC_WORDS]; + int carry; + + /* t */ + uECC_vli_set(result, product, NUM_ECC_WORDS); + + /* s1 */ + tmp[0] = tmp[1] = tmp[2] = 0; + tmp[3] = product[11]; + tmp[4] = product[12]; + tmp[5] = product[13]; + tmp[6] = product[14]; + tmp[7] = product[15]; + carry = uECC_vli_add(tmp, tmp, tmp, NUM_ECC_WORDS); + carry += uECC_vli_add(result, result, tmp, NUM_ECC_WORDS); + + /* s2 */ + tmp[3] = product[12]; + tmp[4] = product[13]; + tmp[5] = product[14]; + tmp[6] = product[15]; + tmp[7] = 0; + carry += uECC_vli_add(tmp, tmp, tmp, NUM_ECC_WORDS); + carry += uECC_vli_add(result, result, tmp, NUM_ECC_WORDS); + + /* s3 */ + tmp[0] = product[8]; + tmp[1] = product[9]; + tmp[2] = product[10]; + tmp[3] = tmp[4] = tmp[5] = 0; + tmp[6] = product[14]; + tmp[7] = product[15]; + carry += uECC_vli_add(result, result, tmp, NUM_ECC_WORDS); + + /* s4 */ + tmp[0] = product[9]; + tmp[1] = product[10]; + tmp[2] = product[11]; + tmp[3] = product[13]; + tmp[4] = product[14]; + tmp[5] = product[15]; + tmp[6] = product[13]; + tmp[7] = product[8]; + carry += uECC_vli_add(result, result, tmp, NUM_ECC_WORDS); + + /* d1 */ + tmp[0] = product[11]; + tmp[1] = product[12]; + tmp[2] = product[13]; + tmp[3] = tmp[4] = tmp[5] = 0; + tmp[6] = product[8]; + tmp[7] = product[10]; + carry -= uECC_vli_sub(result, result, tmp, NUM_ECC_WORDS); + + /* d2 */ + tmp[0] = product[12]; + tmp[1] = product[13]; + tmp[2] = product[14]; + tmp[3] = product[15]; + tmp[4] = tmp[5] = 0; + tmp[6] = product[9]; + tmp[7] = product[11]; + carry -= uECC_vli_sub(result, result, tmp, NUM_ECC_WORDS); + + /* d3 */ + tmp[0] = product[13]; + tmp[1] = product[14]; + tmp[2] = product[15]; + tmp[3] = product[8]; + tmp[4] = product[9]; + tmp[5] = product[10]; + tmp[6] = 0; + tmp[7] = product[12]; + carry -= uECC_vli_sub(result, result, tmp, NUM_ECC_WORDS); + + /* d4 */ + tmp[0] = product[14]; + tmp[1] = product[15]; + tmp[2] = 0; + tmp[3] = product[9]; + tmp[4] = product[10]; + tmp[5] = product[11]; + tmp[6] = 0; + tmp[7] = product[13]; + carry -= uECC_vli_sub(result, result, tmp, NUM_ECC_WORDS); + + if (carry < 0) { + do { + carry += uECC_vli_add(result, result, curve_secp256r1.p, NUM_ECC_WORDS); + } + while (carry < 0); + } else { + while (carry || + uECC_vli_cmp_unsafe(curve_secp256r1.p, result, NUM_ECC_WORDS) != 1) { + carry -= uECC_vli_sub(result, result, curve_secp256r1.p, NUM_ECC_WORDS); + } + } +} + +uECC_word_t EccPoint_isZero(const uECC_word_t *point, uECC_Curve curve) +{ + return uECC_vli_isZero(point, curve->num_words * 2); +} + +void apply_z(uECC_word_t * X1, uECC_word_t * Y1, const uECC_word_t * const Z, + uECC_Curve curve) +{ + uECC_word_t t1[NUM_ECC_WORDS]; + + uECC_vli_modSquare_fast(t1, Z, curve); /* z^2 */ + uECC_vli_modMult_fast(X1, X1, t1, curve); /* x1 * z^2 */ + uECC_vli_modMult_fast(t1, t1, Z, curve); /* z^3 */ + uECC_vli_modMult_fast(Y1, Y1, t1, curve); /* y1 * z^3 */ +} + +/* P = (x1, y1) => 2P, (x2, y2) => P' */ +static void XYcZ_initial_double(uECC_word_t * X1, uECC_word_t * Y1, + uECC_word_t * X2, uECC_word_t * Y2, + const uECC_word_t * const initial_Z, + uECC_Curve curve) +{ + uECC_word_t z[NUM_ECC_WORDS]; + wordcount_t num_words = curve->num_words; + if (initial_Z) { + uECC_vli_set(z, initial_Z, num_words); + } else { + uECC_vli_clear(z, num_words); + z[0] = 1; + } + + uECC_vli_set(X2, X1, num_words); + uECC_vli_set(Y2, Y1, num_words); + + apply_z(X1, Y1, z, curve); + curve->double_jacobian(X1, Y1, z, curve); + apply_z(X2, Y2, z, curve); +} + +void XYcZ_add(uECC_word_t * X1, uECC_word_t * Y1, + uECC_word_t * X2, uECC_word_t * Y2, + uECC_Curve curve) +{ + /* t1 = X1, t2 = Y1, t3 = X2, t4 = Y2 */ + uECC_word_t t5[NUM_ECC_WORDS]; + wordcount_t num_words = curve->num_words; + + uECC_vli_modSub(t5, X2, X1, curve->p, num_words); /* t5 = x2 - x1 */ + uECC_vli_modSquare_fast(t5, t5, curve); /* t5 = (x2 - x1)^2 = A */ + uECC_vli_modMult_fast(X1, X1, t5, curve); /* t1 = x1*A = B */ + uECC_vli_modMult_fast(X2, X2, t5, curve); /* t3 = x2*A = C */ + uECC_vli_modSub(Y2, Y2, Y1, curve->p, num_words); /* t4 = y2 - y1 */ + uECC_vli_modSquare_fast(t5, Y2, curve); /* t5 = (y2 - y1)^2 = D */ + + uECC_vli_modSub(t5, t5, X1, curve->p, num_words); /* t5 = D - B */ + uECC_vli_modSub(t5, t5, X2, curve->p, num_words); /* t5 = D - B - C = x3 */ + uECC_vli_modSub(X2, X2, X1, curve->p, num_words); /* t3 = C - B */ + uECC_vli_modMult_fast(Y1, Y1, X2, curve); /* t2 = y1*(C - B) */ + uECC_vli_modSub(X2, X1, t5, curve->p, num_words); /* t3 = B - x3 */ + uECC_vli_modMult_fast(Y2, Y2, X2, curve); /* t4 = (y2 - y1)*(B - x3) */ + uECC_vli_modSub(Y2, Y2, Y1, curve->p, num_words); /* t4 = y3 */ + + uECC_vli_set(X2, t5, num_words); +} + +/* Input P = (x1, y1, Z), Q = (x2, y2, Z) + Output P + Q = (x3, y3, Z3), P - Q = (x3', y3', Z3) + or P => P - Q, Q => P + Q + */ +static void XYcZ_addC(uECC_word_t * X1, uECC_word_t * Y1, + uECC_word_t * X2, uECC_word_t * Y2, + uECC_Curve curve) +{ + /* t1 = X1, t2 = Y1, t3 = X2, t4 = Y2 */ + uECC_word_t t5[NUM_ECC_WORDS]; + uECC_word_t t6[NUM_ECC_WORDS]; + uECC_word_t t7[NUM_ECC_WORDS]; + wordcount_t num_words = curve->num_words; + + uECC_vli_modSub(t5, X2, X1, curve->p, num_words); /* t5 = x2 - x1 */ + uECC_vli_modSquare_fast(t5, t5, curve); /* t5 = (x2 - x1)^2 = A */ + uECC_vli_modMult_fast(X1, X1, t5, curve); /* t1 = x1*A = B */ + uECC_vli_modMult_fast(X2, X2, t5, curve); /* t3 = x2*A = C */ + uECC_vli_modAdd(t5, Y2, Y1, curve->p, num_words); /* t5 = y2 + y1 */ + uECC_vli_modSub(Y2, Y2, Y1, curve->p, num_words); /* t4 = y2 - y1 */ + + uECC_vli_modSub(t6, X2, X1, curve->p, num_words); /* t6 = C - B */ + uECC_vli_modMult_fast(Y1, Y1, t6, curve); /* t2 = y1 * (C - B) = E */ + uECC_vli_modAdd(t6, X1, X2, curve->p, num_words); /* t6 = B + C */ + uECC_vli_modSquare_fast(X2, Y2, curve); /* t3 = (y2 - y1)^2 = D */ + uECC_vli_modSub(X2, X2, t6, curve->p, num_words); /* t3 = D - (B + C) = x3 */ + + uECC_vli_modSub(t7, X1, X2, curve->p, num_words); /* t7 = B - x3 */ + uECC_vli_modMult_fast(Y2, Y2, t7, curve); /* t4 = (y2 - y1)*(B - x3) */ + /* t4 = (y2 - y1)*(B - x3) - E = y3: */ + uECC_vli_modSub(Y2, Y2, Y1, curve->p, num_words); + + uECC_vli_modSquare_fast(t7, t5, curve); /* t7 = (y2 + y1)^2 = F */ + uECC_vli_modSub(t7, t7, t6, curve->p, num_words); /* t7 = F - (B + C) = x3' */ + uECC_vli_modSub(t6, t7, X1, curve->p, num_words); /* t6 = x3' - B */ + uECC_vli_modMult_fast(t6, t6, t5, curve); /* t6 = (y2+y1)*(x3' - B) */ + /* t2 = (y2+y1)*(x3' - B) - E = y3': */ + uECC_vli_modSub(Y1, t6, Y1, curve->p, num_words); + + uECC_vli_set(X1, t7, num_words); +} + +void EccPoint_mult(uECC_word_t * result, const uECC_word_t * point, + const uECC_word_t * scalar, + const uECC_word_t * initial_Z, + bitcount_t num_bits, uECC_Curve curve) +{ + /* R0 and R1 */ + uECC_word_t Rx[2][NUM_ECC_WORDS]; + uECC_word_t Ry[2][NUM_ECC_WORDS]; + uECC_word_t z[NUM_ECC_WORDS]; + bitcount_t i; + uECC_word_t nb; + wordcount_t num_words = curve->num_words; + + uECC_vli_set(Rx[1], point, num_words); + uECC_vli_set(Ry[1], point + num_words, num_words); + + XYcZ_initial_double(Rx[1], Ry[1], Rx[0], Ry[0], initial_Z, curve); + + for (i = num_bits - 2; i > 0; --i) { + nb = !uECC_vli_testBit(scalar, i); + XYcZ_addC(Rx[1 - nb], Ry[1 - nb], Rx[nb], Ry[nb], curve); + XYcZ_add(Rx[nb], Ry[nb], Rx[1 - nb], Ry[1 - nb], curve); + } + + nb = !uECC_vli_testBit(scalar, 0); + XYcZ_addC(Rx[1 - nb], Ry[1 - nb], Rx[nb], Ry[nb], curve); + + /* Find final 1/Z value. */ + uECC_vli_modSub(z, Rx[1], Rx[0], curve->p, num_words); /* X1 - X0 */ + uECC_vli_modMult_fast(z, z, Ry[1 - nb], curve); /* Yb * (X1 - X0) */ + uECC_vli_modMult_fast(z, z, point, curve); /* xP * Yb * (X1 - X0) */ + uECC_vli_modInv(z, z, curve->p, num_words); /* 1 / (xP * Yb * (X1 - X0))*/ + /* yP / (xP * Yb * (X1 - X0)) */ + uECC_vli_modMult_fast(z, z, point + num_words, curve); + /* Xb * yP / (xP * Yb * (X1 - X0)) */ + uECC_vli_modMult_fast(z, z, Rx[1 - nb], curve); + /* End 1/Z calculation */ + + XYcZ_add(Rx[nb], Ry[nb], Rx[1 - nb], Ry[1 - nb], curve); + apply_z(Rx[0], Ry[0], z, curve); + + uECC_vli_set(result, Rx[0], num_words); + uECC_vli_set(result + num_words, Ry[0], num_words); +} + +uECC_word_t regularize_k(const uECC_word_t * const k, uECC_word_t *k0, + uECC_word_t *k1, uECC_Curve curve) +{ + + wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits); + + bitcount_t num_n_bits = curve->num_n_bits; + + uECC_word_t carry = uECC_vli_add(k0, k, curve->n, num_n_words) || + (num_n_bits < ((bitcount_t)num_n_words * uECC_WORD_SIZE * 8) && + uECC_vli_testBit(k0, num_n_bits)); + + uECC_vli_add(k1, k0, curve->n, num_n_words); + + return carry; +} + +uECC_word_t EccPoint_compute_public_key(uECC_word_t *result, + uECC_word_t *private_key, + uECC_Curve curve) +{ + + uECC_word_t tmp1[NUM_ECC_WORDS]; + uECC_word_t tmp2[NUM_ECC_WORDS]; + uECC_word_t *p2[2] = {tmp1, tmp2}; + uECC_word_t carry; + + /* Regularize the bitcount for the private key so that attackers cannot + * use a side channel attack to learn the number of leading zeros. */ + carry = regularize_k(private_key, tmp1, tmp2, curve); + + EccPoint_mult(result, curve->G, p2[!carry], 0, curve->num_n_bits + 1, curve); + + if (EccPoint_isZero(result, curve)) { + return 0; + } + return 1; +} + +/* Converts an integer in uECC native format to big-endian bytes. */ +void uECC_vli_nativeToBytes(uint8_t *bytes, int num_bytes, + const unsigned int *native) +{ + wordcount_t i; + for (i = 0; i < num_bytes; ++i) { + unsigned b = num_bytes - 1 - i; + bytes[i] = native[b / uECC_WORD_SIZE] >> (8 * (b % uECC_WORD_SIZE)); + } +} + +/* Converts big-endian bytes to an integer in uECC native format. */ +void uECC_vli_bytesToNative(unsigned int *native, const uint8_t *bytes, + int num_bytes) +{ + wordcount_t i; + uECC_vli_clear(native, (num_bytes + (uECC_WORD_SIZE - 1)) / uECC_WORD_SIZE); + for (i = 0; i < num_bytes; ++i) { + unsigned b = num_bytes - 1 - i; + native[b / uECC_WORD_SIZE] |= + (uECC_word_t)bytes[i] << (8 * (b % uECC_WORD_SIZE)); + } +} + +int uECC_generate_random_int(uECC_word_t *random, const uECC_word_t *top, + wordcount_t num_words) +{ + uECC_word_t mask = (uECC_word_t)-1; + uECC_word_t tries; + bitcount_t num_bits = uECC_vli_numBits(top, num_words); + + if (!g_rng_function) { + return 0; + } + + for (tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) { + if (!g_rng_function((uint8_t *)random, num_words * uECC_WORD_SIZE)) { + return 0; + } + random[num_words - 1] &= + mask >> ((bitcount_t)(num_words * uECC_WORD_SIZE * 8 - num_bits)); + if (!uECC_vli_isZero(random, num_words) && + uECC_vli_cmp(top, random, num_words) == 1) { + return 1; + } + } + return 0; +} + + +int uECC_valid_point(const uECC_word_t *point, uECC_Curve curve) +{ + uECC_word_t tmp1[NUM_ECC_WORDS]; + uECC_word_t tmp2[NUM_ECC_WORDS]; + wordcount_t num_words = curve->num_words; + + /* The point at infinity is invalid. */ + if (EccPoint_isZero(point, curve)) { + return -1; + } + + /* x and y must be smaller than p. */ + if (uECC_vli_cmp_unsafe(curve->p, point, num_words) != 1 || + uECC_vli_cmp_unsafe(curve->p, point + num_words, num_words) != 1) { + return -2; + } + + uECC_vli_modSquare_fast(tmp1, point + num_words, curve); + curve->x_side(tmp2, point, curve); /* tmp2 = x^3 + ax + b */ + + /* Make sure that y^2 == x^3 + ax + b */ + if (uECC_vli_equal(tmp1, tmp2, num_words) != 0) + return -3; + + return 0; +} + +int uECC_valid_public_key(const uint8_t *public_key, uECC_Curve curve) +{ + + uECC_word_t _public[NUM_ECC_WORDS * 2]; + + uECC_vli_bytesToNative(_public, public_key, curve->num_bytes); + uECC_vli_bytesToNative( + _public + curve->num_words, + public_key + curve->num_bytes, + curve->num_bytes); + + if (uECC_vli_cmp_unsafe(_public, curve->G, NUM_ECC_WORDS * 2) == 0) { + return -4; + } + + return uECC_valid_point(_public, curve); +} + +int uECC_compute_public_key(const uint8_t *private_key, uint8_t *public_key, + uECC_Curve curve) +{ + + uECC_word_t _private[NUM_ECC_WORDS]; + uECC_word_t _public[NUM_ECC_WORDS * 2]; + + uECC_vli_bytesToNative( + _private, + private_key, + BITS_TO_BYTES(curve->num_n_bits)); + + /* Make sure the private key is in the range [1, n-1]. */ + if (uECC_vli_isZero(_private, BITS_TO_WORDS(curve->num_n_bits))) { + return 0; + } + + if (uECC_vli_cmp(curve->n, _private, BITS_TO_WORDS(curve->num_n_bits)) != 1) { + return 0; + } + + /* Compute public key. */ + if (!EccPoint_compute_public_key(_public, _private, curve)) { + return 0; + } + + uECC_vli_nativeToBytes(public_key, curve->num_bytes, _public); + uECC_vli_nativeToBytes( + public_key + + curve->num_bytes, curve->num_bytes, _public + curve->num_words); + return 1; +} + + + diff --git a/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/ecc_dh.c b/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/ecc_dh.c new file mode 100644 index 000000000..e5257d2d4 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/ecc_dh.c @@ -0,0 +1,200 @@ +/* ec_dh.c - TinyCrypt implementation of EC-DH */ + +/* + * Copyright (c) 2014, Kenneth MacKay + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Copyright (C) 2017 by Intel Corporation, All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include + +#if default_RNG_defined +static uECC_RNG_Function g_rng_function = &default_CSPRNG; +#else +static uECC_RNG_Function g_rng_function = 0; +#endif + +int uECC_make_key_with_d(uint8_t *public_key, uint8_t *private_key, + unsigned int *d, uECC_Curve curve) +{ + + uECC_word_t _private[NUM_ECC_WORDS]; + uECC_word_t _public[NUM_ECC_WORDS * 2]; + + /* This function is designed for test purposes-only (such as validating NIST + * test vectors) as it uses a provided value for d instead of generating + * it uniformly at random. */ + memcpy (_private, d, NUM_ECC_BYTES); + + /* Computing public-key from private: */ + if (EccPoint_compute_public_key(_public, _private, curve)) { + + /* Converting buffers to correct bit order: */ + uECC_vli_nativeToBytes(private_key, + BITS_TO_BYTES(curve->num_n_bits), + _private); + uECC_vli_nativeToBytes(public_key, + curve->num_bytes, + _public); + uECC_vli_nativeToBytes(public_key + curve->num_bytes, + curve->num_bytes, + _public + curve->num_words); + + /* erasing temporary buffer used to store secret: */ + memset(_private, 0, NUM_ECC_BYTES); + + return 1; + } + return 0; +} + +int uECC_make_key(uint8_t *public_key, uint8_t *private_key, uECC_Curve curve) +{ + + uECC_word_t _random[NUM_ECC_WORDS * 2]; + uECC_word_t _private[NUM_ECC_WORDS]; + uECC_word_t _public[NUM_ECC_WORDS * 2]; + uECC_word_t tries; + + for (tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) { + /* Generating _private uniformly at random: */ + uECC_RNG_Function rng_function = uECC_get_rng(); + if (!rng_function || + !rng_function((uint8_t *)_random, 2 * NUM_ECC_WORDS*uECC_WORD_SIZE)) { + return 0; + } + + /* computing modular reduction of _random (see FIPS 186.4 B.4.1): */ + uECC_vli_mmod(_private, _random, curve->n, BITS_TO_WORDS(curve->num_n_bits)); + + /* Computing public-key from private: */ + if (EccPoint_compute_public_key(_public, _private, curve)) { + + /* Converting buffers to correct bit order: */ + uECC_vli_nativeToBytes(private_key, + BITS_TO_BYTES(curve->num_n_bits), + _private); + uECC_vli_nativeToBytes(public_key, + curve->num_bytes, + _public); + uECC_vli_nativeToBytes(public_key + curve->num_bytes, + curve->num_bytes, + _public + curve->num_words); + + /* erasing temporary buffer that stored secret: */ + memset(_private, 0, NUM_ECC_BYTES); + + return 1; + } + } + return 0; +} + +int uECC_shared_secret(const uint8_t *public_key, const uint8_t *private_key, + uint8_t *secret, uECC_Curve curve) +{ + + uECC_word_t _public[NUM_ECC_WORDS * 2]; + uECC_word_t _private[NUM_ECC_WORDS]; + + uECC_word_t tmp[NUM_ECC_WORDS]; + uECC_word_t *p2[2] = {_private, tmp}; + uECC_word_t *initial_Z = 0; + uECC_word_t carry; + wordcount_t num_words = curve->num_words; + wordcount_t num_bytes = curve->num_bytes; + int r; + + /* Converting buffers to correct bit order: */ + uECC_vli_bytesToNative(_private, + private_key, + BITS_TO_BYTES(curve->num_n_bits)); + uECC_vli_bytesToNative(_public, + public_key, + num_bytes); + uECC_vli_bytesToNative(_public + num_words, + public_key + num_bytes, + num_bytes); + + /* Regularize the bitcount for the private key so that attackers cannot use a + * side channel attack to learn the number of leading zeros. */ + carry = regularize_k(_private, _private, tmp, curve); + + /* If an RNG function was specified, try to get a random initial Z value to + * improve protection against side-channel attacks. */ + if (g_rng_function) { + if (!uECC_generate_random_int(p2[carry], curve->p, num_words)) { + r = 0; + goto clear_and_out; + } + initial_Z = p2[carry]; + } + + EccPoint_mult(_public, _public, p2[!carry], initial_Z, curve->num_n_bits + 1, + curve); + + uECC_vli_nativeToBytes(secret, num_bytes, _public); + r = !EccPoint_isZero(_public, curve); + +clear_and_out: + /* erasing temporary buffer used to store secret: */ + memset(p2, 0, sizeof(p2)); + __asm__ __volatile__("" :: "g"(p2) : "memory"); + memset(tmp, 0, sizeof(tmp)); + __asm__ __volatile__("" :: "g"(tmp) : "memory"); + memset(_private, 0, sizeof(_private)); + __asm__ __volatile__("" :: "g"(_private) : "memory"); + + return r; +} diff --git a/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/ecc_dsa.c b/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/ecc_dsa.c new file mode 100644 index 000000000..064dfe5ae --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/ecc_dsa.c @@ -0,0 +1,295 @@ +/* ec_dsa.c - TinyCrypt implementation of EC-DSA */ + +/* Copyright (c) 2014, Kenneth MacKay + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE.*/ + +/* + * Copyright (C) 2017 by Intel Corporation, All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +#if default_RNG_defined +static uECC_RNG_Function g_rng_function = &default_CSPRNG; +#else +static uECC_RNG_Function g_rng_function = 0; +#endif + +static void bits2int(uECC_word_t *native, const uint8_t *bits, + unsigned bits_size, uECC_Curve curve) +{ + unsigned num_n_bytes = BITS_TO_BYTES(curve->num_n_bits); + unsigned num_n_words = BITS_TO_WORDS(curve->num_n_bits); + int shift; + uECC_word_t carry; + uECC_word_t *ptr; + + if (bits_size > num_n_bytes) { + bits_size = num_n_bytes; + } + + uECC_vli_clear(native, num_n_words); + uECC_vli_bytesToNative(native, bits, bits_size); + if (bits_size * 8 <= (unsigned)curve->num_n_bits) { + return; + } + shift = bits_size * 8 - curve->num_n_bits; + carry = 0; + ptr = native + num_n_words; + while (ptr-- > native) { + uECC_word_t temp = *ptr; + *ptr = (temp >> shift) | carry; + carry = temp << (uECC_WORD_BITS - shift); + } + + /* Reduce mod curve_n */ + if (uECC_vli_cmp_unsafe(curve->n, native, num_n_words) != 1) { + uECC_vli_sub(native, native, curve->n, num_n_words); + } +} + +int uECC_sign_with_k(const uint8_t *private_key, const uint8_t *message_hash, + unsigned hash_size, uECC_word_t *k, uint8_t *signature, + uECC_Curve curve) +{ + + uECC_word_t tmp[NUM_ECC_WORDS]; + uECC_word_t s[NUM_ECC_WORDS]; + uECC_word_t *k2[2] = {tmp, s}; + uECC_word_t p[NUM_ECC_WORDS * 2]; + uECC_word_t carry; + wordcount_t num_words = curve->num_words; + wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits); + bitcount_t num_n_bits = curve->num_n_bits; + + /* Make sure 0 < k < curve_n */ + if (uECC_vli_isZero(k, num_words) || + uECC_vli_cmp(curve->n, k, num_n_words) != 1) { + return 0; + } + + carry = regularize_k(k, tmp, s, curve); + EccPoint_mult(p, curve->G, k2[!carry], 0, num_n_bits + 1, curve); + if (uECC_vli_isZero(p, num_words)) { + return 0; + } + + /* If an RNG function was specified, get a random number + to prevent side channel analysis of k. */ + if (!g_rng_function) { + uECC_vli_clear(tmp, num_n_words); + tmp[0] = 1; + } + else if (!uECC_generate_random_int(tmp, curve->n, num_n_words)) { + return 0; + } + + /* Prevent side channel analysis of uECC_vli_modInv() to determine + bits of k / the private key by premultiplying by a random number */ + uECC_vli_modMult(k, k, tmp, curve->n, num_n_words); /* k' = rand * k */ + uECC_vli_modInv(k, k, curve->n, num_n_words); /* k = 1 / k' */ + uECC_vli_modMult(k, k, tmp, curve->n, num_n_words); /* k = 1 / k */ + + uECC_vli_nativeToBytes(signature, curve->num_bytes, p); /* store r */ + + /* tmp = d: */ + uECC_vli_bytesToNative(tmp, private_key, BITS_TO_BYTES(curve->num_n_bits)); + + s[num_n_words - 1] = 0; + uECC_vli_set(s, p, num_words); + uECC_vli_modMult(s, tmp, s, curve->n, num_n_words); /* s = r*d */ + + bits2int(tmp, message_hash, hash_size, curve); + uECC_vli_modAdd(s, tmp, s, curve->n, num_n_words); /* s = e + r*d */ + uECC_vli_modMult(s, s, k, curve->n, num_n_words); /* s = (e + r*d) / k */ + if (uECC_vli_numBits(s, num_n_words) > (bitcount_t)curve->num_bytes * 8) { + return 0; + } + + uECC_vli_nativeToBytes(signature + curve->num_bytes, curve->num_bytes, s); + return 1; +} + +int uECC_sign(const uint8_t *private_key, const uint8_t *message_hash, + unsigned hash_size, uint8_t *signature, uECC_Curve curve) +{ + uECC_word_t _random[2*NUM_ECC_WORDS]; + uECC_word_t k[NUM_ECC_WORDS]; + uECC_word_t tries; + + for (tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) { + /* Generating _random uniformly at random: */ + uECC_RNG_Function rng_function = uECC_get_rng(); + if (!rng_function || + !rng_function((uint8_t *)_random, 2*NUM_ECC_WORDS*uECC_WORD_SIZE)) { + return 0; + } + + // computing k as modular reduction of _random (see FIPS 186.4 B.5.1): + uECC_vli_mmod(k, _random, curve->n, BITS_TO_WORDS(curve->num_n_bits)); + + if (uECC_sign_with_k(private_key, message_hash, hash_size, k, signature, + curve)) { + return 1; + } + } + return 0; +} + +static bitcount_t smax(bitcount_t a, bitcount_t b) +{ + return (a > b ? a : b); +} + +int uECC_verify(const uint8_t *public_key, const uint8_t *message_hash, + unsigned hash_size, const uint8_t *signature, + uECC_Curve curve) +{ + + uECC_word_t u1[NUM_ECC_WORDS], u2[NUM_ECC_WORDS]; + uECC_word_t z[NUM_ECC_WORDS]; + uECC_word_t sum[NUM_ECC_WORDS * 2]; + uECC_word_t rx[NUM_ECC_WORDS]; + uECC_word_t ry[NUM_ECC_WORDS]; + uECC_word_t tx[NUM_ECC_WORDS]; + uECC_word_t ty[NUM_ECC_WORDS]; + uECC_word_t tz[NUM_ECC_WORDS]; + const uECC_word_t *points[4]; + const uECC_word_t *point; + bitcount_t num_bits; + bitcount_t i; + + uECC_word_t _public[NUM_ECC_WORDS * 2]; + uECC_word_t r[NUM_ECC_WORDS], s[NUM_ECC_WORDS]; + wordcount_t num_words = curve->num_words; + wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits); + + rx[num_n_words - 1] = 0; + r[num_n_words - 1] = 0; + s[num_n_words - 1] = 0; + + uECC_vli_bytesToNative(_public, public_key, curve->num_bytes); + uECC_vli_bytesToNative(_public + num_words, public_key + curve->num_bytes, + curve->num_bytes); + uECC_vli_bytesToNative(r, signature, curve->num_bytes); + uECC_vli_bytesToNative(s, signature + curve->num_bytes, curve->num_bytes); + + /* r, s must not be 0. */ + if (uECC_vli_isZero(r, num_words) || uECC_vli_isZero(s, num_words)) { + return 0; + } + + /* r, s must be < n. */ + if (uECC_vli_cmp_unsafe(curve->n, r, num_n_words) != 1 || + uECC_vli_cmp_unsafe(curve->n, s, num_n_words) != 1) { + return 0; + } + + /* Calculate u1 and u2. */ + uECC_vli_modInv(z, s, curve->n, num_n_words); /* z = 1/s */ + u1[num_n_words - 1] = 0; + bits2int(u1, message_hash, hash_size, curve); + uECC_vli_modMult(u1, u1, z, curve->n, num_n_words); /* u1 = e/s */ + uECC_vli_modMult(u2, r, z, curve->n, num_n_words); /* u2 = r/s */ + + /* Calculate sum = G + Q. */ + uECC_vli_set(sum, _public, num_words); + uECC_vli_set(sum + num_words, _public + num_words, num_words); + uECC_vli_set(tx, curve->G, num_words); + uECC_vli_set(ty, curve->G + num_words, num_words); + uECC_vli_modSub(z, sum, tx, curve->p, num_words); /* z = x2 - x1 */ + XYcZ_add(tx, ty, sum, sum + num_words, curve); + uECC_vli_modInv(z, z, curve->p, num_words); /* z = 1/z */ + apply_z(sum, sum + num_words, z, curve); + + /* Use Shamir's trick to calculate u1*G + u2*Q */ + points[0] = 0; + points[1] = curve->G; + points[2] = _public; + points[3] = sum; + num_bits = smax(uECC_vli_numBits(u1, num_n_words), + uECC_vli_numBits(u2, num_n_words)); + + point = points[(!!uECC_vli_testBit(u1, num_bits - 1)) | + ((!!uECC_vli_testBit(u2, num_bits - 1)) << 1)]; + uECC_vli_set(rx, point, num_words); + uECC_vli_set(ry, point + num_words, num_words); + uECC_vli_clear(z, num_words); + z[0] = 1; + + for (i = num_bits - 2; i >= 0; --i) { + uECC_word_t index; + curve->double_jacobian(rx, ry, z, curve); + + index = (!!uECC_vli_testBit(u1, i)) | ((!!uECC_vli_testBit(u2, i)) << 1); + point = points[index]; + if (point) { + uECC_vli_set(tx, point, num_words); + uECC_vli_set(ty, point + num_words, num_words); + apply_z(tx, ty, z, curve); + uECC_vli_modSub(tz, rx, tx, curve->p, num_words); /* Z = x2 - x1 */ + XYcZ_add(tx, ty, rx, ry, curve); + uECC_vli_modMult_fast(z, z, tz, curve); + } + } + + uECC_vli_modInv(z, z, curve->p, num_words); /* Z = 1/Z */ + apply_z(rx, ry, z, curve); + + /* v = x1 (mod n) */ + if (uECC_vli_cmp_unsafe(curve->n, rx, num_n_words) != 1) { + uECC_vli_sub(rx, rx, curve->n, num_n_words); + } + + /* Accept only if v == r. */ + return (int)(uECC_vli_equal(rx, r, num_words) == 0); +} + diff --git a/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/ecc_platform_specific.c b/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/ecc_platform_specific.c new file mode 100644 index 000000000..1867988f9 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/ecc_platform_specific.c @@ -0,0 +1,105 @@ +/* uECC_platform_specific.c - Implementation of platform specific functions*/ + +/* Copyright (c) 2014, Kenneth MacKay + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE.*/ + +/* + * Copyright (C) 2017 by Intel Corporation, All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * uECC_platform_specific.c -- Implementation of platform specific functions + */ + + +#if defined(unix) || defined(__linux__) || defined(__unix__) || \ + defined(__unix) | (defined(__APPLE__) && defined(__MACH__)) || \ + defined(uECC_POSIX) + +/* Some POSIX-like system with /dev/urandom or /dev/random. */ +#include +#include +#include + +#include + +#ifndef O_CLOEXEC +#define O_CLOEXEC 0 +#endif + +int default_CSPRNG(uint8_t *dest, unsigned int size) { + + /* input sanity check: */ + if (dest == (uint8_t *) 0 || (size <= 0)) + return 0; + + int fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC); + if (fd == -1) { + fd = open("/dev/random", O_RDONLY | O_CLOEXEC); + if (fd == -1) { + return 0; + } + } + + char *ptr = (char *)dest; + size_t left = (size_t) size; + while (left > 0) { + ssize_t bytes_read = read(fd, ptr, left); + if (bytes_read <= 0) { // read failed + close(fd); + return 0; + } + left -= bytes_read; + ptr += bytes_read; + } + + close(fd); + return 1; +} + +#endif /* platform */ + diff --git a/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/hmac.c b/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/hmac.c new file mode 100644 index 000000000..89878cec7 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/hmac.c @@ -0,0 +1,148 @@ +/* hmac.c - TinyCrypt implementation of the HMAC algorithm */ + +/* + * Copyright (C) 2017 by Intel Corporation, All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +static void rekey(uint8_t *key, const uint8_t *new_key, unsigned int key_size) +{ + const uint8_t inner_pad = (uint8_t) 0x36; + const uint8_t outer_pad = (uint8_t) 0x5c; + unsigned int i; + + for (i = 0; i < key_size; ++i) { + key[i] = inner_pad ^ new_key[i]; + key[i + TC_SHA256_BLOCK_SIZE] = outer_pad ^ new_key[i]; + } + for (; i < TC_SHA256_BLOCK_SIZE; ++i) { + key[i] = inner_pad; key[i + TC_SHA256_BLOCK_SIZE] = outer_pad; + } +} + +int tc_hmac_set_key(TCHmacState_t ctx, const uint8_t *key, + unsigned int key_size) +{ + + /* input sanity check: */ + if (ctx == (TCHmacState_t) 0 || + key == (const uint8_t *) 0 || + key_size == 0) { + return TC_CRYPTO_FAIL; + } + + const uint8_t dummy_key[key_size]; + struct tc_hmac_state_struct dummy_state; + + if (key_size <= TC_SHA256_BLOCK_SIZE) { + /* + * The next three lines consist of dummy calls just to avoid + * certain timing attacks. Without these dummy calls, + * adversaries would be able to learn whether the key_size is + * greater than TC_SHA256_BLOCK_SIZE by measuring the time + * consumed in this process. + */ + (void)tc_sha256_init(&dummy_state.hash_state); + (void)tc_sha256_update(&dummy_state.hash_state, + dummy_key, + key_size); + (void)tc_sha256_final(&dummy_state.key[TC_SHA256_DIGEST_SIZE], + &dummy_state.hash_state); + + /* Actual code for when key_size <= TC_SHA256_BLOCK_SIZE: */ + rekey(ctx->key, key, key_size); + } else { + (void)tc_sha256_init(&ctx->hash_state); + (void)tc_sha256_update(&ctx->hash_state, key, key_size); + (void)tc_sha256_final(&ctx->key[TC_SHA256_DIGEST_SIZE], + &ctx->hash_state); + rekey(ctx->key, + &ctx->key[TC_SHA256_DIGEST_SIZE], + TC_SHA256_DIGEST_SIZE); + } + + return TC_CRYPTO_SUCCESS; +} + +int tc_hmac_init(TCHmacState_t ctx) +{ + + /* input sanity check: */ + if (ctx == (TCHmacState_t) 0) { + return TC_CRYPTO_FAIL; + } + + (void) tc_sha256_init(&ctx->hash_state); + (void) tc_sha256_update(&ctx->hash_state, ctx->key, TC_SHA256_BLOCK_SIZE); + + return TC_CRYPTO_SUCCESS; +} + +int tc_hmac_update(TCHmacState_t ctx, + const void *data, + unsigned int data_length) +{ + + /* input sanity check: */ + if (ctx == (TCHmacState_t) 0) { + return TC_CRYPTO_FAIL; + } + + (void)tc_sha256_update(&ctx->hash_state, data, data_length); + + return TC_CRYPTO_SUCCESS; +} + +int tc_hmac_final(uint8_t *tag, unsigned int taglen, TCHmacState_t ctx) +{ + + /* input sanity check: */ + if (tag == (uint8_t *) 0 || + taglen != TC_SHA256_DIGEST_SIZE || + ctx == (TCHmacState_t) 0) { + return TC_CRYPTO_FAIL; + } + + (void) tc_sha256_final(tag, &ctx->hash_state); + + (void)tc_sha256_init(&ctx->hash_state); + (void)tc_sha256_update(&ctx->hash_state, + &ctx->key[TC_SHA256_BLOCK_SIZE], + TC_SHA256_BLOCK_SIZE); + (void)tc_sha256_update(&ctx->hash_state, tag, TC_SHA256_DIGEST_SIZE); + (void)tc_sha256_final(tag, &ctx->hash_state); + + /* destroy the current state */ + _set(ctx, 0, sizeof(*ctx)); + + return TC_CRYPTO_SUCCESS; +} diff --git a/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/hmac_prng.c b/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/hmac_prng.c new file mode 100644 index 000000000..68b5b1faf --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/hmac_prng.c @@ -0,0 +1,212 @@ +/* hmac_prng.c - TinyCrypt implementation of HMAC-PRNG */ + +/* + * Copyright (C) 2017 by Intel Corporation, All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +/* + * min bytes in the seed string. + * MIN_SLEN*8 must be at least the expected security level. + */ +static const unsigned int MIN_SLEN = 32; + +/* + * max bytes in the seed string; + * SP800-90A specifies a maximum of 2^35 bits (i.e., 2^32 bytes). + */ +static const unsigned int MAX_SLEN = UINT32_MAX; + +/* + * max bytes in the personalization string; + * SP800-90A specifies a maximum of 2^35 bits (i.e., 2^32 bytes). + */ +static const unsigned int MAX_PLEN = UINT32_MAX; + +/* + * max bytes in the additional_info string; + * SP800-90A specifies a maximum of 2^35 bits (i.e., 2^32 bytes). + */ +static const unsigned int MAX_ALEN = UINT32_MAX; + +/* + * max number of generates between re-seeds; + * TinyCrypt accepts up to (2^32 - 1) which is the maximal value of + * a 32-bit unsigned int variable, while SP800-90A specifies a maximum of 2^48. + */ +static const unsigned int MAX_GENS = UINT32_MAX; + +/* + * maximum bytes per generate call; + * SP800-90A specifies a maximum up to 2^19. + */ +static const unsigned int MAX_OUT = (1 << 19); + +/* + * Assumes: prng != NULL, e != NULL, len >= 0. + */ +static void update(TCHmacPrng_t prng, const uint8_t *e, unsigned int len) +{ + const uint8_t separator0 = 0x00; + const uint8_t separator1 = 0x01; + + /* use current state, e and separator 0 to compute a new prng key: */ + (void)tc_hmac_init(&prng->h); + (void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v)); + (void)tc_hmac_update(&prng->h, &separator0, sizeof(separator0)); + (void)tc_hmac_update(&prng->h, e, len); + (void)tc_hmac_final(prng->key, sizeof(prng->key), &prng->h); + /* configure the new prng key into the prng's instance of hmac */ + (void)tc_hmac_set_key(&prng->h, prng->key, sizeof(prng->key)); + + /* use the new key to compute a new state variable v */ + (void)tc_hmac_init(&prng->h); + (void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v)); + (void)tc_hmac_final(prng->v, sizeof(prng->v), &prng->h); + + /* use current state, e and separator 1 to compute a new prng key: */ + (void)tc_hmac_init(&prng->h); + (void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v)); + (void)tc_hmac_update(&prng->h, &separator1, sizeof(separator1)); + (void)tc_hmac_update(&prng->h, e, len); + (void)tc_hmac_final(prng->key, sizeof(prng->key), &prng->h); + /* configure the new prng key into the prng's instance of hmac */ + (void)tc_hmac_set_key(&prng->h, prng->key, sizeof(prng->key)); + + /* use the new key to compute a new state variable v */ + (void)tc_hmac_init(&prng->h); + (void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v)); + (void)tc_hmac_final(prng->v, sizeof(prng->v), &prng->h); +} + +int tc_hmac_prng_init(TCHmacPrng_t prng, + const uint8_t *personalization, + unsigned int plen) +{ + + /* input sanity check: */ + if (prng == (TCHmacPrng_t) 0 || + personalization == (uint8_t *) 0 || + plen > MAX_PLEN) { + return TC_CRYPTO_FAIL; + } + + /* put the generator into a known state: */ + _set(prng->key, 0x00, sizeof(prng->key)); + _set(prng->v, 0x01, sizeof(prng->v)); + tc_hmac_set_key(&prng->h, prng->key, sizeof(prng->key)); + /* update assumes SOME key has been configured into HMAC */ + + update(prng, personalization, plen); + + /* force a reseed before allowing tc_hmac_prng_generate to succeed: */ + prng->countdown = 0; + + return TC_CRYPTO_SUCCESS; +} + +int tc_hmac_prng_reseed(TCHmacPrng_t prng, + const uint8_t *seed, + unsigned int seedlen, + const uint8_t *additional_input, + unsigned int additionallen) +{ + + /* input sanity check: */ + if (prng == (TCHmacPrng_t) 0 || + seed == (const uint8_t *) 0 || + seedlen < MIN_SLEN || + seedlen > MAX_SLEN) { + return TC_CRYPTO_FAIL; + } + + if (additional_input != (const uint8_t *) 0) { + /* + * Abort if additional_input is provided but has inappropriate + * length + */ + if (additionallen == 0 || + additionallen > MAX_ALEN) { + return TC_CRYPTO_FAIL; + } else { + /* call update for the seed and additional_input */ + update(prng, seed, seedlen); + update(prng, additional_input, additionallen); + } + } else { + /* call update only for the seed */ + update(prng, seed, seedlen); + } + + /* ... and enable hmac_prng_generate */ + prng->countdown = MAX_GENS; + + return TC_CRYPTO_SUCCESS; +} + +int tc_hmac_prng_generate(uint8_t *out, unsigned int outlen, TCHmacPrng_t prng) +{ + unsigned int bufferlen; + + /* input sanity check: */ + if (out == (uint8_t *) 0 || + prng == (TCHmacPrng_t) 0 || + outlen == 0 || + outlen > MAX_OUT) { + return TC_CRYPTO_FAIL; + } else if (prng->countdown == 0) { + return TC_HMAC_PRNG_RESEED_REQ; + } + + prng->countdown--; + + while (outlen != 0) { + /* operate HMAC in OFB mode to create "random" outputs */ + (void)tc_hmac_init(&prng->h); + (void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v)); + (void)tc_hmac_final(prng->v, sizeof(prng->v), &prng->h); + + bufferlen = (TC_SHA256_DIGEST_SIZE > outlen) ? + outlen : TC_SHA256_DIGEST_SIZE; + (void)_copy(out, bufferlen, prng->v, bufferlen); + + out += bufferlen; + outlen = (outlen > TC_SHA256_DIGEST_SIZE) ? + (outlen - TC_SHA256_DIGEST_SIZE) : 0; + } + + /* block future PRNG compromises from revealing past state */ + update(prng, prng->v, TC_SHA256_DIGEST_SIZE); + + return TC_CRYPTO_SUCCESS; +} diff --git a/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/sha256.c b/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/sha256.c new file mode 100644 index 000000000..b4efd2044 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/sha256.c @@ -0,0 +1,217 @@ +/* sha256.c - TinyCrypt SHA-256 crypto hash algorithm implementation */ + +/* + * Copyright (C) 2017 by Intel Corporation, All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +static void compress(unsigned int *iv, const uint8_t *data); + +int tc_sha256_init(TCSha256State_t s) +{ + /* input sanity check: */ + if (s == (TCSha256State_t) 0) { + return TC_CRYPTO_FAIL; + } + + /* + * Setting the initial state values. + * These values correspond to the first 32 bits of the fractional parts + * of the square roots of the first 8 primes: 2, 3, 5, 7, 11, 13, 17 + * and 19. + */ + _set((uint8_t *) s, 0x00, sizeof(*s)); + s->iv[0] = 0x6a09e667; + s->iv[1] = 0xbb67ae85; + s->iv[2] = 0x3c6ef372; + s->iv[3] = 0xa54ff53a; + s->iv[4] = 0x510e527f; + s->iv[5] = 0x9b05688c; + s->iv[6] = 0x1f83d9ab; + s->iv[7] = 0x5be0cd19; + + return TC_CRYPTO_SUCCESS; +} + +int tc_sha256_update(TCSha256State_t s, const uint8_t *data, size_t datalen) +{ + /* input sanity check: */ + if (s == (TCSha256State_t) 0 || + data == (void *) 0) { + return TC_CRYPTO_FAIL; + } else if (datalen == 0) { + return TC_CRYPTO_SUCCESS; + } + + while (datalen-- > 0) { + s->leftover[s->leftover_offset++] = *(data++); + if (s->leftover_offset >= TC_SHA256_BLOCK_SIZE) { + compress(s->iv, s->leftover); + s->leftover_offset = 0; + s->bits_hashed += (TC_SHA256_BLOCK_SIZE << 3); + } + } + + return TC_CRYPTO_SUCCESS; +} + +int tc_sha256_final(uint8_t *digest, TCSha256State_t s) +{ + unsigned int i; + + /* input sanity check: */ + if (digest == (uint8_t *) 0 || + s == (TCSha256State_t) 0) { + return TC_CRYPTO_FAIL; + } + + s->bits_hashed += (s->leftover_offset << 3); + + s->leftover[s->leftover_offset++] = 0x80; /* always room for one byte */ + if (s->leftover_offset > (sizeof(s->leftover) - 8)) { + /* there is not room for all the padding in this block */ + _set(s->leftover + s->leftover_offset, 0x00, + sizeof(s->leftover) - s->leftover_offset); + compress(s->iv, s->leftover); + s->leftover_offset = 0; + } + + /* add the padding and the length in big-Endian format */ + _set(s->leftover + s->leftover_offset, 0x00, + sizeof(s->leftover) - 8 - s->leftover_offset); + s->leftover[sizeof(s->leftover) - 1] = (uint8_t)(s->bits_hashed); + s->leftover[sizeof(s->leftover) - 2] = (uint8_t)(s->bits_hashed >> 8); + s->leftover[sizeof(s->leftover) - 3] = (uint8_t)(s->bits_hashed >> 16); + s->leftover[sizeof(s->leftover) - 4] = (uint8_t)(s->bits_hashed >> 24); + s->leftover[sizeof(s->leftover) - 5] = (uint8_t)(s->bits_hashed >> 32); + s->leftover[sizeof(s->leftover) - 6] = (uint8_t)(s->bits_hashed >> 40); + s->leftover[sizeof(s->leftover) - 7] = (uint8_t)(s->bits_hashed >> 48); + s->leftover[sizeof(s->leftover) - 8] = (uint8_t)(s->bits_hashed >> 56); + + /* hash the padding and length */ + compress(s->iv, s->leftover); + + /* copy the iv out to digest */ + for (i = 0; i < TC_SHA256_STATE_BLOCKS; ++i) { + unsigned int t = *((unsigned int *) &s->iv[i]); + *digest++ = (uint8_t)(t >> 24); + *digest++ = (uint8_t)(t >> 16); + *digest++ = (uint8_t)(t >> 8); + *digest++ = (uint8_t)(t); + } + + /* destroy the current state */ + _set(s, 0, sizeof(*s)); + + return TC_CRYPTO_SUCCESS; +} + +/* + * Initializing SHA-256 Hash constant words K. + * These values correspond to the first 32 bits of the fractional parts of the + * cube roots of the first 64 primes between 2 and 311. + */ +static const unsigned int k256[64] = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, + 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, + 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, + 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, + 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, + 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +}; + +static inline unsigned int ROTR(unsigned int a, unsigned int n) +{ + return (((a) >> n) | ((a) << (32 - n))); +} + +#define Sigma0(a)(ROTR((a), 2) ^ ROTR((a), 13) ^ ROTR((a), 22)) +#define Sigma1(a)(ROTR((a), 6) ^ ROTR((a), 11) ^ ROTR((a), 25)) +#define sigma0(a)(ROTR((a), 7) ^ ROTR((a), 18) ^ ((a) >> 3)) +#define sigma1(a)(ROTR((a), 17) ^ ROTR((a), 19) ^ ((a) >> 10)) + +#define Ch(a, b, c)(((a) & (b)) ^ ((~(a)) & (c))) +#define Maj(a, b, c)(((a) & (b)) ^ ((a) & (c)) ^ ((b) & (c))) + +static inline unsigned int BigEndian(const uint8_t **c) +{ + unsigned int n = 0; + + n = (((unsigned int)(*((*c)++))) << 24); + n |= ((unsigned int)(*((*c)++)) << 16); + n |= ((unsigned int)(*((*c)++)) << 8); + n |= ((unsigned int)(*((*c)++))); + return n; +} + +static void compress(unsigned int *iv, const uint8_t *data) +{ + unsigned int a, b, c, d, e, f, g, h; + unsigned int s0, s1; + unsigned int t1, t2; + unsigned int work_space[16]; + unsigned int n; + unsigned int i; + + a = iv[0]; b = iv[1]; c = iv[2]; d = iv[3]; + e = iv[4]; f = iv[5]; g = iv[6]; h = iv[7]; + + for (i = 0; i < 16; ++i) { + n = BigEndian(&data); + t1 = work_space[i] = n; + t1 += h + Sigma1(e) + Ch(e, f, g) + k256[i]; + t2 = Sigma0(a) + Maj(a, b, c); + h = g; g = f; f = e; e = d + t1; + d = c; c = b; b = a; a = t1 + t2; + } + + for ( ; i < 64; ++i) { + s0 = work_space[(i+1)&0x0f]; + s0 = sigma0(s0); + s1 = work_space[(i+14)&0x0f]; + s1 = sigma1(s1); + + t1 = work_space[i&0xf] += s0 + s1 + work_space[(i+9)&0xf]; + t1 += h + Sigma1(e) + Ch(e, f, g) + k256[i]; + t2 = Sigma0(a) + Maj(a, b, c); + h = g; g = f; f = e; e = d + t1; + d = c; c = b; b = a; a = t1 + t2; + } + + iv[0] += a; iv[1] += b; iv[2] += c; iv[3] += d; + iv[4] += e; iv[5] += f; iv[6] += g; iv[7] += h; +} diff --git a/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/utils.c b/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/utils.c new file mode 100644 index 000000000..13cc49512 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/ext/tinycrypt/src/utils.c @@ -0,0 +1,74 @@ +/* utils.c - TinyCrypt platform-dependent run-time operations */ + +/* + * Copyright (C) 2017 by Intel Corporation, All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +#include + +#define MASK_TWENTY_SEVEN 0x1b + +unsigned int _copy(uint8_t *to, unsigned int to_len, + const uint8_t *from, unsigned int from_len) +{ + if (from_len <= to_len) { + (void)memcpy(to, from, from_len); + return from_len; + } else { + return TC_CRYPTO_FAIL; + } +} + +void _set(void *to, uint8_t val, unsigned int len) +{ + (void)memset(to, val, len); +} + +/* + * Doubles the value of a byte for values up to 127. + */ +uint8_t _double_byte(uint8_t a) +{ + return ((a<<1) ^ ((a>>7) * MASK_TWENTY_SEVEN)); +} + +int _compare(const uint8_t *a, const uint8_t *b, size_t size) +{ + const uint8_t *tempa = a; + const uint8_t *tempb = b; + uint8_t result = 0; + + for (unsigned int i = 0; i < size; i++) { + result |= tempa[i] ^ tempb[i]; + } + return result; +} diff --git a/libesp32/NimBLE-Arduino/src/hal/hal_timer.h b/libesp32/NimBLE-Arduino/src/hal/hal_timer.h new file mode 100644 index 000000000..be41c6095 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/hal/hal_timer.h @@ -0,0 +1,173 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + +/** + * @addtogroup HAL + * @{ + * @defgroup HALTimer HAL Timer + * @{ + */ + +#ifndef H_HAL_TIMER_ +#define H_HAL_TIMER_ + +#include +#include "os/queue.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* HAL timer callback */ +typedef void (*hal_timer_cb)(void *arg); + +/** + * The HAL timer structure. The user can declare as many of these structures + * as desired. They are enqueued on a particular HW timer queue when the user + * calls the :c:func:`hal_timer_start()` or :c:func:`hal_timer_start_at()` API. + * The user must have called :c:func:`hal_timer_set_cb()` before starting a + * timer. + * + * NOTE: the user should not have to modify/examine the contents of this + * structure; the hal timer API should be used. + */ +struct hal_timer { + /** Internal platform specific pointer */ + void *bsp_timer; + /** Callback function */ + hal_timer_cb cb_func; + /** Callback argument */ + void *cb_arg; + /** Tick at which timer should expire */ + uint32_t expiry; + TAILQ_ENTRY(hal_timer) link; /* Queue linked list structure */ +}; + +/** + * Initialize a HW timer. + * + * @param timer_num The number of the HW timer to initialize + * @param cfg Hardware specific timer configuration. This is + * passed from BSP directly to the MCU specific driver. + */ +int hal_timer_init(int timer_num, void *cfg); + +/** + * Un-initialize a HW timer. + * + * @param timer_num The number of the HW timer to un-initialize + */ +int hal_timer_deinit(int timer_num); + +/** + * Config a HW timer at the given frequency and start it. If the exact + * frequency is not obtainable the closest obtainable frequency is set. + * + * @param timer_num The number of the HW timer to configure + * @param freq_hz The frequency in Hz to configure the timer at + * + * @return 0 on success, non-zero error code on failure + */ +int hal_timer_config(int timer_num, uint32_t freq_hz); + +/** + * Returns the resolution of the HW timer. NOTE: the frequency may not be + * obtainable so the caller can use this to determine the resolution. + * Returns resolution in nanoseconds. A return value of 0 indicates an invalid + * timer was used. + * + * @param timer_num The number of the HW timer to get resolution for + * + * @return The resolution of the timer + */ +uint32_t hal_timer_get_resolution(int timer_num); + +/** + * Returns the HW timer current tick value + * + * @param timer_num The HW timer to read the tick value from + * + * @return The current tick value + */ +uint32_t hal_timer_read(int timer_num); + +/** + * Perform a blocking delay for a number of ticks. + * + * @param timer_num The timer number to use for the blocking delay + * @param ticks The number of ticks to delay for + * + * @return 0 on success, non-zero error code on failure + */ +int hal_timer_delay(int timer_num, uint32_t ticks); + +/** + * Set the timer structure prior to use. Should not be called if the timer + * is running. Must be called at least once prior to using timer. + * + * @param timer_num The number of the HW timer to configure the callback on + * @param tmr The timer structure to use for this timer + * @param cb_func The timer callback to call when the timer fires + * @param arg An opaque argument to provide the timer callback + * + * @return 0 on success, non-zero error code on failure. + */ +int hal_timer_set_cb(int timer_num, struct hal_timer *tmr, hal_timer_cb cb_func, + void *arg); + +/** + * Start a timer that will expire in 'ticks' ticks. Ticks cannot be 0 + * + * @param tmr The timer to start + * @param ticks The number of ticks to expire the timer in + * + * @return 0 on success, non-zero error code on failure. + */ +int hal_timer_start(struct hal_timer *tmr, uint32_t ticks); + +/** + * Start a timer that will expire when the timer reaches 'tick'. If tick + * has already passed the timer callback will be called "immediately" (at + * interrupt context). + * + * @param tmr The timer to start + * @param tick The absolute tick value to fire the timer at + * + * @return 0 on success, non-zero error code on failure. + */ +int hal_timer_start_at(struct hal_timer *tmr, uint32_t tick); + +/** + * Stop a currently running timer; associated callback will NOT be called + * + * @param tmr The timer to stop + */ +int hal_timer_stop(struct hal_timer *tmr); + +#ifdef __cplusplus +} +#endif + +#endif /* H_HAL_TIMER_ */ + +/** + * @} HALTimer + * @} HAL + */ diff --git a/libesp32/NimBLE-Arduino/src/host/ble_att.h b/libesp32/NimBLE-Arduino/src/host/ble_att.h new file mode 100644 index 000000000..391a992ae --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/host/ble_att.h @@ -0,0 +1,194 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_BLE_ATT_ +#define H_BLE_ATT_ + +/** + * @brief Bluetooth Attribute Protocol (ATT) + * @defgroup bt_att Bluetooth Attribute Protocol (ATT) + * @ingroup bt_host + * @{ + */ + +#include "os/queue.h" +#ifdef __cplusplus +extern "C" { +#endif + +struct os_mbuf; + +#define BLE_ATT_UUID_PRIMARY_SERVICE 0x2800 +#define BLE_ATT_UUID_SECONDARY_SERVICE 0x2801 +#define BLE_ATT_UUID_INCLUDE 0x2802 +#define BLE_ATT_UUID_CHARACTERISTIC 0x2803 + +#define BLE_ATT_ERR_INVALID_HANDLE 0x01 +#define BLE_ATT_ERR_READ_NOT_PERMITTED 0x02 +#define BLE_ATT_ERR_WRITE_NOT_PERMITTED 0x03 +#define BLE_ATT_ERR_INVALID_PDU 0x04 +#define BLE_ATT_ERR_INSUFFICIENT_AUTHEN 0x05 +#define BLE_ATT_ERR_REQ_NOT_SUPPORTED 0x06 +#define BLE_ATT_ERR_INVALID_OFFSET 0x07 +#define BLE_ATT_ERR_INSUFFICIENT_AUTHOR 0x08 +#define BLE_ATT_ERR_PREPARE_QUEUE_FULL 0x09 +#define BLE_ATT_ERR_ATTR_NOT_FOUND 0x0a +#define BLE_ATT_ERR_ATTR_NOT_LONG 0x0b +#define BLE_ATT_ERR_INSUFFICIENT_KEY_SZ 0x0c +#define BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN 0x0d +#define BLE_ATT_ERR_UNLIKELY 0x0e +#define BLE_ATT_ERR_INSUFFICIENT_ENC 0x0f +#define BLE_ATT_ERR_UNSUPPORTED_GROUP 0x10 +#define BLE_ATT_ERR_INSUFFICIENT_RES 0x11 + +#define BLE_ATT_OP_ERROR_RSP 0x01 +#define BLE_ATT_OP_MTU_REQ 0x02 +#define BLE_ATT_OP_MTU_RSP 0x03 +#define BLE_ATT_OP_FIND_INFO_REQ 0x04 +#define BLE_ATT_OP_FIND_INFO_RSP 0x05 +#define BLE_ATT_OP_FIND_TYPE_VALUE_REQ 0x06 +#define BLE_ATT_OP_FIND_TYPE_VALUE_RSP 0x07 +#define BLE_ATT_OP_READ_TYPE_REQ 0x08 +#define BLE_ATT_OP_READ_TYPE_RSP 0x09 +#define BLE_ATT_OP_READ_REQ 0x0a +#define BLE_ATT_OP_READ_RSP 0x0b +#define BLE_ATT_OP_READ_BLOB_REQ 0x0c +#define BLE_ATT_OP_READ_BLOB_RSP 0x0d +#define BLE_ATT_OP_READ_MULT_REQ 0x0e +#define BLE_ATT_OP_READ_MULT_RSP 0x0f +#define BLE_ATT_OP_READ_GROUP_TYPE_REQ 0x10 +#define BLE_ATT_OP_READ_GROUP_TYPE_RSP 0x11 +#define BLE_ATT_OP_WRITE_REQ 0x12 +#define BLE_ATT_OP_WRITE_RSP 0x13 +#define BLE_ATT_OP_PREP_WRITE_REQ 0x16 +#define BLE_ATT_OP_PREP_WRITE_RSP 0x17 +#define BLE_ATT_OP_EXEC_WRITE_REQ 0x18 +#define BLE_ATT_OP_EXEC_WRITE_RSP 0x19 +#define BLE_ATT_OP_NOTIFY_REQ 0x1b +#define BLE_ATT_OP_INDICATE_REQ 0x1d +#define BLE_ATT_OP_INDICATE_RSP 0x1e +#define BLE_ATT_OP_WRITE_CMD 0x52 + +#define BLE_ATT_ATTR_MAX_LEN 512 + +#define BLE_ATT_F_READ 0x01 +#define BLE_ATT_F_WRITE 0x02 +#define BLE_ATT_F_READ_ENC 0x04 +#define BLE_ATT_F_READ_AUTHEN 0x08 +#define BLE_ATT_F_READ_AUTHOR 0x10 +#define BLE_ATT_F_WRITE_ENC 0x20 +#define BLE_ATT_F_WRITE_AUTHEN 0x40 +#define BLE_ATT_F_WRITE_AUTHOR 0x80 + +#define HA_FLAG_PERM_RW (BLE_ATT_F_READ | BLE_ATT_F_WRITE) + +#define BLE_ATT_ACCESS_OP_READ 1 +#define BLE_ATT_ACCESS_OP_WRITE 2 + +/** Default ATT MTU. Also the minimum. */ +#define BLE_ATT_MTU_DFLT 23 + +/** + * An ATT MTU of 527 allows the largest ATT command (signed write) to contain a + * 512-byte attribute value. + */ +#define BLE_ATT_MTU_MAX 527 + +/** + * Reads a locally registered attribute. If the specified attribute handle + * corresponds to a GATT characteristic value or descriptor, the read is + * performed by calling the registered GATT access callback. + * + * @param attr_handle The 16-bit handle of the attribute to read. + * @param out_om On success, this is made to point to a + * newly-allocated mbuf containing the + * attribute data read. + * + * @return 0 on success; + * NimBLE host ATT return code if the attribute + * access callback reports failure; + * NimBLE host core return code on unexpected + * error. + */ +int ble_att_svr_read_local(uint16_t attr_handle, struct os_mbuf **out_om); + +/** + * Writes a locally registered attribute. This function consumes the supplied + * mbuf regardless of the outcome. If the specified attribute handle + * corresponds to a GATT characteristic value or descriptor, the write is + * performed by calling the registered GATT access callback. + * + * @param attr_handle The 16-bit handle of the attribute to write. + * @param om The value to write to the attribute. + * + * @return 0 on success; + * NimBLE host ATT return code if the attribute + * access callback reports failure; + * NimBLE host core return code on unexpected + * error. + */ +int ble_att_svr_write_local(uint16_t attr_handle, struct os_mbuf *om); + +/** + * Retrieves the ATT MTU of the specified connection. If an MTU exchange for + * this connection has occurred, the MTU is the lower of the two peers' + * preferred values. Otherwise, the MTU is the default value of 23. + * + * @param conn_handle The handle of the connection to query. + * + * @return The specified connection's ATT MTU, or 0 if + * there is no such connection. + */ +uint16_t ble_att_mtu(uint16_t conn_handle); + +/** + * Retrieves the preferred ATT MTU. This is the value indicated by the device + * during an ATT MTU exchange. + * + * @return The preferred ATT MTU. + */ +uint16_t ble_att_preferred_mtu(void); + +/** + * Sets the preferred ATT MTU; the device will indicate this value in all + * subsequent ATT MTU exchanges. The ATT MTU of a connection is equal to the + * lower of the two peers' preferred MTU values. The ATT MTU is what dictates + * the maximum size of any message sent during a GATT procedure. + * + * The specified MTU must be within the following range: [23, BLE_ATT_MTU_MAX]. + * 23 is a minimum imposed by the Bluetooth specification; BLE_ATT_MTU_MAX is a + * NimBLE compile-time setting. + * + * @param mtu The preferred ATT MTU. + * + * @return 0 on success; + * BLE_HS_EINVAL if the specified value is not + * within the allowed range. + */ +int ble_att_set_preferred_mtu(uint16_t mtu); + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif diff --git a/libesp32/NimBLE-Arduino/src/host/ble_eddystone.h b/libesp32/NimBLE-Arduino/src/host/ble_eddystone.h new file mode 100644 index 000000000..76b7e2b01 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/host/ble_eddystone.h @@ -0,0 +1,117 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_BLE_EDDYSTONE_ +#define H_BLE_EDDYSTONE_ + +/** + * @brief Eddystone - BLE beacon from Google + * @defgroup bt_eddystone Eddystone - BLE beacon from Google + * @ingroup bt_host + * @{ + */ + +#include +#ifdef __cplusplus +extern "C" { +#endif + +struct ble_hs_adv_fields; + +#define BLE_EDDYSTONE_MAX_UUIDS16 3 +#define BLE_EDDYSTONE_URL_MAX_LEN 17 + +#define BLE_EDDYSTONE_URL_SCHEME_HTTP_WWW 0 +#define BLE_EDDYSTONE_URL_SCHEME_HTTPS_WWW 1 +#define BLE_EDDYSTONE_URL_SCHEME_HTTP 2 +#define BLE_EDDYSTONE_URL_SCHEME_HTTPS 3 + +#define BLE_EDDYSTONE_URL_SUFFIX_COM_SLASH 0x00 +#define BLE_EDDYSTONE_URL_SUFFIX_ORG_SLASH 0x01 +#define BLE_EDDYSTONE_URL_SUFFIX_EDU_SLASH 0x02 +#define BLE_EDDYSTONE_URL_SUFFIX_NET_SLASH 0x03 +#define BLE_EDDYSTONE_URL_SUFFIX_INFO_SLASH 0x04 +#define BLE_EDDYSTONE_URL_SUFFIX_BIZ_SLASH 0x05 +#define BLE_EDDYSTONE_URL_SUFFIX_GOV_SLASH 0x06 +#define BLE_EDDYSTONE_URL_SUFFIX_COM 0x07 +#define BLE_EDDYSTONE_URL_SUFFIX_ORG 0x08 +#define BLE_EDDYSTONE_URL_SUFFIX_EDU 0x09 +#define BLE_EDDYSTONE_URL_SUFFIX_NET 0x0a +#define BLE_EDDYSTONE_URL_SUFFIX_INFO 0x0b +#define BLE_EDDYSTONE_URL_SUFFIX_BIZ 0x0c +#define BLE_EDDYSTONE_URL_SUFFIX_GOV 0x0d +#define BLE_EDDYSTONE_URL_SUFFIX_NONE 0xff + +/** + * Configures the device to advertise Eddystone UID beacons. + * + * @param adv_fields The base advertisement fields to transform into + * an eddystone beacon. All configured fields + * are preserved; you probably want to clear + * this struct before calling this function. + * @param uid The 16-byte UID to advertise. + * @param measured_power The Measured Power (RSSI value at 0 Meter). + * + * @return 0 on success; + * BLE_HS_EBUSY if advertising is in progress; + * BLE_HS_EMSGSIZE if the specified data is too + * large to fit in an advertisement; + * Other nonzero on failure. + */ +int ble_eddystone_set_adv_data_uid(struct ble_hs_adv_fields *adv_fields, + void *uid, int8_t measured_power); + +/** + * Configures the device to advertise Eddystone URL beacons. + * + * @param adv_fields The base advertisement fields to transform into + * an eddystone beacon. All configured fields + * are preserved; you probably want to clear + * this struct before calling this function. + * @param url_scheme The prefix of the URL; one of the + * BLE_EDDYSTONE_URL_SCHEME values. + * @param url_body The middle of the URL. Don't include the + * suffix if there is a suitable suffix code. + * @param url_body_len The string length of the url_body argument. + * @param url_suffix The suffix of the URL; one of the + * BLE_EDDYSTONE_URL_SUFFIX values; use + * BLE_EDDYSTONE_URL_SUFFIX_NONE if the suffix + * is embedded in the body argument. + * @param measured_power The Measured Power (RSSI value at 0 Meter). + * + * @return 0 on success; + * BLE_HS_EBUSY if advertising is in progress; + * BLE_HS_EMSGSIZE if the specified data is too + * large to fit in an advertisement; + * Other nonzero on failure. + */ +int ble_eddystone_set_adv_data_url(struct ble_hs_adv_fields *adv_fields, + uint8_t url_scheme, char *url_body, + uint8_t url_body_len, uint8_t suffix, + int8_t measured_power); + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif diff --git a/libesp32/NimBLE-Arduino/src/host/ble_gap.h b/libesp32/NimBLE-Arduino/src/host/ble_gap.h new file mode 100644 index 000000000..b4dbdb051 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/host/ble_gap.h @@ -0,0 +1,1939 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_BLE_GAP_ +#define H_BLE_GAP_ + +/** + * @brief Bluetooth Host Generic Access Profile (GAP) + * @defgroup bt_host_gap Bluetooth Host Generic Access Profile (GAP) + * @ingroup bt_host + * @{ + */ + +#include +#include "host/ble_hs.h" +#include "host/ble_hs_adv.h" +#include "syscfg/syscfg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct hci_le_conn_complete; +struct hci_conn_update; + +/** 30 ms. */ +#define BLE_GAP_ADV_FAST_INTERVAL1_MIN (30 * 1000 / BLE_HCI_ADV_ITVL) + +/** 60 ms. */ +#define BLE_GAP_ADV_FAST_INTERVAL1_MAX (60 * 1000 / BLE_HCI_ADV_ITVL) + +/** 100 ms. */ +#define BLE_GAP_ADV_FAST_INTERVAL2_MIN (100 * 1000 / BLE_HCI_ADV_ITVL) + +/** 150 ms. */ +#define BLE_GAP_ADV_FAST_INTERVAL2_MAX (150 * 1000 / BLE_HCI_ADV_ITVL) + +/** 30 ms; active scanning. */ +#define BLE_GAP_SCAN_FAST_INTERVAL_MIN (30 * 1000 / BLE_HCI_ADV_ITVL) + +/** 60 ms; active scanning. */ +#define BLE_GAP_SCAN_FAST_INTERVAL_MAX (60 * 1000 / BLE_HCI_ADV_ITVL) + +/** 11.25 ms; limited discovery interval. */ +#define BLE_GAP_LIM_DISC_SCAN_INT (11.25 * 1000 / BLE_HCI_SCAN_ITVL) + +/** 11.25 ms; limited discovery window (not from the spec). */ +#define BLE_GAP_LIM_DISC_SCAN_WINDOW (11.25 * 1000 / BLE_HCI_SCAN_ITVL) + +/** 30 ms; active scanning. */ +#define BLE_GAP_SCAN_FAST_WINDOW (30 * 1000 / BLE_HCI_SCAN_ITVL) + +/* 30.72 seconds; active scanning. */ +#define BLE_GAP_SCAN_FAST_PERIOD (30.72 * 1000) + +/** 1.28 seconds; background scanning. */ +#define BLE_GAP_SCAN_SLOW_INTERVAL1 (1280 * 1000 / BLE_HCI_SCAN_ITVL) + +/** 11.25 ms; background scanning. */ +#define BLE_GAP_SCAN_SLOW_WINDOW1 (11.25 * 1000 / BLE_HCI_SCAN_ITVL) + +/** 10.24 seconds. */ +#define BLE_GAP_DISC_DUR_DFLT (10.24 * 1000) + +/** 30 seconds (not from the spec). */ +#define BLE_GAP_CONN_DUR_DFLT (30 * 1000) + +/** 1 second. */ +#define BLE_GAP_CONN_PAUSE_CENTRAL (1 * 1000) + +/** 5 seconds. */ +#define BLE_GAP_CONN_PAUSE_PERIPHERAL (5 * 1000) + +/* 30 ms. */ +#define BLE_GAP_INITIAL_CONN_ITVL_MIN (30 * 1000 / BLE_HCI_CONN_ITVL) + +/* 50 ms. */ +#define BLE_GAP_INITIAL_CONN_ITVL_MAX (50 * 1000 / BLE_HCI_CONN_ITVL) + +/** Default channels mask: all three channels are used. */ +#define BLE_GAP_ADV_DFLT_CHANNEL_MAP 0x07 + +#define BLE_GAP_INITIAL_CONN_LATENCY 0 +#define BLE_GAP_INITIAL_SUPERVISION_TIMEOUT 0x0100 +#define BLE_GAP_INITIAL_CONN_MIN_CE_LEN 0x0000 +#define BLE_GAP_INITIAL_CONN_MAX_CE_LEN 0x0000 + +#define BLE_GAP_ROLE_MASTER 0 +#define BLE_GAP_ROLE_SLAVE 1 + +#define BLE_GAP_EVENT_CONNECT 0 +#define BLE_GAP_EVENT_DISCONNECT 1 +/* Reserved 2 */ +#define BLE_GAP_EVENT_CONN_UPDATE 3 +#define BLE_GAP_EVENT_CONN_UPDATE_REQ 4 +#define BLE_GAP_EVENT_L2CAP_UPDATE_REQ 5 +#define BLE_GAP_EVENT_TERM_FAILURE 6 +#define BLE_GAP_EVENT_DISC 7 +#define BLE_GAP_EVENT_DISC_COMPLETE 8 +#define BLE_GAP_EVENT_ADV_COMPLETE 9 +#define BLE_GAP_EVENT_ENC_CHANGE 10 +#define BLE_GAP_EVENT_PASSKEY_ACTION 11 +#define BLE_GAP_EVENT_NOTIFY_RX 12 +#define BLE_GAP_EVENT_NOTIFY_TX 13 +#define BLE_GAP_EVENT_SUBSCRIBE 14 +#define BLE_GAP_EVENT_MTU 15 +#define BLE_GAP_EVENT_IDENTITY_RESOLVED 16 +#define BLE_GAP_EVENT_REPEAT_PAIRING 17 +#define BLE_GAP_EVENT_PHY_UPDATE_COMPLETE 18 +#define BLE_GAP_EVENT_EXT_DISC 19 +#define BLE_GAP_EVENT_PERIODIC_SYNC 20 +#define BLE_GAP_EVENT_PERIODIC_REPORT 21 +#define BLE_GAP_EVENT_PERIODIC_SYNC_LOST 22 +#define BLE_GAP_EVENT_SCAN_REQ_RCVD 23 + +/*** Reason codes for the subscribe GAP event. */ + +/** Peer's CCCD subscription state changed due to a descriptor write. */ +#define BLE_GAP_SUBSCRIBE_REASON_WRITE 1 + +/** Peer's CCCD subscription state cleared due to connection termination. */ +#define BLE_GAP_SUBSCRIBE_REASON_TERM 2 + +/** + * Peer's CCCD subscription state changed due to restore from persistence + * (bonding restored). + */ +#define BLE_GAP_SUBSCRIBE_REASON_RESTORE 3 + +#define BLE_GAP_REPEAT_PAIRING_RETRY 1 +#define BLE_GAP_REPEAT_PAIRING_IGNORE 2 + +/** Connection security state */ +struct ble_gap_sec_state { + /** If connection is encrypted */ + unsigned encrypted:1; + + /** If connection is authenticated */ + unsigned authenticated:1; + + /** If connection is bonded (security information is stored) */ + unsigned bonded:1; + + /** Size of a key used for encryption */ + unsigned key_size:5; +}; + +/** Advertising parameters */ +struct ble_gap_adv_params { + /** Advertising mode. Can be one of following constants: + * - BLE_GAP_CONN_MODE_NON (non-connectable; 3.C.9.3.2). + * - BLE_GAP_CONN_MODE_DIR (directed-connectable; 3.C.9.3.3). + * - BLE_GAP_CONN_MODE_UND (undirected-connectable; 3.C.9.3.4). + */ + uint8_t conn_mode; + /** Discoverable mode. Can be one of following constants: + * - BLE_GAP_DISC_MODE_NON (non-discoverable; 3.C.9.2.2). + * - BLE_GAP_DISC_MODE_LTD (limited-discoverable; 3.C.9.2.3). + * - BLE_GAP_DISC_MODE_GEN (general-discoverable; 3.C.9.2.4). + */ + uint8_t disc_mode; + + /** Minimum advertising interval, if 0 stack use sane defaults */ + uint16_t itvl_min; + /** Maximum advertising interval, if 0 stack use sane defaults */ + uint16_t itvl_max; + /** Advertising channel map , if 0 stack use sane defaults */ + uint8_t channel_map; + + /** Advertising Filter policy */ + uint8_t filter_policy; + + /** If do High Duty cycle for Directed Advertising */ + uint8_t high_duty_cycle:1; +}; + +/** @brief Connection descriptor */ +struct ble_gap_conn_desc { + /** Connection security state */ + struct ble_gap_sec_state sec_state; + + /** Local identity address */ + ble_addr_t our_id_addr; + + /** Peer identity address */ + ble_addr_t peer_id_addr; + + /** Local over-the-air address */ + ble_addr_t our_ota_addr; + + /** Peer over-the-air address */ + ble_addr_t peer_ota_addr; + + /** Connection handle */ + uint16_t conn_handle; + + /** Connection interval */ + uint16_t conn_itvl; + + /** Connection latency */ + uint16_t conn_latency; + + /** Connection supervision timeout */ + uint16_t supervision_timeout; + + /** Connection Role + * Possible values BLE_GAP_ROLE_SLAVE or BLE_GAP_ROLE_MASTER + */ + uint8_t role; + + /** Master clock accuracy */ + uint8_t master_clock_accuracy; +}; + +/** @brief Connection parameters */ +struct ble_gap_conn_params { + /** Scan interval in 0.625ms units */ + uint16_t scan_itvl; + + /** Scan window in 0.625ms units */ + uint16_t scan_window; + + /** Minimum value for connection interval in 1.25ms units */ + uint16_t itvl_min; + + /** Maximum value for connection interval in 1.25ms units */ + uint16_t itvl_max; + + /** Connection latency */ + uint16_t latency; + + /** Supervision timeout in 10ms units */ + uint16_t supervision_timeout; + + /** Minimum length of connection event in 0.625ms units */ + uint16_t min_ce_len; + + /** Maximum length of connection event in 0.625ms units */ + uint16_t max_ce_len; +}; + +/** @brief Extended discovery parameters */ +struct ble_gap_ext_disc_params { + /** Scan interval in 0.625ms units */ + uint16_t itvl; + + /** Scan window in 0.625ms units */ + uint16_t window; + + /** If passive scan should be used */ + uint8_t passive:1; +}; + +/** @brief Discovery parameters */ +struct ble_gap_disc_params { + /** Scan interval in 0.625ms units */ + uint16_t itvl; + + /** Scan window in 0.625ms units */ + uint16_t window; + + /** Scan filter policy */ + uint8_t filter_policy; + + /** If limited discovery procedure should be used */ + uint8_t limited:1; + + /** If passive scan should be used */ + uint8_t passive:1; + + /** If enable duplicates filtering */ + uint8_t filter_duplicates:1; +}; + +/** @brief Connection parameters update parameters */ +struct ble_gap_upd_params { + /** Minimum value for connection interval in 1.25ms units */ + uint16_t itvl_min; + + /** Maximum value for connection interval in 1.25ms units */ + uint16_t itvl_max; + + /** Connection latency */ + uint16_t latency; + + /** Supervision timeout in 10ms units */ + uint16_t supervision_timeout; + + /** Minimum length of connection event in 0.625ms units */ + uint16_t min_ce_len; + + /** Maximum length of connection event in 0.625ms units */ + uint16_t max_ce_len; +}; + +/** @brief Passkey query */ +struct ble_gap_passkey_params { + /** Passkey action, can be one of following constants: + * - BLE_SM_IOACT_NONE + * - BLE_SM_IOACT_OOB + * - BLE_SM_IOACT_INPUT + * - BLE_SM_IOACT_DISP + * - BLE_SM_IOACT_NUMCMP + */ + uint8_t action; + + /** Passkey to compare, valid for BLE_SM_IOACT_NUMCMP action */ + uint32_t numcmp; +}; + +#if MYNEWT_VAL(BLE_EXT_ADV) + +#define BLE_GAP_EXT_ADV_DATA_STATUS_COMPLETE 0x00 +#define BLE_GAP_EXT_ADV_DATA_STATUS_INCOMPLETE 0x01 +#define BLE_GAP_EXT_ADV_DATA_STATUS_TRUNCATED 0x02 + +/** @brief Extended advertising report */ +struct ble_gap_ext_disc_desc { + /** Report properties bitmask + * - BLE_HCI_ADV_CONN_MASK + * - BLE_HCI_ADV_SCAN_MASK + * - BLE_HCI_ADV_DIRECT_MASK + * - BLE_HCI_ADV_SCAN_RSP_MASK + * - BLE_HCI_ADV_LEGACY_MASK + * */ + uint8_t props; + + /** Advertising data status, can be one of following constants: + * - BLE_GAP_EXT_ADV_DATA_STATUS_COMPLETE + * - BLE_GAP_EXT_ADV_DATA_STATUS_INCOMPLETE + * - BLE_GAP_EXT_ADV_DATA_STATUS_TRUNCATED + */ + uint8_t data_status; + + /** Legacy advertising PDU type. Valid if BLE_HCI_ADV_LEGACY_MASK props is + * set. Can be one of following constants: + * - BLE_HCI_ADV_RPT_EVTYPE_ADV_IND + * - BLE_HCI_ADV_RPT_EVTYPE_DIR_IND + * - BLE_HCI_ADV_RPT_EVTYPE_SCAN_IND + * - BLE_HCI_ADV_RPT_EVTYPE_NONCONN_IND + * - BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP + */ + uint8_t legacy_event_type; + + /** Advertiser address */ + ble_addr_t addr; + + /** Received signal strength indication in dBm (127 if unavailable) */ + int8_t rssi; + + /** Advertiser transmit power in dBm (127 if unavailable) */ + int8_t tx_power; + + /** Advertising Set ID */ + uint8_t sid; + + /** Primary advertising PHY, can be one of following constants: + * - BLE_HCI_LE_PHY_1M + * - BLE_HCI_LE_PHY_CODED + */ + uint8_t prim_phy; + + /** Secondary advertising PHY, can be one of following constants: + * - BLE_HCI_LE_PHY_1M + * - LE_HCI_LE_PHY_2M + * - BLE_HCI_LE_PHY_CODED + */ + uint8_t sec_phy; + + /** Periodic advertising interval. 0 if no periodic advertising. */ + uint16_t periodic_adv_itvl; + + /** Advertising Data length */ + uint8_t length_data; + + /** Advertising data */ + uint8_t *data; + + /** Directed advertising address. Valid if BLE_HCI_ADV_DIRECT_MASK props is + * set (BLE_ADDR_ANY otherwise). + */ + ble_addr_t direct_addr; +}; +#endif + +/** @brief Advertising report */ +struct ble_gap_disc_desc { + /** Advertising PDU type. Can be one of following constants: + * - BLE_HCI_ADV_RPT_EVTYPE_ADV_IND + * - BLE_HCI_ADV_RPT_EVTYPE_DIR_IND + * - BLE_HCI_ADV_RPT_EVTYPE_SCAN_IND + * - BLE_HCI_ADV_RPT_EVTYPE_NONCONN_IND + * - BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP + */ + uint8_t event_type; + + /** Advertising Data length */ + uint8_t length_data; + + /** Advertiser address */ + ble_addr_t addr; + + /** Received signal strength indication in dBm (127 if unavailable) */ + int8_t rssi; + + /** Advertising data */ + uint8_t *data; + + /** Directed advertising address. Valid for BLE_HCI_ADV_RPT_EVTYPE_DIR_IND + * event type (BLE_ADDR_ANY otherwise). + */ + ble_addr_t direct_addr; +}; + +struct ble_gap_repeat_pairing { + /** The handle of the relevant connection. */ + uint16_t conn_handle; + + /** Properties of the existing bond. */ + uint8_t cur_key_size; + uint8_t cur_authenticated:1; + uint8_t cur_sc:1; + + /** + * Properties of the imminent secure link if the pairing procedure is + * allowed to continue. + */ + uint8_t new_key_size; + uint8_t new_authenticated:1; + uint8_t new_sc:1; + uint8_t new_bonding:1; +}; + +/** + * Represents a GAP-related event. When such an event occurs, the host + * notifies the application by passing an instance of this structure to an + * application-specified callback. + */ +struct ble_gap_event { + /** + * Indicates the type of GAP event that occurred. This is one of the + * BLE_GAP_EVENT codes. + */ + uint8_t type; + + /** + * A discriminated union containing additional details concerning the GAP + * event. The 'type' field indicates which member of the union is valid. + */ + union { + /** + * Represents a connection attempt. Valid for the following event + * types: + * o BLE_GAP_EVENT_CONNECT + */ + struct { + /** + * The status of the connection attempt; + * o 0: the connection was successfully established. + * o BLE host error code: the connection attempt failed for + * the specified reason. + */ + int status; + + /** The handle of the relevant connection. */ + uint16_t conn_handle; + } connect; + + /** + * Represents a terminated connection. Valid for the following event + * types: + * o BLE_GAP_EVENT_DISCONNECT + */ + struct { + /** + * A BLE host return code indicating the reason for the + * disconnect. + */ + int reason; + + /** Information about the connection prior to termination. */ + struct ble_gap_conn_desc conn; + } disconnect; + + /** + * Represents an advertising report received during a discovery + * procedure. Valid for the following event types: + * o BLE_GAP_EVENT_DISC + */ + struct ble_gap_disc_desc disc; + +#if MYNEWT_VAL(BLE_EXT_ADV) + /** + * Represents an extended advertising report received during a discovery + * procedure. Valid for the following event types: + * o BLE_GAP_EVENT_EXT_DISC + */ + struct ble_gap_ext_disc_desc ext_disc; +#endif + + /** + * Represents a completed discovery procedure. Valid for the following + * event types: + * o BLE_GAP_EVENT_DISC_COMPLETE + */ + struct { + /** + * The reason the discovery procedure stopped. Typical reason + * codes are: + * o 0: Duration expired. + * o BLE_HS_EPREEMPTED: Host aborted procedure to configure a + * peer's identity. + */ + int reason; + } disc_complete; + + /** + * Represents a completed advertise procedure. Valid for the following + * event types: + * o BLE_GAP_EVENT_ADV_COMPLETE + */ + struct { + /** + * The reason the advertise procedure stopped. Typical reason + * codes are: + * o 0: Terminated due to connection. + * o BLE_HS_ETIMEOUT: Duration expired. + * o BLE_HS_EPREEMPTED: Host aborted procedure to configure a + * peer's identity. + */ + int reason; + +#if MYNEWT_VAL(BLE_EXT_ADV) + /** Advertising instance */ + uint8_t instance; + /** The handle of the relevant connection - valid if reason=0 */ + uint16_t conn_handle; + /** + * Number of completed extended advertising events + * + * This field is only valid if non-zero max_events was passed to + * ble_gap_ext_adv_start() and advertising completed due to duration + * timeout or max events transmitted. + * */ + uint8_t num_ext_adv_events; +#endif + } adv_complete; + + /** + * Represents an attempt to update a connection's parameters. If the + * attempt was successful, the connection's descriptor reflects the + * updated parameters. + * + * Valid for the following event types: + * o BLE_GAP_EVENT_CONN_UPDATE + */ + struct { + /** + * The result of the connection update attempt; + * o 0: the connection was successfully updated. + * o BLE host error code: the connection update attempt failed + * for the specified reason. + */ + int status; + + /** The handle of the relevant connection. */ + uint16_t conn_handle; + } conn_update; + + /** + * Represents a peer's request to update the connection parameters. + * This event is generated when a peer performs any of the following + * procedures: + * o L2CAP Connection Parameter Update Procedure + * o Link-Layer Connection Parameters Request Procedure + * + * To reject the request, return a non-zero HCI error code. The value + * returned is the reject reason given to the controller. + * + * Valid for the following event types: + * o BLE_GAP_EVENT_L2CAP_UPDATE_REQ + * o BLE_GAP_EVENT_CONN_UPDATE_REQ + */ + struct { + /** + * Indicates the connection parameters that the peer would like to + * use. + */ + const struct ble_gap_upd_params *peer_params; + + /** + * Indicates the connection parameters that the local device would + * like to use. The application callback should fill this in. By + * default, this struct contains the requested parameters (i.e., + * it is a copy of 'peer_params'). + */ + struct ble_gap_upd_params *self_params; + + /** The handle of the relevant connection. */ + uint16_t conn_handle; + } conn_update_req; + + /** + * Represents a failed attempt to terminate an established connection. + * Valid for the following event types: + * o BLE_GAP_EVENT_TERM_FAILURE + */ + struct { + /** + * A BLE host return code indicating the reason for the failure. + */ + int status; + + /** The handle of the relevant connection. */ + uint16_t conn_handle; + } term_failure; + + /** + * Represents an attempt to change the encrypted state of a + * connection. If the attempt was successful, the connection + * descriptor reflects the updated encrypted state. + * + * Valid for the following event types: + * o BLE_GAP_EVENT_ENC_CHANGE + */ + struct { + /** + * Indicates the result of the encryption state change attempt; + * o 0: the encrypted state was successfully updated; + * o BLE host error code: the encryption state change attempt + * failed for the specified reason. + */ + int status; + + /** The handle of the relevant connection. */ + uint16_t conn_handle; + } enc_change; + + /** + * Represents a passkey query needed to complete a pairing procedure. + * + * Valid for the following event types: + * o BLE_GAP_EVENT_PASSKEY_ACTION + */ + struct { + /** Contains details about the passkey query. */ + struct ble_gap_passkey_params params; + + /** The handle of the relevant connection. */ + uint16_t conn_handle; + } passkey; + + /** + * Represents a received ATT notification or indication. + * + * Valid for the following event types: + * o BLE_GAP_EVENT_NOTIFY_RX + */ + struct { + /** + * The contents of the notification or indication. If the + * application wishes to retain this mbuf for later use, it must + * set this pointer to NULL to prevent the stack from freeing it. + */ + struct os_mbuf *om; + + /** The handle of the relevant ATT attribute. */ + uint16_t attr_handle; + + /** The handle of the relevant connection. */ + uint16_t conn_handle; + + /** + * Whether the received command is a notification or an + * indication; + * o 0: Notification; + * o 1: Indication. + */ + uint8_t indication:1; + } notify_rx; + + /** + * Represents a transmitted ATT notification or indication, or a + * completed indication transaction. + * + * Valid for the following event types: + * o BLE_GAP_EVENT_NOTIFY_TX + */ + struct { + /** + * The status of the notification or indication transaction; + * o 0: Command successfully sent; + * o BLE_HS_EDONE: Confirmation (indication ack) received; + * o BLE_HS_ETIMEOUT: Confirmation (indication ack) never + * received; + * o Other return code: Error. + */ + int status; + + /** The handle of the relevant connection. */ + uint16_t conn_handle; + + /** The handle of the relevant characteristic value. */ + uint16_t attr_handle; + + /** + * Whether the transmitted command is a notification or an + * indication; + * o 0: Notification; + * o 1: Indication. + */ + uint8_t indication:1; + } notify_tx; + + /** + * Represents a state change in a peer's subscription status. In this + * comment, the term "update" is used to refer to either a notification + * or an indication. This event is triggered by any of the following + * occurrences: + * o Peer enables or disables updates via a CCCD write. + * o Connection is about to be terminated and the peer is + * subscribed to updates. + * o Peer is now subscribed to updates after its state was restored + * from persistence. This happens when bonding is restored. + * + * Valid for the following event types: + * o BLE_GAP_EVENT_SUBSCRIBE + */ + struct { + /** The handle of the relevant connection. */ + uint16_t conn_handle; + + /** The value handle of the relevant characteristic. */ + uint16_t attr_handle; + + /** One of the BLE_GAP_SUBSCRIBE_REASON codes. */ + uint8_t reason; + + /** Whether the peer was previously subscribed to notifications. */ + uint8_t prev_notify:1; + + /** Whether the peer is currently subscribed to notifications. */ + uint8_t cur_notify:1; + + /** Whether the peer was previously subscribed to indications. */ + uint8_t prev_indicate:1; + + /** Whether the peer is currently subscribed to indications. */ + uint8_t cur_indicate:1; + } subscribe; + + /** + * Represents a change in an L2CAP channel's MTU. + * + * Valid for the following event types: + * o BLE_GAP_EVENT_MTU + */ + struct { + /** The handle of the relevant connection. */ + uint16_t conn_handle; + + /** + * Indicates the channel whose MTU has been updated; either + * BLE_L2CAP_CID_ATT or the ID of a connection-oriented channel. + */ + uint16_t channel_id; + + /* The channel's new MTU. */ + uint16_t value; + } mtu; + + /** + * Represents a change in peer's identity. This is issued after + * successful pairing when Identity Address Information was received. + * + * Valid for the following event types: + * o BLE_GAP_EVENT_IDENTITY_RESOLVED + */ + struct { + /** The handle of the relevant connection. */ + uint16_t conn_handle; + } identity_resolved; + + /** + * Represents a peer's attempt to pair despite a bond already existing. + * The application has two options for handling this event type: + * o Retry: Return BLE_GAP_REPEAT_PAIRING_RETRY after deleting the + * conflicting bond. The stack will verify the bond has + * been deleted and continue the pairing procedure. If + * the bond is still present, this event will be reported + * again. + * o Ignore: Return BLE_GAP_REPEAT_PAIRING_IGNORE. The stack will + * silently ignore the pairing request. + * + * Valid for the following event types: + * o BLE_GAP_EVENT_REPEAT_PAIRING + */ + struct ble_gap_repeat_pairing repeat_pairing; + + /** + * Represents a change of PHY. This is issue after successful + * change on PHY. + */ + struct { + int status; + uint16_t conn_handle; + + /** + * Indicates enabled TX/RX PHY. Possible values: + * o BLE_GAP_LE_PHY_1M + * o BLE_GAP_LE_PHY_2M + * o BLE_GAP_LE_PHY_CODED + */ + uint8_t tx_phy; + uint8_t rx_phy; + } phy_updated; +#if MYNEWT_VAL(BLE_PERIODIC_ADV) + /** + * Represents a periodic advertising sync established during discovery + * procedure. Valid for the following event types: + * o BLE_GAP_EVENT_PERIODIC_SYNC + */ + struct { + /** BLE_ERR_SUCCESS on success or error code on failure. Other + * fields are valid only for success + */ + uint8_t status; + /** Periodic sync handle */ + uint16_t sync_handle; + + /** Advertising Set ID */ + uint8_t sid; + + /** Advertiser address */ + ble_addr_t adv_addr; + + /** Advertising PHY, can be one of following constants: + * - BLE_HCI_LE_PHY_1M + * - LE_HCI_LE_PHY_2M + * - BLE_HCI_LE_PHY_CODED + */ + uint8_t adv_phy; + + /** Periodic advertising interval */ + uint16_t per_adv_ival; + + /** Advertiser clock accuracy */ + uint8_t adv_clk_accuracy; + } periodic_sync; + + /** + * Represents a periodic advertising report received on established + * sync. Valid for the following event types: + * o BLE_GAP_EVENT_PERIODIC_REPORT + */ + struct { + /** Periodic sync handle */ + uint16_t sync_handle; + + /** Advertiser transmit power in dBm (127 if unavailable) */ + int8_t tx_power; + + /** Received signal strength indication in dBm (127 if unavailable) */ + int8_t rssi; + + /** Advertising data status, can be one of following constants: + * - BLE_HCI_PERIODIC_DATA_STATUS_COMPLETE + * - BLE_HCI_PERIODIC_DATA_STATUS_INCOMPLETE + * - BLE_HCI_PERIODIC_DATA_STATUS_TRUNCATED + */ + uint8_t data_status; + + /** Advertising Data length */ + uint8_t data_length; + + /** Advertising data */ + uint8_t *data; + } periodic_report; + + /** + * Represents a periodic advertising sync lost of established sync. + * Sync lost reason can be BLE_HS_ETIMEOUT (sync timeout) or + * BLE_HS_EDONE (sync terminated locally). + * Valid for the following event types: + * o BLE_GAP_EVENT_PERIODIC_SYNC_LOST + */ + struct { + /** Periodic sync handle */ + uint16_t sync_handle; + + /** Reason for sync lost, can be BLE_HS_ETIMEOUT for timeout or + * BLE_HS_EDONE for locally terminated sync + */ + int reason; + } periodic_sync_lost; +#endif + +#if MYNEWT_VAL(BLE_EXT_ADV) + /** + * Represents a scan request for an extended advertising instance where + * scan request notifications were enabled. + * Valid for the following event types: + * o BLE_GAP_EVENT_SCAN_REQ_RCVD + */ + struct { + /** Extended advertising instance */ + uint8_t instance; + /** Address of scanner */ + ble_addr_t scan_addr; + } scan_req_rcvd; +#endif + }; +}; + +typedef int ble_gap_event_fn(struct ble_gap_event *event, void *arg); + +#define BLE_GAP_CONN_MODE_NON 0 +#define BLE_GAP_CONN_MODE_DIR 1 +#define BLE_GAP_CONN_MODE_UND 2 + +#define BLE_GAP_DISC_MODE_NON 0 +#define BLE_GAP_DISC_MODE_LTD 1 +#define BLE_GAP_DISC_MODE_GEN 2 + +/** + * Searches for a connection with the specified handle. If a matching + * connection is found, the supplied connection descriptor is filled + * correspondingly. + * + * @param handle The connection handle to search for. + * @param out_desc On success, this is populated with information relating to + * the matching connection. Pass NULL if you don't need this + * information. + * + * @return 0 on success, BLE_HS_ENOTCONN if no matching connection was + * found. + */ +int ble_gap_conn_find(uint16_t handle, struct ble_gap_conn_desc *out_desc); + +/** + * Searches for a connection with a peer with the specified address. + * If a matching connection is found, the supplied connection descriptor + * is filled correspondingly. + * + * @param addr The ble address of a connected peer device to search for. + * @param out_desc On success, this is populated with information relating to + * the matching connection. Pass NULL if you don't need this + * information. + * + * @return 0 on success, BLE_HS_ENOTCONN if no matching connection was + * found. + */ +int ble_gap_conn_find_by_addr(const ble_addr_t *addr, + struct ble_gap_conn_desc *out_desc); + +/** + * Configures a connection to use the specified GAP event callback. A + * connection's GAP event callback is first specified when the connection is + * created, either via advertising or initiation. This function replaces the + * callback that was last configured. + * + * @param conn_handle The handle of the connection to configure. + * @param cb The callback to associate with the connection. + * @param cb_arg An optional argument that the callback receives. + * + * @return 0 on success, BLE_HS_ENOTCONN if there is no connection + * with the specified handle. + */ +int ble_gap_set_event_cb(uint16_t conn_handle, + ble_gap_event_fn *cb, void *cb_arg); + +/** @brief Start advertising + * + * This function configures and start advertising procedure. + * + * @param own_addr_type The type of address the stack should use for itself. + * Valid values are: + * - BLE_OWN_ADDR_PUBLIC + * - BLE_OWN_ADDR_RANDOM + * - BLE_OWN_ADDR_RPA_PUBLIC_DEFAULT + * - BLE_OWN_ADDR_RPA_RANDOM_DEFAULT + * @param direct_addr The peer's address for directed advertising. This + * parameter shall be non-NULL if directed advertising is + * being used. + * @param duration_ms The duration of the advertisement procedure. On + * expiration, the procedure ends and a + * BLE_GAP_EVENT_ADV_COMPLETE event is reported. Units are + * milliseconds. Specify BLE_HS_FOREVER for no expiration. + * @param adv_params Additional arguments specifying the particulars of the + * advertising procedure. + * @param cb The callback to associate with this advertising + * procedure. If advertising ends, the event is reported + * through this callback. If advertising results in a + * connection, the connection inherits this callback as its + * event-reporting mechanism. + * @param cb_arg The optional argument to pass to the callback function. + * + * @return 0 on success, error code on failure. + */ +int ble_gap_adv_start(uint8_t own_addr_type, const ble_addr_t *direct_addr, + int32_t duration_ms, + const struct ble_gap_adv_params *adv_params, + ble_gap_event_fn *cb, void *cb_arg); + +/** + * Stops the currently-active advertising procedure. A success return + * code indicates that advertising has been fully aborted and a new advertising + * procedure can be initiated immediately. + * + * NOTE: If the caller is running in the same task as the NimBLE host, or if it + * is running in a higher priority task than that of the host, care must be + * taken when restarting advertising. Under these conditions, the following is + * *not* a reliable method to restart advertising: + * ble_gap_adv_stop() + * ble_gap_adv_start() + * + * Instead, the call to `ble_gap_adv_start()` must be made in a separate event + * context. That is, `ble_gap_adv_start()` must be called asynchronously by + * enqueueing an event on the current task's event queue. See + * https://github.com/apache/mynewt-nimble/pull/211 for more information. + * + * @return 0 on success, BLE_HS_EALREADY if there is no active advertising + * procedure, other error code on failure. + */ +int ble_gap_adv_stop(void); + +/** + * Indicates whether an advertisement procedure is currently in progress. + * + * @return 0 if no advertisement procedure in progress, 1 otherwise. + */ +int ble_gap_adv_active(void); + +/** + * Configures the data to include in subsequent advertisements. + * + * @param data Buffer containing the advertising data. + * @param data_len The size of the advertising data, in bytes. + * + * @return 0 on succes, BLE_HS_EBUSY if advertising is in progress, + * other error code on failure. + */ +int ble_gap_adv_set_data(const uint8_t *data, int data_len); + +/** + * Configures the data to include in subsequent scan responses. + * + * @param data Buffer containing the scan response data. + * @param data_len The size of the response data, in bytes. + * + * @return 0 on succes, BLE_HS_EBUSY if advertising is in progress, + * other error code on failure. + */ +int ble_gap_adv_rsp_set_data(const uint8_t *data, int data_len); + +/** + * Configures the fields to include in subsequent advertisements. This is a + * convenience wrapper for ble_gap_adv_set_data(). + * + * @param adv_fields Specifies the advertisement data. + * + * @return 0 on success, + * BLE_HS_EBUSY if advertising is in progress, + * BLE_HS_EMSGSIZE if the specified data is too large to + * fit in an advertisement, + * other error code on failure. + */ +int ble_gap_adv_set_fields(const struct ble_hs_adv_fields *rsp_fields); + +/** + * Configures the fields to include in subsequent scan responses. This is a + * convenience wrapper for ble_gap_adv_rsp_set_data(). + * + * @param adv_fields Specifies the scan response data. + * + * @return 0 on success, + * BLE_HS_EBUSY if advertising is in progress, + * BLE_HS_EMSGSIZE if the specified data is too large to + * fit in a scan response, + * other error code on failure. + */ +int ble_gap_adv_rsp_set_fields(const struct ble_hs_adv_fields *rsp_fields); + +#if MYNEWT_VAL(BLE_EXT_ADV) +/** @brief Extended advertising parameters */ +struct ble_gap_ext_adv_params { + /** If perform connectable advertising */ + unsigned int connectable:1; + + /** If perform scannable advertising */ + unsigned int scannable:1; + + /** If perform directed advertising */ + unsigned int directed:1; + + /** If perform high-duty directed advertising */ + unsigned int high_duty_directed:1; + + /** If use legacy PDUs for advertising */ + unsigned int legacy_pdu:1; + + /** If perform anonymous advertising */ + unsigned int anonymous:1; + + /** If include TX power in advertising PDU */ + unsigned int include_tx_power:1; + + /** If enable scan request notification */ + unsigned int scan_req_notif:1; + + /** Minimum advertising interval in 0.625ms units, if 0 stack use sane + * defaults + */ + uint32_t itvl_min; + + /** Maximum advertising interval in 0.625ms units, if 0 stack use sane + * defaults + */ + uint32_t itvl_max; + + /** Advertising channel map , if 0 stack use sane defaults */ + uint8_t channel_map; + + /** Own address type to be used by advertising instance */ + uint8_t own_addr_type; + + /** Peer address for directed advertising, valid only if directed is set */ + ble_addr_t peer; + + /** Advertising Filter policy */ + uint8_t filter_policy; + + /** Primary advertising PHY to use , can be one of following constants: + * - BLE_HCI_LE_PHY_1M + * - BLE_HCI_LE_PHY_CODED + */ + uint8_t primary_phy; + + /** Secondary advertising PHY to use, can be one of following constants: + * - BLE_HCI_LE_PHY_1M + * - LE_HCI_LE_PHY_2M + * - BLE_HCI_LE_PHY_CODED + */ + uint8_t secondary_phy; + + /** Preferred advertiser transmit power */ + int8_t tx_power; + + /** Advertising Set ID */ + uint8_t sid; +}; + +/** + * Configure extended advertising instance + * + * @param instance Instance ID + * @param params Additional arguments specifying the particulars + * of the advertising. + * @param selected_tx_power Selected advertising transmit power will be + * stored in that param if non-NULL. + * @param cb The callback to associate with this advertising + * procedure. Advertising complete event is reported + * through this callback + * @param cb_arg The optional argument to pass to the callback + * function. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gap_ext_adv_configure(uint8_t instance, + const struct ble_gap_ext_adv_params *params, + int8_t *selected_tx_power, + ble_gap_event_fn *cb, void *cb_arg); + +/** + * Set random address for configured advertising instance. + * + * @param instance Instance ID + * @param addr Random address to be set + * + * @return 0 on success; nonzero on failure. + */ +int ble_gap_ext_adv_set_addr(uint8_t instance, const ble_addr_t *addr); + +/** + * Start advertising instance. + * + * @param instance Instance ID + * @param duration The duration of the advertisement procedure. On + * expiration, the procedure ends and + * a BLE_HS_FOREVER event is reported. + * Units are milliseconds. Specify 0 for no + * expiration. + * @params max_events Number of advertising events that should be sent + * before advertising ends and + * a BLE_GAP_EVENT_ADV_COMPLETE event is reported. + * Specify 0 for no limit. + * + * @return 0 on success, error code on failure. + */ +int ble_gap_ext_adv_start(uint8_t instance, int duration, int max_events); + +/** + * Stops advertising procedure for specified instance. + * + * @param instance Instance ID + * + * @return 0 on success, BLE_HS_EALREADY if there is no active advertising + * procedure for instance, other error code on failure. + */ +int ble_gap_ext_adv_stop(uint8_t instance); + +/** + * Configures the data to include in advertisements packets for specified + * advertising instance. + * + * @param instance Instance ID + * @param data Chain containing the advertising data. + * + * @return 0 on success or error code on failure. + */ +int ble_gap_ext_adv_set_data(uint8_t instance, struct os_mbuf *data); + +/** + * Configures the data to include in subsequent scan responses for specified + * advertisign instance. + * + * @param instance Instance ID + * @param data Chain containing the scan response data. + * + * @return 0 on success or error code on failure. + */ + +int ble_gap_ext_adv_rsp_set_data(uint8_t instance, struct os_mbuf *data); + +/** + * Remove existing advertising instance. + * + * @param instance Instance ID + * + * @return 0 on success, + * BLE_HS_EBUSY if advertising is in progress, + * other error code on failure. + */ +int ble_gap_ext_adv_remove(uint8_t instance); + +/** + * Clear all existing advertising instances + * @return 0 on success, + * BLE_HS_EBUSY if advertising is in progress, + * other error code on failure. + */ +int ble_gap_ext_adv_clear(void); +#endif + +/* Periodic Advertising */ +#if MYNEWT_VAL(BLE_PERIODIC_ADV) + +/** @brief Periodic advertising parameters */ +struct ble_gap_periodic_adv_params { + /** If include TX power in advertising PDU */ + unsigned int include_tx_power:1; + + /** Minimum advertising interval in 0.625ms units, if 0 stack use sane + * defaults + */ + uint16_t itvl_min; + + /** Maximum advertising interval in 0.625ms units, if 0 stack use sane + * defaults + */ + uint16_t itvl_max; +}; + +/** @brief Periodic sync parameters */ +struct ble_gap_periodic_sync_params { + /** The maximum number of periodic advertising events that controller can + * skip after a successful receive. + * */ + uint16_t skip; + + /** Synchronization timeout for the periodic advertising train in 10ms units + */ + uint16_t sync_timeout; +}; + +/** + * Configure periodic advertising for specified advertising instance + * + * This is allowed only for instances configured as non-announymous, + * non-connectable and non-scannable. + * + * @param instance Instance ID + * @param params Additional arguments specifying the particulars + * of periodic advertising. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gap_periodic_adv_configure(uint8_t instance, + const struct ble_gap_periodic_adv_params *params); + +/** + * Start periodic advertising for specified advertising instance. + * + * @param instance Instance ID + * + * @return 0 on success, error code on failure. + */ +int ble_gap_periodic_adv_start(uint8_t instance); + +/** + * Stop periodic advertising for specified advertising instance. + * + * @param instance Instance ID + * + * @return 0 on success, error code on failure. + */ +int ble_gap_periodic_adv_stop(uint8_t instance); + +/** + * Configures the data to include in periodic advertisements for specified + * advertising instance. + * + * @param instance Instance ID + * @param data Chain containing the periodic advertising data. + * + * @return 0 on success or error code on failure. + */ +int ble_gap_periodic_adv_set_data(uint8_t instance, struct os_mbuf *data); + +/** + * Performs the Synchronization procedure with periodic advertiser. + * + * @param addr Peer address to synchronize with. If NULL than + * peers from periodic list are used. + * @param adv_sid Advertiser Set ID + * @param params Additional arguments specifying the particulars + * of the synchronization procedure. + * @param cb The callback to associate with this synchrnization + * procedure. BLE_GAP_EVENT_PERIODIC_REPORT events + * are reported only by this callback. + * @param cb_arg The optional argument to pass to the callback + * function. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gap_periodic_adv_create_sync(const ble_addr_t *addr, uint8_t adv_sid, + const struct ble_gap_periodic_sync_params *params, + ble_gap_event_fn *cb, void *cb_arg); + +/** + * Cancel pending synchronization procedure. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gap_periodic_adv_create_sync_cancel(void); + +/** + * Terminate synchronization procedure. + * + * @param sync_handle Handle identifying synchronization to terminate. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gap_periodic_adv_terminate_sync(uint16_t sync_handle); + +/** + * Add peer device to periodic synchronization list. + * + * @param addr Peer address to add to list. + * @param adv_sid Advertiser Set ID + * + * @return 0 on success; nonzero on failure. + */ +int ble_gap_add_dev_to_periodic_adv_list(const ble_addr_t *peer_addr, + uint8_t adv_sid); + +/** + * Remove peer device from periodic synchronization list. + * + * @param addr Peer address to remove from list. + * @param adv_sid Advertiser Set ID + * + * @return 0 on success; nonzero on failure. + */ +int ble_gap_rem_dev_from_periodic_adv_list(const ble_addr_t *peer_addr, + uint8_t adv_sid); + +/** + * Clear periodic synchrnization list. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gap_clear_periodic_adv_list(void); + +/** + * Get periodic synchronization list size. + * + * @param per_adv_list_size On success list size is stored here. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gap_read_periodic_adv_list_size(uint8_t *per_adv_list_size); +#endif + + +/** + * Performs the Limited or General Discovery Procedures. + * + * @param own_addr_type The type of address the stack should use for + * itself when sending scan requests. Valid + * values are: + * - BLE_ADDR_TYPE_PUBLIC + * - BLE_ADDR_TYPE_RANDOM + * - BLE_ADDR_TYPE_RPA_PUB_DEFAULT + * - BLE_ADDR_TYPE_RPA_RND_DEFAULT + * This parameter is ignored unless active + * scanning is being used. + * @param duration_ms The duration of the discovery procedure. + * On expiration, the procedure ends and a + * BLE_GAP_EVENT_DISC_COMPLETE event is + * reported. Units are milliseconds. Specify + * BLE_HS_FOREVER for no expiration. + * @param disc_params Additional arguments specifying the particulars + * of the discovery procedure. + * @param cb The callback to associate with this discovery + * procedure. Advertising reports and + * discovery termination events are reported + * through this callback. + * @param cb_arg The optional argument to pass to the callback + * function. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gap_disc(uint8_t own_addr_type, int32_t duration_ms, + const struct ble_gap_disc_params *disc_params, + ble_gap_event_fn *cb, void *cb_arg); + +/** + * Performs the Limited or General Extended Discovery Procedures. + * + * @param own_addr_type The type of address the stack should use for + * itself when sending scan requests. Valid + * values are: + * - BLE_ADDR_TYPE_PUBLIC + * - BLE_ADDR_TYPE_RANDOM + * - BLE_ADDR_TYPE_RPA_PUB_DEFAULT + * - BLE_ADDR_TYPE_RPA_RND_DEFAULT + * This parameter is ignored unless active + * scanning is being used. + * @param duration The duration of the discovery procedure. + * On expiration, if period is set to 0, the + * procedure ends and a + * BLE_GAP_EVENT_DISC_COMPLETE event is + * reported. Units are 10 milliseconds. + * Specify 0 for no expiration. + * @param period Time interval from when the Controller started + * its last Scan Duration until it begins the + * subsequent Scan Duration. Specify 0 to scan + * continuously. Units are 1.28 second. + * @param limited If limited discovery procedure should be used. + * @param uncoded_params Additional arguments specifying the particulars + * of the discovery procedure for uncoded PHY. + * If NULL is provided no scan is performed for + * this PHY. + * @param coded_params Additional arguments specifying the particulars + * of the discovery procedure for coded PHY. + * If NULL is provided no scan is performed for + * this PHY. + * @param cb The callback to associate with this discovery + * procedure. Advertising reports and discovery + * termination events are reported through this + * callback. + * @param cb_arg The optional argument to pass to the callback + * function. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gap_ext_disc(uint8_t own_addr_type, uint16_t duration, uint16_t period, + uint8_t filter_duplicates, uint8_t filter_policy, + uint8_t limited, + const struct ble_gap_ext_disc_params *uncoded_params, + const struct ble_gap_ext_disc_params *coded_params, + ble_gap_event_fn *cb, void *cb_arg); + +/** + * Cancels the discovery procedure currently in progress. A success return + * code indicates that scanning has been fully aborted; a new discovery or + * connect procedure can be initiated immediately. + * + * @return 0 on success; + * BLE_HS_EALREADY if there is no discovery + * procedure to cancel; + * Other nonzero on unexpected error. + */ +int ble_gap_disc_cancel(void); + +/** + * Indicates whether a discovery procedure is currently in progress. + * + * @return 0: No discovery procedure in progress; + * 1: Discovery procedure in progress. + */ +int ble_gap_disc_active(void); + +/** + * Initiates a connect procedure. + * + * @param own_addr_type The type of address the stack should use for + * itself during connection establishment. + * - BLE_OWN_ADDR_PUBLIC + * - BLE_OWN_ADDR_RANDOM + * - BLE_OWN_ADDR_RPA_PUBLIC_DEFAULT + * - BLE_OWN_ADDR_RPA_RANDOM_DEFAULT + * @param peer_addr The address of the peer to connect to. + * If this parameter is NULL, the white list + * is used. + * @param duration_ms The duration of the discovery procedure. + * On expiration, the procedure ends and a + * BLE_GAP_EVENT_DISC_COMPLETE event is + * reported. Units are milliseconds. + * @param conn_params Additional arguments specifying the particulars + * of the connect procedure. Specify null for + * default values. + * @param cb The callback to associate with this connect + * procedure. When the connect procedure + * completes, the result is reported through + * this callback. If the connect procedure + * succeeds, the connection inherits this + * callback as its event-reporting mechanism. + * @param cb_arg The optional argument to pass to the callback + * function. + * + * @return 0 on success; + * BLE_HS_EALREADY if a connection attempt is + * already in progress; + * BLE_HS_EBUSY if initiating a connection is not + * possible because scanning is in progress; + * BLE_HS_EDONE if the specified peer is already + * connected; + * Other nonzero on error. + */ +int ble_gap_connect(uint8_t own_addr_type, const ble_addr_t *peer_addr, + int32_t duration_ms, + const struct ble_gap_conn_params *params, + ble_gap_event_fn *cb, void *cb_arg); + +/** + * Initiates an extended connect procedure. + * + * @param own_addr_type The type of address the stack should use for + * itself during connection establishment. + * - BLE_OWN_ADDR_PUBLIC + * - BLE_OWN_ADDR_RANDOM + * - BLE_OWN_ADDR_RPA_PUBLIC_DEFAULT + * - BLE_OWN_ADDR_RPA_RANDOM_DEFAULT + * @param peer_addr The address of the peer to connect to. + * If this parameter is NULL, the white list + * is used. + * @param duration_ms The duration of the discovery procedure. + * On expiration, the procedure ends and a + * BLE_GAP_EVENT_DISC_COMPLETE event is + * reported. Units are milliseconds. + * @param phy_mask Define on which PHYs connection attempt should + * be done + * @param phy_1m_conn_params Additional arguments specifying the + * particulars of the connect procedure. When + * BLE_GAP_LE_PHY_1M_MASK is set in phy_mask + * this parameter can be specify to null for + * default values. + * @param phy_2m_conn_params Additional arguments specifying the + * particulars of the connect procedure. When + * BLE_GAP_LE_PHY_2M_MASK is set in phy_mask + * this parameter can be specify to null for + * default values. + * @param phy_coded_conn_params Additional arguments specifying the + * particulars of the connect procedure. When + * BLE_GAP_LE_PHY_CODED_MASK is set in + * phy_mask this parameter can be specify to + * null for default values. + * @param cb The callback to associate with this connect + * procedure. When the connect procedure + * completes, the result is reported through + * this callback. If the connect procedure + * succeeds, the connection inherits this + * callback as its event-reporting mechanism. + * @param cb_arg The optional argument to pass to the callback + * function. + * + * @return 0 on success; + * BLE_HS_EALREADY if a connection attempt is + * already in progress; + * BLE_HS_EBUSY if initiating a connection is not + * possible because scanning is in progress; + * BLE_HS_EDONE if the specified peer is already + * connected; + * Other nonzero on error. + */ +int ble_gap_ext_connect(uint8_t own_addr_type, const ble_addr_t *peer_addr, + int32_t duration_ms, uint8_t phy_mask, + const struct ble_gap_conn_params *phy_1m_conn_params, + const struct ble_gap_conn_params *phy_2m_conn_params, + const struct ble_gap_conn_params *phy_coded_conn_params, + ble_gap_event_fn *cb, void *cb_arg); + +/** + * Aborts a connect procedure in progress. + * + * @return 0 on success; + * BLE_HS_EALREADY if there is no active connect + * procedure. + * Other nonzero on error. + */ +int ble_gap_conn_cancel(void); + +/** + * Indicates whether a connect procedure is currently in progress. + * + * @return 0: No connect procedure in progress; + * 1: Connect procedure in progress. + */ +int ble_gap_conn_active(void); + +/** + * Terminates an established connection. + * + * @param conn_handle The handle corresponding to the connection to + * terminate. + * @param hci_reason The HCI error code to indicate as the reason + * for termination. + * + * @return 0 on success; + * BLE_HS_ENOTCONN if there is no connection with + * the specified handle; + * Other nonzero on failure. + */ +int ble_gap_terminate(uint16_t conn_handle, uint8_t hci_reason); + +/** + * Overwrites the controller's white list with the specified contents. + * + * @param addrs The entries to write to the white list. + * @param white_list_count The number of entries in the white list. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gap_wl_set(const ble_addr_t *addrs, uint8_t white_list_count); + +/** + * Initiates a connection parameter update procedure. + * + * @param conn_handle The handle corresponding to the connection to + * update. + * @param params The connection parameters to attempt to update + * to. + * + * @return 0 on success; + * BLE_HS_ENOTCONN if the there is no connection + * with the specified handle; + * BLE_HS_EALREADY if a connection update + * procedure for this connection is already in + * progress; + * BLE_HS_EINVAL if requested parameters are + * invalid; + * Other nonzero on error. + */ +int ble_gap_update_params(uint16_t conn_handle, + const struct ble_gap_upd_params *params); + +/** + * Initiates the GAP security procedure. + * + * Depending on connection role and stored security information this function + * will start appropriate security procedure (pairing or encryption). + * + * @param conn_handle The handle corresponding to the connection to + * secure. + * + * @return 0 on success; + * BLE_HS_ENOTCONN if the there is no connection + * with the specified handle; + * BLE_HS_EALREADY if an security procedure for + * this connection is already in progress; + * Other nonzero on error. + */ +int ble_gap_security_initiate(uint16_t conn_handle); + +/** + * Initiates the GAP pairing procedure as a master. This is for testing only and + * should not be used by application. Use ble_gap_security_initiate() instead. + * + * @param conn_handle The handle corresponding to the connection to + * start pairing on. + * + * @return 0 on success; + * BLE_HS_ENOTCONN if the there is no connection + * with the specified handle; + * BLE_HS_EALREADY if an pairing procedure for + * this connection is already in progress; + * Other nonzero on error. + */ +int ble_gap_pair_initiate(uint16_t conn_handle); + +/** + * Initiates the GAP encryption procedure as a master. This is for testing only + * and should not be used by application. Use ble_gap_security_initiate() + * instead. + * + * @param conn_handle The handle corresponding to the connection to + * start encryption. + * @param key_size Encryption key size + * @param ltk Long Term Key to be used for encryption. + * @param udiv Encryption Diversifier for LTK + * @param rand_val Random Value for EDIV and LTK + * @param auth If LTK provided is authenticated. + * + * @return 0 on success; + * BLE_HS_ENOTCONN if the there is no connection + * with the specified handle; + * BLE_HS_EALREADY if an encryption procedure for + * this connection is already in progress; + * Other nonzero on error. + */ +int ble_gap_encryption_initiate(uint16_t conn_handle, uint8_t key_size, + const uint8_t *ltk, uint16_t ediv, + uint64_t rand_val, int auth); + +/** + * Retrieves the most-recently measured RSSI for the specified connection. A + * connection's RSSI is updated whenever a data channel PDU is received. + * + * @param conn_handle Specifies the connection to query. + * @param out_rssi On success, the retrieved RSSI is written here. + * + * @return 0 on success; + * A BLE host HCI return code if the controller + * rejected the request; + * A BLE host core return code on unexpected + * error. + */ +int ble_gap_conn_rssi(uint16_t conn_handle, int8_t *out_rssi); + +/** + * Unpairs a device with the specified address. The keys related to that peer + * device are removed from storage and peer address is removed from the resolve + * list from the controller. If a peer is connected, the connection is terminated. + * + * @param peer_addr Address of the device to be unpaired + * + * @return 0 on success; + * A BLE host HCI return code if the controller + * rejected the request; + * A BLE host core return code on unexpected + * error. + */ +int ble_gap_unpair(const ble_addr_t *peer_addr); + +/** + * Unpairs the oldest bonded peer device. The keys related to that peer + * device are removed from storage and peer address is removed from the resolve + * list from the controller. If a peer is connected, the connection is terminated. + * + * @return 0 on success; + * A BLE host HCI return code if the controller + * rejected the request; + * A BLE host core return code on unexpected + * error. + */ +int ble_gap_unpair_oldest_peer(void); + +/** + * Similar to `ble_gap_unpair_oldest_peer()`, except it makes sure that the + * peer received in input parameters is not deleted. + * + * @param peer_addr Address of the peer (not to be deleted) + * + * @return 0 on success; + * A BLE host HCI return code if the controller + * rejected the request; + * A BLE host core return code on unexpected + * error. + */ +int ble_gap_unpair_oldest_except(const ble_addr_t *peer_addr); + +#define BLE_GAP_PRIVATE_MODE_NETWORK 0 +#define BLE_GAP_PRIVATE_MODE_DEVICE 1 + +/** + * Set privacy mode for specified peer device + * + * @param peer_addr Peer device address + * @param priv_mode Privacy mode to be used. Can be one of following + * constants: + * - BLE_GAP_PRIVATE_MODE_NETWORK + * - BLE_GAP_PRIVATE_MODE_DEVICE + * + * @return 0 on success; nonzero on failure. + */ +int ble_gap_set_priv_mode(const ble_addr_t *peer_addr, uint8_t priv_mode); + +#define BLE_GAP_LE_PHY_1M 1 +#define BLE_GAP_LE_PHY_2M 2 +#define BLE_GAP_LE_PHY_CODED 3 +/** + * Read PHYs used for specified connection. + * + * On success output parameters are filled with information about used PHY type. + * + * @param conn_handle Connection handle + * @param tx_phy TX PHY used. Can be one of following constants: + * - BLE_GAP_LE_PHY_1M + * - BLE_GAP_LE_PHY_2M + * - BLE_GAP_LE_PHY_CODED + * @param rx_phy RX PHY used. Can be one of following constants: + * - BLE_GAP_LE_PHY_1M + * - BLE_GAP_LE_PHY_2M + * - BLE_GAP_LE_PHY_CODED + * + * @return 0 on success; nonzero on failure. + */ +int ble_gap_read_le_phy(uint16_t conn_handle, uint8_t *tx_phy, uint8_t *rx_phy); + +#define BLE_GAP_LE_PHY_1M_MASK 0x01 +#define BLE_GAP_LE_PHY_2M_MASK 0x02 +#define BLE_GAP_LE_PHY_CODED_MASK 0x04 +#define BLE_GAP_LE_PHY_ANY_MASK 0x0F +/** + * Set preferred default PHYs to be used for connections. + * + * @params tx_phys_mask Preferred TX PHY. Can be mask of following + * constants: + * - BLE_GAP_LE_PHY_1M_MASK + * - BLE_GAP_LE_PHY_2M_MASK + * - BLE_GAP_LE_PHY_CODED_MASK + * - BLE_GAP_LE_PHY_ANY_MASK + * @params rx_phys_mask Preferred RX PHY. Can be mask of following + * constants: + * - BLE_GAP_LE_PHY_1M_MASK + * - BLE_GAP_LE_PHY_2M_MASK + * - BLE_GAP_LE_PHY_CODED_MASK + * - BLE_GAP_LE_PHY_ANY_MASK + + * @return 0 on success; nonzero on failure. + */ +int ble_gap_set_prefered_default_le_phy(uint8_t tx_phys_mask, + uint8_t rx_phys_mask); + +#define BLE_GAP_LE_PHY_CODED_ANY 0 +#define BLE_GAP_LE_PHY_CODED_S2 1 +#define BLE_GAP_LE_PHY_CODED_S8 2 +/** + * Set preferred PHYs to be used for connection. + * + * @param conn_handle Connection handle + * @params tx_phys_mask Preferred TX PHY. Can be mask of following + * constants: + * - BLE_GAP_LE_PHY_1M_MASK + * - BLE_GAP_LE_PHY_2M_MASK + * - BLE_GAP_LE_PHY_CODED_MASK + * - BLE_GAP_LE_PHY_ANY_MASK + * @params rx_phys_mask Preferred RX PHY. Can be mask of following + * constants: + * - BLE_GAP_LE_PHY_1M_MASK + * - BLE_GAP_LE_PHY_2M_MASK + * - BLE_GAP_LE_PHY_CODED_MASK + * - BLE_GAP_LE_PHY_ANY_MASK + * @param phy_opts Additional PHY options. Valid values are: + * - BLE_GAP_LE_PHY_CODED_ANY + * - BLE_GAP_LE_PHY_CODED_S2 + * - BLE_GAP_LE_PHY_CODED_S8 + * + * @return 0 on success; nonzero on failure. + */ +int ble_gap_set_prefered_le_phy(uint16_t conn_handle, uint8_t tx_phys_mask, + uint8_t rx_phys_mask, uint16_t phy_opts); + +/** + * Event listener structure + * + * This should be used as an opaque structure and not modified manually. + */ +struct ble_gap_event_listener { + ble_gap_event_fn *fn; + void *arg; + SLIST_ENTRY(ble_gap_event_listener) link; +}; + +/** + * Registers listener for GAP events + * + * On success listener structure will be initialized automatically and does not + * need to be initialized prior to calling this function. To change callback + * and/or argument unregister listener first and register it again. + * + * @param listener Listener structure + * @param fn Callback function + * @param arg Callback argument + * + * @return 0 on success + * BLE_HS_EINVAL if no callback is specified + * BLE_HS_EALREADY if listener is already registered + */ +int ble_gap_event_listener_register(struct ble_gap_event_listener *listener, + ble_gap_event_fn *fn, void *arg); + +/** + * Unregisters listener for GAP events + * + * @param listener Listener structure + * + * @return 0 on success + * BLE_HS_ENOENT if listener was not registered + */ +int ble_gap_event_listener_unregister(struct ble_gap_event_listener *listener); + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif diff --git a/libesp32/NimBLE-Arduino/src/host/ble_gatt.h b/libesp32/NimBLE-Arduino/src/host/ble_gatt.h new file mode 100644 index 000000000..d5c3269f0 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/host/ble_gatt.h @@ -0,0 +1,902 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_BLE_GATT_ +#define H_BLE_GATT_ + +/** + * @brief Bluetooth Generic Attribute Profile (GATT) + * @defgroup bt_gatt Bluetooth Generic Attribute Profile (GATT) + * @ingroup bt_host + * @{ + */ + +#include +#include "host/ble_att.h" +#include "host/ble_uuid.h" +#ifdef __cplusplus +extern "C" { +#endif + +struct ble_hs_conn; +struct ble_att_error_rsp; +struct ble_hs_cfg; + +#define BLE_GATT_REGISTER_OP_SVC 1 +#define BLE_GATT_REGISTER_OP_CHR 2 +#define BLE_GATT_REGISTER_OP_DSC 3 + +#define BLE_GATT_SVC_UUID16 0x1801 +#define BLE_GATT_DSC_CLT_CFG_UUID16 0x2902 + +#define BLE_GATT_CHR_PROP_BROADCAST 0x01 +#define BLE_GATT_CHR_PROP_READ 0x02 +#define BLE_GATT_CHR_PROP_WRITE_NO_RSP 0x04 +#define BLE_GATT_CHR_PROP_WRITE 0x08 +#define BLE_GATT_CHR_PROP_NOTIFY 0x10 +#define BLE_GATT_CHR_PROP_INDICATE 0x20 +#define BLE_GATT_CHR_PROP_AUTH_SIGN_WRITE 0x40 +#define BLE_GATT_CHR_PROP_EXTENDED 0x80 + +#define BLE_GATT_ACCESS_OP_READ_CHR 0 +#define BLE_GATT_ACCESS_OP_WRITE_CHR 1 +#define BLE_GATT_ACCESS_OP_READ_DSC 2 +#define BLE_GATT_ACCESS_OP_WRITE_DSC 3 + +#define BLE_GATT_CHR_F_BROADCAST 0x0001 +#define BLE_GATT_CHR_F_READ 0x0002 +#define BLE_GATT_CHR_F_WRITE_NO_RSP 0x0004 +#define BLE_GATT_CHR_F_WRITE 0x0008 +#define BLE_GATT_CHR_F_NOTIFY 0x0010 +#define BLE_GATT_CHR_F_INDICATE 0x0020 +#define BLE_GATT_CHR_F_AUTH_SIGN_WRITE 0x0040 +#define BLE_GATT_CHR_F_RELIABLE_WRITE 0x0080 +#define BLE_GATT_CHR_F_AUX_WRITE 0x0100 +#define BLE_GATT_CHR_F_READ_ENC 0x0200 +#define BLE_GATT_CHR_F_READ_AUTHEN 0x0400 +#define BLE_GATT_CHR_F_READ_AUTHOR 0x0800 +#define BLE_GATT_CHR_F_WRITE_ENC 0x1000 +#define BLE_GATT_CHR_F_WRITE_AUTHEN 0x2000 +#define BLE_GATT_CHR_F_WRITE_AUTHOR 0x4000 + +#define BLE_GATT_SVC_TYPE_END 0 +#define BLE_GATT_SVC_TYPE_PRIMARY 1 +#define BLE_GATT_SVC_TYPE_SECONDARY 2 + +/*** @client. */ +struct ble_gatt_error { + uint16_t status; + uint16_t att_handle; +}; + +struct ble_gatt_svc { + uint16_t start_handle; + uint16_t end_handle; + ble_uuid_any_t uuid; +}; + +struct ble_gatt_attr { + uint16_t handle; + uint16_t offset; + struct os_mbuf *om; +}; + +struct ble_gatt_chr { + uint16_t def_handle; + uint16_t val_handle; + uint8_t properties; + ble_uuid_any_t uuid; +}; + +struct ble_gatt_dsc { + uint16_t handle; + ble_uuid_any_t uuid; +}; + +typedef int ble_gatt_mtu_fn(uint16_t conn_handle, + const struct ble_gatt_error *error, + uint16_t mtu, void *arg); +typedef int ble_gatt_disc_svc_fn(uint16_t conn_handle, + const struct ble_gatt_error *error, + const struct ble_gatt_svc *service, + void *arg); + +/** + * The host will free the attribute mbuf automatically after the callback is + * executed. The application can take ownership of the mbuf and prevent it + * from being freed by assigning NULL to attr->om. + */ +typedef int ble_gatt_attr_fn(uint16_t conn_handle, + const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, + void *arg); + +/** + * The host will free the attribute mbufs automatically after the callback is + * executed. The application can take ownership of the mbufs and prevent them + * from being freed by assigning NULL to each attribute's om field. + */ +typedef int ble_gatt_reliable_attr_fn(uint16_t conn_handle, + const struct ble_gatt_error *error, + struct ble_gatt_attr *attrs, + uint8_t num_attrs, void *arg); + +typedef int ble_gatt_chr_fn(uint16_t conn_handle, + const struct ble_gatt_error *error, + const struct ble_gatt_chr *chr, void *arg); + +typedef int ble_gatt_dsc_fn(uint16_t conn_handle, + const struct ble_gatt_error *error, + uint16_t chr_val_handle, + const struct ble_gatt_dsc *dsc, + void *arg); + +/** + * Initiates GATT procedure: Exchange MTU. + * + * @param conn_handle The connection over which to execute the + * procedure. + * @param cb The function to call to report procedure status + * updates; null for no callback. + * @param cb_arg The optional argument to pass to the callback + * function. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gattc_exchange_mtu(uint16_t conn_handle, + ble_gatt_mtu_fn *cb, void *cb_arg); + +/** + * Initiates GATT procedure: Discover All Primary Services. + * + * @param conn_handle The connection over which to execute the + * procedure. + * @param cb The function to call to report procedure status + * updates; null for no callback. + * @param cb_arg The optional argument to pass to the callback + * function. + */ +int ble_gattc_disc_all_svcs(uint16_t conn_handle, + ble_gatt_disc_svc_fn *cb, void *cb_arg); + +/** + * Initiates GATT procedure: Discover Primary Service by Service UUID. + * + * @param conn_handle The connection over which to execute the + * procedure. + * @param service_uuid128 The 128-bit UUID of the service to discover. + * @param cb The function to call to report procedure status + * updates; null for no callback. + * @param cb_arg The optional argument to pass to the callback + * function. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gattc_disc_svc_by_uuid(uint16_t conn_handle, const ble_uuid_t *uuid, + ble_gatt_disc_svc_fn *cb, void *cb_arg); + +/** + * Initiates GATT procedure: Find Included Services. + * + * @param conn_handle The connection over which to execute the + * procedure. + * @param start_handle The handle to begin the search at (generally + * the service definition handle). + * @param end_handle The handle to end the search at (generally the + * last handle in the service). + * @param cb The function to call to report procedure status + * updates; null for no callback. + * @param cb_arg The optional argument to pass to the callback + * function. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gattc_find_inc_svcs(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle, + ble_gatt_disc_svc_fn *cb, void *cb_arg); + +/** + * Initiates GATT procedure: Discover All Characteristics of a Service. + * + * @param conn_handle The connection over which to execute the + * procedure. + * @param start_handle The handle to begin the search at (generally + * the service definition handle). + * @param end_handle The handle to end the search at (generally the + * last handle in the service). + * @param cb The function to call to report procedure status + * updates; null for no callback. + * @param cb_arg The optional argument to pass to the callback + * function. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gattc_disc_all_chrs(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle, ble_gatt_chr_fn *cb, + void *cb_arg); + +/** + * Initiates GATT procedure: Discover Characteristics by UUID. + * + * @param conn_handle The connection over which to execute the + * procedure. + * @param start_handle The handle to begin the search at (generally + * the service definition handle). + * @param end_handle The handle to end the search at (generally the + * last handle in the service). + * @param chr_uuid128 The 128-bit UUID of the characteristic to + * discover. + * @param cb The function to call to report procedure status + * updates; null for no callback. + * @param cb_arg The optional argument to pass to the callback + * function. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gattc_disc_chrs_by_uuid(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle, const ble_uuid_t *uuid, + ble_gatt_chr_fn *cb, void *cb_arg); + +/** + * Initiates GATT procedure: Discover All Characteristic Descriptors. + * + * @param conn_handle The connection over which to execute the + * procedure. + * @param chr_val_handle The handle of the characteristic value + * attribute. + * @param chr_end_handle The last handle in the characteristic + * definition. + * @param cb The function to call to report procedure status + * updates; null for no callback. + * @param cb_arg The optional argument to pass to the callback + * function. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gattc_disc_all_dscs(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle, + ble_gatt_dsc_fn *cb, void *cb_arg); + +/** + * Initiates GATT procedure: Read Characteristic Value. + * + * @param conn_handle The connection over which to execute the + * procedure. + * @param attr_handle The handle of the characteristic value to read. + * @param cb The function to call to report procedure status + * updates; null for no callback. + * @param cb_arg The optional argument to pass to the callback + * function. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gattc_read(uint16_t conn_handle, uint16_t attr_handle, + ble_gatt_attr_fn *cb, void *cb_arg); + +/** + * Initiates GATT procedure: Read Using Characteristic UUID. + * + * @param conn_handle The connection over which to execute the + * procedure. + * @param start_handle The first handle to search (generally the + * handle of the service definition). + * @param end_handle The last handle to search (generally the + * last handle in the service definition). + * @param cb The function to call to report procedure status + * updates; null for no callback. + * @param cb_arg The optional argument to pass to the callback + * function. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gattc_read_by_uuid(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle, const ble_uuid_t *uuid, + ble_gatt_attr_fn *cb, void *cb_arg); + +/** + * Initiates GATT procedure: Read Long Characteristic Values. + * + * @param conn_handle The connection over which to execute the + * procedure. + * @param handle The handle of the characteristic value to read. + * @param cb The function to call to report procedure status + * updates; null for no callback. + * @param cb_arg The optional argument to pass to the callback + * function. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gattc_read_long(uint16_t conn_handle, uint16_t handle, uint16_t offset, + ble_gatt_attr_fn *cb, void *cb_arg); + +/** + * Initiates GATT procedure: Read Multiple Characteristic Values. + * + * @param conn_handle The connection over which to execute the + * procedure. + * @param handles An array of 16-bit attribute handles to read. + * @param num_handles The number of entries in the "handles" array. + * @param cb The function to call to report procedure status + * updates; null for no callback. + * @param cb_arg The optional argument to pass to the callback + * function. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gattc_read_mult(uint16_t conn_handle, const uint16_t *handles, + uint8_t num_handles, ble_gatt_attr_fn *cb, + void *cb_arg); + +/** + * Initiates GATT procedure: Write Without Response. This function consumes + * the supplied mbuf regardless of the outcome. + * + * @param conn_handle The connection over which to execute the + * procedure. + * @param attr_handle The handle of the characteristic value to write + * to. + * @param txom The value to write to the characteristic. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gattc_write_no_rsp(uint16_t conn_handle, uint16_t attr_handle, + struct os_mbuf *om); + +/** + * Initiates GATT procedure: Write Without Response. This function consumes + * the supplied mbuf regardless of the outcome. + * + * @param conn_handle The connection over which to execute the + * procedure. + * @param attr_handle The handle of the characteristic value to write + * to. + * @param value The value to write to the characteristic. + * @param value_len The number of bytes to write. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gattc_write_no_rsp_flat(uint16_t conn_handle, uint16_t attr_handle, + const void *data, uint16_t data_len); + +/** + * Initiates GATT procedure: Write Characteristic Value. This function + * consumes the supplied mbuf regardless of the outcome. + * + * @param conn_handle The connection over which to execute the + * procedure. + * @param attr_handle The handle of the characteristic value to write + * to. + * @param txom The value to write to the characteristic. + * @param cb The function to call to report procedure status + * updates; null for no callback. + * @param cb_arg The optional argument to pass to the callback + * function. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gattc_write(uint16_t conn_handle, uint16_t attr_handle, + struct os_mbuf *om, + ble_gatt_attr_fn *cb, void *cb_arg); + +/** + * Initiates GATT procedure: Write Characteristic Value (flat buffer version). + * + * @param conn_handle The connection over which to execute the + * procedure. + * @param attr_handle The handle of the characteristic value to write + * to. + * @param value The value to write to the characteristic. + * @param value_len The number of bytes to write. + * @param cb The function to call to report procedure status + * updates; null for no callback. + * @param cb_arg The optional argument to pass to the callback + * function. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gattc_write_flat(uint16_t conn_handle, uint16_t attr_handle, + const void *data, uint16_t data_len, + ble_gatt_attr_fn *cb, void *cb_arg); + +/** + * Initiates GATT procedure: Write Long Characteristic Values. This function + * consumes the supplied mbuf regardless of the outcome. + * + * @param conn_handle The connection over which to execute the + * procedure. + * @param attr_handle The handle of the characteristic value to write + * to. + * @param txom The value to write to the characteristic. + * @param cb The function to call to report procedure status + * updates; null for no callback. + * @param cb_arg The optional argument to pass to the callback + * function. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gattc_write_long(uint16_t conn_handle, uint16_t attr_handle, + uint16_t offset, struct os_mbuf *om, + ble_gatt_attr_fn *cb, void *cb_arg); + +/** + * Initiates GATT procedure: Reliable Writes. This function consumes the + * supplied mbufs regardless of the outcome. + * + * @param conn_handle The connection over which to execute the + * procedure. + * @param attrs An array of attribute descriptors; specifies + * which characteristics to write to and what + * data to write to them. The mbuf pointer in + * each attribute is set to NULL by this + * function. + * @param num_attrs The number of characteristics to write; equal + * to the number of elements in the 'attrs' + * array. + * @param cb The function to call to report procedure status + * updates; null for no callback. + * @param cb_arg The optional argument to pass to the callback + * function. + */ +int ble_gattc_write_reliable(uint16_t conn_handle, + struct ble_gatt_attr *attrs, + int num_attrs, ble_gatt_reliable_attr_fn *cb, + void *cb_arg); + +/** + * Sends a "free-form" characteristic notification. This function consumes the + * supplied mbuf regardless of the outcome. + * + * @param conn_handle The connection over which to execute the + * procedure. + * @param chr_val_handle The attribute handle to indicate in the + * outgoing notification. + * @param txom The value to write to the characteristic. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gattc_notify_custom(uint16_t conn_handle, uint16_t att_handle, + struct os_mbuf *om); + +/** + * Sends a characteristic notification. The content of the message is read + * from the specified characteristic. + * + * @param conn_handle The connection over which to execute the + * procedure. + * @param chr_val_handle The value attribute handle of the + * characteristic to include in the outgoing + * notification. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gattc_notify(uint16_t conn_handle, uint16_t chr_val_handle); + +/** + * Sends a "free-form" characteristic indication. The provided mbuf contains + * the indication payload. This function consumes the supplied mbuf regardless + * of the outcome. + * + * @param conn_handle The connection over which to execute the + * procedure. + * @param chr_val_handle The value attribute handle of the + * characteristic to include in the outgoing + * indication. + * @param txom The data to include in the indication. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gattc_indicate_custom(uint16_t conn_handle, uint16_t chr_val_handle, + struct os_mbuf *txom); + +/** + * Sends a characteristic indication. The content of the message is read from + * the specified characteristic. + * + * @param conn_handle The connection over which to execute the + * procedure. + * @param chr_val_handle The value attribute handle of the + * characteristic to include in the outgoing + * indication. + * + * @return 0 on success; nonzero on failure. + */ +int ble_gattc_indicate(uint16_t conn_handle, uint16_t chr_val_handle); + +int ble_gattc_init(void); + +/*** @server. */ + +struct ble_gatt_access_ctxt; +typedef int ble_gatt_access_fn(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg); + +typedef uint16_t ble_gatt_chr_flags; + +struct ble_gatt_chr_def { + /** + * Pointer to characteristic UUID; use BLE_UUIDxx_DECLARE macros to declare + * proper UUID; NULL if there are no more characteristics in the service. + */ + const ble_uuid_t *uuid; + + /** + * Callback that gets executed when this characteristic is read or + * written. + */ + ble_gatt_access_fn *access_cb; + + /** Optional argument for callback. */ + void *arg; + + /** + * Array of this characteristic's descriptors. NULL if no descriptors. + * Do not include CCCD; it gets added automatically if this + * characteristic's notify or indicate flag is set. + */ + struct ble_gatt_dsc_def *descriptors; + + /** Specifies the set of permitted operations for this characteristic. */ + ble_gatt_chr_flags flags; + + /** Specifies minimum required key size to access this characteristic. */ + uint8_t min_key_size; + + /** + * At registration time, this is filled in with the characteristic's value + * attribute handle. + */ + uint16_t *val_handle; +}; + +struct ble_gatt_svc_def { + /** + * One of the following: + * o BLE_GATT_SVC_TYPE_PRIMARY - primary service + * o BLE_GATT_SVC_TYPE_SECONDARY - secondary service + * o 0 - No more services in this array. + */ + uint8_t type; + + /** + * Pointer to service UUID; use BLE_UUIDxx_DECLARE macros to declare + * proper UUID; NULL if there are no more characteristics in the service. + */ + const ble_uuid_t *uuid; + + /** + * Array of pointers to other service definitions. These services are + * reported as "included services" during service discovery. Terminate the + * array with NULL. + */ + const struct ble_gatt_svc_def **includes; + + /** + * Array of characteristic definitions corresponding to characteristics + * belonging to this service. + */ + const struct ble_gatt_chr_def *characteristics; +}; + +struct ble_gatt_dsc_def { + /** + * Pointer to descriptor UUID; use BLE_UUIDxx_DECLARE macros to declare + * proper UUID; NULL if there are no more characteristics in the service. + */ + const ble_uuid_t *uuid; + + /** Specifies the set of permitted operations for this descriptor. */ + uint8_t att_flags; + + /** Specifies minimum required key size to access this descriptor. */ + uint8_t min_key_size; + + /** Callback that gets executed when the descriptor is read or written. */ + ble_gatt_access_fn *access_cb; + + /** Optional argument for callback. */ + void *arg; +}; + +/** + * Context for an access to a GATT characteristic or descriptor. When a client + * reads or writes a locally registered characteristic or descriptor, an + * instance of this struct gets passed to the application callback. + */ +struct ble_gatt_access_ctxt { + /** + * Indicates the gatt operation being performed. This is equal to one of + * the following values: + * o BLE_GATT_ACCESS_OP_READ_CHR + * o BLE_GATT_ACCESS_OP_WRITE_CHR + * o BLE_GATT_ACCESS_OP_READ_DSC + * o BLE_GATT_ACCESS_OP_WRITE_DSC + */ + uint8_t op; + + /** + * A container for the GATT access data. + * o For reads: The application populates this with the value of the + * characteristic or descriptor being read. + * o For writes: This is already populated with the value being written + * by the peer. If the application wishes to retain this mbuf for + * later use, the access callback must set this pointer to NULL to + * prevent the stack from freeing it. + */ + struct os_mbuf *om; + + /** + * The GATT operation being performed dictates which field in this union is + * valid. If a characteristic is being accessed, the chr field is valid. + * Otherwise a descriptor is being accessed, in which case the dsc field + * is valid. + */ + union { + /** + * The characteristic definition corresponding to the characteristic + * being accessed. This is what the app registered at startup. + */ + const struct ble_gatt_chr_def *chr; + + /** + * The descriptor definition corresponding to the descriptor being + * accessed. This is what the app registered at startup. + */ + const struct ble_gatt_dsc_def *dsc; + }; +}; + +/** + * Context passed to the registration callback; represents the GATT service, + * characteristic, or descriptor being registered. + */ +struct ble_gatt_register_ctxt { + /** + * Indicates the gatt registration operation just performed. This is + * equal to one of the following values: + * o BLE_GATT_REGISTER_OP_SVC + * o BLE_GATT_REGISTER_OP_CHR + * o BLE_GATT_REGISTER_OP_DSC + */ + uint8_t op; + + /** + * The value of the op field determines which field in this union is valid. + */ + union { + /** Service; valid if op == BLE_GATT_REGISTER_OP_SVC. */ + struct { + /** The ATT handle of the service definition attribute. */ + uint16_t handle; + + /** + * The service definition representing the service being + * registered. + */ + const struct ble_gatt_svc_def *svc_def; + } svc; + + /** Characteristic; valid if op == BLE_GATT_REGISTER_OP_CHR. */ + struct { + /** The ATT handle of the characteristic definition attribute. */ + uint16_t def_handle; + + /** The ATT handle of the characteristic value attribute. */ + uint16_t val_handle; + + /** + * The characteristic definition representing the characteristic + * being registered. + */ + const struct ble_gatt_chr_def *chr_def; + + /** + * The service definition corresponding to the characteristic's + * parent service. + */ + const struct ble_gatt_svc_def *svc_def; + } chr; + + /** Descriptor; valid if op == BLE_GATT_REGISTER_OP_DSC. */ + struct { + /** The ATT handle of the descriptor definition attribute. */ + uint16_t handle; + + /** + * The descriptor definition corresponding to the descriptor being + * registered. + */ + const struct ble_gatt_dsc_def *dsc_def; + + /** + * The characteristic definition corresponding to the descriptor's + * parent characteristic. + */ + const struct ble_gatt_chr_def *chr_def; + + /** + * The service definition corresponding to the descriptor's + * grandparent service + */ + const struct ble_gatt_svc_def *svc_def; + } dsc; + }; +}; + +typedef void ble_gatt_register_fn(struct ble_gatt_register_ctxt *ctxt, + void *arg); + +/** + * Queues a set of service definitions for registration. All services queued + * in this manner get registered when ble_gatts_start() is called. + * + * @param svcs An array of service definitions to queue for + * registration. This array must be + * terminated with an entry whose 'type' + * equals 0. + * + * @return 0 on success; + * BLE_HS_ENOMEM on heap exhaustion. + */ +int ble_gatts_add_svcs(const struct ble_gatt_svc_def *svcs); + +/** + * Set visibility of local GATT service. Invisible services are not removed + * from database but are not discoverable by peer devices. Service Changed + * should be handled by application when needed by calling + * ble_svc_gatt_changed(). + * + * @param handle Handle of service + * @param visible non-zero if service should be visible + * + * @return 0 on success; + * BLE_HS_ENOENT if service wasn't found. + */ +int ble_gatts_svc_set_visibility(uint16_t handle, int visible); + +/** + * Adjusts a host configuration object's settings to accommodate the specified + * service definition array. This function adds the counts to the appropriate + * fields in the supplied configuration object without clearing them first, so + * it can be called repeatedly with different inputs to calculate totals. Be + * sure to zero the GATT server settings prior to the first call to this + * function. + * + * @param defs The service array containing the resource + * definitions to be counted. + * + * @return 0 on success; + * BLE_HS_EINVAL if the svcs array contains an + * invalid resource definition. + */ +int ble_gatts_count_cfg(const struct ble_gatt_svc_def *defs); + +/** + * Send notification (or indication) to any connected devices that have + * subscribed for notification (or indication) for specified characteristic. + * + * @param chr_val_handle Characteristic value handle + */ +void ble_gatts_chr_updated(uint16_t chr_val_handle); + +/** + * Retrieves the attribute handle associated with a local GATT service. + * + * @param uuid The UUID of the service to look up. + * @param out_handle On success, populated with the handle of the + * service attribute. Pass null if you don't + * need this value. + * + * @return 0 on success; + * BLE_HS_ENOENT if the specified service could + * not be found. + */ +int ble_gatts_find_svc(const ble_uuid_t *uuid, uint16_t *out_handle); + +/** + * Retrieves the pair of attribute handles associated with a local GATT + * characteristic. + * + * @param svc_uuid The UUID of the parent service. + * @param chr_uuid The UUID of the characteristic to look up. + * @param out_def_handle On success, populated with the handle + * of the characteristic definition attribute. + * Pass null if you don't need this value. + * @param out_val_handle On success, populated with the handle + * of the characteristic value attribute. + * Pass null if you don't need this value. + * + * @return 0 on success; + * BLE_HS_ENOENT if the specified service or + * characteristic could not be found. + */ +int ble_gatts_find_chr(const ble_uuid_t *svc_uuid, const ble_uuid_t *chr_uuid, + uint16_t *out_def_handle, uint16_t *out_val_handle); + +/** + * Retrieves the attribute handle associated with a local GATT descriptor. + * + * @param svc_uuid The UUID of the grandparent service. + * @param chr_uuid The UUID of the parent characteristic. + * @param dsc_uuid The UUID of the descriptor ro look up. + * @param out_handle On success, populated with the handle + * of the descriptor attribute. Pass null if + * you don't need this value. + * + * @return 0 on success; + * BLE_HS_ENOENT if the specified service, + * characteristic, or descriptor could not be + * found. + */ +int ble_gatts_find_dsc(const ble_uuid_t *svc_uuid, const ble_uuid_t *chr_uuid, + const ble_uuid_t *dsc_uuid, uint16_t *out_dsc_handle); + +typedef void (*ble_gatt_svc_foreach_fn)(const struct ble_gatt_svc_def *svc, + uint16_t handle, + uint16_t end_group_handle, + void *arg); + +/** + * Prints dump of local GATT database. This is useful to log local state of + * database in human readable form. + */ +void ble_gatts_show_local(void); + +/** + * Resets the GATT server to its initial state. On success, this function + * removes all supported services, characteristics, and descriptors. This + * function requires that: + * o No peers are connected, and + * o No GAP operations are active (advertise, discover, or connect). + * + * @return 0 on success; + * BLE_HS_EBUSY if the GATT server could not be + * reset due to existing connections or active + * GAP procedures. + */ +int ble_gatts_reset(void); + +/** + * Makes all registered services available to peers. This function gets called + * automatically by the NimBLE host on startup; manual calls are only necessary + * for replacing the set of supported services with a new one. This function + * requires that: + * o No peers are connected, and + * o No GAP operations are active (advertise, discover, or connect). + * + * @return 0 on success; + * A BLE host core return code on unexpected + * error. + */ +int ble_gatts_start(void); + +/** + * Resets the GATT configuration parameters and deallocates the memory of attributes. + * + */ +void ble_gatts_stop(void); + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif diff --git a/libesp32/NimBLE-Arduino/src/host/ble_hs.h b/libesp32/NimBLE-Arduino/src/host/ble_hs.h new file mode 100644 index 000000000..43979ba57 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/host/ble_hs.h @@ -0,0 +1,392 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_BLE_HS_ +#define H_BLE_HS_ + +/** + * @brief Bluetooth Host + * @defgroup bt_host Bluetooth Host + * @{ + */ + +#include +#include "nimble/hci_common.h" +#include "host/ble_att.h" +#include "host/ble_eddystone.h" +#include "host/ble_gap.h" +#include "host/ble_gatt.h" +#include "host/ble_hs_adv.h" +#include "host/ble_hs_id.h" +#include "host/ble_hs_hci.h" +#include "host/ble_hs_log.h" +#include "host/ble_hs_mbuf.h" +#include "host/ble_hs_stop.h" +#include "host/ble_ibeacon.h" +#include "host/ble_l2cap.h" +#include "host/ble_sm.h" +#include "host/ble_store.h" +#include "host/ble_uuid.h" +#include "nimble/nimble_npl.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define BLE_HS_FOREVER INT32_MAX + +/** Connection handle not present */ +#define BLE_HS_CONN_HANDLE_NONE 0xffff + +/** + * @brief Bluetooth Host Error Code + * @defgroup bt_host_err Bluetooth Host Error Code + * + * Defines error codes returned by Bluetooth host. If error comes from specific + * component (eg L2CAP or Security Manager) it is shifted by base allowing to + * identify component. + * @{ + */ + +#define BLE_HS_EAGAIN 1 +#define BLE_HS_EALREADY 2 +#define BLE_HS_EINVAL 3 +#define BLE_HS_EMSGSIZE 4 +#define BLE_HS_ENOENT 5 +#define BLE_HS_ENOMEM 6 +#define BLE_HS_ENOTCONN 7 +#define BLE_HS_ENOTSUP 8 +#define BLE_HS_EAPP 9 +#define BLE_HS_EBADDATA 10 +#define BLE_HS_EOS 11 +#define BLE_HS_ECONTROLLER 12 +#define BLE_HS_ETIMEOUT 13 +#define BLE_HS_EDONE 14 +#define BLE_HS_EBUSY 15 +#define BLE_HS_EREJECT 16 +#define BLE_HS_EUNKNOWN 17 +#define BLE_HS_EROLE 18 +#define BLE_HS_ETIMEOUT_HCI 19 +#define BLE_HS_ENOMEM_EVT 20 +#define BLE_HS_ENOADDR 21 +#define BLE_HS_ENOTSYNCED 22 +#define BLE_HS_EAUTHEN 23 +#define BLE_HS_EAUTHOR 24 +#define BLE_HS_EENCRYPT 25 +#define BLE_HS_EENCRYPT_KEY_SZ 26 +#define BLE_HS_ESTORE_CAP 27 +#define BLE_HS_ESTORE_FAIL 28 +#define BLE_HS_EPREEMPTED 29 +#define BLE_HS_EDISABLED 30 +#define BLE_HS_ESTALLED 31 + +/** Error base for ATT errors */ +#define BLE_HS_ERR_ATT_BASE 0x100 + +/** Converts error to ATT base */ +#define BLE_HS_ATT_ERR(x) ((x) ? BLE_HS_ERR_ATT_BASE + (x) : 0) + +/** Error base for HCI errors */ +#define BLE_HS_ERR_HCI_BASE 0x200 + +/** Converts error to HCI base */ +#define BLE_HS_HCI_ERR(x) ((x) ? BLE_HS_ERR_HCI_BASE + (x) : 0) + +/** Error base for L2CAP errors */ +#define BLE_HS_ERR_L2C_BASE 0x300 + +/** Converts error to L2CAP base */ +#define BLE_HS_L2C_ERR(x) ((x) ? BLE_HS_ERR_L2C_BASE + (x) : 0) + +/** Error base for local Security Manager errors */ +#define BLE_HS_ERR_SM_US_BASE 0x400 + +/** Converts error to local Security Manager base */ +#define BLE_HS_SM_US_ERR(x) ((x) ? BLE_HS_ERR_SM_US_BASE + (x) : 0) + +/** Error base for remote (peer) Security Manager errors */ +#define BLE_HS_ERR_SM_PEER_BASE 0x500 + +/** Converts error to remote (peer) Security Manager base */ +#define BLE_HS_SM_PEER_ERR(x) ((x) ? BLE_HS_ERR_SM_PEER_BASE + (x) : 0) + +/** Error base for hardware errors */ +#define BLE_HS_ERR_HW_BASE 0x600 + +/** Converts error to hardware error base */ +#define BLE_HS_HW_ERR(x) (BLE_HS_ERR_HW_BASE + (x)) + +/** + * @} + */ + +/** + * @brief Bluetooth Host Configuration + * @defgroup bt_host_conf Bluetooth Host Configuration + * + * @{ + */ + +/** + * @brief Local Input-Output capabilities of device + * @defgroup bt_host_io_local Local Input-Output capabilities of device + * + * @{ + */ + +/** DisplayOnly IO capability */ +#define BLE_HS_IO_DISPLAY_ONLY 0x00 + +/** DisplayYesNo IO capability */ +#define BLE_HS_IO_DISPLAY_YESNO 0x01 + +/** KeyboardOnly IO capability */ +#define BLE_HS_IO_KEYBOARD_ONLY 0x02 + +/** NoInputNoOutput IO capability */ +#define BLE_HS_IO_NO_INPUT_OUTPUT 0x03 + +/** KeyboardDisplay Only IO capability */ +#define BLE_HS_IO_KEYBOARD_DISPLAY 0x04 + +/** + * @} + */ + +/** @brief Stack reset callback + * + * @param reason Reason code for reset + */ +typedef void ble_hs_reset_fn(int reason); + + +/** @brief Stack sync callback */ +typedef void ble_hs_sync_fn(void); + +/** @brief Bluetooth Host main configuration structure + * + * Those can be used by application to configure stack. + * + * The only reason Security Manager (sm_ members) is configurable at runtime is + * to simplify security testing. Defaults for those are configured by selecting + * proper options in application's syscfg. + */ +struct ble_hs_cfg { + /** + * An optional callback that gets executed upon registration of each GATT + * resource (service, characteristic, or descriptor). + */ + ble_gatt_register_fn *gatts_register_cb; + + /** + * An optional argument that gets passed to the GATT registration + * callback. + */ + void *gatts_register_arg; + + /** Security Manager Local Input Output Capabilities */ + uint8_t sm_io_cap; + + /** @brief Security Manager OOB flag + * + * If set proper flag in Pairing Request/Response will be set. + */ + unsigned sm_oob_data_flag:1; + + /** @brief Security Manager Bond flag + * + * If set proper flag in Pairing Request/Response will be set. This results + * in storing keys distributed during bonding. + */ + unsigned sm_bonding:1; + + /** @brief Security Manager MITM flag + * + * If set proper flag in Pairing Request/Response will be set. This results + * in requiring Man-In-The-Middle protection when pairing. + */ + unsigned sm_mitm:1; + + /** @brief Security Manager Secure Connections flag + * + * If set proper flag in Pairing Request/Response will be set. This results + * in using LE Secure Connections for pairing if also supported by remote + * device. Fallback to legacy pairing if not supported by remote. + */ + unsigned sm_sc:1; + + /** @brief Security Manager Key Press Notification flag + * + * Currently unsupported and should not be set. + */ + unsigned sm_keypress:1; + + /** @brief Security Manager Local Key Distribution Mask */ + uint8_t sm_our_key_dist; + + /** @brief Security Manager Remote Key Distribution Mask */ + uint8_t sm_their_key_dist; + + /** @brief Stack reset callback + * + * This callback is executed when the host resets itself and the controller + * due to fatal error. + */ + ble_hs_reset_fn *reset_cb; + + /** @brief Stack sync callback + * + * This callback is executed when the host and controller become synced. + * This happens at startup and after a reset. + */ + ble_hs_sync_fn *sync_cb; + + /* XXX: These need to go away. Instead, the nimble host package should + * require the host-store API (not yet implemented).. + */ + /** Storage Read callback handles read of security material */ + ble_store_read_fn *store_read_cb; + + /** Storage Write callback handles write of security material */ + ble_store_write_fn *store_write_cb; + + /** Storage Delete callback handles deletion of security material */ + ble_store_delete_fn *store_delete_cb; + + /** @brief Storage Status callback. + * + * This callback gets executed when a persistence operation cannot be + * performed or a persistence failure is imminent. For example, if is + * insufficient storage capacity for a record to be persisted, this + * function gets called to give the application the opportunity to make + * room. + */ + ble_store_status_fn *store_status_cb; + + /** An optional argument that gets passed to the storage status callback. */ + void *store_status_arg; +}; + +extern struct ble_hs_cfg ble_hs_cfg; + +/** + * @} + */ + +/** + * @brief Indicates whether the host is enabled. The host is enabled if it is + * starting or fully started. It is disabled if it is stopping or stopped. + * + * @return 1 if the host is enabled; + * 0 if the host is disabled. + */ +int ble_hs_is_enabled(void); + +/** + * Indicates whether the host has synchronized with the controller. + * Synchronization must occur before any host procedures can be performed. + * + * @return 1 if the host and controller are in sync; + * 0 if the host and controller are out of sync. + */ +int ble_hs_synced(void); + +/** + * Synchronizes the host with the controller by sending a sequence of HCI + * commands. This function must be called before any other host functionality + * is used, but it must be called after both the host and controller are + * initialized. Typically, the host-parent-task calls this function at the top + * of its task routine. This function must only be called in the host parent + * task. A safe alternative for starting the stack from any task is to call + * `ble_hs_sched_start()`. + * + * If the host fails to synchronize with the controller (if the controller is + * not fully booted, for example), the host will attempt to resynchronize every + * 100 ms. For this reason, an error return code is not necessarily fatal. + * + * @return 0 on success; nonzero on error. + */ +int ble_hs_start(void); + +/** + * Enqueues a host start event to the default event queue. The actual host + * startup is performed in the host parent task, but using the default queue + * here ensures the event won't run until the end of main() when this is + * called during system initialization. This allows the application to + * configure the host package in the meantime. + * + * If auto-start is disabled, the application should use this function to start + * the BLE stack. This function can be called at any time as long as the host + * is stopped. When the host successfully starts, the application is notified + * via the ble_hs_cfg.sync_cb callback. + */ +void ble_hs_sched_start(void); + +/** + * Causes the host to reset the NimBLE stack as soon as possible. The + * application is notified when the reset occurs via the host reset callback. + * + * @param reason The host error code that gets passed to the reset callback. + */ +void ble_hs_sched_reset(int reason); + +/** + * Designates the specified event queue for NimBLE host work. By default, the + * host uses the default event queue and runs in the main task. This function + * is useful if you want the host to run in a different task. + * + * @param evq The event queue to use for host work. + */ +void ble_hs_evq_set(struct ble_npl_eventq *evq); + +/** + * Initializes the NimBLE host. This function must be called before the OS is + * started. The NimBLE stack requires an application task to function. One + * application task in particular is designated as the "host parent task". In + * addition to application-specific work, the host parent task does work for + * NimBLE by processing events generated by the host. + */ +void ble_hs_init(void); + +/** + * Deinitializes the NimBLE host. This function must be called after the + * NimBLE host stop procedure is complete. + */ +void ble_hs_deinit(void); + +/** + * @brief Called when the system is shutting down. Stops the BLE host. + * + * @param reason The reason for the shutdown. One of the + * HAL_RESET_[...] codes or an + * implementation-defined value. + * + * @return SYSDOWN_IN_PROGRESS. + */ +int ble_hs_shutdown(int reason); + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif diff --git a/libesp32/NimBLE-Arduino/src/host/ble_hs_adv.h b/libesp32/NimBLE-Arduino/src/host/ble_hs_adv.h new file mode 100644 index 000000000..b0d85c02a --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/host/ble_hs_adv.h @@ -0,0 +1,177 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_BLE_HS_ADV_ +#define H_BLE_HS_ADV_ + +#include +#include "host/ble_uuid.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define BLE_HS_ADV_MAX_SZ BLE_HCI_MAX_ADV_DATA_LEN + +/** Max field payload size (account for 2-byte header). */ +#define BLE_HS_ADV_MAX_FIELD_SZ (BLE_HS_ADV_MAX_SZ - 2) + +struct ble_hs_adv_field { + uint8_t length; + uint8_t type; + uint8_t value[]; +}; + +typedef int (* ble_hs_adv_parse_func_t) (const struct ble_hs_adv_field *, + void *); + +struct ble_hs_adv_fields { + /*** 0x01 - Flags. */ + uint8_t flags; + + /*** 0x02,0x03 - 16-bit service class UUIDs. */ + ble_uuid16_t *uuids16; + uint8_t num_uuids16; + unsigned uuids16_is_complete:1; + + /*** 0x04,0x05 - 32-bit service class UUIDs. */ + ble_uuid32_t *uuids32; + uint8_t num_uuids32; + unsigned uuids32_is_complete:1; + + /*** 0x06,0x07 - 128-bit service class UUIDs. */ + ble_uuid128_t *uuids128; + uint8_t num_uuids128; + unsigned uuids128_is_complete:1; + + /*** 0x08,0x09 - Local name. */ + uint8_t *name; + uint8_t name_len; + unsigned name_is_complete:1; + + /*** 0x0a - Tx power level. */ + int8_t tx_pwr_lvl; + unsigned tx_pwr_lvl_is_present:1; + + /*** 0x0d - Slave connection interval range. */ + uint8_t *slave_itvl_range; + + /*** 0x16 - Service data - 16-bit UUID. */ + uint8_t *svc_data_uuid16; + uint8_t svc_data_uuid16_len; + + /*** 0x17 - Public target address. */ + uint8_t *public_tgt_addr; + uint8_t num_public_tgt_addrs; + + /*** 0x19 - Appearance. */ + uint16_t appearance; + unsigned appearance_is_present:1; + + /*** 0x1a - Advertising interval. */ + uint16_t adv_itvl; + unsigned adv_itvl_is_present:1; + + /*** 0x20 - Service data - 32-bit UUID. */ + uint8_t *svc_data_uuid32; + uint8_t svc_data_uuid32_len; + + /*** 0x21 - Service data - 128-bit UUID. */ + uint8_t *svc_data_uuid128; + uint8_t svc_data_uuid128_len; + + /*** 0x24 - URI. */ + uint8_t *uri; + uint8_t uri_len; + + /*** 0xff - Manufacturer specific data. */ + uint8_t *mfg_data; + uint8_t mfg_data_len; +}; + +#define BLE_HS_ADV_TYPE_FLAGS 0x01 +#define BLE_HS_ADV_TYPE_INCOMP_UUIDS16 0x02 +#define BLE_HS_ADV_TYPE_COMP_UUIDS16 0x03 +#define BLE_HS_ADV_TYPE_INCOMP_UUIDS32 0x04 +#define BLE_HS_ADV_TYPE_COMP_UUIDS32 0x05 +#define BLE_HS_ADV_TYPE_INCOMP_UUIDS128 0x06 +#define BLE_HS_ADV_TYPE_COMP_UUIDS128 0x07 +#define BLE_HS_ADV_TYPE_INCOMP_NAME 0x08 +#define BLE_HS_ADV_TYPE_COMP_NAME 0x09 +#define BLE_HS_ADV_TYPE_TX_PWR_LVL 0x0a +#define BLE_HS_ADV_TYPE_SLAVE_ITVL_RANGE 0x12 +#define BLE_HS_ADV_TYPE_SOL_UUIDS16 0x14 +#define BLE_HS_ADV_TYPE_SOL_UUIDS128 0x15 +#define BLE_HS_ADV_TYPE_SVC_DATA_UUID16 0x16 +#define BLE_HS_ADV_TYPE_PUBLIC_TGT_ADDR 0x17 +#define BLE_HS_ADV_TYPE_RANDOM_TGT_ADDR 0x18 +#define BLE_HS_ADV_TYPE_APPEARANCE 0x19 +#define BLE_HS_ADV_TYPE_ADV_ITVL 0x1a +#define BLE_HS_ADV_TYPE_SVC_DATA_UUID32 0x20 +#define BLE_HS_ADV_TYPE_SVC_DATA_UUID128 0x21 +#define BLE_HS_ADV_TYPE_URI 0x24 +#define BLE_HS_ADV_TYPE_MESH_PROV 0x29 +#define BLE_HS_ADV_TYPE_MESH_MESSAGE 0x2a +#define BLE_HS_ADV_TYPE_MESH_BEACON 0x2b +#define BLE_HS_ADV_TYPE_MFG_DATA 0xff + +#define BLE_HS_ADV_FLAGS_LEN 1 +#define BLE_HS_ADV_F_DISC_LTD 0x01 +#define BLE_HS_ADV_F_DISC_GEN 0x02 +#define BLE_HS_ADV_F_BREDR_UNSUP 0x04 + +#define BLE_HS_ADV_TX_PWR_LVL_LEN 1 + +/** + * Set the tx_pwr_lvl field to this if you want the stack to fill in the tx + * power level field. + */ +#define BLE_HS_ADV_TX_PWR_LVL_AUTO (-128) + +#define BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN 4 + +#define BLE_HS_ADV_SVC_DATA_UUID16_MIN_LEN 2 + +#define BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN 6 + +#define BLE_HS_ADV_APPEARANCE_LEN 2 + +#define BLE_HS_ADV_ADV_ITVL_LEN 2 + +#define BLE_HS_ADV_SVC_DATA_UUID32_MIN_LEN 4 + +#define BLE_HS_ADV_SVC_DATA_UUID128_MIN_LEN 16 + +int ble_hs_adv_set_fields_mbuf(const struct ble_hs_adv_fields *adv_fields, + struct os_mbuf *om); + +int ble_hs_adv_set_fields(const struct ble_hs_adv_fields *adv_fields, + uint8_t *dst, uint8_t *dst_len, uint8_t max_len); + +int ble_hs_adv_parse_fields(struct ble_hs_adv_fields *adv_fields, uint8_t *src, + uint8_t src_len); + +int ble_hs_adv_parse(const uint8_t *data, uint8_t length, + ble_hs_adv_parse_func_t func, void *user_data); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libesp32/NimBLE-Arduino/src/host/ble_hs_hci.h b/libesp32/NimBLE-Arduino/src/host/ble_hs_hci.h new file mode 100644 index 000000000..e10b8e62a --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/host/ble_hs_hci.h @@ -0,0 +1,98 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_BLE_HS_HCI_ +#define H_BLE_HS_HCI_ + +/** + * @brief Bluetooth Host HCI utils + * @defgroup bt_host_hci Bluetooth Host HCI utils + * @ingroup bt_host + * @{ + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Queries the controller for the channel map used with the specified + * connection. The channel map is represented as an array of five bytes, with + * each bit corresponding to an individual channel. The array is interpreted + * as little-endian, such that: + * map[0] & 0x01 --> Channel 0. + * map[0] & 0x02 --> Channel 1. + * ... + * map[1] & 0x01 --> Channel 8. + * + * As there are 37 channels, only the first 37 bits get written. + * + * If a bit is 1, the corresponding channel is used. Otherwise, the channel is + * unused. + * + * @param conn_handle The handle of the connection whose channel map + * is being read. + * @param out_chan_map On success, the retrieved channel map gets + * written here. This buffer must have a size + * >= 5 bytes. + * + * @return 0 on success; + * A BLE host HCI return code if the controller + * rejected the request; + * A BLE host core return code on unexpected + * error. + */ +int ble_hs_hci_read_chan_map(uint16_t conn_handle, uint8_t *out_chan_map); + +/** + * Instructs the controller to use the specified channel map. The channel map + * is represented as an array of five bytes, with each bit corresponding to an + * individual channel. The array is interpreted as little-endian, such that: + * map[0] & 0x01 --> Channel 0. + * map[0] & 0x02 --> Channel 1. + * ... + * map[1] & 0x01 --> Channel 8. + * + * As there are 37 channels, only the first 37 bits should be written are used. + * + * If a bit is 1, the corresponding channel can be used. Otherwise, the + * channel should not be used. + * + * @param chan_map The channel map to configure. This buffer + * should have a size of 5 bytes. + * + * @return 0 on success; + * A BLE host HCI return code if the controller + * rejected the request; + * A BLE host core return code on unexpected + * error. + */ +int ble_hs_hci_set_chan_class(const uint8_t *chan_map); + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif diff --git a/libesp32/NimBLE-Arduino/src/host/ble_hs_id.h b/libesp32/NimBLE-Arduino/src/host/ble_hs_id.h new file mode 100644 index 000000000..c96bd20f5 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/host/ble_hs_id.h @@ -0,0 +1,132 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_BLE_HS_ID_ +#define H_BLE_HS_ID_ + +/** + * @brief Bluetooth Host Identity + * @defgroup bt_host_id Bluetooth Host Identity + * @ingroup bt_host + * @{ + */ + +#include +#include "nimble/ble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Generates a new random address. This function does not configure the device + * with the new address; the caller can use the address in subsequent + * operations. + * + * @param nrpa The type of random address to generate: + * 0: static + * 1: non-resolvable private + * @param out_addr On success, the generated address gets written + * here. + * + * @return 0 on success; nonzero on failure. + */ +int ble_hs_id_gen_rnd(int nrpa, ble_addr_t *out_addr); + +/** + * Sets the device's random address. The address type (static vs. + * non-resolvable private) is inferred from the most-significant byte of the + * address. The address is specified in host byte order (little-endian!). + * + * @param rnd_addr The random address to set. + * + * @return 0 on success; + * BLE_HS_EINVAL if the specified address is not a + * valid static random or non-resolvable + * private address. + * Other nonzero on error. + */ +int ble_hs_id_set_rnd(const uint8_t *rnd_addr); + +/** + * Retrieves one of the device's identity addresses. The device can have two + * identity addresses: one public and one random. The id_addr_type argument + * specifies which of these two addresses to retrieve. + * + * @param id_addr_type The type of identity address to retrieve. + * Valid values are: + * o BLE_ADDR_PUBLIC + * o BLE_ADDR_RANDOM + * @param out_id_addr On success, the requested identity address is + * copied into this buffer. The buffer must + * be at least six bytes in size. Pass NULL + * if you do not require this information. + * @param out_is_nrpa On success, the pointed-to value indicates + * whether the retrieved address is a + * non-resolvable private address. Pass NULL + * if you do not require this information. + * + * @return 0 on success; + * BLE_HS_EINVAL if an invalid address type was + * specified; + * BLE_HS_ENOADDR if the device does not have an + * identity address of the requested type; + * Other BLE host core code on error. + */ +int ble_hs_id_copy_addr(uint8_t id_addr_type, uint8_t *out_id_addr, + int *out_is_nrpa); + +/** + * Determines the best address type to use for automatic address type + * resolution. Calculation of the best address type is done as follows: + * + * if privacy requested: + * if we have a random static address: + * --> RPA with static random ID + * else + * --> RPA with public ID + * end + * else + * if we have a random static address: + * --> random static address + * else + * --> public address + * end + * end + * + * @param privacy (0/1) Whether to use a private address. + * @param out_addr_type On success, the "own addr type" code gets + * written here. + * + * @return 0 if an address type was successfully inferred. + * BLE_HS_ENOADDR if the device does not have a + * suitable address. + * Other BLE host core code on error. + */ +int ble_hs_id_infer_auto(int privacy, uint8_t *out_addr_type); + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif diff --git a/libesp32/NimBLE-Arduino/src/host/ble_hs_log.h b/libesp32/NimBLE-Arduino/src/host/ble_hs_log.h new file mode 100644 index 000000000..3fb1db978 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/host/ble_hs_log.h @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_BLE_HS_LOG_ +#define H_BLE_HS_LOG_ + +#include "modlog/modlog.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct os_mbuf; + +#define BLE_HS_LOG(lvl, ...) \ + MODLOG_ ## lvl(LOG_MODULE_NIMBLE_HOST, __VA_ARGS__) + +#define BLE_HS_LOG_ADDR(lvl, addr) \ + MODLOG_ ## lvl(LOG_MODULE_NIMBLE_HOST, \ + "%02x:%02x:%02x:%02x:%02x:%02x", \ + (addr)[5], (addr)[4], (addr)[3], \ + (addr)[2], (addr)[1], (addr)[0]) + +void ble_hs_log_mbuf(const struct os_mbuf *om); +void ble_hs_log_flat_buf(const void *data, int len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libesp32/NimBLE-Arduino/src/host/ble_hs_mbuf.h b/libesp32/NimBLE-Arduino/src/host/ble_hs_mbuf.h new file mode 100644 index 000000000..a3c2c0296 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/host/ble_hs_mbuf.h @@ -0,0 +1,82 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_BLE_HS_MBUF_ +#define H_BLE_HS_MBUF_ + +/** + * @brief Bluetooth Host chained memory buffer (mbuf) + * @defgroup bt_host_mbuf Bluetooth Host chained memory buffer (mbuf) + * @ingroup bt_host + * @{ + */ + +#include +#ifdef __cplusplus +extern "C" { +#endif + +struct os_mbuf; + +/** + * Allocates an mbuf suitable for an ATT command packet. The resulting packet + * has sufficient leading space for: + * - ACL data header + * - L2CAP B-frame header + * - Largest ATT command base (prepare write request / response). + * + * @return An empty mbuf on success, NULL on error. + */ +struct os_mbuf *ble_hs_mbuf_att_pkt(void); + +/** + * Allocates an mbuf and fills it with the contents of the specified flat + * buffer. + * + * @param buf The flat buffer to copy from. + * @param len The length of the flat buffer. + * + * @return A newly-allocated mbuf on success, NULL on error. + */ +struct os_mbuf *ble_hs_mbuf_from_flat(const void *buf, uint16_t len); + +/** + * Copies the contents of an mbuf into the specified flat buffer. If the flat + * buffer is too small to contain the mbuf's contents, it is filled to capacity + * and BLE_HS_EMSGSIZE is returned. + * + * @param om The mbuf to copy from. + * @param flat The destination flat buffer. + * @param max_len The size of the flat buffer. + * @param out_copy_len The number of bytes actually copied gets written here. + * + * @return 0 on success or BLE host core return code on error. + */ +int ble_hs_mbuf_to_flat(const struct os_mbuf *om, void *flat, uint16_t max_len, + uint16_t *out_copy_len); + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif diff --git a/libesp32/NimBLE-Arduino/src/host/ble_hs_pvcy.h b/libesp32/NimBLE-Arduino/src/host/ble_hs_pvcy.h new file mode 100644 index 000000000..19087f220 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/host/ble_hs_pvcy.h @@ -0,0 +1,73 @@ +/* + * Copyright 2020 Espressif Systems (Shanghai) PTE LTD + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_BLE_HS_PVCY_ +#define H_BLE_HS_PVCY_ + +#include "host/ble_hs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if MYNEWT_VAL(BLE_HOST_BASED_PRIVACY) + +#define NIMBLE_HOST_DISABLE_PRIVACY 0x00 +#define NIMBLE_HOST_ENABLE_RPA 0x01 +#define NIMBLE_HOST_ENABLE_NRPA 0x02 + +/* Called to configure local(own) privacy (RPA/NRPA) when using Host based privacy. + * In Host based privacy, as controller is not aware of RPA/NRPA address is in use, + * we do it through 'BLE_ADDR_RANDOM (0x01)' addr_type route. This is necessary + * so as to set the private address as random address in controller. + * Remember to configure `BLE_SM_PAIR_KEY_DIST_ID` in our & their + * key distributions for using RPA. For NRPA part of privacy it is not + * necessary to configure key distributions in host, as anyway NRPA is non-resolvable. + * Please call this API once host-controller are synced as we set the private + * (RPA/NRPA) address using host-controller HCI commands. + * + * To give brief information on how to use this feature, + * please refer to following steps while using RPA feature: + * + * 1. Include "host/ble_hs_pvcy.h". + * 2. Set own_addr_type to `BLE_OWN_ADDR_RANDOM`. + * 3. Add `BLE_SM_PAIR_KEY_DIST_ID` to key distribution in + * `ble_hs_cfg.sm_our_key_dist` & `ble_hs_cfg.sm_their_key_dist`. + * 4. Call `ble_hs_pvcy_rpa_config(1)` in Host-Controller sync callback. + * + * In case of NRPA, steps 1, 2 and calling ble_hs_pvcy_rpa_config(2) will + * suffice. + * + * @param enable RPA when param = 1 (NIMBLE_HOST_ENABLE_RPA) + * enable NRPA when param = 2 (NIMBLE_HOST_ENABLE_NRPA) + * disable privacy when param = 0 (NIMBLE_HOST_DISABLE_PRIVACY) + * + * @return return 0 when successful. + * return appropriate error code otherwise + */ +int ble_hs_pvcy_rpa_config(uint8_t enable); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libesp32/NimBLE-Arduino/src/host/ble_hs_stop.h b/libesp32/NimBLE-Arduino/src/host/ble_hs_stop.h new file mode 100644 index 000000000..d16c9c27b --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/host/ble_hs_stop.h @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_BLE_HS_STOP_ +#define H_BLE_HS_STOP_ + +/** @typedef ble_hs_stop_fn + * @brief Callback function; reports the result of a host stop procedure. + * + * @param status The result of the host stop procedure. One of + * the HAL_RESET_[...] codes or an + * implementation-defined value. + * @param arg Optional argument specified when the stop + * procedure was initiated. + * + */ +typedef void ble_hs_stop_fn(int status, void *arg); + +/** + * @brief Used to report the result of a stop procedure. + * + * This should be used as an opaque structure and not modified manually. + */ +struct ble_hs_stop_listener { + ble_hs_stop_fn *fn; + void *arg; + SLIST_ENTRY(ble_hs_stop_listener) link; +}; + +/** + * @brief Stops the BLE host. + * + * Aborts all active GAP procedures and terminates all open connections. + * Connection termination is performed asynchronously, so this function's + * result is reported via the provided listener. + * + * @param listener A listener to populate. This object's initial + * value doesn't matter, but its lifetime must + * extend until the stop procedure completes. + * @param fn The callback to execute when the stop procedure + * completes. + * @param arg Optional argument to pass to the callback. + * + * @return 0: Stop procedure successfully initiated. + * BLE_HS_EBUSY: Stop procedure already in + * progress; the provided callback gets called + * when the procedure completes. + * BLE_HS_EALREADY: Host already stopped; the + * provided callback does *not* get called. + */ +int ble_hs_stop(struct ble_hs_stop_listener *listener, + ble_hs_stop_fn *fn, void *arg); + +#endif diff --git a/libesp32/NimBLE-Arduino/src/host/ble_ibeacon.h b/libesp32/NimBLE-Arduino/src/host/ble_ibeacon.h new file mode 100644 index 000000000..fff7c57ae --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/host/ble_ibeacon.h @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_BLE_IBEACON_ +#define H_BLE_IBEACON_ + +#ifdef __cplusplus +extern "C" { +#endif + +int ble_ibeacon_set_adv_data(void *uuid128, uint16_t major, + uint16_t minor, int8_t measured_power); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libesp32/NimBLE-Arduino/src/host/ble_l2cap.h b/libesp32/NimBLE-Arduino/src/host/ble_l2cap.h new file mode 100644 index 000000000..644bd9d0d --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/host/ble_l2cap.h @@ -0,0 +1,223 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_BLE_L2CAP_ +#define H_BLE_L2CAP_ + +#include "nimble/nimble_opt.h" +#ifdef __cplusplus +extern "C" { +#endif + +struct ble_l2cap_sig_update_req; +struct ble_hs_conn; + +#define BLE_L2CAP_CID_ATT 4 +#define BLE_L2CAP_CID_SIG 5 +#define BLE_L2CAP_CID_SM 6 + +#define BLE_L2CAP_SIG_OP_REJECT 0x01 +#define BLE_L2CAP_SIG_OP_CONNECT_REQ 0x02 +#define BLE_L2CAP_SIG_OP_CONNECT_RSP 0x03 +#define BLE_L2CAP_SIG_OP_CONFIG_REQ 0x04 +#define BLE_L2CAP_SIG_OP_CONFIG_RSP 0x05 +#define BLE_L2CAP_SIG_OP_DISCONN_REQ 0x06 +#define BLE_L2CAP_SIG_OP_DISCONN_RSP 0x07 +#define BLE_L2CAP_SIG_OP_ECHO_REQ 0x08 +#define BLE_L2CAP_SIG_OP_ECHO_RSP 0x09 +#define BLE_L2CAP_SIG_OP_INFO_REQ 0x0a +#define BLE_L2CAP_SIG_OP_INFO_RSP 0x0b +#define BLE_L2CAP_SIG_OP_CREATE_CHAN_REQ 0x0c +#define BLE_L2CAP_SIG_OP_CREATE_CHAN_RSP 0x0d +#define BLE_L2CAP_SIG_OP_MOVE_CHAN_REQ 0x0e +#define BLE_L2CAP_SIG_OP_MOVE_CHAN_RSP 0x0f +#define BLE_L2CAP_SIG_OP_MOVE_CHAN_CONF_REQ 0x10 +#define BLE_L2CAP_SIG_OP_MOVE_CHAN_CONF_RSP 0x11 +#define BLE_L2CAP_SIG_OP_UPDATE_REQ 0x12 +#define BLE_L2CAP_SIG_OP_UPDATE_RSP 0x13 +#define BLE_L2CAP_SIG_OP_CREDIT_CONNECT_REQ 0x14 +#define BLE_L2CAP_SIG_OP_CREDIT_CONNECT_RSP 0x15 +#define BLE_L2CAP_SIG_OP_FLOW_CTRL_CREDIT 0x16 +#define BLE_L2CAP_SIG_OP_MAX 0x17 + +#define BLE_L2CAP_SIG_ERR_CMD_NOT_UNDERSTOOD 0x0000 +#define BLE_L2CAP_SIG_ERR_MTU_EXCEEDED 0x0001 +#define BLE_L2CAP_SIG_ERR_INVALID_CID 0x0002 + +#define BLE_L2CAP_COC_ERR_CONNECTION_SUCCESS 0x0000 +#define BLE_L2CAP_COC_ERR_UNKNOWN_LE_PSM 0x0002 +#define BLE_L2CAP_COC_ERR_NO_RESOURCES 0x0004 +#define BLE_L2CAP_COC_ERR_INSUFFICIENT_AUTHEN 0x0005 +#define BLE_L2CAP_COC_ERR_INSUFFICIENT_AUTHOR 0x0006 +#define BLE_L2CAP_COC_ERR_INSUFFICIENT_KEY_SZ 0x0007 +#define BLE_L2CAP_COC_ERR_INSUFFICIENT_ENC 0x0008 +#define BLE_L2CAP_COC_ERR_INVALID_SOURCE_CID 0x0009 +#define BLE_L2CAP_COC_ERR_SOURCE_CID_ALREADY_USED 0x000A +#define BLE_L2CAP_COC_ERR_UNACCEPTABLE_PARAMETERS 0x000B + +#define BLE_L2CAP_EVENT_COC_CONNECTED 0 +#define BLE_L2CAP_EVENT_COC_DISCONNECTED 1 +#define BLE_L2CAP_EVENT_COC_ACCEPT 2 +#define BLE_L2CAP_EVENT_COC_DATA_RECEIVED 3 +#define BLE_L2CAP_EVENT_COC_TX_UNSTALLED 4 + +typedef void ble_l2cap_sig_update_fn(uint16_t conn_handle, int status, + void *arg); + +struct ble_l2cap_sig_update_params { + uint16_t itvl_min; + uint16_t itvl_max; + uint16_t slave_latency; + uint16_t timeout_multiplier; +}; + +int ble_l2cap_sig_update(uint16_t conn_handle, + struct ble_l2cap_sig_update_params *params, + ble_l2cap_sig_update_fn *cb, void *cb_arg); + +struct ble_l2cap_chan; + +/** + * Represents a L2CAP-related event. + * When such an event occurs, the host notifies the application by passing an + * instance of this structure to an application-specified callback. + */ +struct ble_l2cap_event { + /** + * Indicates the type of L2CAP event that occurred. This is one of the + * BLE_L2CAP_EVENT codes. + */ + uint8_t type; + + /** + * A discriminated union containing additional details concerning the L2CAP + * event. The 'type' field indicates which member of the union is valid. + */ + union { + /** + * Represents a connection attempt. Valid for the following event + * types: + * o BLE_L2CAP_EVENT_COC_CONNECTED */ + struct { + /** + * The status of the connection attempt; + * o 0: the connection was successfully established. + * o BLE host error code: the connection attempt failed for + * the specified reason. + */ + int status; + + /** Connection handle of the relevant connection */ + uint16_t conn_handle; + + /** The L2CAP channel of the relevant L2CAP connection. */ + struct ble_l2cap_chan *chan; + } connect; + + /** + * Represents a terminated connection. Valid for the following event + * types: + * o BLE_L2CAP_EVENT_COC_DISCONNECTED + */ + struct { + /** Connection handle of the relevant connection */ + uint16_t conn_handle; + + /** Information about the L2CAP connection prior to termination. */ + struct ble_l2cap_chan *chan; + } disconnect; + + /** + * Represents connection accept. Valid for the following event + * types: + * o BLE_L2CAP_EVENT_COC_ACCEPT + */ + struct { + /** Connection handle of the relevant connection */ + uint16_t conn_handle; + + /** MTU supported by peer device on the channel */ + uint16_t peer_sdu_size; + + /** The L2CAP channel of the relevant L2CAP connection. */ + struct ble_l2cap_chan *chan; + } accept; + + /** + * Represents received data. Valid for the following event + * types: + * o BLE_L2CAP_EVENT_COC_DATA_RECEIVED + */ + struct { + /** Connection handle of the relevant connection */ + uint16_t conn_handle; + + /** The L2CAP channel of the relevant L2CAP connection. */ + struct ble_l2cap_chan *chan; + + /** The mbuf with received SDU. */ + struct os_mbuf *sdu_rx; + } receive; + + /** + * Represents tx_unstalled data. Valid for the following event + * types: + * o BLE_L2CAP_EVENT_COC_TX_UNSTALLED + */ + struct { + /** Connection handle of the relevant connection */ + uint16_t conn_handle; + + /** The L2CAP channel of the relevant L2CAP connection. */ + struct ble_l2cap_chan *chan; + + /** + * The status of the send attempt which was stalled due to + * lack of credits; This can be non zero only if there + * is an issue with memory allocation for following SDU fragments. + * In such a case last SDU has been partially sent to peer device + * and it is up to application to decide how to handle it. + */ + int status; + } tx_unstalled; + }; +}; + +typedef int ble_l2cap_event_fn(struct ble_l2cap_event *event, void *arg); + +uint16_t ble_l2cap_get_conn_handle(struct ble_l2cap_chan *chan); +int ble_l2cap_create_server(uint16_t psm, uint16_t mtu, + ble_l2cap_event_fn *cb, void *cb_arg); + +int ble_l2cap_connect(uint16_t conn_handle, uint16_t psm, uint16_t mtu, + struct os_mbuf *sdu_rx, + ble_l2cap_event_fn *cb, void *cb_arg); +int ble_l2cap_disconnect(struct ble_l2cap_chan *chan); +int ble_l2cap_send(struct ble_l2cap_chan *chan, struct os_mbuf *sdu_tx); +int ble_l2cap_recv_ready(struct ble_l2cap_chan *chan, struct os_mbuf *sdu_rx); +int ble_l2cap_get_scid(struct ble_l2cap_chan *chan); +int ble_l2cap_get_dcid(struct ble_l2cap_chan *chan); +int ble_l2cap_get_our_mtu(struct ble_l2cap_chan *chan); +int ble_l2cap_get_peer_mtu(struct ble_l2cap_chan *chan); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libesp32/NimBLE-Arduino/src/host/ble_monitor.h b/libesp32/NimBLE-Arduino/src/host/ble_monitor.h new file mode 100644 index 000000000..61722f7db --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/host/ble_monitor.h @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_BLE_MONITOR_ +#define H_BLE_MONITOR_ + +#include + +#undef BLE_MONITOR +#define BLE_MONITOR (MYNEWT_VAL(BLE_MONITOR_UART) || MYNEWT_VAL(BLE_MONITOR_RTT)) + +#ifdef __cplusplus +extern "C" { +#endif + +int ble_monitor_log(int level, const char *fmt, ...); + +int ble_monitor_out(int c); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libesp32/NimBLE-Arduino/src/host/ble_sm.h b/libesp32/NimBLE-Arduino/src/host/ble_sm.h new file mode 100644 index 000000000..9bd25adfc --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/host/ble_sm.h @@ -0,0 +1,109 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_BLE_SM_ +#define H_BLE_SM_ + +#include +#include "syscfg/syscfg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define BLE_SM_ERR_PASSKEY 0x01 +#define BLE_SM_ERR_OOB 0x02 +#define BLE_SM_ERR_AUTHREQ 0x03 +#define BLE_SM_ERR_CONFIRM_MISMATCH 0x04 +#define BLE_SM_ERR_PAIR_NOT_SUPP 0x05 +#define BLE_SM_ERR_ENC_KEY_SZ 0x06 +#define BLE_SM_ERR_CMD_NOT_SUPP 0x07 +#define BLE_SM_ERR_UNSPECIFIED 0x08 +#define BLE_SM_ERR_REPEATED 0x09 +#define BLE_SM_ERR_INVAL 0x0a +#define BLE_SM_ERR_DHKEY 0x0b +#define BLE_SM_ERR_NUMCMP 0x0c +#define BLE_SM_ERR_ALREADY 0x0d +#define BLE_SM_ERR_CROSS_TRANS 0x0e +#define BLE_SM_ERR_MAX_PLUS_1 0x0f + +#define BLE_SM_PAIR_ALG_JW 0 +#define BLE_SM_PAIR_ALG_PASSKEY 1 +#define BLE_SM_PAIR_ALG_OOB 2 +#define BLE_SM_PAIR_ALG_NUMCMP 3 + +#define BLE_SM_PAIR_KEY_DIST_ENC 0x01 +#define BLE_SM_PAIR_KEY_DIST_ID 0x02 +#define BLE_SM_PAIR_KEY_DIST_SIGN 0x04 +#define BLE_SM_PAIR_KEY_DIST_LINK 0x08 +#define BLE_SM_PAIR_KEY_DIST_RESERVED 0xf0 + +#define BLE_SM_IO_CAP_DISP_ONLY 0x00 +#define BLE_SM_IO_CAP_DISP_YES_NO 0x01 +#define BLE_SM_IO_CAP_KEYBOARD_ONLY 0x02 +#define BLE_SM_IO_CAP_NO_IO 0x03 +#define BLE_SM_IO_CAP_KEYBOARD_DISP 0x04 +#define BLE_SM_IO_CAP_RESERVED 0x05 + +#define BLE_SM_PAIR_OOB_NO 0x00 +#define BLE_SM_PAIR_OOB_YES 0x01 +#define BLE_SM_PAIR_OOB_RESERVED 0x02 + +#define BLE_SM_PAIR_AUTHREQ_BOND 0x01 +#define BLE_SM_PAIR_AUTHREQ_MITM 0x04 +#define BLE_SM_PAIR_AUTHREQ_SC 0x08 +#define BLE_SM_PAIR_AUTHREQ_KEYPRESS 0x10 +#define BLE_SM_PAIR_AUTHREQ_RESERVED 0xe2 + +#define BLE_SM_PAIR_KEY_SZ_MIN 7 +#define BLE_SM_PAIR_KEY_SZ_MAX 16 + +/* + * The security manager asks the application to perform a key generation + * action. The application passes the passkey back to SM via + * ble_sm_inject_io(). + */ +#define BLE_SM_IOACT_NONE 0 +#define BLE_SM_IOACT_OOB 1 +#define BLE_SM_IOACT_INPUT 2 +#define BLE_SM_IOACT_DISP 3 +#define BLE_SM_IOACT_NUMCMP 4 +#define BLE_SM_IOACT_MAX_PLUS_ONE 5 + +struct ble_sm_io { + uint8_t action; + union { + uint32_t passkey; + uint8_t oob[16]; + uint8_t numcmp_accept; + }; +}; + +#if NIMBLE_BLE_SM +int ble_sm_inject_io(uint16_t conn_handle, struct ble_sm_io *pkey); +#else +#define ble_sm_inject_io(conn_handle, pkey) \ + ((void)(conn_handle), BLE_HS_ENOTSUP) +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libesp32/NimBLE-Arduino/src/host/ble_store.h b/libesp32/NimBLE-Arduino/src/host/ble_store.h new file mode 100644 index 000000000..a3eca5d23 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/host/ble_store.h @@ -0,0 +1,304 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_BLE_STORE_ +#define H_BLE_STORE_ + +#include +#include "nimble/ble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define BLE_STORE_OBJ_TYPE_OUR_SEC 1 +#define BLE_STORE_OBJ_TYPE_PEER_SEC 2 +#define BLE_STORE_OBJ_TYPE_CCCD 3 +#define BLE_STORE_OBJ_TYPE_PEER_DEV_REC 4 + +/** Failed to persist record; insufficient storage capacity. */ +#define BLE_STORE_EVENT_OVERFLOW 1 + +/** About to execute a procedure that may fail due to overflow. */ +#define BLE_STORE_EVENT_FULL 2 + +/** + * Used as a key for lookups of security material. This struct corresponds to + * the following store object types: + * o BLE_STORE_OBJ_TYPE_OUR_SEC + * o BLE_STORE_OBJ_TYPE_PEER_SEC + */ +struct ble_store_key_sec { + /** + * Key by peer identity address; + * peer_addr=BLE_ADDR_NONE means don't key off peer. + */ + ble_addr_t peer_addr; + + /** Key by ediv; ediv_rand_present=0 means don't key off ediv. */ + uint16_t ediv; + + /** Key by rand_num; ediv_rand_present=0 means don't key off rand_num. */ + uint64_t rand_num; + + unsigned ediv_rand_present:1; + + /** Number of results to skip; 0 means retrieve the first match. */ + uint8_t idx; +}; + +/** + * Represents stored security material. This struct corresponds to the + * following store object types: + * o BLE_STORE_OBJ_TYPE_OUR_SEC + * o BLE_STORE_OBJ_TYPE_PEER_SEC + */ +struct ble_store_value_sec { + ble_addr_t peer_addr; + + uint8_t key_size; + uint16_t ediv; + uint64_t rand_num; + uint8_t ltk[16]; + uint8_t ltk_present:1; + + uint8_t irk[16]; + uint8_t irk_present:1; + + uint8_t csrk[16]; + uint8_t csrk_present:1; + + unsigned authenticated:1; + uint8_t sc:1; +}; + +/** + * Used as a key for lookups of stored client characteristic configuration + * descriptors (CCCDs). This struct corresponds to the BLE_STORE_OBJ_TYPE_CCCD + * store object type. + */ +struct ble_store_key_cccd { + /** + * Key by peer identity address; + * peer_addr=BLE_ADDR_NONE means don't key off peer. + */ + ble_addr_t peer_addr; + + /** + * Key by characteristic value handle; + * chr_val_handle=0 means don't key off characteristic handle. + */ + uint16_t chr_val_handle; + + /** Number of results to skip; 0 means retrieve the first match. */ + uint8_t idx; +}; + +/** + * Represents a stored client characteristic configuration descriptor (CCCD). + * This struct corresponds to the BLE_STORE_OBJ_TYPE_CCCD store object type. + */ +struct ble_store_value_cccd { + ble_addr_t peer_addr; + uint16_t chr_val_handle; + uint16_t flags; + unsigned value_changed:1; +}; + +/** + * Used as a key for store lookups. This union must be accompanied by an + * object type code to indicate which field is valid. + */ +union ble_store_key { + struct ble_store_key_sec sec; + struct ble_store_key_cccd cccd; +}; + +/** + * Represents stored data. This union must be accompanied by an object type + * code to indicate which field is valid. + */ +union ble_store_value { + struct ble_store_value_sec sec; + struct ble_store_value_cccd cccd; +}; + +struct ble_store_status_event { + /** + * The type of event being reported; one of the BLE_STORE_EVENT_TYPE_[...] + * codes. + */ + int event_code; + + /** + * Additional data related to the event; the valid field is inferred from + * the obj_type,event_code pair. + */ + union { + /** + * Represents a write that failed due to storage exhaustion. Valid for + * the following event types: + * o BLE_STORE_EVENT_OVERFLOW + */ + struct { + /** The type of object that failed to be written. */ + int obj_type; + + /** The object that failed to be written. */ + const union ble_store_value *value; + } overflow; + + /** + * Represents the possibility that a scheduled write will fail due to + * storage exhaustion. Valid for the following event types: + * o BLE_STORE_EVENT_FULL + */ + struct { + /** The type of object that may fail to be written. */ + int obj_type; + + /** The handle of the connection which prompted the write. */ + uint16_t conn_handle; + } full; + }; +}; + +/** + * Searches the store for an object matching the specified criteria. If a + * match is found, it is read from the store and the dst parameter is populated + * with the retrieved object. + * + * @param obj_type The type of object to search for; one of the + * BLE_STORE_OBJ_TYPE_[...] codes. + * @param key Specifies properties of the object to search + * for. An object is retrieved if it matches + * these criteria. + * @param dst On success, this is populated with the + * retrieved object. + * + * @return 0 if an object was successfully retreived; + * BLE_HS_ENOENT if no matching object was found; + * Other nonzero on error. + */ +typedef int ble_store_read_fn(int obj_type, const union ble_store_key *key, + union ble_store_value *dst); + +/** + * Writes the specified object to the store. If an object with the same + * identity is already in the store, it is replaced. If the store lacks + * sufficient capacity to write the object, this function may remove previously + * stored values to make room. + * + * @param obj_type The type of object being written; one of the + * BLE_STORE_OBJ_TYPE_[...] codes. + * @param val The object to persist. + * + * @return 0 if the object was successfully written; + * Other nonzero on error. + */ +typedef int ble_store_write_fn(int obj_type, const union ble_store_value *val); + +/** + * Searches the store for the first object matching the specified criteria. If + * a match is found, it is deleted from the store. + * + * @param obj_type The type of object to delete; one of the + * BLE_STORE_OBJ_TYPE_[...] codes. + * @param key Specifies properties of the object to search + * for. An object is deleted if it matches + * these criteria. + * @return 0 if an object was successfully retrieved; + * BLE_HS_ENOENT if no matching object was found; + * Other nonzero on error. + */ +typedef int ble_store_delete_fn(int obj_type, const union ble_store_key *key); + +/** + * Indicates an inability to perform a store operation. This callback should + * do one of two things: + * o Address the problem and return 0, indicating that the store operation + * should proceed. + * o Return nonzero to indicate that the store operation should be aborted. + * + * @param event Describes the store event being reported. + * @param arg Optional user argument. + * + * @return 0 if the store operation should proceed; + * nonzero if the store operation should be + * aborted. + */ +typedef int ble_store_status_fn(struct ble_store_status_event *event, + void *arg); + +int ble_store_read(int obj_type, const union ble_store_key *key, + union ble_store_value *val); +int ble_store_write(int obj_type, const union ble_store_value *val); +int ble_store_delete(int obj_type, const union ble_store_key *key); +int ble_store_overflow_event(int obj_type, const union ble_store_value *value); +int ble_store_full_event(int obj_type, uint16_t conn_handle); + +int ble_store_read_our_sec(const struct ble_store_key_sec *key_sec, + struct ble_store_value_sec *value_sec); +int ble_store_write_our_sec(const struct ble_store_value_sec *value_sec); +int ble_store_delete_our_sec(const struct ble_store_key_sec *key_sec); +int ble_store_read_peer_sec(const struct ble_store_key_sec *key_sec, + struct ble_store_value_sec *value_sec); +int ble_store_write_peer_sec(const struct ble_store_value_sec *value_sec); +int ble_store_delete_peer_sec(const struct ble_store_key_sec *key_sec); + +int ble_store_read_cccd(const struct ble_store_key_cccd *key, + struct ble_store_value_cccd *out_value); +int ble_store_write_cccd(const struct ble_store_value_cccd *value); +int ble_store_delete_cccd(const struct ble_store_key_cccd *key); + +void ble_store_key_from_value_sec(struct ble_store_key_sec *out_key, + const struct ble_store_value_sec *value); +void ble_store_key_from_value_cccd(struct ble_store_key_cccd *out_key, + const struct ble_store_value_cccd *value); + +void ble_store_key_from_value(int obj_type, + union ble_store_key *out_key, + const union ble_store_value *value); + +typedef int ble_store_iterator_fn(int obj_type, + union ble_store_value *val, + void *cookie); + +int ble_store_iterate(int obj_type, + ble_store_iterator_fn *callback, + void *cookie); + +int ble_store_clear(void); + +/*** Utility functions. */ + +int ble_store_util_bonded_peers(ble_addr_t *out_peer_id_addrs, + int *out_num_peers, + int max_peers); +int ble_store_util_delete_all(int type, const union ble_store_key *key); +int ble_store_util_delete_peer(const ble_addr_t *peer_id_addr); +int ble_store_util_delete_oldest_peer(void); +int ble_store_util_count(int type, int *out_count); +int ble_store_util_status_rr(struct ble_store_status_event *event, void *arg); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libesp32/NimBLE-Arduino/src/host/ble_uuid.h b/libesp32/NimBLE-Arduino/src/host/ble_uuid.h new file mode 100644 index 000000000..d3576c595 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/host/ble_uuid.h @@ -0,0 +1,182 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_BLE_UUID_ +#define H_BLE_UUID_ + +/** + * @brief Bluetooth UUID + * @defgroup bt_uuid Bluetooth UUID + * @ingroup bt_host + * @{ + */ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct os_mbuf; + +/** Type of UUID */ +enum { + /** 16-bit UUID (BT SIG assigned) */ + BLE_UUID_TYPE_16 = 16, + + /** 32-bit UUID (BT SIG assigned) */ + BLE_UUID_TYPE_32 = 32, + + /** 128-bit UUID */ + BLE_UUID_TYPE_128 = 128, +}; + +/** Generic UUID type, to be used only as a pointer */ +typedef struct { + /** Type of the UUID */ + uint8_t type; +} ble_uuid_t; + +/** 16-bit UUID */ +typedef struct { + ble_uuid_t u; + uint16_t value; +} ble_uuid16_t; + +/** 32-bit UUID */ +typedef struct { + ble_uuid_t u; + uint32_t value; +} ble_uuid32_t; + +/** 128-bit UUID */ +typedef struct { + ble_uuid_t u; + uint8_t value[16]; +} ble_uuid128_t; + +/** Universal UUID type, to be used for any-UUID static allocation */ +typedef union { + ble_uuid_t u; + ble_uuid16_t u16; + ble_uuid32_t u32; + ble_uuid128_t u128; +} ble_uuid_any_t; + +#define BLE_UUID16_INIT(uuid16) \ + { \ + .u.type = BLE_UUID_TYPE_16, \ + .value = (uuid16), \ + } + +#define BLE_UUID32_INIT(uuid32) \ + { \ + .u.type = BLE_UUID_TYPE_32, \ + .value = (uuid32), \ + } + +#define BLE_UUID128_INIT(uuid128...) \ + { \ + .u.type = BLE_UUID_TYPE_128, \ + .value = { uuid128 }, \ + } + +#define BLE_UUID16_DECLARE(uuid16) \ + ((ble_uuid_t *) (&(ble_uuid16_t) BLE_UUID16_INIT(uuid16))) + +#define BLE_UUID32_DECLARE(uuid32) \ + ((ble_uuid_t *) (&(ble_uuid32_t) BLE_UUID32_INIT(uuid32))) + +#define BLE_UUID128_DECLARE(uuid128...) \ + ((ble_uuid_t *) (&(ble_uuid128_t) BLE_UUID128_INIT(uuid128))) + +#define BLE_UUID16(u) \ + ((ble_uuid16_t *) (u)) + +#define BLE_UUID32(u) \ + ((ble_uuid32_t *) (u)) + +#define BLE_UUID128(u) \ + ((ble_uuid128_t *) (u)) + +/** Size of buffer needed to store UUID as a string. + * Includes trailing \0. + */ +#define BLE_UUID_STR_LEN (37) + +/** @brief Constructs a UUID object from a byte array. + * + * @param uuid On success, this gets populated with the constructed UUID. + * @param buf The source buffer to parse. + * @param len The size of the buffer, in bytes. + * + * @return 0 on success, BLE_HS_EINVAL if the source buffer does not contain + * a valid UUID. + */ +int ble_uuid_init_from_buf(ble_uuid_any_t *uuid, const void *buf, size_t len); + +/** @brief Compares two Bluetooth UUIDs. + * + * @param uuid1 The first UUID to compare. + * @param uuid2 The second UUID to compare. + * + * @return 0 if the two UUIDs are equal, nonzero if the UUIDs differ. + */ +int ble_uuid_cmp(const ble_uuid_t *uuid1, const ble_uuid_t *uuid2); + +/** @brief Copy Bluetooth UUID + * + * @param dst Destination UUID. + * @param src Source UUID. + */ +void ble_uuid_copy(ble_uuid_any_t *dst, const ble_uuid_t *src); + +/** @brief Converts the specified UUID to its string representation. + * + * Example string representations: + * o 16-bit: 0x1234 + * o 32-bit: 0x12345678 + * o 128-bit: 12345678-1234-1234-1234-123456789abc + * + * @param uuid The source UUID to convert. + * @param dst The destination buffer. + * + * @return A pointer to the supplied destination buffer. + */ +char *ble_uuid_to_str(const ble_uuid_t *uuid, char *dst); + +/** @brief Converts the specified 16-bit UUID to a uint16_t. + * + * @param uuid The source UUID to convert. + * + * @return The converted integer on success, NULL if the specified UUID is + * not 16 bits. + */ +uint16_t ble_uuid_u16(const ble_uuid_t *uuid); + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* _BLE_HOST_UUID_H */ diff --git a/libesp32/NimBLE-Arduino/src/host/util/util.h b/libesp32/NimBLE-Arduino/src/host/util/util.h new file mode 100644 index 000000000..3f07c005a --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/host/util/util.h @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_HOST_UTIL_ +#define H_HOST_UTIL_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Tries to configure the device with at least one Bluetooth address. + * Addresses are restored in a hardware-specific fashion. + * + * @param prefer_random Whether to attempt to restore a random address + * before checking if a public address has + * already been configured. + * + * @return 0 on success; + * BLE_HS_ENOADDR if the device does not have any + * available addresses. + * Other BLE host core code on error. + */ +int ble_hs_util_ensure_addr(int prefer_random); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libesp32/NimBLE-Arduino/src/log/log.h b/libesp32/NimBLE-Arduino/src/log/log.h new file mode 100644 index 000000000..e5a05fc2c --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/log/log.h @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef __LOG_H__ +#define __LOG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +struct log { +}; + +#ifdef __cplusplus +} +#endif + +#endif /* __LOG_H__ */ diff --git a/libesp32/NimBLE-Arduino/src/mem/mem.h b/libesp32/NimBLE-Arduino/src/mem/mem.h new file mode 100644 index 000000000..13a325b5a --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/mem/mem.h @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_UTIL_MEM_ +#define H_UTIL_MEM_ + +#ifdef __cplusplus +extern "C" { +#endif + +struct os_mempool; +struct os_mbuf_pool; + +int mem_malloc_mempool(struct os_mempool *mempool, uint16_t num_blocks, + uint32_t block_size, char *name, void **out_buf); +int mem_malloc_mempool_ext(struct os_mempool_ext *mempool, uint16_t num_blocks, + uint32_t block_size, char *name, void **out_buf); + +int mem_malloc_mbuf_pool(struct os_mempool *mempool, + struct os_mbuf_pool *mbuf_pool, uint16_t num_blocks, + uint32_t block_size, char *name, + void **out_buf); +int mem_malloc_mbufpkt_pool(struct os_mempool *mempool, + struct os_mbuf_pool *mbuf_pool, int num_blocks, + int block_size, char *name, + void **out_buf); +int mem_init_mbuf_pool(void *mem, struct os_mempool *mempool, + struct os_mbuf_pool *mbuf_pool, int num_blocks, + int block_size, const char *name); + +/** + * Specifies a function used as a callback. Functions of this type allocate an + * mbuf chain meant to hold a packet fragment. The resulting mbuf must contain + * a pkthdr. + * + * @param frag_size The number of data bytes that the mbuf will + * eventually contain. + * @param arg A generic parameter. + * + * @return An allocated mbuf chain on success; + * NULL on failure. + */ +typedef struct os_mbuf *mem_frag_alloc_fn(uint16_t frag_size, void *arg); + +struct os_mbuf *mem_split_frag(struct os_mbuf **om, uint16_t max_frag_sz, + mem_frag_alloc_fn *alloc_cb, void *cb_arg); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libesp32/NimBLE-Arduino/src/mesh/access.h b/libesp32/NimBLE-Arduino/src/mesh/access.h new file mode 100644 index 000000000..71ca34e2d --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/mesh/access.h @@ -0,0 +1,423 @@ +/** @file + * @brief Bluetooth Mesh Access Layer APIs. + */ + +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef __BT_MESH_ACCESS_H +#define __BT_MESH_ACCESS_H + +/** + * @brief Bluetooth Mesh Access Layer + * @defgroup bt_mesh_access Bluetooth Mesh Access Layer + * @ingroup bt_mesh + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#define BT_MESH_ADDR_UNASSIGNED 0x0000 +#define BT_MESH_ADDR_ALL_NODES 0xffff +#define BT_MESH_ADDR_PROXIES 0xfffc +#define BT_MESH_ADDR_FRIENDS 0xfffd +#define BT_MESH_ADDR_RELAYS 0xfffe + +#define BT_MESH_KEY_UNUSED 0xffff +#define BT_MESH_KEY_DEV 0xfffe + +/** Helper to define a mesh element within an array. + * + * In case the element has no SIG or Vendor models the helper + * macro BT_MESH_MODEL_NONE can be given instead. + * + * @param _loc Location Descriptor. + * @param _mods Array of models. + * @param _vnd_mods Array of vendor models. + */ +#define BT_MESH_ELEM(_loc, _mods, _vnd_mods) \ +{ \ + .loc = (_loc), \ + .model_count = ARRAY_SIZE(_mods), \ + .models = (_mods), \ + .vnd_model_count = ARRAY_SIZE(_vnd_mods), \ + .vnd_models = (_vnd_mods), \ +} + +/** Abstraction that describes a Mesh Element */ +struct bt_mesh_elem { + /* Unicast Address. Set at runtime during provisioning. */ + u16_t addr; + + /* Location Descriptor (GATT Bluetooth Namespace Descriptors) */ + const u16_t loc; + + const u8_t model_count; + const u8_t vnd_model_count; + + struct bt_mesh_model * const models; + struct bt_mesh_model * const vnd_models; +}; + +/* Foundation Models */ +#define BT_MESH_MODEL_ID_CFG_SRV 0x0000 +#define BT_MESH_MODEL_ID_CFG_CLI 0x0001 +#define BT_MESH_MODEL_ID_HEALTH_SRV 0x0002 +#define BT_MESH_MODEL_ID_HEALTH_CLI 0x0003 + +/* Models from the Mesh Model Specification */ +#define BT_MESH_MODEL_ID_GEN_ONOFF_SRV 0x1000 +#define BT_MESH_MODEL_ID_GEN_ONOFF_CLI 0x1001 +#define BT_MESH_MODEL_ID_GEN_LEVEL_SRV 0x1002 +#define BT_MESH_MODEL_ID_GEN_LEVEL_CLI 0x1003 +#define BT_MESH_MODEL_ID_GEN_DEF_TRANS_TIME_SRV 0x1004 +#define BT_MESH_MODEL_ID_GEN_DEF_TRANS_TIME_CLI 0x1005 +#define BT_MESH_MODEL_ID_GEN_POWER_ONOFF_SRV 0x1006 +#define BT_MESH_MODEL_ID_GEN_POWER_ONOFF_SETUP_SRV 0x1007 +#define BT_MESH_MODEL_ID_GEN_POWER_ONOFF_CLI 0x1008 +#define BT_MESH_MODEL_ID_GEN_POWER_LEVEL_SRV 0x1009 +#define BT_MESH_MODEL_ID_GEN_POWER_LEVEL_SETUP_SRV 0x100a +#define BT_MESH_MODEL_ID_GEN_POWER_LEVEL_CLI 0x100b +#define BT_MESH_MODEL_ID_GEN_BATTERY_SRV 0x100c +#define BT_MESH_MODEL_ID_GEN_BATTERY_CLI 0x100d +#define BT_MESH_MODEL_ID_GEN_LOCATION_SRV 0x100e +#define BT_MESH_MODEL_ID_GEN_LOCATION_SETUPSRV 0x100f +#define BT_MESH_MODEL_ID_GEN_LOCATION_CLI 0x1010 +#define BT_MESH_MODEL_ID_GEN_ADMIN_PROP_SRV 0x1011 +#define BT_MESH_MODEL_ID_GEN_MANUFACTURER_PROP_SRV 0x1012 +#define BT_MESH_MODEL_ID_GEN_USER_PROP_SRV 0x1013 +#define BT_MESH_MODEL_ID_GEN_CLIENT_PROP_SRV 0x1014 +#define BT_MESH_MODEL_ID_GEN_PROP_CLI 0x1015 +#define BT_MESH_MODEL_ID_SENSOR_SRV 0x1100 +#define BT_MESH_MODEL_ID_SENSOR_SETUP_SRV 0x1101 +#define BT_MESH_MODEL_ID_SENSOR_CLI 0x1102 +#define BT_MESH_MODEL_ID_TIME_SRV 0x1200 +#define BT_MESH_MODEL_ID_TIME_SETUP_SRV 0x1201 +#define BT_MESH_MODEL_ID_TIME_CLI 0x1202 +#define BT_MESH_MODEL_ID_SCENE_SRV 0x1203 +#define BT_MESH_MODEL_ID_SCENE_SETUP_SRV 0x1204 +#define BT_MESH_MODEL_ID_SCENE_CLI 0x1205 +#define BT_MESH_MODEL_ID_SCHEDULER_SRV 0x1206 +#define BT_MESH_MODEL_ID_SCHEDULER_SETUP_SRV 0x1207 +#define BT_MESH_MODEL_ID_SCHEDULER_CLI 0x1208 +#define BT_MESH_MODEL_ID_LIGHT_LIGHTNESS_SRV 0x1300 +#define BT_MESH_MODEL_ID_LIGHT_LIGHTNESS_SETUP_SRV 0x1301 +#define BT_MESH_MODEL_ID_LIGHT_LIGHTNESS_CLI 0x1302 +#define BT_MESH_MODEL_ID_LIGHT_CTL_SRV 0x1303 +#define BT_MESH_MODEL_ID_LIGHT_CTL_SETUP_SRV 0x1304 +#define BT_MESH_MODEL_ID_LIGHT_CTL_CLI 0x1305 +#define BT_MESH_MODEL_ID_LIGHT_CTL_TEMP_SRV 0x1306 +#define BT_MESH_MODEL_ID_LIGHT_HSL_SRV 0x1307 +#define BT_MESH_MODEL_ID_LIGHT_HSL_SETUP_SRV 0x1308 +#define BT_MESH_MODEL_ID_LIGHT_HSL_CLI 0x1309 +#define BT_MESH_MODEL_ID_LIGHT_HSL_HUE_SRV 0x130a +#define BT_MESH_MODEL_ID_LIGHT_HSL_SAT_SRV 0x130b +#define BT_MESH_MODEL_ID_LIGHT_XYL_SRV 0x130c +#define BT_MESH_MODEL_ID_LIGHT_XYL_SETUP_SRV 0x130d +#define BT_MESH_MODEL_ID_LIGHT_XYL_CLI 0x130e +#define BT_MESH_MODEL_ID_LIGHT_LC_SRV 0x130f +#define BT_MESH_MODEL_ID_LIGHT_LC_SETUPSRV 0x1310 +#define BT_MESH_MODEL_ID_LIGHT_LC_CLI 0x1311 + +/** Message sending context. */ +struct bt_mesh_msg_ctx { + /** NetKey Index of the subnet to send the message on. */ + u16_t net_idx; + + /** AppKey Index to encrypt the message with. */ + u16_t app_idx; + + /** Remote address. */ + u16_t addr; + + /** Destination address of a received message. Not used for sending. */ + u16_t recv_dst; + + /** Received TTL value. Not used for sending. */ + u8_t recv_ttl:7; + + /** Force sending reliably by using segment acknowledgement */ + u8_t send_rel:1; + + /** TTL, or BT_MESH_TTL_DEFAULT for default TTL. */ + u8_t send_ttl; +}; + +struct bt_mesh_model_op { + /* OpCode encoded using the BT_MESH_MODEL_OP_* macros */ + const u32_t opcode; + + /* Minimum required message length */ + const size_t min_len; + + /* Message handler for the opcode */ + void (*const func)(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf); +}; + +#define BT_MESH_MODEL_OP_1(b0) (b0) +#define BT_MESH_MODEL_OP_2(b0, b1) (((b0) << 8) | (b1)) +#define BT_MESH_MODEL_OP_3(b0, cid) ((((b0) << 16) | 0xc00000) | (cid)) + +#define BT_MESH_MODEL_OP_END { 0, 0, NULL } +#define BT_MESH_MODEL_NO_OPS ((struct bt_mesh_model_op []) \ + { BT_MESH_MODEL_OP_END }) + +/** Helper to define an empty model array */ +#define BT_MESH_MODEL_NONE ((struct bt_mesh_model []){}) + +#define BT_MESH_MODEL(_id, _op, _pub, _user_data) \ +{ \ + .id = (_id), \ + .op = _op, \ + .keys = { [0 ... (CONFIG_BT_MESH_MODEL_KEY_COUNT - 1)] = \ + BT_MESH_KEY_UNUSED }, \ + .pub = _pub, \ + .groups = { [0 ... (CONFIG_BT_MESH_MODEL_GROUP_COUNT - 1)] = \ + BT_MESH_ADDR_UNASSIGNED }, \ + .user_data = _user_data, \ +} + +#define BT_MESH_MODEL_VND(_company, _id, _op, _pub, _user_data) \ +{ \ + .vnd.company = (_company), \ + .vnd.id = (_id), \ + .op = _op, \ + .pub = _pub, \ + .keys = { [0 ... (CONFIG_BT_MESH_MODEL_KEY_COUNT - 1)] = \ + BT_MESH_KEY_UNUSED }, \ + .groups = { [0 ... (CONFIG_BT_MESH_MODEL_GROUP_COUNT - 1)] = \ + BT_MESH_ADDR_UNASSIGNED }, \ + .user_data = _user_data, \ +} + +/** @def BT_MESH_TRANSMIT + * + * @brief Encode transmission count & interval steps. + * + * @param count Number of retransmissions (first transmission is excluded). + * @param int_ms Interval steps in milliseconds. Must be greater than 0, + * less than or equal to 320, and a multiple of 10. + * + * @return Mesh transmit value that can be used e.g. for the default + * values of the configuration model data. + */ +#define BT_MESH_TRANSMIT(count, int_ms) ((count) | (((int_ms / 10) - 1) << 3)) + +/** @def BT_MESH_TRANSMIT_COUNT + * + * @brief Decode transmit count from a transmit value. + * + * @param transmit Encoded transmit count & interval value. + * + * @return Transmission count (actual transmissions is N + 1). + */ +#define BT_MESH_TRANSMIT_COUNT(transmit) (((transmit) & (u8_t)BIT_MASK(3))) + +/** @def BT_MESH_TRANSMIT_INT + * + * @brief Decode transmit interval from a transmit value. + * + * @param transmit Encoded transmit count & interval value. + * + * @return Transmission interval in milliseconds. + */ +#define BT_MESH_TRANSMIT_INT(transmit) ((((transmit) >> 3) + 1) * 10) + +/** @def BT_MESH_PUB_TRANSMIT + * + * @brief Encode Publish Retransmit count & interval steps. + * + * @param count Number of retransmissions (first transmission is excluded). + * @param int_ms Interval steps in milliseconds. Must be greater than 0 + * and a multiple of 50. + * + * @return Mesh transmit value that can be used e.g. for the default + * values of the configuration model data. + */ +#define BT_MESH_PUB_TRANSMIT(count, int_ms) BT_MESH_TRANSMIT(count, \ + (int_ms) / 5) + +/** @def BT_MESH_PUB_TRANSMIT_COUNT + * + * @brief Decode Pubhlish Retransmit count from a given value. + * + * @param transmit Encoded Publish Retransmit count & interval value. + * + * @return Retransmission count (actual transmissions is N + 1). + */ +#define BT_MESH_PUB_TRANSMIT_COUNT(transmit) BT_MESH_TRANSMIT_COUNT(transmit) + +/** @def BT_MESH_PUB_TRANSMIT_INT + * + * @brief Decode Publish Retransmit interval from a given value. + * + * @param transmit Encoded Publish Retransmit count & interval value. + * + * @return Transmission interval in milliseconds. + */ +#define BT_MESH_PUB_TRANSMIT_INT(transmit) ((((transmit) >> 3) + 1) * 50) + +/** Model publication context. */ +struct bt_mesh_model_pub { + /** The model the context belongs to. Initialized by the stack. */ + struct bt_mesh_model *mod; + + u16_t addr; /**< Publish Address. */ + u16_t key; /**< Publish AppKey Index. */ + + u8_t ttl; /**< Publish Time to Live. */ + u8_t retransmit; /**< Retransmit Count & Interval Steps. */ + u8_t period; /**< Publish Period. */ + u8_t period_div:4, /**< Divisor for the Period. */ + cred:1, /**< Friendship Credentials Flag. */ + count:3; /**< Retransmissions left. */ + + u32_t period_start; /**< Start of the current period. */ + + /** @brief Publication buffer, containing the publication message. + * + * The application is expected to initialize this with + * a valid net_buf_simple pointer, with the help of e.g. + * the NET_BUF_SIMPLE() macro. The publication buffer must + * contain a valid publication message before calling the + * bt_mesh_model_publish() API or after the publication's + * @ref bt_mesh_model_pub.update callback has been called + * and returned success. The buffer must be created outside + * of function context, i.e. it must not be on the stack. + * This is most conveniently acheived by creating it inline + * when declaring the publication context: + * + * static struct bt_mesh_model_pub my_pub = { + * .msg = NET_BUF_SIMPLE(size), + * }; + */ + struct os_mbuf *msg; + + /** @brief Callback for updating the publication buffer. + * + * When set to NULL, the model is assumed not to support + * periodic publishing. When set to non-NULL the callback + * will be called periodically and is expected to update + * @ref bt_mesh_model_pub.msg with a valid publication + * message. + * + * @param mod The Model the Publication Context belogs to. + * + * @return Zero on success or (negative) error code otherwise. + */ + int (*update)(struct bt_mesh_model *mod); + + /** Publish Period Timer. Only for stack-internal use. */ + struct k_delayed_work timer; +}; + +/** Abstraction that describes a Mesh Model instance */ +struct bt_mesh_model { + union { + const u16_t id; + struct { + u16_t company; + u16_t id; + } vnd; + }; + + /* Internal information, mainly for persistent storage */ + u8_t elem_idx; /* Belongs to Nth element */ + u8_t mod_idx; /* Is the Nth model in the element */ + u16_t flags; /* Information about what has changed */ + + /* Model Publication */ + struct bt_mesh_model_pub * const pub; + + /* AppKey List */ + u16_t keys[CONFIG_BT_MESH_MODEL_KEY_COUNT]; + + /* Subscription List (group or virtual addresses) */ + u16_t groups[CONFIG_BT_MESH_MODEL_GROUP_COUNT]; + + const struct bt_mesh_model_op * const op; + + /* Model-specific user data */ + void *user_data; +}; + +struct bt_mesh_send_cb { + void (*start)(u16_t duration, int err, void *cb_data); + void (*end)(int err, void *cb_data); +}; + +void bt_mesh_model_msg_init(struct os_mbuf *msg, u32_t opcode); + +/** Special TTL value to request using configured default TTL */ +#define BT_MESH_TTL_DEFAULT 0xff + +/** Maximum allowed TTL value */ +#define BT_MESH_TTL_MAX 0x7f + +/** + * @brief Send an Access Layer message. + * + * @param model Mesh (client) Model that the message belongs to. + * @param ctx Message context, includes keys, TTL, etc. + * @param msg Access Layer payload (the actual message to be sent). + * @param cb Optional "message sent" callback. + * @param cb_data User data to be passed to the callback. + * + * @return 0 on success, or (negative) error code on failure. + */ +int bt_mesh_model_send(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *msg, + const struct bt_mesh_send_cb *cb, + void *cb_data); + +/** + * @brief Send a model publication message. + * + * Before calling this function, the user needs to ensure that the model + * publication message (@ref bt_mesh_model_pub.msg) contains a valid + * message to be sent. Note that this API is only to be used for + * non-period publishing. For periodic publishing the app only needs + * to make sure that @ref bt_mesh_model_pub.msg contains a valid message + * whenever the @ref bt_mesh_model_pub.update callback is called. + * + * @param model Mesh (client) Model that's publishing the message. + * + * @return 0 on success, or (negative) error code on failure. + */ +int bt_mesh_model_publish(struct bt_mesh_model *model); + +/** + * @brief Get the element that a model belongs to. + * + * @param mod Mesh model. + * + * @return Pointer to the element that the given model belongs to. + */ +struct bt_mesh_elem *bt_mesh_model_elem(struct bt_mesh_model *mod); + +/** Node Composition */ +struct bt_mesh_comp { + u16_t cid; + u16_t pid; + u16_t vid; + + size_t elem_count; + struct bt_mesh_elem *elem; +}; + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* __BT_MESH_ACCESS_H */ diff --git a/libesp32/NimBLE-Arduino/src/mesh/cfg_cli.h b/libesp32/NimBLE-Arduino/src/mesh/cfg_cli.h new file mode 100644 index 000000000..9d80ccda7 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/mesh/cfg_cli.h @@ -0,0 +1,233 @@ +/** @file + * @brief Bluetooth Mesh Configuration Client Model APIs. + */ + +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef __BT_MESH_CFG_CLI_H +#define __BT_MESH_CFG_CLI_H + +/** + * @brief Bluetooth Mesh + * @defgroup bt_mesh_cfg_cli Bluetooth Mesh Configuration Client Model + * @ingroup bt_mesh + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** Mesh Configuration Client Model Context */ +struct bt_mesh_cfg_cli { + struct bt_mesh_model *model; + + struct k_sem op_sync; + u32_t op_pending; + void *op_param; +}; + +extern const struct bt_mesh_model_op bt_mesh_cfg_cli_op[]; + +#define BT_MESH_MODEL_CFG_CLI(cli_data) \ + BT_MESH_MODEL(BT_MESH_MODEL_ID_CFG_CLI, \ + bt_mesh_cfg_cli_op, NULL, cli_data) + +int bt_mesh_cfg_comp_data_get(u16_t net_idx, u16_t addr, u8_t page, + u8_t *status, struct os_mbuf *comp); + +int bt_mesh_cfg_beacon_get(u16_t net_idx, u16_t addr, u8_t *status); + +int bt_mesh_cfg_beacon_set(u16_t net_idx, u16_t addr, u8_t val, u8_t *status); + +int bt_mesh_cfg_ttl_get(u16_t net_idx, u16_t addr, u8_t *ttl); + +int bt_mesh_cfg_ttl_set(u16_t net_idx, u16_t addr, u8_t val, u8_t *ttl); + +int bt_mesh_cfg_friend_get(u16_t net_idx, u16_t addr, u8_t *status); + +int bt_mesh_cfg_friend_set(u16_t net_idx, u16_t addr, u8_t val, u8_t *status); + +int bt_mesh_cfg_gatt_proxy_get(u16_t net_idx, u16_t addr, u8_t *status); + +int bt_mesh_cfg_gatt_proxy_set(u16_t net_idx, u16_t addr, u8_t val, + u8_t *status); + +int bt_mesh_cfg_relay_get(u16_t net_idx, u16_t addr, u8_t *status, + u8_t *transmit); + +int bt_mesh_cfg_relay_set(u16_t net_idx, u16_t addr, u8_t new_relay, + u8_t new_transmit, u8_t *status, u8_t *transmit); + +int bt_mesh_cfg_net_key_add(u16_t net_idx, u16_t addr, u16_t key_net_idx, + const u8_t net_key[16], u8_t *status); + +int bt_mesh_cfg_app_key_add(u16_t net_idx, u16_t addr, u16_t key_net_idx, + u16_t key_app_idx, const u8_t app_key[16], + u8_t *status); + +int bt_mesh_cfg_mod_app_bind(u16_t net_idx, u16_t addr, u16_t elem_addr, + u16_t mod_app_idx, u16_t mod_id, u8_t *status); + +int bt_mesh_cfg_mod_app_bind_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr, + u16_t mod_app_idx, u16_t mod_id, u16_t cid, + u8_t *status); + +/** @def BT_MESH_PUB_PERIOD_100MS + * + * @brief Helper macro to encode model publication period in units of 100ms + * + * @param steps Number of 100ms steps. + * + * @return Encoded value that can be assigned to bt_mesh_cfg_mod_pub.period + */ +#define BT_MESH_PUB_PERIOD_100MS(steps) ((steps) & BIT_MASK(6)) + +/** @def BT_MESH_PUB_PERIOD_SEC + * + * @brief Helper macro to encode model publication period in units of 1 second + * + * @param steps Number of 1 second steps. + * + * @return Encoded value that can be assigned to bt_mesh_cfg_mod_pub.period + */ +#define BT_MESH_PUB_PERIOD_SEC(steps) (((steps) & BIT_MASK(6)) | (1 << 6)) + +/** @def BT_MESH_PUB_PERIOD_10SEC + * + * @brief Helper macro to encode model publication period in units of 10 + * seconds + * + * @param steps Number of 10 second steps. + * + * @return Encoded value that can be assigned to bt_mesh_cfg_mod_pub.period + */ +#define BT_MESH_PUB_PERIOD_10SEC(steps) (((steps) & BIT_MASK(6)) | (2 << 6)) + +/** @def BT_MESH_PUB_PERIOD_10MIN + * + * @brief Helper macro to encode model publication period in units of 10 + * minutes + * + * @param steps Number of 10 minute steps. + * + * @return Encoded value that can be assigned to bt_mesh_cfg_mod_pub.period + */ +#define BT_MESH_PUB_PERIOD_10MIN(steps) (((steps) & BIT_MASK(6)) | (3 << 6)) + +struct bt_mesh_cfg_mod_pub { + u16_t addr; + u16_t app_idx; + bool cred_flag; + u8_t ttl; + u8_t period; + u8_t transmit; +}; + +int bt_mesh_cfg_mod_pub_get(u16_t net_idx, u16_t addr, u16_t elem_addr, + u16_t mod_id, struct bt_mesh_cfg_mod_pub *pub, + u8_t *status); + +int bt_mesh_cfg_mod_pub_get_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr, + u16_t mod_id, u16_t cid, + struct bt_mesh_cfg_mod_pub *pub, u8_t *status); + +int bt_mesh_cfg_mod_pub_set(u16_t net_idx, u16_t addr, u16_t elem_addr, + u16_t mod_id, struct bt_mesh_cfg_mod_pub *pub, + u8_t *status); + +int bt_mesh_cfg_mod_pub_set_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr, + u16_t mod_id, u16_t cid, + struct bt_mesh_cfg_mod_pub *pub, u8_t *status); + +int bt_mesh_cfg_mod_sub_add(u16_t net_idx, u16_t addr, u16_t elem_addr, + u16_t sub_addr, u16_t mod_id, u8_t *status); + +int bt_mesh_cfg_mod_sub_add_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr, + u16_t sub_addr, u16_t mod_id, u16_t cid, + u8_t *status); + +int bt_mesh_cfg_mod_sub_del(u16_t net_idx, u16_t addr, u16_t elem_addr, + u16_t sub_addr, u16_t mod_id, u8_t *status); + +int bt_mesh_cfg_mod_sub_del_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr, + u16_t sub_addr, u16_t mod_id, u16_t cid, + u8_t *status); + +int bt_mesh_cfg_mod_sub_overwrite(u16_t net_idx, u16_t addr, u16_t elem_addr, + u16_t sub_addr, u16_t mod_id, u8_t *status); + +int bt_mesh_cfg_mod_sub_overwrite_vnd(u16_t net_idx, u16_t addr, + u16_t elem_addr, u16_t sub_addr, + u16_t mod_id, u16_t cid, u8_t *status); + +int bt_mesh_cfg_mod_sub_va_add(u16_t net_idx, u16_t addr, u16_t elem_addr, + const u8_t label[16], u16_t mod_id, + u16_t *virt_addr, u8_t *status); + +int bt_mesh_cfg_mod_sub_va_add_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr, + const u8_t label[16], u16_t mod_id, + u16_t cid, u16_t *virt_addr, u8_t *status); + +int bt_mesh_cfg_mod_sub_va_del(u16_t net_idx, u16_t addr, u16_t elem_addr, + const u8_t label[16], u16_t mod_id, + u16_t *virt_addr, u8_t *status); + +int bt_mesh_cfg_mod_sub_va_del_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr, + const u8_t label[16], u16_t mod_id, + u16_t cid, u16_t *virt_addr, u8_t *status); + +int bt_mesh_cfg_mod_sub_va_overwrite(u16_t net_idx, u16_t addr, + u16_t elem_addr, const u8_t label[16], + u16_t mod_id, u16_t *virt_addr, + u8_t *status); + +int bt_mesh_cfg_mod_sub_va_overwrite_vnd(u16_t net_idx, u16_t addr, + u16_t elem_addr, const u8_t label[16], + u16_t mod_id, u16_t cid, + u16_t *virt_addr, u8_t *status); + +struct bt_mesh_cfg_hb_sub { + u16_t src; + u16_t dst; + u8_t period; + u8_t count; + u8_t min; + u8_t max; +}; + +int bt_mesh_cfg_hb_sub_set(u16_t net_idx, u16_t addr, + struct bt_mesh_cfg_hb_sub *sub, u8_t *status); + +int bt_mesh_cfg_hb_sub_get(u16_t net_idx, u16_t addr, + struct bt_mesh_cfg_hb_sub *sub, u8_t *status); + +struct bt_mesh_cfg_hb_pub { + u16_t dst; + u8_t count; + u8_t period; + u8_t ttl; + u16_t feat; + u16_t net_idx; +}; + +int bt_mesh_cfg_hb_pub_set(u16_t net_idx, u16_t addr, + const struct bt_mesh_cfg_hb_pub *pub, u8_t *status); + +int bt_mesh_cfg_hb_pub_get(u16_t net_idx, u16_t addr, + struct bt_mesh_cfg_hb_pub *pub, u8_t *status); + +s32_t bt_mesh_cfg_cli_timeout_get(void); +void bt_mesh_cfg_cli_timeout_set(s32_t timeout); + +#ifdef __cplusplus +} +#endif +/** + * @} + */ + +#endif /* __BT_MESH_CFG_CLI_H */ diff --git a/libesp32/NimBLE-Arduino/src/mesh/cfg_srv.h b/libesp32/NimBLE-Arduino/src/mesh/cfg_srv.h new file mode 100644 index 000000000..cb5d25e69 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/mesh/cfg_srv.h @@ -0,0 +1,77 @@ +/** @file + * @brief Bluetooth Mesh Configuration Server Model APIs. + */ + +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef __BT_MESH_CFG_SRV_H +#define __BT_MESH_CFG_SRV_H + +/** + * @brief Bluetooth Mesh + * @defgroup bt_mesh_cfg_srv Bluetooth Mesh Configuration Server Model + * @ingroup bt_mesh + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** Mesh Configuration Server Model Context */ +struct bt_mesh_cfg_srv { + struct bt_mesh_model *model; + + u8_t net_transmit; /* Network Transmit state */ + u8_t relay; /* Relay Mode state */ + u8_t relay_retransmit; /* Relay Retransmit state */ + u8_t beacon; /* Secure Network Beacon state */ + u8_t gatt_proxy; /* GATT Proxy state */ + u8_t frnd; /* Friend state */ + u8_t default_ttl; /* Default TTL */ + + /* Heartbeat Publication */ + struct bt_mesh_hb_pub { + struct k_delayed_work timer; + + u16_t dst; + u16_t count; + u8_t period; + u8_t ttl; + u16_t feat; + u16_t net_idx; + } hb_pub; + + /* Heartbeat Subscription */ + struct bt_mesh_hb_sub { + s64_t expiry; + + u16_t src; + u16_t dst; + u16_t count; + u8_t min_hops; + u8_t max_hops; + + /* Optional subscription tracking function */ + void (*func)(u8_t hops, u16_t feat); + } hb_sub; +}; + +extern const struct bt_mesh_model_op bt_mesh_cfg_srv_op[]; + +#define BT_MESH_MODEL_CFG_SRV(srv_data) \ + BT_MESH_MODEL(BT_MESH_MODEL_ID_CFG_SRV, \ + bt_mesh_cfg_srv_op, NULL, srv_data) + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* __BT_MESH_CFG_SRV_H */ diff --git a/libesp32/NimBLE-Arduino/src/mesh/glue.h b/libesp32/NimBLE-Arduino/src/mesh/glue.h new file mode 100644 index 000000000..d6aee21f9 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/mesh/glue.h @@ -0,0 +1,484 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef _MESH_GLUE_ +#define _MESH_GLUE_ + +#include +#include + +#include "syscfg/syscfg.h" +#include "nimble/nimble_npl.h" + +#include "os/os_mbuf.h" +#include "os/queue.h" + +#include "nimble/ble.h" +#include "host/ble_hs.h" +#include "host/ble_uuid.h" +#include "../src/ble_sm_priv.h" +#include "../src/ble_hs_hci_priv.h" + +#if MYNEWT_VAL(BLE_CRYPTO_STACK_MBEDTLS) +#include "mbedtls/aes.h" +#include "mbedtls/cipher.h" +#include "mbedtls/entropy.h" +#include "mbedtls/ctr_drbg.h" +#include "mbedtls/cmac.h" +#include "mbedtls/ecdh.h" +#include "mbedtls/ecp.h" + +#else +#include "tinycrypt/aes.h" +#include "tinycrypt/constants.h" +#include "tinycrypt/utils.h" +#include "tinycrypt/cmac_mode.h" +#include "tinycrypt/ecc_dh.h" +#endif + +#if MYNEWT_VAL(BLE_MESH_SETTINGS) +#include "config/config.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define u8_t uint8_t +#define s8_t int8_t +#define u16_t uint16_t +#define s16_t int16_t +#define u32_t uint32_t +#define u64_t uint64_t +#define s64_t int64_t +#define s32_t int32_t + +/** @brief Helper to declare elements of bt_data arrays + * + * This macro is mainly for creating an array of struct bt_data + * elements which is then passed to bt_le_adv_start(). + * + * @param _type Type of advertising data field + * @param _data Pointer to the data field payload + * @param _data_len Number of bytes behind the _data pointer + */ +#define BT_DATA(_type, _data, _data_len) \ + { \ + .type = (_type), \ + .data_len = (_data_len), \ + .data = (const u8_t *)(_data), \ + } + +/** @brief Helper to declare elements of bt_data arrays + * + * This macro is mainly for creating an array of struct bt_data + * elements which is then passed to bt_le_adv_start(). + * + * @param _type Type of advertising data field + * @param _bytes Variable number of single-byte parameters + */ +#define BT_DATA_BYTES(_type, _bytes...) \ + BT_DATA(_type, ((u8_t []) { _bytes }), \ + sizeof((u8_t []) { _bytes })) + +/* EIR/AD data type definitions */ +#define BT_DATA_FLAGS 0x01 /* AD flags */ +#define BT_DATA_UUID16_SOME 0x02 /* 16-bit UUID, more available */ +#define BT_DATA_UUID16_ALL 0x03 /* 16-bit UUID, all listed */ +#define BT_DATA_UUID32_SOME 0x04 /* 32-bit UUID, more available */ +#define BT_DATA_UUID32_ALL 0x05 /* 32-bit UUID, all listed */ +#define BT_DATA_UUID128_SOME 0x06 /* 128-bit UUID, more available */ +#define BT_DATA_UUID128_ALL 0x07 /* 128-bit UUID, all listed */ +#define BT_DATA_NAME_SHORTENED 0x08 /* Shortened name */ +#define BT_DATA_NAME_COMPLETE 0x09 /* Complete name */ +#define BT_DATA_TX_POWER 0x0a /* Tx Power */ +#define BT_DATA_SOLICIT16 0x14 /* Solicit UUIDs, 16-bit */ +#define BT_DATA_SOLICIT128 0x15 /* Solicit UUIDs, 128-bit */ +#define BT_DATA_SVC_DATA16 0x16 /* Service data, 16-bit UUID */ +#define BT_DATA_GAP_APPEARANCE 0x19 /* GAP appearance */ +#define BT_DATA_SOLICIT32 0x1f /* Solicit UUIDs, 32-bit */ +#define BT_DATA_SVC_DATA32 0x20 /* Service data, 32-bit UUID */ +#define BT_DATA_SVC_DATA128 0x21 /* Service data, 128-bit UUID */ +#define BT_DATA_URI 0x24 /* URI */ +#define BT_DATA_MESH_PROV 0x29 /* Mesh Provisioning PDU */ +#define BT_DATA_MESH_MESSAGE 0x2a /* Mesh Networking PDU */ +#define BT_DATA_MESH_BEACON 0x2b /* Mesh Beacon */ + +#define BT_DATA_MANUFACTURER_DATA 0xff /* Manufacturer Specific Data */ + +#define BT_LE_AD_LIMITED 0x01 /* Limited Discoverable */ +#define BT_LE_AD_GENERAL 0x02 /* General Discoverable */ +#define BT_LE_AD_NO_BREDR 0x04 /* BR/EDR not supported */ + +#define sys_put_be16(a,b) put_be16(b, a) +#define sys_put_le16(a,b) put_le16(b, a) +#define sys_put_be32(a,b) put_be32(b, a) +#define sys_get_be16(a) get_be16(a) +#define sys_get_le16(a) get_le16(a) +#define sys_get_be32(a) get_be32(a) +#define sys_cpu_to_be16(a) htobe16(a) +#define sys_cpu_to_be32(a) htobe32(a) +#define sys_be32_to_cpu(a) be32toh(a) +#define sys_be16_to_cpu(a) be16toh(a) +#define sys_le16_to_cpu(a) le16toh(a) + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#endif + +#define CODE_UNREACHABLE __builtin_unreachable() +#define __ASSERT(code, str) \ + do { \ + if (!(code)) BT_ERR(str); \ + assert(code); \ + } while (0); + +#define __ASSERT_NO_MSG(test) __ASSERT(test, "") + +/* Mesh is designed to not use mbuf chains */ +#if BT_DBG_ENABLED +#define ASSERT_NOT_CHAIN(om) assert(SLIST_NEXT(om, om_next) == NULL) +#else +#define ASSERT_NOT_CHAIN(om) (void)(om) +#endif + +#define __packed __attribute__((__packed__)) + +#define MSEC_PER_SEC (1000) +#define K_MSEC(ms) (ms) +#define K_SECONDS(s) K_MSEC((s) * MSEC_PER_SEC) +#define K_MINUTES(m) K_SECONDS((m) * 60) +#define K_HOURS(h) K_MINUTES((h) * 60) + +#ifndef BIT +#define BIT(n) (1UL << (n)) +#endif + +#define BIT_MASK(n) (BIT(n) - 1) + +#define BT_GAP_ADV_FAST_INT_MIN_1 0x0030 /* 30 ms */ +#define BT_GAP_ADV_FAST_INT_MAX_1 0x0060 /* 60 ms */ +#define BT_GAP_ADV_FAST_INT_MIN_2 0x00a0 /* 100 ms */ +#define BT_GAP_ADV_FAST_INT_MAX_2 0x00f0 /* 150 ms */ +#define BT_GAP_ADV_SLOW_INT_MIN 0x0640 /* 1 s */ +#define BT_GAP_ADV_SLOW_INT_MAX 0x0780 /* 1.2 s */ + +#define BT_DBG(fmt, ...) \ + if (BT_DBG_ENABLED) { \ + BLE_HS_LOG(DEBUG, "%s: " fmt "\n", __func__, ## __VA_ARGS__); \ + } +#define BT_INFO(fmt, ...) BLE_HS_LOG(INFO, "%s: " fmt "\n", __func__, ## __VA_ARGS__); +#define BT_WARN(fmt, ...) BLE_HS_LOG(WARN, "%s: " fmt "\n", __func__, ## __VA_ARGS__); +#define BT_ERR(fmt, ...) BLE_HS_LOG(ERROR, "%s: " fmt "\n", __func__, ## __VA_ARGS__); +#define BT_GATT_ERR(_att_err) (-(_att_err)) + +typedef ble_addr_t bt_addr_le_t; + +#define k_fifo_init(queue) ble_npl_eventq_init(queue) +#define net_buf_simple_tailroom(buf) OS_MBUF_TRAILINGSPACE(buf) +#define net_buf_tailroom(buf) net_buf_simple_tailroom(buf) +#define net_buf_headroom(buf) ((buf)->om_data - &(buf)->om_databuf[buf->om_pkthdr_len]) +#define net_buf_simple_headroom(buf) net_buf_headroom(buf) +#define net_buf_simple_tail(buf) ((buf)->om_data + (buf)->om_len) + +struct net_buf_simple_state { + /** Offset of the data pointer from the beginning of the storage */ + u16_t offset; + /** Length of data */ + u16_t len; +}; + +static inline struct os_mbuf * NET_BUF_SIMPLE(uint16_t size) +{ + struct os_mbuf *buf; + + buf = os_msys_get(size, 0); + assert(buf); + + return buf; +} + +#define K_NO_WAIT (0) +#define K_FOREVER (-1) + +/* This is by purpose */ +static inline void net_buf_simple_init(struct os_mbuf *buf, + size_t reserve_head) +{ + /* This is called in Zephyr after init. + * Note in Mynewt case we don't care abour reserved head*/ + buf->om_data = &buf->om_databuf[buf->om_pkthdr_len] + reserve_head; + buf->om_len = 0; +} + +void net_buf_put(struct ble_npl_eventq *fifo, struct os_mbuf *buf); +void * net_buf_ref(struct os_mbuf *om); +void net_buf_unref(struct os_mbuf *om); +uint16_t net_buf_simple_pull_le16(struct os_mbuf *om); +uint16_t net_buf_simple_pull_be16(struct os_mbuf *om); +uint32_t net_buf_simple_pull_be32(struct os_mbuf *om); +uint32_t net_buf_simple_pull_le32(struct os_mbuf *om); +uint8_t net_buf_simple_pull_u8(struct os_mbuf *om); +void net_buf_simple_add_le16(struct os_mbuf *om, uint16_t val); +void net_buf_simple_add_be16(struct os_mbuf *om, uint16_t val); +void net_buf_simple_add_u8(struct os_mbuf *om, uint8_t val); +void net_buf_simple_add_be32(struct os_mbuf *om, uint32_t val); +void net_buf_simple_add_le32(struct os_mbuf *om, uint32_t val); +void net_buf_add_zeros(struct os_mbuf *om, uint8_t len); +void net_buf_simple_push_le16(struct os_mbuf *om, uint16_t val); +void net_buf_simple_push_be16(struct os_mbuf *om, uint16_t val); +void net_buf_simple_push_u8(struct os_mbuf *om, uint8_t val); +void *net_buf_simple_pull(struct os_mbuf *om, uint8_t len); +void *net_buf_simple_pull_mem(struct os_mbuf *om, uint8_t len); +void *net_buf_simple_add(struct os_mbuf *om, uint8_t len); +bool k_fifo_is_empty(struct ble_npl_eventq *q); +void *net_buf_get(struct ble_npl_eventq *fifo,s32_t t); +uint8_t *net_buf_simple_push(struct os_mbuf *om, uint8_t len); +void net_buf_reserve(struct os_mbuf *om, size_t reserve); + +#define net_buf_add_mem(a,b,c) os_mbuf_append(a,b,c) +#define net_buf_simple_add_mem(a,b,c) os_mbuf_append(a,b,c) +#define net_buf_add_u8(a,b) net_buf_simple_add_u8(a,b) +#define net_buf_add(a,b) net_buf_simple_add(a,b) + +#define net_buf_clone(a, b) os_mbuf_dup(a) +#define net_buf_add_be32(a, b) net_buf_simple_add_be32(a, b) +#define net_buf_add_be16(a, b) net_buf_simple_add_be16(a, b) + +#define BT_GATT_CCC_NOTIFY BLE_GATT_CHR_PROP_NOTIFY + +/** Description of different data types that can be encoded into + * advertising data. Used to form arrays that are passed to the + * bt_le_adv_start() function. + */ +struct bt_data { + u8_t type; + u8_t data_len; + const u8_t *data; +}; + +struct bt_pub_key_cb { + /** @brief Callback type for Public Key generation. + * + * Used to notify of the local public key or that the local key is not + * available (either because of a failure to read it or because it is + * being regenerated). + * + * @param key The local public key, or NULL in case of no key. + */ + void (*func)(const u8_t key[64]); + + struct bt_pub_key_cb *_next; +}; + +typedef void (*bt_dh_key_cb_t)(const u8_t key[32]); +int bt_dh_key_gen(const u8_t remote_pk[64], bt_dh_key_cb_t cb); +int bt_pub_key_gen(struct bt_pub_key_cb *new_cb); +uint8_t *bt_pub_key_get(void); +int bt_rand(void *buf, size_t len); +const char * bt_hex(const void *buf, size_t len); +int bt_encrypt_be(const uint8_t *key, const uint8_t *plaintext, uint8_t *enc_data); +void bt_mesh_register_gatt(void); +int bt_le_adv_start(const struct ble_gap_adv_params *param, + const struct bt_data *ad, size_t ad_len, + const struct bt_data *sd, size_t sd_len); +int bt_le_adv_stop(bool proxy); + +struct k_delayed_work { + struct ble_npl_callout work; +}; + +void k_work_init(struct ble_npl_callout *work, ble_npl_event_fn handler); +void k_delayed_work_init(struct k_delayed_work *w, ble_npl_event_fn *f); +void k_delayed_work_cancel(struct k_delayed_work *w); +void k_delayed_work_submit(struct k_delayed_work *w, uint32_t ms); +int64_t k_uptime_get(void); +u32_t k_uptime_get_32(void); +void k_sleep(int32_t duration); +void k_work_submit(struct ble_npl_callout *w); +void k_work_add_arg(struct ble_npl_callout *w, void *arg); +void k_delayed_work_add_arg(struct k_delayed_work *w, void *arg); +uint32_t k_delayed_work_remaining_get(struct k_delayed_work *w); + +static inline void net_buf_simple_save(struct os_mbuf *buf, + struct net_buf_simple_state *state) +{ + state->offset = net_buf_simple_headroom(buf); + state->len = buf->om_len; +} + +static inline void net_buf_simple_restore(struct os_mbuf *buf, + struct net_buf_simple_state *state) +{ + buf->om_data = &buf->om_databuf[buf->om_pkthdr_len] + state->offset; + buf->om_len = state->len; +} + +static inline void sys_memcpy_swap(void *dst, const void *src, size_t length) +{ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpointer-arith" + __ASSERT(((src < dst && (src + length) <= dst) || + (src > dst && (dst + length) <= src)), + "Source and destination buffers must not overlap"); + + src += length - 1; + + for (; length > 0; length--) { + *((u8_t *)dst++) = *((u8_t *)src--); + } +#pragma GCC diagnostic pop +} + +#define popcount(x) __builtin_popcount(x) + +static inline unsigned int find_lsb_set(u32_t op) +{ + return __builtin_ffs(op); +} + +static inline unsigned int find_msb_set(u32_t op) +{ + if (!op) + return 0; + + return 32 - __builtin_clz(op); +} + +#define CONFIG_BT_MESH_FRIEND BLE_MESH_FRIEND +#define CONFIG_BT_MESH_GATT_PROXY BLE_MESH_GATT_PROXY +#define CONFIG_BT_MESH_IV_UPDATE_TEST BLE_MESH_IV_UPDATE_TEST +#define CONFIG_BT_MESH_LOW_POWER BLE_MESH_LOW_POWER +#define CONFIG_BT_MESH_LPN_AUTO BLE_MESH_LPN_AUTO +#define CONFIG_BT_MESH_LPN_ESTABLISHMENT BLE_MESH_LPN_ESTABLISHMENT +#define CONFIG_BT_MESH_PB_ADV BLE_MESH_PB_ADV +#define CONFIG_BT_MESH_PB_GATT BLE_MESH_PB_GATT +#define CONFIG_BT_MESH_PROV BLE_MESH_PROV +#define CONFIG_BT_TESTING BLE_MESH_TESTING +#define CONFIG_BT_SETTINGS BLE_MESH_SETTINGS +#define CONFIG_SETTINGS BLE_MESH_SETTINGS + +/* Above flags are used with IS_ENABLED macro */ +#define IS_ENABLED(config) MYNEWT_VAL(config) + +#define CONFIG_BT_MESH_LPN_GROUPS MYNEWT_VAL(BLE_MESH_LPN_GROUPS) +#define CONFIG_BT_MESH_ADV_BUF_COUNT MYNEWT_VAL(BLE_MESH_ADV_BUF_COUNT) +#define CONFIG_BT_MESH_FRIEND_QUEUE_SIZE MYNEWT_VAL(BLE_MESH_FRIEND_QUEUE_SIZE) +#define CONFIG_BT_MESH_FRIEND_RECV_WIN MYNEWT_VAL(BLE_MESH_FRIEND_RECV_WIN) +#define CONFIG_BT_MESH_LPN_POLL_TIMEOUT MYNEWT_VAL(BLE_MESH_LPN_POLL_TIMEOUT) +#define CONFIG_BT_MESH_MODEL_GROUP_COUNT MYNEWT_VAL(BLE_MESH_MODEL_GROUP_COUNT) +#define CONFIG_BT_MESH_MODEL_KEY_COUNT MYNEWT_VAL(BLE_MESH_MODEL_KEY_COUNT) +#define CONFIG_BT_MESH_NODE_ID_TIMEOUT MYNEWT_VAL(BLE_MESH_NODE_ID_TIMEOUT) +#define CONFIG_BT_MAX_CONN MYNEWT_VAL(BLE_MAX_CONNECTIONS) +#define CONFIG_BT_MESH_SEQ_STORE_RATE MYNEWT_VAL(BLE_MESH_SEQ_STORE_RATE) +#define CONFIG_BT_MESH_RPL_STORE_TIMEOUT MYNEWT_VAL(BLE_MESH_RPL_STORE_TIMEOUT) +#define CONFIG_BT_MESH_APP_KEY_COUNT MYNEWT_VAL(BLE_MESH_APP_KEY_COUNT) +#define CONFIG_BT_MESH_SUBNET_COUNT MYNEWT_VAL(BLE_MESH_SUBNET_COUNT) +#define CONFIG_BT_MESH_STORE_TIMEOUT MYNEWT_VAL(BLE_MESH_STORE_TIMEOUT) +#define CONFIG_BT_MESH_IVU_DIVIDER MYNEWT_VAL(BLE_MESH_IVU_DIVIDER) +#define CONFIG_BT_DEVICE_NAME MYNEWT_VAL(BLE_MESH_DEVICE_NAME) +#define CONFIG_BT_MESH_TX_SEG_MAX MYNEWT_VAL(BLE_MESH_TX_SEG_MAX) + +#define printk console_printf + +#define CONTAINER_OF(ptr, type, field) \ + ((type *)(((char *)(ptr)) - offsetof(type, field))) + + +#define k_sem ble_npl_sem + +static inline void k_sem_init(struct k_sem *sem, unsigned int initial_count, + unsigned int limit) +{ + ble_npl_sem_init(sem, initial_count); +} + +static inline int k_sem_take(struct k_sem *sem, s32_t timeout) +{ + uint32_t ticks; + + ble_npl_time_ms_to_ticks(timeout, &ticks); + return - ble_npl_sem_pend(sem, ticks); +} + +static inline void k_sem_give(struct k_sem *sem) +{ + ble_npl_sem_release(sem); +} + +/* Helpers to access the storage array, since we don't have access to its + * type at this point anymore. + */ + +#define BUF_SIZE(pool) (pool->omp_pool->mp_block_size) + +static inline int net_buf_id(struct os_mbuf *buf) +{ + struct os_mbuf_pool *pool = buf->om_omp; + u8_t *pool_start = (u8_t *)pool->omp_pool->mp_membuf_addr; + u8_t *buf_ptr = (u8_t *)buf; + + return (buf_ptr - pool_start) / BUF_SIZE(pool); +} + +/* XXX: We should not use os_mbuf_pkthdr chains to represent a list of + * packets, this is a hack. For now this is not an issue, because mesh + * does not use os_mbuf chains. We should change this in the future. + */ +STAILQ_HEAD(net_buf_slist_t, os_mbuf_pkthdr); + +void net_buf_slist_init(struct net_buf_slist_t *list); +bool net_buf_slist_is_empty(struct net_buf_slist_t *list); +struct os_mbuf *net_buf_slist_peek_head(struct net_buf_slist_t *list); +struct os_mbuf *net_buf_slist_peek_next(struct os_mbuf *buf); +struct os_mbuf *net_buf_slist_get(struct net_buf_slist_t *list); +void net_buf_slist_put(struct net_buf_slist_t *list, struct os_mbuf *buf); +void net_buf_slist_remove(struct net_buf_slist_t *list, struct os_mbuf *prev, + struct os_mbuf *cur); +void net_buf_slist_merge_slist(struct net_buf_slist_t *list, + struct net_buf_slist_t *list_to_append); +#define NET_BUF_SLIST_FOR_EACH_NODE(head, var) STAILQ_FOREACH(var, head, omp_next) + +#if MYNEWT_VAL(BLE_MESH_SETTINGS) + +#define settings_load conf_load +int settings_bytes_from_str(char *val_str, void *vp, int *len); +char *settings_str_from_bytes(void *vp, int vp_len, char *buf, int buf_len); + +#define snprintk snprintf +#define BT_SETTINGS_SIZE(in_size) ((((((in_size) - 1) / 3) * 4) + 4) + 1) +#define settings_save_one conf_save_one + +#else + +static inline int +settings_load(void) +{ + return 0; +} + +#endif /* MYNEWT_VAL(MYNEWT_VAL_BLE_MESH_SETTINGS) */ + +#define BUILD_ASSERT(cond) _Static_assert(cond, "") + +#ifdef __cplusplus +} +#endif + +#endif /* _MESH_GLUE_ */ diff --git a/libesp32/NimBLE-Arduino/src/mesh/health_cli.h b/libesp32/NimBLE-Arduino/src/mesh/health_cli.h new file mode 100644 index 000000000..719d621e0 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/mesh/health_cli.h @@ -0,0 +1,80 @@ +/** @file + * @brief Bluetooth Mesh Health Client Model APIs. + */ + +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef __BT_MESH_HEALTH_CLI_H +#define __BT_MESH_HEALTH_CLI_H + +/** + * @brief Bluetooth Mesh + * @defgroup bt_mesh_health_cli Bluetooth Mesh Health Client Model + * @ingroup bt_mesh + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** Mesh Health Client Model Context */ +struct bt_mesh_health_cli { + struct bt_mesh_model *model; + + void (*current_status)(struct bt_mesh_health_cli *cli, u16_t addr, + u8_t test_id, u16_t cid, u8_t *faults, + size_t fault_count); + + struct k_sem op_sync; + u32_t op_pending; + void *op_param; +}; + +extern const struct bt_mesh_model_op bt_mesh_health_cli_op[]; + +#define BT_MESH_MODEL_HEALTH_CLI(cli_data) \ + BT_MESH_MODEL(BT_MESH_MODEL_ID_HEALTH_CLI, \ + bt_mesh_health_cli_op, NULL, cli_data) + +int bt_mesh_health_cli_set(struct bt_mesh_model *model); + +int bt_mesh_health_fault_get(u16_t net_idx, u16_t addr, u16_t app_idx, + u16_t cid, u8_t *test_id, u8_t *faults, + size_t *fault_count); + +int bt_mesh_health_fault_clear(u16_t net_idx, u16_t addr, u16_t app_idx, + u16_t cid, u8_t *test_id, u8_t *faults, + size_t *fault_count); + +int bt_mesh_health_fault_test(u16_t net_idx, u16_t addr, u16_t app_idx, + u16_t cid, u8_t test_id, u8_t *faults, + size_t *fault_count); + +int bt_mesh_health_period_get(u16_t net_idx, u16_t addr, u16_t app_idx, + u8_t *divisor); + +int bt_mesh_health_period_set(u16_t net_idx, u16_t addr, u16_t app_idx, + u8_t divisor, u8_t *updated_divisor); + +int bt_mesh_health_attention_get(u16_t net_idx, u16_t addr, u16_t app_idx, + u8_t *attention); + +int bt_mesh_health_attention_set(u16_t net_idx, u16_t addr, u16_t app_idx, + u8_t attention, u8_t *updated_attention); + +s32_t bt_mesh_health_cli_timeout_get(void); +void bt_mesh_health_cli_timeout_set(s32_t timeout); + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* __BT_MESH_HEALTH_CLI_H */ diff --git a/libesp32/NimBLE-Arduino/src/mesh/health_srv.h b/libesp32/NimBLE-Arduino/src/mesh/health_srv.h new file mode 100644 index 000000000..0638c982a --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/mesh/health_srv.h @@ -0,0 +1,99 @@ +/** @file + * @brief Bluetooth Mesh Health Server Model APIs. + */ + +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef __BT_MESH_HEALTH_SRV_H +#define __BT_MESH_HEALTH_SRV_H + +/** + * @brief Mesh Bluetooth Mesh Health Server Model + * @defgroup bt_mesh_health_srv + * @ingroup bt_mesh + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +struct bt_mesh_health_srv_cb { + /* Fetch current faults */ + int (*fault_get_cur)(struct bt_mesh_model *model, u8_t *test_id, + u16_t *company_id, u8_t *faults, + u8_t *fault_count); + + /* Fetch registered faults */ + int (*fault_get_reg)(struct bt_mesh_model *model, u16_t company_id, + u8_t *test_id, u8_t *faults, + u8_t *fault_count); + + /* Clear registered faults */ + int (*fault_clear)(struct bt_mesh_model *model, u16_t company_id); + + /* Run a specific test */ + int (*fault_test)(struct bt_mesh_model *model, u8_t test_id, + u16_t company_id); + + /* Attention on */ + void (*attn_on)(struct bt_mesh_model *model); + + /* Attention off */ + void (*attn_off)(struct bt_mesh_model *model); +}; + +/** @def BT_MESH_HEALTH_FAULT_MSG + * + * A helper to define a health fault message. + * + * @param max_faults Maximum number of faults the element can have. + * + * @return a New net_buf_simple of the needed size. + */ +#define BT_MESH_HEALTH_FAULT_MSG(max_faults) \ + NET_BUF_SIMPLE(1 + 3 + (max_faults)) + +/** Mesh Health Server Model Context */ +struct bt_mesh_health_srv { + struct bt_mesh_model *model; + + /* Optional callback struct */ + const struct bt_mesh_health_srv_cb *cb; + + /* Attention Timer state */ + struct k_delayed_work attn_timer; +}; + +int bt_mesh_fault_update(struct bt_mesh_elem *elem); + +extern const struct bt_mesh_model_op bt_mesh_health_srv_op[]; + +/** @def BT_MESH_MODEL_HEALTH_SRV + * + * Define a new health server model. Note that this API needs to be + * repeated for each element that the application wants to have a + * health server model on. Each instance also needs a unique + * bt_mesh_health_srv and bt_mesh_model_pub context. + * + * @param srv Pointer to a unique struct bt_mesh_health_srv. + * @param pub Pointer to a unique struct bt_mesh_model_pub. + * + * @return New mesh model instance. + */ +#define BT_MESH_MODEL_HEALTH_SRV(srv, pub) \ + BT_MESH_MODEL(BT_MESH_MODEL_ID_HEALTH_SRV, \ + bt_mesh_health_srv_op, pub, srv) + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* __BT_MESH_HEALTH_SRV_H */ diff --git a/libesp32/NimBLE-Arduino/src/mesh/main.h b/libesp32/NimBLE-Arduino/src/mesh/main.h new file mode 100644 index 000000000..515d1d527 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/mesh/main.h @@ -0,0 +1,394 @@ +/** @file + * @brief Bluetooth Mesh Profile APIs. + */ + +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef __BT_MESH_MAIN_H +#define __BT_MESH_MAIN_H + +/** + * @brief Bluetooth Mesh Provisioning + * @defgroup bt_mesh_prov Bluetooth Mesh Provisioning + * @ingroup bt_mesh + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + BT_MESH_NO_OUTPUT = 0, + BT_MESH_BLINK = BIT(0), + BT_MESH_BEEP = BIT(1), + BT_MESH_VIBRATE = BIT(2), + BT_MESH_DISPLAY_NUMBER = BIT(3), + BT_MESH_DISPLAY_STRING = BIT(4), +} bt_mesh_output_action_t; + +typedef enum { + BT_MESH_NO_INPUT = 0, + BT_MESH_PUSH = BIT(0), + BT_MESH_TWIST = BIT(1), + BT_MESH_ENTER_NUMBER = BIT(2), + BT_MESH_ENTER_STRING = BIT(3), +} bt_mesh_input_action_t; + +typedef enum { + BT_MESH_PROV_ADV = BIT(0), + BT_MESH_PROV_GATT = BIT(1), +} bt_mesh_prov_bearer_t; + +typedef enum { + BT_MESH_PROV_OOB_OTHER = BIT(0), + BT_MESH_PROV_OOB_URI = BIT(1), + BT_MESH_PROV_OOB_2D_CODE = BIT(2), + BT_MESH_PROV_OOB_BAR_CODE = BIT(3), + BT_MESH_PROV_OOB_NFC = BIT(4), + BT_MESH_PROV_OOB_NUMBER = BIT(5), + BT_MESH_PROV_OOB_STRING = BIT(6), + /* 7 - 10 are reserved */ + BT_MESH_PROV_OOB_ON_BOX = BIT(11), + BT_MESH_PROV_OOB_IN_BOX = BIT(12), + BT_MESH_PROV_OOB_ON_PAPER = BIT(13), + BT_MESH_PROV_OOB_IN_MANUAL = BIT(14), + BT_MESH_PROV_OOB_ON_DEV = BIT(15), +} bt_mesh_prov_oob_info_t; + +/** Provisioning properties & capabilities. */ +struct bt_mesh_prov { + /** The UUID that's used when advertising as unprovisioned */ + const u8_t *uuid; + + /** Optional URI. This will be advertised separately from the + * unprovisioned beacon, however the unprovisioned beacon will + * contain a hash of it so the two can be associated by the + * provisioner. + */ + const char *uri; + + /** Out of Band information field. */ + bt_mesh_prov_oob_info_t oob_info; + + /** Static OOB value */ + const u8_t *static_val; + /** Static OOB value length */ + u8_t static_val_len; + + /** Maximum size of Output OOB supported */ + u8_t output_size; + /** Supported Output OOB Actions */ + u16_t output_actions; + + /* Maximum size of Input OOB supported */ + u8_t input_size; + /** Supported Input OOB Actions */ + u16_t input_actions; + + /** @brief Output of a number is requested. + * + * This callback notifies the application that it should + * output the given number using the given action. + * + * @param act Action for outputting the number. + * @param num Number to be outputted. + * + * @return Zero on success or negative error code otherwise + */ + int (*output_number)(bt_mesh_output_action_t act, u32_t num); + + /** @brief Output of a string is requested. + * + * This callback notifies the application that it should + * display the given string to the user. + * + * @param str String to be displayed. + * + * @return Zero on success or negative error code otherwise + */ + int (*output_string)(const char *str); + + /** @brief Input is requested. + * + * This callback notifies the application that it should + * request input from the user using the given action. The + * requested input will either be a string or a number, and + * the application needs to consequently call the + * bt_mesh_input_string() or bt_mesh_input_number() functions + * once the data has been acquired from the user. + * + * @param act Action for inputting data. + * @param num Maximum size of the inputted data. + * + * @return Zero on success or negative error code otherwise + */ + int (*input)(bt_mesh_input_action_t act, u8_t size); + + /** @brief Provisioning link has been opened. + * + * This callback notifies the application that a provisioning + * link has been opened on the given provisioning bearer. + * + * @param bearer Provisioning bearer. + */ + void (*link_open)(bt_mesh_prov_bearer_t bearer); + + /** @brief Provisioning link has been closed. + * + * This callback notifies the application that a provisioning + * link has been closed on the given provisioning bearer. + * + * @param bearer Provisioning bearer. + */ + void (*link_close)(bt_mesh_prov_bearer_t bearer); + + /** @brief Provisioning is complete. + * + * This callback notifies the application that provisioning has + * been successfully completed, and that the local node has been + * assigned the specified NetKeyIndex and primary element address. + * + * @param net_idx NetKeyIndex given during provisioning. + * @param addr Primary element address. + */ + void (*complete)(u16_t net_idx, u16_t addr); + + /** @brief Node has been reset. + * + * This callback notifies the application that the local node + * has been reset and needs to be reprovisioned. The node will + * not automatically advertise as unprovisioned, rather the + * bt_mesh_prov_enable() API needs to be called to enable + * unprovisioned advertising on one or more provisioning bearers. + */ + void (*reset)(void); +}; + +/** @brief Provide provisioning input OOB string. + * + * This is intended to be called after the bt_mesh_prov input callback + * has been called with BT_MESH_ENTER_STRING as the action. + * + * @param str String. + * + * @return Zero on success or (negative) error code otherwise. + */ +int bt_mesh_input_string(const char *str); + +/** @brief Provide provisioning input OOB number. + * + * This is intended to be called after the bt_mesh_prov input callback + * has been called with BT_MESH_ENTER_NUMBER as the action. + * + * @param num Number. + * + * @return Zero on success or (negative) error code otherwise. + */ +int bt_mesh_input_number(u32_t num); + +/** @brief Enable specific provisioning bearers + * + * Enable one or more provisioning bearers. + * + * @param bearers Bit-wise or of provisioning bearers. + * + * @return Zero on success or (negative) error code otherwise. + */ +int bt_mesh_prov_enable(bt_mesh_prov_bearer_t bearers); + +/** @brief Disable specific provisioning bearers + * + * Disable one or more provisioning bearers. + * + * @param bearers Bit-wise or of provisioning bearers. + * + * @return Zero on success or (negative) error code otherwise. + */ +int bt_mesh_prov_disable(bt_mesh_prov_bearer_t bearers); + +/** + * @} + */ + +/** + * @brief Bluetooth Mesh + * @defgroup bt_mesh Bluetooth Mesh + * @ingroup bluetooth + * @{ + */ + +/* Primary Network Key index */ +#define BT_MESH_NET_PRIMARY 0x000 + +#define BT_MESH_RELAY_DISABLED 0x00 +#define BT_MESH_RELAY_ENABLED 0x01 +#define BT_MESH_RELAY_NOT_SUPPORTED 0x02 + +#define BT_MESH_BEACON_DISABLED 0x00 +#define BT_MESH_BEACON_ENABLED 0x01 + +#define BT_MESH_GATT_PROXY_DISABLED 0x00 +#define BT_MESH_GATT_PROXY_ENABLED 0x01 +#define BT_MESH_GATT_PROXY_NOT_SUPPORTED 0x02 + +#define BT_MESH_FRIEND_DISABLED 0x00 +#define BT_MESH_FRIEND_ENABLED 0x01 +#define BT_MESH_FRIEND_NOT_SUPPORTED 0x02 + +#define BT_MESH_NODE_IDENTITY_STOPPED 0x00 +#define BT_MESH_NODE_IDENTITY_RUNNING 0x01 +#define BT_MESH_NODE_IDENTITY_NOT_SUPPORTED 0x02 + +/* Features */ +#define BT_MESH_FEAT_RELAY BIT(0) +#define BT_MESH_FEAT_PROXY BIT(1) +#define BT_MESH_FEAT_FRIEND BIT(2) +#define BT_MESH_FEAT_LOW_POWER BIT(3) +#define BT_MESH_FEAT_SUPPORTED (BT_MESH_FEAT_RELAY | \ + BT_MESH_FEAT_PROXY | \ + BT_MESH_FEAT_FRIEND | \ + BT_MESH_FEAT_LOW_POWER) + +/** @brief Initialize Mesh support + * + * After calling this API, the node will not automatically advertise as + * unprovisioned, rather the bt_mesh_prov_enable() API needs to be called + * to enable unprovisioned advertising on one or more provisioning bearers. + * + * @param own_addr_type Node address type + * @param prov Node provisioning information. + * @param comp Node Composition. + * + * @return Zero on success or (negative) error code otherwise. + */ +int bt_mesh_init(u8_t own_addr_type, + const struct bt_mesh_prov *prov, + const struct bt_mesh_comp *comp); + +/** @brief Reset the state of the local Mesh node. + * + * Resets the state of the node, which means that it needs to be + * reprovisioned to become an active node in a Mesh network again. + * + * After calling this API, the node will not automatically advertise as + * unprovisioned, rather the bt_mesh_prov_enable() API needs to be called + * to enable unprovisioned advertising on one or more provisioning bearers. + * + */ +void bt_mesh_reset(void); + +/** @brief Suspend the Mesh network temporarily. + * + * This API can be used for power saving purposes, but the user should be + * aware that leaving the local node suspended for a long period of time + * may cause it to become permanently disconnected from the Mesh network. + * If at all possible, the Friendship feature should be used instead, to + * make the node into a Low Power Node. + * + * @return 0 on success, or (negative) error code on failure. + */ +int bt_mesh_suspend(void); + +/** @brief Resume a suspended Mesh network. + * + * This API resumes the local node, after it has been suspended using the + * bt_mesh_suspend() API. + * + * @return 0 on success, or (negative) error code on failure. + */ +int bt_mesh_resume(void); + +/** @brief Provision the local Mesh Node. + * + * This API should normally not be used directly by the application. The + * only exception is for testing purposes where manual provisioning is + * desired without an actual external provisioner. + * + * @param net_key Network Key + * @param net_idx Network Key Index + * @param flags Provisioning Flags + * @param iv_index IV Index + * @param addr Primary element address + * @param dev_key Device Key + * + * @return Zero on success or (negative) error code otherwise. + */ +int bt_mesh_provision(const u8_t net_key[16], u16_t net_idx, + u8_t flags, u32_t iv_index, u16_t addr, + const u8_t dev_key[16]); + +/** @brief Check if the local node has been provisioned. + * + * This API can be used to check if the local node has been provisioned + * or not. It can e.g. be helpful to determine if there was a stored + * network in flash, i.e. if the network was restored after calling + * settings_load(). + * + * @return True if the node is provisioned. False otherwise. + */ +bool bt_mesh_is_provisioned(void); + +/** @brief Toggle the IV Update test mode + * + * This API is only available if the IV Update test mode has been enabled + * in Kconfig. It is needed for passing most of the IV Update qualification + * test cases. + * + * @param enable true to enable IV Update test mode, false to disable it. + */ +void bt_mesh_iv_update_test(bool enable); + +/** @brief Toggle the IV Update state + * + * This API is only available if the IV Update test mode has been enabled + * in Kconfig. It is needed for passing most of the IV Update qualification + * test cases. + * + * @return true if IV Update In Progress state was entered, false otherwise. + */ +bool bt_mesh_iv_update(void); + +/** @brief Toggle the Low Power feature of the local device + * + * Enables or disables the Low Power feature of the local device. This is + * exposed as a run-time feature, since the device might want to change + * this e.g. based on being plugged into a stable power source or running + * from a battery power source. + * + * @param enable true to enable LPN functionality, false to disable it. + * + * @return Zero on success or (negative) error code otherwise. + */ +int bt_mesh_lpn_set(bool enable); + +/** @brief Send out a Friend Poll message. + * + * Send a Friend Poll message to the Friend of this node. If there is no + * established Friendship the function will return an error. + * + * @return Zero on success or (negative) error code otherwise. + */ +int bt_mesh_lpn_poll(void); + +/** @brief Register a callback for Friendship changes. + * + * Registers a callback that will be called whenever Friendship gets + * established or is lost. + * + * @param cb Function to call when the Friendship status changes. + */ +void bt_mesh_lpn_set_cb(void (*cb)(u16_t friend_addr, bool established)); + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* __BT_MESH_MAIN_H */ diff --git a/libesp32/NimBLE-Arduino/src/mesh/mesh.h b/libesp32/NimBLE-Arduino/src/mesh/mesh.h new file mode 100644 index 000000000..9ba63ef0e --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/mesh/mesh.h @@ -0,0 +1,26 @@ +/** @file + * @brief Bluetooth Mesh Profile APIs. + */ + +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef __BT_MESH_H +#define __BT_MESH_H + +#include +#include "syscfg/syscfg.h" +#include "os/os_mbuf.h" + +#include "glue.h" +#include "access.h" +#include "main.h" +#include "cfg_srv.h" +#include "health_srv.h" +#include "cfg_cli.h" +#include "health_cli.h" +#include "proxy.h" + +#endif /* __BT_MESH_H */ diff --git a/libesp32/NimBLE-Arduino/src/mesh/model_cli.h b/libesp32/NimBLE-Arduino/src/mesh/model_cli.h new file mode 100644 index 000000000..33fbd6e9d --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/mesh/model_cli.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __MODEL_CLI_H__ +#define __MODEL_CLI_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +struct bt_mesh_gen_model_cli { + struct bt_mesh_model *model; + + struct k_sem op_sync; + u32_t op_pending; + void *op_param; +}; + +extern struct bt_mesh_gen_model_cli gen_onoff_cli; +extern const struct bt_mesh_model_op gen_onoff_cli_op[]; + +#define BT_MESH_MODEL_GEN_ONOFF_CLI() \ + BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_ONOFF_CLI, \ + gen_onoff_cli_op, NULL, &gen_onoff_cli) + +extern struct bt_mesh_gen_model_cli gen_level_cli; +extern const struct bt_mesh_model_op gen_level_cli_op[]; + +#define BT_MESH_MODEL_GEN_LEVEL_CLI(pub) \ + BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_LEVEL_CLI, \ + gen_level_cli_op, NULL, &gen_level_cli) + + +int bt_mesh_gen_onoff_get(u16_t net_idx, u16_t addr, u16_t app_idx, + u8_t *state); +int bt_mesh_gen_onoff_set(u16_t net_idx, u16_t addr, u16_t app_idx, + u8_t val, u8_t *state); +int bt_mesh_gen_level_get(u16_t net_idx, u16_t addr, u16_t app_idx, + s16_t *level); +int bt_mesh_gen_level_set(u16_t net_idx, u16_t addr, u16_t app_idx, + s16_t val, s16_t *state); +int bt_mesh_gen_model_cli_init(struct bt_mesh_model *model, bool primary); + +#ifdef __cplusplus +} +#endif + +#endif /* __MODEL_CLI_H__ */ diff --git a/libesp32/NimBLE-Arduino/src/mesh/model_srv.h b/libesp32/NimBLE-Arduino/src/mesh/model_srv.h new file mode 100644 index 000000000..c4f4033df --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/mesh/model_srv.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __MODEL_SRV_H__ +#define __MODEL_SRV_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +struct bt_mesh_gen_onoff_srv_cb { + int (*get)(struct bt_mesh_model *model, u8_t *state); + int (*set)(struct bt_mesh_model *model, u8_t state); +}; + +extern const struct bt_mesh_model_op gen_onoff_srv_op[]; + +#define BT_MESH_MODEL_GEN_ONOFF_SRV(srv, pub) \ + BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_ONOFF_SRV, \ + gen_onoff_srv_op, pub, srv) + +struct bt_mesh_gen_level_srv_cb { + int (*get)(struct bt_mesh_model *model, s16_t *level); + int (*set)(struct bt_mesh_model *model, s16_t level); +}; + +extern const struct bt_mesh_model_op gen_level_srv_op[]; + +#define BT_MESH_MODEL_GEN_LEVEL_SRV(srv, pub) \ + BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_LEVEL_SRV, \ + gen_level_srv_op, pub, srv) + +struct bt_mesh_light_lightness_srv_cb { + int (*get)(struct bt_mesh_model *model, s16_t *level); + int (*set)(struct bt_mesh_model *model, s16_t level); +}; + +extern const struct bt_mesh_model_op light_lightness_srv_op[]; + +#define BT_MESH_MODEL_LIGHT_LIGHTNESS_SRV(srv, pub) \ + BT_MESH_MODEL(BT_MESH_MODEL_ID_LIGHT_LIGHTNESS_SRV, \ + light_lightness_srv_op, pub, srv) + + +void bt_mesh_set_gen_onoff_srv_cb(struct bt_mesh_gen_onoff_srv_cb *gen_onoff_cb); +void bt_mesh_set_gen_level_srv_cb(struct bt_mesh_gen_level_srv_cb *gen_level_cb); +void bt_mesh_set_light_lightness_srv_cb(struct bt_mesh_light_lightness_srv_cb *light_lightness_cb); + +#ifdef __cplusplus +} +#endif + +#endif /* __MODEL_SRV_H__ */ diff --git a/libesp32/NimBLE-Arduino/src/mesh/porting.h b/libesp32/NimBLE-Arduino/src/mesh/porting.h new file mode 100644 index 000000000..1667a8a04 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/mesh/porting.h @@ -0,0 +1,27 @@ +/** @file + * @brief Bluetooth Mesh Porting APIs. + */ + +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef __BT_MESH_PORTING_H +#define __BT_MESH_PORTING_H + +#ifdef __cplusplus +extern "C" { +#endif + +void mesh_adv_thread(void *args); + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* __BT_MESH_PORTING_H */ diff --git a/libesp32/NimBLE-Arduino/src/mesh/proxy.h b/libesp32/NimBLE-Arduino/src/mesh/proxy.h new file mode 100644 index 000000000..63bbfa3e5 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/mesh/proxy.h @@ -0,0 +1,43 @@ +/** @file + * @brief Bluetooth Mesh Proxy APIs. + */ + +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef __BT_MESH_PROXY_H +#define __BT_MESH_PROXY_H + +/** + * @brief Bluetooth Mesh Proxy + * @defgroup bt_mesh_proxy Bluetooth Mesh Proxy + * @ingroup bt_mesh + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Enable advertising with Node Identity. + * + * This API requires that GATT Proxy support has been enabled. Once called + * each subnet will start advertising using Node Identity for the next + * 60 seconds. + * + * @return 0 on success, or (negative) error code on failure. + */ +int bt_mesh_proxy_identity_enable(void); + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* __BT_MESH_PROXY_H */ diff --git a/libesp32/NimBLE-Arduino/src/mesh/slist.h b/libesp32/NimBLE-Arduino/src/mesh/slist.h new file mode 100644 index 000000000..8a858f83b --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/mesh/slist.h @@ -0,0 +1,468 @@ +/* + * Copyright (c) 2016 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * + * @brief Single-linked list implementation + * + * Single-linked list implementation using inline macros/functions. + * This API is not thread safe, and thus if a list is used across threads, + * calls to functions must be protected with synchronization primitives. + */ + +#ifndef __SLIST_H__ +#define __SLIST_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +struct _snode { + struct _snode *next; +}; + +typedef struct _snode sys_snode_t; + +struct _slist { + sys_snode_t *head; + sys_snode_t *tail; +}; + +typedef struct _slist sys_slist_t; + +/** + * @brief Provide the primitive to iterate on a list + * Note: the loop is unsafe and thus __sn should not be removed + * + * User _MUST_ add the loop statement curly braces enclosing its own code: + * + * SYS_SLIST_FOR_EACH_NODE(l, n) { + * + * } + * + * This and other SYS_SLIST_*() macros are not thread safe. + * + * @param __sl A pointer on a sys_slist_t to iterate on + * @param __sn A sys_snode_t pointer to peek each node of the list + */ +#define SYS_SLIST_FOR_EACH_NODE(__sl, __sn) \ + for (__sn = sys_slist_peek_head(__sl); __sn; \ + __sn = sys_slist_peek_next(__sn)) + +/** + * @brief Provide the primitive to iterate on a list, from a node in the list + * Note: the loop is unsafe and thus __sn should not be removed + * + * User _MUST_ add the loop statement curly braces enclosing its own code: + * + * SYS_SLIST_ITERATE_FROM_NODE(l, n) { + * + * } + * + * Like SYS_SLIST_FOR_EACH_NODE(), but __dn already contains a node in the list + * where to start searching for the next entry from. If NULL, it starts from + * the head. + * + * This and other SYS_SLIST_*() macros are not thread safe. + * + * @param __sl A pointer on a sys_slist_t to iterate on + * @param __sn A sys_snode_t pointer to peek each node of the list + * it contains the starting node, or NULL to start from the head + */ +#define SYS_SLIST_ITERATE_FROM_NODE(__sl, __sn) \ + for (__sn = __sn ? sys_slist_peek_next_no_check(__sn) \ + : sys_slist_peek_head(__sl); \ + __sn; \ + __sn = sys_slist_peek_next(__sn)) + +/** + * @brief Provide the primitive to safely iterate on a list + * Note: __sn can be removed, it will not break the loop. + * + * User _MUST_ add the loop statement curly braces enclosing its own code: + * + * SYS_SLIST_FOR_EACH_NODE_SAFE(l, n, s) { + * + * } + * + * This and other SYS_SLIST_*() macros are not thread safe. + * + * @param __sl A pointer on a sys_slist_t to iterate on + * @param __sn A sys_snode_t pointer to peek each node of the list + * @param __sns A sys_snode_t pointer for the loop to run safely + */ +#define SYS_SLIST_FOR_EACH_NODE_SAFE(__sl, __sn, __sns) \ + for (__sn = sys_slist_peek_head(__sl), \ + __sns = sys_slist_peek_next(__sn); \ + __sn; __sn = __sns, \ + __sns = sys_slist_peek_next(__sn)) + +/* + * @brief Provide the primitive to resolve the container of a list node + * Note: it is safe to use with NULL pointer nodes + * + * @param __ln A pointer on a sys_node_t to get its container + * @param __cn Container struct type pointer + * @param __n The field name of sys_node_t within the container struct + */ +#define SYS_SLIST_CONTAINER(__ln, __cn, __n) \ + ((__ln) ? CONTAINER_OF((__ln), __typeof__(*(__cn)), __n) : NULL) +/* + * @brief Provide the primitive to peek container of the list head + * + * @param __sl A pointer on a sys_slist_t to peek + * @param __cn Container struct type pointer + * @param __n The field name of sys_node_t within the container struct + */ +#define SYS_SLIST_PEEK_HEAD_CONTAINER(__sl, __cn, __n) \ + SYS_SLIST_CONTAINER(sys_slist_peek_head(__sl), __cn, __n) + +/* + * @brief Provide the primitive to peek container of the list tail + * + * @param __sl A pointer on a sys_slist_t to peek + * @param __cn Container struct type pointer + * @param __n The field name of sys_node_t within the container struct + */ +#define SYS_SLIST_PEEK_TAIL_CONTAINER(__sl, __cn, __n) \ + SYS_SLIST_CONTAINER(sys_slist_peek_tail(__sl), __cn, __n) + +/* + * @brief Provide the primitive to peek the next container + * + * @param __cn Container struct type pointer + * @param __n The field name of sys_node_t within the container struct + */ + +#define SYS_SLIST_PEEK_NEXT_CONTAINER(__cn, __n) \ + ((__cn) ? SYS_SLIST_CONTAINER(sys_slist_peek_next(&((__cn)->__n)), \ + __cn, __n) : NULL) + +/** + * @brief Provide the primitive to iterate on a list under a container + * Note: the loop is unsafe and thus __cn should not be detached + * + * User _MUST_ add the loop statement curly braces enclosing its own code: + * + * SYS_SLIST_FOR_EACH_CONTAINER(l, c, n) { + * + * } + * + * @param __sl A pointer on a sys_slist_t to iterate on + * @param __cn A pointer to peek each entry of the list + * @param __n The field name of sys_node_t within the container struct + */ +#define SYS_SLIST_FOR_EACH_CONTAINER(__sl, __cn, __n) \ + for (__cn = SYS_SLIST_PEEK_HEAD_CONTAINER(__sl, __cn, __n); __cn; \ + __cn = SYS_SLIST_PEEK_NEXT_CONTAINER(__cn, __n)) + +/** + * @brief Provide the primitive to safely iterate on a list under a container + * Note: __cn can be detached, it will not break the loop. + * + * User _MUST_ add the loop statement curly braces enclosing its own code: + * + * SYS_SLIST_FOR_EACH_NODE_SAFE(l, c, cn, n) { + * + * } + * + * @param __sl A pointer on a sys_slist_t to iterate on + * @param __cn A pointer to peek each entry of the list + * @param __cns A pointer for the loop to run safely + * @param __n The field name of sys_node_t within the container struct + */ +#define SYS_SLIST_FOR_EACH_CONTAINER_SAFE(__sl, __cn, __cns, __n) \ + for (__cn = SYS_SLIST_PEEK_HEAD_CONTAINER(__sl, __cn, __n), \ + __cns = SYS_SLIST_PEEK_NEXT_CONTAINER(__cn, __n); __cn; \ + __cn = __cns, __cns = SYS_SLIST_PEEK_NEXT_CONTAINER(__cn, __n)) + +/** + * @brief Initialize a list + * + * @param list A pointer on the list to initialize + */ +static inline void sys_slist_init(sys_slist_t *list) +{ + list->head = NULL; + list->tail = NULL; +} + +#define SYS_SLIST_STATIC_INIT(ptr_to_list) {NULL, NULL} + +/** + * @brief Test if the given list is empty + * + * @param list A pointer on the list to test + * + * @return a boolean, true if it's empty, false otherwise + */ +static inline bool sys_slist_is_empty(sys_slist_t *list) +{ + return (!list->head); +} + +/** + * @brief Peek the first node from the list + * + * @param list A point on the list to peek the first node from + * + * @return A pointer on the first node of the list (or NULL if none) + */ +static inline sys_snode_t *sys_slist_peek_head(sys_slist_t *list) +{ + return list->head; +} + +/** + * @brief Peek the last node from the list + * + * @param list A point on the list to peek the last node from + * + * @return A pointer on the last node of the list (or NULL if none) + */ +static inline sys_snode_t *sys_slist_peek_tail(sys_slist_t *list) +{ + return list->tail; +} + +/** + * @brief Peek the next node from current node, node is not NULL + * + * Faster then sys_slist_peek_next() if node is known not to be NULL. + * + * @param node A pointer on the node where to peek the next node + * + * @return a pointer on the next node (or NULL if none) + */ +static inline sys_snode_t *sys_slist_peek_next_no_check(sys_snode_t *node) +{ + return node->next; +} + +/** + * @brief Peek the next node from current node + * + * @param node A pointer on the node where to peek the next node + * + * @return a pointer on the next node (or NULL if none) + */ +static inline sys_snode_t *sys_slist_peek_next(sys_snode_t *node) +{ + return node ? sys_slist_peek_next_no_check(node) : NULL; +} + +/** + * @brief Prepend a node to the given list + * + * This and other sys_slist_*() functions are not thread safe. + * + * @param list A pointer on the list to affect + * @param node A pointer on the node to prepend + */ +static inline void sys_slist_prepend(sys_slist_t *list, + sys_snode_t *node) +{ + node->next = list->head; + list->head = node; + + if (!list->tail) { + list->tail = list->head; + } +} + +/** + * @brief Append a node to the given list + * + * This and other sys_slist_*() functions are not thread safe. + * + * @param list A pointer on the list to affect + * @param node A pointer on the node to append + */ +static inline void sys_slist_append(sys_slist_t *list, + sys_snode_t *node) +{ + node->next = NULL; + + if (!list->tail) { + list->tail = node; + list->head = node; + } else { + list->tail->next = node; + list->tail = node; + } +} + +/** + * @brief Append a list to the given list + * + * Append a singly-linked, NULL-terminated list consisting of nodes containing + * the pointer to the next node as the first element of a node, to @a list. + * This and other sys_slist_*() functions are not thread safe. + * + * @param list A pointer on the list to affect + * @param head A pointer to the first element of the list to append + * @param tail A pointer to the last element of the list to append + */ +static inline void sys_slist_append_list(sys_slist_t *list, + void *head, void *tail) +{ + if (!list->tail) { + list->head = (sys_snode_t *)head; + list->tail = (sys_snode_t *)tail; + } else { + list->tail->next = (sys_snode_t *)head; + list->tail = (sys_snode_t *)tail; + } +} + +/** + * @brief merge two slists, appending the second one to the first + * + * When the operation is completed, the appending list is empty. + * This and other sys_slist_*() functions are not thread safe. + * + * @param list A pointer on the list to affect + * @param list_to_append A pointer to the list to append. + */ +static inline void sys_slist_merge_slist(sys_slist_t *list, + sys_slist_t *list_to_append) +{ + sys_slist_append_list(list, list_to_append->head, + list_to_append->tail); + sys_slist_init(list_to_append); +} + +/** + * @brief Insert a node to the given list + * + * This and other sys_slist_*() functions are not thread safe. + * + * @param list A pointer on the list to affect + * @param prev A pointer on the previous node + * @param node A pointer on the node to insert + */ +static inline void sys_slist_insert(sys_slist_t *list, + sys_snode_t *prev, + sys_snode_t *node) +{ + if (!prev) { + sys_slist_prepend(list, node); + } else if (!prev->next) { + sys_slist_append(list, node); + } else { + node->next = prev->next; + prev->next = node; + } +} + +/** + * @brief Fetch and remove the first node of the given list + * + * List must be known to be non-empty. + * This and other sys_slist_*() functions are not thread safe. + * + * @param list A pointer on the list to affect + * + * @return A pointer to the first node of the list + */ +static inline sys_snode_t *sys_slist_get_not_empty(sys_slist_t *list) +{ + sys_snode_t *node = list->head; + + list->head = node->next; + if (list->tail == node) { + list->tail = list->head; + } + + return node; +} + +/** + * @brief Fetch and remove the first node of the given list + * + * This and other sys_slist_*() functions are not thread safe. + * + * @param list A pointer on the list to affect + * + * @return A pointer to the first node of the list (or NULL if empty) + */ +static inline sys_snode_t *sys_slist_get(sys_slist_t *list) +{ + return sys_slist_is_empty(list) ? NULL : sys_slist_get_not_empty(list); +} + +/** + * @brief Remove a node + * + * This and other sys_slist_*() functions are not thread safe. + * + * @param list A pointer on the list to affect + * @param prev_node A pointer on the previous node + * (can be NULL, which means the node is the list's head) + * @param node A pointer on the node to remove + */ +static inline void sys_slist_remove(sys_slist_t *list, + sys_snode_t *prev_node, + sys_snode_t *node) +{ + if (!prev_node) { + list->head = node->next; + + /* Was node also the tail? */ + if (list->tail == node) { + list->tail = list->head; + } + } else { + prev_node->next = node->next; + + /* Was node the tail? */ + if (list->tail == node) { + list->tail = prev_node; + } + } + + node->next = NULL; +} + +/** + * @brief Find and remove a node from a list + * + * This and other sys_slist_*() functions are not thread safe. + * + * @param list A pointer on the list to affect + * @param node A pointer on the node to remove from the list + * + * @return true if node was removed + */ +static inline bool sys_slist_find_and_remove(sys_slist_t *list, + sys_snode_t *node) +{ + sys_snode_t *prev = NULL; + sys_snode_t *test; + + SYS_SLIST_FOR_EACH_NODE(list, test) { + if (test == node) { + sys_slist_remove(list, prev, node); + return true; + } + + prev = test; + } + + return false; +} + + +#ifdef __cplusplus +} +#endif + +#endif /* __SLIST_H__ */ diff --git a/libesp32/NimBLE-Arduino/src/mesh/testing.h b/libesp32/NimBLE-Arduino/src/mesh/testing.h new file mode 100644 index 000000000..4c2b2a619 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/mesh/testing.h @@ -0,0 +1,105 @@ +/** + * @file testing.h + * @brief Internal API for Bluetooth testing. + */ + +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __BT_TESTING_H +#define __BT_TESTING_H + +#include "slist.h" +#include "glue.h" +#include "access.h" + +/** + * @brief Bluetooth testing + * @defgroup bt_test_cb Bluetooth testing callbacks + * @ingroup bluetooth + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Bluetooth Testing callbacks structure. + * + * Callback structure to be used for Bluetooth testing purposes. + * Allows access to Bluetooth stack internals, not exposed by public API. + */ +struct bt_test_cb { + void (*mesh_net_recv)(u8_t ttl, u8_t ctl, u16_t src, u16_t dst, + const void *payload, size_t payload_len); + void (*mesh_model_bound)(u16_t addr, struct bt_mesh_model *model, + u16_t key_idx); + void (*mesh_model_unbound)(u16_t addr, struct bt_mesh_model *model, + u16_t key_idx); + void (*mesh_prov_invalid_bearer)(u8_t opcode); + void (*mesh_trans_incomp_timer_exp)(void); + + sys_snode_t node; +}; + +/** Register callbacks for Bluetooth testing purposes + * + * @param cb bt_test_cb callback structure + */ +void bt_test_cb_register(struct bt_test_cb *cb); + +/** Unregister callbacks for Bluetooth testing purposes + * + * @param cb bt_test_cb callback structure + */ +void bt_test_cb_unregister(struct bt_test_cb *cb); + +/** Send Friend Subscription List Add message. + * + * Used by Low Power node to send the group address for which messages are to + * be stored by Friend node. + * + * @param group Group address + * + * @return Zero on success or (negative) error code otherwise. + */ +int bt_test_mesh_lpn_group_add(u16_t group); + +/** Send Friend Subscription List Remove message. + * + * Used by Low Power node to remove the group addresses from Friend node + * subscription list. Messages sent to those addresses will not be stored + * by Friend node. + * + * @param groups Group addresses + * @param groups_count Group addresses count + * + * @return Zero on success or (negative) error code otherwise. + */ +int bt_test_mesh_lpn_group_remove(u16_t *groups, size_t groups_count); + +/** Clear replay protection list cache. + * + * @return Zero on success or (negative) error code otherwise. + */ +int bt_test_mesh_rpl_clear(void); + +u8_t mod_bind(struct bt_mesh_model *model, u16_t key_idx); +u8_t mod_unbind(struct bt_mesh_model *model, u16_t key_idx, bool store); +int cmd_mesh_init(int argc, char *argv[]); + +int bt_test_shell_init(void); +int bt_test_bind_app_key_to_model(struct bt_mesh_model *model, u16_t key_idx, u16_t id); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __BT_TESTING_H */ diff --git a/libesp32/NimBLE-Arduino/src/modlog/modlog.h b/libesp32/NimBLE-Arduino/src/modlog/modlog.h new file mode 100644 index 000000000..e81ea3812 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/modlog/modlog.h @@ -0,0 +1,124 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_MODLOG_ +#define H_MODLOG_ + +#include + +#include "log/log.h" + +#ifdef ESP_PLATFORM +#include "esp_log.h" +#include +#include +#endif + +#define MODLOG_MODULE_DFLT 255 + +#if (MYNEWT_VAL(LOG_LEVEL) > 0) +static inline void +modlog_dummy(const char *msg, ...) +{ + (void)msg; +} +#endif + +#ifdef ESP_PLATFORM +#define MODLOG_ESP_LOCAL(level, ml_msg_, ...) do { \ + if (LOG_LOCAL_LEVEL >= level) esp_log_write(level, "NimBLE", ml_msg_, ##__VA_ARGS__); \ +} while(0) + +#ifdef ARDUINO_ARCH_ESP32 +#include "nimconfig.h" +#endif + +#if defined(ARDUINO_ARCH_ESP32) && defined(CONFIG_BT_NIMBLE_DEBUG) + +#define MODLOG_DEBUG(ml_mod_, ml_msg_, ...) \ + MODLOG_ESP_LOCAL(ESP_LOG_ERROR, ml_msg_, ##__VA_ARGS__) + +#define MODLOG_INFO(ml_mod_, ml_msg_, ...) \ + MODLOG_ESP_LOCAL(ESP_LOG_ERROR, ml_msg_, ##__VA_ARGS__) + +#define MODLOG_WARN(ml_mod_, ml_msg_, ...) \ + MODLOG_ESP_LOCAL(ESP_LOG_ERROR, ml_msg_, ##__VA_ARGS__) + +#else + +#define MODLOG_DEBUG(ml_mod_, ml_msg_, ...) \ + MODLOG_ESP_LOCAL(ESP_LOG_DEBUG, ml_msg_, ##__VA_ARGS__) + +#define MODLOG_INFO(ml_mod_, ml_msg_, ...) \ + MODLOG_ESP_LOCAL(ESP_LOG_INFO, ml_msg_, ##__VA_ARGS__) + +#define MODLOG_WARN(ml_mod_, ml_msg_, ...) \ + MODLOG_ESP_LOCAL(ESP_LOG_WARN, ml_msg_, ##__VA_ARGS__) + +#endif + +#define MODLOG_ERROR(ml_mod_, ml_msg_, ...) \ + MODLOG_ESP_LOCAL(ESP_LOG_ERROR, ml_msg_, ##__VA_ARGS__) + +#define MODLOG_CRITICAL(ml_mod_, ml_msg_, ...) \ + MODLOG_ESP_LOCAL(ESP_LOG_ERROR, ml_msg_, ##__VA_ARGS__) + +#else + +#if (MYNEWT_VAL(LOG_LEVEL) > 1) +#define MODLOG_INFO(ml_mod_, ml_msg_, ...) \ + modlog_dummy((ml_msg_), ##__VA_ARGS__) +#else +#define MODLOG_INFO(ml_mod_, ml_msg_, ...) \ + printf((ml_msg_), ##__VA_ARGS__); +#endif + +#if (MYNEWT_VAL(LOG_LEVEL) > 2) +#define MODLOG_WARN(ml_mod_, ml_msg_, ...) \ + modlog_dummy((ml_msg_), ##__VA_ARGS__) +#else +#define MODLOG_WARN(ml_mod_, ml_msg_, ...) \ + printf((ml_msg_), ##__VA_ARGS__); +#endif + +#if (MYNEWT_VAL(LOG_LEVEL) > 3) +#define MODLOG_ERROR(ml_mod_, ml_msg_, ...) \ + modlog_dummy((ml_msg_), ##__VA_ARGS__) +#else +#define MODLOG_ERROR(ml_mod_, ml_msg_, ...) \ + printf((ml_msg_), ##__VA_ARGS__); +#endif + +#if (MYNEWT_VAL(LOG_LEVEL) > 4) +#define MODLOG_CRITICAL(ml_mod_, ml_msg_, ...) \ + modlog_dummy((ml_msg_), ##__VA_ARGS__) +#else +#define MODLOG_CRITICAL(ml_mod_, ml_msg_, ...) \ + printf((ml_msg_), ##__VA_ARGS__); +#endif + +#endif + +#define MODLOG(ml_lvl_, ml_mod_, ...) \ + MODLOG_ ## ml_lvl_((ml_mod_), __VA_ARGS__) + +#define MODLOG_DFLT(ml_lvl_, ...) \ + MODLOG(ml_lvl_, LOG_MODULE_DEFAULT, __VA_ARGS__) + +#endif diff --git a/libesp32/NimBLE-Arduino/src/nimble/ble.h b/libesp32/NimBLE-Arduino/src/nimble/ble.h new file mode 100644 index 000000000..1d726958d --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/ble.h @@ -0,0 +1,290 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_BLE_ +#define H_BLE_ + +#include +#include +#include "syscfg/syscfg.h" +#include "os/os.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* The number of advertising instances */ +#define BLE_ADV_INSTANCES (MYNEWT_VAL(BLE_MULTI_ADV_INSTANCES) + 1) + +/* BLE encryption block definitions */ +#define BLE_ENC_BLOCK_SIZE (16) + +/* 4 byte header + 251 byte payload. */ +#define BLE_ACL_MAX_PKT_SIZE 255 + +struct ble_encryption_block +{ + uint8_t key[BLE_ENC_BLOCK_SIZE]; + uint8_t plain_text[BLE_ENC_BLOCK_SIZE]; + uint8_t cipher_text[BLE_ENC_BLOCK_SIZE]; +}; + +/* + * BLE MBUF structure: + * + * The BLE mbuf structure is as follows. Note that this structure applies to + * the packet header mbuf (not mbufs that are part of a "packet chain"): + * struct os_mbuf (16) + * struct os_mbuf_pkthdr (8) + * struct ble_mbuf_hdr (8) + * Data buffer (payload size, in bytes) + * + * The BLE mbuf header contains the following: + * flags: bitfield with the following values + * 0x01: Set if there was a match on the whitelist + * 0x02: Set if a connect request was transmitted upon receiving pdu + * 0x04: Set the first time we transmit the PDU (used to detect retry). + * channel: The logical BLE channel PHY channel # (0 - 39) + * crcok: flag denoting CRC check passed (1) or failed (0). + * rssi: RSSI, in dBm. + */ +struct ble_mbuf_hdr_rxinfo +{ + uint16_t flags; + uint8_t channel; + uint8_t handle; + int8_t rssi; + /* XXX: we could just use single phy_mode field */ + int8_t phy; + uint8_t phy_mode; +#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) + void *user_data; +#endif +}; + +/* Flag definitions for rxinfo */ +#define BLE_MBUF_HDR_F_INITA_RESOLVED (0x2000) +#define BLE_MBUF_HDR_F_EXT_ADV_SEC (0x1000) +#define BLE_MBUF_HDR_F_EXT_ADV (0x0800) +#define BLE_MBUF_HDR_F_RESOLVED (0x0400) +#define BLE_MBUF_HDR_F_AUX_PTR_WAIT (0x0200) +#define BLE_MBUF_HDR_F_AUX_INVALID (0x0100) +#define BLE_MBUF_HDR_F_CRC_OK (0x0080) +#define BLE_MBUF_HDR_F_DEVMATCH (0x0040) +#define BLE_MBUF_HDR_F_MIC_FAILURE (0x0020) +#define BLE_MBUF_HDR_F_SCAN_RSP_TXD (0x0010) +#define BLE_MBUF_HDR_F_SCAN_RSP_CHK (0x0008) +#define BLE_MBUF_HDR_F_RXSTATE_MASK (0x0007) + +/* Transmit info. NOTE: no flags defined */ +struct ble_mbuf_hdr_txinfo +{ + uint8_t flags; + uint8_t offset; + uint8_t pyld_len; + uint8_t hdr_byte; +}; + +struct ble_mbuf_hdr +{ + union { + struct ble_mbuf_hdr_rxinfo rxinfo; + struct ble_mbuf_hdr_txinfo txinfo; + }; + uint32_t beg_cputime; + uint32_t rem_usecs; +}; + +#define BLE_MBUF_HDR_EXT_ADV_SEC(hdr) \ + (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_EXT_ADV_SEC)) + +#define BLE_MBUF_HDR_EXT_ADV(hdr) \ + (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_EXT_ADV)) + +#define BLE_MBUF_HDR_DEVMATCH(hdr) \ + (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_DEVMATCH)) + +#define BLE_MBUF_HDR_SCAN_RSP_RCV(hdr) \ + (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_SCAN_RSP_CHK)) + +#define BLE_MBUF_HDR_AUX_INVALID(hdr) \ + (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_AUX_INVALID)) + +#define BLE_MBUF_HDR_WAIT_AUX(hdr) \ + (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_AUX_PTR_WAIT)) + +#define BLE_MBUF_HDR_CRC_OK(hdr) \ + (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_CRC_OK)) + +#define BLE_MBUF_HDR_MIC_FAILURE(hdr) \ + (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_MIC_FAILURE)) + +#define BLE_MBUF_HDR_RESOLVED(hdr) \ + (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_RESOLVED)) + +#define BLE_MBUF_HDR_INITA_RESOLVED(hdr) \ + (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_INITA_RESOLVED)) + +#define BLE_MBUF_HDR_RX_STATE(hdr) \ + ((uint8_t)((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_RXSTATE_MASK)) + +#define BLE_MBUF_HDR_PTR(om) \ + (struct ble_mbuf_hdr *)((uint8_t *)om + sizeof(struct os_mbuf) + \ + sizeof(struct os_mbuf_pkthdr)) + +/* BLE mbuf overhead per packet header mbuf */ +#define BLE_MBUF_PKTHDR_OVERHEAD \ + (sizeof(struct os_mbuf_pkthdr) + sizeof(struct ble_mbuf_hdr)) + +#define BLE_MBUF_MEMBLOCK_OVERHEAD \ + (sizeof(struct os_mbuf) + BLE_MBUF_PKTHDR_OVERHEAD) + +/* Length of host user header. Only contains the peer's connection handle. */ +#define BLE_MBUF_HS_HDR_LEN (2) + +#define BLE_DEV_ADDR_LEN (6) +extern uint8_t g_dev_addr[BLE_DEV_ADDR_LEN]; +extern uint8_t g_random_addr[BLE_DEV_ADDR_LEN]; + +/* BLE Error Codes (Core v4.2 Vol 2 part D) */ +enum ble_error_codes +{ + /* An "error" code of 0x0 means success */ + BLE_ERR_SUCCESS = 0x00, + BLE_ERR_UNKNOWN_HCI_CMD = 0x01, + BLE_ERR_UNK_CONN_ID = 0x02, + BLE_ERR_HW_FAIL = 0x03, + BLE_ERR_PAGE_TMO = 0x04, + BLE_ERR_AUTH_FAIL = 0x05, + BLE_ERR_PINKEY_MISSING = 0x06, + BLE_ERR_MEM_CAPACITY = 0x07, + BLE_ERR_CONN_SPVN_TMO = 0x08, + BLE_ERR_CONN_LIMIT = 0x09, + BLE_ERR_SYNCH_CONN_LIMIT = 0x0a, + BLE_ERR_ACL_CONN_EXISTS = 0x0b, + BLE_ERR_CMD_DISALLOWED = 0x0c, + BLE_ERR_CONN_REJ_RESOURCES = 0x0d, + BLE_ERR_CONN_REJ_SECURITY = 0x0e, + BLE_ERR_CONN_REJ_BD_ADDR = 0x0f, + BLE_ERR_CONN_ACCEPT_TMO = 0x10, + BLE_ERR_UNSUPPORTED = 0x11, + BLE_ERR_INV_HCI_CMD_PARMS = 0x12, + BLE_ERR_REM_USER_CONN_TERM = 0x13, + BLE_ERR_RD_CONN_TERM_RESRCS = 0x14, + BLE_ERR_RD_CONN_TERM_PWROFF = 0x15, + BLE_ERR_CONN_TERM_LOCAL = 0x16, + BLE_ERR_REPEATED_ATTEMPTS = 0x17, + BLE_ERR_NO_PAIRING = 0x18, + BLE_ERR_UNK_LMP = 0x19, + BLE_ERR_UNSUPP_REM_FEATURE = 0x1a, + BLE_ERR_SCO_OFFSET = 0x1b, + BLE_ERR_SCO_ITVL = 0x1c, + BLE_ERR_SCO_AIR_MODE = 0x1d, + BLE_ERR_INV_LMP_LL_PARM = 0x1e, + BLE_ERR_UNSPECIFIED = 0x1f, + BLE_ERR_UNSUPP_LMP_LL_PARM = 0x20, + BLE_ERR_NO_ROLE_CHANGE = 0x21, + BLE_ERR_LMP_LL_RSP_TMO = 0x22, + BLE_ERR_LMP_COLLISION = 0x23, + BLE_ERR_LMP_PDU = 0x24, + BLE_ERR_ENCRYPTION_MODE = 0x25, + BLE_ERR_LINK_KEY_CHANGE = 0x26, + BLE_ERR_UNSUPP_QOS = 0x27, + BLE_ERR_INSTANT_PASSED = 0x28, + BLE_ERR_UNIT_KEY_PAIRING = 0x29, + BLE_ERR_DIFF_TRANS_COLL = 0x2a, + /* BLE_ERR_RESERVED = 0x2b */ + BLE_ERR_QOS_PARM = 0x2c, + BLE_ERR_QOS_REJECTED = 0x2d, + BLE_ERR_CHAN_CLASS = 0x2e, + BLE_ERR_INSUFFICIENT_SEC = 0x2f, + BLE_ERR_PARM_OUT_OF_RANGE = 0x30, + /* BLE_ERR_RESERVED = 0x31 */ + BLE_ERR_PENDING_ROLE_SW = 0x32, + /* BLE_ERR_RESERVED = 0x33 */ + BLE_ERR_RESERVED_SLOT = 0x34, + BLE_ERR_ROLE_SW_FAIL = 0x35, + BLE_ERR_INQ_RSP_TOO_BIG = 0x36, + BLE_ERR_SEC_SIMPLE_PAIR = 0x37, + BLE_ERR_HOST_BUSY_PAIR = 0x38, + BLE_ERR_CONN_REJ_CHANNEL = 0x39, + BLE_ERR_CTLR_BUSY = 0x3a, + BLE_ERR_CONN_PARMS = 0x3b, + BLE_ERR_DIR_ADV_TMO = 0x3c, + BLE_ERR_CONN_TERM_MIC = 0x3d, + BLE_ERR_CONN_ESTABLISHMENT = 0x3e, + BLE_ERR_MAC_CONN_FAIL = 0x3f, + BLE_ERR_COARSE_CLK_ADJ = 0x40, + BLE_ERR_TYPE0_SUBMAP_NDEF = 0x41, + BLE_ERR_UNK_ADV_INDENT = 0x42, + BLE_ERR_LIMIT_REACHED = 0x43, + BLE_ERR_OPERATION_CANCELLED = 0x44, + BLE_ERR_MAX = 0xff +}; + +int ble_err_from_os(int os_err); + +/* HW error codes */ +#define BLE_HW_ERR_DO_NOT_USE (0) /* XXX: reserve this one for now */ +#define BLE_HW_ERR_HCI_SYNC_LOSS (1) + +/* Own Bluetooth Device address type */ +#define BLE_OWN_ADDR_PUBLIC (0x00) +#define BLE_OWN_ADDR_RANDOM (0x01) +#define BLE_OWN_ADDR_RPA_PUBLIC_DEFAULT (0x02) +#define BLE_OWN_ADDR_RPA_RANDOM_DEFAULT (0x03) + +/* Bluetooth Device address type */ +#define BLE_ADDR_PUBLIC (0x00) +#define BLE_ADDR_RANDOM (0x01) +#define BLE_ADDR_PUBLIC_ID (0x02) +#define BLE_ADDR_RANDOM_ID (0x03) + +#define BLE_ADDR_ANY (&(ble_addr_t) { 0, {0, 0, 0, 0, 0, 0} }) + +#define BLE_ADDR_IS_RPA(addr) (((addr)->type == BLE_ADDR_RANDOM) && \ + ((addr)->val[5] & 0xc0) == 0x40) +#define BLE_ADDR_IS_NRPA(addr) (((addr)->type == BLE_ADDR_RANDOM) && \ + ((addr)->val[5] & 0xc0) == 0x00) +#define BLE_ADDR_IS_STATIC(addr) (((addr)->type == BLE_ADDR_RANDOM) && \ + ((addr)->val[5] & 0xc0) == 0xc0) + +typedef struct { + uint8_t type; + uint8_t val[6]; +} ble_addr_t; + + +static inline int ble_addr_cmp(const ble_addr_t *a, const ble_addr_t *b) +{ + int type_diff; + + type_diff = a->type - b->type; + if (type_diff != 0) { + return type_diff; + } + + return memcmp(a->val, b->val, sizeof(a->val)); +} + +#ifdef __cplusplus +} +#endif + +#endif /* H_BLE_ */ diff --git a/libesp32/NimBLE-Arduino/src/nimble/ble_hci_trans.h b/libesp32/NimBLE-Arduino/src/nimble/ble_hci_trans.h new file mode 100644 index 000000000..e8d3ec031 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/ble_hci_trans.h @@ -0,0 +1,192 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_HCI_TRANSPORT_ +#define H_HCI_TRANSPORT_ + +#include +#include "os/os_mempool.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct os_mbuf; + +#define BLE_HCI_TRANS_CMD_SZ 260 + +/*** Type of buffers for holding commands and events. */ +/** + * Controller-to-host event buffers. Events have one of two priorities: + * o Low-priority (BLE_HCI_TRANS_BUF_EVT_LO) + * o High-priority (BLE_HCI_TRANS_BUF_EVT_HI) + * + * Low-priority event buffers are only used for advertising reports. If there + * are no free low-priority event buffers, then an incoming advertising report + * will get dropped. + * + * High-priority event buffers are for everything except advertising reports. + * If there are no free high-priority event buffers, a request to allocate one + * will try to allocate a low-priority buffer instead. + * + * If you want all events to be given equal treatment, then you should allocate + * low-priority events only. + * + * Event priorities solve the problem of critical events getting dropped due to + * a flood of advertising reports. This solution is likely temporary: when + * HCI flow control is added, event priorities may become obsolete. + * + * Not all transports distinguish between low and high priority events. If the + * transport does not have separate settings for low and high buffer counts, + * then it treats all events with equal priority. + */ +#define BLE_HCI_TRANS_BUF_EVT_LO 1 +#define BLE_HCI_TRANS_BUF_EVT_HI 2 + +/* Host-to-controller command. */ +#define BLE_HCI_TRANS_BUF_CMD 3 + +/** Callback function types; executed when HCI packets are received. */ +typedef int ble_hci_trans_rx_cmd_fn(uint8_t *cmd, void *arg); +typedef int ble_hci_trans_rx_acl_fn(struct os_mbuf *om, void *arg); + +/** + * Sends an HCI event from the controller to the host. + * + * @param cmd The HCI event to send. This buffer must be + * allocated via ble_hci_trans_buf_alloc(). + * + * @return 0 on success; + * A BLE_ERR_[...] error code on failure. + */ +int ble_hci_trans_ll_evt_tx(uint8_t *hci_ev); + +/** + * Sends ACL data from controller to host. + * + * @param om The ACL data packet to send. + * + * @return 0 on success; + * A BLE_ERR_[...] error code on failure. + */ +int ble_hci_trans_ll_acl_tx(struct os_mbuf *om); + +/** + * Sends an HCI command from the host to the controller. + * + * @param cmd The HCI command to send. This buffer must be + * allocated via ble_hci_trans_buf_alloc(). + * + * @return 0 on success; + * A BLE_ERR_[...] error code on failure. + */ +int ble_hci_trans_hs_cmd_tx(uint8_t *cmd); + +/** + * Sends ACL data from host to controller. + * + * @param om The ACL data packet to send. + * + * @return 0 on success; + * A BLE_ERR_[...] error code on failure. + */ +int ble_hci_trans_hs_acl_tx(struct os_mbuf *om); + +/** + * Allocates a flat buffer of the specified type. + * + * @param type The type of buffer to allocate; one of the + * BLE_HCI_TRANS_BUF_[...] constants. + * + * @return The allocated buffer on success; + * NULL on buffer exhaustion. + */ +uint8_t *ble_hci_trans_buf_alloc(int type); + +/** + * Frees the specified flat buffer. The buffer must have been allocated via + * ble_hci_trans_buf_alloc(). + * + * @param buf The buffer to free. + */ +void ble_hci_trans_buf_free(uint8_t *buf); + +/** + * Configures a callback to get executed whenever an ACL data packet is freed. + * The function is called immediately before the free occurs. + * + * @param cb The callback to configure. + * @param arg An optional argument to pass to the callback. + * + * @return 0 on success; + * BLE_ERR_UNSUPPORTED if the transport does not + * support this operation. + */ +int ble_hci_trans_set_acl_free_cb(os_mempool_put_fn *cb, void *arg); + +/** + * Configures the HCI transport to operate with a controller. The transport + * will execute specified callbacks upon receiving HCI packets from the host. + * + * @param cmd_cb The callback to execute upon receiving an HCI + * command. + * @param cmd_arg Optional argument to pass to the command + * callback. + * @param acl_cb The callback to execute upon receiving ACL + * data. + * @param acl_arg Optional argument to pass to the ACL + * callback. + */ +void ble_hci_trans_cfg_ll(ble_hci_trans_rx_cmd_fn *cmd_cb, + void *cmd_arg, + ble_hci_trans_rx_acl_fn *acl_cb, + void *acl_arg); + +/** + * Configures the HCI transport to operate with a host. The transport will + * execute specified callbacks upon receiving HCI packets from the controller. + * + * @param evt_cb The callback to execute upon receiving an HCI + * event. + * @param evt_arg Optional argument to pass to the event + * callback. + * @param acl_cb The callback to execute upon receiving ACL + * data. + * @param acl_arg Optional argument to pass to the ACL + * callback. + */ +void ble_hci_trans_cfg_hs(ble_hci_trans_rx_cmd_fn *evt_cb, + void *evt_arg, + ble_hci_trans_rx_acl_fn *acl_cb, + void *acl_arg); + +/** + * Resets the HCI module to a clean state. Frees all buffers and reinitializes + * the underlying transport. + * + * @return 0 on success; + * A BLE_ERR_[...] error code on failure. + */ +int ble_hci_trans_reset(void); + +#ifdef __cplusplus +} +#endif + +#endif /* H_HCI_TRANSPORT_ */ diff --git a/libesp32/NimBLE-Arduino/src/nimble/hci_common.h b/libesp32/NimBLE-Arduino/src/nimble/hci_common.h new file mode 100644 index 000000000..1b049c88b --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/hci_common.h @@ -0,0 +1,1254 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_BLE_HCI_COMMON_ +#define H_BLE_HCI_COMMON_ + +#include "ble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * HCI Command Header + * + * Comprises the following fields + * -> Opcode group field & Opcode command field (2) + * -> Parameter Length (1) + * Length of all the parameters (does not include any part of the hci + * command header + */ +#define BLE_HCI_CMD_HDR_LEN (3) + +#define BLE_HCI_OPCODE_NOP (0) + +/* Set opcode based on OCF and OGF */ +#define BLE_HCI_OP(ogf, ocf) ((ocf) | ((ogf) << 10)) + +/* Get the OGF and OCF from the opcode in the command */ +#define BLE_HCI_OGF(opcode) (((opcode) >> 10) & 0x003F) +#define BLE_HCI_OCF(opcode) ((opcode) & 0x03FF) + +/* Opcode Group definitions (note: 0x07 not defined in spec) */ +#define BLE_HCI_OGF_LINK_CTRL (0x01) +#define BLE_HCI_OGF_LINK_POLICY (0x02) +#define BLE_HCI_OGF_CTLR_BASEBAND (0x03) +#define BLE_HCI_OGF_INFO_PARAMS (0x04) +#define BLE_HCI_OGF_STATUS_PARAMS (0x05) +#define BLE_HCI_OGF_TESTING (0x06) +#define BLE_HCI_OGF_LE (0x08) +#define BLE_HCI_OGF_VENDOR (0x3F) + +/* + * Number of LE commands. NOTE: this is really just used to size the array + * containing the lengths of the LE commands. + */ +#define BLE_HCI_NUM_LE_CMDS (79) + +/* List of OCF for Link Control commands (OGF=0x01) */ +#define BLE_HCI_OCF_DISCONNECT_CMD (0x0006) +#define BLE_HCI_OCF_RD_REM_VER_INFO (0x001D) + +/* List of OCF for Controller and Baseband commands (OGF=0x03) */ +#define BLE_HCI_OCF_CB_SET_EVENT_MASK (0x0001) +#define BLE_HCI_OCF_CB_RESET (0x0003) +#define BLE_HCI_OCF_CB_READ_TX_PWR (0x002D) +#define BLE_HCI_OCF_CB_SET_CTLR_TO_HOST_FC (0x0031) +#define BLE_HCI_OCF_CB_HOST_BUF_SIZE (0x0033) +#define BLE_HCI_OCF_CB_HOST_NUM_COMP_PKTS (0x0035) +#define BLE_HCI_OCF_CB_SET_EVENT_MASK2 (0x0063) +#define BLE_HCI_OCF_CB_RD_AUTH_PYLD_TMO (0x007B) +#define BLE_HCI_OCF_CB_WR_AUTH_PYLD_TMO (0x007C) + +/* List of OCF for Info Param commands (OGF=0x04) */ +#define BLE_HCI_OCF_IP_RD_LOCAL_VER (0x0001) +#define BLE_HCI_OCF_IP_RD_LOC_SUPP_CMD (0x0002) +#define BLE_HCI_OCF_IP_RD_LOC_SUPP_FEAT (0x0003) +#define BLE_HCI_OCF_IP_RD_BUF_SIZE (0x0005) +#define BLE_HCI_OCF_IP_RD_BD_ADDR (0x0009) + +/* List of OCF for Status parameters commands (OGF = 0x05) */ +#define BLE_HCI_OCF_RD_RSSI (0x0005) + +/* List of OCF for LE commands (OGF = 0x08) */ +#define BLE_HCI_OCF_LE_SET_EVENT_MASK (0x0001) +#define BLE_HCI_OCF_LE_RD_BUF_SIZE (0x0002) +#define BLE_HCI_OCF_LE_RD_LOC_SUPP_FEAT (0x0003) +/* NOTE: 0x0004 is intentionally left undefined */ +#define BLE_HCI_OCF_LE_SET_RAND_ADDR (0x0005) +#define BLE_HCI_OCF_LE_SET_ADV_PARAMS (0x0006) +#define BLE_HCI_OCF_LE_RD_ADV_CHAN_TXPWR (0x0007) +#define BLE_HCI_OCF_LE_SET_ADV_DATA (0x0008) +#define BLE_HCI_OCF_LE_SET_SCAN_RSP_DATA (0x0009) +#define BLE_HCI_OCF_LE_SET_ADV_ENABLE (0x000A) +#define BLE_HCI_OCF_LE_SET_SCAN_PARAMS (0x000B) +#define BLE_HCI_OCF_LE_SET_SCAN_ENABLE (0x000C) +#define BLE_HCI_OCF_LE_CREATE_CONN (0x000D) +#define BLE_HCI_OCF_LE_CREATE_CONN_CANCEL (0x000E) +#define BLE_HCI_OCF_LE_RD_WHITE_LIST_SIZE (0x000F) +#define BLE_HCI_OCF_LE_CLEAR_WHITE_LIST (0x0010) +#define BLE_HCI_OCF_LE_ADD_WHITE_LIST (0x0011) +#define BLE_HCI_OCF_LE_RMV_WHITE_LIST (0x0012) +#define BLE_HCI_OCF_LE_CONN_UPDATE (0x0013) +#define BLE_HCI_OCF_LE_SET_HOST_CHAN_CLASS (0x0014) +#define BLE_HCI_OCF_LE_RD_CHAN_MAP (0x0015) +#define BLE_HCI_OCF_LE_RD_REM_FEAT (0x0016) +#define BLE_HCI_OCF_LE_ENCRYPT (0x0017) +#define BLE_HCI_OCF_LE_RAND (0x0018) +#define BLE_HCI_OCF_LE_START_ENCRYPT (0x0019) +#define BLE_HCI_OCF_LE_LT_KEY_REQ_REPLY (0x001A) +#define BLE_HCI_OCF_LE_LT_KEY_REQ_NEG_REPLY (0x001B) +#define BLE_HCI_OCF_LE_RD_SUPP_STATES (0x001C) +#define BLE_HCI_OCF_LE_RX_TEST (0x001D) +#define BLE_HCI_OCF_LE_TX_TEST (0x001E) +#define BLE_HCI_OCF_LE_TEST_END (0x001F) +#define BLE_HCI_OCF_LE_REM_CONN_PARAM_RR (0x0020) +#define BLE_HCI_OCF_LE_REM_CONN_PARAM_NRR (0x0021) +#define BLE_HCI_OCF_LE_SET_DATA_LEN (0x0022) +#define BLE_HCI_OCF_LE_RD_SUGG_DEF_DATA_LEN (0x0023) +#define BLE_HCI_OCF_LE_WR_SUGG_DEF_DATA_LEN (0x0024) +#define BLE_HCI_OCF_LE_RD_P256_PUBKEY (0x0025) +#define BLE_HCI_OCF_LE_GEN_DHKEY (0x0026) +#define BLE_HCI_OCF_LE_ADD_RESOLV_LIST (0x0027) +#define BLE_HCI_OCF_LE_RMV_RESOLV_LIST (0x0028) +#define BLE_HCI_OCF_LE_CLR_RESOLV_LIST (0x0029) +#define BLE_HCI_OCF_LE_RD_RESOLV_LIST_SIZE (0x002A) +#define BLE_HCI_OCF_LE_RD_PEER_RESOLV_ADDR (0x002B) +#define BLE_HCI_OCF_LE_RD_LOCAL_RESOLV_ADDR (0x002C) +#define BLE_HCI_OCF_LE_SET_ADDR_RES_EN (0x002D) +#define BLE_HCI_OCF_LE_SET_RPA_TMO (0x002E) +#define BLE_HCI_OCF_LE_RD_MAX_DATA_LEN (0x002F) +#define BLE_HCI_OCF_LE_RD_PHY (0x0030) +#define BLE_HCI_OCF_LE_SET_DEFAULT_PHY (0x0031) +#define BLE_HCI_OCF_LE_SET_PHY (0x0032) +#define BLE_HCI_OCF_LE_ENH_RX_TEST (0x0033) +#define BLE_HCI_OCF_LE_ENH_TX_TEST (0x0034) +#define BLE_HCI_OCF_LE_SET_ADV_SET_RND_ADDR (0x0035) +#define BLE_HCI_OCF_LE_SET_EXT_ADV_PARAM (0x0036) +#define BLE_HCI_OCF_LE_SET_EXT_ADV_DATA (0x0037) +#define BLE_HCI_OCF_LE_SET_EXT_SCAN_RSP_DATA (0x0038) +#define BLE_HCI_OCF_LE_SET_EXT_ADV_ENABLE (0x0039) +#define BLE_HCI_OCF_LE_RD_MAX_ADV_DATA_LEN (0x003A) +#define BLE_HCI_OCF_LE_RD_NUM_OF_ADV_SETS (0x003B) +#define BLE_HCI_OCF_LE_REMOVE_ADV_SET (0x003C) +#define BLE_HCI_OCF_LE_CLEAR_ADV_SETS (0x003D) +#define BLE_HCI_OCF_LE_SET_PERIODIC_ADV_PARAMS (0x003E) +#define BLE_HCI_OCF_LE_SET_PERIODIC_ADV_DATA (0x003F) +#define BLE_HCI_OCF_LE_SET_PERIODIC_ADV_ENABLE (0x0040) +#define BLE_HCI_OCF_LE_SET_EXT_SCAN_PARAM (0x0041) +#define BLE_HCI_OCF_LE_SET_EXT_SCAN_ENABLE (0x0042) +#define BLE_HCI_OCF_LE_EXT_CREATE_CONN (0x0043) +#define BLE_HCI_OCF_LE_PERIODIC_ADV_CREATE_SYNC (0x0044) +#define BLE_HCI_OCF_LE_PERIODIC_ADV_CREATE_SYNC_CANCEL (0x0045) +#define BLE_HCI_OCF_LE_PERIODIC_ADV_TERM_SYNC (0x0046) +#define BLE_HCI_OCF_LE_ADD_DEV_TO_PERIODIC_ADV_LIST (0x0047) +#define BLE_HCI_OCF_LE_REM_DEV_FROM_PERIODIC_ADV_LIST (0x0048) +#define BLE_HCI_OCF_LE_CLEAR_PERIODIC_ADV_LIST (0x0049) +#define BLE_HCI_OCF_LE_RD_PERIODIC_ADV_LIST_SIZE (0x004A) +#define BLE_HCI_OCF_LE_RD_TRANSMIT_POWER (0x004B) +#define BLE_HCI_OCF_LE_RD_RF_PATH_COMPENSATION (0x004C) +#define BLE_HCI_OCF_LE_WR_RF_PATH_COMPENSATION (0x004D) +#define BLE_HCI_OCF_LE_SET_PRIVACY_MODE (0x004E) + +/* Command Specific Definitions */ +#define BLE_HCI_VARIABLE_LEN (0xFF) + +/* --- Disconnect command (OGF 0x01, OCF 0x0006) --- */ +#define BLE_HCI_DISCONNECT_CMD_LEN (3) + +/* --- Set event mask (OGF 0x03, OCF 0x0001 --- */ +#define BLE_HCI_SET_EVENT_MASK_LEN (8) + +/* --- Set controller to host flow control (OGF 0x03, OCF 0x0031) --- */ +#define BLE_HCI_CTLR_TO_HOST_FC_LEN (1) + +#define BLE_HCI_CTLR_TO_HOST_FC_OFF (0) +#define BLE_HCI_CTLR_TO_HOST_FC_ACL (1) +#define BLE_HCI_CTLR_TO_HOST_FC_SYNC (2) +#define BLE_HCI_CTLR_TO_HOST_FC_BOTH (3) + +/* --- Host buffer size (OGF 0x03, OCF 0x0033) --- */ +#define BLE_HCI_HOST_BUF_SIZE_LEN (7) + +/* --- Host number of completed packets (OGF 0x03, OCF 0x0035) --- */ +#define BLE_HCI_HOST_NUM_COMP_PKTS_HDR_LEN (1) +#define BLE_HCI_HOST_NUM_COMP_PKTS_ENT_LEN (4) + +/* --- Read BD_ADDR (OGF 0x04, OCF 0x0009 --- */ +#define BLE_HCI_IP_RD_BD_ADDR_ACK_PARAM_LEN (6) + +/* --- Read buffer size (OGF 0x04, OCF 0x0005) --- */ +#define BLE_HCI_IP_RD_BUF_SIZE_LEN (0) +#define BLE_HCI_IP_RD_BUF_SIZE_RSPLEN (7) /* No status byte. */ + +/* --- Read/Write authenticated payload timeout (ocf 0x007B/0x007C) */ +#define BLE_HCI_RD_AUTH_PYLD_TMO_LEN (4) +#define BLE_HCI_WR_AUTH_PYLD_TMO_LEN (2) + +/* --- Read local version information (OGF 0x04, OCF 0x0001) --- */ +#define BLE_HCI_RD_LOC_VER_INFO_RSPLEN (8) /* No status byte. */ + +/* --- Read local supported command (OGF 0x04, OCF 0x0002) --- */ +#define BLE_HCI_RD_LOC_SUPP_CMD_RSPLEN (64) /* No status byte. */ + +/* --- Read local supported features (OGF 0x04, OCF 0x0003) --- */ +#define BLE_HCI_RD_LOC_SUPP_FEAT_RSPLEN (8) /* No status byte. */ + +/* --- Read RSSI (OGF 0x05, OCF 0x0005) --- */ +#define BLE_HCI_READ_RSSI_LEN (2) +#define BLE_HCI_READ_RSSI_ACK_PARAM_LEN (3) /* No status byte. */ + +/* --- LE set event mask (OCF 0x0001) --- */ +#define BLE_HCI_SET_LE_EVENT_MASK_LEN (8) + +/* --- LE read buffer size (OCF 0x0002) --- */ +#define BLE_HCI_RD_BUF_SIZE_LEN (0) +#define BLE_HCI_RD_BUF_SIZE_RSPLEN (3) /* No status byte. */ + +/* --- LE read local supported features (OCF 0x0003) --- */ +#define BLE_HCI_RD_LE_LOC_SUPP_FEAT_RSPLEN (8) /* No status byte. */ + +/* --- LE set random address (OCF 0x0005) */ +#define BLE_HCI_SET_RAND_ADDR_LEN (6) + +/* --- LE set advertising parameters (OCF 0x0006) */ +#define BLE_HCI_SET_ADV_PARAM_LEN (15) + +/* Advertising types */ +#define BLE_HCI_ADV_TYPE_ADV_IND (0) +#define BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD (1) +#define BLE_HCI_ADV_TYPE_ADV_SCAN_IND (2) +#define BLE_HCI_ADV_TYPE_ADV_NONCONN_IND (3) +#define BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_LD (4) +#define BLE_HCI_ADV_TYPE_MAX (4) + +#define BLE_HCI_ADV_CONN_MASK (0x0001) +#define BLE_HCI_ADV_SCAN_MASK (0x0002) +#define BLE_HCI_ADV_DIRECT_MASK (0x0004) +#define BLE_HCI_ADV_SCAN_RSP_MASK (0x0008) +#define BLE_HCI_ADV_LEGACY_MASK (0x0010) + +#define BLE_HCI_ADV_DATA_STATUS_COMPLETE (0x0000) +#define BLE_HCI_ADV_DATA_STATUS_INCOMPLETE (0x0020) +#define BLE_HCI_ADV_DATA_STATUS_TRUNCATED (0x0040) +#define BLE_HCI_ADV_DATA_STATUS_MASK (0x0060) + +/* Own address types */ +#define BLE_HCI_ADV_OWN_ADDR_PUBLIC (0) +#define BLE_HCI_ADV_OWN_ADDR_RANDOM (1) +#define BLE_HCI_ADV_OWN_ADDR_PRIV_PUB (2) +#define BLE_HCI_ADV_OWN_ADDR_PRIV_RAND (3) +#define BLE_HCI_ADV_OWN_ADDR_MAX (3) + +/* Advertisement peer address Type */ +#define BLE_HCI_ADV_PEER_ADDR_PUBLIC (0) +#define BLE_HCI_ADV_PEER_ADDR_RANDOM (1) +#define BLE_HCI_ADV_PEER_ADDR_MAX (1) + +/* --- LE advertising channel tx power (OCF 0x0007) */ +#define BLE_HCI_ADV_CHAN_TXPWR_ACK_PARAM_LEN (2) /* Includes status byte. */ +#define BLE_HCI_ADV_CHAN_TXPWR_MIN (-20) +#define BLE_HCI_ADV_CHAN_TXPWR_MAX (10) + +/* --- LE set advertising data (OCF 0x0008) */ +#define BLE_HCI_MAX_ADV_DATA_LEN (31) +#define BLE_HCI_SET_ADV_DATA_LEN (32) + +/* --- LE set scan response data (OCF 0x0009) */ +#define BLE_HCI_MAX_SCAN_RSP_DATA_LEN (31) +#define BLE_HCI_SET_SCAN_RSP_DATA_LEN (32) + +/* --- LE set advertising enable (OCF 0x000a) */ +#define BLE_HCI_SET_ADV_ENABLE_LEN (1) + +/* --- LE set scan enable (OCF 0x000c) */ +#define BLE_HCI_SET_SCAN_ENABLE_LEN (2) + +/* Connect peer address type */ +#define BLE_HCI_CONN_PEER_ADDR_PUBLIC (0) +#define BLE_HCI_CONN_PEER_ADDR_RANDOM (1) +#define BLE_HCI_CONN_PEER_ADDR_PUBLIC_IDENT (2) +#define BLE_HCI_CONN_PEER_ADDR_RANDOM_IDENT (3) +#define BLE_HCI_CONN_PEER_ADDR_MAX (3) + +/* + * Advertising filter policy + * + * Determines how an advertiser filters scan and connection requests. + * + * NONE: no filtering (default value). No whitelist used. + * SCAN: process all connection requests but only scans from white list. + * CONN: process all scan request but only connection requests from white list + * BOTH: ignore all scan and connection requests unless in white list. + */ +#define BLE_HCI_ADV_FILT_NONE (0) +#define BLE_HCI_ADV_FILT_SCAN (1) +#define BLE_HCI_ADV_FILT_CONN (2) +#define BLE_HCI_ADV_FILT_BOTH (3) +#define BLE_HCI_ADV_FILT_MAX (3) + +#define BLE_HCI_ADV_FILT_DEF (BLE_HCI_ADV_FILT_NONE) + +/* Advertising interval */ +#define BLE_HCI_ADV_ITVL (625) /* usecs */ +#define BLE_HCI_ADV_ITVL_MIN (32) /* units */ +#define BLE_HCI_ADV_ITVL_MAX (16384) /* units */ +#define BLE_HCI_ADV_ITVL_NONCONN_MIN (160) /* units */ + +#define BLE_HCI_ADV_ITVL_DEF (0x800) /* 1.28 seconds */ +#define BLE_HCI_ADV_CHANMASK_DEF (0x7) /* all channels */ + +/* Set scan parameters */ +#define BLE_HCI_SET_SCAN_PARAM_LEN (7) +#define BLE_HCI_SCAN_TYPE_PASSIVE (0) +#define BLE_HCI_SCAN_TYPE_ACTIVE (1) + +/* Scan interval and scan window timing */ +#define BLE_HCI_SCAN_ITVL (625) /* usecs */ +#define BLE_HCI_SCAN_ITVL_MIN (4) /* units */ +#define BLE_HCI_SCAN_ITVL_MAX (16384) /* units */ +#define BLE_HCI_SCAN_ITVL_DEF (16) /* units */ +#define BLE_HCI_SCAN_WINDOW_MIN (4) /* units */ +#define BLE_HCI_SCAN_WINDOW_MAX (16384) /* units */ +#define BLE_HCI_SCAN_WINDOW_DEF (16) /* units */ + +/* + * Scanning filter policy + * NO_WL: + * Scanner processes all advertising packets (white list not used) except + * directed, connectable advertising packets not sent to the scanner. + * USE_WL: + * Scanner processes advertisements from white list only. A connectable, + * directed advertisment is ignored unless it contains scanners address. + * NO_WL_INITA: + * Scanner process all advertising packets (white list not used). A + * connectable, directed advertisement shall not be ignored if the InitA + * is a resolvable private address. + * USE_WL_INITA: + * Scanner process advertisements from white list only. A connectable, + * directed advertisement shall not be ignored if the InitA is a + * resolvable private address. + */ +#define BLE_HCI_SCAN_FILT_NO_WL (0) +#define BLE_HCI_SCAN_FILT_USE_WL (1) +#define BLE_HCI_SCAN_FILT_NO_WL_INITA (2) +#define BLE_HCI_SCAN_FILT_USE_WL_INITA (3) +#define BLE_HCI_SCAN_FILT_MAX (3) + +/* Whitelist commands */ +#define BLE_HCI_ADD_WHITE_LIST_LEN (7) +#define BLE_HCI_RMV_WHITE_LIST_LEN (7) + +/* Create Connection */ +#define BLE_HCI_CREATE_CONN_LEN (25) +#define BLE_HCI_CONN_ITVL (1250) /* usecs */ +#define BLE_HCI_CONN_FILT_NO_WL (0) +#define BLE_HCI_CONN_FILT_USE_WL (1) +#define BLE_HCI_CONN_FILT_MAX (1) +#define BLE_HCI_CONN_ITVL_MIN (0x0006) +#define BLE_HCI_CONN_ITVL_MAX (0x0c80) +#define BLE_HCI_CONN_LATENCY_MIN (0x0000) +#define BLE_HCI_CONN_LATENCY_MAX (0x01f3) +#define BLE_HCI_CONN_SPVN_TIMEOUT_MIN (0x000a) +#define BLE_HCI_CONN_SPVN_TIMEOUT_MAX (0x0c80) +#define BLE_HCI_CONN_SPVN_TMO_UNITS (10) /* msecs */ +#define BLE_HCI_INITIATOR_FILT_POLICY_MAX (1) + +/* Peer Address Type */ +#define BLE_HCI_CONN_PEER_ADDR_PUBLIC (0) +#define BLE_HCI_CONN_PEER_ADDR_RANDOM (1) +#define BLE_HCI_CONN_PEER_ADDR_PUB_ID (2) +#define BLE_HCI_CONN_PEER_ADDR_RAND_ID (3) +#define BLE_HCI_CONN_PEER_ADDR_MAX (3) + +/* --- LE connection update (OCF 0x0013) */ +#define BLE_HCI_CONN_UPDATE_LEN (14) + +/* --- LE set host channel classification command (OCF 0x0014) */ +#define BLE_HCI_SET_HOST_CHAN_CLASS_LEN (5) + +/* --- LE read channel map command (OCF 0x0015) */ +#define BLE_HCI_RD_CHANMAP_LEN (2) +#define BLE_HCI_RD_CHANMAP_RSP_LEN (7) + +/* --- LE read remote features (OCF 0x0016) */ +#define BLE_HCI_CONN_RD_REM_FEAT_LEN (2) + +/* --- LE encrypt (OCF 0x0017) */ +#define BLE_HCI_LE_ENCRYPT_LEN (32) + +/* --- LE rand (OCF 0x0018) */ +#define BLE_HCI_LE_RAND_LEN (8) + +/* --- LE start encryption (OCF 0x0019) */ +#define BLE_HCI_LE_START_ENCRYPT_LEN (28) + +/* --- LE long term key request reply command (OCF 0x001a) */ +#define BLE_HCI_LT_KEY_REQ_REPLY_LEN (18) +#define BLE_HCI_LT_KEY_REQ_REPLY_ACK_PARAM_LEN (2) /* No status byte. */ + +/* --- LE long term key request negative reply command (OCF 0x001b) */ +#define BLE_HCI_LT_KEY_REQ_NEG_REPLY_LEN (2) +#define BLE_HCI_LT_KEY_REQ_NEG_REPLY_ACK_PARAM_LEN (2) + +/* --- LE read supported states (OCF 0x001C) --- */ +#define BLE_HCI_RD_SUPP_STATES_RSPLEN (8) + +/* --- LE receiver test command (OCF 0x001D) --- */ +#define BLE_HCI_RX_TEST_LEN (1) + +/* --- LE transitter test command (OCF 0x001E) --- */ +#define BLE_HCI_TX_TEST_LEN (3) + +/* --- LE remote connection parameter request reply (OCF 0x0020) */ +#define BLE_HCI_CONN_PARAM_REPLY_LEN (14) + +/* --- LE remote connection parameter request negative reply (OCF 0x0021) */ +#define BLE_HCI_CONN_PARAM_NEG_REPLY_LEN (3) + +/* --- LE set data length (OCF 0x0022) */ +#define BLE_HCI_SET_DATALEN_LEN (6) +#define BLE_HCI_SET_DATALEN_ACK_PARAM_LEN (2) /* No status byte. */ +#define BLE_HCI_SET_DATALEN_TX_OCTETS_MIN (0x001b) +#define BLE_HCI_SET_DATALEN_TX_OCTETS_MAX (0x00fb) +#define BLE_HCI_SET_DATALEN_TX_TIME_MIN (0x0148) +#define BLE_HCI_SET_DATALEN_TX_TIME_MAX (0x4290) + +/* --- LE read suggested default data length (OCF 0x0023) */ +#define BLE_HCI_RD_SUGG_DATALEN_RSPLEN (4) + +/* --- LE write suggested default data length (OCF 0x0024) */ +#define BLE_HCI_WR_SUGG_DATALEN_LEN (4) + +/* --- LE generate DHKEY command (OCF 0x0026) */ +#define BLE_HCI_GEN_DHKEY_LEN (64) + +/* --- LE add device to resolving list (OCF 0x0027) */ +#define BLE_HCI_ADD_TO_RESOLV_LIST_LEN (39) + +/* --- LE add device to resolving list (OCF 0x0028) */ +#define BLE_HCI_RMV_FROM_RESOLV_LIST_LEN (7) + +/* --- LE read peer resolvable address (OCF 0x002B) */ +#define BLE_HCI_RD_PEER_RESOLV_ADDR_LEN (7) + +/* --- LE read peer resolvable address (OCF 0x002C) */ +#define BLE_HCI_RD_LOC_RESOLV_ADDR_LEN (7) + +/* --- LE set address resolution enable (OCF 0x002D) */ +#define BLE_HCI_SET_ADDR_RESOL_ENA_LEN (1) + +/* --- LE set resolvable private address timeout (OCF 0x002E) */ +#define BLE_HCI_SET_RESOLV_PRIV_ADDR_TO_LEN (2) + +/* --- LE read maximum data length (OCF 0x002F) */ +#define BLE_HCI_RD_MAX_DATALEN_RSPLEN (8) + +/* --- LE read maximum default PHY (OCF 0x0030) */ +#define BLE_HCI_LE_RD_PHY_LEN (2) +#define BLE_HCI_LE_RD_PHY_RSPLEN (4) +#define BLE_HCI_LE_PHY_1M (1) +#define BLE_HCI_LE_PHY_2M (2) +#define BLE_HCI_LE_PHY_CODED (3) + +/* --- LE set default PHY (OCF 0x0031) */ +#define BLE_HCI_LE_SET_DEFAULT_PHY_LEN (3) +#define BLE_HCI_LE_PHY_NO_TX_PREF_MASK (0x01) +#define BLE_HCI_LE_PHY_NO_RX_PREF_MASK (0x02) +#define BLE_HCI_LE_PHY_1M_PREF_MASK (0x01) +#define BLE_HCI_LE_PHY_2M_PREF_MASK (0x02) +#define BLE_HCI_LE_PHY_CODED_PREF_MASK (0x04) + +#define BLE_HCI_LE_PHY_PREF_MASK_ALL \ + (BLE_HCI_LE_PHY_1M_PREF_MASK | BLE_HCI_LE_PHY_2M_PREF_MASK | \ + BLE_HCI_LE_PHY_CODED_PREF_MASK) + +/* --- LE set PHY (OCF 0x0032) */ +#define BLE_HCI_LE_SET_PHY_LEN (7) +#define BLE_HCI_LE_PHY_CODED_ANY (0x0000) +#define BLE_HCI_LE_PHY_CODED_S2_PREF (0x0001) +#define BLE_HCI_LE_PHY_CODED_S8_PREF (0x0002) + +/* --- LE enhanced receiver test (OCF 0x0033) */ +#define BLE_HCI_LE_ENH_RX_TEST_LEN (3) +#define BLE_HCI_LE_PHY_1M (1) +#define BLE_HCI_LE_PHY_2M (2) +#define BLE_HCI_LE_PHY_CODED (3) + +/* --- LE enhanced transmitter test (OCF 0x0034) */ +#define BLE_HCI_LE_ENH_TX_TEST_LEN (4) +#define BLE_HCI_LE_PHY_CODED_S8 (3) +#define BLE_HCI_LE_PHY_CODED_S2 (4) + +/* --- LE set advertising set random address (OCF 0x0035) */ +#define BLE_HCI_LE_SET_ADV_SET_RND_ADDR_LEN (7) + +/* --- LE set extended advertising parameters (OCF 0x0036) */ +#define BLE_HCI_LE_SET_EXT_ADV_PARAM_LEN (25) +#define BLE_HCI_LE_SET_EXT_ADV_PROP_CONNECTABLE (0x0001) +#define BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE (0x0002) +#define BLE_HCI_LE_SET_EXT_ADV_PROP_DIRECTED (0x0004) +#define BLE_HCI_LE_SET_EXT_ADV_PROP_HD_DIRECTED (0x0008) +#define BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY (0x0010) +#define BLE_HCI_LE_SET_EXT_ADV_PROP_ANON_ADV (0x0020) +#define BLE_HCI_LE_SET_EXT_ADV_PROP_INC_TX_PWR (0x0040) +#define BLE_HCI_LE_SET_EXT_ADV_PROP_MASK (0x7F) + +#define BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY_IND (0x0013) +#define BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY_LD_DIR (0x0015) +#define BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY_HD_DIR (0x001d) +#define BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY_SCAN (0x0012) +#define BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY_NONCONN (0x0010) + +/* --- LE set extended advertising data (OCF 0x0037) */ +#define BLE_HCI_MAX_EXT_ADV_DATA_LEN (251) +#define BLE_HCI_SET_EXT_ADV_DATA_HDR_LEN (4) + +#define BLE_HCI_LE_SET_EXT_ADV_DATA_LEN BLE_HCI_VARIABLE_LEN +#define BLE_HCI_LE_SET_DATA_OPER_INT (0) +#define BLE_HCI_LE_SET_DATA_OPER_FIRST (1) +#define BLE_HCI_LE_SET_DATA_OPER_LAST (2) +#define BLE_HCI_LE_SET_DATA_OPER_COMPLETE (3) +#define BLE_HCI_LE_SET_DATA_OPER_UNCHANGED (4) + +/* --- LE set extended scan response data (OCF 0x0038) */ +#define BLE_HCI_MAX_EXT_SCAN_RSP_DATA_LEN (251) +#define BLE_HCI_SET_EXT_SCAN_RSP_DATA_HDR_LEN (4) + +#define BLE_HCI_LE_SET_EXT_SCAN_RSP_DATA_LEN BLE_HCI_VARIABLE_LEN + + +/* --- LE set extended advertising enable (OCF 0x0039) */ +#define BLE_HCI_LE_SET_EXT_ADV_ENABLE_LEN BLE_HCI_VARIABLE_LEN + +/* --- LE remove advertising set (OCF 0x003C) */ +#define BLE_HCI_LE_REMOVE_ADV_SET_LEN (1) + +/* --- LE read maximum advertising data length (OCF 0x003A) */ +#define BLE_HCI_RD_MAX_ADV_DATA_LEN (2) + +/* --- LE read number of supported advertising sets (OCF 0x003B) */ +#define BLE_HCI_RD_NR_SUP_ADV_SETS (1) + +/* --- LE set periodic advertising parameters (OCF 0x003E) */ +#define BLE_HCI_LE_SET_PERIODIC_ADV_PARAMS_LEN (7) +#define BLE_HCI_LE_SET_PERIODIC_ADV_PROP_INC_TX_PWR (0x0040) +#define BLE_HCI_LE_SET_PERIODIC_ADV_PROP_MASK (0x0040) + +/* --- LE set periodic advertising data (OCF 0x003F) */ +#define BLE_HCI_LE_SET_PERIODIC_ADV_DATA_LEN BLE_HCI_VARIABLE_LEN +#define BLE_HCI_MAX_PERIODIC_ADV_DATA_LEN (252) +#define BLE_HCI_SET_PERIODIC_ADV_DATA_HDR_LEN (3) + +/* --- LE periodic advertising enable (OCF 0x0040) */ +#define BLE_HCI_LE_SET_PERIODIC_ADV_ENABLE_LEN (2) + +/* --- LE set extended scan parameters (OCF 0x0041) */ +#define BLE_HCI_LE_SET_EXT_SCAN_PARAM_LEN BLE_HCI_VARIABLE_LEN +#define BLE_HCI_LE_EXT_SCAN_BASE_LEN (3) +#define BLE_HCI_LE_EXT_SCAN_SINGLE_PARAM_LEN (5) + +/* --- LE set extended scan enable (OCF 0x0042) */ +#define BLE_HCI_LE_SET_EXT_SCAN_ENABLE_LEN (6) + +/* --- LE extended create connection (OCF 0x0043) */ +#define BLE_HCI_LE_EXT_CREATE_CONN_LEN BLE_HCI_VARIABLE_LEN +#define BLE_HCI_LE_EXT_CREATE_CONN_BASE_LEN (10) + +/* --- LE periodic advertising create sync (OCF 0x0044) */ +#define BLE_HCI_LE_PERIODIC_ADV_CREATE_SYNC_LEN (14) + +/* --- LE periodic advertising terminate (OCF 0x0046) */ +#define BLE_HCI_LE_PERIODIC_ADV_TERM_SYNC_LEN (2) + +/* --- LE add device to periodic advertising list (OCF 0x0047) */ +#define BLE_HCI_LE_ADD_DEV_TO_PERIODIC_ADV_LIST_LEN (8) + +/* --- LE remove device from periodic advertising list (OCF 0x0048) */ +#define BLE_HCI_LE_REM_DEV_FROM_PERIODIC_ADV_LIST_LEN (8) + +#define BLE_HCI_PERIODIC_DATA_STATUS_COMPLETE 0x00 +#define BLE_HCI_PERIODIC_DATA_STATUS_INCOMPLETE 0x01 +#define BLE_HCI_PERIODIC_DATA_STATUS_TRUNCATED 0x02 + +/* --- LE write RF path (OCF 0x004D) */ +#define BLE_HCI_LE_WR_RF_PATH_COMPENSATION_LEN (4) + +/* --- LE set privacy mode (OCF 0x004E) */ +#define BLE_HCI_LE_SET_PRIVACY_MODE_LEN (8) +#define BLE_HCI_PRIVACY_NETWORK (0) +#define BLE_HCI_PRIVACY_DEVICE (1) + +/* Event Codes */ +#define BLE_HCI_EVCODE_INQUIRY_CMP (0x01) +#define BLE_HCI_EVCODE_INQUIRY_RESULT (0x02) +#define BLE_HCI_EVCODE_CONN_DONE (0x03) +#define BLE_HCI_EVCODE_CONN_REQUEST (0x04) +#define BLE_HCI_EVCODE_DISCONN_CMP (0x05) +#define BLE_HCI_EVCODE_AUTH_CMP (0x06) +#define BLE_HCI_EVCODE_REM_NAME_REQ_CMP (0x07) +#define BLE_HCI_EVCODE_ENCRYPT_CHG (0x08) +#define BLE_HCI_EVCODE_CHG_LINK_KEY_CMP (0x09) +#define BLE_HCI_EVCODE_MASTER_LINK_KEY_CMP (0x0A) +#define BLE_HCI_EVCODE_RD_REM_SUPP_FEAT_CMP (0x0B) +#define BLE_HCI_EVCODE_RD_REM_VER_INFO_CMP (0x0C) +#define BLE_HCI_EVCODE_QOS_SETUP_CMP (0x0D) +#define BLE_HCI_EVCODE_COMMAND_COMPLETE (0x0E) +#define BLE_HCI_EVCODE_COMMAND_STATUS (0x0F) +#define BLE_HCI_EVCODE_HW_ERROR (0x10) +#define BLE_HCI_EVCODE_NUM_COMP_PKTS (0x13) +#define BLE_HCI_EVCODE_MODE_CHANGE (0x14) +#define BLE_HCI_EVCODE_RETURN_LINK_KEYS (0x15) +#define BLE_HCI_EVCODE_PIN_CODE_REQ (0x16) +#define BLE_HCI_EVCODE_LINK_KEY_REQ (0x17) +#define BLE_HCI_EVCODE_LINK_KEY_NOTIFY (0x18) +#define BLE_HCI_EVCODE_LOOPBACK_CMD (0x19) +#define BLE_HCI_EVCODE_DATA_BUF_OVERFLOW (0x1A) +#define BLE_HCI_EVCODE_MAX_SLOTS_CHG (0x1B) +#define BLE_HCI_EVCODE_READ_CLK_OFF_COMP (0x1C) +#define BLE_HCI_EVCODE_CONN_PKT_TYPE_CHG (0x1D) +#define BLE_HCI_EVCODE_QOS_VIOLATION (0x1E) +/* NOTE: 0x1F not defined */ +#define BLE_HCI_EVCODE_PSR_MODE_CHG (0x20) +#define BLE_HCI_EVCODE_FLOW_SPEC_COMP (0x21) +#define BLE_HCI_EVCODE_INQ_RESULT_RSSI (0x22) +#define BLE_HCI_EVCODE_READ_REM_EXT_FEAT (0x23) +/* NOTE: 0x24 - 0x2B not defined */ +#define BLE_HCI_EVCODE_SYNCH_CONN_COMP (0x2C) +#define BLE_HCI_EVCODE_SYNCH_CONN_CHG (0x2D) +#define BLE_HCI_EVCODE_SNIFF_SUBRATING (0x2E) +#define BLE_HCI_EVCODE_EXT_INQ_RESULT (0x2F) +#define BLE_HCI_EVCODE_ENC_KEY_REFRESH (0x30) +#define BLE_HCI_EVOCDE_IO_CAP_REQ (0x31) +#define BLE_HCI_EVCODE_IO_CAP_RSP (0x32) +#define BLE_HCI_EVCODE_USER_CONFIRM_REQ (0x33) +#define BLE_HCI_EVCODE_PASSKEY_REQ (0x34) +#define BLE_HCI_EVCODE_REM_OOB_DATA_REQ (0x35) +#define BLE_HCI_EVCODE_SIMPLE_PAIR_COMP (0x36) +/* NOTE: 0x37 not defined */ +#define BLE_HCI_EVCODE_LNK_SPVN_TMO_CHG (0x38) +#define BLE_HCI_EVCODE_ENH_FLUSH_COMP (0x39) +#define BLE_HCI_EVCODE_USER_PASSKEY_NOTIFY (0x3B) +#define BLE_HCI_EVCODE_KEYPRESS_NOTIFY (0x3C) +#define BLE_HCI_EVCODE_REM_HOST_SUPP_FEAT (0x3D) +#define BLE_HCI_EVCODE_LE_META (0x3E) +/* NOTE: 0x3F not defined */ +#define BLE_HCI_EVCODE_PHYS_LINK_COMP (0x40) +#define BLE_HCI_EVCODE_CHAN_SELECTED (0x41) +#define BLE_HCI_EVCODE_DISCONN_PHYS_LINK (0x42) +#define BLE_HCI_EVCODE_PHYS_LINK_LOSS_EARLY (0x43) +#define BLE_HCI_EVCODE_PHYS_LINK_RECOVERY (0x44) +#define BLE_HCI_EVCODE_LOGICAL_LINK_COMP (0x45) +#define BLE_HCI_EVCODE_DISCONN_LOGICAL_LINK (0x46) +#define BLE_HCI_EVCODE_FLOW_SPEC_MODE_COMP (0x47) +#define BLE_HCI_EVCODE_NUM_COMP_DATA_BLKS (0x48) +#define BLE_HCI_EVCODE_AMP_START_TEST (0x49) +#define BLE_HCI_EVOCDE_AMP_TEST_END (0x4A) +#define BLE_HCI_EVOCDE_AMP_RCVR_REPORT (0x4B) +#define BLE_HCI_EVCODE_SHORT_RANGE_MODE_CHG (0x4C) +#define BLE_HCI_EVCODE_AMP_STATUS_CHG (0x4D) +#define BLE_HCI_EVCODE_TRIG_CLK_CAPTURE (0x4E) +#define BLE_HCI_EVCODE_SYNCH_TRAIN_COMP (0x4F) +#define BLE_HCI_EVCODE_SYNCH_TRAIN_RCVD (0x50) +#define BLE_HCI_EVCODE_SLAVE_BCAST_RX (0x51) +#define BLE_HCI_EVCODE_SLAVE_BCAST_TMO (0x52) +#define BLE_HCI_EVCODE_TRUNC_PAGE_COMP (0x53) +#define BLE_HCI_EVCODE_SLAVE_PAGE_RSP_TMO (0x54) +#define BLE_HCI_EVCODE_SLAVE_BCAST_CHAN_MAP (0x55) +#define BLE_HCI_EVCODE_INQ_RSP_NOTIFY (0x56) +#define BLE_HCI_EVCODE_AUTH_PYLD_TMO (0x57) +#define BLE_HCI_EVCODE_VENDOR_DEBUG (0xFF) + +/* LE sub-event codes */ +#define BLE_HCI_LE_SUBEV_CONN_COMPLETE (0x01) +#define BLE_HCI_LE_SUBEV_ADV_RPT (0x02) +#define BLE_HCI_LE_SUBEV_CONN_UPD_COMPLETE (0x03) +#define BLE_HCI_LE_SUBEV_RD_REM_USED_FEAT (0x04) +#define BLE_HCI_LE_SUBEV_LT_KEY_REQ (0x05) +#define BLE_HCI_LE_SUBEV_REM_CONN_PARM_REQ (0x06) +#define BLE_HCI_LE_SUBEV_DATA_LEN_CHG (0x07) +#define BLE_HCI_LE_SUBEV_RD_LOC_P256_PUBKEY (0x08) +#define BLE_HCI_LE_SUBEV_GEN_DHKEY_COMPLETE (0x09) +#define BLE_HCI_LE_SUBEV_ENH_CONN_COMPLETE (0x0A) +#define BLE_HCI_LE_SUBEV_DIRECT_ADV_RPT (0x0B) +#define BLE_HCI_LE_SUBEV_PHY_UPDATE_COMPLETE (0x0C) +#define BLE_HCI_LE_SUBEV_EXT_ADV_RPT (0x0D) +#define BLE_HCI_LE_SUBEV_PERIODIC_ADV_SYNC_ESTAB (0x0E) +#define BLE_HCI_LE_SUBEV_PERIODIC_ADV_RPT (0x0F) +#define BLE_HCI_LE_SUBEV_PERIODIC_ADV_SYNC_LOST (0x10) +#define BLE_HCI_LE_SUBEV_SCAN_TIMEOUT (0x11) +#define BLE_HCI_LE_SUBEV_ADV_SET_TERMINATED (0x12) +#define BLE_HCI_LE_SUBEV_SCAN_REQ_RCVD (0x13) +#define BLE_HCI_LE_SUBEV_CHAN_SEL_ALG (0x14) + +/* Generic event header */ +#define BLE_HCI_EVENT_HDR_LEN (2) + +/* Event specific definitions */ +/* Event disconnect complete */ +#define BLE_HCI_EVENT_DISCONN_COMPLETE_LEN (4) + +/* Event encryption change (code=0x08) */ +#define BLE_HCI_EVENT_ENCRYPT_CHG_LEN (4) + +/* Event hardware error (code=0x10) */ +#define BLE_HCI_EVENT_HW_ERROR_LEN (1) + +/* Event key refresh complete (code=0x30) */ +#define BLE_HCI_EVENT_ENC_KEY_REFRESH_LEN (3) + +/* Event command complete */ +#define BLE_HCI_EVENT_CMD_COMPLETE_HDR_LEN (5) +#define BLE_HCI_EVENT_CMD_COMPLETE_MIN_LEN (6) + +/* Event command status */ +#define BLE_HCI_EVENT_CMD_STATUS_LEN (6) + +/* Number of completed packets */ +#define BLE_HCI_EVENT_NUM_COMP_PKTS_HDR_LEN (1) +#define BLE_HCI_EVENT_NUM_COMP_PKTS_ENT_LEN (4) + +/* Read remote version informaton */ +#define BLE_HCI_EVENT_RD_RM_VER_LEN (8) + +/* Data buffer overflow event */ +#define BLE_HCI_EVENT_DATABUF_OVERFLOW_LEN (1) +#define BLE_HCI_EVENT_ACL_BUF_OVERFLOW (0x01) + +/* Advertising report */ +#define BLE_HCI_ADV_RPT_EVTYPE_ADV_IND (0) +#define BLE_HCI_ADV_RPT_EVTYPE_DIR_IND (1) +#define BLE_HCI_ADV_RPT_EVTYPE_SCAN_IND (2) +#define BLE_HCI_ADV_RPT_EVTYPE_NONCONN_IND (3) +#define BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP (4) + +/* Bluetooth 5, Vol 2, Part E, 7.7.65.13 */ +#define BLE_HCI_LEGACY_ADV_EVTYPE_ADV_IND (0x13) +#define BLE_HCI_LEGACY_ADV_EVTYPE_ADV_DIRECT_IND (0x15) +#define BLE_HCI_LEGACY_ADV_EVTYPE_ADV_SCAN_IND (0x12) +#define BLE_HCI_LEGACY_ADV_EVTYPE_ADV_NONCON_IND (0x10) +#define BLE_HCI_LEGACY_ADV_EVTYPE_SCAN_RSP_ADV_IND (0x1b) +#define BLE_HCI_LEGACY_ADV_EVTYPE_SCAN_RSP_ADV_SCAN_IND (0x1a) + +/* LE sub-event specific definitions */ +#define BLE_HCI_LE_MIN_LEN (1) /* Not including event hdr. */ + +/* LE connection complete event (sub event 0x01) */ +#define BLE_HCI_LE_CONN_COMPLETE_LEN (19) +#define BLE_HCI_LE_CONN_COMPLETE_ROLE_MASTER (0x00) +#define BLE_HCI_LE_CONN_COMPLETE_ROLE_SLAVE (0x01) + +/* Maximum valid connection handle value */ +#define BLE_HCI_LE_CONN_HANDLE_MAX (0x0eff) + +/* LE advertising report event. (sub event 0x02) */ +#define BLE_HCI_LE_ADV_RPT_MIN_LEN (12) +#define BLE_HCI_LE_ADV_DIRECT_RPT_LEN (18) +#define BLE_HCI_LE_ADV_RPT_NUM_RPTS_MIN (1) +#define BLE_HCI_LE_ADV_RPT_NUM_RPTS_MAX (0x19) + +/* Length of each record in an LE direct advertising report event. */ +#define BLE_HCI_LE_ADV_DIRECT_RPT_SUB_LEN (16) + +/* LE connection update complete event (sub event 0x03) */ +#define BLE_HCI_LE_CONN_UPD_LEN (10) + +/* LE long term key request event (sub event 0x05) */ +#define BLE_HCI_LE_LT_KEY_REQ_LEN (13) + +/* LE connection update complete event (sub event 0x03) */ +#define BLE_HCI_LE_RD_REM_USED_FEAT_LEN (12) + +/* LE remote connection parameter request event (sub event 0x06) */ +#define BLE_HCI_LE_REM_CONN_PARM_REQ_LEN (11) + +/* LE data length change event (sub event 0x07) */ +#define BLE_HCI_LE_DATA_LEN_CHG_LEN (11) + +/* LE PHY update complete event (sub event 0x0C) */ +#define BLE_HCI_LE_PHY_UPD_LEN (6) + +/* LE Periodic Advertising Sync Established Event (sub event 0x0e) */ +#define BLE_HCI_LE_PERIODIC_ADV_SYNC_ESTAB_LEN (16) + +/* LE Periodic Advertising Report Event (sub event 0x0f) */ +#define BLE_HCI_LE_PERIODIC_ADV_RPT_LEN (8) + +/* LE Periodic Advertising Sync Lost Event (sub event 0x10) */ +#define BLE_HCI_LE_PERIODIC_ADV_SYNC_LOST_LEN (3) + +/* LE Scan Timeout Event (sub event 0x11) */ +#define BLE_HCI_LE_SUBEV_SCAN_TIMEOUT_LEN (1) + +/* LE Advertising Set Terminated Event (sub event 0x12) */ +#define BLE_HCI_LE_SUBEV_ADV_SET_TERMINATED_LEN (6) + +/* LE Scan Request Received event (sub event 0x13) */ +#define BLE_HCI_LE_SUBEV_SCAN_REQ_RCVD_LEN (9) + +/* LE Channel Selection Algorithm event (sub event 0x14) */ +#define BLE_HCI_LE_SUBEV_CHAN_SEL_ALG_LEN (4) + +/* Bluetooth Assigned numbers for version information.*/ +#define BLE_HCI_VER_BCS_1_0b (0) +#define BLE_HCI_VER_BCS_1_1 (1) +#define BLE_HCI_VER_BCS_1_2 (2) +#define BLE_HCI_VER_BCS_2_0_EDR (3) +#define BLE_HCI_VER_BCS_2_1_EDR (4) +#define BLE_HCI_VER_BCS_3_0_HCS (5) +#define BLE_HCI_VER_BCS_4_0 (6) +#define BLE_HCI_VER_BCS_4_1 (7) +#define BLE_HCI_VER_BCS_4_2 (8) +#define BLE_HCI_VER_BCS_5_0 (9) + +#define BLE_LMP_VER_BCS_1_0b (0) +#define BLE_LMP_VER_BCS_1_1 (1) +#define BLE_LMP_VER_BCS_1_2 (2) +#define BLE_LMP_VER_BCS_2_0_EDR (3) +#define BLE_LMP_VER_BCS_2_1_EDR (4) +#define BLE_LMP_VER_BCS_3_0_HCS (5) +#define BLE_LMP_VER_BCS_4_0 (6) +#define BLE_LMP_VER_BCS_4_1 (7) +#define BLE_LMP_VER_BCS_4_2 (8) +#define BLE_LMP_VER_BCS_5_0 (9) + +/* Sub-event 0x0A: enhanced connection complete */ +#define BLE_HCI_LE_ENH_CONN_COMPLETE_LEN (31) + +/*--- Shared data structures ---*/ + +/* Host buffer size (OGF=0x03, OCF=0x0033) */ +struct hci_host_buf_size +{ + uint16_t acl_pkt_len; + uint8_t sync_pkt_len; + uint16_t num_acl_pkts; + uint16_t num_sync_pkts; +}; + +/* Host number of completed packets (OGF=0x03, OCF=0x0035) */ +struct hci_host_num_comp_pkts_entry +{ + uint16_t conn_handle; + uint16_t num_pkts; +}; + +/* Read local version information (OGF=0x0004, OCF=0x0001) */ +struct hci_loc_ver_info +{ + uint8_t status; + uint8_t hci_version; + uint16_t hci_revision; + uint8_t lmp_pal_version; + uint16_t mfrg_name; + uint8_t lmp_pal_subversion; +}; + +/* set random address command (ocf = 0x0005) */ +struct hci_rand_addr +{ + uint8_t addr[6]; +}; + +/* set advertising parameters command (ocf = 0x0006) */ +struct hci_adv_params +{ + uint8_t adv_type; + uint8_t adv_channel_map; + uint8_t own_addr_type; + uint8_t peer_addr_type; + uint8_t adv_filter_policy; + uint16_t adv_itvl_min; + uint16_t adv_itvl_max; + uint8_t peer_addr[BLE_DEV_ADDR_LEN]; +}; + +/* LE create connection command (ocf=0x000d). */ +struct hci_create_conn +{ + uint16_t scan_itvl; + uint16_t scan_window; + uint8_t filter_policy; + uint8_t peer_addr_type; + uint8_t peer_addr[BLE_DEV_ADDR_LEN]; + uint8_t own_addr_type; + uint16_t conn_itvl_min; + uint16_t conn_itvl_max; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_ce_len; + uint16_t max_ce_len; +}; + +/* LE Read Local P-256 Public Key Complete Event */ +struct hci_le_subev_rd_loc_p256_pubkey { + uint8_t status; + uint8_t pubkey[64]; +} __attribute__((packed)); + +/* LE Generate DHKey Complete Event */ +struct hci_le_subev_gen_dhkey_complete { + uint8_t status; + uint8_t dhkey[32]; +} __attribute__((packed)); + +/* LE Directed Advertising Report Event */ +struct hci_le_subev_direct_adv_rpt_param { + uint8_t evt_type; + uint8_t addr_type; + uint8_t addr[6]; + uint8_t dir_addr_type; + uint8_t dir_addr[6]; + int8_t rssi; +} __attribute__((packed)); + +struct hci_le_subev_direct_adv_rpt { + uint8_t num_reports; + struct hci_le_subev_direct_adv_rpt_param params[0]; +} __attribute__((packed)); + +#if MYNEWT_VAL(BLE_EXT_ADV) +/* LE create connection command (ocf=0x0043). */ +struct hci_ext_conn_params +{ + uint16_t scan_itvl; + uint16_t scan_window; + uint16_t conn_itvl_min; + uint16_t conn_itvl_max; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_ce_len; + uint16_t max_ce_len; +}; + +struct hci_ext_create_conn +{ + uint8_t filter_policy; + uint8_t own_addr_type; + uint8_t peer_addr_type; + uint8_t peer_addr[BLE_DEV_ADDR_LEN]; + uint8_t init_phy_mask; + struct hci_ext_conn_params params[3]; +}; + +struct hci_ext_adv_report_param { + uint16_t evt_type; + uint8_t addr_type; + uint8_t addr[6]; + uint8_t prim_phy; + uint8_t sec_phy; + uint8_t sid; + int8_t tx_power; + int8_t rssi; + uint16_t per_adv_itvl; + uint8_t dir_addr_type; + uint8_t dir_addr[6]; + uint8_t adv_data_len; + uint8_t adv_data[0]; +} __attribute__((packed)); + +struct hci_ext_adv_report { + /* We support one report per event for now */ + uint8_t subevt; + uint8_t num_reports; + struct hci_ext_adv_report_param params[0]; +} __attribute__((packed)); + +/* Ext Adv Set enable parameters, not in HCI order */ +struct hci_ext_adv_set +{ + uint8_t handle; + uint8_t events; + uint16_t duration; +}; + +/* Ext Advertising Parameters */ +struct hci_ext_adv_params +{ + uint16_t properties; + uint32_t min_interval; + uint32_t max_interval; + uint8_t chan_map; + uint8_t own_addr_type; + uint8_t peer_addr_type; + uint8_t peer_addr[6]; + uint8_t filter_policy; + int8_t tx_power; + uint8_t primary_phy; + uint8_t max_skip; + uint8_t secondary_phy; + uint8_t sid; + uint8_t scan_req_notif; +}; + +/* LE Extended Advertising Report Event */ +struct hci_le_subev_ext_adv_rpt { + uint8_t num_reports; + struct hci_ext_adv_report_param params[0]; +} __attribute__((packed)); + +#if MYNEWT_VAL(BLE_PERIODIC_ADV) +/* LE Periodic Advertising Sync Established Event */ +struct hci_le_subev_periodic_adv_sync_estab { + uint8_t status; + uint16_t sync_handle; + uint8_t sid; + uint8_t adv_addr_type; + uint8_t adv_addr[6]; + uint8_t adv_phy; + uint16_t per_adv_ival; + uint8_t adv_clk_accuracy; +} __attribute__((packed)); + +/* LE Periodic Advertising Report Event */ +struct hci_le_subev_periodic_adv_rpt { + uint16_t sync_handle; + int8_t tx_power; + int8_t rssi; + uint8_t unused; + uint8_t data_status; + uint8_t data_length; + uint8_t data[0]; +} __attribute__((packed)); + +/* LE Periodic Advertising Sync Lost Event */ +struct hci_le_subev_periodic_adv_sync_lost { + uint16_t sync_handle; +} __attribute__((packed)); +#endif + +/* LE Advertising Set Terminated Event */ +struct hci_le_subev_adv_set_terminated { + uint8_t status; + uint8_t adv_handle; + uint16_t conn_handle; + uint8_t num_compl_ext_adv_ev; +} __attribute__((packed)); + +/* LE Scan Request Received Event */ +struct hci_le_subev_scan_req_rcvd { + uint8_t adv_handle; + uint8_t scan_addr_type; + uint8_t scan_addr[6]; +} __attribute__((packed)); + +#endif + +/* LE Channel Selection Algorithm Event */ +struct hci_le_subev_chan_sel_alg { + uint16_t conn_handle; + uint8_t chan_sel_alg; +} __attribute__((packed)); + +/* LE connection update command (ocf=0x0013). */ +struct hci_conn_update +{ + uint16_t handle; + uint16_t conn_itvl_min; + uint16_t conn_itvl_max; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_ce_len; + uint16_t max_ce_len; +}; + +/* LE start encryption command (ocf=0x0019) (note: fields out of order). */ +struct hci_start_encrypt +{ + uint16_t connection_handle; + uint16_t encrypted_diversifier; + uint64_t random_number; + uint8_t long_term_key[16]; +}; + +/* LE long term key request reply command (ocf=0x001a). */ +struct hci_lt_key_req_reply +{ + uint16_t conn_handle; + uint8_t long_term_key[16]; +}; + +/* LE Remote connection parameter request reply command */ +struct hci_conn_param_reply +{ + uint16_t handle; + uint16_t conn_itvl_min; + uint16_t conn_itvl_max; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_ce_len; + uint16_t max_ce_len; +}; + +/* LE Remote connection parameter request negative reply command */ +struct hci_conn_param_neg_reply +{ + uint16_t handle; + uint8_t reason; +}; + +/* Encryption change event (code=0x08) (note: fields out of order) */ +struct hci_encrypt_change +{ + uint8_t status; + uint8_t encryption_enabled; + uint16_t connection_handle; +}; + +/* Encryption key refresh complete event (code=0x30) */ +struct hci_encrypt_key_refresh +{ + uint8_t status; + uint16_t connection_handle; +}; + +/* Connection complete LE meta subevent */ +struct hci_le_conn_complete +{ + uint8_t subevent_code; + uint8_t status; + uint16_t connection_handle; + uint8_t role; + uint8_t peer_addr_type; + uint8_t peer_addr[BLE_DEV_ADDR_LEN]; + uint16_t conn_itvl; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint8_t master_clk_acc; + uint8_t local_rpa[BLE_DEV_ADDR_LEN]; + uint8_t peer_rpa[BLE_DEV_ADDR_LEN]; +}; + +/* Connection update complete LE meta subevent */ +struct hci_le_conn_upd_complete +{ + uint8_t subevent_code; + uint8_t status; + uint16_t connection_handle; + uint16_t conn_itvl; + uint16_t conn_latency; + uint16_t supervision_timeout; +}; + +/* Remote connection parameter request LE meta subevent */ +struct hci_le_conn_param_req +{ + uint8_t subevent_code; + uint16_t connection_handle; + uint16_t itvl_min; + uint16_t itvl_max; + uint16_t latency; + uint16_t timeout; +}; + +/* Read Remote Supported Features complete LE meta subevent */ +struct hci_le_rd_rem_supp_feat_complete +{ + uint8_t subevent_code; + uint8_t status; + uint16_t connection_handle; + uint8_t features[8]; +}; + +/* LE long term key request event (note: fields out of order). */ +struct hci_le_lt_key_req +{ + uint64_t random_number; + uint16_t connection_handle; + uint16_t encrypted_diversifier; + uint8_t subevent_code; +}; + +/* Disconnection complete event (note: fields out of order). */ +struct hci_disconn_complete +{ + uint16_t connection_handle; + uint8_t status; + uint8_t reason; +}; + +/* Read RSSI command-complete parameters (note: fields out of order). */ +struct hci_read_rssi_ack_params +{ + uint16_t connection_handle; + uint8_t status; + int8_t rssi; +}; + +/* PHY updated completed LE meta subevent */ +struct hci_le_phy_upd_complete +{ + uint8_t subevent_code; + uint8_t status; + uint16_t connection_handle; + uint8_t tx_phy; + uint8_t rx_phy; +}; + +/* LE Advertising Set Terminated subevent*/ +struct hci_le_adv_set_terminated +{ + uint8_t subevent_code; + uint8_t status; + uint8_t adv_handle; + uint16_t conn_handle; + uint8_t completed_events; +}; + +/* LE Scan Request Received subevent */ +struct hci_le_scan_req_rcvd +{ + uint8_t subevent_code; + uint8_t adv_handle; + uint8_t scan_addr_type; + uint8_t scan_addr[BLE_DEV_ADDR_LEN]; +}; + +#define BLE_HCI_DATA_HDR_SZ 4 +#define BLE_HCI_DATA_HANDLE(handle_pb_bc) (((handle_pb_bc) & 0x0fff) >> 0) +#define BLE_HCI_DATA_PB(handle_pb_bc) (((handle_pb_bc) & 0x3000) >> 12) +#define BLE_HCI_DATA_BC(handle_pb_bc) (((handle_pb_bc) & 0xc000) >> 14) + +struct hci_data_hdr +{ + uint16_t hdh_handle_pb_bc; + uint16_t hdh_len; +}; + +#define BLE_HCI_PB_FIRST_NON_FLUSH 0 +#define BLE_HCI_PB_MIDDLE 1 +#define BLE_HCI_PB_FIRST_FLUSH 2 +#define BLE_HCI_PB_FULL 3 + +struct hci_add_dev_to_resolving_list { + uint8_t addr_type; + uint8_t addr[6]; + uint8_t local_irk[16]; + uint8_t peer_irk[16]; +}; + +/* External data structures */ +extern const uint8_t g_ble_hci_le_cmd_len[BLE_HCI_NUM_LE_CMDS]; + +#ifdef __cplusplus +} +#endif + +#endif /* H_BLE_HCI_COMMON_ */ diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/access.c b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/access.c new file mode 100644 index 000000000..a6a12316b --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/access.c @@ -0,0 +1,767 @@ +/* Bluetooth Mesh */ + +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include +#include "mesh/mesh.h" + +#include "syscfg/syscfg.h" +#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG_ACCESS)) +#include "host/ble_hs_log.h" + +#include "mesh_priv.h" +#include "adv.h" +#include "net.h" +#include "lpn.h" +#include "transport.h" +#include "access.h" +#include "foundation.h" +#if MYNEWT_VAL(BLE_MESH_SHELL_MODELS) +#include "mesh/model_cli.h" +#endif + +static const struct bt_mesh_comp *dev_comp; +static u16_t dev_primary_addr; + +static const struct { + const u16_t id; + int (*const init)(struct bt_mesh_model *model, bool primary); +} model_init[] = { + { BT_MESH_MODEL_ID_CFG_SRV, bt_mesh_cfg_srv_init }, + { BT_MESH_MODEL_ID_HEALTH_SRV, bt_mesh_health_srv_init }, +#if MYNEWT_VAL(BLE_MESH_CFG_CLI) + { BT_MESH_MODEL_ID_CFG_CLI, bt_mesh_cfg_cli_init }, +#endif +#if MYNEWT_VAL(BLE_MESH_HEALTH_CLI) + { BT_MESH_MODEL_ID_HEALTH_CLI, bt_mesh_health_cli_init }, +#endif +#if MYNEWT_VAL(BLE_MESH_SHELL_MODELS) + { BT_MESH_MODEL_ID_GEN_ONOFF_CLI, bt_mesh_gen_model_cli_init }, + { BT_MESH_MODEL_ID_GEN_LEVEL_CLI, bt_mesh_gen_model_cli_init }, +#endif +}; + +void bt_mesh_model_foreach(void (*func)(struct bt_mesh_model *mod, + struct bt_mesh_elem *elem, + bool vnd, bool primary, + void *user_data), + void *user_data) +{ + int i, j; + + for (i = 0; i < dev_comp->elem_count; i++) { + struct bt_mesh_elem *elem = &dev_comp->elem[i]; + + for (j = 0; j < elem->model_count; j++) { + struct bt_mesh_model *model = &elem->models[j]; + + func(model, elem, false, i == 0, user_data); + } + + for (j = 0; j < elem->vnd_model_count; j++) { + struct bt_mesh_model *model = &elem->vnd_models[j]; + + func(model, elem, true, i == 0, user_data); + } + } +} + +s32_t bt_mesh_model_pub_period_get(struct bt_mesh_model *mod) +{ + int period; + + if (!mod->pub) { + return 0; + } + + switch (mod->pub->period >> 6) { + case 0x00: + /* 1 step is 100 ms */ + period = K_MSEC((mod->pub->period & BIT_MASK(6)) * 100); + break; + case 0x01: + /* 1 step is 1 second */ + period = K_SECONDS(mod->pub->period & BIT_MASK(6)); + break; + case 0x02: + /* 1 step is 10 seconds */ + period = K_SECONDS((mod->pub->period & BIT_MASK(6)) * 10); + break; + case 0x03: + /* 1 step is 10 minutes */ + period = K_MINUTES((mod->pub->period & BIT_MASK(6)) * 10); + break; + default: + CODE_UNREACHABLE; + } + + return period >> mod->pub->period_div; +} + +static s32_t next_period(struct bt_mesh_model *mod) +{ + struct bt_mesh_model_pub *pub = mod->pub; + u32_t elapsed, period; + + period = bt_mesh_model_pub_period_get(mod); + if (!period) { + return 0; + } + + elapsed = k_uptime_get_32() - pub->period_start; + + BT_DBG("Publishing took %ums", (unsigned) elapsed); + + if (elapsed > period) { + BT_WARN("Publication sending took longer than the period"); + /* Return smallest positive number since 0 means disabled */ + return K_MSEC(1); + } + + return period - elapsed; +} + +static void publish_sent(int err, void *user_data) +{ + struct bt_mesh_model *mod = user_data; + s32_t delay; + + BT_DBG("err %d", err); + + if (mod->pub->count) { + delay = BT_MESH_PUB_TRANSMIT_INT(mod->pub->retransmit); + } else { + delay = next_period(mod); + } + + if (delay) { + BT_DBG("Publishing next time in %dms", (int) delay); + k_delayed_work_submit(&mod->pub->timer, delay); + } +} + +static const struct bt_mesh_send_cb pub_sent_cb = { + .end = publish_sent, +}; + +static int publish_retransmit(struct bt_mesh_model *mod) +{ + struct os_mbuf *sdu = NET_BUF_SIMPLE(BT_MESH_TX_SDU_MAX); + struct bt_mesh_model_pub *pub = mod->pub; + struct bt_mesh_app_key *key; + struct bt_mesh_msg_ctx ctx = { + .addr = pub->addr, + .send_ttl = pub->ttl, + }; + struct bt_mesh_net_tx tx = { + .ctx = &ctx, + .src = bt_mesh_model_elem(mod)->addr, + .xmit = bt_mesh_net_transmit_get(), + .friend_cred = pub->cred, + }; + int err; + + key = bt_mesh_app_key_find(pub->key); + if (!key) { + err = -EADDRNOTAVAIL; + goto done; + } + + tx.sub = bt_mesh_subnet_get(key->net_idx); + + ctx.net_idx = key->net_idx; + ctx.app_idx = key->app_idx; + + net_buf_simple_init(sdu, 0); + net_buf_simple_add_mem(sdu, pub->msg->om_data, pub->msg->om_len); + + pub->count--; + + err = bt_mesh_trans_send(&tx, sdu, &pub_sent_cb, mod); + +done: + os_mbuf_free_chain(sdu); + return err; +} + +static void mod_publish(struct ble_npl_event *work) +{ + struct bt_mesh_model_pub *pub = ble_npl_event_get_arg(work); + s32_t period_ms; + int err; + + BT_DBG(""); + + period_ms = bt_mesh_model_pub_period_get(pub->mod); + BT_DBG("period %u ms", (unsigned) period_ms); + + if (pub->count) { + err = publish_retransmit(pub->mod); + if (err) { + BT_ERR("Failed to retransmit (err %d)", err); + + pub->count = 0; + + /* Continue with normal publication */ + if (period_ms) { + k_delayed_work_submit(&pub->timer, period_ms); + } + } + + return; + } + + if (!period_ms) { + return; + } + + __ASSERT_NO_MSG(pub->update != NULL); + + pub->period_start = k_uptime_get_32(); + + err = pub->update(pub->mod); + if (err) { + BT_ERR("Failed to update publication message"); + return; + } + + err = bt_mesh_model_publish(pub->mod); + if (err) { + BT_ERR("Publishing failed (err %d)", err); + } + + if (pub->count) { + /* Retransmissions also control the timer */ + k_delayed_work_cancel(&pub->timer); + } +} + +struct bt_mesh_elem *bt_mesh_model_elem(struct bt_mesh_model *mod) +{ + return &dev_comp->elem[mod->elem_idx]; +} + +struct bt_mesh_model *bt_mesh_model_get(bool vnd, u8_t elem_idx, u8_t mod_idx) +{ + struct bt_mesh_elem *elem; + + if (elem_idx >= dev_comp->elem_count) { + BT_ERR("Invalid element index %u", elem_idx); + return NULL; + } + + elem = &dev_comp->elem[elem_idx]; + + if (vnd) { + if (mod_idx >= elem->vnd_model_count) { + BT_ERR("Invalid vendor model index %u", mod_idx); + return NULL; + } + + return &elem->vnd_models[mod_idx]; + } else { + if (mod_idx >= elem->model_count) { + BT_ERR("Invalid SIG model index %u", mod_idx); + return NULL; + } + + return &elem->models[mod_idx]; + } +} + +static void mod_init(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, + bool vnd, bool primary, void *user_data) +{ + int i; + + if (mod->pub) { + mod->pub->mod = mod; + k_delayed_work_init(&mod->pub->timer, mod_publish); + k_delayed_work_add_arg(&mod->pub->timer, mod->pub); + } + + for (i = 0; i < ARRAY_SIZE(mod->keys); i++) { + mod->keys[i] = BT_MESH_KEY_UNUSED; + } + + mod->elem_idx = elem - dev_comp->elem; + if (vnd) { + mod->mod_idx = mod - elem->vnd_models; + } else { + mod->mod_idx = mod - elem->models; + } + + if (vnd) { + return; + } + + for (i = 0; i < ARRAY_SIZE(model_init); i++) { + if (model_init[i].id == mod->id) { + model_init[i].init(mod, primary); + } + } +} + +int bt_mesh_comp_register(const struct bt_mesh_comp *comp) +{ + /* There must be at least one element */ + if (!comp->elem_count) { + return -EINVAL; + } + + dev_comp = comp; + + bt_mesh_model_foreach(mod_init, NULL); + + return 0; +} + +void bt_mesh_comp_provision(u16_t addr) +{ + int i; + + dev_primary_addr = addr; + + BT_DBG("addr 0x%04x elem_count %zu", addr, dev_comp->elem_count); + + for (i = 0; i < dev_comp->elem_count; i++) { + struct bt_mesh_elem *elem = &dev_comp->elem[i]; + + elem->addr = addr++; + + BT_DBG("addr 0x%04x mod_count %u vnd_mod_count %u", + elem->addr, elem->model_count, elem->vnd_model_count); + } +} + +void bt_mesh_comp_unprovision(void) +{ + BT_DBG(""); + + dev_primary_addr = BT_MESH_ADDR_UNASSIGNED; + + bt_mesh_model_foreach(mod_init, NULL); +} + +u16_t bt_mesh_primary_addr(void) +{ + return dev_primary_addr; +} + +u16_t *bt_mesh_model_find_group(struct bt_mesh_model *mod, u16_t addr) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(mod->groups); i++) { + if (mod->groups[i] == addr) { + return &mod->groups[i]; + } + } + + return NULL; +} + +static struct bt_mesh_model *bt_mesh_elem_find_group(struct bt_mesh_elem *elem, + u16_t group_addr) +{ + struct bt_mesh_model *model; + u16_t *match; + int i; + + for (i = 0; i < elem->model_count; i++) { + model = &elem->models[i]; + + match = bt_mesh_model_find_group(model, group_addr); + if (match) { + return model; + } + } + + for (i = 0; i < elem->vnd_model_count; i++) { + model = &elem->vnd_models[i]; + + match = bt_mesh_model_find_group(model, group_addr); + if (match) { + return model; + } + } + + return NULL; +} + +struct bt_mesh_elem *bt_mesh_elem_find(u16_t addr) +{ + int i; + + for (i = 0; i < dev_comp->elem_count; i++) { + struct bt_mesh_elem *elem = &dev_comp->elem[i]; + + if (BT_MESH_ADDR_IS_GROUP(addr) || + BT_MESH_ADDR_IS_VIRTUAL(addr)) { + if (bt_mesh_elem_find_group(elem, addr)) { + return elem; + } + } else if (elem->addr == addr) { + return elem; + } + } + + return NULL; +} + +u8_t bt_mesh_elem_count(void) +{ + return dev_comp->elem_count; +} + +static bool model_has_key(struct bt_mesh_model *mod, u16_t key) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(mod->keys); i++) { + if (mod->keys[i] == key) { + return true; + } + } + + return false; +} + +static const struct bt_mesh_model_op *find_op(struct bt_mesh_model *models, + u8_t model_count, u16_t dst, + u16_t app_idx, u32_t opcode, + struct bt_mesh_model **model) +{ + u8_t i; + + for (i = 0; i < model_count; i++) { + const struct bt_mesh_model_op *op; + + *model = &models[i]; + + if (BT_MESH_ADDR_IS_GROUP(dst) || + BT_MESH_ADDR_IS_VIRTUAL(dst)) { + if (!bt_mesh_model_find_group(*model, dst)) { + continue; + } + } + + if (!model_has_key(*model, app_idx)) { + continue; + } + + for (op = (*model)->op; op->func; op++) { + if (op->opcode == opcode) { + return op; + } + } + } + + *model = NULL; + return NULL; +} + +static int get_opcode(struct os_mbuf *buf, u32_t *opcode) +{ + switch (buf->om_data[0] >> 6) { + case 0x00: + case 0x01: + if (buf->om_data[0] == 0x7f) { + BT_ERR("Ignoring RFU OpCode"); + return -EINVAL; + } + + *opcode = net_buf_simple_pull_u8(buf); + return 0; + case 0x02: + if (buf->om_len < 2) { + BT_ERR("Too short payload for 2-octet OpCode"); + return -EINVAL; + } + + *opcode = net_buf_simple_pull_be16(buf); + return 0; + case 0x03: + if (buf->om_len < 3) { + BT_ERR("Too short payload for 3-octet OpCode"); + return -EINVAL; + } + + *opcode = net_buf_simple_pull_u8(buf) << 16; + *opcode |= net_buf_simple_pull_le16(buf); + return 0; + } + + CODE_UNREACHABLE; +} + +bool bt_mesh_fixed_group_match(u16_t addr) +{ + /* Check for fixed group addresses */ + switch (addr) { + case BT_MESH_ADDR_ALL_NODES: + return true; + case BT_MESH_ADDR_PROXIES: + /* TODO: Proxy not yet supported */ + return false; + case BT_MESH_ADDR_FRIENDS: + return (bt_mesh_friend_get() == BT_MESH_FRIEND_ENABLED); + case BT_MESH_ADDR_RELAYS: + return (bt_mesh_relay_get() == BT_MESH_RELAY_ENABLED); + default: + return false; + } +} + +void bt_mesh_model_recv(struct bt_mesh_net_rx *rx, struct os_mbuf *buf) +{ + struct bt_mesh_model *models, *model; + const struct bt_mesh_model_op *op; + u32_t opcode; + u8_t count; + int i; + + BT_DBG("app_idx 0x%04x src 0x%04x dst 0x%04x", rx->ctx.app_idx, + rx->ctx.addr, rx->ctx.recv_dst); + BT_DBG("len %u: %s", buf->om_len, bt_hex(buf->om_data, buf->om_len)); + + if (get_opcode(buf, &opcode) < 0) { + BT_WARN("Unable to decode OpCode"); + return; + } + + BT_DBG("OpCode 0x%08x", (unsigned) opcode); + + for (i = 0; i < dev_comp->elem_count; i++) { + struct bt_mesh_elem *elem = &dev_comp->elem[i]; + + if (BT_MESH_ADDR_IS_UNICAST(rx->ctx.recv_dst)) { + if (elem->addr != rx->ctx.recv_dst) { + continue; + } + } else if (BT_MESH_ADDR_IS_GROUP(rx->ctx.recv_dst) || + BT_MESH_ADDR_IS_VIRTUAL(rx->ctx.recv_dst)) { + /* find_op() will do proper model/group matching */ + } else if (i != 0 || + !bt_mesh_fixed_group_match(rx->ctx.recv_dst)) { + continue; + } + + /* SIG models cannot contain 3-byte (vendor) OpCodes, and + * vendor models cannot contain SIG (1- or 2-byte) OpCodes, so + * we only need to do the lookup in one of the model lists. + */ + if (opcode < 0x10000) { + models = elem->models; + count = elem->model_count; + } else { + models = elem->vnd_models; + count = elem->vnd_model_count; + } + + op = find_op(models, count, rx->ctx.recv_dst, rx->ctx.app_idx, + opcode, &model); + if (op) { + struct net_buf_simple_state state; + + if (buf->om_len < op->min_len) { + BT_ERR("Too short message for OpCode 0x%08x", + (unsigned) opcode); + continue; + } + + /* The callback will likely parse the buffer, so + * store the parsing state in case multiple models + * receive the message. + */ + net_buf_simple_save(buf, &state); + op->func(model, &rx->ctx, buf); + net_buf_simple_restore(buf, &state); + + } else { + BT_DBG("No OpCode 0x%08x for elem %d", + (unsigned) opcode, i); + } + } +} + +void bt_mesh_model_msg_init(struct os_mbuf *msg, u32_t opcode) +{ + net_buf_simple_init(msg, 0); + + if (opcode < 0x100) { + /* 1-byte OpCode */ + net_buf_simple_add_u8(msg, opcode); + return; + } + + if (opcode < 0x10000) { + /* 2-byte OpCode */ + net_buf_simple_add_be16(msg, opcode); + return; + } + + /* 3-byte OpCode */ + net_buf_simple_add_u8(msg, ((opcode >> 16) & 0xff)); + net_buf_simple_add_le16(msg, opcode & 0xffff); +} + +static int model_send(struct bt_mesh_model *model, + struct bt_mesh_net_tx *tx, bool implicit_bind, + struct os_mbuf *msg, + const struct bt_mesh_send_cb *cb, void *cb_data) +{ + BT_DBG("net_idx 0x%04x app_idx 0x%04x dst 0x%04x", tx->ctx->net_idx, + tx->ctx->app_idx, tx->ctx->addr); + BT_DBG("len %u: %s", msg->om_len, bt_hex(msg->om_data, msg->om_len)); + + if (!bt_mesh_is_provisioned()) { + BT_ERR("Local node is not yet provisioned"); + return -EAGAIN; + } + + if (net_buf_simple_tailroom(msg) < 4) { + BT_ERR("Not enough tailroom for TransMIC"); + return -EINVAL; + } + + if (msg->om_len > BT_MESH_TX_SDU_MAX - 4) { + BT_ERR("Too big message"); + return -EMSGSIZE; + } + + if (!implicit_bind && !model_has_key(model, tx->ctx->app_idx)) { + BT_ERR("Model not bound to AppKey 0x%04x", tx->ctx->app_idx); + return -EINVAL; + } + + return bt_mesh_trans_send(tx, msg, cb, cb_data); +} + +int bt_mesh_model_send(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *msg, + const struct bt_mesh_send_cb *cb, void *cb_data) +{ + struct bt_mesh_net_tx tx = { + .sub = bt_mesh_subnet_get(ctx->net_idx), + .ctx = ctx, + .src = bt_mesh_model_elem(model)->addr, + .xmit = bt_mesh_net_transmit_get(), + .friend_cred = 0, + }; + + return model_send(model, &tx, false, msg, cb, cb_data); +} + +int bt_mesh_model_publish(struct bt_mesh_model *model) +{ + struct os_mbuf *sdu = NET_BUF_SIMPLE(BT_MESH_TX_SDU_MAX); + struct bt_mesh_model_pub *pub = model->pub; + struct bt_mesh_app_key *key; + struct bt_mesh_msg_ctx ctx = { + }; + struct bt_mesh_net_tx tx = { + .ctx = &ctx, + .src = bt_mesh_model_elem(model)->addr, + .xmit = bt_mesh_net_transmit_get(), + }; + int err; + + BT_DBG(""); + + if (!pub) { + err = -ENOTSUP; + goto done; + } + + if (pub->addr == BT_MESH_ADDR_UNASSIGNED) { + err = -EADDRNOTAVAIL; + goto done; + } + + key = bt_mesh_app_key_find(pub->key); + if (!key) { + err = -EADDRNOTAVAIL; + goto done; + } + + if (pub->msg->om_len + 4 > BT_MESH_TX_SDU_MAX) { + BT_ERR("Message does not fit maximum SDU size"); + err = -EMSGSIZE; + goto done; + } + + if (pub->count) { + BT_WARN("Clearing publish retransmit timer"); + k_delayed_work_cancel(&pub->timer); + } + + net_buf_simple_init(sdu, 0); + net_buf_simple_add_mem(sdu, pub->msg->om_data, pub->msg->om_len); + + ctx.addr = pub->addr; + ctx.send_ttl = pub->ttl; + ctx.net_idx = key->net_idx; + ctx.app_idx = key->app_idx; + + tx.friend_cred = pub->cred; + tx.sub = bt_mesh_subnet_get(ctx.net_idx), + + pub->count = BT_MESH_PUB_TRANSMIT_COUNT(pub->retransmit); + + BT_DBG("Publish Retransmit Count %u Interval %ums", pub->count, + BT_MESH_PUB_TRANSMIT_INT(pub->retransmit)); + + err = model_send(model, &tx, true, sdu, &pub_sent_cb, model); + if (err) { + /* Don't try retransmissions for this publish attempt */ + pub->count = 0; + /* Make sure the publish timer gets reset */ + publish_sent(err, model); + } + +done: + os_mbuf_free_chain(sdu); + return err; +} + +struct bt_mesh_model *bt_mesh_model_find_vnd(struct bt_mesh_elem *elem, + u16_t company, u16_t id) +{ + u8_t i; + + for (i = 0; i < elem->vnd_model_count; i++) { + if (elem->vnd_models[i].vnd.company == company && + elem->vnd_models[i].vnd.id == id) { + return &elem->vnd_models[i]; + } + } + + return NULL; +} + +struct bt_mesh_model *bt_mesh_model_find(struct bt_mesh_elem *elem, + u16_t id) +{ + u8_t i; + + for (i = 0; i < elem->model_count; i++) { + if (elem->models[i].id == id) { + return &elem->models[i]; + } + } + + return NULL; +} + +const struct bt_mesh_comp *bt_mesh_comp_get(void) +{ + return dev_comp; +} diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/access.h b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/access.h new file mode 100644 index 000000000..5ce7f1990 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/access.h @@ -0,0 +1,57 @@ +/* Bluetooth Mesh */ + +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __ACCESS_H__ +#define __ACCESS_H__ + +#include "mesh/mesh.h" + +/* bt_mesh_model.flags */ +enum { + BT_MESH_MOD_BIND_PENDING = BIT(0), + BT_MESH_MOD_SUB_PENDING = BIT(1), + BT_MESH_MOD_PUB_PENDING = BIT(2), +}; + +void bt_mesh_elem_register(struct bt_mesh_elem *elem, u8_t count); + +u8_t bt_mesh_elem_count(void); + +/* Find local element based on unicast or group address */ +struct bt_mesh_elem *bt_mesh_elem_find(u16_t addr); + +struct bt_mesh_model *bt_mesh_model_find_vnd(struct bt_mesh_elem *elem, + u16_t company, u16_t id); +struct bt_mesh_model * bt_mesh_model_find(struct bt_mesh_elem *elem, + u16_t id); + +u16_t *bt_mesh_model_find_group(struct bt_mesh_model *mod, u16_t addr); + +bool bt_mesh_fixed_group_match(u16_t addr); + +void bt_mesh_model_foreach(void (*func)(struct bt_mesh_model *mod, + struct bt_mesh_elem *elem, + bool vnd, bool primary, + void *user_data), + void *user_data); + +s32_t bt_mesh_model_pub_period_get(struct bt_mesh_model *mod); + +void bt_mesh_comp_provision(u16_t addr); +void bt_mesh_comp_unprovision(void); + +u16_t bt_mesh_primary_addr(void); + +const struct bt_mesh_comp *bt_mesh_comp_get(void); + +struct bt_mesh_model *bt_mesh_model_get(bool vnd, u8_t elem_idx, u8_t mod_idx); + +void bt_mesh_model_recv(struct bt_mesh_net_rx *rx, struct os_mbuf *buf); + +int bt_mesh_comp_register(const struct bt_mesh_comp *comp); +#endif diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/adv.c b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/adv.c new file mode 100644 index 000000000..5364ddc73 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/adv.c @@ -0,0 +1,423 @@ +/* Bluetooth Mesh */ + +/* + * Copyright (c) 2018 Nordic Semiconductor ASA + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "mesh/mesh.h" + +#include "syscfg/syscfg.h" +#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG_ADV)) +#include "host/ble_hs_log.h" + +#include "host/ble_hs_adv.h" +#include "host/ble_gap.h" +#include "nimble/hci_common.h" +#include "mesh/porting.h" +#include "nimble/nimble_port.h" + +#include "adv.h" +#include "net.h" +#include "foundation.h" +#include "beacon.h" +#include "prov.h" +#include "proxy.h" + +/* Convert from ms to 0.625ms units */ +#define ADV_SCAN_UNIT(_ms) ((_ms) * 8 / 5) + +/* Window and Interval are equal for continuous scanning */ +#define MESH_SCAN_INTERVAL_MS 30 +#define MESH_SCAN_WINDOW_MS 30 +#define MESH_SCAN_INTERVAL ADV_SCAN_UNIT(MESH_SCAN_INTERVAL_MS) +#define MESH_SCAN_WINDOW ADV_SCAN_UNIT(MESH_SCAN_WINDOW_MS) + +/* Pre-5.0 controllers enforce a minimum interval of 100ms + * whereas 5.0+ controllers can go down to 20ms. + */ +#define ADV_INT_DEFAULT_MS 100 +#define ADV_INT_FAST_MS 20 + +static s32_t adv_int_min = ADV_INT_DEFAULT_MS; + +/* TinyCrypt PRNG consumes a lot of stack space, so we need to have + * an increased call stack whenever it's used. + */ +#if MYNEWT +#define ADV_STACK_SIZE 768 +OS_TASK_STACK_DEFINE(g_blemesh_stack, ADV_STACK_SIZE); +struct os_task adv_task; +#else +static TaskHandle_t adv_task_h; +#endif + +static struct ble_npl_eventq adv_queue; +extern u8_t g_mesh_addr_type; +static int adv_initialized = false; + +static os_membuf_t adv_buf_mem[OS_MEMPOOL_SIZE( + MYNEWT_VAL(BLE_MESH_ADV_BUF_COUNT), + BT_MESH_ADV_DATA_SIZE + BT_MESH_MBUF_HEADER_SIZE)]; + +struct os_mbuf_pool adv_os_mbuf_pool; +static struct os_mempool adv_buf_mempool; + +static const u8_t adv_type[] = { + [BT_MESH_ADV_PROV] = BLE_HS_ADV_TYPE_MESH_PROV, + [BT_MESH_ADV_DATA] = BLE_HS_ADV_TYPE_MESH_MESSAGE, + [BT_MESH_ADV_BEACON] = BLE_HS_ADV_TYPE_MESH_BEACON, + [BT_MESH_ADV_URI] = BLE_HS_ADV_TYPE_URI, +}; + + +static struct bt_mesh_adv adv_pool[CONFIG_BT_MESH_ADV_BUF_COUNT]; + +static struct bt_mesh_adv *adv_alloc(int id) +{ + return &adv_pool[id]; +} + +static inline void adv_send_start(u16_t duration, int err, + const struct bt_mesh_send_cb *cb, + void *cb_data) +{ + if (cb && cb->start) { + cb->start(duration, err, cb_data); + } +} + +static inline void adv_send_end(int err, const struct bt_mesh_send_cb *cb, + void *cb_data) +{ + if (cb && cb->end) { + cb->end(err, cb_data); + } +} + +static inline void adv_send(struct os_mbuf *buf) +{ + const struct bt_mesh_send_cb *cb = BT_MESH_ADV(buf)->cb; + void *cb_data = BT_MESH_ADV(buf)->cb_data; + struct ble_gap_adv_params param = { 0 }; + u16_t duration, adv_int; + struct bt_data ad; + int err; + + adv_int = max(adv_int_min, + BT_MESH_TRANSMIT_INT(BT_MESH_ADV(buf)->xmit)); + duration = (MESH_SCAN_WINDOW_MS + + ((BT_MESH_TRANSMIT_COUNT(BT_MESH_ADV(buf)->xmit) + 1) * + (adv_int + 10))); + + BT_DBG("type %u om_len %u: %s", BT_MESH_ADV(buf)->type, + buf->om_len, bt_hex(buf->om_data, buf->om_len)); + BT_DBG("count %u interval %ums duration %ums", + BT_MESH_TRANSMIT_COUNT(BT_MESH_ADV(buf)->xmit) + 1, adv_int, + duration); + + ad.type = adv_type[BT_MESH_ADV(buf)->type]; + ad.data_len = buf->om_len; + ad.data = buf->om_data; + + param.itvl_min = ADV_SCAN_UNIT(adv_int); + param.itvl_max = param.itvl_min; + param.conn_mode = BLE_GAP_CONN_MODE_NON; + + err = bt_le_adv_start(¶m, &ad, 1, NULL, 0); + net_buf_unref(buf); + adv_send_start(duration, err, cb, cb_data); + if (err) { + BT_ERR("Advertising failed: err %d", err); + return; + } + + BT_DBG("Advertising started. Sleeping %u ms", duration); + + k_sleep(K_MSEC(duration)); + + err = bt_le_adv_stop(false); + adv_send_end(err, cb, cb_data); + if (err) { + BT_ERR("Stopping advertising failed: err %d", err); + return; + } + + BT_DBG("Advertising stopped"); +} + +void +mesh_adv_thread(void *args) +{ + static struct ble_npl_event *ev; + struct os_mbuf *buf; +#if (MYNEWT_VAL(BLE_MESH_PROXY)) + s32_t timeout; +#endif + + BT_DBG("started"); + + while (1) { +#if (MYNEWT_VAL(BLE_MESH_PROXY)) + ev = ble_npl_eventq_get(&adv_queue, 0); + while (!ev) { + timeout = bt_mesh_proxy_adv_start(); + BT_DBG("Proxy Advertising up to %d ms", (int) timeout); + + // FIXME: should we redefine K_SECONDS macro instead in glue? + if (timeout != K_FOREVER) { + timeout = ble_npl_time_ms_to_ticks32(timeout); + } + + ev = ble_npl_eventq_get(&adv_queue, timeout); + bt_mesh_proxy_adv_stop(); + } +#else + ev = ble_npl_eventq_get(&adv_queue, BLE_NPL_TIME_FOREVER); +#endif + + if (!ev || !ble_npl_event_get_arg(ev)) { + continue; + } + + buf = ble_npl_event_get_arg(ev); + + /* busy == 0 means this was canceled */ + if (BT_MESH_ADV(buf)->busy) { + BT_MESH_ADV(buf)->busy = 0; + adv_send(buf); + } + + /* os_sched(NULL); */ + } +} + +void bt_mesh_adv_update(void) +{ + static struct ble_npl_event ev = { }; + + BT_DBG(""); + + ble_npl_eventq_put(&adv_queue, &ev); +} + +struct os_mbuf *bt_mesh_adv_create_from_pool(struct os_mbuf_pool *pool, + bt_mesh_adv_alloc_t get_id, + enum bt_mesh_adv_type type, + u8_t xmit, s32_t timeout) +{ + struct bt_mesh_adv *adv; + struct os_mbuf *buf; + + if (atomic_test_bit(bt_mesh.flags, BT_MESH_SUSPENDED)) { + BT_WARN("Refusing to allocate buffer while suspended"); + return NULL; + } + + buf = os_mbuf_get_pkthdr(pool, BT_MESH_ADV_USER_DATA_SIZE); + if (!buf) { + return NULL; + } + + adv = get_id(net_buf_id(buf)); + BT_MESH_ADV(buf) = adv; + + memset(adv, 0, sizeof(*adv)); + + adv->type = type; + adv->xmit = xmit; + + adv->ref_cnt = 1; + ble_npl_event_set_arg(&adv->ev, buf); + + return buf; +} + +struct os_mbuf *bt_mesh_adv_create(enum bt_mesh_adv_type type, u8_t xmit, + s32_t timeout) +{ + return bt_mesh_adv_create_from_pool(&adv_os_mbuf_pool, adv_alloc, type, + xmit, timeout); +} + +void bt_mesh_adv_send(struct os_mbuf *buf, const struct bt_mesh_send_cb *cb, + void *cb_data) +{ + BT_DBG("buf %p, type 0x%02x len %u: %s", buf, BT_MESH_ADV(buf)->type, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); + + BT_MESH_ADV(buf)->cb = cb; + BT_MESH_ADV(buf)->cb_data = cb_data; + BT_MESH_ADV(buf)->busy = 1; + + net_buf_put(&adv_queue, net_buf_ref(buf)); +} + +static void bt_mesh_scan_cb(const bt_addr_le_t *addr, s8_t rssi, + u8_t adv_type, struct os_mbuf *buf) +{ + if (adv_type != BLE_HCI_ADV_TYPE_ADV_NONCONN_IND) { + return; + } + +#if BT_MESH_EXTENDED_DEBUG + BT_DBG("len %u: %s", buf->om_len, bt_hex(buf->om_data, buf->om_len)); +#endif + + while (buf->om_len > 1) { + struct net_buf_simple_state state; + u8_t len, type; + + len = net_buf_simple_pull_u8(buf); + /* Check for early termination */ + if (len == 0) { + return; + } + + if (len > buf->om_len) { + BT_WARN("AD malformed"); + return; + } + + net_buf_simple_save(buf, &state); + + type = net_buf_simple_pull_u8(buf); + + switch (type) { + case BLE_HS_ADV_TYPE_MESH_MESSAGE: + bt_mesh_net_recv(buf, rssi, BT_MESH_NET_IF_ADV); + break; +#if MYNEWT_VAL(BLE_MESH_PB_ADV) + case BLE_HS_ADV_TYPE_MESH_PROV: + bt_mesh_pb_adv_recv(buf); + break; +#endif + case BLE_HS_ADV_TYPE_MESH_BEACON: + bt_mesh_beacon_recv(buf); + break; + default: + break; + } + + net_buf_simple_restore(buf, &state); + net_buf_simple_pull(buf, len); + } +} + +void bt_mesh_adv_init(void) +{ + int rc; + + /* Advertising should only be initialized once. Calling + * os_task init the second time will result in an assert. */ + if (adv_initialized) { + return; + } + + rc = os_mempool_init(&adv_buf_mempool, MYNEWT_VAL(BLE_MESH_ADV_BUF_COUNT), + BT_MESH_ADV_DATA_SIZE + BT_MESH_MBUF_HEADER_SIZE, + adv_buf_mem, "adv_buf_pool"); + assert(rc == 0); + + rc = os_mbuf_pool_init(&adv_os_mbuf_pool, &adv_buf_mempool, + BT_MESH_ADV_DATA_SIZE + BT_MESH_MBUF_HEADER_SIZE, + MYNEWT_VAL(BLE_MESH_ADV_BUF_COUNT)); + assert(rc == 0); + + ble_npl_eventq_init(&adv_queue); + +#if MYNEWT + os_task_init(&adv_task, "mesh_adv", mesh_adv_thread, NULL, + MYNEWT_VAL(BLE_MESH_ADV_TASK_PRIO), OS_WAIT_FOREVER, + g_blemesh_stack, ADV_STACK_SIZE); +#else + xTaskCreatePinnedToCore(mesh_adv_thread, "mesh_adv", 2768, + NULL, (configMAX_PRIORITIES - 5), &adv_task_h, NIMBLE_CORE); +#endif + + /* For BT5 controllers we can have fast advertising interval */ + if (ble_hs_hci_get_hci_version() >= BLE_HCI_VER_BCS_5_0) { + adv_int_min = ADV_INT_FAST_MS; + } + + adv_initialized = true; +} + +int +ble_adv_gap_mesh_cb(struct ble_gap_event *event, void *arg) +{ +#if MYNEWT_VAL(BLE_EXT_ADV) + struct ble_gap_ext_disc_desc *ext_desc; +#endif + struct ble_gap_disc_desc *desc; + struct os_mbuf *buf = NULL; + +#if BT_MESH_EXTENDED_DEBUG + BT_DBG("event->type %d", event->type); +#endif + + switch (event->type) { +#if MYNEWT_VAL(BLE_EXT_ADV) + case BLE_GAP_EVENT_EXT_DISC: + ext_desc = &event->ext_disc; + buf = os_mbuf_get_pkthdr(&adv_os_mbuf_pool, 0); + if (!buf || os_mbuf_append(buf, ext_desc->data, ext_desc->length_data)) { + BT_ERR("Could not append data"); + goto done; + } + bt_mesh_scan_cb(&ext_desc->addr, ext_desc->rssi, + ext_desc->legacy_event_type, buf); + break; +#endif + case BLE_GAP_EVENT_DISC: + desc = &event->disc; + buf = os_mbuf_get_pkthdr(&adv_os_mbuf_pool, 0); + if (!buf || os_mbuf_append(buf, desc->data, desc->length_data)) { + BT_ERR("Could not append data"); + goto done; + } + + bt_mesh_scan_cb(&desc->addr, desc->rssi, desc->event_type, buf); + break; + default: + break; + } + +done: + if (buf) { + os_mbuf_free_chain(buf); + } + + return 0; +} + +int bt_mesh_scan_enable(void) +{ +#if MYNEWT_VAL(BLE_EXT_ADV) + struct ble_gap_ext_disc_params uncoded_params = + { .itvl = MESH_SCAN_INTERVAL, .window = MESH_SCAN_WINDOW, + .passive = 1 }; + + BT_DBG(""); + + return ble_gap_ext_disc(g_mesh_addr_type, 0, 0, 0, 0, 0, + &uncoded_params, NULL, NULL, NULL); +#else + struct ble_gap_disc_params scan_param = + { .passive = 1, .filter_duplicates = 0, .itvl = + MESH_SCAN_INTERVAL, .window = MESH_SCAN_WINDOW }; + + BT_DBG(""); + + return ble_gap_disc(g_mesh_addr_type, BLE_HS_FOREVER, &scan_param, NULL, NULL); +#endif +} + +int bt_mesh_scan_disable(void) +{ + BT_DBG(""); + + return ble_gap_disc_cancel(); +} diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/adv.h b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/adv.h new file mode 100644 index 000000000..8e76e4197 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/adv.h @@ -0,0 +1,82 @@ +/* Bluetooth Mesh */ + +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __ADV_H__ +#define __ADV_H__ + +/* Maximum advertising data payload for a single data type */ +#include "mesh/mesh.h" + +#define BT_MESH_ADV(om) (*(struct bt_mesh_adv **) OS_MBUF_USRHDR(om)) + +#define BT_MESH_ADV_DATA_SIZE 31 + +/* The user data is a pointer (4 bytes) to struct bt_mesh_adv */ +#define BT_MESH_ADV_USER_DATA_SIZE (sizeof(struct bt_mesh_adv *)) + +#define BT_MESH_MBUF_HEADER_SIZE (sizeof(struct os_mbuf_pkthdr) + \ + BT_MESH_ADV_USER_DATA_SIZE +\ + sizeof(struct os_mbuf)) + +enum bt_mesh_adv_type +{ + BT_MESH_ADV_PROV, + BT_MESH_ADV_DATA, + BT_MESH_ADV_BEACON, + BT_MESH_ADV_URI, +}; + +typedef void (*bt_mesh_adv_func_t)(struct os_mbuf *buf, u16_t duration, + int err, void *user_data); + +struct bt_mesh_adv { + const struct bt_mesh_send_cb *cb; + void *cb_data; + + u8_t type:2, + busy:1; + u8_t xmit; + + union { + /* Address, used e.g. for Friend Queue messages */ + u16_t addr; + + /* For transport layer segment sending */ + struct { + u8_t attempts; + } seg; + }; + + int ref_cnt; + struct ble_npl_event ev; +}; + +typedef struct bt_mesh_adv *(*bt_mesh_adv_alloc_t)(int id); + +/* xmit_count: Number of retransmissions, i.e. 0 == 1 transmission */ +struct os_mbuf *bt_mesh_adv_create(enum bt_mesh_adv_type type, u8_t xmit, + s32_t timeout); + +struct os_mbuf *bt_mesh_adv_create_from_pool(struct os_mbuf_pool *pool, + bt_mesh_adv_alloc_t get_id, + enum bt_mesh_adv_type type, + u8_t xmit, s32_t timeout); + +void bt_mesh_adv_send(struct os_mbuf *buf, const struct bt_mesh_send_cb *cb, + void *cb_data); + +void bt_mesh_adv_update(void); + +void bt_mesh_adv_init(void); + +int bt_mesh_scan_enable(void); + +int bt_mesh_scan_disable(void); + +int ble_adv_gap_mesh_cb(struct ble_gap_event *event, void *arg); +#endif diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/atomic.h b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/atomic.h new file mode 100644 index 000000000..2c7317948 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/atomic.h @@ -0,0 +1,409 @@ +/* atomic operations */ + +/* + * Copyright (c) 1997-2015, Wind River Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __ATOMIC_H__ +#define __ATOMIC_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef int atomic_t; +typedef atomic_t atomic_val_t; + +/** + * @defgroup atomic_apis Atomic Services APIs + * @ingroup kernel_apis + * @{ + */ + +/** + * @brief Atomic compare-and-set. + * + * This routine performs an atomic compare-and-set on @a target. If the current + * value of @a target equals @a old_value, @a target is set to @a new_value. + * If the current value of @a target does not equal @a old_value, @a target + * is left unchanged. + * + * @param target Address of atomic variable. + * @param old_value Original value to compare against. + * @param new_value New value to store. + * @return 1 if @a new_value is written, 0 otherwise. + */ +static inline int atomic_cas(atomic_t *target, atomic_val_t old_value, + atomic_val_t new_value) +{ + return __atomic_compare_exchange_n(target, &old_value, new_value, + 0, __ATOMIC_SEQ_CST, + __ATOMIC_SEQ_CST); +} + +/** + * + * @brief Atomic addition. + * + * This routine performs an atomic addition on @a target. + * + * @param target Address of atomic variable. + * @param value Value to add. + * + * @return Previous value of @a target. + */ +static inline atomic_val_t atomic_add(atomic_t *target, atomic_val_t value) +{ + return __atomic_fetch_add(target, value, __ATOMIC_SEQ_CST); +} + +/** + * + * @brief Atomic subtraction. + * + * This routine performs an atomic subtraction on @a target. + * + * @param target Address of atomic variable. + * @param value Value to subtract. + * + * @return Previous value of @a target. + */ + +static inline atomic_val_t atomic_sub(atomic_t *target, atomic_val_t value) +{ + return __atomic_fetch_sub(target, value, __ATOMIC_SEQ_CST); +} + +/** + * + * @brief Atomic increment. + * + * This routine performs an atomic increment by 1 on @a target. + * + * @param target Address of atomic variable. + * + * @return Previous value of @a target. + */ + +static inline atomic_val_t atomic_inc(atomic_t *target) +{ + return atomic_add(target, 1); +} + +/** + * + * @brief Atomic decrement. + * + * This routine performs an atomic decrement by 1 on @a target. + * + * @param target Address of atomic variable. + * + * @return Previous value of @a target. + */ + +static inline atomic_val_t atomic_dec(atomic_t *target) +{ + return atomic_sub(target, 1); +} + +/** + * + * @brief Atomic get. + * + * This routine performs an atomic read on @a target. + * + * @param target Address of atomic variable. + * + * @return Value of @a target. + */ + +static inline atomic_val_t atomic_get(const atomic_t *target) +{ + return __atomic_load_n(target, __ATOMIC_SEQ_CST); +} + +/** + * + * @brief Atomic get-and-set. + * + * This routine atomically sets @a target to @a value and returns + * the previous value of @a target. + * + * @param target Address of atomic variable. + * @param value Value to write to @a target. + * + * @return Previous value of @a target. + */ + +static inline atomic_val_t atomic_set(atomic_t *target, atomic_val_t value) +{ + /* This builtin, as described by Intel, is not a traditional + * test-and-set operation, but rather an atomic exchange operation. It + * writes value into *ptr, and returns the previous contents of *ptr. + */ + return __atomic_exchange_n(target, value, __ATOMIC_SEQ_CST); +} + +/** + * + * @brief Atomic clear. + * + * This routine atomically sets @a target to zero and returns its previous + * value. (Hence, it is equivalent to atomic_set(target, 0).) + * + * @param target Address of atomic variable. + * + * @return Previous value of @a target. + */ + +static inline atomic_val_t atomic_clear(atomic_t *target) +{ + return atomic_set(target, 0); +} + +/** + * + * @brief Atomic bitwise inclusive OR. + * + * This routine atomically sets @a target to the bitwise inclusive OR of + * @a target and @a value. + * + * @param target Address of atomic variable. + * @param value Value to OR. + * + * @return Previous value of @a target. + */ + +static inline atomic_val_t atomic_or(atomic_t *target, atomic_val_t value) +{ + return __atomic_fetch_or(target, value, __ATOMIC_SEQ_CST); +} + +/** + * + * @brief Atomic bitwise exclusive OR (XOR). + * + * This routine atomically sets @a target to the bitwise exclusive OR (XOR) of + * @a target and @a value. + * + * @param target Address of atomic variable. + * @param value Value to XOR + * + * @return Previous value of @a target. + */ + +static inline atomic_val_t atomic_xor(atomic_t *target, atomic_val_t value) +{ + return __atomic_fetch_xor(target, value, __ATOMIC_SEQ_CST); +} + +/** + * + * @brief Atomic bitwise AND. + * + * This routine atomically sets @a target to the bitwise AND of @a target + * and @a value. + * + * @param target Address of atomic variable. + * @param value Value to AND. + * + * @return Previous value of @a target. + */ + +static inline atomic_val_t atomic_and(atomic_t *target, atomic_val_t value) +{ + return __atomic_fetch_and(target, value, __ATOMIC_SEQ_CST); +} + +/** + * + * @brief Atomic bitwise NAND. + * + * This routine atomically sets @a target to the bitwise NAND of @a target + * and @a value. (This operation is equivalent to target = ~(target & value).) + * + * @param target Address of atomic variable. + * @param value Value to NAND. + * + * @return Previous value of @a target. + */ + +static inline atomic_val_t atomic_nand(atomic_t *target, atomic_val_t value) +{ + return __atomic_fetch_nand(target, value, __ATOMIC_SEQ_CST); +} + + /** + * @brief Initialize an atomic variable. + * + * This macro can be used to initialize an atomic variable. For example, + * @code atomic_t my_var = ATOMIC_INIT(75); @endcode + * + * @param i Value to assign to atomic variable. + */ +#define ATOMIC_INIT(i) (i) + + /** + * @cond INTERNAL_HIDDEN + */ + +#define ATOMIC_BITS (sizeof(atomic_val_t) * 8) +#define ATOMIC_MASK(bit) (1 << ((bit) & (ATOMIC_BITS - 1))) +#define ATOMIC_ELEM(addr, bit) ((addr) + ((bit) / ATOMIC_BITS)) + + /** + * INTERNAL_HIDDEN @endcond + */ + + /** + * @brief Define an array of atomic variables. + * + * This macro defines an array of atomic variables containing at least + * @a num_bits bits. + * + * @note + * If used from file scope, the bits of the array are initialized to zero; + * if used from within a function, the bits are left uninitialized. + * + * @param name Name of array of atomic variables. + * @param num_bits Number of bits needed. + */ +#define ATOMIC_DEFINE(name, num_bits) \ + atomic_t name[1 + ((num_bits) - 1) / ATOMIC_BITS] + + /** + * @brief Atomically test a bit. + * + * This routine tests whether bit number @a bit of @a target is set or not. + * The target may be a single atomic variable or an array of them. + * + * @param target Address of atomic variable or array. + * @param bit Bit number (starting from 0). + * + * @return 1 if the bit was set, 0 if it wasn't. + */ + static inline int + atomic_test_bit(const atomic_t *target, int bit) + { + atomic_val_t val = atomic_get(ATOMIC_ELEM(target, bit)); + + return (1 & (val >> (bit & (ATOMIC_BITS - 1)))); + } + + /** + * @brief Atomically test and clear a bit. + * + * Atomically clear bit number @a bit of @a target and return its old value. + * The target may be a single atomic variable or an array of them. + * + * @param target Address of atomic variable or array. + * @param bit Bit number (starting from 0). + * + * @return 1 if the bit was set, 0 if it wasn't. + */ + static inline int + atomic_test_and_clear_bit(atomic_t *target, int bit) + { + atomic_val_t mask = ATOMIC_MASK(bit); + atomic_val_t old; + + old = atomic_and(ATOMIC_ELEM(target, bit), ~mask); + + return (old & mask) != 0; + } + + /** + * @brief Atomically set a bit. + * + * Atomically set bit number @a bit of @a target and return its old value. + * The target may be a single atomic variable or an array of them. + * + * @param target Address of atomic variable or array. + * @param bit Bit number (starting from 0). + * + * @return 1 if the bit was set, 0 if it wasn't. + */ + static inline int + atomic_test_and_set_bit(atomic_t *target, int bit) + { + atomic_val_t mask = ATOMIC_MASK(bit); + atomic_val_t old; + + old = atomic_or(ATOMIC_ELEM(target, bit), mask); + + return (old & mask) != 0; + } + + /** + * @brief Atomically clear a bit. + * + * Atomically clear bit number @a bit of @a target. + * The target may be a single atomic variable or an array of them. + * + * @param target Address of atomic variable or array. + * @param bit Bit number (starting from 0). + * + * @return N/A + */ + static inline void + atomic_clear_bit(atomic_t *target, int bit) + { + atomic_val_t mask = ATOMIC_MASK(bit); + + atomic_and(ATOMIC_ELEM(target, bit), ~mask); + } + + /** + * @brief Atomically set a bit. + * + * Atomically set bit number @a bit of @a target. + * The target may be a single atomic variable or an array of them. + * + * @param target Address of atomic variable or array. + * @param bit Bit number (starting from 0). + * + * @return N/A + */ + static inline void + atomic_set_bit(atomic_t *target, int bit) + { + atomic_val_t mask = ATOMIC_MASK(bit); + + atomic_or(ATOMIC_ELEM(target, bit), mask); + } + +/** +* @brief Atomically set a bit to a given value. +* +* Atomically set bit number @a bit of @a target to value @a val. +* The target may be a single atomic variable or an array of them. +* +* @param target Address of atomic variable or array. +* @param bit Bit number (starting from 0). +* @param val true for 1, false for 0. +* +* @return N/A +*/ +static inline void atomic_set_bit_to(atomic_t *target, int bit, bool val) +{ + atomic_val_t mask = ATOMIC_MASK(bit); + + if (val) { + (void)atomic_or(ATOMIC_ELEM(target, bit), mask); + } else { + (void)atomic_and(ATOMIC_ELEM(target, bit), ~mask); + } +} + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ATOMIC_H__ */ diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/beacon.c b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/beacon.c new file mode 100644 index 000000000..da909852f --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/beacon.c @@ -0,0 +1,411 @@ +/* Bluetooth Mesh */ + +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "os/os_mbuf.h" +#include "mesh/mesh.h" + +#include "syscfg/syscfg.h" +#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG_BEACON)) +#include "host/ble_hs_log.h" + +#include "adv.h" +#include "mesh_priv.h" +#include "net.h" +#include "prov.h" +#include "crypto.h" +#include "beacon.h" +#include "foundation.h" + +#define UNPROVISIONED_INTERVAL (K_SECONDS(5)) +#define PROVISIONED_INTERVAL (K_SECONDS(10)) + +#define BEACON_TYPE_UNPROVISIONED 0x00 +#define BEACON_TYPE_SECURE 0x01 + +/* 3 transmissions, 20ms interval */ +#define UNPROV_XMIT BT_MESH_TRANSMIT(2, 20) + +/* 1 transmission, 20ms interval */ +#define PROV_XMIT BT_MESH_TRANSMIT(0, 20) + +static struct k_delayed_work beacon_timer; + +static struct bt_mesh_subnet *cache_check(u8_t data[21]) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) { + struct bt_mesh_subnet *sub = &bt_mesh.sub[i]; + + if (sub->net_idx == BT_MESH_KEY_UNUSED) { + continue; + } + + if (!memcmp(sub->beacon_cache, data, 21)) { + return sub; + } + } + + return NULL; +} + +static void cache_add(u8_t data[21], struct bt_mesh_subnet *sub) +{ + memcpy(sub->beacon_cache, data, 21); +} + +static void beacon_complete(int err, void *user_data) +{ + struct bt_mesh_subnet *sub = user_data; + + BT_DBG("err %d", err); + + sub->beacon_sent = k_uptime_get_32(); +} + +void bt_mesh_beacon_create(struct bt_mesh_subnet *sub, + struct os_mbuf *buf) +{ + u8_t flags = bt_mesh_net_flags(sub); + struct bt_mesh_subnet_keys *keys; + + net_buf_simple_add_u8(buf, BEACON_TYPE_SECURE); + + if (sub->kr_flag) { + keys = &sub->keys[1]; + } else { + keys = &sub->keys[0]; + } + + net_buf_simple_add_u8(buf, flags); + + /* Network ID */ + net_buf_simple_add_mem(buf, keys->net_id, 8); + + /* IV Index */ + net_buf_simple_add_be32(buf, bt_mesh.iv_index); + + net_buf_simple_add_mem(buf, sub->auth, 8); + + BT_DBG("net_idx 0x%04x flags 0x%02x NetID %s", sub->net_idx, + flags, bt_hex(keys->net_id, 8)); + BT_DBG("IV Index 0x%08x Auth %s", (unsigned) bt_mesh.iv_index, + bt_hex(sub->auth, 8)); +} + +/* If the interval has passed or is within 5 seconds from now send a beacon */ +#define BEACON_THRESHOLD(sub) (K_SECONDS(10 * ((sub)->beacons_last + 1)) - \ + K_SECONDS(5)) + +static int secure_beacon_send(void) +{ + static const struct bt_mesh_send_cb send_cb = { + .end = beacon_complete, + }; + u32_t now = k_uptime_get_32(); + int i; + + BT_DBG(""); + + for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) { + struct bt_mesh_subnet *sub = &bt_mesh.sub[i]; + struct os_mbuf *buf; + u32_t time_diff; + + if (sub->net_idx == BT_MESH_KEY_UNUSED) { + continue; + } + + time_diff = now - sub->beacon_sent; + if (time_diff < K_SECONDS(600) && + time_diff < BEACON_THRESHOLD(sub)) { + continue; + } + + buf = bt_mesh_adv_create(BT_MESH_ADV_BEACON, PROV_XMIT, + K_NO_WAIT); + if (!buf) { + BT_ERR("Unable to allocate beacon buffer"); + return -ENOBUFS; + } + + bt_mesh_beacon_create(sub, buf); + + bt_mesh_adv_send(buf, &send_cb, sub); + net_buf_unref(buf); + } + + return 0; +} + +static int unprovisioned_beacon_send(void) +{ +#if (MYNEWT_VAL(BLE_MESH_PB_ADV)) + const struct bt_mesh_prov *prov; + u8_t uri_hash[16] = { 0 }; + struct os_mbuf *buf; + u16_t oob_info; + + BT_DBG("unprovisioned_beacon_send"); + + buf = bt_mesh_adv_create(BT_MESH_ADV_BEACON, UNPROV_XMIT, K_NO_WAIT); + if (!buf) { + BT_ERR("Unable to allocate beacon buffer"); + return -ENOBUFS; + } + + prov = bt_mesh_prov_get(); + + net_buf_add_u8(buf, BEACON_TYPE_UNPROVISIONED); + net_buf_add_mem(buf, prov->uuid, 16); + + if (prov->uri && bt_mesh_s1(prov->uri, uri_hash) == 0) { + oob_info = prov->oob_info | BT_MESH_PROV_OOB_URI; + } else { + oob_info = prov->oob_info; + } + + net_buf_add_be16(buf, oob_info); + net_buf_add_mem(buf, uri_hash, 4); + + bt_mesh_adv_send(buf, NULL, NULL); + net_buf_unref(buf); + + if (prov->uri) { + size_t len; + + buf = bt_mesh_adv_create(BT_MESH_ADV_URI, UNPROV_XMIT, + K_NO_WAIT); + if (!buf) { + BT_ERR("Unable to allocate URI buffer"); + return -ENOBUFS; + } + + len = strlen(prov->uri); + if (net_buf_tailroom(buf) < len) { + BT_WARN("Too long URI to fit advertising data"); + } else { + net_buf_add_mem(buf, prov->uri, len); + bt_mesh_adv_send(buf, NULL, NULL); + } + + net_buf_unref(buf); + } + +#endif /* MYNEWT_VAL(BLE_MESH_PB_ADV) */ + return 0; +} + +static void update_beacon_observation(void) +{ + static bool first_half; + int i; + + /* Observation period is 20 seconds, whereas the beacon timer + * runs every 10 seconds. We process what's happened during the + * window only after the seconnd half. + */ + first_half = !first_half; + if (first_half) { + return; + } + + for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) { + struct bt_mesh_subnet *sub = &bt_mesh.sub[i]; + + if (sub->net_idx == BT_MESH_KEY_UNUSED) { + continue; + } + + sub->beacons_last = sub->beacons_cur; + sub->beacons_cur = 0; + } +} + +static void beacon_send(struct ble_npl_event *work) +{ + /* Don't send anything if we have an active provisioning link */ + if ((MYNEWT_VAL(BLE_MESH_PROV)) && bt_prov_active()) { + k_delayed_work_submit(&beacon_timer, UNPROVISIONED_INTERVAL); + return; + } + + BT_DBG(""); + + if (bt_mesh_is_provisioned()) { + update_beacon_observation(); + secure_beacon_send(); + + /* Only resubmit if beaconing is still enabled */ + if (bt_mesh_beacon_get() == BT_MESH_BEACON_ENABLED || + atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_INITIATOR)) { + k_delayed_work_submit(&beacon_timer, + PROVISIONED_INTERVAL); + } + } else { + unprovisioned_beacon_send(); + k_delayed_work_submit(&beacon_timer, UNPROVISIONED_INTERVAL); + } + +} + +static void secure_beacon_recv(struct os_mbuf *buf) +{ + u8_t *data, *net_id, *auth; + struct bt_mesh_subnet *sub; + u32_t iv_index; + bool new_key, kr_change, iv_change; + u8_t flags; + + if (buf->om_len < 21) { + BT_ERR("Too short secure beacon (len %u)", buf->om_len); + return; + } + + sub = cache_check(buf->om_data); + if (sub) { + /* We've seen this beacon before - just update the stats */ + goto update_stats; + } + + /* So we can add to the cache if auth matches */ + data = buf->om_data; + + flags = net_buf_simple_pull_u8(buf); + net_id = net_buf_simple_pull_mem(buf, 8); + iv_index = net_buf_simple_pull_be32(buf); + auth = buf->om_data; + + BT_DBG("flags 0x%02x id %s iv_index 0x%08x", + flags, bt_hex(net_id, 8), (unsigned) iv_index); + + sub = bt_mesh_subnet_find(net_id, flags, iv_index, auth, &new_key); + if (!sub) { + BT_DBG("No subnet that matched beacon"); + return; + } + + if (sub->kr_phase == BT_MESH_KR_PHASE_2 && !new_key) { + BT_WARN("Ignoring Phase 2 KR Update secured using old key"); + return; + } + + cache_add(data, sub); + + /* If we have NetKey0 accept initiation only from it */ + if (bt_mesh_subnet_get(BT_MESH_KEY_PRIMARY) && + sub->net_idx != BT_MESH_KEY_PRIMARY) { + BT_WARN("Ignoring secure beacon on non-primary subnet"); + goto update_stats; + } + + BT_DBG("net_idx 0x%04x iv_index 0x%08x, current iv_index 0x%08x", + sub->net_idx, (unsigned) iv_index, (unsigned) bt_mesh.iv_index); + + if (atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_INITIATOR) && + (atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS) == + BT_MESH_IV_UPDATE(flags))) { + bt_mesh_beacon_ivu_initiator(false); + } + + iv_change = bt_mesh_net_iv_update(iv_index, BT_MESH_IV_UPDATE(flags)); + + kr_change = bt_mesh_kr_update(sub, BT_MESH_KEY_REFRESH(flags), new_key); + if (kr_change) { + bt_mesh_net_beacon_update(sub); + } + + if (iv_change) { + /* Update all subnets */ + bt_mesh_net_sec_update(NULL); + } else if (kr_change) { + /* Key Refresh without IV Update only impacts one subnet */ + bt_mesh_net_sec_update(sub); + } + +update_stats: + if (bt_mesh_beacon_get() == BT_MESH_BEACON_ENABLED && + sub->beacons_cur < 0xff) { + sub->beacons_cur++; + } +} + +void bt_mesh_beacon_recv(struct os_mbuf *buf) +{ + u8_t type; + + BT_DBG("%u bytes: %s", buf->om_len, bt_hex(buf->om_data, buf->om_len)); + + if (buf->om_len < 1) { + BT_ERR("Too short beacon"); + return; + } + + type = net_buf_simple_pull_u8(buf); + switch (type) { + case BEACON_TYPE_UNPROVISIONED: + BT_DBG("Ignoring unprovisioned device beacon"); + break; + case BEACON_TYPE_SECURE: + secure_beacon_recv(buf); + break; + default: + BT_WARN("Unknown beacon type 0x%02x", type); + break; + } +} + +void bt_mesh_beacon_init(void) +{ + k_delayed_work_init(&beacon_timer, beacon_send); +} + +void bt_mesh_beacon_ivu_initiator(bool enable) +{ + atomic_set_bit_to(bt_mesh.flags, BT_MESH_IVU_INITIATOR, enable); + + if (enable) { + k_work_submit(&beacon_timer.work); + } else if (bt_mesh_beacon_get() == BT_MESH_BEACON_DISABLED) { + k_delayed_work_cancel(&beacon_timer); + } +} + +void bt_mesh_beacon_enable(void) +{ + int i; + + if (!bt_mesh_is_provisioned()) { + k_work_submit(&beacon_timer.work); + return; + } + + for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) { + struct bt_mesh_subnet *sub = &bt_mesh.sub[i]; + + if (sub->net_idx == BT_MESH_KEY_UNUSED) { + continue; + } + + sub->beacons_last = 0; + sub->beacons_cur = 0; + + bt_mesh_net_beacon_update(sub); + } + + k_work_submit(&beacon_timer.work); +} + +void bt_mesh_beacon_disable(void) +{ + if (!atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_INITIATOR)) { + k_delayed_work_cancel(&beacon_timer); + } +} diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/beacon.h b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/beacon.h new file mode 100644 index 000000000..ac4bfed8a --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/beacon.h @@ -0,0 +1,26 @@ +/* Bluetooth Mesh */ + +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __BEACON_H__ +#define __BEACON_H__ + +#include "os/os_mbuf.h" + +void bt_mesh_beacon_enable(void); +void bt_mesh_beacon_disable(void); + +void bt_mesh_beacon_ivu_initiator(bool enable); + +void bt_mesh_beacon_recv(struct os_mbuf *buf); + +void bt_mesh_beacon_create(struct bt_mesh_subnet *sub, + struct os_mbuf *buf); + +void bt_mesh_beacon_init(void); + +#endif diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/ble_att_priv.h b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/ble_att_priv.h new file mode 100644 index 000000000..2201d4ddb --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/ble_att_priv.h @@ -0,0 +1,307 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_BLE_ATT_PRIV_ +#define H_BLE_ATT_PRIV_ + +#include +#include "stats/stats.h" +#include "host/ble_att.h" +#include "host/ble_uuid.h" +#include "nimble/nimble_npl.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct os_mbuf; +struct ble_hs_conn; +struct ble_l2cap_chan; +struct ble_att_find_info_req; +struct ble_att_error_rsp; +struct ble_att_mtu_cmd; +struct ble_att_read_req; +struct ble_att_read_blob_req; +struct ble_att_read_type_req; +struct ble_att_read_group_type_req; +struct ble_att_read_group_type_rsp; +struct ble_att_find_type_value_req; +struct ble_att_write_req; +struct ble_att_prep_write_cmd; +struct ble_att_exec_write_req; +struct ble_att_notify_req; +struct ble_att_indicate_req; + +STATS_SECT_START(ble_att_stats) + STATS_SECT_ENTRY(error_rsp_rx) + STATS_SECT_ENTRY(error_rsp_tx) + STATS_SECT_ENTRY(mtu_req_rx) + STATS_SECT_ENTRY(mtu_req_tx) + STATS_SECT_ENTRY(mtu_rsp_rx) + STATS_SECT_ENTRY(mtu_rsp_tx) + STATS_SECT_ENTRY(find_info_req_rx) + STATS_SECT_ENTRY(find_info_req_tx) + STATS_SECT_ENTRY(find_info_rsp_rx) + STATS_SECT_ENTRY(find_info_rsp_tx) + STATS_SECT_ENTRY(find_type_value_req_rx) + STATS_SECT_ENTRY(find_type_value_req_tx) + STATS_SECT_ENTRY(find_type_value_rsp_rx) + STATS_SECT_ENTRY(find_type_value_rsp_tx) + STATS_SECT_ENTRY(read_type_req_rx) + STATS_SECT_ENTRY(read_type_req_tx) + STATS_SECT_ENTRY(read_type_rsp_rx) + STATS_SECT_ENTRY(read_type_rsp_tx) + STATS_SECT_ENTRY(read_req_rx) + STATS_SECT_ENTRY(read_req_tx) + STATS_SECT_ENTRY(read_rsp_rx) + STATS_SECT_ENTRY(read_rsp_tx) + STATS_SECT_ENTRY(read_blob_req_rx) + STATS_SECT_ENTRY(read_blob_req_tx) + STATS_SECT_ENTRY(read_blob_rsp_rx) + STATS_SECT_ENTRY(read_blob_rsp_tx) + STATS_SECT_ENTRY(read_mult_req_rx) + STATS_SECT_ENTRY(read_mult_req_tx) + STATS_SECT_ENTRY(read_mult_rsp_rx) + STATS_SECT_ENTRY(read_mult_rsp_tx) + STATS_SECT_ENTRY(read_group_type_req_rx) + STATS_SECT_ENTRY(read_group_type_req_tx) + STATS_SECT_ENTRY(read_group_type_rsp_rx) + STATS_SECT_ENTRY(read_group_type_rsp_tx) + STATS_SECT_ENTRY(write_req_rx) + STATS_SECT_ENTRY(write_req_tx) + STATS_SECT_ENTRY(write_rsp_rx) + STATS_SECT_ENTRY(write_rsp_tx) + STATS_SECT_ENTRY(prep_write_req_rx) + STATS_SECT_ENTRY(prep_write_req_tx) + STATS_SECT_ENTRY(prep_write_rsp_rx) + STATS_SECT_ENTRY(prep_write_rsp_tx) + STATS_SECT_ENTRY(exec_write_req_rx) + STATS_SECT_ENTRY(exec_write_req_tx) + STATS_SECT_ENTRY(exec_write_rsp_rx) + STATS_SECT_ENTRY(exec_write_rsp_tx) + STATS_SECT_ENTRY(notify_req_rx) + STATS_SECT_ENTRY(notify_req_tx) + STATS_SECT_ENTRY(indicate_req_rx) + STATS_SECT_ENTRY(indicate_req_tx) + STATS_SECT_ENTRY(indicate_rsp_rx) + STATS_SECT_ENTRY(indicate_rsp_tx) + STATS_SECT_ENTRY(write_cmd_rx) + STATS_SECT_ENTRY(write_cmd_tx) +STATS_SECT_END +extern STATS_SECT_DECL(ble_att_stats) ble_att_stats; + +struct ble_att_prep_entry { + SLIST_ENTRY(ble_att_prep_entry) bape_next; + uint16_t bape_handle; + uint16_t bape_offset; + + /* XXX: This is wasteful; we should use one mbuf chain for the entire + * prepared write, and compress the data into as few mbufs as possible. + */ + struct os_mbuf *bape_value; +}; + +SLIST_HEAD(ble_att_prep_entry_list, ble_att_prep_entry); + +struct ble_att_svr_conn { + /** This list is sorted by attribute handle ID. */ + struct ble_att_prep_entry_list basc_prep_list; + ble_npl_time_t basc_prep_timeout_at; +}; + +/** + * Handles a host attribute request. + * + * @param entry The host attribute being requested. + * @param op The operation being performed on the attribute. + * @param arg The request data associated with that host + * attribute. + * + * @return 0 on success; + * One of the BLE_ATT_ERR_[...] codes on + * failure. + */ +typedef int ble_att_svr_access_fn(uint16_t conn_handle, uint16_t attr_handle, + uint8_t op, uint16_t offset, + struct os_mbuf **om, void *arg); + +int ble_att_svr_register(const ble_uuid_t *uuid, uint8_t flags, + uint8_t min_key_size, uint16_t *handle_id, + ble_att_svr_access_fn *cb, void *cb_arg); + +struct ble_att_svr_entry { + STAILQ_ENTRY(ble_att_svr_entry) ha_next; + + const ble_uuid_t *ha_uuid; + uint8_t ha_flags; + uint8_t ha_min_key_size; + uint16_t ha_handle_id; + ble_att_svr_access_fn *ha_cb; + void *ha_cb_arg; +}; + +SLIST_HEAD(ble_att_clt_entry_list, ble_att_clt_entry); + +/*** @gen */ + +struct ble_l2cap_chan *ble_att_create_chan(uint16_t conn_handle); +int ble_att_conn_chan_find(uint16_t conn_handle, struct ble_hs_conn **out_conn, + struct ble_l2cap_chan **out_chan); +void ble_att_inc_tx_stat(uint8_t att_op); +void ble_att_truncate_to_mtu(const struct ble_l2cap_chan *att_chan, + struct os_mbuf *txom); +void ble_att_set_peer_mtu(struct ble_l2cap_chan *chan, uint16_t peer_mtu); +uint16_t ble_att_chan_mtu(const struct ble_l2cap_chan *chan); +int ble_att_init(void); + +#define BLE_ATT_LOG_CMD(is_tx, cmd_name, conn_handle, log_cb, cmd) \ + BLE_HS_LOG_CMD((is_tx), "att", (cmd_name), (conn_handle), (log_cb), (cmd)) + +#define BLE_ATT_LOG_EMPTY_CMD(is_tx, cmd_name, conn_handle) \ + BLE_HS_LOG_EMPTY_CMD((is_tx), "att", (cmd_name), (conn_handle)) + +/*** @svr */ + +int ble_att_svr_start(void); +void ble_att_svr_stop(void); + +struct ble_att_svr_entry * +ble_att_svr_find_by_uuid(struct ble_att_svr_entry *start_at, + const ble_uuid_t *uuid, + uint16_t end_handle); +uint16_t ble_att_svr_prev_handle(void); +int ble_att_svr_rx_mtu(uint16_t conn_handle, struct os_mbuf **rxom); +struct ble_att_svr_entry *ble_att_svr_find_by_handle(uint16_t handle_id); +int32_t ble_att_svr_ticks_until_tmo(const struct ble_att_svr_conn *svr, + ble_npl_time_t now); +int ble_att_svr_rx_find_info(uint16_t conn_handle, struct os_mbuf **rxom); +int ble_att_svr_rx_find_type_value(uint16_t conn_handle, + struct os_mbuf **rxom); +int ble_att_svr_rx_read_type(uint16_t conn_handle, + struct os_mbuf **rxom); +int ble_att_svr_rx_read_group_type(uint16_t conn_handle, + struct os_mbuf **rxom); +int ble_att_svr_rx_read(uint16_t conn_handle, + struct os_mbuf **rxom); +int ble_att_svr_rx_read_blob(uint16_t conn_handle, + struct os_mbuf **rxom); +int ble_att_svr_rx_read_mult(uint16_t conn_handle, + struct os_mbuf **rxom); +int ble_att_svr_rx_write(uint16_t conn_handle, + struct os_mbuf **rxom); +int ble_att_svr_rx_write_no_rsp(uint16_t conn_handle, struct os_mbuf **rxom); +int ble_att_svr_rx_prep_write(uint16_t conn_handle, + struct os_mbuf **rxom); +int ble_att_svr_rx_exec_write(uint16_t conn_handle, + struct os_mbuf **rxom); +int ble_att_svr_rx_notify(uint16_t conn_handle, + struct os_mbuf **rxom); +int ble_att_svr_rx_indicate(uint16_t conn_handle, + struct os_mbuf **rxom); +void ble_att_svr_prep_clear(struct ble_att_prep_entry_list *prep_list); +int ble_att_svr_read_handle(uint16_t conn_handle, uint16_t attr_handle, + uint16_t offset, struct os_mbuf *om, + uint8_t *out_att_err); +void ble_att_svr_reset(void); +int ble_att_svr_init(void); + +void ble_att_svr_hide_range(uint16_t start_handle, uint16_t end_handle); +void ble_att_svr_restore_range(uint16_t start_handle, uint16_t end_handle); + +int ble_att_svr_tx_error_rsp(uint16_t conn_handle, struct os_mbuf *txom, + uint8_t req_op, uint16_t handle, + uint8_t error_code); +/*** $clt */ + +/** An information-data entry in a find information response. */ +struct ble_att_find_info_idata { + uint16_t attr_handle; + ble_uuid_any_t uuid; +}; + +/** A handles-information entry in a find by type value response. */ +struct ble_att_find_type_value_hinfo { + uint16_t attr_handle; + uint16_t group_end_handle; +}; + +/** An attribute-data entry in a read by type response. */ +struct ble_att_read_type_adata { + uint16_t att_handle; + int value_len; + uint8_t *value; + +}; + +/** An attribute-data entry in a read by group type response. */ +struct ble_att_read_group_type_adata { + uint16_t att_handle; + uint16_t end_group_handle; + int value_len; + uint8_t *value; +}; + +int ble_att_clt_rx_error(uint16_t conn_handle, struct os_mbuf **rxom); +int ble_att_clt_tx_mtu(uint16_t conn_handle, uint16_t mtu); +int ble_att_clt_rx_mtu(uint16_t conn_handle, struct os_mbuf **rxom); +int ble_att_clt_tx_read(uint16_t conn_handle, uint16_t handle); +int ble_att_clt_rx_read(uint16_t conn_handle, struct os_mbuf **rxom); +int ble_att_clt_tx_read_blob(uint16_t conn_handle, uint16_t handle, + uint16_t offset); +int ble_att_clt_rx_read_blob(uint16_t conn_handle, struct os_mbuf **rxom); +int ble_att_clt_tx_read_mult(uint16_t conn_handle, + const uint16_t *handles, int num_handles); +int ble_att_clt_rx_read_mult(uint16_t conn_handle, struct os_mbuf **rxom); +int ble_att_clt_tx_read_type(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle, const ble_uuid_t *uuid); +int ble_att_clt_rx_read_type(uint16_t conn_handle, struct os_mbuf **rxom); +int ble_att_clt_tx_read_group_type(uint16_t conn_handle, + uint16_t start_handle, uint16_t end_handle, + const ble_uuid_t *uuid128); +int ble_att_clt_rx_read_group_type(uint16_t conn_handle, + struct os_mbuf **rxom); +int ble_att_clt_tx_find_info(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle); +int ble_att_clt_rx_find_info(uint16_t conn_handle, struct os_mbuf **rxom); +int ble_att_clt_tx_find_type_value(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle, uint16_t attribute_type, + const void *attribute_value, int value_len); +int ble_att_clt_rx_find_type_value(uint16_t conn_handle, + struct os_mbuf **rxom); +int ble_att_clt_tx_write_req(uint16_t conn_handle, uint16_t handle, + struct os_mbuf *txom); +int ble_att_clt_tx_write_cmd(uint16_t conn_handle, uint16_t handle, + struct os_mbuf *txom); +int ble_att_clt_tx_prep_write(uint16_t conn_handle, uint16_t handle, + uint16_t offset, struct os_mbuf *txom); +int ble_att_clt_rx_prep_write(uint16_t conn_handle, struct os_mbuf **rxom); +int ble_att_clt_tx_exec_write(uint16_t conn_handle, uint8_t flags); +int ble_att_clt_rx_exec_write(uint16_t conn_handle, struct os_mbuf **rxom); +int ble_att_clt_rx_write(uint16_t conn_handle, struct os_mbuf **rxom); +int ble_att_clt_tx_notify(uint16_t conn_handle, uint16_t handle, + struct os_mbuf *txom); +int ble_att_clt_tx_indicate(uint16_t conn_handle, uint16_t handle, + struct os_mbuf *txom); +int ble_att_clt_rx_indicate(uint16_t conn_handle, struct os_mbuf **rxom); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/ble_gatt_priv.h b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/ble_gatt_priv.h new file mode 100644 index 000000000..4a59635b8 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/ble_gatt_priv.h @@ -0,0 +1,199 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_BLE_GATT_PRIV_ +#define H_BLE_GATT_PRIV_ + +#include "syscfg/syscfg.h" +#include "stats/stats.h" +#include "host/ble_gatt.h" +#ifdef __cplusplus +extern "C" { +#endif + +struct ble_att_read_type_adata; +struct ble_att_find_type_value_hinfo; +struct ble_att_find_info_idata; +struct ble_att_read_group_type_adata; +struct ble_att_prep_write_cmd; + +STATS_SECT_START(ble_gattc_stats) + STATS_SECT_ENTRY(mtu) + STATS_SECT_ENTRY(mtu_fail) + STATS_SECT_ENTRY(disc_all_svcs) + STATS_SECT_ENTRY(disc_all_svcs_fail) + STATS_SECT_ENTRY(disc_svc_uuid) + STATS_SECT_ENTRY(disc_svc_uuid_fail) + STATS_SECT_ENTRY(find_inc_svcs) + STATS_SECT_ENTRY(find_inc_svcs_fail) + STATS_SECT_ENTRY(disc_all_chrs) + STATS_SECT_ENTRY(disc_all_chrs_fail) + STATS_SECT_ENTRY(disc_chrs_uuid) + STATS_SECT_ENTRY(disc_chrs_uuid_fail) + STATS_SECT_ENTRY(disc_all_dscs) + STATS_SECT_ENTRY(disc_all_dscs_fail) + STATS_SECT_ENTRY(read) + STATS_SECT_ENTRY(read_fail) + STATS_SECT_ENTRY(read_uuid) + STATS_SECT_ENTRY(read_uuid_fail) + STATS_SECT_ENTRY(read_long) + STATS_SECT_ENTRY(read_long_fail) + STATS_SECT_ENTRY(read_mult) + STATS_SECT_ENTRY(read_mult_fail) + STATS_SECT_ENTRY(write_no_rsp) + STATS_SECT_ENTRY(write_no_rsp_fail) + STATS_SECT_ENTRY(write) + STATS_SECT_ENTRY(write_fail) + STATS_SECT_ENTRY(write_long) + STATS_SECT_ENTRY(write_long_fail) + STATS_SECT_ENTRY(write_reliable) + STATS_SECT_ENTRY(write_reliable_fail) + STATS_SECT_ENTRY(notify) + STATS_SECT_ENTRY(notify_fail) + STATS_SECT_ENTRY(indicate) + STATS_SECT_ENTRY(indicate_fail) + STATS_SECT_ENTRY(proc_timeout) +STATS_SECT_END +extern STATS_SECT_DECL(ble_gattc_stats) ble_gattc_stats; + +STATS_SECT_START(ble_gatts_stats) + STATS_SECT_ENTRY(svcs) + STATS_SECT_ENTRY(chrs) + STATS_SECT_ENTRY(dscs) + STATS_SECT_ENTRY(svc_def_reads) + STATS_SECT_ENTRY(svc_inc_reads) + STATS_SECT_ENTRY(chr_def_reads) + STATS_SECT_ENTRY(chr_val_reads) + STATS_SECT_ENTRY(chr_val_writes) + STATS_SECT_ENTRY(dsc_reads) + STATS_SECT_ENTRY(dsc_writes) +STATS_SECT_END +extern STATS_SECT_DECL(ble_gatts_stats) ble_gatts_stats; + +#define BLE_GATT_CHR_DECL_SZ_16 5 +#define BLE_GATT_CHR_DECL_SZ_128 19 + +typedef uint8_t ble_gatts_conn_flags; + +struct ble_gatts_conn { + struct ble_gatts_clt_cfg *clt_cfgs; + int num_clt_cfgs; + + uint16_t indicate_val_handle; +}; + +/*** @client. */ + +int ble_gattc_locked_by_cur_task(void); +void ble_gatts_indicate_fail_notconn(uint16_t conn_handle); + +void ble_gattc_rx_err(uint16_t conn_handle, uint16_t handle, uint16_t status); +void ble_gattc_rx_mtu(uint16_t conn_handle, int status, uint16_t chan_mtu); +void ble_gattc_rx_read_type_adata(uint16_t conn_handle, + struct ble_att_read_type_adata *adata); +void ble_gattc_rx_read_type_complete(uint16_t conn_handle, int status); +void ble_gattc_rx_read_rsp(uint16_t conn_handle, int status, + struct os_mbuf **rxom); +void ble_gattc_rx_read_blob_rsp(uint16_t conn_handle, int status, + struct os_mbuf **rxom); +void ble_gattc_rx_read_mult_rsp(uint16_t conn_handle, int status, + struct os_mbuf **rxom); +void ble_gattc_rx_read_group_type_adata( + uint16_t conn_handle, struct ble_att_read_group_type_adata *adata); +void ble_gattc_rx_read_group_type_complete(uint16_t conn_handle, int rc); +void ble_gattc_rx_find_type_value_hinfo( + uint16_t conn_handle, struct ble_att_find_type_value_hinfo *hinfo); +void ble_gattc_rx_find_type_value_complete(uint16_t conn_handle, int status); +void ble_gattc_rx_write_rsp(uint16_t conn_handle); +void ble_gattc_rx_prep_write_rsp(uint16_t conn_handle, int status, + uint16_t handle, uint16_t offset, + struct os_mbuf **rxom); +void ble_gattc_rx_exec_write_rsp(uint16_t conn_handle, int status); +void ble_gattc_rx_indicate_rsp(uint16_t conn_handle); +void ble_gattc_rx_find_info_idata(uint16_t conn_handle, + struct ble_att_find_info_idata *idata); +void ble_gattc_rx_find_info_complete(uint16_t conn_handle, int status); +void ble_gattc_connection_txable(uint16_t conn_handle); +void ble_gattc_connection_broken(uint16_t conn_handle); +int32_t ble_gattc_timer(void); + +int ble_gattc_any_jobs(void); +int ble_gattc_init(void); + +/*** @server. */ +#define BLE_GATTS_CLT_CFG_F_NOTIFY 0x0001 +#define BLE_GATTS_CLT_CFG_F_INDICATE 0x0002 +#define BLE_GATTS_CLT_CFG_F_MODIFIED 0x0080 /* Internal only. */ +#define BLE_GATTS_CLT_CFG_F_RESERVED 0xfffc + +#define BLE_GATTS_INC_SVC_LEN_NO_UUID 4 +#define BLE_GATTS_INC_SVC_LEN_UUID 6 + +/** + * Contains counts of resources required by the GATT server. The contents of + * this struct are generally used to populate a configuration struct before + * the host is initialized. + */ +struct ble_gatt_resources { + /** Number of services. */ + uint16_t svcs; + + /** Number of included services. */ + uint16_t incs; + + /** Number of characteristics. */ + uint16_t chrs; + + /** Number of descriptors. */ + uint16_t dscs; + + /** + * Number of client characteristic configuration descriptors. Each of + * these also contributes to the total descriptor count. + */ + uint16_t cccds; + + /** Total number of ATT attributes. */ + uint16_t attrs; +}; + +int ble_gatts_rx_indicate_ack(uint16_t conn_handle, uint16_t chr_val_handle); +int ble_gatts_send_next_indicate(uint16_t conn_handle); +void ble_gatts_tx_notifications(void); +void ble_gatts_bonding_established(uint16_t conn_handle); +void ble_gatts_bonding_restored(uint16_t conn_handle); +void ble_gatts_connection_broken(uint16_t conn_handle); +void ble_gatts_lcl_svc_foreach(ble_gatt_svc_foreach_fn cb, void *arg); +int ble_gatts_register_svcs(const struct ble_gatt_svc_def *svcs, + ble_gatt_register_fn *register_cb, + void *cb_arg); +int ble_gatts_clt_cfg_access(uint16_t conn_handle, uint16_t attr_handle, + uint8_t op, uint16_t offset, struct os_mbuf **om, + void *arg); + +/*** @misc. */ +int ble_gatts_conn_can_alloc(void); +int ble_gatts_conn_init(struct ble_gatts_conn *gatts_conn); +int ble_gatts_init(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/ble_hs_conn_priv.h b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/ble_hs_conn_priv.h new file mode 100644 index 000000000..92aacd405 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/ble_hs_conn_priv.h @@ -0,0 +1,128 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_BLE_HS_CONN_ +#define H_BLE_HS_CONN_ + +#include +#include "ble_l2cap_priv.h" +#include "ble_gatt_priv.h" +#include "ble_att_priv.h" +#ifdef __cplusplus +extern "C" { +#endif + +struct hci_le_conn_complete; +struct hci_create_conn; +struct ble_l2cap_chan; + +typedef uint8_t ble_hs_conn_flags_t; + +#define BLE_HS_CONN_F_MASTER 0x01 +#define BLE_HS_CONN_F_TERMINATING 0x02 +#define BLE_HS_CONN_F_TX_FRAG 0x04 /* Cur ACL packet partially txed. */ + +struct ble_hs_conn { + SLIST_ENTRY(ble_hs_conn) bhc_next; + uint16_t bhc_handle; + uint8_t bhc_our_addr_type; +#if MYNEWT_VAL(BLE_EXT_ADV) + uint8_t bhc_our_rnd_addr[6]; +#endif + ble_addr_t bhc_peer_addr; + ble_addr_t bhc_our_rpa_addr; + ble_addr_t bhc_peer_rpa_addr; + + uint16_t bhc_itvl; + uint16_t bhc_latency; + uint16_t bhc_supervision_timeout; + uint8_t bhc_master_clock_accuracy; + + uint32_t supported_feat; + + ble_hs_conn_flags_t bhc_flags; + + struct ble_l2cap_chan_list bhc_channels; + struct ble_l2cap_chan *bhc_rx_chan; /* Channel rxing current packet. */ + ble_npl_time_t bhc_rx_timeout; + + /** + * Count of packets sent over this connection that the controller has not + * transmitted or flushed yet. + */ + uint16_t bhc_outstanding_pkts; + +#if MYNEWT_VAL(BLE_HS_FLOW_CTRL) + /** + * Count of packets received over this connection that have been processed + * and freed. + */ + uint16_t bhc_completed_pkts; +#endif + + /** Queue of outgoing packets that could not be sent. */ + STAILQ_HEAD(, os_mbuf_pkthdr) bhc_tx_q; + + struct ble_att_svr_conn bhc_att_svr; + struct ble_gatts_conn bhc_gatt_svr; + + struct ble_gap_sec_state bhc_sec_state; + + ble_gap_event_fn *bhc_cb; + void *bhc_cb_arg; +}; + +struct ble_hs_conn_addrs { + ble_addr_t our_id_addr; + ble_addr_t peer_id_addr; + ble_addr_t our_ota_addr; + ble_addr_t peer_ota_addr; +}; + +int ble_hs_conn_can_alloc(void); +struct ble_hs_conn *ble_hs_conn_alloc(uint16_t conn_handle); +void ble_hs_conn_free(struct ble_hs_conn *conn); +void ble_hs_conn_insert(struct ble_hs_conn *conn); +void ble_hs_conn_remove(struct ble_hs_conn *conn); +struct ble_hs_conn *ble_hs_conn_find(uint16_t conn_handle); +struct ble_hs_conn *ble_hs_conn_find_assert(uint16_t conn_handle); +struct ble_hs_conn *ble_hs_conn_find_by_addr(const ble_addr_t *addr); +struct ble_hs_conn *ble_hs_conn_find_by_idx(int idx); +int ble_hs_conn_exists(uint16_t conn_handle); +struct ble_hs_conn *ble_hs_conn_first(void); +struct ble_l2cap_chan *ble_hs_conn_chan_find_by_scid(struct ble_hs_conn *conn, + uint16_t cid); +struct ble_l2cap_chan *ble_hs_conn_chan_find_by_dcid(struct ble_hs_conn *conn, + uint16_t cid); +int ble_hs_conn_chan_insert(struct ble_hs_conn *conn, + struct ble_l2cap_chan *chan); +void +ble_hs_conn_delete_chan(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan); + +void ble_hs_conn_addrs(const struct ble_hs_conn *conn, + struct ble_hs_conn_addrs *addrs); +int32_t ble_hs_conn_timer(void); + +int ble_hs_conn_init(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/ble_l2cap_coc_priv.h b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/ble_l2cap_coc_priv.h new file mode 100644 index 000000000..0a1a97b77 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/ble_l2cap_coc_priv.h @@ -0,0 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_L2CAP_COC_PRIV_ +#define H_L2CAP_COC_PRIV_ + +#include +#include "syscfg/syscfg.h" +#include "os/queue.h" +#include "os/os_mbuf.h" +#include "host/ble_l2cap.h" +#include "ble_l2cap_sig_priv.h" +#ifdef __cplusplus +extern "C" { +#endif + +#define BLE_L2CAP_COC_CID_START 0x0040 +#define BLE_L2CAP_COC_CID_END 0x007F + +struct ble_l2cap_chan; + +#define BLE_L2CAP_COC_FLAG_STALLED 0x01 + +struct ble_l2cap_coc_endpoint { + struct os_mbuf *sdu; + uint16_t mtu; + uint16_t credits; + uint16_t data_offset; + uint8_t flags; +}; + +struct ble_l2cap_coc_srv { + STAILQ_ENTRY(ble_l2cap_coc_srv) next; + uint16_t psm; + uint16_t mtu; + ble_l2cap_event_fn *cb; + void *cb_arg; +}; + +#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) != 0 +int ble_l2cap_coc_init(void); +int ble_l2cap_coc_create_server(uint16_t psm, uint16_t mtu, + ble_l2cap_event_fn *cb, void *cb_arg); +int ble_l2cap_coc_create_srv_chan(uint16_t conn_handle, uint16_t psm, + struct ble_l2cap_chan **chan); +struct ble_l2cap_chan * ble_l2cap_coc_chan_alloc(uint16_t conn_handle, + uint16_t psm, uint16_t mtu, + struct os_mbuf *sdu_rx, + ble_l2cap_event_fn *cb, + void *cb_arg); +void ble_l2cap_coc_cleanup_chan(struct ble_l2cap_chan *chan); +void ble_l2cap_coc_le_credits_update(uint16_t conn_handle, uint16_t dcid, + uint16_t credits); +int ble_l2cap_coc_recv_ready(struct ble_l2cap_chan *chan, + struct os_mbuf *sdu_rx); +int ble_l2cap_coc_send(struct ble_l2cap_chan *chan, struct os_mbuf *sdu_tx); +#else +#define ble_l2cap_coc_init() 0 +#define ble_l2cap_coc_create_server(psm, mtu, cb, cb_arg) BLE_HS_ENOTSUP +#define ble_l2cap_coc_recv_ready(chan, sdu_rx) BLE_HS_ENOTSUP +#define ble_l2cap_coc_cleanup_chan(chan) +#define ble_l2cap_coc_send(chan, sdu_tx) BLE_HS_ENOTSUP +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* H_L2CAP_COC_PRIV_ */ diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/ble_l2cap_priv.h b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/ble_l2cap_priv.h new file mode 100644 index 000000000..640974d2a --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/ble_l2cap_priv.h @@ -0,0 +1,125 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_L2CAP_PRIV_ +#define H_L2CAP_PRIV_ + +#include "ble_l2cap_coc_priv.h" +#include "host/ble_l2cap.h" +#include +#include "stats/stats.h" +#include "os/queue.h" +#include "os/os_mbuf.h" +#ifdef __cplusplus +extern "C" { +#endif + +struct ble_hs_conn; +struct hci_data_hdr; + +STATS_SECT_START(ble_l2cap_stats) + STATS_SECT_ENTRY(chan_create) + STATS_SECT_ENTRY(chan_delete) + STATS_SECT_ENTRY(update_init) + STATS_SECT_ENTRY(update_rx) + STATS_SECT_ENTRY(update_fail) + STATS_SECT_ENTRY(proc_timeout) + STATS_SECT_ENTRY(sig_tx) + STATS_SECT_ENTRY(sig_rx) + STATS_SECT_ENTRY(sm_tx) + STATS_SECT_ENTRY(sm_rx) +STATS_SECT_END +extern STATS_SECT_DECL(ble_l2cap_stats) ble_l2cap_stats; + +extern struct os_mempool ble_l2cap_chan_pool; + +/* This is nimble specific; packets sent to the black hole CID do not elicit + * an "invalid CID" response. + */ +#define BLE_L2CAP_CID_BLACK_HOLE 0xffff + +#define BLE_L2CAP_HDR_SZ 4 + +typedef uint8_t ble_l2cap_chan_flags; + +typedef int ble_l2cap_rx_fn(struct ble_l2cap_chan *chan); + +struct ble_l2cap_chan { + SLIST_ENTRY(ble_l2cap_chan) next; + uint16_t conn_handle; + uint16_t dcid; + uint16_t scid; + uint16_t my_mtu; + uint16_t peer_mtu; /* 0 if not exchanged. */ + ble_l2cap_chan_flags flags; + + struct os_mbuf *rx_buf; + uint16_t rx_len; /* Length of current reassembled rx packet. */ + + ble_l2cap_rx_fn *rx_fn; + +#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) != 0 + uint16_t psm; + struct ble_l2cap_coc_endpoint coc_rx; + struct ble_l2cap_coc_endpoint coc_tx; + uint16_t initial_credits; + ble_l2cap_event_fn *cb; + void *cb_arg; +#endif +}; + +struct ble_l2cap_hdr { + uint16_t len; + uint16_t cid; +}; + +typedef int ble_l2cap_tx_fn(struct ble_hs_conn *conn, + struct ble_l2cap_chan *chan); + +#define BLE_L2CAP_CHAN_F_TXED_MTU 0x01 /* We have sent our MTU. */ + +SLIST_HEAD(ble_l2cap_chan_list, ble_l2cap_chan); + +int ble_l2cap_parse_hdr(struct os_mbuf *om, int off, + struct ble_l2cap_hdr *l2cap_hdr); +struct os_mbuf *ble_l2cap_prepend_hdr(struct os_mbuf *om, uint16_t cid, + uint16_t len); + +struct ble_l2cap_chan *ble_l2cap_chan_alloc(uint16_t conn_handle); +void ble_l2cap_chan_free(struct ble_l2cap_chan *chan); + +bool ble_l2cap_is_mtu_req_sent(const struct ble_l2cap_chan *chan); + +int ble_l2cap_rx(struct ble_hs_conn *conn, + struct hci_data_hdr *hci_hdr, + struct os_mbuf *om, + ble_l2cap_rx_fn **out_rx_cb, + int *out_reject_cid); +int ble_l2cap_tx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan, + struct os_mbuf *txom); + +void ble_l2cap_remove_rx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan); + +int ble_l2cap_init(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/ble_l2cap_sig_priv.h b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/ble_l2cap_sig_priv.h new file mode 100644 index 000000000..1a6fb8293 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/ble_l2cap_sig_priv.h @@ -0,0 +1,124 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef H_BLE_L2CAP_SIG_ +#define H_BLE_L2CAP_SIG_ + +#include "syscfg/syscfg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define BLE_L2CAP_SIG_MTU 100 /* This is our own default. */ + +#define BLE_L2CAP_SIG_HDR_SZ 4 +struct ble_l2cap_sig_hdr { + uint8_t op; + uint8_t identifier; + uint16_t length; + uint8_t data[0]; +} __attribute__((packed)); + +#define BLE_L2CAP_SIG_REJECT_MIN_SZ 2 +struct ble_l2cap_sig_reject { + uint16_t reason; + uint8_t data[0]; +} __attribute__((packed)); + +#define BLE_L2CAP_SIG_UPDATE_REQ_SZ 8 +struct ble_l2cap_sig_update_req { + uint16_t itvl_min; + uint16_t itvl_max; + uint16_t slave_latency; + uint16_t timeout_multiplier; +} __attribute__((packed)); + +#define BLE_L2CAP_SIG_UPDATE_RSP_SZ 2 +struct ble_l2cap_sig_update_rsp { + uint16_t result; +} __attribute__((packed)); + +#define BLE_L2CAP_SIG_UPDATE_RSP_RESULT_ACCEPT 0x0000 +#define BLE_L2CAP_SIG_UPDATE_RSP_RESULT_REJECT 0x0001 + +struct ble_l2cap_sig_le_con_req { + uint16_t psm; + uint16_t scid; + uint16_t mtu; + uint16_t mps; + uint16_t credits; +} __attribute__((packed)); + +struct ble_l2cap_sig_le_con_rsp { + uint16_t dcid; + uint16_t mtu; + uint16_t mps; + uint16_t credits; + uint16_t result; +} __attribute__((packed)); + +struct ble_l2cap_sig_disc_req { + uint16_t dcid; + uint16_t scid; +} __attribute__((packed)); + +struct ble_l2cap_sig_disc_rsp { + uint16_t dcid; + uint16_t scid; +} __attribute__((packed)); + +struct ble_l2cap_sig_le_credits { + uint16_t scid; + uint16_t credits; +} __attribute__((packed)); + +void ble_l2cap_sig_hdr_parse(void *payload, uint16_t len, + struct ble_l2cap_sig_hdr *hdr); +int ble_l2cap_sig_reject_tx(uint16_t conn_handle, + uint8_t id, uint16_t reason, + void *data, int data_len); +int ble_l2cap_sig_reject_invalid_cid_tx(uint16_t conn_handle, uint8_t id, + uint16_t src_cid, uint16_t dst_cid); +int ble_l2cap_sig_tx(uint16_t conn_handle, struct os_mbuf *txom); +void *ble_l2cap_sig_cmd_get(uint8_t opcode, uint8_t id, uint16_t len, + struct os_mbuf **txom); +#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) != 0 +int ble_l2cap_sig_coc_connect(uint16_t conn_handle, uint16_t psm, uint16_t mtu, + struct os_mbuf *sdu_rx, + ble_l2cap_event_fn *cb, void *cb_arg); +int ble_l2cap_sig_disconnect(struct ble_l2cap_chan *chan); +int ble_l2cap_sig_le_credits(uint16_t conn_handle, uint16_t scid, + uint16_t credits); +#else +#define ble_l2cap_sig_coc_connect(conn_handle, psm, mtu, sdu_rx, cb, cb_arg) \ + BLE_HS_ENOTSUP +#define ble_l2cap_sig_disconnect(chan) BLE_HS_ENOTSUP +#endif + +void ble_l2cap_sig_conn_broken(uint16_t conn_handle, int reason); +int32_t ble_l2cap_sig_timer(void); +struct ble_l2cap_chan *ble_l2cap_sig_create_chan(uint16_t conn_handle); +int ble_l2cap_sig_init(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/cfg_cli.c b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/cfg_cli.c new file mode 100644 index 000000000..17f01b993 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/cfg_cli.c @@ -0,0 +1,1488 @@ +/* Bluetooth Mesh */ + +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "syscfg/syscfg.h" +#if MYNEWT_VAL(BLE_MESH_CFG_CLI) + +#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG_MODEL)) +#include "mesh/mesh.h" + +#include +#include +#include + +#include "net.h" +#include "foundation.h" + +#define CID_NVAL 0xffff + +struct comp_data { + u8_t *status; + struct os_mbuf *comp; +}; + +static s32_t msg_timeout = K_SECONDS(5); + +static struct bt_mesh_cfg_cli *cli; + +static void comp_data_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct comp_data *param; + size_t to_copy; + + BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); + + if (cli->op_pending != OP_DEV_COMP_DATA_STATUS) { + BT_WARN("Unexpected Composition Data Status"); + return; + } + + param = cli->op_param; + + *(param->status) = net_buf_simple_pull_u8(buf); + to_copy = min(net_buf_simple_tailroom(param->comp), buf->om_len); + net_buf_simple_add_mem(param->comp, buf->om_data, to_copy); + + k_sem_give(&cli->op_sync); +} + +static void state_status_u8(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf*buf, + u32_t expect_status) +{ + u8_t *status; + + BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); + + if (cli->op_pending != expect_status) { + BT_WARN("Unexpected Status (0x%08x != 0x%08x)", + (unsigned) cli->op_pending, (unsigned) expect_status); + return; + } + + status = cli->op_param; + *status = net_buf_simple_pull_u8(buf); + + k_sem_give(&cli->op_sync); +} + +static void beacon_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + state_status_u8(model, ctx, buf, OP_BEACON_STATUS); +} + +static void ttl_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf*buf) +{ + state_status_u8(model, ctx, buf, OP_DEFAULT_TTL_STATUS); +} + +static void friend_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf*buf) +{ + state_status_u8(model, ctx, buf, OP_FRIEND_STATUS); +} + +static void gatt_proxy_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf*buf) +{ + state_status_u8(model, ctx, buf, OP_GATT_PROXY_STATUS); +} + +struct relay_param { + u8_t *status; + u8_t *transmit; +}; + +static void relay_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf*buf) +{ + struct relay_param *param; + + BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); + + if (cli->op_pending != OP_RELAY_STATUS) { + BT_WARN("Unexpected Relay Status message"); + return; + } + + param = cli->op_param; + *param->status = net_buf_simple_pull_u8(buf); + *param->transmit = net_buf_simple_pull_u8(buf); + + k_sem_give(&cli->op_sync); +} + +struct net_key_param { + u8_t *status; + u16_t net_idx; +}; + +static void net_key_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct net_key_param *param; + u16_t net_idx, app_idx; + u8_t status; + + BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); + + if (cli->op_pending != OP_NET_KEY_STATUS) { + BT_WARN("Unexpected Net Key Status message"); + return; + } + + status = net_buf_simple_pull_u8(buf); + key_idx_unpack(buf, &net_idx, &app_idx); + + param = cli->op_param; + if (param->net_idx != net_idx) { + BT_WARN("Net Key Status key index does not match"); + return; + } + + if (param->status) { + *param->status = status; + } + + k_sem_give(&cli->op_sync); +} + +struct app_key_param { + u8_t *status; + u16_t net_idx; + u16_t app_idx; +}; + +static void app_key_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf*buf) +{ + struct app_key_param *param; + u16_t net_idx, app_idx; + u8_t status; + + BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); + + if (cli->op_pending != OP_APP_KEY_STATUS) { + BT_WARN("Unexpected App Key Status message"); + return; + } + + status = net_buf_simple_pull_u8(buf); + key_idx_unpack(buf, &net_idx, &app_idx); + + param = cli->op_param; + if (param->net_idx != net_idx || param->app_idx != app_idx) { + BT_WARN("App Key Status key indices did not match"); + return; + } + + if (param->status) { + *param->status = status; + } + + k_sem_give(&cli->op_sync); +} + +struct mod_app_param { + u8_t *status; + u16_t elem_addr; + u16_t mod_app_idx; + u16_t mod_id; + u16_t cid; +}; + +static void mod_app_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf*buf) +{ + u16_t elem_addr, mod_app_idx, mod_id, cid; + struct mod_app_param *param; + u8_t status; + + BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); + + if (cli->op_pending != OP_MOD_APP_STATUS) { + BT_WARN("Unexpected Model App Status message"); + return; + } + + status = net_buf_simple_pull_u8(buf); + elem_addr = net_buf_simple_pull_le16(buf); + mod_app_idx = net_buf_simple_pull_le16(buf); + + if (buf->om_len >= 4) { + cid = net_buf_simple_pull_le16(buf); + } else { + cid = CID_NVAL; + } + + mod_id = net_buf_simple_pull_le16(buf); + + param = cli->op_param; + if (param->elem_addr != elem_addr || + param->mod_app_idx != mod_app_idx || param->mod_id != mod_id || + param->cid != cid) { + BT_WARN("Model App Status parameters did not match"); + return; + } + + if (param->status) { + *param->status = status; + } + + k_sem_give(&cli->op_sync); +} + +struct mod_pub_param { + u16_t mod_id; + u16_t cid; + u16_t elem_addr; + u8_t *status; + struct bt_mesh_cfg_mod_pub *pub; +}; + +static void mod_pub_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf*buf) +{ + u16_t mod_id, cid, elem_addr; + struct mod_pub_param *param; + u8_t status; + + BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); + + if (cli->op_pending != OP_MOD_PUB_STATUS) { + BT_WARN("Unexpected Model Pub Status message"); + return; + } + + param = cli->op_param; + if (param->cid != CID_NVAL) { + if (buf->om_len < 14) { + BT_WARN("Unexpected Mod Pub Status with SIG Model"); + return; + } + + cid = sys_get_le16(&buf->om_data[10]); + mod_id = sys_get_le16(&buf->om_data[12]); + } else { + if (buf->om_len > 12) { + BT_WARN("Unexpected Mod Pub Status with Vendor Model"); + return; + } + + cid = CID_NVAL; + mod_id = sys_get_le16(&buf->om_data[10]); + } + + if (mod_id != param->mod_id || cid != param->cid) { + BT_WARN("Mod Pub Model ID or Company ID mismatch"); + return; + } + + status = net_buf_simple_pull_u8(buf); + + elem_addr = net_buf_simple_pull_le16(buf); + if (elem_addr != param->elem_addr) { + BT_WARN("Model Pub Status for unexpected element (0x%04x)", + elem_addr); + return; + } + + if (param->status) { + *param->status = status; + } + + if (param->pub) { + param->pub->addr = net_buf_simple_pull_le16(buf); + param->pub->app_idx = net_buf_simple_pull_le16(buf); + param->pub->cred_flag = (param->pub->app_idx & BIT(12)); + param->pub->app_idx &= BIT_MASK(12); + param->pub->ttl = net_buf_simple_pull_u8(buf); + param->pub->period = net_buf_simple_pull_u8(buf); + param->pub->transmit = net_buf_simple_pull_u8(buf); + } + + k_sem_give(&cli->op_sync); +} + +struct mod_sub_param { + u8_t *status; + u16_t elem_addr; + u16_t *sub_addr; + u16_t *expect_sub; + u16_t mod_id; + u16_t cid; +}; + +static void mod_sub_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf*buf) +{ + u16_t elem_addr, sub_addr, mod_id, cid; + struct mod_sub_param *param; + u8_t status; + + BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); + + if (cli->op_pending != OP_MOD_SUB_STATUS) { + BT_WARN("Unexpected Model Subscription Status message"); + return; + } + + status = net_buf_simple_pull_u8(buf); + elem_addr = net_buf_simple_pull_le16(buf); + sub_addr = net_buf_simple_pull_le16(buf); + + if (buf->om_len >= 4) { + cid = net_buf_simple_pull_le16(buf); + } else { + cid = CID_NVAL; + } + + mod_id = net_buf_simple_pull_le16(buf); + + param = cli->op_param; + if (param->elem_addr != elem_addr || param->mod_id != mod_id || + (param->expect_sub && *param->expect_sub != sub_addr) || + param->cid != cid) { + BT_WARN("Model Subscription Status parameters did not match"); + return; + } + + if (param->sub_addr) { + *param->sub_addr = sub_addr; + } + + if (param->status) { + *param->status = status; + } + + k_sem_give(&cli->op_sync); +} + +struct hb_sub_param { + u8_t *status; + struct bt_mesh_cfg_hb_sub *sub; +}; + +static void hb_sub_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf*buf) +{ + struct hb_sub_param *param; + + BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); + + if (cli->op_pending != OP_HEARTBEAT_SUB_STATUS) { + BT_WARN("Unexpected Heartbeat Subscription Status message"); + return; + } + + param = cli->op_param; + + *param->status = net_buf_simple_pull_u8(buf); + + param->sub->src = net_buf_simple_pull_le16(buf); + param->sub->dst = net_buf_simple_pull_le16(buf); + param->sub->period = net_buf_simple_pull_u8(buf); + param->sub->count = net_buf_simple_pull_u8(buf); + param->sub->min = net_buf_simple_pull_u8(buf); + param->sub->max = net_buf_simple_pull_u8(buf); + + k_sem_give(&cli->op_sync); +} + +struct hb_pub_param { + u8_t *status; + struct bt_mesh_cfg_hb_pub *pub; +}; + +static void hb_pub_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct hb_pub_param *param; + + BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); + + if (cli->op_pending != OP_HEARTBEAT_PUB_STATUS) { + BT_WARN("Unexpected Heartbeat Publication Status message"); + return; + } + + param = cli->op_param; + + *param->status = net_buf_simple_pull_u8(buf); + + if (param->pub) { + param->pub->dst = net_buf_simple_pull_le16(buf); + param->pub->count = net_buf_simple_pull_u8(buf); + param->pub->period = net_buf_simple_pull_u8(buf); + param->pub->ttl = net_buf_simple_pull_u8(buf); + param->pub->feat = net_buf_simple_pull_u8(buf); + param->pub->net_idx = net_buf_simple_pull_u8(buf); + } + + k_sem_give(&cli->op_sync); +} + +const struct bt_mesh_model_op bt_mesh_cfg_cli_op[] = { + { OP_DEV_COMP_DATA_STATUS, 15, comp_data_status }, + { OP_BEACON_STATUS, 1, beacon_status }, + { OP_DEFAULT_TTL_STATUS, 1, ttl_status }, + { OP_FRIEND_STATUS, 1, friend_status }, + { OP_GATT_PROXY_STATUS, 1, gatt_proxy_status }, + { OP_RELAY_STATUS, 2, relay_status }, + { OP_NET_KEY_STATUS, 3, net_key_status }, + { OP_APP_KEY_STATUS, 4, app_key_status }, + { OP_MOD_APP_STATUS, 7, mod_app_status }, + { OP_MOD_PUB_STATUS, 12, mod_pub_status }, + { OP_MOD_SUB_STATUS, 7, mod_sub_status }, + { OP_HEARTBEAT_SUB_STATUS, 9, hb_sub_status }, + { OP_HEARTBEAT_PUB_STATUS, 10, hb_pub_status }, + BT_MESH_MODEL_OP_END, +}; + +static int cli_prepare(void *param, u32_t op) +{ + if (!cli) { + BT_ERR("No available Configuration Client context!"); + return -EINVAL; + } + + if (cli->op_pending) { + BT_WARN("Another synchronous operation pending"); + return -EBUSY; + } + + cli->op_param = param; + cli->op_pending = op; + + return 0; +} + +static void cli_reset(void) +{ + cli->op_pending = 0; + cli->op_param = NULL; +} + +static int cli_wait(void) +{ + int err; + + err = k_sem_take(&cli->op_sync, msg_timeout); + + cli_reset(); + + return err; +} + +int bt_mesh_cfg_comp_data_get(u16_t net_idx, u16_t addr, u8_t page, + u8_t *status, struct os_mbuf *comp) +{ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4); + struct bt_mesh_msg_ctx ctx = { + .net_idx = net_idx, + .app_idx = BT_MESH_KEY_DEV, + .addr = addr, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; + struct comp_data param = { + .status = status, + .comp = comp, + }; + int err; + + err = cli_prepare(¶m, OP_DEV_COMP_DATA_STATUS); + if (err) { + goto done; + } + + bt_mesh_model_msg_init(msg, OP_DEV_COMP_DATA_GET); + net_buf_simple_add_u8(msg, page); + + err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); + if (err) { + BT_ERR("model_send() failed (err %d)", err); + cli_reset(); + goto done; + } + + err = cli_wait(); +done: + os_mbuf_free_chain(msg); + return err; +} + +static int get_state_u8(u16_t net_idx, u16_t addr, u32_t op, u32_t rsp, + u8_t *val) +{ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 0 + 4); + struct bt_mesh_msg_ctx ctx = { + .net_idx = net_idx, + .app_idx = BT_MESH_KEY_DEV, + .addr = addr, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; + int err; + + err = cli_prepare(val, rsp); + if (err) { + goto done; + } + + bt_mesh_model_msg_init(msg, op); + + err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); + if (err) { + BT_ERR("model_send() failed (err %d)", err); + cli_reset(); + goto done; + } + + err = cli_wait(); +done: + os_mbuf_free_chain(msg); + return err; +} + +static int set_state_u8(u16_t net_idx, u16_t addr, u32_t op, u32_t rsp, + u8_t new_val, u8_t *val) +{ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4); + struct bt_mesh_msg_ctx ctx = { + .net_idx = net_idx, + .app_idx = BT_MESH_KEY_DEV, + .addr = addr, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; + int err; + + err = cli_prepare(val, rsp); + if (err) { + goto done; + } + + bt_mesh_model_msg_init(msg, op); + net_buf_simple_add_u8(msg, new_val); + + err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); + if (err) { + BT_ERR("model_send() failed (err %d)", err); + cli_reset(); + goto done; + } + + err = cli_wait(); +done: + os_mbuf_free_chain(msg); + return err; +} + +int bt_mesh_cfg_beacon_get(u16_t net_idx, u16_t addr, u8_t *status) +{ + return get_state_u8(net_idx, addr, OP_BEACON_GET, OP_BEACON_STATUS, + status); +} + +int bt_mesh_cfg_beacon_set(u16_t net_idx, u16_t addr, u8_t val, u8_t *status) +{ + return set_state_u8(net_idx, addr, OP_BEACON_SET, OP_BEACON_STATUS, + val, status); +} + +int bt_mesh_cfg_ttl_get(u16_t net_idx, u16_t addr, u8_t *ttl) +{ + return get_state_u8(net_idx, addr, OP_DEFAULT_TTL_GET, + OP_DEFAULT_TTL_STATUS, ttl); +} + +int bt_mesh_cfg_ttl_set(u16_t net_idx, u16_t addr, u8_t val, u8_t *ttl) +{ + return set_state_u8(net_idx, addr, OP_DEFAULT_TTL_SET, + OP_DEFAULT_TTL_STATUS, val, ttl); +} + +int bt_mesh_cfg_friend_get(u16_t net_idx, u16_t addr, u8_t *status) +{ + return get_state_u8(net_idx, addr, OP_FRIEND_GET, + OP_FRIEND_STATUS, status); +} + +int bt_mesh_cfg_friend_set(u16_t net_idx, u16_t addr, u8_t val, u8_t *status) +{ + return set_state_u8(net_idx, addr, OP_FRIEND_SET, OP_FRIEND_STATUS, + val, status); +} + +int bt_mesh_cfg_gatt_proxy_get(u16_t net_idx, u16_t addr, u8_t *status) +{ + return get_state_u8(net_idx, addr, OP_GATT_PROXY_GET, + OP_GATT_PROXY_STATUS, status); +} + +int bt_mesh_cfg_gatt_proxy_set(u16_t net_idx, u16_t addr, u8_t val, + u8_t *status) +{ + return set_state_u8(net_idx, addr, OP_GATT_PROXY_SET, + OP_GATT_PROXY_STATUS, val, status); +} + +int bt_mesh_cfg_relay_get(u16_t net_idx, u16_t addr, u8_t *status, + u8_t *transmit) +{ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 0 + 4); + struct bt_mesh_msg_ctx ctx = { + .net_idx = net_idx, + .app_idx = BT_MESH_KEY_DEV, + .addr = addr, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; + struct relay_param param = { + .status = status, + .transmit = transmit, + }; + int err; + + err = cli_prepare(¶m, OP_RELAY_STATUS); + if (err) { + goto done; + } + + bt_mesh_model_msg_init(msg, OP_RELAY_GET); + + err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); + if (err) { + BT_ERR("model_send() failed (err %d)", err); + cli_reset(); + goto done; + } + + err = cli_wait(); +done: + os_mbuf_free_chain(msg); + return err; +} + +int bt_mesh_cfg_relay_set(u16_t net_idx, u16_t addr, u8_t new_relay, + u8_t new_transmit, u8_t *status, u8_t *transmit) +{ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 2 + 4); + struct bt_mesh_msg_ctx ctx = { + .net_idx = net_idx, + .app_idx = BT_MESH_KEY_DEV, + .addr = addr, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; + struct relay_param param = { + .status = status, + .transmit = transmit, + }; + int err; + + err = cli_prepare(¶m, OP_RELAY_STATUS); + if (err) { + goto done; + } + + bt_mesh_model_msg_init(msg, OP_RELAY_SET); + net_buf_simple_add_u8(msg, new_relay); + net_buf_simple_add_u8(msg, new_transmit); + + err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); + if (err) { + BT_ERR("model_send() failed (err %d)", err); + cli_reset(); + goto done; + } + + err = cli_wait(); +done: + os_mbuf_free_chain(msg); + return err; +} + +int bt_mesh_cfg_net_key_add(u16_t net_idx, u16_t addr, u16_t key_net_idx, + const u8_t net_key[16], u8_t *status) +{ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 18 + 4); + struct bt_mesh_msg_ctx ctx = { + .net_idx = net_idx, + .app_idx = BT_MESH_KEY_DEV, + .addr = addr, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; + struct net_key_param param = { + .status = status, + .net_idx = key_net_idx, + }; + int err; + + err = cli_prepare(¶m, OP_NET_KEY_STATUS); + if (err) { + goto done; + } + + bt_mesh_model_msg_init(msg, OP_NET_KEY_ADD); + net_buf_simple_add_le16(msg, key_net_idx); + net_buf_simple_add_mem(msg, net_key, 16); + + err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); + if (err) { + BT_ERR("model_send() failed (err %d)", err); + cli_reset(); + goto done; + } + + if (!status) { + cli_reset(); + goto done; + } + + err = cli_wait(); +done: + os_mbuf_free_chain(msg); + return err; +} + +int bt_mesh_cfg_app_key_add(u16_t net_idx, u16_t addr, u16_t key_net_idx, + u16_t key_app_idx, const u8_t app_key[16], + u8_t *status) +{ + struct os_mbuf *msg = NET_BUF_SIMPLE(1 + 19 + 4); + struct bt_mesh_msg_ctx ctx = { + .net_idx = net_idx, + .app_idx = BT_MESH_KEY_DEV, + .addr = addr, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; + struct app_key_param param = { + .status = status, + .net_idx = key_net_idx, + .app_idx = key_app_idx, + }; + int err; + + err = cli_prepare(¶m, OP_APP_KEY_STATUS); + if (err) { + goto done; + } + + bt_mesh_model_msg_init(msg, OP_APP_KEY_ADD); + key_idx_pack(msg, key_net_idx, key_app_idx); + net_buf_simple_add_mem(msg, app_key, 16); + + err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); + if (err) { + BT_ERR("model_send() failed (err %d)", err); + cli_reset(); + goto done; + } + + if (!status) { + cli_reset(); + goto done; + } + + err = cli_wait(); +done: + os_mbuf_free_chain(msg); + return err; +} + +static int mod_app_bind(u16_t net_idx, u16_t addr, u16_t elem_addr, + u16_t mod_app_idx, u16_t mod_id, u16_t cid, + u8_t *status) +{ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 8 + 4); + struct bt_mesh_msg_ctx ctx = { + .net_idx = net_idx, + .app_idx = BT_MESH_KEY_DEV, + .addr = addr, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; + struct mod_app_param param = { + .status = status, + .elem_addr = elem_addr, + .mod_app_idx = mod_app_idx, + .mod_id = mod_id, + .cid = cid, + }; + int err; + + err = cli_prepare(¶m, OP_MOD_APP_STATUS); + if (err) { + goto done; + } + + bt_mesh_model_msg_init(msg, OP_MOD_APP_BIND); + net_buf_simple_add_le16(msg, elem_addr); + net_buf_simple_add_le16(msg, mod_app_idx); + + if (cid != CID_NVAL) { + net_buf_simple_add_le16(msg, cid); + } + + net_buf_simple_add_le16(msg, mod_id); + + err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); + if (err) { + BT_ERR("model_send() failed (err %d)", err); + cli_reset(); + goto done; + } + + if (!status) { + cli_reset(); + goto done; + } + + err = cli_wait(); +done: + os_mbuf_free_chain(msg); + return err; +} + +int bt_mesh_cfg_mod_app_bind(u16_t net_idx, u16_t addr, u16_t elem_addr, + u16_t mod_app_idx, u16_t mod_id, u8_t *status) +{ + return mod_app_bind(net_idx, addr, elem_addr, mod_app_idx, mod_id, + CID_NVAL, status); +} + +int bt_mesh_cfg_mod_app_bind_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr, + u16_t mod_app_idx, u16_t mod_id, u16_t cid, + u8_t *status) +{ + if (cid == CID_NVAL) { + return -EINVAL; + } + + return mod_app_bind(net_idx, addr, elem_addr, mod_app_idx, mod_id, cid, + status); +} + +static int mod_sub(u32_t op, u16_t net_idx, u16_t addr, u16_t elem_addr, + u16_t sub_addr, u16_t mod_id, u16_t cid, u8_t *status) +{ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 8 + 4); + struct bt_mesh_msg_ctx ctx = { + .net_idx = net_idx, + .app_idx = BT_MESH_KEY_DEV, + .addr = addr, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; + struct mod_sub_param param = { + .status = status, + .elem_addr = elem_addr, + .expect_sub = &sub_addr, + .mod_id = mod_id, + .cid = cid, + }; + int err; + + err = cli_prepare(¶m, OP_MOD_SUB_STATUS); + if (err) { + goto done; + } + + bt_mesh_model_msg_init(msg, op); + net_buf_simple_add_le16(msg, elem_addr); + net_buf_simple_add_le16(msg, sub_addr); + + if (cid != CID_NVAL) { + net_buf_simple_add_le16(msg, cid); + } + + net_buf_simple_add_le16(msg, mod_id); + + err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); + if (err) { + BT_ERR("model_send() failed (err %d)", err); + cli_reset(); + goto done; + } + + if (!status) { + cli_reset(); + goto done; + } + + err = cli_wait(); +done: + os_mbuf_free_chain(msg); + return err; +} + +int bt_mesh_cfg_mod_sub_add(u16_t net_idx, u16_t addr, u16_t elem_addr, + u16_t sub_addr, u16_t mod_id, u8_t *status) +{ + return mod_sub(OP_MOD_SUB_ADD, net_idx, addr, elem_addr, sub_addr, + mod_id, CID_NVAL, status); +} + +int bt_mesh_cfg_mod_sub_add_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr, + u16_t sub_addr, u16_t mod_id, u16_t cid, + u8_t *status) +{ + if (cid == CID_NVAL) { + return -EINVAL; + } + + return mod_sub(OP_MOD_SUB_ADD, net_idx, addr, elem_addr, sub_addr, + mod_id, cid, status); +} + +int bt_mesh_cfg_mod_sub_del(u16_t net_idx, u16_t addr, u16_t elem_addr, + u16_t sub_addr, u16_t mod_id, u8_t *status) +{ + return mod_sub(OP_MOD_SUB_DEL, net_idx, addr, elem_addr, sub_addr, + mod_id, CID_NVAL, status); +} + +int bt_mesh_cfg_mod_sub_del_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr, + u16_t sub_addr, u16_t mod_id, u16_t cid, + u8_t *status) +{ + if (cid == CID_NVAL) { + return -EINVAL; + } + + return mod_sub(OP_MOD_SUB_DEL, net_idx, addr, elem_addr, sub_addr, + mod_id, cid, status); +} + +int bt_mesh_cfg_mod_sub_overwrite(u16_t net_idx, u16_t addr, u16_t elem_addr, + u16_t sub_addr, u16_t mod_id, u8_t *status) +{ + return mod_sub(OP_MOD_SUB_OVERWRITE, net_idx, addr, elem_addr, + sub_addr, mod_id, CID_NVAL, status); +} + +int bt_mesh_cfg_mod_sub_overwrite_vnd(u16_t net_idx, u16_t addr, + u16_t elem_addr, u16_t sub_addr, + u16_t mod_id, u16_t cid, u8_t *status) +{ + if (cid == CID_NVAL) { + return -EINVAL; + } + + return mod_sub(OP_MOD_SUB_OVERWRITE, net_idx, addr, elem_addr, + sub_addr, mod_id, cid, status); +} + +static int mod_sub_va(u32_t op, u16_t net_idx, u16_t addr, u16_t elem_addr, + const u8_t label[16], u16_t mod_id, u16_t cid, + u16_t *virt_addr, u8_t *status) +{ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 22 + 4); + struct bt_mesh_msg_ctx ctx = { + .net_idx = net_idx, + .app_idx = BT_MESH_KEY_DEV, + .addr = addr, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; + struct mod_sub_param param = { + .status = status, + .elem_addr = elem_addr, + .sub_addr = virt_addr, + .mod_id = mod_id, + .cid = cid, + }; + int err; + + err = cli_prepare(¶m, OP_MOD_SUB_STATUS); + if (err) { + goto done; + } + + BT_DBG("net_idx 0x%04x addr 0x%04x elem_addr 0x%04x label %s", + net_idx, addr, elem_addr, label); + BT_DBG("mod_id 0x%04x cid 0x%04x", mod_id, cid); + + bt_mesh_model_msg_init(msg, op); + net_buf_simple_add_le16(msg, elem_addr); + net_buf_simple_add_mem(msg, label, 16); + + if (cid != CID_NVAL) { + net_buf_simple_add_le16(msg, cid); + } + + net_buf_simple_add_le16(msg, mod_id); + + err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); + if (err) { + BT_ERR("model_send() failed (err %d)", err); + cli_reset(); + goto done; + } + + if (!status) { + cli_reset(); + goto done; + } + + err = cli_wait(); +done: + os_mbuf_free_chain(msg); + return err; +} + +int bt_mesh_cfg_mod_sub_va_add(u16_t net_idx, u16_t addr, u16_t elem_addr, + const u8_t label[16], u16_t mod_id, + u16_t *virt_addr, u8_t *status) +{ + return mod_sub_va(OP_MOD_SUB_VA_ADD, net_idx, addr, elem_addr, label, + mod_id, CID_NVAL, virt_addr, status); +} + +int bt_mesh_cfg_mod_sub_va_add_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr, + const u8_t label[16], u16_t mod_id, + u16_t cid, u16_t *virt_addr, u8_t *status) +{ + if (cid == CID_NVAL) { + return -EINVAL; + } + + return mod_sub_va(OP_MOD_SUB_VA_ADD, net_idx, addr, elem_addr, label, + mod_id, cid, virt_addr, status); +} + +int bt_mesh_cfg_mod_sub_va_del(u16_t net_idx, u16_t addr, u16_t elem_addr, + const u8_t label[16], u16_t mod_id, + u16_t *virt_addr, u8_t *status) +{ + return mod_sub_va(OP_MOD_SUB_VA_DEL, net_idx, addr, elem_addr, label, + mod_id, CID_NVAL, virt_addr, status); +} + +int bt_mesh_cfg_mod_sub_va_del_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr, + const u8_t label[16], u16_t mod_id, + u16_t cid, u16_t *virt_addr, u8_t *status) +{ + if (cid == CID_NVAL) { + return -EINVAL; + } + + return mod_sub_va(OP_MOD_SUB_VA_DEL, net_idx, addr, elem_addr, label, + mod_id, cid, virt_addr, status); +} + +int bt_mesh_cfg_mod_sub_va_overwrite(u16_t net_idx, u16_t addr, + u16_t elem_addr, const u8_t label[16], + u16_t mod_id, u16_t *virt_addr, + u8_t *status) +{ + return mod_sub_va(OP_MOD_SUB_VA_OVERWRITE, net_idx, addr, elem_addr, + label, mod_id, CID_NVAL, virt_addr, status); +} + +int bt_mesh_cfg_mod_sub_va_overwrite_vnd(u16_t net_idx, u16_t addr, + u16_t elem_addr, const u8_t label[16], + u16_t mod_id, u16_t cid, + u16_t *virt_addr, u8_t *status) +{ + if (cid == CID_NVAL) { + return -EINVAL; + } + + return mod_sub_va(OP_MOD_SUB_VA_OVERWRITE, net_idx, addr, elem_addr, + label, mod_id, cid, virt_addr, status); +} + +static int mod_pub_get(u16_t net_idx, u16_t addr, u16_t elem_addr, + u16_t mod_id, u16_t cid, + struct bt_mesh_cfg_mod_pub *pub, u8_t *status) +{ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 6 + 4); + struct bt_mesh_msg_ctx ctx = { + .net_idx = net_idx, + .app_idx = BT_MESH_KEY_DEV, + .addr = addr, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; + struct mod_pub_param param = { + .mod_id = mod_id, + .cid = cid, + .elem_addr = elem_addr, + .status = status, + .pub = pub, + }; + int err; + + err = cli_prepare(¶m, OP_MOD_PUB_STATUS); + if (err) { + goto done; + } + + bt_mesh_model_msg_init(msg, OP_MOD_PUB_GET); + + net_buf_simple_add_le16(msg, elem_addr); + + if (cid != CID_NVAL) { + net_buf_simple_add_le16(msg, cid); + } + + net_buf_simple_add_le16(msg, mod_id); + + err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); + if (err) { + BT_ERR("model_send() failed (err %d)", err); + cli_reset(); + goto done; + } + + if (!status) { + cli_reset(); + goto done; + } + + err = cli_wait(); +done: + os_mbuf_free_chain(msg); + return err; +} + +int bt_mesh_cfg_mod_pub_get(u16_t net_idx, u16_t addr, u16_t elem_addr, + u16_t mod_id, struct bt_mesh_cfg_mod_pub *pub, + u8_t *status) +{ + return mod_pub_get(net_idx, addr, elem_addr, mod_id, CID_NVAL, + pub, status); +} + +int bt_mesh_cfg_mod_pub_get_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr, + u16_t mod_id, u16_t cid, + struct bt_mesh_cfg_mod_pub *pub, u8_t *status) +{ + if (cid == CID_NVAL) { + return -EINVAL; + } + + return mod_pub_get(net_idx, addr, elem_addr, mod_id, cid, pub, status); +} + +static int mod_pub_set(u16_t net_idx, u16_t addr, u16_t elem_addr, + u16_t mod_id, u16_t cid, + struct bt_mesh_cfg_mod_pub *pub, u8_t *status) +{ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 13 + 4); + struct bt_mesh_msg_ctx ctx = { + .net_idx = net_idx, + .app_idx = BT_MESH_KEY_DEV, + .addr = addr, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; + struct mod_pub_param param = { + .mod_id = mod_id, + .cid = cid, + .elem_addr = elem_addr, + .status = status, + .pub = pub, + }; + int err; + + err = cli_prepare(¶m, OP_MOD_PUB_STATUS); + if (err) { + goto done; + } + + bt_mesh_model_msg_init(msg, OP_MOD_PUB_SET); + + net_buf_simple_add_le16(msg, elem_addr); + net_buf_simple_add_le16(msg, pub->addr); + net_buf_simple_add_le16(msg, (pub->app_idx & (pub->cred_flag << 12))); + net_buf_simple_add_u8(msg, pub->ttl); + net_buf_simple_add_u8(msg, pub->period); + net_buf_simple_add_u8(msg, pub->transmit); + + if (cid != CID_NVAL) { + net_buf_simple_add_le16(msg, cid); + } + + net_buf_simple_add_le16(msg, mod_id); + + err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); + if (err) { + BT_ERR("model_send() failed (err %d)", err); + cli_reset(); + goto done; + } + + if (!status) { + cli_reset(); + goto done; + } + + err = cli_wait(); +done: + os_mbuf_free_chain(msg); + return err; +} + +int bt_mesh_cfg_mod_pub_set(u16_t net_idx, u16_t addr, u16_t elem_addr, + u16_t mod_id, struct bt_mesh_cfg_mod_pub *pub, + u8_t *status) +{ + return mod_pub_set(net_idx, addr, elem_addr, mod_id, CID_NVAL, + pub, status); +} + +int bt_mesh_cfg_mod_pub_set_vnd(u16_t net_idx, u16_t addr, u16_t elem_addr, + u16_t mod_id, u16_t cid, + struct bt_mesh_cfg_mod_pub *pub, u8_t *status) +{ + if (cid == CID_NVAL) { + return -EINVAL; + } + + return mod_pub_set(net_idx, addr, elem_addr, mod_id, cid, pub, status); +} + +int bt_mesh_cfg_hb_sub_set(u16_t net_idx, u16_t addr, + struct bt_mesh_cfg_hb_sub *sub, u8_t *status) +{ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 5 + 4); + struct bt_mesh_msg_ctx ctx = { + .net_idx = net_idx, + .app_idx = BT_MESH_KEY_DEV, + .addr = addr, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; + struct hb_sub_param param = { + .status = status, + .sub = sub, + }; + int err; + + err = cli_prepare(¶m, OP_HEARTBEAT_SUB_STATUS); + if (err) { + goto done; + } + + bt_mesh_model_msg_init(msg, OP_HEARTBEAT_SUB_SET); + net_buf_simple_add_le16(msg, sub->src); + net_buf_simple_add_le16(msg, sub->dst); + net_buf_simple_add_u8(msg, sub->period); + + err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); + if (err) { + BT_ERR("model_send() failed (err %d)", err); + cli_reset(); + goto done; + } + + if (!status) { + cli_reset(); + goto done; + } + + err = cli_wait(); +done: + os_mbuf_free_chain(msg); + return err; +} + +int bt_mesh_cfg_hb_sub_get(u16_t net_idx, u16_t addr, + struct bt_mesh_cfg_hb_sub *sub, u8_t *status) +{ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 0 + 4); + struct bt_mesh_msg_ctx ctx = { + .net_idx = net_idx, + .app_idx = BT_MESH_KEY_DEV, + .addr = addr, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; + struct hb_sub_param param = { + .status = status, + .sub = sub, + }; + int err; + + err = cli_prepare(¶m, OP_HEARTBEAT_SUB_STATUS); + if (err) { + goto done; + } + + bt_mesh_model_msg_init(msg, OP_HEARTBEAT_SUB_GET); + + err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); + if (err) { + BT_ERR("model_send() failed (err %d)", err); + cli_reset(); + goto done; + } + + if (!status) { + cli_reset(); + goto done; + } + + err = cli_wait(); +done: + os_mbuf_free_chain(msg); + return err; +} + +int bt_mesh_cfg_hb_pub_set(u16_t net_idx, u16_t addr, + const struct bt_mesh_cfg_hb_pub *pub, u8_t *status) +{ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 9 + 4); + struct bt_mesh_msg_ctx ctx = { + .net_idx = net_idx, + .app_idx = BT_MESH_KEY_DEV, + .addr = addr, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; + struct hb_pub_param param = { + .status = status, + }; + int err; + + err = cli_prepare(¶m, OP_HEARTBEAT_PUB_STATUS); + if (err) { + goto done; + } + + bt_mesh_model_msg_init(msg, OP_HEARTBEAT_PUB_SET); + net_buf_simple_add_le16(msg, pub->dst); + net_buf_simple_add_u8(msg, pub->count); + net_buf_simple_add_u8(msg, pub->period); + net_buf_simple_add_u8(msg, pub->ttl); + net_buf_simple_add_le16(msg, pub->feat); + net_buf_simple_add_le16(msg, pub->net_idx); + + err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); + if (err) { + BT_ERR("model_send() failed (err %d)", err); + cli_reset(); + goto done; + } + + if (!status) { + cli_reset(); + goto done; + } + + err = cli_wait(); +done: + os_mbuf_free_chain(msg); + return err; +} + +int bt_mesh_cfg_hb_pub_get(u16_t net_idx, u16_t addr, + struct bt_mesh_cfg_hb_pub *pub, u8_t *status) +{ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 0 + 4); + struct bt_mesh_msg_ctx ctx = { + .net_idx = net_idx, + .app_idx = BT_MESH_KEY_DEV, + .addr = addr, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; + struct hb_pub_param param = { + .status = status, + .pub = pub, + }; + int err; + + err = cli_prepare(¶m, OP_HEARTBEAT_PUB_STATUS); + if (err) { + goto done; + } + + bt_mesh_model_msg_init(msg, OP_HEARTBEAT_PUB_GET); + + err = bt_mesh_model_send(cli->model, &ctx, msg, NULL, NULL); + if (err) { + BT_ERR("model_send() failed (err %d)", err); + cli_reset(); + goto done; + } + + if (!status) { + cli_reset(); + goto done; + } + + err = cli_wait(); +done: + os_mbuf_free_chain(msg); + return err; +} + +s32_t bt_mesh_cfg_cli_timeout_get(void) +{ + return msg_timeout; +} + +void bt_mesh_cfg_cli_timeout_set(s32_t timeout) +{ + msg_timeout = timeout; +} + +int bt_mesh_cfg_cli_init(struct bt_mesh_model *model, bool primary) +{ + BT_DBG("primary %u", primary); + + if (!primary) { + BT_ERR("Configuration Client only allowed in primary element"); + return -EINVAL; + } + + if (!model->user_data) { + BT_ERR("No Configuration Client context provided"); + return -EINVAL; + } + + cli = model->user_data; + cli->model = model; + + /* Configuration Model security is device-key based */ + model->keys[0] = BT_MESH_KEY_DEV; + + k_sem_init(&cli->op_sync, 0, 1); + + return 0; +} + +#endif diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/cfg_srv.c b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/cfg_srv.c new file mode 100644 index 000000000..4ee9e8cfd --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/cfg_srv.c @@ -0,0 +1,3617 @@ +/* Bluetooth Mesh */ + +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include "mesh/mesh.h" + +#include "syscfg/syscfg.h" +#define BT_DBG_ENABLED MYNEWT_VAL(BLE_MESH_DEBUG_MODEL) +#include "host/ble_hs_log.h" + +#include "mesh_priv.h" +#include "adv.h" +#include "net.h" +#include "lpn.h" +#include "transport.h" +#include "crypto.h" +#include "access.h" +#include "beacon.h" +#include "proxy.h" +#include "foundation.h" +#include "friend.h" +#include "testing.h" +#include "settings.h" + +#define DEFAULT_TTL 7 + +static struct bt_mesh_cfg_srv *conf; + +static struct label { + u16_t ref; + u16_t addr; + u8_t uuid[16]; +} labels[MYNEWT_VAL(BLE_MESH_LABEL_COUNT)]; + +static void hb_send(struct bt_mesh_model *model) +{ + + struct bt_mesh_cfg_srv *cfg = model->user_data; + u16_t feat = 0; + struct __packed { + u8_t init_ttl; + u16_t feat; + } hb; + struct bt_mesh_msg_ctx ctx = { + .net_idx = cfg->hb_pub.net_idx, + .app_idx = BT_MESH_KEY_UNUSED, + .addr = cfg->hb_pub.dst, + .send_ttl = cfg->hb_pub.ttl, + }; + struct bt_mesh_net_tx tx = { + .sub = bt_mesh_subnet_get(cfg->hb_pub.net_idx), + .ctx = &ctx, + .src = bt_mesh_model_elem(model)->addr, + .xmit = bt_mesh_net_transmit_get(), + }; + + hb.init_ttl = cfg->hb_pub.ttl; + + if (bt_mesh_relay_get() == BT_MESH_RELAY_ENABLED) { + feat |= BT_MESH_FEAT_RELAY; + } + + if (bt_mesh_gatt_proxy_get() == BT_MESH_GATT_PROXY_ENABLED) { + feat |= BT_MESH_FEAT_PROXY; + } + + if (bt_mesh_friend_get() == BT_MESH_FRIEND_ENABLED) { + feat |= BT_MESH_FEAT_FRIEND; + } + +#if (MYNEWT_VAL(BLE_MESH_LOW_POWER)) + if (bt_mesh.lpn.state != BT_MESH_LPN_DISABLED) { + feat |= BT_MESH_FEAT_LOW_POWER; + } +#endif + + hb.feat = sys_cpu_to_be16(feat); + + BT_DBG("InitTTL %u feat 0x%04x", cfg->hb_pub.ttl, feat); + + bt_mesh_ctl_send(&tx, TRANS_CTL_OP_HEARTBEAT, &hb, sizeof(hb), + NULL, NULL, NULL); +} + +static int comp_add_elem(struct os_mbuf *buf, struct bt_mesh_elem *elem, + bool primary) +{ + struct bt_mesh_model *mod; + int i; + + if (net_buf_simple_tailroom(buf) < + 4 + (elem->model_count * 2) + (elem->vnd_model_count * 2)) { + BT_ERR("Too large device composition"); + return -E2BIG; + } + + net_buf_simple_add_le16(buf, elem->loc); + + net_buf_simple_add_u8(buf, elem->model_count); + net_buf_simple_add_u8(buf, elem->vnd_model_count); + + for (i = 0; i < elem->model_count; i++) { + mod = &elem->models[i]; + net_buf_simple_add_le16(buf, mod->id); + } + + for (i = 0; i < elem->vnd_model_count; i++) { + mod = &elem->vnd_models[i]; + net_buf_simple_add_le16(buf, mod->vnd.company); + net_buf_simple_add_le16(buf, mod->vnd.id); + } + + return 0; +} + +static int comp_get_page_0(struct os_mbuf *buf) +{ + u16_t feat = 0; + const struct bt_mesh_comp *comp; + int i; + + comp = bt_mesh_comp_get(); + + if ((MYNEWT_VAL(BLE_MESH_RELAY))) { + feat |= BT_MESH_FEAT_RELAY; + } + + if ((MYNEWT_VAL(BLE_MESH_GATT_PROXY))) { + feat |= BT_MESH_FEAT_PROXY; + } + + if ((MYNEWT_VAL(BLE_MESH_FRIEND))) { + feat |= BT_MESH_FEAT_FRIEND; + } + + if ((MYNEWT_VAL(BLE_MESH_LOW_POWER))) { + feat |= BT_MESH_FEAT_LOW_POWER; + } + + net_buf_simple_add_le16(buf, comp->cid); + net_buf_simple_add_le16(buf, comp->pid); + net_buf_simple_add_le16(buf, comp->vid); + net_buf_simple_add_le16(buf, MYNEWT_VAL(BLE_MESH_CRPL)); + net_buf_simple_add_le16(buf, feat); + + for (i = 0; i < comp->elem_count; i++) { + int err; + + err = comp_add_elem(buf, &comp->elem[i], i == 0); + if (err) { + return err; + } + } + + return 0; +} + +static void dev_comp_data_get(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct os_mbuf *sdu = NET_BUF_SIMPLE(BT_MESH_TX_SDU_MAX); + u8_t page; + + BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); + + page = net_buf_simple_pull_u8(buf); + if (page != 0) { + BT_WARN("Composition page %u not available", page); + page = 0; + } + + bt_mesh_model_msg_init(sdu, OP_DEV_COMP_DATA_STATUS); + + net_buf_simple_add_u8(sdu, page); + if (comp_get_page_0(sdu) < 0) { + BT_ERR("Unable to get composition page 0"); + goto done; + } + + if (bt_mesh_model_send(model, ctx, sdu, NULL, NULL)) { + BT_ERR("Unable to send Device Composition Status response"); + } + +done: + os_mbuf_free_chain(sdu); +} + +static struct bt_mesh_model *get_model(struct bt_mesh_elem *elem, + struct os_mbuf *buf, bool *vnd) +{ + if (buf->om_len < 4) { + u16_t id; + + id = net_buf_simple_pull_le16(buf); + + BT_DBG("ID 0x%04x addr 0x%04x", id, elem->addr); + + *vnd = false; + + return bt_mesh_model_find(elem, id); + } else { + u16_t company, id; + + company = net_buf_simple_pull_le16(buf); + id = net_buf_simple_pull_le16(buf); + + BT_DBG("Company 0x%04x ID 0x%04x addr 0x%04x", company, id, + elem->addr); + + *vnd = true; + + return bt_mesh_model_find_vnd(elem, company, id); + } +} + +static bool app_key_is_valid(u16_t app_idx) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(bt_mesh.app_keys); i++) { + struct bt_mesh_app_key *key = &bt_mesh.app_keys[i]; + + if (key->net_idx != BT_MESH_KEY_UNUSED && + key->app_idx == app_idx) { + return true; + } + } + + return false; +} + +static u8_t _mod_pub_set(struct bt_mesh_model *model, u16_t pub_addr, + u16_t app_idx, u8_t cred_flag, u8_t ttl, u8_t period, + u8_t retransmit, bool store) +{ + if (!model->pub) { + return STATUS_NVAL_PUB_PARAM; + } + + if (!(MYNEWT_VAL(BLE_MESH_LOW_POWER)) && cred_flag) { + return STATUS_FEAT_NOT_SUPP; + } + + if (!model->pub->update && period) { + return STATUS_NVAL_PUB_PARAM; + } + + if (pub_addr == BT_MESH_ADDR_UNASSIGNED) { + if (model->pub->addr == BT_MESH_ADDR_UNASSIGNED) { + return STATUS_SUCCESS; + } + + model->pub->addr = BT_MESH_ADDR_UNASSIGNED; + model->pub->key = 0; + model->pub->cred = 0; + model->pub->ttl = 0; + model->pub->period = 0; + model->pub->retransmit = 0; + model->pub->count = 0; + + if (model->pub->update) { + k_delayed_work_cancel(&model->pub->timer); + } + + if (IS_ENABLED(CONFIG_BT_SETTINGS) && store) { + bt_mesh_store_mod_pub(model); + } + + return STATUS_SUCCESS; + } + + if (!bt_mesh_app_key_find(app_idx)) { + return STATUS_INVALID_APPKEY; + } + + model->pub->addr = pub_addr; + model->pub->key = app_idx; + model->pub->cred = cred_flag; + model->pub->ttl = ttl; + model->pub->period = period; + model->pub->retransmit = retransmit; + + if (model->pub->update) { + s32_t period_ms; + + period_ms = bt_mesh_model_pub_period_get(model); + BT_DBG("period %u ms", (unsigned) period_ms); + + if (period_ms) { + k_delayed_work_submit(&model->pub->timer, period_ms); + } else { + k_delayed_work_cancel(&model->pub->timer); + } + } + + if (IS_ENABLED(CONFIG_BT_SETTINGS) && store) { + bt_mesh_store_mod_pub(model); + } + + return STATUS_SUCCESS; +} + +u8_t mod_bind(struct bt_mesh_model *model, u16_t key_idx) +{ + int i; + + BT_DBG("model %p key_idx 0x%03x", model, key_idx); + + if (!app_key_is_valid(key_idx)) { + return STATUS_INVALID_APPKEY; + } + + for (i = 0; i < ARRAY_SIZE(model->keys); i++) { + /* Treat existing binding as success */ + if (model->keys[i] == key_idx) { + return STATUS_SUCCESS; + } + } + + for (i = 0; i < ARRAY_SIZE(model->keys); i++) { + if (model->keys[i] == BT_MESH_KEY_UNUSED) { + model->keys[i] = key_idx; + + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + bt_mesh_store_mod_bind(model); + } + + return STATUS_SUCCESS; + } + } + + return STATUS_INSUFF_RESOURCES; +} + +u8_t mod_unbind(struct bt_mesh_model *model, u16_t key_idx, bool store) +{ + int i; + + BT_DBG("model %p key_idx 0x%03x store %u", model, key_idx, store); + + if (!app_key_is_valid(key_idx)) { + return STATUS_INVALID_APPKEY; + } + + for (i = 0; i < ARRAY_SIZE(model->keys); i++) { + if (model->keys[i] != key_idx) { + continue; + } + + model->keys[i] = BT_MESH_KEY_UNUSED; + + if (IS_ENABLED(CONFIG_BT_SETTINGS) && store) { + bt_mesh_store_mod_bind(model); + } + + if (model->pub && model->pub->key == key_idx) { + _mod_pub_set(model, BT_MESH_ADDR_UNASSIGNED, + 0, 0, 0, 0, 0, store); + } + } + + return STATUS_SUCCESS; +} + +struct bt_mesh_app_key *bt_mesh_app_key_alloc(u16_t app_idx) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(bt_mesh.app_keys); i++) { + struct bt_mesh_app_key *key = &bt_mesh.app_keys[i]; + + if (key->net_idx == BT_MESH_KEY_UNUSED) { + return key; + } + } + + return NULL; +} + +static u8_t app_key_set(u16_t net_idx, u16_t app_idx, const u8_t val[16], + bool update) +{ + struct bt_mesh_app_keys *keys; + struct bt_mesh_app_key *key; + struct bt_mesh_subnet *sub; + + BT_DBG("net_idx 0x%04x app_idx %04x update %u val %s", + net_idx, app_idx, update, bt_hex(val, 16)); + + sub = bt_mesh_subnet_get(net_idx); + if (!sub) { + return STATUS_INVALID_NETKEY; + } + + key = bt_mesh_app_key_find(app_idx); + if (update) { + if (!key) { + return STATUS_INVALID_APPKEY; + } + + if (key->net_idx != net_idx) { + return STATUS_INVALID_BINDING; + } + + keys = &key->keys[1]; + + /* The AppKey Update message shall generate an error when node + * is in normal operation, Phase 2, or Phase 3 or in Phase 1 + * when the AppKey Update message on a valid AppKeyIndex when + * the AppKey value is different. + */ + if (sub->kr_phase != BT_MESH_KR_PHASE_1) { + return STATUS_CANNOT_UPDATE; + } + + if (key->updated) { + if (memcmp(keys->val, val, 16)) { + return STATUS_CANNOT_UPDATE; + } else { + return STATUS_SUCCESS; + } + } + + key->updated = true; + } else { + if (key) { + if (key->net_idx == net_idx && + !memcmp(key->keys[0].val, val, 16)) { + return STATUS_SUCCESS; + } + + if (key->net_idx == net_idx) { + return STATUS_IDX_ALREADY_STORED; + } else { + return STATUS_INVALID_NETKEY; + } + } + + key = bt_mesh_app_key_alloc(app_idx); + if (!key) { + return STATUS_INSUFF_RESOURCES; + } + + keys = &key->keys[0]; + } + + if (bt_mesh_app_id(val, &keys->id)) { + if (update) { + key->updated = false; + } + + return STATUS_STORAGE_FAIL; + } + + BT_DBG("app_idx 0x%04x AID 0x%02x", app_idx, keys->id); + + key->net_idx = net_idx; + key->app_idx = app_idx; + memcpy(keys->val, val, 16); + + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + BT_DBG("Storing AppKey persistently"); + bt_mesh_store_app_key(key); + } + + return STATUS_SUCCESS; +} + +static void app_key_add(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 4 + 4); + u16_t key_net_idx, key_app_idx; + u8_t status; + + key_idx_unpack(buf, &key_net_idx, &key_app_idx); + + BT_DBG("AppIdx 0x%04x NetIdx 0x%04x", key_app_idx, key_net_idx); + + bt_mesh_model_msg_init(msg, OP_APP_KEY_STATUS); + + status = app_key_set(key_net_idx, key_app_idx, buf->om_data, false); + BT_DBG("status 0x%02x", status); + net_buf_simple_add_u8(msg, status); + + key_idx_pack(msg, key_net_idx, key_app_idx); + + if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + BT_ERR("Unable to send App Key Status response"); + } + + os_mbuf_free_chain(msg); +} + +static void app_key_update(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 4 + 4); + u16_t key_net_idx, key_app_idx; + u8_t status; + + key_idx_unpack(buf, &key_net_idx, &key_app_idx); + + BT_DBG("AppIdx 0x%04x NetIdx 0x%04x", key_app_idx, key_net_idx); + + bt_mesh_model_msg_init(msg, OP_APP_KEY_STATUS); + + status = app_key_set(key_net_idx, key_app_idx, buf->om_data, true); + BT_DBG("status 0x%02x", status); + net_buf_simple_add_u8(msg, status); + + key_idx_pack(msg, key_net_idx, key_app_idx); + + if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + BT_ERR("Unable to send App Key Status response"); + } + + os_mbuf_free_chain(msg); +} + +struct unbind_data { + u16_t app_idx; + bool store; +}; + +static void _mod_unbind(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, + bool vnd, bool primary, void *user_data) +{ + struct unbind_data *data = user_data; + + mod_unbind(mod, data->app_idx, data->store); +} + +void bt_mesh_app_key_del(struct bt_mesh_app_key *key, bool store) +{ + struct unbind_data data = { .app_idx = key->app_idx, .store = store }; + + BT_DBG("AppIdx 0x%03x store %u", key->app_idx, store); + + bt_mesh_model_foreach(_mod_unbind, &data); + + if (IS_ENABLED(CONFIG_BT_SETTINGS) && store) { + bt_mesh_clear_app_key(key); + } + + key->net_idx = BT_MESH_KEY_UNUSED; + memset(key->keys, 0, sizeof(key->keys)); +} + +static void app_key_del(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 4 + 4); + u16_t key_net_idx, key_app_idx; + struct bt_mesh_app_key *key; + u8_t status; + + key_idx_unpack(buf, &key_net_idx, &key_app_idx); + + BT_DBG("AppIdx 0x%04x NetIdx 0x%04x", key_app_idx, key_net_idx); + + if (!bt_mesh_subnet_get(key_net_idx)) { + status = STATUS_INVALID_NETKEY; + goto send_status; + } + + key = bt_mesh_app_key_find(key_app_idx); + if (!key) { + /* Treat as success since the client might have missed a + * previous response and is resending the request. + */ + status = STATUS_SUCCESS; + goto send_status; + } + + if (key->net_idx != key_net_idx) { + status = STATUS_INVALID_BINDING; + goto send_status; + } + + bt_mesh_app_key_del(key, true); + status = STATUS_SUCCESS; + +send_status: + bt_mesh_model_msg_init(msg, OP_APP_KEY_STATUS); + + net_buf_simple_add_u8(msg, status); + + key_idx_pack(msg, key_net_idx, key_app_idx); + + if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + BT_ERR("Unable to send App Key Status response"); + } + + os_mbuf_free_chain(msg); +} + +/* Index list length: 3 bytes for every pair and 2 bytes for an odd idx */ +#define IDX_LEN(num) (((num) / 2) * 3 + ((num) % 2) * 2) + +static void app_key_get(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct os_mbuf *msg = + NET_BUF_SIMPLE(2 + 3 + 4 + + IDX_LEN(MYNEWT_VAL(BLE_MESH_APP_KEY_COUNT))); + u16_t get_idx, i, prev; + u8_t status; + + get_idx = net_buf_simple_pull_le16(buf); + if (get_idx > 0xfff) { + BT_ERR("Invalid NetKeyIndex 0x%04x", get_idx); + goto done; + } + + BT_DBG("idx 0x%04x", get_idx); + + bt_mesh_model_msg_init(msg, OP_APP_KEY_LIST); + + if (!bt_mesh_subnet_get(get_idx)) { + status = STATUS_INVALID_NETKEY; + } else { + status = STATUS_SUCCESS; + } + + net_buf_simple_add_u8(msg, status); + net_buf_simple_add_le16(msg, get_idx); + + if (status != STATUS_SUCCESS) { + goto send_status; + } + + prev = BT_MESH_KEY_UNUSED; + for (i = 0; i < ARRAY_SIZE(bt_mesh.app_keys); i++) { + struct bt_mesh_app_key *key = &bt_mesh.app_keys[i]; + + if (key->net_idx != get_idx) { + continue; + } + + if (prev == BT_MESH_KEY_UNUSED) { + prev = key->app_idx; + continue; + } + + key_idx_pack(msg, prev, key->app_idx); + prev = BT_MESH_KEY_UNUSED; + } + + if (prev != BT_MESH_KEY_UNUSED) { + net_buf_simple_add_le16(msg, prev); + } + +send_status: + if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + BT_ERR("Unable to send AppKey List"); + } + +done: + os_mbuf_free_chain(msg); +} + +static void beacon_get(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + /* Needed size: opcode (2 bytes) + msg + MIC */ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4); + + BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); + + bt_mesh_model_msg_init(msg, OP_BEACON_STATUS); + net_buf_simple_add_u8(msg, bt_mesh_beacon_get()); + + if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + BT_ERR("Unable to send Config Beacon Status response"); + } + os_mbuf_free_chain(msg); +} + +static void beacon_set(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + /* Needed size: opcode (2 bytes) + msg + MIC */ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4); + struct bt_mesh_cfg_srv *cfg = model->user_data; + + BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); + + if (!cfg) { + BT_WARN("No Configuration Server context available"); + } else if (buf->om_data[0] == 0x00 || buf->om_data[0] == 0x01) { + if (buf->om_data[0] != cfg->beacon) { + cfg->beacon = buf->om_data[0]; + + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + bt_mesh_store_cfg(); + } + + if (cfg->beacon) { + bt_mesh_beacon_enable(); + } else { + bt_mesh_beacon_disable(); + } + } + } else { + BT_WARN("Invalid Config Beacon value 0x%02x", buf->om_data[0]); + goto done; + } + + bt_mesh_model_msg_init(msg, OP_BEACON_STATUS); + net_buf_simple_add_u8(msg, bt_mesh_beacon_get()); + + if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + BT_ERR("Unable to send Config Beacon Status response"); + } + +done: + os_mbuf_free_chain(msg); + +} + +static void default_ttl_get(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + /* Needed size: opcode (2 bytes) + msg + MIC */ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4); + + BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); + + bt_mesh_model_msg_init(msg, OP_DEFAULT_TTL_STATUS); + net_buf_simple_add_u8(msg, bt_mesh_default_ttl_get()); + + if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + BT_ERR("Unable to send Default TTL Status response"); + } + + os_mbuf_free_chain(msg); + +} + +static void default_ttl_set(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + /* Needed size: opcode (2 bytes) + msg + MIC */ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4); + struct bt_mesh_cfg_srv *cfg = model->user_data; + + BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); + + if (!cfg) { + BT_WARN("No Configuration Server context available"); + } else if (buf->om_data[0] <= BT_MESH_TTL_MAX && buf->om_data[0] != 0x01) { + if (cfg->default_ttl != buf->om_data[0]) { + cfg->default_ttl = buf->om_data[0]; + + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + bt_mesh_store_cfg(); + } + } + } else { + BT_WARN("Prohibited Default TTL value 0x%02x", buf->om_data[0]); + goto done; + } + + bt_mesh_model_msg_init(msg, OP_DEFAULT_TTL_STATUS); + net_buf_simple_add_u8(msg, bt_mesh_default_ttl_get()); + + if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + BT_ERR("Unable to send Default TTL Status response"); + } + +done: + os_mbuf_free_chain(msg); +} + +static void send_gatt_proxy_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx) +{ + /* Needed size: opcode (2 bytes) + msg + MIC */ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4); + + bt_mesh_model_msg_init(msg, OP_GATT_PROXY_STATUS); + net_buf_simple_add_u8(msg, bt_mesh_gatt_proxy_get()); + + if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + BT_ERR("Unable to send GATT Proxy Status"); + } + + os_mbuf_free_chain(msg); + +} + +static void gatt_proxy_get(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); + + send_gatt_proxy_status(model, ctx); +} + +static void gatt_proxy_set(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct bt_mesh_cfg_srv *cfg = model->user_data; + struct bt_mesh_subnet *sub; + + BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); + + if (buf->om_data[0] != 0x00 && buf->om_data[0] != 0x01) { + BT_WARN("Invalid GATT Proxy value 0x%02x", buf->om_data[0]); + return; + } + + if (!(MYNEWT_VAL(BLE_MESH_GATT_PROXY)) || + bt_mesh_gatt_proxy_get() == BT_MESH_GATT_PROXY_NOT_SUPPORTED) { + goto send_status; + } + + if (!cfg) { + BT_WARN("No Configuration Server context available"); + goto send_status; + } + + BT_DBG("GATT Proxy 0x%02x -> 0x%02x", cfg->gatt_proxy, buf->om_data[0]); + + if (cfg->gatt_proxy == buf->om_data[0]) { + goto send_status; + } + + cfg->gatt_proxy = buf->om_data[0]; + + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + bt_mesh_store_cfg(); + } + + if (cfg->gatt_proxy == BT_MESH_GATT_PROXY_DISABLED) { + int i; + + /* Section 4.2.11.1: "When the GATT Proxy state is set to + * 0x00, the Node Identity state for all subnets shall be set + * to 0x00 and shall not be changed." + */ + for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) { + struct bt_mesh_subnet *sub = &bt_mesh.sub[i]; + + if (sub->net_idx != BT_MESH_KEY_UNUSED) { + bt_mesh_proxy_identity_stop(sub); + } + } + + /* Section 4.2.11: "Upon transition from GATT Proxy state 0x01 + * to GATT Proxy state 0x00 the GATT Bearer Server shall + * disconnect all GATT Bearer Clients. + */ + bt_mesh_proxy_gatt_disconnect(); + } + + bt_mesh_adv_update(); + + sub = bt_mesh_subnet_get(cfg->hb_pub.net_idx); + if ((cfg->hb_pub.feat & BT_MESH_FEAT_PROXY) && sub) { + hb_send(model); + } + +send_status: + send_gatt_proxy_status(model, ctx); +} + +static void net_transmit_get(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + /* Needed size: opcode (2 bytes) + msg + MIC */ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4); + + BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); + + bt_mesh_model_msg_init(msg, OP_NET_TRANSMIT_STATUS); + net_buf_simple_add_u8(msg, bt_mesh_net_transmit_get()); + + if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + BT_ERR("Unable to send Config Network Transmit Status"); + } + + os_mbuf_free_chain(msg); + +} + +static void net_transmit_set(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + /* Needed size: opcode (2 bytes) + msg + MIC */ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4); + struct bt_mesh_cfg_srv *cfg = model->user_data; + + BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); + + BT_DBG("Transmit 0x%02x (count %u interval %ums)", buf->om_data[0], + BT_MESH_TRANSMIT_COUNT(buf->om_data[0]), + BT_MESH_TRANSMIT_INT(buf->om_data[0])); + + if (!cfg) { + BT_WARN("No Configuration Server context available"); + } else { + cfg->net_transmit = buf->om_data[0]; + + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + bt_mesh_store_cfg(); + } + } + + bt_mesh_model_msg_init(msg, OP_NET_TRANSMIT_STATUS); + net_buf_simple_add_u8(msg, bt_mesh_net_transmit_get()); + + if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + BT_ERR("Unable to send Network Transmit Status"); + } + + os_mbuf_free_chain(msg); +} + +static void relay_get(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + /* Needed size: opcode (2 bytes) + msg + MIC */ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 2 + 4); + + BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); + + bt_mesh_model_msg_init(msg, OP_RELAY_STATUS); + net_buf_simple_add_u8(msg, bt_mesh_relay_get()); + net_buf_simple_add_u8(msg, bt_mesh_relay_retransmit_get()); + + if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + BT_ERR("Unable to send Config Relay Status response"); + } + + os_mbuf_free_chain(msg); + +} + +static void relay_set(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + /* Needed size: opcode (2 bytes) + msg + MIC */ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 2 + 4); + struct bt_mesh_cfg_srv *cfg = model->user_data; + + BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); + + if (!cfg) { + BT_WARN("No Configuration Server context available"); + } else if (buf->om_data[0] == 0x00 || buf->om_data[0] == 0x01) { + struct bt_mesh_subnet *sub; + bool change; + + if (cfg->relay == BT_MESH_RELAY_NOT_SUPPORTED) { + change = false; + } else { + change = (cfg->relay != buf->om_data[0]); + cfg->relay = buf->om_data[0]; + cfg->relay_retransmit = buf->om_data[1]; + + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + bt_mesh_store_cfg(); + } + } + + BT_DBG("Relay 0x%02x (%s) xmit 0x%02x (count %u interval %u)", + cfg->relay, change ? "changed" : "not changed", + cfg->relay_retransmit, + BT_MESH_TRANSMIT_COUNT(cfg->relay_retransmit), + BT_MESH_TRANSMIT_INT(cfg->relay_retransmit)); + + sub = bt_mesh_subnet_get(cfg->hb_pub.net_idx); + if ((cfg->hb_pub.feat & BT_MESH_FEAT_RELAY) && sub && change) { + hb_send(model); + } + } else { + BT_WARN("Invalid Relay value 0x%02x", buf->om_data[0]); + goto done; + } + + bt_mesh_model_msg_init(msg, OP_RELAY_STATUS); + net_buf_simple_add_u8(msg, bt_mesh_relay_get()); + net_buf_simple_add_u8(msg, bt_mesh_relay_retransmit_get()); + + if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + BT_ERR("Unable to send Relay Status response"); + } + +done: + os_mbuf_free_chain(msg); + +} + +static void send_mod_pub_status(struct bt_mesh_model *cfg_mod, + struct bt_mesh_msg_ctx *ctx, + u16_t elem_addr, u16_t pub_addr, + bool vnd, struct bt_mesh_model *mod, + u8_t status, u8_t *mod_id) +{ + /* Needed size: opcode (2 bytes) + msg + MIC */ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 14 + 4); + + bt_mesh_model_msg_init(msg, OP_MOD_PUB_STATUS); + + net_buf_simple_add_u8(msg, status); + net_buf_simple_add_le16(msg, elem_addr); + + if (status != STATUS_SUCCESS) { + memset(net_buf_simple_add(msg, 7), 0, 7); + } else { + u16_t idx_cred; + + net_buf_simple_add_le16(msg, pub_addr); + + idx_cred = mod->pub->key | (u16_t)mod->pub->cred << 12; + net_buf_simple_add_le16(msg, idx_cred); + net_buf_simple_add_u8(msg, mod->pub->ttl); + net_buf_simple_add_u8(msg, mod->pub->period); + net_buf_simple_add_u8(msg, mod->pub->retransmit); + } + + if (vnd) { + memcpy(net_buf_simple_add(msg, 4), mod_id, 4); + } else { + memcpy(net_buf_simple_add(msg, 2), mod_id, 2); + } + + if (bt_mesh_model_send(cfg_mod, ctx, msg, NULL, NULL)) { + BT_ERR("Unable to send Model Publication Status"); + } + + os_mbuf_free_chain(msg); +} + +static void mod_pub_get(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + u16_t elem_addr, pub_addr = 0; + struct bt_mesh_model *mod; + struct bt_mesh_elem *elem; + u8_t *mod_id, status; + bool vnd; + + elem_addr = net_buf_simple_pull_le16(buf); + if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { + BT_WARN("Prohibited element address"); + return; + } + + mod_id = buf->om_data; + + BT_DBG("elem_addr 0x%04x", elem_addr); + + elem = bt_mesh_elem_find(elem_addr); + if (!elem) { + mod = NULL; + vnd = (buf->om_len == 4); + status = STATUS_INVALID_ADDRESS; + goto send_status; + } + + mod = get_model(elem, buf, &vnd); + if (!mod) { + status = STATUS_INVALID_MODEL; + goto send_status; + } + + if (!mod->pub) { + status = STATUS_NVAL_PUB_PARAM; + goto send_status; + } + + pub_addr = mod->pub->addr; + status = STATUS_SUCCESS; + +send_status: + send_mod_pub_status(model, ctx, elem_addr, pub_addr, vnd, mod, + status, mod_id); +} + +static void mod_pub_set(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + u8_t retransmit, status, pub_ttl, pub_period, cred_flag; + u16_t elem_addr, pub_addr, pub_app_idx; + struct bt_mesh_model *mod; + struct bt_mesh_elem *elem; + u8_t *mod_id; + bool vnd; + + elem_addr = net_buf_simple_pull_le16(buf); + if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { + BT_WARN("Prohibited element address"); + return; + } + + pub_addr = net_buf_simple_pull_le16(buf); + pub_app_idx = net_buf_simple_pull_le16(buf); + cred_flag = ((pub_app_idx >> 12) & BIT_MASK(1)); + pub_app_idx &= BIT_MASK(12); + + pub_ttl = net_buf_simple_pull_u8(buf); + if (pub_ttl > BT_MESH_TTL_MAX && pub_ttl != BT_MESH_TTL_DEFAULT) { + BT_ERR("Invalid TTL value 0x%02x", pub_ttl); + return; + } + + pub_period = net_buf_simple_pull_u8(buf); + retransmit = net_buf_simple_pull_u8(buf); + mod_id = buf->om_data; + + BT_DBG("elem_addr 0x%04x pub_addr 0x%04x cred_flag %u", + elem_addr, pub_addr, cred_flag); + BT_DBG("pub_app_idx 0x%03x, pub_ttl %u pub_period 0x%02x", + pub_app_idx, pub_ttl, pub_period); + BT_DBG("retransmit 0x%02x (count %u interval %ums)", retransmit, + BT_MESH_PUB_TRANSMIT_COUNT(retransmit), + BT_MESH_PUB_TRANSMIT_INT(retransmit)); + + elem = bt_mesh_elem_find(elem_addr); + if (!elem) { + mod = NULL; + vnd = (buf->om_len == 4); + status = STATUS_INVALID_ADDRESS; + goto send_status; + } + + mod = get_model(elem, buf, &vnd); + if (!mod) { + status = STATUS_INVALID_MODEL; + goto send_status; + } + + status = _mod_pub_set(mod, pub_addr, pub_app_idx, cred_flag, pub_ttl, + pub_period, retransmit, true); + +send_status: + send_mod_pub_status(model, ctx, elem_addr, pub_addr, vnd, mod, + status, mod_id); +} + +#if MYNEWT_VAL(BLE_MESH_LABEL_COUNT) > 0 +static u8_t va_add(u8_t *label_uuid, u16_t *addr) +{ + struct label *free_slot = NULL; + int i; + + for (i = 0; i < ARRAY_SIZE(labels); i++) { + if (!labels[i].ref) { + free_slot = &labels[i]; + continue; + } + + if (!memcmp(labels[i].uuid, label_uuid, 16)) { + *addr = labels[i].addr; + labels[i].ref++; + return STATUS_SUCCESS; + } + } + + if (!free_slot) { + return STATUS_INSUFF_RESOURCES; + } + + if (bt_mesh_virtual_addr(label_uuid, addr) < 0) { + return STATUS_UNSPECIFIED; + } + + free_slot->ref = 1; + free_slot->addr = *addr; + memcpy(free_slot->uuid, label_uuid, 16); + + return STATUS_SUCCESS; +} + +static u8_t va_del(u8_t *label_uuid, u16_t *addr) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(labels); i++) { + if (!memcmp(labels[i].uuid, label_uuid, 16)) { + if (addr) { + *addr = labels[i].addr; + } + + labels[i].ref--; + return STATUS_SUCCESS; + } + } + + if (addr) { + *addr = BT_MESH_ADDR_UNASSIGNED; + } + + return STATUS_CANNOT_REMOVE; +} + +static void mod_sub_list_clear(struct bt_mesh_model *mod) +{ + u8_t *label_uuid; + int i; + + /* Unref stored labels related to this model */ + for (i = 0; i < ARRAY_SIZE(mod->groups); i++) { + if (!BT_MESH_ADDR_IS_VIRTUAL(mod->groups[i])) { + continue; + } + + label_uuid = bt_mesh_label_uuid_get(mod->groups[i]); + if (!label_uuid) { + BT_ERR("Label UUID not found"); + continue; + } + + va_del(label_uuid, NULL); + } + + /* Clear all subscriptions (0x0000 is the unassigned address) */ + memset(mod->groups, 0, sizeof(mod->groups)); +} + +static void mod_pub_va_set(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + u8_t retransmit, status, pub_ttl, pub_period, cred_flag; + u16_t elem_addr, pub_addr, pub_app_idx; + struct bt_mesh_model *mod; + struct bt_mesh_elem *elem; + u8_t *label_uuid; + u8_t *mod_id; + bool vnd; + + elem_addr = net_buf_simple_pull_le16(buf); + if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { + BT_WARN("Prohibited element address"); + return; + } + + label_uuid = net_buf_simple_pull_mem(buf, 16); + pub_app_idx = net_buf_simple_pull_le16(buf); + cred_flag = ((pub_app_idx >> 12) & BIT_MASK(1)); + pub_app_idx &= BIT_MASK(12); + pub_ttl = net_buf_simple_pull_u8(buf); + if (pub_ttl > BT_MESH_TTL_MAX && pub_ttl != BT_MESH_TTL_DEFAULT) { + BT_ERR("Invalid TTL value 0x%02x", pub_ttl); + return; + } + + pub_period = net_buf_simple_pull_u8(buf); + retransmit = net_buf_simple_pull_u8(buf); + mod_id = buf->om_data; + + BT_DBG("elem_addr 0x%04x pub_addr 0x%04x cred_flag %u", + elem_addr, pub_addr, cred_flag); + BT_DBG("pub_app_idx 0x%03x, pub_ttl %u pub_period 0x%02x", + pub_app_idx, pub_ttl, pub_period); + BT_DBG("retransmit 0x%02x (count %u interval %ums)", retransmit, + BT_MESH_PUB_TRANSMIT_COUNT(retransmit), + BT_MESH_PUB_TRANSMIT_INT(retransmit)); + + elem = bt_mesh_elem_find(elem_addr); + if (!elem) { + mod = NULL; + vnd = (buf->om_len == 4); + pub_addr = 0; + status = STATUS_INVALID_ADDRESS; + goto send_status; + } + + mod = get_model(elem, buf, &vnd); + if (!mod) { + pub_addr = 0; + status = STATUS_INVALID_MODEL; + goto send_status; + } + + status = va_add(label_uuid, &pub_addr); + if (status == STATUS_SUCCESS) { + status = _mod_pub_set(mod, pub_addr, pub_app_idx, cred_flag, + pub_ttl, pub_period, retransmit, true); + } + +send_status: + send_mod_pub_status(model, ctx, elem_addr, pub_addr, vnd, mod, + status, mod_id); +} +#else +static void mod_sub_list_clear(struct bt_mesh_model *mod) +{ + /* Clear all subscriptions (0x0000 is the unassigned address) */ + memset(mod->groups, 0, sizeof(mod->groups)); +} + +static void mod_pub_va_set(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + u8_t *mod_id, status; + struct bt_mesh_model *mod; + struct bt_mesh_elem *elem; + u16_t elem_addr, pub_addr = 0; + bool vnd; + + elem_addr = net_buf_simple_pull_le16(buf); + if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { + BT_WARN("Prohibited element address"); + return; + } + + net_buf_simple_pull(buf, 16); + mod_id = net_buf_simple_pull(buf, 4); + + BT_DBG("elem_addr 0x%04x", elem_addr); + + elem = bt_mesh_elem_find(elem_addr); + if (!elem) { + mod = NULL; + vnd = (buf->om_len == 4); + status = STATUS_INVALID_ADDRESS; + goto send_status; + } + + mod = get_model(elem, buf, &vnd); + if (!mod) { + status = STATUS_INVALID_MODEL; + goto send_status; + } + + if (!mod->pub) { + status = STATUS_NVAL_PUB_PARAM; + goto send_status; + } + + pub_addr = mod->pub->addr; + status = STATUS_INSUFF_RESOURCES; + +send_status: + send_mod_pub_status(model, ctx, elem_addr, pub_addr, vnd, mod, + status, mod_id); +} +#endif /* MYNEWT_VAL(BLE_MESH_LABEL_COUNT) > 0 */ + +static void send_mod_sub_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, u8_t status, + u16_t elem_addr, u16_t sub_addr, u8_t *mod_id, + bool vnd) +{ + /* Needed size: opcode (2 bytes) + msg + MIC */ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 9 + 4); + + BT_DBG("status 0x%02x elem_addr 0x%04x sub_addr 0x%04x", status, + elem_addr, sub_addr); + + bt_mesh_model_msg_init(msg, OP_MOD_SUB_STATUS); + + net_buf_simple_add_u8(msg, status); + net_buf_simple_add_le16(msg, elem_addr); + net_buf_simple_add_le16(msg, sub_addr); + + if (vnd) { + memcpy(net_buf_simple_add(msg, 4), mod_id, 4); + } else { + memcpy(net_buf_simple_add(msg, 2), mod_id, 2); + } + + if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + BT_ERR("Unable to send Model Subscription Status"); + } + + os_mbuf_free_chain(msg); +} + +static void mod_sub_add(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + u16_t elem_addr, sub_addr; + struct bt_mesh_model *mod; + struct bt_mesh_elem *elem; + u8_t *mod_id; + u8_t status; + bool vnd; + int i; + + elem_addr = net_buf_simple_pull_le16(buf); + if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { + BT_WARN("Prohibited element address"); + return; + } + + sub_addr = net_buf_simple_pull_le16(buf); + + BT_DBG("elem_addr 0x%04x, sub_addr 0x%04x", elem_addr, sub_addr); + + mod_id = buf->om_data; + + elem = bt_mesh_elem_find(elem_addr); + if (!elem) { + mod = NULL; + vnd = (buf->om_len == 4); + status = STATUS_INVALID_ADDRESS; + goto send_status; + } + + mod = get_model(elem, buf, &vnd); + if (!mod) { + status = STATUS_INVALID_MODEL; + goto send_status; + } + + if (!BT_MESH_ADDR_IS_GROUP(sub_addr)) { + status = STATUS_INVALID_ADDRESS; + goto send_status; + } + + if (bt_mesh_model_find_group(mod, sub_addr)) { + /* Tried to add existing subscription */ + status = STATUS_SUCCESS; + goto send_status; + } + + for (i = 0; i < ARRAY_SIZE(mod->groups); i++) { + if (mod->groups[i] == BT_MESH_ADDR_UNASSIGNED) { + mod->groups[i] = sub_addr; + break; + } + } + + if (i == ARRAY_SIZE(mod->groups)) { + status = STATUS_INSUFF_RESOURCES; + } else { + status = STATUS_SUCCESS; + + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + bt_mesh_store_mod_sub(mod); + } + + if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) { + bt_mesh_lpn_group_add(sub_addr); + } + } + +send_status: + send_mod_sub_status(model, ctx, status, elem_addr, sub_addr, + mod_id, vnd); +} + +static void mod_sub_del(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + u16_t elem_addr, sub_addr; + struct bt_mesh_model *mod; + struct bt_mesh_elem *elem; + u8_t *mod_id; + u16_t *match; + u8_t status; + bool vnd; + + elem_addr = net_buf_simple_pull_le16(buf); + if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { + BT_WARN("Prohibited element address"); + return; + } + + sub_addr = net_buf_simple_pull_le16(buf); + + BT_DBG("elem_addr 0x%04x sub_addr 0x%04x", elem_addr, sub_addr); + + mod_id = buf->om_data; + + elem = bt_mesh_elem_find(elem_addr); + if (!elem) { + mod = NULL; + vnd = (buf->om_len == 4); + status = STATUS_INVALID_ADDRESS; + goto send_status; + } + + mod = get_model(elem, buf, &vnd); + if (!mod) { + status = STATUS_INVALID_MODEL; + goto send_status; + } + + if (!BT_MESH_ADDR_IS_GROUP(sub_addr)) { + status = STATUS_INVALID_ADDRESS; + goto send_status; + } + + /* An attempt to remove a non-existing address shall be treated + * as a success. + */ + status = STATUS_SUCCESS; + + if ((MYNEWT_VAL(BLE_MESH_LOW_POWER))) { + bt_mesh_lpn_group_del(&sub_addr, 1); + } + + match = bt_mesh_model_find_group(mod, sub_addr); + if (match) { + *match = BT_MESH_ADDR_UNASSIGNED; + + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + bt_mesh_store_mod_sub(mod); + } + } + +send_status: + send_mod_sub_status(model, ctx, status, elem_addr, sub_addr, + mod_id, vnd); +} + +static void mod_sub_overwrite(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + u16_t elem_addr, sub_addr; + struct bt_mesh_model *mod; + struct bt_mesh_elem *elem; + u8_t *mod_id; + u8_t status; + bool vnd; + + elem_addr = net_buf_simple_pull_le16(buf); + if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { + BT_WARN("Prohibited element address"); + return; + } + + sub_addr = net_buf_simple_pull_le16(buf); + + BT_DBG("elem_addr 0x%04x sub_addr 0x%04x", elem_addr, sub_addr); + + mod_id = buf->om_data; + + elem = bt_mesh_elem_find(elem_addr); + if (!elem) { + mod = NULL; + vnd = (buf->om_len == 4); + status = STATUS_INVALID_ADDRESS; + goto send_status; + } + + mod = get_model(elem, buf, &vnd); + if (!mod) { + status = STATUS_INVALID_MODEL; + goto send_status; + } + + if (!BT_MESH_ADDR_IS_GROUP(sub_addr)) { + status = STATUS_INVALID_ADDRESS; + goto send_status; + } + + if ((MYNEWT_VAL(BLE_MESH_LOW_POWER))) { + bt_mesh_lpn_group_del(mod->groups, ARRAY_SIZE(mod->groups)); + } + + mod_sub_list_clear(mod); + + if (ARRAY_SIZE(mod->groups) > 0) { + mod->groups[0] = sub_addr; + status = STATUS_SUCCESS; + + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + bt_mesh_store_mod_sub(mod); + } + + if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) { + bt_mesh_lpn_group_add(sub_addr); + } + } else { + status = STATUS_INSUFF_RESOURCES; + } + + +send_status: + send_mod_sub_status(model, ctx, status, elem_addr, sub_addr, + mod_id, vnd); +} + +static void mod_sub_del_all(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct bt_mesh_model *mod; + struct bt_mesh_elem *elem; + u16_t elem_addr; + u8_t *mod_id; + u8_t status; + bool vnd; + + elem_addr = net_buf_simple_pull_le16(buf); + if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { + BT_WARN("Prohibited element address"); + return; + } + + BT_DBG("elem_addr 0x%04x", elem_addr); + + mod_id = buf->om_data; + + elem = bt_mesh_elem_find(elem_addr); + if (!elem) { + mod = NULL; + vnd = (buf->om_len == 4); + status = STATUS_INVALID_ADDRESS; + goto send_status; + } + + mod = get_model(elem, buf, &vnd); + if (!mod) { + status = STATUS_INVALID_MODEL; + goto send_status; + } + + if ((MYNEWT_VAL(BLE_MESH_LOW_POWER))) { + bt_mesh_lpn_group_del(mod->groups, ARRAY_SIZE(mod->groups)); + } + + mod_sub_list_clear(mod); + + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + bt_mesh_store_mod_sub(mod); + } + + status = STATUS_SUCCESS; + +send_status: + send_mod_sub_status(model, ctx, status, elem_addr, + BT_MESH_ADDR_UNASSIGNED, mod_id, vnd); +} + +static void mod_sub_get(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct os_mbuf *msg = + NET_BUF_SIMPLE(2 + 5 + 4 + + MYNEWT_VAL(BLE_MESH_MODEL_GROUP_COUNT) * 2); + struct bt_mesh_model *mod; + struct bt_mesh_elem *elem; + u16_t addr, id; + int i; + + addr = net_buf_simple_pull_le16(buf); + if (!BT_MESH_ADDR_IS_UNICAST(addr)) { + BT_WARN("Prohibited element address"); + goto done; + } + + id = net_buf_simple_pull_le16(buf); + + BT_DBG("addr 0x%04x id 0x%04x", addr, id); + + bt_mesh_model_msg_init(msg, OP_MOD_SUB_LIST); + + elem = bt_mesh_elem_find(addr); + if (!elem) { + net_buf_simple_add_u8(msg, STATUS_INVALID_ADDRESS); + net_buf_simple_add_le16(msg, addr); + net_buf_simple_add_le16(msg, id); + goto send_list; + } + + mod = bt_mesh_model_find(elem, id); + if (!mod) { + net_buf_simple_add_u8(msg, STATUS_INVALID_MODEL); + net_buf_simple_add_le16(msg, addr); + net_buf_simple_add_le16(msg, id); + goto send_list; + } + + net_buf_simple_add_u8(msg, STATUS_SUCCESS); + + net_buf_simple_add_le16(msg, addr); + net_buf_simple_add_le16(msg, id); + + for (i = 0; i < ARRAY_SIZE(mod->groups); i++) { + if (mod->groups[i] != BT_MESH_ADDR_UNASSIGNED) { + net_buf_simple_add_le16(msg, mod->groups[i]); + } + } + +send_list: + if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + BT_ERR("Unable to send Model Subscription List"); + } + +done: + os_mbuf_free_chain(msg); + +} + +static void mod_sub_get_vnd(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct os_mbuf *msg = + NET_BUF_SIMPLE(2 + 7 + 4 + + MYNEWT_VAL(BLE_MESH_MODEL_GROUP_COUNT) * 2); + struct bt_mesh_model *mod; + struct bt_mesh_elem *elem; + u16_t company, addr, id; + int i; + + addr = net_buf_simple_pull_le16(buf); + if (!BT_MESH_ADDR_IS_UNICAST(addr)) { + BT_WARN("Prohibited element address"); + goto done; + } + + company = net_buf_simple_pull_le16(buf); + id = net_buf_simple_pull_le16(buf); + + BT_DBG("addr 0x%04x company 0x%04x id 0x%04x", addr, company, id); + + bt_mesh_model_msg_init(msg, OP_MOD_SUB_LIST_VND); + + elem = bt_mesh_elem_find(addr); + if (!elem) { + net_buf_simple_add_u8(msg, STATUS_INVALID_ADDRESS); + net_buf_simple_add_le16(msg, addr); + net_buf_simple_add_le16(msg, company); + net_buf_simple_add_le16(msg, id); + goto send_list; + } + + mod = bt_mesh_model_find_vnd(elem, company, id); + if (!mod) { + net_buf_simple_add_u8(msg, STATUS_INVALID_MODEL); + net_buf_simple_add_le16(msg, addr); + net_buf_simple_add_le16(msg, company); + net_buf_simple_add_le16(msg, id); + goto send_list; + } + + net_buf_simple_add_u8(msg, STATUS_SUCCESS); + + net_buf_simple_add_le16(msg, addr); + net_buf_simple_add_le16(msg, company); + net_buf_simple_add_le16(msg, id); + + for (i = 0; i < ARRAY_SIZE(mod->groups); i++) { + if (mod->groups[i] != BT_MESH_ADDR_UNASSIGNED) { + net_buf_simple_add_le16(msg, mod->groups[i]); + } + } + +send_list: + if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + BT_ERR("Unable to send Vendor Model Subscription List"); + } + +done: + os_mbuf_free_chain(msg); + +} + +#if MYNEWT_VAL(BLE_MESH_LABEL_COUNT) > 0 +static void mod_sub_va_add(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + u16_t elem_addr, sub_addr; + struct bt_mesh_model *mod; + struct bt_mesh_elem *elem; + u8_t *label_uuid; + u8_t *mod_id; + u8_t status; + bool vnd; + int i; + + elem_addr = net_buf_simple_pull_le16(buf); + if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { + BT_WARN("Prohibited element address"); + return; + } + + label_uuid = net_buf_simple_pull_mem(buf, 16); + + BT_DBG("elem_addr 0x%04x", elem_addr); + + mod_id = buf->om_data; + elem = bt_mesh_elem_find(elem_addr); + if (!elem) { + mod = NULL; + vnd = (buf->om_len == 4); + sub_addr = BT_MESH_ADDR_UNASSIGNED; + status = STATUS_INVALID_ADDRESS; + goto send_status; + } + + mod = get_model(elem, buf, &vnd); + if (!mod) { + sub_addr = BT_MESH_ADDR_UNASSIGNED; + status = STATUS_INVALID_MODEL; + goto send_status; + } + + status = va_add(label_uuid, &sub_addr); + if (status != STATUS_SUCCESS) { + goto send_status; + } + + if (bt_mesh_model_find_group(mod, sub_addr)) { + /* Tried to add existing subscription */ + status = STATUS_SUCCESS; + goto send_status; + } + + for (i = 0; i < ARRAY_SIZE(mod->groups); i++) { + if (mod->groups[i] == BT_MESH_ADDR_UNASSIGNED) { + mod->groups[i] = sub_addr; + break; + } + } + + if (i == ARRAY_SIZE(mod->groups)) { + status = STATUS_INSUFF_RESOURCES; + } else { + if ((MYNEWT_VAL(BLE_MESH_LOW_POWER))) { + bt_mesh_lpn_group_add(sub_addr); + } + + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + bt_mesh_store_mod_sub(mod); + } + + status = STATUS_SUCCESS; + } + +send_status: + send_mod_sub_status(model, ctx, status, elem_addr, sub_addr, + mod_id, vnd); +} + +static void mod_sub_va_del(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + u16_t elem_addr, sub_addr; + struct bt_mesh_model *mod; + struct bt_mesh_elem *elem; + u8_t *label_uuid; + u8_t *mod_id; + u16_t *match; + u8_t status; + bool vnd; + + elem_addr = net_buf_simple_pull_le16(buf); + if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { + BT_WARN("Prohibited element address"); + return; + } + + label_uuid = net_buf_simple_pull_mem(buf, 16); + + BT_DBG("elem_addr 0x%04x", elem_addr); + + mod_id = buf->om_data; + + elem = bt_mesh_elem_find(elem_addr); + if (!elem) { + mod = NULL; + vnd = (buf->om_len == 4); + sub_addr = BT_MESH_ADDR_UNASSIGNED; + status = STATUS_INVALID_ADDRESS; + goto send_status; + } + + mod = get_model(elem, buf, &vnd); + if (!mod) { + sub_addr = BT_MESH_ADDR_UNASSIGNED; + status = STATUS_INVALID_MODEL; + goto send_status; + } + + status = va_del(label_uuid, &sub_addr); + if (sub_addr == BT_MESH_ADDR_UNASSIGNED) { + goto send_status; + } + + if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) { + bt_mesh_lpn_group_del(&sub_addr, 1); + } + + match = bt_mesh_model_find_group(mod, sub_addr); + if (match) { + *match = BT_MESH_ADDR_UNASSIGNED; + + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + bt_mesh_store_mod_sub(mod); + } + + status = STATUS_SUCCESS; + } else { + status = STATUS_CANNOT_REMOVE; + } + +send_status: + send_mod_sub_status(model, ctx, status, elem_addr, sub_addr, + mod_id, vnd); +} + +static void mod_sub_va_overwrite(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + u16_t elem_addr, sub_addr = BT_MESH_ADDR_UNASSIGNED; + struct bt_mesh_model *mod; + struct bt_mesh_elem *elem; + u8_t *label_uuid; + u8_t *mod_id; + u8_t status; + bool vnd; + + elem_addr = net_buf_simple_pull_le16(buf); + if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { + BT_WARN("Prohibited element address"); + return; + } + + label_uuid = net_buf_simple_pull_mem(buf, 16); + + BT_DBG("elem_addr 0x%04x", elem_addr); + + mod_id = buf->om_data; + + elem = bt_mesh_elem_find(elem_addr); + if (!elem) { + mod = NULL; + vnd = (buf->om_len == 4); + status = STATUS_INVALID_ADDRESS; + goto send_status; + } + + mod = get_model(elem, buf, &vnd); + if (!mod) { + status = STATUS_INVALID_MODEL; + goto send_status; + } + + if ((MYNEWT_VAL(BLE_MESH_LOW_POWER))) { + bt_mesh_lpn_group_del(mod->groups, ARRAY_SIZE(mod->groups)); + } + + mod_sub_list_clear(mod); + + if (ARRAY_SIZE(mod->groups) > 0) { + status = va_add(label_uuid, &sub_addr); + if (status == STATUS_SUCCESS) { + mod->groups[0] = sub_addr; + + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + bt_mesh_store_mod_sub(mod); + } + + if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) { + bt_mesh_lpn_group_add(sub_addr); + } + } + } else { + status = STATUS_INSUFF_RESOURCES; + } + +send_status: + send_mod_sub_status(model, ctx, status, elem_addr, sub_addr, + mod_id, vnd); +} +#else +static void mod_sub_va_add(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct bt_mesh_model *mod; + struct bt_mesh_elem *elem; + u16_t elem_addr; + u8_t *mod_id; + u8_t status; + bool vnd; + + elem_addr = net_buf_simple_pull_le16(buf); + if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { + BT_WARN("Prohibited element address"); + return; + } + + net_buf_simple_pull(buf, 16); + + mod_id = buf->om_data; + + elem = bt_mesh_elem_find(elem_addr); + if (!elem) { + mod = NULL; + vnd = (buf->om_len == 4); + status = STATUS_INVALID_ADDRESS; + goto send_status; + } + + mod = get_model(elem, buf, &vnd); + if (!mod) { + status = STATUS_INVALID_MODEL; + goto send_status; + } + + status = STATUS_INSUFF_RESOURCES; + +send_status: + send_mod_sub_status(model, ctx, status, elem_addr, + BT_MESH_ADDR_UNASSIGNED, mod_id, vnd); +} + +static void mod_sub_va_del(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct bt_mesh_elem *elem; + u16_t elem_addr; + u8_t *mod_id; + u8_t status; + bool vnd; + + elem_addr = net_buf_simple_pull_le16(buf); + if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { + BT_WARN("Prohibited element address"); + return; + } + + net_buf_simple_pull(buf, 16); + + mod_id = buf->om_data; + + elem = bt_mesh_elem_find(elem_addr); + if (!elem) { + vnd = (buf->om_len == 4); + status = STATUS_INVALID_ADDRESS; + goto send_status; + } + + if (!get_model(elem, buf, &vnd)) { + status = STATUS_INVALID_MODEL; + goto send_status; + } + + status = STATUS_INSUFF_RESOURCES; + +send_status: + send_mod_sub_status(model, ctx, status, elem_addr, + BT_MESH_ADDR_UNASSIGNED, mod_id, vnd); +} + +static void mod_sub_va_overwrite(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct bt_mesh_elem *elem; + u16_t elem_addr; + u8_t *mod_id; + u8_t status; + bool vnd; + + elem_addr = net_buf_simple_pull_le16(buf); + if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { + BT_WARN("Prohibited element address"); + return; + } + + net_buf_simple_pull(buf, 18); + + mod_id = buf->om_data; + + elem = bt_mesh_elem_find(elem_addr); + if (!elem) { + vnd = (buf->om_len == 4); + status = STATUS_INVALID_ADDRESS; + goto send_status; + } + + if (!get_model(elem, buf, &vnd)) { + status = STATUS_INVALID_MODEL; + goto send_status; + } + + status = STATUS_INSUFF_RESOURCES; + +send_status: + send_mod_sub_status(model, ctx, status, elem_addr, + BT_MESH_ADDR_UNASSIGNED, mod_id, vnd); +} +#endif /* MYNEWT_VAL(BLE_MESH_LABEL_COUNT) > 0 */ + +static void send_net_key_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + u16_t idx, u8_t status) +{ + /* Needed size: opcode (2 bytes) + msg + MIC */ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 3 + 4); + + bt_mesh_model_msg_init(msg, OP_NET_KEY_STATUS); + + net_buf_simple_add_u8(msg, status); + net_buf_simple_add_le16(msg, idx); + + if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + BT_ERR("Unable to send NetKey Status"); + } + + os_mbuf_free_chain(msg); +} + +static void net_key_add(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct bt_mesh_subnet *sub; + u16_t idx; + int err; + + idx = net_buf_simple_pull_le16(buf); + if (idx > 0xfff) { + BT_ERR("Invalid NetKeyIndex 0x%04x", idx); + return; + } + + BT_DBG("idx 0x%04x", idx); + + sub = bt_mesh_subnet_get(idx); + if (!sub) { + int i; + + for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) { + if (bt_mesh.sub[i].net_idx == BT_MESH_KEY_UNUSED) { + sub = &bt_mesh.sub[i]; + break; + } + } + + if (!sub) { + send_net_key_status(model, ctx, idx, + STATUS_INSUFF_RESOURCES); + return; + } + } + + /* Check for already existing subnet */ + if (sub->net_idx == idx) { + u8_t status; + + if (memcmp(buf->om_data, sub->keys[0].net, 16)) { + status = STATUS_IDX_ALREADY_STORED; + } else { + status = STATUS_SUCCESS; + } + + send_net_key_status(model, ctx, idx, status); + return; + } + + err = bt_mesh_net_keys_create(&sub->keys[0], buf->om_data); + if (err) { + send_net_key_status(model, ctx, idx, STATUS_UNSPECIFIED); + return; + } + + sub->net_idx = idx; + + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + BT_DBG("Storing NetKey persistently"); + bt_mesh_store_subnet(sub); + } + + /* Make sure we have valid beacon data to be sent */ + bt_mesh_net_beacon_update(sub); + + if ((MYNEWT_VAL(BLE_MESH_GATT_PROXY))) { + sub->node_id = BT_MESH_NODE_IDENTITY_STOPPED; + bt_mesh_proxy_beacon_send(sub); + bt_mesh_adv_update(); + } else { + sub->node_id = BT_MESH_NODE_IDENTITY_NOT_SUPPORTED; + } + + send_net_key_status(model, ctx, idx, STATUS_SUCCESS); +} + +static void net_key_update(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct bt_mesh_subnet *sub; + u16_t idx; + int err; + + idx = net_buf_simple_pull_le16(buf); + if (idx > 0xfff) { + BT_ERR("Invalid NetKeyIndex 0x%04x", idx); + return; + } + + BT_DBG("idx 0x%04x", idx); + + sub = bt_mesh_subnet_get(idx); + if (!sub) { + send_net_key_status(model, ctx, idx, STATUS_INVALID_NETKEY); + return; + } + + /* The node shall successfully process a NetKey Update message on a + * valid NetKeyIndex when the NetKey value is different and the Key + * Refresh procedure has not been started, or when the NetKey value is + * the same in Phase 1. The NetKey Update message shall generate an + * error when the node is in Phase 2, or Phase 3. + */ + switch (sub->kr_phase) { + case BT_MESH_KR_NORMAL: + if (!memcmp(buf->om_data, sub->keys[0].net, 16)) { + return; + } + break; + case BT_MESH_KR_PHASE_1: + if (!memcmp(buf->om_data, sub->keys[1].net, 16)) { + send_net_key_status(model, ctx, idx, STATUS_SUCCESS); + return; + } + /* fall through */ + case BT_MESH_KR_PHASE_2: + case BT_MESH_KR_PHASE_3: + send_net_key_status(model, ctx, idx, STATUS_CANNOT_UPDATE); + return; + } + + err = bt_mesh_net_keys_create(&sub->keys[1], buf->om_data); + if (!err && ((MYNEWT_VAL(BLE_MESH_LOW_POWER)) || + (MYNEWT_VAL(BLE_MESH_FRIEND)))) { + err = friend_cred_update(sub); + } + + if (err) { + send_net_key_status(model, ctx, idx, STATUS_UNSPECIFIED); + return; + } + + sub->kr_phase = BT_MESH_KR_PHASE_1; + + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + BT_DBG("Storing NetKey persistently"); + bt_mesh_store_subnet(sub); + } + + bt_mesh_net_beacon_update(sub); + + send_net_key_status(model, ctx, idx, STATUS_SUCCESS); +} + +static void hb_pub_disable(struct bt_mesh_cfg_srv *cfg) +{ + BT_DBG(""); + + cfg->hb_pub.dst = BT_MESH_ADDR_UNASSIGNED; + cfg->hb_pub.count = 0; + cfg->hb_pub.ttl = 0; + cfg->hb_pub.period = 0; + + k_delayed_work_cancel(&cfg->hb_pub.timer); +} + +static void net_key_del(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct bt_mesh_subnet *sub; + u16_t del_idx; + u8_t status; + + del_idx = net_buf_simple_pull_le16(buf); + if (del_idx > 0xfff) { + BT_ERR("Invalid NetKeyIndex 0x%04x", del_idx); + return; + } + + BT_DBG("idx 0x%04x", del_idx); + + sub = bt_mesh_subnet_get(del_idx); + if (!sub) { + /* This could be a retry of a previous attempt that had its + * response lost, so pretend that it was a success. + */ + status = STATUS_SUCCESS; + goto send_status; + } + + /* The key that the message was encrypted with cannot be removed. + * The NetKey List must contain a minimum of one NetKey. + */ + if (ctx->net_idx == del_idx) { + status = STATUS_CANNOT_REMOVE; + goto send_status; + } + + bt_mesh_subnet_del(sub, true); + status = STATUS_SUCCESS; + +send_status: + send_net_key_status(model, ctx, del_idx, status); +} + +static void net_key_get(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct os_mbuf *msg = + NET_BUF_SIMPLE(2 + 4 + + IDX_LEN(MYNEWT_VAL(BLE_MESH_SUBNET_COUNT))); + u16_t prev, i; + + bt_mesh_model_msg_init(msg, OP_NET_KEY_LIST); + + prev = BT_MESH_KEY_UNUSED; + for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) { + struct bt_mesh_subnet *sub = &bt_mesh.sub[i]; + + if (sub->net_idx == BT_MESH_KEY_UNUSED) { + continue; + } + + if (prev == BT_MESH_KEY_UNUSED) { + prev = sub->net_idx; + continue; + } + + key_idx_pack(msg, prev, sub->net_idx); + prev = BT_MESH_KEY_UNUSED; + } + + if (prev != BT_MESH_KEY_UNUSED) { + net_buf_simple_add_le16(msg, prev); + } + + if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + BT_ERR("Unable to send NetKey List"); + } + + os_mbuf_free_chain(msg); +} + +static void node_identity_get(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + /* Needed size: opcode (2 bytes) + msg + MIC */ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 4 + 4); + struct bt_mesh_subnet *sub; + u8_t node_id; + u16_t idx; + + BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); + + idx = net_buf_simple_pull_le16(buf); + if (idx > 0xfff) { + BT_ERR("Invalid NetKeyIndex 0x%04x", idx); + goto done; + } + + bt_mesh_model_msg_init(msg, OP_NODE_IDENTITY_STATUS); + + sub = bt_mesh_subnet_get(idx); + if (!sub) { + net_buf_simple_add_u8(msg, STATUS_INVALID_NETKEY); + node_id = 0x00; + } else { + net_buf_simple_add_u8(msg, STATUS_SUCCESS); + node_id = sub->node_id; + } + + net_buf_simple_add_le16(msg, idx); + net_buf_simple_add_u8(msg, node_id); + + if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + BT_ERR("Unable to send Node Identity Status"); + } + +done: + os_mbuf_free_chain(msg); +} + +static void node_identity_set(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + /* Needed size: opcode (2 bytes) + msg + MIC */ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 4 + 4); + struct bt_mesh_subnet *sub; + u8_t node_id; + u16_t idx; + + BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); + + idx = net_buf_simple_pull_le16(buf); + if (idx > 0xfff) { + BT_WARN("Invalid NetKeyIndex 0x%04x", idx); + goto done; + } + + node_id = net_buf_simple_pull_u8(buf); + if (node_id != 0x00 && node_id != 0x01) { + BT_WARN("Invalid Node ID value 0x%02x", node_id); + goto done; + } + + bt_mesh_model_msg_init(msg, OP_NODE_IDENTITY_STATUS); + + sub = bt_mesh_subnet_get(idx); + if (!sub) { + net_buf_simple_add_u8(msg, STATUS_INVALID_NETKEY); + net_buf_simple_add_le16(msg, idx); + net_buf_simple_add_u8(msg, node_id); + } else { + net_buf_simple_add_u8(msg, STATUS_SUCCESS); + net_buf_simple_add_le16(msg, idx); + + /* Section 4.2.11.1: "When the GATT Proxy state is set to + * 0x00, the Node Identity state for all subnets shall be set + * to 0x00 and shall not be changed." + */ + if (MYNEWT_VAL(BLE_MESH_GATT_PROXY) && + bt_mesh_gatt_proxy_get() == BT_MESH_GATT_PROXY_ENABLED) { + if (node_id) { + bt_mesh_proxy_identity_start(sub); + } else { + bt_mesh_proxy_identity_stop(sub); + } + bt_mesh_adv_update(); + } + + net_buf_simple_add_u8(msg, sub->node_id); + } + + if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + BT_ERR("Unable to send Node Identity Status"); + } + +done: + os_mbuf_free_chain(msg); + +} + +static void create_mod_app_status(struct os_mbuf *msg, + struct bt_mesh_model *mod, bool vnd, + u16_t elem_addr, u16_t app_idx, + u8_t status, u8_t *mod_id) +{ + bt_mesh_model_msg_init(msg, OP_MOD_APP_STATUS); + + net_buf_simple_add_u8(msg, status); + net_buf_simple_add_le16(msg, elem_addr); + net_buf_simple_add_le16(msg, app_idx); + + if (vnd) { + memcpy(net_buf_simple_add(msg, 4), mod_id, 4); + } else { + memcpy(net_buf_simple_add(msg, 2), mod_id, 2); + } +} + +static void mod_app_bind(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 9 + 4); + u16_t elem_addr, key_app_idx; + struct bt_mesh_model *mod; + struct bt_mesh_elem *elem; + u8_t *mod_id, status; + bool vnd; + + elem_addr = net_buf_simple_pull_le16(buf); + if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { + BT_WARN("Prohibited element address"); + goto done; + } + + key_app_idx = net_buf_simple_pull_le16(buf); + mod_id = buf->om_data; + + elem = bt_mesh_elem_find(elem_addr); + if (!elem) { + mod = NULL; + vnd = (buf->om_len == 4); + status = STATUS_INVALID_ADDRESS; + goto send_status; + } + + mod = get_model(elem, buf, &vnd); + if (!mod) { + status = STATUS_INVALID_MODEL; + goto send_status; + } + + /* Configuration Server only allows device key based access */ + if (model == mod) { + BT_ERR("Client tried to bind AppKey to Configuration Model"); + status = STATUS_CANNOT_BIND; + goto send_status; + } + + status = mod_bind(mod, key_app_idx); + + if (IS_ENABLED(CONFIG_BT_TESTING) && status == STATUS_SUCCESS) { + bt_test_mesh_model_bound(ctx->addr, mod, key_app_idx); + } + +send_status: + BT_DBG("status 0x%02x", status); + create_mod_app_status(msg, mod, vnd, elem_addr, key_app_idx, status, + mod_id); + + if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + BT_ERR("Unable to send Model App Bind Status response"); + } + +done: + os_mbuf_free_chain(msg); + +} + +static void mod_app_unbind(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 9 + 4); + u16_t elem_addr, key_app_idx; + struct bt_mesh_model *mod; + struct bt_mesh_elem *elem; + u8_t *mod_id, status; + bool vnd; + + elem_addr = net_buf_simple_pull_le16(buf); + if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { + BT_WARN("Prohibited element address"); + goto done; + } + + key_app_idx = net_buf_simple_pull_le16(buf); + mod_id = buf->om_data; + + elem = bt_mesh_elem_find(elem_addr); + if (!elem) { + mod = NULL; + vnd = (buf->om_len == 4); + status = STATUS_INVALID_ADDRESS; + goto send_status; + } + + mod = get_model(elem, buf, &vnd); + if (!mod) { + status = STATUS_INVALID_MODEL; + goto send_status; + } + + status = mod_unbind(mod, key_app_idx, true); + + if (IS_ENABLED(CONFIG_BT_TESTING) && status == STATUS_SUCCESS) { + bt_test_mesh_model_unbound(ctx->addr, mod, key_app_idx); + } + +send_status: + BT_DBG("status 0x%02x", status); + create_mod_app_status(msg, mod, vnd, elem_addr, key_app_idx, status, + mod_id); + + if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + BT_ERR("Unable to send Model App Unbind Status response"); + } + +done: + os_mbuf_free_chain(msg); +} + +#define KEY_LIST_LEN (MYNEWT_VAL(BLE_MESH_MODEL_KEY_COUNT) * 2) + +static void mod_app_get(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 9 + KEY_LIST_LEN + 4); + struct bt_mesh_model *mod; + struct bt_mesh_elem *elem; + u8_t *mod_id, status; + u16_t elem_addr; + bool vnd; + + elem_addr = net_buf_simple_pull_le16(buf); + if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) { + BT_WARN("Prohibited element address"); + goto done; + } + + mod_id = buf->om_data; + + BT_DBG("elem_addr 0x%04x", elem_addr); + + elem = bt_mesh_elem_find(elem_addr); + if (!elem) { + mod = NULL; + vnd = (buf->om_len == 4); + status = STATUS_INVALID_ADDRESS; + goto send_list; + } + + mod = get_model(elem, buf, &vnd); + if (!mod) { + status = STATUS_INVALID_MODEL; + goto send_list; + } + + status = STATUS_SUCCESS; + +send_list: + if (vnd) { + bt_mesh_model_msg_init(msg, OP_VND_MOD_APP_LIST); + } else { + bt_mesh_model_msg_init(msg, OP_SIG_MOD_APP_LIST); + } + + net_buf_simple_add_u8(msg, status); + net_buf_simple_add_le16(msg, elem_addr); + + if (vnd) { + net_buf_simple_add_mem(msg, mod_id, 4); + } else { + net_buf_simple_add_mem(msg, mod_id, 2); + } + + if (mod) { + int i; + + for (i = 0; i < ARRAY_SIZE(mod->keys); i++) { + if (mod->keys[i] != BT_MESH_KEY_UNUSED) { + net_buf_simple_add_le16(msg, mod->keys[i]); + } + } + } + + if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + BT_ERR("Unable to send Model Application List message"); + } + +done: + os_mbuf_free_chain(msg); +} + +static void node_reset(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + /* Needed size: opcode (2 bytes) + msg + MIC */ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 0 + 4); + + BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); + + + bt_mesh_model_msg_init(msg, OP_NODE_RESET_STATUS); + + /* Send the response first since we wont have any keys left to + * send it later. + */ + if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + BT_ERR("Unable to send Node Reset Status"); + } + + bt_mesh_reset(); + os_mbuf_free_chain(msg); +} + +static void send_friend_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx) +{ + /* Needed size: opcode (2 bytes) + msg + MIC */ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4); + struct bt_mesh_cfg_srv *cfg = model->user_data; + + bt_mesh_model_msg_init(msg, OP_FRIEND_STATUS); + net_buf_simple_add_u8(msg, cfg->frnd); + + if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + BT_ERR("Unable to send Friend Status"); + } + os_mbuf_free_chain(msg); +} + +static void friend_get(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); + + send_friend_status(model, ctx); +} + +static void friend_set(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct bt_mesh_cfg_srv *cfg = model->user_data; + struct bt_mesh_subnet *sub; + + BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); + + if (buf->om_data[0] != 0x00 && buf->om_data[0] != 0x01) { + BT_WARN("Invalid Friend value 0x%02x", buf->om_data[0]); + return; + } + + if (!cfg) { + BT_WARN("No Configuration Server context available"); + goto send_status; + } + + BT_DBG("Friend 0x%02x -> 0x%02x", cfg->frnd, buf->om_data[0]); + + if (cfg->frnd == buf->om_data[0]) { + goto send_status; + } + + if (MYNEWT_VAL(BLE_MESH_FRIEND)) { + cfg->frnd = buf->om_data[0]; + + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + bt_mesh_store_cfg(); + } + + if (cfg->frnd == BT_MESH_FRIEND_DISABLED) { + bt_mesh_friend_clear_net_idx(BT_MESH_KEY_ANY); + } + } + + sub = bt_mesh_subnet_get(cfg->hb_pub.net_idx); + if ((cfg->hb_pub.feat & BT_MESH_FEAT_FRIEND) && sub) { + hb_send(model); + } + +send_status: + send_friend_status(model, ctx); +} + +static void lpn_timeout_get(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + /* Needed size: opcode (2 bytes) + msg + MIC */ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 5 + 4); + struct bt_mesh_friend *frnd; + u16_t lpn_addr; + s32_t timeout; + + lpn_addr = net_buf_simple_pull_le16(buf); + + BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x lpn_addr 0x%02x", + ctx->net_idx, ctx->app_idx, ctx->addr, lpn_addr); + + /* check if it's the address of the Low Power Node? */ + if (!BT_MESH_ADDR_IS_UNICAST(lpn_addr)) { + BT_WARN("Invalid LPNAddress; ignoring msg"); + goto done; + } + + bt_mesh_model_msg_init(msg, OP_LPN_TIMEOUT_STATUS); + net_buf_simple_add_le16(msg, lpn_addr); + + if (!IS_ENABLED(CONFIG_BT_MESH_FRIEND)) { + timeout = 0; + goto send_rsp; + } + + frnd = bt_mesh_friend_find(BT_MESH_KEY_ANY, lpn_addr, true, true); + if (!frnd) { + timeout = 0; + goto send_rsp; + } + + timeout = k_delayed_work_remaining_get(&frnd->timer) / 100; + +send_rsp: + net_buf_simple_add_u8(msg, timeout); + net_buf_simple_add_u8(msg, timeout >> 8); + net_buf_simple_add_u8(msg, timeout >> 16); + + if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + BT_ERR("Unable to send LPN PollTimeout Status"); + } + +done: + os_mbuf_free_chain(msg); +} + +static void send_krp_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + u16_t idx, u8_t phase, u8_t status) +{ + /* Needed size: opcode (2 bytes) + msg + MIC */ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 4 + 4); + + bt_mesh_model_msg_init(msg, OP_KRP_STATUS); + + net_buf_simple_add_u8(msg, status); + net_buf_simple_add_le16(msg, idx); + net_buf_simple_add_u8(msg, phase); + + if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + BT_ERR("Unable to send Key Refresh State Status"); + } + + os_mbuf_free_chain(msg); +} + +static void krp_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct bt_mesh_subnet *sub; + u16_t idx; + + idx = net_buf_simple_pull_le16(buf); + if (idx > 0xfff) { + BT_ERR("Invalid NetKeyIndex 0x%04x", idx); + return; + } + + BT_DBG("idx 0x%04x", idx); + + sub = bt_mesh_subnet_get(idx); + if (!sub) { + send_krp_status(model, ctx, idx, 0x00, STATUS_INVALID_NETKEY); + } else { + send_krp_status(model, ctx, idx, sub->kr_phase, + STATUS_SUCCESS); + } +} + +static void krp_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct bt_mesh_subnet *sub; + u8_t phase; + u16_t idx; + + idx = net_buf_simple_pull_le16(buf); + phase = net_buf_simple_pull_u8(buf); + + if (idx > 0xfff) { + BT_ERR("Invalid NetKeyIndex 0x%04x", idx); + return; + } + + BT_DBG("idx 0x%04x transition 0x%02x", idx, phase); + + sub = bt_mesh_subnet_get(idx); + if (!sub) { + send_krp_status(model, ctx, idx, 0x00, STATUS_INVALID_NETKEY); + return; + } + + BT_DBG("%u -> %u", sub->kr_phase, phase); + + if (phase < BT_MESH_KR_PHASE_2 || phase > BT_MESH_KR_PHASE_3 || + (sub->kr_phase == BT_MESH_KR_NORMAL && + phase == BT_MESH_KR_PHASE_2)) { + BT_WARN("Prohibited transition %u -> %u", sub->kr_phase, phase); + return; + } + + if (sub->kr_phase == BT_MESH_KR_PHASE_1 && + phase == BT_MESH_KR_PHASE_2) { + sub->kr_phase = BT_MESH_KR_PHASE_2; + sub->kr_flag = 1; + bt_mesh_net_beacon_update(sub); + } else if ((sub->kr_phase == BT_MESH_KR_PHASE_1 || + sub->kr_phase == BT_MESH_KR_PHASE_2) && + phase == BT_MESH_KR_PHASE_3) { + bt_mesh_net_revoke_keys(sub); + if ((MYNEWT_VAL(BLE_MESH_LOW_POWER)) || + (MYNEWT_VAL(BLE_MESH_FRIEND))) { + friend_cred_refresh(ctx->net_idx); + } + sub->kr_phase = BT_MESH_KR_NORMAL; + sub->kr_flag = 0; + bt_mesh_net_beacon_update(sub); + } + + send_krp_status(model, ctx, idx, sub->kr_phase, STATUS_SUCCESS); +} + +static u8_t hb_log(u16_t val) +{ + if (!val) { + return 0x00; + } else if (val == 0xffff) { + return 0xff; + } else { + return 32 - __builtin_clz(val); + } +} + +static u8_t hb_pub_count_log(u16_t val) +{ + if (!val) { + return 0x00; + } else if (val == 0x01) { + return 0x01; + } else if (val == 0xffff) { + return 0xff; + } else { + return 32 - __builtin_clz(val - 1) + 1; + } +} + +static u16_t hb_pwr2(u8_t val, u8_t sub) +{ + if (!val) { + return 0x0000; + } else if (val == 0xff || val == 0x11) { + return 0xffff; + } else { + return (1 << (val - sub)); + } +} + +struct hb_pub_param { + u16_t dst; + u8_t count_log; + u8_t period_log; + u8_t ttl; + u16_t feat; + u16_t net_idx; +} __packed; + +static void hb_pub_send_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, u8_t status, + struct hb_pub_param *orig_msg) +{ + /* Needed size: opcode (1 byte) + msg + MIC */ + struct os_mbuf *msg = NET_BUF_SIMPLE(1 + 10 + 4); + struct bt_mesh_cfg_srv *cfg = model->user_data; + + BT_DBG("src 0x%04x status 0x%02x", ctx->addr, status); + + bt_mesh_model_msg_init(msg, OP_HEARTBEAT_PUB_STATUS); + + net_buf_simple_add_u8(msg, status); + + if (orig_msg) { + memcpy(net_buf_simple_add(msg, sizeof(*orig_msg)), orig_msg, + sizeof(*orig_msg)); + goto send; + } + + net_buf_simple_add_le16(msg, cfg->hb_pub.dst); + net_buf_simple_add_u8(msg, hb_pub_count_log(cfg->hb_pub.count)); + net_buf_simple_add_u8(msg, cfg->hb_pub.period); + net_buf_simple_add_u8(msg, cfg->hb_pub.ttl); + net_buf_simple_add_le16(msg, cfg->hb_pub.feat); + net_buf_simple_add_le16(msg, cfg->hb_pub.net_idx); + +send: + if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + BT_ERR("Unable to send Heartbeat Publication Status"); + } + + os_mbuf_free_chain(msg); +} + +static void heartbeat_pub_get(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + BT_DBG("src 0x%04x", ctx->addr); + + hb_pub_send_status(model, ctx, STATUS_SUCCESS, NULL); +} + +static void heartbeat_pub_set(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct hb_pub_param *param = (void *)buf->om_data; + struct bt_mesh_cfg_srv *cfg = model->user_data; + u16_t dst, feat, idx; + u8_t status; + + BT_DBG("src 0x%04x", ctx->addr); + + dst = sys_le16_to_cpu(param->dst); + /* All other address types but virtual are valid */ + if (BT_MESH_ADDR_IS_VIRTUAL(dst)) { + status = STATUS_INVALID_ADDRESS; + goto failed; + } + + if (param->count_log > 0x11 && param->count_log != 0xff) { + status = STATUS_CANNOT_SET; + goto failed; + } + + if (param->period_log > 0x10) { + status = STATUS_CANNOT_SET; + goto failed; + } + + if (param->ttl > BT_MESH_TTL_MAX && param->ttl != BT_MESH_TTL_DEFAULT) { + BT_ERR("Invalid TTL value 0x%02x", param->ttl); + return; + } + + feat = sys_le16_to_cpu(param->feat); + + idx = sys_le16_to_cpu(param->net_idx); + if (idx > 0xfff) { + BT_ERR("Invalid NetKeyIndex 0x%04x", idx); + return; + } + + if (!bt_mesh_subnet_get(idx)) { + status = STATUS_INVALID_NETKEY; + goto failed; + } + + cfg->hb_pub.dst = dst; + cfg->hb_pub.period = param->period_log; + cfg->hb_pub.feat = feat & BT_MESH_FEAT_SUPPORTED; + cfg->hb_pub.net_idx = idx; + + if (dst == BT_MESH_ADDR_UNASSIGNED) { + hb_pub_disable(cfg); + } else { + /* 2^(n-1) */ + cfg->hb_pub.count = hb_pwr2(param->count_log, 1); + cfg->hb_pub.ttl = param->ttl; + + BT_DBG("period %u ms", hb_pwr2(param->period_log, 1) * 1000); + + /* The first Heartbeat message shall be published as soon + * as possible after the Heartbeat Publication Period state + * has been configured for periodic publishing. + */ + if (param->period_log && param->count_log) { + k_work_submit(&cfg->hb_pub.timer.work); + } else { + k_delayed_work_cancel(&cfg->hb_pub.timer); + } + } + + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + bt_mesh_store_hb_pub(); + } + + hb_pub_send_status(model, ctx, STATUS_SUCCESS, NULL); + + return; + +failed: + hb_pub_send_status(model, ctx, status, param); +} + +static void hb_sub_send_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, u8_t status) +{ + /* Needed size: opcode (2 bytes) + msg + MIC */ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 9 + 4); + struct bt_mesh_cfg_srv *cfg = model->user_data; + u16_t period; + s64_t uptime; + + BT_DBG("src 0x%04x status 0x%02x", ctx->addr, status); + + uptime = k_uptime_get(); + if (uptime > cfg->hb_sub.expiry) { + period = 0; + } else { + period = (cfg->hb_sub.expiry - uptime) / 1000; + } + + bt_mesh_model_msg_init(msg, OP_HEARTBEAT_SUB_STATUS); + + net_buf_simple_add_u8(msg, status); + + net_buf_simple_add_le16(msg, cfg->hb_sub.src); + net_buf_simple_add_le16(msg, cfg->hb_sub.dst); + + net_buf_simple_add_u8(msg, hb_log(period)); + net_buf_simple_add_u8(msg, hb_log(cfg->hb_sub.count)); + net_buf_simple_add_u8(msg, cfg->hb_sub.min_hops); + net_buf_simple_add_u8(msg, cfg->hb_sub.max_hops); + + + if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + BT_ERR("Unable to send Heartbeat Subscription Status"); + } + + os_mbuf_free_chain(msg); +} + +static void heartbeat_sub_get(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + BT_DBG("src 0x%04x", ctx->addr); + + hb_sub_send_status(model, ctx, STATUS_SUCCESS); +} + +static void heartbeat_sub_set(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct bt_mesh_cfg_srv *cfg = model->user_data; + u16_t sub_src, sub_dst; + u8_t sub_period; + s32_t period_ms; + + BT_DBG("src 0x%04x", ctx->addr); + + sub_src = net_buf_simple_pull_le16(buf); + sub_dst = net_buf_simple_pull_le16(buf); + sub_period = net_buf_simple_pull_u8(buf); + + BT_DBG("sub_src 0x%04x sub_dst 0x%04x period 0x%02x", + sub_src, sub_dst, sub_period); + + if (sub_src != BT_MESH_ADDR_UNASSIGNED && + !BT_MESH_ADDR_IS_UNICAST(sub_src)) { + BT_WARN("Prohibited source address"); + return; + } + + if (BT_MESH_ADDR_IS_VIRTUAL(sub_dst) || BT_MESH_ADDR_IS_RFU(sub_dst) || + (BT_MESH_ADDR_IS_UNICAST(sub_dst) && + sub_dst != bt_mesh_primary_addr())) { + BT_WARN("Prohibited destination address"); + return; + } + + if (sub_period > 0x11) { + BT_WARN("Prohibited subscription period 0x%02x", sub_period); + return; + } + + if (sub_src == BT_MESH_ADDR_UNASSIGNED || + sub_dst == BT_MESH_ADDR_UNASSIGNED || + sub_period == 0x00) { + /* Only an explicit address change to unassigned should + * trigger clearing of the values according to + * MESH/NODE/CFG/HBS/BV-02-C. + */ + if (sub_src == BT_MESH_ADDR_UNASSIGNED || + sub_dst == BT_MESH_ADDR_UNASSIGNED) { + cfg->hb_sub.src = BT_MESH_ADDR_UNASSIGNED; + cfg->hb_sub.dst = BT_MESH_ADDR_UNASSIGNED; + cfg->hb_sub.min_hops = BT_MESH_TTL_MAX; + cfg->hb_sub.max_hops = 0; + cfg->hb_sub.count = 0; + } + + period_ms = 0; + } else { + cfg->hb_sub.src = sub_src; + cfg->hb_sub.dst = sub_dst; + cfg->hb_sub.min_hops = BT_MESH_TTL_MAX; + cfg->hb_sub.max_hops = 0; + cfg->hb_sub.count = 0; + period_ms = hb_pwr2(sub_period, 1) * 1000; + } + + /* Let the transport layer know it needs to handle this address */ + bt_mesh_set_hb_sub_dst(cfg->hb_sub.dst); + + BT_DBG("period_ms %u", (unsigned) period_ms); + + if (period_ms) { + cfg->hb_sub.expiry = k_uptime_get() + period_ms; + } else { + cfg->hb_sub.expiry = 0; + } + + hb_sub_send_status(model, ctx, STATUS_SUCCESS); + + /* MESH/NODE/CFG/HBS/BV-01-C expects the MinHops to be 0x7f after + * disabling subscription, but 0x00 for subsequent Get requests. + */ + if (!period_ms) { + cfg->hb_sub.min_hops = 0; + } +} + +const struct bt_mesh_model_op bt_mesh_cfg_srv_op[] = { + { OP_DEV_COMP_DATA_GET, 1, dev_comp_data_get }, + { OP_APP_KEY_ADD, 19, app_key_add }, + { OP_APP_KEY_UPDATE, 19, app_key_update }, + { OP_APP_KEY_DEL, 3, app_key_del }, + { OP_APP_KEY_GET, 2, app_key_get }, + { OP_BEACON_GET, 0, beacon_get }, + { OP_BEACON_SET, 1, beacon_set }, + { OP_DEFAULT_TTL_GET, 0, default_ttl_get }, + { OP_DEFAULT_TTL_SET, 1, default_ttl_set }, + { OP_GATT_PROXY_GET, 0, gatt_proxy_get }, + { OP_GATT_PROXY_SET, 1, gatt_proxy_set }, + { OP_NET_TRANSMIT_GET, 0, net_transmit_get }, + { OP_NET_TRANSMIT_SET, 1, net_transmit_set }, + { OP_RELAY_GET, 0, relay_get }, + { OP_RELAY_SET, 2, relay_set }, + { OP_MOD_PUB_GET, 4, mod_pub_get }, + { OP_MOD_PUB_SET, 11, mod_pub_set }, + { OP_MOD_PUB_VA_SET, 24, mod_pub_va_set }, + { OP_MOD_SUB_ADD, 6, mod_sub_add }, + { OP_MOD_SUB_VA_ADD, 20, mod_sub_va_add }, + { OP_MOD_SUB_DEL, 6, mod_sub_del }, + { OP_MOD_SUB_VA_DEL, 20, mod_sub_va_del }, + { OP_MOD_SUB_OVERWRITE, 6, mod_sub_overwrite }, + { OP_MOD_SUB_VA_OVERWRITE, 20, mod_sub_va_overwrite }, + { OP_MOD_SUB_DEL_ALL, 4, mod_sub_del_all }, + { OP_MOD_SUB_GET, 4, mod_sub_get }, + { OP_MOD_SUB_GET_VND, 6, mod_sub_get_vnd }, + { OP_NET_KEY_ADD, 18, net_key_add }, + { OP_NET_KEY_UPDATE, 18, net_key_update }, + { OP_NET_KEY_DEL, 2, net_key_del }, + { OP_NET_KEY_GET, 0, net_key_get }, + { OP_NODE_IDENTITY_GET, 2, node_identity_get }, + { OP_NODE_IDENTITY_SET, 3, node_identity_set }, + { OP_MOD_APP_BIND, 6, mod_app_bind }, + { OP_MOD_APP_UNBIND, 6, mod_app_unbind }, + { OP_SIG_MOD_APP_GET, 4, mod_app_get }, + { OP_VND_MOD_APP_GET, 6, mod_app_get }, + { OP_NODE_RESET, 0, node_reset }, + { OP_FRIEND_GET, 0, friend_get }, + { OP_FRIEND_SET, 1, friend_set }, + { OP_LPN_TIMEOUT_GET, 2, lpn_timeout_get }, + { OP_KRP_GET, 2, krp_get }, + { OP_KRP_SET, 3, krp_set }, + { OP_HEARTBEAT_PUB_GET, 0, heartbeat_pub_get }, + { OP_HEARTBEAT_PUB_SET, 9, heartbeat_pub_set }, + { OP_HEARTBEAT_SUB_GET, 0, heartbeat_sub_get }, + { OP_HEARTBEAT_SUB_SET, 5, heartbeat_sub_set }, + BT_MESH_MODEL_OP_END, +}; + +static void hb_publish(struct ble_npl_event *work) +{ + struct bt_mesh_cfg_srv *cfg = ble_npl_event_get_arg(work); + struct bt_mesh_model *model = cfg->model; + struct bt_mesh_subnet *sub; + u16_t period_ms; + + BT_DBG("hb_pub.count: %u", cfg->hb_pub.count); + + sub = bt_mesh_subnet_get(cfg->hb_pub.net_idx); + if (!sub) { + BT_ERR("No matching subnet for idx 0x%02x", + cfg->hb_pub.net_idx); + cfg->hb_pub.dst = BT_MESH_ADDR_UNASSIGNED; + return; + } + + if (cfg->hb_pub.count == 0) { + return; + } + + period_ms = hb_pwr2(cfg->hb_pub.period, 1) * 1000; + if (period_ms && cfg->hb_pub.count > 1) { + k_delayed_work_submit(&cfg->hb_pub.timer, period_ms); + } + + hb_send(model); + + if (cfg->hb_pub.count != 0xffff) { + cfg->hb_pub.count--; + } +} + +static bool conf_is_valid(struct bt_mesh_cfg_srv *cfg) +{ + if (cfg->relay > 0x02) { + return false; + } + + if (cfg->beacon > 0x01) { + return false; + } + + if (cfg->default_ttl > BT_MESH_TTL_MAX) { + return false; + } + + return true; +} + +int bt_mesh_cfg_srv_init(struct bt_mesh_model *model, bool primary) +{ + struct bt_mesh_cfg_srv *cfg = model->user_data; + + if (!cfg) { + BT_ERR("No Configuration Server context provided"); + return -EINVAL; + } + + if (!conf_is_valid(cfg)) { + BT_ERR("Invalid values in configuration"); + return -EINVAL; + } + + /* Configuration Model security is device-key based */ + model->keys[0] = BT_MESH_KEY_DEV; + + if (!(MYNEWT_VAL(BLE_MESH_RELAY))) { + cfg->relay = BT_MESH_RELAY_NOT_SUPPORTED; + } + + if (!(MYNEWT_VAL(BLE_MESH_FRIEND))) { + cfg->frnd = BT_MESH_FRIEND_NOT_SUPPORTED; + } + + if (!(MYNEWT_VAL(BLE_MESH_GATT_PROXY))) { + cfg->gatt_proxy = BT_MESH_GATT_PROXY_NOT_SUPPORTED; + } + + k_delayed_work_init(&cfg->hb_pub.timer, hb_publish); + k_delayed_work_add_arg(&cfg->hb_pub.timer, cfg); + cfg->hb_pub.net_idx = BT_MESH_KEY_UNUSED; + cfg->hb_sub.expiry = 0; + + cfg->model = model; + + conf = cfg; + + return 0; +} + +static void mod_reset(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, + bool vnd, bool primary, void *user_data) +{ + /* Clear model state that isn't otherwise cleared. E.g. AppKey + * binding and model publication is cleared as a consequence + * of removing all app keys, however model subscription clearing + * must be taken care of here. + */ + + mod_sub_list_clear(mod); + + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + bt_mesh_store_mod_sub(mod); + } +} + +void bt_mesh_cfg_reset(void) +{ + struct bt_mesh_cfg_srv *cfg = conf; + int i; + + if (!cfg) { + return; + } + + bt_mesh_set_hb_sub_dst(BT_MESH_ADDR_UNASSIGNED); + + cfg->hb_sub.src = BT_MESH_ADDR_UNASSIGNED; + cfg->hb_sub.dst = BT_MESH_ADDR_UNASSIGNED; + cfg->hb_sub.expiry = 0; + + /* Delete all net keys, which also takes care of all app keys which + * are associated with each net key. + */ + for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) { + struct bt_mesh_subnet *sub = &bt_mesh.sub[i]; + + if (sub->net_idx != BT_MESH_KEY_UNUSED) { + bt_mesh_subnet_del(sub, true); + } + } + + bt_mesh_model_foreach(mod_reset, NULL); + + memset(labels, 0, sizeof(labels)); +} + +void bt_mesh_heartbeat(u16_t src, u16_t dst, u8_t hops, u16_t feat) +{ + struct bt_mesh_cfg_srv *cfg = conf; + + if (!cfg) { + BT_WARN("No configuaration server context available"); + return; + } + + if (src != cfg->hb_sub.src || dst != cfg->hb_sub.dst) { + BT_WARN("No subscription for received heartbeat"); + return; + } + + if (k_uptime_get() > cfg->hb_sub.expiry) { + BT_WARN("Heartbeat subscription period expired"); + return; + } + + cfg->hb_sub.min_hops = min(cfg->hb_sub.min_hops, hops); + cfg->hb_sub.max_hops = max(cfg->hb_sub.max_hops, hops); + + if (cfg->hb_sub.count < 0xffff) { + cfg->hb_sub.count++; + } + + BT_DBG("src 0x%04x dst 0x%04x hops %u min %u max %u count %u", src, + dst, hops, cfg->hb_sub.min_hops, cfg->hb_sub.max_hops, + cfg->hb_sub.count); + + if (cfg->hb_sub.func) { + cfg->hb_sub.func(hops, feat); + } +} + +u8_t bt_mesh_net_transmit_get(void) +{ + if (conf) { + return conf->net_transmit; + } + + return 0; +} + +u8_t bt_mesh_relay_get(void) +{ + if (conf) { + return conf->relay; + } + + return BT_MESH_RELAY_NOT_SUPPORTED; +} + +u8_t bt_mesh_friend_get(void) +{ + BT_DBG("conf %p conf->frnd 0x%02x", conf, conf->frnd); + + if (conf) { + return conf->frnd; + } + + return BT_MESH_FRIEND_NOT_SUPPORTED; +} + +u8_t bt_mesh_relay_retransmit_get(void) +{ + if (conf) { + return conf->relay_retransmit; + } + + return 0; +} + +u8_t bt_mesh_beacon_get(void) +{ + if (conf) { + return conf->beacon; + } + + return BT_MESH_BEACON_DISABLED; +} + +u8_t bt_mesh_gatt_proxy_get(void) +{ + if (conf) { + return conf->gatt_proxy; + } + + return BT_MESH_GATT_PROXY_NOT_SUPPORTED; +} + +u8_t bt_mesh_default_ttl_get(void) +{ + if (conf) { + return conf->default_ttl; + } + + return DEFAULT_TTL; +} + +u8_t *bt_mesh_label_uuid_get(u16_t addr) +{ + int i; + + BT_DBG("addr 0x%04x", addr); + + for (i = 0; i < ARRAY_SIZE(labels); i++) { + if (labels[i].addr == addr) { + BT_DBG("Found Label UUID for 0x%04x: %s", addr, + bt_hex(labels[i].uuid, 16)); + return labels[i].uuid; + } + } + + BT_WARN("No matching Label UUID for 0x%04x", addr); + + return NULL; +} + +struct bt_mesh_hb_pub *bt_mesh_hb_pub_get(void) +{ + if (!conf) { + return NULL; + } + + return &conf->hb_pub; +} + +void bt_mesh_hb_pub_disable(void) +{ + if (conf) { + hb_pub_disable(conf); + } +} + +struct bt_mesh_cfg_srv *bt_mesh_cfg_get(void) +{ + return conf; +} + +void bt_mesh_subnet_del(struct bt_mesh_subnet *sub, bool store) +{ + int i; + + BT_DBG("NetIdx 0x%03x store %u", sub->net_idx, store); + + if (conf && conf->hb_pub.net_idx == sub->net_idx) { + hb_pub_disable(conf); + + if (IS_ENABLED(CONFIG_BT_SETTINGS) && store) { + bt_mesh_store_hb_pub(); + } + } + + /* Delete any app keys bound to this NetKey index */ + for (i = 0; i < ARRAY_SIZE(bt_mesh.app_keys); i++) { + struct bt_mesh_app_key *key = &bt_mesh.app_keys[i]; + + if (key->net_idx == sub->net_idx) { + bt_mesh_app_key_del(key, store); + } + } + + if (IS_ENABLED(CONFIG_BT_MESH_FRIEND)) { + bt_mesh_friend_clear_net_idx(sub->net_idx); + } + + if (IS_ENABLED(CONFIG_BT_SETTINGS) && store) { + bt_mesh_clear_subnet(sub); + } + + memset(sub, 0, sizeof(*sub)); + sub->net_idx = BT_MESH_KEY_UNUSED; +} diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/crypto.c b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/crypto.c new file mode 100644 index 000000000..79553cba4 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/crypto.c @@ -0,0 +1,926 @@ +/* Bluetooth Mesh */ + +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include "syscfg/syscfg.h" + +#if (MYNEWT_VAL(BLE_CRYPTO_STACK_MBEDTLS)) +#include "mbedtls/aes.h" +#include "mbedtls/cipher.h" +#include "mbedtls/entropy.h" +#include "mbedtls/ctr_drbg.h" +#include "mbedtls/cmac.h" +#include "mbedtls/ecdh.h" +#include "mbedtls/ecp.h" + +#else +#include +#include +#include +#include +#include + +#endif + +#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG_CRYPTO)) +#include "host/ble_hs_log.h" + +#include "crypto.h" + +#define NET_MIC_LEN(pdu) (((pdu)[1] & 0x80) ? 8 : 4) +#define APP_MIC_LEN(aszmic) ((aszmic) ? 8 : 4) + +#if MYNEWT_VAL(BLE_CRYPTO_STACK_MBEDTLS) +int bt_mesh_aes_cmac(const u8_t key[16], struct bt_mesh_sg *sg, + size_t sg_len, u8_t mac[16]) +{ + int rc = BLE_HS_EUNKNOWN; + mbedtls_cipher_context_t ctx = {0}; + const mbedtls_cipher_info_t *cipher_info; + + mbedtls_cipher_init(&ctx); + + cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB); + if (cipher_info == NULL) { + goto exit; + } + + if (mbedtls_cipher_setup(&ctx, cipher_info) != 0) { + goto exit; + } + + rc = mbedtls_cipher_cmac_starts(&ctx, key, 128); + if (rc != 0) { + goto exit; + } + + for (; sg_len; sg_len--, sg++) { + if (sg->len != 0 && sg->data != NULL) { + if ((rc = mbedtls_cipher_cmac_update(&ctx, sg->data, sg->len)) != 0) { + goto exit; + } + } + } + rc = mbedtls_cipher_cmac_finish(&ctx, mac); + +exit: + mbedtls_cipher_free(&ctx); + if (rc != 0) { + return -EIO; + } + + return 0; +} + +#else +int bt_mesh_aes_cmac(const u8_t key[16], struct bt_mesh_sg *sg, + size_t sg_len, u8_t mac[16]) +{ + struct tc_aes_key_sched_struct sched; + struct tc_cmac_struct state; + + if (tc_cmac_setup(&state, key, &sched) == TC_CRYPTO_FAIL) { + return -EIO; + } + + for (; sg_len; sg_len--, sg++) { + if (tc_cmac_update(&state, sg->data, + sg->len) == TC_CRYPTO_FAIL) { + return -EIO; + } + } + + if (tc_cmac_final(mac, &state) == TC_CRYPTO_FAIL) { + return -EIO; + } + + return 0; +} +#endif + +int bt_mesh_k1(const u8_t *ikm, size_t ikm_len, const u8_t salt[16], + const char *info, u8_t okm[16]) +{ + int err; + + err = bt_mesh_aes_cmac_one(salt, ikm, ikm_len, okm); + if (err < 0) { + return err; + } + + return bt_mesh_aes_cmac_one(okm, info, strlen(info), okm); +} + +int bt_mesh_k2(const u8_t n[16], const u8_t *p, size_t p_len, + u8_t net_id[1], u8_t enc_key[16], u8_t priv_key[16]) +{ + struct bt_mesh_sg sg[3]; + u8_t salt[16]; + u8_t out[16]; + u8_t t[16]; + u8_t pad; + int err; + + BT_DBG("n %s", bt_hex(n, 16)); + BT_DBG("p %s", bt_hex(p, p_len)); + + err = bt_mesh_s1("smk2", salt); + if (err) { + return err; + } + + err = bt_mesh_aes_cmac_one(salt, n, 16, t); + if (err) { + return err; + } + + pad = 0x01; + + sg[0].data = NULL; + sg[0].len = 0; + sg[1].data = p; + sg[1].len = p_len; + sg[2].data = &pad; + sg[2].len = sizeof(pad); + + err = bt_mesh_aes_cmac(t, sg, ARRAY_SIZE(sg), out); + if (err) { + return err; + } + + net_id[0] = out[15] & 0x7f; + + sg[0].data = out; + sg[0].len = sizeof(out); + pad = 0x02; + + err = bt_mesh_aes_cmac(t, sg, ARRAY_SIZE(sg), out); + if (err) { + return err; + } + + memcpy(enc_key, out, 16); + + pad = 0x03; + + err = bt_mesh_aes_cmac(t, sg, ARRAY_SIZE(sg), out); + if (err) { + return err; + } + + memcpy(priv_key, out, 16); + + BT_DBG("NID 0x%02x enc_key %s", net_id[0], bt_hex(enc_key, 16)); + BT_DBG("priv_key %s", bt_hex(priv_key, 16)); + + return 0; +} + +int bt_mesh_k3(const u8_t n[16], u8_t out[8]) +{ + u8_t id64[] = { 'i', 'd', '6', '4', 0x01 }; + u8_t tmp[16]; + u8_t t[16]; + int err; + + err = bt_mesh_s1("smk3", tmp); + if (err) { + return err; + } + + err = bt_mesh_aes_cmac_one(tmp, n, 16, t); + if (err) { + return err; + } + + err = bt_mesh_aes_cmac_one(t, id64, sizeof(id64), tmp); + if (err) { + return err; + } + + memcpy(out, tmp + 8, 8); + + return 0; +} + +int bt_mesh_k4(const u8_t n[16], u8_t out[1]) +{ + u8_t id6[] = { 'i', 'd', '6', 0x01 }; + u8_t tmp[16]; + u8_t t[16]; + int err; + + err = bt_mesh_s1("smk4", tmp); + if (err) { + return err; + } + + err = bt_mesh_aes_cmac_one(tmp, n, 16, t); + if (err) { + return err; + } + + err = bt_mesh_aes_cmac_one(t, id6, sizeof(id6), tmp); + if (err) { + return err; + } + + out[0] = tmp[15] & BIT_MASK(6); + + return 0; +} + +int bt_mesh_id128(const u8_t n[16], const char *s, u8_t out[16]) +{ + const char *id128 = "id128\x01"; + u8_t salt[16]; + int err; + + err = bt_mesh_s1(s, salt); + if (err) { + return err; + } + + return bt_mesh_k1(n, 16, salt, id128, out); +} + +static int bt_mesh_ccm_decrypt(const u8_t key[16], u8_t nonce[13], + const u8_t *enc_msg, size_t msg_len, + const u8_t *aad, size_t aad_len, + u8_t *out_msg, size_t mic_size) +{ + u8_t msg[16], pmsg[16], cmic[16], cmsg[16], Xn[16], mic[16]; + u16_t last_blk, blk_cnt; + size_t i, j; + int err; + + if (msg_len < 1 || aad_len >= 0xff00) { + return -EINVAL; + } + + /* C_mic = e(AppKey, 0x01 || nonce || 0x0000) */ + pmsg[0] = 0x01; + memcpy(pmsg + 1, nonce, 13); + sys_put_be16(0x0000, pmsg + 14); + + err = bt_encrypt_be(key, pmsg, cmic); + if (err) { + return err; + } + + /* X_0 = e(AppKey, 0x09 || nonce || length) */ + if (mic_size == sizeof(u64_t)) { + pmsg[0] = 0x19 | (aad_len ? 0x40 : 0x00); + } else { + pmsg[0] = 0x09 | (aad_len ? 0x40 : 0x00); + } + + memcpy(pmsg + 1, nonce, 13); + sys_put_be16(msg_len, pmsg + 14); + + err = bt_encrypt_be(key, pmsg, Xn); + if (err) { + return err; + } + + /* If AAD is being used to authenticate, include it here */ + if (aad_len) { + sys_put_be16(aad_len, pmsg); + + for (i = 0; i < sizeof(u16_t); i++) { + pmsg[i] = Xn[i] ^ pmsg[i]; + } + + j = 0; + aad_len += sizeof(u16_t); + while (aad_len > 16) { + do { + pmsg[i] = Xn[i] ^ aad[j]; + i++, j++; + } while (i < 16); + + aad_len -= 16; + i = 0; + + err = bt_encrypt_be(key, pmsg, Xn); + if (err) { + return err; + } + } + + for (i = 0; i < aad_len; i++, j++) { + pmsg[i] = Xn[i] ^ aad[j]; + } + + for (i = aad_len; i < 16; i++) { + pmsg[i] = Xn[i]; + } + + err = bt_encrypt_be(key, pmsg, Xn); + if (err) { + return err; + } + } + + last_blk = msg_len % 16; + blk_cnt = (msg_len + 15) / 16; + if (!last_blk) { + last_blk = 16; + } + + for (j = 0; j < blk_cnt; j++) { + if (j + 1 == blk_cnt) { + /* C_1 = e(AppKey, 0x01 || nonce || 0x0001) */ + pmsg[0] = 0x01; + memcpy(pmsg + 1, nonce, 13); + sys_put_be16(j + 1, pmsg + 14); + + err = bt_encrypt_be(key, pmsg, cmsg); + if (err) { + return err; + } + + /* Encrypted = Payload[0-15] ^ C_1 */ + for (i = 0; i < last_blk; i++) { + msg[i] = enc_msg[(j * 16) + i] ^ cmsg[i]; + } + + memcpy(out_msg + (j * 16), msg, last_blk); + + /* X_1 = e(AppKey, X_0 ^ Payload[0-15]) */ + for (i = 0; i < last_blk; i++) { + pmsg[i] = Xn[i] ^ msg[i]; + } + + for (i = last_blk; i < 16; i++) { + pmsg[i] = Xn[i] ^ 0x00; + } + + err = bt_encrypt_be(key, pmsg, Xn); + if (err) { + return err; + } + + /* MIC = C_mic ^ X_1 */ + for (i = 0; i < sizeof(mic); i++) { + mic[i] = cmic[i] ^ Xn[i]; + } + } else { + /* C_1 = e(AppKey, 0x01 || nonce || 0x0001) */ + pmsg[0] = 0x01; + memcpy(pmsg + 1, nonce, 13); + sys_put_be16(j + 1, pmsg + 14); + + err = bt_encrypt_be(key, pmsg, cmsg); + if (err) { + return err; + } + + /* Encrypted = Payload[0-15] ^ C_1 */ + for (i = 0; i < 16; i++) { + msg[i] = enc_msg[(j * 16) + i] ^ cmsg[i]; + } + + memcpy(out_msg + (j * 16), msg, 16); + + /* X_1 = e(AppKey, X_0 ^ Payload[0-15]) */ + for (i = 0; i < 16; i++) { + pmsg[i] = Xn[i] ^ msg[i]; + } + + err = bt_encrypt_be(key, pmsg, Xn); + if (err) { + return err; + } + } + } + + if (memcmp(mic, enc_msg + msg_len, mic_size)) { + return -EBADMSG; + } + + return 0; +} + +static int bt_mesh_ccm_encrypt(const u8_t key[16], u8_t nonce[13], + const u8_t *msg, size_t msg_len, + const u8_t *aad, size_t aad_len, + u8_t *out_msg, size_t mic_size) +{ + u8_t pmsg[16], cmic[16], cmsg[16], mic[16], Xn[16]; + u16_t blk_cnt, last_blk; + size_t i, j; + int err; + + BT_DBG("key %s", bt_hex(key, 16)); + BT_DBG("nonce %s", bt_hex(nonce, 13)); + BT_DBG("msg (len %zu) %s", msg_len, bt_hex(msg, msg_len)); + BT_DBG("aad_len %zu mic_size %zu", aad_len, mic_size); + + /* Unsupported AAD size */ + if (aad_len >= 0xff00) { + return -EINVAL; + } + + /* C_mic = e(AppKey, 0x01 || nonce || 0x0000) */ + pmsg[0] = 0x01; + memcpy(pmsg + 1, nonce, 13); + sys_put_be16(0x0000, pmsg + 14); + + err = bt_encrypt_be(key, pmsg, cmic); + if (err) { + return err; + } + + /* X_0 = e(AppKey, 0x09 || nonce || length) */ + if (mic_size == sizeof(u64_t)) { + pmsg[0] = 0x19 | (aad_len ? 0x40 : 0x00); + } else { + pmsg[0] = 0x09 | (aad_len ? 0x40 : 0x00); + } + + memcpy(pmsg + 1, nonce, 13); + sys_put_be16(msg_len, pmsg + 14); + + err = bt_encrypt_be(key, pmsg, Xn); + if (err) { + return err; + } + + /* If AAD is being used to authenticate, include it here */ + if (aad_len) { + sys_put_be16(aad_len, pmsg); + + for (i = 0; i < sizeof(u16_t); i++) { + pmsg[i] = Xn[i] ^ pmsg[i]; + } + + j = 0; + aad_len += sizeof(u16_t); + while (aad_len > 16) { + do { + pmsg[i] = Xn[i] ^ aad[j]; + i++, j++; + } while (i < 16); + + aad_len -= 16; + i = 0; + + err = bt_encrypt_be(key, pmsg, Xn); + if (err) { + return err; + } + } + + for (i = 0; i < aad_len; i++, j++) { + pmsg[i] = Xn[i] ^ aad[j]; + } + + for (i = aad_len; i < 16; i++) { + pmsg[i] = Xn[i]; + } + + err = bt_encrypt_be(key, pmsg, Xn); + if (err) { + return err; + } + } + + last_blk = msg_len % 16; + blk_cnt = (msg_len + 15) / 16; + if (!last_blk) { + last_blk = 16; + } + + for (j = 0; j < blk_cnt; j++) { + if (j + 1 == blk_cnt) { + /* X_1 = e(AppKey, X_0 ^ Payload[0-15]) */ + for (i = 0; i < last_blk; i++) { + pmsg[i] = Xn[i] ^ msg[(j * 16) + i]; + } + for (i = last_blk; i < 16; i++) { + pmsg[i] = Xn[i] ^ 0x00; + } + + err = bt_encrypt_be(key, pmsg, Xn); + if (err) { + return err; + } + + /* MIC = C_mic ^ X_1 */ + for (i = 0; i < sizeof(mic); i++) { + mic[i] = cmic[i] ^ Xn[i]; + } + + /* C_1 = e(AppKey, 0x01 || nonce || 0x0001) */ + pmsg[0] = 0x01; + memcpy(pmsg + 1, nonce, 13); + sys_put_be16(j + 1, pmsg + 14); + + err = bt_encrypt_be(key, pmsg, cmsg); + if (err) { + return err; + } + + /* Encrypted = Payload[0-15] ^ C_1 */ + for (i = 0; i < last_blk; i++) { + out_msg[(j * 16) + i] = + msg[(j * 16) + i] ^ cmsg[i]; + } + } else { + /* X_1 = e(AppKey, X_0 ^ Payload[0-15]) */ + for (i = 0; i < 16; i++) { + pmsg[i] = Xn[i] ^ msg[(j * 16) + i]; + } + + err = bt_encrypt_be(key, pmsg, Xn); + if (err) { + return err; + } + + /* C_1 = e(AppKey, 0x01 || nonce || 0x0001) */ + pmsg[0] = 0x01; + memcpy(pmsg + 1, nonce, 13); + sys_put_be16(j + 1, pmsg + 14); + + err = bt_encrypt_be(key, pmsg, cmsg); + if (err) { + return err; + } + + /* Encrypted = Payload[0-15] ^ C_N */ + for (i = 0; i < 16; i++) { + out_msg[(j * 16) + i] = + msg[(j * 16) + i] ^ cmsg[i]; + } + + } + } + + memcpy(out_msg + msg_len, mic, mic_size); + + return 0; +} + +#if (MYNEWT_VAL(BLE_MESH_PROXY)) +static void create_proxy_nonce(u8_t nonce[13], const u8_t *pdu, + u32_t iv_index) +{ + /* Nonce Type */ + nonce[0] = 0x03; + + /* Pad */ + nonce[1] = 0x00; + + /* Sequence Number */ + nonce[2] = pdu[2]; + nonce[3] = pdu[3]; + nonce[4] = pdu[4]; + + /* Source Address */ + nonce[5] = pdu[5]; + nonce[6] = pdu[6]; + + /* Pad */ + nonce[7] = 0; + nonce[8] = 0; + + /* IV Index */ + sys_put_be32(iv_index, &nonce[9]); +} +#endif /* PROXY */ + +static void create_net_nonce(u8_t nonce[13], const u8_t *pdu, + u32_t iv_index) +{ + /* Nonce Type */ + nonce[0] = 0x00; + + /* FRND + TTL */ + nonce[1] = pdu[1]; + + /* Sequence Number */ + nonce[2] = pdu[2]; + nonce[3] = pdu[3]; + nonce[4] = pdu[4]; + + /* Source Address */ + nonce[5] = pdu[5]; + nonce[6] = pdu[6]; + + /* Pad */ + nonce[7] = 0; + nonce[8] = 0; + + /* IV Index */ + sys_put_be32(iv_index, &nonce[9]); +} + +int bt_mesh_net_obfuscate(u8_t *pdu, u32_t iv_index, + const u8_t privacy_key[16]) +{ + u8_t priv_rand[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, }; + u8_t tmp[16]; + int err, i; + + BT_DBG("IVIndex %u, PrivacyKey %s", (unsigned) iv_index, + bt_hex(privacy_key, 16)); + + sys_put_be32(iv_index, &priv_rand[5]); + memcpy(&priv_rand[9], &pdu[7], 7); + + BT_DBG("PrivacyRandom %s", bt_hex(priv_rand, 16)); + + err = bt_encrypt_be(privacy_key, priv_rand, tmp); + if (err) { + return err; + } + + for (i = 0; i < 6; i++) { + pdu[1 + i] ^= tmp[i]; + } + + return 0; +} + +int bt_mesh_net_encrypt(const u8_t key[16], struct os_mbuf *buf, + u32_t iv_index, bool proxy) +{ + u8_t mic_len = NET_MIC_LEN(buf->om_data); + u8_t nonce[13]; + int err; + + BT_DBG("IVIndex %u EncKey %s mic_len %u", (unsigned) iv_index, + bt_hex(key, 16), mic_len); + BT_DBG("PDU (len %u) %s", buf->om_len, bt_hex(buf->om_data, buf->om_len)); + +#if (MYNEWT_VAL(BLE_MESH_PROXY)) + if (proxy) { + create_proxy_nonce(nonce, buf->om_data, iv_index); + } else { + create_net_nonce(nonce, buf->om_data, iv_index); + } +#else + create_net_nonce(nonce, buf->om_data, iv_index); +#endif + + BT_DBG("Nonce %s", bt_hex(nonce, 13)); + + err = bt_mesh_ccm_encrypt(key, nonce, &buf->om_data[7], buf->om_len - 7, + NULL, 0, &buf->om_data[7], mic_len); + if (!err) { + net_buf_simple_add(buf, mic_len); + } + + return err; +} + +int bt_mesh_net_decrypt(const u8_t key[16], struct os_mbuf *buf, + u32_t iv_index, bool proxy) +{ + u8_t mic_len = NET_MIC_LEN(buf->om_data); + u8_t nonce[13]; + + BT_DBG("PDU (%u bytes) %s", buf->om_len, bt_hex(buf->om_data, buf->om_len)); + BT_DBG("iv_index %u, key %s mic_len %u", (unsigned) iv_index, + bt_hex(key, 16), mic_len); + +#if (MYNEWT_VAL(BLE_MESH_PROXY)) + if (proxy) { + create_proxy_nonce(nonce, buf->om_data, iv_index); + } else { + create_net_nonce(nonce, buf->om_data, iv_index); + } +#else + create_net_nonce(nonce, buf->om_data, iv_index); +#endif + + BT_DBG("Nonce %s", bt_hex(nonce, 13)); + + buf->om_len -= mic_len; + + return bt_mesh_ccm_decrypt(key, nonce, &buf->om_data[7], buf->om_len - 7, + NULL, 0, &buf->om_data[7], mic_len); +} + +static void create_app_nonce(u8_t nonce[13], bool dev_key, u8_t aszmic, + u16_t src, u16_t dst, u32_t seq_num, + u32_t iv_index) +{ + if (dev_key) { + nonce[0] = 0x02; + } else { + nonce[0] = 0x01; + } + + sys_put_be32((seq_num | ((u32_t)aszmic << 31)), &nonce[1]); + + sys_put_be16(src, &nonce[5]); + sys_put_be16(dst, &nonce[7]); + + sys_put_be32(iv_index, &nonce[9]); +} + +int bt_mesh_app_encrypt(const u8_t key[16], bool dev_key, u8_t aszmic, + struct os_mbuf *buf, const u8_t *ad, + u16_t src, u16_t dst, u32_t seq_num, u32_t iv_index) +{ + u8_t nonce[13]; + int err; + + BT_DBG("AppKey %s", bt_hex(key, 16)); + BT_DBG("dev_key %u src 0x%04x dst 0x%04x", dev_key, src, dst); + BT_DBG("seq_num 0x%08x iv_index 0x%08x", (unsigned) seq_num, + (unsigned) iv_index); + BT_DBG("Clear: %s", bt_hex(buf->om_data, buf->om_len)); + + create_app_nonce(nonce, dev_key, aszmic, src, dst, seq_num, iv_index); + + BT_DBG("Nonce %s", bt_hex(nonce, 13)); + + err = bt_mesh_ccm_encrypt(key, nonce, buf->om_data, buf->om_len, ad, + ad ? 16 : 0, buf->om_data, APP_MIC_LEN(aszmic)); + if (!err) { + net_buf_simple_add(buf, APP_MIC_LEN(aszmic)); + BT_DBG("Encr: %s", bt_hex(buf->om_data, buf->om_len)); + } + + return err; +} + +int bt_mesh_app_decrypt(const u8_t key[16], bool dev_key, u8_t aszmic, + struct os_mbuf *buf, struct os_mbuf *out, + const u8_t *ad, u16_t src, u16_t dst, u32_t seq_num, + u32_t iv_index) +{ + u8_t nonce[13]; + int err; + + BT_DBG("EncData (len %u) %s", buf->om_len, bt_hex(buf->om_data, buf->om_len)); + + create_app_nonce(nonce, dev_key, aszmic, src, dst, seq_num, iv_index); + + BT_DBG("AppKey %s", bt_hex(key, 16)); + BT_DBG("Nonce %s", bt_hex(nonce, 13)); + + err = bt_mesh_ccm_decrypt(key, nonce, buf->om_data, buf->om_len, ad, + ad ? 16 : 0, out->om_data, APP_MIC_LEN(aszmic)); + if (!err) { + net_buf_simple_add(out, buf->om_len); + } + + return err; +} + +/* reversed, 8-bit, poly=0x07 */ +static const u8_t crc_table[256] = { + 0x00, 0x91, 0xe3, 0x72, 0x07, 0x96, 0xe4, 0x75, + 0x0e, 0x9f, 0xed, 0x7c, 0x09, 0x98, 0xea, 0x7b, + 0x1c, 0x8d, 0xff, 0x6e, 0x1b, 0x8a, 0xf8, 0x69, + 0x12, 0x83, 0xf1, 0x60, 0x15, 0x84, 0xf6, 0x67, + + 0x38, 0xa9, 0xdb, 0x4a, 0x3f, 0xae, 0xdc, 0x4d, + 0x36, 0xa7, 0xd5, 0x44, 0x31, 0xa0, 0xd2, 0x43, + 0x24, 0xb5, 0xc7, 0x56, 0x23, 0xb2, 0xc0, 0x51, + 0x2a, 0xbb, 0xc9, 0x58, 0x2d, 0xbc, 0xce, 0x5f, + + 0x70, 0xe1, 0x93, 0x02, 0x77, 0xe6, 0x94, 0x05, + 0x7e, 0xef, 0x9d, 0x0c, 0x79, 0xe8, 0x9a, 0x0b, + 0x6c, 0xfd, 0x8f, 0x1e, 0x6b, 0xfa, 0x88, 0x19, + 0x62, 0xf3, 0x81, 0x10, 0x65, 0xf4, 0x86, 0x17, + + 0x48, 0xd9, 0xab, 0x3a, 0x4f, 0xde, 0xac, 0x3d, + 0x46, 0xd7, 0xa5, 0x34, 0x41, 0xd0, 0xa2, 0x33, + 0x54, 0xc5, 0xb7, 0x26, 0x53, 0xc2, 0xb0, 0x21, + 0x5a, 0xcb, 0xb9, 0x28, 0x5d, 0xcc, 0xbe, 0x2f, + + 0xe0, 0x71, 0x03, 0x92, 0xe7, 0x76, 0x04, 0x95, + 0xee, 0x7f, 0x0d, 0x9c, 0xe9, 0x78, 0x0a, 0x9b, + 0xfc, 0x6d, 0x1f, 0x8e, 0xfb, 0x6a, 0x18, 0x89, + 0xf2, 0x63, 0x11, 0x80, 0xf5, 0x64, 0x16, 0x87, + + 0xd8, 0x49, 0x3b, 0xaa, 0xdf, 0x4e, 0x3c, 0xad, + 0xd6, 0x47, 0x35, 0xa4, 0xd1, 0x40, 0x32, 0xa3, + 0xc4, 0x55, 0x27, 0xb6, 0xc3, 0x52, 0x20, 0xb1, + 0xca, 0x5b, 0x29, 0xb8, 0xcd, 0x5c, 0x2e, 0xbf, + + 0x90, 0x01, 0x73, 0xe2, 0x97, 0x06, 0x74, 0xe5, + 0x9e, 0x0f, 0x7d, 0xec, 0x99, 0x08, 0x7a, 0xeb, + 0x8c, 0x1d, 0x6f, 0xfe, 0x8b, 0x1a, 0x68, 0xf9, + 0x82, 0x13, 0x61, 0xf0, 0x85, 0x14, 0x66, 0xf7, + + 0xa8, 0x39, 0x4b, 0xda, 0xaf, 0x3e, 0x4c, 0xdd, + 0xa6, 0x37, 0x45, 0xd4, 0xa1, 0x30, 0x42, 0xd3, + 0xb4, 0x25, 0x57, 0xc6, 0xb3, 0x22, 0x50, 0xc1, + 0xba, 0x2b, 0x59, 0xc8, 0xbd, 0x2c, 0x5e, 0xcf +}; + +u8_t bt_mesh_fcs_calc(const u8_t *data, u8_t data_len) +{ + u8_t fcs = 0xff; + + while (data_len--) { + fcs = crc_table[fcs ^ *data++]; + } + + BT_DBG("fcs 0x%02x", 0xff - fcs); + + return 0xff - fcs; +} + +bool bt_mesh_fcs_check(struct os_mbuf *buf, u8_t received_fcs) +{ + const u8_t *data = buf->om_data; + u16_t data_len = buf->om_len; + u8_t fcs = 0xff; + + while (data_len--) { + fcs = crc_table[fcs ^ *data++]; + } + + return crc_table[fcs ^ received_fcs] == 0xcf; +} + +int bt_mesh_virtual_addr(const u8_t virtual_label[16], u16_t *addr) +{ + u8_t salt[16]; + u8_t tmp[16]; + int err; + + err = bt_mesh_s1("vtad", salt); + if (err) { + return err; + } + + err = bt_mesh_aes_cmac_one(salt, virtual_label, 16, tmp); + if (err) { + return err; + } + + *addr = (sys_get_be16(&tmp[14]) & 0x3fff) | 0x8000; + + return 0; +} + +int bt_mesh_prov_conf_salt(const u8_t conf_inputs[145], u8_t salt[16]) +{ + const u8_t conf_salt_key[16] = { 0 }; + + return bt_mesh_aes_cmac_one(conf_salt_key, conf_inputs, 145, salt); +} + +int bt_mesh_prov_conf_key(const u8_t dhkey[32], const u8_t conf_salt[16], + u8_t conf_key[16]) +{ + return bt_mesh_k1(dhkey, 32, conf_salt, "prck", conf_key); +} + +int bt_mesh_prov_conf(const u8_t conf_key[16], const u8_t rand[16], + const u8_t auth[16], u8_t conf[16]) +{ + struct bt_mesh_sg sg[] = { { rand, 16 }, { auth, 16 } }; + + BT_DBG("ConfirmationKey %s", bt_hex(conf_key, 16)); + BT_DBG("RandomDevice %s", bt_hex(rand, 16)); + BT_DBG("AuthValue %s", bt_hex(auth, 16)); + + return bt_mesh_aes_cmac(conf_key, sg, ARRAY_SIZE(sg), conf); +} + +int bt_mesh_prov_decrypt(const u8_t key[16], u8_t nonce[13], + const u8_t data[25 + 8], u8_t out[25]) +{ + return bt_mesh_ccm_decrypt(key, nonce, data, 25, NULL, 0, out, 8); +} + +int bt_mesh_beacon_auth(const u8_t beacon_key[16], u8_t flags, + const u8_t net_id[8], u32_t iv_index, + u8_t auth[8]) +{ + u8_t msg[13], tmp[16]; + int err; + + BT_DBG("BeaconKey %s", bt_hex(beacon_key, 16)); + BT_DBG("NetId %s", bt_hex(net_id, 8)); + BT_DBG("IV Index 0x%08x", (unsigned) iv_index); + + msg[0] = flags; + memcpy(&msg[1], net_id, 8); + sys_put_be32(iv_index, &msg[9]); + + BT_DBG("BeaconMsg %s", bt_hex(msg, sizeof(msg))); + + err = bt_mesh_aes_cmac_one(beacon_key, msg, sizeof(msg), tmp); + if (!err) { + memcpy(auth, tmp, 8); + } + + return err; +} diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/crypto.h b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/crypto.h new file mode 100644 index 000000000..a56e6b9e8 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/crypto.h @@ -0,0 +1,160 @@ +/* Bluetooth Mesh */ + +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef __CRYPTO_H__ +#define __CRYPTO_H__ + +#include "mesh/mesh.h" + +struct bt_mesh_sg { + const void *data; + size_t len; +}; + +int bt_mesh_aes_cmac(const u8_t key[16], struct bt_mesh_sg *sg, + size_t sg_len, u8_t mac[16]); + +static inline int bt_mesh_aes_cmac_one(const u8_t key[16], const void *m, + size_t len, u8_t mac[16]) +{ + struct bt_mesh_sg sg = { m, len }; + + return bt_mesh_aes_cmac(key, &sg, 1, mac); +} + +static inline bool bt_mesh_s1(const char *m, u8_t salt[16]) +{ + const u8_t zero[16] = { 0 }; + + return bt_mesh_aes_cmac_one(zero, m, strlen(m), salt); +} + +int bt_mesh_k1(const u8_t *ikm, size_t ikm_len, const u8_t salt[16], + const char *info, u8_t okm[16]); + +#define bt_mesh_k1_str(ikm, ikm_len, salt_str, info, okm) \ +({ \ + const u8_t salt[16] = salt_str; \ + bt_mesh_k1(ikm, ikm_len, salt, info, okm); \ +}) + +int bt_mesh_k2(const u8_t n[16], const u8_t *p, size_t p_len, + u8_t net_id[1], u8_t enc_key[16], u8_t priv_key[16]); + +int bt_mesh_k3(const u8_t n[16], u8_t out[8]); + +int bt_mesh_k4(const u8_t n[16], u8_t out[1]); + +int bt_mesh_id128(const u8_t n[16], const char *s, u8_t out[16]); + +static inline int bt_mesh_id_resolving_key(const u8_t net_key[16], + u8_t resolving_key[16]) +{ + return bt_mesh_k1_str(net_key, 16, "smbt", "smbi", resolving_key); +} + +static inline int bt_mesh_identity_key(const u8_t net_key[16], + u8_t identity_key[16]) +{ + return bt_mesh_id128(net_key, "nkik", identity_key); +} + +static inline int bt_mesh_beacon_key(const u8_t net_key[16], + u8_t beacon_key[16]) +{ + return bt_mesh_id128(net_key, "nkbk", beacon_key); +} + +int bt_mesh_beacon_auth(const u8_t beacon_key[16], u8_t flags, + const u8_t net_id[16], u32_t iv_index, + u8_t auth[8]); + +static inline int bt_mesh_app_id(const u8_t app_key[16], u8_t app_id[1]) +{ + return bt_mesh_k4(app_key, app_id); +} + +static inline int bt_mesh_session_key(const u8_t dhkey[32], + const u8_t prov_salt[16], + u8_t session_key[16]) +{ + return bt_mesh_k1(dhkey, 32, prov_salt, "prsk", session_key); +} + +static inline int bt_mesh_prov_nonce(const u8_t dhkey[32], + const u8_t prov_salt[16], + u8_t nonce[13]) +{ + u8_t tmp[16]; + int err; + + err = bt_mesh_k1(dhkey, 32, prov_salt, "prsn", tmp); + if (!err) { + memcpy(nonce, tmp + 3, 13); + } + + return err; +} + +static inline int bt_mesh_dev_key(const u8_t dhkey[32], + const u8_t prov_salt[16], + u8_t dev_key[16]) +{ + return bt_mesh_k1(dhkey, 32, prov_salt, "prdk", dev_key); +} + +static inline int bt_mesh_prov_salt(const u8_t conf_salt[16], + const u8_t prov_rand[16], + const u8_t dev_rand[16], + u8_t prov_salt[16]) +{ + const u8_t prov_salt_key[16] = { 0 }; + struct bt_mesh_sg sg[] = { + { conf_salt, 16 }, + { prov_rand, 16 }, + { dev_rand, 16 }, + }; + + return bt_mesh_aes_cmac(prov_salt_key, sg, ARRAY_SIZE(sg), prov_salt); +} + +int bt_mesh_net_obfuscate(u8_t *pdu, u32_t iv_index, + const u8_t privacy_key[16]); + +int bt_mesh_net_encrypt(const u8_t key[16], struct os_mbuf *buf, + u32_t iv_index, bool proxy); + +int bt_mesh_net_decrypt(const u8_t key[16], struct os_mbuf *buf, + u32_t iv_index, bool proxy); + +int bt_mesh_app_encrypt(const u8_t key[16], bool dev_key, u8_t aszmic, + struct os_mbuf*buf, const u8_t *ad, + u16_t src, u16_t dst, u32_t seq_num, u32_t iv_index); + +int bt_mesh_app_decrypt(const u8_t key[16], bool dev_key, u8_t aszmic, + struct os_mbuf*buf, struct os_mbuf*out, + const u8_t *ad, u16_t src, u16_t dst, u32_t seq_num, + u32_t iv_index); + +u8_t bt_mesh_fcs_calc(const u8_t *data, u8_t data_len); + +bool bt_mesh_fcs_check(struct os_mbuf *buf, u8_t received_fcs); + +int bt_mesh_virtual_addr(const u8_t virtual_label[16], u16_t *addr); + +int bt_mesh_prov_conf_salt(const u8_t conf_inputs[145], u8_t salt[16]); + +int bt_mesh_prov_conf_key(const u8_t dhkey[32], const u8_t conf_salt[16], + u8_t conf_key[16]); + +int bt_mesh_prov_conf(const u8_t conf_key[16], const u8_t rand[16], + const u8_t auth[16], u8_t conf[16]); + +int bt_mesh_prov_decrypt(const u8_t key[16], u8_t nonce[13], + const u8_t data[25 + 8], u8_t out[25]); + +#endif diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/foundation.h b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/foundation.h new file mode 100644 index 000000000..2c257ee38 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/foundation.h @@ -0,0 +1,164 @@ +/* Bluetooth Mesh */ + +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __FUNDATION_H__ +#define __FUNDATION_H__ + +#define OP_APP_KEY_ADD BT_MESH_MODEL_OP_1(0x00) +#define OP_APP_KEY_UPDATE BT_MESH_MODEL_OP_1(0x01) +#define OP_DEV_COMP_DATA_STATUS BT_MESH_MODEL_OP_1(0x02) +#define OP_MOD_PUB_SET BT_MESH_MODEL_OP_1(0x03) +#define OP_HEALTH_CURRENT_STATUS BT_MESH_MODEL_OP_1(0x04) +#define OP_HEALTH_FAULT_STATUS BT_MESH_MODEL_OP_1(0x05) +#define OP_HEARTBEAT_PUB_STATUS BT_MESH_MODEL_OP_1(0x06) +#define OP_APP_KEY_DEL BT_MESH_MODEL_OP_2(0x80, 0x00) +#define OP_APP_KEY_GET BT_MESH_MODEL_OP_2(0x80, 0x01) +#define OP_APP_KEY_LIST BT_MESH_MODEL_OP_2(0x80, 0x02) +#define OP_APP_KEY_STATUS BT_MESH_MODEL_OP_2(0x80, 0x03) +#define OP_ATTENTION_GET BT_MESH_MODEL_OP_2(0x80, 0x04) +#define OP_ATTENTION_SET BT_MESH_MODEL_OP_2(0x80, 0x05) +#define OP_ATTENTION_SET_UNREL BT_MESH_MODEL_OP_2(0x80, 0x06) +#define OP_ATTENTION_STATUS BT_MESH_MODEL_OP_2(0x80, 0x07) +#define OP_DEV_COMP_DATA_GET BT_MESH_MODEL_OP_2(0x80, 0x08) +#define OP_BEACON_GET BT_MESH_MODEL_OP_2(0x80, 0x09) +#define OP_BEACON_SET BT_MESH_MODEL_OP_2(0x80, 0x0a) +#define OP_BEACON_STATUS BT_MESH_MODEL_OP_2(0x80, 0x0b) +#define OP_DEFAULT_TTL_GET BT_MESH_MODEL_OP_2(0x80, 0x0c) +#define OP_DEFAULT_TTL_SET BT_MESH_MODEL_OP_2(0x80, 0x0d) +#define OP_DEFAULT_TTL_STATUS BT_MESH_MODEL_OP_2(0x80, 0x0e) +#define OP_FRIEND_GET BT_MESH_MODEL_OP_2(0x80, 0x0f) +#define OP_FRIEND_SET BT_MESH_MODEL_OP_2(0x80, 0x10) +#define OP_FRIEND_STATUS BT_MESH_MODEL_OP_2(0x80, 0x11) +#define OP_GATT_PROXY_GET BT_MESH_MODEL_OP_2(0x80, 0x12) +#define OP_GATT_PROXY_SET BT_MESH_MODEL_OP_2(0x80, 0x13) +#define OP_GATT_PROXY_STATUS BT_MESH_MODEL_OP_2(0x80, 0x14) +#define OP_KRP_GET BT_MESH_MODEL_OP_2(0x80, 0x15) +#define OP_KRP_SET BT_MESH_MODEL_OP_2(0x80, 0x16) +#define OP_KRP_STATUS BT_MESH_MODEL_OP_2(0x80, 0x17) +#define OP_MOD_PUB_GET BT_MESH_MODEL_OP_2(0x80, 0x18) +#define OP_MOD_PUB_STATUS BT_MESH_MODEL_OP_2(0x80, 0x19) +#define OP_MOD_PUB_VA_SET BT_MESH_MODEL_OP_2(0x80, 0x1a) +#define OP_MOD_SUB_ADD BT_MESH_MODEL_OP_2(0x80, 0x1b) +#define OP_MOD_SUB_DEL BT_MESH_MODEL_OP_2(0x80, 0x1c) +#define OP_MOD_SUB_DEL_ALL BT_MESH_MODEL_OP_2(0x80, 0x1d) +#define OP_MOD_SUB_OVERWRITE BT_MESH_MODEL_OP_2(0x80, 0x1e) +#define OP_MOD_SUB_STATUS BT_MESH_MODEL_OP_2(0x80, 0x1f) +#define OP_MOD_SUB_VA_ADD BT_MESH_MODEL_OP_2(0x80, 0x20) +#define OP_MOD_SUB_VA_DEL BT_MESH_MODEL_OP_2(0x80, 0x21) +#define OP_MOD_SUB_VA_OVERWRITE BT_MESH_MODEL_OP_2(0x80, 0x22) +#define OP_NET_TRANSMIT_GET BT_MESH_MODEL_OP_2(0x80, 0x23) +#define OP_NET_TRANSMIT_SET BT_MESH_MODEL_OP_2(0x80, 0x24) +#define OP_NET_TRANSMIT_STATUS BT_MESH_MODEL_OP_2(0x80, 0x25) +#define OP_RELAY_GET BT_MESH_MODEL_OP_2(0x80, 0x26) +#define OP_RELAY_SET BT_MESH_MODEL_OP_2(0x80, 0x27) +#define OP_RELAY_STATUS BT_MESH_MODEL_OP_2(0x80, 0x28) +#define OP_MOD_SUB_GET BT_MESH_MODEL_OP_2(0x80, 0x29) +#define OP_MOD_SUB_LIST BT_MESH_MODEL_OP_2(0x80, 0x2a) +#define OP_MOD_SUB_GET_VND BT_MESH_MODEL_OP_2(0x80, 0x2b) +#define OP_MOD_SUB_LIST_VND BT_MESH_MODEL_OP_2(0x80, 0x2c) +#define OP_LPN_TIMEOUT_GET BT_MESH_MODEL_OP_2(0x80, 0x2d) +#define OP_LPN_TIMEOUT_STATUS BT_MESH_MODEL_OP_2(0x80, 0x2e) +#define OP_HEALTH_FAULT_CLEAR BT_MESH_MODEL_OP_2(0x80, 0x2f) +#define OP_HEALTH_FAULT_CLEAR_UNREL BT_MESH_MODEL_OP_2(0x80, 0x30) +#define OP_HEALTH_FAULT_GET BT_MESH_MODEL_OP_2(0x80, 0x31) +#define OP_HEALTH_FAULT_TEST BT_MESH_MODEL_OP_2(0x80, 0x32) +#define OP_HEALTH_FAULT_TEST_UNREL BT_MESH_MODEL_OP_2(0x80, 0x33) +#define OP_HEALTH_PERIOD_GET BT_MESH_MODEL_OP_2(0x80, 0x34) +#define OP_HEALTH_PERIOD_SET BT_MESH_MODEL_OP_2(0x80, 0x35) +#define OP_HEALTH_PERIOD_SET_UNREL BT_MESH_MODEL_OP_2(0x80, 0x36) +#define OP_HEALTH_PERIOD_STATUS BT_MESH_MODEL_OP_2(0x80, 0x37) +#define OP_HEARTBEAT_PUB_GET BT_MESH_MODEL_OP_2(0x80, 0x38) +#define OP_HEARTBEAT_PUB_SET BT_MESH_MODEL_OP_2(0x80, 0x39) +#define OP_HEARTBEAT_SUB_GET BT_MESH_MODEL_OP_2(0x80, 0x3a) +#define OP_HEARTBEAT_SUB_SET BT_MESH_MODEL_OP_2(0x80, 0x3b) +#define OP_HEARTBEAT_SUB_STATUS BT_MESH_MODEL_OP_2(0x80, 0x3c) +#define OP_MOD_APP_BIND BT_MESH_MODEL_OP_2(0x80, 0x3d) +#define OP_MOD_APP_STATUS BT_MESH_MODEL_OP_2(0x80, 0x3e) +#define OP_MOD_APP_UNBIND BT_MESH_MODEL_OP_2(0x80, 0x3f) +#define OP_NET_KEY_ADD BT_MESH_MODEL_OP_2(0x80, 0x40) +#define OP_NET_KEY_DEL BT_MESH_MODEL_OP_2(0x80, 0x41) +#define OP_NET_KEY_GET BT_MESH_MODEL_OP_2(0x80, 0x42) +#define OP_NET_KEY_LIST BT_MESH_MODEL_OP_2(0x80, 0x43) +#define OP_NET_KEY_STATUS BT_MESH_MODEL_OP_2(0x80, 0x44) +#define OP_NET_KEY_UPDATE BT_MESH_MODEL_OP_2(0x80, 0x45) +#define OP_NODE_IDENTITY_GET BT_MESH_MODEL_OP_2(0x80, 0x46) +#define OP_NODE_IDENTITY_SET BT_MESH_MODEL_OP_2(0x80, 0x47) +#define OP_NODE_IDENTITY_STATUS BT_MESH_MODEL_OP_2(0x80, 0x48) +#define OP_NODE_RESET BT_MESH_MODEL_OP_2(0x80, 0x49) +#define OP_NODE_RESET_STATUS BT_MESH_MODEL_OP_2(0x80, 0x4a) +#define OP_SIG_MOD_APP_GET BT_MESH_MODEL_OP_2(0x80, 0x4b) +#define OP_SIG_MOD_APP_LIST BT_MESH_MODEL_OP_2(0x80, 0x4c) +#define OP_VND_MOD_APP_GET BT_MESH_MODEL_OP_2(0x80, 0x4d) +#define OP_VND_MOD_APP_LIST BT_MESH_MODEL_OP_2(0x80, 0x4e) + +#define STATUS_SUCCESS 0x00 +#define STATUS_INVALID_ADDRESS 0x01 +#define STATUS_INVALID_MODEL 0x02 +#define STATUS_INVALID_APPKEY 0x03 +#define STATUS_INVALID_NETKEY 0x04 +#define STATUS_INSUFF_RESOURCES 0x05 +#define STATUS_IDX_ALREADY_STORED 0x06 +#define STATUS_NVAL_PUB_PARAM 0x07 +#define STATUS_NOT_SUB_MOD 0x08 +#define STATUS_STORAGE_FAIL 0x09 +#define STATUS_FEAT_NOT_SUPP 0x0a +#define STATUS_CANNOT_UPDATE 0x0b +#define STATUS_CANNOT_REMOVE 0x0c +#define STATUS_CANNOT_BIND 0x0d +#define STATUS_TEMP_STATE_CHG_FAIL 0x0e +#define STATUS_CANNOT_SET 0x0f +#define STATUS_UNSPECIFIED 0x10 +#define STATUS_INVALID_BINDING 0x11 + +int bt_mesh_cfg_srv_init(struct bt_mesh_model *model, bool primary); +int bt_mesh_health_srv_init(struct bt_mesh_model *model, bool primary); + +int bt_mesh_cfg_cli_init(struct bt_mesh_model *model, bool primary); +int bt_mesh_health_cli_init(struct bt_mesh_model *model, bool primary); + +void bt_mesh_cfg_reset(void); + +void bt_mesh_heartbeat(u16_t src, u16_t dst, u8_t hops, u16_t feat); + +void bt_mesh_attention(struct bt_mesh_model *model, u8_t time); + +u8_t *bt_mesh_label_uuid_get(u16_t addr); + +struct bt_mesh_hb_pub *bt_mesh_hb_pub_get(void); +void bt_mesh_hb_pub_disable(void); +struct bt_mesh_cfg_srv *bt_mesh_cfg_get(void); + +u8_t bt_mesh_net_transmit_get(void); +u8_t bt_mesh_relay_get(void); +u8_t bt_mesh_friend_get(void); +u8_t bt_mesh_relay_retransmit_get(void); +u8_t bt_mesh_beacon_get(void); +u8_t bt_mesh_gatt_proxy_get(void); +u8_t bt_mesh_default_ttl_get(void); + +void bt_mesh_subnet_del(struct bt_mesh_subnet *sub, bool store); + +struct bt_mesh_app_key *bt_mesh_app_key_alloc(u16_t app_idx); +void bt_mesh_app_key_del(struct bt_mesh_app_key *key, bool store); + +static inline void key_idx_pack(struct os_mbuf *buf, + u16_t idx1, u16_t idx2) +{ + net_buf_simple_add_le16(buf, idx1 | ((idx2 & 0x00f) << 12)); + net_buf_simple_add_u8(buf, idx2 >> 4); +} + +static inline void key_idx_unpack(struct os_mbuf *buf, + u16_t *idx1, u16_t *idx2) +{ + *idx1 = sys_get_le16(&buf->om_data[0]) & 0xfff; + *idx2 = sys_get_le16(&buf->om_data[1]) >> 4; + net_buf_simple_pull(buf, 3); +} + +#endif diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/friend.c b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/friend.c new file mode 100644 index 000000000..a9f25f777 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/friend.c @@ -0,0 +1,1350 @@ +/* Bluetooth Mesh */ + +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + + +#include "syscfg/syscfg.h" +#if MYNEWT_VAL(BLE_MESH_FRIEND) + +#include +#include +#include + +#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG_FRIEND)) +#include "host/ble_hs_log.h" + +#include "mesh/mesh.h" +#include "mesh/slist.h" +#include "mesh_priv.h" +#include "crypto.h" +#include "adv.h" +#include "net.h" +#include "transport.h" +#include "access.h" +#include "foundation.h" +#include "friend.h" + +/* We reserve one extra buffer for each friendship, since we need to be able + * to resend the last sent PDU, which sits separately outside of the queue. + */ +#define FRIEND_BUF_COUNT ((MYNEWT_VAL(BLE_MESH_FRIEND_QUEUE_SIZE) + 1) * MYNEWT_VAL(BLE_MESH_FRIEND_LPN_COUNT)) + +static os_membuf_t friend_buf_mem[OS_MEMPOOL_SIZE( + FRIEND_BUF_COUNT, + BT_MESH_ADV_DATA_SIZE + BT_MESH_MBUF_HEADER_SIZE)]; + +struct os_mbuf_pool friend_os_mbuf_pool; +static struct os_mempool friend_buf_mempool; + + +#define FRIEND_ADV(buf) CONTAINER_OF(BT_MESH_ADV(buf), \ + struct friend_adv, adv) + +/* PDUs from Friend to the LPN should only be transmitted once with the + * smallest possible interval (20ms). + */ +#define FRIEND_XMIT BT_MESH_TRANSMIT(0, 20) + +struct friend_pdu_info { + u16_t src; + u16_t dst; + + u8_t seq[3]; + + u8_t ttl:7, + ctl:1; + + u32_t iv_index; +}; + +static struct friend_adv { + struct bt_mesh_adv adv; + u64_t seq_auth; +} adv_pool[FRIEND_BUF_COUNT]; + +static struct bt_mesh_adv *adv_alloc(int id) +{ + return &adv_pool[id].adv; +} + +static void discard_buffer(void) +{ + struct bt_mesh_friend *frnd = &bt_mesh.frnd[0]; + struct os_mbuf *buf; + int i; + + /* Find the Friend context with the most queued buffers */ + for (i = 1; i < ARRAY_SIZE(bt_mesh.frnd); i++) { + if (bt_mesh.frnd[i].queue_size > frnd->queue_size) { + frnd = &bt_mesh.frnd[i]; + } + } + + buf = net_buf_slist_get(&frnd->queue); + __ASSERT_NO_MSG(buf != NULL); + BT_WARN("Discarding buffer %p for LPN 0x%04x", buf, frnd->lpn); + net_buf_unref(buf); +} + +static struct os_mbuf *friend_buf_alloc(u16_t src) +{ + struct os_mbuf *buf; + + do { + buf = bt_mesh_adv_create_from_pool(&friend_os_mbuf_pool, adv_alloc, + BT_MESH_ADV_DATA, + FRIEND_XMIT, K_NO_WAIT); + if (!buf) { + discard_buffer(); + } + } while (!buf); + + BT_MESH_ADV(buf)->addr = src; + FRIEND_ADV(buf)->seq_auth = TRANS_SEQ_AUTH_NVAL; + + BT_DBG("allocated buf %p", buf); + + return buf; +} + +static bool is_lpn_unicast(struct bt_mesh_friend *frnd, u16_t addr) +{ + if (frnd->lpn == BT_MESH_ADDR_UNASSIGNED) { + return false; + } + + return (addr >= frnd->lpn && addr < (frnd->lpn + frnd->num_elem)); +} + +struct bt_mesh_friend *bt_mesh_friend_find(u16_t net_idx, u16_t lpn_addr, + bool valid, bool established) +{ + int i; + + BT_DBG("net_idx 0x%04x lpn_addr 0x%04x", net_idx, lpn_addr); + + for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) { + struct bt_mesh_friend *frnd = &bt_mesh.frnd[i]; + + if (valid && !frnd->valid) { + continue; + } + + if (established && !frnd->established) { + continue; + } + + if (net_idx != BT_MESH_KEY_ANY && frnd->net_idx != net_idx) { + continue; + } + + if (is_lpn_unicast(frnd, lpn_addr)) { + return frnd; + } + } + + return NULL; +} + +/* Intentionally start a little bit late into the ReceiveWindow when + * it's large enough. This may improve reliability with some platforms, + * like the PTS, where the receiver might not have sufficiently compensated + * for internal latencies required to start scanning. + */ +static s32_t recv_delay(struct bt_mesh_friend *frnd) +{ +#if CONFIG_BT_MESH_FRIEND_RECV_WIN > 50 + return (s32_t)frnd->recv_delay + (CONFIG_BT_MESH_FRIEND_RECV_WIN / 5); +#else + return frnd->recv_delay; +#endif +} + +static void friend_clear(struct bt_mesh_friend *frnd) +{ + int i; + + BT_DBG("LPN 0x%04x", frnd->lpn); + + k_delayed_work_cancel(&frnd->timer); + + friend_cred_del(frnd->net_idx, frnd->lpn); + + if (frnd->last) { + /* Cancel the sending if necessary */ + if (frnd->pending_buf) { + BT_MESH_ADV(frnd->last)->busy = 0; + } + + net_buf_unref(frnd->last); + frnd->last = NULL; + } + + while (!net_buf_slist_is_empty(&frnd->queue)) { + net_buf_unref(net_buf_slist_get(&frnd->queue)); + } + + for (i = 0; i < ARRAY_SIZE(frnd->seg); i++) { + struct bt_mesh_friend_seg *seg = &frnd->seg[i]; + + while (!net_buf_slist_is_empty(&seg->queue)) { + net_buf_unref(net_buf_slist_get(&seg->queue)); + } + } + + frnd->valid = 0; + frnd->established = 0; + frnd->pending_buf = 0; + frnd->fsn = 0; + frnd->queue_size = 0; + frnd->pending_req = 0; + memset(frnd->sub_list, 0, sizeof(frnd->sub_list)); +} + +void bt_mesh_friend_clear_net_idx(u16_t net_idx) +{ + int i; + + BT_DBG("net_idx 0x%04x", net_idx); + + for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) { + struct bt_mesh_friend *frnd = &bt_mesh.frnd[i]; + + if (frnd->net_idx == BT_MESH_KEY_UNUSED) { + continue; + } + + if (net_idx == BT_MESH_KEY_ANY || frnd->net_idx == net_idx) { + friend_clear(frnd); + } + } +} + +void bt_mesh_friend_sec_update(u16_t net_idx) +{ + int i; + + BT_DBG("net_idx 0x%04x", net_idx); + + for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) { + struct bt_mesh_friend *frnd = &bt_mesh.frnd[i]; + + if (frnd->net_idx == BT_MESH_KEY_UNUSED) { + continue; + } + + if (net_idx == BT_MESH_KEY_ANY || frnd->net_idx == net_idx) { + frnd->sec_update = 1; + } + } +} + +int bt_mesh_friend_clear(struct bt_mesh_net_rx *rx, struct os_mbuf *buf) +{ + struct bt_mesh_ctl_friend_clear *msg = (void *)buf->om_data; + struct bt_mesh_friend *frnd; + u16_t lpn_addr, lpn_counter; + struct bt_mesh_net_tx tx = { + .sub = rx->sub, + .ctx = &rx->ctx, + .src = bt_mesh_primary_addr(), + .xmit = bt_mesh_net_transmit_get(), + }; + struct bt_mesh_ctl_friend_clear_confirm cfm; + + if (buf->om_len < sizeof(*msg)) { + BT_WARN("Too short Friend Clear"); + return -EINVAL; + } + + lpn_addr = sys_be16_to_cpu(msg->lpn_addr); + lpn_counter = sys_be16_to_cpu(msg->lpn_counter); + + BT_DBG("LPN addr 0x%04x counter 0x%04x", lpn_addr, lpn_counter); + + frnd = bt_mesh_friend_find(rx->sub->net_idx, lpn_addr, false, false); + if (!frnd) { + BT_WARN("No matching LPN addr 0x%04x", lpn_addr); + return 0; + } + + /* A Friend Clear message is considered valid if the result of the + * subtraction of the value of the LPNCounter field of the Friend + * Request message (the one that initiated the friendship) from the + * value of the LPNCounter field of the Friend Clear message, modulo + * 65536, is in the range 0 to 255 inclusive. + */ + if (lpn_counter - frnd->lpn_counter > 255) { + BT_WARN("LPN Counter out of range (old %u new %u)", + frnd->lpn_counter, lpn_counter); + return 0; + } + + tx.ctx->send_ttl = BT_MESH_TTL_MAX; + + cfm.lpn_addr = msg->lpn_addr; + cfm.lpn_counter = msg->lpn_counter; + + bt_mesh_ctl_send(&tx, TRANS_CTL_OP_FRIEND_CLEAR_CFM, &cfm, + sizeof(cfm), NULL, NULL, NULL); + + friend_clear(frnd); + + return 0; +} + +static void friend_sub_add(struct bt_mesh_friend *frnd, u16_t addr) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(frnd->sub_list); i++) { + if (frnd->sub_list[i] == BT_MESH_ADDR_UNASSIGNED) { + frnd->sub_list[i] = addr; + return; + } + } + + BT_WARN("No space in friend subscription list"); +} + +static void friend_sub_rem(struct bt_mesh_friend *frnd, u16_t addr) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(frnd->sub_list); i++) { + if (frnd->sub_list[i] == addr) { + frnd->sub_list[i] = BT_MESH_ADDR_UNASSIGNED; + return; + } + } +} + +static struct os_mbuf *create_friend_pdu(struct bt_mesh_friend *frnd, + struct friend_pdu_info *info, + struct os_mbuf *sdu) +{ + struct bt_mesh_subnet *sub; + const u8_t *enc, *priv; + struct os_mbuf *buf; + u8_t nid; + + sub = bt_mesh_subnet_get(frnd->net_idx); + __ASSERT_NO_MSG(sub != NULL); + + buf = friend_buf_alloc(info->src); + + /* Friend Offer needs master security credentials */ + if (info->ctl && TRANS_CTL_OP(sdu->om_data) == TRANS_CTL_OP_FRIEND_OFFER) { + enc = sub->keys[sub->kr_flag].enc; + priv = sub->keys[sub->kr_flag].privacy; + nid = sub->keys[sub->kr_flag].nid; + } else { + if (friend_cred_get(sub, frnd->lpn, &nid, &enc, &priv)) { + BT_ERR("friend_cred_get failed"); + goto failed; + } + } + + net_buf_add_u8(buf, (nid | (info->iv_index & 1) << 7)); + + if (info->ctl) { + net_buf_add_u8(buf, info->ttl | 0x80); + } else { + net_buf_add_u8(buf, info->ttl); + } + + net_buf_add_mem(buf, info->seq, sizeof(info->seq)); + + net_buf_add_be16(buf, info->src); + net_buf_add_be16(buf, info->dst); + + net_buf_add_mem(buf, sdu->om_data, sdu->om_len); + + /* We re-encrypt and obfuscate using the received IVI rather than + * the normal TX IVI (which may be different) since the transport + * layer nonce includes the IVI. + */ + if (bt_mesh_net_encrypt(enc, buf, info->iv_index, false)) { + BT_ERR("Re-encrypting failed"); + goto failed; + } + + if (bt_mesh_net_obfuscate(buf->om_data, info->iv_index, priv)) { + BT_ERR("Re-obfuscating failed"); + goto failed; + } + + return buf; + +failed: + net_buf_unref(buf); + return NULL; +} + +static struct os_mbuf *encode_friend_ctl(struct bt_mesh_friend *frnd, + u8_t ctl_op, + struct os_mbuf *sdu) +{ + struct friend_pdu_info info; + u32_t seq; + + BT_DBG("LPN 0x%04x", frnd->lpn); + + net_buf_simple_push_u8(sdu, TRANS_CTL_HDR(ctl_op, 0)); + + info.src = bt_mesh_primary_addr(); + info.dst = frnd->lpn; + + info.ctl = 1; + info.ttl = 0; + + seq = bt_mesh_next_seq(); + info.seq[0] = seq >> 16; + info.seq[1] = seq >> 8; + info.seq[2] = seq; + + info.iv_index = BT_MESH_NET_IVI_TX; + + return create_friend_pdu(frnd, &info, sdu); +} + +static struct os_mbuf *encode_update(struct bt_mesh_friend *frnd, u8_t md) +{ + struct bt_mesh_ctl_friend_update *upd; + struct os_mbuf *sdu = NET_BUF_SIMPLE(1 + sizeof(*upd)); + struct bt_mesh_subnet *sub = bt_mesh_subnet_get(frnd->net_idx); + struct os_mbuf *buf; + + __ASSERT_NO_MSG(sub != NULL); + + BT_DBG("lpn 0x%04x md 0x%02x", frnd->lpn, md); + + net_buf_simple_init(sdu, 1); + + upd = net_buf_simple_add(sdu, sizeof(*upd)); + upd->flags = bt_mesh_net_flags(sub); + upd->iv_index = sys_cpu_to_be32(bt_mesh.iv_index); + upd->md = md; + + buf = encode_friend_ctl(frnd, TRANS_CTL_OP_FRIEND_UPDATE, sdu); + + os_mbuf_free_chain(sdu); + return buf; +} + +static void enqueue_sub_cfm(struct bt_mesh_friend *frnd, u8_t xact) +{ + struct bt_mesh_ctl_friend_sub_confirm *cfm; + struct os_mbuf *sdu = NET_BUF_SIMPLE(1 + sizeof(*cfm)); + struct os_mbuf *buf; + + BT_DBG("lpn 0x%04x xact 0x%02x", frnd->lpn, xact); + + net_buf_simple_init(sdu, 1); + + cfm = net_buf_simple_add(sdu, sizeof(*cfm)); + cfm->xact = xact; + + buf = encode_friend_ctl(frnd, TRANS_CTL_OP_FRIEND_SUB_CFM, sdu); + if (!buf) { + BT_ERR("Unable to encode Subscription List Confirmation"); + goto done; + } + + if (frnd->last) { + BT_DBG("Discarding last PDU"); + net_buf_unref(frnd->last); + } + + frnd->last = buf; + frnd->send_last = 1; + +done: + os_mbuf_free_chain(sdu); +} + +static void friend_recv_delay(struct bt_mesh_friend *frnd) +{ + frnd->pending_req = 1; + k_delayed_work_submit(&frnd->timer, recv_delay(frnd)); + BT_DBG("Waiting RecvDelay of %d ms", (int) recv_delay(frnd)); +} + +int bt_mesh_friend_sub_add(struct bt_mesh_net_rx *rx, + struct os_mbuf *buf) +{ + struct bt_mesh_friend *frnd; + u8_t xact; + + if (buf->om_len < BT_MESH_FRIEND_SUB_MIN_LEN) { + BT_WARN("Too short Friend Subscription Add"); + return -EINVAL; + } + + frnd = bt_mesh_friend_find(rx->sub->net_idx, rx->ctx.addr, true, true); + if (!frnd) { + BT_WARN("No matching LPN addr 0x%04x", rx->ctx.addr); + return 0; + } + + if (frnd->pending_buf) { + BT_WARN("Previous buffer not yet sent!"); + return 0; + } + + friend_recv_delay(frnd); + + xact = net_buf_simple_pull_u8(buf); + + while (buf->om_len >= 2) { + friend_sub_add(frnd, net_buf_simple_pull_be16(buf)); + } + + enqueue_sub_cfm(frnd, xact); + + return 0; +} + +int bt_mesh_friend_sub_rem(struct bt_mesh_net_rx *rx, + struct os_mbuf *buf) +{ + struct bt_mesh_friend *frnd; + u8_t xact; + + if (buf->om_len < BT_MESH_FRIEND_SUB_MIN_LEN) { + BT_WARN("Too short Friend Subscription Remove"); + return -EINVAL; + } + + frnd = bt_mesh_friend_find(rx->sub->net_idx, rx->ctx.addr, true, true); + if (!frnd) { + BT_WARN("No matching LPN addr 0x%04x", rx->ctx.addr); + return 0; + } + + if (frnd->pending_buf) { + BT_WARN("Previous buffer not yet sent!"); + return 0; + } + + friend_recv_delay(frnd); + + xact = net_buf_simple_pull_u8(buf); + + while (buf->om_len >= 2) { + friend_sub_rem(frnd, net_buf_simple_pull_be16(buf)); + } + + enqueue_sub_cfm(frnd, xact); + + return 0; +} + +static void enqueue_buf(struct bt_mesh_friend *frnd, struct os_mbuf *buf) +{ + net_buf_slist_put(&frnd->queue, buf); + frnd->queue_size++; +} + +static void enqueue_update(struct bt_mesh_friend *frnd, u8_t md) +{ + struct os_mbuf *buf; + + buf = encode_update(frnd, md); + if (!buf) { + BT_ERR("Unable to encode Friend Update"); + return; + } + + frnd->sec_update = 0; + enqueue_buf(frnd, buf); +} + +int bt_mesh_friend_poll(struct bt_mesh_net_rx *rx, struct os_mbuf *buf) +{ + struct bt_mesh_ctl_friend_poll *msg = (void *)buf->om_data; + struct bt_mesh_friend *frnd; + + if (buf->om_len < sizeof(*msg)) { + BT_WARN("Too short Friend Poll"); + return -EINVAL; + } + + frnd = bt_mesh_friend_find(rx->sub->net_idx, rx->ctx.addr, true, false); + if (!frnd) { + BT_WARN("No matching LPN addr 0x%04x", rx->ctx.addr); + return 0; + } + + if (msg->fsn & ~1) { + BT_WARN("Prohibited (non-zero) padding bits"); + return -EINVAL; + } + + if (frnd->pending_buf) { + BT_WARN("Previous buffer not yet sent"); + return 0; + } + + BT_DBG("msg->fsn %u frnd->fsn %u", (msg->fsn & 1), frnd->fsn); + + friend_recv_delay(frnd); + + if (!frnd->established) { + BT_DBG("Friendship established with 0x%04x", frnd->lpn); + frnd->established = 1; + } + + if (msg->fsn == frnd->fsn && frnd->last) { + BT_DBG("Re-sending last PDU"); + frnd->send_last = 1; + } else { + if (frnd->last) { + net_buf_unref(frnd->last); + frnd->last = NULL; + } + + frnd->fsn = msg->fsn; + + if (net_buf_slist_is_empty(&frnd->queue)) { + enqueue_update(frnd, 0); + BT_DBG("Enqueued Friend Update to empty queue"); + } + } + + return 0; +} + +static struct bt_mesh_friend *find_clear(u16_t prev_friend) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) { + struct bt_mesh_friend *frnd = &bt_mesh.frnd[i]; + + if (frnd->clear.frnd == prev_friend) { + return frnd; + } + } + + return NULL; +} + +static void friend_clear_sent(int err, void *user_data) +{ + struct bt_mesh_friend *frnd = user_data; + + k_delayed_work_submit(&frnd->clear.timer, + K_SECONDS(frnd->clear.repeat_sec)); + frnd->clear.repeat_sec *= 2; +} + +static const struct bt_mesh_send_cb clear_sent_cb = { + .end = friend_clear_sent, +}; + +static void send_friend_clear(struct bt_mesh_friend *frnd) +{ + struct bt_mesh_msg_ctx ctx = { + .net_idx = frnd->net_idx, + .app_idx = BT_MESH_KEY_UNUSED, + .addr = frnd->clear.frnd, + .send_ttl = BT_MESH_TTL_MAX, + }; + struct bt_mesh_net_tx tx = { + .sub = &bt_mesh.sub[0], + .ctx = &ctx, + .src = bt_mesh_primary_addr(), + .xmit = bt_mesh_net_transmit_get(), + }; + struct bt_mesh_ctl_friend_clear req = { + .lpn_addr = sys_cpu_to_be16(frnd->lpn), + .lpn_counter = sys_cpu_to_be16(frnd->lpn_counter), + }; + + BT_DBG(""); + + bt_mesh_ctl_send(&tx, TRANS_CTL_OP_FRIEND_CLEAR, &req, + sizeof(req), NULL, &clear_sent_cb, frnd); +} + +static void clear_timeout(struct ble_npl_event *work) +{ + struct bt_mesh_friend *frnd = ble_npl_event_get_arg(work); + u32_t duration; + + BT_DBG("LPN 0x%04x (old) Friend 0x%04x", frnd->lpn, frnd->clear.frnd); + + duration = k_uptime_get_32() - frnd->clear.start; + if (duration > 2 * frnd->poll_to) { + BT_DBG("Clear Procedure timer expired"); + frnd->clear.frnd = BT_MESH_ADDR_UNASSIGNED; + return; + } + + send_friend_clear(frnd); +} + +static void clear_procedure_start(struct bt_mesh_friend *frnd) +{ + BT_DBG("LPN 0x%04x (old) Friend 0x%04x", frnd->lpn, frnd->clear.frnd); + + frnd->clear.start = k_uptime_get_32() + (2 * frnd->poll_to); + frnd->clear.repeat_sec = 1; + + send_friend_clear(frnd); +} + +int bt_mesh_friend_clear_cfm(struct bt_mesh_net_rx *rx, + struct os_mbuf *buf) +{ + struct bt_mesh_ctl_friend_clear_confirm *msg = (void *)buf->om_data; + struct bt_mesh_friend *frnd; + u16_t lpn_addr, lpn_counter; + + BT_DBG(""); + + if (buf->om_len < sizeof(*msg)) { + BT_WARN("Too short Friend Clear Confirm"); + return -EINVAL; + } + + frnd = find_clear(rx->ctx.addr); + if (!frnd) { + BT_WARN("No pending clear procedure for 0x%02x", rx->ctx.addr); + return 0; + } + + lpn_addr = sys_be16_to_cpu(msg->lpn_addr); + if (lpn_addr != frnd->lpn) { + BT_WARN("LPN address mismatch (0x%04x != 0x%04x)", + lpn_addr, frnd->lpn); + return 0; + } + + lpn_counter = sys_be16_to_cpu(msg->lpn_counter); + if (lpn_counter != frnd->lpn_counter) { + BT_WARN("LPN counter mismatch (0x%04x != 0x%04x)", + lpn_counter, frnd->lpn_counter); + return 0; + } + + k_delayed_work_cancel(&frnd->clear.timer); + frnd->clear.frnd = BT_MESH_ADDR_UNASSIGNED; + + return 0; +} + +static void enqueue_offer(struct bt_mesh_friend *frnd, s8_t rssi) +{ + struct bt_mesh_ctl_friend_offer *off; + struct os_mbuf *sdu = NET_BUF_SIMPLE(1 + sizeof(*off)); + struct os_mbuf *buf; + + BT_DBG(""); + + net_buf_simple_init(sdu, 1); + + off = net_buf_simple_add(sdu, sizeof(*off)); + + off->recv_win = CONFIG_BT_MESH_FRIEND_RECV_WIN, + off->queue_size = CONFIG_BT_MESH_FRIEND_QUEUE_SIZE, + off->sub_list_size = ARRAY_SIZE(frnd->sub_list), + off->rssi = rssi, + off->frnd_counter = sys_cpu_to_be16(frnd->counter); + + buf = encode_friend_ctl(frnd, TRANS_CTL_OP_FRIEND_OFFER, sdu); + if (!buf) { + BT_ERR("Unable to encode Friend Offer"); + goto done; + } + + frnd->counter++; + + if (frnd->last) { + net_buf_unref(frnd->last); + } + + frnd->last = buf; + frnd->send_last = 1; + +done: + os_mbuf_free_chain(sdu); +} + +#define RECV_WIN CONFIG_BT_MESH_FRIEND_RECV_WIN +#define RSSI_FACT(crit) (((crit) >> 5) & (u8_t)BIT_MASK(2)) +#define RECV_WIN_FACT(crit) (((crit) >> 3) & (u8_t)BIT_MASK(2)) +#define MIN_QUEUE_SIZE_LOG(crit) ((crit) & (u8_t)BIT_MASK(3)) +#define MIN_QUEUE_SIZE(crit) ((u32_t)BIT(MIN_QUEUE_SIZE_LOG(crit))) + +static s32_t offer_delay(struct bt_mesh_friend *frnd, s8_t rssi, u8_t crit) +{ + /* Scaling factors. The actual values are 1, 1.5, 2 & 2.5, but we + * want to avoid floating-point arithmetic. + */ + static const u8_t fact[] = { 10, 15, 20, 25 }; + s32_t delay; + + BT_DBG("ReceiveWindowFactor %u ReceiveWindow %u RSSIFactor %u RSSI %d", + fact[RECV_WIN_FACT(crit)], RECV_WIN, + fact[RSSI_FACT(crit)], rssi); + + /* Delay = ReceiveWindowFactor * ReceiveWindow - RSSIFactor * RSSI */ + delay = (s32_t)fact[RECV_WIN_FACT(crit)] * RECV_WIN; + delay -= (s32_t)fact[RSSI_FACT(crit)] * rssi; + delay /= 10; + + BT_DBG("Local Delay calculated as %d ms", (int) delay); + + if (delay < 100) { + return K_MSEC(100); + } + + return K_MSEC(delay); +} + +int bt_mesh_friend_req(struct bt_mesh_net_rx *rx, struct os_mbuf *buf) +{ + struct bt_mesh_ctl_friend_req *msg = (void *)buf->om_data; + struct bt_mesh_friend *frnd = NULL; + u32_t poll_to; + int i; + + if (buf->om_len < sizeof(*msg)) { + BT_WARN("Too short Friend Request"); + return -EINVAL; + } + + if (msg->recv_delay <= 0x09) { + BT_WARN("Prohibited ReceiveDelay (0x%02x)", msg->recv_delay); + return -EINVAL; + } + + poll_to = (((u32_t)msg->poll_to[0] << 16) | + ((u32_t)msg->poll_to[1] << 8) | + ((u32_t)msg->poll_to[2])); + + if (poll_to <= 0x000009 || poll_to >= 0x34bc00) { + BT_WARN("Prohibited PollTimeout (0x%06x)", (unsigned) poll_to); + return -EINVAL; + } + + if (msg->num_elem == 0x00) { + BT_WARN("Prohibited NumElements value (0x00)"); + return -EINVAL; + } + + if (!BT_MESH_ADDR_IS_UNICAST(rx->ctx.addr + msg->num_elem - 1)) { + BT_WARN("LPN elements stretch outside of unicast range"); + return -EINVAL; + } + + if (!MIN_QUEUE_SIZE_LOG(msg->criteria)) { + BT_WARN("Prohibited Minimum Queue Size in Friend Request"); + return -EINVAL; + } + + if (CONFIG_BT_MESH_FRIEND_QUEUE_SIZE < MIN_QUEUE_SIZE(msg->criteria)) { + BT_WARN("We have a too small Friend Queue size (%u < %u)", + CONFIG_BT_MESH_FRIEND_QUEUE_SIZE, + (unsigned) MIN_QUEUE_SIZE(msg->criteria)); + return 0; + } + + frnd = bt_mesh_friend_find(rx->sub->net_idx, rx->ctx.addr, true, false); + if (frnd) { + BT_WARN("Existing LPN re-requesting Friendship"); + friend_clear(frnd); + goto init_friend; + } + + for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) { + if (!bt_mesh.frnd[i].valid) { + frnd = &bt_mesh.frnd[i]; + frnd->valid = 1; + break; + } + } + + if (!frnd) { + BT_WARN("No free Friend contexts for new LPN"); + return -ENOMEM; + } + +init_friend: + frnd->lpn = rx->ctx.addr; + frnd->num_elem = msg->num_elem; + frnd->net_idx = rx->sub->net_idx; + frnd->recv_delay = msg->recv_delay; + frnd->poll_to = poll_to * 100; + frnd->lpn_counter = sys_be16_to_cpu(msg->lpn_counter); + frnd->clear.frnd = sys_be16_to_cpu(msg->prev_addr); + + BT_DBG("LPN 0x%04x rssi %d recv_delay %u poll_to %ums", + frnd->lpn, rx->rssi, frnd->recv_delay, + (unsigned) frnd->poll_to); + + if (BT_MESH_ADDR_IS_UNICAST(frnd->clear.frnd) && + !bt_mesh_elem_find(frnd->clear.frnd)) { + clear_procedure_start(frnd); + } + + k_delayed_work_submit(&frnd->timer, + offer_delay(frnd, rx->rssi, msg->criteria)); + + friend_cred_create(rx->sub, frnd->lpn, frnd->lpn_counter, + frnd->counter); + + enqueue_offer(frnd, rx->rssi); + + return 0; +} + +static struct bt_mesh_friend_seg *get_seg(struct bt_mesh_friend *frnd, + u16_t src, u64_t *seq_auth) +{ + struct bt_mesh_friend_seg *unassigned = NULL; + int i; + + for (i = 0; i < ARRAY_SIZE(frnd->seg); i++) { + struct bt_mesh_friend_seg *seg = &frnd->seg[i]; + struct os_mbuf *buf = (void *)net_buf_slist_peek_head(&seg->queue); + + if (buf && BT_MESH_ADV(buf)->addr == src && + FRIEND_ADV(buf)->seq_auth == *seq_auth) { + return seg; + } + + if (!unassigned && !buf) { + unassigned = seg; + } + } + + return unassigned; +} + +static void enqueue_friend_pdu(struct bt_mesh_friend *frnd, + enum bt_mesh_friend_pdu_type type, + struct os_mbuf *buf) +{ + struct bt_mesh_friend_seg *seg; + struct friend_adv *adv; + + BT_DBG("type %u", type); + + if (type == BT_MESH_FRIEND_PDU_SINGLE) { + if (frnd->sec_update) { + enqueue_update(frnd, 1); + } + + enqueue_buf(frnd, buf); + return; + } + + adv = FRIEND_ADV(buf); + seg = get_seg(frnd, BT_MESH_ADV(buf)->addr, &adv->seq_auth); + if (!seg) { + BT_ERR("No free friend segment RX contexts for 0x%04x", + BT_MESH_ADV(buf)->addr); + net_buf_unref(buf); + return; + } + + net_buf_slist_put(&seg->queue, buf); + + if (type == BT_MESH_FRIEND_PDU_COMPLETE) { + if (frnd->sec_update) { + enqueue_update(frnd, 1); + } + + /* Only acks should have a valid SeqAuth in the Friend queue + * (otherwise we can't easily detect them there), so clear + * the SeqAuth information from the segments before merging. + */ + struct os_mbuf *m; + struct os_mbuf_pkthdr *pkthdr; + NET_BUF_SLIST_FOR_EACH_NODE(&seg->queue, pkthdr) { + m = OS_MBUF_PKTHDR_TO_MBUF(pkthdr); + FRIEND_ADV(m)->seq_auth = TRANS_SEQ_AUTH_NVAL; + frnd->queue_size++; + } + + net_buf_slist_merge_slist(&frnd->queue, &seg->queue); + } +} + +static void buf_send_start(u16_t duration, int err, void *user_data) +{ + struct bt_mesh_friend *frnd = user_data; + + BT_DBG("err %d", err); + + frnd->pending_buf = 0; + + /* Friend Offer doesn't follow the re-sending semantics */ + if (!frnd->established) { + net_buf_unref(frnd->last); + frnd->last = NULL; + } +} + +static void buf_send_end(int err, void *user_data) +{ + struct bt_mesh_friend *frnd = user_data; + + BT_DBG("err %d", err); + + if (frnd->pending_req) { + BT_WARN("Another request before previous completed sending"); + return; + } + + if (frnd->established) { + k_delayed_work_submit(&frnd->timer, frnd->poll_to); + BT_DBG("Waiting %u ms for next poll", + (unsigned) frnd->poll_to); + } else { + /* Friend offer timeout is 1 second */ + k_delayed_work_submit(&frnd->timer, K_SECONDS(1)); + BT_DBG("Waiting for first poll"); + } +} + +static void friend_timeout(struct ble_npl_event *work) +{ + struct bt_mesh_friend *frnd = ble_npl_event_get_arg(work); + static const struct bt_mesh_send_cb buf_sent_cb = { + .start = buf_send_start, + .end = buf_send_end, + }; + + __ASSERT_NO_MSG(frnd->pending_buf == 0); + + BT_DBG("lpn 0x%04x send_last %u last %p", frnd->lpn, + frnd->send_last, frnd->last); + + if (frnd->send_last && frnd->last) { + BT_DBG("Sending frnd->last %p", frnd->last); + frnd->send_last = 0; + goto send_last; + } + + if (frnd->established && !frnd->pending_req) { + BT_WARN("Friendship lost with 0x%04x", frnd->lpn); + friend_clear(frnd); + return; + } + + frnd->last = net_buf_slist_get(&frnd->queue); + if (!frnd->last) { + BT_WARN("Friendship not established with 0x%04x", frnd->lpn); + friend_clear(frnd); + return; + } + + BT_DBG("Sending buf %p from Friend Queue of LPN 0x%04x", + frnd->last, frnd->lpn); + frnd->queue_size--; + +send_last: + frnd->pending_req = 0; + frnd->pending_buf = 1; + bt_mesh_adv_send(frnd->last, &buf_sent_cb, frnd); +} + +int bt_mesh_friend_init(void) +{ + int rc; + int i; + + rc = os_mempool_init(&friend_buf_mempool, FRIEND_BUF_COUNT, + BT_MESH_ADV_DATA_SIZE + BT_MESH_MBUF_HEADER_SIZE, + friend_buf_mem, "friend_buf_pool"); + assert(rc == 0); + + rc = os_mbuf_pool_init(&friend_os_mbuf_pool, &friend_buf_mempool, + BT_MESH_ADV_DATA_SIZE + BT_MESH_MBUF_HEADER_SIZE, + FRIEND_BUF_COUNT); + assert(rc == 0); + + for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) { + struct bt_mesh_friend *frnd = &bt_mesh.frnd[i]; + int j; + + frnd->net_idx = BT_MESH_KEY_UNUSED; + + net_buf_slist_init(&frnd->queue); + + k_delayed_work_init(&frnd->timer, friend_timeout); + k_delayed_work_add_arg(&frnd->timer, frnd); + k_delayed_work_init(&frnd->clear.timer, clear_timeout); + k_delayed_work_add_arg(&frnd->clear.timer, frnd); + + for (j = 0; j < ARRAY_SIZE(frnd->seg); j++) { + net_buf_slist_init(&frnd->seg[j].queue); + } + } + + return 0; +} + +static void friend_purge_old_ack(struct bt_mesh_friend *frnd, u64_t *seq_auth, + u16_t src) +{ + struct os_mbuf *cur, *prev = NULL; + + BT_DBG("SeqAuth %llx src 0x%04x", *seq_auth, src); + + for (cur = net_buf_slist_peek_head(&frnd->queue); + cur != NULL; prev = cur, cur = net_buf_slist_peek_next(cur)) { + struct os_mbuf *buf = (void *)cur; + + if (BT_MESH_ADV(buf)->addr == src && + FRIEND_ADV(buf)->seq_auth == *seq_auth) { + BT_DBG("Removing old ack from Friend Queue"); + + net_buf_slist_remove(&frnd->queue, prev, cur); + frnd->queue_size--; + + net_buf_unref(buf); + break; + } + } +} + +static void friend_lpn_enqueue_rx(struct bt_mesh_friend *frnd, + struct bt_mesh_net_rx *rx, + enum bt_mesh_friend_pdu_type type, + u64_t *seq_auth, struct os_mbuf *sbuf) +{ + struct friend_pdu_info info; + struct os_mbuf *buf; + + BT_DBG("LPN 0x%04x queue_size %u", frnd->lpn, + (unsigned) frnd->queue_size); + + if (type == BT_MESH_FRIEND_PDU_SINGLE && seq_auth) { + friend_purge_old_ack(frnd, seq_auth, rx->ctx.addr); + } + + info.src = rx->ctx.addr; + info.dst = rx->ctx.recv_dst; + + if (rx->net_if == BT_MESH_NET_IF_LOCAL) { + info.ttl = rx->ctx.recv_ttl; + } else { + info.ttl = rx->ctx.recv_ttl - 1; + } + + info.ctl = rx->ctl; + + info.seq[0] = (rx->seq >> 16); + info.seq[1] = (rx->seq >> 8); + info.seq[2] = rx->seq; + + info.iv_index = BT_MESH_NET_IVI_RX(rx); + + buf = create_friend_pdu(frnd, &info, sbuf); + if (!buf) { + BT_ERR("Failed to encode Friend buffer"); + return; + } + + if (seq_auth) { + FRIEND_ADV(buf)->seq_auth = *seq_auth; + } + + enqueue_friend_pdu(frnd, type, buf); + + BT_DBG("Queued message for LPN 0x%04x, queue_size %u", + frnd->lpn, (unsigned) frnd->queue_size); +} + +static void friend_lpn_enqueue_tx(struct bt_mesh_friend *frnd, + struct bt_mesh_net_tx *tx, + enum bt_mesh_friend_pdu_type type, + u64_t *seq_auth, struct os_mbuf *sbuf) +{ + struct friend_pdu_info info; + struct os_mbuf *buf; + u32_t seq; + + BT_DBG("LPN 0x%04x", frnd->lpn); + + if (type == BT_MESH_FRIEND_PDU_SINGLE && seq_auth) { + friend_purge_old_ack(frnd, seq_auth, tx->src); + } + + info.src = tx->src; + info.dst = tx->ctx->addr; + + info.ttl = tx->ctx->send_ttl; + info.ctl = (tx->ctx->app_idx == BT_MESH_KEY_UNUSED); + + seq = bt_mesh_next_seq(); + info.seq[0] = seq >> 16; + info.seq[1] = seq >> 8; + info.seq[2] = seq; + + info.iv_index = BT_MESH_NET_IVI_TX; + + buf = create_friend_pdu(frnd, &info, sbuf); + if (!buf) { + BT_ERR("Failed to encode Friend buffer"); + return; + } + + if (seq_auth) { + FRIEND_ADV(buf)->seq_auth = *seq_auth; + } + + enqueue_friend_pdu(frnd, type, buf); + + BT_DBG("Queued message for LPN 0x%04x", frnd->lpn); +} + +static bool friend_lpn_matches(struct bt_mesh_friend *frnd, u16_t net_idx, + u16_t addr) +{ + int i; + + if (!frnd->established) { + return false; + } + + if (net_idx != frnd->net_idx) { + return false; + } + + if (BT_MESH_ADDR_IS_UNICAST(addr)) { + return is_lpn_unicast(frnd, addr); + } + + for (i = 0; i < ARRAY_SIZE(frnd->sub_list); i++) { + if (frnd->sub_list[i] == addr) { + return true; + } + } + + return false; +} + +bool bt_mesh_friend_match(u16_t net_idx, u16_t addr) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) { + struct bt_mesh_friend *frnd = &bt_mesh.frnd[i]; + + if (friend_lpn_matches(frnd, net_idx, addr)) { + BT_DBG("LPN 0x%04x matched address 0x%04x", + frnd->lpn, addr); + return true; + } + } + + BT_DBG("No matching LPN for address 0x%04x", addr); + + return false; +} + +void bt_mesh_friend_enqueue_rx(struct bt_mesh_net_rx *rx, + enum bt_mesh_friend_pdu_type type, + u64_t *seq_auth, struct os_mbuf *sbuf) +{ + int i; + + if (!rx->friend_match || + (rx->ctx.recv_ttl <= 1 && rx->net_if != BT_MESH_NET_IF_LOCAL) || + bt_mesh_friend_get() != BT_MESH_FRIEND_ENABLED) { + return; + } + + BT_DBG("recv_ttl %u net_idx 0x%04x src 0x%04x dst 0x%04x", + rx->ctx.recv_ttl, rx->sub->net_idx, rx->ctx.addr, + rx->ctx.recv_dst); + + for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) { + struct bt_mesh_friend *frnd = &bt_mesh.frnd[i]; + + if (friend_lpn_matches(frnd, rx->sub->net_idx, + rx->ctx.recv_dst)) { + friend_lpn_enqueue_rx(frnd, rx, type, seq_auth, sbuf); + } + } +} + +bool bt_mesh_friend_enqueue_tx(struct bt_mesh_net_tx *tx, + enum bt_mesh_friend_pdu_type type, + u64_t *seq_auth, struct os_mbuf *sbuf) +{ + bool matched = false; + int i; + + if (!bt_mesh_friend_match(tx->sub->net_idx, tx->ctx->addr) || + bt_mesh_friend_get() != BT_MESH_FRIEND_ENABLED) { + return matched; + } + + BT_DBG("net_idx 0x%04x dst 0x%04x src 0x%04x", tx->sub->net_idx, + tx->ctx->addr, tx->src); + + for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) { + struct bt_mesh_friend *frnd = &bt_mesh.frnd[i]; + + if (friend_lpn_matches(frnd, tx->sub->net_idx, tx->ctx->addr)) { + friend_lpn_enqueue_tx(frnd, tx, type, seq_auth, sbuf); + matched = true; + } + } + + return matched; +} + +void bt_mesh_friend_clear_incomplete(struct bt_mesh_subnet *sub, u16_t src, + u16_t dst, u64_t *seq_auth) +{ + int i; + + BT_DBG(""); + + for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) { + struct bt_mesh_friend *frnd = &bt_mesh.frnd[i]; + int j; + + if (!friend_lpn_matches(frnd, sub->net_idx, dst)) { + continue; + } + + for (j = 0; j < ARRAY_SIZE(frnd->seg); j++) { + struct bt_mesh_friend_seg *seg = &frnd->seg[j]; + struct os_mbuf *buf; + + buf = (void *)net_buf_slist_peek_head(&seg->queue); + if (!buf) { + continue; + } + + if (BT_MESH_ADV(buf)->addr != src) { + continue; + } + + if (FRIEND_ADV(buf)->seq_auth != *seq_auth) { + continue; + } + + BT_WARN("Clearing incomplete segments for 0x%04x", src); + + while (!net_buf_slist_is_empty(&seg->queue)) { + net_buf_unref(net_buf_slist_get(&seg->queue)); + } + } + } +} + +#endif /* MYNEWT_VAL(BLE_MESH_FRIEND) */ diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/friend.h b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/friend.h new file mode 100644 index 000000000..053de146c --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/friend.h @@ -0,0 +1,51 @@ +/* Bluetooth Mesh */ + +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __FRIEND_H__ +#define __FRIEND_H__ + +#include "mesh/mesh.h" + +enum bt_mesh_friend_pdu_type { + BT_MESH_FRIEND_PDU_SINGLE, + BT_MESH_FRIEND_PDU_PARTIAL, + BT_MESH_FRIEND_PDU_COMPLETE, +}; + +bool bt_mesh_friend_match(u16_t net_idx, u16_t addr); + +struct bt_mesh_friend *bt_mesh_friend_find(u16_t net_idx, u16_t lpn_addr, + bool valid, bool established); + +void bt_mesh_friend_enqueue_rx(struct bt_mesh_net_rx *rx, + enum bt_mesh_friend_pdu_type type, + u64_t *seq_auth, struct os_mbuf *sbuf); +bool bt_mesh_friend_enqueue_tx(struct bt_mesh_net_tx *tx, + enum bt_mesh_friend_pdu_type type, + u64_t *seq_auth, struct os_mbuf *sbuf); + +void bt_mesh_friend_clear_incomplete(struct bt_mesh_subnet *sub, u16_t src, + u16_t dst, u64_t *seq_auth); + +void bt_mesh_friend_sec_update(u16_t net_idx); + +void bt_mesh_friend_clear_net_idx(u16_t net_idx); + +int bt_mesh_friend_poll(struct bt_mesh_net_rx *rx, struct os_mbuf *buf); +int bt_mesh_friend_req(struct bt_mesh_net_rx *rx, struct os_mbuf *buf); +int bt_mesh_friend_clear(struct bt_mesh_net_rx *rx, struct os_mbuf *buf); +int bt_mesh_friend_clear_cfm(struct bt_mesh_net_rx *rx, + struct os_mbuf *buf); +int bt_mesh_friend_sub_add(struct bt_mesh_net_rx *rx, + struct os_mbuf *buf); +int bt_mesh_friend_sub_rem(struct bt_mesh_net_rx *rx, + struct os_mbuf *buf); + +int bt_mesh_friend_init(void); + +#endif diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/glue.c b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/glue.c new file mode 100644 index 000000000..3b765ee65 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/glue.c @@ -0,0 +1,904 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "mesh/glue.h" +#include "adv.h" +#ifndef MYNEWT +#include "nimble/nimble_port.h" +#endif + +#if MYNEWT_VAL(BLE_MESH_SETTINGS) +#include "base64/base64.h" +#endif + +#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG)) + +#if MYNEWT_VAL(BLE_EXT_ADV) +#define BT_MESH_ADV_INST (MYNEWT_VAL(BLE_MULTI_ADV_INSTANCES)) + +#if MYNEWT_VAL(BLE_MESH_PROXY) +/* Note that BLE_MULTI_ADV_INSTANCES contains number of additional instances. + * Instance 0 is always there + */ +#if MYNEWT_VAL(BLE_MULTI_ADV_INSTANCES) < 1 +#error "Mesh needs at least BLE_MULTI_ADV_INSTANCES set to 1" +#endif +#define BT_MESH_ADV_GATT_INST (MYNEWT_VAL(BLE_MULTI_ADV_INSTANCES) - 1) +#endif /* BLE_MESH_PROXY */ +#endif /* BLE_EXT_ADV */ + +extern u8_t g_mesh_addr_type; + +#if MYNEWT_VAL(BLE_EXT_ADV) +/* Store configuration for different bearers */ +#define BT_MESH_ADV_IDX (0) +#define BT_MESH_GATT_IDX (1) +static struct ble_gap_adv_params ble_adv_cur_conf[2]; +#endif + +const char * +bt_hex(const void *buf, size_t len) +{ + static const char hex[] = "0123456789abcdef"; + static char hexbufs[4][137]; + static u8_t curbuf; + const u8_t *b = buf; + char *str; + int i; + + str = hexbufs[curbuf++]; + curbuf %= ARRAY_SIZE(hexbufs); + + len = min(len, (sizeof(hexbufs[0]) - 1) / 2); + + for (i = 0; i < len; i++) { + str[i * 2] = hex[b[i] >> 4]; + str[i * 2 + 1] = hex[b[i] & 0xf]; + } + + str[i * 2] = '\0'; + + return str; +} + +void +net_buf_put(struct ble_npl_eventq *fifo, struct os_mbuf *om) +{ + struct ble_npl_event *ev; + + assert(OS_MBUF_IS_PKTHDR(om)); + ev = &BT_MESH_ADV(om)->ev; + assert(ev); + assert(ble_npl_event_get_arg(ev)); + + ble_npl_eventq_put(fifo, ev); +} + +void * +net_buf_ref(struct os_mbuf *om) +{ + struct bt_mesh_adv *adv; + + /* For bufs with header we count refs*/ + if (OS_MBUF_USRHDR_LEN(om) == 0) { + return om; + } + + adv = BT_MESH_ADV(om); + adv->ref_cnt++; + + return om; +} + +void +net_buf_unref(struct os_mbuf *om) +{ + struct bt_mesh_adv *adv; + + /* For bufs with header we count refs*/ + if (OS_MBUF_USRHDR_LEN(om) == 0) { + goto free; + } + + adv = BT_MESH_ADV(om); + if (--adv->ref_cnt > 0) { + return; + } + +free: + os_mbuf_free_chain(om); +} + +#if MYNEWT_VAL(BLE_CRYPTO_STACK_MBEDTLS) +int +bt_encrypt_be(const uint8_t *key, const uint8_t *plaintext, uint8_t *enc_data) +{ + mbedtls_aes_context s = {0}; + mbedtls_aes_init(&s); + + if (mbedtls_aes_setkey_enc(&s, key, 128) != 0) { + return BLE_HS_EUNKNOWN; + } + + if (mbedtls_aes_crypt_ecb(&s, MBEDTLS_AES_ENCRYPT, plaintext, enc_data) != 0) { + return BLE_HS_EUNKNOWN; + } + + return 0; +} + +#else +int +bt_encrypt_be(const uint8_t *key, const uint8_t *plaintext, uint8_t *enc_data) +{ + struct tc_aes_key_sched_struct s = {0}; + + if (tc_aes128_set_encrypt_key(&s, key) == TC_CRYPTO_FAIL) { + return BLE_HS_EUNKNOWN; + } + + if (tc_aes_encrypt(enc_data, plaintext, &s) == TC_CRYPTO_FAIL) { + return BLE_HS_EUNKNOWN; + } + + return 0; +} +#endif + +uint16_t +net_buf_simple_pull_le16(struct os_mbuf *om) +{ + uint16_t val; + struct os_mbuf *old = om; + + om = os_mbuf_pullup(om, sizeof(val)); + assert(om == old); + val = get_le16(om->om_data); + os_mbuf_adj(om, sizeof(val)); + + return val; +} + +uint16_t +net_buf_simple_pull_be16(struct os_mbuf *om) +{ + uint16_t val; + struct os_mbuf *old = om; + + om = os_mbuf_pullup(om, sizeof(val)); + assert(om == old); + val = get_be16(om->om_data); + os_mbuf_adj(om, sizeof(val)); + + return val; +} + +uint32_t +net_buf_simple_pull_be32(struct os_mbuf *om) +{ + uint32_t val; + struct os_mbuf *old = om; + + om = os_mbuf_pullup(om, sizeof(val)); + assert(om == old); + val = get_be32(om->om_data); + os_mbuf_adj(om, sizeof(val)); + + return val; +} + +uint32_t +net_buf_simple_pull_le32(struct os_mbuf *om) +{ + uint32_t val; + struct os_mbuf *old = om; + + om = os_mbuf_pullup(om, sizeof(val)); + assert(om == old); + val = get_le32(om->om_data); + os_mbuf_adj(om, sizeof(val)); + + return val; +} + +uint8_t +net_buf_simple_pull_u8(struct os_mbuf *om) +{ + uint8_t val; + struct os_mbuf *old = om; + + om = os_mbuf_pullup(om, sizeof(val)); + assert(om == old); + val = om->om_data[0]; + os_mbuf_adj(om, 1); + + return val; +} + +void +net_buf_simple_add_le16(struct os_mbuf *om, uint16_t val) +{ + val = htole16(val); + os_mbuf_append(om, &val, sizeof(val)); + ASSERT_NOT_CHAIN(om); +} + +void +net_buf_simple_add_be16(struct os_mbuf *om, uint16_t val) +{ + val = htobe16(val); + os_mbuf_append(om, &val, sizeof(val)); + ASSERT_NOT_CHAIN(om); +} + +void +net_buf_simple_add_be32(struct os_mbuf *om, uint32_t val) +{ + val = htobe32(val); + os_mbuf_append(om, &val, sizeof(val)); + ASSERT_NOT_CHAIN(om); +} + +void +net_buf_simple_add_le32(struct os_mbuf *om, uint32_t val) +{ + val = htole32(val); + os_mbuf_append(om, &val, sizeof(val)); + ASSERT_NOT_CHAIN(om); +} + +void +net_buf_simple_add_u8(struct os_mbuf *om, uint8_t val) +{ + os_mbuf_append(om, &val, 1); + ASSERT_NOT_CHAIN(om); +} + +void +net_buf_simple_push_le16(struct os_mbuf *om, uint16_t val) +{ + uint8_t headroom = om->om_data - &om->om_databuf[om->om_pkthdr_len]; + + assert(headroom >= 2); + om->om_data -= 2; + put_le16(om->om_data, val); + om->om_len += 2; + + if (om->om_pkthdr_len) { + OS_MBUF_PKTHDR(om)->omp_len += 2; + } + ASSERT_NOT_CHAIN(om); +} + +void +net_buf_simple_push_be16(struct os_mbuf *om, uint16_t val) +{ + uint8_t headroom = om->om_data - &om->om_databuf[om->om_pkthdr_len]; + + assert(headroom >= 2); + om->om_data -= 2; + put_be16(om->om_data, val); + om->om_len += 2; + + if (om->om_pkthdr_len) { + OS_MBUF_PKTHDR(om)->omp_len += 2; + } + ASSERT_NOT_CHAIN(om); +} + +void +net_buf_simple_push_u8(struct os_mbuf *om, uint8_t val) +{ + uint8_t headroom = om->om_data - &om->om_databuf[om->om_pkthdr_len]; + + assert(headroom >= 1); + om->om_data -= 1; + om->om_data[0] = val; + om->om_len += 1; + + if (om->om_pkthdr_len) { + OS_MBUF_PKTHDR(om)->omp_len += 1; + } + ASSERT_NOT_CHAIN(om); +} + +void +net_buf_add_zeros(struct os_mbuf *om, uint8_t len) +{ + uint8_t z[len]; + int rc; + + memset(z, 0, len); + + rc = os_mbuf_append(om, z, len); + if(rc) { + assert(0); + } + ASSERT_NOT_CHAIN(om); +} + +void * +net_buf_simple_pull(struct os_mbuf *om, uint8_t len) +{ + os_mbuf_adj(om, len); + return om->om_data; +} + +void * +net_buf_simple_pull_mem(struct os_mbuf *om, uint8_t len) +{ + void *data = om->om_data; + + net_buf_simple_pull(om, len); + return data; +} + +void* +net_buf_simple_add(struct os_mbuf *om, uint8_t len) +{ + void * tmp; + + tmp = os_mbuf_extend(om, len); + ASSERT_NOT_CHAIN(om); + + return tmp; +} + +bool +k_fifo_is_empty(struct ble_npl_eventq *q) +{ + return ble_npl_eventq_is_empty(q); +} + +void * net_buf_get(struct ble_npl_eventq *fifo, s32_t t) +{ + struct ble_npl_event *ev = ble_npl_eventq_get(fifo, 0); + + if (ev) { + return ble_npl_event_get_arg(ev); + } + + return NULL; +} + +uint8_t * +net_buf_simple_push(struct os_mbuf *om, uint8_t len) +{ + uint8_t headroom = om->om_data - &om->om_databuf[om->om_pkthdr_len]; + + assert(headroom >= len); + om->om_data -= len; + om->om_len += len; + + return om->om_data; +} + +void +net_buf_reserve(struct os_mbuf *om, size_t reserve) +{ + /* We need reserve to be done on fresh buf */ + assert(om->om_len == 0); + om->om_data += reserve; +} + +void +k_work_init(struct ble_npl_callout *work, ble_npl_event_fn handler) +{ +#ifndef MYNEWT + ble_npl_callout_init(work, nimble_port_get_dflt_eventq(), handler, NULL); +#else + ble_npl_callout_init(work, ble_npl_eventq_dflt_get(), handler, NULL); +#endif +} + +void +k_delayed_work_init(struct k_delayed_work *w, ble_npl_event_fn *f) +{ +#ifndef MYNEWT + ble_npl_callout_init(&w->work, nimble_port_get_dflt_eventq(), f, NULL); +#else + ble_npl_callout_init(&w->work, ble_npl_eventq_dflt_get(), f, NULL); +#endif +} + +void +k_delayed_work_cancel(struct k_delayed_work *w) +{ + ble_npl_callout_stop(&w->work); +} + +void +k_delayed_work_submit(struct k_delayed_work *w, uint32_t ms) +{ + uint32_t ticks; + + if (ble_npl_time_ms_to_ticks(ms, &ticks) != 0) { + assert(0); + } + ble_npl_callout_reset(&w->work, ticks); +} + +void +k_work_submit(struct ble_npl_callout *w) +{ + ble_npl_callout_reset(w, 0); +} + +void +k_work_add_arg(struct ble_npl_callout *w, void *arg) +{ + ble_npl_callout_set_arg(w, arg); +} + +void +k_delayed_work_add_arg(struct k_delayed_work *w, void *arg) +{ + k_work_add_arg(&w->work, arg); +} + +uint32_t +k_delayed_work_remaining_get (struct k_delayed_work *w) +{ + int sr; + ble_npl_time_t t; + + OS_ENTER_CRITICAL(sr); + + t = ble_npl_callout_remaining_ticks(&w->work, ble_npl_time_get()); + + OS_EXIT_CRITICAL(sr); + + return ble_npl_time_ticks_to_ms32(t); +} + +int64_t k_uptime_get(void) +{ + /* We should return ms */ + return ble_npl_time_ticks_to_ms32(ble_npl_time_get()); +} + +u32_t k_uptime_get_32(void) +{ + return k_uptime_get(); +} + +void k_sleep(int32_t duration) +{ + uint32_t ticks; + + ticks = ble_npl_time_ms_to_ticks32(duration); + + ble_npl_time_delay(ticks); +} + +static uint8_t pub[64]; +static uint8_t priv[32]; +static bool has_pub = false; + +int +bt_dh_key_gen(const u8_t remote_pk[64], bt_dh_key_cb_t cb) +{ + uint8_t dh[32]; + + if (ble_sm_alg_gen_dhkey((uint8_t *)&remote_pk[0], (uint8_t *)&remote_pk[32], + priv, dh)) { + return -1; + } + + cb(dh); + return 0; +} + +int +bt_rand(void *buf, size_t len) +{ + int rc; + rc = ble_hs_hci_util_rand(buf, len); + if (rc != 0) { + return -1; + } + + return 0; +} + +int +bt_pub_key_gen(struct bt_pub_key_cb *new_cb) +{ + + if (ble_sm_alg_gen_key_pair(pub, priv)) { + assert(0); + return -1; + } + + new_cb->func(pub); + has_pub = true; + + return 0; +} + +uint8_t * +bt_pub_key_get(void) +{ + if (!has_pub) { + return NULL; + } + + return pub; +} + +static int +set_ad(const struct bt_data *ad, size_t ad_len, u8_t *buf, u8_t *buf_len) +{ + int i; + + for (i = 0; i < ad_len; i++) { + buf[(*buf_len)++] = ad[i].data_len + 1; + buf[(*buf_len)++] = ad[i].type; + + memcpy(&buf[*buf_len], ad[i].data, + ad[i].data_len); + *buf_len += ad[i].data_len; + } + + return 0; +} + +#if MYNEWT_VAL(BLE_EXT_ADV) +static void +ble_adv_copy_to_ext_param(struct ble_gap_ext_adv_params *ext_param, + const struct ble_gap_adv_params *param) +{ + memset(ext_param, 0, sizeof(*ext_param)); + + ext_param->legacy_pdu = 1; + + if (param->conn_mode != BLE_GAP_CONN_MODE_NON) { + ext_param->connectable = 1; + ext_param->scannable = 1; + } + + ext_param->itvl_max = param->itvl_max; + ext_param->itvl_min = param->itvl_min; + ext_param->channel_map = param->channel_map; + ext_param->high_duty_directed = param->high_duty_cycle; + ext_param->own_addr_type = g_mesh_addr_type; +} + +static int +ble_adv_conf_adv_instance(const struct ble_gap_adv_params *param, int *instance) +{ + struct ble_gap_ext_adv_params ext_params; + struct ble_gap_adv_params *cur_conf; + int err = 0; + + if (param->conn_mode == BLE_GAP_CONN_MODE_NON) { + *instance = BT_MESH_ADV_INST; + cur_conf = &ble_adv_cur_conf[BT_MESH_ADV_IDX]; + } else { +#if MYNEWT_VAL(BLE_MESH_PROXY) + *instance = BT_MESH_ADV_GATT_INST; + cur_conf = &ble_adv_cur_conf[BT_MESH_GATT_IDX]; +#else + assert(0); +#endif + } + + /* Checking interval max as it has to be in place if instance was configured + * before. + */ + if (cur_conf->itvl_max == 0) { + goto configure; + } + + if (memcmp(param, cur_conf, sizeof(*cur_conf)) == 0) { + /* Same parameters - skip reconfiguring */ + goto done; + } + + ble_gap_ext_adv_stop(*instance); + err = ble_gap_ext_adv_remove(*instance); + if (err) { + assert(0); + goto done; + } + +configure: + ble_adv_copy_to_ext_param(&ext_params, param); + + err = ble_gap_ext_adv_configure(*instance, &ext_params, 0, + ble_adv_gap_mesh_cb, NULL); + if (!err) { + memcpy(cur_conf, param, sizeof(*cur_conf)); + } + +done: + return err; +} + +int +bt_le_adv_start(const struct ble_gap_adv_params *param, + const struct bt_data *ad, size_t ad_len, + const struct bt_data *sd, size_t sd_len) +{ + struct os_mbuf *data; + int instance; + int err; + uint8_t buf[BLE_HS_ADV_MAX_SZ]; + uint8_t buf_len = 0; + + err = ble_adv_conf_adv_instance(param, &instance); + if (err) { + return err; + } + + if (ad_len > 0) { + err = set_ad(ad, ad_len, buf, &buf_len); + if (err) { + return err; + } + + /* For now let's use msys pool. We are not putting more then legacy */ + data = os_msys_get_pkthdr(BLE_HS_ADV_MAX_SZ, 0); + if (!data) { + return OS_ENOMEM; + } + + err = os_mbuf_append(data, buf, buf_len); + if (err) { + goto error; + } + + err = ble_gap_ext_adv_set_data(instance, data); + if (err) { + return err; + } + + data = NULL; + } + + if (sd_len > 0) { + buf_len = 0; + + err = set_ad(sd, sd_len, buf, &buf_len); + if (err) { + return err; + } + + /* For now let's use msys pool. We are not putting more then legace*/ + data = os_msys_get_pkthdr(BLE_HS_ADV_MAX_SZ, 0); + if (!data) { + return OS_ENOMEM; + } + + err = os_mbuf_append(data, buf, buf_len); + if (err) { + goto error; + } + + err = ble_gap_ext_adv_rsp_set_data(instance, data); + if (err) { + goto error; + } + } + + /*TODO: We could use duration and max events in the future */ + err = ble_gap_ext_adv_start(instance, 0, 0); + return err; + +error: + if (data) { + os_mbuf_free_chain(data); + } + + return err; +} + +int bt_le_adv_stop(bool proxy) +{ +#if MYNEWT_VAL(BLE_MESH_PROXY) + int rc; + + if (proxy) { + rc = ble_gap_ext_adv_stop(BT_MESH_ADV_GATT_INST); + } else { + rc = ble_gap_ext_adv_stop(BT_MESH_ADV_INST); + } + + return rc; +#else + return ble_gap_ext_adv_stop(BT_MESH_ADV_INST); +#endif +} + +#else + +int +bt_le_adv_start(const struct ble_gap_adv_params *param, + const struct bt_data *ad, size_t ad_len, + const struct bt_data *sd, size_t sd_len) +{ + uint8_t buf[BLE_HS_ADV_MAX_SZ]; + uint8_t buf_len = 0; + int err; + + err = set_ad(ad, ad_len, buf, &buf_len); + if (err) { + return err; + } + + err = ble_gap_adv_set_data(buf, buf_len); + if (err != 0) { + return err; + } + + if (sd) { + buf_len = 0; + + err = set_ad(sd, sd_len, buf, &buf_len); + if (err) { + BT_ERR("Advertising failed: err %d", err); + return err; + } + + err = ble_gap_adv_rsp_set_data(buf, buf_len); + if (err != 0) { + BT_ERR("Advertising failed: err %d", err); + return err; + } + } + + err = ble_gap_adv_start(g_mesh_addr_type, NULL, BLE_HS_FOREVER, param, + NULL, NULL); + if (err) { + BT_ERR("Advertising failed: err %d", err); + return err; + } + + return 0; +} + +int bt_le_adv_stop(bool proxy) +{ + return ble_gap_adv_stop(); +} + +#endif + +#if MYNEWT_VAL(BLE_MESH_PROXY) +int bt_mesh_proxy_svcs_register(void); +#endif + +void +bt_mesh_register_gatt(void) +{ +#if MYNEWT_VAL(BLE_MESH_PROXY) + bt_mesh_proxy_svcs_register(); +#endif +} + +void net_buf_slist_init(struct net_buf_slist_t *list) +{ + STAILQ_INIT(list); +} + +bool net_buf_slist_is_empty(struct net_buf_slist_t *list) +{ + return STAILQ_EMPTY(list); +} + +struct os_mbuf *net_buf_slist_peek_head(struct net_buf_slist_t *list) +{ + struct os_mbuf_pkthdr *pkthdr; + + /* Get mbuf pointer from packet header pointer */ + pkthdr = STAILQ_FIRST(list); + if (!pkthdr) { + return NULL; + } + + return OS_MBUF_PKTHDR_TO_MBUF(pkthdr); +} + +struct os_mbuf *net_buf_slist_peek_next(struct os_mbuf *buf) +{ + struct os_mbuf_pkthdr *pkthdr; + + /* Get mbuf pointer from packet header pointer */ + pkthdr = OS_MBUF_PKTHDR(buf); + pkthdr = STAILQ_NEXT(pkthdr, omp_next); + if (!pkthdr) { + return NULL; + } + + return OS_MBUF_PKTHDR_TO_MBUF(pkthdr); +} + +struct os_mbuf *net_buf_slist_get(struct net_buf_slist_t *list) +{ + os_sr_t sr; + struct os_mbuf *m; + + m = net_buf_slist_peek_head(list); + if (!m) { + return NULL; + } + + /* Remove from queue */ + OS_ENTER_CRITICAL(sr); + STAILQ_REMOVE_HEAD(list, omp_next); + OS_EXIT_CRITICAL(sr); + return m; +} + +void net_buf_slist_put(struct net_buf_slist_t *list, struct os_mbuf *buf) +{ + struct os_mbuf_pkthdr *pkthdr; + + pkthdr = OS_MBUF_PKTHDR(buf); + STAILQ_INSERT_TAIL(list, pkthdr, omp_next); +} + +void net_buf_slist_remove(struct net_buf_slist_t *list, struct os_mbuf *prev, + struct os_mbuf *cur) +{ + struct os_mbuf_pkthdr *pkthdr, *cur_pkthdr; + + cur_pkthdr = OS_MBUF_PKTHDR(cur); + + STAILQ_FOREACH(pkthdr, list, omp_next) { + if (cur_pkthdr == pkthdr) { + STAILQ_REMOVE(list, cur_pkthdr, os_mbuf_pkthdr, omp_next); + break; + } + } +} + +void net_buf_slist_merge_slist(struct net_buf_slist_t *list, + struct net_buf_slist_t *list_to_append) +{ + struct os_mbuf_pkthdr *pkthdr; + + STAILQ_FOREACH(pkthdr, list_to_append, omp_next) { + STAILQ_INSERT_TAIL(list, pkthdr, omp_next); + } + + STAILQ_INIT(list); +} + +#if MYNEWT_VAL(BLE_MESH_SETTINGS) + +int settings_bytes_from_str(char *val_str, void *vp, int *len) +{ + *len = base64_decode(val_str, vp); + return 0; +} + +char *settings_str_from_bytes(void *vp, int vp_len, char *buf, int buf_len) +{ + if (BASE64_ENCODE_SIZE(vp_len) > buf_len) { + return NULL; + } + + base64_encode(vp, vp_len, buf, 1); + + return buf; +} + +#endif /* MYNEWT_VAL(BLE_MESH_SETTINGS) */ + diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/health_cli.c b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/health_cli.c new file mode 100644 index 000000000..68543415c --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/health_cli.c @@ -0,0 +1,553 @@ +/* Bluetooth Mesh */ + +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include "syscfg/syscfg.h" +#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG_MODEL)) +#include "host/ble_hs_log.h" + +#include "mesh/mesh.h" +#include "mesh_priv.h" +#include "adv.h" +#include "net.h" +#include "transport.h" +#include "foundation.h" +#include "mesh/health_cli.h" + +static s32_t msg_timeout = K_SECONDS(5); + +static struct bt_mesh_health_cli *health_cli; + +struct health_fault_param { + u16_t cid; + u8_t *expect_test_id; + u8_t *test_id; + u8_t *faults; + size_t *fault_count; +}; + +static void health_fault_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct health_fault_param *param; + u8_t test_id; + u16_t cid; + + BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); + + if (health_cli->op_pending != OP_HEALTH_FAULT_STATUS) { + BT_WARN("Unexpected Health Fault Status message"); + return; + } + + param = health_cli->op_param; + + test_id = net_buf_simple_pull_u8(buf); + if (param->expect_test_id && test_id != *param->expect_test_id) { + BT_WARN("Health fault with unexpected Test ID"); + return; + } + + cid = net_buf_simple_pull_le16(buf); + if (cid != param->cid) { + BT_WARN("Health fault with unexpected Company ID"); + return; + } + + if (param->test_id) { + *param->test_id = test_id; + } + + if (buf->om_len > *param->fault_count) { + BT_WARN("Got more faults than there's space for"); + } else { + *param->fault_count = buf->om_len; + } + + memcpy(param->faults, buf->om_data, *param->fault_count); + + k_sem_give(&health_cli->op_sync); +} + +static void health_current_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct bt_mesh_health_cli *cli = model->user_data; + u8_t test_id; + u16_t cid; + + BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); + + test_id = net_buf_simple_pull_u8(buf); + cid = net_buf_simple_pull_le16(buf); + + BT_DBG("Test ID 0x%02x Company ID 0x%04x Fault Count %u", + test_id, cid, buf->om_len); + + if (!cli->current_status) { + BT_WARN("No Current Status callback available"); + return; + } + + cli->current_status(cli, ctx->addr, test_id, cid, buf->om_data, buf->om_len); +} + +struct health_period_param { + u8_t *divisor; +}; + +static void health_period_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct health_period_param *param; + + BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); + + if (health_cli->op_pending != OP_HEALTH_PERIOD_STATUS) { + BT_WARN("Unexpected Health Period Status message"); + return; + } + + param = health_cli->op_param; + + *param->divisor = net_buf_simple_pull_u8(buf); + + k_sem_give(&health_cli->op_sync); +} + +struct health_attention_param { + u8_t *attention; +}; + +static void health_attention_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct health_attention_param *param; + + BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); + + if (health_cli->op_pending != OP_ATTENTION_STATUS) { + BT_WARN("Unexpected Health Attention Status message"); + return; + } + + param = health_cli->op_param; + + if (param->attention) { + *param->attention = net_buf_simple_pull_u8(buf); + } + + k_sem_give(&health_cli->op_sync); +} + +const struct bt_mesh_model_op bt_mesh_health_cli_op[] = { + { OP_HEALTH_FAULT_STATUS, 3, health_fault_status }, + { OP_HEALTH_CURRENT_STATUS, 3, health_current_status }, + { OP_HEALTH_PERIOD_STATUS, 1, health_period_status }, + { OP_ATTENTION_STATUS, 1, health_attention_status }, + BT_MESH_MODEL_OP_END, +}; + +static int cli_prepare(void *param, u32_t op) +{ + if (!health_cli) { + BT_ERR("No available Health Client context!"); + return -EINVAL; + } + + if (health_cli->op_pending) { + BT_WARN("Another synchronous operation pending"); + return -EBUSY; + } + + health_cli->op_param = param; + health_cli->op_pending = op; + + return 0; +} + +static void cli_reset(void) +{ + health_cli->op_pending = 0; + health_cli->op_param = NULL; +} + +static int cli_wait(void) +{ + int err; + + err = k_sem_take(&health_cli->op_sync, msg_timeout); + + cli_reset(); + + return err; +} + +int bt_mesh_health_attention_get(u16_t net_idx, u16_t addr, u16_t app_idx, + u8_t *attention) +{ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 0 + 4); + struct bt_mesh_msg_ctx ctx = { + .net_idx = net_idx, + .app_idx = app_idx, + .addr = addr, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; + struct health_attention_param param = { + .attention = attention, + }; + int err; + + err = cli_prepare(¶m, OP_ATTENTION_STATUS); + if (err) { + goto done; + } + + bt_mesh_model_msg_init(msg, OP_ATTENTION_GET); + + err = bt_mesh_model_send(health_cli->model, &ctx, msg, NULL, NULL); + if (err) { + BT_ERR("model_send() failed (err %d)", err); + cli_reset(); + goto done; + } + + err = cli_wait(); +done: + os_mbuf_free_chain(msg); + return err; +} + +int bt_mesh_health_attention_set(u16_t net_idx, u16_t addr, u16_t app_idx, + u8_t attention, u8_t *updated_attention) +{ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4); + struct bt_mesh_msg_ctx ctx = { + .net_idx = net_idx, + .app_idx = app_idx, + .addr = addr, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; + struct health_attention_param param = { + .attention = updated_attention, + }; + int err; + + err = cli_prepare(¶m, OP_ATTENTION_STATUS); + if (err) { + goto done; + } + + if (updated_attention) { + bt_mesh_model_msg_init(msg, OP_ATTENTION_SET); + } else { + bt_mesh_model_msg_init(msg, OP_ATTENTION_SET_UNREL); + } + + net_buf_simple_add_u8(msg, attention); + + err = bt_mesh_model_send(health_cli->model, &ctx, msg, NULL, NULL); + if (err) { + BT_ERR("model_send() failed (err %d)", err); + cli_reset(); + goto done; + } + + if (!updated_attention) { + cli_reset(); + goto done; + } + + err = cli_wait(); +done: + os_mbuf_free_chain(msg); + return err; +} + +int bt_mesh_health_period_get(u16_t net_idx, u16_t addr, u16_t app_idx, + u8_t *divisor) +{ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 0 + 4); + struct bt_mesh_msg_ctx ctx = { + .net_idx = net_idx, + .app_idx = app_idx, + .addr = addr, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; + struct health_period_param param = { + .divisor = divisor, + }; + int err; + + err = cli_prepare(¶m, OP_HEALTH_PERIOD_STATUS); + if (err) { + goto done; + } + + bt_mesh_model_msg_init(msg, OP_HEALTH_PERIOD_GET); + + err = bt_mesh_model_send(health_cli->model, &ctx, msg, NULL, NULL); + if (err) { + BT_ERR("model_send() failed (err %d)", err); + cli_reset(); + goto done; + } + + err = cli_wait(); +done: + os_mbuf_free_chain(msg); + return err; +} + +int bt_mesh_health_period_set(u16_t net_idx, u16_t addr, u16_t app_idx, + u8_t divisor, u8_t *updated_divisor) +{ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4); + struct bt_mesh_msg_ctx ctx = { + .net_idx = net_idx, + .app_idx = app_idx, + .addr = addr, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; + struct health_period_param param = { + .divisor = updated_divisor, + }; + int err; + + err = cli_prepare(¶m, OP_HEALTH_PERIOD_STATUS); + if (err) { + goto done; + } + + if (updated_divisor) { + bt_mesh_model_msg_init(msg, OP_HEALTH_PERIOD_SET); + } else { + bt_mesh_model_msg_init(msg, OP_HEALTH_PERIOD_SET_UNREL); + } + + net_buf_simple_add_u8(msg, divisor); + + err = bt_mesh_model_send(health_cli->model, &ctx, msg, NULL, NULL); + if (err) { + BT_ERR("model_send() failed (err %d)", err); + cli_reset(); + goto done; + } + + if (!updated_divisor) { + cli_reset(); + goto done; + } + + err = cli_wait(); +done: + os_mbuf_free_chain(msg); + return err; +} + +int bt_mesh_health_fault_test(u16_t net_idx, u16_t addr, u16_t app_idx, + u16_t cid, u8_t test_id, u8_t *faults, + size_t *fault_count) +{ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 3 + 4); + struct bt_mesh_msg_ctx ctx = { + .net_idx = net_idx, + .app_idx = app_idx, + .addr = addr, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; + struct health_fault_param param = { + .cid = cid, + .expect_test_id = &test_id, + .faults = faults, + .fault_count = fault_count, + }; + int err; + + err = cli_prepare(¶m, OP_HEALTH_FAULT_STATUS); + if (err) { + goto done; + } + + if (faults) { + bt_mesh_model_msg_init(msg, OP_HEALTH_FAULT_TEST); + } else { + bt_mesh_model_msg_init(msg, OP_HEALTH_FAULT_TEST_UNREL); + } + + net_buf_simple_add_u8(msg, test_id); + net_buf_simple_add_le16(msg, cid); + + err = bt_mesh_model_send(health_cli->model, &ctx, msg, NULL, NULL); + if (err) { + BT_ERR("model_send() failed (err %d)", err); + cli_reset(); + goto done; + } + + if (!faults) { + cli_reset(); + goto done; + } + + err = cli_wait(); +done: + os_mbuf_free_chain(msg); + return err; +} + +int bt_mesh_health_fault_clear(u16_t net_idx, u16_t addr, u16_t app_idx, + u16_t cid, u8_t *test_id, u8_t *faults, + size_t *fault_count) +{ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 2 + 4); + struct bt_mesh_msg_ctx ctx = { + .net_idx = net_idx, + .app_idx = app_idx, + .addr = addr, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; + struct health_fault_param param = { + .cid = cid, + .test_id = test_id, + .faults = faults, + .fault_count = fault_count, + }; + int err; + + err = cli_prepare(¶m, OP_HEALTH_FAULT_STATUS); + if (err) { + goto done; + } + + if (test_id) { + bt_mesh_model_msg_init(msg, OP_HEALTH_FAULT_CLEAR); + } else { + bt_mesh_model_msg_init(msg, OP_HEALTH_FAULT_CLEAR_UNREL); + } + + net_buf_simple_add_le16(msg, cid); + + err = bt_mesh_model_send(health_cli->model, &ctx, msg, NULL, NULL); + if (err) { + BT_ERR("model_send() failed (err %d)", err); + cli_reset(); + goto done; + } + + if (!test_id) { + cli_reset(); + goto done; + } + + err = cli_wait(); +done: + os_mbuf_free_chain(msg); + return err; +} + +int bt_mesh_health_fault_get(u16_t net_idx, u16_t addr, u16_t app_idx, + u16_t cid, u8_t *test_id, u8_t *faults, + size_t *fault_count) +{ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 2 + 4); + struct bt_mesh_msg_ctx ctx = { + .net_idx = net_idx, + .app_idx = app_idx, + .addr = addr, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; + struct health_fault_param param = { + .cid = cid, + .test_id = test_id, + .faults = faults, + .fault_count = fault_count, + }; + int err; + + err = cli_prepare(¶m, OP_HEALTH_FAULT_STATUS); + if (err) { + goto done; + } + + bt_mesh_model_msg_init(msg, OP_HEALTH_FAULT_GET); + net_buf_simple_add_le16(msg, cid); + + err = bt_mesh_model_send(health_cli->model, &ctx, msg, NULL, NULL); + if (err) { + BT_ERR("model_send() failed (err %d)", err); + cli_reset(); + goto done; + } + + err = cli_wait(); +done: + os_mbuf_free_chain(msg); + return err; +} + +s32_t bt_mesh_health_cli_timeout_get(void) +{ + return msg_timeout; +} + +void bt_mesh_health_cli_timeout_set(s32_t timeout) +{ + msg_timeout = timeout; +} + +int bt_mesh_health_cli_set(struct bt_mesh_model *model) +{ + if (!model->user_data) { + BT_ERR("No Health Client context for given model"); + return -EINVAL; + } + + health_cli = model->user_data; + + return 0; +} + +int bt_mesh_health_cli_init(struct bt_mesh_model *model, bool primary) +{ + struct bt_mesh_health_cli *cli = model->user_data; + + BT_DBG("primary %u", primary); + + if (!cli) { + BT_ERR("No Health Client context provided"); + return -EINVAL; + } + + cli = model->user_data; + cli->model = model; + + k_sem_init(&cli->op_sync, 0, 1); + + /* Set the default health client pointer */ + if (!health_cli) { + health_cli = cli; + } + + return 0; +} diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/health_srv.c b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/health_srv.c new file mode 100644 index 000000000..97e3e043b --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/health_srv.c @@ -0,0 +1,441 @@ +/* Bluetooth Mesh */ + +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include "syscfg/syscfg.h" +#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG_MODEL)) +#include "host/ble_hs_log.h" + +#include "mesh/mesh.h" +#include "mesh_priv.h" +#include "adv.h" +#include "net.h" +#include "transport.h" +#include "access.h" +#include "foundation.h" + +#define HEALTH_TEST_STANDARD 0x00 + +/* Health Server context of the primary element */ +struct bt_mesh_health_srv *health_srv; + +static void health_get_registered(struct bt_mesh_model *mod, + u16_t company_id, + struct os_mbuf *msg) +{ + struct bt_mesh_health_srv *srv = mod->user_data; + u8_t *test_id; + + BT_DBG("Company ID 0x%04x", company_id); + + bt_mesh_model_msg_init(msg, OP_HEALTH_FAULT_STATUS); + + test_id = net_buf_simple_add(msg, 1); + net_buf_simple_add_le16(msg, company_id); + + if (srv->cb && srv->cb->fault_get_reg) { + u8_t fault_count = net_buf_simple_tailroom(msg) - 4; + int err; + + err = srv->cb->fault_get_reg(mod, company_id, test_id, + net_buf_simple_tail(msg), + &fault_count); + if (err) { + BT_ERR("Failed to get faults (err %d)", err); + *test_id = HEALTH_TEST_STANDARD; + } else { + net_buf_simple_add(msg, fault_count); + } + } else { + BT_WARN("No callback for getting faults"); + *test_id = HEALTH_TEST_STANDARD; + } +} + +static size_t health_get_current(struct bt_mesh_model *mod, + struct os_mbuf *msg) +{ + struct bt_mesh_health_srv *srv = mod->user_data; + const struct bt_mesh_comp *comp; + u8_t *test_id, *company_ptr; + u16_t company_id; + u8_t fault_count; + int err; + + bt_mesh_model_msg_init(msg, OP_HEALTH_CURRENT_STATUS); + + test_id = net_buf_simple_add(msg, 1); + company_ptr = net_buf_simple_add(msg, sizeof(company_id)); + comp = bt_mesh_comp_get(); + + if (srv->cb && srv->cb->fault_get_cur) { + fault_count = net_buf_simple_tailroom(msg); + err = srv->cb->fault_get_cur(mod, test_id, &company_id, + net_buf_simple_tail(msg), + &fault_count); + if (err) { + BT_ERR("Failed to get faults (err %d)", err); + sys_put_le16(comp->cid, company_ptr); + *test_id = HEALTH_TEST_STANDARD; + fault_count = 0; + } else { + sys_put_le16(company_id, company_ptr); + net_buf_simple_add(msg, fault_count); + } + } else { + BT_WARN("No callback for getting faults"); + sys_put_le16(comp->cid, company_ptr); + *test_id = HEALTH_TEST_STANDARD; + fault_count = 0; + } + + return fault_count; +} + +static void health_fault_get(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct os_mbuf *sdu = NET_BUF_SIMPLE(BT_MESH_TX_SDU_MAX); + u16_t company_id; + + company_id = net_buf_simple_pull_le16(buf); + + BT_DBG("company_id 0x%04x", company_id); + + health_get_registered(model, company_id, sdu); + + if (bt_mesh_model_send(model, ctx, sdu, NULL, NULL)) { + BT_ERR("Unable to send Health Current Status response"); + } + + os_mbuf_free_chain(sdu); +} + +static void health_fault_clear_unrel(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct bt_mesh_health_srv *srv = model->user_data; + u16_t company_id; + + company_id = net_buf_simple_pull_le16(buf); + + BT_DBG("company_id 0x%04x", company_id); + + if (srv->cb && srv->cb->fault_clear) { + srv->cb->fault_clear(model, company_id); + } +} + +static void health_fault_clear(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct os_mbuf *sdu = NET_BUF_SIMPLE(BT_MESH_TX_SDU_MAX); + struct bt_mesh_health_srv *srv = model->user_data; + u16_t company_id; + + company_id = net_buf_simple_pull_le16(buf); + + BT_DBG("company_id 0x%04x", company_id); + + if (srv->cb && srv->cb->fault_clear) { + srv->cb->fault_clear(model, company_id); + } + + health_get_registered(model, company_id, sdu); + + if (bt_mesh_model_send(model, ctx, sdu, NULL, NULL)) { + BT_ERR("Unable to send Health Current Status response"); + } + + os_mbuf_free_chain(sdu); +} + +static void health_fault_test_unrel(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct bt_mesh_health_srv *srv = model->user_data; + u16_t company_id; + u8_t test_id; + + test_id = net_buf_simple_pull_u8(buf); + company_id = net_buf_simple_pull_le16(buf); + + BT_DBG("test 0x%02x company 0x%04x", test_id, company_id); + + if (srv->cb && srv->cb->fault_test) { + srv->cb->fault_test(model, test_id, company_id); + } +} + +static void health_fault_test(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct os_mbuf *sdu = NET_BUF_SIMPLE(BT_MESH_TX_SDU_MAX); + struct bt_mesh_health_srv *srv = model->user_data; + u16_t company_id; + u8_t test_id; + + BT_DBG(""); + + test_id = net_buf_simple_pull_u8(buf); + company_id = net_buf_simple_pull_le16(buf); + + BT_DBG("test 0x%02x company 0x%04x", test_id, company_id); + + if (srv->cb && srv->cb->fault_test) { + int err; + + err = srv->cb->fault_test(model, test_id, company_id); + if (err) { + BT_WARN("Running fault test failed with err %d", err); + goto done; + } + } + + health_get_registered(model, company_id, sdu); + + if (bt_mesh_model_send(model, ctx, sdu, NULL, NULL)) { + BT_ERR("Unable to send Health Current Status response"); + } + +done: + os_mbuf_free_chain(sdu); +} + +static void send_attention_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx) +{ + /* Needed size: opcode (2 bytes) + msg + MIC */ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4); + struct bt_mesh_health_srv *srv = model->user_data; + u8_t time; + + time = k_delayed_work_remaining_get(&srv->attn_timer) / 1000; + BT_DBG("%u second%s", time, (time == 1) ? "" : "s"); + + bt_mesh_model_msg_init(msg, OP_ATTENTION_STATUS); + + net_buf_simple_add_u8(msg, time); + + if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + BT_ERR("Unable to send Attention Status"); + } + + os_mbuf_free_chain(msg); +} + +static void attention_get(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + BT_DBG(""); + + send_attention_status(model, ctx); +} + +static void attention_set_unrel(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + u8_t time; + + time = net_buf_simple_pull_u8(buf); + + BT_DBG("%u second%s", time, (time == 1) ? "" : "s"); + + bt_mesh_attention(model, time); +} + +static void attention_set(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + BT_DBG(""); + + attention_set_unrel(model, ctx, buf); + + send_attention_status(model, ctx); +} + +static void send_health_period_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx) +{ + /* Needed size: opcode (2 bytes) + msg + MIC */ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 1 + 4); + + bt_mesh_model_msg_init(msg, OP_HEALTH_PERIOD_STATUS); + + net_buf_simple_add_u8(msg, model->pub->period_div); + + if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + BT_ERR("Unable to send Health Period Status"); + } + + os_mbuf_free_chain(msg); +} + +static void health_period_get(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + BT_DBG(""); + + send_health_period_status(model, ctx); +} + +static void health_period_set_unrel(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + u8_t period; + + period = net_buf_simple_pull_u8(buf); + if (period > 15) { + BT_WARN("Prohibited period value %u", period); + return; + } + + BT_DBG("period %u", period); + + model->pub->period_div = period; +} + +static void health_period_set(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + BT_DBG(""); + + health_period_set_unrel(model, ctx, buf); + + send_health_period_status(model, ctx); +} + +const struct bt_mesh_model_op bt_mesh_health_srv_op[] = { + { OP_HEALTH_FAULT_GET, 2, health_fault_get }, + { OP_HEALTH_FAULT_CLEAR, 2, health_fault_clear }, + { OP_HEALTH_FAULT_CLEAR_UNREL, 2, health_fault_clear_unrel }, + { OP_HEALTH_FAULT_TEST, 3, health_fault_test }, + { OP_HEALTH_FAULT_TEST_UNREL, 3, health_fault_test_unrel }, + { OP_HEALTH_PERIOD_GET, 0, health_period_get }, + { OP_HEALTH_PERIOD_SET, 1, health_period_set }, + { OP_HEALTH_PERIOD_SET_UNREL, 1, health_period_set_unrel }, + { OP_ATTENTION_GET, 0, attention_get }, + { OP_ATTENTION_SET, 1, attention_set }, + { OP_ATTENTION_SET_UNREL, 1, attention_set_unrel }, + BT_MESH_MODEL_OP_END, +}; + +static int health_pub_update(struct bt_mesh_model *mod) +{ + struct bt_mesh_model_pub *pub = mod->pub; + size_t count; + + BT_DBG(""); + + count = health_get_current(mod, pub->msg); + if (!count) { + pub->period_div = 0; + } + + return 0; +} + +int bt_mesh_fault_update(struct bt_mesh_elem *elem) +{ + struct bt_mesh_model *mod; + + mod = bt_mesh_model_find(elem, BT_MESH_MODEL_ID_HEALTH_SRV); + if (!mod) { + return -EINVAL; + } + + return bt_mesh_model_publish(mod); +} + +static void attention_off(struct ble_npl_event *work) +{ + struct bt_mesh_health_srv *srv = ble_npl_event_get_arg(work); + BT_DBG(""); + + if (srv->cb && srv->cb->attn_off) { + srv->cb->attn_off(srv->model); + } +} + +int bt_mesh_health_srv_init(struct bt_mesh_model *model, bool primary) +{ + struct bt_mesh_health_srv *srv = model->user_data; + + if (!srv) { + if (!primary) { + return 0; + } + + BT_ERR("No Health Server context provided"); + return -EINVAL; + } + + if (!model->pub) { + BT_ERR("Health Server has no publication support"); + return -EINVAL; + } + + model->pub->update = health_pub_update; + + k_delayed_work_init(&srv->attn_timer, attention_off); + k_delayed_work_add_arg(&srv->attn_timer, srv); + + srv->model = model; + + if (primary) { + health_srv = srv; + } + + return 0; +} + +void bt_mesh_attention(struct bt_mesh_model *model, u8_t time) +{ + struct bt_mesh_health_srv *srv; + + BT_DBG("bt_mesh_attention"); + if (!model) { + srv = health_srv; + if (!srv) { + BT_WARN("No Health Server available"); + return; + } + + model = srv->model; + } else { + srv = model->user_data; + } + + if (time) { + if (srv->cb && srv->cb->attn_on) { + srv->cb->attn_on(model); + } + + k_delayed_work_submit(&srv->attn_timer, time * 1000); + } else { + k_delayed_work_cancel(&srv->attn_timer); + + if (srv->cb && srv->cb->attn_off) { + srv->cb->attn_off(model); + } + } +} diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/light_model.c b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/light_model.c new file mode 100644 index 000000000..b6d838188 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/light_model.c @@ -0,0 +1,58 @@ + +#include "syscfg/syscfg.h" + +#include "mesh/mesh.h" +#include "console/console.h" +#include "light_model.h" + + +static u8_t gen_onoff_state; +static s16_t gen_level_state; + +static void update_light_state(void) +{ + console_printf("Light state: onoff=%d lvl=0x%04x\n", gen_onoff_state, (u16_t)gen_level_state); +} + +int light_model_gen_onoff_get(struct bt_mesh_model *model, u8_t *state) +{ + *state = gen_onoff_state; + return 0; +} + +int light_model_gen_onoff_set(struct bt_mesh_model *model, u8_t state) +{ + gen_onoff_state = state; + update_light_state(); + return 0; +} + +int light_model_gen_level_get(struct bt_mesh_model *model, s16_t *level) +{ + *level = gen_level_state; + return 0; +} + +int light_model_gen_level_set(struct bt_mesh_model *model, s16_t level) +{ + gen_level_state = level; + if ((u16_t)gen_level_state > 0x0000) { + gen_onoff_state = 1; + } + if ((u16_t)gen_level_state == 0x0000) { + gen_onoff_state = 0; + } + update_light_state(); + return 0; +} + +int light_model_light_lightness_get(struct bt_mesh_model *model, s16_t *lightness) +{ + return light_model_gen_level_get(model, lightness); +} + +int light_model_light_lightness_set(struct bt_mesh_model *model, s16_t lightness) +{ + return light_model_gen_level_set(model, lightness); +} + diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/light_model.h b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/light_model.h new file mode 100644 index 000000000..95fcdb786 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/light_model.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef __BT_MESH_LIGHT_MODEL_H +#define __BT_MESH_LIGHT_MODEL_H + +#include "syscfg/syscfg.h" +#include "mesh/mesh.h" + +int light_model_gen_onoff_get(struct bt_mesh_model *model, u8_t *state); +int light_model_gen_onoff_set(struct bt_mesh_model *model, u8_t state); +int light_model_gen_level_get(struct bt_mesh_model *model, s16_t *level); +int light_model_gen_level_set(struct bt_mesh_model *model, s16_t level); +int light_model_light_lightness_get(struct bt_mesh_model *model, s16_t *lightness); +int light_model_light_lightness_set(struct bt_mesh_model *model, s16_t lightness); + +#endif diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/lpn.c b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/lpn.c new file mode 100644 index 000000000..0dd00ac6c --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/lpn.c @@ -0,0 +1,1046 @@ +/* Bluetooth Mesh */ + +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "syscfg/syscfg.h" + +#if MYNEWT_VAL(BLE_MESH_LOW_POWER) + +#include + +#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG_LOW_POWER)) +#include "host/ble_hs_log.h" + +#include "mesh/mesh.h" +#include "mesh_priv.h" +#include "crypto.h" +#include "adv.h" +#include "net.h" +#include "transport.h" +#include "access.h" +#include "beacon.h" +#include "foundation.h" +#include "lpn.h" + +#if MYNEWT_VAL(BLE_MESH_LPN_AUTO) +#define LPN_AUTO_TIMEOUT K_SECONDS(MYNEWT_VAL(BLE_MESH_LPN_AUTO_TIMEOUT)) +#else +#define LPN_AUTO_TIMEOUT 0 +#endif + +#define LPN_RECV_DELAY MYNEWT_VAL(BLE_MESH_LPN_RECV_DELAY) +#define SCAN_LATENCY min(MYNEWT_VAL(BLE_MESH_LPN_SCAN_LATENCY), \ + LPN_RECV_DELAY) + +#define FRIEND_REQ_RETRY_TIMEOUT K_SECONDS(MYNEWT_VAL(BLE_MESH_LPN_RETRY_TIMEOUT)) + +#define FRIEND_REQ_WAIT K_MSEC(100) +#define FRIEND_REQ_SCAN K_SECONDS(1) +#define FRIEND_REQ_TIMEOUT (FRIEND_REQ_WAIT + FRIEND_REQ_SCAN) + +#define POLL_RETRY_TIMEOUT K_MSEC(100) + +#define REQ_RETRY_DURATION(lpn) (4 * (LPN_RECV_DELAY + (lpn)->adv_duration + \ + (lpn)->recv_win + POLL_RETRY_TIMEOUT)) + +#define POLL_TIMEOUT_INIT (MYNEWT_VAL(BLE_MESH_LPN_INIT_POLL_TIMEOUT) * 100) +#define POLL_TIMEOUT_MAX(lpn) ((MYNEWT_VAL(BLE_MESH_LPN_POLL_TIMEOUT) * 100) - \ + REQ_RETRY_DURATION(lpn)) +#define REQ_ATTEMPTS(lpn) (POLL_TIMEOUT_MAX(lpn) < K_SECONDS(3) ? 2 : 4) + +#define CLEAR_ATTEMPTS 2 + +#define LPN_CRITERIA ((MYNEWT_VAL(BLE_MESH_LPN_MIN_QUEUE_SIZE)) | \ + (MYNEWT_VAL(BLE_MESH_LPN_RSSI_FACTOR) << 3) | \ + (MYNEWT_VAL(BLE_MESH_LPN_RECV_WIN_FACTOR) << 5)) + +#define POLL_TO(to) { (u8_t)((to) >> 16), (u8_t)((to) >> 8), (u8_t)(to) } +#define LPN_POLL_TO POLL_TO(MYNEWT_VAL(BLE_MESH_LPN_POLL_TIMEOUT)) + +/* 2 transmissions, 20ms interval */ +#define POLL_XMIT BT_MESH_TRANSMIT(1, 20) + +static void (*lpn_cb)(u16_t friend_addr, bool established); + +#if MYNEWT_VAL(BLE_MESH_DEBUG_LOW_POWER) +static const char *state2str(int state) +{ + switch (state) { + case BT_MESH_LPN_DISABLED: + return "disabled"; + case BT_MESH_LPN_CLEAR: + return "clear"; + case BT_MESH_LPN_TIMER: + return "timer"; + case BT_MESH_LPN_ENABLED: + return "enabled"; + case BT_MESH_LPN_REQ_WAIT: + return "req wait"; + case BT_MESH_LPN_WAIT_OFFER: + return "wait offer"; + case BT_MESH_LPN_ESTABLISHED: + return "established"; + case BT_MESH_LPN_RECV_DELAY: + return "recv delay"; + case BT_MESH_LPN_WAIT_UPDATE: + return "wait update"; + default: + return "(unknown)"; + } +} +#endif /* CONFIG_BLUETOOTH_MESH_DEBUG_LPN */ + +static inline void lpn_set_state(int state) +{ +#if MYNEWT_VAL(BLE_MESH_DEBUG_LOW_POWER) + BT_DBG("%s -> %s", state2str(bt_mesh.lpn.state), state2str(state)); +#endif + bt_mesh.lpn.state = state; +} + +static inline void group_zero(atomic_t *target) +{ +#if CONFIG_BT_MESH_LPN_GROUPS > 32 + int i; + + for (i = 0; i < ARRAY_SIZE(bt_mesh.lpn.added); i++) { + atomic_set(&target[i], 0); + } +#else + atomic_set(target, 0); +#endif +} + +static inline void group_set(atomic_t *target, atomic_t *source) +{ +#if CONFIG_BT_MESH_LPN_GROUPS > 32 + int i; + + for (i = 0; i < ARRAY_SIZE(bt_mesh.lpn.added); i++) { + atomic_or(&target[i], atomic_get(&source[i])); + } +#else + atomic_or(target, atomic_get(source)); +#endif +} + +static inline void group_clear(atomic_t *target, atomic_t *source) +{ +#if CONFIG_BT_MESH_LPN_GROUPS > 32 + int i; + + for (i = 0; i < ARRAY_SIZE(bt_mesh.lpn.added); i++) { + atomic_and(&target[i], ~atomic_get(&source[i])); + } +#else + atomic_and(target, ~atomic_get(source)); +#endif +} + +static void clear_friendship(bool force, bool disable); + +static void friend_clear_sent(int err, void *user_data) +{ + struct bt_mesh_lpn *lpn = &bt_mesh.lpn; + + /* We're switching away from Low Power behavior, so permanently + * enable scanning. + */ + bt_mesh_scan_enable(); + + lpn->req_attempts++; + + if (err) { + BT_ERR("Sending Friend Request failed (err %d)", err); + lpn_set_state(BT_MESH_LPN_ENABLED); + clear_friendship(false, lpn->disable); + return; + } + + lpn_set_state(BT_MESH_LPN_CLEAR); + k_delayed_work_submit(&lpn->timer, FRIEND_REQ_TIMEOUT); +} + +static const struct bt_mesh_send_cb clear_sent_cb = { + .end = friend_clear_sent, +}; + +static int send_friend_clear(void) +{ + struct bt_mesh_msg_ctx ctx = { + .net_idx = bt_mesh.sub[0].net_idx, + .app_idx = BT_MESH_KEY_UNUSED, + .addr = bt_mesh.lpn.frnd, + .send_ttl = 0, + }; + struct bt_mesh_net_tx tx = { + .sub = &bt_mesh.sub[0], + .ctx = &ctx, + .src = bt_mesh_primary_addr(), + .xmit = bt_mesh_net_transmit_get(), + }; + struct bt_mesh_ctl_friend_clear req = { + .lpn_addr = sys_cpu_to_be16(tx.src), + .lpn_counter = sys_cpu_to_be16(bt_mesh.lpn.counter), + }; + + BT_DBG(""); + + return bt_mesh_ctl_send(&tx, TRANS_CTL_OP_FRIEND_CLEAR, &req, + sizeof(req), NULL, &clear_sent_cb, NULL); +} + +static void clear_friendship(bool force, bool disable) +{ + struct bt_mesh_lpn *lpn = &bt_mesh.lpn; + + BT_DBG("force %u disable %u", force, disable); + + if (!force && lpn->established && !lpn->clear_success && + lpn->req_attempts < CLEAR_ATTEMPTS) { + send_friend_clear(); + lpn->disable = disable; + return; + } + + bt_mesh_rx_reset(); + + k_delayed_work_cancel(&lpn->timer); + + friend_cred_del(bt_mesh.sub[0].net_idx, lpn->frnd); + + if (lpn->clear_success) { + lpn->old_friend = BT_MESH_ADDR_UNASSIGNED; + } else { + lpn->old_friend = lpn->frnd; + } + + if (lpn_cb && lpn->frnd != BT_MESH_ADDR_UNASSIGNED) { + lpn_cb(lpn->frnd, false); + } + + lpn->frnd = BT_MESH_ADDR_UNASSIGNED; + lpn->fsn = 0; + lpn->req_attempts = 0; + lpn->recv_win = 0; + lpn->queue_size = 0; + lpn->disable = 0; + lpn->sent_req = 0; + lpn->established = 0; + lpn->clear_success = 0; + + group_zero(lpn->added); + group_zero(lpn->pending); + group_zero(lpn->to_remove); + + /* Set this to 1 to force group subscription when the next + * Friendship is created, in case lpn->groups doesn't get + * modified meanwhile. + */ + lpn->groups_changed = 1; + + if (disable) { + lpn_set_state(BT_MESH_LPN_DISABLED); + return; + } + + lpn_set_state(BT_MESH_LPN_ENABLED); + k_delayed_work_submit(&lpn->timer, FRIEND_REQ_RETRY_TIMEOUT); +} + +static void friend_req_sent(u16_t duration, int err, void *user_data) +{ + struct bt_mesh_lpn *lpn = &bt_mesh.lpn; + + if (err) { + BT_ERR("Sending Friend Request failed (err %d)", err); + return; + } + + lpn->adv_duration = duration; + + if (IS_ENABLED(CONFIG_BT_MESH_LPN_ESTABLISHMENT)) { + k_delayed_work_submit(&lpn->timer, FRIEND_REQ_WAIT); + lpn_set_state(BT_MESH_LPN_REQ_WAIT); + } else { + k_delayed_work_submit(&lpn->timer, + duration + FRIEND_REQ_TIMEOUT); + lpn_set_state(BT_MESH_LPN_WAIT_OFFER); + } +} + +static const struct bt_mesh_send_cb friend_req_sent_cb = { + .start = friend_req_sent, +}; + +static int send_friend_req(struct bt_mesh_lpn *lpn) +{ + const struct bt_mesh_comp *comp = bt_mesh_comp_get(); + struct bt_mesh_msg_ctx ctx = { + .net_idx = bt_mesh.sub[0].net_idx, + .app_idx = BT_MESH_KEY_UNUSED, + .addr = BT_MESH_ADDR_FRIENDS, + .send_ttl = 0, + }; + struct bt_mesh_net_tx tx = { + .sub = &bt_mesh.sub[0], + .ctx = &ctx, + .src = bt_mesh_primary_addr(), + .xmit = POLL_XMIT, + }; + struct bt_mesh_ctl_friend_req req = { + .criteria = LPN_CRITERIA, + .recv_delay = LPN_RECV_DELAY, + .poll_to = LPN_POLL_TO, + .prev_addr = lpn->old_friend, + .num_elem = comp->elem_count, + .lpn_counter = sys_cpu_to_be16(lpn->counter), + }; + + BT_DBG(""); + + return bt_mesh_ctl_send(&tx, TRANS_CTL_OP_FRIEND_REQ, &req, + sizeof(req), NULL, &friend_req_sent_cb, NULL); +} + +static void req_sent(u16_t duration, int err, void *user_data) +{ + struct bt_mesh_lpn *lpn = &bt_mesh.lpn; + +#if BT_DBG_ENABLED + BT_DBG("req 0x%02x duration %u err %d state %s", + lpn->sent_req, duration, err, state2str(lpn->state)); +#endif + + if (err) { + BT_ERR("Sending request failed (err %d)", err); + lpn->sent_req = 0; + group_zero(lpn->pending); + return; + } + + lpn->req_attempts++; + lpn->adv_duration = duration; + + if (lpn->established || IS_ENABLED(CONFIG_BT_MESH_LPN_ESTABLISHMENT)) { + lpn_set_state(BT_MESH_LPN_RECV_DELAY); + /* We start scanning a bit early to elimitate risk of missing + * response data due to HCI and other latencies. + */ + k_delayed_work_submit(&lpn->timer, + LPN_RECV_DELAY - SCAN_LATENCY); + } else { + k_delayed_work_submit(&lpn->timer, + LPN_RECV_DELAY + duration + + lpn->recv_win); + } +} + +static const struct bt_mesh_send_cb req_sent_cb = { + .start = req_sent, +}; + +static int send_friend_poll(void) +{ + struct bt_mesh_msg_ctx ctx = { + .net_idx = bt_mesh.sub[0].net_idx, + .app_idx = BT_MESH_KEY_UNUSED, + .addr = bt_mesh.lpn.frnd, + .send_ttl = 0, + }; + struct bt_mesh_net_tx tx = { + .sub = &bt_mesh.sub[0], + .ctx = &ctx, + .src = bt_mesh_primary_addr(), + .xmit = POLL_XMIT, + .friend_cred = true, + }; + struct bt_mesh_lpn *lpn = &bt_mesh.lpn; + u8_t fsn = lpn->fsn; + int err; + + BT_DBG("lpn->sent_req 0x%02x", lpn->sent_req); + + if (lpn->sent_req) { + if (lpn->sent_req != TRANS_CTL_OP_FRIEND_POLL) { + lpn->pending_poll = 1; + } + + return 0; + } + + err = bt_mesh_ctl_send(&tx, TRANS_CTL_OP_FRIEND_POLL, &fsn, 1, + NULL, &req_sent_cb, NULL); + if (err == 0) { + lpn->pending_poll = 0; + lpn->sent_req = TRANS_CTL_OP_FRIEND_POLL; + } + + return err; +} + +void bt_mesh_lpn_disable(bool force) +{ + if (bt_mesh.lpn.state == BT_MESH_LPN_DISABLED) { + return; + } + + clear_friendship(force, true); +} + +int bt_mesh_lpn_set(bool enable) +{ + struct bt_mesh_lpn *lpn = &bt_mesh.lpn; + + if (enable) { + if (lpn->state != BT_MESH_LPN_DISABLED) { + return 0; + } + } else { + if (lpn->state == BT_MESH_LPN_DISABLED) { + return 0; + } + } + + if (!bt_mesh_is_provisioned()) { + if (enable) { + lpn_set_state(BT_MESH_LPN_ENABLED); + } else { + lpn_set_state(BT_MESH_LPN_DISABLED); + } + + return 0; + } + + if (enable) { + lpn_set_state(BT_MESH_LPN_ENABLED); + + if (IS_ENABLED(CONFIG_BT_MESH_LPN_ESTABLISHMENT)) { + bt_mesh_scan_disable(); + } + + send_friend_req(lpn); + } else { + if (IS_ENABLED(CONFIG_BT_MESH_LPN_AUTO) && + lpn->state == BT_MESH_LPN_TIMER) { + k_delayed_work_cancel(&lpn->timer); + lpn_set_state(BT_MESH_LPN_DISABLED); + } else { + bt_mesh_lpn_disable(false); + } + } + + return 0; +} + +static void friend_response_received(struct bt_mesh_lpn *lpn) +{ + BT_DBG("lpn->sent_req 0x%02x", lpn->sent_req); + + if (lpn->sent_req == TRANS_CTL_OP_FRIEND_POLL) { + lpn->fsn++; + } + + k_delayed_work_cancel(&lpn->timer); + bt_mesh_scan_disable(); + lpn_set_state(BT_MESH_LPN_ESTABLISHED); + lpn->req_attempts = 0; + lpn->sent_req = 0; +} + +void bt_mesh_lpn_msg_received(struct bt_mesh_net_rx *rx) +{ + struct bt_mesh_lpn *lpn = &bt_mesh.lpn; + + if (lpn->state == BT_MESH_LPN_TIMER) { + BT_DBG("Restarting establishment timer"); + k_delayed_work_submit(&lpn->timer, LPN_AUTO_TIMEOUT); + return; + } + + if (lpn->sent_req != TRANS_CTL_OP_FRIEND_POLL) { + BT_WARN("Unexpected message withouth a preceding Poll"); + return; + } + + friend_response_received(lpn); + + BT_DBG("Requesting more messages from Friend"); + + send_friend_poll(); +} + +int bt_mesh_lpn_friend_offer(struct bt_mesh_net_rx *rx, + struct os_mbuf *buf) +{ + struct bt_mesh_ctl_friend_offer *msg = (void *)buf->om_data; + struct bt_mesh_lpn *lpn = &bt_mesh.lpn; + struct bt_mesh_subnet *sub = rx->sub; + struct friend_cred *cred; + u16_t frnd_counter; + int err; + + if (buf->om_len < sizeof(*msg)) { + BT_WARN("Too short Friend Offer"); + return -EINVAL; + } + + if (lpn->state != BT_MESH_LPN_WAIT_OFFER) { + BT_WARN("Ignoring unexpected Friend Offer"); + return 0; + } + + if (!msg->recv_win) { + BT_WARN("Prohibited ReceiveWindow value"); + return -EINVAL; + } + + frnd_counter = sys_be16_to_cpu(msg->frnd_counter); + + BT_DBG("recv_win %u queue_size %u sub_list_size %u rssi %d counter %u", + msg->recv_win, msg->queue_size, msg->sub_list_size, msg->rssi, + frnd_counter); + + lpn->frnd = rx->ctx.addr; + + cred = friend_cred_create(sub, lpn->frnd, lpn->counter, frnd_counter); + if (!cred) { + lpn->frnd = BT_MESH_ADDR_UNASSIGNED; + return -ENOMEM; + } + + /* TODO: Add offer acceptance criteria check */ + + k_delayed_work_cancel(&lpn->timer); + + lpn->recv_win = msg->recv_win; + lpn->queue_size = msg->queue_size; + + err = send_friend_poll(); + if (err) { + friend_cred_clear(cred); + lpn->frnd = BT_MESH_ADDR_UNASSIGNED; + lpn->recv_win = 0; + lpn->queue_size = 0; + return err; + } + + lpn->counter++; + + return 0; +} + +int bt_mesh_lpn_friend_clear_cfm(struct bt_mesh_net_rx *rx, + struct os_mbuf *buf) +{ + struct bt_mesh_ctl_friend_clear_confirm *msg = (void *)buf->om_data; + struct bt_mesh_lpn *lpn = &bt_mesh.lpn; + u16_t addr, counter; + + if (buf->om_len < sizeof(*msg)) { + BT_WARN("Too short Friend Clear Confirm"); + return -EINVAL; + } + + if (lpn->state != BT_MESH_LPN_CLEAR) { + BT_WARN("Ignoring unexpected Friend Clear Confirm"); + return 0; + } + + addr = sys_be16_to_cpu(msg->lpn_addr); + counter = sys_be16_to_cpu(msg->lpn_counter); + + BT_DBG("LPNAddress 0x%04x LPNCounter 0x%04x", addr, counter); + + if (addr != bt_mesh_primary_addr() || counter != lpn->counter) { + BT_WARN("Invalid parameters in Friend Clear Confirm"); + return 0; + } + + lpn->clear_success = 1; + clear_friendship(false, lpn->disable); + + return 0; +} + +static void lpn_group_add(u16_t group) +{ + struct bt_mesh_lpn *lpn = &bt_mesh.lpn; + u16_t *free_slot = NULL; + int i; + + for (i = 0; i < ARRAY_SIZE(lpn->groups); i++) { + if (lpn->groups[i] == group) { + atomic_clear_bit(lpn->to_remove, i); + return; + } + + if (!free_slot && lpn->groups[i] == BT_MESH_ADDR_UNASSIGNED) { + free_slot = &lpn->groups[i]; + } + } + + if (!free_slot) { + BT_WARN("Friend Subscription List exceeded!"); + return; + } + + *free_slot = group; + lpn->groups_changed = 1; +} + +static void lpn_group_del(u16_t group) +{ + struct bt_mesh_lpn *lpn = &bt_mesh.lpn; + int i; + + for (i = 0; i < ARRAY_SIZE(lpn->groups); i++) { + if (lpn->groups[i] == group) { + if (atomic_test_bit(lpn->added, i) || + atomic_test_bit(lpn->pending, i)) { + atomic_set_bit(lpn->to_remove, i); + lpn->groups_changed = 1; + } else { + lpn->groups[i] = BT_MESH_ADDR_UNASSIGNED; + } + } + } +} + +static inline int group_popcount(atomic_t *target) +{ +#if CONFIG_BT_MESH_LPN_GROUPS > 32 + int i, count = 0; + + for (i = 0; i < ARRAY_SIZE(bt_mesh.lpn.added); i++) { + count += popcount(atomic_get(&target[i])); + } +#else + return popcount(atomic_get(target)); +#endif +} + +static bool sub_update(u8_t op) +{ + struct bt_mesh_lpn *lpn = &bt_mesh.lpn; + int added_count = group_popcount(lpn->added); + struct bt_mesh_msg_ctx ctx = { + .net_idx = bt_mesh.sub[0].net_idx, + .app_idx = BT_MESH_KEY_UNUSED, + .addr = lpn->frnd, + .send_ttl = 0, + }; + struct bt_mesh_net_tx tx = { + .sub = &bt_mesh.sub[0], + .ctx = &ctx, + .src = bt_mesh_primary_addr(), + .xmit = POLL_XMIT, + .friend_cred = true, + }; + struct bt_mesh_ctl_friend_sub req; + size_t i, g; + + BT_DBG("op 0x%02x sent_req 0x%02x", op, lpn->sent_req); + + if (lpn->sent_req) { + return false; + } + + for (i = 0, g = 0; i < ARRAY_SIZE(lpn->groups); i++) { + if (lpn->groups[i] == BT_MESH_ADDR_UNASSIGNED) { + continue; + } + + if (op == TRANS_CTL_OP_FRIEND_SUB_ADD) { + if (atomic_test_bit(lpn->added, i)) { + continue; + } + } else { + if (!atomic_test_bit(lpn->to_remove, i)) { + continue; + } + } + + if (added_count + g >= lpn->queue_size) { + BT_WARN("Friend Queue Size exceeded"); + break; + } + + req.addr_list[g++] = sys_cpu_to_be16(lpn->groups[i]); + atomic_set_bit(lpn->pending, i); + + if (g == ARRAY_SIZE(req.addr_list)) { + break; + } + } + + if (g == 0) { + group_zero(lpn->pending); + return false; + } + + req.xact = lpn->xact_next++; + + if (bt_mesh_ctl_send(&tx, op, &req, 1 + g * 2, NULL, + &req_sent_cb, NULL) < 0) { + group_zero(lpn->pending); + return false; + } + + lpn->xact_pending = req.xact; + lpn->sent_req = op; + return true; +} + +static void update_timeout(struct bt_mesh_lpn *lpn) +{ + if (lpn->established) { + BT_WARN("No response from Friend during ReceiveWindow"); + bt_mesh_scan_disable(); + lpn_set_state(BT_MESH_LPN_ESTABLISHED); + k_delayed_work_submit(&lpn->timer, POLL_RETRY_TIMEOUT); + } else { + if (IS_ENABLED(CONFIG_BT_MESH_LPN_ESTABLISHMENT)) { + bt_mesh_scan_disable(); + } + + if (lpn->req_attempts < 6) { + BT_WARN("Retrying first Friend Poll"); + lpn->sent_req = 0; + if (send_friend_poll() == 0) { + return; + } + } + + BT_ERR("Timed out waiting for first Friend Update"); + clear_friendship(false, false); + } +} + +static void lpn_timeout(struct ble_npl_event *work) +{ + struct bt_mesh_lpn *lpn = &bt_mesh.lpn; + +#if MYNEWT_VAL(BLE_MESH_DEBUG_LOW_POWER) + BT_DBG("state: %s", state2str(lpn->state)); +#endif + + switch (lpn->state) { + case BT_MESH_LPN_DISABLED: + break; + case BT_MESH_LPN_CLEAR: + clear_friendship(false, bt_mesh.lpn.disable); + break; + case BT_MESH_LPN_TIMER: + BT_DBG("Starting to look for Friend nodes"); + lpn_set_state(BT_MESH_LPN_ENABLED); + if (IS_ENABLED(CONFIG_BT_MESH_LPN_ESTABLISHMENT)) { + bt_mesh_scan_disable(); + } + /* fall through */ + case BT_MESH_LPN_ENABLED: + send_friend_req(lpn); + break; + case BT_MESH_LPN_REQ_WAIT: + bt_mesh_scan_enable(); + k_delayed_work_submit(&lpn->timer, + lpn->adv_duration + FRIEND_REQ_SCAN); + lpn_set_state(BT_MESH_LPN_WAIT_OFFER); + break; + case BT_MESH_LPN_WAIT_OFFER: + BT_WARN("No acceptable Friend Offers received"); + if (IS_ENABLED(CONFIG_BT_MESH_LPN_ESTABLISHMENT)) { + bt_mesh_scan_disable(); + } + lpn->counter++; + lpn_set_state(BT_MESH_LPN_ENABLED); + k_delayed_work_submit(&lpn->timer, FRIEND_REQ_RETRY_TIMEOUT); + break; + case BT_MESH_LPN_ESTABLISHED: + if (lpn->req_attempts < REQ_ATTEMPTS(lpn)) { + u8_t req = lpn->sent_req; + + lpn->sent_req = 0; + + if (!req || req == TRANS_CTL_OP_FRIEND_POLL) { + send_friend_poll(); + } else { + sub_update(req); + } + + break; + } + + BT_ERR("No response from Friend after %u retries", + lpn->req_attempts); + lpn->req_attempts = 0; + clear_friendship(false, false); + break; + case BT_MESH_LPN_RECV_DELAY: + k_delayed_work_submit(&lpn->timer, + lpn->adv_duration + SCAN_LATENCY + + lpn->recv_win); + bt_mesh_scan_enable(); + lpn_set_state(BT_MESH_LPN_WAIT_UPDATE); + break; + case BT_MESH_LPN_WAIT_UPDATE: + update_timeout(lpn); + break; + default: + __ASSERT(0, "Unhandled LPN state"); + break; + } +} + +void bt_mesh_lpn_group_add(u16_t group) +{ + BT_DBG("group 0x%04x", group); + + lpn_group_add(group); + + if (!bt_mesh_lpn_established() || bt_mesh.lpn.sent_req) { + return; + } + + sub_update(TRANS_CTL_OP_FRIEND_SUB_ADD); +} + +void bt_mesh_lpn_group_del(u16_t *groups, size_t group_count) +{ + int i; + + for (i = 0; i < group_count; i++) { + if (groups[i] != BT_MESH_ADDR_UNASSIGNED) { + BT_DBG("group 0x%04x", groups[i]); + lpn_group_del(groups[i]); + } + } + + if (!bt_mesh_lpn_established() || bt_mesh.lpn.sent_req) { + return; + } + + sub_update(TRANS_CTL_OP_FRIEND_SUB_REM); +} + +static s32_t poll_timeout(struct bt_mesh_lpn *lpn) +{ + /* If we're waiting for segment acks keep polling at high freq */ + if (bt_mesh_tx_in_progress()) { + return min(POLL_TIMEOUT_MAX(lpn), K_SECONDS(1)); + } + + if (lpn->poll_timeout < POLL_TIMEOUT_MAX(lpn)) { + lpn->poll_timeout *= 2; + lpn->poll_timeout = min(lpn->poll_timeout, + POLL_TIMEOUT_MAX(lpn)); + } + + BT_DBG("Poll Timeout is %ums", (unsigned) lpn->poll_timeout); + + return lpn->poll_timeout; +} + +int bt_mesh_lpn_friend_sub_cfm(struct bt_mesh_net_rx *rx, + struct os_mbuf *buf) +{ + struct bt_mesh_ctl_friend_sub_confirm *msg = (void *)buf->om_data; + struct bt_mesh_lpn *lpn = &bt_mesh.lpn; + + if (buf->om_len < sizeof(*msg)) { + BT_WARN("Too short Friend Subscription Confirm"); + return -EINVAL; + } + + BT_DBG("xact 0x%02x", msg->xact); + + if (!lpn->sent_req) { + BT_WARN("No pending subscription list message"); + return 0; + } + + if (msg->xact != lpn->xact_pending) { + BT_WARN("Transaction mismatch (0x%02x != 0x%02x)", + msg->xact, lpn->xact_pending); + return 0; + } + + if (lpn->sent_req == TRANS_CTL_OP_FRIEND_SUB_ADD) { + group_set(lpn->added, lpn->pending); + group_zero(lpn->pending); + } else if (lpn->sent_req == TRANS_CTL_OP_FRIEND_SUB_REM) { + int i; + + group_clear(lpn->added, lpn->pending); + + for (i = 0; i < ARRAY_SIZE(lpn->groups); i++) { + if (atomic_test_and_clear_bit(lpn->pending, i) && + atomic_test_and_clear_bit(lpn->to_remove, i)) { + lpn->groups[i] = BT_MESH_ADDR_UNASSIGNED; + } + } + } else { + BT_WARN("Unexpected Friend Subscription Confirm"); + return 0; + } + + friend_response_received(lpn); + + if (lpn->groups_changed) { + sub_update(TRANS_CTL_OP_FRIEND_SUB_ADD); + sub_update(TRANS_CTL_OP_FRIEND_SUB_REM); + + if (!lpn->sent_req) { + lpn->groups_changed = 0; + } + } + + if (lpn->pending_poll) { + send_friend_poll(); + } + + if (!lpn->sent_req) { + k_delayed_work_submit(&lpn->timer, poll_timeout(lpn)); + } + + return 0; +} + +int bt_mesh_lpn_friend_update(struct bt_mesh_net_rx *rx, + struct os_mbuf *buf) +{ + struct bt_mesh_ctl_friend_update *msg = (void *)buf->om_data; + struct bt_mesh_lpn *lpn = &bt_mesh.lpn; + struct bt_mesh_subnet *sub = rx->sub; + u32_t iv_index; + + if (buf->om_len < sizeof(*msg)) { + BT_WARN("Too short Friend Update"); + return -EINVAL; + } + + if (lpn->sent_req != TRANS_CTL_OP_FRIEND_POLL) { + BT_WARN("Unexpected friend update"); + return 0; + } + + if (sub->kr_phase == BT_MESH_KR_PHASE_2 && !rx->new_key) { + BT_WARN("Ignoring Phase 2 KR Update secured using old key"); + return 0; + } + + if (atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_INITIATOR) && + (atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS) == + BT_MESH_IV_UPDATE(msg->flags))) { + bt_mesh_beacon_ivu_initiator(false); + } + + if (!lpn->established) { + /* This is normally checked on the transport layer, however + * in this state we're also still accepting master + * credentials so we need to ensure the right ones (Friend + * Credentials) were used for this message. + */ + if (!rx->friend_cred) { + BT_WARN("Friend Update with wrong credentials"); + return -EINVAL; + } + + lpn->established = 1; + + BT_INFO("Friendship established with 0x%04x", lpn->frnd); + + if (lpn_cb) { + lpn_cb(lpn->frnd, true); + } + + /* Set initial poll timeout */ + lpn->poll_timeout = min(POLL_TIMEOUT_MAX(lpn), + POLL_TIMEOUT_INIT); + } + + friend_response_received(lpn); + + iv_index = sys_be32_to_cpu(msg->iv_index); + + BT_DBG("flags 0x%02x iv_index 0x%08x md %u", msg->flags, + (unsigned) iv_index, msg->md); + + if (bt_mesh_kr_update(sub, BT_MESH_KEY_REFRESH(msg->flags), + rx->new_key)) { + bt_mesh_net_beacon_update(sub); + } + + bt_mesh_net_iv_update(iv_index, BT_MESH_IV_UPDATE(msg->flags)); + + if (lpn->groups_changed) { + sub_update(TRANS_CTL_OP_FRIEND_SUB_ADD); + sub_update(TRANS_CTL_OP_FRIEND_SUB_REM); + + if (!lpn->sent_req) { + lpn->groups_changed = 0; + } + } + + if (msg->md) { + BT_DBG("Requesting for more messages"); + send_friend_poll(); + } + + if (!lpn->sent_req) { + k_delayed_work_submit(&lpn->timer, poll_timeout(lpn)); + } + + return 0; +} + +int bt_mesh_lpn_poll(void) +{ + if (!bt_mesh.lpn.established) { + return -EAGAIN; + } + + BT_DBG("Requesting more messages"); + + return send_friend_poll(); +} + +void bt_mesh_lpn_set_cb(void (*cb)(u16_t friend_addr, bool established)) +{ + lpn_cb = cb; +} + +int bt_mesh_lpn_init(void) +{ + struct bt_mesh_lpn *lpn = &bt_mesh.lpn; + + BT_DBG(""); + + k_delayed_work_init(&lpn->timer, lpn_timeout); + + if (lpn->state == BT_MESH_LPN_ENABLED) { + if (IS_ENABLED(CONFIG_BT_MESH_LPN_ESTABLISHMENT)) { + bt_mesh_scan_disable(); + } else { + bt_mesh_scan_enable(); + } + + send_friend_req(lpn); + } else { + bt_mesh_scan_enable(); + + if (IS_ENABLED(CONFIG_BT_MESH_LPN_AUTO)) { + BT_DBG("Waiting %u ms for messages", LPN_AUTO_TIMEOUT); + lpn_set_state(BT_MESH_LPN_TIMER); + k_delayed_work_submit(&lpn->timer, LPN_AUTO_TIMEOUT); + } + } + + return 0; +} + +#endif /* MYNEWT_VAL(BLE_MESH_LOW_POWER) */ diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/lpn.h b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/lpn.h new file mode 100644 index 000000000..0ff6c9cfd --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/lpn.h @@ -0,0 +1,68 @@ +/* Bluetooth Mesh */ + +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef __LPN_H__ +#define __LPN_H__ + +#include "mesh/mesh.h" + +int bt_mesh_lpn_friend_update(struct bt_mesh_net_rx *rx, + struct os_mbuf *buf); +int bt_mesh_lpn_friend_offer(struct bt_mesh_net_rx *rx, + struct os_mbuf *buf); +int bt_mesh_lpn_friend_clear_cfm(struct bt_mesh_net_rx *rx, + struct os_mbuf *buf); +int bt_mesh_lpn_friend_sub_cfm(struct bt_mesh_net_rx *rx, + struct os_mbuf *buf); + +static inline bool bt_mesh_lpn_established(void) +{ +#if (MYNEWT_VAL(BLE_MESH_LOW_POWER)) + return bt_mesh.lpn.established; +#else + return false; +#endif +} + +static inline bool bt_mesh_lpn_match(u16_t addr) +{ +#if (MYNEWT_VAL(BLE_MESH_LOW_POWER)) + if (bt_mesh_lpn_established()) { + return (addr == bt_mesh.lpn.frnd); + } +#endif + return false; +} + +static inline bool bt_mesh_lpn_waiting_update(void) +{ +#if (MYNEWT_VAL(BLE_MESH_LOW_POWER)) + return (bt_mesh.lpn.state == BT_MESH_LPN_WAIT_UPDATE); +#else + return false; +#endif +} + +static inline bool bt_mesh_lpn_timer(void) +{ +#if MYNEWT_VAL(BLE_MESH_LOW_POWER) && MYNEWT_VAL(BLE_MESH_LPN_AUTO) + return (bt_mesh.lpn.state == BT_MESH_LPN_TIMER); +#else + return false; +#endif +} + +void bt_mesh_lpn_msg_received(struct bt_mesh_net_rx *rx); + +void bt_mesh_lpn_group_add(u16_t group); +void bt_mesh_lpn_group_del(u16_t *groups, size_t group_count); + +void bt_mesh_lpn_disable(bool force); + +int bt_mesh_lpn_init(void); + +#endif diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/mesh.c b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/mesh.c new file mode 100644 index 000000000..80b638b1f --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/mesh.c @@ -0,0 +1,345 @@ +/* Bluetooth Mesh */ + +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include "os/os_mbuf.h" +#include "mesh/mesh.h" + +#include "syscfg/syscfg.h" +#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG)) +#include "host/ble_hs_log.h" +#include "host/ble_uuid.h" + +#include "adv.h" +#include "prov.h" +#include "net.h" +#include "beacon.h" +#include "lpn.h" +#include "friend.h" +#include "transport.h" +#include "access.h" +#include "foundation.h" +#include "proxy.h" +#include "shell.h" +#include "mesh_priv.h" +#include "settings.h" + +u8_t g_mesh_addr_type; +static struct ble_gap_event_listener mesh_event_listener; + +int bt_mesh_provision(const u8_t net_key[16], u16_t net_idx, + u8_t flags, u32_t iv_index, u16_t addr, + const u8_t dev_key[16]) +{ + bool pb_gatt_enabled; + int err; + + BT_INFO("Primary Element: 0x%04x", addr); + BT_DBG("net_idx 0x%04x flags 0x%02x iv_index 0x%04x", + net_idx, flags, (unsigned) iv_index); + + if (atomic_test_and_set_bit(bt_mesh.flags, BT_MESH_VALID)) { + return -EALREADY; + } + + if ((MYNEWT_VAL(BLE_MESH_PB_GATT))) { + if (bt_mesh_proxy_prov_disable() == 0) { + pb_gatt_enabled = true; + } else { + pb_gatt_enabled = false; + } + } else { + pb_gatt_enabled = false; + } + + err = bt_mesh_net_create(net_idx, flags, net_key, iv_index); + if (err) { + atomic_clear_bit(bt_mesh.flags, BT_MESH_VALID); + + if (MYNEWT_VAL(BLE_MESH_PB_GATT) && pb_gatt_enabled) { + bt_mesh_proxy_prov_enable(); + } + + return err; + } + + bt_mesh.seq = 0; + + bt_mesh_comp_provision(addr); + + memcpy(bt_mesh.dev_key, dev_key, 16); + + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + BT_DBG("Storing network information persistently"); + bt_mesh_store_net(); + bt_mesh_store_subnet(&bt_mesh.sub[0]); + bt_mesh_store_iv(false); + } + + bt_mesh_net_start(); + + return 0; +} + +void bt_mesh_reset(void) +{ + if (!atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) { + return; + } + + bt_mesh.iv_index = 0U; + bt_mesh.seq = 0U; + + memset(bt_mesh.flags, 0, sizeof(bt_mesh.flags)); + + k_delayed_work_cancel(&bt_mesh.ivu_timer); + + bt_mesh_cfg_reset(); + + bt_mesh_rx_reset(); + bt_mesh_tx_reset(); + + if ((MYNEWT_VAL(BLE_MESH_LOW_POWER))) { + bt_mesh_lpn_disable(true); + } + + if ((MYNEWT_VAL(BLE_MESH_FRIEND))) { + bt_mesh_friend_clear_net_idx(BT_MESH_KEY_ANY); + } + + if ((MYNEWT_VAL(BLE_MESH_GATT_PROXY))) { + bt_mesh_proxy_gatt_disable(); + } + + if ((MYNEWT_VAL(BLE_MESH_PB_GATT))) { + bt_mesh_proxy_prov_enable(); + } + + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + bt_mesh_clear_net(); + } + + memset(bt_mesh.dev_key, 0, sizeof(bt_mesh.dev_key)); + + bt_mesh_scan_disable(); + bt_mesh_beacon_disable(); + + bt_mesh_comp_unprovision(); + + if (IS_ENABLED(CONFIG_BT_MESH_PROV)) { + bt_mesh_prov_reset(); + } +} + +bool bt_mesh_is_provisioned(void) +{ + return atomic_test_bit(bt_mesh.flags, BT_MESH_VALID); +} + +int bt_mesh_prov_enable(bt_mesh_prov_bearer_t bearers) +{ + if (bt_mesh_is_provisioned()) { + return -EALREADY; + } + + if (MYNEWT_VAL(BLE_MESH_DEBUG)) { + char uuid_buf[BLE_UUID_STR_LEN]; + const struct bt_mesh_prov *prov = bt_mesh_prov_get(); + ble_uuid_t *uuid = BLE_UUID128_DECLARE(); + + memcpy(BLE_UUID128(uuid)->value, prov->uuid, 16); + BT_INFO("Device UUID: %s", ble_uuid_to_str(uuid, uuid_buf)); + } + + if (IS_ENABLED(CONFIG_BT_MESH_PB_ADV) && + (bearers & BT_MESH_PROV_ADV)) { + /* Make sure we're scanning for provisioning inviations */ + bt_mesh_scan_enable(); + /* Enable unprovisioned beacon sending */ + bt_mesh_beacon_enable(); + } + + if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT) && + (bearers & BT_MESH_PROV_GATT)) { + bt_mesh_proxy_prov_enable(); + bt_mesh_adv_update(); + } + + return 0; +} + +int bt_mesh_prov_disable(bt_mesh_prov_bearer_t bearers) +{ + if (bt_mesh_is_provisioned()) { + return -EALREADY; + } + + if (IS_ENABLED(CONFIG_BT_MESH_PB_ADV) && + (bearers & BT_MESH_PROV_ADV)) { + bt_mesh_beacon_disable(); + bt_mesh_scan_disable(); + } + + if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT) && + (bearers & BT_MESH_PROV_GATT)) { + bt_mesh_proxy_prov_disable(); + bt_mesh_adv_update(); + } + + return 0; +} + +static int bt_mesh_gap_event(struct ble_gap_event *event, void *arg) +{ + ble_adv_gap_mesh_cb(event, arg); + +#if (MYNEWT_VAL(BLE_MESH_PROXY)) + ble_mesh_proxy_gap_event(event, arg); +#endif + + return 0; +} + +static void model_suspend(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, + bool vnd, bool primary, void *user_data) +{ + if (mod->pub && mod->pub->update) { + mod->pub->count = 0; + k_delayed_work_cancel(&mod->pub->timer); + } +} + +int bt_mesh_suspend(void) +{ + int err; + + if (!atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) { + return -EINVAL; + } + + if (atomic_test_and_set_bit(bt_mesh.flags, BT_MESH_SUSPENDED)) { + return -EALREADY; + } + + err = bt_mesh_scan_disable(); + if (err) { + atomic_clear_bit(bt_mesh.flags, BT_MESH_SUSPENDED); + BT_WARN("Disabling scanning failed (err %d)", err); + return err; + } + + bt_mesh_hb_pub_disable(); + + if (bt_mesh_beacon_get() == BT_MESH_BEACON_ENABLED) { + bt_mesh_beacon_disable(); + } + + bt_mesh_model_foreach(model_suspend, NULL); + + return 0; +} + +static void model_resume(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, + bool vnd, bool primary, void *user_data) +{ + if (mod->pub && mod->pub->update) { + s32_t period_ms = bt_mesh_model_pub_period_get(mod); + + if (period_ms) { + k_delayed_work_submit(&mod->pub->timer, period_ms); + } + } +} + +int bt_mesh_resume(void) +{ + int err; + + if (!atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) { + return -EINVAL; + } + + if (!atomic_test_and_clear_bit(bt_mesh.flags, BT_MESH_SUSPENDED)) { + return -EALREADY; + } + + err = bt_mesh_scan_enable(); + if (err) { + BT_WARN("Re-enabling scanning failed (err %d)", err); + atomic_set_bit(bt_mesh.flags, BT_MESH_SUSPENDED); + return err; + } + + if (bt_mesh_beacon_get() == BT_MESH_BEACON_ENABLED) { + bt_mesh_beacon_enable(); + } + + bt_mesh_model_foreach(model_resume, NULL); + + return err; +} + +int bt_mesh_init(uint8_t own_addr_type, const struct bt_mesh_prov *prov, + const struct bt_mesh_comp *comp) +{ + int err; + + g_mesh_addr_type = own_addr_type; + + /* initialize SM alg ECC subsystem (it is used directly from mesh code) */ + ble_sm_alg_ecc_init(); + + err = bt_mesh_comp_register(comp); + if (err) { + return err; + } + +#if (MYNEWT_VAL(BLE_MESH_PROV)) + err = bt_mesh_prov_init(prov); + if (err) { + return err; + } +#endif + +#if (MYNEWT_VAL(BLE_MESH_PROXY)) + bt_mesh_proxy_init(); +#endif + +#if (MYNEWT_VAL(BLE_MESH_PROV)) + /* Need this to proper link.rx.buf allocation */ + bt_mesh_prov_reset_link(); +#endif + + bt_mesh_net_init(); + bt_mesh_trans_init(); + bt_mesh_beacon_init(); + bt_mesh_adv_init(); + +#if (MYNEWT_VAL(BLE_MESH_PB_ADV)) + /* Make sure we're scanning for provisioning inviations */ + bt_mesh_scan_enable(); + /* Enable unprovisioned beacon sending */ + + bt_mesh_beacon_enable(); +#endif + +#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) + bt_mesh_proxy_prov_enable(); +#endif + + ble_gap_event_listener_register(&mesh_event_listener, + bt_mesh_gap_event, NULL); + +#if (MYNEWT_VAL(BLE_MESH_SETTINGS)) + bt_mesh_settings_init(); +#endif + + return 0; +} diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/mesh_priv.h b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/mesh_priv.h new file mode 100644 index 000000000..0a26c903b --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/mesh_priv.h @@ -0,0 +1,38 @@ +/* Bluetooth Mesh */ + +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef __MESH_PRIV_H +#define __MESH_PRIV_H + +#define BT_MESH_KEY_PRIMARY 0x0000 +#define BT_MESH_KEY_ANY 0xffff + +#define BT_MESH_ADDR_IS_UNICAST(addr) ((addr) && (addr) < 0x8000) +#define BT_MESH_ADDR_IS_GROUP(addr) ((addr) >= 0xc000 && (addr) <= 0xff00) +#define BT_MESH_ADDR_IS_VIRTUAL(addr) ((addr) >= 0x8000 && (addr) < 0xc000) +#define BT_MESH_ADDR_IS_RFU(addr) ((addr) >= 0xff00 && (addr) <= 0xfffb) +struct bt_mesh_net; + +#define OP_GEN_ONOFF_GET BT_MESH_MODEL_OP_2(0x82, 0x01) +#define OP_GEN_ONOFF_SET BT_MESH_MODEL_OP_2(0x82, 0x02) +#define OP_GEN_ONOFF_SET_UNACK BT_MESH_MODEL_OP_2(0x82, 0x03) +#define OP_GEN_ONOFF_STATUS BT_MESH_MODEL_OP_2(0x82, 0x04) +#define OP_GEN_LEVEL_GET BT_MESH_MODEL_OP_2(0x82, 0x05) +#define OP_GEN_LEVEL_SET BT_MESH_MODEL_OP_2(0x82, 0x06) +#define OP_GEN_LEVEL_SET_UNACK BT_MESH_MODEL_OP_2(0x82, 0x07) +#define OP_GEN_LEVEL_STATUS BT_MESH_MODEL_OP_2(0x82, 0x08) +#define OP_GEN_DELTA_SET BT_MESH_MODEL_OP_2(0x82, 0x09) +#define OP_GEN_DELTA_SET_UNACK BT_MESH_MODEL_OP_2(0x82, 0x0a) +#define OP_GEN_MOVE_SET BT_MESH_MODEL_OP_2(0x82, 0x0b) +#define OP_GEN_MOVE_SET_UNACK BT_MESH_MODEL_OP_2(0x82, 0x0c) +#define OP_LIGHT_LIGHTNESS_GET BT_MESH_MODEL_OP_2(0x82, 0x4b) +#define OP_LIGHT_LIGHTNESS_SET BT_MESH_MODEL_OP_2(0x82, 0x4c) +#define OP_LIGHT_LIGHTNESS_SET_UNACK BT_MESH_MODEL_OP_2(0x82, 0x4d) + +bool bt_mesh_is_provisioned(void); + +#endif diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/model_cli.c b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/model_cli.c new file mode 100644 index 000000000..c9e9cf622 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/model_cli.c @@ -0,0 +1,276 @@ +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG_MODEL)) +#include "mesh/model_cli.h" +#include "mesh_priv.h" + +static s32_t msg_timeout = K_SECONDS(5); + +struct bt_mesh_gen_model_cli gen_onoff_cli; +struct bt_mesh_gen_model_cli gen_level_cli; + +static u8_t transaction_id = 0; + +struct gen_onoff_param { + u8_t *state; +}; + +struct gen_level_param { + s16_t *level; +}; + +static void gen_onoff_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct bt_mesh_gen_model_cli *cli = model->user_data; + struct gen_onoff_param *param; + u8_t state; + + + BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); + + if (cli->op_pending != OP_GEN_ONOFF_STATUS) { + BT_WARN("Unexpected Generic OnOff Status message"); + return; + } + + param = cli->op_param; + + state = net_buf_simple_pull_u8(buf); + if (param->state) { + *param->state = state; + } + + BT_DBG("state: %d", state); + + k_sem_give(&cli->op_sync); +} + +static void gen_level_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct bt_mesh_gen_model_cli *cli = model->user_data; + struct gen_level_param *param; + s16_t level; + + + BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", + ctx->net_idx, ctx->app_idx, ctx->addr, buf->om_len, + bt_hex(buf->om_data, buf->om_len)); + + if (cli->op_pending != OP_GEN_LEVEL_STATUS) { + BT_WARN("Unexpected Generic LEVEL Status message"); + return; + } + + param = cli->op_param; + + level = net_buf_simple_pull_le16(buf); + if (param->level) { + *param->level = level; + } + + BT_DBG("level: %d", level); + + k_sem_give(&cli->op_sync); +} + +const struct bt_mesh_model_op gen_onoff_cli_op[] = { + { OP_GEN_ONOFF_STATUS, 1, gen_onoff_status }, + BT_MESH_MODEL_OP_END, +}; + +const struct bt_mesh_model_op gen_level_cli_op[] = { + { OP_GEN_LEVEL_STATUS, 2, gen_level_status }, + BT_MESH_MODEL_OP_END, +}; + +static int cli_wait(struct bt_mesh_gen_model_cli *cli, void *param, u32_t op) +{ + int err; + + BT_DBG(""); + + cli->op_param = param; + cli->op_pending = op; + + err = k_sem_take(&cli->op_sync, msg_timeout); + + cli->op_pending = 0; + cli->op_param = NULL; + + return err; +} + +int bt_mesh_gen_onoff_get(u16_t net_idx, u16_t addr, u16_t app_idx, + u8_t *state) +{ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 0 + 4); + struct bt_mesh_msg_ctx ctx = { + .net_idx = net_idx, + .app_idx = app_idx, + .addr = addr, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; + struct gen_onoff_param param = { + .state = state, + }; + int err; + + bt_mesh_model_msg_init(msg, OP_GEN_ONOFF_GET); + + err = bt_mesh_model_send(gen_onoff_cli.model, &ctx, msg, NULL, NULL); + if (err) { + BT_ERR("model_send() failed (err %d)", err); + goto done; + } + + err = cli_wait(&gen_onoff_cli, ¶m, OP_GEN_ONOFF_STATUS); +done: + os_mbuf_free_chain(msg); + return err; +} + +int bt_mesh_gen_onoff_set(u16_t net_idx, u16_t addr, u16_t app_idx, + u8_t val, u8_t *state) +{ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 2 + 4); + struct bt_mesh_msg_ctx ctx = { + .net_idx = net_idx, + .app_idx = app_idx, + .addr = addr, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; + struct gen_onoff_param param = { + .state = state, + }; + int err; + + if (state) { + bt_mesh_model_msg_init(msg, OP_GEN_ONOFF_SET); + } else { + bt_mesh_model_msg_init(msg, OP_GEN_ONOFF_SET_UNACK); + } + + net_buf_simple_add_u8(msg, val); + net_buf_simple_add_u8(msg, transaction_id); + + err = bt_mesh_model_send(gen_onoff_cli.model, &ctx, msg, NULL, NULL); + if (err) { + BT_ERR("model_send() failed (err %d)", err); + goto done; + } + + if (!state) { + goto done; + } + + err = cli_wait(&gen_onoff_cli, ¶m, OP_GEN_ONOFF_STATUS); +done: + if (err == 0) { + transaction_id++; + } + os_mbuf_free_chain(msg); + return err; +} + +int bt_mesh_gen_level_get(u16_t net_idx, u16_t addr, u16_t app_idx, + s16_t *level) +{ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 0 + 4); + struct bt_mesh_msg_ctx ctx = { + .net_idx = net_idx, + .app_idx = app_idx, + .addr = addr, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; + struct gen_level_param param = { + .level = level, + }; + int err; + + bt_mesh_model_msg_init(msg, OP_GEN_LEVEL_GET); + + err = bt_mesh_model_send(gen_level_cli.model, &ctx, msg, NULL, NULL); + if (err) { + BT_ERR("model_send() failed (err %d)", err); + goto done; + } + + err = cli_wait(&gen_level_cli, ¶m, OP_GEN_LEVEL_STATUS); +done: + os_mbuf_free_chain(msg); + return err; +} + +int bt_mesh_gen_level_set(u16_t net_idx, u16_t addr, u16_t app_idx, + s16_t val, s16_t *state) +{ + struct os_mbuf *msg = NET_BUF_SIMPLE(2 + 3 + 4); + struct bt_mesh_msg_ctx ctx = { + .net_idx = net_idx, + .app_idx = app_idx, + .addr = addr, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; + struct gen_level_param param = { + .level = state, + }; + int err; + + if (state) { + bt_mesh_model_msg_init(msg, OP_GEN_LEVEL_SET); + } else { + bt_mesh_model_msg_init(msg, OP_GEN_LEVEL_SET_UNACK); + } + + net_buf_simple_add_le16(msg, val); + net_buf_simple_add_u8(msg, transaction_id); + + err = bt_mesh_model_send(gen_level_cli.model, &ctx, msg, NULL, NULL); + if (err) { + BT_ERR("model_send() failed (err %d)", err); + goto done; + } + + if (!state) { + goto done; + } + + err = cli_wait(&gen_level_cli, ¶m, OP_GEN_LEVEL_STATUS); +done: + if (err == 0) { + transaction_id++; + } + os_mbuf_free_chain(msg); + return err; +} + +int bt_mesh_gen_model_cli_init(struct bt_mesh_model *model, bool primary) +{ + struct bt_mesh_gen_model_cli *cli = model->user_data; + + BT_DBG("primary %u", primary); + + if (!cli) { + BT_ERR("No Generic Model Client context provided"); + return -EINVAL; + } + + cli->model = model; + + k_sem_init(&cli->op_sync, 0, 1); + + return 0; +} + diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/model_srv.c b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/model_srv.c new file mode 100644 index 000000000..1420b1ccc --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/model_srv.c @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "mesh/mesh.h" + +#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG_MODEL)) + +#include "mesh/model_srv.h" +#include "mesh_priv.h" + +static void gen_onoff_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx) +{ + struct bt_mesh_gen_onoff_srv_cb *cb = model->user_data; + struct os_mbuf *msg = NET_BUF_SIMPLE(3); + u8_t *state; + + bt_mesh_model_msg_init(msg, OP_GEN_ONOFF_STATUS); + state = net_buf_simple_add(msg, 1); + if (cb && cb->get) { + cb->get(model, state); + } + + BT_DBG("state: %d", *state); + + if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + BT_ERR("Send status failed"); + } + + os_mbuf_free_chain(msg); +} + +static void gen_onoff_get(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + BT_DBG(""); + + gen_onoff_status(model, ctx); +} + +static void gen_onoff_set_unack(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + struct bt_mesh_gen_onoff_srv_cb *cb = model->user_data; + u8_t state; + + state = buf->om_data[0]; + + BT_DBG("state: %d", state); + + if (cb && cb->set) { + cb->set(model, state); + } +} + +static void gen_onoff_set(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + BT_DBG(""); + + gen_onoff_set_unack(model, ctx, buf); + gen_onoff_status(model, ctx); +} + +static void gen_level_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx) +{ + struct bt_mesh_gen_level_srv_cb *cb = model->user_data; + struct os_mbuf *msg = NET_BUF_SIMPLE(4); + s16_t *level; + + bt_mesh_model_msg_init(msg, OP_GEN_LEVEL_STATUS); + level = net_buf_simple_add(msg, 2); + if (cb && cb->get) { + cb->get(model, level); + } + + BT_DBG("level: %d", *level); + + if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + BT_ERR("Send status failed"); + } + + os_mbuf_free_chain(msg); +} + +static void gen_level_get(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + BT_DBG(""); + + gen_level_status(model, ctx); +} + +static void gen_level_set_unack(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { + struct bt_mesh_gen_level_srv_cb *cb = model->user_data; + s16_t level; + + level = (s16_t) net_buf_simple_pull_le16(buf); + BT_DBG("level: %d", level); + + if (cb && cb->set) { + cb->set(model, level); + } +} + +static void gen_level_set(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + gen_level_set_unack(model, ctx, buf); + gen_level_status(model, ctx); +} + +static void light_lightness_status(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx) +{ + struct bt_mesh_light_lightness_srv_cb *cb = model->user_data; + struct os_mbuf *msg = NET_BUF_SIMPLE(4); + s16_t *lightness; + + bt_mesh_model_msg_init(msg, OP_GEN_LEVEL_STATUS); + lightness = net_buf_simple_add(msg, 2); + if (cb && cb->get) { + cb->get(model, lightness); + } + + BT_DBG("lightness: %d", *lightness); + + if (bt_mesh_model_send(model, ctx, msg, NULL, NULL)) { + BT_ERR("Send status failed"); + } + + os_mbuf_free_chain(msg); +} + +static void light_lightness_get(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + BT_DBG(""); + + light_lightness_status(model, ctx); +} + +static void light_lightness_set_unack(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) { + struct bt_mesh_light_lightness_srv_cb *cb = model->user_data; + s16_t lightness; + + lightness = (s16_t) net_buf_simple_pull_le16(buf); + BT_DBG("lightness: %d", lightness); + + if (cb && cb->set) { + cb->set(model, lightness); + } +} + +static void light_lightness_set(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct os_mbuf *buf) +{ + light_lightness_set_unack(model, ctx, buf); + light_lightness_status(model, ctx); +} + +const struct bt_mesh_model_op gen_onoff_srv_op[] = { + { OP_GEN_ONOFF_GET, 0, gen_onoff_get }, + { OP_GEN_ONOFF_SET, 2, gen_onoff_set }, + { OP_GEN_ONOFF_SET_UNACK, 2, gen_onoff_set_unack }, + BT_MESH_MODEL_OP_END, +}; + +const struct bt_mesh_model_op gen_level_srv_op[] = { + { OP_GEN_LEVEL_GET, 0, gen_level_get }, + { OP_GEN_LEVEL_SET, 3, gen_level_set }, + { OP_GEN_LEVEL_SET_UNACK, 3, gen_level_set_unack }, + BT_MESH_MODEL_OP_END, +}; + +const struct bt_mesh_model_op light_lightness_srv_op[] = { + { OP_LIGHT_LIGHTNESS_GET, 0, light_lightness_get }, + { OP_LIGHT_LIGHTNESS_SET, 3, light_lightness_set }, + { OP_LIGHT_LIGHTNESS_SET_UNACK, 3, light_lightness_set_unack }, + BT_MESH_MODEL_OP_END, +}; diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/net.c b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/net.c new file mode 100644 index 000000000..455893354 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/net.c @@ -0,0 +1,1410 @@ +/* Bluetooth Mesh */ + +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include "os/os_mbuf.h" +#include "mesh/mesh.h" + +#include "syscfg/syscfg.h" +#define BT_DBG_ENABLED MYNEWT_VAL(BLE_MESH_DEBUG_NET) +#include "host/ble_hs_log.h" + +#include "crypto.h" +#include "adv.h" +#include "mesh_priv.h" +#include "net.h" +#include "lpn.h" +#include "friend.h" +#include "proxy.h" +#include "transport.h" +#include "access.h" +#include "foundation.h" +#include "beacon.h" +#include "settings.h" +#include "prov.h" + +/* Minimum valid Mesh Network PDU length. The Network headers + * themselves take up 9 bytes. After that there is a minumum of 1 byte + * payload for both CTL=1 and CTL=0 PDUs (smallest OpCode is 1 byte). CTL=1 + * PDUs must use a 64-bit (8 byte) NetMIC, whereas CTL=0 PDUs have at least + * a 32-bit (4 byte) NetMIC and AppMIC giving again a total of 8 bytes. + */ +#define BT_MESH_NET_MIN_PDU_LEN (BT_MESH_NET_HDR_LEN + 1 + 8) + +/* Seq limit after IV Update is triggered */ +#define IV_UPDATE_SEQ_LIMIT 8000000 + +#define IVI(pdu) ((pdu)[0] >> 7) +#define NID(pdu) ((pdu)[0] & 0x7f) +#define CTL(pdu) ((pdu)[1] >> 7) +#define TTL(pdu) ((pdu)[1] & 0x7f) +#define SEQ(pdu) (((u32_t)(pdu)[2] << 16) | \ + ((u32_t)(pdu)[3] << 8) | (u32_t)(pdu)[4]); +#define SRC(pdu) (sys_get_be16(&(pdu)[5])) +#define DST(pdu) (sys_get_be16(&(pdu)[7])) + +/* Determine how many friendship credentials we need */ +#if (MYNEWT_VAL(BLE_MESH_FRIEND)) +#define FRIEND_CRED_COUNT MYNEWT_VAL(BLE_MESH_FRIEND_LPN_COUNT) +#elif (MYNEWT_VAL(BLE_MESH_LOW_POWER)) +#define FRIEND_CRED_COUNT MYNEWT_VAL(BLE_MESH_SUBNET_COUNT) +#else +#define FRIEND_CRED_COUNT 0 +#endif + +#if FRIEND_CRED_COUNT > 0 +static struct friend_cred friend_cred[FRIEND_CRED_COUNT]; +#endif + +static u64_t msg_cache[MYNEWT_VAL(BLE_MESH_MSG_CACHE_SIZE)]; +static u16_t msg_cache_next; + +/* Singleton network context (the implementation only supports one) */ +struct bt_mesh_net bt_mesh = { + .local_queue = STAILQ_HEAD_INITIALIZER(bt_mesh.local_queue), + .sub = { + [0 ... (MYNEWT_VAL(BLE_MESH_SUBNET_COUNT) - 1)] = { + .net_idx = BT_MESH_KEY_UNUSED, + } + }, + .app_keys = { + [0 ... (MYNEWT_VAL(BLE_MESH_APP_KEY_COUNT) - 1)] = { + .net_idx = BT_MESH_KEY_UNUSED, + } + }, +}; + +static u32_t dup_cache[4]; +static int dup_cache_next; + +static bool check_dup(struct os_mbuf *data) +{ + const u8_t *tail = net_buf_simple_tail(data); + u32_t val; + int i; + + val = sys_get_be32(tail - 4) ^ sys_get_be32(tail - 8); + + for (i = 0; i < ARRAY_SIZE(dup_cache); i++) { + if (dup_cache[i] == val) { + return true; + } + } + + dup_cache[dup_cache_next++] = val; + dup_cache_next %= ARRAY_SIZE(dup_cache); + + return false; +} + +static u64_t msg_hash(struct bt_mesh_net_rx *rx, struct os_mbuf *pdu) +{ + u32_t hash1, hash2; + + /* Three least significant bytes of IVI + first byte of SEQ */ + hash1 = (BT_MESH_NET_IVI_RX(rx) << 8) | pdu->om_data[2]; + + /* Two last bytes of SEQ + SRC */ + memcpy(&hash2, &pdu->om_data[3], 4); + + return (u64_t)hash1 << 32 | (u64_t)hash2; +} + +static bool msg_cache_match(struct bt_mesh_net_rx *rx, + struct os_mbuf *pdu) +{ + u64_t hash = msg_hash(rx, pdu); + u16_t i; + + for (i = 0; i < ARRAY_SIZE(msg_cache); i++) { + if (msg_cache[i] == hash) { + return true; + } + } + + /* Add to the cache */ + msg_cache[msg_cache_next++] = hash; + msg_cache_next %= ARRAY_SIZE(msg_cache); + + return false; +} + +struct bt_mesh_subnet *bt_mesh_subnet_get(u16_t net_idx) +{ + int i; + + if (net_idx == BT_MESH_KEY_ANY) { + return &bt_mesh.sub[0]; + } + + for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) { + if (bt_mesh.sub[i].net_idx == net_idx) { + return &bt_mesh.sub[i]; + } + } + + return NULL; +} + +int bt_mesh_net_keys_create(struct bt_mesh_subnet_keys *keys, + const u8_t key[16]) +{ + u8_t p[] = { 0 }; + u8_t nid; + int err; + + err = bt_mesh_k2(key, p, sizeof(p), &nid, keys->enc, keys->privacy); + if (err) { + BT_ERR("Unable to generate NID, EncKey & PrivacyKey"); + return err; + } + + memcpy(keys->net, key, 16); + + keys->nid = nid; + + BT_DBG("NID 0x%02x EncKey %s", keys->nid, bt_hex(keys->enc, 16)); + BT_DBG("PrivacyKey %s", bt_hex(keys->privacy, 16)); + + err = bt_mesh_k3(key, keys->net_id); + if (err) { + BT_ERR("Unable to generate Net ID"); + return err; + } + + BT_DBG("NetID %s", bt_hex(keys->net_id, 8)); + +#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) + err = bt_mesh_identity_key(key, keys->identity); + if (err) { + BT_ERR("Unable to generate IdentityKey"); + return err; + } + + BT_DBG("IdentityKey %s", bt_hex(keys->identity, 16)); +#endif /* GATT_PROXY */ + + err = bt_mesh_beacon_key(key, keys->beacon); + if (err) { + BT_ERR("Unable to generate beacon key"); + return err; + } + + BT_DBG("BeaconKey %s", bt_hex(keys->beacon, 16)); + + return 0; +} + +#if ((MYNEWT_VAL(BLE_MESH_LOW_POWER)) || \ + (MYNEWT_VAL(BLE_MESH_FRIEND))) +int friend_cred_set(struct friend_cred *cred, u8_t idx, const u8_t net_key[16]) +{ + u16_t lpn_addr, frnd_addr; + int err; + u8_t p[9]; + +#if (MYNEWT_VAL(BLE_MESH_LOW_POWER)) + if (cred->addr == bt_mesh.lpn.frnd) { + lpn_addr = bt_mesh_primary_addr(); + frnd_addr = cred->addr; + } else { + lpn_addr = cred->addr; + frnd_addr = bt_mesh_primary_addr(); + } +#else + lpn_addr = cred->addr; + frnd_addr = bt_mesh_primary_addr(); +#endif + + BT_DBG("LPNAddress 0x%04x FriendAddress 0x%04x", lpn_addr, frnd_addr); + BT_DBG("LPNCounter 0x%04x FriendCounter 0x%04x", cred->lpn_counter, + cred->frnd_counter); + + p[0] = 0x01; + sys_put_be16(lpn_addr, p + 1); + sys_put_be16(frnd_addr, p + 3); + sys_put_be16(cred->lpn_counter, p + 5); + sys_put_be16(cred->frnd_counter, p + 7); + + err = bt_mesh_k2(net_key, p, sizeof(p), &cred->cred[idx].nid, + cred->cred[idx].enc, cred->cred[idx].privacy); + if (err) { + BT_ERR("Unable to generate NID, EncKey & PrivacyKey"); + return err; + } + + BT_DBG("Friend NID 0x%02x EncKey %s", cred->cred[idx].nid, + bt_hex(cred->cred[idx].enc, 16)); + BT_DBG("Friend PrivacyKey %s", bt_hex(cred->cred[idx].privacy, 16)); + + return 0; +} + +void friend_cred_refresh(u16_t net_idx) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(friend_cred); i++) { + struct friend_cred *cred = &friend_cred[i]; + + if (cred->addr != BT_MESH_ADDR_UNASSIGNED && + cred->net_idx == net_idx) { + memcpy(&cred->cred[0], &cred->cred[1], + sizeof(cred->cred[0])); + } + } +} + +int friend_cred_update(struct bt_mesh_subnet *sub) +{ + int err, i; + + BT_DBG("net_idx 0x%04x", sub->net_idx); + + for (i = 0; i < ARRAY_SIZE(friend_cred); i++) { + struct friend_cred *cred = &friend_cred[i]; + + if (cred->addr == BT_MESH_ADDR_UNASSIGNED || + cred->net_idx != sub->net_idx) { + continue; + } + + err = friend_cred_set(cred, 1, sub->keys[1].net); + if (err) { + return err; + } + } + + return 0; +} + +struct friend_cred *friend_cred_create(struct bt_mesh_subnet *sub, u16_t addr, + u16_t lpn_counter, u16_t frnd_counter) +{ + struct friend_cred *cred; + int i, err; + + BT_DBG("net_idx 0x%04x addr 0x%04x", sub->net_idx, addr); + + for (cred = NULL, i = 0; i < ARRAY_SIZE(friend_cred); i++) { + if ((friend_cred[i].addr == BT_MESH_ADDR_UNASSIGNED) || + (friend_cred[i].addr == addr && + friend_cred[i].net_idx == sub->net_idx)) { + cred = &friend_cred[i]; + break; + } + } + + if (!cred) { + BT_WARN("No free friend credential slots"); + return NULL; + } + + cred->net_idx = sub->net_idx; + cred->addr = addr; + cred->lpn_counter = lpn_counter; + cred->frnd_counter = frnd_counter; + + err = friend_cred_set(cred, 0, sub->keys[0].net); + if (err) { + friend_cred_clear(cred); + return NULL; + } + + if (sub->kr_flag) { + err = friend_cred_set(cred, 1, sub->keys[1].net); + if (err) { + friend_cred_clear(cred); + return NULL; + } + } + + return cred; +} + +void friend_cred_clear(struct friend_cred *cred) +{ + cred->net_idx = BT_MESH_KEY_UNUSED; + cred->addr = BT_MESH_ADDR_UNASSIGNED; + cred->lpn_counter = 0; + cred->frnd_counter = 0; + memset(cred->cred, 0, sizeof(cred->cred)); +} + +int friend_cred_del(u16_t net_idx, u16_t addr) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(friend_cred); i++) { + struct friend_cred *cred = &friend_cred[i]; + + if (cred->addr == addr && cred->net_idx == net_idx) { + friend_cred_clear(cred); + return 0; + } + } + + return -ENOENT; +} + +int friend_cred_get(struct bt_mesh_subnet *sub, u16_t addr, u8_t *nid, + const u8_t **enc, const u8_t **priv) +{ + int i; + + BT_DBG("net_idx 0x%04x addr 0x%04x", sub->net_idx, addr); + + for (i = 0; i < ARRAY_SIZE(friend_cred); i++) { + struct friend_cred *cred = &friend_cred[i]; + + if (cred->net_idx != sub->net_idx) { + continue; + } + + if (addr != BT_MESH_ADDR_UNASSIGNED && cred->addr != addr) { + continue; + } + + if (nid) { + *nid = cred->cred[sub->kr_flag].nid; + } + + if (enc) { + *enc = cred->cred[sub->kr_flag].enc; + } + + if (priv) { + *priv = cred->cred[sub->kr_flag].privacy; + } + + return 0; + } + + return -ENOENT; +} +#else +int friend_cred_get(struct bt_mesh_subnet *sub, u16_t addr, u8_t *nid, + const u8_t **enc, const u8_t **priv) +{ + return -ENOENT; +} +#endif /* FRIEND || LOW_POWER */ + +u8_t bt_mesh_net_flags(struct bt_mesh_subnet *sub) +{ + u8_t flags = 0x00; + + if (sub && sub->kr_flag) { + flags |= BT_MESH_NET_FLAG_KR; + } + + if (atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS)) { + flags |= BT_MESH_NET_FLAG_IVU; + } + + return flags; +} + +int bt_mesh_net_beacon_update(struct bt_mesh_subnet *sub) +{ + u8_t flags = bt_mesh_net_flags(sub); + struct bt_mesh_subnet_keys *keys; + + if (sub->kr_flag) { + BT_DBG("NetIndex %u Using new key", sub->net_idx); + keys = &sub->keys[1]; + } else { + BT_DBG("NetIndex %u Using current key", sub->net_idx); + keys = &sub->keys[0]; + } + + BT_DBG("flags 0x%02x, IVI 0x%08x", flags, (unsigned) bt_mesh.iv_index); + + return bt_mesh_beacon_auth(keys->beacon, flags, keys->net_id, + bt_mesh.iv_index, sub->auth); +} + +int bt_mesh_net_create(u16_t idx, u8_t flags, const u8_t key[16], + u32_t iv_index) +{ + struct bt_mesh_subnet *sub; + int err; + + BT_DBG("idx %u flags 0x%02x iv_index %u", idx, flags, + (unsigned) iv_index); + + BT_DBG("NetKey %s", bt_hex(key, 16)); + + (void)memset(msg_cache, 0, sizeof(msg_cache)); + msg_cache_next = 0U; + + sub = &bt_mesh.sub[0]; + + sub->kr_flag = BT_MESH_KEY_REFRESH(flags); + if (sub->kr_flag) { + err = bt_mesh_net_keys_create(&sub->keys[1], key); + if (err) { + return -EIO; + } + + sub->kr_phase = BT_MESH_KR_PHASE_2; + } else { + err = bt_mesh_net_keys_create(&sub->keys[0], key); + if (err) { + return -EIO; + } + } + + sub->net_idx = idx; + + if ((MYNEWT_VAL(BLE_MESH_GATT_PROXY))) { + sub->node_id = BT_MESH_NODE_IDENTITY_STOPPED; + } else { + sub->node_id = BT_MESH_NODE_IDENTITY_NOT_SUPPORTED; + } + + bt_mesh.iv_index = iv_index; + atomic_set_bit_to(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS, + BT_MESH_IV_UPDATE(flags)); + + /* Set minimum required hours, since the 96-hour minimum requirement + * doesn't apply straight after provisioning (since we can't know how + * long has actually passed since the network changed its state). + */ + bt_mesh.ivu_duration = BT_MESH_IVU_MIN_HOURS; + + /* Make sure we have valid beacon data to be sent */ + bt_mesh_net_beacon_update(sub); + + return 0; +} + +void bt_mesh_net_revoke_keys(struct bt_mesh_subnet *sub) +{ + int i; + + BT_DBG("idx 0x%04x", sub->net_idx); + + memcpy(&sub->keys[0], &sub->keys[1], sizeof(sub->keys[0])); + + for (i = 0; i < ARRAY_SIZE(bt_mesh.app_keys); i++) { + struct bt_mesh_app_key *key = &bt_mesh.app_keys[i]; + + if (key->net_idx != sub->net_idx || !key->updated) { + continue; + } + + memcpy(&key->keys[0], &key->keys[1], sizeof(key->keys[0])); + key->updated = false; + } +} + +bool bt_mesh_kr_update(struct bt_mesh_subnet *sub, u8_t new_kr, bool new_key) +{ + if (new_kr != sub->kr_flag && sub->kr_phase == BT_MESH_KR_NORMAL) { + BT_WARN("KR change in normal operation. Are we blacklisted?"); + return false; + } + + sub->kr_flag = new_kr; + + if (sub->kr_flag) { + if (sub->kr_phase == BT_MESH_KR_PHASE_1) { + BT_DBG("Phase 1 -> Phase 2"); + sub->kr_phase = BT_MESH_KR_PHASE_2; + return true; + } + } else { + switch (sub->kr_phase) { + case BT_MESH_KR_PHASE_1: + if (!new_key) { + /* Ignore */ + break; + } + /* Upon receiving a Secure Network beacon with the KR flag set + * to 0 using the new NetKey in Phase 1, the node shall + * immediately transition to Phase 3, which effectively skips + * Phase 2. + * + */ + /* falls through */ + case BT_MESH_KR_PHASE_2: + BT_DBG("KR Phase 0x%02x -> Normal", sub->kr_phase); + bt_mesh_net_revoke_keys(sub); + if ((MYNEWT_VAL(BLE_MESH_LOW_POWER)) || + (MYNEWT_VAL(BLE_MESH_FRIEND))) { + friend_cred_refresh(sub->net_idx); + } + sub->kr_phase = BT_MESH_KR_NORMAL; + return true; + } + } + + return false; +} + +void bt_mesh_rpl_reset(void) +{ + int i; + + /* Discard "old old" IV Index entries from RPL and flag + * any other ones (which are valid) as old. + */ + for (i = 0; i < ARRAY_SIZE(bt_mesh.rpl); i++) { + struct bt_mesh_rpl *rpl = &bt_mesh.rpl[i]; + + if (rpl->src) { + if (rpl->old_iv) { + memset(rpl, 0, sizeof(*rpl)); + } else { + rpl->old_iv = true; + } + } + } +} + +#if MYNEWT_VAL(BLE_MESH_IV_UPDATE_TEST) +void bt_mesh_iv_update_test(bool enable) +{ + atomic_set_bit_to(bt_mesh.flags, BT_MESH_IVU_TEST, enable); + /* Reset the duration variable - needed for some PTS tests */ + bt_mesh.ivu_duration = 0; +} + +bool bt_mesh_iv_update(void) +{ + if (!bt_mesh_is_provisioned()) { + BT_ERR("Not yet provisioned"); + return false; + } + + if (atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS)) { + bt_mesh_net_iv_update(bt_mesh.iv_index, false); + } else { + bt_mesh_net_iv_update(bt_mesh.iv_index + 1, true); + } + + bt_mesh_net_sec_update(NULL); + + return atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS); +} +#endif /* CONFIG_BT_MESH_IV_UPDATE_TEST */ + +/* Used for sending immediate beacons to Friend queues and GATT clients */ +void bt_mesh_net_sec_update(struct bt_mesh_subnet *sub) +{ + if (IS_ENABLED(CONFIG_BT_MESH_FRIEND)) { + bt_mesh_friend_sec_update(sub ? sub->net_idx : BT_MESH_KEY_ANY); + } + + if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY) && + bt_mesh_gatt_proxy_get() == BT_MESH_GATT_PROXY_ENABLED) { + bt_mesh_proxy_beacon_send(sub); + } +} + +bool bt_mesh_net_iv_update(u32_t iv_index, bool iv_update) +{ + int i; + + if (atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS)) { + /* We're currently in IV Update mode */ + + if (iv_index != bt_mesh.iv_index) { + BT_WARN("IV Index mismatch: 0x%08x != 0x%08x", + (unsigned) iv_index, + (unsigned) bt_mesh.iv_index); + return false; + } + + if (iv_update) { + /* Nothing to do */ + BT_DBG("Already in IV Update in Progress state"); + return false; + } + } else { + /* We're currently in Normal mode */ + + if (iv_index == bt_mesh.iv_index) { + BT_DBG("Same IV Index in normal mode"); + return false; + } + + if (iv_index < bt_mesh.iv_index || + iv_index > bt_mesh.iv_index + 42) { + BT_ERR("IV Index out of sync: 0x%08x != 0x%08x", + (unsigned) iv_index, + (unsigned) bt_mesh.iv_index); + return false; + } + + if (iv_index > bt_mesh.iv_index + 1) { + BT_WARN("Performing IV Index Recovery"); + memset(bt_mesh.rpl, 0, sizeof(bt_mesh.rpl)); + bt_mesh.iv_index = iv_index; + bt_mesh.seq = 0; + goto do_update; + } + + if (iv_index == bt_mesh.iv_index + 1 && !iv_update) { + BT_WARN("Ignoring new index in normal mode"); + return false; + } + + if (!iv_update) { + /* Nothing to do */ + BT_DBG("Already in Normal state"); + return false; + } + } + + if (!(IS_ENABLED(CONFIG_BT_MESH_IV_UPDATE_TEST) && + atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_TEST))) { + if (bt_mesh.ivu_duration < BT_MESH_IVU_MIN_HOURS) { + BT_WARN("IV Update before minimum duration"); + return false; + } + } + + /* Defer change to Normal Operation if there are pending acks */ + if (!iv_update && bt_mesh_tx_in_progress()) { + BT_WARN("IV Update deferred because of pending transfer"); + atomic_set_bit(bt_mesh.flags, BT_MESH_IVU_PENDING); + return false; + } + +do_update: + atomic_set_bit_to(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS, iv_update); + bt_mesh.ivu_duration = 0U; + + if (iv_update) { + bt_mesh.iv_index = iv_index; + BT_DBG("IV Update state entered. New index 0x%08x", + (unsigned) bt_mesh.iv_index); + + bt_mesh_rpl_reset(); + } else { + BT_DBG("Normal mode entered"); + bt_mesh.seq = 0; + } + + k_delayed_work_submit(&bt_mesh.ivu_timer, BT_MESH_IVU_TIMEOUT); + + for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) { + if (bt_mesh.sub[i].net_idx != BT_MESH_KEY_UNUSED) { + bt_mesh_net_beacon_update(&bt_mesh.sub[i]); + } + } + + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + bt_mesh_store_iv(false); + } + + return true; +} + +u32_t bt_mesh_next_seq(void) +{ + u32_t seq = bt_mesh.seq++; + + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + bt_mesh_store_seq(); + } + + return seq; +} + +int bt_mesh_net_resend(struct bt_mesh_subnet *sub, struct os_mbuf *buf, + bool new_key, const struct bt_mesh_send_cb *cb, + void *cb_data) +{ + const u8_t *enc, *priv; + u32_t seq; + int err; + + BT_DBG("net_idx 0x%04x new_key %u len %u", sub->net_idx, new_key, + buf->om_len); + + enc = sub->keys[new_key].enc; + priv = sub->keys[new_key].privacy; + + err = bt_mesh_net_obfuscate(buf->om_data, BT_MESH_NET_IVI_TX, priv); + if (err) { + BT_ERR("deobfuscate failed (err %d)", err); + return err; + } + + err = bt_mesh_net_decrypt(enc, buf, BT_MESH_NET_IVI_TX, false); + if (err) { + BT_ERR("decrypt failed (err %d)", err); + return err; + } + + seq = bt_mesh_next_seq(); + buf->om_data[2] = seq >> 16; + buf->om_data[3] = seq >> 8; + buf->om_data[4] = seq; + + err = bt_mesh_net_encrypt(enc, buf, BT_MESH_NET_IVI_TX, false); + if (err) { + BT_ERR("encrypt failed (err %d)", err); + return err; + } + + err = bt_mesh_net_obfuscate(buf->om_data, BT_MESH_NET_IVI_TX, priv); + if (err) { + BT_ERR("obfuscate failed (err %d)", err); + return err; + } + + bt_mesh_adv_send(buf, cb, cb_data); + + if (!atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS) && + bt_mesh.seq > IV_UPDATE_SEQ_LIMIT) { + bt_mesh_beacon_ivu_initiator(true); + bt_mesh_net_iv_update(bt_mesh.iv_index + 1, true); + bt_mesh_net_sec_update(NULL); + } + + return 0; +} + +static void bt_mesh_net_local(struct ble_npl_event *work) +{ + struct os_mbuf *buf; + + while ((buf = net_buf_slist_get(&bt_mesh.local_queue))) { + BT_DBG("len %u: %s", buf->om_len, bt_hex(buf->om_data, buf->om_len)); + bt_mesh_net_recv(buf, 0, BT_MESH_NET_IF_LOCAL); + net_buf_unref(buf); + } +} + +int bt_mesh_net_encode(struct bt_mesh_net_tx *tx, struct os_mbuf *buf, + bool proxy) +{ + const bool ctl = (tx->ctx->app_idx == BT_MESH_KEY_UNUSED); + u32_t seq_val; + u8_t nid; + const u8_t *enc, *priv; + u8_t *seq; + int err; + + if (ctl && net_buf_simple_tailroom(buf) < 8) { + BT_ERR("Insufficient MIC space for CTL PDU"); + return -EINVAL; + } else if (net_buf_simple_tailroom(buf) < 4) { + BT_ERR("Insufficient MIC space for PDU"); + return -EINVAL; + } + + BT_DBG("src 0x%04x dst 0x%04x ctl %u seq 0x%06x", + tx->src, tx->ctx->addr, ctl, bt_mesh.seq); + + net_buf_simple_push_be16(buf, tx->ctx->addr); + net_buf_simple_push_be16(buf, tx->src); + + seq = net_buf_simple_push(buf, 3); + seq_val = bt_mesh_next_seq(); + seq[0] = seq_val >> 16; + seq[1] = seq_val >> 8; + seq[2] = seq_val; + + if (ctl) { + net_buf_simple_push_u8(buf, tx->ctx->send_ttl | 0x80); + } else { + net_buf_simple_push_u8(buf, tx->ctx->send_ttl); + } + + if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER) && tx->friend_cred) { + if (friend_cred_get(tx->sub, BT_MESH_ADDR_UNASSIGNED, + &nid, &enc, &priv)) { + BT_WARN("Falling back to master credentials"); + + tx->friend_cred = 0; + + nid = tx->sub->keys[tx->sub->kr_flag].nid; + enc = tx->sub->keys[tx->sub->kr_flag].enc; + priv = tx->sub->keys[tx->sub->kr_flag].privacy; + } + } else { + tx->friend_cred = 0; + nid = tx->sub->keys[tx->sub->kr_flag].nid; + enc = tx->sub->keys[tx->sub->kr_flag].enc; + priv = tx->sub->keys[tx->sub->kr_flag].privacy; + } + + net_buf_simple_push_u8(buf, (nid | (BT_MESH_NET_IVI_TX & 1) << 7)); + + err = bt_mesh_net_encrypt(enc, buf, BT_MESH_NET_IVI_TX, proxy); + if (err) { + return err; + } + + return bt_mesh_net_obfuscate(buf->om_data, BT_MESH_NET_IVI_TX, priv); +} + +int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct os_mbuf *buf, + const struct bt_mesh_send_cb *cb, void *cb_data) +{ + int err; + + BT_DBG("src 0x%04x dst 0x%04x len %u headroom %zu tailroom %zu", + tx->src, tx->ctx->addr, buf->om_len, net_buf_headroom(buf), + net_buf_tailroom(buf)); + BT_DBG("Payload len %u: %s", buf->om_len, bt_hex(buf->om_data, buf->om_len)); + BT_DBG("Seq 0x%06x", bt_mesh.seq); + + if (tx->ctx->send_ttl == BT_MESH_TTL_DEFAULT) { + tx->ctx->send_ttl = bt_mesh_default_ttl_get(); + } + + err = bt_mesh_net_encode(tx, buf, false); + if (err) { + goto done; + } + + BT_DBG("encoded %u bytes: %s", buf->om_len, + bt_hex(buf->om_data, buf->om_len)); + + /* Deliver to GATT Proxy Clients if necessary. Mesh spec 3.4.5.2: + * "The output filter of the interface connected to advertising or + * GATT bearers shall drop all messages with TTL value set to 1." + */ + if (MYNEWT_VAL(BLE_MESH_GATT_PROXY) && + tx->ctx->send_ttl != 1) { + if (bt_mesh_proxy_relay(buf, tx->ctx->addr) && + BT_MESH_ADDR_IS_UNICAST(tx->ctx->addr)) { + /* Notify completion if this only went + * through the Mesh Proxy. + */ + if (cb) { + if (cb->start) { + cb->start(0, 0, cb_data); + } + + if (cb->end) { + cb->end(0, cb_data); + } + } + + err = 0; + goto done; + } + } + + /* Deliver to local network interface if necessary */ + if (bt_mesh_fixed_group_match(tx->ctx->addr) || + bt_mesh_elem_find(tx->ctx->addr)) { + if (cb && cb->start) { + cb->start(0, 0, cb_data); + } + net_buf_slist_put(&bt_mesh.local_queue, net_buf_ref(buf)); + if (cb && cb->end) { + cb->end(0, cb_data); + } + k_work_submit(&bt_mesh.local_work); + } else if (tx->ctx->send_ttl != 1) { + /* Deliver to to the advertising network interface. Mesh spec + * 3.4.5.2: "The output filter of the interface connected to + * advertising or GATT bearers shall drop all messages with + * TTL value set to 1." + */ + bt_mesh_adv_send(buf, cb, cb_data); + } + +done: + net_buf_unref(buf); + return err; +} + +static bool auth_match(struct bt_mesh_subnet_keys *keys, + const u8_t net_id[8], u8_t flags, + u32_t iv_index, const u8_t auth[8]) +{ + u8_t net_auth[8]; + + if (memcmp(net_id, keys->net_id, 8)) { + return false; + } + + bt_mesh_beacon_auth(keys->beacon, flags, keys->net_id, iv_index, + net_auth); + + if (memcmp(auth, net_auth, 8)) { + BT_WARN("Authentication Value %s != %s", + bt_hex(auth, 8), bt_hex(net_auth, 8)); + return false; + } + + return true; +} + +struct bt_mesh_subnet *bt_mesh_subnet_find(const u8_t net_id[8], u8_t flags, + u32_t iv_index, const u8_t auth[8], + bool *new_key) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) { + struct bt_mesh_subnet *sub = &bt_mesh.sub[i]; + + if (sub->net_idx == BT_MESH_KEY_UNUSED) { + continue; + } + + if (auth_match(&sub->keys[0], net_id, flags, iv_index, auth)) { + *new_key = false; + return sub; + } + + if (sub->kr_phase == BT_MESH_KR_NORMAL) { + continue; + } + + if (auth_match(&sub->keys[1], net_id, flags, iv_index, auth)) { + *new_key = true; + return sub; + } + } + + return NULL; +} + +static int net_decrypt(struct bt_mesh_subnet *sub, const u8_t *enc, + const u8_t *priv, const u8_t *data, + size_t data_len, struct bt_mesh_net_rx *rx, + struct os_mbuf *buf) +{ + BT_DBG("NID 0x%02x net_idx 0x%04x", NID(data), sub->net_idx); + BT_DBG("IVI %u net->iv_index 0x%08x", IVI(data), + (unsigned) bt_mesh.iv_index); + + rx->old_iv = (IVI(data) != (bt_mesh.iv_index & 0x01)); + + net_buf_simple_init(buf, 0); + memcpy(net_buf_simple_add(buf, data_len), data, data_len); + + if (bt_mesh_net_obfuscate(buf->om_data, BT_MESH_NET_IVI_RX(rx), priv)) { + return -ENOENT; + } + + if (rx->net_if == BT_MESH_NET_IF_ADV && msg_cache_match(rx, buf)) { + BT_WARN("Duplicate found in Network Message Cache"); + return -EALREADY; + } + + rx->ctx.addr = SRC(buf->om_data); + if (!BT_MESH_ADDR_IS_UNICAST(rx->ctx.addr)) { + BT_WARN("Ignoring non-unicast src addr 0x%04x", rx->ctx.addr); + return -EINVAL; + } + + BT_DBG("src 0x%04x", rx->ctx.addr); + + if ((MYNEWT_VAL(BLE_MESH_PROXY)) && + rx->net_if == BT_MESH_NET_IF_PROXY_CFG) { + return bt_mesh_net_decrypt(enc, buf, BT_MESH_NET_IVI_RX(rx), + true); + } + + return bt_mesh_net_decrypt(enc, buf, BT_MESH_NET_IVI_RX(rx), false); +} + +#if (MYNEWT_VAL(BLE_MESH_LOW_POWER) || \ + MYNEWT_VAL(BLE_MESH_FRIEND)) +static int friend_decrypt(struct bt_mesh_subnet *sub, const u8_t *data, + size_t data_len, struct bt_mesh_net_rx *rx, + struct os_mbuf *buf) +{ + int i; + + BT_DBG("NID 0x%02x net_idx 0x%04x", NID(data), sub->net_idx); + + for (i = 0; i < ARRAY_SIZE(friend_cred); i++) { + struct friend_cred *cred = &friend_cred[i]; + + if (cred->net_idx != sub->net_idx) { + continue; + } + + if (NID(data) == cred->cred[0].nid && + !net_decrypt(sub, cred->cred[0].enc, cred->cred[0].privacy, + data, data_len, rx, buf)) { + return 0; + } + + if (sub->kr_phase == BT_MESH_KR_NORMAL) { + continue; + } + + if (NID(data) == cred->cred[1].nid && + !net_decrypt(sub, cred->cred[1].enc, cred->cred[1].privacy, + data, data_len, rx, buf)) { + rx->new_key = 1; + return 0; + } + } + + return -ENOENT; +} +#endif + +static bool net_find_and_decrypt(const u8_t *data, size_t data_len, + struct bt_mesh_net_rx *rx, + struct os_mbuf *buf) +{ + struct bt_mesh_subnet *sub; + unsigned int i; + + BT_DBG(""); + + for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) { + sub = &bt_mesh.sub[i]; + if (sub->net_idx == BT_MESH_KEY_UNUSED) { + continue; + } + +#if (MYNEWT_VAL(BLE_MESH_LOW_POWER) || \ + MYNEWT_VAL(BLE_MESH_FRIEND)) + if (!friend_decrypt(sub, data, data_len, rx, buf)) { + rx->friend_cred = 1; + rx->ctx.net_idx = sub->net_idx; + rx->sub = sub; + return true; + } +#endif + + if (NID(data) == sub->keys[0].nid && + !net_decrypt(sub, sub->keys[0].enc, sub->keys[0].privacy, + data, data_len, rx, buf)) { + rx->ctx.net_idx = sub->net_idx; + rx->sub = sub; + return true; + } + + if (sub->kr_phase == BT_MESH_KR_NORMAL) { + continue; + } + + if (NID(data) == sub->keys[1].nid && + !net_decrypt(sub, sub->keys[1].enc, sub->keys[1].privacy, + data, data_len, rx, buf)) { + rx->new_key = 1; + rx->ctx.net_idx = sub->net_idx; + rx->sub = sub; + return true; + } + } + + return false; +} + +/* Relaying from advertising to the advertising bearer should only happen + * if the Relay state is set to enabled. Locally originated packets always + * get sent to the advertising bearer. If the packet came in through GATT, + * then we should only relay it if the GATT Proxy state is enabled. + */ +static bool relay_to_adv(enum bt_mesh_net_if net_if) +{ + switch (net_if) { + case BT_MESH_NET_IF_LOCAL: + return true; + case BT_MESH_NET_IF_ADV: + return (bt_mesh_relay_get() == BT_MESH_RELAY_ENABLED); + case BT_MESH_NET_IF_PROXY: + return (bt_mesh_gatt_proxy_get() == BT_MESH_GATT_PROXY_ENABLED); + default: + return false; + } +} + +static void bt_mesh_net_relay(struct os_mbuf *sbuf, + struct bt_mesh_net_rx *rx) +{ + const u8_t *enc, *priv; + struct os_mbuf *buf; + u8_t nid, transmit; + + if (rx->net_if == BT_MESH_NET_IF_LOCAL) { + /* Locally originated PDUs with TTL=1 will only be delivered + * to local elements as per Mesh Profile 1.0 section 3.4.5.2: + * "The output filter of the interface connected to + * advertising or GATT bearers shall drop all messages with + * TTL value set to 1." + */ + if (rx->ctx.recv_ttl == 1) { + return; + } + } else { + if (rx->ctx.recv_ttl <= 1) { + return; + } + } + + if (rx->net_if == BT_MESH_NET_IF_ADV && + bt_mesh_relay_get() != BT_MESH_RELAY_ENABLED && + bt_mesh_gatt_proxy_get() != BT_MESH_GATT_PROXY_ENABLED) { + return; + } + + BT_DBG("TTL %u CTL %u dst 0x%04x", rx->ctx.recv_ttl, rx->ctl, + rx->ctx.recv_dst); + + /* The Relay Retransmit state is only applied to adv-adv relaying. + * Anything else (like GATT to adv, or locally originated packets) + * use the Network Transmit state. + */ + if (rx->net_if == BT_MESH_NET_IF_ADV) { + transmit = bt_mesh_relay_retransmit_get(); + } else { + transmit = bt_mesh_net_transmit_get(); + } + + buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, transmit, K_NO_WAIT); + if (!buf) { + BT_ERR("Out of relay buffers"); + return; + } + + /* Only decrement TTL for non-locally originated packets */ + if (rx->net_if != BT_MESH_NET_IF_LOCAL) { + /* Leave CTL bit intact */ + sbuf->om_data[1] &= 0x80; + sbuf->om_data[1] |= rx->ctx.recv_ttl - 1; + } + + net_buf_add_mem(buf, sbuf->om_data, sbuf->om_len); + + enc = rx->sub->keys[rx->sub->kr_flag].enc; + priv = rx->sub->keys[rx->sub->kr_flag].privacy; + nid = rx->sub->keys[rx->sub->kr_flag].nid; + + BT_DBG("Relaying packet. TTL is now %u", TTL(buf->om_data)); + + /* Update NID if RX or RX was with friend credentials */ + if (rx->friend_cred) { + buf->om_data[0] &= 0x80; /* Clear everything except IVI */ + buf->om_data[0] |= nid; + } + + /* We re-encrypt and obfuscate using the received IVI rather than + * the normal TX IVI (which may be different) since the transport + * layer nonce includes the IVI. + */ + if (bt_mesh_net_encrypt(enc, buf, BT_MESH_NET_IVI_RX(rx), false)) { + BT_ERR("Re-encrypting failed"); + goto done; + } + + if (bt_mesh_net_obfuscate(buf->om_data, BT_MESH_NET_IVI_RX(rx), priv)) { + BT_ERR("Re-obfuscating failed"); + goto done; + } + + BT_DBG("encoded %u bytes: %s", buf->om_len, + bt_hex(buf->om_data, buf->om_len)); + + /* Sending to the GATT bearer should only happen if GATT Proxy + * is enabled or the message originates from the local node. + */ + if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY) && + (bt_mesh_gatt_proxy_get() == BT_MESH_GATT_PROXY_ENABLED || + rx->net_if == BT_MESH_NET_IF_LOCAL)) { + if (bt_mesh_proxy_relay(buf, rx->ctx.recv_dst) && + BT_MESH_ADDR_IS_UNICAST(rx->ctx.recv_dst)) { + goto done; + } + } + + if (relay_to_adv(rx->net_if)) { + bt_mesh_adv_send(buf, NULL, NULL); + } + +done: + net_buf_unref(buf); +} + +int bt_mesh_net_decode(struct os_mbuf *data, enum bt_mesh_net_if net_if, + struct bt_mesh_net_rx *rx, struct os_mbuf *buf) +{ + if (data->om_len < BT_MESH_NET_MIN_PDU_LEN) { + BT_WARN("Dropping too short mesh packet (len %u)", data->om_len); + BT_WARN("%s", bt_hex(data->om_data, data->om_len)); + return -EINVAL; + } + + if (net_if == BT_MESH_NET_IF_ADV && check_dup(data)) { + BT_DBG("duplicate packet; dropping %u bytes: %s", data->om_len, + bt_hex(data->om_data, data->om_len)); + return -EINVAL; + } + + BT_DBG("%u bytes: %s", data->om_len, bt_hex(data->om_data, data->om_len)); + + rx->net_if = net_if; + + if (!net_find_and_decrypt(data->om_data, data->om_len, rx, buf)) { + BT_DBG("Unable to find matching net for packet"); + return -ENOENT; + } + + /* Initialize AppIdx to a sane value */ + rx->ctx.app_idx = BT_MESH_KEY_UNUSED; + + rx->ctx.recv_ttl = TTL(buf->om_data); + + /* Default to responding with TTL 0 for non-routed messages */ + if (rx->ctx.recv_ttl == 0) { + rx->ctx.send_ttl = 0; + } else { + rx->ctx.send_ttl = BT_MESH_TTL_DEFAULT; + } + + rx->ctl = CTL(buf->om_data); + rx->seq = SEQ(buf->om_data); + rx->ctx.recv_dst = DST(buf->om_data); + + BT_DBG("Decryption successful. Payload len %u: %s", buf->om_len, + bt_hex(buf->om_data, buf->om_len)); + + if (net_if != BT_MESH_NET_IF_PROXY_CFG && + rx->ctx.recv_dst == BT_MESH_ADDR_UNASSIGNED) { + BT_ERR("Destination address is unassigned; dropping packet"); + return -EBADMSG; + } + + if (BT_MESH_ADDR_IS_RFU(rx->ctx.recv_dst)) { + BT_ERR("Destination address is RFU; dropping packet"); + return -EBADMSG; + } + + if (net_if != BT_MESH_NET_IF_LOCAL && bt_mesh_elem_find(rx->ctx.addr)) { + BT_DBG("Dropping locally originated packet"); + return -EBADMSG; + } + + BT_DBG("src 0x%04x dst 0x%04x ttl %u", rx->ctx.addr, rx->ctx.recv_dst, + rx->ctx.recv_ttl); + BT_DBG("PDU: %s", bt_hex(buf->om_data, buf->om_len)); + + return 0; +} + +void bt_mesh_net_recv(struct os_mbuf *data, s8_t rssi, + enum bt_mesh_net_if net_if) +{ + struct os_mbuf *buf = NET_BUF_SIMPLE(29); + struct bt_mesh_net_rx rx = { .rssi = rssi }; + struct net_buf_simple_state state; + + BT_DBG("rssi %d net_if %u", rssi, net_if); + + if (!bt_mesh_is_provisioned()) { + BT_ERR("Not provisioned; dropping packet"); + goto done; + } + + if (bt_mesh_net_decode(data, net_if, &rx, buf)) { + goto done; + } + + /* Save the state so the buffer can later be relayed */ + net_buf_simple_save(buf, &state); + + if ((MYNEWT_VAL(BLE_MESH_GATT_PROXY)) && + net_if == BT_MESH_NET_IF_PROXY) { + bt_mesh_proxy_addr_add(data, rx.ctx.addr); + } + + rx.local_match = (bt_mesh_fixed_group_match(rx.ctx.recv_dst) || + bt_mesh_elem_find(rx.ctx.recv_dst)); + + bt_mesh_trans_recv(buf, &rx); + + /* Relay if this was a group/virtual address, or if the destination + * was neither a local element nor an LPN we're Friends for. + */ + if (!BT_MESH_ADDR_IS_UNICAST(rx.ctx.recv_dst) || + (!rx.local_match && !rx.friend_match)) { + net_buf_simple_restore(buf, &state); + bt_mesh_net_relay(buf, &rx); + } + +done: + os_mbuf_free_chain(buf); +} + +static void ivu_refresh(struct ble_npl_event *work) +{ + bt_mesh.ivu_duration += BT_MESH_IVU_HOURS; + + BT_DBG("%s for %u hour%s", + atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS) ? + "IVU in Progress" : "IVU Normal mode", + bt_mesh.ivu_duration, bt_mesh.ivu_duration == 1 ? "" : "s"); + + if (bt_mesh.ivu_duration < BT_MESH_IVU_MIN_HOURS) { + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + bt_mesh_store_iv(true); + } + + k_delayed_work_submit(&bt_mesh.ivu_timer, BT_MESH_IVU_TIMEOUT); + return; + } + + if (atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS)) { + bt_mesh_beacon_ivu_initiator(true); + bt_mesh_net_iv_update(bt_mesh.iv_index, false); + } else if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + bt_mesh_store_iv(true); + } +} + +void bt_mesh_net_start(void) +{ + if (bt_mesh_beacon_get() == BT_MESH_BEACON_ENABLED) { + bt_mesh_beacon_enable(); + } else { + bt_mesh_beacon_disable(); + } + + if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY) && + bt_mesh_gatt_proxy_get() != BT_MESH_GATT_PROXY_NOT_SUPPORTED) { + bt_mesh_proxy_gatt_enable(); + bt_mesh_adv_update(); + } + + if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) { + bt_mesh_lpn_init(); + } else { + bt_mesh_scan_enable(); + } + + if (IS_ENABLED(CONFIG_BT_MESH_FRIEND)) { + bt_mesh_friend_init(); + } + + if (IS_ENABLED(CONFIG_BT_MESH_PROV)) { + u16_t net_idx = bt_mesh.sub[0].net_idx; + u16_t addr = bt_mesh_primary_addr(); + + bt_mesh_prov_complete(net_idx, addr); + } +} + +void bt_mesh_net_init(void) +{ + k_delayed_work_init(&bt_mesh.ivu_timer, ivu_refresh); + + k_work_init(&bt_mesh.local_work, bt_mesh_net_local); + net_buf_slist_init(&bt_mesh.local_queue); +} diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/net.h b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/net.h new file mode 100644 index 000000000..e55102c06 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/net.h @@ -0,0 +1,375 @@ +/* Bluetooth Mesh */ + +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __NET_H__ +#define __NET_H__ + +#define BT_MESH_NET_FLAG_KR BIT(0) +#define BT_MESH_NET_FLAG_IVU BIT(1) + +#define BT_MESH_KR_NORMAL 0x00 +#define BT_MESH_KR_PHASE_1 0x01 +#define BT_MESH_KR_PHASE_2 0x02 +#define BT_MESH_KR_PHASE_3 0x03 + +#define BT_MESH_IV_UPDATE(flags) ((flags >> 1) & 0x01) +#define BT_MESH_KEY_REFRESH(flags) (flags & 0x01) + +#include +#include "atomic.h" +#include "mesh/mesh.h" +#include "mesh/glue.h" + +/* How many hours in between updating IVU duration */ +#define BT_MESH_IVU_MIN_HOURS 96 +#define BT_MESH_IVU_HOURS (BT_MESH_IVU_MIN_HOURS / \ + CONFIG_BT_MESH_IVU_DIVIDER) +#define BT_MESH_IVU_TIMEOUT K_HOURS(BT_MESH_IVU_HOURS) + +struct bt_mesh_app_key { + u16_t net_idx; + u16_t app_idx; + bool updated; + struct bt_mesh_app_keys { + u8_t id; + u8_t val[16]; + } keys[2]; +}; + +struct bt_mesh_subnet { + u32_t beacon_sent; /* Timestamp of last sent beacon */ + u8_t beacons_last; /* Number of beacons during last + * observation window + */ + u8_t beacons_cur; /* Number of beaconds observed during + * currently ongoing window. + */ + + u8_t beacon_cache[21]; /* Cached last authenticated beacon */ + + u16_t net_idx; /* NetKeyIndex */ + + bool kr_flag; /* Key Refresh Flag */ + u8_t kr_phase; /* Key Refresh Phase */ + + u8_t node_id; /* Node Identity State */ + u32_t node_id_start; /* Node Identity started timestamp */ + + u8_t auth[8]; /* Beacon Authentication Value */ + + struct bt_mesh_subnet_keys { + u8_t net[16]; /* NetKey */ + u8_t nid; /* NID */ + u8_t enc[16]; /* EncKey */ + u8_t net_id[8]; /* Network ID */ +#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) + u8_t identity[16]; /* IdentityKey */ +#endif + u8_t privacy[16]; /* PrivacyKey */ + u8_t beacon[16]; /* BeaconKey */ + } keys[2]; +}; + +struct bt_mesh_rpl { + u16_t src; + bool old_iv; +#if defined(CONFIG_BT_SETTINGS) + bool store; +#endif + u32_t seq; +}; + +#if MYNEWT_VAL(BLE_MESH_FRIEND) +#define FRIEND_SEG_RX MYNEWT_VAL(BLE_MESH_FRIEND_SEG_RX) +#define FRIEND_SUB_LIST_SIZE MYNEWT_VAL(BLE_MESH_FRIEND_SUB_LIST_SIZE) +#else +#define FRIEND_SEG_RX 0 +#define FRIEND_SUB_LIST_SIZE 0 +#endif + +struct bt_mesh_friend { + u16_t lpn; + u8_t recv_delay; + u8_t fsn:1, + send_last:1, + pending_req:1, + sec_update:1, + pending_buf:1, + valid:1, + established:1; + s32_t poll_to; + u8_t num_elem; + u16_t lpn_counter; + u16_t counter; + + u16_t net_idx; + + u16_t sub_list[FRIEND_SUB_LIST_SIZE]; + + struct k_delayed_work timer; + + struct bt_mesh_friend_seg { + struct net_buf_slist_t queue; + } seg[FRIEND_SEG_RX]; + + struct os_mbuf *last; + + struct net_buf_slist_t queue; + u32_t queue_size; + + /* Friend Clear Procedure */ + struct { + u32_t start; /* Clear Procedure start */ + u16_t frnd; /* Previous Friend's address */ + u16_t repeat_sec; /* Repeat timeout in seconds */ + struct k_delayed_work timer; /* Repeat timer */ + } clear; +}; + +#if (MYNEWT_VAL(BLE_MESH_LOW_POWER)) +#define LPN_GROUPS CONFIG_BT_MESH_LPN_GROUPS +#else +#define LPN_GROUPS 0 +#endif + +/* Low Power Node state */ +struct bt_mesh_lpn { + enum __packed { + BT_MESH_LPN_DISABLED, /* LPN feature is disabled */ + BT_MESH_LPN_CLEAR, /* Clear in progress */ + BT_MESH_LPN_TIMER, /* Waiting for auto timer expiry */ + BT_MESH_LPN_ENABLED, /* LPN enabled, but no Friend */ + BT_MESH_LPN_REQ_WAIT, /* Wait before scanning for offers */ + BT_MESH_LPN_WAIT_OFFER, /* Friend Req sent */ + BT_MESH_LPN_ESTABLISHED, /* Friendship established */ + BT_MESH_LPN_RECV_DELAY, /* Poll sent, waiting ReceiveDelay */ + BT_MESH_LPN_WAIT_UPDATE, /* Waiting for Update or message */ + } state; + + /* Transaction Number (used for subscription list) */ + u8_t xact_next; + u8_t xact_pending; + u8_t sent_req; + + /* Address of our Friend when we're a LPN. Unassigned if we don't + * have a friend yet. + */ + u16_t frnd; + + /* Value from the friend offer */ + u8_t recv_win; + + u8_t req_attempts; /* Number of Request attempts */ + + s32_t poll_timeout; + + u8_t groups_changed:1, /* Friend Subscription List needs updating */ + pending_poll:1, /* Poll to be sent after subscription */ + disable:1, /* Disable LPN after clearing */ + fsn:1, /* Friend Sequence Number */ + established:1, /* Friendship established */ + clear_success:1; /* Friend Clear Confirm received */ + + /* Friend Queue Size */ + u8_t queue_size; + + /* LPNCounter */ + u16_t counter; + + /* Previous Friend of this LPN */ + u16_t old_friend; + + /* Duration reported for last advertising packet */ + u16_t adv_duration; + + /* Next LPN related action timer */ + struct k_delayed_work timer; + + /* Subscribed groups */ + u16_t groups[LPN_GROUPS]; + + /* Bit fields for tracking which groups the Friend knows about */ + ATOMIC_DEFINE(added, LPN_GROUPS); + ATOMIC_DEFINE(pending, LPN_GROUPS); + ATOMIC_DEFINE(to_remove, LPN_GROUPS); +}; + +/* bt_mesh_net.flags */ +enum { + BT_MESH_VALID, /* We have been provisioned */ + BT_MESH_SUSPENDED, /* Network is temporarily suspended */ + BT_MESH_IVU_IN_PROGRESS, /* IV Update in Progress */ + BT_MESH_IVU_INITIATOR, /* IV Update initiated by us */ + BT_MESH_IVU_TEST, /* IV Update test mode */ + BT_MESH_IVU_PENDING, /* Update blocked by SDU in progress */ + + /* pending storage actions */ + BT_MESH_RPL_PENDING, + BT_MESH_KEYS_PENDING, + BT_MESH_NET_PENDING, + BT_MESH_IV_PENDING, + BT_MESH_SEQ_PENDING, + BT_MESH_HB_PUB_PENDING, + BT_MESH_CFG_PENDING, + BT_MESH_MOD_PENDING, + + /* Don't touch - intentionally last */ + BT_MESH_FLAG_COUNT, +}; + +struct bt_mesh_net { + u32_t iv_index; /* Current IV Index */ + u32_t seq; /* Next outgoing sequence number (24 bits) */ + + ATOMIC_DEFINE(flags, BT_MESH_FLAG_COUNT); + + /* Local network interface */ + struct ble_npl_callout local_work; + struct net_buf_slist_t local_queue; + +#if MYNEWT_VAL(BLE_MESH_FRIEND) + /* Friend state, unique for each LPN that we're Friends for */ + struct bt_mesh_friend frnd[MYNEWT_VAL(BLE_MESH_FRIEND_LPN_COUNT)]; +#endif + +#if (MYNEWT_VAL(BLE_MESH_LOW_POWER)) + struct bt_mesh_lpn lpn; /* Low Power Node state */ +#endif + + /* Number of hours in current IV Update state */ + u8_t ivu_duration; + + /* Timer to track duration in current IV Update state */ + struct k_delayed_work ivu_timer; + + u8_t dev_key[16]; + + struct bt_mesh_app_key app_keys[MYNEWT_VAL(BLE_MESH_APP_KEY_COUNT)]; + + struct bt_mesh_subnet sub[MYNEWT_VAL(BLE_MESH_SUBNET_COUNT)]; + + struct bt_mesh_rpl rpl[MYNEWT_VAL(BLE_MESH_CRPL)]; +}; + +/* Network interface */ +enum bt_mesh_net_if { + BT_MESH_NET_IF_ADV, + BT_MESH_NET_IF_LOCAL, + BT_MESH_NET_IF_PROXY, + BT_MESH_NET_IF_PROXY_CFG, +}; + +/* Decoding context for Network/Transport data */ +struct bt_mesh_net_rx { + struct bt_mesh_subnet *sub; + struct bt_mesh_msg_ctx ctx; + u32_t seq; /* Sequence Number */ + u8_t old_iv:1, /* iv_index - 1 was used */ + new_key:1, /* Data was encrypted with updated key */ + friend_cred:1, /* Data was encrypted with friend cred */ + ctl:1, /* Network Control */ + net_if:2, /* Network interface */ + local_match:1, /* Matched a local element */ + friend_match:1; /* Matched an LPN we're friends for */ + s8_t rssi; +}; + +/* Encoding context for Network/Transport data */ +struct bt_mesh_net_tx { + struct bt_mesh_subnet *sub; + struct bt_mesh_msg_ctx *ctx; + u16_t src; + u8_t xmit; + u8_t friend_cred:1, + aszmic:1, + aid:6; +}; + +extern struct bt_mesh_net bt_mesh; + +#define BT_MESH_NET_IVI_TX (bt_mesh.iv_index - \ + atomic_test_bit(bt_mesh.flags, \ + BT_MESH_IVU_IN_PROGRESS)) +#define BT_MESH_NET_IVI_RX(rx) (bt_mesh.iv_index - (rx)->old_iv) + +#define BT_MESH_NET_HDR_LEN 9 + +int bt_mesh_net_keys_create(struct bt_mesh_subnet_keys *keys, + const u8_t key[16]); + +int bt_mesh_net_create(u16_t idx, u8_t flags, const u8_t key[16], + u32_t iv_index); + +u8_t bt_mesh_net_flags(struct bt_mesh_subnet *sub); + +bool bt_mesh_kr_update(struct bt_mesh_subnet *sub, u8_t new_kr, bool new_key); + +void bt_mesh_net_revoke_keys(struct bt_mesh_subnet *sub); + +int bt_mesh_net_beacon_update(struct bt_mesh_subnet *sub); + +void bt_mesh_rpl_reset(void); + +bool bt_mesh_net_iv_update(u32_t iv_index, bool iv_update); + +void bt_mesh_net_sec_update(struct bt_mesh_subnet *sub); + +struct bt_mesh_subnet *bt_mesh_subnet_get(u16_t net_idx); + +struct bt_mesh_subnet *bt_mesh_subnet_find(const u8_t net_id[8], u8_t flags, + u32_t iv_index, const u8_t auth[8], + bool *new_key); + +int bt_mesh_net_encode(struct bt_mesh_net_tx *tx, struct os_mbuf *buf, + bool proxy); + +int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct os_mbuf *buf, + const struct bt_mesh_send_cb *cb, void *cb_data); + +int bt_mesh_net_resend(struct bt_mesh_subnet *sub, struct os_mbuf *buf, + bool new_key, const struct bt_mesh_send_cb *cb, + void *cb_data); + +int bt_mesh_net_decode(struct os_mbuf *data, enum bt_mesh_net_if net_if, + struct bt_mesh_net_rx *rx, struct os_mbuf *buf); + +void bt_mesh_net_recv(struct os_mbuf *data, s8_t rssi, + enum bt_mesh_net_if net_if); + +u32_t bt_mesh_next_seq(void); + +void bt_mesh_net_start(void); + +void bt_mesh_net_init(void); + +/* Friendship Credential Management */ +struct friend_cred { + u16_t net_idx; + u16_t addr; + + u16_t lpn_counter; + u16_t frnd_counter; + + struct { + u8_t nid; /* NID */ + u8_t enc[16]; /* EncKey */ + u8_t privacy[16]; /* PrivacyKey */ + } cred[2]; +}; + +int friend_cred_get(struct bt_mesh_subnet *sub, u16_t addr, u8_t *nid, + const u8_t **enc, const u8_t **priv); +int friend_cred_set(struct friend_cred *cred, u8_t idx, const u8_t net_key[16]); +void friend_cred_refresh(u16_t net_idx); +int friend_cred_update(struct bt_mesh_subnet *sub); +struct friend_cred *friend_cred_create(struct bt_mesh_subnet *sub, u16_t addr, + u16_t lpn_counter, u16_t frnd_counter); +void friend_cred_clear(struct friend_cred *cred); +int friend_cred_del(u16_t net_idx, u16_t addr); + +#endif diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/prov.c b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/prov.c new file mode 100644 index 000000000..5c519e75a --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/prov.c @@ -0,0 +1,1665 @@ +/* Bluetooth Mesh */ + +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "syscfg/syscfg.h" +#if MYNEWT_VAL(BLE_MESH_PROV) + +#include + +#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG_PROV)) +#include "host/ble_hs_log.h" + +#include "mesh/mesh.h" +#include "mesh_priv.h" + +#include "crypto.h" +#include "atomic.h" +#include "adv.h" +#include "net.h" +#include "access.h" +#include "foundation.h" +#include "proxy.h" +#include "prov.h" +#include "testing.h" + +/* 3 transmissions, 20ms interval */ +#define PROV_XMIT BT_MESH_TRANSMIT(2, 20) + +#define AUTH_METHOD_NO_OOB 0x00 +#define AUTH_METHOD_STATIC 0x01 +#define AUTH_METHOD_OUTPUT 0x02 +#define AUTH_METHOD_INPUT 0x03 + +#define OUTPUT_OOB_BLINK 0x00 +#define OUTPUT_OOB_BEEP 0x01 +#define OUTPUT_OOB_VIBRATE 0x02 +#define OUTPUT_OOB_NUMBER 0x03 +#define OUTPUT_OOB_STRING 0x04 + +#define INPUT_OOB_PUSH 0x00 +#define INPUT_OOB_TWIST 0x01 +#define INPUT_OOB_NUMBER 0x02 +#define INPUT_OOB_STRING 0x03 + +#define PUB_KEY_NO_OOB 0x00 +#define PUB_KEY_OOB 0x01 + +#define PROV_ERR_NONE 0x00 +#define PROV_ERR_NVAL_PDU 0x01 +#define PROV_ERR_NVAL_FMT 0x02 +#define PROV_ERR_UNEXP_PDU 0x03 +#define PROV_ERR_CFM_FAILED 0x04 +#define PROV_ERR_RESOURCES 0x05 +#define PROV_ERR_DECRYPT 0x06 +#define PROV_ERR_UNEXP_ERR 0x07 +#define PROV_ERR_ADDR 0x08 + +#define PROV_INVITE 0x00 +#define PROV_CAPABILITIES 0x01 +#define PROV_START 0x02 +#define PROV_PUB_KEY 0x03 +#define PROV_INPUT_COMPLETE 0x04 +#define PROV_CONFIRM 0x05 +#define PROV_RANDOM 0x06 +#define PROV_DATA 0x07 +#define PROV_COMPLETE 0x08 +#define PROV_FAILED 0x09 + +#define PROV_ALG_P256 0x00 + +#define GPCF(gpc) (gpc & 0x03) +#define GPC_START(last_seg) (((last_seg) << 2) | 0x00) +#define GPC_ACK 0x01 +#define GPC_CONT(seg_id) (((seg_id) << 2) | 0x02) +#define GPC_CTL(op) (((op) << 2) | 0x03) + +#define START_PAYLOAD_MAX 20 +#define CONT_PAYLOAD_MAX 23 + +#define START_LAST_SEG(gpc) (gpc >> 2) +#define CONT_SEG_INDEX(gpc) (gpc >> 2) + +#define BEARER_CTL(gpc) (gpc >> 2) +#define LINK_OPEN 0x00 +#define LINK_ACK 0x01 +#define LINK_CLOSE 0x02 + +#define CLOSE_REASON_SUCCESS 0x00 +#define CLOSE_REASON_TIMEOUT 0x01 +#define CLOSE_REASON_FAILED 0x02 + +#define XACT_SEG_DATA(_seg) (&link.rx.buf->om_data[20 + ((_seg - 1) * 23)]) +#define XACT_SEG_RECV(_seg) (link.rx.seg &= ~(1 << (_seg))) + +#define XACT_NVAL 0xff + +enum { + REMOTE_PUB_KEY, /* Remote key has been received */ + LINK_ACTIVE, /* Link has been opened */ + HAVE_DHKEY, /* DHKey has been calculated */ + SEND_CONFIRM, /* Waiting to send Confirm value */ + WAIT_NUMBER, /* Waiting for number input from user */ + WAIT_STRING, /* Waiting for string input from user */ + LINK_INVALID, /* Error occurred during provisioning */ + + NUM_FLAGS, +}; + +struct prov_link { + ATOMIC_DEFINE(flags, NUM_FLAGS); +#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) + uint16_t conn_handle; /* GATT connection */ +#endif + u8_t dhkey[32]; /* Calculated DHKey */ + u8_t expect; /* Next expected PDU */ + + u8_t oob_method; + u8_t oob_action; + u8_t oob_size; + + u8_t conf[16]; /* Remote Confirmation */ + u8_t rand[16]; /* Local Random */ + u8_t auth[16]; /* Authentication Value */ + + u8_t conf_salt[16]; /* ConfirmationSalt */ + u8_t conf_key[16]; /* ConfirmationKey */ + u8_t conf_inputs[145]; /* ConfirmationInputs */ + u8_t prov_salt[16]; /* Provisioning Salt */ + +#if (MYNEWT_VAL(BLE_MESH_PB_ADV)) + u32_t id; /* Link ID */ + + struct { + u8_t id; /* Transaction ID */ + u8_t prev_id; /* Previous Transaction ID */ + u8_t seg; /* Bit-field of unreceived segments */ + u8_t last_seg; /* Last segment (to check length) */ + u8_t fcs; /* Expected FCS value */ + struct os_mbuf *buf; + } rx; + + struct { + /* Start timestamp of the transaction */ + s64_t start; + + /* Transaction id*/ + u8_t id; + + /* Pending outgoing buffer(s) */ + struct os_mbuf *buf[3]; + + /* Retransmit timer */ + struct k_delayed_work retransmit; + } tx; +#endif + + struct k_delayed_work prot_timer; +}; + +struct prov_rx { + u32_t link_id; + u8_t xact_id; + u8_t gpc; +}; + +#define RETRANSMIT_TIMEOUT K_MSEC(500) +#define BUF_TIMEOUT K_MSEC(400) +#define TRANSACTION_TIMEOUT K_SECONDS(30) +#define PROTOCOL_TIMEOUT K_SECONDS(60) + +#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) +#define PROV_BUF_HEADROOM 5 +#else +#define PROV_BUF_HEADROOM 0 +static struct os_mbuf *rx_buf; +#endif + +#define PROV_BUF(len) NET_BUF_SIMPLE(PROV_BUF_HEADROOM + len) + +static struct prov_link link; + +static const struct bt_mesh_prov *prov; + +static void pub_key_ready(const u8_t *pkey); + +static int reset_state(void) +{ + static struct bt_pub_key_cb pub_key_cb = { + .func = pub_key_ready, + }; + int err; + + k_delayed_work_cancel(&link.prot_timer); + + /* Disable Attention Timer if it was set */ + if (link.conf_inputs[0]) { + bt_mesh_attention(NULL, 0); + } + +#if (MYNEWT_VAL(BLE_MESH_PB_ADV)) + /* Clear everything except the retransmit and protocol timer + * delayed work objects. + */ + (void)memset(&link, 0, offsetof(struct prov_link, tx.retransmit)); + link.rx.prev_id = XACT_NVAL; + +#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) + link.rx.buf = bt_mesh_proxy_get_buf(); +#else + net_buf_simple_init(rx_buf, 0); + link.rx.buf = rx_buf; +#endif /* PB_GATT */ + +#else /* !PB_ADV */ + /* Clear everything except the protocol timer (k_delayed_work) */ + (void)memset(&link, 0, offsetof(struct prov_link, prot_timer)); +#endif /* PB_ADV */ + +#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) + link.conn_handle = BLE_HS_CONN_HANDLE_NONE; +#endif + + err = bt_pub_key_gen(&pub_key_cb); + if (err) { + BT_ERR("Failed to generate public key (%d)", err); + return err; + } + + return 0; +} + +#if (MYNEWT_VAL(BLE_MESH_PB_ADV)) +static void buf_sent(int err, void *user_data) +{ + BT_DBG("buf_sent"); + + if (!link.tx.buf[0]) { + return; + } + + k_delayed_work_submit(&link.tx.retransmit, RETRANSMIT_TIMEOUT); +} + +static struct bt_mesh_send_cb buf_sent_cb = { + .end = buf_sent, +}; + +static void free_segments(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(link.tx.buf); i++) { + struct os_mbuf *buf = link.tx.buf[i]; + + if (!buf) { + break; + } + + link.tx.buf[i] = NULL; + /* Mark as canceled */ + BT_MESH_ADV(buf)->busy = 0; + net_buf_unref(buf); + } +} + +static void prov_clear_tx(void) +{ + BT_DBG(""); + + k_delayed_work_cancel(&link.tx.retransmit); + + free_segments(); +} + +static void reset_adv_link(void) +{ + prov_clear_tx(); + + if (prov->link_close) { + prov->link_close(BT_MESH_PROV_ADV); + } + + reset_state(); +} + +static struct os_mbuf *adv_buf_create(void) +{ + struct os_mbuf *buf; + + buf = bt_mesh_adv_create(BT_MESH_ADV_PROV, PROV_XMIT, BUF_TIMEOUT); + if (!buf) { + BT_ERR("Out of provisioning buffers"); + assert(0); + return NULL; + } + + return buf; +} + +static u8_t pending_ack = XACT_NVAL; + +static void ack_complete(u16_t duration, int err, void *user_data) +{ + BT_DBG("xact %u complete", (u8_t)pending_ack); + pending_ack = XACT_NVAL; +} + +static void gen_prov_ack_send(u8_t xact_id) +{ + static const struct bt_mesh_send_cb cb = { + .start = ack_complete, + }; + const struct bt_mesh_send_cb *complete; + struct os_mbuf *buf; + + BT_DBG("xact_id %u", xact_id); + + if (pending_ack == xact_id) { + BT_DBG("Not sending duplicate ack"); + return; + } + + buf = adv_buf_create(); + if (!buf) { + return; + } + + if (pending_ack == XACT_NVAL) { + pending_ack = xact_id; + complete = &cb; + } else { + complete = NULL; + } + + net_buf_add_be32(buf, link.id); + net_buf_add_u8(buf, xact_id); + net_buf_add_u8(buf, GPC_ACK); + + bt_mesh_adv_send(buf, complete, NULL); + net_buf_unref(buf); +} + +static void send_reliable(void) +{ + int i; + + link.tx.start = k_uptime_get(); + + for (i = 0; i < ARRAY_SIZE(link.tx.buf); i++) { + struct os_mbuf *buf = link.tx.buf[i]; + + if (!buf) { + break; + } + + if (i + 1 < ARRAY_SIZE(link.tx.buf) && link.tx.buf[i + 1]) { + bt_mesh_adv_send(buf, NULL, NULL); + } else { + bt_mesh_adv_send(buf, &buf_sent_cb, NULL); + } + } +} + +static int bearer_ctl_send(u8_t op, void *data, u8_t data_len) +{ + struct os_mbuf *buf; + + BT_DBG("op 0x%02x data_len %u", op, data_len); + + prov_clear_tx(); + + buf = adv_buf_create(); + if (!buf) { + return -ENOBUFS; + } + + net_buf_add_be32(buf, link.id); + /* Transaction ID, always 0 for Bearer messages */ + net_buf_add_u8(buf, 0x00); + net_buf_add_u8(buf, GPC_CTL(op)); + net_buf_add_mem(buf, data, data_len); + + link.tx.buf[0] = buf; + send_reliable(); + + return 0; +} + +static u8_t last_seg(u8_t len) +{ + if (len <= START_PAYLOAD_MAX) { + return 0; + } + + len -= START_PAYLOAD_MAX; + + return 1 + (len / CONT_PAYLOAD_MAX); +} + +static inline u8_t next_transaction_id(void) +{ + if (link.tx.id != 0 && link.tx.id != 0xFF) { + return ++link.tx.id; + } + + link.tx.id = 0x80; + return link.tx.id; +} + +static int prov_send_adv(struct os_mbuf *msg) +{ + struct os_mbuf *start, *buf; + u8_t seg_len, seg_id; + u8_t xact_id; + + BT_DBG("len %u: %s", msg->om_len, bt_hex(msg->om_data, msg->om_len)); + + prov_clear_tx(); + + start = adv_buf_create(); + if (!start) { + return -ENOBUFS; + } + + xact_id = next_transaction_id(); + net_buf_add_be32(start, link.id); + net_buf_add_u8(start, xact_id); + + net_buf_add_u8(start, GPC_START(last_seg(msg->om_len))); + net_buf_add_be16(start, msg->om_len); + net_buf_add_u8(start, bt_mesh_fcs_calc(msg->om_data, msg->om_len)); + + link.tx.buf[0] = start; + + seg_len = min(msg->om_len, START_PAYLOAD_MAX); + BT_DBG("seg 0 len %u: %s", seg_len, bt_hex(msg->om_data, seg_len)); + net_buf_add_mem(start, msg->om_data, seg_len); + net_buf_simple_pull(msg, seg_len); + + buf = start; + for (seg_id = 1; msg->om_len > 0; seg_id++) { + if (seg_id >= ARRAY_SIZE(link.tx.buf)) { + BT_ERR("Too big message"); + free_segments(); + return -E2BIG; + } + + buf = adv_buf_create(); + if (!buf) { + free_segments(); + return -ENOBUFS; + } + + link.tx.buf[seg_id] = buf; + + seg_len = min(msg->om_len, CONT_PAYLOAD_MAX); + + BT_DBG("seg_id %u len %u: %s", seg_id, seg_len, + bt_hex(msg->om_data, seg_len)); + + net_buf_add_be32(buf, link.id); + net_buf_add_u8(buf, xact_id); + net_buf_add_u8(buf, GPC_CONT(seg_id)); + net_buf_add_mem(buf, msg->om_data, seg_len); + net_buf_simple_pull(msg, seg_len); + } + + send_reliable(); + + return 0; +} + +#endif /* MYNEWT_VAL(BLE_MESH_PB_ADV) */ + +#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) +static int prov_send_gatt(struct os_mbuf *msg) +{ + if (link.conn_handle == BLE_HS_CONN_HANDLE_NONE) { + BT_ERR("No connection handle!?"); + return -ENOTCONN; + } + + return bt_mesh_proxy_send(link.conn_handle, BT_MESH_PROXY_PROV, msg); +} +#endif /* MYNEWT_VAL(BLE_MESH_PB_GATT) */ + +static inline int prov_send(struct os_mbuf *buf) +{ + k_delayed_work_submit(&link.prot_timer, PROTOCOL_TIMEOUT); + +#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) + if (link.conn_handle != BLE_HS_CONN_HANDLE_NONE) { + return prov_send_gatt(buf); + } +#endif +#if (MYNEWT_VAL(BLE_MESH_PB_ADV)) + return prov_send_adv(buf); +#else + return 0; +#endif +} + +static void prov_buf_init(struct os_mbuf *buf, u8_t type) +{ + net_buf_simple_init(buf, PROV_BUF_HEADROOM); + net_buf_simple_add_u8(buf, type); +} + +static void prov_send_fail_msg(u8_t err) +{ + struct os_mbuf *buf = PROV_BUF(2); + + prov_buf_init(buf, PROV_FAILED); + net_buf_simple_add_u8(buf, err); + + if (prov_send(buf)) { + BT_ERR("Failed to send Provisioning Failed message"); + } + + atomic_set_bit(link.flags, LINK_INVALID); + + os_mbuf_free_chain(buf); +} + +static void prov_invite(const u8_t *data) +{ + struct os_mbuf *buf = PROV_BUF(12); + + BT_DBG("Attention Duration: %u seconds", data[0]); + + if (data[0]) { + bt_mesh_attention(NULL, data[0]); + } + + link.conf_inputs[0] = data[0]; + + prov_buf_init(buf, PROV_CAPABILITIES); + + /* Number of Elements supported */ + net_buf_simple_add_u8(buf, bt_mesh_elem_count()); + + /* Supported algorithms - FIPS P-256 Eliptic Curve */ + net_buf_simple_add_be16(buf, BIT(PROV_ALG_P256)); + + /* Public Key Type, Only "No OOB" Public Key is supported*/ + net_buf_simple_add_u8(buf, PUB_KEY_NO_OOB); + + /* Static OOB Type */ + net_buf_simple_add_u8(buf, prov->static_val ? BIT(0) : 0x00); + + /* Output OOB Size */ + net_buf_simple_add_u8(buf, prov->output_size); + + /* Output OOB Action */ + net_buf_simple_add_be16(buf, prov->output_actions); + + /* Input OOB Size */ + net_buf_simple_add_u8(buf, prov->input_size); + + /* Input OOB Action */ + net_buf_simple_add_be16(buf, prov->input_actions); + + memcpy(&link.conf_inputs[1], &buf->om_data[1], 11); + + if (prov_send(buf)) { + BT_ERR("Failed to send capabilities"); + goto done; + } + + link.expect = PROV_START; + +done: + os_mbuf_free_chain(buf); +} + +static void prov_capabilities(const u8_t *data) +{ + u16_t algorithms, output_action, input_action; + + BT_DBG("Elements: %u", data[0]); + + algorithms = sys_get_be16(&data[1]); + BT_DBG("Algorithms: %u", algorithms); + + BT_DBG("Public Key Type: 0x%02x", data[3]); + BT_DBG("Static OOB Type: 0x%02x", data[4]); + BT_DBG("Output OOB Size: %u", data[5]); + + output_action = sys_get_be16(&data[6]); + BT_DBG("Output OOB Action: 0x%04x", output_action); + + BT_DBG("Input OOB Size: %u", data[8]); + + input_action = sys_get_be16(&data[9]); + BT_DBG("Input OOB Action: 0x%04x", input_action); +} + +static bt_mesh_output_action_t output_action(u8_t action) +{ + switch (action) { + case OUTPUT_OOB_BLINK: + return BT_MESH_BLINK; + case OUTPUT_OOB_BEEP: + return BT_MESH_BEEP; + case OUTPUT_OOB_VIBRATE: + return BT_MESH_VIBRATE; + case OUTPUT_OOB_NUMBER: + return BT_MESH_DISPLAY_NUMBER; + case OUTPUT_OOB_STRING: + return BT_MESH_DISPLAY_STRING; + default: + return BT_MESH_NO_OUTPUT; + } +} + +static bt_mesh_input_action_t input_action(u8_t action) +{ + switch (action) { + case INPUT_OOB_PUSH: + return BT_MESH_PUSH; + case INPUT_OOB_TWIST: + return BT_MESH_TWIST; + case INPUT_OOB_NUMBER: + return BT_MESH_ENTER_NUMBER; + case INPUT_OOB_STRING: + return BT_MESH_ENTER_STRING; + default: + return BT_MESH_NO_INPUT; + } +} + +static int prov_auth(u8_t method, u8_t action, u8_t size) +{ + bt_mesh_output_action_t output; + bt_mesh_input_action_t input; + + switch (method) { + case AUTH_METHOD_NO_OOB: + if (action || size) { + return -EINVAL; + } + + memset(link.auth, 0, sizeof(link.auth)); + return 0; + case AUTH_METHOD_STATIC: + if (action || size) { + return -EINVAL; + } + + memcpy(link.auth + 16 - prov->static_val_len, + prov->static_val, prov->static_val_len); + memset(link.auth, 0, sizeof(link.auth) - prov->static_val_len); + return 0; + + case AUTH_METHOD_OUTPUT: + output = output_action(action); + if (!output) { + return -EINVAL; + } + + if (!(prov->output_actions & output)) { + return -EINVAL; + } + + if (size > prov->output_size) { + return -EINVAL; + } + + if (output == BT_MESH_DISPLAY_STRING) { + unsigned char str[9]; + u8_t i; + + bt_rand(str, size); + + /* Normalize to '0' .. '9' & 'A' .. 'Z' */ + for (i = 0; i < size; i++) { + str[i] %= 36; + if (str[i] < 10) { + str[i] += '0'; + } else { + str[i] += 'A' - 10; + } + } + str[size] = '\0'; + + memcpy(link.auth, str, size); + memset(link.auth + size, 0, sizeof(link.auth) - size); + + return prov->output_string((char *)str); + } else { + u32_t div[8] = { 10, 100, 1000, 10000, 100000, + 1000000, 10000000, 100000000 }; + u32_t num; + + bt_rand(&num, sizeof(num)); + num %= div[size - 1]; + + sys_put_be32(num, &link.auth[12]); + memset(link.auth, 0, 12); + + return prov->output_number(output, num); + } + + case AUTH_METHOD_INPUT: + input = input_action(action); + if (!input) { + return -EINVAL; + } + + if (!(prov->input_actions & input)) { + return -EINVAL; + } + + if (size > prov->input_size) { + return -EINVAL; + } + + if (input == BT_MESH_ENTER_STRING) { + atomic_set_bit(link.flags, WAIT_STRING); + } else { + atomic_set_bit(link.flags, WAIT_NUMBER); + } + + return prov->input(input, size); + + default: + return -EINVAL; + } +} + +static void prov_start(const u8_t *data) +{ + BT_DBG("Algorithm: 0x%02x", data[0]); + BT_DBG("Public Key: 0x%02x", data[1]); + BT_DBG("Auth Method: 0x%02x", data[2]); + BT_DBG("Auth Action: 0x%02x", data[3]); + BT_DBG("Auth Size: 0x%02x", data[4]); + + if (data[0] != PROV_ALG_P256) { + BT_ERR("Unknown algorithm 0x%02x", data[0]); + prov_send_fail_msg(PROV_ERR_NVAL_FMT); + return; + } + + if (data[1] != PUB_KEY_NO_OOB) { + BT_ERR("Invalid public key type: 0x%02x", data[1]); + prov_send_fail_msg(PROV_ERR_NVAL_FMT); + return; + } + + memcpy(&link.conf_inputs[12], data, 5); + + /* TODO: reset link when auth fails? */ + link.expect = PROV_PUB_KEY; + + if (prov_auth(data[2], data[3], data[4]) < 0) { + BT_ERR("Invalid authentication method: 0x%02x; " + "action: 0x%02x; size: 0x%02x", data[2], data[3], + data[4]); + prov_send_fail_msg(PROV_ERR_NVAL_FMT); + } +} + +static void send_confirm(void) +{ + struct os_mbuf *cfm = PROV_BUF(17); + + BT_DBG("ConfInputs[0] %s", bt_hex(link.conf_inputs, 64)); + BT_DBG("ConfInputs[64] %s", bt_hex(&link.conf_inputs[64], 64)); + BT_DBG("ConfInputs[128] %s", bt_hex(&link.conf_inputs[128], 17)); + + if (bt_mesh_prov_conf_salt(link.conf_inputs, link.conf_salt)) { + BT_ERR("Unable to generate confirmation salt"); + prov_send_fail_msg(PROV_ERR_UNEXP_ERR); + goto done; + } + + BT_DBG("ConfirmationSalt: %s", bt_hex(link.conf_salt, 16)); + + if (bt_mesh_prov_conf_key(link.dhkey, link.conf_salt, link.conf_key)) { + BT_ERR("Unable to generate confirmation key"); + prov_send_fail_msg(PROV_ERR_UNEXP_ERR); + goto done; + } + + BT_DBG("ConfirmationKey: %s", bt_hex(link.conf_key, 16)); + + if (bt_rand(link.rand, 16)) { + BT_ERR("Unable to generate random number"); + prov_send_fail_msg(PROV_ERR_UNEXP_ERR); + goto done; + } + + BT_DBG("LocalRandom: %s", bt_hex(link.rand, 16)); + + prov_buf_init(cfm, PROV_CONFIRM); + + if (bt_mesh_prov_conf(link.conf_key, link.rand, link.auth, + net_buf_simple_add(cfm, 16))) { + BT_ERR("Unable to generate confirmation value"); + prov_send_fail_msg(PROV_ERR_UNEXP_ERR); + goto done; + } + + if (prov_send(cfm)) { + BT_ERR("Failed to send Provisioning Confirm"); + goto done; + } + + link.expect = PROV_RANDOM; + +done: + os_mbuf_free_chain(cfm); +} + +static void send_input_complete(void) +{ + struct os_mbuf *buf = PROV_BUF(1); + + prov_buf_init(buf, PROV_INPUT_COMPLETE); + if (prov_send(buf)) { + BT_ERR("Failed to send Provisioning Input Complete"); + } + + os_mbuf_free_chain(buf); +} + +int bt_mesh_input_number(u32_t num) +{ + BT_DBG("%u", (unsigned) num); + + if (!atomic_test_and_clear_bit(link.flags, WAIT_NUMBER)) { + return -EINVAL; + } + + sys_put_be32(num, &link.auth[12]); + + send_input_complete(); + + if (!atomic_test_bit(link.flags, HAVE_DHKEY)) { + return 0; + } + + if (atomic_test_and_clear_bit(link.flags, SEND_CONFIRM)) { + send_confirm(); + } + + return 0; +} + +int bt_mesh_input_string(const char *str) +{ + BT_DBG("%s", str); + + if (!atomic_test_and_clear_bit(link.flags, WAIT_STRING)) { + return -EINVAL; + } + + strncpy((char *)link.auth, str, prov->input_size); + + send_input_complete(); + + if (!atomic_test_bit(link.flags, HAVE_DHKEY)) { + return 0; + } + + if (atomic_test_and_clear_bit(link.flags, SEND_CONFIRM)) { + send_confirm(); + } + + return 0; +} + +static void prov_dh_key_cb(const u8_t key[32]) +{ + BT_DBG("%p", key); + + if (!key) { + BT_ERR("DHKey generation failed"); + prov_send_fail_msg(PROV_ERR_UNEXP_ERR); + return; + } + + sys_memcpy_swap(link.dhkey, key, 32); + + BT_DBG("DHkey: %s", bt_hex(link.dhkey, 32)); + + atomic_set_bit(link.flags, HAVE_DHKEY); + + if (atomic_test_bit(link.flags, WAIT_NUMBER) || + atomic_test_bit(link.flags, WAIT_STRING)) { + return; + } + + if (atomic_test_and_clear_bit(link.flags, SEND_CONFIRM)) { + send_confirm(); + } +} + +static void send_pub_key(void) +{ + struct os_mbuf *buf = PROV_BUF(65); + const u8_t *key; + + key = bt_pub_key_get(); + if (!key) { + BT_ERR("No public key available"); + prov_send_fail_msg(PROV_ERR_UNEXP_ERR); + goto done; + } + + BT_DBG("Local Public Key: %s", bt_hex(key, 64)); + + /* Copy remote key in little-endian for bt_dh_key_gen(). + * X and Y halves are swapped independently. Use response + * buffer as a temporary storage location. The bt_dh_key_gen() + * will also take care of validating the remote public key. + */ + sys_memcpy_swap(buf->om_data, &link.conf_inputs[17], 32); + sys_memcpy_swap(&buf->om_data[32], &link.conf_inputs[49], 32); + + if (bt_dh_key_gen(buf->om_data, prov_dh_key_cb)) { + BT_ERR("Failed to generate DHKey"); + prov_send_fail_msg(PROV_ERR_UNEXP_ERR); + return; + } + + prov_buf_init(buf, PROV_PUB_KEY); + + /* Swap X and Y halves independently to big-endian */ + sys_memcpy_swap(net_buf_simple_add(buf, 32), key, 32); + sys_memcpy_swap(net_buf_simple_add(buf, 32), &key[32], 32); + + memcpy(&link.conf_inputs[81], &buf->om_data[1], 64); + + if (prov_send(buf)) { + BT_ERR("Failed to send Public Key"); + return; + } + + link.expect = PROV_CONFIRM; + +done: + os_mbuf_free_chain(buf); +} + +static void prov_pub_key(const u8_t *data) +{ + BT_DBG("Remote Public Key: %s", bt_hex(data, 64)); + + memcpy(&link.conf_inputs[17], data, 64); + + if (!bt_pub_key_get()) { + /* Clear retransmit timer */ +#if (MYNEWT_VAL(BLE_MESH_PB_ADV)) + prov_clear_tx(); +#endif + atomic_set_bit(link.flags, REMOTE_PUB_KEY); + BT_WARN("Waiting for local public key"); + return; + } + + send_pub_key(); +} + +static void pub_key_ready(const u8_t *pkey) +{ + if (!pkey) { + BT_WARN("Public key not available"); + return; + } + + BT_DBG("Local public key ready"); + + if (atomic_test_and_clear_bit(link.flags, REMOTE_PUB_KEY)) { + send_pub_key(); + } +} + +static void prov_input_complete(const u8_t *data) +{ + BT_DBG(""); +} + +static void prov_confirm(const u8_t *data) +{ + BT_DBG("Remote Confirm: %s", bt_hex(data, 16)); + + memcpy(link.conf, data, 16); + + if (!atomic_test_bit(link.flags, HAVE_DHKEY)) { +#if (MYNEWT_VAL(BLE_MESH_PB_ADV)) + prov_clear_tx(); +#endif + atomic_set_bit(link.flags, SEND_CONFIRM); + } else { + send_confirm(); + } +} + +static void prov_random(const u8_t *data) +{ + struct os_mbuf *rnd = PROV_BUF(16); + u8_t conf_verify[16]; + + BT_DBG("Remote Random: %s", bt_hex(data, 16)); + + if (bt_mesh_prov_conf(link.conf_key, data, link.auth, conf_verify)) { + BT_ERR("Unable to calculate confirmation verification"); + prov_send_fail_msg(PROV_ERR_UNEXP_ERR); + goto done; + } + + if (memcmp(conf_verify, link.conf, 16)) { + BT_ERR("Invalid confirmation value"); + BT_DBG("Received: %s", bt_hex(link.conf, 16)); + BT_DBG("Calculated: %s", bt_hex(conf_verify, 16)); + prov_send_fail_msg(PROV_ERR_CFM_FAILED); + goto done; + } + + prov_buf_init(rnd, PROV_RANDOM); + net_buf_simple_add_mem(rnd, link.rand, 16); + + if (prov_send(rnd)) { + BT_ERR("Failed to send Provisioning Random"); + goto done; + } + + if (bt_mesh_prov_salt(link.conf_salt, data, link.rand, + link.prov_salt)) { + BT_ERR("Failed to generate provisioning salt"); + prov_send_fail_msg(PROV_ERR_UNEXP_ERR); + goto done; + } + + BT_DBG("ProvisioningSalt: %s", bt_hex(link.prov_salt, 16)); + + link.expect = PROV_DATA; + +done: + os_mbuf_free_chain(rnd); +} + +static inline bool is_pb_gatt(void) +{ +#if MYNEWT_VAL(BLE_MESH_PB_GATT) + return (link.conn_handle != BLE_HS_CONN_HANDLE_NONE); +#else + return false; +#endif +} + +static void prov_data(const u8_t *data) +{ + struct os_mbuf *msg = PROV_BUF(1); + u8_t session_key[16]; + u8_t nonce[13]; + u8_t dev_key[16]; + u8_t pdu[25]; + u8_t flags; + u32_t iv_index; + u16_t addr; + u16_t net_idx; + int err; + bool identity_enable; + + BT_DBG(""); + + err = bt_mesh_session_key(link.dhkey, link.prov_salt, session_key); + if (err) { + BT_ERR("Unable to generate session key"); + prov_send_fail_msg(PROV_ERR_UNEXP_ERR); + goto done; + } + + BT_DBG("SessionKey: %s", bt_hex(session_key, 16)); + + err = bt_mesh_prov_nonce(link.dhkey, link.prov_salt, nonce); + if (err) { + BT_ERR("Unable to generate session nonce"); + prov_send_fail_msg(PROV_ERR_UNEXP_ERR); + goto done; + } + + BT_DBG("Nonce: %s", bt_hex(nonce, 13)); + + err = bt_mesh_prov_decrypt(session_key, nonce, data, pdu); + if (err) { + BT_ERR("Unable to decrypt provisioning data"); + prov_send_fail_msg(PROV_ERR_DECRYPT); + goto done; + } + + err = bt_mesh_dev_key(link.dhkey, link.prov_salt, dev_key); + if (err) { + BT_ERR("Unable to generate device key"); + prov_send_fail_msg(PROV_ERR_UNEXP_ERR); + goto done; + } + + BT_DBG("DevKey: %s", bt_hex(dev_key, 16)); + + net_idx = sys_get_be16(&pdu[16]); + flags = pdu[18]; + iv_index = sys_get_be32(&pdu[19]); + addr = sys_get_be16(&pdu[23]); + + BT_DBG("net_idx %u iv_index 0x%08x, addr 0x%04x", + net_idx, (unsigned) iv_index, addr); + + prov_buf_init(msg, PROV_COMPLETE); + if (prov_send(msg)) { + BT_ERR("Failed to send Provisioning Complete"); + goto done; + } + + /* Ignore any further PDUs on this link */ + link.expect = 0; + + /* Store info, since bt_mesh_provision() will end up clearing it */ + if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) { + identity_enable = is_pb_gatt(); + } else { + identity_enable = false; + } + + err = bt_mesh_provision(pdu, net_idx, flags, iv_index, addr, dev_key); + if (err) { + BT_ERR("Failed to provision (err %d)", err); + goto done; + } + + /* After PB-GATT provisioning we should start advertising + * using Node Identity. + */ + if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY) && identity_enable) { + bt_mesh_proxy_identity_enable(); + } + +done: + os_mbuf_free_chain(msg); +} + +static void prov_complete(const u8_t *data) +{ + BT_DBG(""); +} + +static void prov_failed(const u8_t *data) +{ + BT_WARN("Error: 0x%02x", data[0]); +} + +static const struct { + void (*func)(const u8_t *data); + u16_t len; +} prov_handlers[] = { + { prov_invite, 1 }, + { prov_capabilities, 11 }, + { prov_start, 5, }, + { prov_pub_key, 64 }, + { prov_input_complete, 0 }, + { prov_confirm, 16 }, + { prov_random, 16 }, + { prov_data, 33 }, + { prov_complete, 0 }, + { prov_failed, 1 }, +}; + +#if (MYNEWT_VAL(BLE_MESH_PB_ADV)) +static void prov_retransmit(struct ble_npl_event *work) +{ + int i; + + BT_DBG(""); + + if (!atomic_test_bit(link.flags, LINK_ACTIVE)) { + BT_WARN("Link not active"); + return; + } + + if (k_uptime_get() - link.tx.start > TRANSACTION_TIMEOUT) { + BT_WARN("Giving up transaction"); + reset_adv_link(); + return; + } + + for (i = 0; i < ARRAY_SIZE(link.tx.buf); i++) { + struct os_mbuf *buf = link.tx.buf[i]; + + if (!buf) { + break; + } + + if (BT_MESH_ADV(buf)->busy) { + continue; + } + + BT_DBG("%u bytes: %s", buf->om_len, bt_hex(buf->om_data, buf->om_len)); + + if (i + 1 < ARRAY_SIZE(link.tx.buf) && link.tx.buf[i + 1]) { + bt_mesh_adv_send(buf, NULL, NULL); + } else { + bt_mesh_adv_send(buf, &buf_sent_cb, NULL); + } + + } +} + +static void link_open(struct prov_rx *rx, struct os_mbuf *buf) +{ + BT_DBG("link open: len %u", buf->om_len); + + if (buf->om_len < 16) { + BT_ERR("Too short bearer open message (len %u)", buf->om_len); + return; + } + + if (atomic_test_bit(link.flags, LINK_ACTIVE)) { + /* Send another link ack if the provisioner missed the last */ + if (link.id == rx->link_id && link.expect == PROV_INVITE) { + BT_DBG("Resending link ack"); + bearer_ctl_send(LINK_ACK, NULL, 0); + } else { + BT_WARN("Ignoring bearer open: link already active"); + } + + return; + } + + if (memcmp(buf->om_data, prov->uuid, 16)) { + BT_DBG("Bearer open message not for us"); + return; + } + + if (prov->link_open) { + prov->link_open(BT_MESH_PROV_ADV); + } + + link.id = rx->link_id; + atomic_set_bit(link.flags, LINK_ACTIVE); + net_buf_simple_init(link.rx.buf, 0); + + bearer_ctl_send(LINK_ACK, NULL, 0); + + link.expect = PROV_INVITE; + +} + +static void link_ack(struct prov_rx *rx, struct os_mbuf *buf) +{ + BT_DBG("Link ack: len %u", buf->om_len); +} + +static void link_close(struct prov_rx *rx, struct os_mbuf *buf) +{ + BT_DBG("Link close: len %u", buf->om_len); + + reset_adv_link(); +} + +static void gen_prov_ctl(struct prov_rx *rx, struct os_mbuf *buf) +{ + BT_DBG("op 0x%02x len %u", BEARER_CTL(rx->gpc), buf->om_len); + + switch (BEARER_CTL(rx->gpc)) { + case LINK_OPEN: + link_open(rx, buf); + break; + case LINK_ACK: + if (!atomic_test_bit(link.flags, LINK_ACTIVE)) { + return; + } + + link_ack(rx, buf); + break; + case LINK_CLOSE: + if (!atomic_test_bit(link.flags, LINK_ACTIVE)) { + return; + } + + link_close(rx, buf); + break; + default: + BT_ERR("Unknown bearer opcode: 0x%02x", BEARER_CTL(rx->gpc)); + + if (IS_ENABLED(CONFIG_BT_TESTING)) { + bt_test_mesh_prov_invalid_bearer(BEARER_CTL(rx->gpc)); + } + + return; + } +} + +static void prov_msg_recv(void) +{ + u8_t type = link.rx.buf->om_data[0]; + + BT_DBG("type 0x%02x len %u", type, link.rx.buf->om_len); + + k_delayed_work_submit(&link.prot_timer, PROTOCOL_TIMEOUT); + + if (!bt_mesh_fcs_check(link.rx.buf, link.rx.fcs)) { + BT_ERR("Incorrect FCS"); + return; + } + + gen_prov_ack_send(link.rx.id); + link.rx.prev_id = link.rx.id; + link.rx.id = 0; + + if (atomic_test_bit(link.flags, LINK_INVALID)) { + BT_WARN("Unexpected msg 0x%02x on invalidated link", type); + prov_send_fail_msg(PROV_ERR_UNEXP_PDU); + return; + } + + if (type != PROV_FAILED && type != link.expect) { + BT_WARN("Unexpected msg 0x%02x != 0x%02x", type, link.expect); + prov_send_fail_msg(PROV_ERR_UNEXP_PDU); + return; + } + + if (type >= ARRAY_SIZE(prov_handlers)) { + BT_ERR("Unknown provisioning PDU type 0x%02x", type); + prov_send_fail_msg(PROV_ERR_NVAL_PDU); + return; + } + + if (1 + prov_handlers[type].len != link.rx.buf->om_len) { + BT_ERR("Invalid length %u for type 0x%02x", + link.rx.buf->om_len, type); + prov_send_fail_msg(PROV_ERR_NVAL_FMT); + return; + } + + prov_handlers[type].func(&link.rx.buf->om_data[1]); +} + +static void gen_prov_cont(struct prov_rx *rx, struct os_mbuf *buf) +{ + u8_t seg = CONT_SEG_INDEX(rx->gpc); + + BT_DBG("len %u, seg_index %u", buf->om_len, seg); + + if (!link.rx.seg && link.rx.prev_id == rx->xact_id) { + BT_WARN("Resending ack"); + gen_prov_ack_send(rx->xact_id); + return; + } + + if (rx->xact_id != link.rx.id) { + BT_WARN("Data for unknown transaction (%u != %u)", + rx->xact_id, link.rx.id); + return; + } + + if (seg > link.rx.last_seg) { + BT_ERR("Invalid segment index %u", seg); + prov_send_fail_msg(PROV_ERR_NVAL_FMT); + return; + } else if (seg == link.rx.last_seg) { + u8_t expect_len; + + expect_len = (link.rx.buf->om_len - 20 - + ((link.rx.last_seg - 1) * 23)); + if (expect_len != buf->om_len) { + BT_ERR("Incorrect last seg len: %u != %u", + expect_len, buf->om_len); + prov_send_fail_msg(PROV_ERR_NVAL_FMT); + return; + } + } + + if (!(link.rx.seg & BIT(seg))) { + BT_WARN("Ignoring already received segment"); + return; + } + + memcpy(XACT_SEG_DATA(seg), buf->om_data, buf->om_len); + XACT_SEG_RECV(seg); + + if (!link.rx.seg) { + prov_msg_recv(); + } +} + +static void gen_prov_ack(struct prov_rx *rx, struct os_mbuf *buf) +{ + BT_DBG("len %u", buf->om_len); + + if (!link.tx.buf[0]) { + return; + } + + if (rx->xact_id == link.tx.id) { + prov_clear_tx(); + } +} + +static void gen_prov_start(struct prov_rx *rx, struct os_mbuf *buf) +{ + u16_t trailing_space = 0; + + if (link.rx.seg) { + BT_WARN("Got Start while there are unreceived segments"); + return; + } + + if (link.rx.prev_id == rx->xact_id) { + BT_WARN("Resending ack"); + gen_prov_ack_send(rx->xact_id); + return; + } + + trailing_space = OS_MBUF_TRAILINGSPACE(link.rx.buf); + + link.rx.buf->om_len = net_buf_simple_pull_be16(buf); + link.rx.id = rx->xact_id; + link.rx.fcs = net_buf_simple_pull_u8(buf); + + BT_DBG("len %u last_seg %u total_len %u fcs 0x%02x", buf->om_len, + START_LAST_SEG(rx->gpc), link.rx.buf->om_len, link.rx.fcs); + + if (link.rx.buf->om_len < 1) { + BT_ERR("Ignoring zero-length provisioning PDU"); + prov_send_fail_msg(PROV_ERR_NVAL_FMT); + return; + } + + if (link.rx.buf->om_len > trailing_space) { + BT_ERR("Too large provisioning PDU (%u bytes)", + link.rx.buf->om_len); + prov_send_fail_msg(PROV_ERR_NVAL_FMT); + return; + } + + if (START_LAST_SEG(rx->gpc) > 0 && link.rx.buf->om_len <= 20) { + BT_ERR("Too small total length for multi-segment PDU"); + prov_send_fail_msg(PROV_ERR_NVAL_FMT); + return; + } + + link.rx.seg = (1 << (START_LAST_SEG(rx->gpc) + 1)) - 1; + link.rx.last_seg = START_LAST_SEG(rx->gpc); + memcpy(link.rx.buf->om_data, buf->om_data, buf->om_len); + XACT_SEG_RECV(0); + + if (!link.rx.seg) { + prov_msg_recv(); + } +} + +static const struct { + void (*const func)(struct prov_rx *rx, struct os_mbuf *buf); + const u8_t require_link; + const u8_t min_len; +} gen_prov[] = { + { gen_prov_start, true, 3 }, + { gen_prov_ack, true, 0 }, + { gen_prov_cont, true, 0 }, + { gen_prov_ctl, false, 0 }, +}; + +static void gen_prov_recv(struct prov_rx *rx, struct os_mbuf *buf) +{ + if (buf->om_len < gen_prov[GPCF(rx->gpc)].min_len) { + BT_ERR("Too short GPC message type %u", GPCF(rx->gpc)); + return; + } + + if (!atomic_test_bit(link.flags, LINK_ACTIVE) && + gen_prov[GPCF(rx->gpc)].require_link) { + BT_DBG("Ignoring message that requires active link"); + return; + } + + BT_DBG("prov_action: %d", GPCF(rx->gpc)); + gen_prov[GPCF(rx->gpc)].func(rx, buf); +} + +void bt_mesh_pb_adv_recv(struct os_mbuf *buf) +{ + struct prov_rx rx; + + if (!bt_prov_active() && bt_mesh_is_provisioned()) { + BT_DBG("Ignoring provisioning PDU - already provisioned"); + return; + } + + if (buf->om_len < 6) { + BT_WARN("Too short provisioning packet (len %u)", buf->om_len); + return; + } + + rx.link_id = net_buf_simple_pull_be32(buf); + rx.xact_id = net_buf_simple_pull_u8(buf); + rx.gpc = net_buf_simple_pull_u8(buf); + + BT_DBG("link_id 0x%08x xact_id %u", (unsigned) rx.link_id, rx.xact_id); + + if (atomic_test_bit(link.flags, LINK_ACTIVE) && link.id != rx.link_id) { + BT_DBG("Ignoring mesh beacon for unknown link"); + return; + } + + gen_prov_recv(&rx, buf); +} +#endif /* MYNEWT_VAL(BLE_MESH_PB_ADV) */ + +#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) +int bt_mesh_pb_gatt_recv(uint16_t conn_handle, struct os_mbuf *buf) +{ + u8_t type; + + BT_DBG("%u bytes: %s", buf->om_len, bt_hex(buf->om_data, buf->om_len)); + + if (link.conn_handle != conn_handle) { + BT_WARN("Data for unexpected connection"); + return -ENOTCONN; + } + + if (buf->om_len < 1) { + BT_WARN("Too short provisioning packet (len %u)", buf->om_len); + return -EINVAL; + } + + type = net_buf_simple_pull_u8(buf); + if (type != PROV_FAILED && type != link.expect) { + BT_WARN("Unexpected msg 0x%02x != 0x%02x", type, link.expect); + prov_send_fail_msg(PROV_ERR_UNEXP_PDU); + return -EINVAL; + } + + if (type >= ARRAY_SIZE(prov_handlers)) { + BT_ERR("Unknown provisioning PDU type 0x%02x", type); + return -EINVAL; + } + + if (prov_handlers[type].len != buf->om_len) { + BT_ERR("Invalid length %u for type 0x%02x", buf->om_len, type); + return -EINVAL; + } + + prov_handlers[type].func(buf->om_data); + + return 0; +} + +int bt_mesh_pb_gatt_open(uint16_t conn_handle) +{ + BT_DBG("conn_handle %d", conn_handle); + + if (atomic_test_and_set_bit(link.flags, LINK_ACTIVE)) { + BT_ERR("Link already opened?"); + return -EBUSY; + } + + link.conn_handle = conn_handle; + link.expect = PROV_INVITE; + + if (prov->link_open) { + prov->link_open(BT_MESH_PROV_GATT); + } + + return 0; +} + +int bt_mesh_pb_gatt_close(uint16_t conn_handle) +{ + BT_DBG("conn_handle %d", conn_handle); + + if (link.conn_handle != conn_handle) { + BT_ERR("Not connected"); + return -ENOTCONN; + } + + if (prov->link_close) { + prov->link_close(BT_MESH_PROV_GATT); + } + + return reset_state(); +} +#endif /* MYNEWT_VAL(BLE_MESH_PB_GATT) */ + +const struct bt_mesh_prov *bt_mesh_prov_get(void) +{ + return prov; +} + +bool bt_prov_active(void) +{ + return atomic_test_bit(link.flags, LINK_ACTIVE); +} + +static void protocol_timeout(struct ble_npl_event *work) +{ + BT_DBG("Protocol timeout"); + +#if MYNEWT_VAL(BLE_MESH_PB_GATT) + if (link.conn_handle != BLE_HS_CONN_HANDLE_NONE) { + bt_mesh_pb_gatt_close(link.conn_handle); + return; + } +#endif + +#if MYNEWT_VAL(BLE_MESH_PB_ADV) + u8_t reason = CLOSE_REASON_TIMEOUT; + + link.rx.seg = 0U; + bearer_ctl_send(LINK_CLOSE, &reason, sizeof(reason)); + + reset_state(); +#endif +} + +int bt_mesh_prov_init(const struct bt_mesh_prov *prov_info) +{ + if (!prov_info) { + BT_ERR("No provisioning context provided"); + return -EINVAL; + } + + k_delayed_work_init(&link.prot_timer, protocol_timeout); + + prov = prov_info; + +#if MYNEWT_VAL(BLE_MESH_PB_ADV) + k_delayed_work_init(&link.tx.retransmit, prov_retransmit); +#endif + + return reset_state(); +} + +void bt_mesh_prov_reset_link(void) +{ +#if (MYNEWT_VAL(BLE_MESH_PB_ADV)) +#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) + link.rx.buf = bt_mesh_proxy_get_buf(); +#else + net_buf_simple_init(rx_buf, 0); + link.rx.buf = rx_buf; +#endif +#endif +} + +void bt_mesh_prov_complete(u16_t net_idx, u16_t addr) +{ + if (prov->complete) { + prov->complete(net_idx, addr); + } +} + +void bt_mesh_prov_reset(void) +{ + if (prov->reset) { + prov->reset(); + } +} + +#endif /* MYNEWT_VAL(BLE_MESH_PROV) */ diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/prov.h b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/prov.h new file mode 100644 index 000000000..3675b6cc7 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/prov.h @@ -0,0 +1,33 @@ +/* Bluetooth Mesh */ + +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __PROV_H__ +#define __PROV_H__ + +#include "os/os_mbuf.h" +#include "mesh/mesh.h" +#include "../src/ble_hs_conn_priv.h" + +void bt_mesh_pb_adv_recv(struct os_mbuf *buf); + +bool bt_prov_active(void); + +int bt_mesh_pb_gatt_open(uint16_t conn_handle); +int bt_mesh_pb_gatt_close(uint16_t conn_handle); +int bt_mesh_pb_gatt_recv(uint16_t conn_handle, struct os_mbuf *buf); + +const struct bt_mesh_prov *bt_mesh_prov_get(void); + +int bt_mesh_prov_init(const struct bt_mesh_prov *prov); + +void bt_mesh_prov_reset_link(void); + +void bt_mesh_prov_complete(u16_t net_idx, u16_t addr); +void bt_mesh_prov_reset(void); + +#endif diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/proxy.c b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/proxy.c new file mode 100644 index 000000000..609da54d2 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/proxy.c @@ -0,0 +1,1464 @@ +/* Bluetooth Mesh */ + +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "syscfg/syscfg.h" + +#if MYNEWT_VAL(BLE_MESH_PROXY) + +#include "mesh/mesh.h" + +#define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG_PROXY)) +#include "host/ble_hs_log.h" +#include "host/ble_att.h" +#include "services/gatt/ble_svc_gatt.h" +#include "../../host/src/ble_hs_priv.h" + +#include "mesh_priv.h" +#include "adv.h" +#include "net.h" +#include "prov.h" +#include "beacon.h" +#include "foundation.h" +#include "access.h" +#include "proxy.h" + +#define PDU_TYPE(data) (data[0] & BIT_MASK(6)) +#define PDU_SAR(data) (data[0] >> 6) + +/* Mesh Profile 1.0 Section 6.6: + * "The timeout for the SAR transfer is 20 seconds. When the timeout + * expires, the Proxy Server shall disconnect." + */ +#define PROXY_SAR_TIMEOUT K_SECONDS(20) + +#define SAR_COMPLETE 0x00 +#define SAR_FIRST 0x01 +#define SAR_CONT 0x02 +#define SAR_LAST 0x03 + +#define CFG_FILTER_SET 0x00 +#define CFG_FILTER_ADD 0x01 +#define CFG_FILTER_REMOVE 0x02 +#define CFG_FILTER_STATUS 0x03 + +/** @def BT_UUID_MESH_PROV + * @brief Mesh Provisioning Service + */ +ble_uuid16_t BT_UUID_MESH_PROV = BLE_UUID16_INIT(0x1827); +#define BT_UUID_MESH_PROV_VAL 0x1827 +/** @def BT_UUID_MESH_PROXY + * @brief Mesh Proxy Service + */ +ble_uuid16_t BT_UUID_MESH_PROXY = BLE_UUID16_INIT(0x1828); +#define BT_UUID_MESH_PROXY_VAL 0x1828 +/** @def BT_UUID_GATT_CCC + * @brief GATT Client Characteristic Configuration + */ +ble_uuid16_t BT_UUID_GATT_CCC = BLE_UUID16_INIT(0x2902); +#define BT_UUID_GATT_CCC_VAL 0x2902 +/** @def BT_UUID_MESH_PROV_DATA_IN + * @brief Mesh Provisioning Data In + */ +ble_uuid16_t BT_UUID_MESH_PROV_DATA_IN = BLE_UUID16_INIT(0x2adb); +#define BT_UUID_MESH_PROV_DATA_IN_VAL 0x2adb +/** @def BT_UUID_MESH_PROV_DATA_OUT + * @brief Mesh Provisioning Data Out + */ +ble_uuid16_t BT_UUID_MESH_PROV_DATA_OUT = BLE_UUID16_INIT(0x2adc); +#define BT_UUID_MESH_PROV_DATA_OUT_VAL 0x2adc +/** @def BT_UUID_MESH_PROXY_DATA_IN + * @brief Mesh Proxy Data In + */ +ble_uuid16_t BT_UUID_MESH_PROXY_DATA_IN = BLE_UUID16_INIT(0x2add); +#define BT_UUID_MESH_PROXY_DATA_IN_VAL 0x2add +/** @def BT_UUID_MESH_PROXY_DATA_OUT + * @brief Mesh Proxy Data Out + */ +ble_uuid16_t BT_UUID_MESH_PROXY_DATA_OUT = BLE_UUID16_INIT(0x2ade); +#define BT_UUID_MESH_PROXY_DATA_OUT_VAL 0x2ade + +#define PDU_HDR(sar, type) (sar << 6 | (type & BIT_MASK(6))) + +#define CLIENT_BUF_SIZE 68 + +static const struct ble_gap_adv_params slow_adv_param = { + .conn_mode = (BLE_GAP_CONN_MODE_UND), + .disc_mode = (BLE_GAP_DISC_MODE_GEN), + .itvl_min = BT_GAP_ADV_SLOW_INT_MIN, + .itvl_max = BT_GAP_ADV_SLOW_INT_MAX, +}; + +static const struct ble_gap_adv_params fast_adv_param = { + .conn_mode = (BLE_GAP_CONN_MODE_UND), + .disc_mode = (BLE_GAP_DISC_MODE_GEN), + .itvl_min = BT_GAP_ADV_FAST_INT_MIN_2, + .itvl_max = BT_GAP_ADV_FAST_INT_MAX_2, +}; + +static bool proxy_adv_enabled; + +#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) +static void proxy_send_beacons(struct ble_npl_event *work); +#endif + +#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) +static bool prov_fast_adv; +#endif + +static struct bt_mesh_proxy_client { + uint16_t conn_handle; + u16_t filter[MYNEWT_VAL(BLE_MESH_PROXY_FILTER_SIZE)]; + enum __packed { + NONE, + WHITELIST, + BLACKLIST, + PROV, + } filter_type; + u8_t msg_type; +#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) + struct ble_npl_callout send_beacons; +#endif + struct k_delayed_work sar_timer; + struct os_mbuf *buf; +} clients[MYNEWT_VAL(BLE_MAX_CONNECTIONS)] = { + [0 ... (MYNEWT_VAL(BLE_MAX_CONNECTIONS) - 1)] = { 0 }, +}; + +/* Track which service is enabled */ +static enum { + MESH_GATT_NONE, + MESH_GATT_PROV, + MESH_GATT_PROXY, +} gatt_svc = MESH_GATT_NONE; + +static struct { + uint16_t proxy_h; + uint16_t proxy_data_out_h; + uint16_t prov_h; + uint16_t prov_data_in_h; + uint16_t prov_data_out_h; +} svc_handles; + +static void resolve_svc_handles(void) +{ + int rc; + + /* Either all handles are already resolved, or none of them */ + if (svc_handles.prov_data_out_h) { + return; + } + + /* + * We assert if attribute is not found since at this stage all attributes + * shall be already registered and thus shall be found. + */ + + rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL), + &svc_handles.proxy_h); + assert(rc == 0); + + rc = ble_gatts_find_chr(BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL), + BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_DATA_OUT_VAL), + NULL, &svc_handles.proxy_data_out_h); + assert(rc == 0); + + rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), + &svc_handles.prov_h); + assert(rc == 0); + + rc = ble_gatts_find_chr(BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), + BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_DATA_IN_VAL), + NULL, &svc_handles.prov_data_in_h); + assert(rc == 0); + + rc = ble_gatts_find_chr(BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), + BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_DATA_OUT_VAL), + NULL, &svc_handles.prov_data_out_h); + assert(rc == 0); +} + +static struct bt_mesh_proxy_client *find_client(uint16_t conn_handle) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(clients); i++) { + if (clients[i].conn_handle == conn_handle) { + return &clients[i]; + } + } + + return NULL; +} + +#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) +/* Next subnet in queue to be advertised */ +static int next_idx; + +static int proxy_segment_and_send(uint16_t conn_handle, u8_t type, + struct os_mbuf *msg); + +static int filter_set(struct bt_mesh_proxy_client *client, + struct os_mbuf *buf) +{ + u8_t type; + + if (buf->om_len < 1) { + BT_WARN("Too short Filter Set message"); + return -EINVAL; + } + + type = net_buf_simple_pull_u8(buf); + BT_DBG("type 0x%02x", type); + + switch (type) { + case 0x00: + memset(client->filter, 0, sizeof(client->filter)); + client->filter_type = WHITELIST; + break; + case 0x01: + memset(client->filter, 0, sizeof(client->filter)); + client->filter_type = BLACKLIST; + break; + default: + BT_WARN("Prohibited Filter Type 0x%02x", type); + return -EINVAL; + } + + return 0; +} + +static void filter_add(struct bt_mesh_proxy_client *client, u16_t addr) +{ + int i; + + BT_DBG("addr 0x%04x", addr); + + if (addr == BT_MESH_ADDR_UNASSIGNED) { + return; + } + + for (i = 0; i < ARRAY_SIZE(client->filter); i++) { + if (client->filter[i] == addr) { + return; + } + } + + for (i = 0; i < ARRAY_SIZE(client->filter); i++) { + if (client->filter[i] == BT_MESH_ADDR_UNASSIGNED) { + client->filter[i] = addr; + return; + } + } +} + +static void filter_remove(struct bt_mesh_proxy_client *client, u16_t addr) +{ + int i; + + BT_DBG("addr 0x%04x", addr); + + if (addr == BT_MESH_ADDR_UNASSIGNED) { + return; + } + + for (i = 0; i < ARRAY_SIZE(client->filter); i++) { + if (client->filter[i] == addr) { + client->filter[i] = BT_MESH_ADDR_UNASSIGNED; + return; + } + } +} + +static void send_filter_status(struct bt_mesh_proxy_client *client, + struct bt_mesh_net_rx *rx, + struct os_mbuf *buf) +{ + struct bt_mesh_net_tx tx = { + .sub = rx->sub, + .ctx = &rx->ctx, + .src = bt_mesh_primary_addr(), + }; + u16_t filter_size; + int i, err; + + /* Configuration messages always have dst unassigned */ + tx.ctx->addr = BT_MESH_ADDR_UNASSIGNED; + + net_buf_simple_init(buf, 10); + + net_buf_simple_add_u8(buf, CFG_FILTER_STATUS); + + if (client->filter_type == WHITELIST) { + net_buf_simple_add_u8(buf, 0x00); + } else { + net_buf_simple_add_u8(buf, 0x01); + } + + for (filter_size = 0, i = 0; i < ARRAY_SIZE(client->filter); i++) { + if (client->filter[i] != BT_MESH_ADDR_UNASSIGNED) { + filter_size++; + } + } + + net_buf_simple_add_be16(buf, filter_size); + + BT_DBG("%u bytes: %s", buf->om_len, bt_hex(buf->om_data, buf->om_len)); + + err = bt_mesh_net_encode(&tx, buf, true); + if (err) { + BT_ERR("Encoding Proxy cfg message failed (err %d)", err); + return; + } + + err = proxy_segment_and_send(client->conn_handle, BT_MESH_PROXY_CONFIG, buf); + if (err) { + BT_ERR("Failed to send proxy cfg message (err %d)", err); + } +} + +static void proxy_cfg(struct bt_mesh_proxy_client *client) +{ + struct os_mbuf *buf = NET_BUF_SIMPLE(29); + struct bt_mesh_net_rx rx; + u8_t opcode; + int err; + + err = bt_mesh_net_decode(client->buf, BT_MESH_NET_IF_PROXY_CFG, + &rx, buf); + if (err) { + BT_ERR("Failed to decode Proxy Configuration (err %d)", err); + goto done; + } + + /* Remove network headers */ + net_buf_simple_pull(buf, BT_MESH_NET_HDR_LEN); + + BT_DBG("%u bytes: %s", buf->om_len, bt_hex(buf->om_data, buf->om_len)); + + if (buf->om_len < 1) { + BT_WARN("Too short proxy configuration PDU"); + goto done; + } + + opcode = net_buf_simple_pull_u8(buf); + switch (opcode) { + case CFG_FILTER_SET: + filter_set(client, buf); + send_filter_status(client, &rx, buf); + break; + case CFG_FILTER_ADD: + while (buf->om_len >= 2) { + u16_t addr; + + addr = net_buf_simple_pull_be16(buf); + filter_add(client, addr); + } + send_filter_status(client, &rx, buf); + break; + case CFG_FILTER_REMOVE: + while (buf->om_len >= 2) { + u16_t addr; + + addr = net_buf_simple_pull_be16(buf); + filter_remove(client, addr); + } + send_filter_status(client, &rx, buf); + break; + default: + BT_WARN("Unhandled configuration OpCode 0x%02x", opcode); + break; + } + +done: + os_mbuf_free_chain(buf); +} + +static int beacon_send(uint16_t conn_handle, struct bt_mesh_subnet *sub) +{ + struct os_mbuf *buf = NET_BUF_SIMPLE(23); + int rc; + + net_buf_simple_init(buf, 1); + bt_mesh_beacon_create(sub, buf); + + rc = proxy_segment_and_send(conn_handle, BT_MESH_PROXY_BEACON, buf); + os_mbuf_free_chain(buf); + return rc; +} + +static void proxy_send_beacons(struct ble_npl_event *work) +{ + struct bt_mesh_proxy_client *client; + int i; + + + client = ble_npl_event_get_arg(work); + + for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) { + struct bt_mesh_subnet *sub = &bt_mesh.sub[i]; + + if (sub->net_idx != BT_MESH_KEY_UNUSED) { + beacon_send(client->conn_handle, sub); + } + } +} + +static void proxy_sar_timeout(struct ble_npl_event *work) +{ + struct bt_mesh_proxy_client *client; + int rc; + + BT_WARN("Proxy SAR timeout"); + + client = ble_npl_event_get_arg(work); + assert(client != NULL); + + if ((client->conn_handle != BLE_HS_CONN_HANDLE_NONE)) { + rc = ble_gap_terminate(client->conn_handle, + BLE_ERR_REM_USER_CONN_TERM); + assert(rc == 0); + } +} + +void bt_mesh_proxy_beacon_send(struct bt_mesh_subnet *sub) +{ + int i; + + if (!sub) { + /* NULL means we send on all subnets */ + for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) { + if (bt_mesh.sub[i].net_idx != BT_MESH_KEY_UNUSED) { + bt_mesh_proxy_beacon_send(&bt_mesh.sub[i]); + } + } + + return; + } + + for (i = 0; i < ARRAY_SIZE(clients); i++) { + if (clients[i].conn_handle != BLE_HS_CONN_HANDLE_NONE) { + beacon_send(clients[i].conn_handle, sub); + } + } +} + +void bt_mesh_proxy_identity_start(struct bt_mesh_subnet *sub) +{ + sub->node_id = BT_MESH_NODE_IDENTITY_RUNNING; + sub->node_id_start = k_uptime_get_32(); + + /* Prioritize the recently enabled subnet */ + next_idx = sub - bt_mesh.sub; +} + +void bt_mesh_proxy_identity_stop(struct bt_mesh_subnet *sub) +{ + sub->node_id = BT_MESH_NODE_IDENTITY_STOPPED; + sub->node_id_start = 0; +} + +int bt_mesh_proxy_identity_enable(void) +{ + int i, count = 0; + + BT_DBG(""); + + if (!bt_mesh_is_provisioned()) { + return -EAGAIN; + } + + for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) { + struct bt_mesh_subnet *sub = &bt_mesh.sub[i]; + + if (sub->net_idx == BT_MESH_KEY_UNUSED) { + continue; + } + + if (sub->node_id == BT_MESH_NODE_IDENTITY_NOT_SUPPORTED) { + continue; + } + + bt_mesh_proxy_identity_start(sub); + count++; + } + + if (count) { + bt_mesh_adv_update(); + } + + return 0; +} + +#endif /* GATT_PROXY */ + +static void proxy_complete_pdu(struct bt_mesh_proxy_client *client) +{ + switch (client->msg_type) { +#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) + case BT_MESH_PROXY_NET_PDU: + BT_INFO("Mesh Network PDU"); + bt_mesh_net_recv(client->buf, 0, BT_MESH_NET_IF_PROXY); + break; + case BT_MESH_PROXY_BEACON: + BT_INFO("Mesh Beacon PDU"); + bt_mesh_beacon_recv(client->buf); + break; + case BT_MESH_PROXY_CONFIG: + BT_INFO("Mesh Configuration PDU"); + proxy_cfg(client); + break; +#endif +#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) + case BT_MESH_PROXY_PROV: + BT_INFO("Mesh Provisioning PDU"); + bt_mesh_pb_gatt_recv(client->conn_handle, client->buf); + break; +#endif + default: + BT_WARN("Unhandled Message Type 0x%02x", client->msg_type); + break; + } + + net_buf_simple_init(client->buf, 0); +} + +static int proxy_recv(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg) +{ + struct bt_mesh_proxy_client *client; + const u8_t *data = ctxt->om->om_data; + u16_t len = ctxt->om->om_len; + + client = find_client(conn_handle); + + if (!client) { + return -ENOTCONN; + } + + if (len < 1) { + BT_WARN("Too small Proxy PDU"); + return -EINVAL; + } + + if ((attr_handle == svc_handles.prov_data_in_h) != + (PDU_TYPE(data) == BT_MESH_PROXY_PROV)) { + BT_WARN("Proxy PDU type doesn't match GATT service"); + return -EINVAL; + } + + if (len - 1 > net_buf_simple_tailroom(client->buf)) { + BT_WARN("Too big proxy PDU"); + return -EINVAL; + } + + switch (PDU_SAR(data)) { + case SAR_COMPLETE: + if (client->buf->om_len) { + BT_WARN("Complete PDU while a pending incomplete one"); + return -EINVAL; + } + + client->msg_type = PDU_TYPE(data); + net_buf_simple_add_mem(client->buf, data + 1, len - 1); + proxy_complete_pdu(client); + break; + + case SAR_FIRST: + if (client->buf->om_len) { + BT_WARN("First PDU while a pending incomplete one"); + return -EINVAL; + } + + k_delayed_work_submit(&client->sar_timer, PROXY_SAR_TIMEOUT); + client->msg_type = PDU_TYPE(data); + net_buf_simple_add_mem(client->buf, data + 1, len - 1); + break; + + case SAR_CONT: + if (!client->buf->om_len) { + BT_WARN("Continuation with no prior data"); + return -EINVAL; + } + + if (client->msg_type != PDU_TYPE(data)) { + BT_WARN("Unexpected message type in continuation"); + return -EINVAL; + } + + k_delayed_work_submit(&client->sar_timer, PROXY_SAR_TIMEOUT); + net_buf_simple_add_mem(client->buf, data + 1, len - 1); + break; + + case SAR_LAST: + if (!client->buf->om_len) { + BT_WARN("Last SAR PDU with no prior data"); + return -EINVAL; + } + + if (client->msg_type != PDU_TYPE(data)) { + BT_WARN("Unexpected message type in last SAR PDU"); + return -EINVAL; + } + + k_delayed_work_cancel(&client->sar_timer); + net_buf_simple_add_mem(client->buf, data + 1, len - 1); + proxy_complete_pdu(client); + break; + } + + return len; +} + +static int conn_count; + +static void proxy_connected(uint16_t conn_handle) +{ + struct bt_mesh_proxy_client *client; + int i; + + BT_INFO("conn_handle %d", conn_handle); + + conn_count++; + + /* Since we use ADV_OPT_ONE_TIME */ + proxy_adv_enabled = false; + + /* Try to re-enable advertising in case it's possible */ + if (conn_count < CONFIG_BT_MAX_CONN) { + bt_mesh_adv_update(); + } + + for (client = NULL, i = 0; i < ARRAY_SIZE(clients); i++) { + if (clients[i].conn_handle == BLE_HS_CONN_HANDLE_NONE) { + client = &clients[i]; + break; + } + } + + if (!client) { + BT_ERR("No free Proxy Client objects"); + return; + } + + client->conn_handle = conn_handle; + client->filter_type = NONE; + memset(client->filter, 0, sizeof(client->filter)); + net_buf_simple_init(client->buf, 0); +} + +static void proxy_disconnected(uint16_t conn_handle, int reason) +{ + int i; + + BT_INFO("conn_handle %d reason %d", conn_handle, reason); + + conn_count--; + + for (i = 0; i < ARRAY_SIZE(clients); i++) { + struct bt_mesh_proxy_client *client = &clients[i]; + + if (client->conn_handle == conn_handle) { + if ((MYNEWT_VAL(BLE_MESH_PB_GATT)) && + client->filter_type == PROV) { + bt_mesh_pb_gatt_close(conn_handle); + } + + k_delayed_work_cancel(&client->sar_timer); + client->conn_handle = BLE_HS_CONN_HANDLE_NONE; + break; + } + } + + bt_mesh_adv_update(); +} + +struct os_mbuf *bt_mesh_proxy_get_buf(void) +{ + struct os_mbuf *buf = clients[0].buf; + + if (buf != NULL) { + net_buf_simple_init(buf, 0); + } + + return buf; +} + +#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) +static void prov_ccc_write(uint16_t conn_handle) +{ + struct bt_mesh_proxy_client *client; + + BT_DBG("conn_handle %d", conn_handle); + + /* If a connection exists there must be a client */ + client = find_client(conn_handle); + __ASSERT(client, "No client for connection"); + + if (client->filter_type == NONE) { + client->filter_type = PROV; + bt_mesh_pb_gatt_open(conn_handle); + } +} + +int bt_mesh_proxy_prov_enable(void) +{ + uint16_t handle; + int rc; + int i; + + BT_DBG(""); + + if (gatt_svc == MESH_GATT_PROV) { + return -EALREADY; + } + + if (gatt_svc != MESH_GATT_NONE) { + return -EBUSY; + } + + rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), &handle); + assert(rc == 0); + ble_gatts_svc_set_visibility(handle, 1); + /* FIXME: figure out end handle */ + ble_svc_gatt_changed(svc_handles.prov_h, 0xffff); + + gatt_svc = MESH_GATT_PROV; + prov_fast_adv = true; + + for (i = 0; i < ARRAY_SIZE(clients); i++) { + if (clients[i].conn_handle != BLE_HS_CONN_HANDLE_NONE) { + clients[i].filter_type = PROV; + } + } + + + return 0; +} + +int bt_mesh_proxy_prov_disable(void) +{ + uint16_t handle; + int rc; + int i; + + BT_DBG(""); + + if (gatt_svc == MESH_GATT_NONE) { + return -EALREADY; + } + + if (gatt_svc != MESH_GATT_PROV) { + return -EBUSY; + } + + rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), &handle); + assert(rc == 0); + ble_gatts_svc_set_visibility(handle, 0); + /* FIXME: figure out end handle */ + ble_svc_gatt_changed(svc_handles.prov_h, 0xffff); + + gatt_svc = MESH_GATT_NONE; + + for (i = 0; i < ARRAY_SIZE(clients); i++) { + struct bt_mesh_proxy_client *client = &clients[i]; + + if ((client->conn_handle != BLE_HS_CONN_HANDLE_NONE) + && (client->filter_type == PROV)) { + bt_mesh_pb_gatt_close(client->conn_handle); + client->filter_type = NONE; + } + } + + return 0; +} +#endif /* MYNEWT_VAL(BLE_MESH_PB_GATT) */ + +#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) +static void proxy_ccc_write(uint16_t conn_handle) +{ + struct bt_mesh_proxy_client *client; + + BT_DBG("conn_handle %d", conn_handle); + + client = find_client(conn_handle); + __ASSERT(client, "No client for connection"); + + if (client->filter_type == NONE) { + client->filter_type = WHITELIST; + k_work_add_arg(&client->send_beacons, client); + k_work_submit(&client->send_beacons); + } +} + +int bt_mesh_proxy_gatt_enable(void) +{ + uint16_t handle; + int rc; + int i; + + BT_DBG(""); + + if (gatt_svc == MESH_GATT_PROXY) { + return -EALREADY; + } + + if (gatt_svc != MESH_GATT_NONE) { + return -EBUSY; + } + + rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL), &handle); + assert(rc == 0); + ble_gatts_svc_set_visibility(handle, 1); + /* FIXME: figure out end handle */ + ble_svc_gatt_changed(svc_handles.proxy_h, 0xffff); + + gatt_svc = MESH_GATT_PROXY; + + for (i = 0; i < ARRAY_SIZE(clients); i++) { + if (clients[i].conn_handle != BLE_HS_CONN_HANDLE_NONE) { + clients[i].filter_type = WHITELIST; + } + } + + return 0; +} + +void bt_mesh_proxy_gatt_disconnect(void) +{ + int rc; + int i; + + BT_DBG(""); + + for (i = 0; i < ARRAY_SIZE(clients); i++) { + struct bt_mesh_proxy_client *client = &clients[i]; + + if ((client->conn_handle != BLE_HS_CONN_HANDLE_NONE) && + (client->filter_type == WHITELIST || + client->filter_type == BLACKLIST)) { + client->filter_type = NONE; + rc = ble_gap_terminate(client->conn_handle, + BLE_ERR_REM_USER_CONN_TERM); + assert(rc == 0); + } + } +} + +int bt_mesh_proxy_gatt_disable(void) +{ + uint16_t handle; + int rc; + + BT_DBG(""); + + if (gatt_svc == MESH_GATT_NONE) { + return -EALREADY; + } + + if (gatt_svc != MESH_GATT_PROXY) { + return -EBUSY; + } + + bt_mesh_proxy_gatt_disconnect(); + + rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL), &handle); + assert(rc == 0); + ble_gatts_svc_set_visibility(handle, 0); + /* FIXME: figure out end handle */ + ble_svc_gatt_changed(svc_handles.proxy_h, 0xffff); + + gatt_svc = MESH_GATT_NONE; + + return 0; +} + +void bt_mesh_proxy_addr_add(struct os_mbuf *buf, u16_t addr) +{ + struct bt_mesh_proxy_client *client = NULL; + int i; + + for (i = 0; i < ARRAY_SIZE(clients); i++) { + client = &clients[i]; + if (client->buf == buf) { + break; + } + } + + assert(client); + + BT_DBG("filter_type %u addr 0x%04x", client->filter_type, addr); + + if (client->filter_type == WHITELIST) { + filter_add(client, addr); + } else if (client->filter_type == BLACKLIST) { + filter_remove(client, addr); + } +} + +static bool client_filter_match(struct bt_mesh_proxy_client *client, + u16_t addr) +{ + int i; + + BT_DBG("filter_type %u addr 0x%04x", client->filter_type, addr); + + if (client->filter_type == WHITELIST) { + for (i = 0; i < ARRAY_SIZE(client->filter); i++) { + if (client->filter[i] == addr) { + return true; + } + } + + return false; + } + + if (client->filter_type == BLACKLIST) { + for (i = 0; i < ARRAY_SIZE(client->filter); i++) { + if (client->filter[i] == addr) { + return false; + } + } + + return true; + } + + return false; +} + +bool bt_mesh_proxy_relay(struct os_mbuf *buf, u16_t dst) +{ + bool relayed = false; + int i; + + BT_DBG("%u bytes to dst 0x%04x", buf->om_len, dst); + + for (i = 0; i < ARRAY_SIZE(clients); i++) { + struct bt_mesh_proxy_client *client = &clients[i]; + struct os_mbuf *msg; + + if (client->conn_handle == BLE_HS_CONN_HANDLE_NONE) { + continue; + } + + if (!client_filter_match(client, dst)) { + continue; + } + + /* Proxy PDU sending modifies the original buffer, + * so we need to make a copy. + */ + msg = NET_BUF_SIMPLE(32); + net_buf_simple_init(msg, 1); + net_buf_simple_add_mem(msg, buf->om_data, buf->om_len); + + bt_mesh_proxy_send(client->conn_handle, BT_MESH_PROXY_NET_PDU, msg); + os_mbuf_free_chain(msg); + relayed = true; + } + + return relayed; +} + +#endif /* MYNEWT_VAL(BLE_MESH_GATT_PROXY) */ + +static int proxy_send(uint16_t conn_handle, const void *data, u16_t len) +{ + struct os_mbuf *om; + + BT_DBG("%u bytes: %s", len, bt_hex(data, len)); + +#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) + if (gatt_svc == MESH_GATT_PROXY) { + om = ble_hs_mbuf_from_flat(data, len); + assert(om); + ble_gattc_notify_custom(conn_handle, svc_handles.proxy_data_out_h, om); + } +#endif + +#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) + if (gatt_svc == MESH_GATT_PROV) { + om = ble_hs_mbuf_from_flat(data, len); + assert(om); + ble_gattc_notify_custom(conn_handle, svc_handles.prov_data_out_h, om); + } +#endif + + return 0; +} + +static int proxy_segment_and_send(uint16_t conn_handle, u8_t type, + struct os_mbuf *msg) +{ + u16_t mtu; + + BT_DBG("conn_handle %d type 0x%02x len %u: %s", conn_handle, type, msg->om_len, + bt_hex(msg->om_data, msg->om_len)); + + /* ATT_MTU - OpCode (1 byte) - Handle (2 bytes) */ + mtu = ble_att_mtu(conn_handle) - 3; + if (mtu > msg->om_len) { + net_buf_simple_push_u8(msg, PDU_HDR(SAR_COMPLETE, type)); + return proxy_send(conn_handle, msg->om_data, msg->om_len); + } + + net_buf_simple_push_u8(msg, PDU_HDR(SAR_FIRST, type)); + proxy_send(conn_handle, msg->om_data, mtu); + net_buf_simple_pull(msg, mtu); + + while (msg->om_len) { + if (msg->om_len + 1 < mtu) { + net_buf_simple_push_u8(msg, PDU_HDR(SAR_LAST, type)); + proxy_send(conn_handle, msg->om_data, msg->om_len); + break; + } + + net_buf_simple_push_u8(msg, PDU_HDR(SAR_CONT, type)); + proxy_send(conn_handle, msg->om_data, mtu); + net_buf_simple_pull(msg, mtu); + } + + return 0; +} + +int bt_mesh_proxy_send(uint16_t conn_handle, u8_t type, + struct os_mbuf *msg) +{ + struct bt_mesh_proxy_client *client = find_client(conn_handle); + + if (!client) { + BT_ERR("No Proxy Client found"); + return -ENOTCONN; + } + + if ((client->filter_type == PROV) != (type == BT_MESH_PROXY_PROV)) { + BT_ERR("Invalid PDU type for Proxy Client"); + return -EINVAL; + } + + return proxy_segment_and_send(conn_handle, type, msg); +} + +#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) +static u8_t prov_svc_data[20] = { 0x27, 0x18, }; + +static const struct bt_data prov_ad[] = { + BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), + BT_DATA_BYTES(BT_DATA_UUID16_ALL, 0x27, 0x18), + BT_DATA(BT_DATA_SVC_DATA16, prov_svc_data, sizeof(prov_svc_data)), +}; +#endif /* PB_GATT */ + +#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) + +#define ID_TYPE_NET 0x00 +#define ID_TYPE_NODE 0x01 + +#define NODE_ID_LEN 19 +#define NET_ID_LEN 11 + +#define NODE_ID_TIMEOUT K_SECONDS(CONFIG_BT_MESH_NODE_ID_TIMEOUT) + +static u8_t proxy_svc_data[NODE_ID_LEN] = { 0x28, 0x18, }; + +static const struct bt_data node_id_ad[] = { + BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), + BT_DATA_BYTES(BT_DATA_UUID16_ALL, 0x28, 0x18), + BT_DATA(BT_DATA_SVC_DATA16, proxy_svc_data, NODE_ID_LEN), +}; + +static const struct bt_data net_id_ad[] = { + BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), + BT_DATA_BYTES(BT_DATA_UUID16_ALL, 0x28, 0x18), + BT_DATA(BT_DATA_SVC_DATA16, proxy_svc_data, NET_ID_LEN), +}; + +static int node_id_adv(struct bt_mesh_subnet *sub) +{ + u8_t tmp[16]; + int err; + + BT_DBG(""); + + proxy_svc_data[2] = ID_TYPE_NODE; + + err = bt_rand(proxy_svc_data + 11, 8); + if (err) { + return err; + } + + memset(tmp, 0, 6); + memcpy(tmp + 6, proxy_svc_data + 11, 8); + sys_put_be16(bt_mesh_primary_addr(), tmp + 14); + + err = bt_encrypt_be(sub->keys[sub->kr_flag].identity, tmp, tmp); + if (err) { + return err; + } + + memcpy(proxy_svc_data + 3, tmp + 8, 8); + + err = bt_le_adv_start(&fast_adv_param, node_id_ad, + ARRAY_SIZE(node_id_ad), NULL, 0); + if (err) { + BT_WARN("Failed to advertise using Node ID (err %d)", err); + return err; + } + + proxy_adv_enabled = true; + + return 0; +} + +static int net_id_adv(struct bt_mesh_subnet *sub) +{ + int err; + + BT_DBG(""); + + proxy_svc_data[2] = ID_TYPE_NET; + + BT_DBG("Advertising with NetId %s", + bt_hex(sub->keys[sub->kr_flag].net_id, 8)); + + memcpy(proxy_svc_data + 3, sub->keys[sub->kr_flag].net_id, 8); + + err = bt_le_adv_start(&slow_adv_param, net_id_ad, + ARRAY_SIZE(net_id_ad), NULL, 0); + if (err) { + BT_WARN("Failed to advertise using Network ID (err %d)", err); + return err; + } + + proxy_adv_enabled = true; + + return 0; +} + +static bool advertise_subnet(struct bt_mesh_subnet *sub) +{ + if (sub->net_idx == BT_MESH_KEY_UNUSED) { + return false; + } + + return (sub->node_id == BT_MESH_NODE_IDENTITY_RUNNING || + bt_mesh_gatt_proxy_get() == BT_MESH_GATT_PROXY_ENABLED); +} + +static struct bt_mesh_subnet *next_sub(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) { + struct bt_mesh_subnet *sub; + + sub = &bt_mesh.sub[(i + next_idx) % ARRAY_SIZE(bt_mesh.sub)]; + if (advertise_subnet(sub)) { + next_idx = (next_idx + 1) % ARRAY_SIZE(bt_mesh.sub); + return sub; + } + } + + return NULL; +} + +static int sub_count(void) +{ + int i, count = 0; + + for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) { + struct bt_mesh_subnet *sub = &bt_mesh.sub[i]; + + if (advertise_subnet(sub)) { + count++; + } + } + + return count; +} + +static s32_t gatt_proxy_advertise(struct bt_mesh_subnet *sub) +{ + s32_t remaining = K_FOREVER; + int subnet_count; + + BT_DBG(""); + + if (conn_count == CONFIG_BT_MAX_CONN) { + BT_WARN("Connectable advertising deferred (max connections)"); + return remaining; + } + + if (!sub) { + BT_WARN("No subnets to advertise on"); + return remaining; + } + + if (sub->node_id == BT_MESH_NODE_IDENTITY_RUNNING) { + u32_t active = k_uptime_get_32() - sub->node_id_start; + + if (active < NODE_ID_TIMEOUT) { + remaining = NODE_ID_TIMEOUT - active; + BT_DBG("Node ID active for %u ms, %d ms remaining", + (unsigned) active, (int) remaining); + node_id_adv(sub); + } else { + bt_mesh_proxy_identity_stop(sub); + BT_DBG("Node ID stopped"); + } + } + + if (sub->node_id == BT_MESH_NODE_IDENTITY_STOPPED) { + if (bt_mesh_gatt_proxy_get() == BT_MESH_GATT_PROXY_ENABLED) { + net_id_adv(sub); + } else { + return gatt_proxy_advertise(next_sub()); + } + } + + subnet_count = sub_count(); + BT_DBG("sub_count %u", subnet_count); + if (subnet_count > 1) { + s32_t max_timeout; + + /* We use NODE_ID_TIMEOUT as a starting point since it may + * be less than 60 seconds. Divide this period into at least + * 6 slices, but make sure that a slice is at least one + * second long (to avoid excessive rotation). + */ + max_timeout = NODE_ID_TIMEOUT / max(subnet_count, 6); + max_timeout = max(max_timeout, K_SECONDS(1)); + + if (remaining > max_timeout || remaining < 0) { + remaining = max_timeout; + } + } + + BT_DBG("Advertising %d ms for net_idx 0x%04x", + (int) remaining, sub->net_idx); + + return remaining; +} +#endif /* GATT_PROXY */ + +#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) +static size_t gatt_prov_adv_create(struct bt_data prov_sd[2]) +{ + const struct bt_mesh_prov *prov = bt_mesh_prov_get(); + const char *name = CONFIG_BT_DEVICE_NAME; + size_t name_len = strlen(name); + size_t prov_sd_len = 0; + size_t sd_space = 31; + + memcpy(prov_svc_data + 2, prov->uuid, 16); + sys_put_be16(prov->oob_info, prov_svc_data + 18); + + if (prov->uri) { + size_t uri_len = strlen(prov->uri); + + if (uri_len > 29) { + /* There's no way to shorten an URI */ + BT_WARN("Too long URI to fit advertising packet"); + } else { + prov_sd[0].type = BT_DATA_URI; + prov_sd[0].data_len = uri_len; + prov_sd[0].data = (void *)prov->uri; + sd_space -= 2 + uri_len; + prov_sd_len++; + } + } + + if (sd_space > 2 && name_len > 0) { + sd_space -= 2; + + if (sd_space < name_len) { + prov_sd[prov_sd_len].type = BT_DATA_NAME_SHORTENED; + prov_sd[prov_sd_len].data_len = sd_space; + } else { + prov_sd[prov_sd_len].type = BT_DATA_NAME_COMPLETE; + prov_sd[prov_sd_len].data_len = name_len; + } + + prov_sd[prov_sd_len].data = (void *)name; + prov_sd_len++; + } + + return prov_sd_len; +} +#endif /* PB_GATT */ + +s32_t bt_mesh_proxy_adv_start(void) +{ + BT_DBG(""); + + if (gatt_svc == MESH_GATT_NONE) { + return K_FOREVER; + } + +#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) + if (!bt_mesh_is_provisioned()) { + const struct ble_gap_adv_params *param; + struct bt_data prov_sd[2]; + size_t prov_sd_len; + + if (prov_fast_adv) { + param = &fast_adv_param; + } else { + param = &slow_adv_param; + } + + prov_sd_len = gatt_prov_adv_create(prov_sd); + + if (bt_le_adv_start(param, prov_ad, ARRAY_SIZE(prov_ad), + prov_sd, prov_sd_len) == 0) { + proxy_adv_enabled = true; + + /* Advertise 60 seconds using fast interval */ + if (prov_fast_adv) { + prov_fast_adv = false; + return K_SECONDS(60); + } + } + } +#endif /* PB_GATT */ + +#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) + if (bt_mesh_is_provisioned()) { + return gatt_proxy_advertise(next_sub()); + } +#endif /* GATT_PROXY */ + + return K_FOREVER; +} + +void bt_mesh_proxy_adv_stop(void) +{ + int err; + + BT_DBG("adv_enabled %u", proxy_adv_enabled); + + if (!proxy_adv_enabled) { + return; + } + + err = bt_le_adv_stop(true); + if (err) { + BT_ERR("Failed to stop advertising (err %d)", err); + } else { + proxy_adv_enabled = false; + } +} + +int +ble_mesh_proxy_gap_event(struct ble_gap_event *event, void *arg) +{ + + if (event->type == BLE_GAP_EVENT_CONNECT) { + proxy_connected(event->connect.conn_handle); + } else if (event->type == BLE_GAP_EVENT_DISCONNECT) { + proxy_disconnected(event->disconnect.conn.conn_handle, + event->disconnect.reason); + } else if (event->type == BLE_GAP_EVENT_SUBSCRIBE) { + if (event->subscribe.attr_handle == svc_handles.proxy_data_out_h) { +#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) + proxy_ccc_write(event->subscribe.conn_handle); +#endif + } else if (event->subscribe.attr_handle == + svc_handles.prov_data_out_h) { +#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) + prov_ccc_write(event->subscribe.conn_handle); +#endif + } + } + + return 0; +} + +static int +dummy_access_cb(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg) +{ + /* + * We should never never enter this callback - it's attached to notify-only + * characteristic which are notified directly from mbuf. And we can't pass + * NULL as access_cb because gatts will assert on init... + */ + BLE_HS_DBG_ASSERT(0); + return 0; +} + +static const struct ble_gatt_svc_def svc_defs [] = { + { + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL), + .characteristics = (struct ble_gatt_chr_def[]) { { + .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_DATA_IN_VAL), + .access_cb = proxy_recv, + .flags = BLE_GATT_CHR_F_WRITE_NO_RSP, + }, { + .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_DATA_OUT_VAL), + .access_cb = dummy_access_cb, + .flags = BLE_GATT_CHR_F_NOTIFY, + }, { + 0, /* No more characteristics in this service. */ + } }, + }, { + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), + .characteristics = (struct ble_gatt_chr_def[]) { { + .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_DATA_IN_VAL), + .access_cb = proxy_recv, + .flags = BLE_GATT_CHR_F_WRITE_NO_RSP, + }, { + .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_DATA_OUT_VAL), + .access_cb = dummy_access_cb, + .flags = BLE_GATT_CHR_F_NOTIFY, + }, { + 0, /* No more characteristics in this service. */ + } }, + }, { + 0, /* No more services. */ + }, +}; + +int bt_mesh_proxy_svcs_register(void) +{ + int rc; + + rc = ble_gatts_count_cfg(svc_defs); + assert(rc == 0); + + rc = ble_gatts_add_svcs(svc_defs); + assert(rc == 0); + + return 0; +} + +int bt_mesh_proxy_init(void) +{ + int i; + + for (i = 0; i < MYNEWT_VAL(BLE_MAX_CONNECTIONS); ++i) { +#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) + k_work_init(&clients[i].send_beacons, proxy_send_beacons); +#endif + clients[i].buf = NET_BUF_SIMPLE(CLIENT_BUF_SIZE); + clients[i].conn_handle = BLE_HS_CONN_HANDLE_NONE; + + k_delayed_work_init(&clients[i].sar_timer, proxy_sar_timeout); + k_delayed_work_add_arg(&clients[i].sar_timer, &clients[i]); + } + + resolve_svc_handles(); + + ble_gatts_svc_set_visibility(svc_handles.proxy_h, 0); + ble_gatts_svc_set_visibility(svc_handles.prov_h, 0); + + return 0; +} + +#endif /* MYNEWT_VAL(BLE_MESH_PROXY) */ diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/proxy.h b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/proxy.h new file mode 100644 index 000000000..9f19be07b --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/proxy.h @@ -0,0 +1,45 @@ +/* Bluetooth Mesh */ + +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __PROXY_H__ +#define __PROXY_H__ + +#define BT_MESH_PROXY_NET_PDU 0x00 +#define BT_MESH_PROXY_BEACON 0x01 +#define BT_MESH_PROXY_CONFIG 0x02 +#define BT_MESH_PROXY_PROV 0x03 + +#include "mesh/mesh.h" + +int bt_mesh_proxy_send(uint16_t conn_handle, u8_t type, struct os_mbuf *msg); + +int bt_mesh_proxy_prov_enable(void); +int bt_mesh_proxy_prov_disable(void); + +int bt_mesh_proxy_gatt_enable(void); +int bt_mesh_proxy_gatt_disable(void); +void bt_mesh_proxy_gatt_disconnect(void); + +void bt_mesh_proxy_beacon_send(struct bt_mesh_subnet *sub); + +struct os_mbuf *bt_mesh_proxy_get_buf(void); + +s32_t bt_mesh_proxy_adv_start(void); +void bt_mesh_proxy_adv_stop(void); + +void bt_mesh_proxy_identity_start(struct bt_mesh_subnet *sub); +void bt_mesh_proxy_identity_stop(struct bt_mesh_subnet *sub); + +bool bt_mesh_proxy_relay(struct os_mbuf *buf, u16_t dst); +void bt_mesh_proxy_addr_add(struct os_mbuf *buf, u16_t addr); + +int bt_mesh_proxy_init(void); + +int ble_mesh_proxy_gap_event(struct ble_gap_event *event, void *arg); + +#endif diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/settings.c b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/settings.c new file mode 100644 index 000000000..f0f4a27ea --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/settings.c @@ -0,0 +1,1575 @@ +/* + * Copyright (c) 2018 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "syscfg/syscfg.h" + +#if MYNEWT_VAL(BLE_MESH_SETTINGS) + +#define BT_DBG_ENABLED MYNEWT_VAL(BLE_MESH_DEBUG_SETTINGS) + +#include "mesh/mesh.h" +#include "mesh/glue.h" +#include "net.h" +#include "crypto.h" +#include "transport.h" +#include "access.h" +#include "foundation.h" +#include "proxy.h" +#include "settings.h" + +#include "config/config.h" + +/* Tracking of what storage changes are pending for App and Net Keys. We + * track this in a separate array here instead of within the respective + * bt_mesh_app_key and bt_mesh_subnet structs themselves, since once a key + * gets deleted its struct becomes invalid and may be reused for other keys. + */ +static struct key_update { + u16_t key_idx:12, /* AppKey or NetKey Index */ + valid:1, /* 1 if this entry is valid, 0 if not */ + app_key:1, /* 1 if this is an AppKey, 0 if a NetKey */ + clear:1; /* 1 if key needs clearing, 0 if storing */ +} key_updates[CONFIG_BT_MESH_APP_KEY_COUNT + CONFIG_BT_MESH_SUBNET_COUNT]; + +static struct k_delayed_work pending_store; + +/* Mesh network storage information */ +struct net_val { + u16_t primary_addr; + u8_t dev_key[16]; +} __packed; + +/* Sequence number storage */ +struct seq_val { + u8_t val[3]; +} __packed; + +/* Heartbeat Publication storage */ +struct hb_pub_val { + u16_t dst; + u8_t period; + u8_t ttl; + u16_t feat; + u16_t net_idx:12, + indefinite:1; +}; + +/* Miscelaneous configuration server model states */ +struct cfg_val { + u8_t net_transmit; + u8_t relay; + u8_t relay_retransmit; + u8_t beacon; + u8_t gatt_proxy; + u8_t frnd; + u8_t default_ttl; +}; + +/* IV Index & IV Update storage */ +struct iv_val { + u32_t iv_index; + u8_t iv_update:1, + iv_duration:7; +} __packed; + +/* Replay Protection List storage */ +struct rpl_val { + u32_t seq:24, + old_iv:1; +}; + +/* NetKey storage information */ +struct net_key_val { + u8_t kr_flag:1, + kr_phase:7; + u8_t val[2][16]; +} __packed; + +/* AppKey storage information */ +struct app_key_val { + u16_t net_idx; + bool updated; + u8_t val[2][16]; +} __packed; + +struct mod_pub_val { + u16_t addr; + u16_t key; + u8_t ttl; + u8_t retransmit; + u8_t period; + u8_t period_div:4, + cred:1; +}; + +/* We need this so we don't overwrite app-hardcoded values in case FCB + * contains a history of changes but then has a NULL at the end. + */ +static struct { + bool valid; + struct cfg_val cfg; +} stored_cfg; + +static int net_set(int argc, char **argv, char *val) +{ + struct net_val net; + int len, err; + + BT_DBG("val %s", val ? val : "(null)"); + + if (!val) { + bt_mesh_comp_unprovision(); + memset(bt_mesh.dev_key, 0, sizeof(bt_mesh.dev_key)); + return 0; + } + + len = sizeof(net); + err = settings_bytes_from_str(val, &net, &len); + if (err) { + BT_ERR("Failed to decode value %s (err %d)", val, err); + return err; + } + + if (len != sizeof(net)) { + BT_ERR("Unexpected value length (%d != %zu)", len, sizeof(net)); + return -EINVAL; + } + + memcpy(bt_mesh.dev_key, net.dev_key, sizeof(bt_mesh.dev_key)); + bt_mesh_comp_provision(net.primary_addr); + + BT_DBG("Provisioned with primary address 0x%04x", net.primary_addr); + BT_DBG("Recovered DevKey %s", bt_hex(bt_mesh.dev_key, 16)); + + return 0; +} + +static int iv_set(int argc, char **argv, char *val) +{ + struct iv_val iv; + int len, err; + + BT_DBG("val %s", val ? val : "(null)"); + + if (!val) { + bt_mesh.iv_index = 0U; + atomic_clear_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS); + return 0; + } + + len = sizeof(iv); + err = settings_bytes_from_str(val, &iv, &len); + if (err) { + BT_ERR("Failed to decode value %s (err %d)", val, err); + return err; + } + + if (len != sizeof(iv)) { + BT_ERR("Unexpected value length (%d != %zu)", len, sizeof(iv)); + return -EINVAL; + } + + bt_mesh.iv_index = iv.iv_index; + atomic_set_bit_to(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS, iv.iv_update); + bt_mesh.ivu_duration = iv.iv_duration; + + BT_DBG("IV Index 0x%04x (IV Update Flag %u) duration %u hours", + (unsigned) iv.iv_index, iv.iv_update, iv.iv_duration); + + return 0; +} + +static int seq_set(int argc, char **argv, char *val) +{ + struct seq_val seq; + int len, err; + + BT_DBG("val %s", val ? val : "(null)"); + + if (!val) { + bt_mesh.seq = 0; + return 0; + } + + len = sizeof(seq); + err = settings_bytes_from_str(val, &seq, &len); + if (err) { + BT_ERR("Failed to decode value %s (err %d)", val, err); + return err; + } + + if (len != sizeof(seq)) { + BT_ERR("Unexpected value length (%d != %zu)", len, sizeof(seq)); + return -EINVAL; + } + + bt_mesh.seq = ((u32_t)seq.val[0] | ((u32_t)seq.val[1] << 8) | + ((u32_t)seq.val[2] << 16)); + + if (CONFIG_BT_MESH_SEQ_STORE_RATE > 0) { + /* Make sure we have a large enough sequence number. We + * subtract 1 so that the first transmission causes a write + * to the settings storage. + */ + bt_mesh.seq += (CONFIG_BT_MESH_SEQ_STORE_RATE - + (bt_mesh.seq % CONFIG_BT_MESH_SEQ_STORE_RATE)); + bt_mesh.seq--; + } + + BT_DBG("Sequence Number 0x%06x", bt_mesh.seq); + + return 0; +} + +static struct bt_mesh_rpl *rpl_find(u16_t src) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(bt_mesh.rpl); i++) { + if (bt_mesh.rpl[i].src == src) { + return &bt_mesh.rpl[i]; + } + } + + return NULL; +} + +static struct bt_mesh_rpl *rpl_alloc(u16_t src) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(bt_mesh.rpl); i++) { + if (!bt_mesh.rpl[i].src) { + bt_mesh.rpl[i].src = src; + return &bt_mesh.rpl[i]; + } + } + + return NULL; +} + +static int rpl_set(int argc, char **argv, char *val) +{ + struct bt_mesh_rpl *entry; + struct rpl_val rpl; + int len, err; + u16_t src; + + if (argc < 1) { + BT_ERR("Invalid argc (%d)", argc); + return -ENOENT; + } + + BT_DBG("argv[0] %s val %s", argv[0], val ? val : "(null)"); + + src = strtol(argv[0], NULL, 16); + entry = rpl_find(src); + + if (!val) { + if (entry) { + memset(entry, 0, sizeof(*entry)); + } else { + BT_WARN("Unable to find RPL entry for 0x%04x", src); + } + + return 0; + } + + if (!entry) { + entry = rpl_alloc(src); + if (!entry) { + BT_ERR("Unable to allocate RPL entry for 0x%04x", src); + return -ENOMEM; + } + } + + len = sizeof(rpl); + err = settings_bytes_from_str(val, &rpl, &len); + if (err) { + BT_ERR("Failed to decode value %s (err %d)", val, err); + return err; + } + + if (len != sizeof(rpl)) { + BT_ERR("Unexpected value length (%d != %zu)", len, sizeof(rpl)); + return -EINVAL; + } + + entry->seq = rpl.seq; + entry->old_iv = rpl.old_iv; + + BT_DBG("RPL entry for 0x%04x: Seq 0x%06x old_iv %u", entry->src, + (unsigned) entry->seq, entry->old_iv); + + return 0; +} + +static int net_key_set(int argc, char **argv, char *val) +{ + struct bt_mesh_subnet *sub; + struct net_key_val key; + int len, i, err; + u16_t net_idx; + + BT_DBG("argv[0] %s val %s", argv[0], val ? val : "(null)"); + + net_idx = strtol(argv[0], NULL, 16); + sub = bt_mesh_subnet_get(net_idx); + + if (!val) { + if (!sub) { + BT_ERR("No subnet with NetKeyIndex 0x%03x", net_idx); + return -ENOENT; + } + + BT_DBG("Deleting NetKeyIndex 0x%03x", net_idx); + bt_mesh_subnet_del(sub, false); + return 0; + } + + len = sizeof(key); + err = settings_bytes_from_str(val, &key, &len); + if (err) { + BT_ERR("Failed to decode value %s (err %d)", val, err); + return err; + } + + if (len != sizeof(key)) { + BT_ERR("Unexpected value length (%d != %zu)", len, sizeof(key)); + return -EINVAL; + } + + if (sub) { + BT_DBG("Updating existing NetKeyIndex 0x%03x", net_idx); + + sub->kr_flag = key.kr_flag; + sub->kr_phase = key.kr_phase; + memcpy(sub->keys[0].net, &key.val[0], 16); + memcpy(sub->keys[1].net, &key.val[1], 16); + + return 0; + } + + for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) { + if (bt_mesh.sub[i].net_idx == BT_MESH_KEY_UNUSED) { + sub = &bt_mesh.sub[i]; + break; + } + } + + if (!sub) { + BT_ERR("No space to allocate a new subnet"); + return -ENOMEM; + } + + sub->net_idx = net_idx; + sub->kr_flag = key.kr_flag; + sub->kr_phase = key.kr_phase; + memcpy(sub->keys[0].net, &key.val[0], 16); + memcpy(sub->keys[1].net, &key.val[1], 16); + + BT_DBG("NetKeyIndex 0x%03x recovered from storage", net_idx); + + return 0; +} + +static int app_key_set(int argc, char **argv, char *val) +{ + struct bt_mesh_app_key *app; + struct app_key_val key; + u16_t app_idx; + int len, err; + + BT_DBG("argv[0] %s val %s", argv[0], val ? val : "(null)"); + + app_idx = strtol(argv[0], NULL, 16); + + if (!val) { + BT_DBG("Deleting AppKeyIndex 0x%03x", app_idx); + + app = bt_mesh_app_key_find(app_idx); + if (app) { + bt_mesh_app_key_del(app, false); + } + + return 0; + } + + len = sizeof(key); + err = settings_bytes_from_str(val, &key, &len); + if (err) { + BT_ERR("Failed to decode value %s (err %d)", val, err); + return err; + } + + if (len != sizeof(key)) { + BT_ERR("Unexpected value length (%d != %zu)", len, sizeof(key)); + return -EINVAL; + } + + app = bt_mesh_app_key_find(app_idx); + if (!app) { + app = bt_mesh_app_key_alloc(app_idx); + } + + if (!app) { + BT_ERR("No space for a new app key"); + return -ENOMEM; + } + + app->net_idx = key.net_idx; + app->app_idx = app_idx; + app->updated = key.updated; + memcpy(app->keys[0].val, key.val[0], 16); + memcpy(app->keys[1].val, key.val[1], 16); + + bt_mesh_app_id(app->keys[0].val, &app->keys[0].id); + bt_mesh_app_id(app->keys[1].val, &app->keys[1].id); + + BT_DBG("AppKeyIndex 0x%03x recovered from storage", app_idx); + + return 0; +} + +static int hb_pub_set(int argc, char **argv, char *val) +{ + struct bt_mesh_hb_pub *pub = bt_mesh_hb_pub_get(); + struct hb_pub_val hb_val; + int len, err; + + BT_DBG("val %s", val ? val : "(null)"); + + if (!pub) { + return -ENOENT; + } + + if (!val) { + pub->dst = BT_MESH_ADDR_UNASSIGNED; + pub->count = 0; + pub->ttl = 0; + pub->period = 0; + pub->feat = 0; + + BT_DBG("Cleared heartbeat publication"); + return 0; + } + + len = sizeof(hb_val); + err = settings_bytes_from_str(val, &hb_val, &len); + if (err) { + BT_ERR("Failed to decode value %s (err %d)", val, err); + return err; + } + + if (len != sizeof(hb_val)) { + BT_ERR("Unexpected value length (%d != %zu)", len, + sizeof(hb_val)); + return -EINVAL; + } + + pub->dst = hb_val.dst; + pub->period = hb_val.period; + pub->ttl = hb_val.ttl; + pub->feat = hb_val.feat; + pub->net_idx = hb_val.net_idx; + + if (hb_val.indefinite) { + pub->count = 0xffff; + } else { + pub->count = 0; + } + + BT_DBG("Restored heartbeat publication"); + + return 0; +} + +static int cfg_set(int argc, char **argv, char *val) +{ + struct bt_mesh_cfg_srv *cfg = bt_mesh_cfg_get(); + int len, err; + + BT_DBG("val %s", val ? val : "(null)"); + + if (!cfg) { + return -ENOENT; + } + + if (!val) { + stored_cfg.valid = false; + BT_DBG("Cleared configuration state"); + return 0; + } + + len = sizeof(stored_cfg.cfg); + err = settings_bytes_from_str(val, &stored_cfg.cfg, &len); + if (err) { + BT_ERR("Failed to decode value %s (err %d)", val, err); + return err; + } + + if (len != sizeof(stored_cfg.cfg)) { + BT_ERR("Unexpected value length (%d != %zu)", len, + sizeof(stored_cfg.cfg)); + return -EINVAL; + } + + stored_cfg.valid = true; + BT_DBG("Restored configuration state"); + + return 0; +} + +static int mod_set_bind(struct bt_mesh_model *mod, char *val) +{ + int len, err, i; + + /* Start with empty array regardless of cleared or set value */ + for (i = 0; i < ARRAY_SIZE(mod->keys); i++) { + mod->keys[i] = BT_MESH_KEY_UNUSED; + } + + if (!val) { + BT_DBG("Cleared bindings for model"); + return 0; + } + + len = sizeof(mod->keys); + err = settings_bytes_from_str(val, mod->keys, &len); + if (err) { + BT_ERR("Failed to decode value %s (err %d)", val, err); + return -EINVAL; + } + + BT_DBG("Decoded %u bound keys for model", len / sizeof(mod->keys[0])); + return 0; +} + +static int mod_set_sub(struct bt_mesh_model *mod, char *val) +{ + int len, err; + + /* Start with empty array regardless of cleared or set value */ + memset(mod->groups, 0, sizeof(mod->groups)); + + if (!val) { + BT_DBG("Cleared subscriptions for model"); + return 0; + } + + len = sizeof(mod->groups); + err = settings_bytes_from_str(val, mod->groups, &len); + if (err) { + BT_ERR("Failed to decode value %s (err %d)", val, err); + return -EINVAL; + } + + BT_DBG("Decoded %u subscribed group addresses for model", + len / sizeof(mod->groups[0])); + return 0; +} + +static int mod_set_pub(struct bt_mesh_model *mod, char *val) +{ + struct mod_pub_val pub; + int len, err; + + if (!mod->pub) { + BT_WARN("Model has no publication context!"); + return -EINVAL; + } + + if (!val) { + mod->pub->addr = BT_MESH_ADDR_UNASSIGNED; + mod->pub->key = 0; + mod->pub->cred = 0; + mod->pub->ttl = 0; + mod->pub->period = 0; + mod->pub->retransmit = 0; + mod->pub->count = 0; + + BT_DBG("Cleared publication for model"); + return 0; + } + + len = sizeof(pub); + err = settings_bytes_from_str(val, &pub, &len); + if (err) { + BT_ERR("Failed to decode value %s (err %d)", val, err); + return -EINVAL; + } + + if (len != sizeof(pub)) { + BT_ERR("Invalid length for model publication"); + return -EINVAL; + } + + mod->pub->addr = pub.addr; + mod->pub->key = pub.key; + mod->pub->cred = pub.cred; + mod->pub->ttl = pub.ttl; + mod->pub->period = pub.period; + mod->pub->retransmit = pub.retransmit; + mod->pub->count = 0; + + BT_DBG("Restored model publication, dst 0x%04x app_idx 0x%03x", + pub.addr, pub.key); + + return 0; +} + +static int mod_set(bool vnd, int argc, char **argv, char *val) +{ + struct bt_mesh_model *mod; + u8_t elem_idx, mod_idx; + u16_t mod_key; + + if (argc < 2) { + BT_ERR("Too small argc (%d)", argc); + return -ENOENT; + } + + mod_key = strtol(argv[0], NULL, 16); + elem_idx = mod_key >> 8; + mod_idx = mod_key; + + BT_DBG("Decoded mod_key 0x%04x as elem_idx %u mod_idx %u", + mod_key, elem_idx, mod_idx); + + mod = bt_mesh_model_get(vnd, elem_idx, mod_idx); + if (!mod) { + BT_ERR("Failed to get model for elem_idx %u mod_idx %u", + elem_idx, mod_idx); + return -ENOENT; + } + + if (!strcmp(argv[1], "bind")) { + return mod_set_bind(mod, val); + } + + if (!strcmp(argv[1], "sub")) { + return mod_set_sub(mod, val); + } + + if (!strcmp(argv[1], "pub")) { + return mod_set_pub(mod, val); + } + + BT_WARN("Unknown module key %s", argv[1]); + return -ENOENT; +} + +static int sig_mod_set(int argc, char **argv, char *val) +{ + return mod_set(false, argc, argv, val); +} + +static int vnd_mod_set(int argc, char **argv, char *val) +{ + return mod_set(true, argc, argv, val); +} + +const struct mesh_setting { + const char *name; + int (*func)(int argc, char **argv, char *val); +} settings[] = { + { "Net", net_set }, + { "IV", iv_set }, + { "Seq", seq_set }, + { "RPL", rpl_set }, + { "NetKey", net_key_set }, + { "AppKey", app_key_set }, + { "HBPub", hb_pub_set }, + { "Cfg", cfg_set }, + { "s", sig_mod_set }, + { "v", vnd_mod_set }, +}; + +static int mesh_set(int argc, char **argv, char *val) +{ + int i; + + if (argc < 1) { + BT_ERR("Insufficient number of arguments"); + return -EINVAL; + } + + BT_DBG("argv[0] %s val %s", argv[0], val ? val : "(null)"); + + for (i = 0; i < ARRAY_SIZE(settings); i++) { + if (!strcmp(settings[i].name, argv[0])) { + argc--; + argv++; + + return settings[i].func(argc, argv, val); + } + } + + BT_WARN("No matching handler for key %s", argv[0]); + + return -ENOENT; +} + +static int subnet_init(struct bt_mesh_subnet *sub) +{ + int err; + + err = bt_mesh_net_keys_create(&sub->keys[0], sub->keys[0].net); + if (err) { + BT_ERR("Unable to generate keys for subnet"); + return -EIO; + } + + if (sub->kr_phase != BT_MESH_KR_NORMAL) { + err = bt_mesh_net_keys_create(&sub->keys[1], sub->keys[1].net); + if (err) { + BT_ERR("Unable to generate keys for subnet"); + memset(&sub->keys[0], 0, sizeof(sub->keys[0])); + return -EIO; + } + } + + if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) { + sub->node_id = BT_MESH_NODE_IDENTITY_STOPPED; + } else { + sub->node_id = BT_MESH_NODE_IDENTITY_NOT_SUPPORTED; + } + + /* Make sure we have valid beacon data to be sent */ + bt_mesh_net_beacon_update(sub); + + return 0; +} + +static void commit_mod(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, + bool vnd, bool primary, void *user_data) +{ + if (mod->pub && mod->pub->update && + mod->pub->addr != BT_MESH_ADDR_UNASSIGNED) { + s32_t ms = bt_mesh_model_pub_period_get(mod); + if (ms) { + BT_DBG("Starting publish timer (period %u ms)", + (unsigned) ms); + k_delayed_work_submit(&mod->pub->timer, ms); + } + } +} + +static int mesh_commit(void) +{ + struct bt_mesh_hb_pub *hb_pub; + struct bt_mesh_cfg_srv *cfg; + int i; + + BT_DBG("sub[0].net_idx 0x%03x", bt_mesh.sub[0].net_idx); + + if (bt_mesh.sub[0].net_idx == BT_MESH_KEY_UNUSED) { + /* Nothing to do since we're not yet provisioned */ + return 0; + } + + if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT)) { + bt_mesh_proxy_prov_disable(); + } + + for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) { + struct bt_mesh_subnet *sub = &bt_mesh.sub[i]; + int err; + + if (sub->net_idx == BT_MESH_KEY_UNUSED) { + continue; + } + + err = subnet_init(sub); + if (err) { + BT_ERR("Failed to init subnet 0x%03x", sub->net_idx); + } + } + + if (bt_mesh.ivu_duration < BT_MESH_IVU_MIN_HOURS) { + k_delayed_work_submit(&bt_mesh.ivu_timer, BT_MESH_IVU_TIMEOUT); + } + + bt_mesh_model_foreach(commit_mod, NULL); + + hb_pub = bt_mesh_hb_pub_get(); + if (hb_pub && hb_pub->dst != BT_MESH_ADDR_UNASSIGNED && + hb_pub->count && hb_pub->period) { + BT_DBG("Starting heartbeat publication"); + k_work_submit(&hb_pub->timer.work); + } + + cfg = bt_mesh_cfg_get(); + if (cfg && stored_cfg.valid) { + cfg->net_transmit = stored_cfg.cfg.net_transmit; + cfg->relay = stored_cfg.cfg.relay; + cfg->relay_retransmit = stored_cfg.cfg.relay_retransmit; + cfg->beacon = stored_cfg.cfg.beacon; + cfg->gatt_proxy = stored_cfg.cfg.gatt_proxy; + cfg->frnd = stored_cfg.cfg.frnd; + cfg->default_ttl = stored_cfg.cfg.default_ttl; + } + + atomic_set_bit(bt_mesh.flags, BT_MESH_VALID); + + bt_mesh_net_start(); + + return 0; +} + +static void schedule_store(int flag) +{ + s32_t timeout; + + atomic_set_bit(bt_mesh.flags, flag); + + if (atomic_test_bit(bt_mesh.flags, BT_MESH_NET_PENDING) || + atomic_test_bit(bt_mesh.flags, BT_MESH_IV_PENDING) || + atomic_test_bit(bt_mesh.flags, BT_MESH_SEQ_PENDING)) { + timeout = K_NO_WAIT; + } else if (atomic_test_bit(bt_mesh.flags, BT_MESH_RPL_PENDING) && + (CONFIG_BT_MESH_RPL_STORE_TIMEOUT < + CONFIG_BT_MESH_STORE_TIMEOUT)) { + timeout = K_SECONDS(CONFIG_BT_MESH_RPL_STORE_TIMEOUT); + } else { + timeout = K_SECONDS(CONFIG_BT_MESH_STORE_TIMEOUT); + } + + BT_DBG("Waiting %d seconds", (int) (timeout / MSEC_PER_SEC)); + + k_delayed_work_submit(&pending_store, timeout); +} + +static void clear_iv(void) +{ + BT_DBG("Clearing IV"); + settings_save_one("bt_mesh/IV", NULL); +} + +static void clear_net(void) +{ + BT_DBG("Clearing Network"); + settings_save_one("bt_mesh/Net", NULL); +} + +static void store_pending_net(void) +{ + char buf[BT_SETTINGS_SIZE(sizeof(struct net_val))]; + struct net_val net; + char *str; + + BT_DBG("addr 0x%04x DevKey %s", bt_mesh_primary_addr(), + bt_hex(bt_mesh.dev_key, 16)); + + net.primary_addr = bt_mesh_primary_addr(); + memcpy(net.dev_key, bt_mesh.dev_key, 16); + + str = settings_str_from_bytes(&net, sizeof(net), buf, sizeof(buf)); + if (!str) { + BT_ERR("Unable to encode Network as value"); + return; + } + + BT_DBG("Saving Network as value %s", str); + settings_save_one("bt_mesh/Net", str); +} + +void bt_mesh_store_net(void) +{ + schedule_store(BT_MESH_NET_PENDING); +} + +static void store_pending_iv(void) +{ + char buf[BT_SETTINGS_SIZE(sizeof(struct iv_val))]; + struct iv_val iv; + char *str; + + iv.iv_index = bt_mesh.iv_index; + iv.iv_update = atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS); + iv.iv_duration = bt_mesh.ivu_duration; + + str = settings_str_from_bytes(&iv, sizeof(iv), buf, sizeof(buf)); + if (!str) { + BT_ERR("Unable to encode IV as value"); + return; + } + + BT_DBG("Saving IV as value %s", str); + settings_save_one("bt_mesh/IV", str); +} + +void bt_mesh_store_iv(bool only_duration) +{ + schedule_store(BT_MESH_IV_PENDING); + + if (!only_duration) { + /* Always update Seq whenever IV changes */ + schedule_store(BT_MESH_SEQ_PENDING); + } +} + +static void store_pending_seq(void) +{ + char buf[BT_SETTINGS_SIZE(sizeof(struct seq_val))]; + struct seq_val seq; + char *str; + + seq.val[0] = bt_mesh.seq; + seq.val[1] = bt_mesh.seq >> 8; + seq.val[2] = bt_mesh.seq >> 16; + + str = settings_str_from_bytes(&seq, sizeof(seq), buf, sizeof(buf)); + if (!str) { + BT_ERR("Unable to encode Seq as value"); + return; + } + + BT_DBG("Saving Seq as value %s", str); + settings_save_one("bt_mesh/Seq", str); +} + +void bt_mesh_store_seq(void) +{ + if (CONFIG_BT_MESH_SEQ_STORE_RATE && + (bt_mesh.seq % CONFIG_BT_MESH_SEQ_STORE_RATE)) { + return; + } + + schedule_store(BT_MESH_SEQ_PENDING); +} + +static void store_rpl(struct bt_mesh_rpl *entry) +{ + char buf[BT_SETTINGS_SIZE(sizeof(struct rpl_val))]; + struct rpl_val rpl; + char path[18]; + char *str; + + BT_DBG("src 0x%04x seq 0x%06x old_iv %u", entry->src, + (unsigned) entry->seq, entry->old_iv); + + rpl.seq = entry->seq; + rpl.old_iv = entry->old_iv; + + str = settings_str_from_bytes(&rpl, sizeof(rpl), buf, sizeof(buf)); + if (!str) { + BT_ERR("Unable to encode RPL as value"); + return; + } + + snprintk(path, sizeof(path), "bt_mesh/RPL/%x", entry->src); + + BT_DBG("Saving RPL %s as value %s", path, str); + settings_save_one(path, str); +} + +static void clear_rpl(void) +{ + int i; + + BT_DBG(""); + + for (i = 0; i < ARRAY_SIZE(bt_mesh.rpl); i++) { + struct bt_mesh_rpl *rpl = &bt_mesh.rpl[i]; + char path[18]; + + if (!rpl->src) { + continue; + } + + snprintk(path, sizeof(path), "bt_mesh/RPL/%x", rpl->src); + settings_save_one(path, NULL); + + memset(rpl, 0, sizeof(*rpl)); + } +} + +static void store_pending_rpl(void) +{ + int i; + + BT_DBG(""); + + for (i = 0; i < ARRAY_SIZE(bt_mesh.rpl); i++) { + struct bt_mesh_rpl *rpl = &bt_mesh.rpl[i]; + + if (rpl->store) { + rpl->store = false; + store_rpl(rpl); + } + } +} + +static void store_pending_hb_pub(void) +{ + char buf[BT_SETTINGS_SIZE(sizeof(struct hb_pub_val))]; + struct bt_mesh_hb_pub *pub = bt_mesh_hb_pub_get(); + struct hb_pub_val val; + char *str; + + if (!pub) { + return; + } + + if (pub->dst == BT_MESH_ADDR_UNASSIGNED) { + str = NULL; + } else { + val.indefinite = (pub->count == 0xffff); + val.dst = pub->dst; + val.period = pub->period; + val.ttl = pub->ttl; + val.feat = pub->feat; + val.net_idx = pub->net_idx; + + str = settings_str_from_bytes(&val, sizeof(val), + buf, sizeof(buf)); + if (!str) { + BT_ERR("Unable to encode hb pub as value"); + return; + } + } + + BT_DBG("Saving Heartbeat Publication as value %s", + str ? str : "(null)"); + settings_save_one("bt_mesh/HBPub", str); +} + +static void store_pending_cfg(void) +{ + char buf[BT_SETTINGS_SIZE(sizeof(struct cfg_val))]; + struct bt_mesh_cfg_srv *cfg = bt_mesh_cfg_get(); + struct cfg_val val; + char *str; + + if (!cfg) { + return; + } + + val.net_transmit = cfg->net_transmit; + val.relay = cfg->relay; + val.relay_retransmit = cfg->relay_retransmit; + val.beacon = cfg->beacon; + val.gatt_proxy = cfg->gatt_proxy; + val.frnd = cfg->frnd; + val.default_ttl = cfg->default_ttl; + + str = settings_str_from_bytes(&val, sizeof(val), buf, sizeof(buf)); + if (!str) { + BT_ERR("Unable to encode configuration as value"); + return; + } + + BT_DBG("Saving configuration as value %s", str); + settings_save_one("bt_mesh/Cfg", str); +} + +static void clear_cfg(void) +{ + BT_DBG("Clearing configuration"); + settings_save_one("bt_mesh/Cfg", NULL); +} + +static void clear_app_key(u16_t app_idx) +{ + char path[20]; + + BT_DBG("AppKeyIndex 0x%03x", app_idx); + + snprintk(path, sizeof(path), "bt_mesh/AppKey/%x", app_idx); + settings_save_one(path, NULL); +} + +static void clear_net_key(u16_t net_idx) +{ + char path[20]; + + BT_DBG("NetKeyIndex 0x%03x", net_idx); + + snprintk(path, sizeof(path), "bt_mesh/NetKey/%x", net_idx); + settings_save_one(path, NULL); +} + +static void store_net_key(struct bt_mesh_subnet *sub) +{ + char buf[BT_SETTINGS_SIZE(sizeof(struct net_key_val))]; + struct net_key_val key; + char path[20]; + char *str; + + BT_DBG("NetKeyIndex 0x%03x NetKey %s", sub->net_idx, + bt_hex(sub->keys[0].net, 16)); + + memcpy(&key.val[0], sub->keys[0].net, 16); + memcpy(&key.val[1], sub->keys[1].net, 16); + key.kr_flag = sub->kr_flag; + key.kr_phase = sub->kr_phase; + + str = settings_str_from_bytes(&key, sizeof(key), buf, sizeof(buf)); + if (!str) { + BT_ERR("Unable to encode NetKey as value"); + return; + } + + snprintk(path, sizeof(path), "bt_mesh/NetKey/%x", sub->net_idx); + + BT_DBG("Saving NetKey %s as value %s", path, str); + settings_save_one(path, str); +} + +static void store_app_key(struct bt_mesh_app_key *app) +{ + char buf[BT_SETTINGS_SIZE(sizeof(struct app_key_val))]; + struct app_key_val key; + char path[20]; + char *str; + + key.net_idx = app->net_idx; + key.updated = app->updated; + memcpy(key.val[0], app->keys[0].val, 16); + memcpy(key.val[1], app->keys[1].val, 16); + + str = settings_str_from_bytes(&key, sizeof(key), buf, sizeof(buf)); + if (!str) { + BT_ERR("Unable to encode AppKey as value"); + return; + } + + snprintk(path, sizeof(path), "bt_mesh/AppKey/%x", app->app_idx); + + BT_DBG("Saving AppKey %s as value %s", path, str); + settings_save_one(path, str); +} + +static void store_pending_keys(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(key_updates); i++) { + struct key_update *update = &key_updates[i]; + + if (!update->valid) { + continue; + } + + if (update->clear) { + if (update->app_key) { + clear_app_key(update->key_idx); + } else { + clear_net_key(update->key_idx); + } + } else { + if (update->app_key) { + struct bt_mesh_app_key *key; + + key = bt_mesh_app_key_find(update->key_idx); + if (key) { + store_app_key(key); + } else { + BT_WARN("AppKeyIndex 0x%03x not found", + update->key_idx); + } + + } else { + struct bt_mesh_subnet *sub; + + sub = bt_mesh_subnet_get(update->key_idx); + if (sub) { + store_net_key(sub); + } else { + BT_WARN("NetKeyIndex 0x%03x not found", + update->key_idx); + } + } + } + + update->valid = 0; + } +} + +static void encode_mod_path(struct bt_mesh_model *mod, bool vnd, + const char *key, char *path, size_t path_len) +{ + u16_t mod_key = (((u16_t)mod->elem_idx << 8) | mod->mod_idx); + + if (vnd) { + snprintk(path, path_len, "bt_mesh/v/%x/%s", mod_key, key); + } else { + snprintk(path, path_len, "bt_mesh/s/%x/%s", mod_key, key); + } +} + +static void store_pending_mod_bind(struct bt_mesh_model *mod, bool vnd) +{ + u16_t keys[CONFIG_BT_MESH_MODEL_KEY_COUNT]; + char buf[BT_SETTINGS_SIZE(sizeof(keys))]; + char path[20]; + int i, count; + char *val; + + for (i = 0, count = 0; i < ARRAY_SIZE(mod->keys); i++) { + if (mod->keys[i] != BT_MESH_KEY_UNUSED) { + keys[count++] = mod->keys[i]; + } + } + + if (count) { + val = settings_str_from_bytes(keys, count * sizeof(keys[0]), + buf, sizeof(buf)); + if (!val) { + BT_ERR("Unable to encode model bindings as value"); + return; + } + } else { + val = NULL; + } + + encode_mod_path(mod, vnd, "bind", path, sizeof(path)); + + BT_DBG("Saving %s as %s", path, val ? val : "(null)"); + settings_save_one(path, val); +} + +static void store_pending_mod_sub(struct bt_mesh_model *mod, bool vnd) +{ + u16_t groups[CONFIG_BT_MESH_MODEL_GROUP_COUNT]; + char buf[BT_SETTINGS_SIZE(sizeof(groups))]; + char path[20]; + int i, count; + char *val; + + for (i = 0, count = 0; i < ARRAY_SIZE(mod->groups); i++) { + if (mod->groups[i] != BT_MESH_ADDR_UNASSIGNED) { + groups[count++] = mod->groups[i]; + } + } + + if (count) { + val = settings_str_from_bytes(groups, count * sizeof(groups[0]), + buf, sizeof(buf)); + if (!val) { + BT_ERR("Unable to encode model subscription as value"); + return; + } + } else { + val = NULL; + } + + encode_mod_path(mod, vnd, "sub", path, sizeof(path)); + + BT_DBG("Saving %s as %s", path, val ? val : "(null)"); + settings_save_one(path, val); +} + +static void store_pending_mod_pub(struct bt_mesh_model *mod, bool vnd) +{ + char buf[BT_SETTINGS_SIZE(sizeof(struct mod_pub_val))]; + struct mod_pub_val pub; + char path[20]; + char *val; + + if (!mod->pub || mod->pub->addr == BT_MESH_ADDR_UNASSIGNED) { + val = NULL; + } else { + pub.addr = mod->pub->addr; + pub.key = mod->pub->key; + pub.ttl = mod->pub->ttl; + pub.retransmit = mod->pub->retransmit; + pub.period = mod->pub->period; + pub.period_div = mod->pub->period_div; + pub.cred = mod->pub->cred; + + val = settings_str_from_bytes(&pub, sizeof(pub), + buf, sizeof(buf)); + if (!val) { + BT_ERR("Unable to encode model publication as value"); + return; + } + } + + encode_mod_path(mod, vnd, "pub", path, sizeof(path)); + + BT_DBG("Saving %s as %s", path, val ? val : "(null)"); + settings_save_one(path, val); +} + +static void store_pending_mod(struct bt_mesh_model *mod, + struct bt_mesh_elem *elem, bool vnd, + bool primary, void *user_data) +{ + if (!mod->flags) { + return; + } + + if (mod->flags & BT_MESH_MOD_BIND_PENDING) { + mod->flags &= ~BT_MESH_MOD_BIND_PENDING; + store_pending_mod_bind(mod, vnd); + } + + if (mod->flags & BT_MESH_MOD_SUB_PENDING) { + mod->flags &= ~BT_MESH_MOD_SUB_PENDING; + store_pending_mod_sub(mod, vnd); + } + + if (mod->flags & BT_MESH_MOD_PUB_PENDING) { + mod->flags &= ~BT_MESH_MOD_PUB_PENDING; + store_pending_mod_pub(mod, vnd); + } +} + +static void store_pending(struct ble_npl_event *work) +{ + BT_DBG(""); + + if (atomic_test_and_clear_bit(bt_mesh.flags, BT_MESH_RPL_PENDING)) { + if (atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) { + store_pending_rpl(); + } else { + clear_rpl(); + } + } + + if (atomic_test_and_clear_bit(bt_mesh.flags, BT_MESH_KEYS_PENDING)) { + store_pending_keys(); + } + + if (atomic_test_and_clear_bit(bt_mesh.flags, BT_MESH_NET_PENDING)) { + if (atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) { + store_pending_net(); + } else { + clear_net(); + } + } + + if (atomic_test_and_clear_bit(bt_mesh.flags, BT_MESH_IV_PENDING)) { + if (atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) { + store_pending_iv(); + } else { + clear_iv(); + } + } + + if (atomic_test_and_clear_bit(bt_mesh.flags, BT_MESH_SEQ_PENDING)) { + store_pending_seq(); + } + + if (atomic_test_and_clear_bit(bt_mesh.flags, BT_MESH_HB_PUB_PENDING)) { + store_pending_hb_pub(); + } + + if (atomic_test_and_clear_bit(bt_mesh.flags, BT_MESH_CFG_PENDING)) { + if (atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) { + store_pending_cfg(); + } else { + clear_cfg(); + } + } + + if (atomic_test_and_clear_bit(bt_mesh.flags, BT_MESH_MOD_PENDING)) { + bt_mesh_model_foreach(store_pending_mod, NULL); + } +} + +void bt_mesh_store_rpl(struct bt_mesh_rpl *entry) +{ + entry->store = true; + schedule_store(BT_MESH_RPL_PENDING); +} + +static struct key_update *key_update_find(bool app_key, u16_t key_idx, + struct key_update **free_slot) +{ + struct key_update *match; + int i; + + match = NULL; + *free_slot = NULL; + + for (i = 0; i < ARRAY_SIZE(key_updates); i++) { + struct key_update *update = &key_updates[i]; + + if (!update->valid) { + *free_slot = update; + continue; + } + + if (update->app_key != app_key) { + continue; + } + + if (update->key_idx == key_idx) { + match = update; + } + } + + return match; +} + +void bt_mesh_store_subnet(struct bt_mesh_subnet *sub) +{ + struct key_update *update, *free_slot; + + BT_DBG("NetKeyIndex 0x%03x", sub->net_idx); + + update = key_update_find(false, sub->net_idx, &free_slot); + if (update) { + update->clear = 0; + schedule_store(BT_MESH_KEYS_PENDING); + return; + } + + if (!free_slot) { + store_net_key(sub); + return; + } + + free_slot->valid = 1; + free_slot->key_idx = sub->net_idx; + free_slot->app_key = 0; + free_slot->clear = 0; + + schedule_store(BT_MESH_KEYS_PENDING); +} + +void bt_mesh_store_app_key(struct bt_mesh_app_key *key) +{ + struct key_update *update, *free_slot; + + BT_DBG("AppKeyIndex 0x%03x", key->app_idx); + + update = key_update_find(true, key->app_idx, &free_slot); + if (update) { + update->clear = 0; + schedule_store(BT_MESH_KEYS_PENDING); + return; + } + + if (!free_slot) { + store_app_key(key); + return; + } + + free_slot->valid = 1; + free_slot->key_idx = key->app_idx; + free_slot->app_key = 1; + free_slot->clear = 0; + + schedule_store(BT_MESH_KEYS_PENDING); +} + +void bt_mesh_store_hb_pub(void) +{ + schedule_store(BT_MESH_HB_PUB_PENDING); +} + +void bt_mesh_store_cfg(void) +{ + schedule_store(BT_MESH_CFG_PENDING); +} + +void bt_mesh_clear_net(void) +{ + schedule_store(BT_MESH_NET_PENDING); + schedule_store(BT_MESH_IV_PENDING); + schedule_store(BT_MESH_CFG_PENDING); +} + +void bt_mesh_clear_subnet(struct bt_mesh_subnet *sub) +{ + struct key_update *update, *free_slot; + + BT_DBG("NetKeyIndex 0x%03x", sub->net_idx); + + update = key_update_find(false, sub->net_idx, &free_slot); + if (update) { + update->clear = 1; + schedule_store(BT_MESH_KEYS_PENDING); + return; + } + + if (!free_slot) { + clear_net_key(sub->net_idx); + return; + } + + free_slot->valid = 1; + free_slot->key_idx = sub->net_idx; + free_slot->app_key = 0; + free_slot->clear = 1; + + schedule_store(BT_MESH_KEYS_PENDING); +} + +void bt_mesh_clear_app_key(struct bt_mesh_app_key *key) +{ + struct key_update *update, *free_slot; + + BT_DBG("AppKeyIndex 0x%03x", key->app_idx); + + update = key_update_find(true, key->app_idx, &free_slot); + if (update) { + update->clear = 1; + schedule_store(BT_MESH_KEYS_PENDING); + return; + } + + if (!free_slot) { + clear_app_key(key->app_idx); + return; + } + + free_slot->valid = 1; + free_slot->key_idx = key->app_idx; + free_slot->app_key = 1; + free_slot->clear = 1; + + schedule_store(BT_MESH_KEYS_PENDING); +} + +void bt_mesh_clear_rpl(void) +{ + schedule_store(BT_MESH_RPL_PENDING); +} + +void bt_mesh_store_mod_bind(struct bt_mesh_model *mod) +{ + mod->flags |= BT_MESH_MOD_BIND_PENDING; + schedule_store(BT_MESH_MOD_PENDING); +} + +void bt_mesh_store_mod_sub(struct bt_mesh_model *mod) +{ + mod->flags |= BT_MESH_MOD_SUB_PENDING; + schedule_store(BT_MESH_MOD_PENDING); +} + +void bt_mesh_store_mod_pub(struct bt_mesh_model *mod) +{ + mod->flags |= BT_MESH_MOD_PUB_PENDING; + schedule_store(BT_MESH_MOD_PENDING); +} + +static struct conf_handler bt_mesh_settings_conf_handler = { + .ch_name = "bt_mesh", + .ch_get = NULL, + .ch_set = mesh_set, + .ch_commit = mesh_commit, + .ch_export = NULL, +}; + +void bt_mesh_settings_init(void) +{ + int rc; + + rc = conf_register(&bt_mesh_settings_conf_handler); + + SYSINIT_PANIC_ASSERT_MSG(rc == 0, + "Failed to register bt_mesh_settings conf"); + + k_delayed_work_init(&pending_store, store_pending); +} + +#endif /* MYNEWT_VAL(BLE_MESH_SETTINGS) */ diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/settings.h b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/settings.h new file mode 100644 index 000000000..7bd028477 --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/settings.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2018 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +void bt_mesh_store_net(void); +void bt_mesh_store_iv(bool only_duration); +void bt_mesh_store_seq(void); +void bt_mesh_store_rpl(struct bt_mesh_rpl *rpl); +void bt_mesh_store_subnet(struct bt_mesh_subnet *sub); +void bt_mesh_store_app_key(struct bt_mesh_app_key *key); +void bt_mesh_store_hb_pub(void); +void bt_mesh_store_cfg(void); +void bt_mesh_store_mod_bind(struct bt_mesh_model *mod); +void bt_mesh_store_mod_sub(struct bt_mesh_model *mod); +void bt_mesh_store_mod_pub(struct bt_mesh_model *mod); + +void bt_mesh_clear_net(void); +void bt_mesh_clear_subnet(struct bt_mesh_subnet *sub); +void bt_mesh_clear_app_key(struct bt_mesh_app_key *key); +void bt_mesh_clear_rpl(void); + +void bt_mesh_settings_init(void); diff --git a/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/shell.c b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/shell.c new file mode 100644 index 000000000..94a7b58be --- /dev/null +++ b/libesp32/NimBLE-Arduino/src/nimble/host/mesh/src/shell.c @@ -0,0 +1,2752 @@ +/** @file + * @brief Bluetooth Mesh shell + * + */ + +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "syscfg/syscfg.h" + +#if MYNEWT_VAL(BLE_MESH_SHELL) + +#include +#include +#include +#include "shell/shell.h" +#include "console/console.h" +#include "mesh/mesh.h" +#include "mesh/main.h" +#include "mesh/glue.h" +#include "mesh/testing.h" + +/* Private includes for raw Network & Transport layer access */ +#include "net.h" +#include "access.h" +#include "mesh_priv.h" +#include "lpn.h" +#include "transport.h" +#include "foundation.h" +#include "testing.h" +#include "settings.h" + +#if MYNEWT_VAL(BLE_MESH_SHELL_MODELS) +#include "mesh/model_srv.h" +#include "mesh/model_cli.h" +#include "light_model.h" +#endif + +/* This should be higher priority (lower value) than main task priority */ +#define BLE_MESH_SHELL_TASK_PRIO 126 +#define BLE_MESH_SHELL_STACK_SIZE 768 + +OS_TASK_STACK_DEFINE(g_blemesh_shell_stack, BLE_MESH_SHELL_STACK_SIZE); + +struct os_task mesh_shell_task; +static struct os_eventq mesh_shell_queue; + +#define CID_NVAL 0xffff +#define CID_VENDOR 0x05C3 + +/* Vendor Model data */ +#define VND_MODEL_ID_1 0x1234 + +/* Default net, app & dev key values, unless otherwise specified */ +static const u8_t default_key[16] = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, +}; + +static struct { + u16_t local; + u16_t dst; + u16_t net_idx; + u16_t app_idx; +} net = { + .local = BT_MESH_ADDR_UNASSIGNED, + .dst = BT_MESH_ADDR_UNASSIGNED, +}; + +static struct bt_mesh_cfg_srv cfg_srv = { + .relay = BT_MESH_RELAY_DISABLED, + .beacon = BT_MESH_BEACON_ENABLED, +#if MYNEWT_VAL(BLE_MESH_FRIEND) + .frnd = BT_MESH_FRIEND_DISABLED, +#else + .frnd = BT_MESH_FRIEND_NOT_SUPPORTED, +#endif +#if MYNEWT_VAL(BLE_MESH_GATT_PROXY) + .gatt_proxy = BT_MESH_GATT_PROXY_DISABLED, +#else + .gatt_proxy = BT_MESH_GATT_PROXY_NOT_SUPPORTED, +#endif + + .default_ttl = 7, + + /* 3 transmissions with 20ms interval */ + .net_transmit = BT_MESH_TRANSMIT(2, 20), + .relay_retransmit = BT_MESH_TRANSMIT(2, 20), +}; + +#define CUR_FAULTS_MAX 4 + +static u8_t cur_faults[CUR_FAULTS_MAX]; +static u8_t reg_faults[CUR_FAULTS_MAX * 2]; + +static void get_faults(u8_t *faults, u8_t faults_size, u8_t *dst, u8_t *count) +{ + u8_t i, limit = *count; + + for (i = 0, *count = 0; i < faults_size && *count < limit; i++) { + if (faults[i]) { + *dst++ = faults[i]; + (*count)++; + } + } +} + +static int fault_get_cur(struct bt_mesh_model *model, u8_t *test_id, + u16_t *company_id, u8_t *faults, u8_t *fault_count) +{ + printk("Sending current faults\n"); + + *test_id = 0x00; + *company_id = CID_VENDOR; + + get_faults(cur_faults, sizeof(cur_faults), faults, fault_count); + + return 0; +} + +static int fault_get_reg(struct bt_mesh_model *model, u16_t cid, + u8_t *test_id, u8_t *faults, u8_t *fault_count) +{ + if (cid != CID_VENDOR) { + printk("Faults requested for unknown Company ID 0x%04x\n", cid); + return -EINVAL; + } + + printk("Sending registered faults\n"); + + *test_id = 0x00; + + get_faults(reg_faults, sizeof(reg_faults), faults, fault_count); + + return 0; +} + +static int fault_clear(struct bt_mesh_model *model, uint16_t cid) +{ + if (cid != CID_VENDOR) { + return -EINVAL; + } + + memset(reg_faults, 0, sizeof(reg_faults)); + + return 0; +} + +static int fault_test(struct bt_mesh_model *model, uint8_t test_id, + uint16_t cid) +{ + if (cid != CID_VENDOR) { + return -EINVAL; + } + + if (test_id != 0x00) { + return -EINVAL; + } + + return 0; +} + +static const struct bt_mesh_health_srv_cb health_srv_cb = { + .fault_get_cur = fault_get_cur, + .fault_get_reg = fault_get_reg, + .fault_clear = fault_clear, + .fault_test = fault_test, +}; + +static struct bt_mesh_health_srv health_srv = { + .cb = &health_srv_cb, +}; + +static struct bt_mesh_model_pub health_pub; + +static void +health_pub_init(void) +{ + health_pub.msg = BT_MESH_HEALTH_FAULT_MSG(CUR_FAULTS_MAX); +} +#if MYNEWT_VAL(BLE_MESH_CFG_CLI) + +static struct bt_mesh_cfg_cli cfg_cli = { +}; + +#endif /* MYNEWT_VAL(BLE_MESH_CFG_CLI) */ + +#if MYNEWT_VAL(BLE_MESH_HEALTH_CLI) +void show_faults(u8_t test_id, u16_t cid, u8_t *faults, size_t fault_count) +{ + size_t i; + + if (!fault_count) { + printk("Health Test ID 0x%02x Company ID 0x%04x: no faults\n", + test_id, cid); + return; + } + + printk("Health Test ID 0x%02x Company ID 0x%04x Fault Count %zu:\n", + test_id, cid, fault_count); + + for (i = 0; i < fault_count; i++) { + printk("\t0x%02x\n", faults[i]); + } +} + +static void health_current_status(struct bt_mesh_health_cli *cli, u16_t addr, + u8_t test_id, u16_t cid, u8_t *faults, + size_t fault_count) +{ + printk("Health Current Status from 0x%04x\n", addr); + show_faults(test_id, cid, faults, fault_count); +} + +static struct bt_mesh_health_cli health_cli = { + .current_status = health_current_status, +}; + +#endif /* MYNEWT_VAL(BLE_MESH_HEALTH_CLI) */ + +#if MYNEWT_VAL(BLE_MESH_SHELL_MODELS) +static struct bt_mesh_model_pub gen_onoff_pub; +static struct bt_mesh_model_pub gen_level_pub; +static struct bt_mesh_model_pub light_lightness_pub; +static struct bt_mesh_gen_onoff_srv_cb gen_onoff_srv_cb = { + .get = light_model_gen_onoff_get, + .set = light_model_gen_onoff_set, +}; +static struct bt_mesh_gen_level_srv_cb gen_level_srv_cb = { + .get = light_model_gen_level_get, + .set = light_model_gen_level_set, +}; +static struct bt_mesh_light_lightness_srv_cb light_lightness_srv_cb = { + .get = light_model_light_lightness_get, + .set = light_model_light_lightness_set, +}; + +void bt_mesh_set_gen_onoff_srv_cb(struct bt_mesh_gen_onoff_srv_cb *gen_onoff_cb) +{ + gen_onoff_srv_cb = *gen_onoff_cb; +} + +void bt_mesh_set_gen_level_srv_cb(struct bt_mesh_gen_level_srv_cb *gen_level_cb) +{ + gen_level_srv_cb = *gen_level_cb; +} + +void bt_mesh_set_light_lightness_srv_cb(struct bt_mesh_light_lightness_srv_cb *light_lightness_cb) +{ + light_lightness_srv_cb = *light_lightness_cb; +} + +#endif + +static struct bt_mesh_model root_models[] = { + BT_MESH_MODEL_CFG_SRV(&cfg_srv), + BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub), +#if MYNEWT_VAL(BLE_MESH_CFG_CLI) + BT_MESH_MODEL_CFG_CLI(&cfg_cli), +#endif +#if MYNEWT_VAL(BLE_MESH_HEALTH_CLI) + BT_MESH_MODEL_HEALTH_CLI(&health_cli), +#endif +#if MYNEWT_VAL(BLE_MESH_SHELL_MODELS) + BT_MESH_MODEL_GEN_ONOFF_SRV(&gen_onoff_srv_cb, &gen_onoff_pub), + BT_MESH_MODEL_GEN_ONOFF_CLI(), + BT_MESH_MODEL_GEN_LEVEL_SRV(&gen_level_srv_cb, &gen_level_pub), + BT_MESH_MODEL_GEN_LEVEL_CLI(), + BT_MESH_MODEL_LIGHT_LIGHTNESS_SRV(&light_lightness_srv_cb, &light_lightness_pub), +#endif +}; + +static struct bt_mesh_model vnd_models[] = { + BT_MESH_MODEL_VND(CID_VENDOR, VND_MODEL_ID_1, + BT_MESH_MODEL_NO_OPS, NULL, NULL), +}; + +static struct bt_mesh_elem elements[] = { + BT_MESH_ELEM(0, root_models, vnd_models), +}; + +static const struct bt_mesh_comp comp = { + .cid = CID_VENDOR, + .elem = elements, + .elem_count = ARRAY_SIZE(elements), +}; + +static u8_t hex2val(char c) +{ + if (c >= '0' && c <= '9') { + return c - '0'; + } else if (c >= 'a' && c <= 'f') { + return c - 'a' + 10; + } else if (c >= 'A' && c <= 'F') { + return c - 'A' + 10; + } else { + return 0; + } +} + +static size_t hex2bin(const char *hex, u8_t *bin, size_t bin_len) +{ + size_t len = 0; + + while (*hex && len < bin_len) { + bin[len] = hex2val(*hex++) << 4; + + if (!*hex) { + len++; + break; + } + + bin[len++] |= hex2val(*hex++); + } + + return len; +} + +static void prov_complete(u16_t net_idx, u16_t addr) +{ + printk("Local node provisioned, net_idx 0x%04x address 0x%04x\n", + net_idx, addr); + net.net_idx = net_idx, + net.local = addr; + net.dst = addr; +} + +static void prov_reset(void) +{ + printk("The local node has been reset and needs reprovisioning\n"); +} + +static int output_number(bt_mesh_output_action_t action, uint32_t number) +{ + printk("OOB Number: %lu\n", number); + return 0; +} + +static int output_string(const char *str) +{ + printk("OOB String: %s\n", str); + return 0; +} + +static bt_mesh_input_action_t input_act; +static u8_t input_size; + +static int cmd_input_num(int argc, char *argv[]) +{ + int err; + + if (argc < 2) { + return -EINVAL; + } + + if (input_act != BT_MESH_ENTER_NUMBER) { + printk("A number hasn't been requested!\n"); + return 0; + } + + if (strlen(argv[1]) < input_size) { + printk("Too short input (%u digits required)\n", + input_size); + return 0; + } + + err = bt_mesh_input_number(strtoul(argv[1], NULL, 10)); + if (err) { + printk("Numeric input failed (err %d)\n", err); + return 0; + } + + input_act = BT_MESH_NO_INPUT; + return 0; +} + +struct shell_cmd_help cmd_input_num_help = { + NULL, "", NULL +}; + +static int cmd_input_str(int argc, char *argv[]) +{ + int err; + + if (argc < 2) { + return -EINVAL; + } + + if (input_act != BT_MESH_ENTER_STRING) { + printk("A string hasn't been requested!\n"); + return 0; + } + + if (strlen(argv[1]) < input_size) { + printk("Too short input (%u characters required)\n", + input_size); + return 0; + } + + err = bt_mesh_input_string(argv[1]); + if (err) { + printk("String input failed (err %d)\n", err); + return 0; + } + + input_act = BT_MESH_NO_INPUT; + return 0; +} + +struct shell_cmd_help cmd_input_str_help = { + NULL, "", NULL +}; + +static int input(bt_mesh_input_action_t act, u8_t size) +{ + switch (act) { + case BT_MESH_ENTER_NUMBER: + printk("Enter a number (max %u digits) with: input-num \n", + size); + break; + case BT_MESH_ENTER_STRING: + printk("Enter a string (max %u chars) with: input-str \n", + size); + break; + default: + printk("Unknown input action %u (size %u) requested!\n", + act, size); + return -EINVAL; + } + + input_act = act; + input_size = size; + return 0; +} + +static const char *bearer2str(bt_mesh_prov_bearer_t bearer) +{ + switch (bearer) { + case BT_MESH_PROV_ADV: + return "PB-ADV"; + case BT_MESH_PROV_GATT: + return "PB-GATT"; + default: + return "unknown"; + } +} + +static void link_open(bt_mesh_prov_bearer_t bearer) +{ + printk("Provisioning link opened on %s\n", bearer2str(bearer)); +} + +static void link_close(bt_mesh_prov_bearer_t bearer) +{ + printk("Provisioning link closed on %s\n", bearer2str(bearer)); +} + +static u8_t dev_uuid[16] = MYNEWT_VAL(BLE_MESH_DEV_UUID); + +static u8_t static_val[16]; + +static struct bt_mesh_prov prov = { + .uuid = dev_uuid, + .link_open = link_open, + .link_close = link_close, + .complete = prov_complete, + .reset = prov_reset, + .static_val = NULL, + .static_val_len = 0, + .output_size = MYNEWT_VAL(BLE_MESH_OOB_OUTPUT_SIZE), + .output_actions = MYNEWT_VAL(BLE_MESH_OOB_OUTPUT_ACTIONS), + .output_number = output_number, + .output_string = output_string, + .input_size = MYNEWT_VAL(BLE_MESH_OOB_INPUT_SIZE), + .input_actions = MYNEWT_VAL(BLE_MESH_OOB_INPUT_ACTIONS), + .input = input, +}; + +static int cmd_static_oob(int argc, char *argv[]) +{ + if (argc < 2) { + prov.static_val = NULL; + prov.static_val_len = 0; + } else { + prov.static_val_len = hex2bin(argv[1], static_val, 16); + if (prov.static_val_len) { + prov.static_val = static_val; + } else { + prov.static_val = NULL; + } + } + + if (prov.static_val) { + printk("Static OOB value set (length %u)\n", + prov.static_val_len); + } else { + printk("Static OOB value cleared\n"); + } + + return 0; +} + +struct shell_cmd_help cmd_static_oob_help = { + NULL, "[val: 1-16 hex values]", NULL +}; + +static int cmd_uuid(int argc, char *argv[]) +{ + u8_t uuid[16]; + size_t len; + + if (argc < 2) { + return -EINVAL; + } + + len = hex2bin(argv[1], uuid, sizeof(uuid)); + if (len < 1) { + return -EINVAL; + } + + memcpy(dev_uuid, uuid, len); + memset(dev_uuid + len, 0, sizeof(dev_uuid) - len); + + printk("Device UUID set\n"); + + return 0; +} + +struct shell_cmd_help cmd_uuid_help = { + NULL, "", NULL +}; + +static int cmd_reset(int argc, char *argv[]) +{ + bt_mesh_reset(); + printk("Local node reset complete\n"); + return 0; +} + +static u8_t str2u8(const char *str) +{ + if (isdigit(str[0])) { + return strtoul(str, NULL, 0); + } + + return (!strcmp(str, "on") || !strcmp(str, "enable")); +} + +static bool str2bool(const char *str) +{ + return str2u8(str); +} + +#if MYNEWT_VAL(BLE_MESH_LOW_POWER) +static int cmd_lpn(int argc, char *argv[]) +{ + static bool enabled; + int err; + + if (argc < 2) { + printk("%s\n", enabled ? "enabled" : "disabled"); + return 0; + } + + if (str2bool(argv[1])) { + if (enabled) { + printk("LPN already enabled\n"); + return 0; + } + + err = bt_mesh_lpn_set(true); + if (err) { + printk("Enabling LPN failed (err %d)\n", err); + } else { + enabled = true; + } + } else { + if (!enabled) { + printk("LPN already disabled\n"); + return 0; + } + + err = bt_mesh_lpn_set(false); + if (err) { + printk("Enabling LPN failed (err %d)\n", err); + } else { + enabled = false; + } + } + + return 0; +} + +static int cmd_poll(int argc, char *argv[]) +{ + int err; + + err = bt_mesh_lpn_poll(); + if (err) { + printk("Friend Poll failed (err %d)\n", err); + } + + return 0; +} + +static void lpn_cb(u16_t friend_addr, bool established) +{ + if (established) { + printk("Friendship (as LPN) established to Friend 0x%04x\n", + friend_addr); + } else { + printk("Friendship (as LPN) lost with Friend 0x%04x\n", + friend_addr); + } +} + +struct shell_cmd_help cmd_lpn_help = { + NULL, "", NULL +}; + +#endif /* MESH_LOW_POWER */ + +static int check_pub_addr_unassigned(void) +{ +#ifdef ARCH_sim + return 0; +#else + uint8_t zero_addr[BLE_DEV_ADDR_LEN] = { 0 }; + + return memcmp(MYNEWT_VAL(BLE_PUBLIC_DEV_ADDR), + zero_addr, BLE_DEV_ADDR_LEN) == 0; +#endif +} + +int cmd_mesh_init(int argc, char *argv[]) +{ + int err; + ble_addr_t addr; + + if (check_pub_addr_unassigned()) { + /* Use NRPA */ + err = ble_hs_id_gen_rnd(1, &addr); + assert(err == 0); + err = ble_hs_id_set_rnd(addr.val); + assert(err == 0); + + err = bt_mesh_init(addr.type, &prov, &comp); + } + else { + err = bt_mesh_init(0, &prov, &comp); + } + + if (err) { + printk("Mesh initialization failed (err %d)\n", err); + } + + printk("Mesh initialized\n"); + + if (IS_ENABLED(CONFIG_SETTINGS)) { + settings_load(); + } + + if (bt_mesh_is_provisioned()) { + printk("Mesh network restored from flash\n"); + } else { + printk("Use \"pb-adv on\" or \"pb-gatt on\" to enable" + " advertising\n"); + } + +#if MYNEWT_VAL(BLE_MESH_LOW_POWER) + bt_mesh_lpn_set_cb(lpn_cb); +#endif + + return 0; +} + +#if MYNEWT_VAL(BLE_MESH_GATT_PROXY) +static int cmd_ident(int argc, char *argv[]) +{ + int err; + + err = bt_mesh_proxy_identity_enable(); + if (err) { + printk("Failed advertise using Node Identity (err %d)\n", err); + } + + return 0; +} +#endif /* MESH_GATT_PROXY */ + +static int cmd_dst(int argc, char *argv[]) +{ + if (argc < 2) { + printk("Destination address: 0x%04x%s\n", net.dst, + net.dst == net.local ? " (local)" : ""); + return 0; + } + + if (!strcmp(argv[1], "local")) { + net.dst = net.local; + } else { + net.dst = strtoul(argv[1], NULL, 0); + } + + printk("Destination address set to 0x%04x%s\n", net.dst, + net.dst == net.local ? " (local)" : ""); + return 0; +} + +struct shell_cmd_help cmd_dst_help = { + NULL, "[destination address]", NULL +}; + +static int cmd_netidx(int argc, char *argv[]) +{ + if (argc < 2) { + printk("NetIdx: 0x%04x\n", net.net_idx); + return 0; + } + + net.net_idx = strtoul(argv[1], NULL, 0); + printk("NetIdx set to 0x%04x\n", net.net_idx); + return 0; +} + +struct shell_cmd_help cmd_netidx_help = { + NULL, "[NetIdx]", NULL +}; + +static int cmd_appidx(int argc, char *argv[]) +{ + if (argc < 2) { + printk("AppIdx: 0x%04x\n", net.app_idx); + return 0; + } + + net.app_idx = strtoul(argv[1], NULL, 0); + printk("AppIdx set to 0x%04x\n", net.app_idx); + return 0; +} + +struct shell_cmd_help cmd_appidx_help = { + NULL, "[AppIdx]", NULL +}; + +static int cmd_net_send(int argc, char *argv[]) +{ + struct os_mbuf *msg = NET_BUF_SIMPLE(32); + struct bt_mesh_msg_ctx ctx = { + .send_ttl = BT_MESH_TTL_DEFAULT, + .net_idx = net.net_idx, + .addr = net.dst, + .app_idx = net.app_idx, + + }; + struct bt_mesh_net_tx tx = { + .ctx = &ctx, + .src = net.local, + .xmit = bt_mesh_net_transmit_get(), + .sub = bt_mesh_subnet_get(net.net_idx), + }; + size_t len; + int err = 0; + + if (argc < 2) { + err = -EINVAL; + goto done; + } + + if (!tx.sub) { + printk("No matching subnet for NetKey Index 0x%04x\n", + net.net_idx); + goto done; + } + + net_buf_simple_init(msg, 0); + len = hex2bin(argv[1], msg->om_data, net_buf_simple_tailroom(msg) - 4); + net_buf_simple_add(msg, len); + + err = bt_mesh_trans_send(&tx, msg, NULL, NULL); + if (err) { + printk("Failed to send (err %d)\n", err); + } + +done: + os_mbuf_free_chain(msg); + return err; +} + +struct shell_cmd_help cmd_net_send_help = { + NULL, "", NULL +}; + +static int cmd_iv_update(int argc, char *argv[]) +{ + if (bt_mesh_iv_update()) { + printk("Transitioned to IV Update In Progress state\n"); + } else { + printk("Transitioned to IV Update Normal state\n"); + } + + printk("IV Index is 0x%08lx\n", bt_mesh.iv_index); + + return 0; +} + +static int cmd_rpl_clear(int argc, char *argv[]) +{ + bt_mesh_rpl_clear(); + return 0; +} + +#if MYNEWT_VAL(BLE_MESH_LOW_POWER) +static int cmd_lpn_subscribe(int argc, char *argv[]) +{ + u16_t address; + + if (argc < 2) { + return -EINVAL; + } + + address = strtoul(argv[1], NULL, 0); + + printk("address 0x%04x", address); + + bt_mesh_lpn_group_add(address); + + return 0; +} + +struct shell_cmd_help cmd_lpn_subscribe_help = { + NULL, "", NULL +}; + +static int cmd_lpn_unsubscribe(int argc, char *argv[]) +{ + u16_t address; + + if (argc < 2) { + return -EINVAL; + } + + address = strtoul(argv[1], NULL, 0); + + printk("address 0x%04x", address); + + bt_mesh_lpn_group_del(&address, 1); + + return 0; +} + +struct shell_cmd_help cmd_lpn_unsubscribe_help = { + NULL, "", NULL +}; +#endif + +static int cmd_iv_update_test(int argc, char *argv[]) +{ + bool enable; + + if (argc < 2) { + return -EINVAL; + } + + enable = str2bool(argv[1]); + if (enable) { + printk("Enabling IV Update test mode\n"); + } else { + printk("Disabling IV Update test mode\n"); + } + + bt_mesh_iv_update_test(enable); + + return 0; +} + +struct shell_cmd_help cmd_iv_update_test_help = { + NULL, "", NULL +}; + +#if MYNEWT_VAL(BLE_MESH_CFG_CLI) + +int cmd_timeout(int argc, char *argv[]) +{ + s32_t timeout; + + if (argc < 2) { + timeout = bt_mesh_cfg_cli_timeout_get(); + if (timeout == K_FOREVER) { + printk("Message timeout: forever\n"); + } else { + printk("Message timeout: %lu seconds\n", + timeout / 1000); + } + + return 0; + } + + timeout = strtol(argv[1], NULL, 0); + if (timeout < 0 || timeout > (INT32_MAX / 1000)) { + timeout = K_FOREVER; + } else { + timeout = timeout * 1000; + } + + bt_mesh_cfg_cli_timeout_set(timeout); + if (timeout == K_FOREVER) { + printk("Message timeout: forever\n"); + } else { + printk("Message timeout: %lu seconds\n", + timeout / 1000); + } + + return 0; +} + +struct shell_cmd_help cmd_timeout_help = { + NULL, "[timeout in seconds]", NULL +}; + + +static int cmd_get_comp(int argc, char *argv[]) +{ + struct os_mbuf *comp = NET_BUF_SIMPLE(32); + u8_t status, page = 0x00; + int err = 0; + + if (argc > 1) { + page = strtol(argv[1], NULL, 0); + } + + net_buf_simple_init(comp, 0); + err = bt_mesh_cfg_comp_data_get(net.net_idx, net.dst, page, + &status, comp); + if (err) { + printk("Getting composition failed (err %d)\n", err); + goto done; + } + + if (status != 0x00) { + printk("Got non-success status 0x%02x\n", status); + goto done; + } + + printk("Got Composition Data for 0x%04x:\n", net.dst); + printk("\tCID 0x%04x\n", net_buf_simple_pull_le16(comp)); + printk("\tPID 0x%04x\n", net_buf_simple_pull_le16(comp)); + printk("\tVID 0x%04x\n", net_buf_simple_pull_le16(comp)); + printk("\tCRPL 0x%04x\n", net_buf_simple_pull_le16(comp)); + printk("\tFeatures 0x%04x\n", net_buf_simple_pull_le16(comp)); + + while (comp->om_len > 4) { + u8_t sig, vnd; + u16_t loc; + int i; + + loc = net_buf_simple_pull_le16(comp); + sig = net_buf_simple_pull_u8(comp); + vnd = net_buf_simple_pull_u8(comp); + + printk("\n\tElement @ 0x%04x:\n", loc); + + if (comp->om_len < ((sig * 2) + (vnd * 4))) { + printk("\t\t...truncated data!\n"); + break; + } + + if (sig) { + printk("\t\tSIG Models:\n"); + } else { + printk("\t\tNo SIG Models\n"); + } + + for (i = 0; i < sig; i++) { + u16_t mod_id = net_buf_simple_pull_le16(comp); + + printk("\t\t\t0x%04x\n", mod_id); + } + + if (vnd) { + printk("\t\tVendor Models:\n"); + } else { + printk("\t\tNo Vendor Models\n"); + } + + for (i = 0; i < vnd; i++) { + u16_t cid = net_buf_simple_pull_le16(comp); + u16_t mod_id = net_buf_simple_pull_le16(comp); + + printk("\t\t\tCompany 0x%04x: 0x%04x\n", cid, mod_id); + } + } + +done: + os_mbuf_free_chain(comp); + return err; +} + +struct shell_cmd_help cmd_get_comp_help = { + NULL, "[page]", NULL +}; + +static int cmd_beacon(int argc, char *argv[]) +{ + u8_t status; + int err; + + if (argc < 2) { + err = bt_mesh_cfg_beacon_get(net.net_idx, net.dst, &status); + } else { + u8_t val = str2u8(argv[1]); + + err = bt_mesh_cfg_beacon_set(net.net_idx, net.dst, val, + &status); + } + + if (err) { + printk("Unable to send Beacon Get/Set message (err %d)\n", err); + return 0; + } + + printk("Beacon state is 0x%02x\n", status); + + return 0; +} + +struct shell_cmd_help cmd_beacon_help = { + NULL, "[val: off, on]", NULL +}; + +static int cmd_ttl(int argc, char *argv[]) +{ + u8_t ttl; + int err; + + if (argc < 2) { + err = bt_mesh_cfg_ttl_get(net.net_idx, net.dst, &ttl); + } else { + u8_t val = strtoul(argv[1], NULL, 0); + + err = bt_mesh_cfg_ttl_set(net.net_idx, net.dst, val, &ttl); + } + + if (err) { + printk("Unable to send Default TTL Get/Set (err %d)\n", err); + return 0; + } + + printk("Default TTL is 0x%02x\n", ttl); + + return 0; +} + +struct shell_cmd_help cmd_ttl_help = { + NULL, "[ttl: 0x00, 0x02-0x7f]", NULL +}; + +static int cmd_friend(int argc, char *argv[]) +{ + u8_t frnd; + int err; + + if (argc < 2) { + err = bt_mesh_cfg_friend_get(net.net_idx, net.dst, &frnd); + } else { + u8_t val = str2u8(argv[1]); + + err = bt_mesh_cfg_friend_set(net.net_idx, net.dst, val, &frnd); + } + + if (err) { + printk("Unable to send Friend Get/Set (err %d)\n", err); + return 0; + } + + printk("Friend is set to 0x%02x\n", frnd); + + return 0; +} + +struct shell_cmd_help cmd_friend_help = { + NULL, "[val: off, on]", NULL +}; + +static int cmd_gatt_proxy(int argc, char *argv[]) +{ + u8_t proxy; + int err; + + if (argc < 2) { + err = bt_mesh_cfg_gatt_proxy_get(net.net_idx, net.dst, &proxy); + } else { + u8_t val = str2u8(argv[1]); + + err = bt_mesh_cfg_gatt_proxy_set(net.net_idx, net.dst, val, + &proxy); + } + + if (err) { + printk("Unable to send GATT Proxy Get/Set (err %d)\n", err); + return 0; + } + + printk("GATT Proxy is set to 0x%02x\n", proxy); + + return 0; +} + +struct shell_cmd_help cmd_gatt_proxy_help = { + NULL, "[val: off, on]", NULL +}; + +static int cmd_relay(int argc, char *argv[]) +{ + u8_t relay, transmit; + int err; + + if (argc < 2) { + err = bt_mesh_cfg_relay_get(net.net_idx, net.dst, &relay, + &transmit); + } else { + u8_t val = str2u8(argv[1]); + u8_t count, interval, new_transmit; + + if (val) { + if (argc > 2) { + count = strtoul(argv[2], NULL, 0); + } else { + count = 2; + } + + if (argc > 3) { + interval = strtoul(argv[3], NULL, 0); + } else { + interval = 20; + } + + new_transmit = BT_MESH_TRANSMIT(count, interval); + } else { + new_transmit = 0; + } + + err = bt_mesh_cfg_relay_set(net.net_idx, net.dst, val, + new_transmit, &relay, &transmit); + } + + if (err) { + printk("Unable to send Relay Get/Set (err %d)\n", err); + return 0; + } + + printk("Relay is 0x%02x, Transmit 0x%02x (count %u interval %ums)\n", + relay, transmit, BT_MESH_TRANSMIT_COUNT(transmit), + BT_MESH_TRANSMIT_INT(transmit)); + + return 0; +} + +struct shell_cmd_help cmd_relay_help = { + NULL, "[val: off, on] [count: 0-7] [interval: 0-32]", NULL +}; + +static int cmd_net_key_add(int argc, char *argv[]) +{ + u8_t key_val[16]; + u16_t key_net_idx; + u8_t status; + int err; + + if (argc < 2) { + return -EINVAL; + } + + key_net_idx = strtoul(argv[1], NULL, 0); + + if (argc > 2) { + size_t len; + + len = hex2bin(argv[3], key_val, sizeof(key_val)); + memset(key_val, 0, sizeof(key_val) - len); + } else { + memcpy(key_val, default_key, sizeof(key_val)); + } + + err = bt_mesh_cfg_net_key_add(net.net_idx, net.dst, key_net_idx, + key_val, &status); + if (err) { + printk("Unable to send NetKey Add (err %d)\n", err); + return 0; + } + + if (status) { + printk("NetKeyAdd failed with status 0x%02x\n", status); + } else { + printk("NetKey added with NetKey Index 0x%03x\n", key_net_idx); + } + + return 0; +} + +struct shell_cmd_help cmd_net_key_add_help = { + NULL, " [val]", NULL +}; + +static int cmd_app_key_add(int argc, char *argv[]) +{ + u8_t key_val[16]; + u16_t key_net_idx, key_app_idx; + u8_t status; + int err; + + if (argc < 3) { + return -EINVAL; + } + + key_net_idx = strtoul(argv[1], NULL, 0); + key_app_idx = strtoul(argv[2], NULL, 0); + + if (argc > 3) { + size_t len; + + len = hex2bin(argv[3], key_val, sizeof(key_val)); + memset(key_val, 0, sizeof(key_val) - len); + } else { + memcpy(key_val, default_key, sizeof(key_val)); + } + + err = bt_mesh_cfg_app_key_add(net.net_idx, net.dst, key_net_idx, + key_app_idx, key_val, &status); + if (err) { + printk("Unable to send App Key Add (err %d)\n", err); + return 0; + } + + if (status) { + printk("AppKeyAdd failed with status 0x%02x\n", status); + } else { + printk("AppKey added, NetKeyIndex 0x%04x AppKeyIndex 0x%04x\n", + key_net_idx, key_app_idx); + } + + return 0; +} + +struct shell_cmd_help cmd_app_key_add_help = { + NULL, " [val]", NULL +}; + +static int cmd_mod_app_bind(int argc, char *argv[]) +{ + u16_t elem_addr, mod_app_idx, mod_id, cid; + u8_t status; + int err; + + if (argc < 4) { + return -EINVAL; + } + + elem_addr = strtoul(argv[1], NULL, 0); + mod_app_idx = strtoul(argv[2], NULL, 0); + mod_id = strtoul(argv[3], NULL, 0); + + if (argc > 4) { + cid = strtoul(argv[4], NULL, 0); + err = bt_mesh_cfg_mod_app_bind_vnd(net.net_idx, net.dst, + elem_addr, mod_app_idx, + mod_id, cid, &status); + } else { + err = bt_mesh_cfg_mod_app_bind(net.net_idx, net.dst, elem_addr, + mod_app_idx, mod_id, &status); + } + + if (err) { + printk("Unable to send Model App Bind (err %d)\n", err); + return 0; + } + + if (status) { + printk("Model App Bind failed with status 0x%02x\n", status); + } else { + printk("AppKey successfully bound\n"); + } + + return 0; +} + +struct shell_cmd_help cmd_mod_app_bind_help = { + NULL, " [Company ID]", NULL +}; + +static int cmd_mod_sub_add(int argc, char *argv[]) +{ + u16_t elem_addr, sub_addr, mod_id, cid; + u8_t status; + int err; + + if (argc < 4) { + return -EINVAL; + } + + elem_addr = strtoul(argv[1], NULL, 0); + sub_addr = strtoul(argv[2], NULL, 0); + mod_id = strtoul(argv[3], NULL, 0); + + if (argc > 4) { + cid = strtoul(argv[4], NULL, 0); + err = bt_mesh_cfg_mod_sub_add_vnd(net.net_idx, net.dst, + elem_addr, sub_addr, mod_id, + cid, &status); + } else { + err = bt_mesh_cfg_mod_sub_add(net.net_idx, net.dst, elem_addr, + sub_addr, mod_id, &status); + } + + if (err) { + printk("Unable to send Model Subscription Add (err %d)\n", err); + return 0; + } + + if (status) { + printk("Model Subscription Add failed with status 0x%02x\n", + status); + } else { + printk("Model subscription was successful\n"); + } + + return 0; +} + +struct shell_cmd_help cmd_mod_sub_add_help = { + NULL, " [Company ID]", NULL +}; + +static int cmd_mod_sub_del(int argc, char *argv[]) +{ + u16_t elem_addr, sub_addr, mod_id, cid; + u8_t status; + int err; + + if (argc < 4) { + return -EINVAL; + } + + elem_addr = strtoul(argv[1], NULL, 0); + sub_addr = strtoul(argv[2], NULL, 0); + mod_id = strtoul(argv[3], NULL, 0); + + if (argc > 4) { + cid = strtoul(argv[4], NULL, 0); + err = bt_mesh_cfg_mod_sub_del_vnd(net.net_idx, net.dst, + elem_addr, sub_addr, mod_id, + cid, &status); + } else { + err = bt_mesh_cfg_mod_sub_del(net.net_idx, net.dst, elem_addr, + sub_addr, mod_id, &status); + } + + if (err) { + printk("Unable to send Model Subscription Delete (err %d)\n", + err); + return 0; + } + + if (status) { + printk("Model Subscription Delete failed with status 0x%02x\n", + status); + } else { + printk("Model subscription deltion was successful\n"); + } + + return 0; +} + +struct shell_cmd_help cmd_mod_sub_del_help = { + NULL, " [Company ID]", NULL +}; + +static int cmd_mod_sub_add_va(int argc, char *argv[]) +{ + u16_t elem_addr, sub_addr, mod_id, cid; + u8_t label[16]; + u8_t status; + size_t len; + int err; + + if (argc < 4) { + return -EINVAL; + } + + elem_addr = strtoul(argv[1], NULL, 0); + + len = hex2bin(argv[2], label, sizeof(label)); + memset(label + len, 0, sizeof(label) - len); + + mod_id = strtoul(argv[3], NULL, 0); + + if (argc > 4) { + cid = strtoul(argv[4], NULL, 0); + err = bt_mesh_cfg_mod_sub_va_add_vnd(net.net_idx, net.dst, + elem_addr, label, mod_id, + cid, &sub_addr, &status); + } else { + err = bt_mesh_cfg_mod_sub_va_add(net.net_idx, net.dst, + elem_addr, label, mod_id, + &sub_addr, &status); + } + + if (err) { + printk("Unable to send Mod Sub VA Add (err %d)\n", err); + return 0; + } + + if (status) { + printk("Mod Sub VA Add failed with status 0x%02x\n", + status); + } else { + printk("0x%04x subscribed to Label UUID %s (va 0x%04x)\n", + elem_addr, argv[2], sub_addr); + } + + return 0; +} + +struct shell_cmd_help cmd_mod_sub_add_va_help = { + NULL, "
    , {m} = , {e} =
    ")); @@ -1419,7 +1677,7 @@ void HandleTemplateConfiguration(void) { if (!HttpCheckPriviledgedAccess()) { return; } - if (WebServer->hasArg("save")) { + if (Webserver->hasArg("save")) { TemplateSaveSettings(); WebRestart(1); return; @@ -1427,16 +1685,6 @@ void HandleTemplateConfiguration(void) char stemp[30]; // Template number and Sensor name - if (WebServer->hasArg("m")) { - WSContentBegin(200, CT_PLAIN); - for (uint32_t i = 0; i < sizeof(kModuleNiceList); i++) { // "}2'%d'>%s (%d)}3" - "}2'0'>Sonoff Basic (1)}3" - uint32_t midx = pgm_read_byte(kModuleNiceList + i); - WSContentSend_P(HTTP_MODULE_TEMPLATE_REPLACE, midx, AnyModuleName(midx).c_str(), midx +1); - } - WSContentEnd(); - return; - } - WebGetArg("t", stemp, sizeof(stemp)); // 0 - 69 Template number if (strlen(stemp)) { uint32_t module = atoi(stemp); @@ -1449,25 +1697,8 @@ void HandleTemplateConfiguration(void) WSContentBegin(200, CT_PLAIN); WSContentSend_P(PSTR("%s}1"), AnyModuleName(module).c_str()); // NAME: Generic - for (uint32_t i = 0; i < sizeof(kGpioNiceList); i++) { // GPIO: }2'0'>None (0)}3}2'17'>Button1 (17)}3... - if (1 == i) { - WSContentSend_P(HTTP_MODULE_TEMPLATE_REPLACE, 255, D_SENSOR_USER, 255); // }2'255'>User (255)}3 - } - uint32_t midx = pgm_read_byte(kGpioNiceList + i); - WSContentSend_P(HTTP_MODULE_TEMPLATE_REPLACE, midx, GetTextIndexed(stemp, sizeof(stemp), midx, kSensorNames), midx); - } - WSContentSend_P(PSTR("}1")); // Field separator - - for (uint32_t i = 0; i < ADC0_END; i++) { // FLAG: }2'0'>None (0)}3}2'17'>Analog (17)}3... - if (1 == i) { - WSContentSend_P(HTTP_MODULE_TEMPLATE_REPLACE, ADC0_USER, D_SENSOR_USER, ADC0_USER); // }2'15'>User (15)}3 - } - WSContentSend_P(HTTP_MODULE_TEMPLATE_REPLACE, i, GetTextIndexed(stemp, sizeof(stemp), i, kAdc0Names), i); - } - WSContentSend_P(PSTR("}1")); // Field separator - - for (uint32_t i = 0; i < sizeof(cmodule); i++) { // 17,148,29,149,7,255,255,255,138,255,139,255,255 - if ((i < 6) || ((i > 8) && (i != 11))) { // Ignore flash pins GPIO06, 7, 8 and 11 + for (uint32_t i = 0; i < ARRAY_SIZE(cmodule.io); i++) { // 17,148,29,149,7,255,255,255,138,255,139,255,255 + if (!FlashPin(i)) { WSContentSend_P(PSTR("%s%d"), (i>0)?",":"", cmodule.io[i]); } } @@ -1480,7 +1711,65 @@ void HandleTemplateConfiguration(void) WSContentStart_P(S_CONFIGURE_TEMPLATE); WSContentSend_P(HTTP_SCRIPT_MODULE_TEMPLATE); + WSContentSend_P(HTTP_SCRIPT_TEMPLATE); + for (uint32_t i = 0; i < ARRAY_SIZE(kGpioNiceList); i++) { // GPIO: }2'0'>None (0)}3}2'17'>Button1 (17)}3... +#ifdef ESP8266 + if (1 == i) { + WSContentSend_P(HTTP_MODULE_TEMPLATE_REPLACE, AGPIO(GPIO_USER), D_SENSOR_USER, AGPIO(GPIO_USER)); // }2'255'>User (255)}3 + } + uint32_t midx = pgm_read_byte(kGpioNiceList + i); + uint32_t ridx = midx; + WSContentSend_P(HTTP_MODULE_TEMPLATE_REPLACE, ridx, GetTextIndexed(stemp, sizeof(stemp), midx, kSensorNames), ridx); +#else // ESP32 + if (1 == i) { + WSContentSend_P(HTTP_MODULE_TEMPLATE_REPLACE_NO_INDEX, AGPIO(GPIO_USER), D_SENSOR_USER); // }2'255'>User}3 + } + uint32_t ridx = pgm_read_word(kGpioNiceList + i) & 0xFFE0; + uint32_t midx = BGPIO(ridx); + WSContentSend_P(HTTP_MODULE_TEMPLATE_REPLACE_NO_INDEX, ridx, GetTextIndexed(stemp, sizeof(stemp), midx, kSensorNames)); +#endif // ESP8266 - ESP32 + } + WSContentSend_P(PSTR("\";")); + +#ifdef ESP32 + WSContentSend_P(PSTR("hs=[")); + bool first_done = false; + for (uint32_t i = 0; i < ARRAY_SIZE(kGpioNiceList); i++) { // hs=[36,68,100,132,168,200,232,264,292,324,356,388,421,453]; + uint32_t midx = pgm_read_word(kGpioNiceList + i); + if (midx & 0x001F) { + if (first_done) { WSContentSend_P(PSTR(",")); } + WSContentSend_P(PSTR("%d"), midx); + first_done = true; + } + } + WSContentSend_P(PSTR("];")); +#endif // ESP32 + + WSContentSend_P(HTTP_SCRIPT_TEMPLATE2); + +#ifdef ESP8266 + WSContentSend_P(PSTR("os=\"")); + for (uint32_t i = 0; i < ADC0_END; i++) { // FLAG: }2'0'>None (0)}3}2'17'>Analog (17)}3... + if (1 == i) { + WSContentSend_P(HTTP_MODULE_TEMPLATE_REPLACE, ADC0_USER, D_SENSOR_USER, ADC0_USER); // }2'15'>User (15)}3 + } + WSContentSend_P(HTTP_MODULE_TEMPLATE_REPLACE, i, GetTextIndexed(stemp, sizeof(stemp), i, kAdc0Names), i); + } + WSContentSend_P(HTTP_SCRIPT_TEMPLATE3); +#endif // ESP8266 + + WSContentSend_P(HTTP_SCRIPT_TEMPLATE4); + for (uint32_t i = 0; i < sizeof(kModuleNiceList); i++) { // "}2'%d'>%s (%d)}3" - "}2'0'>Sonoff Basic (1)}3" + uint32_t midx = pgm_read_byte(kModuleNiceList + i); +#ifdef ESP8266 + WSContentSend_P(HTTP_MODULE_TEMPLATE_REPLACE, midx, AnyModuleName(midx).c_str(), midx +1); +#else // ESP32 + WSContentSend_P(HTTP_MODULE_TEMPLATE_REPLACE_INDEX, midx, AnyModuleName(midx).c_str(), midx +1); +#endif // ESP8266 - ESP32 + } + WSContentSend_P(HTTP_SCRIPT_TEMPLATE5); + WSContentSendStyle(); WSContentSend_P(HTTP_FORM_TEMPLATE); WSContentSend_P(HTTP_TABLE100); @@ -1489,18 +1778,32 @@ void HandleTemplateConfiguration(void) "" "
    ")); WSContentSend_P(HTTP_TABLE100); - for (uint32_t i = 0; i < 17; i++) { - if ((i < 6) || ((i > 8) && (i != 11))) { // Ignore flash pins GPIO06, 7, 8 and 11 + for (uint32_t i = 0; i < MAX_GPIO_PIN; i++) { + if (!FlashPin(i)) { +#ifdef ESP8266 WSContentSend_P(PSTR("" D_GPIO "%d"), ((9==i)||(10==i)) ? WebColor(COL_TEXT_WARNING) : WebColor(COL_TEXT), i, (0==i) ? " style='width:200px'" : "", i); +#else // ESP32 + WSContentSend_P(PSTR("" D_GPIO "%d"), + ((9==i)||(10==i)) ? WebColor(COL_TEXT_WARNING) : WebColor(COL_TEXT), i, (0==i) ? " style='width:150px'" : "", i, i); + WSContentSend_P(PSTR(""), i); +#endif // ESP8266 } } +#ifdef ESP8266 WSContentSend_P(PSTR("" D_ADC "0"), WebColor(COL_TEXT)); +#endif WSContentSend_P(PSTR("")); + gpio_flag flag = ModuleFlag(); +#ifdef ESP8266 if (flag.data > ADC0_USER) { +#else // ESP32 + if (flag.data) { +#endif // ESP32 WSContentSend_P(HTTP_FORM_TEMPLATE_FLAG); } + WSContentSend_P(HTTP_FORM_END); WSContentSpaceButton(BUTTON_CONFIGURATION); WSContentStop(); @@ -1510,27 +1813,39 @@ void TemplateSaveSettings(void) { char tmp[TOPSZ]; // WebGetArg NAME and GPIO/BASE/FLAG byte value char webindex[5]; // WebGetArg name - char svalue[200]; // Template command string + char svalue[300]; // Template command string WebGetArg("s1", tmp, sizeof(tmp)); // NAME snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_TEMPLATE " {\"" D_JSON_NAME "\":\"%s\",\"" D_JSON_GPIO "\":["), tmp); uint32_t j = 0; - for (uint32_t i = 0; i < sizeof(Settings.user_template.gp); i++) { + for (uint32_t i = 0; i < ARRAY_SIZE(Settings.user_template.gp.io); i++) { if (6 == i) { j = 9; } if (8 == i) { j = 12; } snprintf_P(webindex, sizeof(webindex), PSTR("g%d"), j); WebGetArg(webindex, tmp, sizeof(tmp)); // GPIO - uint8_t gpio = atoi(tmp); + uint32_t gpio = atoi(tmp); +#ifdef ESP32 + char tmp2[8]; // WebGetArg numbers only + char webindex2[5]; // WebGetArg name + snprintf_P(webindex2, sizeof(webindex2), PSTR("h%d"), j); + WebGetArg(webindex2, tmp2, sizeof(tmp2)); + uint32_t value2 = (!strlen(tmp2)) ? 0 : atoi(tmp2) -1; + gpio += value2; +#endif // ESP32 snprintf_P(svalue, sizeof(svalue), PSTR("%s%s%d"), svalue, (i>0)?",":"", gpio); j++; } - WebGetArg("g17", tmp, sizeof(tmp)); // FLAG - ADC0 +#ifdef ESP8266 + WebGetArg("g" STR(ADC0_PIN), tmp, sizeof(tmp)); // FLAG - ADC0 uint32_t flag = atoi(tmp); +#else // ESP32 + uint32_t flag = 0; +#endif // ESP32 for (uint32_t i = 0; i < GPIO_FLAG_USED; i++) { snprintf_P(webindex, sizeof(webindex), PSTR("c%d"), i); - uint32_t state = WebServer->hasArg(webindex) << i +4; // FLAG + uint32_t state = Webserver->hasArg(webindex) << i +4; // FLAG flag += state; } WebGetArg("g99", tmp, sizeof(tmp)); // BASE @@ -1546,84 +1861,112 @@ void HandleModuleConfiguration(void) { if (!HttpCheckPriviledgedAccess()) { return; } - if (WebServer->hasArg("save")) { + if (Webserver->hasArg("save")) { ModuleSaveSettings(); WebRestart(1); return; } + AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_MODULE); + char stemp[30]; // Sensor name uint32_t midx; myio cmodule; ModuleGpios(&cmodule); - if (WebServer->hasArg("m")) { - WSContentBegin(200, CT_PLAIN); - uint32_t vidx = 0; - for (uint32_t i = 0; i <= sizeof(kModuleNiceList); i++) { // "}2'%d'>%s (%d)}3" - "}2'255'>UserTemplate (0)}3" - "}2'0'>Sonoff Basic (1)}3" - if (0 == i) { - midx = USER_MODULE; - vidx = 0; - } else { - midx = pgm_read_byte(kModuleNiceList + i -1); - vidx = midx +1; - } - WSContentSend_P(HTTP_MODULE_TEMPLATE_REPLACE, midx, AnyModuleName(midx).c_str(), vidx); - } - WSContentEnd(); - return; - } - - if (WebServer->hasArg("g")) { - WSContentBegin(200, CT_PLAIN); - for (uint32_t j = 0; j < sizeof(kGpioNiceList); j++) { - midx = pgm_read_byte(kGpioNiceList + j); - if (!GetUsedInModule(midx, cmodule.io)) { - WSContentSend_P(HTTP_MODULE_TEMPLATE_REPLACE, midx, GetTextIndexed(stemp, sizeof(stemp), midx, kSensorNames), midx); - } - } - WSContentEnd(); - return; - } - -#ifndef USE_ADC_VCC - if (WebServer->hasArg("a")) { - WSContentBegin(200, CT_PLAIN); - for (uint32_t j = 0; j < ADC0_END; j++) { - WSContentSend_P(HTTP_MODULE_TEMPLATE_REPLACE, j, GetTextIndexed(stemp, sizeof(stemp), j, kAdc0Names), j); - } - WSContentEnd(); - return; - } -#endif // USE_ADC_VCC - - AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_MODULE); - WSContentStart_P(S_CONFIGURE_MODULE); WSContentSend_P(HTTP_SCRIPT_MODULE_TEMPLATE); - WSContentSend_P(HTTP_SCRIPT_MODULE1, Settings.module); - for (uint32_t i = 0; i < sizeof(cmodule); i++) { + + WSContentSend_P(PSTR("function sl(){os=\"")); + uint32_t vidx = 0; + for (uint32_t i = 0; i <= sizeof(kModuleNiceList); i++) { // "}2'%d'>%s (%d)}3" - "}2'255'>UserTemplate (0)}3" - "}2'0'>Sonoff Basic (1)}3" + if (0 == i) { + midx = USER_MODULE; + vidx = 0; + } else { + midx = pgm_read_byte(kModuleNiceList + i -1); + vidx = midx +1; + } +#ifdef ESP8266 + WSContentSend_P(HTTP_MODULE_TEMPLATE_REPLACE, midx, AnyModuleName(midx).c_str(), vidx); +#else // ESP32 + WSContentSend_P(HTTP_MODULE_TEMPLATE_REPLACE_INDEX, midx, AnyModuleName(midx).c_str(), vidx); +#endif // ESP8266 - ESP32 + } + WSContentSend_P(PSTR("\";sk(%d,99);os=\""), Settings.module); + for (uint32_t i = 0; i < ARRAY_SIZE(kGpioNiceList); i++) { +#ifdef ESP8266 + midx = pgm_read_byte(kGpioNiceList + i); + uint32_t ridx = midx; + if (!GetUsedInModule(midx, cmodule.io)) { + WSContentSend_P(HTTP_MODULE_TEMPLATE_REPLACE, ridx, GetTextIndexed(stemp, sizeof(stemp), midx, kSensorNames), ridx); + } +#else // ESP32 + uint32_t ridx = pgm_read_word(kGpioNiceList + i) & 0xFFE0; + midx = BGPIO(ridx); + if (!GetUsedInModule(midx, cmodule.io)) { + WSContentSend_P(HTTP_MODULE_TEMPLATE_REPLACE_NO_INDEX, ridx, GetTextIndexed(stemp, sizeof(stemp), midx, kSensorNames)); + } +#endif // ESP8266 - ESP32 + } + WSContentSend_P(PSTR("\";")); + +#ifdef ESP32 + WSContentSend_P(PSTR("hs=[")); + bool first_done = false; + for (uint32_t i = 0; i < ARRAY_SIZE(kGpioNiceList); i++) { // hs=[36,68,100,132,168,200,232,264,292,324,356,388,421,453]; + midx = pgm_read_word(kGpioNiceList + i); + if (midx & 0x001F) { + if (first_done) { WSContentSend_P(PSTR(",")); } + WSContentSend_P(PSTR("%d"), midx); + first_done = true; + } + } + WSContentSend_P(PSTR("];")); +#endif // ESP32 + + for (uint32_t i = 0; i < ARRAY_SIZE(cmodule.io); i++) { if (ValidGPIO(i, cmodule.io[i])) { WSContentSend_P(PSTR("sk(%d,%d);"), my_module.io[i], i); // g0 - g16 } } - WSContentSend_P(HTTP_SCRIPT_MODULE2, Settings.my_adc0); + +#ifdef ESP8266 +#ifndef USE_ADC_VCC + WSContentSend_P(PSTR("os=\"")); + for (uint32_t j = 0; j < ADC0_END; j++) { + WSContentSend_P(HTTP_MODULE_TEMPLATE_REPLACE, j, GetTextIndexed(stemp, sizeof(stemp), j, kAdc0Names), j); + } + WSContentSend_P(PSTR("\";sk(%d," STR(ADC0_PIN) ");"), Settings.my_adc0); +#endif // USE_ADC_VCC +#endif // ESP8266 - ESP32 + + WSContentSend_P(PSTR("}wl(sl);")); + WSContentSendStyle(); WSContentSend_P(HTTP_FORM_MODULE, AnyModuleName(MODULE).c_str()); - for (uint32_t i = 0; i < sizeof(cmodule); i++) { + for (uint32_t i = 0; i < ARRAY_SIZE(cmodule.io); i++) { if (ValidGPIO(i, cmodule.io[i])) { snprintf_P(stemp, 3, PINS_WEMOS +i*2); +#ifdef ESP8266 char sesp8285[40]; snprintf_P(sesp8285, sizeof(sesp8285), PSTR("ESP8285"), WebColor(COL_TEXT_WARNING)); WSContentSend_P(PSTR("%s " D_GPIO "%d %s"), (WEMOS==my_module_type)?stemp:"", i, (0==i)? D_SENSOR_BUTTON "1":(1==i)? D_SERIAL_OUT :(3==i)? D_SERIAL_IN :((9==i)||(10==i))? sesp8285 :(12==i)? D_SENSOR_RELAY "1":(13==i)? D_SENSOR_LED "1i":(14==i)? D_SENSOR :"", i); +#else // ESP32 + WSContentSend_P(PSTR("%s " D_GPIO "%d"), + (WEMOS==my_module_type)?stemp:"", i, i, i); + WSContentSend_P(PSTR(""), i); +#endif // ESP8266 } } +#ifdef ESP8266 #ifndef USE_ADC_VCC if (ValidAdc()) { WSContentSend_P(PSTR("%s " D_ADC "0"), (WEMOS==my_module_type)?"A0":""); } #endif // USE_ADC_VCC +#endif // ESP8266 WSContentSend_P(PSTR("")); WSContentSend_P(HTTP_FORM_END); WSContentSpaceButton(BUTTON_CONFIGURATION); @@ -1643,31 +1986,42 @@ void ModuleSaveSettings(void) myio cmodule; ModuleGpios(&cmodule); String gpios = ""; - for (uint32_t i = 0; i < sizeof(cmodule); i++) { + for (uint32_t i = 0; i < ARRAY_SIZE(cmodule.io); i++) { if (Settings.last_module != new_module) { Settings.my_gp.io[i] = GPIO_NONE; } else { if (ValidGPIO(i, cmodule.io[i])) { snprintf_P(webindex, sizeof(webindex), PSTR("g%d"), i); WebGetArg(webindex, tmp, sizeof(tmp)); - Settings.my_gp.io[i] = (!strlen(tmp)) ? 0 : atoi(tmp); - gpios += F(", " D_GPIO ); gpios += String(i); gpios += F(" "); gpios += String(Settings.my_gp.io[i]); + uint32_t value = (!strlen(tmp)) ? 0 : atoi(tmp); +#ifdef ESP32 + char tmp2[8]; // WebGetArg numbers only + char webindex2[5]; // WebGetArg name + snprintf_P(webindex2, sizeof(webindex2), PSTR("h%d"), i); + WebGetArg(webindex2, tmp2, sizeof(tmp2)); + uint32_t value2 = (!strlen(tmp2)) ? 0 : atoi(tmp2) -1; + value += value2; +#endif // ESP8266 - ESP32 + Settings.my_gp.io[i] = value; + gpios += F(", " D_GPIO ); gpios += String(i); gpios += F(" "); gpios += String(value); } } } +#ifdef ESP8266 #ifndef USE_ADC_VCC - WebGetArg("g17", tmp, sizeof(tmp)); + WebGetArg("g" STR(ADC0_PIN), tmp, sizeof(tmp)); Settings.my_adc0 = (!strlen(tmp)) ? 0 : atoi(tmp); gpios += F(", " D_ADC "0 "); gpios += String(Settings.my_adc0); #endif // USE_ADC_VCC +#endif // ESP8266 AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_MODULE "%s " D_CMND_MODULE "%s"), ModuleName().c_str(), gpios.c_str()); } /*-------------------------------------------------------------------------------------------*/ -const char kUnescapeCode[] = "&><\"\'"; -const char kEscapeCode[] PROGMEM = "&|>|<|"|'"; +const char kUnescapeCode[] = "&><\"\'\\"; +const char kEscapeCode[] PROGMEM = "&|>|<|"|'|\"; String HtmlEscape(const String unescaped) { char escaped[10]; @@ -1694,7 +2048,7 @@ void HandleWifiConfiguration(void) AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_WIFI); - if (WebServer->hasArg("save") && HTTP_MANAGER_RESET_ONLY != Web.state) { + if (Webserver->hasArg("save") && HTTP_MANAGER_RESET_ONLY != Web.state) { WifiSaveSettings(); WebRestart(2); return; @@ -1705,7 +2059,7 @@ void HandleWifiConfiguration(void) WSContentSendStyle(); if (HTTP_MANAGER_RESET_ONLY != Web.state) { - if (WebServer->hasArg("scan")) { + if (Webserver->hasArg("scan")) { #ifdef USE_EMULATION UdpDisconnect(); #endif // USE_EMULATION @@ -1818,7 +2172,7 @@ void HandleLoggingConfiguration(void) AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_LOGGING); - if (WebServer->hasArg("save")) { + if (Webserver->hasArg("save")) { LoggingSaveSettings(); HandleConfiguration(); return; @@ -1883,7 +2237,7 @@ void HandleOtherConfiguration(void) AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_OTHER); - if (WebServer->hasArg("save")) { + if (Webserver->hasArg("save")) { OtherSaveSettings(); WebRestart(1); return; @@ -1895,7 +2249,9 @@ void HandleOtherConfiguration(void) TemplateJson(); char stemp[strlen(mqtt_data) +1]; strlcpy(stemp, mqtt_data, sizeof(stemp)); // Get JSON template - WSContentSend_P(HTTP_FORM_OTHER, stemp, (USER_MODULE == Settings.module) ? " checked disabled" : "", (Settings.flag.mqtt_enabled) ? " checked" : ""); // SetOption3 - Enable MQTT + WSContentSend_P(HTTP_FORM_OTHER, stemp, (USER_MODULE == Settings.module) ? " checked disabled" : "", + (Settings.flag.mqtt_enabled) ? " checked" : "", // SetOption3 - Enable MQTT + SettingsText(SET_FRIENDLYNAME1), SettingsText(SET_DEVICENAME)); uint32_t maxfn = (devices_present > MAX_FRIENDLYNAMES) ? MAX_FRIENDLYNAMES : (!devices_present) ? 1 : devices_present; #ifdef USE_SONOFF_IFAN @@ -1903,7 +2259,7 @@ void HandleOtherConfiguration(void) #endif // USE_SONOFF_IFAN for (uint32_t i = 0; i < maxfn; i++) { snprintf_P(stemp, sizeof(stemp), PSTR("%d"), i +1); - WSContentSend_P(PSTR("" D_FRIENDLY_NAME " %d (" FRIENDLY_NAME "%s)

    "), + WSContentSend_P(PSTR("" D_FRIENDLY_NAME " %d (" FRIENDLY_NAME "%s)

    "), i +1, (i) ? stemp : "", i, @@ -1940,14 +2296,16 @@ void HandleOtherConfiguration(void) void OtherSaveSettings(void) { - char tmp[TOPSZ]; + char tmp[300]; // Needs to hold complete ESP32 template of minimal 230 chars char webindex[5]; char friendlyname[TOPSZ]; char message[LOGSZ]; + WebGetArg("dn", tmp, sizeof(tmp)); + SettingsUpdateText(SET_DEVICENAME, (!strlen(tmp)) ? "" : (!strcmp(tmp,"1")) ? SettingsText(SET_FRIENDLYNAME1) : tmp); WebGetArg("wp", tmp, sizeof(tmp)); SettingsUpdateText(SET_WEBPWD, (!strlen(tmp)) ? "" : (strchr(tmp,'*')) ? SettingsText(SET_WEBPWD) : tmp); - Settings.flag.mqtt_enabled = WebServer->hasArg("b1"); // SetOption3 - Enable MQTT + Settings.flag.mqtt_enabled = Webserver->hasArg("b1"); // SetOption3 - Enable MQTT #ifdef USE_EMULATION UdpDisconnect(); #if defined(USE_EMULATION_WEMO) || defined(USE_EMULATION_HUE) @@ -1956,7 +2314,8 @@ void OtherSaveSettings(void) #endif // USE_EMULATION_WEMO || USE_EMULATION_HUE #endif // USE_EMULATION - snprintf_P(message, sizeof(message), PSTR(D_LOG_OTHER D_MQTT_ENABLE " %s, " D_CMND_EMULATION " %d, " D_CMND_FRIENDLYNAME), GetStateText(Settings.flag.mqtt_enabled), Settings.flag2.emulation); + snprintf_P(message, sizeof(message), PSTR(D_LOG_OTHER D_MQTT_ENABLE " %s, " D_CMND_EMULATION " %d, " D_CMND_DEVICENAME " %s, " D_CMND_FRIENDLYNAME), + GetStateText(Settings.flag.mqtt_enabled), Settings.flag2.emulation, SettingsText(SET_DEVICENAME)); for (uint32_t i = 0; i < MAX_FRIENDLYNAMES; i++) { snprintf_P(webindex, sizeof(webindex), PSTR("a%d"), i); WebGetArg(webindex, tmp, sizeof(tmp)); @@ -1966,25 +2325,9 @@ void OtherSaveSettings(void) } AddLog_P(LOG_LEVEL_INFO, message); -/* - // This sometimes provides intermittent watchdog - bool template_activate = WebServer->hasArg("t2"); // Try this to tackle intermittent watchdog after execution of Template command WebGetArg("t1", tmp, sizeof(tmp)); if (strlen(tmp)) { // {"NAME":"12345678901234","GPIO":[255,255,255,255,255,255,255,255,255,255,255,255,255],"FLAG":255,"BASE":255} - char svalue[128]; - snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_TEMPLATE " %s"), tmp); - ExecuteWebCommand(svalue, SRC_WEBGUI); - - if (template_activate) { - snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_MODULE " 0")); - ExecuteWebCommand(svalue, SRC_WEBGUI); - } - } - // Try async execution of commands -*/ - WebGetArg("t1", tmp, sizeof(tmp)); - if (strlen(tmp)) { // {"NAME":"12345678901234","GPIO":[255,255,255,255,255,255,255,255,255,255,255,255,255],"FLAG":255,"BASE":255} - snprintf_P(message, sizeof(message), PSTR(D_CMND_BACKLOG " " D_CMND_TEMPLATE " %s%s"), tmp, (WebServer->hasArg("t2")) ? "; " D_CMND_MODULE " 0" : ""); + snprintf_P(message, sizeof(message), PSTR(D_CMND_BACKLOG " " D_CMND_TEMPLATE " %s%s"), tmp, (Webserver->hasArg("t2")) ? "; " D_CMND_MODULE " 0" : ""); ExecuteWebCommand(message, SRC_WEBGUI); } } @@ -1999,8 +2342,8 @@ void HandleBackupConfiguration(void) if (!SettingsBufferAlloc()) { return; } - WiFiClient myClient = WebServer->client(); - WebServer->setContentLength(sizeof(Settings)); + WiFiClient myClient = Webserver->client(); + Webserver->setContentLength(sizeof(Settings)); char attachment[TOPSZ]; @@ -2010,7 +2353,7 @@ void HandleBackupConfiguration(void) char hostname[sizeof(my_hostname)]; snprintf_P(attachment, sizeof(attachment), PSTR("attachment; filename=Config_%s_%s.dmp"), NoAlNumToUnderscore(hostname, my_hostname), my_version); - WebServer->sendHeader(F("Content-Disposition"), attachment); + Webserver->sendHeader(F("Content-Disposition"), attachment); WSSend(200, CT_STREAM, ""); @@ -2089,7 +2432,7 @@ void HandleInformation(void) char stopic[TOPSZ]; - int freeMem = ESP.getFreeHeap(); + int freeMem = ESP_getFreeHeap(); WSContentStart_P(S_INFORMATION); // Save 1k of code space replacing table html with javascript replace codes @@ -2099,9 +2442,13 @@ void HandleInformation(void) WSContentSend_P(PSTR("
    ")); WSContentSend_P(PSTR(D_PROGRAM_VERSION "}2%s%s"), my_version, my_image); WSContentSend_P(PSTR("}1" D_BUILD_DATE_AND_TIME "}2%s"), GetBuildDateAndTime().c_str()); - WSContentSend_P(PSTR("}1" D_CORE_AND_SDK_VERSION "}2" ARDUINO_ESP8266_RELEASE "/%s"), ESP.getSdkVersion()); + WSContentSend_P(PSTR("}1" D_CORE_AND_SDK_VERSION "}2" ARDUINO_CORE_RELEASE "/%s"), ESP.getSdkVersion()); WSContentSend_P(PSTR("}1" D_UPTIME "}2%s"), GetUptime().c_str()); +#ifdef ESP8266 WSContentSend_P(PSTR("}1" D_FLASH_WRITE_COUNT "}2%d at 0x%X"), Settings.save_flag, GetSettingsAddress()); +#else + WSContentSend_P(PSTR("}1" D_FLASH_WRITE_COUNT "}2%d"), Settings.save_flag); +#endif WSContentSend_P(PSTR("}1" D_BOOT_COUNT "}2%d"), Settings.bootcount); WSContentSend_P(PSTR("}1" D_RESTART_REASON "}2%s"), GetResetReason().c_str()); uint32_t maxfn = (devices_present > MAX_FRIENDLYNAMES) ? MAX_FRIENDLYNAMES : devices_present; @@ -2112,26 +2459,42 @@ void HandleInformation(void) WSContentSend_P(PSTR("}1" D_FRIENDLY_NAME " %d}2%s"), i +1, SettingsText(SET_FRIENDLYNAME1 +i)); } WSContentSend_P(PSTR("}1}2 ")); // Empty line - int32_t rssi = WiFi.RSSI(); - WSContentSend_P(PSTR("}1" D_AP "%d " D_SSID " (" D_RSSI ")}2%s (%d%%, %d dBm)"), Settings.sta_active +1, SettingsText(SET_STASSID1 + Settings.sta_active), WifiGetRssiAsQuality(rssi), rssi); - WSContentSend_P(PSTR("}1" D_HOSTNAME "}2%s%s"), my_hostname, (Wifi.mdns_begun) ? ".local" : ""); +#ifdef ESP32 +#ifdef USE_ETHERNET + if (static_cast(EthernetLocalIP()) != 0) { + WSContentSend_P(PSTR("}1" D_HOSTNAME "}2%s%s"), EthernetHostname(), (Mdns.begun) ? ".local" : ""); + WSContentSend_P(PSTR("}1" D_MAC_ADDRESS "}2%s"), EthernetMacAddress().c_str()); + WSContentSend_P(PSTR("}1" D_IP_ADDRESS " (eth)}2%s"), EthernetLocalIP().toString().c_str()); + WSContentSend_P(PSTR("}1
    }2
    ")); + } +#endif +#endif + if (Settings.flag4.network_wifi) { + int32_t rssi = WiFi.RSSI(); + WSContentSend_P(PSTR("}1" D_AP "%d " D_SSID " (" D_RSSI ")}2%s (%d%%, %d dBm)"), Settings.sta_active +1, HtmlEscape(SettingsText(SET_STASSID1 + Settings.sta_active)).c_str(), WifiGetRssiAsQuality(rssi), rssi); + WSContentSend_P(PSTR("}1" D_HOSTNAME "}2%s%s"), my_hostname, (Mdns.begun) ? ".local" : ""); #if LWIP_IPV6 String ipv6_addr = WifiGetIPv6(); - if(ipv6_addr != ""){ + if (ipv6_addr != "") { WSContentSend_P(PSTR("}1 IPv6 Address }2%s"), ipv6_addr.c_str()); } #endif - if (static_cast(WiFi.localIP()) != 0) { - WSContentSend_P(PSTR("}1" D_IP_ADDRESS "}2%s"), WiFi.localIP().toString().c_str()); + if (static_cast(WiFi.localIP()) != 0) { + WSContentSend_P(PSTR("}1" D_MAC_ADDRESS "}2%s"), WiFi.macAddress().c_str()); + WSContentSend_P(PSTR("}1" D_IP_ADDRESS " (wifi)}2%s"), WiFi.localIP().toString().c_str()); + WSContentSend_P(PSTR("}1
    }2
    ")); + } + } + if (!global_state.network_down) { WSContentSend_P(PSTR("}1" D_GATEWAY "}2%s"), IPAddress(Settings.ip_address[1]).toString().c_str()); WSContentSend_P(PSTR("}1" D_SUBNET_MASK "}2%s"), IPAddress(Settings.ip_address[2]).toString().c_str()); WSContentSend_P(PSTR("}1" D_DNS_SERVER "}2%s"), IPAddress(Settings.ip_address[3]).toString().c_str()); - WSContentSend_P(PSTR("}1" D_MAC_ADDRESS "}2%s"), WiFi.macAddress().c_str()); } - if (static_cast(WiFi.softAPIP()) != 0) { - WSContentSend_P(PSTR("}1" D_IP_ADDRESS "}2%s"), WiFi.softAPIP().toString().c_str()); - WSContentSend_P(PSTR("}1" D_GATEWAY "}2%s"), WiFi.softAPIP().toString().c_str()); + if ((WiFi.getMode() >= WIFI_AP) && (static_cast(WiFi.softAPIP()) != 0)) { + WSContentSend_P(PSTR("}1
    }2
    ")); WSContentSend_P(PSTR("}1" D_MAC_ADDRESS "}2%s"), WiFi.softAPmacAddress().c_str()); + WSContentSend_P(PSTR("}1" D_IP_ADDRESS " (AP)}2%s"), WiFi.softAPIP().toString().c_str()); + WSContentSend_P(PSTR("}1" D_GATEWAY "}2%s"), WiFi.softAPIP().toString().c_str()); } WSContentSend_P(PSTR("}1}2 ")); // Empty line if (Settings.flag.mqtt_enabled) { // SetOption3 - Enable MQTT @@ -2174,13 +2537,21 @@ void HandleInformation(void) #endif // USE_DISCOVERY WSContentSend_P(PSTR("}1}2 ")); // Empty line - WSContentSend_P(PSTR("}1" D_ESP_CHIP_ID "}2%d"), ESP.getChipId()); + WSContentSend_P(PSTR("}1" D_ESP_CHIP_ID "}2%d"), ESP_getChipId()); +#ifdef ESP8266 WSContentSend_P(PSTR("}1" D_FLASH_CHIP_ID "}20x%06X"), ESP.getFlashChipId()); +#endif WSContentSend_P(PSTR("}1" D_FLASH_CHIP_SIZE "}2%dkB"), ESP.getFlashChipRealSize() / 1024); WSContentSend_P(PSTR("}1" D_PROGRAM_FLASH_SIZE "}2%dkB"), ESP.getFlashChipSize() / 1024); - WSContentSend_P(PSTR("}1" D_PROGRAM_SIZE "}2%dkB"), ESP.getSketchSize() / 1024); + WSContentSend_P(PSTR("}1" D_PROGRAM_SIZE "}2%dkB"), ESP_getSketchSize() / 1024); WSContentSend_P(PSTR("}1" D_FREE_PROGRAM_SPACE "}2%dkB"), ESP.getFreeSketchSpace() / 1024); WSContentSend_P(PSTR("}1" D_FREE_MEMORY "}2%dkB"), freeMem / 1024); +#ifdef ESP32 + if (psramFound()) { + WSContentSend_P(PSTR("}1" D_PSR_MAX_MEMORY "}2%dkB"), ESP.getPsramSize() / 1024); + WSContentSend_P(PSTR("}1" D_PSR_FREE_MEMORY "}2%dkB"), ESP.getFreePsram() / 1024); + } +#endif WSContentSend_P(PSTR("
    ")); WSContentSend_P(HTTP_SCRIPT_INFO_END); @@ -2230,7 +2601,7 @@ void HandleUpgradeFirmwareStart(void) } WSContentStart_P(S_INFORMATION); - WSContentSend_P(HTTP_SCRIPT_RELOAD_OTA); + WSContentSend_P(HTTP_SCRIPT_RELOAD_TIME, HTTP_OTA_RESTART_RECONNECT_TIME); WSContentSendStyle(); WSContentSend_P(PSTR("
    " D_UPGRADE_STARTED " ...
    ")); WSContentSend_P(HTTP_MSG_RSTRT); @@ -2255,7 +2626,7 @@ void HandleUploadDone(void) WSContentStart_P(S_INFORMATION); if (!Web.upload_error) { - WSContentSend_P(HTTP_SCRIPT_RELOAD_OTA); // Refesh main web ui after OTA upgrade + WSContentSend_P(HTTP_SCRIPT_RELOAD_TIME, HTTP_OTA_RESTART_RECONNECT_TIME); // Refesh main web ui after OTA upgrade } WSContentSendStyle(); WSContentSend_P(PSTR("
    " D_UPLOAD " " D_SUCCESSFUL "
    "), WebColor(COL_TEXT_SUCCESS)); WSContentSend_P(HTTP_MSG_RSTRT); ShowWebSource(SRC_WEBGUI); -#ifdef USE_TASMOTA_SLAVE - if (TasmotaSlave_GetFlagFlashing()) { +#ifdef USE_TASMOTA_CLIENT + if (TasmotaClient_GetFlagFlashing()) { restart_flag = 0; } else { // It was a normal firmware file, or we are ready to restart device restart_flag = 2; @@ -2292,9 +2663,9 @@ void HandleUploadDone(void) WSContentSend_P(PSTR("

    ")); WSContentSpaceButton(BUTTON_MAIN); WSContentStop(); -#ifdef USE_TASMOTA_SLAVE - if (TasmotaSlave_GetFlagFlashing()) { - TasmotaSlave_Flash(); +#ifdef USE_TASMOTA_CLIENT + if (TasmotaClient_GetFlagFlashing()) { + TasmotaClient_Flash(); } #endif } @@ -2310,7 +2681,7 @@ void HandleUploadLoop(void) return; } - HTTPUpload& upload = WebServer->upload(); + HTTPUpload& upload = Webserver->upload(); if (UPLOAD_FILE_START == upload.status) { restart_flag = 60; @@ -2364,11 +2735,11 @@ void HandleUploadLoop(void) if (Web.upload_error != 0) { return; } } else #endif // USE_RF_FLASH -#ifdef USE_TASMOTA_SLAVE - if ((WEMOS == my_module_type) && (upload.buf[0] == ':')) { // Check if this is a ARDUINO SLAVE hex file +#ifdef USE_TASMOTA_CLIENT + if ((WEMOS == my_module_type) && (upload.buf[0] == ':')) { // Check if this is a ARDUINO CLIENT hex file Update.end(); // End esp8266 update session - Web.upload_file_type = UPL_TASMOTASLAVE; - Web.upload_error = TasmotaSlave_UpdateInit(); // 0 + Web.upload_file_type = UPL_TASMOTACLIENT; + Web.upload_error = TasmotaClient_UpdateInit(); // 0 if (Web.upload_error != 0) { return; } } else #endif @@ -2432,9 +2803,9 @@ void HandleUploadLoop(void) } } #endif // USE_RF_FLASH -#ifdef USE_TASMOTA_SLAVE - else if (UPL_TASMOTASLAVE == Web.upload_file_type) { - TasmotaSlave_WriteBuffer(upload.buf, upload.currentSize); +#ifdef USE_TASMOTA_CLIENT + else if (UPL_TASMOTACLIENT == Web.upload_file_type) { + TasmotaClient_WriteBuffer(upload.buf, upload.currentSize); } #endif else { // firmware @@ -2472,6 +2843,16 @@ void HandleUploadLoop(void) } else { valid_settings = (settings_buffer[0] == CONFIG_FILE_SIGN); } + + if (valid_settings) { +#ifdef ESP8266 + valid_settings = (0 == settings_buffer[0xF36]); // Settings.config_version +#endif // ESP8266 +#ifdef ESP32 + valid_settings = (1 == settings_buffer[0xF36]); // Settings.config_version +#endif // ESP32 + } + if (valid_settings) { SettingsDefaultSet2(); memcpy((char*)&Settings +16, settings_buffer +16, sizeof(Settings) -16); @@ -2488,10 +2869,10 @@ void HandleUploadLoop(void) Web.upload_file_type = UPL_TASMOTA; } #endif // USE_RF_FLASH -#ifdef USE_TASMOTA_SLAVE - else if (UPL_TASMOTASLAVE == Web.upload_file_type) { +#ifdef USE_TASMOTA_CLIENT + else if (UPL_TASMOTACLIENT == Web.upload_file_type) { // Done writing the hex to SPI flash - TasmotaSlave_SetFlagFlashing(true); // So we know on upload success page if it needs to flash hex or do a normal restart + TasmotaClient_SetFlagFlashing(true); // So we know on upload success page if it needs to flash hex or do a normal restart Web.upload_file_type = UPL_TASMOTA; } #endif @@ -2523,8 +2904,8 @@ void HandleUploadLoop(void) void HandlePreflightRequest(void) { HttpHeaderCors(); - WebServer->sendHeader(F("Access-Control-Allow-Methods"), F("GET, POST")); - WebServer->sendHeader(F("Access-Control-Allow-Headers"), F("authorization")); + Webserver->sendHeader(F("Access-Control-Allow-Methods"), F("GET, POST")); + Webserver->sendHeader(F("Access-Control-Allow-Headers"), F("authorization")); WSSend(200, CT_HTML, ""); } @@ -2536,54 +2917,54 @@ void HandleHttpCommand(void) AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_COMMAND)); - bool valid = true; if (strlen(SettingsText(SET_WEBPWD))) { char tmp1[33]; WebGetArg("user", tmp1, sizeof(tmp1)); char tmp2[strlen(SettingsText(SET_WEBPWD)) +1]; WebGetArg("password", tmp2, sizeof(tmp2)); - if (!(!strcmp(tmp1, WEB_USERNAME) && !strcmp(tmp2, SettingsText(SET_WEBPWD)))) { valid = false; } + if (!(!strcmp(tmp1, WEB_USERNAME) && !strcmp(tmp2, SettingsText(SET_WEBPWD)))) { + WSContentBegin(401, CT_JSON); + WSContentSend_P(PSTR("{\"" D_RSLT_WARNING "\":\"" D_NEED_USER_AND_PASSWORD "\"}")); + WSContentEnd(); + return; + } } WSContentBegin(200, CT_JSON); - if (valid) { - uint32_t curridx = web_log_index; - String svalue = WebServer->arg("cmnd"); - if (svalue.length() && (svalue.length() < MQTT_MAX_PACKET_SIZE)) { - ExecuteWebCommand((char*)svalue.c_str(), SRC_WEBCOMMAND); - if (web_log_index != curridx) { - uint32_t counter = curridx; - WSContentSend_P(PSTR("{")); - bool cflg = false; - do { - char* tmp; - size_t len; - GetLog(counter, &tmp, &len); - if (len) { - // [14:49:36 MQTT: stat/wemos5/RESULT = {"POWER":"OFF"}] > [{"POWER":"OFF"}] - char* JSON = (char*)memchr(tmp, '{', len); - if (JSON) { // Is it a JSON message (and not only [15:26:08 MQT: stat/wemos5/POWER = O]) - size_t JSONlen = len - (JSON - tmp); - if (JSONlen > sizeof(mqtt_data)) { JSONlen = sizeof(mqtt_data); } - char stemp[JSONlen]; - strlcpy(stemp, JSON +1, JSONlen -2); - WSContentSend_P(PSTR("%s%s"), (cflg) ? "," : "", stemp); - cflg = true; - } + uint32_t curridx = web_log_index; + String svalue = Webserver->arg("cmnd"); + if (svalue.length() && (svalue.length() < MQTT_MAX_PACKET_SIZE)) { + ExecuteWebCommand((char*)svalue.c_str(), SRC_WEBCOMMAND); + if (web_log_index != curridx) { + uint32_t counter = curridx; + WSContentSend_P(PSTR("{")); + bool cflg = false; + do { + char* tmp; + size_t len; + GetLog(counter, &tmp, &len); + if (len) { + // [14:49:36 MQTT: stat/wemos5/RESULT = {"POWER":"OFF"}] > [{"POWER":"OFF"}] + char* JSON = (char*)memchr(tmp, '{', len); + if (JSON) { // Is it a JSON message (and not only [15:26:08 MQT: stat/wemos5/POWER = O]) + size_t JSONlen = len - (JSON - tmp); + if (JSONlen > sizeof(mqtt_data)) { JSONlen = sizeof(mqtt_data); } + char stemp[JSONlen]; + strlcpy(stemp, JSON +1, JSONlen -2); + WSContentSend_P(PSTR("%s%s"), (cflg) ? "," : "", stemp); + cflg = true; } - counter++; - counter &= 0xFF; - if (!counter) counter++; // Skip 0 as it is not allowed - } while (counter != web_log_index); - WSContentSend_P(PSTR("}")); - } else { - WSContentSend_P(PSTR("{\"" D_RSLT_WARNING "\":\"" D_ENABLE_WEBLOG_FOR_RESPONSE "\"}")); - } + } + counter++; + counter &= 0xFF; + if (!counter) counter++; // Skip 0 as it is not allowed + } while (counter != web_log_index); + WSContentSend_P(PSTR("}")); } else { - WSContentSend_P(PSTR("{\"" D_RSLT_WARNING "\":\"" D_ENTER_COMMAND " cmnd=\"}")); + WSContentSend_P(PSTR("{\"" D_RSLT_WARNING "\":\"" D_ENABLE_WEBLOG_FOR_RESPONSE "\"}")); } } else { - WSContentSend_P(PSTR("{\"" D_RSLT_WARNING "\":\"" D_NEED_USER_AND_PASSWORD "\"}")); + WSContentSend_P(PSTR("{\"" D_RSLT_WARNING "\":\"" D_ENTER_COMMAND " cmnd=\"}")); } WSContentEnd(); } @@ -2594,7 +2975,7 @@ void HandleConsole(void) { if (!HttpCheckPriviledgedAccess()) { return; } - if (WebServer->hasArg("c2")) { // Console refresh requested + if (Webserver->hasArg("c2")) { // Console refresh requested HandleConsoleRefresh(); return; } @@ -2614,7 +2995,7 @@ void HandleConsoleRefresh(void) bool cflg = true; uint32_t counter = 0; // Initial start, should never be 0 again - String svalue = WebServer->arg("c1"); + String svalue = Webserver->arg("c1"); if (svalue.length() && (svalue.length() < MQTT_MAX_PACKET_SIZE)) { AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_COMMAND "%s"), svalue.c_str()); ExecuteWebCommand((char*)svalue.c_str(), SRC_WEBCONSOLE); @@ -2659,13 +3040,13 @@ void HandleConsoleRefresh(void) void HandleNotFound(void) { -// AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP "Not found (%s)"), WebServer->uri().c_str()); +// AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP "Not found (%s)"), Webserver->uri().c_str()); if (CaptivePortal()) { return; } // If captive portal redirect instead of displaying the error page. #ifdef USE_EMULATION #ifdef USE_EMULATION_HUE - String path = WebServer->uri(); + String path = Webserver->uri(); if ((EMUL_HUE == Settings.flag2.emulation) && (path.startsWith("/api"))) { HandleHueApi(&path); } else @@ -2673,9 +3054,9 @@ void HandleNotFound(void) #endif // USE_EMULATION { WSContentBegin(404, CT_PLAIN); - WSContentSend_P(PSTR(D_FILE_NOT_FOUND "\n\nURI: %s\nMethod: %s\nArguments: %d\n"), WebServer->uri().c_str(), (WebServer->method() == HTTP_GET) ? "GET" : "POST", WebServer->args()); - for (uint32_t i = 0; i < WebServer->args(); i++) { - WSContentSend_P(PSTR(" %s: %s\n"), WebServer->argName(i).c_str(), WebServer->arg(i).c_str()); + WSContentSend_P(PSTR(D_FILE_NOT_FOUND "\n\nURI: %s\nMethod: %s\nArguments: %d\n"), Webserver->uri().c_str(), (Webserver->method() == HTTP_GET) ? "GET" : "POST", Webserver->args()); + for (uint32_t i = 0; i < Webserver->args(); i++) { + WSContentSend_P(PSTR(" %s: %s\n"), Webserver->argName(i).c_str(), Webserver->arg(i).c_str()); } WSContentEnd(); } @@ -2685,12 +3066,12 @@ void HandleNotFound(void) bool CaptivePortal(void) { // Possible hostHeader: connectivitycheck.gstatic.com or 192.168.4.1 - if ((WifiIsInManagerMode()) && !ValidIpAddress(WebServer->hostHeader().c_str())) { + if ((WifiIsInManagerMode()) && !ValidIpAddress(Webserver->hostHeader().c_str())) { AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_REDIRECTED)); - WebServer->sendHeader(F("Location"), String("http://") + WebServer->client().localIP().toString(), true); + Webserver->sendHeader(F("Location"), String("http://") + Webserver->client().localIP().toString(), true); WSSend(302, CT_PLAIN, ""); // Empty content inhibits Content-length header so we have to close the socket ourselves. - WebServer->client().stop(); // Stop is needed because we sent no content length + Webserver->client().stop(); // Stop is needed because we sent no content length return true; } return false; @@ -2911,7 +3292,7 @@ void CmndWebServer(void) } if (Settings.webserver) { Response_P(PSTR("{\"" D_CMND_WEBSERVER "\":\"" D_JSON_ACTIVE_FOR " %s " D_JSON_ON_DEVICE " %s " D_JSON_WITH_IP_ADDRESS " %s\"}"), - (2 == Settings.webserver) ? D_ADMIN : D_USER, my_hostname, WiFi.localIP().toString().c_str()); + (2 == Settings.webserver) ? D_ADMIN : D_USER, NetworkHostname(), NetworkAddress().toString().c_str()); } else { ResponseCmndStateText(0); } @@ -3021,11 +3402,7 @@ bool Xdrv01(uint8_t function) case FUNC_LOOP: PollDnsWebserver(); #ifdef USE_EMULATION -#ifdef USE_DEVICE_GROUPS - if (Settings.flag2.emulation || Settings.flag4.device_groups_enabled) { PollUdp(); } -#else // USE_DEVICE_GROUPS if (Settings.flag2.emulation) { PollUdp(); } -#endif // USE_DEVICE_GROUPS #endif // USE_EMULATION break; case FUNC_COMMAND: diff --git a/tasmota/xdrv_02_mqtt.ino b/tasmota/xdrv_02_mqtt.ino index 7c8f0b29a..7a7eae075 100644 --- a/tasmota/xdrv_02_mqtt.ino +++ b/tasmota/xdrv_02_mqtt.ino @@ -123,34 +123,6 @@ void MakeValidMqtt(uint32_t option, char* str) } } -#ifdef USE_DISCOVERY -#ifdef MQTT_HOST_DISCOVERY -void MqttDiscoverServer(void) -{ - if (!Wifi.mdns_begun) { return; } - - int n = MDNS.queryService("mqtt", "tcp"); // Search for mqtt service - - AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS D_QUERY_DONE " %d"), n); - - if (n > 0) { - uint32_t i = 0; // If the hostname isn't set, use the first record found. -#ifdef MDNS_HOSTNAME - for (i = n; i > 0; i--) { // Search from last to first and use first if not found - if (!strcmp(MDNS.hostname(i).c_str(), MDNS_HOSTNAME)) { - break; // Stop at matching record - } - } -#endif // MDNS_HOSTNAME - SettingsUpdateText(SET_MQTT_HOST, MDNS.IP(i).toString().c_str()); - Settings.mqtt_port = MDNS.port(i); - - AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS D_MQTT_SERVICE_FOUND " %s, " D_IP_ADDRESS " %s, " D_PORT " %d"), MDNS.hostname(i).c_str(), SettingsText(SET_MQTT_HOST), Settings.mqtt_port); - } -} -#endif // MQTT_HOST_DISCOVERY -#endif // USE_DISCOVERY - /*********************************************************************************************\ * MQTT driver specific code need to provide the following functions: * @@ -374,7 +346,7 @@ void MqttPublishPrefixTopic_P(uint32_t prefix, const char* subtopic, bool retain MqttPublish(stopic, retained); #ifdef USE_MQTT_AWS_IOT - if ((prefix > 0) && (Settings.flag4.awsiot_shadow)) { // placeholder for SetOptionXX + if ((prefix > 0) && (Settings.flag4.awsiot_shadow) && (Mqtt.connected)) { // placeholder for SetOptionXX // compute the target topic char *topic = SettingsText(SET_MQTT_TOPIC); char topic2[strlen(topic)+1]; // save buffer onto stack @@ -539,10 +511,10 @@ void MqttConnected(void) if (Settings.webserver) { #if LWIP_IPV6 Response_P(PSTR("{\"" D_JSON_WEBSERVER_MODE "\":\"%s\",\"" D_CMND_HOSTNAME "\":\"%s\",\"" D_CMND_IPADDRESS "\":\"%s\",\"IPv6Address\":\"%s\"}"), - (2 == Settings.webserver) ? D_ADMIN : D_USER, my_hostname, WiFi.localIP().toString().c_str(),WifiGetIPv6().c_str()); + (2 == Settings.webserver) ? D_ADMIN : D_USER, NetworkHostname(), NetworkAddress().toString().c_str(), WifiGetIPv6().c_str()); #else Response_P(PSTR("{\"" D_JSON_WEBSERVER_MODE "\":\"%s\",\"" D_CMND_HOSTNAME "\":\"%s\",\"" D_CMND_IPADDRESS "\":\"%s\"}"), - (2 == Settings.webserver) ? D_ADMIN : D_USER, my_hostname, WiFi.localIP().toString().c_str()); + (2 == Settings.webserver) ? D_ADMIN : D_USER, NetworkHostname(), NetworkAddress().toString().c_str()); #endif // LWIP_IPV6 = 1 MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_INFO "2")); } @@ -1028,6 +1000,9 @@ void CmndPowerRetain(void) } } Settings.flag.mqtt_power_retain = XdrvMailbox.payload; // CMND_POWERRETAIN + if (Settings.flag.mqtt_power_retain) { + Settings.flag4.only_json_message = 0; // SetOption90 - Disable non-json MQTT response + } } ResponseCmndStateText(Settings.flag.mqtt_power_retain); // CMND_POWERRETAIN } @@ -1237,14 +1212,14 @@ const char HTTP_BTN_MENU_MQTT[] PROGMEM = const char HTTP_FORM_MQTT1[] PROGMEM = "
     " D_MQTT_PARAMETERS " " "
    " - "

    " D_HOST " (" MQTT_HOST ")

    " + "

    " D_HOST " (" MQTT_HOST ")

    " "

    " D_PORT " (" STR(MQTT_PORT) ")

    " - "

    " D_CLIENT " (%s)

    "; + "

    " D_CLIENT " (%s)

    "; const char HTTP_FORM_MQTT2[] PROGMEM = - "

    " D_USER " (" MQTT_USER ")

    " - "


    " - "

    " D_TOPIC " = %%topic%% (%s)

    " - "

    " D_FULL_TOPIC " (%s)

    "; + "

    " D_USER " (" MQTT_USER ")

    " + "


    " + "

    " D_TOPIC " = %%topic%% (%s)

    " + "

    " D_FULL_TOPIC " (%s)

    "; void HandleMqttConfiguration(void) { @@ -1252,7 +1227,7 @@ void HandleMqttConfiguration(void) AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_MQTT); - if (WebServer->hasArg("save")) { + if (Webserver->hasArg("save")) { MqttSaveSettings(); WebRestart(1); return; @@ -1334,7 +1309,7 @@ bool Xdrv02(uint8_t function) WSContentSend_P(HTTP_BTN_MENU_MQTT); break; case FUNC_WEB_ADD_HANDLER: - WebServer->on("/" WEB_HANDLE_MQTT, HandleMqttConfiguration); + Webserver->on("/" WEB_HANDLE_MQTT, HandleMqttConfiguration); break; #endif // USE_WEBSERVER case FUNC_COMMAND: diff --git a/tasmota/xdrv_03_energy.ino b/tasmota/xdrv_03_energy.ino index bb74b991d..f38265bb8 100644 --- a/tasmota/xdrv_03_energy.ino +++ b/tasmota/xdrv_03_energy.ino @@ -80,10 +80,12 @@ struct ENERGY { float power_factor[3] = { NAN, NAN, NAN }; // 0.12 float frequency[3] = { NAN, NAN, NAN }; // 123.1 Hz +// float import_active[3] = { NAN, NAN, NAN }; // 123.123 kWh + float export_active[3] = { NAN, NAN, NAN }; // 123.123 kWh + float start_energy = 0; // 12345.12345 kWh total previous float daily = 0; // 123.123 kWh float total = 0; // 12345.12345 kWh total energy - float export_active = NAN; // 123.123 KWh unsigned long kWhtoday_delta = 0; // 1212312345 Wh 10^-5 (deca micro Watt hours) - Overflows to Energy.kWhtoday (HLW and CSE only) unsigned long kWhtoday_offset = 0; // 12312312 Wh * 10^-2 (deca milli Watt hours) - 5764 = 0.05764 kWh = 0.058 kWh = Energy.daily @@ -95,7 +97,9 @@ struct ENERGY { uint8_t data_valid[3] = { 0, 0, 0 }; uint8_t phase_count = 1; // Number of phases active - bool voltage_common = false; // Use single voltage and frequency + bool voltage_common = false; // Use single voltage + bool frequency_common = false; // Use single frequency + bool kWhtoday_offset_init = false; bool voltage_available = true; // Enable if voltage is measured bool current_available = true; // Enable if current is measured @@ -169,9 +173,18 @@ void EnergyUpdateToday(void) RtcSettings.energy_usage.last_usage_kWhtotal = (uint32_t)(Energy.total * 100000); uint32_t return_diff = 0; - if (!isnan(Energy.export_active)) { - return_diff = (uint32_t)(Energy.export_active * 100000) - RtcSettings.energy_usage.last_return_kWhtotal; - RtcSettings.energy_usage.last_return_kWhtotal = (uint32_t)(Energy.export_active * 100000); + if (!isnan(Energy.export_active[0])) { +// return_diff = (uint32_t)(Energy.export_active * 100000) - RtcSettings.energy_usage.last_return_kWhtotal; +// RtcSettings.energy_usage.last_return_kWhtotal = (uint32_t)(Energy.export_active * 100000); + + float export_active = 0.0; + for (uint32_t i = 0; i < Energy.phase_count; i++) { + if (!isnan(Energy.export_active[i])) { + export_active += Energy.export_active[i]; + } + } + return_diff = (uint32_t)(export_active * 100000) - RtcSettings.energy_usage.last_return_kWhtotal; + RtcSettings.energy_usage.last_return_kWhtotal = (uint32_t)(export_active * 100000); } if (EnergyTariff1Active()) { // Tarrif1 = Off-Peak @@ -223,6 +236,12 @@ void Energy200ms(void) XnrgCall(FUNC_ENERGY_EVERY_SECOND); if (RtcTime.valid) { + + if (!Energy.kWhtoday_offset_init && (RtcTime.day_of_year == Settings.energy_kWhdoy)) { + Energy.kWhtoday_offset = Settings.energy_kWhtoday; + Energy.kWhtoday_offset_init = true; + } + if (LocalTime() == Midnight()) { Settings.energy_kWhyesterday = RtcSettings.energy_kWhtoday; @@ -440,7 +459,12 @@ void EnergyEverySecond(void) { // Overtemp check if (global_update) { - if (power && (global_temperature != 9999) && (global_temperature > Settings.param[P_OVER_TEMP])) { // Device overtemp, turn off relays + if (power && !isnan(global_temperature_celsius) && (global_temperature_celsius > (float)Settings.param[P_OVER_TEMP])) { // Device overtemp, turn off relays + + char temperature[33]; + dtostrfd(global_temperature_celsius, 1, temperature); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("NRG: GlobTemp %s"), temperature); + SetAllPower(POWER_ALL_OFF, SRC_OVERTEMP); } } @@ -459,13 +483,13 @@ void EnergyEverySecond(void) if (!isnan(Energy.reactive_power[i])) { Energy.reactive_power[i] = 0; } if (!isnan(Energy.frequency[i])) { Energy.frequency[i] = 0; } if (!isnan(Energy.power_factor[i])) { Energy.power_factor[i] = 0; } + if (!isnan(Energy.export_active[i])) { Energy.export_active[i] = 0; } data_valid--; } } } if (!data_valid) { - if (!isnan(Energy.export_active)) { Energy.export_active = 0; } Energy.start_energy = 0; XnrgCall(FUNC_ENERGY_RESET); @@ -827,14 +851,11 @@ void EnergySnsInit(void) XnrgCall(FUNC_INIT); if (energy_flg) { - if (RtcSettingsValid()) { + Energy.kWhtoday_offset = 0; + // Do not use at Power On as Rtc was invalid (but has been restored from Settings already) + if ((ResetReason() != REASON_DEFAULT_RST) && RtcSettingsValid()) { Energy.kWhtoday_offset = RtcSettings.energy_kWhtoday; - } - else if (RtcTime.day_of_year == Settings.energy_kWhdoy) { - Energy.kWhtoday_offset = Settings.energy_kWhtoday; - } - else { - Energy.kWhtoday_offset = 0; + Energy.kWhtoday_offset_init = true; } Energy.kWhtoday = 0; Energy.kWhtoday_delta = 0; @@ -944,29 +965,31 @@ void EnergyShow(bool json) char voltage_chr[Energy.phase_count][FLOATSZ]; char current_chr[Energy.phase_count][FLOATSZ]; char active_power_chr[Energy.phase_count][FLOATSZ]; + char export_active_chr[Energy.phase_count][FLOATSZ]; for (uint32_t i = 0; i < Energy.phase_count; i++) { dtostrfd(Energy.voltage[i], Settings.flag2.voltage_resolution, voltage_chr[i]); dtostrfd(Energy.current[i], Settings.flag2.current_resolution, current_chr[i]); dtostrfd(Energy.active_power[i], Settings.flag2.wattage_resolution, active_power_chr[i]); + dtostrfd(Energy.export_active[i], Settings.flag2.energy_resolution, export_active_chr[i]); } + char energy_total_chr[FLOATSZ]; + dtostrfd(Energy.total, Settings.flag2.energy_resolution, energy_total_chr); char energy_daily_chr[FLOATSZ]; dtostrfd(Energy.daily, Settings.flag2.energy_resolution, energy_daily_chr); char energy_yesterday_chr[FLOATSZ]; dtostrfd((float)Settings.energy_kWhyesterday / 100000, Settings.flag2.energy_resolution, energy_yesterday_chr); - char energy_total_chr[3][FLOATSZ]; - dtostrfd(Energy.total, Settings.flag2.energy_resolution, energy_total_chr[0]); - char export_active_chr[3][FLOATSZ]; - dtostrfd(Energy.export_active, Settings.flag2.energy_resolution, export_active_chr[0]); - uint8_t energy_total_fields = 1; + bool energy_tariff = false; + char energy_usage_chr[2][FLOATSZ]; + char energy_return_chr[2][FLOATSZ]; if (Settings.tariff[0][0] != Settings.tariff[1][0]) { - dtostrfd((float)RtcSettings.energy_usage.usage1_kWhtotal / 100000, Settings.flag2.energy_resolution, energy_total_chr[1]); // Tariff1 - dtostrfd((float)RtcSettings.energy_usage.usage2_kWhtotal / 100000, Settings.flag2.energy_resolution, energy_total_chr[2]); // Tariff2 - dtostrfd((float)RtcSettings.energy_usage.return1_kWhtotal / 100000, Settings.flag2.energy_resolution, export_active_chr[1]); // Tariff1 - dtostrfd((float)RtcSettings.energy_usage.return2_kWhtotal / 100000, Settings.flag2.energy_resolution, export_active_chr[2]); // Tariff2 - energy_total_fields = 3; + dtostrfd((float)RtcSettings.energy_usage.usage1_kWhtotal / 100000, Settings.flag2.energy_resolution, energy_usage_chr[0]); // Tariff1 + dtostrfd((float)RtcSettings.energy_usage.usage2_kWhtotal / 100000, Settings.flag2.energy_resolution, energy_usage_chr[1]); // Tariff2 + dtostrfd((float)RtcSettings.energy_usage.return1_kWhtotal / 100000, Settings.flag2.energy_resolution, energy_return_chr[0]); // Tariff1 + dtostrfd((float)RtcSettings.energy_usage.return2_kWhtotal / 100000, Settings.flag2.energy_resolution, energy_return_chr[1]); // Tariff2 + energy_tariff = true; } char value_chr[FLOATSZ *3]; // Used by EnergyFormatIndex @@ -976,15 +999,26 @@ void EnergyShow(bool json) if (json) { bool show_energy_period = (0 == tele_period); - ResponseAppend_P(PSTR(",\"" D_RSLT_ENERGY "\":{\"" D_JSON_TOTAL_START_TIME "\":\"%s\",\"" D_JSON_TOTAL "\":%s,\"" D_JSON_YESTERDAY "\":%s,\"" D_JSON_TODAY "\":%s"), + ResponseAppend_P(PSTR(",\"" D_RSLT_ENERGY "\":{\"" D_JSON_TOTAL_START_TIME "\":\"%s\",\"" D_JSON_TOTAL "\":%s"), GetDateAndTime(DT_ENERGY).c_str(), - EnergyFormatIndex(value_chr, energy_total_chr[0], json, energy_total_fields), + energy_total_chr); + + if (energy_tariff) { + ResponseAppend_P(PSTR(",\"" D_JSON_TOTAL D_CMND_TARIFF "\":%s"), + EnergyFormatIndex(value_chr, energy_usage_chr[0], json, 2)); + } + + ResponseAppend_P(PSTR(",\"" D_JSON_YESTERDAY "\":%s,\"" D_JSON_TODAY "\":%s"), energy_yesterday_chr, energy_daily_chr); - if (!isnan(Energy.export_active)) { + if (!isnan(Energy.export_active[0])) { ResponseAppend_P(PSTR(",\"" D_JSON_EXPORT_ACTIVE "\":%s"), - EnergyFormatIndex(value_chr, export_active_chr[0], json, energy_total_fields)); + EnergyFormat(value_chr, export_active_chr[0], json)); + if (energy_tariff) { + ResponseAppend_P(PSTR(",\"" D_JSON_EXPORT D_CMND_TARIFF "\":%s"), + EnergyFormatIndex(value_chr, energy_return_chr[0], json, 2)); + } } if (show_energy_period) { @@ -1008,7 +1042,7 @@ void EnergyShow(bool json) } if (!isnan(Energy.frequency[0])) { ResponseAppend_P(PSTR(",\"" D_JSON_FREQUENCY "\":%s"), - EnergyFormat(value_chr, frequency_chr[0], json, Energy.voltage_common)); + EnergyFormat(value_chr, frequency_chr[0], json, Energy.frequency_common)); } } if (Energy.voltage_available) { @@ -1024,14 +1058,14 @@ void EnergyShow(bool json) #ifdef USE_DOMOTICZ if (show_energy_period) { // Only send if telemetry - dtostrfd(Energy.total * 1000, 1, energy_total_chr[0]); - DomoticzSensorPowerEnergy((int)Energy.active_power[0], energy_total_chr[0]); // PowerUsage, EnergyToday + dtostrfd(Energy.total * 1000, 1, energy_total_chr); + DomoticzSensorPowerEnergy((int)Energy.active_power[0], energy_total_chr); // PowerUsage, EnergyToday - dtostrfd((float)RtcSettings.energy_usage.usage1_kWhtotal / 100, 1, energy_total_chr[1]); // Tariff1 - dtostrfd((float)RtcSettings.energy_usage.usage2_kWhtotal / 100, 1, energy_total_chr[2]); // Tariff2 - dtostrfd((float)RtcSettings.energy_usage.return1_kWhtotal / 100, 1, export_active_chr[1]); - dtostrfd((float)RtcSettings.energy_usage.return2_kWhtotal / 100, 1, export_active_chr[2]); - DomoticzSensorP1SmartMeter(energy_total_chr[1], energy_total_chr[2], export_active_chr[1], export_active_chr[2], (int)Energy.active_power[0]); + dtostrfd((float)RtcSettings.energy_usage.usage1_kWhtotal / 100, 1, energy_usage_chr[0]); // Tariff1 + dtostrfd((float)RtcSettings.energy_usage.usage2_kWhtotal / 100, 1, energy_usage_chr[1]); // Tariff2 + dtostrfd((float)RtcSettings.energy_usage.return1_kWhtotal / 100, 1, energy_return_chr[0]); + dtostrfd((float)RtcSettings.energy_usage.return2_kWhtotal / 100, 1, energy_return_chr[1]); + DomoticzSensorP1SmartMeter(energy_usage_chr[0], energy_usage_chr[1], energy_return_chr[0], energy_return_chr[1], (int)Energy.active_power[0]); if (Energy.voltage_available) { DomoticzSensor(DZ_VOLTAGE, voltage_chr[0]); // Voltage @@ -1075,12 +1109,12 @@ void EnergyShow(bool json) } if (!isnan(Energy.frequency[0])) { WSContentSend_PD(PSTR("{s}" D_FREQUENCY "{m}%s " D_UNIT_HERTZ "{e}"), - EnergyFormat(value_chr, frequency_chr[0], json, Energy.voltage_common)); + EnergyFormat(value_chr, frequency_chr[0], json, Energy.frequency_common)); } } - WSContentSend_PD(HTTP_ENERGY_SNS2, energy_daily_chr, energy_yesterday_chr, energy_total_chr[0]); - if (!isnan(Energy.export_active)) { - WSContentSend_PD(HTTP_ENERGY_SNS3, export_active_chr[0]); + WSContentSend_PD(HTTP_ENERGY_SNS2, energy_daily_chr, energy_yesterday_chr, energy_total_chr); + if (!isnan(Energy.export_active[0])) { + WSContentSend_PD(HTTP_ENERGY_SNS3, EnergyFormat(value_chr, export_active_chr[0], json)); } XnrgCall(FUNC_WEB_SENSOR); @@ -1108,6 +1142,9 @@ bool Xdrv03(uint8_t function) case FUNC_EVERY_250_MSECOND: XnrgCall(FUNC_EVERY_250_MSECOND); break; + case FUNC_EVERY_SECOND: + XnrgCall(FUNC_EVERY_SECOND); + break; case FUNC_SERIAL: result = XnrgCall(FUNC_SERIAL); break; diff --git a/tasmota/xdrv_04_light.ino b/tasmota/xdrv_04_light.ino index 9b83a6879..86293c2b2 100644 --- a/tasmota/xdrv_04_light.ino +++ b/tasmota/xdrv_04_light.ino @@ -131,12 +131,26 @@ const uint8_t LIGHT_COLOR_SIZE = 25; // Char array scolor size const char kLightCommands[] PROGMEM = "|" // No prefix D_CMND_COLOR "|" D_CMND_COLORTEMPERATURE "|" D_CMND_DIMMER "|" D_CMND_DIMMER_RANGE "|" D_CMND_LEDTABLE "|" D_CMND_FADE "|" D_CMND_RGBWWTABLE "|" D_CMND_SCHEME "|" D_CMND_SPEED "|" D_CMND_WAKEUP "|" D_CMND_WAKEUPDURATION "|" - D_CMND_WHITE "|" D_CMND_CHANNEL "|" D_CMND_HSBCOLOR "|UNDOCA" ; + D_CMND_WHITE "|" D_CMND_CHANNEL "|" D_CMND_HSBCOLOR +#ifdef USE_LIGHT_PALETTE + "|" D_CMND_PALETTE +#endif // USE_LIGHT_PALETTE +#ifdef USE_DGR_LIGHT_SEQUENCE + "|" D_CMND_SEQUENCE_OFFSET +#endif // USE_DGR_LIGHT_SEQUENCE + "|UNDOCA" ; void (* const LightCommand[])(void) PROGMEM = { &CmndColor, &CmndColorTemperature, &CmndDimmer, &CmndDimmerRange, &CmndLedTable, &CmndFade, &CmndRgbwwTable, &CmndScheme, &CmndSpeed, &CmndWakeup, &CmndWakeupDuration, - &CmndWhite, &CmndChannel, &CmndHsbColor, &CmndUndocA }; + &CmndWhite, &CmndChannel, &CmndHsbColor, +#ifdef USE_LIGHT_PALETTE + &CmndPalette, +#endif // USE_LIGHT_PALETTE +#ifdef USE_DGR_LIGHT_SEQUENCE + &CmndSequenceOffset, +#endif // USE_DGR_LIGHT_SEQUENCE + &CmndUndocA }; // Light color mode, either RGB alone, or white-CT alone, or both only available if ct_rgb_linked is false enum LightColorModes { @@ -274,13 +288,25 @@ struct LIGHT { bool fade_initialized = false; // dont't fade at startup bool fade_running = false; #ifdef USE_DEVICE_GROUPS + uint8_t last_scheme = 0; bool devgrp_no_channels_out = false; // don't share channels with device group (e.g. if scheme set by other device) +#ifdef USE_DGR_LIGHT_SEQUENCE + uint8_t sequence_offset = 0; // number of channel changes this light is behind the master + uint8_t * channels_fifo; +#endif // USE_DGR_LIGHT_SEQUENCE #endif // USE_DEVICE_GROUPS +#ifdef USE_LIGHT_PALETTE + uint8_t palette_count = 0; // palette entry count + uint8_t * palette; // dynamically allocated palette color array +#endif // USE_LIGHT_PALETTE uint16_t fade_start_10[LST_MAX] = {0,0,0,0,0}; uint16_t fade_cur_10[LST_MAX]; uint16_t fade_end_10[LST_MAX]; // 10 bits resolution target channel values uint16_t fade_duration = 0; // duration of fade in milliseconds uint32_t fade_start = 0; // fade start time in milliseconds, compared to millis() + + uint16_t pwm_min = 0; // minimum value for PWM, from DimmerRange, 0..1023 + uint16_t pwm_max = 1023; // maxumum value for PWM, from DimmerRange, 0..1023 } Light; power_t LightPower(void) @@ -610,6 +636,7 @@ class LightStateClass { void setCW(uint8_t c, uint8_t w, bool free_range = false) { uint16_t max = (w > c) ? w : c; // 0..255 uint16_t sum = c + w; + if (sum <= 257) { free_range = false; } // if we don't allow free range or if sum is below 255 (with tolerance of 2) if (0 == max) { _briCT = 0; // brightness set to null @@ -623,7 +650,7 @@ class LightStateClass { _ww = changeUIntScale(w, 0, max, 0, 255); _wc = changeUIntScale(c, 0, max, 0, 255); } - _ct = changeUIntScale(w, 0, sum, _ct_min_range, _ct_max_range); + _ct = changeUIntScale(w, 0, sum, CT_MIN, CT_MAX); addCTMode(); // activate CT mode if needed if (_color_mode & LCM_CT) { _briCT = free_range ? max : (sum > 255 ? 255 : sum); } } @@ -705,6 +732,8 @@ class LightStateClass { AddLog_P2(LOG_LEVEL_DEBUG_MORE, "LightStateClass::setChannels (%d %d %d %d %d)", channels[0], channels[1], channels[2], channels[3], channels[4]); AddLog_P2(LOG_LEVEL_DEBUG_MORE, "LightStateClass::setChannels CT (%d) briRGB (%d) briCT (%d)", _ct, _briRGB, _briCT); + AddLog_P2(LOG_LEVEL_DEBUG_MORE, "LightStateClass::setChannels Actuals (%d %d %d %d %d)", + _r, _g, _b, _wc, _ww); #endif } @@ -807,28 +836,44 @@ void LightStateClass::HsToRgb(uint16_t hue, uint8_t sat, uint8_t *r_r, uint8_t * #define POW FastPrecisePowf +// +// Matrix 3x3 multiplied to a 3 vector, result in a 3 vector +// +void mat3x3(const float *mat33, const float *vec3, float *res3) { + for (uint32_t i = 0; i < 3; i++) { + const float * v = vec3; + *res3 = 0.0f; + for (uint32_t j = 0; j < 3; j++) { + *res3 += *mat33++ * *v++; + } + res3++; + } +} + void LightStateClass::RgbToXy(uint8_t i_r, uint8_t i_g, uint8_t i_b, float *r_x, float *r_y) { float x = 0.31271f; // default medium white float y = 0.32902f; if (i_r + i_b + i_g > 0) { - float r = (float)i_r / 255.0f; - float g = (float)i_g / 255.0f; - float b = (float)i_b / 255.0f; + float rgb[3] = { (float)i_r, (float)i_g, (float)i_b }; // https://gist.github.com/popcorn245/30afa0f98eea1c2fd34d // Gamma correction - r = (r > 0.04045f) ? POW((r + 0.055f) / (1.0f + 0.055f), 2.4f) : (r / 12.92f); - g = (g > 0.04045f) ? POW((g + 0.055f) / (1.0f + 0.055f), 2.4f) : (g / 12.92f); - b = (b > 0.04045f) ? POW((b + 0.055f) / (1.0f + 0.055f), 2.4f) : (b / 12.92f); + for (uint32_t i = 0; i < 3; i++) { + rgb[i] = rgb[i] / 255.0f; + rgb[i] = (rgb[i] > 0.04045f) ? POW((rgb[i] + 0.055f) / (1.0f + 0.055f), 2.4f) : (rgb[i] / 12.92f); + } // conversion to X, Y, Z // Y is also the Luminance - float X = r * 0.649926f + g * 0.103455f + b * 0.197109f; - float Y = r * 0.234327f + g * 0.743075f + b * 0.022598f; - float Z = r * 0.000000f + g * 0.053077f + b * 1.035763f; + float XYZ[3]; + static const float XYZ_factors[] = { 0.649926f, 0.103455f, 0.197109f, + 0.234327f, 0.743075f, 0.022598f, + 0.000000f, 0.053077f, 1.035763f }; + mat3x3(XYZ_factors, rgb, XYZ); - x = X / (X + Y + Z); - y = Y / (X + Y + Z); + float XYZ_sum = XYZ[0] + XYZ[1] + XYZ[2]; + x = XYZ[0] / XYZ_sum; + y = XYZ[1] / XYZ_sum; // we keep the raw gamut, one nice thing could be to convert to a narrower gamut } if (r_x) *r_x = x; @@ -837,36 +882,33 @@ void LightStateClass::RgbToXy(uint8_t i_r, uint8_t i_g, uint8_t i_b, float *r_x, void LightStateClass::XyToRgb(float x, float y, uint8_t *rr, uint8_t *rg, uint8_t *rb) { + float XYZ[3], rgb[3]; x = (x > 0.99f ? 0.99f : (x < 0.01f ? 0.01f : x)); y = (y > 0.99f ? 0.99f : (y < 0.01f ? 0.01f : y)); float z = 1.0f - x - y; - //float Y = 1.0f; - float X = x / y; - float Z = z / y; - // float r = X * 1.4628067f - 0.1840623f - Z * 0.2743606f; - // float g = -X * 0.5217933f + 1.4472381f + Z * 0.0677227f; - // float b = X * 0.0349342f - 0.0968930f + Z * 1.2884099f; - float r = X * 3.2406f - 1.5372f - Z * 0.4986f; - float g = -X * 0.9689f + 1.8758f + Z * 0.0415f; - float b = X * 0.0557f - 0.2040f + Z * 1.0570f; - float max = (r > g && r > b) ? r : (g > b) ? g : b; - r = r / max; // normalize to max == 1.0 - g = g / max; - b = b / max; - r = (r <= 0.0031308f) ? 12.92f * r : 1.055f * POW(r, (1.0f / 2.4f)) - 0.055f; - g = (g <= 0.0031308f) ? 12.92f * g : 1.055f * POW(g, (1.0f / 2.4f)) - 0.055f; - b = (b <= 0.0031308f) ? 12.92f * b : 1.055f * POW(b, (1.0f / 2.4f)) - 0.055f; - // - // AddLog_P2(LOG_LEVEL_DEBUG_MORE, "XyToRgb XZ (%s %s) rgb (%s %s %s)", - // String(X,5).c_str(), String(Z,5).c_str(), - // String(r,5).c_str(), String(g,5).c_str(),String(b,5).c_str()); + XYZ[0] = x / y; + XYZ[1] = 1.0f; + XYZ[2] = z / y; - int32_t ir = r * 255.0f + 0.5f; - int32_t ig = g * 255.0f + 0.5f; - int32_t ib = b * 255.0f + 0.5f; - if (rr) { *rr = (ir > 255 ? 255: (ir < 0 ? 0 : ir)); } - if (rg) { *rg = (ig > 255 ? 255: (ig < 0 ? 0 : ig)); } - if (rb) { *rb = (ib > 255 ? 255: (ib < 0 ? 0 : ib)); } + static const float rgb_factors[] = { 3.2406f, -1.5372f, -0.4986f, + -0.9689f, 1.8758f, 0.0415f, + 0.0557f, -0.2040f, 1.0570f }; + mat3x3(rgb_factors, XYZ, rgb); + float max = (rgb[0] > rgb[1] && rgb[0] > rgb[2]) ? rgb[0] : (rgb[1] > rgb[2]) ? rgb[1] : rgb[2]; + + for (uint32_t i = 0; i < 3; i++) { + rgb[i] = rgb[i] / max; // normalize to max == 1.0 + rgb[i] = (rgb[i] <= 0.0031308f) ? 12.92f * rgb[i] : 1.055f * POW(rgb[i], (1.0f / 2.4f)) - 0.055f; // gamma + } + + int32_t irgb[3]; + for (uint32_t i = 0; i < 3; i++) { + irgb[i] = rgb[i] * 255.0f + 0.5f; + } + + if (rr) { *rr = (irgb[0] > 255 ? 255: (irgb[0] < 0 ? 0 : irgb[0])); } + if (rg) { *rg = (irgb[1] > 255 ? 255: (irgb[1] < 0 ? 0 : irgb[1])); } + if (rb) { *rb = (irgb[2] > 255 ? 255: (irgb[2] < 0 ? 0 : irgb[2])); } } class LightControllerClass { @@ -950,17 +992,24 @@ public: // only if non-multi channel // We apply dimmer in priority to RGB uint8_t bri = _state->DimmerToBri(Settings.light_dimmer); - if (Settings.light_color[0] + Settings.light_color[1] + Settings.light_color[2] > 0) { - // The default values are #FFFFFFFFFF, in this case we avoid setting all channels - // at the same time, see #6534 - if ( (DEFAULT_LIGHT_COMPONENT == Settings.light_color[0]) && - (DEFAULT_LIGHT_COMPONENT == Settings.light_color[1]) && - (DEFAULT_LIGHT_COMPONENT == Settings.light_color[2]) && - (DEFAULT_LIGHT_COMPONENT == Settings.light_color[3]) && - (DEFAULT_LIGHT_COMPONENT == Settings.light_color[4]) && - (DEFAULT_LIGHT_DIMMER == Settings.light_dimmer) ) { - _state->setColorMode(LCM_RGB); + + // The default values are #FFFFFFFFFF, in this case we avoid setting all channels + // at the same time, see #6534 and #8120 + if ((DEFAULT_LIGHT_COMPONENT == Settings.light_color[0]) && + (DEFAULT_LIGHT_COMPONENT == Settings.light_color[1]) && + (DEFAULT_LIGHT_COMPONENT == Settings.light_color[2]) && + (DEFAULT_LIGHT_COMPONENT == Settings.light_color[3]) && + (DEFAULT_LIGHT_COMPONENT == Settings.light_color[4]) && + (DEFAULT_LIGHT_DIMMER == Settings.light_dimmer) ) { + if ((LST_COLDWARM == Light.subtype) || (LST_RGBCW == Light.subtype)) { + _state->setCW(255, 0); // avoid having both white channels at 100%, zero second channel (#see 8120) } + _state->setBriCT(bri); + _state->setBriRGB(bri); + _state->setColorMode(LCM_RGB); + } + + if (Settings.light_color[0] + Settings.light_color[1] + Settings.light_color[2] > 0) { _state->setBriRGB(bri); } else { _state->setBriCT(bri); @@ -1208,7 +1257,7 @@ bool LightModuleInit(void) if (Settings.flag.pwm_control) { // SetOption15 - Switch between commands PWM or COLOR/DIMMER/CT/CHANNEL for (uint32_t i = 0; i < MAX_PWMS; i++) { - if (pin[GPIO_PWM1 +i] < 99) { light_type++; } // Use Dimmer/Color control for all PWM as SetOption15 = 1 + if (PinUsed(GPIO_PWM1, i)) { light_type++; } // Use Dimmer/Color control for all PWM as SetOption15 = 1 } } @@ -1216,6 +1265,7 @@ bool LightModuleInit(void) if (XlgtCall(FUNC_MODULE_INIT)) { // serviced } +#ifdef ESP8266 else if (SONOFF_BN == my_module_type) { // PWM Single color led (White) light_type = LT_PWM1; } @@ -1234,6 +1284,7 @@ bool LightModuleInit(void) } light_type = LT_PWM2; } +#endif // ESP8266 if (light_type > LT_BASIC) { devices_present++; @@ -1252,6 +1303,25 @@ bool LightModuleInit(void) return (light_type > LT_BASIC); } +// compute actual PWM min/max values from DimmerRange +// must be called when DimmerRange is changed or LedTable +void LightCalcPWMRange(void) { + uint16_t pwm_min, pwm_max; + + pwm_min = change8to10(LightStateClass::DimmerToBri(Settings.dimmer_hw_min)); // default 0 + pwm_max = change8to10(LightStateClass::DimmerToBri(Settings.dimmer_hw_max)); // default 100 + if (Settings.light_correction) { + pwm_min = ledGamma10_10(pwm_min); // apply gamma correction + pwm_max = ledGamma10_10(pwm_max); // 0..1023 + } + pwm_min = pwm_min > 0 ? changeUIntScale(pwm_min, 1, 1023, 1, Settings.pwm_range) : 0; // adapt range but keep zero and non-zero values + pwm_max = changeUIntScale(pwm_max, 1, 1023, 1, Settings.pwm_range); // pwm_max cannot be zero + + Light.pwm_min = pwm_min; + Light.pwm_max = pwm_max; + //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("LightCalcPWMRange %d %d - %d %d"), Settings.dimmer_hw_min, Settings.dimmer_hw_max, Light.pwm_min, Light.pwm_max); +} + void LightInit(void) { Light.device = devices_present; @@ -1273,6 +1343,7 @@ void LightInit(void) // if RGBW or RGBCW, and SetOption37 >= 128, we manage RGB and W separately Light.device--; // we take the last two devices as lights } + LightCalcPWMRange(); #ifdef DEBUG_LIGHT AddLog_P2(LOG_LEVEL_DEBUG_MORE, "LightInit Light.pwm_multi_channels=%d Light.subtype=%d Light.device=%d devices_present=%d", Light.pwm_multi_channels, Light.subtype, Light.device, devices_present); @@ -1281,6 +1352,7 @@ void LightInit(void) light_controller.setSubType(Light.subtype); light_controller.loadSettings(); light_controller.setAlexaCTRange(Settings.flag4.alexa_ct_range); + light_controller.calcLevels(); // calculate the initial values (#8058) if (LST_SINGLE == Light.subtype) { Settings.light_color[0] = 255; // One channel only supports Dimmer but needs max color @@ -1288,14 +1360,14 @@ void LightInit(void) if (light_type < LT_PWM6) { // PWM for (uint32_t i = 0; i < light_type; i++) { Settings.pwm_value[i] = 0; // Disable direct PWM control - if (pin[GPIO_PWM1 +i] < 99) { - pinMode(pin[GPIO_PWM1 +i], OUTPUT); + if (PinUsed(GPIO_PWM1, i)) { + pinMode(Pin(GPIO_PWM1, i), OUTPUT); } } - if (pin[GPIO_ARIRFRCV] < 99) { - if (pin[GPIO_ARIRFSEL] < 99) { - pinMode(pin[GPIO_ARIRFSEL], OUTPUT); - digitalWrite(pin[GPIO_ARIRFSEL], 1); // Turn off RF + if (PinUsed(GPIO_ARIRFRCV)) { + if (PinUsed(GPIO_ARIRFSEL)) { + pinMode(Pin(GPIO_ARIRFSEL), OUTPUT); + digitalWrite(Pin(GPIO_ARIRFSEL), 1); // Turn off RF } } } @@ -1357,6 +1429,10 @@ void LightGetHSB(uint16_t *hue, uint8_t *sat, uint8_t *bri) { light_state.getHSB(hue, sat, bri); } +void LightGetXY(float *X, float *Y) { + light_state.getXY(X, Y); +} + void LightHsToRgb(uint16_t hue, uint8_t sat, uint8_t *r_r, uint8_t *r_g, uint8_t *r_b) { light_state.HsToRgb(hue, sat, r_r, r_g, r_b); } @@ -1402,12 +1478,39 @@ void LightSetBri(uint8_t device, uint8_t bri) { } } +void LightColorOffset(int32_t offset) { + uint16_t hue; + uint8_t sat; + light_state.getHSB(&hue, &sat, nullptr); // Allow user control over Saturation + hue += offset; + if (hue < 0) { hue += 359; } + if (hue > 359) { hue -= 359; } + if (!Light.pwm_multi_channels) { + light_state.setHS(hue, sat); + } else { + light_state.setHS(hue, 255); + light_state.setBri(255); // If multi-channel, force bri to max, it will be later dimmed to correct value + } + light_controller.calcLevels(Light.new_color); +} + +bool LightColorTempOffset(int32_t offset) { + int32_t ct = LightGetColorTemp(); + if (0 == ct) { return false; } // CT not supported + ct += offset; + if (ct < CT_MIN) { ct = CT_MIN; } + else if (ct > CT_MAX) { ct = CT_MAX; } + + LightSetColorTemp(ct); + return true; +} + void LightSetColorTemp(uint16_t ct) { /* Color Temperature (https://developers.meethue.com/documentation/core-concepts) * - * ct = 153 = 6500K = Cold = CCWW = FF00 - * ct = 600 = 2000K = Warm = CCWW = 00FF + * ct = 153 mirek = 6500K = Cold = CCWW = FF00 + * ct = 500 mirek = 2000K = Warm = CCWW = 00FF */ // don't set CT if not supported if ((LST_COLDWARM != Light.subtype) && (LST_RGBCW != Light.subtype)) { @@ -1435,9 +1538,6 @@ void LightSetSignal(uint16_t lo, uint16_t hi, uint16_t value) // AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "Light signal %d"), signal); light_controller.changeRGB(signal, 255 - signal, 0, true); // keep bri Settings.light_scheme = 0; -#ifdef USE_DEVICE_GROUPS - LightUpdateScheme(); -#endif // USE_DEVICE_GROUPS if (0 == light_state.getBri()) { light_controller.changeBri(50); } @@ -1447,7 +1547,9 @@ void LightSetSignal(uint16_t lo, uint16_t hi, uint16_t value) // convert channels to string, use Option 17 to foce decimal, unless force_hex char* LightGetColor(char* scolor, boolean force_hex = false) { - light_controller.calcLevels(); + if ((0 == Settings.light_scheme) || (!Light.pwm_multi_channels)) { + light_controller.calcLevels(); // recalculate levels only if Scheme 0, otherwise we mess up levels + } scolor[0] = '\0'; for (uint32_t i = 0; i < Light.subtype; i++) { if (!force_hex && Settings.flag.decimal_text) { // SetOption17 - Switch between decimal or hexadecimal output @@ -1480,10 +1582,10 @@ void LightState(uint8_t append) if (!Light.pwm_multi_channels) { if (unlinked) { // RGB and W are unlinked, we display the second Power/Dimmer - ResponseAppend_P(PSTR("\"" D_RSLT_POWER "%d\":\"%s\",\"" D_CMND_DIMMER "%d\":%d" - ",\"" D_RSLT_POWER "%d\":\"%s\",\"" D_CMND_DIMMER "%d\":%d"), - Light.device, GetStateText(Light.power & 1), Light.device, light_state.getDimmer(1), - Light.device + 1, GetStateText(Light.power & 2 ? 1 : 0), Light.device + 1, light_state.getDimmer(2)); + ResponseAppend_P(PSTR("\"" D_RSLT_POWER "%d\":\"%s\",\"" D_CMND_DIMMER "1\":%d" + ",\"" D_RSLT_POWER "%d\":\"%s\",\"" D_CMND_DIMMER "2\":%d"), + Light.device, GetStateText(Light.power & 1), light_state.getDimmer(1), + Light.device + 1, GetStateText(Light.power & 2 ? 1 : 0), light_state.getDimmer(2)); } else { GetPowerDevice(scommand, Light.device, sizeof(scommand), Settings.flag.device_index_enable); // SetOption26 - Switch between POWER or POWER1 ResponseAppend_P(PSTR("\"%s\":\"%s\",\"" D_CMND_DIMMER "\":%d"), scommand, GetStateText(Light.power & 1), @@ -1619,6 +1721,22 @@ void LightPreparePower(power_t channels = 0xFFFFFFFF) { // 1 = only RGB, 2 = LightState(0); } +#ifdef USE_LIGHT_PALETTE +void LightSetPaletteEntry(void) +{ + uint8_t bri = light_state.getBri(); + uint8_t * palette_entry = &Light.palette[Light.wheel * LST_MAX]; + for (int i = 0; i < LST_MAX; i++) { + Light.new_color[i] = changeUIntScale(palette_entry[i], 0, 255, 0, bri); + } + light_state.setChannelsRaw(Light.new_color); + if (!Light.pwm_multi_channels) { + light_state.setCW(Light.new_color[3], Light.new_color[4], true); + if (Light.new_color[0] || Light.new_color[1] || Light.new_color[2]) light_state.addRGBMode(); + } +} +#endif // USE_LIGHT_PALETTE + void LightCycleColor(int8_t direction) { // if (Light.strip_timer_counter % (Settings.light_speed * 2)) { return; } // Speed 1: 24sec, 2: 48sec, 3: 72sec, etc @@ -1626,6 +1744,25 @@ void LightCycleColor(int8_t direction) if (Light.strip_timer_counter % (Settings.light_speed - 2)) { return; } // Speed 4: 24sec, 5: 36sec, 6: 48sec, etc } +#ifdef USE_LIGHT_PALETTE + if (Light.palette_count) { + if (!Light.fade_running) { + if (0 == direction) { + Light.wheel = random(Light.palette_count); + } + else { + Light.wheel += direction; + if (Light.wheel >= Light.palette_count) { + Light.wheel = 0; + if (direction < 0) Light.wheel = Light.palette_count - 1; + } + } + LightSetPaletteEntry(); + } + return; + } +#endif // USE_LIGHT_PALETTE + if (0 == direction) { if (Light.random == Light.wheel) { Light.random = random(255); @@ -1648,9 +1785,14 @@ void LightCycleColor(int8_t direction) // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("LGT: random %d, wheel %d, hue %d"), Light.random, Light.wheel, hue); - uint8_t sat; - light_state.getHSB(nullptr, &sat, nullptr); // Allow user control over Saturation - light_state.setHS(hue, sat); + if (!Light.pwm_multi_channels) { + uint8_t sat; + light_state.getHSB(nullptr, &sat, nullptr); // Allow user control over Saturation + light_state.setHS(hue, sat); + } else { + light_state.setHS(hue, 255); + light_state.setBri(255); // If multi-channel, force bri to max, it will be later dimmed to correct value + } light_controller.calcLevels(Light.new_color); } @@ -1701,12 +1843,12 @@ void LightAnimate(void) // or set a maximum of PWM_MAX_SLEEP if light is on or Fade is running if (Light.power || Light.fade_running) { if (Settings.sleep > PWM_MAX_SLEEP) { - sleep = PWM_MAX_SLEEP; // set a maxumum value of 50 milliseconds to ensure that animations are smooth + ssleep = PWM_MAX_SLEEP; // set a maxumum value of 50 milliseconds to ensure that animations are smooth } else { - sleep = Settings.sleep; // or keep the current sleep if it's lower than 50 + ssleep = Settings.sleep; // or keep the current sleep if it's lower than 50 } } else { - sleep = Settings.sleep; + ssleep = Settings.sleep; } if (!Light.power) { // All channels powered off @@ -1751,24 +1893,36 @@ void LightAnimate(void) Light.wakeup_active = 0; Settings.light_scheme = LS_POWER; -#ifdef USE_DEVICE_GROUPS - LightUpdateScheme(); -#endif // USE_DEVICE_GROUPS } } break; case LS_CYCLEUP: - LightCycleColor(1); - break; case LS_CYCLEDN: - LightCycleColor(-1); - break; case LS_RANDOM: - LightCycleColor(0); + if (LS_CYCLEUP == Settings.light_scheme) { + LightCycleColor(1); + } else if (LS_CYCLEDN == Settings.light_scheme) { + LightCycleColor(-1); + } else { + LightCycleColor(0); + } + if (Light.pwm_multi_channels) { // See #8058 + Light.new_color[0] = changeUIntScale(Light.new_color[0], 0, 255, 0, Settings.light_color[0]); + Light.new_color[1] = changeUIntScale(Light.new_color[1], 0, 255, 0, Settings.light_color[1]); + Light.new_color[2] = changeUIntScale(Light.new_color[2], 0, 255, 0, Settings.light_color[2]); + } break; default: XlgtCall(FUNC_SET_SCHEME); } + +#ifdef USE_DEVICE_GROUPS + if (Settings.light_scheme != Light.last_scheme) { + Light.last_scheme = Settings.light_scheme; + SendLocalDeviceGroupMessage(DGR_MSGTYP_UPDATE, DGR_ITEM_LIGHT_SCHEME, Settings.light_scheme); + Light.devgrp_no_channels_out = false; + } +#endif // USE_DEVICE_GROUPS } if ((Settings.light_scheme < LS_MAX) || power_off) { // exclude WS281X Neopixel schemes @@ -1839,13 +1993,9 @@ void LightAnimate(void) } // final adjusments for PMW, post-gamma correction - uint16_t min = 1; -#ifdef USE_PWM_DIMMER - if (PWM_DIMMER == my_module_type) min = Settings.dimmer_hw_min; -#endif // USE_PWM_DIMMER for (uint32_t i = 0; i < LST_MAX; i++) { // scale from 0..1023 to 0..pwm_range, but keep any non-zero value to at least 1 - cur_col_10[i] = (cur_col_10[i] > 0) ? changeUIntScale(cur_col_10[i], 1, 1023, min, Settings.pwm_range) : 0; + cur_col_10[i] = (cur_col_10[i] > 0) ? changeUIntScale(cur_col_10[i], 1, 1023, 1, Settings.pwm_range) : 0; } // apply port remapping on both 8 bits and 10 bits versions @@ -1891,14 +2041,26 @@ void LightAnimate(void) bool isChannelGammaCorrected(uint32_t channel) { if (!Settings.light_correction) { return false; } // Gamma correction not activated if (channel >= Light.subtype) { return false; } // Out of range - - if (PHILIPS == my_module_type) { +#ifdef ESP8266 + if ((PHILIPS == my_module_type) || (Settings.flag4.pwm_ct_mode)) { if ((LST_COLDWARM == Light.subtype) && (1 == channel)) { return false; } // PMW reserved for CT if ((LST_RGBCW == Light.subtype) && (4 == channel)) { return false; } // PMW reserved for CT } +#endif // ESP8266 return true; } +// is the channel a regular PWM or ColorTemp control +bool isChannelCT(uint32_t channel) { +#ifdef ESP8266 + if ((PHILIPS == my_module_type) || (Settings.flag4.pwm_ct_mode)) { + if ((LST_COLDWARM == Light.subtype) && (1 == channel)) { return true; } // PMW reserved for CT + if ((LST_RGBCW == Light.subtype) && (4 == channel)) { return true; } // PMW reserved for CT + } +#endif // ESP8266 + return false; +} + // Calculate the Gamma correction, if any, for fading, using the fast Gamma curve (10 bits in+out) uint16_t fadeGamma(uint32_t channel, uint16_t v) { if (isChannelGammaCorrected(channel)) { @@ -2017,9 +2179,15 @@ void LightSetOutputs(const uint16_t *cur_col_10) { // now apply the actual PWM values, adjusted and remapped 10-bits range if (light_type < LT_PWM6) { // only for direct PWM lights, not for Tuya, Armtronix... for (uint32_t i = 0; i < (Light.subtype - Light.pwm_offset); i++) { - if (pin[GPIO_PWM1 +i] < 99) { + if (PinUsed(GPIO_PWM1, i)) { //AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION "Cur_Col%d 10 bits %d"), i, cur_col_10[i]); - analogWrite(pin[GPIO_PWM1 +i], bitRead(pwm_inverted, i) ? Settings.pwm_range - cur_col_10[(i + Light.pwm_offset)] : cur_col_10[(i + Light.pwm_offset)]); + uint16_t cur_col = cur_col_10[i + Light.pwm_offset]; + if (!isChannelCT(i)) { // if CT don't use pwm_min and pwm_max + cur_col = cur_col > 0 ? changeUIntScale(cur_col, 0, Settings.pwm_range, Light.pwm_min, Light.pwm_max) : 0; // shrink to the range of pwm_min..pwm_max + } + if (!Settings.flag4.zerocross_dimmer) { + analogWrite(Pin(GPIO_PWM1, i), bitRead(pwm_inverted, i) ? Settings.pwm_range - cur_col : cur_col); + } } } } @@ -2070,7 +2238,8 @@ void calcGammaBulbs(uint16_t cur_col_10[5]) { uint16_t white_bri10 = cur_col_10[cw0] + cur_col_10[cw1]; // cumulated brightness uint16_t white_bri10_1023 = (white_bri10 > 1023) ? 1023 : white_bri10; // max 1023 - if (PHILIPS == my_module_type) { // channel 1 is the color tone, mapped to cold channel (0..255) +#ifdef ESP8266 + if ((PHILIPS == my_module_type) || (Settings.flag4.pwm_ct_mode)) { // channel 1 is the color tone, mapped to cold channel (0..255) // Xiaomi Philips bulbs follow a different scheme: cur_col_10[cw1] = light_state.getCT10bits(); // channel 0=intensity, channel1=temperature @@ -2079,7 +2248,9 @@ void calcGammaBulbs(uint16_t cur_col_10[5]) { } else { cur_col_10[cw0] = white_bri10_1023; // no gamma, extend to 10 bits } - } else if (Settings.light_correction) { + } else +#endif // ESP8266 + if (Settings.light_correction) { // if sum of both channels is > 255, then channels are probably uncorrelated if (white_bri10 <= 1031) { // take a margin of 8 above 1023 to account for rounding errors // we calculate the gamma corrected sum of CW + WW @@ -2109,21 +2280,21 @@ void calcGammaBulbs(uint16_t cur_col_10[5]) { } #ifdef USE_DEVICE_GROUPS -void LightSendDeviceGroupStatus(bool force) +void LightSendDeviceGroupStatus(bool status) { - static uint8_t last_channels[LST_MAX]; static uint8_t last_bri; - uint8_t bri = light_state.getBri(); - bool send_bri_update = (force || bri != last_bri); - + bool send_bri_update = (status || bri != last_bri); if (Light.subtype > LST_SINGLE && !Light.devgrp_no_channels_out) { - uint8_t channels[LST_MAX]; - light_state.getChannels(channels); - if (force || memcmp(last_channels, channels, LST_MAX)) { - memcpy(last_channels, channels, LST_MAX); - SendLocalDeviceGroupMessage((send_bri_update ? DGR_MSGTYP_PARTIAL_UPDATE : DGR_MSGTYP_UPDATE), DGR_ITEM_LIGHT_CHANNELS, channels); + static uint8_t channels[LST_MAX + 1] = { 0, 0, 0, 0, 0, 0 }; + if (status) { + light_state.getChannels(channels); } + else { + memcpy(channels, Light.new_color, LST_MAX); + channels[LST_MAX]++; + } + SendLocalDeviceGroupMessage((send_bri_update ? DGR_MSGTYP_PARTIAL_UPDATE : DGR_MSGTYP_UPDATE), DGR_ITEM_LIGHT_CHANNELS, channels); } if (send_bri_update) { last_bri = bri; @@ -2166,17 +2337,49 @@ void LightHandleDevGroupItem(void) break; case DGR_ITEM_LIGHT_SCHEME: if (Settings.light_scheme != value) { - Settings.light_scheme = value; + Light.last_scheme = Settings.light_scheme = value; Light.devgrp_no_channels_out = (value != 0); send_state = true; } break; case DGR_ITEM_LIGHT_CHANNELS: - light_controller.changeChannels((uint8_t *)XdrvMailbox.data); +#ifdef USE_DGR_LIGHT_SEQUENCE + { + static uint8_t last_sequence = 0; + + // If a sequence offset is set, set the channels to the ones we received + // changes ago. + if (Light.sequence_offset) { + light_controller.changeChannels(Light.channels_fifo); + + // Shift the fifo down and load the newly received channels at the end for this update and + // any updates we missed. + int last_entry = (Light.sequence_offset - 1) * LST_MAX; + for (uint8_t sequence = (uint8_t)XdrvMailbox.data[LST_MAX]; (uint8_t)(sequence - last_sequence) > 0; last_sequence++) { + memmove(Light.channels_fifo, &Light.channels_fifo[LST_MAX], last_entry); + memcpy(&Light.channels_fifo[last_entry], XdrvMailbox.data, LST_MAX); + } + } + else { +#endif // USE_DGR_LIGHT_SEQUENCE + light_controller.changeChannels((uint8_t *)XdrvMailbox.data); +#ifdef USE_DGR_LIGHT_SEQUENCE + } + } +#endif // USE_DGR_LIGHT_SEQUENCE send_state = true; break; case DGR_ITEM_LIGHT_FIXED_COLOR: if (Light.subtype >= LST_RGBW) { + send_state = true; +#ifdef USE_LIGHT_PALETTE + if (Light.palette_count) { + Light.wheel = value % Light.palette_count; + LightSetPaletteEntry(); + break; + } +#endif // !USE_LIGHT_PALETTE + value = value % MAX_FIXED_COLOR; if (value) { bool save_decimal_text = Settings.flag.decimal_text; char str[16]; @@ -2196,7 +2399,6 @@ void LightHandleDevGroupItem(void) Light.power = 0xff; restore_power = true; } - send_state = true; } break; case DGR_ITEM_LIGHT_FADE: @@ -2218,17 +2420,6 @@ void LightHandleDevGroupItem(void) break; } } - -void LightUpdateScheme(void) -{ - static uint8_t last_scheme; - - if (Settings.light_scheme != last_scheme) { - last_scheme = Settings.light_scheme; - SendLocalDeviceGroupMessage(DGR_MSGTYP_UPDATE, DGR_ITEM_LIGHT_SCHEME, Settings.light_scheme); - } - Light.devgrp_no_channels_out = false; -} #endif // USE_DEVICE_GROUPS /*********************************************************************************************\ @@ -2242,6 +2433,9 @@ bool LightColorEntry(char *buffer, uint32_t buffer_length) char *str; uint32_t entry_type = 0; // Invalid uint8_t value = Light.fixed_color_index; +#ifdef USE_LIGHT_PALETTE + if (Light.palette_count) value = Light.wheel; +#endif // USE_LIGHT_PALETTE if (buffer[0] == '#') { // Optional hexadecimal entry buffer++; @@ -2250,14 +2444,29 @@ bool LightColorEntry(char *buffer, uint32_t buffer_length) if (Light.subtype >= LST_RGB) { char option = (1 == buffer_length) ? buffer[0] : '\0'; - if (('+' == option) && (Light.fixed_color_index < MAX_FIXED_COLOR)) { - value++; + if ('+' == option) { +#ifdef USE_LIGHT_PALETTE + if (Light.palette_count || Light.fixed_color_index < MAX_FIXED_COLOR) { +#else // USE_LIGHT_PALETTE + if (Light.fixed_color_index < MAX_FIXED_COLOR) { +#endif // !USE_LIGHT_PALETTE + value++; + } } - else if (('-' == option) && (Light.fixed_color_index > 1)) { - value--; + else if ('-' == option) { +#ifdef USE_LIGHT_PALETTE + if (Light.palette_count || Light.fixed_color_index > 1) { +#else // USE_LIGHT_PALETTE + if (Light.fixed_color_index > 1) { +#endif // !USE_LIGHT_PALETTE + value--; + } } else { value = atoi(buffer); } +#ifdef USE_LIGHT_PALETTE + if (Light.palette_count) value = value % Light.palette_count; +#endif // USE_LIGHT_PALETTE } memset(&Light.entry_color, 0x00, sizeof(Light.entry_color)); @@ -2282,6 +2491,14 @@ bool LightColorEntry(char *buffer, uint32_t buffer_length) } entry_type = 1; // Hexadecimal } +#ifdef USE_LIGHT_PALETTE + else if (Light.palette_count) { + value--; + Light.wheel = value; + memcpy_P(&Light.entry_color, &Light.palette[value * LST_MAX], LST_MAX); + entry_type = 1; // Hexadecimal + } +#endif // USE_LIGHT_PALETTE else if ((Light.subtype >= LST_RGB) && (value > 0) && (value <= MAX_FIXED_COLOR)) { Light.fixed_color_index = value; memcpy_P(&Light.entry_color, &kFixedColor[value -1], 3); @@ -2318,18 +2535,23 @@ void CmndSupportColor(void) valid_entry = LightColorEntry(XdrvMailbox.data, XdrvMailbox.data_len); if (valid_entry) { if (XdrvMailbox.index <= 2) { // Color(1), 2 - uint32_t old_bri = light_state.getBri(); - // change all channels to specified values - light_controller.changeChannels(Light.entry_color); - if (2 == XdrvMailbox.index) { - // If Color2, set back old brightness - light_controller.changeBri(old_bri); +#ifdef USE_LIGHT_PALETTE + if (Light.palette_count && XdrvMailbox.index == 2) { + LightSetPaletteEntry(); } - + else { +#endif // USE_LIGHT_PALETTE + uint32_t old_bri = light_state.getBri(); + // change all channels to specified values + light_controller.changeChannels(Light.entry_color); + if (2 == XdrvMailbox.index) { + // If Color2, set back old brightness + light_controller.changeBri(old_bri); + } +#ifdef USE_LIGHT_PALETTE + } +#endif // USE_LIGHT_PALETTE Settings.light_scheme = 0; -#ifdef USE_DEVICE_GROUPS - LightUpdateScheme(); -#endif // USE_DEVICE_GROUPS coldim = true; } else { // Color3, 4, 5 and 6 for (uint32_t i = 0; i < LST_RGB; i++) { @@ -2494,11 +2716,11 @@ void CmndScheme(void) uint32_t parm[2]; if (ParseParameters(2, parm) > 1) { Light.wheel = parm[1]; +#ifdef USE_LIGHT_PALETTE + Light.wheel--; +#endif // USE_LIGHT_PALETTE } Settings.light_scheme = XdrvMailbox.payload; -#ifdef USE_DEVICE_GROUPS - LightUpdateScheme(); -#endif // USE_DEVICE_GROUPS if (LS_WAKEUP == Settings.light_scheme) { Light.wakeup_active = 3; } @@ -2522,9 +2744,6 @@ void CmndWakeup(void) } Light.wakeup_active = 3; Settings.light_scheme = LS_WAKEUP; -#ifdef USE_DEVICE_GROUPS - LightUpdateScheme(); -#endif // USE_DEVICE_GROUPS LightPowerOn(); ResponseCmndChar(D_JSON_STARTED); } @@ -2555,6 +2774,16 @@ void CmndColorTemperature(void) } } +void LightDimmerOffset(int32_t offset) { + int32_t dimmer = light_state.getDimmer() + offset; + if (dimmer < 1) { dimmer = 1; } + if (dimmer > 100) { dimmer = 100; } + + XdrvMailbox.index = 0; + XdrvMailbox.payload = dimmer; + CmndDimmer(); +} + void CmndDimmer(void) { // Dimmer - Show current Dimmer state @@ -2604,8 +2833,11 @@ void CmndDimmer(void) } } #if defined(USE_PWM_DIMMER) && defined(USE_DEVICE_GROUPS) - Settings.bri_power_on = light_state.getBri();; - SendLocalDeviceGroupMessage(DGR_MSGTYP_UPDATE, DGR_ITEM_BRI_POWER_ON, Settings.bri_power_on); + uint8_t bri = light_state.getBri(); + if (bri != Settings.bri_power_on) { + Settings.bri_power_on = bri; + SendLocalDeviceGroupMessage(DGR_MSGTYP_PARTIAL_UPDATE, DGR_ITEM_BRI_POWER_ON, Settings.bri_power_on); + } #endif // USE_PWM_DIMMER && USE_DEVICE_GROUPS Light.update = true; if (skip_light_fade) LightAnimate(); @@ -2631,7 +2863,8 @@ void CmndDimmerRange(void) Settings.dimmer_hw_min = parm[1]; Settings.dimmer_hw_max = parm[0]; } - if (PWM_DIMMER != my_module_type) restart_flag = 2; + LightCalcPWMRange(); + Light.update = true; } Response_P(PSTR("{\"" D_CMND_DIMMER_RANGE "\":{\"Min\":%d,\"Max\":%d}}"), Settings.dimmer_hw_min, Settings.dimmer_hw_max); } @@ -2652,6 +2885,7 @@ void CmndLedTable(void) Settings.light_correction ^= 1; break; } + LightCalcPWMRange(); Light.update = true; } ResponseCmndStateText(Settings.light_correction); @@ -2735,6 +2969,84 @@ void CmndWakeupDuration(void) ResponseCmndNumber(Settings.light_wakeup); } +#ifdef USE_LIGHT_PALETTE +void CmndPalette(void) +{ + uint8_t * palette_entry; + char * p; + + // Palette Color[ ...] + if (XdrvMailbox.data_len) { + Light.wheel = 0; + Light.palette_count = 0; + if (Light.palette) { + free(Light.palette); + Light.palette = nullptr; + } + if (XdrvMailbox.data_len > 1 || XdrvMailbox.data[0] != '0') { + uint8_t palette_count = 0; + char * color = XdrvMailbox.data; + if (!(Light.palette = (uint8_t *)malloc(255 * Light.subtype))) return; + palette_entry = Light.palette; + for (;;) { + p = strchr(color, ' '); + if (p) *p = 0; + color = Trim(color); + if (*color && LightColorEntry(color, strlen(color))) { + memcpy(palette_entry, Light.entry_color, Light.subtype); + palette_entry += Light.subtype; + palette_count++; + } + if (!p) break; + color = p + 1; + } + if (!(Light.palette = (uint8_t *)realloc(Light.palette, palette_count * Light.subtype))) return; + Light.palette_count = palette_count; + } + } + + char palette_str[5 * Light.subtype * Light.palette_count + 3]; + p = palette_str; + *p++ = '['; + if (Light.palette_count) { + palette_entry = Light.palette; + for (int entry = 0; entry < Light.palette_count; entry++) { + if (Settings.flag.decimal_text) { // SetOption17 - Switch between decimal or hexadecimal output + *p++ = '"'; + for (uint32_t i = 0; i < Light.subtype; i++) { + p += sprintf_P(p, PSTR("%d,"), *palette_entry++); + } + *(p - 1) = '"'; + } + else { + for (uint32_t i = 0; i < Light.subtype; i++) { + p += sprintf_P(p, PSTR("%02X"), *palette_entry++); + } + } + *p++ = ','; + } + p--; + } + *p++ = ']'; + *p = 0; + ResponseCmndChar(palette_str); +} +#endif // USE_LIGHT_PALETTE + +#ifdef USE_DGR_LIGHT_SEQUENCE +void CmndSequenceOffset(void) +{ + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 255)) { + if (XdrvMailbox.payload != Light.sequence_offset) { + if (Light.sequence_offset) free(Light.channels_fifo); + Light.sequence_offset = XdrvMailbox.payload; + if (Light.sequence_offset) Light.channels_fifo = (uint8_t *)calloc(Light.sequence_offset, LST_MAX); + } + } + ResponseCmndNumber(Light.sequence_offset); +} +#endif // USE_DGR_LIGHT_SEQUENCE + void CmndUndocA(void) { // Theos legacy status diff --git a/tasmota/xdrv_05_irremote.ino b/tasmota/xdrv_05_irremote.ino index 53197b693..87a51de53 100644 --- a/tasmota/xdrv_05_irremote.ino +++ b/tasmota/xdrv_05_irremote.ino @@ -49,7 +49,7 @@ bool irsend_active = false; void IrSendInit(void) { - irsend = new IRsend(pin[GPIO_IRSEND]); // an IR led is at GPIO_IRSEND + irsend = new IRsend(Pin(GPIO_IRSEND)); // an IR led is at GPIO_IRSEND irsend->begin(); } @@ -78,7 +78,7 @@ void IrReceiveUpdateThreshold(void) void IrReceiveInit(void) { // an IR led is at GPIO_IRRECV - irrecv = new IRrecv(pin[GPIO_IRRECV], IR_RCV_BUFFER_SIZE, IR_RCV_TIMEOUT, IR_RCV_SAVE_BUFFER); + irrecv = new IRrecv(Pin(GPIO_IRRECV), IR_RCV_BUFFER_SIZE, IR_RCV_TIMEOUT, IR_RCV_SAVE_BUFFER); irrecv->setUnknownThreshold(Settings.param[P_IR_UNKNOW_THRESHOLD]); irrecv->enableIRIn(); // Start the receiver @@ -279,28 +279,28 @@ bool Xdrv05(uint8_t function) { bool result = false; - if ((pin[GPIO_IRSEND] < 99) || (pin[GPIO_IRRECV] < 99)) { + if (PinUsed(GPIO_IRSEND) || PinUsed(GPIO_IRRECV)) { switch (function) { case FUNC_PRE_INIT: - if (pin[GPIO_IRSEND] < 99) { + if (PinUsed(GPIO_IRSEND)) { IrSendInit(); } #ifdef USE_IR_RECEIVE - if (pin[GPIO_IRRECV] < 99) { + if (PinUsed(GPIO_IRRECV)) { IrReceiveInit(); } #endif // USE_IR_RECEIVE break; case FUNC_EVERY_50_MSECOND: #ifdef USE_IR_RECEIVE - if (pin[GPIO_IRRECV] < 99) { + if (PinUsed(GPIO_IRRECV)) { IrReceiveCheck(); // check if there's anything on IR side } #endif // USE_IR_RECEIVE irsend_active = false; // re-enable IR reception break; case FUNC_COMMAND: - if (pin[GPIO_IRSEND] < 99) { + if (PinUsed(GPIO_IRSEND)) { result = DecodeCommand(kIrRemoteCommands, IrRemoteCommand); } break; diff --git a/tasmota/xdrv_05_irremote_full.ino b/tasmota/xdrv_05_irremote_full.ino index 7d9987ae5..457ff63f4 100644 --- a/tasmota/xdrv_05_irremote_full.ino +++ b/tasmota/xdrv_05_irremote_full.ino @@ -48,7 +48,7 @@ bool irsend_active = false; void IrSendInit(void) { - irsend = new IRsend(pin[GPIO_IRSEND]); // an IR led is at GPIO_IRSEND + irsend = new IRsend(Pin(GPIO_IRSEND)); // an IR led is at GPIO_IRSEND irsend->begin(); } @@ -105,7 +105,7 @@ void IrReceiveUpdateThreshold(void) void IrReceiveInit(void) { // an IR led is at GPIO_IRRECV - irrecv = new IRrecv(pin[GPIO_IRRECV], IR_FULL_BUFFER_SIZE, IR__FULL_RCV_TIMEOUT, IR_FULL_RCV_SAVE_BUFFER); + irrecv = new IRrecv(Pin(GPIO_IRRECV), IR_FULL_BUFFER_SIZE, IR__FULL_RCV_TIMEOUT, IR_FULL_RCV_SAVE_BUFFER); irrecv->setUnknownThreshold(Settings.param[P_IR_UNKNOW_THRESHOLD]); irrecv->enableIRIn(); // Start the receiver } @@ -365,7 +365,7 @@ uint32_t IrRemoteCmndIrHvacJson(void) if (json[parm_uc]) { state.sleep = json[parm_uc]; } //if (json[D_JSON_IRHVAC_CLOCK]) { state.clock = json[D_JSON_IRHVAC_CLOCK]; } // not sure it's useful to support 'clock' - IRac ac(pin[GPIO_IRSEND]); + IRac ac(Pin(GPIO_IRSEND)); bool success = ac.sendAc(state, &prev); if (!success) { return IE_SYNTAX_IRHVAC; } @@ -470,6 +470,21 @@ uint32_t IrRemoteCmndIrSendRaw(void) return IE_INVALID_RAWDATA; } // Parameters must be at least 3 + if (strcasecmp(str, "gc") == 0) { //if first parameter is gc then we process global cache data else it is raw + uint16_t GC[count+1]; + for (uint32_t i = 0; i <= count; i++) { + GC[i] = strtol(strtok_r(nullptr, ", ", &p), nullptr, 0); + if (!GC[i]) { + return IE_INVALID_RAWDATA; + } + } + irsend_active = true; + for (uint32_t r = 0; r <= repeat; r++) { + irsend->sendGC(GC, count+1); + } + return IE_NO_ERROR; + } + uint16_t parm[count]; for (uint32_t i = 0; i < count; i++) { parm[i] = strtol(strtok_r(nullptr, ", ", &p), nullptr, 0); @@ -635,24 +650,24 @@ bool Xdrv05(uint8_t function) { bool result = false; - if ((pin[GPIO_IRSEND] < 99) || (pin[GPIO_IRRECV] < 99)) { + if (PinUsed(GPIO_IRSEND) || PinUsed(GPIO_IRRECV)) { switch (function) { case FUNC_PRE_INIT: - if (pin[GPIO_IRSEND] < 99) { + if (PinUsed(GPIO_IRSEND)) { IrSendInit(); } - if (pin[GPIO_IRRECV] < 99) { + if (PinUsed(GPIO_IRRECV)) { IrReceiveInit(); } break; case FUNC_EVERY_50_MSECOND: - if (pin[GPIO_IRRECV] < 99) { + if (PinUsed(GPIO_IRRECV)) { IrReceiveCheck(); // check if there's anything on IR side } irsend_active = false; // re-enable IR reception break; case FUNC_COMMAND: - if (pin[GPIO_IRSEND] < 99) { + if (PinUsed(GPIO_IRSEND)) { result = DecodeCommand(kIrRemoteCommands, IrRemoteCommand); } break; diff --git a/tasmota/xdrv_06_snfbridge.ino b/tasmota/xdrv_06_snfbridge.ino index c8e9db67e..210ff87a3 100644 --- a/tasmota/xdrv_06_snfbridge.ino +++ b/tasmota/xdrv_06_snfbridge.ino @@ -481,11 +481,11 @@ void CmndRfKey(void) SnfBridge.learn_active = 0; if (2 == XdrvMailbox.payload) { // Learn RF data SonoffBridgeLearn(XdrvMailbox.index); - ResponseCmndIdxChar(D_JSON_START_LEARNING); + ResponseCmndIdxChar(PSTR(D_JSON_START_LEARNING)); } else if (3 == XdrvMailbox.payload) { // Unlearn RF data Settings.rf_code[XdrvMailbox.index][0] = 0; // Reset sync_time MSB - ResponseCmndIdxChar(D_JSON_SET_TO_DEFAULT); + ResponseCmndIdxChar(PSTR(D_JSON_SET_TO_DEFAULT)); } else if (4 == XdrvMailbox.payload) { // Save RF data provided by RFSync, RfLow, RfHigh and last RfCode for (uint32_t i = 0; i < 6; i++) { @@ -494,7 +494,7 @@ void CmndRfKey(void) Settings.rf_code[XdrvMailbox.index][6] = (SnfBridge.last_send_code >> 16) & 0xff; Settings.rf_code[XdrvMailbox.index][7] = (SnfBridge.last_send_code >> 8) & 0xff; Settings.rf_code[XdrvMailbox.index][8] = SnfBridge.last_send_code & 0xff; - ResponseCmndIdxChar(D_JSON_SAVED); + ResponseCmndIdxChar(PSTR(D_JSON_SAVED)); } else if (5 == XdrvMailbox.payload) { // Show default or learned RF data uint8_t key = XdrvMailbox.index; uint8_t index = (0 == Settings.rf_code[key][0]) ? 0 : key; // Use default if sync_time MSB = 0 @@ -513,10 +513,10 @@ void CmndRfKey(void) } else { if ((1 == XdrvMailbox.payload) || (0 == Settings.rf_code[XdrvMailbox.index][0])) { // Test sync_time MSB SonoffBridgeSend(0, XdrvMailbox.index); // Send default RF data - ResponseCmndIdxChar(D_JSON_DEFAULT_SENT); + ResponseCmndIdxChar(PSTR(D_JSON_DEFAULT_SENT)); } else { SonoffBridgeSend(XdrvMailbox.index, 0); // Send learned RF data - ResponseCmndIdxChar(D_JSON_LEARNED_SENT); + ResponseCmndIdxChar(PSTR(D_JSON_LEARNED_SENT)); } } } else { @@ -565,6 +565,7 @@ bool Xdrv06(uint8_t function) { bool result = false; +#ifdef ESP8266 if (SONOFF_BRIDGE == my_module_type) { switch (function) { case FUNC_SERIAL: @@ -582,6 +583,7 @@ bool Xdrv06(uint8_t function) break; } } +#endif // ESP8266 return result; } diff --git a/tasmota/xdrv_07_domoticz.ino b/tasmota/xdrv_07_domoticz.ino index 1fddf5890..556997bb9 100644 --- a/tasmota/xdrv_07_domoticz.ino +++ b/tasmota/xdrv_07_domoticz.ino @@ -110,7 +110,8 @@ void DomoticzUpdateFanState(void) void MqttPublishDomoticzPowerState(uint8_t device) { if (Settings.flag.mqtt_enabled) { // SetOption3 - Enable MQTT - if ((device < 1) || (device > devices_present)) { device = 1; } + if (device < 1) { device = 1; } + if ((device > devices_present) || (device > MAX_DOMOTICZ_IDX)) { return; } if (Settings.domoticz_relay_idx[device -1]) { #ifdef USE_SHUTTER if (domoticz_is_shutter) { @@ -559,7 +560,7 @@ void HandleDomoticzConfiguration(void) AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_DOMOTICZ); - if (WebServer->hasArg("save")) { + if (Webserver->hasArg("save")) { DomoticzSaveSettings(); WebRestart(1); return; @@ -576,7 +577,7 @@ void HandleDomoticzConfiguration(void) i +1, i, Settings.domoticz_relay_idx[i], i +1, i, Settings.domoticz_key_idx[i]); } - if (pin[GPIO_SWT1 +i] < 99) { + if (PinUsed(GPIO_SWT1, i)) { WSContentSend_P(HTTP_FORM_DOMOTICZ_SWITCH, i +1, i, Settings.domoticz_switch_idx[i]); } @@ -651,7 +652,7 @@ bool Xdrv07(uint8_t function) WSContentSend_P(HTTP_BTN_MENU_DOMOTICZ); break; case FUNC_WEB_ADD_HANDLER: - WebServer->on("/" WEB_HANDLE_DOMOTICZ, HandleDomoticzConfiguration); + Webserver->on("/" WEB_HANDLE_DOMOTICZ, HandleDomoticzConfiguration); break; #endif // USE_WEBSERVER case FUNC_MQTT_SUBSCRIBE: diff --git a/tasmota/xdrv_08_serial_bridge.ino b/tasmota/xdrv_08_serial_bridge.ino index 990bf9c32..0dec9cb6b 100644 --- a/tasmota/xdrv_08_serial_bridge.ino +++ b/tasmota/xdrv_08_serial_bridge.ino @@ -54,28 +54,45 @@ void SerialBridgeInput(void) return; } if (serial_in_byte || serial_bridge_raw) { // Any char between 1 and 127 or any char (0 - 255) + bool in_byte_is_delimiter = // Char is delimiter when... + (((Settings.serial_delimiter < 128) && (serial_in_byte == Settings.serial_delimiter)) || // Any char between 1 and 127 and being delimiter + ((Settings.serial_delimiter == 128) && !isprint(serial_in_byte))) && // Any char not between 32 and 127 + !serial_bridge_raw; // In raw mode (CMND_SERIALSEND3) there is never a delimiter if ((serial_bridge_in_byte_counter < SERIAL_BRIDGE_BUFFER_SIZE -1) && // Add char to string if it still fits and ... - ((isprint(serial_in_byte) && (128 == Settings.serial_delimiter)) || // Any char between 32 and 127 - ((serial_in_byte != Settings.serial_delimiter) && (128 != Settings.serial_delimiter)) || // Any char between 1 and 127 and not being delimiter - serial_bridge_raw)) { // Any char between 0 and 255 + !in_byte_is_delimiter) { // Char is not a delimiter serial_bridge_buffer[serial_bridge_in_byte_counter++] = serial_in_byte; - serial_bridge_polling_window = millis(); // Wait for more data - } else { + } + + if ((serial_bridge_in_byte_counter >= SERIAL_BRIDGE_BUFFER_SIZE -1) || // Send message when buffer is full or ... + in_byte_is_delimiter) { // Char is delimiter serial_bridge_polling_window = 0; // Publish now break; } + + serial_bridge_polling_window = millis(); // Wait for more data } } if (serial_bridge_in_byte_counter && (millis() > (serial_bridge_polling_window + SERIAL_POLLING))) { serial_bridge_buffer[serial_bridge_in_byte_counter] = 0; // Serial data completed - char hex_char[(serial_bridge_in_byte_counter * 2) + 2]; bool assume_json = (!serial_bridge_raw && (serial_bridge_buffer[0] == '{')); - Response_P(PSTR("{\"" D_JSON_SSERIALRECEIVED "\":%s%s%s}"), - (assume_json) ? "" : "\"", - (serial_bridge_raw) ? ToHex_P((unsigned char*)serial_bridge_buffer, serial_bridge_in_byte_counter, hex_char, sizeof(hex_char)) : serial_bridge_buffer, - (assume_json) ? "" : "\""); + + Response_P(PSTR("{\"" D_JSON_SSERIALRECEIVED "\":")); + if (assume_json) { + ResponseAppend_P(serial_bridge_buffer); + } else { + ResponseAppend_P(PSTR("\"")); + if (serial_bridge_raw) { + char hex_char[(serial_bridge_in_byte_counter * 2) + 2]; + ResponseAppend_P(ToHex_P((unsigned char*)serial_bridge_buffer, serial_bridge_in_byte_counter, hex_char, sizeof(hex_char))); + } else { + ResponseAppend_P(EscapeJSONString(serial_bridge_buffer).c_str()); + } + ResponseAppend_P(PSTR("\"")); + } + ResponseJsonEnd(); + MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_SSERIALRECEIVED)); XdrvRulesProcess(); serial_bridge_in_byte_counter = 0; @@ -87,8 +104,8 @@ void SerialBridgeInput(void) void SerialBridgeInit(void) { serial_bridge_active = false; - if ((pin[GPIO_SBR_RX] < 99) && (pin[GPIO_SBR_TX] < 99)) { - SerialBridgeSerial = new TasmotaSerial(pin[GPIO_SBR_RX], pin[GPIO_SBR_TX]); + if (PinUsed(GPIO_SBR_RX) && PinUsed(GPIO_SBR_TX)) { + SerialBridgeSerial = new TasmotaSerial(Pin(GPIO_SBR_RX), Pin(GPIO_SBR_TX)); if (SerialBridgeSerial->begin(Settings.sbaudrate * 300)) { // Baud rate is stored div 300 so it fits into 16 bits if (SerialBridgeSerial->hardwareSerial()) { ClaimSerial(); diff --git a/tasmota/xdrv_09_timers.ino b/tasmota/xdrv_09_timers.ino index f751d853f..1ecfb0b67 100644 --- a/tasmota/xdrv_09_timers.ino +++ b/tasmota/xdrv_09_timers.ino @@ -68,61 +68,61 @@ const float pi2 = TWO_PI; const float pi = PI; const float RAD = DEG_TO_RAD; -float JulianischesDatum(void) -{ - // Gregorianischer Kalender - int Gregor; - int Jahr = RtcTime.year; - int Monat = RtcTime.month; - int Tag = RtcTime.day_of_month; +// Compute the Julian date from the Calendar date, using only unsigned ints for code compactness +// Warning this formula works only from 2000 to 2099, after 2100 we get 1 day off per century. If ever Tasmota survives until then. +uint32_t JulianDate(const struct TIME_T &now) { + // https://en.wikipedia.org/wiki/Julian_day - if (Monat <= 2) { - Monat += 12; - Jahr -= 1; + uint32_t Year = now.year; // Year ex:2020 + uint32_t Month = now.month; // 1..12 + uint32_t Day = now.day_of_month; // 1..31 + uint32_t Julian; // Julian day number + + if (Month <= 2) { + Month += 12; + Year -= 1; } - Gregor = (Jahr / 400) - (Jahr / 100) + (Jahr / 4); // Gregorianischer Kalender - return 2400000.5f + 365.0f*Jahr - 679004.0f + Gregor + (int)(30.6001f * (Monat +1)) + Tag + 0.5f; + // Warning, this formula works only for the 20th century, afterwards be are off by 1 day - which does not impact Sunrise much + // Julian = (1461 * Year + 6884472) / 4 + (153 * Month - 457) / 5 + Day -1 -13; + Julian = (1461 * Year + 6884416) / 4 + (153 * Month - 457) / 5 + Day; // -1 -13 included in 6884472 - 14*4 = 6884416 + return Julian; } +// Force value in the 0..pi2 range float InPi(float x) { - int n = (int)(x / pi2); - x = x - n*pi2; - if (x < 0) x += pi2; - return x; + return ModulusRangef(x, 0.0f, pi2); } -float eps(float T) -{ - // Neigung der Erdachse - return RAD * (23.43929111f + (-46.8150f*T - 0.00059f*T*T + 0.001813f*T*T*T)/3600.0f); -} +// Time formula +// Tdays is the number of days since Jan 1 2000, and replaces T as the Tropical Century. T = Tdays / 36525.0 +float TimeFormula(float *DK, uint32_t Tdays) { + float RA_Mean = 18.71506921f + (2400.0513369f / 36525.0f) * Tdays; // we keep only first order value as T is between 0.20 and 0.30 + float M = InPi( (pi2 * 0.993133f) + (pi2 * 99.997361f / 36525.0f) * Tdays); + float L = InPi( (pi2 * 0.7859453f) + M + (6893.0f * sinf(M) + 72.0f * sinf(M+M) + (6191.2f / 36525.0f) * Tdays) * (pi2 / 1296.0e3f)); -float BerechneZeitgleichung(float *DK,float T) -{ - float RA_Mittel = 18.71506921f + 2400.0513369f*T +(2.5862e-5f - 1.72e-9f*T)*T*T; - float M = InPi(pi2 * (0.993133f + 99.997361f*T)); - float L = InPi(pi2 * (0.7859453f + M/pi2 + (6893.0f*sinf(M)+72.0f*sinf(2.0f*M)+6191.2f*T) / 1296.0e3f)); - float e = eps(T); - float RA = atanf(tanf(L)*cosf(e)); - if (RA < 0.0) RA += pi; + float eps = 0.40904f; // we take this angle as constant over the next decade + float cos_eps = 0.91750f; // precompute cos(eps) + float sin_eps = 0.39773f; // precompute sin(eps) + + float RA = atanf(tanf(L) * cos_eps); + if (RA < 0.0f) RA += pi; if (L > pi) RA += pi; - RA = 24.0*RA/pi2; - *DK = asinf(sinf(e)*sinf(L)); - // Damit 0<=RA_Mittel<24 - RA_Mittel = 24.0f * InPi(pi2*RA_Mittel/24.0f)/pi2; - float dRA = RA_Mittel - RA; - if (dRA < -12.0f) dRA += 24.0f; - if (dRA > 12.0f) dRA -= 24.0f; + RA = RA * (24.0f/pi2); + *DK = asinf(sin_eps * sinf(L)); + RA_Mean = ModulusRangef(RA_Mean, 0.0f, 24.0f); + float dRA = ModulusRangef(RA_Mean - RA, -12.0f, 12.0f); dRA = dRA * 1.0027379f; return dRA; } void DuskTillDawn(uint8_t *hour_up,uint8_t *minute_up, uint8_t *hour_down, uint8_t *minute_down) { - float JD2000 = 2451545.0f; - float JD = JulianischesDatum(); - float T = (JD - JD2000) / 36525.0f; + const uint32_t JD2000 = 2451545; + uint32_t JD = JulianDate(RtcTime); + uint32_t Tdays = JD - JD2000; // number of days since Jan 1 2000 + + // ex 2458977 (2020 May 7) - 2451545 -> 7432 -> 0,2034 float DK; /* h (D) = -0.8333 normaler SA & SU-Gang @@ -130,56 +130,33 @@ void DuskTillDawn(uint8_t *hour_up,uint8_t *minute_up, uint8_t *hour_down, uint8 h (D) = -12.0 nautische Dämmerung h (D) = -18.0 astronomische Dämmerung */ -// double h = -50/60.0*RAD; - float h = SUNRISE_DAWN_ANGLE *RAD; - float B = (((float)Settings.latitude)/1000000) * RAD; // geographische Breite + const float h = SUNRISE_DAWN_ANGLE * RAD; + const float sin_h = sinf(h); // let GCC pre-compute the sin() at compile time + + float B = Settings.latitude / (1000000.0f / RAD); // geographische Breite + //float B = (((float)Settings.latitude)/1000000) * RAD; // geographische Breite float GeographischeLaenge = ((float)Settings.longitude)/1000000; // double Zeitzone = 0; //Weltzeit // double Zeitzone = 1; //Winterzeit // double Zeitzone = 2.0; //Sommerzeit float Zeitzone = ((float)Rtc.time_timezone) / 60; - float Zeitgleichung = BerechneZeitgleichung(&DK, T); - float Zeitdifferenz = 12.0f*acosf((sinf(h) - sinf(B)*sinf(DK)) / (cosf(B)*cosf(DK)))/pi; + float Zeitgleichung = TimeFormula(&DK, Tdays); + float Zeitdifferenz = acosf((sin_h - sinf(B)*sinf(DK)) / (cosf(B)*cosf(DK))) * (12.0f / pi); float AufgangOrtszeit = 12.0f - Zeitdifferenz - Zeitgleichung; float UntergangOrtszeit = 12.0f + Zeitdifferenz - Zeitgleichung; float AufgangWeltzeit = AufgangOrtszeit - GeographischeLaenge / 15.0f; float UntergangWeltzeit = UntergangOrtszeit - GeographischeLaenge / 15.0f; - float Aufgang = AufgangWeltzeit + Zeitzone; // In Stunden - if (Aufgang < 0.0f) { - Aufgang += 24.0f; - } else { - if (Aufgang >= 24.0f) Aufgang -= 24.0f; - } - float Untergang = UntergangWeltzeit + Zeitzone; - if (Untergang < 0.0f) { - Untergang += 24.0f; - } else { - if (Untergang >= 24.0f) Untergang -= 24.0f; - } - int AufgangMinuten = (int)(60.0f*(Aufgang - (int)Aufgang)+0.5f); + float Aufgang = AufgangWeltzeit + Zeitzone + (1/120.0f); // In Stunden, with rounding to nearest minute (1/60 * .5) + + Aufgang = ModulusRangef(Aufgang, 0.0f, 24.0f); // force 0 <= x < 24.0 int AufgangStunden = (int)Aufgang; - if (AufgangMinuten >= 60.0f) { - AufgangMinuten -= 60.0f; - AufgangStunden++; - } else { - if (AufgangMinuten < 0.0f) { - AufgangMinuten += 60.0f; - AufgangStunden--; - if (AufgangStunden < 0.0f) AufgangStunden += 24.0f; - } - } - int UntergangMinuten = (int)(60.0f*(Untergang - (int)Untergang)+0.5f); + int AufgangMinuten = (int)(60.0f * fmodf(Aufgang, 1.0f)); + float Untergang = UntergangWeltzeit + Zeitzone; + + Untergang = ModulusRangef(Untergang, 0.0f, 24.0f); int UntergangStunden = (int)Untergang; - if (UntergangMinuten >= 60.0f) { - UntergangMinuten -= 60.0f; - UntergangStunden++; - } else { - if (UntergangMinuten<0) { - UntergangMinuten += 60.0f; - UntergangStunden--; - if (UntergangStunden < 0.0f) UntergangStunden += 24.0f; - } - } + int UntergangMinuten = (int)(60.0f * fmodf(Untergang, 1.0f)); + *hour_up = AufgangStunden; *minute_up = AufgangMinuten; *hour_down = UntergangStunden; @@ -523,6 +500,15 @@ const char S_CONFIGURE_TIMER[] PROGMEM = D_CONFIGURE_TIMER; const char HTTP_BTN_MENU_TIMER[] PROGMEM = "

    "; +#ifdef USE_UNISHOX_COMPRESSION +const size_t HTTP_TIMER_SCRIPT1_SIZE = 106; +const char HTTP_TIMER_SCRIPT1_COMPRESSED[] PROGMEM = "\x33\xBF\xA1\x94\x7C\x3D\xE3\xDF\x3A\x83\xA3\xE1\xC4\x8F\x04\x60\x5F\x07\x5B\x9C" + "\x83\x67\x77\x4E\xA3\x51\xDE\x3D\xA6\x77\xF5\x87\xC1\x30\x31\x63\x5F\x51\xD0\x3F" + "\xBB\xA6\x4C\x26\x35\xF5\x1D\xD3\xEF\x06\x56\xE7\x1F\x67\x78\xF1\x87\x4A\x66\xCA" + "\x20\xF3\xA9\xF5\x1F\x34\xF0\x6A\x3A\x58\xC1\x8F\x84\x20\xC5\x68\x42\x1D\xDC\x3B" + "\xC7\x83\xDC"; +#define HTTP_TIMER_SCRIPT1 Decompress(HTTP_TIMER_SCRIPT1_COMPRESSED,HTTP_TIMER_SCRIPT1_SIZE).c_str() +#else const char HTTP_TIMER_SCRIPT1[] PROGMEM = "var pt=[],ct=99;" "function ce(i,q){" // Create select option @@ -530,7 +516,33 @@ const char HTTP_TIMER_SCRIPT1[] PROGMEM = "o.textContent=i;" "q.appendChild(o);" "}"; +#endif //USE_UNISHOX_COMPRESSION + #ifdef USE_SUNRISE +#ifdef USE_UNISHOX_COMPRESSION +const size_t HTTP_TIMER_SCRIPT2_SIZE = 630; +const char HTTP_TIMER_SCRIPT2_COMPRESSED[] PROGMEM = "\x30\x2F\x83\xAD\xCE\x43\xD4\x77\x4E\xF1\xED\x33\xBF\xA1\xA7\x50\xC3\xA8\xD4\x78" + "\x1A\x7C\x35\x78\xEE\x9F\x7B\xC3\x05\xD1\xEF\x75\x8D\x67\xC3\xD9\xF1\x0F\x61\xEF" + "\x9E\x61\x8A\x61\x9A\x31\x0F\xB3\xBC\x74\x33\xB0\x85\xB3\xC0\xC3\xE0\xCA\x3D\xE0" + "\xE8\xF7\xCF\xD1\xC6\x46\xC3\x9E\x22\x30\x46\x0F\x1A\x60\xEE\x8D\x3E\x1F\x0E\x33" + "\xBC\x7B\x4B\xD8\x77\x4E\x33\xBC\x78\x23\x51\xF0\x86\xDD\x0A\x3A\x18\x0B\x33\xE7" + "\x74\x61\xD8\x73\x99\xDE\x3C\x16\x98\x3B\xA6\xA3\xD0\xE4\x67\x78\xF6\x91\xA8\xF8" + "\x7D\x9C\x67\xD9\xDB\x23\x51\xE0\xF7\x1A\xBC\x77\x4F\xB3\xC8\x56\x02\x1E\x5E\x7C" + "\x35\x1E\x0D\x47\xC1\x87\xD1\xF4\x73\x99\x02\x9E\x10\x37\x41\x1B\x08\x3D\xDA\x60" + "\xEE\x9D\xD1\xA7\xC3\xE1\xC8\x77\x8F\xF1\xFE\x3B\xA4\x34\xF8\x7C\x39\x47\x78\xEF" + "\x1E\xD2\xF6\x1D\xD3\x90\x81\x53\x59\x3F\x0F\x87\x25\x1D\xE3\xDA\x46\xA3\xAC\xF8" + "\x72\x51\xE0\x8D\x5E\x3B\xA7\xD9\xE4\x27\xCF\xB3\xBC\x74\xF3\x09\x87\x4C\x42\xDE" + "\x11\x9B\x0F\x87\x21\xE0\xF7\x13\x0B\xCC\xF6\x82\x9D\xC3\x8C\xF0\x7B\x88\x19\x67" + "\x04\x87\xB8\x11\x38\xE6\xF6\x1D\xD1\xC7\x78\xF6\xE1\xF0\x11\x32\xD3\xC3\x3E\x61" + "\xD0\x31\x5A\x10\x84\xC2\x63\x5F\x51\x07\x82\xFA\x8F\x1A\x60\xEE\x8E\x3E\x1F\x0E" + "\x43\xBC\x40\x8F\xC0\x1D\x19\x04\xCE\x86\x7B\xED\x1D\xA1\x6D\x19\x1F\x0F\xB3\xEC" + "\xF1\xA6\x0E\xEB\x3F\x0E\x4A\x3B\xC7\xB4\x8C\x67\xCE\xEE\x9F\x0E\x4A\x3C\x16\x9E" + "\x87\xC3\x95\x67\x82\xD3\xB6\x76\xCE\xF1\xED\xC3\xA7\xD8\xDC\x33\x64\x18\xAD\x08" + "\x43\xBB\x87\x40\xAF\xD4\x08\x7A\x08\xAD\x08\x43\xBC\x78\x3D\xC7\xB8\x13\x38\x68" + "\x04\xCD\x04\x56\x88\x23\xE0\x41\xD1\xCF\x43\x95\x64\x0A\x3A\x38\x6C\xEE\xE9\xD5" + "\x87\x78\xF0\x7B\x8F\x71\xEE\x3D\xC6"; +#define HTTP_TIMER_SCRIPT2 Decompress(HTTP_TIMER_SCRIPT2_COMPRESSED,HTTP_TIMER_SCRIPT2_SIZE).c_str() +#else const char HTTP_TIMER_SCRIPT2[] PROGMEM = "function gt(){" // Set hours and minutes according to mode "var m,p,q;" @@ -561,7 +573,55 @@ const char HTTP_TIMER_SCRIPT2[] PROGMEM = "if(e<23){for(i=12;i<=23;i++){ce(i,o);}}" // Create hours select options "}" "}"; -#endif +#endif //USE_UNISHOX_COMPRESSION +#endif //USE_SUNRISE + +#ifdef USE_UNISHOX_COMPRESSION +#ifdef USE_SUNRISE +const size_t HTTP_TIMER_SCRIPT3_SIZE = 587; +const char HTTP_TIMER_SCRIPT3_COMPRESSED[] PROGMEM = "\x30\x2F\x83\xAD\xCE\x5E\xA3\xBA\x77\x8F\x69\x9D\xFD\x69\xD4\x11\xD4\x34\xEA\xE3" + "\xA8\x61\xD5\xE3\xC0\xD3\xE1\xC6\x78\x2F\x1F\x0E\x33\xC1\x71\xF0\xE4\x3D\x0F\x4B" + "\x87\x82\xD3\x07\x75\x8E\x3B\xA7\xDD\x9C\x67\xD9\xDE\x3A\x10\x62\x98\x66\x8C\x43" + "\xBC\x7B\x7C\x7F\x8F\x9C\x78\x3D\xDC\x7C\x39\x0F\x43\xD2\x69\x02\x1D\xFF\x82\x75" + "\xF3\x19\xF3\xBB\xA7\xC3\x8C\xF0\x5A\x7A\x1C\xF1\xE0\xB4\xED\x9D\xB3\xBC\x7B\x78" + "\xF8\x72\x1E\x87\xA1\xDD\x9C\x76\xCB\x4E\xF0\x21\xE2\x83\xE7\xD9\xDB\xD0\x4C\xC5" + "\x4F\x70\xD3\xE1\xAB\xC7\x74\xFB\xDE\x18\x2E\x8F\x7B\xAC\x6B\x3E\x1E\xCF\x88\x7B" + "\x0F\x7C\xF3\x04\x2C\x0C\xFB\x3B\xC7\x43\x3B\x08\x5B\x3C\x78\xFF\x1F\x0E\xE8\x2F" + "\xE0\xA7\xA1\xE8\x72\x91\xDE\x3C\x16\x98\x3B\xA7\xD0\x87\xE1\xC6\x77\x8F\x69\x69" + "\xF0\xD5\xE3\xBA\x7D\x9E\x42\x1C\x87\xD9\xDE\x3A\x17\x98\x4C\x3A\x62\x16\xF0\x8C" + "\xD8\x78\xD3\x07\x77\x4F\xC3\xE1\xC6\x77\x8F\x69\x78\xFF\x1F\x0E\xEE\x9E\x87\xA1" + "\xCA\xB3\xBC\x78\x3D\xC4\x08\x7A\x11\xE4\x30\x13\x30\xD3\xD0\xF4\x39\x5E\x3B\xC7" + "\x83\xDC\x4C\x2F\x33\xDB\xE3\xFC\x7C\x39\x67\xA1\xE9\x5E\x3C\x1E\xE2\x08\xF8\x77" + "\x41\x07\x0D\x15\x80\x97\x86\x9E\xB3\x9C\xCE\xF1\xDB\x23\x57\x8E\xE9\xF6\x79\x0D" + "\xD0\x4B\xB0\x77\x8F\xD1\xC6\x46\xC3\x9E\x22\x30\x46\x0F\x1A\x60\xEE\x8D\x3E\x02" + "\x16\xC2\x11\xE0\xF7\x69\x83\xBA\x77\x46\x9F\x0F\x87\x21\xDE\x3F\xC7\xF8\xEE\x90" + "\xD3\xE1\xF0\xE5\x1D\xE3\xBC\x7B\x4B\x4C\x02\x0E\x78\x27\xC1\x2F\x20\x3F\x0E\x33" + "\xBC\x7B\x4B\x4C\x1D\xD0\x8F\xC3\x8C\xEF\x1E\xD2\x08\xED\x9F\x0E\x7A\x99\xE0\xF7" + "\x1E\xE2\xF1\xFE\x3E\x04\x08\x59\xC1\xEE\xF1\xFE\x04\x3D\xE4\x68\xF8\x27\xEB\xA7" + "\x19\x11\x83\xBC\x7A\x1E\x87\x24\x3C\x10\xCA\x3D\xE0\xE8\xF7\xCF\x9E\x3C\x31\xC7" + "\x74\xFB\xA3\x8C\x81\x0F\x8A\x63\xE0\xCA\x3A\x1A\xF3\x78\xEE\x9D\xE3\xC1\xEE"; +#define HTTP_TIMER_SCRIPT3 Decompress(HTTP_TIMER_SCRIPT3_COMPRESSED,HTTP_TIMER_SCRIPT3_SIZE).c_str() +#else +const size_t HTTP_TIMER_SCRIPT3_SIZE = 424; +const char HTTP_TIMER_SCRIPT3_COMPRESSED[] PROGMEM = "\x30\x2F\x83\xAD\xCE\x5E\xA3\xBA\x77\x8F\x69\x9D\xFD\x69\xD4\x11\xD4\x34\xEA\xE3" + "\xA8\x61\xD5\xE3\xC0\xD3\xE1\xC6\x78\x2F\x1F\x0E\x33\xC1\x71\xF0\xE4\x3D\x0F\x4B" + "\x87\x82\xD3\x07\x75\x8E\x3B\xA7\xDD\x9C\x67\xD9\xDE\x3A\x10\x62\x98\x66\x8C\x43" + "\xBC\x7B\x7C\x7F\x8F\x9C\x78\x3D\xDC\x7C\x39\x0F\x43\xD2\x69\x02\x1D\xFF\x82\x75" + "\xF3\x19\xF3\xBB\xA7\xC3\x8C\xF0\x5A\x7A\x1C\xF1\xE0\xB4\xED\x9D\xB3\xBC\x7B\x78" + "\xF8\x72\x1E\x87\xA1\xDD\x9C\x76\xCB\x4E\xF0\x21\xE2\x83\xE7\xD9\xDB\xD0\x4C\xC5" + "\x4F\x76\x98\x3B\xA7\xD0\x87\xE1\xC6\x77\x8F\x69\x69\xF0\xD5\xE3\xBA\x7D\x9E\x42" + "\x1C\x87\xD9\xDE\x3A\x17\x98\x4C\x3A\x62\x16\xF0\x8C\xD8\x78\xD3\x07\x77\x4F\xC3" + "\xE1\xC6\x77\x8F\x69\x78\xFF\x1F\x0E\xEE\x9E\x87\xA1\xCA\xB3\xBC\x78\x3D\xC5\xE3" + "\xFC\x7C\x3B\xA6\xAF\x1D\xD3\xEC\xF2\x18\x09\x98\x69\xE8\x7A\x1C\xAF\x1D\xE3\xC1" + "\xEE\x26\x17\x99\xED\xF1\xFE\x3E\x1C\xB3\xD0\xF4\xAF\x1E\x0F\x71\x04\x7C\x3B\xA0" + "\x83\x86\x8A\xC0\x4B\xC3\x4F\x59\xCE\x67\x78\xED\x91\xAB\xC7\x74\xFB\x3C\x86\xE8" + "\x25\xD8\x3B\xC7\xE8\xE3\x23\x61\xCF\x11\x18\x23\x07\x8D\x30\x77\x46\x9F\x01\x0B" + "\x61\x08\x10\x75\xB0\x41\xCA\xC6\x8F\x82\x7E\x1E\x71\x91\x18\x3B\xC7\xA1\xE8\x72" + "\x43\xC1\x0C\xA3\xDE\x0E\x8F\x7C\xF9\xE3\xC3\x1C\x77\x4F\xBA\x38\xCF\xB3\xBC\x74" + "\x23\x3B\x08\x5B\x3E\x0C\xA3\xA1\xAF\x37\x8E\xE9\xDE\x3C\x1E\xE3"; +#define HTTP_TIMER_SCRIPT3 Decompress(HTTP_TIMER_SCRIPT3_COMPRESSED,HTTP_TIMER_SCRIPT3_SIZE).c_str() +#endif //USE_SUNRISE +#else const char HTTP_TIMER_SCRIPT3[] PROGMEM = "function st(){" // Save parameters to hidden area "var i,l,m,n,p,s;" @@ -591,6 +651,58 @@ const char HTTP_TIMER_SCRIPT3[] PROGMEM = "pt[ct]=s;" "eb('t0').value=pt.join();" // Save parameters from array to hidden area "}"; +#endif //USE_UNISHOX_COMPRESSION + +#ifdef USE_UNISHOX_COMPRESSION +#ifdef USE_SUNRISE +const size_t HTTP_TIMER_SCRIPT4_SIZE = 548; +const char HTTP_TIMER_SCRIPT4_COMPRESSED[] PROGMEM = "\x30\x2F\x83\xAD\xCE\x59\x47\x76\x8E\xA6\x77\x8F\x69\x9D\xFD\x69\xD5\xC7\x56\x1D" + "\x43\x0E\xA3\x51\xD5\xE3\xC6\x98\x3B\xA1\xD1\xE8\x71\x23\xBC\x7B\x4B\xD4\x77\x4E" + "\xF1\xE0\xF7\x07\x47\xCA\x3C\x61\xF0\x4C\x0C\x58\xD7\xD4\x74\x1E\x74\x4C\x26\x35" + "\xF5\x78\x87\x19\x10\x61\x5F\xBC\x5D\x63\x59\xDD\x3E\xE8\x23\xEC\xEF\x1E\x0C\x67" + "\xCE\xEE\x9F\x0E\x33\xC1\x69\xE9\x87\x40\x9F\x0F\x50\xA3\xC6\x9D\xB3\xB6\x77\x8F" + "\x6E\x1E\xF6\x9E\xF9\xD3\xD4\x64\x13\x3A\x07\xEF\x15\x33\x65\x1F\x0F\x60\xEB\x0C" + "\xD0\x7B\xF8\x2F\x84\x3C\xCF\x23\xE8\xE3\xE2\x36\x1E\x03\xC0\xB3\xE0\x85\x20\xC6" + "\x75\x1D\x63\xEF\x47\x85\x51\xE7\xD9\xF1\xB6\x11\xE0\xF6\x1E\xE6\x0C\x53\x1F\x1D" + "\x81\x08\x78\x3D\x87\x8F\x1F\x06\x51\xEF\x07\x47\xBE\x78\x18\x7C\x3B\xBE\x3F\x0F" + "\xC3\x94\x8E\xF1\xFA\xB3\xC1\x31\xC7\x74\xFB\x1C\x7D\x9D\xB1\x87\x78\xE8\x18\xA6" + "\x19\xA3\x10\xF8\x72\x1E\x08\x7A\x8E\xE9\xDE\x3C\x1A\x8F\x87\x77\xC7\xE1\xF8\x72" + "\x43\xBC\x7E\x99\x1B\x08\xC1\xE3\x4C\x1D\xD3\x51\xE8\x72\x33\xBC\x7B\x48\xD4\x7C" + "\x3E\xCE\x33\xEC\xED\x91\xA8\xF0\x7B\x8D\x5E\x3B\xA7\xD9\xE4\x34\x7C\xFB\x3B\xC7" + "\x43\x3B\x08\x5B\x3E\x1A\x81\x1B\x85\xB3\x9E\x20\x41\xE1\x50\x10\x74\x43\xBA\x72" + "\x71\xDB\x2D\x3B\xC7\x78\xFD\x1C\x87\x82\x63\x8E\xE9\xF6\x3E\x7D\x9D\xBD\x04\x5D" + "\x20\x61\xE0\xF7\x69\x83\xBA\x7D\x08\x7E\x1C\x64\x08\x78\x51\xCA\xB2\x04\x1D\x34" + "\xD5\xE3\xBA\x7D\x9E\x42\x1C\x84\x08\x99\xD8\xC3\xB6\x72\x10\x21\xF0\x28\x73\xC7" + "\x78\xFD\x59\x02\x0D\xC1\x87\x21\xF6\x77\x8E\x85\xE6\x13\x0E\x98\x85\xBC\x23\x36" + "\x1F\x06\x1E\x0F\x70\x20\xE0\x67\x26\x90\x21\xE9\xFF\x38\xCF\xB2\x04\x7D\x38\x10" + "\x6D\x9C\xB8\x40\x87\x6E\xC1\x26\xD9\xEE"; +#define HTTP_TIMER_SCRIPT4 Decompress(HTTP_TIMER_SCRIPT4_COMPRESSED,HTTP_TIMER_SCRIPT4_SIZE).c_str() +#else +const size_t HTTP_TIMER_SCRIPT4_SIZE = 620; +const char HTTP_TIMER_SCRIPT4_COMPRESSED[] PROGMEM = "\x30\x2F\x83\xAD\xCE\x59\x47\x76\x8E\xA6\x77\x8F\x69\x9D\xFD\x69\xD5\xC7\x56\x1D" + "\x43\x0E\xA3\x51\xD5\xE3\xC6\x98\x3B\xA1\xD1\xE8\x71\x23\xBC\x7B\x4B\xD4\x77\x4E" + "\xF1\xE0\xF7\x07\x47\xCA\x3C\x61\xF0\x4C\x0C\x58\xD7\xD4\x74\x1E\x74\x4C\x26\x35" + "\xF5\x78\x87\x19\x10\x61\x5F\xBC\x5D\x63\x59\xDD\x3E\xE8\x23\xEC\xEF\x1E\x0C\x67" + "\xCE\xEE\x9F\x0E\x33\xC1\x69\xE9\x87\x40\x9F\x0F\x50\xA3\xC6\x9D\xB3\xB6\x77\x8F" + "\x6E\x1E\xF6\x9E\xF9\xD3\xD4\x64\x13\x3A\x07\xEF\x15\x33\x65\x1F\x0F\x60\xEB\x0C" + "\xD0\x7B\xF8\x2F\x84\x3C\xCF\x23\xE8\xE3\xE2\x36\x1E\x03\xC0\xB3\xE0\x85\x20\xC6" + "\x75\x1D\x63\xEF\x47\x85\x51\xE7\xD9\xF1\xB6\x11\xE0\xF6\x1E\xE6\x0C\x53\x1F\x1D" + "\x81\x08\x78\x3D\x87\x8F\x1F\x06\x51\xEF\x07\x47\xBE\x78\x18\x7C\xF1\xFA\x38\xC8" + "\xD8\x73\xC4\x46\x08\xC1\xE0\xD4\x7C\x21\xB7\x42\x8E\x86\x02\xCC\xF9\xDD\x18\x76" + "\x1C\xE6\x77\x8F\x05\xA6\x0E\xE9\xA8\xF4\x39\x19\xDE\x3D\xA4\x6A\x3E\x1F\x67\x19" + "\xF6\x76\xC8\xD4\x78\x3D\xC6\xAF\x1D\xD3\xEC\xF2\x15\x87\xD9\xDE\x3A\x19\xD8\x42" + "\xD9\xF0\xD4\x78\x35\x1F\x06\x1F\x47\xD1\xCE\x64\x0A\x78\x40\xDD\x04\x8C\x20\xEE" + "\xF8\xFC\x3F\x0E\x48\x77\x8F\xD3\x23\x61\x18\x05\x4C\x38\x7C\x11\xB0\xE0\x45\xE2" + "\x8C\xE7\x88\x10\x78\x9C\x18\x7C\x3B\xBE\x3F\x0F\xC3\xBA\x72\x71\xDB\x2D\x3B\xC7" + "\x78\xFD\x1C\x87\x82\x63\x8E\xE9\xF6\x3E\x7D\x9D\xBD\x3B\xC7\x40\xC5\x30\xCD\x18" + "\x87\xC1\x87\x83\xDD\xA6\x0E\xE9\xF4\x21\xF8\x71\x90\x21\xE1\x47\x2A\x2B\xC8\x10" + "\x74\xD3\x57\x8E\xE9\xF6\x79\x08\x72\x10\x22\x67\x63\x0E\xD9\xC8\x78\x20\x42\xBC" + "\x73\xC7\x78\xFD\x59\x02\x0D\xC1\x87\x21\xF6\x77\x8E\x85\xE6\x13\x0E\x98\x85\xBC" + "\x23\x36\x1F\x06\x1E\x0F\x70\x20\xE0\x67\x26\x90\x21\xE9\xFF\x38\xCF\xB2\x04\x7D" + "\x38\x10\x6D\x9C\xB8\x40\x87\x6E\xC1\x26\xD9\xEE"; +#define HTTP_TIMER_SCRIPT4 Decompress(HTTP_TIMER_SCRIPT4_COMPRESSED,HTTP_TIMER_SCRIPT4_SIZE).c_str() +#endif //USE_SUNRISE +#else const char HTTP_TIMER_SCRIPT4[] PROGMEM = "function ot(t,e){" // Select tab and update elements "var i,n,o,p,q,s;" @@ -617,6 +729,8 @@ const char HTTP_TIMER_SCRIPT4[] PROGMEM = "p=(s>>15)&1;eb('r0').checked=p;" // Set repeat "p=(s>>31)&1;eb('a0').checked=p;" // Set arm "}"; +#endif //USE_UNISHOX_COMPRESSION + const char HTTP_TIMER_SCRIPT5[] PROGMEM = "function it(){" // Initialize elements and select first tab "var b,i,o,s;" @@ -687,6 +801,17 @@ const char HTTP_FORM_TIMER3[] PROGMEM = const char HTTP_FORM_TIMER3[] PROGMEM = "" D_TIMER_TIME " "; #endif // USE_SUNRISE + +#ifdef USE_UNISHOX_COMPRESSION +const size_t HTTP_FORM_TIMER4_SIZE = 249; +const char HTTP_FORM_TIMER4_COMPRESSED[] PROGMEM = "\x3D\x3C\x32\xF8\xFC\x3D\x3C\xC2\x61\xD2\xF5\x19\x04\xCF\x87\xD8\xFE\x89\x42\x8F" + "\x33\x9C\xC8\x61\xB0\xF0\x7D\xAD\x10\xF8\x7D\x8A\xC3\xEC\xFC\x3D\x0E\xC0\x41\xC0" + "\x4F\xC3\xD0\xEC\xF0\xCB\xE3\xF0\xFD\x70\xEF\x0C\x3C\x1F\x5E\x04\x18\x80\xC0\x72" + "\x41\xBA\x09\xD9\x23\x1B\xE1\x87\x83\xD0\x71\xF8\x76\xCE\xC3\xAC\xF4\x3B\x07\x02" + "\x16\x68\x0C\x0B\x2C\x1F\x04\xDC\xB0\xF4\x3B\x04\xD3\x33\xF0\xF4\x1D\xF3\xF0\xF4" + "\x13\x4C\xD6\x88\x7C\x3E\xC4\xF1\xF6\xBA\xC6\xB3\xE1\xF6\x27\x8F\xB0\x42\xBA"; +#define HTTP_FORM_TIMER4 Decompress(HTTP_FORM_TIMER4_COMPRESSED,HTTP_FORM_TIMER4_SIZE).c_str() +#else const char HTTP_FORM_TIMER4[] PROGMEM = "" " " D_HOUR_MINUTE_SEPARATOR " " @@ -695,6 +820,7 @@ const char HTTP_FORM_TIMER4[] PROGMEM = "" "


    " "
    "; +#endif //USE_UNISHOX_COMPRESSION void HandleTimerConfiguration(void) { @@ -702,7 +828,7 @@ void HandleTimerConfiguration(void) AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_TIMER); - if (WebServer->hasArg("save")) { + if (Webserver->hasArg("save")) { TimerSaveSettings(); HandleConfiguration(); return; @@ -728,7 +854,11 @@ void HandleTimerConfiguration(void) #else WSContentSend_P(HTTP_FORM_TIMER3); #endif // USE_SUNRISE +#ifdef USE_UNISHOX_COMPRESSION + WSContentSend_P(HTTP_FORM_TIMER4,D_HOUR_MINUTE_SEPARATOR); +#else WSContentSend_P(HTTP_FORM_TIMER4); +#endif //USE_UNISHOX_COMPRESSION WSContentSend_P(HTTP_FORM_END); WSContentSpaceButton(BUTTON_CONFIGURATION); WSContentStop(); @@ -740,7 +870,7 @@ void TimerSaveSettings(void) char message[LOGSZ]; Timer timer; - Settings.flag3.timers_enable = WebServer->hasArg("e0"); // CMND_TIMERS + Settings.flag3.timers_enable = Webserver->hasArg("e0"); // CMND_TIMERS WebGetArg("t0", tmp, sizeof(tmp)); char *p = tmp; snprintf_P(message, sizeof(message), PSTR(D_LOG_MQTT D_CMND_TIMERS " %d"), Settings.flag3.timers_enable); // CMND_TIMERS @@ -781,7 +911,7 @@ bool Xdrv09(uint8_t function) #endif // USE_RULES break; case FUNC_WEB_ADD_HANDLER: - WebServer->on("/" WEB_HANDLE_TIMER, HandleTimerConfiguration); + Webserver->on("/" WEB_HANDLE_TIMER, HandleTimerConfiguration); break; #endif // USE_TIMERS_WEB #endif // USE_WEBSERVER diff --git a/tasmota/xdrv_10_rules.ino b/tasmota/xdrv_10_rules.ino index 2509d6f6f..db22183c5 100644 --- a/tasmota/xdrv_10_rules.ino +++ b/tasmota/xdrv_10_rules.ino @@ -47,6 +47,7 @@ * on button1#state do publish cmnd/ring2/power %value% endon on button2#state do publish cmnd/strip1/power %value% endon * on switch1#state do power2 %value% endon * on analog#a0div10 do publish cmnd/ring2/dimmer %value% endon + * on loadavg<50 do power 2 endon * * Notes: * Spaces after , around and before are mandatory @@ -66,6 +67,8 @@ #define XDRV_10 10 +#include + #define D_CMND_RULE "Rule" #define D_CMND_RULETIMER "RuleTimer" #define D_CMND_EVENT "Event" @@ -162,9 +165,10 @@ struct RULES { long old_dimm = -1; uint16_t last_minute = 60; - uint16_t vars_event = 0; - uint8_t mems_event = 0; + uint16_t vars_event = 0; // Bitmask supporting MAX_RULE_VARS bits + uint16_t mems_event = 0; // Bitmask supporting MAX_RULE_MEMS bits bool teleperiod = false; + bool busy = false; char event_data[100]; } Rules; @@ -178,6 +182,222 @@ char rules_vars[MAX_RULE_VARS][33] = {{ 0 }}; #error MAX_RULE_MEMS is bigger than 16 #endif + +/*******************************************************************************************/ +/* + * Add Unishox compression to Rules + * + * New compression for Rules, depends on SetOption93 + * + * To avoid memory corruption when downgrading, the format is as follows: + * - If `SetOption93 0` + * Rule[x][] = 511 char max NULL terminated string (512 with trailing NULL) + * Rule[x][0] = 0 if the Rule is empty + * New: in case the string is empty we also enforce: + * Rule[x][1] = 0 (i.e. we have two conseutive NULLs) + * + * - If `SetOption93 1` + * If the rule is smaller than 511, it is stored uncompressed. Rule[x][0] is not null. + * If the rule is empty, Rule[x][0] = 0 and Rule[x][1] = 0; + * If the rule is bigger than 511, it is stored compressed + * The first byte of each Rule is always NULL. + * Rule[x][0] = 0, if firmware is downgraded, the rule will be considered as empty + * + * The second byte contains the size of uncompressed rule in 8-bytes blocks (i.e. (len+7)/8 ) + * Maximum rule size is 2KB (2048 bytes per rule), although there is little chances compression ratio will go down to 75% + * Rule[x][1] = size uncompressed in dwords. If zero, the rule is empty. + * + * The remaining bytes contain the compressed rule, NULL terminated + */ +/*******************************************************************************************/ + +#ifdef USE_UNISHOX_COMPRESSION +// Statically allocate one String per rule +String k_rules[MAX_RULE_SETS] = { String(), String(), String() }; // Strings are created empty +// Unishox compressor; // singleton +#endif // USE_UNISHOX_COMPRESSION + +// Returns whether the rule is uncompressed, which means the first byte is not NULL +inline bool IsRuleUncompressed(uint32_t idx) { +#ifdef USE_UNISHOX_COMPRESSION + return Settings.rules[idx][0] ? true : false; // first byte not NULL, the rule is not empty and not compressed +#else + return true; +#endif +} + +// Returns whether the rule is empty, which requires two consecutive NULL +inline bool IsRuleEmpty(uint32_t idx) { +#ifdef USE_UNISHOX_COMPRESSION + return (Settings.rules[idx][0] == 0) && (Settings.rules[idx][1] == 0) ? true : false; +#else + return (Settings.rules[idx][0] == 0) ? true : false; +#endif +} + +// Returns the approximate (+3-0) length of the rule, not counting the trailing NULL +size_t GetRuleLen(uint32_t idx) { + // no need to use #ifdef USE_UNISHOX_COMPRESSION, the compiler will optimize since first test is always true + if (IsRuleUncompressed(idx)) { + return strlen(Settings.rules[idx]); + } else { // either empty or compressed + return Settings.rules[idx][1] * 8; // cheap calculation, but not byte accurate (may overshoot by 7) + } +} + +// Returns the actual Flash storage for the Rule, including trailing NULL +size_t GetRuleLenStorage(uint32_t idx) { +#ifdef USE_UNISHOX_COMPRESSION + if (Settings.rules[idx][0] || !Settings.rules[idx][1]) { // if first byte is non-NULL it is uncompressed, if second byte is NULL, then it's either uncompressed or empty + return 1 + strlen(Settings.rules[idx]); // uncompressed or empty + } else { + return 2 + strlen(&Settings.rules[idx][1]); // skip first byte and get len of the compressed rule + } +#else + return 1 + strlen(Settings.rules[idx]); +#endif +} + +#ifdef USE_UNISHOX_COMPRESSION +// internal function, do the actual decompression +void GetRule_decompress(String &rule, const char *rule_head) { + size_t buf_len = 1 + *rule_head * 8; // the first byte contains size of buffer for uncompressed rule / 8, buf_len may overshoot by 7 + rule_head++; // advance to the actual compressed buffer + + rule = Decompress(rule_head, buf_len); +} +#endif // USE_UNISHOX_COMPRESSION + +// +// Read rule in memory, uncompress if needed +// +// Returns: String() object containing a copy of the rule (rule processing is destructive and will change the String) +String GetRule(uint32_t idx) { + if (IsRuleUncompressed(idx)) { + return String(Settings.rules[idx]); + } else { +#ifdef USE_UNISHOX_COMPRESSION // we still do #ifdef to make sure we don't link unnecessary code + + String rule(""); + if (Settings.rules[idx][1] == 0) { return rule; } // the rule is empty + + // If the cache is empty, we need to decompress from Settings + if (0 == k_rules[idx].length() ) { + GetRule_decompress(rule, &Settings.rules[idx][1]); + if (!Settings.flag4.compress_rules_cpu) { + k_rules[idx] = rule; // keep a copy for next time + } + } else { + // we have a valid copy + rule = k_rules[idx]; + } + return rule; +#endif + } +} + +#ifdef USE_UNISHOX_COMPRESSION +// internal function, comrpess rule and store a cached version uncompressed (except if SetOption94 1) +// If out == nullptr, we are in dry-run mode, so don't keep rule in cache +int32_t SetRule_compress(uint32_t idx, const char *in, size_t in_len, char *out, size_t out_len) { + int32_t len_compressed; + len_compressed = compressor.unishox_compress(in, in_len, out, out_len); + + if (len_compressed >= 0) { // negative means compression failed because of buffer too small, we leave the rule untouched + // check if we need to store in cache + k_rules[idx] = (const char*) nullptr; // Assign the String to nullptr, clears previous string and disallocate internal buffers of String object + if ((!Settings.flag4.compress_rules_cpu) && out) { // if out == nullptr, don't store cache + // keep copy in cache + k_rules[idx] = in; + } + } + return len_compressed; +} +#endif // USE_UNISHOX_COMPRESSION + +// Returns: +// >= 0 : the actual stored size +// <0 : not enough space +int32_t SetRule(uint32_t idx, const char *content, bool append = false) { + if (nullptr == content) { content = ""; } // if nullptr, use empty string + size_t len_in = strlen(content); + bool needsCompress = false; + size_t offset = 0; + + if (len_in >= MAX_RULE_SIZE) { // if input is more than 512, it will not fit uncompressed + needsCompress = true; + } + if (append) { + if (IsRuleUncompressed(idx) || IsRuleEmpty(idx)) { // if already uncompressed (so below 512) and append mode, check if it still fits uncompressed + offset = strlen(Settings.rules[idx]); + if (len_in + offset >= MAX_RULE_SIZE) { + needsCompress = true; + } + } else { + needsCompress = true; // we append to a non-empty compressed rule, so it won't fit uncompressed + } + } + + if (!needsCompress) { // the rule fits uncompressed, so just copy it + strlcpy(Settings.rules[idx] + offset, content, sizeof(Settings.rules[idx])); + if (0 == Settings.rules[idx][0]) { + Settings.rules[idx][1] = 0; + } + +#ifdef USE_UNISHOX_COMPRESSION + if (0 != len_in + offset) { + // do a dry-run compression to display how much it would be compressed + int32_t len_compressed, len_uncompressed; + + len_uncompressed = strlen(Settings.rules[idx]); + len_compressed = compressor.unishox_compress(Settings.rules[idx], len_uncompressed, nullptr /* dry-run */, MAX_RULE_SIZE + 8); + AddLog_P2(LOG_LEVEL_INFO, PSTR("RUL: Stored uncompressed, would compress from %d to %d (-%d%%)"), len_uncompressed, len_compressed, 100 - changeUIntScale(len_compressed, 0, len_uncompressed, 0, 100)); + } + +#endif // USE_UNISHOX_COMPRESSION + + return len_in + offset; + } else { +#ifdef USE_UNISHOX_COMPRESSION + int32_t len_compressed; + // allocate temp buffer so we don't nuke the rule if it's too big to fit + char *buf_out = (char*) malloc(MAX_RULE_SIZE + 8); // take some margin + if (!buf_out) { return -1; } // fail if couldn't allocate + + // compress + if (append) { + String content_append = GetRule(idx); // get original Rule and decompress it if needed + content_append += content; // concat new content + len_in = content_append.length(); // adjust length + len_compressed = SetRule_compress(idx, content_append.c_str(), len_in, buf_out, MAX_RULE_SIZE + 8); + } else { + len_compressed = SetRule_compress(idx, content, len_in, buf_out, MAX_RULE_SIZE + 8); + } + + if ((len_compressed >= 0) && (len_compressed < MAX_RULE_SIZE - 2)) { + // size is ok, copy to Settings + Settings.rules[idx][0] = 0; // clear first byte to mark as compressed + Settings.rules[idx][1] = (len_in + 7) / 8; // store original length in first bytes (4 bytes chuks) + memcpy(&Settings.rules[idx][2], buf_out, len_compressed); + Settings.rules[idx][len_compressed + 2] = 0; // add NULL termination + AddLog_P2(LOG_LEVEL_INFO, PSTR("RUL: Compressed from %d to %d (-%d%%)"), len_in, len_compressed, 100 - changeUIntScale(len_compressed, 0, len_in, 0, 100)); + // AddLog_P2(LOG_LEVEL_INFO, PSTR("RUL: First bytes: %02X%02X%02X%02X"), Settings.rules[idx][0], Settings.rules[idx][1], Settings.rules[idx][2], Settings.rules[idx][3]); + // AddLog_P2(LOG_LEVEL_INFO, PSTR("RUL: GetRuleLenStorage = %d"), GetRuleLenStorage(idx)); + } else { + len_compressed = -1; // failed + // clear rule cache, so it will be reloaded from Settings + k_rules[idx] = (const char *) nullptr; + } + free(buf_out); + return len_compressed; + +#else // USE_UNISHOX_COMPRESSION + return -1; // the rule does not fit and we can't compress +#endif // USE_UNISHOX_COMPRESSION + } + +} + /*******************************************************************************************/ bool RulesRuleMatch(uint8_t rule_set, String &event, String &rule) @@ -190,19 +410,20 @@ bool RulesRuleMatch(uint8_t rule_set, String &event, String &rule) char stemp[10]; // Step1: Analyse rule - int pos = rule.indexOf('#'); - if (pos == -1) { return false; } // No # sign in rule - - String rule_task = rule.substring(0, pos); // "INA219" or "SYSTEM" + String rule_expr = rule; // "TELE-INA219#CURRENT>0.100" if (Rules.teleperiod) { - int ppos = rule_task.indexOf("TELE-"); // "TELE-INA219" or "INA219" + int ppos = rule_expr.indexOf("TELE-"); // "TELE-INA219#CURRENT>0.100" or "INA219#CURRENT>0.100" if (ppos == -1) { return false; } // No pre-amble in rule - rule_task = rule.substring(5, pos); // "INA219" or "SYSTEM" + rule_expr = rule.substring(5); // "INA219#CURRENT>0.100" or "SYSTEM#BOOT" } - String rule_expr = rule.substring(pos +1); // "CURRENT>0.100" or "BOOT" or "%var1%" or "MINUTE|5" String rule_name, rule_param; - int8_t compareOperator = parseCompareExpression(rule_expr, rule_name, rule_param); //Parse the compare expression.Return operator and the left, right part of expression + int8_t compareOperator = parseCompareExpression(rule_expr, rule_name, rule_param); // Parse the compare expression.Return operator and the left, right part of expression + + // rule_name = "INA219#CURRENT" + // rule_param = "0.100" or "%VAR1%" + +//AddLog_P2(LOG_LEVEL_DEBUG, PSTR("RUL: expr %s, name %s, param %s"), rule_expr.c_str(), rule_name.c_str(), rule_param.c_str()); char rule_svalue[80] = { 0 }; float rule_value = 0; @@ -221,28 +442,38 @@ bool RulesRuleMatch(uint8_t rule_set, String &event, String &rule) break; } } - snprintf_P(stemp, sizeof(stemp), PSTR("%%TIME%%")); - if (rule_param.startsWith(stemp)) { + if (rule_param.startsWith(F("%TIME%"))) { rule_param = String(MinutesPastMidnight()); } - snprintf_P(stemp, sizeof(stemp), PSTR("%%UPTIME%%")); - if (rule_param.startsWith(stemp)) { + if (rule_param.startsWith(F("%UPTIME%"))) { rule_param = String(MinutesUptime()); } - snprintf_P(stemp, sizeof(stemp), PSTR("%%TIMESTAMP%%")); - if (rule_param.startsWith(stemp)) { + if (rule_param.startsWith(F("%TIMESTAMP%"))) { rule_param = GetDateAndTime(DT_LOCAL).c_str(); } #if defined(USE_TIMERS) && defined(USE_SUNRISE) - snprintf_P(stemp, sizeof(stemp), PSTR("%%SUNRISE%%")); - if (rule_param.startsWith(stemp)) { + if (rule_param.startsWith(F("%SUNRISE%"))) { rule_param = String(SunMinutes(0)); } - snprintf_P(stemp, sizeof(stemp), PSTR("%%SUNSET%%")); - if (rule_param.startsWith(stemp)) { + if (rule_param.startsWith(F("%SUNSET%"))) { rule_param = String(SunMinutes(1)); } #endif // USE_TIMERS and USE_SUNRISE +// #ifdef USE_ZIGBEE +// if (rule_param.startsWith(F("%ZBDEVICE%"))) { +// snprintf_P(stemp, sizeof(stemp), PSTR("0x%04X"), Z_GetLastDevice()); +// rule_param = String(stemp); +// } +// if (rule_param.startsWith(F("%ZBGROUP%"))) { +// rule_param = String(Z_GetLastGroup()); +// } +// if (rule_param.startsWith(F("%ZBCLUSTER%"))) { +// rule_param = String(Z_GetLastCluster()); +// } +// if (rule_param.startsWith(F("%ZBENDPOINT%"))) { +// rule_param = String(Z_GetLastEndpoint()); +// } +// #endif rule_param.toUpperCase(); strlcpy(rule_svalue, rule_param.c_str(), sizeof(rule_svalue)); @@ -250,11 +481,12 @@ bool RulesRuleMatch(uint8_t rule_set, String &event, String &rule) if (temp_value > -1) { rule_value = temp_value; } else { - rule_value = CharToFloat((char*)rule_svalue); // 0.1 - This saves 9k code over toFLoat()! + rule_value = CharToFloat((char*)rule_svalue); // 0.1 - This saves 9k code over toFLoat()! } } - // Step2: Search rule_task and rule_name + // Step2: Search rule_name + int pos; int rule_name_idx = 0; if ((pos = rule_name.indexOf("[")) > 0) { // "SUBTYPE1#CURRENT[1]" rule_name_idx = rule_name.substring(pos +1).toInt(); @@ -267,21 +499,22 @@ bool RulesRuleMatch(uint8_t rule_set, String &event, String &rule) StaticJsonBuffer<1024> jsonBuf; JsonObject &root = jsonBuf.parseObject(event); if (!root.success()) { return false; } // No valid JSON data - if (!root[rule_task].success()) { return false; } // No rule_task in JSON data - - JsonObject &obj1 = root[rule_task]; - JsonObject *obj = &obj1; + JsonObject *obj = &root; String subtype; uint32_t i = 0; while ((pos = rule_name.indexOf("#")) > 0) { // "SUBTYPE1#SUBTYPE2#CURRENT" subtype = rule_name.substring(0, pos); - if (!(*obj)[subtype].success()) { return false; } // No subtype in JSON data - JsonObject &obj2 = (*obj)[subtype]; - obj = &obj2; + const JsonVariant & val = GetCaseInsensitive(*obj, subtype.c_str()); + if (nullptr == &val) { return false; } // not found + obj = &(val.as()); + if (!obj->success()) { return false; } // not a JsonObject + rule_name = rule_name.substring(pos +1); if (i++ > 10) { return false; } // Abandon possible loop } - if (!(*obj)[rule_name].success()) { return false; } // No name in JSON data + + const JsonVariant & val = GetCaseInsensitive(*obj, rule_name.c_str()); + if (nullptr == &val) { return false; } // last level not found const char* str_value; if (rule_name_idx) { str_value = (*obj)[rule_name][rule_name_idx -1]; // "CURRENT[1]" @@ -289,8 +522,8 @@ bool RulesRuleMatch(uint8_t rule_set, String &event, String &rule) str_value = (*obj)[rule_name]; // "CURRENT" } -//AddLog_P2(LOG_LEVEL_DEBUG, PSTR("RUL: Task %s, Name %s, Value |%s|, TrigCnt %d, TrigSt %d, Source %s, Json %s"), -// rule_task.c_str(), rule_name.c_str(), rule_svalue, Rules.trigger_count[rule_set], bitRead(Rules.triggers[rule_set], Rules.trigger_count[rule_set]), event.c_str(), (str_value) ? str_value : "none"); +//AddLog_P2(LOG_LEVEL_DEBUG, PSTR("RUL: Name %s, Value |%s|, TrigCnt %d, TrigSt %d, Source %s, Json %s"), +// rule_name.c_str(), rule_svalue, Rules.trigger_count[rule_set], bitRead(Rules.triggers[rule_set], Rules.trigger_count[rule_set]), event.c_str(), (str_value) ? str_value : "none"); Rules.event_value = str_value; // Prepare %value% @@ -332,7 +565,6 @@ bool RulesRuleMatch(uint8_t rule_set, String &event, String &rule) //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("RUL: Match 1 %d"), match); - if (bitRead(Settings.rule_once, rule_set)) { if (match) { // Only allow match state changes if (!bitRead(Rules.triggers[rule_set], Rules.trigger_count[rule_set])) { @@ -419,7 +651,7 @@ bool RuleSetProcess(uint8_t rule_set, String &event_saved) //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("RUL: Event = %s, Rule = %s"), event_saved.c_str(), Settings.rules[rule_set]); - String rules = Settings.rules[rule_set]; + String rules = GetRule(rule_set); Rules.trigger_count[rule_set] = 0; int plen = 0; @@ -476,13 +708,21 @@ bool RuleSetProcess(uint8_t rule_set, String &event_saved) RulesVarReplace(commands, stemp, SettingsText(SET_MEM1 +i)); } RulesVarReplace(commands, F("%TIME%"), String(MinutesPastMidnight())); + RulesVarReplace(commands, F("%UTCTIME%"), String(UtcTime())); RulesVarReplace(commands, F("%UPTIME%"), String(MinutesUptime())); RulesVarReplace(commands, F("%TIMESTAMP%"), GetDateAndTime(DT_LOCAL)); - RulesVarReplace(commands, F("%TOPIC%"), SettingsText(SET_MQTT_TOPIC)); + RulesVarReplace(commands, F("%TOPIC%"), mqtt_topic); #if defined(USE_TIMERS) && defined(USE_SUNRISE) RulesVarReplace(commands, F("%SUNRISE%"), String(SunMinutes(0))); RulesVarReplace(commands, F("%SUNSET%"), String(SunMinutes(1))); #endif // USE_TIMERS and USE_SUNRISE +#ifdef USE_ZIGBEE + snprintf_P(stemp, sizeof(stemp), PSTR("0x%04X"), Z_GetLastDevice()); + RulesVarReplace(commands, F("%ZBDEVICE%"), String(stemp)); + RulesVarReplace(commands, F("%ZBGROUP%"), String(Z_GetLastGroup())); + RulesVarReplace(commands, F("%ZBCLUSTER%"), String(Z_GetLastCluster())); + RulesVarReplace(commands, F("%ZBENDPOINT%"), String(Z_GetLastEndpoint())); +#endif char command[commands.length() +1]; strlcpy(command, commands.c_str(), sizeof(command)); @@ -509,6 +749,9 @@ bool RuleSetProcess(uint8_t rule_set, String &event_saved) bool RulesProcessEvent(char *json_event) { + if (Rules.busy) { return false; } + + Rules.busy = true; bool serviced = false; #ifdef USE_DEBUG_DRIVER @@ -530,10 +773,13 @@ bool RulesProcessEvent(char *json_event) //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("RUL: Event %s"), event_saved.c_str()); for (uint32_t i = 0; i < MAX_RULE_SETS; i++) { - if (strlen(Settings.rules[i]) && bitRead(Settings.rule_enabled, i)) { + if (GetRuleLen(i) && bitRead(Settings.rule_enabled, i)) { if (RuleSetProcess(i, event_saved)) { serviced = true; } } } + + Rules.busy = false; + return serviced; } @@ -546,7 +792,7 @@ void RulesInit(void) { rules_flag.data = 0; for (uint32_t i = 0; i < MAX_RULE_SETS; i++) { - if (Settings.rules[i][0] == '\0') { + if (0 == GetRuleLen(i)) { bitWrite(Settings.rule_enabled, i, 0); bitWrite(Settings.rule_once, i, 0); } @@ -556,7 +802,7 @@ void RulesInit(void) void RulesEvery50ms(void) { - if (Settings.rule_enabled) { // Any rule enabled + if (Settings.rule_enabled && !Rules.busy) { // Any rule enabled char json_event[120]; if (-1 == Rules.new_power) { Rules.new_power = power; } @@ -579,9 +825,9 @@ void RulesEvery50ms(void) // Boot time SWITCHES Status for (uint32_t i = 0; i < MAX_SWITCHES; i++) { #ifdef USE_TM1638 - if ((pin[GPIO_SWT1 +i] < 99) || ((pin[GPIO_TM16CLK] < 99) && (pin[GPIO_TM16DIO] < 99) && (pin[GPIO_TM16STB] < 99))) { + if (PinUsed(GPIO_SWT1, i) || (PinUsed(GPIO_TM16CLK) && PinUsed(GPIO_TM16DIO) && PinUsed(GPIO_TM16STB))) { #else - if (pin[GPIO_SWT1 +i] < 99) { + if (PinUsed(GPIO_SWT1, i)) { #endif // USE_TM1638 snprintf_P(json_event, sizeof(json_event), PSTR("{\"" D_JSON_SWITCH "%d\":{\"Boot\":%d}}"), i +1, (SwitchState(i))); RulesProcessEvent(json_event); @@ -647,17 +893,18 @@ void RulesEvery50ms(void) rules_flag.data ^= mask; json_event[0] = '\0'; switch (i) { - case 0: strncpy_P(json_event, PSTR("{\"System\":{\"Boot\":1}}"), sizeof(json_event)); break; - case 1: snprintf_P(json_event, sizeof(json_event), PSTR("{\"Time\":{\"Initialized\":%d}}"), MinutesPastMidnight()); break; - case 2: snprintf_P(json_event, sizeof(json_event), PSTR("{\"Time\":{\"Set\":%d}}"), MinutesPastMidnight()); break; - case 3: strncpy_P(json_event, PSTR("{\"MQTT\":{\"Connected\":1}}"), sizeof(json_event)); break; - case 4: strncpy_P(json_event, PSTR("{\"MQTT\":{\"Disconnected\":1}}"), sizeof(json_event)); break; - case 5: strncpy_P(json_event, PSTR("{\"WIFI\":{\"Connected\":1}}"), sizeof(json_event)); break; - case 6: strncpy_P(json_event, PSTR("{\"WIFI\":{\"Disconnected\":1}}"), sizeof(json_event)); break; - case 7: strncpy_P(json_event, PSTR("{\"HTTP\":{\"Initialized\":1}}"), sizeof(json_event)); break; + case 0: strncpy_P(json_event, PSTR("{\"System\":{\"Init\":1}}"), sizeof(json_event)); break; + case 1: strncpy_P(json_event, PSTR("{\"System\":{\"Boot\":1}}"), sizeof(json_event)); break; + case 2: snprintf_P(json_event, sizeof(json_event), PSTR("{\"Time\":{\"Initialized\":%d}}"), MinutesPastMidnight()); break; + case 3: snprintf_P(json_event, sizeof(json_event), PSTR("{\"Time\":{\"Set\":%d}}"), MinutesPastMidnight()); break; + case 4: strncpy_P(json_event, PSTR("{\"MQTT\":{\"Connected\":1}}"), sizeof(json_event)); break; + case 5: strncpy_P(json_event, PSTR("{\"MQTT\":{\"Disconnected\":1}}"), sizeof(json_event)); break; + case 6: strncpy_P(json_event, PSTR("{\"WIFI\":{\"Connected\":1}}"), sizeof(json_event)); break; + case 7: strncpy_P(json_event, PSTR("{\"WIFI\":{\"Disconnected\":1}}"), sizeof(json_event)); break; + case 8: strncpy_P(json_event, PSTR("{\"HTTP\":{\"Initialized\":1}}"), sizeof(json_event)); break; #ifdef USE_SHUTTER - case 8: strncpy_P(json_event, PSTR("{\"SHUTTER\":{\"Moved\":1}}"), sizeof(json_event)); break; - case 9: strncpy_P(json_event, PSTR("{\"SHUTTER\":{\"Moving\":1}}"), sizeof(json_event)); break; + case 9: strncpy_P(json_event, PSTR("{\"SHUTTER\":{\"Moved\":1}}"), sizeof(json_event)); break; + case 10: strncpy_P(json_event, PSTR("{\"SHUTTER\":{\"Moving\":1}}"), sizeof(json_event)); break; #endif // USE_SHUTTER } if (json_event[0]) { @@ -675,7 +922,7 @@ uint8_t rules_xsns_index = 0; void RulesEvery100ms(void) { - if (Settings.rule_enabled && (uptime > 4)) { // Any rule enabled and allow 4 seconds start-up time for sensors (#3811) + if (Settings.rule_enabled && !Rules.busy && (uptime > 4)) { // Any rule enabled and allow 4 seconds start-up time for sensors (#3811) mqtt_data[0] = '\0'; int tele_period_save = tele_period; tele_period = 2; // Do not allow HA updates during next function call @@ -684,14 +931,14 @@ void RulesEvery100ms(void) if (strlen(mqtt_data)) { mqtt_data[0] = '{'; // {"INA219":{"Voltage":4.494,"Current":0.020,"Power":0.089} ResponseJsonEnd(); - RulesProcess(); + RulesProcessEvent(mqtt_data); } } } void RulesEverySecond(void) { - if (Settings.rule_enabled) { // Any rule enabled + if (Settings.rule_enabled && !Rules.busy) { // Any rule enabled char json_event[120]; if (RtcTime.valid) { @@ -715,7 +962,7 @@ void RulesEverySecond(void) void RulesSaveBeforeRestart(void) { - if (Settings.rule_enabled) { // Any rule enabled + if (Settings.rule_enabled && !Rules.busy) { // Any rule enabled char json_event[32]; strncpy_P(json_event, PSTR("{\"System\":{\"Save\":1}}"), sizeof(json_event)); @@ -1043,6 +1290,16 @@ bool findNextVariableValue(char * &pVarname, float &value) } else if (sVarName.equals(F("SUNSET"))) { value = SunMinutes(1); #endif +// #ifdef USE_ZIGBEE +// // } else if (sVarName.equals(F("ZBDEVICE"))) { +// // value = Z_GetLastDevice(); +// } else if (sVarName.equals(F("ZBGROUP"))) { +// value = Z_GetLastGroup(); +// } else if (sVarName.equals(F("ZBCLUSTER"))) { +// value = Z_GetLastCluster(); +// } else if (sVarName.equals(F("ZBENDPOINT"))) { +// value = Z_GetLastEndpoint(); +// #endif } else { succeed = false; } @@ -1724,9 +1981,30 @@ void RulesPreprocessCommand(char *pCommands) void CmndRule(void) { + if (0 == XdrvMailbox.index) { + char data = '\0'; + if (XdrvMailbox.data_len > 0) { // Allow show all if 0 + if (!((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 10))) { + if ('"' == XdrvMailbox.data[0]) { + data = '"'; // Save data as XdrvMailbox.data is destroyed + } else { + XdrvMailbox.data_len = 0; // Discard any additional text + } + } + } + for (uint32_t i = 1; i <= MAX_RULE_SETS; i++) { + XdrvMailbox.index = i; + XdrvMailbox.data[0] = data; // Only 0 or " + CmndRule(); + MqttPublishPrefixTopic_P(RESULT_OR_STAT, XdrvMailbox.command); + } + mqtt_data[0] = '\0'; // Disable further processing + return; + } uint8_t index = XdrvMailbox.index; if ((index > 0) && (index <= MAX_RULE_SETS)) { - if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.rules[index -1]))) { + // if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.rules[index -1]))) { // TODO postpone size calculation + if (XdrvMailbox.data_len > 0) { // TODO postpone size calculation if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 10)) { switch (XdrvMailbox.payload) { case 0: // Off @@ -1752,24 +2030,51 @@ void CmndRule(void) break; } } else { - int offset = 0; + bool append = false; if ('+' == XdrvMailbox.data[0]) { - offset = strlen(Settings.rules[index -1]); - if (XdrvMailbox.data_len < (sizeof(Settings.rules[index -1]) - offset -1)) { // Check free space - XdrvMailbox.data[0] = ' '; // Remove + and make sure at least one space is inserted - } else { - offset = -1; // Not enough space so skip it - } + XdrvMailbox.data[0] = ' '; // Remove + and make sure at least one space is inserted + append = true; } - if (offset != -1) { - strlcpy(Settings.rules[index -1] + offset, ('"' == XdrvMailbox.data[0]) ? "" : XdrvMailbox.data, sizeof(Settings.rules[index -1])); + int32_t res = SetRule(index - 1, ('"' == XdrvMailbox.data[0]) ? "" : XdrvMailbox.data, append); + if (res < 0) { + AddLog_P2(LOG_LEVEL_ERROR, PSTR("RUL: Not enough space")); } } Rules.triggers[index -1] = 0; // Reset once flag } - snprintf_P (mqtt_data, sizeof(mqtt_data), PSTR("{\"%s%d\":\"%s\",\"Once\":\"%s\",\"StopOnError\":\"%s\",\"Free\":%d,\"Rules\":\"%s\"}"), + String rule = GetRule(index - 1); + size_t rule_len = rule.length(); + if (rule_len > MAX_RULE_SIZE - 3) { + + size_t start_index = 0; // start from 0 + while (start_index < rule_len) { // until we reached end of rule + size_t last_index = start_index + MAX_RULE_SIZE - 3; // set max length to what would fit uncompressed, i.e. MAX_RULE_SIZE - 3 (first NULL + length + last NULL) + if (last_index < rule_len) { // if we didn't reach the end, try to shorten to last space character + int32_t next_index = rule.lastIndexOf(" ", last_index); + if (next_index > 0) { // if space was found and is not at the first position (i.e. we are progressing) + last_index = next_index; // shrink to the last space + } // otherwise it means there are no spaces, we need to cut somewhere even if the result cannot be entered back + } else { + last_index = rule_len; // until the end of the rule + } + AddLog_P2(LOG_LEVEL_INFO, PSTR("RUL: Rule%d %s%s"), + index, 0 == start_index ? PSTR("") : PSTR("+"), + rule.substring(start_index, last_index).c_str()); + start_index = last_index + 1; + } + + // we need to split the rule in chunks + rule = rule.substring(0, MAX_RULE_SIZE); + rule += F("..."); + } + // snprintf_P (mqtt_data, sizeof(mqtt_data), PSTR("{\"%s%d\":\"%s\",\"Once\":\"%s\",\"StopOnError\":\"%s\",\"Free\":%d,\"Rules\":\"%s\"}"), + // XdrvMailbox.command, index, GetStateText(bitRead(Settings.rule_enabled, index -1)), GetStateText(bitRead(Settings.rule_once, index -1)), + // GetStateText(bitRead(Settings.rule_stop, index -1)), sizeof(Settings.rules[index -1]) - strlen(Settings.rules[index -1]) -1, Settings.rules[index -1]); + snprintf_P (mqtt_data, sizeof(mqtt_data), PSTR("{\"%s%d\":\"%s\",\"Once\":\"%s\",\"StopOnError\":\"%s\",\"Length\":%d,\"Free\":%d,\"Rules\":\"%s\"}"), XdrvMailbox.command, index, GetStateText(bitRead(Settings.rule_enabled, index -1)), GetStateText(bitRead(Settings.rule_once, index -1)), - GetStateText(bitRead(Settings.rule_stop, index -1)), sizeof(Settings.rules[index -1]) - strlen(Settings.rules[index -1]) -1, Settings.rules[index -1]); + GetStateText(bitRead(Settings.rule_stop, index -1)), + rule_len, MAX_RULE_SIZE - GetRuleLenStorage(index - 1), + EscapeJSONString(rule.c_str()).c_str()); } } @@ -1796,8 +2101,11 @@ void CmndEvent(void) { if (XdrvMailbox.data_len > 0) { strlcpy(Rules.event_data, XdrvMailbox.data, sizeof(Rules.event_data)); +#ifdef USE_DEVICE_GROUPS + SendLocalDeviceGroupMessage(DGR_MSGTYP_UPDATE, DGR_ITEM_EVENT, XdrvMailbox.data); +#endif // USE_DEVICE_GROUPS } - ResponseCmndDone(); + if (XdrvMailbox.command) ResponseCmndDone(); } void CmndVariable(void) diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index 6f43229a9..ddb818a91 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -17,6 +17,7 @@ along with this program. If not, see . */ + #ifdef USE_SCRIPT #ifndef USE_RULES /*********************************************************************************************\ @@ -51,7 +52,9 @@ keywords if then else endif, or, and are better readable for beginners (others m #endif #define MAXNVARS MAXVARS-MAXSVARS +#ifndef MAXFILT #define MAXFILT 5 +#endif #define SCRIPT_SVARSIZE 20 #define SCRIPT_MAXSSIZE 48 #define SCRIPT_EOL '\n' @@ -60,6 +63,133 @@ keywords if then else endif, or, and are better readable for beginners (others m #define SCRIPT_MAXPERM (PMEM_SIZE)-4/sizeof(float) #define MAX_SCRIPT_SIZE MAX_RULE_SIZE*MAX_RULE_SETS + +uint32_t EncodeLightId(uint8_t relay_id); +uint32_t DecodeLightId(uint32_t hue_id); + +#ifdef USE_UNISHOX_COMPRESSION +#define USE_SCRIPT_COMPRESSION +#endif + +// solve conficting defines +// highest priority +#ifdef USE_SCRIPT_FATFS +#undef LITTLEFS_SCRIPT_SIZE +#undef EEP_SCRIPT_SIZE +#undef USE_SCRIPT_COMPRESSION +#if USE_SCRIPT_FATFS==-1 +#ifdef ESP32 +#error "script fat file option -1 currently not supported for ESP32" +#else +#pragma message "script fat file option -1 used" +#endif +#else +#pragma message "script fat file SDC option used" +#endif +#endif // USE_SCRIPT_FATFS + +// lfs on esp8266 spiffs on esp32 +#ifdef LITTLEFS_SCRIPT_SIZE +#undef EEP_SCRIPT_SIZE +#undef USE_SCRIPT_COMPRESSION +#pragma message "script little file system option used" +#endif // LITTLEFS_SCRIPT_SIZE + +// eeprom script +#ifdef EEP_SCRIPT_SIZE +#undef USE_SCRIPT_COMPRESSION +#ifdef USE_24C256 +#pragma message "script 24c256 file option used" +#else +//#warning "EEP_SCRIPT_SIZE also needs USE_24C256" +#pragma message "internal eeprom script buffer used" +//#define USE_24C256 +#endif +#endif // EEP_SCRIPT_SIZE + +// compression last option before default +#ifdef USE_SCRIPT_COMPRESSION +#pragma message "script compression option used" +#endif // USE_UNISHOX_COMPRESSION + + +#ifdef USE_SCRIPT_COMPRESSION +#include + +#define SCRIPT_COMPRESS compressor.unishox_compress +#define SCRIPT_DECOMPRESS compressor.unishox_decompress +#ifndef UNISHOXRSIZE +#define UNISHOXRSIZE 2560 +#endif +#endif // USE_SCRIPT_COMPRESSION + +#ifdef USE_SCRIPT_TIMER +#include +Ticker Script_ticker1; +Ticker Script_ticker2; +Ticker Script_ticker3; +Ticker Script_ticker4; + +void Script_ticker1_end(void) { + Script_ticker1.detach(); + Run_Scripter(">ti1", 4,0); +} +void Script_ticker2_end(void) { + Script_ticker2.detach(); + Run_Scripter(">ti2", 4,0); +} +void Script_ticker3_end(void) { + Script_ticker3.detach(); + Run_Scripter(">ti3", 4,0); +} +void Script_ticker4_end(void) { + Script_ticker4.detach(); + Run_Scripter(">ti4", 4,0); +} +#endif + + +#if defined(LITTLEFS_SCRIPT_SIZE) || (USE_SCRIPT_FATFS==-1) +#ifdef ESP32 +#include "FS.h" +#include "SPIFFS.h" +#else +#include +#endif +FS *fsp; +#endif // LITTLEFS_SCRIPT_SIZE + + +#ifdef LITTLEFS_SCRIPT_SIZE +void SaveFile(const char *name,const uint8_t *buf,uint32_t len) { + File file = fsp->open(name, "w"); + if (!file) return; + file.write(buf, len); + file.close(); +} + +#define FORMAT_SPIFFS_IF_FAILED true +uint8_t fs_mounted=0; + +void LoadFile(const char *name,uint8_t *buf,uint32_t len) { + if (!fs_mounted) { +#ifdef ESP32 + if(!SPIFFS.begin(FORMAT_SPIFFS_IF_FAILED)){ +#else + if(!fsp->begin()){ +#endif + //Serial.println("SPIFFS Mount Failed"); + return; + } + fs_mounted=1; + } + File file = fsp->open(name, "r"); + if (!file) return; + file.read(buf, len); + file.close(); +} +#endif // LITTLEFS_SCRIPT_SIZE + // offsets epoch readings by 1.1.2019 00:00:00 to fit into float with second resolution #define EPOCH_OFFSET 1546300800 @@ -67,19 +197,56 @@ enum {OPER_EQU=1,OPER_PLS,OPER_MIN,OPER_MUL,OPER_DIV,OPER_PLSEQU,OPER_MINEQU,OPE enum {SCRIPT_LOGLEVEL=1,SCRIPT_TELEPERIOD}; #ifdef USE_SCRIPT_FATFS + +#if USE_SCRIPT_FATFS>=0 #include #include +#ifdef ESP32 +FS *fsp; +#else +SDClass *fsp; +#endif +#endif + +#ifndef ESP32 +// esp8266 + +#if USE_SCRIPT_FATFS>=0 +// old fs +#undef FILE_WRITE +#define FILE_WRITE (sdfat::O_READ | sdfat::O_WRITE | sdfat::O_CREAT) +#define FILE_APPEND (sdfat::O_READ | sdfat::O_WRITE | sdfat::O_CREAT | sdfat::O_APPEND) + +#else +// new fs +#undef FILE_WRITE +#define FILE_WRITE "w" +#undef FILE_READ +#define FILE_READ "r" +#undef FILE_APPEND +#define FILE_APPEND "a" +#endif + +#endif // USE_SCRIPT_FATFS>=0 + + #ifndef FAT_SCRIPT_SIZE #define FAT_SCRIPT_SIZE 4096 #endif + +#ifdef ESP32 +#undef FAT_SCRIPT_NAME +#define FAT_SCRIPT_NAME "/script.txt" +#else +#undef FAT_SCRIPT_NAME #define FAT_SCRIPT_NAME "script.txt" -#if USE_LONG_FILE_NAMES==1 -#warning ("FATFS long filenames not supported"); #endif + #if USE_STANDARD_SPI_LIBRARY==0 #warning ("FATFS standard spi should be used"); #endif -#endif + +#endif // USE_SCRIPT_FATFS #ifdef SUPPORT_MQTT_EVENT #include // Import LinkedList library @@ -99,7 +266,11 @@ extern VButton *buttons[MAXBUTTONS]; #endif typedef union { +#ifdef USE_SCRIPT_GLOBVARS + uint16_t data; +#else uint8_t data; +#endif struct { uint8_t is_string : 1; // string or number uint8_t is_permanent : 1; @@ -109,6 +280,9 @@ typedef union { uint8_t settable : 1; uint8_t is_filter : 1; uint8_t constant : 1; +#ifdef USE_SCRIPT_GLOBVARS + uint8_t global : 1; +#endif }; } SCRIPT_TYPE; @@ -138,6 +312,32 @@ typedef union { }; } FILE_FLAGS; +typedef union { + uint8_t data; + struct { + uint8_t nutu8 : 1; + uint8_t nutu7 : 1; + uint8_t nutu6 : 1; + uint8_t nutu5 : 1; + uint8_t nutu4 : 1; + uint8_t nutu3 : 1; + uint8_t udp_connected : 1; + uint8_t udp_used : 1; + }; +} UDP_FLAGS; + + +#define NUM_RES 0xfe +#define STR_RES 0xfd +#define VAR_NV 0xff + +#define NTYPE 0 +#define STYPE 0x80 + +#ifndef FLT_MAX +#define FLT_MAX 99999999 +#endif + #define SFS_MAX 4 // global memory struct SCRIPT_MEM { @@ -164,18 +364,41 @@ struct SCRIPT_MEM { uint8_t max_ssize; uint8_t script_loglevel; uint8_t flags; + uint8_t si_num; + uint8_t siro_num; + char *last_index_string; + #ifdef USE_SCRIPT_FATFS File files[SFS_MAX]; FILE_FLAGS file_flags[SFS_MAX]; uint8_t script_sd_found; char flink[2][14]; #endif +#ifdef USE_SCRIPT_GLOBVARS + UDP_FLAGS udp_flags; +#endif } glob_script_mem; + +#ifdef USE_SCRIPT_GLOBVARS +IPAddress last_udp_ip; +WiFiUDP Script_PortUdp; + +#ifndef USE_DEVICE_GROUPS +char * IPAddressToString(const IPAddress& ip_address) { + static char buffer[16]; + sprintf_P(buffer, PSTR("%u.%u.%u.%u"), ip_address[0], ip_address[1], ip_address[2], ip_address[3]); + return buffer; +} +#endif +#endif + int16_t last_findex; +int16_t last_sindex; uint8_t tasm_cmd_activ=0; uint8_t fast_script=0; +uint8_t glob_script=0; uint32_t script_lastmillis; @@ -193,7 +416,7 @@ void ScriptEverySecond(void) { if (bitRead(Settings.rule_enabled, 0)) { struct T_INDEX *vtp=glob_script_mem.type; - float delta=(millis()-script_lastmillis)/1000; + float delta=(millis()-script_lastmillis)/1000.0; script_lastmillis=millis(); for (uint8_t count=0; count -#define EEPROM_ADDRESS 0x50 -// strange bug, crashes with powers of 2 ??? 4096 crashes -#ifndef EEP_SCRIPT_SIZE -#define EEP_SCRIPT_SIZE 4095 -#endif +#define EEP_WRITE(A,B,C) eeprom_writeBytes(A,B,(uint8_t*)C); +#define EEP_READ(A,B,C) eeprom_readBytes(A,B,(uint8_t*)C); -static Eeprom24C128_256 eeprom(EEPROM_ADDRESS); -// eeprom.writeBytes(address, length, buffer); -#define EEP_WRITE(A,B,C) eeprom.writeBytes(A,B,(uint8_t*)C); -// eeprom.readBytes(address, length, buffer); -#define EEP_READ(A,B,C) eeprom.readBytes(A,B,(uint8_t*)C); -#endif -#endif - #define SCRIPT_SKIP_SPACES while (*lp==' ' || *lp=='\t') lp++; #define SCRIPT_SKIP_EOL while (*lp==SCRIPT_EOL) lp++; @@ -283,7 +492,7 @@ char *script; if (*lp==';') goto next_line; if (init) { // init section - if (*lp=='>') { + if (*lp=='>' || !*lp) { init=0; break; } @@ -312,6 +521,16 @@ char *script; } else { vtypes[vars].bits.is_autoinc=0; } + +#ifdef USE_SCRIPT_GLOBVARS + if (*lp=='g' && *(lp+1)==':') { + lp+=2; + vtypes[vars].bits.global=1; + glob_script_mem.udp_flags.udp_used = 1; + } else { + vtypes[vars].bits.global=0; + } +#endif if ((*lp=='m' || *lp=='M') && *(lp+1)==':') { uint8_t flg=*lp; lp+=2; @@ -554,7 +773,13 @@ char *script; #ifdef USE_SCRIPT_FATFS if (!glob_script_mem.script_sd_found) { + +#if USE_SCRIPT_FATFS>=0 + fsp=&SD; if (SD.begin(USE_SCRIPT_FATFS)) { +#else + if (fsp->begin()) { +#endif glob_script_mem.script_sd_found=1; } else { glob_script_mem.script_sd_found=0; @@ -573,35 +798,136 @@ char *script; // store start of actual program here glob_script_mem.scriptptr=lp-1; glob_script_mem.scriptptr_bu=glob_script_mem.scriptptr; + +#ifdef USE_SCRIPT_GLOBVARS + if (glob_script_mem.udp_flags.udp_used) { + Script_Init_UDP(); + glob_script=Run_Scripter(">G",-2,0); + } +#endif + return 0; } +#ifdef USE_SCRIPT_GLOBVARS +#define SCRIPT_UDP_BUFFER_SIZE 128 +#define SCRIPT_UDP_PORT 1999 +IPAddress script_udp_remote_ip; + +void Script_Stop_UDP(void) { + Script_PortUdp.flush(); + Script_PortUdp.stop(); + glob_script_mem.udp_flags.udp_connected = 0; +} + +void Script_Init_UDP() { + if (global_state.network_down) return; + if (glob_script_mem.udp_flags.udp_connected) return; + + if (Script_PortUdp.beginMulticast(WiFi.localIP(), IPAddress(239,255,255,250), SCRIPT_UDP_PORT)) { + AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_UPNP "SCRIPT UDP started")); + glob_script_mem.udp_flags.udp_connected = 1; + } else { + AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_UPNP "SCRIPT UDP failed")); + glob_script_mem.udp_flags.udp_connected = 0; + } +} +void Script_PollUdp(void) { + if (global_state.network_down) return; + if (!glob_script_mem.udp_flags.udp_used) return; + if (glob_script_mem.udp_flags.udp_connected ) { + while (Script_PortUdp.parsePacket()) { + char packet_buffer[SCRIPT_UDP_BUFFER_SIZE]; + int32_t len = Script_PortUdp.read(packet_buffer, SCRIPT_UDP_BUFFER_SIZE -1); + packet_buffer[len] = 0; + script_udp_remote_ip = Script_PortUdp.remoteIP(); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("UDP: Packet %s - %d - %s"), packet_buffer, len, script_udp_remote_ip.toString().c_str()); + char *lp=packet_buffer; + if (!strncmp(lp,"=>",2)) { + lp+=2; + char *cp=strchr(lp,'='); + if (cp) { + char vnam[32]; + for (uint32_t count=0; countG",2,0); + } + } + } + } + optimistic_yield(100); + } + } else { + Script_Init_UDP(); + } +} + +void script_udp_sendvar(char *vname,float *fp,char *sp) { + if (!glob_script_mem.udp_flags.udp_used) return; + if (!glob_script_mem.udp_flags.udp_connected) return; + + char sbuf[SCRIPT_MAXSSIZE+4]; + strcpy(sbuf,"=>"); + strcat(sbuf,vname); + strcat(sbuf,"="); + if (fp) { + char flstr[16]; + dtostrfd(*fp,8,flstr); + strcat(sbuf,flstr); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("num var updated - %s"),sbuf); + } else { + strcat(sbuf,sp); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("string var updated - %s"),sbuf); + } + Script_PortUdp.beginPacket(IPAddress(239,255,255,250), SCRIPT_UDP_PORT); + // Udp.print(String("RET UC: ") + String(recv_Packet)); + Script_PortUdp.write((const uint8_t*)sbuf,strlen(sbuf)); + Script_PortUdp.endPacket(); +} + +#endif + #ifdef USE_LIGHT #ifdef USE_WS2812 -void ws2812_set_array(float *array ,uint8_t len) { +void ws2812_set_array(float *array ,uint32_t len, uint32_t offset) { Ws2812ForceSuspend(); - for (uint8_t cnt=0;cntSettings.light_pixels) break; + for (uint32_t cnt=0;cntSettings.light_pixels) break; uint32_t col=array[cnt]; - Ws2812SetColor(cnt+1,col>>16,col>>8,col,0); + Ws2812SetColor(index+1,col>>16,col>>8,col,0); } Ws2812ForceUpdate(); } #endif #endif -#define NUM_RES 0xfe -#define STR_RES 0xfd -#define VAR_NV 0xff -#define NTYPE 0 -#define STYPE 0x80 - -#ifndef FLT_MAX -#define FLT_MAX 99999999 -#endif float median_array(float *array,uint8_t len) { uint8_t ind[len]; @@ -631,13 +957,14 @@ float median_array(float *array,uint8_t len) { } -float *Get_MFAddr(uint8_t index,uint8_t *len) { +float *Get_MFAddr(uint8_t index,uint8_t *len,uint8_t *ipos) { *len=0; uint8_t *mp=(uint8_t*)glob_script_mem.mfilt; for (uint8_t count=0; countnumvals&0x7f; + if (ipos) *ipos=mflp->index; return mflp->rbuff; } mp+=sizeof(struct M_FILT)+((mflp->numvals&0x7f)-1)*sizeof(float); @@ -829,6 +1156,87 @@ if (hsv.S == 0) { #endif //#endif +#ifdef USE_ANGLE_FUNC +uint32_t pulse_time_hl; +uint32_t pulse_time_lh; +uint32_t pulse_ltime_hl; +uint32_t pulse_ltime_lh; +uint8_t pt_pin; + +void MP_Timer(void) ICACHE_RAM_ATTR; + +#define MPT_DEBOUNCE 10 + +void MP_Timer(void) { + uint32_t level = digitalRead(pt_pin&0x3f); + uint32_t ms = millis(); + uint32_t time; + if (level) { + // rising edge + pulse_ltime_lh = ms; + time = ms - pulse_ltime_hl; + if (time>MPT_DEBOUNCE) pulse_time_hl = time; + } else { + // falling edge + pulse_ltime_hl = ms; + time = ms - pulse_ltime_lh; + if (time>MPT_DEBOUNCE) pulse_time_lh = time; + } +} + +uint32_t MeasurePulseTime(int32_t in) { + if (in >= 0) { + // define pin; + pt_pin = in; + pinMode(pt_pin&0x3f,INPUT_PULLUP); + attachInterrupt(pt_pin&0x3f, MP_Timer, CHANGE); + pulse_ltime_lh = millis(); + pulse_ltime_hl = millis(); + return 0; + } + uint32_t ptime; + if (in==-1) { + ptime = pulse_time_lh; + pulse_time_lh = 0; + } else { + ptime = pulse_time_hl; + pulse_time_hl = 0; + } + return ptime; +} +#endif // USE_ANGLE_FUNC + +#ifdef USE_SCRIPT_GLOBVARS +uint32_t match_vars(char *dvnam, float **fp, char **sp, uint32_t *ind) { + uint16_t olen=strlen(dvnam); + struct T_INDEX *vtp=glob_script_mem.type; + for (uint32_t count=0; count ff=nothing found, fe=constant number,fd = constant string else bit 7 => 80 = string, 0 = number // no flash strings here for performance reasons!!! char *isvar(char *lp, uint8_t *vtype,struct T_INDEX *tind,float *fp,char *sp,JsonObject *jo) { @@ -920,6 +1328,7 @@ char *isvar(char *lp, uint8_t *vtype,struct T_INDEX *tind,float *fp,char *sp,Jso strcpy (dvnam,vname); uint8_t olen=len; last_findex=-1; + last_sindex=-1; char *ja=strchr(dvnam,'['); if (ja) { *ja=0; @@ -962,10 +1371,12 @@ char *isvar(char *lp, uint8_t *vtype,struct T_INDEX *tind,float *fp,char *sp,Jso if (jo) { // look for json input + char jvname[32]; + strcpy(jvname,vname); const char* str_value; uint8_t aindex; String vn; - char *ja=strchr(vname,'['); + char *ja=strchr(jvname,'['); if (ja) { // json array *ja=0; @@ -978,7 +1389,7 @@ char *isvar(char *lp, uint8_t *vtype,struct T_INDEX *tind,float *fp,char *sp,Jso aindex--; } if (jo->success()) { - char *subtype=strchr(vname,'#'); + char *subtype=strchr(jvname,'#'); char *subtype2; if (subtype) { *subtype=0; @@ -989,7 +1400,7 @@ char *isvar(char *lp, uint8_t *vtype,struct T_INDEX *tind,float *fp,char *sp,Jso *subtype2++; } } - vn=vname; + vn=jvname; str_value = (*jo)[vn]; if ((*jo)[vn].success()) { if (subtype) { @@ -1119,6 +1530,28 @@ chknext: } } } +#ifdef ESP32 + if (!strncmp(vname,"core",4)) { + fvar=xPortGetCoreID(); + goto exit; + } +#ifdef USE_SCRIPT_TASK + if (!strncmp(vname,"ct(",3)) { + lp+=3; + lp=GetNumericResult(lp,OPER_EQU,&fvar,0); + while (*lp==' ') lp++; + float fvar1; + lp=GetNumericResult(lp,OPER_EQU,&fvar1,0); + while (*lp==' ') lp++; + float fvar2; + lp=GetNumericResult(lp,OPER_EQU,&fvar2,0); + lp++; + fvar=scripter_create_task(fvar,fvar1,fvar2); + len=0; + goto exit; + } +#endif +#endif break; case 'd': if (!strncmp(vname,"day",3)) { @@ -1131,21 +1564,87 @@ chknext: fvar=UtcTime()-(uint32_t)EPOCH_OFFSET; goto exit; } +#ifdef USE_ENERGY_SENSOR + if (!strncmp(vname,"enrg[",5)) { + lp+=5; + lp=GetNumericResult(lp,OPER_EQU,&fvar,0); + while (*lp==' ') lp++; + switch ((uint32_t)fvar) { + case 0: + fvar=Energy.total; + break; + case 1: + fvar=Energy.voltage[0]; + break; + case 2: + fvar=Energy.voltage[1]; + break; + case 3: + fvar=Energy.voltage[2]; + break; + case 4: + fvar=Energy.current[0]; + break; + case 5: + fvar=Energy.current[1]; + break; + case 6: + fvar=Energy.current[2]; + break; + case 7: + fvar=Energy.active_power[0]; + break; + case 8: + fvar=Energy.active_power[1]; + break; + case 9: + fvar=Energy.active_power[2]; + break; + + default: + fvar=99999; + break; + } + len=0; + lp++; + goto exit; + } +#endif //USE_ENERGY_SENSOR break; -#ifdef USE_SCRIPT_FATFS case 'f': +//#define DEBUG_FS +#ifdef USE_SCRIPT_FATFS if (!strncmp(vname,"fo(",3)) { lp+=3; char str[SCRIPT_MAXSSIZE]; lp=GetStringResult(lp,OPER_EQU,str,0); while (*lp==' ') lp++; - lp=GetNumericResult(lp,OPER_EQU,&fvar,0); - uint8_t mode=fvar; + uint8_t mode=0; + if ((*lp=='r') || (*lp=='w') || (*lp=='a')) { + switch (*lp) { + case 'r': + mode=0; + break; + case 'w': + mode=1; + break; + case 'a': + mode=2; + break; + } + lp++; + } else { + lp=GetNumericResult(lp,OPER_EQU,&fvar,0); + mode=fvar; + } fvar=-1; for (uint8_t cnt=0;cntopen(str,FILE_READ); if (glob_script_mem.files[cnt].isDirectory()) { glob_script_mem.files[cnt].rewindDirectory(); glob_script_mem.file_flags[cnt].is_dir=1; @@ -1153,7 +1652,19 @@ chknext: glob_script_mem.file_flags[cnt].is_dir=0; } } - else glob_script_mem.files[cnt]=SD.open(str,FILE_WRITE); + else { + if (mode==1) { + glob_script_mem.files[cnt]=fsp->open(str,FILE_WRITE); +#ifdef DEBUG_FS + AddLog_P2(LOG_LEVEL_INFO,PSTR("open file for write %d"),cnt); +#endif + } else { + glob_script_mem.files[cnt]=fsp->open(str,FILE_APPEND); +#ifdef DEBUG_FS + AddLog_P2(LOG_LEVEL_INFO,PSTR("open file for append %d"),cnt); +#endif + } + } if (glob_script_mem.files[cnt]) { fvar=cnt; glob_script_mem.file_flags[cnt].is_open=1; @@ -1170,10 +1681,15 @@ chknext: if (!strncmp(vname,"fc(",3)) { lp+=3; lp=GetNumericResult(lp,OPER_EQU,&fvar,0); - uint8_t ind=fvar; - if (ind>=SFS_MAX) ind=SFS_MAX-1; - glob_script_mem.files[ind].close(); - glob_script_mem.file_flags[ind].is_open=0; + if (fvar>=0) { + uint8_t ind=fvar; + if (ind>=SFS_MAX) ind=SFS_MAX-1; +#ifdef DEBUG_FS + AddLog_P2(LOG_LEVEL_INFO,PSTR("closing file %d"),ind); +#endif + glob_script_mem.files[ind].close(); + glob_script_mem.file_flags[ind].is_open=0; + } fvar=0; lp++; len=0; @@ -1241,7 +1757,13 @@ chknext: File entry=glob_script_mem.files[find].openNextFile(); if (entry) { if (!reject((char*)entry.name())) { - strcpy(str,entry.name()); + char *ep=(char*)entry.name(); + if (*ep=='/') ep++; + char *lcp = strrchr(ep,'/'); + if (lcp) { + ep=lcp+1; + } + strcpy(str,ep); entry.close(); break; } @@ -1279,18 +1801,47 @@ chknext: lp+=3; char str[glob_script_mem.max_ssize+1]; lp=GetStringResult(lp,OPER_EQU,str,0); - SD.remove(str); + fsp->remove(str); lp++; len=0; goto exit; } +#if defined(ESP32) && defined(USE_WEBCAM) + if (!strncmp(vname,"fwp(",4)) { + lp+=4; + lp=GetNumericResult(lp,OPER_EQU,&fvar,0); + while (*lp==' ') lp++; + float fvar1; + lp=GetNumericResult(lp,OPER_EQU,&fvar1,0); + uint8_t ind=fvar1; + if (ind>=SFS_MAX) ind=SFS_MAX-1; + if (glob_script_mem.file_flags[ind].is_open) { + uint8_t *buff; + float maxps=WcGetPicstore(-1,0); + if (fvar<1 || fvar>maxps) fvar=1; + uint32_t len=WcGetPicstore(fvar-1, &buff); + if (len) { + //glob_script_mem.files[ind].seek(0,SeekEnd); + fvar=glob_script_mem.files[ind].write(buff,len); + } else { + fvar=0; + } + //AddLog_P2(LOG_LEVEL_INFO, PSTR("picture save: %d"), len); + } else { + fvar=0; + } + lp++; + len=0; + goto exit; + } +#endif #ifdef USE_SCRIPT_FATFS_EXT if (!strncmp(vname,"fe(",3)) { lp+=3; char str[glob_script_mem.max_ssize+1]; lp=GetStringResult(lp,OPER_EQU,str,0); // execute script - File ef=SD.open(str); + File ef=fsp->open(str,FILE_READ); if (ef) { uint16_t fsiz=ef.size(); if (fsiz<2048) { @@ -1312,7 +1863,7 @@ chknext: lp+=4; char str[glob_script_mem.max_ssize+1]; lp=GetStringResult(lp,OPER_EQU,str,0); - fvar=SD.mkdir(str); + fvar=fsp->mkdir(str); lp++; len=0; goto exit; @@ -1321,7 +1872,7 @@ chknext: lp+=4; char str[glob_script_mem.max_ssize+1]; lp=GetStringResult(lp,OPER_EQU,str,0); - fvar=SD.rmdir(str); + fvar=fsp->rmdir(str); lp++; len=0; goto exit; @@ -1330,13 +1881,13 @@ chknext: lp+=3; char str[glob_script_mem.max_ssize+1]; lp=GetStringResult(lp,OPER_EQU,str,0); - if (SD.exists(str)) fvar=1; + if (fsp->exists(str)) fvar=1; else fvar=0; lp++; len=0; goto exit; } -#endif +#endif // USE_SCRIPT_FATFS_EXT if (!strncmp(vname,"fl1(",4) || !strncmp(vname,"fl2(",4) ) { uint8_t lknum=*(lp+2)&3; lp+=4; @@ -1354,12 +1905,19 @@ chknext: //card_init(); goto exit; } - break; - #endif //USE_SCRIPT_FATFS + if (!strncmp(vname,"freq",4)) { +#ifdef ESP32 + fvar=getCpuFrequencyMhz(); +#else + fvar=ESP.getCpuFreqMHz(); +#endif + goto exit; + } + break; case 'g': if (!strncmp(vname,"gtmp",4)) { - fvar=global_temperature; + fvar=global_temperature_celsius; goto exit; } if (!strncmp(vname,"ghum",4)) { @@ -1367,13 +1925,27 @@ chknext: goto exit; } if (!strncmp(vname,"gprs",4)) { - fvar=global_pressure; + fvar=global_pressure_hpa; goto exit; } if (!strncmp(vname,"gtopic",6)) { if (sp) strlcpy(sp,SettingsText(SET_MQTT_GRP_TOPIC),glob_script_mem.max_ssize); goto strexit; } + +#ifdef SCRIPT_GET_HTTPS_JP + if (!strncmp(vname,"gjp(",4)) { + char host[SCRIPT_MAXSSIZE]; + lp=GetStringResult(lp+4,OPER_EQU,host,0); + SCRIPT_SKIP_SPACES + char path[SCRIPT_MAXSSIZE]; + lp=GetStringResult(lp,OPER_EQU,path,0); + fvar=call2https(host,path); + lp++; + len=0; + goto exit; + } +#endif break; case 'h': if (!strncmp(vname,"hours",5)) { @@ -1381,7 +1953,7 @@ chknext: goto exit; } if (!strncmp(vname,"heap",4)) { - fvar=ESP.getFreeHeap(); + fvar=ESP_getFreeHeap(); goto exit; } if (!strncmp(vname,"hn(",3)) { @@ -1428,6 +2000,7 @@ chknext: //#endif #endif break; +#define MAX_SARRAY_NUM 32 case 'i': if (!strncmp(vname,"int(",4)) { lp=GetNumericResult(lp+4,OPER_EQU,&fvar,0); @@ -1436,8 +2009,93 @@ chknext: len=0; goto exit; } + if (!strncmp(vname,"is(",3)) { + lp=GetNumericResult(lp+3,OPER_EQU,&fvar,0); + SCRIPT_SKIP_SPACES + if (*lp!='"') { + break; + } + lp++; + + if (glob_script_mem.si_num>0 && glob_script_mem.last_index_string) { + free(glob_script_mem.last_index_string); + } + char *sstart=lp; + uint8_t slen=0; + for (uint32_t cnt=0; cnt<256; cnt++) { + if (*lp=='\n' || *lp=='"' || *lp==0) { + lp++; + if (cnt>0 && !slen) { + slen++; + } + glob_script_mem.siro_num=slen; + break; + } + if (*lp=='|') { + slen++; + } + lp++; + } + + glob_script_mem.si_num = fvar; + if (glob_script_mem.si_num>0) { + if (glob_script_mem.si_num>MAX_SARRAY_NUM) { + glob_script_mem.si_num=MAX_SARRAY_NUM; + } + + glob_script_mem.last_index_string=(char*)calloc(glob_script_mem.max_ssize*glob_script_mem.si_num,1); + for (uint32_t cnt=0; cntglob_script_mem.si_num) { + fvar=glob_script_mem.si_num; + } + strlcpy(str,glob_script_mem.last_index_string+(index*glob_script_mem.max_ssize),glob_script_mem.max_ssize); + } + } + lp++; + if (sp) strlcpy(sp,str,glob_script_mem.max_ssize); + len=0; + goto strexit; + } break; case 'l': + if (!strncmp(vname,"lip",3)) { + if (sp) strlcpy(sp,(const char*)WiFi.localIP().toString().c_str(),glob_script_mem.max_ssize); + goto strexit; + } +#ifdef USE_SCRIPT_GLOBVARS + if (!strncmp(vname,"luip",4)) { + if (sp) strlcpy(sp,IPAddressToString(last_udp_ip),glob_script_mem.max_ssize); + goto strexit; + } +#endif if (!strncmp(vname,"loglvl",6)) { fvar=glob_script_mem.script_loglevel; tind->index=SCRIPT_LOGLEVEL; @@ -1462,6 +2120,15 @@ chknext: len=0; goto exit; } +#ifdef USE_ANGLE_FUNC + if (!strncmp(vname,"mpt(",4)) { + lp=GetNumericResult(lp+4,OPER_EQU,&fvar,0); + fvar=MeasurePulseTime(fvar); + lp++; + len=0; + goto exit; + } +#endif if (!strncmp(vname,"micros",6)) { fvar=micros(); goto exit; @@ -1527,6 +2194,22 @@ chknext: len=0; goto exit; } +#ifdef USE_MORITZ + if (!strncmp(vname,"mo(",3)) { + float fvar1; + lp=GetNumericResult(lp+3,OPER_EQU,&fvar1,0); + SCRIPT_SKIP_SPACES + float fvar2; + lp=GetNumericResult(lp,OPER_EQU,&fvar2,0); + SCRIPT_SKIP_SPACES + char rbuff[64]; + fvar=mo_getvars(fvar1,fvar2,rbuff); + lp++; + if (sp) strlcpy(sp,rbuff,glob_script_mem.max_ssize); + len=0; + goto strexit; + } +#endif break; case 'p': if (!strncmp(vname,"pin[",4)) { @@ -1539,7 +2222,15 @@ chknext: } if (!strncmp(vname,"pn[",3)) { GetNumericResult(vname+3,OPER_EQU,&fvar,0); - fvar=pin[(uint8_t)fvar]; + fvar=Pin(fvar); + // skip ] bracket + len++; + goto exit; + } + if (!strncmp(vname,"pn[",3)) { + GetNumericResult(vname+3,OPER_EQU,&fvar,0); +// fvar=pin_gpio[(uint8_t)fvar]; + fvar=Pin(fvar); // skip ] bracket len++; goto exit; @@ -1547,17 +2238,32 @@ chknext: if (!strncmp(vname,"pd[",3)) { GetNumericResult(vname+3,OPER_EQU,&fvar,0); uint8_t gpiopin=fvar; +/* for (uint8_t i=0;i 0)) { + fvar = gpio_pin[gpiopin]; + // skip ] bracket + len++; + goto exit; + } fvar=999; goto exit; } +#ifdef ESP32 + if (!strncmp(vname,"pheap",5)) { + fvar=ESP.getFreePsram(); + goto exit; + } +#endif if (!strncmp(vname,"prefix1",7)) { if (sp) strlcpy(sp,SettingsText(SET_MQTTPREFIX1),glob_script_mem.max_ssize); goto strexit; @@ -1580,7 +2286,7 @@ chknext: lp=GetNumericResult(lp,OPER_EQU,&fvar2,0); lp++; //fvar=pow(fvar1,fvar2); - fvar=FastPrecisePow(fvar1,fvar2); + fvar=FastPrecisePowf(fvar1,fvar2); len=0; goto exit; } @@ -1610,6 +2316,19 @@ chknext: fvar=glob_script_mem.script_mem_size+(glob_script_mem.script_size)+(PMEM_SIZE); goto exit; } + if (!strncmp(vname,"rnd(",4)) { + // tasmota switch state + GetNumericResult(vname+4,OPER_EQU,&fvar,0); + if (fvar<0) { + randomSeed(-fvar); + fvar=0; + } else { + fvar=random(fvar); + } + // skip ] bracket + len++; + goto exit; + } break; case 's': if (!strncmp(vname,"secs",4)) { @@ -1704,6 +2423,19 @@ chknext: len=0; goto strexit; } +#ifdef ESP32 + if (!strncmp(vname,"sf(",3)) { + lp+=2; + lp=GetNumericResult(lp,OPER_EQU,&fvar,0); + if (fvar<80) fvar=80; + if (fvar>240) fvar=240; + setCpuFrequencyMhz(fvar); + fvar=getCpuFrequencyMhz(); + lp++; + len=0; + goto exit; + } +#endif #if defined(USE_TIMERS) && defined(USE_SUNRISE) if (!strncmp(vname,"sunrise",7)) { fvar=SunMinutes(0); @@ -1746,7 +2478,17 @@ chknext: goto exit; } #endif -#ifdef USE_SML_SCRIPT_CMD + +#if defined(USE_SML_M) && defined (USE_SML_SCRIPT_CMD) + if (!strncmp(vname,"sml[",4)) { + lp+=4; + lp=GetNumericResult(lp,OPER_EQU,&fvar,0); + SCRIPT_SKIP_SPACES + fvar=SML_GetVal(fvar); + lp++; + len=0; + goto exit; + } if (!strncmp(vname,"sml(",4)) { lp+=4; float fvar1; @@ -1808,6 +2550,41 @@ chknext: if (sp) strlcpy(sp,SettingsText(SET_MQTT_TOPIC),glob_script_mem.max_ssize); goto strexit; } +#ifdef USE_SCRIPT_TIMER + if (!strncmp(vname,"ts1(",4)) { + lp=GetNumericResult(lp+4,OPER_EQU,&fvar,0); + if (fvar<10) fvar=10; + Script_ticker1.attach_ms(fvar, Script_ticker1_end); + lp++; + len=0; + goto exit; + } + if (!strncmp(vname,"ts2(",4)) { + lp=GetNumericResult(lp+4,OPER_EQU,&fvar,0); + if (fvar<10) fvar=10; + Script_ticker2.attach_ms(fvar, Script_ticker2_end); + lp++; + len=0; + goto exit; + } + if (!strncmp(vname,"ts3(",4)) { + lp=GetNumericResult(lp+4,OPER_EQU,&fvar,0); + if (fvar<10) fvar=10; + Script_ticker3.attach_ms(fvar, Script_ticker3_end); + lp++; + len=0; + goto exit; + } + if (!strncmp(vname,"ts4(",4)) { + lp=GetNumericResult(lp+4,OPER_EQU,&fvar,0); + if (fvar<10) fvar=10; + Script_ticker4.attach_ms(fvar, Script_ticker4_end); + lp++; + len=0; + goto exit; + } +#endif // USE_SCRIPT_TIMER + #ifdef USE_DISPLAY #ifdef USE_TOUCH_BUTTONS if (!strncmp(vname,"tbut[",5)) { @@ -1858,6 +2635,67 @@ chknext: break; case 'w': +#if defined(ESP32) && defined(USE_WEBCAM) + if (!strncmp(vname,"wc(",3)) { + lp+=3; + float fvar1; + lp=GetNumericResult(lp,OPER_EQU,&fvar1,0); + SCRIPT_SKIP_SPACES + switch ((uint32)fvar1) { + case 0: + { float fvar2; + lp=GetNumericResult(lp,OPER_EQU,&fvar2,0); + fvar=WcSetup(fvar2); + } + break; + case 1: + { float fvar2; + lp=GetNumericResult(lp,OPER_EQU,&fvar2,0); + fvar=WcGetFrame(fvar2); + } + break; + case 2: + { float fvar2,fvar3; + lp=GetNumericResult(lp,OPER_EQU,&fvar2,0); + SCRIPT_SKIP_SPACES + lp=GetNumericResult(lp,OPER_EQU,&fvar3,0); + fvar=WcSetOptions(fvar2,fvar3); + } + break; + case 3: + fvar=WcGetWidth(); + break; + case 4: + fvar=WcGetHeight(); + break; + case 5: + { float fvar2; + lp=GetNumericResult(lp,OPER_EQU,&fvar2,0); + fvar=WcSetStreamserver(fvar2); + } + break; + case 6: + { float fvar2; + lp=GetNumericResult(lp,OPER_EQU,&fvar2,0); + fvar=WcSetMotionDetect(fvar2); + } + break; +#ifdef USE_FACE_DETECT + case 7: + { float fvar2; + lp=GetNumericResult(lp,OPER_EQU,&fvar2,0); + fvar=WcSetFaceDetect(fvar2); + } + break; +#endif + default: + fvar=0; + } + lp++; + len=0; + goto exit; + } +#endif //ESP32, USE_WEBCAM if (!strncmp(vname,"wday",4)) { fvar=RtcTime.day_of_week; goto exit; @@ -2028,6 +2866,7 @@ char *getop(char *lp, uint8_t *operand) { } +#ifdef ESP8266 #if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_1) // All version before core 2.4.2 // https://github.com/esp8266/Arduino/issues/2557 @@ -2050,6 +2889,12 @@ uint16_t GetStack(void) { return (4 * (sp - g_pcont->stack)); } #endif +#else +uint16_t GetStack(void) { + register uint8_t *sp asm("a1"); + return (sp - pxTaskGetStackStart(NULL)); +} +#endif char *GetStringResult(char *lp,uint8_t lastop,char *cp,JsonObject *jo) { uint8_t operand=0; @@ -2188,7 +3033,7 @@ char *ForceStringVar(char *lp,char *dstr) { } // replace vars in cmd %var% -void Replace_Cmd_Vars(char *srcbuf,char *dstbuf,uint16_t dstsize) { +void Replace_Cmd_Vars(char *srcbuf,uint32_t srcsize, char *dstbuf,uint32_t dstsize) { char *cp; uint16_t count; uint8_t vtype; @@ -2199,6 +3044,7 @@ void Replace_Cmd_Vars(char *srcbuf,char *dstbuf,uint16_t dstsize) { char string[SCRIPT_MAXSSIZE]; dstsize-=2; for (count=0;count0) return 0; + JsonObject *jo=0; + DynamicJsonBuffer jsonBuffer; // on heap + JsonObject &jobj=jsonBuffer.parseObject(js); + if (js) { + jo=&jobj; + } else { + jo=0; + } + + return Run_script_sub(type, tlen, jo); +} + +int16_t Run_script_sub(const char *type, int8_t tlen, JsonObject *jo) { uint8_t vtype=0,sindex,xflg,floop=0,globvindex,fromscriptcmd=0; - int8_t globaindex; + char *lp_next; + int8_t globaindex,saindex; struct T_INDEX ind; uint8_t operand,lastop,numeric=1,if_state[IF_NEST],if_exe[IF_NEST],if_result[IF_NEST],and_or,ifstck=0; if_state[ifstck]=0; @@ -2445,16 +3343,6 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) { float fvar=0,fvar1,sysvar,swvar; uint8_t section=0,sysv_type=0,swflg=0; - if (!glob_script_mem.scriptptr) { - return -99; - } - - DynamicJsonBuffer jsonBuffer; // on heap - JsonObject &jobj=jsonBuffer.parseObject(js); - JsonObject *jo; - if (js) jo=&jobj; - else jo=0; - char *lp=glob_script_mem.scriptptr; while (1) { @@ -2563,6 +3451,7 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) { // simple implementation, zero loop count not supported lp+=3; SCRIPT_SKIP_SPACES + lp_next=0; lp=isvar(lp,&vtype,&ind,0,0,0); if ((vtype!=VAR_NV) && (vtype&STYPE)==0) { // numeric var @@ -2576,19 +3465,40 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) { lp=GetNumericResult(lp,OPER_EQU,&cv_inc,0); //SCRIPT_SKIP_EOL cv_ptr=lp; - floop=1; + if (*cv_count<=cv_max && cv_inc>0) { + // inc loop + floop=1; + } else { + // dec loop + floop=2; + if (cv_inc>0) { + floop=1; + } + } } else { // error toLogEOL("for error",lp); } - } else if (!strncmp(lp,"next",4) && floop>0) { - // for next loop - *cv_count+=cv_inc; - if (*cv_count<=cv_max) { - lp=cv_ptr; - } else { - lp+=4; - floop=0; + } else if (!strncmp(lp,"next",4)) { + lp_next=lp; + if (floop>0) { + // for next loop + *cv_count+=cv_inc; + if (floop==1) { + if (*cv_count<=cv_max) { + lp=cv_ptr; + } else { + lp+=4; + floop=0; + } + } else { + if (*cv_count>=cv_max) { + lp=cv_ptr; + } else { + lp+=4; + floop=0; + } + } } } @@ -2642,18 +3552,22 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) { if (!if_exe[ifstck] && if_state[ifstck]!=1) goto next_line; #ifdef IFTHEN_DEBUG - sprintf(tbuff,"stack=%d,exe=%d,state=%d,cmpres=%d execute line: ",ifstck,if_exe[ifstck],if_state[ifstck],if_result[ifstck]); + sdtoff(tbuff,"stack=%d,exe=%d,state=%d,cmpres=%d execute line: ",ifstck,if_exe[ifstck],if_state[ifstck],if_result[ifstck]); toLogEOL(tbuff,lp); #endif if (!strncmp(lp,"break",5)) { + lp+=5; if (floop) { // should break loop + if (lp_next) { + lp=lp_next; + } floop=0; } else { section=0; } - break; + goto next_line; } else if (!strncmp(lp,"dp",2) && isdigit(*(lp+2))) { lp+=2; // number precision @@ -2671,9 +3585,29 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) { lp=GetNumericResult(lp,OPER_EQU,&fvar,0); int8_t pinnr=fvar; SCRIPT_SKIP_SPACES - lp=GetNumericResult(lp,OPER_EQU,&fvar,0); - int8_t mode=fvar; - pinMode(pinnr,mode&3); + uint8_t mode=0; + if ((*lp=='I') || (*lp=='O') || (*lp=='P')) { + switch (*lp) { + case 'I': + mode=0; + break; + case 'O': + mode=1; + break; + case 'P': + mode=2; + break; + } + lp++; + } else { + lp=GetNumericResult(lp,OPER_EQU,&fvar,0); + mode=fvar; + } + uint8_t pm=0; + if (mode==0) pm=INPUT; + if (mode==1) pm=OUTPUT; + if (mode==2) pm=INPUT_PULLUP; + pinMode(pinnr,pm); goto next_line; } else if (!strncmp(lp,"spin(",5)) { lp+=5; @@ -2697,21 +3631,39 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) { lp+=7; lp=isvar(lp,&vtype,&ind,0,0,0); if (vtype!=VAR_NV) { + SCRIPT_SKIP_SPACES + if (*lp!=')') { + lp=GetNumericResult(lp,OPER_EQU,&fvar,0); + } else { + fvar=0; + } // found variable as result uint8_t index=glob_script_mem.type[ind.index].index; if ((vtype&STYPE)==0) { // numeric result - if (glob_script_mem.type[index].bits.is_filter) { + if (glob_script_mem.type[ind.index].bits.is_filter) { uint8_t len=0; - float *fa=Get_MFAddr(index,&len); + float *fa=Get_MFAddr(index,&len,0); //Serial.printf(">> 2 %d\n",(uint32_t)*fa); - if (fa && len) ws2812_set_array(fa,len); + if (fa && len) ws2812_set_array(fa,len,fvar); } } } goto next_line; } #endif +#endif +#ifdef ESP32 + else if (!strncmp(lp,"beep(",5)) { + lp+=5; + lp=GetNumericResult(lp,OPER_EQU,&fvar,0); + SCRIPT_SKIP_SPACES + float fvar1; + lp=GetNumericResult(lp,OPER_EQU,&fvar1,0); + esp32_beep(fvar,fvar1); + lp++; + goto next_line; + } #endif else if (!strncmp(lp,"=>",2) || !strncmp(lp,"->",2) || !strncmp(lp,"+>",2) || !strncmp(lp,"print",5)) { @@ -2744,7 +3696,7 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) { //AddLog_P(LOG_LEVEL_INFO, tmp); // replace vars in cmd char *tmp=cmdmem+SCRIPT_CMDMEM/2; - Replace_Cmd_Vars(cmd,tmp,SCRIPT_CMDMEM/2); + Replace_Cmd_Vars(cmd,0,tmp,SCRIPT_CMDMEM/2); //toSLog(tmp); if (!strncmp(tmp,"print",5) || pflg) { @@ -2802,7 +3754,12 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) { str[0]='>'; lp=GetStringResult(lp,OPER_EQU,&str[1],0); lp++; - execute_script(str); + //execute_script(str); + char *svd_sp=glob_script_mem.scriptptr; + strcat(str,"\n#"); + glob_script_mem.scriptptr=str; + Run_script_sub(">",1,jo); + glob_script_mem.scriptptr=svd_sp; } // check for variable result @@ -2817,8 +3774,16 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) { } goto next_line; } else { + char *vnp=lp; lp=isvar(lp,&vtype,&ind,&sysvar,0,0); if (vtype!=VAR_NV) { +#ifdef USE_SCRIPT_GLOBVARS + char varname[16]; + uint32_t vnl=(uint32_t)lp-(uint32)vnp; + strncpy(varname,vnp,vnl); + varname[vnl]=0; +#endif + // found variable as result globvindex=ind.index; // save destination var index here globaindex=last_findex; @@ -2851,7 +3816,7 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) { switch (lastop) { case OPER_EQU: if (glob_script_mem.var_not_found) { - if (!js) toLogEOL("var not found: ",lp); + if (!jo) toLogEOL("var not found: ",lp); goto next_line; } *dfvar=fvar; @@ -2886,6 +3851,11 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) { } // var was changed glob_script_mem.type[globvindex].bits.changed=1; +#ifdef USE_SCRIPT_GLOBVARS + if (glob_script_mem.type[globvindex].bits.global) { + script_udp_sendvar(varname,dfvar,0); + } +#endif if (glob_script_mem.type[globvindex].bits.is_filter) { if (globaindex>=0) { Set_MFVal(glob_script_mem.type[globvindex].index,globaindex,*dfvar); @@ -2911,13 +3881,14 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) { // string result numeric=0; sindex=index; + saindex=last_sindex; // string result char str[SCRIPT_MAXSSIZE]; lp=getop(lp,&lastop); char *slp=lp; glob_script_mem.glob_error=0; lp=GetStringResult(lp,OPER_EQU,str,jo); - if (!js && glob_script_mem.glob_error) { + if (!jo && glob_script_mem.glob_error) { // mismatch lp=GetNumericResult(slp,OPER_EQU,&fvar,0); dtostrfd(fvar,6,str); @@ -2927,10 +3898,24 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) { if (!glob_script_mem.var_not_found) { // var was changed glob_script_mem.type[globvindex].bits.changed=1; - if (lastop==OPER_EQU) { - strlcpy(glob_script_mem.glob_snp+(sindex*glob_script_mem.max_ssize),str,glob_script_mem.max_ssize); - } else if (lastop==OPER_PLSEQU) { - strncat(glob_script_mem.glob_snp+(sindex*glob_script_mem.max_ssize),str,glob_script_mem.max_ssize); +#ifdef USE_SCRIPT_GLOBVARS + if (glob_script_mem.type[globvindex].bits.global) { + script_udp_sendvar(varname,0,str); + } +#endif + if (saindex>=0) { + if (lastop==OPER_EQU) { + strlcpy(glob_script_mem.last_index_string+(saindex*glob_script_mem.max_ssize),str,glob_script_mem.max_ssize); + } else if (lastop==OPER_PLSEQU) { + strncat(glob_script_mem.last_index_string+(saindex*glob_script_mem.max_ssize),str,glob_script_mem.max_ssize); + } + last_sindex=-1; + } else { + if (lastop==OPER_EQU) { + strlcpy(glob_script_mem.glob_snp+(sindex*glob_script_mem.max_ssize),str,glob_script_mem.max_ssize); + } else if (lastop==OPER_PLSEQU) { + strncat(glob_script_mem.glob_snp+(sindex*glob_script_mem.max_ssize),str,glob_script_mem.max_ssize); + } } } } @@ -2944,6 +3929,7 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) { goto next_line; } } else { + //Serial.printf(">> decode %s\n",lp ); // decode line if (*lp=='>' && tlen==1) { // called from cmdline @@ -3223,7 +4209,7 @@ const char HTTP_FORM_FILE_UPGb[] PROGMEM = const char HTTP_FORM_SDC_DIRa[] PROGMEM = "
    "; const char HTTP_FORM_SDC_DIRb[] PROGMEM = - "
    %s    %d
    "; + "
    %s     %s : %8d
    "; const char HTTP_FORM_SDC_DIRd[] PROGMEM = "
    %s
    "; const char HTTP_FORM_SDC_DIRc[] PROGMEM = @@ -3233,6 +4219,76 @@ const char HTTP_FORM_SDC_HREF[] PROGMEM = #endif +uint8_t *script_ex_ptr; +uint16_t uplsize; +uint8_t sc_state; + +// upload script and start immediately +void script_upload_start(void) { + + //AddLog_P(LOG_LEVEL_INFO, PSTR("HTP: file upload execute")); + + HTTPUpload& upload = Webserver->upload(); + if (upload.status == UPLOAD_FILE_START) { + //AddLog_P(LOG_LEVEL_INFO, PSTR("HTP: upload start")); + script_ex_ptr=(uint8_t*)glob_script_mem.script_ram; + //AddLog_P2(LOG_LEVEL_INFO, PSTR("HTP: upload file %s, %d"),upload.filename.c_str(),upload.totalSize); + + if (strcmp(upload.filename.c_str(),"execute_script")) { + Web.upload_error=1; + WSSend(500, CT_PLAIN, F("500: wrong filename")); + return; + } + if (upload.totalSize>=glob_script_mem.script_size) { + Web.upload_error=1; + WSSend(500, CT_PLAIN, F("500: file to large")); + return; + } + uplsize=0; + + sc_state = bitRead(Settings.rule_enabled, 0); + bitWrite(Settings.rule_enabled,0,0); + + } else if(upload.status == UPLOAD_FILE_WRITE) { + //AddLog_P(LOG_LEVEL_INFO, PSTR("HTP: upload write")); + uint32_t csiz=upload.currentSize; + uint32_t tsiz=glob_script_mem.script_size-1; + if (uplsizeopen(path, FILE_READ); if (dir) { dir.rewindDirectory(); if (strlen(path)>1) { @@ -3283,35 +4347,48 @@ void ListDir(char *path, uint8_t depth) { } WSContentSend_P(HTTP_FORM_SDC_DIRd,npath,path,".."); } + char *ep; while (true) { File entry=dir.openNextFile(); if (!entry) { break; } + // esp32 returns path here, shorten to filename + ep=(char*)entry.name(); + if (*ep=='/') ep++; + char *lcp = strrchr(ep,'/'); + if (lcp) { + ep=lcp+1; + } + //AddLog_P2(LOG_LEVEL_INFO, PSTR("entry: %s"),ep); + time_t tm=entry.getLastWrite(); + char tstr[24]; + strftime(tstr, 22, "%d-%m-%Y - %H:%M:%S ", localtime(&tm)); + char *pp=path; if (!*(pp+1)) pp++; char *cp=name; // osx formatted disks contain a lot of stuff we dont want - if (reject((char*)entry.name())) goto fclose; + if (reject((char*)ep)) goto fclose; for (uint8_t cnt=0;cnt1) { strcat(path,"/"); } - strcat(path,entry.name()); + strcat(path,ep); ListDir(path,depth+4); path[plen]=0; } else { - snprintf_P(npath,sizeof(npath),HTTP_FORM_SDC_HREF,WiFi.localIP().toString().c_str(),pp,entry.name()); - WSContentSend_P(HTTP_FORM_SDC_DIRb,npath,entry.name(),name,entry.size()); + snprintf_P(npath,sizeof(npath),HTTP_FORM_SDC_HREF,WiFi.localIP().toString().c_str(),pp,ep); + WSContentSend_P(HTTP_FORM_SDC_DIRb,npath,ep,name,tstr,entry.size()); } fclose: entry.close(); @@ -3322,15 +4399,14 @@ void ListDir(char *path, uint8_t depth) { char path[48]; -void Script_FileUploadConfiguration(void) -{ +void Script_FileUploadConfiguration(void) { uint8_t depth=0; strcpy(path,"/"); if (!HttpCheckPriviledgedAccess()) { return; } - if (WebServer->hasArg("download")) { - String stmp = WebServer->arg("download"); + if (Webserver->hasArg("download")) { + String stmp = Webserver->arg("download"); char *cp=(char*)stmp.c_str(); if (DownloadFile(cp)) { // is directory @@ -3355,8 +4431,6 @@ void Script_FileUploadConfiguration(void) Web.upload_error = 0; } -File upload_file; - void ScriptFileUploadSuccess(void) { WSContentStart_P(S_INFORMATION); WSContentSendStyle(); @@ -3369,17 +4443,16 @@ void ScriptFileUploadSuccess(void) { } +File upload_file; void script_upload(void) { - //AddLog_P(LOG_LEVEL_INFO, PSTR("HTP: file upload")); - - HTTPUpload& upload = WebServer->upload(); + HTTPUpload& upload = Webserver->upload(); if (upload.status == UPLOAD_FILE_START) { char npath[48]; sprintf(npath,"%s/%s",path,upload.filename.c_str()); - SD.remove(npath); - upload_file=SD.open(npath,FILE_WRITE); + fsp->remove(npath); + upload_file=fsp->open(npath,FILE_WRITE); if (!upload_file) Web.upload_error=1; } else if(upload.status == UPLOAD_FILE_WRITE) { if (upload_file) upload_file.write(upload.buf,upload.currentSize); @@ -3390,7 +4463,7 @@ void script_upload(void) { } } else { Web.upload_error=1; - WebServer->send(500, "text/plain", "500: couldn't create file"); + Webserver->send(500, "text/plain", "500: couldn't create file"); } } @@ -3398,12 +4471,12 @@ uint8_t DownloadFile(char *file) { File download_file; WiFiClient download_Client; - if (!SD.exists(file)) { + if (!fsp->exists(file)) { AddLog_P(LOG_LEVEL_INFO,PSTR("file not found")); return 0; } - download_file=SD.open(file,FILE_READ); + download_file=fsp->open(file,FILE_READ); if (!download_file) { AddLog_P(LOG_LEVEL_INFO,PSTR("could not open file")); return 0; @@ -3416,8 +4489,8 @@ uint8_t DownloadFile(char *file) { uint32_t flen=download_file.size(); - download_Client = WebServer->client(); - WebServer->setContentLength(flen); + download_Client = Webserver->client(); + Webserver->setContentLength(flen); char attachment[100]; char *cp; @@ -3428,7 +4501,7 @@ uint8_t DownloadFile(char *file) { } } snprintf_P(attachment, sizeof(attachment), PSTR("attachment; filename=%s"),cp); - WebServer->sendHeader(F("Content-Disposition"), attachment); + Webserver->sendHeader(F("Content-Disposition"), attachment); WSSend(200, CT_STREAM, ""); uint8_t buff[512]; @@ -3460,13 +4533,14 @@ uint8_t DownloadFile(char *file) { void HandleScriptTextareaConfiguration(void) { if (!HttpCheckPriviledgedAccess()) { return; } - if (WebServer->hasArg("save")) { + if (Webserver->hasArg("save")) { ScriptSaveSettings(); HandleConfiguration(); return; } } + void HandleScriptConfiguration(void) { if (!HttpCheckPriviledgedAccess()) { return; } @@ -3474,13 +4548,13 @@ void HandleScriptConfiguration(void) { AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_SCRIPT); #ifdef USE_SCRIPT_FATFS - if (WebServer->hasArg("d1")) { + if (Webserver->hasArg("d1")) { DownloadFile(glob_script_mem.flink[0]); } - if (WebServer->hasArg("d2")) { + if (Webserver->hasArg("d2")) { DownloadFile(glob_script_mem.flink[1]); } - if (WebServer->hasArg("upl")) { + if (Webserver->hasArg("upl")) { Script_FileUploadConfiguration(); } #endif @@ -3515,19 +4589,42 @@ void HandleScriptConfiguration(void) { WSContentSend_P(HTTP_SCRIPT_FORM_END); WSContentSpaceButton(BUTTON_CONFIGURATION); WSContentStop(); - } +} +void SaveScript(void) { + +#ifdef EEP_SCRIPT_SIZE + if (glob_script_mem.flags&1) { + EEP_WRITE(0,EEP_SCRIPT_SIZE,glob_script_mem.script_ram); + } +#endif // EEP_SCRIPT_SIZE + +#ifdef USE_SCRIPT_FATFS + if (glob_script_mem.flags&1) { + fsp->remove(FAT_SCRIPT_NAME); + File file=fsp->open(FAT_SCRIPT_NAME,FILE_WRITE); + file.write((const uint8_t*)glob_script_mem.script_ram,FAT_SCRIPT_SIZE); + file.close(); + } +#endif // USE_SCRIPT_FATFS + +#ifdef LITTLEFS_SCRIPT_SIZE + if (glob_script_mem.flags&1) { + SaveFile("/script.txt",(uint8_t*)glob_script_mem.script_ram,LITTLEFS_SCRIPT_SIZE); + } +#endif // LITTLEFS_SCRIPT_SIZE +} void ScriptSaveSettings(void) { - if (WebServer->hasArg("c1")) { + if (Webserver->hasArg("c1")) { bitWrite(Settings.rule_enabled,0,1); } else { bitWrite(Settings.rule_enabled,0,0); } - String str = WebServer->arg("t1"); + String str = Webserver->arg("t1"); if (*str.c_str()) { @@ -3568,25 +4665,19 @@ void ScriptSaveSettings(void) { strlcpy(glob_script_mem.script_ram,str.c_str(), glob_script_mem.script_size); -#ifdef USE_24C256 -#ifndef USE_SCRIPT_FATFS - if (glob_script_mem.flags&1) { - EEP_WRITE(0,EEP_SCRIPT_SIZE,glob_script_mem.script_ram); + if (glob_script_mem.script_ram[0]!='>' && glob_script_mem.script_ram[1]!='D') { + AddLog_P2(LOG_LEVEL_INFO, PSTR("script error: must start with >D")); + bitWrite(Settings.rule_enabled, 0, 0); } -#endif -#endif -#ifdef USE_SCRIPT_FATFS - if (glob_script_mem.flags&1) { - SD.remove(FAT_SCRIPT_NAME); - File file=SD.open(FAT_SCRIPT_NAME,FILE_WRITE); - file.write(glob_script_mem.script_ram,FAT_SCRIPT_SIZE); - file.close(); - } -#endif + SaveScript(); } + SaveScriptEnd(); +} + +void SaveScriptEnd(void) { if (glob_script_mem.script_mem) { Scripter_save_pvars(); free(glob_script_mem.script_mem); @@ -3594,13 +4685,27 @@ void ScriptSaveSettings(void) { glob_script_mem.script_mem_size=0; } +#ifdef USE_SCRIPT_COMPRESSION + //AddLog_P2(LOG_LEVEL_INFO,PSTR("in string: %s len = %d"),glob_script_mem.script_ram,strlen(glob_script_mem.script_ram)); + uint32_t len_compressed = SCRIPT_COMPRESS(glob_script_mem.script_ram, strlen(glob_script_mem.script_ram), Settings.rules[0], MAX_SCRIPT_SIZE-1); + if (len_compressed > 0) { + Settings.rules[0][len_compressed] = 0; + AddLog_P2(LOG_LEVEL_INFO,PSTR("script compressed to %d bytes = %d %%"),len_compressed,len_compressed * 100 / strlen(glob_script_mem.script_ram)); + } else { + AddLog_P2(LOG_LEVEL_INFO, PSTR("script compress error: %d"), len_compressed); + } +#endif // USE_SCRIPT_COMPRESSION + if (bitRead(Settings.rule_enabled, 0)) { int16_t res=Init_Scripter(); if (res) { AddLog_P2(LOG_LEVEL_INFO, PSTR("script init error: %d"), res); return; } - Run_Scripter(">B",2,0); + + Run_Scripter(">B\n",3,0); + Run_Scripter(">BS",3,0); + fast_script=Run_Scripter(">F",-2,0); } } @@ -3609,8 +4714,6 @@ void ScriptSaveSettings(void) { #if defined(USE_SCRIPT_HUE) && defined(USE_WEBSERVER) && defined(USE_EMULATION) && defined(USE_EMULATION_HUE) && defined(USE_LIGHT) - - #define HUE_DEV_MVNUM 5 #define HUE_DEV_NSIZE 16 struct HUE_SCRIPT { @@ -3827,8 +4930,7 @@ void Script_Check_Hue(String *response) { uint8_t hue_script_found=Run_Scripter(">H",-2,0); if (hue_script_found!=99) return; - char line[128]; - char tmp[128]; + char tmp[256]; uint8_t hue_devs=0; uint8_t vindex=0; char *cp; @@ -3843,17 +4945,7 @@ void Script_Check_Hue(String *response) { } if (*lp!=';') { // check this line - memcpy(line,lp,sizeof(line)); - line[sizeof(line)-1]=0; - cp=line; - for (uint32_t i=0; i0) *response+=",\""; + else *response+="\""; } *response+=String(EncodeLightId(hue_devs+devices_present+1))+"\":"; Script_HueStatus(response,hue_devs); + //AddLog_P2(LOG_LEVEL_INFO, PSTR("Hue: %s - %d "),response->c_str(), hue_devs); } hue_devs++; @@ -3978,11 +5072,11 @@ void Script_Handle_Hue(String *path) { uint8_t device = DecodeLightId(atoi(path->c_str())); uint8_t index = device-devices_present-1; - if (WebServer->args()) { + if (Webserver->args()) { response = "["; StaticJsonBuffer<400> jsonBuffer; - JsonObject &hue_json = jsonBuffer.parseObject(WebServer->arg((WebServer->args())-1)); + JsonObject &hue_json = jsonBuffer.parseObject(Webserver->arg((Webserver->args())-1)); if (hue_json.containsKey("on")) { response += FPSTR(sHUE_LIGHT_RESPONSE_JSON); @@ -3990,14 +5084,12 @@ void Script_Handle_Hue(String *path) { response.replace("{cm", "on"); bool on = hue_json["on"]; - switch(on) - { - case false : glob_script_mem.fvars[hue_script[index].index[0]-1]=0; - response.replace("{re", "false"); - break; - case true : glob_script_mem.fvars[hue_script[index].index[0]-1]=1; - response.replace("{re", "true"); - break; + if (on==false) { + glob_script_mem.fvars[hue_script[index].index[0]-1]=0; + response.replace("{re", "false"); + } else { + glob_script_mem.fvars[hue_script[index].index[0]-1]=1; + response.replace("{re", "true"); } glob_script_mem.type[hue_script[index].vindex[0]].bits.changed=1; resp = true; @@ -4222,6 +5314,14 @@ void dateTime(uint16_t* date, uint16_t* time) { #ifdef SUPPORT_MQTT_EVENT + +#ifndef MQTT_EVENT_MSIZE +#define MQTT_EVENT_MSIZE 256 +#endif +#ifndef MQTT_EVENT_JSIZE +#define MQTT_EVENT_JSIZE 400 +#endif + /********************************************************************************************/ /* * Script: Process received MQTT message. @@ -4236,8 +5336,8 @@ bool ScriptMqttData(void) { bool serviced = false; //toLog(">>> 1"); - toLog(XdrvMailbox.data); - if (XdrvMailbox.data_len < 1 || XdrvMailbox.data_len > 256) { + //toLog(XdrvMailbox.data); + if (XdrvMailbox.data_len < 1 || XdrvMailbox.data_len > MQTT_EVENT_MSIZE) { return false; } String sTopic = XdrvMailbox.topic; @@ -4257,7 +5357,7 @@ bool ScriptMqttData(void) if (event_item.Key.length() == 0) { //If did not specify Key value = sData; } else { //If specified Key, need to parse Key/Value from JSON data - StaticJsonBuffer<400> jsonBuf; + StaticJsonBuffer jsonBuf; JsonObject& jsonData = jsonBuf.parseObject(sData); String key1 = event_item.Key; String key2; @@ -4420,12 +5520,181 @@ String ScriptUnsubscribe(const char * data, int data_len) #ifdef USE_SCRIPT_WEB_DISPLAY +#ifdef SCRIPT_FULL_WEBPAGE +const char HTTP_WEB_FULL_DISPLAY[] PROGMEM = + "

    "; + +const char HTTP_SCRIPT_FULLPAGE1[] PROGMEM = + "" + "" + "" + "" + "%s - %s" + ""; + + +#ifdef USE_SCRIPT_FATFS + +const char HTTP_SCRIPT_MIMES[] PROGMEM = + "HTTP/1.1 200 OK\r\n" + "Content-disposition: inline; filename=%s" + "Content-type: %s\r\n\r\n"; + +void ScriptGetSDCard(void) { + if (!HttpCheckPriviledgedAccess()) { return; } + + String stmp = Webserver->uri(); + char *cp=strstr(stmp.c_str(),"/sdc/"); +// if (cp) Serial.printf(">>>%s\n",cp); + if (cp) { +#ifdef ESP32 + cp+=4 +#else + cp+=5; +#endif + if (fsp->exists(cp)) { + SendFile(cp); + return; + } + } + HandleNotFound(); +} + +void SendFile(char *fname) { +char buff[512]; + const char *mime; + char *jpg=strstr(fname,".jpg"); + if (jpg) { + mime="image/jpeg"; + } + char *html=strstr(fname,".html"); + if (html) { + mime="text/html"; + } + char *txt=strstr(fname,".txt"); + if (txt) { + mime="text/plain"; + } + + WSContentSend_P(HTTP_SCRIPT_MIMES,fname,mime); + + + File file=fsp->open(fname,FILE_READ); + uint32_t siz = file.size(); + uint32_t len=sizeof(buff); + while (siz > 0) { + if (len>siz) len=siz; + file.read((uint8_t *)buff,len ); + Webserver->client().write((const char*)buff, len); + siz -= len; + } + file.close(); + + Webserver->client().stop(); +} +#endif // USE_SCRIPT_FATFS + +void ScriptFullWebpage(void) { + uint32_t fullpage_refresh=10000; + if (!HttpCheckPriviledgedAccess()) { return; } + + String stmp = Webserver->uri(); + + if (Webserver->hasArg("m")) { // Status refresh requested + if (Webserver->hasArg("sv")) { + Script_Check_HTML_Setvars(); + } + WSContentBegin(200, CT_HTML); + ScriptWebShow('w'); + WSContentEnd(); + Serial.printf("fwp update sv %s\n",stmp.c_str() ); + return; //goto redraw; +// } else { + // Serial.printf("fwp update %s\n",stmp.c_str() ); + // } + + return; + } else { + Serial.printf("fwp other %s\n",stmp.c_str() ); + } + + WSContentBegin(200, CT_HTML); + const char *title="Full Screen"; + WSContentSend_P(HTTP_SCRIPT_FULLPAGE1, SettingsText(SET_DEVICENAME), title, fullpage_refresh); + WSContentSend_P(HTTP_SCRIPT_FULLPAGE2, fullpage_refresh); + //WSContentSend_P(PSTR("
    ")); + + //WSContentSendStyle(); + + + WSContentSend_P(PSTR("
    ")); + ScriptWebShow('w'); + WSContentSend_P(PSTR("
    ")); + + ScriptWebShow('x'); + + WSContentStop(); +} +#endif //SCRIPT_FULL_WEBPAGE + void Script_Check_HTML_Setvars(void) { if (!HttpCheckPriviledgedAccess()) { return; } - if (WebServer->hasArg("sv")) { - String stmp = WebServer->arg("sv"); + if (Webserver->hasArg("sv")) { + String stmp = Webserver->arg("sv"); + Serial.printf("fwp has arg dv %s\n",stmp.c_str()); char cmdbuf[64]; memset(cmdbuf,0,sizeof(cmdbuf)); char *cp=cmdbuf; @@ -4490,6 +5759,134 @@ const char SCRIPT_MSG_NUMINP[] PROGMEM = "
    "; +#ifdef USE_GOOGLE_CHARTS +const char SCRIPT_MSG_GTABLE[] PROGMEM = + "" + "" + "" + ""; + +const char SCRIPT_MSG_TABLE[] PROGMEM = + ""; +const char SCRIPT_MSG_GAUGE[] PROGMEM = + ""; +const char SCRIPT_MSG_TIMELINE[] PROGMEM = + ""; + + +const char SCRIPT_MSG_GTABLEa[] PROGMEM = + ""; + +const char SCRIPT_MSG_GOPT1[] PROGMEM = +"title:'%s',isStacked:false"; + +const char SCRIPT_MSG_GAUGEOPT[] PROGMEM = +"max:%d,redFrom:%d,redTo:%d,yellowFrom:%d,yellowTo:%d"; + +const char SCRIPT_MSG_GOPT2[] PROGMEM = +"showRowNumber:true,sort:'disable',allowHtml:true,width:'100%%',height:'100%%',cssClassNames:cssc"; + +const char SCRIPT_MSG_GOPT3[] PROGMEM = +"title:'%s',isStacked:false,vAxes:{0:{maxValue:%d},1:{maxValue:%d}},series:{0:{targetAxisIndex:0},1:{targetAxisIndex:1}}%s"; + +const char SCRIPT_MSG_GOPT4[] PROGMEM = +//"hAxis:{minValue:new Date(0,1,1,0,0),maxValue:new Date(0,1,2,0,0),format:'HH:mm'}"; +"hAxis:{minValue:new Date(0,1,1,0,0),maxValue:new Date(0,1,2,0,0),format:'HH:mm'},theme: 'maximized'"; + +const char SCRIPT_MSG_GOPT5[] PROGMEM = +"new Date(0,1,1,%d,%d)"; + +const char SCRIPT_MSG_GTE1[] PROGMEM = "'%s'"; + +#define GLIBS_MAIN 1<<0 +#define GLIBS_TABLE 1<<1 +#define GLIBS_GAUGE 1<<2 +#define GLIBS_TIMELINE 1<<3 + +#define MAX_GARRAY 4 + +char *gc_get_arrays(char *lp, float **arrays, uint8_t *ranum, uint8_t *rentries, uint8_t *ipos) { +struct T_INDEX ind; +uint8_t vtype; +uint8 entries=0; +uint8_t cipos=0; + + uint8_t anum=0; + while (anum> 2 %d\n",(uint32_t)*fa); + if (fa && len>=entries) { + if (!entries) { + entries = len; + } + // add array to list + arrays[anum]=fa; + anum++; + } + } else { + // single numeric + arrays[anum]=&glob_script_mem.fvars[index]; + anum++; + entries=1; + } + } else { + lp=lp1; + break; + } + } + } + //Serial.printf(">> %d - %d - %d\n",anum,entries,(uint32_t)*arrays[0]); + *ranum=anum; + *rentries=entries; + *ipos=cipos; + return lp; +} + +char *gc_send_labels(char *lp,uint32_t anum) { + WSContentSend_PD("["); + for (uint32_t cnt=0; cntW",-2,0); +void ScriptWebShow(char mc) { + uint8_t web_script,xflg=0; + if (mc=='w' || mc=='x') { + if (mc=='x') { + xflg=1; + mc='$'; + } + web_script=Run_Scripter(">w",-2,0); + } else { + web_script=Run_Scripter(">W",-2,0); + } + if (web_script==99) { - char line[128]; - char tmp[128]; + char tmp[256]; uint8_t optflg=0; + uint8_t chartindex=1; + uint8_t google_libs=0; char *lp=glob_script_mem.section_ptr+2; + if (mc=='w') { + while (*lp) { + if (*lp=='\n') break; + lp++; + } + } while (lp) { while (*lp==SCRIPT_EOL) { lp++; @@ -4517,93 +5931,27 @@ void ScriptWebShow(void) { } if (*lp!=';') { // send this line to web - memcpy(line,lp,sizeof(line)); - line[sizeof(line)-1]=0; - char *cp=line; - for (uint32_t i=0; i0) { - cp="checked='checked'"; - uval=0; + Replace_Cmd_Vars(lp,1,tmp,sizeof(tmp)); + char *lin=tmp; + if ((!mc && (*lin!='$')) || (mc=='w' && (*lin!='$'))) { + // normal web section + if (*lin=='@') { + lin++; + optflg=1; } else { - cp=""; - uval=1; + optflg=0; } - WSContentSend_PD(SCRIPT_MSG_CHKBOX,label,(char*)cp,uval,vname); - - } else if (!strncmp(lin,"bu(",3)) { - char *lp=lin+3; - uint8_t bcnt=0; - char *found=lin; - while (bcnt<4) { - found=strstr(found,"bu("); - if (!found) break; - found+=3; - bcnt++; - } - uint8_t proz=100/bcnt; - if (!optflg && bcnt>1) proz-=2; - if (optflg) WSContentSend_PD(SCRIPT_MSG_BUT_START_TBL); - else WSContentSend_PD(SCRIPT_MSG_BUT_START); - for (uint32_t cnt=0;cnt0) { - cp=ontxt; + cp="checked='checked'"; uval=0; } else { - cp=offtxt; + cp=""; uval=1; } - if (bcnt>1 && cnt==bcnt-1) { - if (!optflg) proz+=2; + WSContentSend_PD(SCRIPT_MSG_CHKBOX,label,(char*)cp,uval,vname); + + } else if (!strncmp(lin,"bu(",3)) { + char *lp=lin+3; + uint8_t bcnt=0; + char *found=lin; + while (bcnt<4) { + found=strstr(found,"bu("); + if (!found) break; + found+=3; + bcnt++; } - if (!optflg) { - WSContentSend_PD(SCRIPT_MSG_BUTTONa,proz,uval,vname,cp); - } else { - WSContentSend_PD(SCRIPT_MSG_BUTTONa_TBL,proz,uval,vname,cp); + uint8_t proz=100/bcnt; + if (!optflg && bcnt>1) proz-=2; + if (optflg) WSContentSend_PD(SCRIPT_MSG_BUT_START_TBL); + else WSContentSend_PD(SCRIPT_MSG_BUT_START); + for (uint32_t cnt=0;cnt0) { + cp=ontxt; + uval=0; + } else { + cp=offtxt; + uval=1; + } + if (bcnt>1 && cnt==bcnt-1) { + if (!optflg) proz+=2; + } + if (!optflg) { + WSContentSend_PD(SCRIPT_MSG_BUTTONa,proz,uval,vname,cp); + } else { + WSContentSend_PD(SCRIPT_MSG_BUTTONa_TBL,proz,uval,vname,cp); + } + if (bcnt>1 && cnt1 && cnt%s
    "),tmp); } else { - WSContentSend_PD(PSTR("{s}%s{e}"),tmp); + if (mc=='w') { + WSContentSend_PD(PSTR("%s"),tmp); + } else { + if (optflg) { + WSContentSend_PD(PSTR("
    %s
    "),tmp); + } else { + WSContentSend_PD(PSTR("{s}%s{e}"),tmp); + } + } + } + // end standard web interface + } else { + // main section interface + if (*lin==mc) { + +#ifdef USE_GOOGLE_CHARTS + lin++; +exgc: + char *lp; + if (!strncmp(lin,"gc(",3)) { + // get google table + lp=lin+3; + SCRIPT_SKIP_SPACES + const char *type; + const char *func; + char options[312]; + uint8_t nanum=MAX_GARRAY; + uint8_t y2f=0; + char ctype; + ctype=*lp; + lp++; + if (!(google_libs&GLIBS_MAIN)) { + google_libs|=GLIBS_MAIN; + WSContentSend_PD(SCRIPT_MSG_GTABLE); + } + switch (ctype) { + case 'l': + type=PSTR("LineChart"); + break; + case 'b': + type=PSTR("BarChart"); + break; + case 'p': + type=PSTR("PieChart"); + break; + case 'g': + type=PSTR("Gauge"); + if (!(google_libs&GLIBS_GAUGE)) { + google_libs|=GLIBS_GAUGE; + WSContentSend_PD(SCRIPT_MSG_GAUGE); + } + break; + case 't': + type=PSTR("Table"); + if (!(google_libs&GLIBS_TABLE)) { + google_libs|=GLIBS_TABLE; + WSContentSend_PD(SCRIPT_MSG_TABLE); + } + break; + case 'T': + type=PSTR("Timeline"); + if (!(google_libs&GLIBS_TIMELINE)) { + google_libs|=GLIBS_TIMELINE; + WSContentSend_PD(SCRIPT_MSG_TIMELINE); + } + break; + case 'h': + type=PSTR("Histogram"); + break; + case 'c': + type=PSTR("ColumnChart"); + break; + default: + // error + goto nextwebline; + break; + } + if (ctype=='l' && *lp=='f') { + lp++; + func=PSTR(",curveType:'function'"); + } else { + func=""; + } + if (*lp=='2') { + lp++; + nanum=2; + y2f=1; + } + SCRIPT_SKIP_SPACES + + //Serial.printf("type %d\n",ctype); + + float *arrays[MAX_GARRAY]; + uint8_t anum=0; + uint8 entries=0; + uint8 ipos=0; + lp=gc_get_arrays(lp, &arrays[0], &anum, &entries, &ipos); + + if (anum>nanum) { + goto nextwebline; + } + // we know how many arrays and the number of entries + //Serial.printf("arrays %d\n",anum); + //Serial.printf("entries %d\n",entries); + if (ctype=='T') { + if (anum && !(entries&1)) { + WSContentSend_PD(SCRIPT_MSG_GTABLEa); + WSContentSend_PD(SCRIPT_MSG_GTABLEd); + char label[SCRIPT_MAXSSIZE]; + lp=GetStringResult(lp,OPER_EQU,label,0); + SCRIPT_SKIP_SPACES + for (uint32_t ind=0; ind=entries) todflg=entries-1; + } + + uint32_t aind=ipos; + if (aind>=entries) aind=entries-1; + for (uint32_t cnt=0; cnt=0) { + sprintf(lbl,"%d",todflg); + todflg++; + if (todflg>=entries) { + todflg=0; + } + } else { + GetTextIndexed(lbl, sizeof(lbl), aind, label); + } + WSContentSend_PD(lbl); + WSContentSend_PD("',"); + for (uint32_t ind=0; ind=entries) { + aind=0; + } + } + + // get header + char header[SCRIPT_MAXSSIZE]; + lp=GetStringResult(lp,OPER_EQU,header,0); + SCRIPT_SKIP_SPACES + + switch (ctype) { + case 't': + snprintf_P(options,sizeof(options),SCRIPT_MSG_GOPT2); + break; + default: + snprintf_P(options,sizeof(options),SCRIPT_MSG_GOPT1,header); + break; + } + // check for 2 axis option + if (y2f) { + // 2 y axes variant + SCRIPT_SKIP_SPACES + float max1; + lp=GetNumericResult(lp,OPER_EQU,&max1,0); + SCRIPT_SKIP_SPACES + float max2; + lp=GetNumericResult(lp,OPER_EQU,&max2,0); + SCRIPT_SKIP_SPACES + snprintf_P(options,sizeof(options),SCRIPT_MSG_GOPT3,header,(uint32_t)max1,(uint32_t)max2,func); + } + + if (ctype=='g') { + float yellowFrom; + lp=GetNumericResult(lp,OPER_EQU,&yellowFrom,0); + SCRIPT_SKIP_SPACES + float redFrom; + lp=GetNumericResult(lp,OPER_EQU,&redFrom,0); + SCRIPT_SKIP_SPACES + float maxValue; + lp=GetNumericResult(lp,OPER_EQU,&maxValue,0); + SCRIPT_SKIP_SPACES + float redTo=maxValue; + float yellowTo=redFrom; + snprintf_P(options,sizeof(options),SCRIPT_MSG_GAUGEOPT,(uint32_t)maxValue,(uint32_t)redFrom,(uint32_t)redTo, + (uint32_t)yellowFrom,(uint32_t)yellowTo); + } + } + WSContentSend_PD(SCRIPT_MSG_GTABLEb,options,type,chartindex); + chartindex++; + } else { + WSContentSend_PD(PSTR("%s"),lin); + } +#else + lin++; + WSContentSend_PD(PSTR("%s"),lin); + } else { + // WSContentSend_PD(PSTR("%s"),lin); +#endif //USE_GOOGLE_CHARTS } } } +nextwebline: if (*lp==SCRIPT_EOL) { lp++; } else { @@ -4708,11 +6341,11 @@ void ScriptWebShow(void) { #ifdef USE_SENDMAIL -void script_send_email_body(BearSSL::WiFiClientSecure_light *client) { + +void script_send_email_body(void(*func)(char *)) { uint8_t msect=Run_Scripter(">m",-2,0); if (msect==99) { - char line[128]; - char tmp[128]; + char tmp[256]; char *lp=glob_script_mem.section_ptr+2; while (lp) { while (*lp==SCRIPT_EOL) { @@ -4723,18 +6356,9 @@ uint8_t msect=Run_Scripter(">m",-2,0); } if (*lp!=';') { // send this line to smtp - memcpy(line,lp,sizeof(line)); - line[sizeof(line)-1]=0; - char *cp=line; - for (uint32_t i=0; iprintln(tmp); + Replace_Cmd_Vars(lp,1,tmp,sizeof(tmp)); + //client->println(tmp); + func(tmp); } if (*lp==SCRIPT_EOL) { lp++; @@ -4745,7 +6369,8 @@ uint8_t msect=Run_Scripter(">m",-2,0); } } } else { - client->println("*"); + //client->println("*"); + func((char*)"*"); } } #endif @@ -4754,8 +6379,7 @@ uint8_t msect=Run_Scripter(">m",-2,0); void ScriptJsonAppend(void) { uint8_t web_script=Run_Scripter(">J",-2,0); if (web_script==99) { - char line[128]; - char tmp[128]; + char tmp[256]; char *lp=glob_script_mem.section_ptr+2; while (lp) { while (*lp==SCRIPT_EOL) { @@ -4766,17 +6390,7 @@ void ScriptJsonAppend(void) { } if (*lp!=';') { // send this line to mqtt - memcpy(line,lp,sizeof(line)); - line[sizeof(line)-1]=0; - char *cp=line; - for (uint32_t i=0; iE",2,json_event); +} + +#ifdef ESP32 +#ifdef USE_SCRIPT_TASK + +#ifndef STASK_STACK +#define STASK_STACK 8192 +#endif + +#ifndef STASK_PRIO +#define STASK_PRIO 1 +#endif + +#if 1 + +struct ESP32_Task { + uint16_t task_timer; + TaskHandle_t task_t; +} esp32_tasks[2]; + + +void script_task1(void *arg) { + //uint32_t lastms=millis(); + //uint32_t time; + while (1) { + //time=millis()-lastms; + //lastms=millis(); + //time=esp32_tasks[0].task_timer-time; + //if (timet1",3,0); + } + } +} + +void script_task2(void *arg) { + //uint32_t lastms=millis(); + //uint32_t time; + while (1) { + //time=millis()-lastms; + //lastms=millis(); + //time=esp32_tasks[1].task_timer-time; + //if (timet2",3,0); + } + } +} +uint32_t scripter_create_task(uint32_t num, uint32_t time, uint32_t core) { + //return 0; + BaseType_t res = 0; + if (core > 1) { core = 1; } + if (num == 1) { + if (esp32_tasks[0].task_t) { vTaskDelete(esp32_tasks[0].task_t); } + res = xTaskCreatePinnedToCore(script_task1, "T1", STASK_STACK, NULL, STASK_PRIO, &esp32_tasks[0].task_t, core); + esp32_tasks[0].task_timer = time; + } else { + if (esp32_tasks[1].task_t) { vTaskDelete(esp32_tasks[1].task_t); } + res = xTaskCreatePinnedToCore(script_task2, "T2", STASK_STACK, NULL, STASK_PRIO, &esp32_tasks[1].task_t, core); + esp32_tasks[1].task_timer = time; + } + return res; +} +#else + +uint16_t task_timer1; +uint16_t task_timer2; +TaskHandle_t task_t1; +TaskHandle_t task_t2; + +void script_task1(void *arg) { + while (1) { + delay(task_timer1); + Run_Scripter(">t1",3,0); + } +} + +void script_task2(void *arg) { + while (1) { + delay(task_timer2); + Run_Scripter(">t2",3,0); + } +} + +uint32_t scripter_create_task(uint32_t num, uint32_t time, uint32_t core) { + //return 0; + BaseType_t res = 0; + if (core > 1) { core = 1; } + if (num == 1) { + if (task_t1) { vTaskDelete(task_t1); } + res = xTaskCreatePinnedToCore(script_task1, "T1", STASK_STACK, NULL, STASK_PRIO, &task_t1, core); + task_timer1 = time; + } else { + if (task_t2) { vTaskDelete(task_t2); } + res = xTaskCreatePinnedToCore(script_task2, "T2", STASK_STACK, NULL, STASK_PRIO, &task_t2, core); + task_timer2 = time; + } + return res; +} +#endif + +#endif // USE_SCRIPT_TASK +#endif // ESP32 + +#ifdef SCRIPT_GET_HTTPS_JP +#ifdef ESP8266 +#include "WiFiClientSecureLightBearSSL.h" +#else +#include +#endif + +// get tesla powerwall info page json string +uint32_t call2https(const char *host, const char *path) { + if (global_state.wifi_down) return 1; + uint32_t status=0; +#ifdef ESP32 + WiFiClientSecure *httpsClient; + httpsClient = new WiFiClientSecure; +#else + BearSSL::WiFiClientSecure_light *httpsClient; + httpsClient = new BearSSL::WiFiClientSecure_light(1024, 1024); +#endif + + httpsClient->setTimeout(1500); + + int retry = 0; + String result; + while ((!httpsClient->connect(host, 443)) && (retry < 5)) { + delay(100); + retry++; + } + if (retry == 5) { + return 2; + } + String request = String("GET ") + path + + " HTTP/1.1\r\n" + + "Host: " + host + + "\r\n" + "Connection: close\r\n\r\n"; + httpsClient->print(request); + + while (httpsClient->connected()) { + String line = httpsClient->readStringUntil('\n'); + if (line == "\r") { + break; + } + } + while (httpsClient->available()) { + String line = httpsClient->readStringUntil('\n'); + if (line!="") { + result += line; + } + } + httpsClient->stop(); + Run_Scripter(">jp",3,(char*)result.c_str()); + return 0; +} + +#endif // SCRIPT_GET_HTTPS_JP + + +void cpy2lf(char *dst,uint32_t dstlen, char *src) { + for (uint32_t cnt=0; cnt0) glob_script_mem.script_ram[len_decompressed]=0; + //AddLog_P2(LOG_LEVEL_INFO, PSTR("decompressed script len %d"),len_decompressed); +#endif // USE_SCRIPT_COMPRESSION + #ifdef USE_BUTTON_EVENT for (uint32_t cnt=0;cnt=0 + // fs on SD card +#ifdef ESP32 + if (PinUsed(GPIO_SPI_MOSI) && PinUsed(GPIO_SPI_MISO) && PinUsed(GPIO_SPI_CLK)) { + SPI.begin(Pin(GPIO_SPI_CLK),Pin(GPIO_SPI_MISO),Pin(GPIO_SPI_MOSI), -1); + } +#endif // ESP32 + fsp = &SD; if (SD.begin(USE_SCRIPT_FATFS)) { +#else + // fs on flash + fsp = &LittleFS; + if (fsp->begin()) { +#endif // USE_SCRIPT_FATFS>=0 + + //fsp->dateTimeCallback(dateTime); + glob_script_mem.script_sd_found=1; char *script; script=(char*)calloc(FAT_SCRIPT_SIZE+4,1); if (!script) break; glob_script_mem.script_ram=script; glob_script_mem.script_size=FAT_SCRIPT_SIZE; - if (SD.exists(FAT_SCRIPT_NAME)) { - File file=SD.open(FAT_SCRIPT_NAME,FILE_READ); + if (fsp->exists(FAT_SCRIPT_NAME)) { + File file=fsp->open(FAT_SCRIPT_NAME,FILE_READ); file.read((uint8_t*)script,FAT_SCRIPT_SIZE); file.close(); } @@ -4861,15 +6679,44 @@ bool Xdrv10(uint8_t function) glob_script_mem.flags=1; -#if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_2) - // for unkonwn reasons is not defined in 2.52 - SdFile::dateTimeCallback(dateTime); -#endif - } else { glob_script_mem.script_sd_found=0; } +#endif // USE_SCRIPT_FATFS + + +#ifdef LITTLEFS_SCRIPT_SIZE + +#ifdef ESP32 + // spiffs on esp32 + fsp = &SPIFFS; + //esp32_part = esp_partition_find_first(ESP_PARTITION_TYPE_DATA,ESP_PARTITION_SUBTYPE_DATA_SPIFFS,NULL); + //Serial.printf("address %d - %d - %s\n",esp32_part->address,esp32_part->size, esp32_part->label); +#else + // lfs on esp8266 + fsp = &LittleFS; #endif + char *script; + script=(char*)calloc(LITTLEFS_SCRIPT_SIZE+4,1); + if (!script) break; + LoadFile("/script.txt",(uint8_t*)script,LITTLEFS_SCRIPT_SIZE); + + glob_script_mem.script_ram=script; + glob_script_mem.script_size=LITTLEFS_SCRIPT_SIZE; + script[LITTLEFS_SCRIPT_SIZE-1]=0; + // use rules storage for permanent vars + glob_script_mem.script_pram=(uint8_t*)Settings.rules[0]; + glob_script_mem.script_pram_size=MAX_SCRIPT_SIZE; + glob_script_mem.flags=1; +#endif // LITTLEFS_SCRIPT_SIZE + + // a valid script MUST start with >D + if (glob_script_mem.script_ram[0]!='>' && glob_script_mem.script_ram[1]!='D') { + // clr all + memset(glob_script_mem.script_ram,0,glob_script_mem.script_size); + strcpy_P(glob_script_mem.script_ram, PSTR(">D\nscript error must start with >D")); + bitWrite(Settings.rule_enabled, 0, 0); + } // assure permanent memory is 4 byte aligned { uint32_t ptr=(uint32_t)glob_script_mem.script_pram; @@ -4883,7 +6730,7 @@ bool Xdrv10(uint8_t function) break; case FUNC_INIT: if (bitRead(Settings.rule_enabled, 0)) { - Run_Scripter(">B",2,0); + Run_Scripter(">B\n",3,0); fast_script=Run_Scripter(">F",-2,0); #if defined(USE_SCRIPT_HUE) && defined(USE_WEBSERVER) && defined(USE_EMULATION) && defined(USE_EMULATION_HUE) && defined(USE_LIGHT) Script_Check_Hue(0); @@ -4913,14 +6760,35 @@ bool Xdrv10(uint8_t function) case FUNC_WEB_ADD_BUTTON: WSContentSend_P(HTTP_BTN_MENU_RULES); break; +#ifdef USE_SCRIPT_WEB_DISPLAY + case FUNC_WEB_ADD_MAIN_BUTTON: + if (bitRead(Settings.rule_enabled, 0)) { + ScriptWebShow('$'); +#ifdef SCRIPT_FULL_WEBPAGE + uint8_t web_script=Run_Scripter(">w",-2,0); + if (web_script==99) { + char bname[48]; + cpy2lf(bname,sizeof(bname),glob_script_mem.section_ptr+3); + WSContentSend_PD(HTTP_WEB_FULL_DISPLAY,bname); + Webserver->on("/sfd", ScriptFullWebpage); +#ifdef USE_SCRIPT_FATFS + Webserver->onNotFound(ScriptGetSDCard); +#endif + } +#endif // SCRIPT_FULL_WEBPAGE + } + break; +#endif // USE_SCRIPT_WEB_DISPLAY case FUNC_WEB_ADD_HANDLER: - WebServer->on("/" WEB_HANDLE_SCRIPT, HandleScriptConfiguration); - WebServer->on("/ta",HTTP_POST, HandleScriptTextareaConfiguration); + Webserver->on("/" WEB_HANDLE_SCRIPT, HandleScriptConfiguration); + Webserver->on("/ta",HTTP_POST, HandleScriptTextareaConfiguration); + Webserver->on("/exs", HTTP_POST,[]() { Webserver->sendHeader("Location","/exs");Webserver->send(303);},script_upload_start); + Webserver->on("/exs", HTTP_GET,ScriptExecuteUploadSuccess); #ifdef USE_SCRIPT_FATFS - WebServer->on("/u3", HTTP_POST,[]() { WebServer->sendHeader("Location","/u3");WebServer->send(303);},script_upload); - WebServer->on("/u3", HTTP_GET,ScriptFileUploadSuccess); - WebServer->on("/upl", HTTP_GET,Script_FileUploadConfiguration); + Webserver->on("/u3", HTTP_POST,[]() { Webserver->sendHeader("Location","/u3");Webserver->send(303);},script_upload); + Webserver->on("/u3", HTTP_GET,ScriptFileUploadSuccess); + Webserver->on("/upl", HTTP_GET,Script_FileUploadConfiguration); #endif break; #endif // USE_WEBSERVER @@ -4929,6 +6797,9 @@ bool Xdrv10(uint8_t function) Run_Scripter(">R",2,0); Scripter_save_pvars(); } +#ifdef USE_SCRIPT_GLOBVARS + Script_Stop_UDP(); +#endif break; #ifdef SUPPORT_MQTT_EVENT case FUNC_MQTT_DATA: @@ -4940,7 +6811,7 @@ bool Xdrv10(uint8_t function) #ifdef USE_SCRIPT_WEB_DISPLAY case FUNC_WEB_SENSOR: if (bitRead(Settings.rule_enabled, 0)) { - ScriptWebShow(); + ScriptWebShow(0); } break; #endif //USE_SCRIPT_WEB_DISPLAY @@ -4964,11 +6835,16 @@ bool Xdrv10(uint8_t function) break; #endif +#ifdef USE_SCRIPT_GLOBVARS + case FUNC_LOOP: + Script_PollUdp(); + break; +#endif + } return result; } - #endif // Do not USE_RULES #endif // USE_SCRIPT diff --git a/tasmota/xdrv_11_knx.ino b/tasmota/xdrv_11_knx.ino index d0198e389..d6fef25fe 100644 --- a/tasmota/xdrv_11_knx.ino +++ b/tasmota/xdrv_11_knx.ino @@ -114,6 +114,7 @@ device_parameters_t device_param[] = { { KNX_SLOT3 , false, false, KNX_Empty }, { KNX_SLOT4 , false, false, KNX_Empty }, { KNX_SLOT5 , false, false, KNX_Empty }, + { KNX_SCENE , false, false, KNX_Empty }, { KNX_Empty, false, false, KNX_Empty} }; @@ -149,6 +150,7 @@ const char * device_param_ga[] = { D_KNX_TX_SLOT " 3", D_KNX_TX_SLOT " 4", D_KNX_TX_SLOT " 5", + D_KNX_TX_SCENE , nullptr }; @@ -184,6 +186,7 @@ const char *device_param_cb[] = { D_KNX_RX_SLOT " 3", D_KNX_RX_SLOT " 4", D_KNX_RX_SLOT " 5", + D_KNX_RX_SCENE , nullptr }; @@ -196,12 +199,14 @@ const char *device_param_cb[] = { #define D_CMND_KNX_PA "_PA" #define D_CMND_KNX_GA "_GA" #define D_CMND_KNX_CB "_CB" +#define D_CMND_KNXTXSCENE "Tx_Scene" + const char kKnxCommands[] PROGMEM = D_PRFX_KNX "|" // Prefix - D_CMND_KNXTXCMND "|" D_CMND_KNXTXVAL "|" D_CMND_KNX_ENABLED "|" D_CMND_KNX_ENHANCED "|" D_CMND_KNX_PA "|" D_CMND_KNX_GA "|" D_CMND_KNX_CB ; + D_CMND_KNXTXCMND "|" D_CMND_KNXTXVAL "|" D_CMND_KNX_ENABLED "|" D_CMND_KNX_ENHANCED "|" D_CMND_KNX_PA "|" D_CMND_KNX_GA "|" D_CMND_KNX_CB "|" D_CMND_KNXTXSCENE ; void (* const KnxCommand[])(void) PROGMEM = { - &CmndKnxTxCmnd, &CmndKnxTxVal, &CmndKnxEnabled, &CmndKnxEnhanced, &CmndKnxPa, &CmndKnxGa, &CmndKnxCb }; + &CmndKnxTxCmnd, &CmndKnxTxVal, &CmndKnxEnabled, &CmndKnxEnhanced, &CmndKnxPa, &CmndKnxGa, &CmndKnxCb, &CmndKnxTxScene }; uint8_t KNX_GA_Search( uint8_t param, uint8_t start = 0 ) { @@ -473,19 +478,19 @@ void KNX_INIT(void) { device_param[i].show = true; } - for (uint32_t i = GPIO_SWT1; i < GPIO_SWT4 + 1; ++i) + for (uint32_t i = GPIO_SWT1; i < GPIO_SWT1 + 4; ++i) { if (GetUsedInModule(i, my_module.io)) { device_param[i - GPIO_SWT1 + 8].show = true; } } - for (uint32_t i = GPIO_KEY1; i < GPIO_KEY4 + 1; ++i) + for (uint32_t i = GPIO_KEY1; i < GPIO_KEY1 + 4; ++i) { if (GetUsedInModule(i, my_module.io)) { device_param[i - GPIO_KEY1 + 8].show = true; } } - for (uint32_t i = GPIO_SWT1_NP; i < GPIO_SWT4_NP + 1; ++i) + for (uint32_t i = GPIO_SWT1_NP; i < GPIO_SWT1_NP + 4; ++i) { if (GetUsedInModule(i, my_module.io)) { device_param[i - GPIO_SWT1_NP + 8].show = true; } } - for (uint32_t i = GPIO_KEY1_NP; i < GPIO_KEY4_NP + 1; ++i) + for (uint32_t i = GPIO_KEY1_NP; i < GPIO_KEY1_NP + 4; ++i) { if (GetUsedInModule(i, my_module.io)) { device_param[i - GPIO_KEY1_NP + 8].show = true; } } @@ -518,6 +523,7 @@ void KNX_INIT(void) device_param[KNX_SLOT3-1].show = true; device_param[KNX_SLOT4-1].show = true; device_param[KNX_SLOT5-1].show = true; + device_param[KNX_SCENE-1].show = true; #endif // Delete from KNX settings all configuration is not anymore related to this device @@ -556,9 +562,12 @@ void KNX_CB_Action(message_t const &msg, void *arg) if (msg.data_len == 1) { // COMMAND - tempchar[0] = msg.data[0]; - tempchar[1] = '\0'; - } else { + sprintf(tempchar,"%d",msg.data[0]); + } else if (chan->type == KNX_SCENE) { + // VALUE + uint8_t tempvar = knx.data_to_1byte_uint(msg.data); + dtostrfd(tempvar,2,tempchar); + } else { // VALUE float tempvar = knx.data_to_2byte_float(msg.data); dtostrfd(tempvar,2,tempchar); @@ -603,6 +612,18 @@ void KNX_CB_Action(message_t const &msg, void *arg) } } } + else if (chan->type == KNX_SCENE) // KNX RX SCENE SLOT (write command) + { + if (!toggle_inhibit) { + char command[25]; + // Value received + snprintf_P(command, sizeof(command), PSTR("event KNX_SCENE=%s"), tempchar); + ExecuteCommand(command, SRC_KNX); + if (Settings.flag.knx_enable_enhancement) { + toggle_inhibit = TOGGLE_INHIBIT_TIME; + } + } + } #endif break; @@ -810,22 +831,22 @@ void HandleKNXConfiguration(void) char tmp[100]; String stmp; - if ( WebServer->hasArg("save") ) { + if ( Webserver->hasArg("save") ) { KNX_Save_Settings(); HandleConfiguration(); } else { - if ( WebServer->hasArg("btn_add") ) { - if ( WebServer->arg("btn_add") == "1" ) { + if ( Webserver->hasArg("btn_add") ) { + if ( Webserver->arg("btn_add") == "1" ) { - stmp = WebServer->arg("GAop"); //option selected + stmp = Webserver->arg("GAop"); //option selected uint8_t GAop = stmp.toInt(); - stmp = WebServer->arg("GA_FNUM"); + stmp = Webserver->arg("GA_FNUM"); uint8_t GA_FNUM = stmp.toInt(); - stmp = WebServer->arg("GA_AREA"); + stmp = Webserver->arg("GA_AREA"); uint8_t GA_AREA = stmp.toInt(); - stmp = WebServer->arg("GA_FDEF"); + stmp = Webserver->arg("GA_FDEF"); uint8_t GA_FDEF = stmp.toInt(); if (GAop) { @@ -835,13 +856,13 @@ void HandleKNXConfiguration(void) else { - stmp = WebServer->arg("CBop"); //option selected + stmp = Webserver->arg("CBop"); //option selected uint8_t CBop = stmp.toInt(); - stmp = WebServer->arg("CB_FNUM"); + stmp = Webserver->arg("CB_FNUM"); uint8_t CB_FNUM = stmp.toInt(); - stmp = WebServer->arg("CB_AREA"); + stmp = Webserver->arg("CB_AREA"); uint8_t CB_AREA = stmp.toInt(); - stmp = WebServer->arg("CB_FDEF"); + stmp = Webserver->arg("CB_FDEF"); uint8_t CB_FDEF = stmp.toInt(); if (CBop) { @@ -849,19 +870,19 @@ void HandleKNXConfiguration(void) } } } - else if ( WebServer->hasArg("btn_del_ga") ) + else if ( Webserver->hasArg("btn_del_ga") ) { - stmp = WebServer->arg("btn_del_ga"); + stmp = Webserver->arg("btn_del_ga"); uint8_t GA_NUM = stmp.toInt(); KNX_DEL_GA(GA_NUM); } - else if ( WebServer->hasArg("btn_del_cb") ) + else if ( Webserver->hasArg("btn_del_cb") ) { - stmp = WebServer->arg("btn_del_cb"); + stmp = Webserver->arg("btn_del_cb"); uint8_t CB_NUM = stmp.toInt(); KNX_DEL_CB(CB_NUM); @@ -955,16 +976,16 @@ void KNX_Save_Settings(void) String stmp; address_t KNX_addr; - Settings.flag.knx_enabled = WebServer->hasArg("b1"); - Settings.flag.knx_enable_enhancement = WebServer->hasArg("b2"); + Settings.flag.knx_enabled = Webserver->hasArg("b1"); + Settings.flag.knx_enable_enhancement = Webserver->hasArg("b2"); AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_KNX D_ENABLED ": %d, " D_KNX_ENHANCEMENT ": %d"), Settings.flag.knx_enabled, Settings.flag.knx_enable_enhancement ); - stmp = WebServer->arg("area"); + stmp = Webserver->arg("area"); KNX_addr.pa.area = stmp.toInt(); - stmp = WebServer->arg("line"); + stmp = Webserver->arg("line"); KNX_addr.pa.line = stmp.toInt(); - stmp = WebServer->arg("member"); + stmp = Webserver->arg("member"); KNX_addr.pa.member = stmp.toInt(); Settings.knx_physsical_addr = KNX_addr.value; knx.physical_address_set( KNX_addr ); // Set Physical KNX Address of the device @@ -1055,6 +1076,31 @@ void CmndKnxTxVal(void) } } +void CmndKnxTxScene(void) +{ + if ( (XdrvMailbox.data_len > 0) && Settings.flag.knx_enabled ) { + // XdrvMailbox.payload <- scene number to send + uint8_t i = KNX_GA_Search(KNX_SCENE); + if ( i != KNX_Empty ) { + KNX_addr.value = Settings.knx_GA_addr[i]; + + uint8_t tempvar = TextToInt(XdrvMailbox.data); + dtostrfd(tempvar,0,XdrvMailbox.data); + + knx.write_1byte_uint(KNX_addr, tempvar); + if (Settings.flag.knx_enable_enhancement) { + knx.write_1byte_uint(KNX_addr, tempvar); + knx.write_1byte_uint(KNX_addr, tempvar); + } + + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_KNX "%s = %s " D_SENT_TO " %d.%d.%d"), + device_param_ga[KNX_SCENE-1], XdrvMailbox.data, + KNX_addr.ga.area, KNX_addr.ga.line, KNX_addr.ga.member); + ResponseCmndIdxChar (XdrvMailbox.data); + } + } +} + void CmndKnxEnabled(void) { if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) { @@ -1209,7 +1255,7 @@ bool Xdrv11(uint8_t function) bool result = false; switch (function) { case FUNC_LOOP: - if (!global_state.wifi_down) { knx.loop(); } // Process knx events + if (!global_state.network_down) { knx.loop(); } // Process knx events break; case FUNC_EVERY_50_MSECOND: if (toggle_inhibit) { @@ -1225,7 +1271,7 @@ bool Xdrv11(uint8_t function) WSContentSend_P(HTTP_BTN_MENU_KNX); break; case FUNC_WEB_ADD_HANDLER: - WebServer->on("/kn", HandleKNXConfiguration); + Webserver->on("/kn", HandleKNXConfiguration); break; #endif // USE_KNX_WEB_MENU #endif // USE_WEBSERVER diff --git a/tasmota/xdrv_12_home_assistant.ino b/tasmota/xdrv_12_home_assistant.ino index e3ba4670d..df53084a8 100644 --- a/tasmota/xdrv_12_home_assistant.ino +++ b/tasmota/xdrv_12_home_assistant.ino @@ -25,76 +25,81 @@ const char kHAssJsonSensorTypes[] PROGMEM = D_JSON_TEMPERATURE "|" D_JSON_DEWPOINT "|" D_JSON_PRESSURE "|" D_JSON_PRESSUREATSEALEVEL "|" D_JSON_APPARENT_POWERUSAGE "|Battery|" D_JSON_CURRENT "|" D_JSON_DISTANCE "|" D_JSON_FREQUENCY "|" D_JSON_HUMIDITY "|" D_JSON_ILLUMINANCE "|" - D_JSON_MOISTURE "|PB0.3|PB0.5|PB1|PB2.5|PB5|PB10|PM1|PM2.5|PM10|" D_JSON_POWERFACTOR "|" D_JSON_POWERUSAGE "|" + D_JSON_MOISTURE "|PB0.3|PB0.5|PB1|PB2.5|PB5|PB10|PM1|PM2.5|PM10|" D_JSON_POWERFACTOR "|" D_JSON_POWERUSAGE "|" D_JSON_TOTAL_START_TIME "|" D_JSON_REACTIVE_POWERUSAGE "|" D_JSON_TODAY "|" D_JSON_TOTAL "|" D_JSON_VOLTAGE "|" D_JSON_WEIGHT "|" D_JSON_YESTERDAY "|" - D_JSON_CO2 "|" D_JSON_ECO2 "|" D_JSON_TVOC "|"; + D_JSON_CO2 "|" D_JSON_ECO2 "|" D_JSON_TVOC "|" D_COLOR_RED "|" D_COLOR_GREEN "|" D_COLOR_BLUE"|" D_CCT "|" D_PROXIMITY "|Ambient|"; + const char kHAssJsonSensorUnits[] PROGMEM = "||||" "VA|%|A|Cm|Hz|%|LX|" - "%|ppd|ppd|ppd|ppd|ppd|ppd|µg/m³|µg/m³|µg/m³|Cos φ|W|" + "%|ppd|ppd|ppd|ppd|ppd|ppd|µg/m³|µg/m³|µg/m³|Cos φ|W| |" "VAr|kWh|kWh|V|Kg|kWh|" - "ppm|ppm|ppb|"; + "ppm|ppm|ppb|R|G|B|" D_UNIT_KELVIN "| |LX|"; + const char kHAssJsonSensorDevCla[] PROGMEM = "dev_cla\":\"temperature|ic\":\"mdi:weather-rainy|dev_cla\":\"pressure|dev_cla\":\"pressure|" "dev_cla\":\"power|dev_cla\":\"battery|ic\":\"mdi:alpha-a-circle-outline|ic\":\"mdi:leak|ic\":\"mdi:current-ac|dev_cla\":\"humidity|dev_cla\":\"illuminance|" "ic\":\"mdi:cup-water|ic\":\"mdi:flask|ic\":\"mdi:flask|ic\":\"mdi:flask|ic\":\"mdi:flask|ic\":\"mdi:flask|ic\":\"mdi:flask|" - "ic\":\"mdi:air-filter|ic\":\"mdi:air-filter|ic\":\"mdi:air-filter|ic\":\"mdi:alpha-f-circle-outline|dev_cla\":\"power|" + "ic\":\"mdi:air-filter|ic\":\"mdi:air-filter|ic\":\"mdi:air-filter|ic\":\"mdi:alpha-f-circle-outline|dev_cla\":\"power|ic\":\"mdi:progress-clock|" "dev_cla\":\"power|dev_cla\":\"power|dev_cla\":\"power|ic\":\"mdi:alpha-v-circle-outline|ic\":\"mdi:scale|dev_cla\":\"power|" - "ic\":\"mdi:periodic-table-co2|ic\":\"mdi:air-filter|ic\":\"mdi:periodic-table-co2|"; + "ic\":\"mdi:periodic-table-co2|ic\":\"mdi:air-filter|ic\":\"mdi:periodic-table-co2|" + "ic\":\"mdi:palette|ic\":\"mdi:palette|ic\":\"mdi:palette|ic\":\"mdi:temperature-kelvin|ic\":\"mdi:ruler|dev_cla\":\"illuminance|"; //"ic\":\"mdi:weather-windy|ic\":\"mdi:weather-windy|ic\":\"mdi:weather-windy|ic\":\"mdi:weather-windy|" // List of sensors ready for discovery -const char HASS_DISCOVER_SENSOR[] PROGMEM = - ",\"unit_of_meas\":\"%s\",\"%s\"," // unit of measure and class (or icon) - "\"frc_upd\":true," // force update for better graph representation - "\"val_tpl\":\"{{value_json['%s']['%s']"; // "COUNTER":{"C1":0} -> {{ value_json['COUNTER']['C1'] - const char HASS_DISCOVER_BASE[] PROGMEM = - "{\"name\":\"%s\"," // dualr2 1 - "\"stat_t\":\"%s\"," // stat/dualr2/RESULT (implies "\"optimistic\":\"false\",") - "\"avty_t\":\"%s\"," // tele/dualr2/LWT - "\"pl_avail\":\"" D_ONLINE "\"," // Online - "\"pl_not_avail\":\"" D_OFFLINE "\""; // Offline + "{\"name\":\"%s\"," // dualr2 1 + "\"stat_t\":\"%s\""; // stat/dualr2/RESULT (implies "\"optimistic\":\"false\",") + +const char HASS_DISCOVER_SENSOR[] PROGMEM = + ",\"unit_of_meas\":\"%s\",\"%s\"," // unit of measure and class (or icon) + "\"frc_upd\":true," // force update for better graph representation + "\"val_tpl\":\"{{value_json['%s']['%s']"; // "COUNTER":{"C1":0} -> {{ value_json['COUNTER']['C1'] + +const char HASS_DISCOVER_SENSOR_LWT[] PROGMEM = + ",\"avty_t\":\"%s\"," // tele/dualr2/LWT + "\"pl_avail\":\"" D_ONLINE "\"," // Online + "\"pl_not_avail\":\"" D_OFFLINE "\""; // Offline const char HASS_DISCOVER_RELAY[] PROGMEM = - ",\"cmd_t\":\"%s\"," // cmnd/dualr2/POWER2 - "\"val_tpl\":\"{{value_json.%s}}\"," // POWER2 - "\"pl_off\":\"%s\"," // OFF - "\"pl_on\":\"%s\""; // ON + ",\"cmd_t\":\"%s\"," // cmnd/dualr2/POWER2 + "\"val_tpl\":\"{{value_json.%s}}\"," // POWER2 + "\"pl_off\":\"%s\"," // OFF + "\"pl_on\":\"%s\""; // ON const char HASS_DISCOVER_BIN_SWITCH[] PROGMEM = - ",\"val_tpl\":\"{{value_json.%s}}\"," // STATE - "\"frc_upd\":true," // In ON/OFF case, enable force_update to make automations work - "\"pl_on\":\"%s\"," // ON - "\"pl_off\":\"%s\""; // OFF + ",\"val_tpl\":\"{{value_json.%s}}\"," // STATE + "\"frc_upd\":true," // In ON/OFF case, enable force_update to make automations work + "\"pl_on\":\"%s\"," // ON + "\"pl_off\":\"%s\""; // OFF const char HASS_DISCOVER_BIN_PIR[] PROGMEM = - ",\"val_tpl\":\"{{value_json.%s}}\"," // STATE - "\"frc_upd\":true," // In ON/OFF case, enable force_update to make automations work - "\"pl_on\":\"%s\"," // ON - "\"off_dly\":1"; // Switchmode13 and Switchmode14 doesn't transmit an OFF state. + ",\"val_tpl\":\"{{value_json.%s}}\"," // STATE + "\"frc_upd\":true," // In ON/OFF case, enable force_update to make automations work + "\"pl_on\":\"%s\"," // ON + "\"off_dly\":1"; // Switchmode13 and Switchmode14 doesn't transmit an OFF state. -const char HASS_DISCOVER_LIGHT_DIMMER[] PROGMEM = - ",\"bri_cmd_t\":\"%s\"," // cmnd/led2/Dimmer - "\"bri_stat_t\":\"%s\"," // stat/led2/RESULT - "\"bri_scl\":100," // 100% - "\"on_cmd_type\":\"%s\"," // power on (first), power on (last), no power on (brightness) - "\"bri_val_tpl\":\"{{value_json." D_CMND_DIMMER "}}\""; +const char HASS_DISCOVER_BASE_LIGHT[] PROGMEM = + ",\"bri_cmd_t\":\"%s\"," // cmnd/led2/Dimmer + "\"bri_stat_t\":\"%s\"," // stat/led2/RESULT + "\"bri_scl\":100," // 100% + "\"on_cmd_type\":\"%s\"," // power on (first), power on (last), no power on (brightness) + "\"bri_val_tpl\":\"{{value_json.%s}}\""; const char HASS_DISCOVER_LIGHT_COLOR[] PROGMEM = - ",\"rgb_cmd_t\":\"%s2\"," // cmnd/led2/Color2 - "\"rgb_stat_t\":\"%s\"," // stat/led2/RESULT + ",\"rgb_cmd_t\":\"%s2\"," // cmnd/led2/Color2 + "\"rgb_stat_t\":\"%s\"," // stat/led2/RESULT "\"rgb_val_tpl\":\"{{value_json." D_CMND_COLOR ".split(',')[0:3]|join(',')}}\""; const char HASS_DISCOVER_LIGHT_WHITE[] PROGMEM = - ",\"whit_val_cmd_t\":\"%s\"," // cmnd/led2/White - "\"whit_val_stat_t\":\"%s\"," // stat/led2/RESULT + ",\"whit_val_cmd_t\":\"%s\"," // cmnd/led2/White + "\"whit_val_stat_t\":\"%s\"," // stat/led2/RESULT "\"whit_val_scl\":100," "\"whit_val_tpl\":\"{{value_json.Channel[3]}}\""; const char HASS_DISCOVER_LIGHT_CT[] PROGMEM = - ",\"clr_temp_cmd_t\":\"%s\"," // cmnd/led2/CT - "\"clr_temp_stat_t\":\"%s\"," // stat/led2/RESULT + ",\"clr_temp_cmd_t\":\"%s\"," // cmnd/led2/CT + "\"clr_temp_stat_t\":\"%s\"," // stat/led2/RESULT "\"clr_temp_val_tpl\":\"{{value_json." D_CMND_COLORTEMPERATURE "}}\""; const char HASS_DISCOVER_LIGHT_SCHEME[] PROGMEM = @@ -132,6 +137,24 @@ const char HASS_TRIGGER_TYPE[] PROGMEM = const char kHAssTriggerType[] PROGMEM = "none|button_short_press|button_long_press|button_double_press"; +const char kHAssTriggerTypeButtons[] PROGMEM = + "|button_short_press|button_double_press|button_triple_press|button_quadruple_press|button_quintuple_press|button_long_press|"; + +const char kHAssTriggerStringButtons[] PROGMEM = + "|SINGLE|DOUBLE|TRIPLE|QUAD|PENTA|HOLD|"; + +const char kHAssError1[] PROGMEM = + "HASS: MQTT discovery failed due to too long topic or device/friendly name. Please shorten topic and/or device/friendly name. Failed to format"; + +const char kHAssError2[] PROGMEM = + "HASS: The configuration of the Relays is wrong, there is a Light that is using an index higher than the number of the validated relay.\n " + "The Relays have priority over the Lights, an incorrect order could lead to an erroneous Light control.\n " + "Please update your configuration to avoid inconsistent results.\n " + "Entities for Relays and Lights will not be available in Home Assistant until the configuration will be updated."; + +const char kHAssError3[] PROGMEM = + "HASS: Unable to create one or more entities from Json data, please check your configuration. Failed to parse"; + uint8_t hass_init_step = 0; uint8_t hass_mode = 0; int hass_tele_period = 0; @@ -147,9 +170,7 @@ void TryResponseAppend_P(const char *format, ...) int slen = sizeof(mqtt_data) - 1 - mlen; if (dlen >= slen) { - AddLog_P2(LOG_LEVEL_ERROR, PSTR("HASS: MQTT discovery failed due to too long topic or friendly name. " - "Please shorten topic and friendly name. Failed to format(%u/%u):"), - dlen, slen); + AddLog_P2(LOG_LEVEL_ERROR, PSTR("%s (%u/%u):"), kHAssError1, dlen, slen); va_start(args, format); vsnprintf_P(log_data, sizeof(log_data), format, args); AddLog(LOG_LEVEL_ERROR); @@ -169,92 +190,155 @@ void HAssAnnounceRelayLight(void) char stemp2[TOPSZ]; char stemp3[TOPSZ]; char unique_id[30]; - bool is_light = false; - bool is_topic_light = false; + + bool LightControl = light_controller.isCTRGBLinked(); // SetOption37 - Color remapping for led channels, also provides an option for allowing independent handling of RGB and white channels + bool PwmMulti = Settings.flag3.pwm_multi_channels; // SetOption68 - Multi-channel PWM instead of a single light + bool is_topic_light = false; // Switch HAss domain between Lights and Relays + bool ind_light = false; // Controls Separated Lights when SetOption37 is >= 128 + bool ct_light = false; // Controls a CT Light when SetOption37 is >= 128 + bool wt_light = false; // Controls a White Light when SetOption37 is >= 128 + bool err_flag = false; // When true it blocks the creation of entities if the order of the Relays is not correct to avoid issue with Lights + bool TuyaMod = false; // Controls Tuya MCU modules + bool PwmMod = false; // Controls PWM_DIMMER module + bool FanMod = false; // Controls SONOFF_IFAN0X modules + + uint8_t dimmer = 1; + uint8_t valid_relay = 0; + uint8_t max_lights = 1; + uint8_t TuyaRel = 0; + uint8_t TuyaRelInv = 0; + uint8_t TuyaDim = 0; + + #ifdef ESP8266 + if (PWM_DIMMER == my_module_type ) { PwmMod = true; } // + if (SONOFF_IFAN02 == my_module_type || SONOFF_IFAN03 == my_module_type) { FanMod = true; } + if (SONOFF_DUAL == my_module_type) { valid_relay = 2; } + if (TUYA_DIMMER == my_module_type || SK03_TUYA == my_module_type) { TuyaMod = true; } + #endif //ESP8266 + + // If there is a special Light to be enabled and managed with SetOption68 or SetOption37 >= 128, Discovery calculates the maximum number of entities to be generated in advance + + if (PwmMulti) { max_lights = Light.subtype; } + + if (!LightControl) { + ind_light = true; + if (!PwmMulti) { max_lights = 2;} + } for (uint32_t i = 1; i <= MAX_RELAYS; i++) { - is_light = ((i == devices_present) && (light_type)); - is_topic_light = Settings.flag.hass_light || is_light; // SetOption30 - Enforce HAss autodiscovery as light +#ifdef USE_TUYA_MCU + TuyaRel = TuyaGetDpId((TUYA_MCU_FUNC_REL1+ i-1) + active_device - 1); + TuyaRelInv = TuyaGetDpId((TUYA_MCU_FUNC_REL1_INV+ i-1) + active_device - 1); + TuyaDim = TuyaGetDpId((TUYA_MCU_FUNC_DIMMER) + active_device - 1); +#endif //USE_TUYA_MCU + + bool RelayX = PinUsed(GPIO_REL1, i-1) || (valid_relay >= i) || (TuyaRel > 0 && TuyaMod) || (TuyaRelInv > 0 && TuyaMod); // Check if the gpio is configured as Relay or force it for Sonoff DUAL R1 with MCU and Tuya MCU + is_topic_light = Settings.flag.hass_light && RelayX || light_type && !RelayX || PwmMod || (TuyaDim > 0 && TuyaMod); // SetOption30 - Enforce HAss autodiscovery as light mqtt_data[0] = '\0'; // Clear retained message // Clear "other" topic first in case the device has been reconfigured from light to switch or vice versa - snprintf_P(unique_id, sizeof(unique_id), PSTR("%06X_%s_%d"), ESP.getChipId(), (is_topic_light) ? "RL" : "LI", i); + snprintf_P(unique_id, sizeof(unique_id), PSTR("%06X_%s_%d"), ESP_getChipId(), (is_topic_light) ? "RL" : "LI", i); snprintf_P(stopic, sizeof(stopic), PSTR(HOME_ASSISTANT_DISCOVERY_PREFIX "/%s/%s/config"), (is_topic_light) ? "switch" : "light", unique_id); MqttPublish(stopic, true); // Clear or Set topic - snprintf_P(unique_id, sizeof(unique_id), PSTR("%06X_%s_%d"), ESP.getChipId(), (is_topic_light) ? "LI" : "RL", i); + snprintf_P(unique_id, sizeof(unique_id), PSTR("%06X_%s_%d"), ESP_getChipId(), (is_topic_light) ? "LI" : "RL", i); snprintf_P(stopic, sizeof(stopic), PSTR(HOME_ASSISTANT_DISCOVERY_PREFIX "/%s/%s/config"), (is_topic_light) ? "light" : "switch", unique_id); - if (Settings.flag.hass_discovery && (i <= devices_present)) - { // SetOption19 - Control Home Assistantautomatic discovery (See SetOption59) - char name[33 + 2]; // friendlyname(33) + " " + index - char value_template[33]; - char prefix[TOPSZ]; - char *command_topic = stemp1; - char *state_topic = stemp2; - char *availability_topic = stemp3; + if ((i < Light.device) && !RelayX) { + err_flag = true; + AddLog_P2(LOG_LEVEL_ERROR, PSTR("%s"), kHAssError2); + } else { + if (Settings.flag.hass_discovery && (RelayX || (Light.device > 0) && (max_lights > 0)) && !err_flag ) + { // SetOption19 - Control Home Assistant automatic discovery (See SetOption59) + char name[TOPSZ]; // friendlyname(33) + " " + index + char value_template[33]; + char prefix[TOPSZ]; + char *command_topic = stemp1; + char *state_topic = stemp2; + char *availability_topic = stemp3; - if (i > MAX_FRIENDLYNAMES) { - snprintf_P(name, sizeof(name), PSTR("%s %d"), SettingsText(SET_FRIENDLYNAME1), i); - } else { - snprintf_P(name, sizeof(name), SettingsText(SET_FRIENDLYNAME1 + i - 1)); + if (i > MAX_FRIENDLYNAMES) { + snprintf_P(name, sizeof(name), PSTR("%s %s %d"), SettingsText(SET_DEVICENAME), SettingsText(SET_FRIENDLYNAME1), i-1); + } else { + snprintf_P(name, sizeof(name), PSTR ("%s %s"), SettingsText(SET_DEVICENAME), SettingsText(SET_FRIENDLYNAME1 + i-1)); + } + + GetPowerDevice(value_template, i, sizeof(value_template), Settings.flag.device_index_enable); // SetOption26 - Switch between POWER or POWER1 + GetTopic_P(command_topic, CMND, mqtt_topic, value_template); + GetTopic_P(state_topic, TELE, mqtt_topic, D_RSLT_STATE); + GetTopic_P(availability_topic, TELE, mqtt_topic, S_LWT); + Response_P(HASS_DISCOVER_BASE, name, state_topic); + TryResponseAppend_P(HASS_DISCOVER_SENSOR_LWT, availability_topic); + TryResponseAppend_P(HASS_DISCOVER_RELAY, command_topic, value_template, SettingsText(SET_STATE_TXT1), SettingsText(SET_STATE_TXT2)); + TryResponseAppend_P(HASS_DISCOVER_DEVICE_INFO_SHORT, unique_id, ESP_getChipId()); + + #ifdef USE_LIGHT + if (i >= Light.device) { + if (!RelayX || PwmMod || (TuyaDim > 0 && TuyaMod)) { + char *brightness_command_topic = stemp1; + strncpy_P(stemp3, Settings.flag.not_power_linked ? PSTR("last") : PSTR("brightness"), sizeof(stemp3)); // SetOption20 - Control power in relation to Dimmer/Color/Ct changes + char channel_num[9]; + if (PwmMulti) { // SetOption68 - Multi-channel PWM instead of a single light + snprintf_P(channel_num, sizeof(channel_num), PSTR("Channel%d"), i); + } else { + if (!LightControl) { // SetOption37 >= 128 - Color remapping for led channels, also provides an option for allowing independent handling of RGB and white channels + snprintf_P(channel_num, sizeof(channel_num), PSTR("" D_CMND_DIMMER "%d"), dimmer); + dimmer ++; + } else { + snprintf_P(channel_num, sizeof(channel_num), PSTR("" D_CMND_DIMMER "")); + } + } + GetTopic_P(brightness_command_topic, CMND, mqtt_topic, channel_num); + TryResponseAppend_P(HASS_DISCOVER_BASE_LIGHT, brightness_command_topic, state_topic, stemp3, channel_num); + } + if ((ind_light && !PwmMulti) || LightControl) { + + if (Light.subtype >= LST_RGB) { + char *rgb_command_topic = stemp1; + + GetTopic_P(rgb_command_topic, CMND, mqtt_topic, D_CMND_COLOR); + TryResponseAppend_P(HASS_DISCOVER_LIGHT_COLOR, rgb_command_topic, state_topic); + + char *effect_command_topic = stemp1; + GetTopic_P(effect_command_topic, CMND, mqtt_topic, D_CMND_SCHEME); + TryResponseAppend_P(HASS_DISCOVER_LIGHT_SCHEME, effect_command_topic, state_topic); + } + if (LST_RGBW == Light.subtype) { wt_light = true; } + if (LST_RGBCW == Light.subtype) { ct_light = true; } + } + + if ((!ind_light && ct_light) || (LST_COLDWARM == Light.subtype && + !PwmMulti && LightControl)) { + char *color_temp_command_topic = stemp1; + + GetTopic_P(color_temp_command_topic, CMND, mqtt_topic, D_CMND_COLORTEMPERATURE); + TryResponseAppend_P(HASS_DISCOVER_LIGHT_CT, color_temp_command_topic, state_topic); + ct_light = false; + } + if ((!ind_light && wt_light) || (LST_RGBW == Light.subtype && + !PwmMulti && LightControl)) { + char *white_temp_command_topic = stemp1; + + GetTopic_P(white_temp_command_topic, CMND, mqtt_topic, D_CMND_WHITE); + TryResponseAppend_P(HASS_DISCOVER_LIGHT_WHITE, white_temp_command_topic, state_topic); + wt_light = false; + } + ind_light = false; + max_lights--; + } + #endif // USE_LIGHT + TryResponseAppend_P(PSTR("}")); } - GetPowerDevice(value_template, i, sizeof(value_template), Settings.flag.device_index_enable); // SetOption26 - Switch between POWER or POWER1 - GetTopic_P(command_topic, CMND, mqtt_topic, value_template); - GetTopic_P(state_topic, TELE, mqtt_topic, D_RSLT_STATE); - GetTopic_P(availability_topic, TELE, mqtt_topic, S_LWT); - - Response_P(HASS_DISCOVER_BASE, name, state_topic, availability_topic); - TryResponseAppend_P(HASS_DISCOVER_RELAY, command_topic, value_template, SettingsText(SET_STATE_TXT1), SettingsText(SET_STATE_TXT2)); - TryResponseAppend_P(HASS_DISCOVER_DEVICE_INFO_SHORT, unique_id, ESP.getChipId()); - -#ifdef USE_LIGHT - if (is_light || PWM_DIMMER == my_module_type) - { - char *brightness_command_topic = stemp1; - - GetTopic_P(brightness_command_topic, CMND, mqtt_topic, D_CMND_DIMMER); - strncpy_P(stemp3, Settings.flag.not_power_linked ? PSTR("last") : PSTR("brightness"), sizeof(stemp3)); // SetOption20 - Control power in relation to Dimmer/Color/Ct changes - TryResponseAppend_P(HASS_DISCOVER_LIGHT_DIMMER, brightness_command_topic, state_topic, stemp3); - - if (Light.subtype >= LST_RGB) - { - char *rgb_command_topic = stemp1; - - GetTopic_P(rgb_command_topic, CMND, mqtt_topic, D_CMND_COLOR); - TryResponseAppend_P(HASS_DISCOVER_LIGHT_COLOR, rgb_command_topic, state_topic); - - char *effect_command_topic = stemp1; - GetTopic_P(effect_command_topic, CMND, mqtt_topic, D_CMND_SCHEME); - TryResponseAppend_P(HASS_DISCOVER_LIGHT_SCHEME, effect_command_topic, state_topic); - } - if (LST_RGBW == Light.subtype) - { - char *white_temp_command_topic = stemp1; - - GetTopic_P(white_temp_command_topic, CMND, mqtt_topic, D_CMND_WHITE); - TryResponseAppend_P(HASS_DISCOVER_LIGHT_WHITE, white_temp_command_topic, state_topic); - } - if ((LST_COLDWARM == Light.subtype) || (LST_RGBCW == Light.subtype)) - { - char *color_temp_command_topic = stemp1; - - GetTopic_P(color_temp_command_topic, CMND, mqtt_topic, D_CMND_COLORTEMPERATURE); - TryResponseAppend_P(HASS_DISCOVER_LIGHT_CT, color_temp_command_topic, state_topic); - } - } -#endif // USE_LIGHT - TryResponseAppend_P(PSTR("}")); } MqttPublish(stopic, true); } } -void HAssAnnouncerTriggers(uint8_t device, uint8_t present, uint8_t key, uint8_t toggle, uint8_t hold) +void HAssAnnouncerTriggers(uint8_t device, uint8_t present, uint8_t key, uint8_t toggle, uint8_t hold, uint8_t single, uint8_t trg_start, uint8_t trg_end) { // key 0 = button // key 1 = switch @@ -262,15 +346,17 @@ void HAssAnnouncerTriggers(uint8_t device, uint8_t present, uint8_t key, uint8_t char stemp1[TOPSZ]; char stemp2[TOPSZ]; char unique_id[30]; + char trigger2[8]; mqtt_data[0] = '\0'; // Clear retained message - for (uint8_t i = 2; i <= 3; i++) { - snprintf_P(unique_id, sizeof(unique_id), PSTR("%06X_%s_%d_%s"), ESP.getChipId(), key ? "SW" : "BTN", device + 1, GetStateText(i)); + for (uint8_t i = trg_start; i <= trg_end; i++) { + GetTextIndexed(trigger2, sizeof(trigger2), i, kHAssTriggerStringButtons); + snprintf_P(unique_id, sizeof(unique_id), PSTR("%06X_%s_%d_%s"), ESP_getChipId(), key ? "SW" : "BTN", device + 1, key ? GetStateText(i) : trigger2); snprintf_P(stopic, sizeof(stopic), PSTR(HOME_ASSISTANT_DISCOVERY_PREFIX "/device_automation/%s/config"), unique_id); if (Settings.flag.hass_discovery && present) { // SetOption19 - Control Home Assistantautomatic discovery (See SetOption59) - char name[33 + 6]; // friendlyname(33) + " " + "BTN" + " " + index + char name[TOPSZ]; // friendlyname(33) + " " + "BTN" + " " + index char value_template[33]; char prefix[TOPSZ]; char *state_topic = stemp1; @@ -285,13 +371,23 @@ void HAssAnnouncerTriggers(uint8_t device, uint8_t present, uint8_t key, uint8_t char param[21]; char subtype[9]; uint8_t pload = toggle; - - if ((i == 2 && toggle != 0) || (i == 3 && hold != 0)) { - if (i == 3) { pload = hold; } - GetTextIndexed(param, sizeof(param), pload, kHAssTriggerType); - snprintf_P(subtype, sizeof(subtype), PSTR("%s_%d"), key ? "switch" : "button", device + 1); - Response_P(HASS_TRIGGER_TYPE, state_topic, GetStateText(i), param, subtype, ESP.getChipId()); - } else { mqtt_data[0] = '\0'; } // Need to be cleaned again to avoid duplicate. + if (key) { + if ((i == 2 && toggle != 0) || (i == 3 && hold != 0)) { + if (i == 3) { pload = hold; } + GetTextIndexed(param, sizeof(param), pload, kHAssTriggerType); + snprintf_P(subtype, sizeof(subtype), PSTR("switch_%d"), device + 1); + Response_P(HASS_TRIGGER_TYPE, state_topic, GetStateText(i), param, subtype, ESP_getChipId()); + } else { mqtt_data[0] = '\0'; } // Need to be cleaned again to avoid duplicate + } else { + char trigger1[24]; + GetTextIndexed(trigger1, sizeof(trigger1), i, kHAssTriggerTypeButtons); + snprintf_P(subtype, sizeof(subtype), PSTR("button_%d"), device + 1); + if (i > 1 && single) { + mqtt_data[0] = '\0'; // Need to be cleaned again to avoid duplicate + } else { + Response_P(HASS_TRIGGER_TYPE, state_topic, trigger2, trigger1, subtype, ESP_getChipId()); + } + } } MqttPublish(stopic, true); } @@ -306,13 +402,13 @@ void HAssAnnouncerBinSensors(uint8_t device, uint8_t present, uint8_t dual, uint mqtt_data[0] = '\0'; // Clear retained message - snprintf_P(unique_id, sizeof(unique_id), PSTR("%06X_SW_%d"), ESP.getChipId(), device + 1); + snprintf_P(unique_id, sizeof(unique_id), PSTR("%06X_SW_%d"), ESP_getChipId(), device + 1); snprintf_P(stopic, sizeof(stopic), PSTR(HOME_ASSISTANT_DISCOVERY_PREFIX "/binary_sensor/%s/config"), unique_id); if (Settings.flag.hass_discovery && present ) { // SetOption19 - Control Home Assistantautomatic discovery (See SetOption59) if (!toggle || dual) { - char name[33 + 6]; // friendlyname(33) + " " + "BTN" + " " + index + char name[TOPSZ]; // friendlyname(33) + " " + "BTN" + " " + index char value_template[33]; char prefix[TOPSZ]; char *state_topic = stemp1; @@ -324,14 +420,22 @@ void HAssAnnouncerBinSensors(uint8_t device, uint8_t present, uint8_t dual, uint GetTopic_P(state_topic, STAT, mqtt_topic, jsoname); GetTopic_P(availability_topic, TELE, mqtt_topic, S_LWT); - snprintf_P(name, sizeof(name), PSTR("%s Switch%d"), SettingsText(SET_FRIENDLYNAME1), device + 1); + snprintf_P(name, sizeof(name), PSTR("%s Switch%d"), SettingsText(SET_DEVICENAME), device + 1); Response_P(HASS_DISCOVER_BASE, name, state_topic, availability_topic); if (!pir) { TryResponseAppend_P(HASS_DISCOVER_BIN_SWITCH, PSTR(D_RSLT_STATE), SettingsText(SET_STATE_TXT2), SettingsText(SET_STATE_TXT1)); } else { TryResponseAppend_P(HASS_DISCOVER_BIN_PIR, PSTR(D_RSLT_STATE), SettingsText(SET_STATE_TXT2)); } - TryResponseAppend_P(HASS_DISCOVER_DEVICE_INFO_SHORT, unique_id, ESP.getChipId()); + TryResponseAppend_P(HASS_DISCOVER_DEVICE_INFO_SHORT, unique_id, ESP_getChipId()); +#ifdef DEEPSLEEP_LWT_HA_DISCOVERY + TryResponseAppend_P(HASS_DISCOVER_SENSOR_LWT, availability_topic); +#else + if (Settings.deepsleep == 0) + { + TryResponseAppend_P(HASS_DISCOVER_SENSOR_LWT, availability_topic); + } +#endif //DEEPSLEEP_LWT_HA_DISCOVERY TryResponseAppend_P(PSTR("}")); } } @@ -348,9 +452,9 @@ void HAssAnnounceSwitches(void) uint8_t hold = 0; uint8_t pir = 0; - if (pin[GPIO_SWT1 + switch_index] < 99) { switch_present = 1; } + if (PinUsed(GPIO_SWT1, switch_index)) { switch_present = 1; } - if (KeyTopicActive(1) && strcmp(SettingsText(SET_MQTT_SWITCH_TOPIC), mqtt_topic)) // Enable Discovery for Switches only if Switchtopic is set to a custom name + if (KeyTopicActive(1) && strcmp(SettingsText(SET_MQTT_SWITCH_TOPIC), mqtt_topic)) // Enable Discovery for Switches only if SwitchTopic is set to a custom name { // switch matrix for triggers and binary sensor generation when switchtopic is set as custom (default index is 0,0 - TOGGLE, TOGGLE): @@ -404,71 +508,56 @@ void HAssAnnounceSwitches(void) case PUSHON: case PUSHON_INV: toggle = 0; - pir = 1; // Binary sensor with only ON state and automatic OFF after 1 second. + pir = 1; // Binary sensor with only ON state and automatic OFF after 1 second } } else { switch_present = 0;} - HAssAnnouncerTriggers(switch_index, switch_present, 1, toggle, hold); + HAssAnnouncerTriggers(switch_index, switch_present, 1, toggle, hold, 0, 2, 3); HAssAnnouncerBinSensors(switch_index, switch_present, dual, toggle, pir); } } - void HAssAnnounceButtons(void) { for (uint32_t button_index = 0; button_index < MAX_KEYS; button_index++) { uint8_t button_present = 0; - uint8_t toggle = 1; - uint8_t hold = 0; + uint8_t single = 0; +#ifdef ESP8266 if (!button_index && ((SONOFF_DUAL == my_module_type) || (CH4 == my_module_type))) { button_present = 1; - } else { - if (pin[GPIO_KEY1 + button_index] < 99) { + } else +#endif // ESP8266 + { + if (PinUsed(GPIO_KEY1, button_index)) { button_present = 1; } } - // button matrix for triggers generation when buttontopic is set as custom (default TOGGLE = 1 HOLD = 0): - // N SetOption1 SetOption11 SetOption13 PRESS DOUBLE PRESS HOLD T,H - // 1 0 0 0 TOGGLE (button_short_press) NONE (toggle real relay) NONE (reset device) 1,0 - // 2 1 0 0 TOGGLE (button_short_press) NONE (toggle real relay) HOLD (button_long_press) 1,2 - // 3 0 1 0 NONE (toggle real relay) TOGGLE (button_double_press) NONE (reset device) 3,0 - // 4 1 1 0 NONE (toggle real relay) TOGGLE (button_double_press) HOLD (button_long_press) 3,2 - // 5 0 0 1 TOGGLE (button_short_press) NONE (toggle real relay) NONE (reset device) 1,0 - // 6 1 0 1 TOGGLE (button_short_press) NONE (toggle real relay) NONE (MQTT HOLD) 1,0 - // 7 0 1 1 NONE (toggle real relay) NONE (toggle real relay) NONE (reset device) 0,0 - // 8 1 1 1 NONE (toggle real relay) NONE (toggle real relay) NONE (MQTT HOLD) 0.0 + // Button matrix for triggers generation when SetOption73 is enabled: + // N SetOption1 SetOption11 SetOption13 PRESS MULTI PRESS HOLD + // 1 0 0 0 SINGLE (10 - button_short_press) DOUBLE to PENTA YES (button_long_press) + // 2 1 0 0 SINGLE (10 - button_short_press) DOUBLE to PENTA YES (button_long_press) + // 3 0 1 0 DOUBLE (11 - button_short_press) SINGLE then TRIPLE TO PENTA YES (button_long_press) + // 4 1 1 0 DOUBLE (11 - button_short_press) SINGLE then TRIPLE TO PENTA YES (button_long_press) + // 5 0 0 1 SINGLE (10 - button_short_press) NONE NONE + // 6 1 0 1 SINGLE (10 - button_short_press) NONE NONE + // 7 0 1 1 SINGLE (10 - button_short_press) NONE NONE + // 8 1 1 1 SINGLE (10 - button_short_press) NONE NONE - // Trigger types: "0 = none | 1 = button_short_press | 2 = button_long_press | 3 = button_double_press"; + // Trigger types: 10 = button_short_press | 11 = button_double_press | 12 = button_triple_press | 13 = button_quadruple_press | 14 = button_quintuple_press | 3 = button_long_press - if (Settings.flag.button_restrict) { // [SetOption1] Enable/Disable button multipress - if (!Settings.flag.button_single) { - hold = 2; // Default TOGGLE (button_short_press) + HOLD (button_long_press) trigger if [SetOption13] is OFF - } + if (!Settings.flag3.mqtt_buttons) { // Enable Buttons for discovery [SetOption73] - Decouple button from relay and send just mqtt topic + button_present = 0; + } else { + if (Settings.flag.button_single) { // [SetOption13] Immediate action on button press, just SINGLE trigger + single = 1; + } } - - if (Settings.flag.button_swap) { // [SetOption11] Swap button single and double press functionality - if (!Settings.flag.button_single) { - if (!Settings.flag.button_restrict) { - hold = 0; // TOGGLE (button_double_press) and remove HOLD (button_long_press) trigger if [SetOption1] is OFF - } - toggle = 3; // TOGGLE (button_double_press) - } else {toggle = 0; hold = 0;} // [SetOption13] Immediate action on button press, no TOGGLE or HOLD triggers - } - - if (KeyTopicActive(0)) { // Enable Discovery for Buttons only if Buttontopic is set to 1 or a custom name - - if (!strcmp(SettingsText(SET_MQTT_BUTTON_TOPIC), mqtt_topic)) { - toggle = 0; // When ButtonTopic is set to 1, TOGGLE is not allowed but an HOLD trigger can be generated. - } - - } else { button_present = 0; } - - HAssAnnouncerTriggers(button_index, button_present, 0, toggle, hold); + HAssAnnouncerTriggers(button_index, button_present, 0, 0, 0, single, 1, 6); } } @@ -481,25 +570,34 @@ void HAssAnnounceSensor(const char *sensorname, const char *subsensortype, const char subname[20]; mqtt_data[0] = '\0'; // Clear retained message - - // Clear or Set topic + + // Clear or Set topic NoAlNumToUnderscore(subname, MultiSubName); //Replace all non alphaumeric characters to '_' to avoid topic name issues - snprintf_P(unique_id, sizeof(unique_id), PSTR("%06X_%s_%s"), ESP.getChipId(), sensorname, subname); + snprintf_P(unique_id, sizeof(unique_id), PSTR("%06X_%s_%s"), ESP_getChipId(), sensorname, subname); snprintf_P(stopic, sizeof(stopic), PSTR(HOME_ASSISTANT_DISCOVERY_PREFIX "/sensor/%s/config"), unique_id); if (Settings.flag.hass_discovery) { // SetOption19 - Control Home Assistantautomatic discovery (See SetOption59) - char name[33 + 42]; // friendlyname(33) + " " + sensorname(20?) + " " + sensortype(20?) + char name[TOPSZ]; // friendlyname(33) + " " + sensorname(20?) + " " + sensortype(20?) char prefix[TOPSZ]; char *state_topic = stemp1; char *availability_topic = stemp2; + //bool LwtSensor = MQTT_LWT_DISCOVERY; GetTopic_P(state_topic, TELE, mqtt_topic, PSTR(D_RSLT_SENSOR)); - snprintf_P(name, sizeof(name), PSTR("%s %s %s"), SettingsText(SET_FRIENDLYNAME1), sensorname, MultiSubName); + snprintf_P(name, sizeof(name), PSTR("%s %s %s"), SettingsText(SET_DEVICENAME), sensorname, MultiSubName); GetTopic_P(availability_topic, TELE, mqtt_topic, S_LWT); - Response_P(HASS_DISCOVER_BASE, name, state_topic, availability_topic); - TryResponseAppend_P(HASS_DISCOVER_DEVICE_INFO_SHORT, unique_id, ESP.getChipId()); + Response_P(HASS_DISCOVER_BASE, name, state_topic); + #ifdef DEEPSLEEP_LWT_HA_DISCOVERY + TryResponseAppend_P(HASS_DISCOVER_SENSOR_LWT, availability_topic); +#else + if (Settings.deepsleep == 0) + { + TryResponseAppend_P(HASS_DISCOVER_SENSOR_LWT, availability_topic); + } +#endif //DEEPSLEEP_LWT_HA_DISCOVERY + TryResponseAppend_P(HASS_DISCOVER_DEVICE_INFO_SHORT, unique_id, ESP_getChipId()); char jname[32]; @@ -517,7 +615,7 @@ void HAssAnnounceSensor(const char *sensorname, const char *subsensortype, const case 3: snprintf_P(param1, sizeof(param1), PSTR("%s"), PressureUnit().c_str()); break; - // case 4: // Speed. Default to km/h if not set to have a graph representation under HAss + // case 4: // Speed. Default to km/h if not set to have a graph representation under HAss // case 5: // case 6: // case 7: @@ -565,14 +663,14 @@ void HAssAnnounceSensors(void) sensordata[0] = '{'; snprintf_P(sensordata, sizeof(sensordata), PSTR("%s}"), sensordata); // {"INA219":{"Voltage":4.494,"Current":0.020,"Power":0.089}} // USE THE FOLLOWING LINE TO TEST JSON - //snprintf_P(sensordata, sizeof(sensordata), PSTR("{\"HX711\":{\"Weight\":[22,34,1023.4]}}")); - //snprintf_P(sensordata, sizeof(sensordata), PSTR("{\"TX23\":{\"Speed\":{\"Act\":8.6,\"Avg\":8.2,\"Min\":0,\"Max\":15.8},\"Dir\":{\"Card\":\"SSO\",\"Deg\":157.5,\"Avg\":145.5,\"AvgCard\":\"SO\",\"Min\":112.5,\"Max\":292.5,\"Range\":180}}}")); + //snprintf_P(sensordata, sizeof(sensordata), PSTR("{\"APDS9960\":{\"Red\":282,\"Green\":252,\"Blue\":196,\"Ambient\":169,\"CCT\":4217,\"Proximity\":9}}")); + //snprintf_P(sensordata, sizeof(sensordata), PSTR("{\"ENERGY\":{\"TotalStartTime\":\"2018-11-23T15:33:47\",\"Total\":0.017,\"TotalTariff\":[0.000,0.017],\"Yesterday\":0.000,\"Today\":0.002,\"ExportActive\":0.000,\"ExportTariff\":[0.000,0.000],\"Period\":0.00,\"Power\":0.00,\"ApparentPower\":7.84,\"ReactivePower\":-7.21,\"Factor\":0.39,\"Frequency\":50.0,\"Voltage\":234.31,\"Current\":0.039,\"ImportActive\":12.580,\"ImportReactive\":0.002,\"ExportReactive\":39.131,\"PhaseAngle\":290.45}}")); StaticJsonBuffer<500> jsonBuffer; JsonObject &root = jsonBuffer.parseObject(sensordata); if (!root.success()) { - AddLog_P2(LOG_LEVEL_ERROR, PSTR("HASS: jsonBuffer failed to parse '%s'"), sensordata); + AddLog_P2(LOG_LEVEL_ERROR, PSTR("%s '%s'"), kHAssError3, sensordata); continue; } for (auto sensor : root) @@ -581,7 +679,7 @@ void HAssAnnounceSensors(void) JsonObject &sensors = sensor.value.as(); if (!sensors.success()) { - AddLog_P2(LOG_LEVEL_ERROR, PSTR("HASS: JsonObject failed to parse '%s'"), sensordata); + AddLog_P2(LOG_LEVEL_ERROR, PSTR("%s '%s'"), kHAssError3, sensordata); continue; } @@ -596,8 +694,8 @@ void HAssAnnounceSensors(void) for (auto subsensor : subsensors) { snprintf_P(NewSensorName, sizeof(NewSensorName), PSTR("%s %s"), NestedName, subsensor.key); HAssAnnounceSensor(sensorname, NestedName, NewSensorName, 0, 0, 1, subsensor.key); - } - } else if (subsensor.value.is()) { + } + } else if (subsensor.value.is()) { // If there is more than a value on sensor data, 'n' entitites will be created JsonArray& subsensors = subsensor.value.as(); uint8_t subqty = subsensors.size(); @@ -614,7 +712,7 @@ void HAssAnnounceSensors(void) } while (hass_xsns_index != 0); } -void HAssAnnounceStatusSensor(void) +void HAssAnnounceDeviceInfoAndStatusSensor(void) { char stopic[TOPSZ]; char stemp1[TOPSZ]; @@ -625,23 +723,24 @@ void HAssAnnounceStatusSensor(void) mqtt_data[0] = '\0'; // Clear retained message // Clear or Set topic - snprintf_P(unique_id, sizeof(unique_id), PSTR("%06X_status"), ESP.getChipId()); + snprintf_P(unique_id, sizeof(unique_id), PSTR("%06X_status"), ESP_getChipId()); snprintf_P(stopic, sizeof(stopic), PSTR(HOME_ASSISTANT_DISCOVERY_PREFIX "/sensor/%s/config"), unique_id); if (Settings.flag.hass_discovery) { // SetOption19 - Control Home Assistantautomatic discovery (See SetOption59) - char name[33 + 7]; // friendlyname(33) + " " + "status" + char name[TOPSZ]; // friendlyname(33) + " " + "status" char prefix[TOPSZ]; char *state_topic = stemp1; char *availability_topic = stemp2; - snprintf_P(name, sizeof(name), PSTR("%s status"), SettingsText(SET_FRIENDLYNAME1)); + snprintf_P(name, sizeof(name), PSTR("%s status"), SettingsText(SET_DEVICENAME)); GetTopic_P(state_topic, TELE, mqtt_topic, PSTR(D_RSLT_HASS_STATE)); GetTopic_P(availability_topic, TELE, mqtt_topic, S_LWT); - Response_P(HASS_DISCOVER_BASE, name, state_topic, availability_topic); + Response_P(HASS_DISCOVER_BASE, name, state_topic); + TryResponseAppend_P(HASS_DISCOVER_SENSOR_LWT, availability_topic); TryResponseAppend_P(HASS_DISCOVER_SENSOR_HASS_STATUS, state_topic); - TryResponseAppend_P(HASS_DISCOVER_DEVICE_INFO, unique_id, ESP.getChipId(), SettingsText(SET_FRIENDLYNAME1), + TryResponseAppend_P(HASS_DISCOVER_DEVICE_INFO, unique_id, ESP_getChipId(), SettingsText(SET_DEVICENAME), ModuleName().c_str(), my_version, my_image); TryResponseAppend_P(PSTR("}")); } @@ -650,16 +749,13 @@ void HAssAnnounceStatusSensor(void) void HAssPublishStatus(void) { - Response_P(PSTR("{\"" D_JSON_VERSION "\":\"%s%s\",\"" D_JSON_BUILDDATETIME "\":\"%s\"," - "\"" D_JSON_COREVERSION "\":\"" ARDUINO_ESP8266_RELEASE "\",\"" D_JSON_SDKVERSION "\":\"%s\"," - "\"" D_CMND_MODULE "\":\"%s\",\"" D_JSON_RESTARTREASON "\":\"%s\",\"" D_JSON_UPTIME "\":\"%s\"," - "\"WiFi " D_JSON_LINK_COUNT "\":%d,\"WiFi " D_JSON_DOWNTIME "\":\"%s\",\"" D_JSON_MQTT_COUNT "\":%d," - "\"" D_JSON_BOOTCOUNT "\":%d,\"" D_JSON_SAVECOUNT "\":%d,\"" D_CMND_IPADDRESS "\":\"%s\"," - "\"" D_JSON_RSSI "\":\"%d\",\"LoadAvg\":%lu}"), - my_version, my_image, GetBuildDateAndTime().c_str(), ESP.getSdkVersion(), ModuleName().c_str(), - GetResetReason().c_str(), GetUptime().c_str(), WifiLinkCount(), WifiDowntime().c_str(), MqttConnectCount(), - Settings.bootcount, Settings.save_flag, WiFi.localIP().toString().c_str(), - WifiGetRssiAsQuality(WiFi.RSSI()), loop_load_avg); + Response_P(PSTR("{\"" D_JSON_VERSION "\":\"%s%s\",\"" D_JSON_BUILDDATETIME "\":\"%s\",\"" D_CMND_MODULE " or " D_CMND_TEMPLATE"\":\"%s\"," + "\"" D_JSON_RESTARTREASON "\":\"%s\",\"" D_JSON_UPTIME "\":\"%s\",\"" D_CMND_HOSTNAME "\":\"%s\"," + "\"" D_CMND_IPADDRESS "\":\"%s\",\"" D_JSON_RSSI "\":\"%d\",\"" D_JSON_SIGNAL " (dBm)""\":\"%d\"," + "\"WiFi " D_JSON_LINK_COUNT "\":%d,\"WiFi " D_JSON_DOWNTIME "\":\"%s\",\"" D_JSON_MQTT_COUNT "\":%d,\"LoadAvg\":%lu}"), + my_version, my_image, GetBuildDateAndTime().c_str(), ModuleName().c_str(), GetResetReason().c_str(), + GetUptime().c_str(), my_hostname, WiFi.localIP().toString().c_str(), WifiGetRssiAsQuality(WiFi.RSSI()), + WiFi.RSSI(), WifiLinkCount(), WifiDowntime().c_str(), MqttConnectCount(), loop_load_avg); MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_HASS_STATE)); } @@ -678,8 +774,6 @@ void HAssDiscovery(void) if (Settings.flag.hass_discovery || (1 == hass_mode)) { // SetOption19 - Control Home Assistantautomatic discovery (See SetOption59) - // Send info about relays and lights - HAssAnnounceRelayLight(); // Send info about buttons HAssAnnounceButtons(); @@ -690,8 +784,11 @@ void HAssDiscovery(void) // Send info about sensors HAssAnnounceSensors(); + // Send info about relays and lights + HAssAnnounceRelayLight(); + // Send info about status sensor - HAssAnnounceStatusSensor(); + HAssAnnounceDeviceInfoAndStatusSensor(); } } @@ -710,7 +807,7 @@ void HAssAnyKey(void) uint32_t key = (XdrvMailbox.payload >> 16) & 0xFF; // 0 = Button, 1 = Switch uint32_t device = XdrvMailbox.payload & 0xFF; // Device number or 1 if more Buttons than Devices - uint32_t state = (XdrvMailbox.payload >> 8) & 0xFF; // 0 = Off, 1 = On, 2 = Toggle, 3 = Hold + uint32_t state = (XdrvMailbox.payload >> 8) & 0xFF; // 0 = Off, 1 = On, 2 = Toggle, 3 = Hold, 10,11,12,13 and 14 for Button Multipress if (!key && KeyTopicActive(0)) { // Button and ButtonTopic is active device = (XdrvMailbox.payload >> 24) & 0xFF; // Button number @@ -719,19 +816,27 @@ void HAssAnyKey(void) char scommand[CMDSZ]; char sw_topic[TOPSZ]; char key_topic[TOPSZ]; + char trg_state[8]; char *tmpbtn = SettingsText(SET_MQTT_BUTTON_TOPIC); char *tmpsw = SettingsText(SET_MQTT_SWITCH_TOPIC); uint8_t evkey = 0; // Flag to select the correct topic for a trigger or a binary_sensor Format(sw_topic, tmpsw, sizeof(sw_topic)); Format(key_topic, tmpbtn, sizeof(key_topic)); - if (state == 2 || state == 3 ) { evkey = 1;} + if (state >= 2) { evkey = 1;} snprintf_P(scommand, sizeof(scommand), PSTR("%s%d%s"), (key) ? "SWITCH" : "BUTTON", device, (evkey) ? "T" : ""); char stopic[TOPSZ]; + if (state == 3) { + snprintf_P(trg_state, sizeof(trg_state), GetStateText(3)); + } else { + if (state == 2) { state = 10; } + GetTextIndexed(trg_state, sizeof(trg_state), state -9, kHAssTriggerStringButtons); + } + GetTopic_P(stopic, STAT, mqtt_topic, scommand); - Response_P(S_JSON_COMMAND_SVALUE, (evkey) ? "TRIG" : PSTR(D_RSLT_STATE), GetStateText(state)); + Response_P(S_JSON_COMMAND_SVALUE, (evkey) ? "TRIG" : PSTR(D_RSLT_STATE), (key) ? GetStateText(state) : trg_state); MqttPublish(stopic); } @@ -742,7 +847,6 @@ void HAssAnyKey(void) bool Xdrv12(uint8_t function) { bool result = false; - if (Settings.flag.mqtt_enabled) { // SetOption3 - Enable MQTT switch (function) @@ -774,10 +878,13 @@ bool Xdrv12(uint8_t function) case FUNC_MQTT_INIT: hass_mode = 0; // Discovery only if Settings.flag.hass_discovery is set hass_init_step = 2; // Delayed discovery + // if (!Settings.flag.hass_discovery) { + // AddLog_P2(LOG_LEVEL_INFO, PSTR("MQT: homeassistant/49A3BC/Discovery = {\"dev\":{\"ids\":[\"49A3BC\"]},\"cmd_t\":\"cmnd/test1/\",\"Discovery\":0}")); + // } break; } } return result; } -#endif // USE_HOME_ASSISTANT \ No newline at end of file +#endif // USE_HOME_ASSISTANT diff --git a/tasmota/xdrv_13_display.ino b/tasmota/xdrv_13_display.ino index 117725024..d1fc01832 100644 --- a/tasmota/xdrv_13_display.ino +++ b/tasmota/xdrv_13_display.ino @@ -45,8 +45,8 @@ uint8_t color_type = COLOR_BW; uint8_t auto_draw=1; const uint8_t DISPLAY_MAX_DRIVERS = 16; // Max number of display drivers/models supported by xdsp_interface.ino -const uint8_t DISPLAY_MAX_COLS = 44; // Max number of columns allowed with command DisplayCols -const uint8_t DISPLAY_MAX_ROWS = 32; // Max number of lines allowed with command DisplayRows +const uint8_t DISPLAY_MAX_COLS = 64; // Max number of columns allowed with command DisplayCols +const uint8_t DISPLAY_MAX_ROWS = 64; // Max number of lines allowed with command DisplayRows const uint8_t DISPLAY_LOG_ROWS = 32; // Number of lines in display log buffer @@ -505,7 +505,7 @@ void DisplayText(void) cp += var; linebuf[fill] = 0; break; -#if defined(USE_SCRIPT_FATFS) && defined(USE_SCRIPT) +#if defined(USE_SCRIPT_FATFS) && defined(USE_SCRIPT) && USE_SCRIPT_FATFS>=0 case 'P': { char *ep=strchr(cp,':'); if (ep) { @@ -838,7 +838,7 @@ void DisplayText(void) if (!fill) { *dp = 0; } else { - linebuf[abs(fill)] = 0; + linebuf[abs(int(fill))] = 0; } if (fill<0) { // right align @@ -1013,14 +1013,14 @@ void DisplayLogBufferInit(void) snprintf_P(buffer, sizeof(buffer), PSTR("Display mode %d"), Settings.display_mode); DisplayLogBufferAdd(buffer); - snprintf_P(buffer, sizeof(buffer), PSTR(D_CMND_HOSTNAME " %s"), my_hostname); + snprintf_P(buffer, sizeof(buffer), PSTR(D_CMND_HOSTNAME " %s"), NetworkHostname()); DisplayLogBufferAdd(buffer); - snprintf_P(buffer, sizeof(buffer), PSTR(D_JSON_SSID " %s"), SettingsText(SET_STASSID1 + Settings.sta_active)); + snprintf_P(buffer, sizeof(buffer), PSTR(D_JSON_MAC " %s"), NetworkMacAddress().c_str()); DisplayLogBufferAdd(buffer); - snprintf_P(buffer, sizeof(buffer), PSTR(D_JSON_MAC " %s"), WiFi.macAddress().c_str()); + snprintf_P(buffer, sizeof(buffer), PSTR("IP %s"), NetworkAddress().toString().c_str()); DisplayLogBufferAdd(buffer); if (!global_state.wifi_down) { - snprintf_P(buffer, sizeof(buffer), PSTR("IP %s"), WiFi.localIP().toString().c_str()); + snprintf_P(buffer, sizeof(buffer), PSTR(D_JSON_SSID " %s"), SettingsText(SET_STASSID1 + Settings.sta_active)); DisplayLogBufferAdd(buffer); snprintf_P(buffer, sizeof(buffer), PSTR(D_JSON_RSSI " %d%%"), WifiGetRssiAsQuality(WiFi.RSSI())); DisplayLogBufferAdd(buffer); @@ -1500,47 +1500,114 @@ void CmndDisplayRows(void) /*********************************************************************************************\ * optional drivers \*********************************************************************************************/ +#ifdef ESP32 +#ifdef JPEG_PICTS +#include "img_converters.h" +#include "esp_jpg_decode.h" +bool jpg2rgb888(const uint8_t *src, size_t src_len, uint8_t * out, jpg_scale_t scale); +char get_jpeg_size(unsigned char* data, unsigned int data_size, unsigned short *width, unsigned short *height); +void rgb888_to_565(uint8_t *in, uint16_t *out, uint32_t len); +#endif +#endif -#if defined(USE_SCRIPT_FATFS) && defined(USE_SCRIPT) +#if defined(USE_SCRIPT_FATFS) && defined(USE_SCRIPT) && USE_SCRIPT_FATFS>=0 + +#ifdef ESP32 +extern FS *fsp; +#else +extern SDClass *fsp; +#endif +#define XBUFF_LEN 128 void Draw_RGB_Bitmap(char *file,uint16_t xp, uint16_t yp) { if (!renderer) return; - - //if (!strstr(file,".RGB")) return; File fp; - fp=SD.open(file,FILE_READ); - if (!fp) return; - uint16_t xsize; - fp.read((uint8_t*)&xsize,2); - uint16_t ysize; - fp.read((uint8_t*)&ysize,2); + char *ending = strrchr(file,'.'); + if (!ending) return; + ending++; + char estr[8]; + memset(estr,0,sizeof(estr)); + for (uint32_t cnt=0; cntopen(file,FILE_READ); + if (!fp) return; + uint16_t xsize; + fp.read((uint8_t*)&xsize,2); + uint16_t ysize; + fp.read((uint8_t*)&ysize,2); #if 1 -#define XBUFF 128 - uint16_t xdiv=xsize/XBUFF; - renderer->setAddrWindow(xp,yp,xp+xsize,yp+ysize); - for(int16_t j=0; j=2) renderer->pushColors(rgb,len/2,true); + uint16_t xdiv=xsize/XBUFF_LEN; + renderer->setAddrWindow(xp,yp,xp+xsize,yp+ysize); + for(int16_t j=0; j=2) renderer->pushColors(rgb,len/2,true); + } + OsWatchLoop(); } - OsWatchLoop(); - } - renderer->setAddrWindow(0,0,0,0); + renderer->setAddrWindow(0,0,0,0); #else - for(int16_t j=0; jwritePixel(xp+i,yp,rgb); + for(int16_t j=0; jwritePixel(xp+i,yp,rgb); + } + delay(0); + OsWatchLoop(); + yp++; } - delay(0); - OsWatchLoop(); - yp++; - } #endif - fp.close(); + fp.close(); + } else if (!strcmp(estr,"jpg")) { + // jpeg files on ESP32 with more memory +#ifdef ESP32 +#ifdef JPEG_PICTS + if (psramFound()) { + fp=fsp->open(file,FILE_READ); + if (!fp) return; + uint32_t size = fp.size(); + uint8_t *mem = (uint8_t *)heap_caps_malloc(size+4, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); + if (mem) { + uint8_t res=fp.read(mem, size); + if (res) { + uint16_t xsize; + uint16_t ysize; + if (mem[0]==0xff && mem[1]==0xd8) { + get_jpeg_size(mem, size, &xsize, &ysize); + //Serial.printf(" x,y %d - %d\n",xsize, ysize ); + if (xsize && ysize) { + uint8_t *out_buf = (uint8_t *)heap_caps_malloc((xsize*ysize*3)+4, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); + if (out_buf) { + uint8_t *ob=out_buf; + jpg2rgb888(mem, size, out_buf, (jpg_scale_t)JPG_SCALE_NONE); + uint16_t pixels=xsize*ysize/XBUFF_LEN; + renderer->setAddrWindow(xp,yp,xp+xsize,yp+ysize); + for(int32_t j=0; jpushColors(rbuff,XBUFF_LEN,true); + OsWatchLoop(); + } + renderer->setAddrWindow(0,0,0,0); + free(out_buf); + } + } + } + } + free(mem); + } + fp.close(); + } +#endif // JPEG_PICTS +#endif // ESP32 + } } #endif @@ -1788,7 +1855,9 @@ void DisplayCheckGraph() { #if defined(USE_SCRIPT_FATFS) && defined(USE_SCRIPT) +#ifdef ESP32 #include +#endif void Save_graph(uint8_t num, char *path) { if (!renderer) return; @@ -1796,8 +1865,8 @@ void Save_graph(uint8_t num, char *path) { struct GRAPH *gp=graph[index]; if (!gp) return; File fp; - SD.remove(path); - fp=SD.open(path,FILE_WRITE); + fsp->remove(path); + fp=fsp->open(path,FILE_WRITE); if (!fp) return; char str[32]; sprintf_P(str,PSTR("%d\t%d\t%d\t"),gp->xcnt,gp->xs,gp->ys); @@ -1822,7 +1891,7 @@ void Restore_graph(uint8_t num, char *path) { struct GRAPH *gp=graph[index]; if (!gp) return; File fp; - fp=SD.open(path,FILE_READ); + fp=fsp->open(path,FILE_READ); if (!fp) return; char vbuff[32]; char *cp=vbuff; diff --git a/tasmota/xdrv_14_mp3.ino b/tasmota/xdrv_14_mp3.ino index c28f3e693..ed6beee63 100644 --- a/tasmota/xdrv_14_mp3.ino +++ b/tasmota/xdrv_14_mp3.ino @@ -136,7 +136,7 @@ uint16_t MP3_Checksum(uint8_t *array) \*********************************************************************************************/ void MP3PlayerInit(void) { - MP3Player = new TasmotaSerial(-1, pin[GPIO_MP3_DFR562]); + MP3Player = new TasmotaSerial(-1, Pin(GPIO_MP3_DFR562)); // start serial communication fixed to 9600 baud if (MP3Player->begin(9600)) { MP3Player->flush(); @@ -232,7 +232,7 @@ bool Xdrv14(uint8_t function) { bool result = false; - if (pin[GPIO_MP3_DFR562] < 99) { + if (PinUsed(GPIO_MP3_DFR562)) { switch (function) { case FUNC_PRE_INIT: MP3PlayerInit(); // init and start communication diff --git a/tasmota/xdrv_16_tuyamcu.ino b/tasmota/xdrv_16_tuyamcu.ino index 466c3faf1..fcc6848db 100644 --- a/tasmota/xdrv_16_tuyamcu.ino +++ b/tasmota/xdrv_16_tuyamcu.ino @@ -36,6 +36,7 @@ #define TUYA_CMD_SET_DP 0x06 #define TUYA_CMD_STATE 0x07 #define TUYA_CMD_QUERY_STATE 0x08 +#define TUYA_CMD_SET_TIME 0x1C #define TUYA_LOW_POWER_CMD_WIFI_STATE 0x02 #define TUYA_LOW_POWER_CMD_WIFI_RESET 0x03 @@ -72,37 +73,37 @@ struct TUYA { } Tuya; -enum TuyaSupportedFunctions { - TUYA_MCU_FUNC_NONE, - TUYA_MCU_FUNC_SWT1 = 1, // Buttons - TUYA_MCU_FUNC_SWT2, - TUYA_MCU_FUNC_SWT3, - TUYA_MCU_FUNC_SWT4, - TUYA_MCU_FUNC_REL1 = 11, // Relays - TUYA_MCU_FUNC_REL2, - TUYA_MCU_FUNC_REL3, - TUYA_MCU_FUNC_REL4, - TUYA_MCU_FUNC_REL5, - TUYA_MCU_FUNC_REL6, - TUYA_MCU_FUNC_REL7, - TUYA_MCU_FUNC_REL8, - TUYA_MCU_FUNC_DIMMER = 21, - TUYA_MCU_FUNC_POWER = 31, - TUYA_MCU_FUNC_CURRENT, - TUYA_MCU_FUNC_VOLTAGE, - TUYA_MCU_FUNC_BATTERY_STATE, - TUYA_MCU_FUNC_BATTERY_PERCENTAGE, - TUYA_MCU_FUNC_REL1_INV = 41, // Inverted Relays - TUYA_MCU_FUNC_REL2_INV, - TUYA_MCU_FUNC_REL3_INV, - TUYA_MCU_FUNC_REL4_INV, - TUYA_MCU_FUNC_REL5_INV, - TUYA_MCU_FUNC_REL6_INV, - TUYA_MCU_FUNC_REL7_INV, - TUYA_MCU_FUNC_REL8_INV, - TUYA_MCU_FUNC_LOWPOWER_MODE = 51, - TUYA_MCU_FUNC_LAST = 255 -}; +// enum TuyaSupportedFunctions { +// TUYA_MCU_FUNC_NONE, +// TUYA_MCU_FUNC_SWT1 = 1, // Buttons +// TUYA_MCU_FUNC_SWT2, +// TUYA_MCU_FUNC_SWT3, +// TUYA_MCU_FUNC_SWT4, +// TUYA_MCU_FUNC_REL1 = 11, // Relays +// TUYA_MCU_FUNC_REL2, +// TUYA_MCU_FUNC_REL3, +// TUYA_MCU_FUNC_REL4, +// TUYA_MCU_FUNC_REL5, +// TUYA_MCU_FUNC_REL6, +// TUYA_MCU_FUNC_REL7, +// TUYA_MCU_FUNC_REL8, +// TUYA_MCU_FUNC_DIMMER = 21, +// TUYA_MCU_FUNC_POWER = 31, +// TUYA_MCU_FUNC_CURRENT, +// TUYA_MCU_FUNC_VOLTAGE, +// TUYA_MCU_FUNC_BATTERY_STATE, +// TUYA_MCU_FUNC_BATTERY_PERCENTAGE, +// TUYA_MCU_FUNC_REL1_INV = 41, // Inverted Relays +// TUYA_MCU_FUNC_REL2_INV, +// TUYA_MCU_FUNC_REL3_INV, +// TUYA_MCU_FUNC_REL4_INV, +// TUYA_MCU_FUNC_REL5_INV, +// TUYA_MCU_FUNC_REL6_INV, +// TUYA_MCU_FUNC_REL7_INV, +// TUYA_MCU_FUNC_REL8_INV, +// TUYA_MCU_FUNC_LOWPOWER_MODE = 51, +// TUYA_MCU_FUNC_LAST = 255 +// }; const char kTuyaCommand[] PROGMEM = "|" // No prefix D_CMND_TUYA_MCU "|" D_CMND_TUYA_MCU_SEND_STATE; @@ -539,6 +540,9 @@ void TuyaNormalPowerModePacketProcess(void) if (Tuya.buffer[6] == 0) { AddLog_P(LOG_LEVEL_DEBUG, PSTR("TYA: Detected MCU restart")); Tuya.wifi_state = -2; + #ifdef USE_TUYA_TIME + TuyaSetTime(); + #endif } break; @@ -565,16 +569,16 @@ void TuyaNormalPowerModePacketProcess(void) uint8_t key1_gpio = Tuya.buffer[7]; bool key1_set = false; bool led1_set = false; - for (uint32_t i = 0; i < sizeof(Settings.my_gp); i++) { - if (Settings.my_gp.io[i] == GPIO_LED1) led1_set = true; - else if (Settings.my_gp.io[i] == GPIO_KEY1) key1_set = true; + for (uint32_t i = 0; i < ARRAY_SIZE(Settings.my_gp.io); i++) { + if (Settings.my_gp.io[i] == AGPIO(GPIO_LED1)) led1_set = true; + else if (Settings.my_gp.io[i] == AGPIO(GPIO_KEY1)) key1_set = true; } if (!Settings.my_gp.io[led1_gpio] && !led1_set) { - Settings.my_gp.io[led1_gpio] = GPIO_LED1; + Settings.my_gp.io[led1_gpio] = AGPIO(GPIO_LED1); restart_flag = 2; } if (!Settings.my_gp.io[key1_gpio] && !key1_set) { - Settings.my_gp.io[key1_gpio] = GPIO_KEY1; + Settings.my_gp.io[key1_gpio] = AGPIO(GPIO_KEY1); restart_flag = 2; } } @@ -592,11 +596,11 @@ void TuyaNormalPowerModePacketProcess(void) bool TuyaModuleSelected(void) { - if (!(pin[GPIO_TUYA_RX] < 99) || !(pin[GPIO_TUYA_TX] < 99)) { // fallback to hardware-serial if not explicitly selected - pin[GPIO_TUYA_TX] = 1; - pin[GPIO_TUYA_RX] = 3; - Settings.my_gp.io[1] = GPIO_TUYA_TX; - Settings.my_gp.io[3] = GPIO_TUYA_RX; + if (!PinUsed(GPIO_TUYA_RX) || !PinUsed(GPIO_TUYA_TX)) { // fallback to hardware-serial if not explicitly selected + SetPin(1, AGPIO(GPIO_TUYA_TX)); + SetPin(3, AGPIO(GPIO_TUYA_RX)); + Settings.my_gp.io[1] = AGPIO(GPIO_TUYA_TX); + Settings.my_gp.io[3] = AGPIO(GPIO_TUYA_RX); restart_flag = 2; } @@ -637,13 +641,16 @@ bool TuyaModuleSelected(void) void TuyaInit(void) { + int baudrate = 9600; + if (Settings.flag4.tuyamcu_baudrate) { baudrate = 115200; } // SetOption97 - Set Baud rate for TuyaMCU serial communication (0 = 9600 or 1 = 115200) + Tuya.buffer = (char*)(malloc(TUYA_BUFFER_SIZE)); if (Tuya.buffer != nullptr) { - TuyaSerial = new TasmotaSerial(pin[GPIO_TUYA_RX], pin[GPIO_TUYA_TX], 2); - if (TuyaSerial->begin(9600)) { + TuyaSerial = new TasmotaSerial(Pin(GPIO_TUYA_RX), Pin(GPIO_TUYA_TX), 2); + if (TuyaSerial->begin(baudrate)) { if (TuyaSerial->hardwareSerial()) { ClaimSerial(); } // Get MCU Configuration - AddLog_P(LOG_LEVEL_DEBUG, PSTR("TYA: Request MCU configuration")); + AddLog_P(LOG_LEVEL_DEBUG, PSTR("TYA: Request MCU configuration at %d baud rate")); TuyaSendCmd(TUYA_CMD_QUERY_PRODUCT); } @@ -797,6 +804,24 @@ void TuyaSetWifiLed(void) } } +#ifdef USE_TUYA_TIME +void TuyaSetTime(void) +{ + uint16_t payload_len = 8; + uint8_t payload_buffer[8]; + payload_buffer[0] = 0x01; + payload_buffer[1] = (uint8_t)RtcTime.year; + payload_buffer[2] = RtcTime.month; + payload_buffer[3] = RtcTime.day_of_month; + payload_buffer[4] = RtcTime.hour; + payload_buffer[5] = RtcTime.minute; + payload_buffer[6] = RtcTime.second; + payload_buffer[7] = RtcTime.day_of_week; + + TuyaSendCmd(TUYA_CMD_SET_TIME, payload_buffer, payload_len); +} +#endif //USE_TUYA_TIME + #ifdef USE_ENERGY_SENSOR /*********************************************************************************************\ * Energy Interface diff --git a/tasmota/xdrv_17_rcswitch.ino b/tasmota/xdrv_17_rcswitch.ino index 9cd2d14d8..c5013828c 100644 --- a/tasmota/xdrv_17_rcswitch.ino +++ b/tasmota/xdrv_17_rcswitch.ino @@ -81,12 +81,12 @@ void RfReceiveCheck(void) void RfInit(void) { - if (pin[GPIO_RFSEND] < 99) { - mySwitch.enableTransmit(pin[GPIO_RFSEND]); + if (PinUsed(GPIO_RFSEND)) { + mySwitch.enableTransmit(Pin(GPIO_RFSEND)); } - if (pin[GPIO_RFRECV] < 99) { - pinMode( pin[GPIO_RFRECV], INPUT); - mySwitch.enableReceive(pin[GPIO_RFRECV]); + if (PinUsed(GPIO_RFRECV)) { + pinMode( Pin(GPIO_RFRECV), INPUT); + mySwitch.enableReceive(Pin(GPIO_RFRECV)); } } @@ -170,15 +170,15 @@ bool Xdrv17(uint8_t function) { bool result = false; - if ((pin[GPIO_RFSEND] < 99) || (pin[GPIO_RFRECV] < 99)) { + if (PinUsed(GPIO_RFSEND) || PinUsed(GPIO_RFRECV)) { switch (function) { case FUNC_EVERY_50_MSECOND: - if (pin[GPIO_RFRECV] < 99) { + if (PinUsed(GPIO_RFRECV)) { RfReceiveCheck(); } break; case FUNC_COMMAND: - if (pin[GPIO_RFSEND] < 99) { + if (PinUsed(GPIO_RFSEND)) { result = DecodeCommand(kRfSendCommands, RfSendCommand); } break; diff --git a/tasmota/xdrv_18_armtronix_dimmers.ino b/tasmota/xdrv_18_armtronix_dimmers.ino index 4a1322b25..710697a28 100644 --- a/tasmota/xdrv_18_armtronix_dimmers.ino +++ b/tasmota/xdrv_18_armtronix_dimmers.ino @@ -97,7 +97,7 @@ void ArmtronixInit(void) Armtronix.dim_state[1] = -1; Armtronix.knob_state[0] = -1; Armtronix.knob_state[1] = -1; - ArmtronixSerial = new TasmotaSerial(pin[GPIO_RXD], pin[GPIO_TXD], 2); + ArmtronixSerial = new TasmotaSerial(Pin(GPIO_RXD), Pin(GPIO_TXD), 2); if (ArmtronixSerial->begin(115200)) { if (ArmtronixSerial->hardwareSerial()) { ClaimSerial(); } ArmtronixSerial->println("Status"); diff --git a/tasmota/xdrv_19_ps16dz_dimmer.ino b/tasmota/xdrv_19_ps16dz_dimmer.ino index ab07289f7..d387ae05c 100644 --- a/tasmota/xdrv_19_ps16dz_dimmer.ino +++ b/tasmota/xdrv_19_ps16dz_dimmer.ino @@ -187,7 +187,7 @@ void PS16DZInit(void) { Ps16dz.rx_buffer = (char*)(malloc(PS16DZ_BUFFER_SIZE)); if (Ps16dz.rx_buffer != nullptr) { - PS16DZSerial = new TasmotaSerial(pin[GPIO_RXD], pin[GPIO_TXD], 2); + PS16DZSerial = new TasmotaSerial(Pin(GPIO_RXD), Pin(GPIO_TXD), 2); if (PS16DZSerial->begin(19200)) { if (PS16DZSerial->hardwareSerial()) { ClaimSerial(); } } diff --git a/tasmota/xdrv_20_hue.ino b/tasmota/xdrv_20_hue.ino index c816eed02..17a0886db 100644 --- a/tasmota/xdrv_20_hue.ino +++ b/tasmota/xdrv_20_hue.ino @@ -114,6 +114,29 @@ void HueRespondToMSearch(void) * Hue web server additions \*********************************************************************************************/ +//10http://{x1:80/urn:schemas-upnp-org:device:Basic:1Amazon-Echo-HA-Bridge ({x1)Royal Philips Electronicshttp://www.philips.comPhilips hue Personal Wireless LightingPhilips hue bridge 2012929000226503{x3uuid:{x2\r\n\r\n +//Successfully compressed from 625 to 391 bytes (-37.4%) +// const size_t HUE_DESCRIPTION_XML_size = 625; +// const char HUE_DESCRIPTION_XML[] PROGMEM = "\x3D\x0E\xD1\xB0\x68\x48\xCD\xFF\xDB\x9C\x7C\x3D\x87\x21\xD1\x9E\xC3\xB4\x7E\x1E" +// "\x85\xFC\xCA\x46\xC1\xA1\x77\x8F\x87\xB0\x5F\xF8\xF3\xF0\x62\x98\xDB\xF1\xD6\x2C" +// "\x67\x0C\x3A\xF3\xE3\xC7\x98\x8C\xCF\x43\x67\x59\xC8\x75\xB3\xD8\x7E\x1E\x85\xE1" +// "\x8C\x32\x33\x04\x1C\x78\xFC\x3D\x06\xD9\xAF\x3E\x7E\x1C\x87\xA1\xD8\x40\x83\x14" +// "\xF4\x1B\xBD\x9F\x3F\x0E\x33\xD0\xEC\x20\x41\x8A\x7A\x1D\x80\x91\x85\x10\xB2\xF9" +// "\x04\x43\xAF\xCC\xFC\x15\x54\x30\xF3\x3B\x0E\xC3\xDA\x6C\x39\x0F\x3F\xB3\xB0\xF4" +// "\x3B\x08\x10\xEA\x1E\x80\x83\xA2\x82\x1C\x42\xA3\x21\x8C\xFC\x05\x6D\xB4\xF3\x21" +// "\xD7\xED\x0C\xF3\x39\x0F\x43\xB0\x81\x1B\x0C\x3D\x0C\x7F\x5F\x08\x11\x91\x75\x8D" +// "\x67\xE1\x58\xDB\x36\xE7\x1D\x64\xC3\x15\x87\x59\x0A\x2B\x3A\xC8\x77\xF4\x41\xE6" +// "\x8E\xE9\xED\x36\x1C\x87\x78\xF4\x3B\x08\x12\x30\x63\xD0\x6D\xF0\xB3\x16\x1D\x0B" +// "\xFB\xF9\xF8\x5F\xC3\x2B\x09\x10\xC1\x5A\x16\x8C\xF2\x26\x13\x0E\xBF\x9D\xA1\xF8" +// "\xF4\x3B\x01\x23\x04\x04\x8C\x48\x85\x97\xC8\x20\x43\xE0\xDC\x7C\x7C\x7C\xE8\x30" +// "\x10\x71\xA3\xA0\x78\x34\x12\x71\x22\x16\x5F\x20\x8F\xC3\xD0\x6E\x08\xC2\x21\x1F" +// "\x83\xFE\x8C\xAD\xCE\x3F\x01\x0F\x49\x14\x2D\xA2\x18\xFF\xEC\xEB\x09\x10\xFE\xFD" +// "\x84\xFD\xE4\x41\x68\xF0\xAA\xDE\x1E\x3D\x0E\xC0\x4C\xC5\x41\x07\x27\x2E\xB1\xAC" +// "\x12\x32\x01\xC0\x83\xC2\x41\xCA\x72\x88\x10\xB1\x10\x42\xE1\x13\x04\x61\x17\x0B" +// "\x1A\x39\xFC\xFC\x38\xA9\x36\xEA\xBB\x5D\x90\x21\xE0\x20\x83\x58\xF4\xF3\xFE\xD8" +// "\x21\xCA\x3D\xA6\xC3\x96\x7A\x1D\x84\x09\x13\x8F\x42\x16\x42\x17\x1F\x82\xC5\xE8" +// "\x87\x99\xED\x36\x1C\xA3\xD0\xEC\x22\x16\x42\x17\x1F\x80\x87\xC7\x19\xF8\x7A\x1D" +// "\x9F\xCC\xA3\xF2\x70\xA4\x6E\x9C\x29\x1B\x8D"; const char HUE_DESCRIPTION_XML[] PROGMEM = "" "" @@ -137,22 +160,59 @@ const char HUE_DESCRIPTION_XML[] PROGMEM = "" "\r\n" "\r\n"; + +//%s"alert":"none","effect":"none","reachable":true} +//Successfully compressed from 50 to 34 bytes (-32%) +// const size_t HUE_LIGHTS_STATUS_JSON1_SUFFIX_size = 50; +// const char HUE_LIGHTS_STATUS_JSON1_SUFFIX[] PROGMEM = "\x3E\xBC\x7B\x2C\x27\xFA\x3D\x87\x99\xEC\xEC\xE6\x7B\x0E\xA3\xD8\xCC\x18\x61\x82" +// "\x34\xCF\xBB\x0C\x55\x8E\x09\x9E\xC3\xCE\xBE\x2D\x9E\xE3"; const char HUE_LIGHTS_STATUS_JSON1_SUFFIX[] PROGMEM = "%s\"alert\":\"none\"," "\"effect\":\"none\"," "\"reachable\":true}"; + +//,"type":"Extended color light","name":"%s","modelid":"%s","manufacturername":"%s","uniqueid":"%s"} +//Successfully compressed from 98 to 64 bytes (-34.7%) +// const size_t HUE_LIGHTS_STATUS_JSON2_size = 98; +// const char HUE_LIGHTS_STATUS_JSON2[] PROGMEM = "\x3A\x8F\x65\x19\x0C\x67\xB0\xF3\x3D\x84\xCD\x94\xF8\x46\x22\x0F\x02\xCF\xA0\xB4" +// "\x78\x55\x1E\xC3\xA8\xF6\x75\x8D\x67\xB0\xF3\x3D\x87\xD7\x8F\x61\xD4\x7B\x06\xE0" +// "\x8C\x2D\x10\x11\x25\xDF\x0B\x31\x61\xD0\xBF\xBF\x82\x3E\x06\x2F\xB4\xD4\x2D\x82" +// "\x1E\x08\x7B\x8D"; const char HUE_LIGHTS_STATUS_JSON2[] PROGMEM = ",\"type\":\"Extended color light\"," "\"name\":\"%s\"," - "\"modelid\":\"LCT007\"," - "\"uniqueid\":\"%s\"," - "\"swversion\":\"5.50.1.19085\"}"; + "\"modelid\":\"%s\"," + "\"manufacturername\":\"%s\"," + "\"uniqueid\":\"%s\"}"; + +//{"name":"Group 0","lights":[{l1],"type":"LightGroup","action": +//Successfully compressed from 62 to 61 bytes (-1.6%) const char HUE_GROUP0_STATUS_JSON[] PROGMEM = "{\"name\":\"Group 0\"," "\"lights\":[{l1]," "\"type\":\"LightGroup\"," "\"action\":"; // "\"scene\":\"none\","; + +//{"name":"Philips hue","mac":"{ma","dhcp":true,"ipaddress":"{ip","netmask":"{ms","gateway":"{gw","proxyaddress":"none","proxyport":0,"bridgeid":"{br","UTC":"{dt","whitelist":{"{id":{"last use date":"{dt","create date":"{dt","name":"Remote"}},"swversion":"01041302","apiversion":"1.17.0","swupdate":{"updatestate":0,"url":"","text":"","notify": false},"linkbutton":false,"portalservices":false} +//Successfully compressed from 392 to 302 bytes (-23%) +// const size_t HueConfigResponse_JSON_size = 392; +// const char HueConfigResponse_JSON[] PROGMEM = "\x3D\xA7\xB3\xAC\x6B\x3D\x87\x99\xEC\x21\x82\xB4\x2D\x19\xE4\x28\x5B\x3D\x87\x51" +// "\xEC\x1B\x61\x9E\xC3\xCC\xF6\x1E\xD1\xB6\x7B\x0E\xA3\xD8\x20\xA0\xC6\x1E\xC3\xCE" +// "\xBE\x2D\x9D\x47\xB3\x46\x58\x82\x7D\xFB\xC7\xB0\xF3\x3D\x87\xB7\x46\x1E\xC3\xA8" +// "\xF6\x73\xA1\xB7\xE3\x43\xD8\x79\x9E\xC3\xDA\x37\xC7\xB0\xEA\x3D\x83\xD7\x4C\x7E" +// "\xCC\x8F\x61\xE6\x7B\x0F\x68\xF0\xF9\xEC\x3A\x8F\x60\xCF\xE1\xB0\xC8\x11\x71\x1E" +// "\xCE\x60\x87\x48\x66\x7E\x8F\x61\xE6\x71\x9D\x47\xB0\x87\x7F\x44\x1E\x7A\x21\xEC" +// "\x3C\xCF\x61\xED\x1D\xF3\xD8\x75\x1E\xC2\x16\x54\x41\x9E\xC3\xCC\xF6\x1E\xD1\x28" +// "\xF6\x1D\x47\xB0\x7C\x56\xD3\x0B\x7D\x47\xB0\xF3\x3D\xA7\xB0\xF6\xE8\x87\xB0\xF3" +// "\x3D\xA7\xB0\x2B\xF5\x21\x7E\x68\x4B\xA6\x08\x98\x30\x7F\x77\x40\x95\x40\x10\xB8" +// "\x3A\x2F\xB1\xB9\x4C\xF6\x1E\xE3\xDC\x75\x1E\xCF\x0F\x99\xBF\xFB\x73\x8F\x61\xE6" +// "\x7B\x0E\x38\xF2\x5B\xA3\xD8\x75\x1E\xC2\xB1\x9A\x08\xB5\x0E\x43\xA4\xF1\xD1\x9E" +// "\xC3\xA8\xF6\x17\x87\xC5\x8C\x04\x1C\xB0\xF6\x9E\xC0\x41\x8D\xEA\xBA\x67\xB0\xF3" +// "\x38\xCE\xA3\xD8\x42\xFE\x11\xEC\x3C\xCF\x61\xEC\x3A\x8F\x65\x33\x65\x02\x0C\x6E" +// "\xCA\xD3\x06\x47\xB0\xF3\x46\x2C\x2F\x33\xDC\x75\x1E\xC0\xB7\x8D\x07\x0B\xAA\xCE" +// "\x3D\x87\x99\x8B\x0B\xCC\xEA\x3D\x83\x33\xF5\x61\x79\xFC\xCF\x43\x7E\x04\x2A\x2B" +// "\x67\xB8"; const char HueConfigResponse_JSON[] PROGMEM = "{\"name\":\"Philips hue\"," "\"mac\":\"{ma\"," @@ -192,7 +252,7 @@ String GetHueUserId(void) { char userid[7]; - snprintf_P(userid, sizeof(userid), PSTR("%03x"), ESP.getChipId()); + snprintf_P(userid, sizeof(userid), PSTR("%03x"), ESP_getChipId()); return String(userid); } @@ -358,7 +418,7 @@ bool HueActive(uint8_t device) { void HueLightStatus2(uint8_t device, String *response) { - const size_t buf_size = 192; + const size_t buf_size = 300; char * buf = (char*) malloc(buf_size); const size_t max_name_len = 32; char fname[max_name_len + 1]; @@ -376,7 +436,11 @@ void HueLightStatus2(uint8_t device, String *response) } fname[fname_len] = 0x00; } - snprintf_P(buf, buf_size, HUE_LIGHTS_STATUS_JSON2, fname, GetHueDeviceId(device).c_str()); + snprintf_P(buf, buf_size, HUE_LIGHTS_STATUS_JSON2, + EscapeJSONString(fname).c_str(), + EscapeJSONString(Settings.user_template_name).c_str(), + PSTR("Tasmota"), + GetHueDeviceId(device).c_str()); *response += buf; free(buf); } @@ -448,7 +512,7 @@ static const char * FIRST_GEN_UA[] = { // list of User-Agents signature // Check if the Echo device is of 1st generation, which triggers different results uint32_t findEchoGeneration(void) { // result is 1 for 1st gen, 2 for 2nd gen and further - String user_agent = WebServer->header("User-Agent"); + String user_agent = Webserver->header("User-Agent"); uint32_t gen = 2; for (uint32_t i = 0; i < sizeof(FIRST_GEN_UA)/sizeof(char*); i++) { @@ -521,11 +585,11 @@ void HueLightsCommand(uint8_t device, uint32_t device_id, String &response) { const size_t buf_size = 100; char * buf = (char*) malloc(buf_size); - if (WebServer->args()) { + if (Webserver->args()) { response = "["; StaticJsonBuffer<300> jsonBuffer; - JsonObject &hue_json = jsonBuffer.parseObject(WebServer->arg((WebServer->args())-1)); + JsonObject &hue_json = jsonBuffer.parseObject(Webserver->arg((Webserver->args())-1)); if (hue_json.containsKey("on")) { on = hue_json["on"]; snprintf_P(buf, buf_size, @@ -542,6 +606,7 @@ void HueLightsCommand(uint8_t device, uint32_t device_id, String &response) { } } else { #endif +/* switch(on) { case false : ExecuteCommandPower(device, POWER_OFF, SRC_HUE); @@ -549,6 +614,8 @@ void HueLightsCommand(uint8_t device, uint32_t device_id, String &response) { case true : ExecuteCommandPower(device, POWER_ON, SRC_HUE); break; } +*/ + ExecuteCommandPower(device, (on) ? POWER_ON : POWER_OFF, SRC_HUE); response += buf; resp = true; #ifdef USE_SHUTTER @@ -786,7 +853,7 @@ void HueGroups(String *path) String response = "{}"; uint8_t maxhue = (devices_present > MAX_HUE_DEVICES) ? MAX_HUE_DEVICES : devices_present; //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_HTTP D_HUE " HueGroups (%s)"), path->c_str()); - + if (path->endsWith("/0")) { response = FPSTR(HUE_GROUP0_STATUS_JSON); String lights = F("\"1\""); @@ -795,7 +862,7 @@ void HueGroups(String *path) lights += EncodeLightId(i); lights += "\""; } - + #ifdef USE_ZIGBEE ZigbeeHueGroups(&response); #endif // USE_ZIGBEE @@ -827,8 +894,8 @@ void HandleHueApi(String *path) path->remove(0, 4); // remove /api uint16_t apilen = path->length(); AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_HTTP D_HUE_API " (%s)"), path->c_str()); // HTP: Hue API (//lights/1/state - for (args = 0; args < WebServer->args(); args++) { - String json = WebServer->arg(args); + for (args = 0; args < Webserver->args(); args++) { + String json = Webserver->arg(args); AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_HTTP D_HUE_POST_ARGS " (%s)"), json.c_str()); // HTP: Hue POST args ({"on":false}) } @@ -861,7 +928,7 @@ bool Xdrv20(uint8_t function) #endif switch (function) { case FUNC_WEB_ADD_HANDLER: - WebServer->on(F("/description.xml"), HandleUpnpSetupHue); + Webserver->on(F("/description.xml"), HandleUpnpSetupHue); break; } } diff --git a/tasmota/xdrv_21_wemo.ino b/tasmota/xdrv_21_wemo.ino index 85d462876..5376d4248 100644 --- a/tasmota/xdrv_21_wemo.ino +++ b/tasmota/xdrv_21_wemo.ino @@ -42,7 +42,7 @@ String WemoSerialnumber(void) { char serial[16]; - snprintf_P(serial, sizeof(serial), PSTR("201612K%08X"), ESP.getChipId()); + snprintf_P(serial, sizeof(serial), PSTR("201612K%08X"), ESP_getChipId()); return String(serial); } @@ -85,6 +85,79 @@ void WemoRespondToMSearch(int echo_type) * Wemo web server additions \*********************************************************************************************/ +#ifdef USE_UNISHOX_COMPRESSION + +//SetBinaryStateBinaryStateBinaryStateinGetBinaryStateBinaryStateBinaryStateoutBinaryStatebool0levelstring0\r\n\r\n +//Successfully compressed from 779 to 249 bytes (-68%) +const size_t WEMO_EVENTSERVICE_XML_SIZE = 779; +const char WEMO_EVENTSERVICE_XML[] PROGMEM = "\x3D\x3C\x18\xC1\x11\xB0\x68\x5D\xE3\xE1\xEC\x17\xFE\x3C\xC8\x73\x08\xD3\x78\xF3" + "\xF3\xF9\x9E\x86\xCE\xB3\x90\xEB\x67\xB0\xFC\x3D\x0A\xC3\xAD\xCE\x20\xB7\xD4\x08" + "\x72\x0F\xC3\xD3\xAC\x6B\x3F\x0B\xCE\x88\x76\xF5\xFC\xC8\xBD\x57\x4C\xF4\x3B\x3A" + "\xC6\xB3\xF0\xF4\xBF\x8F\x0B\x1A\xFA\x81\x0B\x0D\x04\x29\x47\xE1\xE9\xF7\x46\x76" + "\x11\xD8\x08\x58\xC0\x27\x62\xBF\x61\x5D\x31\x0B\xD5\x74\xC8\xCE\xFF\xB6\x38\x20" + "\x4A\xC1\x01\x42\xF1\xE8\x26\xFD\x82\x0E\xE7\xBC\x7A\x1D\x80\x8B\x28\xF4\x3B\x01" + "\x17\x59\x04\x48\xE0\x83\xB9\x1D\x80\x87\xC1\x20\x24\x70\x58\x43\xC0\xDA\xF8\x2C" + "\xC1\x74\x0C\x2F\x82\xD0\x42\x8A\x08\x34\x81\x0B\x92\x42\xF5\x5D\x32\xA0\x41\xCE" + "\x7C\x08\xFA\x42\xF3\xE1\x09\x99\xBE\xAF\x1F\x0F\x61\x93\xF1\xEC\x05\x5E\x0A\x44" + "\xBA\xB2\xA3\x21\x8C\xFC\x1D\x98\x11\xE8\x76\x02\x24\xB3\xD0\x46\x62\xC5\x85\x44" + "\x67\x61\x0B\x67\xE1\xC6\x7A\x1D\x84\x09\x13\x0F\x43\xB0\x12\x34\xC0\x60\x5A\xD8" + "\x4C\xCD\x84\x09\x9A\xAF\xAB\xFB\xC3\xC0\xC5\x75\x73\xB0\x13\xB8\x6A\x3B\x3C\x18" + "\xC1\x0F\xC9\xC2\x91\xBA\x70\xA4\x6E"; + +//10GetMetaInfoGetMetaInfoMetaInfoinMetaInfostring0\r\n\r\n +//Successfully compressed from 479 to 253 bytes (-47.2%) +const size_t WEMO_METASERVICE_XML_SIZE = 479; +const char WEMO_METASERVICE_XML[] PROGMEM = "\x3D\x3C\x18\xC1\x11\xB0\x68\x5D\xE3\xE1\xEC\x17\xFE\x3C\xC8\x73\x08\xD3\x78\xF3" + "\xF3\xF9\x9E\x86\xCE\xB3\x90\xEB\x67\xB0\xFC\x3D\x0B\xC3\x18\x64\x66\xFF\xED\xCE" + "\x3F\x0F\x41\xB6\x6B\xCF\x9F\x87\x21\xE8\x76\x10\x20\xC5\x3D\x06\xEF\x67\xCF\xC3" + "\x8C\xF4\x3B\x08\x10\x62\x9E\x87\x60\x24\x61\x56\x1D\x6E\x71\x05\xBE\xA0\x43\x90" + "\x7E\x1E\x9D\x63\x59\xF8\x43\xCE\x88\x6B\xAB\x2D\xE3\x18\x7A\x1D\x9D\x63\x59\xF8" + "\x7A\x5F\xC7\x85\x8D\x7D\x40\x83\x85\x7D\xD1\x9D\x84\x8E\xC0\x55\xC3\x3E\xC2\xBA" + "\x62\x17\xAA\xE9\x91\x9D\xFF\x6C\x70\x4C\xFC\x04\x5C\x04\x14\x2D\x9E\x82\x6F\xD8" + "\x20\xEC\x9B\xC7\xA1\xD8\x08\xB2\x8F\x43\xB0\x12\x75\xB3\xB0\x10\xF8\x0A\x04\x28" + "\xA0\x83\x48\x10\xB8\x74\x2F\x55\xD3\x2A\x2B\x04\x1C\xB7\xC0\x8F\x9E\x2F\x3E\x10" + "\x99\x9B\xEA\xF1\xF0\xF6\x19\x3F\x1E\xC0\x42\xE0\x68\x12\xF8\x17\x12\xEA\xCA\x8C" + "\x86\x33\xF3\xD5\xFD\xE1\xE3\xD0\xEC\x04\x49\xA7\xA0\x8C\xC5\x8B\x0A\x88\xCE\xC2" + "\x16\xCF\xC3\x8C\xF4\x3B\x08\x12\x26\x1E\x87\x60\x24\x69\x67\xE1\xE8\x76\x02\x76" + "\xDC\x76\x78\x31\x82\x1F\x93\x85\x23\x74\xE1\x48\xDC"; + +//%d\r\n +//Successfully compressed from 282 to 161 bytes (-42.9%) +const size_t WEMO_RESPONSE_STATE_SOAP_SIZE = 282; +const char WEMO_RESPONSE_STATE_SOAP[] PROGMEM = "\x3D\x3C\x79\x93\xE3\x36\x16\x0C\x68\xD8\x34\x2E\xF1\xE7\xE3\xE1\xEC\x15\x54\x30" + "\xF3\x3B\x0E\xCF\x06\x29\x8D\xBF\x1D\x0D\x83\x42\xF6\x58\xC3\xA6\x7C\x78\xEC\xF6" + "\x58\xC3\xB1\x82\x16\x1C\x76\x1E\xC5\xE3\xCD\xF0\x78\x26\xF0\xF1\x7A\x8C\x82\x60" + "\xBF\x8C\x02\x0E\x16\x76\x1E\xC3\xF0\xF4\xF1\xE6\x43\xB0\x43\x23\xF0\xF4\x16\x79" + "\x9F\x41\xBA\x21\xDB\xD7\xF3\x22\xF5\x5D\x32\xFB\xF0\xCC\xEF\x02\x1E\xDE\x2C\xF8" + "\x7B\x05\xFF\x8F\x32\x1C\xC2\x34\xDE\x3C\xFC\xFE\x67\xA1\xB3\xCC\x75\xFB\x43\x66" + "\x6F\xA8\xF3\x39\x0F\x61\xF8\x7A\x10\x23\x63\x67\xE1\xF4\x21\xE8\x76\x02\x3C\xC3" + "\xD0\xEC\x05\x4C\xFC\xFC\x3D\x0E\xC0\x43\xD8\xCE\xC0\x45\xE1\xA0\xFC\x9C\x29\x1B" + "\x8D"; + +//urn:Belkin:device:controllee:1{x1Belkin International Inc.Socket3.1415uuid:{x2{x30urn:Belkin:service:basicevent:1urn:Belkin:serviceId:basicevent1/upnp/control/basicevent1/upnp/event/basicevent1/eventservice.xmlurn:Belkin:service:metainfo:1urn:Belkin:serviceId:metainfo1/upnp/control/metainfo1/upnp/event/metainfo1/metainfoservice.xml\r\n +//Successfully compressed from 923 to 392 bytes (-57.5%) +const size_t WEMO_SETUP_XML_SIZE = 923; +const char WEMO_SETUP_XML[] PROGMEM = "\x3D\x0E\xD1\xB0\x68\x48\xCD\xFF\xDB\x9C\x7C\x3D\x87\x21\xD1\x9E\xC3\xB4\x7E\x1E" + "\x85\xFC\xCA\x46\xC1\xA1\x77\x8F\x87\xB0\x5F\xF8\xF3\x21\xCC\x23\x4D\xE3\xCC\x46" + "\x67\xA1\xB3\xAC\xE4\x3A\xD9\xEC\x3F\x0F\x42\x04\x19\x20\x87\x10\xA8\xC8\x63\x3F" + "\x01\x33\x07\x3C\xC3\xCE\xAF\xE0\x41\x36\x79\x9C\x87\xA1\xD8\x40\x8D\x83\x9E\x86" + "\x3F\xAF\x84\x08\xC8\xBA\xC6\xB3\xF0\xF6\x9B\x0E\x43\xD0\xEC\x20\x48\x9C\x7A\x0D" + "\xBE\x16\x62\xC3\xA1\x7F\x7F\x3F\x01\x07\x31\x45\xBD\x4F\xFD\x75\xB9\xD6\x12\x2D" + "\xE0\xCE\x87\xA1\xD8\x09\x18\x21\xE8\x37\x04\x61\x17\x58\xD6\x7E\x17\xB0\x33\x47" + "\x47\xA1\xD8\x08\xB3\x81\x0A\xC8\xB1\xA3\x9F\xCF\xC3\x96\x74\x99\x34\x81\x0E\xD8" + "\x20\xD0\x3D\x08\x59\x08\x5C\x7E\x0B\x17\xA2\x1E\x67\xB4\xD8\x72\x8F\x43\xB0\x88" + "\x59\x08\x5C\x7E\x1E\x9E\x7F\xDB\x04\x3B\xA7\xB4\xD8\x72\xCF\x43\xB0\x81\x22\x71" + "\xE8\x3B\x7A\xFE\x64\x5E\xAB\xA6\x7E\x1C\x67\xA1\xD8\x40\x8F\x2C\xF4\xF3\xF9\x9E" + "\x86\xC8\x2D\xF5\x02\x24\x90\x44\x8A\x09\x7C\x46\x82\x15\x33\xCC\x75\xFB\x43\x66" + "\x6F\xA8\xF3\x39\x0F\x43\xB0\x81\x1F\x09\x04\x3C\x58\xB4\x40\x4E\xC5\x0B\x44\x04" + "\x6C\x58\x11\x71\x52\xD1\x0F\xC3\xD0\x10\xB8\xE0\x21\x65\xF2\x08\xFC\x3B\x05\x8C" + "\xE1\x87\x60\x21\x4D\x3B\x01\x23\x0D\x04\x6C\x08\xF4\x66\x6F\xA8\xBC\x2C\x70\x22" + "\xE1\xEC\xCD\xF5\x02\x4E\x1A\x08\xF8\x09\xE8\x45\xE0\xC6\x08\x2F\xE1\x11\xF8\x08" + "\x34\x81\x0B\x59\x3A\x1B\x06\x84\x7A\x1D\x80\x87\x5C\x11\x37\x2A\x01\x60\xBC\x34" + "\x0D\x75\x7B\xC6\x30\x18\x5F\x0C\xC0\x87\x8A\x03\x02\xE1\x90\x11\xB0\xB0\x5F\xE1" + "\x88\x11\xB0\xB0\x51\xE1\x80\x10\xEE\x82\xDF\x0C\x60\x87\x18\x10\x79\x7D\x04\x2E" + "\x83\xD1\xF8\x7A\x1D\x9F\xCC\xA3\xF2\x70\xA4\x6E"; +#else const char WEMO_EVENTSERVICE_XML[] PROGMEM = "" "" @@ -190,6 +263,7 @@ const char WEMO_SETUP_XML[] PROGMEM = "" "" "\r\n"; +#endif /********************************************************************************************/ @@ -198,7 +272,7 @@ void HandleUpnpEvent(void) AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, PSTR(D_WEMO_BASIC_EVENT)); char event[500]; - strlcpy(event, WebServer->arg(0).c_str(), sizeof(event)); + strlcpy(event, Webserver->arg(0).c_str(), sizeof(event)); // AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("\n%s"), event); @@ -219,7 +293,11 @@ void HandleUpnpEvent(void) } } +#ifdef USE_UNISHOX_COMPRESSION + snprintf_P(event, sizeof(event), Decompress(WEMO_RESPONSE_STATE_SOAP, WEMO_RESPONSE_STATE_SOAP_SIZE).c_str(), state, bitRead(power, devices_present -1), state); +#else snprintf_P(event, sizeof(event), WEMO_RESPONSE_STATE_SOAP, state, bitRead(power, devices_present -1), state); +#endif WSSend(200, CT_XML, event); } @@ -227,21 +305,33 @@ void HandleUpnpService(void) { AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, PSTR(D_WEMO_EVENT_SERVICE)); +#ifdef USE_UNISHOX_COMPRESSION + WSSend(200, CT_PLAIN, Decompress(WEMO_EVENTSERVICE_XML, WEMO_EVENTSERVICE_XML_SIZE)); +#else WSSend(200, CT_PLAIN, FPSTR(WEMO_EVENTSERVICE_XML)); +#endif } void HandleUpnpMetaService(void) { AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, PSTR(D_WEMO_META_SERVICE)); +#ifdef USE_UNISHOX_COMPRESSION + WSSend(200, CT_PLAIN, Decompress(WEMO_METASERVICE_XML, WEMO_METASERVICE_XML_SIZE)); +#else WSSend(200, CT_PLAIN, FPSTR(WEMO_METASERVICE_XML)); +#endif } void HandleUpnpSetupWemo(void) { AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, PSTR(D_WEMO_SETUP)); +#ifdef USE_UNISHOX_COMPRESSION + String setup_xml = Decompress(WEMO_SETUP_XML, WEMO_SETUP_XML_SIZE); +#else String setup_xml = FPSTR(WEMO_SETUP_XML); +#endif setup_xml.replace("{x1", SettingsText(SET_FRIENDLYNAME1)); setup_xml.replace("{x2", WemoUuid()); setup_xml.replace("{x3", WemoSerialnumber()); @@ -259,10 +349,10 @@ bool Xdrv21(uint8_t function) if (devices_present && (EMUL_WEMO == Settings.flag2.emulation)) { switch (function) { case FUNC_WEB_ADD_HANDLER: - WebServer->on("/upnp/control/basicevent1", HTTP_POST, HandleUpnpEvent); - WebServer->on("/eventservice.xml", HandleUpnpService); - WebServer->on("/metainfoservice.xml", HandleUpnpMetaService); - WebServer->on("/setup.xml", HandleUpnpSetupWemo); + Webserver->on(F("/upnp/control/basicevent1"), HTTP_POST, HandleUpnpEvent); + Webserver->on(F("/eventservice.xml"), HandleUpnpService); + Webserver->on(F("/metainfoservice.xml"), HandleUpnpMetaService); + Webserver->on(F("/setup.xml"), HandleUpnpSetupWemo); break; } } diff --git a/tasmota/xdrv_23_zigbee_0_constants.ino b/tasmota/xdrv_23_zigbee_0_constants.ino index 2aeade28d..ea087e70f 100644 --- a/tasmota/xdrv_23_zigbee_0_constants.ino +++ b/tasmota/xdrv_23_zigbee_0_constants.ino @@ -19,11 +19,22 @@ #ifdef USE_ZIGBEE +#if defined(USE_ZIGBEE_ZNP) && defined(USE_ZIGBEE_EZSP) + #error "#define USE_ZIGBEE_ZNP and #define USE_ZIGBEE_EZSP are mutually incompatible" +#endif +#if !defined(USE_ZIGBEE_ZNP) && !defined(USE_ZIGBEE_EZSP) + #error "You must select one of: #define USE_ZIGBEE_ZNP or #define USE_ZIGBEE_EZSP" +#endif + #define OCCUPANCY "Occupancy" // global define for Aqara +#define ZIGBEE_EZSP_RESET_LED 4 // Led number to drive the EZSP Reset pin typedef uint64_t Z_IEEEAddress; typedef uint16_t Z_ShortAddress; +const uint16_t BAD_SHORTADDR = 0xFFFE; + +#ifdef USE_ZIGBEE_ZNP enum ZnpCommandType { Z_POLL = 0x00, Z_SREQ = 0x20, @@ -43,6 +54,713 @@ enum ZnpSubsystem { Z_DEBUG = 0x08, Z_APP = 0x09 }; +#endif // USE_ZIGBEE_ZNP + +#ifdef USE_ZIGBEE_EZSP + +enum EZSPNodeType { + EMBER_UNKNOWN_DEVICE = 0x00, + EMBER_COORDINATOR = 0x01, + EMBER_ROUTER = 0x02, + EMBER_END_DEVICE = 0x03, + EMBER_SLEEPY_END_DEVICE = 0x04 +}; + +enum EZSPDeviceUpdate { + EMBER_STANDARD_SECURITY_SECURED_REJOIN = 0x00, + EMBER_STANDARD_SECURITY_UNSECURED_JOIN = 0x01, + EMBER_DEVICE_LEFT = 0x02, + EMBER_STANDARD_SECURITY_UNSECURED_REJOIN = 0x03, +}; + +enum EZSPJoinDecision { + EMBER_USE_PRECONFIGURED_KEY = 0x00, + EMBER_SEND_KEY_IN_THE_CLEAR = 0x01, + EMBER_DENY_JOIN = 0x02, + EMBER_NO_ACTION = 0x03 +}; + +enum EZSPCurrentSecurytBitMask { + EMBER_STANDARD_SECURITY_MODE = 0x0000, + EMBER_DISTRIBUTED_TRUST_CENTER_MODE = 0x0002, + EMBER_GLOBAL_LINK_KEY = 0x0004, + EMBER_TRUST_CENTER_GLOBAL_LINK_KEY = 0x0004, + EMBER_PRECONFIGURED_NETWORK_KEY_MODE = 0x0008, + EMBER_HAVE_TRUST_CENTER_LINK_KEY = 0x0010, + EMBER_TRUST_CENTER_USES_HASHED_LINK_KEY = 0x0084, + EMBER_HAVE_PRECONFIGURED_KEY = 0x0100, + EMBER_HAVE_NETWORK_KEY = 0x0200, + EMBER_GET_LINK_KEY_WHEN_JOINING = 0x0400, + EMBER_REQUIRE_ENCRYPTED_KEY = 0x0800, + EMBER_NO_FRAME_COUNTER_RESET = 0x1000, + EMBER_GET_PRECONFIGURED_KEY_FROM_INSTALL_CODE = 0x2000, + EMBER_HAVE_TRUST_CENTER_EUI64 = 0x0040 +}; + +enum EZSPJoinMethod { + EMBER_USE_MAC_ASSOCIATION = 0x0, + EMBER_USE_NWK_REJOIN = 0x1, + EMBER_USE_NWK_REJOIN_HAVE_NWK_KEY = 0x2, + EMBER_USE_CONFIGURED_NWK_STATE = 0x3 +}; + +enum EZSPConfigId { + EZSP_CONFIG_PACKET_BUFFER_COUNT = 0x01, + EZSP_CONFIG_NEIGHBOR_TABLE_SIZE = 0x02, + EZSP_CONFIG_APS_UNICAST_MESSAGE_COUNT = 0x03, + EZSP_CONFIG_BINDING_TABLE_SIZE = 0x04, + EZSP_CONFIG_ADDRESS_TABLE_SIZE = 0x05, + EZSP_CONFIG_MULTICAST_TABLE_SIZE = 0x06, + EZSP_CONFIG_ROUTE_TABLE_SIZE = 0x07, + EZSP_CONFIG_DISCOVERY_TABLE_SIZE = 0x08, + EZSP_CONFIG_STACK_PROFILE = 0x0C, + EZSP_CONFIG_SECURITY_LEVEL = 0x0D, + EZSP_CONFIG_MAX_HOPS = 0x10, + EZSP_CONFIG_MAX_END_DEVICE_CHILDREN = 0x11, + EZSP_CONFIG_INDIRECT_TRANSMISSION_TIMEOUT = 0x12, + EZSP_CONFIG_END_DEVICE_POLL_TIMEOUT = 0x13, + EZSP_CONFIG_TX_POWER_MODE = 0x17, + EZSP_CONFIG_DISABLE_RELAY = 0x18, + EZSP_CONFIG_TRUST_CENTER_ADDRESS_CACHE_SIZE = 0x19, + EZSP_CONFIG_SOURCE_ROUTE_TABLE_SIZE = 0x1A, + EZSP_CONFIG_FRAGMENT_WINDOW_SIZE = 0x1C, + EZSP_CONFIG_FRAGMENT_DELAY_MS = 0x1D, + EZSP_CONFIG_KEY_TABLE_SIZE = 0x1E, + EZSP_CONFIG_APS_ACK_TIMEOUT = 0x1F, + EZSP_CONFIG_BEACON_JITTER_DURATION = 0x20, + EZSP_CONFIG_END_DEVICE_BIND_TIMEOUT = 0x21, + EZSP_CONFIG_PAN_ID_CONFLICT_REPORT_THRESHOLD = 0x22, + EZSP_CONFIG_REQUEST_KEY_TIMEOUT = 0x24, + EZSP_CONFIG_CERTIFICATE_TABLE_SIZE = 0x29, + EZSP_CONFIG_APPLICATION_ZDO_FLAGS = 0x2A, + EZSP_CONFIG_BROADCAST_TABLE_SIZE = 0x2B, + EZSP_CONFIG_MAC_FILTER_TABLE_SIZE = 0x2C, + EZSP_CONFIG_SUPPORTED_NETWORKS = 0x2D, + EZSP_CONFIG_SEND_MULTICASTS_TO_SLEEPY_ADDRESS = 0x2E, + EZSP_CONFIG_ZLL_GROUP_ADDRESSES = 0x2F, + EZSP_CONFIG_ZLL_RSSI_THRESHOLD = 0x30, + EZSP_CONFIG_MTORR_FLOW_CONTROL = 0x33, + EZSP_CONFIG_RETRY_QUEUE_SIZE = 0x34, + EZSP_CONFIG_NEW_BROADCAST_ENTRY_THRESHOLD = 0x35, + EZSP_CONFIG_BROADCAST_MIN_ACKS_NEEDED = 0x37, + EZSP_CONFIG_TC_REJOINS_USING_WELL_KNOWN_KEY_TIMEOUT_S = 0x38, + EZSP_CONFIG_CTUNE_VALUE = 0x39 +}; + +enum EZSPValueId { + EZSP_VALUE_TOKEN_STACK_NODE_DATA = 0x00, + EZSP_VALUE_MAC_PASSTHROUGH_FLAGS = 0x01, + EZSP_VALUE_EMBERNET_PASSTHROUGH_SOURCE_ADDRESS = 0x02, + EZSP_VALUE_FREE_BUFFERS = 0x03, + EZSP_VALUE_UART_SYNCH_CALLBACKS = 0x04, + EZSP_VALUE_MAXIMUM_INCOMING_TRANSFER_SIZE = 0x05, + EZSP_VALUE_MAXIMUM_OUTGOING_TRANSFER_SIZE = 0x06, + EZSP_VALUE_STACK_TOKEN_WRITING = 0x07, + EZSP_VALUE_STACK_IS_PERFORMING_REJOIN = 0x08, + EZSP_VALUE_MAC_FILTER_LIST = 0x09, + EZSP_VALUE_EXTENDED_SECURITY_BITMASK = 0x0A, + EZSP_VALUE_NODE_SHORT_ID = 0x0B, + EZSP_VALUE_DESCRIPTOR_CAPABILITY = 0x0C, + EZSP_VALUE_STACK_DEVICE_REQUEST_SEQUENCE_NUMBER = 0x0D, + EZSP_VALUE_RADIO_HOLD_OFF = 0x0E, + EZSP_VALUE_ENDPOINT_FLAGS = 0x0F, + EZSP_VALUE_MFG_SECURITY_CONFIG = 0x10, + EZSP_VALUE_VERSION_INFO = 0x11, + EZSP_VALUE_NEXT_HOST_REJOIN_REASON = 0x12, + EZSP_VALUE_LAST_REJOIN_REASON = 0x13, + EZSP_VALUE_NEXT_ZIGBEE_SEQUENCE_NUMBER = 0x14, + EZSP_VALUE_CCA_THRESHOLD = 0x15, + EZSP_VALUE_SET_COUNTER_THRESHOLD = 0x17, + EZSP_VALUE_RESET_COUNTER_THRESHOLDS = 0x18, + EZSP_VALUE_CLEAR_COUNTERS = 0x19, + EZSP_VALUE_CERTIFICATE_283K1 = 0x1A, + EZSP_VALUE_PUBLIC_KEY_283K1 = 0x1B, + EZSP_VALUE_PRIVATE_KEY_283K1 = 0x1C, + EZSP_VALUE_NWK_FRAME_COUNTER = 0x23, + EZSP_VALUE_APS_FRAME_COUNTER = 0x24, + EZSP_VALUE_RETRY_DEVICE_TYPE = 0x25, + EZSP_VALUE_ENABLE_R21_BEHAVIOR = 0x29, + EZSP_VALUE_ANTENNA_MODE = 0x30, + EZSP_VALUE_ENABLE_PTA = 0x31, + EZSP_VALUE_PTA_OPTIONS = 0x32, + EZSP_VALUE_MFGLIB_OPTIONS = 0x33, + EZSP_VALUE_USE_NEGOTIATED_POWER_BY_LPD = 0x34, + EZSP_VALUE_PTA_PWM_OPTIONS = 0x35, + EZSP_VALUE_PTA_DIRECTIONAL_PRIORITY_PULSE_WIDTH = 0x36, + EZSP_VALUE_PTA_PHY_SELECT_TIMEOUT = 0x37, + EZSP_VALUE_ANTENNA_RX_MODE = 0x38, + EZSP_VALUE_NWK_KEY_TIMEOUT = 0x39, + EZSP_VALUE_FORCE_TX_AFTER_FAILED_CCA_ATTEMPTS = 0x3A, + EZSP_VALUE_TRANSIENT_KEY_TIMEOUT_S = 0x3B, + ZSP_VALUE_COULOMB_COUNTER_USAGE = 0x3C, + EZSP_VALUE_MAX_BEACONS_TO_STORE = 0x3D, + EZSP_VALUE_END_DEVICE_TIMEOUT_OPTIONS_MASK = 0x3E, + EZSP_VALUE_END_DEVICE_KEEP_ALIVE_SUPPORT_MODE = 0x3F, + EZSP_VALUE_GPIO_RADIO_POWER_MASK = 0x40, + EZSP_VALUE_ACTIVE_RADIO_CONFIG = 0x41 +}; + +enum EZSPEmberStatusId { + EMBER_SUCCESS = 0x00, + EMBER_ERR_FATAL = 0x01, + EMBER_BAD_ARGUMENT = 0x02, + EMBER_EEPROM_MFG_STACK_VERSION_MISMATCH = 0x04, + EMBER_INCOMPATIBLE_STATIC_MEMORY_DEFINITIONS = 0x05, + EMBER_EEPROM_MFG_VERSION_MISMATCH = 0x06, + EMBER_EEPROM_STACK_VERSION_MISMATCH = 0x07, + EMBER_NO_BUFFERS = 0x18, + EMBER_SERIAL_INVALID_BAUD_RATE = 0x20, + EMBER_SERIAL_INVALID_PORT = 0x21, + EMBER_SERIAL_TX_OVERFLOW = 0x22, + EMBER_SERIAL_RX_OVERFLOW = 0x23, + EMBER_SERIAL_RX_FRAME_ERROR = 0x24, + EMBER_SERIAL_RX_PARITY_ERROR = 0x25, + EMBER_SERIAL_RX_EMPTY = 0x26, + EMBER_SERIAL_RX_OVERRUN_ERROR = 0x27, + EMBER_MAC_TRANSMIT_QUEUE_FULL = 0x39, + EMBER_MAC_UNKNOWN_HEADER_TYPE = 0x3A, + EMBER_MAC_SCANNING = 0x3D, + EMBER_MAC_NO_DATA = 0x31, + EMBER_MAC_JOINED_NETWORK = 0x32, + EMBER_MAC_BAD_SCAN_DURATION = 0x33, + EMBER_MAC_INCORRECT_SCAN_TYPE = 0x34, + EMBER_MAC_INVALID_CHANNEL_MASK = 0x35, + EMBER_MAC_COMMAND_TRANSMIT_FAILURE = 0x36, + EMBER_MAC_NO_ACK_RECEIVED = 0x40, + EMBER_MAC_INDIRECT_TIMEOUT = 0x42, + EMBER_SIM_EEPROM_ERASE_PAGE_GREEN = 0x43, + EMBER_SIM_EEPROM_ERASE_PAGE_RED = 0x44, + EMBER_SIM_EEPROM_FULL = 0x45, + EMBER_ERR_FLASH_WRITE_INHIBITED = 0x46, + EMBER_ERR_FLASH_VERIFY_FAILED = 0x47, + EMBER_SIM_EEPROM_INIT_1_FAILED = 0x48, + EMBER_SIM_EEPROM_INIT_2_FAILED = 0x49, + EMBER_SIM_EEPROM_INIT_3_FAILED = 0x4A, + EMBER_ERR_FLASH_PROG_FAIL = 0x4B, + EMBER_ERR_FLASH_ERASE_FAIL = 0x4C, + EMBER_ERR_BOOTLOADER_TRAP_TABLE_BAD = 0x58, + EMBER_ERR_BOOTLOADER_TRAP_UNKNOWN = 0x59, + EMBER_ERR_BOOTLOADER_NO_IMAGE = 0x5A, + EMBER_DELIVERY_FAILED = 0x66, + EMBER_BINDING_INDEX_OUT_OF_RANGE = 0x69, + EMBER_ADDRESS_TABLE_INDEX_OUT_OF_RANGE = 0x6A, + EMBER_INVALID_BINDING_INDEX = 0x6C, + EMBER_INVALID_CALL = 0x70, + EMBER_COST_NOT_KNOWN = 0x71, + EMBER_MAX_MESSAGE_LIMIT_REACHED = 0x72, + EMBER_MESSAGE_TOO_LONG = 0x74, + EMBER_BINDING_IS_ACTIVE = 0x75, + EMBER_ADDRESS_TABLE_ENTRY_IS_ACTIVE = 0x76, + EMBER_ADC_CONVERSION_DONE = 0x80, + EMBER_ADC_CONVERSION_BUSY = 0x81, + EMBER_ADC_CONVERSION_DEFERRED = 0x82, + EMBER_ADC_NO_CONVERSION_PENDING = 0x84, + EMBER_SLEEP_INTERRUPTED = 0x85, + EMBER_PHY_TX_UNDERFLOW = 0x88, + EMBER_PHY_TX_INCOMPLETE = 0x89, + EMBER_PHY_INVALID_CHANNEL = 0x8A, + EMBER_PHY_INVALID_POWER = 0x8B, + EMBER_PHY_TX_BUSY = 0x8C, + EMBER_PHY_TX_CCA_FAIL = 0x8D, + EMBER_PHY_OSCILLATOR_CHECK_FAILED = 0x8E, + EMBER_PHY_ACK_RECEIVED = 0x8F, + EMBER_NETWORK_UP = 0x90, + EMBER_NETWORK_DOWN = 0x91, + EMBER_JOIN_FAILED = 0x94, + EMBER_MOVE_FAILED = 0x96, + EMBER_CANNOT_JOIN_AS_ROUTER = 0x98, + EMBER_NODE_ID_CHANGED = 0x99, + EMBER_PAN_ID_CHANGED = 0x9A, + EMBER_NO_BEACONS = 0xAB, + EMBER_RECEIVED_KEY_IN_THE_CLEAR = 0xAC, + EMBER_NO_NETWORK_KEY_RECEIVED = 0xAD, + EMBER_NO_LINK_KEY_RECEIVED = 0xAE, + EMBER_PRECONFIGURED_KEY_REQUIRED = 0xAF, + EMBER_NOT_JOINED = 0x93, + EMBER_INVALID_SECURITY_LEVEL = 0x95, + EMBER_NETWORK_BUSY = 0xA1, + EMBER_INVALID_ENDPOINT = 0xA3, + EMBER_BINDING_HAS_CHANGED = 0xA4, + EMBER_INSUFFICIENT_RANDOM_DATA = 0xA5, + EMBER_APS_ENCRYPTION_ERROR = 0xA6, + EMBER_SECURITY_STATE_NOT_SET = 0xA8, + EMBER_KEY_TABLE_INVALID_ADDRESS = 0xB3, + EMBER_SECURITY_CONFIGURATION_INVALID = 0xB7, + EMBER_TOO_SOON_FOR_SWITCH_KEY = 0xB8, + EMBER_KEY_NOT_AUTHORIZED = 0xBB, + EMBER_SECURITY_DATA_INVALID = 0xBD, + EMBER_SOURCE_ROUTE_FAILURE = 0xA9, + EMBER_MANY_TO_ONE_ROUTE_FAILURE = 0xAA, + EMBER_STACK_AND_HARDWARE_MISMATCH = 0xB0, + EMBER_INDEX_OUT_OF_RANGE = 0xB1, + EMBER_TABLE_FULL = 0xB4, + EMBER_TABLE_ENTRY_ERASED = 0xB6, + EMBER_LIBRARY_NOT_PRESENT = 0xB5, + EMBER_OPERATION_IN_PROGRESS = 0xBA, +}; + +enum EZSPStatusId { + EZSP_SUCCESS = 0x00, + EZSP_SPI_ERR_FATAL = 0x10, + EZSP_SPI_ERR_NCP_RESET = 0x11, + EZSP_SPI_ERR_OVERSIZED_EZSP_FRAME = 0x12, + EZSP_SPI_ERR_ABORTED_TRANSACTION = 0x13, + EZSP_SPI_ERR_MISSING_FRAME_TERMINATOR = 0x14, + EZSP_SPI_ERR_WAIT_SECTION_TIMEOUT = 0x15, + EZSP_SPI_ERR_NO_FRAME_TERMINATOR = 0x16, + EZSP_SPI_ERR_EZSP_COMMAND_OVERSIZED = 0x17, + EZSP_SPI_ERR_EZSP_RESPONSE_OVERSIZED = 0x18, + EZSP_SPI_WAITING_FOR_RESPONSE = 0x19, + EZSP_SPI_ERR_HANDSHAKE_TIMEOUT = 0x1A, + EZSP_SPI_ERR_STARTUP_TIMEOUT = 0x1B, + EZSP_SPI_ERR_STARTUP_FAIL = 0x1C, + EZSP_SPI_ERR_UNSUPPORTED_SPI_COMMAND = 0x1D, + EZSP_ASH_IN_PROGRESS = 0x20, + EZSP_HOST_FATAL_ERROR = 0x21, + EZSP_ASH_NCP_FATAL_ERROR = 0x22, + EZSP_DATA_FRAME_TOO_LONG = 0x23, + EZSP_DATA_FRAME_TOO_SHORT = 0x24, + EZSP_NO_TX_SPACE = 0x25, + EZSP_NO_RX_SPACE = 0x26, + EZSP_NO_RX_DATA = 0x27, + EZSP_NOT_CONNECTED = 0x28, + EZSP_ERROR_VERSION_NOT_SET = 0x30, + EZSP_ERROR_INVALID_FRAME_ID = 0x31, + EZSP_ERROR_WRONG_DIRECTION = 0x32, + EZSP_ERROR_TRUNCATED = 0x33, + EZSP_ERROR_OVERFLOW = 0x34, + EZSP_ERROR_OUT_OF_MEMORY = 0x35, + EZSP_ERROR_INVALID_VALUE = 0x36, + EZSP_ERROR_INVALID_ID = 0x37, + EZSP_ERROR_INVALID_CALL = 0x38, + EZSP_ERROR_NO_RESPONSE = 0x39, + EZSP_ERROR_COMMAND_TOO_LONG = 0x40, + EZSP_ERROR_QUEUE_FULL = 0x41, + EZSP_ERROR_COMMAND_FILTERED = 0x42, + EZSP_ERROR_SECURITY_KEY_ALREADY_SET = 0x43, + EZSP_ERROR_SECURITY_TYPE_INVALID = 0x44, + EZSP_ERROR_SECURITY_PARAMETERS_INVALID = 0x45, + EZSP_ERROR_SECURITY_PARAMETERS_ALREADY_SET = 0x46, + EZSP_ERROR_SECURITY_KEY_NOT_SET = 0x47, + EZSP_ERROR_SECURITY_PARAMETERS_NOT_SET = 0x48, + EZSP_ERROR_UNSUPPORTED_CONTROL = 0x49, + EZSP_ERROR_UNSECURE_FRAME = 0x4A, + EZSP_NO_ERROR = 0xFF +}; + +enum EZSPPolicyId { + EZSP_TRUST_CENTER_POLICY = 0x00, + EZSP_BINDING_MODIFICATION_POLICY = 0x01, + EZSP_UNICAST_REPLIES_POLICY = 0x02, + EZSP_POLL_HANDLER_POLICY = 0x03, + EZSP_MESSAGE_CONTENTS_IN_CALLBACK_POLICY = 0x04, + EZSP_TC_KEY_REQUEST_POLICY = 0x05, + EZSP_APP_KEY_REQUEST_POLICY = 0x06, + EZSP_PACKET_VALIDATE_LIBRARY_POLICY = 0x07, + EZSP_ZLL_POLICY = 0x08, + EZSP_TC_REJOINS_USING_WELL_KNOWN_KEY_POLICY = 0x09 +}; + +enum EZSPDecisionBitmask { + EZSP_DECISION_BITMASK_DEFAULT_CONFIGURATION = 0x0000, + EZSP_DECISION_ALLOW_JOINS = 0x0001, + EZSP_DECISION_ALLOW_UNSECURED_REJOINS = 0x0002, + EZSP_DECISION_SEND_KEY_IN_CLEAR = 0x0004, + EZSP_DECISION_IGNORE_UNSECURED_REJOINS = 0x0008, + EZSP_DECISION_JOINS_USE_INSTALL_CODE_KEY = 0x0010, + EZSP_DECISION_DEFER_JOINS = 0x0020 +}; + +enum EZSPDecisionId { + EZSP_DEFER_JOINS_REJOINS_HAVE_LINK_KEY = 0x07, + EZSP_DISALLOW_BINDING_MODIFICATION = 0x10, + EZSP_ALLOW_BINDING_MODIFICATION = 0x11, + EZSP_CHECK_BINDING_MODIFICATIONS_ARE_VALID_ENDPOINT_CLUSTERS = 0x12, + EZSP_HOST_WILL_NOT_SUPPLY_REPLY = 0x20, + EZSP_HOST_WILL_SUPPLY_REPLY = 0x21, + EZSP_POLL_HANDLER_IGNORE = 0x30, + EZSP_POLL_HANDLER_CALLBACK = 0x31, + EZSP_MESSAGE_TAG_ONLY_IN_CALLBACK = 0x40, + EZSP_MESSAGE_TAG_AND_CONTENTS_IN_CALLBACK = 0x41, + EZSP_DENY_TC_KEY_REQUESTS = 0x50, + EZSP_ALLOW_TC_KEY_REQUESTS_AND_SEND_CURRENT_KEY = 0x51, + EZSP_ALLOW_TC_KEY_REQUEST_AND_GENERATE_NEW_KEY = 0x52, + EZSP_DENY_APP_KEY_REQUESTS = 0x60, + EZSP_ALLOW_APP_KEY_REQUESTS = 0x61, + EZSP_PACKET_VALIDATE_LIBRARY_CHECKS_ENABLED = 0x62, + EZSP_PACKET_VALIDATE_LIBRARY_CHECKS_DISABLED = 0x63 +}; + +enum EZSP_ZdoConfigurationFlags { + EMBER_APP_RECEIVES_SUPPORTED_ZDO_REQUESTS = 0x01, + EMBER_APP_HANDLES_UNSUPPORTED_ZDO_REQUESTS = 0x02, + EMBER_APP_HANDLES_ZDO_ENDPOINT_REQUESTS = 0x04, + EMBER_APP_HANDLES_ZDO_BINDING_REQUESTS = 0x08 +}; + +enum EZSP_EmberIncomingMessageType { + EMBER_INCOMING_UNICAST = 0x00, + EMBER_INCOMING_UNICAST_REPLY = 0x01, + EMBER_INCOMING_MULTICAST = 0x02, + EMBER_INCOMING_MULTICAST_LOOPBACK = 0x03, + EMBER_INCOMING_BROADCAST = 0x04, + EMBER_INCOMING_BROADCAST_LOOPBACK = 0x05, + EMBER_INCOMING_MANY_TO_ONE_ROUTE_REQUEST = 0x06 +}; + +enum EZSP_EmberApsOption { + EMBER_APS_OPTION_NONE = 0x0000, + EMBER_APS_OPTION_ENCRYPTION = 0x0020, + EMBER_APS_OPTION_RETRY = 0x0040, + EMBER_APS_OPTION_ENABLE_ROUTE_DISCOVERY = 0x0100, + EMBER_APS_OPTION_FORCE_ROUTE_DISCOVERY = 0x0200, + EMBER_APS_OPTION_SOURCE_EUI64 = 0x0400, + EMBER_APS_OPTION_DESTINATION_EUI64 = 0x0800, + EMBER_APS_OPTION_ENABLE_ADDRESS_DISCOVERY = 0x1000, + EMBER_APS_OPTION_POLL_RESPONSE = 0x2000, + EMBER_APS_OPTION_ZDO_RESPONSE_REQUIRED = 0x4000, + EMBER_APS_OPTION_FRAGMENT = 0x8000 +}; + +enum EZSP_EmberOutgoingMessageType { + EMBER_OUTGOING_DIRECT = 0x00, + EMBER_OUTGOING_VIA_ADDRESS_TABLE = 0x01, + EMBER_OUTGOING_VIA_BINDING = 0x02, + EMBER_OUTGOING_MULTICAST = 0x03, + EMBER_OUTGOING_MULTICAST_WITH_ALIAS = 0x04, + EMBER_OUTGOING_BROADCAST_WITH_ALIAS = 0x05, + EMBER_OUTGOING_BROADCAST = 0x06 +}; + +// inspired from https://github.com/zigpy/zigpy/blob/dev/zigpy/zdo/types.py +enum EZSP_ZDO { + ZDO_NWK_addr_req = 0x0000, + ZDO_IEEE_addr_req = 0x0001, + ZDO_Node_Desc_req = 0x0002, + ZDO_Power_Desc_req = 0x0003, + ZDO_Simple_Desc_req = 0x0004, + ZDO_Active_EP_req = 0x0005, + ZDO_Match_Desc_req = 0x0006, + ZDO_Complex_Desc_req = 0x0010, + ZDO_User_Desc_req = 0x0011, + ZDO_Discovery_Cache_req = 0x0012, + ZDO_Device_annce = 0x0013, + ZDO_User_Desc_set = 0x0014, + ZDO_System_Server_Discovery_req = 0x0015, + ZDO_Discovery_store_req = 0x0016, + ZDO_Node_Desc_store_req = 0x0017, + ZDO_Active_EP_store_req = 0x0019, + ZDO_Simple_Desc_store_req = 0x001A, + ZDO_Remove_node_cache_req = 0x001B, + ZDO_Find_node_cache_req = 0x001C, + ZDO_Extended_Simple_Desc_req = 0x001D, + ZDO_Extended_Active_EP_req = 0x001E, + ZDO_Parent_annce = 0x001F, + // Bind Management Server Services Responses + ZDO_End_Device_Bind_req = 0x0020, + ZDO_Bind_req = 0x0021, + ZDO_Unbind_req = 0x0022, + // Network Management Server Services Requests + ZDO_Mgmt_Lqi_req = 0x0031, + ZDO_Mgmt_Rtg_req = 0x0032, + ZDO_Mgmt_Bind_req = 0x0033, + ZDO_Mgmt_Leave_req = 0x0034, + ZDO_Mgmt_Permit_Joining_req = 0x0036, + ZDO_Mgmt_NWK_Update_req = 0x0038, + + // Responses + // Device and Service Discovery Server Responses + ZDO_NWK_addr_rsp = 0x8000, + ZDO_IEEE_addr_rsp = 0x8001, + ZDO_Node_Desc_rsp = 0x8002, + ZDO_Power_Desc_rsp = 0x8003, + ZDO_Simple_Desc_rsp = 0x8004, + ZDO_Active_EP_rsp = 0x8005, + ZDO_Match_Desc_rsp = 0x8006, + ZDO_Complex_Desc_rsp = 0x8010, + ZDO_User_Desc_rsp = 0x8011, + ZDO_Discovery_Cache_rsp = 0x8012, + ZDO_User_Desc_conf = 0x8014, + ZDO_System_Server_Discovery_rsp = 0x8015, + ZDO_Discovery_Store_rsp = 0x8016, + ZDO_Node_Desc_store_rsp = 0x8017, + ZDO_Power_Desc_store_rsp = 0x8018, + ZDO_Active_EP_store_rsp = 0x8019, + ZDO_Simple_Desc_store_rsp = 0x801A, + ZDO_Remove_node_cache_rsp = 0x801B, + ZDO_Find_node_cache_rsp = 0x801C, + ZDO_Extended_Simple_Desc_rsp = 0x801D, + ZDO_Extended_Active_EP_rsp = 0x801E, + ZDO_Parent_annce_rsp = 0x801F, + // Bind Management Server Services Responses + ZDO_End_Device_Bind_rsp = 0x8020, + ZDO_Bind_rsp = 0x8021, + ZDO_Unbind_rsp = 0x8022, + // Network Management Server Services Responses + ZDO_Mgmt_Lqi_rsp = 0x8031, + ZDO_Mgmt_Rtg_rsp = 0x8032, + ZDO_Mgmt_Bind_rsp = 0x8033, + ZDO_Mgmt_Leave_rsp = 0x8034, + ZDO_Mgmt_Permit_Joining_rsp = 0x8036, + ZDO_Mgmt_NWK_Update_rsp = 0x8038, +}; + +enum EZSP_Commands { + EZSP_version = 0x0000, + EZSP_getLibraryStatus = 0x0001, + EZSP_addEndpoint = 0x0002, + EZSP_getExtendedValue = 0x0003, + EZSP_getNextBeacon = 0x0004, + EZSP_nop = 0x0005, + EZSP_callback = 0x0006, + EZSP_noCallbacks = 0x0007, + EZSP_getNumStoredBeacons = 0x0008, + EZSP_setToken = 0x0009, + EZSP_getToken = 0x000A, + EZSP_getMfgToken = 0x000B, + EZSP_setMfgToken = 0x000C, + EZSP_stackTokenChangedHandler = 0x000D, + EZSP_setTimer = 0x000E, + EZSP_timerHandler = 0x000F, + EZSP_setConcentrator = 0x0010, + EZSP_setBrokenRouteErrorCode = 0x0011, + EZSP_debugWrite = 0x0012, + EZSP_getXncpInfo = 0x0013, + EZSP_requestLinkKey = 0x0014, + EZSP_setManufacturerCode = 0x0015, + EZSP_setPowerDescriptor = 0x0016, + EZSP_networkInit = 0x0017, + EZSP_networkState = 0x0018, + EZSP_stackStatusHandler = 0x0019, + EZSP_startScan = 0x001A, + EZSP_networkFoundHandler = 0x001B, + EZSP_scanCompleteHandler = 0x001C, + EZSP_stopScan = 0x001D, + EZSP_formNetwork = 0x001E, + EZSP_joinNetwork = 0x001F, + EZSP_leaveNetwork = 0x0020, + EZSP_findAndRejoinNetwork = 0x0021, + EZSP_permitJoining = 0x0022, + EZSP_childJoinHandler = 0x0023, + EZSP_trustCenterJoinHandler = 0x0024, + EZSP_zllClearTokens = 0x0025, + EZSP_getEui64 = 0x0026, + EZSP_getNodeId = 0x0027, + EZSP_getNetworkParameters = 0x0028, + EZSP_getParentChildParameters = 0x0029, + EZSP_clearBindingTable = 0x002A, + EZSP_setBinding = 0x002B, + EZSP_getBinding = 0x002C, + EZSP_deleteBinding = 0x002D, + EZSP_bindingIsActive = 0x002E, + EZSP_getBindingRemoteNodeId = 0x002F, + EZSP_setBindingRemoteNodeId = 0x0030, + EZSP_remoteSetBindingHandler = 0x0031, + EZSP_remoteDeleteBindingHandler = 0x0032, + EZSP_maximumPayloadLength = 0x0033, + EZSP_sendUnicast = 0x0034, + EZSP_getDutyCycleState = 0x0035, + EZSP_sendBroadcast = 0x0036, + EZSP_proxyBroadcast = 0x0037, + EZSP_sendMulticast = 0x0038, + EZSP_sendReply = 0x0039, + EZSP_sendMulticastWithAlias = 0x003A, + EZSP_joinNetworkDirectly = 0x003B, + EZSP_clearStoredBeacons = 0x003C, + EZSP_getFirstBeacon = 0x003D, + EZSP_getNeighborFrameCounter = 0x003E, + EZSP_messageSentHandler = 0x003F, + EZSP_setDutyCycleLimitsInStack = 0x0040, + EZSP_sendManyToOneRouteRequest = 0x0041, + EZSP_pollForData = 0x0042, + EZSP_pollCompleteHandler = 0x0043, + EZSP_pollHandler = 0x0044, + EZSP_incomingMessageHandler = 0x0045, + EZSP_macFilterMatchMessageHandler = 0x0046, + EZSP_customFrame = 0x0047, + EZSP_energyScanResultHandler = 0x0048, + EZSP_getRandomNumber = 0x0049, + EZSP_getChildData = 0x004A, + EZSP_getDutyCycleLimits = 0x004B, + EZSP_getCurrentDutyCycle = 0x004C, + EZSP_dutyCycleHandler = 0x004D, + EZSP_getTimer = 0x004E, + EZSP_getTrueRandomEntropySource = 0x004F, + EZSP_unicastCurrentNetworkKey = 0x0050, + EZSP_sendRawMessageExtended = 0x0051, + EZSP_getConfigurationValue = 0x0052, + EZSP_setConfigurationValue = 0x0053, + EZSP_customFrameHandler = 0x0054, + EZSP_setPolicy = 0x0055, + EZSP_getPolicy = 0x0056, + EZSP_invalidCommand = 0x0058, + EZSP_setSourceRouteDiscoveryMode = 0x005A, + EZSP_addressTableEntryIsActive = 0x005B, + EZSP_setAddressTableRemoteEui64 = 0x005C, + EZSP_setAddressTableRemoteNodeId = 0x005D, + EZSP_getAddressTableRemoteEui64 = 0x005E, + EZSP_getAddressTableRemoteNodeId = 0x005F, + EZSP_lookupNodeIdByEui64 = 0x0060, + EZSP_lookupEui64ByNodeId = 0x0061, + EZSP_incomingSenderEui64Handler = 0x0062, + EZSP_getMulticastTableEntry = 0x0063, + EZSP_setMulticastTableEntry = 0x0064, + EZSP_readAndClearCounters = 0x0065, + EZSP_addOrUpdateKeyTableEntry = 0x0066, + EZSP_sendTrustCenterLinkKey = 0x0067, + EZSP_setInitialSecurityState = 0x0068, + EZSP_getCurrentSecurityState = 0x0069, + EZSP_getKey = 0x006A, + EZSP_clearTransientLinkKeys = 0x006B, + EZSP_updateTcLinkKey = 0x006C, + EZSP_getTransientKeyTableEntry = 0x006D, + EZSP_switchNetworkKeyHandler = 0x006E, + EZSP_aesMmoHash = 0x006F, + EZSP_gpSinkTableInit = 0x0070, + EZSP_getKeyTableEntry = 0x0071, + EZSP_setKeyTableEntry = 0x0072, + EZSP_broadcastNextNetworkKey = 0x0073, + EZSP_broadcastNetworkKeySwitch = 0x0074, + EZSP_findKeyTableEntry = 0x0075, + EZSP_eraseKeyTableEntry = 0x0076, + EZSP_becomeTrustCenter = 0x0077, + EZSP_dsaVerifyHandler = 0x0078, + EZSP_getNeighbor = 0x0079, + EZSP_neighborCount = 0x007A, + EZSP_getRouteTableEntry = 0x007B, + EZSP_idConflictHandler = 0x007C, + EZSP_incomingManyToOneRouteRequestHandler = 0x007D, + EZSP_setExtendedTimeout = 0x007E, + EZSP_getExtendedTimeout = 0x007F, + EZSP_incomingRouteErrorHandler = 0x0080, + EZSP_echo = 0x0081, + EZSP_replaceAddressTableEntry = 0x0082, + EZSP_mfglibStart = 0x0083, + EZSP_mfglibEnd = 0x0084, + EZSP_mfglibStartTone = 0x0085, + EZSP_mfglibStopTone = 0x0086, + EZSP_mfglibStartStream = 0x0087, + EZSP_mfglibStopStream = 0x0088, + EZSP_mfglibSendPacket = 0x0089, + EZSP_mfglibSetChannel = 0x008A, + EZSP_mfglibGetChannel = 0x008B, + EZSP_mfglibSetPower = 0x008C, + EZSP_mfglibGetPower = 0x008D, + EZSP_mfglibRxHandler = 0x008E, + EZSP_launchStandaloneBootloader = 0x008F, + EZSP_sendBootloadMessage = 0x0090, + EZSP_getStandaloneBootloaderVersionPlatMicroPhy = 0x0091, + EZSP_incomingBootloadMessageHandler = 0x0092, + EZSP_bootloadTransmitCompleteHandler = 0x0093, + EZSP_aesEncrypt = 0x0094, + EZSP_overrideCurrentChannel = 0x0095, + EZSP_sendRawMessage = 0x0096, + EZSP_macPassthroughMessageHandler = 0x0097, + EZSP_rawTransmitCompleteHandler = 0x0098, + EZSP_setRadioPower = 0x0099, + EZSP_setRadioChannel = 0x009A, + EZSP_zigbeeKeyEstablishmentHandler = 0x009B, + EZSP_energyScanRequest = 0x009C, + EZSP_delayTest = 0x009D, + EZSP_generateCbkeKeysHandler = 0x009E, + EZSP_calculateSmacs = 0x009F, + EZSP_calculateSmacsHandler = 0x00A0, + EZSP_clearTemporaryDataMaybeStoreLinkKey = 0x00A1, + EZSP_setPreinstalledCbkeData = 0x00A2, + EZSP_dsaVerify = 0x00A3, + EZSP_generateCbkeKeys = 0x00A4, + EZSP_getCertificate = 0x00A5, + EZSP_dsaSign = 0x00A6, + EZSP_dsaSignHandler = 0x00A7, + EZSP_removeDevice = 0x00A8, + EZSP_unicastNwkKeyUpdate = 0x00A9, + EZSP_getValue = 0x00AA, + EZSP_setValue = 0x00AB, + EZSP_setGpioCurrentConfiguration = 0x00AC, + EZSP_setGpioPowerUpDownConfiguration = 0x00AD, + EZSP_setGpioRadioPowerMask = 0x00AE, + EZSP_addTransientLinkKey = 0x00AF, + EZSP_dsaVerify283k1 = 0x00B0, + EZSP_clearKeyTable = 0x00B1, + EZSP_zllNetworkOps = 0x00B2, + EZSP_zllSetInitialSecurityState = 0x00B3, + EZSP_zllStartScan = 0x00B4, + EZSP_zllSetRxOnWhenIdle = 0x00B5, + EZSP_zllNetworkFoundHandler = 0x00B6, + EZSP_zllScanCompleteHandler = 0x00B7, + EZSP_zllAddressAssignmentHandler = 0x00B8, + EZSP_setLogicalAndRadioChannel = 0x00B9, + EZSP_getLogicalChannel = 0x00BA, + EZSP_zllTouchLinkTargetHandler = 0x00BB, + EZSP_zllGetTokens = 0x00BC, + EZSP_zllSetDataToken = 0x00BD, + EZSP_isZllNetwork = 0x00BE, + EZSP_zllSetNonZllNetwork = 0x00BF, + EZSP_gpProxyTableLookup = 0x00C0, + EZSP_getSourceRouteTableEntry = 0x00C1, + EZSP_getSourceRouteTableFilledSize = 0x00C2, + EZSP_getSourceRouteTableTotalSize = 0x00C3, + EZSP_gpepIncomingMessageHandler = 0x00C5, + EZSP_dGpSend = 0x00C6, + EZSP_dGpSentHandler = 0x00C7, + EZSP_gpProxyTableGetEntry = 0x00C8, + EZSP_gpProxyTableProcessGpPairing = 0x00C9, + EZSP_setSecurityKey = 0x00CA, + EZSP_setSecurityParameters = 0x00CB, + EZSP_resetToFactoryDefaults = 0x00CC, + EZSP_getSecurityKeyStatus = 0x00CD, + EZSP_getTransientLinkKey = 0x00CE, + EZSP_zllSetSecurityStateWithoutKey = 0x00CF, + EZSP_setRoutingShortcutThreshold = 0x00D0, + EZSP_getRoutingShortcutThreshold = 0x00D1, + EZSP_unusedPanIdFoundHandler = 0x00D2, + EZSP_findUnusedPanId = 0x00D3, + EZSP_zllSetRadioIdleMode = 0x00D4, + EZSP_setZllNodeType = 0x00D5, + EZSP_setZllAdditionalState = 0x00D6, + EZSP_zllOperationInProgress = 0x00D7, + EZSP_zllRxOnWhenIdleGetActive = 0x00D8, + EZSP_getZllPrimaryChannelMask = 0x00D9, + EZSP_getZllSecondaryChannelMask = 0x00DA, + EZSP_setZllPrimaryChannelMask = 0x00DB, + EZSP_setZllSecondaryChannelMask = 0x00DC, + EZSP_gpSinkTableGetEntry = 0x00DD, + EZSP_gpSinkTableLookup = 0x00DE, + EZSP_gpSinkTableSetEntry = 0x00DF, + EZSP_gpSinkTableRemoveEntry = 0x00E0, + EZSP_gpSinkTableFindOrAllocateEntry = 0x00E1, + EZSP_gpSinkTableClearAll = 0x00E2, + EZSP_setLongUpTime = 0x00E3, + EZSP_setHubConnectivity = 0x00E4, + EZSP_isUpTimeLong = 0x00E5, + EZSP_isHubConnected = 0x00E6, + EZSP_setParentClassificationEnabled = 0x00E7, + EZSP_generateCbkeKeys283k1 = 0x00E8, + EZSP_generateCbkeKeysHandler283k1 = 0x00E9, + EZSP_calculateSmacs283k1 = 0x00EA, + EZSP_calculateSmacsHandler283k1 = 0x00EB, + EZSP_getCertificate283k1 = 0x00EC, + EZSP_savePreinstalledCbkeData283k1 = 0x00ED, + EZSP_clearTemporaryDataMaybeStoreLinkKey283k1 = 0x00EE, + EZSP_setBeaconClassificationParams = 0x00EF, + EZSP_getParentClassificationEnabled = 0x00F0, + EZSP_readCounters = 0x00F1, + EZSP_counterRolloverHandler = 0x00F2, + EZSP_getBeaconClassificationParams = 0x00F3, + EZSP_setMacPollFailureWaitTime = 0x00F4, + EZSP_sendLinkPowerDeltaRequest = 0x00F7, + EZSP_multiPhyStart = 0x00F8, + EZSP_multiPhyStop = 0x00F9, + EZSP_multiPhySetRadioPower = 0x00FA, + EZSP_multiPhySetRadioChannel = 0x00FB, + EZSP_getPhyInterfaceCount = 0x00FC, + EZSP_getRadioParameters = 0x00FD, + EZSP_writeNodeData = 0x00FE, + // Tasmota specifics + EZSP_rstAck = 0xFFFE, +}; + +#endif // USE_ZIGBEE_EZSP // Commands in the SYS subsystem enum SysCommand { @@ -382,7 +1100,6 @@ enum ZCL_Global_Commands { ZCL_DEFAULT_RESPONSE = 0x0b, ZCL_DISCOVER_ATTRIBUTES = 0x0c, ZCL_DISCOVER_ATTRIBUTES_RESPONSE = 0x0d - }; #define ZF(s) static const char ZS_ ## s[] PROGMEM = #s; @@ -393,6 +1110,34 @@ typedef struct Z_StatusLine { const char * status_msg; } Z_StatusLine; + +// ZDP Enumeration, see Zigbee spec 2.4.5 +String getZDPStatusMessage(uint8_t status) { + static const char StatusMsg[] PROGMEM = "SUCCESS|INV_REQUESTTYPE|DEVICE_NOT_FOUND|INVALID_EP|NOT_ACTIVE|NOT_SUPPORTED" + "|TIMEOUT|NO_MATCH|NO_ENTRY|NO_DESCRIPTOR|INSUFFICIENT_SPACE|NOT_PERMITTED" + "|TABLE_FULL|NOT_AUTHORIZED|DEVICE_BINDING_TABLE_FULL" + ; + static const uint8_t StatusIdx[] PROGMEM = { 0x00, 0x80, 0x81, 0x82, 0x83, 0x84, + 0x85, 0x86, 0x88, 0x89, 0x8A, 0x8B, + 0x8C, 0x8D, 0x8E }; + + char msg[32]; + int32_t idx = -1; + for (uint32_t i = 0; i < sizeof(StatusIdx); i++) { + if (status == pgm_read_byte(&StatusIdx[i])) { + idx = i; + break; + } + } + if (idx >= 0) { + GetTextIndexed(msg, sizeof(msg), idx, StatusMsg); + } else { + *msg = 0x00; // empty string + } + return String(msg); +} + + // Undocumented Zigbee ZCL code here: https://github.com/dresden-elektronik/deconz-rest-plugin/wiki/Zigbee-Error-Codes-in-the-Log String getZigbeeStatusMessage(uint8_t status) { static const char StatusMsg[] PROGMEM = "SUCCESS|FAILURE|NOT_AUTHORIZED|RESERVED_FIELD_NOT_ZERO|MALFORMED_COMMAND|UNSUP_CLUSTER_COMMAND|UNSUP_GENERAL_COMMAND" diff --git a/tasmota/xdrv_23_zigbee_1_headers.ino b/tasmota/xdrv_23_zigbee_1_headers.ino index 051858697..046450927 100644 --- a/tasmota/xdrv_23_zigbee_1_headers.ino +++ b/tasmota/xdrv_23_zigbee_1_headers.ino @@ -23,29 +23,9 @@ void ZigbeeZCLSend_Raw(uint16_t dtsAddr, uint16_t groupaddr, uint16_t clusterId, uint8_t endpoint, uint8_t cmdId, bool clusterSpecific, const uint8_t *msg, size_t len, bool needResponse, uint8_t transacId); - -// Get an JSON attribute, with case insensitive key search -JsonVariant &getCaseInsensitive(const JsonObject &json, const char *needle) { - // key can be in PROGMEM - if ((nullptr == &json) || (nullptr == needle) || (0 == pgm_read_byte(needle))) { - return *(JsonVariant*)nullptr; - } - - for (auto kv : json) { - const char *key = kv.key; - JsonVariant &value = kv.value; - - if (0 == strcasecmp_P(key, needle)) { - return value; - } - } - // if not found - return *(JsonVariant*)nullptr; -} - // get the result as a string (const char*) and nullptr if there is no field or the string is empty const char * getCaseInsensitiveConstCharNull(const JsonObject &json, const char *needle) { - const JsonVariant &val = getCaseInsensitive(json, needle); + const JsonVariant &val = GetCaseInsensitive(json, needle); if (&val) { const char *val_cs = val.as(); if (strlen(val_cs)) { diff --git a/tasmota/xdrv_23_zigbee_2_devices.ino b/tasmota/xdrv_23_zigbee_2_devices.ino index 9f5ef60a9..d570c4560 100644 --- a/tasmota/xdrv_23_zigbee_2_devices.ino +++ b/tasmota/xdrv_23_zigbee_2_devices.ino @@ -26,6 +26,24 @@ #endif const uint16_t kZigbeeSaveDelaySeconds = ZIGBEE_SAVE_DELAY_SECONDS; // wait for x seconds +/*********************************************************************************************\ + * Structures for Rules variables related to the last received message +\*********************************************************************************************/ + +typedef struct Z_LastMessageVars { + uint16_t device; // device short address + uint16_t groupaddr; // group address + uint16_t cluster; // cluster id + uint8_t endpoint; // source endpoint +} Z_LastMessageVars; + +Z_LastMessageVars gZbLastMessage; + +uint16_t Z_GetLastDevice(void) { return gZbLastMessage.device; } +uint16_t Z_GetLastGroup(void) { return gZbLastMessage.groupaddr; } +uint16_t Z_GetLastCluster(void) { return gZbLastMessage.cluster; } +uint8_t Z_GetLastEndpoint(void) { return gZbLastMessage.endpoint; } + /*********************************************************************************************\ * Structures for device configuration \*********************************************************************************************/ @@ -53,6 +71,8 @@ typedef struct Z_Device { uint16_t ct; // last CT: 153-500 uint16_t hue; // last Hue: 0..359 uint16_t x, y; // last color [x,y] + uint8_t linkquality; // lqi from last message, 0xFF means unknown + uint8_t batterypercent; // battery percentage (0..100), 0xFF means unknwon } Z_Device; /*********************************************************************************************\ @@ -65,7 +85,7 @@ typedef int32_t (*Z_DeviceTimer)(uint16_t shortaddr, uint16_t groupaddr, uint16_ typedef enum Z_Def_Category { Z_CAT_NONE = 0, // no category, it will happen anyways Z_CAT_READ_ATTR, // Attribute reporting, either READ_ATTRIBUTE or REPORT_ATTRIBUTE, we coalesce all attributes reported if we can - Z_CAT_VIRTUAL_ATTR, // Creation of a virtual attribute, typically after a time-out. Ex: Aqara presence sensor + Z_CAT_VIRTUAL_OCCUPANCY, // Creation of a virtual attribute, typically after a time-out. Ex: Aqara presence sensor Z_CAT_REACHABILITY, // timer set to measure reachability of device, i.e. if we don't get an answer after 1s, it is marked as unreachable (for Alexa) Z_CAT_READ_0006, // Read 0x0006 cluster Z_CAT_READ_0008, // Read 0x0008 cluster @@ -103,7 +123,7 @@ public: // Probe the existence of device keys // Results: // - 0x0000 = not found - // - 0xFFFF = bad parameter + // - BAD_SHORTADDR = bad parameter // - 0x = the device's short address uint16_t isKnownShortAddr(uint16_t shortaddr) const; uint16_t isKnownLongAddr(uint64_t longaddr) const; @@ -127,7 +147,12 @@ public: void setFriendlyName(uint16_t shortaddr, const char * str); const char * getFriendlyName(uint16_t shortaddr) const; const char * getModelId(uint16_t shortaddr) const; + const char * getManufacturerId(uint16_t shortaddr) const; void setReachable(uint16_t shortaddr, bool reachable); + void setLQI(uint16_t shortaddr, uint8_t lqi); + uint8_t getLQI(uint16_t shortaddr) const; + void setBatteryPercent(uint16_t shortaddr, uint8_t bp); + uint8_t getBatteryPercent(uint16_t shortaddr) const; // get next sequence number for (increment at each all) uint8_t getNextSeqNumber(uint16_t shortaddr); @@ -219,6 +244,7 @@ Z_Devices zigbee_devices = Z_Devices(); // Local coordinator information uint64_t localIEEEAddr = 0; +uint16_t localShortAddr = 0; /*********************************************************************************************\ * Implementation @@ -255,7 +281,7 @@ int32_t Z_Devices::findEndpointInVector(const std::vector & vecOfElements, u // entry with same shortaddr or longaddr exists. // Z_Device & Z_Devices::createDeviceEntry(uint16_t shortaddr, uint64_t longaddr) { - if (!shortaddr && !longaddr) { return *(Z_Device*) nullptr; } // it is not legal to create an enrty with both short/long addr null + if ((BAD_SHORTADDR == shortaddr) && !longaddr) { return *(Z_Device*) nullptr; } // it is not legal to create this entry //Z_Device* device_alloc = (Z_Device*) malloc(sizeof(Z_Device)); Z_Device* device_alloc = new Z_Device{ longaddr, @@ -275,6 +301,8 @@ Z_Device & Z_Devices::createDeviceEntry(uint16_t shortaddr, uint64_t longaddr) { 200, // ct 0, // hue 0, 0, // x, y + 0xFF, // lqi, 0xFF = unknown + 0xFF // battery percentage x 2, 0xFF means unknown }; device_alloc->json_buffer = new DynamicJsonBuffer(16); @@ -294,18 +322,16 @@ void Z_Devices::freeDeviceEntry(Z_Device *device) { // Scan all devices to find a corresponding shortaddr // Looks info device.shortaddr entry // In: -// shortaddr (non null) +// shortaddr (not BAD_SHORTADDR) // Out: // index in _devices of entry, -1 if not found // int32_t Z_Devices::findShortAddr(uint16_t shortaddr) const { - if (!shortaddr) { return -1; } // does not make sense to look for 0x0000 shortaddr (localhost) + if (BAD_SHORTADDR == shortaddr) { return -1; } // does not make sense to look for BAD_SHORTADDR shortaddr (broadcast) int32_t found = 0; - if (shortaddr) { - for (auto &elem : _devices) { - if (elem->shortaddr == shortaddr) { return found; } - found++; - } + for (auto &elem : _devices) { + if (elem->shortaddr == shortaddr) { return found; } + found++; } return -1; } @@ -320,11 +346,9 @@ int32_t Z_Devices::findShortAddr(uint16_t shortaddr) const { int32_t Z_Devices::findLongAddr(uint64_t longaddr) const { if (!longaddr) { return -1; } int32_t found = 0; - if (longaddr) { - for (auto &elem : _devices) { - if (elem->longaddr == longaddr) { return found; } - found++; - } + for (auto &elem : _devices) { + if (elem->longaddr == longaddr) { return found; } + found++; } return -1; } @@ -343,7 +367,7 @@ int32_t Z_Devices::findFriendlyName(const char * name) const { if (name_len) { for (auto &elem : _devices) { if (elem->friendlyName) { - if (strcmp(elem->friendlyName, name) == 0) { return found; } + if (strcasecmp(elem->friendlyName, name) == 0) { return found; } } found++; } @@ -357,7 +381,7 @@ uint16_t Z_Devices::isKnownShortAddr(uint16_t shortaddr) const { if (found >= 0) { return shortaddr; } else { - return 0; // unknown + return BAD_SHORTADDR; // unknown } } @@ -367,7 +391,7 @@ uint16_t Z_Devices::isKnownLongAddr(uint64_t longaddr) const { const Z_Device & device = devicesAt(found); return device.shortaddr; // can be zero, if not yet registered } else { - return 0; + return BAD_SHORTADDR; } } @@ -376,18 +400,18 @@ uint16_t Z_Devices::isKnownIndex(uint32_t index) const { const Z_Device & device = devicesAt(index); return device.shortaddr; } else { - return 0; + return BAD_SHORTADDR; } } uint16_t Z_Devices::isKnownFriendlyName(const char * name) const { - if ((!name) || (0 == strlen(name))) { return 0xFFFF; } // Error + if ((!name) || (0 == strlen(name))) { return BAD_SHORTADDR; } // Error int32_t found = findFriendlyName(name); if (found >= 0) { const Z_Device & device = devicesAt(found); return device.shortaddr; // can be zero, if not yet registered } else { - return 0; + return BAD_SHORTADDR; } } @@ -397,10 +421,10 @@ uint64_t Z_Devices::getDeviceLongAddr(uint16_t shortaddr) const { } // -// We have a seen a shortaddr on the network, get the corresponding +// We have a seen a shortaddr on the network, get the corresponding device object // Z_Device & Z_Devices::getShortAddr(uint16_t shortaddr) { - if (!shortaddr) { return *(Z_Device*) nullptr; } // this is not legal + if (BAD_SHORTADDR == shortaddr) { return *(Z_Device*) nullptr; } // this is not legal int32_t found = findShortAddr(shortaddr); if (found >= 0) { return *(_devices[found]); @@ -410,7 +434,7 @@ Z_Device & Z_Devices::getShortAddr(uint16_t shortaddr) { } // Same version but Const const Z_Device & Z_Devices::getShortAddrConst(uint16_t shortaddr) const { - if (!shortaddr) { return *(Z_Device*) nullptr; } // this is not legal + if (BAD_SHORTADDR == shortaddr) { return *(Z_Device*) nullptr; } // this is not legal int32_t found = findShortAddr(shortaddr); if (found >= 0) { return *(_devices[found]); @@ -470,7 +494,7 @@ void Z_Devices::updateDevice(uint16_t shortaddr, uint64_t longaddr) { dirty(); } else { // neither short/lonf addr are found. - if (shortaddr || longaddr) { + if ((BAD_SHORTADDR != shortaddr) || longaddr) { createDeviceEntry(shortaddr, longaddr); } } @@ -480,7 +504,6 @@ void Z_Devices::updateDevice(uint16_t shortaddr, uint64_t longaddr) { // Clear all endpoints // void Z_Devices::clearEndpoints(uint16_t shortaddr) { - if (!shortaddr) { return; } Z_Device &device = getShortAddr(shortaddr); if (&device == nullptr) { return; } // don't crash if not found @@ -494,7 +517,6 @@ void Z_Devices::clearEndpoints(uint16_t shortaddr) { // Add an endpoint to a shortaddr // void Z_Devices::addEndpoint(uint16_t shortaddr, uint8_t endpoint) { - if (!shortaddr) { return; } if (0x00 == endpoint) { return; } Z_Device &device = getShortAddr(shortaddr); if (&device == nullptr) { return; } // don't crash if not found @@ -513,6 +535,8 @@ void Z_Devices::addEndpoint(uint16_t shortaddr, uint8_t endpoint) { // Find the first endpoint of the device uint8_t Z_Devices::findFirstEndpoint(uint16_t shortaddr) const { + // When in router of end-device mode, the coordinator was not probed, in this case always talk to endpoint 1 + if (0x0000 == shortaddr) { return 1; } int32_t found = findShortAddr(shortaddr); if (found < 0) return 0; // avoid creating an entry if the device was never seen const Z_Device &device = devicesAt(found); @@ -589,12 +613,51 @@ const char * Z_Devices::getModelId(uint16_t shortaddr) const { return nullptr; } +const char * Z_Devices::getManufacturerId(uint16_t shortaddr) const { + int32_t found = findShortAddr(shortaddr); + if (found >= 0) { + const Z_Device & device = devicesAt(found); + return device.manufacturerId; + } + return nullptr; +} + void Z_Devices::setReachable(uint16_t shortaddr, bool reachable) { Z_Device & device = getShortAddr(shortaddr); if (&device == nullptr) { return; } // don't crash if not found bitWrite(device.power, 7, reachable); } +void Z_Devices::setLQI(uint16_t shortaddr, uint8_t lqi) { + Z_Device & device = getShortAddr(shortaddr); + if (&device == nullptr) { return; } // don't crash if not found + device.linkquality = lqi; +} + +uint8_t Z_Devices::getLQI(uint16_t shortaddr) const { + int32_t found = findShortAddr(shortaddr); + if (found >= 0) { + const Z_Device & device = devicesAt(found); + return device.linkquality; + } + return 0xFF; +} + +void Z_Devices::setBatteryPercent(uint16_t shortaddr, uint8_t bp) { + Z_Device & device = getShortAddr(shortaddr); + if (&device == nullptr) { return; } // don't crash if not found + device.batterypercent = bp; +} + +uint8_t Z_Devices::getBatteryPercent(uint16_t shortaddr) const { + int32_t found = findShortAddr(shortaddr); + if (found >= 0) { + const Z_Device & device = devicesAt(found); + return device.batterypercent; + } + return 0xFF; +} + // get the next sequance number for the device, or use the global seq number if device is unknown uint8_t Z_Devices::getNextSeqNumber(uint16_t shortaddr) { int32_t short_found = findShortAddr(shortaddr); @@ -856,21 +919,21 @@ const JsonObject *Z_Devices::jsonGet(uint16_t shortaddr) { void Z_Devices::jsonPublishFlush(uint16_t shortaddr) { Z_Device & device = getShortAddr(shortaddr); if (&device == nullptr) { return; } // don't crash if not found - JsonObject * json = device.json; - if (json == nullptr) { return; } // abort if nothing in buffer + JsonObject & json = *device.json; + if (&json == nullptr) { return; } // abort if nothing in buffer const char * fname = zigbee_devices.getFriendlyName(shortaddr); bool use_fname = (Settings.flag4.zigbee_use_names) && (fname); // should we replace shortaddr with friendlyname? - // Remove redundant "Name" or "Device" - if (use_fname) { - json->remove(F(D_JSON_ZIGBEE_NAME)); - } else { - json->remove(F(D_JSON_ZIGBEE_DEVICE)); - } + // save parameters is global variables to be used by Rules + gZbLastMessage.device = shortaddr; // %zbdevice% + gZbLastMessage.groupaddr = json[F(D_CMND_ZIGBEE_GROUP)]; // %zbgroup% + gZbLastMessage.cluster = json[F(D_CMND_ZIGBEE_CLUSTER)]; // %zbcluster% + gZbLastMessage.endpoint = json[F(D_CMND_ZIGBEE_ENDPOINT)]; // %zbendpoint% + // dump json in string String msg = ""; - json->printTo(msg); + json.printTo(msg); zigbee_devices.jsonClear(shortaddr); if (use_fname) { @@ -885,7 +948,7 @@ void Z_Devices::jsonPublishFlush(uint16_t shortaddr) { } else { MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR), Settings.flag.mqtt_sensor_retain); } - XdrvRulesProcess(); + XdrvRulesProcess(); // apply rules } void Z_Devices::jsonPublishNow(uint16_t shortaddr, JsonObject & values) { @@ -912,14 +975,14 @@ uint16_t Z_Devices::parseDeviceParam(const char * param, bool short_must_be_know char dataBuf[param_len + 1]; strcpy(dataBuf, param); RemoveSpace(dataBuf); - uint16_t shortaddr = 0; + uint16_t shortaddr = BAD_SHORTADDR; // start with unknown if (strlen(dataBuf) < 4) { // simple number 0..99 if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload <= 99)) { shortaddr = zigbee_devices.isKnownIndex(XdrvMailbox.payload - 1); } - } else if ((dataBuf[0] == '0') && (dataBuf[1] == 'x')) { + } else if ((dataBuf[0] == '0') && ((dataBuf[1] == 'x') || (dataBuf[1] == 'X'))) { // starts with 0x if (strlen(dataBuf) < 18) { // expect a short address @@ -1008,8 +1071,8 @@ String Z_Devices::dump(uint32_t dump_mode, uint16_t status_shortaddr) const { uint16_t shortaddr = device.shortaddr; char hex[22]; - // ignore non-current device, if specified device is non-zero - if ((status_shortaddr) && (status_shortaddr != shortaddr)) { continue; } + // ignore non-current device, if device specified + if ((BAD_SHORTADDR != status_shortaddr) && (status_shortaddr != shortaddr)) { continue; } JsonObject& dev = devices.createNestedObject(); @@ -1071,7 +1134,7 @@ int32_t Z_Devices::deviceRestore(const JsonObject &json) { size_t endpoints_len = 0; // read mandatory "Device" - const JsonVariant &val_device = getCaseInsensitive(json, PSTR("Device")); + const JsonVariant &val_device = GetCaseInsensitive(json, PSTR("Device")); if (nullptr != &val_device) { device = strToUInt(val_device); } else { @@ -1079,7 +1142,7 @@ int32_t Z_Devices::deviceRestore(const JsonObject &json) { } // read "IEEEAddr" 64 bits in format "0x0000000000000000" - const JsonVariant &val_ieeeaddr = getCaseInsensitive(json, PSTR("IEEEAddr")); + const JsonVariant &val_ieeeaddr = GetCaseInsensitive(json, PSTR("IEEEAddr")); if (nullptr != &val_ieeeaddr) { ieeeaddr = strtoull(val_ieeeaddr.as(), nullptr, 0); } @@ -1094,7 +1157,7 @@ int32_t Z_Devices::deviceRestore(const JsonObject &json) { manufid = getCaseInsensitiveConstCharNull(json, PSTR("Manufacturer")); // read "Light" - const JsonVariant &val_bulbtype = getCaseInsensitive(json, PSTR(D_JSON_ZIGBEE_LIGHT)); + const JsonVariant &val_bulbtype = GetCaseInsensitive(json, PSTR(D_JSON_ZIGBEE_LIGHT)); if (nullptr != &val_bulbtype) { bulbtype = strToUInt(val_bulbtype);; } // update internal device information @@ -1105,7 +1168,7 @@ int32_t Z_Devices::deviceRestore(const JsonObject &json) { if (&val_bulbtype) { setHueBulbtype(device, bulbtype); } // read "Endpoints" - const JsonVariant &val_endpoints = getCaseInsensitive(json, PSTR("Endpoints")); + const JsonVariant &val_endpoints = GetCaseInsensitive(json, PSTR("Endpoints")); if ((nullptr != &val_endpoints) && (val_endpoints.is())) { const JsonArray &arr_ep = val_endpoints.as(); endpoints_len = arr_ep.size(); diff --git a/tasmota/xdrv_23_zigbee_3_hue.ino b/tasmota/xdrv_23_zigbee_3_hue.ino index 0d00ad9e0..e4e8a8b63 100644 --- a/tasmota/xdrv_23_zigbee_3_hue.ino +++ b/tasmota/xdrv_23_zigbee_3_hue.ino @@ -75,16 +75,21 @@ void HueLightStatus1Zigbee(uint16_t shortaddr, uint8_t local_light_subtype, Stri void HueLightStatus2Zigbee(uint16_t shortaddr, String *response) { - const size_t buf_size = 192; + const size_t buf_size = 300; char * buf = (char*) malloc(buf_size); const char * friendlyName = zigbee_devices.getFriendlyName(shortaddr); + const char * modelId = zigbee_devices.getModelId(shortaddr); + const char * manufacturerId = zigbee_devices.getManufacturerId(shortaddr); char shortaddrname[8]; snprintf_P(shortaddrname, sizeof(shortaddrname), PSTR("0x%04X"), shortaddr); snprintf_P(buf, buf_size, HUE_LIGHTS_STATUS_JSON2, - (friendlyName) ? friendlyName : shortaddrname, + (friendlyName) ? EscapeJSONString(friendlyName).c_str() : shortaddrname, + (modelId) ? EscapeJSONString(modelId).c_str() : PSTR("Unknown"), + (manufacturerId) ? EscapeJSONString(manufacturerId).c_str() : PSTR("Tasmota"), GetHueDeviceId(shortaddr).c_str()); + *response += buf; free(buf); } @@ -190,23 +195,21 @@ void ZigbeeHandleHue(uint16_t shortaddr, uint32_t device_id, String &response) { const size_t buf_size = 100; char * buf = (char*) malloc(buf_size); - if (WebServer->args()) { + if (Webserver->args()) { response = "["; StaticJsonBuffer<300> jsonBuffer; - JsonObject &hue_json = jsonBuffer.parseObject(WebServer->arg((WebServer->args())-1)); + JsonObject &hue_json = jsonBuffer.parseObject(Webserver->arg((Webserver->args())-1)); if (hue_json.containsKey("on")) { on = hue_json["on"]; snprintf_P(buf, buf_size, PSTR("{\"success\":{\"/lights/%d/state/on\":%s}}"), device_id, on ? "true" : "false"); - switch(on) - { - case false : ZigbeeHuePower(shortaddr, 0x00); - break; - case true : ZigbeeHuePower(shortaddr, 0x01); - break; + if (on) { + ZigbeeHuePower(shortaddr, 0x01); + } else { + ZigbeeHuePower(shortaddr, 0x00); } response += buf; resp = true; diff --git a/tasmota/xdrv_23_zigbee_4_persistence.ino b/tasmota/xdrv_23_zigbee_4_persistence.ino index d7b0d0f59..88126d2fc 100644 --- a/tasmota/xdrv_23_zigbee_4_persistence.ino +++ b/tasmota/xdrv_23_zigbee_4_persistence.ino @@ -45,62 +45,34 @@ // str - Manuf (null terminated C string, 32 chars max) // str - FriendlyName (null terminated C string, 32 chars max) // reserved for extensions -// -- V2 -- +// -- V2 -- // int8_t - bulbtype // Memory footprint +#ifdef ESP8266 const static uint16_t z_spi_start_sector = 0xFF; // Force last bank of first MB const static uint8_t* z_spi_start = (uint8_t*) 0x402FF000; // 0x402FF000 -const static uint8_t* z_dev_start = z_spi_start + 0x0800; // 0x402FF800 - 2KB -const static size_t z_spi_len = 0x1000; // 4kb blocs +const static uint8_t* z_dev_start = z_spi_start + 0x0800; // 0x402FF800 - 2KB +const static size_t z_spi_len = 0x1000; // 4kb blocks const static size_t z_block_offset = 0x0800; const static size_t z_block_len = 0x0800; // 2kb +#else // ESP32 +uint8_t* z_dev_start; +const static size_t z_spi_len = 0x1000; // 4kb blocks +const static size_t z_block_offset = 0x0000; // No offset needed +const static size_t z_block_len = 0x1000; // 4kb +#endif class z_flashdata_t { public: uint32_t name; // simple 4 letters name. Currently 'skey', 'crt ', 'crt1', 'crt2' uint16_t len; // len of object uint16_t reserved; // align on 4 bytes boundary -}; +}; const static uint32_t ZIGB_NAME = 0x3167697A; // 'zig1' little endian const static size_t Z_MAX_FLASH = z_block_len - sizeof(z_flashdata_t); // 2040 -// encoding for the most commonly 32 clusters, used for binary encoding -const uint16_t Z_ClusterNumber[] PROGMEM = { - 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, - 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, - 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, - 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, - 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, - 0x0100, 0x0101, 0x0102, - 0x0201, 0x0202, 0x0203, 0x0204, - 0x0300, 0x0301, - 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, - 0x0500, 0x0501, 0x0502, - 0x0700, 0x0701, 0x0702, - 0x0B00, 0x0B01, 0x0B02, 0x0B03, 0x0B04, 0x0B05, - 0x1000, - 0xFC0F, -}; - -// convert a 1 byte cluster code to the actual cluster number -uint16_t fromClusterCode(uint8_t c) { - if (c >= sizeof(Z_ClusterNumber)/sizeof(Z_ClusterNumber[0])) { - return 0xFFFF; // invalid - } - return pgm_read_word(&Z_ClusterNumber[c]); -} - -// convert a cluster number to 1 byte, or 0xFF if not in table -uint8_t toClusterCode(uint16_t c) { - for (uint32_t i = 0; i < sizeof(Z_ClusterNumber)/sizeof(Z_ClusterNumber[0]); i++) { - if (c == pgm_read_word(&Z_ClusterNumber[i])) { - return i; - } - } - return 0xFF; // not found -} class SBuffer hibernateDevice(const struct Z_Device &device) { SBuffer buf(128); @@ -202,18 +174,8 @@ void hydrateDevices(const SBuffer &buf) { for (uint32_t i = 0; (i < num_devices) && (k < buf_len); i++) { uint32_t dev_record_len = buf.get8(k); -// AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "Device %d Before Memory = %d // DIFF %d // record_len %d"), i, ESP.getFreeHeap(), before - ESP.getFreeHeap(), dev_record_len); -// before = ESP.getFreeHeap(); - SBuffer buf_d = buf.subBuffer(k, dev_record_len); -// char *hex_char = (char*) malloc((dev_record_len * 2) + 2); -// if (hex_char) { -// AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "/// SUB %s"), -// ToHex_P(buf_d.getBuffer(), dev_record_len, hex_char, (dev_record_len * 2) + 2)); -// free(hex_char); -// } - uint32_t d = 1; // index in device buffer uint16_t shortaddr = buf_d.get16(d); d += 2; uint64_t longaddr = buf_d.get64(d); d += 8; @@ -238,7 +200,7 @@ void hydrateDevices(const SBuffer &buf) { // ignore } } -//AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "Device 0x%04X Memory3.shrink = %d"), shortaddr, ESP.getFreeHeap()); +//AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "Device 0x%04X Memory3.shrink = %d"), shortaddr, ESP_getFreeHeap()); // parse 3 strings char empty[] = ""; @@ -269,14 +231,24 @@ void hydrateDevices(const SBuffer &buf) { // next iteration k += dev_record_len; -//AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "Device %d After Memory = %d"), i, ESP.getFreeHeap()); +//AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "Device %d After Memory = %d"), i, ESP_getFreeHeap()); } } void loadZigbeeDevices(void) { +#ifdef ESP32 + // first copy SPI buffer into ram + uint8_t *spi_buffer = (uint8_t*) malloc(z_spi_len); + if (!spi_buffer) { + AddLog_P2(LOG_LEVEL_ERROR, PSTR(D_LOG_ZIGBEE "Cannot allocate 4KB buffer")); + return; + } + ZigbeeRead(&spi_buffer, z_spi_len); + z_dev_start = spi_buffer; +#endif // ESP32 z_flashdata_t flashdata; memcpy_P(&flashdata, z_dev_start, sizeof(z_flashdata_t)); -// AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE "Memory %d"), ESP.getFreeHeap()); +// AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE "Memory %d"), ESP_getFreeHeap()); AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE "Zigbee signature in Flash: %08X - %d"), flashdata.name, flashdata.len); // Check the signature @@ -291,7 +263,10 @@ void loadZigbeeDevices(void) { } else { AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "No zigbee devices data in Flash")); } -// AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE "Memory %d"), ESP.getFreeHeap()); +// AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE "Memory %d"), ESP_getFreeHeap()); +#ifdef ESP32 + free(spi_buffer); +#endif // ESP32 } void saveZigbeeDevices(void) { @@ -309,7 +284,11 @@ void saveZigbeeDevices(void) { return; } // copy the flash into RAM to make local change, and write back the whole buffer +#ifdef ESP8266 ESP.flashRead(z_spi_start_sector * SPI_FLASH_SEC_SIZE, (uint32_t*) spi_buffer, SPI_FLASH_SEC_SIZE); +#else // ESP32 + ZigbeeRead(&spi_buffer, z_spi_len); +#endif // ESP8266 - ESP32 z_flashdata_t *flashdata = (z_flashdata_t*)(spi_buffer + z_block_offset); flashdata->name = ZIGB_NAME; @@ -319,17 +298,22 @@ void saveZigbeeDevices(void) { memcpy(spi_buffer + z_block_offset + sizeof(z_flashdata_t), buf.getBuffer(), buf_len); // buffer is now ready, write it back +#ifdef ESP8266 if (ESP.flashEraseSector(z_spi_start_sector)) { ESP.flashWrite(z_spi_start_sector * SPI_FLASH_SEC_SIZE, (uint32_t*) spi_buffer, SPI_FLASH_SEC_SIZE); } - - free(spi_buffer); AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "Zigbee Devices Data store in Flash (0x%08X - %d bytes)"), z_dev_start, buf_len); +#else // ESP32 + ZigbeeWrite(&spi_buffer, z_spi_len); + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "Zigbee Devices Data saved (%d bytes)"), buf_len); +#endif // ESP8266 - ESP32 + free(spi_buffer); } // Erase the flash area containing the ZigbeeData void eraseZigbeeDevices(void) { zigbee_devices.clean(); // avoid writing data to flash after erase +#ifdef ESP8266 // first copy SPI buffer into ram uint8_t *spi_buffer = (uint8_t*) malloc(z_spi_len); if (!spi_buffer) { @@ -341,7 +325,7 @@ void eraseZigbeeDevices(void) { // Fill the Zigbee area with 0xFF memset(spi_buffer + z_block_offset, 0xFF, z_block_len); - + // buffer is now ready, write it back if (ESP.flashEraseSector(z_spi_start_sector)) { ESP.flashWrite(z_spi_start_sector * SPI_FLASH_SEC_SIZE, (uint32_t*) spi_buffer, SPI_FLASH_SEC_SIZE); @@ -349,6 +333,10 @@ void eraseZigbeeDevices(void) { free(spi_buffer); AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "Zigbee Devices Data erased (0x%08X - %d bytes)"), z_dev_start, z_block_len); +#else // ESP32 + ZigbeeErase(); + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "Zigbee Devices Data erased (%d bytes)"), z_block_len); +#endif // ESP8266 - ESP32 } #endif // USE_ZIGBEE diff --git a/tasmota/xdrv_23_zigbee_5_converters.ino b/tasmota/xdrv_23_zigbee_5_converters.ino index 7a8ea4806..4cba00500 100644 --- a/tasmota/xdrv_23_zigbee_5_converters.ino +++ b/tasmota/xdrv_23_zigbee_5_converters.ino @@ -23,525 +23,121 @@ * ZCL \*********************************************************************************************/ -typedef union ZCLHeaderFrameControl_t { - struct { - uint8_t frame_type : 2; // 00 = across entire profile, 01 = cluster specific - uint8_t manuf_specific : 1; // Manufacturer Specific Sub-field - uint8_t direction : 1; // 0 = tasmota to zigbee, 1 = zigbee to tasmota - uint8_t disable_def_resp : 1; // don't send back default response - uint8_t reserved : 3; - } b; - uint32_t d8; // raw 8 bits field -} ZCLHeaderFrameControl_t; - -class ZCLFrame { -public: - - ZCLFrame(uint8_t frame_control, uint16_t manuf_code, uint8_t transact_seq, uint8_t cmd_id, - const char *buf, size_t buf_len, uint16_t clusterid, uint16_t groupaddr, - uint16_t srcaddr, uint8_t srcendpoint, uint8_t dstendpoint, uint8_t wasbroadcast, - uint8_t linkquality, uint8_t securityuse, uint8_t seqnumber, - uint32_t timestamp): - _cmd_id(cmd_id), _manuf_code(manuf_code), _transact_seq(transact_seq), - _payload(buf_len ? buf_len : 250), // allocate the data frame from source or preallocate big enough - _cluster_id(clusterid), _groupaddr(groupaddr), - _srcaddr(srcaddr), _srcendpoint(srcendpoint), _dstendpoint(dstendpoint), _wasbroadcast(wasbroadcast), - _linkquality(linkquality), _securityuse(securityuse), _seqnumber(seqnumber), - _timestamp(timestamp) - { - _frame_control.d8 = frame_control; - _payload.addBuffer(buf, buf_len); - }; - - - void log(void) { - char hex_char[_payload.len()*2+2]; - ToHex_P((unsigned char*)_payload.getBuffer(), _payload.len(), hex_char, sizeof(hex_char)); - Response_P(PSTR("{\"" D_JSON_ZIGBEEZCL_RECEIVED "\":{" - "\"groupid\":%d," "\"clusterid\":%d," "\"srcaddr\":\"0x%04X\"," - "\"srcendpoint\":%d," "\"dstendpoint\":%d," "\"wasbroadcast\":%d," - "\"" D_CMND_ZIGBEE_LINKQUALITY "\":%d," "\"securityuse\":%d," "\"seqnumber\":%d," - "\"timestamp\":%d," - "\"fc\":\"0x%02X\",\"manuf\":\"0x%04X\",\"transact\":%d," - "\"cmdid\":\"0x%02X\",\"payload\":\"%s\"}}"), - _groupaddr, _cluster_id, _srcaddr, - _srcendpoint, _dstendpoint, _wasbroadcast, - _linkquality, _securityuse, _seqnumber, - _timestamp, - _frame_control, _manuf_code, _transact_seq, _cmd_id, - hex_char); - if (Settings.flag3.tuya_serial_mqtt_publish) { - MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR)); - XdrvRulesProcess(); - } else { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE "%s"), mqtt_data); - } - } - - static ZCLFrame parseRawFrame(const SBuffer &buf, uint8_t offset, uint8_t len, uint16_t clusterid, uint16_t groupid, - uint16_t srcaddr, uint8_t srcendpoint, uint8_t dstendpoint, uint8_t wasbroadcast, - uint8_t linkquality, uint8_t securityuse, uint8_t seqnumber, - uint32_t timestamp) { // parse a raw frame and build the ZCL frame object - uint32_t i = offset; - ZCLHeaderFrameControl_t frame_control; - uint16_t manuf_code = 0; - uint8_t transact_seq; - uint8_t cmd_id; - - frame_control.d8 = buf.get8(i++); - if (frame_control.b.manuf_specific) { - manuf_code = buf.get16(i); - i += 2; - } - transact_seq = buf.get8(i++); - cmd_id = buf.get8(i++); - ZCLFrame zcl_frame(frame_control.d8, manuf_code, transact_seq, cmd_id, - (const char *)(buf.buf() + i), len + offset - i, - clusterid, groupid, - srcaddr, srcendpoint, dstendpoint, wasbroadcast, - linkquality, securityuse, seqnumber, - timestamp); - return zcl_frame; - } - - bool isClusterSpecificCommand(void) { - return _frame_control.b.frame_type & 1; - } - - static void generateAttributeName(const JsonObject& json, uint16_t cluster, uint16_t attr, char *key, size_t key_len); - void parseRawAttributes(JsonObject& json, uint8_t offset = 0); - void parseReadAttributes(JsonObject& json, uint8_t offset = 0); - void parseResponse(void); - void parseClusterSpecificCommand(JsonObject& json, uint8_t offset = 0); - void postProcessAttributes(uint16_t shortaddr, JsonObject& json); - - inline void setGroupId(uint16_t groupid) { - _groupaddr = groupid; - } - - inline void setClusterId(uint16_t clusterid) { - _cluster_id = clusterid; - } - - inline uint8_t getCmdId(void) const { - return _cmd_id; - } - - inline uint16_t getClusterId(void) const { - return _cluster_id; - } - - inline uint16_t getSrcEndpoint(void) const { - return _srcendpoint; - } - - const SBuffer &getPayload(void) const { - return _payload; - } - - uint16_t getManufCode(void) const { - return _manuf_code; - } - -private: - ZCLHeaderFrameControl_t _frame_control = { .d8 = 0 }; - uint16_t _manuf_code = 0; // optional - uint8_t _transact_seq = 0; // transaction sequence number - uint8_t _cmd_id = 0; - uint16_t _cluster_id = 0; - uint16_t _groupaddr = 0; - SBuffer _payload; - // information from decoded ZCL frame - uint16_t _srcaddr; - uint8_t _srcendpoint; - uint8_t _dstendpoint; - uint8_t _wasbroadcast; - uint8_t _linkquality; - uint8_t _securityuse; - uint8_t _seqnumber; - uint32_t _timestamp; +enum Z_DataTypes { + Znodata = 0x00, + Zdata8 = 0x08, Zdata16, Zdata24, Zdata32, Zdata40, Zdata48, Zdata56, Zdata64, + Zbool = 0x10, + Zmap8 = 0x18, Zmap16, Zmap24, Zmap32, Zmap40, Zmap48, Zmap56, Zmap64, + Zuint8 = 0x20, Zuint16, Zuint24, Zuint32, Zuint40, Zuint48, Zuint56, Zuint64, + Zint8 = 0x28, Zint16, Zint24, Zint32, Zint40, Zint48, Zint56, Zint64, + Zenum8 = 0x30, Zenum16 = 0x31, + Zsemi = 0x38, Zsingle = 0x39, Zdouble = 0x3A, + Zoctstr = 0x41, Zstring = 0x42, Zoctstr16 = 0x43, Zstring16 = 0x44, + Arrray = 0x48, + Zstruct = 0x4C, + Zset = 0x50, Zbag = 0x51, + ZToD = 0xE0, Zdate = 0xE1, ZUTC = 0xE2, + ZclusterId = 0xE8, ZattribId = 0xE9, ZbacOID = 0xEA, + ZEUI64 = 0xF0, Zkey128 = 0xF1, + Zunk = 0xFF }; -// Zigbee ZCL converters - -// from https://github.com/Koenkk/zigbee-shepherd-converters/blob/638d29f0cace6343052b9a4e7fd60980fa785479/converters/fromZigbee.js#L55 -// Input voltage in mV, i.e. 3000 = 3.000V -// Output percentage from 0 to 100 as int -uint8_t toPercentageCR2032(uint32_t voltage) { - uint32_t percentage; - if (voltage < 2100) { - percentage = 0; - } else if (voltage < 2440) { - percentage = 6 - ((2440 - voltage) * 6) / 340; - } else if (voltage < 2740) { - percentage = 18 - ((2740 - voltage) * 12) / 300; - } else if (voltage < 2900) { - percentage = 42 - ((2900 - voltage) * 24) / 160; - } else if (voltage < 3000) { - percentage = 100 - ((3000 - voltage) * 58) / 100; - } else if (voltage >= 3000) { - percentage = 100; +// +// get the lenth in bytes for a data-type +// return 0 if unknown of type specific +// +// Note: this code is smaller than a static array +uint8_t Z_getDatatypeLen(uint8_t t) { + if ( ((t >= 0x08) && (t <= 0x0F)) || // data8 - data64 + ((t >= 0x18) && (t <= 0x2F)) ) { // map/uint/int + return (t & 0x07) + 1; } - return percentage; -} - - -uint32_t parseSingleAttribute(JsonObject& json, char *attrid_str, class SBuffer &buf, - uint32_t offset, uint32_t len) { - - uint32_t i = offset; - uint32_t attrtype = buf.get8(i++); - - // fallback - enter a null value - json[attrid_str] = (char*) nullptr; - - // now parse accordingly to attr type - switch (attrtype) { - case 0x00: // nodata - case 0xFF: // unk - break; - case 0x10: // bool - case 0x20: // uint8 - case 0x30: // enum8 - { - uint8_t uint8_val = buf.get8(i); - i += 1; - if (0xFF != uint8_val) { - json[attrid_str] = uint8_val; - } - } - break; - case 0x21: // uint16 - case 0x31: // enum16 - { - uint16_t uint16_val = buf.get16(i); - i += 2; - if (0xFFFF != uint16_val) { - json[attrid_str] = uint16_val; - } - } - break; - case 0x23: // uint32 - { - uint32_t uint32_val = buf.get32(i); - i += 4; - if (0xFFFFFFFF != uint32_val) { - json[attrid_str] = uint32_val; - } - } - break; - // Note: uint40, uint48, uint56, uint64 are stored as Hex - case 0x24: // uint40 - case 0x25: // uint48 - case 0x26: // uint56 - case 0x27: // uint64 - { - uint8_t len = attrtype - 0x1F; // 5 - 8 - // print as HEX - char hex[2*len+1]; - ToHex_P(buf.buf(i), len, hex, sizeof(hex)); - json[attrid_str] = hex; - i += len; - } - break; - case 0x28: // uint8 - { - int8_t int8_val = buf.get8(i); - i += 1; - if (0x80 != int8_val) { - json[attrid_str] = int8_val; - } - } - break; - case 0x29: // uint16 - { - int16_t int16_val = buf.get16(i); - i += 2; - if (0x8000 != int16_val) { - json[attrid_str] = int16_val; - } - } - break; - case 0x2B: // uint16 - { - int32_t int32_val = buf.get32(i); - i += 4; - if (0x80000000 != int32_val) { - json[attrid_str] = int32_val; - } - } - break; - // Note: int40, int48, int56, int64 are not stored as Hex - case 0x2C: // int40 - case 0x2D: // int48 - case 0x2E: // int56 - case 0x2F: // int64 - { - uint8_t len = attrtype - 0x27; // 5 - 8 - // print as HEX - char hex[2*len+1]; - ToHex_P(buf.buf(i), len, hex, sizeof(hex)); - json[attrid_str] = hex; - i += len; - } - break; - - case 0x41: // octet string, 1 byte len - case 0x42: // char string, 1 byte len - case 0x43: // octet string, 2 bytes len - case 0x44: // char string, 2 bytes len - // For strings, default is to try to do a real string, but reverts to octet stream if null char is present or on some exceptions - { - bool parse_as_string = true; - uint32_t len = (attrtype <= 0x42) ? buf.get8(i) : buf.get16(i); // len is 8 or 16 bits - i += (attrtype <= 0x42) ? 1 : 2; // increment pointer - if (i + len > buf.len()) { // make sure we don't get past the buffer - len = buf.len() - i; - } - - // check if we can safely use a string - if ((0x41 == attrtype) || (0x43 == attrtype)) { parse_as_string = false; } - // else { - // for (uint32_t j = 0; j < len; j++) { - // if (0x00 == buf.get8(i+j)) { - // parse_as_string = false; - // break; - // } - // } - // } - - if (parse_as_string) { - char str[len+1]; - strncpy(str, buf.charptr(i), len); - str[len] = 0x00; - json[attrid_str] = str; - } else { - // print as HEX - char hex[2*len+1]; - ToHex_P(buf.buf(i), len, hex, sizeof(hex)); - json[attrid_str] = hex; - } - - i += len; - break; - } - i += buf.get8(i) + 1; - break; - - case 0x08: // data8 - case 0x18: // map8 - { - uint8_t uint8_val = buf.get8(i); - i += 1; - json[attrid_str] = uint8_val; - } - break; - case 0x09: // data16 - case 0x19: // map16 - { - uint16_t uint16_val = buf.get16(i); - i += 2; - json[attrid_str] = uint16_val; - } - break; - case 0x0B: // data32 - case 0x1B: // map32 - { - uint32_t uint32_val = buf.get32(i); - i += 4; - json[attrid_str] = uint32_val; - } - break; - - // TODO - case 0x39: // float - { - uint32_t uint32_val = buf.get32(i); - float * float_val = (float*) &uint32_val; - i += 4; - json[attrid_str] = *float_val; - } - break; - - case 0xE0: // ToD - case 0xE1: // date - case 0xE2: // UTC - i += 4; - break; - - case 0xE8: // clusterId - case 0xE9: // attribId - i += 2; - break; - case 0xEA: // bacOID - i += 4; - break; - - case 0xF0: // EUI64 - i += 8; - break; - case 0xF1: // key128 - i += 16; - break; - - // Other un-implemented data types - case 0x0A: // data24 - case 0x0C: // data40 - case 0x0D: // data48 - case 0x0E: // data56 - case 0x0F: // data64 - i += attrtype - 0x07; // 2-8 - break; - // map - case 0x1A: // map24 - case 0x1C: // map40 - case 0x1D: // map48 - case 0x1E: // map56 - case 0x1F: // map64 - i += attrtype - 0x17; - break; - // semi - case 0x38: // semi (float on 2 bytes) - i += 2; - break; - case 0x3A: // double precision - { - uint64_t uint64_val = buf.get64(i); - double * double_val = (double*) &uint64_val; - i += 8; - json[attrid_str] = *double_val; - } - break; - } - - // String pp; // pretty print - // json[attrid_str].prettyPrintTo(pp); - // // now store the attribute - // AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "ZCL attribute decoded, id %s, type 0x%02X, val=%s"), - // attrid_str, attrtype, pp.c_str()); - return i - offset; // how much have we increased the index -} - -// Generate an attribute name based on cluster number, attribute, and suffix if duplicates -void ZCLFrame::generateAttributeName(const JsonObject& json, uint16_t cluster, uint16_t attr, char *key, size_t key_len) { - uint32_t suffix = 1; - - snprintf_P(key, key_len, PSTR("%04X/%04X"), cluster, attr); - while (json.containsKey(key)) { - suffix++; - snprintf_P(key, key_len, PSTR("%04X/%04X+%d"), cluster, attr, suffix); // add "0008/0001+2" suffix if duplicate + switch (t) { + case Zbool: + case Zenum8: + return 1; + case Zenum16: + case Zsemi: + case ZclusterId: + case ZattribId: + return 2; + case Zsingle: + case ZToD: + case Zdate: + case ZUTC: + case ZbacOID: + return 4; + case Zdouble: + case ZEUI64: + return 8; + case Zkey128: + return 16; + case Znodata: + default: + return 0; } } -// First pass, parse all attributes in their native format -void ZCLFrame::parseRawAttributes(JsonObject& json, uint8_t offset) { - uint32_t i = offset; - uint32_t len = _payload.len(); - - while (len >= i + 3) { - uint16_t attrid = _payload.get16(i); - i += 2; - - char key[16]; - generateAttributeName(json, _cluster_id, attrid, key, sizeof(key)); - - // exception for Xiaomi lumi.weather - specific field to be treated as octet and not char - if ((0x0000 == _cluster_id) && (0xFF01 == attrid)) { - if (0x42 == _payload.get8(i)) { - _payload.set8(i, 0x41); // change type from 0x42 to 0x41 - } - } - i += parseSingleAttribute(json, key, _payload, i, len); - } -} - -// ZCL_READ_ATTRIBUTES_RESPONSE -void ZCLFrame::parseReadAttributes(JsonObject& json, uint8_t offset) { - uint32_t i = offset; - uint32_t len = _payload.len(); - - while (len - i >= 4) { - uint16_t attrid = _payload.get16(i); - i += 2; - uint8_t status = _payload.get8(i++); - - if (0 == status) { - char key[16]; - generateAttributeName(json, _cluster_id, attrid, key, sizeof(key)); - - i += parseSingleAttribute(json, key, _payload, i, len); - } - } -} - -// ZCL_DEFAULT_RESPONSE -void ZCLFrame::parseResponse(void) { - if (_payload.len() < 2) { return; } // wrong format - uint8_t cmd = _payload.get8(0); - uint8_t status = _payload.get8(1); - - DynamicJsonBuffer jsonBuffer; - JsonObject& json = jsonBuffer.createObject(); - - // "Device" - char s[12]; - snprintf_P(s, sizeof(s), PSTR("0x%04X"), _srcaddr); - json[F(D_JSON_ZIGBEE_DEVICE)] = s; - // "Name" - const char * friendlyName = zigbee_devices.getFriendlyName(_srcaddr); - if (friendlyName) { - json[F(D_JSON_ZIGBEE_NAME)] = (char*) friendlyName; - } - // "Command" - snprintf_P(s, sizeof(s), PSTR("%04X!%02X"), _cluster_id, cmd); - json[F(D_JSON_ZIGBEE_CMD)] = s; - // "Status" - json[F(D_JSON_ZIGBEE_STATUS)] = status; - // "StatusMessage" - json[F(D_JSON_ZIGBEE_STATUS_MSG)] = getZigbeeStatusMessage(status); - // Add Endpoint - json[F(D_CMND_ZIGBEE_ENDPOINT)] = _srcendpoint; - // Add Group if non-zero - if (_groupaddr) { - json[F(D_CMND_ZIGBEE_GROUP)] = _groupaddr; - } - // Add linkquality - json[F(D_CMND_ZIGBEE_LINKQUALITY)] = _linkquality; - - String msg(""); - msg.reserve(100); - json.printTo(msg); - Response_P(PSTR("{\"" D_JSON_ZIGBEE_RESPONSE "\":%s}"), msg.c_str()); - MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED)); - XdrvRulesProcess(); -} - - -// Parse non-normalized attributes -void ZCLFrame::parseClusterSpecificCommand(JsonObject& json, uint8_t offset) { - convertClusterSpecific(json, _cluster_id, _cmd_id, _frame_control.b.direction, _payload); - sendHueUpdate(_srcaddr, _groupaddr, _cluster_id, _cmd_id, _frame_control.b.direction); -} // return value: // 0 = keep initial value // 1 = remove initial value typedef int32_t (*Z_AttrConverter)(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr); typedef struct Z_AttributeConverter { - uint16_t cluster; + uint8_t type; + uint8_t cluster_short; uint16_t attribute; const char * name; - Z_AttrConverter func; + int16_t multiplier; // multiplier for numerical value, (if > 0 multiply by x, if <0 device by x) + uint8_t cb; // callback func from Z_ConvOperators + // Z_AttrConverter func; } Z_AttributeConverter; +// Cluster numbers are store in 8 bits format to save space, +// the following tables allows the conversion from 8 bits index Cx... +// to the 16 bits actual cluster number +enum Cx_cluster_short { + Cx0000, Cx0001, Cx0002, Cx0003, Cx0004, Cx0005, Cx0006, Cx0007, + Cx0008, Cx0009, Cx000A, Cx000B, Cx000C, Cx000D, Cx000E, Cx000F, + Cx0010, Cx0011, Cx0012, Cx0013, Cx0014, Cx001A, Cx0020, Cx0100, + Cx0101, Cx0102, Cx0300, Cx0400, Cx0401, Cx0402, Cx0403, Cx0404, + Cx0405, Cx0406, Cx0B01, Cx0B05, +}; + +const uint16_t Cx_cluster[] PROGMEM = { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x001A, 0x0020, 0x0100, + 0x0101, 0x0102, 0x0300, 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, + 0x0405, 0x0406, 0x0B01, 0x0B05, +}; + +uint16_t CxToCluster(uint8_t cx) { + if (cx < ARRAY_SIZE(Cx_cluster)) { + return pgm_read_word(&Cx_cluster[cx]); + } + return 0xFFFF; +} + +enum Z_ConvOperators { + Z_Nop, // copy value + Z_AddPressureUnit, // add pressure unit attribute (non numerical) + Z_ManufKeep, // copy and record Manufacturer attribute + Z_ModelKeep, // copy and record ModelId attribute + Z_AqaraSensor, // decode prioprietary Aqara Sensor message + Z_AqaraVibration, // decode Aqara vibration modes + Z_AqaraCube, // decode Aqara cube + Z_BatteryPercentage, // memorize Battery Percentage in RAM +}; + ZF(ZCLVersion) ZF(AppVersion) ZF(StackVersion) ZF(HWVersion) ZF(Manufacturer) ZF(ModelId) ZF(DateCode) ZF(PowerSource) ZF(SWBuildID) ZF(Power) ZF(SwitchType) ZF(Dimmer) ZF(MainsVoltage) ZF(MainsFrequency) ZF(BatteryVoltage) ZF(BatteryPercentage) ZF(CurrentTemperature) ZF(MinTempExperienced) ZF(MaxTempExperienced) ZF(OverTempTotalDwell) ZF(SceneCount) ZF(CurrentScene) ZF(CurrentGroup) ZF(SceneValid) ZF(AlarmCount) ZF(Time) ZF(TimeStatus) ZF(TimeZone) ZF(DstStart) ZF(DstEnd) -ZF(DstShift) ZF(StandardTime) ZF(LocalTime) ZF(LastSetTime) ZF(ValidUntilTime) +ZF(DstShift) ZF(StandardTime) ZF(LocalTime) ZF(LastSetTime) ZF(ValidUntilTime) ZF(TimeEpoch) ZF(LocationType) ZF(LocationMethod) ZF(LocationAge) ZF(QualityMeasure) ZF(NumberOfDevices) @@ -606,7 +202,7 @@ ZF(WhitePointY) ZF(ColorPointRX) ZF(ColorPointRY) ZF(ColorPointRIntensity) ZF(Co ZF(ColorPointGIntensity) ZF(ColorPointBX) ZF(ColorPointBY) ZF(ColorPointBIntensity) ZF(Illuminance) ZF(IlluminanceMinMeasuredValue) ZF(IlluminanceMaxMeasuredValue) ZF(IlluminanceTolerance) -ZF(IlluminanceLightSensorType) ZF(IlluminanceLevelStatus) +ZF(IlluminanceLightSensorType) ZF(IlluminanceLevelStatus) ZF(IlluminanceTargetLevel) ZF(Temperature) ZF(TemperatureMinMeasuredValue) ZF(TemperatureMaxMeasuredValue) ZF(TemperatureTolerance) @@ -621,392 +217,975 @@ ZF(Humidity) ZF(HumidityMinMeasuredValue) ZF(HumidityMaxMeasuredValue) ZF(Humidi ZF(Occupancy) ZF(OccupancySensorType) ZF(CompanyName) ZF(MeterTypeID) ZF(DataQualityID) ZF(CustomerName) ZF(Model) ZF(PartNumber) -ZF(SoftwareRevision) ZF(POD) ZF(AvailablePower) ZF(PowerThreshold) +ZF(SoftwareRevision) ZF(POD) ZF(AvailablePower) ZF(PowerThreshold) ZF(ProductRevision) ZF(UtilityName) ZF(NumberOfResets) ZF(PersistentMemoryWrites) ZF(LastMessageLQI) ZF(LastMessageRSSI) // list of post-processing directives const Z_AttributeConverter Z_PostProcess[] PROGMEM = { - { 0x0000, 0x0000, Z(ZCLVersion), &Z_Copy }, - { 0x0000, 0x0001, Z(AppVersion), &Z_Copy }, - { 0x0000, 0x0002, Z(StackVersion), &Z_Copy }, - { 0x0000, 0x0003, Z(HWVersion), &Z_Copy }, - { 0x0000, 0x0004, Z(Manufacturer), &Z_ManufKeep }, // record Manufacturer - { 0x0000, 0x0005, Z(ModelId), &Z_ModelKeep }, // record Model - { 0x0000, 0x0006, Z(DateCode), &Z_Copy }, - { 0x0000, 0x0007, Z(PowerSource), &Z_Copy }, - { 0x0000, 0x4000, Z(SWBuildID), &Z_Copy }, - { 0x0000, 0xFFFF, nullptr, &Z_Remove }, // Remove all other values + { Zuint8, Cx0000, 0x0000, Z(ZCLVersion), 1, Z_Nop }, + { Zuint8, Cx0000, 0x0001, Z(AppVersion), 1, Z_Nop }, + { Zuint8, Cx0000, 0x0002, Z(StackVersion), 1, Z_Nop }, + { Zuint8, Cx0000, 0x0003, Z(HWVersion), 1, Z_Nop }, + { Zstring, Cx0000, 0x0004, Z(Manufacturer), 1, Z_ManufKeep }, // record Manufacturer + { Zstring, Cx0000, 0x0005, Z(ModelId), 1, Z_ModelKeep }, // record Model + { Zstring, Cx0000, 0x0006, Z(DateCode), 1, Z_Nop }, + { Zenum8, Cx0000, 0x0007, Z(PowerSource), 1, Z_Nop }, + { Zstring, Cx0000, 0x4000, Z(SWBuildID), 1, Z_Nop }, + // { Zunk, Cx0000, 0xFFFF, nullptr, 0, Z_Nop }, // Remove all other values // Cmd 0x0A - Cluster 0x0000, attribute 0xFF01 - proprietary - { 0x0000, 0xFF01, nullptr, &Z_AqaraSensor }, // Occupancy (map8) + { Zmap8, Cx0000, 0xFF01, nullptr, 0, Z_AqaraSensor }, // Occupancy (map8) // Power Configuration cluster - { 0x0001, 0x0000, Z(MainsVoltage), &Z_Copy }, - { 0x0001, 0x0001, Z(MainsFrequency), &Z_Copy }, - { 0x0001, 0x0020, Z(BatteryVoltage), &Z_FloatDiv10 }, - { 0x0001, 0x0021, Z(BatteryPercentage), &Z_Copy }, + { Zuint16, Cx0001, 0x0000, Z(MainsVoltage), 1, Z_Nop }, + { Zuint8, Cx0001, 0x0001, Z(MainsFrequency), 1, Z_Nop }, + { Zuint8, Cx0001, 0x0020, Z(BatteryVoltage), -10,Z_Nop }, // divide by 10 + { Zuint8, Cx0001, 0x0021, Z(BatteryPercentage), -2, Z_BatteryPercentage }, // divide by 2 // Device Temperature Configuration cluster - { 0x0002, 0x0000, Z(CurrentTemperature), &Z_Copy }, - { 0x0002, 0x0001, Z(MinTempExperienced), &Z_Copy }, - { 0x0002, 0x0002, Z(MaxTempExperienced), &Z_Copy }, - { 0x0002, 0x0003, Z(OverTempTotalDwell), &Z_Copy }, + { Zint16, Cx0002, 0x0000, Z(CurrentTemperature), 1, Z_Nop }, + { Zint16, Cx0002, 0x0001, Z(MinTempExperienced), 1, Z_Nop }, + { Zint16, Cx0002, 0x0002, Z(MaxTempExperienced), 1, Z_Nop }, + { Zuint16, Cx0002, 0x0003, Z(OverTempTotalDwell), 1, Z_Nop }, // Scenes cluster - { 0x0005, 0x0000, Z(SceneCount), &Z_Copy }, - { 0x0005, 0x0001, Z(CurrentScene), &Z_Copy }, - { 0x0005, 0x0002, Z(CurrentGroup), &Z_Copy }, - { 0x0005, 0x0003, Z(SceneValid), &Z_Copy }, - //{ 0x0005, 0x0004, Z(NameSupport), &Z_Copy }, + { Zuint8, Cx0005, 0x0000, Z(SceneCount), 1, Z_Nop }, + { Zuint8, Cx0005, 0x0001, Z(CurrentScene), 1, Z_Nop }, + { Zuint16, Cx0005, 0x0002, Z(CurrentGroup), 1, Z_Nop }, + { Zbool, Cx0005, 0x0003, Z(SceneValid), 1, Z_Nop }, + //{ Zmap8, Cx0005, 0x0004, Z(NameSupport), 1, Z_Nop }, // On/off cluster - { 0x0006, 0x0000, Z(Power), &Z_Copy }, - { 0x0006, 0x8000, Z(Power), &Z_Copy }, // See 7280 + { Zbool, Cx0006, 0x0000, Z(Power), 1, Z_Nop }, + { Zbool, Cx0006, 0x8000, Z(Power), 1, Z_Nop }, // See 7280 // On/Off Switch Configuration cluster - { 0x0007, 0x0000, Z(SwitchType), &Z_Copy }, + { Zenum8, Cx0007, 0x0000, Z(SwitchType), 1, Z_Nop }, // Level Control cluster - { 0x0008, 0x0000, Z(Dimmer), &Z_Copy }, - // { 0x0008, 0x0001, Z(RemainingTime", &Z_Copy }, - // { 0x0008, 0x0010, Z(OnOffTransitionTime", &Z_Copy }, - // { 0x0008, 0x0011, Z(OnLevel", &Z_Copy }, - // { 0x0008, 0x0012, Z(OnTransitionTime", &Z_Copy }, - // { 0x0008, 0x0013, Z(OffTransitionTime", &Z_Copy }, - // { 0x0008, 0x0014, Z(DefaultMoveRate", &Z_Copy }, + { Zuint8, Cx0008, 0x0000, Z(Dimmer), 1, Z_Nop }, + // { Zuint16, Cx0008, 0x0001, Z(RemainingTime", 1, Z_Nop }, + // { Zuint16, Cx0008, 0x0010, Z(OnOffTransitionTime", 1, Z_Nop }, + // { Zuint8, Cx0008, 0x0011, Z(OnLevel", 1, Z_Nop }, + // { Zuint16, Cx0008, 0x0012, Z(OnTransitionTime", 1, Z_Nop }, + // { Zuint16, Cx0008, 0x0013, Z(OffTransitionTime", 1, Z_Nop }, + // { Zuint16, Cx0008, 0x0014, Z(DefaultMoveRate", 1, Z_Nop }, // Alarms cluster - { 0x0009, 0x0000, Z(AlarmCount), &Z_Copy }, + { Zuint16, Cx0009, 0x0000, Z(AlarmCount), 1, Z_Nop }, + // Time cluster - { 0x000A, 0x0000, Z(Time), &Z_Copy }, - { 0x000A, 0x0001, Z(TimeStatus), &Z_Copy }, - { 0x000A, 0x0002, Z(TimeZone), &Z_Copy }, - { 0x000A, 0x0003, Z(DstStart), &Z_Copy }, - { 0x000A, 0x0004, Z(DstEnd), &Z_Copy }, - { 0x000A, 0x0005, Z(DstShift), &Z_Copy }, - { 0x000A, 0x0006, Z(StandardTime), &Z_Copy }, - { 0x000A, 0x0007, Z(LocalTime), &Z_Copy }, - { 0x000A, 0x0008, Z(LastSetTime), &Z_Copy }, - { 0x000A, 0x0009, Z(ValidUntilTime), &Z_Copy }, + { ZUTC, Cx000A, 0x0000, Z(Time), 1, Z_Nop }, + { Zmap8, Cx000A, 0x0001, Z(TimeStatus), 1, Z_Nop }, + { Zint32, Cx000A, 0x0002, Z(TimeZone), 1, Z_Nop }, + { Zuint32, Cx000A, 0x0003, Z(DstStart), 1, Z_Nop }, + { Zuint32, Cx000A, 0x0004, Z(DstEnd), 1, Z_Nop }, + { Zint32, Cx000A, 0x0005, Z(DstShift), 1, Z_Nop }, + { Zuint32, Cx000A, 0x0006, Z(StandardTime), 1, Z_Nop }, + { Zuint32, Cx000A, 0x0007, Z(LocalTime), 1, Z_Nop }, + { ZUTC, Cx000A, 0x0008, Z(LastSetTime), 1, Z_Nop }, + { ZUTC, Cx000A, 0x0009, Z(ValidUntilTime), 1, Z_Nop }, + { ZUTC, Cx000A, 0xFF00, Z(TimeEpoch), 1, Z_Nop }, // Tasmota specific, epoch + // RSSI Location cluster - { 0x000B, 0x0000, Z(LocationType), &Z_Copy }, - { 0x000B, 0x0000, Z(LocationMethod), &Z_Copy }, - { 0x000B, 0x0000, Z(LocationAge), &Z_Copy }, - { 0x000B, 0x0000, Z(QualityMeasure), &Z_Copy }, - { 0x000B, 0x0000, Z(NumberOfDevices), &Z_Copy }, + { Zdata8, Cx000B, 0x0000, Z(LocationType), 1, Z_Nop }, + { Zenum8, Cx000B, 0x0001, Z(LocationMethod), 1, Z_Nop }, + { Zuint16, Cx000B, 0x0002, Z(LocationAge), 1, Z_Nop }, + { Zuint8, Cx000B, 0x0003, Z(QualityMeasure), 1, Z_Nop }, + { Zuint8, Cx000B, 0x0004, Z(NumberOfDevices), 1, Z_Nop }, + // Analog Input cluster - { 0x000C, 0x0004, Z(AnalogInActiveText), &Z_Copy }, - { 0x000C, 0x001C, Z(AnalogInDescription), &Z_Copy }, - { 0x000C, 0x002E, Z(AnalogInInactiveText), &Z_Copy }, - { 0x000C, 0x0041, Z(AnalogInMaxValue), &Z_Copy }, - { 0x000C, 0x0045, Z(AnalogInMinValue), &Z_Copy }, - { 0x000C, 0x0051, Z(AnalogInOutOfService), &Z_Copy }, - { 0x000C, 0x0055, Z(AqaraRotate), &Z_Copy }, - { 0x000C, 0x0057, Z(AnalogInPriorityArray),&Z_Copy }, - { 0x000C, 0x0067, Z(AnalogInReliability), &Z_Copy }, - { 0x000C, 0x0068, Z(AnalogInRelinquishDefault),&Z_Copy }, - { 0x000C, 0x006A, Z(AnalogInResolution), &Z_Copy }, - { 0x000C, 0x006F, Z(AnalogInStatusFlags), &Z_Copy }, - { 0x000C, 0x0075, Z(AnalogInEngineeringUnits),&Z_Copy }, - { 0x000C, 0x0100, Z(AnalogInApplicationType),&Z_Copy }, - { 0x000C, 0xFF05, Z(Aqara_FF05), &Z_Copy }, + // { 0xFF, Cx000C, 0x0004, Z(AnalogInActiveText), 1, Z_Nop }, + { Zstring, Cx000C, 0x001C, Z(AnalogInDescription), 1, Z_Nop }, + // { 0xFF, Cx000C, 0x002E, Z(AnalogInInactiveText), 1, Z_Nop }, + { Zsingle, Cx000C, 0x0041, Z(AnalogInMaxValue), 1, Z_Nop }, + { Zsingle, Cx000C, 0x0045, Z(AnalogInMinValue), 1, Z_Nop }, + { Zbool, Cx000C, 0x0051, Z(AnalogInOutOfService), 1, Z_Nop }, + { Zsingle, Cx000C, 0x0055, Z(AqaraRotate), 1, Z_Nop }, + // { 0xFF, Cx000C, 0x0057, Z(AnalogInPriorityArray),1, Z_Nop }, + { Zenum8, Cx000C, 0x0067, Z(AnalogInReliability), 1, Z_Nop }, + // { 0xFF, Cx000C, 0x0068, Z(AnalogInRelinquishDefault),1, Z_Nop }, + { Zsingle, Cx000C, 0x006A, Z(AnalogInResolution), 1, Z_Nop }, + { Zmap8, Cx000C, 0x006F, Z(AnalogInStatusFlags), 1, Z_Nop }, + { Zenum16, Cx000C, 0x0075, Z(AnalogInEngineeringUnits),1, Z_Nop }, + { Zuint32, Cx000C, 0x0100, Z(AnalogInApplicationType),1, Z_Nop }, + { Zuint16, Cx000C, 0xFF05, Z(Aqara_FF05), 1, Z_Nop }, + // Analog Output cluster - { 0x000D, 0x001C, Z(AnalogOutDescription), &Z_Copy }, - { 0x000D, 0x0041, Z(AnalogOutMaxValue), &Z_Copy }, - { 0x000D, 0x0045, Z(AnalogOutMinValue), &Z_Copy }, - { 0x000D, 0x0051, Z(AnalogOutOutOfService),&Z_Copy }, - { 0x000D, 0x0055, Z(AnalogOutValue), &Z_Copy }, - { 0x000D, 0x0057, Z(AnalogOutPriorityArray),&Z_Copy }, - { 0x000D, 0x0067, Z(AnalogOutReliability), &Z_Copy }, - { 0x000D, 0x0068, Z(AnalogOutRelinquishDefault),&Z_Copy }, - { 0x000D, 0x006A, Z(AnalogOutResolution), &Z_Copy }, - { 0x000D, 0x006F, Z(AnalogOutStatusFlags), &Z_Copy }, - { 0x000D, 0x0075, Z(AnalogOutEngineeringUnits),&Z_Copy }, - { 0x000D, 0x0100, Z(AnalogOutApplicationType),&Z_Copy }, + { Zstring, Cx000D, 0x001C, Z(AnalogOutDescription), 1, Z_Nop }, + { Zsingle, Cx000D, 0x0041, Z(AnalogOutMaxValue), 1, Z_Nop }, + { Zsingle, Cx000D, 0x0045, Z(AnalogOutMinValue), 1, Z_Nop }, + { Zbool, Cx000D, 0x0051, Z(AnalogOutOutOfService),1, Z_Nop }, + { Zsingle, Cx000D, 0x0055, Z(AnalogOutValue), 1, Z_Nop }, + // { Zunk, Cx000D, 0x0057, Z(AnalogOutPriorityArray),1, Z_Nop }, + { Zenum8, Cx000D, 0x0067, Z(AnalogOutReliability), 1, Z_Nop }, + { Zsingle, Cx000D, 0x0068, Z(AnalogOutRelinquishDefault),1, Z_Nop }, + { Zsingle, Cx000D, 0x006A, Z(AnalogOutResolution), 1, Z_Nop }, + { Zmap8, Cx000D, 0x006F, Z(AnalogOutStatusFlags), 1, Z_Nop }, + { Zenum16, Cx000D, 0x0075, Z(AnalogOutEngineeringUnits),1, Z_Nop }, + { Zuint32, Cx000D, 0x0100, Z(AnalogOutApplicationType),1, Z_Nop }, + // Analog Value cluster - { 0x000E, 0x001C, Z(AnalogDescription), &Z_Copy }, - { 0x000E, 0x0051, Z(AnalogOutOfService), &Z_Copy }, - { 0x000E, 0x0055, Z(AnalogValue), &Z_Copy }, - { 0x000E, 0x0057, Z(AnalogPriorityArray), &Z_Copy }, - { 0x000E, 0x0067, Z(AnalogReliability), &Z_Copy }, - { 0x000E, 0x0068, Z(AnalogRelinquishDefault),&Z_Copy }, - { 0x000E, 0x006F, Z(AnalogStatusFlags), &Z_Copy }, - { 0x000E, 0x0075, Z(AnalogEngineeringUnits),&Z_Copy }, - { 0x000E, 0x0100, Z(AnalogApplicationType),&Z_Copy }, + { Zstring, Cx000E, 0x001C, Z(AnalogDescription), 1, Z_Nop }, + { Zbool, Cx000E, 0x0051, Z(AnalogOutOfService), 1, Z_Nop }, + { Zsingle, Cx000E, 0x0055, Z(AnalogValue), 1, Z_Nop }, + { Zunk, Cx000E, 0x0057, Z(AnalogPriorityArray), 1, Z_Nop }, + { Zenum8, Cx000E, 0x0067, Z(AnalogReliability), 1, Z_Nop }, + { Zsingle, Cx000E, 0x0068, Z(AnalogRelinquishDefault),1, Z_Nop }, + { Zmap8, Cx000E, 0x006F, Z(AnalogStatusFlags), 1, Z_Nop }, + { Zenum16, Cx000E, 0x0075, Z(AnalogEngineeringUnits),1, Z_Nop }, + { Zuint32, Cx000E, 0x0100, Z(AnalogApplicationType),1, Z_Nop }, + // Binary Input cluster - { 0x000F, 0x0004, Z(BinaryInActiveText), &Z_Copy }, - { 0x000F, 0x001C, Z(BinaryInDescription), &Z_Copy }, - { 0x000F, 0x002E, Z(BinaryInInactiveText),&Z_Copy }, - { 0x000F, 0x0051, Z(BinaryInOutOfService),&Z_Copy }, - { 0x000F, 0x0054, Z(BinaryInPolarity), &Z_Copy }, - { 0x000F, 0x0055, Z(BinaryInValue), &Z_Copy }, - { 0x000F, 0x0057, Z(BinaryInPriorityArray),&Z_Copy }, - { 0x000F, 0x0067, Z(BinaryInReliability), &Z_Copy }, - { 0x000F, 0x006F, Z(BinaryInStatusFlags), &Z_Copy }, - { 0x000F, 0x0100, Z(BinaryInApplicationType),&Z_Copy }, + { Zstring, Cx000F, 0x0004, Z(BinaryInActiveText), 1, Z_Nop }, + { Zstring, Cx000F, 0x001C, Z(BinaryInDescription), 1, Z_Nop }, + { Zstring, Cx000F, 0x002E, Z(BinaryInInactiveText),1, Z_Nop }, + { Zbool, Cx000F, 0x0051, Z(BinaryInOutOfService),1, Z_Nop }, + { Zenum8, Cx000F, 0x0054, Z(BinaryInPolarity), 1, Z_Nop }, + { Zstring, Cx000F, 0x0055, Z(BinaryInValue), 1, Z_Nop }, + // { 0xFF, Cx000F, 0x0057, Z(BinaryInPriorityArray),1, Z_Nop }, + { Zenum8, Cx000F, 0x0067, Z(BinaryInReliability), 1, Z_Nop }, + { Zmap8, Cx000F, 0x006F, Z(BinaryInStatusFlags), 1, Z_Nop }, + { Zuint32, Cx000F, 0x0100, Z(BinaryInApplicationType),1, Z_Nop }, + // Binary Output cluster - { 0x0010, 0x0004, Z(BinaryOutActiveText), &Z_Copy }, - { 0x0010, 0x001C, Z(BinaryOutDescription), &Z_Copy }, - { 0x0010, 0x002E, Z(BinaryOutInactiveText),&Z_Copy }, - { 0x0010, 0x0042, Z(BinaryOutMinimumOffTime),&Z_Copy }, - { 0x0010, 0x0043, Z(BinaryOutMinimumOnTime),&Z_Copy }, - { 0x0010, 0x0051, Z(BinaryOutOutOfService),&Z_Copy }, - { 0x0010, 0x0054, Z(BinaryOutPolarity), &Z_Copy }, - { 0x0010, 0x0055, Z(BinaryOutValue), &Z_Copy }, - { 0x0010, 0x0057, Z(BinaryOutPriorityArray),&Z_Copy }, - { 0x0010, 0x0067, Z(BinaryOutReliability), &Z_Copy }, - { 0x0010, 0x0068, Z(BinaryOutRelinquishDefault),&Z_Copy }, - { 0x0010, 0x006F, Z(BinaryOutStatusFlags), &Z_Copy }, - { 0x0010, 0x0100, Z(BinaryOutApplicationType),&Z_Copy }, + { Zstring, Cx0010, 0x0004, Z(BinaryOutActiveText), 1, Z_Nop }, + { Zstring, Cx0010, 0x001C, Z(BinaryOutDescription), 1, Z_Nop }, + { Zstring, Cx0010, 0x002E, Z(BinaryOutInactiveText),1, Z_Nop }, + { Zuint32, Cx0010, 0x0042, Z(BinaryOutMinimumOffTime),1, Z_Nop }, + { Zuint32, Cx0010, 0x0043, Z(BinaryOutMinimumOnTime),1, Z_Nop }, + { Zbool, Cx0010, 0x0051, Z(BinaryOutOutOfService),1, Z_Nop }, + { Zenum8, Cx0010, 0x0054, Z(BinaryOutPolarity), 1, Z_Nop }, + { Zbool, Cx0010, 0x0055, Z(BinaryOutValue), 1, Z_Nop }, + // { Zunk, Cx0010, 0x0057, Z(BinaryOutPriorityArray),1, Z_Nop }, + { Zenum8, Cx0010, 0x0067, Z(BinaryOutReliability), 1, Z_Nop }, + { Zbool, Cx0010, 0x0068, Z(BinaryOutRelinquishDefault),1, Z_Nop }, + { Zmap8, Cx0010, 0x006F, Z(BinaryOutStatusFlags), 1, Z_Nop }, + { Zuint32, Cx0010, 0x0100, Z(BinaryOutApplicationType),1, Z_Nop }, + // Binary Value cluster - { 0x0011, 0x0004, Z(BinaryActiveText), &Z_Copy }, - { 0x0011, 0x001C, Z(BinaryDescription), &Z_Copy }, - { 0x0011, 0x002E, Z(BinaryInactiveText), &Z_Copy }, - { 0x0011, 0x0042, Z(BinaryMinimumOffTime), &Z_Copy }, - { 0x0011, 0x0043, Z(BinaryMinimumOnTime), &Z_Copy }, - { 0x0011, 0x0051, Z(BinaryOutOfService), &Z_Copy }, - { 0x0011, 0x0055, Z(BinaryValue), &Z_Copy }, - { 0x0011, 0x0057, Z(BinaryPriorityArray), &Z_Copy }, - { 0x0011, 0x0067, Z(BinaryReliability), &Z_Copy }, - { 0x0011, 0x0068, Z(BinaryRelinquishDefault),&Z_Copy }, - { 0x0011, 0x006F, Z(BinaryStatusFlags), &Z_Copy }, - { 0x0011, 0x0100, Z(BinaryApplicationType),&Z_Copy }, + { Zstring, Cx0011, 0x0004, Z(BinaryActiveText), 1, Z_Nop }, + { Zstring, Cx0011, 0x001C, Z(BinaryDescription), 1, Z_Nop }, + { Zstring, Cx0011, 0x002E, Z(BinaryInactiveText), 1, Z_Nop }, + { Zuint32, Cx0011, 0x0042, Z(BinaryMinimumOffTime), 1, Z_Nop }, + { Zuint32, Cx0011, 0x0043, Z(BinaryMinimumOnTime), 1, Z_Nop }, + { Zbool, Cx0011, 0x0051, Z(BinaryOutOfService), 1, Z_Nop }, + { Zbool, Cx0011, 0x0055, Z(BinaryValue), 1, Z_Nop }, + // { Zunk, Cx0011, 0x0057, Z(BinaryPriorityArray), 1, Z_Nop }, + { Zenum8, Cx0011, 0x0067, Z(BinaryReliability), 1, Z_Nop }, + { Zbool, Cx0011, 0x0068, Z(BinaryRelinquishDefault),1, Z_Nop }, + { Zmap8, Cx0011, 0x006F, Z(BinaryStatusFlags), 1, Z_Nop }, + { Zuint32, Cx0011, 0x0100, Z(BinaryApplicationType),1, Z_Nop }, + // Multistate Input cluster - { 0x0012, 0x000E, Z(MultiInStateText), &Z_Copy }, - { 0x0012, 0x001C, Z(MultiInDescription), &Z_Copy }, - { 0x0012, 0x004A, Z(MultiInNumberOfStates),&Z_Copy }, - { 0x0012, 0x0051, Z(MultiInOutOfService), &Z_Copy }, - { 0x0012, 0x0055, Z(MultiInValue), &Z_AqaraCube }, - { 0x0012, 0x0067, Z(MultiInReliability), &Z_Copy }, - { 0x0012, 0x006F, Z(MultiInStatusFlags), &Z_Copy }, - { 0x0012, 0x0100, Z(MultiInApplicationType),&Z_Copy }, + // { Zunk, Cx0012, 0x000E, Z(MultiInStateText), 1, Z_Nop }, + { Zstring, Cx0012, 0x001C, Z(MultiInDescription), 1, Z_Nop }, + { Zuint16, Cx0012, 0x004A, Z(MultiInNumberOfStates),1, Z_Nop }, + { Zbool, Cx0012, 0x0051, Z(MultiInOutOfService), 1, Z_Nop }, + { Zuint16, Cx0012, 0x0055, Z(MultiInValue), 0, Z_AqaraCube }, + { Zenum8, Cx0012, 0x0067, Z(MultiInReliability), 1, Z_Nop }, + { Zmap8, Cx0012, 0x006F, Z(MultiInStatusFlags), 1, Z_Nop }, + { Zuint32, Cx0012, 0x0100, Z(MultiInApplicationType),1, Z_Nop }, + // Multistate output - { 0x0013, 0x000E, Z(MultiOutStateText), &Z_Copy }, - { 0x0013, 0x001C, Z(MultiOutDescription), &Z_Copy }, - { 0x0013, 0x004A, Z(MultiOutNumberOfStates),&Z_Copy }, - { 0x0013, 0x0051, Z(MultiOutOutOfService), &Z_Copy }, - { 0x0013, 0x0055, Z(MultiOutValue), &Z_Copy }, - { 0x0013, 0x0057, Z(MultiOutPriorityArray),&Z_Copy }, - { 0x0013, 0x0067, Z(MultiOutReliability), &Z_Copy }, - { 0x0013, 0x0068, Z(MultiOutRelinquishDefault),&Z_Copy }, - { 0x0013, 0x006F, Z(MultiOutStatusFlags), &Z_Copy }, - { 0x0013, 0x0100, Z(MultiOutApplicationType),&Z_Copy }, + // { Zunk, Cx0013, 0x000E, Z(MultiOutStateText), 1, Z_Nop }, + { Zstring, Cx0013, 0x001C, Z(MultiOutDescription), 1, Z_Nop }, + { Zuint16, Cx0013, 0x004A, Z(MultiOutNumberOfStates),1, Z_Nop }, + { Zbool, Cx0013, 0x0051, Z(MultiOutOutOfService), 1, Z_Nop }, + { Zuint16, Cx0013, 0x0055, Z(MultiOutValue), 1, Z_Nop }, + // { Zunk, Cx0013, 0x0057, Z(MultiOutPriorityArray),1, Z_Nop }, + { Zenum8, Cx0013, 0x0067, Z(MultiOutReliability), 1, Z_Nop }, + { Zuint16, Cx0013, 0x0068, Z(MultiOutRelinquishDefault),1, Z_Nop }, + { Zmap8, Cx0013, 0x006F, Z(MultiOutStatusFlags), 1, Z_Nop }, + { Zuint32, Cx0013, 0x0100, Z(MultiOutApplicationType),1, Z_Nop }, + // Multistate Value cluster - { 0x0014, 0x000E, Z(MultiStateText), &Z_Copy }, - { 0x0014, 0x001C, Z(MultiDescription), &Z_Copy }, - { 0x0014, 0x004A, Z(MultiNumberOfStates), &Z_Copy }, - { 0x0014, 0x0051, Z(MultiOutOfService), &Z_Copy }, - { 0x0014, 0x0055, Z(MultiValue), &Z_Copy }, - { 0x0014, 0x0067, Z(MultiReliability), &Z_Copy }, - { 0x0014, 0x0068, Z(MultiRelinquishDefault),&Z_Copy }, - { 0x0014, 0x006F, Z(MultiStatusFlags), &Z_Copy }, - { 0x0014, 0x0100, Z(MultiApplicationType), &Z_Copy }, + // { Zunk, Cx0014, 0x000E, Z(MultiStateText), 1, Z_Nop }, + { Zstring, Cx0014, 0x001C, Z(MultiDescription), 1, Z_Nop }, + { Zuint16, Cx0014, 0x004A, Z(MultiNumberOfStates), 1, Z_Nop }, + { Zbool, Cx0014, 0x0051, Z(MultiOutOfService), 1, Z_Nop }, + { Zuint16, Cx0014, 0x0055, Z(MultiValue), 1, Z_Nop }, + { Zenum8, Cx0014, 0x0067, Z(MultiReliability), 1, Z_Nop }, + { Zuint16, Cx0014, 0x0068, Z(MultiRelinquishDefault),1, Z_Nop }, + { Zmap8, Cx0014, 0x006F, Z(MultiStatusFlags), 1, Z_Nop }, + { Zuint32, Cx0014, 0x0100, Z(MultiApplicationType), 1, Z_Nop }, + // Power Profile cluster - { 0x001A, 0x0000, Z(TotalProfileNum), &Z_Copy }, - { 0x001A, 0x0001, Z(MultipleScheduling), &Z_Copy }, - { 0x001A, 0x0002, Z(EnergyFormatting), &Z_Copy }, - { 0x001A, 0x0003, Z(EnergyRemote), &Z_Copy }, - { 0x001A, 0x0004, Z(ScheduleMode), &Z_Copy }, + { Zuint8, Cx001A, 0x0000, Z(TotalProfileNum), 1, Z_Nop }, + { Zbool, Cx001A, 0x0001, Z(MultipleScheduling), 1, Z_Nop }, + { Zmap8, Cx001A, 0x0002, Z(EnergyFormatting), 1, Z_Nop }, + { Zbool, Cx001A, 0x0003, Z(EnergyRemote), 1, Z_Nop }, + { Zmap8, Cx001A, 0x0004, Z(ScheduleMode), 1, Z_Nop }, + // Poll Control cluster - { 0x0020, 0x0000, Z(CheckinInterval), &Z_Copy }, - { 0x0020, 0x0001, Z(LongPollInterval), &Z_Copy }, - { 0x0020, 0x0002, Z(ShortPollInterval), &Z_Copy }, - { 0x0020, 0x0003, Z(FastPollTimeout), &Z_Copy }, - { 0x0020, 0x0004, Z(CheckinIntervalMin), &Z_Copy }, - { 0x0020, 0x0005, Z(LongPollIntervalMin), &Z_Copy }, - { 0x0020, 0x0006, Z(FastPollTimeoutMax), &Z_Copy }, + { Zuint32, Cx0020, 0x0000, Z(CheckinInterval), 1, Z_Nop }, + { Zuint32, Cx0020, 0x0001, Z(LongPollInterval), 1, Z_Nop }, + { Zuint16, Cx0020, 0x0002, Z(ShortPollInterval), 1, Z_Nop }, + { Zuint16, Cx0020, 0x0003, Z(FastPollTimeout), 1, Z_Nop }, + { Zuint32, Cx0020, 0x0004, Z(CheckinIntervalMin), 1, Z_Nop }, + { Zuint32, Cx0020, 0x0005, Z(LongPollIntervalMin), 1, Z_Nop }, + { Zuint16, Cx0020, 0x0006, Z(FastPollTimeoutMax), 1, Z_Nop }, + // Shade Configuration cluster - { 0x0100, 0x0000, Z(PhysicalClosedLimit), &Z_Copy }, - { 0x0100, 0x0001, Z(MotorStepSize), &Z_Copy }, - { 0x0100, 0x0002, Z(Status), &Z_Copy }, - { 0x0100, 0x0010, Z(ClosedLimit), &Z_Copy }, - { 0x0100, 0x0011, Z(Mode), &Z_Copy }, + { Zuint16, Cx0100, 0x0000, Z(PhysicalClosedLimit), 1, Z_Nop }, + { Zuint8, Cx0100, 0x0001, Z(MotorStepSize), 1, Z_Nop }, + { Zmap8, Cx0100, 0x0002, Z(Status), 1, Z_Nop }, + { Zuint16, Cx0100, 0x0010, Z(ClosedLimit), 1, Z_Nop }, + { Zenum8, Cx0100, 0x0011, Z(Mode), 1, Z_Nop }, + // Door Lock cluster - { 0x0101, 0x0000, Z(LockState), &Z_Copy }, - { 0x0101, 0x0001, Z(LockType), &Z_Copy }, - { 0x0101, 0x0002, Z(ActuatorEnabled), &Z_Copy }, - { 0x0101, 0x0003, Z(DoorState), &Z_Copy }, - { 0x0101, 0x0004, Z(DoorOpenEvents), &Z_Copy }, - { 0x0101, 0x0005, Z(DoorClosedEvents), &Z_Copy }, - { 0x0101, 0x0006, Z(OpenPeriod), &Z_Copy }, + { Zenum8, Cx0101, 0x0000, Z(LockState), 1, Z_Nop }, + { Zenum8, Cx0101, 0x0001, Z(LockType), 1, Z_Nop }, + { Zbool, Cx0101, 0x0002, Z(ActuatorEnabled), 1, Z_Nop }, + { Zenum8, Cx0101, 0x0003, Z(DoorState), 1, Z_Nop }, + { Zuint32, Cx0101, 0x0004, Z(DoorOpenEvents), 1, Z_Nop }, + { Zuint32, Cx0101, 0x0005, Z(DoorClosedEvents), 1, Z_Nop }, + { Zuint16, Cx0101, 0x0006, Z(OpenPeriod), 1, Z_Nop }, + // Aqara Lumi Vibration Sensor - { 0x0101, 0x0055, Z(AqaraVibrationMode), &Z_AqaraVibration }, - { 0x0101, 0x0503, Z(AqaraVibrationsOrAngle), &Z_Copy }, - { 0x0101, 0x0505, Z(AqaraVibration505), &Z_Copy }, - { 0x0101, 0x0508, Z(AqaraAccelerometer), &Z_AqaraVibration }, + { Zuint16, Cx0101, 0x0055, Z(AqaraVibrationMode), 0, Z_AqaraVibration }, + { Zuint16, Cx0101, 0x0503, Z(AqaraVibrationsOrAngle), 1, Z_Nop }, + { Zuint32, Cx0101, 0x0505, Z(AqaraVibration505), 1, Z_Nop }, + { Zuint48, Cx0101, 0x0508, Z(AqaraAccelerometer), 0, Z_AqaraVibration }, + // Window Covering cluster - { 0x0102, 0x0000, Z(WindowCoveringType), &Z_Copy }, - { 0x0102, 0x0001, Z(PhysicalClosedLimitLift),&Z_Copy }, - { 0x0102, 0x0002, Z(PhysicalClosedLimitTilt),&Z_Copy }, - { 0x0102, 0x0003, Z(CurrentPositionLift), &Z_Copy }, - { 0x0102, 0x0004, Z(CurrentPositionTilt), &Z_Copy }, - { 0x0102, 0x0005, Z(NumberofActuationsLift),&Z_Copy }, - { 0x0102, 0x0006, Z(NumberofActuationsTilt),&Z_Copy }, - { 0x0102, 0x0007, Z(ConfigStatus), &Z_Copy }, - { 0x0102, 0x0008, Z(CurrentPositionLiftPercentage),&Z_Copy }, - { 0x0102, 0x0009, Z(CurrentPositionTiltPercentage),&Z_Copy }, - { 0x0102, 0x0010, Z(InstalledOpenLimitLift),&Z_Copy }, - { 0x0102, 0x0011, Z(InstalledClosedLimitLift),&Z_Copy }, - { 0x0102, 0x0012, Z(InstalledOpenLimitTilt),&Z_Copy }, - { 0x0102, 0x0013, Z(InstalledClosedLimitTilt),&Z_Copy }, - { 0x0102, 0x0014, Z(VelocityLift), &Z_Copy }, - { 0x0102, 0x0015, Z(AccelerationTimeLift),&Z_Copy }, - { 0x0102, 0x0016, Z(DecelerationTimeLift), &Z_Copy }, - { 0x0102, 0x0017, Z(Mode), &Z_Copy }, - { 0x0102, 0x0018, Z(IntermediateSetpointsLift),&Z_Copy }, - { 0x0102, 0x0019, Z(IntermediateSetpointsTilt),&Z_Copy }, + { Zenum8, Cx0102, 0x0000, Z(WindowCoveringType), 1, Z_Nop }, + { Zuint16, Cx0102, 0x0001, Z(PhysicalClosedLimitLift),1, Z_Nop }, + { Zuint16, Cx0102, 0x0002, Z(PhysicalClosedLimitTilt),1, Z_Nop }, + { Zuint16, Cx0102, 0x0003, Z(CurrentPositionLift), 1, Z_Nop }, + { Zuint16, Cx0102, 0x0004, Z(CurrentPositionTilt), 1, Z_Nop }, + { Zuint16, Cx0102, 0x0005, Z(NumberofActuationsLift),1, Z_Nop }, + { Zuint16, Cx0102, 0x0006, Z(NumberofActuationsTilt),1, Z_Nop }, + { Zmap8, Cx0102, 0x0007, Z(ConfigStatus), 1, Z_Nop }, + { Zuint8, Cx0102, 0x0008, Z(CurrentPositionLiftPercentage),1, Z_Nop }, + { Zuint8, Cx0102, 0x0009, Z(CurrentPositionTiltPercentage),1, Z_Nop }, + { Zuint16, Cx0102, 0x0010, Z(InstalledOpenLimitLift),1, Z_Nop }, + { Zuint16, Cx0102, 0x0011, Z(InstalledClosedLimitLift),1, Z_Nop }, + { Zuint16, Cx0102, 0x0012, Z(InstalledOpenLimitTilt),1, Z_Nop }, + { Zuint16, Cx0102, 0x0013, Z(InstalledClosedLimitTilt),1, Z_Nop }, + { Zuint16, Cx0102, 0x0014, Z(VelocityLift), 1, Z_Nop }, + { Zuint16, Cx0102, 0x0015, Z(AccelerationTimeLift),1, Z_Nop }, + { Zuint16, Cx0102, 0x0016, Z(DecelerationTimeLift), 1, Z_Nop }, + { Zmap8, Cx0102, 0x0017, Z(Mode), 1, Z_Nop }, + { Zoctstr, Cx0102, 0x0018, Z(IntermediateSetpointsLift),1, Z_Nop }, + { Zoctstr, Cx0102, 0x0019, Z(IntermediateSetpointsTilt),1, Z_Nop }, // Color Control cluster - { 0x0300, 0x0000, Z(Hue), &Z_Copy }, - { 0x0300, 0x0001, Z(Sat), &Z_Copy }, - { 0x0300, 0x0002, Z(RemainingTime), &Z_Copy }, - { 0x0300, 0x0003, Z(X), &Z_Copy }, - { 0x0300, 0x0004, Z(Y), &Z_Copy }, - { 0x0300, 0x0005, Z(DriftCompensation), &Z_Copy }, - { 0x0300, 0x0006, Z(CompensationText), &Z_Copy }, - { 0x0300, 0x0007, Z(CT), &Z_Copy }, - { 0x0300, 0x0008, Z(ColorMode), &Z_Copy }, - { 0x0300, 0x0010, Z(NumberOfPrimaries), &Z_Copy }, - { 0x0300, 0x0011, Z(Primary1X), &Z_Copy }, - { 0x0300, 0x0012, Z(Primary1Y), &Z_Copy }, - { 0x0300, 0x0013, Z(Primary1Intensity), &Z_Copy }, - { 0x0300, 0x0015, Z(Primary2X), &Z_Copy }, - { 0x0300, 0x0016, Z(Primary2Y), &Z_Copy }, - { 0x0300, 0x0017, Z(Primary2Intensity), &Z_Copy }, - { 0x0300, 0x0019, Z(Primary3X), &Z_Copy }, - { 0x0300, 0x001A, Z(Primary3Y), &Z_Copy }, - { 0x0300, 0x001B, Z(Primary3Intensity), &Z_Copy }, - { 0x0300, 0x0030, Z(WhitePointX), &Z_Copy }, - { 0x0300, 0x0031, Z(WhitePointY), &Z_Copy }, - { 0x0300, 0x0032, Z(ColorPointRX), &Z_Copy }, - { 0x0300, 0x0033, Z(ColorPointRY), &Z_Copy }, - { 0x0300, 0x0034, Z(ColorPointRIntensity), &Z_Copy }, - { 0x0300, 0x0036, Z(ColorPointGX), &Z_Copy }, - { 0x0300, 0x0037, Z(ColorPointGY), &Z_Copy }, - { 0x0300, 0x0038, Z(ColorPointGIntensity), &Z_Copy }, - { 0x0300, 0x003A, Z(ColorPointBX), &Z_Copy }, - { 0x0300, 0x003B, Z(ColorPointBY), &Z_Copy }, - { 0x0300, 0x003C, Z(ColorPointBIntensity), &Z_Copy }, + { Zuint8, Cx0300, 0x0000, Z(Hue), 1, Z_Nop }, + { Zuint8, Cx0300, 0x0001, Z(Sat), 1, Z_Nop }, + { Zuint16, Cx0300, 0x0002, Z(RemainingTime), 1, Z_Nop }, + { Zuint16, Cx0300, 0x0003, Z(X), 1, Z_Nop }, + { Zuint16, Cx0300, 0x0004, Z(Y), 1, Z_Nop }, + { Zenum8, Cx0300, 0x0005, Z(DriftCompensation), 1, Z_Nop }, + { Zstring, Cx0300, 0x0006, Z(CompensationText), 1, Z_Nop }, + { Zuint16, Cx0300, 0x0007, Z(CT), 1, Z_Nop }, + { Zenum8, Cx0300, 0x0008, Z(ColorMode), 1, Z_Nop }, + { Zuint8, Cx0300, 0x0010, Z(NumberOfPrimaries), 1, Z_Nop }, + { Zuint16, Cx0300, 0x0011, Z(Primary1X), 1, Z_Nop }, + { Zuint16, Cx0300, 0x0012, Z(Primary1Y), 1, Z_Nop }, + { Zuint8, Cx0300, 0x0013, Z(Primary1Intensity), 1, Z_Nop }, + { Zuint16, Cx0300, 0x0015, Z(Primary2X), 1, Z_Nop }, + { Zuint16, Cx0300, 0x0016, Z(Primary2Y), 1, Z_Nop }, + { Zuint8, Cx0300, 0x0017, Z(Primary2Intensity), 1, Z_Nop }, + { Zuint16, Cx0300, 0x0019, Z(Primary3X), 1, Z_Nop }, + { Zuint16, Cx0300, 0x001A, Z(Primary3Y), 1, Z_Nop }, + { Zuint8, Cx0300, 0x001B, Z(Primary3Intensity), 1, Z_Nop }, + { Zuint16, Cx0300, 0x0030, Z(WhitePointX), 1, Z_Nop }, + { Zuint16, Cx0300, 0x0031, Z(WhitePointY), 1, Z_Nop }, + { Zuint16, Cx0300, 0x0032, Z(ColorPointRX), 1, Z_Nop }, + { Zuint16, Cx0300, 0x0033, Z(ColorPointRY), 1, Z_Nop }, + { Zuint8, Cx0300, 0x0034, Z(ColorPointRIntensity), 1, Z_Nop }, + { Zuint16, Cx0300, 0x0036, Z(ColorPointGX), 1, Z_Nop }, + { Zuint16, Cx0300, 0x0037, Z(ColorPointGY), 1, Z_Nop }, + { Zuint8, Cx0300, 0x0038, Z(ColorPointGIntensity), 1, Z_Nop }, + { Zuint16, Cx0300, 0x003A, Z(ColorPointBX), 1, Z_Nop }, + { Zuint16, Cx0300, 0x003B, Z(ColorPointBY), 1, Z_Nop }, + { Zuint8, Cx0300, 0x003C, Z(ColorPointBIntensity), 1, Z_Nop }, // Illuminance Measurement cluster - { 0x0400, 0x0000, Z(Illuminance), &Z_Copy }, // Illuminance (in Lux) - { 0x0400, 0x0001, Z(IlluminanceMinMeasuredValue), &Z_Copy }, // - { 0x0400, 0x0002, Z(IlluminanceMaxMeasuredValue), &Z_Copy }, // - { 0x0400, 0x0003, Z(IlluminanceTolerance), &Z_Copy }, // - { 0x0400, 0x0004, Z(IlluminanceLightSensorType), &Z_Copy }, // - { 0x0400, 0xFFFF, nullptr, &Z_Remove }, // Remove all other values + { Zuint16, Cx0400, 0x0000, Z(Illuminance), 1, Z_Nop }, // Illuminance (in Lux) + { Zuint16, Cx0400, 0x0001, Z(IlluminanceMinMeasuredValue), 1, Z_Nop }, // + { Zuint16, Cx0400, 0x0002, Z(IlluminanceMaxMeasuredValue), 1, Z_Nop }, // + { Zuint16, Cx0400, 0x0003, Z(IlluminanceTolerance), 1, Z_Nop }, // + { Zenum8, Cx0400, 0x0004, Z(IlluminanceLightSensorType), 1, Z_Nop }, // + { Zunk, Cx0400, 0xFFFF, nullptr, 0, Z_Nop }, // Remove all other values // Illuminance Level Sensing cluster - { 0x0401, 0x0000, Z(IlluminanceLevelStatus), &Z_Copy }, // Illuminance (in Lux) - { 0x0401, 0x0001, Z(IlluminanceLightSensorType), &Z_Copy }, // LightSensorType - { 0x0401, 0xFFFF, nullptr, &Z_Remove }, // Remove all other values + { Zenum8, Cx0401, 0x0000, Z(IlluminanceLevelStatus), 1, Z_Nop }, // Illuminance (in Lux) + { Zenum8, Cx0401, 0x0001, Z(IlluminanceLightSensorType), 1, Z_Nop }, // LightSensorType + { Zuint16, Cx0401, 0x0010, Z(IlluminanceTargetLevel), 1, Z_Nop }, // + { Zunk, Cx0401, 0xFFFF, nullptr, 0, Z_Nop }, // Remove all other values // Temperature Measurement cluster - { 0x0402, 0x0000, Z(Temperature), &Z_FloatDiv100 }, // Temperature - { 0x0402, 0x0001, Z(TemperatureMinMeasuredValue), &Z_FloatDiv100 }, // - { 0x0402, 0x0002, Z(TemperatureMaxMeasuredValue), &Z_FloatDiv100 }, // - { 0x0402, 0x0003, Z(TemperatureTolerance), &Z_FloatDiv100 }, // - { 0x0402, 0xFFFF, nullptr, &Z_Remove }, // Remove all other values + { Zint16, Cx0402, 0x0000, Z(Temperature), -100, Z_Nop }, // divide by 100 + { Zint16, Cx0402, 0x0001, Z(TemperatureMinMeasuredValue), -100, Z_Nop }, // + { Zint16, Cx0402, 0x0002, Z(TemperatureMaxMeasuredValue), -100, Z_Nop }, // + { Zuint16, Cx0402, 0x0003, Z(TemperatureTolerance), -100, Z_Nop }, // + { Zunk, Cx0402, 0xFFFF, nullptr, 0, Z_Nop }, // Remove all other values // Pressure Measurement cluster - { 0x0403, 0x0000, Z(PressureUnit), &Z_AddPressureUnit }, // Pressure Unit - { 0x0403, 0x0000, Z(Pressure), &Z_Copy }, // Pressure - { 0x0403, 0x0001, Z(PressureMinMeasuredValue), &Z_Copy }, // - { 0x0403, 0x0002, Z(PressureMaxMeasuredValue), &Z_Copy }, // - { 0x0403, 0x0003, Z(PressureTolerance), &Z_Copy }, // - { 0x0403, 0x0010, Z(PressureScaledValue), &Z_Copy }, // - { 0x0403, 0x0011, Z(PressureMinScaledValue), &Z_Copy }, // - { 0x0403, 0x0012, Z(PressureMaxScaledValue), &Z_Copy }, // - { 0x0403, 0x0013, Z(PressureScaledTolerance), &Z_Copy }, // - { 0x0403, 0x0014, Z(PressureScale), &Z_Copy }, // - { 0x0403, 0xFFFF, nullptr, &Z_Remove }, // Remove all other Pressure values + { Zunk, Cx0403, 0x0000, Z(PressureUnit), 0, Z_AddPressureUnit }, // Pressure Unit + { Zint16, Cx0403, 0x0000, Z(Pressure), 1, Z_Nop }, // Pressure + { Zint16, Cx0403, 0x0001, Z(PressureMinMeasuredValue), 1, Z_Nop }, // + { Zint16, Cx0403, 0x0002, Z(PressureMaxMeasuredValue), 1, Z_Nop }, // + { Zuint16, Cx0403, 0x0003, Z(PressureTolerance), 1, Z_Nop }, // + { Zint16, Cx0403, 0x0010, Z(PressureScaledValue), 1, Z_Nop }, // + { Zint16, Cx0403, 0x0011, Z(PressureMinScaledValue), 1, Z_Nop }, // + { Zint16, Cx0403, 0x0012, Z(PressureMaxScaledValue), 1, Z_Nop }, // + { Zuint16, Cx0403, 0x0013, Z(PressureScaledTolerance), 1, Z_Nop }, // + { Zint8, Cx0403, 0x0014, Z(PressureScale), 1, Z_Nop }, // + { Zunk, Cx0403, 0xFFFF, nullptr, 0, Z_Nop }, // Remove all other Pressure values // Flow Measurement cluster - { 0x0404, 0x0000, Z(FlowRate), &Z_FloatDiv10 }, // Flow (in m3/h) - { 0x0404, 0x0001, Z(FlowMinMeasuredValue), &Z_Copy }, // - { 0x0404, 0x0002, Z(FlowMaxMeasuredValue), &Z_Copy }, // - { 0x0404, 0x0003, Z(FlowTolerance), &Z_Copy }, // - { 0x0404, 0xFFFF, nullptr, &Z_Remove }, // Remove all other values + { Zuint16, Cx0404, 0x0000, Z(FlowRate), -10, Z_Nop }, // Flow (in m3/h) + { Zuint16, Cx0404, 0x0001, Z(FlowMinMeasuredValue), 1, Z_Nop }, // + { Zuint16, Cx0404, 0x0002, Z(FlowMaxMeasuredValue), 1, Z_Nop }, // + { Zuint16, Cx0404, 0x0003, Z(FlowTolerance), 1, Z_Nop }, // + { Zunk, Cx0404, 0xFFFF, nullptr, 0, Z_Nop }, // Remove all other values // Relative Humidity Measurement cluster - { 0x0405, 0x0000, Z(Humidity), &Z_FloatDiv100 }, // Humidity - { 0x0405, 0x0001, Z(HumidityMinMeasuredValue), &Z_Copy }, // - { 0x0405, 0x0002, Z(HumidityMaxMeasuredValue), &Z_Copy }, // - { 0x0405, 0x0003, "HumidityTolerance", &Z_Copy }, // - { 0x0405, 0xFFFF, nullptr, &Z_Remove }, // Remove all other values + { Zuint16, Cx0405, 0x0000, Z(Humidity), -100, Z_Nop }, // Humidity + { Zuint16, Cx0405, 0x0001, Z(HumidityMinMeasuredValue), 1, Z_Nop }, // + { Zuint16, Cx0405, 0x0002, Z(HumidityMaxMeasuredValue), 1, Z_Nop }, // + { Zuint16, Cx0405, 0x0003, Z(HumidityTolerance), 1, Z_Nop }, // + { Zunk, Cx0405, 0xFFFF, nullptr, 0, Z_Nop }, // Remove all other values // Occupancy Sensing cluster - { 0x0406, 0x0000, Z(Occupancy), &Z_Copy }, // Occupancy (map8) - { 0x0406, 0x0001, Z(OccupancySensorType), &Z_Copy }, // OccupancySensorType - { 0x0406, 0xFFFF, nullptr, &Z_Remove }, // Remove all other values + { Zmap8, Cx0406, 0x0000, Z(Occupancy), 1, Z_Nop }, // Occupancy (map8) + { Zenum8, Cx0406, 0x0001, Z(OccupancySensorType), 1, Z_Nop }, // OccupancySensorType + { Zunk, Cx0406, 0xFFFF, nullptr, 0, Z_Nop }, // Remove all other values // Meter Identification cluster - { 0x0B01, 0x0000, Z(CompanyName), &Z_Copy }, - { 0x0B01, 0x0001, Z(MeterTypeID), &Z_Copy }, - { 0x0B01, 0x0004, Z(DataQualityID), &Z_Copy }, - { 0x0B01, 0x0005, Z(CustomerName), &Z_Copy }, - { 0x0B01, 0x0006, Z(Model), &Z_Copy }, - { 0x0B01, 0x0007, Z(PartNumber), &Z_Copy }, - { 0x0B01, 0x000A, Z(SoftwareRevision), &Z_Copy }, - { 0x0B01, 0x000C, Z(POD), &Z_Copy }, - { 0x0B01, 0x000D, Z(AvailablePower), &Z_Copy }, - { 0x0B01, 0x000E, Z(PowerThreshold), &Z_Copy }, + { Zstring, Cx0B01, 0x0000, Z(CompanyName), 1, Z_Nop }, + { Zuint16, Cx0B01, 0x0001, Z(MeterTypeID), 1, Z_Nop }, + { Zuint16, Cx0B01, 0x0004, Z(DataQualityID), 1, Z_Nop }, + { Zstring, Cx0B01, 0x0005, Z(CustomerName), 1, Z_Nop }, + { Zoctstr, Cx0B01, 0x0006, Z(Model), 1, Z_Nop }, + { Zoctstr, Cx0B01, 0x0007, Z(PartNumber), 1, Z_Nop }, + { Zoctstr, Cx0B01, 0x0008, Z(ProductRevision), 1, Z_Nop }, + { Zoctstr, Cx0B01, 0x000A, Z(SoftwareRevision), 1, Z_Nop }, + { Zstring, Cx0B01, 0x000B, Z(UtilityName), 1, Z_Nop }, + { Zstring, Cx0B01, 0x000C, Z(POD), 1, Z_Nop }, + { Zint24, Cx0B01, 0x000D, Z(AvailablePower), 1, Z_Nop }, + { Zint24, Cx0B01, 0x000E, Z(PowerThreshold), 1, Z_Nop }, // Diagnostics cluster - { 0x0B05, 0x0000, Z(NumberOfResets), &Z_Copy }, - { 0x0B05, 0x0001, Z(PersistentMemoryWrites),&Z_Copy }, - { 0x0B05, 0x011C, Z(LastMessageLQI), &Z_Copy }, - { 0x0B05, 0x011D, Z(LastMessageRSSI), &Z_Copy }, + { Zuint16, Cx0B05, 0x0000, Z(NumberOfResets), 1, Z_Nop }, + { Zuint16, Cx0B05, 0x0001, Z(PersistentMemoryWrites),1, Z_Nop }, + { Zuint8, Cx0B05, 0x011C, Z(LastMessageLQI), 1, Z_Nop }, + { Zuint8, Cx0B05, 0x011D, Z(LastMessageRSSI), 1, Z_Nop }, }; + +typedef union ZCLHeaderFrameControl_t { + struct { + uint8_t frame_type : 2; // 00 = across entire profile, 01 = cluster specific + uint8_t manuf_specific : 1; // Manufacturer Specific Sub-field + uint8_t direction : 1; // 0 = tasmota to zigbee, 1 = zigbee to tasmota + uint8_t disable_def_resp : 1; // don't send back default response + uint8_t reserved : 3; + } b; + uint32_t d8; // raw 8 bits field +} ZCLHeaderFrameControl_t; + + +class ZCLFrame { +public: + + ZCLFrame(uint8_t frame_control, uint16_t manuf_code, uint8_t transact_seq, uint8_t cmd_id, + const char *buf, size_t buf_len, uint16_t clusterid, uint16_t groupaddr, + uint16_t srcaddr, uint8_t srcendpoint, uint8_t dstendpoint, uint8_t wasbroadcast, + uint8_t linkquality, uint8_t securityuse, uint8_t seqnumber): + _manuf_code(manuf_code), _transact_seq(transact_seq), _cmd_id(cmd_id), + _payload(buf_len ? buf_len : 250), // allocate the data frame from source or preallocate big enough + _cluster_id(clusterid), _groupaddr(groupaddr), + _srcaddr(srcaddr), _srcendpoint(srcendpoint), _dstendpoint(dstendpoint), _wasbroadcast(wasbroadcast), + _linkquality(linkquality), _securityuse(securityuse), _seqnumber(seqnumber) + { + _frame_control.d8 = frame_control; + _payload.addBuffer(buf, buf_len); + }; + + + void log(void) { + char hex_char[_payload.len()*2+2]; + ToHex_P((unsigned char*)_payload.getBuffer(), _payload.len(), hex_char, sizeof(hex_char)); + Response_P(PSTR("{\"" D_JSON_ZIGBEEZCL_RECEIVED "\":{" + "\"groupid\":%d," "\"clusterid\":%d," "\"srcaddr\":\"0x%04X\"," + "\"srcendpoint\":%d," "\"dstendpoint\":%d," "\"wasbroadcast\":%d," + "\"" D_CMND_ZIGBEE_LINKQUALITY "\":%d," "\"securityuse\":%d," "\"seqnumber\":%d," + "\"fc\":\"0x%02X\",\"manuf\":\"0x%04X\",\"transact\":%d," + "\"cmdid\":\"0x%02X\",\"payload\":\"%s\"}}"), + _groupaddr, _cluster_id, _srcaddr, + _srcendpoint, _dstendpoint, _wasbroadcast, + _linkquality, _securityuse, _seqnumber, + _frame_control, _manuf_code, _transact_seq, _cmd_id, + hex_char); + if (Settings.flag3.tuya_serial_mqtt_publish) { + MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR)); + XdrvRulesProcess(); + } else { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE "%s"), mqtt_data); + } + } + + static ZCLFrame parseRawFrame(const SBuffer &buf, uint8_t offset, uint8_t len, uint16_t clusterid, uint16_t groupid, + uint16_t srcaddr, uint8_t srcendpoint, uint8_t dstendpoint, uint8_t wasbroadcast, + uint8_t linkquality, uint8_t securityuse, uint8_t seqnumber) { // parse a raw frame and build the ZCL frame object + uint32_t i = offset; + ZCLHeaderFrameControl_t frame_control; + uint16_t manuf_code = 0; + uint8_t transact_seq; + uint8_t cmd_id; + + frame_control.d8 = buf.get8(i++); + if (frame_control.b.manuf_specific) { + manuf_code = buf.get16(i); + i += 2; + } + transact_seq = buf.get8(i++); + cmd_id = buf.get8(i++); + ZCLFrame zcl_frame(frame_control.d8, manuf_code, transact_seq, cmd_id, + (const char *)(buf.buf() + i), len + offset - i, + clusterid, groupid, + srcaddr, srcendpoint, dstendpoint, wasbroadcast, + linkquality, securityuse, seqnumber); + return zcl_frame; + } + + bool isClusterSpecificCommand(void) { + return _frame_control.b.frame_type & 1; + } + + static void generateAttributeName(const JsonObject& json, uint16_t cluster, uint16_t attr, char *key, size_t key_len); + void parseReportAttributes(JsonObject& json, uint8_t offset = 0); + void parseReadAttributes(JsonObject& json, uint8_t offset = 0); + void parseReadAttributesResponse(JsonObject& json, uint8_t offset = 0); + void parseResponse(void); + void parseClusterSpecificCommand(JsonObject& json, uint8_t offset = 0); + void postProcessAttributes(uint16_t shortaddr, JsonObject& json); + + inline void setGroupId(uint16_t groupid) { + _groupaddr = groupid; + } + + inline void setClusterId(uint16_t clusterid) { + _cluster_id = clusterid; + } + + inline uint16_t getSrcAddr(void) const { return _srcaddr; } + inline uint16_t getGroupAddr(void) const { return _groupaddr; } + inline uint16_t getClusterId(void) const { return _cluster_id; } + inline uint8_t getLinkQuality(void) const { return _linkquality; } + inline uint8_t getCmdId(void) const { return _cmd_id; } + inline uint16_t getSrcEndpoint(void) const { return _srcendpoint; } + + const SBuffer &getPayload(void) const { + return _payload; + } + + uint16_t getManufCode(void) const { + return _manuf_code; + } + + +private: + ZCLHeaderFrameControl_t _frame_control = { .d8 = 0 }; + uint16_t _manuf_code = 0; // optional + uint8_t _transact_seq = 0; // transaction sequence number + uint8_t _cmd_id = 0; + SBuffer _payload; + uint16_t _cluster_id = 0; + uint16_t _groupaddr = 0; + // information from decoded ZCL frame + uint16_t _srcaddr; + uint8_t _srcendpoint; + uint8_t _dstendpoint; + uint8_t _wasbroadcast; + uint8_t _linkquality; + uint8_t _securityuse; + uint8_t _seqnumber; +}; + +// Zigbee ZCL converters + +// from https://github.com/Koenkk/zigbee-shepherd-converters/blob/638d29f0cace6343052b9a4e7fd60980fa785479/converters/fromZigbee.js#L55 +// Input voltage in mV, i.e. 3000 = 3.000V +// Output percentage from 0 to 100 as int +uint8_t toPercentageCR2032(uint32_t voltage) { + uint32_t percentage; + if (voltage < 2100) { + percentage = 0; + } else if (voltage < 2440) { + percentage = 6 - ((2440 - voltage) * 6) / 340; + } else if (voltage < 2740) { + percentage = 18 - ((2740 - voltage) * 12) / 300; + } else if (voltage < 2900) { + percentage = 42 - ((2900 - voltage) * 24) / 160; + } else if (voltage < 3000) { + percentage = 100 - ((3000 - voltage) * 58) / 100; + } else if (voltage >= 3000) { + percentage = 100; + } + return percentage; +} + +// +// Appends the attribute value to Write or to Report +// Adds to buf: +// - 2 bytes: attribute identigier +// - 1 byte: attribute type +// - n bytes: value (typically between 1 and 4 bytes, or bigger for strings) +// returns number of bytes of attribute, or <0 if error +// status: shall we insert a status OK (0x00) as required by ReadResponse +int32_t encodeSingleAttribute(class SBuffer &buf, const JsonVariant &val, float val_f, uint16_t attr, uint8_t attrtype, bool status = false) { + uint32_t len = Z_getDatatypeLen(attrtype); // pre-compute lenght, overloaded for variable length attributes + uint32_t u32; + int32_t i32; + float f32; + + if (&val) { + u32 = val.as(); + i32 = val.as(); + f32 = val.as(); + } else { + u32 = val_f; + i32 = val_f; + f32 = val_f; + } + + buf.add16(attr); // prepend with attribute identifier + if (status) { + buf.add8(Z_SUCCESS); // status OK = 0x00 + } + buf.add8(attrtype); // prepend with attribute type + + switch (attrtype) { + // unsigned 8 + case Zbool: // bool + case Zuint8: // uint8 + case Zenum8: // enum8 + case Zdata8: // data8 + case Zmap8: // map8 + buf.add8(u32); + break; + // unsigned 16 + case Zuint16: // uint16 + case Zenum16: // enum16 + case Zdata16: // data16 + case Zmap16: // map16 + buf.add16(u32); + break; + // unisgned 32 + case Zuint32: // uint32 + case Zdata32: // data32 + case Zmap32: // map32 + case ZUTC: // UTC - epoch 32 bits, seconds since 1-Jan-2000 + buf.add32(u32); + break; + + // signed 8 + case Zint8: // int8 + buf.add8(i32); + break; + case Zint16: // int16 + buf.add16(i32); + break; + case Zint32: // int32 + buf.add32(i32); + break; + + case Zsingle: // float + uint32_t *f_ptr; + buf.add32( *((uint32_t*)&f32) ); // cast float as uint32_t + break; + + case Zstring: + case Zstring16: + { + const char * val_str = (&val) ? val.as() : ""; // avoid crash if &val is null + if (nullptr == val_str) { return -2; } + size_t val_len = strlen(val_str); + if (val_len > 32) { val_len = 32; } + len = val_len + 1; + buf.add8(val_len); + if (Zstring16 == attrtype) { + buf.add8(0); // len is on 2 bytes + len++; + } + for (uint32_t i = 0; i < val_len; i++) { + buf.add8(val_str[i]); + } + } + break; + + default: + // remove the attribute type we just added + buf.setLen(buf.len() - (status ? 4 : 3)); + return -1; + } + return len + (status ? 4 : 3); +} + +uint32_t parseSingleAttribute(JsonObject& json, char *attrid_str, class SBuffer &buf, + uint32_t offset, uint32_t buflen) { + + uint32_t i = offset; + uint32_t attrtype = buf.get8(i++); + + // fallback - enter a null value + json[attrid_str] = (char*) nullptr; + + uint32_t len = Z_getDatatypeLen(attrtype); // pre-compute lenght, overloaded for variable length attributes + + // now parse accordingly to attr type + switch (attrtype) { + // case Znodata: // nodata + // case Zunk: // unk + // break; + case Zbool: // bool + case Zuint8: // uint8 + case Zenum8: // enum8 + { + uint8_t uint8_val = buf.get8(i); + // i += 1; + if (0xFF != uint8_val) { + json[attrid_str] = uint8_val; + } + } + break; + case Zuint16: // uint16 + case Zenum16: // enum16 + { + uint16_t uint16_val = buf.get16(i); + // i += 2; + if (0xFFFF != uint16_val) { + json[attrid_str] = uint16_val; + } + } + break; + case Zuint32: // uint32 + case ZUTC: // UTC + { + uint32_t uint32_val = buf.get32(i); + // i += 4; + if (0xFFFFFFFF != uint32_val) { + json[attrid_str] = uint32_val; + } + } + break; + // Note: uint40, uint48, uint56, uint64 are displayed as Hex + // Note: int40, int48, int56, int64 are displayed as Hex + case Zuint40: // uint40 + case Zuint48: // uint48 + case Zuint56: // uint56 + case Zuint64: // uint64 + case Zint40: // int40 + case Zint48: // int48 + case Zint56: // int56 + case Zint64: // int64 + { + // uint8_t len = attrtype - 0x27; // 5 - 8 + // print as HEX + char hex[2*len+1]; + ToHex_P(buf.buf(i), len, hex, sizeof(hex)); + json[attrid_str] = hex; + // i += len; + } + break; + case Zint8: // int8 + { + int8_t int8_val = buf.get8(i); + // i += 1; + if (0x80 != int8_val) { + json[attrid_str] = int8_val; + } + } + break; + case Zint16: // int16 + { + int16_t int16_val = buf.get16(i); + // i += 2; + if (0x8000 != int16_val) { + json[attrid_str] = int16_val; + } + } + break; + case Zint32: // int32 + { + int32_t int32_val = buf.get32(i); + // i += 4; + if (0x80000000 != int32_val) { + json[attrid_str] = int32_val; + } + } + break; + + case Zoctstr: // octet string, 1 byte len + case Zstring: // char string, 1 byte len + case Zoctstr16: // octet string, 2 bytes len + case Zstring16: // char string, 2 bytes len + // For strings, default is to try to do a real string, but reverts to octet stream if null char is present or on some exceptions + { + bool parse_as_string = true; + len = (attrtype <= 0x42) ? buf.get8(i) : buf.get16(i); // len is 8 or 16 bits + i += (attrtype <= 0x42) ? 1 : 2; // increment pointer + if (i + len > buf.len()) { // make sure we don't get past the buffer + len = buf.len() - i; + } + + // check if we can safely use a string + if ((0x41 == attrtype) || (0x43 == attrtype)) { parse_as_string = false; } + + if (parse_as_string) { + char str[len+1]; + strncpy(str, buf.charptr(i), len); + str[len] = 0x00; + json[attrid_str] = str; + } else { + // print as HEX + char hex[2*len+1]; + ToHex_P(buf.buf(i), len, hex, sizeof(hex)); + json[attrid_str] = hex; + } + + // i += len; + // break; + } + // i += buf.get8(i) + 1; + break; + + case Zdata8: // data8 + case Zmap8: // map8 + { + uint8_t uint8_val = buf.get8(i); + // i += 1; + json[attrid_str] = uint8_val; + } + break; + case Zdata16: // data16 + case Zmap16: // map16 + { + uint16_t uint16_val = buf.get16(i); + // i += 2; + json[attrid_str] = uint16_val; + } + break; + case Zdata32: // data32 + case Zmap32: // map32 + { + uint32_t uint32_val = buf.get32(i); + // i += 4; + json[attrid_str] = uint32_val; + } + break; + + case Zsingle: // float + { + uint32_t uint32_val = buf.get32(i); + float * float_val = (float*) &uint32_val; + // i += 4; + json[attrid_str] = *float_val; + } + break; + + // TODO + case ZToD: // ToD + case Zdate: // date + case ZclusterId: // clusterId + case ZattribId: // attribId + case ZbacOID: // bacOID + case ZEUI64: // EUI64 + case Zkey128: // key128 + case Zsemi: // semi (float on 2 bytes) + break; + + // Other un-implemented data types + case Zdata24: // data24 + case Zdata40: // data40 + case Zdata48: // data48 + case Zdata56: // data56 + case Zdata64: // data64 + break; + // map + case Zmap24: // map24 + case Zmap40: // map40 + case Zmap48: // map48 + case Zmap56: // map56 + case Zmap64: // map64 + break; + case Zdouble: // double precision + { + uint64_t uint64_val = buf.get64(i); + double * double_val = (double*) &uint64_val; + // i += 8; + json[attrid_str] = *double_val; + } + break; + } + i += len; + + // String pp; // pretty print + // json[attrid_str].prettyPrintTo(pp); + // // now store the attribute + // AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "ZCL attribute decoded, id %s, type 0x%02X, val=%s"), + // attrid_str, attrtype, pp.c_str()); + return i - offset; // how much have we increased the index +} + +// Generate an attribute name based on cluster number, attribute, and suffix if duplicates +void ZCLFrame::generateAttributeName(const JsonObject& json, uint16_t cluster, uint16_t attr, char *key, size_t key_len) { + uint32_t suffix = 1; + + snprintf_P(key, key_len, PSTR("%04X/%04X"), cluster, attr); + while (json.containsKey(key)) { + suffix++; + snprintf_P(key, key_len, PSTR("%04X/%04X+%d"), cluster, attr, suffix); // add "0008/0001+2" suffix if duplicate + } +} + +// First pass, parse all attributes in their native format +void ZCLFrame::parseReportAttributes(JsonObject& json, uint8_t offset) { + uint32_t i = offset; + uint32_t len = _payload.len(); + + while (len >= i + 3) { + uint16_t attrid = _payload.get16(i); + i += 2; + + char key[16]; + generateAttributeName(json, _cluster_id, attrid, key, sizeof(key)); + + // exception for Xiaomi lumi.weather - specific field to be treated as octet and not char + if ((0x0000 == _cluster_id) && (0xFF01 == attrid)) { + if (0x42 == _payload.get8(i)) { + _payload.set8(i, 0x41); // change type from 0x42 to 0x41 + } + } + i += parseSingleAttribute(json, key, _payload, i, len); + } +} + +// ZCL_READ_ATTRIBUTES +// TODO +void ZCLFrame::parseReadAttributes(JsonObject& json, uint8_t offset) { + uint32_t i = offset; + uint32_t len = _payload.len(); + + json[F(D_CMND_ZIGBEE_CLUSTER)] = _cluster_id; + + JsonArray &attr_list = json.createNestedArray(F("Read")); + JsonObject &attr_names = json.createNestedObject(F("ReadNames")); + while (len - i >= 2) { + uint16_t attrid = _payload.get16(i); + attr_list.add(attrid); + + // find the attribute name + for (uint32_t i = 0; i < ARRAY_SIZE(Z_PostProcess); i++) { + const Z_AttributeConverter *converter = &Z_PostProcess[i]; + uint16_t conv_cluster = CxToCluster(pgm_read_byte(&converter->cluster_short)); + uint16_t conv_attribute = pgm_read_word(&converter->attribute); + + if ((conv_cluster == _cluster_id) && (conv_attribute == attrid)) { + attr_names[(const __FlashStringHelper*) converter->name] = true; + break; + } + } + i += 2; + } +} + +// ZCL_READ_ATTRIBUTES_RESPONSE +void ZCLFrame::parseReadAttributesResponse(JsonObject& json, uint8_t offset) { + uint32_t i = offset; + uint32_t len = _payload.len(); + + while (len >= i + 4) { + uint16_t attrid = _payload.get16(i); + i += 2; + uint8_t status = _payload.get8(i++); + + if (0 == status) { + char key[16]; + generateAttributeName(json, _cluster_id, attrid, key, sizeof(key)); + + i += parseSingleAttribute(json, key, _payload, i, len); + } + } +} + +// ZCL_DEFAULT_RESPONSE +void ZCLFrame::parseResponse(void) { + if (_payload.len() < 2) { return; } // wrong format + uint8_t cmd = _payload.get8(0); + uint8_t status = _payload.get8(1); + + DynamicJsonBuffer jsonBuffer; + JsonObject& json = jsonBuffer.createObject(); + + // "Device" + char s[12]; + snprintf_P(s, sizeof(s), PSTR("0x%04X"), _srcaddr); + json[F(D_JSON_ZIGBEE_DEVICE)] = s; + // "Name" + const char * friendlyName = zigbee_devices.getFriendlyName(_srcaddr); + if (friendlyName) { + json[F(D_JSON_ZIGBEE_NAME)] = (char*) friendlyName; + } + // "Command" + snprintf_P(s, sizeof(s), PSTR("%04X!%02X"), _cluster_id, cmd); + json[F(D_JSON_ZIGBEE_CMD)] = s; + // "Status" + json[F(D_JSON_ZIGBEE_STATUS)] = status; + // "StatusMessage" + json[F(D_JSON_ZIGBEE_STATUS_MSG)] = getZigbeeStatusMessage(status); + // Add Endpoint + json[F(D_CMND_ZIGBEE_ENDPOINT)] = _srcendpoint; + // Add Group if non-zero + if (_groupaddr) { + json[F(D_CMND_ZIGBEE_GROUP)] = _groupaddr; + } + // Add linkquality + json[F(D_CMND_ZIGBEE_LINKQUALITY)] = _linkquality; + + String msg(""); + msg.reserve(100); + json.printTo(msg); + Response_P(PSTR("{\"" D_JSON_ZIGBEE_RESPONSE "\":%s}"), msg.c_str()); + MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED)); + XdrvRulesProcess(); +} + + +// Parse non-normalized attributes +void ZCLFrame::parseClusterSpecificCommand(JsonObject& json, uint8_t offset) { + convertClusterSpecific(json, _cluster_id, _cmd_id, _frame_control.b.direction, _payload); + sendHueUpdate(_srcaddr, _groupaddr, _cluster_id, _cmd_id, _frame_control.b.direction); +} + // ====================================================================== // Record Manuf -int32_t Z_ManufKeep(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { - json[new_name] = value; +int32_t Z_ManufKeepFunc(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { zigbee_devices.setManufId(shortaddr, value.as()); return 1; } -// -int32_t Z_ModelKeep(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { - json[new_name] = value; +// Record ModelId +int32_t Z_ModelKeepFunc(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { zigbee_devices.setModelId(shortaddr, value.as()); return 1; } - -// ====================================================================== -// Remove attribute -int32_t Z_Remove(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { - return 1; // remove original key -} - -// Copy value as-is -int32_t Z_Copy(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { - json[new_name] = value; - return 1; // remove original key +// Record BatteryPercentage +int32_t Z_BatteryPercentageKeepFunc(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { + zigbee_devices.setBatteryPercent(shortaddr, json[new_name]); + return 1; } // Add pressure unit -int32_t Z_AddPressureUnit(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { +int32_t Z_AddPressureUnitFunc(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { json[new_name] = F(D_UNIT_PRESSURE); return 0; // keep original key } -// Convert int to float and divide by 100 -int32_t Z_FloatDiv100(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { - json[new_name] = ((float)value) / 100.0f; - return 1; // remove original key -} -// Convert int to float and divide by 10 -int32_t Z_FloatDiv10(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { - json[new_name] = ((float)value) / 10.0f; - return 1; // remove original key -} -// Convert int to float and divide by 10 -int32_t Z_FloatDiv2(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { - json[new_name] = ((float)value) / 2.0f; - return 1; // remove original key -} - // Publish a message for `"Occupancy":0` when the timer expired int32_t Z_OccupancyCallback(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint32_t value) { DynamicJsonBuffer jsonBuffer; @@ -1016,40 +1195,44 @@ int32_t Z_OccupancyCallback(uint16_t shortaddr, uint16_t groupaddr, uint16_t clu } // Aqara Cube -int32_t Z_AqaraCube(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { - json[new_name] = value; // copy the original value - int32_t val = value; - const __FlashStringHelper *aqara_cube = F("AqaraCube"); - const __FlashStringHelper *aqara_cube_side = F("AqaraCubeSide"); - const __FlashStringHelper *aqara_cube_from_side = F("AqaraCubeFromSide"); +int32_t Z_AqaraCubeFunc(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { + const char * modelId_c = zigbee_devices.getModelId(shortaddr); // null if unknown + String modelId((char*) modelId_c); - switch (val) { - case 0: - json[aqara_cube] = F("shake"); - break; - case 2: - json[aqara_cube] = F("wakeup"); - break; - case 3: - json[aqara_cube] = F("fall"); - break; - case 64 ... 127: - json[aqara_cube] = F("flip90"); - json[aqara_cube_side] = val % 8; - json[aqara_cube_from_side] = (val - 64) / 8; - break; - case 128 ... 132: - json[aqara_cube] = F("flip180"); - json[aqara_cube_side] = val - 128; - break; - case 256 ... 261: - json[aqara_cube] = F("slide"); - json[aqara_cube_side] = val - 256; - break; - case 512 ... 517: - json[aqara_cube] = F("tap"); - json[aqara_cube_side] = val - 512; - break; + if (modelId.startsWith(F("lumi.sensor_cube"))) { // only for Aqara cube + int32_t val = value; + const __FlashStringHelper *aqara_cube = F("AqaraCube"); + const __FlashStringHelper *aqara_cube_side = F("AqaraCubeSide"); + const __FlashStringHelper *aqara_cube_from_side = F("AqaraCubeFromSide"); + + switch (val) { + case 0: + json[aqara_cube] = F("shake"); + break; + case 2: + json[aqara_cube] = F("wakeup"); + break; + case 3: + json[aqara_cube] = F("fall"); + break; + case 64 ... 127: + json[aqara_cube] = F("flip90"); + json[aqara_cube_side] = val % 8; + json[aqara_cube_from_side] = (val - 64) / 8; + break; + case 128 ... 132: + json[aqara_cube] = F("flip180"); + json[aqara_cube_side] = val - 128; + break; + case 256 ... 261: + json[aqara_cube] = F("slide"); + json[aqara_cube_side] = val - 256; + break; + case 512 ... 517: + json[aqara_cube] = F("tap"); + json[aqara_cube_side] = val - 512; + break; + } } // Source: https://github.com/kirovilya/ioBroker.zigbee @@ -1075,7 +1258,7 @@ int32_t Z_AqaraCube(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& j } // Aqara Vibration Sensor - special proprietary attributes -int32_t Z_AqaraVibration(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { +int32_t Z_AqaraVibrationFunc(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { //json[new_name] = value; switch (attr) { case 0x0055: @@ -1126,7 +1309,7 @@ int32_t Z_AqaraVibration(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObje return 1; // remove original key } -int32_t Z_AqaraSensor(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { +int32_t Z_AqaraSensorFunc(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, uint16_t cluster, uint16_t attr) { String hex = value; SBuffer buf2 = SBuffer::SBufferFromHex(hex.c_str(), hex.length()); uint32_t i = 0; @@ -1145,7 +1328,13 @@ int32_t Z_AqaraSensor(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json.remove(tmp); bool translated = false; // were we able to translate to a known format? if (0x01 == attrid) { - json[F(D_JSON_VOLTAGE)] = val / 1000.0f; + float batteryvoltage = val / 1000.0f; + json[F("BatteryVoltage")] = batteryvoltage; + uint8_t batterypercentage = toPercentageCR2032(val); + json[F("BatteryPercentage")] = batterypercentage; + zigbee_devices.setBatteryPercent(shortaddr, batterypercentage); + // deprecated + json[F(D_JSON_VOLTAGE)] = batteryvoltage; json[F("Battery")] = toPercentageCR2032(val); } else if ((nullptr != modelId) && (0 == zcl->getManufCode())) { translated = true; @@ -1186,6 +1375,53 @@ int32_t Z_AqaraSensor(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& } // ====================================================================== +// apply the transformation from the converter +int32_t Z_ApplyConverter(const class ZCLFrame *zcl, uint16_t shortaddr, JsonObject& json, const char *name, JsonVariant& value, const String &new_name, + uint16_t cluster, uint16_t attr, int16_t multiplier, uint16_t cb) { + // apply multiplier if needed + if (1 == multiplier) { // copy unchanged + json[new_name] = value; + } else if (0 != multiplier) { + if (multiplier > 0) { + json[new_name] = ((float)value) * multiplier; + } else { + json[new_name] = ((float)value) / (-multiplier); + } + } + + // apply callback if needed + Z_AttrConverter func = nullptr; + switch (cb) { + case Z_Nop: + return 1; // drop original key + case Z_AddPressureUnit: + func = &Z_AddPressureUnitFunc; + break; + case Z_ManufKeep: + func = &Z_ManufKeepFunc; + break; + case Z_ModelKeep: + func = &Z_ModelKeepFunc; + break; + case Z_AqaraSensor: + func = &Z_AqaraSensorFunc; + break; + case Z_AqaraVibration: + func = &Z_AqaraVibrationFunc; + break; + case Z_AqaraCube: + func = &Z_AqaraCubeFunc; + break; + case Z_BatteryPercentage: + func = &Z_BatteryPercentageKeepFunc; + break; + }; + + if (func) { + return (*func)(zcl, shortaddr, json, name, value, new_name, cluster, attr); + } +} + void ZCLFrame::postProcessAttributes(uint16_t shortaddr, JsonObject& json) { // iterate on json elements for (auto kv : json) { @@ -1245,14 +1481,17 @@ void ZCLFrame::postProcessAttributes(uint16_t shortaddr, JsonObject& json) { // Iterate on filter for (uint32_t i = 0; i < sizeof(Z_PostProcess) / sizeof(Z_PostProcess[0]); i++) { const Z_AttributeConverter *converter = &Z_PostProcess[i]; - uint16_t conv_cluster = pgm_read_word(&converter->cluster); + uint16_t conv_cluster = CxToCluster(pgm_read_byte(&converter->cluster_short)); uint16_t conv_attribute = pgm_read_word(&converter->attribute); + int16_t conv_multiplier = pgm_read_word(&converter->multiplier); + uint16_t conv_cb = pgm_read_word(&converter->cb); // callback id if ((conv_cluster == cluster) && ((conv_attribute == attribute) || (conv_attribute == 0xFFFF)) ) { String new_name_str = (const __FlashStringHelper*) converter->name; if (suffix > 1) { new_name_str += suffix; } // append suffix number - int32_t drop = (*converter->func)(this, shortaddr, json, key, value, new_name_str, conv_cluster, conv_attribute); + // apply the transformation + int32_t drop = Z_ApplyConverter(this, shortaddr, json, key, value, new_name_str, conv_cluster, conv_attribute, conv_multiplier, conv_cb); if (drop) { json.remove(key); } diff --git a/tasmota/xdrv_23_zigbee_6_commands.ino b/tasmota/xdrv_23_zigbee_6_commands.ino index 1893925f3..1f6c4e3a1 100644 --- a/tasmota/xdrv_23_zigbee_6_commands.ino +++ b/tasmota/xdrv_23_zigbee_6_commands.ino @@ -49,13 +49,17 @@ ZF(ResetAlarm) ZF(ResetAllAlarms) ZF(HueSat) ZF(Color) ZF(ShutterOpen) ZF(ShutterClose) ZF(ShutterStop) ZF(ShutterLift) ZF(ShutterTilt) ZF(Shutter) //ZF(Occupancy) -ZF(DimmerMove) ZF(DimmerStep) -ZF(HueMove) ZF(HueStep) ZF(SatMove) ZF(SatStep) ZF(ColorMove) ZF(ColorStep) +ZF(DimmerMove) ZF(DimmerStep) ZF(DimmerStepUp) ZF(DimmerStepDown) +ZF(HueMove) ZF(HueStep) ZF(HueStepUp) ZF(HueStepDown) ZF(SatMove) ZF(SatStep) ZF(ColorMove) ZF(ColorStep) +ZF(ColorTempMoveUp) ZF(ColorTempMoveDown) ZF(ColorTempMoveStop) ZF(ColorTempMove) +ZF(ColorTempStep) ZF(ColorTempStepUp) ZF(ColorTempStepDown) ZF(ArrowClick) ZF(ArrowHold) ZF(ArrowRelease) ZF(ZoneStatusChange) -ZF(xxxx00) ZF(xxxx) ZF(01xxxx) ZF(00) ZF(01) ZF() ZF(xxxxyy) ZF(001902) ZF(011902) ZF(xxyyyy) ZF(xx) +ZF(xxxx00) ZF(xxxx) ZF(01xxxx) ZF(03xxxx) ZF(00) ZF(01) ZF() ZF(xxxxyy) ZF(00190200) ZF(01190200) ZF(xxyyyy) ZF(xx) ZF(xx000A00) ZF(xx0A00) ZF(xxyy0A00) ZF(xxxxyyyy0A00) ZF(xxxx0A00) ZF(xx0A) ZF(xx190A00) ZF(xx19) ZF(xx190A) ZF(xxxxyyyy) ZF(xxxxyyzz) ZF(xxyyzzzz) ZF(xxyyyyzz) +ZF(01xxxx000000000000) ZF(03xxxx000000000000) ZF(00xxxx000000000000) ZF(xxyyyy000000000000) +ZF(00xx0A00) ZF(01xx0A00) ZF(03xx0A00) ZF(01xxxx0A0000000000) ZF(03xxxx0A0000000000) ZF(xxyyyy0A0000000000) // Cluster specific commands // Note: the table is both for sending commands, but also displaying received commands @@ -82,8 +86,8 @@ const Z_CommandConverter Z_Commands[] PROGMEM = { // Light & Shutter commands { Z(Power), 0x0006, 0xFF, 0x01, Z() }, // 0=Off, 1=On, 2=Toggle { Z(Dimmer), 0x0008, 0x04, 0x01, Z(xx0A00) }, // Move to Level with On/Off, xx=0..254 (255 is invalid) - { Z(DimmerUp), 0x0008, 0x06, 0x01, Z(001902) }, // Step up by 10%, 0.2 secs - { Z(DimmerDown), 0x0008, 0x06, 0x01, Z(011902) }, // Step down by 10%, 0.2 secs + { Z(DimmerUp), 0x0008, 0x06, 0x01, Z(00190200) }, // Step up by 10%, 0.2 secs + { Z(DimmerDown), 0x0008, 0x06, 0x01, Z(01190200) }, // Step down by 10%, 0.2 secs { Z(DimmerStop), 0x0008, 0x03, 0x01, Z() }, // Stop any Dimmer animation { Z(ResetAlarm), 0x0009, 0x00, 0x01, Z(xxyyyy) }, // Reset alarm (alarm code + cluster identifier) { Z(ResetAllAlarms), 0x0009, 0x01, 0x01, Z() }, // Reset all alarms @@ -103,17 +107,28 @@ const Z_CommandConverter Z_Commands[] PROGMEM = { // Decoders only - normally not used to send, and names may be masked by previous definitions { Z(Dimmer), 0x0008, 0x00, 0x01, Z(xx) }, { Z(DimmerMove), 0x0008, 0x01, 0x01, Z(xx0A) }, + { Z(DimmerStepUp), 0x0008, 0x02, 0x01, Z(00xx0A00) }, + { Z(DimmerStepDown), 0x0008, 0x02, 0x01, Z(01xx0A00) }, { Z(DimmerStep), 0x0008, 0x02, 0x01, Z(xx190A00) }, { Z(DimmerMove), 0x0008, 0x05, 0x01, Z(xx0A) }, { Z(DimmerUp), 0x0008, 0x06, 0x01, Z(00) }, { Z(DimmerDown), 0x0008, 0x06, 0x01, Z(01) }, { Z(DimmerStop), 0x0008, 0x07, 0x01, Z() }, { Z(HueMove), 0x0300, 0x01, 0x01, Z(xx19) }, + { Z(HueStepUp), 0x0300, 0x02, 0x01, Z(01xx0A00) }, + { Z(HueStepDown), 0x0300, 0x02, 0x01, Z(03xx0A00) }, { Z(HueStep), 0x0300, 0x02, 0x01, Z(xx190A00) }, { Z(SatMove), 0x0300, 0x04, 0x01, Z(xx19) }, { Z(SatStep), 0x0300, 0x05, 0x01, Z(xx190A) }, { Z(ColorMove), 0x0300, 0x08, 0x01, Z(xxxxyyyy) }, { Z(ColorStep), 0x0300, 0x09, 0x01, Z(xxxxyyyy0A00) }, + { Z(ColorTempMoveUp), 0x0300, 0x4B, 0x01, Z(01xxxx000000000000) }, + { Z(ColorTempMoveDown),0x0300, 0x4B, 0x01, Z(03xxxx000000000000) }, + { Z(ColorTempMoveStop),0x0300, 0x4B, 0x01, Z(00xxxx000000000000) }, + { Z(ColorTempMove), 0x0300, 0x4B, 0x01, Z(xxyyyy000000000000) }, + { Z(ColorTempStepUp), 0x0300, 0x4C, 0x01, Z(01xxxx0A0000000000) }, + { Z(ColorTempStepDown),0x0300, 0x4C, 0x01, Z(03xxxx0A0000000000) }, + { Z(ColorTempStep), 0x0300, 0x4C, 0x01, Z(xxyyyy0A0000000000) }, //xx = 0x01 up, 0x03 down, yyyy = step // Tradfri { Z(ArrowClick), 0x0005, 0x07, 0x01, Z(xx) }, // xx == 0x01 = left, 0x00 = right { Z(ArrowHold), 0x0005, 0x08, 0x01, Z(xx) }, // xx == 0x01 = left, 0x00 = right @@ -169,6 +184,9 @@ int32_t Z_ReadAttrCallback(uint16_t shortaddr, uint16_t groupaddr, uint16_t clus break; } if (attrs) { + if (groupaddr) { + shortaddr = BAD_SHORTADDR; // if group address, don't send to device + } ZigbeeZCLSend_Raw(shortaddr, groupaddr, cluster, endpoint, ZCL_READ_ATTRIBUTES, false, 0, attrs, attrs_len, true /* we do want a response */, zigbee_devices.getNextSeqNumber(shortaddr)); } } @@ -176,7 +194,7 @@ int32_t Z_ReadAttrCallback(uint16_t shortaddr, uint16_t groupaddr, uint16_t clus // This callback is registered after a an attribute read command was made to a light, and fires if we don't get any response after 1000 ms int32_t Z_Unreachable(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint32_t value) { - if (shortaddr) { + if (BAD_SHORTADDR != shortaddr) { zigbee_devices.setReachable(shortaddr, false); // mark device as reachable } } @@ -200,7 +218,7 @@ void zigbeeSetCommandTimer(uint16_t shortaddr, uint16_t groupaddr, uint16_t clus } if (wait_ms) { zigbee_devices.setTimer(shortaddr, groupaddr, wait_ms, cluster, endpoint, Z_CAT_NONE, 0 /* value */, &Z_ReadAttrCallback); - if (shortaddr) { // reachability test is not possible for group addresses, since we don't know the list of devices in the group + if (BAD_SHORTADDR != shortaddr) { // reachability test is not possible for group addresses, since we don't know the list of devices in the group zigbee_devices.setTimer(shortaddr, groupaddr, wait_ms + Z_CAT_REACHABILITY_TIMEOUT, cluster, endpoint, Z_CAT_REACHABILITY, 0 /* value */, &Z_Unreachable); } } @@ -306,12 +324,12 @@ void sendHueUpdate(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster, uin } if (z_cat >= 0) { uint8_t endpoint = 0; - if (shortaddr) { + if (BAD_SHORTADDR != shortaddr) { endpoint = zigbee_devices.findFirstEndpoint(shortaddr); } - if ((!shortaddr) || (endpoint)) { // send if group address or endpoint is known + if ((BAD_SHORTADDR == shortaddr) || (endpoint)) { // send if group address or endpoint is known zigbee_devices.setTimer(shortaddr, groupaddr, wait_ms, cluster, endpoint, z_cat, 0 /* value */, &Z_ReadAttrCallback); - if (shortaddr) { // reachability test is not possible for group addresses, since we don't know the list of devices in the group + if (BAD_SHORTADDR != shortaddr) { // reachability test is not possible for group addresses, since we don't know the list of devices in the group zigbee_devices.setTimer(shortaddr, groupaddr, wait_ms + Z_CAT_REACHABILITY_TIMEOUT, cluster, endpoint, Z_CAT_REACHABILITY, 0 /* value */, &Z_Unreachable); } diff --git a/tasmota/xdrv_23_zigbee_7_statemachine.ino b/tasmota/xdrv_23_zigbee_7_statemachine.ino index fc93e8a8d..7b0c1adc6 100644 --- a/tasmota/xdrv_23_zigbee_7_statemachine.ino +++ b/tasmota/xdrv_23_zigbee_7_statemachine.ino @@ -33,8 +33,11 @@ const uint8_t ZIGBEE_STATUS_NODE_DESC = 31; // Node descriptor const uint8_t ZIGBEE_STATUS_ACTIVE_EP = 32; // Endpoints descriptor const uint8_t ZIGBEE_STATUS_SIMPLE_DESC = 33; // Simple Descriptor (clusters) const uint8_t ZIGBEE_STATUS_DEVICE_INDICATION = 34; // Device announces its address +const uint8_t ZIGBEE_STATUS_SCANNING = 40; // State change const uint8_t ZIGBEE_STATUS_CC_VERSION = 50; // Status: CC2530 ZNP Version const uint8_t ZIGBEE_STATUS_CC_INFO = 51; // Status: CC2530 Device Configuration +const uint8_t ZIGBEE_STATUS_EZ_VERSION = 55; // Status: EFR32 EZ Version +const uint8_t ZIGBEE_STATUS_EZ_INFO = 56; // Status: EFR32 EZ Device Configuration const uint8_t ZIGBEE_STATUS_UNSUPPORTED_VERSION = 98; // Unsupported ZNP version const uint8_t ZIGBEE_STATUS_ABORT = 99; // Fatal error, Zigbee not working @@ -79,6 +82,7 @@ enum Zigbee_StateMachine_Instruction_Set { // 12 bytes instructions ZGB_INSTR_12_BYTES = 0xF0, + ZGB_INSTR_WAIT_UNTIL_CALL, // wait until the specified message is received and call function upon receive, ignore all others ZGB_INSTR_WAIT_RECV_CALL, // wait for a filtered message and call function upon receive }; @@ -98,15 +102,33 @@ enum Zigbee_StateMachine_Instruction_Set { #define ZI_SEND(m) { .i = { ZGB_INSTR_SEND, sizeof(m), 0x0000} }, { .p = (const void*)(m) }, #define ZI_WAIT_RECV(x, m) { .i = { ZGB_INSTR_WAIT_RECV, sizeof(m), (x)} }, { .p = (const void*)(m) }, #define ZI_WAIT_UNTIL(x, m) { .i = { ZGB_INSTR_WAIT_UNTIL, sizeof(m), (x)} }, { .p = (const void*)(m) }, -#define ZI_WAIT_RECV_FUNC(x, m, f) { .i = { ZGB_INSTR_WAIT_RECV_CALL, sizeof(m), (x)} }, { .p = (const void*)(m) }, { .p = (const void*)(f) }, +#define ZI_WAIT_UNTIL_FUNC(x, m, f) { .i = { ZGB_INSTR_WAIT_UNTIL_CALL, sizeof(m), (x)} }, { .p = (const void*)(m) }, { .p = (const void*)(f) }, +#define ZI_WAIT_RECV_FUNC(x, m, f) { .i = { ZGB_INSTR_WAIT_RECV_CALL, sizeof(m), (x)} }, { .p = (const void*)(m) }, { .p = (const void*)(f) }, // Labels used in the State Machine -- internal only -const uint8_t ZIGBEE_LABEL_START = 10; // Start ZNP +const uint8_t ZIGBEE_LABEL_RESTART = 1; // Restart the state_machine in a different mode +const uint8_t ZIGBEE_LABEL_INIT_COORD = 10; // Start ZNP as coordinator +const uint8_t ZIGBEE_LABEL_START_COORD = 11; // Start ZNP as coordinator +const uint8_t ZIGBEE_LABEL_INIT_ROUTER = 12; // Init ZNP as router +const uint8_t ZIGBEE_LABEL_START_ROUTER = 13; // Start ZNP as router +const uint8_t ZIGBEE_LABEL_INIT_DEVICE = 14; // Init ZNP as end-device +const uint8_t ZIGBEE_LABEL_START_DEVICE = 15; // Start ZNP as end-device +const uint8_t ZIGBEE_LABEL_START_ROUTER_DEVICE = 16; // Start common to router and device +const uint8_t ZIGBEE_LABEL_BOOT_OK = 17; // MCU has rebooted +const uint8_t ZIGBEE_LABEL_BOOT_TIME_OUT = 18; // MCU has not rebooted +const uint8_t ZIGBEE_LABEL_FACT_RESET_ROUTER_DEVICE_POST = 19; // common post configuration for router and device const uint8_t ZIGBEE_LABEL_READY = 20; // goto label 20 for main loop const uint8_t ZIGBEE_LABEL_MAIN_LOOP = 21; // main loop +const uint8_t ZIGBEE_LABEL_NETWORK_CONFIGURED = 22; // main loop +const uint8_t ZIGBEE_LABEL_BAD_CONFIG = 23; // EZSP configuration is not the right one const uint8_t ZIGBEE_LABEL_PERMIT_JOIN_CLOSE = 30; // disable permit join const uint8_t ZIGBEE_LABEL_PERMIT_JOIN_OPEN_60 = 31; // enable permit join for 60 seconds const uint8_t ZIGBEE_LABEL_PERMIT_JOIN_OPEN_XX = 32; // enable permit join for 60 seconds +// factory reset or reconfiguration +const uint8_t ZIGBEE_LABEL_FACT_RESET_COORD = 50; // main loop +const uint8_t ZIGBEE_LABEL_FACT_RESET_ROUTER = 51; // main loop +const uint8_t ZIGBEE_LABEL_FACT_RESET_DEVICE = 52; // main loop +const uint8_t ZIGBEE_LABEL_CONFIGURE_EZSP = 53; // main loop // errors const uint8_t ZIGBEE_LABEL_ABORT = 99; // goto label 99 in case of fatal error const uint8_t ZIGBEE_LABEL_UNSUPPORTED_VERSION = 98; // Unsupported ZNP version @@ -148,9 +170,27 @@ SBuffer *zigbee_buffer = nullptr; #define Z_B7(a) (uint8_t)( ((a) >> 56) & 0xFF ) // Macro to define message to send and receive #define ZBM(n, x...) const uint8_t n[] PROGMEM = { x }; +// For commands that need to be changed with configuration, ZBR stores in RAM, and ZBW write new values +#define ZBR(n, x...) uint8_t n[] = { x }; // same but in RAM to be modified +#define ZBW(n, x...) { const uint8_t n##t[] = { x }; memcpy(n, n##t, sizeof(n)); } // re-write content in RAM #define USE_ZIGBEE_CHANNEL_MASK (1 << (USE_ZIGBEE_CHANNEL)) +const char kCheckingDeviceConfiguration[] PROGMEM = D_LOG_ZIGBEE "checking device configuration"; +const char kConfiguredCoord[] PROGMEM = "Configured, starting coordinator"; +const char kConfiguredRouter[] PROGMEM = "Configured, starting router"; +const char kConfiguredDevice[] PROGMEM = "Configured, starting device"; +const char kStarted[] PROGMEM = "Started"; +const char kZigbeeStarted[] PROGMEM = D_LOG_ZIGBEE "Zigbee started"; +const char kResetting[] PROGMEM = "Resetting configuration"; +const char kResettingDevice[] PROGMEM = D_LOG_ZIGBEE "Resetting EZSP device"; +const char kZNP12[] PROGMEM = "Only ZNP 1.2 is currently supported"; +const char kEZ8[] PROGMEM = "Only EZSP protocol v8 is currently supported"; +const char kAbort[] PROGMEM = "Abort"; +const char kZigbeeAbort[] PROGMEM = D_LOG_ZIGBEE "Abort"; + +#ifdef USE_ZIGBEE_ZNP + // ZBS_* Zigbee Send // ZBR_* Zigbee Recv ZBM(ZBS_RESET, Z_AREQ | Z_SYS, SYS_RESET, 0x00 ) // 410001 SYS_RESET_REQ Hardware reset @@ -165,24 +205,24 @@ ZBM(ZBR_ZNPHC, Z_SRSP | Z_SYS, SYS_OSAL_NV_READ, Z_SUCCESS, 0x01 /* len */, 0x55 // If not set, the response is 61-08-02-00 = Z_SRSP | Z_SYS, SYS_OSAL_NV_READ, Z_INVALIDPARAMETER, 0x00 /* len */ ZBM(ZBS_PAN, Z_SREQ | Z_SAPI, SAPI_READ_CONFIGURATION, CONF_PANID ) // 260483 -ZBM(ZBR_PAN, Z_SRSP | Z_SAPI, SAPI_READ_CONFIGURATION, Z_SUCCESS, CONF_PANID, 0x02 /* len */, +ZBR(ZBR_PAN, Z_SRSP | Z_SAPI, SAPI_READ_CONFIGURATION, Z_SUCCESS, CONF_PANID, 0x02 /* len */, Z_B0(USE_ZIGBEE_PANID), Z_B1(USE_ZIGBEE_PANID) ) // 6604008302xxxx ZBM(ZBS_EXTPAN, Z_SREQ | Z_SAPI, SAPI_READ_CONFIGURATION, CONF_EXTENDED_PAN_ID ) // 26042D -ZBM(ZBR_EXTPAN, Z_SRSP | Z_SAPI, SAPI_READ_CONFIGURATION, Z_SUCCESS, CONF_EXTENDED_PAN_ID, +ZBR(ZBR_EXTPAN, Z_SRSP | Z_SAPI, SAPI_READ_CONFIGURATION, Z_SUCCESS, CONF_EXTENDED_PAN_ID, 0x08 /* len */, Z_B0(USE_ZIGBEE_EXTPANID), Z_B1(USE_ZIGBEE_EXTPANID), Z_B2(USE_ZIGBEE_EXTPANID), Z_B3(USE_ZIGBEE_EXTPANID), Z_B4(USE_ZIGBEE_EXTPANID), Z_B5(USE_ZIGBEE_EXTPANID), Z_B6(USE_ZIGBEE_EXTPANID), Z_B7(USE_ZIGBEE_EXTPANID), ) // 6604002D08xxxxxxxxxxxxxxxx ZBM(ZBS_CHANN, Z_SREQ | Z_SAPI, SAPI_READ_CONFIGURATION, CONF_CHANLIST ) // 260484 -ZBM(ZBR_CHANN, Z_SRSP | Z_SAPI, SAPI_READ_CONFIGURATION, Z_SUCCESS, CONF_CHANLIST, +ZBR(ZBR_CHANN, Z_SRSP | Z_SAPI, SAPI_READ_CONFIGURATION, Z_SUCCESS, CONF_CHANLIST, 0x04 /* len */, Z_B0(USE_ZIGBEE_CHANNEL_MASK), Z_B1(USE_ZIGBEE_CHANNEL_MASK), Z_B2(USE_ZIGBEE_CHANNEL_MASK), Z_B3(USE_ZIGBEE_CHANNEL_MASK), ) // 6604008404xxxxxxxx ZBM(ZBS_PFGK, Z_SREQ | Z_SAPI, SAPI_READ_CONFIGURATION, CONF_PRECFGKEY ) // 260462 -ZBM(ZBR_PFGK, Z_SRSP | Z_SAPI, SAPI_READ_CONFIGURATION, Z_SUCCESS, CONF_PRECFGKEY, +ZBR(ZBR_PFGK, Z_SRSP | Z_SAPI, SAPI_READ_CONFIGURATION, Z_SUCCESS, CONF_PRECFGKEY, 0x10 /* len */, Z_B0(USE_ZIGBEE_PRECFGKEY_L), Z_B1(USE_ZIGBEE_PRECFGKEY_L), Z_B2(USE_ZIGBEE_PRECFGKEY_L), Z_B3(USE_ZIGBEE_PRECFGKEY_L), Z_B4(USE_ZIGBEE_PRECFGKEY_L), Z_B5(USE_ZIGBEE_PRECFGKEY_L), Z_B6(USE_ZIGBEE_PRECFGKEY_L), Z_B7(USE_ZIGBEE_PRECFGKEY_L), @@ -195,28 +235,48 @@ ZBM(ZBS_PFGKEN, Z_SREQ | Z_SAPI, SAPI_READ_CONFIGURATION, CONF_PRECFGKEYS_ENABLE ZBM(ZBR_PFGKEN, Z_SRSP | Z_SAPI, SAPI_READ_CONFIGURATION, Z_SUCCESS, CONF_PRECFGKEYS_ENABLE, 0x01 /* len */, 0x00 ) // 660400630100 +ZBM(ZBS_LOGTYPE, Z_SREQ | Z_SAPI, SAPI_READ_CONFIGURATION, CONF_LOGICAL_TYPE ) // 260487 +ZBM(ZBS_LOGTYPE_COORD, Z_SRSP | Z_SAPI, SAPI_READ_CONFIGURATION, Z_SUCCESS, CONF_LOGICAL_TYPE, + 0x01 /* len */, 0x00 ) // 660400870100 - coordinator +ZBM(ZBS_LOGTYPE_ROUTER, Z_SRSP | Z_SAPI, SAPI_READ_CONFIGURATION, Z_SUCCESS, CONF_LOGICAL_TYPE, + 0x01 /* len */, 0x01 ) // 660400870101 - router +ZBM(ZBS_LOGTYPE_DEVICE, Z_SRSP | Z_SAPI, SAPI_READ_CONFIGURATION, Z_SUCCESS, CONF_LOGICAL_TYPE, + 0x01 /* len */, 0x02 ) // 660400870102 - device + + // commands to "format" the device // Write configuration - write success ZBM(ZBR_W_OK, Z_SRSP | Z_SAPI, SAPI_WRITE_CONFIGURATION, Z_SUCCESS ) // 660500 - Write Configuration ZBM(ZBR_WNV_OK, Z_SRSP | Z_SYS, SYS_OSAL_NV_WRITE, Z_SUCCESS ) // 610900 - NV Write // Factory reset -ZBM(ZBS_FACTRES, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_STARTUP_OPTION, 0x01 /* len */, 0x02 ) // 2605030102 +ZBM(ZBS_FACTRES, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_STARTUP_OPTION, 0x01 /* len */, 0x03 ) // 2605030103 // Write PAN ID -ZBM(ZBS_W_PAN, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_PANID, 0x02 /* len */, Z_B0(USE_ZIGBEE_PANID), Z_B1(USE_ZIGBEE_PANID) ) // 26058302xxxx +ZBR(ZBS_W_PAN, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_PANID, 0x02 /* len */, Z_B0(USE_ZIGBEE_PANID), Z_B1(USE_ZIGBEE_PANID) ) // 26058302xxxx +// Write Universal PAN ID +ZBR(ZBS_W_ALL_PAN, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_PANID, 0x02 /* len */, Z_B0(0xFFFF), Z_B1(0xFFFF) ) // 26058302FFFF // Write EXT PAN ID -ZBM(ZBS_W_EXTPAN, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_EXTENDED_PAN_ID, 0x08 /* len */, +ZBR(ZBS_W_EXTPAN, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_EXTENDED_PAN_ID, 0x08 /* len */, Z_B0(USE_ZIGBEE_EXTPANID), Z_B1(USE_ZIGBEE_EXTPANID), Z_B2(USE_ZIGBEE_EXTPANID), Z_B3(USE_ZIGBEE_EXTPANID), Z_B4(USE_ZIGBEE_EXTPANID), Z_B5(USE_ZIGBEE_EXTPANID), Z_B6(USE_ZIGBEE_EXTPANID), Z_B7(USE_ZIGBEE_EXTPANID) ) // 26052D086263151D004B1200 // Write Channel ID -ZBM(ZBS_W_CHANN, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_CHANLIST, 0x04 /* len */, +ZBR(ZBS_W_CHANN, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_CHANLIST, 0x04 /* len */, Z_B0(USE_ZIGBEE_CHANNEL_MASK), Z_B1(USE_ZIGBEE_CHANNEL_MASK), Z_B2(USE_ZIGBEE_CHANNEL_MASK), Z_B3(USE_ZIGBEE_CHANNEL_MASK), /*0x00, 0x08, 0x00, 0x00*/ ) // 26058404xxxxxxxx +// Write All Channels +const uint32_t ZB_ALL_CHANNELS = 0x07FFF800; +ZBR(ZBS_W_ALL_CHANN, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_CHANLIST, 0x04 /* len */, + Z_B0(ZB_ALL_CHANNELS), Z_B1(ZB_ALL_CHANNELS), Z_B2(ZB_ALL_CHANNELS), Z_B3(ZB_ALL_CHANNELS), + /*0x00, 0x08, 0x00, 0x00*/ ) // 2605840400F8FF7F // Write Logical Type = 00 = coordinator -ZBM(ZBS_W_LOGTYP, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_LOGICAL_TYPE, 0x01 /* len */, 0x00 ) // 2605870100 +ZBM(ZBS_W_LOGTYP_COORD, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_LOGICAL_TYPE, 0x01 /* len */, 0x00 ) // 2605870100 +// Write Logical Type = 01 = router +ZBM(ZBS_W_LOGTYP_ROUTER, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_LOGICAL_TYPE, 0x01 /* len */, 0x01 ) // 2605870101 +// Write Logical Type = 02 = device +ZBM(ZBS_W_LOGTYP_DEVICE, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_LOGICAL_TYPE, 0x01 /* len */, 0x02 ) // 2605870102 // Write precfgkey -ZBM(ZBS_W_PFGK, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_PRECFGKEY, +ZBR(ZBS_W_PFGK, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_PRECFGKEY, 0x10 /* len */, Z_B0(USE_ZIGBEE_PRECFGKEY_L), Z_B1(USE_ZIGBEE_PRECFGKEY_L), Z_B2(USE_ZIGBEE_PRECFGKEY_L), Z_B3(USE_ZIGBEE_PRECFGKEY_L), Z_B4(USE_ZIGBEE_PRECFGKEY_L), Z_B5(USE_ZIGBEE_PRECFGKEY_L), Z_B6(USE_ZIGBEE_PRECFGKEY_L), Z_B7(USE_ZIGBEE_PRECFGKEY_L), @@ -248,7 +308,10 @@ ZBM(ZBS_WNV_ZNPHC, Z_SREQ | Z_SYS, SYS_OSAL_NV_WRITE, Z_B0(ZNP_HAS_CONFIGURED), // Z_ZDO:startupFromApp ZBM(ZBS_STARTUPFROMAPP, Z_SREQ | Z_ZDO, ZDO_STARTUP_FROM_APP, 100, 0 /* delay */) // 25406400 ZBM(ZBR_STARTUPFROMAPP, Z_SRSP | Z_ZDO, ZDO_STARTUP_FROM_APP ) // 6540 + 01 for new network, 00 for exisitng network, 02 for error -ZBM(AREQ_STARTUPFROMAPP, Z_AREQ | Z_ZDO, ZDO_STATE_CHANGE_IND, ZDO_DEV_ZB_COORD ) // 45C009 + 08 = starting, 09 = started +ZBM(AREQ_STARTUPFROMAPP, Z_AREQ | Z_ZDO, ZDO_STATE_CHANGE_IND ) // 45C00xx - state change +ZBM(AREQ_STARTUPFROMAPP_COORD, Z_AREQ | Z_ZDO, ZDO_STATE_CHANGE_IND, ZDO_DEV_ZB_COORD ) // 45C009 + 08 = starting, 09 = started +ZBM(AREQ_STARTUPFROMAPP_ROUTER, Z_AREQ | Z_ZDO, ZDO_STATE_CHANGE_IND, ZDO_DEV_ROUTER ) // 45C009 + 02 = looking PanID, 07 = started +ZBM(AREQ_STARTUPFROMAPP_DEVICE, Z_AREQ | Z_ZDO, ZDO_STATE_CHANGE_IND, ZDO_DEV_END_DEVICE ) // 45C009 + 02 = looking PanID, 06 = started // GetDeviceInfo ZBM(ZBS_GETDEVICEINFO, Z_SREQ | Z_UTIL, Z_UTIL_GET_DEVICE_INFO ) // 2700 ZBM(ZBR_GETDEVICEINFO, Z_SRSP | Z_UTIL, Z_UTIL_GET_DEVICE_INFO, Z_SUCCESS ) // Ex= 6700.00.6263151D004B1200.0000.07.09.00 @@ -295,40 +358,108 @@ ZBM(ZBR_AF_REGISTER, Z_SRSP | Z_AF, AF_REGISTER, Z_SUCCESS) // 640000 ZBM(ZBS_AF_REGISTER0B, Z_SREQ | Z_AF, AF_REGISTER, 0x0B /* endpoint */, Z_B0(Z_PROF_HA), Z_B1(Z_PROF_HA), // 2400040B050000000000 0x05, 0x00 /* AppDeviceId */, 0x00 /* AppDevVer */, 0x00 /* LatencyReq */, 0x00 /* AppNumInClusters */, 0x00 /* AppNumInClusters */) +// Z_AF:register profile:104, ep:01 - main clusters for router or device +ZBM(ZBS_AF_REGISTER_ALL, Z_SREQ | Z_AF, AF_REGISTER, 0x01 /* endpoint */, Z_B0(Z_PROF_HA), Z_B1(Z_PROF_HA), // 24000401050000000000 + 0x05, 0x00 /* AppDeviceId */, 0x00 /* AppDevVer */, 0x00 /* LatencyReq */, + 0x0E /* AppNumInClusters */, // actually all clusters will be received + 0x00,0x00, 0x04,0x00, 0x05,0x00, 0x06,0x00, // 0x0000, 0x0004, 0x0005, 0x0006 + 0x07,0x00, 0x08,0x00, 0x0A,0x00, 0x02,0x01, // 0x0007, 0x0008, 0x000A, 0X0102 + 0x00,0x03, 0x00,0x04, 0x02,0x04, 0x03,0x04, // 0x0300, 0x0400, 0x0402, 0x0403 + 0x05,0x04, 0x06,0x04, // 0x0405, 0x0406 + 0x00 /* AppNumInClusters */) + // Z_ZDO:mgmtPermitJoinReq ZBM(ZBS_PERMITJOINREQ_CLOSE, Z_SREQ | Z_ZDO, ZDO_MGMT_PERMIT_JOIN_REQ, 0x02 /* AddrMode */, // 25360200000000 0x00, 0x00 /* DstAddr */, 0x00 /* Duration */, 0x00 /* TCSignificance */) ZBM(ZBR_PERMITJOINREQ, Z_SRSP | Z_ZDO, ZDO_MGMT_PERMIT_JOIN_REQ, Z_SUCCESS) // 653600 ZBM(ZBR_PERMITJOIN_AREQ_RSP, Z_AREQ | Z_ZDO, ZDO_MGMT_PERMIT_JOIN_RSP, 0x00, 0x00 /* srcAddr*/, Z_SUCCESS ) // 45B6000000 -const char kCheckingDeviceConfiguration[] PROGMEM = D_LOG_ZIGBEE "checking device configuration"; -const char kConfigured[] PROGMEM = "Configured, starting coordinator"; -const char kStarted[] PROGMEM = "Started"; -const char kZigbeeStarted[] PROGMEM = D_LOG_ZIGBEE "Zigbee started"; -const char kResetting[] PROGMEM = "Resetting configuration"; -const char kZNP12[] PROGMEM = "Only ZNP 1.2 is currently supported"; -const char kAbort[] PROGMEM = "Abort"; -const char kZigbeeAbort[] PROGMEM = D_LOG_ZIGBEE "Abort"; +// Update the relevant commands with Settings +void ZNP_UpdateConfig(uint8_t zb_channel, uint16_t zb_pan_id, uint64_t zb_ext_panid, uint64_t zb_precfgkey_l, uint64_t zb_precfgkey_h) { + uint32_t zb_channel_mask = (1 << zb_channel); + + ZBW(ZBR_PAN, Z_SRSP | Z_SAPI, SAPI_READ_CONFIGURATION, Z_SUCCESS, CONF_PANID, 0x02 /* len */, + Z_B0(zb_pan_id), Z_B1(zb_pan_id) ) // 6604008302xxxx + + ZBW(ZBR_EXTPAN, Z_SRSP | Z_SAPI, SAPI_READ_CONFIGURATION, Z_SUCCESS, CONF_EXTENDED_PAN_ID, + 0x08 /* len */, + Z_B0(zb_ext_panid), Z_B1(zb_ext_panid), Z_B2(zb_ext_panid), Z_B3(zb_ext_panid), + Z_B4(zb_ext_panid), Z_B5(zb_ext_panid), Z_B6(zb_ext_panid), Z_B7(zb_ext_panid), + ) // 6604002D08xxxxxxxxxxxxxxxx + + ZBW(ZBR_CHANN, Z_SRSP | Z_SAPI, SAPI_READ_CONFIGURATION, Z_SUCCESS, CONF_CHANLIST, + 0x04 /* len */, + Z_B0(zb_channel_mask), Z_B1(zb_channel_mask), Z_B2(zb_channel_mask), Z_B3(zb_channel_mask), + ) // 6604008404xxxxxxxx + + ZBW(ZBR_PFGK, Z_SRSP | Z_SAPI, SAPI_READ_CONFIGURATION, Z_SUCCESS, CONF_PRECFGKEY, + 0x10 /* len */, + Z_B0(zb_precfgkey_l), Z_B1(zb_precfgkey_l), Z_B2(zb_precfgkey_l), Z_B3(zb_precfgkey_l), + Z_B4(zb_precfgkey_l), Z_B5(zb_precfgkey_l), Z_B6(zb_precfgkey_l), Z_B7(zb_precfgkey_l), + Z_B0(zb_precfgkey_h), Z_B1(zb_precfgkey_h), Z_B2(zb_precfgkey_h), Z_B3(zb_precfgkey_h), + Z_B4(zb_precfgkey_h), Z_B5(zb_precfgkey_h), Z_B6(zb_precfgkey_h), Z_B7(zb_precfgkey_h), + /*0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F, + 0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0D*/ ) // 660400621001030507090B0D0F00020406080A0C0D + + ZBW(ZBS_W_PAN, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_PANID, 0x02 /* len */, Z_B0(zb_pan_id), Z_B1(zb_pan_id) ) // 26058302xxxx + // Write EXT PAN ID + ZBW(ZBS_W_EXTPAN, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_EXTENDED_PAN_ID, 0x08 /* len */, + Z_B0(zb_ext_panid), Z_B1(zb_ext_panid), Z_B2(zb_ext_panid), Z_B3(zb_ext_panid), + Z_B4(zb_ext_panid), Z_B5(zb_ext_panid), Z_B6(zb_ext_panid), Z_B7(zb_ext_panid) + ) // 26052D086263151D004B1200 + // Write Channel ID + ZBW(ZBS_W_CHANN, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_CHANLIST, 0x04 /* len */, + Z_B0(zb_channel_mask), Z_B1(zb_channel_mask), Z_B2(zb_channel_mask), Z_B3(zb_channel_mask), + /*0x00, 0x08, 0x00, 0x00*/ ) // 26058404xxxxxxxx + // Write precfgkey + ZBW(ZBS_W_PFGK, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_PRECFGKEY, + 0x10 /* len */, + Z_B0(zb_precfgkey_l), Z_B1(zb_precfgkey_l), Z_B2(zb_precfgkey_l), Z_B3(zb_precfgkey_l), + Z_B4(zb_precfgkey_l), Z_B5(zb_precfgkey_l), Z_B6(zb_precfgkey_l), Z_B7(zb_precfgkey_l), + Z_B0(zb_precfgkey_h), Z_B1(zb_precfgkey_h), Z_B2(zb_precfgkey_h), Z_B3(zb_precfgkey_h), + Z_B4(zb_precfgkey_h), Z_B5(zb_precfgkey_h), Z_B6(zb_precfgkey_h), Z_B7(zb_precfgkey_h), + ) // 2605621001030507090B0D0F00020406080A0C0D +} static const Zigbee_Instruction zb_prog[] PROGMEM = { ZI_LABEL(0) ZI_NOOP() ZI_ON_ERROR_GOTO(ZIGBEE_LABEL_ABORT) ZI_ON_TIMEOUT_GOTO(ZIGBEE_LABEL_ABORT) - ZI_ON_RECV_UNEXPECTED(&Z_Recv_Default) + ZI_ON_RECV_UNEXPECTED(&ZNP_Recv_Default) ZI_WAIT(10500) // wait for 10 seconds for Tasmota to stabilize - ZI_ON_ERROR_GOTO(50) //ZI_MQTT_STATE(ZIGBEE_STATUS_BOOT, "Booting") //ZI_LOG(LOG_LEVEL_INFO, D_LOG_ZIGBEE "rebooting device") + ZI_ON_TIMEOUT_GOTO(ZIGBEE_LABEL_BOOT_TIME_OUT) // give a second chance ZI_SEND(ZBS_RESET) // reboot cc2530 just in case we rebooted ESP8266 but not cc2530 - ZI_WAIT_RECV_FUNC(5000, ZBR_RESET, &Z_Reboot) // timeout 5s + ZI_WAIT_RECV_FUNC(5000, ZBR_RESET, &ZNP_Reboot) // timeout 5s + ZI_GOTO(ZIGBEE_LABEL_BOOT_OK) + + ZI_LABEL(ZIGBEE_LABEL_BOOT_TIME_OUT) + ZI_ON_TIMEOUT_GOTO(ZIGBEE_LABEL_ABORT) + ZI_SEND(ZBS_RESET) // reboot cc2530 just in case we rebooted ESP8266 but not cc2530 + ZI_WAIT_RECV_FUNC(5000, ZBR_RESET, &ZNP_Reboot) // timeout 5s + + ZI_LABEL(ZIGBEE_LABEL_BOOT_OK) ZI_WAIT(100) - ZI_LOG(LOG_LEVEL_DEBUG, kCheckingDeviceConfiguration) + ZI_LOG(LOG_LEVEL_DEBUG, kCheckingDeviceConfiguration) // Log Debug: checking device configuration + ZI_SEND(ZBS_VERSION) // check ZNP software version + ZI_WAIT_RECV_FUNC(2000, ZBR_VERSION, &ZNP_ReceiveCheckVersion) // Check if version is valid + + // Dispatching whether coordinator, router or end-device + ZI_CALL(&Z_SwitchDeviceType, 0) // goto ZIGBEE_LABEL_INIT_ROUTER, ZIGBEE_LABEL_INIT_DEVICE or continue if coordinator + + // ====================================================================== + // Start as Zigbee Coordinator + // ====================================================================== + // Check the configuration as Coordinator + ZI_ON_ERROR_GOTO(ZIGBEE_LABEL_FACT_RESET_COORD) ZI_SEND(ZBS_ZNPHC) // check value of ZNP Has Configured ZI_WAIT_RECV(2000, ZBR_ZNPHC) - ZI_SEND(ZBS_VERSION) // check ZNP software version - ZI_WAIT_RECV_FUNC(2000, ZBR_VERSION, &Z_ReceiveCheckVersion) // Check version + + ZI_SEND(ZBS_LOGTYPE) // check the logical type + ZI_WAIT_RECV(1000, ZBS_LOGTYPE_COORD) // it should be coordinator ZI_SEND(ZBS_PAN) // check PAN ID ZI_WAIT_RECV(1000, ZBR_PAN) ZI_SEND(ZBS_EXTPAN) // check EXT PAN ID @@ -342,16 +473,16 @@ static const Zigbee_Instruction zb_prog[] PROGMEM = { //ZI_LOG(LOG_LEVEL_INFO, D_LOG_ZIGBEE "zigbee configuration ok") // all is good, we can start - ZI_LABEL(ZIGBEE_LABEL_START) // START ZNP App - ZI_MQTT_STATE(ZIGBEE_STATUS_STARTING, kConfigured) + ZI_LABEL(ZIGBEE_LABEL_START_COORD) // START ZNP App + ZI_MQTT_STATE(ZIGBEE_STATUS_STARTING, kConfiguredCoord) ZI_ON_ERROR_GOTO(ZIGBEE_LABEL_ABORT) // Z_ZDO:startupFromApp //ZI_LOG(LOG_LEVEL_INFO, D_LOG_ZIGBEE "starting zigbee coordinator") -ZI_SEND(ZBS_STARTUPFROMAPP) // start coordinator + ZI_SEND(ZBS_STARTUPFROMAPP) // start coordinator ZI_WAIT_RECV(2000, ZBR_STARTUPFROMAPP) // wait for sync ack of command - ZI_WAIT_UNTIL(10000, AREQ_STARTUPFROMAPP) // wait for async message that coordinator started + ZI_WAIT_UNTIL_FUNC(10000, AREQ_STARTUPFROMAPP, &ZNP_ReceiveStateChange) // wait for async message that coordinator started ZI_SEND(ZBS_GETDEVICEINFO) // GetDeviceInfo - ZI_WAIT_RECV_FUNC(2000, ZBR_GETDEVICEINFO, &Z_ReceiveDeviceInfo) + ZI_WAIT_RECV_FUNC(2000, ZBR_GETDEVICEINFO, &ZNP_ReceiveDeviceInfo) //ZI_WAIT_RECV(2000, ZBR_GETDEVICEINFO) // memorize info ZI_SEND(ZBS_ZDO_NODEDESCREQ) // Z_ZDO:nodeDescReq ZI_WAIT_RECV(1000, ZBR_ZDO_NODEDESCREQ) @@ -370,7 +501,10 @@ ZI_SEND(ZBS_STARTUPFROMAPP) // start coordinator ZI_SEND(ZBS_PERMITJOINREQ_CLOSE) // Closing the Permit Join ZI_WAIT_RECV(1000, ZBR_PERMITJOINREQ) ZI_WAIT_UNTIL(1000, ZBR_PERMITJOIN_AREQ_RSP) - + + // ====================================================================== + // Correctly configured and running, enable all Tasmota features + // ====================================================================== ZI_LABEL(ZIGBEE_LABEL_READY) ZI_MQTT_STATE(ZIGBEE_STATUS_OK, kStarted) ZI_LOG(LOG_LEVEL_INFO, kZigbeeStarted) @@ -381,7 +515,7 @@ ZI_SEND(ZBS_STARTUPFROMAPP) // start coordinator ZI_WAIT_FOREVER() ZI_GOTO(ZIGBEE_LABEL_READY) - ZI_LABEL(50) // reformat device + ZI_LABEL(ZIGBEE_LABEL_FACT_RESET_COORD) // reformat device ZI_MQTT_STATE(ZIGBEE_STATUS_RESET_CONF, kResetting) //ZI_LOG(LOG_LEVEL_INFO, D_LOG_ZIGBEE "zigbee bad configuration of device, doing a factory reset") ZI_ON_ERROR_GOTO(ZIGBEE_LABEL_ABORT) @@ -395,7 +529,7 @@ ZI_SEND(ZBS_STARTUPFROMAPP) // start coordinator ZI_WAIT_RECV(1000, ZBR_W_OK) ZI_SEND(ZBS_W_CHANN) // write CHANNEL ZI_WAIT_RECV(1000, ZBR_W_OK) - ZI_SEND(ZBS_W_LOGTYP) // write Logical Type = coordinator + ZI_SEND(ZBS_W_LOGTYP_COORD) // write Logical Type = coordinator ZI_WAIT_RECV(1000, ZBR_W_OK) ZI_SEND(ZBS_W_PFGK) // write PRECFGKEY ZI_WAIT_RECV(1000, ZBR_W_OK) @@ -407,23 +541,408 @@ ZI_SEND(ZBS_STARTUPFROMAPP) // start coordinator ZI_WAIT_RECV(1000, ZBR_W_OK) // Now mark the device as ready, writing 0x55 in memory slot 0x0F00 ZI_SEND(ZBS_WNV_INITZNPHC) // Init NV ZNP Has Configured - ZI_WAIT_RECV_FUNC(1000, ZBR_WNV_INIT_OK, &Z_CheckNVWrite) + ZI_WAIT_RECV_FUNC(1000, ZBR_WNV_INIT_OK, &ZNP_CheckNVWrite) ZI_SEND(ZBS_WNV_ZNPHC) // Write NV ZNP Has Configured ZI_WAIT_RECV(1000, ZBR_WNV_OK) //ZI_LOG(LOG_LEVEL_INFO, D_LOG_ZIGBEE "zigbee device reconfigured") - ZI_GOTO(ZIGBEE_LABEL_START) + ZI_GOTO(ZIGBEE_LABEL_START_COORD) + // ====================================================================== + // Start as Zigbee Router + // ====================================================================== + ZI_LABEL(ZIGBEE_LABEL_INIT_ROUTER) // Init as a router + // Check the configuration as Router + ZI_ON_ERROR_GOTO(ZIGBEE_LABEL_FACT_RESET_ROUTER) + ZI_SEND(ZBS_ZNPHC) // check value of ZNP Has Configured + ZI_WAIT_RECV(2000, ZBR_ZNPHC) + ZI_SEND(ZBS_LOGTYPE) // check the logical type + ZI_WAIT_RECV(1000, ZBS_LOGTYPE_ROUTER) // it should be coordinator + + // ZI_LABEL(ZIGBEE_LABEL_START_ROUTER) // Init as a router + ZI_MQTT_STATE(ZIGBEE_STATUS_STARTING, kConfiguredRouter) + ZI_LABEL(ZIGBEE_LABEL_START_ROUTER_DEVICE) + ZI_ON_ERROR_GOTO(ZIGBEE_LABEL_ABORT) + ZI_SEND(ZBS_AF_REGISTER_ALL) // Z_AF register for endpoint 01, profile 0x0104 Home Automation + ZI_WAIT_RECV(1000, ZBR_AF_REGISTER) + ZI_SEND(ZBS_STARTUPFROMAPP) // start router + ZI_WAIT_RECV(2000, ZBR_STARTUPFROMAPP) // wait for sync ack of command + ZI_WAIT_UNTIL_FUNC(0xFFFF, AREQ_STARTUPFROMAPP, &ZNP_ReceiveStateChange) // wait for async message that coordinator started + ZI_SEND(ZBS_GETDEVICEINFO) // GetDeviceInfo + ZI_WAIT_RECV_FUNC(2000, ZBR_GETDEVICEINFO, &ZNP_ReceiveDeviceInfo) + ZI_GOTO(ZIGBEE_LABEL_READY) + + ZI_LABEL(ZIGBEE_LABEL_FACT_RESET_ROUTER) // Factory reset for router + ZI_MQTT_STATE(ZIGBEE_STATUS_RESET_CONF, kResetting) + ZI_ON_ERROR_GOTO(ZIGBEE_LABEL_ABORT) + ZI_SEND(ZBS_FACTRES) // factory reset + ZI_WAIT_RECV(1000, ZBR_W_OK) + ZI_SEND(ZBS_RESET) // reset device + ZI_WAIT_RECV(5000, ZBR_RESET) + ZI_SEND(ZBS_W_LOGTYP_ROUTER) // write Logical Type = router + ZI_WAIT_RECV(1000, ZBR_W_OK) + ZI_LABEL(ZIGBEE_LABEL_FACT_RESET_ROUTER_DEVICE_POST) + ZI_SEND(ZBS_W_ALL_PAN) // write universal PAN ID = 0xFFFF + ZI_WAIT_RECV(1000, ZBR_W_OK) + ZI_SEND(ZBS_W_ALL_CHANN) // write Allows all CHANNELS = 0x07FFF800, 11-26 + ZI_WAIT_RECV(1000, ZBR_W_OK) + + // Now mark the device as ready, writing 0x55 in memory slot 0x0F00 + ZI_SEND(ZBS_WNV_INITZNPHC) // Init NV ZNP Has Configured + ZI_WAIT_RECV_FUNC(1000, ZBR_WNV_INIT_OK, &ZNP_CheckNVWrite) + ZI_SEND(ZBS_WNV_ZNPHC) // Write NV ZNP Has Configured + ZI_WAIT_RECV(1000, ZBR_WNV_OK) + + ZI_GOTO(ZIGBEE_LABEL_START_ROUTER_DEVICE) + + // ====================================================================== + // Start as Zigbee Device + // ====================================================================== + ZI_LABEL(ZIGBEE_LABEL_INIT_DEVICE) // Init as a router + // Check the configuration as Router + ZI_ON_ERROR_GOTO(ZIGBEE_LABEL_FACT_RESET_DEVICE) + ZI_SEND(ZBS_ZNPHC) // check value of ZNP Has Configured + ZI_WAIT_RECV(2000, ZBR_ZNPHC) + ZI_SEND(ZBS_LOGTYPE) // check the logical type + ZI_WAIT_RECV(1000, ZBS_LOGTYPE_DEVICE) // it should be coordinator + + ZI_MQTT_STATE(ZIGBEE_STATUS_STARTING, kConfiguredDevice) + ZI_GOTO(ZIGBEE_LABEL_START_ROUTER_DEVICE) + + ZI_LABEL(ZIGBEE_LABEL_FACT_RESET_DEVICE) // Factory reset for router + ZI_MQTT_STATE(ZIGBEE_STATUS_RESET_CONF, kResetting) + ZI_ON_ERROR_GOTO(ZIGBEE_LABEL_ABORT) + ZI_SEND(ZBS_FACTRES) // factory reset + ZI_WAIT_RECV(1000, ZBR_W_OK) + ZI_SEND(ZBS_RESET) // reset device + ZI_WAIT_RECV(5000, ZBR_RESET) + ZI_SEND(ZBS_W_LOGTYP_DEVICE) // write Logical Type = router + ZI_WAIT_RECV(1000, ZBR_W_OK) + ZI_GOTO(ZIGBEE_LABEL_FACT_RESET_ROUTER_DEVICE_POST) + + // Error: version of Z-Stack is not supported ZI_LABEL(ZIGBEE_LABEL_UNSUPPORTED_VERSION) ZI_MQTT_STATE(ZIGBEE_STATUS_UNSUPPORTED_VERSION, kZNP12) ZI_GOTO(ZIGBEE_LABEL_ABORT) + // Abort state machine, general error ZI_LABEL(ZIGBEE_LABEL_ABORT) // Label 99: abort ZI_MQTT_STATE(ZIGBEE_STATUS_ABORT, kAbort) ZI_LOG(LOG_LEVEL_ERROR, kZigbeeAbort) ZI_STOP(ZIGBEE_LABEL_ABORT) }; +#endif // USE_ZIGBEE_ZNP + +#ifdef USE_ZIGBEE_EZSP + +// patterns for EZSP + +// wait for RSTACK, meaning the device booted +ZBM(ZBR_RSTACK, Z_B0(EZSP_rstAck), Z_B1(EZSP_rstAck)) // FEFF - internal code for RSTACK + +// call version() and ask for EZSP v8 +ZBM(ZBS_VERSION, EZSP_version, 0x00, 0x08) // 000008 +ZBM(ZBR_VERSION, EZSP_version, 0x00, 0x08, 0x02) // 00000802 - expect v8, proto v2 + +// general configuration +// inspired from bellows: https://github.com/zigpy/bellows/blob/dev/bellows/config/ezsp.py +ZBM(ZBS_SET_ADDR_TABLE, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_KEY_TABLE_SIZE, 0x02, 0x00) // 53001E0400 +ZBM(ZBS_SET_MCAST_TABLE, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_MULTICAST_TABLE_SIZE, 0x10, 0x00) // 5300061000 +ZBM(ZBS_SET_STK_PROF, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_STACK_PROFILE, 0x02, 0x00) // 53000C0200 +ZBM(ZBS_SET_SEC_LEVEL, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_SECURITY_LEVEL, 0x05, 0x00) // 53000D0500 +ZBM(ZBS_SET_MAX_DEVICES, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_MAX_END_DEVICE_CHILDREN, 0x20, 0x00) // 5300111800 +ZBM(ZBS_SET_INDIRECT_TMO, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_INDIRECT_TRANSMISSION_TIMEOUT, 0x00, 0x1E) // 530012001E +ZBM(ZBS_SET_TC_CACHE, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_TRUST_CENTER_ADDRESS_CACHE_SIZE, 0x02, 0x00) // 5300190200 +ZBM(ZBS_SET_ROUTE_TBL, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_SOURCE_ROUTE_TABLE_SIZE, 0x10, 0x00) // 53001A1000 +ZBM(ZBS_SET_KEY_TBL, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_KEY_TABLE_SIZE, 0x04, 0x00) // 53001E0400 +ZBM(ZBS_SET_PANID_CNFLCT, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_PAN_ID_CONFLICT_REPORT_THRESHOLD, 0x02, 0x00)// 5300220200 +ZBM(ZBS_SET_ZDO_REQ, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_APPLICATION_ZDO_FLAGS, EMBER_APP_RECEIVES_SUPPORTED_ZDO_REQUESTS | EMBER_APP_HANDLES_UNSUPPORTED_ZDO_REQUESTS, 0x00) // 53002A0300 +ZBM(ZBS_SET_NETWORKS, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_SUPPORTED_NETWORKS, 0x01, 0x00) // 53002D0100 +ZBM(ZBS_SET_PACKET_BUF, EZSP_setConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_PACKET_BUFFER_COUNT, 0xFF, 0x00) // 530001FF00 + +ZBM(ZBR_SET_OK, EZSP_setConfigurationValue, 0x00 /*high*/, 0x00 /*ok*/) // 530000 +ZBM(ZBR_SET_OK2, 0x00, 0x00 /*high*/, 0x00 /*ok*/) // 000000 - TODO why does setting EZSP_CONFIG_PACKET_BUFFER_COUNT has a different response? + +// Read some configuration values +// ZBM(ZBS_GET_APS_UNI, EZSP_getConfigurationValue, 0x00 /*high*/, EZSP_CONFIG_APS_UNICAST_MESSAGE_COUNT) // 520003 +// ZBM(ZBR_GET_OK, EZSP_getConfigurationValue, 0x00 /*high*/, 0x00 /*ok*/) // 5200 - followed by the value + +// Add Endpoints +ZBM(ZBS_ADD_ENDPOINT1, EZSP_addEndpoint, 0x00 /*high*/, 0x01 /*ep*/, Z_B0(Z_PROF_HA), Z_B1(Z_PROF_HA), + 0x05, 0x00 /* AppDeviceId */, 0x00 /* AppDevVer */, + 0x00 /* inputClusterCount */, // actually all clusters will be received + 0X00 /* outputClusterCount */, // 02000104010500000000 + // 0x00,0x00, 0x04,0x00, 0x05,0x00, 0x06,0x00, // 0x0000, 0x0004, 0x0005, 0x0006 + // 0x07,0x00, 0x08,0x00, 0x0A,0x00, 0x02,0x01, // 0x0007, 0x0008, 0x000A, 0X0102 + // 0x00,0x03, 0x00,0x04, 0x02,0x04, 0x03,0x04, // 0x0300, 0x0400, 0x0402, 0x0403 + // 0x05,0x04, 0x06,0x04, // 0x0405, 0x0406 + ) +ZBM(ZBS_ADD_ENDPOINTB, EZSP_addEndpoint, 0x00 /*high*/, 0x0B /*ep*/, Z_B0(Z_PROF_HA), Z_B1(Z_PROF_HA), + 0x05, 0x00 /* AppDeviceId */, 0x00 /* AppDevVer */, + 0x00 /* inputClusterCount */, // actually all clusters will be received + 0X00 /* outputClusterCount */, // 02000B04010500000000 + // 0x00,0x00, 0x04,0x00, 0x05,0x00, 0x06,0x00, // 0x0000, 0x0004, 0x0005, 0x0006 + // 0x07,0x00, 0x08,0x00, 0x0A,0x00, 0x02,0x01, // 0x0007, 0x0008, 0x000A, 0X0102 + // 0x00,0x03, 0x00,0x04, 0x02,0x04, 0x03,0x04, // 0x0300, 0x0400, 0x0402, 0x0403 + // 0x05,0x04, 0x06,0x04, // 0x0405, 0x0406 + ) +ZBM(ZBR_ADD_ENDPOINT, EZSP_addEndpoint, 0x00 /*high*/, 0x00 /*ok*/) // 020000 + +// set concentrator false +ZBM(ZBS_SET_CONCENTRATOR, EZSP_setConcentrator, 0x00 /*high*/, 0x00 /*false*/, 0xF9,0xFF /*HIGH_RAM_CONCENTRATOR*/, + 0x58,0x02 /*minTime*/, 0x08,0x07 /*maxTime*/, 0x02 /*errThr*/, 0x05 /*failThr*/, 0x00 /*maxHops*/) // 100000F9FF58020807020500 +ZBM(ZBR_SET_CONCENTRATOR, EZSP_setConcentrator, 0x00 /*high*/, 0x00 /*ok*/) // 100000 + +// setInitialSecurityState +#define EZ_SECURITY_MODE EMBER_TRUST_CENTER_GLOBAL_LINK_KEY | EMBER_PRECONFIGURED_NETWORK_KEY_MODE | EMBER_HAVE_NETWORK_KEY | EMBER_HAVE_PRECONFIGURED_KEY +ZBR(ZBS_SET_SECURITY, EZSP_setInitialSecurityState, 0x00 /*high*/, + Z_B0(EZ_SECURITY_MODE), Z_B1(EZ_SECURITY_MODE), + // preConfiguredKey + 0x5A, 0x69, 0x67, 0x42, 0x65, 0x65, 0x41, 0x6C, 0x6C, 0x69, 0x61, 0x6E, 0x63, 0x65, 0x30, 0x39, // well known key "ZigBeeAlliance09" + // networkKey + Z_B0(USE_ZIGBEE_PRECFGKEY_L), Z_B1(USE_ZIGBEE_PRECFGKEY_L), Z_B2(USE_ZIGBEE_PRECFGKEY_L), Z_B3(USE_ZIGBEE_PRECFGKEY_L), + Z_B4(USE_ZIGBEE_PRECFGKEY_L), Z_B5(USE_ZIGBEE_PRECFGKEY_L), Z_B6(USE_ZIGBEE_PRECFGKEY_L), Z_B7(USE_ZIGBEE_PRECFGKEY_L), + Z_B0(USE_ZIGBEE_PRECFGKEY_H), Z_B1(USE_ZIGBEE_PRECFGKEY_H), Z_B2(USE_ZIGBEE_PRECFGKEY_H), Z_B3(USE_ZIGBEE_PRECFGKEY_H), + Z_B4(USE_ZIGBEE_PRECFGKEY_H), Z_B5(USE_ZIGBEE_PRECFGKEY_H), Z_B6(USE_ZIGBEE_PRECFGKEY_H), Z_B7(USE_ZIGBEE_PRECFGKEY_H), + 0x00 /*sequence*/, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*trustcenter*/ + ) +ZBM(ZBR_SET_SECURITY, EZSP_setInitialSecurityState, 0x00 /*high*/, 0x00 /*status*/) + +// setIndividual policies +ZBM(ZBS_SET_POLICY_00, EZSP_setPolicy, 0x00 /*high*/, EZSP_TRUST_CENTER_POLICY, + EZSP_DECISION_ALLOW_JOINS | EZSP_DECISION_ALLOW_UNSECURED_REJOINS) // 55000003 +ZBM(ZBS_SET_POLICY_02, EZSP_setPolicy, 0x00 /*high*/, EZSP_UNICAST_REPLIES_POLICY, + EZSP_HOST_WILL_NOT_SUPPLY_REPLY) // 55000220 +ZBM(ZBS_SET_POLICY_03, EZSP_setPolicy, 0x00 /*high*/, EZSP_POLL_HANDLER_POLICY, + EZSP_POLL_HANDLER_IGNORE) // 55000330 +ZBM(ZBS_SET_POLICY_04, EZSP_setPolicy, 0x00 /*high*/, EZSP_MESSAGE_CONTENTS_IN_CALLBACK_POLICY, + EZSP_MESSAGE_TAG_AND_CONTENTS_IN_CALLBACK) // 55000441 +ZBM(ZBS_SET_POLICY_05, EZSP_setPolicy, 0x00 /*high*/, EZSP_TC_KEY_REQUEST_POLICY, + EZSP_ALLOW_TC_KEY_REQUESTS_AND_SEND_CURRENT_KEY) // 55000551 +ZBM(ZBS_SET_POLICY_06, EZSP_setPolicy, 0x00 /*high*/, EZSP_APP_KEY_REQUEST_POLICY, + EZSP_DENY_APP_KEY_REQUESTS) // 55000660 +ZBM(ZBR_SET_POLICY_XX, EZSP_setPolicy, 0x00 /*high*/, 0x00 /*status*/) + +// networkInit - restart the network from previous settings +ZBM(ZBS_NETWORK_INIT, EZSP_networkInit, 0x00 /*high*/, 0x00, 0x00) // 17000000 +ZBM(ZBR_NETWORK_INIT, EZSP_networkInit, 0x00 /*high*/, 0x00 /*status*/) // 170000 + +// formNetwork - i.e. start zigbee network as coordinator +ZBR(ZBS_FORM_NETWORK, EZSP_formNetwork, 0x00 /*high*/, + Z_B0(USE_ZIGBEE_EXTPANID), Z_B1(USE_ZIGBEE_EXTPANID), Z_B2(USE_ZIGBEE_EXTPANID), Z_B3(USE_ZIGBEE_EXTPANID), + Z_B4(USE_ZIGBEE_EXTPANID), Z_B5(USE_ZIGBEE_EXTPANID), Z_B6(USE_ZIGBEE_EXTPANID), Z_B7(USE_ZIGBEE_EXTPANID), + Z_B0(USE_ZIGBEE_PANID), Z_B1(USE_ZIGBEE_PANID), + USE_ZIGBEE_TXRADIO_DBM /*radioTxPower*/, + USE_ZIGBEE_CHANNEL /*channel*/, + EMBER_USE_MAC_ASSOCIATION, + 0xFF,0xFF, /*nwkManagerId, unused*/ + 0x00, /*nwkUpdateId, unused*/ + 0x00,0x00,0x00,0x00, /*NWK channel mask, unused*/ + ) // 1E00... +ZBM(ZBR_FORM_NETWORK, EZSP_formNetwork, 0x00 /*high*/, 0x00 /*status*/) // 1E0000 +ZBM(ZBR_NETWORK_UP, EZSP_stackStatusHandler, 0x00 /*high*/, EMBER_NETWORK_UP) // 190090 + +// leaveNetwork +ZBR(ZBS_LEAVE_NETWORK, EZSP_leaveNetwork, 0x00 /*high*/) // 2000 +ZBM(ZBR_LEAVE_NETWORK, EZSP_leaveNetwork, 0x00 /*high*/) // 2000, we don't care whether it succeeeded or the network was not up + +// read configuration details +ZBM(ZBS_GET_NETW_PARM, EZSP_getNetworkParameters, 0x00 /*high*/) // 2800 +ZBM(ZBR_GET_NETW_PARM, EZSP_getNetworkParameters, 0x00 /*high*/, 0x00 /*ok*/) // 2800 +ZBR(ZBR_CHECK_NETW_PARM, EZSP_getNetworkParameters, 0x00 /*high*/, + 0x00 /*status*/, + EMBER_COORDINATOR /*0x01*/, + Z_B0(USE_ZIGBEE_EXTPANID), Z_B1(USE_ZIGBEE_EXTPANID), Z_B2(USE_ZIGBEE_EXTPANID), Z_B3(USE_ZIGBEE_EXTPANID), + Z_B4(USE_ZIGBEE_EXTPANID), Z_B5(USE_ZIGBEE_EXTPANID), Z_B6(USE_ZIGBEE_EXTPANID), Z_B7(USE_ZIGBEE_EXTPANID), + Z_B0(USE_ZIGBEE_PANID), Z_B1(USE_ZIGBEE_PANID), + USE_ZIGBEE_TXRADIO_DBM /*radioTxPower*/, + USE_ZIGBEE_CHANNEL /*channel*/, + ) // 2800... + +ZBM(ZBS_GET_EUI64, EZSP_getEui64, 0x00 /*high*/) // 2600 +ZBM(ZBR_GET_EUI64, EZSP_getEui64, 0x00 /*high*/) // 2600 +ZBM(ZBS_GET_NODEID, EZSP_getNodeId, 0x00 /*high*/) // 2700 +ZBM(ZBR_GET_NODEID, EZSP_getNodeId, 0x00 /*high*/) // 2700 + +// getCurrentSecurityState +// TODO double check the security bitmask +ZBM(ZBS_GET_CURR_SEC, EZSP_getCurrentSecurityState, 0x00 /*high*/) // 6900 +ZBR(ZBR_GET_CURR_SEC, EZSP_getCurrentSecurityState, 0x00 /*high*/, + 0x00 /*status*/, + 0x7C, 0x00 /*Current Security Bitmask*/, + ) // 6900... + +/*********************************************************************************************\ + * Update the relevant commands with Settings +\*********************************************************************************************/ +// +void EZ_UpdateConfig(uint8_t zb_channel, uint16_t zb_pan_id, uint64_t zb_ext_panid, uint64_t zb_precfgkey_l, uint64_t zb_precfgkey_h, uint8_t zb_txradio_dbm) { + uint8_t txradio = zb_txradio_dbm; + // restrict txradio to acceptable range, and use default otherwise + if (txradio == 0) { txradio = USE_ZIGBEE_TXRADIO_DBM; } + if (txradio > 20) { txradio = USE_ZIGBEE_TXRADIO_DBM; } + + ZBW(ZBS_SET_SECURITY, EZSP_setInitialSecurityState, 0x00 /*high*/, + Z_B0(EZ_SECURITY_MODE), Z_B1(EZ_SECURITY_MODE), + // preConfiguredKey + 0x5A, 0x69, 0x67, 0x42, 0x65, 0x65, 0x41, 0x6C, 0x6C, 0x69, 0x61, 0x6E, 0x63, 0x65, 0x30, 0x39, // well known key "ZigBeeAlliance09" + // networkKey + Z_B0(zb_precfgkey_l), Z_B1(zb_precfgkey_l), Z_B2(zb_precfgkey_l), Z_B3(zb_precfgkey_l), + Z_B4(zb_precfgkey_l), Z_B5(zb_precfgkey_l), Z_B6(zb_precfgkey_l), Z_B7(zb_precfgkey_l), + Z_B0(zb_precfgkey_h), Z_B1(zb_precfgkey_h), Z_B2(zb_precfgkey_h), Z_B3(zb_precfgkey_h), + Z_B4(zb_precfgkey_h), Z_B5(zb_precfgkey_h), Z_B6(zb_precfgkey_h), Z_B7(zb_precfgkey_h), + 0x00 /*sequence*/, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*trustcenter*/ + ) + + ZBW(ZBS_FORM_NETWORK, EZSP_formNetwork, 0x00 /*high*/, + Z_B0(zb_ext_panid), Z_B1(zb_ext_panid), Z_B2(zb_ext_panid), Z_B3(zb_ext_panid), + Z_B4(zb_ext_panid), Z_B5(zb_ext_panid), Z_B6(zb_ext_panid), Z_B7(zb_ext_panid), + Z_B0(zb_pan_id), Z_B1(zb_pan_id), + txradio /*radioTxPower*/, + zb_channel /*channel*/, + EMBER_USE_MAC_ASSOCIATION, + 0xFF,0xFF, /*nwkManagerId, unused*/ + 0x00, /*nwkUpdateId, unused*/ + 0x00,0x00,0x00,0x00, /*NWK channel mask, unused*/ + ) // 1E00... + +ZBW(ZBR_CHECK_NETW_PARM, EZSP_getNetworkParameters, 0x00 /*high*/, + 0x00 /*status*/, + EMBER_COORDINATOR /*0x01*/, + Z_B0(zb_ext_panid), Z_B1(zb_ext_panid), Z_B2(zb_ext_panid), Z_B3(zb_ext_panid), + Z_B4(zb_ext_panid), Z_B5(zb_ext_panid), Z_B6(zb_ext_panid), Z_B7(zb_ext_panid), + Z_B0(zb_pan_id), Z_B1(zb_pan_id), + txradio /*radioTxPower*/, + zb_channel /*channel*/, + ) // 2800... +} + +static const Zigbee_Instruction zb_prog[] PROGMEM = { + ZI_LABEL(0) + ZI_NOOP() + ZI_CALL(EZ_Set_ResetConfig, 0) // for the firt pass, don't do a reset_config + ZI_LABEL(ZIGBEE_LABEL_RESTART) + ZI_ON_ERROR_GOTO(ZIGBEE_LABEL_ABORT) + ZI_ON_TIMEOUT_GOTO(ZIGBEE_LABEL_ABORT) + ZI_ON_RECV_UNEXPECTED(&EZ_Recv_Default) + ZI_WAIT(10500) // wait for 10 seconds for Tasmota to stabilize + + // Hardware reset + ZI_LOG(LOG_LEVEL_INFO, kResettingDevice) // Log Debug: resetting EZSP device + ZI_CALL(&EZ_Reset_Device, 0) // LOW = reset + ZI_WAIT(100) // wait for .1 second + ZI_CALL(&EZ_Reset_Device, 1) // HIGH = release reset + + // wait for device to start + ZI_WAIT_UNTIL(5000, ZBR_RSTACK) // wait for RSTACK message + + // Init device and probe version + ZI_SEND(ZBS_VERSION) ZI_WAIT_RECV_FUNC(1000, ZBR_VERSION, &EZ_ReceiveCheckVersion) // check EXT PAN ID + + // configure EFR32 + ZI_MQTT_STATE(ZIGBEE_STATUS_STARTING, kConfiguredCoord) + ZI_SEND(ZBS_SET_ADDR_TABLE) ZI_WAIT_RECV(500, ZBR_SET_OK) // Address table size + ZI_SEND(ZBS_SET_MCAST_TABLE) ZI_WAIT_RECV(500, ZBR_SET_OK) + ZI_SEND(ZBS_SET_STK_PROF) ZI_WAIT_RECV(500, ZBR_SET_OK) + ZI_SEND(ZBS_SET_SEC_LEVEL) ZI_WAIT_RECV(500, ZBR_SET_OK) + ZI_SEND(ZBS_SET_MAX_DEVICES) ZI_WAIT_RECV(500, ZBR_SET_OK) + ZI_SEND(ZBS_SET_INDIRECT_TMO) ZI_WAIT_RECV(500, ZBR_SET_OK) + ZI_SEND(ZBS_SET_TC_CACHE) ZI_WAIT_RECV(500, ZBR_SET_OK) + ZI_SEND(ZBS_SET_ROUTE_TBL) ZI_WAIT_RECV(500, ZBR_SET_OK) + ZI_SEND(ZBS_SET_KEY_TBL) ZI_WAIT_RECV(500, ZBR_SET_OK) + ZI_SEND(ZBS_SET_PANID_CNFLCT) ZI_WAIT_RECV(500, ZBR_SET_OK) + ZI_SEND(ZBS_SET_ZDO_REQ) ZI_WAIT_RECV(500, ZBR_SET_OK) + ZI_SEND(ZBS_SET_NETWORKS) ZI_WAIT_RECV(500, ZBR_SET_OK) + ZI_SEND(ZBS_SET_PACKET_BUF) ZI_WAIT_RECV(500, ZBR_SET_OK2) + + // read configuration + // TODO - not sure it's useful + //ZI_SEND(ZBS_GET_APS_UNI) ZI_WAIT_RECV_FUNC(500, ZBR_GET_OK, &EZ_ReadAPSUnicastMessage) + + // add endpoint 0x01 and 0x0B + ZI_SEND(ZBS_ADD_ENDPOINT1) ZI_WAIT_RECV(500, ZBR_ADD_ENDPOINT) + ZI_SEND(ZBS_ADD_ENDPOINTB) ZI_WAIT_RECV(500, ZBR_ADD_ENDPOINT) + + // set Concentrator + ZI_SEND(ZBS_SET_CONCENTRATOR) ZI_WAIT_RECV(500, ZBR_SET_CONCENTRATOR) + + // setInitialSecurityState + ZI_SEND(ZBS_SET_POLICY_00) ZI_WAIT_RECV(500, ZBR_SET_POLICY_XX) + ZI_SEND(ZBS_SET_POLICY_02) ZI_WAIT_RECV(500, ZBR_SET_POLICY_XX) + ZI_SEND(ZBS_SET_POLICY_03) ZI_WAIT_RECV(500, ZBR_SET_POLICY_XX) + // ZI_SEND(ZBS_SET_POLICY_04) ZI_WAIT_RECV(500, ZBR_SET_POLICY_XX) + ZI_SEND(ZBS_SET_POLICY_05) ZI_WAIT_RECV(500, ZBR_SET_POLICY_XX) + ZI_SEND(ZBS_SET_POLICY_06) ZI_WAIT_RECV(500, ZBR_SET_POLICY_XX) + + // set encryption keys + ZI_SEND(ZBS_SET_SECURITY) ZI_WAIT_RECV(500, ZBR_SET_SECURITY) + + // Decide whether we try 'networkInit()' to restore configuration, or create a new network + ZI_CALL(&EZ_GotoIfResetConfig, ZIGBEE_LABEL_CONFIGURE_EZSP) // goto ZIGBEE_LABEL_CONFIGURE_EZSP if reset_config is set + + // ZI_GOTO(ZIGBEE_LABEL_CONFIGURE_EZSP) + + // // Try networkInit to restore settings, and check if network comes up + ZI_ON_TIMEOUT_GOTO(ZIGBEE_LABEL_BAD_CONFIG) // + ZI_ON_ERROR_GOTO(ZIGBEE_LABEL_BAD_CONFIG) + ZI_SEND(ZBS_NETWORK_INIT) ZI_WAIT_RECV(500, ZBR_NETWORK_INIT) + ZI_WAIT_RECV(1500, ZBR_NETWORK_UP) // wait for network to start + // check if configuration is ok + ZI_SEND(ZBS_GET_CURR_SEC) ZI_WAIT_RECV(500, ZBR_GET_CURR_SEC) + ZI_SEND(ZBS_GET_NETW_PARM) ZI_WAIT_RECV(500, ZBR_CHECK_NETW_PARM) + // all ok, proceed to next step + ZI_GOTO(ZIGBEE_LABEL_NETWORK_CONFIGURED) + + ZI_LABEL(ZIGBEE_LABEL_BAD_CONFIG) + ZI_MQTT_STATE(ZIGBEE_STATUS_RESET_CONF, kResetting) + ZI_CALL(EZ_Set_ResetConfig, 1) // change mode to reset_config + ZI_GOTO(ZIGBEE_LABEL_RESTART) // restart state_machine + + ZI_LABEL(ZIGBEE_LABEL_CONFIGURE_EZSP) + // Set back normal error handlers + ZI_ON_TIMEOUT_GOTO(ZIGBEE_LABEL_ABORT) + ZI_ON_ERROR_GOTO(ZIGBEE_LABEL_ABORT) + // formNetwork + ZI_SEND(ZBS_FORM_NETWORK) ZI_WAIT_RECV(500, ZBR_FORM_NETWORK) + ZI_WAIT_RECV(5000, ZBR_NETWORK_UP) // wait for network to start + + ZI_LABEL(ZIGBEE_LABEL_NETWORK_CONFIGURED) + // Set back normal error handlers + ZI_ON_TIMEOUT_GOTO(ZIGBEE_LABEL_ABORT) + ZI_ON_ERROR_GOTO(ZIGBEE_LABEL_ABORT) + // Query device information + ZI_SEND(ZBS_GET_EUI64) ZI_WAIT_RECV_FUNC(500, ZBR_GET_EUI64, &EZ_GetEUI64) + ZI_SEND(ZBS_GET_NODEID) ZI_WAIT_RECV_FUNC(500, ZBR_GET_NODEID, &EZ_GetNodeId) + ZI_SEND(ZBS_GET_NETW_PARM) ZI_WAIT_RECV_FUNC(500, ZBR_GET_NETW_PARM, &EZ_NetworkParameters) + + ZI_LABEL(ZIGBEE_LABEL_READY) + ZI_MQTT_STATE(ZIGBEE_STATUS_OK, kStarted) + ZI_LOG(LOG_LEVEL_INFO, kZigbeeStarted) + ZI_CALL(&Z_State_Ready, 1) // Now accept incoming messages + ZI_CALL(&Z_Load_Devices, 0) + ZI_CALL(&Z_Query_Bulbs, 0) + + ZI_LABEL(ZIGBEE_LABEL_MAIN_LOOP) + ZI_WAIT_FOREVER() + ZI_GOTO(ZIGBEE_LABEL_MAIN_LOOP) + + // Error: version of Z-Stack is not supported + ZI_LABEL(ZIGBEE_LABEL_UNSUPPORTED_VERSION) + ZI_MQTT_STATE(ZIGBEE_STATUS_UNSUPPORTED_VERSION, kEZ8) + ZI_GOTO(ZIGBEE_LABEL_ABORT) + + // Abort state machine, general error + ZI_LABEL(ZIGBEE_LABEL_ABORT) // Label 99: abort + ZI_MQTT_STATE(ZIGBEE_STATUS_ABORT, kAbort) + ZI_LOG(LOG_LEVEL_ERROR, kZigbeeAbort) + ZI_STOP(ZIGBEE_LABEL_ABORT) +}; + +#endif // USE_ZIGBEE_EZSP + uint8_t ZigbeeGetInstructionSize(uint8_t instr) { // in Zigbee_Instruction lines (words) if (instr >= ZGB_INSTR_12_BYTES) { return 3; @@ -441,7 +960,7 @@ void ZigbeeGotoLabel(uint8_t label) { uint8_t cur_d8 = 0; uint8_t cur_instr_len = 1; // size of current instruction in words - for (uint32_t i = 0; i < sizeof(zb_prog)/sizeof(zb_prog[0]); i += cur_instr_len) { + for (uint32_t i = 0; i < ARRAY_SIZE(zb_prog); i += cur_instr_len) { const Zigbee_Instruction *cur_instr_line = &zb_prog[i]; cur_instr = pgm_read_byte(&cur_instr_line->i.i); cur_d8 = pgm_read_byte(&cur_instr_line->i.d8); @@ -500,7 +1019,7 @@ void ZigbeeStateMachine_Run(void) { zigbee.recv_until = false; zigbee.state_no_timeout = false; // reset the no_timeout for next instruction - if (zigbee.pc > (sizeof(zb_prog)/sizeof(zb_prog[0]))) { + if (zigbee.pc > ARRAY_SIZE(zb_prog)) { AddLog_P2(LOG_LEVEL_ERROR, PSTR(D_LOG_ZIGBEE "Invalid pc: %d, aborting"), zigbee.pc); zigbee.pc = -1; } @@ -576,33 +1095,46 @@ void ZigbeeStateMachine_Run(void) { case ZGB_INSTR_MQTT_STATE: { const char *f_msg = (const char*) cur_ptr1; - char buf[strlen_P(f_msg) + 1]; - strcpy_P(buf, f_msg); Response_P(PSTR("{\"" D_JSON_ZIGBEE_STATE "\":{\"Status\":%d,\"Message\":\"%s\"}}"), - cur_d8, buf); + cur_d8, f_msg); MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE)); XdrvRulesProcess(); } break; case ZGB_INSTR_SEND: +#ifdef USE_ZIGBEE_ZNP ZigbeeZNPSend((uint8_t*) cur_ptr1, cur_d8 /* len */); +#endif // USE_ZIGBEE_ZNP +#ifdef USE_ZIGBEE_EZSP + ZigbeeEZSPSendCmd((uint8_t*) cur_ptr1, cur_d8 /* len */, true); // send cancel byte +#endif // USE_ZIGBEE_EZSP break; case ZGB_INSTR_WAIT_UNTIL: zigbee.recv_until = true; // and reuse ZGB_INSTR_WAIT_RECV case ZGB_INSTR_WAIT_RECV: zigbee.recv_filter = (uint8_t *) cur_ptr1; zigbee.recv_filter_len = cur_d8; // len - zigbee.next_timeout = now + cur_d16; + if (0xFFFF == cur_d16) { + zigbee.next_timeout = 0; // forever + } else { + zigbee.next_timeout = now + cur_d16; + } zigbee.state_waiting = true; break; case ZGB_ON_RECV_UNEXPECTED: zigbee.recv_unexpected = (ZB_RecvMsgFunc) cur_ptr1; break; + case ZGB_INSTR_WAIT_UNTIL_CALL: + zigbee.recv_until = true; // and reuse ZGB_INSTR_WAIT_RECV case ZGB_INSTR_WAIT_RECV_CALL: zigbee.recv_filter = (uint8_t *) cur_ptr1; zigbee.recv_filter_len = cur_d8; // len zigbee.recv_func = (ZB_RecvMsgFunc) cur_ptr2; - zigbee.next_timeout = now + cur_d16; + if (0xFFFF == cur_d16) { + zigbee.next_timeout = 0; // forever + } else { + zigbee.next_timeout = now + cur_d16; + } zigbee.state_waiting = true; break; } diff --git a/tasmota/xdrv_23_zigbee_8_parsers.ino b/tasmota/xdrv_23_zigbee_8_parsers.ino index aa9505bd7..a94a07aeb 100644 --- a/tasmota/xdrv_23_zigbee_8_parsers.ino +++ b/tasmota/xdrv_23_zigbee_8_parsers.ino @@ -19,6 +19,154 @@ #ifdef USE_ZIGBEE +#ifdef USE_ZIGBEE_EZSP +/*********************************************************************************************\ + * Parsers for incoming EZSP messages +\*********************************************************************************************/ + +// EZSP: received ASH "RSTACK" frame, indicating that the MCU finished boot +int32_t EZ_RSTACK(uint8_t reset_code) { + const char *reason_str; + + switch (reset_code) { + case 0x01: reason_str = PSTR("External"); break; + case 0x02: reason_str = PSTR("Power-on"); break; + case 0x03: reason_str = PSTR("Watchdog"); break; + case 0x06: reason_str = PSTR("Assert"); break; + case 0x09: reason_str = PSTR("Bootloader"); break; + case 0x0B: reason_str = PSTR("Software"); break; + case 0x00: + default: reason_str = PSTR("Unknown"); break; + } + Response_P(PSTR("{\"" D_JSON_ZIGBEE_STATE "\":{" + "\"Status\":%d,\"Message\":\"EFR32 booted\",\"RestartReason\":\"%s\"" + ",\"Code\":%d}}"), + ZIGBEE_STATUS_BOOT, reason_str, reset_code); + + MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE)); + XdrvRulesProcess(); +} + +// EZSP: received ASH "ERROR" frame, indicating that the MCU finished boot +int32_t EZ_ERROR(uint8_t error_code) { + const char *reason_str; + + switch (error_code) { + case 0x51: reason_str = PSTR("ACK timeout"); break; + default: reason_str = PSTR("Unknown"); break; + } + Response_P(PSTR("{\"" D_JSON_ZIGBEE_STATE "\":{" + "\"Status\":%d,\"Message\":\"Failed state\",\"Error\":\"%s\"" + ",\"Code\":%d}}"), + ZIGBEE_STATUS_ABORT, reason_str, error_code); + + MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE)); + XdrvRulesProcess(); +} + +int32_t EZ_ReadAPSUnicastMessage(int32_t res, class SBuffer &buf) { + // Called when receiving a response from getConfigurationValue + // Value is in bytes 2+3 + uint16_t value = buf.get16(2); + return res; +} + +/*********************************************************************************************\ + * Parsers for incoming EZSP messages +\*********************************************************************************************/ + +// +// Handle a "getEui64" incoming message +// +int32_t EZ_GetEUI64(int32_t res, class SBuffer &buf) { + localIEEEAddr = buf.get64(2); + return res; +} + +// +// Handle a "getEui64" incoming message +// +int32_t EZ_GetNodeId(int32_t res, class SBuffer &buf) { + localShortAddr = buf.get8(2); + return res; +} + +// +// Handle a "getNetworkParameters" incoming message +// +int32_t EZ_NetworkParameters(int32_t res, class SBuffer &buf) { + uint8_t node_type = buf.get8(3); + // ext panid: 4->11 + // panid: 12->13 + // radioTxPower: 14 + // radioChannel: 15 + + // Local short and long addresses are supposed to be already retrieved + // localIEEEAddr = long_adr; + // localShortAddr = short_adr; + + char hex[20]; + Uint64toHex(localIEEEAddr, hex, 64); + Response_P(PSTR("{\"" D_JSON_ZIGBEE_STATE "\":{" + "\"Status\":%d,\"IEEEAddr\":\"0x%s\",\"ShortAddr\":\"0x%04X\"" + ",\"DeviceType\":%d}}"), + ZIGBEE_STATUS_EZ_INFO, hex, localShortAddr, node_type); + + MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE)); + XdrvRulesProcess(); + + return res; +} + +#endif // USE_ZIGBEE_EZSP + +/*********************************************************************************************\ + * Parsers for incoming EZSP messages +\*********************************************************************************************/ + +// +// Handle a "getEui64" incoming message +// +int32_t Z_EZSPGetEUI64(int32_t res, class SBuffer &buf) { + localIEEEAddr = buf.get64(2); + return res; +} + +// +// Handle a "getEui64" incoming message +// +int32_t Z_EZSPGetNodeId(int32_t res, class SBuffer &buf) { + localShortAddr = buf.get8(2); + return res; +} + +// +// Handle a "getNetworkParameters" incoming message +// +int32_t Z_EZSPNetworkParameters(int32_t res, class SBuffer &buf) { + uint8_t node_type = buf.get8(3); + // ext panid: 4->11 + // panid: 12->13 + // radioTxPower: 14 + // radioChannel: 15 + + // Local short and long addresses are supposed to be already retrieved + // localIEEEAddr = long_adr; + // localShortAddr = short_adr; + + char hex[20]; + Uint64toHex(localIEEEAddr, hex, 64); + Response_P(PSTR("{\"" D_JSON_ZIGBEE_STATE "\":{" + "\"Status\":%d,\"IEEEAddr\":\"0x%s\",\"ShortAddr\":\"0x%04X\"" + ",\"DeviceType\":%d}}"), + ZIGBEE_STATUS_EZ_INFO, hex, localShortAddr, node_type); + + MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE)); + XdrvRulesProcess(); + + return res; +} + /*********************************************************************************************\ * Parsers for incoming ZNP messages \*********************************************************************************************/ @@ -26,7 +174,7 @@ // // Handle a "Receive Device Info" incoming message // -int32_t Z_ReceiveDeviceInfo(int32_t res, class SBuffer &buf) { +int32_t ZNP_ReceiveDeviceInfo(int32_t res, class SBuffer &buf) { // Ex= 6700.00.6263151D004B1200.0000.07.09.02.83869991 // IEEE Adr (8 bytes) = 0x00124B001D156362 // Short Addr (2 bytes) = 0x0000 @@ -42,6 +190,7 @@ int32_t Z_ReceiveDeviceInfo(int32_t res, class SBuffer &buf) { // keep track of the local IEEE address localIEEEAddr = long_adr; + localShortAddr = short_adr; char hex[20]; Uint64toHex(long_adr, hex, 64); @@ -52,7 +201,7 @@ int32_t Z_ReceiveDeviceInfo(int32_t res, class SBuffer &buf) { ZIGBEE_STATUS_CC_INFO, hex, short_adr, device_type, device_state, device_associated); - if (device_associated > 0) { + if (device_associated > 0) { // If there are devices registered in CC2530, print the list uint idx = 16; ResponseAppend_P(PSTR(",\"AssocDevicesList\":[")); for (uint32_t i = 0; i < device_associated; i++) { @@ -71,7 +220,7 @@ int32_t Z_ReceiveDeviceInfo(int32_t res, class SBuffer &buf) { return res; } -int32_t Z_CheckNVWrite(int32_t res, class SBuffer &buf) { +int32_t ZNP_CheckNVWrite(int32_t res, class SBuffer &buf) { // Check the status after NV Init "ZNP Has Configured" // Good response should be 610700 or 610709 (Success or Created) // We only filter the response on 6107 and check the code in this function @@ -83,22 +232,24 @@ int32_t Z_CheckNVWrite(int32_t res, class SBuffer &buf) { } } -int32_t Z_Reboot(int32_t res, class SBuffer &buf) { +int32_t ZNP_Reboot(int32_t res, class SBuffer &buf) { // print information about the reboot of device // 4180.02.02.00.02.06.03 // - static const char Z_RebootReason[] PROGMEM = "Power-up|External|Watchdog"; - uint8_t reason = buf.get8(2); uint8_t transport_rev = buf.get8(3); uint8_t product_id = buf.get8(4); uint8_t major_rel = buf.get8(5); uint8_t minor_rel = buf.get8(6); uint8_t hw_rev = buf.get8(7); - char reason_str[12]; + const char *reason_str; - if (reason > 3) { reason = 3; } - GetTextIndexed(reason_str, sizeof(reason_str), reason, Z_RebootReason); + switch (reason) { + case 0: reason_str = PSTR("Power-up"); break; + case 1: reason_str = PSTR("External"); break; + case 2: reason_str = PSTR("Watchdog"); break; + default: reason_str = PSTR("Unknown"); break; + } Response_P(PSTR("{\"" D_JSON_ZIGBEE_STATE "\":{" "\"Status\":%d,\"Message\":\"CC2530 booted\",\"RestartReason\":\"%s\"" @@ -116,7 +267,8 @@ int32_t Z_Reboot(int32_t res, class SBuffer &buf) { } } -int32_t Z_ReceiveCheckVersion(int32_t res, class SBuffer &buf) { +#ifdef USE_ZIGBEE_ZNP +int32_t ZNP_ReceiveCheckVersion(int32_t res, class SBuffer &buf) { // check that the version is supported // typical version for ZNP 1.2 // 61020200-02.06.03.D9143401.0200000000 @@ -146,6 +298,64 @@ int32_t Z_ReceiveCheckVersion(int32_t res, class SBuffer &buf) { return ZIGBEE_LABEL_UNSUPPORTED_VERSION; // abort } } +#endif // USE_ZIGBEE_ZNP + +#ifdef USE_ZIGBEE_EZSP +int32_t EZ_ReceiveCheckVersion(int32_t res, class SBuffer &buf) { + uint8_t protocol_version = buf.get8(2); + uint8_t stack_type = buf.get8(3); + uint16_t stack_version = buf.get16(4); + + Response_P(PSTR("{\"" D_JSON_ZIGBEE_STATE "\":{" + "\"Status\":%d,\"Version\":\"%d.%d.%d.%d\",\"Protocol\":%d" + ",\"Stack\":%d}}"), + ZIGBEE_STATUS_EZ_VERSION, + (stack_version & 0xF000) >> 12, + (stack_version & 0x0F00) >> 8, + (stack_version & 0x00F0) >> 4, + stack_version & 0x000F, + protocol_version, + stack_type + ); + + MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEE_STATE)); + XdrvRulesProcess(); + + if (0x08 == protocol_version) { + return 0; // protocol v8 is ok + } else { + return ZIGBEE_LABEL_UNSUPPORTED_VERSION; // abort + } +} + +static bool EZ_reset_config = false; + +// Set or clear reset_config +int32_t EZ_Set_ResetConfig(uint8_t value) { + EZ_reset_config = value ? true : false; + return 0; +} +// checks if we need to reset the configuration of the device +// if reset_config == 0, continue +// if reset_config == 1, goto ZIGBEE_LABEL_CONFIGURE_EZSP +int32_t EZ_GotoIfResetConfig(uint8_t value) { + if (EZ_reset_config) { return ZIGBEE_LABEL_CONFIGURE_EZSP; } + else { return 0; } +} + +#endif // USE_ZIGBEE_EZSP + +// checks the device type (coordinator, router, end-device) +// If coordinator continue +// If router goto ZIGBEE_LABEL_START_ROUTER +// If device goto ZIGBEE_LABEL_START_DEVICE +int32_t Z_SwitchDeviceType(int32_t res, class SBuffer &buf) { + switch (Settings.zb_pan_id) { + case 0xFFFF: return ZIGBEE_LABEL_INIT_ROUTER; + case 0xFFFE: return ZIGBEE_LABEL_INIT_DEVICE; + default: return 0; // continue + } +} // // Helper function, checks if the incoming buffer matches the 2-bytes prefix, i.e. message type in PMEM @@ -162,7 +372,7 @@ bool Z_ReceiveMatchPrefix(const class SBuffer &buf, const uint8_t *match) { // // Handle Permit Join response // -int32_t Z_ReceivePermitJoinStatus(int32_t res, const class SBuffer &buf) { +int32_t ZNP_ReceivePermitJoinStatus(int32_t res, const class SBuffer &buf) { // we received a PermitJoin status change uint8_t duration = buf.get8(2); uint8_t status_code; @@ -189,8 +399,10 @@ int32_t Z_ReceivePermitJoinStatus(int32_t res, const class SBuffer &buf) { return -1; } -const char* Z_DeviceType[] = { "Coordinator", "Router", "End Device", "Unknown" }; -int32_t Z_ReceiveNodeDesc(int32_t res, const class SBuffer &buf) { +// +// ZNP only +// +int32_t ZNP_ReceiveNodeDesc(int32_t res, const class SBuffer &buf) { // Received ZDO_NODE_DESC_RSP Z_ShortAddress srcAddr = buf.get16(2); uint8_t status = buf.get8(4); @@ -205,15 +417,22 @@ int32_t Z_ReceiveNodeDesc(int32_t res, const class SBuffer &buf) { uint16_t maxOutTransferSize = buf.get16(17); uint8_t descriptorCapabilities = buf.get8(19); + if (0 == status) { uint8_t deviceType = logicalType & 0x7; // 0=coordinator, 1=router, 2=end device - if (deviceType > 3) { deviceType = 3; } + const char * deviceTypeStr; + switch (deviceType) { + case 0: deviceTypeStr = PSTR("Coordinator"); break; + case 1: deviceTypeStr = PSTR("Router"); break; + case 2: deviceTypeStr = PSTR("Device"); break; + default: deviceTypeStr = PSTR("Unknown"); break; + } bool complexDescriptorAvailable = (logicalType & 0x08) ? 1 : 0; Response_P(PSTR("{\"" D_JSON_ZIGBEE_STATE "\":{" "\"Status\":%d,\"NodeType\":\"%s\",\"ComplexDesc\":%s}}"), - ZIGBEE_STATUS_NODE_DESC, Z_DeviceType[deviceType], - complexDescriptorAvailable ? "true" : "false" + ZIGBEE_STATUS_NODE_DESC, deviceTypeStr, + complexDescriptorAvailable ? PSTR("true") : PSTR("false") ); MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED)); @@ -228,11 +447,19 @@ int32_t Z_ReceiveNodeDesc(int32_t res, const class SBuffer &buf) { // int32_t Z_ReceiveActiveEp(int32_t res, const class SBuffer &buf) { // Received ZDO_ACTIVE_EP_RSP - Z_ShortAddress srcAddr = buf.get16(2); +#ifdef USE_ZIGBEE_ZNP + // Z_ShortAddress srcAddr = buf.get16(2); uint8_t status = buf.get8(4); Z_ShortAddress nwkAddr = buf.get16(5); uint8_t activeEpCount = buf.get8(7); uint8_t* activeEpList = (uint8_t*) buf.charptr(8); +#endif +#ifdef USE_ZIGBEE_EZSP + uint8_t status = buf.get8(0); + Z_ShortAddress nwkAddr = buf.get16(1); + uint8_t activeEpCount = buf.get8(3); + uint8_t* activeEpList = (uint8_t*) buf.charptr(4); +#endif for (uint32_t i = 0; i < activeEpCount; i++) { zigbee_devices.addEndpoint(nwkAddr, activeEpList[i]); @@ -257,12 +484,22 @@ int32_t Z_ReceiveActiveEp(int32_t res, const class SBuffer &buf) { // // Handle IEEEAddr incoming message // +// Same works for both ZNP and EZSP int32_t Z_ReceiveIEEEAddr(int32_t res, const class SBuffer &buf) { +#ifdef USE_ZIGBEE_ZNP uint8_t status = buf.get8(2); Z_IEEEAddress ieeeAddr = buf.get64(3); Z_ShortAddress nwkAddr = buf.get16(11); // uint8_t startIndex = buf.get8(13); // not used // uint8_t numAssocDev = buf.get8(14); +#endif // USE_ZIGBEE_ZNP +#ifdef USE_ZIGBEE_EZSP + uint8_t status = buf.get8(0); + Z_IEEEAddress ieeeAddr = buf.get64(1); + Z_ShortAddress nwkAddr = buf.get16(9); + // uint8_t numAssocDev = buf.get8(11); + // uint8_t startIndex = buf.get8(12); // not used +#endif // USE_ZIGBEE_EZSP if (0 == status) { // SUCCESS zigbee_devices.updateDevice(nwkAddr, ieeeAddr); @@ -270,15 +507,13 @@ int32_t Z_ReceiveIEEEAddr(int32_t res, const class SBuffer &buf) { Uint64toHex(ieeeAddr, hex, 64); // Ping response const char * friendlyName = zigbee_devices.getFriendlyName(nwkAddr); + + Response_P(PSTR("{\"" D_JSON_ZIGBEE_PING "\":{\"" D_JSON_ZIGBEE_DEVICE "\":\"0x%04X\"" + ",\"" D_JSON_ZIGBEE_IEEE "\":\"0x%s\""), nwkAddr, hex); if (friendlyName) { - Response_P(PSTR("{\"" D_JSON_ZIGBEE_PING "\":{\"" D_JSON_ZIGBEE_DEVICE "\":\"0x%04X\"" - ",\"" D_JSON_ZIGBEE_IEEE "\":\"0x%s\"" - ",\"" D_JSON_ZIGBEE_NAME "\":\"%s\"}}"), nwkAddr, hex, friendlyName); - } else { - Response_P(PSTR("{\"" D_JSON_ZIGBEE_PING "\":{\"" D_JSON_ZIGBEE_DEVICE "\":\"0x%04X\"" - ",\"" D_JSON_ZIGBEE_IEEE "\":\"0x%s\"" - "}}"), nwkAddr, hex); + ResponseAppend_P(PSTR(",\"" D_JSON_ZIGBEE_NAME "\":\"%s\""), friendlyName); } + ResponseAppend_P(PSTR("\"}}")); MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED)); XdrvRulesProcess(); @@ -289,7 +524,7 @@ int32_t Z_ReceiveIEEEAddr(int32_t res, const class SBuffer &buf) { // Report any AF_DATA_CONFIRM message // Ex: {"ZbConfirm":{"Endpoint":1,"Status":0,"StatusMessage":"SUCCESS"}} // -int32_t Z_DataConfirm(int32_t res, const class SBuffer &buf) { +int32_t ZNP_DataConfirm(int32_t res, const class SBuffer &buf) { uint8_t status = buf.get8(2); uint8_t endpoint = buf.get8(3); //uint8_t transId = buf.get8(4); // unused @@ -306,16 +541,85 @@ int32_t Z_DataConfirm(int32_t res, const class SBuffer &buf) { return -1; } +// +// Handle State Change Indication incoming message +// +// Reference: +// 0x00: Initialized - not started automatically +// 0x01: Initialized - not connected to anything +// 0x02: Discovering PAN's to join +// 0x03: Joining a PAN +// 0x04: Rejoining a PAN, only for end devices +// 0x05: Joined but not yet authenticated by trust center +// 0x06: Started as device after authentication +// 0x07: Device joined, authenticated and is a router +// 0x08: Starting as ZigBee Coordinator +// 0x09: Started as ZigBee Coordinator +// 0x0A: Device has lost information about its parent +int32_t ZNP_ReceiveStateChange(int32_t res, const class SBuffer &buf) { + uint8_t state = buf.get8(2); + const char * msg = nullptr; + + switch (state) { + case ZDO_DEV_NWK_DISC: // 0x02 + msg = PSTR("Scanning Zigbee network"); + break; + case ZDO_DEV_NWK_JOINING: // 0x03 + case ZDO_DEV_NWK_REJOIN: // 0x04 + msg = PSTR("Joining a PAN"); + break; + case ZDO_DEV_END_DEVICE_UNAUTH: // 0x05 + msg = PSTR("Joined, not yet authenticated"); + break; + case ZDO_DEV_END_DEVICE: // 0x06 + msg = PSTR("Started as device"); + break; + case ZDO_DEV_ROUTER: // 0x07 + msg = PSTR("Started as router"); + break; + case ZDO_DEV_ZB_COORD: // 0x09 + msg = PSTR("Started as coordinator"); + break; + case ZDO_DEV_NWK_ORPHAN: // 0x0A + msg = PSTR("Device has lost its parent"); + break; + }; + + if (msg) { + Response_P(PSTR("{\"" D_JSON_ZIGBEE_STATE "\":{" + "\"Status\":%d,\"NewState\":%d,\"Message\":\"%s\"}}"), + ZIGBEE_STATUS_SCANNING, state, msg + ); + + MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED)); + XdrvRulesProcess(); + } + + if ((ZDO_DEV_END_DEVICE == state) || (ZDO_DEV_ROUTER == state) || (ZDO_DEV_ZB_COORD == state)) { + return 0; // device sucessfully started + } else { + return -1; // ignore + } +} + // // Handle Receive End Device Announce incoming message // This message is also received when a previously paired device is powered up // Send back Active Ep Req message // int32_t Z_ReceiveEndDeviceAnnonce(int32_t res, const class SBuffer &buf) { - Z_ShortAddress srcAddr = buf.get16(2); +#ifdef USE_ZIGBEE_ZNP + // Z_ShortAddress srcAddr = buf.get16(2); Z_ShortAddress nwkAddr = buf.get16(4); Z_IEEEAddress ieeeAddr = buf.get64(6); uint8_t capabilities = buf.get8(14); +#endif +#ifdef USE_ZIGBEE_EZSP + // uint8_t seq = buf.get8(0); + Z_ShortAddress nwkAddr = buf.get16(0); + Z_IEEEAddress ieeeAddr = buf.get64(2); + uint8_t capabilities = buf.get8(10); +#endif zigbee_devices.updateDevice(nwkAddr, ieeeAddr); @@ -325,9 +629,9 @@ int32_t Z_ReceiveEndDeviceAnnonce(int32_t res, const class SBuffer &buf) { "\"Status\":%d,\"IEEEAddr\":\"0x%s\",\"ShortAddr\":\"0x%04X\"" ",\"PowerSource\":%s,\"ReceiveWhenIdle\":%s,\"Security\":%s}}"), ZIGBEE_STATUS_DEVICE_ANNOUNCE, hex, nwkAddr, - (capabilities & 0x04) ? "true" : "false", - (capabilities & 0x08) ? "true" : "false", - (capabilities & 0x40) ? "true" : "false" + (capabilities & 0x04) ? PSTR("true") : PSTR("false"), + (capabilities & 0x08) ? PSTR("true") : PSTR("false"), + (capabilities & 0x40) ? PSTR("true") : PSTR("false") ); // query the state of the bulb (for Alexa) uint32_t wait_ms = 2000; // wait for 2s @@ -343,7 +647,7 @@ int32_t Z_ReceiveEndDeviceAnnonce(int32_t res, const class SBuffer &buf) { // Handle Receive TC Dev Ind incoming message // 45CA // -int32_t Z_ReceiveTCDevInd(int32_t res, const class SBuffer &buf) { +int32_t ZNP_ReceiveTCDevInd(int32_t res, const class SBuffer &buf) { Z_ShortAddress srcAddr = buf.get16(2); Z_IEEEAddress ieeeAddr = buf.get64(4); Z_ShortAddress parentNw = buf.get16(12); @@ -367,22 +671,27 @@ int32_t Z_ReceiveTCDevInd(int32_t res, const class SBuffer &buf) { // Handle Bind Rsp incoming message // int32_t Z_BindRsp(int32_t res, const class SBuffer &buf) { +#ifdef USE_ZIGBEE_ZNP Z_ShortAddress nwkAddr = buf.get16(2); uint8_t status = buf.get8(4); + String msg = getZigbeeStatusMessage(status); +#endif // USE_ZIGBEE_ZNP +#ifdef USE_ZIGBEE_EZSP + uint8_t status = buf.get8(0); + Z_ShortAddress nwkAddr = buf.get16(buf.len()-2); // last 2 bytes + String msg = getZDPStatusMessage(status); +#endif // USE_ZIGBEE_EZSP const char * friendlyName = zigbee_devices.getFriendlyName(nwkAddr); + + Response_P(PSTR("{\"" D_JSON_ZIGBEE_BIND "\":{\"" D_JSON_ZIGBEE_DEVICE "\":\"0x%04X\""), nwkAddr); if (friendlyName) { - Response_P(PSTR("{\"" D_JSON_ZIGBEE_BIND "\":{\"" D_JSON_ZIGBEE_DEVICE "\":\"0x%04X\"" - ",\"" D_JSON_ZIGBEE_NAME "\":\"%s\"" - ",\"" D_JSON_ZIGBEE_STATUS "\":%d" - ",\"" D_JSON_ZIGBEE_STATUS_MSG "\":\"%s\"" - "}}"), nwkAddr, friendlyName, status, getZigbeeStatusMessage(status).c_str()); - } else { - Response_P(PSTR("{\"" D_JSON_ZIGBEE_BIND "\":{\"" D_JSON_ZIGBEE_DEVICE "\":\"0x%04X\"" - ",\"" D_JSON_ZIGBEE_STATUS "\":%d" - ",\"" D_JSON_ZIGBEE_STATUS_MSG "\":\"%s\"" - "}}"), nwkAddr, status, getZigbeeStatusMessage(status).c_str()); + ResponseAppend_P(PSTR(",\"" D_JSON_ZIGBEE_NAME "\":\"%s\""), friendlyName); } + ResponseAppend_P(PSTR(",\"" D_JSON_ZIGBEE_STATUS "\":%d" + ",\"" D_JSON_ZIGBEE_STATUS_MSG "\":\"%s\"" + "}}"), status, msg.c_str()); + MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED)); XdrvRulesProcess(); @@ -393,22 +702,27 @@ int32_t Z_BindRsp(int32_t res, const class SBuffer &buf) { // Handle Unbind Rsp incoming message // int32_t Z_UnbindRsp(int32_t res, const class SBuffer &buf) { +#ifdef USE_ZIGBEE_ZNP Z_ShortAddress nwkAddr = buf.get16(2); uint8_t status = buf.get8(4); + String msg = getZigbeeStatusMessage(status); +#endif // USE_ZIGBEE_ZNP +#ifdef USE_ZIGBEE_EZSP + uint8_t status = buf.get8(0); + Z_ShortAddress nwkAddr = buf.get16(buf.len()-2); // last 2 bytes + String msg = getZDPStatusMessage(status); +#endif // USE_ZIGBEE_EZSP const char * friendlyName = zigbee_devices.getFriendlyName(nwkAddr); + + Response_P(PSTR("{\"" D_JSON_ZIGBEE_UNBIND "\":{\"" D_JSON_ZIGBEE_DEVICE "\":\"0x%04X\""), nwkAddr); if (friendlyName) { - Response_P(PSTR("{\"" D_JSON_ZIGBEE_UNBIND "\":{\"" D_JSON_ZIGBEE_DEVICE "\":\"0x%04X\"" - ",\"" D_JSON_ZIGBEE_NAME "\":\"%s\"" - ",\"" D_JSON_ZIGBEE_STATUS "\":%d" - ",\"" D_JSON_ZIGBEE_STATUS_MSG "\":\"%s\"" - "}}"), nwkAddr, friendlyName, status, getZigbeeStatusMessage(status).c_str()); - } else { - Response_P(PSTR("{\"" D_JSON_ZIGBEE_UNBIND "\":{\"" D_JSON_ZIGBEE_DEVICE "\":\"0x%04X\"" - ",\"" D_JSON_ZIGBEE_STATUS "\":%d" - ",\"" D_JSON_ZIGBEE_STATUS_MSG "\":\"%s\"" - "}}"), nwkAddr, status, getZigbeeStatusMessage(status).c_str()); + ResponseAppend_P(PSTR(",\"" D_JSON_ZIGBEE_NAME "\":\"%s\""), friendlyName); } + ResponseAppend_P(PSTR(",\"" D_JSON_ZIGBEE_STATUS "\":%d" + ",\"" D_JSON_ZIGBEE_STATUS_MSG "\":\"%s\"" + "}}"), status, msg.c_str()); + MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED)); XdrvRulesProcess(); @@ -418,11 +732,22 @@ int32_t Z_UnbindRsp(int32_t res, const class SBuffer &buf) { // Handle MgMt Bind Rsp incoming message // int32_t Z_MgmtBindRsp(int32_t res, const class SBuffer &buf) { +#ifdef USE_ZIGBEE_ZNP uint16_t shortaddr = buf.get16(2); uint8_t status = buf.get8(4); uint8_t bind_total = buf.get8(5); uint8_t bind_start = buf.get8(6); uint8_t bind_len = buf.get8(7); + const size_t prefix_len = 8; +#endif // USE_ZIGBEE_ZNP +#ifdef USE_ZIGBEE_EZSP + uint16_t shortaddr = buf.get16(buf.len()-2); + uint8_t status = buf.get8(0); + uint8_t bind_total = buf.get8(1); + uint8_t bind_start = buf.get8(2); + uint8_t bind_len = buf.get8(3); + const size_t prefix_len = 4; +#endif // USE_ZIGBEE_EZSP const char * friendlyName = zigbee_devices.getFriendlyName(shortaddr); @@ -433,11 +758,10 @@ int32_t Z_MgmtBindRsp(int32_t res, const class SBuffer &buf) { ResponseAppend_P(PSTR(",\"" D_JSON_ZIGBEE_STATUS "\":%d" ",\"" D_JSON_ZIGBEE_STATUS_MSG "\":\"%s\"" ",\"BindingsTotal\":%d" - //",\"BindingsStart\":%d" ",\"Bindings\":[" ), status, getZigbeeStatusMessage(status).c_str(), bind_total); - uint32_t idx = 8; + uint32_t idx = prefix_len; for (uint32_t i = 0; i < bind_len; i++) { if (idx + 14 > buf.len()) { break; } // overflow, frame size is between 14 and 21 @@ -456,7 +780,7 @@ int32_t Z_MgmtBindRsp(int32_t res, const class SBuffer &buf) { dstep = buf.get8(idx + 20); idx += 21; } else { - //AddLog_P2(LOG_LEVEL_INFO, PSTR("Z_MgmtBindRsp unknwon address mode %d"), addrmode); + //AddLog_P2(LOG_LEVEL_INFO, PSTR("ZNP_MgmtBindRsp unknwon address mode %d"), addrmode); break; // abort for any other value since we don't know the length of the field } @@ -489,18 +813,29 @@ int32_t Z_MgmtBindRsp(int32_t res, const class SBuffer &buf) { // Send ZDO_IEEE_ADDR_REQ request to get IEEE long address // void Z_SendIEEEAddrReq(uint16_t shortaddr) { +#ifdef USE_ZIGBEE_ZNP uint8_t IEEEAddrReq[] = { Z_SREQ | Z_ZDO, ZDO_IEEE_ADDR_REQ, Z_B0(shortaddr), Z_B1(shortaddr), 0x00, 0x00 }; ZigbeeZNPSend(IEEEAddrReq, sizeof(IEEEAddrReq)); +#endif +#ifdef USE_ZIGBEE_EZSP + uint8_t IEEEAddrReq[] = { Z_B0(shortaddr), Z_B1(shortaddr), 0x00, 0x00 }; + EZ_SendZDO(shortaddr, ZDO_IEEE_addr_req, IEEEAddrReq, sizeof(IEEEAddrReq)); +#endif } // // Send ACTIVE_EP_REQ to collect active endpoints for this address // void Z_SendActiveEpReq(uint16_t shortaddr) { +#ifdef USE_ZIGBEE_ZNP uint8_t ActiveEpReq[] = { Z_SREQ | Z_ZDO, ZDO_ACTIVE_EP_REQ, Z_B0(shortaddr), Z_B1(shortaddr), Z_B0(shortaddr), Z_B1(shortaddr) }; - ZigbeeZNPSend(ActiveEpReq, sizeof(ActiveEpReq)); +#endif +#ifdef USE_ZIGBEE_EZSP + uint8_t ActiveEpReq[] = { Z_B0(shortaddr), Z_B1(shortaddr) }; + EZ_SendZDO(shortaddr, ZDO_Active_EP_req, ActiveEpReq, sizeof(ActiveEpReq)); +#endif } // @@ -511,91 +846,100 @@ void Z_SendAFInfoRequest(uint16_t shortaddr) { if (0x00 == endpoint) { endpoint = 0x01; } // if we don't know the endpoint, try 0x01 uint8_t transacid = zigbee_devices.getNextSeqNumber(shortaddr); - uint8_t AFInfoReq[] = { Z_SREQ | Z_AF, AF_DATA_REQUEST, Z_B0(shortaddr), Z_B1(shortaddr), endpoint, - 0x01, 0x00, 0x00, transacid, 0x30, 0x1E, 3 + 2*sizeof(uint16_t), - 0x00, transacid, ZCL_READ_ATTRIBUTES, 0x04, 0x00, 0x05, 0x00 - }; - ZigbeeZNPSend(AFInfoReq, sizeof(AFInfoReq)); + uint8_t InfoReq[] = { 0x04, 0x00, 0x05, 0x00 }; + + ZigbeeZCLSend_Raw(shortaddr, 0x0000 /*group*/, 0x0000 /*cluster*/, endpoint, ZCL_READ_ATTRIBUTES, + false /*clusterSpecific*/, 0x0000 /*manuf*/, + InfoReq, sizeof(InfoReq), true /*needResponse*/, transacid); } -/*********************************************************************************************\ - * Callbacks -\*********************************************************************************************/ +// +// Handle trustCenterJoinHandler +// 2400 +// +#ifdef USE_ZIGBEE_EZSP +int32_t EZ_ReceiveTCJoinHandler(int32_t res, const class SBuffer &buf) { + uint16_t srcAddr = buf.get16(2); + uint64_t ieeeAddr = buf.get64(4); + uint8_t status = buf.get8(12); + uint8_t decision = buf.get8(13); + uint16_t parentNw = buf.get16(14); + if (EMBER_DEVICE_LEFT != status) { // ignore message if the device is leaving + zigbee_devices.updateDevice(srcAddr, ieeeAddr); -// Aqara Occupancy behavior: the Aqara device only sends Occupancy: true events every 60 seconds. -// Here we add a timer so if we don't receive a Occupancy event for 90 seconds, we send Occupancy:false -void Z_AqaraOccupancy(uint16_t shortaddr, uint16_t cluster, uint8_t endpoint, const JsonObject &json) { - static const uint32_t OCCUPANCY_TIMEOUT = 90 * 1000; // 90 s - // Read OCCUPANCY value if any - const JsonVariant &val_endpoint = getCaseInsensitive(json, PSTR(OCCUPANCY)); - if (nullptr != &val_endpoint) { - uint32_t occupancy = strToUInt(val_endpoint); + char hex[20]; + Uint64toHex(ieeeAddr, hex, 64); + Response_P(PSTR("{\"" D_JSON_ZIGBEE_STATE "\":{" + "\"Status\":%d,\"IEEEAddr\":\"0x%s\",\"ShortAddr\":\"0x%04X\"" + ",\"ParentNetwork\":\"0x%04X\"" + ",\"Status\":%d,\"Decision\":%d" + "}}"), + ZIGBEE_STATUS_DEVICE_INDICATION, hex, srcAddr, parentNw, + status, decision + ); - if (occupancy) { - zigbee_devices.setTimer(shortaddr, 0 /* groupaddr */, OCCUPANCY_TIMEOUT, cluster, endpoint, Z_CAT_VIRTUAL_ATTR, 0, &Z_OccupancyCallback); - } + MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED)); + XdrvRulesProcess(); } + return -1; } +#endif // USE_ZIGBEE_EZSP - -// Publish the received values once they have been coalesced -int32_t Z_PublishAttributes(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint32_t value) { - const JsonObject *json = zigbee_devices.jsonGet(shortaddr); - if (json == nullptr) { return 0; } // don't crash if not found - - zigbee_devices.jsonPublishFlush(shortaddr); - return 1; -} - -/*********************************************************************************************\ - * Global dispatcher for incoming messages -\*********************************************************************************************/ - -int32_t Z_ReceiveAfIncomingMessage(int32_t res, const class SBuffer &buf) { - uint16_t groupid = buf.get16(2); - uint16_t clusterid = buf.get16(4); - Z_ShortAddress srcaddr = buf.get16(6); - uint8_t srcendpoint = buf.get8(8); - uint8_t dstendpoint = buf.get8(9); - uint8_t wasbroadcast = buf.get8(10); - uint8_t linkquality = buf.get8(11); - uint8_t securityuse = buf.get8(12); - uint32_t timestamp = buf.get32(13); - uint8_t seqnumber = buf.get8(17); +// +// Parse incoming ZCL message. +// +// This code is common to ZNP and EZSP +void Z_IncomingMessage(ZCLFrame &zcl_received) { + uint16_t srcaddr = zcl_received.getSrcAddr(); + uint16_t groupid = zcl_received.getGroupAddr(); + uint16_t clusterid = zcl_received.getClusterId(); + uint8_t linkquality = zcl_received.getLinkQuality(); + uint8_t srcendpoint = zcl_received.getSrcEndpoint(); bool defer_attributes = false; // do we defer attributes reporting to coalesce - ZCLFrame zcl_received = ZCLFrame::parseRawFrame(buf, 19, buf.get8(18), clusterid, groupid, - srcaddr, - srcendpoint, dstendpoint, wasbroadcast, - linkquality, securityuse, seqnumber, - timestamp); + // log the packet details zcl_received.log(); + + zigbee_devices.setLQI(srcaddr, linkquality != 0xFF ? linkquality : 0xFE); // EFR32 has a different scale for LQI + char shortaddr[8]; snprintf_P(shortaddr, sizeof(shortaddr), PSTR("0x%04X"), srcaddr); DynamicJsonBuffer jsonBuffer; JsonObject& json = jsonBuffer.createObject(); - + if ( (!zcl_received.isClusterSpecificCommand()) && (ZCL_DEFAULT_RESPONSE == zcl_received.getCmdId())) { - zcl_received.parseResponse(); - } else { + zcl_received.parseResponse(); // Zigbee general "Degault Response", publish ZbResponse message + } else { // Build the ZbReceive json if ( (!zcl_received.isClusterSpecificCommand()) && (ZCL_REPORT_ATTRIBUTES == zcl_received.getCmdId())) { - zcl_received.parseRawAttributes(json); + zcl_received.parseReportAttributes(json); // Zigbee report attributes from sensors if (clusterid) { defer_attributes = true; } // don't defer system Cluster=0 messages } else if ( (!zcl_received.isClusterSpecificCommand()) && (ZCL_READ_ATTRIBUTES_RESPONSE == zcl_received.getCmdId())) { - zcl_received.parseReadAttributes(json); + zcl_received.parseReadAttributesResponse(json); if (clusterid) { defer_attributes = true; } // don't defer system Cluster=0 messages + } else if ( (!zcl_received.isClusterSpecificCommand()) && (ZCL_READ_ATTRIBUTES == zcl_received.getCmdId())) { + zcl_received.parseReadAttributes(json); + // never defer read_attributes, so the auto-responder can send response back on a per cluster basis } else if (zcl_received.isClusterSpecificCommand()) { zcl_received.parseClusterSpecificCommand(json); } - String msg(""); - msg.reserve(100); - json.printTo(msg); - AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE D_JSON_ZIGBEEZCL_RAW_RECEIVED ": {\"0x%04X\":%s}"), srcaddr, msg.c_str()); + + { // fence to force early de-allocation of msg + String msg(""); + msg.reserve(100); + json.printTo(msg); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE D_JSON_ZIGBEEZCL_RAW_RECEIVED ": {\"0x%04X\":%s}"), srcaddr, msg.c_str()); + } + + // discard the message if it was sent by us (broadcast or group loopback) + if (srcaddr == localShortAddr) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE "loopback message, ignoring")); + return; // abort the rest of message management + } zcl_received.postProcessAttributes(srcaddr, json); // Add Endpoint @@ -625,56 +969,274 @@ int32_t Z_ReceiveAfIncomingMessage(int32_t res, const class SBuffer &buf) { } else { // Publish immediately zigbee_devices.jsonPublishNow(srcaddr, json); + + // Add auto-responder here + Z_AutoResponder(srcaddr, clusterid, srcendpoint, json[F("ReadNames")]); } } +} + + +#ifdef USE_ZIGBEE_EZSP + +/*********************************************************************************************\ + * Send ZDO Message +\*********************************************************************************************/ + +void EZ_SendZDO(uint16_t shortaddr, uint16_t cmd, const unsigned char *payload, size_t payload_len) { + SBuffer buf(payload_len + 22); + uint8_t seq = zigbee_devices.getNextSeqNumber(0x0000); + + buf.add16(EZSP_sendUnicast); + + buf.add8(EMBER_OUTGOING_DIRECT); // 00 + buf.add16(shortaddr); // dest addr + // ApsFrame + buf.add16(0x0000); // ZOD profile + buf.add16(cmd); // ZDO cmd in cluster + buf.add8(0); // srcEp + buf.add8(0); // dstEp + buf.add16(EMBER_APS_OPTION_ENABLE_ROUTE_DISCOVERY | EMBER_APS_OPTION_RETRY); // APS frame + buf.add16(0x0000); // groupId + buf.add8(seq); + // end of ApsFrame + buf.add8(0x01); // tag TODO + buf.add8(payload_len + 1); // insert seq number + buf.add8(seq); + buf.addBuffer(payload, payload_len); + + ZigbeeEZSPSendCmd(buf.buf(), buf.len(), true); +} + +/*********************************************************************************************\ + * Send specific EZSP messages +\*********************************************************************************************/ + +int32_t EZ_IncomingMessage(int32_t res, const class SBuffer &buf) { + uint8_t msgtype = buf.get8(2); // see EZSP_EmberIncomingMessageType + bool wasbroadcast = (msgtype >= EMBER_INCOMING_MULTICAST) && (msgtype <= EMBER_INCOMING_BROADCAST_LOOPBACK); + uint16_t profileid = buf.get16(3); // HA = 0x0104, ZDO = 0x0000 + uint16_t clusterid = buf.get16(5); + uint8_t srcendpoint = buf.get8(7); + uint8_t dstendpoint = buf.get8(8); + uint16_t apsoptions = buf.get16(9); // see EZSP_EmberApsOption, usually EMBER_APS_OPTION_ENABLE_ADDRESS_DISCOVERY + bool securityuse = (apsoptions & EMBER_APS_OPTION_ENCRYPTION) ? true : false; + uint16_t groupid = buf.get16(11); + uint8_t seqnumber = buf.get8(13); + uint8_t linkquality = buf.get8(14); + // uint8_t linkrsssi = buf.get8(15); // probably not used as there is no equivalent in Z-Stack + uint16_t srcaddr = buf.get16(16); + // uint8_t bindingindex = buf.get8(18); // not sure we need this one as a coordinator + // uint8_t addressindex = buf.get8(19); // not sure how to handle this one + // offset 20 is len, and buffer starts at offset 21 + + + if ((0x0000 == profileid) && (0x00 == srcendpoint)) { + // ZDO request + // Since ZDO messages start with a sequence number, we skip it + // but we add the source address in the last 2 bytes + SBuffer zdo_buf(buf.get8(20) - 1 + 2); + zdo_buf.addBuffer(buf.buf(22), buf.get8(20) - 1); + zdo_buf.add16(srcaddr); + switch (clusterid) { + case ZDO_Device_annce: + return Z_ReceiveEndDeviceAnnonce(res, zdo_buf); + case ZDO_Active_EP_rsp: + return Z_ReceiveActiveEp(res, zdo_buf); + case ZDO_IEEE_addr_rsp: + return Z_ReceiveIEEEAddr(res, zdo_buf); + case ZDO_Bind_rsp: + return Z_BindRsp(res, zdo_buf); + case ZDO_Unbind_rsp: + return Z_UnbindRsp(res, zdo_buf); + case ZDO_Mgmt_Bind_rsp: + return Z_MgmtBindRsp(res, zdo_buf); + } + } else { + bool defer_attributes = false; // do we defer attributes reporting to coalesce + ZCLFrame zcl_received = ZCLFrame::parseRawFrame(buf, 21, buf.get8(20), clusterid, groupid, + srcaddr, + srcendpoint, dstendpoint, wasbroadcast, + linkquality, securityuse, seqnumber); + // + Z_IncomingMessage(zcl_received); + } return -1; } +// +// Callback for loading Zigbee configuration from Flash, called by the state machine +// +// value = 0 : drive reset pin and halt MCU +// value = 1 : release the reset pin, restart +int32_t EZ_Reset_Device(uint8_t value) { + // we use Led4i to drive the reset pin. Since it is reverted we need to pass 1 to start reset, and 0 to release reset + if (PinUsed(GPIO_LED1, ZIGBEE_EZSP_RESET_LED - 1)) { + SetLedPowerIdx(ZIGBEE_EZSP_RESET_LED - 1, value ? 0 : 1); + } else { + // no GPIO so we use software Reset instead + if (value) { // send reset only when we are supposed to release reset + uint8_t ezsp_reset[1] = { 0xC0 }; // EZSP ASH Reset + ZigbeeEZSPSendRaw(ezsp_reset, sizeof(ezsp_reset), true); + } + } + return 0; // continue +} + +/*********************************************************************************************\ + * Default resolver +\*********************************************************************************************/ + +int32_t EZ_Recv_Default(int32_t res, const class SBuffer &buf) { + // Default message handler for new messages + if (zigbee.init_phase) { + // if still during initialization phase, ignore any unexpected message + return -1; // ignore message + } else { + uint16_t ezsp_command_index = buf.get16(0); + + switch (ezsp_command_index) { + case EZSP_incomingMessageHandler: + return EZ_IncomingMessage(res, buf); + break; + case EZSP_trustCenterJoinHandler: + return EZ_ReceiveTCJoinHandler(res, buf); + break; + } + return -1; + } +} + +#endif // USE_ZIGBEE_EZSP + +/*********************************************************************************************\ + * Callbacks +\*********************************************************************************************/ + + +// Aqara Occupancy behavior: the Aqara device only sends Occupancy: true events every 60 seconds. +// Here we add a timer so if we don't receive a Occupancy event for 90 seconds, we send Occupancy:false +void Z_AqaraOccupancy(uint16_t shortaddr, uint16_t cluster, uint8_t endpoint, const JsonObject &json) { + static const uint32_t OCCUPANCY_TIMEOUT = 90 * 1000; // 90 s + // Read OCCUPANCY value if any + const JsonVariant &val_endpoint = GetCaseInsensitive(json, PSTR(OCCUPANCY)); + if (nullptr != &val_endpoint) { + uint32_t occupancy = strToUInt(val_endpoint); + + if (occupancy) { + zigbee_devices.setTimer(shortaddr, 0 /* groupaddr */, OCCUPANCY_TIMEOUT, cluster, endpoint, Z_CAT_VIRTUAL_OCCUPANCY, 0, &Z_OccupancyCallback); + } else { + zigbee_devices.resetTimersForDevice(shortaddr, 0 /* groupaddr */, Z_CAT_VIRTUAL_OCCUPANCY); + } + } +} + + +// Publish the received values once they have been coalesced +int32_t Z_PublishAttributes(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint32_t value) { + const JsonObject *json = zigbee_devices.jsonGet(shortaddr); + if (json == nullptr) { return 0; } // don't crash if not found + + zigbee_devices.jsonPublishFlush(shortaddr); + return 1; +} + +/*********************************************************************************************\ + * Global dispatcher for incoming messages +\*********************************************************************************************/ + +#ifdef USE_ZIGBEE_ZNP + +int32_t ZNP_ReceiveAfIncomingMessage(int32_t res, const class SBuffer &buf) { + uint16_t groupid = buf.get16(2); + uint16_t clusterid = buf.get16(4); + uint16_t srcaddr = buf.get16(6); + uint8_t srcendpoint = buf.get8(8); + uint8_t dstendpoint = buf.get8(9); + uint8_t wasbroadcast = buf.get8(10); + uint8_t linkquality = buf.get8(11); + uint8_t securityuse = buf.get8(12); + // uint32_t timestamp = buf.get32(13); + uint8_t seqnumber = buf.get8(17); + + bool defer_attributes = false; // do we defer attributes reporting to coalesce + + ZCLFrame zcl_received = ZCLFrame::parseRawFrame(buf, 19, buf.get8(18), clusterid, groupid, + srcaddr, + srcendpoint, dstendpoint, wasbroadcast, + linkquality, securityuse, seqnumber); + // + Z_IncomingMessage(zcl_received); + + return -1; +} + +#endif // USE_ZIGBEE_ZNP + + +/*********************************************************************************************\ + * Global dispatcher for incoming messages +\*********************************************************************************************/ + +int32_t Z_ReceiveAfIncomingMessage(int32_t res, const class SBuffer &buf) { + uint16_t groupid = buf.get16(2); + uint16_t clusterid = buf.get16(4); + uint16_t srcaddr = buf.get16(6); + uint8_t srcendpoint = buf.get8(8); + uint8_t dstendpoint = buf.get8(9); + uint8_t wasbroadcast = buf.get8(10); + uint8_t linkquality = buf.get8(11); + uint8_t securityuse = buf.get8(12); + // uint32_t timestamp = buf.get32(13); + uint8_t seqnumber = buf.get8(17); + + bool defer_attributes = false; // do we defer attributes reporting to coalesce + + ZCLFrame zcl_received = ZCLFrame::parseRawFrame(buf, 19, buf.get8(18), clusterid, groupid, + srcaddr, + srcendpoint, dstendpoint, wasbroadcast, + linkquality, securityuse, seqnumber); + // + Z_IncomingMessage(zcl_received); + + return -1; +} + +#ifdef USE_ZIGBEE_ZNP + // Structure for the Dispatcher callbacks table typedef struct Z_Dispatcher { - const uint8_t* match; + uint8_t match[2]; ZB_RecvMsgFunc func; } Z_Dispatcher; -// Ffilters based on ZNP frames -ZBM(AREQ_AF_DATA_CONFIRM, Z_AREQ | Z_AF, AF_DATA_CONFIRM) // 4480 -ZBM(AREQ_AF_INCOMING_MESSAGE, Z_AREQ | Z_AF, AF_INCOMING_MSG) // 4481 -ZBM(AREQ_END_DEVICE_ANNCE_IND, Z_AREQ | Z_ZDO, ZDO_END_DEVICE_ANNCE_IND) // 45C1 -ZBM(AREQ_END_DEVICE_TC_DEV_IND, Z_AREQ | Z_ZDO, ZDO_TC_DEV_IND) // 45CA -ZBM(AREQ_PERMITJOIN_OPEN_XX, Z_AREQ | Z_ZDO, ZDO_PERMIT_JOIN_IND ) // 45CB -ZBM(AREQ_ZDO_ACTIVEEPRSP, Z_AREQ | Z_ZDO, ZDO_ACTIVE_EP_RSP) // 4585 -ZBM(AREQ_ZDO_SIMPLEDESCRSP, Z_AREQ | Z_ZDO, ZDO_SIMPLE_DESC_RSP) // 4584 -ZBM(AREQ_ZDO_IEEE_ADDR_RSP, Z_AREQ | Z_ZDO, ZDO_IEEE_ADDR_RSP) // 4581 -ZBM(AREQ_ZDO_BIND_RSP, Z_AREQ | Z_ZDO, ZDO_BIND_RSP) // 45A1 -ZBM(AREQ_ZDO_UNBIND_RSP, Z_AREQ | Z_ZDO, ZDO_UNBIND_RSP) // 45A2 -ZBM(AREQ_ZDO_MGMT_BIND_RSP, Z_AREQ | Z_ZDO, ZDO_MGMT_BIND_RSP) // 45B3 - // Dispatcher callbacks table const Z_Dispatcher Z_DispatchTable[] PROGMEM = { - { AREQ_AF_DATA_CONFIRM, &Z_DataConfirm }, - { AREQ_AF_INCOMING_MESSAGE, &Z_ReceiveAfIncomingMessage }, - { AREQ_END_DEVICE_ANNCE_IND, &Z_ReceiveEndDeviceAnnonce }, - { AREQ_END_DEVICE_TC_DEV_IND, &Z_ReceiveTCDevInd }, - { AREQ_PERMITJOIN_OPEN_XX, &Z_ReceivePermitJoinStatus }, - { AREQ_ZDO_NODEDESCRSP, &Z_ReceiveNodeDesc }, - { AREQ_ZDO_ACTIVEEPRSP, &Z_ReceiveActiveEp }, - { AREQ_ZDO_IEEE_ADDR_RSP, &Z_ReceiveIEEEAddr }, - { AREQ_ZDO_BIND_RSP, &Z_BindRsp }, - { AREQ_ZDO_UNBIND_RSP, &Z_UnbindRsp }, - { AREQ_ZDO_MGMT_BIND_RSP, &Z_MgmtBindRsp }, + { { Z_AREQ | Z_AF, AF_DATA_CONFIRM }, &ZNP_DataConfirm }, // 4480 + { { Z_AREQ | Z_AF, AF_INCOMING_MSG }, &ZNP_ReceiveAfIncomingMessage }, // 4481 + // { { Z_AREQ | Z_ZDO, ZDO_STATE_CHANGE_IND }, &ZNP_ReceiveStateChange }, // 45C0 + { { Z_AREQ | Z_ZDO, ZDO_END_DEVICE_ANNCE_IND }, &Z_ReceiveEndDeviceAnnonce }, // 45C1 + { { Z_AREQ | Z_ZDO, ZDO_TC_DEV_IND }, &ZNP_ReceiveTCDevInd }, // 45CA + { { Z_AREQ | Z_ZDO, ZDO_PERMIT_JOIN_IND }, &ZNP_ReceivePermitJoinStatus }, // 45CB + { { Z_AREQ | Z_ZDO, ZDO_NODE_DESC_RSP }, &ZNP_ReceiveNodeDesc }, // 4582 + { { Z_AREQ | Z_ZDO, ZDO_ACTIVE_EP_RSP }, &Z_ReceiveActiveEp }, // 4585 + { { Z_AREQ | Z_ZDO, ZDO_IEEE_ADDR_RSP }, &Z_ReceiveIEEEAddr }, // 4581 + { { Z_AREQ | Z_ZDO, ZDO_BIND_RSP }, &Z_BindRsp }, // 45A1 + { { Z_AREQ | Z_ZDO, ZDO_UNBIND_RSP }, &Z_UnbindRsp }, // 45A2 + { { Z_AREQ | Z_ZDO, ZDO_MGMT_BIND_RSP }, &Z_MgmtBindRsp }, // 45B3 }; /*********************************************************************************************\ * Default resolver \*********************************************************************************************/ -int32_t Z_Recv_Default(int32_t res, const class SBuffer &buf) { +int32_t ZNP_Recv_Default(int32_t res, const class SBuffer &buf) { // Default message handler for new messages if (zigbee.init_phase) { // if still during initialization phase, ignore any unexpected message return -1; // ignore message } else { - for (uint32_t i = 0; i < sizeof(Z_DispatchTable)/sizeof(Z_Dispatcher); i++) { + for (uint32_t i = 0; i < ARRAY_SIZE(Z_DispatchTable); i++) { if (Z_ReceiveMatchPrefix(buf, Z_DispatchTable[i].match)) { (*Z_DispatchTable[i].func)(res, buf); } @@ -683,6 +1245,8 @@ int32_t Z_Recv_Default(int32_t res, const class SBuffer &buf) { } } +#endif // USE_ZIGBEE_ZNP + /*********************************************************************************************\ * Functions called by State Machine \*********************************************************************************************/ @@ -739,4 +1303,75 @@ int32_t Z_State_Ready(uint8_t value) { return 0; // continue } +// +// Auto-responder for Read request from extenal devices. +// +// Mostly used for routers/end-devices +// json: holds the attributes in JSON format +void Z_AutoResponder(uint16_t srcaddr, uint16_t cluster, uint8_t endpoint, const JsonObject &json) { + DynamicJsonBuffer jsonBuffer; + JsonObject& json_out = jsonBuffer.createObject(); + + // responder + switch (cluster) { + case 0x0000: + if (HasKeyCaseInsensitive(json, PSTR("ModelId"))) { json_out[F("ModelId")] = F(USE_ZIGBEE_MODELID); } + if (HasKeyCaseInsensitive(json, PSTR("Manufacturer"))) { json_out[F("Manufacturer")] = F(USE_ZIGBEE_MANUFACTURER); } + break; +#ifdef USE_LIGHT + case 0x0006: + if (HasKeyCaseInsensitive(json, PSTR("Power"))) { json_out[F("Power")] = Light.power ? 1 : 0; } + break; + case 0x0008: + if (HasKeyCaseInsensitive(json, PSTR("Dimmer"))) { json_out[F("Dimmer")] = LightGetDimmer(0); } + break; + case 0x0300: + { + uint16_t hue; + uint8_t sat; + float XY[2]; + LightGetHSB(&hue, &sat, nullptr); + LightGetXY(&XY[0], &XY[1]); + uint16_t uxy[2]; + for (uint32_t i = 0; i < ARRAY_SIZE(XY); i++) { + uxy[i] = XY[i] * 65536.0f; + uxy[i] = (uxy[i] > 0xFEFF) ? uxy[i] : 0xFEFF; + } + if (HasKeyCaseInsensitive(json, PSTR("Hue"))) { json_out[F("Hue")] = changeUIntScale(hue, 0, 360, 0, 254); } + if (HasKeyCaseInsensitive(json, PSTR("Sat"))) { json_out[F("Sat")] = changeUIntScale(sat, 0, 255, 0, 254); } + if (HasKeyCaseInsensitive(json, PSTR("CT"))) { json_out[F("CT")] = LightGetColorTemp(); } + if (HasKeyCaseInsensitive(json, PSTR("X"))) { json_out[F("X")] = uxy[0]; } + if (HasKeyCaseInsensitive(json, PSTR("Y"))) { json_out[F("Y")] = uxy[1]; } + } + break; +#endif + case 0x000A: // Time + if (HasKeyCaseInsensitive(json, PSTR("Time"))) { json_out[F("Time")] = (Rtc.utc_time > (60 * 60 * 24 * 365 * 10)) ? Rtc.utc_time - 946684800 : Rtc.utc_time; } + if (HasKeyCaseInsensitive(json, PSTR("TimeEpoch"))) { json_out[F("TimeEpoch")] = Rtc.utc_time; } + if (HasKeyCaseInsensitive(json, PSTR("TimeStatus"))) { json_out[F("TimeStatus")] = (Rtc.utc_time > (60 * 60 * 24 * 365 * 10)) ? 0x02 : 0x00; } // if time is beyond 2010 then we are synchronized + if (HasKeyCaseInsensitive(json, PSTR("TimeZone"))) { json_out[F("TimeZone")] = Settings.toffset[0] * 60; } // seconds + break; + } + + if (json_out.size() > 0) { + // we have a non-empty output + + // log first + String msg(""); + msg.reserve(100); + json_out.printTo(msg); + AddLog_P2(LOG_LEVEL_INFO, PSTR("ZIG: Auto-responder: ZbSend {\"Device\":\"0x%04X\"" + ",\"Cluster\":\"0x%04X\"" + ",\"Endpoint\":%d" + ",\"Response\":%s}" + ), + srcaddr, cluster, endpoint, + msg.c_str()); + + // send + const JsonVariant &json_out_v = json_out; + ZbSendReportWrite(json_out_v, srcaddr, 0 /* group */,cluster, endpoint, 0 /* manuf */, ZCL_READ_ATTRIBUTES_RESPONSE); + } +} + #endif // USE_ZIGBEE diff --git a/tasmota/xdrv_23_zigbee_9_impl.ino b/tasmota/xdrv_23_zigbee_9_impl.ino deleted file mode 100644 index 163580255..000000000 --- a/tasmota/xdrv_23_zigbee_9_impl.ino +++ /dev/null @@ -1,1042 +0,0 @@ -/* - xdrv_23_zigbee.ino - zigbee support for Tasmota - - Copyright (C) 2020 Theo Arends and Stephan Hadinger - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#ifdef USE_ZIGBEE - -#define XDRV_23 23 - -const uint32_t ZIGBEE_BUFFER_SIZE = 256; // Max ZNP frame is SOF+LEN+CMD1+CMD2+250+FCS = 255 -const uint8_t ZIGBEE_SOF = 0xFE; -const uint8_t ZIGBEE_SOF_ALT = 0xFF; - -#include -TasmotaSerial *ZigbeeSerial = nullptr; - - -const char kZbCommands[] PROGMEM = D_PRFX_ZB "|" // prefix - D_CMND_ZIGBEEZNPSEND "|" D_CMND_ZIGBEE_PERMITJOIN "|" - D_CMND_ZIGBEE_STATUS "|" D_CMND_ZIGBEE_RESET "|" D_CMND_ZIGBEE_SEND "|" - D_CMND_ZIGBEE_PROBE "|" D_CMND_ZIGBEE_READ "|" D_CMND_ZIGBEEZNPRECEIVE "|" - D_CMND_ZIGBEE_FORGET "|" D_CMND_ZIGBEE_SAVE "|" D_CMND_ZIGBEE_NAME "|" - D_CMND_ZIGBEE_BIND "|" D_CMND_ZIGBEE_UNBIND "|" D_CMND_ZIGBEE_PING "|" D_CMND_ZIGBEE_MODELID "|" - D_CMND_ZIGBEE_LIGHT "|" D_CMND_ZIGBEE_RESTORE "|" D_CMND_ZIGBEE_BIND_STATE - ; - -void (* const ZigbeeCommand[])(void) PROGMEM = { - &CmndZbZNPSend, &CmndZbPermitJoin, - &CmndZbStatus, &CmndZbReset, &CmndZbSend, - &CmndZbProbe, &CmndZbRead, &CmndZbZNPReceive, - &CmndZbForget, &CmndZbSave, &CmndZbName, - &CmndZbBind, &CmndZbUnbind, &CmndZbPing, &CmndZbModelId, - &CmndZbLight, &CmndZbRestore, &CmndZbBindState, - }; - -// -// Called at event loop, checks for incoming data from the CC2530 -// -void ZigbeeInputLoop(void) -{ - static uint32_t zigbee_polling_window = 0; - static uint8_t fcs = ZIGBEE_SOF; - static uint32_t zigbee_frame_len = 5; // minimal zigbee frame lenght, will be updated when buf[1] is read - // Receive only valid ZNP frames: - // 00 - SOF = 0xFE - // 01 - Length of Data Field - 0..250 - // 02 - CMD1 - first byte of command - // 03 - CMD2 - second byte of command - // 04..FD - Data Field - // FE (or last) - FCS Checksum - - while (ZigbeeSerial->available()) { - yield(); - uint8_t zigbee_in_byte = ZigbeeSerial->read(); - //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZbInput byte=%d len=%d"), zigbee_in_byte, zigbee_buffer->len()); - - if (0 == zigbee_buffer->len()) { // make sure all variables are correctly initialized - zigbee_frame_len = 5; - fcs = ZIGBEE_SOF; - // there is a rare race condition when an interrupt occurs when receiving the first byte - // in this case the first bit (lsb) is missed and Tasmota receives 0xFF instead of 0xFE - // We forgive this mistake, and next bytes are automatically resynchronized - if (ZIGBEE_SOF_ALT == zigbee_in_byte) { - AddLog_P2(LOG_LEVEL_INFO, PSTR("ZbInput forgiven first byte %02X (only for statistics)"), zigbee_in_byte); - zigbee_in_byte = ZIGBEE_SOF; - } - } - - if ((0 == zigbee_buffer->len()) && (ZIGBEE_SOF != zigbee_in_byte)) { - // waiting for SOF (Start Of Frame) byte, discard anything else - AddLog_P2(LOG_LEVEL_INFO, PSTR("ZbInput discarding byte %02X"), zigbee_in_byte); - continue; // discard - } - - if (zigbee_buffer->len() < zigbee_frame_len) { - zigbee_buffer->add8(zigbee_in_byte); - zigbee_polling_window = millis(); // Wait for more data - fcs ^= zigbee_in_byte; - } - - if (zigbee_buffer->len() >= zigbee_frame_len) { - zigbee_polling_window = 0; // Publish now - break; - } - - // recalculate frame length - if (02 == zigbee_buffer->len()) { - // We just received the Lenght byte - uint8_t len_byte = zigbee_buffer->get8(1); - if (len_byte > 250) len_byte = 250; // ZNP spec says len is 250 max - - zigbee_frame_len = len_byte + 5; // SOF + LEN + CMD1 + CMD2 + FCS = 5 bytes overhead - } - } - - if (zigbee_buffer->len() && (millis() > (zigbee_polling_window + ZIGBEE_POLLING))) { - char hex_char[(zigbee_buffer->len() * 2) + 2]; - ToHex_P((unsigned char*)zigbee_buffer->getBuffer(), zigbee_buffer->len(), hex_char, sizeof(hex_char)); - - AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_ZIGBEE "Bytes follow_read_metric = %0d"), ZigbeeSerial->getLoopReadMetric()); - // buffer received, now check integrity - if (zigbee_buffer->len() != zigbee_frame_len) { - // Len is not correct, log and reject frame - AddLog_P2(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEEZNPRECEIVED ": received frame of wrong size %s, len %d, expected %d"), hex_char, zigbee_buffer->len(), zigbee_frame_len); - } else if (0x00 != fcs) { - // FCS is wrong, packet is corrupt, log and reject frame - AddLog_P2(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEEZNPRECEIVED ": received bad FCS frame %s, %d"), hex_char, fcs); - } else { - // frame is correct - //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR(D_JSON_ZIGBEEZNPRECEIVED ": received correct frame %s"), hex_char); - - SBuffer znp_buffer = zigbee_buffer->subBuffer(2, zigbee_frame_len - 3); // remove SOF, LEN and FCS - - ToHex_P((unsigned char*)znp_buffer.getBuffer(), znp_buffer.len(), hex_char, sizeof(hex_char)); - Response_P(PSTR("{\"" D_JSON_ZIGBEEZNPRECEIVED "\":\"%s\"}"), hex_char); - if (Settings.flag3.tuya_serial_mqtt_publish) { - MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR)); - XdrvRulesProcess(); - } else { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE "%s"), mqtt_data); - } - // now process the message - ZigbeeProcessInput(znp_buffer); - } - zigbee_buffer->setLen(0); // empty buffer - } -} - -/********************************************************************************************/ - -// Initialize internal structures -void ZigbeeInit(void) -{ -// AddLog_P2(LOG_LEVEL_INFO, PSTR("ZigbeeInit Mem1 = %d"), ESP.getFreeHeap()); - zigbee.active = false; - if ((pin[GPIO_ZIGBEE_RX] < 99) && (pin[GPIO_ZIGBEE_TX] < 99)) { - AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_ZIGBEE "GPIOs Rx:%d Tx:%d"), pin[GPIO_ZIGBEE_RX], pin[GPIO_ZIGBEE_TX]); - // if seriallog_level is 0, we allow GPIO 13/15 to switch to Hardware Serial - ZigbeeSerial = new TasmotaSerial(pin[GPIO_ZIGBEE_RX], pin[GPIO_ZIGBEE_TX], seriallog_level ? 1 : 2, 0, 256); // set a receive buffer of 256 bytes - ZigbeeSerial->begin(115200); - if (ZigbeeSerial->hardwareSerial()) { - ClaimSerial(); - uint32_t aligned_buffer = ((uint32_t)serial_in_buffer + 3) & ~3; - zigbee_buffer = new PreAllocatedSBuffer(sizeof(serial_in_buffer) - 3, (char*) aligned_buffer); - } else { -// AddLog_P2(LOG_LEVEL_INFO, PSTR("ZigbeeInit Mem2 = %d"), ESP.getFreeHeap()); - zigbee_buffer = new SBuffer(ZIGBEE_BUFFER_SIZE); -// AddLog_P2(LOG_LEVEL_INFO, PSTR("ZigbeeInit Mem3 = %d"), ESP.getFreeHeap()); - } - zigbee.active = true; - zigbee.init_phase = true; // start the state machine - zigbee.state_machine = true; // start the state machine - ZigbeeSerial->flush(); - } -// AddLog_P2(LOG_LEVEL_INFO, PSTR("ZigbeeInit Mem9 = %d"), ESP.getFreeHeap()); -} - -/*********************************************************************************************\ - * Commands -\*********************************************************************************************/ - -uint32_t strToUInt(const JsonVariant &val) { - // if the string starts with 0x, it is considered Hex, otherwise it is an int - if (val.is()) { - return val.as(); - } else { - if (val.is()) { - String sval = val.as(); - return strtoull(sval.c_str(), nullptr, 0); - } - } - return 0; // couldn't parse anything -} - -// Do a factory reset of the CC2530 -const unsigned char ZIGBEE_FACTORY_RESET[] PROGMEM = - { Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_STARTUP_OPTION, 0x01 /* len */, 0x01 /* STARTOPT_CLEAR_CONFIG */}; -//"2605030101"; // Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_STARTUP_OPTION, 0x01 len, 0x01 STARTOPT_CLEAR_CONFIG -void CmndZbReset(void) { - if (ZigbeeSerial) { - switch (XdrvMailbox.payload) { - case 1: - ZigbeeZNPSend(ZIGBEE_FACTORY_RESET, sizeof(ZIGBEE_FACTORY_RESET)); - eraseZigbeeDevices(); - restart_flag = 2; - ResponseCmndChar_P(PSTR(D_JSON_ZIGBEE_CC2530 " " D_JSON_RESET_AND_RESTARTING)); - break; - default: - ResponseCmndChar_P(PSTR(D_JSON_ONE_TO_RESET)); - } - } -} - -// -// Same code for `ZbZNPSend` and `ZbZNPReceive` -// building the complete message (intro, length) -// -void CmndZbZNPSendOrReceive(bool send) -{ - if (ZigbeeSerial && (XdrvMailbox.data_len > 0)) { - uint8_t code; - - char *codes = RemoveSpace(XdrvMailbox.data); - int32_t size = strlen(XdrvMailbox.data); - - SBuffer buf((size+1)/2); - - while (size > 1) { - char stemp[3]; - strlcpy(stemp, codes, sizeof(stemp)); - code = strtol(stemp, nullptr, 16); - buf.add8(code); - size -= 2; - codes += 2; - } - if (send) { - // Command was `ZbZNPSend` - ZigbeeZNPSend(buf.getBuffer(), buf.len()); - } else { - // Command was `ZbZNPReceive` - ZigbeeProcessInput(buf); - } - } - ResponseCmndDone(); -} - -// For debug purposes only, simulates a message received -void CmndZbZNPReceive(void) -{ - CmndZbZNPSendOrReceive(false); -} - -void CmndZbZNPSend(void) -{ - CmndZbZNPSendOrReceive(true); -} - -void ZigbeeZNPSend(const uint8_t *msg, size_t len) { - if ((len < 2) || (len > 252)) { - // abort, message cannot be less than 2 bytes for CMD1 and CMD2 - AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_JSON_ZIGBEEZNPSENT ": bad message len %d"), len); - return; - } - uint8_t data_len = len - 2; // removing CMD1 and CMD2 - - if (ZigbeeSerial) { - uint8_t fcs = data_len; - - ZigbeeSerial->write(ZIGBEE_SOF); // 0xFE - //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZNPSend SOF %02X"), ZIGBEE_SOF); - ZigbeeSerial->write(data_len); - //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZNPSend LEN %02X"), data_len); - for (uint32_t i = 0; i < len; i++) { - uint8_t b = pgm_read_byte(msg + i); - ZigbeeSerial->write(b); - fcs ^= b; - //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZNPSend byt %02X"), b); - } - ZigbeeSerial->write(fcs); // finally send fcs checksum byte - //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZNPSend FCS %02X"), fcs); - } - // Now send a MQTT message to report the sent message - char hex_char[(len * 2) + 2]; - AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE D_JSON_ZIGBEEZNPSENT " %s"), - ToHex_P(msg, len, hex_char, sizeof(hex_char))); -} - -// -// Internal function, send the low-level frame -// Input: -// - shortaddr: 16-bits short address, or 0x0000 if group address -// - groupaddr: 16-bits group address, or 0x0000 if unicast using shortaddr -// - clusterIf: 16-bits cluster number -// - endpoint: 8-bits target endpoint (source is always 0x01), unused for group addresses. Should not be 0x00 except when sending to group address. -// - cmdId: 8-bits ZCL command number -// - clusterSpecific: boolean, is the message general cluster or cluster specific, used to create the FC byte of ZCL -// - msg: pointer to byte array, payload of ZCL message (len is following), ignored if nullptr -// - len: length of the 'msg' payload -// - needResponse: boolean, true = we ask the target to respond, false = the target should not respond -// - transacId: 8-bits, transation id of message (should be incremented at each message), used both for Zigbee message number and ZCL message number -// Returns: None -// -void ZigbeeZCLSend_Raw(uint16_t shortaddr, uint16_t groupaddr, uint16_t clusterId, uint8_t endpoint, uint8_t cmdId, bool clusterSpecific, uint16_t manuf, const uint8_t *msg, size_t len, bool needResponse, uint8_t transacId) { - - SBuffer buf(32+len); - buf.add8(Z_SREQ | Z_AF); // 24 - buf.add8(AF_DATA_REQUEST_EXT); // 02 - if (0x0000 == shortaddr) { // if no shortaddr we assume group address - buf.add8(Z_Addr_Group); // 01 - buf.add64(groupaddr); // group address, only 2 LSB, upper 6 MSB are discarded - buf.add8(0xFF); // dest endpoint is not used for group addresses - } else { - buf.add8(Z_Addr_ShortAddress); // 02 - buf.add64(shortaddr); // dest address, only 2 LSB, upper 6 MSB are discarded - buf.add8(endpoint); // dest endpoint - } - buf.add16(0x0000); // dest Pan ID, 0x0000 = intra-pan - buf.add8(0x01); // source endpoint - buf.add16(clusterId); - buf.add8(transacId); // transacId - buf.add8(0x30); // 30 options - buf.add8(0x1E); // 1E radius - - buf.add16(3 + len + (manuf ? 2 : 0)); - buf.add8((needResponse ? 0x00 : 0x10) | (clusterSpecific ? 0x01 : 0x00) | (manuf ? 0x04 : 0x00)); // Frame Control Field - if (manuf) { - buf.add16(manuf); // add Manuf Id if not null - } - buf.add8(transacId); // Transaction Sequance Number - buf.add8(cmdId); - if (len > 0) { - buf.addBuffer(msg, len); // add the payload - } - - ZigbeeZNPSend(buf.getBuffer(), buf.len()); -} - -/********************************************************************************************/ -// -// High-level function -// Send a command specified as an HEX string for the workload. -// The target endpoint is computed if zero, i.e. sent to the first known endpoint of the device. -// If cluster-specific, a timer may be set calling `zigbeeSetCommandTimer()`, for ex to coalesce attributes or Aqara presence sensor -// -// Inputs: -// - shortaddr: 16-bits short address, or 0x0000 if group address -// - groupaddr: 16-bits group address, or 0x0000 if unicast using shortaddr -// - endpoint: 8-bits target endpoint (source is always 0x01), if 0x00, it will be guessed from ZbStatus information (basically the first endpoint of the device) -// - clusterSpecific: boolean, is the message general cluster or cluster specific, used to create the FC byte of ZCL -// - clusterIf: 16-bits cluster number -// - param: pointer to HEX string for payload, should not be nullptr -// Returns: None -// -void zigbeeZCLSendStr(uint16_t shortaddr, uint16_t groupaddr, uint8_t endpoint, bool clusterSpecific, uint16_t manuf, - uint16_t cluster, uint8_t cmd, const char *param) { - size_t size = param ? strlen(param) : 0; - SBuffer buf((size+2)/2); // actual bytes buffer for data - - if (param) { - while (*param) { - uint8_t code = parseHex_P(¶m, 2); - buf.add8(code); - } - } - - if ((0 == endpoint) && (shortaddr)) { - // endpoint is not specified, let's try to find it from shortAddr, unless it's a group address - endpoint = zigbee_devices.findFirstEndpoint(shortaddr); - //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZbSend: guessing endpoint 0x%02X"), endpoint); - } - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZbSend: shortaddr 0x%04X, groupaddr 0x%04X, cluster 0x%04X, endpoint 0x%02X, cmd 0x%02X, data %s"), - shortaddr, groupaddr, cluster, endpoint, cmd, param); - - if ((0 == endpoint) && (shortaddr)) { // endpoint null is ok for group address - AddLog_P2(LOG_LEVEL_INFO, PSTR("ZbSend: unspecified endpoint")); - return; - } - - // everything is good, we can send the command - ZigbeeZCLSend_Raw(shortaddr, groupaddr, cluster, endpoint, cmd, clusterSpecific, manuf, buf.getBuffer(), buf.len(), true, zigbee_devices.getNextSeqNumber(shortaddr)); - // now set the timer, if any, to read back the state later - if (clusterSpecific) { - zigbeeSetCommandTimer(shortaddr, groupaddr, cluster, endpoint); - } -} - -// -// Command `ZbSend` -// -void CmndZbSend(void) { - // ZbSend { "device":"0x1234", "endpoint":"0x03", "send":{"Power":1} } - // ZbSend { "device":"0x1234", "endpoint":"0x03", "send":{"Power":"3"} } - // ZbSend { "device":"0x1234", "endpoint":"0x03", "send":{"Power":"0xFF"} } - // ZbSend { "device":"0x1234", "endpoint":"0x03", "send":{"Power":null} } - // ZbSend { "device":"0x1234", "endpoint":"0x03", "send":{"Power":false} } - // ZbSend { "device":"0x1234", "endpoint":"0x03", "send":{"Power":true} } - // ZbSend { "device":"0x1234", "endpoint":"0x03", "send":{"Power":"true"} } - // ZbSend { "device":"0x1234", "endpoint":"0x03", "send":{"ShutterClose":null} } - // ZbSend { "devicse":"0x1234", "endpoint":"0x03", "send":{"Power":1} } - // ZbSend { "device":"0x1234", "endpoint":"0x03", "send":{"Color":"1,2"} } - // ZbSend { "device":"0x1234", "endpoint":"0x03", "send":{"Color":"0x1122,0xFFEE"} } - if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; } - DynamicJsonBuffer jsonBuf; - const JsonObject &json = jsonBuf.parseObject((const char*) XdrvMailbox.data); - if (!json.success()) { ResponseCmndChar_P(PSTR(D_JSON_INVALID_JSON)); return; } - - // params - static char delim[] = ", "; // delimiters for parameters - uint16_t device = 0x0000; // 0x0000 is local, so considered invalid - uint16_t groupaddr = 0x0000; // group address - uint8_t endpoint = 0x00; // 0x00 is invalid for the dst endpoint - uint16_t manuf = 0x0000; // Manuf Id in ZCL frame - // Command elements - uint16_t cluster = 0; - uint8_t cmd = 0; - String cmd_str = ""; // the actual low-level command, either specified or computed - const char *cmd_s; // pointer to payload string - bool clusterSpecific = true; - - // parse JSON - const JsonVariant &val_device = getCaseInsensitive(json, PSTR("Device")); - if (nullptr != &val_device) { - device = zigbee_devices.parseDeviceParam(val_device.as()); - if (0xFFFF == device) { ResponseCmndChar_P(PSTR("Invalid parameter")); return; } - } - if (0x0000 == device) { // if not found, check if we have a group - const JsonVariant &val_group = getCaseInsensitive(json, PSTR("Group")); - if (nullptr != &val_group) { - groupaddr = strToUInt(val_group); - } else { // no device nor group - ResponseCmndChar_P(PSTR("Unknown device")); - return; - } - } - - const JsonVariant &val_endpoint = getCaseInsensitive(json, PSTR("Endpoint")); - if (nullptr != &val_endpoint) { endpoint = strToUInt(val_endpoint); } - const JsonVariant &val_manuf = getCaseInsensitive(json, PSTR("Manuf")); - if (nullptr != &val_manuf) { manuf = strToUInt(val_manuf); } - const JsonVariant &val_cmd = getCaseInsensitive(json, PSTR("Send")); - if (nullptr != &val_cmd) { - // probe the type of the argument - // If JSON object, it's high level commands - // If String, it's a low level command - if (val_cmd.is()) { - // we have a high-level command - const JsonObject &cmd_obj = val_cmd.as(); - int32_t cmd_size = cmd_obj.size(); - if (cmd_size > 1) { - Response_P(PSTR("Only 1 command allowed (%d)"), cmd_size); - return; - } else if (1 == cmd_size) { - // We have exactly 1 command, parse it - JsonObject::const_iterator it = cmd_obj.begin(); // just get the first key/value - String key = it->key; - const JsonVariant& value = it->value; - uint32_t x = 0, y = 0, z = 0; - uint16_t cmd_var; - - const __FlashStringHelper* tasmota_cmd = zigbeeFindCommand(key.c_str(), &cluster, &cmd_var); - if (tasmota_cmd) { - cmd_str = tasmota_cmd; - } else { - Response_P(PSTR("Unrecognized zigbee command: %s"), key.c_str()); - return; - } - - // parse the JSON value, depending on its type fill in x,y,z - if (value.is()) { - x = value.as() ? 1 : 0; - } else if (value.is()) { - x = value.as(); - } else { - // if non-bool or non-int, trying char* - const char *s_const = value.as(); - if (s_const != nullptr) { - char s[strlen(s_const)+1]; - strcpy(s, s_const); - if ((nullptr != s) && (0x00 != *s)) { // ignore any null or empty string, could represent 'null' json value - char *sval = strtok(s, delim); - if (sval) { - x = ZigbeeAliasOrNumber(sval); - sval = strtok(nullptr, delim); - if (sval) { - y = ZigbeeAliasOrNumber(sval); - sval = strtok(nullptr, delim); - if (sval) { - z = ZigbeeAliasOrNumber(sval); - } - } - } - } - } - } - - //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZbSend: command_template = %s"), cmd_str.c_str()); - if (0xFF == cmd_var) { // if command number is a variable, replace it with x - cmd = x; - x = y; // and shift other variables - y = z; - } else { - cmd = cmd_var; // or simply copy the cmd number - } - cmd_str = zigbeeCmdAddParams(cmd_str.c_str(), x, y, z); // fill in parameters - //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZbSend: command_final = %s"), cmd_str.c_str()); - cmd_s = cmd_str.c_str(); - } else { - // we have zero command, pass through until last error for missing command - } - } else if (val_cmd.is()) { - // low-level command - cmd_str = val_cmd.as(); - // Now parse the string to extract cluster, command, and payload - // Parse 'cmd' in the form "AAAA_BB/CCCCCCCC" or "AAAA!BB/CCCCCCCC" - // where AA is the cluster number, BBBB the command number, CCCC... the payload - // First delimiter is '_' for a global command, or '!' for a cluster specific command - const char * data = cmd_str.c_str(); - cluster = parseHex(&data, 4); - - // delimiter - if (('_' == *data) || ('!' == *data)) { - if ('_' == *data) { clusterSpecific = false; } - data++; - } else { - ResponseCmndChar_P(PSTR("Wrong delimiter for payload")); - return; - } - // parse cmd number - cmd = parseHex(&data, 2); - - // move to end of payload - // delimiter is optional - if ('/' == *data) { data++; } // skip delimiter - - cmd_s = data; - } else { - // we have an unsupported command type, just ignore it and fallback to missing command - } - - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZigbeeZCLSend device: 0x%04X, group: 0x%04X, endpoint:%d, cluster:0x%04X, cmd:0x%02X, send:\"%s\""), - device, groupaddr, endpoint, cluster, cmd, cmd_s); - zigbeeZCLSendStr(device, groupaddr, endpoint, clusterSpecific, manuf, cluster, cmd, cmd_s); - ResponseCmndDone(); - } else { - Response_P(PSTR("Missing zigbee 'Send'")); - return; - } -} - -// -// Command `ZbBind` -// -void ZbBindUnbind(bool unbind) { // false = bind, true = unbind - // ZbBind {"Device":"", "Endpoint":, "Cluster":, "ToDevice":"", "ToEndpoint":, "ToGroup": } - // ZbUnbind {"Device":"", "Endpoint":, "Cluster":, "ToDevice":"", "ToEndpoint":, "ToGroup": } - - // local endpoint is always 1, IEEE addresses are calculated - if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; } - DynamicJsonBuffer jsonBuf; - const JsonObject &json = jsonBuf.parseObject((const char*) XdrvMailbox.data); - if (!json.success()) { ResponseCmndChar_P(PSTR(D_JSON_INVALID_JSON)); return; } - - // params - // static char delim[] = ", "; // delimiters for parameters - uint16_t srcDevice = 0xFFFF; // 0xFFFF is broadcast, so considered invalid - uint16_t dstDevice = 0xFFFF; // 0xFFFF is broadcast, so considered invalid - uint64_t dstLongAddr = 0; - uint8_t endpoint = 0x00; // 0x00 is invalid for the src endpoint - uint8_t toendpoint = 0x00; // 0x00 is invalid for the dst endpoint - uint16_t toGroup = 0x0000; // group address - uint16_t cluster = 0; // 0xFFFF is invalid - uint32_t group = 0xFFFFFFFF; // 16 bits values, otherwise 0xFFFFFFFF is unspecified - - // Information about source device: "Device", "Endpoint", "Cluster" - // - the source endpoint must have a known IEEE address - const JsonVariant &val_device = getCaseInsensitive(json, PSTR("Device")); - if (nullptr != &val_device) { - srcDevice = zigbee_devices.parseDeviceParam(val_device.as()); - if (0xFFFF == srcDevice) { ResponseCmndChar_P(PSTR("Invalid parameter")); return; } - } - if ((nullptr == &val_device) || (0x0000 == srcDevice)) { ResponseCmndChar_P(PSTR("Unknown source device")); return; } - // check if IEEE address is known - uint64_t srcLongAddr = zigbee_devices.getDeviceLongAddr(srcDevice); - if (0 == srcLongAddr) { ResponseCmndChar_P(PSTR("Unknown source IEEE address")); return; } - // look for source endpoint - const JsonVariant &val_endpoint = getCaseInsensitive(json, PSTR("Endpoint")); - if (nullptr != &val_endpoint) { endpoint = strToUInt(val_endpoint); } - // look for source cluster - const JsonVariant &val_cluster = getCaseInsensitive(json, PSTR("Cluster")); - if (nullptr != &val_cluster) { cluster = strToUInt(val_cluster); } - - // Either Device address - // In this case the following parameters are mandatory - // - "ToDevice" and the device must have a known IEEE address - // - "ToEndpoint" - const JsonVariant &dst_device = getCaseInsensitive(json, PSTR("ToDevice")); - if (nullptr != &dst_device) { - dstDevice = zigbee_devices.parseDeviceParam(dst_device.as()); - if (0xFFFF == dstDevice) { ResponseCmndChar_P(PSTR("Invalid parameter")); return; } - if (0x0000 == dstDevice) { - dstLongAddr = localIEEEAddr; - } else { - dstLongAddr = zigbee_devices.getDeviceLongAddr(dstDevice); - } - if (0 == dstLongAddr) { ResponseCmndChar_P(PSTR("Unknown dest IEEE address")); return; } - - const JsonVariant &val_toendpoint = getCaseInsensitive(json, PSTR("ToEndpoint")); - if (nullptr != &val_toendpoint) { toendpoint = strToUInt(val_endpoint); } else { toendpoint = endpoint; } - } - - // Or Group Address - we don't need a dstEndpoint in this case - const JsonVariant &to_group = getCaseInsensitive(json, PSTR("ToGroup")); - if (nullptr != &to_group) { toGroup = strToUInt(to_group); } - - // make sure we don't have conflicting parameters - if (toGroup && dstLongAddr) { ResponseCmndChar_P(PSTR("Cannot have both \"ToDevice\" and \"ToGroup\"")); return; } - if (!toGroup && !dstLongAddr) { ResponseCmndChar_P(PSTR("Missing \"ToDevice\" or \"ToGroup\"")); return; } - - SBuffer buf(34); - buf.add8(Z_SREQ | Z_ZDO); - if (unbind) { - buf.add8(ZDO_UNBIND_REQ); - } else { - buf.add8(ZDO_BIND_REQ); - } - buf.add16(srcDevice); - buf.add64(srcLongAddr); - buf.add8(endpoint); - buf.add16(cluster); - if (dstLongAddr) { - buf.add8(Z_Addr_IEEEAddress); // DstAddrMode - 0x03 = ADDRESS_64_BIT - buf.add64(dstLongAddr); - buf.add8(toendpoint); - } else { - buf.add8(Z_Addr_Group); // DstAddrMode - 0x01 = GROUP_ADDRESS - buf.add16(toGroup); - } - - ZigbeeZNPSend(buf.getBuffer(), buf.len()); - - ResponseCmndDone(); -} - -// -// Command ZbBind -// -void CmndZbBind(void) { - ZbBindUnbind(false); -} - -// -// Command ZbBind -// -void CmndZbUnbind(void) { - ZbBindUnbind(true); -} - -// -// Command `ZbBindState` -// -void CmndZbBindState(void) { - if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; } - uint16_t shortaddr = zigbee_devices.parseDeviceParam(XdrvMailbox.data); - if (0x0000 == shortaddr) { ResponseCmndChar_P(PSTR("Unknown device")); return; } - if (0xFFFF == shortaddr) { ResponseCmndChar_P(PSTR("Invalid parameter")); return; } - - SBuffer buf(10); - buf.add8(Z_SREQ | Z_ZDO); // 25 - buf.add8(ZDO_MGMT_BIND_REQ); // 33 - buf.add16(shortaddr); // shortaddr - buf.add8(0); // StartIndex = 0 - - ZigbeeZNPSend(buf.getBuffer(), buf.len()); - - ResponseCmndDone(); -} - -// Probe a specific device to get its endpoints and supported clusters -void CmndZbProbe(void) { - CmndZbProbeOrPing(true); -} - -// -// Common code for `ZbProbe` and `ZbPing` -// -void CmndZbProbeOrPing(boolean probe) { - if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; } - uint16_t shortaddr = zigbee_devices.parseDeviceParam(XdrvMailbox.data); - if (0x0000 == shortaddr) { ResponseCmndChar_P(PSTR("Unknown device")); return; } - if (0xFFFF == shortaddr) { ResponseCmndChar_P(PSTR("Invalid parameter")); return; } - - // everything is good, we can send the command - Z_SendIEEEAddrReq(shortaddr); - if (probe) { - Z_SendActiveEpReq(shortaddr); - } - ResponseCmndDone(); -} - -// Ping a device, actually a simplified version of ZbProbe -void CmndZbPing(void) { - CmndZbProbeOrPing(false); -} - -// -// Command `ZbName` -// Specify, read or erase a Friendly Name -// -void CmndZbName(void) { - // Syntax is: - // ZbName , - assign a friendly name - // ZbName - display the current friendly name - // ZbName , - remove friendly name - // - // Where can be: short_addr, long_addr, device_index, friendly_name - - if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; } - - // check if parameters contain a comma ',' - char *p; - char *str = strtok_r(XdrvMailbox.data, ", ", &p); - - // parse first part, - uint16_t shortaddr = zigbee_devices.parseDeviceParam(XdrvMailbox.data, true); // in case of short_addr, it must be already registered - if (0x0000 == shortaddr) { ResponseCmndChar_P(PSTR("Unknown device")); return; } - if (0xFFFF == shortaddr) { ResponseCmndChar_P(PSTR("Invalid parameter")); return; } - - if (p == nullptr) { - const char * friendlyName = zigbee_devices.getFriendlyName(shortaddr); - Response_P(PSTR("{\"0x%04X\":{\"" D_JSON_ZIGBEE_NAME "\":\"%s\"}}"), shortaddr, friendlyName ? friendlyName : ""); - } else { - zigbee_devices.setFriendlyName(shortaddr, p); - Response_P(PSTR("{\"0x%04X\":{\"" D_JSON_ZIGBEE_NAME "\":\"%s\"}}"), shortaddr, p); - } -} - -// -// Command `ZbName` -// Specify, read or erase a ModelId, only for debug purposes -// -void CmndZbModelId(void) { - // Syntax is: - // ZbName , - assign a friendly name - // ZbName - display the current friendly name - // ZbName , - remove friendly name - // - // Where can be: short_addr, long_addr, device_index, friendly_name - - if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; } - - // check if parameters contain a comma ',' - char *p; - char *str = strtok_r(XdrvMailbox.data, ", ", &p); - - // parse first part, - uint16_t shortaddr = zigbee_devices.parseDeviceParam(XdrvMailbox.data, true); // in case of short_addr, it must be already registered - if (0x0000 == shortaddr) { ResponseCmndChar_P(PSTR("Unknown device")); return; } - if (0xFFFF == shortaddr) { ResponseCmndChar_P(PSTR("Invalid parameter")); return; } - - if (p == nullptr) { - const char * modelId = zigbee_devices.getModelId(shortaddr); - Response_P(PSTR("{\"0x%04X\":{\"" D_JSON_ZIGBEE_MODELID "\":\"%s\"}}"), shortaddr, modelId ? modelId : ""); - } else { - zigbee_devices.setModelId(shortaddr, p); - Response_P(PSTR("{\"0x%04X\":{\"" D_JSON_ZIGBEE_MODELID "\":\"%s\"}}"), shortaddr, p); - } -} - -// -// Command `ZbLight` -// Specify, read or erase a Light type for Hue/Alexa integration -void CmndZbLight(void) { - // Syntax is: - // ZbLight , - assign a bulb type 0-5 - // ZbLight - display the current bulb type and status - // - // Where can be: short_addr, long_addr, device_index, friendly_name - - if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; } - - // check if parameters contain a comma ',' - char *p; - char *str = strtok_r(XdrvMailbox.data, ", ", &p); - - // parse first part, - uint16_t shortaddr = zigbee_devices.parseDeviceParam(XdrvMailbox.data, true); // in case of short_addr, it must be already registered - if (0x0000 == shortaddr) { ResponseCmndChar_P(PSTR("Unknown device")); return; } - if (0xFFFF == shortaddr) { ResponseCmndChar_P(PSTR("Invalid parameter")); return; } - - if (p) { - int8_t bulbtype = strtol(p, nullptr, 10); - if (bulbtype > 5) { bulbtype = 5; } - if (bulbtype < -1) { bulbtype = -1; } - zigbee_devices.setHueBulbtype(shortaddr, bulbtype); - } - String dump = zigbee_devices.dumpLightState(shortaddr); - Response_P(PSTR("{\"" D_PRFX_ZB D_CMND_ZIGBEE_LIGHT "\":%s}"), dump.c_str()); - - MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_PRFX_ZB D_CMND_ZIGBEE_LIGHT)); - XdrvRulesProcess(); - ResponseCmndDone(); -} - -// -// Command `ZbForget` -// Remove an old Zigbee device from the list of known devices, use ZigbeeStatus to know all registered devices -// -void CmndZbForget(void) { - if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; } - uint16_t shortaddr = zigbee_devices.parseDeviceParam(XdrvMailbox.data); - if (0x0000 == shortaddr) { ResponseCmndChar_P(PSTR("Unknown device")); return; } - if (0xFFFF == shortaddr) { ResponseCmndChar_P(PSTR("Invalid parameter")); return; } - - // everything is good, we can send the command - if (zigbee_devices.removeDevice(shortaddr)) { - ResponseCmndDone(); - } else { - ResponseCmndChar_P(PSTR("Unknown device")); - } -} - -// -// Command `ZbSave` -// Save Zigbee information to flash -// -void CmndZbSave(void) { - if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; } - saveZigbeeDevices(); - ResponseCmndDone(); -} - - -// Restore a device configuration previously exported via `ZbStatus2`` -// Format: -// Either the entire `ZbStatus3` export, or an array or just the device configuration. -// If array, if can contain multiple devices -// ZbRestore {"ZbStatus3":[{"Device":"0x5ADF","Name":"Petite_Lampe","IEEEAddr":"0x90FD9FFFFE03B051","ModelId":"TRADFRI bulb E27 WS opal 980lm","Manufacturer":"IKEA of Sweden","Endpoints":["0x01","0xF2"]}]} -// ZbRestore [{"Device":"0x5ADF","Name":"Petite_Lampe","IEEEAddr":"0x90FD9FFFFE03B051","ModelId":"TRADFRI bulb E27 WS opal 980lm","Manufacturer":"IKEA of Sweden","Endpoints":["0x01","0xF2"]}] -// ZbRestore {"Device":"0x5ADF","Name":"Petite_Lampe","IEEEAddr":"0x90FD9FFFFE03B051","ModelId":"TRADFRI bulb E27 WS opal 980lm","Manufacturer":"IKEA of Sweden","Endpoints":["0x01","0xF2"]} -void CmndZbRestore(void) { - if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; } - DynamicJsonBuffer jsonBuf; - const JsonVariant json_parsed = jsonBuf.parse((const char*) XdrvMailbox.data); // const to force a copy of parameter - const JsonVariant * json = &json_parsed; // root of restore, to be changed if needed - bool success = false; - - // check if parsing succeeded - if (json_parsed.is()) { - success = json_parsed.as().success(); - } else if (json_parsed.is()) { - success = json_parsed.as().success(); - } - if (!success) { ResponseCmndChar_P(PSTR(D_JSON_INVALID_JSON)); return; } - - // Check is root contains `ZbStatus` key, if so change the root - const JsonVariant * zbstatus = &startsWithCaseInsensitive(*json, PSTR("ZbStatus")); - if (nullptr != zbstatus) { - json = zbstatus; - } - - // check if the root is an array - if (json->is()) { - const JsonArray& arr = json->as(); - for (auto elt : arr) { - // call restore on each item - int32_t res = zigbee_devices.deviceRestore(elt); - if (res < 0) { - ResponseCmndChar_P(PSTR("Restore failed")); - return; - } - } - } else if (json->is()) { - int32_t res = zigbee_devices.deviceRestore(*json); - if (res < 0) { - ResponseCmndChar_P(PSTR("Restore failed")); - return; - } - // call restore on a single object - } else { - ResponseCmndChar_P(PSTR("Missing parameters")); - return; - } - ResponseCmndDone(); -} - -// -// Command `ZbRead` -// Send an attribute read command to a device, specifying cluster and list of attributes -// -void CmndZbRead(void) { - // ZbRead {"Device":"0xF289","Cluster":0,"Endpoint":3,"Attr":5} - // ZbRead {"Device":"0xF289","Cluster":"0x0000","Endpoint":"0x0003","Attr":"0x0005"} - // ZbRead {"Device":"0xF289","Cluster":0,"Endpoint":3,"Attr":[5,6,7,4]} - if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; } - DynamicJsonBuffer jsonBuf; - JsonObject &json = jsonBuf.parseObject((const char*) XdrvMailbox.data); - if (!json.success()) { ResponseCmndChar_P(PSTR(D_JSON_INVALID_JSON)); return; } - - // params - uint16_t device = 0xFFFF; // 0xFFFF is braodcast, so considered valid - uint16_t groupaddr = 0x0000; // if 0x0000 ignore group adress - uint16_t cluster = 0x0000; // default to general cluster - uint8_t endpoint = 0x00; // 0x00 is invalid for the dst endpoint - uint16_t manuf = 0x0000; // Manuf Id in ZCL frame - size_t attrs_len = 0; - uint8_t* attrs = nullptr; // empty string is valid - - const JsonVariant &val_device = getCaseInsensitive(json, PSTR("Device")); - if (nullptr != &val_device) { - device = zigbee_devices.parseDeviceParam(val_device.as()); - if (0xFFFF == device) { ResponseCmndChar_P(PSTR("Invalid parameter")); return; } - } - if (0x0000 == device) { // if not found, check if we have a group - const JsonVariant &val_group = getCaseInsensitive(json, PSTR("Group")); - if (nullptr != &val_group) { - groupaddr = strToUInt(val_group); - } else { // no device nor group - ResponseCmndChar_P(PSTR("Unknown device")); - return; - } - } - - const JsonVariant &val_cluster = getCaseInsensitive(json, PSTR("Cluster")); - if (nullptr != &val_cluster) { cluster = strToUInt(val_cluster); } - const JsonVariant &val_endpoint = getCaseInsensitive(json, PSTR("Endpoint")); - if (nullptr != &val_endpoint) { endpoint = strToUInt(val_endpoint); } - const JsonVariant &val_manuf = getCaseInsensitive(json, PSTR("Manuf")); - if (nullptr != &val_manuf) { manuf = strToUInt(val_manuf); } - - const JsonVariant &val_attr = getCaseInsensitive(json, PSTR("Read")); - if (nullptr != &val_attr) { - uint16_t val = strToUInt(val_attr); - if (val_attr.is()) { - const JsonArray& attr_arr = val_attr.as(); - attrs_len = attr_arr.size() * 2; - attrs = new uint8_t[attrs_len]; - - uint32_t i = 0; - for (auto value : attr_arr) { - uint16_t val = strToUInt(value); - attrs[i++] = val & 0xFF; - attrs[i++] = val >> 8; - } - } else { - attrs_len = 2; - attrs = new uint8_t[attrs_len]; - attrs[0] = val & 0xFF; // little endian - attrs[1] = val >> 8; - } - } - - if ((0 == endpoint) && (device)) { // try to compute the endpoint - endpoint = zigbee_devices.findFirstEndpoint(device); - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZbSend: guessing endpoint 0x%02X"), endpoint); - } - if (0x0000 == device) { - endpoint = 0xFF; // endpoint not used for group addresses - } - - if ((0 != endpoint) && (attrs_len > 0)) { - ZigbeeZCLSend_Raw(device, groupaddr, cluster, endpoint, ZCL_READ_ATTRIBUTES, false, manuf, attrs, attrs_len, true /* we do want a response */, zigbee_devices.getNextSeqNumber(device)); - ResponseCmndDone(); - } else { - ResponseCmndChar_P(PSTR("Missing parameters")); - } - - if (attrs) { delete[] attrs; } -} - -// -// Command `ZbPermitJoin` -// Allow or Deny pairing of new Zigbee devices -// -void CmndZbPermitJoin(void) { - if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; } - uint32_t payload = XdrvMailbox.payload; - uint16_t dstAddr = 0xFFFC; // default addr - uint8_t duration = 60; // default 60s - - if (payload <= 0) { - duration = 0; - } else if (99 == payload) { - duration = 0xFF; // unlimited time - } - - SBuffer buf(34); - buf.add8(Z_SREQ | Z_ZDO); // 25 - buf.add8(ZDO_MGMT_PERMIT_JOIN_REQ); // 36 - buf.add8(0x0F); // AddrMode - buf.add16(0xFFFC); // DstAddr - buf.add8(duration); - buf.add8(0x00); // TCSignificance - - ZigbeeZNPSend(buf.getBuffer(), buf.len()); - - ResponseCmndDone(); -} - -// -// Command `ZbStatus` -// -void CmndZbStatus(void) { - if (ZigbeeSerial) { - if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; } - uint16_t shortaddr = zigbee_devices.parseDeviceParam(XdrvMailbox.data); - if (0xFFFF == shortaddr) { ResponseCmndChar_P(PSTR("Invalid parameter")); return; } - if (XdrvMailbox.payload > 0) { - if (0x0000 == shortaddr) { ResponseCmndChar_P(PSTR("Unknown device")); return; } - } - - String dump = zigbee_devices.dump(XdrvMailbox.index, shortaddr); - Response_P(PSTR("{\"%s%d\":%s}"), XdrvMailbox.command, XdrvMailbox.index, dump.c_str()); - } -} - -/*********************************************************************************************\ - * Interface -\*********************************************************************************************/ - -bool Xdrv23(uint8_t function) -{ - bool result = false; - - if (zigbee.active) { - switch (function) { - case FUNC_EVERY_50_MSECOND: - if (!zigbee.init_phase) { - zigbee_devices.runTimer(); - } - break; - case FUNC_LOOP: - if (ZigbeeSerial) { ZigbeeInputLoop(); } - if (zigbee.state_machine) { - ZigbeeStateMachine_Run(); - } - break; - case FUNC_PRE_INIT: - ZigbeeInit(); - break; - case FUNC_COMMAND: - result = DecodeCommand(kZbCommands, ZigbeeCommand); - break; - } - } - return result; -} - -#endif // USE_ZIGBEE diff --git a/tasmota/xdrv_23_zigbee_9_serial.ino b/tasmota/xdrv_23_zigbee_9_serial.ino new file mode 100644 index 000000000..aeefe8ae4 --- /dev/null +++ b/tasmota/xdrv_23_zigbee_9_serial.ino @@ -0,0 +1,779 @@ +/* + xdrv_23_zigbee_9_serial.ino - zigbee: serial communication with MCU + + Copyright (C) 2020 Theo Arends and Stephan Hadinger + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifdef USE_ZIGBEE + +#ifdef USE_ZIGBEE_ZNP +const uint32_t ZIGBEE_BUFFER_SIZE = 256; // Max ZNP frame is SOF+LEN+CMD1+CMD2+250+FCS = 255 +const uint8_t ZIGBEE_SOF = 0xFE; +const uint8_t ZIGBEE_SOF_ALT = 0xFF; +#endif // USE_ZIGBEE_ZNP + +#ifdef USE_ZIGBEE_EZSP +const uint32_t ZIGBEE_BUFFER_SIZE = 256; +const uint8_t ZIGBEE_EZSP_CANCEL = 0x1A; // cancel byte +const uint8_t ZIGBEE_EZSP_EOF = 0x7E; // end of frame +const uint8_t ZIGBEE_EZSP_ESCAPE = 0x7D; // escape byte + +const uint32_t ZIGBEE_LED_RECEIVE = 0; // LED<1> blinks when receiving +const uint32_t ZIGBEE_LED_SEND = 0; // LED<2> blinks when receiving + +class EZSP_Serial_t { +public: + uint8_t to_ack = 0; // 0..7, frame number of next id to send + uint8_t from_ack = 0; // 0..7, frame to ack + uint8_t ezsp_seq = 0; // 0..255, EZSP sequence number +}; + +EZSP_Serial_t EZSP_Serial; + +#endif // USE_ZIGBEE_EZSP + +#include +TasmotaSerial *ZigbeeSerial = nullptr; + +/********************************************************************************************/ +// +// Called at event loop, checks for incoming data from the CC2530 +// +void ZigbeeInputLoop(void) { + +#ifdef USE_ZIGBEE_ZNP + static uint32_t zigbee_polling_window = 0; // number of milliseconds since first byte + static uint8_t fcs = ZIGBEE_SOF; + static uint32_t zigbee_frame_len = 5; // minimal zigbee frame length, will be updated when buf[1] is read + // Receive only valid ZNP frames: + // 00 - SOF = 0xFE + // 01 - Length of Data Field - 0..250 + // 02 - CMD1 - first byte of command + // 03 - CMD2 - second byte of command + // 04..FD - Data Field + // FE (or last) - FCS Checksum + + while (ZigbeeSerial->available()) { + yield(); + uint8_t zigbee_in_byte = ZigbeeSerial->read(); + //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZbInput byte=%d len=%d"), zigbee_in_byte, zigbee_buffer->len()); + + if (0 == zigbee_buffer->len()) { // make sure all variables are correctly initialized + zigbee_frame_len = 5; + fcs = ZIGBEE_SOF; + // there is a rare race condition when an interrupt occurs when receiving the first byte + // in this case the first bit (lsb) is missed and Tasmota receives 0xFF instead of 0xFE + // We forgive this mistake, and next bytes are automatically resynchronized + if (ZIGBEE_SOF_ALT == zigbee_in_byte) { + AddLog_P2(LOG_LEVEL_INFO, PSTR("ZbInput forgiven first byte %02X (only for statistics)"), zigbee_in_byte); + zigbee_in_byte = ZIGBEE_SOF; + } + } + + if ((0 == zigbee_buffer->len()) && (ZIGBEE_SOF != zigbee_in_byte)) { + // waiting for SOF (Start Of Frame) byte, discard anything else + AddLog_P2(LOG_LEVEL_INFO, PSTR("ZbInput discarding byte %02X"), zigbee_in_byte); + continue; // discard + } + + if (zigbee_buffer->len() < zigbee_frame_len) { + zigbee_buffer->add8(zigbee_in_byte); + zigbee_polling_window = millis(); // Wait for more data + fcs ^= zigbee_in_byte; + } + + if (zigbee_buffer->len() >= zigbee_frame_len) { + zigbee_polling_window = 0; // Publish now + break; + } + + // recalculate frame length + if (02 == zigbee_buffer->len()) { + // We just received the Lenght byte + uint8_t len_byte = zigbee_buffer->get8(1); + if (len_byte > 250) len_byte = 250; // ZNP spec says len is 250 max + + zigbee_frame_len = len_byte + 5; // SOF + LEN + CMD1 + CMD2 + FCS = 5 bytes overhead + } + } + + if (zigbee_buffer->len() && (millis() > (zigbee_polling_window + ZIGBEE_POLLING))) { + char hex_char[(zigbee_buffer->len() * 2) + 2]; + ToHex_P((unsigned char*)zigbee_buffer->getBuffer(), zigbee_buffer->len(), hex_char, sizeof(hex_char)); + + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_ZIGBEE "Bytes follow_read_metric = %0d"), ZigbeeSerial->getLoopReadMetric()); + // buffer received, now check integrity + if (zigbee_buffer->len() != zigbee_frame_len) { + // Len is not correct, log and reject frame + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEEZNPRECEIVED ": received frame of wrong size %s, len %d, expected %d"), hex_char, zigbee_buffer->len(), zigbee_frame_len); + } else if (0x00 != fcs) { + // FCS is wrong, packet is corrupt, log and reject frame + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEEZNPRECEIVED ": received bad FCS frame %s, %d"), hex_char, fcs); + } else { + // frame is correct + //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR(D_JSON_ZIGBEEZNPRECEIVED ": received correct frame %s"), hex_char); + + SBuffer znp_buffer = zigbee_buffer->subBuffer(2, zigbee_frame_len - 3); // remove SOF, LEN and FCS + + ToHex_P((unsigned char*)znp_buffer.getBuffer(), znp_buffer.len(), hex_char, sizeof(hex_char)); + Response_P(PSTR("{\"" D_JSON_ZIGBEEZNPRECEIVED "\":\"%s\"}"), hex_char); + if (Settings.flag3.tuya_serial_mqtt_publish) { + MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR)); + XdrvRulesProcess(); + } else { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE "%s"), mqtt_data); + } + // now process the message + ZigbeeProcessInput(znp_buffer); + } + zigbee_buffer->setLen(0); // empty buffer + } +#endif // USE_ZIGBEE_ZNP + +#ifdef USE_ZIGBEE_EZSP + static uint32_t zigbee_polling_window = 0; // number of milliseconds since first byte + static bool escape = false; // was the previous byte an escape? + bool frame_complete = false; // frame is ready and complete + bool led_status_on = false; // did we turn on the led receive led + // Receive only valid EZSP frames: + // 1A - Cancel - cancel all previous bytes + // 7D - Escape byte - following byte is escaped + // 7E - end of frame + + while (ZigbeeSerial->available()) { + // turn on receive LED<1> + SetLedPowerIdx(ZIGBEE_LED_RECEIVE, 1); + led_status_on = true; // don't forget to switch it off + + yield(); + uint8_t zigbee_in_byte = ZigbeeSerial->read(); + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZIG: ZbInput byte=0x%02X len=%d"), zigbee_in_byte, zigbee_buffer->len()); + + // if (0 == zigbee_buffer->len()) { // make sure all variables are correctly initialized + // escape = false; + // frame_complete = false; + // } + + if ((0x11 == zigbee_in_byte) || (0x13 == zigbee_in_byte)) { + continue; // ignore reserved bytes XON/XOFF + } + + if (ZIGBEE_EZSP_ESCAPE == zigbee_in_byte) { + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZIG: Escape byte received")); + escape = true; + continue; + } + + if (ZIGBEE_EZSP_CANCEL == zigbee_in_byte) { + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZIG: ZbInput byte=0x1A, cancel byte received, discarding %d bytes"), zigbee_buffer->len()); + zigbee_buffer->setLen(0); // empty buffer + escape = false; + frame_complete = false; + continue; // re-loop + } + + if (ZIGBEE_EZSP_EOF == zigbee_in_byte) { + // end of frame + frame_complete = true; + break; + } + + if (zigbee_buffer->len() < ZIGBEE_BUFFER_SIZE) { + if (escape) { + // invert bit 5 + zigbee_in_byte ^= 0x20; + escape = false; + } + + zigbee_buffer->add8(zigbee_in_byte); + zigbee_polling_window = millis(); // Wait for more data + } // adding bytes + } // while (ZigbeeSerial->available()) + // turn receive led off + if (led_status_on) { + SetLedPowerIdx(ZIGBEE_LED_RECEIVE, 0); + } + + uint32_t frame_len = zigbee_buffer->len(); + if (frame_complete || (frame_len && (millis() > (zigbee_polling_window + ZIGBEE_POLLING)))) { + char hex_char[frame_len * 2 + 2]; + ToHex_P((unsigned char*)zigbee_buffer->getBuffer(), zigbee_buffer->len(), hex_char, sizeof(hex_char)); + + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_ZIGBEE "Bytes follow_read_metric = %0d"), ZigbeeSerial->getLoopReadMetric()); + if ((frame_complete) && (frame_len >= 3)) { + // frame received and has at least 3 bytes (without EOF), checking CRC + // AddLog_P2(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEE_EZSP_RECEIVED ": received raw frame %s"), hex_char); + uint16_t crc = 0xFFFF; // frame CRC + // compute CRC + for (uint32_t i=0; iget8(i) << 8); + for (uint32_t i=0; i<8; i++) { + if (crc & 0x8000) { + crc = (crc << 1) ^ 0x1021; // polynom is x^16 + x^12 + x^5 + 1, CCITT standard + } else { + crc <<= 1; + } + } + } + + uint16_t crc_received = zigbee_buffer->get8(frame_len - 2) << 8 | zigbee_buffer->get8(frame_len - 1); + // remove 2 last bytes + + if (crc_received != crc) { + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEE_EZSP_RECEIVED ": bad crc (received 0x%04X, computed 0x%04X) %s"), crc_received, crc, hex_char); + } else { + // copy buffer + SBuffer ezsp_buffer = zigbee_buffer->subBuffer(0, frame_len - 2); // CRC + + // CRC is correct, apply de-stuffing if DATA frame + if (0 == (ezsp_buffer.get8(0) & 0x80)) { + // DATA frame + uint8_t rand = 0x42; + for (uint32_t i=1; i> 1) ^ 0xB8; } + else { rand = (rand >> 1); } + } + } + + ToHex_P((unsigned char*)ezsp_buffer.getBuffer(), ezsp_buffer.len(), hex_char, sizeof(hex_char)); + Response_P(PSTR("{\"" D_JSON_ZIGBEE_EZSP_RECEIVED "2\":\"%s\"}"), hex_char); + if (Settings.flag3.tuya_serial_mqtt_publish) { + MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR)); + XdrvRulesProcess(); + } else { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE "%s"), mqtt_data); // TODO move to LOG_LEVEL_DEBUG when stable + } + // now process the message + ZigbeeProcessInputRaw(ezsp_buffer); + } + } else { + // the buffer timed-out, print error and discard + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEE_EZSP_RECEIVED ": time-out, discarding %s, %d"), hex_char); + } + zigbee_buffer->setLen(0); // empty buffer + escape = false; + frame_complete = false; + } + +#endif // USE_ZIGBEE_EZSP + +} + +/********************************************************************************************/ + +// Initialize internal structures +void ZigbeeInitSerial(void) +{ +// AddLog_P2(LOG_LEVEL_INFO, PSTR("ZigbeeInit Mem1 = %d"), ESP_getFreeHeap()); + zigbee.active = false; + if (PinUsed(GPIO_ZIGBEE_RX) && PinUsed(GPIO_ZIGBEE_TX)) { + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_ZIGBEE "GPIOs Rx:%d Tx:%d"), Pin(GPIO_ZIGBEE_RX), Pin(GPIO_ZIGBEE_TX)); + // if seriallog_level is 0, we allow GPIO 13/15 to switch to Hardware Serial + ZigbeeSerial = new TasmotaSerial(Pin(GPIO_ZIGBEE_RX), Pin(GPIO_ZIGBEE_TX), seriallog_level ? 1 : 2, 0, 256); // set a receive buffer of 256 bytes + ZigbeeSerial->begin(115200); + if (ZigbeeSerial->hardwareSerial()) { + ClaimSerial(); + uint32_t aligned_buffer = ((uint32_t)serial_in_buffer + 3) & ~3; + zigbee_buffer = new PreAllocatedSBuffer(sizeof(serial_in_buffer) - 3, (char*) aligned_buffer); + } else { +// AddLog_P2(LOG_LEVEL_INFO, PSTR("ZigbeeInit Mem2 = %d"), ESP_getFreeHeap()); + zigbee_buffer = new SBuffer(ZIGBEE_BUFFER_SIZE); +// AddLog_P2(LOG_LEVEL_INFO, PSTR("ZigbeeInit Mem3 = %d"), ESP_getFreeHeap()); + } + zigbee.active = true; + zigbee.init_phase = true; // start the state machine + zigbee.state_machine = true; // start the state machine + ZigbeeSerial->flush(); + } +// AddLog_P2(LOG_LEVEL_INFO, PSTR("ZigbeeInit Mem9 = %d"), ESP_getFreeHeap()); +} + +#ifdef USE_ZIGBEE_ZNP + +void ZigbeeZNPSend(const uint8_t *msg, size_t len) { + if ((len < 2) || (len > 252)) { + // abort, message cannot be less than 2 bytes for CMD1 and CMD2 + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_JSON_ZIGBEEZNPSENT ": bad message len %d"), len); + return; + } + uint8_t data_len = len - 2; // removing CMD1 and CMD2 + + if (ZigbeeSerial) { + uint8_t fcs = data_len; + + ZigbeeSerial->write(ZIGBEE_SOF); // 0xFE + //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZNPSend SOF %02X"), ZIGBEE_SOF); + ZigbeeSerial->write(data_len); + //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZNPSend LEN %02X"), data_len); + for (uint32_t i = 0; i < len; i++) { + uint8_t b = pgm_read_byte(msg + i); + ZigbeeSerial->write(b); + fcs ^= b; + //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZNPSend byt %02X"), b); + } + ZigbeeSerial->write(fcs); // finally send fcs checksum byte + //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("ZNPSend FCS %02X"), fcs); + } + // Now send a MQTT message to report the sent message + char hex_char[(len * 2) + 2]; + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE D_JSON_ZIGBEEZNPSENT " %s"), + ToHex_P(msg, len, hex_char, sizeof(hex_char))); +} + +// +// Same code for `ZbZNPSend` and `ZbZNPReceive` +// building the complete message (intro, length) +// +void CmndZbZNPSendOrReceive(bool send) +{ + if (ZigbeeSerial && (XdrvMailbox.data_len > 0)) { + uint8_t code; + + char *codes = RemoveSpace(XdrvMailbox.data); + int32_t size = strlen(XdrvMailbox.data); + + SBuffer buf((size+1)/2); + + while (size > 1) { + char stemp[3]; + strlcpy(stemp, codes, sizeof(stemp)); + code = strtol(stemp, nullptr, 16); + buf.add8(code); + size -= 2; + codes += 2; + } + if (send) { + // Command was `ZbZNPSend` + ZigbeeZNPSend(buf.getBuffer(), buf.len()); + } else { + // Command was `ZbZNPReceive` + ZigbeeProcessInput(buf); + } + } + ResponseCmndDone(); +} + +// For debug purposes only, simulates a message received +void CmndZbZNPReceive(void) +{ + CmndZbZNPSendOrReceive(false); +} + +void CmndZbZNPSend(void) +{ + CmndZbZNPSendOrReceive(true); +} + +#endif // USE_ZIGBEE_ZNP + +#ifdef USE_ZIGBEE_EZSP + +// internal function to output a byte, and escape it (stuffing) if needed +void ZigbeeEZSPSend_Out(uint8_t out_byte) { + switch (out_byte) { + case 0x7E: // Flag byte + case 0x11: // XON + case 0x13: // XOFF + case 0x18: // Substitute byte + case 0x1A: // Cancel byte + case 0x7D: // Escape byte + // case 0xFF: // special wake-up + ZigbeeSerial->write(ZIGBEE_EZSP_ESCAPE); // send Escape byte 0x7D + ZigbeeSerial->write(out_byte ^ 0x20); // send with bit 5 inverted + break; + default: + ZigbeeSerial->write(out_byte); // send unchanged + break; + } +} +// Send low-level EZSP frames +// +// The frame should contain the Control Byte and Data Field +// The frame shouldn't be escaped, nor randomized +// +// Before sending: +// - send Cancel byte (0x1A) if requested +// - randomize Data Field if DATA Frame +// - compute CRC16 +// - escape (stuff) reserved bytes +// - add EOF (0x7E) +// - send frame +// send_cancel: should we first send a EZSP_CANCEL (0x1A) before the message to clear any leftover +void ZigbeeEZSPSendRaw(const uint8_t *msg, size_t len, bool send_cancel) { + bool led_status_on = false; + + if ((len < 1) || (len > 252)) { + // abort, message cannot be less than 2 bytes for CMD1 and CMD2 + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_JSON_ZIGBEE_EZSP_SENT ": bad message len %d"), len); + return; + } + uint8_t data_len = len - 2; // removing CMD1 and CMD2 + + // turn send led on + SetLedPowerIdx(ZIGBEE_LED_SEND, 1); + led_status_on = true; + + if (ZigbeeSerial) { + if (send_cancel) { + ZigbeeSerial->write(ZIGBEE_EZSP_CANCEL); // 0x1A + } + + bool data_frame = (0 == (msg[0] & 0x80)); + uint8_t rand = 0x42; // pseudo-randomizer initial value + uint16_t crc = 0xFFFF; // CRC16 CCITT initialization + + for (uint32_t i=0; i 0)) { + out_byte ^= rand; + if (rand & 1) { rand = (rand >> 1) ^ 0xB8; } + else { rand = (rand >> 1); } + } + + // compute CRC + crc = crc ^ ((uint16_t)out_byte << 8); + for (uint32_t i=0; i<8; i++) { + if (crc & 0x8000) { + crc = (crc << 1) ^ 0x1021; // polynom is x^16 + x^12 + x^5 + 1, CCITT standard + } else { + crc <<= 1; + } + } + + // output byte + ZigbeeEZSPSend_Out(out_byte); + } + // send CRC16 in big-endian + ZigbeeEZSPSend_Out(crc >> 8); + ZigbeeEZSPSend_Out(crc & 0xFF); + + // finally send End of Frame + ZigbeeSerial->write(ZIGBEE_EZSP_EOF); // 0x1A + } + // turn send led off + if (led_status_on) { + SetLedPowerIdx(ZIGBEE_LED_SEND, 0); + } + + // Now send a MQTT message to report the sent message + char hex_char[(len * 2) + 2]; + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_ZIGBEE D_JSON_ZIGBEE_EZSP_SENT_RAW " %s"), + ToHex_P(msg, len, hex_char, sizeof(hex_char))); +} + +// Send an EZSP command and data +// Ex: Version with min v8 = 000008 +void ZigbeeEZSPSendCmd(const uint8_t *msg, size_t len, bool send_cancel) { + char hex_char[len*2 + 2]; + ToHex_P(msg, len, hex_char, sizeof(hex_char)); + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "ZbEZSPSend %s"), hex_char); + + SBuffer cmd(len+3); // prefix with seq number (1 byte) and frame control bytes (2 bytes) + + cmd.add8(EZSP_Serial.ezsp_seq++); + cmd.add8(0x00); // Low byte of Frame Control + cmd.add8(0x01); // High byte of Frame Control, frameFormatVersion = 1 + cmd.addBuffer(msg, len); + + // send + ZigbeeEZSPSendDATA(cmd.getBuffer(), cmd.len(), send_cancel); +} + +// Send an EZSP DATA frame, automatically calculating the correct frame numbers +void ZigbeeEZSPSendDATA(const uint8_t *msg, size_t len, bool send_cancel) { + uint8_t control_byte = ((EZSP_Serial.to_ack & 0x07) << 4) + (EZSP_Serial.from_ack & 0x07); + // increment to_ack + EZSP_Serial.to_ack = (EZSP_Serial.to_ack + 1) & 0x07; + // build complete frame + SBuffer buf(len+1); + buf.add8(control_byte); + buf.addBuffer(msg, len); + // send + ZigbeeEZSPSendRaw(buf.getBuffer(), buf.len(), send_cancel); +} + +// Receive a high-level EZSP command/response, starting with 16-bits frame ID +int32_t ZigbeeProcessInputEZSP(class SBuffer &buf) { + // verify errors in first 2 bytes. + // TODO + // uint8_t sequence_num = buf.get8(0); + uint16_t frame_control = buf.get16(1); + bool truncated = frame_control & 0x02; + bool overflow = frame_control & 0x01; + bool callbackPending = frame_control & 0x04; + bool security_enabled = frame_control & 0x8000; + if (truncated || overflow || security_enabled) { + AddLog_P2(LOG_LEVEL_INFO, PSTR("ZIG: specific frame_control 0x%04X"), frame_control); + } + + // remove first 2 bytes, be + for (uint32_t i=0; i> 4) + 1) & 0x07; + uint8_t ack_byte = 0x80 | EZSP_Serial.from_ack; + ZigbeeEZSPSendRaw(&ack_byte, 1, false); // send a 1-byte ACK + + // build the EZSP frame + // remove first byte + for (uint8_t i=0; i 0)) { + uint8_t code; + + char *codes = RemoveSpace(XdrvMailbox.data); + int32_t size = strlen(XdrvMailbox.data); + + SBuffer buf((size+1)/2); + + while (size > 1) { + char stemp[3]; + strlcpy(stemp, codes, sizeof(stemp)); + code = strtol(stemp, nullptr, 16); + buf.add8(code); + size -= 2; + codes += 2; + } + if (send) { + // Command was `ZbEZSPSend` + if (2 == XdrvMailbox.index) { ZigbeeEZSPSendDATA(buf.getBuffer(), buf.len(), true); } + else if (3 == XdrvMailbox.index) { ZigbeeEZSPSendRaw(buf.getBuffer(), buf.len(), true); } + else { ZigbeeEZSPSendCmd(buf.getBuffer(), buf.len(), true); } + + } else { + // Command was `ZbEZSPReceive` + if (2 == XdrvMailbox.index) { ZigbeeProcessInput(buf); } + else if (3 == XdrvMailbox.index) { ZigbeeProcessInputRaw(buf); } + else { ZigbeeProcessInputEZSP(buf); } // TODO + } + } + ResponseCmndDone(); +} +// Variants with managed ASH frame numbers +// For debug purposes only, simulates a message received +void CmndZbEZSPReceive(void) +{ + CmndZbEZSPSendOrReceive(false); +} + +void CmndZbEZSPSend(void) +{ + CmndZbEZSPSendOrReceive(true); +} +#endif // USE_ZIGBEE_EZSP + +// +// Internal function, send the low-level frame +// Input: +// - shortaddr: 16-bits short address, or 0x0000 if group address +// - groupaddr: 16-bits group address, or 0x0000 if unicast using shortaddr +// - clusterIf: 16-bits cluster number +// - endpoint: 8-bits target endpoint (source is always 0x01), unused for group addresses. Should not be 0x00 except when sending to group address. +// - cmdId: 8-bits ZCL command number +// - clusterSpecific: boolean, is the message general cluster or cluster specific, used to create the FC byte of ZCL +// - msg: pointer to byte array, payload of ZCL message (len is following), ignored if nullptr +// - len: length of the 'msg' payload +// - needResponse: boolean, true = we ask the target to respond, false = the target should not respond +// - transacId: 8-bits, transation id of message (should be incremented at each message), used both for Zigbee message number and ZCL message number +// Returns: None +// +void ZigbeeZCLSend_Raw(uint16_t shortaddr, uint16_t groupaddr, uint16_t clusterId, uint8_t endpoint, uint8_t cmdId, bool clusterSpecific, uint16_t manuf, const uint8_t *msg, size_t len, bool needResponse, uint8_t transacId) { + +#ifdef USE_ZIGBEE_ZNP + SBuffer buf(32+len); + buf.add8(Z_SREQ | Z_AF); // 24 + buf.add8(AF_DATA_REQUEST_EXT); // 02 + if (BAD_SHORTADDR == shortaddr) { // if no shortaddr we assume group address + buf.add8(Z_Addr_Group); // 01 + buf.add64(groupaddr); // group address, only 2 LSB, upper 6 MSB are discarded + buf.add8(0xFF); // dest endpoint is not used for group addresses + } else { + buf.add8(Z_Addr_ShortAddress); // 02 + buf.add64(shortaddr); // dest address, only 2 LSB, upper 6 MSB are discarded + buf.add8(endpoint); // dest endpoint + } + buf.add16(0x0000); // dest Pan ID, 0x0000 = intra-pan + buf.add8(0x01); // source endpoint + buf.add16(clusterId); + buf.add8(transacId); // transacId + buf.add8(0x30); // 30 options + buf.add8(0x1E); // 1E radius + + buf.add16(3 + len + (manuf ? 2 : 0)); + buf.add8((needResponse ? 0x00 : 0x10) | (clusterSpecific ? 0x01 : 0x00) | (manuf ? 0x04 : 0x00)); // Frame Control Field + if (manuf) { + buf.add16(manuf); // add Manuf Id if not null + } + buf.add8(transacId); // Transaction Sequance Number + buf.add8(cmdId); + if (len > 0) { + buf.addBuffer(msg, len); // add the payload + } + + ZigbeeZNPSend(buf.getBuffer(), buf.len()); +#endif // USE_ZIGBEE_ZNP + +#ifdef USE_ZIGBEE_EZSP + SBuffer buf(32+len); + + if (BAD_SHORTADDR != shortaddr) { + // send unicast message to an address + buf.add16(EZSP_sendUnicast); // 3400 + buf.add8(EMBER_OUTGOING_DIRECT); // 00 + buf.add16(shortaddr); // dest addr + // ApsFrame + buf.add16(Z_PROF_HA); // Home Automation profile + buf.add16(clusterId); // cluster + buf.add8(0x01); // srcEp + buf.add8(endpoint); // dstEp + buf.add16(EMBER_APS_OPTION_ENABLE_ROUTE_DISCOVERY | EMBER_APS_OPTION_RETRY); // APS frame + buf.add16(groupaddr); // groupId + buf.add8(transacId); + // end of ApsFrame + buf.add8(0x01); // tag TODO + + buf.add8(3 + len + (manuf ? 2 : 0)); + buf.add8((needResponse ? 0x00 : 0x10) | (clusterSpecific ? 0x01 : 0x00) | (manuf ? 0x04 : 0x00)); // Frame Control Field + if (manuf) { + buf.add16(manuf); // add Manuf Id if not null + } + buf.add8(transacId); // Transaction Sequance Number + buf.add8(cmdId); + if (len > 0) { + buf.addBuffer(msg, len); // add the payload + } + } else { + // send broadcast group address, aka groupcast + buf.add16(EZSP_sendMulticast); // 3800 + // ApsFrame + buf.add16(Z_PROF_HA); // Home Automation profile + buf.add16(clusterId); // cluster + buf.add8(0x01); // srcEp + buf.add8(endpoint); // broadcast endpoint for groupcast + buf.add16(EMBER_APS_OPTION_ENABLE_ROUTE_DISCOVERY | EMBER_APS_OPTION_RETRY); // APS frame + buf.add16(groupaddr); // groupId + buf.add8(transacId); + // end of ApsFrame + buf.add8(0); // hops, 0x00 = EMBER_MAX_HOPS + buf.add8(7); // nonMemberRadius, 7 = infinite + buf.add8(0x01); // tag TODO + + buf.add8(3 + len + (manuf ? 2 : 0)); + buf.add8((needResponse ? 0x00 : 0x10) | (clusterSpecific ? 0x01 : 0x00) | (manuf ? 0x04 : 0x00)); // Frame Control Field + if (manuf) { + buf.add16(manuf); // add Manuf Id if not null + } + buf.add8(transacId); // Transaction Sequance Number + buf.add8(cmdId); + if (len > 0) { + buf.addBuffer(msg, len); // add the payload + } + } + + ZigbeeEZSPSendCmd(buf.buf(), buf.len(), true); +#endif // USE_ZIGBEE_EZSP +} + +#endif // USE_ZIGBEE diff --git a/tasmota/xdrv_23_zigbee_A_impl.ino b/tasmota/xdrv_23_zigbee_A_impl.ino new file mode 100644 index 000000000..e46d847eb --- /dev/null +++ b/tasmota/xdrv_23_zigbee_A_impl.ino @@ -0,0 +1,1253 @@ +/* + xdrv_23_zigbee.ino - zigbee support for Tasmota + + Copyright (C) 2020 Theo Arends and Stephan Hadinger + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifdef USE_ZIGBEE + +#define XDRV_23 23 + +const char kZbCommands[] PROGMEM = D_PRFX_ZB "|" // prefix +#ifdef USE_ZIGBEE_ZNP + D_CMND_ZIGBEEZNPSEND "|" D_CMND_ZIGBEEZNPRECEIVE "|" +#endif // USE_ZIGBEE_ZNP +#ifdef USE_ZIGBEE_EZSP + D_CMND_ZIGBEE_EZSP_SEND "|" D_CMND_ZIGBEE_EZSP_RECEIVE "|" D_CMND_ZIGBEE_EZSP_LISTEN "|" +#endif // USE_ZIGBEE_EZSP + D_CMND_ZIGBEE_PERMITJOIN "|" + D_CMND_ZIGBEE_STATUS "|" D_CMND_ZIGBEE_RESET "|" D_CMND_ZIGBEE_SEND "|" D_CMND_ZIGBEE_PROBE "|" + D_CMND_ZIGBEE_FORGET "|" D_CMND_ZIGBEE_SAVE "|" D_CMND_ZIGBEE_NAME "|" + D_CMND_ZIGBEE_BIND "|" D_CMND_ZIGBEE_UNBIND "|" D_CMND_ZIGBEE_PING "|" D_CMND_ZIGBEE_MODELID "|" + D_CMND_ZIGBEE_LIGHT "|" D_CMND_ZIGBEE_RESTORE "|" D_CMND_ZIGBEE_BIND_STATE "|" + D_CMND_ZIGBEE_CONFIG + ; + +void (* const ZigbeeCommand[])(void) PROGMEM = { +#ifdef USE_ZIGBEE_ZNP + &CmndZbZNPSend, &CmndZbZNPReceive, +#endif // USE_ZIGBEE_ZNP +#ifdef USE_ZIGBEE_EZSP + &CmndZbEZSPSend, &CmndZbEZSPReceive, &CmndZbEZSPListen, +#endif // USE_ZIGBEE_EZSP + &CmndZbPermitJoin, + &CmndZbStatus, &CmndZbReset, &CmndZbSend, &CmndZbProbe, + &CmndZbForget, &CmndZbSave, &CmndZbName, + &CmndZbBind, &CmndZbUnbind, &CmndZbPing, &CmndZbModelId, + &CmndZbLight, &CmndZbRestore, &CmndZbBindState, + &CmndZbConfig, + }; + +/********************************************************************************************/ + +// Initialize internal structures +void ZigbeeInit(void) +{ + // Check if settings in Flash are set + if (0 == Settings.zb_channel) { + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "Initializing Zigbee parameters from defaults")); + Settings.zb_ext_panid = USE_ZIGBEE_EXTPANID; + Settings.zb_precfgkey_l = USE_ZIGBEE_PRECFGKEY_L; + Settings.zb_precfgkey_h = USE_ZIGBEE_PRECFGKEY_H; + Settings.zb_pan_id = USE_ZIGBEE_PANID; + Settings.zb_channel = USE_ZIGBEE_CHANNEL; + Settings.zb_txradio_dbm = USE_ZIGBEE_TXRADIO_DBM; + } + + // update commands with the current settings +#ifdef USE_ZIGBEE_ZNP + ZNP_UpdateConfig(Settings.zb_channel, Settings.zb_pan_id, Settings.zb_ext_panid, Settings.zb_precfgkey_l, Settings.zb_precfgkey_h); +#endif +#ifdef USE_ZIGBEE_EZSP + EZ_UpdateConfig(Settings.zb_channel, Settings.zb_pan_id, Settings.zb_ext_panid, Settings.zb_precfgkey_l, Settings.zb_precfgkey_h, Settings.zb_txradio_dbm); +#endif + + ZigbeeInitSerial(); +} + +/*********************************************************************************************\ + * Commands +\*********************************************************************************************/ + +uint32_t strToUInt(const JsonVariant &val) { + // if the string starts with 0x, it is considered Hex, otherwise it is an int + if (val.is()) { + return val.as(); + } else { + if (val.is()) { + String sval = val.as(); + return strtoull(sval.c_str(), nullptr, 0); + } + } + return 0; // couldn't parse anything +} + +#ifdef USE_ZIGBEE_ZNP +// Do a factory reset of the CC2530 +const unsigned char ZIGBEE_FACTORY_RESET[] PROGMEM = + { Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_STARTUP_OPTION, 0x01 /* len */, 0x01 /* STARTOPT_CLEAR_CONFIG */}; +//"2605030101"; // Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_STARTUP_OPTION, 0x01 len, 0x01 STARTOPT_CLEAR_CONFIG +#endif // USE_ZIGBEE_ZNP + +void CmndZbReset(void) { + if (ZigbeeSerial) { + switch (XdrvMailbox.payload) { + case 1: +#ifdef USE_ZIGBEE_ZNP + ZigbeeZNPSend(ZIGBEE_FACTORY_RESET, sizeof(ZIGBEE_FACTORY_RESET)); +#endif // USE_ZIGBEE_ZNP + eraseZigbeeDevices(); + restart_flag = 2; + ResponseCmndChar_P(PSTR(D_JSON_ZIGBEE_CC2530 " " D_JSON_RESET_AND_RESTARTING)); + break; + default: + ResponseCmndChar_P(PSTR(D_JSON_ONE_TO_RESET)); + } + } +} + +/********************************************************************************************/ +// +// High-level function +// Send a command specified as an HEX string for the workload. +// The target endpoint is computed if zero, i.e. sent to the first known endpoint of the device. +// If cluster-specific, a timer may be set calling `zigbeeSetCommandTimer()`, for ex to coalesce attributes or Aqara presence sensor +// +// Inputs: +// - shortaddr: 16-bits short address, or 0x0000 if group address +// - groupaddr: 16-bits group address, or 0x0000 if unicast using shortaddr +// - endpoint: 8-bits target endpoint (source is always 0x01), if 0x00, it will be guessed from ZbStatus information (basically the first endpoint of the device) +// - clusterSpecific: boolean, is the message general cluster or cluster specific, used to create the FC byte of ZCL +// - clusterIf: 16-bits cluster number +// - param: pointer to HEX string for payload, should not be nullptr +// Returns: None +// +void zigbeeZCLSendStr(uint16_t shortaddr, uint16_t groupaddr, uint8_t endpoint, bool clusterSpecific, uint16_t manuf, + uint16_t cluster, uint8_t cmd, const char *param) { + size_t size = param ? strlen(param) : 0; + SBuffer buf((size+2)/2); // actual bytes buffer for data + + if (param) { + while (*param) { + uint8_t code = parseHex_P(¶m, 2); + buf.add8(code); + } + } + + if ((0 == endpoint) && (BAD_SHORTADDR != shortaddr)) { + // endpoint is not specified, let's try to find it from shortAddr, unless it's a group address + endpoint = zigbee_devices.findFirstEndpoint(shortaddr); + //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZbSend: guessing endpoint 0x%02X"), endpoint); + } + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZbSend: shortaddr 0x%04X, groupaddr 0x%04X, cluster 0x%04X, endpoint 0x%02X, cmd 0x%02X, data %s"), + shortaddr, groupaddr, cluster, endpoint, cmd, param); + + if ((0 == endpoint) && (BAD_SHORTADDR != shortaddr)) { // endpoint null is ok for group address + AddLog_P2(LOG_LEVEL_INFO, PSTR("ZbSend: unspecified endpoint")); + return; + } + + // everything is good, we can send the command + ZigbeeZCLSend_Raw(shortaddr, groupaddr, cluster, endpoint, cmd, clusterSpecific, manuf, buf.getBuffer(), buf.len(), true, zigbee_devices.getNextSeqNumber(shortaddr)); + // now set the timer, if any, to read back the state later + if (clusterSpecific) { + zigbeeSetCommandTimer(shortaddr, groupaddr, cluster, endpoint); + } +} + +// Parse "Report", "Write" or "Response" attribute +// Operation is one of: ZCL_REPORT_ATTRIBUTES (0x0A), ZCL_WRITE_ATTRIBUTES (0x02) or ZCL_READ_ATTRIBUTES_RESPONSE (0x01) +void ZbSendReportWrite(const JsonObject &val_pubwrite, uint16_t device, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint16_t manuf, uint32_t operation) { + SBuffer buf(200); // buffer to store the binary output of attibutes + + if (nullptr == XdrvMailbox.command) { + XdrvMailbox.command = (char*) ""; // prevent a crash when calling ReponseCmndChar and there was no previous command + } + + // iterate on keys + for (JsonObject::const_iterator it=val_pubwrite.begin(); it!=val_pubwrite.end(); ++it) { + const char *key = it->key; + const JsonVariant &value = it->value; + + uint16_t attr_id = 0xFFFF; + uint16_t cluster_id = 0xFFFF; + uint8_t type_id = Znodata; + int16_t multiplier = 1; // multiplier to adjust the key value + float val_f = 0.0f; // alternative value if multiplier is used + + // check if the name has the format "XXXX/YYYY" where XXXX is the cluster, YYYY the attribute id + // alternative "XXXX/YYYY%ZZ" where ZZ is the type (for unregistered attributes) + char * delimiter = strchr(key, '/'); + char * delimiter2 = strchr(key, '%'); + if (delimiter) { + cluster_id = strtoul(key, &delimiter, 16); + if (!delimiter2) { + attr_id = strtoul(delimiter+1, nullptr, 16); + } else { + attr_id = strtoul(delimiter+1, &delimiter2, 16); + type_id = strtoul(delimiter2+1, nullptr, 16); + } + } + // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("cluster_id = 0x%04X, attr_id = 0x%04X"), cluster_id, attr_id); + + // do we already know the type, i.e. attribute and cluster are also known + if (Znodata == type_id) { + // scan attributes to find by name, and retrieve type + for (uint32_t i = 0; i < ARRAY_SIZE(Z_PostProcess); i++) { + const Z_AttributeConverter *converter = &Z_PostProcess[i]; + bool match = false; + uint16_t local_attr_id = pgm_read_word(&converter->attribute); + uint16_t local_cluster_id = CxToCluster(pgm_read_byte(&converter->cluster_short)); + uint8_t local_type_id = pgm_read_byte(&converter->type); + int16_t local_multiplier = pgm_read_word(&converter->multiplier); + // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Try cluster = 0x%04X, attr = 0x%04X, type_id = 0x%02X"), local_cluster_id, local_attr_id, local_type_id); + + if (delimiter) { + if ((cluster_id == local_cluster_id) && (attr_id == local_attr_id)) { + type_id = local_type_id; + break; + } + } else if (converter->name) { + // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Comparing '%s' with '%s'"), attr_name, converter->name); + if (0 == strcasecmp_P(key, converter->name)) { + // match + cluster_id = local_cluster_id; + attr_id = local_attr_id; + type_id = local_type_id; + multiplier = local_multiplier; + break; + } + } + } + } + + // Buffer ready, do some sanity checks + // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("cluster_id = 0x%04X, attr_id = 0x%04X, type_id = 0x%02X"), cluster_id, attr_id, type_id); + if ((0xFFFF == attr_id) || (0xFFFF == cluster_id)) { + Response_P(PSTR("{\"%s\":\"%s'%s'\"}"), XdrvMailbox.command, PSTR("Unknown attribute "), key); + return; + } + if (Znodata == type_id) { + Response_P(PSTR("{\"%s\":\"%s'%s'\"}"), XdrvMailbox.command, PSTR("Unknown attribute type for attribute "), key); + return; + } + + if (0xFFFF == cluster) { + cluster = cluster_id; // set the cluster for this packet + } else if (cluster != cluster_id) { + ResponseCmndChar_P(PSTR("No more than one cluster id per command")); + return; + } + // apply multiplier if needed + bool use_val = true; + if ((0 != multiplier) && (1 != multiplier)) { + val_f = value; + if (multiplier > 0) { // inverse of decoding + val_f = val_f / multiplier; + } else { + val_f = val_f * (-multiplier); + } + use_val = false; + } + // push the value in the buffer + int32_t res = encodeSingleAttribute(buf, use_val ? value : *(const JsonVariant*)nullptr, val_f, attr_id, type_id, operation == ZCL_READ_ATTRIBUTES_RESPONSE); // force status if Reponse + if (res < 0) { + Response_P(PSTR("{\"%s\":\"%s'%s' 0x%02X\"}"), XdrvMailbox.command, PSTR("Unsupported attribute type "), key, type_id); + return; + } + } + + // did we have any attribute? + if (0 == buf.len()) { + ResponseCmndChar_P(PSTR("No attribute in list")); + return; + } + + // all good, send the packet + ZigbeeZCLSend_Raw(device, groupaddr, cluster, endpoint, operation, false /* not cluster specific */, manuf, buf.getBuffer(), buf.len(), false /* noresponse */, zigbee_devices.getNextSeqNumber(device)); + ResponseCmndDone(); +} + +// Parse the "Send" attribute and send the command +void ZbSendSend(const JsonVariant &val_cmd, uint16_t device, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint16_t manuf) { + uint8_t cmd = 0; + String cmd_str = ""; // the actual low-level command, either specified or computed + const char *cmd_s; // pointer to payload string + bool clusterSpecific = true; + + static char delim[] = ", "; // delimiters for parameters + // probe the type of the argument + // If JSON object, it's high level commands + // If String, it's a low level command + if (val_cmd.is()) { + // we have a high-level command + const JsonObject &cmd_obj = val_cmd.as(); + int32_t cmd_size = cmd_obj.size(); + if (cmd_size > 1) { + Response_P(PSTR("Only 1 command allowed (%d)"), cmd_size); + return; + } else if (1 == cmd_size) { + // We have exactly 1 command, parse it + JsonObject::const_iterator it = cmd_obj.begin(); // just get the first key/value + String key = it->key; + const JsonVariant& value = it->value; + uint32_t x = 0, y = 0, z = 0; + uint16_t cmd_var; + uint16_t local_cluster_id; + + const __FlashStringHelper* tasmota_cmd = zigbeeFindCommand(key.c_str(), &local_cluster_id, &cmd_var); + if (tasmota_cmd) { + cmd_str = tasmota_cmd; + } else { + Response_P(PSTR("Unrecognized zigbee command: %s"), key.c_str()); + return; + } + // check cluster + if (0xFFFF == cluster) { + cluster = local_cluster_id; + } else if (cluster != local_cluster_id) { + ResponseCmndChar_P(PSTR("No more than one cluster id per command")); + return; + } + + // parse the JSON value, depending on its type fill in x,y,z + if (value.is()) { + x = value.as() ? 1 : 0; + } else if (value.is()) { + x = value.as(); + } else { + // if non-bool or non-int, trying char* + const char *s_const = value.as(); + if (s_const != nullptr) { + char s[strlen(s_const)+1]; + strcpy(s, s_const); + if ((nullptr != s) && (0x00 != *s)) { // ignore any null or empty string, could represent 'null' json value + char *sval = strtok(s, delim); + if (sval) { + x = ZigbeeAliasOrNumber(sval); + sval = strtok(nullptr, delim); + if (sval) { + y = ZigbeeAliasOrNumber(sval); + sval = strtok(nullptr, delim); + if (sval) { + z = ZigbeeAliasOrNumber(sval); + } + } + } + } + } + } + + //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZbSend: command_template = %s"), cmd_str.c_str()); + if (0xFF == cmd_var) { // if command number is a variable, replace it with x + cmd = x; + x = y; // and shift other variables + y = z; + } else { + cmd = cmd_var; // or simply copy the cmd number + } + cmd_str = zigbeeCmdAddParams(cmd_str.c_str(), x, y, z); // fill in parameters + //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZbSend: command_final = %s"), cmd_str.c_str()); + cmd_s = cmd_str.c_str(); + } else { + // we have zero command, pass through until last error for missing command + } + } else if (val_cmd.is()) { + // low-level command + cmd_str = val_cmd.as(); + // Now parse the string to extract cluster, command, and payload + // Parse 'cmd' in the form "AAAA_BB/CCCCCCCC" or "AAAA!BB/CCCCCCCC" + // where AA is the cluster number, BBBB the command number, CCCC... the payload + // First delimiter is '_' for a global command, or '!' for a cluster specific command + const char * data = cmd_str.c_str(); + uint16_t local_cluster_id = parseHex(&data, 4); + + // check cluster + if (0xFFFF == cluster) { + cluster = local_cluster_id; + } else if (cluster != local_cluster_id) { + ResponseCmndChar_P(PSTR("No more than one cluster id per command")); + return; + } + + // delimiter + if (('_' == *data) || ('!' == *data)) { + if ('_' == *data) { clusterSpecific = false; } + data++; + } else { + ResponseCmndChar_P(PSTR("Wrong delimiter for payload")); + return; + } + // parse cmd number + cmd = parseHex(&data, 2); + + // move to end of payload + // delimiter is optional + if ('/' == *data) { data++; } // skip delimiter + + cmd_s = data; + } else { + // we have an unsupported command type, just ignore it and fallback to missing command + } + + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZigbeeZCLSend device: 0x%04X, group: 0x%04X, endpoint:%d, cluster:0x%04X, cmd:0x%02X, send:\"%s\""), + device, groupaddr, endpoint, cluster, cmd, cmd_s); + zigbeeZCLSendStr(device, groupaddr, endpoint, clusterSpecific, manuf, cluster, cmd, cmd_s); + ResponseCmndDone(); +} + + +// Parse the "Send" attribute and send the command +void ZbSendRead(const JsonVariant &val_attr, uint16_t device, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint16_t manuf) { + // ZbSend {"Device":"0xF289","Cluster":0,"Endpoint":3,"Read":5} + // ZbSend {"Device":"0xF289","Cluster":"0x0000","Endpoint":"0x0003","Read":"0x0005"} + // ZbSend {"Device":"0xF289","Cluster":0,"Endpoint":3,"Read":[5,6,7,4]} + // ZbSend {"Device":"0xF289","Endpoint":3,"Read":{"ModelId":true}} + // ZbSend {"Device":"0xF289","Read":{"ModelId":true}} + + // params + size_t attrs_len = 0; + uint8_t* attrs = nullptr; // empty string is valid + + uint16_t val = strToUInt(val_attr); + if (val_attr.is()) { + const JsonArray& attr_arr = val_attr.as(); + attrs_len = attr_arr.size() * 2; + attrs = new uint8_t[attrs_len]; + + uint32_t i = 0; + for (auto value : attr_arr) { + uint16_t val = strToUInt(value); + attrs[i++] = val & 0xFF; + attrs[i++] = val >> 8; + } + } else if (val_attr.is()) { + const JsonObject& attr_obj = val_attr.as(); + attrs_len = attr_obj.size() * 2; + attrs = new uint8_t[attrs_len]; + uint32_t actual_attr_len = 0; + + // iterate on keys + for (JsonObject::const_iterator it=attr_obj.begin(); it!=attr_obj.end(); ++it) { + const char *key = it->key; + // const JsonVariant &value = it->value; // we don't need the value here, only keys are relevant + + bool found = false; + // scan attributes to find by name, and retrieve type + for (uint32_t i = 0; i < ARRAY_SIZE(Z_PostProcess); i++) { + const Z_AttributeConverter *converter = &Z_PostProcess[i]; + bool match = false; + uint16_t local_attr_id = pgm_read_word(&converter->attribute); + uint16_t local_cluster_id = CxToCluster(pgm_read_byte(&converter->cluster_short)); + // uint8_t local_type_id = pgm_read_byte(&converter->type); + + if ((converter->name) && (0 == strcasecmp_P(key, converter->name))) { + // match name + // check if there is a conflict with cluster + // TODO + attrs[actual_attr_len++] = local_attr_id & 0xFF; + attrs[actual_attr_len++] = local_attr_id >> 8; + found = true; + // check cluster + if (0xFFFF == cluster) { + cluster = local_cluster_id; + } else if (cluster != local_cluster_id) { + ResponseCmndChar_P(PSTR("No more than one cluster id per command")); + if (attrs) { delete[] attrs; } + return; + } + break; // found, exit loop + } + } + if (!found) { + AddLog_P2(LOG_LEVEL_INFO, PSTR("ZIG: Unknown attribute name (ignored): %s"), key); + } + } + + attrs_len = actual_attr_len; + } else { + attrs_len = 2; + attrs = new uint8_t[attrs_len]; + attrs[0] = val & 0xFF; // little endian + attrs[1] = val >> 8; + } + + if (attrs_len > 0) { + ZigbeeZCLSend_Raw(device, groupaddr, cluster, endpoint, ZCL_READ_ATTRIBUTES, false, manuf, attrs, attrs_len, true /* we do want a response */, zigbee_devices.getNextSeqNumber(device)); + ResponseCmndDone(); + } else { + ResponseCmndChar_P(PSTR("Missing parameters")); + } + + if (attrs) { delete[] attrs; } +} + +// +// Command `ZbSend` +// +// Examples: +// ZbSend {"Device":"0x0000","Endpoint":1,"Write":{"0006/0000":0}} +// ZbSend {"Device":"0x0000","Endpoint":1,"Write":{"Power":0}} +// ZbSend {"Device":"0x0000","Endpoint":1,"Write":{"AqaraRotate":0}} +// ZbSend {"Device":"0x0000","Endpoint":1,"Write":{"AqaraRotate":12.5}} +// ZbSend {"Device":"0x0000","Endpoint":1,"Write":{"006/0000%39":12.5}} +// ZbSend {"Device":"0x0000","Endpoint":1,"Write":{"AnalogInApplicationType":1000000}} +// ZbSend {"Device":"0x0000","Endpoint":1,"Write":{"TimeZone":-1000000}} +// ZbSend {"Device":"0x0000","Endpoint":1,"Write":{"Manufacturer":"Tasmota","ModelId":"Tasmota Z2T Router"}} +void CmndZbSend(void) { + // ZbSend { "device":"0x1234", "endpoint":"0x03", "send":{"Power":1} } + // ZbSend { "device":"0x1234", "endpoint":"0x03", "send":{"Power":"3"} } + // ZbSend { "device":"0x1234", "endpoint":"0x03", "send":{"Power":"0xFF"} } + // ZbSend { "device":"0x1234", "endpoint":"0x03", "send":{"Power":null} } + // ZbSend { "device":"0x1234", "endpoint":"0x03", "send":{"Power":false} } + // ZbSend { "device":"0x1234", "endpoint":"0x03", "send":{"Power":true} } + // ZbSend { "device":"0x1234", "endpoint":"0x03", "send":{"Power":"true"} } + // ZbSend { "device":"0x1234", "endpoint":"0x03", "send":{"ShutterClose":null} } + // ZbSend { "device":"0x1234", "endpoint":"0x03", "send":{"Power":1} } + // ZbSend { "device":"0x1234", "endpoint":"0x03", "send":{"Color":"1,2"} } + // ZbSend { "device":"0x1234", "endpoint":"0x03", "send":{"Color":"0x1122,0xFFEE"} } + if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; } + DynamicJsonBuffer jsonBuf; + const JsonObject &json = jsonBuf.parseObject((const char*) XdrvMailbox.data); + if (!json.success()) { ResponseCmndChar_P(PSTR(D_JSON_INVALID_JSON)); return; } + + // params + uint16_t device = BAD_SHORTADDR; // BAD_SHORTADDR is broadcast, so considered invalid + uint16_t groupaddr = 0x0000; // group address valid only if device == BAD_SHORTADDR + uint16_t cluster = 0xFFFF; // no default + uint8_t endpoint = 0x00; // 0x00 is invalid for the dst endpoint + uint16_t manuf = 0x0000; // Manuf Id in ZCL frame + + + // parse "Device" and "Group" + const JsonVariant &val_device = GetCaseInsensitive(json, PSTR(D_CMND_ZIGBEE_DEVICE)); + if (nullptr != &val_device) { + device = zigbee_devices.parseDeviceParam(val_device.as()); + if (BAD_SHORTADDR == device) { ResponseCmndChar_P(PSTR("Invalid parameter")); return; } + } + if (BAD_SHORTADDR == device) { // if not found, check if we have a group + const JsonVariant &val_group = GetCaseInsensitive(json, PSTR(D_CMND_ZIGBEE_GROUP)); + if (nullptr != &val_group) { + groupaddr = strToUInt(val_group); + } else { // no device nor group + ResponseCmndChar_P(PSTR("Unknown device")); + return; + } + } + // from here, either device has a device shortaddr, or if BAD_SHORTADDR then use group address + // Note: groupaddr == 0 is valid + + // read other parameters + const JsonVariant &val_cluster = GetCaseInsensitive(json, PSTR(D_CMND_ZIGBEE_CLUSTER)); + if (nullptr != &val_cluster) { cluster = strToUInt(val_cluster); } + const JsonVariant &val_endpoint = GetCaseInsensitive(json, PSTR(D_CMND_ZIGBEE_ENDPOINT)); + if (nullptr != &val_endpoint) { endpoint = strToUInt(val_endpoint); } + const JsonVariant &val_manuf = GetCaseInsensitive(json, PSTR(D_CMND_ZIGBEE_MANUF)); + if (nullptr != &val_manuf) { manuf = strToUInt(val_manuf); } + + // infer endpoint + if (BAD_SHORTADDR == device) { + endpoint = 0xFF; // endpoint not used for group addresses, so use a dummy broadcast endpoint + } else if (0 == endpoint) { // if it was not already specified, try to guess it + endpoint = zigbee_devices.findFirstEndpoint(device); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ZIG: guessing endpoint %d"), endpoint); + } + if (0 == endpoint) { // after this, if it is still zero, then it's an error + ResponseCmndChar_P(PSTR("Missing endpoint")); + return; + } + // from here endpoint is valid and non-zero + // cluster may be already specified or 0xFFFF + + const JsonVariant &val_cmd = GetCaseInsensitive(json, PSTR(D_CMND_ZIGBEE_SEND)); + const JsonVariant &val_read = GetCaseInsensitive(json, PSTR(D_CMND_ZIGBEE_READ)); + const JsonVariant &val_write = GetCaseInsensitive(json, PSTR(D_CMND_ZIGBEE_WRITE)); + const JsonVariant &val_publish = GetCaseInsensitive(json, PSTR(D_CMND_ZIGBEE_REPORT)); + const JsonVariant &val_response = GetCaseInsensitive(json, PSTR(D_CMND_ZIGBEE_RESPONSE)); + uint32_t multi_cmd = (nullptr != &val_cmd) + (nullptr != &val_read) + (nullptr != &val_write) + (nullptr != &val_publish)+ (nullptr != &val_response); + if (multi_cmd > 1) { + ResponseCmndChar_P(PSTR("Can only have one of: 'Send', 'Read', 'Write', 'Report' or 'Reponse'")); + return; + } + // from here we have one and only one command + + if (nullptr != &val_cmd) { + // "Send":{...commands...} + // we accept either a string or a JSON object + ZbSendSend(val_cmd, device, groupaddr, cluster, endpoint, manuf); + } else if (nullptr != &val_read) { + // "Read":{...attributes...}, "Read":attribute or "Read":[...attributes...] + // we accept eitehr a number, a string, an array of numbers/strings, or a JSON object + ZbSendRead(val_read, device, groupaddr, cluster, endpoint, manuf); + } else if (nullptr != &val_write) { + // only KSON object + if (!val_write.is()) { + ResponseCmndChar_P(PSTR("Missing parameters")); + return; + } + // "Write":{...attributes...} + ZbSendReportWrite(val_write, device, groupaddr, cluster, endpoint, manuf, ZCL_WRITE_ATTRIBUTES); + } else if (nullptr != &val_publish) { + // "Report":{...attributes...} + // only KSON object + if (!val_publish.is()) { + ResponseCmndChar_P(PSTR("Missing parameters")); + return; + } + ZbSendReportWrite(val_publish, device, groupaddr, cluster, endpoint, manuf, ZCL_REPORT_ATTRIBUTES); + } else if (nullptr != &val_response) { + // "Report":{...attributes...} + // only KSON object + if (!val_response.is()) { + ResponseCmndChar_P(PSTR("Missing parameters")); + return; + } + ZbSendReportWrite(val_response, device, groupaddr, cluster, endpoint, manuf, ZCL_READ_ATTRIBUTES_RESPONSE); + } else { + Response_P(PSTR("Missing zigbee 'Send', 'Write', 'Report' or 'Response'")); + return; + } +} + +// +// Command `ZbBind` +// +void ZbBindUnbind(bool unbind) { // false = bind, true = unbind + // ZbBind {"Device":"", "Endpoint":, "Cluster":, "ToDevice":"", "ToEndpoint":, "ToGroup": } + // ZbUnbind {"Device":"", "Endpoint":, "Cluster":, "ToDevice":"", "ToEndpoint":, "ToGroup": } + + // local endpoint is always 1, IEEE addresses are calculated + if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; } + DynamicJsonBuffer jsonBuf; + const JsonObject &json = jsonBuf.parseObject((const char*) XdrvMailbox.data); + if (!json.success()) { ResponseCmndChar_P(PSTR(D_JSON_INVALID_JSON)); return; } + + // params + uint16_t srcDevice = BAD_SHORTADDR; // BAD_SHORTADDR is broadcast, so considered invalid + uint16_t dstDevice = BAD_SHORTADDR; // BAD_SHORTADDR is broadcast, so considered invalid + uint64_t dstLongAddr = 0; + uint8_t endpoint = 0x00; // 0x00 is invalid for the src endpoint + uint8_t toendpoint = 0x00; // 0x00 is invalid for the dst endpoint + uint16_t toGroup = 0x0000; // group address + uint16_t cluster = 0; // 0xFFFF is invalid + uint32_t group = 0xFFFFFFFF; // 16 bits values, otherwise 0xFFFFFFFF is unspecified + + // Information about source device: "Device", "Endpoint", "Cluster" + // - the source endpoint must have a known IEEE address + const JsonVariant &val_device = GetCaseInsensitive(json, PSTR(D_CMND_ZIGBEE_DEVICE)); + if (nullptr != &val_device) { + srcDevice = zigbee_devices.parseDeviceParam(val_device.as()); + } + if ((nullptr == &val_device) || (BAD_SHORTADDR == srcDevice)) { ResponseCmndChar_P(PSTR("Unknown source device")); return; } + // check if IEEE address is known + uint64_t srcLongAddr = zigbee_devices.getDeviceLongAddr(srcDevice); + if (0 == srcLongAddr) { ResponseCmndChar_P(PSTR("Unknown source IEEE address")); return; } + // look for source endpoint + const JsonVariant &val_endpoint = GetCaseInsensitive(json, PSTR(D_CMND_ZIGBEE_ENDPOINT)); + if (nullptr != &val_endpoint) { endpoint = strToUInt(val_endpoint); } + // look for source cluster + const JsonVariant &val_cluster = GetCaseInsensitive(json, PSTR(D_CMND_ZIGBEE_CLUSTER)); + if (nullptr != &val_cluster) { cluster = strToUInt(val_cluster); } + + // Either Device address + // In this case the following parameters are mandatory + // - "ToDevice" and the device must have a known IEEE address + // - "ToEndpoint" + const JsonVariant &dst_device = GetCaseInsensitive(json, PSTR("ToDevice")); + if (nullptr != &dst_device) { + dstDevice = zigbee_devices.parseDeviceParam(dst_device.as()); + if (BAD_SHORTADDR == dstDevice) { ResponseCmndChar_P(PSTR("Invalid parameter")); return; } + if (0x0000 == dstDevice) { + dstLongAddr = localIEEEAddr; + } else { + dstLongAddr = zigbee_devices.getDeviceLongAddr(dstDevice); + } + if (0 == dstLongAddr) { ResponseCmndChar_P(PSTR("Unknown dest IEEE address")); return; } + + const JsonVariant &val_toendpoint = GetCaseInsensitive(json, PSTR("ToEndpoint")); + if (nullptr != &val_toendpoint) { toendpoint = strToUInt(val_endpoint); } else { toendpoint = endpoint; } + } + + // Or Group Address - we don't need a dstEndpoint in this case + const JsonVariant &to_group = GetCaseInsensitive(json, PSTR("ToGroup")); + if (nullptr != &to_group) { toGroup = strToUInt(to_group); } + + // make sure we don't have conflicting parameters + if (&to_group && dstLongAddr) { ResponseCmndChar_P(PSTR("Cannot have both \"ToDevice\" and \"ToGroup\"")); return; } + if (!&to_group && !dstLongAddr) { ResponseCmndChar_P(PSTR("Missing \"ToDevice\" or \"ToGroup\"")); return; } + +#ifdef USE_ZIGBEE_ZNP + SBuffer buf(34); + buf.add8(Z_SREQ | Z_ZDO); + if (unbind) { + buf.add8(ZDO_UNBIND_REQ); + } else { + buf.add8(ZDO_BIND_REQ); + } + buf.add16(srcDevice); + buf.add64(srcLongAddr); + buf.add8(endpoint); + buf.add16(cluster); + if (dstLongAddr) { + buf.add8(Z_Addr_IEEEAddress); // DstAddrMode - 0x03 = ADDRESS_64_BIT + buf.add64(dstLongAddr); + buf.add8(toendpoint); + } else { + buf.add8(Z_Addr_Group); // DstAddrMode - 0x01 = GROUP_ADDRESS + buf.add16(toGroup); + } + + ZigbeeZNPSend(buf.getBuffer(), buf.len()); +#endif // USE_ZIGBEE_ZNP + +#ifdef USE_ZIGBEE_EZSP + SBuffer buf(24); + + // ZDO message payload (see Zigbee spec 2.4.3.2.2) + buf.add64(srcLongAddr); + buf.add8(endpoint); + buf.add16(cluster); + if (dstLongAddr) { + buf.add8(Z_Addr_IEEEAddress); // DstAddrMode - 0x03 = ADDRESS_64_BIT + buf.add64(dstLongAddr); + buf.add8(toendpoint); + } else { + buf.add8(Z_Addr_Group); // DstAddrMode - 0x01 = GROUP_ADDRESS + buf.add16(toGroup); + } + + EZ_SendZDO(srcDevice, unbind ? ZDO_UNBIND_REQ : ZDO_BIND_REQ, buf.buf(), buf.len()); +#endif // USE_ZIGBEE_EZSP + + ResponseCmndDone(); +} + +// +// Command ZbBind +// +void CmndZbBind(void) { + ZbBindUnbind(false); +} + +// +// Command ZbBind +// +void CmndZbUnbind(void) { + ZbBindUnbind(true); +} + +// +// Command `ZbBindState` +// +void CmndZbBindState(void) { + if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; } + uint16_t shortaddr = zigbee_devices.parseDeviceParam(XdrvMailbox.data); + if (BAD_SHORTADDR == shortaddr) { ResponseCmndChar_P(PSTR("Unknown device")); return; } + +#ifdef USE_ZIGBEE_ZNP + SBuffer buf(10); + buf.add8(Z_SREQ | Z_ZDO); // 25 + buf.add8(ZDO_MGMT_BIND_REQ); // 33 + buf.add16(shortaddr); // shortaddr + buf.add8(0); // StartIndex = 0 + + ZigbeeZNPSend(buf.getBuffer(), buf.len()); +#endif // USE_ZIGBEE_ZNP + + +#ifdef USE_ZIGBEE_EZSP + // ZDO message payload (see Zigbee spec 2.4.3.3.4) + uint8_t buf[] = { 0x00 }; // index = 0 + + EZ_SendZDO(shortaddr, ZDO_Mgmt_Bind_req, buf, sizeof(buf)); +#endif // USE_ZIGBEE_EZSP + + ResponseCmndDone(); +} + +// Probe a specific device to get its endpoints and supported clusters +void CmndZbProbe(void) { + CmndZbProbeOrPing(true); +} + +// +// Common code for `ZbProbe` and `ZbPing` +// +void CmndZbProbeOrPing(boolean probe) { + if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; } + uint16_t shortaddr = zigbee_devices.parseDeviceParam(XdrvMailbox.data); + if (BAD_SHORTADDR == shortaddr) { ResponseCmndChar_P(PSTR("Unknown device")); return; } + + // everything is good, we can send the command + Z_SendIEEEAddrReq(shortaddr); + if (probe) { + Z_SendActiveEpReq(shortaddr); + } + ResponseCmndDone(); +} + +// Ping a device, actually a simplified version of ZbProbe +void CmndZbPing(void) { + CmndZbProbeOrPing(false); +} + +// +// Command `ZbName` +// Specify, read or erase a Friendly Name +// +void CmndZbName(void) { + // Syntax is: + // ZbName , - assign a friendly name + // ZbName - display the current friendly name + // ZbName , - remove friendly name + // + // Where can be: short_addr, long_addr, device_index, friendly_name + + if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; } + + // check if parameters contain a comma ',' + char *p; + char *str = strtok_r(XdrvMailbox.data, ", ", &p); + + // parse first part, + uint16_t shortaddr = zigbee_devices.parseDeviceParam(XdrvMailbox.data, true); // in case of short_addr, it must be already registered + if (BAD_SHORTADDR == shortaddr) { ResponseCmndChar_P(PSTR("Unknown device")); return; } + + if (p == nullptr) { + const char * friendlyName = zigbee_devices.getFriendlyName(shortaddr); + Response_P(PSTR("{\"0x%04X\":{\"" D_JSON_ZIGBEE_NAME "\":\"%s\"}}"), shortaddr, friendlyName ? friendlyName : ""); + } else { + zigbee_devices.setFriendlyName(shortaddr, p); + Response_P(PSTR("{\"0x%04X\":{\"" D_JSON_ZIGBEE_NAME "\":\"%s\"}}"), shortaddr, p); + } +} + +// +// Command `ZbName` +// Specify, read or erase a ModelId, only for debug purposes +// +void CmndZbModelId(void) { + // Syntax is: + // ZbName , - assign a friendly name + // ZbName - display the current friendly name + // ZbName , - remove friendly name + // + // Where can be: short_addr, long_addr, device_index, friendly_name + + if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; } + + // check if parameters contain a comma ',' + char *p; + char *str = strtok_r(XdrvMailbox.data, ", ", &p); + + // parse first part, + uint16_t shortaddr = zigbee_devices.parseDeviceParam(XdrvMailbox.data, true); // in case of short_addr, it must be already registered + if (BAD_SHORTADDR == shortaddr) { ResponseCmndChar_P(PSTR("Unknown device")); return; } + + if (p == nullptr) { + const char * modelId = zigbee_devices.getModelId(shortaddr); + Response_P(PSTR("{\"0x%04X\":{\"" D_JSON_ZIGBEE_MODELID "\":\"%s\"}}"), shortaddr, modelId ? modelId : ""); + } else { + zigbee_devices.setModelId(shortaddr, p); + Response_P(PSTR("{\"0x%04X\":{\"" D_JSON_ZIGBEE_MODELID "\":\"%s\"}}"), shortaddr, p); + } +} + +// +// Command `ZbLight` +// Specify, read or erase a Light type for Hue/Alexa integration +void CmndZbLight(void) { + // Syntax is: + // ZbLight , - assign a bulb type 0-5 + // ZbLight - display the current bulb type and status + // + // Where can be: short_addr, long_addr, device_index, friendly_name + + if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; } + + // check if parameters contain a comma ',' + char *p; + char *str = strtok_r(XdrvMailbox.data, ", ", &p); + + // parse first part, + uint16_t shortaddr = zigbee_devices.parseDeviceParam(XdrvMailbox.data, true); // in case of short_addr, it must be already registered + if (BAD_SHORTADDR == shortaddr) { ResponseCmndChar_P(PSTR("Unknown device")); return; } + + if (p) { + int8_t bulbtype = strtol(p, nullptr, 10); + if (bulbtype > 5) { bulbtype = 5; } + if (bulbtype < -1) { bulbtype = -1; } + zigbee_devices.setHueBulbtype(shortaddr, bulbtype); + } + String dump = zigbee_devices.dumpLightState(shortaddr); + Response_P(PSTR("{\"" D_PRFX_ZB D_CMND_ZIGBEE_LIGHT "\":%s}"), dump.c_str()); + + MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_PRFX_ZB D_CMND_ZIGBEE_LIGHT)); + XdrvRulesProcess(); + ResponseCmndDone(); +} + +// +// Command `ZbForget` +// Remove an old Zigbee device from the list of known devices, use ZigbeeStatus to know all registered devices +// +void CmndZbForget(void) { + if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; } + uint16_t shortaddr = zigbee_devices.parseDeviceParam(XdrvMailbox.data); + if (BAD_SHORTADDR == shortaddr) { ResponseCmndChar_P(PSTR("Unknown device")); return; } + + // everything is good, we can send the command + if (zigbee_devices.removeDevice(shortaddr)) { + ResponseCmndDone(); + } else { + ResponseCmndChar_P(PSTR("Unknown device")); + } +} + +// +// Command `ZbSave` +// Save Zigbee information to flash +// +void CmndZbSave(void) { + if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; } + saveZigbeeDevices(); + ResponseCmndDone(); +} + + +// Restore a device configuration previously exported via `ZbStatus2`` +// Format: +// Either the entire `ZbStatus3` export, or an array or just the device configuration. +// If array, if can contain multiple devices +// ZbRestore {"ZbStatus3":[{"Device":"0x5ADF","Name":"Petite_Lampe","IEEEAddr":"0x90FD9FFFFE03B051","ModelId":"TRADFRI bulb E27 WS opal 980lm","Manufacturer":"IKEA of Sweden","Endpoints":["0x01","0xF2"]}]} +// ZbRestore [{"Device":"0x5ADF","Name":"Petite_Lampe","IEEEAddr":"0x90FD9FFFFE03B051","ModelId":"TRADFRI bulb E27 WS opal 980lm","Manufacturer":"IKEA of Sweden","Endpoints":["0x01","0xF2"]}] +// ZbRestore {"Device":"0x5ADF","Name":"Petite_Lampe","IEEEAddr":"0x90FD9FFFFE03B051","ModelId":"TRADFRI bulb E27 WS opal 980lm","Manufacturer":"IKEA of Sweden","Endpoints":["0x01","0xF2"]} +void CmndZbRestore(void) { + if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; } + DynamicJsonBuffer jsonBuf; + const JsonVariant json_parsed = jsonBuf.parse((const char*) XdrvMailbox.data); // const to force a copy of parameter + const JsonVariant * json = &json_parsed; // root of restore, to be changed if needed + bool success = false; + + // check if parsing succeeded + if (json_parsed.is()) { + success = json_parsed.as().success(); + } else if (json_parsed.is()) { + success = json_parsed.as().success(); + } + if (!success) { ResponseCmndChar_P(PSTR(D_JSON_INVALID_JSON)); return; } + + // Check is root contains `ZbStatus` key, if so change the root + const JsonVariant * zbstatus = &startsWithCaseInsensitive(*json, PSTR("ZbStatus")); + if (nullptr != zbstatus) { + json = zbstatus; + } + + // check if the root is an array + if (json->is()) { + const JsonArray& arr = json->as(); + for (auto elt : arr) { + // call restore on each item + int32_t res = zigbee_devices.deviceRestore(elt); + if (res < 0) { + ResponseCmndChar_P(PSTR("Restore failed")); + return; + } + } + } else if (json->is()) { + int32_t res = zigbee_devices.deviceRestore(*json); + if (res < 0) { + ResponseCmndChar_P(PSTR("Restore failed")); + return; + } + // call restore on a single object + } else { + ResponseCmndChar_P(PSTR("Missing parameters")); + return; + } + ResponseCmndDone(); +} + +// +// Command `ZbPermitJoin` +// Allow or Deny pairing of new Zigbee devices +// +void CmndZbPermitJoin(void) { + if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; } + + uint32_t payload = XdrvMailbox.payload; + uint8_t duration = 60; // default 60s + + if (payload <= 0) { + duration = 0; + } else if (99 == payload) { + duration = 0xFF; // unlimited time + } + +// ZNP Version +#ifdef USE_ZIGBEE_ZNP + uint16_t dstAddr = 0xFFFC; // default addr + + SBuffer buf(34); + buf.add8(Z_SREQ | Z_ZDO); // 25 + buf.add8(ZDO_MGMT_PERMIT_JOIN_REQ); // 36 + buf.add8(0x0F); // AddrMode + buf.add16(0xFFFC); // DstAddr + buf.add8(duration); + buf.add8(0x00); // TCSignificance + + ZigbeeZNPSend(buf.getBuffer(), buf.len()); + +#endif // USE_ZIGBEE_ZNP + +// EZSP VERSION +#ifdef USE_ZIGBEE_EZSP + SBuffer buf(3); + buf.add16(EZSP_permitJoining); + buf.add8(duration); + ZigbeeEZSPSendCmd(buf.getBuffer(), buf.len(), true); +#endif // USE_ZIGBEE_EZSP + + ResponseCmndDone(); +} + +#ifdef USE_ZIGBEE_EZSP +// +// `ZbListen`: add a multicast group to listen to +// Overcomes a current limitation that EZSP only shows messages from multicast groups it listens too +// +// Ex: `ZbListen 99`, `ZbListen2 100` +void CmndZbEZSPListen(void) { + if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; } + + int32_t index = XdrvMailbox.index - 1; // 0 based + int32_t group = XdrvMailbox.payload; + + if (group <= 0) { + group = 0; + } else if (group > 0xFFFF) { + group = 0xFFFF; + } + + SBuffer buf(8); + buf.add16(EZSP_setMulticastTableEntry); + buf.add8(index); + buf.add16(group); // group + buf.add8(0x01); // endpoint + buf.add8(0x00); // network index + ZigbeeEZSPSendCmd(buf.getBuffer(), buf.len(), true); + + ResponseCmndDone(); +} +#endif // USE_ZIGBEE_EZSP + +// +// Command `ZbStatus` +// +void CmndZbStatus(void) { + if (ZigbeeSerial) { + if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; } + uint16_t shortaddr = zigbee_devices.parseDeviceParam(XdrvMailbox.data); + if (XdrvMailbox.payload > 0) { + if (BAD_SHORTADDR == shortaddr) { ResponseCmndChar_P(PSTR("Unknown device")); return; } + } + + String dump = zigbee_devices.dump(XdrvMailbox.index, shortaddr); + Response_P(PSTR("{\"%s%d\":%s}"), XdrvMailbox.command, XdrvMailbox.index, dump.c_str()); + } +} + +// +// Command `ZbConfig` +// +void CmndZbConfig(void) { + // ZbConfig + // ZbConfig {"Channel":11,"PanID":"0x1A63","ExtPanID":"0xCCCCCCCCCCCCCCCC","KeyL":"0x0F0D0B0907050301L","KeyH":"0x0D0C0A0806040200L"} + uint8_t zb_channel = Settings.zb_channel; + uint16_t zb_pan_id = Settings.zb_pan_id; + uint64_t zb_ext_panid = Settings.zb_ext_panid; + uint64_t zb_precfgkey_l = Settings.zb_precfgkey_l; + uint64_t zb_precfgkey_h = Settings.zb_precfgkey_h; + uint8_t zb_txradio_dbm = Settings.zb_txradio_dbm; + + // if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; } + RemoveAllSpaces(XdrvMailbox.data); + if (strlen(XdrvMailbox.data) > 0) { + DynamicJsonBuffer jsonBuf; + const JsonObject &json = jsonBuf.parseObject((const char*) XdrvMailbox.data); + if (!json.success()) { ResponseCmndChar_P(PSTR(D_JSON_INVALID_JSON)); return; } + + // Channel + const JsonVariant &val_channel = GetCaseInsensitive(json, PSTR("Channel")); + if (nullptr != &val_channel) { zb_channel = strToUInt(val_channel); } + if (zb_channel < 11) { zb_channel = 11; } + if (zb_channel > 26) { zb_channel = 26; } + // PanID + const JsonVariant &val_pan_id = GetCaseInsensitive(json, PSTR("PanID")); + if (nullptr != &val_pan_id) { zb_pan_id = strToUInt(val_pan_id); } + // ExtPanID + const JsonVariant &val_ext_pan_id = GetCaseInsensitive(json, PSTR("ExtPanID")); + if (nullptr != &val_ext_pan_id) { zb_ext_panid = strtoull(val_ext_pan_id.as(), nullptr, 0); } + // KeyL + const JsonVariant &val_key_l = GetCaseInsensitive(json, PSTR("KeyL")); + if (nullptr != &val_key_l) { zb_precfgkey_l = strtoull(val_key_l.as(), nullptr, 0); } + // KeyH + const JsonVariant &val_key_h = GetCaseInsensitive(json, PSTR("KeyH")); + if (nullptr != &val_key_h) { zb_precfgkey_h = strtoull(val_key_h.as(), nullptr, 0); } + // TxRadio dBm + const JsonVariant &val_txradio = GetCaseInsensitive(json, PSTR("TxRadio")); + if (nullptr != &val_txradio) { zb_txradio_dbm = strToUInt(val_txradio); } + + // Check if a parameter was changed after all + if ( (zb_channel != Settings.zb_channel) || + (zb_pan_id != Settings.zb_pan_id) || + (zb_ext_panid != Settings.zb_ext_panid) || + (zb_precfgkey_l != Settings.zb_precfgkey_l) || + (zb_precfgkey_h != Settings.zb_precfgkey_h) || + (zb_txradio_dbm != Settings.zb_txradio_dbm) ) { + Settings.zb_channel = zb_channel; + Settings.zb_pan_id = zb_pan_id; + Settings.zb_ext_panid = zb_ext_panid; + Settings.zb_precfgkey_l = zb_precfgkey_l; + Settings.zb_precfgkey_h = zb_precfgkey_h; + Settings.zb_txradio_dbm = zb_txradio_dbm; + restart_flag = 2; // save and reboot + } + } + + // display the current or new configuration + char hex_ext_panid[20] = "0x"; + Uint64toHex(zb_ext_panid, &hex_ext_panid[2], 64); + char hex_precfgkey_l[20] = "0x"; + Uint64toHex(zb_precfgkey_l, &hex_precfgkey_l[2], 64); + char hex_precfgkey_h[20] = "0x"; + Uint64toHex(zb_precfgkey_h, &hex_precfgkey_h[2], 64); + + // {"ZbConfig":{"Channel":11,"PanID":"0x1A63","ExtPanID":"0xCCCCCCCCCCCCCCCC","KeyL":"0x0F0D0B0907050301L","KeyH":"0x0D0C0A0806040200L"}} + Response_P(PSTR("{\"" D_PRFX_ZB D_JSON_ZIGBEE_CONFIG "\":{" + "\"Channel\":%d" + ",\"PanID\":\"0x%04X\"" + ",\"ExtPanID\":\"%s\"" + ",\"KeyL\":\"%s\"" + ",\"KeyH\":\"%s\"" + ",\"TxRadio\":%d" + "}}"), + zb_channel, zb_pan_id, + hex_ext_panid, + hex_precfgkey_l, hex_precfgkey_h, + zb_txradio_dbm); +} + +/*********************************************************************************************\ + * Presentation +\*********************************************************************************************/ + +void ZigbeeShow(bool json) +{ + if (json) { + return; +#ifdef USE_WEBSERVER + } else { + uint32_t zigbee_num = zigbee_devices.devicesSize(); + if (!zigbee_num) { return; } + + // Calculate fixed column width for best visual result (Theos opinion) + const uint8_t px_batt = (strlen(D_BATT) + 5 + 1) * 10; // Batt 100% = 90px + 10px column separator + const uint8_t px_lqi = (strlen(D_LQI) + 4) * 10; // LQI 254 = 70px + + WSContentSend_P(PSTR("{t}")); // Terminate current two column table and open new table +// WSContentSend_P(PSTR("{t}")); // Insert multi column table + +// WSContentSend_PD(PSTR("{s}Device 0x1234" D_BATT " 100%%" D_LQI " 254{e}")); +// WSContentSend_PD(PSTR("{s}Device 0x1234" D_BATT " 100%%" D_LQI " 254{e}")); +// WSContentSend_PD(PSTR("{s}Device 0x1234" D_BATT " 100%%" D_LQI " 254{e}"), px_batt, px_lqi); + + char sdevice[33]; + char sbatt[20]; + char slqi[20]; + + for (uint32_t i = 0; i < zigbee_num; i++) { + uint16_t shortaddr = zigbee_devices.devicesAt(i).shortaddr; + char *name = (char*)zigbee_devices.getFriendlyName(shortaddr); + if (nullptr == name) { + snprintf_P(sdevice, sizeof(sdevice), PSTR(D_DEVICE " 0x%04X"), shortaddr); + name = sdevice; + } + + snprintf_P(slqi, sizeof(slqi), PSTR("-")); + uint8_t lqi = zigbee_devices.getLQI(shortaddr); + if (0xFF != lqi) { + snprintf_P(slqi, sizeof(slqi), PSTR("%d"), lqi); + } + + snprintf_P(sbatt, sizeof(sbatt), PSTR(" ")); + uint8_t bp = zigbee_devices.getBatteryPercent(shortaddr); + if (0xFF != bp) { + snprintf_P(sbatt, sizeof(sbatt), PSTR(D_BATT " %d%%"), bp); + } + + if (!i) { // First row needs style info + WSContentSend_PD(PSTR("{s}%s%s" D_LQI " %s{e}"), + name, px_batt, sbatt, px_lqi, slqi); + } else { // Following rows don't need style info so reducing ajax package + WSContentSend_PD(PSTR("{s}%s{m}%s" D_LQI " %s{e}"), name, sbatt, slqi); + } + } + + WSContentSend_P(PSTR("{t}")); // Terminate current multi column table and open new table +// WSContentSend_P(PSTR("{e}")); // Terminate multi column table +#endif + } +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xdrv23(uint8_t function) +{ + bool result = false; + + if (zigbee.active) { + switch (function) { + case FUNC_EVERY_50_MSECOND: + if (!zigbee.init_phase) { + zigbee_devices.runTimer(); + } + break; + case FUNC_LOOP: + if (ZigbeeSerial) { ZigbeeInputLoop(); } + if (zigbee.state_machine) { + ZigbeeStateMachine_Run(); + } + break; +#ifdef USE_WEBSERVER + case FUNC_WEB_SENSOR: + ZigbeeShow(false); + break; +#endif // USE_WEBSERVER + case FUNC_PRE_INIT: + ZigbeeInit(); + break; + case FUNC_COMMAND: + result = DecodeCommand(kZbCommands, ZigbeeCommand); + break; + } + } + return result; +} + +#endif // USE_ZIGBEE diff --git a/tasmota/xdrv_24_buzzer.ino b/tasmota/xdrv_24_buzzer.ino index 5e582d7db..10232cc52 100644 --- a/tasmota/xdrv_24_buzzer.ino +++ b/tasmota/xdrv_24_buzzer.ino @@ -41,7 +41,7 @@ struct BUZZER { void BuzzerOff(void) { - DigitalWrite(GPIO_BUZZER, Buzzer.inverted); // Buzzer Off + DigitalWrite(GPIO_BUZZER, 0, Buzzer.inverted); // Buzzer Off } //void BuzzerBeep(uint32_t count = 1, uint32_t on = 1, uint32_t off = 1, uint32_t tune = 0, uint32_t mode = 0); @@ -81,7 +81,7 @@ void BuzzerSetStateToLed(uint32_t state) { if (Buzzer.enable && (2 == Buzzer.mode)) { Buzzer.state = (state != 0); - DigitalWrite(GPIO_BUZZER, (Buzzer.inverted) ? !Buzzer.state : Buzzer.state); + DigitalWrite(GPIO_BUZZER, 0, (Buzzer.inverted) ? !Buzzer.state : Buzzer.state); } } @@ -101,9 +101,9 @@ void BuzzerEnabledBeep(uint32_t count, uint32_t duration) bool BuzzerPinState(void) { - if (XdrvMailbox.index == GPIO_BUZZER_INV) { + if (XdrvMailbox.index == AGPIO(GPIO_BUZZER_INV)) { Buzzer.inverted = 1; - XdrvMailbox.index -= (GPIO_BUZZER_INV - GPIO_BUZZER); + XdrvMailbox.index -= (AGPIO(GPIO_BUZZER_INV) - AGPIO(GPIO_BUZZER)); return true; } return false; @@ -111,8 +111,8 @@ bool BuzzerPinState(void) void BuzzerInit(void) { - if (pin[GPIO_BUZZER] < 99) { - pinMode(pin[GPIO_BUZZER], OUTPUT); + if (PinUsed(GPIO_BUZZER)) { + pinMode(Pin(GPIO_BUZZER), OUTPUT); BuzzerOff(); } else { Buzzer.active = false; @@ -140,7 +140,7 @@ void BuzzerEvery100mSec(void) Buzzer.duration = Buzzer.set[Buzzer.state]; } } - DigitalWrite(GPIO_BUZZER, (Buzzer.inverted) ? !Buzzer.state : Buzzer.state); + DigitalWrite(GPIO_BUZZER, 0, (Buzzer.inverted) ? !Buzzer.state : Buzzer.state); } else { Buzzer.enable = false; } diff --git a/tasmota/xdrv_25_A4988_Stepper.ino b/tasmota/xdrv_25_A4988_Stepper.ino index d6456f2a1..48f559314 100644 --- a/tasmota/xdrv_25_A4988_Stepper.ino +++ b/tasmota/xdrv_25_A4988_Stepper.ino @@ -27,12 +27,12 @@ #include -short A4988_dir_pin = pin[GPIO_MAX]; -short A4988_stp_pin = pin[GPIO_MAX]; -short A4988_ms1_pin = pin[GPIO_MAX]; -short A4988_ms2_pin = pin[GPIO_MAX]; -short A4988_ms3_pin = pin[GPIO_MAX]; -short A4988_ena_pin = pin[GPIO_MAX]; +short A4988_dir_pin = 0; +short A4988_stp_pin = 0; +short A4988_ms1_pin = 0; +short A4988_ms2_pin = 0; +short A4988_ms3_pin = 0; +short A4988_ena_pin = 0; int A4988_spr = 0; float A4988_rpm = 0; short A4988_mis = 0; @@ -41,12 +41,12 @@ A4988_Stepper* myA4988 = nullptr; void A4988Init(void) { - A4988_dir_pin = pin[GPIO_A4988_DIR]; - A4988_stp_pin = pin[GPIO_A4988_STP]; - A4988_ena_pin = pin[GPIO_A4988_ENA]; - A4988_ms1_pin = pin[GPIO_A4988_MS1]; - A4988_ms2_pin = pin[GPIO_A4988_MS2]; - A4988_ms3_pin = pin[GPIO_A4988_MS3]; + A4988_dir_pin = Pin(GPIO_A4988_DIR); + A4988_stp_pin = Pin(GPIO_A4988_STP); + A4988_ena_pin = Pin(GPIO_A4988_ENA); + A4988_ms1_pin = Pin(GPIO_A4988_MS1); + A4988_ms2_pin = Pin(GPIO_A4988_MS2); + A4988_ms3_pin = Pin(GPIO_A4988_MS3); A4988_spr = 200; A4988_rpm = 30; A4988_mis = 1; @@ -93,7 +93,7 @@ void CmndDoTurn(void) { } void CmndSetMIS(void) { - if ((pin[GPIO_A4988_MS1] < 99) && (pin[GPIO_A4988_MS2] < 99) && (pin[GPIO_A4988_MS3] < 99) && (XdrvMailbox.data_len > 0)) { + if (PinUsed(GPIO_A4988_MS1) && PinUsed(GPIO_A4988_MS2) && PinUsed(GPIO_A4988_MS3) && (XdrvMailbox.data_len > 0)) { short newMIS = strtoul(XdrvMailbox.data,nullptr,10); myA4988->setMIS(newMIS); ResponseCmndDone(); @@ -122,7 +122,7 @@ void CmndSetRPM(void) { bool Xdrv25(uint8_t function) { bool result = false; - if ((pin[GPIO_A4988_DIR] < 99) && (pin[GPIO_A4988_STP] < 99)) { + if (PinUsed(GPIO_A4988_DIR) && PinUsed(GPIO_A4988_STP)) { switch (function) { case FUNC_INIT: A4988Init(); diff --git a/tasmota/xdrv_26_ariluxrf.ino b/tasmota/xdrv_26_ariluxrf.ino index 2a6c73eaf..5027dfdcb 100644 --- a/tasmota/xdrv_26_ariluxrf.ino +++ b/tasmota/xdrv_26_ariluxrf.ino @@ -147,7 +147,7 @@ void AriluxRfHandler(void) void AriluxRfInit(void) { - if ((pin[GPIO_ARIRFRCV] < 99) && (pin[GPIO_ARIRFSEL] < 99)) { + if (PinUsed(GPIO_ARIRFRCV) && PinUsed(GPIO_ARIRFSEL)) { if (Settings.last_module != Settings.module) { Settings.rf_code[1][6] = 0; Settings.rf_code[1][7] = 0; @@ -155,16 +155,16 @@ void AriluxRfInit(void) } Arilux.rf_received_value = 0; - digitalWrite(pin[GPIO_ARIRFSEL], 0); // Turn on RF - attachInterrupt(pin[GPIO_ARIRFRCV], AriluxRfInterrupt, CHANGE); + digitalWrite(Pin(GPIO_ARIRFSEL), 0); // Turn on RF + attachInterrupt(Pin(GPIO_ARIRFRCV), AriluxRfInterrupt, CHANGE); } } void AriluxRfDisable(void) { - if ((pin[GPIO_ARIRFRCV] < 99) && (pin[GPIO_ARIRFSEL] < 99)) { - detachInterrupt(pin[GPIO_ARIRFRCV]); - digitalWrite(pin[GPIO_ARIRFSEL], 1); // Turn off RF + if (PinUsed(GPIO_ARIRFRCV) && PinUsed(GPIO_ARIRFSEL)) { + detachInterrupt(Pin(GPIO_ARIRFRCV)); + digitalWrite(Pin(GPIO_ARIRFSEL), 1); // Turn off RF } } @@ -178,7 +178,7 @@ bool Xdrv26(uint8_t function) switch (function) { case FUNC_EVERY_50_MSECOND: - if (pin[GPIO_ARIRFRCV] < 99) { AriluxRfHandler(); } + if (PinUsed(GPIO_ARIRFRCV)) { AriluxRfHandler(); } break; case FUNC_EVERY_SECOND: if (10 == uptime) { AriluxRfInit(); } // Needs rest before enabling RF interrupts diff --git a/tasmota/xdrv_27_shutter.ino b/tasmota/xdrv_27_shutter.ino index b68de3c8d..6d0c6e5ce 100644 --- a/tasmota/xdrv_27_shutter.ino +++ b/tasmota/xdrv_27_shutter.ino @@ -37,16 +37,18 @@ enum ShutterModes { SHT_OFF_OPEN__OFF_CLOSE, SHT_OFF_ON__OPEN_CLOSE, SHT_PULSE_O enum ShutterButtonStates { SHT_NOT_PRESSED, SHT_PRESSED_MULTI, SHT_PRESSED_HOLD, SHT_PRESSED_IMMEDIATE, SHT_PRESSED_EXT_HOLD, SHT_PRESSED_MULTI_SIMULTANEOUS, SHT_PRESSED_HOLD_SIMULTANEOUS, SHT_PRESSED_EXT_HOLD_SIMULTANEOUS,}; const char kShutterCommands[] PROGMEM = D_PRFX_SHUTTER "|" - D_CMND_SHUTTER_OPEN "|" D_CMND_SHUTTER_CLOSE "|" D_CMND_SHUTTER_STOP "|" D_CMND_SHUTTER_POSITION "|" + D_CMND_SHUTTER_OPEN "|" D_CMND_SHUTTER_CLOSE "|" D_CMND_SHUTTER_TOGGLE "|" D_CMND_SHUTTER_STOP "|" D_CMND_SHUTTER_POSITION "|" D_CMND_SHUTTER_OPENTIME "|" D_CMND_SHUTTER_CLOSETIME "|" D_CMND_SHUTTER_RELAY "|" - D_CMND_SHUTTER_SETHALFWAY "|" D_CMND_SHUTTER_SETCLOSE "|" D_CMND_SHUTTER_INVERT "|" D_CMND_SHUTTER_CLIBRATION "|" - D_CMND_SHUTTER_MOTORDELAY "|" D_CMND_SHUTTER_FREQUENCY "|" D_CMND_SHUTTER_BUTTON "|" D_CMND_SHUTTER_LOCK "|" D_CMND_SHUTTER_ENABLEENDSTOPTIME "|" D_CMND_SHUTTER_INVERTWEBBUTTONS; + D_CMND_SHUTTER_SETHALFWAY "|" D_CMND_SHUTTER_SETCLOSE "|" D_CMND_SHUTTER_SETOPEN "|" D_CMND_SHUTTER_INVERT "|" D_CMND_SHUTTER_CLIBRATION "|" + D_CMND_SHUTTER_MOTORDELAY "|" D_CMND_SHUTTER_FREQUENCY "|" D_CMND_SHUTTER_BUTTON "|" D_CMND_SHUTTER_LOCK "|" D_CMND_SHUTTER_ENABLEENDSTOPTIME "|" D_CMND_SHUTTER_INVERTWEBBUTTONS "|" + D_CMND_SHUTTER_STOPOPEN "|" D_CMND_SHUTTER_STOPCLOSE "|" D_CMND_SHUTTER_STOPTOGGLE "|" D_CMND_SHUTTER_STOPPOSITION; void (* const ShutterCommand[])(void) PROGMEM = { - &CmndShutterOpen, &CmndShutterClose, &CmndShutterStop, &CmndShutterPosition, + &CmndShutterOpen, &CmndShutterClose, &CmndShutterToggle, &CmndShutterStop, &CmndShutterPosition, &CmndShutterOpenTime, &CmndShutterCloseTime, &CmndShutterRelay, - &CmndShutterSetHalfway, &CmndShutterSetClose, &CmndShutterInvert, &CmndShutterCalibration , &CmndShutterMotorDelay, - &CmndShutterFrequency, &CmndShutterButton, &CmndShutterLock, &CmndShutterEnableEndStopTime, &CmndShutterInvertWebButtons}; + &CmndShutterSetHalfway, &CmndShutterSetClose, &CmndShutterSetOpen, &CmndShutterInvert, &CmndShutterCalibration , &CmndShutterMotorDelay, + &CmndShutterFrequency, &CmndShutterButton, &CmndShutterLock, &CmndShutterEnableEndStopTime, &CmndShutterInvertWebButtons, + &CmndShutterStopOpen, &CmndShutterStopClose, &CmndShutterStopToggle, &CmndShutterStopPosition}; const char JSON_SHUTTER_POS[] PROGMEM = "\"" D_PRFX_SHUTTER "%d\":{\"Position\":%d,\"Direction\":%d,\"Target\":%d}"; const char JSON_SHUTTER_BUTTON[] PROGMEM = "\"" D_PRFX_SHUTTER "%d\":{\"Button%d\":%d}"; @@ -82,7 +84,7 @@ void ShutterLogPos(uint32_t i) { char stemp2[10]; dtostrfd((float)Shutter.time[i] / steps_per_second, 2, stemp2); - AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Shutter%d Real %d, Start %d, Stop %d, Dir %d, Delay %d, Rtc %s [s], Freq %d"), + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Shutter%d Real %d, Start %d, Stop %d, Dir %d, Delay %d, Rtc %s [s], Freq %d"), i+1, Shutter.real_position[i], Shutter.start_position[i], Shutter.target_position[i], Shutter.direction[i], Shutter.motordelay[i], stemp2, Shutter.pwm_frequency[i]); } @@ -91,11 +93,11 @@ void ShutterRtc50mS(void) for (uint8_t i = 0; i < shutters_present; i++) { Shutter.time[i]++; if (Shutter.accelerator[i]) { - //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: accelerator i=%d -> %d"),i, Shutter.accelerator[i]); + //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: accelerator i=%d -> %d"),i, Shutter.accelerator[i]); Shutter.pwm_frequency[i] += Shutter.accelerator[i]; Shutter.pwm_frequency[i] = tmax(0,tmin(Shutter.direction[i]==1 ? Shutter.max_pwm_frequency : Shutter.max_close_pwm_frequency[i],Shutter.pwm_frequency[i])); analogWriteFreq(Shutter.pwm_frequency[i]); - analogWrite(pin[GPIO_PWM1+i], 50); + analogWrite(Pin(GPIO_PWM1, i), 50); } } } @@ -120,13 +122,13 @@ int32_t ShutterPercentToRealPosition(uint32_t percent, uint32_t index) for (uint32_t i = 0; i < 5; i++) { if ((percent * 10) >= Settings.shuttercoeff[i][index]) { realpos = SHT_DIV_ROUND(Shutter.open_max[index] * calibrate_pos[i+1], 100); - //AddLog_P2(LOG_LEVEL_INFO, PSTR("Realposition TEMP1: %d, %% %d, coeff %d"), realpos, percent, Settings.shuttercoeff[i][index]); + //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Realposition TEMP1: %d, %% %d, coeff %d"), realpos, percent, Settings.shuttercoeff[i][index]); } else { if (0 == i) { realpos = SHT_DIV_ROUND(SHT_DIV_ROUND(percent * Shutter.open_max[index] * calibrate_pos[i+1], Settings.shuttercoeff[i][index]), 10); } else { //uint16_t addon = ( percent*10 - Settings.shuttercoeff[i-1][index] ) * Shutter_Open_Max[index] * (calibrate_pos[i+1] - calibrate_pos[i]) / (Settings.shuttercoeff[i][index] -Settings.shuttercoeff[i-1][index]) / 100; - //AddLog_P2(LOG_LEVEL_INFO, PSTR("Realposition TEMP2: %d, %% %d, coeff %d"), addon, (calibrate_pos[i+1] - calibrate_pos[i]), (Settings.shuttercoeff[i][index] -Settings.shuttercoeff[i-1][index])); + //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Realposition TEMP2: %d, %% %d, coeff %d"), addon, (calibrate_pos[i+1] - calibrate_pos[i]), (Settings.shuttercoeff[i][index] -Settings.shuttercoeff[i-1][index])); realpos += SHT_DIV_ROUND(SHT_DIV_ROUND((percent*10 - Settings.shuttercoeff[i-1][index] ) * Shutter.open_max[index] * (calibrate_pos[i+1] - calibrate_pos[i]), Settings.shuttercoeff[i][index] - Settings.shuttercoeff[i-1][index]), 100); } break; @@ -146,20 +148,20 @@ uint8_t ShutterRealToPercentPosition(int32_t realpos, uint32_t index) for (uint32_t i = 0; i < 5; i++) { if (realpos >= Shutter.open_max[index] * calibrate_pos[i+1] / 100) { realpercent = SHT_DIV_ROUND(Settings.shuttercoeff[i][index], 10); - //AddLog_P2(LOG_LEVEL_INFO, PSTR("Realpercent TEMP1: %d, %% %d, coeff %d"), realpercent, realpos, Shutter_Open_Max[index] * calibrate_pos[i+1] / 100); + //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Realpercent TEMP1: %d, %% %d, coeff %d"), realpercent, realpos, Shutter_Open_Max[index] * calibrate_pos[i+1] / 100); } else { if (0 == i) { realpercent = SHT_DIV_ROUND(SHT_DIV_ROUND((realpos - SHT_DIV_ROUND(Shutter.open_max[index] * calibrate_pos[i], 100)) * 10 * Settings.shuttercoeff[i][index], calibrate_pos[i+1]), Shutter.open_max[index]); } else { //uint16_t addon = ( realpos - (Shutter_Open_Max[index] * calibrate_pos[i] / 100) ) * 10 * (Settings.shuttercoeff[i][index] - Settings.shuttercoeff[i-1][index]) / (calibrate_pos[i+1] - calibrate_pos[i])/ Shutter_Open_Max[index]; //uint16_t addon = ( percent*10 - Settings.shuttercoeff[i-1][index] ) * Shutter_Open_Max[index] * (calibrate_pos[i+1] - calibrate_pos[i]) / (Settings.shuttercoeff[i][index] -Settings.shuttercoeff[i-1][index]) / 100; - //AddLog_P2(LOG_LEVEL_INFO, PSTR("Realpercent TEMP2: %d, delta %d, %% %d, coeff %d"), addon,( realpos - (Shutter_Open_Max[index] * calibrate_pos[i] / 100) ) , (calibrate_pos[i+1] - calibrate_pos[i])* Shutter_Open_Max[index]/100, (Settings.shuttercoeff[i][index] -Settings.shuttercoeff[i-1][index])); + //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Realpercent TEMP2: %d, delta %d, %% %d, coeff %d"), addon,( realpos - (Shutter_Open_Max[index] * calibrate_pos[i] / 100) ) , (calibrate_pos[i+1] - calibrate_pos[i])* Shutter_Open_Max[index]/100, (Settings.shuttercoeff[i][index] -Settings.shuttercoeff[i-1][index])); realpercent += SHT_DIV_ROUND(SHT_DIV_ROUND((realpos - SHT_DIV_ROUND(Shutter.open_max[index] * calibrate_pos[i], 100)) * 10 * (Settings.shuttercoeff[i][index] - Settings.shuttercoeff[i-1][index]), (calibrate_pos[i+1] - calibrate_pos[i])), Shutter.open_max[index]) ; } break; } } - return realpercent; + return (int16_t)realpercent < 0 ? 0 : realpercent; } } @@ -172,7 +174,7 @@ void ShutterInit(void) bool relay_in_interlock = false; // if shutter 4 is unused - if (Settings.shutter_startrelay[MAX_SHUTTERS] == 0) { + if (Settings.shutter_startrelay[MAX_SHUTTERS -1] == 0) { Shutter.max_pwm_frequency = Settings.shuttercoeff[4][3] > 0 ? Settings.shuttercoeff[4][3] : Shutter.max_pwm_frequency; } for (uint32_t i = 0; i < MAX_SHUTTERS; i++) { @@ -185,9 +187,9 @@ void ShutterInit(void) Shutter.mask |= 3 << (Settings.shutter_startrelay[i] -1) ; for (uint32_t j = 0; j < MAX_INTERLOCKS * Settings.flag.interlock; j++) { // CMND_INTERLOCK - Enable/disable interlock - //AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Interlock state i=%d %d, flag %d, , shuttermask %d, maskedIL %d"),i, Settings.interlock[i], Settings.flag.interlock,Shutter.mask, Settings.interlock[i]&Shutter.mask); + //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Interlock state i=%d %d, flag %d, , shuttermask %d, maskedIL %d"),i, Settings.interlock[i], Settings.flag.interlock,Shutter.mask, Settings.interlock[i]&Shutter.mask); if (Settings.interlock[j] && (Settings.interlock[j] & Shutter.mask)) { - //AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Relay in Interlock group")); + //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Relay in Interlock group")); relay_in_interlock = true; } } @@ -199,12 +201,13 @@ void ShutterInit(void) } } else { Shutter.mode = SHT_OFF_ON__OPEN_CLOSE; - if ((pin[GPIO_PWM1+i] < 99) && (pin[GPIO_CNTR1+i] < 99)) { + if (PinUsed(GPIO_PWM1, i) && PinUsed(GPIO_CNTR1, i)) { Shutter.mode = SHT_OFF_ON__OPEN_CLOSE_STEPPER; Shutter.pwm_frequency[i] = 0; Shutter.accelerator[i] = 0; analogWriteFreq(Shutter.pwm_frequency[i]); - analogWrite(pin[GPIO_PWM1+i], 50); + analogWrite(Pin(GPIO_PWM1, i), 0); +// ExecuteCommandPower(Settings.shutter_startrelay[i]+2, 0, SRC_SHUTTER); } } @@ -220,7 +223,7 @@ void ShutterInit(void) Shutter.open_max[i] = 200 * Shutter.open_time[i]; Shutter.close_velocity[i] = Shutter.open_max[i] / Shutter.close_time[i] / 2 ; Shutter.max_close_pwm_frequency[i] = Shutter.max_pwm_frequency*Shutter.open_time[i] / Shutter.close_time[i]; - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Shutter %d Closefreq: %d"),i, Shutter.max_close_pwm_frequency[i]); + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Shutter %d Closefreq: %d"),i, Shutter.max_close_pwm_frequency[i]); // calculate a ramp slope at the first 5 percent to compensate that shutters move with down part later than the upper part if (Settings.shutter_set50percent[i] != 50) { @@ -239,7 +242,7 @@ void ShutterInit(void) dtostrfd((float)Shutter.open_time[i] / 10 , 1, shutter_open_chr); char shutter_close_chr[10]; dtostrfd((float)Shutter.close_time[i] / 10, 1, shutter_close_chr); - AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Shutter %d (Relay:%d): Init. Pos: %d [%d %%], Open Vel.: 100, Close Vel.: %d , Max Way: %d, Opentime %s [s], Closetime %s [s], CoeffCalc: c0: %d, c1 %d, c2: %d, c3: %d, c4: %d, binmask %d, is inverted %d, is locked %d, end stop time enabled %d, webButtons inverted %d, shuttermode %d, motordelay %d"), + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Shutter %d (Relay:%d): Init. Pos: %d [%d %%], Open Vel.: 100, Close Vel.: %d , Max Way: %d, Opentime %s [s], Closetime %s [s], CoeffCalc: c0: %d, c1 %d, c2: %d, c3: %d, c4: %d, binmask %d, is inverted %d, is locked %d, end stop time enabled %d, webButtons inverted %d, shuttermode %d, motordelay %d"), i+1, Settings.shutter_startrelay[i], Shutter.real_position[i], Settings.shutter_position[i], Shutter.close_velocity[i], Shutter.open_max[i], shutter_open_chr, shutter_close_chr, Settings.shuttercoeff[0][i], Settings.shuttercoeff[1][i], Settings.shuttercoeff[2][i], Settings.shuttercoeff[3][i], Settings.shuttercoeff[4][i], Shutter.mask, (Settings.shutter_options[i]&1) ? 1 : 0, (Settings.shutter_options[i]&2) ? 1 : 0, (Settings.shutter_options[i]&4) ? 1 : 0, (Settings.shutter_options[i]&8) ? 1 : 0, Shutter.mode, Shutter.motordelay[i]); @@ -253,28 +256,34 @@ void ShutterInit(void) } } -void ShutterReportPosition(bool always) +void ShutterReportPosition(bool always, uint32_t index) { Response_P(PSTR("{")); rules_flag.shutter_moving = 0; - for (uint32_t i = 0; i < shutters_present; i++) { - //AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Shutter %d: Real Pos: %d"), i+1,Shutter.real_position[i]); + uint32_t i = 0; + uint32_t n = shutters_present; + if( index != MAX_SHUTTERS) { + i = index; + n = index+1; + } + for (i; i < n; i++) { + //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Shutter %d: Real Pos: %d"), i+1,Shutter.real_position[i]); uint32_t position = ShutterRealToPercentPosition(Shutter.real_position[i], i); if (Shutter.direction[i] != 0) { rules_flag.shutter_moving = 1; ShutterLogPos(i); } - if (i) { ResponseAppend_P(PSTR(",")); } + if (i && index == MAX_SHUTTERS) { ResponseAppend_P(PSTR(",")); } uint32_t target = ShutterRealToPercentPosition(Shutter.target_position[i], i); ResponseAppend_P(JSON_SHUTTER_POS, i+1, (Settings.shutter_options[i] & 1) ? 100-position : position, Shutter.direction[i],(Settings.shutter_options[i] & 1) ? 100-target : target ); } ResponseJsonEnd(); if (always || (rules_flag.shutter_moving)) { MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR(D_PRFX_SHUTTER)); - //XdrvRulesProcess(); //removed because to many exceptions and reboots. + XdrvRulesProcess(); //RulesProcess() now re-entry protected } - //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: rules_flag.shutter_moving: %d, moved %d"), rules_flag.shutter_moving, rules_flag.shutter_moved); + //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: rules_flag.shutter_moving: %d, moved %d"), rules_flag.shutter_moving, rules_flag.shutter_moved); } @@ -294,16 +303,16 @@ void ShutterUpdatePosition(void) for (uint32_t i = 0; i < shutters_present; i++) { if (Shutter.direction[i] != 0) { int32_t stop_position_delta = 20; - if (Shutter.mode == SHT_OFF_ON__OPEN_CLOSE_STEPPER) { - // Calculate position with counter. Much more accurate and no need for motordelay workaround - // adding some steps to stop early - Shutter.real_position[i] = ShutterCounterBasedPosition(i); - if (!Shutter.start_reported) { - ShutterReportPosition(true); - XdrvRulesProcess(); - Shutter.start_reported = 1; - } + // Calculate position with counter. Much more accurate and no need for motordelay workaround + // adding some steps to stop early + Shutter.real_position[i] = ShutterCounterBasedPosition(i); + if (!Shutter.start_reported) { + ShutterReportPosition(true, i); + XdrvRulesProcess(); + Shutter.start_reported = 1; + } + if (Shutter.mode == SHT_OFF_ON__OPEN_CLOSE_STEPPER) { int32_t max_frequency = Shutter.direction[i] == 1 ? Shutter.max_pwm_frequency : Shutter.max_close_pwm_frequency[i]; int32_t max_freq_change_per_sec = Shutter.max_pwm_frequency*steps_per_second / (Shutter.motordelay[i]>0 ? Shutter.motordelay[i] : 1); int32_t min_runtime_ms = Shutter.pwm_frequency[i]*1000 / max_freq_change_per_sec; @@ -330,7 +339,7 @@ void ShutterUpdatePosition(void) } if ( Shutter.real_position[i] * Shutter.direction[i] + stop_position_delta >= Shutter.target_position[i] * Shutter.direction[i] ) { // calculate relay number responsible for current movement. - //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Stop Condition detected: real: %d, Target: %d, direction: %d"),Shutter.real_position[i], Shutter.target_position[i],Shutter.direction[i]); + //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Stop Condition detected: real: %d, Target: %d, direction: %d"),Shutter.real_position[i], Shutter.target_position[i],Shutter.direction[i]); uint8_t cur_relay = Settings.shutter_startrelay[i] + (Shutter.direction[i] == 1 ? 0 : 1) ; int16_t missing_steps; @@ -346,19 +355,20 @@ void ShutterUpdatePosition(void) case SHT_OFF_ON__OPEN_CLOSE_STEPPER: missing_steps = ((Shutter.target_position[i]-Shutter.start_position[i])*Shutter.direction[i]*Shutter.max_pwm_frequency/2000) - RtcSettings.pulse_counter[i]; //prepare for stop PWM - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Remain steps %d, counter %d, freq %d"), missing_steps, RtcSettings.pulse_counter[i] ,Shutter.pwm_frequency[i]); + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Remain steps %d, counter %d, freq %d"), missing_steps, RtcSettings.pulse_counter[i] ,Shutter.pwm_frequency[i]); Shutter.accelerator[i] = 0; Shutter.pwm_frequency[i] = Shutter.pwm_frequency[i] > 250 ? 250 : Shutter.pwm_frequency[i]; analogWriteFreq(Shutter.pwm_frequency[i]); - analogWrite(pin[GPIO_PWM1+i], 50); + analogWrite(Pin(GPIO_PWM1, i), 50); Shutter.pwm_frequency[i] = 0; analogWriteFreq(Shutter.pwm_frequency[i]); while (RtcSettings.pulse_counter[i] < (uint32_t)(Shutter.target_position[i]-Shutter.start_position[i])*Shutter.direction[i]*Shutter.max_pwm_frequency/2000) { delay(1); } - analogWrite(pin[GPIO_PWM1+i], 0); + analogWrite(Pin(GPIO_PWM1, i), 0); // removed with 8.3 because of reset caused by watchog +// ExecuteCommandPower(Settings.shutter_startrelay[i]+2, 0, SRC_SHUTTER); Shutter.real_position[i] = ShutterCounterBasedPosition(i); - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Real %d, pulsecount %d, start %d"), Shutter.real_position[i],RtcSettings.pulse_counter[i], Shutter.start_position[i]); + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Real %d, pulsecount %d, start %d"), Shutter.real_position[i],RtcSettings.pulse_counter[i], Shutter.start_position[i]); if ((1 << (Settings.shutter_startrelay[i]-1)) & power) { ExecuteCommandPower(Settings.shutter_startrelay[i], 0, SRC_SHUTTER); @@ -393,7 +403,7 @@ void ShutterUpdatePosition(void) MqttPublish(stopic, Settings.flag.mqtt_power_retain); // CMND_POWERRETAIN Shutter.direction[i] = 0; - ShutterReportPosition(true); + ShutterReportPosition(true, i); rules_flag.shutter_moved = 1; XdrvRulesProcess(); } @@ -411,7 +421,7 @@ bool ShutterState(uint32_t device) void ShutterStartInit(uint32_t i, int32_t direction, int32_t target_pos) { - //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: dir %d, delta1 %d, delta2 %d, grant %d"),direction, (Shutter.open_max[i] - Shutter.real_position[i]) / Shutter.close_velocity[i], Shutter.real_position[i] / Shutter.close_velocity[i], 2+Shutter.motordelay[i]); + //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: dir %d, delta1 %d, delta2 %d, grant %d"),direction, (Shutter.open_max[i] - Shutter.real_position[i]) / Shutter.close_velocity[i], Shutter.real_position[i] / Shutter.close_velocity[i], 2+Shutter.motordelay[i]); if ( ( (1 == direction) && ((Shutter.open_max[i] - Shutter.real_position[i]) / 100 <= 2) ) || ( (-1 == direction) && (Shutter.real_position[i] / Shutter.close_velocity[i] <= 2)) ) { Shutter.skip_relay_change = 1; @@ -419,10 +429,10 @@ void ShutterStartInit(uint32_t i, int32_t direction, int32_t target_pos) if (Shutter.mode == SHT_OFF_ON__OPEN_CLOSE_STEPPER) { Shutter.pwm_frequency[i] = 0; analogWriteFreq(Shutter.pwm_frequency[i]); - analogWrite(pin[GPIO_PWM1+i], 0); + analogWrite(Pin(GPIO_PWM1, i), 0); RtcSettings.pulse_counter[i] = 0; Shutter.accelerator[i] = Shutter.max_pwm_frequency / (Shutter.motordelay[i]>0 ? Shutter.motordelay[i] : 1); - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Ramp up: %d"), Shutter.accelerator[i]); + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Ramp up: %d"), Shutter.accelerator[i]); } Shutter.target_position[i] = target_pos; Shutter.start_position[i] = Shutter.real_position[i]; @@ -432,26 +442,27 @@ void ShutterStartInit(uint32_t i, int32_t direction, int32_t target_pos) rules_flag.shutter_moving = 1; rules_flag.shutter_moved = 0; Shutter.start_reported = 0; - //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: real %d, start %d, counter %d, max_freq %d, dir %d, freq %d"),Shutter.real_position[i], Shutter.start_position[i] ,RtcSettings.pulse_counter[i],Shutter.max_pwm_frequency , Shutter.direction[i] ,Shutter.max_pwm_frequency ); + //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: real %d, start %d, counter %d, max_freq %d, dir %d, freq %d"),Shutter.real_position[i], Shutter.start_position[i] ,RtcSettings.pulse_counter[i],Shutter.max_pwm_frequency , Shutter.direction[i] ,Shutter.max_pwm_frequency ); } - //AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Start shutter: %d from %d to %d in directin %d"), i, Shutter.start_position[i], Shutter.target_position[i], Shutter.direction[i]); + //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Start shutter: %d from %d to %d in directin %d"), i, Shutter.start_position[i], Shutter.target_position[i], Shutter.direction[i]); } void ShutterWaitForMotorStop(uint32_t i) { - AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Wait for Motorstop..")); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Wait for Motorstop..")); if ((SHT_OFF_ON__OPEN_CLOSE == Shutter.mode) || (SHT_OFF_ON__OPEN_CLOSE_STEPPER == Shutter.mode)) { if (SHT_OFF_ON__OPEN_CLOSE_STEPPER == Shutter.mode) { - //AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Frequency change %d"), Shutter.pwm_frequency); + //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Frequency change %d"), Shutter.pwm_frequency); while (Shutter.pwm_frequency[i] > 0) { //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Frequency: %ld, delta: %d"), Shutter.pwm_frequency[i], (int32_t)((Shutter.direction[i] == 1 ? Shutter.max_pwm_frequency : Shutter.max_close_pwm_frequency[i])/(Shutter.motordelay[i]+1)) ); Shutter.pwm_frequency[i] = tmax(Shutter.pwm_frequency[i]-((Shutter.direction[i] == 1 ? Shutter.max_pwm_frequency : Shutter.max_close_pwm_frequency[i])/(Shutter.motordelay[i]+1)) , 0); //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Frequency: %ld"), Shutter.pwm_frequency[i]); analogWriteFreq(Shutter.pwm_frequency[i]); - analogWrite(pin[GPIO_PWM1+i], 50); + analogWrite(Pin(GPIO_PWM1, i), 50); delay(50); } - analogWrite(pin[GPIO_PWM1+i], 0); + analogWrite(Pin(GPIO_PWM1, i), 0); +// ExecuteCommandPower(Settings.shutter_startrelay[i]+2, 0, SRC_SHUTTER); Shutter.real_position[i] = ShutterCounterBasedPosition(i); } else { ExecuteCommandPower(Settings.shutter_startrelay[i], 0, SRC_SHUTTER); @@ -479,7 +490,7 @@ void ShutterRelayChanged(void) power_t powerstate_local = (power >> (Settings.shutter_startrelay[i] -1)) & 3; //uint8 manual_relays_changed = ((Shutter.switched_relay >> (Settings.shutter_startrelay[i] -1)) & 3) && SRC_IGNORE != last_source && SRC_SHUTTER != last_source && SRC_PULSETIMER != last_source ; uint8 manual_relays_changed = ((Shutter.switched_relay >> (Settings.shutter_startrelay[i] -1)) & 3) && SRC_SHUTTER != last_source && SRC_PULSETIMER != last_source ; - //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Shutter %d: source: %s, powerstate_local %ld, Shutter.switched_relay %d, manual change %d"), i+1, GetTextIndexed(stemp1, sizeof(stemp1), last_source, kCommandSource), powerstate_local,Shutter.switched_relay,manual_relays_changed); + //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Shutter %d: source: %s, powerstate_local %ld, Shutter.switched_relay %d, manual change %d"), i+1, GetTextIndexed(stemp1, sizeof(stemp1), last_source, kCommandSource), powerstate_local,Shutter.switched_relay,manual_relays_changed); if (manual_relays_changed) { //Shutter.skip_relay_change = true; ShutterLimitRealAndTargetPositions(i); @@ -493,13 +504,13 @@ void ShutterRelayChanged(void) ShutterStartInit(i, -1, 0); break; default: - //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Shutter %d: Switch OFF motor."),i); + //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Shutter %d: Switch OFF motor."),i); Shutter.target_position[i] = Shutter.real_position[i]; } } else { if (Shutter.direction[i] != 0 && (!powerstate_local || (powerstate_local && Shutter.mode == SHT_PULSE_OPEN__PULSE_CLOSE))) { Shutter.target_position[i] = Shutter.real_position[i]; - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Shutter %d: Switch OFF motor. Target: %ld, source: %s, powerstate_local %ld, Shutter.switched_relay %d, manual change %d"), i+1, Shutter.target_position[i], GetTextIndexed(stemp1, sizeof(stemp1), last_source, kCommandSource), powerstate_local,Shutter.switched_relay,manual_relays_changed); + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Shutter %d: Switch OFF motor. Target: %ld, source: %s, powerstate_local %ld, Shutter.switched_relay %d, manual change %d"), i+1, Shutter.target_position[i], GetTextIndexed(stemp1, sizeof(stemp1), last_source, kCommandSource), powerstate_local,Shutter.switched_relay,manual_relays_changed); } else { last_source = SRC_SHUTTER; // avoid switch off in the next loop if (powerstate_local == 2) { // testing on CLOSE relay, if ON @@ -512,7 +523,7 @@ void ShutterRelayChanged(void) ShutterStartInit(i, 1, Shutter.open_max[i]); } } - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Shutter %d: Target: %ld, powerstatelocal %d"), i+1, Shutter.target_position[i], powerstate_local); + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Shutter %d: Target: %ld, powerstatelocal %d"), i+1, Shutter.target_position[i], powerstate_local); } } } @@ -604,15 +615,15 @@ void ShutterButtonHandler(void) // check for simultaneous shutter button press uint32 min_shutterbutton_press_counter = -1; // -1 == max(uint32) for (uint32_t i = 0; i < MAX_KEYS; i++) { - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Settings.shutter_button[i] %ld, shutter_index %d, Button.press_counter[i] %d, min_shutterbutton_press_counter %d, i %d"), Settings.shutter_button[i], shutter_index, Button.press_counter[i] , min_shutterbutton_press_counter, i); + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Settings.shutter_button[i] %ld, shutter_index %d, Button.press_counter[i] %d, min_shutterbutton_press_counter %d, i %d"), Settings.shutter_button[i], shutter_index, Button.press_counter[i] , min_shutterbutton_press_counter, i); if ((button_index != i) && (Settings.shutter_button[i] & (1<<31)) && ((Settings.shutter_button[i] & 0x03) == shutter_index) && (i != button_index) && (Button.press_counter[i] < min_shutterbutton_press_counter)) { min_shutterbutton_press_counter = Button.press_counter[i]; - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: min_shutterbutton_press_counter %d"), min_shutterbutton_press_counter); + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: min_shutterbutton_press_counter %d"), min_shutterbutton_press_counter); } } if (min_shutterbutton_press_counter == Button.press_counter[button_index]) { // simultaneous shutter button press detected - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: simultanous presss deteced")); + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: simultanous presss deteced")); press_index = Button.press_counter[button_index]; for (uint32_t i = 0; i < MAX_KEYS; i++) if ((Settings.shutter_button[i] & (1<<31)) && ((Settings.shutter_button[i] & 0x03) != shutter_index)) @@ -643,7 +654,7 @@ void ShutterButtonHandler(void) // 5x..7x && no SetOption1 (0) checked above // simultaneous or stand alone button press 5x, 6x, 7x detected char scmnd[20]; - GetTextIndexed(scmnd, sizeof(scmnd), press_index -3, kCommands); + snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_WIFICONFIG " 2")); ExecuteCommand(scmnd, SRC_BUTTON); return; } else if ((buttonState == SHT_PRESSED_EXT_HOLD_SIMULTANEOUS) || ((shutter_index_num_buttons==1) && (buttonState == SHT_PRESSED_EXT_HOLD))){ @@ -659,7 +670,7 @@ void ShutterButtonHandler(void) if (Settings.shutter_startrelay[shutter_index] && Settings.shutter_startrelay[shutter_index] <9) { uint8_t pos_press_index = (buttonState == SHT_PRESSED_HOLD) ? 3 : (press_index-1); if (pos_press_index>3) pos_press_index=3; - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: shutter %d, button %d = %d (single=1, double=2, tripple=3, hold=4)"), shutter_index+1, button_index+1, pos_press_index+1); + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: shutter %d, button %d = %d (single=1, double=2, tripple=3, hold=4)"), shutter_index+1, button_index+1, pos_press_index+1); XdrvMailbox.index = shutter_index +1; last_source = SRC_BUTTON; XdrvMailbox.data_len = 0; @@ -677,7 +688,13 @@ void ShutterButtonHandler(void) CmndShutterStop(); } else { XdrvMailbox.payload = position = (position-1)<<1; - CmndShutterPosition(); + //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: shutter %d -> %d"), shutter_index+1, position); + if (102 == position) { + XdrvMailbox.payload = XdrvMailbox.index; + CmndShutterToggle(); + } else { + CmndShutterPosition(); + } if (Settings.shutter_button[button_index] & ((0x01<<26)< 0) && (XdrvMailbox.index <= shutters_present)) { + uint32_t index = XdrvMailbox.index-1; + if (Shutter.direction[index]) { + CmndShutterStop(); + } else { + CmndShutterOpen(); + } + } +} + void CmndShutterClose(void) { - //AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Payload open: %d, i %d"), XdrvMailbox.payload, XdrvMailbox.i); + //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Payload close: %d, i %d"), XdrvMailbox.payload, XdrvMailbox.index); if ((1 == XdrvMailbox.index) && (XdrvMailbox.payload != -99)) { XdrvMailbox.index = XdrvMailbox.payload; } @@ -739,6 +767,45 @@ void CmndShutterClose(void) CmndShutterPosition(); } +void CmndShutterStopClose(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) { + uint32_t index = XdrvMailbox.index-1; + if (Shutter.direction[index]) { + CmndShutterStop(); + } else { + CmndShutterClose(); + } + } +} + +void CmndShutterToggle(void) +{ + //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Payload toggle: %d, i %d"), XdrvMailbox.payload, XdrvMailbox.index); + if ((1 == XdrvMailbox.index) && (XdrvMailbox.payload != -99)) { + XdrvMailbox.index = XdrvMailbox.payload; + } + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) { + uint32_t index = XdrvMailbox.index-1; + XdrvMailbox.payload = (50 < ShutterRealToPercentPosition(Shutter.real_position[index], index)) ? 0 : 100; + XdrvMailbox.data_len = 0; + last_source = SRC_WEBGUI; + CmndShutterPosition(); + } +} + +void CmndShutterStopToggle(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) { + uint32_t index = XdrvMailbox.index-1; + if (Shutter.direction[index]) { + CmndShutterStop(); + } else { + CmndShutterToggle(); + } + } +} + void CmndShutterStop(void) { if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) { @@ -749,7 +816,7 @@ void CmndShutterStop(void) uint32_t i = XdrvMailbox.index -1; if (Shutter.direction[i] != 0) { - AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Stop moving %d: dir: %d"), XdrvMailbox.index, Shutter.direction[i]); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Stop moving %d: dir: %d"), XdrvMailbox.index, Shutter.direction[i]); // set stop position 10 steps ahead (0.5sec to allow normal stop) int32_t temp_realpos = Shutter.start_position[i] + ( (Shutter.time[i]+10) * (Shutter.direction[i] > 0 ? 100 : -Shutter.close_velocity[i])); XdrvMailbox.payload = ShutterRealToPercentPosition(temp_realpos, i); @@ -773,21 +840,25 @@ void CmndShutterPosition(void) if (!(Settings.shutter_options[XdrvMailbox.index-1] & 2)) { uint32_t index = XdrvMailbox.index-1; //limit the payload - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Pos. in: payload %s (%d), payload %d, idx %d, src %d"), XdrvMailbox.data , XdrvMailbox.data_len, XdrvMailbox.payload , XdrvMailbox.index, last_source ); + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Pos. in: payload %s (%d), payload %d, idx %d, src %d"), XdrvMailbox.data , XdrvMailbox.data_len, XdrvMailbox.payload , XdrvMailbox.index, last_source ); // value 0 with data_len > 0 can mean Open // special handling fo UP,DOWN,TOGGLE,STOP command comming with payload -99 if ((XdrvMailbox.data_len > 1) && (XdrvMailbox.payload <= 0)) { //UpperCase(XdrvMailbox.data, XdrvMailbox.data); - if (!strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_UP) || !strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_OPEN) || ((Shutter.direction[index]==0) && !strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_TOGGLEUP))) { + if (!strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_UP) || !strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_OPEN) || ((Shutter.direction[index]==0) && !strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_STOPOPEN))) { CmndShutterOpen(); return; } - if (!strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_DOWN) || !strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_CLOSE) || ((Shutter.direction[index]==0) && !strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_TOGGLEDOWN))) { + if (!strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_DOWN) || !strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_CLOSE) || ((Shutter.direction[index]==0) && !strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_STOPCLOSE))) { CmndShutterClose(); return; } - if (!strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_STOP) || ((Shutter.direction[index]) && (!strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_TOGGLEUP) || !strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_TOGGLEDOWN)))) { + if (!strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_TOGGLE)) { + CmndShutterToggle(); + return; + } + if (!strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_STOP) || ((Shutter.direction[index]) && (!strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_STOPOPEN) || !strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_STOPCLOSE)))) { XdrvMailbox.payload = -99; CmndShutterStop(); return; @@ -802,7 +873,7 @@ void CmndShutterPosition(void) Shutter.target_position[index] = ShutterPercentToRealPosition(target_pos_percent, index); //Shutter.accelerator[index] = Shutter.max_pwm_frequency / ((Shutter.motordelay[index] > 0) ? Shutter.motordelay[index] : 1); //Shutter.target_position[index] = XdrvMailbox.payload < 5 ? Settings.shuttercoeff[2][index] * XdrvMailbox.payload : Settings.shuttercoeff[1][index] * XdrvMailbox.payload + Settings.shuttercoeff[0,index]; - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: lastsource %d:, real %d, target %d, payload %d"), last_source, Shutter.real_position[index] ,Shutter.target_position[index],target_pos_percent); + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: lastsource %d:, real %d, target %d, payload %d"), last_source, Shutter.real_position[index] ,Shutter.target_position[index],target_pos_percent); } if ( (target_pos_percent >= 0) && (target_pos_percent <= 100) && abs(Shutter.target_position[index] - Shutter.real_position[index] ) / Shutter.close_velocity[index] > 2) { if (Settings.shutter_options[index] & 4) { @@ -825,7 +896,7 @@ void CmndShutterPosition(void) } if (Shutter.direction[index] != new_shutterdirection) { if ((SHT_OFF_ON__OPEN_CLOSE == Shutter.mode) || (SHT_OFF_ON__OPEN_CLOSE_STEPPER == Shutter.mode)) { - //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Delay5 5s, xdrv %d"), XdrvMailbox.payload); + //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Delay5 5s, xdrv %d"), XdrvMailbox.payload); ShutterWaitForMotorStop(index); ExecuteCommandPower(Settings.shutter_startrelay[index], 0, SRC_SHUTTER); ShutterStartInit(index, new_shutterdirection, Shutter.target_position[index]); @@ -834,33 +905,48 @@ void CmndShutterPosition(void) ExecuteCommandPower(Settings.shutter_startrelay[index] +1, new_shutterdirection == 1 ? 0 : 1, SRC_SHUTTER); // power on ExecuteCommandPower(Settings.shutter_startrelay[index], 1, SRC_SHUTTER); + if (SHT_OFF_ON__OPEN_CLOSE_STEPPER == Shutter.mode) { + ExecuteCommandPower(Settings.shutter_startrelay[index]+2, 1, SRC_SHUTTER); + } } } else { // now start the motor for the right direction, work for momentary and normal shutters. - AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Start in dir %d"), Shutter.direction[index]); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Start in dir %d"), Shutter.direction[index]); ShutterStartInit(index, new_shutterdirection, Shutter.target_position[index]); if (Shutter.skip_relay_change == 0) { ExecuteCommandPower(Settings.shutter_startrelay[index] + (new_shutterdirection == 1 ? 0 : 1), 1, SRC_SHUTTER); } - //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Delay6 5s, xdrv %d"), XdrvMailbox.payload); + //AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Delay6 5s, xdrv %d"), XdrvMailbox.payload); } Shutter.switched_relay = 0; } } else { target_pos_percent = ShutterRealToPercentPosition(Shutter.real_position[index], index); - ShutterReportPosition(true); + ShutterReportPosition(true, index); } XdrvMailbox.index = index +1; // Fix random index for ShutterClose if (XdrvMailbox.command) ResponseCmndIdxNumber((Settings.shutter_options[index] & 1) ? 100 - target_pos_percent : target_pos_percent); } else { - ShutterReportPosition(true); + ShutterReportPosition(true, MAX_SHUTTERS); if (XdrvMailbox.command) ResponseCmndIdxChar("Locked"); } } } +void CmndShutterStopPosition(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) { + uint32_t index = XdrvMailbox.index-1; + if (Shutter.direction[index]) { + XdrvMailbox.payload = -99; + CmndShutterStop(); + } else { + CmndShutterPosition(); + } + } +} void CmndShutterOpenTime(void) { if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) { @@ -928,10 +1014,10 @@ void CmndShutterButton(void) // (setting>>28)&(0x01) : mqtt broadcast tripple press // (setting>>27)&(0x01) : mqtt broadcast double press // (setting>>26)&(0x01) : mqtt broadcast single press - // (setting>>20)&(0x3f) : shutter_position hold; 0 disabled, 1..101 == 0..100% - // (setting>>14)&(0x3f) : shutter_position tripple press 0 disabled, 1..101 == 0..100% - // (setting>> 8)&(0x3f) : shutter_position double press 0 disabled, 1..101 == 0..100% - // (setting>> 2)&(0x3f) : shutter_position single press 0 disabled, 1..101 == 0..100% + // (setting>>20)&(0x3f) : shutter_position hold; 0 disabled, 1..101 == 0..100%, 102 == toggle + // (setting>>14)&(0x3f) : shutter_position tripple press 0 disabled, 1..101 == 0..100%, 102 == toggle + // (setting>> 8)&(0x3f) : shutter_position double press 0 disabled, 1..101 == 0..100%, 102 == toggle + // (setting>> 2)&(0x3f) : shutter_position single press 0 disabled, 1..101 == 0..100%, 102 == toggle // (setting>> 0)&(0x03) : shutter_index if (XdrvMailbox.data_len > 0) { uint32_t i = 0; @@ -945,10 +1031,16 @@ void CmndShutterButton(void) // Loop through the data string, splitting on ' ' seperators. for (char *str = strtok_r(data_copy, " ", &str_ptr); str && i < (1+4+4+1); str = strtok_r(nullptr, " ", &str_ptr), i++) { int field; - if (str[0] == '-') { - field = -1; - } else { - field = atoi(str); + switch (str[0]) { + case '-': + field = -1; + break; + case 't': + field = 102; + break; + default: + field = atoi(str); + break; } switch (i) { case 0: @@ -971,18 +1063,22 @@ void CmndShutterButton(void) setting |= (((100>>1)+1)<<2) | (((0>>1)+1)<<8) | (((50>>1)+1)<<14); isShortCommand = true; break; + } else if (!strcmp_P(str, PSTR("toggle"))) { + setting |= (((102>>1)+1)<<2) | (((50>>1)+1)<<8); + isShortCommand = true; + break; } case 2: if (isShortCommand) { if ((field==1) && (setting & (0x3F<<(2+6*3)))) - // if short command up or down then also enable MQTT broadcast + // if short command up or down (hold press position set) then also enable MQTT broadcast setting |= (0x3<<29); done = true; break; } case 3: case 4: - if ((field >= -1) && (field<=100)) + if ((field >= -1) && (field<=102)) setting |= (((field>>1)+1)<<(i*6 + (2-6))); break; case 5: @@ -1023,8 +1119,12 @@ void CmndShutterButton(void) for (uint32_t j=0 ; j < 4 ; j++) { int8_t pos = (((setting>> (2+6*j))&(0x3f))-1)<<1; - if (pos>=0) - setting_chr_ptr += snprintf_P(setting_chr_ptr, 5, PSTR(" %d"), pos); + if (0 <= pos) + if (102 == pos) { + setting_chr_ptr += sprintf_P(setting_chr_ptr, PSTR(" t")); + } else { + setting_chr_ptr += snprintf_P(setting_chr_ptr, 5, PSTR(" %d"), pos); + } else setting_chr_ptr += sprintf_P(setting_chr_ptr, PSTR(" -")); } @@ -1076,6 +1176,16 @@ void CmndShutterSetClose(void) } } +void CmndShutterSetOpen(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) { + Shutter.real_position[XdrvMailbox.index -1] = Shutter.open_max[XdrvMailbox.index -1]; + ShutterStartInit(XdrvMailbox.index -1, 0, Shutter.open_max[XdrvMailbox.index -1]); + Settings.shutter_position[XdrvMailbox.index -1] = 100; + ResponseCmndIdxChar(D_CONFIGURATION_RESET); + } +} + void CmndShutterInvert(void) { if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) { @@ -1109,7 +1219,7 @@ void CmndShutterCalibration(void) } for (i = 0; i < 5; i++) { Settings.shuttercoeff[i][XdrvMailbox.index -1] = SHT_DIV_ROUND((uint32_t)messwerte[i] * 1000, messwerte[4]); - AddLog_P2(LOG_LEVEL_INFO, PSTR("Settings.shuttercoeff: %d, i: %d, value: %d, messwert %d"), i,XdrvMailbox.index -1,Settings.shuttercoeff[i][XdrvMailbox.index -1], messwerte[i]); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Settings.shuttercoeff: %d, i: %d, value: %d, messwert %d"), i,XdrvMailbox.index -1,Settings.shuttercoeff[i][XdrvMailbox.index -1], messwerte[i]); } ShutterInit(); ResponseCmndIdxChar(XdrvMailbox.data); @@ -1173,7 +1283,7 @@ bool Xdrv27(uint8_t function) break; case FUNC_EVERY_SECOND: //case FUNC_EVERY_250_MSECOND: - ShutterReportPosition(false); + ShutterReportPosition(false, MAX_SHUTTERS); break; case FUNC_COMMAND: diff --git a/tasmota/xdrv_28_pcf8574.ino b/tasmota/xdrv_28_pcf8574.ino index 95074fab8..888f34fee 100644 --- a/tasmota/xdrv_28_pcf8574.ino +++ b/tasmota/xdrv_28_pcf8574.ino @@ -160,7 +160,7 @@ void HandlePcf8574(void) AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_CONFIGURE_PCF8574)); - if (WebServer->hasArg("save")) { + if (Webserver->hasArg("save")) { Pcf8574SaveSettings(); WebRestart(1); return; @@ -193,9 +193,9 @@ void Pcf8574SaveSettings(void) char stemp[7]; char tmp[100]; - //AddLog_P(LOG_LEVEL_DEBUG, PSTR("PCF: Start working on Save arguements: inverted:%d")), WebServer->hasArg("b1"); + //AddLog_P(LOG_LEVEL_DEBUG, PSTR("PCF: Start working on Save arguements: inverted:%d")), Webserver->hasArg("b1"); - Settings.flag3.pcf8574_ports_inverted = WebServer->hasArg("b1"); // SetOption81 - Invert all ports on PCF8574 devices + Settings.flag3.pcf8574_ports_inverted = Webserver->hasArg("b1"); // SetOption81 - Invert all ports on PCF8574 devices for (byte idx = 0; idx < Pcf8574.max_devices; idx++) { byte count=0; byte n = Settings.pcf8574_config[idx]; @@ -248,7 +248,7 @@ bool Xdrv28(uint8_t function) WSContentSend_P(HTTP_BTN_MENU_PCF8574); break; case FUNC_WEB_ADD_HANDLER: - WebServer->on("/" WEB_HANDLE_PCF8574, HandlePcf8574); + Webserver->on("/" WEB_HANDLE_PCF8574, HandlePcf8574); break; #endif // USE_WEBSERVER } diff --git a/tasmota/xdrv_29_deepsleep.ino b/tasmota/xdrv_29_deepsleep.ino index 69366cdd8..4ac0531db 100644 --- a/tasmota/xdrv_29_deepsleep.ino +++ b/tasmota/xdrv_29_deepsleep.ino @@ -54,9 +54,9 @@ bool DeepSleepEnabled(void) return false; // Disabled } - if (pin[GPIO_DEEPSLEEP] < 99) { - pinMode(pin[GPIO_DEEPSLEEP], INPUT_PULLUP); - return (digitalRead(pin[GPIO_DEEPSLEEP])); // Disable DeepSleep if user holds pin GPIO_DEEPSLEEP low + if (PinUsed(GPIO_DEEPSLEEP)) { + pinMode(Pin(GPIO_DEEPSLEEP), INPUT_PULLUP); + return (digitalRead(Pin(GPIO_DEEPSLEEP))); // Disable DeepSleep if user holds pin GPIO_DEEPSLEEP low } return true; // Enabled diff --git a/tasmota/xdrv_30_exs_dimmer.ino b/tasmota/xdrv_30_exs_dimmer.ino index 765fba1c6..485112977 100644 --- a/tasmota/xdrv_30_exs_dimmer.ino +++ b/tasmota/xdrv_30_exs_dimmer.ino @@ -395,11 +395,11 @@ void EsxMcuStart(void) int retries = 3; #ifdef EXS_DEBUG - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("EXS: Request MCU configuration, PIN %d to Low"), pin[GPIO_EXS_ENABLE]); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("EXS: Request MCU configuration, PIN %d to Low"), Pin(GPIO_EXS_ENABLE)); #endif - pinMode(pin[GPIO_EXS_ENABLE], OUTPUT); - digitalWrite(pin[GPIO_EXS_ENABLE], LOW); + pinMode(Pin(GPIO_EXS_ENABLE), OUTPUT); + digitalWrite(Pin(GPIO_EXS_ENABLE), LOW); delay(1); // wait 1ms fot the MCU to come online @@ -413,13 +413,13 @@ void EsxMcuStart(void) void ExsInit(void) { #ifdef EXS_DEBUG - AddLog_P2(LOG_LEVEL_INFO, PSTR("EXS: Starting Tx %d Rx %d"), pin[GPIO_TXD], pin[GPIO_RXD]); + AddLog_P2(LOG_LEVEL_INFO, PSTR("EXS: Starting Tx %d Rx %d"), Pin(GPIO_TXD), Pin(GPIO_RXD)); #endif Exs.buffer = (uint8_t *)malloc(EXS_BUFFER_SIZE); if (Exs.buffer != nullptr) { - ExsSerial = new TasmotaSerial(pin[GPIO_RXD], pin[GPIO_TXD], 2); + ExsSerial = new TasmotaSerial(Pin(GPIO_RXD), Pin(GPIO_TXD), 2); if (ExsSerial->begin(9600)) { if (ExsSerial->hardwareSerial()) diff --git a/tasmota/xdrv_31_tasmota_client.ino b/tasmota/xdrv_31_tasmota_client.ino new file mode 100644 index 000000000..3fdbad076 --- /dev/null +++ b/tasmota/xdrv_31_tasmota_client.ino @@ -0,0 +1,587 @@ +/* + xdrv_31_tasmota_client.ino - Support for external microcontroller on serial + + Copyright (C) 2020 Andre Thomas and Theo Arends + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifdef USE_TASMOTA_CLIENT +/*********************************************************************************************\ + * Tasmota to microcontroller +\*********************************************************************************************/ + +#define XDRV_31 31 + +#define CONST_STK_CRC_EOP 0x20 + +#define CMND_STK_GET_SYNC 0x30 +#define CMND_STK_SET_DEVICE 0x42 +#define CMND_STK_SET_DEVICE_EXT 0x45 +#define CMND_STK_ENTER_PROGMODE 0x50 +#define CMND_STK_LEAVE_PROGMODE 0x51 +#define CMND_STK_LOAD_ADDRESS 0x55 +#define CMND_STK_PROG_PAGE 0x64 + +/*************************************************\ + * Tasmota Client Specific Commands +\*************************************************/ + +#define CMND_START 0xFC +#define CMND_END 0xFD + +#define CMND_FEATURES 0x01 +#define CMND_JSON 0x02 +#define CMND_FUNC_EVERY_SECOND 0x03 +#define CMND_FUNC_EVERY_100_MSECOND 0x04 +#define CMND_CLIENT_SEND 0x05 +#define CMND_PUBLISH_TELE 0x06 +#define CMND_EXECUTE_CMND 0x07 + +#define PARAM_DATA_START 0xFE +#define PARAM_DATA_END 0xFF + +#include + +/* + * Embedding class in here since its rather specific to Arduino bootloader + */ + +class SimpleHexParse { + public: + SimpleHexParse(void); + uint8_t parseLine(char *hexline); + uint8_t ptr_l = 0; + uint8_t ptr_h = 0; + bool PageIsReady = false; + bool firstrun = true; + bool EndOfFile = false; + uint8_t FlashPage[128]; + uint8_t FlashPageIdx = 0; + uint8_t layoverBuffer[16]; + uint8_t layoverIdx = 0; + uint8_t getByte(char *hexline, uint8_t idx); +}; + +SimpleHexParse::SimpleHexParse(void) { + +} + +uint8_t SimpleHexParse::parseLine(char *hexline) { + if (layoverIdx) { + memcpy(&FlashPage[0], &layoverBuffer[0], layoverIdx); + FlashPageIdx = layoverIdx; + layoverIdx = 0; + } + uint8_t len = getByte(hexline, 1); + uint8_t addr_h = getByte(hexline, 2); + uint8_t addr_l = getByte(hexline, 3); + uint8_t rectype = getByte(hexline, 4); + for (uint8_t idx = 0; idx < len; idx++) { + if (FlashPageIdx < 128) { + FlashPage[FlashPageIdx] = getByte(hexline, idx+5); + FlashPageIdx++; + } else { // We have layover bytes + layoverBuffer[layoverIdx] = getByte(hexline, idx+5); + layoverIdx++; + } + } + if (1 == rectype) { + EndOfFile = true; + while (FlashPageIdx < 128) { + FlashPage[FlashPageIdx] = 0xFF; + FlashPageIdx++; + } + } + if (FlashPageIdx == 128) { + if (firstrun) { + firstrun = false; + } else { + ptr_l += 0x40; + if (ptr_l == 0) { + ptr_l = 0; + ptr_h++; + } + } + firstrun = false; + PageIsReady = true; + } + return 0; +} + +uint8_t SimpleHexParse::getByte(char* hexline, uint8_t idx) { + char buff[3]; + buff[3] = '\0'; + memcpy(&buff, &hexline[(idx*2)-1], 2); + return strtol(buff, 0, 16); +} + +/* + * End of embedded class SimpleHexParse + */ + +struct TCLIENT { + uint32_t spi_hex_size = 0; + uint32_t spi_sector_counter = 0; + uint8_t spi_sector_cursor = 0; + uint8_t inverted = LOW; + bool type = false; + bool flashing = false; + bool SerialEnabled = false; + uint8_t waitstate = 0; // We use this so that features detection does not slow down other stuff on startup + bool unsupported = false; +} TClient; + +typedef union { + uint32_t data; + struct { + uint32_t func_json_append : 1; // Client supports providing a JSON for TELEPERIOD + uint32_t func_every_second : 1; // Client supports receiving a FUNC_EVERY_SECOND callback with no response + uint32_t func_every_100_msecond : 1; // Client supports receiving a FUNC_EVERY_100_MSECOND callback with no response + uint32_t func_client_send : 1; // Client supports receiving commands with "client send xxx" + uint32_t spare4 : 1; + uint32_t spare5 : 1; + uint32_t spare6 : 1; + uint32_t spare7 : 1; + uint32_t spare8 : 1; + uint32_t spare9 : 1; + uint32_t spare10 : 1; + uint32_t spare11 : 1; + uint32_t spare12 : 1; + uint32_t spare13 : 1; + uint32_t spare14 : 1; + uint32_t spare15 : 1; + uint32_t spare16 : 1; + uint32_t spare17 : 1; + uint32_t spare18 : 1; + uint32_t spare19 : 1; + uint32_t spare20 : 1; + uint32_t spare21 : 1; + uint32_t spare22 : 1; + uint32_t spare23 : 1; + uint32_t spare24 : 1; + uint32_t spare25 : 1; + uint32_t spare26 : 1; + uint32_t spare27 : 1; + uint32_t spare28 : 1; + uint32_t spare29 : 1; + uint32_t spare30 : 1; + uint32_t spare31 : 1; + }; +} TClientFeatureCfg; + +/* + * The structure below must remain 4 byte aligned to be compatible with + * Tasmota as master + */ + +struct TCLIENT_FEATURES { + uint32_t features_version; + TClientFeatureCfg features; +} TClientSettings; + +struct TCLIENT_COMMAND { + uint8_t command; + uint8_t parameter; + uint8_t unused2; + uint8_t unused3; +} TClientCommand; + +TasmotaSerial *TasmotaClient_Serial; + +uint32_t TasmotaClient_FlashStart(void) { + return (ESP.getSketchSize() / SPI_FLASH_SEC_SIZE) + 2; // Stay on the safe side +} + +uint8_t TasmotaClient_UpdateInit(void) { + TClient.spi_hex_size = 0; + TClient.spi_sector_counter = TasmotaClient_FlashStart(); // Reset the pre-defined write address where firmware will temporarily be stored + TClient.spi_sector_cursor = 0; + return 0; +} + +void TasmotaClient_Reset(void) { + if (TClient.SerialEnabled) { + digitalWrite(Pin(GPIO_TASMOTACLIENT_RST), !TClient.inverted); + delay(1); + digitalWrite(Pin(GPIO_TASMOTACLIENT_RST), TClient.inverted); + delay(1); + digitalWrite(Pin(GPIO_TASMOTACLIENT_RST), !TClient.inverted); + delay(5); + } +} + +uint8_t TasmotaClient_waitForSerialData(int dataCount, int timeout) { + int timer = 0; + while (timer < timeout) { + if (TasmotaClient_Serial->available() >= dataCount) { + return 1; + } + delay(1); + timer++; + } + return 0; +} + +uint8_t TasmotaClient_sendBytes(uint8_t* bytes, int count) { + TasmotaClient_Serial->write(bytes, count); + TasmotaClient_waitForSerialData(2, 250); + uint8_t sync = TasmotaClient_Serial->read(); + uint8_t ok = TasmotaClient_Serial->read(); + if ((sync == 0x14) && (ok == 0x10)) { + return 1; + } + return 0; +} + +uint8_t TasmotaClient_execCmd(uint8_t cmd) { + uint8_t bytes[] = { cmd, CONST_STK_CRC_EOP }; + return TasmotaClient_sendBytes(bytes, 2); +} + +uint8_t TasmotaClient_execParam(uint8_t cmd, uint8_t* params, int count) { + uint8_t bytes[32]; + bytes[0] = cmd; + int i = 0; + while (i < count) { + bytes[i + 1] = params[i]; + i++; + } + bytes[i + 1] = CONST_STK_CRC_EOP; + return TasmotaClient_sendBytes(bytes, i + 2); +} + +uint8_t TasmotaClient_exitProgMode(void) { + return TasmotaClient_execCmd(CMND_STK_LEAVE_PROGMODE); // Exit programming mode +} + +uint8_t TasmotaClient_SetupFlash(void) { + uint8_t ProgParams[] = {0x86, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x03, 0xff, 0xff, 0xff, 0xff, 0x00, 0x80, 0x04, 0x00, 0x00, 0x00, 0x80, 0x00}; + uint8_t ExtProgParams[] = {0x05, 0x04, 0xd7, 0xc2, 0x00}; + TasmotaClient_Serial->begin(USE_TASMOTA_CLIENT_FLASH_SPEED); + if (TasmotaClient_Serial->hardwareSerial()) { + ClaimSerial(); + } + + TasmotaClient_Reset(); + + uint8_t timeout = 0; + uint8_t no_error = 0; + while (50 > timeout) { + if (TasmotaClient_execCmd(CMND_STK_GET_SYNC)) { + timeout = 200; + no_error = 1; + } + timeout++; + delay(1); + } + if (no_error) { + AddLog_P2(LOG_LEVEL_INFO, PSTR("TCL: Found bootloader")); + } else { + no_error = 0; + AddLog_P2(LOG_LEVEL_INFO, PSTR("TCL: Bootloader could not be found")); + } + if (no_error) { + if (TasmotaClient_execParam(CMND_STK_SET_DEVICE, ProgParams, sizeof(ProgParams))) { + } else { + no_error = 0; + AddLog_P2(LOG_LEVEL_INFO, PSTR("TCL: Could not configure device for programming (1)")); + } + } + if (no_error) { + if (TasmotaClient_execParam(CMND_STK_SET_DEVICE_EXT, ExtProgParams, sizeof(ExtProgParams))) { + } else { + no_error = 0; + AddLog_P2(LOG_LEVEL_INFO, PSTR("TCL: Could not configure device for programming (2)")); + } + } + if (no_error) { + if (TasmotaClient_execCmd(CMND_STK_ENTER_PROGMODE)) { + } else { + no_error = 0; + AddLog_P2(LOG_LEVEL_INFO, PSTR("TCL: Failed to put bootloader into programming mode")); + } + } + return no_error; +} + +uint8_t TasmotaClient_loadAddress(uint8_t adrHi, uint8_t adrLo) { + uint8_t params[] = { adrLo, adrHi }; + return TasmotaClient_execParam(CMND_STK_LOAD_ADDRESS, params, sizeof(params)); +} + +void TasmotaClient_FlashPage(uint8_t addr_h, uint8_t addr_l, uint8_t* data) { + uint8_t Header[] = {CMND_STK_PROG_PAGE, 0x00, 0x80, 0x46}; + TasmotaClient_loadAddress(addr_h, addr_l); + TasmotaClient_Serial->write(Header, 4); + for (int i = 0; i < 128; i++) { + TasmotaClient_Serial->write(data[i]); + } + TasmotaClient_Serial->write(CONST_STK_CRC_EOP); + TasmotaClient_waitForSerialData(2, 250); + TasmotaClient_Serial->read(); + TasmotaClient_Serial->read(); +} + +void TasmotaClient_Flash(void) { + bool reading = true; + uint32_t read = 0; + uint32_t processed = 0; + char thishexline[50]; + uint8_t position = 0; + char* flash_buffer; + + SimpleHexParse hexParse = SimpleHexParse(); + + if (!TasmotaClient_SetupFlash()) { + AddLog_P2(LOG_LEVEL_INFO, PSTR("TCL: Flashing aborted!")); + TClient.flashing = false; + restart_flag = 2; + return; + } + + flash_buffer = new char[SPI_FLASH_SEC_SIZE]; + uint32_t flash_start = TasmotaClient_FlashStart() * SPI_FLASH_SEC_SIZE; + while (reading) { + ESP.flashRead(flash_start + read, (uint32_t*)flash_buffer, SPI_FLASH_SEC_SIZE); + read = read + SPI_FLASH_SEC_SIZE; + if (read >= TClient.spi_hex_size) { + reading = false; + } + for (uint32_t ca = 0; ca < SPI_FLASH_SEC_SIZE; ca++) { + processed++; + if ((processed <= TClient.spi_hex_size) && (!hexParse.EndOfFile)) { + if (':' == flash_buffer[ca]) { + position = 0; + } + if (0x0D == flash_buffer[ca]) { + thishexline[position] = 0; + hexParse.parseLine(thishexline); + if (hexParse.PageIsReady) { + TasmotaClient_FlashPage(hexParse.ptr_h, hexParse.ptr_l, hexParse.FlashPage); + hexParse.PageIsReady = false; + hexParse.FlashPageIdx = 0; + } + } else { + if (0x0A != flash_buffer[ca]) { + thishexline[position] = flash_buffer[ca]; + position++; + } + } + } + } + } + TasmotaClient_exitProgMode(); + AddLog_P2(LOG_LEVEL_INFO, PSTR("TCL: Flash done!")); + TClient.flashing = false; + restart_flag = 2; +} + +void TasmotaClient_SetFlagFlashing(bool value) { + TClient.flashing = value; +} + +bool TasmotaClient_GetFlagFlashing(void) { + return TClient.flashing; +} + +void TasmotaClient_WriteBuffer(uint8_t *buf, size_t size) { + if (0 == TClient.spi_sector_cursor) { // Starting a new sector write so we need to erase it first + ESP.flashEraseSector(TClient.spi_sector_counter); + } + TClient.spi_sector_cursor++; + ESP.flashWrite((TClient.spi_sector_counter * SPI_FLASH_SEC_SIZE) + ((TClient.spi_sector_cursor-1)*2048), (uint32_t*)buf, size); + TClient.spi_hex_size = TClient.spi_hex_size + size; + if (2 == TClient.spi_sector_cursor) { // The web upload sends 2048 bytes at a time so keep track of the cursor position to reset it for the next flash sector erase + TClient.spi_sector_cursor = 0; + TClient.spi_sector_counter++; + } +} + +void TasmotaClient_Init(void) { + if (TClient.type) { + return; + } + if (10 > TClient.waitstate) { + TClient.waitstate++; + return; + } + if (!TClient.SerialEnabled) { + if (PinUsed(GPIO_TASMOTACLIENT_RXD) && PinUsed(GPIO_TASMOTACLIENT_TXD) && + (PinUsed(GPIO_TASMOTACLIENT_RST) || PinUsed(GPIO_TASMOTACLIENT_RST_INV))) { + TasmotaClient_Serial = new TasmotaSerial(Pin(GPIO_TASMOTACLIENT_RXD), Pin(GPIO_TASMOTACLIENT_TXD), 1, 0, 200); + if (TasmotaClient_Serial->begin(USE_TASMOTA_CLIENT_SERIAL_SPEED)) { + if (TasmotaClient_Serial->hardwareSerial()) { + ClaimSerial(); + } + TasmotaClient_Serial->setTimeout(100); // Theo 20200502 - increase from 50 + if (PinUsed(GPIO_TASMOTACLIENT_RST_INV)) { + SetPin(Pin(GPIO_TASMOTACLIENT_RST_INV), AGPIO(GPIO_TASMOTACLIENT_RST)); + TClient.inverted = HIGH; + } + pinMode(Pin(GPIO_TASMOTACLIENT_RST), OUTPUT); + TClient.SerialEnabled = true; + TasmotaClient_Reset(); + AddLog_P2(LOG_LEVEL_INFO, PSTR("TCL: Enabled")); + } + } + } + if (TClient.SerialEnabled) { // All go for hardware now we need to detect features if there are any + TasmotaClient_sendCmnd(CMND_FEATURES, 0); + char buffer[32] = { 0 }; + TasmotaClient_Serial->readBytesUntil(char(PARAM_DATA_START), buffer, sizeof(buffer)); + uint8_t len = TasmotaClient_Serial->readBytesUntil(char(PARAM_DATA_END), buffer, sizeof(buffer)); + + if (len) { AddLogBuffer(LOG_LEVEL_DEBUG_MORE, (uint8_t*)buffer, len); } // Theo 20200502 - DMP: 99 17 34 01 02 00 00 00 + + memcpy(&TClientSettings, &buffer, sizeof(TClientSettings)); + if (20191129 == TClientSettings.features_version) { + TClient.type = true; + AddLog_P2(LOG_LEVEL_INFO, PSTR("TCL: Version %u"), TClientSettings.features_version); + } else { + if ((!TClient.unsupported) && (TClientSettings.features_version > 0)) { + AddLog_P2(LOG_LEVEL_INFO, PSTR("TCL: Version %u not supported!"), TClientSettings.features_version); + TClient.unsupported = true; + } + } + } +} + +void TasmotaClient_Show(void) { + if ((TClient.type) && (TClientSettings.features.func_json_append)) { + char buffer[100]; + TasmotaClient_sendCmnd(CMND_JSON, 0); + TasmotaClient_Serial->readBytesUntil(char(PARAM_DATA_START), buffer, sizeof(buffer)-1); + uint8_t len = TasmotaClient_Serial->readBytesUntil(char(PARAM_DATA_END), buffer, sizeof(buffer)-1); + buffer[len] = '\0'; + ResponseAppend_P(PSTR(",\"TasmotaClient\":%s"), buffer); + } +} + +void TasmotaClient_sendCmnd(uint8_t cmnd, uint8_t param) { + TClientCommand.command = cmnd; + TClientCommand.parameter = param; + char buffer[sizeof(TClientCommand)+2]; + buffer[0] = CMND_START; + memcpy(&buffer[1], &TClientCommand, sizeof(TClientCommand)); + buffer[sizeof(TClientCommand)+1] = CMND_END; + + TasmotaClient_Serial->flush(); // Theo 20200502 + + for (uint8_t ca = 0; ca < sizeof(buffer); ca++) { + TasmotaClient_Serial->write(buffer[ca]); + } +} + +#define D_PRFX_CLIENT "Client" +#define D_CMND_CLIENT_RESET "Reset" +#define D_CMND_CLIENT_SEND "Send" + +const char kTasmotaClientCommands[] PROGMEM = D_PRFX_CLIENT "|" + D_CMND_CLIENT_RESET "|" D_CMND_CLIENT_SEND; + +void (* const TasmotaClientCommand[])(void) PROGMEM = { + &CmndClientReset, &CmndClientSend }; + +void CmndClientReset(void) { + TasmotaClient_Reset(); + TClient.type = false; // Force redetection + TClient.waitstate = 7; // give it at least 3 seconds to restart from bootloader + TClient.unsupported = false; // Reset unsupported flag + ResponseCmndDone(); +} + +void CmndClientSend(void) { + if (TClient.SerialEnabled) { + if (0 < XdrvMailbox.data_len) { + TasmotaClient_sendCmnd(CMND_CLIENT_SEND, XdrvMailbox.data_len); + TasmotaClient_Serial->write(char(PARAM_DATA_START)); + for (uint8_t idx = 0; idx < XdrvMailbox.data_len; idx++) { + TasmotaClient_Serial->write(XdrvMailbox.data[idx]); + } + TasmotaClient_Serial->write(char(PARAM_DATA_END)); + } + ResponseCmndDone(); + } +} + +void TasmotaClient_ProcessIn(void) { + uint8_t cmnd = TasmotaClient_Serial->read(); + if (CMND_START == cmnd) { + TasmotaClient_waitForSerialData(sizeof(TClientCommand),50); + uint8_t buffer[sizeof(TClientCommand)]; + for (uint8_t idx = 0; idx < sizeof(TClientCommand); idx++) { + buffer[idx] = TasmotaClient_Serial->read(); + } + TasmotaClient_Serial->read(); // read trailing byte of command + memcpy(&TClientCommand, &buffer, sizeof(TClientCommand)); + char inbuf[TClientCommand.parameter+1]; + TasmotaClient_waitForSerialData(TClientCommand.parameter, 50); + TasmotaClient_Serial->read(); // Read leading byte + for (uint8_t idx = 0; idx < TClientCommand.parameter; idx++) { + inbuf[idx] = TasmotaClient_Serial->read(); + } + TasmotaClient_Serial->read(); // Read trailing byte + inbuf[TClientCommand.parameter] = '\0'; + + if (CMND_PUBLISH_TELE == TClientCommand.command) { // We need to publish stat/ with incoming stream as content + Response_P(PSTR("{\"TasmotaClient\":")); + ResponseAppend_P("%s", inbuf); + ResponseJsonEnd(); + MqttPublishPrefixTopic_P(RESULT_OR_TELE, mqtt_data); + XdrvRulesProcess(); + } + if (CMND_EXECUTE_CMND == TClientCommand.command) { // We need to execute the incoming command + ExecuteCommand(inbuf, SRC_IGNORE); + } + } +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xdrv31(uint8_t function) { + bool result = false; + + switch (function) { + case FUNC_EVERY_100_MSECOND: + if (TClient.type) { + if (TasmotaClient_Serial->available()) { + TasmotaClient_ProcessIn(); + } + if (TClientSettings.features.func_every_100_msecond) { + TasmotaClient_sendCmnd(CMND_FUNC_EVERY_100_MSECOND, 0); + } + } + break; + case FUNC_EVERY_SECOND: + if ((TClient.type) && (TClientSettings.features.func_every_second)) { + TasmotaClient_sendCmnd(CMND_FUNC_EVERY_SECOND, 0); + } + TasmotaClient_Init(); + break; + case FUNC_JSON_APPEND: + if ((TClient.type) && (TClientSettings.features.func_json_append)) { + TasmotaClient_Show(); + } + break; + case FUNC_COMMAND: + result = DecodeCommand(kTasmotaClientCommands, TasmotaClientCommand); + break; + } + return result; +} + +#endif // USE_TASMOTA_CLIENT diff --git a/tasmota/xdrv_31_tasmota_slave.ino b/tasmota/xdrv_31_tasmota_slave.ino deleted file mode 100644 index a30e05bd3..000000000 --- a/tasmota/xdrv_31_tasmota_slave.ino +++ /dev/null @@ -1,610 +0,0 @@ -/* - xdrv_31_tasmota_slave.ino - Support for external microcontroller slave on serial - - Copyright (C) 2020 Andre Thomas and Theo Arends - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#ifdef USE_TASMOTA_SLAVE -/*********************************************************************************************\ - * Tasmota slave -\*********************************************************************************************/ - -#define XDRV_31 31 - -#define CONST_STK_CRC_EOP 0x20 - -#define CMND_STK_GET_SYNC 0x30 -#define CMND_STK_SET_DEVICE 0x42 -#define CMND_STK_SET_DEVICE_EXT 0x45 -#define CMND_STK_ENTER_PROGMODE 0x50 -#define CMND_STK_LEAVE_PROGMODE 0x51 -#define CMND_STK_LOAD_ADDRESS 0x55 -#define CMND_STK_PROG_PAGE 0x64 - -/*************************************************\ - * Tasmota Slave Specific Commands -\*************************************************/ - -#define CMND_START 0xFC -#define CMND_END 0xFD - -#define CMND_FEATURES 0x01 -#define CMND_JSON 0x02 -#define CMND_FUNC_EVERY_SECOND 0x03 -#define CMND_FUNC_EVERY_100_MSECOND 0x04 -#define CMND_SLAVE_SEND 0x05 -#define CMND_PUBLISH_TELE 0x06 -#define CMND_EXECUTE_CMND 0x07 - -#define PARAM_DATA_START 0xFE -#define PARAM_DATA_END 0xFF - -#include - -/* - * Embedding class in here since its rather specific to Arduino bootloader - */ - -class SimpleHexParse { - public: - SimpleHexParse(void); - uint8_t parseLine(char *hexline); - uint8_t ptr_l = 0; - uint8_t ptr_h = 0; - bool PageIsReady = false; - bool firstrun = true; - bool EndOfFile = false; - uint8_t FlashPage[128]; - uint8_t FlashPageIdx = 0; - uint8_t layoverBuffer[16]; - uint8_t layoverIdx = 0; - uint8_t getByte(char *hexline, uint8_t idx); -}; - -SimpleHexParse::SimpleHexParse(void) -{ - -} - -uint8_t SimpleHexParse::parseLine(char *hexline) -{ - if (layoverIdx) { - memcpy(&FlashPage[0], &layoverBuffer[0], layoverIdx); - FlashPageIdx = layoverIdx; - layoverIdx = 0; - } - uint8_t len = getByte(hexline, 1); - uint8_t addr_h = getByte(hexline, 2); - uint8_t addr_l = getByte(hexline, 3); - uint8_t rectype = getByte(hexline, 4); - for (uint8_t idx = 0; idx < len; idx++) { - if (FlashPageIdx < 128) { - FlashPage[FlashPageIdx] = getByte(hexline, idx+5); - FlashPageIdx++; - } else { // We have layover bytes - layoverBuffer[layoverIdx] = getByte(hexline, idx+5); - layoverIdx++; - } - } - if (1 == rectype) { - EndOfFile = true; - while (FlashPageIdx < 128) { - FlashPage[FlashPageIdx] = 0xFF; - FlashPageIdx++; - } - } - if (FlashPageIdx == 128) { - if (firstrun) { - firstrun = false; - } else { - ptr_l += 0x40; - if (ptr_l == 0) { - ptr_l = 0; - ptr_h++; - } - } - firstrun = false; - PageIsReady = true; - } - return 0; -} - -uint8_t SimpleHexParse::getByte(char* hexline, uint8_t idx) -{ - char buff[3]; - buff[3] = '\0'; - memcpy(&buff, &hexline[(idx*2)-1], 2); - return strtol(buff, 0, 16); -} - -/* - * End of embedded class SimpleHexParse - */ - -struct TSLAVE { - uint32_t spi_hex_size = 0; - uint32_t spi_sector_counter = 0; - uint8_t spi_sector_cursor = 0; - uint8_t inverted = LOW; - bool type = false; - bool flashing = false; - bool SerialEnabled = false; - uint8_t waitstate = 0; // We use this so that features detection does not slow down other stuff on startup - bool unsupported = false; -} TSlave; - -typedef union { - uint32_t data; - struct { - uint32_t func_json_append : 1; // Slave supports providing a JSON for TELEPERIOD - uint32_t func_every_second : 1; // Slave supports receiving a FUNC_EVERY_SECOND callback with no response - uint32_t func_every_100_msecond : 1; // Slave supports receiving a FUNC_EVERY_100_MSECOND callback with no response - uint32_t func_slave_send : 1; // Slave supports receiving commands with "slave send xxx" - uint32_t spare4 : 1; - uint32_t spare5 : 1; - uint32_t spare6 : 1; - uint32_t spare7 : 1; - uint32_t spare8 : 1; - uint32_t spare9 : 1; - uint32_t spare10 : 1; - uint32_t spare11 : 1; - uint32_t spare12 : 1; - uint32_t spare13 : 1; - uint32_t spare14 : 1; - uint32_t spare15 : 1; - uint32_t spare16 : 1; - uint32_t spare17 : 1; - uint32_t spare18 : 1; - uint32_t spare19 : 1; - uint32_t spare20 : 1; - uint32_t spare21 : 1; - uint32_t spare22 : 1; - uint32_t spare23 : 1; - uint32_t spare24 : 1; - uint32_t spare25 : 1; - uint32_t spare26 : 1; - uint32_t spare27 : 1; - uint32_t spare28 : 1; - uint32_t spare29 : 1; - uint32_t spare30 : 1; - uint32_t spare31 : 1; - }; -} TSlaveFeatureCfg; - -/* - * The structure below must remain 4 byte aligned to be compatible with - * Tasmota as master - */ - -struct TSLAVE_FEATURES { - uint32_t features_version; - TSlaveFeatureCfg features; -} TSlaveSettings; - -struct TSLAVE_COMMAND { - uint8_t command; - uint8_t parameter; - uint8_t unused2; - uint8_t unused3; -} TSlaveCommand; - -TasmotaSerial *TasmotaSlave_Serial; - -uint32_t TasmotaSlave_FlashStart(void) -{ - return (ESP.getSketchSize() / SPI_FLASH_SEC_SIZE) + 2; // Stay on the safe side -} - -uint8_t TasmotaSlave_UpdateInit(void) -{ - TSlave.spi_hex_size = 0; - TSlave.spi_sector_counter = TasmotaSlave_FlashStart(); // Reset the pre-defined write address where firmware will temporarily be stored - TSlave.spi_sector_cursor = 0; - return 0; -} - -void TasmotaSlave_Reset(void) -{ - if (TSlave.SerialEnabled) { - digitalWrite(pin[GPIO_TASMOTASLAVE_RST], !TSlave.inverted); - delay(1); - digitalWrite(pin[GPIO_TASMOTASLAVE_RST], TSlave.inverted); - delay(1); - digitalWrite(pin[GPIO_TASMOTASLAVE_RST], !TSlave.inverted); - delay(5); - } -} - -uint8_t TasmotaSlave_waitForSerialData(int dataCount, int timeout) -{ - int timer = 0; - while (timer < timeout) { - if (TasmotaSlave_Serial->available() >= dataCount) { - return 1; - } - delay(1); - timer++; - } - return 0; -} - -uint8_t TasmotaSlave_sendBytes(uint8_t* bytes, int count) -{ - TasmotaSlave_Serial->write(bytes, count); - TasmotaSlave_waitForSerialData(2, 250); - uint8_t sync = TasmotaSlave_Serial->read(); - uint8_t ok = TasmotaSlave_Serial->read(); - if ((sync == 0x14) && (ok == 0x10)) { - return 1; - } - return 0; -} - -uint8_t TasmotaSlave_execCmd(uint8_t cmd) -{ - uint8_t bytes[] = { cmd, CONST_STK_CRC_EOP }; - return TasmotaSlave_sendBytes(bytes, 2); -} - -uint8_t TasmotaSlave_execParam(uint8_t cmd, uint8_t* params, int count) -{ - uint8_t bytes[32]; - bytes[0] = cmd; - int i = 0; - while (i < count) { - bytes[i + 1] = params[i]; - i++; - } - bytes[i + 1] = CONST_STK_CRC_EOP; - return TasmotaSlave_sendBytes(bytes, i + 2); -} - -uint8_t TasmotaSlave_exitProgMode(void) -{ - return TasmotaSlave_execCmd(CMND_STK_LEAVE_PROGMODE); // Exit programming mode -} - -uint8_t TasmotaSlave_SetupFlash(void) -{ - uint8_t ProgParams[] = {0x86, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x03, 0xff, 0xff, 0xff, 0xff, 0x00, 0x80, 0x04, 0x00, 0x00, 0x00, 0x80, 0x00}; - uint8_t ExtProgParams[] = {0x05, 0x04, 0xd7, 0xc2, 0x00}; - TasmotaSlave_Serial->begin(USE_TASMOTA_SLAVE_FLASH_SPEED); - if (TasmotaSlave_Serial->hardwareSerial()) { - ClaimSerial(); - } - - TasmotaSlave_Reset(); - - uint8_t timeout = 0; - uint8_t no_error = 0; - while (50 > timeout) { - if (TasmotaSlave_execCmd(CMND_STK_GET_SYNC)) { - timeout = 200; - no_error = 1; - } - timeout++; - delay(1); - } - if (no_error) { - AddLog_P2(LOG_LEVEL_INFO, PSTR("TasmotaSlave: Found bootloader")); - } else { - no_error = 0; - AddLog_P2(LOG_LEVEL_INFO, PSTR("TasmotaSlave: Bootloader could not be found")); - } - if (no_error) { - if (TasmotaSlave_execParam(CMND_STK_SET_DEVICE, ProgParams, sizeof(ProgParams))) { - } else { - no_error = 0; - AddLog_P2(LOG_LEVEL_INFO, PSTR("TasmotaSlave: Could not configure device for programming (1)")); - } - } - if (no_error) { - if (TasmotaSlave_execParam(CMND_STK_SET_DEVICE_EXT, ExtProgParams, sizeof(ExtProgParams))) { - } else { - no_error = 0; - AddLog_P2(LOG_LEVEL_INFO, PSTR("TasmotaSlave: Could not configure device for programming (2)")); - } - } - if (no_error) { - if (TasmotaSlave_execCmd(CMND_STK_ENTER_PROGMODE)) { - } else { - no_error = 0; - AddLog_P2(LOG_LEVEL_INFO, PSTR("TasmotaSlave: Failed to put bootloader into programming mode")); - } - } - return no_error; -} - -uint8_t TasmotaSlave_loadAddress(uint8_t adrHi, uint8_t adrLo) -{ - uint8_t params[] = { adrLo, adrHi }; - return TasmotaSlave_execParam(CMND_STK_LOAD_ADDRESS, params, sizeof(params)); -} - -void TasmotaSlave_FlashPage(uint8_t addr_h, uint8_t addr_l, uint8_t* data) -{ - uint8_t Header[] = {CMND_STK_PROG_PAGE, 0x00, 0x80, 0x46}; - TasmotaSlave_loadAddress(addr_h, addr_l); - TasmotaSlave_Serial->write(Header, 4); - for (int i = 0; i < 128; i++) { - TasmotaSlave_Serial->write(data[i]); - } - TasmotaSlave_Serial->write(CONST_STK_CRC_EOP); - TasmotaSlave_waitForSerialData(2, 250); - TasmotaSlave_Serial->read(); - TasmotaSlave_Serial->read(); -} - -void TasmotaSlave_Flash(void) -{ - bool reading = true; - uint32_t read = 0; - uint32_t processed = 0; - char thishexline[50]; - uint8_t position = 0; - char* flash_buffer; - - SimpleHexParse hexParse = SimpleHexParse(); - - if (!TasmotaSlave_SetupFlash()) { - AddLog_P2(LOG_LEVEL_INFO, PSTR("TasmotaSlave: Flashing aborted!")); - TSlave.flashing = false; - restart_flag = 2; - return; - } - - flash_buffer = new char[SPI_FLASH_SEC_SIZE]; - uint32_t flash_start = TasmotaSlave_FlashStart() * SPI_FLASH_SEC_SIZE; - while (reading) { - ESP.flashRead(flash_start + read, (uint32_t*)flash_buffer, SPI_FLASH_SEC_SIZE); - read = read + SPI_FLASH_SEC_SIZE; - if (read >= TSlave.spi_hex_size) { - reading = false; - } - for (uint32_t ca = 0; ca < SPI_FLASH_SEC_SIZE; ca++) { - processed++; - if ((processed <= TSlave.spi_hex_size) && (!hexParse.EndOfFile)) { - if (':' == flash_buffer[ca]) { - position = 0; - } - if (0x0D == flash_buffer[ca]) { - thishexline[position] = 0; - hexParse.parseLine(thishexline); - if (hexParse.PageIsReady) { - TasmotaSlave_FlashPage(hexParse.ptr_h, hexParse.ptr_l, hexParse.FlashPage); - hexParse.PageIsReady = false; - hexParse.FlashPageIdx = 0; - } - } else { - if (0x0A != flash_buffer[ca]) { - thishexline[position] = flash_buffer[ca]; - position++; - } - } - } - } - } - TasmotaSlave_exitProgMode(); - AddLog_P2(LOG_LEVEL_INFO, PSTR("TasmotaSlave: Flash done!")); - TSlave.flashing = false; - restart_flag = 2; -} - -void TasmotaSlave_SetFlagFlashing(bool value) -{ - TSlave.flashing = value; -} - -bool TasmotaSlave_GetFlagFlashing(void) -{ - return TSlave.flashing; -} - -void TasmotaSlave_WriteBuffer(uint8_t *buf, size_t size) -{ - if (0 == TSlave.spi_sector_cursor) { // Starting a new sector write so we need to erase it first - ESP.flashEraseSector(TSlave.spi_sector_counter); - } - TSlave.spi_sector_cursor++; - ESP.flashWrite((TSlave.spi_sector_counter * SPI_FLASH_SEC_SIZE) + ((TSlave.spi_sector_cursor-1)*2048), (uint32_t*)buf, size); - TSlave.spi_hex_size = TSlave.spi_hex_size + size; - if (2 == TSlave.spi_sector_cursor) { // The web upload sends 2048 bytes at a time so keep track of the cursor position to reset it for the next flash sector erase - TSlave.spi_sector_cursor = 0; - TSlave.spi_sector_counter++; - } -} - -void TasmotaSlave_Init(void) -{ - if (TSlave.type) { - return; - } - if (10 > TSlave.waitstate) { - TSlave.waitstate++; - return; - } - if (!TSlave.SerialEnabled) { - if ((pin[GPIO_TASMOTASLAVE_RXD] < 99) && (pin[GPIO_TASMOTASLAVE_TXD] < 99) && - ((pin[GPIO_TASMOTASLAVE_RST] < 99) || (pin[GPIO_TASMOTASLAVE_RST_INV] < 99))) { - TasmotaSlave_Serial = new TasmotaSerial(pin[GPIO_TASMOTASLAVE_RXD], pin[GPIO_TASMOTASLAVE_TXD], 1, 0, 200); - if (TasmotaSlave_Serial->begin(USE_TASMOTA_SLAVE_SERIAL_SPEED)) { - if (TasmotaSlave_Serial->hardwareSerial()) { - ClaimSerial(); - } - TasmotaSlave_Serial->setTimeout(50); - if (pin[GPIO_TASMOTASLAVE_RST_INV] < 99) { - pin[GPIO_TASMOTASLAVE_RST] = pin[GPIO_TASMOTASLAVE_RST_INV]; - pin[GPIO_TASMOTASLAVE_RST_INV] = 99; - TSlave.inverted = HIGH; - } - pinMode(pin[GPIO_TASMOTASLAVE_RST], OUTPUT); - TSlave.SerialEnabled = true; - TasmotaSlave_Reset(); - AddLog_P2(LOG_LEVEL_INFO, PSTR("Tasmota Slave Enabled")); - } - } - } - if (TSlave.SerialEnabled) { // All go for hardware now we need to detect features if there are any - TasmotaSlave_sendCmnd(CMND_FEATURES, 0); - char buffer[32]; - TasmotaSlave_Serial->readBytesUntil(char(PARAM_DATA_START), buffer, sizeof(buffer)); - uint8_t len = TasmotaSlave_Serial->readBytesUntil(char(PARAM_DATA_END), buffer, sizeof(buffer)); - memcpy(&TSlaveSettings, &buffer, sizeof(TSlaveSettings)); - if (20191129 == TSlaveSettings.features_version) { - TSlave.type = true; - AddLog_P2(LOG_LEVEL_INFO, PSTR("Tasmota Slave Version %u"), TSlaveSettings.features_version); - } else { - if ((!TSlave.unsupported) && (TSlaveSettings.features_version > 0)) { - AddLog_P2(LOG_LEVEL_INFO, PSTR("Tasmota Slave Version %u not supported!"), TSlaveSettings.features_version); - TSlave.unsupported = true; - } - } - } -} - -void TasmotaSlave_Show(void) -{ - if ((TSlave.type) && (TSlaveSettings.features.func_json_append)) { - char buffer[100]; - TasmotaSlave_sendCmnd(CMND_JSON, 0); - TasmotaSlave_Serial->readBytesUntil(char(PARAM_DATA_START), buffer, sizeof(buffer)-1); - uint8_t len = TasmotaSlave_Serial->readBytesUntil(char(PARAM_DATA_END), buffer, sizeof(buffer)-1); - buffer[len] = '\0'; - ResponseAppend_P(PSTR(",\"TasmotaSlave\":%s"), buffer); - } -} - -void TasmotaSlave_sendCmnd(uint8_t cmnd, uint8_t param) -{ - TSlaveCommand.command = cmnd; - TSlaveCommand.parameter = param; - char buffer[sizeof(TSlaveCommand)+2]; - buffer[0] = CMND_START; - memcpy(&buffer[1], &TSlaveCommand, sizeof(TSlaveCommand)); - buffer[sizeof(TSlaveCommand)+1] = CMND_END; - for (uint8_t ca = 0; ca < sizeof(buffer); ca++) { - TasmotaSlave_Serial->write(buffer[ca]); - } -} - -#define D_PRFX_SLAVE "Slave" -#define D_CMND_SLAVE_RESET "Reset" -#define D_CMND_SLAVE_SEND "Send" - -const char kTasmotaSlaveCommands[] PROGMEM = D_PRFX_SLAVE "|" - D_CMND_SLAVE_RESET "|" D_CMND_SLAVE_SEND; - -void (* const TasmotaSlaveCommand[])(void) PROGMEM = { - &CmndTasmotaSlaveReset, &CmndTasmotaSlaveSend }; - -void CmndTasmotaSlaveReset(void) -{ - TasmotaSlave_Reset(); - TSlave.type = false; // Force redetection - TSlave.waitstate = 7; // give it at least 3 seconds to restart from bootloader - TSlave.unsupported = false; // Reset unsupported flag - ResponseCmndDone(); -} - -void CmndTasmotaSlaveSend(void) -{ - if (0 < XdrvMailbox.data_len) { - TasmotaSlave_sendCmnd(CMND_SLAVE_SEND, XdrvMailbox.data_len); - TasmotaSlave_Serial->write(char(PARAM_DATA_START)); - for (uint8_t idx = 0; idx < XdrvMailbox.data_len; idx++) { - TasmotaSlave_Serial->write(XdrvMailbox.data[idx]); - } - TasmotaSlave_Serial->write(char(PARAM_DATA_END)); - } - ResponseCmndDone(); -} - -void TasmotaSlave_ProcessIn(void) -{ - uint8_t cmnd = TasmotaSlave_Serial->read(); - switch (cmnd) { - case CMND_START: - TasmotaSlave_waitForSerialData(sizeof(TSlaveCommand),50); - uint8_t buffer[sizeof(TSlaveCommand)]; - for (uint8_t idx = 0; idx < sizeof(TSlaveCommand); idx++) { - buffer[idx] = TasmotaSlave_Serial->read(); - } - TasmotaSlave_Serial->read(); // read trailing byte of command - memcpy(&TSlaveCommand, &buffer, sizeof(TSlaveCommand)); - char inbuf[TSlaveCommand.parameter+1]; - TasmotaSlave_waitForSerialData(TSlaveCommand.parameter, 50); - TasmotaSlave_Serial->read(); // Read leading byte - for (uint8_t idx = 0; idx < TSlaveCommand.parameter; idx++) { - inbuf[idx] = TasmotaSlave_Serial->read(); - } - TasmotaSlave_Serial->read(); // Read trailing byte - inbuf[TSlaveCommand.parameter] = '\0'; - - if (CMND_PUBLISH_TELE == TSlaveCommand.command) { // We need to publish stat/ with incoming stream as content - Response_P(PSTR("{\"TasmotaSlave\":")); - ResponseAppend_P("%s", inbuf); - ResponseJsonEnd(); - MqttPublishPrefixTopic_P(RESULT_OR_TELE, mqtt_data); - XdrvRulesProcess(); - } - if (CMND_EXECUTE_CMND == TSlaveCommand.command) { // We need to execute the incoming command - ExecuteCommand(inbuf, SRC_IGNORE); - } - break; - default: - break; - } -} - - -/*********************************************************************************************\ - * Interface -\*********************************************************************************************/ - -bool Xdrv31(uint8_t function) -{ - bool result = false; - - switch (function) { - case FUNC_EVERY_100_MSECOND: - if (TSlave.type) { - if (TasmotaSlave_Serial->available()) { - TasmotaSlave_ProcessIn(); - } - if (TSlaveSettings.features.func_every_100_msecond) { - TasmotaSlave_sendCmnd(CMND_FUNC_EVERY_100_MSECOND, 0); - } - } - break; - case FUNC_EVERY_SECOND: - if ((TSlave.type) && (TSlaveSettings.features.func_every_second)) { - TasmotaSlave_sendCmnd(CMND_FUNC_EVERY_SECOND, 0); - } - TasmotaSlave_Init(); - break; - case FUNC_JSON_APPEND: - if ((TSlave.type) && (TSlaveSettings.features.func_json_append)) { - TasmotaSlave_Show(); - } - break; - case FUNC_COMMAND: - result = DecodeCommand(kTasmotaSlaveCommands, TasmotaSlaveCommand); - break; - } - return result; -} - -#endif // USE_TASMOTA_SLAVE diff --git a/tasmota/xdrv_33_nrf24l01.ino b/tasmota/xdrv_33_nrf24l01.ino index b6eecce32..7b8f173f9 100644 --- a/tasmota/xdrv_33_nrf24l01.ino +++ b/tasmota/xdrv_33_nrf24l01.ino @@ -21,6 +21,7 @@ Version yyyymmdd Action Description -------------------------------------------------------------------------------------------- + 0.9.0.1 20200624 changes - removed unused legacy code --- 0.9.0.0 20191127 started - further development by Christian Baars forked - from arendst/tasmota - https://github.com/arendst/Tasmota @@ -38,18 +39,10 @@ #define XDRV_33 33 -#define MOSI 13 -#define MISO 12 -#define SCK 14 - -#include #include const char NRF24type[] PROGMEM = "NRF24"; -const char HTTP_NRF24[] PROGMEM = - "{s}%sL01%c: " "{m}started{e}"; - struct { uint8_t chipType = 0; // NRF24l01 active: 32 - NRF24L01 , 43- NRF24L01+ ... we mis-use ascii-codes } NRF24; @@ -60,7 +53,7 @@ RF24 NRF24radio; bool NRF24initRadio() { - NRF24radio.begin(pin[GPIO_SPI_CS],pin[GPIO_SPI_DC]); + NRF24radio.begin(Pin(GPIO_SPI_CS),Pin(GPIO_SPI_DC)); NRF24radio.powerUp(); if(NRF24radio.isChipConnected()){ @@ -73,8 +66,7 @@ bool NRF24initRadio() bool NRF24Detect(void) { - if ((pin[GPIO_SPI_CS]<99) && (pin[GPIO_SPI_DC]<99)){ - SPI.pins(SCK,MOSI,MISO,-1); + if (PinUsed(GPIO_SPI_CS) && PinUsed(GPIO_SPI_DC)) { if(NRF24initRadio()){ NRF24.chipType = 32; // SPACE AddLog_P2(LOG_LEVEL_INFO,PSTR("NRF24L01 initialized")); diff --git a/tasmota/xdrv_35_pwm_dimmer.ino b/tasmota/xdrv_35_pwm_dimmer.ino index 555ccbd4b..39ab399df 100644 --- a/tasmota/xdrv_35_pwm_dimmer.ino +++ b/tasmota/xdrv_35_pwm_dimmer.ino @@ -40,7 +40,7 @@ void (* const PWMDimmerCommand[])(void) PROGMEM = { #ifdef USE_PWM_DIMMER_REMOTE struct remote_pwm_dimmer { - power_t power; + bool power_on; uint8_t bri_power_on; uint8_t bri_preset_low; uint8_t bri_preset_high; @@ -94,7 +94,7 @@ void PWMModulePreInit(void) PWMDimmerSetPoweredOffLed(); // The relay initializes to on. If the power is supposed to be off, turn the relay off. - if (!power && pin[GPIO_REL1] < 99) digitalWrite(pin[GPIO_REL1], bitRead(rel_inverted, 0) ? 1 : 0); + if (!power && PinUsed(GPIO_REL1)) digitalWrite(Pin(GPIO_REL1), bitRead(rel_inverted, 0) ? 1 : 0); #ifdef USE_PWM_DIMMER_REMOTE // If remote device mode is enabled, set the device group count to the number of buttons @@ -104,7 +104,7 @@ void PWMModulePreInit(void) device_group_count = 0; for (uint32_t button_index = 0; button_index < MAX_KEYS; button_index++) { - if (pin[GPIO_KEY1 + button_index] < 99) device_group_count++; + if (PinUsed(GPIO_KEY1, button_index)) device_group_count++; } remote_pwm_dimmer_count = device_group_count - 1; @@ -156,16 +156,16 @@ void PWMDimmerSetBrightnessLeds(int32_t operation) void PWMDimmerSetPoweredOffLed(void) { // Set the powered-off LED state. - if (pin[GPIO_LEDLNK] < 99) { + if (PinUsed(GPIO_LEDLNK)) { bool power_off_led_on = !power && Settings.flag4.powered_off_led; if (ledlnk_inverted) power_off_led_on ^= 1; - digitalWrite(pin[GPIO_LEDLNK], power_off_led_on); + digitalWrite(Pin(GPIO_LEDLNK), power_off_led_on); } } void PWMDimmerSetPower(void) { - DigitalWrite(GPIO_REL1, bitRead(rel_inverted, 0) ? !power : power); + DigitalWrite(GPIO_REL1, 0, bitRead(rel_inverted, 0) ? !power : power); PWMDimmerSetBrightnessLeds(0); PWMDimmerSetPoweredOffLed(); } @@ -178,7 +178,7 @@ void PWMDimmerHandleDevGroupItem(void) uint8_t device_group_index = *(uint8_t *)XdrvMailbox.topic; if (device_group_index > remote_pwm_dimmer_count) return; bool device_is_local = device_groups[device_group_index].local; - struct remote_pwm_dimmer * remote_pwm_dimmer = &remote_pwm_dimmers[device_group_index]; + struct remote_pwm_dimmer * remote_pwm_dimmer = &remote_pwm_dimmers[device_group_index - 1]; #else // USE_PWM_DIMMER_REMOTE if (*(uint8_t *)XdrvMailbox.topic) return; #endif // !USE_PWM_DIMMER_REMOTE @@ -190,7 +190,7 @@ void PWMDimmerHandleDevGroupItem(void) break; case DGR_ITEM_POWER: if (!device_is_local) { - remote_pwm_dimmer->power = value; + remote_pwm_dimmer->power_on = value & 1; remote_pwm_dimmer->power_button_increases_bri = (remote_pwm_dimmer->bri < 128); } break; @@ -250,13 +250,13 @@ void PWMDimmerHandleButton(void) * Released Hold down On No Dimmer * Released Press & release up Off No Power on at bri preset low * Released Press & release down Off No Power on at bri preset high - * + * * Holding any button for over 10 seconds executes the WiFiConfig 2 command. - * + * * In remote mode, whichever button is pressed first becomes the power button and any buttons * pressed while it is held affect the device associated with it. The up and down buttons change * depeneding on which button is the current power button: - * + * * Power Down Up * ----- ---- -- * 1 2 3 @@ -276,17 +276,17 @@ void PWMDimmerHandleButton(void) } bool state_updated = false; - int8_t bri_offset = 0; + int32_t bri_offset = 0; uint8_t power_on_bri = 0; uint8_t dgr_item = 0; uint8_t dgr_value; uint8_t dgr_more_to_come = false; uint32_t button_index = XdrvMailbox.index; uint32_t now = millis(); - + // Initialize some variables. #ifdef USE_PWM_DIMMER_REMOTE - bool power_is_on = (!active_device_is_local ? active_remote_pwm_dimmer->power : power); + bool power_is_on = (!active_device_is_local ? active_remote_pwm_dimmer->power_on : power); bool is_power_button = (button_index == power_button_index); #else // USE_PWM_DIMMER_REMOTE bool power_is_on = power; @@ -344,8 +344,9 @@ void PWMDimmerHandleButton(void) // If this is about the power button, ... if (is_power_button) { - // If no other buttons are pressed, ... - if (buttons_pressed == 1) { + // If no other buttons are pressed and the up or down button was not tapped while holding + // the power button before this, ... + if (buttons_pressed == 1 && !tap_count) { // If the power is on, adjust the brightness. Set the direction based on the current // direction for the device and then invert the direction when the power button is @@ -400,18 +401,10 @@ void PWMDimmerHandleButton(void) else #endif // USE_PWM_DIMMER_REMOTE uint8_value = Light.fixed_color_index; - if (is_down_button) { - if (uint8_value) - uint8_value--; - else - uint8_value = MAX_FIXED_COLOR; - } - else { - if (uint8_value < MAX_FIXED_COLOR) - uint8_value++; - else - uint8_value = 0; - } + if (is_down_button) + uint8_value--; + else + uint8_value++; #ifdef USE_PWM_DIMMER_REMOTE if (!active_device_is_local) active_remote_pwm_dimmer->fixed_color_index = uint8_value; @@ -489,7 +482,7 @@ void PWMDimmerHandleButton(void) // If the up or down button was tapped while the power button was held, ... else if (tap_count) { - + // If the button was tapped but not held, handle the operation based on which button was // tapped. if (!button_was_held) { @@ -553,12 +546,13 @@ void PWMDimmerHandleButton(void) // If the power is on, ... if (power_is_on) { - + // If the button was not held, adjust the brightness. Set the direction based on which // button is pressed. The new brightness will be calculated below. if (button_hold_time[button_index] >= now) { - bri_offset = (is_down_button ? -10 : 10); + bri_offset = (is_down_button ? -1 : 1); dgr_item = 255; + state_updated = true; } // If the button was held and the hold was not processed by a rule, we changed the @@ -598,9 +592,8 @@ void PWMDimmerHandleButton(void) else #endif // USE_PWM_DIMMER_REMOTE bri = light_state.getBri(); - int32_t new_bri; - bri_offset *= (Settings.light_correction ? 4 : bri / 16 + 1); - new_bri = bri + bri_offset; + int32_t new_bri = bri + bri_offset * ((dgr_item ? 16 : Settings.light_correction ? 4 : bri / 16 + 1)); + if (bri_offset > 0) { if (new_bri > 255) new_bri = 255; } @@ -609,7 +602,7 @@ void PWMDimmerHandleButton(void) } if (new_bri != bri) { #ifdef USE_DEVICE_GROUPS - SendDeviceGroupMessage(power_button_index, (dgr_item ? DGR_MSGTYP_UPDATE : DGR_MSGTYP_UPDATE_MORE_TO_COME), DGR_ITEM_LIGHT_BRI, new_bri); + SendDeviceGroupMessage(power_button_index, DGR_MSGTYP_UPDATE_MORE_TO_COME, DGR_ITEM_LIGHT_BRI, new_bri); #endif // USE_DEVICE_GROUPS #ifdef USE_PWM_DIMMER_REMOTE if (!active_device_is_local) @@ -617,9 +610,15 @@ void PWMDimmerHandleButton(void) else { #endif // USE_PWM_DIMMER_REMOTE skip_light_fade = true; +#ifdef USE_DEVICE_GROUPS + ignore_dgr_sends = true; +#endif // USE_DEVICE_GROUPS light_state.setBri(new_bri); LightAnimate(); skip_light_fade = false; +#ifdef USE_DEVICE_GROUPS + ignore_dgr_sends = false; +#endif // USE_DEVICE_GROUPS Settings.bri_power_on = new_bri; #ifdef USE_PWM_DIMMER_REMOTE } @@ -636,8 +635,8 @@ void PWMDimmerHandleButton(void) #ifdef USE_DEVICE_GROUPS #ifdef USE_PWM_DIMMER_REMOTE if (!active_device_is_local) { - active_remote_pwm_dimmer->power ^= 1; - new_power = active_remote_pwm_dimmer->power; + active_remote_pwm_dimmer->power_on ^= 1; + new_power = active_remote_pwm_dimmer->power_on; } else { #endif // USE_PWM_DIMMER_REMOTE @@ -665,7 +664,7 @@ void PWMDimmerHandleButton(void) // If we're not changing the brightness or toggling the power and we made changes, send a group // update. - else if (dgr_item) { + if (dgr_item) { #ifdef USE_DEVICE_GROUPS if (dgr_item == 255) dgr_item = 0; SendDeviceGroupMessage(power_button_index, (dgr_more_to_come ? DGR_MSGTYP_UPDATE_MORE_TO_COME : DGR_MSGTYP_UPDATE_DIRECT), dgr_item, dgr_value); diff --git a/tasmota/xdrv_36_keeloq.ino b/tasmota/xdrv_36_keeloq.ino index d975a5a79..c271cf3f7 100644 --- a/tasmota/xdrv_36_keeloq.ino +++ b/tasmota/xdrv_36_keeloq.ino @@ -242,8 +242,8 @@ void CreateKeeloqPacket() void KeeloqInit() { - jaroliftDevice.port_tx = pin[GPIO_CC1101_GDO2]; // Output port for transmission - jaroliftDevice.port_rx = pin[GPIO_CC1101_GDO0]; // Input port for reception + jaroliftDevice.port_tx = Pin(GPIO_CC1101_GDO2); // Output port for transmission + jaroliftDevice.port_rx = Pin(GPIO_CC1101_GDO0); // Input port for reception DEBUG_DRIVER_LOG(LOG_LEVEL_DEBUG_MORE, PSTR("cc1101.init()")); delay(100); @@ -266,7 +266,7 @@ void KeeloqInit() \*********************************************************************************************/ bool Xdrv36(uint8_t function) { - if ((99 == pin[GPIO_CC1101_GDO0]) || (99 == pin[GPIO_CC1101_GDO2])) { return false; } + if (!PinUsed(GPIO_CC1101_GDO0) || !PinUsed(GPIO_CC1101_GDO2)) { return false; } bool result = false; @@ -284,4 +284,4 @@ bool Xdrv36(uint8_t function) return result; } -#endif // USE_KEELOQ +#endif // USE_KEELOQ diff --git a/tasmota/xdrv_37_sonoff_d1.ino b/tasmota/xdrv_37_sonoff_d1.ino index 9ebc4b4f3..cd1bdd4b2 100644 --- a/tasmota/xdrv_37_sonoff_d1.ino +++ b/tasmota/xdrv_37_sonoff_d1.ino @@ -17,6 +17,7 @@ along with this program. If not, see . */ +#ifdef USE_LIGHT #ifdef USE_SONOFF_D1 /*********************************************************************************************\ * Sonoff D1 dimmer 433 @@ -196,3 +197,4 @@ bool Xdrv37(uint8_t function) } #endif // USE_SONOFF_D1 +#endif // USE_LIGHT diff --git a/tasmota/xdrv_38_ping.ino b/tasmota/xdrv_38_ping.ino new file mode 100644 index 000000000..d30c0093d --- /dev/null +++ b/tasmota/xdrv_38_ping.ino @@ -0,0 +1,344 @@ +/* + xdrv_38_ping.ino - support for ICMP Ping + + Copyright (C) 2020 Theo Arends and Stephan Hadinger + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifdef USE_PING + +#define XDRV_38 38 + +#include "lwip/icmp.h" +#include "lwip/inet_chksum.h" +#include "lwip/raw.h" +#include "lwip/timeouts.h" + +const char kPingCommands[] PROGMEM = "|" // no prefix + D_CMND_PING + ; + +void (* const PingCommand[])(void) PROGMEM = { + &CmndPing, + }; + +extern "C" { + + extern uint32 system_relative_time(uint32 time); + extern void ets_bzero(void *s, size_t n); + + const uint16_t Ping_ID = 0xAFAF; // PING packet ID + const size_t Ping_data_size = 32; // default packet size + const uint32_t Ping_timeout_ms = 1000; // default time-out of 1 second, which is enough for LAN/WIFI + const uint32_t Ping_coarse = 1000; // interval between sending packets, 1 packet every second + + typedef struct Ping_t { + uint32 ip; // target IPv4 address + Ping_t *next; // next object in linked list + uint16_t seq_num; // next sequence number + uint16_t seqno; // reject a packet already received + uint8_t success_count; // sucessful responses received + uint8_t timeout_count; // time-outs (no responses) + uint8_t to_send_count; // number of packets remaining to send + uint32_t ping_time_sent; // timestamp when the packet was sent + uint32_t min_time; // minimum time in ms for a successful response + uint32_t max_time; // maximum time in ms for a successful response + uint32_t sum_time; // cumulated time in ms for all successful responses (used to compute the average) + bool done; // indicates the ping campaign is finished + bool fast; // fast mode, i.e. stop pings when first successful response + } Ping_t; + + // globals + Ping_t *ping_head = nullptr; // head of the Linked List for ping objects + struct raw_pcb *t_ping_pcb = nullptr; // registered with first ping, deregistered after last ping, the same pcb is used for all packets + + // ================================================================================ + // Find the Ping object indexed by IP address + // ================================================================================ + // + // find the ping structure corresponding to the specified IP, or nullptr if not found + // + Ping_t ICACHE_FLASH_ATTR * t_ping_find(uint32_t ip) { + Ping_t *ping = ping_head; + while (ping != nullptr) { + if (ping->ip == ip) { + return ping; + } + ping = ping->next; + } + return nullptr; + } + + // ================================================================================ + // Timer called a packet response is in time-out + // ================================================================================ + // + // called after the ICMP timeout occured + // we never received the packet, increase the timeout count + // + void ICACHE_FLASH_ATTR t_ping_timeout(void* arg) { + Ping_t *ping = (Ping_t*) arg; + ping->timeout_count++; + } + + // ================================================================================ + // Send ICMP packet + // ================================================================================ + // Prepare a echo ICMP request + // + void ICACHE_FLASH_ATTR t_ping_prepare_echo(struct icmp_echo_hdr *iecho, uint16_t len, Ping_t *ping) { + size_t data_len = len - sizeof(struct icmp_echo_hdr); + + ICMPH_TYPE_SET(iecho, ICMP_ECHO); + ICMPH_CODE_SET(iecho, 0); + iecho->chksum = 0; + iecho->id = Ping_ID; + ping->seq_num++; + if (ping->seq_num == 0x7fff) { ping->seq_num = 0; } + + iecho->seqno = htons(ping->seq_num); // TODO + + /* fill the additional data buffer with some data */ + for (uint32_t i = 0; i < data_len; i++) { + ((char*)iecho)[sizeof(struct icmp_echo_hdr) + i] = (char)i; + } + + iecho->chksum = inet_chksum(iecho, len); + } + // + // send the ICMP packet + // + void ICACHE_FLASH_ATTR t_ping_send(struct raw_pcb *raw, Ping_t *ping) { + struct pbuf *p; + uint16_t ping_size = sizeof(struct icmp_echo_hdr) + Ping_data_size; + + ping->ping_time_sent = system_get_time(); + p = pbuf_alloc(PBUF_IP, ping_size, PBUF_RAM); + if (!p) { return; } + if ((p->len == p->tot_len) && (p->next == nullptr)) { + ip_addr_t ping_target; + struct icmp_echo_hdr *iecho; + + ping_target.addr = ping->ip; + iecho = (struct icmp_echo_hdr *) p->payload; + + t_ping_prepare_echo(iecho, ping_size, ping); + raw_sendto(raw, p, &ping_target); + } + pbuf_free(p); + } + + // ================================================================================ + // Timer called when it's time to send next packet, of when finished + // ================================================================================ + // this timer is called every x seconds to send a new packet, whatever happened to the previous packet + static void ICACHE_FLASH_ATTR t_ping_coarse_tmr(void *arg) { + Ping_t *ping = (Ping_t*) arg; + if (ping->to_send_count > 0) { + ping->to_send_count--; + // have we sent all packets? + t_ping_send(t_ping_pcb, ping); + + sys_timeout(Ping_timeout_ms, t_ping_timeout, ping); + sys_timeout(Ping_coarse, t_ping_coarse_tmr, ping); + } else { + sys_untimeout(t_ping_coarse_tmr, ping); + ping->done = true; + } + } + + // ================================================================================ + // Callback: a packet response was received + // ================================================================================ + // + // Reveived packet + // + static uint8_t ICACHE_FLASH_ATTR t_ping_recv(void *arg, struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *addr) { + Ping_t *ping = t_ping_find(addr->addr); + + if (nullptr == ping) { // unknown source address + return 0; // don't eat the packet and ignore it + } + + if (pbuf_header( p, -PBUF_IP_HLEN)==0) { + struct icmp_echo_hdr *iecho; + iecho = (struct icmp_echo_hdr *)p->payload; + + if ((iecho->id == Ping_ID) && (iecho->seqno == htons(ping->seq_num)) && iecho->type == ICMP_ER) { + + if (iecho->seqno != ping->seqno){ // debounce already received packet + /* do some ping result processing */ + sys_untimeout(t_ping_timeout, ping); // remove time-out handler + uint32_t delay = system_relative_time(ping->ping_time_sent); + delay /= 1000; + + ping->sum_time += delay; + if (delay < ping->min_time) { ping->min_time = delay; } + if (delay > ping->max_time) { ping->max_time = delay; } + + ping->success_count++; + ping->seqno = iecho->seqno; + if (ping->fast) { // if fast mode, abort further pings when first successful response is received + sys_untimeout(t_ping_coarse_tmr, ping); + ping->done = true; + ping->to_send_count = 0; + } + } + + pbuf_free(p); + return 1; /* eat the packet */ + } + } + + return 0; /* don't eat the packet */ + } + + // ================================================================================ + // Internal structure PCB management + // ================================================================================ + // we are going to send a packet, make sure pcb is initialized + void t_ping_register_pcb(void) { + if (nullptr == t_ping_pcb) { + t_ping_pcb = raw_new(IP_PROTO_ICMP); + + raw_recv(t_ping_pcb, t_ping_recv, nullptr); // we cannot register data structure here as we can only register one + raw_bind(t_ping_pcb, IP_ADDR_ANY); + } + } + + // we have finsihed a ping series, deallocated if no more ongoing + void t_ping_deregister_pcb(void) { + if (nullptr == ping_head) { // deregister only if no ping is flying + raw_remove(t_ping_pcb); + t_ping_pcb = nullptr; + } + } + + // ================================================================================ + // Start pings + // ================================================================================ + bool t_ping_start(uint32_t ip, uint32_t count) { + // check if pings are already ongoing for this IP + if (t_ping_find(ip)) { + return false; + } + + Ping_t *ping = new Ping_t(); + if (0 == count) { + count = 4; + ping->fast = true; + } + ping->min_time = UINT32_MAX; + ping->ip = ip; + ping->to_send_count = count - 1; + + // add to Linked List from head + ping->next = ping_head; + ping_head = ping; // insert at head + + t_ping_register_pcb(); + t_ping_send(t_ping_pcb, ping); + + // set timers for time-out and cadence + sys_timeout(Ping_timeout_ms, t_ping_timeout, ping); + sys_timeout(Ping_coarse, t_ping_coarse_tmr, ping); + } + +} + +// Check if any ping requests is completed, and publish the results +void PingResponsePoll(void) { + Ping_t *ping = ping_head; + Ping_t **prev_link = &ping_head; // previous link pointer (used to remove en entry) + + while (ping != nullptr) { + if (ping->done) { + uint32_t success = ping->success_count; + uint32_t ip = ping->ip; + + Response_P(PSTR("{\"" D_JSON_PING "\":{\"%d.%d.%d.%d\":{" + "\"Reachable\":%s" + ",\"Success\":%d" + ",\"Timeout\":%d" + ",\"MinTime\":%d" + ",\"MaxTime\":%d" + ",\"AvgTime\":%d" + "}}}"), + ip & 0xFF, (ip >> 8) & 0xFF, (ip >> 16) & 0xFF, ip >> 24, + success ? "true" : "false", + success, ping->timeout_count, + success ? ping->min_time : 0, ping->max_time, + success ? ping->sum_time / success : 0 + ); + MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_PING)); + XdrvRulesProcess(); + + // remove from linked list + *prev_link = ping->next; + // don't increment prev_link + Ping_t *ping_to_delete = ping; + ping = ping->next; // move to next before deleting the object + delete ping_to_delete; // free memory allocated + } else { + prev_link = &ping->next; + ping = ping->next; + } + } +} + +/*********************************************************************************************\ + * Ping Command +\*********************************************************************************************/ + +void CmndPing(void) { + uint32_t count = XdrvMailbox.index; + IPAddress ip; + + RemoveSpace(XdrvMailbox.data); + if (count > 10) { count = 8; } // max 8 seconds + + if (WiFi.hostByName(XdrvMailbox.data, ip)) { + bool ok = t_ping_start(ip, count); + if (ok) { + ResponseCmndDone(); + } else { + ResponseCmndChar_P(PSTR("Ping already ongoing for this IP")); + } + } else { + ResponseCmndChar_P(PSTR("Unable to resolve IP address")); + } +} + + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xdrv38(uint8_t function) +{ + bool result = false; + + switch (function) { + case FUNC_EVERY_250_MSECOND: + PingResponsePoll(); // TODO + break; + case FUNC_COMMAND: + result = DecodeCommand(kPingCommands, PingCommand); + break; + } + return result; +} + +#endif // USE_PING \ No newline at end of file diff --git a/tasmota/xdrv_39_thermostat.ino b/tasmota/xdrv_39_thermostat.ino new file mode 100644 index 000000000..768088117 --- /dev/null +++ b/tasmota/xdrv_39_thermostat.ino @@ -0,0 +1,2028 @@ +/* + xdrv_39_thermostat.ino - Thermostat controller for Tasmota + + Copyright (C) 2020 Javier Arigita + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifdef USE_THERMOSTAT + +#define XDRV_39 39 + +// Enable/disable debugging +//#define DEBUG_THERMOSTAT + +// Enable/disable experimental PI auto-tuning inspired by the Arduino +// Autotune Library by Brett Beauregard +//#define USE_PI_AUTOTUNING // (Ziegler-Nichols closed loop method) + +#ifdef DEBUG_THERMOSTAT +#define DOMOTICZ_MAX_IDX 4 +#define DOMOTICZ_IDX1 791 +#define DOMOTICZ_IDX2 792 +#define DOMOTICZ_IDX3 799 +#define DOMOTICZ_IDX4 800 +#define DOMOTICZ_IDX5 801 +#endif // DEBUG_THERMOSTAT + +// Commands +#define D_CMND_THERMOSTATMODESET "ThermostatModeSet" +#define D_CMND_CLIMATEMODESET "ClimateModeSet" +#define D_CMND_TEMPFROSTPROTECTSET "TempFrostProtectSet" +#define D_CMND_CONTROLLERMODESET "ControllerModeSet" +#define D_CMND_INPUTSWITCHSET "InputSwitchSet" +#define D_CMND_INPUTSWITCHUSE "InputSwitchUse" +#define D_CMND_OUTPUTRELAYSET "OutputRelaySet" +#define D_CMND_TIMEALLOWRAMPUPSET "TimeAllowRampupSet" +#define D_CMND_TEMPFORMATSET "TempFormatSet" +#define D_CMND_TEMPMEASUREDSET "TempMeasuredSet" +#define D_CMND_TEMPTARGETSET "TempTargetSet" +#define D_CMND_TEMPMEASUREDGRDREAD "TempMeasuredGrdRead" +#define D_CMND_TEMPSENSNUMBERSET "TempSensNumberSet" +#define D_CMND_SENSORINPUTSET "SensorInputSet" +#define D_CMND_STATEEMERGENCYSET "StateEmergencySet" +#define D_CMND_TIMEMANUALTOAUTOSET "TimeManualToAutoSet" +#define D_CMND_TIMEONLIMITSET "TimeOnLimitSet" +#define D_CMND_PROPBANDSET "PropBandSet" +#define D_CMND_TIMERESETSET "TimeResetSet" +#define D_CMND_TIMEPICYCLESET "TimePiCycleSet" +#define D_CMND_TEMPANTIWINDUPRESETSET "TempAntiWindupResetSet" +#define D_CMND_TEMPHYSTSET "TempHystSet" +#ifdef USE_PI_AUTOTUNING +#define D_CMND_PERFLEVELAUTOTUNE "PerfLevelAutotune" +#endif // USE_PI_AUTOTUNING +#define D_CMND_TIMEMAXACTIONSET "TimeMaxActionSet" +#define D_CMND_TIMEMINACTIONSET "TimeMinActionSet" +#define D_CMND_TIMEMINTURNOFFACTIONSET "TimeMinTurnoffActionSet" +#define D_CMND_TEMPRUPDELTINSET "TempRupDeltInSet" +#define D_CMND_TEMPRUPDELTOUTSET "TempRupDeltOutSet" +#define D_CMND_TIMERAMPUPMAXSET "TimeRampupMaxSet" +#define D_CMND_TIMERAMPUPCYCLESET "TimeRampupCycleSet" +#define D_CMND_TEMPRAMPUPPIACCERRSET "TempRampupPiAccErrSet" +#define D_CMND_TIMEPIPROPORTREAD "TimePiProportRead" +#define D_CMND_TIMEPIINTEGRREAD "TimePiIntegrRead" +#define D_CMND_TIMESENSLOSTSET "TimeSensLostSet" +#define D_CMND_DIAGNOSTICMODESET "DiagnosticModeSet" +#define D_CMND_CTRDUTYCYCLEREAD "CtrDutyCycleRead" +#define D_CMND_ENABLEOUTPUTSET "EnableOutputSet" + +enum ThermostatModes { THERMOSTAT_OFF, THERMOSTAT_AUTOMATIC_OP, THERMOSTAT_MANUAL_OP, THERMOSTAT_MODES_MAX }; +#ifdef USE_PI_AUTOTUNING +enum ControllerModes { CTR_HYBRID, CTR_PI, CTR_RAMP_UP, CTR_PI_AUTOTUNE, CTR_MODES_MAX }; +enum ControllerHybridPhases { CTR_HYBRID_RAMP_UP, CTR_HYBRID_PI, CTR_HYBRID_PI_AUTOTUNE }; +enum AutotuneStates { AUTOTUNE_OFF, AUTOTUNE_ON, AUTOTUNE_MAX }; +enum AutotunePerformanceParam { AUTOTUNE_PERF_FAST, AUTOTUNE_PERF_NORMAL, AUTOTUNE_PERF_SLOW, AUTOTUNE_PERF_MAX }; +#else +enum ControllerModes { CTR_HYBRID, CTR_PI, CTR_RAMP_UP, CTR_MODES_MAX }; +enum ControllerHybridPhases { CTR_HYBRID_RAMP_UP, CTR_HYBRID_PI }; +#endif // USE_PI_AUTOTUNING +enum ClimateModes { CLIMATE_HEATING, CLIMATE_COOLING, CLIMATE_MODES_MAX }; +enum InterfaceStates { IFACE_OFF, IFACE_ON }; +enum InputUsage { INPUT_NOT_USED, INPUT_USED }; +enum CtrCycleStates { CYCLE_OFF, CYCLE_ON }; +enum EmergencyStates { EMERGENCY_OFF, EMERGENCY_ON }; +enum SensorType { SENSOR_MQTT, SENSOR_LOCAL, SENSOR_MAX }; +enum TempFormat { TEMP_CELSIUS, TEMP_FAHRENHEIT }; +enum TempConvType { TEMP_CONV_ABSOLUTE, TEMP_CONV_RELATIVE }; +enum DiagnosticModes { DIAGNOSTIC_OFF, DIAGNOSTIC_ON }; +enum ThermostatSupportedInputSwitches { + THERMOSTAT_INPUT_NONE, + THERMOSTAT_INPUT_SWT1 = 1, // Buttons + THERMOSTAT_INPUT_SWT2, + THERMOSTAT_INPUT_SWT3, + THERMOSTAT_INPUT_SWT4, + THERMOSTAT_INPUT_SWT5, + THERMOSTAT_INPUT_SWT6, + THERMOSTAT_INPUT_SWT7, + THERMOSTAT_INPUT_SWT8 +}; +enum ThermostatSupportedOutputRelays { + THERMOSTAT_OUTPUT_NONE, + THERMOSTAT_OUTPUT_REL1 = 1, // Relays + THERMOSTAT_OUTPUT_REL2, + THERMOSTAT_OUTPUT_REL3, + THERMOSTAT_OUTPUT_REL4, + THERMOSTAT_OUTPUT_REL5, + THERMOSTAT_OUTPUT_REL6, + THERMOSTAT_OUTPUT_REL7, + THERMOSTAT_OUTPUT_REL8 +}; + +typedef union { + uint32_t data; + struct { + uint32_t thermostat_mode : 2; // Operation mode of the thermostat system + uint32_t controller_mode : 2; // Operation mode of the thermostat controller + uint32_t climate_mode : 1; // Climate mode of the thermostat (0 = heating / 1 = cooling) + uint32_t sensor_alive : 1; // Flag stating if temperature sensor is alive (0 = inactive, 1 = active) + uint32_t sensor_type : 1; // Sensor type: MQTT/local + uint32_t temp_format : 1; // Temperature format (0 = Celsius, 1 = Fahrenheit) + uint32_t command_output : 1; // Flag stating the desired command to the output (0 = inactive, 1 = active) + uint32_t status_output : 1; // Flag stating state of the output (0 = inactive, 1 = active) + uint32_t status_input : 1; // Flag stating state of the input (0 = inactive, 1 = active) + uint32_t use_input : 1; // Flag stating if the input switch shall be used to switch to manual mode + uint32_t phase_hybrid_ctr : 2; // Phase of the hybrid controller (Ramp-up, PI or Autotune) + uint32_t status_cycle_active : 1; // Status showing if cycle is active (Output ON) or not (Output OFF) + uint32_t counter_seconds : 6; // Second counter used to track minutes + uint32_t output_relay_number : 4; // Output relay number + uint32_t input_switch_number : 3; // Input switch number + uint32_t enable_output : 1; // Enables / disables the physical output +#ifdef USE_PI_AUTOTUNING + uint32_t autotune_flag : 1; // Enable/disable autotune + uint32_t autotune_perf_mode : 2; // Autotune performance mode +#else + uint32_t free : 3; // Free bits +#endif // USE_PI_AUTOTUNING + }; +} ThermostatStateBitfield; + +typedef union { + uint8_t data; + struct { + uint8_t state_emergency : 1; // State for thermostat emergency + uint8_t diagnostic_mode : 1; // Diagnostic mode selected + uint8_t output_inconsist_ctr : 2; // Counter of the minutes where the output state is inconsistent with the command + }; +} ThermostatDiagBitfield; + +#ifdef DEBUG_THERMOSTAT +const char DOMOTICZ_MES[] PROGMEM = "{\"idx\":%d,\"nvalue\":%d,\"svalue\":\"%s\"}"; +uint16_t Domoticz_Virtual_Switches[DOMOTICZ_MAX_IDX] = { DOMOTICZ_IDX1, DOMOTICZ_IDX3, DOMOTICZ_IDX4, DOMOTICZ_IDX5 }; +#endif // DEBUG_THERMOSTAT + +const char kThermostatCommands[] PROGMEM = "|" D_CMND_THERMOSTATMODESET "|" D_CMND_CLIMATEMODESET "|" + D_CMND_TEMPFROSTPROTECTSET "|" D_CMND_CONTROLLERMODESET "|" D_CMND_INPUTSWITCHSET "|" D_CMND_INPUTSWITCHUSE "|" + D_CMND_OUTPUTRELAYSET "|" D_CMND_TIMEALLOWRAMPUPSET "|" D_CMND_TEMPFORMATSET "|" D_CMND_TEMPMEASUREDSET "|" + D_CMND_TEMPTARGETSET "|" D_CMND_TEMPMEASUREDGRDREAD "|" D_CMND_SENSORINPUTSET "|" D_CMND_STATEEMERGENCYSET "|" + D_CMND_TIMEMANUALTOAUTOSET "|" D_CMND_PROPBANDSET "|" D_CMND_TIMERESETSET "|" D_CMND_TIMEPICYCLESET "|" +#ifdef USE_PI_AUTOTUNING + D_CMND_TEMPANTIWINDUPRESETSET "|" D_CMND_TEMPHYSTSET "|" D_CMND_PERFLEVELAUTOTUNE "|" D_CMND_TIMEMAXACTIONSET "|" +#else + D_CMND_TEMPANTIWINDUPRESETSET "|" D_CMND_TEMPHYSTSET "|" D_CMND_TIMEMAXACTIONSET "|" +#endif // USE_PI_AUTOTUNING + D_CMND_TIMEMINACTIONSET "|" D_CMND_TIMEMINTURNOFFACTIONSET "|" D_CMND_TEMPRUPDELTINSET "|" D_CMND_TEMPRUPDELTOUTSET "|" + D_CMND_TIMERAMPUPMAXSET "|" D_CMND_TIMERAMPUPCYCLESET "|" D_CMND_TEMPRAMPUPPIACCERRSET "|" D_CMND_TIMEPIPROPORTREAD "|" + D_CMND_TIMEPIINTEGRREAD "|" D_CMND_TIMESENSLOSTSET "|" D_CMND_DIAGNOSTICMODESET "|" D_CMND_CTRDUTYCYCLEREAD "|" + D_CMND_ENABLEOUTPUTSET; + +void (* const ThermostatCommand[])(void) PROGMEM = { + &CmndThermostatModeSet, &CmndClimateModeSet, &CmndTempFrostProtectSet, &CmndControllerModeSet, &CmndInputSwitchSet, + &CmndInputSwitchUse, &CmndOutputRelaySet, &CmndTimeAllowRampupSet, &CmndTempFormatSet, &CmndTempMeasuredSet, + &CmndTempTargetSet, &CmndTempMeasuredGrdRead, &CmndSensorInputSet, &CmndStateEmergencySet, &CmndTimeManualToAutoSet, + &CmndPropBandSet, &CmndTimeResetSet, &CmndTimePiCycleSet, &CmndTempAntiWindupResetSet, &CmndTempHystSet, +#ifdef USE_PI_AUTOTUNING + &CmndPerfLevelAutotune, &CmndTimeMaxActionSet, &CmndTimeMinActionSet, &CmndTimeMinTurnoffActionSet, &CmndTempRupDeltInSet, +#else + &CmndTimeMaxActionSet, &CmndTimeMinActionSet, &CmndTimeMinTurnoffActionSet, &CmndTempRupDeltInSet, +#endif // USE_PI_AUTOTUNING + &CmndTempRupDeltOutSet, &CmndTimeRampupMaxSet, &CmndTimeRampupCycleSet, &CmndTempRampupPiAccErrSet, + &CmndTimePiProportRead, &CmndTimePiIntegrRead, &CmndTimeSensLostSet, &CmndDiagnosticModeSet, &CmndCtrDutyCycleRead, + &CmndEnableOutputSet }; + +struct THERMOSTAT { + ThermostatStateBitfield status; // Bittfield including states as well as several flags + uint32_t timestamp_temp_measured_update = 0; // Timestamp of latest measurement update + uint32_t timestamp_temp_meas_change_update = 0; // Timestamp of latest measurement value change (> or < to previous) + uint32_t timestamp_output_off = 0; // Timestamp of latest thermostat output Off state + uint32_t timestamp_input_on = 0; // Timestamp of latest input On state + uint32_t time_thermostat_total = 0; // Time thermostat on within a specific timeframe + uint32_t time_ctr_checkpoint = 0; // Time to finalize the control cycle within the PI strategy or to switch to PI from Rampup in seconds + uint32_t time_ctr_changepoint = 0; // Time until switching off output within the controller in seconds + int32_t temp_measured_gradient = 0; // Temperature measured gradient from sensor in thousandths of degrees per hour + int16_t temp_target_level = THERMOSTAT_TEMP_INIT; // Target level of the thermostat in tenths of degrees + int16_t temp_target_level_ctr = THERMOSTAT_TEMP_INIT; // Target level set for the controller + int16_t temp_pi_accum_error = 0; // Temperature accumulated error for the PI controller in hundredths of degrees + int16_t temp_pi_error = 0; // Temperature error for the PI controller in hundredths of degrees + int32_t time_proportional_pi; // Time proportional part of the PI controller + int32_t time_integral_pi; // Time integral part of the PI controller + int32_t time_total_pi; // Time total (proportional + integral) of the PI controller + uint16_t kP_pi = 0; // kP value for the PI controller multiplied by 100 (to avoid floating point operations) + uint16_t kI_pi = 0; // kI value for the PI controller multiplied by 100 (to avoid floating point operations) + int32_t temp_rampup_meas_gradient = 0; // Temperature measured gradient from sensor in thousandths of degrees celsius per hour calculated during ramp-up + uint32_t timestamp_rampup_start = 0; // Timestamp where the ramp-up controller mode has been started + uint32_t time_rampup_deadtime = 0; // Time constant of the thermostat system (step response time) + uint32_t time_rampup_nextcycle = 0; // Time where the ramp-up controller shall start the next cycle + int16_t temp_measured = 0; // Temperature measurement received from sensor in tenths of degrees celsius + int16_t temp_rampup_output_off = 0; // Temperature to swith off relay output within the ramp-up controller in tenths of degrees celsius + uint8_t time_output_delay = THERMOSTAT_TIME_OUTPUT_DELAY; // Output delay between state change and real actuation event (f.i. valve open/closed) + uint8_t counter_rampup_cycles = 0; // Counter of ramp-up cycles + uint8_t temp_rampup_pi_acc_error = THERMOSTAT_TEMP_PI_RAMPUP_ACC_E; // Accumulated error when switching from ramp-up controller to PI in hundreths of degrees celsius + uint8_t temp_rampup_delta_out = THERMOSTAT_TEMP_RAMPUP_DELTA_OUT; // Minimum delta temperature to target to get out of the rampup mode, in tenths of degrees celsius + uint8_t temp_rampup_delta_in = THERMOSTAT_TEMP_RAMPUP_DELTA_IN; // Minimum delta temperature to target to get into rampup mode, in tenths of degrees celsius + uint8_t val_prop_band = THERMOSTAT_PROP_BAND; // Proportional band of the PI controller in degrees celsius + int16_t temp_rampup_start = 0; // Temperature at start of ramp-up controller in tenths of degrees celsius + int16_t temp_rampup_cycle = 0; // Temperature set at the beginning of each ramp-up cycle in tenths of degrees + uint16_t time_rampup_max = THERMOSTAT_TIME_RAMPUP_MAX; // Time maximum ramp-up controller duration in minutes + uint16_t time_rampup_cycle = THERMOSTAT_TIME_RAMPUP_CYCLE; // Time ramp-up cycle in minutes + uint16_t time_allow_rampup = THERMOSTAT_TIME_ALLOW_RAMPUP; // Time in minutes after last target update to allow ramp-up controller phase + uint16_t time_sens_lost = THERMOSTAT_TIME_SENS_LOST; // Maximum time w/o sensor update to set it as lost in minutes + uint16_t time_manual_to_auto = THERMOSTAT_TIME_MANUAL_TO_AUTO; // Time without input switch active to change from manual to automatic in minutes + uint32_t time_reset = THERMOSTAT_TIME_RESET; // Reset time of the PI controller in seconds + uint16_t time_pi_cycle = THERMOSTAT_TIME_PI_CYCLE; // Cycle time for the thermostat controller in minutes + uint16_t time_max_action = THERMOSTAT_TIME_MAX_ACTION; // Maximum thermostat time per cycle in minutes + uint16_t time_min_action = THERMOSTAT_TIME_MIN_ACTION; // Minimum thermostat time per cycle in minutes + uint16_t time_min_turnoff_action = THERMOSTAT_TIME_MIN_TURNOFF_ACTION; // Minimum turnoff time in minutes, below it the thermostat will stay on + uint8_t temp_reset_anti_windup = THERMOSTAT_TEMP_RESET_ANTI_WINDUP; // Range where reset antiwindup is disabled, in tenths of degrees celsius + int8_t temp_hysteresis = THERMOSTAT_TEMP_HYSTERESIS; // Range hysteresis for temperature PI controller, in tenths of degrees celsius + uint8_t temp_frost_protect = THERMOSTAT_TEMP_FROST_PROTECT; // Minimum temperature for frost protection, in tenths of degrees celsius + ThermostatDiagBitfield diag; // Bittfield including diagnostic flags +#ifdef USE_PI_AUTOTUNING + uint8_t dutycycle_step_autotune = THERMOSTAT_DUTYCYCLE_AUTOTUNE; // Duty cycle for the step response of the autotune PI function in % + uint8_t peak_ctr = 0; // Peak counter for the autotuning function + uint8_t temp_band_no_peak_det = THERMOSTAT_TEMP_BAND_NO_PEAK_DET; // Temperature band in thenths of degrees celsius within no peak will be detected + uint8_t val_prop_band_atune = 0; // Proportional band calculated from the the PI autotune function in degrees celsius + uint32_t time_reset_atune = 0; // Reset time calculated from the PI autotune function in seconds + uint16_t pU_pi_atune = 0; // pU value ("Ultimate" period) period of self-sustaining oscillations determined when the controller gain was set to Ku in minutes (for PI autotune) + uint16_t kU_pi_atune = 0; // kU value ("Ultimate" gain) determined by increasing controller gain until self-sustaining oscillations are achieved (for PI autotune) + uint16_t kP_pi_atune = 0; // kP value calculated by the autotune PI function multiplied by 100 (to avoid floating point operations) + uint16_t kI_pi_atune = 0; // kI value calulated by the autotune PI function multiplied by 100 (to avoid floating point operations) + int16_t temp_peaks_atune[THERMOSTAT_PEAKNUMBER_AUTOTUNE]; // Array to store temperature peaks to be used by the autotune PI function + int16_t temp_abs_max_atune; // Max temperature reached within autotune + int16_t temp_abs_min_atune; // Min temperature reached within autotune + uint16_t time_peak_timestamps_atune[THERMOSTAT_PEAKNUMBER_AUTOTUNE]; // Array to store timestamps in minutes of the temperature peaks to be used by the autotune PI function + uint16_t time_std_dev_peak_det_ok = THERMOSTAT_TIME_STD_DEV_PEAK_DET_OK; // Standard deviation in minutes of the oscillation periods within the peak detection is successful +#endif // USE_PI_AUTOTUNING +} Thermostat[THERMOSTAT_CONTROLLER_OUTPUTS]; + +/*********************************************************************************************/ + +void ThermostatInit(uint8_t ctr_output) +{ + // Init Thermostat[ctr_output].status bitfield: + Thermostat[ctr_output].status.thermostat_mode = THERMOSTAT_OFF; + Thermostat[ctr_output].status.controller_mode = CTR_HYBRID; + Thermostat[ctr_output].status.climate_mode = CLIMATE_HEATING; + Thermostat[ctr_output].status.sensor_alive = IFACE_OFF; + Thermostat[ctr_output].status.sensor_type = SENSOR_MQTT; + Thermostat[ctr_output].status.temp_format = TEMP_CELSIUS; + Thermostat[ctr_output].status.command_output = IFACE_OFF; + Thermostat[ctr_output].status.status_output = IFACE_OFF; + Thermostat[ctr_output].status.phase_hybrid_ctr = CTR_HYBRID_PI; + Thermostat[ctr_output].status.status_cycle_active = CYCLE_OFF; + Thermostat[ctr_output].diag.state_emergency = EMERGENCY_OFF; + Thermostat[ctr_output].status.counter_seconds = 0; + Thermostat[ctr_output].status.output_relay_number = (THERMOSTAT_RELAY_NUMBER + ctr_output); + Thermostat[ctr_output].status.input_switch_number = (THERMOSTAT_SWITCH_NUMBER + ctr_output); + Thermostat[ctr_output].status.use_input = INPUT_NOT_USED; + Thermostat[ctr_output].status.enable_output = IFACE_ON; + Thermostat[ctr_output].diag.output_inconsist_ctr = 0; + Thermostat[ctr_output].diag.diagnostic_mode = DIAGNOSTIC_ON; +#ifdef USE_PI_AUTOTUNING + Thermostat[ctr_output].status.autotune_flag = AUTOTUNE_OFF; + Thermostat[ctr_output].status.autotune_perf_mode = AUTOTUNE_PERF_FAST; +#endif // USE_PI_AUTOTUNING + // Make sure the Output is OFF + if (Thermostat[ctr_output].status.enable_output == IFACE_ON) { + ExecuteCommandPower(Thermostat[ctr_output].status.output_relay_number, POWER_OFF, SRC_THERMOSTAT); + } +} + +bool ThermostatMinuteCounter(uint8_t ctr_output) +{ + bool result = false; + Thermostat[ctr_output].status.counter_seconds++; // increment time + + if ((Thermostat[ctr_output].status.counter_seconds % 60) == 0) { + result = true; + Thermostat[ctr_output].status.counter_seconds = 0; + } + return result; +} + +inline bool ThermostatSwitchIdValid(uint8_t switchId) +{ + return (switchId >= THERMOSTAT_INPUT_SWT1 && switchId <= THERMOSTAT_INPUT_SWT8); +} + +inline bool ThermostatRelayIdValid(uint8_t relayId) +{ + return (relayId >= THERMOSTAT_OUTPUT_REL1 && relayId <= THERMOSTAT_OUTPUT_REL8); +} + +uint8_t ThermostatInputStatus(uint8_t input_switch) +{ + bool ifId = ThermostatSwitchIdValid(input_switch); + uint8_t value = 0; + if(ifId) { + value = SwitchGetVirtual(ifId - THERMOSTAT_INPUT_SWT1); + } + return value; +} + +uint8_t ThermostatOutputStatus(uint8_t output_switch) +{ + return (uint8_t)bitRead(power, (output_switch - 1)); +} + +int16_t ThermostatCelsiusToFahrenheit(const int32_t deg, uint8_t conv_type) { + int32_t value; + value = (int32_t)(((int32_t)deg * (int32_t)90) / (int32_t)50); + if (conv_type == TEMP_CONV_ABSOLUTE) { + value += (int32_t)320; + } + + // Protect overflow + if (value <= (int32_t)(INT16_MIN)) { + value = (int32_t)(INT16_MIN); + } + else if (value >= (int32_t)INT16_MAX) { + value = (int32_t)INT16_MAX; + } + + return (int16_t)value; +} + +int16_t ThermostatFahrenheitToCelsius(const int32_t deg, uint8_t conv_type) { + int16_t offset = 0; + int32_t value; + if (conv_type == TEMP_CONV_ABSOLUTE) { + offset = 320; + } + + value = (int32_t)(((deg - (int32_t)offset) * (int32_t)50) / (int32_t)90); + + // Protect overflow + if (value <= (int32_t)(INT16_MIN)) { + value = (int32_t)(INT16_MIN); + } + else if (value >= (int32_t)INT16_MAX) { + value = (int32_t)INT16_MAX; + } + + return (int16_t)value; +} + +void ThermostatSignalPreProcessingSlow(uint8_t ctr_output) +{ + // Update input sensor status + if ((uptime - Thermostat[ctr_output].timestamp_temp_measured_update) > ((uint32_t)Thermostat[ctr_output].time_sens_lost * 60)) { + Thermostat[ctr_output].status.sensor_alive = IFACE_OFF; + Thermostat[ctr_output].temp_measured_gradient = 0; + Thermostat[ctr_output].temp_measured = 0; + } +} + +void ThermostatSignalPostProcessingSlow(uint8_t ctr_output) +{ + // Increate counter when inconsistent output state exists + if ((Thermostat[ctr_output].status.status_output != Thermostat[ctr_output].status.command_output) + &&(Thermostat[ctr_output].status.enable_output == IFACE_ON)) { + Thermostat[ctr_output].diag.output_inconsist_ctr++; + } + else { + Thermostat[ctr_output].diag.output_inconsist_ctr = 0; + } +} + +void ThermostatSignalProcessingFast(uint8_t ctr_output) +{ + // Update real status of the input + Thermostat[ctr_output].status.status_input = (uint32_t)ThermostatInputStatus(Thermostat[ctr_output].status.input_switch_number); + // Update timestamp of last input + if (Thermostat[ctr_output].status.status_input == IFACE_ON) { + Thermostat[ctr_output].timestamp_input_on = uptime; + } + // Update real status of the output + Thermostat[ctr_output].status.status_output = (uint32_t)ThermostatOutputStatus(Thermostat[ctr_output].status.output_relay_number); +} + +void ThermostatCtrState(uint8_t ctr_output) +{ +#ifdef USE_PI_AUTOTUNING + bool flag_heating = (Thermostat[ctr_output].status.climate_mode == CLIMATE_HEATING); +#endif //USE_PI_AUTOTUNING + + switch (Thermostat[ctr_output].status.controller_mode) { + // Hybrid controller (Ramp-up + PI) + case CTR_HYBRID: + ThermostatHybridCtrPhase(ctr_output); + break; + // PI controller + case CTR_PI: +#ifdef USE_PI_AUTOTUNING + // If Autotune has been enabled (via flag) + // AND we have just reached the setpoint temperature + // AND the temperature gradient is negative for heating and positive for cooling + // then switch state to PI autotuning + if ((Thermostat[ctr_output].status.autotune_flag == AUTOTUNE_ON) + &&(Thermostat[ctr_output].temp_measured == Thermostat[ctr_output].temp_target_level) + && ((flag_heating && (Thermostat[ctr_output].temp_measured_gradient < 0)) + ||(!flag_heating && (Thermostat[ctr_output].temp_measured_gradient > 0)))) + { + Thermostat[ctr_output].status.controller_mode = CTR_PI_AUTOTUNE; + ThermostatPeakDetectorInit(ctr_output); + } +#endif // USE_PI_AUTOTUNING + break; + // Ramp-up controller (predictive) + case CTR_RAMP_UP: + break; +#ifdef USE_PI_AUTOTUNING + // PI autotune + case CTR_PI_AUTOTUNE: + // If autotune finalized (flag Off) + // then go back to the PI controller + if (Thermostat[ctr_output].status.autotune_flag == AUTOTUNE_OFF) + { + Thermostat[ctr_output].status.controller_mode = CTR_PI; + } + break; +#endif //USE_PI_AUTOTUNING + } +} + +void ThermostatHybridCtrPhase(uint8_t ctr_output) +{ + bool flag_heating = (Thermostat[ctr_output].status.climate_mode == CLIMATE_HEATING); + if (Thermostat[ctr_output].status.controller_mode == CTR_HYBRID) { + switch (Thermostat[ctr_output].status.phase_hybrid_ctr) { + // Ramp-up phase with gradient control + case CTR_HYBRID_RAMP_UP: + // If ramp-up offtime counter has been initalized + // AND ramp-up offtime counter value reached + if((Thermostat[ctr_output].time_ctr_checkpoint != 0) + && (uptime >= Thermostat[ctr_output].time_ctr_checkpoint)) { + // Reset pause period + Thermostat[ctr_output].time_ctr_checkpoint = 0; + // Reset timers + Thermostat[ctr_output].time_ctr_changepoint = 0; + // Set PI controller + Thermostat[ctr_output].status.phase_hybrid_ctr = CTR_HYBRID_PI; + } + break; + // PI controller phase + case CTR_HYBRID_PI: + // If no output action for a pre-defined time + // AND temp target has changed + // AND value of temp target - actual temperature bigger than threshold for heating and lower for cooling + // then go to ramp-up + if (((uptime - Thermostat[ctr_output].timestamp_output_off) > (60 * (uint32_t)Thermostat[ctr_output].time_allow_rampup)) + && (Thermostat[ctr_output].temp_target_level != Thermostat[ctr_output].temp_target_level_ctr) + && ( ( (Thermostat[ctr_output].temp_target_level - Thermostat[ctr_output].temp_measured > Thermostat[ctr_output].temp_rampup_delta_in) + && (flag_heating)) + || ( (Thermostat[ctr_output].temp_measured - Thermostat[ctr_output].temp_target_level > Thermostat[ctr_output].temp_rampup_delta_in) + && (!flag_heating)))) { + Thermostat[ctr_output].timestamp_rampup_start = uptime; + Thermostat[ctr_output].temp_rampup_start = Thermostat[ctr_output].temp_measured; + Thermostat[ctr_output].temp_rampup_meas_gradient = 0; + Thermostat[ctr_output].time_rampup_deadtime = 0; + Thermostat[ctr_output].counter_rampup_cycles = 1; + Thermostat[ctr_output].time_ctr_changepoint = 0; + Thermostat[ctr_output].time_ctr_checkpoint = 0; + Thermostat[ctr_output].status.phase_hybrid_ctr = CTR_HYBRID_RAMP_UP; + } +#ifdef USE_PI_AUTOTUNING + // If Autotune has been enabled (via flag) + // AND we have just reached the setpoint temperature + // AND the temperature gradient is negative for heating and positive for cooling + // then switch state to PI autotuning + if ((Thermostat[ctr_output].status.autotune_flag == AUTOTUNE_ON) + &&(Thermostat[ctr_output].temp_measured == Thermostat[ctr_output].temp_target_level) + && ((flag_heating && (Thermostat[ctr_output].temp_measured_gradient < 0)) + ||(!flag_heating && (Thermostat[ctr_output].temp_measured_gradient > 0)))) + { + Thermostat[ctr_output].status.phase_hybrid_ctr = CTR_HYBRID_PI_AUTOTUNE; + ThermostatPeakDetectorInit(ctr_output); + } +#endif // USE_PI_AUTOTUNING + break; +#ifdef USE_PI_AUTOTUNING + // PI autotune controller phase + case CTR_HYBRID_PI_AUTOTUNE: + // If autotune finalized (flag Off) + // then go back to the PI controller + if (Thermostat[ctr_output].status.autotune_flag == AUTOTUNE_OFF) + { + Thermostat[ctr_output].status.phase_hybrid_ctr = CTR_HYBRID_PI; + } + break; +#endif // USE_PI_AUTOTUNING + } + } +#ifdef DEBUG_THERMOSTAT + ThermostatVirtualSwitchCtrState(ctr_output); +#endif // DEBUG_THERMOSTAT +} + +bool ThermostatStateAutoToManual(uint8_t ctr_output) +{ + bool change_state = false; + // If input is used + // AND switch input is active + // OR temperature sensor is not alive + // then go to manual + if ((Thermostat[ctr_output].status.use_input == INPUT_USED) + &&((Thermostat[ctr_output].status.status_input == IFACE_ON) + || (Thermostat[ctr_output].status.sensor_alive == IFACE_OFF))) { + change_state = true; + } + return change_state; +} + +bool ThermostatStateManualToAuto(uint8_t ctr_output) +{ + bool change_state = false; + + // If switch input inactive + // AND sensor alive + // AND no switch input action (time in current state) bigger than a pre-defined time + // then go to automatic + if ((Thermostat[ctr_output].status.status_input == IFACE_OFF) + &&(Thermostat[ctr_output].status.sensor_alive == IFACE_ON) + && ((uptime - Thermostat[ctr_output].timestamp_input_on) > ((uint32_t)Thermostat[ctr_output].time_manual_to_auto * 60))) { + change_state = true; + } + return change_state; +} + +void ThermostatEmergencyShutdown(uint8_t ctr_output) +{ + // Emergency switch to THERMOSTAT_OFF + Thermostat[ctr_output].status.thermostat_mode = THERMOSTAT_OFF; + Thermostat[ctr_output].status.command_output = IFACE_OFF; + if (Thermostat[ctr_output].status.enable_output == IFACE_ON) { + ThermostatOutputRelay(ctr_output, Thermostat[ctr_output].status.command_output); + } +} + +void ThermostatState(uint8_t ctr_output) +{ + switch (Thermostat[ctr_output].status.thermostat_mode) { + // State if Off or Emergency + case THERMOSTAT_OFF: + // No change of state possible without external command + break; + // State automatic, thermostat active following the command target temp. + case THERMOSTAT_AUTOMATIC_OP: + if (ThermostatStateAutoToManual(ctr_output)) { + // If sensor not alive change to THERMOSTAT_MANUAL_OP + Thermostat[ctr_output].status.thermostat_mode = THERMOSTAT_MANUAL_OP; + } + ThermostatCtrState(ctr_output); + break; + // State manual operation following input switch + case THERMOSTAT_MANUAL_OP: + if (ThermostatStateManualToAuto(ctr_output)) { + // Input switch inactive and timeout reached change to THERMOSTAT_AUTOMATIC_OP + Thermostat[ctr_output].status.thermostat_mode = THERMOSTAT_AUTOMATIC_OP; + } + break; + } +} + +void ThermostatOutputRelay(uint8_t ctr_output, uint32_t command) +{ + // If command received to enable output + // AND current output status is OFF + // then switch output to ON + if ((command == IFACE_ON) + && (Thermostat[ctr_output].status.status_output == IFACE_OFF)) { +//#ifndef DEBUG_THERMOSTAT + if (Thermostat[ctr_output].status.enable_output == IFACE_ON) { + ExecuteCommandPower(Thermostat[ctr_output].status.output_relay_number, POWER_ON, SRC_THERMOSTAT); + } +//#endif // DEBUG_THERMOSTAT + Thermostat[ctr_output].status.status_output = IFACE_ON; +#ifdef DEBUG_THERMOSTAT + ThermostatVirtualSwitch(ctr_output); +#endif // DEBUG_THERMOSTAT + } + // If command received to disable output + // AND current output status is ON + // then switch output to OFF + else if ((command == IFACE_OFF) && (Thermostat[ctr_output].status.status_output == IFACE_ON)) { +//#ifndef DEBUG_THERMOSTAT + if (Thermostat[ctr_output].status.enable_output == IFACE_ON) { + ExecuteCommandPower(Thermostat[ctr_output].status.output_relay_number, POWER_OFF, SRC_THERMOSTAT); + } +//#endif // DEBUG_THERMOSTAT + Thermostat[ctr_output].timestamp_output_off = uptime; + Thermostat[ctr_output].status.status_output = IFACE_OFF; +#ifdef DEBUG_THERMOSTAT + ThermostatVirtualSwitch(ctr_output); +#endif // DEBUG_THERMOSTAT + } +} + +void ThermostatCalculatePI(uint8_t ctr_output) +{ + // General comment: Some variables have been increased in resolution to avoid loosing accuracy in division operations + + bool flag_heating = (Thermostat[ctr_output].status.climate_mode == CLIMATE_HEATING); + int32_t aux_temp_error; + + // Calculate error + aux_temp_error = (int32_t)(Thermostat[ctr_output].temp_target_level_ctr - Thermostat[ctr_output].temp_measured) * 10; + + // Invert error for cooling + if (Thermostat[ctr_output].status.climate_mode == CLIMATE_COOLING) { + aux_temp_error *= -1; + } + + // Protect overflow + if (aux_temp_error <= (int32_t)(INT16_MIN)) { + Thermostat[ctr_output].temp_pi_error = (int16_t)(INT16_MIN); + } + else if (aux_temp_error >= (int32_t)INT16_MAX) { + Thermostat[ctr_output].temp_pi_error = (int16_t)INT16_MAX; + } + else { + Thermostat[ctr_output].temp_pi_error = (int16_t)aux_temp_error; + } + + // Kp = 100/PI.propBand. PI.propBand(Xp) = Proportional range (4K in 4K/200 controller) + Thermostat[ctr_output].kP_pi = 100 / (uint16_t)(Thermostat[ctr_output].val_prop_band); + // Calculate proportional + Thermostat[ctr_output].time_proportional_pi = ((int32_t)(Thermostat[ctr_output].temp_pi_error * (int16_t)Thermostat[ctr_output].kP_pi) * ((int32_t)Thermostat[ctr_output].time_pi_cycle * 60)) / 10000; + + // Minimum proportional action limiter + // If proportional action is less than the minimum action time + // AND proportional > 0 + // then adjust to minimum value + if ((Thermostat[ctr_output].time_proportional_pi < abs(((int32_t)Thermostat[ctr_output].time_min_action * 60))) + && (Thermostat[ctr_output].time_proportional_pi > 0)) { + Thermostat[ctr_output].time_proportional_pi = ((int32_t)Thermostat[ctr_output].time_min_action * 60); + } + + if (Thermostat[ctr_output].time_proportional_pi < 0) { + Thermostat[ctr_output].time_proportional_pi = 0; + } + else if (Thermostat[ctr_output].time_proportional_pi > ((int32_t)Thermostat[ctr_output].time_pi_cycle * 60)) { + Thermostat[ctr_output].time_proportional_pi = ((int32_t)Thermostat[ctr_output].time_pi_cycle * 60); + } + + // Calculate integral (resolution increased to avoid use of floats in consequent operations) + Thermostat[ctr_output].kI_pi = (uint16_t)((((uint32_t)Thermostat[ctr_output].kP_pi * (uint32_t)Thermostat[ctr_output].time_pi_cycle * 6000)) / (uint32_t)Thermostat[ctr_output].time_reset); + + // Reset of antiwindup + // If error does not lay within the integrator scope range, do not use the integral + // and accumulate error = 0 + if (abs((Thermostat[ctr_output].temp_pi_error) / 10) > Thermostat[ctr_output].temp_reset_anti_windup) { + Thermostat[ctr_output].time_integral_pi = 0; + Thermostat[ctr_output].temp_pi_accum_error = 0; + } + // Normal use of integrator + // result will be calculated with the cummulated previous error anterior + // and current error will be cummulated to the previous one + else { + // Hysteresis limiter + // If error is less than or equal than hysteresis, limit output to 0, when temperature + // is rising, never when falling. Limit cummulated error. If this is not done, + // there will be very strong control actions from the integral part due to a + // very high cummulated error when beingin hysteresis. This triggers high + // integral actions + + // Update accumulated error + aux_temp_error = (int32_t)Thermostat[ctr_output].temp_pi_accum_error + (int32_t)Thermostat[ctr_output].temp_pi_error; + + // Protect overflow + if (aux_temp_error <= (int32_t)INT16_MIN) { + Thermostat[ctr_output].temp_pi_accum_error = INT16_MIN; + } + else if (aux_temp_error >= (int32_t)INT16_MAX) { + Thermostat[ctr_output].temp_pi_accum_error = INT16_MAX; + } + else { + Thermostat[ctr_output].temp_pi_accum_error = (int16_t)aux_temp_error; + } + + // If we are under setpoint + // AND we are within the hysteresis + // AND the temperature is rising for heating or sinking for cooling + if ( (Thermostat[ctr_output].temp_pi_error >= 0) + && (abs((Thermostat[ctr_output].temp_pi_error) / 10) <= (int16_t)Thermostat[ctr_output].temp_hysteresis) + && ( ((Thermostat[ctr_output].temp_measured_gradient > 0) + && (flag_heating)) + || ( (Thermostat[ctr_output].temp_measured_gradient < 0) + && (!flag_heating)))) { + // Reduce accumulator error 20% in each cycle + Thermostat[ctr_output].temp_pi_accum_error *= 0.8; + } + // If we are over setpoint + // AND temperature is rising for heating or sinking for cooling + else if ((Thermostat[ctr_output].temp_pi_error < 0) + && ( ((Thermostat[ctr_output].temp_measured_gradient > 0) + && (flag_heating)) + || ( (Thermostat[ctr_output].temp_measured_gradient < 0) + && (!flag_heating)))) { + // Reduce accumulator error 20% in each cycle + Thermostat[ctr_output].temp_pi_accum_error *= 0.8; + } + + // Limit lower limit of acumErr to 0 + if (Thermostat[ctr_output].temp_pi_accum_error < 0) { + Thermostat[ctr_output].temp_pi_accum_error = 0; + } + + // Integral calculation + Thermostat[ctr_output].time_integral_pi = (((int32_t)Thermostat[ctr_output].temp_pi_accum_error * (int32_t)Thermostat[ctr_output].kI_pi) * (int32_t)((uint32_t)Thermostat[ctr_output].time_pi_cycle * 60)) / 1000000; + + // Antiwindup of the integrator + // If integral calculation is bigger than cycle time, adjust result + // to the cycle time and error will not be cummulated + if (Thermostat[ctr_output].time_integral_pi > ((uint32_t)Thermostat[ctr_output].time_pi_cycle * 60)) { + Thermostat[ctr_output].time_integral_pi = ((uint32_t)Thermostat[ctr_output].time_pi_cycle * 60); + } + } + + // Calculate output + Thermostat[ctr_output].time_total_pi = Thermostat[ctr_output].time_proportional_pi + Thermostat[ctr_output].time_integral_pi; + + // Antiwindup of the output + // If result is bigger than cycle time, the result will be adjusted + // to the cylce time minus safety time and error will not be cummulated + if (Thermostat[ctr_output].time_total_pi >= ((int32_t)Thermostat[ctr_output].time_pi_cycle * 60)) { + // Limit to cycle time //at least switch down a minimum time + Thermostat[ctr_output].time_total_pi = ((int32_t)Thermostat[ctr_output].time_pi_cycle * 60); + } + else if (Thermostat[ctr_output].time_total_pi < 0) { + Thermostat[ctr_output].time_total_pi = 0; + } + + // Target value limiter + // If target value has been reached or we are over it for heating or under it for cooling + if (Thermostat[ctr_output].temp_pi_error <= 0) { + // If we are over the hysteresis or the gradient is positive for heating or negative for cooling + if ((abs((Thermostat[ctr_output].temp_pi_error) / 10) > Thermostat[ctr_output].temp_hysteresis) + || ( ((Thermostat[ctr_output].temp_measured_gradient >= 0) + && (flag_heating)) + || ( (Thermostat[ctr_output].temp_measured_gradient <= 0) + && (!flag_heating)))){ + Thermostat[ctr_output].time_total_pi = 0; + } + } + // If target value has not been reached + // AND we are within the histeresis + // AND gradient is positive for heating or negative for cooling + // then set value to 0 + else if ((Thermostat[ctr_output].temp_pi_error > 0) + && (abs((Thermostat[ctr_output].temp_pi_error) / 10) <= Thermostat[ctr_output].temp_hysteresis) + && (((Thermostat[ctr_output].temp_measured_gradient > 0) + && (flag_heating)) + || ( (Thermostat[ctr_output].temp_measured_gradient < 0) + && (!flag_heating)))) { + Thermostat[ctr_output].time_total_pi = 0; + } + + // Minimum action limiter + // If result is less than the minimum action time, adjust to minimum value + if ((Thermostat[ctr_output].time_total_pi <= abs(((uint32_t)Thermostat[ctr_output].time_min_action * 60))) + && (Thermostat[ctr_output].time_total_pi != 0)) { + Thermostat[ctr_output].time_total_pi = ((int32_t)Thermostat[ctr_output].time_min_action * 60); + } + // Maximum action limiter + // If result is more than the maximum action time, adjust to maximum value + else if (Thermostat[ctr_output].time_total_pi > abs(((int32_t)Thermostat[ctr_output].time_max_action * 60))) { + Thermostat[ctr_output].time_total_pi = ((int32_t)Thermostat[ctr_output].time_max_action * 60); + } + // If switched off less time than safety time, do not switch off + else if (Thermostat[ctr_output].time_total_pi > (((int32_t)Thermostat[ctr_output].time_pi_cycle * 60) - ((int32_t)Thermostat[ctr_output].time_min_turnoff_action * 60))) { + Thermostat[ctr_output].time_total_pi = ((int32_t)Thermostat[ctr_output].time_pi_cycle * 60); + } + + // Adjust output switch point + Thermostat[ctr_output].time_ctr_changepoint = uptime + (uint32_t)Thermostat[ctr_output].time_total_pi; + // Adjust next cycle point + Thermostat[ctr_output].time_ctr_checkpoint = uptime + ((uint32_t)Thermostat[ctr_output].time_pi_cycle * 60); +} + +void ThermostatWorkAutomaticPI(uint8_t ctr_output) +{ + bool flag_heating = (Thermostat[ctr_output].status.climate_mode == CLIMATE_HEATING); + if ( (uptime >= Thermostat[ctr_output].time_ctr_checkpoint) + || (Thermostat[ctr_output].temp_target_level != Thermostat[ctr_output].temp_target_level_ctr) + || ( (( (Thermostat[ctr_output].temp_measured < Thermostat[ctr_output].temp_target_level) + && (Thermostat[ctr_output].temp_measured_gradient < 0) + && (flag_heating)) + || ((Thermostat[ctr_output].temp_measured > Thermostat[ctr_output].temp_target_level) + && (Thermostat[ctr_output].temp_measured_gradient > 0) + && (!flag_heating))) + && (Thermostat[ctr_output].status.status_cycle_active == CYCLE_OFF))) { + Thermostat[ctr_output].temp_target_level_ctr = Thermostat[ctr_output].temp_target_level; + ThermostatCalculatePI(ctr_output); + // Reset cycle active + Thermostat[ctr_output].status.status_cycle_active = CYCLE_OFF; + } + if (uptime < Thermostat[ctr_output].time_ctr_changepoint) { + Thermostat[ctr_output].status.status_cycle_active = CYCLE_ON; + Thermostat[ctr_output].status.command_output = IFACE_ON; + } + else { + Thermostat[ctr_output].status.command_output = IFACE_OFF; + } +} + +void ThermostatWorkAutomaticRampUp(uint8_t ctr_output) +{ + uint32_t time_in_rampup; + int16_t aux_temp_delta; + int16_t temp_delta_rampup; + bool flag_heating = (Thermostat[ctr_output].status.climate_mode == CLIMATE_HEATING); + + // Update timestamp for temperature at start of ramp-up if temperature still + // dropping for heating or rising for cooling + if ( ((Thermostat[ctr_output].temp_measured < Thermostat[ctr_output].temp_rampup_start) + && (flag_heating)) + || ((Thermostat[ctr_output].temp_measured > Thermostat[ctr_output].temp_rampup_start) + && (!flag_heating))) + { + Thermostat[ctr_output].temp_rampup_start = Thermostat[ctr_output].temp_measured; + } + + // Update time in ramp-up as well as delta temp + time_in_rampup = uptime - Thermostat[ctr_output].timestamp_rampup_start; + temp_delta_rampup = Thermostat[ctr_output].temp_measured - Thermostat[ctr_output].temp_rampup_start; + // Init command output status to true + Thermostat[ctr_output].status.command_output = IFACE_ON; + // Update temperature target level for controller + Thermostat[ctr_output].temp_target_level_ctr = Thermostat[ctr_output].temp_target_level; + + // If time in ramp-up < max time + // AND temperature measured < target for heating or > for cooling + if ((time_in_rampup <= (60 * (uint32_t)Thermostat[ctr_output].time_rampup_max)) + && ( ((Thermostat[ctr_output].temp_measured < Thermostat[ctr_output].temp_target_level) + && (flag_heating)) + || ((Thermostat[ctr_output].temp_measured > Thermostat[ctr_output].temp_target_level) + && (!flag_heating)))){ + // DEADTIME point reached + // If temperature measured minus temperature at start of ramp-up >= threshold + // AND deadtime still 0 + if ( (abs(temp_delta_rampup) >= Thermostat[ctr_output].temp_rampup_delta_out) + && (Thermostat[ctr_output].time_rampup_deadtime == 0)) { + // Set deadtime, assuming it is half of the time until slope, since thermal inertia of the temp. fall needs to be considered + // minus open time of the valve (arround 3 minutes). If rise/sink very fast limit it to delay of output valve + int32_t time_aux; + time_aux = ((time_in_rampup / 2) - Thermostat[ctr_output].time_output_delay); + if (time_aux >= Thermostat[ctr_output].time_output_delay) { + Thermostat[ctr_output].time_rampup_deadtime = (uint32_t)time_aux; + } + else { + Thermostat[ctr_output].time_rampup_deadtime = Thermostat[ctr_output].time_output_delay; + } + // Calculate absolute gradient since start of ramp-up (considering deadtime) in thousandths of º/hour + Thermostat[ctr_output].temp_rampup_meas_gradient = (int32_t)((360000 * (int32_t)temp_delta_rampup) / (int32_t)time_in_rampup); + Thermostat[ctr_output].time_rampup_nextcycle = uptime + ((uint32_t)Thermostat[ctr_output].time_rampup_cycle * 60); + // Set auxiliary variables + Thermostat[ctr_output].temp_rampup_cycle = Thermostat[ctr_output].temp_measured; + Thermostat[ctr_output].time_ctr_changepoint = uptime + (60 * (uint32_t)Thermostat[ctr_output].time_rampup_max); + Thermostat[ctr_output].temp_rampup_output_off = Thermostat[ctr_output].temp_target_level_ctr; + } + // Gradient calculation every time_rampup_cycle + else if ((Thermostat[ctr_output].time_rampup_deadtime > 0) && (uptime >= Thermostat[ctr_output].time_rampup_nextcycle)) { + // Calculate temp. gradient in º/hour and set again time_rampup_nextcycle and temp_rampup_cycle + // temp_rampup_meas_gradient = ((3600 * temp_delta_rampup) / (os.time() - time_rampup_nextcycle)) + temp_delta_rampup = Thermostat[ctr_output].temp_measured - Thermostat[ctr_output].temp_rampup_cycle; + uint32_t time_total_rampup = (uint32_t)Thermostat[ctr_output].time_rampup_cycle * 60 * Thermostat[ctr_output].counter_rampup_cycles; + // Translate into gradient per hour (thousandths of ° per hour) + Thermostat[ctr_output].temp_rampup_meas_gradient = int32_t((360000 * (int32_t)temp_delta_rampup) / (int32_t)time_total_rampup); + if ( ((Thermostat[ctr_output].temp_rampup_meas_gradient > 0) + && ((flag_heating))) + || ((Thermostat[ctr_output].temp_rampup_meas_gradient < 0) + && ((!flag_heating)))) { + // Calculate time to switch Off and come out of ramp-up + // y-y1 = m(x-x1) -> x = ((y-y1) / m) + x1 -> y1 = temp_rampup_cycle, x1 = (time_rampup_nextcycle - time_rampup_cycle), m = gradient in º/sec + // Better Alternative -> (y-y1)/(x-x1) = ((y2-y1)/(x2-x1)) -> where y = temp (target) and x = time (to switch off, what its needed) + // x = ((y-y1)/(y2-y1))*(x2-x1) + x1 - deadtime + aux_temp_delta =Thermostat[ctr_output].temp_target_level_ctr - Thermostat[ctr_output].temp_rampup_cycle; + Thermostat[ctr_output].time_ctr_changepoint = (uint32_t)(uint32_t)(((uint32_t)(aux_temp_delta) * (uint32_t)(time_total_rampup)) / (uint32_t)temp_delta_rampup) + (uint32_t)Thermostat[ctr_output].time_rampup_nextcycle - (uint32_t)time_total_rampup - (uint32_t)Thermostat[ctr_output].time_rampup_deadtime; + + // Calculate temperature for switching off the output + // y = (((y2-y1)/(x2-x1))*(x-x1)) + y1 + Thermostat[ctr_output].temp_rampup_output_off = (int16_t)(((int32_t)temp_delta_rampup * (int32_t)(Thermostat[ctr_output].time_ctr_changepoint - (uptime - (time_total_rampup)))) / (int32_t)(time_total_rampup * Thermostat[ctr_output].counter_rampup_cycles)) + Thermostat[ctr_output].temp_rampup_cycle; + // Set auxiliary variables + Thermostat[ctr_output].time_rampup_nextcycle = uptime + ((uint32_t)Thermostat[ctr_output].time_rampup_cycle * 60); + Thermostat[ctr_output].temp_rampup_cycle = Thermostat[ctr_output].temp_measured; + // Reset period counter + Thermostat[ctr_output].counter_rampup_cycles = 1; + } + else { + // Increase the period counter + Thermostat[ctr_output].counter_rampup_cycles++; + // Set another period + Thermostat[ctr_output].time_rampup_nextcycle = uptime + ((uint32_t)Thermostat[ctr_output].time_rampup_cycle * 60); + // Reset time_ctr_changepoint and temp_rampup_output_off + Thermostat[ctr_output].time_ctr_changepoint = uptime + (60 * (uint32_t)Thermostat[ctr_output].time_rampup_max) - time_in_rampup; + Thermostat[ctr_output].temp_rampup_output_off = Thermostat[ctr_output].temp_target_level_ctr; + } + // Set time to get out of ramp-up + Thermostat[ctr_output].time_ctr_checkpoint = Thermostat[ctr_output].time_ctr_changepoint + Thermostat[ctr_output].time_rampup_deadtime; + } + + // Set output switch ON or OFF + // If deadtime has not been calculated + // or checkpoint has not been calculated + // or it is not yet time and temperature to switch it off acc. to calculations + // or gradient is <= 0 for heating of >= 0 for cooling + if ((Thermostat[ctr_output].time_rampup_deadtime == 0) + || (Thermostat[ctr_output].time_ctr_checkpoint == 0) + || (uptime < Thermostat[ctr_output].time_ctr_changepoint) + || ( ((Thermostat[ctr_output].temp_measured < Thermostat[ctr_output].temp_rampup_output_off) + && (flag_heating)) + || ((Thermostat[ctr_output].temp_measured > Thermostat[ctr_output].temp_rampup_output_off) + && (!flag_heating))) + || ( ((Thermostat[ctr_output].temp_rampup_meas_gradient <= 0) + && (flag_heating)) + || ((Thermostat[ctr_output].temp_rampup_meas_gradient >= 0) + && (!flag_heating)))) { + Thermostat[ctr_output].status.command_output = IFACE_ON; + } + else { + Thermostat[ctr_output].status.command_output = IFACE_OFF; + } + } + else { + // If we have not reached the temperature, start with an initial value for accumulated error for the PI controller + if ( ((Thermostat[ctr_output].temp_measured < Thermostat[ctr_output].temp_target_level_ctr) + && (flag_heating)) + || ((Thermostat[ctr_output].temp_measured > Thermostat[ctr_output].temp_target_level_ctr) + && (!flag_heating))) { + Thermostat[ctr_output].temp_pi_accum_error = Thermostat[ctr_output].temp_rampup_pi_acc_error; + } + // Set to now time to get out of ramp-up + Thermostat[ctr_output].time_ctr_checkpoint = uptime; + // Switch Off output + Thermostat[ctr_output].status.command_output = IFACE_OFF; + } +} + +#ifdef USE_PI_AUTOTUNING + +void ThermostatPeakDetectorInit(uint8_t ctr_output) +{ + for (uint8_t i = 0; i < THERMOSTAT_PEAKNUMBER_AUTOTUNE; i++) { + Thermostat[ctr_output].temp_peaks_atune[i] = 0; + } + Thermostat[ctr_output].pU_pi_atune = 0; + Thermostat[ctr_output].kP_pi_atune = 0; + Thermostat[ctr_output].kI_pi_atune = 0; + Thermostat[ctr_output].kU_pi_atune = 0; + Thermostat[ctr_output].peak_ctr = 0; + Thermostat[ctr_output].temp_abs_max_atune = 0; + Thermostat[ctr_output].temp_abs_min_atune = 100; + Thermostat[ctr_output].time_ctr_checkpoint = uptime + THERMOSTAT_TIME_MAX_AUTOTUNE; +} + +void ThermostatPeakDetector(uint8_t ctr_output) +{ + uint8_t peak_num = Thermostat[ctr_output].peak_ctr; + int16_t peak_avg = 0; + bool peak_transition = false; + // Update Max/Min Thermostat[ctr_output].temp_abs_max_atune + if (Thermostat[ctr_output].temp_measured > Thermostat[ctr_output].temp_abs_max_atune) { + Thermostat[ctr_output].temp_abs_max_atune = Thermostat[ctr_output].temp_measured; + } + if (Thermostat[ctr_output].temp_measured < Thermostat[ctr_output].temp_abs_min_atune) { + Thermostat[ctr_output].temp_abs_min_atune = Thermostat[ctr_output].temp_measured; + } + // For heating, even peak numbers look for maxes, odd for minds, the contrary for cooling + // If we did not found all peaks yet + if (peak_num < THERMOSTAT_PEAKNUMBER_AUTOTUNE) { + bool flag_heating = (Thermostat[ctr_output].status.climate_mode == CLIMATE_HEATING); + bool cond_peak_1 = ( (Thermostat[ctr_output].temp_measured > Thermostat[ctr_output].temp_peaks_atune[peak_num]) + && (flag_heating) + || (Thermostat[ctr_output].temp_measured < Thermostat[ctr_output].temp_peaks_atune[peak_num]) + && (!flag_heating)); + bool cond_peak_2 = ( (Thermostat[ctr_output].temp_measured < Thermostat[ctr_output].temp_peaks_atune[peak_num]) + && (flag_heating) + || (Thermostat[ctr_output].temp_measured > Thermostat[ctr_output].temp_peaks_atune[peak_num]) + && (!flag_heating)); + bool cond_gradient_1 = ( (Thermostat[ctr_output].temp_measured_gradient > 0) + && (flag_heating) + || (Thermostat[ctr_output].temp_measured_gradient < 0) + && (!flag_heating)); + bool cond_gradient_2 = ( (Thermostat[ctr_output].temp_measured_gradient < 0) + && (flag_heating) + || (Thermostat[ctr_output].temp_measured_gradient > 0) + && (!flag_heating)); + // If peak number is even (look for max if heating and min if cooling) + if ((peak_num % 2) == 0) { + // If current temperature higher (heating) or lower (cooling) than registered value for peak + // AND temperature gradient > 0 for heating or < 0 for cooling + // then, update value + if (cond_peak_1 && cond_gradient_1) { + Thermostat[ctr_output].temp_peaks_atune[peak_num] = Thermostat[ctr_output].temp_measured; + } + // Else if current temperature lower (heating) or higher (cooling) then registered value for peak + // AND difference to peak is outside of the peak no detection band + // then the current peak value is the peak (max for heating, min for cooling), switch detection + if ( (cond_peak_2) + && (abs(Thermostat[ctr_output].temp_measured - Thermostat[ctr_output].temp_peaks_atune[peak_num]) > Thermostat[ctr_output].temp_band_no_peak_det)) { + // Register peak timestamp; + Thermostat[ctr_output].time_peak_timestamps_atune[peak_num] = (uptime / 60); + Thermostat[ctr_output].peak_ctr++; + peak_transition = true; + } + } + // Peak number is odd (look for min if heating and max if cooling) + else { + // If current temperature lower (heating) or higher (cooling) than registered value for peak + // AND temperature gradient < 0 for heating or > 0 for cooling + // then, update value + if (cond_peak_2 && cond_gradient_2) { + Thermostat[ctr_output].temp_peaks_atune[peak_num] = Thermostat[ctr_output].temp_measured; + } + // Else if current temperature higher (heating) or lower (cooling) then registered value for peak + // AND difference to peak is outside of the peak no detection band + // then the current peak value is the peak (min for heating, max for cooling), switch detection + if ( (cond_peak_1) + && (abs(Thermostat[ctr_output].temp_measured - Thermostat[ctr_output].temp_peaks_atune[peak_num]) > Thermostat[ctr_output].temp_band_no_peak_det)) { + // Calculate period + // Register peak timestamp; + Thermostat[ctr_output].time_peak_timestamps_atune[peak_num] = (uptime / 60); + Thermostat[ctr_output].peak_ctr++; + peak_transition = true; + } + } + } + else { + // Peak detection done, proceed to evaluate results + ThermostatAutotuneParamCalc(ctr_output); + Thermostat[ctr_output].status.autotune_flag = AUTOTUNE_OFF; + } + + // If peak detection not finalized but bigger than 3 and we have just found a peak, check if results can be extracted + if ((Thermostat[ctr_output].peak_ctr > 2) && (peak_transition)) { + //Update peak_num + peak_num = Thermostat[ctr_output].peak_ctr; + // Calculate average value among the last 3 peaks + peak_avg = (abs(Thermostat[ctr_output].temp_peaks_atune[peak_num - 1] + - Thermostat[ctr_output].temp_peaks_atune[peak_num - 2]) + + abs(Thermostat[ctr_output].temp_peaks_atune[peak_num - 2] + - Thermostat[ctr_output].temp_peaks_atune[peak_num - 3])) / 2; + + if ((20 * (int32_t)peak_avg) < (int32_t)(Thermostat[ctr_output].temp_abs_max_atune - Thermostat[ctr_output].temp_abs_min_atune)) { + // Calculate average temperature among all peaks + for (uint8_t i = 0; i < peak_num; i++) { + peak_avg += Thermostat[ctr_output].temp_peaks_atune[i]; + } + peak_avg /= peak_num; + // If last period crosses the average value, result valid + if (10 * abs(Thermostat[ctr_output].temp_peaks_atune[peak_num - 1] - Thermostat[ctr_output].temp_peaks_atune[peak_num - 2]) < (Thermostat[ctr_output].temp_abs_max_atune - peak_avg)) { + // Peak detection done, proceed to evaluate results + ThermostatAutotuneParamCalc(ctr_output); + Thermostat[ctr_output].status.autotune_flag = AUTOTUNE_OFF; + } + } + } + peak_transition = false; +} + +void ThermostatAutotuneParamCalc(uint8_t ctr_output) +{ + uint8_t peak_num = Thermostat[ctr_output].peak_ctr; + + // Calculate the tunning parameters + // Resolution increased to avoid float operations + Thermostat[ctr_output].kU_pi_atune = (uint16_t)(100 * ((uint32_t)400000 * (uint32_t)(Thermostat[ctr_output].dutycycle_step_autotune)) / ((uint32_t)(Thermostat[ctr_output].temp_abs_max_atune - Thermostat[ctr_output].temp_abs_min_atune) * (uint32_t)314159)); + Thermostat[ctr_output].pU_pi_atune = (Thermostat[ctr_output].time_peak_timestamps_atune[peak_num - 1] - Thermostat[ctr_output].time_peak_timestamps_atune[peak_num - 2]); + + switch (Thermostat[ctr_output].status.autotune_perf_mode) { + case AUTOTUNE_PERF_FAST: + // Calculate kP/Ki autotune + Thermostat[ctr_output].kP_pi_atune = (4 * Thermostat[ctr_output].kU_pi_atune) / 10; + break; + case AUTOTUNE_PERF_NORMAL: + // Calculate kP/Ki autotune + Thermostat[ctr_output].kP_pi_atune = (18 * Thermostat[ctr_output].kU_pi_atune) / 100; + break; + case AUTOTUNE_PERF_SLOW: + // Calculate kP/Ki autotune + Thermostat[ctr_output].kP_pi_atune = (13 * Thermostat[ctr_output].kU_pi_atune) / 100; + break; + } + + // Resolution increased to avoid float operations + Thermostat[ctr_output].kI_pi_atune = (12 * (6000 * Thermostat[ctr_output].kU_pi_atune / Thermostat[ctr_output].pU_pi_atune)) / 10; + + // Calculate PropBand Autotune + Thermostat[ctr_output].val_prop_band_atune = 100 / Thermostat[ctr_output].kP_pi_atune; + // Calculate Reset Time Autotune + Thermostat[ctr_output].time_reset_atune = (uint32_t)((((uint32_t)Thermostat[ctr_output].kP_pi_atune * (uint32_t)Thermostat[ctr_output].time_pi_cycle * 6000)) / (uint32_t)Thermostat[ctr_output].kI_pi_atune); +} + +void ThermostatWorkAutomaticPIAutotune(uint8_t ctr_output) +{ + bool flag_heating = (Thermostat[ctr_output].status.climate_mode == CLIMATE_HEATING); + // If no timeout of the PI Autotune function + // AND no change in setpoint + if ((uptime < Thermostat[ctr_output].time_ctr_checkpoint) + &&(Thermostat[ctr_output].temp_target_level_ctr == Thermostat[ctr_output].temp_target_level)) { + if (uptime >= Thermostat[ctr_output].time_ctr_checkpoint) { + Thermostat[ctr_output].temp_target_level_ctr = Thermostat[ctr_output].temp_target_level; + // Calculate time_ctr_changepoint + Thermostat[ctr_output].time_ctr_changepoint = uptime + (((uint32_t)Thermostat[ctr_output].time_pi_cycle * (uint32_t)Thermostat[ctr_output].dutycycle_step_autotune) / (uint32_t)100); + // Reset cycle active + Thermostat[ctr_output].status.status_cycle_active = CYCLE_OFF; + } + // Set Output On/Off depending on the changepoint + if (uptime < Thermostat[ctr_output].time_ctr_changepoint) { + Thermostat[ctr_output].status.status_cycle_active = CYCLE_ON; + Thermostat[ctr_output].status.command_output = IFACE_ON; + } + else { + Thermostat[ctr_output].status.command_output = IFACE_OFF; + } + // Update peak values + ThermostatPeakDetector(ctr_output); + } + else { + // Disable Autotune flag + Thermostat[ctr_output].status.autotune_flag = AUTOTUNE_OFF; + } + + if (Thermostat[ctr_output].status.autotune_flag == AUTOTUNE_OFF) { + // Set output Off + Thermostat[ctr_output].status.command_output = IFACE_OFF; + } +} +#endif //USE_PI_AUTOTUNING + +void ThermostatCtrWork(uint8_t ctr_output) +{ + switch (Thermostat[ctr_output].status.controller_mode) { + // Hybrid controller (Ramp-up + PI) + case CTR_HYBRID: + switch (Thermostat[ctr_output].status.phase_hybrid_ctr) { + case CTR_HYBRID_RAMP_UP: + ThermostatWorkAutomaticRampUp(ctr_output); + break; + case CTR_HYBRID_PI: + ThermostatWorkAutomaticPI(ctr_output); + break; +#ifdef USE_PI_AUTOTUNING + // PI autotune + case CTR_HYBRID_PI_AUTOTUNE: + ThermostatWorkAutomaticPIAutotune(ctr_output); + break; +#endif //USE_PI_AUTOTUNING + } + break; + // PI controller + case CTR_PI: + ThermostatWorkAutomaticPI(ctr_output); + break; + // Ramp-up controller (predictive) + case CTR_RAMP_UP: + ThermostatWorkAutomaticRampUp(ctr_output); + break; +#ifdef USE_PI_AUTOTUNING + // PI autotune + case CTR_PI_AUTOTUNE: + ThermostatWorkAutomaticPIAutotune(ctr_output); + break; +#endif //USE_PI_AUTOTUNING + } +} + +void ThermostatWork(uint8_t ctr_output) +{ + switch (Thermostat[ctr_output].status.thermostat_mode) { + // State if thermostat Off or Emergency + case THERMOSTAT_OFF: + Thermostat[ctr_output].status.command_output = IFACE_OFF; + break; + // State automatic thermostat active following to command target temp. + case THERMOSTAT_AUTOMATIC_OP: + ThermostatCtrWork(ctr_output); + + break; + // State manual operation following input switch + case THERMOSTAT_MANUAL_OP: + Thermostat[ctr_output].time_ctr_checkpoint = 0; + Thermostat[ctr_output].status.command_output = Thermostat[ctr_output].status.status_input; + break; + } + ThermostatOutputRelay(ctr_output, Thermostat[ctr_output].status.command_output); +} + +void ThermostatDiagnostics(uint8_t ctr_output) +{ + // Diagnostic related to the plausibility of the output state + if ((Thermostat[ctr_output].diag.diagnostic_mode == DIAGNOSTIC_ON) + &&(Thermostat[ctr_output].diag.output_inconsist_ctr >= THERMOSTAT_TIME_MAX_OUTPUT_INCONSIST)) { + Thermostat[ctr_output].status.thermostat_mode = THERMOSTAT_OFF; + Thermostat[ctr_output].diag.state_emergency = EMERGENCY_ON; + } + + // Diagnostic related to the plausibility of the output power implemented + // already into the energy driver + + // If diagnostics fail, emergency enabled and thermostat shutdown triggered + if (Thermostat[ctr_output].diag.state_emergency == EMERGENCY_ON) { + ThermostatEmergencyShutdown(ctr_output); + } +} + +void ThermostatController(uint8_t ctr_output) +{ + ThermostatState(ctr_output); + ThermostatWork(ctr_output); +} + +bool ThermostatTimerArm(uint8_t ctr_output, int16_t tempVal) +{ + bool result = false; + // TempVal unit is tenths of degrees celsius + if ((tempVal >= -1000) + && (tempVal <= 1000) + && (tempVal >= (int16_t)Thermostat[ctr_output].temp_frost_protect)) { + Thermostat[ctr_output].temp_target_level = tempVal; + Thermostat[ctr_output].status.thermostat_mode = THERMOSTAT_AUTOMATIC_OP; + result = true; + } + // Returns true if setpoint plausible and thermostat armed, false on the contrary + return result; +} + +void ThermostatTimerDisarm(uint8_t ctr_output) +{ + Thermostat[ctr_output].temp_target_level = THERMOSTAT_TEMP_INIT; + Thermostat[ctr_output].status.thermostat_mode = THERMOSTAT_OFF; +} + +#ifdef DEBUG_THERMOSTAT +void ThermostatVirtualSwitch(uint8_t ctr_output) +{ + char domoticz_in_topic[] = DOMOTICZ_IN_TOPIC; + if (ctr_output < DOMOTICZ_MAX_IDX) { + Response_P(DOMOTICZ_MES, Domoticz_Virtual_Switches[ctr_output], (0 == Thermostat[ctr_output].status.command_output) ? 0 : 1, ""); + MqttPublish(domoticz_in_topic); + } +} + +void ThermostatVirtualSwitchCtrState(uint8_t ctr_output) +{ + char domoticz_in_topic[] = DOMOTICZ_IN_TOPIC; + Response_P(DOMOTICZ_MES, DOMOTICZ_IDX2, (0 == Thermostat[0].status.phase_hybrid_ctr) ? 0 : 1, ""); + MqttPublish(domoticz_in_topic); +} + +void ThermostatDebug(uint8_t ctr_output) +{ + char result_chr[FLOATSZ]; + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("")); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("------ Thermostat Start ------")); + dtostrfd(Thermostat[ctr_output].status.counter_seconds, 0, result_chr); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].status.counter_seconds: %s"), result_chr); + dtostrfd(Thermostat[ctr_output].status.thermostat_mode, 0, result_chr); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].status.thermostat_mode: %s"), result_chr); + dtostrfd(Thermostat[ctr_output].diag.state_emergency, 0, result_chr); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].diag.state_emergency: %s"), result_chr); + dtostrfd(Thermostat[ctr_output].diag.output_inconsist_ctr, 0, result_chr); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].diag.output_inconsist_ctr: %s"), result_chr); + dtostrfd(Thermostat[ctr_output].status.controller_mode, 0, result_chr); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].status.controller_mode: %s"), result_chr); + dtostrfd(Thermostat[ctr_output].status.command_output, 0, result_chr); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].status.command_output: %s"), result_chr); + dtostrfd(Thermostat[ctr_output].status.status_output, 0, result_chr); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].status.status_output: %s"), result_chr); + dtostrfd(Thermostat[ctr_output].status.status_input, 0, result_chr); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].status.status_input: %s"), result_chr); + dtostrfd(Thermostat[ctr_output].status.phase_hybrid_ctr, 0, result_chr); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].status.phase_hybrid_ctr: %s"), result_chr); + dtostrfd(Thermostat[ctr_output].status.sensor_alive, 0, result_chr); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].status.sensor_alive: %s"), result_chr); + dtostrfd(Thermostat[ctr_output].status.status_cycle_active, 0, result_chr); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].status.status_cycle_active: %s"), result_chr); + dtostrfd(Thermostat[ctr_output].temp_pi_error, 0, result_chr); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].temp_pi_error: %s"), result_chr); + dtostrfd(Thermostat[ctr_output].temp_pi_accum_error, 0, result_chr); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].temp_pi_accum_error: %s"), result_chr); + dtostrfd(Thermostat[ctr_output].time_proportional_pi, 0, result_chr); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].time_proportional_pi: %s"), result_chr); + dtostrfd(Thermostat[ctr_output].time_integral_pi, 0, result_chr); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].time_integral_pi: %s"), result_chr); + dtostrfd(Thermostat[ctr_output].time_total_pi, 0, result_chr); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].time_total_pi: %s"), result_chr); + dtostrfd(Thermostat[ctr_output].temp_measured_gradient, 0, result_chr); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].temp_measured_gradient: %s"), result_chr); + dtostrfd(Thermostat[ctr_output].time_rampup_deadtime, 0, result_chr); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].time_rampup_deadtime: %s"), result_chr); + dtostrfd(Thermostat[ctr_output].temp_rampup_meas_gradient, 0, result_chr); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].temp_rampup_meas_gradient: %s"), result_chr); + dtostrfd(Thermostat[ctr_output].time_ctr_changepoint, 0, result_chr); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].time_ctr_changepoint: %s"), result_chr); + dtostrfd(Thermostat[ctr_output].temp_rampup_output_off, 0, result_chr); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].temp_rampup_output_off: %s"), result_chr); + dtostrfd(Thermostat[ctr_output].time_ctr_checkpoint, 0, result_chr); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Thermostat[ctr_output].time_ctr_checkpoint: %s"), result_chr); + dtostrfd(uptime, 0, result_chr); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("uptime: %s"), result_chr); + dtostrfd(power, 0, result_chr); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("power: %s"), result_chr); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("------ Thermostat End ------")); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("")); +} +#endif // DEBUG_THERMOSTAT + +void ThermostatGetLocalSensor(uint8_t ctr_output) { + DynamicJsonBuffer jsonBuffer; + JsonObject& root = jsonBuffer.parseObject((const char*)mqtt_data); + if (root.success()) { + const char* value_c = root[THERMOSTAT_SENSOR_NAME]["Temperature"]; + if (value_c != NULL && strlen(value_c) > 0 && (isdigit(value_c[0]) || (value_c[0] == '-' && isdigit(value_c[1])) ) ) { + int16_t value = (int16_t)(CharToFloat(value_c) * 10); + if ( (value >= -1000) + && (value <= 1000) + && (Thermostat[ctr_output].status.sensor_type == SENSOR_LOCAL)) { + uint32_t timestamp = uptime; + // Calculate temperature gradient if temperature value has changed + if (value != Thermostat[ctr_output].temp_measured) { + int32_t temp_delta = (value - Thermostat[ctr_output].temp_measured); // in tenths of degrees + uint32_t time_delta = (timestamp - Thermostat[ctr_output].timestamp_temp_meas_change_update); // in seconds + Thermostat[ctr_output].temp_measured_gradient = (int32_t)((360000 * temp_delta) / ((int32_t)time_delta)); // thousandths of degrees per hour + Thermostat[ctr_output].temp_measured = value; + Thermostat[ctr_output].timestamp_temp_meas_change_update = timestamp; + } + Thermostat[ctr_output].timestamp_temp_measured_update = timestamp; + Thermostat[ctr_output].status.sensor_alive = IFACE_ON; + } + } + } +} + +/*********************************************************************************************\ + * Commands +\*********************************************************************************************/ + +void CmndThermostatModeSet(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= THERMOSTAT_CONTROLLER_OUTPUTS)) { + uint8_t ctr_output = XdrvMailbox.index - 1; + if (XdrvMailbox.data_len > 0) { + uint8_t value = (uint8_t)(CharToFloat(XdrvMailbox.data)); + if ((value >= THERMOSTAT_OFF) && (value < THERMOSTAT_MODES_MAX)) { + Thermostat[ctr_output].status.thermostat_mode = value; + Thermostat[ctr_output].timestamp_input_on = 0; // Reset last manual switch timer if command set externally + } + } + ResponseCmndNumber((int)Thermostat[ctr_output].status.thermostat_mode); + } +} + +void CmndClimateModeSet(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= THERMOSTAT_CONTROLLER_OUTPUTS)) { + uint8_t ctr_output = XdrvMailbox.index - 1; + if (XdrvMailbox.data_len > 0) { + uint8_t value = (uint8_t)(CharToFloat(XdrvMailbox.data)); + if ((value >= CLIMATE_HEATING) && (value < CLIMATE_MODES_MAX)) { + Thermostat[ctr_output].status.climate_mode = value; + // Trigger a restart of the controller + Thermostat[ctr_output].time_ctr_checkpoint = uptime; + } + } + ResponseCmndNumber((int)Thermostat[ctr_output].status.climate_mode); + } +} + +void CmndTempFrostProtectSet(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= THERMOSTAT_CONTROLLER_OUTPUTS)) { + uint8_t ctr_output = XdrvMailbox.index - 1; + int16_t value; + if (XdrvMailbox.data_len > 0) { + if (Thermostat[ctr_output].status.temp_format == TEMP_FAHRENHEIT) { + value = (int16_t)ThermostatFahrenheitToCelsius((int32_t)(CharToFloat(XdrvMailbox.data) * 10), TEMP_CONV_ABSOLUTE); + } + else { + value = (int16_t)(CharToFloat(XdrvMailbox.data) * 10); + } + if ( (value >= 0) + && (value <= 127)) { + Thermostat[ctr_output].temp_frost_protect = (uint8_t)value; + } + } + if (Thermostat[ctr_output].status.temp_format == TEMP_FAHRENHEIT) { + value = ThermostatCelsiusToFahrenheit((int32_t)Thermostat[ctr_output].temp_frost_protect, TEMP_CONV_ABSOLUTE); + } + else { + value = (int16_t)Thermostat[ctr_output].temp_frost_protect; + } + ResponseCmndFloat((float)value / 10, 1); + } +} + +void CmndControllerModeSet(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= THERMOSTAT_CONTROLLER_OUTPUTS)) { + uint8_t ctr_output = XdrvMailbox.index - 1; + if (XdrvMailbox.data_len > 0) { + uint8_t value = (uint8_t)(XdrvMailbox.payload); + if ((value >= CTR_HYBRID) && (value < CTR_MODES_MAX)) { + Thermostat[ctr_output].status.controller_mode = value; + // Reset controller variables + Thermostat[ctr_output].timestamp_rampup_start = uptime; + Thermostat[ctr_output].temp_rampup_start = Thermostat[ctr_output].temp_measured; + Thermostat[ctr_output].temp_rampup_meas_gradient = 0; + Thermostat[ctr_output].time_rampup_deadtime = 0; + Thermostat[ctr_output].counter_rampup_cycles = 1; + Thermostat[ctr_output].time_ctr_changepoint = 0; + Thermostat[ctr_output].time_ctr_checkpoint = 0; + } + } + ResponseCmndNumber((int)Thermostat[ctr_output].status.controller_mode); + } +} + +void CmndInputSwitchSet(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= THERMOSTAT_CONTROLLER_OUTPUTS)) { + uint8_t ctr_output = XdrvMailbox.index - 1; + if (XdrvMailbox.data_len > 0) { + uint8_t value = (uint8_t)(XdrvMailbox.payload); + if (ThermostatSwitchIdValid(value)) { + Thermostat[ctr_output].status.input_switch_number = value; + Thermostat[ctr_output].timestamp_input_on = uptime; + } + } + ResponseCmndNumber((int)Thermostat[ctr_output].status.input_switch_number); + } +} + +void CmndInputSwitchUse(void) +{ + if ((XdrvMailbox.index >= INPUT_NOT_USED) && (XdrvMailbox.index <= INPUT_USED)) { + uint8_t ctr_output = XdrvMailbox.index - 1; + if (XdrvMailbox.data_len > 0) { + Thermostat[ctr_output].status.use_input = (uint32_t)(XdrvMailbox.payload); + } + ResponseCmndNumber((int)Thermostat[ctr_output].status.use_input); + } +} + +void CmndSensorInputSet(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= THERMOSTAT_CONTROLLER_OUTPUTS)) { + uint8_t ctr_output = XdrvMailbox.index - 1; + if (XdrvMailbox.data_len > 0) { + uint8_t value = (uint8_t)(XdrvMailbox.payload); + if ((value >= SENSOR_MQTT) && (value < SENSOR_MAX)) { + Thermostat[ctr_output].status.sensor_type = value; + } + } + ResponseCmndNumber((int)Thermostat[ctr_output].status.sensor_type); + } +} + +void CmndOutputRelaySet(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= THERMOSTAT_CONTROLLER_OUTPUTS)) { + uint8_t ctr_output = XdrvMailbox.index - 1; + if (XdrvMailbox.data_len > 0) { + uint8_t value = (uint8_t)(XdrvMailbox.payload); + if (ThermostatRelayIdValid(value)) { + Thermostat[ctr_output].status.output_relay_number = value; + } + } + ResponseCmndNumber((int)Thermostat[ctr_output].status.output_relay_number); + } +} + +void CmndTimeAllowRampupSet(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= THERMOSTAT_CONTROLLER_OUTPUTS)) { + uint8_t ctr_output = XdrvMailbox.index - 1; + if (XdrvMailbox.data_len > 0) { + uint32_t value = (uint32_t)(XdrvMailbox.payload); + if ((value >= 0) && (value < 1440)) { + Thermostat[ctr_output].time_allow_rampup = (uint16_t)value; + } + } + ResponseCmndNumber((int)((uint32_t)Thermostat[ctr_output].time_allow_rampup)); + } +} + +void CmndTempFormatSet(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= THERMOSTAT_CONTROLLER_OUTPUTS)) { + uint8_t ctr_output = XdrvMailbox.index - 1; + if (XdrvMailbox.data_len > 0) { + uint8_t value = (uint8_t)(XdrvMailbox.payload); + if ((value >= 0) && (value <= TEMP_FAHRENHEIT)) { + Thermostat[ctr_output].status.temp_format = value; + } + } + ResponseCmndNumber((int)Thermostat[ctr_output].status.temp_format); + } +} + +void CmndTempMeasuredSet(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= THERMOSTAT_CONTROLLER_OUTPUTS)) { + uint8_t ctr_output = XdrvMailbox.index - 1; + int16_t value; + if (XdrvMailbox.data_len > 0) { + if (Thermostat[ctr_output].status.temp_format == TEMP_FAHRENHEIT) { + value = ThermostatFahrenheitToCelsius((int32_t)(CharToFloat(XdrvMailbox.data) * 10), TEMP_CONV_ABSOLUTE); + } + else { + value = (int16_t)(CharToFloat(XdrvMailbox.data) * 10); + } + if ( (value >= -1000) + && (value <= 1000) + && (Thermostat[ctr_output].status.sensor_type == SENSOR_MQTT)) { + uint32_t timestamp = uptime; + // Calculate temperature gradient if temperature value has changed + if (value != Thermostat[ctr_output].temp_measured) { + int32_t temp_delta = (value - Thermostat[ctr_output].temp_measured); // in tenths of degrees + uint32_t time_delta = (timestamp - Thermostat[ctr_output].timestamp_temp_meas_change_update); // in seconds + Thermostat[ctr_output].temp_measured_gradient = (int32_t)((360000 * temp_delta) / ((int32_t)time_delta)); // thousandths of degrees per hour + Thermostat[ctr_output].temp_measured = value; + Thermostat[ctr_output].timestamp_temp_meas_change_update = timestamp; + } + Thermostat[ctr_output].timestamp_temp_measured_update = timestamp; + Thermostat[ctr_output].status.sensor_alive = IFACE_ON; + } + } + if (Thermostat[ctr_output].status.temp_format == TEMP_FAHRENHEIT) { + value = ThermostatCelsiusToFahrenheit((int32_t)Thermostat[ctr_output].temp_measured, TEMP_CONV_ABSOLUTE); + } + else { + value = Thermostat[ctr_output].temp_measured; + } + ResponseCmndFloat((float)value / 10, 1); + } +} + +void CmndTempTargetSet(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= THERMOSTAT_CONTROLLER_OUTPUTS)) { + uint8_t ctr_output = XdrvMailbox.index - 1; + int16_t value; + if (XdrvMailbox.data_len > 0) { + if (Thermostat[ctr_output].status.temp_format == TEMP_FAHRENHEIT) { + value = ThermostatFahrenheitToCelsius((int32_t)(CharToFloat(XdrvMailbox.data) * 10), TEMP_CONV_ABSOLUTE); + } + else { + value = (int16_t)(CharToFloat(XdrvMailbox.data) * 10); + } + if ( (value >= -1000) + && (value <= 1000) + && (value >= (int16_t)Thermostat[ctr_output].temp_frost_protect)) { + Thermostat[ctr_output].temp_target_level = value; + } + } + if (Thermostat[ctr_output].status.temp_format == TEMP_FAHRENHEIT) { + value = ThermostatCelsiusToFahrenheit((int32_t)Thermostat[ctr_output].temp_target_level, TEMP_CONV_ABSOLUTE); + } + else { + value = Thermostat[ctr_output].temp_target_level; + } + ResponseCmndFloat((float)value / 10, 1); + } +} + +void CmndTempMeasuredGrdRead(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= THERMOSTAT_CONTROLLER_OUTPUTS)) { + uint8_t ctr_output = XdrvMailbox.index - 1; + int16_t value; + if (Thermostat[ctr_output].status.temp_format == TEMP_FAHRENHEIT) { + value = ThermostatCelsiusToFahrenheit((int32_t)Thermostat[ctr_output].temp_measured_gradient, TEMP_CONV_RELATIVE); + } + else { + value = Thermostat[ctr_output].temp_measured_gradient; + } + ResponseCmndFloat(((float)value) / 1000, 1); + } +} + +void CmndStateEmergencySet(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= THERMOSTAT_CONTROLLER_OUTPUTS)) { + uint8_t ctr_output = XdrvMailbox.index - 1; + if (XdrvMailbox.data_len > 0) { + uint8_t value = (uint8_t)(XdrvMailbox.payload); + if ((value >= 0) && (value <= 1)) { + Thermostat[ctr_output].diag.state_emergency = (uint16_t)value; + } + } + ResponseCmndNumber((int)Thermostat[ctr_output].diag.state_emergency); + } +} + +void CmndTimeManualToAutoSet(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= THERMOSTAT_CONTROLLER_OUTPUTS)) { + uint8_t ctr_output = XdrvMailbox.index - 1; + if (XdrvMailbox.data_len > 0) { + uint32_t value = (uint32_t)(XdrvMailbox.payload); + if ((value >= 0) && (value <= 1440)) { + Thermostat[ctr_output].time_manual_to_auto = (uint16_t)value; + } + } + ResponseCmndNumber((int)((uint32_t)Thermostat[ctr_output].time_manual_to_auto)); + } +} + +void CmndPropBandSet(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= THERMOSTAT_CONTROLLER_OUTPUTS)) { + uint8_t ctr_output = XdrvMailbox.index - 1; + if (XdrvMailbox.data_len > 0) { + uint8_t value = (uint8_t)(XdrvMailbox.payload); + if ((value >= 0) && (value <= 20)) { + Thermostat[ctr_output].val_prop_band = value; + } + } + ResponseCmndNumber((int)Thermostat[ctr_output].val_prop_band); + } +} + +void CmndTimeResetSet(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= THERMOSTAT_CONTROLLER_OUTPUTS)) { + uint8_t ctr_output = XdrvMailbox.index - 1; + if (XdrvMailbox.data_len > 0) { + uint32_t value = (uint32_t)(XdrvMailbox.payload); + if ((value >= 0) && (value <= 86400)) { + Thermostat[ctr_output].time_reset = value; + } + } + ResponseCmndNumber((int)Thermostat[ctr_output].time_reset); + } +} + +void CmndTimePiProportRead(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= THERMOSTAT_CONTROLLER_OUTPUTS)) { + uint8_t ctr_output = XdrvMailbox.index - 1; + ResponseCmndNumber((int)Thermostat[ctr_output].time_proportional_pi); + } +} + +void CmndTimePiIntegrRead(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= THERMOSTAT_CONTROLLER_OUTPUTS)) { + uint8_t ctr_output = XdrvMailbox.index - 1; + ResponseCmndNumber((int)Thermostat[ctr_output].time_integral_pi); + } +} + +void CmndTimePiCycleSet(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= THERMOSTAT_CONTROLLER_OUTPUTS)) { + uint8_t ctr_output = XdrvMailbox.index - 1; + if (XdrvMailbox.data_len > 0) { + uint32_t value = (uint32_t)(XdrvMailbox.payload); + if ((value >= 0) && (value <= 1440)) { + Thermostat[ctr_output].time_pi_cycle = (uint16_t)value; + } + } + ResponseCmndNumber((int)((uint32_t)Thermostat[ctr_output].time_pi_cycle)); + } +} + +void CmndTempAntiWindupResetSet(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= THERMOSTAT_CONTROLLER_OUTPUTS)) { + uint8_t ctr_output = XdrvMailbox.index - 1; + uint8_t value; + if (XdrvMailbox.data_len > 0) { + if (Thermostat[ctr_output].status.temp_format == TEMP_FAHRENHEIT) { + value = (uint8_t)ThermostatFahrenheitToCelsius((int32_t)(CharToFloat(XdrvMailbox.data) * 10), TEMP_CONV_RELATIVE); + } + else { + value = (uint8_t)(CharToFloat(XdrvMailbox.data) * 10); + } + if ( (value >= 0) + && (value <= 100)) { + Thermostat[ctr_output].temp_reset_anti_windup = value; + } + } + if (Thermostat[ctr_output].status.temp_format == TEMP_FAHRENHEIT) { + value = ThermostatCelsiusToFahrenheit((int32_t)Thermostat[ctr_output].temp_reset_anti_windup, TEMP_CONV_RELATIVE); + } + else { + value = Thermostat[ctr_output].temp_reset_anti_windup; + } + ResponseCmndFloat((float)value / 10, 1); + } +} + +void CmndTempHystSet(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= THERMOSTAT_CONTROLLER_OUTPUTS)) { + uint8_t ctr_output = XdrvMailbox.index - 1; + int8_t value; + if (XdrvMailbox.data_len > 0) { + if (Thermostat[ctr_output].status.temp_format == TEMP_FAHRENHEIT) { + value = (int8_t)ThermostatFahrenheitToCelsius((int32_t)(CharToFloat(XdrvMailbox.data) * 10), TEMP_CONV_RELATIVE); + } + else { + value = (int8_t)(CharToFloat(XdrvMailbox.data) * 10); + } + if ( (value >= -100) + && (value <= 100)) { + Thermostat[ctr_output].temp_hysteresis = value; + } + } + if (Thermostat[ctr_output].status.temp_format == TEMP_FAHRENHEIT) { + value = ThermostatCelsiusToFahrenheit((int32_t)Thermostat[ctr_output].temp_hysteresis, TEMP_CONV_RELATIVE); + } + else { + value = Thermostat[ctr_output].temp_hysteresis; + } + ResponseCmndFloat((float)value / 10, 1); + } +} + +#ifdef USE_PI_AUTOTUNING +void CmndPerfLevelAutotune(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= THERMOSTAT_CONTROLLER_OUTPUTS)) { + uint8_t ctr_output = XdrvMailbox.index - 1; + if (XdrvMailbox.data_len > 0) { + uint8_t value = (uint8_t)(XdrvMailbox.payload); + if ((value >= 0) && (value <= AUTOTUNE_PERF_MAX)) { + Thermostat[ctr_output].status.autotune_perf_mode = value; + } + } + ResponseCmndNumber((int)Thermostat[ctr_output].status.autotune_perf_mode); + } +} +#endif // USE_PI_AUTOTUNING + +void CmndTimeMaxActionSet(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= THERMOSTAT_CONTROLLER_OUTPUTS)) { + uint8_t ctr_output = XdrvMailbox.index - 1; + if (XdrvMailbox.data_len > 0) { + uint32_t value = (uint32_t)(XdrvMailbox.payload); + if ((value >= 0) && (value <= 1440)) { + Thermostat[ctr_output].time_max_action = (uint16_t)value; + } + } + ResponseCmndNumber((int)((uint32_t)Thermostat[ctr_output].time_max_action)); + } +} + +void CmndTimeMinActionSet(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= THERMOSTAT_CONTROLLER_OUTPUTS)) { + uint8_t ctr_output = XdrvMailbox.index - 1; + if (XdrvMailbox.data_len > 0) { + uint32_t value = (uint32_t)(XdrvMailbox.payload); + if ((value >= 0) && (value <= 1440)) { + Thermostat[ctr_output].time_min_action = (uint16_t)value; + } + } + ResponseCmndNumber((int)((uint32_t)Thermostat[ctr_output].time_min_action)); + } +} + +void CmndTimeSensLostSet(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= THERMOSTAT_CONTROLLER_OUTPUTS)) { + uint8_t ctr_output = XdrvMailbox.index - 1; + if (XdrvMailbox.data_len > 0) { + uint32_t value = (uint32_t)(XdrvMailbox.payload); + if ((value >= 0) && (value <= 1440)) { + Thermostat[ctr_output].time_sens_lost = (uint16_t)value; + } + } + ResponseCmndNumber((int)((uint32_t)Thermostat[ctr_output].time_sens_lost)); + } +} + +void CmndTimeMinTurnoffActionSet(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= THERMOSTAT_CONTROLLER_OUTPUTS)) { + uint8_t ctr_output = XdrvMailbox.index - 1; + if (XdrvMailbox.data_len > 0) { + uint32_t value = (uint32_t)(XdrvMailbox.payload); + if ((value >= 0) && (value <= 1440)) { + Thermostat[ctr_output].time_min_turnoff_action = (uint16_t)value; + } + } + ResponseCmndNumber((int)((uint32_t)Thermostat[ctr_output].time_min_turnoff_action)); + } +} + +void CmndTempRupDeltInSet(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= THERMOSTAT_CONTROLLER_OUTPUTS)) { + uint8_t ctr_output = XdrvMailbox.index - 1; + uint8_t value; + if (XdrvMailbox.data_len > 0) { + if (Thermostat[ctr_output].status.temp_format == TEMP_FAHRENHEIT) { + value = (uint8_t)ThermostatFahrenheitToCelsius((int32_t)(CharToFloat(XdrvMailbox.data) * 10), TEMP_CONV_RELATIVE); + } + else { + value = (uint8_t)(CharToFloat(XdrvMailbox.data) * 10); + } + if ( (value >= 0) + && (value <= 100)) { + Thermostat[ctr_output].temp_rampup_delta_in = value; + } + } + if (Thermostat[ctr_output].status.temp_format == TEMP_FAHRENHEIT) { + value = ThermostatCelsiusToFahrenheit((int32_t)Thermostat[ctr_output].temp_rampup_delta_in, TEMP_CONV_RELATIVE); + } + else { + value = Thermostat[ctr_output].temp_rampup_delta_in; + } + ResponseCmndFloat((float)value / 10, 1); + } +} + +void CmndTempRupDeltOutSet(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= THERMOSTAT_CONTROLLER_OUTPUTS)) { + uint8_t ctr_output = XdrvMailbox.index - 1; + uint8_t value; + if (XdrvMailbox.data_len > 0) { + if (Thermostat[ctr_output].status.temp_format == TEMP_FAHRENHEIT) { + value = (uint8_t)ThermostatFahrenheitToCelsius((int32_t)(CharToFloat(XdrvMailbox.data) * 10), TEMP_CONV_RELATIVE); + } + else { + value = (uint8_t)(CharToFloat(XdrvMailbox.data) * 10); + } + if ( (value >= 0) + && (value <= 100)) { + Thermostat[ctr_output].temp_rampup_delta_out = value; + } + } + if (Thermostat[ctr_output].status.temp_format == TEMP_FAHRENHEIT) { + value = ThermostatCelsiusToFahrenheit((int32_t)Thermostat[ctr_output].temp_rampup_delta_out, TEMP_CONV_RELATIVE); + } + else { + value = Thermostat[ctr_output].temp_rampup_delta_out; + } + ResponseCmndFloat((float)value / 10, 1); + } +} + +void CmndTimeRampupMaxSet(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= THERMOSTAT_CONTROLLER_OUTPUTS)) { + uint8_t ctr_output = XdrvMailbox.index - 1; + if (XdrvMailbox.data_len > 0) { + uint32_t value = (uint32_t)(XdrvMailbox.payload); + if ((value >= 0) && (value <= 1440)) { + Thermostat[ctr_output].time_rampup_max = (uint16_t)value; + } + } + ResponseCmndNumber((int)((uint32_t)Thermostat[ctr_output].time_rampup_max)); + } +} + +void CmndTimeRampupCycleSet(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= THERMOSTAT_CONTROLLER_OUTPUTS)) { + uint8_t ctr_output = XdrvMailbox.index - 1; + if (XdrvMailbox.data_len > 0) { + uint32_t value = (uint32_t)(XdrvMailbox.payload); + if ((value >= 0) && (value <= 1440)) { + Thermostat[ctr_output].time_rampup_cycle = (uint16_t)value; + } + } + ResponseCmndNumber((int)Thermostat[ctr_output].time_rampup_cycle); + } +} + +void CmndTempRampupPiAccErrSet(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= THERMOSTAT_CONTROLLER_OUTPUTS)) { + uint8_t ctr_output = XdrvMailbox.index - 1; + uint16_t value; + if (XdrvMailbox.data_len > 0) { + if (Thermostat[ctr_output].status.temp_format == TEMP_FAHRENHEIT) { + value = (uint16_t)ThermostatFahrenheitToCelsius((int32_t)(CharToFloat(XdrvMailbox.data) * 100), TEMP_CONV_RELATIVE); + } + else { + value = (uint16_t)(CharToFloat(XdrvMailbox.data) * 100); + } + if ( (value >= 0) + && (value <= 2500)) { + Thermostat[ctr_output].temp_rampup_pi_acc_error = value; + } + } + if (Thermostat[ctr_output].status.temp_format == TEMP_FAHRENHEIT) { + value = ThermostatCelsiusToFahrenheit((int32_t)Thermostat[ctr_output].temp_rampup_pi_acc_error, TEMP_CONV_RELATIVE); + } + else { + value = Thermostat[ctr_output].temp_rampup_pi_acc_error; + } + ResponseCmndFloat((float)value / 100, 1); + } +} + +void CmndDiagnosticModeSet(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= THERMOSTAT_CONTROLLER_OUTPUTS)) { + uint8_t ctr_output = XdrvMailbox.index - 1; + if (XdrvMailbox.data_len > 0) { + uint8_t value = (uint8_t)(CharToFloat(XdrvMailbox.data)); + if ((value >= DIAGNOSTIC_OFF) && (value <= DIAGNOSTIC_ON)) { + Thermostat[ctr_output].diag.diagnostic_mode = value; + } + } + ResponseCmndNumber((int)Thermostat[ctr_output].diag.diagnostic_mode); + } +} + +void CmndCtrDutyCycleRead(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= THERMOSTAT_CONTROLLER_OUTPUTS)) { + uint8_t ctr_output = XdrvMailbox.index - 1; + uint8_t value = 0; + if ( (Thermostat[ctr_output].status.controller_mode == CTR_PI) + || ((Thermostat[ctr_output].status.controller_mode == CTR_HYBRID) + &&(Thermostat[ctr_output].status.phase_hybrid_ctr == CTR_HYBRID_PI))) { + value = Thermostat[ctr_output].time_total_pi / Thermostat[ctr_output].time_pi_cycle; + } + else if ( (Thermostat[ctr_output].status.controller_mode == CTR_RAMP_UP) + || ((Thermostat[ctr_output].status.controller_mode == CTR_HYBRID) + &&(Thermostat[ctr_output].status.phase_hybrid_ctr == CTR_HYBRID_RAMP_UP))) { + if (Thermostat[ctr_output].status.status_output == IFACE_ON) { + value = 100; + } + else { + value = 0; + } + } + ResponseCmndNumber((int)value); + } +} + +void CmndEnableOutputSet(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= THERMOSTAT_CONTROLLER_OUTPUTS)) { + uint8_t ctr_output = XdrvMailbox.index - 1; + if (XdrvMailbox.data_len > 0) { + uint8_t value = (uint8_t)(CharToFloat(XdrvMailbox.data)); + if ((value >= IFACE_OFF) && (value <= IFACE_ON)) { + Thermostat[ctr_output].status.enable_output = value; + } + } + ResponseCmndNumber((int)Thermostat[ctr_output].status.enable_output); + } +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xdrv39(uint8_t function) +{ + bool result = false; + uint8_t ctr_output; + + switch (function) { + case FUNC_INIT: + for (ctr_output = 0; ctr_output < THERMOSTAT_CONTROLLER_OUTPUTS; ctr_output++) { + ThermostatInit(ctr_output); + } + break; + case FUNC_LOOP: + for (ctr_output = 0; ctr_output < THERMOSTAT_CONTROLLER_OUTPUTS; ctr_output++) { + if (Thermostat[ctr_output].status.thermostat_mode != THERMOSTAT_OFF) { + ThermostatSignalProcessingFast(ctr_output); + ThermostatDiagnostics(ctr_output); + } + } + break; + case FUNC_SERIAL: + break; + case FUNC_EVERY_SECOND: + for (ctr_output = 0; ctr_output < THERMOSTAT_CONTROLLER_OUTPUTS; ctr_output++) { + if ((ThermostatMinuteCounter(ctr_output)) + && (Thermostat[ctr_output].status.thermostat_mode != THERMOSTAT_OFF)) { + ThermostatSignalPreProcessingSlow(ctr_output); + ThermostatController(ctr_output); + ThermostatSignalPostProcessingSlow(ctr_output); +#ifdef DEBUG_THERMOSTAT + ThermostatDebug(ctr_output); +#endif // DEBUG_THERMOSTAT + } + } + break; + case FUNC_SHOW_SENSOR: + for (ctr_output = 0; ctr_output < THERMOSTAT_CONTROLLER_OUTPUTS; ctr_output++) { + if (Thermostat[ctr_output].status.thermostat_mode != THERMOSTAT_OFF) { + ThermostatGetLocalSensor(ctr_output); + } + } + break; + case FUNC_COMMAND: + result = DecodeCommand(kThermostatCommands, ThermostatCommand); + break; + } + return result; +} + +#endif // USE_THERMOSTAT diff --git a/tasmota/xdrv_40_telegram.ino b/tasmota/xdrv_40_telegram.ino new file mode 100644 index 000000000..a7beb5005 --- /dev/null +++ b/tasmota/xdrv_40_telegram.ino @@ -0,0 +1,470 @@ +/* + xdrv_40_telegram.ino - telegram for Tasmota + + Copyright (C) 2020 Theo Arends + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifdef USE_TELEGRAM +/*********************************************************************************************\ + * Telegram bot + * + * Supported commands: + * TmToken - Add your BotFather created bot token (default none) + * TmChatId - Add your BotFather created bot chat id (default none) + * TmPoll - Telegram receive poll time (default 10 seconds) + * TmState 0 - Disable telegram sending (default) + * TmState 1 - Enable telegram sending + * TmState 2 - Disable telegram listener (default) + * TmState 3 - Enable telegram listener + * TmState 4 - Disable telegram response echo (default) + * TmState 5 - Enable telegram response echo + * TmSend - If telegram sending is enabled AND a chat id is present then send data + * + * Tested with defines + * #define USE_TELEGRAM // Support for Telegram protocol + * #define USE_TELEGRAM_FINGERPRINT "\xB2\x72\x47\xA6\x69\x8C\x3C\x69\xF9\x58\x6C\xF3\x60\x02\xFB\x83\xFA\x8B\x1F\x23" // Telegram api.telegram.org TLS public key fingerpring +\*********************************************************************************************/ + +#define XDRV_40 40 + +#define TELEGRAM_SEND_RETRY 4 // Retries +#define TELEGRAM_LOOP_WAIT 10 // Seconds + +#ifdef USE_MQTT_TLS_CA_CERT + static const uint32_t tls_rx_size = 2048; // since Telegram CA is bigger than 1024 bytes, we need to increase rx buffer + static const uint32_t tls_tx_size = 1024; +#else + static const uint32_t tls_rx_size = 1024; + static const uint32_t tls_tx_size = 1024; +#endif + +#include "WiFiClientSecureLightBearSSL.h" +BearSSL::WiFiClientSecure_light *telegramClient = nullptr; + +static const uint8_t Telegram_Fingerprint[] PROGMEM = USE_TELEGRAM_FINGERPRINT; + +struct { + String message[3][6]; // amount of messages read per time (update_id, name_id, name, lastname, chat_id, text) + uint8_t state = 0; + uint8_t index = 0; + uint8_t retry = 0; + uint8_t poll = TELEGRAM_LOOP_WAIT; + uint8_t wait = 0; + bool send_enable = false; + bool recv_enable = false; + bool echo_enable = false; + bool recv_busy = false; +} Telegram; + +bool TelegramInit(void) { + bool init_done = false; + if (strlen(SettingsText(SET_TELEGRAM_TOKEN))) { + if (!telegramClient) { + telegramClient = new BearSSL::WiFiClientSecure_light(tls_rx_size, tls_tx_size); +#ifdef USE_MQTT_TLS_CA_CERT + telegramClient->setTrustAnchor(&GoDaddyCAG2_TA); +#else + telegramClient->setPubKeyFingerprint(Telegram_Fingerprint, Telegram_Fingerprint, false); // check server fingerprint +#endif + + Telegram.message[0][0]="0"; // Number of received messages + Telegram.message[1][0]=""; + Telegram.message[0][1]="0"; // Code of last read Message + + AddLog_P2(LOG_LEVEL_INFO, PSTR("TGM: Started")); + } + + init_done = true; + } + return init_done; +} + +String TelegramConnectToTelegram(String command) { +// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: Cmnd %s"), command.c_str()); + + if (!TelegramInit()) { return ""; } + + String response = ""; + uint32_t tls_connect_time = millis(); + + if (telegramClient->connect("api.telegram.org", 443)) { +// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: Connected in %d ms, max ThunkStack used %d"), millis() - tls_connect_time, telegramClient->getMaxThunkStackUse()); + + telegramClient->println("GET /"+command); + + String a = ""; + char c; + int ch_count=0; + uint32_t now = millis(); + bool avail = false; + while (millis() -now < 1500) { + while (telegramClient->available()) { + char c = telegramClient->read(); + if (ch_count < 700) { + response = response + c; + ch_count++; + } + avail = true; + } + if (avail) { + break; + } + } + + telegramClient->stop(); + } + + return response; +} + +void TelegramGetUpdates(String offset) { + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("TGM: getUpdates")); + + if (!TelegramInit()) { return; } + + String _token = SettingsText(SET_TELEGRAM_TOKEN); + String command = "bot" + _token + "/getUpdates?offset=" + offset; + String response = TelegramConnectToTelegram(command); //recieve reply from telegram.org + + // {"ok":true,"result":[]} + // or + // {"ok":true,"result":[ + // {"update_id":973125394, + // "message":{"message_id":25, + // "from":{"id":139920293,"is_bot":false,"first_name":"Theo","last_name":"Arends","username":"tjatja","language_code":"nl"}, + // "chat":{"id":139920293,"first_name":"Theo","last_name":"Arends","username":"tjatja","type":"private"}, + // "date":1591877503, + // "text":"M1" + // } + // }, + // {"update_id":973125395, + // "message":{"message_id":26, + // "from":{"id":139920293,"is_bot":false,"first_name":"Theo","last_name":"Arends","username":"tjatja","language_code":"nl"}, + // "chat":{"id":139920293,"first_name":"Theo","last_name":"Arends","username":"tjatja","type":"private"}, + // "date":1591877508, + // "text":"M2" + // } + // } + // ]} + // or + // {"ok":true,"result":[ + // {"update_id":973125396, + // "message":{"message_id":29, + // "from":{"id":139920293,"is_bot":false,"first_name":"Theo","last_name":"Arends","username":"tjatja","language_code":"nl"}, + // "chat":{"id":139920293,"first_name":"Theo","last_name":"Arends","username":"tjatja","type":"private"}, + // "date":1591879753, + // "text":"/power toggle", + // "entities":[{"offset":0,"length":6,"type":"bot_command"}] + // } + // } + // ]} + +// AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("TGM: Response %s"), response.c_str()); + + // parsing of reply from Telegram into separate received messages + int i = 0; //messages received counter + if (response != "") { + +// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: Sent Update request messages up to %s"), offset.c_str()); + + String a = ""; + int ch_count = 0; + String c; + for (uint32_t n = 1; n < response.length() +1; n++) { //Search for each message start + ch_count++; + c = response.substring(n -1, n); + a = a + c; + if (ch_count > 8) { + if (a.substring(ch_count -9) == "update_id") { + if (i > 1) { break; } + Telegram.message[i][0] = a.substring(0, ch_count -11); + a = a.substring(ch_count-11); + i++; + ch_count = 11; + } + } + } + if (1 == i) { + Telegram.message[i][0] = a.substring(0, ch_count); //Assign of parsed message into message matrix if only 1 message) + } + if (i > 1) { i = i -1; } + } + //check result of parsing process + if (response == "") { +// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: Failed to update")); + return; + } + if (0 == i) { +// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: No new messages")); + Telegram.message[0][0] = "0"; + } else { + Telegram.message[0][0] = String(i); //returns how many messages are in the array + for (int b = 1; b < i+1; b++) { +// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: Msg %d %s"), b, Telegram.message[b][0].c_str()); + } + + TelegramAnalizeMessage(); + } +} + +void TelegramAnalizeMessage(void) { + for (uint32_t i = 1; i < Telegram.message[0][0].toInt() +1; i++) { + Telegram.message[i][5] = ""; + + DynamicJsonBuffer jsonBuffer; + JsonObject &root = jsonBuffer.parseObject(Telegram.message[i][0]); + if (root.success()) { + Telegram.message[i][0] = root["update_id"].as(); + Telegram.message[i][1] = root["message"]["from"]["id"].as(); + Telegram.message[i][2] = root["message"]["from"]["first_name"].as(); + Telegram.message[i][3] = root["message"]["from"]["last_name"].as(); + Telegram.message[i][4] = root["message"]["chat"]["id"].as(); + Telegram.message[i][5] = root["message"]["text"].as(); + } + + int id = Telegram.message[Telegram.message[0][0].toInt()][0].toInt() +1; + Telegram.message[0][1] = id; // Write id of last read message + + for (int j = 0; j < 6; j++) { +// AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("TGM: Parsed%d \"%s\""), j, Telegram.message[i][j].c_str()); + } + } +} + +bool TelegramSendMessage(String chat_id, String text) { + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("TGM: sendMessage")); + + if (!TelegramInit()) { return false; } + + bool sent = false; + if (text != "") { + String _token = SettingsText(SET_TELEGRAM_TOKEN); + String command = "bot" + _token + "/sendMessage?chat_id=" + chat_id + "&text=" + text; + String response = TelegramConnectToTelegram(command); + +// AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("TGM: Response %s"), response.c_str()); + + if (response.startsWith("{\"ok\":true")) { +// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TGM: Message sent")); + sent = true; + } + + } + + return sent; +} + +/* +void TelegramSendGetMe(void) { + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("TGM: getMe")); + + if (!TelegramInit()) { return; } + + String _token = SettingsText(SET_TELEGRAM_TOKEN); + String command = "bot" + _token + "/getMe"; + String response = TelegramConnectToTelegram(command); + + // {"ok":true,"result":{"id":1179906608,"is_bot":true,"first_name":"Tasmota","username":"tasmota_bot","can_join_groups":true,"can_read_all_group_messages":false,"supports_inline_queries":false}} + +// AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("TGM: Response %s"), response.c_str()); +} +*/ + +String TelegramExecuteCommand(const char *svalue) { + String response = ""; + + uint32_t curridx = web_log_index; + ExecuteCommand(svalue, SRC_CHAT); + if (web_log_index != curridx) { + uint32_t counter = curridx; + response = F("{"); + bool cflg = false; + do { + char* tmp; + size_t len; + GetLog(counter, &tmp, &len); + if (len) { + // [14:49:36 MQTT: stat/wemos5/RESULT = {"POWER":"OFF"}] > [{"POWER":"OFF"}] + char* JSON = (char*)memchr(tmp, '{', len); + if (JSON) { // Is it a JSON message (and not only [15:26:08 MQT: stat/wemos5/POWER = O]) + size_t JSONlen = len - (JSON - tmp); + if (JSONlen > sizeof(mqtt_data)) { JSONlen = sizeof(mqtt_data); } + char stemp[JSONlen]; + strlcpy(stemp, JSON +1, JSONlen -2); + if (cflg) { response += F(","); } + response += stemp; + cflg = true; + } + } + counter++; + counter &= 0xFF; + if (!counter) counter++; // Skip 0 as it is not allowed + } while (counter != web_log_index); + response += F("}"); + } else { + response = F("{\"" D_RSLT_WARNING "\":\"" D_ENABLE_WEBLOG_FOR_RESPONSE "\"}"); + } + + return response; +} + +void TelegramLoop(void) { + if (!global_state.network_down && (Telegram.recv_enable || Telegram.echo_enable)) { + switch (Telegram.state) { + case 0: + TelegramInit(); + Telegram.state++; + break; + case 1: + TelegramGetUpdates(Telegram.message[0][1]); // launch API GetUpdates up to xxx message + Telegram.index = 1; + Telegram.retry = TELEGRAM_SEND_RETRY; + Telegram.state++; + break; + case 2: + if (Telegram.echo_enable) { + if (Telegram.retry && (Telegram.index < Telegram.message[0][0].toInt() + 1)) { + if (TelegramSendMessage(Telegram.message[Telegram.index][4], Telegram.message[Telegram.index][5])) { + Telegram.index++; + Telegram.retry = TELEGRAM_SEND_RETRY; + } else { + Telegram.retry--; + } + } else { + Telegram.message[0][0] = ""; // All messages have been replied - reset new messages + Telegram.wait = Telegram.poll; + Telegram.state++; + } + } else { + if (Telegram.message[0][0].toInt() && (Telegram.message[Telegram.index][5].length() > 0)) { + String logging = TelegramExecuteCommand(Telegram.message[Telegram.index][5].c_str()); + if (logging.length() > 0) { + TelegramSendMessage(Telegram.message[Telegram.index][4], logging); + } + } + Telegram.message[0][0] = ""; // All messages have been replied - reset new messages + Telegram.wait = Telegram.poll; + Telegram.state++; + } + break; + case 3: + if (Telegram.wait) { + Telegram.wait--; + } else { + Telegram.state = 1; + } + } + } +} + +/*********************************************************************************************\ + * Commands +\*********************************************************************************************/ + +#define D_CMND_TMSTATE "State" +#define D_CMND_TMPOLL "Poll" +#define D_CMND_TMSEND "Send" +#define D_CMND_TMTOKEN "Token" +#define D_CMND_TMCHATID "ChatId" + +const char kTelegramCommands[] PROGMEM = "Tm|" // Prefix + D_CMND_TMSTATE "|" D_CMND_TMPOLL "|" D_CMND_TMTOKEN "|" D_CMND_TMCHATID "|" D_CMND_TMSEND; + +void (* const TelegramCommand[])(void) PROGMEM = { + &CmndTmState, &CmndTmPoll, &CmndTmToken, &CmndTmChatId, &CmndTmSend }; + +void CmndTmState(void) { + if (XdrvMailbox.data_len > 0) { + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 6)) { + switch (XdrvMailbox.payload) { + case 0: // Off + case 1: // On + Telegram.send_enable = XdrvMailbox.payload &1; + break; + case 2: // Off + case 3: // On + Telegram.recv_enable = XdrvMailbox.payload &1; + break; + case 4: // Off + case 5: // On + Telegram.echo_enable = XdrvMailbox.payload &1; + break; + } + } + } + snprintf_P (mqtt_data, sizeof(mqtt_data), PSTR("{\"%s\":{\"Send\":\"%s\",\"Receive\":\"%s\",\"Echo\":\"%s\"}}"), + XdrvMailbox.command, GetStateText(Telegram.send_enable), GetStateText(Telegram.recv_enable), GetStateText(Telegram.echo_enable)); +} + +void CmndTmPoll(void) { + if ((XdrvMailbox.payload >= 4) && (XdrvMailbox.payload <= 300)) { + Telegram.poll = XdrvMailbox.payload; + if (Telegram.poll < Telegram.wait) { + Telegram.wait = Telegram.poll; + } + } + ResponseCmndNumber(Telegram.poll); +} + +void CmndTmToken(void) { + if (XdrvMailbox.data_len > 0) { + SettingsUpdateText(SET_TELEGRAM_TOKEN, ('"' == XdrvMailbox.data[0]) ? "" : XdrvMailbox.data); + } + ResponseCmndChar(SettingsText(SET_TELEGRAM_TOKEN)); +} + +void CmndTmChatId(void) { + if (XdrvMailbox.data_len > 0) { + SettingsUpdateText(SET_TELEGRAM_CHATID, ('"' == XdrvMailbox.data[0]) ? "" : XdrvMailbox.data); + } + ResponseCmndChar(SettingsText(SET_TELEGRAM_CHATID)); +} + +void CmndTmSend(void) { + if (!Telegram.send_enable || !strlen(SettingsText(SET_TELEGRAM_CHATID))) { + ResponseCmndChar(D_JSON_FAILED); + return; + } + if (XdrvMailbox.data_len > 0) { + String message = XdrvMailbox.data; + String chat_id = SettingsText(SET_TELEGRAM_CHATID); + if (!TelegramSendMessage(chat_id, message)) { + ResponseCmndChar(D_JSON_FAILED); + return; + } + } + ResponseCmndDone(); +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xdrv40(uint8_t function) +{ + bool result = false; + + switch (function) { + case FUNC_EVERY_SECOND: + TelegramLoop(); + break; + case FUNC_COMMAND: + result = DecodeCommand(kTelegramCommands, TelegramCommand); + break; + } + return result; +} +#endif // USE_TELEGRAM diff --git a/tasmota/xdrv_41_tcp_bridge.ino b/tasmota/xdrv_41_tcp_bridge.ino new file mode 100644 index 000000000..a6513ec46 --- /dev/null +++ b/tasmota/xdrv_41_tcp_bridge.ino @@ -0,0 +1,205 @@ +/* + xdrv_41_tcp_bridge.ino - TCP to serial bridge + + Copyright (C) 2020 Theo Arends and Stephan Hadinger + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifdef USE_TCP_BRIDGE + +#define XDRV_41 41 + +#ifndef TCP_BRIDGE_CONNECTIONS +#define TCP_BRIDGE_CONNECTIONS 2 // number of maximum parallel connections +#endif + +#ifndef TCP_BRIDGE_BUF_SIZE +#define TCP_BRIDGE_BUF_SIZE 255 // size of the buffer, above 132 required for efficient XMODEM +#endif + +//const uint16_t tcp_port = 8880; +WiFiServer *server_tcp = nullptr; +//WiFiClient client_tcp1, client_tcp2; +WiFiClient client_tcp[TCP_BRIDGE_CONNECTIONS]; +uint8_t client_next = 0; +uint8_t *tcp_buf = nullptr; // data transfer buffer + +#include +TasmotaSerial *TCPSerial = nullptr; + +const char kTCPCommands[] PROGMEM = "TCP" "|" // prefix + "Start" "|" "Baudrate" + ; + +void (* const TCPCommand[])(void) PROGMEM = { + &CmndTCPStart, &CmndTCPBaudrate + }; + +// +// Called at event loop, checks for incoming data from the CC2530 +// +void TCPLoop(void) +{ + uint8_t c; + bool busy; // did we transfer some data? + int32_t buf_len; + + if (!TCPSerial) return; + + // check for a new client connection + if ((server_tcp) && (server_tcp->hasClient())) { + // find an empty slot + uint32_t i; + for (i=0; iavailable(); + break; + } + } + if (i >= ARRAY_SIZE(client_tcp)) { + i = client_next++ % ARRAY_SIZE(client_tcp); + WiFiClient &client = client_tcp[i]; + client.stop(); + client = server_tcp->available(); + } + } + + do { + busy = false; // exit loop if no data was transferred + + // start reading the UART, this buffer can quickly overflow + buf_len = 0; + while ((buf_len < TCP_BRIDGE_BUF_SIZE) && (TCPSerial->available())) { + c = TCPSerial->read(); + if (c >= 0) { + tcp_buf[buf_len++] = c; + busy = true; + } + } + if (buf_len > 0) { + char hex_char[TCP_BRIDGE_BUF_SIZE+1]; + ToHex_P(tcp_buf, buf_len, hex_char, 256); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_TCP "from MCU: %s"), hex_char); + + for (uint32_t i=0; i= 0) { + tcp_buf[buf_len++] = c; + busy = true; + } + } + if (buf_len > 0) { + char hex_char[TCP_BRIDGE_BUF_SIZE+1]; + ToHex_P(tcp_buf, buf_len, hex_char, 256); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_TCP "to MCU/%d: %s"), i+1, hex_char); + TCPSerial->write(tcp_buf, buf_len); + } + } + + yield(); // avoid WDT if heavy traffic + } while (busy); +} + +/********************************************************************************************/ +void TCPInit(void) { + if (PinUsed(GPIO_TCP_RX) && PinUsed(GPIO_TCP_TX)) { + tcp_buf = (uint8_t*) malloc(TCP_BRIDGE_BUF_SIZE); + if (!tcp_buf) { AddLog_P2(LOG_LEVEL_ERROR, PSTR(D_LOG_TCP "could not allocate buffer")); return; } + + if (!Settings.tcp_baudrate) { Settings.tcp_baudrate = 115200 / 1200; } + TCPSerial = new TasmotaSerial(Pin(GPIO_TCP_RX), Pin(GPIO_TCP_TX), seriallog_level ? 1 : 2, 0, TCP_BRIDGE_BUF_SIZE); // set a receive buffer of 256 bytes + TCPSerial->begin(Settings.tcp_baudrate * 1200); + if (TCPSerial->hardwareSerial()) { + ClaimSerial(); + } + } +} + +/*********************************************************************************************\ + * Commands +\*********************************************************************************************/ + +// +// Command `ZbConfig` +// +void CmndTCPStart(void) { + + if (!TCPSerial) { return; } + int32_t tcp_port = XdrvMailbox.payload; + + if (server_tcp) { + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_TCP "Stopping TCP server")); + server_tcp->stop(); + delete server_tcp; + server_tcp = nullptr; + + for (uint32_t i=0; i 0) { + AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_TCP "Starting TCP server on port %d"), tcp_port); + server_tcp = new WiFiServer(tcp_port); + server_tcp->begin(); // start TCP server + server_tcp->setNoDelay(true); + } + + ResponseCmndDone(); +} + +void CmndTCPBaudrate(void) { + if ((XdrvMailbox.payload >= 1200) && (XdrvMailbox.payload <= 115200)) { + XdrvMailbox.payload /= 1200; // Make it a valid baudrate + Settings.tcp_baudrate = XdrvMailbox.payload; + TCPSerial->begin(Settings.tcp_baudrate * 1200); // Reinitialize serial port with new baud rate + } + ResponseCmndNumber(Settings.tcp_baudrate * 1200); +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xdrv41(uint8_t function) +{ + bool result = false; + + switch (function) { + case FUNC_LOOP: + TCPLoop(); + break; + case FUNC_PRE_INIT: + TCPInit(); + break; + case FUNC_COMMAND: + result = DecodeCommand(kTCPCommands, TCPCommand); + break; + } + return result; +} + +#endif // USE_TCP_BRIDGE diff --git a/tasmota/xdrv_81_webcam.ino b/tasmota/xdrv_81_webcam.ino new file mode 100644 index 000000000..b0dab47b7 --- /dev/null +++ b/tasmota/xdrv_81_webcam.ino @@ -0,0 +1,988 @@ +/* + xdrv_81_webcam.ino - ESP32 webcam support for Tasmota + + Copyright (C) 2020 Gerhard Mutz and Theo Arends + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifdef ESP32 +#ifdef USE_WEBCAM +/*********************************************************************************************\ + * ESP32 webcam based on example in Arduino-ESP32 library + * + * Template as used on ESP32-CAM WiFi + bluetooth Camera Module Development Board ESP32 With Camera Module OV2640 Geekcreit for Arduino + * {"NAME":"AITHINKER CAM","GPIO":[4992,1,1,1,1,5088,1,1,1,1,1,1,1,1,5089,5090,0,5091,5184,5152,0,5120,5024,5056,0,0,0,0,4928,1,5094,5095,5092,0,0,5093],"FLAG":0,"BASE":1} + * + * Supported commands: + * WcStream = Control streaming, 0 = stop, 1 = start + * WcResolution = Set resolution + * 0 = FRAMESIZE_96x96, (96x96) + * 1 = FRAMESIZE_QQVGA2 (128x160) + * 2 = FRAMESIZE_QCIF (176x144) + * 3 = FRAMESIZE_HQVGA (240x176) + * 4 = FRAMESIZE_QVGA (320x240) + * 5 = FRAMESIZE_CIF (400x296) + * 6 = FRAMESIZE_VGA (640x480) + * 7 = FRAMESIZE_SVGA (800x600) + * 8 = FRAMESIZE_XGA (1024x768) + * 9 = FRAMESIZE_SXGA (1280x1024) + * 10 = FRAMESIZE_UXGA (1600x1200) + * WcMirror = Mirror picture, 0 = no, 1 = yes + * WcFlip = Flip picture, 0 = no, 1 = yes + * WcSaturation = Set picture Saturation -2 ... +2 + * WcBrightness = Set picture Brightness -2 ... +2 + * WcContrast = Set picture Contrast -2 ... +2 + * + * Only boards with PSRAM should be used. To enable PSRAM board should be se set to esp32cam in common32 of platform_override.ini + * board = esp32cam + * To speed up cam processing cpu frequency should be better set to 240Mhz in common32 of platform_override.ini + * board_build.f_cpu = 240000000L + * remarks for AI-THINKER + * GPIO0 zero must be disconnected from any wire after programming because this pin drives the cam clock and does + * not tolerate any capictive load + * flash led = gpio 4 + * red led = gpio 33 + */ + +/*********************************************************************************************/ + +#define XDRV_81 81 + +#include "esp_camera.h" +#include "sensor.h" +#include "fb_gfx.h" +#include "fd_forward.h" +#include "fr_forward.h" + +bool HttpCheckPriviledgedAccess(bool); +extern ESP8266WebServer *Webserver; + +ESP8266WebServer *CamServer; +#define BOUNDARY "e8b8c539-047d-4777-a985-fbba6edff11e" + +WiFiClient client; + + +// CAMERA_MODEL_AI_THINKER default template pins +#define PWDN_GPIO_NUM 32 +#define RESET_GPIO_NUM -1 +#define XCLK_GPIO_NUM 0 +#define SIOD_GPIO_NUM 26 +#define SIOC_GPIO_NUM 27 + +#define Y9_GPIO_NUM 35 +#define Y8_GPIO_NUM 34 +#define Y7_GPIO_NUM 39 +#define Y6_GPIO_NUM 36 +#define Y5_GPIO_NUM 21 +#define Y4_GPIO_NUM 19 +#define Y3_GPIO_NUM 18 +#define Y2_GPIO_NUM 5 +#define VSYNC_GPIO_NUM 25 +#define HREF_GPIO_NUM 23 +#define PCLK_GPIO_NUM 22 + +struct { + uint8_t up; + uint16_t width; + uint16_t height; + uint8_t stream_active; +#ifdef USE_FACE_DETECT + uint8_t faces; + uint16_t face_detect_time; +#endif +} Wc; + +/*********************************************************************************************/ + +bool WcPinUsed(void) { + bool pin_used = true; + for (uint32_t i = 0; i < MAX_WEBCAM_DATA; i++) { + if (!PinUsed(GPIO_WEBCAM_DATA, i)) { + pin_used = false; + } +// if (i < MAX_WEBCAM_HSD) { +// if (!PinUsed(GPIO_WEBCAM_HSD, i)) { +// pin_used = false; +// } +// } + } + if (!PinUsed(GPIO_WEBCAM_XCLK) || !PinUsed(GPIO_WEBCAM_PCLK) || + !PinUsed(GPIO_WEBCAM_VSYNC) || !PinUsed(GPIO_WEBCAM_HREF) || + !PinUsed(GPIO_WEBCAM_SIOD) || !PinUsed(GPIO_WEBCAM_SIOC)) { + pin_used = false; + } + return pin_used; +} + +uint32_t WcSetup(int32_t fsiz) { + if (fsiz > 10) { fsiz = 10; } + + Wc.stream_active = 0; + + if (fsiz < 0) { + esp_camera_deinit(); + Wc.up = 0; + return 0; + } + + if (Wc.up) { + esp_camera_deinit(); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: Deinit")); + //return Wc.up; + } + Wc.up = 0; + +//esp_log_level_set("*", ESP_LOG_VERBOSE); + + camera_config_t config; + config.ledc_channel = LEDC_CHANNEL_0; + config.ledc_timer = LEDC_TIMER_0; + config.xclk_freq_hz = 20000000; + config.pixel_format = PIXFORMAT_JPEG; +// config.pixel_format = PIXFORMAT_GRAYSCALE; +// config.pixel_format = PIXFORMAT_RGB565; + + if (WcPinUsed()) { + config.pin_d0 = Pin(GPIO_WEBCAM_DATA); // Y2_GPIO_NUM; + config.pin_d1 = Pin(GPIO_WEBCAM_DATA, 1); // Y3_GPIO_NUM; + config.pin_d2 = Pin(GPIO_WEBCAM_DATA, 2); // Y4_GPIO_NUM; + config.pin_d3 = Pin(GPIO_WEBCAM_DATA, 3); // Y5_GPIO_NUM; + config.pin_d4 = Pin(GPIO_WEBCAM_DATA, 4); // Y6_GPIO_NUM; + config.pin_d5 = Pin(GPIO_WEBCAM_DATA, 5); // Y7_GPIO_NUM; + config.pin_d6 = Pin(GPIO_WEBCAM_DATA, 6); // Y8_GPIO_NUM; + config.pin_d7 = Pin(GPIO_WEBCAM_DATA, 7); // Y9_GPIO_NUM; + config.pin_xclk = Pin(GPIO_WEBCAM_XCLK); // XCLK_GPIO_NUM; + config.pin_pclk = Pin(GPIO_WEBCAM_PCLK); // PCLK_GPIO_NUM; + config.pin_vsync = Pin(GPIO_WEBCAM_VSYNC); // VSYNC_GPIO_NUM; + config.pin_href = Pin(GPIO_WEBCAM_HREF); // HREF_GPIO_NUM; + config.pin_sscb_sda = Pin(GPIO_WEBCAM_SIOD); // SIOD_GPIO_NUM; + config.pin_sscb_scl = Pin(GPIO_WEBCAM_SIOC); // SIOC_GPIO_NUM; + config.pin_pwdn = (PinUsed(GPIO_WEBCAM_PWDN)) ? Pin(GPIO_WEBCAM_PWDN) : -1; // PWDN_GPIO_NUM; + config.pin_reset = (PinUsed(GPIO_WEBCAM_RESET)) ? Pin(GPIO_WEBCAM_RESET) : -1; // RESET_GPIO_NUM; + + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: User template")); + } else { + // defaults to AI THINKER + config.pin_d0 = Y2_GPIO_NUM; + config.pin_d1 = Y3_GPIO_NUM; + config.pin_d2 = Y4_GPIO_NUM; + config.pin_d3 = Y5_GPIO_NUM; + config.pin_d4 = Y6_GPIO_NUM; + config.pin_d5 = Y7_GPIO_NUM; + config.pin_d6 = Y8_GPIO_NUM; + config.pin_d7 = Y9_GPIO_NUM; + config.pin_xclk = XCLK_GPIO_NUM; + config.pin_pclk = PCLK_GPIO_NUM; + config.pin_vsync = VSYNC_GPIO_NUM; + config.pin_href = HREF_GPIO_NUM; + config.pin_sscb_sda = SIOD_GPIO_NUM; + config.pin_sscb_scl = SIOC_GPIO_NUM; + config.pin_pwdn = PWDN_GPIO_NUM; + config.pin_reset = RESET_GPIO_NUM; + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: Default template")); + } + + //ESP.getPsramSize() + + //esp_log_level_set("*", ESP_LOG_INFO); + + + // if PSRAM IC present, init with UXGA resolution and higher JPEG quality + // for larger pre-allocated frame buffer. + + bool psram = psramFound(); + if (psram) { + config.frame_size = FRAMESIZE_UXGA; + config.jpeg_quality = 10; + config.fb_count = 2; + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: PSRAM found")); + } else { + config.frame_size = FRAMESIZE_VGA; + config.jpeg_quality = 12; + config.fb_count = 1; + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: PSRAM not found")); + } + + // stupid workaround camera diver eats up static ram should prefer PSRAM + // so we steal static ram to force driver to alloc PSRAM + //ESP.getMaxAllocHeap() + +// void *x=malloc(70000); + void *x = 0; + esp_err_t err = esp_camera_init(&config); + if (x) { free(x); } + + if (err != ESP_OK) { + AddLog_P2(LOG_LEVEL_INFO, PSTR("CAM: Init failed with error 0x%x"), err); + return 0; + } + + sensor_t * wc_s = esp_camera_sensor_get(); + + wc_s->set_vflip(wc_s, Settings.webcam_config.flip); + wc_s->set_hmirror(wc_s, Settings.webcam_config.mirror); + wc_s->set_brightness(wc_s, Settings.webcam_config.brightness -2); // up the brightness just a bit + wc_s->set_saturation(wc_s, Settings.webcam_config.saturation -2); // lower the saturation + wc_s->set_contrast(wc_s, Settings.webcam_config.contrast -2); // keep contrast + + // drop down frame size for higher initial frame rate + wc_s->set_framesize(wc_s, (framesize_t)fsiz); + + camera_fb_t *wc_fb = esp_camera_fb_get(); + if (!wc_fb) { + AddLog_P2(LOG_LEVEL_INFO, PSTR("CAM: Init failed to get the frame on time")); + return 0; + } + Wc.width = wc_fb->width; + Wc.height = wc_fb->height; + esp_camera_fb_return(wc_fb); + +#ifdef USE_FACE_DETECT + fd_init(); +#endif + + AddLog_P2(LOG_LEVEL_INFO, PSTR("CAM: Initialized")); + + Wc.up = 1; + if (psram) { Wc.up = 2; } + + return Wc.up; +} + +/*********************************************************************************************/ + +int32_t WcSetOptions(uint32_t sel, int32_t value) { + int32_t res = 0; + sensor_t *s = esp_camera_sensor_get(); + if (!s) { return -99; } + + switch (sel) { + case 0: + if (value >= 0) { s->set_framesize(s, (framesize_t)value); } + res = s->status.framesize; + break; + case 1: + if (value >= 0) { s->set_special_effect(s, value); } + res = s->status.special_effect; + break; + case 2: + if (value >= 0) { s->set_vflip(s, value); } + res = s->status.vflip; + break; + case 3: + if (value >= 0) { s->set_hmirror(s, value); } + res = s->status.hmirror; + break; + case 4: + if (value >= -4) { s->set_contrast(s, value); } + res = s->status.contrast; + break; + case 5: + if (value >= -4) { s->set_brightness(s, value); } + res = s->status.brightness; + break; + case 6: + if (value >= -4) { s->set_saturation(s,value); } + res = s->status.saturation; + break; + } + + return res; +} + +uint32_t WcGetWidth(void) { + camera_fb_t *wc_fb = esp_camera_fb_get(); + if (!wc_fb) { return 0; } + Wc.width = wc_fb->width; + esp_camera_fb_return(wc_fb); + return Wc.width; +} + +uint32_t WcGetHeight(void) { + camera_fb_t *wc_fb = esp_camera_fb_get(); + if (!wc_fb) { return 0; } + Wc.height = wc_fb->height; + esp_camera_fb_return(wc_fb); + return Wc.height; +} + +/*********************************************************************************************/ + +uint16_t motion_detect; +uint32_t motion_ltime; +uint32_t motion_trigger; +uint32_t motion_brightness; +uint8_t *last_motion_buffer; + +uint32_t WcSetMotionDetect(int32_t value) { + if (value >= 0) { motion_detect = value; } + if (-1 == value) { + return motion_trigger; + } else { + return motion_brightness; + } +} + +// optional motion detector +void WcDetectMotion(void) { + camera_fb_t *wc_fb; + uint8_t *out_buf = 0; + + if ((millis()-motion_ltime) > motion_detect) { + motion_ltime = millis(); + wc_fb = esp_camera_fb_get(); + if (!wc_fb) { return; } + + if (!last_motion_buffer) { + last_motion_buffer=(uint8_t *)heap_caps_malloc((wc_fb->width*wc_fb->height)+4, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); + } + if (last_motion_buffer) { + if (PIXFORMAT_JPEG == wc_fb->format) { + out_buf = (uint8_t *)heap_caps_malloc((wc_fb->width*wc_fb->height*3)+4, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); + if (out_buf) { + fmt2rgb888(wc_fb->buf, wc_fb->len, wc_fb->format, out_buf); + uint32_t x, y; + uint8_t *pxi = out_buf; + uint8_t *pxr = last_motion_buffer; + // convert to bw + uint64_t accu = 0; + uint64_t bright = 0; + for (y = 0; y < wc_fb->height; y++) { + for (x = 0; x < wc_fb->width; x++) { + int32_t gray = (pxi[0] + pxi[1] + pxi[2]) / 3; + int32_t lgray = pxr[0]; + pxr[0] = gray; + pxi += 3; + pxr++; + accu += abs(gray - lgray); + bright += gray; + } + } + motion_trigger = accu / ((wc_fb->height * wc_fb->width) / 100); + motion_brightness = bright / ((wc_fb->height * wc_fb->width) / 100); + free(out_buf); + } + } + } + esp_camera_fb_return(wc_fb); + } +} + +/*********************************************************************************************/ + +#ifdef USE_FACE_DETECT + +static mtmn_config_t mtmn_config = {0}; + +void fd_init(void) { + mtmn_config.type = FAST; + mtmn_config.min_face = 80; + mtmn_config.pyramid = 0.707; + mtmn_config.pyramid_times = 4; + mtmn_config.p_threshold.score = 0.6; + mtmn_config.p_threshold.nms = 0.7; + mtmn_config.p_threshold.candidate_number = 20; + mtmn_config.r_threshold.score = 0.7; + mtmn_config.r_threshold.nms = 0.7; + mtmn_config.r_threshold.candidate_number = 10; + mtmn_config.o_threshold.score = 0.7; + mtmn_config.o_threshold.nms = 0.7; + mtmn_config.o_threshold.candidate_number = 1; +} + +#define FACE_COLOR_WHITE 0x00FFFFFF +#define FACE_COLOR_BLACK 0x00000000 +#define FACE_COLOR_RED 0x000000FF +#define FACE_COLOR_GREEN 0x0000FF00 +#define FACE_COLOR_BLUE 0x00FF0000 +#define FACE_COLOR_YELLOW (FACE_COLOR_RED | FACE_COLOR_GREEN) +#define FACE_COLOR_CYAN (FACE_COLOR_BLUE | FACE_COLOR_GREEN) +#define FACE_COLOR_PURPLE (FACE_COLOR_BLUE | FACE_COLOR_RED) +void draw_face_boxes(dl_matrix3du_t *image_matrix, box_array_t *boxes, int face_id); + +/* +void draw_face_boxes(dl_matrix3du_t *image_matrix, box_array_t *boxes, int face_id) { + int x, y, w, h, i; + uint32_t color = FACE_COLOR_YELLOW; + if(face_id < 0){ + color = FACE_COLOR_RED; + } else if(face_id > 0){ + color = FACE_COLOR_GREEN; + } + fb_data_t fb; + fb.width = image_matrix->w; + fb.height = image_matrix->h; + fb.data = image_matrix->item; + fb.bytes_per_pixel = 3; + fb.format = FB_BGR888; + for (i = 0; i < boxes->len; i++){ + // rectangle box + x = (int)boxes->box[i].box_p[0]; + y = (int)boxes->box[i].box_p[1]; + w = (int)boxes->box[i].box_p[2] - x + 1; + h = (int)boxes->box[i].box_p[3] - y + 1; + fb_gfx_drawFastHLine(&fb, x, y, w, color); + fb_gfx_drawFastHLine(&fb, x, y+h-1, w, color); + fb_gfx_drawFastVLine(&fb, x, y, h, color); + fb_gfx_drawFastVLine(&fb, x+w-1, y, h, color); +#if 0 + // landmark + int x0, y0, j; + for (j = 0; j < 10; j+=2) { + x0 = (int)boxes->landmark[i].landmark_p[j]; + y0 = (int)boxes->landmark[i].landmark_p[j+1]; + fb_gfx_fillRect(&fb, x0, y0, 3, 3, color); + } +#endif + } +} +*/ + +#define DL_SPIRAM_SUPPORT + +uint32_t WcSetFaceDetect(int32_t value) { + if (value >= 0) { Wc.face_detect_time = value; } + return Wc.faces; +} + +uint32_t face_ltime; + +uint32_t WcDetectFace(void); + +uint32_t WcDetectFace(void) { + dl_matrix3du_t *image_matrix; + size_t out_len, out_width, out_height; + uint8_t * out_buf; + bool s; + bool detected = false; + int face_id = 0; + camera_fb_t *fb; + + if ((millis() - face_ltime) > Wc.face_detect_time) { + face_ltime = millis(); + fb = esp_camera_fb_get(); + if (!fb) { return ESP_FAIL; } + + image_matrix = dl_matrix3du_alloc(1, fb->width, fb->height, 3); + if (!image_matrix) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: dl_matrix3du_alloc failed")); + esp_camera_fb_return(fb); + return ESP_FAIL; + } + + out_buf = image_matrix->item; + //out_len = fb->width * fb->height * 3; + //out_width = fb->width; + //out_height = fb->height; + + s = fmt2rgb888(fb->buf, fb->len, fb->format, out_buf); + esp_camera_fb_return(fb); + if (!s){ + dl_matrix3du_free(image_matrix); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: to rgb888 failed")); + return ESP_FAIL; + } + + box_array_t *net_boxes = face_detect(image_matrix, &mtmn_config); + if (net_boxes){ + detected = true; + Wc.faces = net_boxes->len; + //if(recognition_enabled){ + // face_id = run_face_recognition(image_matrix, net_boxes); + //} + //draw_face_boxes(image_matrix, net_boxes, face_id); + free(net_boxes->score); + free(net_boxes->box); + free(net_boxes->landmark); + free(net_boxes); + } else { + Wc.faces = 0; + } + dl_matrix3du_free(image_matrix); + //Serial.printf("face detected: %d",Wc.faces); + + } +} +#endif + +/*********************************************************************************************/ + +#ifndef MAX_PICSTORE +#define MAX_PICSTORE 4 +#endif +struct PICSTORE { + uint8_t *buff; + uint32_t len; +}; + +struct PICSTORE picstore[MAX_PICSTORE]; + +#ifdef COPYFRAME +struct PICSTORE tmp_picstore; +#endif + +uint32_t WcGetPicstore(int32_t num, uint8_t **buff) { + if (num<0) { return MAX_PICSTORE; } + *buff = picstore[num].buff; + return picstore[num].len; +} + +uint32_t WcGetFrame(int32_t bnum) { + size_t _jpg_buf_len = 0; + uint8_t * _jpg_buf = NULL; + camera_fb_t *wc_fb = 0; + bool jpeg_converted = false; + + if (bnum < 0) { + if (bnum < -MAX_PICSTORE) { bnum=-1; } + bnum = -bnum; + bnum--; + if (picstore[bnum].buff) { free(picstore[bnum].buff); } + picstore[bnum].len = 0; + return 0; + } + +#ifdef COPYFRAME + if (bnum & 0x10) { + bnum &= 0xf; + _jpg_buf = tmp_picstore.buff; + _jpg_buf_len = tmp_picstore.len; + if (!_jpg_buf_len) { return 0; } + goto pcopy; + } +#endif + + wc_fb = esp_camera_fb_get(); + if (!wc_fb) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: Can't get frame")); + return 0; + } + if (!bnum) { + Wc.width = wc_fb->width; + Wc.height = wc_fb->height; + esp_camera_fb_return(wc_fb); + return 0; + } + + if (wc_fb->format != PIXFORMAT_JPEG) { + jpeg_converted = frame2jpg(wc_fb, 80, &_jpg_buf, &_jpg_buf_len); + if (!jpeg_converted){ + //Serial.println("JPEG compression failed"); + _jpg_buf_len = wc_fb->len; + _jpg_buf = wc_fb->buf; + } + } else { + _jpg_buf_len = wc_fb->len; + _jpg_buf = wc_fb->buf; + } + +pcopy: + if ((bnum < 1) || (bnum > MAX_PICSTORE)) { bnum = 1; } + bnum--; + if (picstore[bnum].buff) { free(picstore[bnum].buff); } + picstore[bnum].buff = (uint8_t *)heap_caps_malloc(_jpg_buf_len+4, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); + if (picstore[bnum].buff) { + memcpy(picstore[bnum].buff, _jpg_buf, _jpg_buf_len); + picstore[bnum].len = _jpg_buf_len; + } else { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: Can't allocate picstore")); + picstore[bnum].len = 0; + } + if (wc_fb) { esp_camera_fb_return(wc_fb); } + if (jpeg_converted) { free(_jpg_buf); } + if (!picstore[bnum].buff) { return 0; } + + return _jpg_buf_len; +} + +void HandleImage(void) { + if (!HttpCheckPriviledgedAccess()) { return; } + + uint32_t bnum = Webserver->arg(F("p")).toInt(); + if ((bnum < 0) || (bnum > MAX_PICSTORE)) { bnum= 1; } + WiFiClient client = Webserver->client(); + String response = "HTTP/1.1 200 OK\r\n"; + response += "Content-disposition: inline; filename=cap.jpg\r\n"; + response += "Content-type: image/jpeg\r\n\r\n"; + Webserver->sendContent(response); + + if (!bnum) { + size_t _jpg_buf_len = 0; + uint8_t * _jpg_buf = NULL; + camera_fb_t *wc_fb = 0; + wc_fb = esp_camera_fb_get(); + if (!wc_fb) { return; } + if (wc_fb->format != PIXFORMAT_JPEG) { + bool jpeg_converted = frame2jpg(wc_fb, 80, &_jpg_buf, &_jpg_buf_len); + if (!jpeg_converted) { + _jpg_buf_len = wc_fb->len; + _jpg_buf = wc_fb->buf; + } + } else { + _jpg_buf_len = wc_fb->len; + _jpg_buf = wc_fb->buf; + } + if (_jpg_buf_len) { + client.write((char *)_jpg_buf, _jpg_buf_len); + } + if (wc_fb) { esp_camera_fb_return(wc_fb); } + } else { + bnum--; + if (!picstore[bnum].len) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: No image #: %d"), bnum); + return; + } + client.write((char *)picstore[bnum].buff, picstore[bnum].len); + } + client.stop(); + + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("CAM: Sending image #: %d"), bnum+1); +} + +void HandleImageBasic(void) { + if (!HttpCheckPriviledgedAccess()) { return; } + + AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_HTTP "Capture image")); + + if (Settings.webcam_config.stream) { + if (!CamServer) { + WcStreamControl(); + } + } + + camera_fb_t *wc_fb; + wc_fb = esp_camera_fb_get(); // Acquire frame + if (!wc_fb) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: Frame buffer could not be acquired")); + return; + } + + size_t _jpg_buf_len = 0; + uint8_t * _jpg_buf = NULL; + if (wc_fb->format != PIXFORMAT_JPEG) { + bool jpeg_converted = frame2jpg(wc_fb, 80, &_jpg_buf, &_jpg_buf_len); + if (!jpeg_converted) { + _jpg_buf_len = wc_fb->len; + _jpg_buf = wc_fb->buf; + } + } else { + _jpg_buf_len = wc_fb->len; + _jpg_buf = wc_fb->buf; + } + + if (_jpg_buf_len) { + Webserver->client().flush(); + WSHeaderSend(); + Webserver->sendHeader(F("Content-disposition"), F("inline; filename=snapshot.jpg")); + Webserver->send_P(200, "image/jpeg", (char *)_jpg_buf, _jpg_buf_len); + Webserver->client().stop(); + } + + esp_camera_fb_return(wc_fb); // Free frame buffer + + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("CAM: Image sent")); +} + +void HandleWebcamMjpeg(void) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: Handle camserver")); +// if (!Wc.stream_active) { +// always restart stream + Wc.stream_active = 1; + client = CamServer->client(); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: Create client")); +// } +} + +void HandleWebcamMjpegTask(void) { + camera_fb_t *wc_fb; + size_t _jpg_buf_len = 0; + uint8_t * _jpg_buf = NULL; + + //WiFiClient client = CamServer->client(); + uint32_t tlen; + bool jpeg_converted = false; + + if (!client.connected()) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: Client fail")); + Wc.stream_active = 0; + } + if (1 == Wc.stream_active) { + client.flush(); + client.setTimeout(3); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: Start stream")); + client.print("HTTP/1.1 200 OK\r\n" + "Content-Type: multipart/x-mixed-replace;boundary=" BOUNDARY "\r\n" + "\r\n"); + Wc.stream_active = 2; + } + if (2 == Wc.stream_active) { + wc_fb = esp_camera_fb_get(); + if (!wc_fb) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: Frame fail")); + Wc.stream_active = 0; + } + } + if (2 == Wc.stream_active) { + if (wc_fb->format != PIXFORMAT_JPEG) { + jpeg_converted = frame2jpg(wc_fb, 80, &_jpg_buf, &_jpg_buf_len); + if (!jpeg_converted){ + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: JPEG compression failed")); + _jpg_buf_len = wc_fb->len; + _jpg_buf = wc_fb->buf; + } + } else { + _jpg_buf_len = wc_fb->len; + _jpg_buf = wc_fb->buf; + } + + client.printf("Content-Type: image/jpeg\r\n" + "Content-Length: %d\r\n" + "\r\n", static_cast(_jpg_buf_len)); + tlen = client.write(_jpg_buf, _jpg_buf_len); + /* + if (tlen!=_jpg_buf_len) { + esp_camera_fb_return(wc_fb); + Wc.stream_active=0; + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: Send fail")); + }*/ + client.print("\r\n--" BOUNDARY "\r\n"); + +#ifdef COPYFRAME + if (tmp_picstore.buff) { free(tmp_picstore.buff); } + tmp_picstore.buff = (uint8_t *)heap_caps_malloc(_jpg_buf_len+4, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); + if (tmp_picstore.buff) { + memcpy(tmp_picstore.buff, _jpg_buf, _jpg_buf_len); + tmp_picstore.len = _jpg_buf_len; + } else { + tmp_picstore.len = 0; + } +#endif + + if (jpeg_converted) { free(_jpg_buf); } + esp_camera_fb_return(wc_fb); + //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: send frame")); + } + if (0 == Wc.stream_active) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: Stream exit")); + client.flush(); + client.stop(); + } +} + +void HandleWebcamRoot(void) { + //CamServer->redirect("http://" + String(ip) + ":81/cam.mjpeg"); + CamServer->sendHeader("Location", WiFi.localIP().toString() + ":81/cam.mjpeg"); + CamServer->send(302, "", ""); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: Root called")); +} + +/*********************************************************************************************/ + +uint32_t WcSetStreamserver(uint32_t flag) { + if (global_state.network_down) { return 0; } + + Wc.stream_active = 0; + + if (flag) { + if (!CamServer) { + CamServer = new ESP8266WebServer(81); + CamServer->on("/", HandleWebcamRoot); + CamServer->on("/cam.mjpeg", HandleWebcamMjpeg); + CamServer->on("/cam.jpg", HandleWebcamMjpeg); + CamServer->on("/stream", HandleWebcamMjpeg); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: Stream init")); + CamServer->begin(); + } + } else { + if (CamServer) { + CamServer->stop(); + delete CamServer; + CamServer = NULL; + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CAM: Stream exit")); + } + } + return 0; +} + +void WcStreamControl() { + WcSetStreamserver(Settings.webcam_config.stream); + int resolution = (!Settings.webcam_config.stream) ? -1 : Settings.webcam_config.resolution; + WcSetup(resolution); +} + +/*********************************************************************************************/ + +void WcLoop(void) { + if (CamServer) { + CamServer->handleClient(); + if (Wc.stream_active) { HandleWebcamMjpegTask(); } + } + if (motion_detect) { WcDetectMotion(); } +#ifdef USE_FACE_DETECT + if (Wc.face_detect_time) { WcDetectFace(); } +#endif +} + +void WcPicSetup(void) { + Webserver->on("/wc.jpg", HandleImage); + Webserver->on("/wc.mjpeg", HandleImage); + Webserver->on("/snapshot.jpg", HandleImageBasic); +} + +void WcShowStream(void) { + if (Settings.webcam_config.stream) { +// if (!CamServer || !Wc.up) { + if (!CamServer) { + WcStreamControl(); + delay(50); // Give the webcam webserver some time to prepare the stream + } + if (CamServer && Wc.up) { + WSContentSend_P(PSTR("

    Webcam stream

    "), + WiFi.localIP().toString().c_str()); + } + } +} + +void WcInit(void) { + if (!Settings.webcam_config.data) { + Settings.webcam_config.stream = 1; + Settings.webcam_config.resolution = 5; + Settings.webcam_config.flip = 0; + Settings.webcam_config.mirror = 0; + Settings.webcam_config.saturation = 0; // -2 + Settings.webcam_config.brightness = 3; // 1 + Settings.webcam_config.contrast = 2; // 0 + } +} + +/*********************************************************************************************\ + * Commands +\*********************************************************************************************/ + +#define D_PRFX_WEBCAM "WC" +#define D_CMND_WC_STREAM "Stream" +#define D_CMND_WC_RESOLUTION "Resolution" +#define D_CMND_WC_MIRROR "Mirror" +#define D_CMND_WC_FLIP "Flip" +#define D_CMND_WC_SATURATION "Saturation" +#define D_CMND_WC_BRIGHTNESS "Brightness" +#define D_CMND_WC_CONTRAST "Contrast" + +const char kWCCommands[] PROGMEM = D_PRFX_WEBCAM "|" // Prefix + "|" D_CMND_WC_STREAM "|" D_CMND_WC_RESOLUTION "|" D_CMND_WC_MIRROR "|" D_CMND_WC_FLIP "|" + D_CMND_WC_SATURATION "|" D_CMND_WC_BRIGHTNESS "|" D_CMND_WC_CONTRAST + ; + +void (* const WCCommand[])(void) PROGMEM = { + &CmndWebcam, &CmndWebcamStream, &CmndWebcamResolution, &CmndWebcamMirror, &CmndWebcamFlip, + &CmndWebcamSaturation, &CmndWebcamBrightness, &CmndWebcamContrast + }; + +void CmndWebcam(void) { + Response_P(PSTR("{\"" D_PRFX_WEBCAM "\":{\"" D_CMND_WC_STREAM "\":%d,\"" D_CMND_WC_RESOLUTION "\":%d,\"" D_CMND_WC_MIRROR "\":%d,\"" + D_CMND_WC_FLIP "\":%d,\"" + D_CMND_WC_SATURATION "\":%d,\"" D_CMND_WC_BRIGHTNESS "\":%d,\"" D_CMND_WC_CONTRAST "\":%d}}"), + Settings.webcam_config.stream, Settings.webcam_config.resolution, Settings.webcam_config.mirror, + Settings.webcam_config.flip, + Settings.webcam_config.saturation -2, Settings.webcam_config.brightness -2, Settings.webcam_config.contrast -2); +} + +void CmndWebcamStream(void) { + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) { + Settings.webcam_config.stream = XdrvMailbox.payload; + if (!Settings.webcam_config.stream) { WcStreamControl(); } // Stop stream + } + ResponseCmndStateText(Settings.webcam_config.stream); +} + +void CmndWebcamResolution(void) { + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 10)) { + Settings.webcam_config.resolution = XdrvMailbox.payload; + WcSetOptions(0, Settings.webcam_config.resolution); + } + ResponseCmndNumber(Settings.webcam_config.resolution); +} + +void CmndWebcamMirror(void) { + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) { + Settings.webcam_config.mirror = XdrvMailbox.payload; + WcSetOptions(3, Settings.webcam_config.mirror); + } + ResponseCmndStateText(Settings.webcam_config.mirror); +} + +void CmndWebcamFlip(void) { + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) { + Settings.webcam_config.flip = XdrvMailbox.payload; + WcSetOptions(2, Settings.webcam_config.flip); + } + ResponseCmndStateText(Settings.webcam_config.flip); +} + +void CmndWebcamSaturation(void) { + if ((XdrvMailbox.payload >= -2) && (XdrvMailbox.payload <= 2)) { + Settings.webcam_config.saturation = XdrvMailbox.payload +2; + WcSetOptions(6, Settings.webcam_config.saturation -2); + } + ResponseCmndNumber(Settings.webcam_config.saturation -2); +} + +void CmndWebcamBrightness(void) { + if ((XdrvMailbox.payload >= -2) && (XdrvMailbox.payload <= 2)) { + Settings.webcam_config.brightness = XdrvMailbox.payload +2; + WcSetOptions(5, Settings.webcam_config.brightness -2); + } + ResponseCmndNumber(Settings.webcam_config.brightness -2); +} + +void CmndWebcamContrast(void) { + if ((XdrvMailbox.payload >= -2) && (XdrvMailbox.payload <= 2)) { + Settings.webcam_config.contrast = XdrvMailbox.payload +2; + WcSetOptions(4, Settings.webcam_config.contrast -2); + } + ResponseCmndNumber(Settings.webcam_config.contrast -2); +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xdrv81(uint8_t function) { + bool result = false; + + switch (function) { + case FUNC_LOOP: + WcLoop(); + break; + case FUNC_WEB_ADD_HANDLER: + WcPicSetup(); + break; + case FUNC_WEB_ADD_MAIN_BUTTON: + WcShowStream(); + break; + case FUNC_COMMAND: + result = DecodeCommand(kWCCommands, WCCommand); + break; + case FUNC_PRE_INIT: + WcInit(); + break; + + } + return result; +} + +#endif // USE_WEBCAM +#endif // ESP32 diff --git a/tasmota/xdrv_82_ethernet.ino b/tasmota/xdrv_82_ethernet.ino new file mode 100644 index 000000000..dcaa5fde8 --- /dev/null +++ b/tasmota/xdrv_82_ethernet.ino @@ -0,0 +1,204 @@ +/* + xdrv_82_ethernet.ino - ESP32 (PoE) ethernet support for Tasmota + + Copyright (C) 2020 Theo Arends + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifdef ESP32 +#ifdef USE_ETHERNET +/*********************************************************************************************\ + * Ethernet support for ESP32 + * + * Dedicated fixed Phy pins + * GPIO17 - EMAC_CLK_OUT_180 + * GPIO19 - EMAC_TXD0(RMII) + * GPIO21 - EMAC_TX_EN(RMII) + * GPIO22 - EMAC_TXD1(RMII) + * GPIO25 - EMAC_RXD0(RMII) + * GPIO26 - EMAC_RXD1(RMII) + * GPIO27 - EMAC_RX_CRS_DV + * + * {"NAME":"Olimex ESP32-PoE","GPIO":[1,1,1,1,1,1,0,0,5536,1,1,1,1,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1} + * {"NAME":"wESP32","GPIO":[0,0,1,0,1,1,0,0,1,1,1,1,5568,5600,1,0,0,0,0,1,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1} +\*********************************************************************************************/ + +#define XDRV_82 82 + +/* +// Olimex ESP32-PoE +#define ETH_CLKMODE ETH_CLOCK_GPIO17_OUT +#define ETH_POWER_PIN 12 + +//******************************************************************************************** + +#ifndef ETH_ADDR +#define ETH_ADDR 0 // esp_eth.h eth_phy_base_t: 0 = PHY0 .. 31 = PHY31 +#endif + +#ifndef ETH_TYPE +#define ETH_TYPE ETH_PHY_LAN8720 // ETH.h eth_phy_type_t: 0 = ETH_PHY_LAN8720, 1 = ETH_PHY_TLK110, 2 = ETH_PHY_IP101 +#endif + +#ifndef ETH_CLKMODE +#define ETH_CLKMODE ETH_CLOCK_GPIO0_IN // esp_eth.h eth_clock_mode_t: 0 = ETH_CLOCK_GPIO0_IN, 1 = ETH_CLOCK_GPIO0_OUT, 2 = ETH_CLOCK_GPIO16_OUT, 3 = ETH_CLOCK_GPIO17_OUT +#endif +*/ + +#include + +char eth_hostname[sizeof(my_hostname)]; + +void EthernetEvent(WiFiEvent_t event) { + switch (event) { + case SYSTEM_EVENT_ETH_START: + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ETH: " D_ATTEMPTING_CONNECTION)); + ETH.setHostname(eth_hostname); + break; + case SYSTEM_EVENT_ETH_CONNECTED: + AddLog_P2(LOG_LEVEL_INFO, PSTR("ETH: " D_CONNECTED)); + break; + case SYSTEM_EVENT_ETH_GOT_IP: + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ETH: Mac %s, IPAddress %s, Hostname %s"), + ETH.macAddress().c_str(), ETH.localIP().toString().c_str(), eth_hostname); +/* + if (ETH.fullDuplex()) { + Serial.print(", FULL_DUPLEX"); + } + Serial.print(", "); + Serial.print(ETH.linkSpeed()); + Serial.println("Mbps"); +*/ + Settings.ip_address[1] = (uint32_t)ETH.gatewayIP(); + Settings.ip_address[2] = (uint32_t)ETH.subnetMask(); + Settings.ip_address[3] = (uint32_t)ETH.dnsIP(); + global_state.eth_down = 0; + break; + case SYSTEM_EVENT_ETH_DISCONNECTED: + AddLog_P2(LOG_LEVEL_INFO, PSTR("ETH: Disconnected")); + global_state.eth_down = 1; + break; + case SYSTEM_EVENT_ETH_STOP: + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ETH: Stopped")); + global_state.eth_down = 1; + break; + default: + break; + } +} + +void EthernetInit(void) { + if (!Settings.flag4.network_ethernet) { return; } + if (!PinUsed(GPIO_ETH_PHY_MDC) && !PinUsed(GPIO_ETH_PHY_MDIO)) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ETH: No ETH MDC and/or ETH MDIO GPIO defined")); + return; + } + +// snprintf_P(Eth.hostname, sizeof(Eth.hostname), PSTR("%s_eth"), my_hostname); + strlcpy(eth_hostname, my_hostname, sizeof(eth_hostname) -5); // Make sure there is room for "_eth" + strcat(eth_hostname, "_eth"); + + WiFi.onEvent(EthernetEvent); + + int eth_power = (PinUsed(GPIO_ETH_PHY_POWER)) ? Pin(GPIO_ETH_PHY_POWER) : -1; + int eth_mdc = Pin(GPIO_ETH_PHY_MDC); + int eth_mdio = Pin(GPIO_ETH_PHY_MDIO); + if (!ETH.begin(Settings.eth_address, eth_power, eth_mdc, eth_mdio, (eth_phy_type_t)Settings.eth_type, (eth_clock_mode_t)Settings.eth_clk_mode)) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("ETH: Bad PHY type or init error")); + }; +} + +IPAddress EthernetLocalIP(void) { + return ETH.localIP(); +} + +char* EthernetHostname(void) { + return eth_hostname; +} + +String EthernetMacAddress(void) { + return ETH.macAddress(); +} + +/*********************************************************************************************\ + * Commands +\*********************************************************************************************/ + +#define D_CMND_ETHADDRESS "EthAddress" +#define D_CMND_ETHTYPE "EthType" +#define D_CMND_ETHCLOCKMODE "EthClockMode" + +const char kEthernetCommands[] PROGMEM = "|" // No prefix + D_CMND_ETHERNET "|" D_CMND_ETHADDRESS "|" D_CMND_ETHTYPE "|" D_CMND_ETHCLOCKMODE; + +void (* const EthernetCommand[])(void) PROGMEM = { + &CmndEthernet, &CmndEthAddress, &CmndEthType, &CmndEthClockMode }; + +void CmndEthernet(void) +{ + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) { + Settings.flag4.network_ethernet = XdrvMailbox.payload; + restart_flag = 2; + } + ResponseCmndStateText(Settings.flag4.network_ethernet); +} + +void CmndEthAddress(void) +{ + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 31)) { + Settings.eth_address = XdrvMailbox.payload; + restart_flag = 2; + } + ResponseCmndNumber(Settings.eth_address); +} + +void CmndEthType(void) +{ + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 2)) { + Settings.eth_type = XdrvMailbox.payload; + restart_flag = 2; + } + ResponseCmndNumber(Settings.eth_type); +} + +void CmndEthClockMode(void) +{ + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 3)) { + Settings.eth_clk_mode = XdrvMailbox.payload; + restart_flag = 2; + } + ResponseCmndNumber(Settings.eth_clk_mode); +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xdrv82(uint8_t function) { + bool result = false; + + switch (function) { + case FUNC_COMMAND: + result = DecodeCommand(kEthernetCommands, EthernetCommand); + break; + case FUNC_INIT: + EthernetInit(); + break; + } + return result; +} + +#endif // USE_ETHERNET +#endif // ESP32 diff --git a/tasmota/xdrv_99_debug.ino b/tasmota/xdrv_99_debug.ino index 538ac7f71..08f451c30 100644 --- a/tasmota/xdrv_99_debug.ino +++ b/tasmota/xdrv_99_debug.ino @@ -45,7 +45,6 @@ #define D_CMND_CFGDUMP "CfgDump" #define D_CMND_CFGPEEK "CfgPeek" #define D_CMND_CFGPOKE "CfgPoke" -#define D_CMND_CFGSHOW "CfgShow" #define D_CMND_CFGXOR "CfgXor" #define D_CMND_CPUCHECK "CpuChk" #define D_CMND_EXCEPTION "Exception" @@ -59,13 +58,14 @@ #define D_CMND_I2CREAD "I2CRead" #define D_CMND_I2CSTRETCH "I2CStretch" #define D_CMND_I2CCLOCK "I2CClock" +#define D_CMND_SERBUFF "SerBufSize" const char kDebugCommands[] PROGMEM = "|" // No prefix D_CMND_CFGDUMP "|" D_CMND_CFGPEEK "|" D_CMND_CFGPOKE "|" #ifdef USE_WEBSERVER D_CMND_CFGXOR "|" #endif - D_CMND_CPUCHECK "|" + D_CMND_CPUCHECK "|" D_CMND_SERBUFF "|" #ifdef DEBUG_THEO D_CMND_EXCEPTION "|" #endif @@ -80,7 +80,7 @@ void (* const DebugCommand[])(void) PROGMEM = { #ifdef USE_WEBSERVER &CmndCfgXor, #endif - &CmndCpuCheck, + &CmndCpuCheck, &CmndSerBufSize, #ifdef DEBUG_THEO &CmndException, #endif @@ -172,11 +172,11 @@ void CpuLoadLoop(void) CPU_loops ++; if ((CPU_last_millis + (CPU_load_check *1000)) <= CPU_last_loop_time) { #if defined(F_CPU) && (F_CPU == 160000000L) - int CPU_load = 100 - ( (CPU_loops*(1 + 30*sleep)) / (CPU_load_check *800) ); + int CPU_load = 100 - ( (CPU_loops*(1 + 30*ssleep)) / (CPU_load_check *800) ); CPU_loops = CPU_loops / CPU_load_check; AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "FreeRam %d, CPU %d%%(160MHz), Loops/sec %d"), ESP.getFreeHeap(), CPU_load, CPU_loops); #else - int CPU_load = 100 - ( (CPU_loops*(1 + 30*sleep)) / (CPU_load_check *400) ); + int CPU_load = 100 - ( (CPU_loops*(1 + 30*ssleep)) / (CPU_load_check *400) ); CPU_loops = CPU_loops / CPU_load_check; AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "FreeRam %d, CPU %d%%(80MHz), Loops/sec %d"), ESP.getFreeHeap(), CPU_load, CPU_loops); #endif @@ -188,6 +188,7 @@ void CpuLoadLoop(void) /*******************************************************************************************/ +#ifdef ESP8266 #if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_1) // All version before core 2.4.2 // https://github.com/esp8266/Arduino/issues/2557 @@ -224,10 +225,22 @@ void DebugFreeMem(void) #endif // ARDUINO_ESP8266_RELEASE_2_x_x +#else // ESP32 + +void DebugFreeMem(void) +{ + register uint8_t *sp asm("a1"); + + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "FreeRam %d, FreeStack %d (%s)"), ESP.getFreeHeap(), sp - pxTaskGetStackStart(NULL), XdrvMailbox.data); +} + +#endif // ESP8266 - ESP32 + /*******************************************************************************************/ void DebugRtcDump(char* parms) { +#ifdef ESP8266 #define CFG_COLS 16 uint16_t idx; @@ -283,6 +296,7 @@ void DebugRtcDump(char* parms) snprintf_P(log_data, sizeof(log_data), PSTR("%s|"), log_data); AddLog(LOG_LEVEL_INFO); } +#endif // ESP8266 } /*******************************************************************************************/ @@ -298,7 +312,7 @@ void DebugCfgDump(char* parms) char *p; uint8_t *buffer = (uint8_t *) &Settings; - maxrow = ((sizeof(SYSCFG)+CFG_COLS)/CFG_COLS); + maxrow = ((sizeof(Settings)+CFG_COLS)/CFG_COLS); uint16_t srow = strtol(parms, &p, 16) / CFG_COLS; uint16_t mrow = strtol(p, &p, 10); @@ -342,7 +356,7 @@ void DebugCfgPeek(char* parms) char *p; uint16_t address = strtol(parms, &p, 16); - if (address > sizeof(SYSCFG)) address = sizeof(SYSCFG) -4; + if (address > sizeof(Settings)) address = sizeof(Settings) -4; address = (address >> 2) << 2; uint8_t *buffer = (uint8_t *) &Settings; @@ -367,7 +381,7 @@ void DebugCfgPoke(char* parms) char *p; uint16_t address = strtol(parms, &p, 16); - if (address > sizeof(SYSCFG)) address = sizeof(SYSCFG) -4; + if (address > sizeof(Settings)) address = sizeof(Settings) -4; address = (address >> 2) << 2; uint32_t data = strtol(p, &p, 16); @@ -385,6 +399,7 @@ void DebugCfgPoke(char* parms) void SetFlashMode(uint8_t mode) { +#ifdef ESP8266 uint8_t *_buffer; uint32_t address; @@ -400,6 +415,7 @@ void SetFlashMode(uint8_t mode) } } delete[] _buffer; +#endif // ESP8266 } /*********************************************************************************************\ @@ -442,7 +458,9 @@ void CmndCfgXor(void) if (XdrvMailbox.data_len > 0) { Web.config_xor_on_set = XdrvMailbox.payload; } - ResponseCmndNumber(Web.config_xor_on_set); + char temp[10]; + snprintf_P(temp, sizeof(temp), PSTR("0x%02X"), Web.config_xor_on_set); + ResponseCmndChar(temp); } #endif // USE_WEBSERVER @@ -463,6 +481,18 @@ void CmndCpuCheck(void) ResponseCmndNumber(CPU_load_check); } +void CmndSerBufSize(void) +{ + if (XdrvMailbox.data_len > 0) { + Serial.setRxBufferSize(XdrvMailbox.payload); + } +#ifdef ESP8266 + ResponseCmndNumber(Serial.getRxBufferSize()); +#else + ResponseCmndDone(); +#endif +} + void CmndFreemem(void) { if (XdrvMailbox.data_len > 0) { @@ -503,6 +533,7 @@ uint32_t DebugSwap32(uint32_t x) { void CmndFlashDump(void) { +#ifdef ESP8266 // FlashDump // FlashDump 0xFF000 // FlashDump 0xFC000 10 @@ -533,6 +564,7 @@ void CmndFlashDump(void) DebugSwap32(values[4]), DebugSwap32(values[5]), DebugSwap32(values[6]), DebugSwap32(values[7])); } ResponseCmndDone(); +#endif // ESP8266 } #ifdef USE_I2C @@ -600,10 +632,12 @@ void CmndI2cRead(void) void CmndI2cStretch(void) { +#ifdef ESP8266 if (i2c_flg && (XdrvMailbox.payload > 0)) { Wire.setClockStretchLimit(XdrvMailbox.payload); } ResponseCmndDone(); +#endif // ESP8266 } void CmndI2cClock(void) diff --git a/tasmota/xdsp_02_ssd1306.ino b/tasmota/xdsp_02_ssd1306.ino index 6060686b9..24700b0af 100644 --- a/tasmota/xdsp_02_ssd1306.ino +++ b/tasmota/xdsp_02_ssd1306.ino @@ -71,8 +71,8 @@ void SSD1306InitDriver(void) } uint8_t reset_pin = -1; - if (pin[GPIO_OLED_RESET] < 99) { - reset_pin = pin[GPIO_OLED_RESET]; + if (PinUsed(GPIO_OLED_RESET)) { + reset_pin = Pin(GPIO_OLED_RESET); } // allocate screen buffer diff --git a/tasmota/xdsp_04_ili9341.ino b/tasmota/xdsp_04_ili9341.ino index 5ad269e82..191c074bb 100644 --- a/tasmota/xdsp_04_ili9341.ino +++ b/tasmota/xdsp_04_ili9341.ino @@ -34,10 +34,29 @@ Adafruit_ILI9341 *tft; -uint16_t tft_scroll; +uint16_t tft_top = TFT_TOP; +uint16_t tft_bottom = TFT_BOTTOM; +uint16_t tft_scroll = TFT_TOP; +uint16_t tft_cols = 0; /*********************************************************************************************/ +bool Ili9341Header(void) { + if (Settings.display_cols[0] != tft_cols) { + tft_cols = Settings.display_cols[0]; + if (tft_cols > 17) { + tft_top = TFT_TOP; + tft_bottom = TFT_BOTTOM; + } else { + tft_top = 0; + tft_bottom = 0; + } + tft_scroll = tft_top; + tft->setScrollMargins(tft_top, tft_bottom); + } + return (tft_cols > 17); +} + void Ili9341InitMode(void) { tft->setRotation(Settings.display_rotate); // 0 @@ -50,13 +69,12 @@ void Ili9341InitMode(void) tft->setTextColor(ILI9341_WHITE, ILI9341_BLACK); tft->setTextSize(1); } else { - tft->setScrollMargins(TFT_TOP, TFT_BOTTOM); + Ili9341Header(); tft->setCursor(0, 0); tft->setTextColor(ILI9341_YELLOW, ILI9341_BLACK); tft->setTextSize(2); // tft->println("HEADER"); - tft_scroll = TFT_TOP; } } @@ -90,7 +108,8 @@ void Ili9341InitDriver(void) if (Settings.display_height != ILI9341_TFTHEIGHT) { Settings.display_height = ILI9341_TFTHEIGHT; } - tft = new Adafruit_ILI9341(pin[GPIO_SPI_CS], pin[GPIO_SPI_DC]); + + tft = new Adafruit_ILI9341(Pin(GPIO_SPI_CS), Pin(GPIO_SPI_DC)); tft->begin(); #ifdef USE_DISPLAY_MODES1TO5 @@ -100,6 +119,8 @@ void Ili9341InitDriver(void) #endif // USE_DISPLAY_MODES1TO5 Ili9341InitMode(); + + AddLog_P2(LOG_LEVEL_INFO, PSTR("DSP: ILI9341")); } } @@ -128,9 +149,9 @@ void Ili9341DisplayOnOff(uint8_t on) { // tft->showDisplay(on); // tft->invertDisplay(on); - if (pin[GPIO_BACKLIGHT] < 99) { - pinMode(pin[GPIO_BACKLIGHT], OUTPUT); - digitalWrite(pin[GPIO_BACKLIGHT], on); + if (PinUsed(GPIO_BACKLIGHT)) { + pinMode(Pin(GPIO_BACKLIGHT), OUTPUT); + digitalWrite(Pin(GPIO_BACKLIGHT), on); } } @@ -164,14 +185,14 @@ void Ili9341PrintLog(void) tft->fillRect(0, tft_scroll, tft->width(), theight, ILI9341_BLACK); // Erase line tft->print(txt); tft_scroll += theight; - if (tft_scroll >= (tft->height() - TFT_BOTTOM)) { - tft_scroll = TFT_TOP; + if (tft_scroll >= (tft->height() - tft_bottom)) { + tft_scroll = tft_top; } tft->scrollTo(tft_scroll); } else { uint8_t last_row = Settings.display_rows -1; - tft_scroll = theight; // Start below header + tft_scroll = (tft_top) ? theight : 0; // Start below header tft->setCursor(0, tft_scroll); for (uint32_t i = 0; i < last_row; i++) { strlcpy(disp_screen_buffer[i], disp_screen_buffer[i +1], disp_screen_buffer_cols); @@ -193,22 +214,30 @@ void Ili9341PrintLog(void) void Ili9341Refresh(void) // Every second { if (Settings.display_mode) { // Mode 0 is User text - char tftdt[Settings.display_cols[0] +1]; - char date4[11]; // 24-04-2017 - char space[Settings.display_cols[0] - 17]; - char time[9]; // 13:45:43 + // 24-04-2017 13:45:43 = 19 + 1 ('\0') = 20 + // 24-04-2017 13:45 = 16 + 1 ('\0') = 17 - tft->setTextSize(2); - tft->setTextColor(ILI9341_YELLOW, ILI9341_RED); // Add background color to solve flicker - tft->setCursor(0, 0); + if (Ili9341Header()) { + char tftdt[Settings.display_cols[0] +1]; + char date4[11]; // 24-04-2017 + uint8_t time_size = (Settings.display_cols[0] >= 20) ? 9 : 6; // 13:45:43 or 13:45 + char spaces[Settings.display_cols[0] - (8 + time_size)]; + char time[time_size]; // 13:45:43 - snprintf_P(date4, sizeof(date4), PSTR("%02d" D_MONTH_DAY_SEPARATOR "%02d" D_YEAR_MONTH_SEPARATOR "%04d"), RtcTime.day_of_month, RtcTime.month, RtcTime.year); - memset(space, 0x20, sizeof(space)); - space[sizeof(space) -1] = '\0'; - snprintf_P(time, sizeof(time), PSTR("%02d" D_HOUR_MINUTE_SEPARATOR "%02d" D_MINUTE_SECOND_SEPARATOR "%02d"), RtcTime.hour, RtcTime.minute, RtcTime.second); - snprintf_P(tftdt, sizeof(tftdt), PSTR("%s%s%s"), date4, space, time); + tft->setTextSize(Settings.display_size); + tft->setTextColor(ILI9341_YELLOW, ILI9341_RED); // Add background color to solve flicker + tft->setCursor(0, 0); - tft->print(tftdt); + snprintf_P(date4, sizeof(date4), PSTR("%02d" D_MONTH_DAY_SEPARATOR "%02d" D_YEAR_MONTH_SEPARATOR "%04d"), RtcTime.day_of_month, RtcTime.month, RtcTime.year); + memset(spaces, 0x20, sizeof(spaces)); + spaces[sizeof(spaces) -1] = '\0'; + snprintf_P(time, sizeof(time), PSTR("%02d" D_HOUR_MINUTE_SEPARATOR "%02d" D_MINUTE_SECOND_SEPARATOR "%02d"), RtcTime.hour, RtcTime.minute, RtcTime.second); + snprintf_P(tftdt, sizeof(tftdt), PSTR("%s%s%s"), date4, spaces, time); + + tft->print(tftdt); + } else { + tft->setCursor(0, 0); + } switch (Settings.display_mode) { case 1: // Text diff --git a/tasmota/xdsp_05_epaper_29.ino b/tasmota/xdsp_05_epaper_29.ino index 946fc6343..dc7397221 100644 --- a/tasmota/xdsp_05_epaper_29.ino +++ b/tasmota/xdsp_05_epaper_29.ino @@ -67,13 +67,13 @@ void EpdInitDriver29() epd = new Epd(EPD_WIDTH,EPD_HEIGHT); // whiten display with full update, takes 3 seconds - if ((pin[GPIO_SPI_CS] < 99) && (pin[GPIO_SPI_CLK] < 99) && (pin[GPIO_SPI_MOSI] < 99)) { - epd->Begin(pin[GPIO_SPI_CS],pin[GPIO_SPI_MOSI],pin[GPIO_SPI_CLK]); - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("EPD: HardSPI CS %d, CLK %d, MOSI %d"),pin[GPIO_SPI_CS], pin[GPIO_SPI_CLK], pin[GPIO_SPI_MOSI]); + if (PinUsed(GPIO_SPI_CS) && PinUsed(GPIO_SPI_CLK) && PinUsed(GPIO_SPI_MOSI)) { + epd->Begin(Pin(GPIO_SPI_CS),Pin(GPIO_SPI_MOSI),Pin(GPIO_SPI_CLK)); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("EPD: HardSPI CS %d, CLK %d, MOSI %d"),Pin(GPIO_SPI_CS), Pin(GPIO_SPI_CLK), Pin(GPIO_SPI_MOSI)); } - else if ((pin[GPIO_SSPI_CS] < 99) && (pin[GPIO_SSPI_SCLK] < 99) && (pin[GPIO_SSPI_MOSI] < 99)) { - epd->Begin(pin[GPIO_SSPI_CS],pin[GPIO_SSPI_MOSI],pin[GPIO_SSPI_SCLK]); - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("EPD: SoftSPI CS %d, CLK %d, MOSI %d"),pin[GPIO_SSPI_CS], pin[GPIO_SSPI_SCLK], pin[GPIO_SSPI_MOSI]); + else if (PinUsed(GPIO_SSPI_CS) && PinUsed(GPIO_SSPI_SCLK) && PinUsed(GPIO_SSPI_MOSI)) { + epd->Begin(Pin(GPIO_SSPI_CS),Pin(GPIO_SSPI_MOSI),Pin(GPIO_SSPI_SCLK)); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("EPD: SoftSPI CS %d, CLK %d, MOSI %d"),Pin(GPIO_SSPI_CS), Pin(GPIO_SSPI_SCLK), Pin(GPIO_SSPI_MOSI)); } else { free(buffer); return; diff --git a/tasmota/xdsp_06_epaper_42.ino b/tasmota/xdsp_06_epaper_42.ino index 7a19ebb7f..fee42db6c 100644 --- a/tasmota/xdsp_06_epaper_42.ino +++ b/tasmota/xdsp_06_epaper_42.ino @@ -65,15 +65,15 @@ void EpdInitDriver42() epd42 = new Epd42(EPD_WIDTH42,EPD_HEIGHT42); #ifdef USE_SPI - if ((pin[GPIO_SSPI_CS]<99) && (pin[GPIO_SSPI_MOSI]<99) && (pin[GPIO_SSPI_SCLK]<99)) { - epd42->Begin(pin[GPIO_SSPI_CS],pin[GPIO_SSPI_MOSI],pin[GPIO_SSPI_SCLK]); + if (PinUsed(GPIO_SSPI_CS) && PinUsed(GPIO_SSPI_MOSI) && PinUsed(GPIO_SSPI_SCLK)) { + epd42->Begin(Pin(GPIO_SSPI_CS),Pin(GPIO_SSPI_MOSI),Pin(GPIO_SSPI_SCLK)); } else { free(buffer); return; } #else - if ((pin[GPIO_SPI_CS]<99) && (pin[GPIO_SPI_MOSI]<99) && (pin[GPIO_SPI_CLK]<99)) { - epd42->Begin(pin[GPIO_SPI_CS],pin[GPIO_SPI_MOSI],pin[GPIO_SPI_CLK]); + if (PinUsed(GPIO_SPI_CS) && PinUsed(GPIO_SPI_MOSI) && PinUsed(GPIO_SPI_CLK)) { + epd42->Begin(Pin(GPIO_SPI_CS),Pin(GPIO_SPI_MOSI),Pin(GPIO_SPI_CLK)); } else { free(buffer); return; diff --git a/tasmota/xdsp_08_ILI9488.ino b/tasmota/xdsp_08_ILI9488.ino index 84a493fc6..e49e7bffe 100644 --- a/tasmota/xdsp_08_ILI9488.ino +++ b/tasmota/xdsp_08_ILI9488.ino @@ -80,22 +80,37 @@ void ILI9488_InitDriver() bg_color = ILI9488_BLACK; uint8_t bppin=BACKPLANE_PIN; - if (pin[GPIO_BACKLIGHT]<99) { - bppin=pin[GPIO_BACKLIGHT]; + if (PinUsed(GPIO_BACKLIGHT)) { + bppin=Pin(GPIO_BACKLIGHT); } - // init renderer - if ((pin[GPIO_SSPI_CS]<99) && (pin[GPIO_SSPI_MOSI]<99) && (pin[GPIO_SSPI_SCLK]<99)){ - ili9488 = new ILI9488(pin[GPIO_SSPI_CS],pin[GPIO_SSPI_MOSI],pin[GPIO_SSPI_SCLK],bppin); +#ifdef ESP32 +#undef HW_SPI_MOSI +#define HW_SPI_MOSI 23 +#undef HW_SPI_MISO +#define HW_SPI_MISO 19 +#undef HW_SPI_CLK +#define HW_SPI_CLK 18 +#else +#undef HW_SPI_MOSI +#define HW_SPI_MOSI 13 +#undef HW_SPI_MISO +#define HW_SPI_MISO 12 +#undef HW_SPI_CLK +#define HW_SPI_CLK 14 +#endif + + // init renderer, must use hardware spi + if (PinUsed(GPIO_SSPI_CS) && (Pin(GPIO_SSPI_MOSI)==HW_SPI_MOSI) && (Pin(GPIO_SSPI_SCLK)==HW_SPI_CLK)) { + ili9488 = new ILI9488(Pin(GPIO_SSPI_CS),Pin(GPIO_SSPI_MOSI),Pin(GPIO_SSPI_SCLK),bppin); } else { - if ((pin[GPIO_SPI_CS]<99) && (pin[GPIO_SPI_MOSI]<99) && (pin[GPIO_SPI_CLK]<99)) { - ili9488 = new ILI9488(pin[GPIO_SPI_CS],pin[GPIO_SPI_MOSI],pin[GPIO_SPI_CLK],bppin); + if (PinUsed(GPIO_SPI_CS) && (Pin(GPIO_SPI_MOSI)==HW_SPI_MOSI) && (Pin(GPIO_SPI_CLK)==HW_SPI_CLK)) { + ili9488 = new ILI9488(Pin(GPIO_SPI_CS),Pin(GPIO_SPI_MOSI),Pin(GPIO_SPI_CLK),bppin); } else { return; } } - SPI.begin(); ili9488->begin(); renderer = ili9488; renderer->DisplayInit(DISPLAY_INIT_MODE,Settings.display_size,Settings.display_rotate,Settings.display_font); diff --git a/tasmota/xdsp_09_SSD1351.ino b/tasmota/xdsp_09_SSD1351.ino index be7138f65..822025d16 100644 --- a/tasmota/xdsp_09_SSD1351.ino +++ b/tasmota/xdsp_09_SSD1351.ino @@ -60,18 +60,17 @@ void SSD1351_InitDriver() { bg_color = SSD1351_BLACK; // init renderer - if ((pin[GPIO_SSPI_CS]<99) && (pin[GPIO_SSPI_MOSI]<99) && (pin[GPIO_SSPI_SCLK]<99)){ - ssd1351 = new SSD1351(pin[GPIO_SSPI_CS],pin[GPIO_SSPI_MOSI],pin[GPIO_SSPI_SCLK]); + if (PinUsed(GPIO_SSPI_CS) && PinUsed(GPIO_SSPI_MOSI) && PinUsed(GPIO_SSPI_SCLK)){ + ssd1351 = new SSD1351(Pin(GPIO_SSPI_CS),Pin(GPIO_SSPI_MOSI),Pin(GPIO_SSPI_SCLK)); } else { - if ((pin[GPIO_SPI_CS]<99) && (pin[GPIO_SPI_MOSI]<99) && (pin[GPIO_SPI_CLK]<99)){ - ssd1351 = new SSD1351(pin[GPIO_SPI_CS],pin[GPIO_SPI_MOSI],pin[GPIO_SPI_CLK]); + if (PinUsed(GPIO_SPI_CS) && PinUsed(GPIO_SPI_MOSI) && PinUsed(GPIO_SPI_CLK)) { + ssd1351 = new SSD1351(Pin(GPIO_SPI_CS),Pin(GPIO_SPI_MOSI),Pin(GPIO_SPI_CLK)); } else { return; } } delay(100); - SPI.begin(); ssd1351->begin(); renderer = ssd1351; renderer->DisplayInit(DISPLAY_INIT_MODE,Settings.display_size,Settings.display_rotate,Settings.display_font); diff --git a/tasmota/xdsp_10_RA8876.ino b/tasmota/xdsp_10_RA8876.ino index 88f3ebad2..aa8e82f4d 100644 --- a/tasmota/xdsp_10_RA8876.ino +++ b/tasmota/xdsp_10_RA8876.ino @@ -71,12 +71,28 @@ void RA8876_InitDriver() fg_color = RA8876_WHITE; bg_color = RA8876_BLACK; +#ifdef ESP32 +#undef HW_SPI_MOSI +#define HW_SPI_MOSI 23 +#undef HW_SPI_MISO +#define HW_SPI_MISO 19 +#undef HW_SPI_CLK +#define HW_SPI_CLK 18 +#else +#undef HW_SPI_MOSI +#define HW_SPI_MOSI 13 +#undef HW_SPI_MISO +#define HW_SPI_MISO 12 +#undef HW_SPI_CLK +#define HW_SPI_CLK 14 +#endif + // init renderer, must use hardware spi - if ((pin[GPIO_SSPI_CS]<99) && (pin[GPIO_SSPI_MOSI]==13) && (pin[GPIO_SSPI_MISO]==12) && (pin[GPIO_SSPI_SCLK]==14)) { - ra8876 = new RA8876(pin[GPIO_SSPI_CS],pin[GPIO_SSPI_MOSI],pin[GPIO_SSPI_MISO],pin[GPIO_SSPI_SCLK],pin[GPIO_BACKLIGHT]); + if (PinUsed(GPIO_SSPI_CS) && (Pin(GPIO_SSPI_MOSI)==HW_SPI_MOSI) && (Pin(GPIO_SSPI_MISO)==HW_SPI_MISO) && (Pin(GPIO_SSPI_SCLK)==HW_SPI_CLK)) { + ra8876 = new RA8876(Pin(GPIO_SSPI_CS),Pin(GPIO_SSPI_MOSI),Pin(GPIO_SSPI_MISO),Pin(GPIO_SSPI_SCLK),Pin(GPIO_BACKLIGHT)); } else { - if ((pin[GPIO_SPI_CS]<99) && (pin[GPIO_SPI_MOSI]==13) && (pin[GPIO_SPI_MISO]==12) && (pin[GPIO_SPI_CLK]==14)) { - ra8876 = new RA8876(pin[GPIO_SPI_CS],pin[GPIO_SPI_MOSI],pin[GPIO_SPI_MISO],pin[GPIO_SPI_CLK],pin[GPIO_BACKLIGHT]); + if (PinUsed(GPIO_SPI_CS) && (Pin(GPIO_SPI_MOSI)==HW_SPI_MOSI) && (Pin(GPIO_SPI_MISO)==HW_SPI_MISO) && (Pin(GPIO_SPI_CLK)==HW_SPI_CLK)) { + ra8876 = new RA8876(Pin(GPIO_SPI_CS),Pin(GPIO_SPI_MOSI),Pin(GPIO_SPI_MISO),Pin(GPIO_SPI_CLK),Pin(GPIO_BACKLIGHT)); } else { return; } diff --git a/tasmota/xdsp_11_sevenseg.ino b/tasmota/xdsp_11_sevenseg.ino index 2e0a5b11e..20193e54e 100644 --- a/tasmota/xdsp_11_sevenseg.ino +++ b/tasmota/xdsp_11_sevenseg.ino @@ -189,7 +189,7 @@ void SevensegDrawStringAt(uint16_t x, uint16_t y, char *str, uint16_t color, uin #ifdef USE_DISPLAY_MODES1TO5 void SevensegTime(boolean time_24) { - + uint hours = RtcTime.hour; uint minutes = RtcTime.minute; uint second = RtcTime.second; @@ -239,8 +239,6 @@ void SevensegTime(boolean time_24) sevenseg.writeDisplay(); } -#endif // USE_DISPLAY_MODES1TO5 - void SevensegRefresh(void) // Every second { if (disp_power) { @@ -262,6 +260,8 @@ void SevensegRefresh(void) // Every second } } +#endif // USE_DISPLAY_MODES1TO5 + /*********************************************************************************************\ * Interface \*********************************************************************************************/ @@ -286,9 +286,11 @@ bool Xdsp11(uint8_t function) case FUNC_DISPLAY_CLEAR: SevensegClear(); break; +#ifdef USE_DISPLAY_MODES1TO5 case FUNC_DISPLAY_EVERY_SECOND: SevensegRefresh(); break; +#endif // USE_DISPLAY_MODES1TO5 case FUNC_DISPLAY_ONOFF: case FUNC_DISPLAY_POWER: SevensegOnOff(); @@ -301,6 +303,6 @@ bool Xdsp11(uint8_t function) return result; } -#endif // USE_DISPLAY_MATRIX +#endif // USE_DISPLAY_SEVENSEG #endif // USE_DISPLAY #endif // USE_I2C diff --git a/tasmota/xdsp_interface.ino b/tasmota/xdsp_interface.ino index f713bf2de..c92d6eceb 100644 --- a/tasmota/xdsp_interface.ino +++ b/tasmota/xdsp_interface.ino @@ -17,6 +17,7 @@ along with this program. If not, see . */ +#if defined(USE_I2C) || defined(USE_SPI) #ifdef USE_DISPLAY #ifdef XFUNC_PTR_IN_ROM @@ -137,3 +138,4 @@ bool XdspCall(uint8_t Function) } #endif // USE_DISPLAY +#endif // USE_I2C or USE_SPI diff --git a/tasmota/xlgt_01_ws2812.ino b/tasmota/xlgt_01_ws2812.ino index f6d332198..368567181 100644 --- a/tasmota/xlgt_01_ws2812.ino +++ b/tasmota/xlgt_01_ws2812.ino @@ -449,10 +449,10 @@ void Ws2812ShowScheme(void) void Ws2812ModuleSelected(void) { - if (pin[GPIO_WS2812] < 99) { // RGB led + if (PinUsed(GPIO_WS2812)) { // RGB led // For DMA, the Pin is ignored as it uses GPIO3 due to DMA hardware use. - strip = new NeoPixelBus(WS2812_MAX_LEDS, pin[GPIO_WS2812]); + strip = new NeoPixelBus(WS2812_MAX_LEDS, Pin(GPIO_WS2812)); strip->Begin(); Ws2812Clear(); diff --git a/tasmota/xlgt_02_my92x1.ino b/tasmota/xlgt_02_my92x1.ino index 69bccaf36..6d12abf84 100644 --- a/tasmota/xlgt_02_my92x1.ino +++ b/tasmota/xlgt_02_my92x1.ino @@ -115,9 +115,9 @@ bool My92x1SetChannels(void) void My92x1ModuleSelected(void) { - if ((pin[GPIO_DCKI] < 99) && (pin[GPIO_DI] < 99)) { - My92x1.pdi_pin = pin[GPIO_DI]; - My92x1.pdcki_pin = pin[GPIO_DCKI]; + if (PinUsed(GPIO_DCKI) && PinUsed(GPIO_DI)) { + My92x1.pdi_pin = Pin(GPIO_DI); + My92x1.pdcki_pin = Pin(GPIO_DCKI); pinMode(My92x1.pdi_pin, OUTPUT); pinMode(My92x1.pdcki_pin, OUTPUT); diff --git a/tasmota/xlgt_03_sm16716.ino b/tasmota/xlgt_03_sm16716.ino index 8332c80d1..314122a8b 100644 --- a/tasmota/xlgt_03_sm16716.ino +++ b/tasmota/xlgt_03_sm16716.ino @@ -100,9 +100,9 @@ void SM16716_Update(uint8_t duty_r, uint8_t duty_g, uint8_t duty_b) /* bool SM16716_ModuleSelected(void) { - Sm16716.pin_clk = pin[GPIO_SM16716_CLK]; - Sm16716.pin_dat = pin[GPIO_SM16716_DAT]; - Sm16716.pin_sel = pin[GPIO_SM16716_SEL]; + Sm16716.pin_clk = Pin(GPIO_SM16716_CLK); + Sm16716.pin_dat = Pin(GPIO_SM16716_DAT); + Sm16716.pin_sel = Pin(GPIO_SM16716_SEL); DEBUG_DRIVER_LOG(PSTR(D_LOG_SM16716 "ModuleSelected; clk_pin=%d, dat_pin=%d)"), Sm16716.pin_clk, Sm16716.pin_dat); return (Sm16716.pin_clk < 99) && (Sm16716.pin_dat < 99); } @@ -122,9 +122,9 @@ bool Sm16716SetChannels(void) /* // handle any PWM pins, skipping the first 3 values for sm16716 for (uint32_t i = 3; i < Light.subtype; i++) { - if (pin[GPIO_PWM1 +i-3] < 99) { + if (PinUsed(GPIO_PWM1, i-3)) { //AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION "Cur_Col%d 10 bits %d, Pwm%d %d"), i, cur_col[i], i+1, curcol); - analogWrite(pin[GPIO_PWM1 +i-3], bitRead(pwm_inverted, i-3) ? Settings.pwm_range - cur_col_10bits[i] : cur_col_10bits[i]); + analogWrite(Pin(GPIO_PWM1, i-3), bitRead(pwm_inverted, i-3) ? Settings.pwm_range - cur_col_10bits[i] : cur_col_10bits[i]); } } */ @@ -138,17 +138,17 @@ bool Sm16716SetChannels(void) void Sm16716ModuleSelected(void) { - if ((pin[GPIO_SM16716_CLK] < 99) && (pin[GPIO_SM16716_DAT] < 99)) { - Sm16716.pin_clk = pin[GPIO_SM16716_CLK]; - Sm16716.pin_dat = pin[GPIO_SM16716_DAT]; - Sm16716.pin_sel = pin[GPIO_SM16716_SEL]; + if (PinUsed(GPIO_SM16716_CLK) && PinUsed(GPIO_SM16716_DAT)) { + Sm16716.pin_clk = Pin(GPIO_SM16716_CLK); + Sm16716.pin_dat = Pin(GPIO_SM16716_DAT); + Sm16716.pin_sel = Pin(GPIO_SM16716_SEL); /* // init PWM for (uint32_t i = 0; i < Light.subtype; i++) { Settings.pwm_value[i] = 0; // Disable direct PWM control - if (pin[GPIO_PWM1 +i] < 99) { - pinMode(pin[GPIO_PWM1 +i], OUTPUT); + if (PinUsed(GPIO_PWM1, i)) { + pinMode(Pin(GPIO_PWM1, i), OUTPUT); } } */ diff --git a/tasmota/xlgt_04_sm2135.ino b/tasmota/xlgt_04_sm2135.ino index a77108dbb..e262395a8 100644 --- a/tasmota/xlgt_04_sm2135.ino +++ b/tasmota/xlgt_04_sm2135.ino @@ -134,9 +134,9 @@ bool Sm2135SetChannels(void) void Sm2135ModuleSelected(void) { - if ((pin[GPIO_SM2135_CLK] < 99) && (pin[GPIO_SM2135_DAT] < 99)) { - Sm2135.clk = pin[GPIO_SM2135_CLK]; - Sm2135.data = pin[GPIO_SM2135_DAT]; + if (PinUsed(GPIO_SM2135_CLK) && PinUsed(GPIO_SM2135_DAT)) { + Sm2135.clk = Pin(GPIO_SM2135_CLK); + Sm2135.data = Pin(GPIO_SM2135_DAT); pinMode(Sm2135.data, OUTPUT); digitalWrite(Sm2135.data, HIGH); diff --git a/tasmota/xlgt_05_sonoff_l1.ino b/tasmota/xlgt_05_sonoff_l1.ino index 3caf1b06d..295330142 100644 --- a/tasmota/xlgt_05_sonoff_l1.ino +++ b/tasmota/xlgt_05_sonoff_l1.ino @@ -221,7 +221,7 @@ bool SnfL1SetChannels(void) void SnfL1ModuleSelected(void) { if (SONOFF_L1 == my_module_type) { - if ((pin[GPIO_RXD] < 99) && (pin[GPIO_TXD] < 99)) { + if (PinUsed(GPIO_RXD) && PinUsed(GPIO_TXD)) { SetSerial(19200, TS_SERIAL_8N1); light_type = LT_RGB; diff --git a/tasmota/xlgt_06_electriq_moodl.ino b/tasmota/xlgt_06_electriq_moodl.ino index 7e972f968..57c493e64 100644 --- a/tasmota/xlgt_06_electriq_moodl.ino +++ b/tasmota/xlgt_06_electriq_moodl.ino @@ -70,7 +70,7 @@ bool ElectriqMoodLSetChannels(void) void ElectriqMoodLModuleSelected(void) { - if (pin[GPIO_ELECTRIQ_MOODL_TX] < 99) { + if (PinUsed(GPIO_ELECTRIQ_MOODL_TX)) { SetSerial(9600, TS_SERIAL_8N1); light_type = LT_RGBW; light_flg = XLGT_06; diff --git a/tasmota/xnrg_01_hlw8012.ino b/tasmota/xnrg_01_hlw8012.ino index 4cbe111cd..3a0873dd1 100644 --- a/tasmota/xnrg_01_hlw8012.ino +++ b/tasmota/xnrg_01_hlw8012.ino @@ -138,12 +138,12 @@ void HlwEvery200ms(void) } } - if (pin[GPIO_NRG_CF1] < 99) { + if (PinUsed(GPIO_NRG_CF1)) { Hlw.cf1_timer++; if (Hlw.cf1_timer >= 8) { Hlw.cf1_timer = 0; Hlw.select_ui_flag = (Hlw.select_ui_flag) ? false : true; - DigitalWrite(GPIO_NRG_SEL, Hlw.select_ui_flag); + DigitalWrite(GPIO_NRG_SEL, 0, Hlw.select_ui_flag); if (Hlw.cf1_pulse_counter) { cf1_pulse_length = Hlw.cf1_summed_pulse_length / Hlw.cf1_pulse_counter; @@ -233,38 +233,36 @@ void HlwSnsInit(void) Hlw.current_ratio = HLW_IREF; } - if (pin[GPIO_NRG_SEL] < 99) { - pinMode(pin[GPIO_NRG_SEL], OUTPUT); - digitalWrite(pin[GPIO_NRG_SEL], Hlw.select_ui_flag); + if (PinUsed(GPIO_NRG_SEL)) { + pinMode(Pin(GPIO_NRG_SEL), OUTPUT); + digitalWrite(Pin(GPIO_NRG_SEL), Hlw.select_ui_flag); } - if (pin[GPIO_NRG_CF1] < 99) { - pinMode(pin[GPIO_NRG_CF1], INPUT_PULLUP); - attachInterrupt(pin[GPIO_NRG_CF1], HlwCf1Interrupt, FALLING); + if (PinUsed(GPIO_NRG_CF1)) { + pinMode(Pin(GPIO_NRG_CF1), INPUT_PULLUP); + attachInterrupt(Pin(GPIO_NRG_CF1), HlwCf1Interrupt, FALLING); } - pinMode(pin[GPIO_HLW_CF], INPUT_PULLUP); - attachInterrupt(pin[GPIO_HLW_CF], HlwCfInterrupt, FALLING); + pinMode(Pin(GPIO_HLW_CF), INPUT_PULLUP); + attachInterrupt(Pin(GPIO_HLW_CF), HlwCfInterrupt, FALLING); } void HlwDrvInit(void) { Hlw.model_type = 0; // HLW8012 - if (pin[GPIO_HJL_CF] < 99) { - pin[GPIO_HLW_CF] = pin[GPIO_HJL_CF]; - pin[GPIO_HJL_CF] = 99; + if (PinUsed(GPIO_HJL_CF)) { + SetPin(Pin(GPIO_HJL_CF), AGPIO(GPIO_HLW_CF)); Hlw.model_type = 1; // HJL-01/BL0937 } - if (pin[GPIO_HLW_CF] < 99) { // HLW8012 or HJL-01 based device Power monitor + if (PinUsed(GPIO_HLW_CF)) { // HLW8012 or HJL-01 based device Power monitor Hlw.ui_flag = true; // Voltage on high - if (pin[GPIO_NRG_SEL_INV] < 99) { - pin[GPIO_NRG_SEL] = pin[GPIO_NRG_SEL_INV]; - pin[GPIO_NRG_SEL_INV] = 99; + if (PinUsed(GPIO_NRG_SEL_INV)) { + SetPin(Pin(GPIO_NRG_SEL_INV), AGPIO(GPIO_NRG_SEL)); Hlw.ui_flag = false; // Voltage on low } - if (pin[GPIO_NRG_CF1] < 99) { // Voltage and/or Current monitor - if (99 == pin[GPIO_NRG_SEL]) { // Voltage and/or Current selector + if (PinUsed(GPIO_NRG_CF1)) { // Voltage and/or Current monitor + if (!PinUsed(GPIO_NRG_SEL)) { // Voltage and/or Current selector Energy.current_available = false; // Assume Voltage } } else { diff --git a/tasmota/xnrg_02_cse7766.ino b/tasmota/xnrg_02_cse7766.ino index d7bb93665..9c8417bc6 100644 --- a/tasmota/xnrg_02_cse7766.ino +++ b/tasmota/xnrg_02_cse7766.ino @@ -23,6 +23,8 @@ * CSE7759 and CSE7766 - Energy (Sonoff S31 and Sonoff Pow R2) * HLW8032 - Energy (Blitzwolf SHP5) * + * Needs GPIO_CSE7766_RX only + * * Based on datasheet from http://www.chipsea.com/UploadFiles/2017/08/11144342F01B5662.pdf \*********************************************************************************************/ @@ -57,8 +59,7 @@ struct CSE { bool received = false; } Cse; -void CseReceived(void) -{ +void CseReceived(void) { // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 // F2 5A 02 F7 60 00 03 61 00 40 10 05 72 40 51 A6 58 63 10 1B E1 7F 4D 4E - F2 = Power cycle exceeds range - takes too long - No load // 55 5A 02 F7 60 00 03 5A 00 40 10 04 8B 9F 51 A6 58 18 72 75 61 AC A1 30 - 55 = Ok, 61 = Power not valid (load below 5W) @@ -67,7 +68,7 @@ void CseReceived(void) uint8_t header = Cse.rx_buffer[0]; if ((header & 0xFC) == 0xFC) { - AddLog_P(LOG_LEVEL_DEBUG, PSTR("CSE: Abnormal hardware")); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CSE: Abnormal hardware")); return; } @@ -140,8 +141,7 @@ void CseReceived(void) } } -bool CseSerialInput(void) -{ +bool CseSerialInput(void) { while (CseSerial->available()) { yield(); uint8_t serial_in_byte = CseSerial->read(); @@ -160,12 +160,12 @@ bool CseSerialInput(void) Cse.received = false; return true; } else { - AddLog_P(LOG_LEVEL_DEBUG, PSTR("CSE: " D_CHECKSUM_FAILURE)); do { // Sync buffer with data (issue #1907 and #3425) memmove(Cse.rx_buffer, Cse.rx_buffer +1, 24); Cse.byte_counter--; } while ((Cse.byte_counter > 2) && (0x5A != Cse.rx_buffer[1])); if (0x5A != Cse.rx_buffer[1]) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CSE: " D_CHECKSUM_FAILURE)); Cse.received = false; Cse.byte_counter = 0; } @@ -184,34 +184,31 @@ bool CseSerialInput(void) /********************************************************************************************/ -void CseEverySecond(void) -{ +void CseEverySecond(void) { if (Energy.data_valid[0] > ENERGY_WATCHDOG) { Cse.voltage_cycle = 0; Cse.current_cycle = 0; Cse.power_cycle = 0; } else { - long cf_frequency = 0; - if (CSE_PULSES_NOT_INITIALIZED == Cse.cf_pulses_last_time) { Cse.cf_pulses_last_time = Cse.cf_pulses; // Init after restart } else { - if (Cse.cf_pulses < Cse.cf_pulses_last_time) { // Rolled over after 65535 pulses - cf_frequency = (65536 - Cse.cf_pulses_last_time) + Cse.cf_pulses; + uint32_t cf_pulses = 0; + if (Cse.cf_pulses < Cse.cf_pulses_last_time) { // Rolled over after 0xFFFF (65535) pulses + cf_pulses = (0x10000 - Cse.cf_pulses_last_time) + Cse.cf_pulses; } else { - cf_frequency = Cse.cf_pulses - Cse.cf_pulses_last_time; + cf_pulses = Cse.cf_pulses - Cse.cf_pulses_last_time; } - if (cf_frequency && Energy.active_power[0]) { - unsigned long delta = (cf_frequency * Settings.energy_power_calibration) / 36; + if (cf_pulses && Energy.active_power[0]) { + uint32_t delta = (cf_pulses * Settings.energy_power_calibration) / 36; // prevent invalid load delta steps even checksum is valid (issue #5789): -// if (delta <= (3680*100/36) * 10 ) { // max load for S31/Pow R2: 3.68kW // prevent invalid load delta steps even checksum is valid but allow up to 4kW (issue #7155): - if (delta <= (4000*100/36) * 10 ) { // max load for S31/Pow R2: 4.00kW + if (delta <= (4000 * 1000 / 36)) { // max load for S31/Pow R2: 4.00kW Cse.cf_pulses_last_time = Cse.cf_pulses; Energy.kWhtoday_delta += delta; } else { - AddLog_P(LOG_LEVEL_DEBUG, PSTR("CSE: Load overflow")); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("CSE: Overload")); Cse.cf_pulses_last_time = CSE_PULSES_NOT_INITIALIZED; } EnergyUpdateToday(); @@ -220,11 +217,10 @@ void CseEverySecond(void) } } -void CseSnsInit(void) -{ +void CseSnsInit(void) { // Software serial init needs to be done here as earlier (serial) interrupts may lead to Exceptions -// CseSerial = new TasmotaSerial(pin[GPIO_CSE7766_RX], pin[GPIO_CSE7766_TX], 1); - CseSerial = new TasmotaSerial(pin[GPIO_CSE7766_RX], -1, 1); +// CseSerial = new TasmotaSerial(Pin(GPIO_CSE7766_RX), Pin(GPIO_CSE7766_TX), 1); + CseSerial = new TasmotaSerial(Pin(GPIO_CSE7766_RX), -1, 1); if (CseSerial->begin(4800, 2)) { // Fake Software Serial 8E1 by using two stop bits if (CseSerial->hardwareSerial()) { SetSerial(4800, TS_SERIAL_8E1); @@ -239,19 +235,17 @@ void CseSnsInit(void) } } -void CseDrvInit(void) -{ - Cse.rx_buffer = (uint8_t*)(malloc(CSE_BUFFER_SIZE)); - if (Cse.rx_buffer != nullptr) { -// if ((pin[GPIO_CSE7766_RX] < 99) && (pin[GPIO_CSE7766_TX] < 99)) { - if (pin[GPIO_CSE7766_RX] < 99) { +void CseDrvInit(void) { +// if (PinUsed(GPIO_CSE7766_RX) && PinUsed(GPIO_CSE7766_TX)) { + if (PinUsed(GPIO_CSE7766_RX)) { + Cse.rx_buffer = (uint8_t*)(malloc(CSE_BUFFER_SIZE)); + if (Cse.rx_buffer != nullptr) { energy_flg = XNRG_02; } } } -bool CseCommand(void) -{ +bool CseCommand(void) { bool serviced = true; if (CMND_POWERSET == Energy.command_code) { @@ -278,15 +272,14 @@ bool CseCommand(void) * Interface \*********************************************************************************************/ -bool Xnrg02(uint8_t function) -{ +bool Xnrg02(uint8_t function) { bool result = false; switch (function) { case FUNC_LOOP: if (CseSerial) { CseSerialInput(); } break; - case FUNC_ENERGY_EVERY_SECOND: + case FUNC_EVERY_SECOND: CseEverySecond(); break; case FUNC_COMMAND: diff --git a/tasmota/xnrg_03_pzem004t.ino b/tasmota/xnrg_03_pzem004t.ino index 466298b0f..f06b34b0e 100644 --- a/tasmota/xnrg_03_pzem004t.ino +++ b/tasmota/xnrg_03_pzem004t.ino @@ -241,7 +241,7 @@ void PzemEvery250ms(void) void PzemSnsInit(void) { // Software serial init needs to be done here as earlier (serial) interrupts may lead to Exceptions - PzemSerial = new TasmotaSerial(pin[GPIO_PZEM004_RX], pin[GPIO_PZEM0XX_TX], 1); + PzemSerial = new TasmotaSerial(Pin(GPIO_PZEM004_RX), Pin(GPIO_PZEM0XX_TX), 1); if (PzemSerial->begin(9600)) { if (PzemSerial->hardwareSerial()) { ClaimSerial(); @@ -256,7 +256,7 @@ void PzemSnsInit(void) void PzemDrvInit(void) { - if ((pin[GPIO_PZEM004_RX] < 99) && (pin[GPIO_PZEM0XX_TX] < 99)) { // Any device with a Pzem004T + if (PinUsed(GPIO_PZEM004_RX) && PinUsed(GPIO_PZEM0XX_TX)) { // Any device with a Pzem004T energy_flg = XNRG_03; } } diff --git a/tasmota/xnrg_04_mcp39f501.ino b/tasmota/xnrg_04_mcp39f501.ino index 92eec2013..b3f8dbe6c 100644 --- a/tasmota/xnrg_04_mcp39f501.ino +++ b/tasmota/xnrg_04_mcp39f501.ino @@ -562,7 +562,7 @@ void McpEverySecond(void) void McpSnsInit(void) { // Software serial init needs to be done here as earlier (serial) interrupts may lead to Exceptions - McpSerial = new TasmotaSerial(pin[GPIO_MCP39F5_RX], pin[GPIO_MCP39F5_TX], 1); + McpSerial = new TasmotaSerial(Pin(GPIO_MCP39F5_RX), Pin(GPIO_MCP39F5_TX), 1); if (McpSerial->begin(MCP_BAUDRATE)) { if (McpSerial->hardwareSerial()) { ClaimSerial(); @@ -570,7 +570,7 @@ void McpSnsInit(void) } else { mcp_buffer = (char*)(malloc(MCP_BUFFER_SIZE)); } - DigitalWrite(GPIO_MCP39F5_RST, 1); // MCP enable + DigitalWrite(GPIO_MCP39F5_RST, 0, 1); // MCP enable } else { energy_flg = ENERGY_NONE; } @@ -578,10 +578,10 @@ void McpSnsInit(void) void McpDrvInit(void) { - if ((pin[GPIO_MCP39F5_RX] < 99) && (pin[GPIO_MCP39F5_TX] < 99)) { - if (pin[GPIO_MCP39F5_RST] < 99) { - pinMode(pin[GPIO_MCP39F5_RST], OUTPUT); - digitalWrite(pin[GPIO_MCP39F5_RST], 0); // MCP disable - Reset Delta Sigma ADC's + if (PinUsed(GPIO_MCP39F5_RX) && PinUsed(GPIO_MCP39F5_TX)) { + if (PinUsed(GPIO_MCP39F5_RST)) { + pinMode(Pin(GPIO_MCP39F5_RST), OUTPUT); + digitalWrite(Pin(GPIO_MCP39F5_RST), 0); // MCP disable - Reset Delta Sigma ADC's } mcp_calibrate = 0; mcp_timeout = 2; // Initial wait diff --git a/tasmota/xnrg_05_pzem_ac.ino b/tasmota/xnrg_05_pzem_ac.ino index 86c4355aa..bd656a874 100644 --- a/tasmota/xnrg_05_pzem_ac.ino +++ b/tasmota/xnrg_05_pzem_ac.ino @@ -117,7 +117,7 @@ void PzemAcEverySecond(void) void PzemAcSnsInit(void) { - PzemAcModbus = new TasmotaModbus(pin[GPIO_PZEM016_RX], pin[GPIO_PZEM0XX_TX]); + PzemAcModbus = new TasmotaModbus(Pin(GPIO_PZEM016_RX), Pin(GPIO_PZEM0XX_TX)); uint8_t result = PzemAcModbus->Begin(9600); if (result) { if (2 == result) { ClaimSerial(); } @@ -130,7 +130,7 @@ void PzemAcSnsInit(void) void PzemAcDrvInit(void) { - if ((pin[GPIO_PZEM016_RX] < 99) && (pin[GPIO_PZEM0XX_TX] < 99)) { + if (PinUsed(GPIO_PZEM016_RX) && PinUsed(GPIO_PZEM0XX_TX)) { energy_flg = XNRG_05; } } diff --git a/tasmota/xnrg_06_pzem_dc.ino b/tasmota/xnrg_06_pzem_dc.ino index 961e4f854..444861fb0 100644 --- a/tasmota/xnrg_06_pzem_dc.ino +++ b/tasmota/xnrg_06_pzem_dc.ino @@ -113,7 +113,7 @@ void PzemDcEverySecond(void) void PzemDcSnsInit(void) { - PzemDcModbus = new TasmotaModbus(pin[GPIO_PZEM017_RX], pin[GPIO_PZEM0XX_TX]); + PzemDcModbus = new TasmotaModbus(Pin(GPIO_PZEM017_RX), Pin(GPIO_PZEM0XX_TX)); uint8_t result = PzemDcModbus->Begin(9600, 2); // Uses two stop bits!! if (result) { if (2 == result) { ClaimSerial(); } @@ -127,7 +127,7 @@ void PzemDcSnsInit(void) void PzemDcDrvInit(void) { - if ((pin[GPIO_PZEM017_RX] < 99) && (pin[GPIO_PZEM0XX_TX] < 99)) { + if (PinUsed(GPIO_PZEM017_RX) && PinUsed(GPIO_PZEM0XX_TX)) { energy_flg = XNRG_06; } } diff --git a/tasmota/xnrg_07_ade7953.ino b/tasmota/xnrg_07_ade7953.ino index 46f2ebd81..3d7b405d5 100644 --- a/tasmota/xnrg_07_ade7953.ino +++ b/tasmota/xnrg_07_ade7953.ino @@ -199,7 +199,7 @@ void Ade7953EnergyEverySecond(void) void Ade7953DrvInit(void) { - if (pin[GPIO_ADE7953_IRQ] < 99) { // Irq on GPIO16 is not supported... + if (PinUsed(GPIO_ADE7953_IRQ)) { // Irq on GPIO16 is not supported... delay(100); // Need 100mS to init ADE7953 if (I2cSetDevice(ADE7953_ADDR)) { if (HLW_PREF_PULSE == Settings.energy_power_calibration) { @@ -209,10 +209,9 @@ void Ade7953DrvInit(void) } I2cSetActiveFound(ADE7953_ADDR, "ADE7953"); Ade7953.init_step = 2; - Energy.phase_count = 2; // Handle two channels as two phases - Energy.voltage_common = true; // Use common voltage and frequency - + Energy.voltage_common = true; // Use common voltage + Energy.frequency_common = true; // Use common frequency energy_flg = XNRG_07; } } diff --git a/tasmota/xnrg_08_sdm120.ino b/tasmota/xnrg_08_sdm120.ino index e41323a73..8f764ad52 100644 --- a/tasmota/xnrg_08_sdm120.ino +++ b/tasmota/xnrg_08_sdm120.ino @@ -134,7 +134,7 @@ void SDM120Every250ms(void) break; case 9: - Energy.export_active = value; // 6.216 kWh + Energy.export_active[0] = value; // 6.216 kWh break; case 10: @@ -176,7 +176,7 @@ void SDM120Every250ms(void) void Sdm120SnsInit(void) { - Sdm120Modbus = new TasmotaModbus(pin[GPIO_SDM120_RX], pin[GPIO_SDM120_TX]); + Sdm120Modbus = new TasmotaModbus(Pin(GPIO_SDM120_RX), Pin(GPIO_SDM120_TX)); uint8_t result = Sdm120Modbus->Begin(SDM120_SPEED); if (result) { if (2 == result) { ClaimSerial(); } @@ -187,7 +187,7 @@ void Sdm120SnsInit(void) void Sdm120DrvInit(void) { - if ((pin[GPIO_SDM120_RX] < 99) && (pin[GPIO_SDM120_TX] < 99)) { + if (PinUsed(GPIO_SDM120_RX) && PinUsed(GPIO_SDM120_TX)) { energy_flg = XNRG_08; } } diff --git a/tasmota/xnrg_09_dds2382.ino b/tasmota/xnrg_09_dds2382.ino index aea1f03ea..7acb36f05 100644 --- a/tasmota/xnrg_09_dds2382.ino +++ b/tasmota/xnrg_09_dds2382.ino @@ -74,7 +74,7 @@ void Dds2382EverySecond(void) if (Settings.flag3.dds2382_model) { // SetOption71 - Select different Modbus registers for Active Energy (#6531) offset = 19; } - Energy.export_active = (float)((buffer[offset] << 24) + (buffer[offset +1] << 16) + (buffer[offset +2] << 8) + buffer[offset +3]) / 100.0; // 429496.729 kW + Energy.export_active[0] = (float)((buffer[offset] << 24) + (buffer[offset +1] << 16) + (buffer[offset +2] << 8) + buffer[offset +3]) / 100.0; // 429496.729 kW float import_active = (float)((buffer[offset +4] << 24) + (buffer[offset +5] << 16) + (buffer[offset +6] << 8) + buffer[offset +7]) / 100.0; // 429496.729 kW EnergyUpdateTotal(import_active, true); // 484.708 kWh @@ -91,7 +91,7 @@ void Dds2382EverySecond(void) void Dds2382SnsInit(void) { - Dds2382Modbus = new TasmotaModbus(pin[GPIO_DDS2382_RX], pin[GPIO_DDS2382_TX]); + Dds2382Modbus = new TasmotaModbus(Pin(GPIO_DDS2382_RX), Pin(GPIO_DDS2382_TX)); uint8_t result = Dds2382Modbus->Begin(DDS2382_SPEED); if (result) { if (2 == result) { ClaimSerial(); } @@ -102,7 +102,7 @@ void Dds2382SnsInit(void) void Dds2382DrvInit(void) { - if ((pin[GPIO_DDS2382_RX] < 99) && (pin[GPIO_DDS2382_TX] < 99)) { + if (PinUsed(GPIO_DDS2382_RX) && PinUsed(GPIO_DDS2382_TX)) { energy_flg = XNRG_09; } } diff --git a/tasmota/xnrg_10_sdm630.ino b/tasmota/xnrg_10_sdm630.ino index 81b8bdcbf..d239c1c73 100644 --- a/tasmota/xnrg_10_sdm630.ino +++ b/tasmota/xnrg_10_sdm630.ino @@ -40,22 +40,30 @@ TasmotaModbus *Sdm630Modbus; const uint16_t sdm630_start_addresses[] { - 0x0000, // L1 - SDM630_VOLTAGE [V] - 0x0002, // L2 - SDM630_VOLTAGE [V] - 0x0004, // L3 - SDM630_VOLTAGE [V] - 0x0006, // L1 - SDM630_CURRENT [A] - 0x0008, // L2 - SDM630_CURRENT [A] - 0x000A, // L3 - SDM630_CURRENT [A] - 0x000C, // L1 - SDM630_POWER [W] - 0x000E, // L2 - SDM630_POWER [W] - 0x0010, // L3 - SDM630_POWER [W] - 0x0018, // L1 - SDM630_REACTIVE_POWER [VAR] - 0x001A, // L2 - SDM630_REACTIVE_POWER [VAR] - 0x001C, // L3 - SDM630_REACTIVE_POWER [VAR] - 0x001E, // L1 - SDM630_POWER_FACTOR - 0x0020, // L2 - SDM630_POWER_FACTOR - 0x0022, // L3 - SDM630_POWER_FACTOR - 0x0156 // Total - SDM630_TOTAL_ACTIVE_ENERGY [Wh] + // 3P4 3P3 1P2 Unit Description + 0x0000, // + - + V Phase 1 line to neutral volts + 0x0002, // + - - V Phase 2 line to neutral volts + 0x0004, // + - - V Phase 3 line to neutral volts + 0x0006, // + + + A Phase 1 current + 0x0008, // + + - A Phase 2 current + 0x000A, // + + - A Phase 3 current + 0x000C, // + - + W Phase 1 power + 0x000E, // + - + W Phase 2 power + 0x0010, // + - - W Phase 3 power + 0x0018, // + - + VAr Phase 1 volt amps reactive + 0x001A, // + - - VAr Phase 2 volt amps reactive + 0x001C, // + - - VAr Phase 3 volt amps reactive + 0x001E, // + - + Phase 1 power factor + 0x0020, // + - - Phase 2 power factor + 0x0022, // + - - Phase 3 power factor + 0x0046, // + + + Hz Frequency of supply voltages + 0x0160, // + + + kWh Phase 1 export active energy + 0x0162, // + + + kWh Phase 2 export active energy + 0x0164, // + + + kWh Phase 3 export active energy +// 0x015A, // + + + kWh Phase 1 import active energy +// 0x015C, // + + + kWh Phase 2 import active energy +// 0x015E, // + + + kWh Phase 3 import active energy + 0x0156 // + + + kWh Total active energy }; struct SDM630 { @@ -153,6 +161,22 @@ void SDM630Every250ms(void) break; case 15: + Energy.frequency[0] = value; + break; + + case 16: + Energy.export_active[0] = value; + break; + + case 17: + Energy.export_active[1] = value; + break; + + case 18: + Energy.export_active[2] = value; + break; + + case 19: EnergyUpdateTotal(value, true); break; } @@ -174,11 +198,12 @@ void SDM630Every250ms(void) void Sdm630SnsInit(void) { - Sdm630Modbus = new TasmotaModbus(pin[GPIO_SDM630_RX], pin[GPIO_SDM630_TX]); + Sdm630Modbus = new TasmotaModbus(Pin(GPIO_SDM630_RX), Pin(GPIO_SDM630_TX)); uint8_t result = Sdm630Modbus->Begin(SDM630_SPEED); if (result) { if (2 == result) { ClaimSerial(); } Energy.phase_count = 3; + Energy.frequency_common = true; // Use common frequency } else { energy_flg = ENERGY_NONE; } @@ -186,7 +211,7 @@ void Sdm630SnsInit(void) void Sdm630DrvInit(void) { - if ((pin[GPIO_SDM630_RX] < 99) && (pin[GPIO_SDM630_TX] < 99)) { + if (PinUsed(GPIO_SDM630_RX) && PinUsed(GPIO_SDM630_TX)) { energy_flg = XNRG_10; } } diff --git a/tasmota/xnrg_11_ddsu666.ino b/tasmota/xnrg_11_ddsu666.ino index 6299f4f4a..f01ad50a5 100644 --- a/tasmota/xnrg_11_ddsu666.ino +++ b/tasmota/xnrg_11_ddsu666.ino @@ -110,7 +110,7 @@ void DDSU666Every250ms(void) break; case 7: - Energy.export_active = value; // 6.216 kWh + Energy.export_active[0] = value; // 6.216 kWh break; } @@ -133,7 +133,7 @@ void DDSU666Every250ms(void) void Ddsu666SnsInit(void) { - Ddsu666Modbus = new TasmotaModbus(pin[GPIO_DDSU666_RX], pin[GPIO_DDSU666_TX]); + Ddsu666Modbus = new TasmotaModbus(Pin(GPIO_DDSU666_RX), Pin(GPIO_DDSU666_TX)); uint8_t result = Ddsu666Modbus->Begin(DDSU666_SPEED); if (result) { if (2 == result) { ClaimSerial(); } @@ -144,7 +144,7 @@ void Ddsu666SnsInit(void) void Ddsu666DrvInit(void) { - if ((pin[GPIO_DDSU666_RX] < 99) && (pin[GPIO_DDSU666_TX] < 99)) { + if (PinUsed(GPIO_DDSU666_RX) && PinUsed(GPIO_DDSU666_TX)) { energy_flg = XNRG_11; } } diff --git a/tasmota/xnrg_12_solaxX1.ino b/tasmota/xnrg_12_solaxX1.ino index e9da3147d..418a92acb 100644 --- a/tasmota/xnrg_12_solaxX1.ino +++ b/tasmota/xnrg_12_solaxX1.ino @@ -406,10 +406,10 @@ void solaxX1250MSecond(void) // Every Second void solaxX1SnsInit(void) { AddLog_P(LOG_LEVEL_DEBUG, PSTR("SX1: Solax X1 Inverter Init")); - DEBUG_SENSOR_LOG(PSTR("SX1: RX pin: %d, TX pin: %d"), pin[GPIO_SOLAXX1_RX], pin[GPIO_SOLAXX1_TX]); + DEBUG_SENSOR_LOG(PSTR("SX1: RX pin: %d, TX pin: %d"), Pin(GPIO_SOLAXX1_RX), Pin(GPIO_SOLAXX1_TX)); protocolStatus.status = 0b00100000; // hasAddress - solaxX1Serial = new TasmotaSerial(pin[GPIO_SOLAXX1_RX], pin[GPIO_SOLAXX1_TX], 1); + solaxX1Serial = new TasmotaSerial(Pin(GPIO_SOLAXX1_RX), Pin(GPIO_SOLAXX1_TX), 1); if (solaxX1Serial->begin(SOLAXX1_SPEED)) { if (solaxX1Serial->hardwareSerial()) { ClaimSerial(); } } else { @@ -419,7 +419,7 @@ void solaxX1SnsInit(void) void solaxX1DrvInit(void) { - if ((pin[GPIO_SOLAXX1_RX] < 99) && (pin[GPIO_SOLAXX1_TX] < 99)) { + if (PinUsed(GPIO_SOLAXX1_RX) && PinUsed(GPIO_SOLAXX1_TX)) { energy_flg = XNRG_12; } } diff --git a/tasmota/xnrg_13_fif_le01mr.ino b/tasmota/xnrg_13_fif_le01mr.ino index 18f45065c..f8d25e06f 100644 --- a/tasmota/xnrg_13_fif_le01mr.ino +++ b/tasmota/xnrg_13_fif_le01mr.ino @@ -127,15 +127,15 @@ void FifLEEvery250ms(void) } else { Energy.data_valid[0] = 0; - // SA=Slave Address, FC=Function Code, BC=Byte Count, B3..B0=Data byte, Ch Cl = crc16 checksum + // CA=Client Address, FC=Function Code, BC=Byte Count, B3..B0=Data byte, Ch Cl = crc16 checksum // U32 registers: // 00 01 02 03 04 05 06 07 08 - // SA FC BC B3 B2 B1 B0 Cl Ch + // CA FC BC B3 B2 B1 B0 Cl Ch // 01 03 04 00 00 00 72 7A 16 = REG[B3..B2=0x0139,B1..B0=0x013A] 114 = 0.114 A // 01 03 04 00 00 00 B0 FB 87 = REG[B3..B2=0xA01E,B1..B0=0xA01F] 176 = 1.76 kvarh // U16/S16 registers: // 00 01 02 03 04 05 06 - // SA FC BC B1 B0 Cl Ch + // CA FC BC B1 B0 Cl Ch // 01 03 02 5B 02 02 B5 = REG[B1..B0=0x0131] 23298 = 232.98 V // 01 03 02 03 E8 B8 FA = REG[B1..B0=0x0158] 1000 = 1.000 (power factor) // there are 3 data types used: @@ -213,7 +213,7 @@ void FifLEEvery250ms(void) void FifLESnsInit(void) { - FifLEModbus = new TasmotaModbus(pin[GPIO_LE01MR_RX], pin[GPIO_LE01MR_TX]); + FifLEModbus = new TasmotaModbus(Pin(GPIO_LE01MR_RX), Pin(GPIO_LE01MR_TX)); uint8_t result = FifLEModbus->Begin(LE01MR_SPEED); if (result) { if (2 == result) { ClaimSerial(); } @@ -224,7 +224,7 @@ void FifLESnsInit(void) void FifLEDrvInit(void) { - if ((pin[GPIO_LE01MR_RX] < 99) && (pin[GPIO_LE01MR_TX] < 99)) { + if (PinUsed(GPIO_LE01MR_RX) && PinUsed(GPIO_LE01MR_TX)) { energy_flg = XNRG_13; } } diff --git a/tasmota/xnrg_14_bl0940.ino b/tasmota/xnrg_14_bl0940.ino new file mode 100644 index 000000000..fae36ea3a --- /dev/null +++ b/tasmota/xnrg_14_bl0940.ino @@ -0,0 +1,327 @@ +/* + xnrg_14_bl0940.ino - BL0940 energy sensor support for Tasmota + + Copyright (C) 2020 Theo Arends + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifdef USE_ENERGY_SENSOR +#ifdef USE_BL0940 +/*********************************************************************************************\ + * BL0940 - Energy (Blitzwolf SHP10) + * + * Template {"NAME":"BW-SHP10","GPIO":[0,148,0,207,158,21,0,0,0,17,0,0,0],"FLAG":0,"BASE":18} + * + * Based on datasheet from http://www.belling.com.cn/media/file_object/bel_product/BL0940/datasheet/BL0940_V1.1_en.pdf +\*********************************************************************************************/ + +#define XNRG_14 14 + +#define BL0940_PREF 1430 +#define BL0940_UREF 33000 +#define BL0940_IREF 2750 + +#define BL0940_PULSES_NOT_INITIALIZED -1 + +#define BL0940_BUFFER_SIZE 36 + +#define BL0940_WRITE_COMMAND 0xA0 // 0xA8 according to documentation +#define BL0940_REG_I_FAST_RMS_CTRL 0x10 +#define BL0940_REG_MODE 0x18 +#define BL0940_REG_SOFT_RESET 0x19 +#define BL0940_REG_USR_WRPROT 0x1A +#define BL0940_REG_TPS_CTRL 0x1B + +#define BL0940_READ_COMMAND 0x50 // 0x58 according to documentation +#define BL0940_FULL_PACKET 0xAA + +#define BL0940_PACKET_HEADER 0x55 // 0x58 according to documentation + +#include + +TasmotaSerial *Bl0940Serial = nullptr; + +struct BL0940 { + long voltage = 0; + long current = 0; + long power = 0; + long power_cycle_first = 0; + long cf_pulses = 0; + long cf_pulses_last_time = BL0940_PULSES_NOT_INITIALIZED; + float temperature; + + int byte_counter = 0; + uint16_t tps1 = 0; + uint8_t *rx_buffer = nullptr; + bool received = false; +} Bl0940; + +const uint8_t bl0940_init[5][6] = { + { BL0940_WRITE_COMMAND, BL0940_REG_SOFT_RESET, 0x5A, 0x5A, 0x5A, 0x38 }, // Reset to default + { BL0940_WRITE_COMMAND, BL0940_REG_USR_WRPROT, 0x55, 0x00, 0x00, 0xF0 }, // Enable User Operation Write + { BL0940_WRITE_COMMAND, BL0940_REG_MODE, 0x00, 0x10, 0x00, 0x37 }, // 0x0100 = CF_UNABLE energy pulse, AC_FREQ_SEL 50Hz, RMS_UPDATE_SEL 800mS + { BL0940_WRITE_COMMAND, BL0940_REG_TPS_CTRL, 0xFF, 0x47, 0x00, 0xFE }, // 0x47FF = Over-current and leakage alarm on, Automatic temperature measurement, Interval 100mS + { BL0940_WRITE_COMMAND, BL0940_REG_I_FAST_RMS_CTRL, 0x1C, 0x18, 0x00, 0x1B }}; // 0x181C = Half cycle, Fast RMS threshold 6172 + +void Bl0940Received(void) { + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 + // 55 F2 03 00 00 00 00 7E 02 00 D4 B0 72 AC 01 00 00 00 00 02 01 00 00 00 00 00 00 00 BA 01 00 FE 03 00 83 + // 55 88 02 00 49 00 00 FE 02 00 AF EF 71 D2 01 00 EB FF FF 49 01 00 00 00 00 02 00 00 CF 01 00 FE 03 00 9F + // 55 B9 33 00 DE 45 00 94 02 00 CF E4 70 63 02 00 6C 4C 00 13 01 00 09 00 00 00 00 00 E4 01 00 FE 03 00 72 + // Hd IFRms--- Current- Reserved Voltage- Reserved Power--- Reserved CF------ Reserved TPS1---- TPS2---- Ck + + uint16_t tps1 = Bl0940.rx_buffer[29] << 8 | Bl0940.rx_buffer[28]; // TPS1 unsigned + if ((Bl0940.rx_buffer[0] != BL0940_PACKET_HEADER) || // Bad header + (Bl0940.tps1 && ((tps1 < (Bl0940.tps1 -10)) || (tps1 > (Bl0940.tps1 +10)))) // Invalid temperature change + ) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("BL9: Invalid data")); + return; + } + + Bl0940.tps1 = tps1; + float t = ((170.0f/448.0f)*(((float)Bl0940.tps1/2.0f)-32.0f))-45.0f; + Bl0940.temperature = ConvertTemp(t); + + Bl0940.voltage = Bl0940.rx_buffer[12] << 16 | Bl0940.rx_buffer[11] << 8 | Bl0940.rx_buffer[10]; // V_RMS unsigned + Bl0940.current = Bl0940.rx_buffer[6] << 16 | Bl0940.rx_buffer[5] << 8 | Bl0940.rx_buffer[4]; // I_RMS unsigned + int32_t power = Bl0940.rx_buffer[18] << 24 | Bl0940.rx_buffer[17] << 16 | Bl0940.rx_buffer[16] << 8; // WATT signed + Bl0940.power = abs(power) >> 8; // WATT unsigned + int32_t cf_cnt = Bl0940.rx_buffer[24] << 24 | Bl0940.rx_buffer[23] << 16 | Bl0940.rx_buffer[22] << 8; // CF_CNT signed + Bl0940.cf_pulses = abs(cf_cnt) >> 8; + + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("BL9: U %d, I %d, P %d, C %d, T %d"), + Bl0940.voltage, Bl0940.current, Bl0940.power, Bl0940.cf_pulses, Bl0940.tps1); + + if (Energy.power_on) { // Powered on + Energy.voltage[0] = (float)Bl0940.voltage / Settings.energy_voltage_calibration; + if (power && (Bl0940.power > Settings.energy_power_calibration)) { // We need at least 1W + Energy.active_power[0] = (float)Bl0940.power / Settings.energy_power_calibration; + Energy.current[0] = (float)Bl0940.current / (Settings.energy_current_calibration * 100); + } else { + Energy.active_power[0] = 0; + Energy.current[0] = 0; + } + } else { // Powered off +// Bl0940.power_cycle_first = 0; + Energy.voltage[0] = 0; + Energy.active_power[0] = 0; + Energy.current[0] = 0; + } +} + +bool Bl0940SerialInput(void) { + while (Bl0940Serial->available()) { + yield(); + uint8_t serial_in_byte = Bl0940Serial->read(); + if (!Bl0940.received && (BL0940_PACKET_HEADER == serial_in_byte)) { + Bl0940.received = true; + Bl0940.byte_counter = 0; + } + if (Bl0940.received) { + Bl0940.rx_buffer[Bl0940.byte_counter++] = serial_in_byte; + if (BL0940_BUFFER_SIZE == Bl0940.byte_counter) { + + AddLogBuffer(LOG_LEVEL_DEBUG_MORE, Bl0940.rx_buffer, BL0940_BUFFER_SIZE -1); + + uint8_t checksum = BL0940_READ_COMMAND; + for (uint32_t i = 0; i < BL0940_BUFFER_SIZE -2; i++) { checksum += Bl0940.rx_buffer[i]; } + checksum ^= 0xFF; + if (checksum == Bl0940.rx_buffer[34]) { + Energy.data_valid[0] = 0; + Bl0940Received(); + Bl0940.received = false; + return true; + } else { + do { // Sync buffer with data (issue #1907 and #3425) + memmove(Bl0940.rx_buffer, Bl0940.rx_buffer +1, BL0940_BUFFER_SIZE -1); + Bl0940.byte_counter--; + } while ((Bl0940.byte_counter > 1) && (BL0940_PACKET_HEADER != Bl0940.rx_buffer[0])); + if (BL0940_PACKET_HEADER != Bl0940.rx_buffer[0]) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("BL9: " D_CHECKSUM_FAILURE)); + Bl0940.received = false; + Bl0940.byte_counter = 0; + } + } + } + } + } +} + +/********************************************************************************************/ + +void Bl0940EverySecond(void) { + if (Energy.data_valid[0] > ENERGY_WATCHDOG) { + Bl0940.voltage = 0; + Bl0940.current = 0; + Bl0940.power = 0; + } else { +/* + // Calculate energy by using active power + if (Energy.active_power[0]) { + Energy.kWhtoday_delta += (Energy.active_power[0] * 1000) / 36; + EnergyUpdateToday(); + } +*/ + // Calculate energy by using active energy pulse count + if (BL0940_PULSES_NOT_INITIALIZED == Bl0940.cf_pulses_last_time) { + Bl0940.cf_pulses_last_time = Bl0940.cf_pulses; // Init after restart + } else { + uint32_t cf_pulses = 0; + if (Bl0940.cf_pulses < Bl0940.cf_pulses_last_time) { // Rolled over after 0xFFFFFF (16777215) pulses + cf_pulses = (0x1000000 - Bl0940.cf_pulses_last_time) + Bl0940.cf_pulses; + } else { + cf_pulses = Bl0940.cf_pulses - Bl0940.cf_pulses_last_time; + } + if (cf_pulses && Energy.active_power[0]) { + uint32_t watt256 = (1638400 * 256) / Settings.energy_power_calibration; + uint32_t delta = (cf_pulses * watt256) / 36; + if (delta <= (4000 * 1000 / 36)) { // max load for SHP10: 4.00kW (3.68kW) + Bl0940.cf_pulses_last_time = Bl0940.cf_pulses; + Energy.kWhtoday_delta += delta; + } else { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("BL9: Overload")); + Bl0940.cf_pulses_last_time = BL0940_PULSES_NOT_INITIALIZED; + } + EnergyUpdateToday(); + } + } + + } + +// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("BL9: Poll")); + + Bl0940Serial->flush(); + Bl0940Serial->write(BL0940_READ_COMMAND); + Bl0940Serial->write(BL0940_FULL_PACKET); +} + +void Bl0940SnsInit(void) { + // Software serial init needs to be done here as earlier (serial) interrupts may lead to Exceptions + Bl0940Serial = new TasmotaSerial(Pin(GPIO_BL0940_RX), Pin(GPIO_TXD), 1); + if (Bl0940Serial->begin(4800, 1)) { + if (Bl0940Serial->hardwareSerial()) { + ClaimSerial(); + } + if (HLW_UREF_PULSE == Settings.energy_voltage_calibration) { + Settings.energy_voltage_calibration = BL0940_UREF; + Settings.energy_current_calibration = BL0940_IREF; + Settings.energy_power_calibration = BL0940_PREF; + } + + for (uint32_t i = 0; i < 5; i++) { + for (uint32_t j = 0; j < 6; j++) { + Bl0940Serial->write(bl0940_init[i][j]); +// Bl0940Serial->write(pgm_read_byte(bl0940_init + (6 * i) + j)); // Wrong byte order! + } + delay(1); + } + + } else { + energy_flg = ENERGY_NONE; + } +} + +void Bl0940DrvInit(void) { + if (PinUsed(GPIO_BL0940_RX) && PinUsed(GPIO_TXD)) { + Bl0940.rx_buffer = (uint8_t*)(malloc(BL0940_BUFFER_SIZE)); + if (Bl0940.rx_buffer != nullptr) { + energy_flg = XNRG_14; + } + } +} + +bool Bl0940Command(void) { + bool serviced = true; + + uint32_t value = (uint32_t)(CharToFloat(XdrvMailbox.data) * 100); // 1.23 = 123 + + if (CMND_POWERSET == Energy.command_code) { + if (XdrvMailbox.data_len && Bl0940.power) { + Settings.energy_power_calibration = (Bl0940.power * 100) / value; + } + } + else if (CMND_VOLTAGESET == Energy.command_code) { + if (XdrvMailbox.data_len && Bl0940.voltage) { + Settings.energy_voltage_calibration = (Bl0940.voltage * 100) / value; + } + } + else if (CMND_CURRENTSET == Energy.command_code) { + if (XdrvMailbox.data_len && Bl0940.current) { + Settings.energy_current_calibration = Bl0940.current / value; + } + } + else serviced = false; // Unknown command + + return serviced; +} + +void Bl0940Show(bool json) { + char temperature[33]; + dtostrfd(Bl0940.temperature, Settings.flag2.temperature_resolution, temperature); + + if (json) { + ResponseAppend_P(JSON_SNS_TEMP, "BL0940", temperature); + if (0 == tele_period) { +#ifdef USE_DOMOTICZ + DomoticzSensor(DZ_TEMP, temperature); +#endif // USE_DOMOTICZ +#ifdef USE_KNX + KnxSensor(KNX_TEMPERATURE, Bl0940.temperature); +#endif // USE_KNX + } +#ifdef USE_WEBSERVER + } else { + WSContentSend_PD(HTTP_SNS_TEMP, "", temperature, TempUnit()); +#endif // USE_WEBSERVER + } +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xnrg14(uint8_t function) { + bool result = false; + + switch (function) { + case FUNC_LOOP: + if (Bl0940Serial) { Bl0940SerialInput(); } + break; + case FUNC_EVERY_SECOND: + Bl0940EverySecond(); + break; + case FUNC_JSON_APPEND: + Bl0940Show(1); + break; +#ifdef USE_WEBSERVER + case FUNC_WEB_SENSOR: + Bl0940Show(0); + break; +#endif // USE_WEBSERVER + case FUNC_COMMAND: + result = Bl0940Command(); + break; + case FUNC_INIT: + Bl0940SnsInit(); + break; + case FUNC_PRE_INIT: + Bl0940DrvInit(); + break; + } + return result; +} + +#endif // USE_BL0940 +#endif // USE_ENERGY_SENSOR diff --git a/tasmota/xnrg_15_teleinfo.ino b/tasmota/xnrg_15_teleinfo.ino new file mode 100755 index 000000000..8d552d771 --- /dev/null +++ b/tasmota/xnrg_15_teleinfo.ino @@ -0,0 +1,488 @@ +/* + xnrg_15_Teleinfo.ino - Teleinfo support for Tasmota + + Copyright (C) 2020 Charles-Henri Hallard + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifdef USE_ENERGY_SENSOR +#ifdef USE_TELEINFO +/*********************************************************************************************\ + * Teleinfo : French energy provider metering telemety data + * Source: http://hallard.me/category/tinfo/ + * + * Denky ESP32 Teleinfo Template + * {"NAME":"Denky (Teleinfo)","GPIO":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1} + * + * Denky (aka WifInfo) ESP8266 Teleinfo Template + * {"NAME":"WifInfo","GPIO":[7,255,255,208,6,5,255,255,255,255,255,255,255],"FLAG":15,"BASE":18} + * +\*********************************************************************************************/ + +#define XNRG_15 15 + +#include "LibTeleinfo.h" +#include + +#define TINFO_READ_TIMEOUT 400 + +// All contract type +enum TInfoContrat{ + CONTRAT_BAS = 1, // BASE => Option Base. + CONTRAT_HC, // HC.. => Option Heures Creuses. + CONTRAT_EJP, // EJP. => Option EJP. + CONTRAT_BBR, // BBRx => Option Tempo + CONTRAT_END +}; + +// contract displayed name +const char kContratName[] PROGMEM = + "|Base|Heures Creuses|EJP|Bleu Blanc Rouge" + ; + +// Received current contract value +const char kContratValue[] PROGMEM = + "|BASE|HC..|EJP.|BBR" + ; + +// all tariff type +enum TInfoTarif{ + TARIF_TH = 1, + TARIF_HC, TARIF_HP, + TARIF_HN, TARIF_PM, + TARIF_CB, TARIF_CW, TARIF_CR, + TARIF_PB, TARIF_PW, TARIF_PR, + TARIF_END +}; + +// Received current tariff values +const char kTarifValue[] PROGMEM = + "|TH..|HC..|HP.." + "|HN..|PM.." + "|HCJB|HCJW|HCJR" + "|HPJB|HPJW|HPJR" + ; + +// tariff displayed name +const char kTarifName[] PROGMEM = + "|Toutes|Creuses|Pleines" + "|Normales|Pointe Mobile" + "|Creuses Bleu|Creuses Blanc|Creuse Rouges" + "|Pleines Bleu|Pleines Blanc|Pleines Rouges" + ; + +enum TInfoLabel{ + LABEL_BASE = 1, + LABEL_HCHC, LABEL_HCHP, + LABEL_OPTARIF, LABEL_ISOUSC, LABEL_PTEC, + LABEL_PAPP, LABEL_IINST, LABEL_IMAX, LABEL_TENSION, + LABEL_DEMAIN, + LABEL_END +}; + +const char kLabel[] PROGMEM = + "|BASE|HCHC|HCHP" + "|OPTARIF|ISOUSC|PTEC" + "|PAPP|IINST|IMAX|TENSION" + "|DEMAIN" + ; + +TInfo tinfo; // Teleinfo object +TasmotaSerial *TInfoSerial = nullptr; +bool tinfo_found = false; +uint8_t contrat; +uint8_t tarif; +uint8_t isousc; + +/*********************************************************************************************/ + +/* ====================================================================== +Function: getValueFromLabelIndex +Purpose : return label value from label index +Input : label index to search for +Output : value filled +Comments: - +====================================================================== */ +char * getValueFromLabelIndex(int labelIndex, char * value) +{ + char labelName[16]; + // Get the label name + GetTextIndexed(labelName, sizeof(labelName), labelIndex, kLabel); + // Get value of label name + return tinfo.valueGet(labelName, value) ; +} + +/* ====================================================================== +Function: ADPSCallback +Purpose : called by library when we detected a ADPS on any phased +Input : phase number + 0 for ADPS (monophase) + 1 for ADIR1 triphase + 2 for ADIR2 triphase + 3 for ADIR3 triphase +Output : - +Comments: should have been initialised in the main sketch with a + tinfo.attachADPSCallback(ADPSCallback()) +====================================================================== */ +void ADPSCallback(uint8_t phase) +{ + // n = phase number 1 to 3 + if (phase == 0){ + phase = 1; + } + AddLog_P2(LOG_LEVEL_INFO, PSTR("ADPS on phase %d"), phase); +} + +/* ====================================================================== +Function: DataCallback +Purpose : callback when we detected new or modified data received +Input : linked list pointer on the concerned data + current flags value +Output : - +Comments: - +====================================================================== */ +void DataCallback(struct _ValueList * me, uint8_t flags) +{ + char c = ' '; + int ilabel ; + + // Does this value is new or changed? + if (flags & (TINFO_FLAGS_ADDED | TINFO_FLAGS_UPDATED) ) { + char labelName[16]; + // Find the label index + for ( ilabel = 1 ; ilabel < LABEL_END ; ilabel++) { + GetTextIndexed(labelName, sizeof(labelName), ilabel, kLabel); + if (!strcmp(labelName, me->name)) { + break; + } + } + + // Current tariff + if (ilabel == LABEL_PTEC) + { + char tarif_value[] = " "; // 4 spaces + // Find the tariff index + for (tarif = TARIF_TH ; tarif < TARIF_END ; tarif++) { + GetTextIndexed(tarif_value, sizeof(tarif_value), tarif-1, kTarifValue); + if (!strcmp(tarif_value, me->value)) { + break; + } + } + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: Tarif changed, now '%s' (%d)"), me->value, tarif); + } + + // Voltage V (not present on all Smart Meter) + else if ( ilabel == LABEL_TENSION) + { + Energy.voltage_available = true; + Energy.voltage[0] = (float) atoi(me->value); + // Update current + if (Energy.voltage_available && Energy.voltage[0]) { + Energy.current[0] = Energy.active_power[0] / Energy.voltage[0] ; + } + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: Voltage %s, now %d"), me->value, (int) Energy.voltage[0]); + } + + // Current I + else if (ilabel == LABEL_IINST) + { + if (!Energy.voltage_available) { + Energy.current[0] = (float) atoi(me->value); + } else if (Energy.voltage[0]) { + Energy.current[0] = Energy.active_power[0] / Energy.voltage[0] ; + } + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: Current %s, now %d"), me->value, (int) Energy.current[0]); + } + + // Power P + else if (ilabel == LABEL_PAPP) + { + int papp = atoi(me->value); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: Power %s, now %d"), me->value, papp); + Energy.active_power[0] = (float) atoi(me->value); + // Update current + if (Energy.voltage_available && Energy.voltage[0]) { + Energy.current[0] = Energy.active_power[0] / Energy.voltage[0] ; + } + } + + // Wh indexes + else if ( ilabel == LABEL_HCHC || ilabel == LABEL_HCHP) + { + char value[32]; + uint32_t hc = 0; + uint32_t hp = 0; + uint32_t total = 0; + + if ( getValueFromLabelIndex(LABEL_HCHC, value) ) { hc = atoi(value);} + if ( getValueFromLabelIndex(LABEL_HCHP, value) ) { hp = atoi(value);} + total = hc + hp; + EnergyUpdateTotal(total/1000.0f, true); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: HC:%u HP:%u Total:%u"), hc, hp, total); + } + + // Contract subscribed + else if (ilabel == LABEL_OPTARIF) + { + char contrat_value[] = " "; // 4 spaces + // Find the contract index + for (contrat = CONTRAT_BAS ; contrat < CONTRAT_END ; contrat++) { + GetTextIndexed(contrat_value, sizeof(contrat_value), contrat, kContratValue); + if (!strcmp(contrat_value, me->value)) { + break; + } + } + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: Contract changed, now '%s' (%d)"), me->value, contrat); + } + + // Contract subscribed (Power) + else if (ilabel == LABEL_ISOUSC) + { + isousc = atoi( me->value); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: ISousc set to %d"), isousc); + } + + } + + if (flags & TINFO_FLAGS_ADDED) { c = '#'; } + if (flags & TINFO_FLAGS_UPDATED) { c = '*'; } + AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("TIC: %c %s=%s"),c , me->name, me->value); +} + +/* ====================================================================== +Function: NewFrameCallback +Purpose : callback when we received a complete Teleinfo frama +Input : linked list pointer on the concerned data +Output : - +Comments: - +====================================================================== */ +void NewFrameCallback(struct _ValueList * me) +{ + // Reset Energy Watchdog + Energy.data_valid[0] = 0; +} + + +/* ====================================================================== +Function: TInfoDrvInit +Purpose : Tasmota core driver init +Input : - +Output : - +Comments: - +====================================================================== */ +void TInfoDrvInit(void) { + if (PinUsed(GPIO_TELEINFO_RX)) { + energy_flg = XNRG_15; + Energy.voltage_available = false; + //Energy.current_available = false; + Energy.type_dc = true; + } +} + +/* ====================================================================== +Function: TInfoInit +Purpose : Tasmota core device init +Input : - +Output : - +Comments: - +====================================================================== */ +void TInfoInit(void) +{ + #ifdef USE_TELEINFO_STANDARD + #define TINFO_SPEED 9600 + #else + #define TINFO_SPEED 1200 + #endif + + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TIC: inferface speed %d bps"),TINFO_SPEED); + + if (PinUsed(GPIO_TELEINFO_RX)) { + uint8_t rx_pin = Pin(GPIO_TELEINFO_RX); + AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: RX on GPIO%d"), rx_pin); + + // Enable Teleinfo pin used, control it + if (PinUsed(GPIO_TELEINFO_ENABLE)) { + uint8_t en_pin = Pin(GPIO_TELEINFO_ENABLE); + pinMode(en_pin, OUTPUT); + digitalWrite(en_pin, HIGH); + AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: Enable with GPIO%d"), en_pin); + } else { + AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: always enabled")); + } + + TInfoSerial = new TasmotaSerial(rx_pin, -1, 1); + // pinMode(GPIO_TELEINFO_RX, INPUT_PULLUP); + + // Trick here even using SERIAL_7E1 or TS_SERIAL_7E1 + // this is not working, need to call SetSerialConfig after + if (TInfoSerial->begin(TINFO_SPEED)) { + // This is a hack, looks like begin does not take into account + // the TS_SERIAL_7E1 configuration so on ESP8266 this is + // working only on Serial RX pin (Hardware Serial) for now + SetSerialConfig(TS_SERIAL_7E1); + TInfoSerial->setTimeout(TINFO_READ_TIMEOUT); + +#if defined (ESP8266) + if (TInfoSerial->hardwareSerial() ) { + ClaimSerial(); + AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: using hardware serial")); + } else { + AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: using software serial")); + } + +#elif defined (ESP32) + AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: using ESP32 hardware serial")); +#endif + // Init teleinfo + tinfo.init(); + // Attach needed callbacks + tinfo.attachADPS(ADPSCallback); + tinfo.attachData(DataCallback); + tinfo.attachNewFrame(NewFrameCallback); + tinfo_found = true; + AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: Ready")); + } + } +} + +/* ====================================================================== +Function: TInfoEvery250ms +Purpose : Tasmota callback executed every 250ms +Input : - +Output : - +Comments: - +====================================================================== */ +void TInfoEvery250ms(void) +{ + char c; + if (!tinfo_found) + return; + + if (TInfoSerial->available()) { + //AddLog_P2(LOG_LEVEL_INFO, PSTR("TIC: received %d chars"), TInfoSerial->available()); + // We received some data? + while (TInfoSerial->available()>8) { + // get char + c = TInfoSerial->read(); + // data processing + tinfo.process(c); + } + } +} + +/* ====================================================================== +Function: TInfoShow +Purpose : Tasmota callback executed to send telemetry or WEB display +Input : - +Output : - +Comments: - +====================================================================== */ +#ifdef USE_WEBSERVER +const char HTTP_ENERGY_INDEX_TELEINFO[] PROGMEM = "{s}%s{m}%s " D_UNIT_WATTHOUR "{e}" ; +const char HTTP_ENERGY_PAPP_TELEINFO[] PROGMEM = "{s}" D_POWERUSAGE "{m}%d " D_UNIT_WATT "{e}" ; +const char HTTP_ENERGY_IINST_TELEINFO[] PROGMEM = "{s}" D_CURRENT "{m}%d " D_UNIT_AMPERE "{e}" ; +const char HTTP_ENERGY_TARIF_TELEINFO[] PROGMEM = "{s}Tarif en cours{m}Heures %s{e}" ; +const char HTTP_ENERGY_CONTRAT_TELEINFO[] PROGMEM = "{s}Contrat{m}%s %d" D_UNIT_AMPERE "{e}" ; +const char HTTP_ENERGY_LOAD_TELEINFO[] PROGMEM = "{s}Charge actuelle{m}%d" D_UNIT_PERCENT "{e}" ; +#endif // USE_WEBSERVER + +void TInfoShow(bool json) +{ + char name[32]; + char value[32]; + + // Since it's an Energy device , current, voltage and power are + // already present on the telemetry frame. No need to add here + // Just add the specific and missing ones there + if (json) + { + if ( getValueFromLabelIndex(LABEL_PTEC, value) ) { + ResponseAppend_P(PSTR(",\"" "TARIF" "\":\"%s\""), value); + } + + GetTextIndexed(name, sizeof(name), LABEL_ISOUSC, kLabel); + ResponseAppend_P(PSTR(",\"%s\":%d"), name, isousc); + + if ( getValueFromLabelIndex(LABEL_HCHC, value) ) { + GetTextIndexed(name, sizeof(name), LABEL_HCHC, kLabel); + ResponseAppend_P(PSTR(",\"%s\":\"%u\""), name, atoi(value)); + } + if ( getValueFromLabelIndex(LABEL_HCHP, value) ) { + GetTextIndexed(name, sizeof(name), LABEL_HCHP, kLabel); + ResponseAppend_P(PSTR(",\"%s\":\"%u\""),name , atoi(value)); + } + + if (isousc) { + ResponseAppend_P(PSTR(",\"Load\":\"%d\""),(int) ((Energy.current[0]*100.0f) / isousc)); + } + +#ifdef USE_WEBSERVER + } + else + { + if (getValueFromLabelIndex(LABEL_HCHC, value) ) { + GetTextIndexed(name, sizeof(name), LABEL_HCHC, kLabel); + WSContentSend_PD(HTTP_ENERGY_INDEX_TELEINFO, name, value); + } + if (getValueFromLabelIndex(LABEL_HCHP, value) ) { + GetTextIndexed(name, sizeof(name), LABEL_HCHP, kLabel); + WSContentSend_PD(HTTP_ENERGY_INDEX_TELEINFO, name, value); + } + if (tarif) { + GetTextIndexed(name, sizeof(name), tarif-1, kTarifName); + WSContentSend_PD(HTTP_ENERGY_TARIF_TELEINFO, name,value); + } + if (contrat) { + GetTextIndexed(name, sizeof(name), contrat, kContratName); + WSContentSend_PD(HTTP_ENERGY_CONTRAT_TELEINFO, name, isousc); + if (isousc) { + int percent = (int) ((Energy.current[0]*100.0f) / isousc) ; + WSContentSend_PD(HTTP_ENERGY_LOAD_TELEINFO, percent); + } + } +#endif // USE_WEBSERVER + } +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ +bool Xnrg15(uint8_t function) +{ + switch (function) + { + case FUNC_EVERY_250_MSECOND: + if (uptime > 4) { TInfoEvery250ms(); } + break; + case FUNC_JSON_APPEND: + TInfoShow(1); + break; + #ifdef USE_WEBSERVER + case FUNC_WEB_SENSOR: + TInfoShow(0); + break; + #endif // USE_WEBSERVER + case FUNC_INIT: + TInfoInit(); + break; + case FUNC_PRE_INIT: + TInfoDrvInit(); + break; + } + return false; +} + +#endif // USE_TELEINFO +#endif // USE_ENERGY_SENSOR \ No newline at end of file diff --git a/tasmota/xsns_01_counter.ino b/tasmota/xsns_01_counter.ino index 663d9413a..ae03ef324 100644 --- a/tasmota/xsns_01_counter.ino +++ b/tasmota/xsns_01_counter.ino @@ -44,6 +44,9 @@ struct COUNTER { bool any_counter = false; } Counter; +uint32_t last_cycle; +uint32_t cycle_time; + #ifndef ARDUINO_ESP8266_RELEASE_2_3_0 // Fix core 2.5.x ISR not in IRAM Exception void CounterUpdate(uint8_t index) ICACHE_RAM_ATTR; void CounterUpdate1(void) ICACHE_RAM_ATTR; @@ -59,7 +62,7 @@ void CounterUpdate(uint8_t index) if (Counter.pin_state) { // handle low and high debounce times when configured - if (digitalRead(pin[GPIO_CNTR1 +index]) == bitRead(Counter.pin_state, index)) { + if (digitalRead(Pin(GPIO_CNTR1, index)) == bitRead(Counter.pin_state, index)) { // new pin state to be ignored because debounce time was not met during last IRQ return; } @@ -75,7 +78,40 @@ void CounterUpdate(uint8_t index) Counter.timer_low_high[index] = time; Counter.pin_state ^= (1<= GPIO_CNTR1_NP) && (XdrvMailbox.index < (GPIO_CNTR1_NP + MAX_COUNTERS))) { - bitSet(Counter.no_pullup, XdrvMailbox.index - GPIO_CNTR1_NP); - XdrvMailbox.index -= (GPIO_CNTR1_NP - GPIO_CNTR1); + if ((XdrvMailbox.index >= AGPIO(GPIO_CNTR1_NP)) && (XdrvMailbox.index < (AGPIO(GPIO_CNTR1_NP) + MAX_COUNTERS))) { + bitSet(Counter.no_pullup, XdrvMailbox.index - AGPIO(GPIO_CNTR1_NP)); + XdrvMailbox.index -= (AGPIO(GPIO_CNTR1_NP) - AGPIO(GPIO_CNTR1)); return true; } return false; @@ -127,15 +163,15 @@ void CounterInit(void) function counter_callbacks[] = { CounterUpdate1, CounterUpdate2, CounterUpdate3, CounterUpdate4 }; for (uint32_t i = 0; i < MAX_COUNTERS; i++) { - if (pin[GPIO_CNTR1 +i] < 99) { + if (PinUsed(GPIO_CNTR1, i)) { Counter.any_counter = true; - pinMode(pin[GPIO_CNTR1 +i], bitRead(Counter.no_pullup, i) ? INPUT : INPUT_PULLUP); - if ((0 == Settings.pulse_counter_debounce_low) && (0 == Settings.pulse_counter_debounce_high)) { + pinMode(Pin(GPIO_CNTR1, i), bitRead(Counter.no_pullup, i) ? INPUT : INPUT_PULLUP); + if ((0 == Settings.pulse_counter_debounce_low) && (0 == Settings.pulse_counter_debounce_high) && !Settings.flag4.zerocross_dimmer) { Counter.pin_state = 0; - attachInterrupt(pin[GPIO_CNTR1 +i], counter_callbacks[i], FALLING); + attachInterrupt(Pin(GPIO_CNTR1, i), counter_callbacks[i], FALLING); } else { Counter.pin_state = 0x8f; - attachInterrupt(pin[GPIO_CNTR1 +i], counter_callbacks[i], CHANGE); + attachInterrupt(Pin(GPIO_CNTR1, i), counter_callbacks[i], CHANGE); } } } @@ -144,7 +180,7 @@ void CounterInit(void) void CounterEverySecond(void) { for (uint32_t i = 0; i < MAX_COUNTERS; i++) { - if (pin[GPIO_CNTR1 +i] < 99) { + if (PinUsed(GPIO_CNTR1, i)) { if (bitRead(Settings.pulse_counter_type, i)) { uint32_t time = micros() - Counter.timer[i]; if (time > 4200000000) { // 70 minutes @@ -158,7 +194,7 @@ void CounterEverySecond(void) void CounterSaveState(void) { for (uint32_t i = 0; i < MAX_COUNTERS; i++) { - if (pin[GPIO_CNTR1 +i] < 99) { + if (PinUsed(GPIO_CNTR1, i)) { Settings.pulse_counter[i] = RtcSettings.pulse_counter[i]; } } @@ -169,7 +205,7 @@ void CounterShow(bool json) bool header = false; uint8_t dsxflg = 0; for (uint32_t i = 0; i < MAX_COUNTERS; i++) { - if (pin[GPIO_CNTR1 +i] < 99) { + if (PinUsed(GPIO_CNTR1, i)) { char counter[33]; if (bitRead(Settings.pulse_counter_type, i)) { dtostrfd((double)RtcSettings.pulse_counter[i] / 1000000, 6, counter); @@ -213,7 +249,7 @@ void CounterShow(bool json) void CmndCounter(void) { if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_COUNTERS)) { - if ((XdrvMailbox.data_len > 0) && (pin[GPIO_CNTR1 + XdrvMailbox.index -1] < 99)) { + if ((XdrvMailbox.data_len > 0) && PinUsed(GPIO_CNTR1, XdrvMailbox.index -1)) { if ((XdrvMailbox.data[0] == '-') || (XdrvMailbox.data[0] == '+')) { RtcSettings.pulse_counter[XdrvMailbox.index -1] += XdrvMailbox.payload; Settings.pulse_counter[XdrvMailbox.index -1] += XdrvMailbox.payload; @@ -229,7 +265,7 @@ void CmndCounter(void) void CmndCounterType(void) { if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_COUNTERS)) { - if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1) && (pin[GPIO_CNTR1 + XdrvMailbox.index -1] < 99)) { + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1) && PinUsed(GPIO_CNTR1, XdrvMailbox.index -1)) { bitWrite(Settings.pulse_counter_type, XdrvMailbox.index -1, XdrvMailbox.payload &1); RtcSettings.pulse_counter[XdrvMailbox.index -1] = 0; Settings.pulse_counter[XdrvMailbox.index -1] = 0; diff --git a/tasmota/xsns_02_analog.ino b/tasmota/xsns_02_analog.ino index 038da9fa5..235a91bdd 100644 --- a/tasmota/xsns_02_analog.ino +++ b/tasmota/xsns_02_analog.ino @@ -166,18 +166,30 @@ void AdcGetCurrentPower(uint8_t factor) uint16_t analog = 0; uint16_t analog_min = 1023; uint16_t analog_max = 0; - for (uint32_t i = 0; i < samples; i++) { - analog = analogRead(A0); - if (analog < analog_min) { - analog_min = analog; + + if (0 == Settings.adc_param1) { + for (uint32_t i = 0; i < samples; i++) { + analog = analogRead(A0); + if (analog < analog_min) { + analog_min = analog; + } + if (analog > analog_max) { + analog_max = analog; + } + delay(1); } - if (analog > analog_max) { - analog_max = analog; + Adc.current = (float)(analog_max-analog_min) * ((float)(Settings.adc_param2) / 100000); + } + else { + analog = AdcRead(5); + if (analog > Settings.adc_param1) { + Adc.current = ((float)(analog) - (float)Settings.adc_param1) * ((float)(Settings.adc_param2) / 100000); + } + else { + Adc.current = 0; } - delay(1); } - Adc.current = (float)(analog_max-analog_min) * ((float)(Settings.adc_param2) / 100000); float power = Adc.current * (float)(Settings.adc_param3) / 10; uint32_t current_millis = millis(); Adc.energy = Adc.energy + ((power * (current_millis - Adc.previous_millis)) / 3600000000); @@ -305,11 +317,18 @@ void AdcShow(bool json) \*********************************************************************************************/ const char kAdcCommands[] PROGMEM = "|" // No prefix - D_CMND_ADC "|" D_CMND_ADCS "|" D_CMND_ADCPARAM; +#ifdef ESP8266 + D_CMND_ADC "|" D_CMND_ADCS "|" +#endif // ESP8266 + D_CMND_ADCPARAM; void (* const AdcCommand[])(void) PROGMEM = { - &CmndAdc, &CmndAdcs, &CmndAdcParam }; +#ifdef ESP8266 + &CmndAdc, &CmndAdcs, +#endif // ESP8266 + &CmndAdcParam }; +#ifdef ESP8266 void CmndAdc(void) { if (ValidAdc() && (XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < ADC0_END)) { @@ -334,6 +353,7 @@ void CmndAdcs(void) } ResponseJsonEndEnd(); } +#endif // ESP8266 void CmndAdcParam(void) { @@ -357,7 +377,7 @@ void CmndAdcParam(void) Settings.adc_param3 = (int)(CharToFloat(subStr(sub_string, XdrvMailbox.data, ",", 4)) * 10000); } if (ADC0_CT_POWER == XdrvMailbox.payload) { - if ((Settings.adc_param1 & CT_FLAG_ENERGY_RESET) > 0) { + if (((1 == Settings.adc_param1) & CT_FLAG_ENERGY_RESET) > 0) { Adc.energy = 0; Settings.adc_param1 ^= CT_FLAG_ENERGY_RESET; // Cancel energy reset flag } @@ -435,4 +455,4 @@ bool Xsns02(uint8_t function) return result; } -#endif // USE_ADC_VCC +#endif // USE_ADC_VCC \ No newline at end of file diff --git a/tasmota/xsns_05_ds18x20.ino b/tasmota/xsns_05_ds18x20.ino index 046fb11c4..a762014c7 100644 --- a/tasmota/xsns_05_ds18x20.ino +++ b/tasmota/xsns_05_ds18x20.ino @@ -304,10 +304,10 @@ void Ds18x20Init(void) { uint64_t ids[DS18X20_MAX_SENSORS]; - ds18x20_pin = pin[GPIO_DSB]; + ds18x20_pin = Pin(GPIO_DSB); - if (pin[GPIO_DSB_OUT] < 99) { - ds18x20_pin_out = pin[GPIO_DSB_OUT]; + if (PinUsed(GPIO_DSB_OUT)) { + ds18x20_pin_out = Pin(GPIO_DSB_OUT); ds18x20_dual_mode = true; // Dual pins mode as used by Shelly pinMode(ds18x20_pin_out, OUTPUT); pinMode(ds18x20_pin, Settings.flag3.ds18x20_internal_pullup ? INPUT_PULLUP : INPUT); // SetOption74 - Enable internal pullup for single DS18x20 sensor @@ -518,7 +518,7 @@ bool Xsns05(uint8_t function) { bool result = false; - if (pin[GPIO_DSB] < 99) { + if (PinUsed(GPIO_DSB)) { switch (function) { case FUNC_INIT: Ds18x20Init(); diff --git a/tasmota/xsns_06_dht.ino b/tasmota/xsns_06_dht.ino index 2edc4abfa..d2e47fe17 100644 --- a/tasmota/xsns_06_dht.ino +++ b/tasmota/xsns_06_dht.ino @@ -77,7 +77,8 @@ bool DhtRead(uint32_t sensor) delay(19); // minimum 18ms break; case GPIO_DHT22: // DHT21, DHT22, AM2301, AM2302, AM2321 - delay(2); // minimum 1ms +// delay(2); // minimum 1ms + delayMicroseconds(2000); // See https://github.com/arendst/Tasmota/pull/7468#issuecomment-647067015 break; case GPIO_SI7021: // iTead SI7021 delayMicroseconds(500); @@ -187,12 +188,12 @@ bool DhtRead(uint32_t sensor) bool DhtPinState() { - if ((XdrvMailbox.index >= GPIO_DHT11) && (XdrvMailbox.index <= GPIO_SI7021)) { + if ((XdrvMailbox.index >= AGPIO(GPIO_DHT11)) && (XdrvMailbox.index <= AGPIO(GPIO_SI7021))) { if (dht_sensors < DHT_MAX_SENSORS) { Dht[dht_sensors].pin = XdrvMailbox.payload; - Dht[dht_sensors].type = XdrvMailbox.index; + Dht[dht_sensors].type = BGPIO(XdrvMailbox.index); dht_sensors++; - XdrvMailbox.index = GPIO_DHT11; + XdrvMailbox.index = AGPIO(GPIO_DHT11); } else { XdrvMailbox.index = 0; } @@ -204,8 +205,8 @@ bool DhtPinState() void DhtInit(void) { if (dht_sensors) { - if (pin[GPIO_DHT11_OUT] < 99) { - dht_pin_out = pin[GPIO_DHT11_OUT]; + if (PinUsed(GPIO_DHT11_OUT)) { + dht_pin_out = Pin(GPIO_DHT11_OUT); dht_dual_mode = true; // Dual pins mode as used by Shelly dht_sensors = 1; // We only support one sensor in pseudo mode pinMode(dht_pin_out, OUTPUT); diff --git a/tasmota/xsns_07_sht1x.ino b/tasmota/xsns_07_sht1x.ino index 735802ca2..e58c5553f 100644 --- a/tasmota/xsns_07_sht1x.ino +++ b/tasmota/xsns_07_sht1x.ino @@ -159,8 +159,8 @@ bool ShtRead(void) void ShtDetect(void) { - sht_sda_pin = pin[GPIO_I2C_SDA]; - sht_scl_pin = pin[GPIO_I2C_SCL]; + sht_sda_pin = Pin(GPIO_I2C_SDA); + sht_scl_pin = Pin(GPIO_I2C_SCL); if (ShtRead()) { sht_type = 1; AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_I2C D_SHT1X_FOUND)); diff --git a/tasmota/xsns_08_htu21.ino b/tasmota/xsns_08_htu21.ino index e0cab5d1c..1dc4d4fb1 100644 --- a/tasmota/xsns_08_htu21.ino +++ b/tasmota/xsns_08_htu21.ino @@ -59,14 +59,18 @@ const char kHtuTypes[] PROGMEM = "HTU21|SI7013|SI7020|SI7021|T/RH?"; -uint8_t htu_address; -uint8_t htu_type = 0; -uint8_t htu_delay_temp; -uint8_t htu_delay_humidity = 50; -uint8_t htu_valid = 0; -float htu_temperature = 0; -float htu_humidity = 0; -char htu_types[7]; +struct { + float temperature = 0; + float humidity = 0; + uint8_t address; + uint8_t type = 0; + uint8_t delay_temp; + uint8_t delay_humidity = 50; + uint8_t valid = 0; + char types[7]; +} Htu; + +/*********************************************************************************************/ uint8_t HtuCheckCrc8(uint16_t data) { @@ -82,6 +86,8 @@ uint8_t HtuCheckCrc8(uint16_t data) uint8_t HtuReadDeviceId(void) { + HtuReset(); // Fixes ESP32 sensor loss at restart + uint16_t deviceID = 0; uint8_t checksum = 0; @@ -146,12 +152,12 @@ bool HtuRead(void) uint8_t checksum = 0; uint16_t sensorval = 0; - if (htu_valid) { htu_valid--; } + if (Htu.valid) { Htu.valid--; } Wire.beginTransmission(HTU21_ADDR); Wire.write(HTU21_READTEMP); if (Wire.endTransmission() != 0) { return false; } // In case of error - delay(htu_delay_temp); // Sensor time at max resolution + delay(Htu.delay_temp); // Sensor time at max resolution Wire.requestFrom(HTU21_ADDR, 3); if (3 == Wire.available()) { @@ -161,12 +167,12 @@ bool HtuRead(void) } if (HtuCheckCrc8(sensorval) != checksum) { return false; } // Checksum mismatch - htu_temperature = ConvertTemp(0.002681 * (float)sensorval - 46.85); + Htu.temperature = ConvertTemp(0.002681 * (float)sensorval - 46.85); Wire.beginTransmission(HTU21_ADDR); Wire.write(HTU21_READHUM); if (Wire.endTransmission() != 0) { return false; } // In case of error - delay(htu_delay_humidity); // Sensor time at max resolution + delay(Htu.delay_humidity); // Sensor time at max resolution Wire.requestFrom(HTU21_ADDR, 3); if (3 <= Wire.available()) { @@ -177,19 +183,19 @@ bool HtuRead(void) if (HtuCheckCrc8(sensorval) != checksum) { return false; } // Checksum mismatch sensorval ^= 0x02; // clear status bits - htu_humidity = 0.001907 * (float)sensorval - 6; - if (htu_humidity > 100) { htu_humidity = 100.0; } - if (htu_humidity < 0) { htu_humidity = 0.01; } + Htu.humidity = 0.001907 * (float)sensorval - 6; + if (Htu.humidity > 100) { Htu.humidity = 100.0; } + if (Htu.humidity < 0) { Htu.humidity = 0.01; } - if ((0.00 == htu_humidity) && (0.00 == htu_temperature)) { - htu_humidity = 0.0; + if ((0.00 == Htu.humidity) && (0.00 == Htu.temperature)) { + Htu.humidity = 0.0; } - if ((htu_temperature > 0.00) && (htu_temperature < 80.00)) { - htu_humidity = (-0.15) * (25 - htu_temperature) + htu_humidity; + if ((Htu.temperature > 0.00) && (Htu.temperature < 80.00)) { + Htu.humidity = (-0.15) * (25 - Htu.temperature) + Htu.humidity; } - htu_humidity = ConvertHumidity(htu_humidity); + Htu.humidity = ConvertHumidity(Htu.humidity); - htu_valid = SENSOR_MAX_MISS; + Htu.valid = SENSOR_MAX_MISS; return true; } @@ -197,17 +203,17 @@ bool HtuRead(void) void HtuDetect(void) { - htu_address = HTU21_ADDR; - if (I2cActive(htu_address)) { return; } + Htu.address = HTU21_ADDR; + if (I2cActive(Htu.address)) { return; } - htu_type = HtuReadDeviceId(); - if (htu_type) { + Htu.type = HtuReadDeviceId(); + if (Htu.type) { uint8_t index = 0; HtuInit(); - switch (htu_type) { + switch (Htu.type) { case HTU21_CHIPID: - htu_delay_temp = 50; - htu_delay_humidity = 16; + Htu.delay_temp = 50; + Htu.delay_humidity = 16; break; case SI7021_CHIPID: index++; // 3 @@ -215,16 +221,16 @@ void HtuDetect(void) index++; // 2 case SI7013_CHIPID: index++; // 1 - htu_delay_temp = 12; - htu_delay_humidity = 23; + Htu.delay_temp = 12; + Htu.delay_humidity = 23; break; default: index = 4; - htu_delay_temp = 50; - htu_delay_humidity = 23; + Htu.delay_temp = 50; + Htu.delay_humidity = 23; } - GetTextIndexed(htu_types, sizeof(htu_types), index, kHtuTypes); - I2cSetActiveFound(htu_address, htu_types); + GetTextIndexed(Htu.types, sizeof(Htu.types), index, kHtuTypes); + I2cSetActiveFound(Htu.address, Htu.types); } } @@ -233,15 +239,15 @@ void HtuEverySecond(void) if (uptime &1) { // Every 2 seconds // HTU21: 68mS, SI70xx: 37mS if (!HtuRead()) { - AddLogMissed(htu_types, htu_valid); + AddLogMissed(Htu.types, Htu.valid); } } } void HtuShow(bool json) { - if (htu_valid) { - TempHumDewShow(json, (0 == tele_period), htu_types, htu_temperature, htu_humidity); + if (Htu.valid) { + TempHumDewShow(json, (0 == tele_period), Htu.types, Htu.temperature, Htu.humidity); } } @@ -258,7 +264,7 @@ bool Xsns08(uint8_t function) if (FUNC_INIT == function) { HtuDetect(); } - else if (htu_type) { + else if (Htu.type) { switch (function) { case FUNC_EVERY_SECOND: HtuEverySecond(); diff --git a/tasmota/xsns_10_bh1750.ino b/tasmota/xsns_10_bh1750.ino index a098166df..2c3c801a7 100644 --- a/tasmota/xsns_10_bh1750.ino +++ b/tasmota/xsns_10_bh1750.ino @@ -22,6 +22,11 @@ /*********************************************************************************************\ * BH1750 - Ambient Light Intensity * + * Bh1750Resolution1 0..2 - Set BH1750 1 resolution mode + * Bh1750Resolution2 0..2 - Set BH1750 2 resolution mode + * Bh1750MTime1 30..255 - Set BH1750 1 MT register + * Bh1750MTime2 30..255 - Set BH1750 2 MT register + * * I2C Address: 0x23 or 0x5C \*********************************************************************************************/ @@ -38,119 +43,148 @@ #define BH1750_MEASUREMENT_TIME_HIGH 0x40 // Measurement Time register high 3 bits #define BH1750_MEASUREMENT_TIME_LOW 0x60 // Measurement Time register low 5 bits -struct BH1750DATA { - uint8_t address; +#define D_PRFX_BH1750 "Bh1750" +#define D_CMND_RESOLUTION "Resolution" +#define D_CMND_MTREG "MTime" + +const char kBh1750Commands[] PROGMEM = D_PRFX_BH1750 "|" // Prefix + D_CMND_RESOLUTION "|" D_CMND_MTREG ; + +void (* const Bh1750Command[])(void) PROGMEM = { + &CmndBh1750Resolution, &CmndBh1750MTime }; + +struct { uint8_t addresses[2] = { BH1750_ADDR1, BH1750_ADDR2 }; uint8_t resolution[3] = { BH1750_CONTINUOUS_HIGH_RES_MODE, BH1750_CONTINUOUS_HIGH_RES_MODE2, BH1750_CONTINUOUS_LOW_RES_MODE }; - uint8_t type = 0; - uint8_t valid = 0; - uint8_t mtreg = 69; // Default Measurement Time - uint16_t illuminance = 0; + uint8_t count = 0; char types[7] = "BH1750"; } Bh1750; +struct { + uint8_t address; + uint8_t valid = 0; + uint8_t mtreg = 69; // Default Measurement Time + uint16_t illuminance = 0; +} Bh1750_sensors[2]; + /*********************************************************************************************/ -bool Bh1750SetResolution(void) -{ - Wire.beginTransmission(Bh1750.address); - Wire.write(Bh1750.resolution[Settings.SensorBits1.bh1750_resolution]); +uint8_t Bh1750Resolution(uint32_t sensor_index) { + uint8_t settings_resolution = Settings.SensorBits1.bh1750_1_resolution; + if (1 == sensor_index) { + settings_resolution = Settings.SensorBits1.bh1750_2_resolution; + } + return settings_resolution; +} + +bool Bh1750SetResolution(uint32_t sensor_index) { + Wire.beginTransmission(Bh1750_sensors[sensor_index].address); + Wire.write(Bh1750.resolution[Bh1750Resolution(sensor_index)]); return (!Wire.endTransmission()); } -bool Bh1750SetMTreg(void) -{ - Wire.beginTransmission(Bh1750.address); - uint8_t data = BH1750_MEASUREMENT_TIME_HIGH | ((Bh1750.mtreg >> 5) & 0x07); +bool Bh1750SetMTreg(uint32_t sensor_index) { + Wire.beginTransmission(Bh1750_sensors[sensor_index].address); + uint8_t data = BH1750_MEASUREMENT_TIME_HIGH | ((Bh1750_sensors[sensor_index].mtreg >> 5) & 0x07); Wire.write(data); if (Wire.endTransmission()) { return false; } - Wire.beginTransmission(Bh1750.address); - data = BH1750_MEASUREMENT_TIME_LOW | (Bh1750.mtreg & 0x1F); + Wire.beginTransmission(Bh1750_sensors[sensor_index].address); + data = BH1750_MEASUREMENT_TIME_LOW | (Bh1750_sensors[sensor_index].mtreg & 0x1F); Wire.write(data); if (Wire.endTransmission()) { return false; } - return Bh1750SetResolution(); + return Bh1750SetResolution(sensor_index); } -bool Bh1750Read(void) -{ - if (Bh1750.valid) { Bh1750.valid--; } +bool Bh1750Read(uint32_t sensor_index) { + if (Bh1750_sensors[sensor_index].valid) { Bh1750_sensors[sensor_index].valid--; } + + if (2 != Wire.requestFrom(Bh1750_sensors[sensor_index].address, (uint8_t)2)) { return false; } - if (2 != Wire.requestFrom(Bh1750.address, (uint8_t)2)) { return false; } float illuminance = (Wire.read() << 8) | Wire.read(); - illuminance /= (1.2 * (69 / (float)Bh1750.mtreg)); - if (1 == Settings.SensorBits1.bh1750_resolution) { + illuminance /= (1.2 * (69 / (float)Bh1750_sensors[sensor_index].mtreg)); + if (1 == Bh1750Resolution(sensor_index)) { illuminance /= 2; } - Bh1750.illuminance = illuminance; + Bh1750_sensors[sensor_index].illuminance = illuminance; - Bh1750.valid = SENSOR_MAX_MISS; + Bh1750_sensors[sensor_index].valid = SENSOR_MAX_MISS; return true; } /********************************************************************************************/ -void Bh1750Detect(void) -{ +void Bh1750Detect(void) { for (uint32_t i = 0; i < sizeof(Bh1750.addresses); i++) { - Bh1750.address = Bh1750.addresses[i]; - if (I2cActive(Bh1750.address)) { continue; } + if (I2cActive(Bh1750.addresses[i])) { continue; } - if (Bh1750SetMTreg()) { - I2cSetActiveFound(Bh1750.address, Bh1750.types); - Bh1750.type = 1; - break; + Bh1750_sensors[Bh1750.count].address = Bh1750.addresses[i]; + if (Bh1750SetMTreg(Bh1750.count)) { + I2cSetActiveFound(Bh1750_sensors[Bh1750.count].address, Bh1750.types); + Bh1750.count++; } } } -void Bh1750EverySecond(void) -{ - // 1mS - if (!Bh1750Read()) { - AddLogMissed(Bh1750.types, Bh1750.valid); +void Bh1750EverySecond(void) { + for (uint32_t i = 0; i < Bh1750.count; i++) { + // 1mS + if (!Bh1750Read(i)) { +// AddLogMissed(Bh1750.types, Bh1750.valid); + } } } /*********************************************************************************************\ - * Command Sensor10 - * - * 0 - High resolution mode (default) - * 1 - High resolution mode 2 - * 2 - Low resolution mode - * 31..254 - Measurement Time value (not persistent, default is 69) + * Commands \*********************************************************************************************/ -bool Bh1750CommandSensor(void) -{ - if (XdrvMailbox.data_len) { +void CmndBh1750Resolution(void) { + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= Bh1750.count)) { if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 2)) { - Settings.SensorBits1.bh1750_resolution = XdrvMailbox.payload; - Bh1750SetResolution(); - } - else if ((XdrvMailbox.payload > 30) && (XdrvMailbox.payload < 255)) { - Bh1750.mtreg = XdrvMailbox.payload; - Bh1750SetMTreg(); + if (1 == XdrvMailbox.index) { + Settings.SensorBits1.bh1750_1_resolution = XdrvMailbox.payload; + } else { + Settings.SensorBits1.bh1750_2_resolution = XdrvMailbox.payload; + } + Bh1750SetResolution(XdrvMailbox.index -1); } + ResponseCmndIdxNumber(Bh1750Resolution(XdrvMailbox.index -1)); } - Response_P(PSTR("{\"" D_CMND_SENSOR "10\":{\"Resolution\":%d,\"MTime\":%d}}"), Settings.SensorBits1.bh1750_resolution, Bh1750.mtreg); - - return true; } -void Bh1750Show(bool json) -{ - if (Bh1750.valid) { - if (json) { - ResponseAppend_P(JSON_SNS_ILLUMINANCE, Bh1750.types, Bh1750.illuminance); -#ifdef USE_DOMOTICZ - if (0 == tele_period) { - DomoticzSensor(DZ_ILLUMINANCE, Bh1750.illuminance); +void CmndBh1750MTime(void) { + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= Bh1750.count)) { + if ((XdrvMailbox.payload > 30) && (XdrvMailbox.payload < 255)) { + Bh1750_sensors[XdrvMailbox.index -1].mtreg = XdrvMailbox.payload; + Bh1750SetMTreg(XdrvMailbox.index -1); + } + ResponseCmndIdxNumber(Bh1750_sensors[XdrvMailbox.index -1].mtreg); + } +} + +/********************************************************************************************/ + +void Bh1750Show(bool json) { + for (uint32_t sensor_index = 0; sensor_index < Bh1750.count; sensor_index++) { + if (Bh1750_sensors[sensor_index].valid) { + char sensor_name[10]; + strlcpy(sensor_name, Bh1750.types, sizeof(sensor_name)); + if (Bh1750.count > 1) { + snprintf_P(sensor_name, sizeof(sensor_name), PSTR("%s%c%02X"), sensor_name, IndexSeparator(), Bh1750_sensors[sensor_index].address); // BH1750-23 } + + if (json) { + ResponseAppend_P(JSON_SNS_ILLUMINANCE, sensor_name, Bh1750_sensors[sensor_index].illuminance); +#ifdef USE_DOMOTICZ + if ((0 == tele_period) && (0 == sensor_index)) { + DomoticzSensor(DZ_ILLUMINANCE, Bh1750_sensors[sensor_index].illuminance); + } #endif // USE_DOMOTICZ #ifdef USE_WEBSERVER - } else { - WSContentSend_PD(HTTP_SNS_ILLUMINANCE, Bh1750.types, Bh1750.illuminance); + } else { + WSContentSend_PD(HTTP_SNS_ILLUMINANCE, sensor_name, Bh1750_sensors[sensor_index].illuminance); #endif // USE_WEBSERVER + } } } } @@ -159,8 +193,7 @@ void Bh1750Show(bool json) * Interface \*********************************************************************************************/ -bool Xsns10(uint8_t function) -{ +bool Xsns10(uint8_t function) { if (!I2cEnabled(XI2C_11)) { return false; } bool result = false; @@ -168,15 +201,13 @@ bool Xsns10(uint8_t function) if (FUNC_INIT == function) { Bh1750Detect(); } - else if (Bh1750.type) { + else if (Bh1750.count) { switch (function) { case FUNC_EVERY_SECOND: Bh1750EverySecond(); break; - case FUNC_COMMAND_SENSOR: - if (XSNS_10 == XdrvMailbox.index) { - result = Bh1750CommandSensor(); - } + case FUNC_COMMAND: + result = DecodeCommand(kBh1750Commands, Bh1750Command); break; case FUNC_JSON_APPEND: Bh1750Show(1); diff --git a/tasmota/xsns_15_mhz19.ino b/tasmota/xsns_15_mhz19.ino index 633ca3f59..bc0ee8904 100644 --- a/tasmota/xsns_15_mhz19.ino +++ b/tasmota/xsns_15_mhz19.ino @@ -325,8 +325,8 @@ bool MhzCommandSensor(void) void MhzInit(void) { mhz_type = 0; - if ((pin[GPIO_MHZ_RXD] < 99) && (pin[GPIO_MHZ_TXD] < 99)) { - MhzSerial = new TasmotaSerial(pin[GPIO_MHZ_RXD], pin[GPIO_MHZ_TXD], 1); + if (PinUsed(GPIO_MHZ_RXD) && PinUsed(GPIO_MHZ_TXD)) { + MhzSerial = new TasmotaSerial(Pin(GPIO_MHZ_RXD), Pin(GPIO_MHZ_TXD), 1); if (MhzSerial->begin(9600)) { if (MhzSerial->hardwareSerial()) { ClaimSerial(); } mhz_type = 1; diff --git a/tasmota/xsns_17_senseair.ino b/tasmota/xsns_17_senseair.ino index 60614b4c7..90ba979bb 100644 --- a/tasmota/xsns_17_senseair.ino +++ b/tasmota/xsns_17_senseair.ino @@ -132,8 +132,8 @@ void Senseair250ms(void) // Every 250 mSec void SenseairInit(void) { senseair_type = 0; - if ((pin[GPIO_SAIR_RX] < 99) && (pin[GPIO_SAIR_TX] < 99)) { - SenseairModbus = new TasmotaModbus(pin[GPIO_SAIR_RX], pin[GPIO_SAIR_TX]); + if (PinUsed(GPIO_SAIR_RX) && PinUsed(GPIO_SAIR_TX)) { + SenseairModbus = new TasmotaModbus(Pin(GPIO_SAIR_RX), Pin(GPIO_SAIR_TX)); uint8_t result = SenseairModbus->Begin(SENSEAIR_MODBUS_SPEED); if (result) { if (2 == result) { ClaimSerial(); } diff --git a/tasmota/xsns_18_pms5003.ino b/tasmota/xsns_18_pms5003.ino index 0909921dc..d54527ddc 100644 --- a/tasmota/xsns_18_pms5003.ino +++ b/tasmota/xsns_18_pms5003.ino @@ -32,10 +32,40 @@ #include +#ifndef WARMUP_PERIOD +#define WARMUP_PERIOD 30 // Turn on PMSX003 XX-seconds before read in passive mode +#endif + +#ifndef MIN_INTERVAL_PERIOD +#define MIN_INTERVAL_PERIOD 60 // minimum interval period in seconds required for passive mode +#endif + TasmotaSerial *PmsSerial; -uint8_t pms_type = 1; -uint8_t pms_valid = 0; +struct PMS5003 { + uint16_t time = 0; + uint8_t type = 1; + uint8_t valid = 0; + uint8_t wake_mode = 1; + uint8_t ready = 1; +} Pms; + +enum PmsCommands +{ + CMD_MODE_ACTIVE, + CMD_SLEEP, + CMD_WAKEUP, + CMD_MODE_PASSIVE, + CMD_READ_DATA +}; + +const uint8_t kPmsCommands[][7] PROGMEM = { + // 0 1 2 3 4 5 6 + {0x42, 0x4D, 0xE1, 0x00, 0x01, 0x01, 0x71}, // pms_set_active_mode + {0x42, 0x4D, 0xE4, 0x00, 0x00, 0x01, 0x73}, // pms_sleep + {0x42, 0x4D, 0xE4, 0x00, 0x01, 0x01, 0x74}, // pms_wake + {0x42, 0x4D, 0xE1, 0x00, 0x00, 0x01, 0x70}, // pms_set_passive_mode + {0x42, 0x4D, 0xE2, 0x00, 0x00, 0x01, 0x71}}; // pms_passive_mode_read struct pmsX003data { uint16_t framelen; @@ -52,6 +82,13 @@ struct pmsX003data { /*********************************************************************************************/ +size_t PmsSendCmd(uint8_t command_id) +{ + return PmsSerial->write(kPmsCommands[command_id], sizeof(kPmsCommands[command_id])); +} + +/*********************************************************************************************/ + bool PmsReadData(void) { if (! PmsSerial->available()) { @@ -117,7 +154,42 @@ bool PmsReadData(void) #else memcpy((void *)&pms_data, (void *)buffer_u16, 30); #endif // PMS_MODEL_PMS3003 - pms_valid = 10; + Pms.valid = 10; + + return true; +} + +/*********************************************************************************************\ + * Command Sensor18 + * + * Warmup time for sensor is 30 seconds, therfore setting interval time to less than 60 + * seconds doesn't really make sense. + * + * 0 - 59 - Active Mode (continuous sensor readings) + * 60 .. 65535 - Passive Mode (read sensor every x seconds) +\*********************************************************************************************/ + +bool PmsCommandSensor(void) +{ + if (PinUsed(GPIO_PMS5003_TX) && (XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 32001)) { + if (XdrvMailbox.payload < MIN_INTERVAL_PERIOD) { + // Set Active Mode if interval is less than 60 seconds + Settings.pms_wake_interval = 0; + Pms.wake_mode = 1; + Pms.ready = 1; + PmsSendCmd(CMD_MODE_ACTIVE); + PmsSendCmd(CMD_WAKEUP); + } else { + // Set Passive Mode and schedule read once per interval time + Settings.pms_wake_interval = XdrvMailbox.payload; + PmsSendCmd(CMD_MODE_PASSIVE); + PmsSendCmd(CMD_SLEEP); + Pms.wake_mode = 0; + Pms.ready = 0; + } + } + + Response_P(S_JSON_SENSOR_INDEX_NVALUE, XSNS_18, Settings.pms_wake_interval); return true; } @@ -126,11 +198,38 @@ bool PmsReadData(void) void PmsSecond(void) // Every second { - if (PmsReadData()) { - pms_valid = 10; - } else { - if (pms_valid) { - pms_valid--; + if (Settings.pms_wake_interval >= MIN_INTERVAL_PERIOD) { + // Passive Mode + Pms.time++; + if ((Settings.pms_wake_interval - Pms.time <= WARMUP_PERIOD) && !Pms.wake_mode) { + // wakeup sensor WARMUP_PERIOD before read interval + Pms.wake_mode = 1; + PmsSendCmd(CMD_WAKEUP); + } + if (Pms.time >= Settings.pms_wake_interval) { + // sensor is awake and warmed up, set up for reading + PmsSendCmd(CMD_READ_DATA); + Pms.ready = 1; + Pms.time = 0; + } + } + + if (Pms.ready) { + if (PmsReadData()) { + Pms.valid = 10; + if (Settings.pms_wake_interval >= MIN_INTERVAL_PERIOD) { + PmsSendCmd(CMD_SLEEP); + Pms.wake_mode = 0; + Pms.ready = 0; + } + } else { + if (Pms.valid) { + Pms.valid--; + if (Settings.pms_wake_interval >= MIN_INTERVAL_PERIOD) { + PmsSendCmd(CMD_READ_DATA); + Pms.ready = 1; + } + } } } } @@ -139,12 +238,18 @@ void PmsSecond(void) // Every second void PmsInit(void) { - pms_type = 0; - if (pin[GPIO_PMS5003] < 99) { - PmsSerial = new TasmotaSerial(pin[GPIO_PMS5003], -1, 1); + Pms.type = 0; + if (PinUsed(GPIO_PMS5003_RX)) { + PmsSerial = new TasmotaSerial(Pin(GPIO_PMS5003_RX), (PinUsed(GPIO_PMS5003_TX)) ? Pin(GPIO_PMS5003_TX) : -1, 1); if (PmsSerial->begin(9600)) { if (PmsSerial->hardwareSerial()) { ClaimSerial(); } - pms_type = 1; + + if (!PinUsed(GPIO_PMS5003_TX)) { // setting interval not supported if TX pin not connected + Settings.pms_wake_interval = 0; + Pms.ready = 1; + } + + Pms.type = 1; } } } @@ -177,7 +282,7 @@ const char HTTP_PMS5003_SNS[] PROGMEM = void PmsShow(bool json) { - if (pms_valid) { + if (Pms.valid) { if (json) { #ifdef PMS_MODEL_PMS3003 ResponseAppend_P(PSTR(",\"PMS3003\":{\"CF1\":%d,\"CF2.5\":%d,\"CF10\":%d,\"PM1\":%d,\"PM2.5\":%d,\"PM10\":%d}"), @@ -222,7 +327,7 @@ bool Xsns18(uint8_t function) { bool result = false; - if (pms_type) { + if (Pms.type) { switch (function) { case FUNC_INIT: PmsInit(); @@ -230,6 +335,11 @@ bool Xsns18(uint8_t function) case FUNC_EVERY_SECOND: PmsSecond(); break; + case FUNC_COMMAND_SENSOR: + if (XSNS_18 == XdrvMailbox.index) { + result = PmsCommandSensor(); + } + break; case FUNC_JSON_APPEND: PmsShow(1); break; diff --git a/tasmota/xsns_20_novasds.ino b/tasmota/xsns_20_novasds.ino index 0b1580dde..ffaee14bc 100644 --- a/tasmota/xsns_20_novasds.ino +++ b/tasmota/xsns_20_novasds.ino @@ -202,8 +202,8 @@ bool NovaSdsCommandSensor(void) void NovaSdsInit(void) { novasds_type = 0; - if (pin[GPIO_SDS0X1_RX] < 99 && pin[GPIO_SDS0X1_TX] < 99) { - NovaSdsSerial = new TasmotaSerial(pin[GPIO_SDS0X1_RX], pin[GPIO_SDS0X1_TX], 1); + if (PinUsed(GPIO_SDS0X1_RX) && PinUsed(GPIO_SDS0X1_TX)) { + NovaSdsSerial = new TasmotaSerial(Pin(GPIO_SDS0X1_RX), Pin(GPIO_SDS0X1_TX), 1); if (NovaSdsSerial->begin(9600)) { if (NovaSdsSerial->hardwareSerial()) { ClaimSerial(); diff --git a/tasmota/xsns_21_sgp30.ino b/tasmota/xsns_21_sgp30.ino index e3aa2e9e8..6f52f14a4 100644 --- a/tasmota/xsns_21_sgp30.ino +++ b/tasmota/xsns_21_sgp30.ino @@ -55,7 +55,7 @@ void sgp30_Init(void) //#define POW_FUNC pow #define POW_FUNC FastPrecisePow -float sgp30_AbsoluteHumidity(float temperature, float humidity,char tempUnit) { +float sgp30_AbsoluteHumidity(float temperature, float humidity) { //taken from https://carnotcycle.wordpress.com/2012/08/04/how-to-convert-relative-humidity-to-absolute-humidity/ //precision is about 0.1°C in range -30 to 35°C //August-Roche-Magnus 6.1094 exp(17.625 x T)/(T + 243.04) @@ -69,10 +69,6 @@ float sgp30_AbsoluteHumidity(float temperature, float humidity,char tempUnit) { return NAN; } - if (tempUnit != 'C') { - temperature = (temperature - 32.0) * (5.0 / 9.0); /*conversion to [°C]*/ - } - temp = POW_FUNC(2.718281828, (17.67 * temperature) / (temperature + 243.5)); //return (6.112 * temp * humidity * 2.1674) / (273.15 + temperature); //simplified version @@ -87,9 +83,9 @@ void Sgp30Update(void) // Perform every second to ensure proper operation of th if (!sgp.IAQmeasure()) { return; // Measurement failed } - if (global_update && (global_humidity > 0) && (global_temperature != 9999)) { + if (global_update && (global_humidity > 0) && !isnan(global_temperature_celsius)) { // abs hum in mg/m3 - sgp30_abshum=sgp30_AbsoluteHumidity(global_temperature,global_humidity,TempUnit()); + sgp30_abshum = sgp30_AbsoluteHumidity(global_temperature_celsius, global_humidity); sgp.setHumidity(sgp30_abshum*1000); } sgp30_ready = true; @@ -119,11 +115,13 @@ void Sgp30Show(bool json) if (sgp30_ready) { char abs_hum[33]; - if (json) { - ResponseAppend_P(PSTR(",\"SGP30\":{\"" D_JSON_ECO2 "\":%d,\"" D_JSON_TVOC "\":%d"), sgp.eCO2, sgp.TVOC); - if (global_update && global_humidity>0 && global_temperature!=9999) { + if (global_update && (global_humidity > 0) && !isnan(global_temperature_celsius)) { // has humidity + temperature dtostrfd(sgp30_abshum,4,abs_hum); + } + if (json) { + ResponseAppend_P(PSTR(",\"SGP30\":{\"" D_JSON_ECO2 "\":%d,\"" D_JSON_TVOC "\":%d"), sgp.eCO2, sgp.TVOC); + if (global_update && global_humidity>0 && !isnan(global_temperature_celsius)) { ResponseAppend_P(PSTR(",\"" D_JSON_AHUM "\":%s"),abs_hum); } ResponseJsonEnd(); diff --git a/tasmota/xsns_22_sr04.ino b/tasmota/xsns_22_sr04.ino index 636992a57..187a67c3f 100644 --- a/tasmota/xsns_22_sr04.ino +++ b/tasmota/xsns_22_sr04.ino @@ -32,40 +32,39 @@ #define XSNS_22 22 uint8_t sr04_type = 1; -int sr04_echo_pin = 0; -int sr04_trig_pin = 0; real64_t distance; NewPing* sonar = nullptr; TasmotaSerial* sonar_serial = nullptr; - - uint8_t Sr04TModeDetect(void) { sr04_type = 0; - if (pin[GPIO_SR04_ECHO]>=99) return sr04_type; + if (!PinUsed(GPIO_SR04_ECHO)) { return sr04_type; } - sr04_echo_pin = pin[GPIO_SR04_ECHO]; - sr04_trig_pin = (pin[GPIO_SR04_TRIG] < 99) ? pin[GPIO_SR04_TRIG] : -1; + int sr04_echo_pin = Pin(GPIO_SR04_ECHO); + int sr04_trig_pin = (PinUsed(GPIO_SR04_TRIG)) ? Pin(GPIO_SR04_TRIG) : Pin(GPIO_SR04_ECHO); // if GPIO_SR04_TRIG is not configured use single PIN mode with GPIO_SR04_ECHO only sonar_serial = new TasmotaSerial(sr04_echo_pin, sr04_trig_pin, 1); if (sonar_serial->begin(9600,1)) { DEBUG_SENSOR_LOG(PSTR("SR04: Detect mode")); - if (sr04_trig_pin!=-1) { - sr04_type = (Sr04TMiddleValue(Sr04TMode3Distance(),Sr04TMode3Distance(),Sr04TMode3Distance())!=NO_ECHO)?3:1; + if (sr04_trig_pin != -1) { + sr04_type = (Sr04TMiddleValue(Sr04TMode3Distance(), Sr04TMode3Distance(), Sr04TMode3Distance()) != NO_ECHO) ? 3 : 1; } else { - sr04_type = 2; + sr04_type = 2; } } else { sr04_type = 1; } if (sr04_type < 2) { - delete sonar_serial; - sonar_serial = nullptr; - sonar = new NewPing(sr04_trig_pin, sr04_echo_pin, 300); + delete sonar_serial; + sonar_serial = nullptr; + if (-1 == sr04_trig_pin) { + sr04_trig_pin = Pin(GPIO_SR04_ECHO); // if GPIO_SR04_TRIG is not configured use single PIN mode with GPIO_SR04_ECHO only + } + sonar = new NewPing(sr04_trig_pin, sr04_echo_pin, 300); } else { if (sonar_serial->hardwareSerial()) { ClaimSerial(); @@ -194,7 +193,7 @@ bool Xsns22(uint8_t function) if (sr04_type) { switch (function) { case FUNC_INIT: - result = (pin[GPIO_SR04_ECHO]<99); + result = (PinUsed(GPIO_SR04_ECHO)); break; case FUNC_EVERY_SECOND: Sr04TReading(); diff --git a/tasmota/xsns_26_lm75ad.ino b/tasmota/xsns_26_lm75ad.ino index 5b735dcb7..d5073f759 100644 --- a/tasmota/xsns_26_lm75ad.ino +++ b/tasmota/xsns_26_lm75ad.ino @@ -89,7 +89,7 @@ void LM75ADShow(bool json) dtostrfd(t, Settings.flag2.temperature_resolution, temperature); if (json) { - ResponseAppend_P(PSTR(",\"LM75AD\":{\"" D_JSON_TEMPERATURE "\":%s}"), temperature); + ResponseAppend_P(JSON_SNS_TEMP, "LM75AD", temperature); #ifdef USE_DOMOTICZ if (0 == tele_period) DomoticzSensor(DZ_TEMP, temperature); #endif // USE_DOMOTICZ diff --git a/tasmota/xsns_27_apds9960.ino b/tasmota/xsns_27_apds9960.ino index c426d535a..e0fe1acaf 100644 --- a/tasmota/xsns_27_apds9960.ino +++ b/tasmota/xsns_27_apds9960.ino @@ -33,65 +33,76 @@ * Source: Shawn Hymel (SparkFun Electronics) * Adaption for TASMOTA: Christian Baars * - * I2C Address: 0x39 + * I2C Address: 0x39 - standard address \*********************************************************************************************/ -#define XSNS_27 27 -#define XI2C_21 21 // See I2CDEVICES.md +// #if defined(USE_SHT) || defined(USE_VEML6070) || defined(USE_TSL2561) +// #warning **** Turned off conflicting drivers SHT and VEML6070 **** +// #ifdef USE_SHT +// #undef USE_SHT // SHT-Driver blocks gesture sensor +// #endif +// #ifdef USE_VEML6070 +// #undef USE_VEML6070 // address conflict on the I2C-bus +// #endif +// #ifdef USE_TSL2561 +// #undef USE_TSL2561 // possible address conflict on the I2C-bus +// #endif +// #endif + +#define XSNS_27 27 +#define XI2C_21 21 // See I2CDEVICES.md -#if defined(USE_SHT) || defined(USE_VEML6070) || defined(USE_TSL2561) - #warning **** Turned off conflicting drivers SHT and VEML6070 **** - #ifdef USE_SHT - #undef USE_SHT // SHT-Driver blocks gesture sensor - #endif - #ifdef USE_VEML6070 - #undef USE_VEML6070 // address conflict on the I2C-bus - #endif - #ifdef USE_TSL2561 - #undef USE_TSL2561 // possible address conflict on the I2C-bus - #endif -#endif #define APDS9960_I2C_ADDR 0x39 #define APDS9960_CHIPID_1 0xAB #define APDS9960_CHIPID_2 0x9C +#define APDS9960_CHIPID_3 0xA8 #define APDS9930_CHIPID_1 0x12 // we will check, if someone got an incorrect sensor #define APDS9930_CHIPID_2 0x39 // there are case reports about "accidentially bought" 9930's +#define APDS9960_MODE_GESTURE 0 +#define APDS9960_MODE_COLOR 1 + /* Gesture parameters */ -#define GESTURE_THRESHOLD_OUT 10 -#define GESTURE_SENSITIVITY_1 50 -#define GESTURE_SENSITIVITY_2 20 +#define GESTURE_THRESHOLD_OUT 10 +#define GESTURE_SENSITIVITY_1 50 +#define GESTURE_SENSITIVITY_2 20 -uint8_t APDS9960addr; -uint8_t APDS9960type = 0; -char APDS9960stype[] = "APDS9960"; -char currentGesture[6]; -uint8_t gesture_mode = 1; +#define APDS9960_LONG_RECOVERY 50 // long pause after sensor overload in loops +#define APDS9960_MAX_GESTURE_CYCLES 50 // how many FIFO-reads are allowed to prevent crash +/******************************************************************************\ + * Constants +\******************************************************************************/ -volatile uint8_t recovery_loop_counter = 0; //count number of stateloops to switch the sensor off, if needed -#define APDS9960_LONG_RECOVERY 50 //long pause after sensor overload in loops -#define APDS9960_MAX_GESTURE_CYCLES 50 //how many FIFO-reads are allowed to prevent crash -bool APDS9960_overload = false; +const char APDS9960_TAG[] PROGMEM = "APDS9960"; // Only one actualy #ifdef USE_WEBSERVER -const char HTTP_APDS_9960_SNS[] PROGMEM = - "{s}" "Red" "{m}%s{e}" - "{s}" "Green" "{m}%s{e}" - "{s}" "Blue" "{m}%s{e}" - "{s}" "Ambient" "{m}%s " D_UNIT_LUX "{e}" - "{s}" "CCT" "{m}%s " "K" "{e}" // calculated color temperature in Kelvin - "{s}" "Proximity" "{m}%s{e}"; // {s} = , {m} = , {e} = + +#ifdef USE_APDS9960_GESTURE +const char HTTP_SNS_GESTURE[] PROGMEM = "{s}%s " D_GESTURE "{m}%s{e}"; +#endif // USE_APDS9960_GESTURE + +#ifdef USE_APDS9960_COLOR +const char HTTP_SNS_COLOR_RED[] PROGMEM = "{s}%s " D_COLOR_RED "{m}%u{e}"; +const char HTTP_SNS_COLOR_GREEN[] PROGMEM = "{s}%s " D_COLOR_GREEN "{m}%u{e}"; +const char HTTP_SNS_COLOR_BLUE[] PROGMEM = "{s}%s " D_COLOR_BLUE "{m}%u{e}"; +const char HTTP_SNS_CCT[] PROGMEM = "{s}%s " D_CCT "{m}%u " D_UNIT_KELVIN "{e}"; +#endif // USE_APDS9960_COLOR + +#ifdef USE_APDS9960_PROXIMITY +const char HTTP_SNS_PROXIMITY[] PROGMEM = "{s}%s " D_PROXIMITY "{m}%u{e}"; +#endif // USE_APDS9960_PROXIMITY + #endif // USE_WEBSERVER -/*********************************************************************************************\ +/******************************************************************************\ * APDS9960 * * Programmer : APDS9960 Datasheet and Sparkfun -\*********************************************************************************************/ +\******************************************************************************/ /* Misc parameters */ #define FIFO_PAUSE_TIME 30 // Wait period (ms) between FIFO reads @@ -152,9 +163,10 @@ const char HTTP_APDS_9960_SNS[] PROGMEM = #define APDS9960_AEN 0b00000010 #define APDS9960_PEN 0b00000100 #define APDS9960_WEN 0b00001000 -#define APSD9960_AIEN 0b00010000 +#define APDS9960_AIEN 0b00010000 #define APDS9960_PIEN 0b00100000 #define APDS9960_GEN 0b01000000 + #define APDS9960_GVALID 0b00000001 /* On/Off definitions */ @@ -211,149 +223,137 @@ const char HTTP_APDS_9960_SNS[] PROGMEM = #define GWTIME_30_8MS 6 #define GWTIME_39_2MS 7 + + /* Default values */ -#define DEFAULT_ATIME 0xdb // 103ms = 0xdb -#define DEFAULT_WTIME 246 // 27ms -#define DEFAULT_PROX_PPULSE 0x87 // 16us, 8 pulses -#define DEFAULT_GESTURE_PPULSE 0x89 // 16us, 10 pulses ---89 -#define DEFAULT_POFFSET_UR 0 // 0 offset -#define DEFAULT_POFFSET_DL 0 // 0 offset -#define DEFAULT_CONFIG1 0x60 // No 12x wait (WTIME) factor +#define DEFAULT_ATIME 0xdb // 103ms = 0xdb = 219 +#define DEFAULT_WTIME 246 // 27ms +#define DEFAULT_PROX_PPULSE 0x87 // 16us, 8 pulses +#define DEFAULT_GESTURE_PPULSE 0x89 // 16us, 10 pulses ---89 +#define DEFAULT_POFFSET_UR 0 // 0 offset +#define DEFAULT_POFFSET_DL 0 // 0 offset +#define DEFAULT_CONFIG1 0x60 // No 12x wait (WTIME) factor #define DEFAULT_LDRIVE LED_DRIVE_100MA #define DEFAULT_PGAIN PGAIN_4X -#define DEFAULT_AGAIN AGAIN_4X // we have to divide by the same facot at the end -#define DEFAULT_PILT 0 // Low proximity threshold -#define DEFAULT_PIHT 50 // High proximity threshold -#define DEFAULT_AILT 0xFFFF // Force interrupt for calibration +#define DEFAULT_AGAIN AGAIN_4X // we have to divide by the same facot at the end +#define DEFAULT_PILT 0 // Low proximity threshold +#define DEFAULT_PIHT 50 // High proximity threshold +#define DEFAULT_AILT 0xFFFF // Force interrupt for calibration #define DEFAULT_AIHT 0 -#define DEFAULT_PERS 0x11 // 2 consecutive prox or ALS for int. -#define DEFAULT_CONFIG2 0x01 // No saturation interrupts or LED boost -#define DEFAULT_CONFIG3 0 // Enable all photodiodes, no SAI -#define DEFAULT_GPENTH 40 // Threshold for entering gesture mode -#define DEFAULT_GEXTH 30 // Threshold for exiting gesture mode -#define DEFAULT_GCONF1 0x40 // 4 gesture events for int., 1 for exit +#define DEFAULT_PERS 0x11 // 2 consecutive prox or ALS for int. +#define DEFAULT_CONFIG2 0x01 // No saturation interrupts or LED boost +#define DEFAULT_CONFIG3 0 // Enable all photodiodes, no SAI +#define DEFAULT_GPENTH 40 // Threshold for entering gesture mode +#define DEFAULT_GEXTH 30 // Threshold for exiting gesture mode +#define DEFAULT_GCONF1 0x40 // 4 gesture events for int., 1 for exit #define DEFAULT_GGAIN GGAIN_4X -#define DEFAULT_GLDRIVE LED_DRIVE_100MA // default 100ma -#define DEFAULT_GWTIME GWTIME_2_8MS // default 2_8MS -#define DEFAULT_GOFFSET 0 // No offset scaling for gesture mode -#define DEFAULT_GPULSE 0xC9 // 32us, 10 pulses -#define DEFAULT_GCONF3 0 // All photodiodes active during gesture -#define DEFAULT_GIEN 0 // Disable gesture interrupts +#define DEFAULT_GLDRIVE LED_DRIVE_100MA // default 100ma +#define DEFAULT_GWTIME GWTIME_2_8MS // default 2_8MS +#define DEFAULT_GOFFSET 0 // No offset scaling for gesture mode +#define DEFAULT_GPULSE 0xC9 // 32us, 10 pulses +#define DEFAULT_GCONF3 0 // All photodiodes active during gesture +#define DEFAULT_GIEN 0 // Disable gesture interrupts #define APDS9960_ERROR 0xFF +#ifdef USE_APDS9960_GESTURE + /* Direction definitions */ +const char GESTURE_UP[] PROGMEM = "Up"; +const char GESTURE_DOWN[] PROGMEM = "Down"; +const char GESTURE_LEFT[] PROGMEM = "Left"; +const char GESTURE_RIGHT[] PROGMEM = "Right"; +const char GESTURE_LONG[] PROGMEM = "Long"; +const char GESTURE_NONE[] PROGMEM = "None"; + enum { DIR_NONE, DIR_LEFT, DIR_RIGHT, DIR_UP, DIR_DOWN, + DIR_NEAR, + DIR_FAR, DIR_ALL }; /* State definitions*/ +/* enum { APDS9960_NA_STATE, + APDS9960_NEAR_STATE, + APDS9960_FAR_STATE, APDS9960_ALL_STATE }; +*/ /* Container for gesture data */ typedef struct gesture_data_type { - uint8_t u_data[32]; - uint8_t d_data[32]; - uint8_t l_data[32]; - uint8_t r_data[32]; - uint8_t index; - uint8_t total_gestures; - uint8_t in_threshold; - uint8_t out_threshold; -} gesture_data_type; + uint8_t u_data[32]; + uint8_t d_data[32]; + uint8_t l_data[32]; + uint8_t r_data[32]; + uint8_t index; + uint8_t total_gestures; + uint8_t in_threshold; + uint8_t out_threshold; +} gesture_data_t; -/*Members*/ - gesture_data_type gesture_data_; - int16_t gesture_ud_delta_ = 0; - int16_t gesture_lr_delta_ = 0; - int16_t gesture_ud_count_ = 0; - int16_t gesture_lr_count_ = 0; - int16_t gesture_state_ = 0; - int16_t gesture_motion_ = DIR_NONE; +typedef struct gesture_type { + int16_t ud_delta_ = 0; + int16_t lr_delta_ = 0; + int16_t ud_count_ = 0; + int16_t lr_count_ = 0; + int16_t state_ = 0; + int16_t motion_ = DIR_NONE; +} gesture_t; - typedef struct color_data_type { - uint16_t a; // measured ambient - uint16_t r; - uint16_t g; - uint16_t b; - uint8_t p; // proximity - uint16_t cct; // calculated color temperature - uint16_t lux; // calculated illuminance - atm only from rgb - } color_data_type; +#endif // USE_APDS9960_GESTURE - color_data_type color_data; - uint8_t APDS9960_aTime = DEFAULT_ATIME; +#if defined(USE_APDS9960_COLOR) || defined(USE_APDS9960_PROXIMITY) +typedef struct color_data_type { + uint16_t a; // measured ambient + uint16_t r; // Red + uint16_t g; // Green + uint16_t b; // Blue + uint8_t p; // proximity + uint16_t cct; // calculated color temperature + uint16_t lux; // calculated illuminance - atm only from rgb +} color_data_t; +#endif // USE_APDS9960_COLOR || USE_APDS9960_PROXIMITY - /******************************************************************************* - * Helper functions - ******************************************************************************/ +/******************************************************************************\ + * Globals +\******************************************************************************/ - /** - * @brief Writes a single byte to the I2C device (no register) - * - * @param[in] val the 1-byte value to write to the I2C device - * @return True if successful write operation. False otherwise. - */ - bool wireWriteByte(uint8_t val) - { - Wire.beginTransmission(APDS9960_I2C_ADDR); - Wire.write(val); - if( Wire.endTransmission() != 0 ) { - return false; - } +#ifdef USE_APDS9960_GESTURE +gesture_data_t gesture_data; +gesture_t gesture; +char currentGesture[6]; +#endif // USE_APDS9960_GESTURE - return true; - } - /** - * @brief Reads a block (array) of bytes from the I2C device and register - * - * @param[in] reg the register to read from - * @param[out] val pointer to the beginning of the data - * @param[in] len number of bytes to read - * @return Number of bytes read. -1 on read error. - */ +#if defined(USE_APDS9960_COLOR) || defined(USE_APDS9960_PROXIMITY) +color_data_t color_data; +#endif // USE_APDS9960_COLOR || USE_APDS9960_PROXIMITY -int8_t wireReadDataBlock( uint8_t reg, - uint8_t *val, - uint16_t len) -{ - unsigned char i = 0; +volatile uint8_t recovery_loop_counter = 0; // count number of stateloops to switch the sensor off, if needed +bool APDS9960_overload = false; +uint8_t APDS9960_aTime = DEFAULT_ATIME; +uint8_t APDS9960_type = 0; +uint8_t gesture_mode = 1; // 1 : Gesture | 2 : Color - /* Indicate which register we want to read from */ - if (!wireWriteByte(reg)) { - return -1; - } - - /* Read block data */ - Wire.requestFrom(APDS9960_I2C_ADDR, len); - while (Wire.available()) { - if (i >= len) { - return -1; - } - val[i] = Wire.read(); - i++; - } - - return i; -} +/******************************************************************************\ + * Helper functions +\******************************************************************************/ +#ifdef USE_APDS9960_COLOR /** -* Taken from the Adafruit-library -* @brief Converts the raw R/G/B values to color temperature in degrees -* Kelvin -*/ - -void calculateColorTemperature(void) -{ + * Taken from the Adafruit-library + * @brief Converts the raw R/G/B values to color temperature in degrees + * Kelvin + */ +void calculateColorTemperature(void) { float X, Y, Z; /* RGB to XYZ correlation */ float xc, yc; /* Chromaticity co-ordinates */ float n; /* McCamy's formula */ @@ -364,8 +364,8 @@ void calculateColorTemperature(void) /* and 60W incandescent values for a wide range. */ /* Note: Y = Illuminance or lux */ X = (-0.14282F * color_data.r) + (1.54924F * color_data.g) + (-0.95641F * color_data.b); - Y = (-0.32466F * color_data.r) + (1.57837F * color_data.g) + (-0.73191F * color_data.b); // this is Lux ... under certain circumstances - Z = (-0.68202F * color_data.r) + (0.77073F * color_data.g) + ( 0.56332F * color_data.b); + Y = (-0.32466F * color_data.r) + (1.57837F * color_data.g) + (-0.73191F * color_data.b); // this is Lux ... under certain circumstances + Z = (-0.68202F * color_data.r) + (0.77073F * color_data.g) + (+0.56332F * color_data.b); /* 2. Calculate the chromaticity co-ordinates */ xc = (X) / (X + Y + Z); @@ -379,965 +379,909 @@ void calculateColorTemperature(void) return; } +#endif // USE_APDS9960_COLOR - /******************************************************************************* - * Getters and setters for register values - ******************************************************************************/ +/******************************************************************************\ + * Getters and setters for register values +\******************************************************************************/ - /** - * @brief Returns the lower threshold for proximity detection - * - * @return lower threshold - */ - uint8_t getProxIntLowThresh(void) - { - uint8_t val; +/** + * @brief Returns the lower threshold for proximity detection + * + * @return lower threshold + */ +uint8_t getProxIntLowThresh(void) { + uint8_t val; - /* Read value from PILT register */ - val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_PILT) ; - return val; - } + /* Read value from PILT register */ + val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_PILT); - /** - * @brief Sets the lower threshold for proximity detection - * - * @param[in] threshold the lower proximity threshold - */ - void setProxIntLowThresh(uint8_t threshold) - { - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_PILT, threshold); - } - - /** - * @brief Returns the high threshold for proximity detection - * - * @return high threshold - */ - uint8_t getProxIntHighThresh(void) - { - uint8_t val; - - /* Read value from PIHT register */ - val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_PIHT) ; - return val; - } - - /** - * @brief Sets the high threshold for proximity detection - * - * @param[in] threshold the high proximity threshold - */ - - void setProxIntHighThresh(uint8_t threshold) - { - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_PIHT, threshold); - } - - - /** - * @brief Returns LED drive strength for proximity and ALS - * - * Value LED Current - * 0 100 mA - * 1 50 mA - * 2 25 mA - * 3 12.5 mA - * - * @return the value of the LED drive strength. 0xFF on failure. - */ - uint8_t getLEDDrive(void) - { - uint8_t val; - - /* Read value from CONTROL register */ - val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_CONTROL) ; - /* Shift and mask out LED drive bits */ - val = (val >> 6) & 0b00000011; - - return val; - } - - /** - * @brief Sets the LED drive strength for proximity and ALS - * - * Value LED Current - * 0 100 mA - * 1 50 mA - * 2 25 mA - * 3 12.5 mA - * - * @param[in] drive the value (0-3) for the LED drive strength - */ - void setLEDDrive(uint8_t drive) - { - uint8_t val; - - /* Read value from CONTROL register */ - val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_CONTROL); - - /* Set bits in register to given value */ - drive &= 0b00000011; - drive = drive << 6; - val &= 0b00111111; - val |= drive; - - /* Write register value back into CONTROL register */ - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_CONTROL, val); - } - - - /** - * @brief Returns receiver gain for proximity detection - * - * Value Gain - * 0 1x - * 1 2x - * 2 4x - * 3 8x - * - * @return the value of the proximity gain. 0xFF on failure. - */ - uint8_t getProximityGain(void) - { - uint8_t val; - - /* Read value from CONTROL register */ - val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_CONTROL) ; - /* Shift and mask out PDRIVE bits */ - val = (val >> 2) & 0b00000011; - - return val; - } - - /** - * @brief Sets the receiver gain for proximity detection - * - * Value Gain - * 0 1x - * 1 2x - * 2 4x - * 3 8x - * - * @param[in] drive the value (0-3) for the gain - */ - void setProximityGain(uint8_t drive) - { - uint8_t val; - - /* Read value from CONTROL register */ - val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_CONTROL); - - /* Set bits in register to given value */ - drive &= 0b00000011; - drive = drive << 2; - val &= 0b11110011; - val |= drive; - - /* Write register value back into CONTROL register */ - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_CONTROL, val); - } - - - /** - * @brief Returns receiver gain for the ambient light sensor (ALS) - * - * Value Gain - * 0 1x - * 1 4x - * 2 16x - * 3 64x - * - * @return the value of the ALS gain. 0xFF on failure. - */ - - /** - * @brief Sets the receiver gain for the ambient light sensor (ALS) - * - * Value Gain - * 0 1x - * 1 4x - * 2 16x - * 3 64x - * - * @param[in] drive the value (0-3) for the gain - */ - void setAmbientLightGain(uint8_t drive) - { - uint8_t val; - - /* Read value from CONTROL register */ - val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_CONTROL); - - /* Set bits in register to given value */ - drive &= 0b00000011; - val &= 0b11111100; - val |= drive; - - /* Write register value back into CONTROL register */ - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_CONTROL, val); - } - - /** - * @brief Get the current LED boost value - * - * Value Boost Current - * 0 100% - * 1 150% - * 2 200% - * 3 300% - * - * @return The LED boost value. 0xFF on failure. - */ - uint8_t getLEDBoost(void) - { - uint8_t val; - - /* Read value from CONFIG2 register */ - val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_CONFIG2) ; - - /* Shift and mask out LED_BOOST bits */ - val = (val >> 4) & 0b00000011; - - return val; - } - - /** - * @brief Sets the LED current boost value - * - * Value Boost Current - * 0 100% - * 1 150% - * 2 200% - * 3 300% - * - * @param[in] drive the value (0-3) for current boost (100-300%) - */ - void setLEDBoost(uint8_t boost) - { - uint8_t val; - - /* Read value from CONFIG2 register */ - val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_CONFIG2) ; - /* Set bits in register to given value */ - boost &= 0b00000011; - boost = boost << 4; - val &= 0b11001111; - val |= boost; - - /* Write register value back into CONFIG2 register */ - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_CONFIG2, val) ; - } - - /** - * @brief Gets proximity gain compensation enable - * - * @return 1 if compensation is enabled. 0 if not. 0xFF on error. - */ - uint8_t getProxGainCompEnable(void) - { - uint8_t val; - - /* Read value from CONFIG3 register */ - val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_CONFIG3) ; - - /* Shift and mask out PCMP bits */ - val = (val >> 5) & 0b00000001; - - return val; - } - - /** - * @brief Sets the proximity gain compensation enable - * - * @param[in] enable 1 to enable compensation. 0 to disable compensation. - */ - void setProxGainCompEnable(uint8_t enable) - { - uint8_t val; - - /* Read value from CONFIG3 register */ - val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_CONFIG3) ; - - /* Set bits in register to given value */ - enable &= 0b00000001; - enable = enable << 5; - val &= 0b11011111; - val |= enable; - - /* Write register value back into CONFIG3 register */ - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_CONFIG3, val) ; - } - - /** - * @brief Gets the current mask for enabled/disabled proximity photodiodes - * - * 1 = disabled, 0 = enabled - * Bit Photodiode - * 3 UP - * 2 DOWN - * 1 LEFT - * 0 RIGHT - * - * @return Current proximity mask for photodiodes. 0xFF on error. - */ - uint8_t getProxPhotoMask(void) - { - uint8_t val; - - /* Read value from CONFIG3 register */ - val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_CONFIG3) ; - - /* Mask out photodiode enable mask bits */ - val &= 0b00001111; - - return val; - } - - /** - * @brief Sets the mask for enabling/disabling proximity photodiodes - * - * 1 = disabled, 0 = enabled - * Bit Photodiode - * 3 UP - * 2 DOWN - * 1 LEFT - * 0 RIGHT - * - * @param[in] mask 4-bit mask value - */ - void setProxPhotoMask(uint8_t mask) - { - uint8_t val; - - /* Read value from CONFIG3 register */ - val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_CONFIG3) ; - - /* Set bits in register to given value */ - mask &= 0b00001111; - val &= 0b11110000; - val |= mask; - - /* Write register value back into CONFIG3 register */ - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_CONFIG3, val) ; - } - - /** - * @brief Gets the entry proximity threshold for gesture sensing - * - * @return Current entry proximity threshold. - */ - uint8_t getGestureEnterThresh(void) - { - uint8_t val; - - /* Read value from GPENTH register */ - val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_GPENTH) ; - - return val; - } - - /** - * @brief Sets the entry proximity threshold for gesture sensing - * - * @param[in] threshold proximity value needed to start gesture mode - */ - void setGestureEnterThresh(uint8_t threshold) - { - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_GPENTH, threshold) ; - - } - - /** - * @brief Gets the exit proximity threshold for gesture sensing - * - * @return Current exit proximity threshold. - */ - uint8_t getGestureExitThresh(void) - { - uint8_t val; - - /* Read value from GEXTH register */ - val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_GEXTH) ; - - return val; - } - - /** - * @brief Sets the exit proximity threshold for gesture sensing - * - * @param[in] threshold proximity value needed to end gesture mode - */ - void setGestureExitThresh(uint8_t threshold) - { - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_GEXTH, threshold) ; - } - - /** - * @brief Gets the gain of the photodiode during gesture mode - * - * Value Gain - * 0 1x - * 1 2x - * 2 4x - * 3 8x - * - * @return the current photodiode gain. 0xFF on error. - */ - uint8_t getGestureGain(void) - { - uint8_t val; - - /* Read value from GCONF2 register */ - val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_GCONF2) ; - - /* Shift and mask out GGAIN bits */ - val = (val >> 5) & 0b00000011; - - return val; - } - - /** - * @brief Sets the gain of the photodiode during gesture mode - * - * Value Gain - * 0 1x - * 1 2x - * 2 4x - * 3 8x - * - * @param[in] gain the value for the photodiode gain - */ - void setGestureGain(uint8_t gain) - { - uint8_t val; - - /* Read value from GCONF2 register */ - val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_GCONF2) ; - - /* Set bits in register to given value */ - gain &= 0b00000011; - gain = gain << 5; - val &= 0b10011111; - val |= gain; - - /* Write register value back into GCONF2 register */ - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_GCONF2, val) ; - } - - /** - * @brief Gets the drive current of the LED during gesture mode - * - * Value LED Current - * 0 100 mA - * 1 50 mA - * 2 25 mA - * 3 12.5 mA - * - * @return the LED drive current value. 0xFF on error. - */ - uint8_t getGestureLEDDrive(void) - { - uint8_t val; - - /* Read value from GCONF2 register */ - val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_GCONF2) ; - - /* Shift and mask out GLDRIVE bits */ - val = (val >> 3) & 0b00000011; - - return val; - } - - /** - * @brief Sets the LED drive current during gesture mode - * - * Value LED Current - * 0 100 mA - * 1 50 mA - * 2 25 mA - * 3 12.5 mA - * - * @param[in] drive the value for the LED drive current - */ - void setGestureLEDDrive(uint8_t drive) - { - uint8_t val; - - /* Read value from GCONF2 register */ - val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_GCONF2) ; - - /* Set bits in register to given value */ - drive &= 0b00000011; - drive = drive << 3; - val &= 0b11100111; - val |= drive; - - /* Write register value back into GCONF2 register */ - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_GCONF2, val) ; - } - - /** - * @brief Gets the time in low power mode between gesture detections - * - * Value Wait time - * 0 0 ms - * 1 2.8 ms - * 2 5.6 ms - * 3 8.4 ms - * 4 14.0 ms - * 5 22.4 ms - * 6 30.8 ms - * 7 39.2 ms - * - * @return the current wait time between gestures. 0xFF on error. - */ - uint8_t getGestureWaitTime(void) - { - uint8_t val; - - /* Read value from GCONF2 register */ - val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_GCONF2) ; - - /* Mask out GWTIME bits */ - val &= 0b00000111; - - return val; - } - - /** - * @brief Sets the time in low power mode between gesture detections - * - * Value Wait time - * 0 0 ms - * 1 2.8 ms - * 2 5.6 ms - * 3 8.4 ms - * 4 14.0 ms - * 5 22.4 ms - * 6 30.8 ms - * 7 39.2 ms - * - * @param[in] the value for the wait time - */ - void setGestureWaitTime(uint8_t time) - { - uint8_t val; - - /* Read value from GCONF2 register */ - val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_GCONF2) ; - - /* Set bits in register to given value */ - time &= 0b00000111; - val &= 0b11111000; - val |= time; - - /* Write register value back into GCONF2 register */ - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_GCONF2, val) ; - } - - /** - * @brief Gets the low threshold for ambient light interrupts - * - * @param[out] threshold current low threshold stored on the APDS-9960 - */ - void getLightIntLowThreshold(uint16_t &threshold) - { - uint8_t val_byte; - threshold = 0; - - /* Read value from ambient light low threshold, low byte register */ - val_byte = I2cRead8(APDS9960_I2C_ADDR, APDS9960_AILTL) ; - threshold = val_byte; - - /* Read value from ambient light low threshold, high byte register */ - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_AILTH, val_byte) ; - threshold = threshold + ((uint16_t)val_byte << 8); - } - - /** - * @brief Sets the low threshold for ambient light interrupts - * - * @param[in] threshold low threshold value for interrupt to trigger - */ - - void setLightIntLowThreshold(uint16_t threshold) - { - uint8_t val_low; - uint8_t val_high; - - /* Break 16-bit threshold into 2 8-bit values */ - val_low = threshold & 0x00FF; - val_high = (threshold & 0xFF00) >> 8; - - /* Write low byte */ - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_AILTL, val_low) ; - - /* Write high byte */ - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_AILTH, val_high) ; - - } - - - /** - * @brief Gets the high threshold for ambient light interrupts - * - * @param[out] threshold current low threshold stored on the APDS-9960 - */ - void getLightIntHighThreshold(uint16_t &threshold) - { - uint8_t val_byte; - threshold = 0; - - /* Read value from ambient light high threshold, low byte register */ - val_byte = I2cRead8(APDS9960_I2C_ADDR, APDS9960_AIHTL); - threshold = val_byte; - - /* Read value from ambient light high threshold, high byte register */ - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_AIHTH, val_byte) ; - threshold = threshold + ((uint16_t)val_byte << 8); - } - - /** - * @brief Sets the high threshold for ambient light interrupts - * - * @param[in] threshold high threshold value for interrupt to trigger - */ - void setLightIntHighThreshold(uint16_t threshold) - { - uint8_t val_low; - uint8_t val_high; - - /* Break 16-bit threshold into 2 8-bit values */ - val_low = threshold & 0x00FF; - val_high = (threshold & 0xFF00) >> 8; - - /* Write low byte */ - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_AIHTL, val_low); - - /* Write high byte */ - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_AIHTH, val_high) ; - } - - - /** - * @brief Gets the low threshold for proximity interrupts - * - * @param[out] threshold current low threshold stored on the APDS-9960 - */ - void getProximityIntLowThreshold(uint8_t &threshold) - { - threshold = 0; - - /* Read value from proximity low threshold register */ - threshold = I2cRead8(APDS9960_I2C_ADDR, APDS9960_PILT); - - } - - /** - * @brief Sets the low threshold for proximity interrupts - * - * @param[in] threshold low threshold value for interrupt to trigger - */ - void setProximityIntLowThreshold(uint8_t threshold) - { - - /* Write threshold value to register */ - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_PILT, threshold) ; - } - - - - /** - * @brief Gets the high threshold for proximity interrupts - * - * @param[out] threshold current low threshold stored on the APDS-9960 - */ - void getProximityIntHighThreshold(uint8_t &threshold) - { - threshold = 0; - - /* Read value from proximity low threshold register */ - threshold = I2cRead8(APDS9960_I2C_ADDR, APDS9960_PIHT) ; - - } - - /** - * @brief Sets the high threshold for proximity interrupts - * - * @param[in] threshold high threshold value for interrupt to trigger - */ - void setProximityIntHighThreshold(uint8_t threshold) - { - - /* Write threshold value to register */ - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_PIHT, threshold) ; - } - - /** - * @brief Gets if ambient light interrupts are enabled or not - * - * @return 1 if interrupts are enabled, 0 if not. 0xFF on error. - */ - uint8_t getAmbientLightIntEnable(void) - { - uint8_t val; - - /* Read value from ENABLE register */ - val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_ENABLE) ; - - /* Shift and mask out AIEN bit */ - val = (val >> 4) & 0b00000001; - - return val; - } - - /** - * @brief Turns ambient light interrupts on or off - * - * @param[in] enable 1 to enable interrupts, 0 to turn them off - */ - void setAmbientLightIntEnable(uint8_t enable) - { - uint8_t val; - - /* Read value from ENABLE register */ - val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_ENABLE); - - /* Set bits in register to given value */ - enable &= 0b00000001; - enable = enable << 4; - val &= 0b11101111; - val |= enable; - - /* Write register value back into ENABLE register */ - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_ENABLE, val) ; - } - - /** - * @brief Gets if proximity interrupts are enabled or not - * - * @return 1 if interrupts are enabled, 0 if not. 0xFF on error. - */ - uint8_t getProximityIntEnable(void) - { - uint8_t val; - - /* Read value from ENABLE register */ - val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_ENABLE) ; - - /* Shift and mask out PIEN bit */ - val = (val >> 5) & 0b00000001; - - return val; - } - - /** - * @brief Turns proximity interrupts on or off - * - * @param[in] enable 1 to enable interrupts, 0 to turn them off - */ - void setProximityIntEnable(uint8_t enable) - { - uint8_t val; - - /* Read value from ENABLE register */ - val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_ENABLE) ; - - /* Set bits in register to given value */ - enable &= 0b00000001; - enable = enable << 5; - val &= 0b11011111; - val |= enable; - - /* Write register value back into ENABLE register */ - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_ENABLE, val) ; - } - - /** - * @brief Gets if gesture interrupts are enabled or not - * - * @return 1 if interrupts are enabled, 0 if not. 0xFF on error. - */ - uint8_t getGestureIntEnable(void) - { - uint8_t val; - - /* Read value from GCONF4 register */ - val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_GCONF4) ; - - /* Shift and mask out GIEN bit */ - val = (val >> 1) & 0b00000001; - - return val; - } - - /** - * @brief Turns gesture-related interrupts on or off - * - * @param[in] enable 1 to enable interrupts, 0 to turn them off - */ - void setGestureIntEnable(uint8_t enable) - { - uint8_t val; - - /* Read value from GCONF4 register */ - val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_GCONF4) ; - - /* Set bits in register to given value */ - enable &= 0b00000001; - enable = enable << 1; - val &= 0b11111101; - val |= enable; - - /* Write register value back into GCONF4 register */ - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_GCONF4, val) ; - } - - /** - * @brief Clears the ambient light interrupt - * - */ - void clearAmbientLightInt(void) - { - uint8_t throwaway; - throwaway = I2cRead8(APDS9960_I2C_ADDR, APDS9960_AICLEAR); - } - - /** - * @brief Clears the proximity interrupt - * - */ - void clearProximityInt(void) - { - uint8_t throwaway; - throwaway = I2cRead8(APDS9960_I2C_ADDR, APDS9960_PICLEAR) ; - - } - - /** - * @brief Tells if the gesture state machine is currently running - * - * @return 1 if gesture state machine is running, 0 if not. 0xFF on error. - */ - uint8_t getGestureMode(void) - { - uint8_t val; - - /* Read value from GCONF4 register */ - val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_GCONF4) ; - - /* Mask out GMODE bit */ - val &= 0b00000001; - - return val; - } - - /** - * @brief Tells the state machine to either enter or exit gesture state machine - * - * @param[in] mode 1 to enter gesture state machine, 0 to exit. - */ - void setGestureMode(uint8_t mode) - { - uint8_t val; - - /* Read value from GCONF4 register */ - val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_GCONF4) ; - - /* Set bits in register to given value */ - mode &= 0b00000001; - val &= 0b11111110; - val |= mode; - - /* Write register value back into GCONF4 register */ - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_GCONF4, val) ; - } - - -bool APDS9960_init(void) -{ - /* Set default values for ambient light and proximity registers */ - - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_ATIME, DEFAULT_ATIME) ; - - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_WTIME, DEFAULT_WTIME) ; - - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_PPULSE, DEFAULT_PROX_PPULSE) ; - - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_POFFSET_UR, DEFAULT_POFFSET_UR) ; - - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_POFFSET_DL, DEFAULT_POFFSET_DL) ; - - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_CONFIG1, DEFAULT_CONFIG1) ; - - setLEDDrive(DEFAULT_LDRIVE); - - setProximityGain(DEFAULT_PGAIN); - - setAmbientLightGain(DEFAULT_AGAIN); - - setProxIntLowThresh(DEFAULT_PILT) ; - - setProxIntHighThresh(DEFAULT_PIHT); - - setLightIntLowThreshold(DEFAULT_AILT) ; - - setLightIntHighThreshold(DEFAULT_AIHT) ; - - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_PERS, DEFAULT_PERS) ; - - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_CONFIG2, DEFAULT_CONFIG2) ; - - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_CONFIG3, DEFAULT_CONFIG3) ; - - /* Set default values for gesture sense registers */ - setGestureEnterThresh(DEFAULT_GPENTH); - - setGestureExitThresh(DEFAULT_GEXTH) ; - - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_GCONF1, DEFAULT_GCONF1) ; - - setGestureGain(DEFAULT_GGAIN) ; - - setGestureLEDDrive(DEFAULT_GLDRIVE) ; - - setGestureWaitTime(DEFAULT_GWTIME) ; - - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_GOFFSET_U, DEFAULT_GOFFSET) ; - - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_GOFFSET_D, DEFAULT_GOFFSET) ; - - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_GOFFSET_L, DEFAULT_GOFFSET) ; - - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_GOFFSET_R, DEFAULT_GOFFSET) ; - - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_GPULSE, DEFAULT_GPULSE) ; - - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_GCONF3, DEFAULT_GCONF3) ; - - setGestureIntEnable(DEFAULT_GIEN); - - disablePower(); // go to sleep - - return true; + return val; } -/******************************************************************************* + +/** + * @brief Sets the lower threshold for proximity detection + * + * @param[in] threshold the lower proximity threshold + */ +inline void setProxIntLowThresh(uint8_t threshold) { + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_PILT, threshold); +} + +/** + * @brief Returns the high threshold for proximity detection + * + * @return high threshold + */ +uint8_t getProxIntHighThresh(void) { + uint8_t val; + + /* Read value from PIHT register */ + val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_PIHT); + + return val; +} + +/** + * @brief Sets the high threshold for proximity detection + * + * @param[in] threshold the high proximity threshold + */ +inline void setProxIntHighThresh(uint8_t threshold) { + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_PIHT, threshold); +} + +/** + * @brief Returns LED drive strength for proximity and ALS + * + * Value LED Current + * 0 100 mA + * 1 50 mA + * 2 25 mA + * 3 12.5 mA + * + * @return the value of the LED drive strength. 0xFF on failure. + */ +uint8_t getLEDDrive(void) { + uint8_t val; + + /* Read value from CONTROL register */ + val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_CONTROL); + + /* Shift and mask out LED drive bits */ + val = (val >> 6) & 0b00000011; + + return val; +} + +/** + * @brief Sets the LED drive strength for proximity and ALS + * + * Value LED Current + * 0 100 mA + * 1 50 mA + * 2 25 mA + * 3 12.5 mA + * + * @param[in] drive the value (0-3) for the LED drive strength + */ +void setLEDDrive(uint8_t drive) { + uint8_t val; + + /* Read value from CONTROL register */ + val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_CONTROL); + + /* Set bits in register to given value */ + drive &= 0b00000011; + drive = drive << 6; + val &= 0b00111111; + val |= drive; + + /* Write register value back into CONTROL register */ + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_CONTROL, val); +} + +/** + * @brief Returns receiver gain for proximity detection + * + * Value Gain + * 0 1x + * 1 2x + * 2 4x + * 3 8x + * + * @return the value of the proximity gain. 0xFF on failure. + */ +uint8_t getProximityGain(void) { + uint8_t val; + + /* Read value from CONTROL register */ + val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_CONTROL); + + /* Shift and mask out PDRIVE bits */ + val = (val >> 2) & 0b00000011; + + return val; +} + +/** + * @brief Sets the receiver gain for proximity detection + * + * Value Gain + * 0 1x + * 1 2x + * 2 4x + * 3 8x + * + * @param[in] drive the value (0-3) for the gain + */ +void setProximityGain(uint8_t drive) { + uint8_t val; + + /* Read value from CONTROL register */ + val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_CONTROL); + + /* Set bits in register to given value */ + drive &= 0b00000011; + drive = drive << 2; + val &= 0b11110011; + val |= drive; + + /* Write register value back into CONTROL register */ + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_CONTROL, val); +} + +/** + * @brief Returns receiver gain for the ambient light sensor (ALS) + * + * Value Gain + * 0 1x + * 1 4x + * 2 16x + * 3 64x + * + * @return the value of the ALS gain. 0xFF on failure. + */ +uint8_t getAmbientLightGain() { + uint8_t val; + + /* Read value from CONTROL register */ + val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_CONTROL); + + /* Shift and mask out ADRIVE bits */ + val &= 0b00000011; + + return val; +} + +/** + * @brief Sets the receiver gain for the ambient light sensor (ALS) + * + * Value Gain + * 0 1x + * 1 4x + * 2 16x + * 3 64x + * + * @param[in] drive the value (0-3) for the gain + */ +void setAmbientLightGain(uint8_t drive) { + uint8_t val; + + /* Read value from CONTROL register */ + val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_CONTROL); + + /* Set bits in register to given value */ + drive &= 0b00000011; + val &= 0b11111100; + val |= drive; + + /* Write register value back into CONTROL register */ + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_CONTROL, val); +} + +/** + * @brief Get the current LED boost value + * + * Value Boost Current + * 0 100% + * 1 150% + * 2 200% + * 3 300% + * + * @return The LED boost value. 0xFF on failure. + */ +uint8_t getLEDBoost(void) { + uint8_t val; + + /* Read value from CONFIG2 register */ + val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_CONFIG2); + + /* Shift and mask out LED_BOOST bits */ + val = (val >> 4) & 0b00000011; + + return val; +} + +/** + * @brief Sets the LED current boost value + * + * Value Boost Current + * 0 100% + * 1 150% + * 2 200% + * 3 300% + * + * @param[in] drive the value (0-3) for current boost (100-300%) + */ +void setLEDBoost(uint8_t boost) { + uint8_t val; + + /* Read value from CONFIG2 register */ + val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_CONFIG2); + + /* Set bits in register to given value */ + boost &= 0b00000011; + boost = boost << 4; + val &= 0b11001111; + val |= boost; + + /* Write register value back into CONFIG2 register */ + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_CONFIG2, val); +} + +/** + * @brief Gets proximity gain compensation enable + * + * @return 1 if compensation is enabled. 0 if not. 0xFF on error. + */ +uint8_t getProxGainCompEnable(void) { + uint8_t val; + + /* Read value from CONFIG3 register */ + val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_CONFIG3); + + /* Shift and mask out PCMP bits */ + val = (val >> 5) & 0b00000001; + + return val; +} + +/** + * @brief Sets the proximity gain compensation enable + * + * @param[in] enable 1 to enable compensation. 0 to disable compensation. + */ +void setProxGainCompEnable(uint8_t enable) { + uint8_t val; + + /* Read value from CONFIG3 register */ + val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_CONFIG3); + + /* Set bits in register to given value */ + enable &= 0b00000001; + enable = enable << 5; + val &= 0b11011111; + val |= enable; + + /* Write register value back into CONFIG3 register */ + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_CONFIG3, val); +} + +/** + * @brief Gets the current mask for enabled/disabled proximity photodiodes + * + * 1 = disabled, 0 = enabled + * Bit Photodiode + * 3 UP + * 2 DOWN + * 1 LEFT + * 0 RIGHT + * + * @return Current proximity mask for photodiodes. 0xFF on error. + */ +uint8_t getProxPhotoMask(void) { + uint8_t val; + + /* Read value from CONFIG3 register */ + val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_CONFIG3); + + /* Mask out photodiode enable mask bits */ + val &= 0b00001111; + + return val; +} + +/** + * @brief Sets the mask for enabling/disabling proximity photodiodes + * + * 1 = disabled, 0 = enabled + * Bit Photodiode + * 3 UP + * 2 DOWN + * 1 LEFT + * 0 RIGHT + * + * @param[in] mask 4-bit mask value + */ +void setProxPhotoMask(uint8_t mask) { + uint8_t val; + + /* Read value from CONFIG3 register */ + val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_CONFIG3); + + /* Set bits in register to given value */ + mask &= 0b00001111; + val &= 0b11110000; + val |= mask; + + /* Write register value back into CONFIG3 register */ + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_CONFIG3, val); +} + +#ifdef USE_APDS9960_GESTURE + +/** + * @brief Gets the entry proximity threshold for gesture sensing + * + * @return Current entry proximity threshold. + */ +uint8_t getGestureEnterThresh(void) { + uint8_t val; + + /* Read value from GPENTH register */ + val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_GPENTH); + + return val; +} + +/** + * @brief Sets the entry proximity threshold for gesture sensing + * + * @param[in] threshold proximity value needed to start gesture mode + */ +inline void setGestureEnterThresh(uint8_t threshold) { + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_GPENTH, threshold); +} + +/** + * @brief Gets the exit proximity threshold for gesture sensing + * + * @return Current exit proximity threshold. + */ +uint8_t getGestureExitThresh(void) { + uint8_t val; + + /* Read value from GEXTH register */ + val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_GEXTH); + + return val; +} + +/** + * @brief Sets the exit proximity threshold for gesture sensing + * + * @param[in] threshold proximity value needed to end gesture mode + */ +inline void setGestureExitThresh(uint8_t threshold) { + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_GEXTH, threshold); +} + +/** + * @brief Gets the gain of the photodiode during gesture mode + * + * Value Gain + * 0 1x + * 1 2x + * 2 4x + * 3 8x + * + * @return the current photodiode gain. 0xFF on error. + */ +uint8_t getGestureGain(void) { + uint8_t val; + + /* Read value from GCONF2 register */ + val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_GCONF2); + + /* Shift and mask out GGAIN bits */ + val = (val >> 5) & 0b00000011; + + return val; +} + +/** + * @brief Sets the gain of the photodiode during gesture mode + * + * Value Gain + * 0 1x + * 1 2x + * 2 4x + * 3 8x + * + * @param[in] gain the value for the photodiode gain + */ +void setGestureGain(uint8_t gain) { + uint8_t val; + + /* Read value from GCONF2 register */ + val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_GCONF2); + + /* Set bits in register to given value */ + gain &= 0b00000011; + gain = gain << 5; + val &= 0b10011111; + val |= gain; + + /* Write register value back into GCONF2 register */ + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_GCONF2, val); +} + +/** + * @brief Gets the drive current of the LED during gesture mode + * + * Value LED Current + * 0 100 mA + * 1 50 mA + * 2 25 mA + * 3 12.5 mA + * + * @return the LED drive current value. 0xFF on error. + */ +uint8_t getGestureLEDDrive(void) { + uint8_t val; + + /* Read value from GCONF2 register */ + val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_GCONF2); + + /* Shift and mask out GLDRIVE bits */ + val = (val >> 3) & 0b00000011; + + return val; +} + +/** + * @brief Sets the LED drive current during gesture mode + * + * Value LED Current + * 0 100 mA + * 1 50 mA + * 2 25 mA + * 3 12.5 mA + * + * @param[in] drive the value for the LED drive current + */ +void setGestureLEDDrive(uint8_t drive) { + uint8_t val; + + /* Read value from GCONF2 register */ + val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_GCONF2); + + /* Set bits in register to given value */ + drive &= 0b00000011; + drive = drive << 3; + val &= 0b11100111; + val |= drive; + + /* Write register value back into GCONF2 register */ + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_GCONF2, val); +} + +/** + * @brief Gets the time in low power mode between gesture detections + * + * Value Wait time + * 0 0 ms + * 1 2.8 ms + * 2 5.6 ms + * 3 8.4 ms + * 4 14.0 ms + * 5 22.4 ms + * 6 30.8 ms + * 7 39.2 ms + * + * @return the current wait time between gestures. 0xFF on error. + */ +uint8_t getGestureWaitTime(void) { + uint8_t val; + + /* Read value from GCONF2 register */ + val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_GCONF2); + + /* Mask out GWTIME bits */ + val &= 0b00000111; + + return val; +} + +/** + * @brief Sets the time in low power mode between gesture detections + * + * Value Wait time + * 0 0 ms + * 1 2.8 ms + * 2 5.6 ms + * 3 8.4 ms + * 4 14.0 ms + * 5 22.4 ms + * 6 30.8 ms + * 7 39.2 ms + * + * @param[in] the value for the wait time + */ +void setGestureWaitTime(uint8_t time) { + uint8_t val; + + /* Read value from GCONF2 register */ + val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_GCONF2); + + /* Set bits in register to given value */ + time &= 0b00000111; + val &= 0b11111000; + val |= time; + + /* Write register value back into GCONF2 register */ + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_GCONF2, val); +} + +#endif // USE_APDS9960_GESTURE + +/** + * @brief Gets the low threshold for ambient light interrupts + * + * @param[out] threshold current low threshold stored on the APDS-9960 + */ +void getLightIntLowThreshold(uint16_t &threshold) { + uint8_t val_byte; + threshold = 0; + + /* Read value from ambient light low threshold, low byte register */ + val_byte = I2cRead8(APDS9960_I2C_ADDR, APDS9960_AILTL); + threshold = val_byte; + + /* Read value from ambient light low threshold, high byte register */ + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_AILTH, val_byte); + threshold = threshold + ((uint16_t)val_byte << 8); +} + +/** + * @brief Sets the low threshold for ambient light interrupts + * + * @param[in] threshold low threshold value for interrupt to trigger + */ +void setLightIntLowThreshold(uint16_t threshold) { + uint8_t val_low; + uint8_t val_high; + + /* Break 16-bit threshold into 2 8-bit values */ + val_low = threshold & 0x00FF; + val_high = (threshold & 0xFF00) >> 8; + + /* Write low byte */ + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_AILTL, val_low); + + /* Write high byte */ + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_AILTH, val_high); +} + +/** + * @brief Gets the high threshold for ambient light interrupts + * + * @param[out] threshold current low threshold stored on the APDS-9960 + */ +void getLightIntHighThreshold(uint16_t &threshold) { + uint8_t val_byte; + threshold = 0; + + /* Read value from ambient light high threshold, low byte register */ + val_byte = I2cRead8(APDS9960_I2C_ADDR, APDS9960_AIHTL); + threshold = val_byte; + + /* Read value from ambient light high threshold, high byte register */ + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_AIHTH, val_byte); + threshold = threshold + ((uint16_t)val_byte << 8); +} + +/** + * @brief Sets the high threshold for ambient light interrupts + * + * @param[in] threshold high threshold value for interrupt to trigger + */ +void setLightIntHighThreshold(uint16_t threshold) { + uint8_t val_low; + uint8_t val_high; + + /* Break 16-bit threshold into 2 8-bit values */ + val_low = threshold & 0x00FF; + val_high = (threshold & 0xFF00) >> 8; + + /* Write low byte */ + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_AIHTL, val_low); + + /* Write high byte */ + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_AIHTH, val_high); +} + +/** + * @brief Gets the low threshold for proximity interrupts + * + * @param[out] threshold current low threshold stored on the APDS-9960 + */ +void getProximityIntLowThreshold(uint8_t &threshold) { + threshold = 0; + + /* Read value from proximity low threshold register */ + threshold = I2cRead8(APDS9960_I2C_ADDR, APDS9960_PILT); +} + +/** + * @brief Sets the low threshold for proximity interrupts + * + * @param[in] threshold low threshold value for interrupt to trigger + */ +void setProximityIntLowThreshold(uint8_t threshold) { + /* Write threshold value to register */ + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_PILT, threshold); +} + +/** + * @brief Gets the high threshold for proximity interrupts + * + * @param[out] threshold current low threshold stored on the APDS-9960 + */ +void getProximityIntHighThreshold(uint8_t &threshold) { + threshold = 0; + + /* Read value from proximity low threshold register */ + threshold = I2cRead8(APDS9960_I2C_ADDR, APDS9960_PIHT); +} + +/** + * @brief Sets the high threshold for proximity interrupts + * + * @param[in] threshold high threshold value for interrupt to trigger + */ +void setProximityIntHighThreshold(uint8_t threshold) { + /* Write threshold value to register */ + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_PIHT, threshold); +} + +/** + * @brief Gets if ambient light interrupts are enabled or not + * + * @return 1 if interrupts are enabled, 0 if not. 0xFF on error. + */ +uint8_t getAmbientLightIntEnable(void) { + uint8_t val; + + /* Read value from ENABLE register */ + val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_ENABLE); + + /* Shift and mask out AIEN bit */ + val = (val >> 4) & 0b00000001; + + return val; +} + +/** + * @brief Turns ambient light interrupts on or off + * + * @param[in] enable 1 to enable interrupts, 0 to turn them off + */ +void setAmbientLightIntEnable(uint8_t enable) { + uint8_t val; + + /* Read value from ENABLE register */ + val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_ENABLE); + + /* Set bits in register to given value */ + enable &= 0b00000001; + enable = enable << 4; + val &= 0b11101111; + val |= enable; + + /* Write register value back into ENABLE register */ + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_ENABLE, val); +} + +/** + * @brief Gets if proximity interrupts are enabled or not + * + * @return 1 if interrupts are enabled, 0 if not. 0xFF on error. + */ +uint8_t getProximityIntEnable(void) { + uint8_t val; + + /* Read value from ENABLE register */ + val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_ENABLE); + + /* Shift and mask out PIEN bit */ + val = (val >> 5) & 0b00000001; + + return val; +} + +/** + * @brief Turns proximity interrupts on or off + * + * @param[in] enable 1 to enable interrupts, 0 to turn them off + */ +void setProximityIntEnable(uint8_t enable) { + uint8_t val; + + /* Read value from ENABLE register */ + val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_ENABLE); + + /* Set bits in register to given value */ + enable &= 0b00000001; + enable = enable << 5; + val &= 0b11011111; + val |= enable; + + /* Write register value back into ENABLE register */ + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_ENABLE, val); +} + +/** + * @brief Gets if gesture interrupts are enabled or not + * + * @return 1 if interrupts are enabled, 0 if not. 0xFF on error. + */ +uint8_t getGestureIntEnable(void) { + uint8_t val; + + /* Read value from GCONF4 register */ + val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_GCONF4); + + /* Shift and mask out GIEN bit */ + val = (val >> 1) & 0b00000001; + + return val; +} + +/** + * @brief Turns gesture-related interrupts on or off + * + * @param[in] enable 1 to enable interrupts, 0 to turn them off + */ +void setGestureIntEnable(uint8_t enable) { + uint8_t val; + + /* Read value from GCONF4 register */ + val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_GCONF4); + + /* Set bits in register to given value */ + enable &= 0b00000001; + enable = enable << 1; + val &= 0b11111101; + val |= enable; + + /* Write register value back into GCONF4 register */ + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_GCONF4, val); +} + +/** + * @brief Clears the ambient light interrupt + * + */ +void clearAmbientLightInt(void) { + uint8_t throwaway; + throwaway = I2cRead8(APDS9960_I2C_ADDR, APDS9960_AICLEAR); +} + +/** + * @brief Clears the proximity interrupt + * + */ +void clearProximityInt(void) { + uint8_t throwaway; + throwaway = I2cRead8(APDS9960_I2C_ADDR, APDS9960_PICLEAR); +} + +/** + * @brief Tells if the gesture state machine is currently running + * + * @return 1 if gesture state machine is running, 0 if not. 0xFF on error. + */ +uint8_t getGestureMode(void) { + uint8_t val; + + /* Read value from GCONF4 register */ + val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_GCONF4); + + /* Mask out GMODE bit */ + val &= 0b00000001; + + return val; +} + +/** + * @brief Tells the state machine to either enter or exit gesture state machine + * + * @param[in] mode 1 to enter gesture state machine, 0 to exit. + */ +void setGestureMode(uint8_t mode) { + uint8_t val; + + /* Read value from GCONF4 register */ + val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_GCONF4); + + /* Set bits in register to given value */ + mode &= 0b00000001; + val &= 0b11111110; + val |= mode; + + /* Write register value back into GCONF4 register */ + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_GCONF4, val); +} + + +bool APDS9960_init(void) { + setMode(ALL, OFF); + + /* Set default values for ambient light and proximity registers */ + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_ATIME, DEFAULT_ATIME); + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_WTIME, DEFAULT_WTIME); + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_PPULSE, DEFAULT_PROX_PPULSE); + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_POFFSET_UR, DEFAULT_POFFSET_UR); + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_POFFSET_DL, DEFAULT_POFFSET_DL); + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_CONFIG1, DEFAULT_CONFIG1); + + setLEDDrive(DEFAULT_LDRIVE); + setProximityGain(DEFAULT_PGAIN); + setAmbientLightGain(DEFAULT_AGAIN); + setProxIntLowThresh(DEFAULT_PILT); + setProxIntHighThresh(DEFAULT_PIHT); + setLightIntLowThreshold(DEFAULT_AILT); + setLightIntHighThreshold(DEFAULT_AIHT); + + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_PERS, DEFAULT_PERS); + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_CONFIG2, DEFAULT_CONFIG2); + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_CONFIG3, DEFAULT_CONFIG3); + + /* Set default values for gesture sense registers */ +#ifdef USE_APDS9960_GESTURE + setGestureEnterThresh(DEFAULT_GPENTH); + setGestureExitThresh(DEFAULT_GEXTH); + + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_GCONF1, DEFAULT_GCONF1); + + setGestureGain(DEFAULT_GGAIN); + setGestureLEDDrive(DEFAULT_GLDRIVE); + setGestureWaitTime(DEFAULT_GWTIME); + + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_GOFFSET_U, DEFAULT_GOFFSET); + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_GOFFSET_D, DEFAULT_GOFFSET); + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_GOFFSET_L, DEFAULT_GOFFSET); + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_GOFFSET_R, DEFAULT_GOFFSET); + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_GPULSE, DEFAULT_GPULSE); + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_GCONF3, DEFAULT_GCONF3); + + setGestureIntEnable(DEFAULT_GIEN); +#endif // USE_APDS9960_GESTURE + + disablePower(); // go to sleep + + return true; +} + + +/******************************************************************************\ * Public methods for controlling the APDS-9960 - ******************************************************************************/ +\******************************************************************************/ /** * @brief Reads and returns the contents of the ENABLE register * * @return Contents of the ENABLE register. 0xFF if error. */ -uint8_t getMode(void) -{ - uint8_t enable_value; +inline uint8_t getMode(void) { + uint8_t enable_value; - /* Read current ENABLE register */ - enable_value = I2cRead8(APDS9960_I2C_ADDR, APDS9960_ENABLE) ; + /* Read current ENABLE register */ + enable_value = I2cRead8(APDS9960_I2C_ADDR, APDS9960_ENABLE); - return enable_value; + return enable_value; } /** @@ -1346,32 +1290,30 @@ uint8_t getMode(void) * @param[in] mode which feature to enable * @param[in] enable ON (1) or OFF (0) */ -void setMode(uint8_t mode, uint8_t enable) -{ - uint8_t reg_val; +void setMode(uint8_t mode, uint8_t enable) { + uint8_t reg_val; - /* Read current ENABLE register */ - reg_val = getMode(); + /* Read current ENABLE register */ + reg_val = getMode(); - - /* Change bit(s) in ENABLE register */ - enable = enable & 0x01; - if( mode >= 0 && mode <= 6 ) { - if (enable) { - reg_val |= (1 << mode); - } else { - reg_val &= ~(1 << mode); - } - } else if( mode == ALL ) { - if (enable) { - reg_val = 0x7F; - } else { - reg_val = 0x00; - } + /* Change bit(s) in ENABLE register */ + enable = enable & 0x01; + if (mode <= 6) { + if (enable) { + reg_val |= (1 << mode); + } else { + reg_val &= ~(1 << mode); } + } else if (mode == ALL) { + if (enable) { + reg_val = 0x7F; + } else { + reg_val = 0x00; + } + } - /* Write value back to ENABLE register */ - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_ENABLE, reg_val) ; + /* Write value back to ENABLE register */ + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_ENABLE, reg_val); } /** @@ -1379,23 +1321,21 @@ void setMode(uint8_t mode, uint8_t enable) * * no interrupts */ -void enableLightSensor(void) -{ - /* Set default gain, interrupts, enable power, and enable sensor */ - setAmbientLightGain(DEFAULT_AGAIN); - setAmbientLightIntEnable(0); - enablePower() ; - setMode(AMBIENT_LIGHT, 1) ; +void enableLightSensor(void) { + /* Set default gain, interrupts, enable power, and enable sensor */ + setAmbientLightGain(DEFAULT_AGAIN); + setAmbientLightIntEnable(OFF); + enablePower(); + setMode(AMBIENT_LIGHT, ON); } /** * @brief Ends the light sensor on the APDS-9960 * */ -void disableLightSensor(void) -{ - setAmbientLightIntEnable(0) ; - setMode(AMBIENT_LIGHT, 0) ; +void disableLightSensor(void) { + setAmbientLightIntEnable(OFF); + setMode(AMBIENT_LIGHT, OFF); } /** @@ -1403,62 +1343,59 @@ void disableLightSensor(void) * * no interrupts */ -void enableProximitySensor(void) -{ - /* Set default gain, LED, interrupts, enable power, and enable sensor */ - setProximityGain(DEFAULT_PGAIN); - setLEDDrive(DEFAULT_LDRIVE) ; - setProximityIntEnable(0) ; - enablePower(); - setMode(PROXIMITY, 1) ; +void enableProximitySensor(void) { + /* Set default gain, LED, interrupts, enable power, and enable sensor */ + setProximityGain(DEFAULT_PGAIN); + setLEDDrive(DEFAULT_LDRIVE); + setProximityIntEnable(OFF); + enablePower(); + setMode(PROXIMITY, ON); } /** * @brief Ends the proximity sensor on the APDS-9960 * */ -void disableProximitySensor(void) -{ - setProximityIntEnable(0) ; - setMode(PROXIMITY, 0) ; +void disableProximitySensor(void) { + setProximityIntEnable(OFF); + setMode(PROXIMITY, OFF); } +#ifdef USE_APDS9960_GESTURE /** * @brief Starts the gesture recognition engine on the APDS-9960 * * no interrupts */ -void enableGestureSensor(void) -{ - /* Enable gesture mode - Set ENABLE to 0 (power off) - Set WTIME to 0xFF - Set AUX to LED_BOOST_300 - Enable PON, WEN, PEN, GEN in ENABLE - */ +void enableGestureSensor(void) { + /* Enable gesture mode + Set ENABLE to 0 (power off) + Set WTIME to 0xFF + Set AUX to LED_BOOST_300 + Enable PON, WEN, PEN, GEN in ENABLE + */ - resetGestureParameters(); - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_WTIME, 0xFF) ; - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_PPULSE, DEFAULT_GESTURE_PPULSE) ; - setLEDBoost(LED_BOOST_100); // tip from jonn26 - 100 for 300 ---- 200 from Adafruit - setGestureIntEnable(0) ; - setGestureMode(1); - enablePower() ; - setMode(WAIT, 1) ; - setMode(PROXIMITY, 1) ; - setMode(GESTURE, 1); + resetGestureParameters(); + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_WTIME, 0xFF); + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_PPULSE, DEFAULT_GESTURE_PPULSE); + setLEDBoost(LED_BOOST_100); // tip from jonn26 - 100 for 300 ---- 200 from Adafruit + setGestureIntEnable(OFF); + setGestureMode(ON); + enablePower(); + setMode(WAIT, ON); + setMode(PROXIMITY, ON); + setMode(GESTURE, ON); } /** * @brief Ends the gesture recognition engine on the APDS-9960 * */ -void disableGestureSensor(void) -{ - resetGestureParameters(); - setGestureIntEnable(0) ; - setGestureMode(0) ; - setMode(GESTURE, 0) ; +void disableGestureSensor(void) { + resetGestureParameters(); + setGestureIntEnable(OFF); + setGestureMode(OFF); + setMode(GESTURE, OFF); } /** @@ -1466,22 +1403,17 @@ void disableGestureSensor(void) * * @return True if gesture available. False otherwise. */ -bool isGestureAvailable(void) -{ - uint8_t val; +bool isGestureAvailable(void) { + uint8_t val; - /* Read value from GSTATUS register */ - val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_GSTATUS) ; + /* Read value from GSTATUS register */ + val = I2cRead8(APDS9960_I2C_ADDR, APDS9960_GSTATUS); - /* Shift and mask out GVALID bit */ - val &= APDS9960_GVALID; + /* Shift and mask out GVALID bit */ + val &= APDS9960_GVALID; - /* Return true/false based on GVALID bit */ - if( val == 1) { - return true; - } else { - return false; - } + /* Return true/false based on GVALID bit */ + return (val == 1); } /** @@ -1489,143 +1421,183 @@ bool isGestureAvailable(void) * * @return Number corresponding to gesture. -1 on error. */ -int16_t readGesture(void) -{ - uint8_t fifo_level = 0; - uint8_t bytes_read = 0; - uint8_t fifo_data[128]; - uint8_t gstatus; - uint16_t motion; - uint16_t i; - uint8_t gesture_loop_counter = 0; // don't loop forever later +int16_t readGesture(void) { + uint8_t fifo_level = 0; + uint8_t fifo_data[128]; + uint8_t gstatus; + int16_t motion; + uint16_t i; + uint8_t gesture_loop_counter = 0; // don't loop forever later + int8_t bytes_read = 0; - /* Make sure that power and gesture is on and data is valid */ - if( !isGestureAvailable() || !(getMode() & 0b01000001) ) { - return DIR_NONE; + /* Make sure that power and gesture is on and data is valid */ + if (!isGestureAvailable() || !(getMode() & 0b01000001)) { + return DIR_NONE; + } + + /* Keep looping as long as gesture data is valid */ + while (1) { + if (gesture_loop_counter == APDS9960_MAX_GESTURE_CYCLES) { // We will escape after a few loops + disableGestureSensor(); // stop the sensor to prevent problems with power consumption/blocking and return to the main loop + APDS9960_overload = true; // we report this as "long"-gesture + AddLog_P(LOG_LEVEL_DEBUG, PSTR("Sensor overload")); } + gesture_loop_counter += 1; - /* Keep looping as long as gesture data is valid */ - while(1) { - if (gesture_loop_counter == APDS9960_MAX_GESTURE_CYCLES){ // We will escape after a few loops - disableGestureSensor(); // stop the sensor to prevent problems with power consumption/blocking and return to the main loop - APDS9960_overload = true; // we report this as "long"-gesture - AddLog_P(LOG_LEVEL_DEBUG, PSTR("Sensor overload")); + /* Wait some time to collect next batch of FIFO data */ + delay(FIFO_PAUSE_TIME); + + /* Get the contents of the STATUS register. Is data still valid? */ + gstatus = I2cRead8(APDS9960_I2C_ADDR, APDS9960_GSTATUS); + + /* If we have valid data, read in FIFO */ + if ((gstatus & APDS9960_GVALID) == APDS9960_GVALID) { + /* Read the current FIFO level */ + fifo_level = I2cRead8(APDS9960_I2C_ADDR, APDS9960_GFLVL); + +#ifdef USE_DEBUG_DRIVER + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DRV: FIFO Level : %d"), fifo_level); +#endif // USE_DEBUG_DRIVER + + /* If there's stuff in the FIFO, read it into our data block */ + if (fifo_level > 0) { + bytes_read = (fifo_level * 4); + + if (I2cReadBuffer(APDS9960_I2C_ADDR, APDS9960_GFIFO_U, (uint8_t*)fifo_data, bytes_read)) { + return APDS9960_ERROR; } - gesture_loop_counter += 1; - /* Wait some time to collect next batch of FIFO data */ - delay(FIFO_PAUSE_TIME); - /* Get the contents of the STATUS register. Is data still valid? */ - gstatus = I2cRead8(APDS9960_I2C_ADDR, APDS9960_GSTATUS); +#ifdef USE_DEBUG_DRIVER + char output[(bytes_read * 2) + 1]; + char *ptr = &output[0]; - /* If we have valid data, read in FIFO */ - if( (gstatus & APDS9960_GVALID) == APDS9960_GVALID ) { + for ( i = 0; i < bytes_read; i++ ) { + ptr += sprintf(ptr, "%02X", fifo_data[i]); + } + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DRV: FIFO Dump : %s"), output); +#endif // USE_DEBUG_DRIVER - /* Read the current FIFO level */ - fifo_level = I2cRead8(APDS9960_I2C_ADDR,APDS9960_GFLVL) ; + /* If at least 1 set of data, sort the data into U/D/L/R */ + if (bytes_read >= 4) { + for (i = 0; i < bytes_read; i += 4) { + gesture_data.u_data[gesture_data.index] = fifo_data[i + 0]; + gesture_data.d_data[gesture_data.index] = fifo_data[i + 1]; + gesture_data.l_data[gesture_data.index] = fifo_data[i + 2]; + gesture_data.r_data[gesture_data.index] = fifo_data[i + 3]; + gesture_data.index++; + gesture_data.total_gestures++; + } - /* If there's stuff in the FIFO, read it into our data block */ - if( fifo_level > 0) { - bytes_read = wireReadDataBlock( APDS9960_GFIFO_U, - (uint8_t*)fifo_data, - (fifo_level * 4) ); - if( bytes_read == -1 ) { - return APDS9960_ERROR; - } - - /* If at least 1 set of data, sort the data into U/D/L/R */ - if( bytes_read >= 4 ) { - for( i = 0; i < bytes_read; i += 4 ) { - gesture_data_.u_data[gesture_data_.index] = \ - fifo_data[i + 0]; - gesture_data_.d_data[gesture_data_.index] = \ - fifo_data[i + 1]; - gesture_data_.l_data[gesture_data_.index] = \ - fifo_data[i + 2]; - gesture_data_.r_data[gesture_data_.index] = \ - fifo_data[i + 3]; - gesture_data_.index++; - gesture_data_.total_gestures++; - } - /* Filter and process gesture data. Decode near/far state */ - if( processGestureData() ) { - if( decodeGesture() ) { - //***TODO: U-Turn Gestures - } - } - /* Reset data */ - gesture_data_.index = 0; - gesture_data_.total_gestures = 0; - } - } - } else { - - /* Determine best guessed gesture and clean up */ - delay(FIFO_PAUSE_TIME); - decodeGesture(); - motion = gesture_motion_; - resetGestureParameters(); - return motion; + /* Filter and process gesture data. Decode near/far state */ + if (processGestureData()) { + if (decodeGesture()) { + // TODO(xx): U-Turn Gestures + } + } + /* Reset data */ + gesture_data.index = 0; + gesture_data.total_gestures = 0; } + } + } else { + /* Determine best guessed gesture and clean up */ + delay(FIFO_PAUSE_TIME); + decodeGesture(); + motion = gesture.motion_; + resetGestureParameters(); + return motion; } + } } +#endif // USE_APDS9960_GESTURE + /** * Turn the APDS-9960 on * */ -void enablePower(void) -{ - setMode(POWER, 1) ; +inline void enablePower(void) { + setMode(POWER, ON); } /** * Turn the APDS-9960 off * */ -void disablePower(void) -{ - setMode(POWER, 0) ; +inline void disablePower(void) { + setMode(POWER, OFF); } -/******************************************************************************* + +/******************************************************************************\ * Ambient light and color sensor controls - ******************************************************************************/ +\******************************************************************************/ - /** - * @brief Reads the ARGB-Data and fills color_data - * - */ - -void readAllColorAndProximityData(void) -{ - if (I2cReadBuffer(APDS9960_I2C_ADDR, APDS9960_CDATAL, (uint8_t *) &color_data, (uint16_t)9)) - { +#if defined(USE_APDS9960_COLOR) || defined(USE_APDS9960_PROXIMITY) +/** + * @brief Reads the ARGB-Data and fills color_data + */ +inline void readAllColorAndProximityData(void) { + if (I2cReadBuffer(APDS9960_I2C_ADDR, APDS9960_CDATAL, (uint8_t *) &color_data, (uint16_t)9)) { // not absolutely shure, if this is a correct way to do this, but it is very short // we fill the struct byte by byte } } -/******************************************************************************* +void APDS9960_adjustATime(void) { // not really used atm + // readAllColorAndProximityData(); + I2cValidRead16LE(&color_data.a, APDS9960_I2C_ADDR, APDS9960_CDATAL); + // disablePower(); + + if (color_data.a < (uint16_t)20) { + APDS9960_aTime = 0x40; + } else if (color_data.a < (uint16_t)40) { + APDS9960_aTime = 0x80; + } else if (color_data.a < (uint16_t)50) { + APDS9960_aTime = DEFAULT_ATIME; + } else if (color_data.a < (uint16_t)70) { + APDS9960_aTime = 0xc0; + } + + if (color_data.a < 200) { + APDS9960_aTime = 0xe9; + } + /* if (color_data.a < 10000){ + APDS9960_aTime = 0xF0; + }*/ + else { + APDS9960_aTime = 0xff; + } + + // disableLightSensor(); + I2cWrite8(APDS9960_I2C_ADDR, APDS9960_ATIME, APDS9960_aTime); + enablePower(); + enableLightSensor(); + delay(20); +} +#endif // USE_APDS9960_COLOR || USE_APDS9960_PROXIMITY + +/******************************************************************************\ * High-level gesture controls - ******************************************************************************/ +\******************************************************************************/ + +#ifdef USE_APDS9960_GESTURE /** * @brief Resets all the parameters in the gesture data member */ -void resetGestureParameters(void) -{ - gesture_data_.index = 0; - gesture_data_.total_gestures = 0; +void resetGestureParameters(void) { + gesture_data.index = 0; + gesture_data.total_gestures = 0; - gesture_ud_delta_ = 0; - gesture_lr_delta_ = 0; + gesture.ud_delta_ = 0; + gesture.lr_delta_ = 0; - gesture_ud_count_ = 0; - gesture_lr_count_ = 0; + gesture.ud_count_ = 0; + gesture.lr_count_ = 0; - gesture_state_ = 0; - gesture_motion_ = DIR_NONE; + gesture.state_ = 0; + gesture.motion_ = DIR_NONE; } /** @@ -1633,103 +1605,97 @@ void resetGestureParameters(void) * * @return True if near or far state seen. False otherwise. */ -bool processGestureData(void) -{ - uint8_t u_first = 0; - uint8_t d_first = 0; - uint8_t l_first = 0; - uint8_t r_first = 0; - uint8_t u_last = 0; - uint8_t d_last = 0; - uint8_t l_last = 0; - uint8_t r_last = 0; - uint16_t ud_ratio_first; - uint16_t lr_ratio_first; - uint16_t ud_ratio_last; - uint16_t lr_ratio_last; - uint16_t ud_delta; - uint16_t lr_delta; - uint16_t i; +bool processGestureData(void) { + uint8_t u_first = 0; + uint8_t d_first = 0; + uint8_t l_first = 0; + uint8_t r_first = 0; + uint8_t u_last = 0; + uint8_t d_last = 0; + uint8_t l_last = 0; + uint8_t r_last = 0; + uint16_t ud_ratio_first; + uint16_t lr_ratio_first; + uint16_t ud_ratio_last; + uint16_t lr_ratio_last; + uint16_t ud_delta; + uint16_t lr_delta; + uint16_t i; - /* If we have less than 4 total gestures, that's not enough */ - if( gesture_data_.total_gestures <= 4 ) { - return false; - } - - /* Check to make sure our data isn't out of bounds */ - if( (gesture_data_.total_gestures <= 32) && \ - (gesture_data_.total_gestures > 0) ) { - - /* Find the first value in U/D/L/R above the threshold */ - for( i = 0; i < gesture_data_.total_gestures; i++ ) { - if( (gesture_data_.u_data[i] > GESTURE_THRESHOLD_OUT) && - (gesture_data_.d_data[i] > GESTURE_THRESHOLD_OUT) && - (gesture_data_.l_data[i] > GESTURE_THRESHOLD_OUT) && - (gesture_data_.r_data[i] > GESTURE_THRESHOLD_OUT) ) { - - u_first = gesture_data_.u_data[i]; - d_first = gesture_data_.d_data[i]; - l_first = gesture_data_.l_data[i]; - r_first = gesture_data_.r_data[i]; - break; - } - } - - /* If one of the _first values is 0, then there is no good data */ - if( (u_first == 0) || (d_first == 0) || \ - (l_first == 0) || (r_first == 0) ) { - - return false; - } - /* Find the last value in U/D/L/R above the threshold */ - for( i = gesture_data_.total_gestures - 1; i >= 0; i-- ) { - - if( (gesture_data_.u_data[i] > GESTURE_THRESHOLD_OUT) && - (gesture_data_.d_data[i] > GESTURE_THRESHOLD_OUT) && - (gesture_data_.l_data[i] > GESTURE_THRESHOLD_OUT) && - (gesture_data_.r_data[i] > GESTURE_THRESHOLD_OUT) ) { - - u_last = gesture_data_.u_data[i]; - d_last = gesture_data_.d_data[i]; - l_last = gesture_data_.l_data[i]; - r_last = gesture_data_.r_data[i]; - break; - } - } - } - - /* Calculate the first vs. last ratio of up/down and left/right */ - ud_ratio_first = ((u_first - d_first) * 100) / (u_first + d_first); - lr_ratio_first = ((l_first - r_first) * 100) / (l_first + r_first); - ud_ratio_last = ((u_last - d_last) * 100) / (u_last + d_last); - lr_ratio_last = ((l_last - r_last) * 100) / (l_last + r_last); - - /* Determine the difference between the first and last ratios */ - ud_delta = ud_ratio_last - ud_ratio_first; - lr_delta = lr_ratio_last - lr_ratio_first; - - /* Accumulate the UD and LR delta values */ - gesture_ud_delta_ += ud_delta; - gesture_lr_delta_ += lr_delta; - - /* Determine U/D gesture */ - if( gesture_ud_delta_ >= GESTURE_SENSITIVITY_1 ) { - gesture_ud_count_ = 1; - } else if( gesture_ud_delta_ <= -GESTURE_SENSITIVITY_1 ) { - gesture_ud_count_ = -1; - } else { - gesture_ud_count_ = 0; - } - - /* Determine L/R gesture */ - if( gesture_lr_delta_ >= GESTURE_SENSITIVITY_1 ) { - gesture_lr_count_ = 1; - } else if( gesture_lr_delta_ <= -GESTURE_SENSITIVITY_1 ) { - gesture_lr_count_ = -1; - } else { - gesture_lr_count_ = 0; - } + /* If we have less than 4 total gestures, that's not enough */ + if (gesture_data.total_gestures <= 4) { return false; + } + + /* Check to make sure our data isn't out of bounds */ + if ((gesture_data.total_gestures <= 32) && \ + (gesture_data.total_gestures > 0)) { + /* Find the first value in U/D/L/R above the threshold */ + for (i = 0; i < gesture_data.total_gestures; i++) { + if ((gesture_data.u_data[i] > GESTURE_THRESHOLD_OUT) && + (gesture_data.d_data[i] > GESTURE_THRESHOLD_OUT) && + (gesture_data.l_data[i] > GESTURE_THRESHOLD_OUT) && + (gesture_data.r_data[i] > GESTURE_THRESHOLD_OUT) ) { + u_first = gesture_data.u_data[i]; + d_first = gesture_data.d_data[i]; + l_first = gesture_data.l_data[i]; + r_first = gesture_data.r_data[i]; + break; + } + } + + /* If one of the _first values is 0, then there is no good data */ + if ((u_first == 0) || (d_first == 0) || (l_first == 0) || (r_first == 0)) { + return false; + } + + /* Find the last value in U/D/L/R above the threshold */ + for (i = gesture_data.total_gestures - 1; i >= 0; i--) { + if ((gesture_data.u_data[i] > GESTURE_THRESHOLD_OUT) && + (gesture_data.d_data[i] > GESTURE_THRESHOLD_OUT) && + (gesture_data.l_data[i] > GESTURE_THRESHOLD_OUT) && + (gesture_data.r_data[i] > GESTURE_THRESHOLD_OUT)) { + u_last = gesture_data.u_data[i]; + d_last = gesture_data.d_data[i]; + l_last = gesture_data.l_data[i]; + r_last = gesture_data.r_data[i]; + break; + } + } + } + + /* Calculate the first vs. last ratio of up/down and left/right */ + ud_ratio_first = ((u_first - d_first) * 100) / (u_first + d_first); + lr_ratio_first = ((l_first - r_first) * 100) / (l_first + r_first); + ud_ratio_last = ((u_last - d_last) * 100) / (u_last + d_last); + lr_ratio_last = ((l_last - r_last) * 100) / (l_last + r_last); + + /* Determine the difference between the first and last ratios */ + ud_delta = ud_ratio_last - ud_ratio_first; + lr_delta = lr_ratio_last - lr_ratio_first; + + /* Accumulate the UD and LR delta values */ + gesture.ud_delta_ += ud_delta; + gesture.lr_delta_ += lr_delta; + + /* Determine U/D gesture */ + if (gesture.ud_delta_ >= GESTURE_SENSITIVITY_1) { + gesture.ud_count_ = 1; + } else if (gesture.ud_delta_ <= -GESTURE_SENSITIVITY_1) { + gesture.ud_count_ = -1; + } else { + gesture.ud_count_ = 0; + } + + /* Determine L/R gesture */ + if (gesture.lr_delta_ >= GESTURE_SENSITIVITY_1) { + gesture.lr_count_ = 1; + } else if (gesture.lr_delta_ <= -GESTURE_SENSITIVITY_1) { + gesture.lr_count_ = -1; + } else { + gesture.lr_count_ = 0; + } + return false; } /** @@ -1737,213 +1703,232 @@ bool processGestureData(void) * * @return True if near/far event. False otherwise. */ -bool decodeGesture(void) -{ - - /* Determine swipe direction */ - if( (gesture_ud_count_ == -1) && (gesture_lr_count_ == 0) ) { - gesture_motion_ = DIR_UP; - } else if( (gesture_ud_count_ == 1) && (gesture_lr_count_ == 0) ) { - gesture_motion_ = DIR_DOWN; - } else if( (gesture_ud_count_ == 0) && (gesture_lr_count_ == 1) ) { - gesture_motion_ = DIR_RIGHT; - } else if( (gesture_ud_count_ == 0) && (gesture_lr_count_ == -1) ) { - gesture_motion_ = DIR_LEFT; - } else if( (gesture_ud_count_ == -1) && (gesture_lr_count_ == 1) ) { - if( abs(gesture_ud_delta_) > abs(gesture_lr_delta_) ) { - gesture_motion_ = DIR_UP; - } else { - gesture_motion_ = DIR_RIGHT; - } - } else if( (gesture_ud_count_ == 1) && (gesture_lr_count_ == -1) ) { - if( abs(gesture_ud_delta_) > abs(gesture_lr_delta_) ) { - gesture_motion_ = DIR_DOWN; - } else { - gesture_motion_ = DIR_LEFT; - } - } else if( (gesture_ud_count_ == -1) && (gesture_lr_count_ == -1) ) { - if( abs(gesture_ud_delta_) > abs(gesture_lr_delta_) ) { - gesture_motion_ = DIR_UP; - } else { - gesture_motion_ = DIR_LEFT; - } - } else if( (gesture_ud_count_ == 1) && (gesture_lr_count_ == 1) ) { - if( abs(gesture_ud_delta_) > abs(gesture_lr_delta_) ) { - gesture_motion_ = DIR_DOWN; - } else { - gesture_motion_ = DIR_RIGHT; - } +bool decodeGesture(void) { + /* Determine swipe direction */ + if ((gesture.ud_count_ == -1) && (gesture.lr_count_ == 0)) { + gesture.motion_ = DIR_UP; + } else if ((gesture.ud_count_ == 1) && (gesture.lr_count_ == 0)) { + gesture.motion_ = DIR_DOWN; + } else if ((gesture.ud_count_ == 0) && (gesture.lr_count_ == 1)) { + gesture.motion_ = DIR_RIGHT; + } else if ((gesture.ud_count_ == 0) && (gesture.lr_count_ == -1)) { + gesture.motion_ = DIR_LEFT; + } else if ((gesture.ud_count_ == -1) && (gesture.lr_count_ == 1)) { + if (abs(gesture.ud_delta_) > abs(gesture.lr_delta_)) { + gesture.motion_ = DIR_UP; } else { - return false; + gesture.motion_ = DIR_RIGHT; } + } else if ((gesture.ud_count_ == 1) && (gesture.lr_count_ == -1)) { + if (abs(gesture.ud_delta_) > abs(gesture.lr_delta_)) { + gesture.motion_ = DIR_DOWN; + } else { + gesture.motion_ = DIR_LEFT; + } + } else if ((gesture.ud_count_ == -1) && (gesture.lr_count_ == -1)) { + if (abs(gesture.ud_delta_) > abs(gesture.lr_delta_)) { + gesture.motion_ = DIR_UP; + } else { + gesture.motion_ = DIR_LEFT; + } + } else if ((gesture.ud_count_ == 1) && (gesture.lr_count_ == 1)) { + if (abs(gesture.ud_delta_) > abs(gesture.lr_delta_)) { + gesture.motion_ = DIR_DOWN; + } else { + gesture.motion_ = DIR_RIGHT; + } + } else { + return false; + } - return true; + return true; } void handleGesture(void) { - if (isGestureAvailable() ) { + if (isGestureAvailable()) { switch (readGesture()) { case DIR_UP: - AddLog_P(LOG_LEVEL_DEBUG, PSTR("UP")); - snprintf_P(currentGesture, sizeof(currentGesture), PSTR("Up")); + AddLog_P(LOG_LEVEL_DEBUG, GESTURE_UP); + snprintf_P(currentGesture, sizeof(currentGesture), GESTURE_UP); break; case DIR_DOWN: - AddLog_P(LOG_LEVEL_DEBUG, PSTR("DOWN")); - snprintf_P(currentGesture, sizeof(currentGesture), PSTR("Down")); + AddLog_P(LOG_LEVEL_DEBUG, GESTURE_DOWN); + snprintf_P(currentGesture, sizeof(currentGesture), GESTURE_DOWN); break; case DIR_LEFT: - AddLog_P(LOG_LEVEL_DEBUG, PSTR("LEFT")); - snprintf_P(currentGesture, sizeof(currentGesture), PSTR("Left")); + AddLog_P(LOG_LEVEL_DEBUG, GESTURE_LEFT); + snprintf_P(currentGesture, sizeof(currentGesture), GESTURE_LEFT); break; case DIR_RIGHT: - AddLog_P(LOG_LEVEL_DEBUG, PSTR("RIGHT")); - snprintf_P(currentGesture, sizeof(currentGesture), PSTR("Right")); + AddLog_P(LOG_LEVEL_DEBUG, GESTURE_RIGHT); + snprintf_P(currentGesture, sizeof(currentGesture), GESTURE_RIGHT); break; default: - if(APDS9960_overload) - { - AddLog_P(LOG_LEVEL_DEBUG, PSTR("LONG")); - snprintf_P(currentGesture, sizeof(currentGesture), PSTR("Long")); - } - else{ - AddLog_P(LOG_LEVEL_DEBUG, PSTR("NONE")); - snprintf_P(currentGesture, sizeof(currentGesture), PSTR("None")); - } + if (APDS9960_overload) { + AddLog_P(LOG_LEVEL_DEBUG, GESTURE_LONG); + snprintf_P(currentGesture, sizeof(currentGesture), GESTURE_LONG); + } else { + AddLog_P(LOG_LEVEL_DEBUG, GESTURE_NONE); + snprintf_P(currentGesture, sizeof(currentGesture), GESTURE_NONE); + } + break; } MqttPublishSensor(); } } -void APDS9960_adjustATime(void) // not really used atm -{ - //readAllColorAndProximityData(); - I2cValidRead16LE(&color_data.a, APDS9960_I2C_ADDR, APDS9960_CDATAL); - //disablePower(); - - if (color_data.a < (uint16_t)20){ - APDS9960_aTime = 0x40; - } - else if (color_data.a < (uint16_t)40){ - APDS9960_aTime = 0x80; - } - else if (color_data.a < (uint16_t)50){ - APDS9960_aTime = DEFAULT_ATIME; - } - else if (color_data.a < (uint16_t)70){ - APDS9960_aTime = 0xc0; - } - if (color_data.a < 200){ - APDS9960_aTime = 0xe9; - } -/* if (color_data.a < 10000){ - APDS9960_aTime = 0xF0; - }*/ - else{ - APDS9960_aTime = 0xff; - } - - //disableLightSensor(); - I2cWrite8(APDS9960_I2C_ADDR, APDS9960_ATIME, APDS9960_aTime); - enablePower(); - enableLightSensor(); - delay(20); -} - - -void APDS9960_loop(void) -{ - if (recovery_loop_counter > 0){ +void APDS9960_loop(void) { + if (recovery_loop_counter > 0) { recovery_loop_counter -= 1; } - if (recovery_loop_counter == 1 && APDS9960_overload){ //restart sensor just before the end of recovery from long press + + if (recovery_loop_counter == 1 && APDS9960_overload) { // restart sensor just before the end of recovery from long press enableGestureSensor(); APDS9960_overload = false; Response_P(PSTR("{\"Gesture\":\"On\"}")); - MqttPublishPrefixTopic_P(RESULT_OR_TELE, mqtt_data); // only after the long break we report, that we are online again + MqttPublishPrefixTopic_P(RESULT_OR_TELE, mqtt_data); // only after the long break we report, that we are online again gesture_mode = 1; } if (gesture_mode) { - if (recovery_loop_counter == 0){ + if (recovery_loop_counter == 0) { handleGesture(); - if (APDS9960_overload) - { + if (APDS9960_overload) { disableGestureSensor(); recovery_loop_counter = APDS9960_LONG_RECOVERY; // long pause after overload/long press - number of stateloops Response_P(PSTR("{\"Gesture\":\"Off\"}")); MqttPublishPrefixTopic_P(RESULT_OR_TELE, mqtt_data); gesture_mode = 0; - } } + } } } -void APDS9960_detect(void) -{ - if (APDS9960type || I2cActive(APDS9960_I2C_ADDR)) { return; } +#endif // USE_APDS9960_GESTURE - APDS9960type = I2cRead8(APDS9960_I2C_ADDR, APDS9960_ID); - if (APDS9960type == APDS9960_CHIPID_1 || APDS9960type == APDS9960_CHIPID_2) { +void APDS9960_detect(void) { + if (APDS9960_type || I2cActive(APDS9960_I2C_ADDR)) { return; } + + APDS9960_type = I2cRead8(APDS9960_I2C_ADDR, APDS9960_ID); + +#ifdef USE_DEBUG_DRIVER + // Debug new chip + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DRV: %s Chip %X"), APDS9960_TAG, APDS9960_type); +#endif // USE_DEBUG_DRIVER + + if (APDS9960_type == APDS9960_CHIPID_1 || APDS9960_type == APDS9960_CHIPID_2 || APDS9960_type == APDS9960_CHIPID_3) { if (APDS9960_init()) { - I2cSetActiveFound(APDS9960_I2C_ADDR, APDS9960stype); + I2cSetActiveFound(APDS9960_I2C_ADDR, APDS9960_TAG); enableProximitySensor(); + +#if defined(USE_APDS9960_GESTURE) && USE_APDS9960_STARTMODE == APDS9960_MODE_GESTURE + gesture_mode = 1; enableGestureSensor(); +#endif // USE_APDS9960_GESTURE + +#if ( defined(USE_APDS9960_COLOR) || defined(USE_APDS9960_PROXIMITY) ) && USE_APDS9960_STARTMODE == APDS9960_MODE_COLOR + gesture_mode = 0; + enableLightSensor(); + APDS9960_overload = false; +#endif // USE_APDS9960_GESTURE } else { - APDS9960type = 0; + APDS9960_type = 0; } } else { - APDS9960type = 0; + APDS9960_type = 0; } + +#ifdef USE_APDS9960_GESTURE currentGesture[0] = '\0'; +#endif // USE_APDS9960_GESTURE } /*********************************************************************************************\ * Presentation \*********************************************************************************************/ -void APDS9960_show(bool json) -{ - if (!APDS9960type) { return; } +void APDS9960_show(bool json) { + if (!APDS9960_type) { return; } if (!gesture_mode && !APDS9960_overload) { - char red_chr[10]; - char green_chr[10]; - char blue_chr[10]; - char ambient_chr[10]; - char cct_chr[10]; - char prox_chr[10]; + +#if defined(USE_APDS9960_COLOR) || defined(USE_APDS9960_PROXIMITY) + uint16_t ambient; readAllColorAndProximityData(); + ambient = color_data.a/4; - sprintf (ambient_chr, "%u", color_data.a/4); - sprintf (red_chr, "%u", color_data.r); - sprintf (green_chr, "%u", color_data.g); - sprintf (blue_chr, "%u", color_data.b ); - sprintf (prox_chr, "%u", color_data.p ); - - /* disableLightSensor(); + /* disableLightSensor(); I2cWrite8(APDS9960_I2C_ADDR, APDS9960_ATIME, DEFAULT_ATIME); // reset to default enableLightSensor();*/ +#ifdef USE_APDS9960_COLOR calculateColorTemperature(); // and calculate Lux - sprintf (cct_chr, "%u", color_data.cct); - +#endif // USE_APDS9960_COLOR if (json) { - ResponseAppend_P(PSTR(",\"%s\":{\"Red\":%s,\"Green\":%s,\"Blue\":%s,\"Ambient\":%s,\"CCT\":%s,\"Proximity\":%s}"), - APDS9960stype, red_chr, green_chr, blue_chr, ambient_chr, cct_chr, prox_chr); +#if defined(USE_APDS9960_COLOR) && defined(USE_APDS9960_PROXIMITY) + ResponseAppend_P(PSTR(",\"%s\":{\"Red\":%u,\"Green\":%u,\"Blue\":%u,\"" D_JSON_ILLUMINANCE "\":%u,\"CCT\":%u,\"Proximity\":%u}"), + APDS9960_TAG, + color_data.r, + color_data.g, + color_data.b, + ambient, + color_data.cct, + color_data.p); +#else + +#ifdef USE_APDS9960_COLOR + ResponseAppend_P(PSTR(",\"%s\":{\"Red\":%u,\"Green\":%u,\"Blue\":%u,\"" D_JSON_ILLUMINANCE "\":%u,\"CCT\":%u}"), + APDS9960_TAG, + color_data.r, + color_data.g, + color_data.b, + ambient, + color_data.cct); +#endif // USE_APDS9960_COLOR + +#ifdef USE_APDS9960_PROXIMITY + ResponseAppend_P(PSTR(",\"%s\":{\"Proximity\":%u}"), + APDS9960_TAG, + color_data.p); +#endif // USE_APDS9960_PROXIMITY + +#endif // USE_APDS9960_COLOR && USE_APDS9960_PROXIMITY #ifdef USE_WEBSERVER } else { - WSContentSend_PD(HTTP_APDS_9960_SNS, red_chr, green_chr, blue_chr, ambient_chr, cct_chr, prox_chr ); + +#ifdef USE_APDS9960_COLOR + WSContentSend_PD(HTTP_SNS_COLOR_RED, APDS9960_TAG, color_data.r); + WSContentSend_PD(HTTP_SNS_COLOR_GREEN, APDS9960_TAG, color_data.g); + WSContentSend_PD(HTTP_SNS_COLOR_BLUE, APDS9960_TAG, color_data.b); + WSContentSend_PD(HTTP_SNS_ILLUMINANCE, APDS9960_TAG, ambient); + WSContentSend_PD(HTTP_SNS_CCT, APDS9960_TAG, color_data.cct); +#endif // USE_APDS9960_COLOR + +#ifdef USE_APDS9960_PROXIMITY + WSContentSend_PD(HTTP_SNS_PROXIMITY, APDS9960_TAG, color_data.p); +#endif // USE_APDS9960_PROXIMITY + #endif // USE_WEBSERVER } - } - else { - if (json && (currentGesture[0] != '\0' )) { - ResponseAppend_P(PSTR(",\"%s\":{\"%s\":1}"), APDS9960stype, currentGesture); - currentGesture[0] = '\0'; +#endif // USE_APDS9960_COLOR || USE_APDS9960_PROXIMITY + +#ifdef USE_APDS9960_GESTURE + } else { + if (currentGesture[0] != '\0') { + if (json) { + ResponseAppend_P(PSTR(",\"%s\":{\"%s\":1}"), APDS9960_TAG, currentGesture); +#ifdef USE_WEBSERVER + } else { + WSContentSend_PD(HTTP_SNS_GESTURE, APDS9960_TAG, currentGesture); +#endif // USE_WEBSERVER + currentGesture[0] = '\0'; + } } +#endif // USE_APDS9960_GESTURE + } } @@ -1958,19 +1943,21 @@ void APDS9960_show(bool json) * Sensor27 | 2 / On | Enable gesture mode with half gain \*********************************************************************************************/ -bool APDS9960CommandSensor(void) -{ +bool APDS9960CommandSensor(void) { bool serviced = true; switch (XdrvMailbox.payload) { - case 0: // Off + case 0: // Off +#ifdef USE_APDS9960_GESTURE disableGestureSensor(); +#endif // USE_APDS9960_GESTURE gesture_mode = 0; enableLightSensor(); - APDS9960_overload = false; // prevent unwanted re-enabling + APDS9960_overload = false; // prevent unwanted re-enabling break; - case 1: // On with default gain of 4x - if (APDS9960type) { +#ifdef USE_APDS9960_GESTURE + case 1: // On with default gain of 4x + if (APDS9960_type) { setGestureGain(DEFAULT_GGAIN); setProximityGain(DEFAULT_PGAIN); disableLightSensor(); @@ -1979,7 +1966,7 @@ bool APDS9960CommandSensor(void) } break; case 2: // gain of 2x , needed for some models - if (APDS9960type) { + if (APDS9960_type) { setGestureGain(GGAIN_2X); setProximityGain(PGAIN_2X); disableLightSensor(); @@ -1987,15 +1974,16 @@ bool APDS9960CommandSensor(void) gesture_mode = 1; } break; +#endif // USE_APDS9960_GESTURE default: int temp_aTime = (uint8_t)XdrvMailbox.payload; - if (temp_aTime > 2 && temp_aTime < 256){ + if (temp_aTime > 2 && temp_aTime < 256) { disablePower(); I2cWrite8(APDS9960_I2C_ADDR, APDS9960_ATIME, temp_aTime); enablePower(); enableLightSensor(); } - break; + break; } Response_P(S_JSON_SENSOR_INDEX_SVALUE, XSNS_27, GetStateText(gesture_mode)); @@ -2006,28 +1994,28 @@ bool APDS9960CommandSensor(void) * Interface \*********************************************************************************************/ -bool Xsns27(uint8_t function) -{ +bool Xsns27(uint8_t function) { if (!I2cEnabled(XI2C_21)) { return false; } bool result = false; if (FUNC_INIT == function) { APDS9960_detect(); - } - else if (APDS9960type) { + } else if (APDS9960_type) { switch (function) { +#ifdef USE_APDS9960_GESTURE case FUNC_EVERY_50_MSECOND: - APDS9960_loop(); - break; + APDS9960_loop(); + break; +#endif // USE_APDS9960_GESTURE case FUNC_COMMAND_SENSOR: - if (XSNS_27 == XdrvMailbox.index) { + if (XSNS_27 == XdrvMailbox.index) { result = APDS9960CommandSensor(); - } - break; + } + break; case FUNC_JSON_APPEND: - APDS9960_show(1); - break; + APDS9960_show(1); + break; #ifdef USE_WEBSERVER case FUNC_WEB_SENSOR: APDS9960_show(0); @@ -2037,5 +2025,6 @@ bool Xsns27(uint8_t function) } return result; } + #endif // USE_APDS9960 #endif // USE_I2C diff --git a/tasmota/xsns_28_tm1638.ino b/tasmota/xsns_28_tm1638.ino index da4de6999..9df220848 100644 --- a/tasmota/xsns_28_tm1638.ino +++ b/tasmota/xsns_28_tm1638.ino @@ -144,10 +144,10 @@ uint8_t Tm1638GetButtons(void) void TmInit(void) { tm1638_type = 0; - if ((pin[GPIO_TM16CLK] < 99) && (pin[GPIO_TM16DIO] < 99) && (pin[GPIO_TM16STB] < 99)) { - tm1638_clock_pin = pin[GPIO_TM16CLK]; - tm1638_data_pin = pin[GPIO_TM16DIO]; - tm1638_strobe_pin = pin[GPIO_TM16STB]; + if (PinUsed(GPIO_TM16CLK) && PinUsed(GPIO_TM16DIO) && PinUsed(GPIO_TM16STB)) { + tm1638_clock_pin = Pin(GPIO_TM16CLK); + tm1638_data_pin = Pin(GPIO_TM16DIO); + tm1638_strobe_pin = Pin(GPIO_TM16STB); pinMode(tm1638_data_pin, OUTPUT); pinMode(tm1638_clock_pin, OUTPUT); diff --git a/tasmota/xsns_29_mcp230xx.ino b/tasmota/xsns_29_mcp230xx.ino index 0a831d869..208fbcdd8 100644 --- a/tasmota/xsns_29_mcp230xx.ino +++ b/tasmota/xsns_29_mcp230xx.ino @@ -306,6 +306,9 @@ void MCP230xx_CheckForInterrupt(void) { ResponseTime_P(PSTR(",\"MCP230XX_INT\":{\"D%i\":%i,\"MS\":%lu}}"), intp+(mcp230xx_port*8), ((mcp230xx_intcap >> intp) & 0x01),millis_since_last_int); MqttPublishPrefixTopic_P(RESULT_OR_STAT, PSTR("MCP230XX_INT")); + if (Settings.flag3.hass_tele_on_power) { // SetOption59 - Send tele/%topic%/SENSOR in addition to stat/%topic%/RESULT + MqttPublishSensor(); + } } if (int_event) { char command[19]; // Theoretical max = 'event MCPINT_D16=1' so 18 + 1 (for the \n) diff --git a/tasmota/xsns_31_ccs811.ino b/tasmota/xsns_31_ccs811.ino index a968319cb..71bac8240 100644 --- a/tasmota/xsns_31_ccs811.ino +++ b/tasmota/xsns_31_ccs811.ino @@ -65,7 +65,9 @@ void CCS811Update(void) // Perform every n second TVOC = ccs.getTVOC(); eCO2 = ccs.geteCO2(); CCS811_ready = 1; - if (global_update && global_humidity>0 && global_temperature!=9999) { ccs.setEnvironmentalData((uint8_t)global_humidity, global_temperature); } + if (global_update && (global_humidity > 0) && !isnan(global_temperature_celsius)) { + ccs.setEnvironmentalData((uint8_t)global_humidity, global_temperature_celsius); + } ecnt = 0; } } else { diff --git a/tasmota/xsns_34_hx711.ino b/tasmota/xsns_34_hx711.ino index 44bb9036c..8145a5a55 100644 --- a/tasmota/xsns_34_hx711.ino +++ b/tasmota/xsns_34_hx711.ino @@ -282,9 +282,9 @@ long HxWeight(void) void HxInit(void) { Hx.type = 0; - if ((pin[GPIO_HX711_DAT] < 99) && (pin[GPIO_HX711_SCK] < 99)) { - Hx.pin_sck = pin[GPIO_HX711_SCK]; - Hx.pin_dout = pin[GPIO_HX711_DAT]; + if (PinUsed(GPIO_HX711_DAT) && PinUsed(GPIO_HX711_SCK)) { + Hx.pin_sck = Pin(GPIO_HX711_SCK); + Hx.pin_dout = Pin(GPIO_HX711_DAT); pinMode(Hx.pin_sck, OUTPUT); pinMode(Hx.pin_dout, INPUT); @@ -494,7 +494,7 @@ void HandleHxAction(void) AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_HX711); - if (WebServer->hasArg("save")) { + if (Webserver->hasArg("save")) { HxSaveSettings(); HandleConfiguration(); return; @@ -502,7 +502,7 @@ void HandleHxAction(void) char stemp1[20]; - if (WebServer->hasArg("reset")) { + if (Webserver->hasArg("reset")) { snprintf_P(stemp1, sizeof(stemp1), PSTR("Sensor34 1")); // Reset ExecuteWebCommand(stemp1, SRC_WEBGUI); @@ -510,7 +510,7 @@ void HandleHxAction(void) return; } - if (WebServer->hasArg("calibrate")) { + if (Webserver->hasArg("calibrate")) { WebGetArg("p1", stemp1, sizeof(stemp1)); Settings.weight_reference = (!strlen(stemp1)) ? 0 : (unsigned long)(CharToFloat(stemp1) * 1000); @@ -593,7 +593,7 @@ bool Xsns34(uint8_t function) WSContentSend_P(HTTP_BTN_MENU_HX711); break; case FUNC_WEB_ADD_HANDLER: - WebServer->on("/" WEB_HANDLE_HX711, HandleHxAction); + Webserver->on("/" WEB_HANDLE_HX711, HandleHxAction); break; #endif // USE_HX711_GUI #endif // USE_WEBSERVER diff --git a/tasmota/xsns_35_tx20.ino b/tasmota/xsns_35_tx20.ino index 06d715ac0..cf41a41fb 100644 --- a/tasmota/xsns_35_tx20.ino +++ b/tasmota/xsns_35_tx20.ino @@ -206,7 +206,7 @@ void TX2xStartRead(void) delayMicroseconds(TX2X_BIT_TIME / 2); for (int32_t bitcount = 41; bitcount > 0; bitcount--) { - uint32_t dpin = (digitalRead(pin[GPIO_TX2X_TXD_BLACK])); + uint32_t dpin = (digitalRead(Pin(GPIO_TX2X_TXD_BLACK))); #ifdef USE_TX23_WIND_SENSOR dpin ^= 1; #endif // USE_TX23_WIND_SENSOR @@ -263,7 +263,7 @@ void TX2xStartRead(void) // Must clear this bit in the interrupt register, // it gets set even when interrupts are disabled - GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, 1 << pin[GPIO_TX2X_TXD_BLACK]); + GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, 1 << Pin(GPIO_TX2X_TXD_BLACK)); } bool Tx2xAvailable(void) @@ -338,13 +338,13 @@ void Tx2xRead(void) // TX23 start transmission by pulling down TxD line for at minimum 500ms // so we pull TxD signal to low every 3 seconds tx23_stage = 0; - pinMode(pin[GPIO_TX2X_TXD_BLACK], OUTPUT); - digitalWrite(pin[GPIO_TX2X_TXD_BLACK], LOW); + pinMode(Pin(GPIO_TX2X_TXD_BLACK), OUTPUT); + digitalWrite(Pin(GPIO_TX2X_TXD_BLACK), LOW); } else if ((uptime % TX23_READ_INTERVAL)==1) { // after pulling down TxD: pull-up TxD every x+1 seconds // to trigger TX23 start transmission tx23_stage = 1; // first rising signal is invalid - pinMode(pin[GPIO_TX2X_TXD_BLACK], INPUT_PULLUP); + pinMode(Pin(GPIO_TX2X_TXD_BLACK), INPUT_PULLUP); } #endif // USE_TX23_WIND_SENSOR if (Tx2xAvailable()) { @@ -465,12 +465,12 @@ void Tx2xInit(void) #endif // USE_TX2X_WIND_SENSOR_NOSTATISTICS #ifdef USE_TX23_WIND_SENSOR tx23_stage = 0; - pinMode(pin[GPIO_TX2X_TXD_BLACK], OUTPUT); - digitalWrite(pin[GPIO_TX2X_TXD_BLACK], LOW); + pinMode(Pin(GPIO_TX2X_TXD_BLACK), OUTPUT); + digitalWrite(Pin(GPIO_TX2X_TXD_BLACK), LOW); #else // USE_TX23_WIND_SENSOR - pinMode(pin[GPIO_TX2X_TXD_BLACK], INPUT); + pinMode(Pin(GPIO_TX2X_TXD_BLACK), INPUT); #endif // USE_TX23_WIND_SENSOR - attachInterrupt(pin[GPIO_TX2X_TXD_BLACK], TX2xStartRead, RISING); + attachInterrupt(Pin(GPIO_TX2X_TXD_BLACK), TX2xStartRead, RISING); } int32_t Tx2xNormalize(int32_t value) @@ -582,7 +582,7 @@ bool Xsns35(uint8_t function) { bool result = false; - if (pin[GPIO_TX2X_TXD_BLACK] < 99) { + if (PinUsed(GPIO_TX2X_TXD_BLACK)) { switch (function) { case FUNC_INIT: Tx2xInit(); diff --git a/tasmota/xsns_36_mgc3130.ino b/tasmota/xsns_36_mgc3130.ino index 4dd76155b..036ecf009 100644 --- a/tasmota/xsns_36_mgc3130.ino +++ b/tasmota/xsns_36_mgc3130.ino @@ -39,14 +39,11 @@ #define MGC3130_I2C_ADDR 0x42 -#define MGC3130_xfer pin[GPIO_MGC3130_XFER] -#define MGC3130_reset pin[GPIO_MGC3130_RESET] - - +uint8_t MGC3130_xfer = 0; +uint8_t MGC3130_reset = 0; bool MGC3130_type = false; char MGC3130stype[] = "MGC3130"; - #define MGC3130_SYSTEM_STATUS 0x15 #define MGC3130_REQUEST_MSG 0x06 #define MGC3130_FW_VERSION 0x83 @@ -478,6 +475,9 @@ void MGC3130_detect(void) { if (MGC3130_type || I2cActive(MGC3130_I2C_ADDR)) { return; } + MGC3130_xfer = Pin(GPIO_MGC3130_XFER); + MGC3130_reset = Pin(GPIO_MGC3130_RESET); + pinMode(MGC3130_xfer, INPUT_PULLUP); pinMode(MGC3130_reset, OUTPUT); digitalWrite(MGC3130_reset, LOW); @@ -588,7 +588,7 @@ bool Xsns36(uint8_t function) bool result = false; - if ((FUNC_INIT == function) && (pin[GPIO_MGC3130_XFER] < 99) && (pin[GPIO_MGC3130_RESET] < 99)) { + if ((FUNC_INIT == function) && PinUsed(GPIO_MGC3130_XFER) && PinUsed(GPIO_MGC3130_RESET)) { MGC3130_detect(); } else if (MGC3130_type) { diff --git a/tasmota/xsns_37_rfsensor.ino b/tasmota/xsns_37_rfsensor.ino index d58e06b66..53945f2bb 100644 --- a/tasmota/xsns_37_rfsensor.ino +++ b/tasmota/xsns_37_rfsensor.ino @@ -607,9 +607,9 @@ void RfSnsInit(void) RfSnsInitAlectoV2(); #endif if (rfsns_any_sensor) { - rfsns_rf_bit = digitalPinToBitMask(pin[GPIO_RF_SENSOR]); - rfsns_rf_port = digitalPinToPort(pin[GPIO_RF_SENSOR]); - pinMode(pin[GPIO_RF_SENSOR], INPUT); + rfsns_rf_bit = digitalPinToBitMask(Pin(GPIO_RF_SENSOR)); + rfsns_rf_port = digitalPinToPort(Pin(GPIO_RF_SENSOR)); + pinMode(Pin(GPIO_RF_SENSOR), INPUT); } else { free(rfsns_raw_signal); rfsns_raw_signal = nullptr; @@ -654,18 +654,18 @@ bool Xsns37(uint8_t function) { bool result = false; - if ((pin[GPIO_RF_SENSOR] < 99) && (FUNC_INIT == function)) { + if (PinUsed(GPIO_RF_SENSOR) && (FUNC_INIT == function)) { RfSnsInit(); } else if (rfsns_raw_signal) { switch (function) { case FUNC_LOOP: if ((*portInputRegister(rfsns_rf_port) &rfsns_rf_bit) == rfsns_rf_bit) { - if (RfSnsFetchSignal(pin[GPIO_RF_SENSOR], HIGH)) { + if (RfSnsFetchSignal(Pin(GPIO_RF_SENSOR), HIGH)) { RfSnsAnalyzeRawSignal(); } } - sleep = 0; + ssleep = 0; break; case FUNC_EVERY_SECOND: RfSnsEverySecond(); diff --git a/tasmota/xsns_38_az7798.ino b/tasmota/xsns_38_az7798.ino index b6b1dffbe..352f59389 100644 --- a/tasmota/xsns_38_az7798.ino +++ b/tasmota/xsns_38_az7798.ino @@ -267,8 +267,8 @@ void AzEverySecond(void) void AzInit(void) { az_type = 0; - if ((pin[GPIO_AZ_RXD] < 99) && (pin[GPIO_AZ_TXD] < 99)) { - AzSerial = new TasmotaSerial(pin[GPIO_AZ_RXD], pin[GPIO_AZ_TXD], 1); + if (PinUsed(GPIO_AZ_RXD) && PinUsed(GPIO_AZ_TXD)) { + AzSerial = new TasmotaSerial(Pin(GPIO_AZ_RXD), Pin(GPIO_AZ_TXD), 1); if (AzSerial->begin(9600)) { if (AzSerial->hardwareSerial()) { ClaimSerial(); } az_type = 1; diff --git a/tasmota/xsns_39_max31855.ino b/tasmota/xsns_39_max31855.ino index b4a430b54..fcdb69094 100644 --- a/tasmota/xsns_39_max31855.ino +++ b/tasmota/xsns_39_max31855.ino @@ -18,130 +18,153 @@ */ #ifdef USE_MAX31855 +/*********************************************************************************************\ + * MAX31855 and MAX6675 - Thermocouple + * + * SetOption94 0 - MAX31855 + * SetOption94 1 - MAX6675 +\*********************************************************************************************/ #define XSNS_39 39 -bool initialized = false; +const char kMax31855Types[] PROGMEM = "MAX31855|MAX6675"; -struct MAX31855_ResultStruct{ - uint8_t ErrorCode; // Error Codes: 0 = No Error / 1 = TC open circuit / 2 = TC short to GND / 4 = TC short to VCC - float ProbeTemperature; // Measured temperature of the 'hot' TC junction (probe temp) - float ReferenceTemperature; // Measured temperature of the 'cold' TC junction (reference temp) +bool max31855_initialized = false; + +struct MAX31855_ResultStruct { + uint8_t ErrorCode; // Error Codes: 0 = No Error / 1 = TC open circuit / 2 = TC short to GND / 4 = TC short to VCC + float ProbeTemperature; // Measured temperature of the 'hot' TC junction (probe temp) + float ReferenceTemperature; // Measured temperature of the 'cold' TC junction (reference temp) } MAX31855_Result; -void MAX31855_Init(void){ - if(initialized) - return; +void MAX31855_Init(void) { + if (PinUsed(GPIO_MAX31855CS) && PinUsed(GPIO_MAX31855CLK) && PinUsed(GPIO_MAX31855DO)) { // Set GPIO modes for SW-SPI - pinMode(pin[GPIO_MAX31855CS], OUTPUT); - pinMode(pin[GPIO_MAX31855CLK], OUTPUT); - pinMode(pin[GPIO_MAX31855DO], INPUT); + pinMode(Pin(GPIO_MAX31855CS), OUTPUT); + pinMode(Pin(GPIO_MAX31855CLK), OUTPUT); + pinMode(Pin(GPIO_MAX31855DO), INPUT); // Chip not selected / Clock low - digitalWrite(pin[GPIO_MAX31855CS], HIGH); - digitalWrite(pin[GPIO_MAX31855CLK], LOW); + digitalWrite(Pin(GPIO_MAX31855CS), HIGH); + digitalWrite(Pin(GPIO_MAX31855CLK), LOW); - initialized = true; -} - -/* -* MAX31855_GetResult(void) -* Acquires the raw data via SPI, checks for MAX31855 errors and fills result structure -*/ -void MAX31855_GetResult(void){ - int32_t RawData = MAX31855_ShiftIn(32); - uint8_t probeerror = RawData & 0x7; - - MAX31855_Result.ErrorCode = probeerror; - MAX31855_Result.ReferenceTemperature = MAX31855_GetReferenceTemperature(RawData); - if(probeerror) - MAX31855_Result.ProbeTemperature = NAN; // Return NaN if MAX31855 reports an error - else - MAX31855_Result.ProbeTemperature = MAX31855_GetProbeTemperature(RawData); -} - - -/* -* MAX31855_GetProbeTemperature(int32_t RawData) -* Decodes and returns the temperature of TCs 'hot' junction from RawData -*/ -float MAX31855_GetProbeTemperature(int32_t RawData){ - if(RawData & 0x80000000) - RawData = (RawData >> 18) | 0xFFFFC000; // Negative value - Drop lower 18 bits and extend to negative number - else - RawData >>= 18; // Positiv value - Drop lower 18 bits - - float result = (RawData * 0.25); // MAX31855 LSB resolution is 0.25°C for probe temperature - - return ConvertTemp(result); // Check if we have to convert to Fahrenheit -} - -/* -* MAX31855_GetReferenceTemperature(int32_t RawData) -* Decodes and returns the temperature of TCs 'cold' junction from RawData -*/ -float MAX31855_GetReferenceTemperature(int32_t RawData){ - if(RawData & 0x8000) - RawData = (RawData >> 4) | 0xFFFFF000; // Negative value - Drop lower 4 bits and extend to negative number - else - RawData = (RawData >> 4) & 0x00000FFF; // Positiv value - Drop lower 4 bits and mask out remaining bits (probe temp, error bit, etc.) - - float result = (RawData * 0.0625); // MAX31855 LSB resolution is 0.0625°C for reference temperature - - return ConvertTemp(result); // Check if we have to convert to Fahrenheit + max31855_initialized = true; + } } /* * MAX31855_ShiftIn(uint8_t Length) * Communicates with MAX31855 via SW-SPI and returns the raw data read from the chip */ -int32_t MAX31855_ShiftIn(uint8_t Length){ - int32_t dataIn = 0; +int32_t MAX31855_ShiftIn(uint8_t Length) { + int32_t dataIn = 0; - digitalWrite(pin[GPIO_MAX31855CS], LOW); // CS = LOW -> Start SPI communication - delayMicroseconds(1); // CS fall to output enable = max. 100ns + digitalWrite(Pin(GPIO_MAX31855CS), LOW); // CS = LOW -> Start SPI communication + delayMicroseconds(1); // CS fall to output enable = max. 100ns - for (uint32_t i = 0; i < Length; i++) - { - digitalWrite(pin[GPIO_MAX31855CLK], LOW); - delayMicroseconds(1); // CLK pulse width low = min. 100ns / CLK fall to output valid = max. 40ns - dataIn <<= 1; - if(digitalRead(pin[GPIO_MAX31855DO])) - dataIn |= 1; - digitalWrite(pin[GPIO_MAX31855CLK], HIGH); - delayMicroseconds(1); // CLK pulse width high = min. 100ns + for (uint32_t i = 0; i < Length; i++) { + digitalWrite(Pin(GPIO_MAX31855CLK), LOW); + delayMicroseconds(1); // CLK pulse width low = min. 100ns / CLK fall to output valid = max. 40ns + dataIn <<= 1; + if (digitalRead(Pin(GPIO_MAX31855DO))) { + dataIn |= 1; } + digitalWrite(Pin(GPIO_MAX31855CLK), HIGH); + delayMicroseconds(1); // CLK pulse width high = min. 100ns + } - digitalWrite(pin[GPIO_MAX31855CS], HIGH); // CS = HIGH -> End SPI communication - digitalWrite(pin[GPIO_MAX31855CLK], LOW); - return dataIn; + digitalWrite(Pin(GPIO_MAX31855CS), HIGH); // CS = HIGH -> End SPI communication + digitalWrite(Pin(GPIO_MAX31855CLK), LOW); + return dataIn; } -void MAX31855_Show(bool Json){ - char probetemp[33]; - char referencetemp[33]; - dtostrfd(MAX31855_Result.ProbeTemperature, Settings.flag2.temperature_resolution, probetemp); - dtostrfd(MAX31855_Result.ReferenceTemperature, Settings.flag2.temperature_resolution, referencetemp); +/* +* MAX31855_GetProbeTemperature(int32_t RawData) +* Decodes and returns the temperature of TCs 'hot' junction from RawData +*/ +float MAX31855_GetProbeTemperature(int32_t RawData) { + if (RawData & 0x80000000) { + RawData = (RawData >> 18) | 0xFFFFC000; // Negative value - Drop lower 18 bits and extend to negative number + } else { + RawData >>= 18; // Positiv value - Drop lower 18 bits + } + float result = (RawData * 0.25); // MAX31855 LSB resolution is 0.25°C for probe temperature - if(Json){ - ResponseAppend_P(PSTR(",\"MAX31855\":{\"" D_JSON_PROBETEMPERATURE "\":%s,\"" D_JSON_REFERENCETEMPERATURE "\":%s,\"" D_JSON_ERROR "\":%d}"), \ - probetemp, referencetemp, MAX31855_Result.ErrorCode); + return ConvertTemp(result); // Check if we have to convert to Fahrenheit +} + +/* +* MAX31855_GetReferenceTemperature(int32_t RawData) +* Decodes and returns the temperature of TCs 'cold' junction from RawData +*/ +float MAX31855_GetReferenceTemperature(int32_t RawData) { + if (RawData & 0x8000) { + RawData = (RawData >> 4) | 0xFFFFF000; // Negative value - Drop lower 4 bits and extend to negative number + } else { + RawData = (RawData >> 4) & 0x00000FFF; // Positiv value - Drop lower 4 bits and mask out remaining bits (probe temp, error bit, etc.) + } + float result = (RawData * 0.0625); // MAX31855 LSB resolution is 0.0625°C for reference temperature + + return ConvertTemp(result); // Check if we have to convert to Fahrenheit +} + +/* +* MAX31855_GetResult(void) +* Acquires the raw data via SPI, checks for MAX31855 errors and fills result structure +*/ +void MAX31855_GetResult(void) { + if (Settings.flag4.max6675) { // SetOption94 - Implement simpler MAX6675 protocol instead of MAX31855 + int32_t RawData = MAX31855_ShiftIn(16); + int32_t temp = (RawData >> 3) & ((1 << 12) - 1); + + /* Occasionally the sensor returns 0xfff, consider it an error */ + if (temp == ((1 << 12) - 1)) { return; } + + MAX31855_Result.ErrorCode = 0; + MAX31855_Result.ReferenceTemperature = NAN; + MAX31855_Result.ProbeTemperature = ConvertTemp(0.25 * temp); + } else { + int32_t RawData = MAX31855_ShiftIn(32); + uint8_t probeerror = RawData & 0x7; + + MAX31855_Result.ErrorCode = probeerror; + MAX31855_Result.ReferenceTemperature = MAX31855_GetReferenceTemperature(RawData); + if (probeerror) { + MAX31855_Result.ProbeTemperature = NAN; // Return NaN if MAX31855 reports an error + } else { + MAX31855_Result.ProbeTemperature = MAX31855_GetProbeTemperature(RawData); + } + } +} + +void MAX31855_Show(bool Json) { + char probetemp[33]; + char referencetemp[33]; + dtostrfd(MAX31855_Result.ProbeTemperature, Settings.flag2.temperature_resolution, probetemp); + dtostrfd(MAX31855_Result.ReferenceTemperature, Settings.flag2.temperature_resolution, referencetemp); + + char sensor_name[10]; + GetTextIndexed(sensor_name, sizeof(sensor_name), Settings.flag4.max6675, kMax31855Types); + + if (Json) { + ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_PROBETEMPERATURE "\":%s,\"" D_JSON_REFERENCETEMPERATURE "\":%s,\"" D_JSON_ERROR "\":%d}"), \ + sensor_name, probetemp, referencetemp, MAX31855_Result.ErrorCode); #ifdef USE_DOMOTICZ - if (0 == tele_period) { - DomoticzSensor(DZ_TEMP, probetemp); - } + if (0 == tele_period) { + DomoticzSensor(DZ_TEMP, probetemp); + } #endif // USE_DOMOTICZ #ifdef USE_KNX - if (0 == tele_period) { - KnxSensor(KNX_TEMPERATURE, MAX31855_Result.ProbeTemperature); - } -#endif // USE_KNX - } else { -#ifdef USE_WEBSERVER - WSContentSend_PD(HTTP_SNS_TEMP, "MAX31855", probetemp, TempUnit()); -#endif // USE_WEBSERVER + if (0 == tele_period) { + KnxSensor(KNX_TEMPERATURE, MAX31855_Result.ProbeTemperature); } +#endif // USE_KNX +#ifdef USE_WEBSERVER + } else { + WSContentSend_PD(HTTP_SNS_TEMP, sensor_name, probetemp, TempUnit()); +#endif // USE_WEBSERVER + } } /*********************************************************************************************\ @@ -151,12 +174,12 @@ void MAX31855_Show(bool Json){ bool Xsns39(uint8_t function) { bool result = false; - if((pin[GPIO_MAX31855CS] < 99) && (pin[GPIO_MAX31855CLK] < 99) && (pin[GPIO_MAX31855DO] < 99)){ + if (FUNC_INIT == function) { + MAX31855_Init(); + } + else if (max31855_initialized) { switch (function) { - case FUNC_INIT: - MAX31855_Init(); - break; case FUNC_EVERY_SECOND: MAX31855_GetResult(); break; diff --git a/tasmota/xsns_40_pn532.ino b/tasmota/xsns_40_pn532.ino index b241eb320..8218d0b35 100644 --- a/tasmota/xsns_40_pn532.ino +++ b/tasmota/xsns_40_pn532.ino @@ -66,8 +66,8 @@ uint8_t pn532_newdata_len = 0; void PN532_Init(void) { - if ((pin[GPIO_PN532_RXD] < 99) && (pin[GPIO_PN532_TXD] < 99)) { - PN532_Serial = new TasmotaSerial(pin[GPIO_PN532_RXD], pin[GPIO_PN532_TXD], 1); + if (PinUsed(GPIO_PN532_RXD) && PinUsed(GPIO_PN532_TXD)) { + PN532_Serial = new TasmotaSerial(Pin(GPIO_PN532_RXD), Pin(GPIO_PN532_TXD), 1); if (PN532_Serial->begin(115200)) { if (PN532_Serial->hardwareSerial()) { ClaimSerial(); } PN532_wakeup(); diff --git a/tasmota/xsns_43_hre.ino b/tasmota/xsns_43_hre.ino index fa03d0301..19fffe957 100644 --- a/tasmota/xsns_43_hre.ino +++ b/tasmota/xsns_43_hre.ino @@ -71,10 +71,10 @@ bool hre_good = false; // The settling times here were determined using a single unit hooked to a scope int hreReadBit() { - digitalWrite(pin[GPIO_HRE_CLOCK], HIGH); + digitalWrite(Pin(GPIO_HRE_CLOCK), HIGH); delay(1); - int bit = digitalRead(pin[GPIO_HRE_DATA]); - digitalWrite(pin[GPIO_HRE_CLOCK], LOW); + int bit = digitalRead(Pin(GPIO_HRE_DATA)); + digitalWrite(Pin(GPIO_HRE_CLOCK), LOW); delay(1); return bit; } @@ -110,12 +110,12 @@ void hreInit(void) hre_read_errors = 0; hre_good = false; - pinMode(pin[GPIO_HRE_CLOCK], OUTPUT); - pinMode(pin[GPIO_HRE_DATA], INPUT); + pinMode(Pin(GPIO_HRE_CLOCK), OUTPUT); + pinMode(Pin(GPIO_HRE_DATA), INPUT); // Note that the level shifter inverts this line and we want to leave it // high when not being read. - digitalWrite(pin[GPIO_HRE_CLOCK], LOW); + digitalWrite(Pin(GPIO_HRE_CLOCK), LOW); hre_state = hre_sync; } @@ -260,8 +260,7 @@ void hreShow(boolean json) bool Xsns43(byte function) { // If we don't have pins assigned give up quickly. - if (pin[GPIO_HRE_CLOCK] >= 99 || pin[GPIO_HRE_DATA] >= 99) - return false; + if (!PinUsed(GPIO_HRE_CLOCK) || !PinUsed(GPIO_HRE_DATA)) { return false; } switch (function) { diff --git a/tasmota/xsns_45_vl53l0x.ino b/tasmota/xsns_45_vl53l0x.ino index ef9de345c..f3a9bbe74 100644 --- a/tasmota/xsns_45_vl53l0x.ino +++ b/tasmota/xsns_45_vl53l0x.ino @@ -1,5 +1,5 @@ /* - xsns_45_vl53l0x.ino - VL53L0X support for Tasmota + xsns_45_vl53l0x.ino - VL53L0X time of flight sensor support for Tasmota Copyright (C) 2020 Theo Arends and Gerhard Mutz @@ -19,23 +19,30 @@ #ifdef USE_I2C #ifdef USE_VL53L0X +/*********************************************************************************************\ + * VL53L0x time of flight sensor + * + * I2C Addres: 0x29 +\*********************************************************************************************/ -#define XSNS_45 45 -#define XI2C_31 31 // See I2CDEVICES.md +#define XSNS_45 45 +#define XI2C_31 31 // See I2CDEVICES.md #include #include "VL53L0X.h" VL53L0X sensor; -uint8_t vl53l0x_ready = 0; -uint16_t vl53l0x_distance; -uint16_t Vl53l0_buffer[5]; -uint8_t Vl53l0_index; +struct { + uint16_t distance; + uint16_t distance_prev; + uint16_t buffer[5]; + uint8_t ready = 0; + uint8_t index; +} Vl53l0x; /********************************************************************************************/ -void Vl53l0Detect(void) -{ +void Vl53l0Detect(void) { if (!I2cSetDevice(0x29)) { return; } if (!sensor.init()) { return; } @@ -49,9 +56,9 @@ void Vl53l0Detect(void) // instead, provide a desired inter-measurement period in // ms (e.g. sensor.startContinuous(100)). sensor.startContinuous(); - vl53l0x_ready = 1; + Vl53l0x.ready = 1; - Vl53l0_index=0; + Vl53l0x.index = 0; } #ifdef USE_WEBSERVER @@ -61,50 +68,64 @@ const char HTTP_SNS_VL53L0X[] PROGMEM = #define USE_VL_MEDIAN -void Vl53l0Every_250MSecond(void) -{ - uint16_t tbuff[5],tmp; - uint8_t flag; - +void Vl53l0Every_250MSecond(void) { // every 200 ms uint16_t dist = sensor.readRangeContinuousMillimeters(); - if (dist==0 || dist>2000) { - dist=9999; + if ((0 == dist) || (dist > 2000)) { + dist = 9999; } #ifdef USE_VL_MEDIAN // store in ring buffer - Vl53l0_buffer[Vl53l0_index]=dist; - Vl53l0_index++; - if (Vl53l0_index>=5) Vl53l0_index=0; + Vl53l0x.buffer[Vl53l0x.index] = dist; + Vl53l0x.index++; + if (Vl53l0x.index >= 5) { + Vl53l0x.index = 0; + } // sort list and take median - memmove(tbuff,Vl53l0_buffer,sizeof(tbuff)); - for (byte ocnt=0; ocnt<5; ocnt++) { - flag=0; - for (byte count=0; count<4; count++) { - if (tbuff[count]>tbuff[count+1]) { - tmp=tbuff[count]; - tbuff[count]=tbuff[count+1]; - tbuff[count+1]=tmp; - flag=1; + uint16_t tbuff[5]; + memmove(tbuff, Vl53l0x.buffer, sizeof(tbuff)); + uint16_t tmp; + uint8_t flag; + for (uint32_t ocnt = 0; ocnt < 5; ocnt++) { + flag = 0; + for (uint32_t count = 0; count < 4; count++) { + if (tbuff[count] > tbuff[count +1]) { + tmp = tbuff[count]; + tbuff[count] = tbuff[count +1]; + tbuff[count +1] = tmp; + flag = 1; } } - if (!flag) break; + if (!flag) { break; } } - vl53l0x_distance=tbuff[2]; + Vl53l0x.distance = tbuff[2]; #else - vl53l0x_distance=dist; + Vl53l0x.distance = dist; #endif } -void Vl53l0Show(boolean json) -{ +#ifdef USE_DOMOTICZ +void Vl53l0Every_Second(void) { + if (abs(Vl53l0x.distance - Vl53l0x.distance_prev) > 8) { + Vl53l0x.distance_prev = Vl53l0x.distance; + DomoticzSensor(DZ_ILLUMINANCE, Vl53l0x.distance); + } +} +#endif // USE_DOMOTICZ + +void Vl53l0Show(boolean json) { if (json) { - ResponseAppend_P(PSTR(",\"VL53L0X\":{\"" D_JSON_DISTANCE "\":%d}"), vl53l0x_distance); + ResponseAppend_P(PSTR(",\"VL53L0X\":{\"" D_JSON_DISTANCE "\":%d}"), Vl53l0x.distance); +#ifdef USE_DOMOTICZ + if (0 == tele_period) { + DomoticzSensor(DZ_ILLUMINANCE, Vl53l0x.distance); + } +#endif // USE_DOMOTICZ #ifdef USE_WEBSERVER } else { - WSContentSend_PD(HTTP_SNS_VL53L0X, vl53l0x_distance); + WSContentSend_PD(HTTP_SNS_VL53L0X, Vl53l0x.distance); #endif } } @@ -122,11 +143,16 @@ bool Xsns45(byte function) if (FUNC_INIT == function) { Vl53l0Detect(); } - else if (vl53l0x_ready) { + else if (Vl53l0x.ready) { switch (function) { case FUNC_EVERY_250_MSECOND: Vl53l0Every_250MSecond(); break; +#ifdef USE_DOMOTICZ + case FUNC_EVERY_SECOND: + Vl53l0Every_Second(); + break; +#endif // USE_DOMOTICZ case FUNC_JSON_APPEND: Vl53l0Show(1); break; diff --git a/tasmota/xsns_47_max31865.ino b/tasmota/xsns_47_max31865.ino index 3b8a11706..e29054392 100644 --- a/tasmota/xsns_47_max31865.ino +++ b/tasmota/xsns_47_max31865.ino @@ -51,10 +51,10 @@ void MAX31865_Init(void){ return; max31865.setPins( - pin[GPIO_SSPI_CS], - pin[GPIO_SSPI_MOSI], - pin[GPIO_SSPI_MISO], - pin[GPIO_SSPI_SCLK] + Pin(GPIO_SSPI_CS), + Pin(GPIO_SSPI_MOSI), + Pin(GPIO_SSPI_MISO), + Pin(GPIO_SSPI_SCLK) ); if(max31865.begin(PTD_WIRES)) @@ -110,8 +110,8 @@ void MAX31865_Show(bool Json){ bool Xsns47(uint8_t function) { bool result = false; - if((pin[GPIO_SSPI_MISO] < 99) && (pin[GPIO_SSPI_MOSI] < 99) && - (pin[GPIO_SSPI_SCLK] < 99) && (pin[GPIO_SSPI_CS] < 99)) { + if (PinUsed(GPIO_SSPI_MISO) && PinUsed(GPIO_SSPI_MOSI) && + PinUsed(GPIO_SSPI_SCLK) && PinUsed(GPIO_SSPI_CS)) { switch (function) { case FUNC_INIT: diff --git a/tasmota/xsns_48_chirp.ino b/tasmota/xsns_48_chirp.ino index 9606b419c..934dff205 100644 --- a/tasmota/xsns_48_chirp.ino +++ b/tasmota/xsns_48_chirp.ino @@ -20,6 +20,8 @@ Version Date Action Description -------------------------------------------------------------------------------------------- + 1.0.0.2 20200611 changed - bugfix: decouple restart of the work loop from FUNC_JSON_APPEND callback + --- 1.0.0.1 20190917 changed - rework of the inner loop to enable delays in the middle of I2C-reads changed - double send address change only for fw>0x25 changed - use DEBUG_SENSOR_LOG, change ILLUMINANCE to DARKNESS @@ -300,7 +302,7 @@ void ChirpServiceAllSensors(uint8_t job){ void ChirpEvery100MSecond(void) { - // DEBUG_SENSOR_LOG(PSTR("CHIRP: every second")); + // DEBUG_SENSOR_LOG(PSTR("CHIRP: every 100 mseconds, counter: %u, next job: %u"),chirp_timeout_count,chirp_next_job); if(chirp_timeout_count == 0) { //countdown complete, now do something switch(chirp_next_job) { case 0: //this should only be called after driver initialization @@ -377,10 +379,11 @@ void ChirpEvery100MSecond(void) break; case 13: DEBUG_SENSOR_LOG(PSTR("CHIRP: paused, waiting for TELE")); + chirp_next_job++; break; case 14: if (Settings.tele_period > 16){ - chirp_timeout_count = (Settings.tele_period - 17) * 10; // sync it with the TELEPERIOD, we need about up to 17 seconds to measure + chirp_timeout_count = (Settings.tele_period - 16) * 10; // sync it with the TELEPERIOD, we need about up to 16 seconds to measure DEBUG_SENSOR_LOG(PSTR("CHIRP: timeout 1/10 sec: %u, tele: %u"), chirp_timeout_count, Settings.tele_period); } else{ @@ -533,7 +536,6 @@ bool Xsns48(uint8_t function) break; case FUNC_JSON_APPEND: ChirpShow(1); - chirp_next_job = 14; // TELE done, now compute time for next measure cycle break; #ifdef USE_WEBSERVER case FUNC_WEB_SENSOR: diff --git a/tasmota/xsns_51_rdm6300.ino b/tasmota/xsns_51_rdm6300.ino index 7fd8bc5b5..de2714cb2 100644 --- a/tasmota/xsns_51_rdm6300.ino +++ b/tasmota/xsns_51_rdm6300.ino @@ -36,8 +36,8 @@ uint8_t rdm_blcnt; TasmotaSerial *RDM6300_Serial = nullptr; void RDM6300_Init() { - if (pin[GPIO_RDM6300_RX] < 99) { - RDM6300_Serial = new TasmotaSerial(pin[GPIO_RDM6300_RX],-1,1); + if (PinUsed(GPIO_RDM6300_RX)) { + RDM6300_Serial = new TasmotaSerial(Pin(GPIO_RDM6300_RX),-1,1); if (RDM6300_Serial->begin(RDM6300_BAUDRATE)) { if (RDM6300_Serial->hardwareSerial()) { ClaimSerial(); diff --git a/tasmota/xsns_52_ibeacon.ino b/tasmota/xsns_52_ibeacon.ino old mode 100644 new mode 100755 index 97130df2a..5c8b0afd4 --- a/tasmota/xsns_52_ibeacon.ino +++ b/tasmota/xsns_52_ibeacon.ino @@ -25,6 +25,8 @@ #include +#define TMSBSIZ52 512 + #define HM17_BAUDRATE 9600 #define IBEACON_DEBUG @@ -85,6 +87,9 @@ struct IBEACON { struct IBEACON_UID { char MAC[12]; char RSSI[4]; + char UID[32]; + char MAJOR[4]; + char MINOR[4]; uint8_t FLAGS; uint8_t TIME; } ibeacons[MAX_IBEACONS]; @@ -95,8 +100,8 @@ void IBEACON_Init() { hm17_found=0; // actually doesnt work reliably with software serial - if ((pin[GPIO_IBEACON_RX] < 99) && (pin[GPIO_IBEACON_TX] < 99)) { - IBEACON_Serial = new TasmotaSerial(pin[GPIO_IBEACON_RX], pin[GPIO_IBEACON_TX],1); + if (PinUsed(GPIO_IBEACON_RX) && PinUsed(GPIO_IBEACON_TX)) { + IBEACON_Serial = new TasmotaSerial(Pin(GPIO_IBEACON_RX), Pin(GPIO_IBEACON_TX),1,0,TMSBSIZ52); if (IBEACON_Serial->begin(HM17_BAUDRATE)) { if (IBEACON_Serial->hardwareSerial()) { ClaimSerial(); @@ -130,7 +135,7 @@ void hm17_every_second(void) { ibeacons[cnt].TIME++; if (ibeacons[cnt].TIME>IB_TIMEOUT_TIME) { ibeacons[cnt].FLAGS=0; - ibeacon_mqtt(ibeacons[cnt].MAC,"0000"); + ibeacon_mqtt(ibeacons[cnt].MAC,"0000",ibeacons[cnt].UID,ibeacons[cnt].MAJOR,ibeacons[cnt].MINOR); } } } @@ -144,7 +149,7 @@ void hm17_every_second(void) { void hm17_sbclr(void) { memset(hm17_sbuffer,0,HM17_BSIZ); hm17_sindex=0; - IBEACON_Serial->flush(); + //IBEACON_Serial->flush(); } void hm17_sendcmd(uint8_t cmd) { @@ -192,15 +197,32 @@ void hm17_sendcmd(uint8_t cmd) { } uint32_t ibeacon_add(struct IBEACON *ib) { +/* if (!strncmp(ib->MAJOR,"4B1C",4)) { + return 0; + } + */ + if (!strncmp(ib->RSSI,"0",1)) { + return 0; + } + // keyfob starts with ffff, ibeacon has valid facid if (!strncmp(ib->MAC,"FFFF",4) || strncmp(ib->FACID,"00000000",8)) { for (uint32_t cnt=0;cntMAC,12)) { - // exists - memcpy(ibeacons[cnt].RSSI,ib->RSSI,4); - ibeacons[cnt].TIME=0; - return 1; + if (!strncmp_P(ib->UID,PSTR("00000000000000000000000000000000"),32)) { + if (!strncmp(ibeacons[cnt].MAC,ib->MAC,12)) { + // exists + memcpy(ibeacons[cnt].RSSI,ib->RSSI,4); + ibeacons[cnt].TIME=0; + return 1; + } + } else { + if (!strncmp(ibeacons[cnt].UID,ib->UID,32)) { + // exists + memcpy(ibeacons[cnt].RSSI,ib->RSSI,4); + ibeacons[cnt].TIME=0; + return 1; + } } } } @@ -208,6 +230,9 @@ uint32_t ibeacon_add(struct IBEACON *ib) { if (!ibeacons[cnt].FLAGS) { memcpy(ibeacons[cnt].MAC,ib->MAC,12); memcpy(ibeacons[cnt].RSSI,ib->RSSI,4); + memcpy(ibeacons[cnt].UID,ib->UID,32); + memcpy(ibeacons[cnt].MAJOR,ib->MAJOR,4); + memcpy(ibeacons[cnt].MINOR,ib->MINOR,4); ibeacons[cnt].FLAGS=1; ibeacons[cnt].TIME=0; return 1; @@ -398,14 +423,14 @@ hm17_v110: memcpy(ib.RSSI,&hm17_sbuffer[8+8+1+32+1+4+4+2+1+12+1],4); if (ibeacon_add(&ib)) { - ibeacon_mqtt(ib.MAC,ib.RSSI); + ibeacon_mqtt(ib.MAC,ib.RSSI,ib.UID,ib.MAJOR,ib.MINOR); } hm17_sbclr(); hm17_result=1; } } else { #ifdef IBEACON_DEBUG - if (hm17_debug) AddLog_P2(LOG_LEVEL_INFO, PSTR(">>%s"),&hm17_sbuffer[8]); + if (hm17_debug) AddLog_P2(LOG_LEVEL_INFO, PSTR(">->%s"),&hm17_sbuffer[8]); #endif } break; @@ -442,12 +467,15 @@ uint32_t difftime=millis()-hm17_lastms; } #ifdef USE_WEBSERVER -const char HTTP_IBEACON[] PROGMEM = +const char HTTP_IBEACON_mac[] PROGMEM = + "{s}IBEACON-MAC : %s" " - RSSI : %s" "{m}{e}"; +const char HTTP_IBEACON_uid[] PROGMEM = "{s}IBEACON-UID : %s" " - RSSI : %s" "{m}{e}"; void IBEACON_Show(void) { char mac[14]; char rssi[6]; +char uid[34]; for (uint32_t cnt=0;cnt // use special no wait serial driver, should be always on +#ifndef ESP32 #define SPECIAL_SS +#endif + +#undef TMSBSIZ +#define TMSBSIZ 256 // addresses a bug in meter DWS74 //#define DWS74_BUG @@ -440,7 +445,9 @@ const uint8_t meter[]= #endif // max number of meters , may be adjusted +#ifndef MAX_METERS #define MAX_METERS 5 +#endif double meter_vars[SML_MAX_VARS]; // calulate deltas #define MAX_DVARS MAX_METERS*2 @@ -453,7 +460,11 @@ const uint8_t *meter_p; uint8_t meter_spos[MAX_METERS]; // software serial pointers +#ifdef ESP32 +HardwareSerial *meter_ss[MAX_METERS]; +#else TasmotaSerial *meter_ss[MAX_METERS]; +#endif // serial buffers, may be made larger depending on telegram lenght #define SML_BSIZ 48 @@ -774,18 +785,21 @@ uint8_t dump2log=0; bool Serial_available() { uint8_t num=dump2log&7; if (num<1 || num>meters_used) num=1; + if (!meter_ss[num-1]) return 0; return meter_ss[num-1]->available(); } uint8_t Serial_read() { uint8_t num=dump2log&7; if (num<1 || num>meters_used) num=1; + if (!meter_ss[num-1]) return 0; return meter_ss[num-1]->read(); } uint8_t Serial_peek() { uint8_t num=dump2log&7; if (num<1 || num>meters_used) num=1; + if (!meter_ss[num-1]) return 0; return meter_ss[num-1]->peek(); } @@ -944,6 +958,9 @@ double dval; if (*cp==0x64 && *cpx==0 && *(cpx+1)==0x01 && *(cpx+2)==0x08 && *(cpx+3)==0) { sml_status[g_mindex]=*(cp+3); } + if (*cp==0x63 && *cpx==0 && *(cpx+1)==0x01 && *(cpx+2)==0x08 && *(cpx+3)==0) { + sml_status[g_mindex]=*(cp+2); + } #endif cp=skip_sml(cp,&result); @@ -1186,7 +1203,8 @@ void sml_shift_in(uint32_t meters,uint32_t shard) { } else if (meter_desc_p[meters].type=='m' || meter_desc_p[meters].type=='M') { smltbuf[meters][meter_spos[meters]] = iob; meter_spos[meters]++; - if (meter_spos[meters]>=9) { + uint32_t mlen=smltbuf[meters][2]+5; + if (meter_spos[meters]>=mlen) { SML_Decode(meters); sml_empty_receiver(meters); meter_spos[meters]=0; @@ -1236,6 +1254,7 @@ uint32_t meters; for (meters=0; metersavailable()) { sml_shift_in(meters,0); } @@ -1530,9 +1549,10 @@ void SML_Decode(uint8_t index) { if (mb_index!=meter_desc_p[mindex].index) { goto nextsect; } - uint16_t crc = MBUS_calculateCRC(&smltbuf[mindex][0],7); - if (lowByte(crc)!=smltbuf[mindex][7]) goto nextsect; - if (highByte(crc)!=smltbuf[mindex][8]) goto nextsect; + uint16_t pos = smltbuf[mindex][2]+3; + uint16_t crc = MBUS_calculateCRC(&smltbuf[mindex][0],pos); + if (lowByte(crc)!=smltbuf[mindex][pos]) goto nextsect; + if (highByte(crc)!=smltbuf[mindex][pos+1]) goto nextsect; dval=mbus_dval; //AddLog_P2(LOG_LEVEL_INFO, PSTR(">> %s"),mp); mp++; @@ -1728,7 +1748,7 @@ void SML_Show(boolean json) { } else { // web ui export //snprintf_P(b_mqtt_data, sizeof(b_mqtt_data), "%s{s}%s %s: {m}%s %s{e}", b_mqtt_data,meter_desc[mindex].prefix,name,tpowstr,unit); - WSContentSend_PD(PSTR("{s}%s %s: {m}%s %s{e}"),meter_desc_p[mindex].prefix,name,tpowstr,unit); + if (strcmp(name,"*")) WSContentSend_PD(PSTR("{s}%s %s: {m}%s %s{e}"),meter_desc_p[mindex].prefix,name,tpowstr,unit); } } } @@ -1769,6 +1789,7 @@ struct SML_COUNTER { uint32_t sml_cnt_last_ts; uint32_t sml_counter_ltime; uint16_t sml_debounce; + uint8_t sml_cnt_updated; #ifdef ANALOG_OPTO_SENSOR int16_t ana_curr; @@ -1797,7 +1818,8 @@ void SML_CounterUpd(uint8_t index) { sml_counters[index].sml_counter_ltime=millis(); if (ltime>sml_counters[index].sml_debounce) { RtcSettings.pulse_counter[index]++; - InjektCounterValue(sml_counters[index].sml_cnt_old_state,RtcSettings.pulse_counter[index]); + sml_counters[index].sml_cnt_updated=1; + //InjektCounterValue(sml_counters[index].sml_cnt_old_state,RtcSettings.pulse_counter[index]); } } else { // rising edge @@ -1830,12 +1852,64 @@ uint8_t *script_meter; #define METER_DEF_SIZE 3000 #endif + + +#ifdef SML_REPLACE_VARS + +#define SML_SRCBSIZE 256 + +uint32_t SML_getlinelen(char *lp) { +uint32_t cnt; + for (cnt=0; cnt') break; + if (*lp==0) break; + } + //AddLog_P2(LOG_LEVEL_INFO, PSTR("len=%d"),mlen); + return mlen+32; +} +#else +uint32_t SML_getscriptsize(char *lp) { + uint32_t mlen=0; + for (uint32_t cnt=0;cnt 0)) { + return true; + } return false; } @@ -1859,10 +1933,19 @@ void SML_Init(void) { for (uint32_t cnt=0;cntM",-2,0); if (meter_script==99) { // use script definition @@ -1880,13 +1963,7 @@ void SML_Init(void) { lp+=2; meters_used=strtol(lp,0,10); section=1; - uint32_t mlen=0; - for (uint32_t cnt=0;cnt>",lp); + // add meters line -1,1-0:1.8.0*255(@10000,H2OIN,cbm,COUNTER,4| + if (*lp1=='-') lp1++; + uint8_t mnum=strtol(lp1,0,10); + if (mnum<1 || mnum>meters_used) goto next_line; + while (1) { + if (*lp1==0) { + *tp++='|'; + goto next_line; + } + *tp++=*lp1++; + index++; + if (index>=METER_DEF_SIZE) break; + } + } +#else + if (*lp=='-' || isdigit(*lp)) { //toLogEOL(">>",lp); // add meters line -1,1-0:1.8.0*255(@10000,H2OIN,cbm,COUNTER,4| @@ -1991,6 +2092,7 @@ dddef_exit: if (index>=METER_DEF_SIZE) break; } } +#endif } @@ -2007,6 +2109,7 @@ next_line: meter_desc_p=script_meter_desc; meter_p=script_meter; } + } #endif init10: @@ -2018,6 +2121,7 @@ init10: RtcSettings.pulse_counter[i]=Settings.pulse_counter[i]; sml_counters[i].sml_cnt_last_ts=millis(); } + uint32_t uart_index=2; for (uint8_t meters=0; meterssetRxBufferSize(TMSBSIZ); +#else + meter_ss[meters] = new TasmotaSerial(meter_desc_p[meters].srcpin,meter_desc_p[meters].trxpin,1,0,TMSBSIZ); #endif +#endif + +#ifdef ESP32 + if (meter_desc_p[meters].type=='M') { + meter_ss[meters]->begin(meter_desc_p[meters].params, SERIAL_8E1,meter_desc_p[meters].srcpin,meter_desc_p[meters].trxpin); + } else { + meter_ss[meters]->begin(meter_desc_p[meters].params,SERIAL_8N1,meter_desc_p[meters].srcpin,meter_desc_p[meters].trxpin); + } +#else if (meter_ss[meters]->begin(meter_desc_p[meters].params)) { meter_ss[meters]->flush(); } @@ -2063,8 +2183,9 @@ init10: Serial.begin(meter_desc_p[meters].params, SERIAL_8E1); } ClaimSerial(); + //Serial.setRxBufferSize(512); } - +#endif } } @@ -2076,6 +2197,11 @@ uint32_t SML_SetBaud(uint32_t meter, uint32_t br) { if (meter<1 || meter>meters_used) return 0; meter--; if (!meter_ss[meter]) return 0; + +#ifdef ESP32 + meter_ss[meter]->flush(); + meter_ss[meter]->updateBaudRate(br); +#else if (meter_ss[meter]->begin(br)) { meter_ss[meter]->flush(); } @@ -2084,6 +2210,7 @@ uint32_t SML_SetBaud(uint32_t meter, uint32_t br) { Serial.begin(br, SERIAL_8E1); } } +#endif return 1; } @@ -2105,7 +2232,13 @@ uint32_t SML_Write(uint32_t meter,char *hstr) { SML_Send_Seq(meter,hstr); return 1; } -#endif + +float SML_GetVal(uint32_t index) { + if (index<1 && index>SML_MAX_VARS) { index = 1;} + return meter_vars[index-1]; +} + +#endif // USE_SML_SCRIPT_CMD void SetDBGLed(uint8_t srcpin, uint8_t ledpin) { @@ -2179,6 +2312,13 @@ uint32_t ctime=millis(); if (cindex==1) SetDBGLed(meter_desc_p[meters].srcpin,DEBUG_CNT_LED2); #endif } + + if (sml_counters[cindex].sml_cnt_updated) { + InjektCounterValue(sml_counters[cindex].sml_cnt_old_state,RtcSettings.pulse_counter[cindex]); + sml_counters[cindex].sml_cnt_updated=0; + } + + } cindex++; } @@ -2206,7 +2346,10 @@ void SML_Check_Send(void) { char *cp; for (uint32_t cnt=sml_desc_cnt; cnt=0 && script_meter_desc[cnt].txmem) { - if ((sml_100ms_cnt%script_meter_desc[cnt].tsecs)==0) { + //AddLog_P2(LOG_LEVEL_INFO, PSTR("100 ms>> %d - %s - %d"),sml_desc_cnt,script_meter_desc[cnt].txmem,script_meter_desc[cnt].tsecs); + if ((sml_100ms_cnt>=script_meter_desc[cnt].tsecs)) { + sml_100ms_cnt=0; + //AddLog_P2(LOG_LEVEL_INFO, PSTR("100 ms>> 2"),cp); if (script_meter_desc[cnt].max_index>1) { script_meter_desc[cnt].index++; if (script_meter_desc[cnt].index>=script_meter_desc[cnt].max_index) { @@ -2253,6 +2396,11 @@ void SML_Send_Seq(uint32_t meter,char *seq) { uint8_t sbuff[32]; uint8_t *ucp=sbuff,slen=0; char *cp=seq; + uint8_t rflg = 0; + if (*cp=='r') { + rflg = 1; + cp++; + } while (*cp) { if (!*cp || !*(cp+1)) break; if (*cp==',') break; @@ -2263,13 +2411,16 @@ void SML_Send_Seq(uint32_t meter,char *seq) { if (slen>=sizeof(sbuff)) break; } if (script_meter_desc[meter].type=='m' || script_meter_desc[meter].type=='M') { - *ucp++=0; - *ucp++=2; + if (!rflg) { + *ucp++=0; + *ucp++=2; + slen+=2; + } // append crc - uint16_t crc = MBUS_calculateCRC(sbuff,6); + uint16_t crc = MBUS_calculateCRC(sbuff,slen); *ucp++=lowByte(crc); *ucp++=highByte(crc); - slen+=4; + slen+=2; } if (script_meter_desc[meter].type=='o') { for (uint32_t cnt=0;cntaddress, INA226_REG_CALIBRATION, si->calibrationValue); @@ -167,10 +167,10 @@ bool Ina226TestPresence(uint8_t device) // Read config - uint16_t config = I2cRead16( slaveInfo[device].address, INA226_REG_CONFIG ); + uint16_t config = I2cRead16( Ina226Info[device].address, INA226_REG_CONFIG ); //AddLog_P2( LOG_LEVEL_NONE, PSTR("Config register %04x" ), config); - if (config != slaveInfo[device].config) + if (config != Ina226Info[device].config) return false; return true; @@ -179,10 +179,10 @@ bool Ina226TestPresence(uint8_t device) void Ina226ResetActive(void) { - Ina226SlaveInfo_t *p = slaveInfo; + Ina226Info_t *p = Ina226Info; for (uint32_t i = 0; i < INA226_MAX_ADDRESSES; i++) { - p = &slaveInfo[i]; + p = &Ina226Info[i]; // Address uint8_t addr = p->address; if (addr) { @@ -199,9 +199,9 @@ void Ina226Init() { uint32_t i; - slavesFound = 0; + Ina226sFound = 0; - Ina226SlaveInfo_t *p = slaveInfo; + Ina226Info_t *p = Ina226Info; //AddLog_P2( LOG_LEVEL_NONE, "Ina226Init"); // AddLog_P2( LOG_LEVEL_NONE, "Size of Settings: %d bytes", sizeof(Settings)); @@ -210,7 +210,7 @@ void Ina226Init() // AddLog_P2(LOG_LEVEL_DEBUG, "INA226: Initialization failed: No I2C support"); - // Clear slave info data + // Clear Ina226 info data for (i = 0; i < 4; i++){ *p = {0}; @@ -232,7 +232,7 @@ void Ina226Init() continue; - //AddLog_P2( LOG_LEVEL_NONE, PSTR("INA226 trying slave address %02x" ), addr ); + //AddLog_P2( LOG_LEVEL_NONE, PSTR("INA226 trying address %02x" ), addr ); // Try Resetting the device @@ -257,8 +257,8 @@ void Ina226Init() if (!I2cWrite16( addr, INA226_REG_CONFIG, config)) continue; // No device - // store data in slave info struct. - p = &slaveInfo[i]; + // store data in info struct. + p = &Ina226Info[i]; // Address p->address = addr; // Configuration @@ -282,7 +282,7 @@ void Ina226Init() I2cSetActiveFound(addr, Ina226Str); - slavesFound++; + Ina226sFound++; } } @@ -292,7 +292,7 @@ void Ina226Init() float Ina226ReadBus_v(uint8_t device) { - uint8_t addr = slaveInfo[device].address; + uint8_t addr = Ina226Info[device].address; int16_t reg_bus_v = I2cReadS16( addr, INA226_REG_BUSVOLTAGE); float result = ((float) reg_bus_v) * 0.00125f; @@ -307,10 +307,10 @@ float Ina226ReadBus_v(uint8_t device) float Ina226ReadShunt_i(uint8_t device) { - uint8_t addr = slaveInfo[device].address; + uint8_t addr = Ina226Info[device].address; int16_t reg_shunt_i = I2cReadS16( addr, INA226_REG_CURRENT); - float result = ((float) reg_shunt_i) * slaveInfo[device].i_lsb; + float result = ((float) reg_shunt_i) * Ina226Info[device].i_lsb; return result; } @@ -321,10 +321,10 @@ float Ina226ReadShunt_i(uint8_t device) float Ina226ReadPower_w(uint8_t device) { - uint8_t addr = slaveInfo[device].address; + uint8_t addr = Ina226Info[device].address; int16_t reg_shunt_i = I2cReadS16( addr, INA226_REG_POWER); - float result = ((float) reg_shunt_i) * (slaveInfo[device].i_lsb * 25.0); + float result = ((float) reg_shunt_i) * (Ina226Info[device].i_lsb * 25.0); return result; } @@ -354,19 +354,19 @@ void Ina226EverySecond() { //AddLog_P2( LOG_LEVEL_NONE, "Ina226EverySecond"); for (uint8_t device = 0; device < INA226_MAX_ADDRESSES; device++){ - // If there are slaves, and the device was present, and the device still is present, read its registers - if (slavesFound && slaveInfo[device].present && Ina226TestPresence(device)){ + // If there are Ina226s, and the device was present, and the device still is present, read its registers + if (Ina226sFound && Ina226Info[device].present && Ina226TestPresence(device)){ Ina226Read(device); } else { powers[device] = currents[device] = voltages[device] = 0.0f; // If device was present, note that it dropped off here - //if(slaveInfo[device].present){ + //if(Ina226Info[device].present){ //reinit_count[device]++; //AddLog_P2( LOG_LEVEL_DEBUG, "INA226 Device %d dropped off, count: %d", device, reinit_count[device]); //} // Device no longer present - slaveInfo[device].present = false; + Ina226Info[device].present = false; } } } @@ -413,7 +413,7 @@ bool Ina226CommandSensor() case 1: // Rerun init Ina226ResetActive(); Ina226Init(); - Response_P(PSTR("{\"Sensor54-Command-Result\":{\"SlavesFound\":%d}}"),slavesFound); + Response_P(PSTR("{\"Sensor54-Command-Result\":{\"Ina226sFound\":%d}}"),Ina226sFound); break; case 2: // Save and restart @@ -497,7 +497,7 @@ void Ina226Show(bool json) int i, num_found; for (num_found = 0, i = 0; i < INA226_MAX_ADDRESSES; i++) { // Skip uninstalled sensors - if (!slaveInfo[i].present) + if (!Ina226Info[i].present) continue; num_found++; diff --git a/tasmota/xsns_56_hpma.ino b/tasmota/xsns_56_hpma.ino index c66b3c7fd..a0e8aef5a 100644 --- a/tasmota/xsns_56_hpma.ino +++ b/tasmota/xsns_56_hpma.ino @@ -64,8 +64,8 @@ void HpmaSecond(void) // Every second void HpmaInit(void) { hpma_type = 0; - if (pin[GPIO_HPMA_RX] < 99 && pin[GPIO_HPMA_TX] < 99) { - HpmaSerial = new TasmotaSerial(pin[GPIO_HPMA_RX], pin[GPIO_HPMA_TX], 1); + if (PinUsed(GPIO_HPMA_RX) && PinUsed(GPIO_HPMA_TX)) { + HpmaSerial = new TasmotaSerial(Pin(GPIO_HPMA_RX), Pin(GPIO_HPMA_TX), 1); hpma115S0 = new HPMA115S0(*HpmaSerial); if (HpmaSerial->begin(9600)) { diff --git a/tasmota/xsns_59_ds1624.ino b/tasmota/xsns_59_ds1624.ino index f3ffcd1f1..60b176c6e 100644 --- a/tasmota/xsns_59_ds1624.ino +++ b/tasmota/xsns_59_ds1624.ino @@ -184,7 +184,7 @@ void DS1624Show(bool json) dtostrfd(ds1624_sns[i].value, Settings.flag2.temperature_resolution, temperature); if (json) { - ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_TEMPERATURE "\":%s}"), ds1624_sns[i].name, temperature); + ResponseAppend_P(JSON_SNS_TEMP, ds1624_sns[i].name, temperature); if ((0 == tele_period) && once) { #ifdef USE_DOMOTICZ DomoticzSensor(DZ_TEMP, temperature); diff --git a/tasmota/xsns_60_GPS.ino b/tasmota/xsns_60_GPS.ino index 69b13aedd..e7094887b 100644 --- a/tasmota/xsns_60_GPS.ino +++ b/tasmota/xsns_60_GPS.ino @@ -18,6 +18,10 @@ */ #ifdef USE_GPS +#if defined(ESP32) && defined(USE_FLOG) + #undef USE_FLOG + #warning FLOG deactivated on ESP32 +#endif //ESP32 /*********************************************************************************************\ -------------------------------------------------------------------------------------------- Version Date Action Description @@ -94,7 +98,7 @@ The serial pins are GPS_RX and GPS_TX, no further installation steps needed. To set latitude and longitude in settings + sensor60 14 - open virtual serial port over TCP, usable for u-center + open virtual serial port over TCP, usable for u-center + sensor60 15 pause virtual serial port over TCP @@ -129,7 +133,7 @@ const char kUBXTypes[] PROGMEM = "UBX"; #define UBX_SERIAL_BUFFER_SIZE 256 #define UBX_TCP_PORT 1234 -#define NTP_MILLIS_OFFSET 50 // estimated latency in milliseconds +#define NTP_MILLIS_OFFSET 50 // estimated latency in milliseconds /********************************************************************************************\ | *globals @@ -350,8 +354,8 @@ void UBXTriggerTele(void) void UBXDetect(void) { UBX.mode.init = 0; - if ((pin[GPIO_GPS_RX] < 99) && (pin[GPIO_GPS_TX] < 99)) { - UBXSerial = new TasmotaSerial(pin[GPIO_GPS_RX], pin[GPIO_GPS_TX], 1, 0, UBX_SERIAL_BUFFER_SIZE); // 64 byte buffer is NOT enough + if (PinUsed(GPIO_GPS_RX) && PinUsed(GPIO_GPS_TX)) { + UBXSerial = new TasmotaSerial(Pin(GPIO_GPS_RX), Pin(GPIO_GPS_TX), 1, 0, UBX_SERIAL_BUFFER_SIZE); // 64 byte buffer is NOT enough if (UBXSerial->begin(9600)) { DEBUG_SENSOR_LOG(PSTR("UBX: started serial")); if (UBXSerial->hardwareSerial()) { @@ -484,8 +488,8 @@ uint32_t UBXprocessGPS() #ifdef USE_FLOG void UBXsendHeader(void) { - WebServer->setContentLength(CONTENT_LENGTH_UNKNOWN); - WebServer->sendHeader(F("Content-Disposition"), F("attachment; filename=TASMOTA.gpx")); + Webserver->setContentLength(CONTENT_LENGTH_UNKNOWN); + Webserver->sendHeader(F("Content-Disposition"), F("attachment; filename=TASMOTA.gpx")); WSSend(200, CT_STREAM, F( "\r\n" "lon/10000000.0f,7,lon); snprintf_P(record, sizeof(record),PSTR("\n\t\n\n"),lat ,lon, stime); // DEBUG_SENSOR_LOG(PSTR("FLOG: DL %u %u"), Flog->sector.dword_buffer[k+j],Flog->sector.dword_buffer[k+j+1]); - WebServer->sendContent_P(record); + Webserver->sendContent_P(record); } void UBXsendFooter(void) { - WebServer->sendContent(F("\n\n")); - WebServer->sendContent(""); + Webserver->sendContent(F("\n\n")); + Webserver->sendContent(""); Rtc.user_time_entry = false; // we have blocked the main loop and want a new valid time } @@ -687,7 +691,7 @@ void UBXHandleTIME() if (UBX.mode.forceUTCupdate || Rtc.user_time_entry == false){ AddLog_P(LOG_LEVEL_INFO, PSTR("UBX: UTC-Time is valid, set system time")); Rtc.utc_time = UBX.rec_buffer.values.time; - } + } Rtc.user_time_entry = true; } } @@ -908,7 +912,7 @@ bool Xsns60(uint8_t function) break; #ifdef USE_FLOG case FUNC_WEB_ADD_HANDLER: - WebServer->on("/UBX", UBXsendFile); + Webserver->on("/UBX", UBXsendFile); break; #endif //USE_FLOG case FUNC_JSON_APPEND: diff --git a/tasmota/xsns_61_MI_NRF24.ino b/tasmota/xsns_61_MI_NRF24.ino index d21f9e7e1..c24bd07da 100644 --- a/tasmota/xsns_61_MI_NRF24.ino +++ b/tasmota/xsns_61_MI_NRF24.ino @@ -21,16 +21,24 @@ Version yyyymmdd Action Description -------------------------------------------------------------------------------------------- + 0.9.8.0 20200705 integrate - add YEE-RC, NLIGHT and MJYD2S, add NRFUSE + --- + 0.9.7.0 20200624 integrate - fix BEARSSL-decryption, remove MBEDTLS, prepare night light sensors + --- + 0.9.6.1 20200622 integrate - use BEARSSL-lib for decryption as default, make decryption optional + --- + 0.9.6.0 20200618 integrate - add decryption for LYWSD03 + --- 0.9.5.0 20200328 integrate - add dew point, multi-page-web ui, refactoring, command interface, simple beacon --- 0.9.4.0 20200304 integrate - sensor types can be ignored (default for LYWSD03), add CGD1 (Alarm clock), correct PDU-types for LYWSD02 --- - 0.9.3.0 20200222 integrate - use now the correct id-word instead of MAC-OUI, + 0.9.3.0 20200222 integrate - use now the correct id-word instead of MAC-OUI, add CGG1 --- - 0.9.2.0 20200212 integrate - "backports" from MI-HM10, change reading pattern, + 0.9.2.0 20200212 integrate - "backports" from MI-HM10, change reading pattern, add missing PDU-types, renaming driver --- 0.9.1.0 20200117 integrate - Added support for the LYWSD02 @@ -51,10 +59,10 @@ #define MINRF_LOG_BUFFER(x) #endif - +#define USE_MI_DECRYPTION /*********************************************************************************************\ * MINRF -* BLE-Sniffer/Bridge for MIJIA/XIAOMI Temperatur/Humidity-Sensor, Mi Flora, LYWSD02, GCx +* BLE-Sniffer/Bridge for MIJIA/XIAOMI Temperatur/Humidity-Sensor, Mi Flora, LYWSD02, GCx, ... * * Usage: Configure NRF24 \*********************************************************************************************/ @@ -62,6 +70,9 @@ #define XSNS_61 61 #include +#ifdef USE_MI_DECRYPTION +#include +#endif //USE_MI_DECRYPTION #define FLORA 1 #define MJ_HT_V1 2 @@ -69,56 +80,81 @@ #define LYWSD03 4 #define CGG1 5 #define CGD1 6 +#define NLIGHT 7 +#define MJYD2S 8 +#define YEERC 9 + +#define MI_TYPES 9 //count this manually #define D_CMND_NRF "NRF" const char S_JSON_NRF_COMMAND_NVALUE[] PROGMEM = "{\"" D_CMND_NRF "%s\":%d}"; const char S_JSON_NRF_COMMAND[] PROGMEM = "{\"" D_CMND_NRF "%s\":\"%s\"}"; -const char kNRF_Commands[] PROGMEM = "Ignore|Page|Scan|Beacon|Chan"; +const char kNRF_Commands[] PROGMEM = "Ignore|Use|Page|Scan|Beacon|Chan|Nlight" +#ifdef USE_MI_DECRYPTION + "|Mjyd2s" + "|Key" +#endif //USE_MI_DECRYPTION + ; enum NRF_Commands { // commands useable in console or rules - CMND_NRF_IGNORE, // ignore specific sensor type (1-6) + CMND_NRF_IGNORE, // ignore specific sensor type (1-9) --- DEPRECATED!!!! + CMND_NRF_USE, // use specific sensor type (1-9) CMND_NRF_PAGE, // sensor entries per web page, which will be shown alternated CMND_NRF_SCAN, // simplified passive BLE adv scan CMND_NRF_BEACON, // even more simplified Beacon, reports time since last sighting - CMND_NRF_CHAN // ignore channel 0-2 (translates to 37-39) + CMND_NRF_CHAN, // ignore channel 0-2 (translates to 37-39) + CMND_NRF_NLIGHT // add Philips night light via MAC +#ifdef USE_MI_DECRYPTION + , CMND_NRF_MJYD2S // add MJYD2S night light via bind_key to a MAC for payload decryption + , CMND_NRF_KEY // add bind_key to a MAC for payload decryption +#endif //USE_MI_DECRYPTION }; -const uint16_t kMINRFSlaveID[6]={ 0x0098, // Flora - 0x01aa, // MJ_HT_V1 - 0x045b, // LYWSD02 - 0x055b, // LYWSD03 - 0x0347, // CGG1 - 0x0576 // CGD1 - }; +const uint16_t kMINRFDeviceID[MI_TYPES]={ 0x0098, // Flora + 0x01aa, // MJ_HT_V1 + 0x045b, // LYWSD02 + 0x055b, // LYWSD03 + 0x0347, // CGG1 + 0x0576, // CGD1 + 0x03dd, // NLIGHT + 0x07f6, // MJYD2S + 0x0153 // yee-rc + }; -const char kMINRFSlaveType1[] PROGMEM = "Flora"; -const char kMINRFSlaveType2[] PROGMEM = "MJ_HT_V1"; -const char kMINRFSlaveType3[] PROGMEM = "LYWSD02"; -const char kMINRFSlaveType4[] PROGMEM = "LYWSD03"; -const char kMINRFSlaveType5[] PROGMEM = "CGG1"; -const char kMINRFSlaveType6[] PROGMEM = "CGD1"; -const char * kMINRFSlaveType[] PROGMEM = {kMINRFSlaveType1,kMINRFSlaveType2,kMINRFSlaveType3,kMINRFSlaveType4,kMINRFSlaveType5,kMINRFSlaveType6}; +const char kMINRFDeviceType1[] PROGMEM = "Flora"; +const char kMINRFDeviceType2[] PROGMEM = "MJ_HT_V1"; +const char kMINRFDeviceType3[] PROGMEM = "LYWSD02"; +const char kMINRFDeviceType4[] PROGMEM = "LYWSD03"; +const char kMINRFDeviceType5[] PROGMEM = "CGG1"; +const char kMINRFDeviceType6[] PROGMEM = "CGD1"; +const char kMINRFDeviceType7[] PROGMEM = "NLIGHT"; +const char kMINRFDeviceType8[] PROGMEM = "MJYD2S"; +const char kMINRFDeviceType9[] PROGMEM = "YEERC"; +const char * kMINRFDeviceType[] PROGMEM = {kMINRFDeviceType1,kMINRFDeviceType2,kMINRFDeviceType3,kMINRFDeviceType4,kMINRFDeviceType5,kMINRFDeviceType6,kMINRFDeviceType7,kMINRFDeviceType8,kMINRFDeviceType9}; // PDU's or different channels 37-39 const uint32_t kMINRFFloPDU[3] = {0x3eaa857d,0xef3b8730,0x71da7b46}; const uint32_t kMINRFMJPDU[3] = {0x4760cd66,0xdbcc0cd3,0x33048df5}; const uint32_t kMINRFL2PDU[3] = {0x3eaa057d,0xef3b0730,0x71dafb46}; -// const uint32_t kMINRFL3PDU[3] = {0x4760dd78,0xdbcc1ccd,0xffffffff}; //encrypted - 58 58 -const uint32_t kMINRFL3PDU[3] = {0x4760cb78,0xdbcc0acd,0x33048beb}; //unencrypted - 30 58 +const uint32_t kMINRFL3PDU[3] = {0x4760dd78,0xdbcc1ccd,0x33049deb}; //encrypted - 58 58 +// const uint32_t kMINRFL3PDU[3] = {0x4760cb78,0xdbcc0acd,0x33048beb}; //unencrypted - 30 58 const uint32_t kMINRFCGGPDU[3] = {0x4760cd6e,0xdbcc0cdb,0x33048dfd}; const uint32_t kMINRFCGDPDU[3] = {0x5da0d752,0xc10c16e7,0x29c497c1}; +// const uint32_t kMINRFNLIPDU[3] = {0x4760C56E,0xDBCC04DB,0x0330485FD}; //NLIGHT +const uint32_t kMINRFYRCPDU[3] = {0x216D63E2,0x5C3DD47E,0x0A5D0E96}; //yee-rc - 50 30 // start-LSFR for different channels 37-39 const uint8_t kMINRFlsfrList_A[3] = {0x4b,0x17,0x23}; // Flora, LYWSD02 const uint8_t kMINRFlsfrList_B[3] = {0x21,0x72,0x43}; // MJ_HT_V1, LYWSD03, CGx +const uint8_t kMINRFlsfrList_C[3] = {0x38,0x25,0x2e}; // yee-rc #pragma pack(1) // important!! struct mi_beacon_t{ - uint16_t productID; + uint16_t PID; uint8_t counter; - uint8_t Mac[6]; + uint8_t MAC[6]; uint8_t spare; // not on MJ_HT_V1 and CGG1 uint8_t type; uint8_t ten; @@ -134,11 +170,15 @@ struct mi_beacon_t{ uint32_t lux:24; //07 uint8_t moist; //08 uint16_t fert; //09 + struct{ //01 + uint16_t num; + uint8_t longPress; + }Btn; }; }; struct CGDPacket_t { // related to the whole 32-byte-packet/buffer - uint8_t serial[6]; + uint8_t MAC[6]; uint16_t mode; union { struct { @@ -152,9 +192,43 @@ struct CGDPacket_t { // related to the whole 32-byte-packet/buffer struct bleAdvPacket_t { // for nRF24L01 max 32 bytes = 2+6+24 uint8_t pduType; uint8_t payloadSize; - uint8_t mac[6]; + uint8_t MAC[6]; }; +#ifdef USE_MI_DECRYPTION +struct encPayload_t { + uint8_t cipher[5]; + uint8_t ExtCnt[3]; + uint8_t tag[4]; +}; + +struct encPacket_t{ + // the packet is longer, but this part is enough to decrypt + uint16_t PID; + uint8_t frameCnt; + uint8_t MAC[6]; + encPayload_t payload; +}; + +struct mjysd02_Packet_t{ + uint8_t padding[11]; + uint8_t payloadSize; + uint8_t padding3; + uint16_t UUID; + uint16_t frameCtrl; + uint16_t PID; + uint8_t frameCnt; + uint8_t data[18]; +}; + +union mi_bindKey_t{ + struct{ + uint8_t key[16]; + uint8_t MAC[6]; + }; + uint8_t buf[22]; +}; +#endif //USE_MI_DECRYPTION union FIFO_t{ bleAdvPacket_t bleAdv; mi_beacon_t miBeacon; @@ -169,24 +243,26 @@ struct { const uint8_t frequency[3] = { 2,26,80}; // real frequency (2400+x MHz) uint16_t timer; + uint16_t ignore = 0; //bitfield: 2^sensor type uint8_t currentChan=0; - uint8_t ignore = 0; //bitfield: 2^sensor type uint8_t channelIgnore = 0; //bitfield: 2^channel (0=37,1=38,2=39) uint8_t confirmedSensors = 0; - uint8_t packetMode; // 0 - normal BLE-advertisements, 1 - 6 "special" sensor packets + uint8_t packetMode; // 0 - normal BLE-advertisements, 1 - 9 "special" sensor packets uint8_t perPage = 4; uint8_t firstUsedPacketMode = 1; - + uint8_t activeLight = 0; + FIFO_t buffer; struct { - uint8_t mac[6]; + uint8_t MAC[6]; uint32_t time; uint32_t PDU[3]; bool active = false; } beacon; bool activeScan = false; bool stopScan = false; + bool triggeredTELE = false; #ifdef DEBUG_TASMOTA_SENSOR uint8_t streamBuffer[sizeof(buffer)]; // raw data stream bytes @@ -196,8 +272,8 @@ struct { } MINRF; struct mi_sensor_t{ - uint8_t type; //Flora = 1; MJ_HT_V1=2; LYWSD02=3; LYWSD03=4; CGG1=5; CGD1=6 - uint8_t serial[6]; + uint8_t type; //Flora = 1; MJ_HT_V1=2; LYWSD02=3; LYWSD03=4; CGG1=5; CGD1=6; YEERC=9 + uint8_t MAC[6]; uint8_t showedUp; float temp; //Flora, MJ_HT_V1, LYWSD0x, CGx union { @@ -210,11 +286,33 @@ struct mi_sensor_t{ float hum; uint8_t bat; }; // MJ_HT_V1, LYWSD0x, CGx + struct { + uint8_t btn; + uint8_t shallSendMQTT; + uint8_t lastCnt; + }; // yee-rc }; }; +struct mi_light_t{ + uint8_t MAC[6]; + uint32_t PDU[3]; + uint8_t type; // NLIGHT=7, MJYD2S=8 + uint8_t bat; + struct { + uint16_t events; //"alarms" since boot + uint8_t lastCnt; //device generated counter of the packet + uint8_t shallSendMQTT; + }; + uint32_t NMT; // no motion time in seconds for the MJYD2S + uint32_t lastTime; + uint8_t lux; //1 or 64 for the MJYD2S + uint8_t eventType; //internal type of actual event for the MJYD2S + +}; + struct scan_entry_t { - uint8_t mac[6]; + uint8_t MAC[6]; uint16_t cid; uint16_t svc; uint16_t uuid; @@ -223,6 +321,10 @@ struct scan_entry_t { std::vector MIBLEsensors; std::vector MINRFscanResult; +#ifdef USE_MI_DECRYPTION +std::vector MIBLEbindKeys; +#endif //USE_MI_DECRYPTION +std::vector MIBLElights; static union{ scan_entry_t MINRFdummyEntry; @@ -232,16 +334,16 @@ static union{ /********************************************************************************************/ /** - * @brief - * - * @param _mode Packet mode 0-6 + * @brief + * + * @param _mode Packet mode 0-9 * @return true If no error occured - * @return false If NRF24L01 is not connected + * @return false If NRF24L01 is not connected */ bool MINRFinitBLE(uint8_t _mode) { if (MINRF.timer%1000 == 0){ // only re-init every 20 seconds - NRF24radio.begin(pin[GPIO_SPI_CS],pin[GPIO_SPI_DC]); + NRF24radio.begin(Pin(GPIO_SPI_CS),Pin(GPIO_SPI_DC)); NRF24radio.setAutoAck(false); NRF24radio.setDataRate(RF24_1MBPS); NRF24radio.disableCRC(); @@ -264,7 +366,7 @@ bool MINRFinitBLE(uint8_t _mode) /** * @brief cycle through the channels 37-39, skip ignored channel - * + * */ void MINRFhopChannel() { @@ -303,26 +405,17 @@ bool MINRFreceivePacket(void) // AddLog_P2(LOG_LEVEL_INFO,PSTR("MINRF: _lsfrlist: %x, chan: %u, mode: %u"),_lsfrlist[MINRF.currentChan],MINRF.currentChan, MINRF.packetMode); switch (MINRF.packetMode) { - case 0: - MINRFwhiten((uint8_t *)&MINRF.buffer, sizeof(MINRF.buffer), MINRF.channel[MINRF.currentChan] | 0x40); + case 0: case 7: case 8: + MINRFwhiten((uint8_t *)&MINRF.buffer, sizeof(MINRF.buffer), MINRF.channel[MINRF.currentChan] | 0x40); // "BEACON" mode, "NLIGHT" mode, "MJYD2S" mode break; - case 1: - MINRFwhiten((uint8_t *)&MINRF.buffer, sizeof(MINRF.buffer), kMINRFlsfrList_A[MINRF.currentChan]); // "flora" mode + case 1: case 3: + MINRFwhiten((uint8_t *)&MINRF.buffer, sizeof(MINRF.buffer), kMINRFlsfrList_A[MINRF.currentChan]); // "flora" mode, "LYWSD02" mode break; - case 2: - MINRFwhiten((uint8_t *)&MINRF.buffer, sizeof(MINRF.buffer), kMINRFlsfrList_B[MINRF.currentChan]); // "MJ_HT_V1" mode + case 2: case 4: case 5: case 6: + MINRFwhiten((uint8_t *)&MINRF.buffer, sizeof(MINRF.buffer), kMINRFlsfrList_B[MINRF.currentChan]); // "MJ_HT_V1" mode, LYWSD03" mode, "CGG1" mode, "CGD1" mode break; - case 3: - MINRFwhiten((uint8_t *)&MINRF.buffer, sizeof(MINRF.buffer), kMINRFlsfrList_A[MINRF.currentChan]); // "LYWSD02" mode - break; - case 4: - MINRFwhiten((uint8_t *)&MINRF.buffer, sizeof(MINRF.buffer), kMINRFlsfrList_B[MINRF.currentChan]); // "LYWSD03" mode - break; - case 5: - MINRFwhiten((uint8_t *)&MINRF.buffer, sizeof(MINRF.buffer), kMINRFlsfrList_B[MINRF.currentChan]); // "CGG1" mode - break; - case 6: - MINRFwhiten((uint8_t *)&MINRF.buffer, sizeof(MINRF.buffer), kMINRFlsfrList_B[MINRF.currentChan]); // "CGD1" mode + case 9: + MINRFwhiten((uint8_t *)&MINRF.buffer, sizeof(MINRF.buffer), kMINRFlsfrList_C[MINRF.currentChan]); // "YEE-RC" mode break; } // DEBUG_SENSOR_LOG(PSTR("MINRF: LSFR:%x"),_lsfr); @@ -332,7 +425,7 @@ bool MINRFreceivePacket(void) return true; } -#ifdef DEBUG_TASMOTA_SENSOR +// #ifdef DEBUG_TASMOTA_SENSOR void MINRFshowBuffer(uint8_t (&buf)[32]){ // we use this only for the 32-byte-FIFO-buffer, so 32 is hardcoded // DEBUG_SENSOR_LOG(PSTR("MINRF: Buffer: %c %c %c %c %c %c %c %c" // " %c %c %c %c %c %c %c %c" @@ -347,7 +440,7 @@ void MINRFshowBuffer(uint8_t (&buf)[32]){ // we use this only for the 32-byte-FI buf[24],buf[25],buf[26],buf[27],buf[28],buf[29],buf[30],buf[31] ); } -#endif // DEBUG_TASMOTA_SENSOR +// #endif // DEBUG_TASMOTA_SENSOR /** * @brief change lsfrBuffer content to "wire bit order" @@ -405,30 +498,30 @@ bool MINRFhandleBeacon(scan_entry_t * entry, uint32_t offset); /** * @brief handle a generic BLE-packet in the scan process - * + * */ void MINRFhandleScan(void){ if(MINRFscanResult.size()>20 || MINRF.stopScan) { MINRF.activeScan=false; MINRFcomputefirstUsedPacketMode(); uint32_t i = 0; // pass counter as reference to lambda - MINRFscanResult.erase(std::remove_if(MINRFscanResult.begin(), + MINRFscanResult.erase(std::remove_if(MINRFscanResult.begin(), MINRFscanResult.end(), [&i](scan_entry_t e) { - if(e.showedUp>2) AddLog_P2(LOG_LEVEL_INFO,PSTR("MINRF: Beacon %02u: %02X%02X%02X%02X%02X%02X Cid: %04X Svc: %04X UUID: %04X"),i,e.mac[0],e.mac[1],e.mac[2],e.mac[3],e.mac[4],e.mac[5],e.cid,e.svc,e.uuid); + if(e.showedUp>2) AddLog_P2(LOG_LEVEL_INFO,PSTR("MINRF: Beacon %02u: %02X%02X%02X%02X%02X%02X Cid: %04X Svc: %04X UUID: %04X"),i,e.MAC[0],e.MAC[1],e.MAC[2],e.MAC[3],e.MAC[4],e.MAC[5],e.cid,e.svc,e.uuid); i++; - return ((e.showedUp < 3)); + return ((e.showedUp < 3)); }), MINRFscanResult.end()); MINRF.stopScan=false; return; } - MINRFreverseMAC(MINRF.buffer.bleAdv.mac); + MINRFreverseMAC(MINRF.buffer.bleAdv.MAC); for(uint32_t i=0; iregular BLE-ADV, 6->"cutted" BLE-ADV with MAC as PDU * @return true - when name, cid, uuid or svc is found with any value @@ -475,7 +568,7 @@ bool MINRFhandleBeacon(scan_entry_t * entry, uint32_t offset){ MINRFwhiten((uint8_t *)&_buf, sizeof(_buf), MINRF.channel[MINRF.currentChan] | 0x40); if (offset == 6) MINRFreverseMAC((uint8_t*)&_buf[2]); - if(memcmp((uint8_t*)&_buf[2],MINRF.beacon.mac,2)==0){ // always at least 2 undestroyed bytes left + if(memcmp((uint8_t*)&_buf[2],MINRF.beacon.MAC,2)==0){ // always at least 2 undestroyed bytes left if(_buf[8]!=2 && _buf[9]!=1){ DEBUG_SENSOR_LOG(PSTR("MINRF: unsupported ADV %02x %02x"), _buf[8],_buf[9]); return success; @@ -536,87 +629,274 @@ bool MINRFhandleBeacon(scan_entry_t * entry, uint32_t offset){ /** * @brief increase beacon timer every second and process the result - * + * */ -void MINRFbeaconCounter(void){ - if(MINRF.beacon.active) { +void MINRFbeaconCounter(void) { + if (MINRF.beacon.active) { MINRF.beacon.time++; +/* char stemp[20]; snprintf_P(stemp, sizeof(stemp),PSTR("{%s:{\"Beacon\": %u}}"),D_CMND_NRF, MINRF.beacon.time); AddLog_P2(LOG_LEVEL_DEBUG, stemp); RulesProcessEvent(stemp); +*/ + Response_P(PSTR("{%s:{\"Beacon\":%u}}"), D_CMND_NRF, MINRF.beacon.time); + XdrvRulesProcess(); } } /** * @brief compute "PDU" from MAC for each possible channel and store it globally - * + * */ -void MINRFcomputeBeaconPDU(void){ +void MINRFcomputeBeaconPDU(uint8_t (&_MAC)[6], uint32_t (&PDU)[3], uint32_t offset){ + uint32_t _PDU[3]; for (uint32_t i = 0; i<3; i++){ bleAdvPacket_t packet; - memcpy((uint8_t *)&packet.mac, (uint8_t *)&MINRF.beacon.mac, sizeof(packet.mac)); - MINRFreverseMAC(packet.mac); + memcpy((uint8_t *)&packet.MAC, (uint8_t *)&_MAC, sizeof(packet.MAC)); + MINRFreverseMAC(packet.MAC); MINRFwhiten((uint8_t *)&packet, sizeof(packet), MINRF.channel[i] | 0x40); MINRFswapbuf((uint8_t*)&packet,sizeof(packet)); - uint32_t pdu = packet.mac[0]<<24 | packet.mac[1]<<16 | packet.mac[2]<<8 | packet.mac[3]; - MINRF.beacon.PDU[i] = pdu; + uint32_t pdu = packet.MAC[0+offset]<<24 | packet.MAC[1+offset]<<16 | packet.MAC[2+offset]<<8 | packet.MAC[3+offset]; + _PDU[i] = pdu; } + memcpy(PDU,_PDU,sizeof(_PDU)); } +#ifdef USE_MI_DECRYPTION +int MINRFdecryptPacket(char *_buf){ + encPacket_t *packet = (encPacket_t*)_buf; + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("to decrypt: %02x %02x %02x %02x %02x %02x %02x %02x"),(uint8_t)_buf[0],(uint8_t)_buf[1],(uint8_t)_buf[2],(uint8_t)_buf[3],(uint8_t)_buf[4],(uint8_t)_buf[5],(uint8_t)_buf[6],(uint8_t)_buf[7]); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR(" : %02x %02x %02x %02x %02x %02x %02x %02x"),(uint8_t)_buf[8],(uint8_t)_buf[9],(uint8_t)_buf[10],(uint8_t)_buf[11],(uint8_t)_buf[12],(uint8_t)_buf[13],(uint8_t)_buf[14],(uint8_t)_buf[15]); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR(" : %02x %02x %02x %02x %02x "),(uint8_t)_buf[16],(uint8_t)_buf[17],(uint8_t)_buf[18],(uint8_t)_buf[19],(uint8_t)_buf[20]); + + int ret = 0; + unsigned char output[16] = {0}; + uint8_t nonce[12]; + const unsigned char authData[1] = {0x11}; + + // nonce: device MAC, device type, frame cnt, ext. cnt + for (uint32_t i = 0; i<6; i++){ + nonce[i] = packet->MAC[5-i]; + } + memcpy((uint8_t*)&nonce+6,(uint8_t*)&packet->PID,2); + nonce[8] = packet->frameCnt; + memcpy((uint8_t*)&nonce+9,(uint8_t*)&packet->payload.ExtCnt,3); + + uint8_t _bindkey[16] = {0x0}; + for(uint32_t i=0; iMAC,MIBLEbindKeys[i].MAC,sizeof(packet->MAC))==0){ + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("have key")); + memcpy(_bindkey,MIBLEbindKeys[i].key,sizeof(_bindkey)); + break; + } + // else{ + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MAC in packet: %02x %02x %02x %02x %02x %02x"), packet->MAC[0], packet->MAC[1], packet->MAC[2], packet->MAC[3], packet->MAC[4], packet->MAC[5]); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MAC in vector: %02x %02x %02x %02x %02x %02x"), MIBLEbindKeys[i].MAC[0], MIBLEbindKeys[i].MAC[1], MIBLEbindKeys[i].MAC[2], MIBLEbindKeys[i].MAC[3], MIBLEbindKeys[i].MAC[4], MIBLEbindKeys[i].MAC[5]); + // } + } + + memcpy(output,packet->payload.cipher, sizeof(packet->payload.cipher)); + + br_aes_small_ctrcbc_keys keyCtx; + br_aes_small_ctrcbc_init(&keyCtx, _bindkey, sizeof(_bindkey)); + + br_ccm_context ctx; + br_ccm_init(&ctx, &keyCtx.vtable); + br_ccm_reset(&ctx, nonce, sizeof(nonce), sizeof(authData),sizeof(packet->payload.cipher),sizeof(packet->payload.tag)); + br_ccm_aad_inject(&ctx, authData, sizeof(authData)); + br_ccm_flip(&ctx); + br_ccm_run(&ctx, 0, output, sizeof(packet->payload.cipher)); + + ret = br_ccm_check_tag(&ctx, packet->payload.tag); + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("BEARSSL: Err:%i, Decrypted : %02x %02x %02x %02x %02x "), ret, output[0],output[1],output[2],output[3],output[4]); + memcpy((uint8_t*)(packet->payload.cipher)+1,output,sizeof(packet->payload.cipher)); + return ret; +} + +int MINRFdecryptMJYD2SPacket(char *_buf, uint8_t _light, char* _output){ + int ret = 0; + uint8_t nonce[12]; + const unsigned char authData[1] = {0x11}; + uint8_t tag[4]; + mjysd02_Packet_t *packet = (mjysd02_Packet_t*)_buf; + + // nonce: device MAC, device type, frame cnt, ext. cnt + for (uint32_t i = 0; i<6; i++){ + nonce[i] = MIBLElights[_light-1].MAC[5-i]; + } + memcpy((uint8_t*)&nonce+6,(uint8_t*)&packet->PID,2); + nonce[8] = packet->frameCnt; + memcpy((uint8_t*)&nonce+9,(uint8_t*)&packet->padding[0] + packet->payloadSize + 5, 3); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("nonce: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x"), nonce[0], nonce[1], nonce[2], nonce[3], nonce[4], nonce[5], nonce[6], nonce[7], nonce[8], nonce[9], nonce[10], nonce[11]); + + uint8_t _bindkey[16]; + for(uint32_t i=0; iMAC[0], packet->MAC[1], packet->MAC[2], packet->MAC[3], packet->MAC[4], packet->MAC[5]); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MAC in vector: %02x %02x %02x %02x %02x %02x"), MIBLEbindKeys[i].MAC[0], MIBLEbindKeys[i].MAC[1], MIBLEbindKeys[i].MAC[2], MIBLEbindKeys[i].MAC[3], MIBLEbindKeys[i].MAC[4], MIBLEbindKeys[i].MAC[5]); + // } + } + + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("size %u"),packet->payloadSize); + uint32_t _size; + int32_t _offset; + uint32_t _tagSize; + switch (packet->payloadSize){ + case 22: + _size = 7; + _offset = 2; + _tagSize = 4; + break; + case 25: + _size = packet->payloadSize - 21; + _offset = -1; + _tagSize = 4; + break; + case 27: + _size = packet->payloadSize - 21; + _offset = 1; + _tagSize = 3; + break; + default: + return 0; + break; + } + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("size %u , offset %u"),_size,_offset); + memcpy(_output,(uint8_t*)&packet->padding[0] + packet->payloadSize - _offset, _size); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("BEARSSL: Output : %02x %02x %02x %02x %02x %02x %02x"), _output[0], _output[1],_output[2],_output[3],_output[4],_output[5],_output[6]); + + br_aes_small_ctrcbc_keys keyCtx; + br_aes_small_ctrcbc_init(&keyCtx, _bindkey, sizeof(_bindkey)); + + br_ccm_context ctx; + br_ccm_init(&ctx, &keyCtx.vtable); + br_ccm_reset(&ctx, nonce, sizeof(nonce), sizeof(authData),_size,4); + br_ccm_aad_inject(&ctx, authData, sizeof(authData)); + br_ccm_flip(&ctx); + br_ccm_run(&ctx, 0, _output, _size); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("BEARSSL: Err:%i, Decrypted : %02x %02x %02x %02x %02x %02x %02x"), ret, _output[0], _output[1],_output[2],_output[3],_output[4],_output[5],_output[6]); + + br_ccm_get_tag(&ctx, tag); + ret = memcmp(tag,(uint8_t*)&packet->padding[0] + packet->payloadSize + 8, _tagSize); + return ret; +} +#endif //USE_MI_DECRYPTION + /*********************************************************************************************\ * helper functions \*********************************************************************************************/ /** * @brief reverse 6-byte-array, hard-coded size of 6 - * - * @param _mac pass an uint_t[6] + * + * @param _MAC pass an uint_t[6] */ -void MINRFreverseMAC(uint8_t _mac[]){ +void MINRFreverseMAC(uint8_t _MAC[]){ uint8_t _reversedMAC[6]; for (uint8_t i=0; i<6; i++){ - _reversedMAC[5-i] = _mac[i]; + _reversedMAC[5-i] = _MAC[i]; + } + memcpy(_MAC,_reversedMAC, sizeof(_reversedMAC)); +} +#ifdef USE_MI_DECRYPTION +void MINRFAddKey(char* payload){ + mi_bindKey_t keyMAC; + memset(keyMAC.buf,0,sizeof(keyMAC)); + MINRFKeyMACStringToBytes(payload,keyMAC.buf); + bool unknownKey = true; + for(uint32_t i=0; i= '0' && c <= '9') + value = (c - '0'); + else if (c >= 'A' && c <= 'F') + value = (10 + (c - 'A')); + _keyMAC[(index/2)] += value << (((index + 1) % 2) * 4); + index++; + } + DEBUG_SENSOR_LOG(PSTR("MINRF: %s to:"),_string); + DEBUG_SENSOR_LOG(PSTR("MINRF: key-array: %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X"),_keyMAC[0],_keyMAC[1],_keyMAC[2],_keyMAC[3],_keyMAC[4],_keyMAC[5],_keyMAC[6],_keyMAC[7],_keyMAC[8],_keyMAC[9],_keyMAC[10],_keyMAC[11],_keyMAC[12],_keyMAC[13],_keyMAC[14],_keyMAC[15]); + DEBUG_SENSOR_LOG(PSTR("MINRF: MAC-array: %02X%02X%02X%02X%02X%02X"),_keyMAC[16],_keyMAC[17],_keyMAC[18],_keyMAC[19],_keyMAC[20],_keyMAC[21]); +} +#endif //USE_MI_DECRYPTION +/** + * @brief + * + * @param _string input string in format: AABBCCDDEEFF (upper case!) + * @param _MAC target byte array with fixed size of 6 + */ +void MINRFMACStringToBytes(char* _string, uint8_t _MAC[]) { //uppercase uint32_t index = 0; while (index < 12) { char c = _string[index]; uint8_t value = 0; if(c >= '0' && c <= '9') value = (c - '0'); - else if (c >= 'A' && c <= 'F') + else if (c >= 'A' && c <= 'F') value = (10 + (c - 'A')); - _mac[(index/2)] += value << (((index + 1) % 2) * 4); + _MAC[(index/2)] += value << (((index + 1) % 2) * 4); index++; } - // DEBUG_SENSOR_LOG(PSTR("MINRF: %s to MAC-array: %02X%02X%02X%02X%02X%02X"),_string,_mac[0],_mac[1],_mac[2],_mac[3],_mac[4],_mac[5]); + // DEBUG_SENSOR_LOG(PSTR("MINRF: %s to MAC-array: %02X%02X%02X%02X%02X%02X"),_string,_MAC[0],_MAC[1],_MAC[2],_MAC[3],_MAC[4],_MAC[5]); } /** * @brief helper function, to avoid to start with an ignored sensor type - * + * */ void MINRFcomputefirstUsedPacketMode(void){ - for (uint32_t i = 0; iCGD1) MINRF.firstUsedPacketMode=0; + if(MINRF.firstUsedPacketMode>MI_TYPES) MINRF.firstUsedPacketMode=0; break; } } } +/** + * @brief Recalculates the receive buffer with an offset in relation to a standard BLE advertisement. + * Used for custom PDU, typically based on a MAC + * + * @param _buf - The receive buffer + * @param offset - in bytes + */ + +void MINRFrecalcBuffer(uint8_t *_buf, uint32_t offset){ + MINRFwhiten((uint8_t *)&MINRF.buffer, sizeof(MINRF.buffer), MINRF.channel[MINRF.currentChan] | 0x40); + MINRFswapbuf((uint8_t*)&MINRF.buffer,sizeof(MINRF.buffer)); + memcpy(_buf+offset,MINRF.buffer.raw,32); + MINRFswapbuf(_buf,32+offset); + MINRFwhiten(_buf, 32+offset, MINRF.channel[MINRF.currentChan] | 0x40); +} + /** * @brief Set packet mode and fitting PDU-type of the NRF24L01 * @@ -640,7 +920,7 @@ void MINRFchangePacketModeTo(uint8_t _mode) { NRF24radio.openReadingPipe(0,kMINRFL2PDU[_nextchannel]);// 95 fe 70 20 -> LYWSD02 break; case 4: // special LYWSD03 packet - NRF24radio.openReadingPipe(0,kMINRFL3PDU[_nextchannel]);// 95 fe 58 30 -> LYWSD03 (= no data message) + NRF24radio.openReadingPipe(0,kMINRFL3PDU[_nextchannel]);// 95 fe 58 58 -> LYWSD03 (= encrypted data message) break; case 5: // special CGG1 packet NRF24radio.openReadingPipe(0,kMINRFCGGPDU[_nextchannel]); // 95 fe 50 30 -> CGG1 @@ -648,6 +928,14 @@ void MINRFchangePacketModeTo(uint8_t _mode) { case 6: // special CGD1 packet NRF24radio.openReadingPipe(0,kMINRFCGDPDU[_nextchannel]); // cd fd 08 0c -> CGD1 break; + case 7: case 8:// MAC based LIGHT packet + if (MIBLElights.size()==0) break; + NRF24radio.openReadingPipe(0,MIBLElights[MINRF.activeLight].PDU[_nextchannel]); // computed from MAC -> NLIGHT and MJYSD2S + MINRF.activeLight++; + break; + case 9: // YEE-RC packet + NRF24radio.openReadingPipe(0,kMINRFYRCPDU[_nextchannel]);// 95 fe 50 30 -> YEE-RC + break; } // DEBUG_SENSOR_LOG(PSTR("MINRF: Change Mode to %u"),_mode); MINRF.packetMode = _mode; @@ -656,29 +944,29 @@ void MINRFchangePacketModeTo(uint8_t _mode) { /** * @brief Return the slot number of a known sensor or return create new sensor slot * - * @param _serial BLE address of the sensor + * @param _MAC BLE address of the sensor * @param _type Type number of the sensor * @return uint32_t Known or new slot in the sensors-vector */ -uint32_t MINRFgetSensorSlot(uint8_t (&_serial)[6], uint16_t _type){ +uint32_t MINRFgetSensorSlot(uint8_t (&_MAC)[6], uint16_t _type){ DEBUG_SENSOR_LOG(PSTR("MINRF: will test ID-type: %x"), _type); bool _success = false; - for (uint32_t i=0;i<6;i++){ // i < sizeof(kMINRFSlaveID) gives compiler warning - if(_type == kMINRFSlaveID[i]){ + for (uint32_t i=0;itype,MINRF.buffer.miBeacon.type); float _tempFloat; + int decryptRet; - if (_sensorVec->type==MJ_HT_V1 || _sensorVec->type==CGG1){ + switch(_sensorVec->type){ + case MJ_HT_V1: case CGG1: case YEERC: memcpy(MINRFtempBuf,(uint8_t*)&MINRF.buffer.miBeacon.spare, 32-9); // shift by one byte for the MJ_HT_V1 and CGG1 memcpy((uint8_t*)&MINRF.buffer.miBeacon.type,MINRFtempBuf, 32-9); // shift by one byte for the MJ_HT_V1 and CGG1 + break; +#ifdef USE_MI_DECRYPTION + case LYWSD03: + decryptRet = MINRFdecryptPacket((char*)&MINRF.buffer); //start with PID + if(decryptRet==1) _sensorVec->showedUp=255; // if decryption worked, this must be a valid sensor + break; +#endif //USE_MI_DECRYPTION } DEBUG_SENSOR_LOG(PSTR("%s at slot %u"), kNRFSlaveType[_sensorVec->type-1],_slot); switch(MINRF.buffer.miBeacon.type){ + case 0x1: + if(MINRF.buffer.miBeacon.counter==_sensorVec->lastCnt) break; + // AddLog_P2(LOG_LEVEL_INFO,PSTR("MINRF: YEE-RC button: %u Long: %u"), MINRF.buffer.miBeacon.Btn.num, MINRF.buffer.miBeacon.Btn.longPress); + _sensorVec->lastCnt=MINRF.buffer.miBeacon.counter; + _sensorVec->btn=MINRF.buffer.miBeacon.Btn.num + (MINRF.buffer.miBeacon.Btn.longPress/2)*6; + _sensorVec->shallSendMQTT = 1; + MINRFtriggerTele(); + break; case 0x04: _tempFloat=(float)(MINRF.buffer.miBeacon.temp)/10.0f; if(_tempFloat<60){ @@ -784,7 +1104,7 @@ void MINRFhandleMiBeaconPacket(void){ case 0x07: _sensorVec->lux=MINRF.buffer.miBeacon.lux & 0x00ffffff; DEBUG_SENSOR_LOG(PSTR("Mode 7: U24: %u Lux"), MINRF.buffer.miBeacon.lux & 0x00ffffff); - break; + break; case 0x08: _tempFloat =(float)MINRF.buffer.miBeacon.moist; if(_tempFloat<100){ @@ -823,29 +1143,14 @@ void MINRFhandleMiBeaconPacket(void){ break; } } -/** - * @brief more or less a placeholder, at least it is technically possible to really decrypt data, but - * the bind_key must be retrieved with 3rd-party-tools -> TODO - */ -void MINRFhandleLYWSD03Packet(void){ - // not much to do ATM, just show the sensor without data - MINRFreverseMAC(MINRF.buffer.miBeacon.Mac); - uint32_t _slot = MINRFgetSensorSlot(MINRF.buffer.miBeacon.Mac, MINRF.buffer.miBeacon.productID); - DEBUG_SENSOR_LOG(PSTR("MINRF: Sensor slot: %u"), _slot); - if(_slot==0xff) return; - - MINRF_LOG_BUFFER(MINRF.streamBuffer); - MINRF_LOG_BUFFER(MINRF.lsfrBuffer); - MINRF_LOG_BUFFER(MINRF.buffer.raw); -} /** * @brief parse the Cleargrass-packet * Note: battery section is based on "internet data" -> not confirmed yet */ void MINRFhandleCGD1Packet(void){ // no MiBeacon - MINRFreverseMAC(MINRF.buffer.CGDPacket.serial); - uint32_t _slot = MINRFgetSensorSlot(MINRF.buffer.CGDPacket.serial, 0x0576); // This must be hard-coded, no object-id in Cleargrass-packet + MINRFreverseMAC(MINRF.buffer.CGDPacket.MAC); + uint32_t _slot = MINRFgetSensorSlot(MINRF.buffer.CGDPacket.MAC, 0x0576); // This must be hard-coded, no object-id in Cleargrass-packet DEBUG_SENSOR_LOG(PSTR("MINRF: Sensor slot: %u"), _slot); if(_slot==0xff) return; @@ -876,12 +1181,130 @@ void MINRFhandleCGD1Packet(void){ // no MiBeacon } } +void MINRFhandleNlightPacket(void){ // no MiBeacon + uint32_t offset = 6; + uint8_t _buf[32+offset]; + MINRFrecalcBuffer((uint8_t*)&_buf,offset); + // AddLog_P2(LOG_LEVEL_INFO,PSTR("MINRF: NLIGHT: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x"),_buf[0],_buf[1],_buf[2],_buf[3],_buf[4],_buf[5],_buf[6],_buf[7],_buf[8],_buf[9],_buf[10],_buf[11],_buf[12],_buf[13],_buf[14],_buf[15],_buf[16],_buf[17],_buf[18]); + uint32_t _frame_PID = _buf[15]<<24 | _buf[16]<<16 | _buf[17]<<8 | _buf[18]; + if(_frame_PID!=0x4030dd03) return; // invalid packet + // AddLog_P2(LOG_LEVEL_INFO,PSTR("MINRF: NLIGHT:%x"),_frame_PID); + uint32_t _idx = MINRF.activeLight-1; + if((millis() - MIBLElights[_idx].lastTime)<1500) return; + if(_buf[19]!=MIBLElights[_idx].lastCnt){ + MIBLElights[_idx].lastCnt = _buf[19]; + MIBLElights[_idx].events++; + MIBLElights[_idx].shallSendMQTT = 1; + MIBLElights[_idx].lastTime = millis(); + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MINRF: NLIGHT %u: events: %u, Cnt:%u"), _idx,MIBLElights[_idx].events, MIBLElights[_idx].lastCnt); + } +} + +void MINRFhandleMJYD2SPacket(void){ // no MiBeacon + uint32_t offset = 8; + uint8_t _buf[32+offset]; + MINRFrecalcBuffer((uint8_t*)&_buf,offset); + mjysd02_Packet_t *_packet = (mjysd02_Packet_t*)&_buf; + if(_packet->PID!=0x07f6) return; // invalid packet + // AddLog_P2(LOG_LEVEL_INFO,PSTR("MINRF: MJYD2S: %02u %04x %04x %04x %02x"),_packet->payloadSize,_packet->UUID,_packet->frameCtrl,_packet->PID,_packet->frameCnt); + // AddLog_P2(LOG_LEVEL_INFO,PSTR("MINRF: PAYLOAD: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x"),_packet->data[0],_packet->data[1],_packet->data[2],_packet->data[3],_packet->data[4],_packet->data[5],_packet->data[6],_packet->data[7],_packet->data[8],_packet->data[9],_packet->data[10],_packet->data[11],_packet->data[12],_packet->data[13],_packet->data[14],_packet->data[15],_packet->data[16],_packet->data[17]); + uint32_t _idx = MINRF.activeLight-1; + switch(_packet->frameCtrl){ + case 0x5910: + if(_packet->frameCnt!=MIBLElights[_idx].lastCnt){ + // AddLog_P2(LOG_LEVEL_INFO,PSTR("MINRF: MJYD2S after motion:%x"),_packet->frameCnt); + MIBLElights[_idx].lastCnt = _packet->frameCnt; + if(millis()-MIBLElights[_idx].lastTime>120000){ + MIBLElights[_idx].eventType = 1; + MIBLElights[_idx].events++; + MIBLElights[_idx].shallSendMQTT = 1; + MIBLElights[_idx].lastTime = millis(); + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MINRF: MJYD2S secondary PIR")); + } + } + break; + case 0x5948: case 0x5958: + uint8_t output[16]; + if(_packet->frameCnt==MIBLElights[_idx].lastCnt) break; + int32_t ret = MINRFdecryptMJYD2SPacket((char*)&_buf, MINRF.activeLight,(char*)&output); + if(ret==0){ + MIBLElights[_idx].lastCnt = _packet->frameCnt; + switch(output[0]){ + case 0x0f: + if(output[1] == 0){ + if(millis()-MIBLElights[_idx].lastTime>1000){ + MIBLElights[_idx].eventType = 1; //PIR + MIBLElights[_idx].shallSendMQTT = 1; + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MINRF: MJYD2S primary PIR")); + MIBLElights[_idx].events++; + } + MIBLElights[_idx].lastTime = millis(); + MIBLElights[_idx].lux = output[3]; + } + break; + case 0x07: + if(output[1] == 0x10){ + MIBLElights[_idx].eventType = 2; //No PIR + MIBLElights[_idx].lux = output[3]; + MIBLElights[_idx].shallSendMQTT = 1; + } + break; + case 0x0a: + MIBLElights[_idx].bat = output[3]; + break; + case 0x17: + MIBLElights[_idx].NMT = output[6]<<24 | output[5]<<16 | output[4]<<8 | output[3]; + MIBLElights[_idx].eventType = 3; // NMT 0, 120, 300, 600, 1800, ... seconds + MIBLElights[_idx].shallSendMQTT = 1; + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MINRF: MJYD2S NMT: %u"), MIBLElights[_idx].NMT ); + break; + } + } + } + // AddLog_P2(LOG_LEVEL_INFO,PSTR("MINRF: NLIGHT:%x"),_frame_PID); +} + + +void MINRFhandleLightPacket(void){ + switch(MIBLElights[MINRF.activeLight-1].type){ + case NLIGHT: + // AddLog_P2(LOG_LEVEL_INFO,PSTR("MINRF: NLIGHT!!")); + MINRFhandleNlightPacket(); + break; + case MJYD2S: + // AddLog_P2(LOG_LEVEL_INFO,PSTR("MINRF: MJYD2S !!")); + MINRFhandleMJYD2SPacket(); + break; + } + if(MIBLElights[MINRF.activeLight-1].shallSendMQTT==1) MINRFtriggerTele(); +} + +void MINRFaddLight(uint8_t _MAC[], uint8_t _type){ // no MiBeacon + for(uint32_t i=0; i6000){ // happens every 6000/20 = 300 seconds DEBUG_SENSOR_LOG(PSTR("MINRF: check for FAKE sensors")); MINRFpurgeFakeSensors(); @@ -890,7 +1313,7 @@ void MINRF_EVERY_50_MSECOND() { // Every 50mseconds MINRF.timer++; if (!MINRFreceivePacket()){ - // DEBUG_SENSOR_LOG(PSTR("MINRF: nothing received")); + // DEBUG_SENSOR_LOG(PSTR("MINRF: nothing received")); } else { @@ -901,15 +1324,15 @@ void MINRF_EVERY_50_MSECOND() { // Every 50mseconds } else MINRFhandleScan(); break; - case FLORA: case MJ_HT_V1: case LYWSD02: case CGG1: + case FLORA: case MJ_HT_V1: case LYWSD02: case CGG1: case LYWSD03: case YEERC: MINRFhandleMiBeaconPacket(); break; - case LYWSD03: - MINRFhandleLYWSD03Packet(); - break; case CGD1: MINRFhandleCGD1Packet(); break; + case NLIGHT: //case MJYD2S: + MINRFhandleLightPacket(); + break; default: break; } @@ -918,12 +1341,21 @@ void MINRF_EVERY_50_MSECOND() { // Every 50mseconds MINRF.firstUsedPacketMode=0; } - MINRF.packetMode = (MINRF.packetMode+1>CGD1) ? MINRF.firstUsedPacketMode : MINRF.packetMode+1; - for (uint32_t i = MINRF.packetMode; iMIBLElights.size()){ + MINRF.activeLight=0; + MINRF.packetMode+=2; + } + else MINRF.packetMode+=2; + } + else{ + MINRF.packetMode = (MINRF.packetMode+1>MI_TYPES) ? MINRF.firstUsedPacketMode : MINRF.packetMode+1; + for (uint32_t i = MINRF.packetMode; i 0) { if (XdrvMailbox.payload == 0){ MINRF.ignore = 0; + MINRF.firstUsedPacketMode = 1; } - else if (XdrvMailbox.payload < CGD1+1) { + else if (XdrvMailbox.payload < MI_TYPES+1) { bitSet(MINRF.ignore,XdrvMailbox.payload); MINRFcomputefirstUsedPacketMode(); MINRF.timer = 5900; - Response_P(S_JSON_NRF_COMMAND, command, kMINRFSlaveType[XdrvMailbox.payload-1]); + Response_P(S_JSON_NRF_COMMAND, command, kMINRFDeviceType[XdrvMailbox.payload-1]); } - else if (XdrvMailbox.payload == 255) { - MINRF.ignore = 255; + else if (XdrvMailbox.payload == 65535) { + MINRF.ignore = 65535; + } + } + Response_P(S_JSON_NRF_COMMAND_NVALUE, command, MINRF.ignore); + break; + case CMND_NRF_USE: + if (XdrvMailbox.data_len > 0) { + if (XdrvMailbox.payload == 0){ + MINRF.ignore = 65535; + MINRF.firstUsedPacketMode = 1; + } + else if (XdrvMailbox.payload < MI_TYPES+1) { + bitClear(MINRF.ignore,XdrvMailbox.payload); + MINRFcomputefirstUsedPacketMode(); + MINRF.timer = 5900; + Response_P(S_JSON_NRF_COMMAND, command, kMINRFDeviceType[XdrvMailbox.payload-1]); + } + else if (XdrvMailbox.payload == 65535) { + MINRF.ignore = 0; } } Response_P(S_JSON_NRF_COMMAND_NVALUE, command, MINRF.ignore); @@ -1007,13 +1458,23 @@ bool NRFCmd(void) { } } if (XdrvMailbox.data_len==12){ // a MAC-string - memset(MINRF.beacon.mac,0,sizeof(MINRF.beacon.mac)); - MINRFMACStringToBytes(XdrvMailbox.data, MINRF.beacon.mac); + memset(MINRF.beacon.MAC,0,sizeof(MINRF.beacon.MAC)); + MINRFMACStringToBytes(XdrvMailbox.data, MINRF.beacon.MAC); MINRF.beacon.time=0; MINRF.beacon.active=true; Response_P(S_JSON_NRF_COMMAND, command, XdrvMailbox.data); } - MINRFcomputeBeaconPDU(); + MINRFcomputeBeaconPDU(MINRF.beacon.MAC,MINRF.beacon.PDU,0); + } + break; + case CMND_NRF_NLIGHT: + if (XdrvMailbox.data_len > 0) { + if (XdrvMailbox.data_len==12){ // a MAC-string + uint8_t _MAC[6] = {0}; + MINRFMACStringToBytes(XdrvMailbox.data, _MAC); + Response_P(S_JSON_NRF_COMMAND, command, XdrvMailbox.data); + MINRFaddLight(_MAC, 7); + } } break; case CMND_NRF_CHAN: @@ -1026,6 +1487,24 @@ bool NRFCmd(void) { } Response_P(S_JSON_NRF_COMMAND_NVALUE, command, MINRF.channelIgnore); break; +#ifdef USE_MI_DECRYPTION + case CMND_NRF_MJYD2S: + if (XdrvMailbox.data_len==44){ // a KEY-MAC-string + MINRFAddKey(XdrvMailbox.data); + uint8_t _MAC[6] = {0}; + MINRFMACStringToBytes((XdrvMailbox.data)+32, _MAC); + MINRFaddLight(_MAC, 8); + Response_P(S_JSON_NRF_COMMAND, command, XdrvMailbox.data); + } + break; + + case CMND_NRF_KEY: + if (XdrvMailbox.data_len==44){ // a KEY-MAC-string + MINRFAddKey(XdrvMailbox.data); + Response_P(S_JSON_NRF_COMMAND, command, XdrvMailbox.data); + } + break; +#endif //USE_MI_DECRYPTION default: // else for Unknown command serviced = false; @@ -1053,40 +1532,98 @@ void MINRFShow(bool json) for (uint32_t i = 0; i < MIBLEsensors.size(); i++) { if(MIBLEsensors[i].showedUp < 3){ DEBUG_SENSOR_LOG(PSTR("MINRF: sensor not fully registered yet")); - break; + if(MIBLEsensors[i].type != YEERC) break; // send every RC code, even if there is a potentially false MAC } - ResponseAppend_P(PSTR(",\"%s-%02x%02x%02x\":{"),kMINRFSlaveType[MIBLEsensors[i].type-1],MIBLEsensors[i].serial[3],MIBLEsensors[i].serial[4],MIBLEsensors[i].serial[5]); - if (MIBLEsensors[i].type==FLORA && !isnan(MIBLEsensors[i].temp)){ - char stemp[FLOATSZ]; - dtostrfd(MIBLEsensors[i].temp, Settings.flag2.temperature_resolution, stemp); - ResponseAppend_P(PSTR("\"" D_JSON_TEMPERATURE "\":%s"), stemp); + switch(MIBLEsensors[i].type){ + case YEERC: + if(MIBLEsensors[i].shallSendMQTT==0) continue; + break; + default: + if(MINRF.triggeredTELE) continue; + break; + } + ResponseAppend_P(PSTR(",\"%s-%02x%02x%02x\":{"),kMINRFDeviceType[MIBLEsensors[i].type-1],MIBLEsensors[i].MAC[3],MIBLEsensors[i].MAC[4],MIBLEsensors[i].MAC[5]); + switch(MIBLEsensors[i].type){ + case FLORA: + if(MINRF.triggeredTELE) { + ResponseJsonEnd(); + break; + } + char stemp[FLOATSZ]; + dtostrfd(MIBLEsensors[i].temp, Settings.flag2.temperature_resolution, stemp); + ResponseAppend_P(PSTR("\"" D_JSON_TEMPERATURE "\":%s"), stemp); - if(MIBLEsensors[i].lux!=0xffffffff){ // this is the error code -> no lux - ResponseAppend_P(PSTR(",\"" D_JSON_ILLUMINANCE "\":%u"), MIBLEsensors[i].lux); - } - if(!isnan(MIBLEsensors[i].moisture)){ - dtostrfd(MIBLEsensors[i].moisture, 0, stemp); - ResponseAppend_P(PSTR(",\"" D_JSON_MOISTURE "\":%s"), stemp); - } - if(!isnan(MIBLEsensors[i].fertility)){ - dtostrfd(MIBLEsensors[i].fertility, 0, stemp); - ResponseAppend_P(PSTR(",\"Fertility\":%s"), stemp); - } - ResponseJsonEnd(); + if(MIBLEsensors[i].lux!=0xffffffff){ // this is the error code -> no lux + ResponseAppend_P(PSTR(",\"" D_JSON_ILLUMINANCE "\":%u"), MIBLEsensors[i].lux); + } + if(!isnan(MIBLEsensors[i].moisture)){ + dtostrfd(MIBLEsensors[i].moisture, 0, stemp); + ResponseAppend_P(PSTR(",\"" D_JSON_MOISTURE "\":%s"), stemp); + } + if(!isnan(MIBLEsensors[i].fertility)){ + dtostrfd(MIBLEsensors[i].fertility, 0, stemp); + ResponseAppend_P(PSTR(",\"Fertility\":%s"), stemp); + } + ResponseJsonEnd(); + break; + case YEERC: + if(MIBLEsensors[i].shallSendMQTT == 1){ + ResponseAppend_P(PSTR("\"Btn\":%u"), MIBLEsensors[i].btn); + MIBLEsensors[i].shallSendMQTT = 0; + } + ResponseJsonEnd(); + break; + default: + if(MINRF.triggeredTELE) { + ResponseJsonEnd(); + break; + } + if(!isnan(MIBLEsensors[i].temp) && !isnan(MIBLEsensors[i].hum)){ + ResponseAppendTHD(MIBLEsensors[i].temp,MIBLEsensors[i].hum); + } + if(MIBLEsensors[i].bat!=0x00){ // this is the error code -> no battery + ResponseAppend_P(PSTR(",\"Battery\":%u"), MIBLEsensors[i].bat); + } + ResponseJsonEnd(); + break; } - if (MIBLEsensors[i].type>FLORA){ - if(!isnan(MIBLEsensors[i].temp) && !isnan(MIBLEsensors[i].hum)){ - ResponseAppendTHD(MIBLEsensors[i].temp,MIBLEsensors[i].hum); + } + for(uint32_t i=0; i no battery - ResponseAppend_P(PSTR(",\"Battery\":%u"), MIBLEsensors[i].bat); - } - ResponseJsonEnd(); + MIBLElights[i].eventType=0; + MIBLElights[i].shallSendMQTT = 0; } + else{ + if(MIBLElights[i].type==MJYD2S){ + if(MIBLElights[i].bat!=0) ResponseAppend_P(PSTR("\"Battery\":%u,\"" D_JSON_ILLUMINANCE "\":%u,"), MIBLElights[i].bat, MIBLElights[i].lux); + } + ResponseAppend_P(PSTR("\"Events\":%u"),MIBLElights[i].events); + } + ResponseJsonEnd(); } if(MINRF.beacon.active){ ResponseAppend_P(PSTR(",\"Beacon\":{\"Timer\":%u}"),MINRF.beacon.time); } + if(MINRF.triggeredTELE) MINRF.triggeredTELE = false; // ResponseJsonEnd(); #ifdef USE_WEBSERVER } else { @@ -1112,36 +1649,53 @@ void MINRFShow(bool json) continue; } WSContentSend_PD(HTTP_MINRF_HL); - WSContentSend_PD(HTTP_MINRF_MAC, kMINRFSlaveType[MIBLEsensors[i].type-1], D_MAC_ADDRESS, MIBLEsensors[i].serial[0], MIBLEsensors[i].serial[1],MIBLEsensors[i].serial[2],MIBLEsensors[i].serial[3],MIBLEsensors[i].serial[4],MIBLEsensors[i].serial[5]); + WSContentSend_PD(HTTP_MINRF_MAC, kMINRFDeviceType[MIBLEsensors[i].type-1], D_MAC_ADDRESS, MIBLEsensors[i].MAC[0], MIBLEsensors[i].MAC[1],MIBLEsensors[i].MAC[2],MIBLEsensors[i].MAC[3],MIBLEsensors[i].MAC[4],MIBLEsensors[i].MAC[5]); + if (MIBLEsensors[i].type==YEERC) continue; if (MIBLEsensors[i].type==FLORA){ if(!isnan(MIBLEsensors[i].temp)){ char temperature[FLOATSZ]; dtostrfd(MIBLEsensors[i].temp, Settings.flag2.temperature_resolution, temperature); - WSContentSend_PD(HTTP_SNS_TEMP, kMINRFSlaveType[MIBLEsensors[i].type-1], temperature, TempUnit()); + WSContentSend_PD(HTTP_SNS_TEMP, kMINRFDeviceType[MIBLEsensors[i].type-1], temperature, TempUnit()); } if(MIBLEsensors[i].lux!=0xffffffff){ // this is the error code -> no valid value - WSContentSend_PD(HTTP_SNS_ILLUMINANCE, kMINRFSlaveType[MIBLEsensors[i].type-1], MIBLEsensors[i].lux); + WSContentSend_PD(HTTP_SNS_ILLUMINANCE, kMINRFDeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].lux); } if(!isnan(MIBLEsensors[i].moisture)){ // this is the error code -> no valid value - WSContentSend_PD(HTTP_SNS_MOISTURE, kMINRFSlaveType[MIBLEsensors[i].type-1], MIBLEsensors[i].moisture); + WSContentSend_PD(HTTP_SNS_MOISTURE, kMINRFDeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].moisture); } if(!isnan(MIBLEsensors[i].fertility)){ // this is the error code -> no valid value - WSContentSend_PD(HTTP_MINRF_FLORA_DATA, kMINRFSlaveType[MIBLEsensors[i].type-1], MIBLEsensors[i].fertility); + WSContentSend_PD(HTTP_MINRF_FLORA_DATA, kMINRFDeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].fertility); } } if (MIBLEsensors[i].type>FLORA){ // everything "above" Flora - WSContentSend_THD(kMINRFSlaveType[MIBLEsensors[i].type-1], MIBLEsensors[i].temp, MIBLEsensors[i].hum); + WSContentSend_THD(kMINRFDeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].temp, MIBLEsensors[i].hum); if(MIBLEsensors[i].bat!=0x00){ // without "juice" nothing can be done - WSContentSend_PD(HTTP_BATTERY, kMINRFSlaveType[MIBLEsensors[i].type-1], MIBLEsensors[i].bat); + WSContentSend_PD(HTTP_BATTERY, kMINRFDeviceType[MIBLEsensors[i].type-1], MIBLEsensors[i].bat); } } } if(MINRF.beacon.active){ WSContentSend_PD(HTTP_MINRF_HL); WSContentSend_PD(HTTP_MINRF_HL); - WSContentSend_PD(HTTP_MINRF_MAC, F("Beacon"), D_MAC_ADDRESS, MINRF.beacon.mac[0], MINRF.beacon.mac[1],MINRF.beacon.mac[2],MINRF.beacon.mac[3],MINRF.beacon.mac[4],MINRF.beacon.mac[5]); + WSContentSend_PD(HTTP_MINRF_MAC, F("Beacon"), D_MAC_ADDRESS, MINRF.beacon.MAC[0], MINRF.beacon.MAC[1],MINRF.beacon.MAC[2],MINRF.beacon.MAC[3],MINRF.beacon.MAC[4],MINRF.beacon.MAC[5]); WSContentSend_PD(PSTR("{s}Beacon Time{m}%u seconds{e}"),MINRF.beacon.time); } + + for(uint32_t i=0; i0){ + WSContentSend_PD(HTTP_BATTERY, kMINRFDeviceType[MIBLElights[i].type-1], MIBLElights[i].bat); + } + if(MIBLElights[i].lux>0){ + WSContentSend_PD(HTTP_SNS_ILLUMINANCE, kMINRFDeviceType[MIBLElights[i].type-1], MIBLElights[i].lux); + } + } + } + if(counter>3) { _page++; counter = 0; @@ -1191,5 +1745,3 @@ bool Xsns61(uint8_t function) #endif // USE_MIBLE #endif // USE_NRF24 #endif // USE_SPI - - diff --git a/tasmota/xsns_62_MI_ESP32.ino b/tasmota/xsns_62_MI_ESP32.ino new file mode 100644 index 000000000..9fa6a71d8 --- /dev/null +++ b/tasmota/xsns_62_MI_ESP32.ino @@ -0,0 +1,1363 @@ +/* + xsns_62_MI_ESP32.ino - MI-BLE-sensors via ESP32 support for Tasmota + + Copyright (C) 2020 Christian Baars and Theo Arends + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + + -------------------------------------------------------------------------------------------- + Version yyyymmdd Action Description + -------------------------------------------------------------------------------------------- + 0.9.0.1 20200706 changed - adapt to new NimBLE-API, tweak scan process + 0.9.0.0 20200413 started - initial development by Christian Baars + forked - from arendst/tasmota - https://github.com/arendst/Tasmota + +*/ +#ifdef ESP32 // ESP32 only. Use define USE_HM10 for ESP8266 support + +#ifdef USE_MI_ESP32 + +#define XSNS_62 62 + +#include +#include + +void MI32scanEndedCB(NimBLEScanResults results); +void MI32notifyCB(NimBLERemoteCharacteristic* pRemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify); + + +struct { + uint16_t perPage = 4; + uint32_t period; // set manually in addition to TELE-period, is set to TELE-period after start + struct { + uint32_t init:1; + uint32_t connected:1; + uint32_t autoScan:1; + uint32_t canScan:1; + uint32_t runningScan:1; + uint32_t canConnect:1; + uint32_t willConnect:1; + uint32_t readingDone:1; + uint32_t shallSetTime:1; + uint32_t willSetTime:1; + uint32_t shallReadBatt:1; + uint32_t willReadBatt:1; + uint32_t shallSetUnit:1; + uint32_t willSetUnit:1; + } mode; + struct { + uint8_t sensor; // points to to the number 0...255 + } state; +} MI32; + +#pragma pack(1) // byte-aligned structures to read the sensor data + + struct { + uint16_t temp; + uint8_t hum; + uint16_t volt; // LYWSD03 only + } LYWSD0x_HT; + struct { + uint8_t spare; + uint16_t temp; + uint16_t hum; + } CGD1_HT; + struct { + uint16_t temp; + uint8_t spare; + uint32_t lux; + uint8_t moist; + uint16_t fert; + } Flora_TLMF; // temperature, lux, moisture, fertility + + +struct mi_beacon_t{ + uint16_t frame; + uint16_t productID; + uint8_t counter; + uint8_t Mac[6]; + uint8_t spare; + uint8_t type; + uint8_t ten; + uint8_t size; + union { + struct{ //0d + uint16_t temp; + uint16_t hum; + }HT; + uint8_t bat; //0a + uint16_t temp; //04 + uint16_t hum; //06 + uint32_t lux; //07 + uint8_t moist; //08 + uint16_t fert; //09 + }; +}; + +struct cg_packet_t { + uint16_t frameID; + uint8_t serial[6]; + uint16_t mode; + union { + struct { + int16_t temp; // -9 - 59 °C + uint16_t hum; + }; + uint8_t bat; + }; +}; + +#pragma pack(0) + +struct mi_sensor_t{ + uint8_t type; //Flora = 1; MI-HT_V1=2; LYWSD02=3; LYWSD03=4; CGG1=5; CGD1=6 + uint8_t serial[6]; + uint8_t showedUp; + float temp; //Flora, MJ_HT_V1, LYWSD0x, CGx + union { + struct { + float moisture; + float fertility; + uint32_t lux; + }; // Flora + struct { + float hum; + }; // MJ_HT_V1, LYWSD0x + }; + union + { + uint8_t bat; // many values seem to be hard-coded garbage (LYWSD0x, GCD1) + uint16_t volt; // LYWSD03MMC + }; + char firmware[6]; // actually only for FLORA but hopefully we can add for more devices +}; + +std::vector MIBLEsensors; +BLEScan* MI32Scan; +BLEScanResults MI32foundDevices; + +/*********************************************************************************************\ + * constants +\*********************************************************************************************/ + +#define D_CMND_MI32 "MI32" + +const char S_JSON_MI32_COMMAND_NVALUE[] PROGMEM = "{\"" D_CMND_MI32 "%s\":%d}"; +const char S_JSON_MI32_COMMAND[] PROGMEM = "{\"" D_CMND_MI32 "%s%s\"}"; +const char kMI32_Commands[] PROGMEM = "Period|Time|Page|Battery|Unit"; + +#define FLORA 1 +#define MJ_HT_V1 2 +#define LYWSD02 3 +#define LYWSD03MMC 4 +#define CGG1 5 +#define CGD1 6 + +const uint16_t kMI32SlaveID[6]={ 0x0098, // Flora + 0x01aa, // MJ_HT_V1 + 0x045b, // LYWSD02 + 0x055b, // LYWSD03 + 0x0347, // CGG1 + 0x0576 // CGD1 + }; + +const char kMI32SlaveType1[] PROGMEM = "Flora"; +const char kMI32SlaveType2[] PROGMEM = "MJ_HT_V1"; +const char kMI32SlaveType3[] PROGMEM = "LYWSD02"; +const char kMI32SlaveType4[] PROGMEM = "LYWSD03"; +const char kMI32SlaveType5[] PROGMEM = "CGG1"; +const char kMI32SlaveType6[] PROGMEM = "CGD1"; +const char * kMI32SlaveType[] PROGMEM = {kMI32SlaveType1,kMI32SlaveType2,kMI32SlaveType3,kMI32SlaveType4,kMI32SlaveType5,kMI32SlaveType6}; + +/*********************************************************************************************\ + * enumerations +\*********************************************************************************************/ + +enum MI32_Commands { // commands useable in console or rules + CMND_MI32_PERIOD, // set period like TELE-period in seconds between read-cycles + CMND_MI32_TIME, // set LYWSD02-Time from ESP8266-time + CMND_MI32_PAGE, // sensor entries per web page, which will be shown alternated + CMND_MI32_BATTERY, // read all battery levels + CMND_MI32_UNIT // toggles the displayed unit between C/F (LYWSD02) + }; + +enum MI32_TASK { + MI32_TASK_SCAN = 0, + MI32_TASK_CONN = 1, + MI32_TASK_TIME = 2, + MI32_TASK_BATT = 3, + MI32_TASK_UNIT = 4, +}; + +/*********************************************************************************************\ + * Classes +\*********************************************************************************************/ + +class MI32SensorCallback : public NimBLEClientCallbacks { + void onConnect(NimBLEClient* pclient) { + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("connected %s"), kMI32SlaveType[(MIBLEsensors[MI32.state.sensor].type)-1]); + MI32.mode.willConnect = 0; + MI32.mode.connected = 1; + } + void onDisconnect(NimBLEClient* pclient) { + MI32.mode.connected = 0; + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("disconnected %s"), kMI32SlaveType[(MIBLEsensors[MI32.state.sensor].type)-1]); + } + bool onConnParamsUpdateRequest(NimBLEClient* MI32Client, const ble_gap_upd_params* params) { + if(params->itvl_min < 24) { /** 1.25ms units */ + return false; + } else if(params->itvl_max > 40) { /** 1.25ms units */ + return false; + } else if(params->latency > 2) { /** Number of intervals allowed to skip */ + return false; + } else if(params->supervision_timeout > 100) { /** 10ms units */ + return false; + } + return true; + } +}; + +class MI32AdvCallbacks: public NimBLEAdvertisedDeviceCallbacks { + void onResult(NimBLEAdvertisedDevice* advertisedDevice) { + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Advertised Device: %s Buffer: %u"),advertisedDevice->getAddress().toString().c_str(),advertisedDevice->getServiceData().length()); + if (advertisedDevice->getServiceData().length() == 0) { + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("No Xiaomi Device: %s Buffer: %u"),advertisedDevice->getAddress().toString().c_str(),advertisedDevice->getServiceData().length()); + return; + } + uint16_t uuid = advertisedDevice->getServiceDataUUID().getNative()->u16.value; + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("UUID: %x"),uuid); + uint8_t addr[6]; + memcpy(addr,advertisedDevice->getAddress().getNative(),6); + MI32_ReverseMAC(addr); + if(uuid==0xfe95) { + MI32ParseResponse((char*)advertisedDevice->getServiceData().data(),advertisedDevice->getServiceData().length(), addr); + MI32Scan->erase(advertisedDevice->getAddress()); + } + else if(uuid==0xfdcd) { + MI32parseCGD1Packet((char*)advertisedDevice->getServiceData().data(),advertisedDevice->getServiceData().length(), addr); + MI32Scan->erase(advertisedDevice->getAddress()); + } + else { + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("No Xiaomi Device: %s Buffer: %u"),advertisedDevice->getAddress().toString().c_str(),advertisedDevice->getServiceData().length()); + } + }; +}; + + +static MI32AdvCallbacks MI32ScanCallbacks; +static MI32SensorCallback MI32SensorCB; +static NimBLEClient* MI32Client; + +/*********************************************************************************************\ + * BLE callback functions +\*********************************************************************************************/ + +void MI32scanEndedCB(NimBLEScanResults results){ + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Scan ended")); + MI32.mode.runningScan = 0; +} + +void MI32notifyCB(NimBLERemoteCharacteristic* pRemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify){ + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Notified length: %u"),length); + switch(MIBLEsensors[MI32.state.sensor].type){ + case LYWSD03MMC: case LYWSD02: + MI32readHT_LY((char*)pData); + MI32.mode.readingDone = 1; + break; + default: + MI32.mode.readingDone = 1; + break; + } +} +/*********************************************************************************************\ + * Helper functions +\*********************************************************************************************/ + +void MI32_ReverseMAC(uint8_t _mac[]){ + uint8_t _reversedMAC[6]; + for (uint8_t i=0; i<6; i++){ + _reversedMAC[5-i] = _mac[i]; + } + memcpy(_mac,_reversedMAC, sizeof(_reversedMAC)); +} + +/*********************************************************************************************\ + * common functions +\*********************************************************************************************/ + + +/** + * @brief Return the slot number of a known sensor or return create new sensor slot + * + * @param _serial BLE address of the sensor + * @param _type Type number of the sensor + * @return uint32_t Known or new slot in the sensors-vector + */ +uint32_t MIBLEgetSensorSlot(uint8_t (&_serial)[6], uint16_t _type){ + + DEBUG_SENSOR_LOG(PSTR("%s: will test ID-type: %x"),D_CMND_MI32, _type); + bool _success = false; + for (uint32_t i=0;i<6;i++){ // i < sizeof(kMI32SlaveID) gives compiler warning + if(_type == kMI32SlaveID[i]){ + DEBUG_SENSOR_LOG(PSTR("MI32: ID is type %u"), i); + _type = i+1; + _success = true; + } + else { + DEBUG_SENSOR_LOG(PSTR("%s: ID-type is not: %x"),D_CMND_MI32,kMI32SlaveID[i]); + } + } + if(!_success) return 0xff; + + DEBUG_SENSOR_LOG(PSTR("%s: vector size %u"),D_CMND_MI32, MIBLEsensors.size()); + for(uint32_t i=0; i= NIMBLE_MAX_CONNECTIONS) { + MI32.mode.willConnect = 0; + DEBUG_SENSOR_LOG(PSTR("%s: max connection already reached"),D_CMND_MI32); + return false; + } + if(!MI32Client) { + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: will create client"),D_CMND_MI32); + MI32Client = NimBLEDevice::createClient(); + MI32Client->setClientCallbacks(&MI32SensorCB , false); + MI32Client->setConnectionParams(12,12,0,48); + MI32Client->setConnectTimeout(30); + } + if (!MI32Client->connect(_address,false)) { + MI32.mode.willConnect = 0; + NimBLEDevice::deleteClient(MI32Client); + DEBUG_SENSOR_LOG(PSTR("%s: did not connect client"),D_CMND_MI32); + return false; + } + DEBUG_SENSOR_LOG(PSTR("%s: did create new client"),D_CMND_MI32); + return true; + // } +} + + +void MI32StartScanTask(){ + if (MI32.mode.connected) return; + MI32.mode.runningScan = 1; + // Wifi.counter = Wifi.counter + 3; + xTaskCreatePinnedToCore( + MI32ScanTask, /* Function to implement the task */ + "MI32ScanTask", /* Name of the task */ + 8192, /* Stack size in words */ + NULL, /* Task input parameter */ + 0, /* Priority of the task */ + NULL, /* Task handle. */ + 0); /* Core where the task should run */ + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: Start scanning"),D_CMND_MI32); +} + +void MI32ScanTask(void *pvParameters){ + if (MI32Scan == nullptr) MI32Scan = NimBLEDevice::getScan(); + DEBUG_SENSOR_LOG(PSTR("%s: Scan Cache Length: %u"),D_CMND_MI32, MI32Scan->getResults().getCount()); + MI32Scan->setAdvertisedDeviceCallbacks(&MI32ScanCallbacks); + MI32Scan->setActiveScan(false); + MI32Scan->start(5, MI32scanEndedCB, true); // hard coded duration + uint32_t timer = 0; + while (MI32.mode.runningScan){ + if (timer>15){ + vTaskDelete( NULL ); + } + timer++; + vTaskDelay(1000/ portTICK_PERIOD_MS); + } + vTaskDelete( NULL ); +} + +void MI32StartSensorTask(){ + MI32.mode.willConnect = 1; + xTaskCreatePinnedToCore( + MI32SensorTask, /* Function to implement the task */ + "MI32SensorTask", /* Name of the task */ + 8192, /* Stack size in words */ + NULL, /* Task input parameter */ + 15, /* Priority of the task */ + NULL, /* Task handle. */ + 0); /* Core where the task should run */ + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: Start sensor connections"),D_CMND_MI32); + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: with sensor: %u"),D_CMND_MI32, MI32.state.sensor); +} + +void MI32SensorTask(void *pvParameters){ + if (MIBLEsensors[MI32.state.sensor].type != LYWSD03MMC) { + MI32.mode.willConnect = 0; + vTaskDelete( NULL ); + } + if (MI32ConnectActiveSensor()){ + uint32_t timer = 0; + while (MI32.mode.connected == 0){ + if (timer>1000){ + MI32Client->disconnect(); + NimBLEDevice::deleteClient(MI32Client); + MI32.mode.willConnect = 0; + vTaskDelay(100/ portTICK_PERIOD_MS); + vTaskDelete( NULL ); + } + timer++; + vTaskDelay(10/ portTICK_PERIOD_MS); + } + + timer = 150; + switch(MIBLEsensors[MI32.state.sensor].type){ + case LYWSD03MMC: + MI32.mode.readingDone = 0; + if(MI32connectLYWSD03forNotification()) timer=0; + break; + default: + break; + } + + while (!MI32.mode.readingDone){ + if (timer>150){ + break; + } + timer++; + vTaskDelay(100/ portTICK_PERIOD_MS); + } + MI32Client->disconnect(); + DEBUG_SENSOR_LOG(PSTR("%s: requested disconnect"),D_CMND_MI32); + } + vTaskDelay(500/ portTICK_PERIOD_MS); + MI32.mode.connected = 0; + vTaskDelete( NULL ); +} + +bool MI32connectLYWSD03forNotification(){ + NimBLERemoteService* pSvc = nullptr; + NimBLERemoteCharacteristic* pChr = nullptr; + static BLEUUID serviceUUID(0xebe0ccb0,0x7a0a,0x4b0c,0x8a1a6ff2997da3a6); + static BLEUUID charUUID(0xebe0ccc1,0x7a0a,0x4b0c,0x8a1a6ff2997da3a6); + pSvc = MI32Client->getService(serviceUUID); + if(pSvc) { + pChr = pSvc->getCharacteristic(charUUID); + } + if (pChr){ + if(pChr->canNotify()) { + if(pChr->subscribe(true,false,MI32notifyCB)) { + return true; + } + } + } + return false; +} + +void MI32StartTimeTask(){ + MI32.mode.willConnect = 1; + xTaskCreatePinnedToCore( + MI32TimeTask, /* Function to implement the task */ + "MI32TimeTask", /* Name of the task */ + 8912, /* Stack size in words */ + NULL, /* Task input parameter */ + 15, /* Priority of the task */ + NULL, /* Task handle. */ + 0); /* Core where the task should run */ + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: Start time set"),D_CMND_MI32); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: with sensor: %u"),D_CMND_MI32, MI32.state.sensor); +} + +void MI32TimeTask(void *pvParameters){ + if (MIBLEsensors[MI32.state.sensor].type != LYWSD02) { + MI32.mode.shallSetTime = 0; + vTaskDelete( NULL ); + } + + if(MI32ConnectActiveSensor()){ + uint32_t timer = 0; + while (MI32.mode.connected == 0){ + if (timer>1000){ + break; + } + timer++; + vTaskDelay(10/ portTICK_PERIOD_MS); + } + + NimBLERemoteService* pSvc = nullptr; + NimBLERemoteCharacteristic* pChr = nullptr; + static BLEUUID serviceUUID(0xEBE0CCB0,0x7A0A,0x4B0C,0x8A1A6FF2997DA3A6); + static BLEUUID charUUID(0xEBE0CCB7,0x7A0A,0x4B0C,0x8A1A6FF2997DA3A6); + pSvc = MI32Client->getService(serviceUUID); + if(pSvc) { + pChr = pSvc->getCharacteristic(charUUID); + + } + if (pChr){ + if(pChr->canWrite()) { + union { + uint8_t buf[5]; + uint32_t time; + } _utc; + _utc.time = Rtc.utc_time; + _utc.buf[4] = Rtc.time_timezone / 60; + + if(!pChr->writeValue(_utc.buf,sizeof(_utc.buf),true)) { // true is important ! + MI32.mode.willConnect = 0; + MI32Client->disconnect(); + } + else { + MI32.mode.shallSetTime = 0; + MI32.mode.willSetTime = 0; + } + } + } + MI32Client->disconnect(); + } + vTaskDelay(500/ portTICK_PERIOD_MS); + MI32.mode.connected = 0; + vTaskDelete( NULL ); +} + +void MI32StartUnitTask(){ + MI32.mode.willConnect = 1; + xTaskCreatePinnedToCore( + MI32UnitTask, /* Function to implement the task */ + "MI32UnitTask", /* Name of the task */ + 8912, /* Stack size in words */ + NULL, /* Task input parameter */ + 15, /* Priority of the task */ + NULL, /* Task handle. */ + 0); /* Core where the task should run */ + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: Start unit set"),D_CMND_MI32); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: with sensor: %u"),D_CMND_MI32, MI32.state.sensor); +} + +void MI32UnitTask(void *pvParameters){ + if (MIBLEsensors[MI32.state.sensor].type != LYWSD02) { + MI32.mode.shallSetUnit = 0; + vTaskDelete( NULL ); + } + + if(MI32ConnectActiveSensor()){ + uint32_t timer = 0; + while (MI32.mode.connected == 0){ + if (timer>1000){ + break; + } + timer++; + vTaskDelay(10/ portTICK_PERIOD_MS); + } + + NimBLERemoteService* pSvc = nullptr; + NimBLERemoteCharacteristic* pChr = nullptr; + static BLEUUID serviceUUID("EBE0CCB0-7A0A-4B0C-8A1A-6FF2997DA3A6"); + static BLEUUID charUUID("EBE0CCBE-7A0A-4B0C-8A1A-6FF2997DA3A6"); + pSvc = MI32Client->getService(serviceUUID); + if(pSvc) { + pChr = pSvc->getCharacteristic(charUUID); + } + + if(pChr->canRead()){ + uint8_t curUnit; + const char *buf = pChr->readValue().c_str(); + if( buf[0] != 0 && buf[0]<101 ){ + curUnit = buf[0]; + } + + if(pChr->canWrite()) { + curUnit = curUnit == 0x01?0xFF:0x01; // C/F + + if(!pChr->writeValue(&curUnit,sizeof(curUnit),true)) { // true is important ! + MI32.mode.willConnect = 0; + MI32Client->disconnect(); + } + else { + MI32.mode.shallSetUnit = 0; + MI32.mode.willSetUnit = 0; + } + } + } + MI32Client->disconnect(); + } + vTaskDelay(500/ portTICK_PERIOD_MS); + MI32.mode.connected = 0; + vTaskDelete( NULL ); +} + +void MI32StartBatteryTask(){ + if (MI32.mode.connected) return; + MI32.mode.willReadBatt = 1; + MI32.mode.willConnect = 1; + MI32.mode.canScan = 0; + xTaskCreatePinnedToCore( + MI32BatteryTask, /* Function to implement the task */ + "MI32BatteryTask", /* Name of the task */ + 8192, /* Stack size in words */ + NULL, /* Task input parameter */ + 15, /* Priority of the task */ + NULL, /* Task handle. */ + 0); /* Core where the task should run */ +} + +void MI32BatteryTask(void *pvParameters){ + // all reported battery values are probably crap, but we allow the reading on demand + switch (MIBLEsensors[MI32.state.sensor].type){ + case LYWSD03MMC: case MJ_HT_V1: case CGG1: + MI32.mode.willConnect = 0; + MI32.mode.willReadBatt = 0; + vTaskDelete( NULL ); + break; + default: + break; + } + + MI32.mode.connected = 0; + if(MI32ConnectActiveSensor()){ + uint32_t timer = 0; + while (MI32.mode.connected == 0){ + if (timer>1000){ + break; + } + timer++; + vTaskDelay(30/ portTICK_PERIOD_MS); + } + + switch(MIBLEsensors[MI32.state.sensor].type){ + case FLORA: + MI32batteryFLORA(); + break; + case LYWSD02: + MI32batteryLYWSD02(); + break; + case CGD1: + MI32batteryCGD1(); + break; + } + MI32Client->disconnect(); + } + MI32.mode.willReadBatt = 0; + // Wifi.counter = 0; // Now check it + vTaskDelay(500/ portTICK_PERIOD_MS); + MI32.mode.connected = 0; + vTaskDelete( NULL ); +} + +void MI32batteryFLORA(){ + uint32_t timer = 0; + while (!MI32.mode.connected){ + if (timer>1000){ + break; + } + timer++; + vTaskDelay(10/ portTICK_PERIOD_MS); + } + DEBUG_SENSOR_LOG(PSTR("%s connected for battery"),kMI32SlaveType[MIBLEsensors[MI32.state.sensor].type-1] ); + NimBLERemoteService* pSvc = nullptr; + NimBLERemoteCharacteristic* pChr = nullptr; + static BLEUUID FLserviceUUID(0x00001204,0x0000,0x1000,0x800000805f9b34fb); + static BLEUUID FLcharUUID(0x00001a02,0x0000,0x1000,0x800000805f9b34fb); + + pSvc = MI32Client->getService(FLserviceUUID); + if(pSvc) { + pChr = pSvc->getCharacteristic(FLcharUUID); + } + if (pChr){ + DEBUG_SENSOR_LOG(PSTR("%s: got Flora char %s"),D_CMND_MI32, pChr->getUUID().toString().c_str()); + if(pChr->canRead()) { + const char *buf = pChr->readValue().c_str(); + MI32readBat((char*)buf); + //we also can read the firmware from response no extra request needed + MI32readFirmwareFLORA((char*)buf); + } + } + MI32.mode.readingDone = 1; +} + +void MI32batteryLYWSD02(){ + uint32_t timer = 0; + while (!MI32.mode.connected){ + if (timer>1000){ + break; + } + timer++; + vTaskDelay(10/ portTICK_PERIOD_MS); + } + + NimBLERemoteService* pSvc = nullptr; + NimBLERemoteCharacteristic* pChr = nullptr; + static BLEUUID LY2serviceUUID(0xEBE0CCB0,0x7A0A,0x4B0C,0x8A1A6FF2997DA3A6); + static BLEUUID LY2charUUID(0xEBE0CCC4,0x7A0A,0x4B0C,0x8A1A6FF2997DA3A6); + + pSvc = MI32Client->getService(LY2serviceUUID); + if(pSvc) { + pChr = pSvc->getCharacteristic(LY2charUUID); + } + if (pChr){ + DEBUG_SENSOR_LOG( PSTR("%s: got LYWSD02 char %s"),D_CMND_MI32, pChr->getUUID().toString().c_str()); + if(pChr->canRead()) { + DEBUG_SENSOR_LOG(PSTR("LYWSD02 char")); + const char *buf = pChr->readValue().c_str(); + MI32readBat((char*)buf); + } + } + MI32.mode.readingDone = 1; +} + +void MI32batteryCGD1(){ + uint32_t timer = 0; + while (!MI32.mode.connected){ + if (timer>1000){ + break; + } + timer++; + vTaskDelay(10/ portTICK_PERIOD_MS); + } + + NimBLERemoteService* pSvc = nullptr; + NimBLERemoteCharacteristic* pChr = nullptr; + static BLEUUID CGD1serviceUUID((uint16_t)0x180F); + static BLEUUID CGD1charUUID((uint16_t)0x2A19); + + pSvc = MI32Client->getService(CGD1serviceUUID); + if(pSvc) { + pChr = pSvc->getCharacteristic(CGD1charUUID); + } + if (pChr){ + DEBUG_SENSOR_LOG(PSTR("%s: got CGD1 char %s"),D_CMND_MI32, pChr->getUUID().toString().c_str()); + if(pChr->canRead()) { + const char *buf = pChr->readValue().c_str(); + MI32readBat((char*)buf); + } + } + MI32.mode.readingDone = 1; +} + + +/*********************************************************************************************\ + * parse the response from advertisements +\*********************************************************************************************/ + +void MI32parseMiBeacon(char * _buf, uint32_t _slot){ + float _tempFloat; + mi_beacon_t _beacon; + if (MIBLEsensors[_slot].type==MJ_HT_V1 || MIBLEsensors[_slot].type==CGG1){ + memcpy((uint8_t*)&_beacon+1,(uint8_t*)_buf, sizeof(_beacon)); // shift by one byte for the MJ_HT_V1 + memcpy((uint8_t*)&_beacon.Mac,(uint8_t*)&_beacon.Mac+1,6); // but shift back the MAC + } + else{ + memcpy((void*)&_beacon,(void*)_buf, sizeof(_beacon)); + } + MI32_ReverseMAC(_beacon.Mac); + + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("MiBeacon type:%02x: %02x %02x %02x %02x %02x %02x %02x %02x"),_beacon.type, (uint8_t)_buf[0],(uint8_t)_buf[1],(uint8_t)_buf[2],(uint8_t)_buf[3],(uint8_t)_buf[4],(uint8_t)_buf[5],(uint8_t)_buf[6],(uint8_t)_buf[7]); + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR(" type:%02x: %02x %02x %02x %02x %02x %02x %02x %02x"),_beacon.type, (uint8_t)_buf[8],(uint8_t)_buf[9],(uint8_t)_buf[10],(uint8_t)_buf[11],(uint8_t)_buf[12],(uint8_t)_buf[13],(uint8_t)_buf[14],(uint8_t)_buf[15]); + + if(MIBLEsensors[_slot].type==4 || MIBLEsensors[_slot].type==6){ + DEBUG_SENSOR_LOG(PSTR("LYWSD03 and CGD1 no support for MiBeacon, type %u"),MIBLEsensors[_slot].type); + return; + } + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s at slot %u"), kMI32SlaveType[MIBLEsensors[_slot].type-1],_slot); + switch(_beacon.type){ + case 0x04: + _tempFloat=(float)(_beacon.temp)/10.0f; + if(_tempFloat<60){ + MIBLEsensors[_slot].temp=_tempFloat; + DEBUG_SENSOR_LOG(PSTR("Mode 4: temp updated")); + } + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 4: U16: %u Temp"), _beacon.temp ); + break; + case 0x06: + _tempFloat=(float)(_beacon.hum)/10.0f; + if(_tempFloat<101){ + MIBLEsensors[_slot].hum=_tempFloat; + DEBUG_SENSOR_LOG(PSTR("Mode 6: hum updated")); + } + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 6: U16: %u Hum"), _beacon.hum); + break; + case 0x07: + MIBLEsensors[_slot].lux=_beacon.lux & 0x00ffffff; + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 7: U24: %u Lux"), _beacon.lux & 0x00ffffff); + break; + case 0x08: + _tempFloat =(float)_beacon.moist; + if(_tempFloat<100){ + MIBLEsensors[_slot].moisture=_tempFloat; + DEBUG_SENSOR_LOG(PSTR("Mode 8: moisture updated")); + } + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 8: U8: %u Moisture"), _beacon.moist); + break; + case 0x09: + _tempFloat=(float)(_beacon.fert); + if(_tempFloat<65535){ // ??? + MIBLEsensors[_slot].fertility=_tempFloat; + DEBUG_SENSOR_LOG(PSTR("Mode 9: fertility updated")); + } + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode 9: U16: %u Fertility"), _beacon.fert); + break; + case 0x0a: + if(_beacon.bat<101){ + MIBLEsensors[_slot].bat = _beacon.bat; + DEBUG_SENSOR_LOG(PSTR("Mode a: bat updated")); + } + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode a: U8: %u %%"), _beacon.bat); + break; + case 0x0d: + _tempFloat=(float)(_beacon.HT.temp)/10.0f; + if(_tempFloat<60){ + MIBLEsensors[_slot].temp = _tempFloat; + DEBUG_SENSOR_LOG(PSTR("Mode d: temp updated")); + } + _tempFloat=(float)(_beacon.HT.hum)/10.0f; + if(_tempFloat<100){ + MIBLEsensors[_slot].hum = _tempFloat; + DEBUG_SENSOR_LOG(PSTR("Mode d: hum updated")); + } + // AddLog_P2(LOG_LEVEL_DEBUG,PSTR("Mode d: U16: %x Temp U16: %x Hum"), _beacon.HT.temp, _beacon.HT.hum); + break; + } +} + +void MI32parseCGD1Packet(char * _buf, uint32_t length, uint8_t addr[6]){ // no MiBeacon + uint8_t _addr[6]; + memcpy(_addr,addr,6); + uint32_t _slot = MIBLEgetSensorSlot(_addr, 0x0576); // This must be hard-coded, no object-id in Cleargrass-packet + DEBUG_SENSOR_LOG(PSTR("MI32: Sensor slot: %u"), _slot); + if(_slot==0xff) return; + cg_packet_t _packet; + memcpy((char*)&_packet,_buf,sizeof(_packet)); + switch (_packet.mode){ + case 0x0401: + float _tempFloat; + _tempFloat=(float)(_packet.temp)/10.0f; + if(_tempFloat<60){ + MIBLEsensors.at(_slot).temp = _tempFloat; + DEBUG_SENSOR_LOG(PSTR("CGD1: temp updated")); + } + _tempFloat=(float)(_packet.hum)/10.0f; + if(_tempFloat<100){ + MIBLEsensors.at(_slot).hum = _tempFloat; + DEBUG_SENSOR_LOG(PSTR("CGD1: hum updated")); + } + DEBUG_SENSOR_LOG(PSTR("CGD1: U16: %x Temp U16: %x Hum"), _packet.temp, _packet.hum); + break; + case 0x0102: + if(_packet.bat<101){ + MIBLEsensors.at(_slot).bat = _packet.bat; + DEBUG_SENSOR_LOG(PSTR("Mode a: bat updated")); + } + break; + default: + DEBUG_SENSOR_LOG(PSTR("MI32: unexpected CGD1-packet")); + } +} + +void MI32ParseResponse(char *buf, uint16_t bufsize, uint8_t addr[6]) { + if(bufsize<10) { + return; + } + char * _pos = buf; + uint16_t _type= _pos[3]*256 + _pos[2]; + // AddLog_P2(LOG_LEVEL_INFO, PSTR("%02x %02x %02x %02x"),(uint8_t)buf[0], (uint8_t)buf[1],(uint8_t)buf[2],(uint8_t)buf[3]); + uint8_t _addr[6]; + memcpy(_addr,addr,6); + uint16_t _slot = MIBLEgetSensorSlot(_addr, _type); + if(_slot!=0xff) MI32parseMiBeacon(_pos,_slot); +} + +/***********************************************************************\ + * Read data from connections +\***********************************************************************/ + +void MI32readHT_LY(char *_buf){ + DEBUG_SENSOR_LOG(PSTR("%s: raw data: %x%x%x%x%x%x%x"),D_CMND_MI32,_buf[0],_buf[1],_buf[2],_buf[3],_buf[4],_buf[5],_buf[6]); + if(_buf[0] != 0 && _buf[1] != 0){ + memcpy(&LYWSD0x_HT,(void *)_buf,sizeof(LYWSD0x_HT)); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s: T * 100: %u, H: %u, V: %u"),D_CMND_MI32,LYWSD0x_HT.temp,LYWSD0x_HT.hum, LYWSD0x_HT.volt); + uint32_t _slot = MI32.state.sensor; + + DEBUG_SENSOR_LOG(PSTR("MIBLE: Sensor slot: %u"), _slot); + static float _tempFloat; + _tempFloat=(float)(LYWSD0x_HT.temp)/100.0f; + if(_tempFloat<60){ + MIBLEsensors[_slot].temp=_tempFloat; + MIBLEsensors[_slot].showedUp=255; // this sensor is real + } + _tempFloat=(float)LYWSD0x_HT.hum; + if(_tempFloat<100){ + MIBLEsensors[_slot].hum = _tempFloat; + DEBUG_SENSOR_LOG(PSTR("LYWSD0x: hum updated")); + } + if (MIBLEsensors[_slot].type == LYWSD03MMC){ + MIBLEsensors[_slot].volt = LYWSD0x_HT.volt; + } + } +} + +bool MI32readBat(char *_buf){ + DEBUG_SENSOR_LOG(PSTR("%s: raw data: %x%x%x%x%x%x%x"),D_CMND_MI32,_buf[0],_buf[1],_buf[2],_buf[3],_buf[4],_buf[5],_buf[6]); + if(_buf[0] != 0){ + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: Battery: %u"),D_CMND_MI32,_buf[0]); + uint32_t _slot = MI32.state.sensor; + DEBUG_SENSOR_LOG(PSTR("MIBLE: Sensor slot: %u"), _slot); + if(_buf[0]<101){ + MIBLEsensors[_slot].bat=_buf[0]; + return true; + } + } + return false; +} + +bool MI32readFirmwareFLORA(char *_buf){ + DEBUG_SENSOR_LOG(PSTR("%s: raw data: %x%x%x%x%x%x%x"),D_CMND_MI32,_buf[0],_buf[1],_buf[2],_buf[3],_buf[4],_buf[5],_buf[6]); + if(_buf[0] != 0){ + char _firmware[5]; // FLORA send 5 byte for firmware version + strncpy(_firmware, _buf+2, 5); + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: Firmware: %s"),D_CMND_MI32,_firmware); + + uint32_t _slot = MI32.state.sensor; + DEBUG_SENSOR_LOG(PSTR("MIBLE: Sensor slot: %u"), _slot); + + memcpy(MIBLEsensors[_slot].firmware, _firmware, 5); + MIBLEsensors[_slot].firmware[5] = '\0'; + return true; + } + return false; +} + +/** + * @brief Main loop of the driver, "high level"-loop + * + */ + +void MI32EverySecond(bool restart){ + static uint32_t _counter = MI32.period - 15; + static uint32_t _nextSensorSlot = 0; + + if(restart){ + _counter = 0; + MI32.mode.canScan = 0; + MI32.mode.canConnect = 1; + MI32.mode.willReadBatt = 0; + MI32.mode.willConnect = 0; + return; + } + + if (MI32.mode.shallSetTime) { + MI32.mode.canScan = 0; + MI32.mode.canConnect = 0; + if (MI32.mode.willSetTime == 0){ + MI32.mode.willSetTime = 1; + MI32StartTask(MI32_TASK_TIME); + } + } + + if (MI32.mode.shallSetUnit) { + MI32.mode.canScan = 0; + MI32.mode.canConnect = 0; + if (MI32.mode.willSetUnit == 0){ + MI32.mode.willSetUnit = 1; + MI32StartTask(MI32_TASK_UNIT); + } + } + + if (MI32.mode.willReadBatt) return; + + if (_counter>MI32.period) { + _counter = 0; + MI32.mode.canScan = 0; + MI32.mode.canConnect = 1; + } + + if(MI32.mode.connected == 1 || MI32.mode.willConnect == 1) return; + + if(MIBLEsensors.size()==0) { + if (MI32.mode.runningScan == 0 && MI32.mode.canScan == 1) MI32StartTask(MI32_TASK_SCAN); + return; + } + + if(_counter==0) { + MI32.state.sensor = _nextSensorSlot; + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: active sensor now: %u of %u"),D_CMND_MI32, MI32.state.sensor, MIBLEsensors.size()-1); + MI32.mode.canScan = 0; + if (MI32.mode.runningScan|| MI32.mode.connected || MI32.mode.willConnect) return; + _nextSensorSlot++; + MI32.mode.canConnect = 1; + if(MI32.mode.connected == 0) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("will connect to %s"),kMI32SlaveType[MIBLEsensors[MI32.state.sensor].type-1] ); + + if (MI32.mode.shallReadBatt) { + MI32StartTask(MI32_TASK_BATT); + } + else{ + MI32StartTask(MI32_TASK_CONN); + } + + } + if (_nextSensorSlot>(MIBLEsensors.size()-1)) { + _nextSensorSlot= 0; + _counter++; + if (MI32.mode.shallReadBatt){ + MI32.mode.shallReadBatt = 0; + } + MI32.mode.canConnect = 0; + MI32.mode.canScan = 1; + } + } + else _counter++; + if (MI32.state.sensor>MIBLEsensors.size()-1) { + _nextSensorSlot = 0; + MI32.mode.canScan = 1; + } + MI32StartTask(MI32_TASK_SCAN); +} + +/*********************************************************************************************\ + * Commands +\*********************************************************************************************/ + +bool MI32Cmd(void) { + char command[CMDSZ]; + bool serviced = true; + uint8_t disp_len = strlen(D_CMND_MI32); + + if (!strncasecmp_P(XdrvMailbox.topic, PSTR(D_CMND_MI32), disp_len)) { // prefix + uint32_t command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic + disp_len, kMI32_Commands); + switch (command_code) { + case CMND_MI32_PERIOD: + if (XdrvMailbox.data_len > 0) { + if (XdrvMailbox.payload==1) { + MI32EverySecond(true); + XdrvMailbox.payload = MI32.period; + } + else { + MI32.period = XdrvMailbox.payload; + } + } + else { + XdrvMailbox.payload = MI32.period; + } + Response_P(S_JSON_MI32_COMMAND_NVALUE, command, XdrvMailbox.payload); + break; + case CMND_MI32_TIME: + if (XdrvMailbox.data_len > 0) { + if(MIBLEsensors.size()>XdrvMailbox.payload){ + if(MIBLEsensors[XdrvMailbox.payload].type == LYWSD02){ + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: will set Time"),D_CMND_MI32); + MI32.state.sensor = XdrvMailbox.payload; + MI32.mode.canScan = 0; + MI32.mode.canConnect = 0; + MI32.mode.shallSetTime = 1; + MI32.mode.willSetTime = 0; + } + } + } + Response_P(S_JSON_MI32_COMMAND_NVALUE, command, XdrvMailbox.payload); + break; + case CMND_MI32_UNIT: + if (XdrvMailbox.data_len > 0) { + if(MIBLEsensors.size()>XdrvMailbox.payload){ + if(MIBLEsensors[XdrvMailbox.payload].type == LYWSD02){ + AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: will set Unit"),D_CMND_MI32); + MI32.state.sensor = XdrvMailbox.payload; + MI32.mode.canScan = 0; + MI32.mode.canConnect = 0; + MI32.mode.shallSetUnit = 1; + MI32.mode.willSetUnit = 0; + } + } + } + Response_P(S_JSON_MI32_COMMAND_NVALUE, command, XdrvMailbox.payload); + break; + case CMND_MI32_PAGE: + if (XdrvMailbox.data_len > 0) { + if (XdrvMailbox.payload == 0) XdrvMailbox.payload = MI32.perPage; // ignore 0 + MI32.perPage = XdrvMailbox.payload; + } + else XdrvMailbox.payload = MI32.perPage; + Response_P(S_JSON_MI32_COMMAND_NVALUE, command, XdrvMailbox.payload); + break; + case CMND_MI32_BATTERY: + MI32EverySecond(true); + MI32.mode.shallReadBatt = 1; + MI32.mode.canConnect = 1; + XdrvMailbox.payload = MI32.period; + Response_P(S_JSON_MI32_COMMAND, command, ""); + break; + default: + // else for Unknown command + serviced = false; + break; + } + } else { + return false; + } + return serviced; +} + + +/*********************************************************************************************\ + * Presentation +\*********************************************************************************************/ + +const char HTTP_MI32[] PROGMEM = "{s}MI ESP32 {m}%u%s / %u{e}"; +const char HTTP_MI32_SERIAL[] PROGMEM = "{s}%s %s{m}%02x:%02x:%02x:%02x:%02x:%02x%{e}"; +const char HTTP_BATTERY[] PROGMEM = "{s}%s" " Battery" "{m}%u %%{e}"; +const char HTTP_VOLTAGE[] PROGMEM = "{s}%s " D_VOLTAGE "{m}%s V{e}"; +const char HTTP_MI32_FLORA_DATA[] PROGMEM = "{s}%s" " Fertility" "{m}%u us/cm{e}"; +const char HTTP_MI32_HL[] PROGMEM = "{s}
    {m}
    {e}"; + +void MI32Show(bool json) +{ + + if (json) { + for (uint32_t i = 0; i < MIBLEsensors.size(); i++) { +/* + char slave[33]; + snprintf_P(slave, sizeof(slave), PSTR("%s-%02x%02x%02x"), + kMI32SlaveType[MIBLEsensors[i].type-1],MIBLEsensors[i].serial[3],MIBLEsensors[i].serial[4],MIBLEsensors[i].serial[5]); + ResponseAppend_P(PSTR(",\"%s\":{"), slave); +*/ + ResponseAppend_P(PSTR(",\"%s-%02x%02x%02x\":{"), + kMI32SlaveType[MIBLEsensors[i].type-1], + MIBLEsensors[i].serial[3], MIBLEsensors[i].serial[4], MIBLEsensors[i].serial[5]); + + if (MIBLEsensors[i].type == FLORA) { + if (!isnan(MIBLEsensors[i].temp)) { + char temperature[FLOATSZ]; // all sensors have temperature + dtostrfd(MIBLEsensors[i].temp, Settings.flag2.temperature_resolution, temperature); + ResponseAppend_P(PSTR("\"" D_JSON_TEMPERATURE "\":%s"), temperature); + } else { + ResponseAppend_P(PSTR("}")); + continue; + } + if (MIBLEsensors[i].lux!=0x0ffffff) { // this is the error code -> no lux + ResponseAppend_P(PSTR(",\"" D_JSON_ILLUMINANCE "\":%u"), MIBLEsensors[i].lux); + } + if (!isnan(MIBLEsensors[i].moisture)) { + ResponseAppend_P(PSTR(",\"" D_JSON_MOISTURE "\":%f"), MIBLEsensors[i].moisture); + } + if (!isnan(MIBLEsensors[i].fertility)) { + ResponseAppend_P(PSTR(",\"Fertility\":%f"), MIBLEsensors[i].fertility); + } + } + if (MIBLEsensors[i].type > FLORA){ + if (!isnan(MIBLEsensors[i].hum) && !isnan(MIBLEsensors[i].temp)) { + ResponseAppendTHD(MIBLEsensors[i].temp, MIBLEsensors[i].hum); + } + } + if (MIBLEsensors[i].bat != 0x00) { // this is the error code -> no battery + if (MIBLEsensors[i].type != LYWSD03MMC) { + ResponseAppend_P(PSTR(",\"Battery\":%u"), MIBLEsensors[i].bat); + } else { + char voltage[FLOATSZ]; + dtostrfd((MIBLEsensors[i].volt)/1000.0f, Settings.flag2.voltage_resolution, voltage); + ResponseAppend_P(PSTR(",\"" D_VOLTAGE "\":%s"), voltage); + } + if (MIBLEsensors[i].type == FLORA) { //actually we can only read FLORA + ResponseAppend_P(PSTR(",\"Firmware\":\"%s\""), MIBLEsensors[i].firmware); + } + } + ResponseAppend_P(PSTR("}")); + } +#ifdef USE_WEBSERVER + } else { + static uint16_t _page = 0; + static uint16_t _counter = 0; + int32_t i = _page * MI32.perPage; + uint32_t j = i + MI32.perPage; + if (j+1>MIBLEsensors.size()){ + j = MIBLEsensors.size(); + } + char stemp[5] ={0}; + if (MIBLEsensors.size()-(_page*MI32.perPage)>1 && MI32.perPage!=1) { + sprintf_P(stemp,"-%u",j); + } + if (MIBLEsensors.size()==0) i=-1; // only for the GUI + + WSContentSend_PD(HTTP_MI32, i+1,stemp,MIBLEsensors.size()); + for (i; i no valid value + WSContentSend_PD(HTTP_SNS_ILLUMINANCE, kMI32SlaveType[MIBLEsensors[i].type-1], MIBLEsensors[i].lux); + } + if (!isnan(MIBLEsensors[i].moisture)) { + WSContentSend_PD(HTTP_SNS_MOISTURE, kMI32SlaveType[MIBLEsensors[i].type-1], int(MIBLEsensors[i].moisture)); + } + if (!isnan(MIBLEsensors[i].fertility)) { + WSContentSend_PD(HTTP_MI32_FLORA_DATA, kMI32SlaveType[MIBLEsensors[i].type-1], int(MIBLEsensors[i].fertility)); + } + } + if (MIBLEsensors[i].type>FLORA) { // everything "above" Flora + if (!isnan(MIBLEsensors[i].hum) && !isnan(MIBLEsensors[i].temp)) { + WSContentSend_THD(kMI32SlaveType[MIBLEsensors[i].type-1], MIBLEsensors[i].temp, MIBLEsensors[i].hum); + } + } + if(MIBLEsensors[i].bat!=0x00){ + if (MIBLEsensors[i].type != LYWSD03MMC) { + WSContentSend_PD(HTTP_BATTERY, kMI32SlaveType[MIBLEsensors[i].type-1], MIBLEsensors[i].bat); + } else { + char voltage[FLOATSZ]; + dtostrfd((MIBLEsensors[i].volt)/1000.0f, Settings.flag2.voltage_resolution, voltage); + WSContentSend_PD(HTTP_VOLTAGE, kMI32SlaveType[MIBLEsensors[i].type-1], voltage); + } + } + } + _counter++; + if(_counter>3) { + _page++; + _counter=0; + } + if (MIBLEsensors.size()%MI32.perPage==0 && _page==MIBLEsensors.size()/MI32.perPage) { _page = 0; } + if (_page>MIBLEsensors.size()/MI32.perPage) { _page = 0; } +#endif // USE_WEBSERVER + } +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xsns62(uint8_t function) +{ + bool result = false; + if (FUNC_INIT == function){ + MI32Init(); + } + + if (MI32.mode.init) { + switch (function) { + case FUNC_EVERY_SECOND: + MI32EverySecond(false); + break; + case FUNC_COMMAND: + result = MI32Cmd(); + break; + case FUNC_JSON_APPEND: + MI32Show(1); + break; +#ifdef USE_WEBSERVER + case FUNC_WEB_SENSOR: + MI32Show(0); + break; +#endif // USE_WEBSERVER + } + } + return result; +} +#endif // USE_MI_ESP32 +#endif // ESP32 \ No newline at end of file diff --git a/tasmota/xsns_62_MI_HM10.ino b/tasmota/xsns_62_MI_HM10.ino index 581a32096..6b5a797eb 100644 --- a/tasmota/xsns_62_MI_HM10.ino +++ b/tasmota/xsns_62_MI_HM10.ino @@ -20,6 +20,8 @@ -------------------------------------------------------------------------------------------- Version yyyymmdd Action Description -------------------------------------------------------------------------------------------- + 0.9.3.1 20200412 added - clean ups, code shrink, battery bugfix + --- 0.9.3.0 20200322 added - multi page web view, command HM10PAGE, polling for MJ_HT_V1, more stable readings, internal refactoring --- @@ -32,6 +34,8 @@ forked - from arendst/tasmota - https://github.com/arendst/Tasmota */ +#ifdef ESP8266 // ESP8266 only. Use define USE_MI_ESP32 for ESP32 support + #ifdef USE_HM10 #define XSNS_62 62 @@ -211,10 +215,10 @@ enum HM10_awaitData: uint8_t { #define TASK_HM10_FEEDBACK 9 // get device response #define TASK_HM10_DISCONN 10 // disconnect #define TASK_HM10_SUB_L3 11 // subscribe to service handle 37 -#define TASK_HM10_READ_HT 12 // read from handle 36 -> Hum & Temp + #define TASK_HM10_SCAN9 13 // longest discovery scan possible #define TASK_HM10_UN_L3 14 // unsubscribe service handle 37 -#define TASK_HM10_DELAY_SUB_LY 15 // start reading from subscription delayed + #define TASK_HM10_READ_BT_L3 16 // read from handle 3A -> Battery #define TASK_HM10_SUB_L2 17 // subscribe to service handle 3C #define TASK_HM10_UN_L2 18 // unsubscribe service handle 3C @@ -227,7 +231,7 @@ enum HM10_awaitData: uint8_t { #define TASK_HM10_SUB_HT_CGD1 25 // subscribe to service handle 4b #define TASK_HM10_UN_HT_CGD1 26 // unsubscribe service handle 4b #define TASK_HM10_READ_B_CGD1 27 // read service handle 11 -#define TASK_HM10_DELAY_SUB_CGD1 28 // start reading from subscription delayed + #define TASK_HM10_READ_B_MJ 29 // read service handle 18 #define TASK_HM10_SUB_HT_MJ 30 // subscribe to service handle 0f @@ -248,7 +252,7 @@ void HM10_Launchtask(uint8_t task, uint8_t slot, uint8_t delay){ void HM10_TaskReplaceInSlot(uint8_t task, uint8_t slot){ HM10.last_command = HM10_TASK_LIST[slot][0]; // save command - HM10_TASK_LIST[slot][0] = task; + HM10_TASK_LIST[slot][0] = task; } void HM10_ReverseMAC(uint8_t _mac[]){ @@ -353,17 +357,17 @@ uint32_t MIBLEgetSensorSlot(uint8_t (&_serial)[6], uint16_t _type){ } } if(!_success) return 0xff; - + DEBUG_SENSOR_LOG(PSTR("%s: vector size %u"),D_CMND_HM10, MIBLEsensors.size()); for(uint32_t i=0; ibegin(HM10.serialSpeed)) { AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s start serial communication fixed to 115200 baud"),D_CMND_HM10); if (HM10Serial->hardwareSerial()) { @@ -422,7 +426,7 @@ void HM10SerialInit(void) { void HM10parseMiBeacon(char * _buf, uint32_t _slot){ float _tempFloat; mi_beacon_t _beacon; - if (MIBLEsensors.at(_slot).type==2){ + if (MIBLEsensors[_slot].type==MJ_HT_V1 || MIBLEsensors[_slot].type==CGG1){ memcpy((uint8_t*)&_beacon+1,(uint8_t*)_buf, sizeof(_beacon)); // shift by one byte for the MJ_HT_V1 memcpy((uint8_t*)&_beacon.Mac,(uint8_t*)&_beacon.Mac+1,6); // but shift back the MAC } @@ -430,29 +434,29 @@ void HM10parseMiBeacon(char * _buf, uint32_t _slot){ memcpy((void*)&_beacon,(void*)_buf, sizeof(_beacon)); } HM10_ReverseMAC(_beacon.Mac); - if(memcmp(_beacon.Mac,MIBLEsensors.at(_slot).serial,sizeof(_beacon.Mac))!=0){ - if (MIBLEsensors.at(_slot).showedUp>3) return; // probably false alarm from a damaged packet + if(memcmp(_beacon.Mac,MIBLEsensors[_slot].serial,sizeof(_beacon.Mac))!=0){ + if (MIBLEsensors[_slot].showedUp>3) return; // probably false alarm from a damaged packet AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s: remove garbage sensor"),D_CMND_HM10); - DEBUG_SENSOR_LOG(PSTR("%s i: %x %x %x %x %x %x"),D_CMND_HM10, MIBLEsensors.at(_slot).serial[5], MIBLEsensors.at(_slot).serial[4],MIBLEsensors.at(_slot).serial[3],MIBLEsensors.at(_slot).serial[2],MIBLEsensors.at(_slot).serial[1],MIBLEsensors.at(_slot).serial[0]); + DEBUG_SENSOR_LOG(PSTR("%s i: %x %x %x %x %x %x"),D_CMND_HM10, MIBLEsensors[_slot].serial[5], MIBLEsensors[_slot].serial[4],MIBLEsensors[_slot].serial[3],MIBLEsensors[_slot].serial[2],MIBLEsensors[_slot].serial[1],MIBLEsensors[_slot].serial[0]); DEBUG_SENSOR_LOG(PSTR("%s n: %x %x %x %x %x %x"),D_CMND_HM10, _beacon.Mac[5], _beacon.Mac[4], _beacon.Mac[3],_beacon.Mac[2],_beacon.Mac[1],_beacon.Mac[0]); MIBLEsensors.erase(MIBLEsensors.begin()+_slot); return; } - if (MIBLEsensors.at(_slot).showedUp<4) MIBLEsensors.at(_slot).showedUp++; + if (MIBLEsensors[_slot].showedUp<4) MIBLEsensors[_slot].showedUp++; DEBUG_SENSOR_LOG(PSTR("MiBeacon type:%02x: %02x %02x %02x %02x %02x %02x %02x %02x"),_beacon.type, (uint8_t)_buf[0],(uint8_t)_buf[1],(uint8_t)_buf[2],(uint8_t)_buf[3],(uint8_t)_buf[4],(uint8_t)_buf[5],(uint8_t)_buf[6],(uint8_t)_buf[7]); DEBUG_SENSOR_LOG(PSTR(" type:%02x: %02x %02x %02x %02x %02x %02x %02x %02x"),_beacon.type, (uint8_t)_buf[8],(uint8_t)_buf[9],(uint8_t)_buf[10],(uint8_t)_buf[11],(uint8_t)_buf[12],(uint8_t)_buf[13],(uint8_t)_buf[14],(uint8_t)_buf[15]); - if(MIBLEsensors.at(_slot).type==4 || MIBLEsensors.at(_slot).type==6){ - DEBUG_SENSOR_LOG(PSTR("LYWSD03 and CGD1 no support for MiBeacon, type %u"),MIBLEsensors.at(_slot).type); + if(MIBLEsensors[_slot].type==4 || MIBLEsensors[_slot].type==6){ + DEBUG_SENSOR_LOG(PSTR("LYWSD03 and CGD1 no support for MiBeacon, type %u"),MIBLEsensors[_slot].type); return; } - DEBUG_SENSOR_LOG(PSTR("%s at slot %u"), kHM10SlaveType[MIBLEsensors.at(_slot).type-1],_slot); + DEBUG_SENSOR_LOG(PSTR("%s at slot %u"), kHM10SlaveType[MIBLEsensors[_slot].type-1],_slot); switch(_beacon.type){ case 0x04: _tempFloat=(float)(_beacon.temp)/10.0f; if(_tempFloat<60){ - MIBLEsensors.at(_slot).temp=_tempFloat; + MIBLEsensors[_slot].temp=_tempFloat; DEBUG_SENSOR_LOG(PSTR("Mode 4: temp updated")); } DEBUG_SENSOR_LOG(PSTR("Mode 4: U16: %u Temp"), _beacon.temp ); @@ -460,19 +464,19 @@ void HM10parseMiBeacon(char * _buf, uint32_t _slot){ case 0x06: _tempFloat=(float)(_beacon.hum)/10.0f; if(_tempFloat<101){ - MIBLEsensors.at(_slot).hum=_tempFloat; + MIBLEsensors[_slot].hum=_tempFloat; DEBUG_SENSOR_LOG(PSTR("Mode 6: hum updated")); } DEBUG_SENSOR_LOG(PSTR("Mode 6: U16: %u Hum"), _beacon.hum); break; case 0x07: - MIBLEsensors.at(_slot).lux=_beacon.lux & 0x00ffffff; + MIBLEsensors[_slot].lux=_beacon.lux & 0x00ffffff; DEBUG_SENSOR_LOG(PSTR("Mode 7: U24: %u Lux"), _beacon.lux & 0x00ffffff); - break; + break; case 0x08: _tempFloat =(float)_beacon.moist; if(_tempFloat<100){ - MIBLEsensors.at(_slot).moisture=_tempFloat; + MIBLEsensors[_slot].moisture=_tempFloat; DEBUG_SENSOR_LOG(PSTR("Mode 8: moisture updated")); } DEBUG_SENSOR_LOG(PSTR("Mode 8: U8: %u Moisture"), _beacon.moist); @@ -480,14 +484,14 @@ void HM10parseMiBeacon(char * _buf, uint32_t _slot){ case 0x09: _tempFloat=(float)(_beacon.fert); if(_tempFloat<65535){ // ??? - MIBLEsensors.at(_slot).fertility=_tempFloat; + MIBLEsensors[_slot].fertility=_tempFloat; DEBUG_SENSOR_LOG(PSTR("Mode 9: fertility updated")); } DEBUG_SENSOR_LOG(PSTR("Mode 9: U16: %u Fertility"), _beacon.fert); break; case 0x0a: if(_beacon.bat<101){ - MIBLEsensors.at(_slot).bat = _beacon.bat; + MIBLEsensors[_slot].bat = _beacon.bat; DEBUG_SENSOR_LOG(PSTR("Mode a: bat updated")); } DEBUG_SENSOR_LOG(PSTR("Mode a: U8: %u %%"), _beacon.bat); @@ -495,12 +499,12 @@ void HM10parseMiBeacon(char * _buf, uint32_t _slot){ case 0x0d: _tempFloat=(float)(_beacon.HT.temp)/10.0f; if(_tempFloat<60){ - MIBLEsensors.at(_slot).temp = _tempFloat; + MIBLEsensors[_slot].temp = _tempFloat; DEBUG_SENSOR_LOG(PSTR("Mode d: temp updated")); } _tempFloat=(float)(_beacon.HT.hum)/10.0f; if(_tempFloat<100){ - MIBLEsensors.at(_slot).hum = _tempFloat; + MIBLEsensors[_slot].hum = _tempFloat; DEBUG_SENSOR_LOG(PSTR("Mode d: hum updated")); } DEBUG_SENSOR_LOG(PSTR("Mode d: U16: %x Temp U16: %x Hum"), _beacon.HT.temp, _beacon.HT.hum); @@ -553,7 +557,7 @@ void HM10ParseResponse(char *buf, uint16_t bufsize) { void HM10readHT_LY(char *_buf){ DEBUG_SENSOR_LOG(PSTR("%s: raw data: %x%x%x%x%x%x%x"),D_CMND_HM10,_buf[0],_buf[1],_buf[2],_buf[3],_buf[4],_buf[5],_buf[6]); - if(_buf[0]==0x4f && _buf[1]==0x4b && _buf[2]==0x2b) return; // "OK+" + if(_buf[0]==0x4f && _buf[1]==0x4b) return; // "OK" if(_buf[0] != 0 && _buf[1] != 0){ memcpy(&LYWSD0x_HT,(void *)_buf,3); AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s: T * 100: %u, H: %u"),D_CMND_HM10,LYWSD0x_HT.temp,LYWSD0x_HT.hum); @@ -563,14 +567,14 @@ void HM10readHT_LY(char *_buf){ static float _tempFloat; _tempFloat=(float)(LYWSD0x_HT.temp)/100.0f; if(_tempFloat<60){ - MIBLEsensors.at(_slot).temp=_tempFloat; + MIBLEsensors[_slot].temp=_tempFloat; HM10.mode.awaiting = none; HM10.current_task_delay = 0; - MIBLEsensors.at(_slot).showedUp=255; // this sensor is real + MIBLEsensors[_slot].showedUp=255; // this sensor is real } _tempFloat=(float)LYWSD0x_HT.hum; if(_tempFloat<100){ - MIBLEsensors.at(_slot).hum = _tempFloat; + MIBLEsensors[_slot].hum = _tempFloat; DEBUG_SENSOR_LOG(PSTR("LYWSD0x: hum updated")); } } @@ -578,7 +582,7 @@ void HM10readHT_LY(char *_buf){ void HM10readHT_CGD1(char *_buf){ DEBUG_SENSOR_LOG(PSTR("%s: raw data: %x%x%x%x%x%x%x"),D_CMND_HM10,_buf[0],_buf[1],_buf[2],_buf[3],_buf[4],_buf[5],_buf[6]); - if(_buf[0]==0x4f && _buf[1]==0x4b && _buf[2]==0x2b) return; // "OK+" + if(_buf[0]==0x4f && _buf[1]==0x4b) return; // "OK" if(_buf[0] == 0){ if(_buf[1]==0 && _buf[2]==0 && _buf[3]==0 && _buf[4]==0) return; memcpy(&CGD1_HT,(void *)_buf,5); @@ -589,14 +593,14 @@ void HM10readHT_CGD1(char *_buf){ static float _tempFloat; _tempFloat=(float)(CGD1_HT.temp)/100.0f; if(_tempFloat<60){ - MIBLEsensors.at(_slot).temp=_tempFloat; + MIBLEsensors[_slot].temp=_tempFloat; HM10.mode.awaiting = none; HM10.current_task_delay = 0; - MIBLEsensors.at(_slot).showedUp=255; // this sensor is real + MIBLEsensors[_slot].showedUp=255; // this sensor is real } _tempFloat=(float)CGD1_HT.hum/100.0f; if(_tempFloat<100){ - MIBLEsensors.at(_slot).hum = _tempFloat; + MIBLEsensors[_slot].hum = _tempFloat; DEBUG_SENSOR_LOG(PSTR("CGD1: hum updated")); } } @@ -608,7 +612,7 @@ void HM10readHT_MJ_HT_V1(char *_buf){ // T=22.7 H=42.2 (response as ASCII) // 0123456789012 uint32_t _temp = (atoi(_buf+2) * 10) + atoi(_buf+5); - uint32_t _hum = (atoi(_buf+9) * 10) + atoi(_buf+12); + uint32_t _hum = (atoi(_buf+9) * 10) + atoi(_buf+12); AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s: T * 10: %u, H * 10: %u"),D_CMND_HM10,_temp,_hum); uint32_t _slot = HM10.state.sensor; @@ -616,21 +620,21 @@ void HM10readHT_MJ_HT_V1(char *_buf){ static float _tempFloat; _tempFloat=(float)_temp/10.0f; if(_tempFloat<60){ - MIBLEsensors.at(_slot).temp=_tempFloat; + MIBLEsensors[_slot].temp=_tempFloat; HM10.mode.awaiting = none; HM10.current_task_delay = 0; - MIBLEsensors.at(_slot).showedUp=255; // this sensor is real + MIBLEsensors[_slot].showedUp=255; // this sensor is real } _tempFloat=(float)_hum/10.0f; if(_tempFloat<100){ - MIBLEsensors.at(_slot).hum = _tempFloat; + MIBLEsensors[_slot].hum = _tempFloat; DEBUG_SENSOR_LOG(PSTR("MJ_HT_V1: hum updated")); } } void HM10readTLMF(char *_buf){ DEBUG_SENSOR_LOG(PSTR("%s: raw data: %x%x%x%x%x%x%x"),D_CMND_HM10,_buf[0],_buf[1],_buf[2],_buf[3],_buf[4],_buf[5],_buf[6]); - if(_buf[0]==0x4f && _buf[1]==0x4b && _buf[2]==0x2b) return; // "OK+" + if(_buf[0]==0x4f && _buf[1]==0x4b) return; // "OK" if(_buf[0] != 0 || _buf[1] != 0){ // this will lose 0.0 degree, but it is not possible to measure a successful reading memcpy(&Flora_TLMF,(void *)_buf,10); AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s: T * 10: %u, L: %u, M: %u, F: %u"),D_CMND_HM10,Flora_TLMF.temp,Flora_TLMF.lux,Flora_TLMF.moist,Flora_TLMF.fert); @@ -640,16 +644,16 @@ void HM10readTLMF(char *_buf){ static float _tempFloat; _tempFloat=(float)(Flora_TLMF.temp)/10.0f; if(_tempFloat<60){ - MIBLEsensors.at(_slot).temp=_tempFloat; - MIBLEsensors.at(_slot).showedUp=255; // this sensor is real + MIBLEsensors[_slot].temp=_tempFloat; + MIBLEsensors[_slot].showedUp=255; // this sensor is real } - MIBLEsensors.at(_slot).lux = Flora_TLMF.lux; + MIBLEsensors[_slot].lux = Flora_TLMF.lux; _tempFloat=(float)Flora_TLMF.moist; if(_tempFloat<100){ - MIBLEsensors.at(_slot).moisture = _tempFloat; + MIBLEsensors[_slot].moisture = _tempFloat; } - MIBLEsensors.at(_slot).fertility = (float)Flora_TLMF.fert; + MIBLEsensors[_slot].fertility = (float)Flora_TLMF.fert; HM10.mode.awaiting = none; HM10.current_task_delay = 0; @@ -658,14 +662,14 @@ void HM10readTLMF(char *_buf){ bool HM10readBat(char *_buf){ DEBUG_SENSOR_LOG(PSTR("%s: raw data: %x%x%x%x%x%x%x"),D_CMND_HM10,_buf[0],_buf[1],_buf[2],_buf[3],_buf[4],_buf[5],_buf[6]); - if(_buf[0]==0x4f && _buf[1]==0x4b && _buf[2]==0x2b) return false; // "OK+" + if(_buf[0]==0x4f && _buf[1]==0x4b) return false; // "OK" if(_buf[0] != 0){ AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: Battery: %u"),D_CMND_HM10,_buf[0]); uint32_t _slot = HM10.state.sensor; DEBUG_SENSOR_LOG(PSTR("MIBLE: Sensor slot: %u"), _slot); if(_buf[0]<101){ - MIBLEsensors.at(_slot).bat=_buf[0]; - MIBLEsensors.at(_slot).showedUp=255; // this sensor is real + MIBLEsensors[_slot].bat=_buf[0]; + MIBLEsensors[_slot].showedUp=255; // this sensor is real return true; } } @@ -680,7 +684,7 @@ bool HM10SerialHandleFeedback(){ // every 50 milliseconds bool success = false; uint32_t i = 0; static char ret[HM10_MAX_RX_BUF] = {0}; - + while(HM10Serial->available()) { // delay(0); if(iwrite("AT+NOTIFY_ON0037"); break; @@ -821,7 +826,8 @@ void HM10_TaskEvery100ms(){ case TASK_HM10_SUB_L2: AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s: subscribe"),D_CMND_HM10); HM10.current_task_delay = 25; // set task delay - HM10_TaskReplaceInSlot(TASK_HM10_DELAY_SUB_LY,i); + HM10.mode.awaiting = tempHumLY; + HM10_TaskReplaceInSlot(TASK_HM10_FEEDBACK,i); runningTaskLoop = false; HM10Serial->write("AT+NOTIFY_ON003C"); break; @@ -844,14 +850,6 @@ void HM10_TaskEvery100ms(){ HM10Serial->write(Rtc.time_timezone / 60); AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s Time-string: %x%x%x%x%x"),D_CMND_HM10, HM10.timebuf[0],HM10.timebuf[1],HM10.timebuf[2],HM10.timebuf[3],(Rtc.time_timezone /60)); break; - case TASK_HM10_READ_HT: - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s: read handle 0036"),D_CMND_HM10); - HM10.current_task_delay = 0; // set task delay - HM10_TaskReplaceInSlot(TASK_HM10_FEEDBACK,i); - runningTaskLoop = false; - HM10Serial->write("AT+READDATA0036?"); - HM10.mode.awaiting = tempHumLY; - break; case TASK_HM10_READ_BT_L3: AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s: read handle 003A"),D_CMND_HM10); HM10.current_task_delay = 2; // set task delay @@ -905,9 +903,9 @@ void HM10_TaskEvery100ms(){ case TASK_HM10_SUB_HT_CGD1: AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s: subscribe 4b"),D_CMND_HM10); HM10.current_task_delay = 5; // set task delay - HM10_TaskReplaceInSlot(TASK_HM10_DELAY_SUB_CGD1,i); + HM10_TaskReplaceInSlot(TASK_HM10_FEEDBACK,i); runningTaskLoop = false; - HM10.mode.awaiting = none; + HM10.mode.awaiting = tempHumCGD1; HM10Serial->write("AT+NOTIFY_ON004b"); break; case TASK_HM10_UN_HT_CGD1: @@ -938,7 +936,6 @@ void HM10_TaskEvery100ms(){ HM10.current_task_delay = 10; // set task delay HM10_TaskReplaceInSlot(TASK_HM10_FEEDBACK,i); runningTaskLoop = false; - HM10.mode.awaiting = none; HM10Serial->write("AT+NOTIFY_ON000F"); HM10.mode.awaiting = tempHumMJ; break; @@ -949,22 +946,6 @@ void HM10_TaskEvery100ms(){ HM10_TASK_LIST[i][0] = TASK_HM10_DONE; // no feedback for reset runningTaskLoop = false; break; - case TASK_HM10_DELAY_SUB_LY: - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s: start reading"),D_CMND_HM10); - HM10SerialHandleFeedback(); - HM10.current_task_delay = HM10_TASK_LIST[i+1][1];; // set task delay - HM10_TASK_LIST[i][0] = TASK_HM10_DONE; // no feedback for reset - HM10.mode.awaiting = tempHumLY; - runningTaskLoop = false; - break; - case TASK_HM10_DELAY_SUB_CGD1: - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s: start reading"),D_CMND_HM10); - HM10SerialHandleFeedback(); - HM10.current_task_delay = HM10_TASK_LIST[i+1][1];; // set task delay - HM10_TASK_LIST[i][0] = TASK_HM10_DONE; // no feedback for reset - HM10.mode.awaiting = tempHumCGD1; - runningTaskLoop = false; - break; case TASK_HM10_STATUS_EVENT: AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s: show status"),D_CMND_HM10); HM10StatusInfo(); @@ -985,10 +966,10 @@ void HM10_TaskEvery100ms(){ } runningTaskLoop = false; // return to main loop HM10.mode.pending_task = 0; // back to main loop control - break; + break; } } - i++; + i++; } } else { @@ -996,16 +977,20 @@ void HM10_TaskEvery100ms(){ } } -void HM10StatusInfo(){ +void HM10StatusInfo() { +/* char stemp[20]; snprintf_P(stemp, sizeof(stemp),PSTR("{%s:{\"found\": %u}}"),D_CMND_HM10, MIBLEsensors.size()); AddLog_P2(LOG_LEVEL_INFO, stemp); RulesProcessEvent(stemp); +*/ + Response_P(PSTR("{%s:{\"found\":%u}}"), D_CMND_HM10, MIBLEsensors.size()); + XdrvRulesProcess(); } /** * @brief Main loop of the driver, "high level"-loop - * + * */ void HM10EverySecond(bool restart){ @@ -1037,11 +1022,11 @@ void HM10EverySecond(bool restart){ HM10.state.sensor = _nextSensorSlot; _nextSensorSlot++; HM10.mode.pending_task = 1; - switch(MIBLEsensors.at(HM10.state.sensor).type){ + switch(MIBLEsensors[HM10.state.sensor].type){ case FLORA: HM10_Read_Flora(); break; - case MJ_HT_V1: + case MJ_HT_V1: case CGG1: HM10_Read_MJ_HT_V1(); break; case LYWSD02: @@ -1125,7 +1110,7 @@ bool HM10Cmd(void) { case CMND_HM10_TIME: if (XdrvMailbox.data_len > 0) { if(MIBLEsensors.size()>XdrvMailbox.payload){ - if(MIBLEsensors.at(XdrvMailbox.payload).type == LYWSD02){ + if(MIBLEsensors[XdrvMailbox.payload].type == LYWSD02){ HM10.state.sensor = XdrvMailbox.payload; HM10_Time_LYWSD02(); } @@ -1173,7 +1158,7 @@ bool HM10Cmd(void) { const char HTTP_HM10[] PROGMEM = "{s}HM10 V%u{m}%u%s / %u{e}"; const char HTTP_HM10_SERIAL[] PROGMEM = "{s}%s %s{m}%02x:%02x:%02x:%02x:%02x:%02x%{e}"; const char HTTP_BATTERY[] PROGMEM = "{s}%s" " Battery" "{m}%u%%{e}"; -const char HTTP_HM10_FLORA_DATA[] PROGMEM = "{s}%s" " Fertility" "{m}%sus/cm{e}"; +const char HTTP_HM10_FLORA_DATA[] PROGMEM = "{s}%s" " Fertility" "{m}%uus/cm{e}"; const char HTTP_HM10_HL[] PROGMEM = "{s}
    {m}
    {e}"; void HM10Show(bool json) @@ -1181,42 +1166,36 @@ void HM10Show(bool json) if (json) { for (uint32_t i = 0; i < MIBLEsensors.size(); i++) { char slave[33]; - sprintf_P(slave,"%s-%02x%02x%02x",kHM10SlaveType[MIBLEsensors.at(i).type-1],MIBLEsensors.at(i).serial[3],MIBLEsensors.at(i).serial[4],MIBLEsensors.at(i).serial[5]); + sprintf_P(slave,"%s-%02x%02x%02x",kHM10SlaveType[MIBLEsensors[i].type-1],MIBLEsensors[i].serial[3],MIBLEsensors[i].serial[4],MIBLEsensors[i].serial[5]); ResponseAppend_P(PSTR(",\"%s\":{"),slave); - if (MIBLEsensors.at(i).type==FLORA){ - if(!isnan(MIBLEsensors.at(i).temp)){ // this is the error code -> no temperature + if (MIBLEsensors[i].type==FLORA){ + if(!isnan(MIBLEsensors[i].temp)){ // this is the error code -> no temperature char temperature[FLOATSZ]; // all sensors have temperature - dtostrfd(MIBLEsensors.at(i).temp, Settings.flag2.temperature_resolution, temperature); + dtostrfd(MIBLEsensors[i].temp, Settings.flag2.temperature_resolution, temperature); ResponseAppend_P(PSTR("\"" D_JSON_TEMPERATURE "\":%s"), temperature); } else { ResponseAppend_P(PSTR("}")); continue; } - char lux[FLOATSZ]; - char moisture[FLOATSZ]; - char fertility[FLOATSZ]; - dtostrfd((float)MIBLEsensors.at(i).lux, 0, lux); - dtostrfd(MIBLEsensors.at(i).moisture, 0, moisture); - dtostrfd(MIBLEsensors.at(i).fertility, 0, fertility); - if(MIBLEsensors.at(i).lux!=0x0ffffff){ // this is the error code -> no temperature - ResponseAppend_P(PSTR(",\"" D_JSON_ILLUMINANCE "\":%s"), lux); + if(MIBLEsensors[i].lux!=0x0ffffff){ // this is the error code -> no lux + ResponseAppend_P(PSTR(",\"" D_JSON_ILLUMINANCE "\":%u"), MIBLEsensors[i].lux); } - if(!isnan(MIBLEsensors.at(i).moisture)){ // this is the error code -> no moisture - ResponseAppend_P(PSTR(",\"" D_JSON_MOISTURE "\":%s"), moisture); + if(!isnan(MIBLEsensors[i].moisture)){ + ResponseAppend_P(PSTR(",\"" D_JSON_MOISTURE "\":%d"), MIBLEsensors[i].moisture); } - if(!isnan(MIBLEsensors.at(i).fertility)){ // this is the error code -> no fertility - ResponseAppend_P(PSTR(",\"Fertility\":%s"), fertility); + if(!isnan(MIBLEsensors[i].fertility)){ + ResponseAppend_P(PSTR(",\"Fertility\":%d"), MIBLEsensors[i].fertility); } } - if (MIBLEsensors.at(i).type>FLORA){ - if(!isnan(MIBLEsensors.at(i).hum) && !isnan(MIBLEsensors.at(i).temp)){ // this is the error code -> no humidity nor temp - ResponseAppendTHD(MIBLEsensors.at(i).temp, MIBLEsensors.at(i).hum); + if (MIBLEsensors[i].type>FLORA){ + if(!isnan(MIBLEsensors[i].hum) && !isnan(MIBLEsensors[i].temp)){ + ResponseAppendTHD(MIBLEsensors[i].temp, MIBLEsensors[i].hum); } } - if(MIBLEsensors.at(i).bat!=0x00){ // this is the error code -> no battery - ResponseAppend_P(PSTR(",\"Battery\":%u"), MIBLEsensors.at(i).bat); - } + if(MIBLEsensors[i].bat!=0x00){ // this is the error code -> no battery + ResponseAppend_P(PSTR(",\"Battery\":%u"), MIBLEsensors[i].bat); + } ResponseAppend_P(PSTR("}")); } #ifdef USE_WEBSERVER @@ -1237,32 +1216,30 @@ void HM10Show(bool json) WSContentSend_PD(HTTP_HM10, HM10.firmware, i+1,stemp,MIBLEsensors.size()); for (i; i no valid value - WSContentSend_PD(HTTP_SNS_ILLUMINANCE, kHM10SlaveType[MIBLEsensors.at(i).type-1], MIBLEsensors.at(i).lux); + if(MIBLEsensors[i].lux!=0x00ffffff){ // this is the error code -> no valid value + WSContentSend_PD(HTTP_SNS_ILLUMINANCE, kHM10SlaveType[MIBLEsensors[i].type-1], MIBLEsensors[i].lux); } - if(!isnan(MIBLEsensors.at(i).moisture)){ // this is the error code -> no valid value - WSContentSend_PD(HTTP_SNS_MOISTURE, kHM10SlaveType[MIBLEsensors.at(i).type-1], MIBLEsensors.at(i).moisture); + if(!isnan(MIBLEsensors[i].moisture)){ + WSContentSend_PD(HTTP_SNS_MOISTURE, kHM10SlaveType[MIBLEsensors[i].type-1], MIBLEsensors[i].moisture); } - if(!isnan(MIBLEsensors.at(i).fertility)){ // this is the error code -> no valid value - char fertility[FLOATSZ]; - dtostrfd(MIBLEsensors.at(i).fertility, 0, fertility); - WSContentSend_PD(HTTP_HM10_FLORA_DATA, kHM10SlaveType[MIBLEsensors.at(i).type-1], fertility); + if(!isnan(MIBLEsensors[i].fertility)){ + WSContentSend_PD(HTTP_HM10_FLORA_DATA, kHM10SlaveType[MIBLEsensors[i].type-1], MIBLEsensors[i].fertility); } } - if (MIBLEsensors.at(i).type>FLORA){ // everything "above" Flora - if(!isnan(MIBLEsensors.at(i).hum) && !isnan(MIBLEsensors.at(i).temp)){ - WSContentSend_THD(kHM10SlaveType[MIBLEsensors.at(i).type-1], MIBLEsensors.at(i).temp, MIBLEsensors.at(i).hum); + if (MIBLEsensors[i].type>FLORA){ // everything "above" Flora + if(!isnan(MIBLEsensors[i].hum) && !isnan(MIBLEsensors[i].temp)){ + WSContentSend_THD(kHM10SlaveType[MIBLEsensors[i].type-1], MIBLEsensors[i].temp, MIBLEsensors[i].hum); } - } - if(MIBLEsensors.at(i).bat!=0x00){ - WSContentSend_PD(HTTP_BATTERY, kHM10SlaveType[MIBLEsensors.at(i).type-1], MIBLEsensors.at(i).bat); + } + if(MIBLEsensors[i].bat!=0x00){ + WSContentSend_PD(HTTP_BATTERY, kHM10SlaveType[MIBLEsensors[i].type-1], MIBLEsensors[i].bat); } } _counter++; @@ -1284,7 +1261,7 @@ bool Xsns62(uint8_t function) { bool result = false; - if ((pin[GPIO_HM10_RX] < 99) && (pin[GPIO_HM10_TX] < 99)) { + if (PinUsed(GPIO_HM10_RX) && PinUsed(GPIO_HM10_TX)) { switch (function) { case FUNC_INIT: HM10SerialInit(); // init and start communication @@ -1315,4 +1292,5 @@ bool Xsns62(uint8_t function) } return result; } -#endif //USE_HM10 +#endif // USE_HM10 +#endif // ESP8266 \ No newline at end of file diff --git a/tasmota/xsns_64_hrxl.ino b/tasmota/xsns_64_hrxl.ino index a82134c94..389197e1a 100644 --- a/tasmota/xsns_64_hrxl.ino +++ b/tasmota/xsns_64_hrxl.ino @@ -41,9 +41,9 @@ bool hrxl_found = false; void HRXLInit(void) { hrxl_found = false; - if ((pin[GPIO_HRXL_RX] < 99)) + if (PinUsed(GPIO_HRXL_RX)) { - HRXLSerial = new TasmotaSerial(pin[GPIO_HRXL_RX], -1, 1); + HRXLSerial = new TasmotaSerial(Pin(GPIO_HRXL_RX), -1, 1); if (HRXLSerial->begin(9600)) { if (HRXLSerial->hardwareSerial()) @@ -100,8 +100,7 @@ void HRXLShow(bool json) bool Xsns64(uint8_t function) { - if (pin[GPIO_HRXL_RX] >= 99) - return false; + if (!PinUsed(GPIO_HRXL_RX)) { return false; } switch (function) { diff --git a/tasmota/xsns_65_hdc1080.ino b/tasmota/xsns_65_hdc1080.ino index 6e834ef90..5b3b159ba 100644 --- a/tasmota/xsns_65_hdc1080.ino +++ b/tasmota/xsns_65_hdc1080.ino @@ -62,7 +62,7 @@ #define HDC1080_CONV_TIME 15 // Assume 6.50 + 6.35 ms + x of conversion delay for this device #define HDC1080_TEMP_MULT 0.0025177 -#define HDC1080_RH_MULT 0.0025177 +#define HDC1080_RH_MULT 0.0015258 #define HDC1080_TEMP_OFFSET 40.0 const char* hdc_type_name = "HDC1080"; diff --git a/tasmota/xsns_67_as3935.ino b/tasmota/xsns_67_as3935.ino new file mode 100644 index 000000000..3e795b91a --- /dev/null +++ b/tasmota/xsns_67_as3935.ino @@ -0,0 +1,811 @@ +/* + xsns_67_as3935.ino - AS3935 Franklin Lightning Sensor support for Tasmota + + Copyright (C) 2020 Martin Wagner + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifdef USE_I2C +#ifdef USE_AS3935 +/*********************************************************************************************\ + * AS3935 Lightning Sensor + * + * I2C Address: 0x03 +\*********************************************************************************************/ + +#define XSNS_67 67 +#define XI2C_48 48 // See I2CDEVICES.md + +#define D_NAME_AS3935 "AS3935" +#define AS3935_ADDR 0x03 + +// Reg mask shift +#define IRQ_TBL 0x03, 0x0F, 0 +#define ENERGY_RAW_1 0x04, 0xFF, 0 +#define ENERGY_RAW_2 0x05, 0xFF, 0 +#define ENERGY_RAW_3 0x06, 0x1F, 0 +#define LGHT_DIST 0x07, 0x3F, 0 +#define DISP_TRCO 0x08, 0x20, 5 +#define DISP_LCO 0x08, 0x80, 7 +#define TUNE_CAPS 0x08, 0x0F, 0 +#define AFE_GB 0x00, 0x3E, 0 +#define WDTH 0x01, 0x0F, 0 +#define NF_LEVEL 0x01, 0x70, 4 +#define SPIKE_REJECT 0x02, 0x0F, 0 +#define MIN_NUM_LIGH 0x02, 0x30, 4 +#define DISTURBER 0x03, 0x20, 5 +#define LCO_FDIV 0x03, 0xC0, 6 + +#define INDOORS 0x24 +#define OUTDOORS 0x1C + +// Global +const char HTTP_SNS_UNIT_KILOMETER[] PROGMEM = D_UNIT_KILOMETER; +// Http +const char HTTP_SNS_AS3935_ENERGY[] PROGMEM = "{s}" D_NAME_AS3935 " " D_AS3935_ENERGY " {m}%d{e}"; +const char HTTP_SNS_AS3935_DISTANZ[] PROGMEM = "{s}" D_NAME_AS3935 " " D_AS3935_DISTANCE " {m}%u " D_UNIT_KILOMETER "{e}"; +const char HTTP_SNS_AS3935_VRMS[] PROGMEM = "{s}" D_NAME_AS3935 " " D_AS3935_VRMS "{m}%#4u (%d){e}"; + +const char HTTP_SNS_AS3935_OUTDOORS[] PROGMEM = "{s}%s " D_AS3935_GAIN " {m}" D_AS3935_OUTDOORS " {e}"; +const char HTTP_SNS_AS3935_INDOORS[] PROGMEM = "{s}%s " D_AS3935_GAIN " {m}" D_AS3935_INDOORS " {e}"; +const char* const HTTP_SNS_AS3935_GAIN[] PROGMEM = {HTTP_SNS_AS3935_INDOORS, HTTP_SNS_AS3935_OUTDOORS}; + +const char HTTP_SNS_AS3935_DIST_ON[] PROGMEM = "{s}%s " D_AS3935_DISTURBER " {m}" D_AS3935_ON " {e}"; +const char HTTP_SNS_AS3935_DIST_OFF[] PROGMEM = "{s}%s " D_AS3935_DISTURBER " {m}" D_AS3935_OFF " {e}"; +const char* const HTTP_SNS_AS3935_DISTURBER[] PROGMEM = {HTTP_SNS_AS3935_DIST_OFF, HTTP_SNS_AS3935_DIST_ON}; +// http Messages +const char HTTP_SNS_AS3935_EMPTY[] PROGMEM = "{s}%s: " D_AS3935_NOMESS "{e}"; +const char HTTP_SNS_AS3935_OUT[] PROGMEM = "{s}%s: " D_AS3935_OUT "{e}"; +const char HTTP_SNS_AS3935_NOT[] PROGMEM = "{s}%s: " D_AS3935_NOT "{e}"; +const char HTTP_SNS_AS3935_ABOVE[] PROGMEM = "{s}%s: " D_AS3935_ABOVE "{e}"; +const char HTTP_SNS_AS3935_NOISE[] PROGMEM = "{s}%s: " D_AS3935_NOISE "{e}"; +const char HTTP_SNS_AS3935_DISTURB[] PROGMEM = "{s}%s: " D_AS3935_DISTDET "{e}"; +const char HTTP_SNS_AS3935_INTNOEV[] PROGMEM = "{s}%s: " D_AS3935_INTNOEV "{e}"; +const char HTTP_SNS_AS3935_MSG[] PROGMEM = "{s}%s: " D_AS3935_LIGHT " " D_AS3935_APRX " %d " D_UNIT_KILOMETER " " D_AS3935_AWAY "{e}"; +const char* const HTTP_SNS_AS3935_TABLE_1[] PROGMEM = { HTTP_SNS_AS3935_EMPTY, HTTP_SNS_AS3935_MSG, HTTP_SNS_AS3935_OUT, HTTP_SNS_AS3935_NOT, HTTP_SNS_AS3935_ABOVE, HTTP_SNS_AS3935_NOISE, HTTP_SNS_AS3935_DISTURB, HTTP_SNS_AS3935_INTNOEV }; +// Json +const char JSON_SNS_AS3935_EVENTS[] PROGMEM = ",\"%s\":{\"" D_JSON_EVENT "\":%d,\"" D_JSON_DISTANCE "\":%d,\"" D_JSON_ENERGY "\":%u,\"" D_JSON_STAGE "\":%d}"; +// Json Command +const char* const S_JSON_AS3935_COMMAND_ONOFF[] PROGMEM = {"\"" D_AS3935_OFF "\"","\"" D_AS3935_ON"\""}; +const char* const S_JSON_AS3935_COMMAND_GAIN[] PROGMEM = {"\"" D_AS3935_INDOORS "\"", "\"" D_AS3935_OUTDOORS "\""}; +const char* const S_JSON_AS3935_COMMAND_CAL[] PROGMEM = {"" D_AS3935_CAL_FAIL "","" D_AS3935_CAL_OK ""}; + +const char S_JSON_AS3935_COMMAND_STRING[] PROGMEM = "{\"" D_NAME_AS3935 "\":{\"%s\":%s}}"; +const char S_JSON_AS3935_COMMAND_NVALUE[] PROGMEM = "{\"" D_NAME_AS3935 "\":{\"%s\":%d}}"; +const char S_JSON_AS3935_COMMAND_SETTINGS[] PROGMEM = "{\"" D_NAME_AS3935 "\":{\"Gain\":%s,\"NFfloor\":%d,\"uVrms\":%d,\"Tunecaps\":%d,\"MinNumLight\":%d,\"Rejektion\":%d,\"Wdthreshold\":%d,\"MinNFstage\":%d,\"NFAutoTime\":%d,\"DisturberAutoTime\":%d,\"Disturber\":%s,\"NFauto\":%s,\"Disturberauto\":%s,\"NFautomax\":%s,\"Mqttlightevent\":%s}}"; + +const char kAS3935_Commands[] PROGMEM = "setnf|setminstage|setml|default|setgain|settunecaps|setrej|setwdth|disttime|nftime|disturber|autonf|autodisturber|autonfmax|mqttevent|settings|calibrate"; + +enum AS3935_Commands { // commands for Console + CMND_AS3935_SET_NF, // Noise Floor Level, value from 0-7 (3 Bit) + CMND_AS3935_SET_MINNF, // Set Min Noise Floor Level when Autotune is active Value von 0-15 + CMND_AS3935_SET_MINLIGHT, // Minimum number of lightning 0=1/1=5/2=9/3=16 Lightnings + CMND_AS3935_SET_DEF, // set default for Sensor and Settings + CMND_AS3935_SET_GAIN, // Set Inddoor/Outdoor + CMND_AS3935_SET_TUNE, // Internal Tuning Capacitors (from 0 to 120pF in steps of 8pf) + CMND_AS3935_SET_REJ, // Set Spike Rejection + CMND_AS3935_SET_WDTH, // Watchdog threshold + CMND_AS3935_DISTTIME, // Threshhold Time for Auto Disturber + CMND_AS3935_NFTIME, // Threshhold Time for NF-Autotune + CMND_AS3935_SET_DISTURBER, // Set Disturber on/off + CMND_AS3935_NF_AUTOTUNE, // Autotune the NF Noise + CMND_AS3935_DIST_AUTOTUNE, // Autotune Disturber on/off + CMND_AS3935_NF_ATUNE_BOTH, // Autotune over both Areas: INDOORS/OUDOORS + CMND_AS3935_MQTT_LIGHT_EVT, // mqtt only if lightning Irq + CMND_AS3935_SETTINGS, // Json output of all settings + CMND_AS3935_CALIBRATE // caps autocalibrate + }; + +struct AS3935STRUCT +{ + bool autodist_activ = false; + volatile bool detected = false; + volatile bool dispLCO = 0; + uint8_t icount = 0; + uint8_t irq = 0; + uint8_t mqtt_irq = 0; + uint8_t http_irq = 0; + uint8_t http_count_start = 0; + int16_t http_distance = 0; + int16_t distance = 0; + uint16_t http_timer = 0; + uint16_t http_count = 0; + uint16_t nftimer = 0; + uint16_t disttimer = 0; + uint32_t intensity = 0; + uint32_t http_intensity = 0; + volatile uint32_t pulse = 0; +} as3935_sensor; + +uint8_t as3935_active = 0; + +void ICACHE_RAM_ATTR AS3935Isr() { + as3935_sensor.detected = true; +} + +uint8_t AS3935ReadRegister(uint8_t reg, uint8_t mask, uint8_t shift) { + uint8_t data = I2cRead8(AS3935_ADDR, reg); + if (reg == 0x08) Settings.as3935_sensor_cfg[4] = data; + if (reg < 0x04) Settings.as3935_sensor_cfg[reg] = data; + return ((data & mask) >> shift); +} + +void AS3935WriteRegister(uint8_t reg, uint8_t mask, uint8_t shift, uint8_t data) { + uint8_t currentReg = I2cRead8(AS3935_ADDR, reg); + currentReg &= (~mask); + data <<= shift; + data &= mask; + data |= currentReg; + I2cWrite8(AS3935_ADDR, reg, data); + if (reg == 0x08) Settings.as3935_sensor_cfg[4] = I2cRead8(AS3935_ADDR, reg); + if (reg < 0x04) Settings.as3935_sensor_cfg[reg] = I2cRead8(AS3935_ADDR, reg); +} + +/********************************************************************************************/ +// Autotune Caps +void ICACHE_RAM_ATTR AS3935CountFreq() { + if (as3935_sensor.dispLCO) + as3935_sensor.pulse++; +} + +bool AS3935AutoTuneCaps(uint8_t irqpin) { + int32_t maxtune = 17500; // there max 3.5 % tol + uint8_t besttune; + AS3935WriteRegister(LCO_FDIV, 0); // Fdiv 16 + delay(2); + for (uint8_t tune = 0; tune < 16; tune++) { + AS3935WriteRegister(TUNE_CAPS, tune); + delay(2); + AS3935WriteRegister(DISP_LCO,1); + delay(1); + as3935_sensor.dispLCO = true; + as3935_sensor.pulse = 0; + attachInterrupt(digitalPinToInterrupt(irqpin), AS3935CountFreq, RISING); + delay(200); // 100ms callback not work accurat for fequ. measure + as3935_sensor.dispLCO = false; + detachInterrupt(irqpin); + AS3935WriteRegister(DISP_LCO,0); + int32_t currentfreq = 500000 - ((as3935_sensor.pulse * 5) * 16); + if(currentfreq < 0) currentfreq = -currentfreq; + if(maxtune > currentfreq) { + maxtune = currentfreq; + besttune = tune; + } + } + if (maxtune >= 17500) // max. 3.5% + return false; + AS3935SetTuneCaps(besttune); + return true; +} + +/********************************************************************************************/ +// functions +void AS3935CalibrateRCO() { + I2cWrite8(AS3935_ADDR, 0x3D, 0x96); + AS3935WriteRegister(DISP_TRCO, 1); + delay(2); + AS3935WriteRegister(DISP_TRCO, 0); +} + +uint8_t AS3935TransMinLights(uint8_t min_lights) { + if (5 > min_lights) { + return 0; + } else if (9 > min_lights) { + return 1; + } else if (16 > min_lights) { + return 2; + } else { + return 3; + } +} + +uint8_t AS3935TranslMinLightsInt(uint8_t min_lights) { + switch (min_lights) { + case 0: return 1; + case 1: return 5; + case 2: return 9; + case 3: return 16; + } +} + +uint8_t AS3935TranslIrq(uint8_t irq, uint8_t distance) { + switch(irq) { + case 0: return 7; // Interrupt with no IRQ + case 1: return 5; // Noise level too high + case 4: return 6; // Disturber detected + case 8: + if (distance == -1) return 2; // Lightning out of Distance + else if (distance == 0) return 3; // Distance cannot be determined + else if (distance == 1) return 4; // Storm is Overhead + else return 1; // Lightning with Distance detected + } +} + +void AS3935CalcVrmsLevel(uint16_t &vrms, uint8_t &stage) +{ + uint8_t room = AS3935GetGain(); + uint8_t nflev = AS3935GetNoiseFloor(); + if (room == 0x24) + { + switch (nflev){ + case 0x00: + vrms = 28; + break; + case 0x01: + vrms = 45; + break; + case 0x02: + vrms = 62; + break; + case 0x03: + vrms = 78; + break; + case 0x04: + vrms = 95; + break; + case 0x05: + vrms = 112; + break; + case 0x06: + vrms = 130; + break; + case 0x07: + vrms = 146; + break; + } + stage = nflev; + } + else + { + switch (nflev) + { + case 0x00: + vrms = 390; + break; + case 0x01: + vrms = 630; + break; + case 0x02: + vrms = 860; + break; + case 0x03: + vrms = 1100; + break; + case 0x04: + vrms = 1140; + break; + case 0x05: + vrms = 1570; + break; + case 0x06: + vrms = 1800; + break; + case 0x07: + vrms = 2000; + break; + } + stage = nflev + 8; + } +} + +/********************************************************************************************/ +uint8_t AS3935GetIRQ() { + delay(2); + return AS3935ReadRegister(IRQ_TBL); +} + +uint8_t AS3935GetDistance() { + return AS3935ReadRegister(LGHT_DIST); +} + +int16_t AS3935CalcDistance() { + uint8_t dist = AS3935GetDistance(); + switch (dist) { + case 0x3F: return -1; // Out of Range + case 0x01: return 1; // Storm is Overhead + case 0x00: return 0; // Distance cannot be determined + default: + if (40 < dist){ + return 40;// limited because higher is not accurate + } + return dist; + } +} + +uint32_t AS3935GetIntensity() { + uint32_t nrgy_raw = (AS3935ReadRegister(ENERGY_RAW_3) << 8); + nrgy_raw |= AS3935ReadRegister(ENERGY_RAW_2); + nrgy_raw <<= 8; + nrgy_raw |= AS3935ReadRegister(ENERGY_RAW_1); + return nrgy_raw; +} + +uint8_t AS3935GetTuneCaps() { + return AS3935ReadRegister(TUNE_CAPS); +} + +void AS3935SetTuneCaps(uint8_t tune) { + AS3935WriteRegister(TUNE_CAPS, tune); + delay(2); + AS3935CalibrateRCO(); +} + +uint8_t AS3935GetDisturber() { + return AS3935ReadRegister(DISTURBER); +} + +uint8_t AS3935SetDisturber(uint8_t stat) { + AS3935WriteRegister(DISTURBER, stat); +} + +uint8_t AS3935GetMinLights() { + return AS3935ReadRegister(MIN_NUM_LIGH); +} + +uint8_t AS3935SetMinLights(uint8_t stat) { + AS3935WriteRegister(MIN_NUM_LIGH, stat); +} + +uint8_t AS3935GetNoiseFloor() { + return AS3935ReadRegister(NF_LEVEL); +} + +uint8_t AS3935SetNoiseFloor(uint8_t noise) { + AS3935WriteRegister(NF_LEVEL , noise); +} + +uint8_t AS3935GetGain() { + if (AS3935ReadRegister(AFE_GB) == OUTDOORS) + return OUTDOORS; + return INDOORS; +} + +uint8_t AS3935SetGain(uint8_t room) { + AS3935WriteRegister(AFE_GB, room); +} + +uint8_t AS3935GetGainInt() { + if (AS3935ReadRegister(AFE_GB) == OUTDOORS) + return 1; +return 0; +} + +uint8_t AS3935GetSpikeRejection() { + return AS3935ReadRegister(SPIKE_REJECT); +} + +void AS3935SetSpikeRejection(uint8_t rej) { + AS3935WriteRegister(SPIKE_REJECT, rej); +} + +uint8_t AS3935GetWdth() { + return AS3935ReadRegister(WDTH); +} + +void AS3935SetWdth(uint8_t wdth) { + AS3935WriteRegister(WDTH, wdth); +} + +bool AS3935AutoTune(){ + detachInterrupt(Pin(GPIO_AS3935)); + bool result = AS3935AutoTuneCaps(Pin(GPIO_AS3935)); + attachInterrupt(digitalPinToInterrupt(Pin(GPIO_AS3935)), AS3935Isr, RISING); + return result; +} + +/********************************************************************************************/ +// Noise Floor autofunctions +bool AS3935LowerNoiseFloor() { + uint8_t noise = AS3935GetNoiseFloor(); + uint16_t vrms; + uint8_t stage; + AS3935CalcVrmsLevel(vrms, stage); + if (Settings.as3935_functions.nf_autotune_both) { + if (stage == 8 && stage > Settings.as3935_parameter.nf_autotune_min) { + AS3935SetGain(INDOORS); + AS3935SetNoiseFloor(7); + return true; + } + } + if (0 < noise && stage > Settings.as3935_parameter.nf_autotune_min) { + noise--; + AS3935SetNoiseFloor(noise); + return true; + } + return false; +} + +bool AS3935RaiseNoiseFloor() { + uint8_t noise = AS3935GetNoiseFloor(); + uint8_t room = AS3935GetGain(); + if (Settings.as3935_functions.nf_autotune_both) { + if (7 == noise && room == INDOORS) { + AS3935SetGain(OUTDOORS); + AS3935SetNoiseFloor(0); + return true; + } + } + if (7 > noise) { + noise++; + AS3935SetNoiseFloor(noise); + return true; + } + return false; +} + +/********************************************************************************************/ +// init functions +bool AS3935SetDefault() { + I2cWrite8(AS3935_ADDR, 0x3C, 0x96); // Set default + delay(2); + Settings.as3935_sensor_cfg[0] = I2cRead8(AS3935_ADDR, 0x00); + Settings.as3935_sensor_cfg[1] = I2cRead8(AS3935_ADDR, 0x01); + Settings.as3935_sensor_cfg[2] = I2cRead8(AS3935_ADDR, 0x02); + Settings.as3935_sensor_cfg[3] = I2cRead8(AS3935_ADDR, 0x03); + Settings.as3935_sensor_cfg[4] = I2cRead8(AS3935_ADDR, 0x08); + Settings.as3935_parameter.nf_autotune_min = 0x00; + Settings.as3935_parameter.nf_autotune_time = 4; + Settings.as3935_parameter.dist_autotune_time = 1; + return true; +} + +void AS3935InitSettings() { + if(Settings.as3935_functions.nf_autotune){ + if(Settings.as3935_parameter.nf_autotune_min) { + if (Settings.as3935_parameter.nf_autotune_min > 7) { + AS3935SetGain(OUTDOORS); + AS3935SetNoiseFloor(Settings.as3935_parameter.nf_autotune_min - 8); + } else { + AS3935SetGain(INDOORS); + AS3935SetNoiseFloor(Settings.as3935_parameter.nf_autotune_min); + } + } + } + I2cWrite8(AS3935_ADDR, 0x00, Settings.as3935_sensor_cfg[0]); + I2cWrite8(AS3935_ADDR, 0x01, Settings.as3935_sensor_cfg[1]); + I2cWrite8(AS3935_ADDR, 0x02, Settings.as3935_sensor_cfg[2]); + I2cWrite8(AS3935_ADDR, 0x03, Settings.as3935_sensor_cfg[3]); + I2cWrite8(AS3935_ADDR, 0x08, Settings.as3935_sensor_cfg[4]); + delay(2); +} + +void AS3935Setup(void) { + if (Settings.as3935_sensor_cfg[0] == 0x00) { + AS3935SetDefault(); + } else { + AS3935InitSettings(); + } + AS3935CalibrateRCO(); +} + +bool AS3935init() { + uint8_t ret = I2cRead8(AS3935_ADDR, 0x00); + if(INDOORS == ret || OUTDOORS == ret) // 0x24 + return true; + return false; +} + +void AS3935Detect(void) { + if (I2cActive(AS3935_ADDR)) return; + if (AS3935init()) + { + I2cSetActiveFound(AS3935_ADDR, D_NAME_AS3935); + pinMode(Pin(GPIO_AS3935), INPUT); + attachInterrupt(digitalPinToInterrupt(Pin(GPIO_AS3935)), AS3935Isr, RISING); + AS3935Setup(); + as3935_active = 1; + } +} + +void AS3935EverySecond() { + if (as3935_sensor.detected) { + as3935_sensor.irq = AS3935GetIRQ(); // 1 =Noise, 4 = Disturber, 8 = storm + switch (as3935_sensor.irq) { + case 1: + if (Settings.as3935_functions.nf_autotune) { + if (AS3935RaiseNoiseFloor()) as3935_sensor.nftimer = 0; + } + break; + case 4: + if (Settings.as3935_functions.dist_autotune) { + AS3935SetDisturber(1); + as3935_sensor.autodist_activ = true; + } + break; + case 8: + as3935_sensor.intensity = AS3935GetIntensity(); + as3935_sensor.distance = AS3935CalcDistance(); + as3935_sensor.http_intensity = as3935_sensor.intensity; + as3935_sensor.http_distance = as3935_sensor.distance; + break; + } + // http show + as3935_sensor.http_irq = AS3935TranslIrq(as3935_sensor.irq, as3935_sensor.distance); + // mqtt publish + as3935_sensor.mqtt_irq = as3935_sensor.http_irq; + switch (as3935_sensor.mqtt_irq) { + case 5: + case 6: + if (!Settings.as3935_functions.mqtt_only_Light_Event) { + MqttPublishSensor(); + as3935_sensor.http_timer = 10; + } + break; + default: + as3935_sensor.http_timer = 60; + MqttPublishSensor(); + } + // clear mqtt events for Teleperiod + as3935_sensor.intensity = 0; + as3935_sensor.distance = 0; + as3935_sensor.mqtt_irq = 0; + // start http times + as3935_sensor.http_count_start = 1; + as3935_sensor.http_count = 0; + as3935_sensor.icount++; // Int counter + as3935_sensor.detected = false; + } + + if (as3935_sensor.http_count_start) as3935_sensor.http_count++; + // clear Http + if (as3935_sensor.http_count > as3935_sensor.http_timer) { + as3935_sensor.http_count_start = 0; + as3935_sensor.http_intensity = 0; + as3935_sensor.http_distance = 0; + as3935_sensor.http_irq = 0; + } + // Noise Floor Autotune function + if (Settings.as3935_functions.nf_autotune) { + as3935_sensor.nftimer++; + if (as3935_sensor.nftimer > Settings.as3935_parameter.nf_autotune_time * 60) { + AS3935LowerNoiseFloor(); + as3935_sensor.nftimer = 0; + } + } + // Disturber auto function + if (Settings.as3935_functions.dist_autotune) { + if (as3935_sensor.autodist_activ) as3935_sensor.disttimer++; + if (as3935_sensor.disttimer >= Settings.as3935_parameter.dist_autotune_time * 60) { + AS3935SetDisturber(0); + as3935_sensor.disttimer = 0; + as3935_sensor.autodist_activ = false; + } + } +} + +bool AS3935Cmd(void) { + char command[CMDSZ]; + uint8_t name_len = strlen(D_NAME_AS3935); + if (!strncasecmp_P(XdrvMailbox.topic, PSTR(D_NAME_AS3935), name_len)) { + uint32_t command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic + name_len, kAS3935_Commands); + switch (command_code) { + case CMND_AS3935_SET_NF: + if (XdrvMailbox.data_len) { + if (15 >= XdrvMailbox.payload) { + AS3935SetNoiseFloor(XdrvMailbox.payload); + } + } + Response_P(S_JSON_AS3935_COMMAND_NVALUE, command, AS3935GetNoiseFloor()); + break; + case CMND_AS3935_SET_MINNF: + if (XdrvMailbox.data_len) { + if (15 >= XdrvMailbox.payload) { + Settings.as3935_parameter.nf_autotune_min = XdrvMailbox.payload; + } + } + Response_P(S_JSON_AS3935_COMMAND_NVALUE, command, Settings.as3935_parameter.nf_autotune_min); + break; + case CMND_AS3935_SET_MINLIGHT: + if (XdrvMailbox.data_len) { + AS3935SetMinLights(AS3935TransMinLights(XdrvMailbox.payload)); + } + Response_P(S_JSON_AS3935_COMMAND_NVALUE, command, AS3935TranslMinLightsInt(AS3935GetMinLights())); + break; + case CMND_AS3935_SET_DEF: + if (!XdrvMailbox.data_len) { + Response_P(S_JSON_AS3935_COMMAND_NVALUE, command, AS3935SetDefault()); + } + break; + case CMND_AS3935_SET_GAIN: + if (XdrvMailbox.data_len > 6) { + uint8_t data_len = strlen(D_AS3935_OUTDOORS); + if (!strncasecmp_P(XdrvMailbox.data, PSTR(D_AS3935_OUTDOORS), data_len)) { + AS3935SetGain(OUTDOORS); + } else { + AS3935SetGain(INDOORS); + } + } + Response_P(S_JSON_AS3935_COMMAND_STRING, command, S_JSON_AS3935_COMMAND_GAIN[AS3935GetGainInt()]); + break; + case CMND_AS3935_SET_TUNE: + if (XdrvMailbox.data_len) { + if (15 >= XdrvMailbox.payload) { + AS3935SetTuneCaps(XdrvMailbox.payload); + } + } + Response_P(S_JSON_AS3935_COMMAND_NVALUE, command, AS3935GetTuneCaps()); + break; + case CMND_AS3935_SET_REJ: + if (XdrvMailbox.data_len) { + if (15 >= XdrvMailbox.payload) { + AS3935SetSpikeRejection(XdrvMailbox.payload); + } + } + Response_P(S_JSON_AS3935_COMMAND_NVALUE, command, AS3935GetSpikeRejection()); + break; + case CMND_AS3935_SET_WDTH: + if (XdrvMailbox.data_len) { + if (15 >= XdrvMailbox.payload) { + AS3935SetWdth(XdrvMailbox.payload); + } + } + Response_P(S_JSON_AS3935_COMMAND_NVALUE, command, AS3935GetWdth()); + break; + case CMND_AS3935_DISTTIME: + if (XdrvMailbox.data_len) { + if (15 >= XdrvMailbox.payload) { + Settings.as3935_parameter.dist_autotune_time = XdrvMailbox.payload; + } + } + Response_P(S_JSON_AS3935_COMMAND_NVALUE, command, Settings.as3935_parameter.dist_autotune_time); + break; + case CMND_AS3935_NFTIME: + if (XdrvMailbox.data_len) { + if (15 >= XdrvMailbox.payload) { + Settings.as3935_parameter.nf_autotune_time = XdrvMailbox.payload; + } + } + Response_P(S_JSON_AS3935_COMMAND_NVALUE, command, Settings.as3935_parameter.nf_autotune_time); + break; + case CMND_AS3935_SET_DISTURBER: + if (XdrvMailbox.data_len) { + if (2 > XdrvMailbox.payload) { + AS3935SetDisturber(XdrvMailbox.payload); + if (!XdrvMailbox.payload) Settings.as3935_functions.dist_autotune = 0; + } + } + Response_P(S_JSON_AS3935_COMMAND_STRING, command, S_JSON_AS3935_COMMAND_ONOFF[AS3935GetDisturber()]); + break; + case CMND_AS3935_NF_AUTOTUNE: + if (XdrvMailbox.data_len) { + if (2 > XdrvMailbox.payload) { + Settings.as3935_functions.nf_autotune = XdrvMailbox.payload; + } + } + Response_P(S_JSON_AS3935_COMMAND_STRING, command, S_JSON_AS3935_COMMAND_ONOFF[Settings.as3935_functions.nf_autotune]); + break; + case CMND_AS3935_DIST_AUTOTUNE: + if (XdrvMailbox.data_len) { + if (2 > XdrvMailbox.payload) { + Settings.as3935_functions.dist_autotune = XdrvMailbox.payload; + } + } + Response_P(S_JSON_AS3935_COMMAND_STRING, command, S_JSON_AS3935_COMMAND_ONOFF[Settings.as3935_functions.dist_autotune]); + break; + case CMND_AS3935_NF_ATUNE_BOTH: + if (XdrvMailbox.data_len) { + if (2 > XdrvMailbox.payload) { + Settings.as3935_functions.nf_autotune_both = XdrvMailbox.payload; + } + } + Response_P(S_JSON_AS3935_COMMAND_STRING, command, S_JSON_AS3935_COMMAND_ONOFF[Settings.as3935_functions.nf_autotune_both]); + break; + case CMND_AS3935_MQTT_LIGHT_EVT: + if (XdrvMailbox.data_len) { + if (2 > XdrvMailbox.payload) { + Settings.as3935_functions.mqtt_only_Light_Event = XdrvMailbox.payload; + } + } + Response_P(S_JSON_AS3935_COMMAND_STRING, command, S_JSON_AS3935_COMMAND_ONOFF[Settings.as3935_functions.mqtt_only_Light_Event]); + break; + case CMND_AS3935_SETTINGS: { + if (!XdrvMailbox.data_len) { + uint8_t gain = AS3935GetGainInt(); + uint16_t vrms; + uint8_t stage; + AS3935CalcVrmsLevel(vrms, stage); + uint8_t nf_floor = AS3935GetNoiseFloor(); + uint8_t min_nf = Settings.as3935_parameter.nf_autotune_min; + uint8_t tunecaps = AS3935GetTuneCaps(); + uint8_t minnumlight = AS3935TranslMinLightsInt(AS3935GetMinLights()); + uint8_t disturber = AS3935GetDisturber(); + uint8_t reinj = AS3935GetSpikeRejection(); + uint8_t wdth = AS3935GetWdth(); + uint8_t nfauto = Settings.as3935_functions.nf_autotune; + uint8_t distauto = Settings.as3935_functions.dist_autotune; + uint8_t nfautomax = Settings.as3935_functions.nf_autotune_both; + uint8_t jsonlight = Settings.as3935_functions.mqtt_only_Light_Event; + uint8_t nf_time = Settings.as3935_parameter.nf_autotune_time; + uint8_t dist_time =Settings.as3935_parameter.dist_autotune_time; + Response_P(S_JSON_AS3935_COMMAND_SETTINGS, S_JSON_AS3935_COMMAND_GAIN[gain], nf_floor, vrms, tunecaps, minnumlight, reinj, wdth, min_nf, nf_time, dist_time, S_JSON_AS3935_COMMAND_ONOFF[disturber], S_JSON_AS3935_COMMAND_ONOFF[nfauto], S_JSON_AS3935_COMMAND_ONOFF[distauto], S_JSON_AS3935_COMMAND_ONOFF[nfautomax], S_JSON_AS3935_COMMAND_ONOFF[jsonlight]); + } + } + break; + case CMND_AS3935_CALIBRATE: { + bool calreslt; + if (!XdrvMailbox.data_len) calreslt = AS3935AutoTune(); + Response_P(S_JSON_AS3935_COMMAND_NVALUE, S_JSON_AS3935_COMMAND_CAL[calreslt], AS3935GetTuneCaps()); + } + break; + default: + return false; + } + return true; + } else { + return false; + } +} + +void AH3935Show(bool json) +{ + if (json) { + uint16_t vrms; + uint8_t stage; + AS3935CalcVrmsLevel(vrms, stage); + ResponseAppend_P(JSON_SNS_AS3935_EVENTS, D_SENSOR_AS3935, as3935_sensor.mqtt_irq, as3935_sensor.distance, as3935_sensor.intensity, stage); +#ifdef USE_WEBSERVER + } else { + uint8_t gain = AS3935GetGainInt(); + uint8_t disturber = AS3935GetDisturber(); + uint16_t vrms; + uint8_t stage; + AS3935CalcVrmsLevel(vrms, stage); + + WSContentSend_PD(HTTP_SNS_AS3935_TABLE_1[as3935_sensor.http_irq], D_NAME_AS3935, as3935_sensor.http_distance); + WSContentSend_PD(HTTP_SNS_AS3935_DISTANZ, as3935_sensor.http_distance); + WSContentSend_PD(HTTP_SNS_AS3935_ENERGY, as3935_sensor.http_intensity); + WSContentSend_PD(HTTP_SNS_AS3935_GAIN[gain], D_NAME_AS3935); + WSContentSend_PD(HTTP_SNS_AS3935_DISTURBER[disturber], D_NAME_AS3935); + WSContentSend_PD(HTTP_SNS_AS3935_VRMS, vrms, stage); +#endif // USE_WEBSERVER + } +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xsns67(uint8_t function) +{ + if (!I2cEnabled(XI2C_48)) { return false; } + + bool result = false; + + if (FUNC_INIT == function) { + AS3935Detect(); + } + else if (as3935_active) { + switch (function) { + case FUNC_EVERY_SECOND: + AS3935EverySecond(); + break; + case FUNC_COMMAND: + result = AS3935Cmd(); + break; + case FUNC_JSON_APPEND: + AH3935Show(1); + break; +#ifdef USE_WEBSERVER + case FUNC_WEB_SENSOR: + AH3935Show(0); + break; +#endif // USE_WEBSERVER + } + } + return result; +} + +#endif // USE_AS3935 +#endif // USE_I2C diff --git a/tasmota/xsns_68_windmeter.ino b/tasmota/xsns_68_windmeter.ino new file mode 100644 index 000000000..5487c898c --- /dev/null +++ b/tasmota/xsns_68_windmeter.ino @@ -0,0 +1,377 @@ +/* + xsns_68_windmeter.ino - Analog wind sensor support for Tasmota + + Copyright (C) 2020 Matteo Albinola + (inspired by great works of Thomas Eckerstorfer, Norbert Richter, Maarten Damen and Theo Arends) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifdef USE_WINDMETER +/*********************************************************************************************\ + * WindMeter sensor (speed) +\*********************************************************************************************/ + +#define XSNS_68 68 + +#define D_WINDMETER_NAME "WindMeter" + +#define WINDMETER_DEF_RADIUS 61 // Radius in millimeters (calculated by measuring the distance from the centre to the edge of one of the cups) +#define WINDMETER_DEF_PULSES_X_ROT 1 // Number of pulses for a complete rotation +#define WINDMETER_DEF_PULSE_DEBOUNCE 10 // Pulse counter debounce time (milliseconds) +#define WINDMETER_DEF_COMP_FACTOR 1.18 // Compensation factor +#define WINDMETER_DEF_TELE_PCHANGE 255 // Minimum percentage change between current and last reported speed in order to trigger a new tele message (0...100, 255 means off) +#define WINDMETER_WEIGHT_AVG_SAMPLE 150 // No of samples to take + +#ifdef USE_WEBSERVER +#define D_WINDMETER_WIND_AVG "∅" +#define D_WINDMETER_WIND_ANGLE "∠" +#define D_WINDMETER_WIND_DEGREE "°" +const char HTTP_SNS_WINDMETER[] PROGMEM = + "{s}" D_WINDMETER_NAME " " D_TX20_WIND_SPEED "{m}%s %s{e}" +#ifndef USE_WINDMETER_NOSTATISTICS + "{s}" D_WINDMETER_NAME " " D_TX20_WIND_SPEED " " D_WINDMETER_WIND_AVG "{m}%s %s{e}" + "{s}" D_WINDMETER_NAME " " D_TX20_WIND_SPEED_MIN "{m}%s %s{e}" + "{s}" D_WINDMETER_NAME " " D_TX20_WIND_SPEED_MAX "{m}%s %s{e}" +#endif // USE_WINDMETER_NOSTATISTICS +// "{s}WindMeter " D_TX20_WIND_DIRECTION "{m}%s %s" D_WINDMETER_WIND_DEGREE "{e}" +//#ifndef USE_WINDMETER_NOSTATISTICS +// "{s}WindMeter " D_TX20_WIND_DIRECTION " " D_WINDMETER_WIND_AVG "{m}%s %s" D_WINDMETER_WIND_DEGREE "{e}" +// "{s}WindMeter " D_TX20_WIND_DIRECTION " " D_WINDMETER_WIND_ANGLE "{m}%s" D_WINDMETER_WIND_DEGREE " (%s,%s)" D_WINDMETER_WIND_DEGREE; +//#endif // USE_WINDMETER_NOSTATISTICS + ; +#endif // USE_WEBSERVER + +// float saves 48 byte +float const windmeter_pi = 3.1415926535897932384626433; // Pi +float const windmeter_2pi = windmeter_pi * 2; + +struct WINDMETER { + volatile uint32_t counter_time; + volatile unsigned long counter = 0; + //uint32_t speed_time; + float speed = 0; + float last_tele_speed = 0; +#ifndef USE_WINDMETER_NOSTATISTICS + float speed_min = 0; + float speed_max = 0; + float speed_avg = 0; + uint32_t samples_count = 0; + uint32_t avg_samples_no; +#endif // USE_WINDMETER_NOSTATISTICS +} WindMeter; + +#ifndef ARDUINO_ESP8266_RELEASE_2_3_0 // Fix core 2.5.x ISR not in IRAM Exception +void WindMeterUpdateSpeed(void) ICACHE_RAM_ATTR; +#endif // ARDUINO_ESP8266_RELEASE_2_3_0 + +void WindMeterUpdateSpeed(void) +{ + uint32_t time = micros(); + uint32_t time_diff = time - WindMeter.counter_time; + if (time_diff > Settings.windmeter_pulse_debounce * 1000) { + WindMeter.counter_time = time; + WindMeter.counter++; +// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("WMET: Counter %d"), WindMeter.counter); + } +} + +/********************************************************************************************/ + +void WindMeterInit(void) +{ + if (!Settings.flag2.speed_conversion) { + Settings.flag2.speed_conversion = 2; // 0 = none, 1 = m/s, 2 = km/h, 3 = kn, 4 = mph, 5 = ft/s, 6 = yd/s + } + if (!Settings.windmeter_radius) { + Settings.windmeter_radius = WINDMETER_DEF_RADIUS; + } + if (!Settings.windmeter_pulses_x_rot) { + Settings.windmeter_pulses_x_rot = WINDMETER_DEF_PULSES_X_ROT; + } + if (!Settings.windmeter_pulse_debounce) { + Settings.windmeter_pulse_debounce = WINDMETER_DEF_PULSE_DEBOUNCE; + } + if (!Settings.windmeter_speed_factor) { + Settings.windmeter_speed_factor = (int16_t)(WINDMETER_DEF_COMP_FACTOR * 1000); + } + if (!Settings.windmeter_tele_pchange) { + Settings.windmeter_tele_pchange = WINDMETER_DEF_TELE_PCHANGE; + } + +#ifndef USE_WINDMETER_NOSTATISTICS + WindMeterResetStatData(); + WindMeterCheckSampleCount(); +#endif // USE_WINDMETER_NOSTATISTICS + + pinMode(Pin(GPIO_WINDMETER_SPEED), INPUT_PULLUP); + attachInterrupt(Pin(GPIO_WINDMETER_SPEED), WindMeterUpdateSpeed, FALLING); +} + +void WindMeterEverySecond(void) +{ + //uint32_t time = micros(); + //uint32_t delta_time = time - WindMeter.speed_time; + //AddLog_P2(LOG_LEVEL_INFO, PSTR("delta_time: %d"), delta_time); + + // speed = ( (pulses / pulses_per_rotation) * (2 * pi * radius) ) / delta_time + WindMeter.speed = ((WindMeter.counter / Settings.windmeter_pulses_x_rot) * (windmeter_2pi * ((float)Settings.windmeter_radius / 1000))) * ((float)Settings.windmeter_speed_factor / 1000); + //WindMeter.speed = (((WindMeter.counter / Settings.windmeter_pulses_x_rot) * (windmeter_2pi * ((float)Settings.windmeter_radius / 1000))) / ((float)delta_time / 1000000)) * ((float)Settings.windmeter_speed_factor / 1000); + WindMeter.counter = 0; + //WindMeter.speed_time = time; + + //char speed_string[FLOATSZ]; + //dtostrfd(WindMeter.speed, 2, speed_string); + //char uspeed_string[FLOATSZ]; + //dtostrfd(ConvertSpeed(WindMeter.speed), 2, uspeed_string); + //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("WMET: Speed %s [m/s] - %s [unit]"), speed_string, uspeed_string); + +#ifndef USE_WINDMETER_NOSTATISTICS + if (WindMeter.speed < WindMeter.speed_min) { + WindMeter.speed_min = WindMeter.speed; + } + if (WindMeter.speed > WindMeter.speed_max) { + WindMeter.speed_max = WindMeter.speed; + } + + // exponentially weighted average is not quite as smooth as the arithmetic average + // but close enough to the moving average and does not require the regular reset + // of the divider with the associated jump in avg values after period is over + if (WindMeter.samples_count <= WindMeter.avg_samples_no) { + WindMeter.samples_count++; + } + WindMeter.speed_avg -= WindMeter.speed_avg / WindMeter.samples_count; + WindMeter.speed_avg += float(WindMeter.speed) / WindMeter.samples_count; + + WindMeterCheckSampleCount(); + if (0==Settings.tele_period) { + WindMeterResetStatData(); + } +#endif // USE_WINDMETER_NOSTATISTICS + + if (WindMeterShouldTriggerTele()) { + WindMeterTriggerTele(); + } +} + +bool WindMeterShouldTriggerTele() +{ + if (Settings.windmeter_tele_pchange > 100) { + return false; + } else if (WindMeter.last_tele_speed == 0) { + return WindMeter.speed > 0; + } else { + float perc_change = (WindMeter.speed / WindMeter.last_tele_speed) -1; + return (perc_change * ((perc_change < 0) ? -100 : 100)) >= Settings.windmeter_tele_pchange; + } +} + +void WindMeterResetStatData(void) +{ + WindMeter.speed_min = WindMeter.speed; + WindMeter.speed_max = WindMeter.speed; + //WindMeter.direction_min = WindMeter.direction; + //WindMeter.direction_max = WindMeter.direction; +} + +void WindMeterCheckSampleCount(void) +{ + uint32_t prev_avg_samples_no = WindMeter.avg_samples_no; + if (Settings.tele_period) { + // number for avg samples = teleperiod value if set + WindMeter.avg_samples_no = Settings.tele_period; + } else { + // otherwise use default number of samples for this driver + WindMeter.avg_samples_no = WINDMETER_WEIGHT_AVG_SAMPLE; + } + if (prev_avg_samples_no != WindMeter.avg_samples_no) { + WindMeter.speed_avg = WindMeter.speed; + WindMeter.samples_count = 0; + } +} + +void WindMeterShow(bool json) +{ + char speed_string[FLOATSZ]; + dtostrfd(ConvertSpeed(WindMeter.speed), 2, speed_string); +#ifndef USE_WINDMETER_NOSTATISTICS + char speed_min_string[FLOATSZ]; + dtostrfd(ConvertSpeed(WindMeter.speed_min), 2, speed_min_string); + char speed_max_string[FLOATSZ]; + dtostrfd(ConvertSpeed(WindMeter.speed_max), 2, speed_max_string); + char speed_avg_string[FLOATSZ]; + dtostrfd(ConvertSpeed(WindMeter.speed_avg), 2, speed_avg_string); + //char direction_avg_string[FLOATSZ]; + //dtostrfd(WindMeter.direction_avg, 1, direction_avg_string); + //char direction_avg_cardinal_string[4]; + //GetTextIndexed(direction_avg_cardinal_string, sizeof(direction_avg_cardinal_string), int((WindMeter.direction_avg/22.5f)+0.5f) % 16, kWindMeterDirections); + //char direction_range_string[FLOATSZ]; + //dtostrfd(Tx2xNormalize(WindMeter.direction_max-WindMeter.direction_min)*22.5, 1, direction_range_string); + //char direction_min_string[FLOATSZ]; + //dtostrfd(Tx2xNormalize(WindMeter.direction_min)*22.5, 1, direction_min_string); + //char direction_max_string[FLOATSZ]; + //dtostrfd(Tx2xNormalize(WindMeter.direction_max)*22.5, 1, direction_max_string); +#endif // USE_WINDMETER_NOSTATISTICS + + if (json) { + WindMeter.last_tele_speed = WindMeter.speed; +#ifndef USE_WINDMETER_NOSTATISTICS + //ResponseAppend_P(PSTR(",\"" D_WINDMETER_NAME "\":{\"" D_JSON_SPEED "\":{\"Act\":%s,\"Avg\":%s,\"Min\":%s,\"Max\":%s},\"Dir\":{\"Card\":\"%s\",\"Deg\":%s,\"Avg\":%s,\"AvgCard\":\"%s\",\"Min\":%s,\"Max\":%s,\"Range\":%s}}"), + ResponseAppend_P(PSTR(",\"" D_WINDMETER_NAME "\":{\"" D_JSON_SPEED "\":{\"Act\":%s,\"Avg\":%s,\"Min\":%s,\"Max\":%s}}"), + speed_string, + speed_avg_string, + speed_min_string, + speed_max_string + //direction_cardinal_string, + //direction_string, + //direction_avg_string, + //direction_avg_cardinal_string, + //direction_min_string, + //direction_max_string, + //direction_range_string + ); +#else // USE_WINDMETER_NOSTATISTICS + //ResponseAppend_P(PSTR(",\"" D_WINDMETER_NAME "\":{\"" D_JSON_SPEED "\":{\"Act\":%s},\"Dir\":{\"Card\":\"%s\",\"Deg\":%s}}"), + ResponseAppend_P(PSTR(",\"" D_WINDMETER_NAME "\":{\"" D_JSON_SPEED "\":{\"Act\":%s}}"), + speed_string + //wind_direction_cardinal_string, + //wind_direction_string + ); +#endif // USE_WINDMETER_NOSTATISTICS +#ifdef USE_WEBSERVER + } else { + WSContentSend_PD(HTTP_SNS_WINDMETER, + speed_string, + SpeedUnit().c_str(), +#ifndef USE_WINDMETER_NOSTATISTICS + speed_avg_string, + SpeedUnit().c_str(), + speed_min_string, + SpeedUnit().c_str(), + speed_max_string, + SpeedUnit().c_str(), +#endif // USE_WINDMETER_NOSTATISTICS + "n/a", //wind_direction_cardinal_string, + "n/a" //wind_direction_string +#ifndef USE_WINDMETER_NOSTATISTICS + ,"n/a", //,wind_direction_avg_cardinal_string, + "n/a", //wind_direction_avg_string, + "n/a", //wind_direction_range_string, + "n/a", //wind_direction_min_string, + "n/a" //wind_direction_max_string +#endif // USE_WINDMETER_NOSTATISTICS + ); +#endif // USE_WEBSERVER + } +} + +void WindMeterTriggerTele(void) +{ + mqtt_data[0] = '\0'; + if (MqttShowSensor()) { + MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR), Settings.flag.mqtt_sensor_retain); +#ifdef USE_RULES + RulesTeleperiod(); // Allow rule based HA messages +#endif // USE_RULES + } +} + +/*********************************************************************************************\ + * Commands +\*********************************************************************************************/ + +bool Xsns68Cmnd(void) +{ + bool serviced = true; + bool show_parms = true; + char sub_string[XdrvMailbox.data_len +1]; + switch (XdrvMailbox.payload) { + case 1: + if (strstr(XdrvMailbox.data, ",") != nullptr) { + Settings.windmeter_radius = (uint16_t)strtol(subStr(sub_string, XdrvMailbox.data, ",", 2), nullptr, 10); + } + break; + case 2: + if (strstr(XdrvMailbox.data, ",") != nullptr) { + Settings.windmeter_pulses_x_rot = (uint8_t)strtol(subStr(sub_string, XdrvMailbox.data, ",", 2), nullptr, 10); + } + break; + case 3: + if (strstr(XdrvMailbox.data, ",") != nullptr) { + Settings.windmeter_pulse_debounce = (uint16_t)strtol(subStr(sub_string, XdrvMailbox.data, ",", 2), nullptr, 10); + } + break; + case 4: + if (strstr(XdrvMailbox.data, ",") != nullptr) { + Settings.windmeter_speed_factor = (int16_t)(CharToFloat(subStr(sub_string, XdrvMailbox.data, ",", 2)) * 1000); + } + break; + case 5: + if (strstr(XdrvMailbox.data, ",") != nullptr) { + Settings.windmeter_tele_pchange = (uint8_t)strtol(subStr(sub_string, XdrvMailbox.data, ",", 2), nullptr, 10); + } + break; + } + + if (show_parms) { + char speed_factor_string[FLOATSZ]; + dtostrfd((float)Settings.windmeter_speed_factor / 1000, 3, speed_factor_string); + char tele_pchange_string[4] = "off"; + if (Settings.windmeter_tele_pchange <= 100) { + itoa(Settings.windmeter_tele_pchange, tele_pchange_string, 10); + } + Response_P(PSTR("{\"" D_WINDMETER_NAME "\":{\"Radius\":%d,\"PulsesPerRot\":%d,\"PulseDebounce\":%d,\"SpeedFactor\":%s,\"TeleTriggerMin%Change\":%s}}"), + Settings.windmeter_radius, Settings.windmeter_pulses_x_rot, Settings.windmeter_pulse_debounce, speed_factor_string, tele_pchange_string); + } + return serviced; +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xsns68(uint8_t function) +{ + bool result = false; + if (PinUsed(GPIO_WINDMETER_SPEED)) { + switch (function) { + case FUNC_INIT: + WindMeterInit(); + break; + case FUNC_EVERY_SECOND: + WindMeterEverySecond(); + break; +#ifndef USE_WINDMETER_NOSTATISTICS + case FUNC_AFTER_TELEPERIOD: + WindMeterResetStatData(); + break; +#endif // USE_WINDMETER_NOSTATISTICS + case FUNC_JSON_APPEND: + WindMeterShow(true); + break; +#ifdef USE_WEBSERVER + case FUNC_WEB_SENSOR: + WindMeterShow(false); + break; +#endif // USE_WEBSERVER + case FUNC_COMMAND_SENSOR: + if (XSNS_68 == XdrvMailbox.index) { + result = Xsns68Cmnd(); + } + } + } + return result; +} + +#endif // USE_WINDMETER diff --git a/tasmota/xsns_69_opentherm.ino b/tasmota/xsns_69_opentherm.ino new file mode 100644 index 000000000..39b7748fe --- /dev/null +++ b/tasmota/xsns_69_opentherm.ino @@ -0,0 +1,598 @@ +/* + xsns_69_opentherm.ino - OpenTherm protocol support for Tasmota + + Copyright (C) 2020 Yuriy Sannikov + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifdef USE_OPENTHERM + +#define XSNS_69 69 + +#include + +// Hot water and boiler parameter ranges +#define OT_HOT_WATER_MIN 23 +#define OT_HOT_WATER_MAX 55 +#define OT_BOILER_MIN 40 +#define OT_BOILER_MAX 85 + +#define OT_HOT_WATER_DEFAULT 36; +#define OT_BOILER_DEFAULT 85; + +// Seconds before OT will make an attempt to connect to the boiler after connection error +#define SNS_OT_DISCONNECT_COOLDOWN_SECONDS 10 + +// Count of the OpenThermSettingsFlags +#define OT_FLAGS_COUNT 6 +enum OpenThermSettingsFlags +{ + // If set, central heating on/off state follows diagnostic indication bit(6), however + // EnableCentralHeating flag has a priority over it + EnableCentralHeatingOnDiagnostics = 0x01, + // If set, DHW is on after restart. + EnableHotWater = 0x02, + // If set, keep CH always on after restart. If off, follows the EnableCentralHeatingOnDiagnostics rule + EnableCentralHeating = 0x04, + EnableCooling = 0x08, + EnableTemperatureCompensation = 0x10, + EnableCentralHeating2 = 0x20, +}; + +enum OpenThermConnectionStatus +{ + OTC_NONE, // OT not initialized + OTC_DISCONNECTED, // OT communication timed out + OTC_CONNECTING, // Connecting after start or from DISCONNECTED state + OTC_HANDSHAKE, // Wait for the handshake response + OTC_READY, // Last Known Good response state is SUCCESS and no requests are in flight + OTC_INFLIGHT // Request sent, waiting from the response +}; + +OpenThermConnectionStatus sns_ot_connection_status = OpenThermConnectionStatus::OTC_NONE; +uint8_t sns_ot_disconnect_cooldown = 0; + +OpenTherm *sns_ot_master = NULL; + +// Has valid values if connection status is READY or INFLIGHT +typedef struct OT_BOILER_STATUS_T +{ + // Boiler fault code + uint8_t m_fault_code; + // Boiler OEM fault code + uint8_t m_oem_fault_code; + // Boilder OEM Diagnostics code + uint16_t m_oem_diag_code; + // OpenTherm ID(3) response. + uint8_t m_slave_flags; + // OpenTherm ID(1) codes. Should be used to display state + unsigned long m_slave_raw_status; + // Desired boiler states + bool m_enableCentralHeating; + bool m_enableHotWater; + bool m_enableCooling; + bool m_enableOutsideTemperatureCompensation; + bool m_enableCentralHeating2; + + // Some boilers has an input for the heat request. When short, heat is requested + // OT ID(0) bit 6 may indicate state of the Heat Request input + // By enabling this bit we will set m_enableCentralHeating to true when OT ID(0) bit 6 is set. + // This enables to use external mechanical thermostat to enable heating. + // Some of the use cases might be setting an emergency temperature to prevent freezing + // in case of the software thermostat failure. + bool m_useDiagnosticIndicationAsHeatRequest; + + // Hot Water temperature + float m_hotWaterSetpoint_read; + // Flame Modulation + float m_flame_modulation_read; + // Boiler Temperature + float m_boiler_temperature_read; + + // Boiler desired values + float m_boilerSetpoint; + float m_hotWaterSetpoint; + +} OT_BOILER_STATUS; + +OT_BOILER_STATUS sns_ot_boiler_status; + +const char *sns_opentherm_connection_stat_to_str(int status) +{ + switch (status) + { + case OpenThermConnectionStatus::OTC_NONE: + return "NONE"; + case OpenThermConnectionStatus::OTC_DISCONNECTED: + return "FAULT"; + case OpenThermConnectionStatus::OTC_CONNECTING: + return "CONNECTING"; + case OpenThermConnectionStatus::OTC_HANDSHAKE: + return "HANDSHAKE"; + case OpenThermConnectionStatus::OTC_READY: + return "READY"; + case OpenThermConnectionStatus::OTC_INFLIGHT: + return "BUSY"; + default: + return "UNKNOWN"; + } +} + +void sns_opentherm_init_boiler_status() +{ + memset(&sns_ot_boiler_status, 0, sizeof(OT_BOILER_STATUS)); + + // Settings + sns_ot_boiler_status.m_useDiagnosticIndicationAsHeatRequest = Settings.ot_flags & (uint8_t)OpenThermSettingsFlags::EnableCentralHeatingOnDiagnostics; + sns_ot_boiler_status.m_enableHotWater = Settings.ot_flags & (uint8_t)OpenThermSettingsFlags::EnableHotWater; + sns_ot_boiler_status.m_enableCentralHeating = Settings.ot_flags & (uint8_t)OpenThermSettingsFlags::EnableCentralHeating; + sns_ot_boiler_status.m_enableCooling = Settings.ot_flags & (uint8_t)OpenThermSettingsFlags::EnableCooling; + sns_ot_boiler_status.m_enableOutsideTemperatureCompensation = Settings.ot_flags & (uint8_t)OpenThermSettingsFlags::EnableTemperatureCompensation; + sns_ot_boiler_status.m_enableCentralHeating2 = Settings.ot_flags & (uint8_t)OpenThermSettingsFlags::EnableCentralHeating2; + + sns_ot_boiler_status.m_boilerSetpoint = (float)Settings.ot_boiler_setpoint; + sns_ot_boiler_status.m_hotWaterSetpoint = (float)Settings.ot_hot_water_setpoint; + + sns_ot_boiler_status.m_fault_code = 0; + sns_ot_boiler_status.m_oem_fault_code = 0; + sns_ot_boiler_status.m_oem_diag_code = 0; + sns_ot_boiler_status.m_hotWaterSetpoint_read = 0; + sns_ot_boiler_status.m_flame_modulation_read = 0; + sns_ot_boiler_status.m_boiler_temperature_read = 0; +} + +void ICACHE_RAM_ATTR sns_opentherm_handleInterrupt() +{ + sns_ot_master->handleInterrupt(); +} + +void sns_opentherm_processResponseCallback(unsigned long response, int st) +{ + OpenThermResponseStatus status = (OpenThermResponseStatus)st; + AddLog_P2(LOG_LEVEL_DEBUG_MORE, + PSTR("[OTH]: Processing response. Status=%s, Response=0x%lX"), + sns_ot_master->statusToString(status), response); + + if (sns_ot_connection_status == OpenThermConnectionStatus::OTC_HANDSHAKE) + { + return sns_ot_process_handshake(response, st); + } + + switch (status) + { + case OpenThermResponseStatus::SUCCESS: + if (sns_ot_master->isValidResponse(response)) + { + sns_opentherm_process_success_response(&sns_ot_boiler_status, response); + } + sns_ot_connection_status = OpenThermConnectionStatus::OTC_READY; + break; + + case OpenThermResponseStatus::INVALID: + sns_opentherm_check_retry_request(); + sns_ot_connection_status = OpenThermConnectionStatus::OTC_READY; + break; + + // Timeout may indicate not valid/supported command or connection error + // In this case we do reconnect. + // If this command will timeout multiple times, it will be excluded from the rotation later on + // after couple of failed attempts. See sns_opentherm_check_retry_request logic + case OpenThermResponseStatus::TIMEOUT: + sns_opentherm_check_retry_request(); + sns_ot_connection_status = OpenThermConnectionStatus::OTC_DISCONNECTED; + break; + } +} + +bool sns_opentherm_Init() +{ + if (PinUsed(GPIO_BOILER_OT_RX) && PinUsed(GPIO_BOILER_OT_TX)) + { + sns_ot_master = new OpenTherm(Pin(GPIO_BOILER_OT_RX), Pin(GPIO_BOILER_OT_TX)); + sns_ot_master->begin(sns_opentherm_handleInterrupt, sns_opentherm_processResponseCallback); + sns_ot_connection_status = OpenThermConnectionStatus::OTC_CONNECTING; + + sns_opentherm_init_boiler_status(); + return true; + } + return false; + // !warning, sns_opentherm settings are not ready at this point +} + +void sns_opentherm_stat(bool json) +{ + if (!sns_ot_master) + { + return; + } + const char *statusStr = sns_opentherm_connection_stat_to_str(sns_ot_connection_status); + + if (json) + { + ResponseAppend_P(PSTR(",\"OPENTHERM\":{")); + ResponseAppend_P(PSTR("\"conn\":\"%s\","), statusStr); + ResponseAppend_P(PSTR("\"settings\":%d,"), Settings.ot_flags); + sns_opentherm_dump_telemetry(); + ResponseJsonEnd(); +#ifdef USE_WEBSERVER + } + else + { + WSContentSend_P(PSTR("{s}OpenTherm status{m}%s (0x%X){e}"), statusStr, (int)sns_ot_boiler_status.m_slave_flags); + if (sns_ot_connection_status < OpenThermConnectionStatus::OTC_READY) + { + return; + } + WSContentSend_P(PSTR("{s}Std/OEM Fault Codes{m}%d / %d{e}"), + (int)sns_ot_boiler_status.m_fault_code, + (int)sns_ot_boiler_status.m_oem_fault_code); + + WSContentSend_P(PSTR("{s}OEM Diagnostic Code{m}%d{e}"), + (int)sns_ot_boiler_status.m_oem_diag_code); + + WSContentSend_P(PSTR("{s}Hot Water Setpoint{m}%d{e}"), + (int)sns_ot_boiler_status.m_hotWaterSetpoint_read); + + WSContentSend_P(PSTR("{s}Flame Modulation{m}%d{e}"), + (int)sns_ot_boiler_status.m_flame_modulation_read); + + WSContentSend_P(PSTR("{s}Boiler Temp/Setpnt{m}%d / %d{e}"), + (int)sns_ot_boiler_status.m_boiler_temperature_read, + (int)sns_ot_boiler_status.m_boilerSetpoint); + + if (OpenTherm::isCentralHeatingActive(sns_ot_boiler_status.m_slave_raw_status)) + { + WSContentSend_P(PSTR("{s}Central Heating is ACTIVE{m}{e}")); + } + + if (sns_ot_boiler_status.m_enableHotWater) + { + WSContentSend_P(PSTR("{s}Hot Water is Enabled{m}{e}")); + } + + if (OpenTherm::isHotWaterActive(sns_ot_boiler_status.m_slave_raw_status)) + { + WSContentSend_P(PSTR("{s}Hot Water is ACTIVE{m}{e}")); + } + + if (OpenTherm::isFlameOn(sns_ot_boiler_status.m_slave_raw_status)) + { + WSContentSend_P(PSTR("{s}Flame is ACTIVE{m}{e}")); + } + + if (sns_ot_boiler_status.m_enableCooling) + { + WSContentSend_P(PSTR("{s}Cooling is Enabled{m}{e}")); + } + + if (OpenTherm::isCoolingActive(sns_ot_boiler_status.m_slave_raw_status)) + { + WSContentSend_P(PSTR("{s}Cooling is ACTIVE{m}{e}")); + } + + if (OpenTherm::isDiagnostic(sns_ot_boiler_status.m_slave_raw_status)) + { + WSContentSend_P(PSTR("{s}Diagnostic Indication{m}{e}")); + } + +#endif // USE_WEBSERVER + } +} + +void sns_ot_start_handshake() +{ + if (!sns_ot_master) + { + return; + } + + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("[OTH]: perform handshake")); + + sns_ot_master->sendRequestAync( + OpenTherm::buildRequest(OpenThermMessageType::READ_DATA, OpenThermMessageID::SConfigSMemberIDcode, 0)); + + sns_ot_connection_status = OpenThermConnectionStatus::OTC_HANDSHAKE; +} + +void sns_ot_process_handshake(unsigned long response, int st) +{ + OpenThermResponseStatus status = (OpenThermResponseStatus)st; + + if (status != OpenThermResponseStatus::SUCCESS || !sns_ot_master->isValidResponse(response)) + { + AddLog_P2(LOG_LEVEL_ERROR, + PSTR("[OTH]: getSlaveConfiguration failed. Status=%s"), + sns_ot_master->statusToString(status)); + sns_ot_connection_status = OpenThermConnectionStatus::OTC_DISCONNECTED; + return; + } + + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("[OTH]: getLastResponseStatus SUCCESS. Slave Cfg: %lX"), response); + + sns_ot_boiler_status.m_slave_flags = (response & 0xFF00) >> 8; + + sns_ot_connection_status = OpenThermConnectionStatus::OTC_READY; +} + +void sns_opentherm_CheckSettings(void) +{ + bool settingsValid = true; + + settingsValid &= Settings.ot_hot_water_setpoint >= OT_HOT_WATER_MIN; + settingsValid &= Settings.ot_hot_water_setpoint <= OT_HOT_WATER_MAX; + settingsValid &= Settings.ot_boiler_setpoint >= OT_BOILER_MIN; + settingsValid &= Settings.ot_boiler_setpoint <= OT_BOILER_MAX; + + if (!settingsValid) + { + Settings.ot_hot_water_setpoint = OT_HOT_WATER_DEFAULT; + Settings.ot_boiler_setpoint = OT_BOILER_DEFAULT; + Settings.ot_flags = + OpenThermSettingsFlags::EnableCentralHeatingOnDiagnostics | + OpenThermSettingsFlags::EnableHotWater; + } +} +/*********************************************************************************************\ + * Command Processing +\*********************************************************************************************/ +const char *sns_opentherm_flag_text(uint8_t mode) +{ + switch ((OpenThermSettingsFlags)mode) + { + case OpenThermSettingsFlags::EnableCentralHeatingOnDiagnostics: + return "CHOD"; + case OpenThermSettingsFlags::EnableHotWater: + return "DHW"; + case OpenThermSettingsFlags::EnableCentralHeating: + return "CH"; + case OpenThermSettingsFlags::EnableCooling: + return "COOL"; + case OpenThermSettingsFlags::EnableTemperatureCompensation: + return "OTC"; + case OpenThermSettingsFlags::EnableCentralHeating2: + return "CH2"; + default: + return "?"; + } +} + +uint8_t sns_opentherm_parse_flag(char *flag) +{ + if (!strncmp(flag, "CHOD", 4)) + { + return OpenThermSettingsFlags::EnableCentralHeatingOnDiagnostics; + } + else if (!strncmp(flag, "COOL", 4)) + { + return OpenThermSettingsFlags::EnableCooling; + } + else if (!strncmp(flag, "DHW", 3)) + { + return OpenThermSettingsFlags::EnableHotWater; + } + else if (!strncmp(flag, "OTC", 3)) + { + return OpenThermSettingsFlags::EnableTemperatureCompensation; + } + else if (!strncmp(flag, "CH2", 3)) + { + return OpenThermSettingsFlags::EnableCentralHeating2; + } + else if (!strncmp(flag, "CH", 2)) + { + return OpenThermSettingsFlags::EnableCentralHeating; + } + return 0; +} + +uint8_t sns_opentherm_read_flags(char *data, uint32_t len) +{ + uint8_t tokens = 1; + for (int i = 0; i < len; ++i) + { + if (data[i] == ',') + { + ++tokens; + } + } + uint8_t result = 0; + char sub_string[XdrvMailbox.data_len + 1]; + for (int i = 1; i <= tokens; ++i) + { + char *flag = subStr(sub_string, data, ",", i); + if (!flag) + { + break; + } + result |= sns_opentherm_parse_flag(flag); + } + return result; +} +#define D_PRFX_OTHERM "ot_" +// set the boiler temperature (CH). Sutable for the PID app. +// After restart will use the defaults from the settings +#define D_CMND_OTHERM_BOILER_SETPOINT "tboiler" +// set hot water (DHW) temperature. Do not write it in the flash memory. +// suitable for the temporary changes +#define D_CMND_OTHERM_DHW_SETPOINT "twater" +// This command will save CH and DHW setpoints into the settings. Those values will be used after system restart +// The reason to separate set and save is to reduce flash memory write count, especially if boiler temperature is controlled +// by the PID thermostat +#define D_CMND_OTHERM_SAVE_SETTINGS "save_setpoints" +// Get or set flags + +// EnableCentralHeatingOnDiagnostics -> CHOD +// EnableHotWater -> DHW +// EnableCentralHeating -> CH +// EnableCooling -> COOL +// EnableTemperatureCompensation -> OTC +// EnableCentralHeating2 -> CH2 +#define D_CMND_OTHERM_FLAGS "flags" + +// Get/Set boiler status m_enableCentralHeating value. It's equivalent of the EnableCentralHeating settings +// flag value, however, this command does not update the settings. +// Usefull to buld automations +// Please note, if you set it to "0" and EnableCentralHeatingOnDiagnostics is set +// boiler will follow the Diagnostics bit and won't turn CH off. When Diagnostics bit cleared, +// and "ot_ch" is "1", boiler will keep heating +#define D_CMND_SET_CENTRAL_HEATING_ENABLED "ch" + +const char kOpenThermCommands[] PROGMEM = D_PRFX_OTHERM "|" D_CMND_OTHERM_BOILER_SETPOINT "|" D_CMND_OTHERM_DHW_SETPOINT + "|" D_CMND_OTHERM_SAVE_SETTINGS "|" D_CMND_OTHERM_FLAGS "|" D_CMND_SET_CENTRAL_HEATING_ENABLED; + +void (*const OpenThermCommands[])(void) PROGMEM = { + &sns_opentherm_boiler_setpoint_cmd, + &sns_opentherm_hot_water_setpoint_cmd, + &sns_opentherm_save_settings_cmd, + &sns_opentherm_flags_cmd, + &sns_opentherm_set_central_heating_cmd}; + +void sns_opentherm_cmd(void) { } +void sns_opentherm_boiler_setpoint_cmd(void) +{ + bool query = strlen(XdrvMailbox.data) == 0; + if (!query) + { + sns_ot_boiler_status.m_boilerSetpoint = atof(XdrvMailbox.data); + } + ResponseCmndFloat(sns_ot_boiler_status.m_boilerSetpoint, Settings.flag2.temperature_resolution); +} + +void sns_opentherm_hot_water_setpoint_cmd(void) +{ + bool query = strlen(XdrvMailbox.data) == 0; + if (!query) + { + sns_ot_boiler_status.m_hotWaterSetpoint = atof(XdrvMailbox.data); + } + ResponseCmndFloat(sns_ot_boiler_status.m_hotWaterSetpoint, Settings.flag2.temperature_resolution); +} + +void sns_opentherm_save_settings_cmd(void) +{ + Settings.ot_hot_water_setpoint = (uint8_t)sns_ot_boiler_status.m_hotWaterSetpoint; + Settings.ot_boiler_setpoint = (uint8_t)sns_ot_boiler_status.m_boilerSetpoint; + ResponseCmndDone(); +} + +void sns_opentherm_flags_cmd(void) +{ + bool query = strlen(XdrvMailbox.data) == 0; + if (!query) + { + // Set flags value + Settings.ot_flags = sns_opentherm_read_flags(XdrvMailbox.data, XdrvMailbox.data_len); + // Reset boiler status to apply settings + sns_opentherm_init_boiler_status(); + } + bool addComma = false; + mqtt_data[0] = 0; + for (int pos = 0; pos < OT_FLAGS_COUNT; ++pos) + { + int mask = 1 << pos; + int mode = Settings.ot_flags & (uint8_t)mask; + if (mode > 0) + { + if (addComma) + { + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,"), mqtt_data); + } + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s"), mqtt_data, sns_opentherm_flag_text(mode)); + addComma = true; + } + } +} + +void sns_opentherm_set_central_heating_cmd(void) +{ + bool query = strlen(XdrvMailbox.data) == 0; + if (!query) + { + sns_ot_boiler_status.m_enableCentralHeating = atoi(XdrvMailbox.data); + } + ResponseCmndNumber(sns_ot_boiler_status.m_enableCentralHeating ? 1 : 0); +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xsns69(uint8_t function) +{ + bool result = false; + if (FUNC_INIT == function) + { + if (sns_opentherm_Init()) + { + sns_opentherm_CheckSettings(); + } + } + + if (!sns_ot_master) + { + return result; + } + + switch (function) + { + case FUNC_LOOP: + sns_ot_master->process(); + break; + case FUNC_EVERY_100_MSECOND: + if (sns_ot_connection_status == OpenThermConnectionStatus::OTC_READY && sns_ot_master->isReady()) + { + unsigned long request = sns_opentherm_get_next_request(&sns_ot_boiler_status); + if (-1 != request) + { + sns_ot_master->sendRequestAync(request); + sns_ot_connection_status = OpenThermConnectionStatus::OTC_INFLIGHT; + } + } + break; + case FUNC_EVERY_SECOND: + if (sns_ot_connection_status == OpenThermConnectionStatus::OTC_DISCONNECTED) + { + // If disconnected, wait for the SNS_OT_DISCONNECT_COOLDOWN_SECONDS before the handshake + if (sns_ot_disconnect_cooldown == 0) + { + sns_ot_disconnect_cooldown = SNS_OT_DISCONNECT_COOLDOWN_SECONDS; + } + else if (--sns_ot_disconnect_cooldown == 0) + { + sns_ot_connection_status = OpenThermConnectionStatus::OTC_CONNECTING; + } + } + else if (sns_ot_connection_status == OpenThermConnectionStatus::OTC_CONNECTING) + { + sns_ot_start_handshake(); + } + break; + case FUNC_COMMAND: + result = DecodeCommand(kOpenThermCommands, OpenThermCommands); + break; + case FUNC_JSON_APPEND: + sns_opentherm_stat(1); + break; +#ifdef USE_WEBSERVER + case FUNC_WEB_SENSOR: + sns_opentherm_stat(0); + break; +#endif // USE_WEBSERVER + } + + return result; +} + +#endif // USE_OPENTHERM diff --git a/tasmota/xsns_69_opentherm_protocol.ino b/tasmota/xsns_69_opentherm_protocol.ino new file mode 100644 index 000000000..1ebc5c14b --- /dev/null +++ b/tasmota/xsns_69_opentherm_protocol.ino @@ -0,0 +1,441 @@ +/* + xsns_69_opentherm_protocol.ino - OpenTherm protocol support for Tasmota + + Copyright (C) 2020 Yuriy Sannikov + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifdef USE_OPENTHERM + +#include "OpenTherm.h" + +// Temperature tolerance. If temperature setpoint difference is less than the value, +// OT (1)(Control setpoint) command will be skipped +#define OPENTHERM_BOILER_SETPOINT_TOLERANCE 1.0 + +typedef union { + uint8_t m_flags; + struct + { + uint8_t notSupported : 1; // If set, boiler does not support this command + uint8_t supported : 1; // Set if at least one response were successfull + uint8_t retryCount : 2; // Retry counter before notSupported flag being set + }; +} OpenThermParamFlags; + +typedef union { + float m_float; + uint8_t m_u8; + uint16_t m_u16; + unsigned long m_ul; + bool m_bool; +} ResponseStorage; + +typedef struct OpenThermCommandT +{ + const char *m_command_name; + uint8_t m_command_code; + OpenThermParamFlags m_flags; + ResponseStorage m_results[2]; + unsigned long (*m_ot_make_request)(OpenThermCommandT *self, OT_BOILER_STATUS_T *boilerStatus); + void (*m_ot_parse_response)(OpenThermCommandT *self, OT_BOILER_STATUS_T *boilerStatus, unsigned long response); + void (*m_ot_appent_telemetry)(OpenThermCommandT *self); +} OpenThermCommand; + +OpenThermCommand sns_opentherm_commands[] = { + {// Get/Set Slave Status Flags + .m_command_name = "SLAVE", + .m_command_code = 0, + // OpenTherm ID(0) should never go into the notSupported state due to some connectivity issues + // otherwice it may lose boiler control + .m_flags = {.supported = 1}, + .m_results = {{.m_u8 = 0}, {.m_u8 = 0}}, + .m_ot_make_request = sns_opentherm_set_slave_flags, + .m_ot_parse_response = sns_opentherm_parse_slave_flags, + .m_ot_appent_telemetry = sns_opentherm_tele_slave_flags}, + {// Set boiler temperature + .m_command_name = "BTMP", + .m_command_code = 0, + // OpenTherm ID(1) also should never go into the notSupported state due to some connectivity issues + .m_flags = {.supported = 1}, + .m_results = {{.m_u8 = 0}, {.m_u8 = 0}}, + .m_ot_make_request = sns_opentherm_set_boiler_temperature, + .m_ot_parse_response = sns_opentherm_parse_set_boiler_temperature, + .m_ot_appent_telemetry = sns_opentherm_tele_boiler_temperature}, + {// Set Hot Water temperature + .m_command_name = "HWTMP", + .m_command_code = 0, + // OpenTherm ID(56) may not be supported + .m_flags = 0, + .m_results = {{.m_u8 = 0}, {.m_u8 = 0}}, + .m_ot_make_request = sns_opentherm_set_boiler_dhw_temperature, + .m_ot_parse_response = sns_opentherm_parse_boiler_dhw_temperature, + .m_ot_appent_telemetry = sns_opentherm_tele_boiler_dhw_temperature}, + {// Read Application-specific fault flags and OEM fault code + .m_command_name = "ASFF", + .m_command_code = 0, + .m_flags = 0, + .m_results = {{.m_u8 = 0}, {.m_u8 = 0}}, + .m_ot_make_request = sns_opentherm_get_flags, + .m_ot_parse_response = sns_opentherm_parse_flags, + .m_ot_appent_telemetry = sns_opentherm_tele_flags}, + {// Read An OEM-specific diagnostic/service code + .m_command_name = "OEMD", + .m_command_code = 0, + .m_flags = 0, + .m_results = {{.m_u8 = 0}, {.m_u8 = 0}}, + .m_ot_make_request = sns_opentherm_get_oem_diag, + .m_ot_parse_response = sns_opentherm_parse_oem_diag, + .m_ot_appent_telemetry = sns_opentherm_tele_oem_diag}, + {// Read Flame modulation + .m_command_name = "FLM", + .m_command_code = (uint8_t)OpenThermMessageID::RelModLevel, + .m_flags = 0, + .m_results = {{.m_u8 = 0}, {.m_u8 = 0}}, + .m_ot_make_request = sns_opentherm_get_generic_float, + .m_ot_parse_response = sns_opentherm_parse_flame_modulation, + .m_ot_appent_telemetry = sns_opentherm_tele_generic_float}, + {// Read Boiler Temperature + .m_command_name = "TB", + .m_command_code = (uint8_t)OpenThermMessageID::Tboiler, + .m_flags = 0, + .m_results = {{.m_u8 = 0}, {.m_u8 = 0}}, + .m_ot_make_request = sns_opentherm_get_generic_float, + .m_ot_parse_response = sns_opentherm_parse_boiler_temperature, + .m_ot_appent_telemetry = sns_opentherm_tele_generic_float}, + {// Read DHW temperature + .m_command_name = "TDHW", + .m_command_code = (uint8_t)OpenThermMessageID::Tdhw, + .m_flags = 0, + .m_results = {{.m_u8 = 0}, {.m_u8 = 0}}, + .m_ot_make_request = sns_opentherm_get_generic_float, + .m_ot_parse_response = sns_opentherm_parse_generic_float, + .m_ot_appent_telemetry = sns_opentherm_tele_generic_float}, + {// Read Outside temperature + .m_command_name = "TOUT", + .m_command_code = (uint8_t)OpenThermMessageID::Toutside, + .m_flags = 0, + .m_results = {{.m_u8 = 0}, {.m_u8 = 0}}, + .m_ot_make_request = sns_opentherm_get_generic_float, + .m_ot_parse_response = sns_opentherm_parse_generic_float, + .m_ot_appent_telemetry = sns_opentherm_tele_generic_float}, + {// Read Return water temperature + .m_command_name = "TRET", + .m_command_code = (uint8_t)OpenThermMessageID::Tret, + .m_flags = 0, + .m_results = {{.m_u8 = 0}, {.m_u8 = 0}}, + .m_ot_make_request = sns_opentherm_get_generic_float, + .m_ot_parse_response = sns_opentherm_parse_generic_float, + .m_ot_appent_telemetry = sns_opentherm_tele_generic_float}, + {// Read DHW setpoint + .m_command_name = "DHWS", + .m_command_code = (uint8_t)OpenThermMessageID::TdhwSet, + .m_flags = 0, + .m_results = {{.m_u8 = 0}, {.m_u8 = 0}}, + .m_ot_make_request = sns_opentherm_get_generic_float, + .m_ot_parse_response = sns_opentherm_parse_dhw_setpoint, + .m_ot_appent_telemetry = sns_opentherm_tele_generic_float}, + {// Read max CH water setpoint + .m_command_name = "TMAX", + .m_command_code = (uint8_t)OpenThermMessageID::MaxTSet, + .m_flags = 0, + .m_results = {{.m_u8 = 0}, {.m_u8 = 0}}, + .m_ot_make_request = sns_opentherm_get_generic_float, + .m_ot_parse_response = sns_opentherm_parse_generic_float, + .m_ot_appent_telemetry = sns_opentherm_tele_generic_float}, + +}; + +/////////////////////////////////// Process Slave Status Flags & Control ////////////////////////////////////////////////// +unsigned long sns_opentherm_set_slave_flags(struct OpenThermCommandT *self, struct OT_BOILER_STATUS_T *status) +{ + bool centralHeatingIsOn = status->m_enableCentralHeating; + + if (status->m_useDiagnosticIndicationAsHeatRequest) { + centralHeatingIsOn |= OpenTherm::isDiagnostic(status->m_slave_raw_status); + } + + if (self->m_results[1].m_bool != centralHeatingIsOn) { + AddLog_P2(LOG_LEVEL_INFO, + PSTR("[OTH]: Central Heating transitioning from %s to %s"), + self->m_results[1].m_bool ? "on" : "off", + status->m_enableCentralHeating ? "on" : "off"); + } + self->m_results[1].m_bool = centralHeatingIsOn; + + unsigned int data = centralHeatingIsOn | + (status->m_enableHotWater << 1) | + (status->m_enableCooling << 2) | + (status->m_enableOutsideTemperatureCompensation << 3) | + (status->m_enableCentralHeating2 << 4); + + data <<= 8; + + return OpenTherm::buildRequest(OpenThermRequestType::READ, OpenThermMessageID::Status, data); +} + +void sns_opentherm_parse_slave_flags(struct OpenThermCommandT *self, struct OT_BOILER_STATUS_T *boilerStatus, unsigned long response) +{ + boilerStatus->m_slave_raw_status = response; + self->m_results[0].m_ul = response; +} + +#define OT_FLAG_TO_ON_OFF(status, flag) ((((status) & (flag)) != 0) ? 1 : 0) +void sns_opentherm_tele_slave_flags(struct OpenThermCommandT *self) +{ + unsigned long st = self->m_results[0].m_ul; + ResponseAppend_P(PSTR("{\"FAULT\":%d,\"CH\":%d,\"DHW\":%d,\"FL\":%d,\"COOL\":%d,\"CH2\":%d,\"DIAG\":%d,\"RAW\":%lu}"), + OT_FLAG_TO_ON_OFF(st, 0x01), + OT_FLAG_TO_ON_OFF(st, 0x02), + OT_FLAG_TO_ON_OFF(st, 0x04), + OT_FLAG_TO_ON_OFF(st, 0x08), + OT_FLAG_TO_ON_OFF(st, 0x10), + OT_FLAG_TO_ON_OFF(st, 0x20), + OT_FLAG_TO_ON_OFF(st, 0x40), + st); +} + +/////////////////////////////////// Set Boiler Temperature ////////////////////////////////////////////////// +unsigned long sns_opentherm_set_boiler_temperature(struct OpenThermCommandT *self, struct OT_BOILER_STATUS_T *status) +{ + // Assuming some boilers might write setpoint temperature into the Flash memory + // Having PID controlled appliance may produce a lot of small fluctuations in the setpoint value + // wearing out Boiler flash memory. + float diff = abs(status->m_boilerSetpoint - self->m_results[0].m_float); + // Ignore small changes in the boiler setpoint temperature + if (diff < OPENTHERM_BOILER_SETPOINT_TOLERANCE) + { + return -1; + } + AddLog_P2(LOG_LEVEL_INFO, + PSTR("[OTH]: Setting Boiler Temp. Old: %d, New: %d"), + (int)self->m_results[0].m_float, + (int)status->m_boilerSetpoint); + self->m_results[0].m_float = status->m_boilerSetpoint; + + unsigned int data = OpenTherm::temperatureToData(status->m_boilerSetpoint); + return OpenTherm::buildRequest(OpenThermMessageType::WRITE_DATA, OpenThermMessageID::TSet, data); +} +void sns_opentherm_parse_set_boiler_temperature(struct OpenThermCommandT *self, struct OT_BOILER_STATUS_T *boilerStatus, unsigned long response) +{ + self->m_results[1].m_float = OpenTherm::getFloat(response); +} +void sns_opentherm_tele_boiler_temperature(struct OpenThermCommandT *self) +{ + char requested[FLOATSZ]; + dtostrfd(self->m_results[0].m_float, Settings.flag2.temperature_resolution, requested); + char actual[FLOATSZ]; + dtostrfd(self->m_results[1].m_float, Settings.flag2.temperature_resolution, actual); + + // indicate fault if tepmerature demand and actual setpoint are greater then tolerance + bool isFault = abs(self->m_results[1].m_float - self->m_results[0].m_float) > OPENTHERM_BOILER_SETPOINT_TOLERANCE; + + ResponseAppend_P(PSTR("{\"FAULT\":%d,\"REQ\":%s,\"ACT\": %s}"), + (int)isFault, + requested, + actual); +} + +/////////////////////////////////// Set Domestic Hot Water Temperature ////////////////////////////////////////////////// +unsigned long sns_opentherm_set_boiler_dhw_temperature(struct OpenThermCommandT *self, struct OT_BOILER_STATUS_T *status) +{ + // The same consideration as for the boiler temperature + float diff = abs(status->m_hotWaterSetpoint - self->m_results[0].m_float); + // Ignore small changes in the boiler setpoint temperature + if (diff < OPENTHERM_BOILER_SETPOINT_TOLERANCE) + { + return -1; + } + AddLog_P2(LOG_LEVEL_INFO, + PSTR("[OTH]: Setting Hot Water Temp. Old: %d, New: %d"), + (int)self->m_results[0].m_float, + (int)status->m_hotWaterSetpoint); + + self->m_results[0].m_float = status->m_hotWaterSetpoint; + + unsigned int data = OpenTherm::temperatureToData(status->m_hotWaterSetpoint); + return OpenTherm::buildRequest(OpenThermMessageType::WRITE_DATA, OpenThermMessageID::TdhwSet, data); +} +void sns_opentherm_parse_boiler_dhw_temperature(struct OpenThermCommandT *self, struct OT_BOILER_STATUS_T *boilerStatus, unsigned long response) +{ + self->m_results[1].m_float = OpenTherm::getFloat(response); +} +void sns_opentherm_tele_boiler_dhw_temperature(struct OpenThermCommandT *self) +{ + char requested[FLOATSZ]; + dtostrfd(self->m_results[0].m_float, Settings.flag2.temperature_resolution, requested); + char actual[FLOATSZ]; + dtostrfd(self->m_results[1].m_float, Settings.flag2.temperature_resolution, actual); + + ResponseAppend_P(PSTR("{\"REQ\":%s,\"ACT\": %s}"), + requested, + actual); +} + +/////////////////////////////////// App Specific Fault Flags ////////////////////////////////////////////////// +unsigned long sns_opentherm_get_flags(struct OpenThermCommandT *self, struct OT_BOILER_STATUS_T *) +{ + return OpenTherm::buildRequest(OpenThermRequestType::READ, OpenThermMessageID::ASFflags, 0); +} + +void sns_opentherm_parse_flags(struct OpenThermCommandT *self, struct OT_BOILER_STATUS_T *boilerStatus, unsigned long response) +{ + uint8_t fault_code = (response >> 8) & 0xFF; + uint8_t oem_fault_code = response & 0xFF; + boilerStatus->m_fault_code = fault_code; + boilerStatus->m_oem_fault_code = fault_code; + self->m_results[0].m_u8 = fault_code; + self->m_results[1].m_u8 = oem_fault_code; +} + +void sns_opentherm_tele_flags(struct OpenThermCommandT *self) +{ + ResponseAppend_P(PSTR("{\"FC\":%d,\"OFC\":%d}"), + (int)self->m_results[0].m_u8, + (int)self->m_results[1].m_u8); +} + +/////////////////////////////////// OEM Diag Code ////////////////////////////////////////////////// +unsigned long sns_opentherm_get_oem_diag(struct OpenThermCommandT *self, struct OT_BOILER_STATUS_T *) +{ + return OpenTherm::buildRequest(OpenThermRequestType::READ, OpenThermMessageID::OEMDiagnosticCode, 0); +} + +void sns_opentherm_parse_oem_diag(struct OpenThermCommandT *self, struct OT_BOILER_STATUS_T *boilerStatus, unsigned long response) +{ + uint16_t diag_code = (uint16_t)response & 0xFFFF; + boilerStatus->m_oem_diag_code = diag_code; + self->m_results[0].m_u16 = diag_code; +} + +void sns_opentherm_tele_oem_diag(struct OpenThermCommandT *self) +{ + ResponseAppend_P(PSTR("%d"), (int)self->m_results[0].m_u16); +} + +/////////////////////////////////// Generic Single Float ///////////////////////////////////////////////// +unsigned long sns_opentherm_get_generic_float(struct OpenThermCommandT *self, struct OT_BOILER_STATUS_T *) +{ + return OpenTherm::buildRequest(OpenThermRequestType::READ, (OpenThermMessageID)self->m_command_code, 0); +} + +void sns_opentherm_parse_generic_float(struct OpenThermCommandT *self, struct OT_BOILER_STATUS_T *boilerStatus, unsigned long response) +{ + self->m_results[0].m_float = OpenTherm::getFloat(response); +} + +void sns_opentherm_tele_generic_float(struct OpenThermCommandT *self) +{ + char str[FLOATSZ]; + dtostrfd(self->m_results[0].m_float, Settings.flag2.temperature_resolution, str); + ResponseAppend_P(PSTR("%s"), str); +} + +/////////////////////////////////// Specific Floats Rerports to the ///////////////////////////////////////////////// +void sns_opentherm_parse_dhw_setpoint(struct OpenThermCommandT *self, struct OT_BOILER_STATUS_T *boilerStatus, unsigned long response) +{ + self->m_results[0].m_float = OpenTherm::getFloat(response); + boilerStatus->m_hotWaterSetpoint_read = self->m_results[0].m_float; +} + +void sns_opentherm_parse_flame_modulation(struct OpenThermCommandT *self, struct OT_BOILER_STATUS_T *boilerStatus, unsigned long response) +{ + self->m_results[0].m_float = OpenTherm::getFloat(response); + boilerStatus->m_flame_modulation_read = self->m_results[0].m_float; +} + +void sns_opentherm_parse_boiler_temperature(struct OpenThermCommandT *self, struct OT_BOILER_STATUS_T *boilerStatus, unsigned long response) +{ + self->m_results[0].m_float = OpenTherm::getFloat(response); + boilerStatus->m_boiler_temperature_read = self->m_results[0].m_float; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#define SNS_OT_COMMANDS_COUNT (sizeof(sns_opentherm_commands) / sizeof(OpenThermCommand)) +int sns_opentherm_current_command = SNS_OT_COMMANDS_COUNT; + +unsigned long sns_opentherm_get_next_request(struct OT_BOILER_STATUS_T *boilerStatus) +{ + // get next and loop the command + if (++sns_opentherm_current_command >= SNS_OT_COMMANDS_COUNT) + { + sns_opentherm_current_command = 0; + } + + struct OpenThermCommandT *cmd = &sns_opentherm_commands[sns_opentherm_current_command]; + // Return error if command known as not supported + if (cmd->m_flags.notSupported) + { + return -1; + } + // Retrurn OT compatible request + return cmd->m_ot_make_request(cmd, boilerStatus); +} + +void sns_opentherm_check_retry_request() +{ + if (sns_opentherm_current_command >= SNS_OT_COMMANDS_COUNT) + { + return; + } + struct OpenThermCommandT *cmd = &sns_opentherm_commands[sns_opentherm_current_command]; + + bool canRetry = ++cmd->m_flags.retryCount < 3; + // In case of last retry and if this command never respond successfully, set notSupported flag + if (!canRetry && !cmd->m_flags.supported) + { + cmd->m_flags.notSupported = true; + AddLog_P2(LOG_LEVEL_ERROR, + PSTR("[OTH]: command %s is not supported by the boiler. Last status: %s"), + cmd->m_command_name, + sns_ot_master->statusToString(sns_ot_master->getLastResponseStatus())); + } +} + +void sns_opentherm_process_success_response(struct OT_BOILER_STATUS_T *boilerStatus, unsigned long response) +{ + if (sns_opentherm_current_command >= SNS_OT_COMMANDS_COUNT) + { + return; + } + struct OpenThermCommandT *cmd = &sns_opentherm_commands[sns_opentherm_current_command]; + // mark command as supported + cmd->m_flags.supported = true; + + cmd->m_ot_parse_response(cmd, boilerStatus, response); +} + +void sns_opentherm_dump_telemetry() +{ + bool add_coma = false; + for (int i = 0; i < SNS_OT_COMMANDS_COUNT; ++i) + { + struct OpenThermCommandT *cmd = &sns_opentherm_commands[i]; + if (!cmd->m_flags.supported) + { + continue; + } + + ResponseAppend_P(PSTR("%s\"%s\":"), add_coma ? "," : "", cmd->m_command_name); + + cmd->m_ot_appent_telemetry(cmd); + + add_coma = true; + } +} +#endif \ No newline at end of file diff --git a/tasmota/xsns_70_veml6075.ino b/tasmota/xsns_70_veml6075.ino new file mode 100644 index 000000000..4735d1140 --- /dev/null +++ b/tasmota/xsns_70_veml6075.ino @@ -0,0 +1,306 @@ +/* + xsns_70_veml6075.ino - VEML6075 UVA/UVB/UVINDEX Sensor support for Tasmota + + Copyright (C) 2020 Martin Wagner + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifdef USE_I2C +#ifdef USE_VEML6075 +/*********************************************************************************************\ + * VEML6075 UVA/UVB/UVINDEX Sensor + * + * I2C Address: 0x10 +\*********************************************************************************************/ + +#define XSNS_70 70 +#define XI2C_49 49 // See I2CDEVICES.md + + +#define VEML6075_ADDR 0x10 // I2C address +#define VEML6075_CHIP_ID 0x26 // Manufacture ID + +// I2C register +#define VEML6075_REG_CONF 0x00 // Configuration register +#define VEML6075_REG_UVA 0x07 // UVA band raw measurement +#define VEML6075_REG_DARK 0x08 // Dark current (?) measurement +#define VEML6075_REG_UVB 0x09 // UVB band raw measurement +#define VEML6075_REG_UVCOMP1 0x0A // UV1 compensation value +#define VEML6075_REG_UVCOMP2 0x0B // UV2 compensation value +#define VEML6075_REG_ID 0x0C // ID Register + +// global constants for Calc +#define VEML6075_DEFAULT_UVA_A_COEFF 2.22 // Default for no coverglass +#define VEML6075_DEFAULT_UVA_B_COEFF 1.33 // Default for no coverglass +#define VEML6075_DEFAULT_UVB_C_COEFF 2.95 // Default for no coverglass +#define VEML6075_DEFAULT_UVB_D_COEFF 1.74 // Default for no coverglass +#define UVA_RESPONSIVITY_100MS_UNCOVERED 0.001461 // Default for no coverglass +#define UVB_RESPONSIVITY_100MS_UNCOVERED 0.002591 // Default for no coverglass + +const float UVA_RESPONSIVITY[] PROGMEM = +{ + UVA_RESPONSIVITY_100MS_UNCOVERED / 0.5016286645, // 50ms + UVA_RESPONSIVITY_100MS_UNCOVERED, // 100ms + UVA_RESPONSIVITY_100MS_UNCOVERED / 2.039087948, // 200ms + UVA_RESPONSIVITY_100MS_UNCOVERED / 3.781758958, // 400ms + UVA_RESPONSIVITY_100MS_UNCOVERED / 7.371335505 // 800ms +}; + +const float UVB_RESPONSIVITY[] PROGMEM = +{ + UVB_RESPONSIVITY_100MS_UNCOVERED / 0.5016286645, // 50ms + UVB_RESPONSIVITY_100MS_UNCOVERED, // 100ms + UVB_RESPONSIVITY_100MS_UNCOVERED / 2.039087948, // 200ms + UVB_RESPONSIVITY_100MS_UNCOVERED / 3.781758958, // 400ms + UVB_RESPONSIVITY_100MS_UNCOVERED / 7.371335505 // 800ms +}; + +// http and json defines +#define D_NAME_VEML6075 "VEML6075" +#define D_UVA_INTENSITY "UVA intensity" +#define D_UVB_INTENSITY "UVB intensity" + +const char HTTP_SNS_UVA[] PROGMEM = "{s}%s " D_UVA_INTENSITY "{m}%d " D_UNIT_WATT_METER_QUADRAT "{e}"; +const char HTTP_SNS_UVB[] PROGMEM = "{s}%s " D_UVB_INTENSITY "{m}%d " D_UNIT_WATT_METER_QUADRAT "{e}"; +const char HTTP_SNS_UVINDEX[] PROGMEM = "{s}%s " D_UV_INDEX "{m}%s {e}"; +const char JSON_SNS_VEML6075[] PROGMEM = ",\"%s\":{\"" D_JSON_UVA_INTENSITY "\":%d,\"" D_JSON_UVB_INTENSITY "\":%d,\"" D_JSON_UV_INDEX "\":%s}"; +const char S_JSON_VEML6075_COMMAND_NVALUE[] PROGMEM = "{\"" D_NAME_VEML6075 "\":{\"%s\":%d}}"; + +const char kVEML6075_Commands[] PROGMEM = D_CMND_VEML6075_POWER "|" D_CMND_VEML6075_DYNAMIC "|" D_CMND_VEML6075_INTTIME; + +enum VEML6075_Commands { // commands for Console + CMND_VEML6075_PWR, + CMND_VEML6075_SET_HD, + CMND_VEML6075_SET_UVIT, + }; + +// global variables +struct VEML6075STRUCT +{ + char types[9] = D_NAME_VEML6075; + uint8_t address = VEML6075_ADDR; + uint8_t inttime = 0; + uint16_t uva = 0; + uint16_t uvb = 0; + uint16_t uva_raw = 0; + uint16_t uvb_raw = 0; + uint16_t comp1 = 0; + uint16_t comp2 = 0; + uint16_t conf = 0; + float uvi = 0.0f; +} veml6075_sensor; + +uint8_t veml6075_active = 0; + +// typedef of config register +typedef union { + struct { + uint8_t pwr:1; // Shut Down + uint8_t forded_auto:1; // Auto or forced + uint8_t forced_trigger:1; // Trigger forced mode + uint8_t hd:1; // High dynamic + uint8_t inttime:3; // Integration Time + uint8_t spare7:1; // spare + }; + uint16_t config; +} veml6075configRegister; + +veml6075configRegister veml6075Config; + +/********************************************************************************************/ + +uint16_t VEML6075read16 (uint8_t reg) { + uint16_t swap = I2cRead16(VEML6075_ADDR, reg); + uint16_t ret = ((swap & 0xFF) << 8) | (swap >> 8); + return ret; +} + +void VEML6075write16 (uint8_t reg, uint16_t val) { + uint16_t swap = ((val & 0xFF) << 8) | (val >> 8); + I2cWrite16(VEML6075_ADDR, reg, swap); +} + +float VEML6075calcUVA (void) { + float uva_calc = veml6075_sensor.uva_raw - (VEML6075_DEFAULT_UVA_A_COEFF * veml6075_sensor.comp1) - (VEML6075_DEFAULT_UVA_B_COEFF * veml6075_sensor.comp2); + return uva_calc; +} + +float VEML6075calcUVB (void) { + float uvb_calc = veml6075_sensor.uvb_raw - (VEML6075_DEFAULT_UVB_C_COEFF * veml6075_sensor.comp1) - (VEML6075_DEFAULT_UVB_D_COEFF * veml6075_sensor.comp2); + return uvb_calc; +} + +float VEML6075calcUVI (void) { + float uvi_calc = ((veml6075_sensor.uva * UVA_RESPONSIVITY[veml6075_sensor.inttime]) + (veml6075_sensor.uvb * UVB_RESPONSIVITY[veml6075_sensor.inttime])) / 2; + return uvi_calc; +} + +void VEML6075SetHD(uint8_t val){ + veml6075Config.hd = val; + VEML6075write16 (VEML6075_REG_CONF, veml6075Config.config); +} + +uint8_t VEML6075ReadHD(void){ + veml6075Config.config = VEML6075read16 (VEML6075_REG_CONF); + return veml6075Config.hd; +} + +void VEML6075SetUvIt(uint8_t val){ + veml6075Config.inttime = val; + VEML6075Pwr(1); + VEML6075write16 (VEML6075_REG_CONF, veml6075Config.config); + VEML6075Pwr(0); +} + +uint8_t VEML6075GetUvIt(void){ + veml6075Config.config = VEML6075read16 (VEML6075_REG_CONF); + return veml6075Config.inttime; +} + +void VEML6075Pwr(uint8_t val){ + veml6075Config.pwr = val; + VEML6075write16 (VEML6075_REG_CONF, veml6075Config.config); +} + +uint8_t VEML6075GetPwr(void){ + veml6075Config.config = VEML6075read16 (VEML6075_REG_CONF); + return veml6075Config.pwr; +} + +void VEML6075ReadData(void) +{ + veml6075_sensor.uva_raw = VEML6075read16 (VEML6075_REG_UVA); + veml6075_sensor.uvb_raw = VEML6075read16 (VEML6075_REG_UVB); + veml6075_sensor.comp1 = VEML6075read16 (VEML6075_REG_UVCOMP1); + veml6075_sensor.comp2 = VEML6075read16 (VEML6075_REG_UVCOMP2); + veml6075_sensor.inttime = VEML6075GetUvIt(); + veml6075_sensor.uva = VEML6075calcUVA(); + veml6075_sensor.uvb = VEML6075calcUVB(); + veml6075_sensor.uvi = VEML6075calcUVI(); +} + +bool VEML6075init(void) +{ + uint8_t id = VEML6075read16 (VEML6075_REG_ID); + if(id == VEML6075_CHIP_ID) // Sensor id + return true; + return false; +} + +void VEML6075Detect(void) { + if (I2cActive(veml6075_sensor.address)) return; + + if (VEML6075init()) { + I2cSetActiveFound(veml6075_sensor.address, veml6075_sensor.types); + VEML6075write16 (VEML6075_REG_CONF, 0x10); // set default + veml6075_active = 1; + } +} + +void VEML6075EverySecond(void) { + VEML6075ReadData(); +} + +bool VEML6075Cmd(void) { + char command[CMDSZ]; + uint8_t name_len = strlen(D_NAME_VEML6075); + if (!strncasecmp_P(XdrvMailbox.topic, PSTR(D_NAME_VEML6075), name_len)) { + uint32_t command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic + name_len, kVEML6075_Commands); + switch (command_code) { + case CMND_VEML6075_PWR: + if (XdrvMailbox.data_len) { + if (2 >= XdrvMailbox.payload) { + VEML6075Pwr(XdrvMailbox.payload); + } + } + Response_P(S_JSON_VEML6075_COMMAND_NVALUE, command, VEML6075GetPwr()); + break; + case CMND_VEML6075_SET_HD: + if (XdrvMailbox.data_len) { + if (2 >= XdrvMailbox.payload) { + VEML6075SetHD(XdrvMailbox.payload); + } + } + Response_P(S_JSON_VEML6075_COMMAND_NVALUE, command, VEML6075ReadHD()); + break; + case CMND_VEML6075_SET_UVIT: + if (XdrvMailbox.data_len) { + if (4 >= XdrvMailbox.payload) { + VEML6075SetUvIt(XdrvMailbox.payload); + } + } + Response_P(S_JSON_VEML6075_COMMAND_NVALUE, command, VEML6075GetUvIt()); + break; + default: + return false; + } + return true; + } else { + return false; + } +} + +void VEML6075Show(bool json) +{ + char s_uvindex[FLOATSZ]; + dtostrfd(veml6075_sensor.uvi,1, s_uvindex); + + if (json) { + ResponseAppend_P(JSON_SNS_VEML6075, D_NAME_VEML6075, veml6075_sensor.uva, veml6075_sensor.uvb, s_uvindex); +#ifdef USE_WEBSERVER + } else { + WSContentSend_PD(HTTP_SNS_UVA, D_NAME_VEML6075, veml6075_sensor.uva); + WSContentSend_PD(HTTP_SNS_UVB, D_NAME_VEML6075, veml6075_sensor.uvb); + WSContentSend_PD(HTTP_SNS_UVINDEX, D_NAME_VEML6075 ,s_uvindex); +#endif // USE_WEBSERVER + } +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xsns70(uint8_t function) +{ + if (!I2cEnabled(XI2C_49)) { return false; } + + bool result = false; + + if (FUNC_INIT == function) { + VEML6075Detect(); + } + else if (veml6075_active) { + switch (function) { + case FUNC_EVERY_SECOND: + VEML6075EverySecond(); + break; + case FUNC_COMMAND: + result = VEML6075Cmd(); + break; + case FUNC_JSON_APPEND: + VEML6075Show(1); + break; +#ifdef USE_WEBSERVER + case FUNC_WEB_SENSOR: + VEML6075Show(0); + break; +#endif // USE_WEBSERVER + } + } + return result; +} + +#endif // USE_VEML6075 +#endif // USE_I2C diff --git a/tasmota/xsns_71_veml7700.ino b/tasmota/xsns_71_veml7700.ino new file mode 100644 index 000000000..695e35824 --- /dev/null +++ b/tasmota/xsns_71_veml7700.ino @@ -0,0 +1,205 @@ +/* + xsns_71_VEML7700.ino - VEML7700 Ambient light intensity Sensor support for Tasmota + + Copyright (C) 2020 Martin Wagner + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifdef USE_I2C +#ifdef USE_VEML7700 +/*********************************************************************************************\ + * VEML7700 ALS Sensor + * Using the Adafruit VEML7700 Libary + * I2C Address: 0x10 +\*********************************************************************************************/ + +#define XSNS_71 71 +#define XI2C_50 50 // See I2CDEVICES.md + +#include "Adafruit_VEML7700.h" +Adafruit_VEML7700 veml7700 = Adafruit_VEML7700(); //create object copy + +#define D_NAME_VEML7700 "VEML7700" +#define D_WHITE_CONTENT "White content" + +const char HTTP_SNS_WHITE[] PROGMEM = "{s}%s " D_WHITE_CONTENT "{m}%d {e}"; +const char JSON_SNS_VEML7700[] PROGMEM = ",\"%s\":{\"" D_JSON_ILLUMINANCE "\":%d,\"" D_JSON_WHITE_CONTENT "\":%d}"; + +#define D_CMND_VEML7700_PWR "power" +#define D_CMND_VEML7700_GAIN "gain" +#define D_CMND_VEML7700_INTTIME "inttime" +#define D_CMND_VEML7700_PERSIST "persist" + +const char S_JSON_VEML7700_COMMAND_NVALUE[] PROGMEM = "{\"" D_NAME_VEML7700 "\":{\"%s\":%d}}"; +const char kVEML7700_Commands[] PROGMEM = D_CMND_VEML7700_PWR "|" D_CMND_VEML7700_GAIN "|" D_CMND_VEML7700_INTTIME "|" D_CMND_VEML7700_PERSIST; + +enum VEML7700_Commands { // commands for Console + CMND_VEML7700_PWR, + CMND_VEML7700_GAIN, + CMND_VEML7700_SET_IT, + CMND_VEML7700_PERSIST, +}; + +struct VEML7700STRUCT +{ + bool active = 0; + char types[9] = D_NAME_VEML7700; + uint8_t address = VEML7700_I2CADDR_DEFAULT; + uint32_t lux_normalized = 0; + uint32_t white_normalized = 0; +} veml7700_sensor; + + +/********************************************************************************************/ + +void VEML7700Detect(void) { + if (!I2cSetDevice(veml7700_sensor.address)) return; + if (veml7700.begin()) { + I2cSetActiveFound(veml7700_sensor.address, veml7700_sensor.types); + veml7700_sensor.active = 1; + } +} + +uint16_t VEML7700TranslateItMs (uint8_t ittime){ + switch (ittime) { + case 0: return 100; + case 1: return 200; + case 2: return 400; + case 3: return 800; + case 8: return 50; + case 12: return 25; + default: return 0xFFFF; + } +} + +uint8_t VEML7700TranslateItInt (uint16_t ittimems){ + switch (ittimems) { + case 100: return 0; + case 200: return 1; + case 400: return 2; + case 800: return 3; + case 50: return 8; + case 25: return 12; + default: return 0xFF; + } +} + +void VEML7700EverySecond(void) { + veml7700_sensor.lux_normalized = (uint32_t) veml7700.readLuxNormalized(); + veml7700_sensor.white_normalized = (uint32_t) veml7700.readWhiteNormalized(); +} + +void VEML7700Show(bool json) +{ + if (json) { + ResponseAppend_P(JSON_SNS_VEML7700, D_NAME_VEML7700, veml7700_sensor.lux_normalized, veml7700_sensor.white_normalized); + +#ifdef USE_DOMOTICZ + if (0 == tele_period) DomoticzSensor(DZ_ILLUMINANCE, veml7700_sensor.lux_normalized); +#endif // USE_DOMOTICZ +#ifdef USE_WEBSERVER + } else { + WSContentSend_PD(HTTP_SNS_ILLUMINANCE, D_NAME_VEML7700, veml7700_sensor.lux_normalized); + WSContentSend_PD(HTTP_SNS_WHITE, D_NAME_VEML7700, veml7700_sensor.white_normalized); +#endif // USE_WEBSERVER + } +} + +bool VEML7700Cmd(void) { + char command[CMDSZ]; + uint8_t name_len = strlen(D_NAME_VEML7700); + if (!strncasecmp_P(XdrvMailbox.topic, PSTR(D_NAME_VEML7700), name_len)) { + uint32_t command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic + name_len, kVEML7700_Commands); + switch (command_code) { + case CMND_VEML7700_PWR: + if (XdrvMailbox.data_len) { + if (2 >= XdrvMailbox.payload) { + veml7700.enable(XdrvMailbox.payload); + } + } + Response_P(S_JSON_VEML7700_COMMAND_NVALUE, command, veml7700.enabled()); + break; + case CMND_VEML7700_GAIN: + if (XdrvMailbox.data_len) { + if (4 >= XdrvMailbox.payload) { + veml7700.setGain(XdrvMailbox.payload); + } + } + Response_P(S_JSON_VEML7700_COMMAND_NVALUE, command, veml7700.getGain()); + break; + case CMND_VEML7700_SET_IT: { + if (XdrvMailbox.data_len) { + uint8_t data = VEML7700TranslateItInt(XdrvMailbox.payload); + if (0xFF != data) { + veml7700.setIntegrationTime(data); + } + } + uint16_t dataret = VEML7700TranslateItMs(veml7700.getIntegrationTime()); + Response_P(S_JSON_VEML7700_COMMAND_NVALUE, command, dataret); + } + break; + case CMND_VEML7700_PERSIST: + if (XdrvMailbox.data_len) { + if (4 >= XdrvMailbox.payload) { + veml7700.setPersistence(XdrvMailbox.payload); + } + } + Response_P(S_JSON_VEML7700_COMMAND_NVALUE, command, veml7700.getPersistence()); + break; + default: + return false; + } + return true; + } + else { + return false; + } +} +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xsns71(uint8_t function) +{ + if (!I2cEnabled(XI2C_50)) { return false; } + + bool result = false; + + if (FUNC_INIT == function) { + VEML7700Detect(); + } + else if (veml7700_sensor.active) { + switch (function) { + case FUNC_EVERY_SECOND: + VEML7700EverySecond(); + break; + case FUNC_COMMAND: + result = VEML7700Cmd(); + break; + case FUNC_JSON_APPEND: + VEML7700Show(1); + break; +#ifdef USE_WEBSERVER + case FUNC_WEB_SENSOR: + VEML7700Show(0); + break; +#endif // USE_WEBSERVER + } + } + return result; +} + +#endif // USE_VEML7700 +#endif // USE_I2C diff --git a/tasmota/xsns_72_mcp9808.ino b/tasmota/xsns_72_mcp9808.ino new file mode 100644 index 000000000..8af129f97 --- /dev/null +++ b/tasmota/xsns_72_mcp9808.ino @@ -0,0 +1,136 @@ +/* + xsns_72_mcp9808 - MCP9808 I2C temperature sensor support for Tasmota + + Copyright (C) 2020 Martin Wagner and Theo Arends + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +*/ + +#ifdef USE_I2C +#ifdef USE_MCP9808 +/*********************************************************************************************\ + * MCP9808 - Temperature Sensor + * + * I2C Address: 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F + * +\*********************************************************************************************/ + +#define XSNS_72 72 +#define XI2C_51 51 // See I2CDEVICES.md + +#include "Adafruit_MCP9808.h" +Adafruit_MCP9808 mcp9808 = Adafruit_MCP9808(); // create object copy + +#define MCP9808_MAX_SENSORS 8 +#define MCP9808_START_ADDRESS 0x18 + +struct { +char types[9] = "MCP9808"; +uint8_t count = 0; +} mcp9808_cfg; + +struct { + float temperature = NAN; + uint8_t address; +} mcp9808_sensors[MCP9808_MAX_SENSORS]; + +/********************************************************************************************/ + +float MCP9808Read(uint8_t addr) { + float t = mcp9808.readTempC(addr); + return t; +} + +void MCP9808Detect(void) { + for (uint8_t i = 0; i < MCP9808_MAX_SENSORS; i++) { + if (!I2cSetDevice(MCP9808_START_ADDRESS + i)) { continue; } + + if (mcp9808.begin(MCP9808_START_ADDRESS + i)) { + mcp9808_sensors[mcp9808_cfg.count].address = MCP9808_START_ADDRESS + i; + I2cSetActiveFound(mcp9808_sensors[mcp9808_cfg.count].address, mcp9808_cfg.types); + mcp9808.setResolution (mcp9808_sensors[mcp9808_cfg.count].address, 2); // Set Resolution to 0.125°C + mcp9808_cfg.count++; + } + } +} + +void MCP9808EverySecond(void) { + for (uint32_t i = 0; i < mcp9808_cfg.count; i++) { + float t = MCP9808Read(mcp9808_sensors[i].address); + mcp9808_sensors[i].temperature = ConvertTemp(t); + } +} + +void MCP9808Show(bool json) { + for (uint32_t i = 0; i < mcp9808_cfg.count; i++) { + char temperature[33]; + dtostrfd(mcp9808_sensors[i].temperature, Settings.flag2.temperature_resolution, temperature); + + char sensor_name[11]; + strlcpy(sensor_name, mcp9808_cfg.types, sizeof(sensor_name)); + if (mcp9808_cfg.count > 1) { + snprintf_P(sensor_name, sizeof(sensor_name), PSTR("%s%c%02X"), sensor_name, IndexSeparator(), mcp9808_sensors[i].address); // MCP9808-18, MCP9808-1A etc. + } + + if (json) { + ResponseAppend_P(JSON_SNS_TEMP, sensor_name, temperature); + if ((0 == tele_period) && (0 == i)) { +#ifdef USE_DOMOTICZ + DomoticzSensor(DZ_TEMP, temperature); +#endif // USE_DOMOTICZ +#ifdef USE_KNX + KnxSensor(KNX_TEMPERATURE, mcp9808_sensors[i].temperature); +#endif // USE_KNX + } +#ifdef USE_WEBSERVER + } else { + WSContentSend_PD(HTTP_SNS_TEMP, sensor_name, temperature, TempUnit()); +#endif // USE_WEBSERVER + } + } +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xsns72(uint8_t function) +{ + if (!I2cEnabled(XI2C_51)) { return false; } + bool result = false; + + if (FUNC_INIT == function) { + MCP9808Detect(); + } + else if (mcp9808_cfg.count){ + switch (function) { + case FUNC_EVERY_SECOND: + MCP9808EverySecond(); + break; + case FUNC_JSON_APPEND: + MCP9808Show(1); + break; + #ifdef USE_WEBSERVER + case FUNC_WEB_SENSOR: + MCP9808Show(0); + break; + #endif // USE_WEBSERVER + } + } + return result; +} + +#endif // USE_MCP9808 +#endif // USE_I2C diff --git a/tasmota/xsns_73_hp303b.ino b/tasmota/xsns_73_hp303b.ino new file mode 100644 index 000000000..0d9363409 --- /dev/null +++ b/tasmota/xsns_73_hp303b.ino @@ -0,0 +1,178 @@ +/* + xsns_72_hp303b.ino - HP303B digital barometric air pressure sensor support for Tasmota + + Copyright (C) 2020 Theo Arends + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifdef USE_I2C +#ifdef USE_HP303B +/*********************************************************************************************\ + * HP303B - Pressure and temperature sensor + * + * Source: Lolin LOLIN_HP303B_Library + * + * I2C Address: 0x77 or 0x76 +\*********************************************************************************************/ + +#define XSNS_73 73 +#define XI2C_52 52 // See I2CDEVICES.md + +#define HP303B_MAX_SENSORS 2 +#define HP303B_START_ADDRESS 0x76 + +#include +// HP303B Object +LOLIN_HP303B HP303BSensor = LOLIN_HP303B(); + +struct { + int16_t oversampling = 7; + char types[7] = "HP303B"; + uint8_t count = 0; +} hp303b_cfg; + +struct BHP303B { + float temperature = NAN; + float pressure = NAN; + uint8_t address; + uint8_t valid = 0; +} hp303b_sensor[HP303B_MAX_SENSORS]; + +/*********************************************************************************************/ + +bool HP303B_Read(uint32_t hp303b_idx) { + if (hp303b_sensor[hp303b_idx].valid) { hp303b_sensor[hp303b_idx].valid--; } + + float t; + if (HP303BSensor.measureTempOnce(t, hp303b_sensor[hp303b_idx].address, hp303b_cfg.oversampling) != 0) { + return false; + } + + float p; + if (HP303BSensor.measurePressureOnce(p, hp303b_sensor[hp303b_idx].address, hp303b_cfg.oversampling) != 0) { + return false; + } + + hp303b_sensor[hp303b_idx].temperature = (float)ConvertTemp(t); + hp303b_sensor[hp303b_idx].pressure = (float)ConvertPressure(p / 100); // Conversion to hPa + + hp303b_sensor[hp303b_idx].valid = SENSOR_MAX_MISS; + return true; +} + +/********************************************************************************************/ + +void HP303B_Detect(void) { + for (uint32_t i = 0; i < HP303B_MAX_SENSORS; i++) { + if (!I2cSetDevice(HP303B_START_ADDRESS + i)) { continue; } + + if (HP303BSensor.begin(HP303B_START_ADDRESS + i)) { + hp303b_sensor[hp303b_cfg.count].address = HP303B_START_ADDRESS + i; + I2cSetActiveFound(hp303b_sensor[hp303b_cfg.count].address, hp303b_cfg.types); + hp303b_cfg.count++; + } + } +} + +void HP303B_EverySecond(void) { + for (uint32_t i = 0; i < hp303b_cfg.count; i++) { + if (uptime &1) { + if (!HP303B_Read(i)) { + AddLogMissed(hp303b_cfg.types, hp303b_sensor[i].valid); + } + } + } +} + +void HP303B_Show(bool json) { + for (uint32_t i = 0; i < hp303b_cfg.count; i++) { + if (hp303b_sensor[i].valid) { + char sensor_name[12]; + strlcpy(sensor_name, hp303b_cfg.types, sizeof(sensor_name)); + if (hp303b_cfg.count > 1) { + snprintf_P(sensor_name, sizeof(sensor_name), PSTR("%s%c%02X"), sensor_name, IndexSeparator(), hp303b_sensor[i].address); // HP303B-76, HP303B-77 + } + + float sealevel = 0.0; + if (hp303b_sensor[i].pressure != 0.0) { + sealevel = (hp303b_sensor[i].pressure / FastPrecisePow(1.0 - ((float)Settings.altitude / 44330.0), 5.255)) - 21.6; + sealevel = ConvertPressure(sealevel); + } + + char str_temperature[33]; + dtostrfd(hp303b_sensor[i].temperature, Settings.flag2.temperature_resolution, str_temperature); + char str_pressure[33]; + dtostrfd(hp303b_sensor[i].pressure, Settings.flag2.pressure_resolution, str_pressure); + char sea_pressure[33]; + dtostrfd(sealevel, Settings.flag2.pressure_resolution, sea_pressure); + + if (json) { + ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_TEMPERATURE "\":%s,\"" D_JSON_PRESSURE "\":%s"), sensor_name, str_temperature, str_pressure); + if (Settings.altitude != 0) { + ResponseAppend_P(PSTR(",\"" D_JSON_PRESSUREATSEALEVEL "\":%s"), sea_pressure); + } + ResponseJsonEnd(); +#ifdef USE_DOMOTICZ + // Domoticz and knx only support one temp sensor + if ((0 == tele_period) && (0 == i)) { + DomoticzSensor(DZ_TEMP, hp303b_sensor[i].temperature); + } +#endif // USE_DOMOTICZ +#ifdef USE_WEBSERVER + } else { + WSContentSend_PD(HTTP_SNS_TEMP, sensor_name, str_temperature, TempUnit()); + WSContentSend_PD(HTTP_SNS_PRESSURE, sensor_name, str_pressure, PressureUnit().c_str()); + if (Settings.altitude != 0) { + WSContentSend_PD(HTTP_SNS_SEAPRESSURE, sensor_name, sea_pressure, PressureUnit().c_str()); + } +#endif // USE_WEBSERVER + } + } + } +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xsns73(uint8_t function) +{ + if (!I2cEnabled(XI2C_52)) { return false; } + + bool result = false; + + if (FUNC_INIT == function) { + HP303B_Detect(); + } + else if (hp303b_cfg.count) { + switch (function) { + case FUNC_EVERY_SECOND: + HP303B_EverySecond(); + break; + case FUNC_JSON_APPEND: + HP303B_Show(1); + break; +#ifdef USE_WEBSERVER + case FUNC_WEB_SENSOR: + HP303B_Show(0); + break; +#endif // USE_WEBSERVER + } + } + return result; +} + +#endif // USE_HP303B +#endif // USE_I2C diff --git a/tasmota/xsns_74_lmt01.ino b/tasmota/xsns_74_lmt01.ino new file mode 100644 index 000000000..d52e6dae2 --- /dev/null +++ b/tasmota/xsns_74_lmt01.ino @@ -0,0 +1,143 @@ +/* + xns_74_lmt01.ino - Support for single wire LMT01 Temperature Sensor + + Copyright (C) 2020 Theo Arends, Justifiably + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifdef USE_LMT01 +/*********************************************************************************************\ + * LMT01 - 0.5°C Accurate 2-Pin Digital Output Temperature Sensor With Pulse Count Interface + * + * Uses fragments of public domain code LMT01_Example.ino released by Texas Instruments, July 10th 2017. + * See https://training.ti.com/how-interface-lmt01-temperature-sensor-arduino +\*********************************************************************************************/ + +#define XSNS_74 74 + +#define LMT01_TIMEOUT 200 // ms timeout for a reading cycle + +bool lmt01_initialized = false; +float lmt01_temperature = NAN; + +void LMT01_Init(void) { + if (PinUsed(GPIO_LMT01)) { + pinMode(Pin(GPIO_LMT01), INPUT); + attachInterrupt(Pin(GPIO_LMT01), LMT01_countPulse, FALLING); + lmt01_initialized = true; + } +} + +#ifndef ARDUINO_ESP8266_RELEASE_2_3_0 // Fix core 2.5.x ISR not in IRAM Exception +void LMT01_countPulse(void) ICACHE_RAM_ATTR; +#endif // ARDUINO_ESP8266_RELEASE_2_3_0 + +volatile int lmt01_pulseCount = 0; + +void LMT01_countPulse(void) { + lmt01_pulseCount++; +} + +void LMT01_GetTemperature(void) { + int pulses = 0; + pulses = LMT01_getPulses(); + if (pulses >= 0) { + // simple linear conversion, datasheet has a look-up table alternative + // which is accurate over a wider temperature range + lmt01_temperature = ConvertTemp(0.0625 * pulses - 50); + } else { + lmt01_temperature = NAN; // Timeout + } +} + +int LMT01_getPulses(void) { + int timeout = LMT01_TIMEOUT; + int hold = -1; + // complete current pulse cycle (50ms max) + while(lmt01_pulseCount != hold && --timeout > 0) { + hold = lmt01_pulseCount; + delay(1); + } + lmt01_pulseCount = 0; + // wait for start of next (54ms max) + while(lmt01_pulseCount == 0 && --timeout > 0) { + delay(1); + } + hold = -1; + // take this count (up to 50ms) + while(lmt01_pulseCount != hold && --timeout > 0) { + hold = lmt01_pulseCount; + delay(1); + } + // discard spurious low counts + if (timeout > 0 && hold >= 10) { + return hold; + } + return -1; +} + +void LMT01_Show(bool Json) { + char temp[33]; + dtostrfd(lmt01_temperature, Settings.flag2.temperature_resolution, temp); + + if (Json) { + ResponseAppend_P(JSON_SNS_TEMP, "LMT01", temp); +#ifdef USE_DOMOTICZ + if (0 == tele_period) { + DomoticzSensor(DZ_TEMP, temp); + } +#endif // USE_DOMOTICZ +#ifdef USE_KNX + if (0 == tele_period) { + KnxSensor(KNX_TEMPERATURE, lmt01_temperature); + } +#endif // USE_KNX +#ifdef USE_WEBSERVER + } else { + WSContentSend_PD(HTTP_SNS_TEMP, "LMT01", temp, TempUnit()); +#endif // USE_WEBSERVER + } +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xsns74(uint8_t function) +{ + bool result = false; + + if (FUNC_INIT == function) { + LMT01_Init(); + } + else if (lmt01_initialized) { + switch (function) { + case FUNC_EVERY_SECOND: + LMT01_GetTemperature(); + break; + case FUNC_JSON_APPEND: + LMT01_Show(true); + break; +#ifdef USE_WEBSERVER + case FUNC_WEB_SENSOR: + LMT01_Show(false); + break; +#endif // USE_WEBSERVER + } + } + return result; +} + +#endif // USE_LMT01 diff --git a/tasmota/xsns_91_prometheus.ino b/tasmota/xsns_75_prometheus.ino similarity index 63% rename from tasmota/xsns_91_prometheus.ino rename to tasmota/xsns_75_prometheus.ino index ea4c0047a..934c01dd8 100644 --- a/tasmota/xsns_91_prometheus.ino +++ b/tasmota/xsns_75_prometheus.ino @@ -1,5 +1,5 @@ /* - xsns_91_prometheus.ino - Web based information for Tasmota + xsns_75_prometheus.ino - Web based information for Tasmota Copyright (C) 2020 Theo Arends @@ -17,14 +17,12 @@ along with this program. If not, see . */ -//#define USE_PROMETHEUS // Enable retrieval of metrics - #ifdef USE_PROMETHEUS /*********************************************************************************************\ * Prometheus support \*********************************************************************************************/ -#define XSNS_91 91 +#define XSNS_75 75 void HandleMetrics(void) { @@ -37,17 +35,31 @@ void HandleMetrics(void) char parameter[FLOATSZ]; - if (global_temperature != 9999) { - dtostrfd(global_temperature, Settings.flag2.temperature_resolution, parameter); - WSContentSend_P(PSTR("# TYPE global_temperature gauge\nglobal_temperature %s\n"), parameter); + // Pseudo-metric providing metadata about the running firmware version. + WSContentSend_P(PSTR("# TYPE tasmota_info gauge\ntasmota_info{version=\"%s\",image=\"%s\",build_timestamp=\"%s\"} 1\n"), + my_version, my_image, GetBuildDateAndTime().c_str()); + WSContentSend_P(PSTR("# TYPE tasmota_uptime_seconds gauge\ntasmota_uptime_seconds %d\n"), uptime); + WSContentSend_P(PSTR("# TYPE tasmota_boot_count counter\ntasmota_boot_count %d\n"), Settings.bootcount); + WSContentSend_P(PSTR("# TYPE tasmota_flash_writes_total counter\ntasmota_flash_writes_total %d\n"), Settings.save_flag); + + + // Pseudo-metric providing metadata about the WiFi station. + WSContentSend_P(PSTR("# TYPE tasmota_wifi_station_info gauge\ntasmota_wifi_station_info{bssid=\"%s\",ssid=\"%s\"} 1\n"), WiFi.BSSIDstr().c_str(), WiFi.SSID().c_str()); + + // Wi-Fi Signal strength + WSContentSend_P(PSTR("# TYPE tasmota_wifi_station_signal_dbm gauge\ntasmota_wifi_station_signal_dbm{mac_address=\"%s\"} %d\n"), WiFi.BSSIDstr().c_str(), WiFi.RSSI()); + + if (!isnan(global_temperature_celsius)) { + dtostrfd(global_temperature_celsius, Settings.flag2.temperature_resolution, parameter); + WSContentSend_P(PSTR("# TYPE global_temperature_celsius gauge\nglobal_temperature_celsius %s\n"), parameter); } if (global_humidity != 0) { dtostrfd(global_humidity, Settings.flag2.humidity_resolution, parameter); WSContentSend_P(PSTR("# TYPE global_humidity gauge\nglobal_humidity %s\n"), parameter); } - if (global_pressure != 0) { - dtostrfd(global_pressure, Settings.flag2.pressure_resolution, parameter); - WSContentSend_P(PSTR("# TYPE global_pressure gauge\nglobal_pressure %s\n"), parameter); + if (global_pressure_hpa != 0) { + dtostrfd(global_pressure_hpa, Settings.flag2.pressure_resolution, parameter); + WSContentSend_P(PSTR("# TYPE global_pressure_hpa gauge\nglobal_pressure_hpa %s\n"), parameter); } #ifdef USE_ENERGY_SENSOR @@ -84,13 +96,13 @@ void HandleMetrics(void) * Interface \*********************************************************************************************/ -bool Xsns91(uint8_t function) +bool Xsns75(uint8_t function) { bool result = false; switch (function) { case FUNC_WEB_ADD_HANDLER: - WebServer->on("/metrics", HandleMetrics); + Webserver->on("/metrics", HandleMetrics); break; } return result; diff --git a/tools/Esptool/ESP32/boot_app0.bin b/tools/Esptool/ESP32/boot_app0.bin new file mode 100644 index 000000000..13562cabb Binary files /dev/null and b/tools/Esptool/ESP32/boot_app0.bin differ diff --git a/tools/Esptool/ESP32/bootloader_dout_40m.bin b/tools/Esptool/ESP32/bootloader_dout_40m.bin new file mode 100644 index 000000000..eab1e96d1 Binary files /dev/null and b/tools/Esptool/ESP32/bootloader_dout_40m.bin differ diff --git a/tools/Esptool/ESP32/partitions.bin b/tools/Esptool/ESP32/partitions.bin new file mode 100644 index 000000000..7ae174cb4 Binary files /dev/null and b/tools/Esptool/ESP32/partitions.bin differ diff --git a/tools/Esptool/ESP32/readme.txt b/tools/Esptool/ESP32/readme.txt new file mode 100644 index 000000000..bdedc87de --- /dev/null +++ b/tools/Esptool/ESP32/readme.txt @@ -0,0 +1,5 @@ +These files are needed for flashing Tasmota32 with esptool.py to an ESP32. + +Command syntax for flashing Tasmota32 firmware on ESP32 via Esptool (replace COM Port Number!): + +esptool.py --chip esp32 --port COM5 --baud 921600 --before default_reset --after hard_reset write_flash -z --flash_mode dout --flash_freq 40m --flash_size detect 0x1000 bootloader_dout_40m.bin 0x8000 partitions.bin 0xe000 boot_app0.bin 0x10000 tasmota32.bin diff --git a/tools/Esptool/VerifyFlash.bat b/tools/Esptool/VerifyFlash.bat index bfe33f494..d5865d3a6 100644 --- a/tools/Esptool/VerifyFlash.bat +++ b/tools/Esptool/VerifyFlash.bat @@ -1 +1 @@ -esptool.py --baud 115200 verify_flash -fs 1MB -fm dout 0x000000 firmware.bin +esptool.py --baud 115200 verify_flash -fs 1MB -fm dout 0x000000 firmware.bin diff --git a/tools/Esptool/WriteFlash.bat b/tools/Esptool/WriteFlash.bat index 25dc9bf86..8adc4192e 100644 --- a/tools/Esptool/WriteFlash.bat +++ b/tools/Esptool/WriteFlash.bat @@ -1 +1 @@ -esptool.py --baud 115200 write_flash -fs 1MB -fm dout 0x000000 firmware.bin +esptool.py --baud 115200 write_flash -fs 1MB -fm dout 0x000000 firmware.bin diff --git a/tools/decode-status.py b/tools/decode-status.py index d1d361d29..e6e4138bd 100755 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -20,7 +20,7 @@ Requirements: - Python - - pip json pycurl + - pip json requests Instructions: Execute command with option -d to retrieve status report from device or @@ -42,11 +42,10 @@ Example: import io import os.path import json -import pycurl -import urllib2 +import requests +import urllib from sys import exit from optparse import OptionParser -from StringIO import StringIO a_on_off = ["OFF","ON "] @@ -93,7 +92,7 @@ a_setoption = [[ "IR Unknown threshold", "CSE7766 invalid power margin", "Ignore hold time (s)", - "(not used) Number of Tuya MCU relays", + "Gratuitous ARP repeat time", "Over temperature threshold (celsius)", "(not used) Tuya MCU max dimmer value", "(not used) Tuya MCU voltage Id", @@ -126,7 +125,7 @@ a_setoption = [[ "Enable Weekend Energy Tariff", "Select different Modbus registers for Active Energy", "Enable hardware energy total counter as reference", - "Enable HTTP CORS", + "Detach buttons from relays and enable MQTT action state for multipress", "Enable internal pullup for single DS18x20 sensor", "GroupTopic replaces %topic% (0) or fixed topic cmnd/grouptopic (1)", "Enable incrementing bootcount when deepsleep is enabled", @@ -144,9 +143,16 @@ a_setoption = [[ "PWM Dimmer Turn red LED on when powered off", "PWM Dimmer Buttons control remote devices", "Distinct MQTT topics per device for Zigbee", - "","","","", - "","","","", - "","","","", + "Disable non-json MQTT response", + "Enable light fading at start/power on", + "Set PWM Mode from regular PWM to ColorTemp control", + "Keep uncompressed rules in memory to avoid CPU load of uncompressing at each tick", + "Implement simpler MAX6675 protocol instead of MAX31855", + "Enable Wifi", + "Enable Ethernet (ESP32)", + "Set Baud rate for TuyaMCU serial communication (0 = 9600 or 1 = 115200)", + "Rotary encoder uses rules instead of light control", + "","","", "","","","", "","","","", "","","","" @@ -193,19 +199,19 @@ a_features = [[ "USE_INA226","USE_A4988_STEPPER","USE_DDS2382","USE_SM2135", "USE_SHUTTER","USE_PCF8574","USE_DDSU666","USE_DEEPSLEEP", "USE_SONOFF_SC","USE_SONOFF_RF","USE_SONOFF_L1","USE_EXS_DIMMER", - "USE_ARDUINO_SLAVE","USE_HIH6","USE_HPMA","USE_TSL2591", + "USE_TASMOTA_SLAVE","USE_HIH6","USE_HPMA","USE_TSL2591", "USE_DHT12","USE_DS1624","USE_GPS","USE_HOTPLUG", "USE_NRF24","USE_MIBLE","USE_HM10","USE_LE01MR", "USE_AHT1x","USE_WEMOS_MOTOR_V1","USE_DEVICE_GROUPS","USE_PWM_DIMMER" ],[ "USE_KEELOQ","USE_HRXL","USE_SONOFF_D1","USE_HDC1080", - "USE_IAQ","","","", + "USE_IAQ","USE_DISPLAY_SEVENSEG","USE_AS3935","USE_PING", + "USE_WINDMETER","USE_OPENTHERM","USE_THERMOSTAT","USE_VEML6075", + "USE_VEML7700","USE_MCP9808","USE_BL0940","USE_TELEGRAM", + "USE_HP303B","USE_TCP_BRIDGE","USE_TELEINFO","USE_LMT01", + "USE_PROMETHEUS","","","", "","","","", - "","","","", - "","","","", - "","","","", - "","","","", - "","","","" + "","","USE_ETHERNET","USE_WEBCAM" ]] usage = "usage: decode-status {-d | -f} arg" @@ -221,25 +227,19 @@ parser.add_option("-f", "--file", metavar="FILE", (options, args) = parser.parse_args() if (options.device): - buffer = StringIO() loginstr = "" if options.password is not None: - loginstr = "user={}&password={}&".format(urllib2.quote(options.username), urllib2.quote(options.password)) + loginstr = "user={}&password={}&".format(urllib.parse.quote(options.username), urllib.parse.quote(options.password)) url = str("http://{}/cm?{}cmnd=status%200".format(options.device, loginstr)) - c = pycurl.Curl() - c.setopt(c.URL, url) - c.setopt(c.WRITEDATA, buffer) - c.perform() - c.close() - body = buffer.getvalue() - obj = json.loads(body) + res = requests.get(url) + obj = json.loads(res.content) else: jsonfile = options.jsonfile with open(jsonfile, "r") as fp: obj = json.load(fp) def StartDecode(): - print ("\n*** decode-status.py v20200314 by Theo Arends and Jacek Ziolkowski ***") + print ("\n*** decode-status.py v20200704 by Theo Arends and Jacek Ziolkowski ***") # print("Decoding\n{}".format(obj)) diff --git a/tools/serial-plotter.py b/tools/serial-plotter.py new file mode 100644 index 000000000..83ec6dba6 --- /dev/null +++ b/tools/serial-plotter.py @@ -0,0 +1,192 @@ +#!/usr/bin/env python3 + +""" + serial-plotter.py - for Tasmota + + Copyright (C) 2020 Christian Baars + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Requirements: + - Python + - pip3 install matplotlib pyserial + - for Windows: Full python install including tkinter + - a Tasmotadriver that plots + +Instructions: + expects serial data in the format: + 'PLOT: graphnumber value' + graph (1-4) + integer value + Code snippet example: (last value will be ignored) + AddLog_P2(LOG_LEVEL_INFO, PSTR("PLOT: %u, %u, %u,"),button_index+1, _value, Button.touch_hits[button_index]); + +Usage: + ./serial-plotter.py --port /dev/PORT --baud BAUD (or change defaults in the script) + set output in tasmota, e.g.; TouchCal 1..4 (via Textbox) + +""" +import numpy as np +import matplotlib.pyplot as plt +import matplotlib.animation as animation +from matplotlib.widgets import TextBox +import time +import serial +import argparse +import sys + +print("Python version") +print (sys.version) + +#default values +port = '/dev/cu.SLAB_USBtoUART' +baud = 115200 + +#command line input +parser = argparse.ArgumentParser() +parser.add_argument("--port", "-p", help="change serial port, default: " + port) +parser.add_argument("--baud", "-b", help="change baud rate, default: " + str(baud)) +args = parser.parse_args() +if args.port: + print("change serial port to %s" % args.port) + port = args.port +if args.baud: + print("change baud rate to %s" % args.baud) + baud = args.baud + + +#time range +dt = 0.01 +t = np.arange(0.0, 100, dt) + +#lists for the data +xs = [0] #counting up x +ys = [[0],[0],[0],[0]] #4 fixed graphs for now +max_y = 1 +# min_y = 0 + +fig = plt.figure('Tasmota Serial Plotter') +ax = fig.add_subplot(111, autoscale_on=True, xlim=(0, 200), ylim=(0, 20)) #fixed x scale for now, y will adapt +ax.grid() + +line1, = ax.plot([], [], color = "r", label='G 1') +line2, = ax.plot([], [], color = "g", label='G 2') +line3, = ax.plot([], [], color = "b", label='G 3') +line4, = ax.plot([], [], color = "y", label='G 4') + +time_template = 'time = %.1fs' +time_text = ax.text(0.05, 0.9, '', transform=ax.transAxes) + +ser = serial.Serial() +ser.port = port +ser.baudrate = baud +ser.timeout = 0 #return immediately +try: + ser.open() +except: + print("Could not connect to serial with settings: " + str(ser.port) + ' at ' + str(ser.baudrate) + 'baud') + print("port available?") + exit() + +if ser.is_open==True: + print("Serial Plotter started ...:") + plt.title('connected to ' + str(ser.port) + ' at ' + str(ser.baudrate) + 'baud') +else: + print("Could not connect to serial: " + str(ser.port) + ' at ' + str(ser.baudrate) + 'baud') + plt.title('NOT connected to ' + str(ser.port) + ' at ' + str(ser.baudrate) + 'baud') + +def init(): + line1.set_data([], []) + line2.set_data([], []) + line3.set_data([], []) + line4.set_data([], []) + time_text.set_text('') + return [line1,line2,line3,line4,time_text ] #was line + + +def parse_line(data_line): + pos = data_line.find("PLOT:", 10) + if pos<0: + # print("wrong format") + return 0,0 + + raw_data = data_line[pos+6:] + val_list = raw_data.split(',') + try: + g = int(val_list[0]) + v = int(val_list[1]) + return g, v + except: + return 0,0 + +def update(num, line1, line2): + global xs, ys, max_y + + time_text.set_text(time_template % (num*dt) ) + + receive_data = str(ser.readline()) #string + + g, v = parse_line(receive_data) + if (g in range(1,5)): + # print(v,g) + if v>max_y: + max_y = v + print(max_y) + ax.set_ylim([0, max_y * 1.2]) + + idx = 0 + for y in ys: + y.append(y[-1]) + if idx == g-1: + y[-1] = v + idx = idx +1 + xs.append(xs[-1]+1) + + if len(ys[0])>200: + xs.pop() + for y in ys: + y.pop(0) + line1.set_data(xs, ys[0]) + line2.set_data(xs, ys[1]) + line3.set_data(xs, ys[2]) + line4.set_data(xs, ys[3]) + return [line1,line2,line3,line4, time_text] + +def handle_close(evt): + print('Closing serial connection') + ser.close() + print('Closed serial plotter') + +def submit(text): + print (text) + ser.write(text.encode() + "\n".encode()) + + +ani = animation.FuncAnimation(fig, update, None, fargs=[line1, line2], + interval=10, blit=True, init_func=init) + +ax.set_xlabel('Last 200 Samples') +ax.set_ylabel('Values') +plt.subplots_adjust(bottom=0.25) +ax.legend(loc='lower right', ncol=2) + +fig.canvas.mpl_connect('close_event', handle_close) + +axbox = plt.axes([0.15, 0.05, 0.7, 0.075]) +text_box = TextBox(axbox, 'Send:', initial='') +text_box.on_submit(submit) + +if ser.is_open==True: + plt.show() + \ No newline at end of file diff --git a/tools/templates/templates.py b/tools/templates/templates.py new file mode 100644 index 000000000..c1d696cbc --- /dev/null +++ b/tools/templates/templates.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python3 + +""" + templates.py - template beautify TEMPLATES.md for Tasmota + + Copyright (C) 2020 Theo Arends + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Requirements: + - Python + - pip pycurl certifi + +Instructions: + Execute command to produce file TEMPLATE.md as found in the Tasmota root folder + +Usage: + python templates.py + +""" + +import io +import pycurl +import certifi +from io import BytesIO +from io import StringIO +from datetime import datetime + +column = 27 # Start position of {"NAME":... in line + +def main(): + print ("\n*** templates.py v20200514 by Theo Arends ***") + + # Download from template website + buffer = BytesIO() + url = "https://templates.blakadder.com/list.json" + c = pycurl.Curl() + c.setopt(c.URL, url) + c.setopt(c.WRITEDATA, buffer) + c.setopt(c.CAINFO, certifi.where()) + c.perform() + c.close() + body = buffer.getvalue() + fin = StringIO(body.decode('UTF-8')) + + now = datetime.now() + month = now.strftime('%B') + year = now.strftime('%Y') + + # Write to root/TEMPLATES.md + fout = open("..\..\TEMPLATES.md","w+") + + fout.write("\"Logo\"\n") + fout.write("\n") + fout.write("# Templates\n") + fout.write("\n") + fout.write("Find below the available templates as of " + month + " " + year + ". More template information can be found in the [Tasmota Device Templates Repository](http://blakadder.github.io/templates)\n") + + not_first = 0 + fline = fin.readlines() + for line in fline: + if line.strip(): + if line.startswith("##"): + if not_first: + fout.write('```\n') + fout.write('\n') + fout.write(line) + fout.write('```\n') + not_first = 1 + elif line.startswith("#"): + noop = 0 + else: + pos1 = line.find("{") + if pos1 < column: + a = column + 2 - pos1 + lout = line[0:pos1 - 4] + " "*a + line[pos1:len(line)] + else: + lout = line[0:pos1 - 4] + " " + line[pos1:len(line)] + fout.write(lout) + + fout.write('```\n') + + fout.close() + fin.close() + +if __name__ == "__main__": + main() diff --git a/tools/unishox/clipboard-const-converter.py b/tools/unishox/clipboard-const-converter.py new file mode 100644 index 000000000..ee180d8a9 --- /dev/null +++ b/tools/unishox/clipboard-const-converter.py @@ -0,0 +1,112 @@ +from tkinter import Tk +import unishox + +# get text from clipboard expecting something like that: +# const char HTTP_SCRIPT_WIFI[] PROGMEM = +# "function c(l){" // comments +# "eb('s1').value=l.innerText||l.textContent;" // comments +# "eb('p1').focus();" // comments +# // comments +# "}"; + +text = Tk().clipboard_get() +# print(text) + +# parsing and cleaning +text_list = text.splitlines() +text = '' #just reuse the string +const_name = '' #default if no name will be found + +line_number = 0 +for line in text_list: + pos = line.find("const char") + # print(pos, line) + if pos > -1: + line_list = line.rsplit(" ") + for el in line_list: + if el.find('[]') > -1: + const_name = el[:-2] #extract the "const char" variable name + line_list.pop(line_number) + else: # remove line comments + line_el = line.rsplit("//") + # print('Splitted line list by //' % line_el) + # print(line_el[0]) + text = text + line_el[0] + line_number = line_number +1 + +# print const_name +# print text + +#remove unwanted quotation marks +qm = [] +pos =0 +last_char = "" +for char in text: + if char == "\"": + if last_char != "\\": + qm.append(pos) #find all quotation marks without preceding backslash + last_char = char + pos = pos + 1 +# print(qm) +lastel = 0 +input = "" +for pos in qm: + sub = text[lastel+1:pos:] + if not sub.isspace() and pos-lastel > 1: + # print(lastel, pos) + input = input + sub #only copy substrings that are not whitespace + # print(text[lastel+1:pos:]) + lastel = pos + +print("####### Parsing intput:") +print("Const char name: ",const_name) +print('####### Cleaned input:') +print(input) + +#construct output (taken from shadinger) +input = input.replace("\\t", "\t") +input = input.replace("\\n", "\n") +input = input.replace("\\r", "\r") +input = input.replace("\\f", "\f") +input = input.replace("\\b", "\b") +input = input.replace("\\\"", u"\u0022") + +in_bytes = bytearray(input, 'utf-8') +in_len = len(in_bytes) +out_bytes = bytearray(in_len * 2) + +UNISHOX = unishox.Unishox() +out_len = UNISHOX.compress(in_bytes, len(in_bytes), out_bytes, len(out_bytes)) +print("####### Compression result:") +print("Compressed from {i} to {o}, -{p:.1f}%".format(i=in_len, o=out_len, p=(100-out_len/in_len*100))) +out_bytes = out_bytes[:out_len] # truncate to right size + +#PROGMEM is growing in steps 0,8,24,40,56,... bytes of data resulting in size of 0,16,32,48,64,... bytes +for in_real in range(8,in_len+16,16): + if in_real>=in_len: + print("Old real PROGMEM-size:",in_real+8,"(unused bytes:",in_real-in_len,")") + break +for out_real in range(8,out_len+16,16): + if out_real>=out_len: + print("New real PROGMEM-size:",out_real+8,"(unused bytes:",out_real-out_len,")") + break +print("the optimal case would be raw bytes + 8, real difference: ", in_real - out_real, "bytes") +# https://www.geeksforgeeks.org/break-list-chunks-size-n-python/ +def chunked(my_list, n): + return [my_list[i * n:(i + 1) * n] for i in range((len(my_list) + n - 1) // n )] + +# split in chunks of 20 characters +chunks = chunked(out_bytes, 20) + +lines_raw = [ "\"\\x" + "\\x".join( [ '{:02X}'.format(b) for b in chunk ] ) + "\"" for chunk in chunks ] +line_complete = "const char " + const_name + "_COMPRESSED" +"[] PROGMEM = " + ("\n" + " "*29).join(lines_raw) + ";" +lines = "const size_t " + const_name +"_SIZE = {size};\n{lines}".format(size=in_len, lines=line_complete) + +print('####### Final output:') +print(lines) + +definition = "#define " + const_name + " Decompress(" + const_name + "_COMPRESSED" + "," + const_name +"_SIZE" + ").c_str()" +print(definition) + + +# maybe add export to clipboard for later ... \ No newline at end of file diff --git a/tools/unishox/unishox.py b/tools/unishox/unishox.py new file mode 100644 index 000000000..087932daa --- /dev/null +++ b/tools/unishox/unishox.py @@ -0,0 +1,521 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +Python Class for compressing short strings. + +This class contains a highly modified and optimized version of Unishox +for Tasmota converted in C ported to Pyhton3. + +It was basically developed to individually compress and decompress small strings +(see https://github.com/siara-cc/Unishox) +In general compression utilities such as zip, gzip do not compress short strings +well and often expand them. They also use lots of memory which makes them unusable +in constrained environments like Arduino. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" + +class Unishox: + """ + This is a highly modified and optimized version of Unishox + for Tasmota, aimed at compressing `Rules` which are typically + short strings from 50 to 500 bytes. + + @author Stephan Hadinger + @revised Norbert Richter + """ + + # pylint: disable=bad-continuation,bad-whitespace,line-too-long + #cl_95 = [0x4000 + 3, 0x3F80 + 11, 0x3D80 + 11, 0x3C80 + 10, 0x3BE0 + 12, 0x3E80 + 10, 0x3F40 + 11, 0x3EC0 + 10, 0x3BA0 + 11, 0x3BC0 + 11, 0x3D60 + 11, 0x3B60 + 11, 0x3A80 + 10, 0x3AC0 + 10, 0x3A00 + 9, 0x3B00 + 10, 0x38C0 + 10, 0x3900 + 10, 0x3940 + 11, 0x3960 + 11, 0x3980 + 11, 0x39A0 + 11, 0x39C0 + 11, 0x39E0 + 12, 0x39F0 + 12, 0x3880 + 10, 0x3CC0 + 10, 0x3C00 + 9, 0x3D00 + 10, 0x3E00 + 9, 0x3F00 + 10, 0x3B40 + 11, 0x3BF0 + 12, 0x2B00 + 8, 0x21C0 + 11, 0x20C0 + 10, 0x2100 + 10, 0x2600 + 7, 0x2300 + 11, 0x21E0 + 12, 0x2140 + 11, 0x2D00 + 8, 0x2358 + 13, 0x2340 + 12, 0x2080 + 10, 0x21A0 + 11, 0x2E00 + 8, 0x2C00 + 8, 0x2180 + 11, 0x2350 + 13, 0x2F80 + 9, 0x2F00 + 9, 0x2A00 + 8, 0x2160 + 11, 0x2330 + 12, 0x21F0 + 12, 0x2360 + 13, 0x2320 + 12, 0x2368 + 13, 0x3DE0 + 12, 0x3FA0 + 11, 0x3DF0 + 12, 0x3D40 + 11, 0x3F60 + 11, 0x3FF0 + 12, 0xB000 + 4, 0x1C00 + 7, 0x0C00 + 6, 0x1000 + 6, 0x6000 + 3, 0x3000 + 7, 0x1E00 + 8, 0x1400 + 7, 0xD000 + 4, 0x3580 + 9, 0x3400 + 8, 0x0800 + 6, 0x1A00 + 7, 0xE000 + 4, 0xC000 + 4, 0x1800 + 7, 0x3500 + 9, 0xF800 + 5, 0xF000 + 5, 0xA000 + 4, 0x1600 + 7, 0x3300 + 8, 0x1F00 + 8, 0x3600 + 9, 0x3200 + 8, 0x3680 + 9, 0x3DA0 + 11, 0x3FC0 + 11, 0x3DC0 + 11, 0x3FE0 + 12] + cl_95 = [0x4000 + 3, 0x3F80 + 11, 0x3D80 + 11, 0x3C80 + 10, 0x3BE0 + 12, 0x3E80 + 10, 0x3F40 + 11, 0x3EC0 + 10, 0x3BA0 + 11, 0x3BC0 + 11, 0x3D60 + 11, 0x3B60 + 11, 0x3A80 + 10, 0x3AC0 + 10, 0x3A00 + 9, 0x3B00 + 10, 0x38C0 + 10, 0x3900 + 10, 0x3940 + 11, 0x3960 + 11, 0x3980 + 11, 0x39A0 + 11, 0x39C0 + 11, 0x39E0 + 12, 0x39F0 + 12, 0x3880 + 10, 0x3CC0 + 10, 0x3C00 + 9, 0x3D00 + 10, 0x3E00 + 9, 0x3F00 + 10, 0x3B40 + 11, 0x3BF0 + 12, 0x2B00 + 8, 0x21C0 + 11, 0x20C0 + 10, 0x2100 + 10, 0x2600 + 7, 0x2300 + 11, 0x21E0 + 12, 0x2140 + 11, 0x2D00 + 8, 0x46B0 + 13, 0x2340 + 12, 0x2080 + 10, 0x21A0 + 11, 0x2E00 + 8, 0x2C00 + 8, 0x2180 + 11, 0x46A0 + 13, 0x2F80 + 9, 0x2F00 + 9, 0x2A00 + 8, 0x2160 + 11, 0x2330 + 12, 0x21F0 + 12, 0x46C0 + 13, 0x2320 + 12, 0x46D0 + 13, 0x3DE0 + 12, 0x3FA0 + 11, 0x3DF0 + 12, 0x3D40 + 11, 0x3F60 + 11, 0x3FF0 + 12, 0xB000 + 4, 0x1C00 + 7, 0x0C00 + 6, 0x1000 + 6, 0x6000 + 3, 0x3000 + 7, 0x1E00 + 8, 0x1400 + 7, 0xD000 + 4, 0x3580 + 9, 0x3400 + 8, 0x0800 + 6, 0x1A00 + 7, 0xE000 + 4, 0xC000 + 4, 0x1800 + 7, 0x3500 + 9, 0xF800 + 5, 0xF000 + 5, 0xA000 + 4, 0x1600 + 7, 0x3300 + 8, 0x1F00 + 8, 0x3600 + 9, 0x3200 + 8, 0x3680 + 9, 0x3DA0 + 11, 0x3FC0 + 11, 0x3DC0 + 11, 0x3FE0 + 12] + + # enum {SHX_STATE_1 = 1, SHX_STATE_2}; // removed Unicode state + SHX_STATE_1 = 1 + SHX_STATE_2 = 2 + + SHX_SET1 = 0 + SHX_SET1A = 1 + SHX_SET1B = 2 + SHX_SET2 = 3 + + sets = [['\0', ' ', 'e', '\0', 't', 'a', 'o', 'i', 'n', 's', 'r'], + ['\0', 'l', 'c', 'd', 'h', 'u', 'p', 'm', 'b', 'g', 'w'], + ['f', 'y', 'v', 'k', 'q', 'j', 'x', 'z', '\0', '\0', '\0'], + ['\0', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8'], + ['.', ',', '-', '/', '?', '+', ' ', '(', ')', '$', '@'], + [';', '#', ':', '<', '^', '*', '"', '{', '}', '[', ']'], + ['=', '%', '\'', '>', '&', '_', '!', '\\', '|', '~', '`']] + + us_vcode = [2 + (0 << 3), 3 + (3 << 3), 3 + (1 << 3), 4 + (6 << 3), 0, + # 5, 6, 7, 8, 9, 10 + 4 + (4 << 3), 3 + (2 << 3), 4 + (8 << 3), 0, 0, 0, + # 11, 12, 13, 14, 15 + 4 + (7 << 3), 0, 4 + (5 << 3), 0, 5 + (9 << 3), + # 16, 17, 18, 19, 20, 21, 22, 23 + 0, 0, 0, 0, 0, 0, 0, 0, + # 24, 25, 26, 27, 28, 29, 30, 31 + 0, 0, 0, 0, 0, 0, 0, 5 + (10 << 3) ] + # 0, 1, 2, 3, 4, 5, 6, 7, + us_hcode = [1 + (1 << 3), 2 + (0 << 3), 0, 3 + (2 << 3), 0, 0, 0, 5 + (3 << 3), + # 8, 9, 10, 11, 12, 13, 14, 15, + 0, 0, 0, 0, 0, 0, 0, 5 + (5 << 3), + # 16, 17, 18, 19, 20, 21, 22, 23 + 0, 0, 0, 0, 0, 0, 0, 5 + (4 << 3), + # 24, 25, 26, 27, 28, 29, 30, 31 + 0, 0, 0, 0, 0, 0, 0, 5 + (6 << 3) ] + # pylint: enable=bad-continuation,bad-whitespace + + ESCAPE_MARKER = 0x2A + + TERM_CODE = 0x37C0 + # TERM_CODE_LEN = 10 + DICT_CODE = 0x0000 + DICT_CODE_LEN = 5 + #DICT_OTHER_CODE = 0x0000 + #DICT_OTHER_CODE_LEN = 6 + RPT_CODE_TASMOTA = 0x3780 + RPT_CODE_TASMOTA_LEN = 10 + BACK2_STATE1_CODE = 0x2000 + BACK2_STATE1_CODE_LEN = 4 + #BACK_FROM_UNI_CODE = 0xFE00 + #BACK_FROM_UNI_CODE_LEN = 8 + LF_CODE = 0x3700 + LF_CODE_LEN = 9 + TAB_CODE = 0x2400 + TAB_CODE_LEN = 7 + ALL_UPPER_CODE = 0x2200 + ALL_UPPER_CODE_LEN = 8 + SW2_STATE2_CODE = 0x3800 + SW2_STATE2_CODE_LEN = 7 + ST2_SPC_CODE = 0x3B80 + ST2_SPC_CODE_LEN = 11 + BIN_CODE_TASMOTA = 0x8000 + BIN_CODE_TASMOTA_LEN = 3 + + NICE_LEN = 5 + + mask = [0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFF] + + # pylint: disable=missing-function-docstring,invalid-name + + # Input + # out = bytearray + def append_bits(self, out, ol, code, clen, state): + #print("Append bits {ol} {code} {clen} {state}".format(ol=ol, code=code, clen=clen, state=state)) + if state == self.SHX_STATE_2: + # remove change state prefix + if (code >> 9) == 0x1C: + code <<= 7 + clen -= 7 + while clen > 0: + cur_bit = ol % 8 + blen = 8 if (clen > 8) else clen + a_byte = (code >> 8) & self.mask[blen - 1] + #print("append_bits a_byte {ab} blen {blen}".format(ab=a_byte,blen=blen)) + a_byte >>= cur_bit + if blen + cur_bit > 8: + blen = (8 - cur_bit) + if cur_bit == 0: + out[ol // 8] = a_byte + else: + out[ol // 8] |= a_byte + code <<= blen + ol += blen + if 0 == ol % 8: # pylint: disable=misplaced-comparison-constant + # we completed a full byte + last_c = out[(ol // 8) - 1] + if last_c in (0, self.ESCAPE_MARKER): + out[ol // 8] = 1 + last_c # increment to 0x01 or 0x2B + out[(ol // 8) -1] = self.ESCAPE_MARKER # replace old value with marker + ol += 8 # add one full byte + clen -= blen + return ol + + codes = [0x82, 0xC3, 0xE5, 0xED, 0xF5] # pylint: disable=bad-whitespace + bit_len = [ 5, 7, 9, 12, 16] # pylint: disable=bad-whitespace + + def encodeCount(self, out, ol, count): + #print("encodeCount ol = {ol}, count = {count}".format(ol=ol, count=count)) + till = 0 + base = 0 + for i in range(len(self.bit_len)): + bit_len_i = self.bit_len[i] + till += (1 << bit_len_i) + if count < till: + codes_i = self.codes[i] + ol = self.append_bits(out, ol, (codes_i & 0xF8) << 8, codes_i & 0x07, 1) + #print("encodeCount append_bits ol = {ol}, code = {code}, len = {len}".format(ol=ol,code=(codes_i & 0xF8) << 8,len=codes_i & 0x07)) + ol = self.append_bits(out, ol, (count - base) << (16 - bit_len_i), bit_len_i, 1) + #print("encodeCount append_bits ol = {ol}, code = {code}, len = {len}".format(ol=ol,code=(count - base) << (16 - bit_len_i),len=bit_len_i)) + return ol + base = till + return ol + + # Returns (int, ol, state, is_all_upper) + def matchOccurance(self, inn, len_, l_, out, ol, state, is_all_upper): + # int j, k; + longest_dist = 0 + longest_len = 0 + #for (j = l_ - self.NICE_LEN; j >= 0; j--) { + j = l_ - self.NICE_LEN + while j >= 0: + k = l_ + #for (k = l_; k < len && j + k - l_ < l_; k++) { + while k < len_ and j + k - l_ < l_: + if inn[k] != inn[j + k - l_]: + break + k += 1 + if k - l_ > self.NICE_LEN - 1: + match_len = k - l_ - self.NICE_LEN + match_dist = l_ - j - self.NICE_LEN + 1 + if match_len > longest_len: + longest_len = match_len + longest_dist = match_dist + j -= 1 + + if longest_len: + #print("longest_len {ll}".format(ll=longest_len)) + #ol_save = ol + if state == self.SHX_STATE_2 or is_all_upper: + is_all_upper = 0 + state = self.SHX_STATE_1 + ol = self.append_bits(out, ol, self.BACK2_STATE1_CODE, self.BACK2_STATE1_CODE_LEN, state) + + ol = self.append_bits(out, ol, self.DICT_CODE, self.DICT_CODE_LEN, 1) + ol = self.encodeCount(out, ol, longest_len) + ol = self.encodeCount(out, ol, longest_dist) + #print("longest_len {ll} longest_dist {ld} ol {ols}-{ol}".format(ll=longest_len, ld=longest_dist, ol=ol, ols=ol_save)) + l_ += longest_len + self.NICE_LEN + l_ -= 1 + + return l_, ol, state, is_all_upper + return -l_, ol, state, is_all_upper + + + def compress(self, inn, len_, out, len_out): + ol = 0 + state = self.SHX_STATE_1 + is_all_upper = 0 + l = 0 + while l < len_: + # for (l=0; l 0: + #print("matchOccurance l = {l} l_old = {lo}".format(l=l,lo=l_old)) + l += 1 # for loop + continue + + l = -l + + if state == self.SHX_STATE_2: # if Set2 + if ord(' ') <= c_in <= ord('@') or ord('[') <= c_in <= ord('`') or ord('{') <= c_in <= ord('~'): + pass + else: + state = self.SHX_STATE_1 # back to Set1 and lower case + ol = self.append_bits(out, ol, self.BACK2_STATE1_CODE, self.BACK2_STATE1_CODE_LEN, state) + + is_upper = 0 + if ord('A') <= c_in <= ord('Z'): + is_upper = 1 + else: + if is_all_upper: + is_all_upper = 0 + ol = self.append_bits(out, ol, self.BACK2_STATE1_CODE, self.BACK2_STATE1_CODE_LEN, state) + + if 32 <= c_in <= 126: + if is_upper and not is_all_upper: + ll = l+5 + # for (ll=l+5; ll>=l && ll ord('Z'): + break + + ll -= 1 + + if ll == l-1: + ol = self.append_bits(out, ol, self.ALL_UPPER_CODE, self.ALL_UPPER_CODE_LEN, state) # CapsLock + is_all_upper = 1 + + if state == self.SHX_STATE_1 and ord('0') <= c_in <= ord('9'): + ol = self.append_bits(out, ol, self.SW2_STATE2_CODE, self.SW2_STATE2_CODE_LEN, state) # Switch to sticky Set2 + state = self.SHX_STATE_2 + + c_in -= 32 + if is_all_upper and is_upper: + c_in += 32 + if c_in == 0 and state == self.SHX_STATE_2: + ol = self.append_bits(out, ol, self.ST2_SPC_CODE, self.ST2_SPC_CODE_LEN, state) # space from Set2 ionstead of Set1 + else: + # ol = self.append_bits(out, ol, pgm_read_word(&c_95[c_in]), pgm_read_byte(&l_95[c_in]), state); // original version with c/l in split arrays + cl = self.cl_95[c_in] + cl_code = cl & 0xFFF0 + cl_len = cl & 0x000F + if cl_len == 13: + cl_code = cl_code >> 1 + ol = self.append_bits(out, ol, cl_code, cl_len, state) + + elif c_in == 10: + ol = self.append_bits(out, ol, self.LF_CODE, self.LF_CODE_LEN, state) # LF + elif c_in == '\t': + ol = self.append_bits(out, ol, self.TAB_CODE, self.TAB_CODE_LEN, state) # TAB + else: + ol = self.append_bits(out, ol, self.BIN_CODE_TASMOTA, self.BIN_CODE_TASMOTA_LEN, state) # Binary, we reuse the Unicode marker which 3 bits instead of 9 + ol = self.encodeCount(out, ol, (255 - c_in) & 0xFF) + + + # check that we have some headroom in the output buffer + if ol // 8 >= len_out - 4: + return -1 # we risk overflow and crash + + l += 1 + + bits = ol % 8 + if bits: + ol = self.append_bits(out, ol, self.TERM_CODE, 8 - bits, 1) # 0011 0111 1100 0000 TERM = 0011 0111 11 + return (ol + 7) // 8 + # return ol // 8 + 1 if (ol%8) else 0 + + + def getBitVal(self, inn, bit_no, count): + c_in = inn[bit_no >> 3] + if bit_no >> 3 and self.ESCAPE_MARKER == inn[(bit_no >> 3) - 1]: + c_in -= 1 + r = 1 << count if (c_in & (0x80 >> (bit_no % 8))) else 0 + #print("getBitVal r={r}".format(r=r)) + return r + + # Returns: + # 0..11 + # or -1 if end of stream + def getCodeIdx(self, code_type, inn, len_, bit_no_p): + code = 0 + count = 0 + while count < 5: + if bit_no_p >= len_: + return -1, bit_no_p + # detect marker + if self.ESCAPE_MARKER == inn[bit_no_p >> 3]: + bit_no_p += 8 # skip marker + + if bit_no_p >= len_: + return -1, bit_no_p + + code += self.getBitVal(inn, bit_no_p, count) + bit_no_p += 1 + count += 1 + code_type_code = code_type[code] + if code_type_code and (code_type_code & 0x07) == count: + #print("getCodeIdx = {r}".format(r=code_type_code >> 3)) + return code_type_code >> 3, bit_no_p + + #print("getCodeIdx not found = {r}".format(r=1)) + return 1, bit_no_p + + def getNumFromBits(self, inn, bit_no_p, count): + ret = 0 + while count: + count -= 1 + if self.ESCAPE_MARKER == inn[bit_no_p >> 3]: + bit_no_p += 8 # skip marker + ret += self.getBitVal(inn, bit_no_p, count) + bit_no_p += 1 + # print("getNumFromBits = {r}".format(r=ret)) + return ret, bit_no_p + + def readCount(self, inn, bit_no_p, len_): + (idx, bit_no_p) = self.getCodeIdx(self.us_hcode, inn, len_, bit_no_p) + if idx >= 1: + idx -= 1 # we skip v = 1 (code '0') since we no more accept 2 bits encoding + if idx >= 5 or idx < 0: + return 0, bit_no_p # unsupported or end of stream + till = 0 + bit_len_idx = 0 + base = 0 + #for (uint32_t i = 0; i <= idx; i++) { + i = 0 + while i <= idx: + # for i in range(idx): + base = till + bit_len_idx = self.bit_len[i] + till += (1 << bit_len_idx) + i += 1 + + (count, bit_no_p) = self.getNumFromBits(inn, bit_no_p, bit_len_idx) + count = count + base + #print("readCount getNumFromBits = {count} ({bl})".format(count=count,bl=bit_len_idx)) + + return count, bit_no_p + + def decodeRepeat(self, inn, len_, out, ol, bit_no): + #print("decodeRepeat Enter") + (dict_len, bit_no) = self.readCount(inn, bit_no, len_) + dict_len += self.NICE_LEN + (dist, bit_no) = self.readCount(inn, bit_no, len_) + dist += self.NICE_LEN - 1 + #memcpy(out + ol, out + ol - dist, dict_len); + i = 0 + while i < dict_len: + #for i in range(dict_len): + out[ol + i] = out[ol - dist + i] + i += 1 + ol += dict_len + + return ol, bit_no + + def decompress(self, inn, len_, out, len_out): + ol = 0 + bit_no = 0 + dstate = self.SHX_SET1 + is_all_upper = 0 + + len_ <<= 3 # *8, len_ in bits + out[ol] = 0 + while bit_no < len_: + c = 0 + is_upper = is_all_upper + (v, bit_no) = self.getCodeIdx(self.us_vcode, inn, len_, bit_no) # read vCode + #print("bit_no {b}. v = {v}".format(b=bit_no,v=v)) + if v < 0: + break # end of stream + h = dstate # Set1 or Set2 + if v == 0: # Switch which is common to Set1 and Set2, first entry + (h, bit_no) = self.getCodeIdx(self.us_hcode, inn, len_, bit_no) # read hCode + #print("bit_no {b}. h = {h}".format(b=bit_no,h=h)) + if h < 0: + break # end of stream + if h == self.SHX_SET1: # target is Set1 + if dstate == self.SHX_SET1: # Switch from Set1 to Set1 us UpperCase + if is_all_upper: # if CapsLock, then back to LowerCase + is_upper = 0 + is_all_upper = 0 + continue + + (v, bit_no) = self.getCodeIdx(self.us_vcode, inn, len_, bit_no) # read again vCode + if v < 0: + break # end of stream + if v == 0: + (h, bit_no) = self.getCodeIdx(self.us_hcode, inn, len_, bit_no) # read second hCode + if h < 0: + break # end of stream + if h == self.SHX_SET1: # If double Switch Set1, the CapsLock + is_all_upper = 1 + continue + + is_upper = 1 # anyways, still uppercase + else: + dstate = self.SHX_SET1 # if Set was not Set1, switch to Set1 + continue + + elif h == self.SHX_SET2: # If Set2, switch dstate to Set2 + if dstate == self.SHX_SET1: + dstate = self.SHX_SET2 + continue + + if h != self.SHX_SET1: # all other Sets (why not else) + (v, bit_no) = self.getCodeIdx(self.us_vcode, inn, len_, bit_no) # we changed set, now read vCode for char + if v < 0: + break # end of stream + + if v == 0 and h == self.SHX_SET1A: + #print("v = 0, h = self.SHX_SET1A") + if is_upper: + (temp, bit_no) = self.readCount(inn, bit_no, len_) + out[ol] = 255 - temp # binary + ol += 1 + else: + (ol, bit_no) = self.decodeRepeat(inn, len_, out, ol, bit_no) # dist + continue + + if h == self.SHX_SET1 and v == 3: + # was Unicode, will do Binary instead + (temp, bit_no) = self.readCount(inn, bit_no, len_) + out[ol] = 255 - temp # binary + ol += 1 + continue + + if h < 7 and v < 11: + #print("h {h} v {v}".format(h=h,v=v)) + c = ord(self.sets[h][v]) + if ord('a') <= c <= ord('z'): + if is_upper: + c -= 32 # go to UpperCase for letters + else: # handle all other cases + if is_upper and dstate == self.SHX_SET1 and v == 1: + c = ord('\t') # If UpperCase Space, change to TAB + if h == self.SHX_SET1B: + if 8 == v: # was LF or RPT, now only LF # pylint: disable=misplaced-comparison-constant + out[ol] = ord('\n') + ol += 1 + continue + + if 9 == v: # was CRLF, now RPT # pylint: disable=misplaced-comparison-constant + (count, bit_no) = self.readCount(inn, bit_no, len_) + count += 4 + if ol + count >= len_out: + return -1 # overflow + + rpt_c = out[ol - 1] + while count: + count -= 1 + out[ol] = rpt_c + ol += 1 + continue + + if 10 == v: # pylint: disable=misplaced-comparison-constant + break # TERM, stop decoding + + out[ol] = c + ol += 1 + + if ol >= len_out: + return -1 # overflow + + return ol + + # pylint: enable=missing-function-docstring + + +if __name__ == "__main__": + # pylint: disable=line-too-long + UNISHOX = Unishox() + BYTES_ = bytearray(2048) + INN = bytearray(b'ON Switch1#State==1 DO Add1 1 ENDON ON Var1#State==0 DO ShutterStop1 ENDON ON Var1#State==1 DO ShutterClose1 ENDON ON Var1#State>=2 DO Var1 0 ENDON ON Shutter1#Close DO Var1 0 ENDON ON Switch2#State==1 DO Add2 1 ENDON ON Var2#State==0 DO ShutterStop1 ENDON ON Var2#State==1 DO ShutterOpen1 ENDON ON Var2#State>=2 DO Var2 0 ENDON ON Shutter1#Open DO Var2 0 ENDON') + LEN_ = UNISHOX.compress(INN, len(INN), BYTES_, len(BYTES_)) + print("Compressed from {fromm} to {to} ({p}%)".format(fromm=len(INN), to=LEN_, p=(100-LEN_/len(INN)*100))) + + OUT = bytearray(2048) + LEN_ = UNISHOX.decompress(BYTES_, LEN_, OUT, len(OUT)) + print(str(OUT, 'utf-8').split('\x00')[0]) diff --git a/updateDocs.sh b/updateDocs.sh deleted file mode 100644 index b23976cc7..000000000 --- a/updateDocs.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh - -SCRIPTPATH="$(readlink -f "$0")" -SCRIPTPATH="${SCRIPTPATH%/*}" - -rm -rf "$SCRIPTPATH/html" -echo -e "\n\n\n\n" -#cd "$SCRIPTPATH/" && doxygen && git add $DOCDIR && git commit -a -m "Documentation update." -cd "$SCRIPTPATH/" && doxygen